From 71d7a680102854126731b7fce34884d1720316fa Mon Sep 17 00:00:00 2001 From: UbiquitousLearning <38753457+UbiquitousLearning@users.noreply.github.com> Date: Mon, 9 Jun 2025 16:05:33 +0800 Subject: [PATCH 01/22] feat: add qwen2vl-qnn & flashattn2 support (#291) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Squashed commit of the following: commit efde6d0d014b647b8ceea59441aef1bd3ac424c0 Author: yirongjie Date: Tue May 27 16:09:16 2025 +0000 fix: merge commit fe7fb476717e99df2eac23ab7fd1088e03cf8b3c Merge: f52bb32e 20e94c06 Author: yirongjie Date: Tue May 27 16:09:08 2025 +0000 Merge branch 'main' of https://github.com/yirongjie/mllm commit f52bb32e5dbf4edcd4998d664ae071a1b5c8dbbb Author: yirongjie Date: Tue May 27 12:25:08 2025 +0000 fix: merge from qnn-qwen2vl; commit 6f6c2442f750363c6789e7717861ea3a216cf356 Author: yirongjie Date: Tue May 27 12:24:17 2025 +0000 Squashed commit of the following: commit 4862c764505dce2fdb5155036d0de724e475c799 Author: oreomaker Date: Thu May 15 14:59:37 2025 +0800 refact: use hvx qnn silu(faster); usable showui npu version commit 5df1b07cfbe3d4b5bbc09318b92ee17da262f897 Author: oreomaker Date: Wed May 14 22:10:52 2025 +0800 feat: qnn dequantize_add hvx op commit c813f55975bc35946bbeafbbc0349b013f25c840 Author: oreomaker Date: Tue May 13 09:50:06 2025 +0800 chore: format qnn op package code commit ea215f0320d32a271a4a0789a54d4b0d5c294c54 Author: oreomaker Date: Mon May 12 11:34:38 2025 +0800 feat: free act tensors after qnn vit embedding commit e4f50119ad2f78fff1175276c0760c3a20ea256c Author: oreomaker Date: Mon May 12 11:14:30 2025 +0800 chore: remove save data in modeling qwen2vlnpu commit 2dcb67798c8df48cbd7b78e0b7c979c5f24736f4 Author: oreomaker Date: Mon May 12 10:48:34 2025 +0800 fix: seperate weights for embedding-lmhead when using rotated qwen2vl/showui commit 484731856a3f18f670295b7fa744822ad254f515 Author: oreomaker Date: Sun May 11 21:16:59 2025 +0800 fix: cpu tensor free bug(todo: handle tensor free) commit 799b6734b2f241402a42c365139c56dea7b2ec64 Author: xudaliang Date: Sat May 10 22:51:11 2025 +0800 feat : new qwen2_vl model. commit dd1817d2bf7a69fd26691776336bdd205c15eee9 Author: xudaliang Date: Sat May 10 22:50:35 2025 +0800 feat : support qwen2-vl rotation model with fp bias. commit 305dc5cc9df7fddc32b3f0484463f529097785de Author: oreomaker Date: Thu May 8 21:37:35 2025 +0800 feat: runnable qwen2vl qnn showui(2*256) commit 8e148156a05a122d1b883f0ef8dd84693e151cdc Author: oreomaker Date: Thu May 8 21:36:33 2025 +0800 fix: pre processing of qwen2vl commit e041296c97eac7af600b42ab3255f9b90f7acbfe Author: oreomaker Date: Thu May 8 21:34:07 2025 +0800 refact: qwen vl npu modeling using closetFactor view(64->8x8) feat: get_position_id padding in Qwen2VL_ImagePatchAndEmbedding commit 5b17204b1a9bd1c3c96e2c2d7f2014c5f0624f1e Author: oreomaker Date: Thu May 8 21:29:13 2025 +0800 feat: vit(visual_xx) tensor reuse for qnn (noted as: QNN VLM trick) commit 7c426584baeb1eed60dd392ee1edd651667eaab3 Author: oreomaker Date: Thu May 8 21:26:49 2025 +0800 feat: finish cpu pipeline mrope commit 0962c0051b110925bf191a180f13a24eaba2303e Author: oreomaker Date: Tue May 6 11:39:29 2025 +0800 feat: pipeline multimodal rope commit 53179338623e4d74306b3c73fb5993291c289305 Author: oreomaker Date: Tue May 6 11:38:10 2025 +0800 refactor: use old&fast qnn silu commit 5bd14def5bcb64fedda80e14cc9874ee37d6caf6 Author: oreomaker Date: Mon Apr 28 21:10:48 2025 +0800 feat: runnable qwen 2 vl npu commit 1df6eedb738ea2f3f079f49762c8dcafda721498 Author: oreomaker Date: Sun Apr 27 10:13:44 2025 +0800 refactor: tensor.to(QNN) commit d3d29c4a900428cf7e22244bc7860fd85c3bde5b Author: oreomaker Date: Sat Apr 26 21:22:52 2025 +0800 chore: remove saveData in qwen2vl modeling commit c40e0c0fcb3e748b5d19bcc193f8bf47ac0fe33b Author: oreomaker Date: Sat Apr 26 20:51:16 2025 +0800 feat: add qnn retrieve context info log commit 175d3a21b0b65186305a761d0417fe3a981e8fbc Author: oreomaker Date: Sat Apr 26 20:46:14 2025 +0800 fix: qwen 2 vl npu input tensor backend(correct version) commit 871e920ea1b9eda62fb39d8bc42b7378fd1cc7fa Author: oreomaker Date: Fri Apr 25 09:50:05 2025 +0800 fix: quantize i16 arm neon macro commit a2b802c81c99a55a1e99bd36a52ea3995efb27e0 Author: xudaliang Date: Wed Apr 23 18:33:26 2025 +0800 fix : Qwen2-VL prefill bugs: 1.FP32 KVCache. 2.LMHead does not execute. commit 8c666041e9962292101b4747fb450f82a2cf54d9 Author: oreomaker Date: Fri Apr 18 15:35:03 2025 +0800 fix: restore qwen2.5 modeling commit f138bebef7f97742543e111877d3d004d0f8515a Author: oreomaker Date: Fri Apr 18 15:28:35 2025 +0800 fix: restore debug change commit 09e12ced5efb91f40a5291f28e92e4cd9db38f20 Merge: d725942b 9b271a99 Author: oreomaker Date: Fri Apr 18 13:39:10 2025 +0800 Merge branch 'debug-qwen2.5' of github.com:liang1232018/mllm into debug-qwen2.5 commit d725942b304f41637ecc1dcea72eb7571a3846be Author: oreomaker Date: Fri Apr 18 13:39:04 2025 +0800 dev: qnn sigmoid version silu feat: qnn backend f16 type input commit 9b271a9973d8870e48eb9ce3aca5041908fa13b0 Author: xudaliang Date: Fri Apr 18 13:24:52 2025 +0800 fix : linear W8A8 bias uint8 type bug commit 793a6c6c678f392895245903f36b1c3bfab38de9 Author: xudaliang Date: Fri Apr 18 13:23:49 2025 +0800 fix : Shadow linear triger condition. commit 4e24bca3fcc3e10214e361d459d27de9c4e62f2e Author: oreomaker Date: Wed Apr 16 20:53:07 2025 +0800 qwen 2.5 debug commit 4d747562dfbd1b544b33bd7297f2dcf2495edc35 Author: oreomaker Date: Wed Apr 16 20:52:33 2025 +0800 fix: shadow linear commit 5866e2bcd1eff3dfbc6d35353c053cab5c227bfb Author: oreomaker Date: Tue Apr 15 22:17:12 2025 +0800 qwen 2.5 debug commit 29e9b92afea6758eb42dfa298efedaa9ec31304c Author: oreomaker Date: Mon Apr 14 09:28:45 2025 +0800 fix: remove shadow linear if(round_value) logic commit a61e837c0885672200431c270f83818d70e048a2 Author: oreomaker Date: Sun Apr 13 22:03:45 2025 +0800 feat: int16 qkv for qwen2.5 vl npu commit 566f21dfc63a80b8f8b91926d657c28ed870fd7b Author: xudaliang Date: Sun Apr 13 18:45:06 2025 +0800 fix : modeling input quantize to I8, but dequantize with I16 bug. commit 60639d063c4659f9aa70f62b1be80050d7584153 Author: xudaliang Date: Sun Apr 13 18:44:18 2025 +0800 fix : LLaMADequantize INT16 to FP32 shuffle order bugs. commit a5cc652ad1f35730957d8be8ada8cecc6eabba6f Author: xudaliang Date: Sun Apr 13 17:31:10 2025 +0800 fix : LLaMAQuantize FP32 to INT16 round scale error. commit f1398225e0b53c3fc743a1eb44bd3b224ca59adf Author: oreomaker Date: Sat Apr 12 22:24:30 2025 +0800 fix: qnn int 16 linear bias(use int8 bias scale) commit 883181191c17a440b021006d484f345992c8d84c Author: oreomaker Date: Sat Apr 12 15:03:40 2025 +0800 debug: qnn int16 linear commit 088fe09cb999a8a48794c922971a82b08107bdca Author: xudaliang Date: Fri Apr 11 23:22:41 2025 +0800 feat : support INT16 dequantize and quantize. commit 73ebe87ab352505465b0a079bdc00e7d8ded93ff Merge: b73c1c34 6007443d Author: liang1232018 <40791416+liang1232018@users.noreply.github.com> Date: Wed Apr 9 14:50:25 2025 +0800 Merge pull request #12 from liang1232018/develop-zh Develop zh commit 6007443d3e00fdf7df2079bb669eafde507ba575 Merge: 1c8647e9 b73c1c34 Author: liang1232018 <40791416+liang1232018@users.noreply.github.com> Date: Wed Apr 9 14:50:07 2025 +0800 Merge branch 'develop-xdl' into develop-zh commit 1c8647e9f1ba295dfc127e36e5a40076fc26bf07 Author: oreomaker Date: Tue Apr 8 21:39:56 2025 +0800 fix: qnn quant scale pow(2,bit) -> pow(2,bit-1) commit cc760aeedefc5f98a988815e77c5ef46eb18497a Author: oreomaker Date: Tue Apr 8 17:03:17 2025 +0800 fix: op create param type->dtype commit 6afa80ce69c4a91dd9a504dfe3e1af935e07019f Author: oreomaker Date: Mon Apr 7 15:25:21 2025 +0800 feat: Tensor::saveData only do when STATIC_READY commit 2ebded3526913e45f0b9927145a9313062bc56a2 Author: oreomaker Date: Mon Apr 7 15:24:11 2025 +0800 feat: add qnn int16 layer param & op todo: qnn llama package implement commit 4faeca8e5e1f33053f059c3c97b16a7b7389b71c Author: oreomaker Date: Mon Mar 24 15:52:54 2025 +0800 dev: runnable qwen2vl npu (buggy) commit ebf110ebdcaf6a467af342512b9827e6b0d6b43e Author: oreomaker Date: Mon Mar 24 15:46:23 2025 +0800 feat: add qwen vl export tool (todo: simulate infer and profile tools) commit bde9a924a2667571d1eda1af62b44f647cb0d1d5 Author: oreomaker Date: Mon Mar 24 15:44:25 2025 +0800 dev: a just working version of qwen 2.5 npu commit 126c283a0b859c21ff8268e5c37df2de58face62 Merge: 25de8c37 9d33aafa Author: oreomaker Date: Mon Mar 24 15:43:30 2025 +0800 Merge branch 'fix-qnn-python' into develop-zh commit 9d33aafaed25f82cb0b3f29027f85c8f22c1a715 Author: oreomaker Date: Fri Mar 21 16:01:23 2025 +0800 fix: qnn profile quant bugs commit 25de8c3723477899036e61ee36a2a002648fcf3e Author: oreomaker Date: Thu Mar 20 16:00:19 2025 +0800 refactor: add graph split layer for QNN, change the modeling note: xnnpack is affected, should not merge commit 690a24ef6cedbe635f7e3c223eceea3fa2b6571c Author: oreomaker Date: Mon Mar 17 17:45:34 2025 +0800 feat: QNN load cache execute commit 4f28330f50174f67dca3ed10b6efaa4414e5c06a Author: oreomaker Date: Sun Mar 9 22:33:21 2025 +0800 dev: QNN graph merging execute commit b73c1c345f69f28c5f872d9dca26a065b690be5e Author: xudaliang Date: Tue Nov 12 23:28:12 2024 +0800 feat : support decoding model configuration. commit ec3d4e5be5b144e92282b9423ac37539c6422b55 Author: xudaliang Date: Tue Nov 12 20:31:45 2024 +0800 feat : support Qwen2.5 npu. commit 7246d5387d2c9d7c1427c06a6d49144e8e8a5bf7 Author: yirongjie Date: Tue May 27 07:12:53 2025 +0000 feat: set run in Backends commit 115024103f0a44b579a1014729e00edafe3b5744 Author: yirongjie Date: Sat May 24 07:57:09 2025 +0000 fix: getFunc commit 24db241ba030fbdd1f9a5da92915d92a4f657c2a Author: yirongjie Date: Fri May 23 05:16:41 2025 +0000 fix: tensor function to shared_ptr commit 0ecce7564b11fa0feb25f290dd564a334bddb6ca Author: yirongjie Date: Thu May 22 14:05:11 2025 +0000 feat:eager cpu commit 9835db5bdc90d7eb404ec19f0883968a4288e78d Author: yirongjie Date: Fri Apr 18 14:57:21 2025 +0000 fix: vtp commit 30c30465cce2747918af7e884243610b77b646b1 Author: yirongjie Date: Wed Apr 16 06:49:46 2025 +0000 fix: vtp commit b416268d590d4888c4bd8c62bcbe42723035f164 Author: yirongjie Date: Tue Apr 15 08:40:22 2025 +0000 fix: vtp commit 6430ca86f64ccf6f36817740d88a418202e30577 Author: yirongjie Date: Mon Apr 14 12:53:58 2025 +0000 feat: vtp commit f86bff6526280c258fba442c940651e175bd0781 Author: yirongjie Date: Sun Mar 23 09:41:14 2025 +0000 ref: add ShowUI * feat: add FlashAttention2 && fix: MULTIMODELROPE * remove broken submodule --------- Co-authored-by: yirongjie Co-authored-by: yi --- .gitignore | 3 +- CMakeLists.txt | 7 +- README.md | 1 + examples/CMakeLists.txt | 7 +- examples/demo_phonelm_npu.cpp | 10 + examples/demo_qwen.cpp | 8 +- examples/demo_qwen2.5_npu.cpp | 30 +- examples/demo_qwen2.5_pipeline.cpp | 124 + examples/demo_qwen2_vl.cpp | 6 +- examples/demo_qwen2_vl_npu.cpp | 185 + examples/demo_qwen_npu.cpp | 23 +- examples/demo_qwen_pipeline.cpp | 4 +- examples/demo_showui.cpp | 3 +- include/OpDefined.hpp | 3 + include/Types.hpp | 1 + scripts/run_phonelm_qnn.sh | 2 +- scripts/run_qwen2_vl_qnn.sh | 52 + scripts/run_qwen_qnn.sh | 3 +- src/Layer.hpp | 68 +- src/Module.hpp | 2 + src/Parallel.hpp | 12 +- src/Tensor.cpp | 254 +- src/Tensor.hpp | 85 + src/Trace.cpp | 10 +- src/backends/cpu/CPUBackend.cpp | 30 +- src/backends/cpu/compute/FlashAttention2.hpp | 3077 +++++++++++++++++ src/backends/cpu/compute/VecDot.hpp | 4 +- src/backends/cpu/function/CPUClipFunc.hpp | 37 + .../cpu/function/CPUFlashAttention2Func.hpp | 74 + ...lyVisionRoPE.hpp => CPUVisionRoPEFunc.hpp} | 2 +- src/backends/cpu/op/CPUElasticLinear.cpp | 26 - src/backends/cpu/op/CPUKVCache.cpp | 14 +- src/backends/cpu/op/CPUKVCache.hpp | 7 +- src/backends/cpu/op/CPULinearINT8Shadow.cpp | 8 +- src/backends/cpu/op/CPULinearInt8.cpp | 4 +- src/backends/cpu/op/CPUMultimodalRoPE.cpp | 12 +- .../cpu/op/CPUMultimodalRoPEPipeline.cpp | 330 ++ .../cpu/op/CPUMultimodalRoPEPipeline.hpp | 72 + src/backends/cpu/op/CPUQuantize.cpp | 70 +- src/backends/cpu/op/CPUQuantize.hpp | 5 +- src/backends/cpu/quantize/QuantizeQ8.cpp | 80 + src/backends/cpu/quantize/QuantizeQ8.hpp | 3 + .../LLaMAPackage/config/LLaMAOpPackageHtp.xml | 89 +- .../src/LLaMAPackageInterface.cpp | 98 +- .../LLaMAPackage/src/ops/Attention.cpp | 66 +- .../LLaMAPackage/src/ops/CausalMask.cpp | 120 +- .../LLaMAPackage/src/ops/HeadMatmul.cpp | 113 +- .../LLaMAPackage/src/ops/IRoPE.cpp | 242 +- .../LLaMAPackage/src/ops/KVCache.cpp | 117 +- .../LLaMAPackage/src/ops/LLaMAAdd.cpp | 195 +- .../LLaMAPackage/src/ops/LLaMADequantize.cpp | 396 ++- .../src/ops/LLaMADequantizeAdd.cpp | 694 ++++ .../LLaMAPackage/src/ops/LLaMALinear.cpp | 125 +- .../LLaMAPackage/src/ops/LLaMAMul.cpp | 300 +- .../LLaMAPackage/src/ops/LLaMAQuantize.cpp | 820 +++-- .../LLaMAPackage/src/ops/LLaMAReLU.cpp | 143 +- .../LLaMAPackage/src/ops/LLaMASuperSiLU.cpp | 1373 ++++---- .../LLaMAPackage/src/ops/MergeOutput.cpp | 135 +- .../LLaMAPackage/src/ops/QLayerNorm.cpp | 237 +- .../LLaMAPackage/src/ops/RMSNorm.cpp | 518 ++- .../LLaMAPackage/src/ops/RoPE.cpp | 1260 ++++--- .../LLaMAPackage/src/ops/SiLU.cpp | 610 +++- .../LLaMAPackage/src/ops/SplitInput.cpp | 120 +- .../LLaMAPackage/src/ops/WNop.cpp | 143 +- src/backends/qnn/Model/QnnModel.cpp | 50 +- src/backends/qnn/Model/QnnModel.hpp | 5 +- src/backends/qnn/QNNBackend.cpp | 390 ++- src/backends/qnn/QNNBackend.hpp | 10 +- src/backends/qnn/QnnTypeMacros.hpp | 792 +++-- src/backends/qnn/README.md | 2 +- src/backends/qnn/Utils/QnnSampleAppUtils.cpp | 611 ++-- src/backends/qnn/Utils/QnnSampleAppUtils.hpp | 38 +- .../qnn/WrapperUtils/QnnWrapperUtils.cpp | 215 +- .../qnn/WrapperUtils/QnnWrapperUtils.hpp | 214 +- src/backends/qnn/op/QNNCommonOp.cpp | 39 +- src/backends/qnn/op/QNNDequantize.cpp | 337 +- src/backends/qnn/op/QNNDequantize.hpp | 6 +- src/backends/qnn/op/QNNIRoPE.cpp | 2 +- src/backends/qnn/op/QNNLinearINT8.cpp | 248 +- src/backends/qnn/op/QNNLinearINT8.hpp | 7 +- src/backends/qnn/op/QNNQuantize.cpp | 83 +- src/backends/qnn/op/QNNQuantize.hpp | 8 +- src/backends/qnn/op/QNNRMSNorm.cpp | 2 +- src/backends/qnn/op/QNNRoPE.cpp | 2 +- src/backends/qnn/op/QNNSiLU.cpp | 5 +- src/backends/qnn/op/QNNSubGraphFinalize.cpp | 32 + src/backends/qnn/op/QNNSubGraphFinalize.hpp | 25 + src/backends/qnn/op/QNNSubGraphStart.cpp | 37 + src/backends/qnn/op/QNNSubGraphStart.hpp | 26 + src/backends/qnn/op/QNNSuperSiLU.cpp | 6 +- src/backends/qnn/op/QNNView.cpp | 2 +- src/models/bert/modeling_bert.hpp | 2 +- src/models/clip/modeling_clip.hpp | 42 +- src/models/dclm/modeling_dclm.hpp | 22 +- src/models/fuyu/configuration_fuyu.hpp | 3 +- src/models/fuyu/modeling_fuyu.hpp | 25 +- src/models/gemma/modeling_gemma.hpp | 7 +- src/models/gemma2/modeling_gemma2.hpp | 27 +- src/models/imagebind/modeling_imagebind.hpp | 42 +- src/models/llama/configuration_llama.hpp | 4 +- src/models/llama/modeling_llama.hpp | 30 +- src/models/llama/modeling_sparse_llama.hpp | 36 +- src/models/llama3/modeling_llama3.hpp | 53 +- src/models/llava/modeling_llava.hpp | 14 +- src/models/minicpm/modeling_minicpm.hpp | 7 +- .../mbm/modeling_minicpm_moe_mbm.hpp | 173 +- .../mbp/modeling_minicpm_moe_mbp.hpp | 6 +- .../minicpm_moe/modeling_minicpm_moe.hpp | 6 +- src/models/mistral/modeling_mistral.hpp | 6 +- src/models/openelm/modeling_openelm.hpp | 23 +- src/models/opt/modeling_opt.hpp | 21 +- src/models/phi3/modeling_phi3.hpp | 11 +- src/models/phi3v/modeling_phi3v.hpp | 19 +- src/models/phonelm/modeling_phonelm.hpp | 27 +- src/models/phonelm/modeling_phonelm_npu.hpp | 269 +- src/models/qwen/configuration_qwen.hpp | 30 + src/models/qwen/modeling_qwen.hpp | 27 +- src/models/qwen/modeling_qwen_npu.hpp | 287 +- src/models/qwen2_vl/modeling_qwen2_vl.hpp | 59 +- src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp | 978 ++++++ src/models/qwen2_vl/processing_qwen2_vl.hpp | 10 +- src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp | 105 +- src/models/qwen2_vl/vtp/ndc_tools.hpp | 515 +++ src/models/qwen2_vl/vtp/vtp_tools.hpp | 25 +- src/models/qwen3/modeling_qwen3.hpp | 25 +- src/models/smollm/modeling_smollm.hpp | 11 +- src/models/stablelm/modeling_stablelm.hpp | 37 +- src/models/tinyllama/modeling_tinyllama.hpp | 19 +- .../transformer/configuration_transformer.hpp | 1 + .../transformer/modeling_transformer.hpp | 34 +- src/models/vit/modeling_vit.hpp | 13 +- .../profiling_activation/export_int8_model.py | 11 +- .../utils/quantization_simulation.py | 62 + tools/jni/LibHelper.cpp | 181 +- tools/jni/LibHelper.hpp | 1 + 135 files changed, 13708 insertions(+), 5464 deletions(-) create mode 100644 examples/demo_qwen2.5_pipeline.cpp create mode 100644 examples/demo_qwen2_vl_npu.cpp create mode 100755 scripts/run_qwen2_vl_qnn.sh create mode 100644 src/backends/cpu/compute/FlashAttention2.hpp create mode 100644 src/backends/cpu/function/CPUFlashAttention2Func.hpp rename src/backends/cpu/function/{CPUApplyVisionRoPE.hpp => CPUVisionRoPEFunc.hpp} (99%) create mode 100644 src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp create mode 100644 src/backends/cpu/op/CPUMultimodalRoPEPipeline.hpp create mode 100755 src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMADequantizeAdd.cpp create mode 100644 src/backends/qnn/op/QNNSubGraphFinalize.cpp create mode 100644 src/backends/qnn/op/QNNSubGraphFinalize.hpp create mode 100644 src/backends/qnn/op/QNNSubGraphStart.cpp create mode 100644 src/backends/qnn/op/QNNSubGraphStart.hpp create mode 100644 src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp create mode 100644 src/models/qwen2_vl/vtp/ndc_tools.hpp diff --git a/.gitignore b/.gitignore index 97847b5ed..82d8c6e40 100644 --- a/.gitignore +++ b/.gitignore @@ -36,5 +36,4 @@ examples/demo_deepseek.cpp src/models/deepseek/* examples/demo.cpp -src/backends/qnn/sdk/* -*.mllm +src/backends/qnn/sdk/* \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index c842fefd4..44022cc63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,12 @@ if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES endif () if (ARM) - set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin-arm) +if(QNN) +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin-arm-qnn) +else() +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin-arm) +endif() + add_compile_definitions(__ARM_FEATURE_DOTPROD) # 检查是否使用的是 GCC 或 Clang 编译器 if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") diff --git a/README.md b/README.md index 142d06958..59b5645e2 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ mllm is a lightweight, fast, and easy-to-use (multimodal) on-device LLM inferenc ```bash git clone https://github.com/UbiquitousLearning/mllm cd mllm +git submodule update --init --recursive ``` ### Check prerequisites diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 198877170..e69921dc3 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -99,11 +99,12 @@ func_vlm_add_executable(demo_showui) if(QNN) func_llm_add_executable(demo_qwen_npu) - func_llm_add_executable(main_qwen_npu) + # func_llm_add_executable(main_qwen_npu) func_llm_add_executable(demo_phonelm_npu) - func_llm_add_executable(main_phonelm_npu) + # func_llm_add_executable(main_phonelm_npu) func_llm_add_executable(demo_qwen2.5_npu) - func_llm_add_executable(demo_qwen_pipeline) + # func_llm_add_executable(demo_qwen_pipeline) + func_vlm_add_executable(demo_qwen2_vl_npu) endif() diff --git a/examples/demo_phonelm_npu.cpp b/examples/demo_phonelm_npu.cpp index 7d269eb94..608ffab53 100644 --- a/examples/demo_phonelm_npu.cpp +++ b/examples/demo_phonelm_npu.cpp @@ -1,4 +1,5 @@ #include "Module.hpp" +#include "QNNBackend.hpp" #include "Types.hpp" #include #include "backends/cpu/CPUBackend.hpp" @@ -13,8 +14,10 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/phonelm_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/phonelm_merges.txt"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/phonelm-1.5b-instruct-int8.mllm"); cmdParser.add("decoding", 'd', "specify mllm decoding model path", false, "../models/phonelm-1.5b-instruct-q4_0_4_4.mllm"); + cmdParser.add("limits", 'l', "max KV cache size", false, 400); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.add("chunk", 'c', "chunk size", false, 64); @@ -28,6 +31,8 @@ int main(int argc, char **argv) { int chunk_size = cmdParser.get("chunk"); CPUBackend::cpu_threads = cmdParser.get("thread"); + Module::initBackend(MLLM_QNN); + auto tokenizer = SmolLMTokenizer(vocab_path, merge_path); PhoneLMConfig config(tokens_limit, "1.5B"); auto model = PhoneLMForCausalLM_NPU(config, chunk_size); @@ -57,8 +62,13 @@ int main(int argc, char **argv) { static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); // turn on the multi-chunk prefilling Module::isMultiChunkPrefilling = true; + // warmup END std::cout << "Warmup finished." << std::endl; + if (!std::filesystem::exists("qnn_context.bin")) { + static_cast(Backend::global_backends[MLLM_QNN])->saveQNNContext(); + } + vector in_strs = { "Give me a short introduction to large language model.", diff --git a/examples/demo_qwen.cpp b/examples/demo_qwen.cpp index 1c70d52ce..3ef6da59d 100644 --- a/examples/demo_qwen.cpp +++ b/examples/demo_qwen.cpp @@ -39,9 +39,7 @@ int main(int argc, char **argv) { model.load(model_path); vector in_strs = { - "Hello, who are you?", - "What can you do?", - "Please introduce Beijing University of Posts and Telecommunications.", + " Give me a short introduction to large language model.", }; for (int i = 0; i < in_strs.size(); ++i) { auto input_str = tokenizer.apply_chat_template(in_strs[i]); @@ -50,8 +48,8 @@ int main(int argc, char **argv) { std::cout << "[A] " << std::flush; LlmTextGeneratorOpts opt{ - .max_new_tokens = 100, - .do_sample = true, + .max_new_tokens = 1, + .do_sample = false, .temperature = 0.3F, .top_k = 50, .top_p = 0.F, diff --git a/examples/demo_qwen2.5_npu.cpp b/examples/demo_qwen2.5_npu.cpp index 761a34926..b86bef3b9 100644 --- a/examples/demo_qwen2.5_npu.cpp +++ b/examples/demo_qwen2.5_npu.cpp @@ -1,3 +1,5 @@ +#include "QNNBackend.hpp" +#include "Types.hpp" #include "backends/cpu/CPUBackend.hpp" #include "cmdline.h" #include "models/qwen/configuration_qwen.hpp" @@ -12,8 +14,8 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2.5_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2.5_merges.txt"); - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/Qwen2.5-1.5B-Instruct.mllm"); - cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B]", false, "1.8B"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-int8-int32bias-0kproj-test.mllm"); + cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B]", false, "1.5B"); cmdParser.add("limits", 'l', "max KV cache size", false, 400); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); @@ -26,11 +28,14 @@ int main(int argc, char **argv) { CPUBackend::cpu_threads = cmdParser.get("thread"); auto tokenizer = QWenTokenizer(vocab_path, merge_path); - QWenConfig config(tokens_limit, "1.5B", RoPEType::HFHUBROPE); - auto model = QWenForCausalLM_NPU(config, 64); + QWenConfig config(tokens_limit, model_billion, RoPEType::HFHUBROPE); + auto model = v2::QWenForCausalLM_NPU(config, 32); + + Module::initBackend(MLLM_QNN); + model.load(model_path); auto decoding_model = QWenForCausalLM(config); - decoding_model.load("../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"); + decoding_model.load("../models/qwen-2.5-1.5b-instruct-q4_k.mllm"); vector in_strs = { " Give me a short introduction to large language model.", @@ -38,7 +43,7 @@ int main(int argc, char **argv) { for (int i = 0; i < in_strs.size(); ++i) { auto input_str = tokenizer.apply_chat_template(in_strs[i]); - auto [real_seq_length, input_tensor] = tokenizer.tokenizeWithPadding(input_str, 64, config.vocab_size); + auto [real_seq_length, input_tensor] = tokenizer.tokenizeWithPadding(input_str, 32, config.vocab_size); std::cout << "[Q] " << in_strs[i] << std::endl; std::cout << "[A] " << std::flush; @@ -48,9 +53,7 @@ int main(int argc, char **argv) { LlmTextGeneratorOpts opt{ .max_new_tokens = 1, .do_sample = false, - .temperature = 0.3f, - .top_k = 50, - .top_p = 0.f, + .is_padding = true, .seq_before_padding = real_seq_length, }; @@ -67,7 +70,7 @@ int main(int argc, char **argv) { static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); LlmTextGeneratorOpts decoding_opt{ - .max_new_tokens = 100, + .max_new_tokens = 50, .do_sample = false, .temperature = 0.3f, .top_k = 50, @@ -79,6 +82,7 @@ int main(int argc, char **argv) { // call only once of switchDecodeTag if (!isSwitched) { static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + isSwitched = true; } auto out_string = tokenizer.detokenize({out_token}); @@ -96,5 +100,9 @@ int main(int argc, char **argv) { static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); std::cout << "\n"; + + if (!std::filesystem::exists("qnn_context.bin")) { + static_cast(Backend::global_backends[MLLM_QNN])->saveQNNContext(); + } } -} \ No newline at end of file +} diff --git a/examples/demo_qwen2.5_pipeline.cpp b/examples/demo_qwen2.5_pipeline.cpp new file mode 100644 index 000000000..5bc99cfcc --- /dev/null +++ b/examples/demo_qwen2.5_pipeline.cpp @@ -0,0 +1,124 @@ +#include "Backend.hpp" +#include "Trace.hpp" +#include "Types.hpp" +#include "backends/cpu/CPUBackend.hpp" +#include "cmdline.h" +#include "models/qwen/configuration_qwen.hpp" +#include "models/qwen/modeling_qwen_npu.hpp" +#include "models/qwen/modeling_qwen.hpp" +#include "models/qwen/tokenization_qwen.hpp" +#include "processor/PostProcess.hpp" +#include "Parallel.hpp" + +using namespace mllm; + +int main(int argc, char **argv) { + cmdline::parser cmdParser; + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2.5_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2.5_merges.txt"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-int8-test.mllm"); + cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B]", false, "1.5B"); + cmdParser.add("limits", 'l', "max KV cache size", false, 400); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + string model_billion = cmdParser.get("billion"); + int tokens_limit = cmdParser.get("limits"); + const int chunk_size = 128; + CPUBackend::cpu_threads = cmdParser.get("thread"); + + Module::initBackend(MLLM_QNN); + + auto tokenizer = QWenTokenizer(vocab_path, merge_path); + QWenConfig config(tokens_limit, model_billion, RoPEType::HFHUBROPE); + auto model = v2::QWenForCausalLM_NPU(config, chunk_size); + model.load(model_path); + auto decoding_model = QWenForCausalLM(config); + decoding_model.load("../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"); + + string trace_string = " "; + auto [_, input_tensor] = tokenizer.tokenizePaddingByChunk(trace_string, chunk_size, config.vocab_size); + Tracer::trace(&model, {input_tensor}); + std::cout << "Trace and Warmup finished" << std::endl; + + vector in_strs = { + // " Give me a short introduction to large language model.", + "\"Large Language Models (LLMs) are advanced artificial intelligence systems designed to understand and generate human-like text. These models are trained on vast amounts of data, enabling them to perform a wide range of tasks, from answering questions and summarizing text to generating creative content and engaging in conversational dialogue. LLMs like GPT-3 and GPT-4, developed by OpenAI, have set new benchmarks in natural language processing by leveraging deep learning architectures, particularly transformer models, which excel at capturing context and relationships within text. The scalability and versatility of LLMs make them invaluable tools for applications in education, customer service, content creation, and more. However, their deployment also raises ethical considerations, including issues of bias, misinformation, and the potential for misuse. As the field continues to evolve, ongoing research and responsible deployment strategies are essential to harnessing the full potential of these powerful AI systems while mitigating their risks.\"\nGenerate a title based on the above text."}; + + for (int i = 0; i < in_strs.size(); ++i) { + auto input_str = tokenizer.apply_chat_template(in_strs[i]); + auto [real_seq_length, input_tensor] = tokenizer.tokenizePaddingByChunk(input_str, chunk_size, config.vocab_size); + + // set total seq length for HeadLinear execute, which can not get the real seq length from Opts + static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts + static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + + std::cout << "[Q] " << in_strs[i] << std::endl; + std::cout << "[A] " << std::flush; + std::cout << "real_seq_length: " << real_seq_length << std::endl; + + LlmTextGeneratorOpts opt{ + .max_new_tokens = 1, + .do_sample = false, + .is_padding = true, + .seq_before_padding = real_seq_length, + .chunk_size = chunk_size, + }; + + // tensor vectors to save the chunked tensors of the QNN prefilling input + bool isSwitched = false; + + ChunkPipeline pipeline(real_seq_length, chunk_size); + auto prefill_result = pipeline.run(input_tensor, opt, tokenizer, model, isSwitched); + + Module::isMultiChunkPrefilling = true; + Module::isFirstChunk = false; + + static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + + LlmTextGeneratorOpts decoding_opt{ + .max_new_tokens = 100, + .do_sample = false, + .temperature = 0.3f, + .top_k = 50, + .top_p = 0.f, + .is_padding = false, + }; + isSwitched = false; + + Tensor decoding_input; + decoding_input.setBackend(Backend::global_backends[MLLM_CPU]); + decoding_input.setTtype(INPUT_TENSOR); + decoding_input.reshape(1, 1, 1, 1); + decoding_input.setName("input0"); + decoding_input.alloc(); + decoding_input.setDataAt(0, 0, 0, 0, prefill_result->dataAt(0, 0, 0, 0)); + decoding_model.generate(decoding_input, decoding_opt, [&](unsigned int out_token) -> bool { + // call only once of switchDecodeTag + if (!isSwitched) { + static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + isSwitched = true; + } + auto out_string = tokenizer.detokenize({out_token}); + auto [isOk, print_string] = tokenizer.postprocess(out_string); + if (isOk) { + std::cout << print_string << std::flush; + } else { + return false; + } + return true; + }); + + // turn on switching, set sequence length and execution type + static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + std::cout << "\n"; + } +} \ No newline at end of file diff --git a/examples/demo_qwen2_vl.cpp b/examples/demo_qwen2_vl.cpp index 3a23c982a..d28139e5c 100644 --- a/examples/demo_qwen2_vl.cpp +++ b/examples/demo_qwen2_vl.cpp @@ -2,6 +2,7 @@ #include "cmdline.h" #include "models/qwen2_vl/configuration_qwen2_vl.hpp" #include "models/qwen2_vl/modeling_qwen2_vl.hpp" +// #include "models/qwen2_vl/vtp/modeling_qwen2_vl.hpp" #include "models/qwen2_vl/processing_qwen2_vl.hpp" #include "processor/PostProcess.hpp" @@ -11,7 +12,7 @@ int main(int argc, char **argv) { cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2vl_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2vl_merges.txt"); cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); - cmdParser.add("limits", 'l', "max KV cache size", false, 2000); + cmdParser.add("limits", 'l', "max KV cache size", false, 800); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); @@ -25,8 +26,7 @@ int main(int argc, char **argv) { ParamLoader param_loader(model_path); auto processor = Qwen2VLProcessor(vocab_path, merge_path); Qwen2VLConfig config(tokens_limit, "1.5b"); - auto model_config = Qwen2VLConfig(config); - auto model = Qwen2VLModel(model_config); + auto model = Qwen2VLModel(config); model.load(model_path); vector in_imgs = { diff --git a/examples/demo_qwen2_vl_npu.cpp b/examples/demo_qwen2_vl_npu.cpp new file mode 100644 index 000000000..15e7723b5 --- /dev/null +++ b/examples/demo_qwen2_vl_npu.cpp @@ -0,0 +1,185 @@ +#include +#include +#include +#include "QNNBackend.hpp" +#include "Timing.hpp" +#include "Types.hpp" +#include "cmdline.h" +#include "models/qwen2_vl/configuration_qwen2_vl.hpp" +#include "models/qwen2_vl/modeling_qwen2_vl_npu.hpp" +#include "models/qwen2_vl/processing_qwen2_vl.hpp" +#include "processor/PostProcess.hpp" +#include "memory/MemInspect.hpp" + +using namespace mllm; +int main(int argc, char **argv) { + cmdline::parser cmdParser; + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/showui_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/showui_merges.txt"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/showui-w8-fpbias-noshadow-xdl-test.mllm"); + cmdParser.add("limits", 'l', "max KV cache size", false, 1000); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + const string cpu_model_path = "../models/showui-2B-rotated-q40.mllm"; + int tokens_limit = cmdParser.get("limits"); + int thread_num = cmdParser.get("thread"); + CPUBackend::cpu_threads = cmdParser.get("thread"); + + // TODO: add a function to calculate the chunk size + const int chunk_size = 256; + + Module::initBackend(MLLM_QNN); + + ParamLoader param_loader(model_path); + auto processor = Qwen2VLProcessor(vocab_path, merge_path); + Qwen2VLConfig config(tokens_limit, "1.5b-rotated"); + auto model_config = Qwen2VLConfig(config); + model_config.attn_implementation = "eager"; + + auto prefill_embedding = Qwen2VL_ImagePatchAndEmbedding(config); + auto prefill_body = Qwen2VL_PrefillBody(config, chunk_size); + prefill_embedding.load(cpu_model_path); + prefill_body.load(model_path); + + auto decoding_model = Qwen2VL_Decoding_Model(model_config); + decoding_model.load(cpu_model_path); + + vector in_imgs = { + "../assets/showui.png"}; + vector in_strs = { + "Based on the screenshot of the page, I give a text description and you give its corresponding location. The coordinate represents a clickable location [x, y] for an element, which is a relative coordinate on the screenshot, scaled from 0 to 1.<|vision_start|><|image_pad|><|vision_end|>桌面", + }; + + auto &in_str = in_strs[0]; + in_str = processor.tokenizer->apply_chat_template(in_str); + auto input_tensors = processor.process(in_str, in_imgs[0]); + + const int real_seq_length = input_tensors[0].sequence(); + std::cout << "real seq length: " << real_seq_length << std::endl; + + const int num_iter = (real_seq_length + chunk_size - 1) / chunk_size; + std::cout << "num_iter" << num_iter << std::endl; + // padding the position_ids to total chunk length(example: 256*2) for CPUMultimodalRoPEPipeline + prefill_embedding.get_position_ids(input_tensors, chunk_size * num_iter); + + // warm up (still need a warm up as the setup stage is not omitted now) + auto merged_embd_warmup_tensor = Tensor(Backend::global_backends[MLLM_QNN]); + merged_embd_warmup_tensor.reshape(1, 1, chunk_size, 1536); + merged_embd_warmup_tensor.setTtype(INPUT_TENSOR); + merged_embd_warmup_tensor.alloc(); + + merged_embd_warmup_tensor.setTtype(INPUT_TENSOR); + input_tensors.back().setTtype(INPUT_TENSOR); + vector prefill_input = {merged_embd_warmup_tensor, input_tensors.back()}; + + auto warm_start = mllm_time_ms(); + prefill_body(prefill_input); + auto warm_end = mllm_time_ms(); + std::cout << "warm up " << warm_end - warm_start << " ms" << std::endl; + + Module::isFirstChunk = false; + static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + + // set total seq length for HeadLinear execute, which can not get the real seq length from Opts + static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts + static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + + for (auto &t : input_tensors) { + t.setTtype(INPUT_TENSOR); + } + + // 1. get the vit embedding using CPU + auto vit_start = mllm_time_ms(); + auto merged_embd = prefill_embedding(input_tensors); + auto vit_end = mllm_time_ms(); + std::cout << "vit embedding: " << vit_end - vit_start << " ms" << std::endl; + + // free prefill embedding tensor, approximately free 1GB for 59ms + auto begin_free = mllm_time_ms(); + auto &embedding_act = prefill_embedding.activation_tensors; + // go through the activation tensors to get the merged_embd + for (auto iter = embedding_act.begin(); iter != embedding_act.end(); ++iter) { + // std::cout << iter->first << std::endl; + if (iter->first.find("input") != std::string::npos || iter->first.find("index_put") != std::string::npos) { + continue; + } + iter->second->free(); + } + auto end_free = mllm_time_ms(); + std::cout << "free time: " << end_free - begin_free << " ms" << std::endl; + + // 2. QNN LLM Prefill + unsigned int out_token = 0; + auto start_time = mllm_time_ms(); + for (auto i = 0; i < num_iter; ++i) { + // copy the data from merged_embd[0] to merged_embd_warmup_tensor + auto source = merged_embd[0].ptrAt(0, 0, chunk_size * i, 0); + auto dest = prefill_input[0].hostPtr(); + if (i == 0) { + memcpy(dest, source, prefill_input[0].cntSize()); + } + { + memcpy(dest, source, (merged_embd[0].sequence() % chunk_size) * merged_embd[0].dimension() * sizeof(float)); + } + + auto result = prefill_body(prefill_input); + + if (i == 0) { // turn off switching to avoid RoPE h_cnt_ reset to curSequenceLength in next chunk + static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + } + + if (i == 1) { + auto end_time = mllm_time_ms(); + std::cout << "Prefill:" << end_time - start_time << " ms" << std::endl; + + auto outputs = processor.detokenize(result[0], real_seq_length % chunk_size); + auto out_string = outputs.first; + out_token = outputs.second; + auto [not_end, output_string] = processor.tokenizer->postprocess(out_string); + std::cout << output_string << std::flush; + } + } + + chatPostProcessing(out_token, input_tensors[0], {&input_tensors[1], &input_tensors[2]}); + + static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + + // 3. CPU LLM Decoding + for (auto &t : input_tensors) { // set to INPUT_TENSOR to let decoding module update act + t.setTtype(INPUT_TENSOR); + } + + const int last_position_id = input_tensors[3].dataAt(0, 0, 0, real_seq_length - 1); + for (int step = 0; step < 100; step++) { + // use the last position id(no padding position) in decoding + prefill_embedding.get_position_ids(input_tensors, 0, last_position_id + 1 + step); + + auto result = decoding_model(input_tensors); + auto outputs = processor.detokenize(result[0]); + auto out_string = outputs.first; + auto out_token = outputs.second; + auto [not_end, output_string] = processor.tokenizer->postprocess(out_string); + if (!not_end) { break; } + std::cout << output_string << std::flush; + chatPostProcessing(out_token, input_tensors[0], {&input_tensors[1], &input_tensors[2]}); + + if (step == 0) static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + } + + std::cout << std::endl; + + if (!std::filesystem::exists("qnn_context.bin")) { + static_cast(Backend::global_backends[MLLM_QNN])->saveQNNContext(); + } + + return 0; +} \ No newline at end of file diff --git a/examples/demo_qwen_npu.cpp b/examples/demo_qwen_npu.cpp index 9e230f01c..4ac0ede23 100644 --- a/examples/demo_qwen_npu.cpp +++ b/examples/demo_qwen_npu.cpp @@ -1,8 +1,10 @@ -#include "backends/cpu/CPUBackend.hpp" +// #include "QNNBackend.hpp" +// #include "backends/cpu/CPUBackend.hpp" +#include "Backend.hpp" #include "cmdline.h" #include "models/qwen/configuration_qwen.hpp" -#include "models/qwen/modeling_qwen_npu.hpp" #include "models/qwen/modeling_qwen.hpp" +#include "models/qwen/modeling_qwen_npu.hpp" #include "models/qwen/tokenization_qwen.hpp" #include "processor/PostProcess.hpp" @@ -23,12 +25,14 @@ int main(int argc, char **argv) { string model_path = cmdParser.get("model"); string model_billion = cmdParser.get("billion"); int tokens_limit = cmdParser.get("limits"); - const int chunk_size = 128; + const int chunk_size = 32; CPUBackend::cpu_threads = cmdParser.get("thread"); + Module::initBackend(MLLM_QNN); + auto tokenizer = QWenTokenizer(vocab_path, merge_path); QWenConfig config(tokens_limit, model_billion, RoPEType::HFHUBROPE); - auto model = QWenForCausalLM_NPU(config, chunk_size); + auto model = v2::QWenForCausalLM_NPU(config, chunk_size); model.load(model_path); auto decoding_model = QWenForCausalLM(config); decoding_model.load("../models/qwen-1.5-1.8b-chat-q4k.mllm"); @@ -58,9 +62,14 @@ int main(int argc, char **argv) { // warmup END std::cout << "Warmup finished." << std::endl; + // if (!std::filesystem::exists("qnn_context.bin")) { + // static_cast(Backend::global_backends[MLLM_QNN])->saveQNNContext(); + // } + vector in_strs = { - // " Give me a short introduction to large language model.", - "\"Large Language Models (LLMs) are advanced artificial intelligence systems designed to understand and generate human-like text. These models are trained on vast amounts of data, enabling them to perform a wide range of tasks, from answering questions and summarizing text to generating creative content and engaging in conversational dialogue. LLMs like GPT-3 and GPT-4, developed by OpenAI, have set new benchmarks in natural language processing by leveraging deep learning architectures, particularly transformer models, which excel at capturing context and relationships within text. The scalability and versatility of LLMs make them invaluable tools for applications in education, customer service, content creation, and more. However, their deployment also raises ethical considerations, including issues of bias, misinformation, and the potential for misuse. As the field continues to evolve, ongoing research and responsible deployment strategies are essential to harnessing the full potential of these powerful AI systems while mitigating their risks.\"\nGenerate a title based on the above text."}; + " Give me a short introduction to large language model.", + // "\"Large Language Models (LLMs) are advanced artificial intelligence systems designed to understand and generate human-like text. These models are trained on vast amounts of data, enabling them to perform a wide range of tasks, from answering questions and summarizing text to generating creative content and engaging in conversational dialogue. LLMs like GPT-3 and GPT-4, developed by OpenAI, have set new benchmarks in natural language processing by leveraging deep learning architectures, particularly transformer models, which excel at capturing context and relationships within text. The scalability and versatility of LLMs make them invaluable tools for applications in education, customer service, content creation, and more. However, their deployment also raises ethical considerations, including issues of bias, misinformation, and the potential for misuse. As the field continues to evolve, ongoing research and responsible deployment strategies are essential to harnessing the full potential of these powerful AI systems while mitigating their risks.\"\nGenerate a title based on the above text." + }; for (int i = 0; i < in_strs.size(); ++i) { auto input_str = tokenizer.apply_chat_template(in_strs[i]); @@ -114,6 +123,8 @@ int main(int argc, char **argv) { static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + exit(0); + LlmTextGeneratorOpts decoding_opt{ .max_new_tokens = 100, .do_sample = false, diff --git a/examples/demo_qwen_pipeline.cpp b/examples/demo_qwen_pipeline.cpp index f2f8bb8d0..1d632d7df 100644 --- a/examples/demo_qwen_pipeline.cpp +++ b/examples/demo_qwen_pipeline.cpp @@ -30,9 +30,11 @@ int main(int argc, char **argv) { const int chunk_size = 128; CPUBackend::cpu_threads = cmdParser.get("thread"); + Module::initBackend(MLLM_QNN); + auto tokenizer = QWenTokenizer(vocab_path, merge_path); QWenConfig config(tokens_limit, model_billion, RoPEType::HFHUBROPE); - auto model = QWenForCausalLM_NPU(config, chunk_size); + auto model = v2::QWenForCausalLM_NPU(config, chunk_size); model.load(model_path); auto decoding_model = QWenForCausalLM(config); decoding_model.load("../models/qwen-1.5-1.8b-chat-q4k.mllm"); diff --git a/examples/demo_showui.cpp b/examples/demo_showui.cpp index 4349f9872..54bfd809a 100644 --- a/examples/demo_showui.cpp +++ b/examples/demo_showui.cpp @@ -29,8 +29,7 @@ int main(int argc, char **argv) { int max_pixels = 1344 * 28 * 28; auto processor = Qwen2VLProcessor(vocab_path, merge_path, min_pixels, max_pixels); Qwen2VLConfig config(tokens_limit, "1.5b"); - auto model_config = Qwen2VLConfig(config); - auto model = Qwen2VLModel(model_config); + auto model = Qwen2VLModel(config); model.load(model_path); vector in_imgs = { diff --git a/include/OpDefined.hpp b/include/OpDefined.hpp index 982896413..76b8a35c0 100644 --- a/include/OpDefined.hpp +++ b/include/OpDefined.hpp @@ -38,6 +38,7 @@ enum OpType { CONVOLUTION2D, CONVOLUTION3D, VISIONROPE, + MULTIMODALROPEPIP, MULTIMODALROPE, AVGPOOL2D, MAXPOOL2D, @@ -114,6 +115,7 @@ static const vector OpNames = { "Convolution2D", "Convolution3D", "VisonRoPE", + "MultimodalRoPEPipeline", "MultimodalRoPE", "AvgPool2D", "MaxPool2D", @@ -187,6 +189,7 @@ enum TensorFuncType { FUNC_LIKE, FUNC_SCATTERREDUCE, FUNC_APPLY_VISIOROPE, + FUNC_FA2, // models use only FUNC_FUYU_GATHER_EMBD, FUNC_PHI3V_HD_MERGE, diff --git a/include/Types.hpp b/include/Types.hpp index 5fd850ce6..6d3bb4429 100644 --- a/include/Types.hpp +++ b/include/Types.hpp @@ -155,6 +155,7 @@ enum RoPEType { PERSIMMONROPE = 3, HFHUBROPE = 4, MLAROPE = 5, + NTKROPE = 6, }; enum RoPEThetaType { diff --git a/scripts/run_phonelm_qnn.sh b/scripts/run_phonelm_qnn.sh index 818fb2ec2..942c72d9a 100755 --- a/scripts/run_phonelm_qnn.sh +++ b/scripts/run_phonelm_qnn.sh @@ -46,5 +46,5 @@ if [ $? -ne 0 ]; then exit 1 fi -adb push ../bin-arm/demo_phonelm_npu /data/local/tmp/mllm/bin/ +adb push ../bin-arm-qnn/demo_phonelm_npu /data/local/tmp/mllm/bin/ adb shell "cd /data/local/tmp/mllm/bin && export LD_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && export ADSP_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && ./demo_phonelm_npu" \ No newline at end of file diff --git a/scripts/run_qwen2_vl_qnn.sh b/scripts/run_qwen2_vl_qnn.sh new file mode 100755 index 000000000..0af243172 --- /dev/null +++ b/scripts/run_qwen2_vl_qnn.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +adb shell mkdir -p /data/local/tmp/mllm/vocab +adb shell mkdir -p /data/local/tmp/mllm/qnn-lib + +adb push ../vocab/qwen_vocab.mllm /data/local/tmp/mllm/vocab/ + + +if ! adb shell [ -f "/data/local/tmp/mllm/models/showui-w8-fpbias-noshadow-xdl-test.mllm" ]; then + adb push ../models/showui-w8-fpbias-noshadow-xdl-test.mllm "/data/local/tmp/mllm/models/showui-w8-fpbias-noshadow-xdl-test.mllm" +else + echo "showui-w8-fpbias-noshadow-xdl-test file already exists" +fi + + +if ! adb shell [ -f "/data/local/tmp/mllm/models/showui-2B-rotated-q40.mllm" ]; then + adb push ../models/showui-2B-rotated-q40.mllm "/data/local/tmp/mllm/models/showui-2B-rotated-q40.mllm" +else + echo "showui-2B-rotated-q40.mllm file already exists" +fi + +if [ -z "$QNN_SDK_ROOT" ]; then + export QNN_SDK_ROOT=/root/research/dev/mllm/src/backends/qnn/sdk + # export HEXAGON_SDK_ROOT=/root/research/dev/mllm/src/backends/qnn/HexagonSDK/5.4.0 + echo "QNN_SDK_ROOT is set to $QNN_SDK_ROOT" + # exit 1 +else + echo "QNN_SDK_ROOT is set to $QNN_SDK_ROOT" +fi + +ANDR_LIB=$QNN_SDK_ROOT/lib/aarch64-android +OP_PATH=../src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/build +DEST=/data/local/tmp/mllm/qnn-lib + +adb push $ANDR_LIB/libQnnHtp.so $DEST +adb push $ANDR_LIB/libQnnHtpV75Stub.so $DEST +adb push $ANDR_LIB/libQnnHtpPrepare.so $DEST +adb push $ANDR_LIB/libQnnHtpProfilingReader.so $DEST +adb push $ANDR_LIB/libQnnHtpOptraceProfilingReader.so $DEST +adb push $ANDR_LIB/libQnnHtpV75CalculatorStub.so $DEST +adb push $QNN_SDK_ROOT/lib/hexagon-v75/unsigned/libQnnHtpV75Skel.so $DEST +adb push $OP_PATH/aarch64-android/libQnnLLaMAPackage.so $DEST/libQnnLLaMAPackage_CPU.so +adb push $OP_PATH/hexagon-v75/libQnnLLaMAPackage.so $DEST/libQnnLLaMAPackage_HTP.so + + +if [ $? -ne 0 ]; then + echo "adb push failed" + exit 1 +fi +# adb shell "rm /data/local/tmp/mllm/bin/qnn_context.bin" +adb push ../bin-arm-qnn/demo_qwen2_vl_npu /data/local/tmp/mllm/bin/ +adb shell "cd /data/local/tmp/mllm/bin && export LD_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && export ADSP_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && ./demo_qwen2_vl_npu" \ No newline at end of file diff --git a/scripts/run_qwen_qnn.sh b/scripts/run_qwen_qnn.sh index 81a572b2f..5c18b320c 100755 --- a/scripts/run_qwen_qnn.sh +++ b/scripts/run_qwen_qnn.sh @@ -47,5 +47,6 @@ if [ $? -ne 0 ]; then exit 1 fi -adb push ../bin-arm/demo_qwen_npu /data/local/tmp/mllm/bin/ +# adb shell "rm /data/local/tmp/mllm/bin/qnn_context.bin" +adb push ../bin-arm-qnn/demo_qwen_npu /data/local/tmp/mllm/bin/ adb shell "cd /data/local/tmp/mllm/bin && export LD_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && export ADSP_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && ./demo_qwen_npu" \ No newline at end of file diff --git a/src/Layer.hpp b/src/Layer.hpp index 670ffcea0..56b40c3c8 100644 --- a/src/Layer.hpp +++ b/src/Layer.hpp @@ -551,6 +551,15 @@ class KVCache final : public Layer { param_["for_xnn"] = false; init(std::move(name), OpType::KVCACHE); } + explicit KVCache(int head, int hidden, int n_rep, int cache_max, bool fa2, std::string name) { + param_["head"] = head; + param_["hidden"] = hidden; + param_["n_rep"] = n_rep; + param_["cache_max"] = cache_max; + param_["for_xnn"] = false; + param_["fa2"] = fa2; + init(std::move(name), OpType::KVCACHE); + } explicit KVCache(int cache_max, std::string name) { param_["n_rep"] = 1; @@ -580,6 +589,18 @@ class KVCache final : public Layer { init(std::move(name), OpType::KVCACHE); } } + explicit KVCache(int head, int hidden, int n_rep, int cache_max, std::string name, bool npuEnbaled) { + param_["head"] = head; + param_["hidden"] = hidden; + param_["n_rep"] = n_rep; + param_["cache_max"] = cache_max; + param_["for_xnn"] = false; + if (npuEnbaled) { + init(std::move(name), OpType::KVCACHENPU); + } else { + init(std::move(name), OpType::KVCACHE); + } + } Tensor operator()(Tensor input) { auto ts = run({input}, 1); return ts[0]; @@ -708,9 +729,13 @@ class MultimodalRoPE final : public Layer { for (int i = 0; i < mrope_section.size(); i++) { param_["mrope_section_" + std::to_string(i)] = (float)mrope_section[i]; } - init(std::move(name), OpType::MULTIMODALROPE); + if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { + init(std::move(name), OpType::MULTIMODALROPEPIP); + } else { + init(std::move(name), OpType::MULTIMODALROPE); + } } - Tensor operator()(Tensor input, Tensor position_ids) { + Tensor operator()(Tensor input, Tensor &position_ids) { auto ts = run({input, position_ids}, 1); return ts[0]; } @@ -750,8 +775,9 @@ class Position final : public Layer { class Quantize final : public Layer { public: - explicit Quantize(bool isNSHD, std::string name) { + explicit Quantize(bool isNSHD, std::string name, DataType type = MLLM_TYPE_I8) { param_["isNSHD"] = (float)isNSHD; + param_["dtype"] = (float)type; init(std::move(name), OpType::QUANTIZE); } Tensor operator()(Tensor input) { @@ -777,9 +803,10 @@ class Direct final : public Layer { class Dequantize final : public Layer { public: - explicit Dequantize(bool isNSHD, std::string name, bool isFP32 = true) { + explicit Dequantize(bool isNSHD, std::string name, bool isFP32 = true, DataType inType = MLLM_TYPE_I8) { param_["isNSHD"] = (float)isNSHD; param_["isFP32"] = (float)isFP32; + param_["inType"] = (float)inType; init(std::move(name), OpType::DEQUANTIZE); } Tensor operator()(Tensor input) { @@ -875,18 +902,6 @@ class View final : public Layer { } }; -class SubgraphStart final : public Layer { -public: - explicit SubgraphStart(const std::string &name) { - init(name, OpType::SUBGRAPHSTART); - } - - Tensor operator()(Tensor input) { - auto ts = run({input}, 1); - return ts[0]; - } -}; - class Transpose final : public Layer { public: explicit Transpose(std::vector perm, std::string name) { @@ -902,14 +917,30 @@ class Transpose final : public Layer { } }; +class SubgraphStart final : public Layer { +public: + SubgraphStart() = default; + explicit SubgraphStart(const std::string &name) { + init(name, OpType::SUBGRAPHSTART); + } + + Tensor operator()(vector inputs) { + Module::tmp_device = MLLM_QNN; + auto ts = run(inputs, 1); + return ts[0]; + } +}; + class SubgraphFinalize final : public Layer { public: + SubgraphFinalize() = default; explicit SubgraphFinalize(const std::string &name) { init(name, OpType::SUBGRAPHFINALIZE); } - Tensor operator()(Tensor input) { - auto ts = run({input}, 1); + Tensor operator()(vector inputs) { + auto ts = run(inputs, 1); + Module::tmp_device = MLLM_CPU; return ts[0]; } }; @@ -981,7 +1012,6 @@ class NTKRoPE final : public Layer { return op_->clearCache(); } }; -// Only for QNN END } // namespace mllm diff --git a/src/Module.hpp b/src/Module.hpp index 93c1c8dab..d7d9fb9a3 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -130,6 +130,8 @@ class Module { } } } + + // TODO: Deprecated, the module is not backend specific, the backend should be set in the SubGraphStart and SubGraphFinalize void to(BackendType type) { initBackend(type); device_ = type; diff --git a/src/Parallel.hpp b/src/Parallel.hpp index 9603a6107..ea014b88b 100644 --- a/src/Parallel.hpp +++ b/src/Parallel.hpp @@ -22,7 +22,7 @@ class ChunkPipeline { chunk_num = seq_length_padding / chunk_size; } - shared_ptr run(Tensor &input_tensor, LlmTextGeneratorOpts &opt, Tokenizer &tokenizer, Module &model, bool &isSwitched) { + shared_ptr run(Tensor &input_tensor, LlmTextGeneratorOpts &opt, Tokenizer &tokenizer, Module &model, bool &isSwitched, const vector &clean_tensors = {}) { const int num_graph = Tracer::model_.size(); Tensor::tensor_status = TENSOR_STATIC_READY; std::cout << "num_graph: " << num_graph << std::endl; @@ -42,7 +42,7 @@ class ChunkPipeline { return; } // only the last chunk need to execute the last graph - if(i == num_graph - 1 && chunk_id != chunk_num - 1) { + if (i == num_graph - 1 && chunk_id != chunk_num - 1) { return; } // before the first graph, need to refresh the input tensor @@ -70,7 +70,7 @@ class ChunkPipeline { } } auto end_t = mllm_time_us(); - std::cout << "time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; + std::cout << "prefill time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; auto postProcessing = [&](shared_ptr result, shared_ptr &out_result, int real_seq_length) -> unsigned int { assert(result->batch() == 1); @@ -95,6 +95,12 @@ class ChunkPipeline { auto token_idx = postProcessing(result[0], chunked_tensors.back(), real_seq_length); auto out_string = tokenizer.detokenize({token_idx}); std::cout << out_string << std::flush; + + for (auto tensor : clean_tensors) { + tensor->reshape(0, 0, 0, 0); + tensor->alloc(); + } + return chunked_tensors.back(); } }; diff --git a/src/Tensor.cpp b/src/Tensor.cpp index d4104528c..40955d557 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -165,6 +165,9 @@ Tensor &Tensor::to(BackendType backend_type) { // realloc the tensor if (backend_type == MLLM_QNN && device() == MLLM_CPU) { this->free(); + module()->activation_tensors[name()]->setBackend(Backend::global_backends[backend_type]); + this->setBackend(Backend::global_backends[backend_type]); + return *this; } if (backend_type == MLLM_CPU && device() == MLLM_XNNPACK) { module()->activation_tensors[name()]->setBackend(Backend::global_backends[backend_type]); @@ -176,8 +179,7 @@ Tensor &Tensor::to(BackendType backend_type) { this->setBackend(Backend::global_backends[backend_type]); return *this; } - module()->activation_tensors[name()]->setBackend(Backend::global_backends[backend_type]); - this->alloc(); + return *this; }; @@ -194,236 +196,6 @@ std::vector Tensor::runFunc(std::vector out_names, return backend->runFunc(out_names, type, float_args, input_tensors, in_place); } -/* -Tensor &Tensor::getFunc(const std::string &suffix, const TensorFuncType type, - vector float_args, vector other_tensors) { - assert(module() != nullptr); - auto &module_tensors = module()->activation_tensors; - auto &activation_tensors_num = module()->activation_tensors_num; - const std::string next_name = impl_->name_ + "-" + suffix; - // if (module_tensors.find(name_) == module_tensors.end()) { - // module_tensors[name_] = std::shared_ptr(this, [](Tensor *) {}); - // } - if (module_tensors.find(next_name) == module_tensors.end()) { - module_tensors[next_name] = std::make_shared(impl_->backend_); - module_tensors[next_name]->setName(next_name); - module_tensors[next_name]->setModule(module()); - activation_tensors_num[next_name] = 0; - } - if (module()->doLoad) { return *module_tensors[next_name]; } - TensorFunction *func = impl_->backend_->funcCreate(type); - std::vector tensorPtrs = {module_tensors[impl_->name_].get()}; - for (auto &other_tensor : other_tensors) { tensorPtrs.push_back(other_tensor); } -#ifdef DEBUGOPTIME - auto start_t = mllm_time_us(); -#endif - switch (Tensor::tensor_status) { - case TENSOR_STATIC_INIT: { - func->setup({module_tensors[next_name].get()}, tensorPtrs, float_args); - break; - } - case TENSOR_STATIC_READY: { - func->execute({module_tensors[next_name].get()}, tensorPtrs, float_args); - break; - } - case TENSOR_STATIC_TRACE: { - if (impl_->backend_->type() == BackendType::MLLM_CPU) { - Tracer::addTensorFunction(func, tensorPtrs, {module_tensors[next_name].get()}, float_args); - } - break; - } - default: { - } - } - if (Backend::global_backends.size() == 1) { - for (auto input_tensor : tensorPtrs) { - if (activation_tensors_num.find(input_tensor->name()) != activation_tensors_num.end()) { - switch (Tensor::tensor_status) { - case TENSOR_STATIC_INIT: { - activation_tensors_num[input_tensor->name()] += 1; - break; - } - case TENSOR_STATIC_READY: { - activation_tensors_num[input_tensor->name()] -= 1; - break; - } - default: { - } - } - if (activation_tensors_num[input_tensor->name()] == 0 && module_tensors[input_tensor->name()]->sequence() > 1 - && module_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { - module_tensors[input_tensor->name()]->free(); - // std::cout << input_tensor->name() << " |F" << std::endl; - } - } - } - } -#ifdef DEBUGOPTIME - if (Tensor::tensor_status == TENSOR_STATIC_READY) { - auto end_t = mllm_time_us(); - std::cout << next_name << " | " << Tensor::tensor_status - << " time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; - } -#endif -#ifdef DEBUGSAVETENSOR - module_tensors[next_name]->saveNData(); -#endif - return *module_tensors[next_name]; -} - -void Tensor::getFunc(const TensorFuncType type, - vector float_args, vector other_tensors) { - assert(module() != nullptr); - auto &module_tensors = module()->activation_tensors; - auto &activation_tensors_num = module()->activation_tensors_num; - if (module()->doLoad) { return; } - TensorFunction *func = impl_->backend_->funcCreate(type); - std::vector tensorPtrs = {module_tensors[impl_->name_].get()}; - for (auto &other_tensor : other_tensors) { tensorPtrs.push_back(other_tensor); } -#ifdef DEBUGOPTIME - auto start_t = mllm_time_us(); -#endif - switch (Tensor::tensor_status) { - case TENSOR_STATIC_INIT: { - func->setup({}, tensorPtrs, float_args); - break; - } - case TENSOR_STATIC_READY: { - func->execute({}, tensorPtrs, float_args); - break; - } - default: { - } - } - if (Backend::global_backends.size() == 1) { - for (auto input_tensor : tensorPtrs) { - if (activation_tensors_num.find(input_tensor->name()) != activation_tensors_num.end() - // && input_tensor->dimension() * input_tensor->sequence() > 0 - ) { - switch (Tensor::tensor_status) { - case TENSOR_STATIC_INIT: { - activation_tensors_num[input_tensor->name()] += 1; - break; - } - case TENSOR_STATIC_READY: { - activation_tensors_num[input_tensor->name()] -= 1; - break; - } - default: { - } - } - if (activation_tensors_num[input_tensor->name()] == 0 && module_tensors[input_tensor->name()]->sequence() > 1 - && module_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { - module_tensors[input_tensor->name()]->free(); - // std::cout << input_tensor->name() << " |F" << std::endl; - } - } - } - } -#ifdef DEBUGOPTIME - if (Tensor::tensor_status == TENSOR_STATIC_READY) { - auto end_t = mllm_time_us(); - std::cout << " | " << Tensor::tensor_status - << " time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; - } -#endif -} - -std::vector> Tensor::getStaticFunc(vector out_names, - const TensorFuncType type, - vector float_args, - vector input_tensors) { - Module *module; - if (!input_tensors.empty()) { - module = input_tensors[0]->module(); - } else { - module = Module::llm_model_ptr; - } - assert(module != nullptr); - auto &module_tensors = module->activation_tensors; - auto &activation_tensors_num = module->activation_tensors_num; - auto *backend_h = Backend::global_backends[MLLM_CPU]; - if (!input_tensors.empty() && input_tensors[0]->impl_->backend_ != nullptr) { - backend_h = input_tensors[0]->backend(); - } - for (auto out_name : out_names) { - if (module_tensors.find(out_name) == module_tensors.end()) { - module_tensors[out_name] = std::make_shared(backend_h); - module_tensors[out_name]->setName(out_name); - module_tensors[out_name]->setModule(module); - activation_tensors_num[out_name] = 0; - } - } - if (module->doLoad) { - std::vector> results; - for (auto out_name : out_names) { results.push_back(*module_tensors[out_name]); } - return results; - } - TensorFunction *func = backend_h->funcCreate(type); - // std::vector tensorPtrs; - // for (auto input_tensor : input_tensors){ tensorPtrs.push_back(module_tensors[input_tensor->name()].get()); } - std::vector outPtrs; - for (auto out_name : out_names) { outPtrs.push_back(module_tensors[out_name].get()); } -#ifdef DEBUGOPTIME - auto start_t = mllm_time_us(); -#endif - switch (Tensor::tensor_status) { - case TENSOR_STATIC_INIT: { - func->setup(outPtrs, input_tensors, float_args); - break; - } - case TENSOR_STATIC_READY: { - func->execute(outPtrs, input_tensors, float_args); - break; - } - case TENSOR_STATIC_TRACE: { - if (backend_h->type() == BackendType::MLLM_CPU) { - Tracer::addTensorFunction(func, input_tensors, outPtrs, float_args); - } - break; - } - default: { - } - } - if (Backend::global_backends.size() == 1) { - for (auto input_tensor : input_tensors) { - if (activation_tensors_num.find(input_tensor->name()) != activation_tensors_num.end()) { - switch (Tensor::tensor_status) { - case TENSOR_STATIC_INIT: { - activation_tensors_num[input_tensor->name()] += 1; - break; - } - case TENSOR_STATIC_READY: { - activation_tensors_num[input_tensor->name()] -= 1; - break; - } - default: { - } - } - if (activation_tensors_num[input_tensor->name()] == 0 && module_tensors[input_tensor->name()]->sequence() > 1 - && module_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { - module_tensors[input_tensor->name()]->free(); - // std::cout << input_tensor->name() << " |S "<< std::endl;// << out_names[0] << std::endl; - } - } - } - } -#ifdef DEBUGOPTIME - if (Tensor::tensor_status == TENSOR_STATIC_READY) { - auto end_t = mllm_time_us(); - std::cout << out_names[0] << " | " << Tensor::tensor_status - << " time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; - } -#endif -#ifdef DEBUGSAVETENSOR - for (auto out_name : out_names) { module_tensors[out_name]->saveNData(); } -#endif - std::vector> results; - for (auto out_name : out_names) { results.push_back(*module_tensors[out_name]); } - return results; -} -*/ - Tensor Tensor::operator+(float data) { return runFunc({name() + "-add"}, FUNC_ADD, {data}, {std::shared_ptr(this, [](Tensor *) {})})[0]; @@ -537,6 +309,17 @@ Tensor Tensor::clip(Chl keep_axis, vector b, vector h, vector s, {std::shared_ptr(this, [](Tensor *) {})})[0]; } +Tensor Tensor::clip(vector index, Chl dim) { + Tensor index_tensor(1, 1, 1, index.size(), impl_->backend_, false); + index_tensor.alloc(); + for (size_t i = 0; i < index.size(); ++i) { + index_tensor.setDataAt(0, 0, 0, i, static_cast(index[i])); + } + index_tensor.setName(name() + "-cliptensor-index"); + return runFunc({name() + "-cliptensor"}, FUNC_CLIPTENSOR, {(float)dim}, + {std::shared_ptr(this, [](Tensor *) {}), + std::shared_ptr(&index_tensor, [](Tensor *) {})})[0]; +} Tensor Tensor::clip(Tensor index, Chl dim) { return runFunc({name() + "-cliptensor"}, FUNC_CLIPTENSOR, {(float)dim}, {std::shared_ptr(this, [](Tensor *) {}), @@ -638,6 +421,13 @@ Tensor Tensor::zero_like(Tensor input) { return runFunc({input.name() + "-zero_like"}, FUNC_LIKE, {0.0}, {std::shared_ptr(&input, [](Tensor *) {})})[0]; } +Tensor Tensor::flash_attention2_forward(Tensor q, Tensor k, Tensor v, bool causal_mask) { + Module *module = q.module(); + return runFunc({q.name() + "-" + k.name() + "-fa2"}, FUNC_FA2, {causal_mask ? 1.0f : 0.0f}, + {std::shared_ptr(&q, [](Tensor *) {}), + std::shared_ptr(&k, [](Tensor *) {}), + std::shared_ptr(&v, [](Tensor *) {})})[0]; +}; Tensor Tensor::apply_rotary_pos_emb_vision(Tensor input, Tensor rotary_pos_emb) { Module *module = input.module(); return runFunc({input.name() + "-apply_rotary_pos_emb"}, FUNC_APPLY_VISIOROPE, diff --git a/src/Tensor.hpp b/src/Tensor.hpp index 429fedd7f..c21518d59 100644 --- a/src/Tensor.hpp +++ b/src/Tensor.hpp @@ -769,6 +769,7 @@ class Tensor { Tensor transpose(vector> axiss); Tensor clip(vector b, vector h, vector s, vector d); Tensor clip(Chl keep_axis, vector b, vector h, vector s, vector d); + Tensor clip(vector index, Chl dim); Tensor clip(Tensor index, Chl dim); Tensor expand(int b, int h, int s, int d); static Tensor cat(vector input_tensors, Chl dims); @@ -788,6 +789,7 @@ class Tensor { Tensor bincount(); Tensor repeat(Chl dim, int dim_size); static Tensor zero_like(Tensor input); + static Tensor flash_attention2_forward(Tensor q, Tensor k, Tensor v, bool is_causal = true); static Tensor apply_rotary_pos_emb_vision(Tensor input, Tensor rotary_pos_emb); // models use only @@ -1587,6 +1589,89 @@ class Tensor { outFile.close(); } + template + void saveIntData(string ex = "") { + if (Tensor::tensor_status != TENSOR_STATIC_READY) return; + if (ctype() == BTHWC || ctype() == BCTHW) { + save5Data(ex); + return; + } + // std::filesystem::create_directory("save_out"); + string directory = "save_out"; + struct stat info; +#ifdef _WIN32 + _mkdir(directory.c_str()); +#else + if (stat(directory.c_str(), &info) != 0) { + if (stat(directory.c_str(), &info) != 0) { + mkdir(directory.c_str(), 0777); // notice that 0777 is different than usual + } else if (!(info.st_mode & S_IFDIR)) { + // if the path exists but it is not a directory, also create it + mkdir(directory.c_str(), 0777); // notice that 0777 is different than usual + } + } +#endif + std::ofstream outFile(directory + "/" + name() + ex + ".log"); + outFile << "----------------------------------------" << std::endl; + if (impl_->ctype_ == BSHD) { + outFile << name() << ": [BSHD]shape:[" << batch() << " " << sequence() << " " << head() << " " << dimension() << "] " << dtype() << " " << ctype() << std::endl; + } else { + outFile << name() << ": shape:[" << batch() << " " << head() << " " << sequence() << " " << dimension() << "] " << dtype() << " " << ctype() << std::endl; + } + + int N = batch(); + int C = head(); + int H = sequence(); + int W = dimension(); + if (impl_->ctype_ == BSHD) { + for (int n = 0; n < batch(); ++n) { + for (int h = 0; h < sequence(); ++h) { + for (int c = 0; c < head(); ++c) { + for (int w = 0; w < dimension(); ++w) { + outFile << (int)dataAt(n, c, h, w) << " "; + } + outFile << std::endl; + } + outFile << std::endl; + } + outFile << std::endl; + } + outFile.close(); + return; + } + if (N == 1 && C == 1) { + for (int h = 0; h < H; ++h) { + for (int c = 0; c < W; ++c) { + outFile << std::fixed << std::setprecision(6) << dataAt(0, 0, h, c) << " "; + } + outFile << std::endl; + outFile << "---------" << std::endl; + } + } else if (N == 1 && W == 1) { + for (int h = 0; h < H; ++h) { + for (int c = 0; c < C; ++c) { + outFile << std::fixed << std::setprecision(6) << dataAt(0, c, h, 0) << " "; + } + outFile << std::endl; + } + } else { + for (int n = 0; n < N; ++n) { + for (int h = 0; h < H; ++h) { + for (int c = 0; c < C; ++c) { + for (int w = 0; w < W; ++w) { + outFile << std::fixed << std::setprecision(6) << dataAt(n, c, h, w) << " "; + } + outFile << std::endl; + } + outFile << std::endl; + } + outFile << std::endl; + } + } + + outFile.close(); + } + template void saveNData(string new_name = "", string ex = "") { if (Tensor::tensor_status == TENSOR_STATIC_READY && !shape().empty()) { diff --git a/src/Trace.cpp b/src/Trace.cpp index 5e1f51ac3..18b57f833 100644 --- a/src/Trace.cpp +++ b/src/Trace.cpp @@ -41,10 +41,12 @@ void Tracer::addTensorFunction(TensorFunction *func, } void Tracer::trace(Module *model, vector inputs) { - inputs[0].setTtype(TensorType::NORMAL_TENSOR); - model->activation_tensors[inputs[0].name()] = std::shared_ptr(&inputs[0], [](Tensor *) {}); - model->activation_tensors[inputs[0].name()]->setName(inputs[0].name()); - model->activation_tensors[inputs[0].name()]->setModule(model); + for(auto& input : inputs) { + input.setTtype(TensorType::NORMAL_TENSOR); + model->activation_tensors[input.name()] = std::shared_ptr(&input, [](Tensor *) {}); + model->activation_tensors[input.name()]->setName(input.name()); + model->activation_tensors[input.name()]->setModule(model); + } Module::llm_model_ptr = model; diff --git a/src/backends/cpu/CPUBackend.cpp b/src/backends/cpu/CPUBackend.cpp index df4e81ed6..92d6ed6e5 100644 --- a/src/backends/cpu/CPUBackend.cpp +++ b/src/backends/cpu/CPUBackend.cpp @@ -11,6 +11,7 @@ #include "op/CPUHeadLinear.hpp" #include "op/CPULinearInt8.hpp" +#include "op/CPUMultimodalRoPEPipeline.hpp" #include "op/CPUNTKRoPE.hpp" #include "op/CPUPoEmbedding.hpp" #include "op/CPUSplitInput.hpp" @@ -88,7 +89,8 @@ #include "function/CPURepeatFunc.hpp" #include "function/CPULikeFunc.hpp" #include "function/CPUScatterReduceFunc.hpp" -#include "function/CPUApplyVisionRoPE.hpp" +#include "function/CPUVisionRoPEFunc.hpp" +#include "function/CPUFlashAttention2Func.hpp" #include "function/CPUFuyuGatherEmbdFunc.hpp" #include "function/CPUPhi3VhdmergeFunc.hpp" @@ -97,16 +99,17 @@ namespace mllm { class CPUBackendCreator : public BackendCreator { Backend *create(BackendConfig config) { shared_ptr mm = nullptr; - switch (config.memory) { - case BackendConfig::Memory_High: - // mm = std::make_shared(); - mm = std::make_shared(); // todomm - break; - default: - // mm = std::make_shared(); - mm = std::make_shared(); // todomm - break; - } + mm = std::make_shared(); // todomm + // switch (config.memory) { + // case BackendConfig::Memory_High: + // mm = std::make_shared(); + // // mm = std::make_shared(); // todomm + // break; + // default: + // mm = std::make_shared(); + // // mm = std::make_shared(); // todomm + // break; + // } return new CPUBackend(mm); }; }; @@ -164,8 +167,8 @@ void CPUBackend::registerOps() { addCreator(MAXPOOL2D, (CPUBackend::Creator *)(new CPUMaxPoolCreator())); addCreator(CONVOLUTION3D, (CPUBackend::Creator *)(new CPUConvolution3DCreator())); addCreator(VISIONROPE, (CPUBackend::Creator *)(new CPUVisionRoPECreator())); + addCreator(MULTIMODALROPEPIP, (CPUBackend::Creator *)(new CPUMultimodalRoPEPipelineCreator())); addCreator(MULTIMODALROPE, (CPUBackend::Creator *)(new CPUMultimodalRoPECreator())); - // addCreator(CAT, (CPUBackend::Creator *)(new CPUCatCreator())); addCreator(TRANSPOSE, (CPUBackend::Creator *)(new CPUTransposeCreator())); addCreator(SUBDIM, (CPUBackend::Creator *)(new CPUSubDimCreator())); addCreator(DIVISION, (CPUBackend::Creator *)(new CPUDivisionCreator())); @@ -230,7 +233,8 @@ void CPUBackend::registerFuncs() { map_function_[TensorFuncType::FUNC_REPEAT] = new CPUrepeatFunction(); map_function_[TensorFuncType::FUNC_LIKE] = new CPUlikeFunction(); map_function_[TensorFuncType::FUNC_SCATTERREDUCE] = new CPUScatterReduceFunction(); - map_function_[TensorFuncType::FUNC_APPLY_VISIOROPE] = new CPUApplyVisionRoPEFunction(); + map_function_[TensorFuncType::FUNC_APPLY_VISIOROPE] = new CPUVisionRoPEFuncFunction(); + map_function_[TensorFuncType::FUNC_FA2] = new CPUFlashAttention2Func(); // models use only map_function_[TensorFuncType::FUNC_FUYU_GATHER_EMBD] = new CPUFuyuGatherEmbdFunc(); map_function_[TensorFuncType::FUNC_PHI3V_HD_MERGE] = new CPUPhi3VhdmergeFunction(); diff --git a/src/backends/cpu/compute/FlashAttention2.hpp b/src/backends/cpu/compute/FlashAttention2.hpp new file mode 100644 index 000000000..ee10fc3ff --- /dev/null +++ b/src/backends/cpu/compute/FlashAttention2.hpp @@ -0,0 +1,3077 @@ + +#ifndef MLLM_FA2_CAL_HPP +#define MLLM_FA2_CAL_HPP + +// #include +// #include +// #include +#ifdef __AVX2__ +#include +#include +#include +#include +#include +#include +#include +#include "Types.hpp" +#include "VecDot.hpp" + +namespace mobi_attn { + +// ======================================== +// 数学函数和工具 +// ======================================== +#define NEG_INF std::numeric_limits::lowest() +// Horizontal max of a __m256 vector +inline float _mm256_hmax_ps(__m256 x) { + __m128 lo = _mm256_castps256_ps128(x); + __m128 hi = _mm256_extractf128_ps(x, 1); + __m128 max_val = _mm_max_ps(lo, hi); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 2, 2))); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 0, 1))); + return _mm_cvtss_f32(max_val); +} + +// Horizontal sum of a __m256 vector +inline float _mm256_hadd_ps(__m256 x) { + __m128 lo = _mm256_castps256_ps128(x); + __m128 hi = _mm256_extractf128_ps(x, 1); + __m128 sum = _mm_add_ps(lo, hi); + sum = _mm_hadd_ps(sum, sum); + sum = _mm_hadd_ps(sum, sum); + return _mm_cvtss_f32(sum); +} + +// ======================================== +// 内存对齐分配函数 +// ======================================== +// 使用 posix_memalign 进行分配 +void x86_align_alloc(void **ptr, size_t required_bytes, size_t align) { + // posix_memalign 要求 alignment 必须是 void* 大小的整数倍,并且是 2 的幂 + if (align % sizeof(void *) != 0 || (align & (align - 1)) != 0) { + *ptr = nullptr; + return; + } + + // posix_memalign 返回 0 表示成功,否则返回错误码 + if (posix_memalign(ptr, align, required_bytes) != 0) { + *ptr = nullptr; + } +} + +// 直接使用标准 free 进行释放 +void x86_align_free(void *ptr) { + free(ptr); +} + +// ======================================== +// FlashAttention2 核心实现 (FP32版本) +// ======================================== +struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { + using dtype_q_in_t = float; + using dtype_kv_in_t = dtype_q_in_t; + using dtype_out_t = dtype_q_in_t; + using dtype_t = dtype_out_t; + using acc_dtype_t = float; + // 添加配置参数作为成员变量 + int32_t Br; + int32_t Bc; + int32_t Q_Head; + int32_t KV_Head; + int32_t threads; + bool high_precision; + // 配置参数初始化 + void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_, bool high_precision_) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_Head_; + KV_Head = KV_Head_; + threads = threads_; + high_precision = high_precision_; + } + + void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, + acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum) { + acc_o_ = acc_o; + acc_s_ = acc_s; + logsum_ = logsum; + scoremax_ = scoremax; + scoremax_prev_ = scoremax_prev; + score_scale_ = score_scale; + score_sum_ = score_sum; + } + + // 核心计算函数 + inline void __fa2_prefill_append(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, // head_size 就是 Q_Head + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + const int32_t Tr = seq_size_q / Br; + const int32_t Tr_left = seq_size_q % Br; + const int32_t Tc = seq_size_k / Bc; + const int32_t Tc_left = seq_size_k % Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + + // 【关键修改 1】计算Q头与KV头的分组对应关系 + const int32_t kv_group_size = Q_Head / KV_Head; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { // h_idx 是当前Q头的索引 + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + + // 【关键修改 1】计算当前Q头 (h_idx) 对应的KV头索引 + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + // --- 主循环 (Tr) --- + for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, + acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + // Q 的指针计算保持不变,因为它有 Q_Head 个头 + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; + + // 【关键修改 2】K 和 V 的指针计算,必须使用 KV_Head 和映射后的 this_thread_kv_head + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + + // 【关键修改 3】为 mma0 传入Q和K各自的正确步长 + mma0(tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + // 【关键修改 3】为 mma1 传入 KV_Head 作为V的头数量,用于计算其内部步长 + mma1(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Br, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Br, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Br, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Br, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); + } + if (Tr_left) { + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Tr_left, Bc, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Tr_left, Bc, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Tr_left, Bc, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Tr_left, Bc, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Tr_left, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Tr_left, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store_pa_n_fixed(Tr_left, acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size, Tr, head_size, dim_size); + } + } + } + } + + inline void __fa2_decode(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + const int32_t Tr = 1; + const int32_t Tc = seq_size_k / Bc; + const int32_t Tc_left = seq_size_k % Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + // FIX: Calculate the ratio of Q_Head to KV_Head to handle GQA/MHA correctly. + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + // FIX: Map the current query head 'h_idx' to its corresponding KV head. + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { + init_temp_d(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; + // FIX: Corrected pointer arithmetic for K and V. + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + + mma0_d(tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax_d(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale_d(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1_d(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_d_n_fixed(Tc_left, tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_d_n_fixed(Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_d_n_fixed(Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_d_n_fixed(Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store_d(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); + } + } + } + } + + void fa2(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, const int32_t batch_size, + const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + assert(Br == Bc); + // assert(Br % 4 == 0); + // FIX: Assert that Q_Head is a multiple of KV_Head for valid GQA/MHA. + assert(Q_Head % KV_Head == 0); + assert(head_size % threads == 0); + assert(dim_size % 8 == 0); // AVX processes 8 floats at a time + + if (seq_size_q != 1) { + __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, + causal_mask); + } else { + __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, + causal_mask); + } + } + +private: + // inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, + // const int32_t dim_size) { + // __m256 zero_vec = _mm256_set1_ps(0.0f); + // __m256 neg_inf_vec = _mm256_set1_ps(NEG_INF); + + // for (int i = 0; i < Br; i += 8) { _mm256_storeu_ps(logsum + i, zero_vec); } + // for (int i = 0; i < Br; i += 8) { _mm256_storeu_ps(scoremax + i, neg_inf_vec); } + // for (int i = 0; i < Br * dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } + // } + + inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { + __m256 zero_vec = _mm256_set1_ps(0.0f); + __m256 neg_inf_vec = _mm256_set1_ps(NEG_INF); + + // 【最终修正】使用安全的循环来确保完全初始化,不再依赖Br是8的倍数 + int i = 0; + for (; i <= Br - 8; i += 8) { + _mm256_storeu_ps(logsum + i, zero_vec); + _mm256_storeu_ps(scoremax + i, neg_inf_vec); + } + // 处理剩余的元素(如果Br不是8的倍数) + for (; i < Br; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF; + } + + // acc_o 的初始化是安全的,因为调用者保证了 dim_size % 8 == 0 + for (int j = 0; j < Br * dim_size; j += 8) { + _mm256_storeu_ps(acc_o + j, zero_vec); + } + } + + // 【关键修改】函数签名增加 kv_stride_size 参数,用于区分Q和K的步长 + inline void mma0(const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t q_stride_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + +#pragma unroll + for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + // 【关键修改】使用传入的 q_stride_size + const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; +#pragma unroll + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + // 【关键修改】使用传入的 kv_stride_size + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + __builtin_prefetch(q_block_line + i + 64); + __builtin_prefetch(k_block_line + i + 64); + __m256 q_vec = _mm256_loadu_ps(q_block_line + i); + __m256 k_vec = _mm256_loadu_ps(k_block_line + i); + sum_vec = _mm256_fmadd_ps(q_vec, k_vec, sum_vec); + } + acc_dtype_t total = _mm256_hadd_ps(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + + if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { + for (int i = 0; i < Br; ++i) { + for (int j = 0; j < Bc; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } + } + + inline void softmax(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); + for (int br = 0; br < Br; ++br) { + __m256 max_vec = _mm256_set1_ps(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 8; bc += 8) { max_vec = _mm256_max_ps(max_vec, _mm256_loadu_ps(row + bc)); } + float max_val = _mm256_hmax_ps(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } + for (int br = 0; br < Br; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } + for (int br = 0; br < Br; ++br) { + const float sm = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((row[bc] - sm) * scale); + row[bc] = val; + sum += val; + } + score_sum[br] = sum; + } + for (int br = 0; br < Br; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } + } + + inline void rescale(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + +#pragma unroll + for (int i = 0; i < Br; ++i) { + __m256 scale_v = _mm256_set1_ps(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 8) { + __m256 acc = _mm256_loadu_ps(row_ptr + j); + acc = _mm256_mul_ps(acc, scale_v); + _mm256_storeu_ps(row_ptr + j, acc); + } + } + } + + // 【关键修改】函数签名增加 kv_head_size 参数,用于计算V的内部步长 + inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + + // 【关键修改】使用传入的 kv_head_size 来计算 V 的步长 + const int32_t v_stride_size = kv_head_size * dim_size; + +#pragma unroll + for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + b_r_idx * dim_size + d_base); +#pragma unroll + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + __m256 w_vec = _mm256_set1_ps(w_block[b_r_idx * Bc + b_c_idx]); + // 【关键修改】使用计算出的 v_stride_size + const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + __m256 v_vec = _mm256_loadu_ps(v_ptr); + acc = _mm256_fmadd_ps(w_vec, v_vec, acc); + } + _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); + } + } + } + + inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, + dtype_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { +#pragma unroll + for (int i = 0; i < Br; ++i) { + dtype_t *o_block_line = o_block + i * head_size * dim_size; + __m256 reciprocal_logsum_vec = _mm256_set1_ps(1.0f / logsum[i]); + int j = 0; + for (; j <= dim_size - 8; j += 8) { + __m256 vec_acc_o = _mm256_loadu_ps(acc_o + i * dim_size + j); + __m256 result_vec = _mm256_mul_ps(vec_acc_o, reciprocal_logsum_vec); + _mm256_storeu_ps(o_block_line + j, result_vec); + } + float reciprocal_logsum = 1.0f / logsum[i]; + for (; j < dim_size; ++j) { + o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; + } + } + } + + // N-fixed functions for handling leftovers + // FIX: Modified mma0_pa_n_fixed to accept separate strides. + inline void mma0_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const dtype_t *__restrict__ q_block, + const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, + const int32_t dim_size, const int32_t q_stride_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br_n_fixed; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + + for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + sum_vec = _mm256_fmadd_ps(_mm256_loadu_ps(q_block_line + i), _mm256_loadu_ps(k_block_line + i), sum_vec); + } + acc_dtype_t total = _mm256_hadd_ps(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + + if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { + for (int i = 0; i < Br_n_fixed; ++i) { + for (int j = 0; j < Bc_n_fixed; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } + } + + inline void softmax_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, + acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, + acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float max_val = NEG_INF; + for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, row[bc]); + scoremax[br] = fmaxf(max_val, scoremax[br]); + } + for (int br = 0; br < Br_n_fixed; ++br) { + score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); + } + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + float val = expf((row[bc] - scoremax[br]) * scale); + row[bc] = val; + current_sum += val; + } + score_sum[br] = current_sum; + } + for (int br = 0; br < Br_n_fixed; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } + } + + inline void rescale_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_o, + acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + + for (int i = 0; i < Br_n_fixed; ++i) { + float *row_ptr = acc_o + i * dim_size; + __m256 scale_v = _mm256_set1_ps(score_scale[i]); + for (int j = 0; j < dim_size; j += 8) { + _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + j), scale_v)); + } + } + } + + // FIX: Modified mma1_pa_n_fixed to accept kv_head_size. + inline void mma1_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const acc_dtype_t *__restrict__ w_block, + const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, + const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + + const int32_t v_stride_size = kv_head_size * dim_size; + + for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + __m256 w_vec = _mm256_set1_ps(w_block[b_r_idx * Bc + b_c_idx]); + const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = _mm256_fmadd_ps(w_vec, _mm256_loadu_ps(v_ptr), acc); + } + _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); + } + } + } + + inline void scale_and_store_pa_n_fixed(const int32_t Br_n_fixed, + const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, + dtype_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + dtype_t *o_block_line = o_block + i * head_size * dim_size; + float reciprocal_logsum = 1.0f / logsum[i]; + __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 8; j += 8) { + __m256 vec_acc_o = _mm256_loadu_ps(acc_o + i * dim_size + j); + _mm256_storeu_ps(o_block_line + j, _mm256_mul_ps(vec_acc_o, reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { + o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; + } + } + } + + // Decode mode functions + inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, + const int32_t dim_size) { + logsum[0] = 0.0f; + scoremax[0] = NEG_INF; + __m256 zero_vec = _mm256_setzero_ps(); + for (int i = 0; i < 1 * dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } + } + + // FIX: Modified mma0_d to accept kv_stride_size. + inline void mma0_d(const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const dtype_t *q_block_line = q_block; +#pragma unroll + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + sum_vec = _mm256_fmadd_ps(_mm256_loadu_ps(q_block_line + i), _mm256_loadu_ps(k_block_line + i), sum_vec); + } + acc_dtype_t total = _mm256_hadd_ps(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + acc_s[b_c_idx] = total; + } + } + + inline void softmax_d(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, + acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, + acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, + const int32_t t_r_idx, + const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + scoremax_prev[0] = scoremax[0]; + float max_val = NEG_INF; + for (int bc = 0; bc < Bc; ++bc) max_val = fmaxf(max_val, acc_s[bc]); + scoremax[0] = fmaxf(max_val, scoremax[0]); + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + float current_sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + __m256 scale_v = _mm256_set1_ps(score_scale[0]); + for (int j = 0; j < dim_size; j += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + j); + acc = _mm256_mul_ps(acc, scale_v); + _mm256_storeu_ps(acc_o + j, acc); + } + } + + // FIX: Modified mma1_d to accept kv_head_size. + inline void mma1_d(const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + __m256 w_vec = _mm256_set1_ps(w_block[b_c_idx]); + const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = _mm256_fmadd_ps(w_vec, _mm256_loadu_ps(v_ptr), acc); + } + _mm256_storeu_ps(acc_o + d_base, acc); + } + } + + inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, + dtype_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { + float reciprocal_logsum = 1.0f / logsum[0]; + __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 8; j += 8) { + _mm256_storeu_ps(o_block + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { + o_block[j] = acc_o[j] * reciprocal_logsum; + } + } + + // Decode n-fixed functions + // FIX: Modified mma0_d_n_fixed to accept kv_stride_size. + inline void mma0_d_n_fixed(const int32_t Bc_n_fixed, const dtype_t *__restrict__ q_block, + const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, + const int32_t dim_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const dtype_t *q_block_line = q_block; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float total = 0.0f; + for (int i = 0; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + acc_s[b_c_idx] = total; + } + } + + inline void softmax_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_s, + acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, + acc_dtype_t *logsum, + const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + scoremax_prev[0] = scoremax[0]; + float max_val = NEG_INF; + for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, acc_s[bc]); + scoremax[0] = fmaxf(max_val, scoremax[0]); + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + inline void rescale_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_o, + acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + float scale = score_scale[0]; + for (int j = 0; j < dim_size; ++j) { + acc_o[j] *= scale; + } + } + + // FIX: Modified mma1_d_n_fixed to accept kv_head_size. + inline void mma1_d_n_fixed(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, + const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, + const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, + const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; ++d_base) { + float acc = acc_o[d_base]; + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + acc += w_block[b_c_idx] * v_block[b_c_idx * v_stride_size + d_base]; + } + acc_o[d_base] = acc; + } + } + +private: + acc_dtype_t *acc_o_; + acc_dtype_t *acc_s_; + acc_dtype_t *logsum_; + acc_dtype_t *scoremax_; + acc_dtype_t *scoremax_prev_; + acc_dtype_t *score_scale_; + acc_dtype_t *score_sum_; +}; + +// ======================================== +// FlashAttention2 核心实现 ( Q FP32/KV FP16 输入,FP32 输出版本) +// ======================================== +struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { + // 【修改】定义多种输入类型 + using dtype_q_in_t = float; + using dtype_kv_in_t = mllm_fp16_t; + using dtype_out_t = float; + using acc_dtype_t = float; + + int32_t Br, Bc, Q_Head, KV_Head, threads; + bool high_precision; + + void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_, bool high_precision_) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_Head_; + KV_Head = KV_Head_; + threads = threads_; + high_precision = high_precision_; + } + + void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, + acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum) { + acc_o_ = acc_o; + acc_s_ = acc_s; + logsum_ = logsum; + scoremax_ = scoremax; + scoremax_prev_ = scoremax_prev; + score_scale_ = score_scale; + score_sum_ = score_sum; + } + + void fa2(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, const int32_t batch_size, + const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + assert(Br == Bc); + // assert(Br % 4 == 0); + assert(head_size % threads == 0); + assert(dim_size % 8 == 0); + + if (seq_size_q != 1) { + __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } else { + __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } + } + +private: + inline void __fa2_prefill_append(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + const int32_t Tr = seq_size_q / Br; + const int32_t Tr_left = seq_size_q % Br; + const int32_t Tc = seq_size_k / Bc; + const int32_t Tc_left = seq_size_k % Tc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +// Note: OpenMP is not applied to the head_size loop in the prefill reference +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, + acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + + mma0(tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Br, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Br, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Br, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Br, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); + } + if (Tr_left) { + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Tr_left, Bc, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Tr_left, Bc, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Tr_left, Bc, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Tr_left, Bc, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Tr_left, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Tr_left, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store_pa_n_fixed(Tr_left, acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size, Tr, head_size, dim_size); + } + } + } + } + + inline void __fa2_decode(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + const int32_t Tr = 1; // In decode, seq_size_q is always 1 + const int32_t Tc = seq_size_k / Bc; + const int32_t Tc_left = seq_size_k % Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + // In decode mode, t_r_idx is always 0 as we process one token + const int t_r_idx = 0; + init_temp_d(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + + mma0_d(tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax_d(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale_d(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1_d(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_d_n_fixed(Tc_left, tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_d_n_fixed(Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_d_n_fixed(Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_d_n_fixed(Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store_d(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); + } + } + } + + inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { + __m256 zero_vec = _mm256_set1_ps(0.0f); + __m256 neg_inf_vec = _mm256_set1_ps(NEG_INF); + + // 【最终修正】使用安全的循环来确保完全初始化,不再依赖Br是8的倍数 + int i = 0; + for (; i <= Br - 8; i += 8) { + _mm256_storeu_ps(logsum + i, zero_vec); + _mm256_storeu_ps(scoremax + i, neg_inf_vec); + } + // 处理剩余的元素(如果Br不是8的倍数) + for (; i < Br; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF; + } + + // acc_o 的初始化是安全的,因为调用者保证了 dim_size % 8 == 0 + for (int j = 0; j < Br * dim_size; j += 8) { + _mm256_storeu_ps(acc_o + j, zero_vec); + } + } + + inline void mma0(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t q_stride_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br, global_r_end = global_r_start + Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + const dtype_q_in_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + __m256 q_vec = _mm256_loadu_ps(q_block_line + i); + __m256 k_vec = MLLM_F32Cx8_LOAD(k_block_line + i); + sum_vec = _mm256_fmadd_ps(q_vec, k_vec, sum_vec); + } + acc_dtype_t total = _mm256_hadd_ps(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { + for (int i = 0; i < Br; ++i) { + for (int j = 0; j < Bc; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } + } + + inline void softmax(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); + for (int br = 0; br < Br; ++br) { + __m256 max_vec = _mm256_set1_ps(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 8; bc += 8) { max_vec = _mm256_max_ps(max_vec, _mm256_loadu_ps(row + bc)); } + float max_val = _mm256_hmax_ps(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } + for (int br = 0; br < Br; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } + for (int br = 0; br < Br; ++br) { + const float sm = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((row[bc] - sm) * scale); + row[bc] = val; + sum += val; + } + score_sum[br] = sum; + } + for (int br = 0; br < Br; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } + } + + inline void rescale(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + // (无变化) + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + for (int i = 0; i < Br; ++i) { + __m256 scale_v = _mm256_set1_ps(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 8) { + __m256 acc = _mm256_loadu_ps(row_ptr + j); + acc = _mm256_mul_ps(acc, scale_v); + _mm256_storeu_ps(row_ptr + j, acc); + } + } + } + + inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + const int32_t v_stride_size = kv_head_size * dim_size; + for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + __m256 w_vec = _mm256_set1_ps(w_block[b_r_idx * Bc + b_c_idx]); + const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + __m256 v_vec = MLLM_F32Cx8_LOAD(v_ptr); + acc = _mm256_fmadd_ps(w_vec, v_vec, acc); + } + _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); + } + } + } + + inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, + dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { + // (无变化,输出O是fp32) + for (int i = 0; i < Br; ++i) { + // 【修正】这里的 o_block_line 计算是错误的,它没有正确处理 BSHD 布局下的行步进 + // 正确的行步进已经由外层循环的 o_block 指针计算好了 + // 我们只需要在此基础上按行写入即可 + dtype_out_t *o_block_line = o_block + i * head_size * dim_size; // << 保持 BSHD 的行步长 + + __m256 reciprocal_logsum_vec = _mm256_set1_ps(1.0f / logsum[i]); + int j = 0; + for (; j <= dim_size - 8; j += 8) { + __m256 vec_acc_o = _mm256_loadu_ps(acc_o + i * dim_size + j); + __m256 result_vec = _mm256_mul_ps(vec_acc_o, reciprocal_logsum_vec); + _mm256_storeu_ps(o_block_line + j, result_vec); + } + float reciprocal_logsum = 1.0f / logsum[i]; + for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } + } + } + + inline void mma0_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t q_stride_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br_n_fixed; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + const dtype_q_in_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + sum_vec = _mm256_fmadd_ps(_mm256_loadu_ps(q_block_line + i), MLLM_F32Cx8_LOAD(k_block_line + i), sum_vec); + } + acc_dtype_t total = _mm256_hadd_ps(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { + for (int i = 0; i < Br_n_fixed; ++i) { + for (int j = 0; j < Bc_n_fixed; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } + } + + inline void softmax_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, + acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, + acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float max_val = NEG_INF; + for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, row[bc]); + scoremax[br] = fmaxf(max_val, scoremax[br]); + } + for (int br = 0; br < Br_n_fixed; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + float val = expf((row[bc] - scoremax[br]) * scale); + row[bc] = val; + current_sum += val; + } + score_sum[br] = current_sum; + } + for (int br = 0; br < Br_n_fixed; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } + } + + // (无变化) + inline void rescale_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + for (int i = 0; i < Br_n_fixed; ++i) { + float *row_ptr = acc_o + i * dim_size; + __m256 scale_v = _mm256_set1_ps(score_scale[i]); + for (int j = 0; j < dim_size; j += 8) { + _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + j), scale_v)); + } + } + } + + inline void mma1_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + const int32_t v_stride_size = kv_head_size * dim_size; + for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + __m256 w_vec = _mm256_set1_ps(w_block[b_r_idx * Bc + b_c_idx]); + const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = _mm256_fmadd_ps(w_vec, MLLM_F32Cx8_LOAD(v_ptr), acc); + } + _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); + } + } + } + + inline void scale_and_store_pa_n_fixed(const int32_t Br_n_fixed, const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, + const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + // 【修正】同上,这里的行步进计算也是错误的 + dtype_out_t *o_block_line = o_block + i * head_size * dim_size; // << 保持 BSHD 的行步长 + + float reciprocal_logsum = 1.0f / logsum[i]; + __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 8; j += 8) { + __m256 vec_acc_o = _mm256_loadu_ps(acc_o + i * dim_size + j); + _mm256_storeu_ps(o_block_line + j, _mm256_mul_ps(vec_acc_o, reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } + } + } + + // (此函数无变化,但为完整性一并提供) + inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { + logsum[0] = 0.0f; + scoremax[0] = NEG_INF; + __m256 zero_vec = _mm256_setzero_ps(); + for (int i = 0; i < 1 * dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } + } + + inline void mma0_d(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const dtype_q_in_t *q_block_line = q_block; + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + sum_vec = _mm256_fmadd_ps(_mm256_loadu_ps(q_block_line + i), MLLM_F32Cx8_LOAD(k_block_line + i), sum_vec); + } + acc_dtype_t total = _mm256_hadd_ps(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_s[b_c_idx] = total; + } + } + + inline void softmax_d(acc_dtype_t *__restrict__ acc_s, + acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, + acc_dtype_t *score_sum, acc_dtype_t *logsum, const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + scoremax_prev[0] = scoremax[0]; + float max_val = NEG_INF; + for (int bc = 0; bc < Bc; ++bc) max_val = fmaxf(max_val, acc_s[bc]); + scoremax[0] = fmaxf(max_val, scoremax[0]); + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + float current_sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + // (此函数无变化,但为完整性一并提供) + inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + __m256 scale_v = _mm256_set1_ps(score_scale[0]); + for (int j = 0; j < dim_size; j += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + j); + acc = _mm256_mul_ps(acc, scale_v); + _mm256_storeu_ps(acc_o + j, acc); + } + } + + inline void mma1_d(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + __m256 w_vec = _mm256_set1_ps(w_block[b_c_idx]); + const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + __m256 v_vec = MLLM_F32Cx8_LOAD(v_ptr); + acc = _mm256_fmadd_ps(w_vec, v_vec, acc); + } + _mm256_storeu_ps(acc_o + d_base, acc); + } + } + // (此函数无变化,但为完整性一并提供) + inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, + dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { + float reciprocal_logsum = 1.0f / logsum[0]; + __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 8; j += 8) { + _mm256_storeu_ps(o_block + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { + o_block[j] = acc_o[j] * reciprocal_logsum; + } + } + + inline void mma0_d_n_fixed(const int32_t Bc_n_fixed, const dtype_q_in_t *__restrict__ q_block, + const dtype_kv_in_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, + const int32_t dim_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const dtype_q_in_t *q_block_line = q_block; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float total = 0.0f; + for (int i = 0; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_s[b_c_idx] = total; + } + } + + inline void softmax_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_s, + acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, + acc_dtype_t *logsum, const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + scoremax_prev[0] = scoremax[0]; + float max_val = NEG_INF; + for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, acc_s[bc]); + scoremax[0] = fmaxf(max_val, scoremax[0]); + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + // (此函数无变化,但为完整性一并提供) + inline void rescale_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_o, + acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + float scale = score_scale[0]; + for (int j = 0; j < dim_size; ++j) { acc_o[j] *= scale; } + } + + inline void mma1_d_n_fixed(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, + const dtype_kv_in_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, + const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, + const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; ++d_base) { + float acc = acc_o[d_base]; + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + // Scalar fallback for leftover dimensions + acc += w_block[b_c_idx] * MLLM_FP16_TO_FP32(v_block[b_c_idx * v_stride_size + d_base]); + } + acc_o[d_base] = acc; + } + } + +private: + // float scale_; + acc_dtype_t *acc_o_; + acc_dtype_t *acc_s_; + acc_dtype_t *logsum_; + acc_dtype_t *scoremax_; + acc_dtype_t *scoremax_prev_; + acc_dtype_t *score_scale_; + acc_dtype_t *score_sum_; +}; + +// ======================================== +// 【修改】统一的FlashAttention2接口,改为模板以支持不同实现 +template +struct FlashAttn2T { +public: + using dtype_q_in_t = typename Impl::dtype_q_in_t; + using dtype_kv_in_t = typename Impl::dtype_kv_in_t; + using dtype_out_t = typename Impl::dtype_out_t; + using acc_dtype_t = typename Impl::acc_dtype_t; + + void configure(int32_t Br, int32_t Bc, int32_t Q_Head, int32_t KV_Head, int32_t threads, bool high_precision) { + impl_.configure(Br, Bc, Q_Head, KV_Head, threads, high_precision); + } + + void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, + acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum) { + // Note: workspace pointers are always float, acc_s_cast is removed + impl_.init_workspace(acc_o, acc_s, logsum, scoremax, scoremax_prev, score_scale, score_sum); + } + + void operator()(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + impl_.fa2(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } + +private: + Impl impl_; +}; + +} // namespace mobi_attn + +// ======================================== +// 用户接口函数 +// ======================================== + +// 【修改】用户接口函数,增加FP16输入分支 +void flash_attention_2_forward( + const void *Q, const void *K, const void *V, void *O, + int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, + bool causal_mask, bool use_fp32, int32_t threads, int32_t br, int32_t bc, + int32_t q_head, int32_t kv_head, bool high_precision_exp) { + // 工作空间大小与输入数据类型无关,因为内部累加器总是float32 + // acc_s_cast is no longer needed as the intermediate softmax result is kept in float32 + const size_t acc_o_size = threads * br * dim_size * sizeof(float); + const size_t acc_s_size = threads * br * bc * sizeof(float); + const size_t logsum_size = threads * br * sizeof(float); + const size_t scoremax_size = threads * br * sizeof(float); + const size_t scoremax_prev_size = threads * br * sizeof(float); + const size_t score_scale_size = threads * br * sizeof(float); + const size_t score_sum_size = threads * br * sizeof(float); + + // 分配对齐的工作空间 + void *workspace[7]; + mobi_attn::x86_align_alloc(&workspace[0], acc_o_size, 32); + mobi_attn::x86_align_alloc(&workspace[1], acc_s_size, 32); + mobi_attn::x86_align_alloc(&workspace[2], logsum_size, 32); + mobi_attn::x86_align_alloc(&workspace[3], scoremax_size, 32); + mobi_attn::x86_align_alloc(&workspace[4], scoremax_prev_size, 32); + mobi_attn::x86_align_alloc(&workspace[5], score_scale_size, 32); + mobi_attn::x86_align_alloc(&workspace[6], score_sum_size, 32); + + if (use_fp32) { + // 使用纯FP32实现 + mobi_attn::FlashAttn2T op; + op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); + + op.init_workspace( + static_cast(workspace[0]), static_cast(workspace[1]), + static_cast(workspace[2]), static_cast(workspace[3]), + static_cast(workspace[4]), static_cast(workspace[5]), + static_cast(workspace[6])); + + op(static_cast(Q), static_cast(K), static_cast(V), + static_cast(O), + batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } else { + // 使用FP16输入,FP32输出的实现 + mobi_attn::FlashAttn2T op; + op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); + + op.init_workspace( + static_cast(workspace[0]), static_cast(workspace[1]), + static_cast(workspace[2]), static_cast(workspace[3]), + static_cast(workspace[4]), static_cast(workspace[5]), + static_cast(workspace[6])); + + op(static_cast(Q), static_cast(K), static_cast(V), + static_cast(O), + batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } + + // 释放工作空间 + for (void *ptr : workspace) { + if (ptr) mobi_attn::x86_align_free(ptr); + } +} +#elif __ARM_NEON +#include +// 核心修改:将 x86 的 immintrin.h 替换为 ARM 的 arm_neon.h +#include +#include +#include +#include +#include +#include +#include "Types.hpp" +#include "VecDot.hpp" + +namespace mobi_attn { + +// ======================================== +// 数学函数和工具 (NEON版本) +// ======================================== +#define NEG_INF std::numeric_limits::lowest() + +// NEON版本:水平最大值 (Horizontal max of a float32x4_t vector) +// float32x4_t 中包含4个float, vmaxvq_f32可以直接找到这4个float中的最大值 +inline float _vmaxvq_f32_hmax(float32x4_t x) { + return vmaxvq_f32(x); +} + +// NEON版本:水平求和 (Horizontal sum of a float32x4_t vector) +// float32x4_t 中包含4个float, vaddvq_f32可以直接将这4个float相加 +inline float _vaddvq_f32_hadd(float32x4_t x) { + return vaddvq_f32(x); +} + +// ======================================== +// 高性能NEON数学函数 (新增) +// ======================================== + +// 基于多项式逼近的快速exp实现 (NEON版本) +inline float32x4_t vexpq_fast_f32(float32x4_t x) { + // 定义常量 + const float32x4_t c0 = vdupq_n_f32(1.0f); + const float32x4_t c1 = vdupq_n_f32(0.0416598990559578f); + const float32x4_t c2 = vdupq_n_f32(0.166664719581604f); + const float32x4_t c3 = vdupq_n_f32(0.5000005960464478f); + const float32x4_t log2e = vdupq_n_f32(1.4426950408889634f); + const float32x4_t ln2_hi = vdupq_n_f32(0.693145751953125f); + const float32x4_t ln2_lo = vdupq_n_f32(1.428606765330187e-06f); + const int32x4_t M_126 = vdupq_n_s32(126); + + // 计算 y = x * log2(e) + float32x4_t y = vmulq_f32(x, log2e); + + // 对y取整, n = round(y) + int32x4_t n = vcvtaq_s32_f32(y); + + // 计算 z = x - n * ln2 + float32x4_t n_f = vcvtq_f32_s32(n); + float32x4_t z = vmlsq_f32(x, n_f, ln2_hi); + z = vmlsq_f32(z, n_f, ln2_lo); + + // 多项式逼近 exp(z) ~= 1 + z + z^2/2! + ... + float32x4_t poly = c1; + poly = vmlaq_f32(c2, poly, z); + poly = vmlaq_f32(c3, poly, z); + poly = vmlaq_f32(c0, poly, z); + poly = vmlaq_f32(poly, vmulq_f32(z, z), poly); + + // 组合结果: poly * 2^n + int32x4_t m = vaddq_s32(n, M_126); + m = vshlq_n_s32(m, 23); + + return vmulq_f32(poly, vreinterpretq_f32_s32(m)); +} + +// ======================================== +// 内存对齐分配函数 (重命名以去除x86特定性) +// ======================================== +// 使用 posix_memalign 进行分配,此函数在支持POSIX的系统(如Linux)上是通用的 +void aligned_alloc(void **ptr, size_t required_bytes, size_t align) { + // posix_memalign 要求 alignment 必须是 void* 大小的整数倍,并且是 2 的幂 + if (align % sizeof(void *) != 0 || (align & (align - 1)) != 0) { + *ptr = nullptr; + return; + } + + // posix_memalign 返回 0 表示成功,否则返回错误码 + if (posix_memalign(ptr, align, required_bytes) != 0) { + *ptr = nullptr; + } +} + +// 直接使用标准 free 进行释放 +void aligned_free(void *ptr) { + free(ptr); +} + +// ======================================== +// FlashAttention2 核心实现 (FP32版本, NEON) +// ======================================== +struct NEON_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { + using dtype_q_in_t = float; + using dtype_kv_in_t = dtype_q_in_t; + using dtype_out_t = dtype_q_in_t; + using dtype_t = dtype_out_t; + using acc_dtype_t = float; + + // 添加配置参数作为成员变量 + int32_t Br; + int32_t Bc; + int32_t Q_Head; + int32_t KV_Head; + int32_t threads; + bool high_precision; + + // 配置参数初始化 + void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_, bool high_precision_) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_Head_; + KV_Head = KV_Head_; + threads = threads_; + high_precision = high_precision_; + } + + // 初始化工作空间指针 + void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, + acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum) { + acc_o_ = acc_o; + acc_s_ = acc_s; + logsum_ = logsum; + scoremax_ = scoremax; + scoremax_prev_ = scoremax_prev; + score_scale_ = score_scale; + score_sum_ = score_sum; + } + + // fa2 主函数,根据Q的序列长度分发到 prefill/append 或 decode 模式 + void fa2(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, const int32_t batch_size, + const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + assert(Br == Bc); + // NEON 一次处理 4 个 float + assert(dim_size % 4 == 0); + // 确保Q头是KV头的整数倍,这是GQA/MHA的有效性要求 + assert(Q_Head % KV_Head == 0); + assert(head_size % threads == 0); + + if (seq_size_q != 1) { + __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, + causal_mask); + } else { + __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, + causal_mask); + } + } + + // ========================================================================================= + // 以下是 NEON_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL 结构体内部的私有函数实现 + // 承接第一部分的代码 + // ========================================================================================= + +private: + // 核心计算函数 (prefill/append 模式, 适用于 seq_size_q > 1) + inline void __fa2_prefill_append(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, // head_size 就是 Q_Head + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + // Tr, Tc 分别是 Q 和 K/V 在序列长度维度上被切分成的块数 + const int32_t Tr = seq_size_q / Br; + const int32_t Tr_left = seq_size_q % Br; + const int32_t Tc = seq_size_k / Bc; + const int32_t Tc_left = seq_size_k % Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + + // 计算Q头与KV头的分组对应关系 (GQA) + const int32_t kv_group_size = Q_Head / KV_Head; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { // h_idx 是当前Q头的索引 + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + + // 计算当前Q头 (h_idx) 对应的KV头索引 + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + // --- 主循环 (处理完整的块) --- + for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { + // 初始化该线程的临时工作空间 + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, + acc_o_ + thread_id * Br * dim_size, dim_size); + + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + // Q 的指针计算,它有 Q_Head (==head_size) 个头 + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; + + // K 和 V 的指针计算,必须使用 KV_Head 和映射后的 this_thread_kv_head + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + + // Step 1: Q * K^T + mma0(tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + // Step 2: Softmax + softmax(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + // Step 3: Rescale O + rescale(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + // Step 4: P * V + mma1(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + // --- 处理 K/V 序列的剩余部分 (Tc_left) --- + if (Tc_left) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Br, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Br, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Br, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Br, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + } + // Step 5: 将最终结果缩放并存回输出 O + scale_and_store(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); + } + // --- 处理 Q 序列的剩余部分 (Tr_left) --- + if (Tr_left) { + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Tr_left, Bc, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Tr_left, Bc, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Tr_left, Bc, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Tr_left, Bc, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Tr_left, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Tr_left, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store_pa_n_fixed(Tr_left, acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size, Tr, head_size, dim_size); + } + } + } + } + inline void __fa2_decode(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + // 在 decode 模式下, Q 的序列长度固定为 1, 因此 Tr = 1, Br = 1 + const int32_t Tr = 1; + const int32_t Tc = seq_size_k / Bc; + const int32_t Tc_left = seq_size_k % Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + const int t_r_idx = 0; + + init_temp_d(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); + + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + + mma0_d(tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax_d(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale_d(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1_d(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + + if (Tc_left) { + const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; + const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_d_n_fixed(Tc_left, tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_d_n_fixed(Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_d_n_fixed(Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_d_n_fixed(Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + } + + scale_and_store_d(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); + } + } + } + + // 初始化临时工作区 (NEON 版本) + inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { + float32x4_t zero_vec = vdupq_n_f32(0.0f); + float32x4_t neg_inf_vec = vdupq_n_f32(NEG_INF); + + int i = 0; + // NEON 一次处理4个 + for (; i <= Br - 4; i += 4) { + vst1q_f32(logsum + i, zero_vec); + vst1q_f32(scoremax + i, neg_inf_vec); + } + // 处理剩余的元素(如果Br不是4的倍数) + for (; i < Br; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF; + } + + // acc_o 的初始化, 调用者保证了 dim_size % 4 == 0 + for (int j = 0; j < Br * dim_size; j += 4) { + vst1q_f32(acc_o + j, zero_vec); + } + } + + // Q * K^T 计算 (NEON 版本) + inline void mma0(const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t q_stride_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + + for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + // 为了性能,可以一次处理8个或更多元素,这里保持与AVX版本类似的逻辑,但向量宽度减半 + for (; i <= dim_size - 8; i += 8) { + // 预取数据到缓存 + __builtin_prefetch(q_block_line + i + 64); + __builtin_prefetch(k_block_line + i + 64); + // 加载两组4个float数据 + float32x4_t q_vec0 = vld1q_f32(q_block_line + i); + float32x4_t k_vec0 = vld1q_f32(k_block_line + i); + float32x4_t q_vec1 = vld1q_f32(q_block_line + i + 4); + float32x4_t k_vec1 = vld1q_f32(k_block_line + i + 4); + // 融合乘加 + sum_vec = vfmaq_f32(sum_vec, q_vec0, k_vec0); + sum_vec = vfmaq_f32(sum_vec, q_vec1, k_vec1); + } + // 处理 dim_size % 8 剩下的部分 + for (; i <= dim_size - 4; i += 4) { + float32x4_t q_vec = vld1q_f32(q_block_line + i); + float32x4_t k_vec = vld1q_f32(k_block_line + i); + sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); + } + + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + // 处理最后不足4个的元素 + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + // 应用因果掩码 + if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { + for (int i = 0; i < Br; ++i) { + for (int j = 0; j < Bc; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } + } + + // Softmax (NEON 版本) + inline void softmax(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + + memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); + + // 1. 找到每行的最大值 m_i + for (int br = 0; br < Br; ++br) { + float32x4_t max_vec = vdupq_n_f32(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 4; bc += 4) { + max_vec = vmaxq_f32(max_vec, vld1q_f32(row + bc)); + } + float max_val = _vmaxvq_f32_hmax(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } + + // 2. 计算缩放因子 s_i = exp((m_i_prev - m_i) * scale) + for (int br = 0; br < Br; ++br) { + score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); + } + + // 3. 计算 P_ij = exp((S_ij - m_i) * scale) 和 l_i = sum(P_ij) + for (int br = 0; br < Br; ++br) { + const float sm = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + // 这里可以进一步用NEON优化expf, 但expf的SIMD实现复杂,暂用标量 + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((row[bc] - sm) * scale); + row[bc] = val; // 更新 acc_s 为 P_ij + sum += val; + } + score_sum[br] = sum; + } + + // 4. 更新 logsum: l_i_new = l_i_prev * s_i + l_i + for (int br = 0; br < Br; ++br) { + logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; + } + } + + // 重缩放累加的输出 O (NEON 版本) + inline void rescale(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + + for (int i = 0; i < Br; ++i) { + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 4) { + float32x4_t acc = vld1q_f32(row_ptr + j); + acc = vmulq_f32(acc, scale_v); + vst1q_f32(row_ptr + j, acc); + } + } + } + + // P * V 计算 (NEON 版本) + inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + + const int32_t v_stride_size = kv_head_size * dim_size; + + for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); + const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + float32x4_t v_vec = vld1q_f32(v_ptr); + acc = vfmaq_f32(acc, w_vec, v_vec); + } + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + } + } + } + + // 缩放并存储最终结果 (NEON 版本) + inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, + dtype_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { + for (int i = 0; i < Br; ++i) { + dtype_t *o_block_line = o_block + i * head_size * dim_size; + float reciprocal_logsum = 1.0f / logsum[i]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); + float32x4_t result_vec = vmulq_f32(vec_acc_o, reciprocal_logsum_vec); + vst1q_f32(o_block_line + j, result_vec); + } + for (; j < dim_size; ++j) { + o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; + } + } + } + + // --- 处理剩余块的 N-fixed 函数 (NEON 版本) --- + inline void mma0_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const dtype_t *__restrict__ q_block, + const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, + const int32_t dim_size, const int32_t q_stride_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br_n_fixed; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + + for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), vld1q_f32(k_block_line + i)); + } + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + + if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { + for (int i = 0; i < Br_n_fixed; ++i) { + for (int j = 0; j < Bc_n_fixed; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } + } + + // (这里的逻辑主要是标量,和AVX版本基本一致) + inline void softmax_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, + acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, + acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + + memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); + + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float max_val = NEG_INF; + for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, row[bc]); + scoremax[br] = fmaxf(max_val, scoremax[br]); + } + for (int br = 0; br < Br_n_fixed; ++br) { + score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); + } + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + float val = expf((row[bc] - scoremax[br]) * scale); + row[bc] = val; + current_sum += val; + } + score_sum[br] = current_sum; + } + for (int br = 0; br < Br_n_fixed; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } + } + + inline void rescale_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_o, + acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + + for (int i = 0; i < Br_n_fixed; ++i) { + float *row_ptr = acc_o + i * dim_size; + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + for (int j = 0; j < dim_size; j += 4) { + vst1q_f32(row_ptr + j, vmulq_f32(vld1q_f32(row_ptr + j), scale_v)); + } + } + } + + inline void mma1_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const acc_dtype_t *__restrict__ w_block, + const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, + const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + + const int32_t v_stride_size = kv_head_size * dim_size; + + for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); + const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = vfmaq_f32(acc, w_vec, vld1q_f32(v_ptr)); + } + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + } + } + } + + inline void scale_and_store_pa_n_fixed(const int32_t Br_n_fixed, + const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, + dtype_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + dtype_t *o_block_line = o_block + i * head_size * dim_size; + float reciprocal_logsum = 1.0f / logsum[i]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); + vst1q_f32(o_block_line + j, vmulq_f32(vec_acc_o, reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { + o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; + } + } + } + + // --- Decode 模式的辅助函数 (NEON 版本) --- + + inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, + const int32_t dim_size) { + logsum[0] = 0.0f; + scoremax[0] = NEG_INF; + float32x4_t zero_vec = vdupq_n_f32(0.0f); + // Br 在 decode 模式下为 1 + for (int i = 0; i < 1 * dim_size; i += 4) { + vst1q_f32(acc_o + i, zero_vec); + } + } + + inline void mma0_d(const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const dtype_t *q_block_line = q_block; // q 只有一个向量 + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), vld1q_f32(k_block_line + i)); + } + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + acc_s[b_c_idx] = total; + } + } + + inline void softmax_d(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, + acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, + acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + scoremax_prev[0] = scoremax[0]; + + float max_val = scoremax[0]; + for (int bc = 0; bc < Bc; ++bc) { + max_val = fmaxf(max_val, acc_s[bc]); + } + scoremax[0] = max_val; + + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + + float current_sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + float32x4_t scale_v = vdupq_n_f32(score_scale[0]); + for (int j = 0; j < dim_size; j += 4) { + float32x4_t acc = vld1q_f32(acc_o + j); + acc = vmulq_f32(acc, scale_v); + vst1q_f32(acc_o + j, acc); + } + } + + inline void mma1_d(const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); + const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = vfmaq_f32(acc, w_vec, vld1q_f32(v_ptr)); + } + vst1q_f32(acc_o + d_base, acc); + } + } + + inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, + dtype_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { + float reciprocal_logsum = 1.0f / logsum[0]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { + o_block[j] = acc_o[j] * reciprocal_logsum; + } + } + + // --- Decode N-fixed 函数 (NEON 版本, 逻辑多为标量) --- + inline void mma0_d_n_fixed(const int32_t Bc_n_fixed, const dtype_t *__restrict__ q_block, + const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, + const int32_t dim_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const dtype_t *q_block_line = q_block; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float total = 0.0f; + for (int i = 0; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + acc_s[b_c_idx] = total; + } + } + + inline void softmax_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_s, + acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, + acc_dtype_t *logsum, + const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + scoremax_prev[0] = scoremax[0]; + float max_val = scoremax[0]; + for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, acc_s[bc]); + scoremax[0] = max_val; + + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + inline void rescale_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_o, + acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + float scale = score_scale[0]; + for (int j = 0; j < dim_size; ++j) { + acc_o[j] *= scale; + } + } + + inline void mma1_d_n_fixed(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, + const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, + const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, + const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; ++d_base) { + float acc = acc_o[d_base]; + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + acc += w_block[b_c_idx] * v_block[b_c_idx * v_stride_size + d_base]; + } + acc_o[d_base] = acc; + } + } + +private: + // 私有成员,用于存储工作空间的指针 + acc_dtype_t *acc_o_; + acc_dtype_t *acc_s_; + acc_dtype_t *logsum_; + acc_dtype_t *scoremax_; + acc_dtype_t *scoremax_prev_; + acc_dtype_t *score_scale_; + acc_dtype_t *score_sum_; +}; +// ======================================== +// FlashAttention2 核心实现 (Q FP32/KV FP16 输入, FP32 输出, NEON 版本) +// 【注意:本版本为完整、未省略代码的版本】 +// ======================================== +struct NEON_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { + // 定义不同的输入数据类型 + using dtype_q_in_t = float; + using dtype_kv_in_t = mllm_fp16_t; // K和V是FP16 + using dtype_out_t = float; + using acc_dtype_t = float; + + // 配置参数 + int32_t Br, Bc, Q_Head, KV_Head, threads; + bool high_precision; + + void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_, bool high_precision_) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_Head_; + KV_Head = KV_Head_; + threads = threads_; + high_precision = high_precision_; + } + + void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, + acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum) { + acc_o_ = acc_o; + acc_s_ = acc_s; + logsum_ = logsum; + scoremax_ = scoremax; + scoremax_prev_ = scoremax_prev; + score_scale_ = score_scale; + score_sum_ = score_sum; + } + + // 主函数 fa2, 注意 K 和 V 的类型是 dtype_kv_in_t + void fa2(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, const int32_t batch_size, + const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + assert(Br == Bc); + assert(dim_size % 4 == 0); + assert(Q_Head % KV_Head == 0); + assert(head_size % threads == 0); + + if (seq_size_q != 1) { + __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } else { + __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } + } + +private: + // 定义一个宏,用于从内存加载4个fp16, 并转换为一个fp32向量 + // 这需要 ARMv8.2-A FP16 指令支持 +#define MLLM_NEON_F32x4_FROM_FP16(addr) vcvt_f32_f16(vld1_f16((const __fp16 *)(addr))) + + // Prefill/Append 主循环 (混合精度) - 完整版 + inline void __fa2_prefill_append(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + const int32_t Tr = seq_size_q / Br; + const int32_t Tr_left = seq_size_q % Br; + const int32_t Tc = seq_size_k / Bc; + const int32_t Tc_left = seq_size_k % Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + // --- 主循环 (Tr) --- + for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0(tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Br, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Br, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Br, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Br, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); + } + // --- 处理 Q 序列的剩余部分 (Tr_left) - 完整版 --- + if (Tr_left) { + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Tr_left, Bc, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Tr_left, Bc, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Tr_left, Bc, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Tr_left, Bc, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_pa_n_fixed(Tr_left, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_pa_n_fixed(Tr_left, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store_pa_n_fixed(Tr_left, acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size, Tr, head_size, dim_size); + } + } + } + } + + // Decode 主循环 (混合精度) - 完整版 + inline void __fa2_decode(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + const int32_t Tr = 1; + const int32_t Tc = seq_size_k / Bc; + const int32_t Tc_left = seq_size_k % Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + const int t_r_idx = 0; + init_temp_d(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_d(tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax_d(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + rescale_d(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + mma1_d(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + } + if (Tc_left) { + const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; + const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + mma0_d_n_fixed(Tc_left, tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + softmax_d_n_fixed(Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + rescale_d_n_fixed(Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + mma1_d_n_fixed(Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); + } + scale_and_store_d(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); + } + } + } + + // --- 完整版辅助函数 --- + + // (与FP32版本相同) + inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { + float32x4_t zero_vec = vdupq_n_f32(0.0f); + float32x4_t neg_inf_vec = vdupq_n_f32(NEG_INF); + int i = 0; + for (; i <= Br - 4; i += 4) { + vst1q_f32(logsum + i, zero_vec); + vst1q_f32(scoremax + i, neg_inf_vec); + } + for (; i < Br; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF; + } + for (int j = 0; j < Br * dim_size; j += 4) { + vst1q_f32(acc_o + j, zero_vec); + } + } + + // 输入Q为FP32,但在函数内动态转为FP16,以使用最高效的 vfmlalq_f16 指令进行计算 + inline void mma0(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t q_stride_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + // 因果掩码的前置检查 + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + + // 遍历Br x Bc的块 + for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + const dtype_q_in_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + + // 使用多个FP32累加器,借鉴自您提供的参考文件 + float32x4_t sum0 = vdupq_n_f32(0.0f); + float32x4_t sum1 = vdupq_n_f32(0.0f); + + int i = 0; + // 主循环,一次处理16个元素 (两个float16x8_t向量) + for (; i <= dim_size - 16; i += 16) { + __builtin_prefetch(q_block_line + i + 64); + __builtin_prefetch(k_block_line + i + 64); + + // 1. 加载16个 FP32 的 Q + float32x4_t q_f32_0 = vld1q_f32(q_block_line + i); + float32x4_t q_f32_1 = vld1q_f32(q_block_line + i + 4); + float32x4_t q_f32_2 = vld1q_f32(q_block_line + i + 8); + float32x4_t q_f32_3 = vld1q_f32(q_block_line + i + 12); + + // 2. 【核心修改】将加载的 FP32 Q 动态转换为 FP16 + float16x8_t q_f16_0 = vcombine_f16(vcvt_f16_f32(q_f32_0), vcvt_f16_f32(q_f32_1)); + float16x8_t q_f16_1 = vcombine_f16(vcvt_f16_f32(q_f32_2), vcvt_f16_f32(q_f32_3)); + + // 3. 加载16个 FP16 的 K + float16x8_t k_f16_0 = vld1q_f16((const __fp16 *)k_block_line + i); + float16x8_t k_f16_1 = vld1q_f16((const __fp16 *)k_block_line + i + 8); + + // 4. 【核心修改】直接对两个FP16向量进行乘加,结果累加到FP32寄存器 + sum0 = vfmlalq_low_f16(sum0, q_f16_0, k_f16_0); + sum0 = vfmlalq_high_f16(sum0, q_f16_0, k_f16_0); + sum1 = vfmlalq_low_f16(sum1, q_f16_1, k_f16_1); + sum1 = vfmlalq_high_f16(sum1, q_f16_1, k_f16_1); + } + + sum0 = vaddq_f32(sum0, sum1); // 合并累加器 + + // 处理剩余的8个元素 + if (i <= dim_size - 8) { + float32x4_t q_f32_0 = vld1q_f32(q_block_line + i); + float32x4_t q_f32_1 = vld1q_f32(q_block_line + i + 4); + float16x8_t q_f16 = vcombine_f16(vcvt_f16_f32(q_f32_0), vcvt_f16_f32(q_f32_1)); + float16x8_t k_f16 = vld1q_f16((const __fp16 *)k_block_line + i); + + sum0 = vfmlalq_low_f16(sum0, q_f16, k_f16); + sum0 = vfmlalq_high_f16(sum0, q_f16, k_f16); + i += 8; + } + + // 水平求和,得到最终的点积结果 + acc_dtype_t total = vaddvq_f32(sum0); + + // 用标量方式处理最后不足8个的元素 + for (; i < dim_size; ++i) { + total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); + } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + + // 应用因果掩码的后处理 + if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { + for (int i = 0; i < Br; ++i) { + for (int j = 0; j < Bc; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } + } + // (与FP32版本相同) + inline void softmax(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); + for (int br = 0; br < Br; ++br) { + float32x4_t max_vec = vdupq_n_f32(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 4; bc += 4) { max_vec = vmaxq_f32(max_vec, vld1q_f32(row + bc)); } + float max_val = _vmaxvq_f32_hmax(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } + for (int br = 0; br < Br; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } + for (int br = 0; br < Br; ++br) { + const float sm = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((row[bc] - sm) * scale); + row[bc] = val; + sum += val; + } + score_sum[br] = sum; + } + for (int br = 0; br < Br; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } + } + + // (与FP32版本相同) + inline void rescale(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + for (int i = 0; i < Br; ++i) { + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 4) { + float32x4_t acc = vld1q_f32(row_ptr + j); + acc = vmulq_f32(acc, scale_v); + vst1q_f32(row_ptr + j, acc); + } + } + } + + // (混合精度修改版) + inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + const int32_t v_stride_size = kv_head_size * dim_size; + for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); + const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); + } + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + } + } + } + + // (与FP32版本相同) + inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, + dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { + for (int i = 0; i < Br; ++i) { + dtype_out_t *o_block_line = o_block + i * head_size * dim_size; + float reciprocal_logsum = 1.0f / logsum[i]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + vst1q_f32(o_block_line + j, vmulq_f32(vld1q_f32(acc_o + i * dim_size + j), reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } + } + } + + // (混合精度修改版) + inline void mma0_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t q_stride_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br, global_r_end = global_r_start + Br_n_fixed; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + const dtype_q_in_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), MLLM_NEON_F32x4_FROM_FP16(k_block_line + i)); + } + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { + for (int i = 0; i < Br_n_fixed; ++i) { + for (int j = 0; j < Bc_n_fixed; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } + } + + // (与FP32版本相同) + inline void softmax_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, + acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, + acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float max_val = NEG_INF; + for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, row[bc]); + scoremax[br] = fmaxf(max_val, scoremax[br]); + } + for (int br = 0; br < Br_n_fixed; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + float val = expf((row[bc] - scoremax[br]) * scale); + row[bc] = val; + current_sum += val; + } + score_sum[br] = current_sum; + } + for (int br = 0; br < Br_n_fixed; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } + } + + // (与FP32版本相同) + inline void rescale_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + for (int i = 0; i < Br_n_fixed; ++i) { + float *row_ptr = acc_o + i * dim_size; + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + for (int j = 0; j < dim_size; j += 4) { + vst1q_f32(row_ptr + j, vmulq_f32(vld1q_f32(row_ptr + j), scale_v)); + } + } + } + + // (混合精度修改版) + inline void mma1_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + const int32_t v_stride_size = kv_head_size * dim_size; + for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); + const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); + } + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + } + } + } + + // (与FP32版本相同) + inline void scale_and_store_pa_n_fixed(const int32_t Br_n_fixed, const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, + const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + dtype_out_t *o_block_line = o_block + i * head_size * dim_size; + float reciprocal_logsum = 1.0f / logsum[i]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + vst1q_f32(o_block_line + j, vmulq_f32(vld1q_f32(acc_o + i * dim_size + j), reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } + } + } + + // --- Decode 模式函数 (完整版) --- + + // (与FP32版本相同) + inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { + logsum[0] = 0.0f; + scoremax[0] = NEG_INF; + float32x4_t zero_vec = vdupq_n_f32(0.0f); + for (int i = 0; i < 1 * dim_size; i += 4) { vst1q_f32(acc_o + i, zero_vec); } + } + + // (混合精度修改版) + inline void mma0_d(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const dtype_q_in_t *q_block_line = q_block; + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), MLLM_NEON_F32x4_FROM_FP16(k_block_line + i)); + } + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_s[b_c_idx] = total; + } + } + + // (与FP32版本相同) + inline void softmax_d(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + scoremax_prev[0] = scoremax[0]; + float max_val = scoremax[0]; + for (int bc = 0; bc < Bc; ++bc) max_val = fmaxf(max_val, acc_s[bc]); + scoremax[0] = max_val; + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + float current_sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + // (与FP32版本相同) + inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, + const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + float32x4_t scale_v = vdupq_n_f32(score_scale[0]); + for (int j = 0; j < dim_size; j += 4) { + vst1q_f32(acc_o + j, vmulq_f32(vld1q_f32(acc_o + j), scale_v)); + } + } + + // (混合精度修改版) + inline void mma1_d(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); + const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); + } + vst1q_f32(acc_o + d_base, acc); + } + } + + // (与FP32版本相同) + inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, + dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, + const int32_t head_size, const int32_t dim_size) { + float reciprocal_logsum = 1.0f / logsum[0]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { o_block[j] = acc_o[j] * reciprocal_logsum; } + } + + // (混合精度修改版) + inline void mma0_d_n_fixed(const int32_t Bc_n_fixed, const dtype_q_in_t *__restrict__ q_block, + const dtype_kv_in_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, + const int32_t dim_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const dtype_q_in_t *q_block_line = q_block; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float total = 0.0f; + for (int i = 0; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_s[b_c_idx] = total; + } + } + + // (与FP32版本相同) + inline void softmax_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_s, + acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, + acc_dtype_t *logsum, const float scale, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + scoremax_prev[0] = scoremax[0]; + float max_val = scoremax[0]; + for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, acc_s[bc]); + scoremax[0] = max_val; + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + // (与FP32版本相同) + inline void rescale_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_o, + acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, + bool causal_mask) { + float scale = score_scale[0]; + for (int j = 0; j < dim_size; ++j) { acc_o[j] *= scale; } + } + + // (混合精度修改版) + inline void mma1_d_n_fixed(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, + const dtype_kv_in_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, + const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, + const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; ++d_base) { + float acc = acc_o[d_base]; + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + acc += w_block[b_c_idx] * MLLM_FP16_TO_FP32(v_block[b_c_idx * v_stride_size + d_base]); + } + acc_o[d_base] = acc; + } + } + +private: + acc_dtype_t *acc_o_; + acc_dtype_t *acc_s_; + acc_dtype_t *logsum_; + acc_dtype_t *scoremax_; + acc_dtype_t *scoremax_prev_; + acc_dtype_t *score_scale_; + acc_dtype_t *score_sum_; +}; + +template +struct FlashAttn2T { +public: + using dtype_q_in_t = typename Impl::dtype_q_in_t; + using dtype_kv_in_t = typename Impl::dtype_kv_in_t; + using dtype_out_t = typename Impl::dtype_out_t; + using acc_dtype_t = typename Impl::acc_dtype_t; + + void configure(int32_t Br, int32_t Bc, int32_t Q_Head, int32_t KV_Head, int32_t threads, bool high_precision) { + impl_.configure(Br, Bc, Q_Head, KV_Head, threads, high_precision); + } + + void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, + acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum) { + impl_.init_workspace(acc_o, acc_s, logsum, scoremax, scoremax_prev, score_scale, score_sum); + } + + void operator()(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + impl_.fa2(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } + +private: + Impl impl_; +}; + +} // namespace mobi_attn + +void flash_attention_2_forward( + const void *Q, const void *K, const void *V, void *O, + int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, + bool causal_mask, bool use_fp32, int32_t threads, int32_t br, int32_t bc, + int32_t q_head, int32_t kv_head, bool high_precision_exp) { + const size_t acc_o_size = threads * br * dim_size * sizeof(float); + const size_t acc_s_size = threads * br * bc * sizeof(float); + const size_t logsum_size = threads * br * sizeof(float); + const size_t scoremax_size = threads * br * sizeof(float); + const size_t scoremax_prev_size = threads * br * sizeof(float); + const size_t score_scale_size = threads * br * sizeof(float); + const size_t score_sum_size = threads * br * sizeof(float); + + // TODO 改为只分配一次 + void *workspace[7]; + mobi_attn::aligned_alloc(&workspace[0], acc_o_size, 32); + mobi_attn::aligned_alloc(&workspace[1], acc_s_size, 32); + mobi_attn::aligned_alloc(&workspace[2], logsum_size, 32); + mobi_attn::aligned_alloc(&workspace[3], scoremax_size, 32); + mobi_attn::aligned_alloc(&workspace[4], scoremax_prev_size, 32); + mobi_attn::aligned_alloc(&workspace[5], score_scale_size, 32); + mobi_attn::aligned_alloc(&workspace[6], score_sum_size, 32); + + if (use_fp32) { + // 使用纯FP32 NEON实现 + mobi_attn::FlashAttn2T op; + op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); + + op.init_workspace( + static_cast(workspace[0]), static_cast(workspace[1]), + static_cast(workspace[2]), static_cast(workspace[3]), + static_cast(workspace[4]), static_cast(workspace[5]), + static_cast(workspace[6])); + + op(static_cast(Q), static_cast(K), static_cast(V), + static_cast(O), + batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } else { + // 使用FP16输入,FP32输出的NEON实现 + mobi_attn::FlashAttn2T op; + op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); + + op.init_workspace( + static_cast(workspace[0]), static_cast(workspace[1]), + static_cast(workspace[2]), static_cast(workspace[3]), + static_cast(workspace[4]), static_cast(workspace[5]), + static_cast(workspace[6])); + + op(static_cast(Q), static_cast(K), static_cast(V), + static_cast(O), + batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } + + for (void *ptr : workspace) { + if (ptr) mobi_attn::aligned_free(ptr); + } +} + +#endif // AVX2 + +#endif // MLLM_FA2_CAL_HPP \ No newline at end of file diff --git a/src/backends/cpu/compute/VecDot.hpp b/src/backends/cpu/compute/VecDot.hpp index 4862a3633..f96e7a2d8 100644 --- a/src/backends/cpu/compute/VecDot.hpp +++ b/src/backends/cpu/compute/VecDot.hpp @@ -225,7 +225,7 @@ #define MLLM_F32Cx8_LOAD(x) _mm256_cvtph_ps(_mm_loadu_si128((__m128i *)(x))) #define MLLM_F32Cx8_STORE(x, y) _mm_storeu_si128((__m128i *)(x), _mm256_cvtps_ph(y, 0)) #else -static inline __m256 __avx_f32cx8_load(MLLM_fp16_t *x) { +static inline __m256 __avx_f32cx8_load(mllm_fp16_t *x) { float tmp[8]; for (int i = 0; i < 8; i++) { @@ -234,7 +234,7 @@ static inline __m256 __avx_f32cx8_load(MLLM_fp16_t *x) { return _mm256_loadu_ps(tmp); } -static inline void __avx_f32cx8_store(MLLM_fp16_t *x, __m256 y) { +static inline void __avx_f32cx8_store(mllm_fp16_t *x, __m256 y) { float arr[8]; _mm256_storeu_ps(arr, y); diff --git a/src/backends/cpu/function/CPUClipFunc.hpp b/src/backends/cpu/function/CPUClipFunc.hpp index 08e6d9e94..d43cb7c72 100644 --- a/src/backends/cpu/function/CPUClipFunc.hpp +++ b/src/backends/cpu/function/CPUClipFunc.hpp @@ -132,6 +132,21 @@ class CPUclipFunction : public TensorFunction { } } } + } else if (d.size() == 1) { + int seq_idx = d[0]; + if (seq_idx < 0) { + seq_idx = inputs[0]->dimension() + seq_idx; + } +#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) + for (int b = 0; b < inputs[0]->batch(); ++b) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + for (int h = 0; h < inputs[0]->head(); ++h) { + memcpy(outputs[0]->hostPtr() + outputs[0]->offset(b, h, s, 0), + inputs[0]->hostPtr() + inputs[0]->offset(b, h, s, seq_idx), + sizeof(float)); + } + } + } } else { std::cout << "[TODO]Tensor.CLip not support!!!!" << std::endl; } @@ -266,6 +281,28 @@ class CPUcliptensorFunction : public TensorFunction { void execute(vector> outputs, vector> inputs, vector args) override { Chl dim = (Chl)args[0]; if (dim == SEQUENCE) { + if (inputs[0]->ctype() == BHDS) { + outputs[0]->chls() = inputs[0]->chls(); + outputs[0]->setCtype(BHDS); + int new_seq = inputs[1]->dimension(); + if (outputs[0]->sequence() == 0 || outputs[0]->shape().empty() + || new_seq != outputs[0]->sequence()) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), new_seq, inputs[0]->dimension()); + outputs[0]->alloc(); + } + +#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) + for (int b = 0; b < inputs[0]->batch(); ++b) { + for (int d = 0; d < inputs[0]->dimension(); ++d) { + for (int s = 0; s < new_seq; ++s) { + auto selected_idx = (int)inputs[1]->dataAt(0, 0, 0, s); + outputs[0]->setDataAt(b, 0, s, d, + inputs[0]->dataAt(b, 0, selected_idx, d)); + } + } + } + return; + } int new_seq = inputs[1]->dimension(); if (outputs[0]->sequence() == 0 || outputs[0]->shape().empty() || new_seq != outputs[0]->sequence()) { diff --git a/src/backends/cpu/function/CPUFlashAttention2Func.hpp b/src/backends/cpu/function/CPUFlashAttention2Func.hpp new file mode 100644 index 000000000..6ae558982 --- /dev/null +++ b/src/backends/cpu/function/CPUFlashAttention2Func.hpp @@ -0,0 +1,74 @@ +// +// Created by Rongjie Yi on 25-2-16. +// + +#ifndef CPUFA2FUNC_HPP +#define CPUFA2FUNC_HPP +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include "../compute/FlashAttention2.hpp" + +namespace mllm { +class Tensor; + +class CPUFlashAttention2Func : public TensorFunction { +public: + void reshape(vector> outputs, vector> inputs, vector args) override { + auto q_tensor = inputs[0]; + auto k_tensor = inputs[1]; + auto v_tensor = inputs[2]; + auto o_tensor = outputs[0]; + int batch_size = q_tensor->batch(); + int q_head = q_tensor->head(); + int q_sequence = q_tensor->sequence(); + int dimension = q_tensor->dimension(); + o_tensor->reshape(batch_size, q_head, q_sequence, dimension); + o_tensor->setDtype(inputs[0]->dtype()); + o_tensor->alloc(); + } + void execute(vector> outputs, vector> inputs, vector args) override { + auto q_tensor = inputs[0]; + auto k_tensor = inputs[1]; + auto v_tensor = inputs[2]; + auto o_tensor = outputs[0]; + bool causal_mask = (bool)args[0]; + int batch_size = q_tensor->batch(); + int q_head = q_tensor->head(); + int q_sequence = q_tensor->sequence(); + int dimension = q_tensor->dimension(); + int k_head = k_tensor->head(); + int k_sequence = k_tensor->sequence(); + int v_head = v_tensor->head(); + int v_sequence = v_tensor->sequence(); + assert(v_head == k_head && v_sequence == k_sequence); + bool kv_use_fp32 = k_tensor->dtype() == MLLM_TYPE_F32 ? true : false; // x86只支持FP32 + int threads = CPUBackend::cpu_threads; + if (threads > v_head) { + threads = v_head; // 线程数不能超过头数 + } + int32_t br = q_sequence >= 4 ? 4 : 1; + int32_t bc = q_sequence >= 4 ? 4 : 1; + constexpr bool high_precision_exp = false; + // q_tensor->saveData(); + // k_tensor->saveData(); + // v_tensor->saveData(); + // GQA is not ready + flash_attention_2_forward( + q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), + o_tensor->hostPtr(), // 输入输出张量 + batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 + causal_mask, // 使用因果掩码 + kv_use_fp32, // 使用FP32(x86必须) + threads, // 使用4线程 + br, // 查询分块大小64 + bc, // 键值分块大小128 + q_head, // 查询头数12 + k_head, // 键值头数4 + high_precision_exp // 使用快速指数近似 + ); + // o_tensor->saveData(); + } +}; +} // namespace mllm +#endif // CPUFA2FUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUApplyVisionRoPE.hpp b/src/backends/cpu/function/CPUVisionRoPEFunc.hpp similarity index 99% rename from src/backends/cpu/function/CPUApplyVisionRoPE.hpp rename to src/backends/cpu/function/CPUVisionRoPEFunc.hpp index 121cf71a8..9b1337a10 100644 --- a/src/backends/cpu/function/CPUApplyVisionRoPE.hpp +++ b/src/backends/cpu/function/CPUVisionRoPEFunc.hpp @@ -11,7 +11,7 @@ namespace mllm { class Tensor; -class CPUApplyVisionRoPEFunction : public TensorFunction { +class CPUVisionRoPEFuncFunction : public TensorFunction { void rope_hf(shared_ptr input, shared_ptr rotary_pos_emb, shared_ptr output, int thread_count = 4) { auto out_dtype = output->dtype(); diff --git a/src/backends/cpu/op/CPUElasticLinear.cpp b/src/backends/cpu/op/CPUElasticLinear.cpp index b2f9462cf..8314a0362 100644 --- a/src/backends/cpu/op/CPUElasticLinear.cpp +++ b/src/backends/cpu/op/CPUElasticLinear.cpp @@ -69,32 +69,6 @@ ErrorCode CPUElasticLinear::execute(vector> inputs, vector> inputs, vector> outputs) { diff --git a/src/backends/cpu/op/CPUKVCache.cpp b/src/backends/cpu/op/CPUKVCache.cpp index 17a8a90e0..d4ea8fb14 100644 --- a/src/backends/cpu/op/CPUKVCache.cpp +++ b/src/backends/cpu/op/CPUKVCache.cpp @@ -6,8 +6,9 @@ int n_pack = 16; namespace mllm { -CPUKVCache::CPUKVCache(Backend *bn, string opName, int hidden, int head, int n_rep, int cache_max, int threadCount) : +CPUKVCache::CPUKVCache(Backend *bn, string opName, int hidden, int head, int n_rep, bool fa2, int cache_max, int threadCount) : thread_count(threadCount), Op(bn, opName) { + fa2_ = fa2; cache_.setBackend(bn); switch (KVCache_TYPE) { case 16: { @@ -32,10 +33,13 @@ CPUKVCache::CPUKVCache(Backend *bn, string opName, int hidden, int head, int n_r break; } } -// #endif + if (!fa2) { // not fa2 #ifdef LLAMAFILE_SGEMM - cache_max = ((cache_max + (n_pack - 1)) / n_pack) * n_pack; + cache_max = ((cache_max + (n_pack - 1)) / n_pack) * n_pack; #endif + } else { // fa2 + n_rep = 1; + } cache_limit_ = cache_max; n_rep_ = n_rep; if (head > 0) { @@ -103,7 +107,9 @@ ErrorCode CPUKVCache::reshape(vector> inputs, int sequence = inputs[0]->sequence() + cache_seq_len_; #ifdef LLAMAFILE_SGEMM - if (!for_xnn_ && sequence % n_pack != 0) sequence = ((sequence + (n_pack - 1)) / n_pack) * n_pack; + if (!fa2_) { + if (!for_xnn_ && sequence % n_pack != 0) sequence = ((sequence + (n_pack - 1)) / n_pack) * n_pack; + } #endif outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head() * n_rep_, sequence, inputs[0]->dimension()); diff --git a/src/backends/cpu/op/CPUKVCache.hpp b/src/backends/cpu/op/CPUKVCache.hpp index abaf4822f..5177fa54d 100644 --- a/src/backends/cpu/op/CPUKVCache.hpp +++ b/src/backends/cpu/op/CPUKVCache.hpp @@ -10,7 +10,7 @@ namespace mllm { class CPUKVCache final : public Op { public: - CPUKVCache(Backend *bn, string opName, int hidden, int head, int n_rep, int cache_max = 100, int threadCount = 4); + CPUKVCache(Backend *bn, string opName, int hidden, int head, int n_rep, bool fa2, int cache_max = 100, int threadCount = 4); virtual ~CPUKVCache() = default; virtual ErrorCode reshape(vector> inputs, vector> outputs) override; virtual ErrorCode load(AbstructLoader &loader) override; @@ -42,6 +42,8 @@ class CPUKVCache final : public Op { bool for_xnn_ = false; int cache_limit_; + + bool fa2_ = false; // not_fa2 }; class CPUKVCacheCreator : public CPUBackend::Creator { @@ -52,7 +54,8 @@ class CPUKVCacheCreator : public CPUBackend::Creator { bool for_xnn = (bool)op_param["for_xnn"]; int hidden = (int)op_param["hidden"]; int head = (int)op_param["head"]; - auto ret = new CPUKVCache(bn, name, hidden, head, n_rep, cache_max, threadCount); + bool fa2 = (bool)op_param["fa2"]; + auto ret = new CPUKVCache(bn, name, hidden, head, n_rep, fa2, cache_max, threadCount); ret->setForXnn(for_xnn); return ret; } diff --git a/src/backends/cpu/op/CPULinearINT8Shadow.cpp b/src/backends/cpu/op/CPULinearINT8Shadow.cpp index f510609c4..461612002 100755 --- a/src/backends/cpu/op/CPULinearINT8Shadow.cpp +++ b/src/backends/cpu/op/CPULinearINT8Shadow.cpp @@ -155,9 +155,9 @@ ErrorCode CPULinearINT8Shadow::execute(vector> inputs, vector int8_t output_clip = outputClip_.dataAt(0, 0, 0, 0); input_scale = input_scale / 127.0; - input_scale = roundf(input_scale * 100000) / 100000; + // input_scale = roundf(input_scale * 100000) / 100000; - output_scale = roundf(output_scale * 100000) / 100000; + // output_scale = roundf(output_scale * 100000) / 100000; memcpy(outputs[0]->hostPtr(), inputs[2]->hostPtr(), inputs[2]->cntSize()); @@ -173,7 +173,7 @@ ErrorCode CPULinearINT8Shadow::execute(vector> inputs, vector for (int j = 0; j < input0_buffer_.sequence(); j++) { for (int k = 0; k < input0_buffer_.dimension(); k++) { float round_value = roundf(input0_buffer_.dataAt(i, h, j, k) / input_scale); - if (round_value > (127.0 * 8) || round_value < (-128.0 * 8)) { + if (round_value > (127.0) || round_value < (-128.0)) { #if defined(__ARM_NEON) float origin_value = round_value * input_scale * weight_scale; float clip_value = std::fmax(std::fmin(round_value, 127), -128) * input_scale * weight_scale; @@ -213,7 +213,7 @@ ErrorCode CPULinearINT8Shadow::execute(vector> inputs, vector } #else - mllm_fp16_t origin_value = round_value * input_scale * weight_scale; + float origin_value = round_value * input_scale * weight_scale; float clip_value = std::fmax(std::fmin(round_value, 127), -128) * input_scale * weight_scale; #pragma omp parallel for collapse(1) num_threads(4) diff --git a/src/backends/cpu/op/CPULinearInt8.cpp b/src/backends/cpu/op/CPULinearInt8.cpp index fdbc09f5a..fa0431007 100644 --- a/src/backends/cpu/op/CPULinearInt8.cpp +++ b/src/backends/cpu/op/CPULinearInt8.cpp @@ -138,7 +138,7 @@ ErrorCode CPULinearInt8::free(vector> inputs, vector()[0] / 127.0; - scale1 = roundf(scale1 * 100000) / 100000; + // scale1 = roundf(scale1 * 100000) / 100000; float scale2 = weightScale_.hostPtr()[0]; @@ -147,7 +147,7 @@ ErrorCode CPULinearInt8::mat_mul_fp32_i8(Tensor *src0_, Tensor *src1, Tensor *ds scale3 = biasScale_.hostPtr()[0]; float scale4 = outputActivatationScale_.hostPtr()[0] / 127.0; - scale4 = roundf(scale4 * 100000) / 100000; + // scale4 = roundf(scale4 * 100000) / 100000; assert(src1->dtype() == MLLM_TYPE_I8); assert(src0_->dtype() == MLLM_TYPE_F32); diff --git a/src/backends/cpu/op/CPUMultimodalRoPE.cpp b/src/backends/cpu/op/CPUMultimodalRoPE.cpp index 4985a6014..c00f4ceb7 100644 --- a/src/backends/cpu/op/CPUMultimodalRoPE.cpp +++ b/src/backends/cpu/op/CPUMultimodalRoPE.cpp @@ -132,12 +132,7 @@ ErrorCode CPUMultimodalRoPE::reshape(vector> inputs, vector(backend_); - if (cpuBackend->isStageSwitching()) { - h_cnt_ = cpuBackend->getCurSequenceLength(); - } -#endif + return Op::reshape(inputs, outputs); } @@ -317,10 +312,7 @@ ErrorCode CPUMultimodalRoPE::doExecute(vector> inputs, vector } } } - h_cnt_ += input->sequence(); - if (h_cnt_ >= pos_max_) { - h_cnt_ = 0; - } + return Op::execute(inputs, outputs); } diff --git a/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp b/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp new file mode 100644 index 000000000..c23b55f27 --- /dev/null +++ b/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp @@ -0,0 +1,330 @@ + +#include "CPUMultimodalRoPEPipeline.hpp" +// #include "Timing.hpp" +#include "Types.hpp" +#include +#include +#include +// #include +#include "backends/cpu/quantize/QuantizeQ8.hpp" + +namespace mllm { + +vector CPUMultimodalRoPEPipeline::theta_; // inv_freq + +vector> CPUMultimodalRoPEPipeline::sin_; +vector> CPUMultimodalRoPEPipeline::cos_; +int CPUMultimodalRoPEPipeline::ishape_old; +int CPUMultimodalRoPEPipeline::last_pos; + +// to avoid conflict with CPUMultimodalRoPE +namespace pipeline_rope { +typedef float (*mllm_rope_init_func)(const OpParam &, std::vector &); + +float multimodal_default_init_rope(const OpParam &config, vector &theta) { + auto base = config.at("base"); // theta_i = base^-(2i/dim) = 1 / base^(2i/dim) i from 0 to (dim/2 - 1) + auto dim = config.at("dim"); + + theta.resize((int)(dim / 2)); +#pragma omp parallel for num_threads(4) + for (int i = 0; i < theta.size(); i++) + theta[i] = 1.0 / pow(base, 2.0 * i / dim); + + return 1.0; +} + +void apply_multimodal_rotary_pos_emb( + const std::vector>> &in_cos, + const std::vector>> &in_sin, + std::vector> &out_cos, + std::vector> &out_sin, + const std::vector &mrope_section) { + int num_rows = in_cos[0].size(); + int num_cols = in_cos[0][0].size(); + // 初始化输出向量大小 + out_cos.resize(num_rows, std::vector(num_cols)); + out_sin.resize(num_rows, std::vector(num_cols)); + // 计算每个块的起始列索引 + std::vector start_cols; + int current_start = 0; + start_cols.push_back(current_start); + for (int s : mrope_section) { + current_start += s; + start_cols.push_back(current_start); + } + // 遍历每个块 + for (int j = 0; j < mrope_section.size(); ++j) { + int layer = j % 3; + int s_j = mrope_section[j]; + int start_col_in = start_cols[j]; + int start_col_out = start_cols[j]; // 输出和输入的起始列相同 + for (int row = 0; row < num_rows; ++row) { + // 处理cos + const auto &in_cos_row = in_cos[layer][row]; + auto &out_cos_row = out_cos[row]; + for (int c = 0; c < s_j; ++c) { + out_cos_row[start_col_out + c] = in_cos_row[start_col_in + c]; + } + // 处理sin + const auto &in_sin_row = in_sin[layer][row]; + auto &out_sin_row = out_sin[row]; + for (int c = 0; c < s_j; ++c) { + out_sin_row[start_col_out + c] = in_sin_row[start_col_in + c]; + } + } + } +} + +void multimodal_sinusoidal_position_embedding(shared_ptr position_ids, int seq_len, int output_dim, const vector &theta, + vector> &sin, vector> &cos, float attention_scaling = 1.0, + const std::vector &mrope_section = {}) { + vector>> tmp_sin; + vector>> tmp_cos; + for (int b = 0; b < position_ids->batch(); ++b) { + vector> cos_freqs(position_ids->dimension(), std::vector(theta.size() * 2, 0)); + vector> sin_freqs(position_ids->dimension(), std::vector(theta.size() * 2, 0)); + for (int i = 0; i < theta.size(); ++i) { + for (int j = 0; j < position_ids->dimension(); ++j) { + auto value = theta[i] * position_ids->dataAt(b, 0, 0, j); + cos_freqs[j][i] = cosf(value) * attention_scaling; + cos_freqs[j][i + theta.size()] = cosf(value) * attention_scaling; + sin_freqs[j][i] = sinf(value) * attention_scaling; + sin_freqs[j][i + theta.size()] = sinf(value) * attention_scaling; + } + } + tmp_cos.push_back(cos_freqs); + tmp_sin.push_back(sin_freqs); + } + if (!mrope_section.empty()) { + apply_multimodal_rotary_pos_emb(tmp_cos, tmp_sin, cos, sin, mrope_section); + } +} +} // namespace pipeline_rope + +CPUMultimodalRoPEPipeline::CPUMultimodalRoPEPipeline(Backend *bn, string opName, float rope_theta, int max_position_embeddings, vector mrope_section, int threadCount) : + thread_count(threadCount), + Op(bn, opName) { + rope_theta_ = rope_theta; + pos_max_ = max_position_embeddings; + mrope_section_ = mrope_section; + for (int i = 0; i < mrope_section.size(); i++) { + mrope_section_.push_back(mrope_section[i]); + } +} + +ErrorCode CPUMultimodalRoPEPipeline::reshape(vector> inputs, vector> outputs) { + assert(inputs.size() == 2); + assert(outputs.size() == 1); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + ishape = inputs[0]->dimension() * partial_rotary_factor_; + // pos_max_ = 16384; + auto position_ids = inputs[1]; + + if (sin_.empty() || ishape_old < ishape || position_ids->dataAt(0, 0, 0, position_ids->dimension() - 1) != last_pos) { + auto config = config_; + config["base"] = (float)rope_theta_; + config["dim"] = ishape; + float attention_scaling = pipeline_rope::multimodal_default_init_rope(config, theta_); + ishape_old = ishape; + last_pos = position_ids->dataAt(0, 0, 0, position_ids->dimension() - 1); + pipeline_rope::multimodal_sinusoidal_position_embedding(position_ids, pos_max_, ishape, theta_, sin_, cos_, attention_scaling, mrope_section_); + } + + // if in switching, reset the h_cnt_ + auto cpuBackend = static_cast(backend_); + if (cpuBackend->isStageSwitching()) { + if(cpuBackend->getExecutionType() == PROMPT) { + // set to 0/chunk_size*iter when in prefill stage + h_cnt_ = cpuBackend->getCurSequenceLength(); + } else { + // when switch to decoding, reset the h_cnt_ to 0 + h_cnt_ = 0; + } + + } + return Op::reshape(inputs, outputs); +} + +void CPUMultimodalRoPEPipeline::multimodal_rope_hf(shared_ptr input, shared_ptr output) { + auto out_dtype = output->dtype(); + int partial_dimension = (input->dimension()) * partial_rotary_factor_; + int half = (int)(partial_dimension / 2); + assert(partial_dimension % 2 == 0); + + const int seq_offset = h_cnt_; + if (static_cast(backend_)->getExecutionType() == PROMPT) { + // increment the h_cnt_ when in prefill stage + h_cnt_ += input->sequence(); + } + + if (output->ctype() == BSHD) { + if (input->dtype() == MLLM_TYPE_F16) { +#pragma omp parallel for collapse(4) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { // sequance + for (int d = 0; d < partial_dimension / 2; ++d) { + auto v = input->ptrAt(n, h, s, d); + auto o = output->ptrAt(n, h, s, d); + float in_value = static_cast(v[0]); + float in_value_2 = static_cast(v[half]); + float sin_value = sin_[s + seq_offset][d]; + float cos_value = cos_[s + seq_offset][d]; + auto value = in_value * cos_value - in_value_2 * sin_value; + auto value2 = in_value * sin_value + in_value_2 * cos_value; + o[0] = MLLM_FP32_TO_FP16(value); + o[half] = MLLM_FP32_TO_FP16(value2); + } + } + } + } + + } else { + if (out_dtype == MLLM_TYPE_F32) { +#pragma omp parallel for collapse(4) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { // sequance + for (int d = 0; d < partial_dimension / 2; ++d) { + auto v = input->ptrAt(n, h, s, d); + auto o = output->ptrAt(n, h, s, d); + float in_value = v[0]; + float in_value_2 = v[half]; + float sin_value = sin_[s + seq_offset][d]; + float cos_value = cos_[s + seq_offset][d]; + auto value = in_value * cos_value - in_value_2 * sin_value; + auto value2 = in_value * sin_value + in_value_2 * cos_value; + o[0] = value; + o[half] = value2; + } + } + } + } + } else if (out_dtype == MLLM_TYPE_F16) { +#pragma omp parallel for collapse(4) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { // sequance + for (int d = 0; d < partial_dimension / 2; ++d) { + auto v = input->ptrAt(n, h, s, d); + auto o = output->ptrAt(n, h, s, d); + float in_value = v[0]; + float in_value_2 = v[half]; + float sin_value = sin_[s + seq_offset][d]; + float cos_value = cos_[s + seq_offset][d]; + auto value = in_value * cos_value - in_value_2 * sin_value; + auto value2 = in_value * sin_value + in_value_2 * cos_value; + o[0] = MLLM_FP32_TO_FP16(value); + o[half] = MLLM_FP32_TO_FP16(value2); + } + } + } + } + } + } + return; + } +#pragma omp parallel for collapse(4) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { // sequance + for (int d = 0; d < partial_dimension / 2; ++d) { + if (input->dtype() == MLLM_TYPE_F16) { + float in_value = static_cast(input->dataAt(n, h, s, d)); + float in_value_2 = static_cast(input->dataAt(n, h, s, d + partial_dimension / 2)); + float sin_value = sin_[s + seq_offset][d]; + float cos_value = cos_[s + seq_offset][d]; + auto value = in_value * cos_value - in_value_2 * sin_value; + auto value2 = in_value * sin_value + in_value_2 * cos_value; + if (out_dtype == MLLM_TYPE_F32) { + output->setDataAt(n, h, s, d, value); + output->setDataAt(n, h, s, d + partial_dimension / 2, value2); + } else if (out_dtype == MLLM_TYPE_F16) { + output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); + output->setDataAt(n, h, s, d + partial_dimension / 2, MLLM_FP32_TO_FP16(value2)); + } + + } else { + float in_value = input->dataAt(n, h, s, d); + float in_value_2 = input->dataAt(n, h, s, d + partial_dimension / 2); + float sin_value = sin_[s + seq_offset][d]; + float cos_value = cos_[s + seq_offset][d]; + auto value = in_value * cos_value - in_value_2 * sin_value; + auto value2 = in_value * sin_value + in_value_2 * cos_value; + if (out_dtype == MLLM_TYPE_F32) { + output->setDataAt(n, h, s, d, value); + output->setDataAt(n, h, s, d + partial_dimension / 2, value2); + } else if (out_dtype == MLLM_TYPE_F16) { + output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); + output->setDataAt(n, h, s, d + partial_dimension / 2, MLLM_FP32_TO_FP16(value2)); + } + } + } + } + } + } +} + +// TODO: Q8_0 KVCache can not use!! +ErrorCode CPUMultimodalRoPEPipeline::execute(vector> inputs, vector> outputs) { + if (outputs[0]->dtype() == MLLM_TYPE_Q8_0) { + auto tmp_out = std::make_shared(outputs[0]->backend()); + // tmp_out->setBackend(outputs[0]->backend()); + auto b = outputs[0]->batch(); + auto h = outputs[0]->head(); + auto d = outputs[0]->dimension(); + auto s = outputs[0]->sequence(); + tmp_out->chls() = outputs[0]->chls(); + tmp_out->setCtype(outputs[0]->ctype()); + tmp_out->reshape(b, h, s, d); + tmp_out->setDtype(MLLM_TYPE_F32); + tmp_out->alloc(); + doExecute(inputs, {tmp_out}); +#pragma omp parallel for collapse(3) num_threads(thread_count) + for (int b = 0; b < tmp_out->batch(); b++) { + for (int h = 0; h < tmp_out->head(); h++) { + for (int s = 0; s < tmp_out->sequence(); s++) { + quantize_row_q8_0(tmp_out->hostPtr() + tmp_out->offset(b, h, s, 0), + (char *)outputs[0]->rawHostPtr() + + outputs[0]->offset(b, h, s, 0) * sizeof(block_q8_0) / QK8_0, + tmp_out->dimension()); + } + } + } + return MLLM_NO_ERROR; + } else { + return doExecute(inputs, outputs); + } +} +ErrorCode CPUMultimodalRoPEPipeline::doExecute(vector> inputs, vector> outputs) { + auto &input = inputs[0]; + auto &output = outputs[0]; + auto out_dtype = output->dtype(); + int partial_dimension = (input->dimension()) * partial_rotary_factor_; + // auto start_t = mllm_time_us(); + multimodal_rope_hf(input, output); +#pragma omp parallel for collapse(4) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { + for (int d = partial_dimension; d < input->dimension(); ++d) { + if (out_dtype == MLLM_TYPE_F32) { + output->setDataAt(n, h, s, d, input->dataAt(n, h, s, d)); + } else if (out_dtype == MLLM_TYPE_F16) { + output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(input->dataAt(n, h, s, d))); + } + } + } + } + } + + return Op::execute(inputs, outputs); +} + +ErrorCode CPUMultimodalRoPEPipeline::load(AbstructLoader &loader) { + return Op::load(loader); +} +ErrorCode CPUMultimodalRoPEPipeline::free(vector> inputs, vector> outputs) { + return Op::free(inputs, outputs); +} +} // namespace mllm diff --git a/src/backends/cpu/op/CPUMultimodalRoPEPipeline.hpp b/src/backends/cpu/op/CPUMultimodalRoPEPipeline.hpp new file mode 100644 index 000000000..9b37e0948 --- /dev/null +++ b/src/backends/cpu/op/CPUMultimodalRoPEPipeline.hpp @@ -0,0 +1,72 @@ +#ifndef MLLM_CPUMULTIMODALROPE_PIPELINE_H +#define MLLM_CPUMULTIMODALROPE_PIPELINE_H + +#include "Op.hpp" +#include "../CPUBackend.hpp" + +namespace mllm { + +class CPUMultimodalRoPEPipeline final : public Op { +public: + CPUMultimodalRoPEPipeline(Backend *bn, string opName, float rope_theta, int max_position_embeddings, vector mrope_section, int threadCount); + + virtual ~CPUMultimodalRoPEPipeline() = default; + virtual ErrorCode reshape(vector> inputs, vector> outputs) override; + virtual ErrorCode load(AbstructLoader &loader) override; + virtual ErrorCode execute(vector> inputs, vector> outputs) override; + virtual ErrorCode free(vector> inputs, vector> outputs) override; + ErrorCode doExecute(vector> inputs, vector> outputs); + +private: + static vector theta_; // inv_freq + static vector> sin_; + static vector> cos_; + static int ishape_old; + static int last_pos; + vector mrope_section_; + int rope_theta_ = 10000; + int h_cnt_ = 0; + int pos_max_ = 16384; + int ishape; + int thread_count = 4; + float partial_rotary_factor_ = 1; + + OpParam config_; + + RoPEThetaType rope_type = DEFAULT; + + void multimodal_rope_hf(shared_ptr input, shared_ptr output); + void clearCache() override { + h_cnt_ = 0; + } +}; + +class CPUMultimodalRoPEPipelineCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + // int pose_type = op_param["pose_type"]; + // if (op_param.find("rope_theta") == op_param.end()) { + // return new CPUMultimodalRoPEPipeline(bn, name, pose_type, threadCount); + // } + // float rope_theta = op_param["rope_theta"]; + // int max_position_embeddings = op_param["max_position_embeddings"]; + // if (op_param.find("partial_rotary_factor") == op_param.end()) { + // return new CPUMultimodalRoPEPipeline(bn, name, pose_type, rope_theta, max_position_embeddings, threadCount); + // } + // float partial_rotary_factor = op_param["partial_rotary_factor"]; + // return new CPUMultimodalRoPEPipeline(bn, name, pose_type, rope_theta, partial_rotary_factor, max_position_embeddings, threadCount); + + // int pose_type = op_param["pose_type"]; + float rope_theta = op_param["rope_theta"]; + int max_position_embeddings = op_param["max_position_embeddings"]; + int length = op_param.size() - 3; + vector mrope_section; + for (int i = 0; i < length; i++) { + mrope_section.push_back((int)op_param["mrope_section_" + std::to_string(i)]); + } + return new CPUMultimodalRoPEPipeline(bn, name, rope_theta, max_position_embeddings, mrope_section, threadCount); + } +}; +} // namespace mllm + +#endif // MLLM_CPUMULTIMODALROPE_PIPELINE_H \ No newline at end of file diff --git a/src/backends/cpu/op/CPUQuantize.cpp b/src/backends/cpu/op/CPUQuantize.cpp index fa4060f8f..11207ea9d 100644 --- a/src/backends/cpu/op/CPUQuantize.cpp +++ b/src/backends/cpu/op/CPUQuantize.cpp @@ -6,11 +6,16 @@ #include "Types.hpp" #include "backends/cpu/quantize/QuantizeQ8.hpp" +#include +#include #include namespace mllm { -CPUQuantize::CPUQuantize(Backend *bn, string opName, int threadCount):thread_count(threadCount), Op(bn, std::move(opName)) { - activation_dtype_ = MLLM_TYPE_I8; +CPUQuantize::CPUQuantize(Backend *bn, string opName, DataType type, int threadCount) : + thread_count(threadCount), + Op(bn, std::move(opName)) { + assert(type == MLLM_TYPE_I8 || type == MLLM_TYPE_I16); + activation_dtype_ = type; scale_.setBackend(bn); } @@ -30,46 +35,53 @@ ErrorCode CPUQuantize::execute(vector> inputs, vectordimension(); float quantScale = 0; - quantScale = scale_.hostPtr()[0] / 127.0; - quantScale = roundf(quantScale * 100000) / 100000; + // quantScale = scale_.hostPtr()[0] / 127.0; + // quantScale = roundf(quantScale * 100000) / 100000; + switch (activation_dtype_) { + case MLLM_TYPE_I8: + quantScale = scale_.hostPtr()[0] / (pow(2, 7) - 1); + break; + case MLLM_TYPE_I16: + quantScale = scale_.hostPtr()[0] / (pow(2, 15) - 1); + break; + default: + return NOT_SUPPORT; + } + // quantScale = roundf(quantScale * 100000) / 100000; auto src0 = inputs[0]; - auto src0_i8 = outputs[0]; - -// #pragma omp parallel for collapse(4) - // for (int b = 0; b dataAt(b, h, s, d); - // int32_t v = static_cast(Round(value / quantScale)); - // v = std::max (std::min(v, 127), -128); - // output->setDataAt(b, h, s, d, static_cast(v)); - // } - // } - // std::cout << std::endl; - // } - // } + auto out0 = outputs[0]; + if (activation_dtype_ == MLLM_TYPE_I8) { #pragma omp parallel for collapse(3) num_threads(thread_count) - for (int b = 0; b < batch; b++) { - for (int h = 0; h hostPtr() + src0->offset(b, h, s, 0), - src0_i8->hostPtr() + src0_i8->offset(b, h, s, 0), + for (int b = 0; b < batch; b++) { + for (int h = 0; h < head; h++) { + for (int s = 0; s < seq; s++) { + quantize_row_i8(src0->hostPtr() + src0->offset(b, h, s, 0), + out0->hostPtr() + out0->offset(b, h, s, 0), dim, quantScale); + } + } + } + } else if (activation_dtype_ == MLLM_TYPE_I16) { +#pragma omp parallel for collapse(3) num_threads(thread_count) + for (int b = 0; b < batch; b++) { + for (int h = 0; h < head; h++) { + for (int s = 0; s < seq; s++) { + quantize_row_i16(src0->hostPtr() + src0->offset(b, h, s, 0), + out0->hostPtr() + out0->offset(b, h, s, 0), + dim, quantScale); + } } } + } else { + return NOT_SUPPORT; } - // outputs[0]->printData(); - - return Op::execute(inputs, outputs); } ErrorCode CPUQuantize::setUp(vector> inputs, vector> outputs) { - activation_dtype_ = MLLM_TYPE_I8; return Op::setUp(inputs, outputs); } diff --git a/src/backends/cpu/op/CPUQuantize.hpp b/src/backends/cpu/op/CPUQuantize.hpp index df3751ee1..13df2b2e0 100644 --- a/src/backends/cpu/op/CPUQuantize.hpp +++ b/src/backends/cpu/op/CPUQuantize.hpp @@ -7,10 +7,11 @@ #include "Op.hpp" #include "../CPUBackend.hpp" +#include "Types.hpp" namespace mllm { class CPUQuantize final : public Op { public: - CPUQuantize(Backend *bn, string opName, int threadCount); + CPUQuantize(Backend *bn, string opName, DataType type, int threadCount); virtual ~CPUQuantize() = default; virtual ErrorCode reshape(vector> inputs, vector> outputs) override; virtual ErrorCode execute(vector> inputs, vector> outputs) override; @@ -36,7 +37,7 @@ class CPUQuantize final : public Op { class CPUQuantizeCreator : public CPUBackend::Creator { public: virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { - return new CPUQuantize(bn, name, threadCount); + return new CPUQuantize(bn, name, (DataType)op_param["dtype"], threadCount); } }; } // namespace mllm diff --git a/src/backends/cpu/quantize/QuantizeQ8.cpp b/src/backends/cpu/quantize/QuantizeQ8.cpp index 44e16292d..35f51f7e8 100644 --- a/src/backends/cpu/quantize/QuantizeQ8.cpp +++ b/src/backends/cpu/quantize/QuantizeQ8.cpp @@ -541,4 +541,84 @@ void quantize_round_dequantize_row_i8(const float *__restrict vx, float *__restr } } +// per-tensor int16 +void quantize_row_i16(const float *__restrict x, void *__restrict vy, int k, float scale) { + const int BLOCK_SIZE = 32; + assert(k % BLOCK_SIZE == 0); + const int nb = k / BLOCK_SIZE; + + int16_t *__restrict y = (int16_t *)vy; + + const float d = scale; + const float id = d ? 1.0f / d : 0.0f; + +#if defined(__ARM_NEON) + const int32x4_t min_32768 = vdupq_n_s32(-32768); + const int32x4_t max32767 = vdupq_n_s32(32767); + + for (int i = 0; i < nb; i++) { + float32x4_t srcv[8]; + for (int j = 0; j < 8; j++) srcv[j] = vld1q_f32(x + i * 32 + 4 * j); + + for (int j = 0; j < 8; j++) { + const float32x4_t v = vmulq_n_f32(srcv[j], id); + int32x4_t vi = vcvtnq_s32_f32(v); + + vi = vminq_s32(vi, max32767); + vi = vmaxq_s32(vi, min_32768); + + y[i * 32 + 4 * j + 0] = (int16_t)vgetq_lane_s32(vi, 0); + y[i * 32 + 4 * j + 1] = (int16_t)vgetq_lane_s32(vi, 1); + y[i * 32 + 4 * j + 2] = (int16_t)vgetq_lane_s32(vi, 2); + y[i * 32 + 4 * j + 3] = (int16_t)vgetq_lane_s32(vi, 3); + } + } +#else + // fallback scalar version + for (int i = 0; i < k; i++) { + int v = (int)roundf(x[i] * id); + if (v < -32768) v = -32768; + if (v > 32767) v = 32767; + y[i] = (int16_t)v; + } +#endif +} + +void dequantize_row_i16(const void *__restrict vx, float *__restrict y, int k, float scale) { +#if defined(__ARM_NEON) + const int16_t *__restrict x = (int16_t *)vx; + + float32x4_t scale_vec = vdupq_n_f32(scale); + + int i; + for (i = 0; i <= k - 8; i += 8) { + // Load 8 int16_t values + int16x8_t x_vec = vld1q_s16(&x[i]); + + // Split into lower and upper 4 elements + int32x4_t x_lo = vmovl_s16(vget_low_s16(x_vec)); // 前4个 int16 -> int32 + int32x4_t x_hi = vmovl_s16(vget_high_s16(x_vec)); // 后4个 int16 -> int32 + + // Convert to float32 + float32x4_t x_f32_lo = vcvtq_f32_s32(x_lo); + float32x4_t x_f32_hi = vcvtq_f32_s32(x_hi); + + // Multiply by scale + x_f32_lo = vmulq_f32(x_f32_lo, scale_vec); + x_f32_hi = vmulq_f32(x_f32_hi, scale_vec); + + // Store result + vst1q_f32(&y[i], x_f32_lo); + vst1q_f32(&y[i + 4], x_f32_hi); + } + + // Handle remaining elements + for (; i < k; i++) { + y[i] = x[i] * scale; + } +#else +// TODO: avx +#endif +} + // #endif \ No newline at end of file diff --git a/src/backends/cpu/quantize/QuantizeQ8.hpp b/src/backends/cpu/quantize/QuantizeQ8.hpp index defb69943..77ead9267 100644 --- a/src/backends/cpu/quantize/QuantizeQ8.hpp +++ b/src/backends/cpu/quantize/QuantizeQ8.hpp @@ -40,5 +40,8 @@ void quantize_row_i8(const float *__restrict x, void *__restrict y, int k, float void dequantize_row_i8(const void *__restrict vx, float *__restrict y, int k, float scale = 1.f); void dequantize_row_i8_to_fp16(const void *__restrict vx, void *__restrict vy, int k, float scale = 1.f); void quantize_round_dequantize_row_i8(const float *__restrict vx, float *__restrict y, int k, float scale = 1.f); +// per-tensor int16 quantize +void quantize_row_i16(const float *__restrict x, void *__restrict y, int k, float scale = 1.f); +void dequantize_row_i16(const void *__restrict vx, float *__restrict y, int k, float scale = 1.f); #endif // MLLM_QUANTIZEQ8_HPP diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/config/LLaMAOpPackageHtp.xml b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/config/LLaMAOpPackageHtp.xml index 259f786ef..b302f2513 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/config/LLaMAOpPackageHtp.xml +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/config/LLaMAOpPackageHtp.xml @@ -729,6 +729,70 @@ Confidential and Proprietary - Qualcomm Technologies, Inc. HTP + + + LLaMADequantizeAdd + + + LLaMA Dequantize and Add + + + + + in[0] + + input activation + + true + BACKEND_SPECIFIC + + 4D + NHWC + [N, C, H , W] + + + + + in[1] + + input bias + + true + BACKEND_SPECIFIC + + 4D + NHWC + [N, C, H , W] + + + + + out[0] + + output activation + + true + BACKEND_SPECIFIC + + 4D + [N, C, H , W] + + + + + scale + true + QNN_DATATYPE_FLOAT_32 + + SCALAR + + N-1 + + + + HTP + + LLaMAQuantize @@ -1554,16 +1618,39 @@ Confidential and Proprietary - Qualcomm Technologies, Inc. out[0] QNN_DATATYPE_SFIXED_POINT_8 + QNN_DATATYPE_SFIXED_POINT_16 - + LLaMADequantize in[0] QNN_DATATYPE_SFIXED_POINT_8 + QNN_DATATYPE_SFIXED_POINT_16 + + + out[0] + QNN_DATATYPE_FLOAT_16 + QNN_DATATYPE_FLOAT_32 + + + + + + LLaMADequantizeAdd + + + in[0] + QNN_DATATYPE_SFIXED_POINT_8 + QNN_DATATYPE_SFIXED_POINT_16 + + + in[1] + QNN_DATATYPE_FLOAT_16 + QNN_DATATYPE_FLOAT_32 out[0] diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/LLaMAPackageInterface.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/LLaMAPackageInterface.cpp index de7261b56..85448fb63 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/LLaMAPackageInterface.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/LLaMAPackageInterface.cpp @@ -19,32 +19,33 @@ BEGIN_PKG_OPS_OPTS_LIST() * registered to the HTP Core. * Append the latest OpName at the bottom */ -DECLARE_PKG_OPS_OPTS_LIST(PKG_IRoPE) -DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMALinear) -DECLARE_PKG_OPS_OPTS_LIST(PKG_SplitInput) -DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMAReLU) -DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMASuperSiLU) -DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMAQuantize) -DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMAMul) +DECLARE_PKG_OPS_OPTS_LIST(PKG_RMSNorm) DECLARE_PKG_OPS_OPTS_LIST(PKG_KVCache) +DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMADequantizeAdd) +DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMAMul) +DECLARE_PKG_OPS_OPTS_LIST(PKG_MergeOutput) +DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMAReLU) +DECLARE_PKG_OPS_OPTS_LIST(PKG_CausalMask) +DECLARE_PKG_OPS_OPTS_LIST(PKG_SiLU) DECLARE_PKG_OPS_OPTS_LIST(PKG_Attention) DECLARE_PKG_OPS_OPTS_LIST(PKG_QLayerNorm) +DECLARE_PKG_OPS_OPTS_LIST(PKG_RoPE) +DECLARE_PKG_OPS_OPTS_LIST(PKG_WNop) DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMAAdd) -DECLARE_PKG_OPS_OPTS_LIST(PKG_CausalMask) +DECLARE_PKG_OPS_OPTS_LIST(PKG_IRoPE) +DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMALinear) +DECLARE_PKG_OPS_OPTS_LIST(PKG_SplitInput) DECLARE_PKG_OPS_OPTS_LIST(PKG_HeadMatmul) -DECLARE_PKG_OPS_OPTS_LIST(PKG_RoPE) DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMADequantize) -DECLARE_PKG_OPS_OPTS_LIST(PKG_WNop) -DECLARE_PKG_OPS_OPTS_LIST(PKG_MergeOutput) -DECLARE_PKG_OPS_OPTS_LIST(PKG_RMSNorm) -DECLARE_PKG_OPS_OPTS_LIST(PKG_SiLU) +DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMASuperSiLU) +DECLARE_PKG_OPS_OPTS_LIST(PKG_LLaMAQuantize) END_PKG_OPS_OPTS_LIST() // op package info static constexpr auto sg_packageName = THIS_PKG_NAME_STR; // package name passed in as compile flag -static std::array sg_opNames{{"IRoPE", "LLaMALinear", "SplitInput", "LLaMAReLU", "LLaMASuperSiLU", "LLaMAQuantize", "LLaMAMul", "KVCache", "Attention", "QLayerNorm", "LLaMAAdd", "CausalMask", "HeadMatmul", "RoPE", "LLaMADequantize", "WNop", "MergeOutput", "RMSNorm", "SiLU"}}; +static std::array sg_opNames{{"RMSNorm", "KVCache", "LLaMADequantizeAdd", "LLaMAMul", "MergeOutput", "LLaMAReLU", "CausalMask", "SiLU", "Attention", "QLayerNorm", "RoPE", "WNop", "LLaMAAdd", "IRoPE", "LLaMALinear", "SplitInput", "HeadMatmul", "LLaMADequantize", "LLaMASuperSiLU", "LLaMAQuantize"}}; static Qnn_ApiVersion_t sg_sdkApiVersion = QNN_HTP_API_VERSION_INIT; static QnnOpPackage_Info_t sg_packageInfo = QNN_OP_PACKAGE_INFO_INIT; @@ -228,43 +229,43 @@ Qnn_ErrorHandle_t LLaMAPackageValidateOpConfig (Qnn_OpConfig_t opConfig){ * Check if op config type matches any registered ops * If a match is found, check number of inputs, outputs and params */ - if (std::string(opConfig.v1.typeName) == "IRoPE"){ - if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 4 || opConfig.v1.numOfOutputs != 1){ + if (std::string(opConfig.v1.typeName) == "RMSNorm"){ + if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "LLaMALinear"){ - if (opConfig.v1.numOfParams != 4 || opConfig.v1.numOfInputs != 3 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "KVCache"){ + if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "SplitInput"){ - if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 2){ + else if (std::string(opConfig.v1.typeName) == "LLaMADequantizeAdd"){ + if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "LLaMAReLU"){ - if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "LLaMAMul"){ + if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "LLaMASuperSiLU"){ - if (opConfig.v1.numOfParams != 3 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "MergeOutput"){ + if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 4 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "LLaMAQuantize"){ - if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "LLaMAReLU"){ + if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "LLaMAMul"){ - if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "CausalMask"){ + if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "KVCache"){ - if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "SiLU"){ + if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } @@ -278,48 +279,53 @@ Qnn_ErrorHandle_t LLaMAPackageValidateOpConfig (Qnn_OpConfig_t opConfig){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "LLaMAAdd"){ - if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "RoPE"){ + if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 4 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "CausalMask"){ - if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "WNop"){ + if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 2){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "HeadMatmul"){ - if (opConfig.v1.numOfParams != 2 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "LLaMAAdd"){ + if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "RoPE"){ + else if (std::string(opConfig.v1.typeName) == "IRoPE"){ if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 4 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "LLaMADequantize"){ - if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "LLaMALinear"){ + if (opConfig.v1.numOfParams != 4 || opConfig.v1.numOfInputs != 3 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "WNop"){ + else if (std::string(opConfig.v1.typeName) == "SplitInput"){ if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 2){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "MergeOutput"){ - if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 4 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "HeadMatmul"){ + if (opConfig.v1.numOfParams != 2 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "RMSNorm"){ - if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "LLaMADequantize"){ + if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } - else if (std::string(opConfig.v1.typeName) == "SiLU"){ - if (opConfig.v1.numOfParams != 0 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ + else if (std::string(opConfig.v1.typeName) == "LLaMASuperSiLU"){ + if (opConfig.v1.numOfParams != 3 || opConfig.v1.numOfInputs != 2 || opConfig.v1.numOfOutputs != 1){ + return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; + } + } + else if (std::string(opConfig.v1.typeName) == "LLaMAQuantize"){ + if (opConfig.v1.numOfParams != 1 || opConfig.v1.numOfInputs != 1 || opConfig.v1.numOfOutputs != 1){ return QNN_OP_PACKAGE_ERROR_VALIDATION_FAILURE; } } diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/Attention.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/Attention.cpp index e3db65468..559985e48 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/Attention.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/Attention.cpp @@ -9,18 +9,16 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_Attention); - // op execute function declarations -template +template GraphStatus attentionImpl(TensorType1 &out_0, const TensorType1 &in_0, const TensorType1 &in_1, - const TensorType& in_2, - const TensorType& in_3, - const TensorType& in_4); + const TensorType &in_2, + const TensorType &in_3, + const TensorType &in_4); // forward declaration of sample cost function static float attentionCostFunc(const Op *op); @@ -65,11 +63,11 @@ DEF_PACKAGE_OP((attentionImpl), "Attention") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -83,47 +81,41 @@ DEF_PACKAGE_OP((attentionImpl), "Attention") * Qnn_addNode */ - /* execute functions for ops */ -template +template GraphStatus attentionImpl(TensorType1 &out_0, const TensorType1 &in_0, const TensorType1 &in_1, - const TensorType& in_2, - const TensorType& in_3, - const TensorType& in_4) + const TensorType &in_2, + const TensorType &in_3, + const TensorType &in_4) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - return GraphStatus::Success; + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + return GraphStatus::Success; } -__attribute__((unused)) static float attentionCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float attentionCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/CausalMask.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/CausalMask.cpp index c3100cea1..a9ab7cd61 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/CausalMask.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/CausalMask.cpp @@ -13,11 +13,10 @@ BEGIN_PKG_OP_DEFINITION(PKG_CausalMask); - // op execute function declarations -template -GraphStatus causalmaskImpl(TensorType& out_0, - const TensorType& in_0); +template +GraphStatus causalmaskImpl(TensorType &out_0, + const TensorType &in_0); // forward declaration of sample cost function static float causalmaskCostFunc(const Op *op); @@ -62,11 +61,11 @@ DEF_PACKAGE_OP((causalmaskImpl), "CausalMask") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -80,78 +79,67 @@ DEF_PACKAGE_OP((causalmaskImpl), "CausalMask") * Qnn_addNode */ - /* execute functions for ops */ -template -GraphStatus causalmaskImpl(TensorType& out_0, - const TensorType& in_0) +template +GraphStatus causalmaskImpl(TensorType &out_0, + const TensorType &in_0) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - out_0.set_dims(in_0); - - int old_dim = 0; - - // NHSD - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - // S > 1 => mask - if (w_in > 1) { - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // CausalMask - for (Idx d = 0; d < d_in; d++) { - - float in_value = in_0(b, h, w, d); - - if (d > w + old_dim) - out_0(b, h, w, d) = in_value - MASK_INFINITY; - else - out_0(b, h, w, d) = in_value; - - } + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + out_0.set_dims(in_0); + + int old_dim = 0; + + // NHSD + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + + // S > 1 => mask + if (w_in > 1) { + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // CausalMask + for (Idx d = 0; d < d_in; d++) { + float in_value = in_0(b, h, w, d); + + if (d > w + old_dim) + out_0(b, h, w, d) = in_value - MASK_INFINITY; + else + out_0(b, h, w, d) = in_value; + } + } + } } - } + } else { + auto in_ptr = in_0.raw_data_const(); + auto out_ptr = out_0.raw_data(); + memcpy(out_ptr, in_ptr, b_in * h_in * w_in * d_in * 4); } - } else { - auto in_ptr = in_0.raw_data_const(); - auto out_ptr = out_0.raw_data(); - memcpy(out_ptr, in_ptr, b_in*h_in*w_in*d_in*4); - } - - - - return GraphStatus::Success; + return GraphStatus::Success; } -__attribute__((unused)) static float causalmaskCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float causalmaskCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/HeadMatmul.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/HeadMatmul.cpp index 18440880c..8dbd62f29 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/HeadMatmul.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/HeadMatmul.cpp @@ -9,25 +9,24 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_HeadMatmul); static Qnn_Scalar_t sg_opDefaultTranspose_In0Scalar = {.dataType = Qnn_DataType_t::QNN_DATATYPE_BOOL_8, - .bool8Value = false}; + .bool8Value = false}; static Qnn_Param_t sg_opDefaultTranspose_In0 = {.paramType = QNN_PARAMTYPE_SCALAR, - .scalarParam = sg_opDefaultTranspose_In0Scalar}; + .scalarParam = sg_opDefaultTranspose_In0Scalar}; static Qnn_Scalar_t sg_opDefaultTranspose_In1Scalar = {.dataType = Qnn_DataType_t::QNN_DATATYPE_BOOL_8, - .bool8Value = false}; + .bool8Value = false}; static Qnn_Param_t sg_opDefaultTranspose_In1 = {.paramType = QNN_PARAMTYPE_SCALAR, - .scalarParam = sg_opDefaultTranspose_In1Scalar}; + .scalarParam = sg_opDefaultTranspose_In1Scalar}; // op execute function declarations -template -GraphStatus headmatmulImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const QuantUint16Tensor& transpose_in0, - const QuantUint16Tensor& transpose_in1); +template +GraphStatus headmatmulImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const QuantUint16Tensor &transpose_in0, + const QuantUint16Tensor &transpose_in1); // forward declaration of sample cost function static float headmatmulCostFunc(const Op *op); @@ -72,11 +71,11 @@ DEF_PACKAGE_OP((headmatmulImpl), "HeadMatmul") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -89,7 +88,7 @@ DEF_PACKAGE_OP((headmatmulImpl), "HeadMatmul") * graph construction will skip this parameter when this parameter is not provided at * Qnn_addNode */ -DEF_PACKAGE_PARAM_ORDER("HeadMatmul", +DEF_PACKAGE_PARAM_ORDER("HeadMatmul", "transpose_in0", false, &sg_opDefaultTranspose_In0, @@ -97,77 +96,65 @@ DEF_PACKAGE_PARAM_ORDER("HeadMatmul", false, &sg_opDefaultTranspose_In1) - /* execute functions for ops */ -template -GraphStatus headmatmulImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const QuantUint16Tensor& transpose_in0, - const QuantUint16Tensor& transpose_in1) +template +GraphStatus headmatmulImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const QuantUint16Tensor &transpose_in0, + const QuantUint16Tensor &transpose_in1) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - auto transpose_in0_ = transpose_in0(0,0,0,0); - auto transpose_in1_ = transpose_in1(0,0,0,0); + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + + auto transpose_in0_ = transpose_in0(0, 0, 0, 0); + auto transpose_in1_ = transpose_in1(0, 0, 0, 0); auto [b_in, h_in, w_in, d_in] = in_0.dims(); auto [b_in2, h_in2, w_in2, d_in2] = in_1.dims(); if (transpose_in0_ && transpose_in1_) { - - // Q KT head matmul - const size_t dims[] = {b_in, w_in, h_in, h_in}; - out_0.set_dims(dims); - debuglog("HeadMatmul execute... dims=(%zdx%zdx%zdx%zd)", out_0.dim(0), out_0.dim(1), out_0.dim(2), out_0.dim(3)); - + // Q KT head matmul + const size_t dims[] = {b_in, w_in, h_in, h_in}; + out_0.set_dims(dims); + debuglog("HeadMatmul execute... dims=(%zdx%zdx%zdx%zd)", out_0.dim(0), out_0.dim(1), out_0.dim(2), out_0.dim(3)); } else if (transpose_in0_) { - } else if (transpose_in1_) { + // QKT V head matmul + const size_t dims[] = {b_in, w_in, h_in, d_in2}; + out_0.set_dims(dims); + debuglog("HeadMatmul execute... dims=(%zdx%zdx%zdx%zd)", out_0.dim(0), out_0.dim(1), out_0.dim(2), out_0.dim(3)); - // QKT V head matmul - const size_t dims[] = {b_in, w_in, h_in, d_in2}; - out_0.set_dims(dims); - debuglog("HeadMatmul execute... dims=(%zdx%zdx%zdx%zd)", out_0.dim(0), out_0.dim(1), out_0.dim(2), out_0.dim(3)); - - // Todo out matrix needs transpose, we directly calculate the final dimensions. + // Todo out matrix needs transpose, we directly calculate the final dimensions. } else { - } - - return GraphStatus::Success; + return GraphStatus::Success; } -__attribute__((unused)) static float headmatmulCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float headmatmulCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/IRoPE.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/IRoPE.cpp index b237b70af..a4fc6d757 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/IRoPE.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/IRoPE.cpp @@ -9,18 +9,16 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_IRoPE); - // op execute function declarations -template -GraphStatus iropeImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const TensorType& cos, +template +GraphStatus iropeImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const TensorType &cos, const TensorType1 &h_cnt, - const Tensor& pose_type); + const Tensor &pose_type); // forward declaration of sample cost function static float iropeCostFunc(const Op *op); @@ -65,11 +63,11 @@ DEF_PACKAGE_OP((iropeImpl), "IRoPE") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -82,142 +80,130 @@ DEF_PACKAGE_OP((iropeImpl), "IRoPE") * graph construction will skip this parameter when this parameter is not provided at * Qnn_addNode */ -DEF_PACKAGE_PARAM_ORDER("IRoPE", +DEF_PACKAGE_PARAM_ORDER("IRoPE", "pose_type", true, nullptr) - /* execute functions for ops */ -template -GraphStatus iropeImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& sin, - const TensorType& cos, +template +GraphStatus iropeImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &sin, + const TensorType &cos, const TensorType1 &h_cnt, - const Tensor& pose_type) + const Tensor &pose_type) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - auto pose_type_ = pose_type(0,0,0,0); - auto h_cnt_ = static_cast(h_cnt(0,0,0,0)); - - out_0.set_dims(in_0); - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - uint32_t half_dimension = d_in / 2; - - auto sin_ptr = (uint8_t*)sin.raw_data_const(); - auto cos_ptr = (uint8_t*)cos.raw_data_const(); - - auto in_ptr = (uint8_t*)in_0.raw_data_const(); - - sin_ptr += half_dimension * h_cnt_; - cos_ptr += half_dimension * h_cnt_; - - // float scale_ = in_0.get_interface_scale() * sin.get_interface_scale() * cos.get_interface_scale(); - - if (pose_type_ == 4) { - DType dtype = out_0.get_dtype(); - - if (dtype == DType::Float32) { - - auto out_ptr = (float*)out_0.raw_data(); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - - int partial_dimension = d_in; - for (Idx d = 0; d < partial_dimension / 2; ++d) { - int in_value = *in_ptr; - int in_value_2 = *(in_ptr + half_dimension); - - int sin_value = *(sin_ptr+d); - int cos_value = *(cos_ptr+d); - float value = (in_value-128) * (cos_value-128) * cos.get_interface_scale() - (in_value_2-128) * (sin_value-128) * sin.get_interface_scale(); - float value2 = (in_value-128) * (sin_value-128) * sin.get_interface_scale() + (in_value_2-128) * (cos_value-128) * cos.get_interface_scale(); - - *out_ptr = value; - *(out_ptr + half_dimension) = value2; - - out_ptr++; - in_ptr++; + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + auto pose_type_ = pose_type(0, 0, 0, 0); + auto h_cnt_ = static_cast(h_cnt(0, 0, 0, 0)); + + out_0.set_dims(in_0); + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + + uint32_t half_dimension = d_in / 2; + + auto sin_ptr = (uint8_t *)sin.raw_data_const(); + auto cos_ptr = (uint8_t *)cos.raw_data_const(); + + auto in_ptr = (uint8_t *)in_0.raw_data_const(); + + sin_ptr += half_dimension * h_cnt_; + cos_ptr += half_dimension * h_cnt_; + + // float scale_ = in_0.get_interface_scale() * sin.get_interface_scale() * cos.get_interface_scale(); + + if (pose_type_ == 4) { + DType dtype = out_0.get_dtype(); + + if (dtype == DType::Float32) { + auto out_ptr = (float *)out_0.raw_data(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + int partial_dimension = d_in; + for (Idx d = 0; d < partial_dimension / 2; ++d) { + int in_value = *in_ptr; + int in_value_2 = *(in_ptr + half_dimension); + + int sin_value = *(sin_ptr + d); + int cos_value = *(cos_ptr + d); + float value = (in_value - 128) * (cos_value - 128) * cos.get_interface_scale() - (in_value_2 - 128) * (sin_value - 128) * sin.get_interface_scale(); + float value2 = (in_value - 128) * (sin_value - 128) * sin.get_interface_scale() + (in_value_2 - 128) * (cos_value - 128) * cos.get_interface_scale(); + + *out_ptr = value; + *(out_ptr + half_dimension) = value2; + + out_ptr++; + in_ptr++; + } + + in_ptr += half_dimension; + out_ptr += half_dimension; + } + + sin_ptr += half_dimension; + cos_ptr += half_dimension; + } } - - in_ptr += half_dimension; - out_ptr += half_dimension; - } - - sin_ptr += half_dimension; - cos_ptr += half_dimension; - - } - } - } else if (dtype == DType::Float16) { - - auto out_ptr = (__fp16*)out_0.raw_data(); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - - int partial_dimension = d_in; - for (Idx d = 0; d < partial_dimension / 2; ++d) { - int in_value = *in_ptr; - int in_value_2 = *(in_ptr + half_dimension); - - int sin_value = *(sin_ptr+d); - int cos_value = *(cos_ptr+d); - float value = (in_value-128) * (cos_value-128) * cos.get_interface_scale() - (in_value_2-128) * (sin_value-128) * sin.get_interface_scale(); - float value2 = (in_value-128) * (sin_value-128) * sin.get_interface_scale() + (in_value_2-128) * (cos_value-128) * cos.get_interface_scale(); - - *out_ptr = static_cast<__fp16>(value); - *(out_ptr + half_dimension) = static_cast<__fp16>(value2); - - out_ptr++; - in_ptr++; + } else if (dtype == DType::Float16) { + auto out_ptr = (__fp16 *)out_0.raw_data(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + int partial_dimension = d_in; + for (Idx d = 0; d < partial_dimension / 2; ++d) { + int in_value = *in_ptr; + int in_value_2 = *(in_ptr + half_dimension); + + int sin_value = *(sin_ptr + d); + int cos_value = *(cos_ptr + d); + float value = (in_value - 128) * (cos_value - 128) * cos.get_interface_scale() - (in_value_2 - 128) * (sin_value - 128) * sin.get_interface_scale(); + float value2 = (in_value - 128) * (sin_value - 128) * sin.get_interface_scale() + (in_value_2 - 128) * (cos_value - 128) * cos.get_interface_scale(); + + *out_ptr = static_cast<__fp16>(value); + *(out_ptr + half_dimension) = static_cast<__fp16>(value2); + + out_ptr++; + in_ptr++; + } + + in_ptr += half_dimension; + out_ptr += half_dimension; + } + + sin_ptr += half_dimension; + cos_ptr += half_dimension; + } } - - in_ptr += half_dimension; - out_ptr += half_dimension; - } - - sin_ptr += half_dimension; - cos_ptr += half_dimension; - } - } - } - } + } - return GraphStatus::Success; + return GraphStatus::Success; } -__attribute__((unused)) static float iropeCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float iropeCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/KVCache.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/KVCache.cpp index 6d3ecb2d3..bf11ce8c8 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/KVCache.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/KVCache.cpp @@ -9,16 +9,14 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_KVCache); - // op execute function declarations -template -GraphStatus kvcacheImpl(TensorType& out_0, - const TensorType& in_0, +template +GraphStatus kvcacheImpl(TensorType &out_0, + const TensorType &in_0, const TensorType1 &seq_pos, - const Tensor& hidden_dim); + const Tensor &hidden_dim); // forward declaration of sample cost function static float kvcacheCostFunc(const Op *op); @@ -63,11 +61,11 @@ DEF_PACKAGE_OP((kvcacheImpl), "KVCache") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -80,12 +78,11 @@ DEF_PACKAGE_OP((kvcacheImpl), "KVCache") * graph construction will skip this parameter when this parameter is not provided at * Qnn_addNode */ -DEF_PACKAGE_PARAM_ORDER("KVCache", +DEF_PACKAGE_PARAM_ORDER("KVCache", "hidden_dim", true, nullptr) - /* execute functions for ops */ // #ifndef REFERENCE_OP @@ -100,7 +97,6 @@ DEF_PACKAGE_PARAM_ORDER("KVCache", // #define ONE 0x3F800000 // #define M_ONE 0xAF800000 - // int32_t hvx_memcpy_af(float *restrict input, float *restrict output, uint32_t size) // { // HVX_Vector *input_v_ptr; @@ -113,7 +109,6 @@ DEF_PACKAGE_PARAM_ORDER("KVCache", // int32_t vectors_in_rounddown = size / 32; // int32_t leftover_size = leftover * sizeof(float); - // /* Check input arguments. Return error status if some argument has invalid value */ // if ((input == 0) || (output == 0) || (size == 0)) // { @@ -187,7 +182,6 @@ DEF_PACKAGE_PARAM_ORDER("KVCache", // return 0; // } - // template // GraphStatus kvcacheImpl(TensorType& out_0, // const TensorType& in_0, @@ -207,10 +201,10 @@ DEF_PACKAGE_PARAM_ORDER("KVCache", // * // * Please check in SDK documentation for more information. // */ - + // out_0.set_dims(in_0); // auto [b_in, h_in, w_in, d_in] = in_0.dims(); - + // uint32_t seq_pos_ = seq_pos(0,0,0,0); // // uint32_t hidden_dim_ = hidden_dim(0,0,0,0); @@ -226,91 +220,76 @@ DEF_PACKAGE_PARAM_ORDER("KVCache", // hvx_memcpy_af(out_ptr, in_ptr, h_in * w_in * d_in); - // return GraphStatus::Success; // } - // #else -template -GraphStatus kvcacheImpl(TensorType& out_0, - const TensorType& in_0, +template +GraphStatus kvcacheImpl(TensorType &out_0, + const TensorType &in_0, const TensorType1 &seq_pos, - const Tensor& hidden_dim) + const Tensor &hidden_dim) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - uint32_t seq_pos_ = seq_pos(0,0,0,0); - const size_t dims[] = {b_in, h_in + seq_pos_, w_in, d_in}; - - out_0.set_dims(dims); - - // uint32_t hidden_dim_ = hidden_dim(0,0,0,0); - - // // const size_t dims[] = {b_in, h_in, seq_pos_+1, hidden_dim_}; - // // out_0.set_dims(dims); - - // NSHD + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + + uint32_t seq_pos_ = seq_pos(0, 0, 0, 0); + const size_t dims[] = {b_in, h_in + seq_pos_, w_in, d_in}; + + out_0.set_dims(dims); + + // uint32_t hidden_dim_ = hidden_dim(0,0,0,0); + + // // const size_t dims[] = {b_in, h_in, seq_pos_+1, hidden_dim_}; + // // out_0.set_dims(dims); + + // NSHD DType dtype = in_0.get_dtype(); - const uint8_t *in_ptr = (uint8_t*)in_0.raw_data_const(); - uint8_t *out_ptr = (uint8_t*)out_0.raw_data(); + const uint8_t *in_ptr = (uint8_t *)in_0.raw_data_const(); + uint8_t *out_ptr = (uint8_t *)out_0.raw_data(); if (dtype == DType::QUInt8) { - out_ptr += seq_pos_ * w_in * d_in; memcpy(out_ptr, in_ptr, h_in * w_in * d_in * sizeof(uint8_t)); } else if (dtype == DType::Float16) { - out_ptr += seq_pos_ * w_in * d_in * sizeof(float) / 2; memcpy(out_ptr, in_ptr, h_in * w_in * d_in * sizeof(float) / 2); } else if (dtype == DType::Float32) { - out_ptr += seq_pos_ * w_in * d_in * sizeof(float); memcpy(out_ptr, in_ptr, h_in * w_in * d_in * sizeof(float)); } - - - - return GraphStatus::Success; + return GraphStatus::Success; } - // #endif +__attribute__((unused)) static float kvcacheCostFunc(const Op *op) { + /* + * add code here + * */ -__attribute__((unused)) static float kvcacheCostFunc(const Op *op) -{ - /* - * add code here - * */ - - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAAdd.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAAdd.cpp index f883d3cb3..99576ab8b 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAAdd.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAAdd.cpp @@ -9,15 +9,13 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_LLaMAAdd); - // op execute function declarations -template -GraphStatus llamaaddImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1); +template +GraphStatus llamaaddImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1); // forward declaration of sample cost function static float llamaaddCostFunc(const Op *op); @@ -62,11 +60,11 @@ DEF_PACKAGE_OP((llamaaddImpl), "LLaMAAdd") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -80,7 +78,6 @@ DEF_PACKAGE_OP((llamaaddImpl), "LLaMAAdd") * Qnn_addNode */ - /* execute functions for ops */ #ifndef REFERENCE_OP @@ -90,17 +87,15 @@ DEF_PACKAGE_OP((llamaaddImpl), "LLaMAAdd") #include #include -#define BLOCK_SIZE (8*1024/VLEN) /* vector chunks */ -#define L2FETCH_AHEAD (BLOCK_SIZE) +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) int32_t hvx_add_af( float *restrict input, float *restrict input2, float *restrict output, - uint32_t size) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + uint32_t size) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -120,25 +115,21 @@ int32_t hvx_add_af( sline1p = *iptr++; sline2p = *iptr2++; - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline2c = *iptr2++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); - // Our add consider uint8->int8 bugs from QNN. // sline2 = Q6_Vb_vsub_VbVb(sline2, v128); *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(sline1, sline2)); @@ -149,134 +140,116 @@ int32_t hvx_add_af( } if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - - sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) input2); - - // sline2 = Q6_Vb_vsub_VbVb(sline2, v128); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(sline1, sline2)); + sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); + // sline2 = Q6_Vb_vsub_VbVb(sline2, v128); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(sline1, sline2)); } // Handle leftover elements. if (leftover_size > 0) { - sline1c = (is_in_one_chunk(iptr, leftover_size, VLEN) - ? sline1p - : *iptr++); - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - + sline1c = (is_in_one_chunk(iptr, leftover_size, VLEN) ? sline1p : *iptr++); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sline2c = (is_in_one_chunk(iptr2, leftover_size, VLEN) - ? sline2p - : *iptr2++); - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); + sline2c = (is_in_one_chunk(iptr2, leftover_size, VLEN) ? sline2p : *iptr2++); + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); - // sline2 = Q6_Vb_vsub_VbVb(sline2, v128); - vstu_variable(optr, leftover_size, Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(sline1, sline2))); + // sline2 = Q6_Vb_vsub_VbVb(sline2, v128); + vstu_variable(optr, leftover_size, Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_VsfVsf(sline1, sline2))); } return 0; } -template -GraphStatus llamaaddImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1) +template +GraphStatus llamaaddImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ out_0.set_dims(in_0); - - auto in_ptr = (float*)in_0.raw_data_const(); - auto in2_ptr = (float*)in_1.raw_data_const(); - auto out_ptr = (float*)out_0.raw_data(); + auto in_ptr = (float *)in_0.raw_data_const(); + auto in2_ptr = (float *)in_1.raw_data_const(); + auto out_ptr = (float *)out_0.raw_data(); auto [b_in, h_in, w_in, d_in] = in_0.dims(); - size_t size = b_in*h_in*w_in*d_in; + size_t size = b_in * h_in * w_in * d_in; hvx_add_af(in_ptr, in2_ptr, out_ptr, size); - return GraphStatus::Success; + return GraphStatus::Success; } #else - -template -GraphStatus llamaaddImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1) +template +GraphStatus llamaaddImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - out_0.set_dims(in_0); - - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // mul - for (Idx d = 0; d < d_in; d++) { - float inval = in_0(b, h, w, d); - float inval2 = in_1(b, h, w, d); - float outval = inval + inval2; - - out_0(b, h, w, d) = outval; - - } + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + out_0.set_dims(in_0); + + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // mul + for (Idx d = 0; d < d_in; d++) { + float inval = in_0(b, h, w, d); + float inval2 = in_1(b, h, w, d); + float outval = inval + inval2; + + out_0(b, h, w, d) = outval; + } + } } - } } - - return GraphStatus::Success; + return GraphStatus::Success; } - - #endif -__attribute__((unused)) static float llamaaddCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float llamaaddCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMADequantize.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMADequantize.cpp index 6afb884f2..c8b03b53b 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMADequantize.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMADequantize.cpp @@ -9,15 +9,13 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_LLaMADequantize); - // op execute function declarations -template +template GraphStatus llamadequantizeImpl(TensorType1 &out_0, const TensorType1 &in_0, - const PlainFloatTensor& scale); + const PlainFloatTensor &scale); // forward declaration of sample cost function static float llamadequantizeCostFunc(const Op *op); @@ -62,11 +60,11 @@ DEF_PACKAGE_OP((llamadequantizeImpl), "LLaMADequantize") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -79,7 +77,7 @@ DEF_PACKAGE_OP((llamadequantizeImpl), "LLaMADequantize") * graph construction will skip this parameter when this parameter is not provided at * Qnn_addNode */ -DEF_PACKAGE_PARAM_ORDER("LLaMADequantize", +DEF_PACKAGE_PARAM_ORDER("LLaMADequantize", "scale", true, nullptr) @@ -91,11 +89,10 @@ DEF_PACKAGE_PARAM_ORDER("LLaMADequantize", #include #include -#define BLOCK_SIZE (8*1024/VLEN) /* vector chunks */ -#define L2FETCH_AHEAD (BLOCK_SIZE) +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) -static inline int32_t float_to_fp16s(float input) -{ +static inline int32_t float_to_fp16s(float input) { union { int32_t i; __fp16 f[2]; @@ -103,35 +100,33 @@ static inline int32_t float_to_fp16s(float input) return fp32.i; } -static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) -{ - union { float f; uint32_t i; } fp32 = { .f = x }; +static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) { + union { + float f; + uint32_t i; + } fp32 = {.f = x}; return fp32.i; } - - /* execute functions for ops */ int32_t qhmath_hvx_dequantize_ahf( int8_t *restrict input, int8_t *restrict output, uint32_t size, - float scale) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } - HVX_Vector *iptr = (HVX_Vector *) input; - HVX_UVector *optr = (HVX_UVector *) output; + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; HVX_Vector sline1p, sline1c, sline1; HVX_Vector scale_vec; int32_t block, l2fetch_block; - int32_t leftover = size & 63; - int32_t vectors_in_rounddown = size / 128; // element number! + int32_t leftover = size & 127; + int32_t vectors_in_rounddown = size / 128; // element number! // int32_t leftover_size = leftover * sizeof(float); sline1p = *iptr++; @@ -139,42 +134,36 @@ int32_t qhmath_hvx_dequantize_ahf( uint32_t convert = 0x00800080; HVX_Vector convert_vector = Q6_V_vsplat_R(convert); - scale_vec = Q6_V_vsplat_R(float_to_fp16s(scale)); HVX_Vector zero_v_sf = Q6_V_vzero(); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); - - *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec)); - *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), scale_vec)); + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec)); + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), scale_vec)); sline1p = sline1c; } } if (vectors_in_rounddown > 0) { - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); @@ -182,30 +171,85 @@ int32_t qhmath_hvx_dequantize_ahf( HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec)); + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), scale_vec)); + } - *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec)); - *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), scale_vec)); + return 0; +} +int32_t qhmath_hvx_dequantize_ui16_ahf( + int8_t *restrict input, + int8_t *restrict output, + uint32_t size, + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { + return -1; } + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; + + HVX_Vector sline1p, sline1c, sline1; + HVX_Vector scale_vec; + + int32_t block, l2fetch_block; + int32_t leftover = size & 63; + int32_t vectors_in_rounddown = size / 64; // element number! + // int32_t leftover_size = leftover * sizeof(float); + + sline1p = *iptr++; + + uint32_t convert = 0x80008000; + HVX_Vector convert_vector = Q6_V_vsplat_R(convert); + + scale_vec = Q6_V_vsplat_R(float_to_fp16s(scale)); + + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { + block = Q6_R_min_RR(i, BLOCK_SIZE); + l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); + + if (l2fetch_block > 0) { + l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); + } + + for (int32_t j = 0; j < block; ++j) { + sline1c = *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + HVX_Vector temp = sline1; + + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(temp, convert_vector); + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec)); + + sline1p = sline1c; + } + } + + if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + HVX_Vector temp = sline1; + + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(temp, convert_vector); + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec)); + } return 0; } -// Only support 128x dimension +// Only support 128x dimension int32_t qhmath_hvx_dequantize_af( int8_t *restrict input, int8_t *restrict output, uint32_t size, - float scale) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } - HVX_Vector *iptr = (HVX_Vector *) input; - HVX_UVector *optr = (HVX_UVector *) output; + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; HVX_Vector sline1p, sline1c, sline1; HVX_Vector scale_vec; @@ -221,26 +265,22 @@ int32_t qhmath_hvx_dequantize_af( uint32_t convert = 0x00800080; HVX_Vector convert_vector = Q6_V_vsplat_R(convert); - scale_vec = Q6_V_vsplat_R(float_to_bits(scale)); one_vec = Q6_V_vsplat_R(float_to_fp16s(1.0)); HVX_Vector zero_v_sf = Q6_V_vzero(); scale_vec = Q6_Vqf32_vadd_VsfVsf(scale_vec, Q6_V_vzero()); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); @@ -253,19 +293,18 @@ int32_t qhmath_hvx_dequantize_af( HVX_VectorPair result2 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), one_vec); result2 = Q6_W_vshuff_VVR(Q6_V_hi_W(result2), Q6_V_lo_W(result2), -4); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), scale_vec)); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), scale_vec)); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), scale_vec)); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), scale_vec)); sline1p = sline1c; } } if (vectors_in_rounddown > 0) { - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); @@ -279,141 +318,222 @@ int32_t qhmath_hvx_dequantize_af( HVX_VectorPair result2 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), one_vec); result2 = Q6_W_vshuff_VVR(Q6_V_hi_W(result2), Q6_V_lo_W(result2), -4); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), scale_vec)); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), scale_vec)); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), scale_vec)); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), scale_vec)); + } + + return 0; +} + +int32_t qhmath_hvx_dequantize_ui16_af( + int8_t *restrict input, + int8_t *restrict output, + uint32_t size, + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { + return -1; + } + + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; + + HVX_Vector sline1p, sline1c, sline1; + HVX_Vector scale_vec; + HVX_Vector one_vec; + + int32_t block, l2fetch_block; + int32_t leftover = size & 63; + int32_t vectors_in_rounddown = size / 64; + // int32_t leftover_size = leftover * sizeof(float); + + sline1p = *iptr++; + + uint32_t convert = 0x80008000; + HVX_Vector convert_vector = Q6_V_vsplat_R(convert); + scale_vec = Q6_V_vsplat_R(float_to_bits(scale)); + one_vec = Q6_V_vsplat_R(float_to_fp16s(1.0)); + scale_vec = Q6_Vqf32_vadd_VsfVsf(scale_vec, Q6_V_vzero()); + + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { + block = Q6_R_min_RR(i, BLOCK_SIZE); + l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); + + if (l2fetch_block > 0) { + l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); + } + + for (int32_t j = 0; j < block; ++j) { + sline1c = *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + HVX_Vector temp = Q6_Vh_vsub_VhVh(sline1, convert_vector); + HVX_VectorPair result = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(temp), one_vec); + result = Q6_W_vshuff_VVR(Q6_V_hi_W(result), Q6_V_lo_W(result), -4); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result), scale_vec)); + + sline1p = sline1c; + } + } + + if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + HVX_Vector temp = Q6_Vh_vsub_VhVh(sline1, convert_vector); + HVX_VectorPair result = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(temp), one_vec); + result = Q6_W_vshuff_VVR(Q6_V_hi_W(result), Q6_V_lo_W(result), -4); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result), scale_vec)); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result), scale_vec)); } return 0; } -template +template GraphStatus llamadequantizeImpl(TensorType1 &out_0, const TensorType1 &in_0, - const PlainFloatTensor& scale) + const PlainFloatTensor &scale) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - // HVX Method -- FP32 Version + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + + // HVX Method -- FP32 Version out_0.set_dims(in_0); - + // NHWC - auto in_ptr = (int8_t*)in_0.raw_data_const(); - auto out_ptr = (int8_t*)out_0.raw_data(); + auto in_ptr = (int8_t *)in_0.raw_data_const(); + auto out_ptr = (int8_t *)out_0.raw_data(); auto [b_in, h_in, w_in, d_in] = in_0.dims(); - float scale_ = scale(0,0,0,0); - + float scale_ = scale(0, 0, 0, 0); - size_t size = b_in*h_in*w_in*d_in; + size_t size = b_in * h_in * w_in * d_in; if (in_0.get_dtype() == DType::QUInt8 && out_0.get_dtype() == DType::Float16) { qhmath_hvx_dequantize_ahf(in_ptr, out_ptr, size, scale_); - } - else { + } else if (in_0.get_dtype() == DType::QUInt16 && out_0.get_dtype() == DType::Float16) { + qhmath_hvx_dequantize_ui16_ahf(in_ptr, out_ptr, size, scale_); + } else if (in_0.get_dtype() == DType::QUInt16 && out_0.get_dtype() == DType::Float32) { + qhmath_hvx_dequantize_ui16_af(in_ptr, out_ptr, size, scale_); + } else { qhmath_hvx_dequantize_af(in_ptr, out_ptr, size, scale_); } - - - return GraphStatus::Success; + return GraphStatus::Success; } #else -template +template GraphStatus llamadequantizeImpl(TensorType1 &out_0, const TensorType1 &in_0, - const PlainFloatTensor& scale) + const PlainFloatTensor &scale) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - // HVX Method -- FP32 Version + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + + // HVX Method -- FP32 Version out_0.set_dims(in_0); - float scale_ = scale(0,0,0,0); - - auto in_ptr = (uint8_t*)in_0.raw_data_const(); + float scale_ = scale(0, 0, 0, 0); auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - if (out_0.get_dtype() == DType::Float32) { - auto out_ptr = (float*)out_0.raw_data(); + if (in_0.get_dtype() == DType::QUInt8 && out_0.get_dtype() == DType::Float32) { + auto out_ptr = (float *)out_0.raw_data(); + auto in_ptr = (uint8_t *)in_0.raw_data_const(); for (Idx b = 0; b < b_in; b++) { for (Idx h = 0; h < h_in; h++) { for (Idx w = 0; w < w_in; w++) { - for (Idx d = 0; d < d_in; d++) { - - int32_t inval = static_cast(*in_ptr++); - *out_ptr++ = (inval-128) * scale_; - + for (Idx d = 0; d < d_in; d++) { + int32_t inval = static_cast(*in_ptr++); + *out_ptr++ = (inval - 128) * scale_; + } } + } + } + } else if (in_0.get_dtype() == DType::QUInt16 && out_0.get_dtype() == DType::Float32) { + auto out_ptr = (float *)out_0.raw_data(); + auto in_ptr = (uint16_t *)in_0.raw_data_const(); + + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + int32_t inval = static_cast(*in_ptr++); + *out_ptr++ = (inval - 32768) * scale_; + } } } } - } else if (out_0.get_dtype() == DType::Float16) { + } else if (in_0.get_dtype() == DType::QUInt16 && out_0.get_dtype() == DType::Float16) { + auto out_ptr = (__fp16 *)out_0.raw_data(); + auto in_ptr = (uint16_t *)in_0.raw_data_const(); - auto out_ptr = (__fp16*)out_0.raw_data(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + int32_t inval = static_cast(*in_ptr++); + *out_ptr++ = (__fp16)((inval - 32768) * scale_); + } + } + } + } + } else if (in_0.get_dtype() == DType::QUInt8 && out_0.get_dtype() == DType::Float16) { + auto out_ptr = (__fp16 *)out_0.raw_data(); + auto in_ptr = (uint8_t *)in_0.raw_data_const(); for (Idx b = 0; b < b_in; b++) { for (Idx h = 0; h < h_in; h++) { for (Idx w = 0; w < w_in; w++) { - for (Idx d = 0; d < d_in; d++) { - - int32_t inval = static_cast(*in_ptr++); - *out_ptr++ = (__fp16)((inval-128) * scale_); - + for (Idx d = 0; d < d_in; d++) { + int32_t inval = static_cast(*in_ptr++); + *out_ptr++ = (__fp16)((inval - 128) * scale_); } } } } } - return GraphStatus::Success; + return GraphStatus::Success; } #endif +__attribute__((unused)) static float llamadequantizeCostFunc(const Op *op) { + /* + * add code here + * */ -__attribute__((unused)) static float llamadequantizeCostFunc(const Op *op) -{ - /* - * add code here - * */ - - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMADequantizeAdd.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMADequantizeAdd.cpp new file mode 100755 index 000000000..86158e228 --- /dev/null +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMADequantizeAdd.cpp @@ -0,0 +1,694 @@ +//============================================================================== +// Auto Generated Code for LLaMAPackage +//============================================================================== + +#include "HTP/core/constraints.h" +#include "HTP/core/op_package_feature_support.h" +#include "HTP/core/op_register_ext.h" +#include "HTP/core/optimize.h" +#include "QnnOpPackage.h" +#include "HTP/core/simple_reg.h" + +BEGIN_PKG_OP_DEFINITION(PKG_LLaMADequantizeAdd); + +// op execute function declarations +template +GraphStatus llamadequantizeaddImpl(TensorType1 &out_0, + const TensorType1 &in_0, + const TensorType &in_1, + const PlainFloatTensor &scale); + +// forward declaration of sample cost function +static float llamadequantizeaddCostFunc(const Op *op); + +/* + * method 1 for defining op, using default cost value (i.e. GLACIAL) and default flag (Flags::RESOURCE_HVX) + * syntax: DEF_PACKAGE_OP(F,OP) + * e.g. DEF_PACKAGE_OP((llamadequantizeaddImpl), "LLaMADequantizeAdd") + */ +DEF_PACKAGE_OP((llamadequantizeaddImpl), "LLaMADequantizeAdd") + +/* + * method 2 for defining op with specified cost value (one of GLACIAL, SNAIL, FAST, FREE) + * and provided flags + * syntax: DEF_PACKAGE_OP_AND_COST_AND_FLAGS(F,OP,COST,...) + * can use zero or more flags, FLAG options are IS_CONST, INHIBIT_CONST_PROP, + * RESOURCE_HVX, RESOURCE_HMX(not supported in external op packages) + * e.g. DEF_PACKAGE_OP_AND_COST_AND_FLAGS((llamadequantizeaddImpl), "LLaMADequantizeAdd", SNAIL) + */ + +/* + * method 3 for defining op with cost function pointer and provided flags + * cost function pointer type: typedef float (*cost_function) (const Op * op); + * syntax: DEF_PACKAGE_OP_AND_COST_F_AND_FLAGS(F,OP,COST_F,...) + * e.g. DEF_PACKAGE_OP_AND_COST_F_AND_FLAGS((llamadequantizeaddImpl), + * "LLaMADequantizeAdd", llamadequantizeaddCostFunc, Flags::RESOURCE_HVX) + */ + +/* + * optimization definitions + * need to be global in the package + * one definition per optimization + * syntax: DEF_PACKAGE_OPTIMIZATION(PRIORITY,MATCHCODE,CONSTRAINTCODE,REPLACECODE) + * PRIORITY predefined values include EARLY(2000), MIDDLE(3000), LATE(4000) + * HTP core provides some replacement functions for op package to use + * for more information about optimization rules, please refer to HTP core documentations + */ + +/* + * op parameter order definitions + * need to be global in the package + * one definition per op, and this is optional + * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) + * one or more parameters can be specified for each op + * order of parameters listed determines the order of parameters passed into op execution functions + * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode + * will be passed into op execution functions + * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted + * name will be abandoned + * if two or more op packages with the same package name will be registered, they cannot list + * conflicting parameter orders + * PARAM refers to parameter name as a string literal + * MANDATORY refers to whether this parameter is required to be provided at Qnn_addNode + * DEFAULT is used when MANDATORY is false + * if provided as Qnn_Param_t*, + * DEFAULT will be used for graph construction when this parameter is not provided at + * Qnn_addNode + * if provided as nullptr, + * graph construction will skip this parameter when this parameter is not provided at + * Qnn_addNode + */ +DEF_PACKAGE_PARAM_ORDER("LLaMADequantizeAdd", + "scale", + true, + nullptr) + +/* execute functions for ops */ +#ifndef REFERENCE_OP +#include "qhmath_hvx.h" +#include "hvx_internal.h" +#include +#include + +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) + +static inline int32_t float_to_fp16s(float input) { + union { + int32_t i; + __fp16 f[2]; + } fp32 = {.f = {(__fp16)input, (__fp16)input}}; + return fp32.i; +} + +static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) { + union { + float f; + uint32_t i; + } fp32 = {.f = x}; + return fp32.i; +} + +/* execute functions for ops */ +int32_t qhmath_hvx_dequantize_add_ahf( + int8_t *restrict input, + float_t *restrict bias, + int8_t *restrict output, + uint32_t size, + float scale) { + if ((input == NULL) || (bias == NULL) || (output == NULL) || (size == 0)) { + return -1; + } + + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_Vector *bptr = (HVX_Vector *)bias; + HVX_UVector *optr = (HVX_UVector *)output; + + HVX_Vector sline1p, sline1c, sline1; + HVX_Vector scale_vec; + + int32_t block, l2fetch_block; + int32_t leftover = size & 127; + int32_t vectors_in_rounddown = size / 128; // element number! + // int32_t leftover_size = leftover * sizeof(float); + + sline1p = *iptr++; + + uint32_t convert = 0x00800080; + HVX_Vector convert_vector = Q6_V_vsplat_R(convert); + + scale_vec = Q6_V_vsplat_R(float_to_fp16s(scale)); + HVX_Vector zero_v_sf = Q6_V_vzero(); + + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { + block = Q6_R_min_RR(i, BLOCK_SIZE); + l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); + + if (l2fetch_block > 0) { + l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); + } + + for (int32_t j = 0; j < block; ++j) { + sline1c = *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); + + temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); + HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + + HVX_Vector bvec1 = *bptr++; // load 32 float elements + HVX_Vector bvec2 = *bptr++; + // see HVX documention for Vector shuffle and deal cross-lane + // Q6_Vhf_equals_Wqf32 will use elements in the lower vector as the odd elements, so need to transpose here + HVX_VectorPair bias_pair = Q6_W_vdeal_VVR(Q6_Vqf32_equals_Vsf(bvec2), Q6_Vqf32_equals_Vsf(bvec1), -4); // make a fp32 pair + HVX_Vector hf16_bias = Q6_Vhf_equals_Wqf32(bias_pair); + + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vadd_Vqf16Vhf( + Q6_Vqf16_vmpy_VhfVhf( + Q6_Vhf_equals_Vh(sout1), scale_vec), + hf16_bias)); + + bvec1 = *bptr++; // load 32 float elements + bvec2 = *bptr++; + // see HVX documention for Vector shuffle and deal cross-lane + // Q6_Vhf_equals_Wqf32 will use elements in the lower vector as the odd elements, so need to transpose here + bias_pair = Q6_W_vdeal_VVR(Q6_Vqf32_equals_Vsf(bvec2), Q6_Vqf32_equals_Vsf(bvec1), -4); // make a fp32 pair + hf16_bias = Q6_Vhf_equals_Wqf32(bias_pair); + + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vadd_Vqf16Vhf( + Q6_Vqf16_vmpy_VhfVhf( + Q6_Vhf_equals_Vh(sout2), scale_vec), + hf16_bias)); + + sline1p = sline1c; + } + } + + if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); + + temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); + HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + + HVX_Vector bvec1 = *bptr++; // load 32 float elements + HVX_Vector bvec2 = *bptr++; + HVX_VectorPair bias_pair = Q6_W_vshuff_VVR(Q6_Vqf32_equals_Vsf(bvec1), Q6_Vqf32_equals_Vsf(bvec2), -4); // make a fp32 pair + HVX_Vector hf16_bias = Q6_Vhf_equals_Wqf32(bias_pair); + + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vadd_Vqf16Vhf( + Q6_Vqf16_vmpy_VhfVhf( + Q6_Vhf_equals_Vh(sout1), scale_vec), + hf16_bias)); + + bvec1 = *bptr++; // load 32 float elements + bvec2 = *bptr++; + bias_pair = Q6_W_vshuff_VVR(Q6_Vqf32_equals_Vsf(bvec1), Q6_Vqf32_equals_Vsf(bvec2), -4); // make a fp32 pair + hf16_bias = Q6_Vhf_equals_Wqf32(bias_pair); + + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vadd_Vqf16Vhf( + Q6_Vqf16_vmpy_VhfVhf( + Q6_Vhf_equals_Vh(sout2), scale_vec), + hf16_bias)); + } + + return 0; +} + +int32_t qhmath_hvx_dequantize_add_ui16_ahf( + int8_t *restrict input, + float_t *restrict bias, + int8_t *restrict output, + uint32_t size, + float scale) { + if ((input == NULL) || (bias == NULL) || (output == NULL) || (size == 0)) { + return -1; + } + + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_Vector *bptr = (HVX_Vector *)bias; + HVX_UVector *optr = (HVX_UVector *)output; + + HVX_Vector sline1p, sline1c, sline1; + HVX_Vector scale_vec; + + int32_t block, l2fetch_block; + int32_t leftover = size & 63; + int32_t vectors_in_rounddown = size / 64; // element number! + // int32_t leftover_size = leftover * sizeof(float); + + sline1p = *iptr++; + + uint32_t convert = 0x80008000; + HVX_Vector convert_vector = Q6_V_vsplat_R(convert); + + scale_vec = Q6_V_vsplat_R(float_to_fp16s(scale)); + + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { + block = Q6_R_min_RR(i, BLOCK_SIZE); + l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); + + if (l2fetch_block > 0) { + l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); + } + + for (int32_t j = 0; j < block; ++j) { + sline1c = *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + HVX_Vector bvec1 = *bptr++; // load 32 float elements + HVX_Vector bvec2 = *bptr++; + // see HVX documention for Vector shuffle and deal cross-lane + // Q6_Vhf_equals_Wqf32 will use elements in the lower vector as the odd elements, so need to transpose here + HVX_VectorPair bias_pair = Q6_W_vdeal_VVR(Q6_Vqf32_equals_Vsf(bvec2), Q6_Vqf32_equals_Vsf(bvec1), -4); // make a fp32 pair + HVX_Vector hf16_bias = Q6_Vhf_equals_Wqf32(bias_pair); + + HVX_Vector temp = sline1; + + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(temp, convert_vector); + HVX_Vector qf16_val = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec); + + *optr++ = Q6_Vhf_equals_Vqf16( + Q6_Vqf16_vadd_Vqf16Vhf(qf16_val, hf16_bias)); + + sline1p = sline1c; + } + } + + if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + HVX_Vector bvec1 = *bptr++; // load 32 float elements + HVX_Vector bvec2 = *bptr++; + + // see HVX documention for Vector shuffle and deal cross-lane + // Q6_Vhf_equals_Wqf32 will use elements in the lower vector as the odd elements, so need to transpose here + HVX_VectorPair bias_pair = Q6_W_vdeal_VVR(Q6_Vqf32_equals_Vsf(bvec2), Q6_Vqf32_equals_Vsf(bvec1), -4); // make a fp32 pair + HVX_Vector hf16_bias = Q6_Vhf_equals_Wqf32(bias_pair); + + HVX_Vector temp = sline1; + + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(temp, convert_vector); + HVX_Vector qf16_val = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec); + + *optr++ = Q6_Vhf_equals_Vqf16( + Q6_Vqf16_vadd_Vqf16Vhf(qf16_val, hf16_bias)); + } + + return 0; +} + +// Only support 128x dimension +int32_t qhmath_hvx_dequantize_add_af( + int8_t *restrict input, + float_t *restrict bias, + int8_t *restrict output, + uint32_t size, + float scale) { + if ((input == NULL) || (bias == NULL) || (output == NULL) || (size == 0)) { + return -1; + } + + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_Vector *bptr = (HVX_Vector *)bias; + HVX_UVector *optr = (HVX_UVector *)output; + + HVX_Vector sline1p, sline1c, sline1; + HVX_Vector scale_vec; + HVX_Vector one_vec; + + int32_t block, l2fetch_block; + int32_t leftover = size & 127; + int32_t vectors_in_rounddown = size / 128; + // int32_t leftover_size = leftover * sizeof(float); + + sline1p = *iptr++; + + uint32_t convert = 0x00800080; + HVX_Vector convert_vector = Q6_V_vsplat_R(convert); + + scale_vec = Q6_V_vsplat_R(float_to_bits(scale)); + one_vec = Q6_V_vsplat_R(float_to_fp16s(1.0)); + HVX_Vector zero_v_sf = Q6_V_vzero(); + scale_vec = Q6_Vqf32_vadd_VsfVsf(scale_vec, Q6_V_vzero()); + + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { + block = Q6_R_min_RR(i, BLOCK_SIZE); + l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); + + if (l2fetch_block > 0) { + l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); + } + + for (int32_t j = 0; j < block; ++j) { + sline1c = *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + HVX_Vector bvec1 = *bptr++; // load 32 float elements + HVX_Vector bvec2 = *bptr++; + HVX_Vector bvec3 = *bptr++; + HVX_Vector bvec4 = *bptr++; + + HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); + + temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); + HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + + HVX_VectorPair result1 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), one_vec); + result1 = Q6_W_vshuff_VVR(Q6_V_hi_W(result1), Q6_V_lo_W(result1), -4); + + HVX_VectorPair result2 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), one_vec); + result2 = Q6_W_vshuff_VVR(Q6_V_hi_W(result2), Q6_V_lo_W(result2), -4); + + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), scale_vec), + Q6_Vqf32_equals_Vsf(bvec1))); + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), scale_vec), + Q6_Vqf32_equals_Vsf(bvec2))); + + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), scale_vec), + Q6_Vqf32_equals_Vsf(bvec3))); + + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), scale_vec), + Q6_Vqf32_equals_Vsf(bvec4))); + + sline1p = sline1c; + } + } + + if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + // NOTE: assume bias size is multiple of 128 + HVX_Vector bvec1 = *bptr++; // load 32 float elements + HVX_Vector bvec2 = *bptr++; + HVX_Vector bvec3 = *bptr++; + HVX_Vector bvec4 = *bptr++; + + HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); + + temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); + HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + + HVX_VectorPair result1 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), one_vec); + result1 = Q6_W_vshuff_VVR(Q6_V_hi_W(result1), Q6_V_lo_W(result1), -4); + + HVX_VectorPair result2 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), one_vec); + result2 = Q6_W_vshuff_VVR(Q6_V_hi_W(result2), Q6_V_lo_W(result2), -4); + + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), scale_vec), + Q6_Vqf32_equals_Vsf(bvec1))); + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), scale_vec), + Q6_Vqf32_equals_Vsf(bvec2))); + + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), scale_vec), + Q6_Vqf32_equals_Vsf(bvec3))); + + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), scale_vec), + Q6_Vqf32_equals_Vsf(bvec4))); + } + + return 0; +} + +int32_t qhmath_hvx_dequantize_add_ui16_af( + int8_t *restrict input, + float_t *restrict bias, + int8_t *restrict output, + uint32_t size, + float scale) { + if ((input == NULL) || (bias == NULL) || (output == NULL) || (size == 0)) { + return -1; + } + + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_Vector *bptr = (HVX_Vector *)bias; + HVX_UVector *optr = (HVX_UVector *)output; + + HVX_Vector sline1p, sline1c, sline1; + HVX_Vector scale_vec; + HVX_Vector one_vec; + + int32_t block, l2fetch_block; + int32_t leftover = size & 63; + int32_t vectors_in_rounddown = size / 64; + // int32_t leftover_size = leftover * sizeof(float); + + sline1p = *iptr++; + + uint32_t convert = 0x80008000; + HVX_Vector convert_vector = Q6_V_vsplat_R(convert); + + scale_vec = Q6_V_vsplat_R(float_to_bits(scale)); + one_vec = Q6_V_vsplat_R(float_to_fp16s(1.0)); + scale_vec = Q6_Vqf32_vadd_VsfVsf(scale_vec, Q6_V_vzero()); + + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { + block = Q6_R_min_RR(i, BLOCK_SIZE); + l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); + + if (l2fetch_block > 0) { + l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); + } + + for (int32_t j = 0; j < block; ++j) { + sline1c = *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + HVX_Vector bvec1 = *bptr++; // load 32 float elements + HVX_Vector bvec2 = *bptr++; + + HVX_Vector temp = Q6_Vh_vsub_VhVh(sline1, convert_vector); + HVX_VectorPair result = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(temp), one_vec); + result = Q6_W_vshuff_VVR(Q6_V_hi_W(result), Q6_V_lo_W(result), -4); + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result), scale_vec), Q6_Vqf32_equals_Vsf(bvec1))); + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result), scale_vec), Q6_Vqf32_equals_Vsf(bvec2))); + + sline1p = sline1c; + } + } + + if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + HVX_Vector bvec1 = *bptr++; // load 32 float elements + HVX_Vector bvec2 = *bptr++; + + HVX_Vector temp = Q6_Vh_vsub_VhVh(sline1, convert_vector); + HVX_VectorPair result = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(temp), one_vec); + result = Q6_W_vshuff_VVR(Q6_V_hi_W(result), Q6_V_lo_W(result), -4); + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result), scale_vec), Q6_Vqf32_equals_Vsf(bvec1))); + *optr++ = Q6_Vsf_equals_Vqf32( + Q6_Vqf32_vadd_Vqf32Vqf32( + Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result), scale_vec), Q6_Vqf32_equals_Vsf(bvec2))); + } + + return 0; +} + +template +GraphStatus llamadequantizeaddImpl(TensorType1 &out_0, + const TensorType1 &in_0, + const TensorType &in_1, + const PlainFloatTensor &scale) + +{ + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + + // HVX Method -- FP32 Version + out_0.set_dims(in_0); + + // NHWC + auto bias_ptr = (float *)in_1.raw_data_const(); + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + + float scale_ = scale(0, 0, 0, 0); + + if (d_in % 128 != 0) { + return GraphStatus::ErrorDimensions; + } + + // call the kernel function for every dim() (assume total_size == bias_length) + // NOTE: in modeling, the dequantize add can appear after linear multihead attention, so w_in * d_in == bias_length + // in other positions, the w_in will be 1 + if (in_0.get_dtype() == DType::QUInt8 && out_0.get_dtype() == DType::Float16) { + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + auto in_ptr = (int8_t *)in_0.raw_data_const() + (((b * h_in) + h) * w_in * d_in); + auto out_ptr = (int8_t *)((int16_t *)out_0.raw_data() + (((b * h_in) + h) * w_in * d_in)); + qhmath_hvx_dequantize_add_ahf(in_ptr, bias_ptr, out_ptr, w_in * d_in, scale_); + } + } + } else if (in_0.get_dtype() == DType::QUInt16 && out_0.get_dtype() == DType::Float16) { + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + auto in_ptr = (int8_t *)((int16_t *)in_0.raw_data_const() + (((b * h_in) + h) * w_in * d_in)); + auto out_ptr = (int8_t *)((int16_t *)out_0.raw_data() + (((b * h_in) + h) * w_in * d_in)); + qhmath_hvx_dequantize_add_ui16_ahf(in_ptr, bias_ptr, out_ptr, w_in * d_in, scale_); + } + } + } else if (in_0.get_dtype() == DType::QUInt16 && out_0.get_dtype() == DType::Float32) { + // NOTE: correct + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + auto in_ptr = (int8_t *)((int16_t *)in_0.raw_data_const() + (((b * h_in) + h) * w_in * d_in)); + auto out_ptr = (int8_t *)((float_t *)out_0.raw_data() + (((b * h_in) + h) * w_in * d_in)); + qhmath_hvx_dequantize_add_ui16_af(in_ptr, bias_ptr, out_ptr, w_in * d_in, scale_); + } + } + } else if (in_0.get_dtype() == DType::QUInt8 && out_0.get_dtype() == DType::Float32) { + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + auto in_ptr = (int8_t *)in_0.raw_data_const() + (((b * h_in) + h) * w_in * d_in); + auto out_ptr = (int8_t *)((float_t *)out_0.raw_data() + ((((b * h_in) + h) * w_in * d_in))); + qhmath_hvx_dequantize_add_af(in_ptr, bias_ptr, out_ptr, w_in * d_in, scale_); + } + } + } else { + return GraphStatus::GraphErrorCode::ErrorUnsupported; + } + + return GraphStatus::Success; +} +#else + +template +GraphStatus llamadequantizeaddImpl(TensorType1 &out_0, + const TensorType1 &in_0, + const TensorType &in_1, + const PlainFloatTensor &scale) + +{ + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + + out_0.set_dims(in_0); + + float scale_ = scale(0, 0, 0, 0); + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + + if (in_0.get_dtype() == DType::QUInt8 && out_0.get_dtype() == DType::Float32) { + auto out_ptr = (float *)out_0.raw_data(); + auto in_ptr = (uint8_t *)in_0.raw_data_const(); + + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + int32_t inval = static_cast(*in_ptr++); + *out_ptr++ = (inval - 128) * scale_ + in_1(0, 0, 0, w * d_in + d); + } + } + } + } + } else if (in_0.get_dtype() == DType::QUInt16 && out_0.get_dtype() == DType::Float32) { + auto out_ptr = (float *)out_0.raw_data(); + auto in_ptr = (uint16_t *)in_0.raw_data_const(); + + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + int32_t inval = static_cast(*in_ptr++); + *out_ptr++ = (inval - 32768) * scale_ + in_1(0, 0, 0, w * d_in + d); + } + } + } + } + } else if (in_0.get_dtype() == DType::QUInt16 && out_0.get_dtype() == DType::Float16) { + auto out_ptr = (__fp16 *)out_0.raw_data(); + auto in_ptr = (uint16_t *)in_0.raw_data_const(); + + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + int32_t inval = static_cast(*in_ptr++); + *out_ptr++ = (__fp16)((inval - 32768) * scale_ + in_1(0, 0, 0, w * d_in + d)); + } + } + } + } + } else if (in_0.get_dtype() == DType::QUInt8 && out_0.get_dtype() == DType::Float16) { + auto out_ptr = (__fp16 *)out_0.raw_data(); + auto in_ptr = (uint8_t *)in_0.raw_data_const(); + + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + int32_t inval = static_cast(*in_ptr++); + *out_ptr++ = (__fp16)((inval - 128) * scale_ + in_1(0, 0, 0, w * d_in + d)); + } + } + } + } + } + return GraphStatus::Success; +} + +#endif + +__attribute__((unused)) static float llamadequantizeaddCostFunc(const Op *op) { + /* + * add code here + * */ + + float cost = 0.0; // add cost computation here + return cost; +} + +/* At the bottom of the op file, call END_PKG_OP_DEFINITION(), + where is as BEGIN_PKG_OP_DEFINITION +*/ +END_PKG_OP_DEFINITION(PKG_LLaMADequantizeAdd); \ No newline at end of file diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMALinear.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMALinear.cpp index 5c3358dac..44487d245 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMALinear.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMALinear.cpp @@ -9,20 +9,18 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_LLaMALinear); - // op execute function declarations -template -GraphStatus llamalinearImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const TensorType& in_2, - const PlainFloatTensor& in_scale, - const PlainFloatTensor& weight_scale, - const PlainFloatTensor& bias_scale, - const PlainFloatTensor& output_scale); +template +GraphStatus llamalinearImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const TensorType &in_2, + const PlainFloatTensor &in_scale, + const PlainFloatTensor &weight_scale, + const PlainFloatTensor &bias_scale, + const PlainFloatTensor &output_scale); // forward declaration of sample cost function static float llamalinearCostFunc(const Op *op); @@ -67,11 +65,11 @@ DEF_PACKAGE_OP((llamalinearImpl), "LLaMALinear") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -84,7 +82,7 @@ DEF_PACKAGE_OP((llamalinearImpl), "LLaMALinear") * graph construction will skip this parameter when this parameter is not provided at * Qnn_addNode */ -DEF_PACKAGE_PARAM_ORDER("LLaMALinear", +DEF_PACKAGE_PARAM_ORDER("LLaMALinear", "in_scale", true, nullptr, @@ -98,13 +96,12 @@ DEF_PACKAGE_PARAM_ORDER("LLaMALinear", true, nullptr) - /* execute functions for ops */ float Round(float num) { float floor_num = floor(num); float ceil_num = ceil(num); - + if (num - floor_num < ceil_num - num) { return floor_num; } else { @@ -112,34 +109,34 @@ float Round(float num) { } } -template -GraphStatus llamalinearImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const TensorType& in_2, - const PlainFloatTensor& in_scale, - const PlainFloatTensor& weight_scale, - const PlainFloatTensor& bias_scale, - const PlainFloatTensor& output_scale) +template +GraphStatus llamalinearImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const TensorType &in_2, + const PlainFloatTensor &in_scale, + const PlainFloatTensor &weight_scale, + const PlainFloatTensor &bias_scale, + const PlainFloatTensor &output_scale) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - // 假设输入张量是4维的,NHWC格式 + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + // 假设输入张量是4维的,NHWC格式 int batch_size = in_0.dims()[0]; int height = in_0.dims()[1]; int width = in_0.dims()[2]; - int in_features = in_0.dims()[3]; // 输入的通道数 + int in_features = in_0.dims()[3]; // 输入的通道数 int out_features = in_1.dims()[3]; // 输出的特征数(即输出通道数) // 检查输入张量的形状是否匹配 @@ -147,24 +144,23 @@ GraphStatus llamalinearImpl(TensorType& out_0, return GraphStatus::ErrorFatal; } - // 获取量化比例 - float w_scale = weight_scale(0,0,0,0); - float i_scale = in_scale(0,0,0,0); - float b_scale = bias_scale(0,0,0,0); - float o_scale = output_scale(0,0,0,0); - + float w_scale = weight_scale(0, 0, 0, 0); + float i_scale = in_scale(0, 0, 0, 0); + float b_scale = bias_scale(0, 0, 0, 0); + float o_scale = output_scale(0, 0, 0, 0); + // 初始化输出张量 size_t dims[] = {static_cast(batch_size), static_cast(height), static_cast(width), static_cast(out_features)}; out_0.set_dims(dims); // only support float bias now. - auto in0_ptr = (uint8_t*)in_0.raw_data_const(); - auto in1_ptr = (uint8_t*)in_1.raw_data_const(); - auto in2_ptr = (uint8_t*)in_2.raw_data_const(); - auto out_ptr = (int8_t*)out_0.raw_data(); - + auto in0_ptr = (uint8_t *)in_0.raw_data_const(); + auto in1_ptr = (uint8_t *)in_1.raw_data_const(); + auto in2_ptr = (uint8_t *)in_2.raw_data_const(); + auto out_ptr = (int8_t *)out_0.raw_data(); + // 进行量化Linear乘法 for (int b = 0; b < batch_size; ++b) { for (int h = 0; h < height; ++h) { @@ -174,24 +170,24 @@ GraphStatus llamalinearImpl(TensorType& out_0, for (int k = 0; k < in_features; ++k) { int in_index = b * height * width * in_features + h * width * in_features + w * in_features + k; int weight_index = k * out_features + n; - acc += ((static_cast(in0_ptr[in_index])-128) * i_scale) * ((static_cast(in1_ptr[weight_index])-128) * w_scale); + acc += ((static_cast(in0_ptr[in_index]) - 128) * i_scale) * ((static_cast(in1_ptr[weight_index]) - 128) * w_scale); } // 加上偏置并进行反量化 float result = acc; - result += (static_cast(in2_ptr[n])-128) * b_scale; + result += (static_cast(in2_ptr[n]) - 128) * b_scale; // 将结果限制在uint8范围内 int out_index = b * height * width * out_features + h * width * out_features + w * out_features + n; result = Round(result / o_scale); long v = lroundf(result); - + if (v > 127) v = 127; - + if (v < -128) v = -128; - + if (out_0.get_dtype() == DType::QUInt8) v += 128; @@ -201,23 +197,18 @@ GraphStatus llamalinearImpl(TensorType& out_0, } } - return GraphStatus::Success; + return GraphStatus::Success; } -__attribute__((unused)) static float llamalinearCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float llamalinearCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAMul.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAMul.cpp index 36c614ea8..802acbacf 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAMul.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAMul.cpp @@ -9,15 +9,13 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_LLaMAMul); - // op execute function declarations -template -GraphStatus llamamulImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1); +template +GraphStatus llamamulImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1); // forward declaration of sample cost function static float llamamulCostFunc(const Op *op); @@ -62,11 +60,11 @@ DEF_PACKAGE_OP((llamamulImpl), "LLaMAMul") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -80,7 +78,6 @@ DEF_PACKAGE_OP((llamamulImpl), "LLaMAMul") * Qnn_addNode */ - /* execute functions for ops */ #ifndef REFERENCE_OP @@ -89,17 +86,15 @@ DEF_PACKAGE_OP((llamamulImpl), "LLaMAMul") #include #include -#define BLOCK_SIZE (8*1024/VLEN) /* vector chunks */ -#define L2FETCH_AHEAD (BLOCK_SIZE) +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) int32_t hvx_mul_af( float *restrict input, float *restrict input2, float *restrict output, - uint32_t size) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + uint32_t size) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -117,19 +112,16 @@ int32_t hvx_mul_af( sline1p = *iptr++; sline2p = *iptr2++; - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline2c = *iptr2++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); @@ -143,31 +135,24 @@ int32_t hvx_mul_af( } if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - - sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) input2); - - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_VsfVsf(sline1, sline2)); + sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_VsfVsf(sline1, sline2)); } // Handle leftover elements. if (leftover_size > 0) { - sline1c = (is_in_one_chunk(iptr, leftover_size, VLEN) - ? sline1p - : *iptr++); - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + sline1c = (is_in_one_chunk(iptr, leftover_size, VLEN) ? sline1p : *iptr++); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + sline2c = (is_in_one_chunk(iptr2, leftover_size, VLEN) ? sline2p : *iptr2++); + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); - sline2c = (is_in_one_chunk(iptr2, leftover_size, VLEN) - ? sline2p - : *iptr2++); - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); - - vstu_variable(optr, leftover_size, Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_VsfVsf(sline1, sline2))); + vstu_variable(optr, leftover_size, Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_VsfVsf(sline1, sline2))); } return 0; @@ -177,10 +162,8 @@ int32_t hvx_mul_ahf( __fp16 *restrict input, __fp16 *restrict input2, __fp16 *restrict output, - uint32_t size) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + uint32_t size) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -198,19 +181,16 @@ int32_t hvx_mul_ahf( sline1p = *iptr++; sline2p = *iptr2++; - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline2c = *iptr2++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); @@ -224,160 +204,140 @@ int32_t hvx_mul_ahf( } if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - - sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) input2); - - *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(sline1, sline2)); + sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); + *optr++ = Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(sline1, sline2)); } // Handle leftover elements. if (leftover_size > 0) { - sline1c = (is_in_one_chunk(iptr, leftover_size, VLEN) - ? sline1p - : *iptr++); - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - + sline1c = (is_in_one_chunk(iptr, leftover_size, VLEN) ? sline1p : *iptr++); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sline2c = (is_in_one_chunk(iptr2, leftover_size, VLEN) - ? sline2p - : *iptr2++); - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); + sline2c = (is_in_one_chunk(iptr2, leftover_size, VLEN) ? sline2p : *iptr2++); + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); - vstu_variable(optr, leftover_size, Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(sline1, sline2))); + vstu_variable(optr, leftover_size, Q6_Vhf_equals_Vqf16(Q6_Vqf16_vmpy_VhfVhf(sline1, sline2))); } return 0; } -template -GraphStatus llamamulImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1) +template +GraphStatus llamamulImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - out_0.set_dims(in_0); - - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - size_t size = b_in*h_in*w_in*d_in; - - DType dtype = in_0.get_dtype(); - - if (dtype == DType::Float16) { - auto in_ptr = (__fp16*)in_0.raw_data_const(); - auto in2_ptr = (__fp16*)in_1.raw_data_const(); - auto out_ptr = (__fp16*)out_0.raw_data(); - - hvx_mul_ahf(in_ptr, in2_ptr, out_ptr, size); - - } else { - auto in_ptr = (float*)in_0.raw_data_const(); - auto in2_ptr = (float*)in_1.raw_data_const(); - auto out_ptr = (float*)out_0.raw_data(); - - hvx_mul_af(in_ptr, in2_ptr, out_ptr, size); - } - - return GraphStatus::Success; + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + out_0.set_dims(in_0); + + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + size_t size = b_in * h_in * w_in * d_in; + + DType dtype = in_0.get_dtype(); + + if (dtype == DType::Float16) { + auto in_ptr = (__fp16 *)in_0.raw_data_const(); + auto in2_ptr = (__fp16 *)in_1.raw_data_const(); + auto out_ptr = (__fp16 *)out_0.raw_data(); + + hvx_mul_ahf(in_ptr, in2_ptr, out_ptr, size); + + } else { + auto in_ptr = (float *)in_0.raw_data_const(); + auto in2_ptr = (float *)in_1.raw_data_const(); + auto out_ptr = (float *)out_0.raw_data(); + + hvx_mul_af(in_ptr, in2_ptr, out_ptr, size); + } + + return GraphStatus::Success; } #else - -template -GraphStatus llamamulImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1) +template +GraphStatus llamamulImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - out_0.set_dims(in_0); - - DType dtype = in_0.get_dtype(); - - - auto out_ptr = (__fp16*)out_0.raw_data(); - auto in_ptr = (__fp16*)in_0.raw_data_const(); - auto in_ptr2 = (__fp16*)in_1.raw_data_const(); - - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // mul - for (Idx d = 0; d < d_in; d++) { - - if (dtype == DType::Float16) { - - __fp16 inval = *in_ptr++; - __fp16 inval2 = *in_ptr2++; - __fp16 outval = inval * inval2; - - *out_ptr++ = outval; - } - - if (dtype == DType::Float32) { - float inval = in_0(b, h, w, d); - float inval2 = in_1(b, h, w, d); - float outval = inval * inval2; - - out_0(b, h, w, d) = outval; + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + out_0.set_dims(in_0); + + DType dtype = in_0.get_dtype(); + + auto out_ptr = (__fp16 *)out_0.raw_data(); + auto in_ptr = (__fp16 *)in_0.raw_data_const(); + auto in_ptr2 = (__fp16 *)in_1.raw_data_const(); + + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // mul + for (Idx d = 0; d < d_in; d++) { + if (dtype == DType::Float16) { + __fp16 inval = *in_ptr++; + __fp16 inval2 = *in_ptr2++; + __fp16 outval = inval * inval2; + + *out_ptr++ = outval; + } + + if (dtype == DType::Float32) { + float inval = in_0(b, h, w, d); + float inval2 = in_1(b, h, w, d); + float outval = inval * inval2; + + out_0(b, h, w, d) = outval; + } + } } - - } } - } } - - return GraphStatus::Success; + return GraphStatus::Success; } - - #endif -__attribute__((unused)) static float llamamulCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float llamamulCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAQuantize.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAQuantize.cpp index 23b357b51..8c90ef05a 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAQuantize.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAQuantize.cpp @@ -9,15 +9,13 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_LLaMAQuantize); - // op execute function declarations -template +template GraphStatus llamaquantizeImpl(TensorType1 &out_0, const TensorType1 &in_0, - const PlainFloatTensor& scale); + const PlainFloatTensor &scale); // forward declaration of sample cost function static float llamaquantizeCostFunc(const Op *op); @@ -62,11 +60,11 @@ DEF_PACKAGE_OP((llamaquantizeImpl), "LLaMAQuantize") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -79,29 +77,29 @@ DEF_PACKAGE_OP((llamaquantizeImpl), "LLaMAQuantize") * graph construction will skip this parameter when this parameter is not provided at * Qnn_addNode */ -DEF_PACKAGE_PARAM_ORDER("LLaMAQuantize", +DEF_PACKAGE_PARAM_ORDER("LLaMAQuantize", "scale", true, nullptr) #ifndef REFERENCE_OP - #include "qhmath_hvx.h" #include "hvx_internal.h" #include #include -#define BLOCK_SIZE (8*1024/VLEN) /* vector chunks */ -#define L2FETCH_AHEAD (BLOCK_SIZE) +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) -static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) -{ - union { float f; uint32_t i; } fp32 = { .f = x }; +static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) { + union { + float f; + uint32_t i; + } fp32 = {.f = x}; return fp32.i; } -static inline int32_t float_to_fp16s(float input) -{ +static inline int32_t float_to_fp16s(float input) { union { int32_t i; __fp16 f[2]; @@ -116,7 +114,6 @@ static inline int32_t float_to_fp16s(float input) #define FP16_SIGN 15 #define FP16_NEG_1 0xbc00 - /* execute functions for ops */ int32_t qhmath_hvx_quantize_ahf( __fp16 *restrict input, @@ -124,15 +121,13 @@ int32_t qhmath_hvx_quantize_ahf( uint32_t size, float low_level, float high_level, - float scale) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } - HVX_Vector *iptr = (HVX_Vector *) input; - HVX_UVector *optr = (HVX_UVector *) output; + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; HVX_Vector sline1p, sline1c, sline1; HVX_Vector sline2p, sline2c, sline2; @@ -153,7 +148,7 @@ int32_t qhmath_hvx_quantize_ahf( HVX_Vector uintconvert = Q6_V_vsplat_R(0x80808080); - float es = 0.5; + float es = 0.5; low_level_vec = Q6_V_vsplat_R(float_to_fp16s(low_level)); high_level_vec = Q6_V_vsplat_R(float_to_fp16s(high_level)); scale_vec = Q6_V_vsplat_R(float_to_fp16s(scale)); @@ -170,22 +165,19 @@ int32_t qhmath_hvx_quantize_ahf( HVX_Vector negone = Q6_Vh_vsplat_R(FP16_NEG_1); HVX_Vector zero = Q6_V_vzero(); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; j+=4) - { + for (int32_t j = 0; j < block; j += 4) { sline1c = *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sout1 = Q6_Vqf16_vmpy_VhfVhf(sline1,scale_vec); + sout1 = Q6_Vqf16_vmpy_VhfVhf(sline1, scale_vec); sout1 = Q6_Vqf16_vadd_Vqf16Vqf16(sout1, es_vec); sout1 = Q6_Vhf_equals_Vqf16(sout1); sout1 = Q6_Vhf_vmin_VhfVhf(sout1, high_level_vec); @@ -228,9 +220,9 @@ int32_t qhmath_hvx_quantize_ahf( sout1 = Q6_Vh_equals_Vhf(sout1); sline2c = *iptr++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) input); + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); - sout2 = Q6_Vqf16_vmpy_VhfVhf(sline2,scale_vec); + sout2 = Q6_Vqf16_vmpy_VhfVhf(sline2, scale_vec); sout2 = Q6_Vqf16_vadd_Vqf16Vqf16(sout2, es_vec); sout2 = Q6_Vhf_equals_Vqf16(sout2); sout2 = Q6_Vhf_vmin_VhfVhf(sout2, high_level_vec); @@ -273,9 +265,9 @@ int32_t qhmath_hvx_quantize_ahf( sout2 = Q6_Vh_equals_Vhf(sout2); sline3c = *iptr++; - sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t) input); + sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t)input); - sout3 = Q6_Vqf16_vmpy_VhfVhf(sline3,scale_vec); + sout3 = Q6_Vqf16_vmpy_VhfVhf(sline3, scale_vec); sout3 = Q6_Vqf16_vadd_Vqf16Vqf16(sout3, es_vec); sout3 = Q6_Vhf_equals_Vqf16(sout3); sout3 = Q6_Vhf_vmin_VhfVhf(sout3, high_level_vec); @@ -318,9 +310,9 @@ int32_t qhmath_hvx_quantize_ahf( sout3 = Q6_Vh_equals_Vhf(sout3); sline4c = *iptr++; - sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t) input); + sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t)input); - sout4 = Q6_Vqf16_vmpy_VhfVhf(sline4,scale_vec); + sout4 = Q6_Vqf16_vmpy_VhfVhf(sline4, scale_vec); sout4 = Q6_Vqf16_vadd_Vqf16Vqf16(sout4, es_vec); sout4 = Q6_Vhf_equals_Vqf16(sout4); sout4 = Q6_Vhf_vmin_VhfVhf(sout4, high_level_vec); @@ -362,15 +354,266 @@ int32_t qhmath_hvx_quantize_ahf( sout4 = Q6_Vh_equals_Vhf(sout4); - HVX_Vector reql_h = Q6_Vb_vpack_VhVh_sat(sout2, sout1); *optr++ = Q6_Vb_vadd_VbVb(reql_h, uintconvert); HVX_Vector reqh_h = Q6_Vb_vpack_VhVh_sat(sout4, sout3); *optr++ = Q6_Vb_vadd_VbVb(reqh_h, uintconvert); + sline1p = sline1c; + sline2p = sline2c; + sline3p = sline3c; + sline4p = sline4c; + } + } + + return 0; +} + +int32_t qhmath_hvx_quantize_ui16_ahf( + __fp16 *restrict input, + __fp16 *restrict output, + uint32_t size, + float low_level, + float high_level, + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { + return -1; + } + + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; + + HVX_Vector sline1p, sline1c, sline1; + HVX_Vector sline2p, sline2c, sline2; + HVX_Vector sline3p, sline3c, sline3; + HVX_Vector sline4p, sline4c, sline4; + + HVX_Vector sout1, sout2, sout3, sout4; + HVX_Vector low_level_vec, high_level_vec, scale_vec, es_vec; + int32_t block, l2fetch_block; + // int32_t leftover = size & 31; + int32_t vectors_in_rounddown = size / 64; + // int32_t leftover_size = leftover * sizeof(float); + + sline1p = *iptr++; + sline2p = *iptr++; + sline3p = *iptr++; + sline4p = *iptr++; + + HVX_Vector uintconvert = Q6_V_vsplat_R(0x80008000); + + float es = 0.5; + low_level_vec = Q6_V_vsplat_R(float_to_fp16s(low_level)); + high_level_vec = Q6_V_vsplat_R(float_to_fp16s(high_level)); + scale_vec = Q6_V_vsplat_R(float_to_fp16s(scale)); + es_vec = Q6_V_vsplat_R(float_to_fp16s(es)); + + HVX_Vector zero_v_sf = Q6_V_vzero(); + es_vec = Q6_Vqf16_vadd_VhfVhf(es_vec, zero_v_sf); + + HVX_Vector expmask = Q6_Vh_vsplat_R(FP16_EXPONENT_MASK); + HVX_Vector expbias = Q6_Vh_vsplat_R(FP16_EXPONENT_BIAS); + HVX_Vector manmask = Q6_Vh_vsplat_R(FP16_MANTISA_MASK); + HVX_Vector exp23 = Q6_Vh_vsplat_R(23 - 1); + HVX_Vector exp0 = Q6_Vh_vsplat_R(0 - 1); + HVX_Vector negone = Q6_Vh_vsplat_R(FP16_NEG_1); + HVX_Vector zero = Q6_V_vzero(); + + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { + block = Q6_R_min_RR(i, BLOCK_SIZE); + l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); + + if (l2fetch_block > 0) { + l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); + } + + for (int32_t j = 0; j < block; j += 4) { + sline1c = *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + sout1 = Q6_Vqf16_vmpy_VhfVhf(sline1, scale_vec); + sout1 = Q6_Vqf16_vadd_Vqf16Vqf16(sout1, es_vec); + sout1 = Q6_Vhf_equals_Vqf16(sout1); + sout1 = Q6_Vhf_vmin_VhfVhf(sout1, high_level_vec); + sout1 = Q6_Vhf_vmax_VhfVhf(sout1, low_level_vec); + + { + HVX_Vector exp = Q6_Vh_vasr_VhR(sout1, FP16_MANTISA); + exp = Q6_V_vand_VV(exp, expmask); + exp = Q6_Vh_vsub_VhVh(exp, expbias); + + HVX_Vector man = Q6_Vh_vasr_VhVh(manmask, exp); + HVX_Vector manzero = Q6_V_vand_VV(sout1, man); + + HVX_Vector sign = Q6_Vh_vasr_VhR(sout1, FP16_SIGN); + HVX_Vector issignpos = Q6_Q_vcmp_eq_VhVh(sign, zero); + + HVX_Vector expgte23 = Q6_Q_vcmp_gt_VhVh(exp, exp23); + HVX_Vector expgte0 = Q6_Q_vcmp_gt_VhVh(exp, exp0); + HVX_Vector maneqzero = Q6_Q_vcmp_eq_VhVh(manzero, zero); + + HVX_Vector exppos_signneg = Q6_Vh_vadd_VhVh(sout1, man); + man = Q6_V_vnot_V(man); + HVX_Vector exppos_signpos = Q6_V_vand_VV(sout1, man); + exppos_signneg = Q6_V_vand_VV(exppos_signneg, man); + HVX_Vector shift1 = Q6_Vh_vasl_VhR(sout1, 1); + HVX_Vector iszero = Q6_Q_vcmp_eq_VhVh(shift1, zero); + + // exp >= 0 + HVX_Vector tsout1 = Q6_V_vmux_QVV(issignpos, exppos_signpos, exppos_signneg); + tsout1 = Q6_V_vmux_QVV(maneqzero, sout1, tsout1); + + // exp < 0 (-1, 1) + HVX_Vector tsout2 = Q6_V_vmux_QVV(iszero, sout1, negone); + tsout2 = Q6_V_vmux_QVV(issignpos, zero, tsout2); + + tsout1 = Q6_V_vmux_QVV(expgte0, tsout1, tsout2); + sout1 = Q6_V_vmux_QVV(expgte23, sout1, tsout1); + } + + sout1 = Q6_Vh_equals_Vhf(sout1); + + sline2c = *iptr++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); + + sout2 = Q6_Vqf16_vmpy_VhfVhf(sline2, scale_vec); + sout2 = Q6_Vqf16_vadd_Vqf16Vqf16(sout2, es_vec); + sout2 = Q6_Vhf_equals_Vqf16(sout2); + sout2 = Q6_Vhf_vmin_VhfVhf(sout2, high_level_vec); + sout2 = Q6_Vhf_vmax_VhfVhf(sout2, low_level_vec); + + { + HVX_Vector exp = Q6_Vh_vasr_VhR(sout2, FP16_MANTISA); + exp = Q6_V_vand_VV(exp, expmask); + exp = Q6_Vh_vsub_VhVh(exp, expbias); + + HVX_Vector man = Q6_Vh_vasr_VhVh(manmask, exp); + HVX_Vector manzero = Q6_V_vand_VV(sout2, man); + + HVX_Vector sign = Q6_Vh_vasr_VhR(sout2, FP16_SIGN); + HVX_Vector issignpos = Q6_Q_vcmp_eq_VhVh(sign, zero); + + HVX_Vector expgte23 = Q6_Q_vcmp_gt_VhVh(exp, exp23); + HVX_Vector expgte0 = Q6_Q_vcmp_gt_VhVh(exp, exp0); + HVX_Vector maneqzero = Q6_Q_vcmp_eq_VhVh(manzero, zero); + + HVX_Vector exppos_signneg = Q6_Vh_vadd_VhVh(sout2, man); + man = Q6_V_vnot_V(man); + HVX_Vector exppos_signpos = Q6_V_vand_VV(sout2, man); + exppos_signneg = Q6_V_vand_VV(exppos_signneg, man); + HVX_Vector shift1 = Q6_Vh_vasl_VhR(sout2, 1); + HVX_Vector iszero = Q6_Q_vcmp_eq_VhVh(shift1, zero); + + // exp >= 0 + HVX_Vector tsout1 = Q6_V_vmux_QVV(issignpos, exppos_signpos, exppos_signneg); + tsout1 = Q6_V_vmux_QVV(maneqzero, sout2, tsout1); + + // exp < 0 (-1, 1) + HVX_Vector tsout2 = Q6_V_vmux_QVV(iszero, sout2, negone); + tsout2 = Q6_V_vmux_QVV(issignpos, zero, tsout2); + + tsout1 = Q6_V_vmux_QVV(expgte0, tsout1, tsout2); + sout2 = Q6_V_vmux_QVV(expgte23, sout2, tsout1); + } + + sout2 = Q6_Vh_equals_Vhf(sout2); + + sline3c = *iptr++; + sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t)input); + + sout3 = Q6_Vqf16_vmpy_VhfVhf(sline3, scale_vec); + sout3 = Q6_Vqf16_vadd_Vqf16Vqf16(sout3, es_vec); + sout3 = Q6_Vhf_equals_Vqf16(sout3); + sout3 = Q6_Vhf_vmin_VhfVhf(sout3, high_level_vec); + sout3 = Q6_Vhf_vmax_VhfVhf(sout3, low_level_vec); + + { + HVX_Vector exp = Q6_Vh_vasr_VhR(sout3, FP16_MANTISA); + exp = Q6_V_vand_VV(exp, expmask); + exp = Q6_Vh_vsub_VhVh(exp, expbias); + + HVX_Vector man = Q6_Vh_vasr_VhVh(manmask, exp); + HVX_Vector manzero = Q6_V_vand_VV(sout3, man); + + HVX_Vector sign = Q6_Vh_vasr_VhR(sout3, FP16_SIGN); + HVX_Vector issignpos = Q6_Q_vcmp_eq_VhVh(sign, zero); + + HVX_Vector expgte23 = Q6_Q_vcmp_gt_VhVh(exp, exp23); + HVX_Vector expgte0 = Q6_Q_vcmp_gt_VhVh(exp, exp0); + HVX_Vector maneqzero = Q6_Q_vcmp_eq_VhVh(manzero, zero); + + HVX_Vector exppos_signneg = Q6_Vh_vadd_VhVh(sout3, man); + man = Q6_V_vnot_V(man); + HVX_Vector exppos_signpos = Q6_V_vand_VV(sout3, man); + exppos_signneg = Q6_V_vand_VV(exppos_signneg, man); + HVX_Vector shift1 = Q6_Vh_vasl_VhR(sout3, 1); + HVX_Vector iszero = Q6_Q_vcmp_eq_VhVh(shift1, zero); + + // exp >= 0 + HVX_Vector tsout1 = Q6_V_vmux_QVV(issignpos, exppos_signpos, exppos_signneg); + tsout1 = Q6_V_vmux_QVV(maneqzero, sout3, tsout1); + + // exp < 0 (-1, 1) + HVX_Vector tsout2 = Q6_V_vmux_QVV(iszero, sout3, negone); + tsout2 = Q6_V_vmux_QVV(issignpos, zero, tsout2); + + tsout1 = Q6_V_vmux_QVV(expgte0, tsout1, tsout2); + sout3 = Q6_V_vmux_QVV(expgte23, sout3, tsout1); + } + + sout3 = Q6_Vh_equals_Vhf(sout3); + + sline4c = *iptr++; + sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t)input); + + sout4 = Q6_Vqf16_vmpy_VhfVhf(sline4, scale_vec); + sout4 = Q6_Vqf16_vadd_Vqf16Vqf16(sout4, es_vec); + sout4 = Q6_Vhf_equals_Vqf16(sout4); + sout4 = Q6_Vhf_vmin_VhfVhf(sout4, high_level_vec); + sout4 = Q6_Vhf_vmax_VhfVhf(sout4, low_level_vec); + + { + HVX_Vector exp = Q6_Vh_vasr_VhR(sout4, FP16_MANTISA); + exp = Q6_V_vand_VV(exp, expmask); + exp = Q6_Vh_vsub_VhVh(exp, expbias); + + HVX_Vector man = Q6_Vh_vasr_VhVh(manmask, exp); + HVX_Vector manzero = Q6_V_vand_VV(sout4, man); + + HVX_Vector sign = Q6_Vh_vasr_VhR(sout4, FP16_SIGN); + HVX_Vector issignpos = Q6_Q_vcmp_eq_VhVh(sign, zero); + + HVX_Vector expgte23 = Q6_Q_vcmp_gt_VhVh(exp, exp23); + HVX_Vector expgte0 = Q6_Q_vcmp_gt_VhVh(exp, exp0); + HVX_Vector maneqzero = Q6_Q_vcmp_eq_VhVh(manzero, zero); + + HVX_Vector exppos_signneg = Q6_Vh_vadd_VhVh(sout4, man); + man = Q6_V_vnot_V(man); + HVX_Vector exppos_signpos = Q6_V_vand_VV(sout4, man); + exppos_signneg = Q6_V_vand_VV(exppos_signneg, man); + HVX_Vector shift1 = Q6_Vh_vasl_VhR(sout4, 1); + HVX_Vector iszero = Q6_Q_vcmp_eq_VhVh(shift1, zero); + + // exp >= 0 + HVX_Vector tsout1 = Q6_V_vmux_QVV(issignpos, exppos_signpos, exppos_signneg); + tsout1 = Q6_V_vmux_QVV(maneqzero, sout4, tsout1); + + // exp < 0 (-1, 1) + HVX_Vector tsout2 = Q6_V_vmux_QVV(iszero, sout4, negone); + tsout2 = Q6_V_vmux_QVV(issignpos, zero, tsout2); + + tsout1 = Q6_V_vmux_QVV(expgte0, tsout1, tsout2); + sout4 = Q6_V_vmux_QVV(expgte23, sout4, tsout1); + } + + sout4 = Q6_Vh_equals_Vhf(sout4); + + *optr++ = Q6_Vh_vadd_VhVh(sout1, uintconvert); + *optr++ = Q6_Vh_vadd_VhVh(sout2, uintconvert); + *optr++ = Q6_Vh_vadd_VhVh(sout3, uintconvert); + *optr++ = Q6_Vh_vadd_VhVh(sout4, uintconvert); - sline1p = sline1c; sline2p = sline2c; sline3p = sline3c; @@ -387,15 +630,13 @@ int32_t qhmath_hvx_quantize_ahf_int8( uint32_t size, float low_level, float high_level, - float scale) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } - HVX_Vector *iptr = (HVX_Vector *) input; - HVX_UVector *optr = (HVX_UVector *) output; + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; HVX_Vector sline1p, sline1c, sline1; HVX_Vector sline2p, sline2c, sline2; @@ -414,7 +655,7 @@ int32_t qhmath_hvx_quantize_ahf_int8( sline3p = *iptr++; sline4p = *iptr++; - float es = 0.5; + float es = 0.5; low_level_vec = Q6_V_vsplat_R(float_to_fp16s(low_level)); high_level_vec = Q6_V_vsplat_R(float_to_fp16s(high_level)); scale_vec = Q6_V_vsplat_R(float_to_fp16s(scale)); @@ -431,22 +672,19 @@ int32_t qhmath_hvx_quantize_ahf_int8( HVX_Vector negone = Q6_Vh_vsplat_R(FP16_NEG_1); HVX_Vector zero = Q6_V_vzero(); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; j+=4) - { + for (int32_t j = 0; j < block; j += 4) { sline1c = *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sout1 = Q6_Vqf16_vmpy_VhfVhf(sline1,scale_vec); + sout1 = Q6_Vqf16_vmpy_VhfVhf(sline1, scale_vec); sout1 = Q6_Vqf16_vadd_Vqf16Vqf16(sout1, es_vec); sout1 = Q6_Vhf_equals_Vqf16(sout1); sout1 = Q6_Vhf_vmin_VhfVhf(sout1, high_level_vec); @@ -489,9 +727,9 @@ int32_t qhmath_hvx_quantize_ahf_int8( sout1 = Q6_Vh_equals_Vhf(sout1); sline2c = *iptr++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) input); + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); - sout2 = Q6_Vqf16_vmpy_VhfVhf(sline2,scale_vec); + sout2 = Q6_Vqf16_vmpy_VhfVhf(sline2, scale_vec); sout2 = Q6_Vqf16_vadd_Vqf16Vqf16(sout2, es_vec); sout2 = Q6_Vhf_equals_Vqf16(sout2); sout2 = Q6_Vhf_vmin_VhfVhf(sout2, high_level_vec); @@ -534,9 +772,9 @@ int32_t qhmath_hvx_quantize_ahf_int8( sout2 = Q6_Vh_equals_Vhf(sout2); sline3c = *iptr++; - sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t) input); + sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t)input); - sout3 = Q6_Vqf16_vmpy_VhfVhf(sline3,scale_vec); + sout3 = Q6_Vqf16_vmpy_VhfVhf(sline3, scale_vec); sout3 = Q6_Vqf16_vadd_Vqf16Vqf16(sout3, es_vec); sout3 = Q6_Vhf_equals_Vqf16(sout3); sout3 = Q6_Vhf_vmin_VhfVhf(sout3, high_level_vec); @@ -579,9 +817,9 @@ int32_t qhmath_hvx_quantize_ahf_int8( sout3 = Q6_Vh_equals_Vhf(sout3); sline4c = *iptr++; - sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t) input); + sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t)input); - sout4 = Q6_Vqf32_vmpy_VsfVsf(sline4,scale_vec); + sout4 = Q6_Vqf32_vmpy_VsfVsf(sline4, scale_vec); sout4 = Q6_Vqf16_vadd_Vqf16Vqf16(sout4, es_vec); sout4 = Q6_Vhf_equals_Vqf16(sout4); sout4 = Q6_Vhf_vmin_VhfVhf(sout4, high_level_vec); @@ -623,15 +861,12 @@ int32_t qhmath_hvx_quantize_ahf_int8( sout4 = Q6_Vh_equals_Vhf(sout4); - HVX_Vector reql_h = Q6_Vb_vpack_VhVh_sat(sout2, sout1); *optr++ = reql_h; HVX_Vector reqh_h = Q6_Vb_vpack_VhVh_sat(sout4, sout3); *optr++ = reqh_h; - - sline1p = sline1c; sline2p = sline2c; sline3p = sline3c; @@ -657,15 +892,13 @@ int32_t qhmath_hvx_quantize_af( uint32_t size, float low_level, float high_level, - float scale) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } - HVX_Vector *iptr = (HVX_Vector *) input; - HVX_UVector *optr = (HVX_UVector *) output; + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; HVX_Vector sline1p, sline1c, sline1; HVX_Vector sline2p, sline2c, sline2; @@ -684,7 +917,7 @@ int32_t qhmath_hvx_quantize_af( sline3p = *iptr++; sline4p = *iptr++; - float es = 0.5f; + float es = 0.5f; low_level_vec = Q6_V_vsplat_R(float_to_bits(low_level)); high_level_vec = Q6_V_vsplat_R(float_to_bits(high_level)); scale_vec = Q6_V_vsplat_R(float_to_bits(scale)); @@ -696,7 +929,6 @@ int32_t qhmath_hvx_quantize_af( HVX_Vector uintconvert = Q6_V_vsplat_R(0x80808080); - // HVX_Vector expmask = Q6_V_vsplat_R(FLOAT_EXPONENT_MASK); // HVX_Vector expbias = Q6_V_vsplat_R(FLOAT_EXPONENT_BIAS); // HVX_Vector manmask = Q6_V_vsplat_R(FLOAT_MANTISA_MASK); @@ -705,22 +937,19 @@ int32_t qhmath_hvx_quantize_af( // HVX_Vector negone = Q6_V_vsplat_R(FLOAT_NEG_1); // HVX_Vector zero = Q6_V_vzero(); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; j+=4) - { + for (int32_t j = 0; j < block; j += 4) { sline1c = *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sout1 = Q6_Vqf32_vmpy_VsfVsf(sline1,scale_vec); + sout1 = Q6_Vqf32_vmpy_VsfVsf(sline1, scale_vec); sout1 = Q6_Vqf32_vadd_Vqf32Vqf32(sout1, es_vec); sout1 = Q6_Vsf_equals_Vqf32(sout1); sout1 = Q6_Vsf_vmin_VsfVsf(sout1, high_level_vec); @@ -767,9 +996,9 @@ int32_t qhmath_hvx_quantize_af( // sout1 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout1, Q6_V_vzero()), 0); sline2c = *iptr++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) input); + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); - sout2 = Q6_Vqf32_vmpy_VsfVsf(sline2,scale_vec); + sout2 = Q6_Vqf32_vmpy_VsfVsf(sline2, scale_vec); sout2 = Q6_Vqf32_vadd_Vqf32Vqf32(sout2, es_vec); sout2 = Q6_Vsf_equals_Vqf32(sout2); sout2 = Q6_Vsf_vmin_VsfVsf(sout2, high_level_vec); @@ -816,9 +1045,9 @@ int32_t qhmath_hvx_quantize_af( // sout2 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout2, Q6_V_vzero()), 0); sline3c = *iptr++; - sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t) input); + sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t)input); - sout3 = Q6_Vqf32_vmpy_VsfVsf(sline3,scale_vec); + sout3 = Q6_Vqf32_vmpy_VsfVsf(sline3, scale_vec); sout3 = Q6_Vqf32_vadd_Vqf32Vqf32(sout3, es_vec); sout3 = Q6_Vsf_equals_Vqf32(sout3); sout3 = Q6_Vsf_vmin_VsfVsf(sout3, high_level_vec); @@ -860,22 +1089,20 @@ int32_t qhmath_hvx_quantize_af( // sout3 = Q6_V_vmux_QVV(expgte23, sout3, tsout1); // } - sout3 = Q6_Vw_equals_Vsf(sout3); sout3 = Q6_Vw_vasr_VwR(sout3, ROUND_2_SCALE); // sout3 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout3, Q6_V_vzero()), 0); sline4c = *iptr++; - sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t) input); + sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t)input); - sout4 = Q6_Vqf32_vmpy_VsfVsf(sline4,scale_vec); + sout4 = Q6_Vqf32_vmpy_VsfVsf(sline4, scale_vec); sout4 = Q6_Vqf32_vadd_Vqf32Vqf32(sout4, es_vec); sout4 = Q6_Vsf_equals_Vqf32(sout4); sout4 = Q6_Vsf_vmin_VsfVsf(sout4, high_level_vec); sout4 = Q6_Vsf_vmax_VsfVsf(sout4, low_level_vec); sout4 = Q6_Vqf32_vmpy_VsfVsf(sout4, round_scale_vec); sout4 = Q6_Vsf_equals_Vqf32(sout4); - // { // HVX_Vector exp = Q6_Vw_vasr_VwR(sout4, FLOAT_MANTISA); @@ -915,7 +1142,6 @@ int32_t qhmath_hvx_quantize_af( sout4 = Q6_Vw_vasr_VwR(sout4, ROUND_2_SCALE); // sout4 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout4, Q6_V_vzero()), 0); - HVX_Vector reql_h = Q6_Vh_vpack_VwVw_sat(sout2, sout1); HVX_Vector reqh_h = Q6_Vh_vpack_VwVw_sat(sout4, sout3); HVX_Vector req_b = Q6_Vb_vpack_VhVh_sat(reqh_h, reql_h); @@ -932,21 +1158,150 @@ int32_t qhmath_hvx_quantize_af( return 0; } +#define INT16_ROUND_2_SCALE 15 +#define INT16_ROUND_SCALSE ((1 << INT16_ROUND_2_SCALE) * 1.0f) + +int32_t qhmath_hvx_quantize_ui16_af( + float *restrict input, + float *restrict output, + uint32_t size, + float low_level, + float high_level, + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { + return -1; + } + + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; + + HVX_Vector sline1p, sline1c, sline1; + HVX_Vector sline2p, sline2c, sline2; + HVX_Vector sline3p, sline3c, sline3; + HVX_Vector sline4p, sline4c, sline4; + + HVX_Vector sout1, sout2, sout3, sout4; + HVX_Vector low_level_vec, high_level_vec, scale_vec, es_vec, round_scale_vec; + int32_t block, l2fetch_block; + // int32_t leftover = size & 31; + int32_t vectors_in_rounddown = size / 32; + // int32_t leftover_size = leftover * sizeof(float); + + sline1p = *iptr++; + sline2p = *iptr++; + sline3p = *iptr++; + sline4p = *iptr++; + + float es = 0.5f; + low_level_vec = Q6_V_vsplat_R(float_to_bits(low_level)); + high_level_vec = Q6_V_vsplat_R(float_to_bits(high_level)); + scale_vec = Q6_V_vsplat_R(float_to_bits(scale)); + es_vec = Q6_V_vsplat_R(float_to_bits(es)); + round_scale_vec = Q6_V_vsplat_R(float_to_bits(INT16_ROUND_SCALSE)); + + HVX_Vector zero_v_sf = Q6_V_vzero(); + es_vec = Q6_Vqf32_vadd_VsfVsf(es_vec, zero_v_sf); + + HVX_Vector uintconvert = Q6_V_vsplat_R(0x80008000); + + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { + block = Q6_R_min_RR(i, BLOCK_SIZE); + l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); + + if (l2fetch_block > 0) { + l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); + } + + for (int32_t j = 0; j < block; j += 4) { + sline1c = *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + sout1 = Q6_Vqf32_vmpy_VsfVsf(sline1, scale_vec); + sout1 = Q6_Vqf32_vadd_Vqf32Vqf32(sout1, es_vec); + sout1 = Q6_Vsf_equals_Vqf32(sout1); + sout1 = Q6_Vsf_vmin_VsfVsf(sout1, high_level_vec); + sout1 = Q6_Vsf_vmax_VsfVsf(sout1, low_level_vec); + sout1 = Q6_Vqf32_vmpy_VsfVsf(sout1, round_scale_vec); + sout1 = Q6_Vsf_equals_Vqf32(sout1); + + sout1 = Q6_Vw_equals_Vsf(sout1); + sout1 = Q6_Vw_vasr_VwR(sout1, INT16_ROUND_2_SCALE); + // sout1 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout1, Q6_V_vzero()), 0); + + sline2c = *iptr++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); + + sout2 = Q6_Vqf32_vmpy_VsfVsf(sline2, scale_vec); + sout2 = Q6_Vqf32_vadd_Vqf32Vqf32(sout2, es_vec); + sout2 = Q6_Vsf_equals_Vqf32(sout2); + sout2 = Q6_Vsf_vmin_VsfVsf(sout2, high_level_vec); + sout2 = Q6_Vsf_vmax_VsfVsf(sout2, low_level_vec); + sout2 = Q6_Vqf32_vmpy_VsfVsf(sout2, round_scale_vec); + sout2 = Q6_Vsf_equals_Vqf32(sout2); + + sout2 = Q6_Vw_equals_Vsf(sout2); + sout2 = Q6_Vw_vasr_VwR(sout2, INT16_ROUND_2_SCALE); + // sout2 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout2, Q6_V_vzero()), 0); + + sline3c = *iptr++; + sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t)input); + + sout3 = Q6_Vqf32_vmpy_VsfVsf(sline3, scale_vec); + sout3 = Q6_Vqf32_vadd_Vqf32Vqf32(sout3, es_vec); + sout3 = Q6_Vsf_equals_Vqf32(sout3); + sout3 = Q6_Vsf_vmin_VsfVsf(sout3, high_level_vec); + sout3 = Q6_Vsf_vmax_VsfVsf(sout3, low_level_vec); + sout3 = Q6_Vqf32_vmpy_VsfVsf(sout3, round_scale_vec); + sout3 = Q6_Vsf_equals_Vqf32(sout3); + + sout3 = Q6_Vw_equals_Vsf(sout3); + sout3 = Q6_Vw_vasr_VwR(sout3, INT16_ROUND_2_SCALE); + // sout3 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout3, Q6_V_vzero()), 0); + + sline4c = *iptr++; + sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t)input); + + sout4 = Q6_Vqf32_vmpy_VsfVsf(sline4, scale_vec); + sout4 = Q6_Vqf32_vadd_Vqf32Vqf32(sout4, es_vec); + sout4 = Q6_Vsf_equals_Vqf32(sout4); + sout4 = Q6_Vsf_vmin_VsfVsf(sout4, high_level_vec); + sout4 = Q6_Vsf_vmax_VsfVsf(sout4, low_level_vec); + sout4 = Q6_Vqf32_vmpy_VsfVsf(sout4, round_scale_vec); + sout4 = Q6_Vsf_equals_Vqf32(sout4); + + sout4 = Q6_Vw_equals_Vsf(sout4); + sout4 = Q6_Vw_vasr_VwR(sout4, INT16_ROUND_2_SCALE); + // sout4 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout4, Q6_V_vzero()), 0); + + HVX_Vector reql_h = Q6_Vh_vpack_VwVw_sat(sout2, sout1); + HVX_Vector reqh_h = Q6_Vh_vpack_VwVw_sat(sout4, sout3); + + *optr++ = Q6_Vh_vadd_VhVh(reql_h, uintconvert); + *optr++ = Q6_Vh_vadd_VhVh(reqh_h, uintconvert); + + sline1p = sline1c; + sline2p = sline2c; + sline3p = sline3c; + sline4p = sline4c; + } + } + + return 0; +} + int32_t qhmath_hvx_quantize_af_out_int8( float *restrict input, float *restrict output, uint32_t size, float low_level, float high_level, - float scale) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } - HVX_Vector *iptr = (HVX_Vector *) input; - HVX_UVector *optr = (HVX_UVector *) output; + HVX_Vector *iptr = (HVX_Vector *)input; + HVX_UVector *optr = (HVX_UVector *)output; HVX_Vector sline1p, sline1c, sline1; HVX_Vector sline2p, sline2c, sline2; @@ -965,7 +1320,7 @@ int32_t qhmath_hvx_quantize_af_out_int8( sline3p = *iptr++; sline4p = *iptr++; - float es = 0.5f; + float es = 0.5f; low_level_vec = Q6_V_vsplat_R(float_to_bits(low_level)); high_level_vec = Q6_V_vsplat_R(float_to_bits(high_level)); scale_vec = Q6_V_vsplat_R(float_to_bits(scale)); @@ -974,7 +1329,6 @@ int32_t qhmath_hvx_quantize_af_out_int8( HVX_Vector zero_v_sf = Q6_V_vzero(); es_vec = Q6_Vqf32_vadd_VsfVsf(es_vec, zero_v_sf); - HVX_Vector expmask = Q6_V_vsplat_R(FLOAT_EXPONENT_MASK); HVX_Vector expbias = Q6_V_vsplat_R(FLOAT_EXPONENT_BIAS); HVX_Vector manmask = Q6_V_vsplat_R(FLOAT_MANTISA_MASK); @@ -983,22 +1337,19 @@ int32_t qhmath_hvx_quantize_af_out_int8( HVX_Vector negone = Q6_V_vsplat_R(FLOAT_NEG_1); HVX_Vector zero = Q6_V_vzero(); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; j+=4) - { + for (int32_t j = 0; j < block; j += 4) { sline1c = *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sout1 = Q6_Vqf32_vmpy_VsfVsf(sline1,scale_vec); + sout1 = Q6_Vqf32_vmpy_VsfVsf(sline1, scale_vec); sout1 = Q6_Vqf32_vadd_Vqf32Vqf32(sout1, es_vec); sout1 = Q6_Vsf_equals_Vqf32(sout1); sout1 = Q6_Vsf_vmin_VsfVsf(sout1, high_level_vec); @@ -1042,9 +1393,9 @@ int32_t qhmath_hvx_quantize_af_out_int8( // sout1 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout1, Q6_V_vzero()), 0); sline2c = *iptr++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) input); + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); - sout2 = Q6_Vqf32_vmpy_VsfVsf(sline2,scale_vec); + sout2 = Q6_Vqf32_vmpy_VsfVsf(sline2, scale_vec); sout2 = Q6_Vqf32_vadd_Vqf32Vqf32(sout2, es_vec); sout2 = Q6_Vsf_equals_Vqf32(sout2); sout2 = Q6_Vsf_vmin_VsfVsf(sout2, high_level_vec); @@ -1088,9 +1439,9 @@ int32_t qhmath_hvx_quantize_af_out_int8( // sout2 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout2, Q6_V_vzero()), 0); sline3c = *iptr++; - sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t) input); + sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t)input); - sout3 = Q6_Vqf32_vmpy_VsfVsf(sline3,scale_vec); + sout3 = Q6_Vqf32_vmpy_VsfVsf(sline3, scale_vec); sout3 = Q6_Vqf32_vadd_Vqf32Vqf32(sout3, es_vec); sout3 = Q6_Vsf_equals_Vqf32(sout3); sout3 = Q6_Vsf_vmin_VsfVsf(sout3, high_level_vec); @@ -1130,14 +1481,13 @@ int32_t qhmath_hvx_quantize_af_out_int8( sout3 = Q6_V_vmux_QVV(expgte23, sout3, tsout1); } - sout3 = Q6_Vw_equals_Vsf(sout3); // sout3 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout3, Q6_V_vzero()), 0); sline4c = *iptr++; - sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t) input); + sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t)input); - sout4 = Q6_Vqf32_vmpy_VsfVsf(sline4,scale_vec); + sout4 = Q6_Vqf32_vmpy_VsfVsf(sline4, scale_vec); sout4 = Q6_Vqf32_vadd_Vqf32Vqf32(sout4, es_vec); sout4 = Q6_Vsf_equals_Vqf32(sout4); sout4 = Q6_Vsf_vmin_VsfVsf(sout4, high_level_vec); @@ -1180,7 +1530,6 @@ int32_t qhmath_hvx_quantize_af_out_int8( sout4 = Q6_Vw_equals_Vsf(sout4); // sout4 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout4, Q6_V_vzero()), 0); - HVX_Vector reql_h = Q6_Vh_vpack_VwVw_sat(sout2, sout1); HVX_Vector reqh_h = Q6_Vh_vpack_VwVw_sat(sout4, sout3); HVX_Vector req_b = Q6_Vb_vpack_VhVh_sat(reqh_h, reql_h); @@ -1197,145 +1546,172 @@ int32_t qhmath_hvx_quantize_af_out_int8( return 0; } - -template +template GraphStatus llamaquantizeImpl(TensorType1 &out_0, const TensorType1 &in_0, - const PlainFloatTensor& scale) + const PlainFloatTensor &scale) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - // HVX Method -- FP32 Version - out_0.set_dims(in_0); - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - float scale_ = scale(0,0,0,0); - - scale_ = 1.0f/scale_; - - size_t size = b_in*h_in*w_in*d_in; - DType dtype = in_0.get_dtype(); - - if (dtype == DType::Float16 && out_0.get_dtype() == DType::QUInt8) { - // NHWC - auto in_ptr = (__fp16*)in_0.raw_data_const(); - auto out_ptr = (__fp16*)out_0.raw_data(); - - qhmath_hvx_quantize_ahf(in_ptr, out_ptr, size, -128.0f, 127.0f, scale_); - - } - if (dtype == DType::Float32 && out_0.get_dtype() == DType::QUInt8) { - - // NHWC - auto in_ptr = (float*)in_0.raw_data_const(); - auto out_ptr = (float*)out_0.raw_data(); - qhmath_hvx_quantize_af(in_ptr, out_ptr, size, -128.0f, 127.0f, scale_); - - } - - if (dtype == DType::Float16 && out_0.get_dtype() == DType::QInt8) { - // NHWC - auto in_ptr = (__fp16*)in_0.raw_data_const(); - auto out_ptr = (__fp16*)out_0.raw_data(); - - qhmath_hvx_quantize_ahf_int8(in_ptr, out_ptr, size, -128.0f, 127.0f, scale_); - - } - - if (dtype == DType::Float32 && out_0.get_dtype() == DType::QInt8) { - - // NHWC - auto in_ptr = (float*)in_0.raw_data_const(); - auto out_ptr = (float*)out_0.raw_data(); - qhmath_hvx_quantize_af_out_int8(in_ptr, out_ptr, size, -128.0f, 127.0f, scale_); - - - } - -// auto out_ptr = (int8_t*)out_0.raw_data(); - -// out_ptr[0] = (int)dtype; -// out_ptr[1] = (int)out_0.get_dtype(); - - return GraphStatus::Success; + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + + // HVX Method -- FP32 Version + out_0.set_dims(in_0); + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + + float scale_ = scale(0, 0, 0, 0); + + scale_ = 1.0f / scale_; + + size_t size = b_in * h_in * w_in * d_in; + DType dtype = in_0.get_dtype(); + + if (dtype == DType::Float16 && out_0.get_dtype() == DType::QUInt8) { + // NHWC + auto in_ptr = (__fp16 *)in_0.raw_data_const(); + auto out_ptr = (__fp16 *)out_0.raw_data(); + + qhmath_hvx_quantize_ahf(in_ptr, out_ptr, size, -128.0f, 127.0f, scale_); + } + if (dtype == DType::Float32 && out_0.get_dtype() == DType::QUInt8) { + // NHWC + auto in_ptr = (float *)in_0.raw_data_const(); + auto out_ptr = (float *)out_0.raw_data(); + qhmath_hvx_quantize_af(in_ptr, out_ptr, size, -128.0f, 127.0f, scale_); + } + + if (dtype == DType::Float16 && out_0.get_dtype() == DType::QUInt16) { + // NHWC + auto in_ptr = (__fp16 *)in_0.raw_data_const(); + auto out_ptr = (__fp16 *)out_0.raw_data(); + + qhmath_hvx_quantize_ui16_ahf(in_ptr, out_ptr, size, -32768.0f, 32767.0f, scale_); + } + if (dtype == DType::Float32 && out_0.get_dtype() == DType::QUInt16) { + // NHWC + auto in_ptr = (float *)in_0.raw_data_const(); + auto out_ptr = (float *)out_0.raw_data(); + qhmath_hvx_quantize_ui16_af(in_ptr, out_ptr, size, -32768.0f, 32767.0f, scale_); + } + + if (dtype == DType::Float16 && out_0.get_dtype() == DType::QInt8) { + // NHWC + auto in_ptr = (__fp16 *)in_0.raw_data_const(); + auto out_ptr = (__fp16 *)out_0.raw_data(); + + qhmath_hvx_quantize_ahf_int8(in_ptr, out_ptr, size, -128.0f, 127.0f, scale_); + } + + if (dtype == DType::Float32 && out_0.get_dtype() == DType::QInt8) { + // NHWC + auto in_ptr = (float *)in_0.raw_data_const(); + auto out_ptr = (float *)out_0.raw_data(); + qhmath_hvx_quantize_af_out_int8(in_ptr, out_ptr, size, -128.0f, 127.0f, scale_); + } + + // auto out_ptr = (int8_t*)out_0.raw_data(); + + // out_ptr[0] = (int)dtype; + // out_ptr[1] = (int)out_0.get_dtype(); + + return GraphStatus::Success; } #else extern float Round(float num); -template +template GraphStatus llamaquantizeImpl(TensorType1 &out_0, const TensorType1 &in_0, - const PlainFloatTensor& scale) + const PlainFloatTensor &scale) { out_0.set_dims(in_0); - float scale_ = scale(0,0,0,0); - - auto out_ptr = (int8_t*)out_0.raw_data(); + float scale_ = scale(0, 0, 0, 0); auto [b_in, h_in, w_in, d_in] = in_0.dims(); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - - for (Idx w = 0; w < w_in; w++) { - - for (Idx d = 0; d < d_in; d++) { - - float inval = in_0(b, h, w, d); - - // float result = Round(inval / scale_); - - - long v = lroundf(inval / scale_); - - if (v > 127) - v = 127; - - if (v < -128) - v = -128; - - if (out_0.get_dtype() == DType::QUInt8) - v += 128; - - *out_ptr++ = static_cast(v); - } + DType dtype = in_0.get_dtype(); + if (dtype == DType::Float32 && out_0.get_dtype() == DType::QUInt8) { + auto out_ptr = (int8_t *)out_0.raw_data(); + + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + float inval = in_0(b, h, w, d); + + // float result = Round(inval / scale_); + + long v = lroundf(inval / scale_); + + if (v > 127) + v = 127; + + if (v < -128) + v = -128; + + v += 128; + + *out_ptr++ = static_cast(v); + } + } } } } - return GraphStatus::Success; -} -#endif + if (dtype == DType::Float32 && out_0.get_dtype() == DType::QUInt16) { + auto out_ptr = (int16_t *)out_0.raw_data(); -__attribute__((unused)) static float llamaquantizeCostFunc(const Op *op) -{ - /* - * add code here - * */ + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + float inval = in_0(b, h, w, d); - float cost = 0.0; // add cost computation here - return cost; -} + // float result = Round(inval / scale_); + + long v = lroundf(inval / scale_); + + if (v > 32767) + v = 32767; + + if (v < -32768) + v = -32768; + + v += 32768; + *out_ptr++ = static_cast(v); + } + } + } + } + } + return GraphStatus::Success; +} +#endif +__attribute__((unused)) static float llamaquantizeCostFunc(const Op *op) { + /* + * add code here + * */ + float cost = 0.0; // add cost computation here + return cost; +} /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAReLU.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAReLU.cpp index 1ef2c0c93..c56bb8719 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAReLU.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMAReLU.cpp @@ -9,14 +9,12 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_LLaMAReLU); - // op execute function declarations -template -GraphStatus llamareluImpl(TensorType& out_0, - const TensorType& in_0); +template +GraphStatus llamareluImpl(TensorType &out_0, + const TensorType &in_0); // forward declaration of sample cost function static float llamareluCostFunc(const Op *op); @@ -61,11 +59,11 @@ DEF_PACKAGE_OP((llamareluImpl), "LLaMAReLU") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -79,7 +77,6 @@ DEF_PACKAGE_OP((llamareluImpl), "LLaMAReLU") * Qnn_addNode */ - /* execute functions for ops */ // #ifndef REFERENCE_OP @@ -94,7 +91,6 @@ DEF_PACKAGE_OP((llamareluImpl), "LLaMAReLU") // #define ONE 0x3F800000 // #define M_ONE 0xAF800000 - // int32_t hvx_relu_au8(uint8_t *restrict input, uint8_t *restrict output, uint32_t size) // { // HVX_Vector *input_v_ptr; @@ -107,7 +103,6 @@ DEF_PACKAGE_OP((llamareluImpl), "LLaMAReLU") // int32_t vectors_in_rounddown = size / 128; // int32_t leftover_size = leftover * sizeof(uint8_t); - // /* Check input arguments. Return error status if some argument has invalid value */ // if ((input == 0) || (output == 0) || (size == 0)) // { @@ -200,7 +195,6 @@ DEF_PACKAGE_OP((llamareluImpl), "LLaMAReLU") // * // * Please check in SDK documentation for more information. // */ - // out_0.set_dims(in_0); @@ -214,91 +208,80 @@ DEF_PACKAGE_OP((llamareluImpl), "LLaMAReLU") // return GraphStatus::Success; // } // #else -template -GraphStatus llamareluImpl(TensorType& out_0, - const TensorType& in_0) +template +GraphStatus llamareluImpl(TensorType &out_0, + const TensorType &in_0) { - out_0.set_dims(in_0); + out_0.set_dims(in_0); // NHWC - if (in_0.get_dtype() == DType::QUInt8) { - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // SiLU - for (Idx d = 0; d < d_in; d++) { - uint8_t inval = in_0(b, h, w, d); - if (inval < 0) - inval = 0; - - out_0(b, h, w, d) = inval; - - } + if (in_0.get_dtype() == DType::QUInt8) { + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // SiLU + for (Idx d = 0; d < d_in; d++) { + uint8_t inval = in_0(b, h, w, d); + if (inval < 0) + inval = 0; + + out_0(b, h, w, d) = inval; + } + } + } } - } - } - } else if (in_0.get_dtype() == DType::Float16) { - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - auto out_ptr = (__fp16*)out_0.raw_data(); - auto in_ptr = (__fp16*)in_0.raw_data_const(); - - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - - for (Idx d = 0; d < d_in; d++) { - __fp16 inval = *in_ptr++; - if (inval < 0) - inval = 0; - - *out_ptr++ = inval; - - } + } else if (in_0.get_dtype() == DType::Float16) { + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + + auto out_ptr = (__fp16 *)out_0.raw_data(); + auto in_ptr = (__fp16 *)in_0.raw_data_const(); + + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + __fp16 inval = *in_ptr++; + if (inval < 0) + inval = 0; + + *out_ptr++ = inval; + } + } + } } - } - } - } else if(in_0.get_dtype() == DType::Float32) { - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - for (Idx d = 0; d < d_in; d++) { - float inval = in_0(b, h, w, d); - if (inval < 0) - inval = 0; - - out_0(b, h, w, d) = inval; - - } + } else if (in_0.get_dtype() == DType::Float32) { + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + for (Idx d = 0; d < d_in; d++) { + float inval = in_0(b, h, w, d); + if (inval < 0) + inval = 0; + + out_0(b, h, w, d) = inval; + } + } + } } - } } - } - - return GraphStatus::Success; + return GraphStatus::Success; } // #endif +__attribute__((unused)) static float llamareluCostFunc(const Op *op) { + /* + * add code here + * */ -__attribute__((unused)) static float llamareluCostFunc(const Op *op) -{ - /* - * add code here - * */ - - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMASuperSiLU.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMASuperSiLU.cpp index 0a849ca11..3976f60ba 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMASuperSiLU.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/LLaMASuperSiLU.cpp @@ -9,18 +9,16 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_LLaMASuperSiLU); - // op execute function declarations -template -GraphStatus llamasupersiluImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const PlainFloatTensor& a_scale, - const PlainFloatTensor& b_scale, - const PlainFloatTensor& o_scale); +template +GraphStatus llamasupersiluImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const PlainFloatTensor &a_scale, + const PlainFloatTensor &b_scale, + const PlainFloatTensor &o_scale); // forward declaration of sample cost function static float llamasupersiluCostFunc(const Op *op); @@ -65,11 +63,11 @@ DEF_PACKAGE_OP((llamasupersiluImpl), "LLaMASuperSiLU") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -82,7 +80,7 @@ DEF_PACKAGE_OP((llamasupersiluImpl), "LLaMASuperSiLU") * graph construction will skip this parameter when this parameter is not provided at * Qnn_addNode */ -DEF_PACKAGE_PARAM_ORDER("LLaMASuperSiLU", +DEF_PACKAGE_PARAM_ORDER("LLaMASuperSiLU", "a_scale", true, nullptr, @@ -93,7 +91,6 @@ DEF_PACKAGE_PARAM_ORDER("LLaMASuperSiLU", true, nullptr) - /* execute functions for ops */ #ifndef REFERENCE_OP @@ -103,8 +100,8 @@ DEF_PACKAGE_PARAM_ORDER("LLaMASuperSiLU", #include #include -#define BLOCK_SIZE (8*1024/VLEN) /* vector chunks */ -#define L2FETCH_AHEAD (BLOCK_SIZE) +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) #define FP16_MANTISA 10 #define FP16_EXPONENT_MASK 0x1f @@ -115,8 +112,7 @@ DEF_PACKAGE_PARAM_ORDER("LLaMASuperSiLU", #define ROUND_2_SCALE 22 #define ROUND_SCALSE ((1 << ROUND_2_SCALE) * 1.0f) -static inline int32_t float_to_fp16s(float input) -{ +static inline int32_t float_to_fp16s(float input) { union { int32_t i; __fp16 f[2]; @@ -124,47 +120,188 @@ static inline int32_t float_to_fp16s(float input) return fp32.i; } -static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) -{ - union { float f; uint32_t i; } fp32 = { .f = x }; +static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) { + union { + float f; + uint32_t i; + } fp32 = {.f = x}; return fp32.i; } - static const float fp16_c0_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.13239719960243818,0.2216255210749415,0.3447664743728659,0.48137452032585476,0.5716299228719798,0.5547323231605259,0.5046287748870234,0.4999985574626892, -0.5000036514755082,0.49475652448004626,0.4441393352532763,0.428500379952032,0.5173297285470642,0.6541461039833616,0.7783931007462818,0.8678015179911097, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.13239719960243818, + 0.2216255210749415, + 0.3447664743728659, + 0.48137452032585476, + 0.5716299228719798, + 0.5547323231605259, + 0.5046287748870234, + 0.4999985574626892, + 0.5000036514755082, + 0.49475652448004626, + 0.4441393352532763, + 0.428500379952032, + 0.5173297285470642, + 0.6541461039833616, + 0.7783931007462818, + 0.8678015179911097, }; static const float fp16_c1_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.05928005756790343,0.11063222460270064,0.1932879057003057,0.30302440212086995,0.3922924462181049,0.36546332659415875,0.2644148210990377,0.24989020912329707, -0.2498532691910313,0.2661055781198988,0.36728015359480604,0.39215270010450015,0.3041825601732039,0.1940762094668647,0.11061794856987572,0.059174800917353595, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.05928005756790343, + 0.11063222460270064, + 0.1932879057003057, + 0.30302440212086995, + 0.3922924462181049, + 0.36546332659415875, + 0.2644148210990377, + 0.24989020912329707, + 0.2498532691910313, + 0.2661055781198988, + 0.36728015359480604, + 0.39215270010450015, + 0.3041825601732039, + 0.1940762094668647, + 0.11061794856987572, + 0.059174800917353595, }; static const float fp16_c2_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.010145494303219278,0.02123968384425681,0.04207468332514667,0.07519946712591977,0.10840620196267145,0.09270738184406795,0.015322371881818012,-0.0009948273994921822, -0.0011544907060402412,-0.017040517565094934,-0.09379878876657094,-0.10835043868732394,-0.07558705272699548,-0.04228875316413285,-0.021235740718738055,-0.010124599879590107, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.010145494303219278, + 0.02123968384425681, + 0.04207468332514667, + 0.07519946712591977, + 0.10840620196267145, + 0.09270738184406795, + 0.015322371881818012, + -0.0009948273994921822, + 0.0011544907060402412, + -0.017040517565094934, + -0.09379878876657094, + -0.10835043868732394, + -0.07558705272699548, + -0.04228875316413285, + -0.021235740718738055, + -0.010124599879590107, }; static const float fp16_c3_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.0007841223015974933,0.001850453397354219,0.004187899308371771,0.008640952434084206,0.01414741414964877,0.010117749275618,-0.01654848996354919,-0.02395108399453624, --0.024199111971064446,-0.015783556879607072,0.010407672131558174,0.014137608186323335,0.008698510795258909,0.004213708431213342,0.0018499827774393985,0.0007822799742289481, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0007841223015974933, + 0.001850453397354219, + 0.004187899308371771, + 0.008640952434084206, + 0.01414741414964877, + 0.010117749275618, + -0.01654848996354919, + -0.02395108399453624, + -0.024199111971064446, + -0.015783556879607072, + 0.010407672131558174, + 0.014137608186323335, + 0.008698510795258909, + 0.004213708431213342, + 0.0018499827774393985, + 0.0007822799742289481, }; static const float fp16_c4_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.3031641204975905e-05,6.150442488966733e-05,0.00015997783736818624,0.00038491646239693526,0.0007283649599237781,0.00034439150914392054,-0.003142246198646662,-0.004120389580321761, -0.004246050162553198,0.0030162727520777893,-0.00037312974308425725,-0.0007277242855014247,-0.00038811687679772674,-0.0001611434776868886,-6.14837984586862e-05,-2.297076123375133e-05, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.3031641204975905e-05, + 6.150442488966733e-05, + 0.00015997783736818624, + 0.00038491646239693526, + 0.0007283649599237781, + 0.00034439150914392054, + -0.003142246198646662, + -0.004120389580321761, + 0.004246050162553198, + 0.0030162727520777893, + -0.00037312974308425725, + -0.0007277242855014247, + -0.00038811687679772674, + -0.0001611434776868886, + -6.14837984586862e-05, + -2.297076123375133e-05, }; int32_t hvx_supersilu_ahf( @@ -174,10 +311,8 @@ int32_t hvx_supersilu_ahf( float a_scale, float b_scale, float o_scale, - uint32_t size) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + uint32_t size) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -195,18 +330,15 @@ int32_t hvx_supersilu_ahf( sline1p = *iptr++; sline2p = *iptr2++; - - // dequantize + // dequantize uint32_t convert = 0x00800080; HVX_Vector convert_vector = Q6_V_vsplat_R(convert); - HVX_Vector a_scale_vec = Q6_V_vsplat_R(float_to_fp16s(a_scale)); HVX_Vector b_scale_vec = Q6_V_vsplat_R(float_to_fp16s(b_scale)); HVX_Vector zero_v_sf = Q6_V_vzero(); - - //silu + // silu HVX_Vector input_min_v_hf; HVX_Vector input_shifted_v_hf; HVX_Vector input_scaled_v; @@ -286,27 +418,25 @@ int32_t hvx_supersilu_ahf( c3_coeff_dv.VV = Q6_Wuw_vzxt_Vuh(c3_coeff_v); c4_coeff_dv.VV = Q6_Wuw_vzxt_Vuh(c4_coeff_v); - // quantize HVX_Vector low_level_vec, high_level_vec, o_scale_vec, es_vec, round_scale_vec; HVX_Vector uintconvert = Q6_V_vsplat_R(0x80808080); HVX_Vector vmb = Q6_V_vsplat_R(0x40004000); - float post_scale_flt = a_scale * b_scale * o_scale; - int scexp = flt_getexp( post_scale_flt); - int rsh = min_i32( -scexp,7); // e.g. 0.11 -> 0.88, rsh = 3 + int scexp = flt_getexp(post_scale_flt); + int rsh = min_i32(-scexp, 7); // e.g. 0.11 -> 0.88, rsh = 3 float rsh_fac = flt_power2(rsh); int adj_bias = roundf_i32(128 * rsh_fac); - adj_bias = Q6_R_combine_RlRl( adj_bias, adj_bias); + adj_bias = Q6_R_combine_RlRl(adj_bias, adj_bias); HVX_Vector vadj = Q6_V_vsplat_R(adj_bias); - float es = 0.5; + float es = 0.5; low_level_vec = Q6_V_vsplat_R(float_to_fp16s(-128.0f)); high_level_vec = Q6_V_vsplat_R(float_to_fp16s(127.0f)); - o_scale_vec = Q6_V_vsplat_R(float_to_fp16s(post_scale_flt * rsh_fac * (1<<15))); + o_scale_vec = Q6_V_vsplat_R(float_to_fp16s(post_scale_flt * rsh_fac * (1 << 15))); // one_vec = Q6_V_vsplat_R(float_to_fp16s(1.0f)); // o_scale_vec = Q6_Vqf16_vadd_VhfVhf(o_scale_vec, zero_v_hf); es_vec = Q6_V_vsplat_R(float_to_fp16s(es)); @@ -323,45 +453,40 @@ int32_t hvx_supersilu_ahf( HVX_Vector negone = Q6_Vh_vsplat_R(FP16_NEG_1); HVX_Vector zero = Q6_V_vzero(); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline2c = *iptr2++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); - HVX_Vector sline1_high; HVX_Vector sline1_low; // HVX_Vector sline2_high; // HVX_Vector sline2_low; { - // dequantize sline1 qf16 - HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); + // dequantize sline1 qf16 + HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); - temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); - HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); - HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); + HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); - sline1_low = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), a_scale_vec); - sline1_low = Q6_Vhf_equals_Vqf16(sline1_low); - sline1_high = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), a_scale_vec); - sline1_high = Q6_Vhf_equals_Vqf16(sline1_high); + sline1_low = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), a_scale_vec); + sline1_low = Q6_Vhf_equals_Vqf16(sline1_low); + sline1_high = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), a_scale_vec); + sline1_high = Q6_Vhf_equals_Vqf16(sline1_high); } - // { // // dequantize sline2 qf16 // HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline2, zero_v_sf); @@ -377,164 +502,162 @@ int32_t hvx_supersilu_ahf( // } { - // silu sline1_low - tmp_v = Q6_Vh_vdeal_Vh(sline1_low); - - /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ - input_shifted_v_hf = Q6_Vqf16_vsub_VhfVhf(tmp_v, input_min_v_hf); - - /* - * Scale shifted input range from [0, input_max - input_min] to [0,16.0) - * in order to get corresponding coefficient indexes - */ - input_scaled_v = Q6_Vqf16_vmpy_Vqf16Vqf16(input_shifted_v_hf, scale_v); - - /* - * VLUT 16 requires integer indexes. Shift scaled input range from [0,16.0) - * to [16.0,32.0) in order to convert float indexes to integer values. - * Float values, represented in IEEE 754, in range [16.0,32.0] have the - * same exponent, which means 4 MSB of mantissa carry information about - * integer index. - * Use the same input_scaled_v vector for hf and qf16 representation - */ - input_scaled_v = Q6_Vqf16_vadd_Vqf16Vhf(input_scaled_v, const16_0_v_hf); - - /* Convert back from qf16 to hf in order to extract integer index */ - tmp_v = Q6_Vhf_equals_Vqf16(input_scaled_v); - - /* Only 4 MSB bits of mantissa represent segment index */ - idx1_v = Q6_Vuh_vlsr_VuhR(tmp_v, 6); - - /* Ensure only 4 MSB bits of mantissa are used as indexes */ - idx1_v = Q6_V_vand_VV(idx1_v, mask_idx1_v); - - idx1_v = Q6_Vb_vshuff_Vb(idx1_v); - idx1_v = Q6_V_vor_VV(idx1_v, mask_idx2_v); - idx2_v = Q6_Vw_vasl_VwR(idx1_v, 16); - - /* Obtain the polynomial coefficients from lookup table */ - c0_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c0_coeff_dv.VV), 1); - c0_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c0_coeff_vp, idx2_v, Q6_V_hi_W(c0_coeff_dv.VV), 1); - c1_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c1_coeff_dv.VV), 1); - c1_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c1_coeff_vp, idx2_v, Q6_V_hi_W(c1_coeff_dv.VV), 1); - c2_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c2_coeff_dv.VV), 1); - c2_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c2_coeff_vp, idx2_v, Q6_V_hi_W(c2_coeff_dv.VV), 1); - c3_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c3_coeff_dv.VV), 1); - c3_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c3_coeff_vp, idx2_v, Q6_V_hi_W(c3_coeff_dv.VV), 1); - c4_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c4_coeff_dv.VV), 1); - c4_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c4_coeff_vp, idx2_v, Q6_V_hi_W(c4_coeff_dv.VV), 1); - - /* Convert input from hf vector to qf32 vector pair for Horner's method*/ - input_vp_qf32 = Q6_Wqf32_vmpy_VhfVhf(sline1_low, one_v_hf); - - /* Perform evaluation of polynomial using Horner's method */ - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(c4_coeff_vp), Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c3_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c2_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c1_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c0_coeff_vp)); - - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(c4_coeff_vp), Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c3_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c2_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c1_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c0_coeff_vp)); - - // x * sigmod - // output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(input_vp_qf32), output_dv.V.lo); - // output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(input_vp_qf32), output_dv.V.hi); - - sline1_low = Q6_Vhf_equals_Wqf32(output_dv.VV); + // silu sline1_low + tmp_v = Q6_Vh_vdeal_Vh(sline1_low); + + /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ + input_shifted_v_hf = Q6_Vqf16_vsub_VhfVhf(tmp_v, input_min_v_hf); + + /* + * Scale shifted input range from [0, input_max - input_min] to [0,16.0) + * in order to get corresponding coefficient indexes + */ + input_scaled_v = Q6_Vqf16_vmpy_Vqf16Vqf16(input_shifted_v_hf, scale_v); + + /* + * VLUT 16 requires integer indexes. Shift scaled input range from [0,16.0) + * to [16.0,32.0) in order to convert float indexes to integer values. + * Float values, represented in IEEE 754, in range [16.0,32.0] have the + * same exponent, which means 4 MSB of mantissa carry information about + * integer index. + * Use the same input_scaled_v vector for hf and qf16 representation + */ + input_scaled_v = Q6_Vqf16_vadd_Vqf16Vhf(input_scaled_v, const16_0_v_hf); + + /* Convert back from qf16 to hf in order to extract integer index */ + tmp_v = Q6_Vhf_equals_Vqf16(input_scaled_v); + + /* Only 4 MSB bits of mantissa represent segment index */ + idx1_v = Q6_Vuh_vlsr_VuhR(tmp_v, 6); + + /* Ensure only 4 MSB bits of mantissa are used as indexes */ + idx1_v = Q6_V_vand_VV(idx1_v, mask_idx1_v); + + idx1_v = Q6_Vb_vshuff_Vb(idx1_v); + idx1_v = Q6_V_vor_VV(idx1_v, mask_idx2_v); + idx2_v = Q6_Vw_vasl_VwR(idx1_v, 16); + + /* Obtain the polynomial coefficients from lookup table */ + c0_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c0_coeff_dv.VV), 1); + c0_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c0_coeff_vp, idx2_v, Q6_V_hi_W(c0_coeff_dv.VV), 1); + c1_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c1_coeff_dv.VV), 1); + c1_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c1_coeff_vp, idx2_v, Q6_V_hi_W(c1_coeff_dv.VV), 1); + c2_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c2_coeff_dv.VV), 1); + c2_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c2_coeff_vp, idx2_v, Q6_V_hi_W(c2_coeff_dv.VV), 1); + c3_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c3_coeff_dv.VV), 1); + c3_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c3_coeff_vp, idx2_v, Q6_V_hi_W(c3_coeff_dv.VV), 1); + c4_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c4_coeff_dv.VV), 1); + c4_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c4_coeff_vp, idx2_v, Q6_V_hi_W(c4_coeff_dv.VV), 1); + + /* Convert input from hf vector to qf32 vector pair for Horner's method*/ + input_vp_qf32 = Q6_Wqf32_vmpy_VhfVhf(sline1_low, one_v_hf); + + /* Perform evaluation of polynomial using Horner's method */ + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(c4_coeff_vp), Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c3_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c2_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c1_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c0_coeff_vp)); + + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(c4_coeff_vp), Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c3_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c2_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c1_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c0_coeff_vp)); + + // x * sigmod + // output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(input_vp_qf32), output_dv.V.lo); + // output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(input_vp_qf32), output_dv.V.hi); + + sline1_low = Q6_Vhf_equals_Wqf32(output_dv.VV); } - { - // silu sline1_high - tmp_v = Q6_Vh_vdeal_Vh(sline1_high); - - /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ - input_shifted_v_hf = Q6_Vqf16_vsub_VhfVhf(tmp_v, input_min_v_hf); - - /* - * Scale shifted input range from [0, input_max - input_min] to [0,16.0) - * in order to get corresponding coefficient indexes - */ - input_scaled_v = Q6_Vqf16_vmpy_Vqf16Vqf16(input_shifted_v_hf, scale_v); - - /* - * VLUT 16 requires integer indexes. Shift scaled input range from [0,16.0) - * to [16.0,32.0) in order to convert float indexes to integer values. - * Float values, represented in IEEE 754, in range [16.0,32.0] have the - * same exponent, which means 4 MSB of mantissa carry information about - * integer index. - * Use the same input_scaled_v vector for hf and qf16 representation - */ - input_scaled_v = Q6_Vqf16_vadd_Vqf16Vhf(input_scaled_v, const16_0_v_hf); - - /* Convert back from qf16 to hf in order to extract integer index */ - tmp_v = Q6_Vhf_equals_Vqf16(input_scaled_v); - - /* Only 4 MSB bits of mantissa represent segment index */ - idx1_v = Q6_Vuh_vlsr_VuhR(tmp_v, 6); - - /* Ensure only 4 MSB bits of mantissa are used as indexes */ - idx1_v = Q6_V_vand_VV(idx1_v, mask_idx1_v); - - idx1_v = Q6_Vb_vshuff_Vb(idx1_v); - idx1_v = Q6_V_vor_VV(idx1_v, mask_idx2_v); - idx2_v = Q6_Vw_vasl_VwR(idx1_v, 16); - - /* Obtain the polynomial coefficients from lookup table */ - c0_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c0_coeff_dv.VV), 1); - c0_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c0_coeff_vp, idx2_v, Q6_V_hi_W(c0_coeff_dv.VV), 1); - c1_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c1_coeff_dv.VV), 1); - c1_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c1_coeff_vp, idx2_v, Q6_V_hi_W(c1_coeff_dv.VV), 1); - c2_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c2_coeff_dv.VV), 1); - c2_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c2_coeff_vp, idx2_v, Q6_V_hi_W(c2_coeff_dv.VV), 1); - c3_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c3_coeff_dv.VV), 1); - c3_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c3_coeff_vp, idx2_v, Q6_V_hi_W(c3_coeff_dv.VV), 1); - c4_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c4_coeff_dv.VV), 1); - c4_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c4_coeff_vp, idx2_v, Q6_V_hi_W(c4_coeff_dv.VV), 1); - - /* Convert input from hf vector to qf32 vector pair for Horner's method*/ - input_vp_qf32 = Q6_Wqf32_vmpy_VhfVhf(sline1_high, one_v_hf); - - /* Perform evaluation of polynomial using Horner's method */ - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(c4_coeff_vp), Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c3_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c2_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c1_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c0_coeff_vp)); - - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(c4_coeff_vp), Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c3_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c2_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c1_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c0_coeff_vp)); - - // x * sigmod - // output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(input_vp_qf32), output_dv.V.lo); - // output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(input_vp_qf32), output_dv.V.hi); - - sline1_high = Q6_Vhf_equals_Wqf32(output_dv.VV); + // silu sline1_high + tmp_v = Q6_Vh_vdeal_Vh(sline1_high); + + /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ + input_shifted_v_hf = Q6_Vqf16_vsub_VhfVhf(tmp_v, input_min_v_hf); + + /* + * Scale shifted input range from [0, input_max - input_min] to [0,16.0) + * in order to get corresponding coefficient indexes + */ + input_scaled_v = Q6_Vqf16_vmpy_Vqf16Vqf16(input_shifted_v_hf, scale_v); + + /* + * VLUT 16 requires integer indexes. Shift scaled input range from [0,16.0) + * to [16.0,32.0) in order to convert float indexes to integer values. + * Float values, represented in IEEE 754, in range [16.0,32.0] have the + * same exponent, which means 4 MSB of mantissa carry information about + * integer index. + * Use the same input_scaled_v vector for hf and qf16 representation + */ + input_scaled_v = Q6_Vqf16_vadd_Vqf16Vhf(input_scaled_v, const16_0_v_hf); + + /* Convert back from qf16 to hf in order to extract integer index */ + tmp_v = Q6_Vhf_equals_Vqf16(input_scaled_v); + + /* Only 4 MSB bits of mantissa represent segment index */ + idx1_v = Q6_Vuh_vlsr_VuhR(tmp_v, 6); + + /* Ensure only 4 MSB bits of mantissa are used as indexes */ + idx1_v = Q6_V_vand_VV(idx1_v, mask_idx1_v); + + idx1_v = Q6_Vb_vshuff_Vb(idx1_v); + idx1_v = Q6_V_vor_VV(idx1_v, mask_idx2_v); + idx2_v = Q6_Vw_vasl_VwR(idx1_v, 16); + + /* Obtain the polynomial coefficients from lookup table */ + c0_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c0_coeff_dv.VV), 1); + c0_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c0_coeff_vp, idx2_v, Q6_V_hi_W(c0_coeff_dv.VV), 1); + c1_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c1_coeff_dv.VV), 1); + c1_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c1_coeff_vp, idx2_v, Q6_V_hi_W(c1_coeff_dv.VV), 1); + c2_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c2_coeff_dv.VV), 1); + c2_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c2_coeff_vp, idx2_v, Q6_V_hi_W(c2_coeff_dv.VV), 1); + c3_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c3_coeff_dv.VV), 1); + c3_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c3_coeff_vp, idx2_v, Q6_V_hi_W(c3_coeff_dv.VV), 1); + c4_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c4_coeff_dv.VV), 1); + c4_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c4_coeff_vp, idx2_v, Q6_V_hi_W(c4_coeff_dv.VV), 1); + + /* Convert input from hf vector to qf32 vector pair for Horner's method*/ + input_vp_qf32 = Q6_Wqf32_vmpy_VhfVhf(sline1_high, one_v_hf); + + /* Perform evaluation of polynomial using Horner's method */ + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(c4_coeff_vp), Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c3_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c2_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c1_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c0_coeff_vp)); + + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(c4_coeff_vp), Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c3_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c2_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c1_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c0_coeff_vp)); + + // x * sigmod + // output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(input_vp_qf32), output_dv.V.lo); + // output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(input_vp_qf32), output_dv.V.hi); + + sline1_high = Q6_Vhf_equals_Wqf32(output_dv.VV); } - HVX_Vector sline_high; HVX_Vector sline_low; - + // { // // mul // sline_high = Q6_Vqf16_vmpy_VhfVhf(sline1_high, sline2_high); @@ -543,35 +666,34 @@ int32_t hvx_supersilu_ahf( // sline_high = Q6_Vhf_equals_Vqf16(sline_high); // sline_low = Q6_Vhf_equals_Vqf16(sline_low); // } - + HVX_VectorPair mul_output; { - // uint8 mul - // (a-128)*(b-128) = a*b - 128 (a+b) + 128*128 - HVX_VectorPair prod1 = Q6_Wuh_vmpyacc_WuhVubVub(Q6_W_vcombine_VV(vmb,vmb), sline1, sline2); - HVX_VectorPair prod2 = Q6_Wh_vmpa_WubRub( Q6_W_vcombine_VV(sline2, sline1), 0x80808080); - mul_output = Q6_Wh_vsub_WhWh(prod1, prod2); + // uint8 mul + // (a-128)*(b-128) = a*b - 128 (a+b) + 128*128 + HVX_VectorPair prod1 = Q6_Wuh_vmpyacc_WuhVubVub(Q6_W_vcombine_VV(vmb, vmb), sline1, sline2); + HVX_VectorPair prod2 = Q6_Wh_vmpa_WubRub(Q6_W_vcombine_VV(sline2, sline1), 0x80808080); + mul_output = Q6_Wh_vsub_WhWh(prod1, prod2); - mul_output = Q6_W_vshuff_VVR(Q6_V_hi_W(mul_output), Q6_V_lo_W(mul_output), -2); - - // sline_low = Q6_Vqf16_vmpy_VhfVhf(sline1_low, Q6_Vhf_equals_Vh(Q6_V_lo_W(mul_output))); - // sline_high = Q6_Vqf16_vmpy_VhfVhf(sline1_high, Q6_Vhf_equals_Vh(Q6_V_hi_W(mul_output))); + mul_output = Q6_W_vshuff_VVR(Q6_V_hi_W(mul_output), Q6_V_lo_W(mul_output), -2); + // sline_low = Q6_Vqf16_vmpy_VhfVhf(sline1_low, Q6_Vhf_equals_Vh(Q6_V_lo_W(mul_output))); + // sline_high = Q6_Vqf16_vmpy_VhfVhf(sline1_high, Q6_Vhf_equals_Vh(Q6_V_hi_W(mul_output))); } { - // scaling quantize - sline_low = Q6_Vqf16_vmpy_VhfVhf(sline1_low, o_scale_vec); - sline_low = Q6_Vh_equals_Vhf(Q6_Vhf_equals_Vqf16(sline_low)); - sline_low = Q6_Vh_vadd_VhVh_sat(Q6_Vh_vmpy_VhVh_s1_rnd_sat(Q6_V_lo_W(mul_output), sline_low), vadj); - - sline_high = Q6_Vqf16_vmpy_VhfVhf(sline1_high, o_scale_vec); - sline_high = Q6_Vh_equals_Vhf(Q6_Vhf_equals_Vqf16(sline_high)); - sline_high = Q6_Vh_vadd_VhVh_sat(Q6_Vh_vmpy_VhVh_s1_rnd_sat(sline_high, Q6_V_hi_W(mul_output)), vadj); - - HVX_Vector sout = Q6_Vub_vasr_VhVhR_rnd_sat( sline_high, sline_low, rsh); - sout = Q6_Vb_vdeal_Vb(sout); - *optr++ = sout; + // scaling quantize + sline_low = Q6_Vqf16_vmpy_VhfVhf(sline1_low, o_scale_vec); + sline_low = Q6_Vh_equals_Vhf(Q6_Vhf_equals_Vqf16(sline_low)); + sline_low = Q6_Vh_vadd_VhVh_sat(Q6_Vh_vmpy_VhVh_s1_rnd_sat(Q6_V_lo_W(mul_output), sline_low), vadj); + + sline_high = Q6_Vqf16_vmpy_VhfVhf(sline1_high, o_scale_vec); + sline_high = Q6_Vh_equals_Vhf(Q6_Vhf_equals_Vqf16(sline_high)); + sline_high = Q6_Vh_vadd_VhVh_sat(Q6_Vh_vmpy_VhVh_s1_rnd_sat(sline_high, Q6_V_hi_W(mul_output)), vadj); + + HVX_Vector sout = Q6_Vub_vasr_VhVhR_rnd_sat(sline_high, sline_low, rsh); + sout = Q6_Vb_vdeal_Vb(sout); + *optr++ = sout; } // { @@ -589,7 +711,6 @@ int32_t hvx_supersilu_ahf( // sout1_low = Q6_V_lo_W(sout1_pair); // sout1_high = Q6_V_hi_W(sout1_pair); - // // { // // HVX_Vector exp = Q6_Vh_vasr_VhR(sout1, FP16_MANTISA); // // exp = Q6_V_vand_VV(exp, expmask); @@ -629,7 +750,6 @@ int32_t hvx_supersilu_ahf( // sout1_high = Q6_Vw_equals_Vsf(sout1_high); // sout1_high = Q6_Vw_vasr_VwR(sout1_high, ROUND_2_SCALE); - // HVX_Vector sout2 = Q6_Vqf16_vmpy_Vqf16Vhf(sline_high, o_scale_vec); // sout2 = Q6_Vqf16_vadd_Vqf16Vqf16(sout2, es_vec); // sout2 = Q6_Vhf_equals_Vqf16(sout2); @@ -689,321 +809,308 @@ int32_t hvx_supersilu_ahf( // *optr++ = Q6_Vb_vadd_VbVb(req_b, uintconvert); // } - - - - sline1p = sline1c; sline2p = sline2c; } } if (vectors_in_rounddown > 0) { + o_scale_vec = Q6_V_vsplat_R(float_to_fp16s(o_scale)); - o_scale_vec = Q6_V_vsplat_R(float_to_fp16s(o_scale)); - - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - - sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) input2); - - - HVX_Vector sline1_high; - HVX_Vector sline1_low; - HVX_Vector sline2_high; - HVX_Vector sline2_low; - - { - // dequantize sline1 qf16 - HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); - - temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); - HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); - HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); - - sline1_low = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), a_scale_vec); - sline1_low = Q6_Vhf_equals_Vqf16(sline1_low); - sline1_high = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), a_scale_vec); - sline1_high = Q6_Vhf_equals_Vqf16(sline1_high); - } - - - { - // dequantize sline2 qf16 - HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline2, zero_v_sf); - - temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); - HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); - HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); - - sline2_low = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), b_scale_vec); - sline2_low = Q6_Vhf_equals_Vqf16(sline2_low); - sline2_high = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), b_scale_vec); - sline2_high = Q6_Vhf_equals_Vqf16(sline2_high); - } - - { - // silu sline1_low - tmp_v = Q6_Vh_vdeal_Vh(sline1_low); - - /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ - input_shifted_v_hf = Q6_Vqf16_vsub_VhfVhf(tmp_v, input_min_v_hf); - - /* - * Scale shifted input range from [0, input_max - input_min] to [0,16.0) - * in order to get corresponding coefficient indexes - */ - input_scaled_v = Q6_Vqf16_vmpy_Vqf16Vqf16(input_shifted_v_hf, scale_v); - - /* - * VLUT 16 requires integer indexes. Shift scaled input range from [0,16.0) - * to [16.0,32.0) in order to convert float indexes to integer values. - * Float values, represented in IEEE 754, in range [16.0,32.0] have the - * same exponent, which means 4 MSB of mantissa carry information about - * integer index. - * Use the same input_scaled_v vector for hf and qf16 representation - */ - input_scaled_v = Q6_Vqf16_vadd_Vqf16Vhf(input_scaled_v, const16_0_v_hf); - - /* Convert back from qf16 to hf in order to extract integer index */ - tmp_v = Q6_Vhf_equals_Vqf16(input_scaled_v); - - /* Only 4 MSB bits of mantissa represent segment index */ - idx1_v = Q6_Vuh_vlsr_VuhR(tmp_v, 6); - - /* Ensure only 4 MSB bits of mantissa are used as indexes */ - idx1_v = Q6_V_vand_VV(idx1_v, mask_idx1_v); - - idx1_v = Q6_Vb_vshuff_Vb(idx1_v); - idx1_v = Q6_V_vor_VV(idx1_v, mask_idx2_v); - idx2_v = Q6_Vw_vasl_VwR(idx1_v, 16); - - /* Obtain the polynomial coefficients from lookup table */ - c0_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c0_coeff_dv.VV), 1); - c0_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c0_coeff_vp, idx2_v, Q6_V_hi_W(c0_coeff_dv.VV), 1); - c1_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c1_coeff_dv.VV), 1); - c1_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c1_coeff_vp, idx2_v, Q6_V_hi_W(c1_coeff_dv.VV), 1); - c2_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c2_coeff_dv.VV), 1); - c2_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c2_coeff_vp, idx2_v, Q6_V_hi_W(c2_coeff_dv.VV), 1); - c3_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c3_coeff_dv.VV), 1); - c3_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c3_coeff_vp, idx2_v, Q6_V_hi_W(c3_coeff_dv.VV), 1); - c4_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c4_coeff_dv.VV), 1); - c4_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c4_coeff_vp, idx2_v, Q6_V_hi_W(c4_coeff_dv.VV), 1); - - /* Convert input from hf vector to qf32 vector pair for Horner's method*/ - input_vp_qf32 = Q6_Wqf32_vmpy_VhfVhf(sline1_low, one_v_hf); - - /* Perform evaluation of polynomial using Horner's method */ - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(c4_coeff_vp), Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c3_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c2_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c1_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c0_coeff_vp)); - - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(c4_coeff_vp), Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c3_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c2_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c1_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c0_coeff_vp)); - - // x * sigmod - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(input_vp_qf32), output_dv.V.lo); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(input_vp_qf32), output_dv.V.hi); - - sline1_low = Q6_Vhf_equals_Wqf32(output_dv.VV); - } - - - { - // silu sline1_high - tmp_v = Q6_Vh_vdeal_Vh(sline1_high); - - /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ - input_shifted_v_hf = Q6_Vqf16_vsub_VhfVhf(tmp_v, input_min_v_hf); - - /* - * Scale shifted input range from [0, input_max - input_min] to [0,16.0) - * in order to get corresponding coefficient indexes - */ - input_scaled_v = Q6_Vqf16_vmpy_Vqf16Vqf16(input_shifted_v_hf, scale_v); - - /* - * VLUT 16 requires integer indexes. Shift scaled input range from [0,16.0) - * to [16.0,32.0) in order to convert float indexes to integer values. - * Float values, represented in IEEE 754, in range [16.0,32.0] have the - * same exponent, which means 4 MSB of mantissa carry information about - * integer index. - * Use the same input_scaled_v vector for hf and qf16 representation - */ - input_scaled_v = Q6_Vqf16_vadd_Vqf16Vhf(input_scaled_v, const16_0_v_hf); - - /* Convert back from qf16 to hf in order to extract integer index */ - tmp_v = Q6_Vhf_equals_Vqf16(input_scaled_v); - - /* Only 4 MSB bits of mantissa represent segment index */ - idx1_v = Q6_Vuh_vlsr_VuhR(tmp_v, 6); - - /* Ensure only 4 MSB bits of mantissa are used as indexes */ - idx1_v = Q6_V_vand_VV(idx1_v, mask_idx1_v); - - idx1_v = Q6_Vb_vshuff_Vb(idx1_v); - idx1_v = Q6_V_vor_VV(idx1_v, mask_idx2_v); - idx2_v = Q6_Vw_vasl_VwR(idx1_v, 16); - - /* Obtain the polynomial coefficients from lookup table */ - c0_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c0_coeff_dv.VV), 1); - c0_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c0_coeff_vp, idx2_v, Q6_V_hi_W(c0_coeff_dv.VV), 1); - c1_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c1_coeff_dv.VV), 1); - c1_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c1_coeff_vp, idx2_v, Q6_V_hi_W(c1_coeff_dv.VV), 1); - c2_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c2_coeff_dv.VV), 1); - c2_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c2_coeff_vp, idx2_v, Q6_V_hi_W(c2_coeff_dv.VV), 1); - c3_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c3_coeff_dv.VV), 1); - c3_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c3_coeff_vp, idx2_v, Q6_V_hi_W(c3_coeff_dv.VV), 1); - c4_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c4_coeff_dv.VV), 1); - c4_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c4_coeff_vp, idx2_v, Q6_V_hi_W(c4_coeff_dv.VV), 1); - - /* Convert input from hf vector to qf32 vector pair for Horner's method*/ - input_vp_qf32 = Q6_Wqf32_vmpy_VhfVhf(sline1_high, one_v_hf); - - /* Perform evaluation of polynomial using Horner's method */ - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(c4_coeff_vp), Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c3_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c2_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c1_coeff_vp)); - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); - output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c0_coeff_vp)); - - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(c4_coeff_vp), Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c3_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c2_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c1_coeff_vp)); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); - output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c0_coeff_vp)); - - // x * sigmod - output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(input_vp_qf32), output_dv.V.lo); - output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(input_vp_qf32), output_dv.V.hi); - - sline1_high = Q6_Vhf_equals_Wqf32(output_dv.VV); - } - - - HVX_Vector sline_high; - HVX_Vector sline_low; - - { - // mul - sline_high = Q6_Vqf16_vmpy_VhfVhf(sline1_high, sline2_high); - sline_low = Q6_Vqf16_vmpy_VhfVhf(sline1_low, sline2_low); - - sline_high = Q6_Vhf_equals_Vqf16(sline_high); - sline_low = Q6_Vhf_equals_Vqf16(sline_low); - } - - - { - // quantize - HVX_Vector sout1 = Q6_Vqf16_vmpy_VhfVhf(sline_low, o_scale_vec); - sout1 = Q6_Vqf16_vadd_Vqf16Vqf16(sout1, es_vec); - sout1 = Q6_Vhf_equals_Vqf16(sout1); - sout1 = Q6_Vhf_vmin_VhfVhf(sout1, high_level_vec); - sout1 = Q6_Vhf_vmax_VhfVhf(sout1, low_level_vec); + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + + sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input2); + + HVX_Vector sline1_high; + HVX_Vector sline1_low; + HVX_Vector sline2_high; + HVX_Vector sline2_low; { - HVX_Vector exp = Q6_Vh_vasr_VhR(sout1, FP16_MANTISA); - exp = Q6_V_vand_VV(exp, expmask); - exp = Q6_Vh_vsub_VhVh(exp, expbias); + // dequantize sline1 qf16 + HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); - HVX_Vector man = Q6_Vh_vasr_VhVh(manmask, exp); - HVX_Vector manzero = Q6_V_vand_VV(sout1, man); + temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); + HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); - HVX_Vector sign = Q6_Vh_vasr_VhR(sout1, FP16_SIGN); - HVX_Vector issignpos = Q6_Q_vcmp_eq_VhVh(sign, zero); + sline1_low = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), a_scale_vec); + sline1_low = Q6_Vhf_equals_Vqf16(sline1_low); + sline1_high = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), a_scale_vec); + sline1_high = Q6_Vhf_equals_Vqf16(sline1_high); + } - HVX_Vector expgte23 = Q6_Q_vcmp_gt_VhVh(exp, exp23); - HVX_Vector expgte0 = Q6_Q_vcmp_gt_VhVh(exp, exp0); - HVX_Vector maneqzero = Q6_Q_vcmp_eq_VhVh(manzero, zero); + { + // dequantize sline2 qf16 + HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline2, zero_v_sf); - HVX_Vector exppos_signneg = Q6_Vh_vadd_VhVh(sout1, man); - man = Q6_V_vnot_V(man); - HVX_Vector exppos_signpos = Q6_V_vand_VV(sout1, man); - exppos_signneg = Q6_V_vand_VV(exppos_signneg, man); - HVX_Vector shift1 = Q6_Vh_vasl_VhR(sout1, 1); - HVX_Vector iszero = Q6_Q_vcmp_eq_VhVh(shift1, zero); + temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); + HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); - // exp >= 0 - HVX_Vector tsout1 = Q6_V_vmux_QVV(issignpos, exppos_signpos, exppos_signneg); - tsout1 = Q6_V_vmux_QVV(maneqzero, sout1, tsout1); + sline2_low = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), b_scale_vec); + sline2_low = Q6_Vhf_equals_Vqf16(sline2_low); + sline2_high = Q6_Vqf16_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), b_scale_vec); + sline2_high = Q6_Vhf_equals_Vqf16(sline2_high); + } - // exp < 0 (-1, 1) - HVX_Vector tsout2 = Q6_V_vmux_QVV(iszero, sout1, negone); - tsout2 = Q6_V_vmux_QVV(issignpos, zero, tsout2); + { + // silu sline1_low + tmp_v = Q6_Vh_vdeal_Vh(sline1_low); + + /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ + input_shifted_v_hf = Q6_Vqf16_vsub_VhfVhf(tmp_v, input_min_v_hf); + + /* + * Scale shifted input range from [0, input_max - input_min] to [0,16.0) + * in order to get corresponding coefficient indexes + */ + input_scaled_v = Q6_Vqf16_vmpy_Vqf16Vqf16(input_shifted_v_hf, scale_v); + + /* + * VLUT 16 requires integer indexes. Shift scaled input range from [0,16.0) + * to [16.0,32.0) in order to convert float indexes to integer values. + * Float values, represented in IEEE 754, in range [16.0,32.0] have the + * same exponent, which means 4 MSB of mantissa carry information about + * integer index. + * Use the same input_scaled_v vector for hf and qf16 representation + */ + input_scaled_v = Q6_Vqf16_vadd_Vqf16Vhf(input_scaled_v, const16_0_v_hf); + + /* Convert back from qf16 to hf in order to extract integer index */ + tmp_v = Q6_Vhf_equals_Vqf16(input_scaled_v); + + /* Only 4 MSB bits of mantissa represent segment index */ + idx1_v = Q6_Vuh_vlsr_VuhR(tmp_v, 6); + + /* Ensure only 4 MSB bits of mantissa are used as indexes */ + idx1_v = Q6_V_vand_VV(idx1_v, mask_idx1_v); + + idx1_v = Q6_Vb_vshuff_Vb(idx1_v); + idx1_v = Q6_V_vor_VV(idx1_v, mask_idx2_v); + idx2_v = Q6_Vw_vasl_VwR(idx1_v, 16); + + /* Obtain the polynomial coefficients from lookup table */ + c0_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c0_coeff_dv.VV), 1); + c0_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c0_coeff_vp, idx2_v, Q6_V_hi_W(c0_coeff_dv.VV), 1); + c1_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c1_coeff_dv.VV), 1); + c1_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c1_coeff_vp, idx2_v, Q6_V_hi_W(c1_coeff_dv.VV), 1); + c2_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c2_coeff_dv.VV), 1); + c2_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c2_coeff_vp, idx2_v, Q6_V_hi_W(c2_coeff_dv.VV), 1); + c3_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c3_coeff_dv.VV), 1); + c3_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c3_coeff_vp, idx2_v, Q6_V_hi_W(c3_coeff_dv.VV), 1); + c4_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c4_coeff_dv.VV), 1); + c4_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c4_coeff_vp, idx2_v, Q6_V_hi_W(c4_coeff_dv.VV), 1); + + /* Convert input from hf vector to qf32 vector pair for Horner's method*/ + input_vp_qf32 = Q6_Wqf32_vmpy_VhfVhf(sline1_low, one_v_hf); + + /* Perform evaluation of polynomial using Horner's method */ + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(c4_coeff_vp), Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c3_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c2_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c1_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c0_coeff_vp)); + + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(c4_coeff_vp), Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c3_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c2_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c1_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c0_coeff_vp)); + + // x * sigmod + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(input_vp_qf32), output_dv.V.lo); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(input_vp_qf32), output_dv.V.hi); + + sline1_low = Q6_Vhf_equals_Wqf32(output_dv.VV); + } - tsout1 = Q6_V_vmux_QVV(expgte0, tsout1, tsout2); - sout1 = Q6_V_vmux_QVV(expgte23, sout1, tsout1); + { + // silu sline1_high + tmp_v = Q6_Vh_vdeal_Vh(sline1_high); + + /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ + input_shifted_v_hf = Q6_Vqf16_vsub_VhfVhf(tmp_v, input_min_v_hf); + + /* + * Scale shifted input range from [0, input_max - input_min] to [0,16.0) + * in order to get corresponding coefficient indexes + */ + input_scaled_v = Q6_Vqf16_vmpy_Vqf16Vqf16(input_shifted_v_hf, scale_v); + + /* + * VLUT 16 requires integer indexes. Shift scaled input range from [0,16.0) + * to [16.0,32.0) in order to convert float indexes to integer values. + * Float values, represented in IEEE 754, in range [16.0,32.0] have the + * same exponent, which means 4 MSB of mantissa carry information about + * integer index. + * Use the same input_scaled_v vector for hf and qf16 representation + */ + input_scaled_v = Q6_Vqf16_vadd_Vqf16Vhf(input_scaled_v, const16_0_v_hf); + + /* Convert back from qf16 to hf in order to extract integer index */ + tmp_v = Q6_Vhf_equals_Vqf16(input_scaled_v); + + /* Only 4 MSB bits of mantissa represent segment index */ + idx1_v = Q6_Vuh_vlsr_VuhR(tmp_v, 6); + + /* Ensure only 4 MSB bits of mantissa are used as indexes */ + idx1_v = Q6_V_vand_VV(idx1_v, mask_idx1_v); + + idx1_v = Q6_Vb_vshuff_Vb(idx1_v); + idx1_v = Q6_V_vor_VV(idx1_v, mask_idx2_v); + idx2_v = Q6_Vw_vasl_VwR(idx1_v, 16); + + /* Obtain the polynomial coefficients from lookup table */ + c0_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c0_coeff_dv.VV), 1); + c0_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c0_coeff_vp, idx2_v, Q6_V_hi_W(c0_coeff_dv.VV), 1); + c1_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c1_coeff_dv.VV), 1); + c1_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c1_coeff_vp, idx2_v, Q6_V_hi_W(c1_coeff_dv.VV), 1); + c2_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c2_coeff_dv.VV), 1); + c2_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c2_coeff_vp, idx2_v, Q6_V_hi_W(c2_coeff_dv.VV), 1); + c3_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c3_coeff_dv.VV), 1); + c3_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c3_coeff_vp, idx2_v, Q6_V_hi_W(c3_coeff_dv.VV), 1); + c4_coeff_vp = Q6_Wh_vlut16_VbVhR(idx1_v, Q6_V_lo_W(c4_coeff_dv.VV), 1); + c4_coeff_vp = Q6_Wh_vlut16or_WhVbVhR(c4_coeff_vp, idx2_v, Q6_V_hi_W(c4_coeff_dv.VV), 1); + + /* Convert input from hf vector to qf32 vector pair for Horner's method*/ + input_vp_qf32 = Q6_Wqf32_vmpy_VhfVhf(sline1_high, one_v_hf); + + /* Perform evaluation of polynomial using Horner's method */ + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(c4_coeff_vp), Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c3_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c2_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c1_coeff_vp)); + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(input_vp_qf32)); + output_dv.V.lo = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.lo, Q6_V_lo_W(c0_coeff_vp)); + + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(c4_coeff_vp), Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c3_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c2_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c1_coeff_vp)); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(input_vp_qf32)); + output_dv.V.hi = Q6_Vqf32_vadd_Vqf32Vqf32(output_dv.V.hi, Q6_V_hi_W(c0_coeff_vp)); + + // x * sigmod + output_dv.V.lo = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(input_vp_qf32), output_dv.V.lo); + output_dv.V.hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(input_vp_qf32), output_dv.V.hi); + + sline1_high = Q6_Vhf_equals_Wqf32(output_dv.VV); } - sout1 = Q6_Vh_equals_Vhf(sout1); + HVX_Vector sline_high; + HVX_Vector sline_low; + { + // mul + sline_high = Q6_Vqf16_vmpy_VhfVhf(sline1_high, sline2_high); + sline_low = Q6_Vqf16_vmpy_VhfVhf(sline1_low, sline2_low); - HVX_Vector sout2 = Q6_Vqf16_vmpy_VhfVhf(sline_high, o_scale_vec); - sout2 = Q6_Vqf16_vadd_Vqf16Vqf16(sout2, es_vec); - sout2 = Q6_Vhf_equals_Vqf16(sout2); - sout2 = Q6_Vhf_vmin_VhfVhf(sout2, high_level_vec); - sout2 = Q6_Vhf_vmax_VhfVhf(sout2, low_level_vec); + sline_high = Q6_Vhf_equals_Vqf16(sline_high); + sline_low = Q6_Vhf_equals_Vqf16(sline_low); + } { - HVX_Vector exp = Q6_Vh_vasr_VhR(sout2, FP16_MANTISA); - exp = Q6_V_vand_VV(exp, expmask); - exp = Q6_Vh_vsub_VhVh(exp, expbias); + // quantize + HVX_Vector sout1 = Q6_Vqf16_vmpy_VhfVhf(sline_low, o_scale_vec); + sout1 = Q6_Vqf16_vadd_Vqf16Vqf16(sout1, es_vec); + sout1 = Q6_Vhf_equals_Vqf16(sout1); + sout1 = Q6_Vhf_vmin_VhfVhf(sout1, high_level_vec); + sout1 = Q6_Vhf_vmax_VhfVhf(sout1, low_level_vec); - HVX_Vector man = Q6_Vh_vasr_VhVh(manmask, exp); - HVX_Vector manzero = Q6_V_vand_VV(sout2, man); + { + HVX_Vector exp = Q6_Vh_vasr_VhR(sout1, FP16_MANTISA); + exp = Q6_V_vand_VV(exp, expmask); + exp = Q6_Vh_vsub_VhVh(exp, expbias); - HVX_Vector sign = Q6_Vh_vasr_VhR(sout2, FP16_SIGN); - HVX_Vector issignpos = Q6_Q_vcmp_eq_VhVh(sign, zero); + HVX_Vector man = Q6_Vh_vasr_VhVh(manmask, exp); + HVX_Vector manzero = Q6_V_vand_VV(sout1, man); - HVX_Vector expgte23 = Q6_Q_vcmp_gt_VhVh(exp, exp23); - HVX_Vector expgte0 = Q6_Q_vcmp_gt_VhVh(exp, exp0); - HVX_Vector maneqzero = Q6_Q_vcmp_eq_VhVh(manzero, zero); + HVX_Vector sign = Q6_Vh_vasr_VhR(sout1, FP16_SIGN); + HVX_Vector issignpos = Q6_Q_vcmp_eq_VhVh(sign, zero); - HVX_Vector exppos_signneg = Q6_Vh_vadd_VhVh(sout2, man); - man = Q6_V_vnot_V(man); - HVX_Vector exppos_signpos = Q6_V_vand_VV(sout2, man); - exppos_signneg = Q6_V_vand_VV(exppos_signneg, man); - HVX_Vector shift1 = Q6_Vh_vasl_VhR(sout2, 1); - HVX_Vector iszero = Q6_Q_vcmp_eq_VhVh(shift1, zero); + HVX_Vector expgte23 = Q6_Q_vcmp_gt_VhVh(exp, exp23); + HVX_Vector expgte0 = Q6_Q_vcmp_gt_VhVh(exp, exp0); + HVX_Vector maneqzero = Q6_Q_vcmp_eq_VhVh(manzero, zero); - // exp >= 0 - HVX_Vector tsout1 = Q6_V_vmux_QVV(issignpos, exppos_signpos, exppos_signneg); - tsout1 = Q6_V_vmux_QVV(maneqzero, sout2, tsout1); + HVX_Vector exppos_signneg = Q6_Vh_vadd_VhVh(sout1, man); + man = Q6_V_vnot_V(man); + HVX_Vector exppos_signpos = Q6_V_vand_VV(sout1, man); + exppos_signneg = Q6_V_vand_VV(exppos_signneg, man); + HVX_Vector shift1 = Q6_Vh_vasl_VhR(sout1, 1); + HVX_Vector iszero = Q6_Q_vcmp_eq_VhVh(shift1, zero); - // exp < 0 (-1, 1) - HVX_Vector tsout2 = Q6_V_vmux_QVV(iszero, sout2, negone); - tsout2 = Q6_V_vmux_QVV(issignpos, zero, tsout2); + // exp >= 0 + HVX_Vector tsout1 = Q6_V_vmux_QVV(issignpos, exppos_signpos, exppos_signneg); + tsout1 = Q6_V_vmux_QVV(maneqzero, sout1, tsout1); - tsout1 = Q6_V_vmux_QVV(expgte0, tsout1, tsout2); - sout2 = Q6_V_vmux_QVV(expgte23, sout2, tsout1); - } + // exp < 0 (-1, 1) + HVX_Vector tsout2 = Q6_V_vmux_QVV(iszero, sout1, negone); + tsout2 = Q6_V_vmux_QVV(issignpos, zero, tsout2); + + tsout1 = Q6_V_vmux_QVV(expgte0, tsout1, tsout2); + sout1 = Q6_V_vmux_QVV(expgte23, sout1, tsout1); + } - sout2 = Q6_Vh_equals_Vhf(sout2); + sout1 = Q6_Vh_equals_Vhf(sout1); - HVX_Vector reql_h = Q6_Vb_vpack_VhVh_sat(sout2, sout1); - *optr++ = Q6_Vb_vadd_VbVb(reql_h, uintconvert); + HVX_Vector sout2 = Q6_Vqf16_vmpy_VhfVhf(sline_high, o_scale_vec); + sout2 = Q6_Vqf16_vadd_Vqf16Vqf16(sout2, es_vec); + sout2 = Q6_Vhf_equals_Vqf16(sout2); + sout2 = Q6_Vhf_vmin_VhfVhf(sout2, high_level_vec); + sout2 = Q6_Vhf_vmax_VhfVhf(sout2, low_level_vec); + + { + HVX_Vector exp = Q6_Vh_vasr_VhR(sout2, FP16_MANTISA); + exp = Q6_V_vand_VV(exp, expmask); + exp = Q6_Vh_vsub_VhVh(exp, expbias); - } + HVX_Vector man = Q6_Vh_vasr_VhVh(manmask, exp); + HVX_Vector manzero = Q6_V_vand_VV(sout2, man); + HVX_Vector sign = Q6_Vh_vasr_VhR(sout2, FP16_SIGN); + HVX_Vector issignpos = Q6_Q_vcmp_eq_VhVh(sign, zero); + + HVX_Vector expgte23 = Q6_Q_vcmp_gt_VhVh(exp, exp23); + HVX_Vector expgte0 = Q6_Q_vcmp_gt_VhVh(exp, exp0); + HVX_Vector maneqzero = Q6_Q_vcmp_eq_VhVh(manzero, zero); + + HVX_Vector exppos_signneg = Q6_Vh_vadd_VhVh(sout2, man); + man = Q6_V_vnot_V(man); + HVX_Vector exppos_signpos = Q6_V_vand_VV(sout2, man); + exppos_signneg = Q6_V_vand_VV(exppos_signneg, man); + HVX_Vector shift1 = Q6_Vh_vasl_VhR(sout2, 1); + HVX_Vector iszero = Q6_Q_vcmp_eq_VhVh(shift1, zero); + + // exp >= 0 + HVX_Vector tsout1 = Q6_V_vmux_QVV(issignpos, exppos_signpos, exppos_signneg); + tsout1 = Q6_V_vmux_QVV(maneqzero, sout2, tsout1); + + // exp < 0 (-1, 1) + HVX_Vector tsout2 = Q6_V_vmux_QVV(iszero, sout2, negone); + tsout2 = Q6_V_vmux_QVV(issignpos, zero, tsout2); + + tsout1 = Q6_V_vmux_QVV(expgte0, tsout1, tsout2); + sout2 = Q6_V_vmux_QVV(expgte23, sout2, tsout1); + } + + sout2 = Q6_Vh_equals_Vhf(sout2); + + HVX_Vector reql_h = Q6_Vb_vpack_VhVh_sat(sout2, sout1); + *optr++ = Q6_Vb_vadd_VbVb(reql_h, uintconvert); + } } // // Handle leftover elements. @@ -1013,7 +1120,6 @@ int32_t hvx_supersilu_ahf( // : *iptr++); // sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - // sline2c = (is_in_one_chunk(iptr2, leftover_size, VLEN) // ? sline2p // : *iptr2++); @@ -1025,146 +1131,131 @@ int32_t hvx_supersilu_ahf( return 0; } - -template -GraphStatus llamasupersiluImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const PlainFloatTensor& a_scale, - const PlainFloatTensor& b_scale, - const PlainFloatTensor& o_scale) +template +GraphStatus llamasupersiluImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const PlainFloatTensor &a_scale, + const PlainFloatTensor &b_scale, + const PlainFloatTensor &o_scale) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - out_0.set_dims(in_0); - - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - size_t size = b_in*h_in*w_in*d_in; - - - float a_scale_ = a_scale(0,0,0,0); - float b_scale_ = b_scale(0,0,0,0); - float o_scale_ = o_scale(0,0,0,0); - - auto in_ptr = (uint8_t*)in_0.raw_data_const(); - auto in_ptr2 = (uint8_t*)in_1.raw_data_const(); - - auto out_ptr = (uint8_t*)out_0.raw_data(); + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + out_0.set_dims(in_0); + + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + size_t size = b_in * h_in * w_in * d_in; + float a_scale_ = a_scale(0, 0, 0, 0); + float b_scale_ = b_scale(0, 0, 0, 0); + float o_scale_ = o_scale(0, 0, 0, 0); + + auto in_ptr = (uint8_t *)in_0.raw_data_const(); + auto in_ptr2 = (uint8_t *)in_1.raw_data_const(); + + auto out_ptr = (uint8_t *)out_0.raw_data(); DType dtype = in_0.get_dtype(); - if (dtype == DType::QUInt8 && out_0.get_dtype() == DType::QUInt8) { - hvx_supersilu_ahf(in_ptr, in_ptr2, out_ptr, a_scale_, b_scale_, 1.0f/o_scale_, size); - } + if (dtype == DType::QUInt8 && out_0.get_dtype() == DType::QUInt8) { + hvx_supersilu_ahf(in_ptr, in_ptr2, out_ptr, a_scale_, b_scale_, 1.0f / o_scale_, size); + } - return GraphStatus::Success; + return GraphStatus::Success; } #else -template -GraphStatus llamasupersiluImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const PlainFloatTensor& a_scale, - const PlainFloatTensor& b_scale, - const PlainFloatTensor& o_scale) +template +GraphStatus llamasupersiluImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const PlainFloatTensor &a_scale, + const PlainFloatTensor &b_scale, + const PlainFloatTensor &o_scale) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - out_0.set_dims(in_0); + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ - float a_scale_ = a_scale(0,0,0,0); - float b_scale_ = b_scale(0,0,0,0); - float o_scale_ = o_scale(0,0,0,0); + out_0.set_dims(in_0); - auto in_ptr = (uint8_t*)in_0.raw_data_const(); - auto in_ptr2 = (uint8_t*)in_1.raw_data_const(); + float a_scale_ = a_scale(0, 0, 0, 0); + float b_scale_ = b_scale(0, 0, 0, 0); + float o_scale_ = o_scale(0, 0, 0, 0); - auto out_ptr = (uint8_t*)out_0.raw_data(); + auto in_ptr = (uint8_t *)in_0.raw_data_const(); + auto in_ptr2 = (uint8_t *)in_1.raw_data_const(); + auto out_ptr = (uint8_t *)out_0.raw_data(); - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // mul - for (Idx d = 0; d < d_in; d++) { + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // mul + for (Idx d = 0; d < d_in; d++) { + int32_t a_inval = static_cast(*in_ptr++); + float a_inval_fp16 = (a_inval - 128) * a_scale_; + int32_t b_inval = static_cast(*in_ptr2++); + float b_inval_fp16 = (b_inval - 128) * b_scale_; - int32_t a_inval = static_cast(*in_ptr++); - float a_inval_fp16 = (a_inval-128) * a_scale_; + a_inval_fp16 = a_inval_fp16 * (1 / (1 + expf(-a_inval_fp16))); + float inval = a_inval_fp16 * b_inval_fp16; - int32_t b_inval = static_cast(*in_ptr2++); - float b_inval_fp16 = (b_inval-128) * b_scale_; + long v = lroundf(inval / o_scale_); - - a_inval_fp16 = a_inval_fp16 * (1 / (1 + expf(-a_inval_fp16))); + if (v > 127) + v = 127; - float inval = a_inval_fp16 * b_inval_fp16; - - long v = lroundf(inval / o_scale_); - - if (v > 127) - v = 127; - - if (v < -128) - v = -128; - - v += 128; + if (v < -128) + v = -128; - *out_ptr++ = static_cast(v); + v += 128; + *out_ptr++ = static_cast(v); + } + } } - } } - } - - return GraphStatus::Success; + return GraphStatus::Success; } #endif -__attribute__((unused)) static float llamasupersiluCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float llamasupersiluCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/MergeOutput.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/MergeOutput.cpp index 6c573ab2d..e001c4e3e 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/MergeOutput.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/MergeOutput.cpp @@ -9,18 +9,16 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_MergeOutput); - // op execute function declarations -template -GraphStatus mergeoutputImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const TensorType& in_2, - const TensorType& in_3, - const Tensor& num); +template +GraphStatus mergeoutputImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const TensorType &in_2, + const TensorType &in_3, + const Tensor &num); // forward declaration of sample cost function static float mergeoutputCostFunc(const Op *op); @@ -65,11 +63,11 @@ DEF_PACKAGE_OP((mergeoutputImpl), "MergeOutput") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -83,90 +81,81 @@ DEF_PACKAGE_OP((mergeoutputImpl), "MergeOutput") * Qnn_addNode */ - /* execute functions for ops */ -template -GraphStatus mergeoutputImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& in_1, - const TensorType& in_2, - const TensorType& in_3, - const Tensor& num) +template +GraphStatus mergeoutputImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &in_1, + const TensorType &in_2, + const TensorType &in_3, + const Tensor &num) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - auto [b_in_0, h_in_0, w_in_0, d_in_0] = in_0.dims(); - auto [b_in_1, h_in_1, w_in_1, d_in_1] = in_1.dims(); - auto [b_in_2, h_in_2, w_in_2, d_in_2] = in_2.dims(); - auto [b_in_3, h_in_3, w_in_3, d_in_3] = in_3.dims(); - - const size_t dims[] = {b_in_0, h_in_0 + h_in_1 + h_in_2 + h_in_3 * 4, w_in_0, d_in_0}; + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ - out_0.set_dims(dims); + auto [b_in_0, h_in_0, w_in_0, d_in_0] = in_0.dims(); + auto [b_in_1, h_in_1, w_in_1, d_in_1] = in_1.dims(); + auto [b_in_2, h_in_2, w_in_2, d_in_2] = in_2.dims(); + auto [b_in_3, h_in_3, w_in_3, d_in_3] = in_3.dims(); - DType dtype = in_0.get_dtype(); - uint32_t bitwidth = 4; + const size_t dims[] = {b_in_0, h_in_0 + h_in_1 + h_in_2 + h_in_3 * 4, w_in_0, d_in_0}; - if (dtype == DType::QUInt8 || dtype == DType::QInt8) { + out_0.set_dims(dims); - bitwidth = 1; + DType dtype = in_0.get_dtype(); + uint32_t bitwidth = 4; - } else if (dtype == DType::Float16) { + if (dtype == DType::QUInt8 || dtype == DType::QInt8) { + bitwidth = 1; - bitwidth = 2; - } else if (dtype == DType::Float32) { + } else if (dtype == DType::Float16) { + bitwidth = 2; + } else if (dtype == DType::Float32) { + bitwidth = 4; + } - bitwidth = 4; - } + const uint8_t *in_ptr_0 = (uint8_t *)in_0.raw_data_const(); + const uint8_t *in_ptr_1 = (uint8_t *)in_1.raw_data_const(); + const uint8_t *in_ptr_2 = (uint8_t *)in_2.raw_data_const(); + // const uint8_t *in_ptr_3 = (uint8_t*)in_3.raw_data_const(); - const uint8_t *in_ptr_0 = (uint8_t*)in_0.raw_data_const(); - const uint8_t *in_ptr_1 = (uint8_t*)in_1.raw_data_const(); - const uint8_t *in_ptr_2 = (uint8_t*)in_2.raw_data_const(); -// const uint8_t *in_ptr_3 = (uint8_t*)in_3.raw_data_const(); - - uint8_t *out_ptr = (uint8_t*)out_0.raw_data(); + uint8_t *out_ptr = (uint8_t *)out_0.raw_data(); - memcpy(out_ptr, in_ptr_0, b_in_0 * h_in_0 * w_in_0 * d_in_0 * bitwidth); - out_ptr += b_in_0 * h_in_0 * w_in_0 * d_in_0 * bitwidth; + memcpy(out_ptr, in_ptr_0, b_in_0 * h_in_0 * w_in_0 * d_in_0 * bitwidth); + out_ptr += b_in_0 * h_in_0 * w_in_0 * d_in_0 * bitwidth; - memcpy(out_ptr, in_ptr_1, b_in_1 * h_in_1 * w_in_1 * d_in_1 * bitwidth); - out_ptr += b_in_1 * h_in_1 * w_in_1 * d_in_1 * bitwidth; + memcpy(out_ptr, in_ptr_1, b_in_1 * h_in_1 * w_in_1 * d_in_1 * bitwidth); + out_ptr += b_in_1 * h_in_1 * w_in_1 * d_in_1 * bitwidth; - memcpy(out_ptr, in_ptr_2, b_in_2 * h_in_2 * w_in_2 * d_in_2 * bitwidth); - out_ptr += b_in_2 * h_in_2 * w_in_2 * d_in_2 * bitwidth; + memcpy(out_ptr, in_ptr_2, b_in_2 * h_in_2 * w_in_2 * d_in_2 * bitwidth); + out_ptr += b_in_2 * h_in_2 * w_in_2 * d_in_2 * bitwidth; -// memcpy(out_ptr, in_ptr_3, b_in_3 * h_in_3 * w_in_3 * d_in_3 * bitwidth * 4); + // memcpy(out_ptr, in_ptr_3, b_in_3 * h_in_3 * w_in_3 * d_in_3 * bitwidth * 4); - return GraphStatus::Success; + return GraphStatus::Success; } -__attribute__((unused)) static float mergeoutputCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float mergeoutputCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/QLayerNorm.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/QLayerNorm.cpp index 0bb733e4f..be61c7286 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/QLayerNorm.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/QLayerNorm.cpp @@ -9,16 +9,14 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_QLayerNorm); - // op execute function declarations -template -GraphStatus qlayernormImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& weights, - const TensorType& bias); +template +GraphStatus qlayernormImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &weights, + const TensorType &bias); // forward declaration of sample cost function static float qlayernormCostFunc(const Op *op); @@ -63,11 +61,11 @@ DEF_PACKAGE_OP((qlayernormImpl), "QLayerNorm") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -81,7 +79,6 @@ DEF_PACKAGE_OP((qlayernormImpl), "QLayerNorm") * Qnn_addNode */ - /* execute functions for ops */ #ifndef REFERENCE_OP @@ -90,18 +87,16 @@ DEF_PACKAGE_OP((qlayernormImpl), "QLayerNorm") #include #include -#define BLOCK_SIZE (8*1024/VLEN) /* vector chunks */ -#define L2FETCH_AHEAD (BLOCK_SIZE) +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) int32_t hvx_qlayernorm_af( float *restrict input, float *restrict weights, float *restrict bias, float *restrict output, - uint32_t size) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + uint32_t size) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -125,58 +120,47 @@ int32_t hvx_qlayernorm_af( // sline1p = *iptr++; - // x sum HVX_Vector xsum = Q6_Vqf32_vadd_VsfVsf(Q6_V_vzero(), Q6_V_vzero()); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - xsum = Q6_Vqf32_vadd_Vqf32Vqf32(xsum, sline1); - + xsum = Q6_Vqf32_vadd_Vqf32Vqf32(xsum, sline1); sline1p = sline1c; } } if (vectors_in_rounddown > 0) { - - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - xsum = Q6_Vqf32_vadd_Vqf32Vqf32(xsum, sline1); - + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + xsum = Q6_Vqf32_vadd_Vqf32Vqf32(xsum, sline1); } union { - float f; - uint32_t ui; + float f; + uint32_t ui; } mean_value; mean_value.f = 0.0f; - - - for (int32_t i = 64; i >= 4; i >>= 1) - { + for (int32_t i = 64; i >= 4; i >>= 1) { xsum = Q6_Vqf32_vadd_Vqf32Vqf32(xsum, Q6_V_vlalign_VVR(xsum, zero, i)); } xsum = Q6_Vsf_equals_Vqf32(xsum); - *(HVX_Vector *) tmp_buf = xsum; + *(HVX_Vector *)tmp_buf = xsum; mean_value.f = xsum[31] / size; - // x-e^2 sum iptr = (HVX_Vector *)input; sline1p = *iptr++; @@ -185,57 +169,49 @@ int32_t hvx_qlayernorm_af( HVX_Vector mean_vsf = Q6_V_vsplat_R(mean_value.ui); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); sline1 = Q6_Vqf32_vsub_Vqf32Vqf32(sline1, mean_vsf); - x2sum = Q6_Vqf32_vadd_Vqf32Vqf32(x2sum, Q6_Vqf32_vmpy_Vqf32Vqf32(sline1, sline1)); - + x2sum = Q6_Vqf32_vadd_Vqf32Vqf32(x2sum, Q6_Vqf32_vmpy_Vqf32Vqf32(sline1, sline1)); + sline1p = sline1c; } } if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - - sline1 = Q6_Vqf32_vsub_Vqf32Vqf32(sline1, mean_vsf); - x2sum = Q6_Vqf32_vadd_Vqf32Vqf32(x2sum, Q6_Vqf32_vmpy_Vqf32Vqf32(sline1, sline1)); + sline1 = Q6_Vqf32_vsub_Vqf32Vqf32(sline1, mean_vsf); + x2sum = Q6_Vqf32_vadd_Vqf32Vqf32(x2sum, Q6_Vqf32_vmpy_Vqf32Vqf32(sline1, sline1)); } float epsilon_ = 1e-5; union { - float f; - uint32_t ui; + float f; + uint32_t ui; } sum_value; sum_value.f = 0.0f; - - - for (int32_t i = 64; i >= 4; i >>= 1) - { + for (int32_t i = 64; i >= 4; i >>= 1) { x2sum = Q6_Vqf32_vadd_Vqf32Vqf32(x2sum, Q6_V_vlalign_VVR(x2sum, zero, i)); } x2sum = Q6_Vsf_equals_Vqf32(x2sum); - *(HVX_Vector *) tmp_buf = x2sum; + *(HVX_Vector *)tmp_buf = x2sum; sum_value.f = 1.0f / sqrtf(x2sum[31] / size + epsilon_); - // x * 1/rsqrt(sum) iptr = (HVX_Vector *)input; sline1p = *iptr++; @@ -245,20 +221,17 @@ int32_t hvx_qlayernorm_af( HVX_Vector irsqrt_vsf = Q6_V_vsplat_R(sum_value.ui); HVX_Vector irsqrt_vqf32 = Q6_Vqf32_vadd_VsfVsf(irsqrt_vsf, Q6_V_vzero()); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr3 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline2c = *iptr2++; sline3c = *iptr3++; @@ -281,107 +254,97 @@ int32_t hvx_qlayernorm_af( } if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - - sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) weights); + sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)weights); - sline3c = is_aligned(iptr3, VLEN) && leftover == 0 ? sline3p : *iptr3++; - sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t) weights); + sline3c = is_aligned(iptr3, VLEN) && leftover == 0 ? sline3p : *iptr3++; + sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t)weights); - sline1 = Q6_Vqf32_vsub_VsfVsf(sline1, mean_vsf); + sline1 = Q6_Vqf32_vsub_VsfVsf(sline1, mean_vsf); - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline1, sline2); - middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); - middle_value_qf32 = Q6_Vqf32_vadd_Vqf32Vqf32(middle_value_qf32, sline3); - - *optr++ = Q6_Vsf_equals_Vqf32(middle_value_qf32); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline1, sline2); + middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); + middle_value_qf32 = Q6_Vqf32_vadd_Vqf32Vqf32(middle_value_qf32, sline3); + *optr++ = Q6_Vsf_equals_Vqf32(middle_value_qf32); } - if (leftover_size > 0) - return -1; + return -1; return 0; } -template -GraphStatus qlayernormImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& weights, - const TensorType& bias) +template +GraphStatus qlayernormImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &weights, + const TensorType &bias) { - out_0.set_dims(in_0); - - // NHWC - - auto in_ptr = (float*)in_0.raw_data_const(); - auto out_ptr = (float*)out_0.raw_data(); - auto weights_ptr = (float*)weights.raw_data_const(); - auto bias_ptr = (float*)bias.raw_data_const(); - - - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // RMS - hvx_qlayernorm_af(in_ptr, weights_ptr, bias_ptr, out_ptr, d_in); - - in_ptr += d_in; - out_ptr += d_in; - } + out_0.set_dims(in_0); + + // NHWC + + auto in_ptr = (float *)in_0.raw_data_const(); + auto out_ptr = (float *)out_0.raw_data(); + auto weights_ptr = (float *)weights.raw_data_const(); + auto bias_ptr = (float *)bias.raw_data_const(); + + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // RMS + hvx_qlayernorm_af(in_ptr, weights_ptr, bias_ptr, out_ptr, d_in); + + in_ptr += d_in; + out_ptr += d_in; + } + } } - } - return GraphStatus::Success; + return GraphStatus::Success; } #else -template -GraphStatus qlayernormImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& weights, - const TensorType& bias) +template +GraphStatus qlayernormImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &weights, + const TensorType &bias) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - return GraphStatus::Success; + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + return GraphStatus::Success; } #endif -__attribute__((unused)) static float qlayernormCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float qlayernormCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/RMSNorm.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/RMSNorm.cpp index bd079a2c9..1197eab19 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/RMSNorm.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/RMSNorm.cpp @@ -9,15 +9,13 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_RMSNorm); - // op execute function declarations -template -GraphStatus rmsnormImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& weights); +template +GraphStatus rmsnormImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &weights); // forward declaration of sample cost function static float rmsnormCostFunc(const Op *op); @@ -62,11 +60,11 @@ DEF_PACKAGE_OP((rmsnormImpl), "RMSNorm") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -80,7 +78,6 @@ DEF_PACKAGE_OP((rmsnormImpl), "RMSNorm") * Qnn_addNode */ - /* execute functions for ops */ #ifndef REFERENCE_OP @@ -90,17 +87,15 @@ DEF_PACKAGE_OP((rmsnormImpl), "RMSNorm") #include #include -#define BLOCK_SIZE (8*1024/VLEN) /* vector chunks */ -#define L2FETCH_AHEAD (BLOCK_SIZE) +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) int32_t hvx_rmsnorm_af( float *restrict input, float *restrict weights, float *restrict output, - uint32_t size) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + uint32_t size) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -117,56 +112,47 @@ int32_t hvx_rmsnorm_af( sline1p = *iptr++; - // ^2 sum HVX_Vector sum = Q6_Vqf32_vadd_VsfVsf(Q6_V_vzero(), Q6_V_vzero()); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); - + sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); sline1p = sline1c; } } if (vectors_in_rounddown > 0) { - - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); - + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); } float epsilon_ = 1e-6; union { - float f; - uint32_t ui; + float f; + uint32_t ui; } sum_value; sum_value.f = 0.0f; - HVX_Vector zero = Q6_V_vzero(); - for (int32_t i = 64; i >= 4; i >>= 1) - { + for (int32_t i = 64; i >= 4; i >>= 1) { sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_V_vlalign_VVR(sum, zero, i)); } sum = Q6_Vsf_equals_Vqf32(sum); - sum_value.f = 1.0f / sqrtf(*((float*)&sum + 31) / size + epsilon_); + sum_value.f = 1.0f / sqrtf(*((float *)&sum + 31) / size + epsilon_); // x * 1/rsqrt(sum) iptr = (HVX_Vector *)input; @@ -176,19 +162,16 @@ int32_t hvx_rmsnorm_af( HVX_Vector irsqrt_vsf = Q6_V_vsplat_R(sum_value.ui); HVX_Vector irsqrt_vqf32 = Q6_Vqf32_vadd_VsfVsf(irsqrt_vsf, Q6_V_vzero()); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline2c = *iptr2++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); @@ -203,33 +186,31 @@ int32_t hvx_rmsnorm_af( } if (vectors_in_rounddown > 0) { + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - - sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t) weights); - - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, sline2); - *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32)); + sline2c = is_aligned(iptr2, VLEN) && leftover == 0 ? sline2p : *iptr2++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)weights); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, sline2); + *optr++ = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32)); } - if (leftover_size > 0) - return -1; + return -1; return 0; } -static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) -{ - union { float f; uint32_t i; } fp32 = { .f = x }; +static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) { + union { + float f; + uint32_t i; + } fp32 = {.f = x}; return fp32.i; } -static inline int32_t float_to_fp16s(float input) -{ +static inline int32_t float_to_fp16s(float input) { union { int32_t i; __fp16 f[2]; @@ -237,7 +218,6 @@ static inline int32_t float_to_fp16s(float input) return fp32.i; } - #define FLOAT_MANTISA 23 #define FLOAT_EXPONENT_MASK 0xff #define FLOAT_EXPONENT_BIAS 0x7f @@ -252,10 +232,8 @@ int32_t hvx_rmsnorm_auint8( float *restrict weights, uint8_t *restrict output, uint32_t size, - float scale) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -274,7 +252,7 @@ int32_t hvx_rmsnorm_auint8( float low_level = -128.0f; float high_level = 127.0f; - float es = 0.5f; + float es = 0.5f; low_level_vec = Q6_V_vsplat_R(float_to_bits(low_level)); high_level_vec = Q6_V_vsplat_R(float_to_bits(high_level)); scale_vec = Q6_V_vsplat_R(float_to_bits(scale)); @@ -287,7 +265,6 @@ int32_t hvx_rmsnorm_auint8( HVX_Vector uintconvert = Q6_V_vsplat_R(0x80808080); - // HVX_Vector expmask = Q6_V_vsplat_R(FLOAT_EXPONENT_MASK); // HVX_Vector expbias = Q6_V_vsplat_R(FLOAT_EXPONENT_BIAS); // HVX_Vector manmask = Q6_V_vsplat_R(FLOAT_MANTISA_MASK); @@ -303,53 +280,45 @@ int32_t hvx_rmsnorm_auint8( sline1p = *iptr++; - // ^2 sum HVX_Vector sum = Q6_Vqf32_vadd_VsfVsf(Q6_V_vzero(), Q6_V_vzero()); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); - + sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); sline1p = sline1c; } } if (vectors_in_rounddown > 0) { - - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); - + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); } float epsilon_ = 1e-6; union { - float f; - uint32_t ui; + float f; + uint32_t ui; } sum_value; sum_value.f = 0.0f; - for (int32_t i = 64; i >= 4; i >>= 1) - { + for (int32_t i = 64; i >= 4; i >>= 1) { sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_V_vlalign_VVR(sum, zero, i)); } sum = Q6_Vsf_equals_Vqf32(sum); - sum_value.f = 1.0f / sqrtf(*((float*)&sum + 31) / size + epsilon_); + sum_value.f = 1.0f / sqrtf(*((float *)&sum + 31) / size + epsilon_); // x * 1/rsqrt(sum) iptr = (HVX_Vector *)input; @@ -361,37 +330,32 @@ int32_t hvx_rmsnorm_auint8( slinewp = *iptr2++; - HVX_Vector irsqrt_vsf = Q6_V_vsplat_R(sum_value.ui); HVX_Vector irsqrt_vqf32 = Q6_Vqf32_vadd_VsfVsf(irsqrt_vsf, Q6_V_vzero()); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; j+=4) - { - + for (int32_t j = 0; j < block; j += 4) { { - sline1c = *iptr++; - slinewc = *iptr2++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); + sline1c = *iptr++; + slinewc = *iptr2++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, slinew); - sline1 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, slinew); + sline1 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); - slinewp = slinewc; + slinewp = slinewc; } - - sout1 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline1,scale_vec); + + sout1 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline1, scale_vec); sout1 = Q6_Vqf32_vadd_Vqf32Vqf32(sout1, es_vec); sout1 = Q6_Vsf_equals_Vqf32(sout1); sout1 = Q6_Vsf_vmin_VsfVsf(sout1, high_level_vec); @@ -438,19 +402,18 @@ int32_t hvx_rmsnorm_auint8( // sout1 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout1, Q6_V_vzero()), 0); { - sline2c = *iptr++; - slinewc = *iptr2++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); - slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); + sline2c = *iptr++; + slinewc = *iptr2++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); + slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline2, slinew); - sline2 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline2, slinew); + sline2 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); - slinewp = slinewc; + slinewp = slinewc; } - - sout2 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline2,scale_vec); + sout2 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline2, scale_vec); sout2 = Q6_Vqf32_vadd_Vqf32Vqf32(sout2, es_vec); sout2 = Q6_Vsf_equals_Vqf32(sout2); sout2 = Q6_Vsf_vmin_VsfVsf(sout2, high_level_vec); @@ -497,19 +460,18 @@ int32_t hvx_rmsnorm_auint8( // sout2 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout2, Q6_V_vzero()), 0); { - sline3c = *iptr++; - slinewc = *iptr2++; - sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t) input); - slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); + sline3c = *iptr++; + slinewc = *iptr2++; + sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t)input); + slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline3, slinew); - sline3 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline3, slinew); + sline3 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); - slinewp = slinewc; + slinewp = slinewc; } - - sout3 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline3,scale_vec); + sout3 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline3, scale_vec); sout3 = Q6_Vqf32_vadd_Vqf32Vqf32(sout3, es_vec); sout3 = Q6_Vsf_equals_Vqf32(sout3); sout3 = Q6_Vsf_vmin_VsfVsf(sout3, high_level_vec); @@ -551,25 +513,23 @@ int32_t hvx_rmsnorm_auint8( // sout3 = Q6_V_vmux_QVV(expgte23, sout3, tsout1); // } - sout3 = Q6_Vw_equals_Vsf(sout3); sout3 = Q6_Vw_vasr_VwR(sout3, ROUND_2_SCALE); // sout3 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout3, Q6_V_vzero()), 0); { - sline4c = *iptr++; - slinewc = *iptr2++; - sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t) input); - slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); + sline4c = *iptr++; + slinewc = *iptr2++; + sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t)input); + slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline4, slinew); - sline4 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline4, slinew); + sline4 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); - slinewp = slinewc; + slinewp = slinewc; } - - sout4 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline4,scale_vec); + sout4 = Q6_Vqf32_vmpy_Vqf32Vqf32(sline4, scale_vec); sout4 = Q6_Vqf32_vadd_Vqf32Vqf32(sout4, es_vec); sout4 = Q6_Vsf_equals_Vqf32(sout4); sout4 = Q6_Vsf_vmin_VsfVsf(sout4, high_level_vec); @@ -615,7 +575,6 @@ int32_t hvx_rmsnorm_auint8( sout4 = Q6_Vw_vasr_VwR(sout4, ROUND_2_SCALE); // sout4 = qhmath_hvx_vw_convert_vqf32_rmode(Q6_Vqf32_vadd_VsfVsf(sout4, Q6_V_vzero()), 0); - HVX_Vector reql_h = Q6_Vh_vpack_VwVw_sat(sout2, sout1); HVX_Vector reqh_h = Q6_Vh_vpack_VwVw_sat(sout4, sout3); HVX_Vector req_b = Q6_Vb_vpack_VhVh_sat(reqh_h, reql_h); @@ -627,9 +586,7 @@ int32_t hvx_rmsnorm_auint8( sline3p = sline3c; sline4p = sline4c; - slinewp = slinewc; - } } @@ -641,10 +598,8 @@ int32_t hvx_rmsnorm_auint8_opt( float *restrict weights, uint8_t *restrict output, uint32_t size, - float scale) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -663,7 +618,7 @@ int32_t hvx_rmsnorm_auint8_opt( // float low_level = -128.0f; // float high_level = 127.0f; - // float es = 0.5f; + // float es = 0.5f; // low_level_vec = Q6_V_vsplat_R(float_to_bits(low_level)); // high_level_vec = Q6_V_vsplat_R(float_to_bits(high_level)); // scale_vec = Q6_V_vsplat_R(float_to_bits(scale)); @@ -676,7 +631,6 @@ int32_t hvx_rmsnorm_auint8_opt( // HVX_Vector uintconvert = Q6_V_vsplat_R(0x80808080); - // HVX_Vector expmask = Q6_V_vsplat_R(FLOAT_EXPONENT_MASK); // HVX_Vector expbias = Q6_V_vsplat_R(FLOAT_EXPONENT_BIAS); // HVX_Vector manmask = Q6_V_vsplat_R(FLOAT_MANTISA_MASK); @@ -692,53 +646,45 @@ int32_t hvx_rmsnorm_auint8_opt( sline1p = *iptr++; - // ^2 sum HVX_Vector sum = Q6_Vqf32_vadd_VsfVsf(Q6_V_vzero(), Q6_V_vzero()); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { sline1c = *iptr++; sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); - + sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); sline1p = sline1c; } } if (vectors_in_rounddown > 0) { - - sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t) input); - sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); - + sline1c = is_aligned(iptr, VLEN) && leftover == 0 ? sline1p : *iptr++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_Vqf32_vmpy_VsfVsf(sline1, sline1)); } float epsilon_ = 1e-6; union { - float f; - uint32_t ui; + float f; + uint32_t ui; } sum_value; sum_value.f = 0.0f; - for (int32_t i = 64; i >= 4; i >>= 1) - { + for (int32_t i = 64; i >= 4; i >>= 1) { sum = Q6_Vqf32_vadd_Vqf32Vqf32(sum, Q6_V_vlalign_VVR(sum, zero, i)); } sum = Q6_Vsf_equals_Vqf32(sum); - sum_value.f = 1.0f / sqrtf(*((float*)&sum + 31) / size + epsilon_); + sum_value.f = 1.0f / sqrtf(*((float *)&sum + 31) / size + epsilon_); // x * 1/rsqrt(sum) iptr = (HVX_Vector *)input; @@ -750,66 +696,58 @@ int32_t hvx_rmsnorm_auint8_opt( slinewp = *iptr2++; - HVX_Vector irsqrt_vsf = Q6_V_vsplat_R(sum_value.ui); HVX_Vector irsqrt_vqf32 = Q6_Vqf32_vadd_VsfVsf(irsqrt_vsf, Q6_V_vzero()); - float post_scale_flt = scale / 64.0f; - int scexp = flt_getexp( post_scale_flt); - int rsh = min_i32( -scexp,7); // e.g. 0.11 -> 0.88, rsh = 3 + int scexp = flt_getexp(post_scale_flt); + int rsh = min_i32(-scexp, 7); // e.g. 0.11 -> 0.88, rsh = 3 float rsh_fac = flt_power2(rsh); int adj_bias = roundf_i32(128 * rsh_fac); - adj_bias = Q6_R_combine_RlRl( adj_bias, adj_bias); - + adj_bias = Q6_R_combine_RlRl(adj_bias, adj_bias); HVX_Vector zero_v_sf = Q6_V_vzero(); - float es = 0.5f; + float es = 0.5f; HVX_Vector es_vec = Q6_V_vsplat_R(float_to_fp16s(es)); es_vec = Q6_Vqf16_vadd_VhfVhf(es_vec, zero_v_sf); HVX_Vector vadj = Q6_V_vsplat_R(adj_bias); - HVX_Vector o_scale_vec = Q6_V_vsplat_R(float_to_fp16s(post_scale_flt * rsh_fac * (1<<15))); + HVX_Vector o_scale_vec = Q6_V_vsplat_R(float_to_fp16s(post_scale_flt * rsh_fac * (1 << 15))); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t j = 0; j < block; j+=4) - { - + for (int32_t j = 0; j < block; j += 4) { { - sline1c = *iptr++; - slinewc = *iptr2++; - sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); - slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); + sline1c = *iptr++; + slinewc = *iptr2++; + sline1 = Q6_V_valign_VVR(sline1c, sline1p, (size_t)input); + slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, slinew); - sline1 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, slinew); + sline1 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); - slinewp = slinewc; + slinewp = slinewc; } { - sline2c = *iptr++; - slinewc = *iptr2++; - sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); - slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); + sline2c = *iptr++; + slinewc = *iptr2++; + sline2 = Q6_V_valign_VVR(sline2c, sline2p, (size_t)input); + slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline2, slinew); - sline2 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline2, slinew); + sline2 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); - slinewp = slinewc; + slinewp = slinewc; } - HVX_Vector sline_low = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(sline2, sline1)); sline_low = Q6_Vqf16_vadd_Vqf16Vqf16(sline_low, es_vec); @@ -820,29 +758,28 @@ int32_t hvx_rmsnorm_auint8_opt( sline_low = Q6_Vh_vdeal_Vh(sline_low); { - sline3c = *iptr++; - slinewc = *iptr2++; - sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t) input); - slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); + sline3c = *iptr++; + slinewc = *iptr2++; + sline3 = Q6_V_valign_VVR(sline3c, sline3p, (size_t)input); + slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline3, slinew); - sline3 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline3, slinew); + sline3 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); - slinewp = slinewc; + slinewp = slinewc; } { - sline4c = *iptr++; - slinewc = *iptr2++; - sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t) input); - slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); + sline4c = *iptr++; + slinewc = *iptr2++; + sline4 = Q6_V_valign_VVR(sline4c, sline4p, (size_t)input); + slinew = Q6_V_valign_VVR(slinewc, slinewp, (size_t)weights); - HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline4, slinew); - sline4 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); + HVX_Vector middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline4, slinew); + sline4 = Q6_Vqf32_vmpy_Vqf32Vqf32(middle_value_qf32, irsqrt_vqf32); - slinewp = slinewc; + slinewp = slinewc; } - HVX_Vector sline_high = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(sline4, sline3)); sline_high = Q6_Vqf16_vadd_Vqf16Vqf16(sline_high, es_vec); @@ -852,7 +789,7 @@ int32_t hvx_rmsnorm_auint8_opt( sline_high = Q6_Vh_vdeal_Vh(sline_high); - HVX_Vector sout = Q6_Vub_vasr_VhVhR_rnd_sat( sline_high, sline_low, rsh); + HVX_Vector sout = Q6_Vub_vasr_VhVhR_rnd_sat(sline_high, sline_low, rsh); sout = Q6_Vb_vdeal_Vb(sout); *optr++ = sout; @@ -861,149 +798,132 @@ int32_t hvx_rmsnorm_auint8_opt( sline3p = sline3c; sline4p = sline4c; - slinewp = slinewc; - } } return 0; } -template -GraphStatus rmsnormImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& weights) +template +GraphStatus rmsnormImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &weights) { - out_0.set_dims(in_0); - - // NHWC + out_0.set_dims(in_0); - auto in_ptr = (float*)in_0.raw_data_const(); - auto weights_ptr = (float*)weights.raw_data_const(); + // NHWC + auto in_ptr = (float *)in_0.raw_data_const(); + auto weights_ptr = (float *)weights.raw_data_const(); - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - + auto [b_in, h_in, w_in, d_in] = in_0.dims(); - DType dtype = out_0.get_dtype(); + DType dtype = out_0.get_dtype(); - if (dtype == DType::Float32) { + if (dtype == DType::Float32) { + auto out_ptr = (float *)out_0.raw_data(); - auto out_ptr = (float*)out_0.raw_data(); + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // RMS + hvx_rmsnorm_af(in_ptr, weights_ptr, out_ptr, d_in); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // RMS - hvx_rmsnorm_af(in_ptr, weights_ptr, out_ptr, d_in); - - in_ptr += d_in; - out_ptr += d_in; + in_ptr += d_in; + out_ptr += d_in; + } + } } - } - } - } else if (dtype == DType::QUInt8) { + } else if (dtype == DType::QUInt8) { + auto out_ptr = (uint8_t *)out_0.raw_data(); + float scale_ = out_0.get_interface_scale(); - auto out_ptr = (uint8_t*)out_0.raw_data(); - float scale_ = out_0.get_interface_scale(); + scale_ = 1.0f / scale_; - scale_ = 1.0f/scale_; + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // RMS + hvx_rmsnorm_auint8(in_ptr, weights_ptr, out_ptr, d_in, scale_); - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // RMS - hvx_rmsnorm_auint8(in_ptr, weights_ptr, out_ptr, d_in, scale_); - - in_ptr += d_in; - out_ptr += d_in; + in_ptr += d_in; + out_ptr += d_in; + } + } } - } } - } - - return GraphStatus::Success; + return GraphStatus::Success; } #else -template -GraphStatus rmsnormImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& weights) +template +GraphStatus rmsnormImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &weights) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - out_0.set_dims(in_0); + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + out_0.set_dims(in_0); // NHWC float epsilon_ = 1e-6; auto [b_in, h_in, w_in, d_in] = in_0.dims(); for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // RMS - float sum_squares = 0.0f; - for (Idx d = 0; d < d_in; d++) { - float inval = in_0(b, h, w, d); - sum_squares += inval*inval; - } - - // debuglog("silu execute... sum_squares=(%f)", sum_squares); - - float rms = sqrtf(sum_squares / d_in + epsilon_); - debuglog("rms execute... sum_squares=(%f)", 1.0f / rms); - debuglog("rms execute... sum_squares=(%f)", sum_squares); - - for (Idx d = 0; d < d_in; d++) { - float inval = in_0(b, h, w, d); - float weight = weights(0, 0, 0, d); - - out_0(b, h, w, d) = inval * weight / rms; - - } - + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // RMS + float sum_squares = 0.0f; + for (Idx d = 0; d < d_in; d++) { + float inval = in_0(b, h, w, d); + sum_squares += inval * inval; + } + + // debuglog("silu execute... sum_squares=(%f)", sum_squares); + + float rms = sqrtf(sum_squares / d_in + epsilon_); + debuglog("rms execute... sum_squares=(%f)", 1.0f / rms); + debuglog("rms execute... sum_squares=(%f)", sum_squares); + + for (Idx d = 0; d < d_in; d++) { + float inval = in_0(b, h, w, d); + float weight = weights(0, 0, 0, d); + + out_0(b, h, w, d) = inval * weight / rms; + } + } } - } } - - - return GraphStatus::Success; + return GraphStatus::Success; } #endif +__attribute__((unused)) static float rmsnormCostFunc(const Op *op) { + /* + * add code here + * */ -__attribute__((unused)) static float rmsnormCostFunc(const Op *op) -{ - /* - * add code here - * */ - - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/RoPE.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/RoPE.cpp index 3aaeccf00..ac36798cc 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/RoPE.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/RoPE.cpp @@ -9,19 +9,16 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_RoPE); - // op execute function declarations -template -GraphStatus ropeImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& sin, - const TensorType& cos, +template +GraphStatus ropeImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &sin, + const TensorType &cos, const TensorType1 &h_cnt, - const Tensor& pose_type); - + const Tensor &pose_type); // forward declaration of sample cost function static float ropeCostFunc(const Op *op); @@ -66,11 +63,11 @@ DEF_PACKAGE_OP((ropeImpl), "RoPE") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -83,12 +80,11 @@ DEF_PACKAGE_OP((ropeImpl), "RoPE") * graph construction will skip this parameter when this parameter is not provided at * Qnn_addNode */ -DEF_PACKAGE_PARAM_ORDER("RoPE", +DEF_PACKAGE_PARAM_ORDER("RoPE", "pose_type", true, nullptr) - /* execute functions for ops */ #ifndef REFERENCE_OP @@ -98,10 +94,10 @@ DEF_PACKAGE_PARAM_ORDER("RoPE", #include #include -#define BLOCK_SIZE (8*1024/VLEN) /* vector chunks */ -#define L2FETCH_AHEAD (BLOCK_SIZE) -#define ONE 0x3F800000 -#define M_ONE 0xAF800000 +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) +#define ONE 0x3F800000 +#define M_ONE 0xAF800000 int32_t hvx_rope_af( float *restrict input, @@ -109,19 +105,18 @@ int32_t hvx_rope_af( float *restrict cos, float *restrict output, uint32_t size, - uint32_t partial_dimension) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + uint32_t partial_dimension) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } HVX_Vector *iptr = (HVX_Vector *)input; - HVX_Vector *iptr_half = (HVX_Vector *)(input + partial_dimension/2); + HVX_Vector *iptr_half = (HVX_Vector *)(input + partial_dimension / 2); HVX_Vector *iptr2 = (HVX_Vector *)sin; HVX_Vector *iptr3 = (HVX_Vector *)cos; HVX_UVector *optr = (HVX_UVector *)output; - HVX_UVector *optr_half = (HVX_UVector *)(output + partial_dimension/2);; + HVX_UVector *optr_half = (HVX_UVector *)(output + partial_dimension / 2); + ; HVX_Vector sline1; HVX_Vector sline1_half; HVX_Vector sinline1p, sinline1c, sinline1; @@ -135,63 +130,53 @@ int32_t hvx_rope_af( sinline1p = *iptr2++; cosline1p = *iptr3++; - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr3 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t d = 0; d < partial_dimension/2; d+=32) { - cosline1c = *iptr3++; - cosline1 = Q6_V_valign_VVR(cosline1c, cosline1p, (size_t)cos); - cosline1p = cosline1c; - - sinline1c = *iptr2++; - sinline1 = Q6_V_valign_VVR(sinline1c, sinline1p, (size_t)sin); - sinline1p = sinline1c; - - - HVX_Vector *jiptr = iptr + d/32; - HVX_Vector *jiptr_half = iptr_half + d/32; - HVX_Vector *joptr = optr + d/32; - HVX_Vector *joptr_half = optr_half + d/32; - - for (int32_t j = 0; j < size/partial_dimension; j++) - { - sline1 = *jiptr; - sline1_half = *jiptr_half; - - // auto value = in_value * cos_value - in_value_2 * sin_value; - { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, cosline1); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1_half, sinline1); - *joptr = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); - } - - - - // auto value2 = in_value * sin_value + in_value_2 * cos_value; - { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1_half, cosline1); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, sinline1); - *joptr_half = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); - } - - jiptr += partial_dimension/32; - jiptr_half += partial_dimension/32; - joptr += partial_dimension/32; - joptr_half += partial_dimension/32; - - } - - + for (int32_t d = 0; d < partial_dimension / 2; d += 32) { + cosline1c = *iptr3++; + cosline1 = Q6_V_valign_VVR(cosline1c, cosline1p, (size_t)cos); + cosline1p = cosline1c; + + sinline1c = *iptr2++; + sinline1 = Q6_V_valign_VVR(sinline1c, sinline1p, (size_t)sin); + sinline1p = sinline1c; + + HVX_Vector *jiptr = iptr + d / 32; + HVX_Vector *jiptr_half = iptr_half + d / 32; + HVX_Vector *joptr = optr + d / 32; + HVX_Vector *joptr_half = optr_half + d / 32; + + for (int32_t j = 0; j < size / partial_dimension; j++) { + sline1 = *jiptr; + sline1_half = *jiptr_half; + + // auto value = in_value * cos_value - in_value_2 * sin_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, cosline1); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1_half, sinline1); + *joptr = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); + } + + // auto value2 = in_value * sin_value + in_value_2 * cos_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1_half, cosline1); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_VsfVsf(sline1, sinline1); + *joptr_half = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); + } + + jiptr += partial_dimension / 32; + jiptr_half += partial_dimension / 32; + joptr += partial_dimension / 32; + joptr_half += partial_dimension / 32; + } } - } // if (vectors_in_rounddown > 0) { @@ -202,15 +187,13 @@ int32_t hvx_rope_af( // } - if (leftover_size > 0) - return -1; + return -1; return 0; } -static inline int32_t float_to_fp16s(float input) -{ +static inline int32_t float_to_fp16s(float input) { union { int32_t i; __fp16 f[2]; @@ -224,10 +207,8 @@ int32_t hvx_rope_uint8_af( float *restrict cos, float *restrict output, uint32_t size, - uint32_t partial_dimension) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + uint32_t partial_dimension) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -246,83 +227,70 @@ int32_t hvx_rope_uint8_af( HVX_Vector convert_vector = Q6_V_vsplat_R(convert); HVX_Vector one_vec = Q6_V_vsplat_R(float_to_fp16s(1.0)); - // - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + // + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - // + // HVX_Vector sinline1_low = *iptr2; HVX_Vector cosline1_low = *iptr3; sinline1_low = Q6_Vqf32_vadd_VsfVsf(sinline1_low, Q6_V_vzero()); cosline1_low = Q6_Vqf32_vadd_VsfVsf(cosline1_low, Q6_V_vzero()); - - HVX_Vector sinline1_high = *(iptr2+1); - HVX_Vector cosline1_high = *(iptr3+1); + HVX_Vector sinline1_high = *(iptr2 + 1); + HVX_Vector cosline1_high = *(iptr3 + 1); sinline1_high = Q6_Vqf32_vadd_VsfVsf(sinline1_high, Q6_V_vzero()); cosline1_high = Q6_Vqf32_vadd_VsfVsf(cosline1_high, Q6_V_vzero()); - - for (int32_t j = 0; j < size/partial_dimension; j++) { - - HVX_Vector sline1 = *iptr++; - - HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); - temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); - HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); - HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + for (int32_t j = 0; j < size / partial_dimension; j++) { + HVX_Vector sline1 = *iptr++; - HVX_VectorPair result1 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), one_vec); - result1 = Q6_W_vshuff_VVR(Q6_V_hi_W(result1), Q6_V_lo_W(result1), -4); + HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); - HVX_VectorPair result2 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), one_vec); - result2 = Q6_W_vshuff_VVR(Q6_V_hi_W(result2), Q6_V_lo_W(result2), -4); + temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); + HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + HVX_VectorPair result1 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), one_vec); + result1 = Q6_W_vshuff_VVR(Q6_V_hi_W(result1), Q6_V_lo_W(result1), -4); + HVX_VectorPair result2 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), one_vec); + result2 = Q6_W_vshuff_VVR(Q6_V_hi_W(result2), Q6_V_lo_W(result2), -4); - // auto value = in_value * cos_value - in_value_2 * sin_value; - { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), cosline1_low); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), sinline1_low); - *optr = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); - } - - - - // auto value2 = in_value * sin_value + in_value_2 * cos_value; - { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), cosline1_low); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), sinline1_low); - *(optr+2) = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); - } - - - // auto value = in_value * cos_value - in_value_2 * sin_value; - { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), cosline1_high); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), sinline1_high); - *(optr+1) = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); - } - + // auto value = in_value * cos_value - in_value_2 * sin_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), cosline1_low); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), sinline1_low); + *optr = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); + } + // auto value2 = in_value * sin_value + in_value_2 * cos_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), cosline1_low); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), sinline1_low); + *(optr + 2) = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); + } - // auto value2 = in_value * sin_value + in_value_2 * cos_value; - { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), cosline1_high); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), sinline1_high); - *(optr+3) = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); - } + // auto value = in_value * cos_value - in_value_2 * sin_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), cosline1_high); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), sinline1_high); + *(optr + 1) = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); + } - optr+=4; + // auto value2 = in_value * sin_value + in_value_2 * cos_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), cosline1_high); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), sinline1_high); + *(optr + 3) = Q6_Vsf_equals_Vqf32(Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32)); + } + optr += 4; } - } // if (vectors_in_rounddown > 0) { @@ -333,9 +301,8 @@ int32_t hvx_rope_uint8_af( // } - if (leftover_size > 0) - return -1; + return -1; return 0; } @@ -347,10 +314,8 @@ int32_t hvx_rope_uint8_ahf( __fp16 *restrict output, uint32_t size, uint32_t partial_dimension, - float scale) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + float scale) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } @@ -370,96 +335,85 @@ int32_t hvx_rope_uint8_ahf( HVX_Vector scale_vec = Q6_V_vsplat_R(float_to_fp16s(scale)); - // - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + // + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - // + // HVX_Vector sinline1_low = *iptr2; HVX_Vector cosline1_low = *iptr3; sinline1_low = Q6_Vqf32_vadd_VsfVsf(sinline1_low, Q6_V_vzero()); cosline1_low = Q6_Vqf32_vadd_VsfVsf(cosline1_low, Q6_V_vzero()); - - HVX_Vector sinline1_high = *(iptr2+1); - HVX_Vector cosline1_high = *(iptr3+1); + HVX_Vector sinline1_high = *(iptr2 + 1); + HVX_Vector cosline1_high = *(iptr3 + 1); sinline1_high = Q6_Vqf32_vadd_VsfVsf(sinline1_high, Q6_V_vzero()); cosline1_high = Q6_Vqf32_vadd_VsfVsf(cosline1_high, Q6_V_vzero()); - - for (int32_t j = 0; j < size/partial_dimension; j++) { - - HVX_Vector sline1 = *iptr++; - - HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); - temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); - HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); - HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + for (int32_t j = 0; j < size / partial_dimension; j++) { + HVX_Vector sline1 = *iptr++; - HVX_VectorPair result1 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec); - result1 = Q6_W_vshuff_VVR(Q6_V_hi_W(result1), Q6_V_lo_W(result1), -4); + HVX_VectorPair temp = Q6_Wh_vadd_VubVub(sline1, zero_v_sf); - HVX_VectorPair result2 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), scale_vec); - result2 = Q6_W_vshuff_VVR(Q6_V_hi_W(result2), Q6_V_lo_W(result2), -4); + temp = Q6_W_vshuff_VVR(Q6_V_hi_W(temp), Q6_V_lo_W(temp), -2); + HVX_Vector sout1 = Q6_Vh_vsub_VhVh(Q6_V_lo_W(temp), convert_vector); + HVX_Vector sout2 = Q6_Vh_vsub_VhVh(Q6_V_hi_W(temp), convert_vector); + HVX_VectorPair result1 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout1), scale_vec); + result1 = Q6_W_vshuff_VVR(Q6_V_hi_W(result1), Q6_V_lo_W(result1), -4); + HVX_VectorPair result2 = Q6_Wqf32_vmpy_VhfVhf(Q6_Vhf_equals_Vh(sout2), scale_vec); + result2 = Q6_W_vshuff_VVR(Q6_V_hi_W(result2), Q6_V_lo_W(result2), -4); - - { - HVX_Vector first; - HVX_Vector second; - // auto value = in_value * cos_value - in_value_2 * sin_value; { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), cosline1_low); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), sinline1_low); - first = Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32); + HVX_Vector first; + HVX_Vector second; + // auto value = in_value * cos_value - in_value_2 * sin_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), cosline1_low); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), sinline1_low); + first = Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32); + } + + // auto value = in_value * cos_value - in_value_2 * sin_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), cosline1_high); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), sinline1_high); + second = Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32); + } + + HVX_Vector r = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(second, first)); + r = Q6_Vh_vdeal_Vh(r); + *optr = r; } - // auto value = in_value * cos_value - in_value_2 * sin_value; - { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), cosline1_high); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), sinline1_high); - second = Q6_Vqf32_vsub_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32); - } - - HVX_Vector r = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(second, first)); - r = Q6_Vh_vdeal_Vh(r); - *optr = r; - } - - { - HVX_Vector first; - HVX_Vector second; - // auto value2 = in_value * sin_value + in_value_2 * cos_value; - { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), cosline1_low); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), sinline1_low); - first = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32); - } - - - // auto value2 = in_value * sin_value + in_value_2 * cos_value; { - HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), cosline1_high); - HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), sinline1_high); - second = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32); + HVX_Vector first; + HVX_Vector second; + // auto value2 = in_value * sin_value + in_value_2 * cos_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result2), cosline1_low); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(result1), sinline1_low); + first = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32); + } + + // auto value2 = in_value * sin_value + in_value_2 * cos_value; + { + HVX_Vector cos_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result2), cosline1_high); + HVX_Vector sin_middle_value_qf32 = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(result1), sinline1_high); + second = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32, sin_middle_value_qf32); + } + HVX_Vector r = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(second, first)); + r = Q6_Vh_vdeal_Vh(r); + *(optr + 1) = r; } - HVX_Vector r = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(second, first)); - r = Q6_Vh_vdeal_Vh(r); - *(optr+1) = r; - } - - - optr+=2; + optr += 2; } - } // if (vectors_in_rounddown > 0) { @@ -470,33 +424,30 @@ int32_t hvx_rope_uint8_ahf( // } - if (leftover_size > 0) - return -1; + return -1; return 0; } - int32_t hvx_rope_ahf( __fp16 *restrict input, float *restrict sin, float *restrict cos, __fp16 *restrict output, uint32_t size, - uint32_t partial_dimension) -{ - if ((input == NULL) || (output == NULL) || (size == 0)) - { + uint32_t partial_dimension) { + if ((input == NULL) || (output == NULL) || (size == 0)) { return -1; } HVX_Vector *iptr = (HVX_Vector *)input; - HVX_Vector *iptr_half = (HVX_Vector *)(input + partial_dimension/2); + HVX_Vector *iptr_half = (HVX_Vector *)(input + partial_dimension / 2); HVX_Vector *iptr2 = (HVX_Vector *)sin; HVX_Vector *iptr3 = (HVX_Vector *)cos; HVX_UVector *optr = (HVX_UVector *)output; - HVX_UVector *optr_half = (HVX_UVector *)(output + partial_dimension/2);; + HVX_UVector *optr_half = (HVX_UVector *)(output + partial_dimension / 2); + ; HVX_Vector sline1; HVX_Vector sline1_half; @@ -511,115 +462,104 @@ int32_t hvx_rope_ahf( HVX_Vector one_vhf = Q6_V_vsplat_R(float_to_fp16s(1.0)); // HVX_Vector m_one_vqf16 = Q6_Vqf32_vsub_VsfVsf(Q6_V_vzero(), one_vhf); - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(iptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr2 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); l2fetch(iptr3 + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } - for (int32_t d = 0; d < partial_dimension/2; d+=64) { + for (int32_t d = 0; d < partial_dimension / 2; d += 64) { + HVX_Vector sinline1_low = *iptr2++; + HVX_Vector cosline1_low = *iptr3++; - HVX_Vector sinline1_low = *iptr2++; - HVX_Vector cosline1_low = *iptr3++; + HVX_Vector sinline1_high = *iptr2++; + HVX_Vector cosline1_high = *iptr3++; - HVX_Vector sinline1_high = *iptr2++; - HVX_Vector cosline1_high = *iptr3++; + HVX_Vector *jiptr = iptr + d / 64; + HVX_Vector *jiptr_half = iptr_half + d / 64; + HVX_Vector *joptr = optr + d / 64; + HVX_Vector *joptr_half = optr_half + d / 64; + for (int32_t j = 0; j < size / partial_dimension; j++) { + sline1 = *jiptr; + sline1_half = *jiptr_half; - HVX_Vector *jiptr = iptr + d/64; - HVX_Vector *jiptr_half = iptr_half + d/64; - HVX_Vector *joptr = optr + d/64; - HVX_Vector *joptr_half = optr_half + d/64; + HVX_VectorPair sline1_half_pair = Q6_Wqf32_vmpy_VhfVhf(sline1_half, one_vhf); + HVX_VectorPair sline1_pair = Q6_Wqf32_vmpy_VhfVhf(sline1, one_vhf); - - for (int32_t j = 0; j < size/partial_dimension; j++) - { - sline1 = *jiptr; - sline1_half = *jiptr_half; + sline1_half_pair = Q6_W_vshuff_VVR(Q6_V_hi_W(sline1_half_pair), Q6_V_lo_W(sline1_half_pair), -4); + sline1_pair = Q6_W_vshuff_VVR(Q6_V_hi_W(sline1_pair), Q6_V_lo_W(sline1_pair), -4); - HVX_VectorPair sline1_half_pair = Q6_Wqf32_vmpy_VhfVhf(sline1_half, one_vhf); - HVX_VectorPair sline1_pair = Q6_Wqf32_vmpy_VhfVhf(sline1, one_vhf); + HVX_Vector m_sline1_half_low = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(sline1_half_pair), m_one_vqf32); + HVX_Vector m_sline1_half_hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(sline1_half_pair), m_one_vqf32); - sline1_half_pair = Q6_W_vshuff_VVR(Q6_V_hi_W(sline1_half_pair), Q6_V_lo_W(sline1_half_pair), -4); - sline1_pair = Q6_W_vshuff_VVR(Q6_V_hi_W(sline1_pair), Q6_V_lo_W(sline1_pair), -4); + // auto value = in_value * cos_value - in_value_2 * sin_value; + HVX_Vector middle_value_low; + { + HVX_Vector cosline1_vqf32_low = Q6_Vqf32_vadd_VsfVsf(cosline1_low, Q6_V_vzero()); + HVX_Vector cos_middle_value_qf32_low = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(sline1_pair), cosline1_vqf32_low); - HVX_Vector m_sline1_half_low = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(sline1_half_pair), m_one_vqf32); - HVX_Vector m_sline1_half_hi = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(sline1_half_pair), m_one_vqf32); + HVX_Vector sinline1_vqf32_low = Q6_Vqf32_vadd_VsfVsf(sinline1_low, Q6_V_vzero()); + HVX_Vector sin_middle_value_qf32_low = Q6_Vqf32_vmpy_Vqf32Vqf32(m_sline1_half_low, sinline1_vqf32_low); + middle_value_low = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32_low, sin_middle_value_qf32_low); + } - // auto value = in_value * cos_value - in_value_2 * sin_value; - HVX_Vector middle_value_low; - { - HVX_Vector cosline1_vqf32_low = Q6_Vqf32_vadd_VsfVsf(cosline1_low, Q6_V_vzero()); - HVX_Vector cos_middle_value_qf32_low = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(sline1_pair), cosline1_vqf32_low); + // auto value2 = in_value * sin_value + in_value_2 * cos_value; - HVX_Vector sinline1_vqf32_low = Q6_Vqf32_vadd_VsfVsf(sinline1_low, Q6_V_vzero()); - - HVX_Vector sin_middle_value_qf32_low = Q6_Vqf32_vmpy_Vqf32Vqf32(m_sline1_half_low, sinline1_vqf32_low); - middle_value_low = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32_low, sin_middle_value_qf32_low); - } - + HVX_Vector middle_value_half_low; + { + HVX_Vector cosline1_vqf32_low = Q6_Vqf32_vadd_VsfVsf(cosline1_low, Q6_V_vzero()); + HVX_Vector cos_middle_value_qf32_low = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(sline1_half_pair), cosline1_vqf32_low); + HVX_Vector sinline1_vqf32_low = Q6_Vqf32_vadd_VsfVsf(sinline1_low, Q6_V_vzero()); + HVX_Vector sin_middle_value_qf32_low = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(sline1_pair), sinline1_vqf32_low); - // auto value2 = in_value * sin_value + in_value_2 * cos_value; + middle_value_half_low = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32_low, sin_middle_value_qf32_low); + } - HVX_Vector middle_value_half_low; - { - HVX_Vector cosline1_vqf32_low = Q6_Vqf32_vadd_VsfVsf(cosline1_low, Q6_V_vzero()); - HVX_Vector cos_middle_value_qf32_low = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(sline1_half_pair), cosline1_vqf32_low); + // second qf16 vector + HVX_Vector middle_value_high; + { + HVX_Vector cosline1_vqf32_high = Q6_Vqf32_vadd_VsfVsf(cosline1_high, Q6_V_vzero()); + HVX_Vector cos_middle_value_qf32_high = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(sline1_pair), cosline1_vqf32_high); - HVX_Vector sinline1_vqf32_low = Q6_Vqf32_vadd_VsfVsf(sinline1_low, Q6_V_vzero()); - HVX_Vector sin_middle_value_qf32_low = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_lo_W(sline1_pair), sinline1_vqf32_low); + HVX_Vector sinline1_vqf32_high = Q6_Vqf32_vadd_VsfVsf(sinline1_high, Q6_V_vzero()); - middle_value_half_low = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32_low, sin_middle_value_qf32_low); - } + HVX_Vector sin_middle_value_qf32_high = Q6_Vqf32_vmpy_Vqf32Vqf32(m_sline1_half_hi, sinline1_vqf32_high); + middle_value_high = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32_high, sin_middle_value_qf32_high); + } - // second qf16 vector - HVX_Vector middle_value_high; - { - HVX_Vector cosline1_vqf32_high= Q6_Vqf32_vadd_VsfVsf(cosline1_high, Q6_V_vzero()); - HVX_Vector cos_middle_value_qf32_high = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(sline1_pair), cosline1_vqf32_high); + // auto value2 = in_value * sin_value + in_value_2 * cos_value; - HVX_Vector sinline1_vqf32_high = Q6_Vqf32_vadd_VsfVsf(sinline1_high, Q6_V_vzero()); + HVX_Vector middle_value_half_high; + { + HVX_Vector cosline1_vqf32_high = Q6_Vqf32_vadd_VsfVsf(cosline1_high, Q6_V_vzero()); + HVX_Vector cos_middle_value_qf32_high = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(sline1_half_pair), cosline1_vqf32_high); - HVX_Vector sin_middle_value_qf32_high = Q6_Vqf32_vmpy_Vqf32Vqf32(m_sline1_half_hi, sinline1_vqf32_high); - middle_value_high = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32_high, sin_middle_value_qf32_high); - } - + HVX_Vector sinline1_vqf32_high = Q6_Vqf32_vadd_VsfVsf(sinline1_high, Q6_V_vzero()); + HVX_Vector sin_middle_value_qf32_high = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(sline1_pair), sinline1_vqf32_high); + middle_value_half_high = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32_high, sin_middle_value_qf32_high); + } - // auto value2 = in_value * sin_value + in_value_2 * cos_value; + HVX_Vector sline = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(middle_value_high, middle_value_low)); + sline = Q6_Vh_vdeal_Vh(sline); - HVX_Vector middle_value_half_high; - { - HVX_Vector cosline1_vqf32_high = Q6_Vqf32_vadd_VsfVsf(cosline1_high, Q6_V_vzero()); - HVX_Vector cos_middle_value_qf32_high = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(sline1_half_pair), cosline1_vqf32_high); + HVX_Vector sline_half = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(middle_value_half_high, middle_value_half_low)); + sline_half = Q6_Vh_vdeal_Vh(sline_half); - HVX_Vector sinline1_vqf32_high = Q6_Vqf32_vadd_VsfVsf(sinline1_high, Q6_V_vzero()); - HVX_Vector sin_middle_value_qf32_high = Q6_Vqf32_vmpy_Vqf32Vqf32(Q6_V_hi_W(sline1_pair), sinline1_vqf32_high); + *joptr = sline; + *joptr_half = sline_half; - middle_value_half_high = Q6_Vqf32_vadd_Vqf32Vqf32(cos_middle_value_qf32_high, sin_middle_value_qf32_high); + jiptr += partial_dimension / 64; + jiptr_half += partial_dimension / 64; + joptr += partial_dimension / 64; + joptr_half += partial_dimension / 64; } - - HVX_Vector sline = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(middle_value_high, middle_value_low)); - sline = Q6_Vh_vdeal_Vh(sline); - - HVX_Vector sline_half = Q6_Vhf_equals_Wqf32(Q6_W_vcombine_VV(middle_value_half_high, middle_value_half_low)); - sline_half = Q6_Vh_vdeal_Vh(sline_half); - - *joptr = sline; - *joptr_half = sline_half; - - jiptr += partial_dimension/64; - jiptr_half += partial_dimension/64; - joptr += partial_dimension/64; - joptr_half += partial_dimension/64; - } } } @@ -631,448 +571,410 @@ int32_t hvx_rope_ahf( // } - if (leftover_size > 0) - return -1; + return -1; return 0; } - -template -GraphStatus ropeImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& sin, - const TensorType& cos, +template +GraphStatus ropeImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &sin, + const TensorType &cos, const TensorType1 &h_cnt, - const Tensor& pose_type) -{ + const Tensor &pose_type) { + out_0.set_dims(in_0); - out_0.set_dims(in_0); + auto pose_type_ = pose_type(0, 0, 0, 0); + auto h_cnt_ = static_cast(h_cnt(0, 0, 0, 0)); - auto pose_type_ = pose_type(0,0,0,0); - auto h_cnt_ = static_cast(h_cnt(0,0,0,0)); + if (pose_type_ == 4) { + DType dtype = out_0.get_dtype(); - if (pose_type_ == 4) { + if (in_0.get_dtype() == DType::Float32 && dtype == DType::Float32) { + auto in_ptr = (float *)in_0.raw_data_const(); + auto sin_ptr = (float *)sin.raw_data_const(); + auto cos_ptr = (float *)cos.raw_data_const(); + auto out_ptr = (float *)out_0.raw_data(); - DType dtype = out_0.get_dtype(); + auto [b_in, h_in, w_in, d_in] = in_0.dims(); - if (in_0.get_dtype() == DType::Float32 && dtype == DType::Float32) { - auto in_ptr = (float*)in_0.raw_data_const(); - auto sin_ptr = (float*)sin.raw_data_const(); - auto cos_ptr = (float*)cos.raw_data_const(); - auto out_ptr = (float*)out_0.raw_data(); + uint32_t half_dimension = d_in / 2; + sin_ptr += half_dimension * h_cnt_; + cos_ptr += half_dimension * h_cnt_; + int partial_dimension = d_in; - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - uint32_t half_dimension = d_in / 2; - sin_ptr += half_dimension * h_cnt_; - cos_ptr += half_dimension * h_cnt_; - - int partial_dimension = d_in; + // NSHD + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + // for (Idx w = 0; w < w_in; w++) { + hvx_rope_af(in_ptr, sin_ptr, cos_ptr, out_ptr, w_in * d_in, partial_dimension); - // NSHD - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - - // for (Idx w = 0; w < w_in; w++) { - hvx_rope_af(in_ptr, sin_ptr, cos_ptr, out_ptr, w_in * d_in, partial_dimension); - - in_ptr += w_in * d_in; - out_ptr += w_in * d_in; - // } + in_ptr += w_in * d_in; + out_ptr += w_in * d_in; + // } - sin_ptr += half_dimension; - cos_ptr += half_dimension; - } - } - } else if (in_0.get_dtype() == DType::Float16 && dtype == DType::Float16) { + sin_ptr += half_dimension; + cos_ptr += half_dimension; + } + } + } else if (in_0.get_dtype() == DType::Float16 && dtype == DType::Float16) { + auto in_ptr = (__fp16 *)in_0.raw_data_const(); + auto sin_ptr = (float *)sin.raw_data_const(); + auto cos_ptr = (float *)cos.raw_data_const(); + auto out_ptr = (__fp16 *)out_0.raw_data(); - auto in_ptr = (__fp16*)in_0.raw_data_const(); - auto sin_ptr = (float*)sin.raw_data_const(); - auto cos_ptr = (float*)cos.raw_data_const(); - auto out_ptr = (__fp16*)out_0.raw_data(); + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + uint32_t half_dimension = d_in / 2; + sin_ptr += half_dimension * h_cnt_; + cos_ptr += half_dimension * h_cnt_; - auto [b_in, h_in, w_in, d_in] = in_0.dims(); + int partial_dimension = d_in; - uint32_t half_dimension = d_in / 2; - sin_ptr += half_dimension * h_cnt_; - cos_ptr += half_dimension * h_cnt_; + // NSHD + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + // for (Idx w = 0; w < w_in; w++) { + hvx_rope_ahf(in_ptr, sin_ptr, cos_ptr, out_ptr, w_in * d_in, partial_dimension); - int partial_dimension = d_in; + in_ptr += w_in * d_in; + out_ptr += w_in * d_in; + // } - // NSHD - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - - // for (Idx w = 0; w < w_in; w++) { - hvx_rope_ahf(in_ptr, sin_ptr, cos_ptr, out_ptr, w_in * d_in, partial_dimension); - - in_ptr += w_in * d_in; - out_ptr += w_in * d_in; - // } + sin_ptr += half_dimension; + cos_ptr += half_dimension; + } + } + } else if (in_0.get_dtype() == DType::QUInt8 && dtype == DType::Float32) { + auto in_ptr = (uint8_t *)in_0.raw_data_const(); + auto sin_ptr = (float *)sin.raw_data_const(); + auto cos_ptr = (float *)cos.raw_data_const(); + auto out_ptr = (float *)out_0.raw_data(); - sin_ptr += half_dimension; - cos_ptr += half_dimension; - } - } - } else if (in_0.get_dtype() == DType::QUInt8 && dtype == DType::Float32) { - auto in_ptr = (uint8_t*)in_0.raw_data_const(); - auto sin_ptr = (float*)sin.raw_data_const(); - auto cos_ptr = (float*)cos.raw_data_const(); - auto out_ptr = (float*)out_0.raw_data(); - - - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - uint32_t half_dimension = d_in / 2; - sin_ptr += half_dimension * h_cnt_; - cos_ptr += half_dimension * h_cnt_; - - int partial_dimension = d_in; - - // NSHD - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - - // for (Idx w = 0; w < w_in; w++) { - hvx_rope_uint8_af(in_ptr, sin_ptr, cos_ptr, out_ptr, w_in * d_in, partial_dimension); - - in_ptr += w_in * d_in; - out_ptr += w_in * d_in; - // } - - sin_ptr += half_dimension; - cos_ptr += half_dimension; - } - } - } else if (in_0.get_dtype() == DType::QUInt8 && dtype == DType::Float16) { + auto [b_in, h_in, w_in, d_in] = in_0.dims(); - auto in_ptr = (uint8_t*)in_0.raw_data_const(); - auto sin_ptr = (float*)sin.raw_data_const(); - auto cos_ptr = (float*)cos.raw_data_const(); - auto out_ptr = (__fp16*)out_0.raw_data(); + uint32_t half_dimension = d_in / 2; + sin_ptr += half_dimension * h_cnt_; + cos_ptr += half_dimension * h_cnt_; - float scale_ = in_0.get_interface_scale(); + int partial_dimension = d_in; - auto [b_in, h_in, w_in, d_in] = in_0.dims(); + // NSHD + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + // for (Idx w = 0; w < w_in; w++) { + hvx_rope_uint8_af(in_ptr, sin_ptr, cos_ptr, out_ptr, w_in * d_in, partial_dimension); - uint32_t half_dimension = d_in / 2; - sin_ptr += half_dimension * h_cnt_; - cos_ptr += half_dimension * h_cnt_; + in_ptr += w_in * d_in; + out_ptr += w_in * d_in; + // } - int partial_dimension = d_in; + sin_ptr += half_dimension; + cos_ptr += half_dimension; + } + } + } else if (in_0.get_dtype() == DType::QUInt8 && dtype == DType::Float16) { + auto in_ptr = (uint8_t *)in_0.raw_data_const(); + auto sin_ptr = (float *)sin.raw_data_const(); + auto cos_ptr = (float *)cos.raw_data_const(); + auto out_ptr = (__fp16 *)out_0.raw_data(); - // NSHD - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - - // for (Idx w = 0; w < w_in; w++) { - hvx_rope_uint8_ahf(in_ptr, sin_ptr, cos_ptr, out_ptr, w_in * d_in, partial_dimension, scale_); - - in_ptr += w_in * d_in; - out_ptr += w_in * d_in; - // } + float scale_ = in_0.get_interface_scale(); - sin_ptr += half_dimension; - cos_ptr += half_dimension; - } - } - } + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + uint32_t half_dimension = d_in / 2; + sin_ptr += half_dimension * h_cnt_; + cos_ptr += half_dimension * h_cnt_; - } else { + int partial_dimension = d_in; - // only support pose_type == 2 (LLaMA) now - return GraphStatus::ErrorFatal; + // NSHD + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + // for (Idx w = 0; w < w_in; w++) { + hvx_rope_uint8_ahf(in_ptr, sin_ptr, cos_ptr, out_ptr, w_in * d_in, partial_dimension, scale_); - } + in_ptr += w_in * d_in; + out_ptr += w_in * d_in; + // } + sin_ptr += half_dimension; + cos_ptr += half_dimension; + } + } + } - - - - return GraphStatus::Success; + } else { + // only support pose_type == 2 (LLaMA) now + return GraphStatus::ErrorFatal; + } + return GraphStatus::Success; } - - #else - -template -GraphStatus ropeImpl(TensorType& out_0, - const TensorType& in_0, - const TensorType& sin, - const TensorType& cos, +template +GraphStatus ropeImpl(TensorType &out_0, + const TensorType &in_0, + const TensorType &sin, + const TensorType &cos, const TensorType1 &h_cnt, - const Tensor& pose_type) + const Tensor &pose_type) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - debuglog("RoPE execute... dims=(%zdx%zdx%zdx%zd)", in_0.dim(0), in_0.dim(1), in_0.dim(2), in_0.dim(3)); - debuglog("RoPE execute... dims=(%zdx%zdx%zdx%zd)", sin.dim(0), sin.dim(1), sin.dim(2), sin.dim(3)); - debuglog("RoPE execute... dims=(%zdx%zdx%zdx%zd)", cos.dim(0), cos.dim(1), cos.dim(2), cos.dim(3)); - - // BSHD => NHWC - - // Todo: We need consider to store the sequence position if we have KV Cache - - auto pose_type_ = pose_type(0,0,0,0); - auto h_cnt_ = static_cast(h_cnt(0,0,0,0)); - - out_0.set_dims(in_0); - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - if (pose_type_ == 4) { - DType dtype = out_0.get_dtype(); - - if (dtype == DType::Float32) { - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - - int s = h; // BSHD order - int partial_dimension = d_in; - int half = (int)(partial_dimension / 2); - for (Idx d = 0; d < partial_dimension / 2; ++d) { - float in_value = in_0(b, h, w, d); - float in_value_2 = in_0(b, h, w, d + half); - float sin_value = sin(0, 0, s + h_cnt_, d); - float cos_value = cos(0, 0, s + h_cnt_, d); - auto value = in_value * cos_value - in_value_2 * sin_value; - auto value2 = in_value * sin_value + in_value_2 * cos_value; - out_0(b, h, w, d) = value; - out_0(b, h, w, d + half) = value2; + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + + debuglog("RoPE execute... dims=(%zdx%zdx%zdx%zd)", in_0.dim(0), in_0.dim(1), in_0.dim(2), in_0.dim(3)); + debuglog("RoPE execute... dims=(%zdx%zdx%zdx%zd)", sin.dim(0), sin.dim(1), sin.dim(2), sin.dim(3)); + debuglog("RoPE execute... dims=(%zdx%zdx%zdx%zd)", cos.dim(0), cos.dim(1), cos.dim(2), cos.dim(3)); + + // BSHD => NHWC + + // Todo: We need consider to store the sequence position if we have KV Cache + + auto pose_type_ = pose_type(0, 0, 0, 0); + auto h_cnt_ = static_cast(h_cnt(0, 0, 0, 0)); + + out_0.set_dims(in_0); + auto [b_in, h_in, w_in, d_in] = in_0.dims(); + if (pose_type_ == 4) { + DType dtype = out_0.get_dtype(); + + if (dtype == DType::Float32) { + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + int s = h; // BSHD order + int partial_dimension = d_in; + int half = (int)(partial_dimension / 2); + for (Idx d = 0; d < partial_dimension / 2; ++d) { + float in_value = in_0(b, h, w, d); + float in_value_2 = in_0(b, h, w, d + half); + float sin_value = sin(0, 0, s + h_cnt_, d); + float cos_value = cos(0, 0, s + h_cnt_, d); + auto value = in_value * cos_value - in_value_2 * sin_value; + auto value2 = in_value * sin_value + in_value_2 * cos_value; + out_0(b, h, w, d) = value; + out_0(b, h, w, d + half) = value2; + } + } + } + } + } else if (dtype == DType::Float16) { + auto in_ptr = (__fp16 *)in_0.raw_data_const(); + // auto sin_ptr = (__fp16*)sin.raw_data_const(); + // auto cos_ptr = (__fp16*)cos.raw_data_const(); + auto out_ptr = (__fp16 *)out_0.raw_data(); + + for (Idx b = 0; b < b_in; b++) { + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + int s = h; // BSHD order + int partial_dimension = d_in; + int half = (int)(partial_dimension / 2); + for (Idx d = 0; d < partial_dimension / 2; ++d) { + __fp16 in_value = *in_ptr; + __fp16 in_value_2 = *(in_ptr + half); + float sin_value = sin(0, 0, s + h_cnt_, d); + float cos_value = cos(0, 0, s + h_cnt_, d); + auto value = in_value * cos_value - in_value_2 * sin_value; + auto value2 = in_value * sin_value + in_value_2 * cos_value; + *out_ptr = static_cast<__fp16>(value); + *(out_ptr + half) = static_cast<__fp16>(value2); + + out_ptr++; + in_ptr++; + } + + out_ptr += half; + in_ptr += half; + } + } } - } } - } - } else if (dtype == DType::Float16) { - - auto in_ptr = (__fp16*)in_0.raw_data_const(); - // auto sin_ptr = (__fp16*)sin.raw_data_const(); - // auto cos_ptr = (__fp16*)cos.raw_data_const(); - auto out_ptr = (__fp16*)out_0.raw_data(); - - for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { + } - int s = h; // BSHD order - int partial_dimension = d_in; - int half = (int)(partial_dimension / 2); - for (Idx d = 0; d < partial_dimension / 2; ++d) { - __fp16 in_value = *in_ptr; - __fp16 in_value_2 = *(in_ptr + half); - float sin_value = sin(0, 0, s + h_cnt_, d); - float cos_value = cos(0, 0, s + h_cnt_, d); - auto value = in_value * cos_value - in_value_2 * sin_value; - auto value2 = in_value * sin_value + in_value_2 * cos_value; - *out_ptr = static_cast<__fp16>(value); - *(out_ptr + half) = static_cast<__fp16>(value2); - - out_ptr++; - in_ptr++; - } + // for (Idx b = 0; b < b_in; b++) { + // for (Idx h = 0; h < h_in; h++) { + // for (Idx w = 0; w < w_in; w++) { + // // RoPE + // for (Idx d = 0; d < d_in; d++) { + + // int s = h; // BSHD order + // if (pose_type_ == 1) { + // float in_value = in_0(b, h, w, d); + // float in_value_2; + // if (d < d_in / 2) { // 偶數 0,2,4 + // in_value_2 = -in_0(b, h, w, d + d_in / 2); + // } else { + // in_value_2 = in_0(b, h, w, d - d_in / 2); + // } + // float sin_value = sin(0, 0, s +h_cnt_, d); + // float cos_value = cos(0, 0, s +h_cnt_, d); + // auto value = in_value * cos_value + in_value_2 * sin_value; + // out_0(b, h, w, d) = value; + // } + // else if (pose_type_ == 2) { + // float in_value = in_0(b, h, w, d); + // debuglog("rope execute... in_value=(%f)", in_value); + // float in_value_2; + // if (d % 2 == 0) { // 偶數 0,2,4 + // in_value_2 = -in_0(b, h, w, d + 1); + // } else { + // in_value_2 = in_0(b, h, w, d - 1); + // } + // debuglog("rope execute... in_value_2=(%f)", in_value_2); + // float sin_value = sin(0, 0, s +h_cnt_, d); + // float cos_value = cos(0, 0, s +h_cnt_, d); + // auto value = in_value * cos_value + in_value_2 * sin_value; + + // debuglog("rope execute... sin_value=(%f)", sin_value); + // debuglog("rope execute... cos_value=(%f)", cos_value); + + // debuglog("rope execute... value=(%f)", value); + // out_0(b, h, w, d) = value; + // } else if (pose_type_ == 4) { + // } else { + // float in_value = in_0(b, h, w, d); + // float in_value_2; + // float sin_value = sin(0, 0, s +h_cnt_, d); + // float cos_value = cos(0, 0, s +h_cnt_, d); + // if (d < d_in / 4) { + // in_value_2 = -in_0(b, h, w, d + d_in / 4); + // auto value = in_value * cos_value + in_value_2 * sin_value; + + // out_0(b ,h , w, d) = value; + // } else if(d < d_in / 2){ + // in_value_2 = in_0(b, h, w, d - d_in / 4); + // auto value = in_value * cos_value + in_value_2 * sin_value; + + // out_0(b ,h , w, d) = value; + // }else { + + // out_0(b ,h , w, d) = in_value; + // } + // } + + // } + // } + // } + // } - out_ptr += half; - in_ptr += half; - } - } - } - } - } - - // for (Idx b = 0; b < b_in; b++) { - // for (Idx h = 0; h < h_in; h++) { - // for (Idx w = 0; w < w_in; w++) { - // // RoPE - // for (Idx d = 0; d < d_in; d++) { - - - // int s = h; // BSHD order - // if (pose_type_ == 1) { - // float in_value = in_0(b, h, w, d); - // float in_value_2; - // if (d < d_in / 2) { // 偶數 0,2,4 - // in_value_2 = -in_0(b, h, w, d + d_in / 2); - // } else { - // in_value_2 = in_0(b, h, w, d - d_in / 2); - // } - // float sin_value = sin(0, 0, s +h_cnt_, d); - // float cos_value = cos(0, 0, s +h_cnt_, d); - // auto value = in_value * cos_value + in_value_2 * sin_value; - // out_0(b, h, w, d) = value; - // } - // else if (pose_type_ == 2) { - // float in_value = in_0(b, h, w, d); - // debuglog("rope execute... in_value=(%f)", in_value); - // float in_value_2; - // if (d % 2 == 0) { // 偶數 0,2,4 - // in_value_2 = -in_0(b, h, w, d + 1); - // } else { - // in_value_2 = in_0(b, h, w, d - 1); - // } - // debuglog("rope execute... in_value_2=(%f)", in_value_2); - // float sin_value = sin(0, 0, s +h_cnt_, d); - // float cos_value = cos(0, 0, s +h_cnt_, d); - // auto value = in_value * cos_value + in_value_2 * sin_value; - - // debuglog("rope execute... sin_value=(%f)", sin_value); - // debuglog("rope execute... cos_value=(%f)", cos_value); - - // debuglog("rope execute... value=(%f)", value); - // out_0(b, h, w, d) = value; - // } else if (pose_type_ == 4) { - // } else { - // float in_value = in_0(b, h, w, d); - // float in_value_2; - // float sin_value = sin(0, 0, s +h_cnt_, d); - // float cos_value = cos(0, 0, s +h_cnt_, d); - // if (d < d_in / 4) { - // in_value_2 = -in_0(b, h, w, d + d_in / 4); - // auto value = in_value * cos_value + in_value_2 * sin_value; - - // out_0(b ,h , w, d) = value; - // } else if(d < d_in / 2){ - // in_value_2 = in_0(b, h, w, d - d_in / 4); - // auto value = in_value * cos_value + in_value_2 * sin_value; - - // out_0(b ,h , w, d) = value; - // }else { - - // out_0(b ,h , w, d) = in_value; - // } - // } - - // } - // } - // } - // } - - -// auto &input = inputs[0]; -// auto &output = outputs[0]; -// for (int n = 0; n < input->batch(); ++n) { -// for (int h = 0; h < input->head(); ++h) { -// for (int s = 0; s < input->sequence(); ++s) {//sequance -// #pragma omp parallel for num_threads(4) -// for (int d = 0; d < input->dimension(); ++d) { -// if (pose_type_== 1) { -// float in_value = input->dataAt(n, h, s, d); -// float in_value_2; -// if (d < input->dimension() / 2) { // 偶數 0,2,4 -// in_value_2 = -input->dataAt(n, h, s, d + input->dimension() / 2); -// } else { -// in_value_2 = input->dataAt(n, h, s, d - input->dimension() / 2); -// } -// float sin_value = sin_.dataAt(0, 0, s +h_cnt_, d); -// float cos_value = cos_.dataAt(0, 0, s +h_cnt_, d); -// auto value = in_value * cos_value + in_value_2 * sin_value; -// if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { -// output->setDataAt(n, h, s, d, value); -// } -// else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { -// output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); -// } -// } -// else if (pose_type_== 2) { -// float in_value = input->dataAt(n, h, s, d); -// float in_value_2; -// if (d % 2 == 0) { // 偶數 0,2,4 -// in_value_2 = -input->dataAt(n, h, s, d + 1); -// } else { -// in_value_2 = input->dataAt(n, h, s, d - 1); -// } -// float sin_value = sin_.dataAt(0, 0, s +h_cnt_, d); -// float cos_value = cos_.dataAt(0, 0, s +h_cnt_, d); -// auto value = in_value * cos_value + in_value_2 * sin_value; -// if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { -// output->setDataAt(n, h, s, d, value); -// } -// else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { -// output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); -// } -// }else{ -// float in_value = input->dataAt(n, h, s, d); -// float in_value_2; -// float sin_value = sin_.dataAt(0, 0, s +h_cnt_, d); -// float cos_value = cos_.dataAt(0, 0, s +h_cnt_, d); -// if (d < input->dimension() / 4) { -// in_value_2 = - input->dataAt(n, h, s, d + input->dimension() / 4); -// auto value = in_value * cos_value + in_value_2 * sin_value; -// if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { -// output->setDataAt(n, h, s, d, value); -// } -// else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { -// output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); -// } -// } else if(d < input->dimension() / 2){ -// in_value_2 = input->dataAt(n, h, s, d - input->dimension() / 4); -// auto value = in_value * cos_value + in_value_2 * sin_value; -// if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { -// output->setDataAt(n, h, s, d, value); -// } -// else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { -// output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); -// } -// }else { -// if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { -// output->setDataAt(n, h, s, d, in_value); -// } -// else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { -// output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(in_value)); -// } -// } -// } -// } -// } -// } -// } - - -// Todo store history position -// h_cnt_ += input->sequence(); -// if(h_cnt_ >pos_max_){ -// h_cnt_ = 0; -// } - - - return GraphStatus::Success; + // auto &input = inputs[0]; + // auto &output = outputs[0]; + // for (int n = 0; n < input->batch(); ++n) { + // for (int h = 0; h < input->head(); ++h) { + // for (int s = 0; s < input->sequence(); ++s) {//sequance + // #pragma omp parallel for num_threads(4) + // for (int d = 0; d < input->dimension(); ++d) { + // if (pose_type_== 1) { + // float in_value = input->dataAt(n, h, s, d); + // float in_value_2; + // if (d < input->dimension() / 2) { // 偶數 0,2,4 + // in_value_2 = -input->dataAt(n, h, s, d + input->dimension() / 2); + // } else { + // in_value_2 = input->dataAt(n, h, s, d - input->dimension() / 2); + // } + // float sin_value = sin_.dataAt(0, 0, s +h_cnt_, d); + // float cos_value = cos_.dataAt(0, 0, s +h_cnt_, d); + // auto value = in_value * cos_value + in_value_2 * sin_value; + // if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { + // output->setDataAt(n, h, s, d, value); + // } + // else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { + // output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); + // } + // } + // else if (pose_type_== 2) { + // float in_value = input->dataAt(n, h, s, d); + // float in_value_2; + // if (d % 2 == 0) { // 偶數 0,2,4 + // in_value_2 = -input->dataAt(n, h, s, d + 1); + // } else { + // in_value_2 = input->dataAt(n, h, s, d - 1); + // } + // float sin_value = sin_.dataAt(0, 0, s +h_cnt_, d); + // float cos_value = cos_.dataAt(0, 0, s +h_cnt_, d); + // auto value = in_value * cos_value + in_value_2 * sin_value; + // if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { + // output->setDataAt(n, h, s, d, value); + // } + // else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { + // output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); + // } + // }else{ + // float in_value = input->dataAt(n, h, s, d); + // float in_value_2; + // float sin_value = sin_.dataAt(0, 0, s +h_cnt_, d); + // float cos_value = cos_.dataAt(0, 0, s +h_cnt_, d); + // if (d < input->dimension() / 4) { + // in_value_2 = - input->dataAt(n, h, s, d + input->dimension() / 4); + // auto value = in_value * cos_value + in_value_2 * sin_value; + // if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { + // output->setDataAt(n, h, s, d, value); + // } + // else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { + // output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); + // } + // } else if(d < input->dimension() / 2){ + // in_value_2 = input->dataAt(n, h, s, d - input->dimension() / 4); + // auto value = in_value * cos_value + in_value_2 * sin_value; + // if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { + // output->setDataAt(n, h, s, d, value); + // } + // else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { + // output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); + // } + // }else { + // if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F32) { + // output->setDataAt(n, h, s, d, in_value); + // } + // else if(output->dtypeAt(n,h,s, d) == MLLM_TYPE_F16) { + // output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(in_value)); + // } + // } + // } + // } + // } + // } + // } + + // Todo store history position + // h_cnt_ += input->sequence(); + // if(h_cnt_ >pos_max_){ + // h_cnt_ = 0; + // } + + return GraphStatus::Success; } #endif +__attribute__((unused)) static float ropeCostFunc(const Op *op) { + /* + * add code here + * */ -__attribute__((unused)) static float ropeCostFunc(const Op *op) -{ - /* - * add code here - * */ - - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/SiLU.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/SiLU.cpp index 28271772f..8b56e7e80 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/SiLU.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/SiLU.cpp @@ -9,14 +9,12 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_SiLU); - // op execute function declarations -template -GraphStatus siluImpl(TensorType& out_0, - const TensorType& in_0); +template +GraphStatus siluImpl(TensorType &out_0, + const TensorType &in_0); // forward declaration of sample cost function static float siluCostFunc(const Op *op); @@ -61,11 +59,11 @@ DEF_PACKAGE_OP((siluImpl), "SiLU") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -79,7 +77,6 @@ DEF_PACKAGE_OP((siluImpl), "SiLU") * Qnn_addNode */ - /* execute functions for ops */ #ifndef REFERENCE_OP @@ -88,11 +85,10 @@ DEF_PACKAGE_OP((siluImpl), "SiLU") #include #include -#define BLOCK_SIZE (8*1024/VLEN) /* vector chunks */ -#define L2FETCH_AHEAD (BLOCK_SIZE) +#define BLOCK_SIZE (8 * 1024 / VLEN) /* vector chunks */ +#define L2FETCH_AHEAD (BLOCK_SIZE) -static inline int32_t float_to_fp16s(float input) -{ +static inline int32_t float_to_fp16s(float input) { union { int32_t i; __fp16 f[2]; @@ -100,48 +96,189 @@ static inline int32_t float_to_fp16s(float input) return fp32.i; } -static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) -{ - union { float f; uint32_t i; } fp32 = { .f = x }; +static HVX_INLINE_ALWAYS uint32_t float_to_bits(float x) { + union { + float f; + uint32_t i; + } fp32 = {.f = x}; return fp32.i; } - /* Polynomial coefficients */ static const float c0_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.1329913082916337,0.22308514882873062,0.347752862580421,0.4845759228057826,0.5724725619240282,0.5532613332075828,0.5041402176920755,0.4999998945071365, -0.500005251569411,0.494975832882496,0.44426898861108216,0.42865769845972046,0.5186084804556764,0.6556781472810073,0.7780379623543565,0.8670752648575938, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.1329913082916337, + 0.22308514882873062, + 0.347752862580421, + 0.4845759228057826, + 0.5724725619240282, + 0.5532613332075828, + 0.5041402176920755, + 0.4999998945071365, + 0.500005251569411, + 0.494975832882496, + 0.44426898861108216, + 0.42865769845972046, + 0.5186084804556764, + 0.6556781472810073, + 0.7780379623543565, + 0.8670752648575938, }; static const float c1_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.0595948414501292,0.11153317908159224,0.19545701719511055,0.3058925677063833,0.3932668307015573,0.3630691859433203,0.26302954631996744,0.2499155333713503, -0.24983690256810576,0.26551386754654915,0.3670764533308477,0.39196882072648825,0.3030372911476408,0.19296191313371913,0.11084562978488391,0.059559556604464964, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0595948414501292, + 0.11153317908159224, + 0.19545701719511055, + 0.3058925677063833, + 0.3932668307015573, + 0.3630691859433203, + 0.26302954631996744, + 0.2499155333713503, + 0.24983690256810576, + 0.26551386754654915, + 0.3670764533308477, + 0.39196882072648825, + 0.3030372911476408, + 0.19296191313371913, + 0.11084562978488391, + 0.059559556604464964, }; static const float c2_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.010207999856103376,0.02144807112969563,0.04266485934992188,0.07616157468726052,0.10882760873715347,0.09125379784995667,0.013872106909816257,-0.0008786208359828815, -0.0011993845621092196,-0.01645080326288375,-0.09367947263571219,-0.10827006684348266,-0.07520301291634655,-0.04198514892887826,-0.021290356584896874,-0.010200991240527542, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.010207999856103376, + 0.02144807112969563, + 0.04266485934992188, + 0.07616157468726052, + 0.10882760873715347, + 0.09125379784995667, + 0.013872106909816257, + -0.0008786208359828815, + 0.0011993845621092196, + -0.01645080326288375, + -0.09367947263571219, + -0.10827006684348266, + -0.07520301291634655, + -0.04198514892887826, + -0.021290356584896874, + -0.010200991240527542, }; static const float c3_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.0007896351019423816,0.0018718593077865326,0.004259190313167949,0.008784166436796144,0.014228201960903939,0.009727536748893095,-0.01721317464724529,-0.023762851116001377, --0.02424226654277249,-0.01604104065157868,0.010376786273973133,0.014122038833203628,0.008641365746408176,0.004176981844803722,0.0018557930308154783,0.0007890167735032168, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0007896351019423816, + 0.0018718593077865326, + 0.004259190313167949, + 0.008784166436796144, + 0.014228201960903939, + 0.009727536748893095, + -0.01721317464724529, + -0.023762851116001377, + -0.02424226654277249, + -0.01604104065157868, + 0.010376786273973133, + 0.014122038833203628, + 0.008641365746408176, + 0.004176981844803722, + 0.0018557930308154783, + 0.0007890167735032168, }; static const float c4_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.3213858349988003e-05,6.232838199801025e-05,0.0001632037964535633,0.0003928983460811959,0.0007341577078787206,0.0003053082875419616,-0.003254838747910248,-0.004021655986643196, -0.004258314078650583,0.0030578644020607566,-0.00037014803880675387,-0.0007265964578827031,-0.0003849331969038772,-0.00015947916435728337,-6.171511304866758e-05,-2.319341439172678e-05, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.3213858349988003e-05, + 6.232838199801025e-05, + 0.0001632037964535633, + 0.0003928983460811959, + 0.0007341577078787206, + 0.0003053082875419616, + -0.003254838747910248, + -0.004021655986643196, + 0.004258314078650583, + 0.0030578644020607566, + -0.00037014803880675387, + -0.0007265964578827031, + -0.0003849331969038772, + -0.00015947916435728337, + -6.171511304866758e-05, + -2.319341439172678e-05, }; /** @@ -151,8 +288,7 @@ static const float c4_coeffs[32] __attribute__((aligned(VLEN))) = * @param[in] length Number of elements in input/output arrays. * @return Returns 0 on successful execution. Otherwise -1. */ -int32_t hvx_silu_af(float *restrict input, float *restrict output, uint32_t size) -{ +int32_t hvx_silu_af(float *restrict input, float *restrict output, uint32_t size) { HVX_Vector *input_v_ptr; HVX_UVector *output_v_ptr; HVX_Vector input_min_v_f; @@ -191,13 +327,12 @@ int32_t hvx_silu_af(float *restrict input, float *restrict output, uint32_t size HVX_Vector f8, f_8; /* Check input arguments. Return error status if some argument has invalid value */ - if ((input == 0) || (output == 0) || (size == 0)) - { + if ((input == 0) || (output == 0) || (size == 0)) { return -1; } - input_v_ptr = (HVX_Vector *) input; - output_v_ptr = (HVX_UVector *) output; + input_v_ptr = (HVX_Vector *)input; + output_v_ptr = (HVX_UVector *)output; f8 = Q6_V_vsplat_R(float_to_bits(8.0f)); f_8 = Q6_V_vsplat_R(float_to_bits(-8.0f)); @@ -267,23 +402,20 @@ int32_t hvx_silu_af(float *restrict input, float *restrict output, uint32_t size * Handle number of whole vectors in input data. * Don't process last vector in order to avoid out-of-boundary load. */ - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(input_v_ptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } /* Process one vector at a time */ - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { slinec = *input_v_ptr++; /* Compose vector of input data from slinec and slinep */ - sline = Q6_V_valign_VVR(slinec, slinep, (size_t) input); + sline = Q6_V_valign_VVR(slinec, slinep, (size_t)input); /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ input_shifted_v_qf32 = Q6_Vqf32_vsub_VsfVsf(sline, input_min_v_f); @@ -340,7 +472,7 @@ int32_t hvx_silu_af(float *restrict input, float *restrict output, uint32_t size // x * sigmod output_v = Q6_Vqf32_vmpy_Vqf32Vqf32(input_v_qf32, output_v); - + HVX_Vector out_v = Q6_Vsf_equals_Vqf32(output_v); HVX_VectorPred islf8 = Q6_Q_vcmp_gt_VsfVsf(sline, f8); @@ -349,7 +481,6 @@ int32_t hvx_silu_af(float *restrict input, float *restrict output, uint32_t size HVX_VectorPred islf_8 = Q6_Q_vcmp_gt_VsfVsf(f_8, sline); out_v = Q6_V_vmux_QVV(islf_8, zero_v_sf, out_v); - /* Store results to the output buffer and convert from qf32 to sf */ *((HVX_UVector *)(output_v_ptr++)) = out_v; @@ -359,10 +490,9 @@ int32_t hvx_silu_af(float *restrict input, float *restrict output, uint32_t size } /* Handle last whole vector from input data */ - if (vectors_in_rounddown > 0) - { + if (vectors_in_rounddown > 0) { slinec = is_aligned(input_v_ptr, VLEN) && leftover == 0 ? slinep : *input_v_ptr++; - sline = Q6_V_valign_VVR(slinec, slinep, (size_t) input); + sline = Q6_V_valign_VVR(slinec, slinep, (size_t)input); /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ input_shifted_v_qf32 = Q6_Vqf32_vsub_VsfVsf(sline, input_min_v_f); @@ -433,13 +563,10 @@ int32_t hvx_silu_af(float *restrict input, float *restrict output, uint32_t size } /* Handle leftover elements */ - if (leftover > 0) - { - slinec = (is_in_one_chunk(input_v_ptr, leftover_size, VLEN) - ? slinep - : *input_v_ptr++); + if (leftover > 0) { + slinec = (is_in_one_chunk(input_v_ptr, leftover_size, VLEN) ? slinep : *input_v_ptr++); - sline = Q6_V_valign_VVR(slinec, slinep, (size_t) input); + sline = Q6_V_valign_VVR(slinec, slinep, (size_t)input); /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ input_shifted_v_qf32 = Q6_Vqf32_vsub_VsfVsf(sline, input_min_v_f); @@ -510,41 +637,180 @@ int32_t hvx_silu_af(float *restrict input, float *restrict output, uint32_t size return 0; } - static const float fp16_c0_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.13239719960243818,0.2216255210749415,0.3447664743728659,0.48137452032585476,0.5716299228719798,0.5547323231605259,0.5046287748870234,0.4999985574626892, -0.5000036514755082,0.49475652448004626,0.4441393352532763,0.428500379952032,0.5173297285470642,0.6541461039833616,0.7783931007462818,0.8678015179911097, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.13239719960243818, + 0.2216255210749415, + 0.3447664743728659, + 0.48137452032585476, + 0.5716299228719798, + 0.5547323231605259, + 0.5046287748870234, + 0.4999985574626892, + 0.5000036514755082, + 0.49475652448004626, + 0.4441393352532763, + 0.428500379952032, + 0.5173297285470642, + 0.6541461039833616, + 0.7783931007462818, + 0.8678015179911097, }; static const float fp16_c1_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.05928005756790343,0.11063222460270064,0.1932879057003057,0.30302440212086995,0.3922924462181049,0.36546332659415875,0.2644148210990377,0.24989020912329707, -0.2498532691910313,0.2661055781198988,0.36728015359480604,0.39215270010450015,0.3041825601732039,0.1940762094668647,0.11061794856987572,0.059174800917353595, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.05928005756790343, + 0.11063222460270064, + 0.1932879057003057, + 0.30302440212086995, + 0.3922924462181049, + 0.36546332659415875, + 0.2644148210990377, + 0.24989020912329707, + 0.2498532691910313, + 0.2661055781198988, + 0.36728015359480604, + 0.39215270010450015, + 0.3041825601732039, + 0.1940762094668647, + 0.11061794856987572, + 0.059174800917353595, }; static const float fp16_c2_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.010145494303219278,0.02123968384425681,0.04207468332514667,0.07519946712591977,0.10840620196267145,0.09270738184406795,0.015322371881818012,-0.0009948273994921822, -0.0011544907060402412,-0.017040517565094934,-0.09379878876657094,-0.10835043868732394,-0.07558705272699548,-0.04228875316413285,-0.021235740718738055,-0.010124599879590107, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.010145494303219278, + 0.02123968384425681, + 0.04207468332514667, + 0.07519946712591977, + 0.10840620196267145, + 0.09270738184406795, + 0.015322371881818012, + -0.0009948273994921822, + 0.0011544907060402412, + -0.017040517565094934, + -0.09379878876657094, + -0.10835043868732394, + -0.07558705272699548, + -0.04228875316413285, + -0.021235740718738055, + -0.010124599879590107, }; static const float fp16_c3_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.0007841223015974933,0.001850453397354219,0.004187899308371771,0.008640952434084206,0.01414741414964877,0.010117749275618,-0.01654848996354919,-0.02395108399453624, --0.024199111971064446,-0.015783556879607072,0.010407672131558174,0.014137608186323335,0.008698510795258909,0.004213708431213342,0.0018499827774393985,0.0007822799742289481, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0007841223015974933, + 0.001850453397354219, + 0.004187899308371771, + 0.008640952434084206, + 0.01414741414964877, + 0.010117749275618, + -0.01654848996354919, + -0.02395108399453624, + -0.024199111971064446, + -0.015783556879607072, + 0.010407672131558174, + 0.014137608186323335, + 0.008698510795258909, + 0.004213708431213342, + 0.0018499827774393985, + 0.0007822799742289481, }; static const float fp16_c4_coeffs[32] __attribute__((aligned(VLEN))) = -{ - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -2.3031641204975905e-05,6.150442488966733e-05,0.00015997783736818624,0.00038491646239693526,0.0007283649599237781,0.00034439150914392054,-0.003142246198646662,-0.004120389580321761, -0.004246050162553198,0.0030162727520777893,-0.00037312974308425725,-0.0007277242855014247,-0.00038811687679772674,-0.0001611434776868886,-6.14837984586862e-05,-2.297076123375133e-05, + { + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.3031641204975905e-05, + 6.150442488966733e-05, + 0.00015997783736818624, + 0.00038491646239693526, + 0.0007283649599237781, + 0.00034439150914392054, + -0.003142246198646662, + -0.004120389580321761, + 0.004246050162553198, + 0.0030162727520777893, + -0.00037312974308425725, + -0.0007277242855014247, + -0.00038811687679772674, + -0.0001611434776868886, + -6.14837984586862e-05, + -2.297076123375133e-05, }; /** @@ -554,8 +820,7 @@ static const float fp16_c4_coeffs[32] __attribute__((aligned(VLEN))) = * @param[in] length Number of elements in input/output arrays. * @return Returns 0 on successful execution. Otherwise -1. */ -int32_t hvx_silu_ahf(__fp16 *restrict input, __fp16 *restrict output, uint32_t size) -{ +int32_t hvx_silu_ahf(__fp16 *restrict input, __fp16 *restrict output, uint32_t size) { HVX_Vector *input_v_ptr; HVX_UVector *output_v_ptr; HVX_Vector input_min_v_hf; @@ -594,13 +859,12 @@ int32_t hvx_silu_ahf(__fp16 *restrict input, __fp16 *restrict output, uint32_t s HVX_Vector c4_coeff_v; /* Check input arguments. Return error status if some argument has invalid value */ - if ((input == 0) || (output == 0) || (size == 0)) - { + if ((input == 0) || (output == 0) || (size == 0)) { return -1; } - input_v_ptr = (HVX_Vector *) input; - output_v_ptr = (HVX_UVector *) output; + input_v_ptr = (HVX_Vector *)input; + output_v_ptr = (HVX_UVector *)output; /* * If input data is not aligned to HVX vector size, compose aligned vectors @@ -671,19 +935,16 @@ int32_t hvx_silu_ahf(__fp16 *restrict input, __fp16 *restrict output, uint32_t s * Handle number of whole vectors in input data. * Don't process last vector in order to avoid out-of-boundary load. */ - for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) - { + for (int32_t i = vectors_in_rounddown - 1; i > 0; i -= BLOCK_SIZE) { block = Q6_R_min_RR(i, BLOCK_SIZE); l2fetch_block = Q6_R_min_RR(i - L2FETCH_AHEAD, BLOCK_SIZE); - if (l2fetch_block > 0) - { + if (l2fetch_block > 0) { l2fetch(input_v_ptr + L2FETCH_AHEAD, VLEN, VLEN, l2fetch_block, 0); } /* Process one vector at a time */ - for (int32_t j = 0; j < block; ++j) - { + for (int32_t j = 0; j < block; ++j) { slinec = *input_v_ptr++; /* Compose vector of input data from slinec and slinep */ @@ -776,17 +1037,15 @@ int32_t hvx_silu_ahf(__fp16 *restrict input, __fp16 *restrict output, uint32_t s // output_v = Q6_Vqf16_vmpy_Vqf16Vqf16(output_v, input_v_qf16); // *output_v_ptr++ = Q6_Vhf_equals_Vqf16(output_v); - /* Prepare slinep for next iteration */ slinep = slinec; } } /* Handle last whole vector from input data */ - if (vectors_in_rounddown > 0) - { + if (vectors_in_rounddown > 0) { slinec = is_aligned(input_v_ptr, VLEN) && leftover == 0 ? slinep : *input_v_ptr++; - sline = Q6_V_valign_VVR(slinec, slinep, (size_t) input); + sline = Q6_V_valign_VVR(slinec, slinep, (size_t)input); tmp_v = Q6_Vh_vdeal_Vh(sline); /* Shift input range from [input_min, input_max] to [0, input_max - input_min] */ input_shifted_v_hf = Q6_Vqf16_vsub_VhfVhf(tmp_v, input_min_v_hf); @@ -862,11 +1121,8 @@ int32_t hvx_silu_ahf(__fp16 *restrict input, __fp16 *restrict output, uint32_t s } /* Handle leftover elements */ - if (leftover > 0) - { - slinec = (is_in_one_chunk(input_v_ptr, leftover_size, VLEN) - ? slinep - : *input_v_ptr++); + if (leftover > 0) { + slinec = (is_in_one_chunk(input_v_ptr, leftover_size, VLEN) ? slinep : *input_v_ptr++); sline = Q6_V_valign_VVR(slinec, slinep, (size_t)input); tmp_v = Q6_Vh_vdeal_Vh(sline); @@ -949,124 +1205,110 @@ int32_t hvx_silu_ahf(__fp16 *restrict input, __fp16 *restrict output, uint32_t s #endif -template -GraphStatus siluImpl(TensorType& out_0, - const TensorType& in_0) +template +GraphStatus siluImpl(TensorType &out_0, + const TensorType &in_0) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ #ifdef REFERENCE_OP - debuglog("silu execute... inval=(%d)", in_0.get_dtype()); - debuglog("silu execute... inval=(%d)", out_0.get_dtype()); - + debuglog("silu execute... inval=(%d)", in_0.get_dtype()); + debuglog("silu execute... inval=(%d)", out_0.get_dtype()); + out_0.set_dims(in_0); // NHWC auto [b_in, h_in, w_in, d_in] = in_0.dims(); for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // SiLU - for (Idx d = 0; d < d_in; d++) { - float inval = in_0(b, h, w, d); - float outval = 1 / (1 + expf(-inval)); - - - debuglog("silu execute... inval=(%f)", inval); - debuglog("silu execute... outval=(%f)", outval); - - out_0(b, h, w, d) = inval * outval; - - } + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // SiLU + for (Idx d = 0; d < d_in; d++) { + float inval = in_0(b, h, w, d); + float outval = 1 / (1 + expf(-inval)); + + debuglog("silu execute... inval=(%f)", inval); + debuglog("silu execute... outval=(%f)", outval); + + out_0(b, h, w, d) = inval * outval; + } + } } - } } #else // HVX Method -- FP32 Version out_0.set_dims(in_0); - + DType dtype = in_0.get_dtype(); auto [b_in, h_in, w_in, d_in] = in_0.dims(); + size_t size = b_in * h_in * w_in * d_in; - size_t size = b_in*h_in*w_in*d_in; - // Noticable size >= 128 - + // SiLU inval / (1 + expf(-inval)); // sigmod 1.0/(exp(-x)+1.0) // SiLU inval * sigmod if (dtype == DType::Float16) { - - // NHWC - auto in_ptr = (__fp16*)in_0.raw_data_const(); - auto out_ptr = (__fp16*)out_0.raw_data(); - hvx_silu_ahf(in_ptr, out_ptr, size); + // NHWC + auto in_ptr = (__fp16 *)in_0.raw_data_const(); + auto out_ptr = (__fp16 *)out_0.raw_data(); + hvx_silu_ahf(in_ptr, out_ptr, size); } else { - // NHWC - auto in_ptr = (float*)in_0.raw_data_const(); - auto out_ptr = (float*)out_0.raw_data(); - hvx_silu_af(in_ptr, out_ptr, size); + // NHWC + auto in_ptr = (float *)in_0.raw_data_const(); + auto out_ptr = (float *)out_0.raw_data(); + hvx_silu_af(in_ptr, out_ptr, size); } return GraphStatus::Success; - - #endif #ifdef DEBUG for (Idx b = 0; b < b_in; b++) { - for (Idx h = 0; h < h_in; h++) { - for (Idx w = 0; w < w_in; w++) { - // SiLU - for (Idx d = 0; d < d_in; d++) { - float out_value = out_0(b, h, w, d); - debuglog("silu execute... outval=(%f)", out_value); - - } + for (Idx h = 0; h < h_in; h++) { + for (Idx w = 0; w < w_in; w++) { + // SiLU + for (Idx d = 0; d < d_in; d++) { + float out_value = out_0(b, h, w, d); + debuglog("silu execute... outval=(%f)", out_value); + } + } } - } } - -#endif - +#endif - return GraphStatus::Success; + return GraphStatus::Success; } -__attribute__((unused)) static float siluCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float siluCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/SplitInput.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/SplitInput.cpp index f055afc51..b33decb01 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/SplitInput.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/SplitInput.cpp @@ -9,17 +9,15 @@ #include "QnnOpPackage.h" #include "HTP/core/simple_reg.h" - BEGIN_PKG_OP_DEFINITION(PKG_SplitInput); - // op execute function declarations -template -GraphStatus splitinputImpl(TensorType& out_0, - TensorType& out_1, - const TensorType& in_0, +template +GraphStatus splitinputImpl(TensorType &out_0, + TensorType &out_1, + const TensorType &in_0, const TensorType1 &in_1, - const Tensor& num); + const Tensor &num); // forward declaration of sample cost function static float splitinputCostFunc(const Op *op); @@ -64,11 +62,11 @@ DEF_PACKAGE_OP((splitinputImpl), "SplitInput") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -82,84 +80,74 @@ DEF_PACKAGE_OP((splitinputImpl), "SplitInput") * Qnn_addNode */ - /* execute functions for ops */ -template -GraphStatus splitinputImpl(TensorType& out_0, - TensorType& out_1, - const TensorType& in_0, +template +GraphStatus splitinputImpl(TensorType &out_0, + TensorType &out_1, + const TensorType &in_0, const TensorType1 &in_1, - const Tensor& num) -{ - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - // default is two. - - size_t o_size = in_1(0,0,0,0); - size_t x_size = in_1(0,0,0,1); + const Tensor &num) { + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - const size_t dims_0[] = {b_in, o_size, w_in, d_in}; - const size_t dims_1[] = {b_in, x_size, w_in, d_in}; + // default is two. - out_0.set_dims(dims_0); - out_1.set_dims(dims_1); + size_t o_size = in_1(0, 0, 0, 0); + size_t x_size = in_1(0, 0, 0, 1); - DType dtype = in_0.get_dtype(); - uint32_t bitwidth = 4; + auto [b_in, h_in, w_in, d_in] = in_0.dims(); - if (dtype == DType::QUInt8 || dtype == DType::QInt8) { + const size_t dims_0[] = {b_in, o_size, w_in, d_in}; + const size_t dims_1[] = {b_in, x_size, w_in, d_in}; - bitwidth = 1; + out_0.set_dims(dims_0); + out_1.set_dims(dims_1); - } else if (dtype == DType::Float16) { + DType dtype = in_0.get_dtype(); + uint32_t bitwidth = 4; - bitwidth = 2; - } else if (dtype == DType::Float32) { + if (dtype == DType::QUInt8 || dtype == DType::QInt8) { + bitwidth = 1; - bitwidth = 4; - } + } else if (dtype == DType::Float16) { + bitwidth = 2; + } else if (dtype == DType::Float32) { + bitwidth = 4; + } - const uint8_t *in_ptr = (uint8_t*)in_0.raw_data_const(); + const uint8_t *in_ptr = (uint8_t *)in_0.raw_data_const(); - uint8_t *out_ptr_0 = (uint8_t*)out_0.raw_data(); - uint8_t *out_ptr_1 = (uint8_t*)out_1.raw_data(); + uint8_t *out_ptr_0 = (uint8_t *)out_0.raw_data(); + uint8_t *out_ptr_1 = (uint8_t *)out_1.raw_data(); - memcpy(out_ptr_0, in_ptr, b_in * o_size * w_in * d_in * bitwidth); - in_ptr += b_in * o_size * w_in * d_in * bitwidth; + memcpy(out_ptr_0, in_ptr, b_in * o_size * w_in * d_in * bitwidth); + in_ptr += b_in * o_size * w_in * d_in * bitwidth; - memcpy(out_ptr_1, in_ptr, b_in * x_size * w_in * d_in * bitwidth * 4); + memcpy(out_ptr_1, in_ptr, b_in * x_size * w_in * d_in * bitwidth * 4); - return GraphStatus::Success; + return GraphStatus::Success; } -__attribute__((unused)) static float splitinputCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float splitinputCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/WNop.cpp b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/WNop.cpp index 547e53589..2a7c1fd1a 100755 --- a/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/WNop.cpp +++ b/src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/WNop.cpp @@ -12,17 +12,15 @@ #include #include - BEGIN_PKG_OP_DEFINITION(PKG_WNop); - // op execute function declarations -template -GraphStatus wnopImpl(TensorType& out_0, - TensorType1 &sync_var, - const TensorType& in_0, - const TensorType& in_1, - const Tensor& sync_type); +template +GraphStatus wnopImpl(TensorType &out_0, + TensorType1 &sync_var, + const TensorType &in_0, + const TensorType &in_1, + const Tensor &sync_type); // forward declaration of sample cost function static float wnopCostFunc(const Op *op); @@ -67,11 +65,11 @@ DEF_PACKAGE_OP((wnopImpl), "WNop") * one definition per op, and this is optional * syntax: DEF_PACKAGE_PARAM_ORDER(OP,PARAM1,MANDATORY1,DEFAULT1,PARAM2,MANDATORY2,DEFAULT2...) * one or more parameters can be specified for each op - * order of parameters listed determines the order of parameters passed into op execution functions + * order of parameters listed determines the order of parameters passed into op execution functions * if an op does not have a parameter order definition, parameter order passed into Qnn_addNode * will be passed into op execution functions * if an op has a parameter order definition, any parameter passed into Qnn_addNode with unlisted - * name will be abandoned + * name will be abandoned * if two or more op packages with the same package name will be registered, they cannot list * conflicting parameter orders * PARAM refers to parameter name as a string literal @@ -84,109 +82,88 @@ DEF_PACKAGE_OP((wnopImpl), "WNop") * graph construction will skip this parameter when this parameter is not provided at * Qnn_addNode */ -DEF_PACKAGE_PARAM_ORDER("WNop", +DEF_PACKAGE_PARAM_ORDER("WNop", "sync_type", true, nullptr) - /* execute functions for ops */ -template -GraphStatus wnopImpl(TensorType& out_0, - TensorType1 &sync_var, - const TensorType& in_0, - const TensorType& in_1, - const Tensor& sync_type) +template +GraphStatus wnopImpl(TensorType &out_0, + TensorType1 &sync_var, + const TensorType &in_0, + const TensorType &in_1, + const Tensor &sync_type) { - /* - * add code here - * */ - /* - * To have good performance and stability, it is required to avoid heap memory - * allocation in this function. The heap memory allocation includes but not - * limited to calling malloc, operator new, constructing STL container objects - * like std::vector with default allocator, and adding items like calling - * std::vector::push_back to STL container objects with default allocator. - * - * Please check in SDK documentation for more information. - */ - - - out_0.set_dims(in_0); - - auto sync_type_ = sync_type(0,0,0,0); - - - // sync_type == 0 sending signal to CPU - // sync_type == 1 waiting signal from CPU - - DType dtype = in_0.get_dtype(); - uint32_t bitwidth = 4; - - if (dtype == DType::QUInt8) { - + /* + * add code here + * */ + /* + * To have good performance and stability, it is required to avoid heap memory + * allocation in this function. The heap memory allocation includes but not + * limited to calling malloc, operator new, constructing STL container objects + * like std::vector with default allocator, and adding items like calling + * std::vector::push_back to STL container objects with default allocator. + * + * Please check in SDK documentation for more information. + */ + + out_0.set_dims(in_0); + + auto sync_type_ = sync_type(0, 0, 0, 0); + + // sync_type == 0 sending signal to CPU + // sync_type == 1 waiting signal from CPU + + DType dtype = in_0.get_dtype(); + uint32_t bitwidth = 4; + + if (dtype == DType::QUInt8) { bitwidth = 1; } else if (dtype == DType::Float16) { - bitwidth = 2; } else if (dtype == DType::Float32) { - bitwidth = 4; } - if (sync_type_ == 0) { - - auto [b_in, h_in, w_in, d_in] = in_0.dims(); + if (sync_type_ == 0) { + auto [b_in, h_in, w_in, d_in] = in_0.dims(); - auto in_ptr = (void*)in_0.raw_data_const(); - auto out_ptr = (void*)out_0.raw_data(); + auto in_ptr = (void *)in_0.raw_data_const(); + auto out_ptr = (void *)out_0.raw_data(); - memcpy(out_ptr, in_ptr, b_in * h_in * w_in * d_in * bitwidth); + memcpy(out_ptr, in_ptr, b_in * h_in * w_in * d_in * bitwidth); - sync_var(0,0,0,0) = 1; + sync_var(0, 0, 0, 0) = 1; - } else if (sync_type_ == 1) { + } else if (sync_type_ == 1) { + while (in_1(0, 0, 0, 0) == 0) { + Q6_V_vzero(); + } - while (in_1(0,0,0,0) == 0) { + auto [b_in, h_in, w_in, d_in] = in_0.dims(); - Q6_V_vzero(); + auto in_ptr = (void *)in_0.raw_data_const(); + auto out_ptr = (void *)out_0.raw_data(); + memcpy(out_ptr, in_ptr, b_in * h_in * w_in * d_in * bitwidth); } - auto [b_in, h_in, w_in, d_in] = in_0.dims(); - - auto in_ptr = (void*)in_0.raw_data_const(); - auto out_ptr = (void*)out_0.raw_data(); - - memcpy(out_ptr, in_ptr, b_in * h_in * w_in * d_in * bitwidth); - - } - - - - - - - return GraphStatus::Success; + return GraphStatus::Success; } -__attribute__((unused)) static float wnopCostFunc(const Op *op) -{ - /* - * add code here - * */ +__attribute__((unused)) static float wnopCostFunc(const Op *op) { + /* + * add code here + * */ - float cost = 0.0; // add cost computation here - return cost; + float cost = 0.0; // add cost computation here + return cost; } - - - - /* At the bottom of the op file, call END_PKG_OP_DEFINITION(), where is as BEGIN_PKG_OP_DEFINITION */ diff --git a/src/backends/qnn/Model/QnnModel.cpp b/src/backends/qnn/Model/QnnModel.cpp index 32adae185..7a2d91a68 100644 --- a/src/backends/qnn/Model/QnnModel.cpp +++ b/src/backends/qnn/Model/QnnModel.cpp @@ -14,6 +14,7 @@ #include "QnnModel.hpp" #include "QnnModelPal.hpp" #include "QnnTypeMacros.hpp" +#include "Utils/QnnSampleAppUtils.hpp" #define FREE_MEMORY(ptr1, ptr2, ptr3) \ do { \ @@ -72,6 +73,10 @@ ModelError_t QnnModel::initialize(const Qnn_BackendHandle_t &backendHandle, return MODEL_NO_ERROR; } +void QnnModel::setInitFromCache() { + isFromCache = true; +} + ModelError_t QnnModel::addTensor(const char *nodeName, Qnn_Tensor_t *tensor, bool saveTensor) { ModelError_t err; if (!tensor) { @@ -152,16 +157,20 @@ ModelError_t QnnModel::addTensor(const char *nodeName, Qnn_Tensor_t *tensor, boo QNN_TENSOR_SET_TYPE(tensor, QNN_TENSOR_TYPE_APP_READ); } - if (m_qnnInterface.tensorCreateGraphTensor(m_graph, tensor) != QNN_TENSOR_NO_ERROR) { - PRINT_ERROR("QnnModel::addTensor() Creating tensor for node: %s, tensorName: %s.\n", - nodeName, - QNN_TENSOR_GET_NAME(tensor)); - return MODEL_TENSOR_ERROR; + if (!isFromCache) { + if (m_qnnInterface.tensorCreateGraphTensor(m_graph, tensor) != QNN_TENSOR_NO_ERROR) { + PRINT_ERROR("QnnModel::addTensor() Creating tensor for node: %s, tensorName: %s.\n", + nodeName, + QNN_TENSOR_GET_NAME(tensor)); + return MODEL_TENSOR_ERROR; + } } if (saveTensor) { Qnn_Tensor_t tensorCopy; - VALIDATE(deepCopyQnnTensors(*tensor, tensorCopy), err); + if (!qnn::tools::sample_app::deepCopyQnnTensorInfo(&tensorCopy, tensor)) { + return MODEL_TENSOR_ERROR; + } // save network input/outputs tensors to use for setting the Qnn graph's input and output // tensors for populating GraphInfo_t for caller @@ -509,6 +518,16 @@ ModelError_t QnnModel::finalize(Qnn_ProfileHandle_t profile, Qnn_SignalHandle_t return err; } +size_t memscpy(void *dst, size_t dstSize, const void *src, size_t copySize) { + if (!dst || !src || !dstSize || !copySize) return 0; + + size_t minSize = dstSize < copySize ? dstSize : copySize; + + memcpy(dst, src, minSize); + + return minSize; +} + ModelError_t getGraphInfoFromModels(QnnModel *models, uint32_t numModels, GraphInfoPtr_t **graphsInfo) { @@ -611,25 +630,6 @@ ModelError_t getSingleGraphInfoFromModel(QnnModel &model, GraphInfoPtr_t* graphI return err; } -ModelError_t freeGraphsInfo(GraphInfoPtr_t **graphsInfo, uint32_t numGraphs) { - if (graphsInfo == nullptr || *graphsInfo == nullptr) { - PRINT_ERROR("freeGraphsInfo() invalid graphsInfo."); - return MODEL_TENSOR_ERROR; - } - for (uint32_t i = 0; i < numGraphs; i++) { - PRINT_INFO("Freeing graph in freeGraphInfo"); - free((*graphsInfo)[i]->graphName); - freeQnnTensors((*graphsInfo)[i]->inputTensors, (*graphsInfo)[i]->numInputTensors); - freeQnnTensors((*graphsInfo)[i]->outputTensors, (*graphsInfo)[i]->numOutputTensors); - } - - free(**graphsInfo); - free(*graphsInfo); - *graphsInfo = nullptr; - - return MODEL_NO_ERROR; -} - ModelError_t QnnModel::freeTensors() { for (std::map::iterator tensorIt = m_modelTensorsMap.begin(); diff --git a/src/backends/qnn/Model/QnnModel.hpp b/src/backends/qnn/Model/QnnModel.hpp index 6521d76e5..1823c49c8 100644 --- a/src/backends/qnn/Model/QnnModel.hpp +++ b/src/backends/qnn/Model/QnnModel.hpp @@ -55,6 +55,8 @@ class QnnModel { uint8_t doNodeValidations = 1, const QnnGraph_Config_t** graphConfigs = nullptr); + void setInitFromCache(); + /** * @brief A wrapper function to create a tensor inside class's context graph. * @@ -226,7 +228,7 @@ class QnnModel { bool m_debug = false; // flag to indicate if requested graph is to be run in debug mode // (i.e. all intermediate tensors will be accessible to client) // flag to indicate whether all addNode calls need to be validated - bool m_doNodeValidations = true; + bool m_doNodeValidations = true, isFromCache = false; std::vector m_modelInputTensors; std::vector m_modelOutputTensors; @@ -266,5 +268,4 @@ ModelError_t getSingleGraphInfoFromModel(QnnModel &model, GraphInfoPtr_t* graphI * @return Error code * */ -ModelError_t freeGraphsInfo(GraphInfoPtr_t** graphsInfo, uint32_t numGraphs); } // namespace qnn_wrapper_api diff --git a/src/backends/qnn/QNNBackend.cpp b/src/backends/qnn/QNNBackend.cpp index 69b112831..793a21b06 100755 --- a/src/backends/qnn/QNNBackend.cpp +++ b/src/backends/qnn/QNNBackend.cpp @@ -20,6 +20,7 @@ #include "QnnTypes.h" #include "HTP/QnnHtpGraph.h" #include "Layer.hpp" +#include "Layer.hpp" #include "Types.hpp" #include "op/QNNAdd.hpp" @@ -34,6 +35,8 @@ #include "op/QNNScale.hpp" #include "op/QNNSiLU.hpp" #include "op/QNNSoftMax.hpp" +#include "op/QNNSubGraphFinalize.hpp" +#include "op/QNNSubGraphStart.hpp" #include "op/QNNView.hpp" #include "op/QNNReLU.hpp" #include "op/QNNQuantize.hpp" @@ -86,6 +89,8 @@ void QNNBackend::registerOps() { addCreator(SPLITINPUT, (QNNBackend::Creator *)(new QNNSplitInputCreator())); addCreator(TRANSPOSE, (QNNBackend::Creator *)(new QNNTransposeCreator())); addCreator(SUPERSILU, (QNNBackend::Creator *)(new QNNSuperSiLUCreator())); + addCreator(SUBGRAPHSTART, (QNNBackend::Creator *)(new QNNSubGraphStartCreator())); + addCreator(SUBGRAPHFINALIZE, (QNNBackend::Creator *)(new QNNSubGraphFinalizeCreator())); } QNNBackend::QNNBackend(shared_ptr mm) : @@ -185,6 +190,23 @@ QNNBackend::QNNBackend(shared_ptr mm) : // register ops this->registerOps(); + + // check if the qnn_context.bin file exists + if (!std::filesystem::exists("qnn_context.bin")) { + // create qnn context + if (StatusCode::SUCCESS != this->createContext()) { + this->reportError("Context Creation failure"); + } + } else { + if (StatusCode::SUCCESS != this->retrieveQNNContext()) { + this->reportError("Context Retieve failure"); + } + } + // assign context to qnn memory manager +#ifdef QNN_ARM + auto qnnMM = std::static_pointer_cast(mem_manager_); + qnnMM->setQnnInterfaceAndContext(m_context); +#endif } QNNBackend::~QNNBackend() { @@ -215,14 +237,6 @@ void QNNBackend::onSetUpStart(vector> &inputs, vectorcreateContext()) { - this->reportError("Context Creation failure"); - } -#ifdef QNN_ARM - auto qnnMM = std::static_pointer_cast(mem_manager_); - qnnMM->setQnnInterfaceAndContext(m_context); -#endif // initialize qnn graph info, set graph info, graph count // NOTE: currently not using it @@ -240,21 +254,22 @@ void QNNBackend::onSetUpStart(vector> &inputs, vectorreportError("Graph Config Info failure"); + if (!isFromCache) { + err = qnnModels_[qnnModelIndex_].initialize(m_backendHandle, + m_qnnFunctionPointers.qnnInterface, + m_context, + graphName.c_str(), + m_debug, + DO_GRAPH_NODE_VALIDATIONS, + graphConfigs); + } else { + // set init from cache, the input and output tensor info still needs the QnnModel to maintain + // setting this is to avoid the tensor creation in the qnn graph + qnnModels_[qnnModelIndex_].setInitFromCache(); } - err = qnnModels_[qnnModelIndex_].initialize(m_backendHandle, - m_qnnFunctionPointers.qnnInterface, - m_context, - graphName.c_str(), - m_debug, - DO_GRAPH_NODE_VALIDATIONS, - graphConfigs); if (err != qnn_wrapper_api::MODEL_NO_ERROR) { this->reportError("Graph Initialization failure: " + graphName); } @@ -281,6 +296,9 @@ void QNNBackend::onSetUpStart(vector> &inputs, vector> &inputs, vectorload(&scaleTensor); - scale = roundf(scaleTensor.hostPtr()[0] / 127.0 * 100000) / 100000; + // scale = roundf(scaleTensor.hostPtr()[0] / (pow(2, 7) - 1) * 100000) / 100000; + scale = scaleTensor.hostPtr()[0] / (pow(2, 7) - 1); + scaleTensor.free(); + + break; + } + case MLLM_TYPE_I16: { + data_type = QNN_DATATYPE_SFIXED_POINT_16; + quantizeDefined = QNN_DEFINITION_DEFINED; + quantizeType = QNN_QUANTIZATION_ENCODING_SCALE_OFFSET; + + string scaleName = input->name(); + + std::string wordToRemove = "outtensor-"; + int pos = scaleName.find(wordToRemove); + if (pos != -1) { // old frontend merge/split generated tensor + scaleName = scaleName.substr(wordToRemove.length()); + wordToRemove = "or_split"; + if (scaleName.find(wordToRemove) != -1) { + pos = scaleName.find("or_split"); + // scaleName.erase(pos, wordToRemove.length()); + scaleName = scaleName.substr(0, pos); + // o + scaleName += "o_proj.input_scale"; + } else if (scaleName.find("ires_split") != -1) { + pos = scaleName.find("ires_split"); + wordToRemove = "ires_split"; + // scaleName.erase(pos, wordToRemove.length()); + scaleName = scaleName.substr(0, pos); + // q + scaleName += "q_proj.input_scale"; + } else if (scaleName.find("fres_split") != -1) { + pos = scaleName.find("fres_split"); + wordToRemove = "fres_split"; + // scaleName.erase(pos, wordToRemove.length()); + scaleName = scaleName.substr(0, pos); + // fc1 + scaleName += "up_proj.input_scale"; + } + } else { // new frontend no merge/split condition + std::string prefix = "out-", suffix = ".quantize"; + if (input->name().find(prefix) != std::string::npos) { + scaleName = input->name().substr(prefix.length()); + } + if (scaleName.find(suffix) != std::string::npos) { + scaleName = scaleName.substr(0, scaleName.length() - suffix.length()); + } + scaleName += ".input_scale"; + } + scaleTensor.setName(scaleName); + loader->load(&scaleTensor); + // scale = roundf(scaleTensor.hostPtr()[0] / (pow(2, 15) - 1) * 100000) / 100000; + scale = scaleTensor.hostPtr()[0] / (pow(2, 15) - 1); scaleTensor.free(); break; @@ -375,15 +445,37 @@ void QNNBackend::onSetUpStart(vector> &inputs, vectorgraph, m_profileBackendHandle, nullptr)) { + return qnn_wrapper_api::ModelError_t::MODEL_GRAPH_ERROR; + } + if (ProfilingLevel::OFF != m_profilingLevel) { + extractBackendProfilingInfo(m_profileBackendHandle); + } + graphsInfo_.push_back(graphInfo); + + return qnn_wrapper_api::ModelError_t::MODEL_NO_ERROR; +} + void QNNBackend::onSetUpEnd(vector> &inputs, vector> &outputs, string graphName) { - currentInputBuffers = &inputBufferMap[graphName]; - currentOutputBuffers = &outputBufferMap[graphName]; - qnnModelIndex_ = qnnModelIndexMap_[graphName]; - PRINT_MEMORY_USAGE("before graph finilize") - auto status = graphFinilize(); - PRINT_MEMORY_USAGE("after graph finilize") - if (qnn_wrapper_api::ModelError_t::MODEL_NO_ERROR != status) { - this->reportError("Graph Finalization failure"); + // currentInputBuffers = &inputBufferMap[graphName]; + // currentOutputBuffers = &outputBufferMap[graphName]; + // qnnModelIndex_ = qnnModelIndexMap_[graphName]; + + // online graph building, finalize graph + if (!isFromCache) { + PRINT_MEMORY_USAGE("before graph finilize") + auto status = graphFinilize(); + PRINT_MEMORY_USAGE("after graph finilize") + if (qnn_wrapper_api::ModelError_t::MODEL_NO_ERROR != status) { + this->reportError("Graph Finalization failure"); + } } auto returnStatus = StatusCode::SUCCESS; @@ -391,7 +483,7 @@ void QNNBackend::onSetUpEnd(vector> &inputs, vector> &inputs, vectornumInputTensors; i++) { qnnMM->registerQnnTensor((*currentInputBuffers)[i], qnnInputs[i]); #ifdef DEBUGPRINT - if (i < inputs.size()) { - std::cout << "\nregistered input tensor: " << inputs[i]->hostPtr() << " backend staged ptr: " << (void *)(*currentInputBuffers)[i] << std::endl; - } else { - std::cout << "\n registered op added input" << std::endl; - } + std::cout << "\nregistered input tensor backend staged ptr: " << (void *)(*currentInputBuffers)[i] << std::endl; std::cout << "qnn input tensor name: " << qnnInputs[i].v1.name << std::endl; std::cout << "qnn input tensor scale: " << qnnInputs[i].v1.quantizeParams.scaleOffsetEncoding.scale << std::endl; #endif @@ -424,18 +512,14 @@ void QNNBackend::onSetUpEnd(vector> &inputs, vectornumOutputTensors; i++) { qnnMM->registerQnnTensor((*currentOutputBuffers)[i], qnnOutputs[i]); #ifdef DEBUGPRINT - if (i < outputs.size()) { - std::cout << "\nregistered output tensor: " << outputs[i]->hostPtr() << " backend staged ptr: " << (void *)(*currentOutputBuffers)[i] << std::endl; - } else { - std::cout << "\n registered op added output" << std::endl; - } + std::cout << "\nregistered output tensor backend staged ptr: " << (void *)(*currentOutputBuffers)[i] << std::endl; std::cout << "qnn output tensor name: " << qnnOutputs[i].v1.name << std::endl; std::cout << "qnn output tensor scale: " << qnnOutputs[i].v1.quantizeParams.scaleOffsetEncoding.scale << std::endl; #endif } - inputsMap_[qnnModelIndex_] = qnnInputs; - outputsMap_[qnnModelIndex_] = qnnOutputs; + graphInfo->inputTensors = qnnInputs; + graphInfo->outputTensors = qnnOutputs; } void QNNBackend::onExecuteStart(vector> &inputs, vector> &outputs, string graphName) { @@ -443,10 +527,12 @@ void QNNBackend::onExecuteStart(vector> &inputs, vectorinputTensors; + // Qnn_Tensor_t *outputs_ = outputsMap_[t_qnnModelIndex_]; + Qnn_Tensor_t *outputs_ = graphInfo->outputTensors; Qnn_ErrorHandle_t executeStatus = QNN_GRAPH_NO_ERROR; #ifdef DEBUGPRINT @@ -502,9 +588,7 @@ void QNNBackend::afterAllGraphsExecute() { inputBufferMap.clear(); outputBufferMap.clear(); - graphInfoMap_.clear(); - inputsMap_.clear(); - outputsMap_.clear(); + graphsInfo_.clear(); } std::string QNNBackend::getBackendBuildId() { @@ -521,6 +605,14 @@ qnn_wrapper_api::ModelError_t QNNBackend::graphAddNode(string name, std::vector outputTensors, std::vector params, string packageName) { + if (isFromCache) { + for (auto &qnnTensor : outputTensors) { + if (qnnTensor.v1.type == QNN_TENSOR_TYPE_APP_READ) { + qnnModels_[qnnModelIndex_].addTensor(qnnTensor.v1.name, qnnTensor); + } + } + return qnn_wrapper_api::ModelError_t::MODEL_NO_ERROR; + } qnn_wrapper_api::ModelError_t err = qnn_wrapper_api::ModelError_t::MODEL_NO_ERROR; Qnn_Param_t *paramsPtr = nullptr; if (!params.empty()) { @@ -542,27 +634,10 @@ qnn_wrapper_api::ModelError_t QNNBackend::graphAddNode(string name, return err; } -qnn_wrapper_api::ModelError_t QNNBackend::graphFinilize() { - // Populate the constructed graphs in provided output variables - qnn_wrapper_api::ModelError_t err = qnn_wrapper_api::MODEL_NO_ERROR; - qnn_wrapper_api::GraphInfo_t *graphInfo = nullptr; - - VALIDATE(getSingleGraphInfoFromModel(qnnModels_[qnnModelIndex_], &graphInfo), err); - - // Graph finalize - if (QNN_GRAPH_NO_ERROR != m_qnnFunctionPointers.qnnInterface.graphFinalize(graphInfo->graph, m_profileBackendHandle, nullptr)) { - return qnn_wrapper_api::ModelError_t::MODEL_GRAPH_ERROR; - } - if (ProfilingLevel::OFF != m_profilingLevel) { - extractBackendProfilingInfo(m_profileBackendHandle); - } - - graphInfoMap_[qnnModelIndex_] = graphInfo; - - return qnn_wrapper_api::ModelError_t::MODEL_NO_ERROR; -} - qnn_wrapper_api::ModelError_t QNNBackend::modelAddTensor(std::string nodeName, Qnn_Tensor_t tensor) { + if (isFromCache && tensor.v1.type != QNN_TENSOR_TYPE_APP_READ) { + return qnn_wrapper_api::ModelError_t::MODEL_NO_ERROR; + } return qnnModels_[qnnModelIndex_].addTensor(nodeName.c_str(), tensor); } @@ -766,6 +841,85 @@ StatusCode QNNBackend::freeDevice() { return StatusCode::SUCCESS; } +void QNNBackend::saveQNNContext() { + uint64_t binarySize, writtenSize; + m_qnnFunctionPointers.qnnInterface.contextGetBinarySize(m_context, &binarySize); + + std::unique_ptr binaryBuffer(new uint8_t[binarySize]); + + m_qnnFunctionPointers.qnnInterface.contextGetBinary(m_context, reinterpret_cast(binaryBuffer.get()), binarySize, &writtenSize); + + if (binarySize < writtenSize) { + QNN_ERROR( + "Illegal written buffer size [%d] bytes. Cannot exceed allocated memory of [%d] bytes", + binarySize, + writtenSize); + } + std::ofstream file("qnn_context.bin", std::ios::binary); + file.write(reinterpret_cast(binaryBuffer.get()), writtenSize); + file.close(); + + std::cout << "QNN context saved to qnn_context.bin written " << writtenSize << std::endl; +} + +StatusCode QNNBackend::retrieveQNNContext() { + auto returnStatus = StatusCode::SUCCESS; + // load qnn system function pointers + if (dynamicloadutil::StatusCode::SUCCESS != dynamicloadutil::getQnnSystemFunctionPointers("libQnnSystem.so", &m_qnnFunctionPointers)) { + reportError("Error initializing QNN System Function Pointers"); + } + + // Read the binary from qnn_context.bin and get the size in byte + std::ifstream file("qnn_context.bin", std::ios::binary | std::ios::ate); + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + shared_ptr binaryBuffer(new uint8_t[size], std::default_delete()); + + file.read(reinterpret_cast(binaryBuffer.get()), size); + file.close(); + + // inspect binary info + + QnnSystemContext_Handle_t sysCtxHandle{nullptr}; + if (QNN_SUCCESS != m_qnnFunctionPointers.qnnSystemInterface.systemContextCreate(&sysCtxHandle)) { + QNN_ERROR("Could not create system handle."); + returnStatus = StatusCode::FAILURE; + } + const QnnSystemContext_BinaryInfo_t *binaryInfo{nullptr}; + Qnn_ContextBinarySize_t binaryInfoSize{0}; + if (StatusCode::SUCCESS == returnStatus && QNN_SUCCESS != m_qnnFunctionPointers.qnnSystemInterface.systemContextGetBinaryInfo(sysCtxHandle, static_cast(binaryBuffer.get()), size, &binaryInfo, &binaryInfoSize)) { + QNN_ERROR("Failed to get context binary info"); + returnStatus = StatusCode::FAILURE; + } + + qnn_wrapper_api::GraphInfo_t **graphsInfo = nullptr; + uint32_t graphNum; + // fill GraphInfo_t based on binary info + if (StatusCode::SUCCESS == returnStatus && !copyMetadataToGraphsInfo(binaryInfo, graphsInfo, graphNum)) { + QNN_ERROR("Failed to copy metadata."); + returnStatus = StatusCode::FAILURE; + } + m_qnnFunctionPointers.qnnSystemInterface.systemContextFree(sysCtxHandle); + sysCtxHandle = nullptr; + + graphsInfo_.assign(graphsInfo, graphsInfo + graphNum); + + Qnn_ContextBinarySize_t writtenSize = 0; + m_qnnFunctionPointers.qnnInterface.contextCreateFromBinary(m_backendHandle, m_deviceHandle, (const QnnContext_Config_t **)m_contextConfig, binaryBuffer.get(), size, &m_context, m_profileBackendHandle); + + for (auto &g : graphsInfo_) { + if (QNN_SUCCESS != m_qnnFunctionPointers.qnnInterface.graphRetrieve(m_context, g->graphName, &g->graph)) { + QNN_ERROR("Unable to retrieve graph handle"); + returnStatus = StatusCode::FAILURE; + } + } + + this->isFromCache = true; + + MLLM_LOG_INFO_STREAM << "QNN context retrieved from qnn_context.bin"; + return returnStatus; +} + std::vector QNNBackend::runFunc(std::vector out_names, TensorFuncType type, std::vector float_args, @@ -958,6 +1112,11 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); #endif } + if (layer->param_["type"] == SUBGRAPHFINALIZE) { + for (auto &input : inputs) { + activation_tensors[input.name()]->setTtype(GRAPH_OUTPUT); + } + } if (module->doLoad) { layer->op_->load(*module->loader); layer->inited_loaded = true; @@ -992,6 +1151,17 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input } } next_name = Layer::layername_2_tensorname[layer_next_name]; + } else if (layer_next_name.find("visual") != string::npos) { + // QNN VLM trick: visual model use act tensor sharing + if (Layer::layername_2_tensorname.find(layer_next_name) == Layer::layername_2_tensorname.end()) { + if (layer->param_["type"] == KVCACHE) { + Layer::layername_2_tensorname[layer_next_name] = layer_next_name; + init_reset_KVCache(inputs[0].name(), module, layer->saved_list_idx, Layer::layername_2_tensorname, layer->backend_); + } else { + Layer::layername_2_tensorname[layer_next_name] = name_num_to_X(layer_next_name); + } + } + next_name = Layer::layername_2_tensorname[layer_next_name]; } else { next_name = layer_next_name; } @@ -1005,7 +1175,7 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input if (module->doLoad) { vector output_result = {}; for (const auto &layer_next_name : layer_next_names) { - string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name; + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); output_result.push_back(*activation_tensors[next_name]); } return output_result; @@ -1035,7 +1205,7 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input } vector> output_tensors = {}; for (const auto &layer_next_name : layer_next_names) { - string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name; + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); output_tensors.push_back(activation_tensors[next_name]); } #ifdef DEBUGOPTIME @@ -1043,17 +1213,25 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input #endif switch (Tensor::tensor_status) { case TENSOR_STATIC_INIT: { - layer->op_->reshape(input_tensors, output_tensors); - layer->op_->setUp(input_tensors, output_tensors); + if (!Module::isFirstChunk && layer->backend_->type() == MLLM_QNN) { + } else { + layer->op_->reshape(input_tensors, output_tensors); + layer->op_->setUp(input_tensors, output_tensors); + } break; } case TENSOR_STATIC_READY: { - layer->op_->execute(input_tensors, output_tensors); + if (!Module::isFirstChunk && layer->backend_->type() == MLLM_QNN && layer->param_["type"] != SUBGRAPHSTART) { + } else { + layer->op_->execute(input_tensors, output_tensors); + } break; } case TENSOR_STATIC_TRACE: { if (layer->backend_->type() == BackendType::MLLM_CPU) { Tracer::addOp(layer->op_, input_tensors, output_tensors); + } else if (layer->param_["type"] == SUBGRAPHSTART) { // begin of QNN graph + Tracer::addModule(input_tensors, {}, layer->op_->name()); } break; } @@ -1061,29 +1239,29 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input break; } } - // if (Backend::global_backends.size() == 1) { - // for (auto input_tensor : input_tensors) { - // if ((activation_tensors_num.find(input_tensor->name()) != activation_tensors_num.end())) { - // switch (Tensor::tensor_status) { - // case TENSOR_STATIC_INIT: { - // activation_tensors_num[input_tensor->name()] += 1; - // break; - // } - // case TENSOR_STATIC_READY: { - // activation_tensors_num[input_tensor->name()] -= 1; - // break; - // } - // default: { - // } - // } - // if (activation_tensors_num[input_tensor->name()] == 0 && activation_tensors[input_tensor->name()]->sequence() > 1 - // && activation_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { - // activation_tensors[input_tensor->name()]->free(); - // // std::cout << input_tensor->name() << "|" << std::endl; - // } - // } - // } - // } +// if (Backend::global_backends.size() == 1) { +// for (auto input_tensor : input_tensors) { +// if ((activation_tensors_num.find(input_tensor->name()) != activation_tensors_num.end())) { +// switch (Tensor::tensor_status) { +// case TENSOR_STATIC_INIT: { +// activation_tensors_num[input_tensor->name()] += 1; +// break; +// } +// case TENSOR_STATIC_READY: { +// activation_tensors_num[input_tensor->name()] -= 1; +// break; +// } +// default: { +// } +// } +// if (activation_tensors_num[input_tensor->name()] == 0 && activation_tensors[input_tensor->name()]->sequence() > 1 +// && activation_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { +// activation_tensors[input_tensor->name()]->free(); +// // std::cout << input_tensor->name() << "|" << std::endl; +// } +// } +// } +// } #ifdef DEBUGOPTIME if (Tensor::tensor_status == TENSOR_STATIC_READY) { auto end_t = mllm_time_us(); @@ -1092,7 +1270,7 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input #endif vector output_result = {}; for (const auto &layer_next_name : layer_next_names) { - string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name; + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); #ifdef DEBUGSAVETENSOR activation_tensors[next_name]->saveNData(layer_next_name); #endif @@ -1102,19 +1280,19 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input } std::vector QNNBackend::runForward(Module *module, std::vector inputs, std::vector args) { // set static tmp_device to device_ to init layers' op - auto previoud_device = Module::tmp_device; - Module::tmp_device = module->device_; + // auto previoud_device = Module::tmp_device; + // Module::tmp_device = module->device_; // Module Loading if (Module::llm_model_ptr && Module::llm_model_ptr->doLoad) { auto outputs = module->Forward(inputs, args); // for inner module, set output tensors to GRAPH_OUTPUT - if (inputs[0].ttype() != TensorType::INPUT_TENSOR) { // XPUs' module should not be the outermost input tensor - for (auto &output : outputs) { - inputs[0].module()->activation_tensors[output.name()]->setTtype(GRAPH_OUTPUT); - } - } - // set Module::tmp_device to previous device - Module::tmp_device = previoud_device; + // if (inputs[0].ttype() != TensorType::INPUT_TENSOR) { // XPUs' module should not be the outermost input tensor + // for (auto &output : outputs) { + // inputs[0].module()->activation_tensors[output.name()]->setTtype(GRAPH_OUTPUT); + // } + // } + // // set Module::tmp_device to previous device + // Module::tmp_device = previoud_device; return outputs; } // if (false) { diff --git a/src/backends/qnn/QNNBackend.hpp b/src/backends/qnn/QNNBackend.hpp index 0064ff753..6e5835a49 100644 --- a/src/backends/qnn/QNNBackend.hpp +++ b/src/backends/qnn/QNNBackend.hpp @@ -110,6 +110,10 @@ class QNNBackend : public Backend { dataLoader_ = dataLoader; } + void saveQNNContext(); + + StatusCode retrieveQNNContext(); + private: qnn_wrapper_api::ModelError_t graphFinilize(); qnn_wrapper_api::ModelError_t graphConfig(); @@ -171,7 +175,8 @@ class QNNBackend : public Backend { iotensor::InputDataType m_inputDataType; sample_app::ProfilingLevel m_profilingLevel; - std::map graphInfoMap_; + // std::map graphInfoMap_; + std::vector graphsInfo_; const QnnGraph_Config_t **graphConfigs = nullptr; // these two pointers is .so library handle @@ -187,8 +192,7 @@ class QNNBackend : public Backend { Qnn_BackendHandle_t m_backendHandle = nullptr; Qnn_DeviceHandle_t m_deviceHandle = nullptr; - std::map inputsMap_; - std::map outputsMap_; + bool isFromCache = false; }; } // namespace mllm diff --git a/src/backends/qnn/QnnTypeMacros.hpp b/src/backends/qnn/QnnTypeMacros.hpp index 99aecbecc..70c70d031 100644 --- a/src/backends/qnn/QnnTypeMacros.hpp +++ b/src/backends/qnn/QnnTypeMacros.hpp @@ -1,21 +1,17 @@ //============================================================================== // -// Copyright (c) 2022 Qualcomm Technologies, Inc. -// All Rights Reserved. +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All rights reserved. // Confidential and Proprietary - Qualcomm Technologies, Inc. // //============================================================================== +// TODO: remove once the SNPE build for QNN core is sorted out #pragma once -#include -#include -#include - #include "QnnTypes.h" -#include "WrapperUtils/QnnWrapperUtils.hpp" -namespace qnn_wrapper_api { +#define QNN_OP_CFG_VALID(opConfig) ((opConfig).version == QNN_OPCONFIG_VERSION_1) /** * @brief Verifies the tensor object passed is of supported Qnn_Tensor_t API version @@ -24,14 +20,8 @@ namespace qnn_wrapper_api { * * @return Error code */ -inline ModelError_t validateTensorVersion(Qnn_Tensor_t tensor) { - if (tensor.version != QNN_TENSOR_VERSION_1) { - PRINT_ERROR("validateTensorVersion() tensor %s, got unsupported version %d.", - tensor.v1.name, - tensor.version); - return MODEL_TENSOR_ERROR; - } - return MODEL_NO_ERROR; +inline bool validateTensorVersion(Qnn_Tensor_t tensor) { + return !(tensor.version != QNN_TENSOR_VERSION_1 && tensor.version != QNN_TENSOR_VERSION_2); } /** @@ -41,467 +31,683 @@ inline ModelError_t validateTensorVersion(Qnn_Tensor_t tensor) { * * @return Error code */ -inline ModelError_t validateOpConfigVersion(Qnn_OpConfig_t opConfig) { - if (opConfig.version != QNN_OPCONFIG_VERSION_1) { - PRINT_ERROR("validateOpConfigVersion() op %s, got unsupported version %d.", - opConfig.v1.name, - opConfig.version); - return MODEL_NODES_ERROR; - } - return MODEL_NO_ERROR; +inline bool validateOpConfigVersion(Qnn_OpConfig_t opConfig) { + return !(opConfig.version != QNN_OPCONFIG_VERSION_1); +} + +inline Qnn_OpConfig_t createQnnOpConfig(const Qnn_OpConfigVersion_t version) { + Qnn_OpConfig_t opConfig = QNN_OPCONFIG_INIT; + opConfig.version = version; + if (version == QNN_OPCONFIG_VERSION_1) { + opConfig.v1 = QNN_OPCONFIG_V1_INIT; + } + return opConfig; } -inline const char* getQnnOpConfigName(const Qnn_OpConfig_t& opConfig) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - return opConfig.v1.name; - } - return nullptr; +inline const char *getQnnOpConfigName(const Qnn_OpConfig_t &opConfig) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + return opConfig.v1.name; + } + return NULL; } -inline const char* getQnnOpConfigName(const Qnn_OpConfig_t* opConfig) { - return getQnnOpConfigName(*opConfig); +inline const char *getQnnOpConfigName(const Qnn_OpConfig_t *opConfig) { + return getQnnOpConfigName(*opConfig); } -inline const char* getQnnOpConfigPackageName(const Qnn_OpConfig_t& opConfig) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - return opConfig.v1.packageName; - } - return nullptr; +inline const char *getQnnOpConfigPackageName(const Qnn_OpConfig_t &opConfig) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + return opConfig.v1.packageName; + } + return NULL; } -inline const char* getQnnOpConfigPackageName(const Qnn_OpConfig_t* opConfig) { - return getQnnOpConfigPackageName(*opConfig); +inline const char *getQnnOpConfigPackageName(const Qnn_OpConfig_t *opConfig) { + return getQnnOpConfigPackageName(*opConfig); } -inline const char* getQnnOpConfigTypeName(const Qnn_OpConfig_t& opConfig) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - return opConfig.v1.typeName; - } - return nullptr; +inline const char *getQnnOpConfigTypeName(const Qnn_OpConfig_t &opConfig) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + return opConfig.v1.typeName; + } + return NULL; } -inline const char* getQnnOpConfigTypeName(const Qnn_OpConfig_t* opConfig) { - return getQnnOpConfigTypeName(*opConfig); +inline const char *getQnnOpConfigTypeName(const Qnn_OpConfig_t *opConfig) { + return getQnnOpConfigTypeName(*opConfig); } -inline uint32_t getQnnOpConfigNumParams(const Qnn_OpConfig_t& opConfig) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - return opConfig.v1.numOfParams; - } - return 0u; +inline uint32_t getQnnOpConfigNumParams(const Qnn_OpConfig_t &opConfig) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + return opConfig.v1.numOfParams; + } + return 0u; } -inline uint32_t getQnnOpConfigNumParams(const Qnn_OpConfig_t* opConfig) { - return getQnnOpConfigNumParams(*opConfig); +inline uint32_t getQnnOpConfigNumParams(const Qnn_OpConfig_t *opConfig) { + return getQnnOpConfigNumParams(*opConfig); } -inline const Qnn_Param_t* getQnnOpConfigParams(const Qnn_OpConfig_t& opConfig) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - return opConfig.v1.params; - } - return nullptr; +inline Qnn_Param_t *getQnnOpConfigParams(const Qnn_OpConfig_t &opConfig) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + return opConfig.v1.params; + } + return NULL; } -inline const Qnn_Param_t* getQnnOpConfigParams(const Qnn_OpConfig_t* opConfig) { - return getQnnOpConfigParams(*opConfig); +inline Qnn_Param_t *getQnnOpConfigParams(const Qnn_OpConfig_t *opConfig) { + return getQnnOpConfigParams(*opConfig); } -inline uint32_t getQnnOpConfigNumInputs(const Qnn_OpConfig_t& opConfig) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - return opConfig.v1.numOfInputs; - } - return 0u; +inline uint32_t getQnnOpConfigNumInputs(const Qnn_OpConfig_t &opConfig) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + return opConfig.v1.numOfInputs; + } + return 0u; } -inline uint32_t getQnnOpConfigNumInputs(const Qnn_OpConfig_t* opConfig) { - return getQnnOpConfigNumInputs(*opConfig); +inline uint32_t getQnnOpConfigNumInputs(const Qnn_OpConfig_t *opConfig) { + return getQnnOpConfigNumInputs(*opConfig); } -inline const Qnn_Tensor_t* getQnnOpConfigInputs(const Qnn_OpConfig_t& opConfig) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - return opConfig.v1.inputTensors; - } - return nullptr; +inline Qnn_Tensor_t *getQnnOpConfigInputs(const Qnn_OpConfig_t &opConfig) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + return opConfig.v1.inputTensors; + } + return NULL; } -inline const Qnn_Tensor_t* getQnnOpConfigInputs(const Qnn_OpConfig_t* opConfig) { - return getQnnOpConfigInputs(*opConfig); +inline Qnn_Tensor_t *getQnnOpConfigInputs(const Qnn_OpConfig_t *opConfig) { + return getQnnOpConfigInputs(*opConfig); } -inline uint32_t getQnnOpConfigNumOutputs(const Qnn_OpConfig_t& opConfig) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - return opConfig.v1.numOfOutputs; - } - return 0u; +inline uint32_t getQnnOpConfigNumOutputs(const Qnn_OpConfig_t &opConfig) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + return opConfig.v1.numOfOutputs; + } + return 0u; } -inline uint32_t getQnnOpConfigNumOutputs(const Qnn_OpConfig_t* opConfig) { - return getQnnOpConfigNumOutputs(*opConfig); +inline uint32_t getQnnOpConfigNumOutputs(const Qnn_OpConfig_t *opConfig) { + return getQnnOpConfigNumOutputs(*opConfig); } -inline const Qnn_Tensor_t* getQnnOpConfigOutputs(const Qnn_OpConfig_t& opConfig) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - return opConfig.v1.outputTensors; - } - return nullptr; +inline Qnn_Tensor_t *getQnnOpConfigOutputs(const Qnn_OpConfig_t &opConfig) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + return opConfig.v1.outputTensors; + } + return NULL; } -inline const Qnn_Tensor_t* getQnnOpConfigOutputs(const Qnn_OpConfig_t* opConfig) { - return getQnnOpConfigOutputs(*opConfig); +inline Qnn_Tensor_t *getQnnOpConfigOutputs(const Qnn_OpConfig_t *opConfig) { + return getQnnOpConfigOutputs(*opConfig); } -inline void setQnnOpConfigName(Qnn_OpConfig_t& opConfig, const char* name) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - opConfig.v1.name = name; - } +inline void setQnnOpConfigName(Qnn_OpConfig_t &opConfig, const char *name) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + opConfig.v1.name = name; + } } -inline void setQnnOpConfigName(Qnn_OpConfig_t* opConfig, const char* name) { - setQnnOpConfigName(*opConfig, name); +inline void setQnnOpConfigName(Qnn_OpConfig_t *opConfig, const char *name) { + setQnnOpConfigName(*opConfig, name); } -inline void setQnnOpConfigPackageName(Qnn_OpConfig_t& opConfig, const char* packageName) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - opConfig.v1.packageName = packageName; - } +inline void setQnnOpConfigPackageName(Qnn_OpConfig_t &opConfig, const char *packageName) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + opConfig.v1.packageName = packageName; + } } -inline void setQnnOpConfigPackageName(Qnn_OpConfig_t* opConfig, const char* packageName) { - setQnnOpConfigPackageName(*opConfig, packageName); +inline void setQnnOpConfigPackageName(Qnn_OpConfig_t *opConfig, const char *packageName) { + setQnnOpConfigPackageName(*opConfig, packageName); } -inline void setQnnOpConfigTypeName(Qnn_OpConfig_t& opConfig, const char* typeName) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - opConfig.v1.typeName = typeName; - } +inline void setQnnOpConfigTypeName(Qnn_OpConfig_t &opConfig, const char *typeName) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + opConfig.v1.typeName = typeName; + } } -inline void setQnnOpConfigTypeName(Qnn_OpConfig_t* opConfig, const char* typeName) { - setQnnOpConfigTypeName(*opConfig, typeName); +inline void setQnnOpConfigTypeName(Qnn_OpConfig_t *opConfig, const char *typeName) { + setQnnOpConfigTypeName(*opConfig, typeName); } -inline void setQnnOpConfigParams(Qnn_OpConfig_t& opConfig, +inline void setQnnOpConfigParams(Qnn_OpConfig_t &opConfig, uint32_t numOfParams, - Qnn_Param_t* params) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - opConfig.v1.numOfParams = numOfParams; - opConfig.v1.params = params; - } + Qnn_Param_t *params) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + opConfig.v1.numOfParams = numOfParams; + opConfig.v1.params = params; + } } -inline void setQnnOpConfigParams(Qnn_OpConfig_t* opConfig, +inline void setQnnOpConfigParams(Qnn_OpConfig_t *opConfig, uint32_t numOfParams, - Qnn_Param_t* params) { - setQnnOpConfigParams(*opConfig, numOfParams, params); + Qnn_Param_t *params) { + setQnnOpConfigParams(*opConfig, numOfParams, params); } -inline void setQnnOpConfigInputs(Qnn_OpConfig_t& opConfig, +inline void setQnnOpConfigInputs(Qnn_OpConfig_t &opConfig, uint32_t numOfInputs, - Qnn_Tensor_t* inputTensors) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - opConfig.v1.numOfInputs = numOfInputs; - opConfig.v1.inputTensors = inputTensors; - } + Qnn_Tensor_t *inputTensors) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + opConfig.v1.numOfInputs = numOfInputs; + opConfig.v1.inputTensors = inputTensors; + } } -inline void setQnnOpConfigInputs(Qnn_OpConfig_t* opConfig, +inline void setQnnOpConfigInputs(Qnn_OpConfig_t *opConfig, uint32_t numOfInputs, - Qnn_Tensor_t* inputTensors) { - setQnnOpConfigInputs(*opConfig, numOfInputs, inputTensors); + Qnn_Tensor_t *inputTensors) { + setQnnOpConfigInputs(*opConfig, numOfInputs, inputTensors); } -inline void setQnnOpConfigOutputs(Qnn_OpConfig_t& opConfig, +inline void setQnnOpConfigOutputs(Qnn_OpConfig_t &opConfig, uint32_t numOfOutputs, - Qnn_Tensor_t* outputTensors) { - if (opConfig.version == QNN_OPCONFIG_VERSION_1) { - opConfig.v1.numOfOutputs = numOfOutputs; - opConfig.v1.outputTensors = outputTensors; - } + Qnn_Tensor_t *outputTensors) { + if (opConfig.version == QNN_OPCONFIG_VERSION_1) { + opConfig.v1.numOfOutputs = numOfOutputs; + opConfig.v1.outputTensors = outputTensors; + } } -inline void setQnnOpConfigOutputs(Qnn_OpConfig_t* opConfig, +inline void setQnnOpConfigOutputs(Qnn_OpConfig_t *opConfig, uint32_t numOfOutputs, - Qnn_Tensor_t* outputTensors) { - setQnnOpConfigOutputs(*opConfig, numOfOutputs, outputTensors); + Qnn_Tensor_t *outputTensors) { + setQnnOpConfigOutputs(*opConfig, numOfOutputs, outputTensors); } -// inline Qnn_OpConfig_t +inline Qnn_Tensor_t createQnnTensor(const Qnn_TensorVersion_t version) { + Qnn_Tensor_t tensor = QNN_TENSOR_INIT; + tensor.version = version; + if (version == QNN_TENSOR_VERSION_1) { + tensor.v1 = QNN_TENSOR_V1_INIT; + } else if (version == QNN_TENSOR_VERSION_2) { + tensor.v2 = QNN_TENSOR_V2_INIT; + } + return tensor; +} -inline uint32_t getQnnTensorId(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline uint32_t getQnnTensorId(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.id; - } - return 0u; } -inline uint32_t getQnnTensorId(const Qnn_Tensor_t* tensor) { return getQnnTensorId(*tensor); } +inline uint32_t getQnnTensorId(const Qnn_Tensor_t *tensor) { + return getQnnTensorId(*tensor); +} -inline const char* getQnnTensorName(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline const char *getQnnTensorName(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.name; - } - return 0u; } - -inline const char* getQnnTensorName(const Qnn_Tensor_t* tensor) { - return getQnnTensorName(*tensor); +inline const char *getQnnTensorName(const Qnn_Tensor_t *tensor) { + return getQnnTensorName(*tensor); } -inline Qnn_TensorType_t getQnnTensorType(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline Qnn_TensorType_t getQnnTensorType(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.type; - } - return QNN_TENSOR_TYPE_UNDEFINED; } -inline Qnn_TensorType_t getQnnTensorType(const Qnn_Tensor_t* tensor) { - return getQnnTensorType(*tensor); +inline Qnn_TensorType_t getQnnTensorType(const Qnn_Tensor_t *tensor) { + return getQnnTensorType(*tensor); } -inline Qnn_TensorDataFormat_t getQnnTensorDataFormat(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline Qnn_TensorDataFormat_t getQnnTensorDataFormat(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.dataFormat; - } - return QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER; } -inline Qnn_TensorDataFormat_t getQnnTensorDataFormat(const Qnn_Tensor_t* tensor) { - return getQnnTensorDataFormat(*tensor); +inline Qnn_TensorDataFormat_t getQnnTensorDataFormat(const Qnn_Tensor_t *tensor) { + return getQnnTensorDataFormat(*tensor); } -inline Qnn_DataType_t getQnnTensorDataType(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline Qnn_DataType_t getQnnTensorDataType(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.dataType; - } - return QNN_DATATYPE_UNDEFINED; } -inline Qnn_DataType_t getQnnTensorDataType(const Qnn_Tensor_t* tensor) { - return getQnnTensorDataType(*tensor); +inline Qnn_DataType_t getQnnTensorDataType(const Qnn_Tensor_t *tensor) { + return getQnnTensorDataType(*tensor); } -inline Qnn_QuantizeParams_t getQnnTensorQuantParams(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline Qnn_QuantizeParams_t getQnnTensorQuantParams(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.quantizeParams; - } - return QNN_QUANTIZE_PARAMS_INIT; } -inline Qnn_QuantizeParams_t getQnnTensorQuantParams(const Qnn_Tensor_t* tensor) { - return getQnnTensorQuantParams(*tensor); +inline Qnn_QuantizeParams_t getQnnTensorQuantParams(const Qnn_Tensor_t *const tensor) { + if (tensor != nullptr) { + return getQnnTensorQuantParams(*tensor); + } + return QNN_QUANTIZE_PARAMS_INIT; } -inline uint32_t getQnnTensorRank(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline uint32_t getQnnTensorRank(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.rank; - } - return 0u; } -inline uint32_t getQnnTensorRank(const Qnn_Tensor_t* tensor) { return getQnnTensorRank(*tensor); } +inline uint32_t getQnnTensorRank(const Qnn_Tensor_t *const tensor) { + if (tensor != nullptr) { + return getQnnTensorRank(*tensor); + } + return 0u; +} -inline uint32_t* getQnnTensorDimensions(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline uint32_t *getQnnTensorDimensions(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.dimensions; - } - return nullptr; } -inline uint32_t* getQnnTensorDimensions(const Qnn_Tensor_t* tensor) { - return getQnnTensorDimensions(*tensor); +inline uint32_t *getQnnTensorDimensions(const Qnn_Tensor_t *tensor) { + return getQnnTensorDimensions(*tensor); +} + +inline uint8_t *getQnnTensorIsDynamicDimensions(const Qnn_Tensor_t &tensor) { + if (tensor.version == QNN_TENSOR_VERSION_2) { + return tensor.v2.isDynamicDimensions; + } + return NULL; +} + +inline uint8_t *getQnnTensorIsDynamicDimensions(const Qnn_Tensor_t *tensor) { + return getQnnTensorIsDynamicDimensions(*tensor); +} + +inline Qnn_SparseParams_t getQnnTensorSparseParams(const Qnn_Tensor_t &tensor) { + if (tensor.version == QNN_TENSOR_VERSION_2) { + return tensor.v2.sparseParams; + } + return QNN_SPARSE_PARAMS_INIT; +} + +inline Qnn_SparseParams_t getQnnTensorSparseParams(const Qnn_Tensor_t *tensor) { + return getQnnTensorSparseParams(*tensor); } -inline Qnn_TensorMemType_t getQnnTensorMemType(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline Qnn_TensorMemType_t getQnnTensorMemType(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.memType; - } - return QNN_TENSORMEMTYPE_UNDEFINED; } -inline Qnn_TensorMemType_t getQnnTensorMemType(const Qnn_Tensor_t* tensor) { - return getQnnTensorMemType(*tensor); +inline Qnn_TensorMemType_t getQnnTensorMemType(const Qnn_Tensor_t *tensor) { + return getQnnTensorMemType(*tensor); } -inline Qnn_ClientBuffer_t getQnnTensorClientBuf(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline Qnn_ClientBuffer_t getQnnTensorClientBuf(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.clientBuf; - } - return QNN_CLIENT_BUFFER_INIT; } -inline Qnn_ClientBuffer_t getQnnTensorClientBuf(const Qnn_Tensor_t* tensor) { - return getQnnTensorClientBuf(*tensor); +inline Qnn_ClientBuffer_t getQnnTensorClientBuf(const Qnn_Tensor_t *tensor) { + return getQnnTensorClientBuf(*tensor); } -inline Qnn_MemHandle_t getQnnTensorMemHandle(const Qnn_Tensor_t& tensor) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline Qnn_MemHandle_t getQnnTensorMemHandle(const Qnn_Tensor_t &tensor) { + // TensorCompatTest justifies no need to check version return tensor.v1.memHandle; - } - return nullptr; } -inline Qnn_MemHandle_t getQnnTensorMemHandle(const Qnn_Tensor_t* tensor) { - return getQnnTensorMemHandle(*tensor); +inline Qnn_MemHandle_t getQnnTensorMemHandle(const Qnn_Tensor_t *tensor) { + return getQnnTensorMemHandle(*tensor); } -inline void setQnnTensorId(Qnn_Tensor_t& tensor, uint32_t id) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline void setQnnTensorId(Qnn_Tensor_t &tensor, const uint32_t id) { + // TensorCompatTest justifies no need to check version tensor.v1.id = id; - } } -inline void setQnnTensorId(Qnn_Tensor_t* tensor, uint32_t id) { setQnnTensorId(*tensor, id); } +inline void setQnnTensorId(Qnn_Tensor_t *tensor, uint32_t id) { + setQnnTensorId(*tensor, id); +} -inline void setQnnTensorName(Qnn_Tensor_t& tensor, const char* name) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline void setQnnTensorName(Qnn_Tensor_t &tensor, const char *const name) { + // TensorCompatTest justifies no need to check version tensor.v1.name = name; - } } -inline void setQnnTensorName(Qnn_Tensor_t* tensor, const char* name) { - setQnnTensorName(*tensor, name); +inline void setQnnTensorName(Qnn_Tensor_t *tensor, const char *name) { + setQnnTensorName(*tensor, name); } -inline void setQnnTensorType(Qnn_Tensor_t& tensor, Qnn_TensorType_t type) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline void setQnnTensorType(Qnn_Tensor_t &tensor, Qnn_TensorType_t type) { + // TensorCompatTest justifies no need to check version tensor.v1.type = type; - } } -inline void setQnnTensorType(Qnn_Tensor_t* tensor, Qnn_TensorType_t type) { - setQnnTensorType(*tensor, type); +inline void setQnnTensorType(Qnn_Tensor_t *tensor, Qnn_TensorType_t type) { + setQnnTensorType(*tensor, type); } -inline void setQnnTensorDataFormat(Qnn_Tensor_t& tensor, Qnn_TensorDataFormat_t format) { - if (tensor.version == QNN_TENSOR_VERSION_1) { - tensor.v1.dataFormat = format; - } +inline void setQnnTensorDataFormat(Qnn_Tensor_t &tensor, const Qnn_TensorDataFormat_t dataFormat) { + // TensorCompatTest justifies no need to check version + tensor.v1.dataFormat = dataFormat; } -inline void setQnnTensorDataFormat(Qnn_Tensor_t* tensor, Qnn_TensorDataFormat_t format) { - setQnnTensorDataFormat(*tensor, format); +inline void setQnnTensorDataFormat(Qnn_Tensor_t *tensor, Qnn_TensorDataFormat_t format) { + setQnnTensorDataFormat(*tensor, format); } -inline void setQnnTensorDataType(Qnn_Tensor_t& tensor, Qnn_DataType_t dataType) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline void setQnnTensorDataType(Qnn_Tensor_t &tensor, const Qnn_DataType_t dataType) { + // TensorCompatTest justifies no need to check version tensor.v1.dataType = dataType; - } } -inline void setQnnTensorDataType(Qnn_Tensor_t* tensor, Qnn_DataType_t dataType) { - setQnnTensorDataType(*tensor, dataType); +inline void setQnnTensorDataType(Qnn_Tensor_t *tensor, Qnn_DataType_t dataType) { + setQnnTensorDataType(*tensor, dataType); } -inline void setQnnTensorQuantParams(Qnn_Tensor_t& tensor, Qnn_QuantizeParams_t params) { - if (tensor.version == QNN_TENSOR_VERSION_1) { - tensor.v1.quantizeParams = params; - } +inline void setQnnTensorQuantParams(Qnn_Tensor_t &tensor, + const Qnn_QuantizeParams_t quantizeParams) { + // TensorCompatTest justifies no need to check version + tensor.v1.quantizeParams = quantizeParams; } -inline void setQnnTensorQuantParams(Qnn_Tensor_t* tensor, Qnn_QuantizeParams_t params) { - setQnnTensorQuantParams(*tensor, params); +inline void setQnnTensorQuantParams(Qnn_Tensor_t *tensor, Qnn_QuantizeParams_t params) { + setQnnTensorQuantParams(*tensor, params); } -inline void setQnnTensorRank(Qnn_Tensor_t& tensor, uint32_t rank) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline void setQnnTensorRank(Qnn_Tensor_t &tensor, const uint32_t rank) { + // TensorCompatTest justifies no need to check version tensor.v1.rank = rank; - } } -inline void setQnnTensorRank(Qnn_Tensor_t* tensor, uint32_t rank) { - setQnnTensorRank(*tensor, rank); +inline void setQnnTensorRank(Qnn_Tensor_t *tensor, uint32_t rank) { + setQnnTensorRank(*tensor, rank); } -inline void setQnnTensorDimensions(Qnn_Tensor_t& tensor, uint32_t* dims) { - if (tensor.version == QNN_TENSOR_VERSION_1) { - tensor.v1.dimensions = dims; - } +inline void setQnnTensorDimensions(Qnn_Tensor_t &tensor, uint32_t *const dimensions) { + // TensorCompatTest justifies no need to check version + tensor.v1.dimensions = dimensions; } -inline void setQnnTensorDimensions(Qnn_Tensor_t* tensor, uint32_t* dims) { - setQnnTensorDimensions(*tensor, dims); +inline void setQnnTensorDimensions(Qnn_Tensor_t *tensor, uint32_t *dims) { + setQnnTensorDimensions(*tensor, dims); } -inline void setQnnTensorMemType(Qnn_Tensor_t& tensor, Qnn_TensorMemType_t memType) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline void setQnnTensorIsDynamicDimensions(Qnn_Tensor_t &tensor, uint8_t *isDynamic) { + if (tensor.version == QNN_TENSOR_VERSION_2) { + tensor.v2.isDynamicDimensions = isDynamic; + } +} + +inline void setQnnTensorIsDynamicDimensions(Qnn_Tensor_t *tensor, uint8_t *isDynamic) { + setQnnTensorIsDynamicDimensions(*tensor, isDynamic); +} + +inline void setQnnTensorSparseParams(Qnn_Tensor_t &tensor, Qnn_SparseParams_t sparseParams) { + if (tensor.version == QNN_TENSOR_VERSION_2) { + tensor.v2.sparseParams = sparseParams; + } +} + +inline void setQnnTensorSparseParams(Qnn_Tensor_t *tensor, Qnn_SparseParams_t sparseParams) { + setQnnTensorSparseParams(*tensor, sparseParams); +} + +inline void setQnnTensorMemType(Qnn_Tensor_t &tensor, const Qnn_TensorMemType_t memType) { + // TensorCompatTest justifies no need to check version tensor.v1.memType = memType; - } } -inline void setQnnTensorMemType(Qnn_Tensor_t* tensor, Qnn_TensorMemType_t memType) { - setQnnTensorMemType(*tensor, memType); +inline void setQnnTensorMemType(Qnn_Tensor_t *tensor, Qnn_TensorMemType_t memType) { + setQnnTensorMemType(*tensor, memType); } -inline void setQnnTensorClientBuf(Qnn_Tensor_t& tensor, Qnn_ClientBuffer_t clientBuf) { - if (tensor.version == QNN_TENSOR_VERSION_1) { +inline void setQnnTensorClientBuf(Qnn_Tensor_t &tensor, const Qnn_ClientBuffer_t clientBuf) { + // TensorCompatTest justifies no need to check version tensor.v1.clientBuf = clientBuf; - } } -inline void setQnnTensorClientBuf(Qnn_Tensor_t* tensor, Qnn_ClientBuffer_t clientBuf) { - setQnnTensorClientBuf(*tensor, clientBuf); +inline void setQnnTensorClientBuf(Qnn_Tensor_t *tensor, Qnn_ClientBuffer_t clientBuf) { + setQnnTensorClientBuf(*tensor, clientBuf); } -inline void setQnnTensorMemHandle(Qnn_Tensor_t& tensor, Qnn_MemHandle_t handle) { - if (tensor.version == QNN_TENSOR_VERSION_1) { - tensor.v1.memHandle = handle; - } +inline void setQnnTensorMemHandle(Qnn_Tensor_t &tensor, const Qnn_MemHandle_t memHandle) { + // TensorCompatTest justifies no need to check version + tensor.v1.memHandle = memHandle; } -inline void setQnnTensorMemHandle(Qnn_Tensor_t* tensor, Qnn_MemHandle_t handle) { - setQnnTensorMemHandle(*tensor, handle); +inline void setQnnTensorMemHandle(Qnn_Tensor_t *tensor, Qnn_MemHandle_t handle) { + setQnnTensorMemHandle(*tensor, handle); +} + +inline void setQnnTensorClientBufRetrieve(Qnn_Tensor_t &tensor, + Qnn_TensorRetrieveRaw_t *const retrieve) { + if (tensor.version == QNN_TENSOR_VERSION_2) { + tensor.v2.retrieveRaw = retrieve; + } +} +inline void setQnnTensorClientBufRetrieve(Qnn_Tensor_t *const tensor, + Qnn_TensorRetrieveRaw_t *const retrieve) { + setQnnTensorClientBufRetrieve(*tensor, retrieve); +} +inline void setQnnTensorClientBufRetrieve(Qnn_Tensor_t &tensor, Qnn_TensorRetrieveRaw_t &retrieve) { + setQnnTensorClientBufRetrieve(tensor, &retrieve); +} +inline void setQnnTensorClientBufRetrieve(Qnn_Tensor_t *const tensor, + Qnn_TensorRetrieveRaw_t &retrieve) { + setQnnTensorClientBufRetrieve(*tensor, &retrieve); +} + +inline Qnn_TensorRetrieveRaw_t *getQnnTensorClientBufRetrieve(const Qnn_Tensor_t &tensor) { + if (tensor.version == QNN_TENSOR_VERSION_2) { + return tensor.v2.retrieveRaw; + } + return nullptr; +} +inline Qnn_TensorRetrieveRaw_t *getQnnTensorClientBufRetrieve(const Qnn_Tensor_t *const tensor) { + return getQnnTensorClientBufRetrieve(*tensor); +} + +inline Qnn_TensorSet_t createQnnTensorSet(const Qnn_TensorSetVersion_t version) { + Qnn_TensorSet_t tensorSet = QNN_TENSOR_SET_INIT; + tensorSet.version = version; + if (version == QNN_TENSOR_SET_VERSION_1) { + tensorSet.v1 = QNN_TENSOR_SET_V1_INIT; + } + return tensorSet; +} + +inline uint32_t getQnnTensorSetNumInputs(const Qnn_TensorSet_t &tensorSet) { + if (tensorSet.version == QNN_TENSOR_SET_VERSION_1) { + return tensorSet.v1.numInputs; + } + return 0; +} + +inline uint32_t getQnnTensorSetNumInputs(const Qnn_TensorSet_t *tensorSet) { + return getQnnTensorSetNumInputs(*tensorSet); +} + +inline Qnn_Tensor_t *getQnnTensorSetInputTensors(const Qnn_TensorSet_t &tensorSet) { + if (tensorSet.version == QNN_TENSOR_SET_VERSION_1) { + return tensorSet.v1.inputs; + } + return 0; +} + +inline Qnn_Tensor_t *getQnnTensorSetInputTensors(const Qnn_TensorSet_t *tensorSet) { + return getQnnTensorSetInputTensors(*tensorSet); +} + +inline uint32_t getQnnTensorSetNumOutputs(const Qnn_TensorSet_t &tensorSet) { + if (tensorSet.version == QNN_TENSOR_SET_VERSION_1) { + return tensorSet.v1.numOutputs; + } + return 0; +} + +inline uint32_t getQnnTensorSetNumOutputs(const Qnn_TensorSet_t *tensorSet) { + return getQnnTensorSetNumOutputs(*tensorSet); +} + +inline Qnn_Tensor_t *getQnnTensorSetOutputTensors(const Qnn_TensorSet_t &tensorSet) { + if (tensorSet.version == QNN_TENSOR_SET_VERSION_1) { + return tensorSet.v1.outputs; + } + return 0; +} + +inline Qnn_Tensor_t *getQnnTensorSetOutputTensors(const Qnn_TensorSet_t *tensorSet) { + return getQnnTensorSetOutputTensors(*tensorSet); +} + +inline void setQnnTensorSetInputTensors(Qnn_TensorSet_t &tensorSet, + Qnn_Tensor_t *inputTensors, + uint32_t const numInputs) { + if (tensorSet.version == QNN_TENSOR_SET_VERSION_1) { + tensorSet.v1.inputs = inputTensors; + tensorSet.v1.numInputs = numInputs; + } +} + +inline void setQnnTensorSetInputTensors(Qnn_TensorSet_t *tensorSet, + Qnn_Tensor_t *inputTensors, + uint32_t const numInputs) { + setQnnTensorSetInputTensors(*tensorSet, inputTensors, numInputs); +} + +inline void setQnnTensorSetOutputTensors(Qnn_TensorSet_t &tensorSet, + Qnn_Tensor_t *outputTensors, + const uint32_t numOutputs) { + if (tensorSet.version == QNN_TENSOR_SET_VERSION_1) { + tensorSet.v1.outputs = outputTensors; + tensorSet.v1.numOutputs = numOutputs; + } +} + +inline void setQnnTensorSetOutputTensors(Qnn_TensorSet_t *tensorSet, + Qnn_Tensor_t *outputTensors, + const uint32_t numOutputs) { + setQnnTensorSetOutputTensors(*tensorSet, outputTensors, numOutputs); } // Validation -#define VALIDATE_TENSOR_VERSION(tensor, err) VALIDATE(validateTensorVersion(tensor), err) -#define VALIDATE_OP_CONFIG_VERSION(op, err) VALIDATE(validateOpConfigVersion(op), err) +#define VALIDATE_TENSOR_VERSION(tensor, err) validateTensorVersion(tensor) +#define VALIDATE_OP_CONFIG_VERSION(op, err) validateOpConfigVersion(op) + +// Creator for QNN Op Config +#define QNN_OP_CFG_CREATE(version) createQnnOpConfig(version) // Accessors for QNN Op Config -#define QNN_OP_CFG_GET_NAME(opConfig) getQnnOpConfigName(opConfig) +#define QNN_OP_CFG_GET_NAME(opConfig) getQnnOpConfigName(opConfig) #define QNN_OP_CFG_GET_PACKAGE_NAME(opConfig) getQnnOpConfigPackageName(opConfig) -#define QNN_OP_CFG_GET_TYPE_NAME(opConfig) getQnnOpConfigTypeName(opConfig) -#define QNN_OP_CFG_GET_NUM_PARAMS(opConfig) getQnnOpConfigNumParams(opConfig) -#define QNN_OP_CFG_GET_PARAMS(opConfig) getQnnOpConfigParams(opConfig) -#define QNN_OP_CFG_GET_NUM_INPUTS(opConfig) getQnnOpConfigNumInputs(opConfig) -#define QNN_OP_CFG_GET_INPUTS(opConfig) getQnnOpConfigInputs(opConfig) -#define QNN_OP_CFG_GET_NUM_OUTPUTS(opConfig) getQnnOpConfigNumOutputs(opConfig) -#define QNN_OP_CFG_GET_OUTPUTS(opConfig) getQnnOpConfigOutputs(opConfig) +#define QNN_OP_CFG_GET_TYPE_NAME(opConfig) getQnnOpConfigTypeName(opConfig) +#define QNN_OP_CFG_GET_NUM_PARAMS(opConfig) getQnnOpConfigNumParams(opConfig) +#define QNN_OP_CFG_GET_PARAMS(opConfig) getQnnOpConfigParams(opConfig) +#define QNN_OP_CFG_GET_NUM_INPUTS(opConfig) getQnnOpConfigNumInputs(opConfig) +#define QNN_OP_CFG_GET_INPUTS(opConfig) getQnnOpConfigInputs(opConfig) +#define QNN_OP_CFG_GET_NUM_OUTPUTS(opConfig) getQnnOpConfigNumOutputs(opConfig) +#define QNN_OP_CFG_GET_OUTPUTS(opConfig) getQnnOpConfigOutputs(opConfig) // Modifiers for QNN Op Config -#define QNN_OP_CFG_SET_NAME(opConfig, value) setQnnOpConfigName(opConfig, value) +#define QNN_OP_CFG_SET_NAME(opConfig, value) setQnnOpConfigName(opConfig, value) #define QNN_OP_CFG_SET_PACKAGE_NAME(opConfig, value) setQnnOpConfigPackageName(opConfig, value) -#define QNN_OP_CFG_SET_TYPE_NAME(opConfig, value) setQnnOpConfigTypeName(opConfig, value) +#define QNN_OP_CFG_SET_TYPE_NAME(opConfig, value) setQnnOpConfigTypeName(opConfig, value) #define QNN_OP_CFG_SET_PARAMS(opConfig, numOfParams, params) \ - setQnnOpConfigParams(opConfig, numOfParams, params) + setQnnOpConfigParams(opConfig, numOfParams, params) #define QNN_OP_CFG_SET_INPUTS(opConfig, numOfInputs, inputTensors) \ - setQnnOpConfigInputs(opConfig, numOfInputs, inputTensors) + setQnnOpConfigInputs(opConfig, numOfInputs, inputTensors) #define QNN_OP_CFG_SET_OUTPUTS(opConfig, numOfOutputs, outputTensors) \ - setQnnOpConfigOutputs(opConfig, numOfOutputs, outputTensors) + setQnnOpConfigOutputs(opConfig, numOfOutputs, outputTensors) + +// Creator for QNN Tensor +#define QNN_TENSOR_CREATE(version) createQnnTensor(version) // Accessors for QNN Tensor -#define QNN_TENSOR_GET_ID(tensor) getQnnTensorId(tensor) -#define QNN_TENSOR_GET_NAME(tensor) getQnnTensorName(tensor) -#define QNN_TENSOR_GET_TYPE(tensor) getQnnTensorType(tensor) -#define QNN_TENSOR_GET_DATA_FORMAT(tensor) getQnnTensorDataFormat(tensor) -#define QNN_TENSOR_GET_DATA_TYPE(tensor) getQnnTensorDataType(tensor) +#define QNN_TENSOR_GET_ID(tensor) getQnnTensorId(tensor) +#define QNN_TENSOR_GET_NAME(tensor) getQnnTensorName(tensor) +#define QNN_TENSOR_GET_TYPE(tensor) getQnnTensorType(tensor) +#define QNN_TENSOR_GET_DATA_FORMAT(tensor) getQnnTensorDataFormat(tensor) +#define QNN_TENSOR_GET_DATA_TYPE(tensor) getQnnTensorDataType(tensor) #define QNN_TENSOR_GET_QUANT_PARAMS(tensor) getQnnTensorQuantParams(tensor) -#define QNN_TENSOR_GET_RANK(tensor) getQnnTensorRank(tensor) -#define QNN_TENSOR_GET_DIMENSIONS(tensor) getQnnTensorDimensions(tensor) -#define QNN_TENSOR_GET_MEM_TYPE(tensor) getQnnTensorMemType(tensor) -#define QNN_TENSOR_GET_CLIENT_BUF(tensor) getQnnTensorClientBuf(tensor) -#define QNN_TENSOR_GET_MEM_HANDLE(tensor) getQnnTensorMemHandle(tensor) +#define QNN_TENSOR_GET_RANK(tensor) getQnnTensorRank(tensor) +#define QNN_TENSOR_GET_DIMENSIONS(tensor) getQnnTensorDimensions(tensor) +#define QNN_TENSOR_GET_IS_DYNAMIC_DIMENSIONS(tensor) getQnnTensorIsDynamicDimensions(tensor) +#define QNN_TENSOR_GET_SPARSE_PARAMS(tensor) getQnnTensorSparseParams(tensor) +#define QNN_TENSOR_GET_MEM_TYPE(tensor) getQnnTensorMemType(tensor) +#define QNN_TENSOR_GET_CLIENT_BUF(tensor) getQnnTensorClientBuf(tensor) +#define QNN_TENSOR_GET_MEM_HANDLE(tensor) getQnnTensorMemHandle(tensor) +#define QNN_TENSOR_GET_CLIENT_BUF_RETRIEVE(tensor) getQnnTensorClientBufRetrieve(tensor) // Modifiers for QNN Tensor -#define QNN_TENSOR_SET_ID(tensor, value) setQnnTensorId(tensor, value) -#define QNN_TENSOR_SET_NAME(tensor, value) setQnnTensorName(tensor, value) -#define QNN_TENSOR_SET_TYPE(tensor, value) setQnnTensorType(tensor, value) -#define QNN_TENSOR_SET_DATA_FORMAT(tensor, value) setQnnTensorDataFormat(tensor, value) -#define QNN_TENSOR_SET_DATA_TYPE(tensor, value) setQnnTensorDataType(tensor, value) +#define QNN_TENSOR_SET_ID(tensor, value) setQnnTensorId(tensor, value) +#define QNN_TENSOR_SET_NAME(tensor, value) setQnnTensorName(tensor, value) +#define QNN_TENSOR_SET_TYPE(tensor, value) setQnnTensorType(tensor, value) +#define QNN_TENSOR_SET_DATA_FORMAT(tensor, value) setQnnTensorDataFormat(tensor, value) +#define QNN_TENSOR_SET_DATA_TYPE(tensor, value) setQnnTensorDataType(tensor, value) #define QNN_TENSOR_SET_QUANT_PARAMS(tensor, value) setQnnTensorQuantParams(tensor, value) -#define QNN_TENSOR_SET_RANK(tensor, value) setQnnTensorRank(tensor, value) -#define QNN_TENSOR_SET_DIMENSIONS(tensor, value) setQnnTensorDimensions(tensor, value) -#define QNN_TENSOR_SET_MEM_TYPE(tensor, value) setQnnTensorMemType(tensor, value) -#define QNN_TENSOR_SET_CLIENT_BUF(tensor, value) setQnnTensorClientBuf(tensor, value) -#define QNN_TENSOR_SET_MEM_HANDLE(tensor, value) setQnnTensorMemHandle(tensor, value) - -} // namespace qnn_wrapper_api +#define QNN_TENSOR_SET_RANK(tensor, value) setQnnTensorRank(tensor, value) +#define QNN_TENSOR_SET_DIMENSIONS(tensor, value) setQnnTensorDimensions(tensor, value) +#define QNN_TENSOR_SET_IS_DYNAMIC_DIMENSIONS(tensor, value) \ + setQnnTensorIsDynamicDimensions(tensor, value) +#define QNN_TENSOR_SET_SPARSE_PARAMS(tensor, value) setQnnTensorSparseParams(tensor, value) +#define QNN_TENSOR_SET_MEM_TYPE(tensor, value) setQnnTensorMemType(tensor, value) +#define QNN_TENSOR_SET_CLIENT_BUF(tensor, value) setQnnTensorClientBuf(tensor, value) +#define QNN_TENSOR_SET_MEM_HANDLE(tensor, value) setQnnTensorMemHandle(tensor, value) +#define QNN_TENSOR_SET_CLIENT_BUF_RETRIEVE(tensor, value) \ + setQnnTensorClientBufRetrieve(tensor, value) + +// Creator for QNN Tensor Set +#define QNN_TENSORSET_CREATE(version) createQnnTensorSet(version) + +// Accessors for QNN Tensor Set +#define QNN_TENSORSET_GET_NUM_INPUTS(tensorSet) getQnnTensorSetNumInputs(tensorSet) +#define QNN_TENSORSET_GET_INPUT_TENSORS(tensorSet) getQnnTensorSetInputTensors(tensorSet) +#define QNN_TENSORSET_GET_NUM_OUTPUTS(tensorSet) getQnnTensorSetNumOutputs(tensorSet) +#define QNN_TENSORSET_GET_OUTPUT_TENSORS(tensorSet) getQnnTensorSetOutputTensors(tensorSet) + +// Modifiers for QNN Tensor Set +#define QNN_TENSORSET_SET_INPUT_TENSORS(tensorSet, inputTensors, numInputs) \ + setQnnTensorSetInputTensors(tensorSet, inputTensors, numInputs) +#define QNN_TENSORSET_SET_OUTPUT_TENSORS(tensorSet, outputTensors, numOutputs) \ + setQnnTensorSetOutputTensors(tensorSet, outputTensors, numOutputs) + +inline bool isQnnTensorV1Compatible(const Qnn_Tensor_t &tensor) { + if (tensor.version == QNN_TENSOR_VERSION_2) { + if (tensor.v2.isDynamicDimensions != NULL) { + return false; + } + if (tensor.v2.dataFormat == QNN_TENSOR_DATA_FORMAT_SPARSE) { + return false; + } + } + return true; +} +inline bool isQnnTensorV1Compatible(const Qnn_Tensor_t *const tensor) { + return isQnnTensorV1Compatible(*tensor); +} +inline bool isQnnTensorV1Compatible(const Qnn_OpConfig_t &opConfig) { + if ((QNN_OP_CFG_GET_INPUTS(opConfig) != NULL) && (QNN_OP_CFG_GET_NUM_INPUTS(opConfig) > 0u)) { + for (uint32_t tensorIdx = 0u; tensorIdx < QNN_OP_CFG_GET_NUM_INPUTS(opConfig); tensorIdx++) { + if (!isQnnTensorV1Compatible(QNN_OP_CFG_GET_INPUTS(opConfig)[tensorIdx])) { + return false; + } + } + } + if ((QNN_OP_CFG_GET_OUTPUTS(opConfig) != NULL) && (QNN_OP_CFG_GET_NUM_OUTPUTS(opConfig) > 0u)) { + for (uint32_t tensorIdx = 0u; tensorIdx < QNN_OP_CFG_GET_NUM_OUTPUTS(opConfig); tensorIdx++) { + if (!isQnnTensorV1Compatible(QNN_OP_CFG_GET_OUTPUTS(opConfig)[tensorIdx])) { + return false; + } + } + } + if ((QNN_OP_CFG_GET_PARAMS(opConfig) != NULL) && (QNN_OP_CFG_GET_NUM_PARAMS(opConfig) > 0)) { + for (uint32_t paramIdx = 0u; paramIdx < QNN_OP_CFG_GET_NUM_PARAMS(opConfig); paramIdx++) { + const Qnn_Param_t ¶m = QNN_OP_CFG_GET_PARAMS(opConfig)[paramIdx]; + if (QNN_PARAMTYPE_TENSOR == param.paramType) { + if (!isQnnTensorV1Compatible(param.tensorParam)) { + return false; + } + } + } + } + return true; +} +inline bool isQnnTensorV1Compatible(const Qnn_OpConfig_t *const opConfig) { + return isQnnTensorV1Compatible(*opConfig); +} \ No newline at end of file diff --git a/src/backends/qnn/README.md b/src/backends/qnn/README.md index b7f38d908..6081c9398 100644 --- a/src/backends/qnn/README.md +++ b/src/backends/qnn/README.md @@ -7,7 +7,7 @@ This section is basically following the QNN documentation, for more details, see The QNN backend relies on the Qualcomm QNN SDK and Hexagon SDK to compile QNN Backends and LLM-specific operators. The QNN SDK can be downloaded [here](https://www.qualcomm.com/developer/software/qualcomm-ai-engine-direct-sdk). The Hexagon SDK can be downloaded using [QPM](https://qpm.qualcomm.com/). The compiling environment only supports Linux now. Version requirements: -* QNN: [Linux v2.20+](https://qpm.qualcomm.com/#/main/tools/details/qualcomm_neural_processing_sdk) +* QNN: [Linux v2.31+](https://qpm.qualcomm.com/#/main/tools/details/qualcomm_neural_processing_sdk) * Hexagon SDK: [Linux 5.x](https://qpm.qualcomm.com/#/main/tools/details/HexagonSDK5.x) (Some accounts may have no permission to access this SDK and may need to contact Qualcomm for support.) **NOTE:** After downloading the QNN SDK, unzip the file and move the folder name like `qairt/2.31.0.250130` to `src/backends/qnn/` and rename the version to 'sdk'. The folder structure should be like `src/backends/qnn/sdk`. diff --git a/src/backends/qnn/Utils/QnnSampleAppUtils.cpp b/src/backends/qnn/Utils/QnnSampleAppUtils.cpp index d38bf9948..6a213ed02 100644 --- a/src/backends/qnn/Utils/QnnSampleAppUtils.cpp +++ b/src/backends/qnn/Utils/QnnSampleAppUtils.cpp @@ -1,7 +1,7 @@ //============================================================================== // -// Copyright (c) 2019-2023 Qualcomm Technologies, Inc. -// All Rights Reserved. +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All rights reserved. // Confidential and Proprietary - Qualcomm Technologies, Inc. // //============================================================================== @@ -14,12 +14,14 @@ #include #include -#include "Log/Logger.hpp" +#include "Logger.hpp" +#ifndef __hexagon__ #include "PAL/Directory.hpp" #include "PAL/FileOp.hpp" #include "PAL/Path.hpp" +#endif #include "PAL/StringOp.hpp" -#include "Utils/QnnSampleAppUtils.hpp" +#include "QnnSampleAppUtils.hpp" #include "QnnTypeMacros.hpp" using namespace qnn; @@ -29,312 +31,411 @@ using namespace qnn_wrapper_api; void sample_app::split(std::vector &splitString, const std::string &tokenizedString, const char separator) { - splitString.clear(); - std::istringstream tokenizedStringStream(tokenizedString); - while (!tokenizedStringStream.eof()) { - std::string value; - getline(tokenizedStringStream, value, separator); - if (!value.empty()) { - splitString.push_back(value); + splitString.clear(); + std::istringstream tokenizedStringStream(tokenizedString); + while (!tokenizedStringStream.eof()) { + std::string value; + getline(tokenizedStringStream, value, separator); + if (!value.empty()) { + splitString.push_back(value); + } } - } } void sample_app::parseInputFilePaths(std::vector &inputFilePaths, std::vector &paths, std::string separator) { - for (auto &inputInfo : inputFilePaths) { - auto position = inputInfo.find(separator); - if (position != std::string::npos) { - auto path = inputInfo.substr(position + separator.size()); - paths.push_back(path); - } else { - paths.push_back(inputInfo); + for (auto &inputInfo : inputFilePaths) { + auto position = inputInfo.find(separator); + if (position != std::string::npos) { + auto path = inputInfo.substr(position + separator.size()); + paths.push_back(path); + } else { + paths.push_back(inputInfo); + } } - } } sample_app::ReadInputListsRetType_t sample_app::readInputLists( std::vector inputFileListPaths) { - std::vector>> filePathsLists; - for (auto const &path : inputFileListPaths) { - bool readSuccess; - std::vector> filePathList; - std::tie(filePathList, readSuccess) = readInputList(path); - if (!readSuccess) { - filePathsLists.clear(); - return std::make_tuple(filePathsLists, false); + std::vector>> filePathsLists; + std::vector> inputNameToIndexMaps; + for (auto const &path : inputFileListPaths) { + bool readSuccess; + std::vector> filePathList; + std::unordered_map inputNameToIndex; + std::tie(filePathList, inputNameToIndex, readSuccess) = readInputList(path); + if (!readSuccess) { + filePathsLists.clear(); + return std::make_tuple(filePathsLists, inputNameToIndexMaps, false); + } + filePathsLists.push_back(filePathList); + inputNameToIndexMaps.push_back(inputNameToIndex); } - filePathsLists.push_back(filePathList); - } - return std::make_tuple(filePathsLists, true); + return std::make_tuple(filePathsLists, inputNameToIndexMaps, true); } sample_app::ReadInputListRetType_t sample_app::readInputList(const std::string inputFileListPath) { - std::queue lines; - std::ifstream fileListStream(inputFileListPath); - if (!fileListStream) { - QNN_ERROR("Failed to open input file: %s", inputFileListPath.c_str()); - std::vector> result; - return std::make_tuple(result, false); - } - std::string fileLine; - while (std::getline(fileListStream, fileLine)) { - if (fileLine.empty()) continue; - lines.push(fileLine); - } - if (!lines.empty() && lines.front().compare(0, 1, "#") == 0) { - lines.pop(); - } - std::string separator = ":="; - std::vector> filePathsList; - while (!lines.empty()) { - std::vector paths{}; + std::queue lines; + std::ifstream fileListStream(inputFileListPath); + if (!fileListStream) { + QNN_ERROR("Failed to open input file: %s", inputFileListPath.c_str()); + return std::make_tuple(std::vector>{}, + std::unordered_map{}, + false); + } + + std::string fileLine; + while (std::getline(fileListStream, fileLine)) { + if (fileLine.empty()) continue; + lines.push(fileLine); + } + + if (!lines.empty() && lines.front().compare(0, 1, "#") == 0) { + lines.pop(); + } + + if (!lines.empty() && lines.front().compare(0, 1, "%") == 0) { + lines.pop(); + } + + std::string separator = ":="; + std::vector> filePathsList; + std::unordered_map inputNameToIndex; + if (!lines.empty()) { + inputNameToIndex = extractInputNameIndices(lines.front(), separator); + } + while (!lines.empty()) { + std::vector paths{}; + std::vector inputFilePaths; + split(inputFilePaths, lines.front(), ' '); + parseInputFilePaths(inputFilePaths, paths, separator); + filePathsList.reserve(paths.size()); + for (size_t idx = 0; idx < paths.size(); idx++) { + if (idx >= filePathsList.size()) { + filePathsList.push_back(std::vector()); + } + filePathsList[idx].push_back(paths[idx]); + } + lines.pop(); + } + return std::make_tuple(filePathsList, inputNameToIndex, true); +} + +std::unordered_map sample_app::extractInputNameIndices( + const std::string &inputLine, const std::string &separator) { std::vector inputFilePaths; - split(inputFilePaths, lines.front(), ' '); - parseInputFilePaths(inputFilePaths, paths, separator); - // TODO: multi input support - filePathsList.reserve(paths.size()); - for (size_t idx = 0; idx < paths.size(); idx++) { - if (idx >= filePathsList.size()) { - filePathsList.push_back(std::queue()); - } - filePathsList.back().push(paths[idx]); + std::unordered_map inputNameToIndex; + split(inputFilePaths, inputLine, ' '); + size_t inputCount = 0; + for (uint32_t idx = 0; idx < inputFilePaths.size(); idx++) { + auto position = inputFilePaths[idx].find(separator); + if (position != std::string::npos) { + auto unsanitizedTensorName = inputFilePaths[idx].substr(0, position); + auto sanitizedTensorName = sanitizeTensorName(unsanitizedTensorName); + if (sanitizedTensorName != unsanitizedTensorName) { + inputNameToIndex[unsanitizedTensorName] = idx; + } + inputNameToIndex[sanitizedTensorName] = idx; + inputCount = inputCount + 1; + } } - lines.pop(); - } - return std::make_tuple(filePathsList, true); + return inputCount == inputFilePaths.size() ? inputNameToIndex : std::unordered_map{}; +} + +std::string sample_app::sanitizeTensorName(std::string name) { + std::string sanitizedName = std::regex_replace(name, std::regex("\\W+"), "_"); + if (!std::isalpha(sanitizedName[0]) && sanitizedName[0] != '_') { + sanitizedName = "_" + sanitizedName; + } + return sanitizedName; } sample_app::ProfilingLevel sample_app::parseProfilingLevel(std::string profilingLevelString) { - std::transform(profilingLevelString.begin(), - profilingLevelString.end(), - profilingLevelString.begin(), - ::tolower); - ProfilingLevel parsedProfilingLevel = ProfilingLevel::INVALID; - if (profilingLevelString == "off") { - parsedProfilingLevel = ProfilingLevel::OFF; - } else if (profilingLevelString == "basic") { - parsedProfilingLevel = ProfilingLevel::BASIC; - } else if (profilingLevelString == "detailed") { - parsedProfilingLevel = ProfilingLevel::DETAILED; - } - return parsedProfilingLevel; + std::transform(profilingLevelString.begin(), + profilingLevelString.end(), + profilingLevelString.begin(), + ::tolower); + ProfilingLevel parsedProfilingLevel = ProfilingLevel::INVALID; + if (profilingLevelString == "off") { + parsedProfilingLevel = ProfilingLevel::OFF; + } else if (profilingLevelString == "basic") { + parsedProfilingLevel = ProfilingLevel::BASIC; + } else if (profilingLevelString == "detailed") { + parsedProfilingLevel = ProfilingLevel::DETAILED; + } + return parsedProfilingLevel; } bool sample_app::deepCopyQnnTensorInfo(Qnn_Tensor_t *dst, const Qnn_Tensor_t *src) { - if (nullptr == dst || nullptr == src) { - QNN_ERROR("Received nullptr"); - return false; - } - // set tensor.version before using QNN_TENSOR_SET macros, as they require the version to be set - // to correctly assign values - dst->version = src->version; - const char *tensorName = QNN_TENSOR_GET_NAME(src); - if (!tensorName) { - QNN_TENSOR_SET_NAME(dst, nullptr); - } else { - QNN_TENSOR_SET_NAME(dst, pal::StringOp::strndup(tensorName, strlen(tensorName))); - } - QNN_TENSOR_SET_ID(dst, QNN_TENSOR_GET_ID(src)); - QNN_TENSOR_SET_TYPE(dst, QNN_TENSOR_GET_TYPE(src)); - QNN_TENSOR_SET_DATA_FORMAT(dst, QNN_TENSOR_GET_DATA_FORMAT(src)); - QNN_TENSOR_SET_DATA_TYPE(dst, QNN_TENSOR_GET_DATA_TYPE(src)); - Qnn_QuantizeParams_t qParams = QNN_QUANTIZE_PARAMS_INIT; - qParams.encodingDefinition = QNN_TENSOR_GET_QUANT_PARAMS(src).encodingDefinition; - qParams.quantizationEncoding = QNN_QUANTIZATION_ENCODING_UNDEFINED; - if (QNN_TENSOR_GET_QUANT_PARAMS(src).quantizationEncoding == - QNN_QUANTIZATION_ENCODING_SCALE_OFFSET) { - qParams.quantizationEncoding = QNN_TENSOR_GET_QUANT_PARAMS(src).quantizationEncoding; - qParams.scaleOffsetEncoding = QNN_TENSOR_GET_QUANT_PARAMS(src).scaleOffsetEncoding; - } else if (QNN_TENSOR_GET_QUANT_PARAMS(src).quantizationEncoding == - QNN_QUANTIZATION_ENCODING_AXIS_SCALE_OFFSET) { - qParams.quantizationEncoding = QNN_TENSOR_GET_QUANT_PARAMS(src).quantizationEncoding; - qParams.axisScaleOffsetEncoding.axis = - QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.axis; - qParams.axisScaleOffsetEncoding.numScaleOffsets = - QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.numScaleOffsets; - if (QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.numScaleOffsets > 0) { - qParams.axisScaleOffsetEncoding.scaleOffset = (Qnn_ScaleOffset_t *)malloc( - QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.numScaleOffsets * - sizeof(Qnn_ScaleOffset_t)); - if (qParams.axisScaleOffsetEncoding.scaleOffset) { - for (size_t idx = 0; - idx < QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.numScaleOffsets; - idx++) { - qParams.axisScaleOffsetEncoding.scaleOffset[idx].scale = - QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.scaleOffset[idx].scale; - qParams.axisScaleOffsetEncoding.scaleOffset[idx].offset = - QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.scaleOffset[idx].offset; + if (nullptr == dst || nullptr == src) { + QNN_ERROR("Received nullptr"); + return false; + } + // set tensor.version before using QNN_TENSOR_SET macros, as they require the version to be set + // to correctly assign values + dst->version = src->version; + const char *tensorName = QNN_TENSOR_GET_NAME(src); + if (!tensorName) { + QNN_TENSOR_SET_NAME(dst, nullptr); + } else { + QNN_TENSOR_SET_NAME(dst, pal::StringOp::strndup(tensorName, strlen(tensorName))); + } + QNN_TENSOR_SET_ID(dst, QNN_TENSOR_GET_ID(src)); + QNN_TENSOR_SET_TYPE(dst, QNN_TENSOR_GET_TYPE(src)); + QNN_TENSOR_SET_DATA_FORMAT(dst, QNN_TENSOR_GET_DATA_FORMAT(src)); + QNN_TENSOR_SET_DATA_TYPE(dst, QNN_TENSOR_GET_DATA_TYPE(src)); + Qnn_QuantizeParams_t qParams = QNN_QUANTIZE_PARAMS_INIT; + qParams.encodingDefinition = QNN_TENSOR_GET_QUANT_PARAMS(src).encodingDefinition; + qParams.quantizationEncoding = QNN_QUANTIZATION_ENCODING_UNDEFINED; + if (QNN_TENSOR_GET_QUANT_PARAMS(src).quantizationEncoding == QNN_QUANTIZATION_ENCODING_SCALE_OFFSET) { + qParams.quantizationEncoding = QNN_TENSOR_GET_QUANT_PARAMS(src).quantizationEncoding; + qParams.scaleOffsetEncoding = QNN_TENSOR_GET_QUANT_PARAMS(src).scaleOffsetEncoding; + } else if (QNN_TENSOR_GET_QUANT_PARAMS(src).quantizationEncoding == QNN_QUANTIZATION_ENCODING_AXIS_SCALE_OFFSET) { + qParams.quantizationEncoding = QNN_TENSOR_GET_QUANT_PARAMS(src).quantizationEncoding; + qParams.axisScaleOffsetEncoding.axis = + QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.axis; + qParams.axisScaleOffsetEncoding.numScaleOffsets = + QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.numScaleOffsets; + if (QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.numScaleOffsets > 0) { + qParams.axisScaleOffsetEncoding.scaleOffset = (Qnn_ScaleOffset_t *)malloc( + QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.numScaleOffsets * sizeof(Qnn_ScaleOffset_t)); + if (qParams.axisScaleOffsetEncoding.scaleOffset) { + for (size_t idx = 0; + idx < QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.numScaleOffsets; + idx++) { + qParams.axisScaleOffsetEncoding.scaleOffset[idx].scale = + QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.scaleOffset[idx].scale; + qParams.axisScaleOffsetEncoding.scaleOffset[idx].offset = + QNN_TENSOR_GET_QUANT_PARAMS(src).axisScaleOffsetEncoding.scaleOffset[idx].offset; + } + } } - } } - } - QNN_TENSOR_SET_QUANT_PARAMS(dst, qParams); - QNN_TENSOR_SET_RANK(dst, QNN_TENSOR_GET_RANK(src)); - QNN_TENSOR_SET_DIMENSIONS(dst, nullptr); - if (QNN_TENSOR_GET_RANK(src) > 0) { - QNN_TENSOR_SET_DIMENSIONS(dst, (uint32_t *)malloc(QNN_TENSOR_GET_RANK(src) * sizeof(uint32_t))); - if (QNN_TENSOR_GET_DIMENSIONS(dst)) { - pal::StringOp::memscpy(QNN_TENSOR_GET_DIMENSIONS(dst), - QNN_TENSOR_GET_RANK(src) * sizeof(uint32_t), - QNN_TENSOR_GET_DIMENSIONS(src), - QNN_TENSOR_GET_RANK(src) * sizeof(uint32_t)); + QNN_TENSOR_SET_QUANT_PARAMS(dst, qParams); + QNN_TENSOR_SET_RANK(dst, QNN_TENSOR_GET_RANK(src)); + QNN_TENSOR_SET_DIMENSIONS(dst, nullptr); + if (QNN_TENSOR_GET_RANK(src) > 0) { + QNN_TENSOR_SET_DIMENSIONS(dst, (uint32_t *)malloc(QNN_TENSOR_GET_RANK(src) * sizeof(uint32_t))); + if (QNN_TENSOR_GET_DIMENSIONS(dst)) { + pal::StringOp::memscpy(QNN_TENSOR_GET_DIMENSIONS(dst), + QNN_TENSOR_GET_RANK(src) * sizeof(uint32_t), + QNN_TENSOR_GET_DIMENSIONS(src), + QNN_TENSOR_GET_RANK(src) * sizeof(uint32_t)); + } + if (QNN_TENSOR_GET_IS_DYNAMIC_DIMENSIONS(src)) { + QNN_TENSOR_SET_IS_DYNAMIC_DIMENSIONS( + dst, (uint8_t *)malloc(QNN_TENSOR_GET_RANK(src) * sizeof(uint8_t))); + pal::StringOp::memscpy(QNN_TENSOR_GET_IS_DYNAMIC_DIMENSIONS(dst), + QNN_TENSOR_GET_RANK(src) * sizeof(uint8_t), + QNN_TENSOR_GET_IS_DYNAMIC_DIMENSIONS(src), + QNN_TENSOR_GET_RANK(src) * sizeof(uint8_t)); + } } - } - return true; + QNN_TENSOR_SET_SPARSE_PARAMS(dst, QNN_TENSOR_GET_SPARSE_PARAMS(src)); + return true; } bool sample_app::copyTensorsInfo(const Qnn_Tensor_t *tensorsInfoSrc, Qnn_Tensor_t *&tensorWrappers, uint32_t tensorsCount) { - QNN_FUNCTION_ENTRY_LOG; - auto returnStatus = true; - tensorWrappers = (Qnn_Tensor_t *)calloc(tensorsCount, sizeof(Qnn_Tensor_t)); - if (nullptr == tensorWrappers) { - QNN_ERROR("Failed to allocate memory for tensorWrappers."); - return false; - } - if (returnStatus) { - for (size_t tIdx = 0; tIdx < tensorsCount; tIdx++) { - QNN_DEBUG("Extracting tensorInfo for tensor Idx: %d", tIdx); - tensorWrappers[tIdx] = QNN_TENSOR_INIT; - deepCopyQnnTensorInfo(&tensorWrappers[tIdx], &tensorsInfoSrc[tIdx]); + QNN_FUNCTION_ENTRY_LOG; + auto returnStatus = true; + tensorWrappers = (Qnn_Tensor_t *)calloc(tensorsCount, sizeof(Qnn_Tensor_t)); + if (nullptr == tensorWrappers) { + QNN_ERROR("Failed to allocate memory for tensorWrappers."); + return false; + } + if (returnStatus) { + for (size_t tIdx = 0; tIdx < tensorsCount; tIdx++) { + QNN_DEBUG("Extracting tensorInfo for tensor Idx: %d", tIdx); + tensorWrappers[tIdx] = QNN_TENSOR_INIT; + deepCopyQnnTensorInfo(&tensorWrappers[tIdx], &tensorsInfoSrc[tIdx]); + } } - } - QNN_FUNCTION_EXIT_LOG; - return returnStatus; + QNN_FUNCTION_EXIT_LOG; + return returnStatus; } bool sample_app::copyGraphsInfoV1(const QnnSystemContext_GraphInfoV1_t *graphInfoSrc, qnn_wrapper_api::GraphInfo_t *graphInfoDst) { - graphInfoDst->graphName = nullptr; - if (graphInfoSrc->graphName) { - graphInfoDst->graphName = - pal::StringOp::strndup(graphInfoSrc->graphName, strlen(graphInfoSrc->graphName)); - } - graphInfoDst->inputTensors = nullptr; - graphInfoDst->numInputTensors = 0; - if (graphInfoSrc->graphInputs) { - if (!copyTensorsInfo( - graphInfoSrc->graphInputs, graphInfoDst->inputTensors, graphInfoSrc->numGraphInputs)) { - return false; + graphInfoDst->graphName = nullptr; + if (graphInfoSrc->graphName) { + graphInfoDst->graphName = + pal::StringOp::strndup(graphInfoSrc->graphName, strlen(graphInfoSrc->graphName)); + } + graphInfoDst->inputTensors = nullptr; + graphInfoDst->numInputTensors = 0; + if (graphInfoSrc->graphInputs) { + if (!copyTensorsInfo( + graphInfoSrc->graphInputs, graphInfoDst->inputTensors, graphInfoSrc->numGraphInputs)) { + return false; + } + graphInfoDst->numInputTensors = graphInfoSrc->numGraphInputs; + } + graphInfoDst->outputTensors = nullptr; + graphInfoDst->numOutputTensors = 0; + if (graphInfoSrc->graphOutputs) { + if (!copyTensorsInfo(graphInfoSrc->graphOutputs, + graphInfoDst->outputTensors, + graphInfoSrc->numGraphOutputs)) { + return false; + } + graphInfoDst->numOutputTensors = graphInfoSrc->numGraphOutputs; } - graphInfoDst->numInputTensors = graphInfoSrc->numGraphInputs; - } - graphInfoDst->outputTensors = nullptr; - graphInfoDst->numOutputTensors = 0; - if (graphInfoSrc->graphOutputs) { - if (!copyTensorsInfo(graphInfoSrc->graphOutputs, - graphInfoDst->outputTensors, - graphInfoSrc->numGraphOutputs)) { - return false; + return true; +} + +bool sample_app::copyGraphsInfoV3(const QnnSystemContext_GraphInfoV3_t *graphInfoSrc, + qnn_wrapper_api::GraphInfo_t *graphInfoDst) { + graphInfoDst->graphName = nullptr; + if (graphInfoSrc->graphName) { + graphInfoDst->graphName = + pal::StringOp::strndup(graphInfoSrc->graphName, strlen(graphInfoSrc->graphName)); + } + graphInfoDst->inputTensors = nullptr; + graphInfoDst->numInputTensors = 0; + if (graphInfoSrc->graphInputs) { + if (!copyTensorsInfo( + graphInfoSrc->graphInputs, graphInfoDst->inputTensors, graphInfoSrc->numGraphInputs)) { + return false; + } + graphInfoDst->numInputTensors = graphInfoSrc->numGraphInputs; + } + graphInfoDst->outputTensors = nullptr; + graphInfoDst->numOutputTensors = 0; + if (graphInfoSrc->graphOutputs) { + if (!copyTensorsInfo(graphInfoSrc->graphOutputs, + graphInfoDst->outputTensors, + graphInfoSrc->numGraphOutputs)) { + return false; + } + graphInfoDst->numOutputTensors = graphInfoSrc->numGraphOutputs; } - graphInfoDst->numOutputTensors = graphInfoSrc->numGraphOutputs; - } - return true; + return true; } bool sample_app::copyGraphsInfo(const QnnSystemContext_GraphInfo_t *graphsInput, const uint32_t numGraphs, qnn_wrapper_api::GraphInfo_t **&graphsInfo) { - QNN_FUNCTION_ENTRY_LOG; - if (!graphsInput) { - QNN_ERROR("Received nullptr for graphsInput."); - return false; - } - auto returnStatus = true; - graphsInfo = - (qnn_wrapper_api::GraphInfo_t **)calloc(numGraphs, sizeof(qnn_wrapper_api::GraphInfo_t *)); - qnn_wrapper_api::GraphInfo_t *graphInfoArr = - (qnn_wrapper_api::GraphInfo_t *)calloc(numGraphs, sizeof(qnn_wrapper_api::GraphInfo_t)); - if (nullptr == graphsInfo || nullptr == graphInfoArr) { - QNN_ERROR("Failure to allocate memory for *graphInfo"); - returnStatus = false; - } - if (true == returnStatus) { - for (size_t gIdx = 0; gIdx < numGraphs; gIdx++) { - QNN_DEBUG("Extracting graphsInfo for graph Idx: %d", gIdx); - if (graphsInput[gIdx].version == QNN_SYSTEM_CONTEXT_GRAPH_INFO_VERSION_1) { - copyGraphsInfoV1(&graphsInput[gIdx].graphInfoV1, &graphInfoArr[gIdx]); - } - graphsInfo[gIdx] = graphInfoArr + gIdx; + QNN_FUNCTION_ENTRY_LOG; + if (!graphsInput) { + QNN_ERROR("Received nullptr for graphsInput."); + return false; } - } - if (true != returnStatus) { - QNN_ERROR("Received an ERROR during extractGraphsInfo. Freeing resources."); - if (graphsInfo) { - for (uint32_t gIdx = 0; gIdx < numGraphs; gIdx++) { - if (graphsInfo[gIdx]) { - if (nullptr != graphsInfo[gIdx]->graphName) { - free(graphsInfo[gIdx]->graphName); - graphsInfo[gIdx]->graphName = nullptr; - } - qnn_wrapper_api::freeQnnTensors(graphsInfo[gIdx]->inputTensors, - graphsInfo[gIdx]->numInputTensors); - qnn_wrapper_api::freeQnnTensors(graphsInfo[gIdx]->outputTensors, - graphsInfo[gIdx]->numOutputTensors); + auto returnStatus = true; + graphsInfo = + (qnn_wrapper_api::GraphInfo_t **)calloc(numGraphs, sizeof(qnn_wrapper_api::GraphInfo_t *)); + qnn_wrapper_api::GraphInfo_t *graphInfoArr = + (qnn_wrapper_api::GraphInfo_t *)calloc(numGraphs, sizeof(qnn_wrapper_api::GraphInfo_t)); + if (nullptr == graphsInfo || nullptr == graphInfoArr) { + QNN_ERROR("Failure to allocate memory for *graphInfo"); + returnStatus = false; + } + if (true == returnStatus) { + for (size_t gIdx = 0; gIdx < numGraphs; gIdx++) { + QNN_DEBUG("Extracting graphsInfo for graph Idx: %d", gIdx); + if (graphsInput[gIdx].version == QNN_SYSTEM_CONTEXT_GRAPH_INFO_VERSION_1) { + copyGraphsInfoV1(&graphsInput[gIdx].graphInfoV1, &graphInfoArr[gIdx]); + } else if (graphsInput[gIdx].version == QNN_SYSTEM_CONTEXT_GRAPH_INFO_VERSION_3) { + copyGraphsInfoV3(&graphsInput[gIdx].graphInfoV3, &graphInfoArr[gIdx]); + } + graphsInfo[gIdx] = graphInfoArr + gIdx; } - } - free(*graphsInfo); } - free(graphsInfo); - graphsInfo = nullptr; - } - QNN_FUNCTION_EXIT_LOG; - return true; + if (true != returnStatus) { + QNN_ERROR("Received an ERROR during extractGraphsInfo. Freeing resources."); + if (graphsInfo) { + for (uint32_t gIdx = 0; gIdx < numGraphs; gIdx++) { + if (graphsInfo[gIdx]) { + if (nullptr != graphsInfo[gIdx]->graphName) { + free(graphsInfo[gIdx]->graphName); + graphsInfo[gIdx]->graphName = nullptr; + } + qnn_wrapper_api::freeQnnTensors(graphsInfo[gIdx]->inputTensors, + graphsInfo[gIdx]->numInputTensors); + qnn_wrapper_api::freeQnnTensors(graphsInfo[gIdx]->outputTensors, + graphsInfo[gIdx]->numOutputTensors); + } + } + free(*graphsInfo); + } + free(graphsInfo); + graphsInfo = nullptr; + } + QNN_FUNCTION_EXIT_LOG; + return true; } bool sample_app::copyMetadataToGraphsInfo(const QnnSystemContext_BinaryInfo_t *binaryInfo, qnn_wrapper_api::GraphInfo_t **&graphsInfo, uint32_t &graphsCount) { - if (nullptr == binaryInfo) { - QNN_ERROR("binaryInfo is nullptr."); - return false; - } - graphsCount = 0; - if (binaryInfo->version == QNN_SYSTEM_CONTEXT_BINARY_INFO_VERSION_1) { - if (binaryInfo->contextBinaryInfoV1.graphs) { - if (!copyGraphsInfo(binaryInfo->contextBinaryInfoV1.graphs, - binaryInfo->contextBinaryInfoV1.numGraphs, - graphsInfo)) { - QNN_ERROR("Failed while copying graphs Info."); + if (nullptr == binaryInfo) { + QNN_ERROR("binaryInfo is nullptr."); return false; - } - graphsCount = binaryInfo->contextBinaryInfoV1.numGraphs; - return true; } - } else if (binaryInfo->version == QNN_SYSTEM_CONTEXT_BINARY_INFO_VERSION_2) { - if (binaryInfo->contextBinaryInfoV2.graphs) { - if (!copyGraphsInfo(binaryInfo->contextBinaryInfoV2.graphs, - binaryInfo->contextBinaryInfoV2.numGraphs, - graphsInfo)) { - QNN_ERROR("Failed while copying graphs Info."); - return false; - } - graphsCount = binaryInfo->contextBinaryInfoV2.numGraphs; - return true; + graphsCount = 0; + if (binaryInfo->version == QNN_SYSTEM_CONTEXT_BINARY_INFO_VERSION_1) { + if (binaryInfo->contextBinaryInfoV1.graphs) { + if (!copyGraphsInfo(binaryInfo->contextBinaryInfoV1.graphs, + binaryInfo->contextBinaryInfoV1.numGraphs, + graphsInfo)) { + QNN_ERROR("Failed while copying graphs Info."); + return false; + } + graphsCount = binaryInfo->contextBinaryInfoV1.numGraphs; + return true; + } + } else if (binaryInfo->version == QNN_SYSTEM_CONTEXT_BINARY_INFO_VERSION_2) { + if (binaryInfo->contextBinaryInfoV2.graphs) { + if (!copyGraphsInfo(binaryInfo->contextBinaryInfoV2.graphs, + binaryInfo->contextBinaryInfoV2.numGraphs, + graphsInfo)) { + QNN_ERROR("Failed while copying graphs Info."); + return false; + } + graphsCount = binaryInfo->contextBinaryInfoV2.numGraphs; + return true; + } + } else if (binaryInfo->version == QNN_SYSTEM_CONTEXT_BINARY_INFO_VERSION_3) { + if (binaryInfo->contextBinaryInfoV3.graphs) { + if (!copyGraphsInfo(binaryInfo->contextBinaryInfoV3.graphs, + binaryInfo->contextBinaryInfoV3.numGraphs, + graphsInfo)) { + QNN_ERROR("Failed while copying graphs Info."); + return false; + } + graphsCount = binaryInfo->contextBinaryInfoV3.numGraphs; + return true; + } } - } - QNN_ERROR("Unrecognized system context binary info version."); - return false; + QNN_ERROR("Unrecognized system context binary info version."); + return false; } QnnLog_Level_t sample_app::parseLogLevel(std::string logLevelString) { - QNN_FUNCTION_ENTRY_LOG; - std::transform(logLevelString.begin(), logLevelString.end(), logLevelString.begin(), ::tolower); - QnnLog_Level_t parsedLogLevel = QNN_LOG_LEVEL_MAX; - if (logLevelString == "error") { - parsedLogLevel = QNN_LOG_LEVEL_ERROR; - } else if (logLevelString == "warn") { - parsedLogLevel = QNN_LOG_LEVEL_WARN; - } else if (logLevelString == "info") { - parsedLogLevel = QNN_LOG_LEVEL_INFO; - } else if (logLevelString == "verbose") { - parsedLogLevel = QNN_LOG_LEVEL_VERBOSE; - } else if (logLevelString == "debug") { - parsedLogLevel = QNN_LOG_LEVEL_DEBUG; - } - QNN_FUNCTION_EXIT_LOG; - return parsedLogLevel; + QNN_FUNCTION_ENTRY_LOG; + std::transform(logLevelString.begin(), logLevelString.end(), logLevelString.begin(), ::tolower); + QnnLog_Level_t parsedLogLevel = QNN_LOG_LEVEL_MAX; + if (logLevelString == "error") { + parsedLogLevel = QNN_LOG_LEVEL_ERROR; + } else if (logLevelString == "warn") { + parsedLogLevel = QNN_LOG_LEVEL_WARN; + } else if (logLevelString == "info") { + parsedLogLevel = QNN_LOG_LEVEL_INFO; + } else if (logLevelString == "verbose") { + parsedLogLevel = QNN_LOG_LEVEL_VERBOSE; + } else if (logLevelString == "debug") { + parsedLogLevel = QNN_LOG_LEVEL_DEBUG; + } + QNN_FUNCTION_EXIT_LOG; + return parsedLogLevel; +} + +unsigned int sample_app::parseNumInferences(std::string numString) { + unsigned int num = 0; + std::stringstream numStream; + numStream << numString; + numStream >> num; + return num; } diff --git a/src/backends/qnn/Utils/QnnSampleAppUtils.hpp b/src/backends/qnn/Utils/QnnSampleAppUtils.hpp index d9f223230..4fcbfc148 100644 --- a/src/backends/qnn/Utils/QnnSampleAppUtils.hpp +++ b/src/backends/qnn/Utils/QnnSampleAppUtils.hpp @@ -1,7 +1,7 @@ //============================================================================== // -// Copyright (c) 2019-2022 Qualcomm Technologies, Inc. -// All Rights Reserved. +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All rights reserved. // Confidential and Proprietary - Qualcomm Technologies, Inc. // //============================================================================== @@ -10,7 +10,9 @@ #include #include #include +#include #include +#include #include #include @@ -20,16 +22,27 @@ namespace qnn { namespace tools { namespace sample_app { -enum class ProfilingLevel { OFF, BASIC, DETAILED, INVALID }; +enum class ProfilingLevel { OFF, + BASIC, + DETAILED, + INVALID }; -using ReadInputListRetType_t = std::tuple>, bool>; +using ReadInputListRetType_t = std:: + tuple>, std::unordered_map, bool>; ReadInputListRetType_t readInputList(std::string inputFileListPath); -using ReadInputListsRetType_t = std::tuple>>, bool>; +using ReadInputListsRetType_t = std::tuple>>, + std::vector>, + bool>; ReadInputListsRetType_t readInputLists(std::vector inputFileListPath); +std::unordered_map extractInputNameIndices(const std::string &inputLine, + const std::string &separator); + +std::string sanitizeTensorName(std::string name); + ProfilingLevel parseProfilingLevel(std::string profilingLevelString); void parseInputFilePaths(std::vector &inputFilePaths, @@ -51,6 +64,9 @@ bool copyGraphsInfo(const QnnSystemContext_GraphInfo_t *graphsInput, bool copyGraphsInfoV1(const QnnSystemContext_GraphInfoV1_t *graphInfoSrc, qnn_wrapper_api::GraphInfo_t *graphInfoDst); +bool copyGraphsInfoV3(const QnnSystemContext_GraphInfoV3_t *graphInfoSrc, + qnn_wrapper_api::GraphInfo_t *graphInfoDst); + bool copyTensorsInfo(const Qnn_Tensor_t *tensorsInfoSrc, Qnn_Tensor_t *&tensorWrappers, uint32_t tensorsCount); @@ -59,11 +75,13 @@ bool deepCopyQnnTensorInfo(Qnn_Tensor_t *dst, const Qnn_Tensor_t *src); QnnLog_Level_t parseLogLevel(std::string logLevelString); +unsigned int parseNumInferences(std::string numString); + void inline exitWithMessage(std::string &&msg, int code) { - std::cerr << msg << std::endl; - std::exit(code); + std::cerr << msg << std::endl; + std::exit(code); } -} // namespace sample_app -} // namespace tools -} // namespace qnn \ No newline at end of file +} +} +} // namespace qnn::tools::sample_app \ No newline at end of file diff --git a/src/backends/qnn/WrapperUtils/QnnWrapperUtils.cpp b/src/backends/qnn/WrapperUtils/QnnWrapperUtils.cpp index b70180308..afbec492d 100644 --- a/src/backends/qnn/WrapperUtils/QnnWrapperUtils.cpp +++ b/src/backends/qnn/WrapperUtils/QnnWrapperUtils.cpp @@ -1,198 +1,55 @@ //============================================================================== // -// Copyright (c) 2019-2022 Qualcomm Technologies, Inc. -// All Rights Reserved. +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All rights reserved. // Confidential and Proprietary - Qualcomm Technologies, Inc. // //============================================================================== -#include -#include -#include +#include -#include "QnnModelPal.hpp" #include "QnnTypeMacros.hpp" #include "QnnWrapperUtils.hpp" -namespace qnn_wrapper_api { -size_t memscpy(void *dst, size_t dstSize, const void *src, size_t copySize) { - if (!dst || !src || !dstSize || !copySize) return 0; - - size_t minSize = dstSize < copySize ? dstSize : copySize; - - memcpy(dst, src, minSize); - - return minSize; -} - -ModelError_t getQnnGraphConfigFromInfo(const char *graphName, - const GraphConfigInfo_t **graphsConfigInfo, - const uint32_t numGraphsConfigInfo, - const QnnGraph_Config_t **&graphConfigs) { - if (!graphsConfigInfo || numGraphsConfigInfo == 0) { - PRINT_DEBUG("getQnnGraphConfigFromInfo() no custom configs passed for graph:%s.\n", graphName); - return MODEL_NO_ERROR; - } - - size_t found = 0; - - for (uint32_t i = 0; i < numGraphsConfigInfo; i++) { - if (!graphsConfigInfo[i]) { - PRINT_ERROR( - "getQnnGraphConfigFromInfo() lookup error while trying to query graphName:%s. " - "numGraphsConfigInfo > num of element in graphsConfigInfo\n", - graphName); - return MODEL_INVALID_ARGUMENT_ERROR; +qnn_wrapper_api::ModelError_t qnn_wrapper_api::freeQnnTensor(Qnn_Tensor_t &tensor) { + // free all pointer allocations in struct + free((void *)QNN_TENSOR_GET_NAME(tensor)); + free(QNN_TENSOR_GET_DIMENSIONS(tensor)); + if (QNN_TENSOR_GET_IS_DYNAMIC_DIMENSIONS(tensor)) { + free(QNN_TENSOR_GET_IS_DYNAMIC_DIMENSIONS(tensor)); } - if (strcmp(graphsConfigInfo[i]->graphName, graphName) == 0) { - graphConfigs = graphsConfigInfo[i]->graphConfigs; - found++; + auto quant = QNN_TENSOR_GET_QUANT_PARAMS(tensor); + auto encoding = quant.quantizationEncoding; + if (encoding == QNN_QUANTIZATION_ENCODING_AXIS_SCALE_OFFSET) { + if (quant.axisScaleOffsetEncoding.scaleOffset != nullptr) { + free(quant.axisScaleOffsetEncoding.scaleOffset); + } } - } - - if (!found) { - PRINT_ERROR( - "getQnnGraphConfigFromInfo() unable to find graphName:%s in provided " - "graphsConfigInfo object.\n", - graphName); - return MODEL_INVALID_ARGUMENT_ERROR; - } else if (found > 1) { - PRINT_ERROR( - "getQnnGraphConfigFromInfo() duplicate GraphConfigInfo entries found with " - "graphName:%s.\n", - graphName); - return MODEL_INVALID_ARGUMENT_ERROR; - } else { return MODEL_NO_ERROR; - } } -ModelError_t deepCopyQnnTensors(Qnn_Tensor_t &src, Qnn_Tensor_t &dst) { - ModelError_t err; - VALIDATE_TENSOR_VERSION(src, err); - - dst.version = src.version; - QNN_TENSOR_SET_NAME( - dst, strnDup(QNN_TENSOR_GET_NAME(src), std::string(QNN_TENSOR_GET_NAME(src)).size())); - if (QNN_TENSOR_GET_NAME(dst) == nullptr) { - return MODEL_TENSOR_ERROR; - } - QNN_TENSOR_SET_ID(dst, QNN_TENSOR_GET_ID(src)); - QNN_TENSOR_SET_TYPE(dst, QNN_TENSOR_GET_TYPE(src)); - QNN_TENSOR_SET_DATA_FORMAT(dst, QNN_TENSOR_GET_DATA_FORMAT(src)); - QNN_TENSOR_SET_DATA_TYPE(dst, QNN_TENSOR_GET_DATA_TYPE(src)); - QNN_TENSOR_SET_MEM_TYPE(dst, QNN_TENSOR_GET_MEM_TYPE(src)); - - // Only metadata (i.e. non-static data) is copied from source to destination. The union still - // must be initialized so that the clientBuf/memHandle do not contain garbage data - if (QNN_TENSOR_GET_MEM_TYPE(src) == QNN_TENSORMEMTYPE_RAW) { - Qnn_ClientBuffer_t clientBuf = {nullptr, 0}; - QNN_TENSOR_SET_CLIENT_BUF(dst, clientBuf); - } else if (QNN_TENSOR_GET_MEM_TYPE(src) == QNN_TENSORMEMTYPE_MEMHANDLE) { - QNN_TENSOR_SET_MEM_HANDLE(dst, nullptr); - } else { - return MODEL_TENSOR_ERROR; - } - - Qnn_QuantizeParams_t srcQParam = QNN_TENSOR_GET_QUANT_PARAMS(src); - Qnn_QuantizationEncoding_t encoding = srcQParam.quantizationEncoding; - if (encoding == QNN_QUANTIZATION_ENCODING_AXIS_SCALE_OFFSET) { - // need to allocate and copy memory for scaleOffset as it is a pointer array - Qnn_QuantizeParams_t srcQParamCpy = srcQParam; - Qnn_AxisScaleOffset_t &axisScaleOffset = srcQParamCpy.axisScaleOffsetEncoding; - Qnn_ScaleOffset_t **scaleOffset = &axisScaleOffset.scaleOffset; - size_t scaleOffsetSize = axisScaleOffset.numScaleOffsets * sizeof(Qnn_ScaleOffset_t); - *scaleOffset = (Qnn_ScaleOffset_t *)malloc(scaleOffsetSize); - memscpy(*scaleOffset, - scaleOffsetSize, - srcQParam.axisScaleOffsetEncoding.scaleOffset, - scaleOffsetSize); - QNN_TENSOR_SET_QUANT_PARAMS(dst, srcQParamCpy); - } else if (encoding == QNN_QUANTIZATION_ENCODING_BW_AXIS_SCALE_OFFSET) { - // need to allocate and copy memory for scaleOffset as it is a pointer array - Qnn_QuantizeParams_t srcQParamCpy = srcQParam; - Qnn_BwAxisScaleOffset_t &bwAxisScaleOffset = srcQParamCpy.bwAxisScaleOffsetEncoding; - size_t scaleSize = bwAxisScaleOffset.numElements * sizeof(float); - float **scales = &bwAxisScaleOffset.scales; - int32_t **offsets = &bwAxisScaleOffset.offsets; - *scales = (float *)malloc(scaleSize); - memscpy(*scales, scaleSize, srcQParam.bwAxisScaleOffsetEncoding.scales, scaleSize); - - // Only copy offsets if present, nullptr implies all offsets are 0 - if (bwAxisScaleOffset.offsets != nullptr) { - size_t offsetSize = bwAxisScaleOffset.numElements * sizeof(int32_t); - *offsets = (int32_t *)malloc(offsetSize); - memscpy(*offsets, offsetSize, srcQParam.bwAxisScaleOffsetEncoding.offsets, offsetSize); +qnn_wrapper_api::ModelError_t qnn_wrapper_api::freeQnnTensors(Qnn_Tensor_t *&tensors, + uint32_t numTensors) { + // free all pointer allocations in struct + for (size_t i = 0; i < numTensors; i++) { + freeQnnTensor(tensors[i]); } - QNN_TENSOR_SET_QUANT_PARAMS(dst, srcQParamCpy); - } else { - QNN_TENSOR_SET_QUANT_PARAMS(dst, srcQParam); - } - - // need to allocate and copy memory for all the pointer members - uint32_t rank = QNN_TENSOR_GET_RANK(src); - QNN_TENSOR_SET_RANK(dst, rank); - size_t dimSize = rank * sizeof(uint32_t); - uint32_t *dimensions = (uint32_t *)malloc(dimSize); - if (dimensions == nullptr) { - PRINT_ERROR("deepCopyQnnTensors() Allocation error while copying tensor %s", - QNN_TENSOR_GET_NAME(src)); - return MODEL_TENSOR_ERROR; - } - memscpy(dimensions, dimSize, QNN_TENSOR_GET_DIMENSIONS(src), dimSize); - QNN_TENSOR_SET_DIMENSIONS(dst, dimensions); - - return err; -} - -ModelError_t freeQnnTensor(Qnn_Tensor_t &tensor) { - ModelError_t err; - VALIDATE_TENSOR_VERSION(tensor, err); - - // free all pointer allocations in struct - free((void *)QNN_TENSOR_GET_NAME(tensor)); - free(QNN_TENSOR_GET_DIMENSIONS(tensor)); - - return MODEL_NO_ERROR; -} - -ModelError_t freeQnnTensors(Qnn_Tensor_t *&tensors, uint32_t numTensors) { - // free all pointer allocations in struct - for (size_t i = 0; i < numTensors; i++) { - freeQnnTensor(tensors[i]); - } - free(tensors); - - return MODEL_NO_ERROR; + free(tensors); + return MODEL_NO_ERROR; } -std::string getModelErrorName(ModelError_t modelError) { - switch (modelError) { - case MODEL_NO_ERROR: - return "MODEL_NO_ERROR"; - case MODEL_TENSOR_ERROR: - return "MODEL_TENSOR_ERROR"; - case MODEL_PARAMS_ERROR: - return "MODEL_PARAMS_ERROR"; - case MODEL_NODES_ERROR: - return "MODEL_NODES_ERROR"; - case MODEL_GRAPH_ERROR: - return "MODEL_GRAPH_ERROR"; - case MODEL_CONTEXT_ERROR: - return "MODEL_CONTEXT_ERROR"; - case MODEL_GENERATION_ERROR: - return "MODEL_GENERATION_ERROR"; - case MODEL_SETUP_ERROR: - return "MODEL_SETUP_ERROR"; - case MODEL_UNKNOWN_ERROR: - return "MODEL_UNKNOWN_ERROR"; - case MODEL_INVALID_ARGUMENT_ERROR: - return "MODEL_INVALID_ARGUMENT_ERROR"; - case MODEL_FILE_ERROR: - return "MODEL_FILE_ERROR"; - default: - return "INVALID_ERROR_CODE"; - } +qnn_wrapper_api::ModelError_t qnn_wrapper_api::freeGraphsInfo(GraphInfoPtr_t **graphsInfo, + uint32_t numGraphs) { + if (graphsInfo == nullptr || *graphsInfo == nullptr) { + return MODEL_TENSOR_ERROR; + } + for (uint32_t i = 0; i < numGraphs; i++) { + free((*graphsInfo)[i]->graphName); + freeQnnTensors((*graphsInfo)[i]->inputTensors, (*graphsInfo)[i]->numInputTensors); + freeQnnTensors((*graphsInfo)[i]->outputTensors, (*graphsInfo)[i]->numOutputTensors); + } + free(**graphsInfo); + free(*graphsInfo); + *graphsInfo = nullptr; + return MODEL_NO_ERROR; } - -} // namespace qnn_wrapper_api diff --git a/src/backends/qnn/WrapperUtils/QnnWrapperUtils.hpp b/src/backends/qnn/WrapperUtils/QnnWrapperUtils.hpp index a51e3f0e8..d82126a28 100644 --- a/src/backends/qnn/WrapperUtils/QnnWrapperUtils.hpp +++ b/src/backends/qnn/WrapperUtils/QnnWrapperUtils.hpp @@ -1,7 +1,7 @@ //============================================================================== // -// Copyright (c) 2019-2022 Qualcomm Technologies, Inc. -// All Rights Reserved. +// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +// All rights reserved. // Confidential and Proprietary - Qualcomm Technologies, Inc. // //============================================================================== @@ -12,7 +12,6 @@ #include "QnnGraph.h" #include "QnnTensor.h" #include "QnnTypes.h" -#include namespace qnn_wrapper_api { @@ -21,159 +20,116 @@ namespace qnn_wrapper_api { // Enables FILE[LINE]: FMT for VALIDATE macro #ifdef QNN_ENABLE_DEBUG -#define PRINTF(fmt, ...) \ - do { \ - printf("%s[%d]: ", __FILE__, __LINE__); \ - printf((fmt), ##__VA_ARGS__); \ - } while (0) +#define PRINTF(fmt, ...) \ + do { \ + printf("%s[%d]: ", __FILE__, __LINE__); \ + printf((fmt), ##__VA_ARGS__); \ + } while (0) #else -#define PRINTF(fmt, ...) \ - do { \ - printf((fmt), ##__VA_ARGS__); \ - } while (0) +#define PRINTF(fmt, ...) \ + do { \ + printf((fmt), ##__VA_ARGS__); \ + } while (0) #endif #ifdef QNN_ENABLE_DEBUG -#define PRINT_DEBUG(fmt, ...) \ - do { \ - printf("[ DEBUG ] "); \ - PRINTF((fmt), ##__VA_ARGS__); \ - } while (0) +#define PRINT_DEBUG(fmt, ...) \ + do { \ + printf("[ DEBUG ] "); \ + PRINTF((fmt), ##__VA_ARGS__); \ + } while (0) #else #define PRINT_DEBUG(fmt, ...) #endif // Enables ERROR tag for errors -#define PRINT_ERROR(fmt, ...) \ - do { \ - printf("[ ERROR ] "); \ - PRINTF((fmt), ##__VA_ARGS__); \ - } while (0) +#define PRINT_ERROR(fmt, ...) \ + do { \ + printf("[ ERROR ] "); \ + PRINTF((fmt), ##__VA_ARGS__); \ + } while (0) // Enables WARNING tag for errors -#define PRINT_WARNING(fmt, ...) \ - do { \ - printf("[ WARNING ] "); \ - PRINTF((fmt), ##__VA_ARGS__); \ - } while (0) +#define PRINT_WARNING(fmt, ...) \ + do { \ + printf("[ WARNING ] "); \ + PRINTF((fmt), ##__VA_ARGS__); \ + } while (0) // Enables INFO tag for errors -#define PRINT_INFO(fmt, ...) \ - do { \ - printf("[ INFO ] "); \ - PRINTF((fmt), ##__VA_ARGS__); \ - } while (0) +#define PRINT_INFO(fmt, ...) \ + do { \ + printf("[ INFO ] "); \ + PRINTF((fmt), ##__VA_ARGS__); \ + } while (0) -#define STRINGFY(str) str +#define STRINGFY(str) str #define STRINGFYVALUE(str) STRINGFY(str) // Ensures ModelError_t returning functions return MODEL_NO_ERROR // retStatus should be set to MODEL_NO_ERROR before passing to macro -#define VALIDATE(value, retStatus) \ - do { \ - retStatus = value; \ - if (retStatus != qnn_wrapper_api::MODEL_NO_ERROR) { \ - PRINT_ERROR( \ - "%s expected MODEL_NO_ERROR, got %s\n", #value, getModelErrorName(retStatus).c_str()); \ - return retStatus; \ - } \ - } while (0) +#define VALIDATE(value, retStatus) \ + do { \ + retStatus = value; \ + if (retStatus != qnn_wrapper_api::MODEL_NO_ERROR) { \ + PRINT_ERROR( \ + "%s expected MODEL_NO_ERROR, got %d\n", #value, retStatus); \ + return retStatus; \ + } \ + } while (0) // macros for retrieving binary data -#define BINVARSTART(NAME) \ - ({ \ - extern const uint8_t _binary_obj_binary_##NAME##_raw_start[]; \ - (void *)_binary_obj_binary_##NAME##_raw_start; \ - }) -#define BINVAREND(NAME) \ - ({ \ - extern const uint8_t _binary_obj_binary_##NAME##_raw_end[]; \ - (void *)_binary_obj_binary_##NAME##_raw_end; \ - }) -#define BINLEN(NAME) \ - ({ \ - extern const uint8_t _binary_obj_binary_##NAME##_raw_start[]; \ - extern const uint8_t _binary_obj_binary_##NAME##_raw_end[]; \ - (uint32_t)((_binary_obj_binary_##NAME##_raw_end) - (_binary_obj_binary_##NAME##_raw_start)); \ - }) +#define BINVARSTART(NAME) \ + ({ \ + extern const uint8_t _binary_obj_binary_##NAME##_raw_start[]; \ + (void *)_binary_obj_binary_##NAME##_raw_start; \ + }) +#define BINVAREND(NAME) \ + ({ \ + extern const uint8_t _binary_obj_binary_##NAME##_raw_end[]; \ + (void *)_binary_obj_binary_##NAME##_raw_end; \ + }) +#define BINLEN(NAME) \ + ({ \ + extern const uint8_t _binary_obj_binary_##NAME##_raw_start[]; \ + extern const uint8_t _binary_obj_binary_##NAME##_raw_end[]; \ + (uint32_t)((_binary_obj_binary_##NAME##_raw_end) - (_binary_obj_binary_##NAME##_raw_start)); \ + }) typedef enum ModelError { - MODEL_NO_ERROR = 0, - MODEL_TENSOR_ERROR = 1, - MODEL_PARAMS_ERROR = 2, - MODEL_NODES_ERROR = 3, - MODEL_GRAPH_ERROR = 4, - MODEL_CONTEXT_ERROR = 5, - MODEL_GENERATION_ERROR = 6, - MODEL_SETUP_ERROR = 7, - MODEL_INVALID_ARGUMENT_ERROR = 8, - MODEL_FILE_ERROR = 9, - MODEL_MEMORY_ALLOCATE_ERROR = 10, - // Value selected to ensure 32 bits. - MODEL_UNKNOWN_ERROR = 0x7FFFFFFF + MODEL_NO_ERROR = 0, + MODEL_TENSOR_ERROR = 1, + MODEL_PARAMS_ERROR = 2, + MODEL_NODES_ERROR = 3, + MODEL_GRAPH_ERROR = 4, + MODEL_CONTEXT_ERROR = 5, + MODEL_GENERATION_ERROR = 6, + MODEL_SETUP_ERROR = 7, + MODEL_INVALID_ARGUMENT_ERROR = 8, + MODEL_FILE_ERROR = 9, + MODEL_MEMORY_ALLOCATE_ERROR = 10, + // Value selected to ensure 32 bits. + MODEL_UNKNOWN_ERROR = 0x7FFFFFFF } ModelError_t; -/** - * @brief Returns the error message associated with a given error code - * - * @param[in] modelError ModelError_t error code - * - * @return string message - */ -std::string getModelErrorName(ModelError_t modelError); - typedef struct GraphInfo { - Qnn_GraphHandle_t graph; - char *graphName; - Qnn_Tensor_t *inputTensors; - uint32_t numInputTensors; - Qnn_Tensor_t *outputTensors; - uint32_t numOutputTensors; + Qnn_GraphHandle_t graph; + char *graphName; + Qnn_Tensor_t *inputTensors; + uint32_t numInputTensors; + Qnn_Tensor_t *outputTensors; + uint32_t numOutputTensors; } GraphInfo_t; typedef GraphInfo_t *GraphInfoPtr_t; typedef struct GraphConfigInfo { - char *graphName; - const QnnGraph_Config_t **graphConfigs; + char *graphName; + const QnnGraph_Config_t **graphConfigs; } GraphConfigInfo_t; -/** - * @brief Helper function to get Qnn GraphConfig structure from provided GraphConfigInfo using - * graphName. - * - * @param[in] graphName the Qnn graphName to use for lookup - * - * @param[in] graphsConfigInfo array of GraphConfig_t objects - * - * @param[in] numGraphsConfigInfo the number of array elements in graphConfigInfo - * - * @param[out] graphConfigs the result of query of graphName from graphsConfigInfo if successful. - * - * @return Error code - * - */ -ModelError_t getQnnGraphConfigFromInfo(const char *graphName, - const GraphConfigInfo_t **graphsConfigInfo, - const uint32_t numGraphsConfigInfo, - const QnnGraph_Config_t **&graphConfigs); - -/** - * @brief Deep Copies QnnTensor_t structs to a pointer array destination location. - * Note: The copy will be stored on the heap and as such requires caller to make - * appropriate free call(s) using function below. - * Note 2: deepCopy is only done for metadata - * - * @param[in] source tensor object to copy from - * - * @param[in] destination tensor object to copy to - * - * @return Error code - */ -ModelError_t deepCopyQnnTensors(Qnn_Tensor_t &source, Qnn_Tensor_t &destination); - /** * @brief Frees all memory allocated tensor attributes. * @@ -195,6 +151,16 @@ ModelError_t freeQnnTensor(Qnn_Tensor_t &tensor); */ ModelError_t freeQnnTensors(Qnn_Tensor_t *&tensors, uint32_t numTensors); -size_t memscpy(void *dst, size_t dstSize, const void *src, size_t copySize); +/** + * @brief A helper function to free memory malloced for communicating the Graph for a model(s) + * + * @param[in] graphsInfo Pointer pointing to location of graph objects + * + * @param[in] numGraphs The number of graph objects the above pointer is pointing to + * + * @return Error code + * + */ +ModelError_t freeGraphsInfo(GraphInfoPtr_t **graphsInfo, uint32_t numGraphs); -} // namespace qnn_wrapper_api +} // namespace qnn_wrapper_api diff --git a/src/backends/qnn/op/QNNCommonOp.cpp b/src/backends/qnn/op/QNNCommonOp.cpp index e448429a9..1196f4601 100644 --- a/src/backends/qnn/op/QNNCommonOp.cpp +++ b/src/backends/qnn/op/QNNCommonOp.cpp @@ -29,26 +29,31 @@ ErrorCode QNNCommonOp::graphAddNode(string name, string nodeType, vector(output->sequence()); } - // TODO tensor type = MLLM_TYPE_I8 - auto data_type = QNN_DATATYPE_FLOAT_32; - if (output->dtype() == MLLM_TYPE_I8) { - data_type = QNN_DATATYPE_SFIXED_POINT_8; - } - - if (output->dtype() == MLLM_TYPE_F16) { - data_type = QNN_DATATYPE_FLOAT_16; - } - - float quantScale = 0.0f; auto quantDefine = QNN_DEFINITION_UNDEFINED; auto quantType = QNN_QUANTIZATION_ENCODING_UNDEFINED; - - if (scale != nullptr) { - quantScale = scale->hostPtr()[0] / 127.0; - quantScale = roundf(quantScale * 100000) / 100000; + auto data_type = QNN_DATATYPE_FLOAT_32; + switch (output->dtype()) { + case MLLM_TYPE_I8: + data_type = QNN_DATATYPE_SFIXED_POINT_8; + quantScale = scale->hostPtr()[0] / (pow(2, 7) - 1); + // quantScale = roundf(quantScale * 100000) / 100000; quantDefine = QNN_DEFINITION_DEFINED; quantType = QNN_QUANTIZATION_ENCODING_SCALE_OFFSET; + break; + case MLLM_TYPE_I16: + data_type = QNN_DATATYPE_SFIXED_POINT_16; + quantScale = scale->hostPtr()[0] / (pow(2, 15) - 1); + // quantScale = roundf(quantScale * 100000) / 100000; + quantDefine = QNN_DEFINITION_DEFINED; + quantType = QNN_QUANTIZATION_ENCODING_SCALE_OFFSET; + break; + case MLLM_TYPE_F16: + data_type = QNN_DATATYPE_FLOAT_16; + break; + default: + data_type = QNN_DATATYPE_FLOAT_32; + break; } inputTensorNames_.push_back(new string(output->name())); @@ -66,7 +71,7 @@ ErrorCode QNNCommonOp::graphAddNode(string name, string nodeType, vectorgraphAddNode(name, nodeType, inputTensorNames, outputTensors, params, packageName)) { @@ -87,7 +92,7 @@ ErrorCode QNNCommonOp::graphAddNode(string name, string nodeType, vector Qnn_TensorType_t QNNCommonOp::getOutputTensorType(shared_ptr tensor) const { if (tensor->ttype() == GRAPH_OUTPUT) { // in Module API, the outputs of a graph is not allocated before setUp, alloc here - if(tensor->allocted() == 0) { + if (tensor->allocted() == 0) { tensor->alloc(); } qnnBackend_->pushOutputBuffers(tensor->hostPtr()); diff --git a/src/backends/qnn/op/QNNDequantize.cpp b/src/backends/qnn/op/QNNDequantize.cpp index 569deb73d..699a51666 100644 --- a/src/backends/qnn/op/QNNDequantize.cpp +++ b/src/backends/qnn/op/QNNDequantize.cpp @@ -6,11 +6,13 @@ #include namespace mllm { -QNNDequantize::QNNDequantize(Backend *bn, string opName, bool isNSHD, bool isFP32) : +QNNDequantize::QNNDequantize(Backend *bn, string opName, bool isNSHD, bool isFP32, DataType type) : QNNCommonOp(bn, opName) { isNSHD_ = isNSHD; isFP32_ = isFP32; + activation_dtype_ = type; scale_.setBackend(bn); + bias_.setBackend(bn); } ErrorCode QNNDequantize::reshape(vector> inputs, vector> outputs) { @@ -20,7 +22,6 @@ ErrorCode QNNDequantize::reshape(vector> inputs, vector> inputs, vector> outputs) { - auto outName = outputs[0]->name(); uint32_t dimensionsOutput[4]; @@ -37,94 +38,226 @@ ErrorCode QNNDequantize::setUp(vector> inputs, vector()[0] / 127.0; - dequantScale = roundf(dequantScale * 100000) / 100000; - - if (name().find("q_proj") != -1) { - dequantScale = dequantScale / std::sqrt(outputs[0]->dimension()); + switch (activation_dtype_) { + case MLLM_TYPE_I8: + dequantScale = scale_.hostPtr()[0] / (pow(2, 7) - 1); + break; + case MLLM_TYPE_I16: + dequantScale = scale_.hostPtr()[0] / (pow(2, 15) - 1); + break; + default: + return NOT_SUPPORT; } + // dequantScale = roundf(dequantScale * 100000) / 100000; + + // if (name().find("q_proj") != -1) { + // dequantScale = dequantScale / std::sqrt(outputs[0]->dimension()); + // } + + if (name().find("q_proj") != -1 || name().find("k_proj") != -1 || name().find("v_proj") != -1 ) { + if (isFP32_) { + uint32_t paramsDeQuantizeDimension[1] = {1}; + auto paramsDeQuantizeName = name() + "dequantize_params"; + + vector paramsDeQuantize = { + {.paramType = QNN_PARAMTYPE_TENSOR, + .name = "scale", + .tensorParam = + (Qnn_Tensor_t){.version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = paramsDeQuantizeName.c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_32, + .quantizeParams = {QNN_DEFINITION_UNDEFINED, + QNN_QUANTIZATION_ENCODING_UNDEFINED, + {.scaleOffsetEncoding = {.scale = 0.0000000000000000f, .offset = 0}}}, + .rank = 1, + .dimensions = paramsDeQuantizeDimension, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = (uint8_t *)&dequantScale, + .dataSize = sizeof(float)}}}}}; + + uint32_t dimensionsBias[4] = {1, 1, 1, static_cast(bias_.dimension())}; + qnnBackend_->modelAddTensor(bias_.name(), (Qnn_Tensor_t){ + .version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = bias_.name().c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_32, + .rank = 4, + .dimensions = dimensionsBias, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = bias_.hostPtr(), + .dataSize = (uint32_t)bias_.cntSize()}}}); + + vector outputTensor = {{.version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = outName.c_str(), + .type = getOutputTensorType(outputs[0]), + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_32, + .quantizeParams = {QNN_DEFINITION_DEFINED, + QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, + {.scaleOffsetEncoding = {.scale = dequantScale, .offset = 0}}}, + .rank = 4, + .dimensions = dimensionsOutput, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = nullptr, + .dataSize = 0}}}}; + return graphAddNode(name(), "LLaMADequantizeAdd", {inputs[0]->name(), bias_.name()}, outputTensor, paramsDeQuantize, "LLaMAPackage"); + } else { + outputs[0]->setDtype(MLLM_TYPE_F16); + uint32_t paramsDeQuantizeDimension[1] = {1}; + auto paramsDeQuantizeName = name() + "dequantize_params"; - if (isFP32_) { - uint32_t paramsDeQuantizeDimension[1] = {1}; - auto paramsDeQuantizeName = name() + "dequantize_params"; - vector paramsDeQuantize = { - {.paramType = QNN_PARAMTYPE_TENSOR, - .name = "scale", - .tensorParam = - (Qnn_Tensor_t){.version = QNN_TENSOR_VERSION_1, - .v1 = { - .id = 0, - .name = paramsDeQuantizeName.c_str(), - .type = QNN_TENSOR_TYPE_STATIC, - .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, - .dataType = QNN_DATATYPE_FLOAT_32, - .quantizeParams = {QNN_DEFINITION_UNDEFINED, - QNN_QUANTIZATION_ENCODING_UNDEFINED, - {.scaleOffsetEncoding = {.scale = 0.0000000000000000f, .offset = 0}}}, - .rank = 1, - .dimensions = paramsDeQuantizeDimension, - .memType = QNN_TENSORMEMTYPE_RAW, - .clientBuf = {.data = (uint8_t *)&dequantScale, - .dataSize = sizeof(float)}}}}}; - - vector outputTensor = {{.version = QNN_TENSOR_VERSION_1, - .v1 = { - .id = 0, - .name = outName.c_str(), - .type = getOutputTensorType(outputs[0]), - .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, - .dataType = QNN_DATATYPE_FLOAT_32, - .quantizeParams = {QNN_DEFINITION_DEFINED, - QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, - {.scaleOffsetEncoding = {.scale = dequantScale, .offset = 0}}}, - .rank = 4, - .dimensions = dimensionsOutput, - .memType = QNN_TENSORMEMTYPE_RAW, - .clientBuf = {.data = nullptr, - .dataSize = 0}}}}; - return graphAddNode(name(), "LLaMADequantize", {inputs[0]->name()}, outputTensor, paramsDeQuantize, "LLaMAPackage"); + vector paramsDeQuantize = { + {.paramType = QNN_PARAMTYPE_TENSOR, + .name = "scale", + .tensorParam = + (Qnn_Tensor_t){.version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = paramsDeQuantizeName.c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_32, + .quantizeParams = {QNN_DEFINITION_UNDEFINED, + QNN_QUANTIZATION_ENCODING_UNDEFINED, + {.scaleOffsetEncoding = {.scale = 0.0000000000000000f, + .offset = 0}}}, + .rank = 1, + .dimensions = paramsDeQuantizeDimension, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = (uint8_t *)&dequantScale, + .dataSize = sizeof(float)}}}}}; + + + uint32_t dimensionsBias[4] = {1, 1, 1, static_cast(bias_.dimension())}; + qnnBackend_->modelAddTensor(bias_.name(), (Qnn_Tensor_t){ + .version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = bias_.name().c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_32, + .rank = 4, + .dimensions = dimensionsBias, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = bias_.hostPtr(), + .dataSize = (uint32_t)bias_.cntSize()}}}); + + vector outputTensor = {{QNN_TENSOR_VERSION_1, + {.v1 = { + .id = 0, + .name = outName.c_str(), + .type = getOutputTensorType(outputs[0]), + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_16, + .quantizeParams = {QNN_DEFINITION_DEFINED, + QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, + {.scaleOffsetEncoding = {.scale = dequantScale, .offset = 0}}}, + .rank = 4, + .dimensions = dimensionsOutput, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = nullptr, + .dataSize = 0}}}}}; + return graphAddNode(name(), "LLaMADequantizeAdd", {inputs[0]->name(), bias_.name()}, outputTensor, paramsDeQuantize, "LLaMAPackage"); + } } else { - outputs[0]->setDtype(MLLM_TYPE_F16); - uint32_t paramsDeQuantizeDimension[1] = {1}; - auto paramsDeQuantizeName = name() + "dequantize_params"; - vector paramsDeQuantize = { - {.paramType = QNN_PARAMTYPE_TENSOR, - .name = "scale", - .tensorParam = - (Qnn_Tensor_t){.version = QNN_TENSOR_VERSION_1, - .v1 = { - .id = 0, - .name = paramsDeQuantizeName.c_str(), - .type = QNN_TENSOR_TYPE_STATIC, - .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, - .dataType = QNN_DATATYPE_FLOAT_32, - .quantizeParams = {QNN_DEFINITION_UNDEFINED, - QNN_QUANTIZATION_ENCODING_UNDEFINED, - {.scaleOffsetEncoding = {.scale = 0.0000000000000000f, - .offset = 0}}}, - .rank = 1, - .dimensions = paramsDeQuantizeDimension, - .memType = QNN_TENSORMEMTYPE_RAW, - .clientBuf = {.data = (uint8_t *)&dequantScale, - .dataSize = sizeof(float)}}}}}; - - vector outputTensor = {{QNN_TENSOR_VERSION_1, - {.v1 = { - .id = 0, - .name = outName.c_str(), - .type = getOutputTensorType(outputs[0]), - .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, - .dataType = QNN_DATATYPE_FLOAT_16, - .quantizeParams = {QNN_DEFINITION_DEFINED, - QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, - {.scaleOffsetEncoding = {.scale = dequantScale, .offset = 0}}}, - .rank = 4, - .dimensions = dimensionsOutput, - .memType = QNN_TENSORMEMTYPE_RAW, - .clientBuf = {.data = nullptr, - .dataSize = 0}}}}}; - return graphAddNode(name(), "LLaMADequantize", {inputs[0]->name()}, outputTensor, paramsDeQuantize, "LLaMAPackage"); + + if (isFP32_) { + uint32_t paramsDeQuantizeDimension[1] = {1}; + auto paramsDeQuantizeName = name() + "dequantize_params"; + + vector paramsDeQuantize = { + {.paramType = QNN_PARAMTYPE_TENSOR, + .name = "scale", + .tensorParam = + (Qnn_Tensor_t){.version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = paramsDeQuantizeName.c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_32, + .quantizeParams = {QNN_DEFINITION_UNDEFINED, + QNN_QUANTIZATION_ENCODING_UNDEFINED, + {.scaleOffsetEncoding = {.scale = 0.0000000000000000f, .offset = 0}}}, + .rank = 1, + .dimensions = paramsDeQuantizeDimension, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = (uint8_t *)&dequantScale, + .dataSize = sizeof(float)}}}}}; + + vector outputTensor = {{.version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = outName.c_str(), + .type = getOutputTensorType(outputs[0]), + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_32, + .quantizeParams = {QNN_DEFINITION_DEFINED, + QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, + {.scaleOffsetEncoding = {.scale = dequantScale, .offset = 0}}}, + .rank = 4, + .dimensions = dimensionsOutput, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = nullptr, + .dataSize = 0}}}}; + return graphAddNode(name(), "LLaMADequantize", {inputs[0]->name()}, outputTensor, paramsDeQuantize, "LLaMAPackage"); + } else { + outputs[0]->setDtype(MLLM_TYPE_F16); + uint32_t paramsDeQuantizeDimension[1] = {1}; + auto paramsDeQuantizeName = name() + "dequantize_params"; + + vector paramsDeQuantize = { + {.paramType = QNN_PARAMTYPE_TENSOR, + .name = "scale", + .tensorParam = + (Qnn_Tensor_t){.version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = paramsDeQuantizeName.c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_32, + .quantizeParams = {QNN_DEFINITION_UNDEFINED, + QNN_QUANTIZATION_ENCODING_UNDEFINED, + {.scaleOffsetEncoding = {.scale = 0.0000000000000000f, + .offset = 0}}}, + .rank = 1, + .dimensions = paramsDeQuantizeDimension, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = (uint8_t *)&dequantScale, + .dataSize = sizeof(float)}}}}}; + + vector outputTensor = {{QNN_TENSOR_VERSION_1, + {.v1 = { + .id = 0, + .name = outName.c_str(), + .type = getOutputTensorType(outputs[0]), + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_16, + .quantizeParams = {QNN_DEFINITION_DEFINED, + QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, + {.scaleOffsetEncoding = {.scale = dequantScale, .offset = 0}}}, + .rank = 4, + .dimensions = dimensionsOutput, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = nullptr, + .dataSize = 0}}}}}; + return graphAddNode(name(), "LLaMADequantize", {inputs[0]->name()}, outputTensor, paramsDeQuantize, "LLaMAPackage"); + } + } + + } ErrorCode QNNDequantize::load(AbstructLoader &loader) { @@ -150,6 +283,38 @@ ErrorCode QNNDequantize::load(AbstructLoader &loader) { scale_.alloc(); loader.load(&scale_); + + if (name().find("q_proj") != -1 || name().find("k_proj") != -1 || name().find("v_proj") != -1 ) { + + // std::cout << name() << std::endl; + + string biasName = name(); + wordToRemove = "dequantize"; + string biasTypeName = "bias"; + + int pos = biasName.find(wordToRemove); + if (pos != -1) { + biasName.erase(pos, wordToRemove.length()); + } + + // std::cout << biasName + biasTypeName << std::endl; + + int hidden_size = 1536; + if (name().find("k_proj") != -1 || name().find("v_proj") != -1 ) + hidden_size = 256; + + bias_.setName(biasName + biasTypeName); + bias_.reshape(1, 1, 1, hidden_size); + bias_.setDtype(MLLM_TYPE_F32); + bias_.alloc(); + loader.load(&bias_); + + // bias_.printData(); + + } + + + return Op::load(loader); } } // namespace mllm diff --git a/src/backends/qnn/op/QNNDequantize.hpp b/src/backends/qnn/op/QNNDequantize.hpp index b4b78fc22..229d11db4 100644 --- a/src/backends/qnn/op/QNNDequantize.hpp +++ b/src/backends/qnn/op/QNNDequantize.hpp @@ -3,10 +3,11 @@ #define MLLM_QNNDEQUANTIZE_H #include "QNNCommonOp.hpp" +#include "Types.hpp" namespace mllm { class QNNDequantize : public QNNCommonOp { public: - QNNDequantize(Backend *bn, string opName, bool isNSHD, bool isFP32); + QNNDequantize(Backend *bn, string opName, bool isNSHD, bool isFP32, DataType type = MLLM_TYPE_I8); virtual ~QNNDequantize() = default; virtual ErrorCode reshape(vector> inputs, vector> outputs) override; virtual ErrorCode setUp(vector> inputs, vector> outputs) override; @@ -15,12 +16,13 @@ class QNNDequantize : public QNNCommonOp { bool isNSHD_; bool isFP32_; Tensor scale_; + Tensor bias_; }; class QNNDequantizeCreator : public QNNBackend::Creator { public: virtual Op *create(OpParam op_param, Backend *bn, string name) const { - return new QNNDequantize(bn, name, (bool)op_param["isNSHD"], (bool)op_param["isFP32"]); + return new QNNDequantize(bn, name, (bool)op_param["isNSHD"], (bool)op_param["isFP32"], (DataType)op_param["inType"]); } }; diff --git a/src/backends/qnn/op/QNNIRoPE.cpp b/src/backends/qnn/op/QNNIRoPE.cpp index d78c8752a..a728aba73 100644 --- a/src/backends/qnn/op/QNNIRoPE.cpp +++ b/src/backends/qnn/op/QNNIRoPE.cpp @@ -92,7 +92,7 @@ ErrorCode QNNIRoPE::setUp(vector> inputs, vector()[0] / 127.0; - dequantScale = roundf(dequantScale * 100000) / 100000; + // dequantScale = roundf(dequantScale * 100000) / 100000; if (name().find("q_proj") != -1) { dequantScale = dequantScale / std::sqrt(outputs[0]->dimension()); diff --git a/src/backends/qnn/op/QNNLinearINT8.cpp b/src/backends/qnn/op/QNNLinearINT8.cpp index a1510a943..33b313f2a 100755 --- a/src/backends/qnn/op/QNNLinearINT8.cpp +++ b/src/backends/qnn/op/QNNLinearINT8.cpp @@ -1,5 +1,6 @@ #include "QNNLinearINT8.hpp" +#include "Backend.hpp" #include "QnnTypes.h" #include "Types.hpp" #include "QNNCommonOp.hpp" @@ -9,13 +10,12 @@ namespace mllm { QNNLinearINT8::QNNLinearINT8(Backend *bn, string opName, int in_features, int out_features, bool bias) : QNNCommonOp(bn, opName), in_features_(in_features), out_features_(out_features), support_bias_(bias) { - weight_.setBackend(bn); - bias_.setBackend(bn); + weight_.setBackend(Backend::global_backends[MLLM_CPU]); + bias_.setBackend(Backend::global_backends[MLLM_CPU]); - weightScale_.setBackend(bn); - biasScale_.setBackend(bn); - outputScale_.setBackend(bn); - inputScale_.setBackend(bn); + weightScale_.setBackend(Backend::global_backends[MLLM_CPU]); + biasScale_.setBackend(Backend::global_backends[MLLM_CPU]); + outputScale_.setBackend(Backend::global_backends[MLLM_CPU]); } ErrorCode QNNLinearINT8::reshape(vector> inputs, vector> outputs) { @@ -38,6 +38,17 @@ ErrorCode QNNLinearINT8::reshape(vector> inputs, vector> inputs, vector> outputs) { + switch (inputs[0]->dtype()) { + case MLLM_TYPE_I8: + return setUpW8A8(inputs, outputs); + case MLLM_TYPE_I16: + return setUpW8A16(inputs, outputs); + default: + return NOT_SUPPORT; + } +} + +ErrorCode QNNLinearINT8::setUpW8A8(vector> &inputs, vector> &outputs) { outputs[0]->setDtype(MLLM_TYPE_I8); // add matmul param to qnn vector paramsMatmul = { @@ -142,8 +153,8 @@ ErrorCode QNNLinearINT8::setUp(vector> inputs, vector()[0] / 127.0; - outputScale = roundf(outputScale * 100000) / 100000; + outputScale = outputScale_.hostPtr()[0] / (pow(2, 7) - 1); + // outputScale = roundf(outputScale * 100000) / 100000; vector matmulOut = {{QNN_TENSOR_VERSION_1, {.v1 = { @@ -170,6 +181,13 @@ ErrorCode QNNLinearINT8::setUp(vector> inputs, vector()[0]; + auto biasBuffer = (int8_t *)malloc(bias_.count() * sizeof(int8_t)); +#pragma omp parallel for + for (int i = 0; i < out_features_; i++) { + int32_t val = bias_.dataAt(0, 0, 0, i) + 128; + biasBuffer[i] = val; + } + qnnBackend_->modelAddTensor(bias_.name(), (Qnn_Tensor_t){ .version = QNN_TENSOR_VERSION_1, .v1 = { @@ -184,14 +202,14 @@ ErrorCode QNNLinearINT8::setUp(vector> inputs, vector(), - .dataSize = (uint32_t)bias_.cntSize()}}}); + .clientBuf = {.data = biasBuffer, + .dataSize = (uint32_t)(bias_.count() * sizeof(int8_t)) }}}); // free bias host memory bias_.free(); float outputScale = 0; - outputScale = outputScale_.hostPtr()[0] / 127.0; - outputScale = roundf(outputScale * 100000) / 100000; + outputScale = outputScale_.hostPtr()[0] / (pow(2, 7) - 1); + // outputScale = roundf(outputScale * 100000) / 100000; // final output vector biasOutput = {{QNN_TENSOR_VERSION_1, @@ -209,7 +227,191 @@ ErrorCode QNNLinearINT8::setUp(vector> inputs, vectorname(), weight_.name(), bias_.name()}, biasOutput, params_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D); + return graphAddNode(name() + ".linear_w8a8", "Conv2d", {inputs[0]->name(), weight_.name(), bias_.name()}, biasOutput, params_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D); +} + +ErrorCode QNNLinearINT8::setUpW8A16(vector> &inputs, vector> &outputs) { + outputs[0]->setDtype(MLLM_TYPE_I16); + // add matmul param to qnn + vector paramsMatmul = { + {.paramType = QNN_PARAMTYPE_SCALAR, + .name = "transpose_in0", + .scalarParam = (Qnn_Scalar_t){QNN_DATATYPE_BOOL_8, {.bool8Value = 0}}}, + {.paramType = QNN_PARAMTYPE_SCALAR, + .name = "transpose_in1", + .scalarParam = (Qnn_Scalar_t){QNN_DATATYPE_BOOL_8, {.bool8Value = 1}}}}; + + uint32_t dimensions_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_dilation[] = {2}; + uint32_t InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_dilation[] = {1, 1}; + uint32_t dimensions_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_pad_amount[] = {2, 2}; + uint32_t InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_pad_amount[] = {0, 0, 0, 0}; + uint32_t dimensions_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_stride[] = {2}; + uint32_t InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_stride[] = {1, 1}; + + string strideName = name() + ".stride"; + string padName = name() + ".pad"; + vector params_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D = { + {.paramType = QNN_PARAMTYPE_TENSOR, + .name = "stride", + .tensorParam = + (Qnn_Tensor_t){ + .version = QNN_TENSOR_VERSION_1, + .v1 = {.id = 0, + .name = strideName.c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_UINT_32, + .quantizeParams = {QNN_DEFINITION_UNDEFINED, + QNN_QUANTIZATION_ENCODING_UNDEFINED, + {.scaleOffsetEncoding = {.scale = 0.0000000000000000f, + .offset = 0}}}, + .rank = 1, + .dimensions = dimensions_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_stride, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = + {.data = (uint8_t *)InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_stride, + .dataSize = 8}}}}, + {.paramType = QNN_PARAMTYPE_TENSOR, + .name = "pad_amount", + .tensorParam = + (Qnn_Tensor_t){ + .version = QNN_TENSOR_VERSION_1, + .v1 = {.id = 0, + .name = padName.c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_UINT_32, + .quantizeParams = {QNN_DEFINITION_UNDEFINED, + QNN_QUANTIZATION_ENCODING_UNDEFINED, + {.scaleOffsetEncoding = {.scale = 0.0000000000000000f, + .offset = 0}}}, + .rank = 2, + .dimensions = + dimensions_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_pad_amount, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = + {.data = (uint8_t *) + InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D_pad_amount, + .dataSize = 16}}}}, + + }; + + // add weight tensor to qnn + uint32_t dimensionsWeight[4] = {1, 1, static_cast(weight_.sequence()), static_cast(weight_.dimension())}; + + auto qnnQuantDefined = QNN_DEFINITION_UNDEFINED; + float weightScale = 0; + + qnnQuantDefined = QNN_DEFINITION_DEFINED; + weightScale = weightScale_.hostPtr()[0]; + + qnnBackend_->modelAddTensor(weight_.name(), (Qnn_Tensor_t){ + .version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = weight_.name().c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_SFIXED_POINT_8, + .quantizeParams = {qnnQuantDefined, + QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, + {.scaleOffsetEncoding = {.scale = weightScale, .offset = 0}}}, + .rank = 4, + .dimensions = dimensionsWeight, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = weight_.hostPtr(), + .dataSize = (uint32_t)weight_.cntSize()}}}); + // free weight host memory + weight_.free(); + + // dimensions of matmul output and bias + uint32_t dimensionsOutput[4] = {static_cast(outputs[0]->batch()), + static_cast(outputs[0]->sequence()), + static_cast(outputs[0]->head()), + static_cast(outputs[0]->dimension())}; + + auto outName = outputs[0]->name(); + + // if don't support bias, just dequantize and write to tensor with name of outputs[0] + if (!support_bias_) { + float outputScale = 0; + outputScale = outputScale_.hostPtr()[0] / (pow(2, 15) - 1); + // outputScale = roundf(outputScale * 100000) / 100000; + + vector matmulOut = {{QNN_TENSOR_VERSION_1, + {.v1 = { + .id = 0, + .name = outName.c_str(), + .type = getOutputTensorType(outputs[0]), + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_SFIXED_POINT_16, + .quantizeParams = {QNN_DEFINITION_DEFINED, + QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, + {.scaleOffsetEncoding = {.scale = outputScale, .offset = 0}}}, + .rank = 4, + .dimensions = dimensionsOutput, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = nullptr, + .dataSize = 0}}}}}; + return graphAddNode(name() + ".linearint8", "Conv2d", {inputs[0]->name(), weight_.name()}, matmulOut, params_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D); + } + + // add bias tensor to qnn + uint32_t dimensionsBias[1] = {(uint32_t)out_features_}; + float biasScale = 0; + + qnnQuantDefined = QNN_DEFINITION_DEFINED; + biasScale = biasScale_.hostPtr()[0]; + // create a int32 buffer, convert the bias to int32 + auto biasBuffer = (int32_t *)malloc(bias_.count() * sizeof(int32_t)); +#pragma omp parallel for + for (int i = 0; i < out_features_; i++) { + // int32_t val = bias_.dataAt(0, 0, 0, i) - 128; + int32_t val = bias_.dataAt(0, 0, 0, i); + biasBuffer[i] = val; + } + + qnnBackend_->modelAddTensor(bias_.name(), (Qnn_Tensor_t){ + .version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = bias_.name().c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_SFIXED_POINT_32, + .quantizeParams = {qnnQuantDefined, + QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, + {.scaleOffsetEncoding = {.scale = biasScale, .offset = 0}}}, + .rank = 1, + .dimensions = dimensionsBias, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = biasBuffer, + .dataSize = (uint32_t)(bias_.count() * sizeof(int32_t))}}}); + // free bias host memory + bias_.free(); + delete biasBuffer; + + float outputScale = 0; + outputScale = outputScale_.hostPtr()[0] / (pow(2, 15) - 1); + // outputScale = roundf(outputScale * 100000) / 100000; + + // final output + vector biasOutput = {{QNN_TENSOR_VERSION_1, + {.v1 = { + .id = 0, + .name = outName.c_str(), + .type = getOutputTensorType(outputs[0]), + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_SFIXED_POINT_16, + .quantizeParams = {QNN_DEFINITION_DEFINED, + QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, + {.scaleOffsetEncoding = {.scale = outputScale, .offset = 0}}}, + .rank = 4, + .dimensions = dimensionsOutput, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = nullptr, + .dataSize = 0}}}}}; + return graphAddNode(name() + ".linear_w8a16", "Conv2d", {inputs[0]->name(), weight_.name(), bias_.name()}, biasOutput, params_InceptionV3_InceptionV3_Conv2d_1a_3x3_Conv2D); } ErrorCode QNNLinearINT8::load(AbstructLoader &loader) { @@ -221,16 +423,16 @@ ErrorCode QNNLinearINT8::load(AbstructLoader &loader) { bias_.setName(name() + ".bias"); bias_.reshape(1, 1, 1, out_features_); - bias_.setDtype(MLLM_TYPE_I8); + bias_.setDtype(MLLM_TYPE_I32); bias_.alloc(); if (support_bias_) { loader.load(&bias_); - // sign to unsign - for (int i = 0; i < out_features_; i++) { - int32_t val = bias_.dataAt(0, 0, 0, i); - val += 128; - bias_.setDataAt(0, 0, 0, i, (uint8_t)val); - } + // // sign to unsign + // for (int i = 0; i < out_features_; i++) { + // int32_t val = bias_.dataAt(0, 0, 0, i); + // val += 128; + // bias_.setDataAt(0, 0, 0, i, (uint8_t)val); + // } } else { memset(bias_.hostPtr(), 0, bias_.cntSize()); } @@ -253,12 +455,6 @@ ErrorCode QNNLinearINT8::load(AbstructLoader &loader) { outputScale_.alloc(); loader.load(&outputScale_); - inputScale_.setName(name() + ".input_scale"); - inputScale_.reshape(1, 1, 1, 1); - inputScale_.setDtype(MLLM_TYPE_F32); - inputScale_.alloc(); - loader.load(&inputScale_); - return Op::load(loader); } diff --git a/src/backends/qnn/op/QNNLinearINT8.hpp b/src/backends/qnn/op/QNNLinearINT8.hpp index ea9395eb3..e53fd3ccb 100644 --- a/src/backends/qnn/op/QNNLinearINT8.hpp +++ b/src/backends/qnn/op/QNNLinearINT8.hpp @@ -19,12 +19,15 @@ class QNNLinearINT8 : public QNNCommonOp { bool support_bias_; Tensor weight_; Tensor bias_; -// #ifdef SMOOTHQUANT + Tensor weightScale_; Tensor biasScale_; -// #endif + Tensor outputScale_; Tensor inputScale_; + + ErrorCode setUpW8A8(vector>& inputs, vector>& outputs); + ErrorCode setUpW8A16(vector>& inputs, vector>& outputs); }; class QNNLinearINT8Creator : public QNNBackend::Creator { diff --git a/src/backends/qnn/op/QNNQuantize.cpp b/src/backends/qnn/op/QNNQuantize.cpp index cbf4937e8..00f381b95 100644 --- a/src/backends/qnn/op/QNNQuantize.cpp +++ b/src/backends/qnn/op/QNNQuantize.cpp @@ -7,9 +7,11 @@ #include namespace mllm { -QNNQuantize::QNNQuantize(Backend *bn, string opName, bool isNSHD) : +QNNQuantize::QNNQuantize(Backend *bn, string opName, DataType type, bool isNSHD) : QNNCommonOp(bn, opName) { isNSHD_ = isNSHD; + assert(type == MLLM_TYPE_I8 || type == MLLM_TYPE_I16); + activation_dtype_ = type; scale_.setBackend(bn); } @@ -20,6 +22,17 @@ ErrorCode QNNQuantize::reshape(vector> inputs, vector> inputs, vector> outputs) { + switch (activation_dtype_) { + case MLLM_TYPE_I8: + return setUpI8(inputs, outputs); + case MLLM_TYPE_I16: + return setUpI16(inputs, outputs); + default: + return NOT_SUPPORT; + } +} + +ErrorCode QNNQuantize::setUpI8(vector> &inputs, vector> &outputs) { outputs[0]->setDtype(MLLM_TYPE_I8); auto outName = outputs[0]->name(); @@ -38,8 +51,8 @@ ErrorCode QNNQuantize::setUp(vector> inputs, vector()[0] / 127.0; - quantScale = roundf(quantScale * 100000) / 100000; + quantScale = scale_.hostPtr()[0] / (pow(2, 7) - 1); + // quantScale = roundf(quantScale * 100000) / 100000; uint32_t paramsQuantizeDimension[1] = {1}; auto paramsQuantizeName = name() + "quantize_params"; @@ -81,6 +94,70 @@ ErrorCode QNNQuantize::setUp(vector> inputs, vectorname()}, outputTensor, paramsQuantize, "LLaMAPackage"); } + +ErrorCode QNNQuantize::setUpI16(vector> &inputs, vector> &outputs) { + outputs[0]->setDtype(MLLM_TYPE_I16); + auto outName = outputs[0]->name(); + + uint32_t dimensionsOutput[4]; + + if (isNSHD_) { + dimensionsOutput[0] = static_cast(outputs[0]->batch()); + dimensionsOutput[1] = static_cast(outputs[0]->sequence()); + dimensionsOutput[2] = static_cast(outputs[0]->head()); + dimensionsOutput[3] = static_cast(outputs[0]->dimension()); + } else { + dimensionsOutput[0] = static_cast(outputs[0]->batch()); + dimensionsOutput[1] = static_cast(outputs[0]->head()); + dimensionsOutput[2] = static_cast(outputs[0]->sequence()); + dimensionsOutput[3] = static_cast(outputs[0]->dimension()); + } + + float quantScale = 0; + quantScale = scale_.hostPtr()[0] / (pow(2, 15) - 1); + // quantScale = roundf(quantScale * 100000) / 100000; + + uint32_t paramsQuantizeDimension[1] = {1}; + auto paramsQuantizeName = name() + "quantize_params"; + vector paramsQuantize = { + {.paramType = QNN_PARAMTYPE_TENSOR, + .name = "scale", + .tensorParam = + (Qnn_Tensor_t){.version = QNN_TENSOR_VERSION_1, + .v1 = { + .id = 0, + .name = paramsQuantizeName.c_str(), + .type = QNN_TENSOR_TYPE_STATIC, + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_FLOAT_32, + .quantizeParams = {QNN_DEFINITION_UNDEFINED, + QNN_QUANTIZATION_ENCODING_UNDEFINED, + {.scaleOffsetEncoding = {.scale = 0.0000000000000000f, + .offset = 0}}}, + .rank = 1, + .dimensions = paramsQuantizeDimension, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = (uint8_t *)&quantScale, + .dataSize = sizeof(float)}}}}}; + + vector outputTensor = {{QNN_TENSOR_VERSION_1, + {.v1 = { + .id = 0, + .name = outName.c_str(), + .type = getOutputTensorType(outputs[0]), + .dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER, + .dataType = QNN_DATATYPE_SFIXED_POINT_16, + .quantizeParams = {QNN_DEFINITION_DEFINED, + QNN_QUANTIZATION_ENCODING_SCALE_OFFSET, + {.scaleOffsetEncoding = {.scale = quantScale, .offset = 0}}}, + .rank = 4, + .dimensions = dimensionsOutput, + .memType = QNN_TENSORMEMTYPE_RAW, + .clientBuf = {.data = nullptr, + .dataSize = 0}}}}}; + return graphAddNode(name(), "LLaMAQuantize", {inputs[0]->name()}, outputTensor, paramsQuantize, "LLaMAPackage"); +} + ErrorCode QNNQuantize::load(AbstructLoader &loader) { string scaleName = name(); diff --git a/src/backends/qnn/op/QNNQuantize.hpp b/src/backends/qnn/op/QNNQuantize.hpp index dbe15852e..d08e044d2 100644 --- a/src/backends/qnn/op/QNNQuantize.hpp +++ b/src/backends/qnn/op/QNNQuantize.hpp @@ -6,20 +6,24 @@ namespace mllm { class QNNQuantize : public QNNCommonOp { public: - QNNQuantize(Backend *bn, string opName, bool isNSHD); + QNNQuantize(Backend *bn, string opName, DataType type, bool isNSHD); virtual ~QNNQuantize() = default; virtual ErrorCode reshape(vector> inputs, vector> outputs) override; virtual ErrorCode setUp(vector> inputs, vector> outputs) override; virtual ErrorCode load(AbstructLoader &loader) override; + private: bool isNSHD_; Tensor scale_; + + ErrorCode setUpI8(vector> &inputs, vector> &outputs); + ErrorCode setUpI16(vector> &inputs, vector> &outputs); }; class QNNQuantizeCreator : public QNNBackend::Creator { public: virtual Op *create(OpParam op_param, Backend *bn, string name) const { - return new QNNQuantize(bn, name, (bool)op_param["isNSHD"]); + return new QNNQuantize(bn, name, (DataType)op_param["dtype"], (bool)op_param["isNSHD"]); } }; diff --git a/src/backends/qnn/op/QNNRMSNorm.cpp b/src/backends/qnn/op/QNNRMSNorm.cpp index 708cc2bbe..f79297c31 100644 --- a/src/backends/qnn/op/QNNRMSNorm.cpp +++ b/src/backends/qnn/op/QNNRMSNorm.cpp @@ -20,7 +20,7 @@ ErrorCode QNNRMSNorm::reshape(vector> inputs, vector> inputs, vector> outputs) { float quantScale = 0; quantScale = scale_.hostPtr()[0] / 127.0; - quantScale = roundf(quantScale * 100000) / 100000; + // quantScale = roundf(quantScale * 100000) / 100000; uint32_t dimWeight[4] = {(uint32_t)normSize_}; qnnBackend_->modelAddTensor(weight_.name(), (Qnn_Tensor_t){ diff --git a/src/backends/qnn/op/QNNRoPE.cpp b/src/backends/qnn/op/QNNRoPE.cpp index 183633a27..4bfa028f6 100644 --- a/src/backends/qnn/op/QNNRoPE.cpp +++ b/src/backends/qnn/op/QNNRoPE.cpp @@ -124,7 +124,7 @@ ErrorCode QNNRoPE::setUp(vector> inputs, vector()[0] / 127.0; - dequantScale = roundf(dequantScale * 100000) / 100000; + // dequantScale = roundf(dequantScale * 100000) / 100000; if (name().find("q_proj") != -1) { dequantScale = dequantScale / std::sqrt(outputs[0]->dimension()); diff --git a/src/backends/qnn/op/QNNSiLU.cpp b/src/backends/qnn/op/QNNSiLU.cpp index 7af121896..7a40caef8 100644 --- a/src/backends/qnn/op/QNNSiLU.cpp +++ b/src/backends/qnn/op/QNNSiLU.cpp @@ -1,4 +1,3 @@ - #include "QNNSiLU.hpp" #include "Types.hpp" #include "QNNCommonOp.hpp" @@ -23,7 +22,6 @@ ErrorCode QNNSiLU::setUp(vector> inputs, vector(outputs[0]->head()); dimensionsOutput[3] = static_cast(outputs[0]->dimension()); - auto type = QNN_DATATYPE_FLOAT_32; outputs[0]->setDtype(MLLM_TYPE_F32); @@ -31,7 +29,6 @@ ErrorCode QNNSiLU::setUp(vector> inputs, vectorsetDtype(MLLM_TYPE_F16); } - vector outputTensor = {{QNN_TENSOR_VERSION_1, {.v1 = { @@ -51,4 +48,4 @@ ErrorCode QNNSiLU::setUp(vector> inputs, vectorname()}, outputTensor, {}, "LLaMAPackage"); } -} // namespace mllm +} // namespace mllm \ No newline at end of file diff --git a/src/backends/qnn/op/QNNSubGraphFinalize.cpp b/src/backends/qnn/op/QNNSubGraphFinalize.cpp new file mode 100644 index 000000000..55df06768 --- /dev/null +++ b/src/backends/qnn/op/QNNSubGraphFinalize.cpp @@ -0,0 +1,32 @@ + +#include "QNNSubGraphFinalize.hpp" +#include "Types.hpp" +#include "QNNCommonOp.hpp" +#include + +namespace mllm { +QNNSubGraphFinalize::QNNSubGraphFinalize(Backend *bn, string opName) : + QNNCommonOp(bn, opName) { +} + +ErrorCode QNNSubGraphFinalize::reshape(vector> inputs, vector> outputs) { + for(auto& t : inputs) { + t->setTtype(GRAPH_OUTPUT); + } + return Op::reshape(inputs, outputs); +} + +ErrorCode QNNSubGraphFinalize::setUp(vector> inputs, vector> outputs) { + for (auto input : inputs) { + input->to(MLLM_CPU); + } + + this->backend_->onSetUpEnd(inputs, outputs); + return MLLM_NO_ERROR; +} + +ErrorCode QNNSubGraphFinalize::free(vector> inputs, vector> outputs) { + return MLLM_NO_ERROR; +} + +} // namespace mllm diff --git a/src/backends/qnn/op/QNNSubGraphFinalize.hpp b/src/backends/qnn/op/QNNSubGraphFinalize.hpp new file mode 100644 index 000000000..f1cb2cddd --- /dev/null +++ b/src/backends/qnn/op/QNNSubGraphFinalize.hpp @@ -0,0 +1,25 @@ + +#ifndef MLLM_QNNSUBGRAPHFINALIZE_H +#define MLLM_QNNSUBGRAPHFINALIZE_H + +#include "QNNCommonOp.hpp" +namespace mllm { +class QNNSubGraphFinalize : public QNNCommonOp { +public: + QNNSubGraphFinalize(Backend *bn, string opName); + virtual ~QNNSubGraphFinalize() = default; + virtual ErrorCode reshape(vector> inputs, vector> outputs) override; + virtual ErrorCode setUp(vector> inputs, vector> outputs) override; + virtual ErrorCode free(vector> inputs, vector> outputs) override; +}; + +class QNNSubGraphFinalizeCreator : public QNNBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name) const { + return new QNNSubGraphFinalize(bn, name); + } +}; + +} // namespace mllm + +#endif diff --git a/src/backends/qnn/op/QNNSubGraphStart.cpp b/src/backends/qnn/op/QNNSubGraphStart.cpp new file mode 100644 index 000000000..1bf35c61d --- /dev/null +++ b/src/backends/qnn/op/QNNSubGraphStart.cpp @@ -0,0 +1,37 @@ + +#include "QNNSubGraphStart.hpp" +#include "Types.hpp" +#include "QNNCommonOp.hpp" +#include + +namespace mllm { +QNNSubGraphStart::QNNSubGraphStart(Backend *bn, string opName) : + QNNCommonOp(bn, opName) { +} + +ErrorCode QNNSubGraphStart::reshape(vector> inputs, vector> outputs) { + return Op::reshape(inputs, outputs); +} + +ErrorCode QNNSubGraphStart::setUp(vector> inputs, vector> outputs) { + for(auto input : inputs) { + input->to(MLLM_QNN); + input->alloc(); + } + + this->backend_->onSetUpStart(inputs, outputs, name_); + return MLLM_NO_ERROR; +} + +ErrorCode QNNSubGraphStart::free(vector> inputs, vector> outputs) { + return MLLM_NO_ERROR; +} + +ErrorCode QNNSubGraphStart::execute(vector> inputs, vector> outputs) { + this->backend_->onExecuteStart(inputs, outputs, name_); + return MLLM_NO_ERROR; +} + + + +} // namespace mllm diff --git a/src/backends/qnn/op/QNNSubGraphStart.hpp b/src/backends/qnn/op/QNNSubGraphStart.hpp new file mode 100644 index 000000000..ebb15824e --- /dev/null +++ b/src/backends/qnn/op/QNNSubGraphStart.hpp @@ -0,0 +1,26 @@ + +#ifndef MLLM_QNNSUBGRAPHSTART_H +#define MLLM_QNNSUBGRAPHSTART_H + +#include "QNNCommonOp.hpp" +namespace mllm { +class QNNSubGraphStart : public QNNCommonOp { +public: + QNNSubGraphStart(Backend *bn, string opName); + virtual ~QNNSubGraphStart() = default; + virtual ErrorCode reshape(vector> inputs, vector> outputs) override; + virtual ErrorCode setUp(vector> inputs, vector> outputs) override; + virtual ErrorCode free(vector> inputs, vector> outputs) override; + virtual ErrorCode execute(vector> inputs, vector> outputs) override; +}; + +class QNNSubGraphStartCreator : public QNNBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name) const { + return new QNNSubGraphStart(bn, name); + } +}; + +} // namespace mllm + +#endif diff --git a/src/backends/qnn/op/QNNSuperSiLU.cpp b/src/backends/qnn/op/QNNSuperSiLU.cpp index 2e0dcc051..11a2f33cc 100644 --- a/src/backends/qnn/op/QNNSuperSiLU.cpp +++ b/src/backends/qnn/op/QNNSuperSiLU.cpp @@ -31,15 +31,15 @@ ErrorCode QNNSuperSiLU::setUp(vector> inputs, vector()[0] / 127.0; - aScale = roundf(aScale * 100000) / 100000; + // aScale = roundf(aScale * 100000) / 100000; float bScale = 0; bScale = b_scale_.hostPtr()[0] / 127.0; - bScale = roundf(bScale * 100000) / 100000; + // bScale = roundf(bScale * 100000) / 100000; float oScale = 0; oScale = o_scale_.hostPtr()[0] / 127.0; - oScale = roundf(oScale * 100000) / 100000; + // oScale = roundf(oScale * 100000) / 100000; auto paramsSuperSiLuNameA = name() + ".supersilu_params.a_scale"; auto paramsSuperSiLuNameB = name() + ".supersilu_params.b_scale"; diff --git a/src/backends/qnn/op/QNNView.cpp b/src/backends/qnn/op/QNNView.cpp index e383ce226..0a971bcd8 100644 --- a/src/backends/qnn/op/QNNView.cpp +++ b/src/backends/qnn/op/QNNView.cpp @@ -82,7 +82,7 @@ ErrorCode QNNView::reshape(vector> inputs, vector> inputs, vector> outputs) { outputs[0]->setDtype(inputs[0]->dtype()); - if (outputs[0]->dtype() == MLLM_TYPE_I8) + if (outputs[0]->dtype() == MLLM_TYPE_I8 || outputs[0]->dtype() == MLLM_TYPE_I16) return graphAddNode(name(), "Reshape", inputs, outputs, {}, "qti.aisw", true, &scale_); else { return graphAddNode(name(), "Reshape", inputs, outputs, {}, "qti.aisw", true, nullptr); diff --git a/src/models/bert/modeling_bert.hpp b/src/models/bert/modeling_bert.hpp index adb344372..d2f9012c5 100644 --- a/src/models/bert/modeling_bert.hpp +++ b/src/models/bert/modeling_bert.hpp @@ -39,7 +39,7 @@ class BertLayer : public Module { BertLayer() = default; BertLayer(const BertConfig &config, const string &base_name) { // base_name: encoder.layer.n. - attention = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_attention_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, RoPEType::NONE, -1, -1, 0, false, true, config.names_config, base_name + config.names_config._attn_base_name); + attention = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_attention_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, RoPEType::NONE, -1, -1, 0, false, true, config.attn_implementation, config.names_config, base_name + config.names_config._attn_base_name); feed_forward = FeedForward(config.hidden_size, config.intermediate_size, config.hidden_act, true, config.names_config, base_name); diff --git a/src/models/clip/modeling_clip.hpp b/src/models/clip/modeling_clip.hpp index c2cb383b0..c47996b9e 100644 --- a/src/models/clip/modeling_clip.hpp +++ b/src/models/clip/modeling_clip.hpp @@ -23,7 +23,7 @@ class ClipVisionEmbedding final : public Module { position_ids = Parameter(1, std::ceil(img_hw / patch) * std::ceil(img_hw / patch) + 1, 1, 1, base_name + names._position_ids_name); position_embedding = Embedding(std::ceil(img_hw / patch) * std::ceil(img_hw / patch) + 1, hidden_dim, base_name + names._position_embeddings_name); } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto embd = patch_embedding(inputs[0]); embd = embd.transpose({{SEQUENCE, DIMENSION}, {HEAD, SEQUENCE}}); // BSHD->BDHS->BDSH embd = embd.flatten(HEAD, SEQUENCE); @@ -42,13 +42,14 @@ class CLipVisionModel final : public Module { public: CLipVisionModel() = default; CLipVisionModel(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, int patch, int img_hw, int block_num, + string attn_implementation, const ViTNameConfig &names, const string &base_name) { embedding = ClipVisionEmbedding(hidden_dim, patch, img_hw, names, base_name + names._embd_name); pre_layrnorm = LayerNorm(hidden_dim, true, 1e-6, base_name + names._vision_pre_layrnorm_name); - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, act_fn_type, names, base_name + names._layer_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, act_fn_type, attn_implementation, names, base_name + names._layer_name); norm = LayerNorm(hidden_dim, true, 1e-6, base_name + names._post_norm_name); } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto x = embedding(inputs)[0]; x = pre_layrnorm(x); for (auto &block : blocks) { @@ -70,7 +71,7 @@ class ClipTextMLP final : public Module { up_proj = Linear(hidden_dim, ffn_hidden, true, base_name + names._up_proj_name); act = ACT_FN[act_fn_type](base_name + names._ffn_base_name + "act"); } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto x = up_proj(inputs[0]); x = act(x); return {x}; @@ -86,15 +87,18 @@ class ClipTextBlock final : public Module { public: ClipTextBlock() = default; - ClipTextBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, const ClipTextNameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, SPLIT_NONE, false, false, - RoPEType::NONE, -1,-1, 0, true, true, names, base_name + names._attn_base_name); + ClipTextBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, + string attn_implementation, const ClipTextNameConfig &names, const string &base_name) { + attention = MultiHeadAttention(hidden_dim, head_size, head_size, + hidden_dim / head_size, SPLIT_NONE, false, false, + RoPEType::NONE, -1, -1, 0, true, true, attn_implementation, + names, base_name + names._attn_base_name); mlp = ClipTextMLP(hidden_dim, ffn_hidden, act_fn_type, names, base_name + names._ffn_base_name); down_proj = Linear(ffn_hidden, hidden_dim, true, base_name + names._down_proj_name); norm1 = LayerNorm(hidden_dim, true, 1e-6, base_name + names._attn_norm_name); norm2 = LayerNorm(hidden_dim, true, 1e-6, base_name + names._ffn_norm_name); } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto x = norm1(inputs[0]); x = attention({x, x, x})[0]; auto tmp = x + inputs[0]; @@ -118,7 +122,7 @@ class ClipTextEmbedding final : public Module { position_ids = Parameter(1, max_position_embeddings, 1, 1, base_name + names._position_ids_name); position_embedding = Embedding(max_position_embeddings, hidden_dim, base_name + names._position_embeddings_name); } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto embd = token_embedding(inputs[0]); auto pos_embd = position_ids().clip({}, {}, {0, embd.sequence()}, {}); auto p_embd = position_embedding(pos_embd); @@ -134,14 +138,17 @@ class CLipTextModel final : public Module { public: CLipTextModel() = default; - CLipTextModel(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, int max_position_embeddings, int vocab_size, int block_num, + CLipTextModel(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, + int max_position_embeddings, int vocab_size, int block_num, + string attn_implementation, const ClipTextNameConfig &names, const string &base_name) { embedding = ClipTextEmbedding(vocab_size, hidden_dim, max_position_embeddings, names, base_name + names._embd_name); - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, act_fn_type, names, base_name + names._layer_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, act_fn_type, + attn_implementation, names, base_name + names._layer_name); norm = LayerNorm(hidden_dim, true, 1e-6, base_name + names._post_norm_name); } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto x = embedding(inputs)[0]; for (auto &block : blocks) { x = block({x})[0]; @@ -164,22 +171,27 @@ class CLipModel final : public Module { config.hidden_dim, config.head_size, config.ffn_hidden, config.act_fn_type, config.max_position_embeddings, config.text_vocab_size, config.text_block_num, config.patch, config.img_hw, config.block_num, + config.attn_implementation, config.text_names_config, "text_model", config.names_config, "vision_model"){}; CLipModel(int text_hidden_dim, int text_head_size, int text_ffn_hidden, int vision_hidden_dim, int vision_head_size, int vision_ffn_hidden, const string &act_fn_type, int max_position_embeddings, int vocab_size, int text_block_num, int patch, int img_hw, int vision_block_num, + string attn_implementation, const ClipTextNameConfig &text_names, const string &text_base_name, const ViTNameConfig &vit_names, const string &vision_base_name) { - text_model = CLipTextModel(text_hidden_dim, text_head_size, text_ffn_hidden, act_fn_type, max_position_embeddings, vocab_size, text_block_num, + text_model = CLipTextModel(text_hidden_dim, text_head_size, text_ffn_hidden, + act_fn_type, max_position_embeddings, + vocab_size, text_block_num, + attn_implementation, text_names, text_base_name); text_projection = Linear(text_hidden_dim, text_hidden_dim, false, "text_projection"); vision_model = CLipVisionModel(vision_hidden_dim, vision_head_size, vision_ffn_hidden, act_fn_type, patch, img_hw, vision_block_num, - vit_names, vision_base_name); + attn_implementation, vit_names, vision_base_name); visual_projection = Linear(vision_hidden_dim, text_hidden_dim, false, "visual_projection"); } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto text = text_model({inputs[0]})[0]; text = text_projection(text); text = text / text.norm(2); diff --git a/src/models/dclm/modeling_dclm.hpp b/src/models/dclm/modeling_dclm.hpp index 8aa7cca4a..99e805702 100644 --- a/src/models/dclm/modeling_dclm.hpp +++ b/src/models/dclm/modeling_dclm.hpp @@ -58,6 +58,7 @@ class DCLMAttention final : public Module { int attn_hidden_dim_; int head_dim_; int n_heads_; + string attn_implementation_; public: DCLMAttention() = default; @@ -66,14 +67,15 @@ class DCLMAttention final : public Module { attn_hidden_dim_ = cfg.n_heads * head_dim; head_dim_ = head_dim; n_heads_ = cfg.n_heads; + attn_implementation_ = cfg.attn_implementation; in_proj = Linear(cfg.dim, 3 * cfg.n_heads * head_dim, false, base_name + "in_proj"); out_proj = Linear(cfg.n_heads * head_dim, cfg.dim, false, base_name + "out_proj"); q_norm = LayerNorm(cfg.n_heads * head_dim, false, cfg.norm_eps, base_name + "q_norm"); k_norm = LayerNorm(cfg.n_heads * head_dim, false, cfg.norm_eps, base_name + "k_norm"); q_rope = RoPE(cfg.RoPE_type, 10000, cfg.seq_len, base_name + "q_rope"); k_rope = RoPE(cfg.RoPE_type, 10000, cfg.seq_len, base_name + "k_rope"); - k_cache = KVCache(cfg.n_heads, head_dim, 1, cfg.cache_limit, base_name + "k_cache"); - v_cache = KVCache(cfg.n_heads, head_dim, 1, cfg.cache_limit, base_name + "v_cache"); + k_cache = KVCache(cfg.n_heads, head_dim, 1, cfg.cache_limit, (cfg.attn_implementation == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(cfg.n_heads, head_dim, 1, cfg.cache_limit, (cfg.attn_implementation == "flash_attention_2"), base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } @@ -98,13 +100,17 @@ class DCLMAttention final : public Module { k = k_cache(k); v = v_cache(v); - k = k.transpose(SEQUENCE, DIMENSION); - auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(head_dim_); + Tensor o; + if (attn_implementation_ == "flash_attention_2") { + o = Tensor::flash_attention2_forward(q, k, v, true); + } else { // eager implementation + k = k.transpose(SEQUENCE, DIMENSION); + auto qk = Tensor::mm(q, k); + qk = qk / std::sqrt(head_dim_); - qk = softmax(qk, k_cache.getCacheSeqLen()); - - auto o = Tensor::mm(qk, v); + qk = softmax(qk, k_cache.getCacheSeqLen()); + o = Tensor::mm(qk, v); + } o = o.view(-1, 1, -1, n_heads_ * head_dim_); o = out_proj(o); return {o}; diff --git a/src/models/fuyu/configuration_fuyu.hpp b/src/models/fuyu/configuration_fuyu.hpp index e240d2c4e..95be8228e 100644 --- a/src/models/fuyu/configuration_fuyu.hpp +++ b/src/models/fuyu/configuration_fuyu.hpp @@ -55,13 +55,14 @@ class FuyuConfig { block_num = 36; patch_size = 30; chl_size = 3; - max_position_embeddings= 16384; + max_position_embeddings = 16384; rope_theta = 25000; } else { throw std::runtime_error("Unsupported model size"); } cache_limit = token_limit; } + string attn_implementation = "flash_attention_2"; // Options: "flash_attention_2", "eager" }; #endif // CONFIG_FUYU_HPP diff --git a/src/models/fuyu/modeling_fuyu.hpp b/src/models/fuyu/modeling_fuyu.hpp index e459fcd95..4ae3e7f98 100644 --- a/src/models/fuyu/modeling_fuyu.hpp +++ b/src/models/fuyu/modeling_fuyu.hpp @@ -22,9 +22,14 @@ class PersimmonBlock final : public Module { public: PersimmonBlock() = default; - PersimmonBlock(int hidden_dim, int head_size, int ffn_hidden, float rope_theta, int max_position_embeddings, int cache_limit, const FuyuNameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, SPLIT_D_HD, true, false, - PERSIMMONROPE, rope_theta, max_position_embeddings, cache_limit, true, true, names, base_name + names._attn_base_name); + PersimmonBlock(int hidden_dim, int head_size, int ffn_hidden, float rope_theta, int max_position_embeddings, int cache_limit, + string attn_implementation, + const FuyuNameConfig &names, const string &base_name) { + attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, + SPLIT_D_HD, true, false, + PERSIMMONROPE, rope_theta, max_position_embeddings, cache_limit, true, true, + attn_implementation, + names, base_name + names._attn_base_name); mlp = FeedForward(hidden_dim, ffn_hidden, "ReLU2", true, names, base_name + names._ffn_base_name); norm1 = LayerNorm(hidden_dim, true, 1e-6, base_name + names._attn_norm_name); @@ -52,8 +57,14 @@ class Persimmon final : public Module { public: Persimmon() = default; - Persimmon(int hidden_dim, int head_size, int ffn_hidden, float rope_theta, int max_position_embeddings, int cache_limit, int block_num, int vocab_size, const FuyuNameConfig &names) { - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, rope_theta, max_position_embeddings, cache_limit, names, names.blk_name); + Persimmon(int hidden_dim, int head_size, int ffn_hidden, float rope_theta, int max_position_embeddings, + int cache_limit, int block_num, int vocab_size, + string attn_implementation, + const FuyuNameConfig &names) { + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, + rope_theta, max_position_embeddings, cache_limit, + attn_implementation, + names, names.blk_name); norm = LayerNorm(hidden_dim, true, 1e-6, names.post_norm_name); lm_head = Linear(hidden_dim, vocab_size, false, names.lm_head_name); } @@ -89,15 +100,17 @@ class FuyuModel final : public Module { FuyuModel(config.vocab_size, config.hidden_dim, config.head_size, config.ffn_hidden, config.block_num, config.rope_theta, config.max_position_embeddings, config.cache_limit, config.patch_size, config.chl_size, + config.attn_implementation, config.name_config) { } FuyuModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, float rope_theta, int max_position_embeddings, int cache_limit, int patch_size, int chl_size, + string attn_implementation, const FuyuNameConfig &names) { embed_tokens = Embedding(vocab_size, hidden_dim, names.token_embd_name); vision_embed_tokens = Linear(patch_size * patch_size * chl_size, hidden_dim, true, names.vision_embed_tokens_name); - persimmon = Persimmon(hidden_dim, head_size, ffn_hidden, rope_theta, max_position_embeddings, cache_limit, block_num, vocab_size, names); + persimmon = Persimmon(hidden_dim, head_size, ffn_hidden, rope_theta, max_position_embeddings, cache_limit, block_num, vocab_size, attn_implementation, names); } vector Forward(vector inputs, vector args) override { auto input_ids = embed_tokens(inputs[0]); diff --git a/src/models/gemma/modeling_gemma.hpp b/src/models/gemma/modeling_gemma.hpp index 08ed1788f..8ebd491f8 100644 --- a/src/models/gemma/modeling_gemma.hpp +++ b/src/models/gemma/modeling_gemma.hpp @@ -53,9 +53,12 @@ class GemmaDecoder final : public Module { public: GemmaDecoder() = default; GemmaDecoder(const GemmaConfig &config, const GemmaNameConfig &names, const string &base_name) { - self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, true, false, names, base_name + names._attn_base_name); + config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, true, false, + config.attn_implementation, + names, base_name + names._attn_base_name); mlp = GemmaMLP(config.hidden_size, config.intermediate_size, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, true, base_name + names._attn_norm_name); post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, true, base_name + names._ffn_norm_name); diff --git a/src/models/gemma2/modeling_gemma2.hpp b/src/models/gemma2/modeling_gemma2.hpp index 5fb9984db..6f5042ab7 100644 --- a/src/models/gemma2/modeling_gemma2.hpp +++ b/src/models/gemma2/modeling_gemma2.hpp @@ -20,7 +20,7 @@ class Gemma2Attention final : public Module { head_dim = 2048 / num_heads; num_key_value_heads = config.num_key_value_heads; num_key_value_groups = num_heads / num_key_value_heads; - + attn_impl = config.attn_implementation; // init layers q_proj = Linear(hidden_size, head_dim * num_heads, false, base_name + names._q_proj_name); k_proj = Linear(hidden_size, head_dim * num_key_value_heads, false, @@ -32,8 +32,8 @@ class Gemma2Attention final : public Module { base_name + "q_rope"); k_rope = RoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "v_cache"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } @@ -56,15 +56,17 @@ class Gemma2Attention final : public Module { key_states = k_cache(key_states); value_states = v_cache(value_states); - // attention weight - auto atten_weight = - Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) - / std::sqrt(head_dim); - - atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); - - // attention output - auto atten_output = Tensor::mm(atten_weight, value_states); + Tensor atten_output; + if (attn_impl == "flash_attention_2") { + atten_output = Tensor::flash_attention2_forward(query_states, key_states, value_states, true); + } else { // eager implementation + // attention weight + auto atten_weight = + Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) + / std::sqrt(head_dim); + atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); + atten_output = Tensor::mm(atten_weight, value_states); + } atten_output = atten_output.view(-1, 1, -1, head_dim * num_heads); atten_output = o_proj(atten_output); return {atten_output}; @@ -93,6 +95,7 @@ class Gemma2Attention final : public Module { KVCache k_cache; KVCache v_cache; Softmax softmax; + string attn_impl; }; class Gemma2MLP final : public Module { diff --git a/src/models/imagebind/modeling_imagebind.hpp b/src/models/imagebind/modeling_imagebind.hpp index 2fe620851..be8179dc7 100644 --- a/src/models/imagebind/modeling_imagebind.hpp +++ b/src/models/imagebind/modeling_imagebind.hpp @@ -20,7 +20,9 @@ class EncoderBlock final : public Module { public: EncoderBlock() = default; - EncoderBlock(int hidden_dim, int head_size, int ffn_hidden, const string &model_type, const ImagebindNameConfig &names, const string &base_name) { + EncoderBlock(int hidden_dim, int head_size, int ffn_hidden, const string &model_type, + string attn_implementation, + const ImagebindNameConfig &names, const string &base_name) { bool do_mask = false; bool bias_kv_cat = false; if (model_type == "text") { @@ -31,6 +33,7 @@ class EncoderBlock final : public Module { attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, SPLIT_HD, false, bias_kv_cat, RoPEType::NONE, -1, -1, 0, do_mask, true, + attn_implementation, names, base_name + names._attn_base_name); ffn = FeedForward(hidden_dim, ffn_hidden, "GELU", true, names, base_name + names._ffn_base_name); @@ -83,13 +86,16 @@ class ImagebindVisionModel final : public Module { ImagebindVisionModel(const ImagebindConfig &config) : ImagebindVisionModel(config.vision_hidden_dim, config.vision_head_size, config.vision_ffn_hidden, config.head_hidden_dim, config.patch, config.patch_time, config.img_hw, config.vision_block_num, + config.attn_implementation, config.names_config){}; ImagebindVisionModel(int hidden_dim, int head_size, int ffn_hidden, int head_hidden_dim, int patch, int patch_time, int img_hw, int block_num, + string attn_implementation, const ImagebindNameConfig &names) { embedding = ImagebindVisionEmbedding(hidden_dim, patch, patch_time, img_hw, names, names._vision_embd_name); pre_transformer_layer = LayerNorm(hidden_dim, true, 1e-6, names.vision_pre_transformer_layer_name); - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, "vision", names, names._vision_blocks_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, "vision", + attn_implementation, names, names._vision_blocks_name); norm = LayerNorm(hidden_dim, true, 1e-6, names.vision_post_norm_name); head = Linear(hidden_dim, head_hidden_dim, false, names.vision_head_name); } @@ -133,14 +139,17 @@ class ImagebindTextModel final : public Module { public: ImagebindTextModel() = default; ImagebindTextModel(const ImagebindConfig &config) : - ImagebindTextModel(config.text_hidden_dim, config.text_head_size, config.text_ffn_hidden, config.head_hidden_dim, + ImagebindTextModel(config.text_hidden_dim, config.text_head_size, + config.text_ffn_hidden, config.head_hidden_dim, config.vocab_size, config.max_position_embeddings, config.text_block_num, + config.attn_implementation, config.names_config){}; ImagebindTextModel(int hidden_dim, int head_size, int ffn_hidden, int head_hidden_dim, int vocab_size, int max_position_embeddings, int block_num, + string attn_implementation, const ImagebindNameConfig &names) { embedding = ImagebindTextEmbedding(vocab_size, hidden_dim, max_position_embeddings, names, names._text_embd_name); - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, "text", names, names._text_blocks_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, "text", attn_implementation, names, names._text_blocks_name); norm = LayerNorm(hidden_dim, true, 1e-6, names.text_post_norm_name); head = Linear(hidden_dim, head_hidden_dim, false, names.text_head_name); } @@ -197,12 +206,15 @@ class ImagebindAudioModel final : public Module { ImagebindAudioModel(config.audio_hidden_dim, config.audio_head_size, config.audio_ffn_hidden, config.head_hidden_dim, config.audio_kernal, config.audio_stride, config.audio_h, config.audio_w, config.audio_block_num, + config.attn_implementation, config.names_config){}; ImagebindAudioModel(int hidden_dim, int head_size, int ffn_hidden, int head_hidden_dim, int patch, int stride, int img_h, int img_w, int block_num, + string attn_implementation, const ImagebindNameConfig &names) { embedding = ImagebindAudioEmbedding(hidden_dim, patch, stride, img_h, img_w, names, names._audio_embd_name); - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, "audio", names, names._audio_blocks_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, "audio", + attn_implementation, names, names._audio_blocks_name); norm = LayerNorm(hidden_dim, true, 1e-6, names.audio_post_norm_name); head = Linear(hidden_dim, head_hidden_dim, false, names.audio_head_name); } @@ -235,18 +247,24 @@ class ImagebindModel final : public Module { config.text_hidden_dim, config.text_head_size, config.text_ffn_hidden, config.vocab_size, config.max_position_embeddings, config.text_block_num, config.audio_hidden_dim, config.audio_head_size, config.audio_ffn_hidden, config.audio_kernal, config.audio_stride, config.audio_h, config.audio_w, config.audio_block_num, config.head_hidden_dim, + config.attn_implementation, config.names_config){}; - ImagebindModel(int vision_hidden_dim, int vision_head_size, int vision_ffn_hidden, int patch, int patch_time, int img_hw, int vision_block_num, + ImagebindModel(int vision_hidden_dim, int vision_head_size, int vision_ffn_hidden, int patch, int patch_time, + int img_hw, int vision_block_num, int text_hidden_dim, int text_head_size, int text_ffn_hidden, int vocab_size, int max_position_embeddings, int text_block_num, int audio_hidden_dim, int audio_head_size, int audio_ffn_hidden, int audio_kernal, int audio_stride, int audio_h, int audio_w, int audio_block_num, int head_hidden_dim, + string attn_implementation, const ImagebindNameConfig &names) { - text_model = ImagebindTextModel(text_hidden_dim, text_head_size, text_ffn_hidden, head_hidden_dim, - vocab_size, max_position_embeddings, text_block_num, names); - vision_model = ImagebindVisionModel(vision_hidden_dim, vision_head_size, vision_ffn_hidden, head_hidden_dim, - patch, patch_time, img_hw, vision_block_num, names); - audio_model = ImagebindAudioModel(audio_hidden_dim, audio_head_size, audio_ffn_hidden, head_hidden_dim, - audio_kernal, audio_stride, audio_h, audio_w, audio_block_num, names); + text_model = ImagebindTextModel(text_hidden_dim, text_head_size, + text_ffn_hidden, head_hidden_dim, + vocab_size, max_position_embeddings, text_block_num, attn_implementation, names); + vision_model = ImagebindVisionModel(vision_hidden_dim, vision_head_size, + vision_ffn_hidden, head_hidden_dim, + patch, patch_time, img_hw, vision_block_num, attn_implementation, names); + audio_model = ImagebindAudioModel(audio_hidden_dim, audio_head_size, + audio_ffn_hidden, head_hidden_dim, + audio_kernal, audio_stride, audio_h, audio_w, audio_block_num, attn_implementation, names); softmax = Softmax(DIMENSION, "final.softmax1"); softmax2 = Softmax(DIMENSION, "final.softmax2"); } diff --git a/src/models/llama/configuration_llama.hpp b/src/models/llama/configuration_llama.hpp index f97ede2be..46256e6a6 100644 --- a/src/models/llama/configuration_llama.hpp +++ b/src/models/llama/configuration_llama.hpp @@ -75,9 +75,11 @@ class LLaMAConfig : public TransformerConfig { float rope_theta; int max_position_embeddings; - explicit LLaMAConfig(int token_limit, string billions = "7B", RoPEType type = LLAMAROPE, int vocab = 32000) { + explicit LLaMAConfig(int token_limit, string billions = "7B", RoPEType type = LLAMAROPE, int vocab = 32000, + string attn_implementation_ = "flash_attention_2") { names_config.init(type); vocab_size = vocab; + attn_implementation = attn_implementation_; if (billions == "7B" || billions == "7b") { hidden_dim = 4096; head_size = 32; diff --git a/src/models/llama/modeling_llama.hpp b/src/models/llama/modeling_llama.hpp index 5e559ca59..7d8eabe26 100644 --- a/src/models/llama/modeling_llama.hpp +++ b/src/models/llama/modeling_llama.hpp @@ -44,9 +44,15 @@ class LLaMABlock final : public Module { public: LLaMABlock() = default; - LLaMABlock(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, const LLaMANameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_NONE, false, false, - RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, names, base_name + names._attn_base_name); + LLaMABlock(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, + RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, + string attn_implementation, + const LLaMANameConfig &names, const string &base_name) { + attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, + SPLIT_NONE, false, false, + RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, + attn_implementation, + names, base_name + names._attn_base_name); mlp = LLaMAMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); norm2 = RMSNorm(hidden_dim, 1e-6, base_name + names._ffn_norm_name); @@ -74,14 +80,24 @@ class LLaMAModel final : public Module { public: explicit LLaMAModel(const LLaMAConfig &config) : - LLaMAModel(config.vocab_size, config.hidden_dim, config.head_size, config.num_key_value_heads, config.ffn_hidden, config.block_num, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, + LLaMAModel(config.vocab_size, config.hidden_dim, config.head_size, + config.num_key_value_heads, config.ffn_hidden, config.block_num, + config.RoPE_type, config.rope_theta, + config.max_position_embeddings, config.cache_limit, + config.attn_implementation, config.names_config, config.names_config.blk_name) { } - LLaMAModel(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, + LLaMAModel(int vocab_size, int hidden_dim, int head_size, + int kv_head_size, int ffn_hidden, int block_num, + RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, + string attn_implementation, const LLaMANameConfig &names, const string &base_name) { embedding = Embedding(vocab_size, hidden_dim, names.token_embd_name); - blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, names, base_name); + blocks = List(block_num, hidden_dim, head_size, + kv_head_size, ffn_hidden, RoPE_type, + rope_theta, max_position_embeddings, cache_limit, + attn_implementation, + names, base_name); norm = RMSNorm(hidden_dim, 1e-6, names.post_norm_name); lm_head = Linear(hidden_dim, vocab_size, false, names.lm_head_name); } diff --git a/src/models/llama/modeling_sparse_llama.hpp b/src/models/llama/modeling_sparse_llama.hpp index c496eb471..d59363239 100644 --- a/src/models/llama/modeling_sparse_llama.hpp +++ b/src/models/llama/modeling_sparse_llama.hpp @@ -24,13 +24,13 @@ class SparseLLaMAMLP final : public Module { gate_proj = Linear(hidden_dim, ffn_hidden, false, base_name + names._gate_proj_name); relu = ReLU(base_name + "act"); up_proj = SparseIdLinear(hidden_dim, ffn_hidden, base_name + names._up_proj_name); - if(is_down_sparse) { + if (is_down_sparse) { down_proj = SparseLinear(ffn_hidden, hidden_dim, base_name + names._down_proj_name); - }else{ + } else { down_proj = Linear(ffn_hidden, hidden_dim, false, base_name + names._down_proj_name); } } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto x = inputs[0]; auto id = gate_proj(inputs[0]); auto gate = relu(id); @@ -49,14 +49,17 @@ class SparseLLaMABlock final : public Module { public: SparseLLaMABlock() = default; - SparseLLaMABlock(bool is_down_sparse, int hidden_dim, int head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, const LLaMANameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, SPLIT_NONE, false, false, - RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, names, base_name + names._attn_base_name); + SparseLLaMABlock(bool is_down_sparse, int hidden_dim, int head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const LLaMANameConfig &names, const string &base_name) { + attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, + SPLIT_NONE, false, false, + RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, + attn_implementation, + names, base_name + names._attn_base_name); mlp = SparseLLaMAMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name, is_down_sparse); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); norm2 = RMSNorm(hidden_dim, 1e-6, base_name + names._ffn_norm_name); } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto x = norm1(inputs[0]); x = attention({x, x, x})[0]; auto tmp = x + inputs[0]; @@ -75,19 +78,22 @@ class SparseLLaMAModel final : public Module { public: explicit SparseLLaMAModel(const LLaMAConfig &config, bool is_down_sparse = false) : - SparseLLaMAModel(config.vocab_size, config.hidden_dim, config.head_size, config.ffn_hidden, config.block_num, config.RoPE_type, - config.rope_theta, config.max_position_embeddings, config.cache_limit, - config.names_config, config.names_config.blk_name, is_down_sparse) { + SparseLLaMAModel(config.vocab_size, config.hidden_dim, config.head_size, + config.ffn_hidden, config.block_num, config.RoPE_type, + config.rope_theta, config.max_position_embeddings, config.cache_limit, + config.attn_implementation, + config.names_config, config.names_config.blk_name, is_down_sparse) { } - SparseLLaMAModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, - float rope_theta, int max_position_embeddings, int cache_limit, - const LLaMANameConfig &names, const string &base_name, bool is_down_sparse) { + SparseLLaMAModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, + float rope_theta, int max_position_embeddings, int cache_limit, + string attn_implementation, + const LLaMANameConfig &names, const string &base_name, bool is_down_sparse) { embedding = Embedding(vocab_size, hidden_dim, names.token_embd_name); - blocks = List(block_num, is_down_sparse, hidden_dim, head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, names, base_name); + blocks = List(block_num, is_down_sparse, hidden_dim, head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, attn_implementation, names, base_name); norm = RMSNorm(hidden_dim, 1e-6, names.post_norm_name); lm_head = Linear(hidden_dim, vocab_size, false, names.lm_head_name); } - vector Forward(vector inputs, vector args) override { + vector Forward(vector inputs, vector args) override { auto x = embedding(inputs[0]); for (auto &block : blocks) { x = block({x})[0]; diff --git a/src/models/llama3/modeling_llama3.hpp b/src/models/llama3/modeling_llama3.hpp index 66020eb7f..63eeb10b4 100644 --- a/src/models/llama3/modeling_llama3.hpp +++ b/src/models/llama3/modeling_llama3.hpp @@ -45,16 +45,18 @@ class Llama3Attention final : public Module { int head_size_; // Size of each attention head int kv_head_size_; // Size of each key/value head int hidden_dim_; // Hidden dimension size + string attn_impl; public: Llama3Attention() = default; Llama3Attention(int hidden_dim, int head_size, int kv_head_size, RoPEType RoPE_type, float rope_theta, - int max_position_embeddings, int cache_limit, const TransformerNameConfig &names, - const string &base_name, const RoPEConfig &rope_config = {}) { + int max_position_embeddings, int cache_limit, string attn_implementation, + const TransformerNameConfig &names, const string &base_name, const RoPEConfig &rope_config = {}) { hidden_dim_ = hidden_dim; head_size_ = head_size; kv_head_size_ = kv_head_size; + attn_impl = attn_implementation; // Initialize projections q_proj = Linear(hidden_dim, head_size * (hidden_dim / head_size), false, base_name + names._q_proj_name); @@ -73,8 +75,8 @@ class Llama3Attention final : public Module { // Initialize KV cache if (cache_limit > 0) { - k_cache = KVCache(kv_head_size, hidden_dim / head_size, head_size / kv_head_size, cache_limit, base_name + "k_cache"); - v_cache = KVCache(kv_head_size, hidden_dim / head_size, head_size / kv_head_size, cache_limit, base_name + "v_cache"); + k_cache = KVCache(kv_head_size, hidden_dim / head_size, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(kv_head_size, hidden_dim / head_size, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); } // Initialize softmax @@ -102,23 +104,27 @@ class Llama3Attention final : public Module { k = k_cache(k); v = v_cache(v); } - - // Transpose keys for dot product - k = k.transpose(SEQUENCE, DIMENSION); - - // Compute attention scores - Tensor qk = Tensor::mm(q, k); // Dot product of queries and keys - qk = qk / std::sqrt(hidden_dim_ / head_size_); // Scale by sqrt(d_k) - - // Apply softmax - if (k_cache.ready() && v_cache.ready()) { - qk = softmax(qk, k_cache.getCacheSeqLen()); // Masked softmax if cache is used - } else { - qk = softmax(qk); // Regular softmax + Tensor o; + if (attn_impl == "flash_attention_2") { + o = Tensor::flash_attention2_forward(q, k, v, true); + } else { // eager implementation + // Transpose keys for dot product + k = k.transpose(SEQUENCE, DIMENSION); + + // Compute attention scores + Tensor qk = Tensor::mm(q, k); // Dot product of queries and keys + qk = qk / std::sqrt(hidden_dim_ / head_size_); // Scale by sqrt(d_k) + + // Apply softmax + if (k_cache.ready() && v_cache.ready()) { + qk = softmax(qk, k_cache.getCacheSeqLen()); // Masked softmax if cache is used + } else { + qk = softmax(qk); // Regular softmax + } + + // Compute attention output + o = Tensor::mm(qk, v); // Weighted sum of values } - - // Compute attention output - Tensor o = Tensor::mm(qk, v); // Weighted sum of values o = o.view(-1, 1, -1, hidden_dim_); // Reshape to original dimensions o = o_proj(o); // Output projection @@ -154,7 +160,8 @@ class Llama3Block final : public Module { } attention = Llama3Attention(hidden_dim, head_size, kv_head_size, RoPE_type, rope_theta, - max_position_embeddings, cache_limit, names, base_name + names._attn_base_name, rope_config); + max_position_embeddings, cache_limit, config.attn_implementation, + names, base_name + names._attn_base_name, rope_config); mlp = Llama3MLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); norm2 = RMSNorm(hidden_dim, 1e-6, base_name + names._ffn_norm_name); @@ -198,8 +205,8 @@ class Llama3Model final : public Module { // we just simply use the token embedding as the lm_head // but now we are not really tying the word embeddings auto lm_head_name = names.lm_head_name; - if (config.tie_word_embeddings) - lm_head_name = names.token_embd_name; + assert(config.tie_word_embeddings); + lm_head_name = names.token_embd_name; lm_head = Parameter(1, vocab_size, 1, hidden_dim, lm_head_name + ".weight"); } vector Forward(vector inputs, vector args) override { diff --git a/src/models/llava/modeling_llava.hpp b/src/models/llava/modeling_llava.hpp index eafa26b92..8aca0088f 100644 --- a/src/models/llava/modeling_llava.hpp +++ b/src/models/llava/modeling_llava.hpp @@ -20,9 +20,8 @@ class LLaMABodyModel final : public Module { public: LLaMABodyModel() = default; - LLaMABodyModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, - const LLaMANameConfig &names, const string &base_name) { - blocks = List(block_num, hidden_dim, head_size, head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, names, base_name); + LLaMABodyModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const LLaMANameConfig &names, const string &base_name) { + blocks = List(block_num, hidden_dim, head_size, head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, attn_implementation, names, base_name); norm = RMSNorm(hidden_dim, 1e-6, names.post_norm_name); lm_head = Linear(hidden_dim, vocab_size, false, names.lm_head_name); } @@ -74,10 +73,11 @@ class LLaVAVisionModel final : public Module { public: LLaVAVisionModel() = default; LLaVAVisionModel(int hidden_dim, int head_size, int ffn_hidden, int patch, int img_hw, int block_num, + string attn_implementation, const ViTNameConfig &names, const string &base_name) { embedding = LLaVAVisionEmbedding(hidden_dim, patch, img_hw, names, base_name + names._embd_name); pre_layrnorm = LayerNorm(hidden_dim, true, 1e-6, base_name + names._vision_pre_layrnorm_name); - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, "QuickGELU", names, base_name + names._layer_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, "QuickGELU", attn_implementation, names, base_name + names._layer_name); clip_len_ = std::ceil(img_hw / patch) * std::ceil(img_hw / patch) + 1; linear_1 = Linear(hidden_dim, ffn_hidden, true, "multi_modal_projector.linear_1"); gelu = GELU("multi_modal_projector.act"); @@ -106,19 +106,21 @@ class LLaVAModel final : public Module { LLaVAModel(config.vocab_size, config.hidden_dim, config.head_size, config.ffn_hidden, config.block_num, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, config.names_config, - config.vision_hidden_dim, config.vision_head_size, config.vision_ffn_hidden, config.patch, config.img_hw, config.vision_block_num, + config.vision_hidden_dim, config.vision_head_size, config.vision_ffn_hidden, config.patch, config.img_hw, config.vision_block_num, config.attn_implementation, config.vit_names_config) { } LLaVAModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, const LLaMANameConfig &names_config, int vision_hidden_dim, int vision_head_size, int vision_ffn_hidden, int patch, int img_hw, int vision_block_num, + string attn_implementation, const ViTNameConfig &vit_names_config) { text_embedding = Embedding(vocab_size, hidden_dim, names_config.token_embd_name); llama_body = LLaMABodyModel(vocab_size, hidden_dim, head_size, ffn_hidden, block_num, - RoPE_type, rope_theta, max_position_embeddings, cache_limit, + RoPE_type, rope_theta, max_position_embeddings, cache_limit, attn_implementation, names_config, names_config.blk_name); vision_tower = LLaVAVisionModel(vision_hidden_dim, vision_head_size, vision_ffn_hidden, patch, img_hw, vision_block_num, + attn_implementation, vit_names_config, vit_names_config.vison_model_name); } vector Forward(vector inputs, vector args) override { diff --git a/src/models/minicpm/modeling_minicpm.hpp b/src/models/minicpm/modeling_minicpm.hpp index 163bc0b47..502357032 100644 --- a/src/models/minicpm/modeling_minicpm.hpp +++ b/src/models/minicpm/modeling_minicpm.hpp @@ -41,10 +41,13 @@ class MiniCPMDecoder final : public Module { public: MiniCPMDecoder() = default; MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { - self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, names, base_name + names._attn_base_name); + true, false, + config.attn_implementation, + names, base_name + names._attn_base_name); mlp = MiniCPMMLP(config.hidden_size, config.intermediate_size, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); diff --git a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp index bdb8f7865..c2ebd5567 100644 --- a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp +++ b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp @@ -98,116 +98,99 @@ class MiniCPMMoE final : public Module { expert_weights = expert_weights.view(-1, -1, 1, 1); // 1, k* batch*seq, 1, 1 auto idxs = expert_indices.argsort(); // 1, 1, 1, k* batch*seq auto tokens_per_expert = expert_indices.bincount(); // (1, 1, 1, 0) 1, 1, 1, k - /* - load_experts_1th(tokens_per_expert); - auto expert_cache = moe_infer(hidden_states, tokens_per_expert, expert_weights, idxs); - */ + Tensor expert_cache; #ifdef MTIME - if (Tensor::tensor_status == TENSOR_STATIC_READY && hidden_states.sequence() == 1) { - std::cout << "attn || exe time: " << (mllm_time_us() - end_infer_last) / 1000.0F << "ms" << std::endl; - } + std::cout << "attn || exe time: " << (mllm_time_us() - end_infer_last) / 1000.0F << "ms" << std::endl; #endif - if (Tensor::tensor_status == TENSOR_STATIC_READY) { - vector tokens_per_expert_vector; - for (int i = 0; i < tokens_per_expert.dimension(); ++i) { - if (tokens_per_expert.d(0, 0, 0, i)) { - tokens_per_expert_vector.push_back(i); - } - } - // - if (layer_idx < 39 && tokens_per_expert_vector.size() == 2) { - if (mbm_maps[layer_idx].find(tokens_per_expert_vector) != mbm_maps[layer_idx].end()) { - mbm_load_expert_idxs.clear(); - auto c = mbm_maps[layer_idx][tokens_per_expert_vector]; - mbm_load_expert_idxs = c[0]; - mbm_load_layer_idx = layer_idx + 1; - do_mbm_load = true; - } - } else if (layer_idx == 39 && tokens_per_expert_vector.size() == 2) { - if (mbm_maps[layer_idx].find(tokens_per_expert_vector) != mbm_maps[layer_idx].end()) { - mbm_load_expert_idxs.clear(); - auto c = mbm_maps[layer_idx][tokens_per_expert_vector]; - mbm_load_expert_idxs = c[0]; - mbm_load_layer_idx = 0; - do_mbm_load = true; - } - } - /* - mbm_load_expert_idxs = mbm_idxs; - mbm_load_layer_idx = layer_idx; - do_mbm_load = true; - */ - if (mbm_idxs_size == 2 && tokens_per_expert_vector.size() == 2) { // layer_idx > 0 && && layer_idx < 39 - int &done = dones[layer_idx]; // 标志变量,用于表示数据是否已被修改 - cvs[layer_idx]->wait(locks[layer_idx], [&done] { return done; }); // 等待条件满足 - assert(dones[layer_idx]); + vector tokens_per_expert_vector; + for (int i = 0; i < tokens_per_expert.dimension(); ++i) { + if (tokens_per_expert.d(0, 0, 0, i)) { + tokens_per_expert_vector.push_back(i); } - if (!experts_loaded(tokens_per_expert_vector)) { - load_experts(tokens_per_expert_vector); + } + // + if (layer_idx < 39 && tokens_per_expert_vector.size() == 2) { + if (mbm_maps[layer_idx].find(tokens_per_expert_vector) != mbm_maps[layer_idx].end()) { + mbm_load_expert_idxs.clear(); + auto c = mbm_maps[layer_idx][tokens_per_expert_vector]; + mbm_load_expert_idxs = c[0]; + mbm_load_layer_idx = layer_idx + 1; + do_mbm_load = true; } - assert(experts_loaded(tokens_per_expert_vector)); - expert_cache = moe_infer(hidden_states, tokens_per_expert, expert_weights, idxs); - if (mbm_idxs_size == 2 && tokens_per_expert_vector.size() == 2) { // layer_idx > 0 && && layer_idx < 39 - reset_syntax_mbm(layer_idx); + } else if (layer_idx == 39 && tokens_per_expert_vector.size() == 2) { + if (mbm_maps[layer_idx].find(tokens_per_expert_vector) != mbm_maps[layer_idx].end()) { + mbm_load_expert_idxs.clear(); + auto c = mbm_maps[layer_idx][tokens_per_expert_vector]; + mbm_load_expert_idxs = c[0]; + mbm_load_layer_idx = 0; + do_mbm_load = true; } - if (layer_idx == 0) - mbm_idxs_size = tokens_per_expert_vector.size(); - } else { - expert_cache = moe_infer(hidden_states, tokens_per_expert, expert_weights, idxs); } -#ifdef MTIME - if (Tensor::tensor_status == TENSOR_STATIC_READY && hidden_states.sequence() == 1) { - end_infer_last = mllm_time_us(); + if (mbm_idxs_size == 2 && tokens_per_expert_vector.size() == 2) { // layer_idx > 0 && && layer_idx < 39 + int &done = dones[layer_idx]; // 标志变量,用于表示数据是否已被修改 + cvs[layer_idx]->wait(locks[layer_idx], [&done] { return done; }); // 等待条件满足 + assert(dones[layer_idx]); + } + if (!experts_loaded(tokens_per_expert_vector)) { + load_experts(tokens_per_expert_vector); + } + assert(experts_loaded(tokens_per_expert_vector)); + expert_cache = moe_infer(hidden_states, tokens_per_expert, expert_weights, idxs); + if (mbm_idxs_size == 2 && tokens_per_expert_vector.size() == 2) { // layer_idx > 0 && && layer_idx < 39 + reset_syntax_mbm(layer_idx); } + if (layer_idx == 0) + mbm_idxs_size = tokens_per_expert_vector.size(); +#ifdef MTIME + end_infer_last = mllm_time_us(); #endif return {expert_cache}; } void load_experts(vector expert_idxs) { - if (Tensor::tensor_status == TENSOR_STATIC_READY) { #ifdef MTIME - auto start_infer = mllm_time_us(); + auto start_infer = mllm_time_us(); #endif - int result; - // #pragma omp parallel for num_threads(CPUBackend::cpu_threads) - for (int i = 0; i < expert_idxs.size(); ++i) { - if (expert_idxs.size() == 2) { - if (std::find(mbm_v[layer_idx].begin(), mbm_v[layer_idx].end(), expert_idxs[i]) != mbm_v[layer_idx].end()) { - // 在 mbm_v[layer_idx] 中找到了 expert_idxs[i] - if (experts[expert_idxs[i]].loaded()) { - continue; - } else { - std::cout << "[ERROR] experts load." << std::endl; - experts[expert_idxs[i]].load(); - continue; - } - } - if (mbm_v[layer_idx].size() >= mbm_num_max_experts) { - result = mbm_queue_remove(mbm_v[layer_idx], expert_idxs); - if (result != -1) { // mbm_v[layer_idx]不全是expert_idxs - experts[result].free(); - mbm_v[layer_idx].push_back(expert_idxs[i]); - // if (mbm_load_layer_idx != layer_idx) - // std::cout << layer_idx << " " << mbm_load_layer_idx << " : " << expert_idxs[i] << std::endl; - experts[expert_idxs[i]].load(); - } + int result; + // #pragma omp parallel for num_threads(CPUBackend::cpu_threads) + for (int i = 0; i < expert_idxs.size(); ++i) { + if (expert_idxs.size() == 2) { + if (std::find(mbm_v[layer_idx].begin(), mbm_v[layer_idx].end(), expert_idxs[i]) != mbm_v[layer_idx].end()) { + // 在 mbm_v[layer_idx] 中找到了 expert_idxs[i] + if (experts[expert_idxs[i]].loaded()) { + continue; } else { + std::cout << "[ERROR] experts load." << std::endl; + experts[expert_idxs[i]].load(); + continue; + } + } + if (mbm_v[layer_idx].size() >= mbm_num_max_experts) { + result = mbm_queue_remove(mbm_v[layer_idx], expert_idxs); + if (result != -1) { // mbm_v[layer_idx]不全是expert_idxs + experts[result].free(); mbm_v[layer_idx].push_back(expert_idxs[i]); + // if (mbm_load_layer_idx != layer_idx) + // std::cout << layer_idx << " " << mbm_load_layer_idx << " : " << expert_idxs[i] << std::endl; experts[expert_idxs[i]].load(); } - assert(experts[expert_idxs[i]].loaded()); } else { + mbm_v[layer_idx].push_back(expert_idxs[i]); experts[expert_idxs[i]].load(); } + assert(experts[expert_idxs[i]].loaded()); + } else { + experts[expert_idxs[i]].load(); } + } #ifdef MTIME - if (expert_idxs.size() == 2) { - auto end_infer = mllm_time_us(); - std::cout << "expert|| load time: " << (end_infer - start_infer) / 1000.0F << "ms" << std::endl; - } -#endif + if (expert_idxs.size() == 2) { + auto end_infer = mllm_time_us(); + std::cout << "expert|| load time: " << (end_infer - start_infer) / 1000.0F << "ms" << std::endl; } +#endif + // } } private: @@ -245,10 +228,8 @@ class MiniCPMMoE final : public Module { } } void free_experts(vector expert_idxs) { - if (Tensor::tensor_status == TENSOR_STATIC_READY) { - for (int i = 0; i < expert_idxs.size(); ++i) { - experts[expert_idxs[i]].free(); - } + for (int i = 0; i < expert_idxs.size(); ++i) { + experts[expert_idxs[i]].free(); } } Tensor moe_infer(Tensor &hidden_states, Tensor &tokens_per_expert, Tensor &expert_weights, Tensor &idxs) { @@ -287,10 +268,8 @@ class MiniCPMMoE final : public Module { // expert_cache.view(ANYDIM, seq, -1, -1); } #ifdef MTIME - if (Tensor::tensor_status == TENSOR_STATIC_READY && hidden_states.sequence() == 1) { - auto end_infer = mllm_time_us(); - std::cout << "expert|| exe time: " << (end_infer - start_infer) / 1000.0F << "ms" << std::endl; - } + auto end_infer = mllm_time_us(); + std::cout << "expert|| exe time: " << (end_infer - start_infer) / 1000.0F << "ms" << std::endl; #endif return expert_cache; } @@ -306,10 +285,12 @@ class MiniCPMDecoder final : public Module { public: MiniCPMDecoder() = default; MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { - self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, names, base_name + names._attn_base_name); + true, false, + config.attn_implementation, names, base_name + names._attn_base_name); moe = MiniCPMMoE(config, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); @@ -389,7 +370,7 @@ class MiniCPMForCausalLM final : public Module { } std::vector Forward(std::vector inputs, std::vector args) override { std::vector outputs; - if (Tensor::tensor_status == TENSOR_STATIC_READY && inputs[0].sequence() == 1) { + if (inputs[0].dimension() == 1) { omp_set_max_active_levels(2); // Enable OpenMP nesting #pragma omp parallel num_threads(2) if (omp_get_thread_num() == 0) { // 根据线程ID决定执行哪个函数 diff --git a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp index 7739090b5..f2254cdf6 100644 --- a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp +++ b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp @@ -292,10 +292,12 @@ class MiniCPMDecoder final : public Module { public: MiniCPMDecoder() = default; MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { - self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, names, base_name + names._attn_base_name); + true, false, + config.attn_implementation, names, base_name + names._attn_base_name); moe = MiniCPMMoE(config, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); diff --git a/src/models/minicpm_moe/modeling_minicpm_moe.hpp b/src/models/minicpm_moe/modeling_minicpm_moe.hpp index 6ba25aa79..96b10f25a 100644 --- a/src/models/minicpm_moe/modeling_minicpm_moe.hpp +++ b/src/models/minicpm_moe/modeling_minicpm_moe.hpp @@ -106,10 +106,12 @@ class MiniCPMDecoder final : public Module { public: MiniCPMDecoder() = default; MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { - self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, names, base_name + names._attn_base_name); + true, false, + config.attn_implementation, names, base_name + names._attn_base_name); moe = MiniCPMMoE(config, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); diff --git a/src/models/mistral/modeling_mistral.hpp b/src/models/mistral/modeling_mistral.hpp index 37de46474..a04ae91ff 100644 --- a/src/models/mistral/modeling_mistral.hpp +++ b/src/models/mistral/modeling_mistral.hpp @@ -51,10 +51,12 @@ class MistralDecoder final : public Module { public: MistralDecoder() = default; MistralDecoder(const MistralConfig &config, const MistralNameConfig &names, const string &base_name) { - self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, names, base_name + names._attn_base_name); + true, false, + config.attn_implementation, names, base_name + names._attn_base_name); mlp = MistralMLP(config.hidden_size, config.intermediate_size, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); diff --git a/src/models/openelm/modeling_openelm.hpp b/src/models/openelm/modeling_openelm.hpp index 8700729d1..14904a7dd 100644 --- a/src/models/openelm/modeling_openelm.hpp +++ b/src/models/openelm/modeling_openelm.hpp @@ -51,6 +51,7 @@ class OpenELMMultiHeadCausalAttention final : public Module { Softmax softmax; int iter = 0; + string attn_impl; public: OpenELMMultiHeadCausalAttention() = default; @@ -60,6 +61,7 @@ class OpenELMMultiHeadCausalAttention final : public Module { q_heads_ = cfg.num_query_heads[layer_idx]; k_heads_ = cfg.num_kv_heads[layer_idx]; v_heads_ = cfg.num_kv_heads[layer_idx]; + attn_impl = cfg.attn_implementation; qkv_proj = Linear(cfg.model_dim, (q_heads_ + k_heads_ + v_heads_) * head_dim_, false, base_name + "qkv_proj"); q_rope = RoPE(cfg.RoPE_type, cfg.rope_freq_constant, cfg.rope_max_length, base_name + "q_rope"); @@ -70,8 +72,8 @@ class OpenELMMultiHeadCausalAttention final : public Module { out_proj = Linear(q_heads_ * head_dim_, cfg.model_dim, false, base_name + "out_proj"); - k_cache = KVCache(k_heads_, head_dim_, q_heads_ / k_heads_, cfg.cache_limit, base_name + "k_cache"); - v_cache = KVCache(v_heads_, head_dim_, q_heads_ / v_heads_, cfg.cache_limit, base_name + "v_cache"); + k_cache = KVCache(k_heads_, head_dim_, q_heads_ / k_heads_, cfg.cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(v_heads_, head_dim_, q_heads_ / v_heads_, cfg.cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } @@ -98,13 +100,16 @@ class OpenELMMultiHeadCausalAttention final : public Module { k = k_cache(k); v = v_cache(v); - k = k.transpose(SEQUENCE, DIMENSION); - auto qk = Tensor::mm(q, k); - - qk = qk / std::sqrt(head_dim_); - - qk = softmax(qk, k_cache.getCacheSeqLen()); - auto o = Tensor::mm(qk, v); + Tensor o; + if (attn_impl == "flash_attention_2") { + o = Tensor::flash_attention2_forward(q, k, v, true); + } else { // eager implementation + k = k.transpose(SEQUENCE, DIMENSION); + auto qk = Tensor::mm(q, k); + qk = qk / std::sqrt(head_dim_); + qk = softmax(qk, k_cache.getCacheSeqLen()); + o = Tensor::mm(qk, v); + } o = o.view(-1, 1, -1, q_heads_ * head_dim_); o = out_proj(o); diff --git a/src/models/opt/modeling_opt.hpp b/src/models/opt/modeling_opt.hpp index b40270924..ca1b5bbca 100644 --- a/src/models/opt/modeling_opt.hpp +++ b/src/models/opt/modeling_opt.hpp @@ -16,9 +16,13 @@ class OPTBlock final : public Module { public: OPTBlock() = default; - OPTBlock(int hidden_dim, int head_size, int ffn_hidden, int cache_limit, const optNameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, SPLIT_NONE, false, false, - NONE, -1, -1, cache_limit, true, true, names, base_name + names._attn_base_name); + OPTBlock(int hidden_dim, int head_size, int ffn_hidden, int cache_limit, + string attn_implementation, const optNameConfig &names, const string &base_name) { + attention = MultiHeadAttention(hidden_dim, head_size, head_size, + hidden_dim / head_size, SPLIT_NONE, false, false, + NONE, -1, -1, cache_limit, true, true, + attn_implementation, + names, base_name + names._attn_base_name); mlp = FeedForward(hidden_dim, ffn_hidden, "ReLU", true, names, base_name + names._ffn_base_name); norm1 = LayerNorm(hidden_dim, true, 1e-05, base_name + names._attn_norm_name); @@ -47,13 +51,18 @@ class OPTModel final : public Module { public: explicit OPTModel(const OPTConfig &config) : - OPTModel(config.vocab_size, config.hidden_dim, config.head_size, config.ffn_hidden, config.block_num, config.cache_limit, config.names_config, config.names_config.blk_name) { + OPTModel(config.vocab_size, config.hidden_dim, + config.head_size, config.ffn_hidden, config.block_num, config.cache_limit, + config.attn_implementation, + config.names_config, config.names_config.blk_name) { } - OPTModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, int cache_limit, const optNameConfig &names, const string &base_name) { + OPTModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, int cache_limit, + string attn_implementation, + const optNameConfig &names, const string &base_name) { embedding = Embedding(vocab_size, hidden_dim, names.token_embd_name); pos_embedding = Embedding(2050, hidden_dim, names.pos_name); pos = Position("pos"); - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, cache_limit, names, base_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, cache_limit, attn_implementation, names, base_name); norm = LayerNorm(hidden_dim, true, 1e-05, names.post_norm_name); lm_head = Linear(hidden_dim, vocab_size, false, names.lm_head_name); } diff --git a/src/models/phi3/modeling_phi3.hpp b/src/models/phi3/modeling_phi3.hpp index b88aaca46..c5a2719cc 100644 --- a/src/models/phi3/modeling_phi3.hpp +++ b/src/models/phi3/modeling_phi3.hpp @@ -45,9 +45,8 @@ class Phi3Block final : public Module { public: Phi3Block() = default; - Phi3Block(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, const Phi3NameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_HD, false, false, - RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, names, base_name + names._attn_base_name); + Phi3Block(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const Phi3NameConfig &names, const string &base_name) { + attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_HD, false, false, RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, attn_implementation, names, base_name + names._attn_base_name); mlp = Phi3MLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); norm2 = RMSNorm(hidden_dim, 1e-6, base_name + names._ffn_norm_name); @@ -76,13 +75,13 @@ class Phi3Model final : public Module { public: explicit Phi3Model(const Phi3Config &config) : Phi3Model(config.vocab_size, config.hidden_dim, config.head_size, config.num_key_value_heads, config.ffn_hidden, config.block_num, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, config.attn_implementation, config.names_config, config.names_config.blk_name) { } - Phi3Model(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, + Phi3Model(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const Phi3NameConfig &names, const string &base_name) { embedding = Embedding(vocab_size, hidden_dim, names.token_embd_name); - blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, names, base_name); + blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, attn_implementation, names, base_name); norm = RMSNorm(hidden_dim, 1e-6, names.post_norm_name); lm_head = Linear(hidden_dim, vocab_size, false, names.lm_head_name); } diff --git a/src/models/phi3v/modeling_phi3v.hpp b/src/models/phi3v/modeling_phi3v.hpp index 9efb8c22e..7502a9a9b 100644 --- a/src/models/phi3v/modeling_phi3v.hpp +++ b/src/models/phi3v/modeling_phi3v.hpp @@ -50,11 +50,12 @@ class Phi3VisionModel final : public Module { public: Phi3VisionModel() = default; Phi3VisionModel(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, int patch, int img_hw, int block_num, + string attn_implementation, const Phi3VNameConfig &names, const string &base_name) { embedding = Phi3VisionEmbedding(hidden_dim, patch, img_hw, names, base_name + names._embd_name); pre_layrnorm = LayerNorm(hidden_dim, true, 1e-5, base_name + names._vision_pre_layrnorm_name); clip_len_ = std::ceil(img_hw / patch) * std::ceil(img_hw / patch) + 1; - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, act_fn_type, names, base_name + names._layer_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, act_fn_type, attn_implementation, names, base_name + names._layer_name); } vector Forward(vector inputs, vector args) override { auto x = embedding(inputs)[0]; @@ -81,9 +82,9 @@ class Phi3Embedding final : public Module { public: Phi3Embedding() = default; - explicit Phi3Embedding(int vocab_size, int hidden_dim, int head_size, int ffn, int vision_hidden_dim, string &projection_cls, const Phi3VNameConfig &nameconfig, const string &base_name, const string &embd_name) { + explicit Phi3Embedding(int vocab_size, int hidden_dim, int head_size, int ffn, int vision_hidden_dim, string &projection_cls, const Phi3VNameConfig &nameconfig, string attn_implementation, const string &base_name, const string &embd_name) { embed_tokens = Embedding(vocab_size, hidden_dim, embd_name); - img_processor = Phi3VisionModel(vision_hidden_dim, 16, vision_hidden_dim * 4, "QuickGELU", 14, 336, 23, nameconfig, nameconfig.vison_model_name); + img_processor = Phi3VisionModel(vision_hidden_dim, 16, vision_hidden_dim * 4, "QuickGELU", 14, 336, 23, attn_implementation, nameconfig, nameconfig.vison_model_name); glb_GN = Parameter(1, 1, 1, vision_hidden_dim * 4, nameconfig._vision_model_prefix + nameconfig._glb_GN); sub_GN = Parameter(1, 1, 1, vision_hidden_dim * 4, nameconfig._vision_model_prefix + nameconfig._sub_GN); project_cls = projection_cls; @@ -150,15 +151,15 @@ class Phi3VModel final : public Module { public: explicit Phi3VModel(const Phi3VConfig &config) : - Phi3VModel(config.vocab_size, config.hidden_dim, config.head_size, config.num_key_value_heads, config.ffn_hidden, config.block_num, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, config.vision_hidden_dim, config.projection_cls, config.name_config, + Phi3VModel(config.vocab_size, config.hidden_dim, config.head_size, + config.num_key_value_heads, config.ffn_hidden, config.block_num, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, config.vision_hidden_dim, config.projection_cls, config.attn_implementation, config.name_config, config.names_config, config.names_config.blk_name) { } - Phi3VModel(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, int vision_hidden_dim, string projection_cls, const Phi3VNameConfig &visionconfig, - const Phi3NameConfig &names, const string &base_name) { + Phi3VModel(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, int vision_hidden_dim, string projection_cls, string attn_implementation, const Phi3VNameConfig &visionconfig, const Phi3NameConfig &names, const string &base_name) { norm = RMSNorm(hidden_dim, 1e-6, names.post_norm_name); - vision_embed_tokens = Phi3Embedding(vocab_size, hidden_dim, head_size, ffn_hidden, vision_hidden_dim, projection_cls, visionconfig, base_name, names.token_embd_name); - blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, names, base_name); + vision_embed_tokens = Phi3Embedding(vocab_size, hidden_dim, head_size, ffn_hidden, vision_hidden_dim, projection_cls, visionconfig, attn_implementation, base_name, names.token_embd_name); + blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, attn_implementation, names, base_name); norm = RMSNorm(hidden_dim, 1e-6, names.post_norm_name); lm_head = Linear(hidden_dim, vocab_size, false, names.lm_head_name); } diff --git a/src/models/phonelm/modeling_phonelm.hpp b/src/models/phonelm/modeling_phonelm.hpp index 31a8dfefa..ccb719a73 100644 --- a/src/models/phonelm/modeling_phonelm.hpp +++ b/src/models/phonelm/modeling_phonelm.hpp @@ -50,6 +50,7 @@ class PhoneLMAttention final : public Module { head_dim = config.hidden_size / num_heads; num_key_value_heads = config.num_key_value_heads; num_key_value_groups = num_heads / num_key_value_heads; + attn_impl = config.attn_implementation; // init layers q_proj = Linear(hidden_size, num_heads * head_dim, false, base_name + names._q_proj_name); @@ -62,8 +63,8 @@ class PhoneLMAttention final : public Module { base_name + "q_rope"); k_rope = IRoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "v_cache"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } @@ -84,15 +85,20 @@ class PhoneLMAttention final : public Module { k = k_cache(k); v = v_cache(v); } - k = k.transpose(SEQUENCE, DIMENSION); - auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(head_dim); - if (k_cache.ready() && v_cache.ready()) { - qk = softmax(qk, k_cache.getCacheSeqLen()); - } else { - qk = softmax(qk); + Tensor o; + if (attn_impl == "flash_attention_2") { + o = Tensor::flash_attention2_forward(q, k, v, true); + } else { // eager implementation + k = k.transpose(SEQUENCE, DIMENSION); + auto qk = Tensor::mm(q, k); + qk = qk / std::sqrt(head_dim); + if (k_cache.ready() && v_cache.ready()) { + qk = softmax(qk, k_cache.getCacheSeqLen()); + } else { + qk = softmax(qk); + } + auto o = Tensor::mm(qk, v); } - auto o = Tensor::mm(qk, v); o = o.view(-1, 1, -1, head_dim * num_heads); o = o_proj(o); return {o}; @@ -120,6 +126,7 @@ class PhoneLMAttention final : public Module { KVCache k_cache; KVCache v_cache; Softmax softmax; + string attn_impl; }; class PhoneLMDecoder final : public Module { diff --git a/src/models/phonelm/modeling_phonelm_npu.hpp b/src/models/phonelm/modeling_phonelm_npu.hpp index c13d0906f..e47f8b76b 100644 --- a/src/models/phonelm/modeling_phonelm_npu.hpp +++ b/src/models/phonelm/modeling_phonelm_npu.hpp @@ -10,8 +10,11 @@ using namespace mllm; +std::set phonelmShadowLayers = {0, 1, 3, 4}; + // NPU QKV part -class PhoneLMDecoderNPUPart1 final : public Module { +class PhoneLMDecoderNPUPart1 : public Module { +protected: int hidden_size; int num_heads; int head_dim; @@ -81,6 +84,64 @@ class PhoneLMDecoderNPUPart1 final : public Module { } }; +class PhoneLMDecoderNPUPart1WithRes final : public PhoneLMDecoderNPUPart1 { + Layer input_layernorm; + Layer pre_attn_quantize; + +public: + PhoneLMDecoderNPUPart1WithRes() = default; + + PhoneLMDecoderNPUPart1WithRes(const PhoneLMConfig &config, const PhoneLMNameConfig &names, int chunk_size, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + num_key_value_heads = config.num_key_value_heads; + num_key_value_groups = num_heads / num_key_value_heads; + + auto layer_base_name = base_name.substr(0, base_name.size() - 10); + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, layer_base_name + names._attn_norm_name); + pre_attn_quantize = Quantize(true, layer_base_name + names._attn_base_name + names._q_proj_name + ".quantize"); + + pre_attn_view = View(-1, 1, -1, num_heads * head_dim, base_name + "ires_split-00_view_"); + + q_proj = Linear(hidden_size, num_heads * head_dim, false, base_name + names._q_proj_name); + k_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._k_proj_name); + v_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._v_proj_name); + + q_view = View(-1, num_heads, -1, head_dim, base_name + names._q_proj_name + "-00_view_"); + k_view = View(-1, num_heads, -1, head_dim, base_name + names._k_proj_name + "-00_view_"); + v_view = View(-1, num_heads, -1, head_dim, base_name + names._v_proj_name + "-00_view_"); + + q_dequant = Dequantize(true, base_name + names._q_proj_name + ".dequantize"); + k_dequant = Dequantize(true, base_name + names._k_proj_name + ".dequantize", false); + v_dequant = Dequantize(true, base_name + names._v_proj_name + ".dequantize", false); + + v_transpose = Transpose({0, 2, 3, 1}, base_name + names._v_proj_name + ".transpose"); + } + + vector Forward(vector inputs, vector args) override { + auto x = input_layernorm(inputs[0]); + x = pre_attn_quantize(x); + + x = pre_attn_view(x); + + auto query_states = q_proj(x); + auto key_states = k_proj(x); + auto value_states = v_proj(x); + + query_states = q_view(query_states); + key_states = k_view(key_states); + value_states = v_view(value_states); + + query_states = q_dequant(query_states); + key_states = k_dequant(key_states); + value_states = v_dequant(value_states); + + value_states = v_transpose(value_states); + return {query_states, key_states, value_states, inputs[0]}; + } +}; + // CPU QKV MM part class PhoneLMQKVmm final : public Module { IRoPE q_rope; @@ -140,7 +201,8 @@ class PhoneLMQKVmm final : public Module { }; // QNN mlp part -class PhoneLMDecoderNPUPart2 final : public Module { +class PhoneLMDecoderNPUPart2 : public Module { +protected: int hidden_size; int num_heads; int head_dim; @@ -250,39 +312,7 @@ class PhoneLMDecoderNPUPart2 final : public Module { } }; -class PhoneLMDecoderNPUPart2WithShadow final : public Module { - int hidden_size; - int num_heads; - int head_dim; - int num_key_value_heads; - int num_key_value_groups; - int intermediate_size; - - // NPU part2 of attention - Layer pre_oproj_view; - Layer out_proj; - Layer post_oproj_view; - Layer post_oproj_dequantize; - - // NPU mlp - Layer pre_mlp_quantize; - Layer pre_mlp_view; - Layer gate_proj; - Layer up_proj; - Layer post_up_proj_dequantize; - Layer post_gate_proj_dequantize; - Layer relu; - Layer post_attn_layernorm; - - Layer down_proj; - Layer pre_down_proj_quantize; - Layer post_down_proj_dequantize; - Layer post_mlp_view; - - Layer post_atten_res_add; - Layer post_mlp_res_add; - Layer mlp_mul; - +class PhoneLMDecoderNPUPart2WithShadow final : public PhoneLMDecoderNPUPart2 { public: PhoneLMDecoderNPUPart2WithShadow() = default; @@ -370,11 +400,17 @@ class PhoneLMNPU_CPUDecoder final : public Module { int num_key_value_heads; int num_key_value_groups; + int layer_idx; + int num_layers; + + SubgraphStart _SubgraphStart_1, _SubgraphStart_2; + SubgraphFinalize _SubgraphEnd_1, _SubgraphEnd_2; + Layer input_layernorm; Layer pre_attn_quantize; - PhoneLMDecoderNPUPart1 part1; + unique_ptr part1; PhoneLMQKVmm qkv_mm; - PhoneLMDecoderNPUPart2 part2; + unique_ptr part2; public: PhoneLMNPU_CPUDecoder() = default; @@ -386,39 +422,65 @@ class PhoneLMNPU_CPUDecoder final : public Module { num_key_value_heads = config.num_key_value_heads; num_key_value_groups = num_heads / num_key_value_heads; - input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); - pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize"); - - part1 = PhoneLMDecoderNPUPart1(config, names, chunk_size, base_name + names._attn_base_name); - part1.to(MLLM_QNN); + // extract layer index from base_name like "model.layers.10." + std::regex re(R"(\d+)"); + std::smatch match; + std::regex_search(base_name, match, re); + layer_idx = std::stoi(match[0]); + num_layers = config.num_hidden_layers; + + if (layer_idx == 0 || phonelmShadowLayers.find(layer_idx - 1) != phonelmShadowLayers.end()) { + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize"); + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } else { + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } qkv_mm = PhoneLMQKVmm(config, names, chunk_size, base_name + names._attn_base_name); - qkv_mm.to(MLLM_CPU); - part2 = PhoneLMDecoderNPUPart2(config, names, chunk_size, base_name); - part2.to(MLLM_QNN); + part2 = make_unique(config, names, chunk_size, base_name); + + _SubgraphStart_1 = SubgraphStart(base_name + "subgraph_start1"); + _SubgraphEnd_1 = SubgraphFinalize(base_name + "subgraph_end1"); + _SubgraphStart_2 = SubgraphStart(base_name + "subgraph_start2"); + _SubgraphEnd_2 = SubgraphFinalize(base_name + "subgraph_end2"); } vector Forward(vector inputs, vector args) override { - auto x = input_layernorm(inputs[0]); - x = pre_attn_quantize(x); - - if (x.device() != MLLM_QNN) { - x = Tensor::toQNN({x})[0]; + Tensor x, q, k, v, res; + if (layer_idx == 0 || phonelmShadowLayers.find(layer_idx - 1) != phonelmShadowLayers.end()) { + x = input_layernorm(inputs[0]); + x = pre_attn_quantize(x); + + _SubgraphStart_1({x}); + + auto q_k_v = (*part1)({x}); // q,k,v + q = q_k_v[0]; + k = q_k_v[1]; + v = q_k_v[2]; + res = inputs[0]; + _SubgraphEnd_1(q_k_v); + } else { + auto q_k_v_res = (*part1)(inputs); // q,k,v,res + q = q_k_v_res[0]; + k = q_k_v_res[1]; + v = q_k_v_res[2]; + res = q_k_v_res[3]; + _SubgraphEnd_1(q_k_v_res); } - auto q_k_v = part1({x}); // q,k,v - auto o_x = qkv_mm(q_k_v)[0]; + auto o_x = qkv_mm({q, k, v})[0]; - if (o_x.device() != MLLM_QNN) { - o_x = Tensor::toQNN({o_x})[0]; - } - if (inputs[0].device() != MLLM_QNN) { - inputs[0] = Tensor::toQNN({inputs[0]})[0]; + _SubgraphStart_2({o_x, res}); + + auto out_part2 = (*part2)({o_x, res}); + + if (layer_idx == num_layers - 1) { + _SubgraphEnd_2(out_part2); } - x = part2({o_x, inputs[0]})[0]; - return {x}; + return out_part2; } }; @@ -432,9 +494,15 @@ class PhoneLMNPU_CPUDecoderWithShadow final : public Module { Layer input_layernorm; Layer pre_attn_quantize; Layer shadow_linear; - PhoneLMDecoderNPUPart1 part1; + unique_ptr part1; PhoneLMQKVmm qkv_mm; - PhoneLMDecoderNPUPart2WithShadow part2; + unique_ptr part2; + + int layer_idx; + int num_layers; + + SubgraphStart _SubgraphStart_1, _SubgraphStart_2; + SubgraphFinalize _SubgraphEnd_1, _SubgraphEnd_2; public: PhoneLMNPU_CPUDecoderWithShadow() = default; @@ -446,45 +514,69 @@ class PhoneLMNPU_CPUDecoderWithShadow final : public Module { num_key_value_heads = config.num_key_value_heads; num_key_value_groups = num_heads / num_key_value_heads; - input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); - pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize"); - - part1 = PhoneLMDecoderNPUPart1(config, names, chunk_size, base_name + names._attn_base_name); - part1.to(MLLM_QNN); + // extract layer index from base_name like "model.layers.10." + std::regex re(R"(\d+)"); + std::smatch match; + std::regex_search(base_name, match, re); + layer_idx = std::stoi(match[0]); + num_layers = config.num_hidden_layers; + + if (layer_idx == 0 || phonelmShadowLayers.find(layer_idx - 1) != phonelmShadowLayers.end()) { + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize"); + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } else { + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } qkv_mm = PhoneLMQKVmm(config, names, chunk_size, base_name + names._attn_base_name); - qkv_mm.to(MLLM_CPU); - part2 = PhoneLMDecoderNPUPart2WithShadow(config, names, chunk_size, base_name); - part2.to(MLLM_QNN); + part2 = make_unique(config, names, chunk_size, base_name); shadow_linear = ShadowLinear(config.intermediate_size, hidden_size, 1024, false, base_name + names._ffn_base_name + names._down_proj_name + ".shadow"); + + _SubgraphStart_1 = SubgraphStart(base_name + "subgraph_start1"); + _SubgraphEnd_1 = SubgraphFinalize(base_name + "subgraph_end1"); + _SubgraphStart_2 = SubgraphStart(base_name + "subgraph_start2"); + _SubgraphEnd_2 = SubgraphFinalize(base_name + "subgraph_end2"); } vector Forward(vector inputs, vector args) override { - auto x = input_layernorm(inputs[0]); - x = pre_attn_quantize(x); - - if (x.device() != MLLM_QNN) { - x = Tensor::toQNN({x})[0]; + Tensor x, q, k, v, res; + if (layer_idx == 0 || phonelmShadowLayers.find(layer_idx - 1) != phonelmShadowLayers.end()) { + x = input_layernorm(inputs[0]); + x = pre_attn_quantize(x); + + _SubgraphStart_1({x}); + + auto q_k_v = (*part1)({x}); // q,k,v + q = q_k_v[0]; + k = q_k_v[1]; + v = q_k_v[2]; + res = inputs[0]; + _SubgraphEnd_1(q_k_v); + } else { + auto q_k_v_res = (*part1)(inputs); // q,k,v,res + q = q_k_v_res[0]; + k = q_k_v_res[1]; + v = q_k_v_res[2]; + res = q_k_v_res[3]; + _SubgraphEnd_1(q_k_v_res); } - auto q_k_v = part1({x}); // q,k,v - auto o_x = qkv_mm(q_k_v)[0]; + auto o_x = qkv_mm({q, k, v})[0]; + + _SubgraphStart_2({o_x, res}); + + auto decoder_out = (*part2)({o_x, res}); + decoder_out = Tensor::toCPU(decoder_out); + + _SubgraphEnd_2(decoder_out); - if (o_x.device() != MLLM_QNN) { - o_x = Tensor::toQNN({o_x})[0]; - } - if (inputs[0].device() != MLLM_QNN) { - inputs[0] = Tensor::toQNN({inputs[0]})[0]; - } - auto decoder_out = part2({o_x, inputs[0]}); - if (decoder_out[0].device() != MLLM_CPU) { - decoder_out = Tensor::toCPU(decoder_out); - } auto shadow_input_1 = decoder_out[0]; auto shadow_input_2 = decoder_out[1]; x = decoder_out[2]; + x = shadow_linear(shadow_input_1, shadow_input_2, x); return {x}; @@ -499,11 +591,10 @@ class PhoneLMModel_NPU final : public Module { static_assert(std::is_base_of::value, "SHADOW must be a subclass of Module"); listIdx = 0; vector> modules; - std::set shadowLayers = {0, 1, 3, 4}; - // for index in shadowLayers, create shadow decoder, for others, create normal decoder + // for index in phonelmShadowLayers, create shadow decoder, for others, create normal decoder for (int i = 0; i < n; i++) { auto new_args = change_last(args...); // 创建新的参数包,最后一个参数被修改为原来的值+ std::to_string(listIdx)+ "." - if (shadowLayers.find(listIdx) != shadowLayers.end()) { + if (phonelmShadowLayers.find(listIdx) != phonelmShadowLayers.end()) { modules.push_back(std::make_unique(std::apply([&](auto &&...args) { return SHADOW(std::forward(args)...); }, new_args))); } else { modules.push_back(std::make_unique(std::apply([&](auto &&...args) { return T1(std::forward(args)...); }, new_args))); diff --git a/src/models/qwen/configuration_qwen.hpp b/src/models/qwen/configuration_qwen.hpp index 446984385..686b48b46 100644 --- a/src/models/qwen/configuration_qwen.hpp +++ b/src/models/qwen/configuration_qwen.hpp @@ -131,6 +131,36 @@ struct QWenConfig : public TransformerConfig { sliding_window = 32768; vocab_size = 151936; tie_embedding_words = true; + } else if (billionsType == "1.5b-rotated") { + attention_dropout = 0.0; + std::string hidden_act = "silu"; + hidden_size = 1536; + intermediate_size = 8960; + max_position_embeddings = 32768; + max_window_layers = 28; + num_attention_heads = 12; + num_hidden_layers = 28; + num_key_value_heads = 2; + rms_norm_eps = 1e-6; + rope_theta = 1000000.0; + sliding_window = 32768; + vocab_size = 151936; + tie_embedding_words = false; + } else if (billionsType == "3b") { + attention_dropout = 0.0; + std::string hidden_act = "silu"; + hidden_size = 2048; + intermediate_size = 11008; + max_position_embeddings = 32768; + max_window_layers = 70; + num_attention_heads = 16; + num_hidden_layers = 36; + num_key_value_heads = 2; + rms_norm_eps = 1e-6; + rope_theta = 1000000.0; + sliding_window = 32768; + vocab_size = 151936; + tie_embedding_words = true; } else if (billionsType == "3b") { attention_dropout = 0.0; std::string hidden_act = "silu"; diff --git a/src/models/qwen/modeling_qwen.hpp b/src/models/qwen/modeling_qwen.hpp index e73c50a8c..90bdfefc8 100644 --- a/src/models/qwen/modeling_qwen.hpp +++ b/src/models/qwen/modeling_qwen.hpp @@ -61,7 +61,7 @@ class QWenAttention final : public Module { head_dim = config.hidden_size / num_heads; num_key_value_heads = config.num_key_value_heads; num_key_value_groups = num_heads / num_key_value_heads; - + attn_impl = config.attn_implementation; // init layers q_proj = Linear(hidden_size, num_heads * head_dim, true, base_name + names._q_proj_name); k_proj = Linear(hidden_size, num_key_value_heads * head_dim, true, @@ -73,10 +73,8 @@ class QWenAttention final : public Module { base_name + "q_rope"); k_rope = RoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "v_cache"); - // mask = SlidingWindowMask(config.sliding_window, base_name + "mask"); - // mask = Causalmask(base_name + "mask"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } @@ -98,15 +96,19 @@ class QWenAttention final : public Module { key_states = k_cache(key_states); value_states = v_cache(value_states); - // attention weight - auto atten_weight = - Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) - / std::sqrt(head_dim); - // atten_weight = mask(atten_weight, k_cache.getCacheSeqLen()); - atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); + Tensor atten_output; + if (attn_impl == "flash_attention_2") { + atten_output = Tensor::flash_attention2_forward(query_states, key_states, value_states, true); + } else { // eager implementation + auto atten_weight = + Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) + / std::sqrt(head_dim); + // atten_weight = mask(atten_weight, k_cache.getCacheSeqLen()); + atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); + auto atten_output = Tensor::mm(atten_weight, value_states); + } // attention output - auto atten_output = Tensor::mm(atten_weight, value_states); atten_output = atten_output.view(-1, 1, -1, head_dim * num_heads); atten_output = o_proj(atten_output); return {atten_output}; @@ -135,6 +137,7 @@ class QWenAttention final : public Module { KVCache v_cache; // Causalmask mask; Softmax softmax; + string attn_impl; }; // Copied from GemmaDecoder with Gemma->Qwen and set RmsNorm(without add_unit_offset) diff --git a/src/models/qwen/modeling_qwen_npu.hpp b/src/models/qwen/modeling_qwen_npu.hpp index 30ae8e1a3..e14dabaa9 100644 --- a/src/models/qwen/modeling_qwen_npu.hpp +++ b/src/models/qwen/modeling_qwen_npu.hpp @@ -1,5 +1,5 @@ -#ifndef MODELING_QWENNPU_HPP -#define MODELING_QWENNPU_HPP +#ifndef MODELING_QWENNPU_V2_HPP +#define MODELING_QWENNPU_V2_HPP #include "Backend.hpp" #include "Layer.hpp" @@ -7,11 +7,18 @@ #include "Tensor.hpp" #include "Types.hpp" #include "configuration_qwen.hpp" +#include using namespace mllm; +namespace v2 { + +// a 'just working' try +std::set shadowLayers = {1, 2, 4, 5, 26}; + // NPU QKV part -class QwenDecoderNPUPart1 final : public Module { +class QwenDecoderNPUPart1 : public Module { +protected: int hidden_size; int num_heads; int head_dim; @@ -45,17 +52,17 @@ class QwenDecoderNPUPart1 final : public Module { pre_attn_view = View(-1, 1, -1, num_heads * head_dim, base_name + "ires_split-00_view_"); - q_proj = Linear(hidden_size, num_heads * head_dim, true, base_name + names._q_proj_name); - k_proj = Linear(hidden_size, num_key_value_heads * head_dim, true, base_name + names._k_proj_name); - v_proj = Linear(hidden_size, num_key_value_heads * head_dim, true, base_name + names._v_proj_name); + q_proj = Linear(hidden_size, num_heads * head_dim, false, base_name + names._q_proj_name); + k_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._k_proj_name); + v_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._v_proj_name); q_view = View(-1, num_heads, -1, head_dim, base_name + names._q_proj_name + "-00_view_"); k_view = View(-1, num_key_value_heads, -1, head_dim, base_name + names._k_proj_name + "-00_view_"); v_view = View(-1, num_key_value_heads, -1, head_dim, base_name + names._v_proj_name + "-00_view_"); - q_dequant = Dequantize(true, base_name + names._q_proj_name + ".dequantize"); - k_dequant = Dequantize(true, base_name + names._k_proj_name + ".dequantize", false); - v_dequant = Dequantize(true, base_name + names._v_proj_name + ".dequantize", false); + q_dequant = Dequantize(true, base_name + names._q_proj_name + ".dequantize", true, MLLM_TYPE_I16); + k_dequant = Dequantize(true, base_name + names._k_proj_name + ".dequantize", false, MLLM_TYPE_I16); + v_dequant = Dequantize(true, base_name + names._v_proj_name + ".dequantize", false, MLLM_TYPE_I16); v_transpose = Transpose({0, 2, 3, 1}, base_name + names._v_proj_name + ".transpose"); } @@ -80,6 +87,64 @@ class QwenDecoderNPUPart1 final : public Module { } }; +class QwenDecoderNPUPart1WithRes final : public QwenDecoderNPUPart1 { + Layer input_layernorm; + Layer pre_attn_quantize; + +public: + QwenDecoderNPUPart1WithRes() = default; + QwenDecoderNPUPart1WithRes(const QWenConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + num_key_value_heads = config.num_key_value_heads; + num_key_value_groups = num_heads / num_key_value_heads; + + // remove "self_attn." in base_name + auto layer_base_name = base_name.substr(0, base_name.size() - 10); + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, layer_base_name + names._attn_norm_name); + pre_attn_quantize = Quantize(true, layer_base_name + names._attn_base_name + names._q_proj_name + ".quantize", MLLM_TYPE_I16); + + pre_attn_view = View(-1, 1, -1, num_heads * head_dim, base_name + "ires_split-00_view_"); + + q_proj = Linear(hidden_size, num_heads * head_dim, false, base_name + names._q_proj_name); + k_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._k_proj_name); + v_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._v_proj_name); + + q_view = View(-1, num_heads, -1, head_dim, base_name + names._q_proj_name + "-00_view_"); + k_view = View(-1, num_key_value_heads, -1, head_dim, base_name + names._k_proj_name + "-00_view_"); + v_view = View(-1, num_key_value_heads, -1, head_dim, base_name + names._v_proj_name + "-00_view_"); + + q_dequant = Dequantize(true, base_name + names._q_proj_name + ".dequantize", true, MLLM_TYPE_I16); + k_dequant = Dequantize(true, base_name + names._k_proj_name + ".dequantize", false, MLLM_TYPE_I16); + v_dequant = Dequantize(true, base_name + names._v_proj_name + ".dequantize", false, MLLM_TYPE_I16); + + v_transpose = Transpose({0, 2, 3, 1}, base_name + names._v_proj_name + ".transpose"); + } + + vector Forward(vector inputs, vector args) override { + auto x = input_layernorm(inputs[0]); + x = pre_attn_quantize(x); + + x = pre_attn_view(x); + + auto query_states = q_proj(x); + auto key_states = k_proj(x); + auto value_states = v_proj(x); + + query_states = q_view(query_states); + key_states = k_view(key_states); + value_states = v_view(value_states); + + query_states = q_dequant(query_states); + key_states = k_dequant(key_states); + value_states = v_dequant(value_states); + + value_states = v_transpose(value_states); + return {query_states, key_states, value_states, inputs[0]}; + } +}; + // CPU QKV MM part class QwenQKVmm final : public Module { RoPE q_rope; @@ -99,6 +164,8 @@ class QwenQKVmm final : public Module { QwenQKVmm() = default; QwenQKVmm(const QWenConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; num_heads = config.num_attention_heads * config.hidden_size / config.num_attention_heads; q_rope = RoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, base_name + "q_rope"); @@ -107,6 +174,9 @@ class QwenQKVmm final : public Module { k_cache = KVCache(config.num_attention_heads / config.num_key_value_heads, config.cache_limit, base_name + "k_cache", true); v_cache = KVCache(config.num_attention_heads / config.num_key_value_heads, config.cache_limit, base_name + "v_cache", true); + // k_cache = KVCache(config.num_key_value_heads, head_dim, config.num_attention_heads / config.num_key_value_heads, config.cache_limit, base_name + "k_cache", true); + // v_cache = KVCache(config.num_key_value_heads, head_dim, config.num_attention_heads / config.num_key_value_heads, config.cache_limit, base_name + "v_cache", true); + softmax = Softmax(DIMENSION, true, base_name + "softmax"); o_quantize = Quantize(true, base_name + names._o_proj_name + ".quantize"); @@ -134,7 +204,8 @@ class QwenQKVmm final : public Module { }; // QNN mlp part -class QwenDecoderNPUPart2 final : public Module { +class QwenDecoderNPUPart2 : public Module { +protected: int hidden_size; int num_heads; int head_dim; @@ -243,39 +314,7 @@ class QwenDecoderNPUPart2 final : public Module { } }; -class QwenDecoderNPUPart2WithShadow final : public Module { - int hidden_size; - int num_heads; - int head_dim; - int num_key_value_heads; - int num_key_value_groups; - int intermediate_size; - - // NPU part2 of attention - Layer pre_oproj_view; - Layer out_proj; - Layer post_oproj_view; - Layer post_oproj_dequantize; - - // NPU mlp - Layer pre_mlp_quantize; - Layer pre_mlp_view; - Layer gate_proj; - Layer up_proj; - Layer post_up_proj_dequantize; - Layer post_gate_proj_dequantize; - Layer silu; - Layer post_attn_layernorm; - - Layer down_proj; - Layer pre_down_proj_quantize; - Layer post_down_proj_dequantize; - Layer post_mlp_view; - - Layer post_atten_res_add; - Layer post_mlp_res_add; - Layer mlp_mul; - +class QwenDecoderNPUPart2WithShadow final : public QwenDecoderNPUPart2 { public: QwenDecoderNPUPart2WithShadow() = default; QwenDecoderNPUPart2WithShadow(const QWenConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { @@ -351,6 +390,7 @@ class QwenDecoderNPUPart2WithShadow final : public Module { gate_out = post_mlp_view(gate_out); gate_out = post_mlp_res_add(gate_out, tmp); + return {shadow_input_1, shadow_input_2, gate_out}; } }; @@ -362,11 +402,17 @@ class QwenNPU_CPUDecoder final : public Module { int num_key_value_heads; int num_key_value_groups; + int layer_idx; + int num_layers; + + SubgraphStart _SubgraphStart_1, _SubgraphStart_2; + SubgraphFinalize _SubgraphEnd_1, _SubgraphEnd_2; + Layer input_layernorm; Layer pre_attn_quantize; - QwenDecoderNPUPart1 part1; + unique_ptr part1; QwenQKVmm qkv_mm; - QwenDecoderNPUPart2 part2; + unique_ptr part2; public: QwenNPU_CPUDecoder() = default; @@ -377,36 +423,65 @@ class QwenNPU_CPUDecoder final : public Module { num_key_value_heads = config.num_key_value_heads; num_key_value_groups = num_heads / num_key_value_heads; - input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); - pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize"); - - part1 = QwenDecoderNPUPart1(config, names, chunk_size, base_name + names._attn_base_name); - part1.to(MLLM_QNN); + // extract layer index from base_name like "model.layers.10." + std::regex re(R"(\d+)"); + std::smatch match; + std::regex_search(base_name, match, re); + layer_idx = std::stoi(match[0]); + num_layers = config.num_hidden_layers; + + if (layer_idx == 0 || shadowLayers.find(layer_idx - 1) != shadowLayers.end()) { + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize", MLLM_TYPE_I16); + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } else { + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } qkv_mm = QwenQKVmm(config, names, chunk_size, base_name + names._attn_base_name); - qkv_mm.to(MLLM_CPU); - part2 = QwenDecoderNPUPart2(config, names, chunk_size, base_name); - part2.to(MLLM_QNN); + part2 = make_unique(config, names, chunk_size, base_name); + + _SubgraphStart_1 = SubgraphStart(base_name + "subgraph_start1"); + _SubgraphEnd_1 = SubgraphFinalize(base_name + "subgraph_end1"); + _SubgraphStart_2 = SubgraphStart(base_name + "subgraph_start2"); + _SubgraphEnd_2 = SubgraphFinalize(base_name + "subgraph_end2"); } vector Forward(vector inputs, vector args) override { - auto x = input_layernorm(inputs[0]); - x = pre_attn_quantize(x); + Tensor x, q, k, v, res; + if (layer_idx == 0 || shadowLayers.find(layer_idx - 1) != shadowLayers.end()) { + x = input_layernorm(inputs[0]); + x = pre_attn_quantize(x); + + _SubgraphStart_1({x}); + + auto q_k_v = (*part1)({x}); // q,k,v + q = q_k_v[0]; + k = q_k_v[1]; + v = q_k_v[2]; + res = inputs[0]; + _SubgraphEnd_1(q_k_v); + } else { + auto q_k_v_res = (*part1)(inputs); // q,k,v,res + q = q_k_v_res[0]; + k = q_k_v_res[1]; + v = q_k_v_res[2]; + res = q_k_v_res[3]; + _SubgraphEnd_1(q_k_v_res); + } - x = Tensor::toQNN({x})[0]; - auto q_k_v = part1({x}); // q,k,v - q_k_v = Tensor::toCPU(q_k_v); + auto o_x = qkv_mm({q, k, v})[0]; - auto o_x = qkv_mm(q_k_v)[0]; + _SubgraphStart_2({o_x, res}); - auto qnn_tensor = Tensor::toQNN({o_x, inputs[0]}); - o_x = qnn_tensor[0]; - inputs[0] = qnn_tensor[1]; - x = part2({o_x, inputs[0]})[0]; - x = Tensor::toCPU({x})[0]; + auto out_part2 = (*part2)({o_x, res}); - return {x}; + if (layer_idx == num_layers - 1) { + _SubgraphEnd_2(out_part2); + } + + return out_part2; } }; @@ -420,9 +495,15 @@ class QwenNPU_CPUDecoderWithShadow final : public Module { Layer input_layernorm; Layer pre_attn_quantize; Layer shadow_linear; - QwenDecoderNPUPart1 part1; + unique_ptr part1; QwenQKVmm qkv_mm; - QwenDecoderNPUPart2WithShadow part2; + unique_ptr part2; + + int layer_idx; + int num_layers; + + SubgraphStart _SubgraphStart_1, _SubgraphStart_2; + SubgraphFinalize _SubgraphEnd_1, _SubgraphEnd_2; public: QwenNPU_CPUDecoderWithShadow() = default; @@ -433,40 +514,69 @@ class QwenNPU_CPUDecoderWithShadow final : public Module { num_key_value_heads = config.num_key_value_heads; num_key_value_groups = num_heads / num_key_value_heads; - input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); - pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize"); - - part1 = QwenDecoderNPUPart1(config, names, chunk_size, base_name + names._attn_base_name); - part1.to(MLLM_QNN); + // extract layer index from base_name like "model.layers.10." + std::regex re(R"(\d+)"); + std::smatch match; + std::regex_search(base_name, match, re); + layer_idx = std::stoi(match[0]); + num_layers = config.num_hidden_layers; + + if (layer_idx == 0 || shadowLayers.find(layer_idx - 1) != shadowLayers.end()) { + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize", MLLM_TYPE_I16); + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } else { + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } qkv_mm = QwenQKVmm(config, names, chunk_size, base_name + names._attn_base_name); - qkv_mm.to(MLLM_CPU); - part2 = QwenDecoderNPUPart2WithShadow(config, names, chunk_size, base_name); - part2.to(MLLM_QNN); + part2 = make_unique(config, names, chunk_size, base_name); shadow_linear = ShadowLinear(config.intermediate_size, hidden_size, 1024, false, base_name + names._ffn_base_name + names._down_proj_name + ".shadow"); + + _SubgraphStart_1 = SubgraphStart(base_name + "subgraph_start1"); + _SubgraphEnd_1 = SubgraphFinalize(base_name + "subgraph_end1"); + _SubgraphStart_2 = SubgraphStart(base_name + "subgraph_start2"); + _SubgraphEnd_2 = SubgraphFinalize(base_name + "subgraph_end2"); } vector Forward(vector inputs, vector args) override { - auto x = input_layernorm(inputs[0]); - x = pre_attn_quantize(x); + Tensor x, q, k, v, res; + if (layer_idx == 0 || shadowLayers.find(layer_idx - 1) != shadowLayers.end()) { + x = input_layernorm(inputs[0]); + x = pre_attn_quantize(x); + + _SubgraphStart_1({x}); + + auto q_k_v = (*part1)({x}); // q,k,v + q = q_k_v[0]; + k = q_k_v[1]; + v = q_k_v[2]; + res = inputs[0]; + _SubgraphEnd_1(q_k_v); + } else { + auto q_k_v_res = (*part1)(inputs); // q,k,v,res + q = q_k_v_res[0]; + k = q_k_v_res[1]; + v = q_k_v_res[2]; + res = q_k_v_res[3]; + _SubgraphEnd_1(q_k_v_res); + } - x = Tensor::toQNN({x})[0]; - auto q_k_v = part1({x}); // q,k,v - q_k_v = Tensor::toCPU(q_k_v); + auto o_x = qkv_mm({q, k, v})[0]; - auto o_x = qkv_mm(q_k_v)[0]; + _SubgraphStart_2({o_x, res}); - auto qnn_tensor = Tensor::toQNN({o_x, inputs[0]}); - o_x = qnn_tensor[0]; - inputs[0] = qnn_tensor[1]; - auto decoder_out = part2({o_x, inputs[0]}); + auto decoder_out = (*part2)({o_x, res}); decoder_out = Tensor::toCPU(decoder_out); + _SubgraphEnd_2(decoder_out); + auto shadow_input_1 = decoder_out[0]; auto shadow_input_2 = decoder_out[1]; x = decoder_out[2]; + x = shadow_linear(shadow_input_1, shadow_input_2, x); return {x}; @@ -481,7 +591,7 @@ class QWenModel_NPU final : public Module { static_assert(std::is_base_of::value, "SHADOW must be a subclass of Module"); listIdx = 0; vector> modules; - std::set shadowLayers = {1, 2, 26}; + // for index in shadowLayers, create shadow decoder, for others, create normal decoder for (int i = 0; i < n; i++) { auto new_args = change_last(args...); // 创建新的参数包,最后一个参数被修改为原来的值+ std::to_string(listIdx)+ "." @@ -500,7 +610,7 @@ class QWenModel_NPU final : public Module { QWenModel_NPU() = default; QWenModel_NPU(const QWenConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { // blocks = List(1, config, names, base_name); - blocks = ListWithShadow(24, config, names, chunk_size, base_name); + blocks = ListWithShadow(config.num_hidden_layers, config, names, chunk_size, base_name); norm = RMSNorm(config.hidden_size, config.rms_norm_eps, names.post_norm_name); } @@ -593,5 +703,6 @@ class QWenForCausalLM_NPU final : public Module { Layer lm_head_layer; QWenModel_NPU model; }; +} // namespace v2 -#endif //! MODELING_QWENNPU_HPP chunk_size, \ No newline at end of file +#endif //! MODELING_QWENNPU_V2_HPP chunk_size, \ No newline at end of file diff --git a/src/models/qwen2_vl/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/modeling_qwen2_vl.hpp index bee84ccae..793b4a118 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl.hpp @@ -40,14 +40,16 @@ class VisionAttention final : public Module { int head_size_{}; int kv_head_size_{}; int attn_hidden_dim_{}; + string attn_impl; public: VisionAttention() = default; - VisionAttention(int hidden_dim, int head_size, int kv_head_size, int attn_hidden_dim, bool bias, + VisionAttention(int hidden_dim, int head_size, int kv_head_size, int attn_hidden_dim, bool bias, string attn_implementation, const TransformerNameConfig &names, const string &base_name) { attn_hidden_dim_ = attn_hidden_dim; head_size_ = head_size; kv_head_size_ = kv_head_size; + attn_impl = attn_implementation; qkv_proj = Linear(hidden_dim, head_size * attn_hidden_dim * 3, bias, base_name + names._qkv_proj_name); softmax = Softmax(DIMENSION, false, base_name + "softmax"); @@ -59,7 +61,6 @@ class VisionAttention final : public Module { auto seq_length = inputs[0].sequence(); Tensor q, k, v; auto qkv = qkv_proj(inputs[0]); - // auto qkv_sp = qkv.split({attn_hidden_dim_, attn_hidden_dim_, attn_hidden_dim_}, HD, head_size_); auto qkv_sp = qkv.split({attn_hidden_dim_ * head_size_, attn_hidden_dim_ * head_size_, attn_hidden_dim_ * head_size_}, DIMENSION); q = qkv_sp[0]; k = qkv_sp[1]; @@ -69,12 +70,17 @@ class VisionAttention final : public Module { v = v.view(-1, head_size_, -1, attn_hidden_dim_); q = Tensor::apply_rotary_pos_emb_vision(q, rotary_pos_emb); k = Tensor::apply_rotary_pos_emb_vision(k, rotary_pos_emb); - k = k.transpose(SEQUENCE, DIMENSION); - auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(attn_hidden_dim_); - // mask - qk = softmax(qk); - auto o = Tensor::mm(qk, v); + Tensor o; + if (attn_impl == "flash_attention_2") { + o = Tensor::flash_attention2_forward(q, k, v, false); + } else { // eager implementation + k = k.transpose(SEQUENCE, DIMENSION); + auto qk = Tensor::mm(q, k); + qk = qk / std::sqrt(attn_hidden_dim_); + // mask + qk = softmax(qk); + o = Tensor::mm(qk, v); + } o = o.view(-1, 1, -1, attn_hidden_dim_ * head_size_); o = o_proj(o); return {o}; @@ -109,8 +115,8 @@ class VisionBlock final : public Module { public: VisionBlock() = default; - VisionBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, const ViTNameConfig &names, const string &base_name) { - attention = VisionAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, true, names, base_name + names._attn_base_name); + VisionBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, string attn_implementation, const ViTNameConfig &names, const string &base_name) { + attention = VisionAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, true, attn_implementation, names, base_name + names._attn_base_name); mlp = VisionMLP(hidden_dim, ffn_hidden, act_fn_type, names, base_name + names._ffn_base_name); norm1 = LayerNorm(hidden_dim, true, 1e-6, base_name + names._attn_norm_name); norm2 = LayerNorm(hidden_dim, true, 1e-6, base_name + names._ffn_norm_name); @@ -160,10 +166,10 @@ class Qwen2VisionModel final : public Module { public: Qwen2VisionModel() = default; - Qwen2VisionModel(int hidden_dim, int vision_embed_dim, int head_size, int mlp_hidden_dim, const string &act_fn_type, int patch, int img_hw, int block_num, int spatial_merge_size, const Qwen2VLNameConfig &names, const string &base_name) { + Qwen2VisionModel(int hidden_dim, int vision_embed_dim, int head_size, int mlp_hidden_dim, const string &act_fn_type, int patch, int img_hw, int block_num, int spatial_merge_size, string attn_implementation, const Qwen2VLNameConfig &names, const string &base_name) { patch_embed = Qwen2PatchEmbed(vision_embed_dim, patch, img_hw, names, base_name + names.patch_embed_name); rot_pos_emb = VisionRoPE((vision_embed_dim / head_size) / 2, spatial_merge_size, base_name + ".rot_pos_emb"); - blocks = List(block_num, vision_embed_dim, head_size, mlp_hidden_dim, act_fn_type, names, base_name + names._layer_name); + blocks = List(block_num, vision_embed_dim, head_size, mlp_hidden_dim, act_fn_type, attn_implementation, names, base_name + names._layer_name); patch_merger = PatchMerger(hidden_dim, vision_embed_dim, spatial_merge_size, names, base_name + names._merger_name); } vector Forward(vector inputs, vector args) override { @@ -219,6 +225,8 @@ class QWen2Attention final : public Module { head_dim = config.hidden_size / num_heads; num_key_value_heads = config.num_key_value_heads; num_key_value_groups = num_heads / num_key_value_heads; + name = base_name; + attn_impl = config.attn_implementation; // init layers q_proj = Linear(hidden_size, num_heads * head_dim, true, base_name + names._q_proj_name); @@ -229,14 +237,13 @@ class QWen2Attention final : public Module { o_proj = Linear(num_heads * head_dim, hidden_size, false, base_name + names._o_proj_name); q_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "q_rope"); k_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "v_cache"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } std::vector Forward(std::vector inputs, std::vector args) override { auto position_ids = inputs[1]; - auto query_states = q_proj(inputs[0]); auto key_states = k_proj(inputs[0]); auto value_states = v_proj(inputs[0]); @@ -247,11 +254,17 @@ class QWen2Attention final : public Module { key_states = k_rope(key_states, position_ids); key_states = k_cache(key_states); value_states = v_cache(value_states); - auto atten_weight = - Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) - / std::sqrt(head_dim); - atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); - auto atten_output = Tensor::mm(atten_weight, value_states); + + Tensor atten_output; + if (attn_impl == "flash_attention_2") { + atten_output = Tensor::flash_attention2_forward(query_states, key_states, value_states, true); + } else { // eager implementation + auto atten_weight = + Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) + / std::sqrt(head_dim); + atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); + atten_output = Tensor::mm(atten_weight, value_states); + } atten_output = atten_output.view(-1, 1, -1, head_dim * num_heads); atten_output = o_proj(atten_output); return {atten_output}; @@ -279,6 +292,8 @@ class QWen2Attention final : public Module { KVCache k_cache; KVCache v_cache; Softmax softmax; + string name; + string attn_impl; }; // Copied from GemmaDecoder with Gemma->Qwen and set RmsNorm(without add_unit_offset) @@ -349,7 +364,7 @@ class Qwen2VLModel final : public Module { vision_start_token_id = config.vision_start_token_id; embed_tokens = Embedding(vocab_size, hidden_dim, qwen_names.token_embd_name); - visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, vision_embed_dim * 4, "QuickGELU", 14, 336, 32, spatial_merge_size, vision_names, vision_names.vison_model_name); + visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, vision_embed_dim * 4, "QuickGELU", 14, 336, 32, spatial_merge_size, config.attn_implementation, vision_names, vision_names.vison_model_name); blocks = List(config.num_hidden_layers, config, qwen_names, qwen_names.blk_name); norm = RMSNorm(hidden_dim, 1e-6, qwen_names.post_norm_name); @@ -575,4 +590,4 @@ class Qwen2VLModel final : public Module { return {position_ids, mrope_position_deltas}; } }; -#endif // MODELING_PHI3_HPP \ No newline at end of file +#endif // MODELING_QWEN2VL_HPP \ No newline at end of file diff --git a/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp b/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp new file mode 100644 index 000000000..e5025d65c --- /dev/null +++ b/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp @@ -0,0 +1,978 @@ +#ifndef MODELING_QWEN2VL_NPU_HPP +#define MODELING_QWEN2VL_NPU_HPP + +#include "Layer.hpp" +#include "Module.hpp" +#include "Tensor.hpp" +#include "Timing.hpp" +#include "Types.hpp" +#include "configuration_qwen2_vl.hpp" +#include "models/qwen2_vl/modeling_qwen2_vl.hpp" +#include +#include +#include +#include + +using namespace mllm; + +// current version of showui/qwen2-vl don't need shadow layers +std::set qwenvlShadowLayers = {100}; + +// NPU QKV part +class QwenDecoderNPUPart1 : public Module { +protected: + int hidden_size; + int num_heads; + int head_dim; + int num_key_value_heads; + int num_key_value_groups; + + // it is for speed up the QNN linear implemented by conv, TODO: should integrate into QNNLinear + Layer pre_attn_view; + + Layer q_proj; + Layer k_proj; + Layer v_proj; + + Layer q_view; + Layer k_view; + Layer v_view; + + Layer q_dequant; + Layer k_dequant; + Layer v_dequant; + Layer v_transpose; + +public: + QwenDecoderNPUPart1() = default; + QwenDecoderNPUPart1(const Qwen2VLConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + num_key_value_heads = config.num_key_value_heads; + num_key_value_groups = num_heads / num_key_value_heads; + + pre_attn_view = View(1, utils::closestFactors(chunk_size).first, utils::closestFactors(chunk_size).second, num_heads * head_dim, base_name + "ires_split-00_view_"); + + q_proj = Linear(hidden_size, num_heads * head_dim, false, base_name + names._q_proj_name); + k_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._k_proj_name); + v_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._v_proj_name); + + q_view = View(1, num_heads, chunk_size, head_dim, base_name + names._q_proj_name + "-00_view_"); + k_view = View(1, num_key_value_heads, chunk_size, head_dim, base_name + names._k_proj_name + "-00_view_"); + v_view = View(1, num_key_value_heads, chunk_size, head_dim, base_name + names._v_proj_name + "-00_view_"); + + q_dequant = Dequantize(true, base_name + names._q_proj_name + ".dequantize", true, MLLM_TYPE_I16); + k_dequant = Dequantize(true, base_name + names._k_proj_name + ".dequantize", false, MLLM_TYPE_I16); + v_dequant = Dequantize(true, base_name + names._v_proj_name + ".dequantize", false, MLLM_TYPE_I16); + + v_transpose = Transpose({0, 2, 3, 1}, base_name + names._v_proj_name + ".transpose"); + } + + vector Forward(vector inputs, vector args) override { + auto x = pre_attn_view(inputs[0]); + + auto query_states = q_proj(x); + auto key_states = k_proj(x); + auto value_states = v_proj(x); + + query_states = q_view(query_states); + key_states = k_view(key_states); + value_states = v_view(value_states); + + // return {query_states, key_states, value_states}; + + query_states = q_dequant(query_states); + key_states = k_dequant(key_states); + value_states = v_dequant(value_states); + + value_states = v_transpose(value_states); + return {query_states, key_states, value_states}; + } +}; + +class QwenDecoderNPUPart1WithRes final : public QwenDecoderNPUPart1 { + Layer input_layernorm; + Layer pre_attn_quantize; + +public: + QwenDecoderNPUPart1WithRes() = default; + QwenDecoderNPUPart1WithRes(const Qwen2VLConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + num_key_value_heads = config.num_key_value_heads; + num_key_value_groups = num_heads / num_key_value_heads; + + // remove "self_attn." in base_name + auto layer_base_name = base_name.substr(0, base_name.size() - 10); + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, layer_base_name + names._attn_norm_name); + pre_attn_quantize = Quantize(true, layer_base_name + names._attn_base_name + names._q_proj_name + ".quantize", MLLM_TYPE_I16); + + pre_attn_view = View(1, utils::closestFactors(chunk_size).first, utils::closestFactors(chunk_size).second, num_heads * head_dim, base_name + "ires_split-00_view_"); + + q_proj = Linear(hidden_size, num_heads * head_dim, false, base_name + names._q_proj_name); + k_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._k_proj_name); + v_proj = Linear(hidden_size, num_key_value_heads * head_dim, false, base_name + names._v_proj_name); + + q_view = View(1, num_heads, chunk_size, head_dim, base_name + names._q_proj_name + "-00_view_"); + k_view = View(1, num_key_value_heads, chunk_size, head_dim, base_name + names._k_proj_name + "-00_view_"); + v_view = View(1, num_key_value_heads, chunk_size, head_dim, base_name + names._v_proj_name + "-00_view_"); + + q_dequant = Dequantize(true, base_name + names._q_proj_name + ".dequantize", true, MLLM_TYPE_I16); + k_dequant = Dequantize(true, base_name + names._k_proj_name + ".dequantize", false, MLLM_TYPE_I16); + v_dequant = Dequantize(true, base_name + names._v_proj_name + ".dequantize", false, MLLM_TYPE_I16); + + v_transpose = Transpose({0, 2, 3, 1}, base_name + names._v_proj_name + ".transpose"); + } + + vector Forward(vector inputs, vector args) override { + auto x = input_layernorm(inputs[0]); + x = pre_attn_quantize(x); + + x = pre_attn_view(x); + + auto query_states = q_proj(x); + auto key_states = k_proj(x); + auto value_states = v_proj(x); + + query_states = q_view(query_states); + key_states = k_view(key_states); + value_states = v_view(value_states); + + query_states = q_dequant(query_states); + key_states = k_dequant(key_states); + value_states = v_dequant(value_states); + + value_states = v_transpose(value_states); + return {query_states, key_states, value_states, inputs[0]}; + } +}; + +// CPU QKV MM part +class QwenQKVmm final : public Module { + MultimodalRoPE q_rope; + MultimodalRoPE k_rope; + KVCache k_cache; + KVCache v_cache; + Softmax softmax; + Layer o_quantize; + + int hidden_size; + int num_heads; + int head_dim; + int num_key_value_heads; + int num_key_value_groups; + +public: + QwenQKVmm() = default; + QwenQKVmm(const Qwen2VLConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + + q_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "q_rope"); + k_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "k_rope"); + + k_cache = KVCache(config.num_key_value_heads, head_dim, config.num_attention_heads / config.num_key_value_heads, config.cache_limit, base_name + "k_cache", true); + v_cache = KVCache(config.num_key_value_heads, head_dim, config.num_attention_heads / config.num_key_value_heads, config.cache_limit, base_name + "v_cache", true); + + softmax = Softmax(DIMENSION, true, base_name + "softmax"); + + o_quantize = Quantize(true, base_name + names._o_proj_name + ".quantize"); + } + + vector Forward(vector inputs, vector args) override { + // TODO: remove it + // auto qkv_start = mllm_time_ms(); + auto position_ids = inputs[3]; + + auto q = inputs[0]; + auto k = inputs[1]; + auto v = inputs[2]; + + q = q_rope(q, position_ids); + k = k_rope(k, position_ids); + + k = k_cache(k); + v = v_cache(v); + + auto qk = Tensor::mm(q, k.transpose(Chl::SEQUENCE, Chl::DIMENSION)); + qk = qk / std::sqrt(head_dim); + qk = softmax(qk); + auto o = Tensor::mm(qk, v); + + o = o_quantize(o); + + // TODO: remove it + // auto qkv_end = mllm_time_ms(); + // std::cout << "QKV mm time: " << qkv_end - qkv_start << "ms" << std::endl; + + return {o}; + } +}; + +// QNN mlp part +class QwenDecoderNPUPart2 : public Module { +protected: + int hidden_size; + int num_heads; + int head_dim; + int num_key_value_heads; + int num_key_value_groups; + int intermediate_size; + + // NPU part2 of attention + Layer pre_oproj_view; + Layer out_proj; + Layer post_oproj_view; + Layer post_oproj_dequantize; + + // NPU mlp + Layer pre_mlp_quantize; + Layer pre_mlp_view; + Layer gate_proj; + Layer up_proj; + Layer post_up_proj_dequantize; + Layer post_gate_proj_dequantize; + Layer silu; + Layer post_attn_layernorm; + + Layer down_proj; + Layer pre_down_proj_quantize; + Layer post_down_proj_dequantize; + Layer post_mlp_view; + + Layer post_atten_res_add; + Layer post_mlp_res_add; + Layer mlp_mul; + +public: + QwenDecoderNPUPart2() = default; + QwenDecoderNPUPart2(const Qwen2VLConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + intermediate_size = config.intermediate_size; + num_key_value_heads = config.num_key_value_heads; + num_key_value_groups = num_heads / num_key_value_heads; + + // for QNN linear speed up + pre_oproj_view = View(1, utils::closestFactors(chunk_size).first, utils::closestFactors(chunk_size).second, head_dim * num_heads, base_name + names._attn_base_name + "or_split-00_view_"); + out_proj = Linear(hidden_size, hidden_size, false, base_name + names._attn_base_name + names._o_proj_name); + post_oproj_dequantize = Dequantize(true, base_name + names._attn_base_name + names._o_proj_name + ".dequantize"); + post_oproj_view = View(1, 1, chunk_size, hidden_size, base_name + names._attn_base_name + names._o_proj_name + ".dequantize-00_view_"); + post_atten_res_add = Add(base_name + names._attn_base_name + "post_atten_add"); + + post_attn_layernorm = + RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); + + auto mlp_base_name = base_name + names._ffn_base_name; + pre_mlp_quantize = Quantize(true, mlp_base_name + names._up_proj_name + ".quantize"); + pre_mlp_view = View(1, utils::closestFactors(chunk_size).first, utils::closestFactors(chunk_size).second, hidden_size, mlp_base_name + names._up_proj_name + ".quantize-00_view_"); + gate_proj = Linear(hidden_size, intermediate_size, false, mlp_base_name + names._gate_proj_name); + silu = SiLU(mlp_base_name + "act"); + up_proj = Linear(hidden_size, intermediate_size, false, mlp_base_name + names._up_proj_name); + post_up_proj_dequantize = Dequantize(true, mlp_base_name + names._up_proj_name + ".dequantize"); + post_gate_proj_dequantize = Dequantize(true, mlp_base_name + names._gate_proj_name + ".dequantize"); + + down_proj = Linear(intermediate_size, hidden_size, false, mlp_base_name + names._down_proj_name); + pre_down_proj_quantize = Quantize(true, mlp_base_name + names._down_proj_name + ".quantize"); + post_down_proj_dequantize = Dequantize(true, mlp_base_name + names._down_proj_name + ".dequantize"); + post_mlp_view = View(1, 1, chunk_size, hidden_size, mlp_base_name + names._down_proj_name + ".dequantize-00_view_"); + + mlp_mul = Mul(mlp_base_name + "mul"); + post_mlp_res_add = Add(mlp_base_name + "res_add"); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto atten_output = inputs[0]; + auto res = inputs[1]; + + atten_output = pre_oproj_view(atten_output); + atten_output = out_proj(atten_output); + atten_output = post_oproj_dequantize(atten_output); + auto float_oproj = post_oproj_view(atten_output); + + auto tmp = post_atten_res_add(float_oproj, res); + + auto x = post_attn_layernorm(tmp); + + x = pre_mlp_quantize(x); + // reshape to 32,2 + x = pre_mlp_view(x); + + auto gate_out = gate_proj(x); + auto up_out = up_proj(x); + + gate_out = post_gate_proj_dequantize(gate_out); + auto silu_out = silu(gate_out); + + up_out = post_up_proj_dequantize(up_out); + gate_out = mlp_mul(silu_out, up_out); + + gate_out = pre_down_proj_quantize(gate_out); + gate_out = down_proj(gate_out); + gate_out = post_down_proj_dequantize(gate_out); + + // reshape to 64,1 + auto float_gate_out = post_mlp_view(gate_out); + + gate_out = post_mlp_res_add(float_gate_out, tmp); + return {gate_out, float_oproj, silu_out, float_gate_out}; + } +}; + +class QwenDecoderNPUPart2WithShadow final : public QwenDecoderNPUPart2 { +public: + QwenDecoderNPUPart2WithShadow() = default; + QwenDecoderNPUPart2WithShadow(const Qwen2VLConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + intermediate_size = config.intermediate_size; + num_key_value_heads = config.num_key_value_heads; + num_key_value_groups = num_heads / num_key_value_heads; + + // for QNN linear speed up + pre_oproj_view = View(1, utils::closestFactors(chunk_size).first, utils::closestFactors(chunk_size).second, head_dim * num_heads, base_name + names._attn_base_name + "or_split-00_view_"); + out_proj = Linear(hidden_size, hidden_size, false, base_name + names._attn_base_name + names._o_proj_name); + post_oproj_dequantize = Dequantize(true, base_name + names._attn_base_name + names._o_proj_name + ".dequantize"); + post_oproj_view = View(1, 1, chunk_size, hidden_size, base_name + names._attn_base_name + names._o_proj_name + ".dequantize-00_view_"); + post_atten_res_add = Add(base_name + names._attn_base_name + "post_atten_add"); + + post_attn_layernorm = + RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); + + auto mlp_base_name = base_name + names._ffn_base_name; + pre_mlp_quantize = Quantize(true, mlp_base_name + names._up_proj_name + ".quantize"); + pre_mlp_view = View(1, utils::closestFactors(chunk_size).first, utils::closestFactors(chunk_size).second, hidden_size, mlp_base_name + names._up_proj_name + ".quantize-00_view_"); + gate_proj = Linear(hidden_size, intermediate_size, false, mlp_base_name + names._gate_proj_name); + silu = SiLU(mlp_base_name + "act"); + up_proj = Linear(hidden_size, intermediate_size, false, mlp_base_name + names._up_proj_name); + post_up_proj_dequantize = Dequantize(true, mlp_base_name + names._up_proj_name + ".dequantize"); + post_gate_proj_dequantize = Dequantize(true, mlp_base_name + names._gate_proj_name + ".dequantize"); + + down_proj = Linear(intermediate_size, hidden_size, false, mlp_base_name + names._down_proj_name); + pre_down_proj_quantize = Quantize(true, mlp_base_name + names._down_proj_name + ".quantize"); + post_down_proj_dequantize = Dequantize(true, mlp_base_name + names._down_proj_name + ".dequantize"); + post_mlp_view = View(1, 1, chunk_size, hidden_size, mlp_base_name + names._down_proj_name + ".dequantize-00_view_"); + + mlp_mul = Mul(mlp_base_name + "mul"); + post_mlp_res_add = Add(mlp_base_name + "res_add"); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto atten_output = inputs[0]; + auto res = inputs[1]; + + atten_output = pre_oproj_view(atten_output); + atten_output = out_proj(atten_output); + atten_output = post_oproj_dequantize(atten_output); + atten_output = post_oproj_view(atten_output); + + auto tmp = post_atten_res_add(atten_output, res); + + auto x = post_attn_layernorm(tmp); + + x = pre_mlp_quantize(x); + // reshape to 32,2 + x = pre_mlp_view(x); + + auto gate_out = gate_proj(x); + auto up_out = up_proj(x); + + gate_out = post_gate_proj_dequantize(gate_out); + gate_out = silu(gate_out); + + up_out = post_up_proj_dequantize(up_out); + gate_out = mlp_mul(gate_out, up_out); + + auto shadow_input_1 = gate_out; + + gate_out = pre_down_proj_quantize(gate_out); + gate_out = down_proj(gate_out); + auto shadow_input_2 = gate_out; + gate_out = post_down_proj_dequantize(gate_out); + + // reshape to 64,1 + gate_out = post_mlp_view(gate_out); + + gate_out = post_mlp_res_add(gate_out, tmp); + + return {shadow_input_1, shadow_input_2, gate_out}; + } +}; + +class QwenNPU_CPUDecoder final : public Module { + int hidden_size; + int num_heads; + int head_dim; + int num_key_value_heads; + int num_key_value_groups; + + int layer_idx; + int num_layers; + + SubgraphStart _SubgraphStart_1, _SubgraphStart_2; + SubgraphFinalize _SubgraphEnd_1, _SubgraphEnd_2; + + Layer input_layernorm; + Layer pre_attn_quantize; + unique_ptr part1; + QwenQKVmm qkv_mm; + unique_ptr part2; + +public: + QwenNPU_CPUDecoder() = default; + QwenNPU_CPUDecoder(const Qwen2VLConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + num_key_value_heads = config.num_key_value_heads; + num_key_value_groups = num_heads / num_key_value_heads; + + // extract layer index from base_name like "model.layers.10." + std::regex re(R"(\d+)"); + std::smatch match; + std::regex_search(base_name, match, re); + layer_idx = std::stoi(match[0]); + num_layers = config.num_hidden_layers; + + if (layer_idx == 0 || qwenvlShadowLayers.find(layer_idx - 1) != qwenvlShadowLayers.end()) { + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize", MLLM_TYPE_I16); + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } else { + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } + + qkv_mm = QwenQKVmm(config, names, chunk_size, base_name + names._attn_base_name); + + part2 = make_unique(config, names, chunk_size, base_name); + + _SubgraphStart_1 = SubgraphStart(base_name + "subgraph_start1"); + _SubgraphEnd_1 = SubgraphFinalize(base_name + "subgraph_end1"); + _SubgraphStart_2 = SubgraphStart(base_name + "subgraph_start2"); + _SubgraphEnd_2 = SubgraphFinalize(base_name + "subgraph_end2"); + } + + vector Forward(vector inputs, vector args) override { + auto position_ids = inputs[1]; + + Tensor x, q, k, v, res; + if (layer_idx == 0 || qwenvlShadowLayers.find(layer_idx - 1) != qwenvlShadowLayers.end()) { + x = input_layernorm(inputs[0]); + + x = pre_attn_quantize(x); + + _SubgraphStart_1({x}); + + auto q_k_v = (*part1)({x}); // q,k,v + q = q_k_v[0]; + k = q_k_v[1]; + v = q_k_v[2]; + res = inputs[0]; + _SubgraphEnd_1(q_k_v); + + } else { + auto q_k_v_res = (*part1)(inputs); // q,k,v,res + q = q_k_v_res[0]; + k = q_k_v_res[1]; + v = q_k_v_res[2]; + res = q_k_v_res[3]; + _SubgraphEnd_1(q_k_v_res); + } + + auto o_x = qkv_mm({q, k, v, position_ids})[0]; + + _SubgraphStart_2({o_x, res}); + + auto out_part2 = (*part2)({o_x, res}); + + if (layer_idx == num_layers - 1) { + _SubgraphEnd_2(out_part2); + } + + return out_part2; + } +}; + +class QwenNPU_CPUDecoderWithShadow final : public Module { + int hidden_size; + int num_heads; + int head_dim; + int num_key_value_heads; + int num_key_value_groups; + + Layer input_layernorm; + Layer pre_attn_quantize; + Layer shadow_linear; + unique_ptr part1; + QwenQKVmm qkv_mm; + unique_ptr part2; + + int layer_idx; + int num_layers; + + SubgraphStart _SubgraphStart_1, _SubgraphStart_2; + SubgraphFinalize _SubgraphEnd_1, _SubgraphEnd_2; + +public: + QwenNPU_CPUDecoderWithShadow() = default; + QwenNPU_CPUDecoderWithShadow(const Qwen2VLConfig &config, const QWenNameConfig &names, int chunk_size, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + num_key_value_heads = config.num_key_value_heads; + num_key_value_groups = num_heads / num_key_value_heads; + + // extract layer index from base_name like "model.layers.10." + std::regex re(R"(\d+)"); + std::smatch match; + std::regex_search(base_name, match, re); + layer_idx = std::stoi(match[0]); + num_layers = config.num_hidden_layers; + + if (layer_idx == 0 || qwenvlShadowLayers.find(layer_idx - 1) != qwenvlShadowLayers.end()) { + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + pre_attn_quantize = Quantize(true, base_name + names._attn_base_name + names._q_proj_name + ".quantize", MLLM_TYPE_I16); + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } else { + part1 = make_unique(config, names, chunk_size, base_name + names._attn_base_name); + } + + qkv_mm = QwenQKVmm(config, names, chunk_size, base_name + names._attn_base_name); + + part2 = make_unique(config, names, chunk_size, base_name); + + shadow_linear = ShadowLinear(config.intermediate_size, hidden_size, 1024, false, base_name + names._ffn_base_name + names._down_proj_name + ".shadow"); + + _SubgraphStart_1 = SubgraphStart(base_name + "subgraph_start1"); + _SubgraphEnd_1 = SubgraphFinalize(base_name + "subgraph_end1"); + _SubgraphStart_2 = SubgraphStart(base_name + "subgraph_start2"); + _SubgraphEnd_2 = SubgraphFinalize(base_name + "subgraph_end2"); + } + + vector Forward(vector inputs, vector args) override { + auto position_ids = inputs[1]; + + Tensor x, q, k, v, res; + if (layer_idx == 0 || qwenvlShadowLayers.find(layer_idx - 1) != qwenvlShadowLayers.end()) { + x = input_layernorm(inputs[0]); + x = pre_attn_quantize(x); + + _SubgraphStart_1({x}); + + auto q_k_v = (*part1)({x}); // q,k,v + q = q_k_v[0]; + k = q_k_v[1]; + v = q_k_v[2]; + res = inputs[0]; + _SubgraphEnd_1(q_k_v); + } else { + auto q_k_v_res = (*part1)(inputs); // q,k,v,res + q = q_k_v_res[0]; + k = q_k_v_res[1]; + v = q_k_v_res[2]; + res = q_k_v_res[3]; + _SubgraphEnd_1(q_k_v_res); + } + + auto o_x = qkv_mm({q, k, v, position_ids})[0]; + + _SubgraphStart_2({o_x, res}); + + auto decoder_out = (*part2)({o_x, res}); + decoder_out = Tensor::toCPU(decoder_out); + + _SubgraphEnd_2(decoder_out); + + auto shadow_input_1 = decoder_out[0]; + auto shadow_input_2 = decoder_out[1]; + x = decoder_out[2]; + + x = shadow_linear(shadow_input_1, shadow_input_2, x); + + return {x}; + } +}; + +class Qwen2VL_ImagePatchAndEmbedding final : public Module { + Qwen2VisionModel visual; + Layer embed_tokens; + + Layer norm; + Parameter lm_head; + Layer lm_head_layer; + + bool tie_embedding_words; + + int64_t spatial_merge_size; + int64_t image_token_id; + int64_t video_token_id; + int64_t vision_start_token_id; + +public: + explicit Qwen2VL_ImagePatchAndEmbedding(const Qwen2VLConfig &config) { + auto vocab_size = config.vocab_size; + auto hidden_dim = config.hidden_size; + auto head_size = config.num_attention_heads; + auto ffn_hidden = config.intermediate_size; + auto projection_cls = config.projection_cls; + auto vision_embed_dim = config.vision_embed_dim; + image_token_id = config.image_token_id; + auto vision_names = config.vision_names_config; + auto qwen_names = config.names_config; + tie_embedding_words = config.tie_embedding_words; + spatial_merge_size = config.spatial_merge_size; + image_token_id = config.image_token_id; + video_token_id = config.video_token_id; + vision_start_token_id = config.vision_start_token_id; + + embed_tokens = Embedding(vocab_size, hidden_dim, qwen_names.token_embd_name); + visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, vision_embed_dim * 4, "QuickGELU", 14, 336, 32, spatial_merge_size, config.attn_implementation, vision_names, vision_names.vison_model_name); + } + + vector Forward(vector inputs, vector args) override { + auto hidden_states = embed_tokens({inputs[0]}); + + auto image_embeds = visual({inputs[1], inputs[2]})[0]; + auto n_image_features = image_embeds.sequence(); + auto where_idx = inputs[0].where(image_token_id, SEQUENCE); + hidden_states = hidden_states.index_put(image_embeds, where_idx, false); + + return {hidden_states}; + } + + // changed from get_position_ids in CPU Qwen2VL, enable padding + // when prefilling, padding_to should be the max length of the input + // when decoding, real_seq should be the real length of the input, thus get the correct position_ids for decoding + void get_position_ids(vector &inputs, int padding_to = 0, int real_seq = 0) { + if (inputs[0].sequence() > 1) { + Tensor video_grid_thw(0, 0, 0, 0, MLLM_CPU, true); + auto rope_indices = get_rope_index_cpp(inputs[0], inputs[2], video_grid_thw, padding_to); + auto position = rope_indices[0]; + if (inputs.size() == 4) { + inputs[3] = position; + } else { + inputs.push_back(position); + } + } else { + auto &position_ids = inputs[3]; + auto last_pos = real_seq == 0 ? position_ids.dataAt(0, 0, 0, position_ids.dimension() - 1) : real_seq - 1; + position_ids.reshape(position_ids.batch(), 1, position_ids.sequence(), 1); + for (int b = 0; b < position_ids.batch(); b++) { + for (int s = 0; s < position_ids.sequence(); s++) { + position_ids.setDataAt(b, 0, s, 0, last_pos + 1); + } + } + } + } + +private: + vector get_rope_index_cpp( + Tensor input_ids, + Tensor image_grid_thw, + Tensor video_grid_thw, + int padding_to = 0) { + vector> attention_mask; + auto attention_mask_shape = input_ids.sequence(); + for (int b = 0; b < input_ids.batch(); b++) { + attention_mask.emplace_back(attention_mask_shape, 1); + } + const size_t batch_size = input_ids.batch(); // input_ids.size(); + + // NOTE: changed from original + const size_t seq_len = batch_size > 0 ? (padding_to > input_ids.sequence() ? padding_to : input_ids.sequence()) : 0; // batch_size > 0 ? input_ids[0].size() : 0; + + Tensor position_ids(3, 1, batch_size, seq_len, Backend::global_backends[MLLM_CPU], true); + Tensor mrope_position_deltas(1, 1, 1, batch_size, Backend::global_backends[MLLM_CPU], true); + bool has_vision = (image_grid_thw.sequence() > 0) || (video_grid_thw.sequence() > 0); // image_grid_thw || video_grid_thw; + if (!has_vision) { + // Pure text case + for (size_t i = 0; i < batch_size; ++i) { + const auto &mask = !attention_mask.empty() ? attention_mask[i] : vector(seq_len, 1); + vector positions; + int64_t pos = 0; + for (size_t j = 0; j < seq_len; ++j) { + if (mask[j] == 1) { + positions.push_back(pos++); + } else { + positions.push_back(1); // Will be overwritten by mask + } + } + for (int dim = 0; dim < 3; ++dim) { + for (size_t j = 0; j < seq_len; ++j) { + position_ids.setDataAt(dim, 0, i, j, (float)(mask[j] == 1 ? positions[j] : 1)); + } + } + int64_t max_pos = pos - 1; + mrope_position_deltas.setDataAt(0, 0, 0, i, (float)((max_pos + 1) - static_cast(input_ids.sequence()))); + } + position_ids.setName("position_ids"); + mrope_position_deltas.setName("mrope_position_deltas"); + return {position_ids, mrope_position_deltas}; + } + // Process vision cases + size_t image_idx = 0, video_idx = 0; + for (size_t i = 0; i < batch_size; ++i) { + const auto &mask = !attention_mask.empty() ? attention_mask[i] : vector(seq_len, 1); + // Extract valid tokens + vector valid_tokens; + for (size_t j = 0; j < input_ids.sequence(); ++j) { + if (mask[j] == 1) valid_tokens.push_back((int)input_ids.dataAt(i, 0, j, 0)); + } + // Find vision start positions + vector vision_starts; + vector vision_types; + for (size_t j = 0; j < valid_tokens.size(); ++j) { + if (valid_tokens[j] == vision_start_token_id && j + 1 < valid_tokens.size()) { + vision_starts.push_back(j); + vision_types.push_back(valid_tokens[j + 1]); + } + } + int64_t image_count = count(vision_types.begin(), vision_types.end(), image_token_id); + int64_t video_count = vision_types.size() - image_count; + vector> llm_positions(3); + size_t st = 0; + int64_t current_max = 0; + int64_t remain_images = image_count; + int64_t remain_videos = video_count; + // Process each vision segment + for (size_t vs = 0; vs < vision_starts.size(); ++vs) { + // Find next vision token + size_t ed_image = valid_tokens.size(); + size_t ed_video = valid_tokens.size(); + if (remain_images > 0) { + auto it = find(valid_tokens.begin() + st, valid_tokens.end(), image_token_id); + if (it != valid_tokens.end()) ed_image = it - valid_tokens.begin(); + } + if (remain_videos > 0) { + auto it = find(valid_tokens.begin() + st, valid_tokens.end(), video_token_id); + if (it != valid_tokens.end()) ed_video = it - valid_tokens.begin(); + } + size_t ed = min(ed_image, ed_video); + if (ed == valid_tokens.size()) break; + // Get grid parameters + int64_t t, h, w; + bool is_image = (ed == ed_image); + if (is_image) { + t = (int64_t)image_grid_thw.dataAt(0, 0, image_idx, 0); + h = (int64_t)image_grid_thw.dataAt(0, 0, image_idx, 1); + w = (int64_t)image_grid_thw.dataAt(0, 0, image_idx, 2); + image_idx++; + remain_images--; + } else { + t = (int64_t)video_grid_thw.dataAt(0, 0, video_idx, 0); + h = (int64_t)video_grid_thw.dataAt(0, 0, video_idx, 1); + w = (int64_t)video_grid_thw.dataAt(0, 0, video_idx, 2); + video_idx++; + remain_videos--; + } + // Calculate grid dimensions + int64_t llm_grid_t = t; + int64_t llm_grid_h = h / spatial_merge_size; + int64_t llm_grid_w = w / spatial_merge_size; + // Process text segment + size_t text_len = ed - st; + if (text_len > 0) { + int64_t start_idx = current_max; + for (int64_t k = 0; k < text_len; ++k) { + for (int dim = 0; dim < 3; ++dim) { + llm_positions[dim].push_back(start_idx + k); + } + } + current_max += text_len; + } + for (int64_t ti = 0; ti < llm_grid_t; ++ti) { + for (int64_t hi = 0; hi < llm_grid_h; ++hi) { + for (int64_t wi = 0; wi < llm_grid_w; ++wi) { + llm_positions[0].push_back(current_max + ti); + llm_positions[1].push_back(current_max + hi); + llm_positions[2].push_back(current_max + wi); + } + } + } + current_max = std::max({llm_positions[0][llm_positions[0].size() - 1], + llm_positions[1][llm_positions[1].size() - 1], + llm_positions[2][llm_positions[2].size() - 1]}); + st = ed + llm_grid_t * llm_grid_h * llm_grid_w; + } + // Process remaining text + if (st < valid_tokens.size()) { + size_t text_len = valid_tokens.size() - st; + int64_t st_idx = current_max + 1; + for (int64_t k = 0; k < text_len; ++k) { + for (int dim = 0; dim < 3; ++dim) { + llm_positions[dim].push_back(st_idx + k); + } + } + current_max += text_len; + } + // Fill position_ids with valid positions + size_t valid_idx = 0; + for (size_t j = 0; j < seq_len; ++j) { + if (mask[j] == 1) { + if (valid_idx < llm_positions[0].size()) { + position_ids.setDataAt(0, 0, i, j, (float)llm_positions[0][valid_idx]); + position_ids.setDataAt(1, 0, i, j, (float)llm_positions[1][valid_idx]); + position_ids.setDataAt(2, 0, i, j, (float)llm_positions[2][valid_idx]); + valid_idx++; + } + } + } + // Calculate delta + int64_t max_pos = 0; + for (const auto &dim : llm_positions) { + for (auto val : dim) { + max_pos = max(max_pos, val); + } + } + mrope_position_deltas.setDataAt(0, 0, 0, i, (float)((max_pos + 1) - static_cast(input_ids.sequence()))); + } + position_ids.setName("position_ids"); + mrope_position_deltas.setName("mrope_position_deltas"); + return {position_ids, mrope_position_deltas}; + } +}; + +class Qwen2VL_PrefillBody final : public Module { + std::vector> blocks; + Layer norm; + Parameter lm_head; + Layer lm_head_layer; + int num_layer; + + bool tie_embedding_words; + + template + static vector> ListWithShadow(int n, Args &&...args) { + static_assert(std::is_base_of::value, "T1 must be a subclass of Module"); + static_assert(std::is_base_of::value, "SHADOW must be a subclass of Module"); + listIdx = 0; + vector> modules; + + // for index in shadowLayers, create shadow decoder, for others, create normal decoder + for (int i = 0; i < n; i++) { + auto new_args = change_last(args...); // 创建新的参数包,最后一个参数被修改为原来的值+ std::to_string(listIdx)+ "." + if (qwenvlShadowLayers.find(listIdx) != qwenvlShadowLayers.end()) { + modules.push_back(std::make_unique(std::apply([&](auto &&...args) { return SHADOW(std::forward(args)...); }, new_args))); + } else { + modules.push_back(std::make_unique(std::apply([&](auto &&...args) { return T1(std::forward(args)...); }, new_args))); + } + listIdx++; + } + listIdx = 0; + return modules; + } + +public: + explicit Qwen2VL_PrefillBody(const Qwen2VLConfig &config, int chunk_size) { + // Module::initBackend(MLLM_QNN); + auto vocab_size = config.vocab_size; + auto hidden_dim = config.hidden_size; + auto head_size = config.num_attention_heads; + auto qwen_names = config.names_config; + tie_embedding_words = config.tie_embedding_words; + + num_layer = config.num_hidden_layers; + + blocks = ListWithShadow(config.num_hidden_layers, config, qwen_names, chunk_size, qwen_names.blk_name); + norm = RMSNorm(hidden_dim, 1e-6, qwen_names.post_norm_name); + if (tie_embedding_words) { + lm_head = Parameter(1, config.vocab_size, 1, config.hidden_size, qwen_names.token_embd_name + ".weight"); + } else { + lm_head_layer = HeadLinear(config.hidden_size, config.vocab_size, false, qwen_names.lm_head_name); + } + } + + vector Forward(vector inputs, vector args) override { + auto hidden_states = inputs[0]; + auto position_ids = inputs[1]; + + for (auto &block : blocks) { + hidden_states = (*block)({hidden_states, position_ids})[0]; + } + + hidden_states = norm(hidden_states); + + if (tie_embedding_words) { + hidden_states = Tensor::mm(hidden_states, lm_head().transpose(Chl::SEQUENCE, Chl::DIMENSION)); + } else { + hidden_states = lm_head_layer(hidden_states); + } + return {hidden_states}; + } +}; + +// CPU decoding model with only the LLM backbone +class Qwen2VL_Decoding_Model final : public Module { + Layer embed_tokens; + + vector blocks; + Layer norm; + Parameter lm_head; + Layer lm_head_layer; + + bool tie_embedding_words; + + int64_t spatial_merge_size; + int64_t image_token_id; + int64_t video_token_id; + int64_t vision_start_token_id; + +public: + explicit Qwen2VL_Decoding_Model(const Qwen2VLConfig &config) { + auto vocab_size = config.vocab_size; + auto hidden_dim = config.hidden_size; + auto head_size = config.num_attention_heads; + auto ffn_hidden = config.intermediate_size; + auto projection_cls = config.projection_cls; + auto vision_embed_dim = config.vision_embed_dim; + image_token_id = config.image_token_id; + auto vision_names = config.vision_names_config; + auto qwen_names = config.names_config; + tie_embedding_words = config.tie_embedding_words; + spatial_merge_size = config.spatial_merge_size; + image_token_id = config.image_token_id; + video_token_id = config.video_token_id; + vision_start_token_id = config.vision_start_token_id; + + embed_tokens = Embedding(vocab_size, hidden_dim, qwen_names.token_embd_name); + + blocks = List(config.num_hidden_layers, config, qwen_names, qwen_names.blk_name); + norm = RMSNorm(hidden_dim, 1e-6, qwen_names.post_norm_name); + if (tie_embedding_words) { + lm_head = Parameter(1, config.vocab_size, 1, config.hidden_size, qwen_names.token_embd_name + ".weight"); + } else { + lm_head_layer = Linear(config.hidden_size, config.vocab_size, false, qwen_names.lm_head_name); + } + } + vector Forward(vector inputs, vector args) override { + auto position_ids = inputs[3]; + + auto hidden_states = embed_tokens({inputs[0]}); + + for (auto &block : blocks) { + hidden_states = block({hidden_states, position_ids})[0]; + } + hidden_states = norm(hidden_states); + if (tie_embedding_words) { + hidden_states = Tensor::mm(hidden_states, lm_head().transpose(Chl::SEQUENCE, Chl::DIMENSION)); + } else { + hidden_states = lm_head_layer(hidden_states); + } + return {hidden_states}; + } + void clear_kvcache() override { + for (auto &block : blocks) { + auto kvcahce = block.get_attention().get_cache(); + for (auto &cache : kvcahce) { + cache->clearCache(); + } + } + } +}; + +#endif // MODELING_QWEN2VL_NPU_HPP \ No newline at end of file diff --git a/src/models/qwen2_vl/processing_qwen2_vl.hpp b/src/models/qwen2_vl/processing_qwen2_vl.hpp index 3a70e972d..bed3638be 100644 --- a/src/models/qwen2_vl/processing_qwen2_vl.hpp +++ b/src/models/qwen2_vl/processing_qwen2_vl.hpp @@ -191,6 +191,12 @@ class Qwen2VLImageProcessor { vector> input_ids_; pair>, vector> preprocess_images(const uint8_t *image, const size_t &image_length) { auto imageinfos = vector(); + // int width, height, channels; + // auto data = stbi_load_from_memory(image, image_length, &width, &height, &channels, 3); + // if (data == nullptr) { + // MLLM_LOG_ERROR_STREAM << "Error: Failed to load image from memory." << std::endl; + // exit(-1); + // } int width, height, channels; auto data = stbi_load_from_memory(image, image_length, &width, &height, &channels, 0); if (data == nullptr) { @@ -431,12 +437,12 @@ class Qwen2VLProcessor final : public PreProcessor { return tokenizer->detokenize(tokens); } - std::pair detokenize(Tensor &result) { + std::pair detokenize(Tensor &result, int seq = 0) { assert(result.batch() == 1 && "Batch size of result is not 1. Which is not supported for now."); assert(result.head() == 1 && "The 3rd dim of result should be one. e.g.:[1, 1, seq, hidden]"); vector scores; int _dims = result.dimension(); - int _seq = result.sequence() - 1; + int _seq = seq == 0 ? result.sequence() - 1 : seq - 1; for (int i = 0; i < _dims; ++i) { auto value = result.dataAt(0, 0, _seq, i); scores.push_back(value); diff --git a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp index 7243ca144..5d3c179e2 100644 --- a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp @@ -4,14 +4,21 @@ #ifndef MODELING_QWEN2VL_HPP #define MODELING_QWEN2VL_HPP +// #define VTP +#include +#define NDC + #include "Layer.hpp" #include "Module.hpp" #include "Tensor.hpp" #include "Types.hpp" #include "../configuration_qwen2_vl.hpp" -// #include "models/qwen/modeling_qwen.hpp" -// #include +#if defined(VTP) #include "vtp_tools.hpp" +#endif +#ifdef NDC +#include "ndc_tools.hpp" +#endif #include #include @@ -231,7 +238,8 @@ class QWen2Attention final : public Module { k_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "k_rope"); k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "k_cache"); v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "v_cache"); - softmax = Softmax(DIMENSION, true, base_name + "softmax"); + mask = Causalmask(base_name + "mask"); + softmax = Softmax(DIMENSION, false, base_name + "softmax"); } std::vector Forward(std::vector inputs, std::vector args) override { @@ -246,24 +254,43 @@ class QWen2Attention final : public Module { value_states = value_states.view(-1, num_key_value_heads, -1, head_dim); query_states = q_rope(query_states, position_ids); key_states = k_rope(key_states, position_ids); - key_states = k_cache(key_states); - value_states = v_cache(value_states); + auto key_cache_states = k_cache(key_states); + auto value_cache_states = v_cache(value_states); +#if defined(NDC) + // ====================================================================================== + WHERE_TOKEN_PRUNING.get_kvcache(key_cache_states, value_cache_states, key_states, value_states, + layer_index, k_cache.getCacheSeqLen()); + //====================================================================================== +#endif auto atten_weight = - Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) + Tensor::mm(query_states, key_cache_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) / std::sqrt(head_dim); +#if defined(NDC) + if (WHERE_TOKEN_PRUNING.causal_masks.find(layer_index) != WHERE_TOKEN_PRUNING.causal_masks.end() + && atten_weight.sequence() > 1) { + atten_weight = atten_weight + WHERE_TOKEN_PRUNING.causal_masks[layer_index]; + WHERE_TOKEN_PRUNING.causal_masks.erase(layer_index); + } else { +#endif + atten_weight = mask(atten_weight, k_cache.getCacheSeqLen()); +#if defined(NDC) + } +#endif atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); - auto atten_output = Tensor::mm(atten_weight, value_states); + auto atten_output = Tensor::mm(atten_weight, value_cache_states); atten_output = atten_output.view(-1, 1, -1, head_dim * num_heads); atten_output = o_proj(atten_output); +#if defined(VTP) //====================================================================================== // pruning stage if (WHERE_TOKEN_PRUNING.is_prefill()) { WHERE_TOKEN_PRUNING.set_prefill_layer(layer_index); WHERE_TOKEN_PRUNING.update_attn_acc_score(atten_weight); - atten_output = WHERE_TOKEN_PRUNING.prunning_attn_output(atten_output); + atten_output = WHERE_TOKEN_PRUNING.prunning_attn_output(atten_output, layer_index); } //====================================================================================== - return {atten_output}; +#endif + return {atten_output, atten_weight}; } vector get_cache() { @@ -288,6 +315,7 @@ class QWen2Attention final : public Module { KVCache k_cache; KVCache v_cache; Softmax softmax; + Causalmask mask; }; // Copied from GemmaDecoder with Gemma->Qwen and set RmsNorm(without add_unit_offset) @@ -308,17 +336,26 @@ class QWen2Decoder final : public Module { auto position_ids = inputs[1]; auto residual = inputs[0]; auto x = input_layernorm(residual); - x = self_atten({x, position_ids}, layer_index)[0]; + auto xs = self_atten({x, position_ids}, layer_index); + x = xs[0]; + auto atten_weight = xs[1]; +#if defined(VTP) //====================================================================================== // pruning stage if (WHERE_TOKEN_PRUNING.is_prefill()) { residual = WHERE_TOKEN_PRUNING.pruning_(residual); } //====================================================================================== +#endif auto tmp = x + residual; x = post_attention_layernorm(tmp); x = mlp({x})[0]; x = x + tmp; +#if defined(NDC) + //====================================================================================== + WHERE_TOKEN_PRUNING.update_hidden_pos(x, atten_weight, layer_index); + //====================================================================================== +#endif return {x}; } QWen2Attention &get_attention() { @@ -342,6 +379,8 @@ class Qwen2VLModel final : public Module { Layer lm_head_layer; bool tie_embedding_words; + int num_hidden_layers; + int num_attention_heads; int64_t spatial_merge_size; int64_t image_token_id; @@ -361,6 +400,8 @@ class Qwen2VLModel final : public Module { auto qwen_names = config.names_config; tie_embedding_words = config.tie_embedding_words; spatial_merge_size = config.spatial_merge_size; + num_hidden_layers = config.num_hidden_layers; + num_attention_heads = config.num_attention_heads; image_token_id = config.image_token_id; video_token_id = config.video_token_id; vision_start_token_id = config.vision_start_token_id; @@ -377,12 +418,11 @@ class Qwen2VLModel final : public Module { } } vector Forward(vector inputs, vector args) override { - WHERE_TOKEN_PRUNING.init(); - if (inputs[0].sequence() <= 1) { - WHERE_TOKEN_PRUNING.prefill_stage = false; - } else { - WHERE_TOKEN_PRUNING.prefill_stage = true; - } +#if defined(VTP) || defined(NDC) + // ====================================================================================== + WHERE_TOKEN_PRUNING.init(inputs[0], num_hidden_layers, num_attention_heads); + // ====================================================================================== +#endif auto position_ids = inputs[3]; bool have_img = inputs[1].batch() > 0; auto hidden_states = embed_tokens({inputs[0]}); @@ -390,16 +430,27 @@ class Qwen2VLModel final : public Module { auto image_embeds = visual({inputs[1], inputs[2]})[0]; auto n_image_features = image_embeds.sequence(); auto where_idx = inputs[0].where(image_token_id, SEQUENCE); - // ======================================================================================================== +#if defined(VTP) || defined(NDC) + // ====================================================================================== // Pruning Stage 1 Start - if (WHERE_TOKEN_PRUNING.is_prefill()) { - WHERE_TOKEN_PRUNING.set_vision_token(where_idx, hidden_states, image_embeds); - } - // ======================================================================================================== + WHERE_TOKEN_PRUNING.set_vision_token(where_idx, hidden_states, image_embeds); + // ====================================================================================== +#endif hidden_states = hidden_states.index_put(image_embeds, where_idx, false); } +#if defined(NDC) + // ====================================================================================== + // if (WHERE_TOKEN_PRUNING.is_prefill()) { + auto past_kv_seq_len = blocks[0].get_attention().get_cache()[0]->getCacheSeqLen(); + if (past_kv_seq_len != -1) { + WHERE_TOKEN_PRUNING.ndc_prepare(hidden_states, position_ids, past_kv_seq_len); + } + // } + // ====================================================================================== +#endif int layer_index = 0; for (auto &block : blocks) { +#if defined(VTP) //====================================================================================== // pruning stage if (WHERE_TOKEN_PRUNING.is_prefill()) { @@ -407,7 +458,17 @@ class Qwen2VLModel final : public Module { position_ids = WHERE_TOKEN_PRUNING.pruning_pos(position_ids, DIMENSION); } //====================================================================================== +#endif hidden_states = block({hidden_states, position_ids}, layer_index)[0]; +#if defined(NDC) + // ====================================================================================== + // change position_ids + auto kv_seq_len = blocks[layer_index + 1].get_attention().get_cache()[0]->getCacheSeqLen(); + if (kv_seq_len != -1) { + hidden_states = WHERE_TOKEN_PRUNING.prepare_next_layer(layer_index, position_ids, hidden_states, kv_seq_len); + } + // ====================================================================================== +#endif layer_index++; } hidden_states = norm(hidden_states); @@ -419,12 +480,14 @@ class Qwen2VLModel final : public Module { } else { hidden_states = lm_head_layer(hidden_states); } +#if defined(VTP) //====================================================================================== // pruning stage if (WHERE_TOKEN_PRUNING.is_prefill() && (Tensor::tensor_status == TENSOR_STATIC_READY)) { WHERE_TOKEN_PRUNING.prefill_stage = false; } //====================================================================================== +#endif return {hidden_states}; } void clear_kvcache() override { diff --git a/src/models/qwen2_vl/vtp/ndc_tools.hpp b/src/models/qwen2_vl/vtp/ndc_tools.hpp new file mode 100644 index 000000000..6ada028b3 --- /dev/null +++ b/src/models/qwen2_vl/vtp/ndc_tools.hpp @@ -0,0 +1,515 @@ +// +// Created by Rongjie Yi on 25-5-29. +// +#ifndef NDC_TOOLS_HPP +#define NDC_TOOLS_HPP + +#include "Module.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace mllm; + +class DelayComputeKVCache { +public: + vector> kv_true_token_appds; + vector hidden_states_cache; + vector hidden_states_filled; + DelayComputeKVCache() { + } + void init_cache_list(int layers) { + hidden_states_cache.resize(layers); + hidden_states_filled.resize(layers); + kv_true_token_appds.resize(layers); + } + void update_hidden_states(Tensor hidden_states, int layer_idx, int original_hs_length, vector pos, bool is_prefill) { + auto b = hidden_states.batch(); + auto d = hidden_states.dimension(); + if (hidden_states_cache[layer_idx].name().empty()) { //=如果hidden_states_cache[layer_idx]为空Tensor + hidden_states_cache[layer_idx] = Tensor(b, 1, original_hs_length, d, MLLM_CPU, true); + hidden_states_cache[layer_idx].setName("hidden_states_cache_" + std::to_string(layer_idx)); + hidden_states_filled[layer_idx] = Tensor(b, 1, original_hs_length, 1, MLLM_CPU, true); + hidden_states_filled[layer_idx].setName("hidden_states_fille_" + std::to_string(layer_idx)); + } + for (int bb = 0; bb < b; ++bb) { + for (int i = 0; i < pos.size(); ++i) { + auto p = pos[i]; + memcpy(hidden_states_cache[layer_idx].ptrAt(bb, 0, p, 0), + hidden_states.ptrAt(bb, 0, i, 0), + sizeof(float) * d); + hidden_states_filled[layer_idx].setDataAt(bb, 0, p, 0, 1.0f); + } + } + } + Tensor get_hidden_states(int layer_idx, vector pos) { + return hidden_states_cache[layer_idx].clip(pos, SEQUENCE); + } + Tensor reset_hidden_states(Tensor hidden_states, int layer_idx, vector pos) { + assert(hidden_states.batch() == 1); + vector hidden_states_last; + hidden_states_last.resize(hidden_states.dimension()); + memcpy(hidden_states_last.data(), + hidden_states.ptrAt(0, 0, hidden_states.sequence() - 1, 0), + sizeof(float) * hidden_states.dimension()); + hidden_states.reshape(1, 1, pos.size() + 1, hidden_states.dimension()); + hidden_states.alloc(); + for (int i = 0; i < pos.size(); ++i) { + int p = pos[i]; + memcpy(hidden_states.ptrAt(0, 0, i, 0), + hidden_states_cache[layer_idx].ptrAt(0, 0, p, 0), + sizeof(float) * hidden_states.dimension()); + } + memcpy(hidden_states.ptrAt(0, 0, hidden_states.sequence() - 1, 0), + hidden_states_last.data(), + sizeof(float) * hidden_states.dimension()); + return hidden_states; + } + vector kv_not_filled_pos(int layer_idx, int original_kv_length) { + auto filled_token = kv_true_token_appds[layer_idx]; + vector not_filled_pos; + for (int i = 0; i < original_kv_length; ++i) { + if (std::find(filled_token.begin(), filled_token.end(), i) == filled_token.end()) { + not_filled_pos.push_back(i); + } + } + return not_filled_pos; + } + template + static void reorder_cache(Tensor &k_cache, Tensor &v_cache, + const vector &indices, + int pos_first, int cache_sequence) { + const int num_heads = v_cache.head(); + const int k_per_head = k_cache.dimension(); + const int v_per_head = v_cache.dimension(); + const int k_size = num_heads * k_per_head; + const int v_size = v_per_head; + // 1. 分配临时内存 + vector> k_cache_data(cache_sequence - pos_first); + vector>> v_cache_data(num_heads); + for (int i = pos_first; i < cache_sequence; i++) { + k_cache_data[i - pos_first].resize(k_size); + } + for (int h = 0; h < num_heads; ++h) { + v_cache_data[h].resize(cache_sequence - pos_first); + for (int i = pos_first; i < cache_sequence; i++) { + v_cache_data[h][i - pos_first].resize(v_size); + } + } + // 2. 拷贝数据到临时内存 + for (int i = pos_first; i < cache_sequence; i++) { + // K_cache拷贝(全部heads) + memcpy(k_cache_data[i - pos_first].data(), + k_cache.ptrAt(0, 0, i, 0), + sizeof(T) * k_size); + // V_cache拷贝(每个head分开) +#pragma omp parallel for num_threads(CPUBackend::cpu_threads) + for (int h = 0; h < num_heads; ++h) { + memcpy(v_cache_data[h][i - pos_first].data(), + v_cache.ptrAt(0, h, i, 0), + sizeof(T) * v_size); + } + } + // 3. 根据索引重新排序 + for (size_t idx : indices) { + if (idx >= (size_t)pos_first && idx < (size_t)cache_sequence) { + const int temp_idx = idx - pos_first; + // 写回K_cache + memcpy(k_cache.ptrAt(0, 0, idx, 0), + k_cache_data[temp_idx].data(), + sizeof(T) * k_size); + // 写回V_cache +#pragma omp parallel for num_threads(CPUBackend::cpu_threads) + for (int h = 0; h < num_heads; ++h) { + memcpy(v_cache.ptrAt(0, h, idx, 0), + v_cache_data[h][temp_idx].data(), + sizeof(T) * v_size); + } + } + } + } + + void update_kv_cache(Tensor &k_cache, Tensor &v_cache, Tensor &k_state, Tensor &v_state, int cache_sequence, int layer_idx, + bool is_prefill, string update_mode, vector pos = {}, int original_kv_length = -1) { + if (update_mode == "insert") { + assert(k_cache.masterTensor() == k_state.masterTensor()); + assert(v_cache.masterTensor() == v_state.masterTensor()); + // pos代表现在的token列表:{0,1,2,3,5,6,8,9}, 8个token及其列表 + if (is_prefill) { + kv_true_token_appds[layer_idx] = pos; // 记录当前token的列表 + assert(kv_true_token_appds[layer_idx].size() == cache_sequence); + } else { + auto new_token_pos = kv_true_token_appds[layer_idx][kv_true_token_appds[layer_idx].size() - 1] + 1; + assert(kv_true_token_appds[layer_idx].size() + 1 + pos.size() == cache_sequence); + kv_true_token_appds[layer_idx].insert(kv_true_token_appds[layer_idx].end(), pos.begin(), pos.end()); + kv_true_token_appds[layer_idx].push_back(new_token_pos); // 添加新的token位置 + auto &cur_pos = kv_true_token_appds[layer_idx]; + // for k_cache; + if (pos.size() > 1) { + auto pos_first = pos[0]; + assert(v_cache.ctype() == BHDS); + // 创建并初始化索引数组 + std::vector indices(cur_pos.size()); + std::iota(indices.begin(), indices.end(), 0); + std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) { + return cur_pos[a] < cur_pos[b]; + }); + assert(k_cache.batch() == 1); + if (k_cache.dtype() == MLLM_TYPE_F16) { + reorder_cache(k_cache, v_cache, indices, pos_first, cache_sequence); + } else { + reorder_cache(k_cache, v_cache, indices, pos_first, cache_sequence); + } + std::sort(kv_true_token_appds[layer_idx].begin(), kv_true_token_appds[layer_idx].end()); + } + } + } + } +}; + +class NdcContext { + int first_img_token_pos = 0; + int last_img_token_pos = 0; + int last_img_token_pos_l = 0; + DelayComputeKVCache kvcache_ctx; + int cur_step = -1; + vector> chosen_pos_in_each; + vector> chosen_pos_to_delay_compute; + Tensor global_position_ids; + int num_hidden_layers = 0; + int num_head = 0; + int original_kv_length = 0; + int chunk_size = 4; + map pruning_place_cfg = {{3, 0.2}, {9, 0.2}, {12, 0.2}, {15, 0.2}, {18, 0.2}, {26, 0.2}}; + // map pruning_place_cfg = {{3, 0.2}, {9, 0.2}}; + +public: + map causal_masks; // layer_idx -> causal_mask + bool prefill_stage = true; + void init(Tensor input_ids, int num_layers, int num_attention_heads) { + if (Module::llm_model_ptr->doLoad) { return; } + num_hidden_layers = num_layers; + num_head = num_attention_heads; + if (kvcache_ctx.hidden_states_cache.empty()) { + chosen_pos_in_each.resize(num_hidden_layers, {}); + kvcache_ctx.init_cache_list(num_hidden_layers); // Initialize with 1 layer, can be adjusted as needed + } + + if (input_ids.sequence() <= 1) { + prefill_stage = false; + } else { + prefill_stage = true; + } + } + bool is_prefill() { + return prefill_stage && cur_step == 0; + } + void set_vision_token(Tensor where_idx, Tensor hidden_states, Tensor image_embeds) { + if (Module::llm_model_ptr->doLoad) { return; } + first_img_token_pos = int(where_idx.dataAt(0, 0, 0, 0)); + last_img_token_pos = int(where_idx.dataAt(0, 0, 0, where_idx.dimension() - 1)) + 1; + } + + void ndc_prepare(Tensor hidden_states, Tensor position_ids, int past_kv_seq_len) { + if (Module::llm_model_ptr->doLoad) { return; } + cur_step += 1; + if (cur_step == 0) { + global_position_ids = position_ids; + original_kv_length = hidden_states.sequence(); + } + chosen_pos_in_each.resize(num_hidden_layers, {}); + int new_seq_len = hidden_states.sequence() + past_kv_seq_len; + chosen_pos_in_each[0].clear(); + for (int i = 0; i < new_seq_len; ++i) { + chosen_pos_in_each[0].push_back(i); + } + if (!is_prefill()) { + chosen_pos_to_delay_compute.resize(num_hidden_layers, {}); + } + } + void get_kvcache(Tensor &k_cache, Tensor &v_cache, Tensor &k_state, Tensor &v_state, int layer_idx, int cache_sequence) { + if (Module::llm_model_ptr->doLoad) { return; } + if (is_prefill()) { + auto chosen_pos = chosen_pos_in_each[layer_idx]; + kvcache_ctx.update_kv_cache(k_cache, v_cache, k_state, v_state, cache_sequence, layer_idx, + is_prefill(), "insert", + chosen_pos, original_kv_length); + } else { + auto chosen_pos = chosen_pos_in_each[layer_idx]; + kvcache_ctx.update_kv_cache(k_cache, v_cache, k_state, v_state, cache_sequence, layer_idx, + is_prefill(), "insert", + chosen_pos_to_delay_compute[layer_idx], original_kv_length); + } + } + + void topk_partial_sort(const vector &scores, int k, + vector &topk_values, vector &topk_indices) { + if (k <= 0 || scores.empty()) { + topk_values.clear(); + topk_indices.clear(); + return; + } + k = std::min(k, static_cast(scores.size())); + // 创建索引向量 + vector indices(scores.size()); + for (int i = 0; i < scores.size(); i++) { + indices[i] = i; + } + // 部分排序 - 将前k个最大的元素移动到前部 + std::partial_sort(indices.begin(), indices.begin() + k, indices.end(), + [&scores](int a, int b) { + return scores[a] > scores[b]; // 降序排序 + }); + // 提取结果 + topk_values.resize(k); + topk_indices.resize(k); + for (int i = 0; i < k; i++) { + topk_indices[i] = indices[i]; + topk_values[i] = scores[indices[i]]; + } + } + + vector select_high_score_visual_token_prefill(Tensor attn, int layer_idx, int chunk_size = 4) { + auto cur_chosen_pos = chosen_pos_in_each[layer_idx]; + // attention_score_analyze_prefill start + attn = attn.mean(HEAD); // 1,t,1,t + int visual_start_in_selected = -1; + int visual_end_in_selected = -1; + for (int i = 0; i < cur_chosen_pos.size(); ++i) { + auto pos = cur_chosen_pos[i]; + if (pos == first_img_token_pos - 1) { // 0 && visual_end_in_selected > 0) { + break; + } + } + int attn_seq_start = visual_end_in_selected + 1; // +1 for the end image token + int attn_seq_end = attn.sequence(); // exclusive + int attn_dim_start = visual_start_in_selected + 1; // +1 for the first image token + int attn_dim_end = visual_end_in_selected; // exclusive + vector attn_score; // 1,1,1,visual_end_in_selected - visual_start_in_selected + 1 + for (int j = attn_dim_start; j < attn_dim_end; ++j) { + float data = 0.0f; + for (int i = attn_seq_start; i < attn_seq_end; ++i) { + data += attn.dataAt(0, 0, i, j); + } + // data /= (attn_seq_end - attn_seq_start); + attn_score.push_back(data); + } + auto v_s = visual_start_in_selected; + auto v_e = visual_end_in_selected; + // attention_score_analyze_prefill end + auto pruning_rate = pruning_place_cfg[layer_idx]; + auto cur_visual_token_length = attn_score.size(); + auto keep_ratio = 1 - pruning_rate; + int k_initial = static_cast(std::ceil(cur_visual_token_length * keep_ratio)); + int k_final = (k_initial / chunk_size) * chunk_size; + k_final = std::min(k_final, static_cast(cur_visual_token_length)); // 确保不超过当前实际长度 + vector topk_vals; + vector topk_indices; + topk_partial_sort(attn_score, k_final, topk_vals, topk_indices); // torch.topk(attn_score, k_final) + vector final_token_chosen; + vector cur_chosen_pos_p1(cur_chosen_pos.begin(), cur_chosen_pos.begin() + v_s + 1); + vector cur_chosen_pos_p2(cur_chosen_pos.begin() + v_s + 1, cur_chosen_pos.begin() + v_e); + vector cur_chosen_pos_p3(cur_chosen_pos.begin() + v_e, cur_chosen_pos.end()); + final_token_chosen = cur_chosen_pos_p1; + for (auto item : topk_indices) { + final_token_chosen.push_back(cur_chosen_pos_p2[item]); + } + final_token_chosen.insert(final_token_chosen.end(), cur_chosen_pos_p3.begin(), cur_chosen_pos_p3.end()); + std::sort(final_token_chosen.begin(), final_token_chosen.end()); + return final_token_chosen; + } + vector select_high_score_visual_token_decode(Tensor attn, int layer_idx, int chunk_size = 4) { + auto cur_chosen_pos = chosen_pos_in_each[layer_idx]; + // attention_score_analyze_decode start + attn = attn.mean(HEAD); // 1,t,1,t TODO + if (attn.sequence() != 1) { + attn = attn.clip({}, {}, {-1}, {}); // 1,1,1,t + } + auto cur_chosen_tokens = chosen_pos_in_each[layer_idx]; + int visual_start_in_selected = -1; + int visual_end_in_selected = -1; + for (int i = 0; i < cur_chosen_pos.size(); ++i) { + auto pos = cur_chosen_pos[i]; + if (pos == first_img_token_pos - 1) { // 0 && visual_end_in_selected > 0) { + break; + } + } + int attn_dim_start = visual_start_in_selected + 1; // +1 for the first image token + int attn_dim_end = visual_end_in_selected; // exclusive + vector attn_score; // 1,1,1,visual_end_in_selected - visual_start_in_selected + 1 + for (int j = attn_dim_start; j < attn_dim_end; ++j) { + float data = attn.dataAt(0, 0, 0, j); + attn_score.push_back(data); + } + auto v_s = visual_start_in_selected; + auto v_e = visual_end_in_selected; + // attention_score_analyze_decode end + auto pruning_rate = pruning_place_cfg[layer_idx]; + auto cur_visual_token_length = attn_score.size(); + auto keep_ratio = 1 - pruning_rate; + int k_initial = static_cast(std::ceil(cur_visual_token_length * keep_ratio)); + int k_final = (k_initial / chunk_size) * chunk_size; + k_final = std::min(k_final, static_cast(cur_visual_token_length)); // 确保不超过当前实际长度 + vector topk_vals; + vector topk_indices; + topk_partial_sort(attn_score, k_final, topk_vals, topk_indices); // torch.topk(attn_score, k_final) + vector final_token_chosen; + vector cur_chosen_pos_p1(cur_chosen_pos.begin(), cur_chosen_pos.begin() + v_s + 1); + vector cur_chosen_pos_p2(cur_chosen_pos.begin() + v_s + 1, cur_chosen_pos.begin() + v_e); + vector cur_chosen_pos_p3(cur_chosen_pos.begin() + v_e, cur_chosen_pos.end()); + final_token_chosen = cur_chosen_pos_p1; + for (auto item : topk_indices) { + final_token_chosen.push_back(cur_chosen_pos_p2[item]); + } + final_token_chosen.insert(final_token_chosen.end(), cur_chosen_pos_p3.begin(), cur_chosen_pos_p3.end()); + std::sort(final_token_chosen.begin(), final_token_chosen.end()); + return final_token_chosen; + } + + void update_hidden_pos(Tensor hidden_states, Tensor attn_weight, int layer_idx) { + if (Module::llm_model_ptr->doLoad) { return; } + if (is_prefill()) { + auto chs_pos = chosen_pos_in_each[layer_idx]; + if (pruning_place_cfg.find(layer_idx) != pruning_place_cfg.end()) { + kvcache_ctx.update_hidden_states(hidden_states, layer_idx, original_kv_length, chs_pos, is_prefill()); + chosen_pos_in_each[layer_idx + 1] = select_high_score_visual_token_prefill(attn_weight, layer_idx, chunk_size); + } else { + if (layer_idx + 1 < num_hidden_layers) { + chosen_pos_in_each[layer_idx + 1] = chosen_pos_in_each[layer_idx]; + } + } + } else { + auto chs_pos = chosen_pos_to_delay_compute[layer_idx]; + if (pruning_place_cfg.find(layer_idx) != pruning_place_cfg.end()) { + kvcache_ctx.update_hidden_states(hidden_states, layer_idx, original_kv_length, chs_pos, is_prefill()); + chosen_pos_in_each[layer_idx + 1] = select_high_score_visual_token_decode(attn_weight, layer_idx, chunk_size); + } else { + if (layer_idx + 1 < num_hidden_layers) { + chosen_pos_in_each[layer_idx + 1] = chosen_pos_in_each[layer_idx]; + } + } + } + } + + Tensor prepare_next_layer(int layer_idx, Tensor &position_ids, Tensor &hidden_states, int kv_seq_len) { + if (Module::llm_model_ptr->doLoad) { return hidden_states; } + if (is_prefill()) { + if (pruning_place_cfg.find(layer_idx) != pruning_place_cfg.end()) { + auto this_layer_pos = chosen_pos_in_each[layer_idx]; + auto next_layer_pos = chosen_pos_in_each[layer_idx + 1]; + position_ids = global_position_ids.clip(next_layer_pos, DIMENSION); + std::vector mapping_this_2_next_pos; + for (size_t idx = 0; idx < this_layer_pos.size(); ++idx) { + int value = this_layer_pos[idx]; + if (std::find(next_layer_pos.begin(), next_layer_pos.end(), value) != next_layer_pos.end()) { + mapping_this_2_next_pos.push_back(idx); + } + } + assert(mapping_this_2_next_pos.size() == next_layer_pos.size()); + hidden_states = hidden_states.clip(mapping_this_2_next_pos, SEQUENCE); + } else { + if (layer_idx + 1 < num_hidden_layers) { + auto this_layer_pos = chosen_pos_in_each[layer_idx]; + auto next_layer_pos = chosen_pos_in_each[layer_idx + 1]; + assert(this_layer_pos.size() == next_layer_pos.size()); + assert(std::equal(this_layer_pos.begin(), this_layer_pos.end(), next_layer_pos.begin())); + } + } + } else { + if (pruning_place_cfg.find(layer_idx) != pruning_place_cfg.end()) { + auto this_layer_pos = chosen_pos_in_each[layer_idx]; + auto next_layer_pos = chosen_pos_in_each[layer_idx + 1]; + auto next_layer_kv_cache_not_filled_pos = kvcache_ctx.kv_not_filled_pos(layer_idx + 1, original_kv_length); + std::vector need_to_delay_compute_in_next_layer_pos; + for (int item : next_layer_pos) { + if (std::find(next_layer_kv_cache_not_filled_pos.begin(), + next_layer_kv_cache_not_filled_pos.end(), + item) + != next_layer_kv_cache_not_filled_pos.end()) { + need_to_delay_compute_in_next_layer_pos.push_back(item); + } + } + std::sort(need_to_delay_compute_in_next_layer_pos.begin(), + need_to_delay_compute_in_next_layer_pos.end()); + chosen_pos_to_delay_compute[layer_idx + 1] = need_to_delay_compute_in_next_layer_pos; + if (!need_to_delay_compute_in_next_layer_pos.empty()) { + position_ids = Tensor::cat( + {global_position_ids.clip(need_to_delay_compute_in_next_layer_pos, DIMENSION), + position_ids.clip({}, {}, {}, {-1})}, + DIMENSION); + hidden_states = kvcache_ctx.reset_hidden_states(hidden_states, layer_idx, need_to_delay_compute_in_next_layer_pos); + // mask + int seq = chosen_pos_to_delay_compute[layer_idx + 1].size(); + int dim = kv_seq_len + hidden_states.sequence(); + auto &delay_compute_vec = chosen_pos_to_delay_compute[layer_idx + 1]; + auto &in_each_vec = chosen_pos_in_each[layer_idx + 1]; + Tensor causal_mask(1, num_head, seq + 1, dim, MLLM_CPU, true); + causal_mask.setName("causal_mask_" + std::to_string(layer_idx + 1)); + float min_val = std::numeric_limits::lowest(); + for (int q_side_idx = 0; q_side_idx < seq; ++q_side_idx) { + // 获取当前查询位置对应的值 + int target_value = delay_compute_vec[q_side_idx]; + // 在in_each_vec中查找target_value的位置 + auto it = std::find(in_each_vec.begin(), in_each_vec.end(), target_value); + // 确保找到目标值 + if (it == in_each_vec.end()) { + // 处理未找到的情况 - 可选择报错或跳过 + std::cerr << "Error: target_value not found in chosen_pos_in_each" << std::endl; + continue; // 跳过当前迭代 + } + // 计算在向量中的索引位置 + int start_index = std::distance(in_each_vec.begin(), it) + 1; + // 设置从start_index到末尾的所有元素为min_val + for (int h = 0; h < num_head; h++) { + for (int j = 0; j < start_index; ++j) { + causal_mask.setDataAt(0, h, q_side_idx, j, 0); + } + for (int j = start_index; j < dim; ++j) { + causal_mask.setDataAt(0, h, q_side_idx, j, -INFINITY); + } + } + } + + for (int h = 0; h < num_head; h++) { + memset(causal_mask.ptrAt(0, h, causal_mask.sequence() - 1, 0), + 0, causal_mask.dimension() * sizeof(float)); + } + causal_masks[layer_idx + 1] = causal_mask; + } else { + hidden_states = hidden_states.clip({}, {}, {-1}, {}); + position_ids = position_ids.clip({}, {}, {}, {-1}); + } + } else { + if (layer_idx + 1 < num_hidden_layers) { + auto this_layer_pos = chosen_pos_in_each[layer_idx]; + auto next_layer_pos = chosen_pos_in_each[layer_idx + 1]; + chosen_pos_to_delay_compute[layer_idx + 1] = chosen_pos_to_delay_compute[layer_idx]; + } + } + } + return hidden_states; + } +}; +NdcContext WHERE_TOKEN_PRUNING; + +#endif // NDC_TOOLS_HPP \ No newline at end of file diff --git a/src/models/qwen2_vl/vtp/vtp_tools.hpp b/src/models/qwen2_vl/vtp/vtp_tools.hpp index 168a9cdf0..dde6c315b 100644 --- a/src/models/qwen2_vl/vtp/vtp_tools.hpp +++ b/src/models/qwen2_vl/vtp/vtp_tools.hpp @@ -23,14 +23,16 @@ using namespace mllm; class VtpContext { public: - void init() { + void init(Tensor input_ids, int num_hidden_layers) { + if (input_ids.sequence() <= 1) { + prefill_stage = false; + } else { + prefill_stage = true; + } if (global_selected.backend() == nullptr) global_selected = Tensor(1, 1, 1, 1, MLLM_CPU); } void set_vision_token(Tensor where_idx, Tensor hidden_states, Tensor image_embeds) { - // if (Module::llm_model_ptr->doLoad) { - // return; - // } no_visual_token_len = hidden_states.sequence() - image_embeds.sequence(); global_selected.reshape(1, 1, 1, hidden_states.sequence()); // pre_visual_token_len); global_selected.alloc(); @@ -46,9 +48,6 @@ class VtpContext { no_visual_token_len = hidden_states.sequence() - pre_visual_token_len; } bool is_prefill() { - // if (Module::llm_model_ptr->doLoad) { - // return false; - // } return prefill_stage; } void set_prefill_layer(int layer_idx_) { @@ -142,7 +141,7 @@ class VtpContext { } } } - Tensor prunning_attn_output(Tensor attn_output) { + Tensor prunning_attn_output(Tensor attn_output, int layer_idx) { if (layer_idx == 0) { return attn_output; } @@ -198,7 +197,15 @@ class VtpContext { int HEAD_TOP_K = 3; float ATTN_ACC_ALPHA = 0.2; - map pruning_setting = {{3, 0.5}}; //{{3, 0.5}}; + map pruning_setting = {{3, 0.5}, {8, 0.8}}; + // map pruning_setting = {{3, 0.2}, {9, 0.2}, {12, 0.4}, {18, 0.4}, {21, 0.8}, {26, 0.8}}; + // map pruning_setting = {{3, 0.2}, {9, 0.2}, {12, 0.2}, {18, 0.5}, {21, 0.5}, {26, 0.5}}; + // map pruning_setting = {{3, 0.8}, {9, 0.8}, {12, 0.8}, {18, 0.8}, {21, 0.8}, {26, 0.8}}; + // map pruning_setting = {{3, 0.5}}; + // map pruning_setting = {{3, 0.8}}; + + // 3, 9, 12, 18, 21, 26 + // 0.2, 0.2, 0.4, 0.4, 0.8, 0.8 private: // 实现 topk 功能 diff --git a/src/models/qwen3/modeling_qwen3.hpp b/src/models/qwen3/modeling_qwen3.hpp index 83e304518..9da5c49e9 100644 --- a/src/models/qwen3/modeling_qwen3.hpp +++ b/src/models/qwen3/modeling_qwen3.hpp @@ -60,6 +60,7 @@ class QWen3Attention final : public Module { num_key_value_heads = config.num_key_value_heads; num_key_value_groups = num_heads / num_key_value_heads; rms_norm_eps = config.rms_norm_eps; + attn_impl = config.attn_implementation; // init layers q_proj = Linear(hidden_size, num_heads * head_dim, config.attention_bias, base_name + names._q_proj_name); k_proj = Linear(hidden_size, num_key_value_heads * head_dim, config.attention_bias, @@ -77,8 +78,8 @@ class QWen3Attention final : public Module { base_name + "q_rope"); k_rope = RoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, base_name + "v_cache"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } @@ -104,14 +105,19 @@ class QWen3Attention final : public Module { key_states = k_cache(key_states); value_states = v_cache(value_states); - // attention weight - auto atten_weight = - Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) - / std::sqrt(head_dim); - atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); + Tensor atten_output; + if (attn_impl == "flash_attention_2") { + atten_output = Tensor::flash_attention2_forward(query_states, key_states, value_states, true); + } else { // eager implementation + // attention weight + auto atten_weight = + Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) + / std::sqrt(head_dim); + atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); - // attention output - auto atten_output = Tensor::mm(atten_weight, value_states); + // attention output + atten_output = Tensor::mm(atten_weight, value_states); + } atten_output = atten_output.view(-1, 1, -1, head_dim * num_heads); atten_output = o_proj(atten_output); return {atten_output}; @@ -143,6 +149,7 @@ class QWen3Attention final : public Module { KVCache v_cache; // Causalmask mask; Softmax softmax; + string attn_impl; }; class QWen3Decoder final : public Module { diff --git a/src/models/smollm/modeling_smollm.hpp b/src/models/smollm/modeling_smollm.hpp index 86d8d6ca8..c09621a42 100644 --- a/src/models/smollm/modeling_smollm.hpp +++ b/src/models/smollm/modeling_smollm.hpp @@ -50,9 +50,8 @@ class SmolLMBlock final : public Module { public: SmolLMBlock() = default; - SmolLMBlock(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, const SmolLMNameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_NONE, false, false, - RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, names, base_name + names._attn_base_name); + SmolLMBlock(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const SmolLMNameConfig &names, const string &base_name) { + attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_NONE, false, false, RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, attn_implementation, names, base_name + names._attn_base_name); mlp = SmolLMMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); norm2 = RMSNorm(hidden_dim, 1e-6, base_name + names._ffn_norm_name); @@ -81,13 +80,13 @@ class SmolLMModel final : public Module { public: explicit SmolLMModel(const SmolLMConfig &config) : SmolLMModel(config.vocab_size, config.hidden_dim, config.head_size, config.num_key_value_heads, config.ffn_hidden, config.block_num, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, config.attn_implementation, config.names_config, config.names_config.blk_name) { } - SmolLMModel(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, + SmolLMModel(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const SmolLMNameConfig &names, const string &base_name) { embedding = Embedding(vocab_size, hidden_dim, names.token_embd_name); - blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, names, base_name); + blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, attn_implementation, names, base_name); norm = RMSNorm(hidden_dim, 1e-6, names.post_norm_name); lm_head = Parameter(1, vocab_size, 1, hidden_dim, names.token_embd_name + ".weight"); diff --git a/src/models/stablelm/modeling_stablelm.hpp b/src/models/stablelm/modeling_stablelm.hpp index 8033689e8..6a0acc582 100644 --- a/src/models/stablelm/modeling_stablelm.hpp +++ b/src/models/stablelm/modeling_stablelm.hpp @@ -22,15 +22,17 @@ class StableLMMultiHeadAttention final : public Module { int kv_head_size_{}; int attn_hidden_dim_{}; Chl split_chl_{}; + string attn_impl; public: StableLMMultiHeadAttention() = default; StableLMMultiHeadAttention(int hidden_dim, int head_size, int kv_head_size, int attn_hidden_dim, - RoPEType RoPE_type, int cache_limit, bool do_mask, bool bias, + RoPEType RoPE_type, int cache_limit, bool do_mask, bool bias, string attn_implementation, const TransformerNameConfig &names, const string &base_name) { attn_hidden_dim_ = attn_hidden_dim; head_size_ = head_size; kv_head_size_ = kv_head_size; + attn_impl = attn_implementation; q_proj = Linear(hidden_dim, head_size * attn_hidden_dim, bias, base_name + names._q_proj_name); k_proj = Linear(hidden_dim, kv_head_size * attn_hidden_dim, bias, base_name + names._k_proj_name); v_proj = Linear(hidden_dim, kv_head_size * attn_hidden_dim, bias, base_name + names._v_proj_name); @@ -39,8 +41,8 @@ class StableLMMultiHeadAttention final : public Module { k_rope = RoPE(RoPE_type, 10000, 0.25, 4096, base_name + "k_rope"); } if (cache_limit > 0) { - k_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, base_name + "k_cache"); - v_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, base_name + "v_cache"); + k_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); } softmax = Softmax(DIMENSION, do_mask, base_name + "softmax"); o_proj = Linear(head_size * attn_hidden_dim, hidden_dim, false, base_name + names._o_proj_name); @@ -61,11 +63,17 @@ class StableLMMultiHeadAttention final : public Module { k = k_cache(k); v = v_cache(v); } - k = k.transpose(SEQUENCE, DIMENSION); - auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(attn_hidden_dim_); - qk = softmax(qk, k_cache.getCacheSeqLen()); - auto o = Tensor::mm(qk, v); + + Tensor o; + if (attn_impl == "flash_attention_2") { + o = Tensor::flash_attention2_forward(q, k, v, true); + } else { // eager implementation + k = k.transpose(SEQUENCE, DIMENSION); + auto qk = Tensor::mm(q, k); + qk = qk / std::sqrt(attn_hidden_dim_); + qk = softmax(qk, k_cache.getCacheSeqLen()); + o = Tensor::mm(qk, v); + } o = o.view(-1, 1, -1, attn_hidden_dim_ * head_size_); o = o_proj(o); return {o}; @@ -104,9 +112,10 @@ class StableLMBlock final : public Module { public: StableLMBlock() = default; - StableLMBlock(int hidden_dim, int head_size, int ffn_hidden, RoPEType RoPE_type, int cache_limit, const stablelmNameConfig &names, const string &base_name) { + StableLMBlock(int hidden_dim, int head_size, int ffn_hidden, RoPEType RoPE_type, int cache_limit, string attn_implementation, const stablelmNameConfig &names, const string &base_name) { attention = StableLMMultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, - RoPE_type, cache_limit, true, true, names, base_name + names._attn_base_name); + RoPE_type, cache_limit, true, true, attn_implementation, + names, base_name + names._attn_base_name); mlp = StableLMMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = LayerNorm(hidden_dim, true, 1e-5, base_name + names._attn_norm_name); norm2 = LayerNorm(hidden_dim, true, 1e-5, base_name + names._ffn_norm_name); @@ -130,13 +139,11 @@ class StableLMModel final : public Module { public: explicit StableLMModel(const StableLMConfig &config) : - StableLMModel(config.vocab_size, config.hidden_dim, config.head_size, config.ffn_hidden, config.block_num, config.RoPE_type, config.cache_limit, - config.names_config, config.names_config.blk_name) { + StableLMModel(config.vocab_size, config.hidden_dim, config.head_size, config.ffn_hidden, config.block_num, config.RoPE_type, config.cache_limit, config.attn_implementation, config.names_config, config.names_config.blk_name) { } - StableLMModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, int cache_limit, - const stablelmNameConfig &names, const string &base_name) { + StableLMModel(int vocab_size, int hidden_dim, int head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, int cache_limit, string attn_implementation, const stablelmNameConfig &names, const string &base_name) { embedding = Embedding(vocab_size, hidden_dim, names.token_embd_name); - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, RoPE_type, cache_limit, names, base_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, RoPE_type, cache_limit, attn_implementation, names, base_name); norm = LayerNorm(hidden_dim, true, 1e-5, names.post_norm_name); lm_head = Linear(hidden_dim, vocab_size, false, names.lm_head_name); } diff --git a/src/models/tinyllama/modeling_tinyllama.hpp b/src/models/tinyllama/modeling_tinyllama.hpp index 3d54d6cf4..69facdf51 100644 --- a/src/models/tinyllama/modeling_tinyllama.hpp +++ b/src/models/tinyllama/modeling_tinyllama.hpp @@ -20,9 +20,12 @@ class TinyLLaMABlock final : public Module { public: TinyLLaMABlock() = default; - TinyLLaMABlock(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, const LLaMANameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_NONE, false, false, - RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, names, base_name + names._attn_base_name); + TinyLLaMABlock(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const LLaMANameConfig &names, const string &base_name) { + attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, + hidden_dim / head_size, SPLIT_NONE, false, false, + RoPE_type, rope_theta, max_position_embeddings, + cache_limit, true, false, + attn_implementation, names, base_name + names._attn_base_name); mlp = LLaMAMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); norm2 = RMSNorm(hidden_dim, 1e-6, base_name + names._ffn_norm_name); @@ -46,15 +49,15 @@ class TinyLLaMAModel final : public Module { public: explicit TinyLLaMAModel(const TinyLLaMAConfig &config) : - TinyLLaMAModel(config.vocab_size, config.hidden_dim, config.head_size, config.kv_head_size, config.ffn_hidden, config.block_num, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, + TinyLLaMAModel(config.vocab_size, config.hidden_dim, config.head_size, config.kv_head_size, config.ffn_hidden, config.block_num, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, config.attn_implementation, config.names_config, config.names_config.blk_name) { } - TinyLLaMAModel(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, - RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, + TinyLLaMAModel(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, + RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const LLaMANameConfig &names, const string &base_name) { embedding = Embedding(vocab_size, hidden_dim, names.token_embd_name); - blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, names, base_name); + blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, attn_implementation, names, base_name); norm = RMSNorm(hidden_dim, 1e-6, names.post_norm_name); lm_head = Linear(hidden_dim, vocab_size, false, names.lm_head_name); } diff --git a/src/models/transformer/configuration_transformer.hpp b/src/models/transformer/configuration_transformer.hpp index 042e0f97f..c425bb768 100644 --- a/src/models/transformer/configuration_transformer.hpp +++ b/src/models/transformer/configuration_transformer.hpp @@ -37,5 +37,6 @@ class TransformerConfig { public: TransformerConfig() { } + string attn_implementation = "flash_attention_2"; // Options: "flash_attention_2", "eager" }; #endif // CONFIGURATION_TRANSFORMER_HPP diff --git a/src/models/transformer/modeling_transformer.hpp b/src/models/transformer/modeling_transformer.hpp index dbc601ce2..b243f46d5 100644 --- a/src/models/transformer/modeling_transformer.hpp +++ b/src/models/transformer/modeling_transformer.hpp @@ -31,6 +31,8 @@ class MultiHeadAttention final : public Module { int kv_head_size_{}; int attn_hidden_dim_{}; Chl split_chl_{}; + bool causal_mask = true; + string attn_implementation_ = "flash_attention_2"; // Options: "flash_attention_2", "eager" public: MultiHeadAttention() = default; @@ -38,10 +40,13 @@ class MultiHeadAttention final : public Module { AttnQKVSplitType do_qkv_proj, bool post_qkv_norm, bool bias_kv_cat, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, bool do_mask, bool bias, + string attn_implementation, const TransformerNameConfig &names, const string &base_name) { attn_hidden_dim_ = attn_hidden_dim; head_size_ = head_size; kv_head_size_ = kv_head_size; + causal_mask = do_mask; + attn_implementation_ = attn_implementation; if (do_qkv_proj > 0) { qkv_proj = Linear(hidden_dim, head_size * attn_hidden_dim * 3, bias, base_name + names._qkv_proj_name); split_chl_ = (Chl)do_qkv_proj; @@ -59,8 +64,12 @@ class MultiHeadAttention final : public Module { k_rope = RoPE(RoPE_type, rope_theta, max_position_embeddings, base_name + "k_rope"); } if (cache_limit > 0) { - k_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, base_name + "k_cache"); - v_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, base_name + "v_cache"); + k_cache = KVCache(kv_head_size, attn_hidden_dim, + head_size / kv_head_size, cache_limit, + (attn_implementation_ == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(kv_head_size, attn_hidden_dim, + head_size / kv_head_size, cache_limit, + (attn_implementation_ == "flash_attention_2"), base_name + "v_cache"); } softmax = Softmax(DIMENSION, do_mask, base_name + "softmax"); o_proj = Linear(head_size * attn_hidden_dim, hidden_dim, bias, base_name + names._o_proj_name); @@ -101,15 +110,20 @@ class MultiHeadAttention final : public Module { k = k_cache(k); v = v_cache(v); } - k = k.transpose(SEQUENCE, DIMENSION); - auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(attn_hidden_dim_); - if (k_cache.ready() && v_cache.ready()) { - qk = softmax(qk, k_cache.getCacheSeqLen()); - } else { - qk = softmax(qk); + Tensor o; + if (attn_implementation_ == "flash_attention_2") { + o = Tensor::flash_attention2_forward(q, k, v, causal_mask); + } else { // eager implementation + k = k.transpose(SEQUENCE, DIMENSION); + auto qk = Tensor::mm(q, k); + qk = qk / std::sqrt(attn_hidden_dim_); + if (k_cache.ready() && v_cache.ready()) { + qk = softmax(qk, k_cache.getCacheSeqLen()); + } else { + qk = softmax(qk); + } + o = Tensor::mm(qk, v); } - auto o = Tensor::mm(qk, v); o = o.view(-1, 1, -1, attn_hidden_dim_ * head_size_); o = o_proj(o); return {o}; diff --git a/src/models/vit/modeling_vit.hpp b/src/models/vit/modeling_vit.hpp index a2a97915d..a26634132 100644 --- a/src/models/vit/modeling_vit.hpp +++ b/src/models/vit/modeling_vit.hpp @@ -37,10 +37,11 @@ class ViTBlock final : public Module { public: ViTBlock() = default; - ViTBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, const ViTNameConfig &names, const string &base_name) { + ViTBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, + string attn_implementation, const ViTNameConfig &names, const string &base_name) { attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, SPLIT_NONE, false, false, RoPEType::NONE, - -1, -1, 0, false, true, + -1, -1, 0, false, true, attn_implementation, names, base_name + names._attn_base_name); mlp = ViTMLP(hidden_dim, ffn_hidden, act_fn_type, names, base_name + names._ffn_base_name); down_proj = Linear(ffn_hidden, hidden_dim, true, base_name + names._down_proj_name); @@ -89,13 +90,11 @@ class ViTModel final : public Module { public: explicit ViTModel(const ViTConfig &config) : - ViTModel(config.hidden_dim, config.head_size, config.ffn_hidden, config.act_fn_type, config.patch, config.img_hw, config.block_num, config.class_size, - config.names_config, config.names_config.vison_model_name) { + ViTModel(config.hidden_dim, config.head_size, config.ffn_hidden, config.act_fn_type, config.patch, config.img_hw, config.block_num, config.class_size, config.attn_implementation, config.names_config, config.names_config.vison_model_name) { } - ViTModel(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, int patch, int img_hw, int block_num, int class_size, - const ViTNameConfig &names, const string &base_name) { + ViTModel(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, int patch, int img_hw, int block_num, int class_size, string attn_implementation, const ViTNameConfig &names, const string &base_name) { embedding = ViTEmbedding(hidden_dim, patch, img_hw, names, base_name + names._embd_name); - blocks = List(block_num, hidden_dim, head_size, ffn_hidden, act_fn_type, names, base_name + names._layer_name); + blocks = List(block_num, hidden_dim, head_size, ffn_hidden, act_fn_type, attn_implementation, names, base_name + names._layer_name); norm = LayerNorm(hidden_dim, true, 1e-6, base_name + names._post_norm_name); lm_head = Linear(hidden_dim, class_size, false, names.lm_head_name); } diff --git a/tools/convertor/profiling_activation/export_int8_model.py b/tools/convertor/profiling_activation/export_int8_model.py index 825cc69aa..b5c51065d 100644 --- a/tools/convertor/profiling_activation/export_int8_model.py +++ b/tools/convertor/profiling_activation/export_int8_model.py @@ -58,7 +58,14 @@ def quantize_weight_per_tensor_absmax(w, n_bits=8): act_dict = args.scale_file.name t01m_clip_threshold = args.t01m_clip_threshold - model = AutoModelForCausalLM.from_pretrained(model_name) + if args.model_type != "qwen2vl": + model = AutoModelForCausalLM.from_pretrained(model_name) + else: + from transformers import Qwen2VLForConditionalGeneration + model = Qwen2VLForConditionalGeneration.from_pretrained( + model_name + ) + act_dict = json.load(open(act_dict)) act_scales, clip_top, return_dict = get_clip_and_scale( @@ -77,6 +84,8 @@ def quantize_weight_per_tensor_absmax(w, n_bits=8): q_model = quantize_llama_like(model, act_scales, layer_clip=clip_top) elif args.model_type == "qwen2" or args.model_type == "qwen1": q_model = quantize_qwen2_like(model, act_scales, layer_clip=clip_top) + elif args.model_type == "qwen2vl": + q_model = quantize_qwen2vl_like(model, act_scales, layer_clip=clip_top) elif args.model_type == "gemma": q_model = quantize_gemma_like(model, act_scales, layer_clip=clip_top) elif args.model_type == "phi": diff --git a/tools/convertor/profiling_activation/utils/quantization_simulation.py b/tools/convertor/profiling_activation/utils/quantization_simulation.py index 716d2c7f3..eeb5367f0 100644 --- a/tools/convertor/profiling_activation/utils/quantization_simulation.py +++ b/tools/convertor/profiling_activation/utils/quantization_simulation.py @@ -374,6 +374,68 @@ def quantize_qwen2_like( ) return model +def quantize_qwen2vl_like( + model, + decoder_scales, + weight_quant="per_tensor", + act_quant="per_tensor", + quantize_bmm_input=False, + layer_clip={}, +): + from transformers.models.qwen2_vl.modeling_qwen2_vl import ( + Qwen2VLSdpaAttention, + Qwen2MLP, + ) + + for name, m in model.model.named_modules(): + if isinstance(m, Qwen2MLP): + m.gate_proj = W8A8LinearStatic.from_float( + m.gate_proj, + decoder_scales["model." + name + ".gate_proj"], + weight_quant_type=weight_quant, + clip_top=layer_clip["model." + name + ".gate_proj"], + ) + m.up_proj = W8A8LinearStatic.from_float( + m.up_proj, + decoder_scales["model." + name + ".up_proj"], + weight_quant_type=weight_quant, + clip_top=layer_clip["model." + name + ".up_proj"], + ) + m.down_proj = W8A8LinearStatic.from_float( + m.down_proj, + decoder_scales["model." + name + ".down_proj"], + weight_quant_type=weight_quant, + clip_top=layer_clip["model." + name + ".down_proj"], + ) + elif isinstance(m, Qwen2VLSdpaAttention): + # Here we simulate quantizing BMM inputs by quantizing the output of q_proj, k_proj, v_proj + m.q_proj = W8A8LinearStatic.from_float( + m.q_proj, + decoder_scales["model." + name + ".q_proj"], + weight_quant_type=weight_quant, + clip_top=layer_clip["model." + name + ".q_proj"], + ) + m.k_proj = W8A8LinearStatic.from_float( + m.k_proj, + decoder_scales["model." + name + ".k_proj"], + weight_quant_type=weight_quant, + clip_top=layer_clip["model." + name + ".k_proj"], + ) + m.v_proj = W8A8LinearStatic.from_float( + m.v_proj, + decoder_scales["model." + name + ".v_proj"], + weight_quant_type=weight_quant, + clip_top=layer_clip["model." + name + ".v_proj"], + ) + + m.o_proj = W8A8LinearStatic.from_float( + m.o_proj, + decoder_scales["model." + name + ".o_proj"], + weight_quant_type=weight_quant, + clip_top=layer_clip["model." + name + ".o_proj"], + ) + return model + def quantize_gemma_like( model, diff --git a/tools/jni/LibHelper.cpp b/tools/jni/LibHelper.cpp index 4c5819360..cfa08047a 100644 --- a/tools/jni/LibHelper.cpp +++ b/tools/jni/LibHelper.cpp @@ -32,7 +32,7 @@ using namespace mllm; #ifdef USE_QNN #include "models/qwen/modeling_qwen_npu.hpp" #include "models/phonelm/modeling_phonelm_npu.hpp" - +#include "models/qwen2_vl/modeling_qwen2_vl_npu.hpp" #endif inline bool exists_test(const std::string &name) { std::ifstream f(name.c_str()); @@ -55,7 +55,18 @@ unsigned int LibHelper::postProcessing(shared_ptr result, shared_ptr(qwconfig, chunk_size); + prefill_module_ = make_shared(qwconfig, chunk_size); prefill_module_->load(qnn_weights_path); auto tokenizer = dynamic_pointer_cast(tokenizer_); @@ -120,7 +131,23 @@ bool LibHelper::setUp(const std::string &base_path, std::string weights_path, st break; case QWEN2VL: processor_ = new Qwen2VLProcessor(vocab_path, merge_path); - module_ = make_shared(qwvlconfig); + LOGI("Init Qwen2VLProcessor: %d", backend_type); +#ifdef USE_QNN + if (backend_type == MLLMBackendType::QNN) { + int chunk_size = 256; + prefill_module_ = make_shared(qwvlconfig, chunk_size); + prefill_module_->load(qnn_weights_path); + prefill_embedding_ = make_shared(qwvlconfig); + prefill_embedding_->load(weights_path); + qwvlconfig.attn_implementation = "eager"; + module_ = make_shared(qwvlconfig); + } else { +#endif + module_ = make_shared(qwvlconfig); + +#ifdef USE_QNN + } +#endif break; case Bert: tokenizer_ = make_shared(vocab_path, true); @@ -318,26 +345,148 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u } module_->clear_kvcache(); } else if (model_ == QWEN2VL) { - auto model = dynamic_cast(module_.get()); auto processor = dynamic_cast(processor_); input_str = "Based on the screenshot of the page, I give a text description and you give its corresponding location. The coordinate represents a clickable location [x, y] for an element, which is a relative coordinate on the screenshot, scaled from 0 to 1.<|vision_start|><|image_pad|><|vision_end|>" + input_str; input_str = processor->tokenizer->apply_chat_template(input_str); auto input_tensors = processor->process(input_str, {image}, {image_length}); LOGE("Instruct: %s", input_str.c_str()); LOGE("Tokens: %d", input_tensors[0].sequence()); - for (int step = 0; step < 100; step++) { - model->get_position_ids(input_tensors); - auto result = (*model)(input_tensors); - auto outputs = processor->detokenize(result[0]); - auto out_string = outputs.first; - auto out_token = outputs.second; - auto [end, string] = processor->tokenizer->postprocess(out_string); - output_string_ += string; - callback_(output_string_, !end, {}); - if (!end) { break; } + +#ifdef USE_QNN + if (backend_ == MLLMBackendType::QNN) { + int chunk_size = 256; + + const int real_seq_length = input_tensors[0].sequence(); + const int num_iter = (real_seq_length + chunk_size - 1) / chunk_size; + auto model = dynamic_cast(module_.get()); + auto prefill_embedding = dynamic_cast(prefill_embedding_.get()); + // padding the position_ids to total chunk length(example: 256*2) for CPUMultimodalRoPEPipeline + LOGE("before get_position_ids"); + prefill_embedding->get_position_ids(input_tensors, chunk_size * num_iter); + LOGE("after get_position_ids"); + + // warm up (still need a warm up as the setup stage is not omitted now) + auto merged_embd_warmup_tensor = Tensor(Backend::global_backends[MLLM_QNN]); + merged_embd_warmup_tensor.reshape(1, 1, chunk_size, 1536); + merged_embd_warmup_tensor.setTtype(INPUT_TENSOR); + merged_embd_warmup_tensor.alloc(); + merged_embd_warmup_tensor.setTtype(INPUT_TENSOR); + input_tensors.back().setTtype(INPUT_TENSOR); + vector prefill_input = {merged_embd_warmup_tensor, input_tensors.back()}; + (*prefill_module_)(prefill_input); + LOGE("after warm up"); + + Module::isFirstChunk = false; + static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + + // set total seq length for HeadLinear execute, which can not get the real seq length from Opts + static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts + static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + + for (auto &t : input_tensors) { + t.setTtype(INPUT_TENSOR); + } + + // 1. get the vit embedding using CPU + auto merged_embd = (*prefill_embedding)(input_tensors); + LOGE("after vit embedding"); + + // free prefill embedding tensor, approximately free 1GB for 59ms + auto begin_free = mllm_time_ms(); + auto &embedding_act = prefill_embedding->activation_tensors; + // go through the activation tensors to get the merged_embd + for (auto iter = embedding_act.begin(); iter != embedding_act.end(); ++iter) { + // std::cout << iter->first << std::endl; + if (iter->first.find("input") != std::string::npos || iter->first.find("index_put") != std::string::npos) { + continue; + } + iter->second->free(); + } + auto end_free = mllm_time_ms(); + LOGE("after free"); + + // 2. QNN LLM Prefill + unsigned int out_token = 0; + for (auto i = 0; i < num_iter; ++i) { + // copy the data from merged_embd[0] to merged_embd_warmup_tensor + auto source = merged_embd[0].ptrAt(0, 0, chunk_size * i, 0); + auto dest = prefill_input[0].hostPtr(); + if (i == 0) { + memcpy(dest, source, prefill_input[0].cntSize()); + } + { + memcpy(dest, source, (merged_embd[0].sequence() % chunk_size) * merged_embd[0].dimension() * sizeof(float)); + } + + auto result = (*prefill_module_)(prefill_input); + + if (i == 0) { // turn off switching to avoid RoPE h_cnt_ reset to curSequenceLength in next chunk + static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + } + + if (i == 1) { + auto outputs = processor->detokenize(result[0], real_seq_length % chunk_size); + auto out_string = outputs.first; + out_token = outputs.second; + // auto [not_end, output_string] = processor->tokenizer->postprocess(out_string); + // std::cout << output_string << std::flush; + auto [end, string] = processor->tokenizer->postprocess(out_string); + output_string_ += string; + callback_(output_string_, !end, {}); + } + } + chatPostProcessing(out_token, input_tensors[0], {&input_tensors[1], &input_tensors[2]}); + + static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + + // 3. CPU LLM Decoding + for (auto &t : input_tensors) { // set to INPUT_TENSOR to let decoding module update act + t.setTtype(INPUT_TENSOR); + } + + const int last_position_id = input_tensors[3].dataAt(0, 0, 0, real_seq_length - 1); + for (int step = 0; step < 100; step++) { + // use the last position id(no padding position) in decoding + prefill_embedding->get_position_ids(input_tensors, 0, last_position_id + 1 + step); + + auto result = (*model)(input_tensors); + auto outputs = processor->detokenize(result[0]); + auto out_string = outputs.first; + auto out_token = outputs.second; + auto [end, string] = processor->tokenizer->postprocess(out_string); + output_string_ += string; + callback_(output_string_, !end, {}); + if (!end) { break; } + chatPostProcessing(out_token, input_tensors[0], {&input_tensors[1], &input_tensors[2]}); + if (step == 0) static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + } + + std::cout << std::endl; + } else { +#endif + auto model = dynamic_cast(module_.get()); + for (int step = 0; step < 100; step++) { + model->get_position_ids(input_tensors); + auto result = (*model)(input_tensors); + auto outputs = processor->detokenize(result[0]); + auto out_string = outputs.first; + auto out_token = outputs.second; + auto [end, string] = processor->tokenizer->postprocess(out_string); + output_string_ += string; + callback_(output_string_, !end, {}); + if (!end) { break; } + chatPostProcessing(out_token, input_tensors[0], {&input_tensors[1], &input_tensors[2]}); + } + module_->clear_kvcache(); +#ifdef USE_QNN } - module_->clear_kvcache(); +#endif } else if (model_ == Bert) { LOGE("Bert model is not supported in this version."); } else if (model_ == PhoneLM) { diff --git a/tools/jni/LibHelper.hpp b/tools/jni/LibHelper.hpp index 98791ae3d..97431528a 100644 --- a/tools/jni/LibHelper.hpp +++ b/tools/jni/LibHelper.hpp @@ -47,6 +47,7 @@ class LibHelper { PreProcessor *processor_; std::shared_ptr module_; std::shared_ptr prefill_module_; + std::shared_ptr prefill_embedding_; // Tokenizer *tokenizer_ = nullptr; unsigned int eos_id_ = 2; From 8476dd0a36687667eb1c68cb00c70c0d7ba98ab9 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Tue, 27 May 2025 16:14:39 +0000 Subject: [PATCH 02/22] Squashed commit of the following: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit efde6d0d014b647b8ceea59441aef1bd3ac424c0 Author: yirongjie Date: Tue May 27 16:09:16 2025 +0000 fix: merge commit fe7fb476717e99df2eac23ab7fd1088e03cf8b3c Merge: f52bb32e 20e94c06 Author: yirongjie Date: Tue May 27 16:09:08 2025 +0000 Merge branch 'main' of https://github.com/yirongjie/mllm commit f52bb32e5dbf4edcd4998d664ae071a1b5c8dbbb Author: yirongjie Date: Tue May 27 12:25:08 2025 +0000 fix: merge from qnn-qwen2vl; commit 6f6c2442f750363c6789e7717861ea3a216cf356 Author: yirongjie Date: Tue May 27 12:24:17 2025 +0000 Squashed commit of the following: commit 4862c764505dce2fdb5155036d0de724e475c799 Author: oreomaker Date: Thu May 15 14:59:37 2025 +0800 refact: use hvx qnn silu(faster); usable showui npu version commit 5df1b07cfbe3d4b5bbc09318b92ee17da262f897 Author: oreomaker Date: Wed May 14 22:10:52 2025 +0800 feat: qnn dequantize_add hvx op commit c813f55975bc35946bbeafbbc0349b013f25c840 Author: oreomaker Date: Tue May 13 09:50:06 2025 +0800 chore: format qnn op package code commit ea215f0320d32a271a4a0789a54d4b0d5c294c54 Author: oreomaker Date: Mon May 12 11:34:38 2025 +0800 feat: free act tensors after qnn vit embedding commit e4f50119ad2f78fff1175276c0760c3a20ea256c Author: oreomaker Date: Mon May 12 11:14:30 2025 +0800 chore: remove save data in modeling qwen2vlnpu commit 2dcb67798c8df48cbd7b78e0b7c979c5f24736f4 Author: oreomaker Date: Mon May 12 10:48:34 2025 +0800 fix: seperate weights for embedding-lmhead when using rotated qwen2vl/showui commit 484731856a3f18f670295b7fa744822ad254f515 Author: oreomaker Date: Sun May 11 21:16:59 2025 +0800 fix: cpu tensor free bug(todo: handle tensor free) commit 799b6734b2f241402a42c365139c56dea7b2ec64 Author: xudaliang Date: Sat May 10 22:51:11 2025 +0800 feat : new qwen2_vl model. commit dd1817d2bf7a69fd26691776336bdd205c15eee9 Author: xudaliang Date: Sat May 10 22:50:35 2025 +0800 feat : support qwen2-vl rotation model with fp bias. commit 305dc5cc9df7fddc32b3f0484463f529097785de Author: oreomaker Date: Thu May 8 21:37:35 2025 +0800 feat: runnable qwen2vl qnn showui(2*256) commit 8e148156a05a122d1b883f0ef8dd84693e151cdc Author: oreomaker Date: Thu May 8 21:36:33 2025 +0800 fix: pre processing of qwen2vl commit e041296c97eac7af600b42ab3255f9b90f7acbfe Author: oreomaker Date: Thu May 8 21:34:07 2025 +0800 refact: qwen vl npu modeling using closetFactor view(64->8x8) feat: get_position_id padding in Qwen2VL_ImagePatchAndEmbedding commit 5b17204b1a9bd1c3c96e2c2d7f2014c5f0624f1e Author: oreomaker Date: Thu May 8 21:29:13 2025 +0800 feat: vit(visual_xx) tensor reuse for qnn (noted as: QNN VLM trick) commit 7c426584baeb1eed60dd392ee1edd651667eaab3 Author: oreomaker Date: Thu May 8 21:26:49 2025 +0800 feat: finish cpu pipeline mrope commit 0962c0051b110925bf191a180f13a24eaba2303e Author: oreomaker Date: Tue May 6 11:39:29 2025 +0800 feat: pipeline multimodal rope commit 53179338623e4d74306b3c73fb5993291c289305 Author: oreomaker Date: Tue May 6 11:38:10 2025 +0800 refactor: use old&fast qnn silu commit 5bd14def5bcb64fedda80e14cc9874ee37d6caf6 Author: oreomaker Date: Mon Apr 28 21:10:48 2025 +0800 feat: runnable qwen 2 vl npu commit 1df6eedb738ea2f3f079f49762c8dcafda721498 Author: oreomaker Date: Sun Apr 27 10:13:44 2025 +0800 refactor: tensor.to(QNN) commit d3d29c4a900428cf7e22244bc7860fd85c3bde5b Author: oreomaker Date: Sat Apr 26 21:22:52 2025 +0800 chore: remove saveData in qwen2vl modeling commit c40e0c0fcb3e748b5d19bcc193f8bf47ac0fe33b Author: oreomaker Date: Sat Apr 26 20:51:16 2025 +0800 feat: add qnn retrieve context info log commit 175d3a21b0b65186305a761d0417fe3a981e8fbc Author: oreomaker Date: Sat Apr 26 20:46:14 2025 +0800 fix: qwen 2 vl npu input tensor backend(correct version) commit 871e920ea1b9eda62fb39d8bc42b7378fd1cc7fa Author: oreomaker Date: Fri Apr 25 09:50:05 2025 +0800 fix: quantize i16 arm neon macro commit a2b802c81c99a55a1e99bd36a52ea3995efb27e0 Author: xudaliang Date: Wed Apr 23 18:33:26 2025 +0800 fix : Qwen2-VL prefill bugs: 1.FP32 KVCache. 2.LMHead does not execute. commit 8c666041e9962292101b4747fb450f82a2cf54d9 Author: oreomaker Date: Fri Apr 18 15:35:03 2025 +0800 fix: restore qwen2.5 modeling commit f138bebef7f97742543e111877d3d004d0f8515a Author: oreomaker Date: Fri Apr 18 15:28:35 2025 +0800 fix: restore debug change commit 09e12ced5efb91f40a5291f28e92e4cd9db38f20 Merge: d725942b 9b271a99 Author: oreomaker Date: Fri Apr 18 13:39:10 2025 +0800 Merge branch 'debug-qwen2.5' of github.com:liang1232018/mllm into debug-qwen2.5 commit d725942b304f41637ecc1dcea72eb7571a3846be Author: oreomaker Date: Fri Apr 18 13:39:04 2025 +0800 dev: qnn sigmoid version silu feat: qnn backend f16 type input commit 9b271a9973d8870e48eb9ce3aca5041908fa13b0 Author: xudaliang Date: Fri Apr 18 13:24:52 2025 +0800 fix : linear W8A8 bias uint8 type bug commit 793a6c6c678f392895245903f36b1c3bfab38de9 Author: xudaliang Date: Fri Apr 18 13:23:49 2025 +0800 fix : Shadow linear triger condition. commit 4e24bca3fcc3e10214e361d459d27de9c4e62f2e Author: oreomaker Date: Wed Apr 16 20:53:07 2025 +0800 qwen 2.5 debug commit 4d747562dfbd1b544b33bd7297f2dcf2495edc35 Author: oreomaker Date: Wed Apr 16 20:52:33 2025 +0800 fix: shadow linear commit 5866e2bcd1eff3dfbc6d35353c053cab5c227bfb Author: oreomaker Date: Tue Apr 15 22:17:12 2025 +0800 qwen 2.5 debug commit 29e9b92afea6758eb42dfa298efedaa9ec31304c Author: oreomaker Date: Mon Apr 14 09:28:45 2025 +0800 fix: remove shadow linear if(round_value) logic commit a61e837c0885672200431c270f83818d70e048a2 Author: oreomaker Date: Sun Apr 13 22:03:45 2025 +0800 feat: int16 qkv for qwen2.5 vl npu commit 566f21dfc63a80b8f8b91926d657c28ed870fd7b Author: xudaliang Date: Sun Apr 13 18:45:06 2025 +0800 fix : modeling input quantize to I8, but dequantize with I16 bug. commit 60639d063c4659f9aa70f62b1be80050d7584153 Author: xudaliang Date: Sun Apr 13 18:44:18 2025 +0800 fix : LLaMADequantize INT16 to FP32 shuffle order bugs. commit a5cc652ad1f35730957d8be8ada8cecc6eabba6f Author: xudaliang Date: Sun Apr 13 17:31:10 2025 +0800 fix : LLaMAQuantize FP32 to INT16 round scale error. commit f1398225e0b53c3fc743a1eb44bd3b224ca59adf Author: oreomaker Date: Sat Apr 12 22:24:30 2025 +0800 fix: qnn int 16 linear bias(use int8 bias scale) commit 883181191c17a440b021006d484f345992c8d84c Author: oreomaker Date: Sat Apr 12 15:03:40 2025 +0800 debug: qnn int16 linear commit 088fe09cb999a8a48794c922971a82b08107bdca Author: xudaliang Date: Fri Apr 11 23:22:41 2025 +0800 feat : support INT16 dequantize and quantize. commit 73ebe87ab352505465b0a079bdc00e7d8ded93ff Merge: b73c1c34 6007443d Author: liang1232018 <40791416+liang1232018@users.noreply.github.com> Date: Wed Apr 9 14:50:25 2025 +0800 Merge pull request #12 from liang1232018/develop-zh Develop zh commit 6007443d3e00fdf7df2079bb669eafde507ba575 Merge: 1c8647e9 b73c1c34 Author: liang1232018 <40791416+liang1232018@users.noreply.github.com> Date: Wed Apr 9 14:50:07 2025 +0800 Merge branch 'develop-xdl' into develop-zh commit 1c8647e9f1ba295dfc127e36e5a40076fc26bf07 Author: oreomaker Date: Tue Apr 8 21:39:56 2025 +0800 fix: qnn quant scale pow(2,bit) -> pow(2,bit-1) commit cc760aeedefc5f98a988815e77c5ef46eb18497a Author: oreomaker Date: Tue Apr 8 17:03:17 2025 +0800 fix: op create param type->dtype commit 6afa80ce69c4a91dd9a504dfe3e1af935e07019f Author: oreomaker Date: Mon Apr 7 15:25:21 2025 +0800 feat: Tensor::saveData only do when STATIC_READY commit 2ebded3526913e45f0b9927145a9313062bc56a2 Author: oreomaker Date: Mon Apr 7 15:24:11 2025 +0800 feat: add qnn int16 layer param & op todo: qnn llama package implement commit 4faeca8e5e1f33053f059c3c97b16a7b7389b71c Author: oreomaker Date: Mon Mar 24 15:52:54 2025 +0800 dev: runnable qwen2vl npu (buggy) commit ebf110ebdcaf6a467af342512b9827e6b0d6b43e Author: oreomaker Date: Mon Mar 24 15:46:23 2025 +0800 feat: add qwen vl export tool (todo: simulate infer and profile tools) commit bde9a924a2667571d1eda1af62b44f647cb0d1d5 Author: oreomaker Date: Mon Mar 24 15:44:25 2025 +0800 dev: a just working version of qwen 2.5 npu commit 126c283a0b859c21ff8268e5c37df2de58face62 Merge: 25de8c37 9d33aafa Author: oreomaker Date: Mon Mar 24 15:43:30 2025 +0800 Merge branch 'fix-qnn-python' into develop-zh commit 9d33aafaed25f82cb0b3f29027f85c8f22c1a715 Author: oreomaker Date: Fri Mar 21 16:01:23 2025 +0800 fix: qnn profile quant bugs commit 25de8c3723477899036e61ee36a2a002648fcf3e Author: oreomaker Date: Thu Mar 20 16:00:19 2025 +0800 refactor: add graph split layer for QNN, change the modeling note: xnnpack is affected, should not merge commit 690a24ef6cedbe635f7e3c223eceea3fa2b6571c Author: oreomaker Date: Mon Mar 17 17:45:34 2025 +0800 feat: QNN load cache execute commit 4f28330f50174f67dca3ed10b6efaa4414e5c06a Author: oreomaker Date: Sun Mar 9 22:33:21 2025 +0800 dev: QNN graph merging execute commit b73c1c345f69f28c5f872d9dca26a065b690be5e Author: xudaliang Date: Tue Nov 12 23:28:12 2024 +0800 feat : support decoding model configuration. commit ec3d4e5be5b144e92282b9423ac37539c6422b55 Author: xudaliang Date: Tue Nov 12 20:31:45 2024 +0800 feat : support Qwen2.5 npu. commit 7246d5387d2c9d7c1427c06a6d49144e8e8a5bf7 Author: yirongjie Date: Tue May 27 07:12:53 2025 +0000 feat: set run in Backends commit 115024103f0a44b579a1014729e00edafe3b5744 Author: yirongjie Date: Sat May 24 07:57:09 2025 +0000 fix: getFunc commit 24db241ba030fbdd1f9a5da92915d92a4f657c2a Author: yirongjie Date: Fri May 23 05:16:41 2025 +0000 fix: tensor function to shared_ptr commit 0ecce7564b11fa0feb25f290dd564a334bddb6ca Author: yirongjie Date: Thu May 22 14:05:11 2025 +0000 feat:eager cpu commit 9835db5bdc90d7eb404ec19f0883968a4288e78d Author: yirongjie Date: Fri Apr 18 14:57:21 2025 +0000 fix: vtp commit 30c30465cce2747918af7e884243610b77b646b1 Author: yirongjie Date: Wed Apr 16 06:49:46 2025 +0000 fix: vtp commit b416268d590d4888c4bd8c62bcbe42723035f164 Author: yirongjie Date: Tue Apr 15 08:40:22 2025 +0000 fix: vtp commit 6430ca86f64ccf6f36817740d88a418202e30577 Author: yirongjie Date: Mon Apr 14 12:53:58 2025 +0000 feat: vtp commit f86bff6526280c258fba442c940651e175bd0781 Author: yirongjie Date: Sun Mar 23 09:41:14 2025 +0000 ref: add ShowUI --- examples/CMakeLists.txt | 2 -- examples/demo_qwen.cpp | 2 +- examples/demo_qwen2_vl.cpp | 6 +++--- src/backends/cpu/CPUBackend.cpp | 1 + src/models/qwen2_vl/modeling_qwen2_vl.hpp | 1 + src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp | 3 +-- third_party/json | 1 + 7 files changed, 8 insertions(+), 8 deletions(-) create mode 160000 third_party/json diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e69921dc3..bd01484cc 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -82,8 +82,6 @@ func_llm_add_executable(demo_llama3) func_llm_add_executable(demo_minicpm_moe_mbm) func_llm_add_executable(demo_qwen_sd) func_llm_add_executable(demo_minicpm_moe_mbp) - - func_vlm_add_executable(demo_llava) func_vlm_add_executable(demo_fuyu) func_vlm_add_executable(demo_vit) diff --git a/examples/demo_qwen.cpp b/examples/demo_qwen.cpp index 3ef6da59d..8d326d834 100644 --- a/examples/demo_qwen.cpp +++ b/examples/demo_qwen.cpp @@ -48,7 +48,7 @@ int main(int argc, char **argv) { std::cout << "[A] " << std::flush; LlmTextGeneratorOpts opt{ - .max_new_tokens = 1, + .max_new_tokens = 200, .do_sample = false, .temperature = 0.3F, .top_k = 50, diff --git a/examples/demo_qwen2_vl.cpp b/examples/demo_qwen2_vl.cpp index d28139e5c..2125a79fa 100644 --- a/examples/demo_qwen2_vl.cpp +++ b/examples/demo_qwen2_vl.cpp @@ -30,9 +30,9 @@ int main(int argc, char **argv) { model.load(model_path); vector in_imgs = { - "../assets/bus.png"}; + "../assets/showui.png"}; vector in_strs = { - "<|vision_start|><|image_pad|><|vision_end|>Describe this image.", + "Based on the screenshot of the page, I give a text description and you give its corresponding location. The coordinate represents a clickable location [x, y] for an element, which is a relative coordinate on the screenshot, scaled from 0 to 1.<|vision_start|><|image_pad|><|vision_end|>桌面", }; for (int i = 0; i < in_strs.size(); ++i) { @@ -41,7 +41,7 @@ int main(int argc, char **argv) { auto input_tensor = processor.process(in_str, in_imgs[i]); std::cout << "[Q] " << in_strs[i] << std::endl; std::cout << "[A] " << std::flush; - for (int step = 0; step < 100; step++) { + for (int step = 0; step < 128; step++) { model.get_position_ids(input_tensor); auto result = model(input_tensor); auto outputs = processor.detokenize(result[0]); diff --git a/src/backends/cpu/CPUBackend.cpp b/src/backends/cpu/CPUBackend.cpp index 92d6ed6e5..712bfe60c 100644 --- a/src/backends/cpu/CPUBackend.cpp +++ b/src/backends/cpu/CPUBackend.cpp @@ -169,6 +169,7 @@ void CPUBackend::registerOps() { addCreator(VISIONROPE, (CPUBackend::Creator *)(new CPUVisionRoPECreator())); addCreator(MULTIMODALROPEPIP, (CPUBackend::Creator *)(new CPUMultimodalRoPEPipelineCreator())); addCreator(MULTIMODALROPE, (CPUBackend::Creator *)(new CPUMultimodalRoPECreator())); + // addCreator(CAT, (CPUBackend::Creator *)(new CPUCatCreator())); addCreator(TRANSPOSE, (CPUBackend::Creator *)(new CPUTransposeCreator())); addCreator(SUBDIM, (CPUBackend::Creator *)(new CPUSubDimCreator())); addCreator(DIVISION, (CPUBackend::Creator *)(new CPUDivisionCreator())); diff --git a/src/models/qwen2_vl/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/modeling_qwen2_vl.hpp index 793b4a118..b696c3c38 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl.hpp @@ -249,6 +249,7 @@ class QWen2Attention final : public Module { auto value_states = v_proj(inputs[0]); query_states = query_states.view(-1, num_heads, -1, head_dim); key_states = key_states.view(-1, num_key_value_heads, -1, head_dim); + value_states = value_states.view(-1, num_key_value_heads, -1, head_dim); query_states = q_rope(query_states, position_ids); key_states = k_rope(key_states, position_ids); diff --git a/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp b/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp index e5025d65c..a9a5b0c7b 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp @@ -631,7 +631,7 @@ class Qwen2VL_ImagePatchAndEmbedding final : public Module { vision_start_token_id = config.vision_start_token_id; embed_tokens = Embedding(vocab_size, hidden_dim, qwen_names.token_embd_name); - visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, vision_embed_dim * 4, "QuickGELU", 14, 336, 32, spatial_merge_size, config.attn_implementation, vision_names, vision_names.vison_model_name); + visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, vision_embed_dim * 4, "QuickGELU", 14, 336, 32, spatial_merge_size, vision_names, vision_names.vison_model_name); } vector Forward(vector inputs, vector args) override { @@ -869,7 +869,6 @@ class Qwen2VL_PrefillBody final : public Module { public: explicit Qwen2VL_PrefillBody(const Qwen2VLConfig &config, int chunk_size) { - // Module::initBackend(MLLM_QNN); auto vocab_size = config.vocab_size; auto hidden_dim = config.hidden_size; auto head_size = config.num_attention_heads; diff --git a/third_party/json b/third_party/json new file mode 160000 index 000000000..51a77f1dc --- /dev/null +++ b/third_party/json @@ -0,0 +1 @@ +Subproject commit 51a77f1dcac97f917db2621a5945f4305ff1bf9f From 6b30afc6f0aaed2cb32b464719c49538aa81bd1d Mon Sep 17 00:00:00 2001 From: yirongjie Date: Sat, 7 Jun 2025 18:19:22 +0000 Subject: [PATCH 03/22] feat: add FlashAttention2 && fix: MULTIMODELROPE --- examples/demo_qwen2_vl.cpp | 6 +++--- src/models/qwen2_vl/modeling_qwen2_vl.hpp | 1 - src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/demo_qwen2_vl.cpp b/examples/demo_qwen2_vl.cpp index 2125a79fa..d28139e5c 100644 --- a/examples/demo_qwen2_vl.cpp +++ b/examples/demo_qwen2_vl.cpp @@ -30,9 +30,9 @@ int main(int argc, char **argv) { model.load(model_path); vector in_imgs = { - "../assets/showui.png"}; + "../assets/bus.png"}; vector in_strs = { - "Based on the screenshot of the page, I give a text description and you give its corresponding location. The coordinate represents a clickable location [x, y] for an element, which is a relative coordinate on the screenshot, scaled from 0 to 1.<|vision_start|><|image_pad|><|vision_end|>桌面", + "<|vision_start|><|image_pad|><|vision_end|>Describe this image.", }; for (int i = 0; i < in_strs.size(); ++i) { @@ -41,7 +41,7 @@ int main(int argc, char **argv) { auto input_tensor = processor.process(in_str, in_imgs[i]); std::cout << "[Q] " << in_strs[i] << std::endl; std::cout << "[A] " << std::flush; - for (int step = 0; step < 128; step++) { + for (int step = 0; step < 100; step++) { model.get_position_ids(input_tensor); auto result = model(input_tensor); auto outputs = processor.detokenize(result[0]); diff --git a/src/models/qwen2_vl/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/modeling_qwen2_vl.hpp index b696c3c38..793b4a118 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl.hpp @@ -249,7 +249,6 @@ class QWen2Attention final : public Module { auto value_states = v_proj(inputs[0]); query_states = query_states.view(-1, num_heads, -1, head_dim); key_states = key_states.view(-1, num_key_value_heads, -1, head_dim); - value_states = value_states.view(-1, num_key_value_heads, -1, head_dim); query_states = q_rope(query_states, position_ids); key_states = k_rope(key_states, position_ids); diff --git a/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp b/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp index a9a5b0c7b..e5025d65c 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp @@ -631,7 +631,7 @@ class Qwen2VL_ImagePatchAndEmbedding final : public Module { vision_start_token_id = config.vision_start_token_id; embed_tokens = Embedding(vocab_size, hidden_dim, qwen_names.token_embd_name); - visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, vision_embed_dim * 4, "QuickGELU", 14, 336, 32, spatial_merge_size, vision_names, vision_names.vison_model_name); + visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, vision_embed_dim * 4, "QuickGELU", 14, 336, 32, spatial_merge_size, config.attn_implementation, vision_names, vision_names.vison_model_name); } vector Forward(vector inputs, vector args) override { @@ -869,6 +869,7 @@ class Qwen2VL_PrefillBody final : public Module { public: explicit Qwen2VL_PrefillBody(const Qwen2VLConfig &config, int chunk_size) { + // Module::initBackend(MLLM_QNN); auto vocab_size = config.vocab_size; auto hidden_dim = config.hidden_size; auto head_size = config.num_attention_heads; From 0ce66c5e5abcdf9ebb2dade0cdecef45efa99c2c Mon Sep 17 00:00:00 2001 From: yi Date: Mon, 9 Jun 2025 15:45:28 +0800 Subject: [PATCH 04/22] remove broken submodule --- third_party/json | 1 - 1 file changed, 1 deletion(-) delete mode 160000 third_party/json diff --git a/third_party/json b/third_party/json deleted file mode 160000 index 51a77f1dc..000000000 --- a/third_party/json +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 51a77f1dcac97f917db2621a5945f4305ff1bf9f From 627ea4127c397ac1a0e00baa32ee2aef78f6fffa Mon Sep 17 00:00:00 2001 From: yirongjie Date: Tue, 10 Jun 2025 11:14:52 +0800 Subject: [PATCH 05/22] fix: support for mac && fix xnn --- .gitignore | 3 +- CMakeLists.txt | 20 +- examples/CMakeLists.txt | 149 ++---- examples/demo_showui_vtp.cpp | 64 +++ src/ParamLoader.cpp | 4 +- src/backends/cpu/CMakeLists.txt | 21 +- src/backends/cpu/compute/GEMM_AArch64.cpp | 22 +- src/backends/qnn/CMakeLists.txt | 10 +- src/backends/xnnpack/CMakeLists.txt | 10 +- .../xnnpack/Functions/XpBinaryFunc.cpp | 10 +- src/backends/xnnpack/XnnpackBackend.cpp | 490 ++++++++++++++++++ src/backends/xnnpack/XnnpackBackend.hpp | 15 +- src/memory/SystemMemoryManager.cpp | 23 +- .../mbm/modeling_minicpm_moe_mbm.hpp | 2 +- .../mbp/modeling_minicpm_moe_mbp.hpp | 2 +- test/CMakeLists.txt | 4 +- 16 files changed, 699 insertions(+), 150 deletions(-) create mode 100644 examples/demo_showui_vtp.cpp diff --git a/.gitignore b/.gitignore index 82d8c6e40..549dbb44e 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,5 @@ examples/demo_deepseek.cpp src/models/deepseek/* examples/demo.cpp -src/backends/qnn/sdk/* \ No newline at end of file +src/backends/qnn/sdk/* +.DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt index 44022cc63..c71a5e0b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,11 +112,11 @@ if (ARM AND NOT APK) set(MLLM_OPENMP_STATIC ON) endif () # turn off openmp when build on mac or for mac -if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING) - message(STATUS "mac detected, turn off openmp") - set(MLLM_OPENMP OFF) - set(MLLM_OPENMP_STATIC OFF) -endif () +# if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING) +# message(STATUS "mac detected, turn off openmp") +# set(MLLM_OPENMP OFF) +# set(MLLM_OPENMP_STATIC OFF) +# endif () if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^(x86_64|i686|AMD64)$") message(STATUS "x86_64 detected") @@ -271,24 +271,24 @@ if(APK) # models/smollm/tokenization_smollm.hpp # tokenizers/Unigram/Unigram.hpp ) - target_link_libraries(mllm_lib MLLM_CPU) + target_link_libraries(mllm_lib lib_mllm_cpu) if(QNN) - target_link_libraries(mllm_lib MLLM_QNN) + target_link_libraries(mllm_lib lib_mllm_qnn) endif() endif() if(MLLM_ENABLE_PYTHON) - target_compile_options(MLLM_CPU PRIVATE -fPIC) + target_compile_options(lib_mllm_cpu PRIVATE -fPIC) find_package(Python3 COMPONENTS Interpreter Development) include_directories(${Python3_INCLUDE_DIRS}) add_subdirectory(${PROJECT_SOURCE_DIR}/third_party/pybind11) set(_py_dep_libs - MLLM_CPU + lib_mllm_cpu - # MLLM_QNN + # lib_mllm_qnn # ${CMAKE_DL_LIBS} ) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index bd01484cc..f12cd17bf 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,58 +1,70 @@ -macro(func_link_libaries target) - target_link_libraries(${target} PUBLIC MLLM_CPU fmt::fmt-header-only) +set(COMMON_SRC + ${DIR_SRC_CPU} + ${DIR_SRC_MEM_MANAGER} + ${DIR_SRC_EXP} + ${DIR_SRC} + ${PROJECT_SOURCE_DIR}/src/tokenizers/Tokenizer.cpp + ${PROJECT_SOURCE_DIR}/src/tokenizers/BPE/Bpe.cpp + ${PROJECT_SOURCE_DIR}/src/tokenizers/WordPiece/WordPiece.cpp + ${PROJECT_SOURCE_DIR}/src/tokenizers/Tiktoken/tiktoken.cpp + ${PROJECT_SOURCE_DIR}/src/tokenizers/Unicode.cpp + ${PROJECT_SOURCE_DIR}/src/tokenizers/UnicodeData.cpp + ${PROJECT_SOURCE_DIR}/src/processor/PreProcess.cpp +) + +set(VLM_SPECIFIC_SRC + ${PROJECT_SOURCE_DIR}/src/tokenizers/Unigram/Unigram.cpp + ${DIR_SRC_PROCESSOE} + ${DIR_THIRDPARTY_AUDIO} +) + +macro(func_set_compile_opts_defs target) if (MLLM_OPENMP) target_compile_options(${target} PRIVATE -fopenmp) - if (ARM) + endif() + if (QNN) + target_compile_definitions(${target} PRIVATE USE_QNN) + endif() +endmacro() + +macro(func_link_libs target) + target_link_libraries(${target} PUBLIC lib_mllm_cpu fmt::fmt-header-only) + if (MLLM_OPENMP) + if (ARM AND NOT (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING)) + # 非Mac的ARM,静态链接OpenMP target_link_libraries(${target} PUBLIC -fopenmp -static-openmp) - else () + else() + # 其它平台(含Mac),动态链接OpenMP target_link_libraries(${target} PUBLIC -fopenmp) - endif () - endif () + endif() + endif() if (QNN) - target_compile_definitions(${target} PRIVATE USE_QNN) - target_link_libraries(${target} PUBLIC MLLM_QNN ${CMAKE_DL_LIBS}) + target_link_libraries(${target} PUBLIC lib_mllm_qnn ${CMAKE_DL_LIBS}) endif() if (MLLM_BUILD_XNNPACK_BACKEND) - target_link_libraries(${target} PRIVATE MllmXnnpackBackend) + target_link_libraries(${target} PRIVATE lib_mllm_xnnpack) endif() endmacro() +add_library(lib_mllm_common_llm STATIC ${COMMON_SRC}) +func_set_compile_opts_defs(lib_mllm_common_llm) + +add_library(lib_mllm_vlm STATIC ${VLM_SPECIFIC_SRC}) +target_link_libraries(lib_mllm_vlm PUBLIC lib_mllm_common_llm) +func_set_compile_opts_defs(lib_mllm_vlm) + macro(func_llm_add_executable target) - add_executable(${target} - ${PROJECT_SOURCE_DIR}/examples/${target}.cpp - ${DIR_SRC_CPU} - ${DIR_SRC_MEM_MANAGER} - ${DIR_SRC_EXP} - ${DIR_SRC} - ${PROJECT_SOURCE_DIR}/src/tokenizers/Tokenizer.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/BPE/Bpe.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/WordPiece/WordPiece.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/Tiktoken/tiktoken.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/Unicode.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/UnicodeData.cpp - ${PROJECT_SOURCE_DIR}/src/processor/PreProcess.cpp - ) - func_link_libaries(${target}) + add_executable(${target} ${PROJECT_SOURCE_DIR}/examples/${target}.cpp) + target_link_libraries(${target} PUBLIC lib_mllm_common_llm) + func_set_compile_opts_defs(${target}) + func_link_libs(${target}) endmacro() macro(func_vlm_add_executable target) - add_executable(${target} - ${PROJECT_SOURCE_DIR}/examples/${target}.cpp - ${DIR_SRC_CPU} - ${DIR_SRC_MEM_MANAGER} - ${DIR_SRC_EXP} - ${DIR_SRC} - ${PROJECT_SOURCE_DIR}/src/tokenizers/Tokenizer.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/Unigram/Unigram.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/Unicode.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/UnicodeData.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/BPE/Bpe.cpp - ${PROJECT_SOURCE_DIR}/src/tokenizers/WordPiece/WordPiece.cpp - ${PROJECT_SOURCE_DIR}/src/processor/PreProcess.cpp - ${DIR_SRC_PROCESSOE} - ${DIR_THIRDPARTY_AUDIO} - ) - func_link_libaries(${target}) + add_executable(${target} ${PROJECT_SOURCE_DIR}/examples/${target}.cpp) + target_link_libraries(${target} PUBLIC lib_mllm_vlm) + func_set_compile_opts_defs(${target}) + func_link_libs(${target}) endmacro() func_llm_add_executable(mllm_benchmark) @@ -82,6 +94,7 @@ func_llm_add_executable(demo_llama3) func_llm_add_executable(demo_minicpm_moe_mbm) func_llm_add_executable(demo_qwen_sd) func_llm_add_executable(demo_minicpm_moe_mbp) + func_vlm_add_executable(demo_llava) func_vlm_add_executable(demo_fuyu) func_vlm_add_executable(demo_vit) @@ -91,65 +104,15 @@ func_vlm_add_executable(demo_imagebind_1mod) func_vlm_add_executable(demo_phi3v) func_vlm_add_executable(demo_qwen2_vl) func_vlm_add_executable(demo_showui) -# func_vlm_add_executable(demo) - -# QNN demo +func_vlm_add_executable(demo_showui_vtp) if(QNN) func_llm_add_executable(demo_qwen_npu) - # func_llm_add_executable(main_qwen_npu) func_llm_add_executable(demo_phonelm_npu) - # func_llm_add_executable(main_phonelm_npu) func_llm_add_executable(demo_qwen2.5_npu) - # func_llm_add_executable(demo_qwen_pipeline) func_vlm_add_executable(demo_qwen2_vl_npu) endif() - if(MLLM_BUILD_XNNPACK_BACKEND) func_llm_add_executable(demo_qwen_xp) -endif() - - -# old main -# macro(func_o_vlm_add_executable target) -# add_executable(${target} -# ${PROJECT_SOURCE_DIR}/examples/${target}.cpp -# ${DIR_SRC_CPU} -# ${DIR_SRC_MEM_MANAGER} -# ${DIR_SRC_EXP} -# ${DIR_SRC} -# ${PROJECT_SOURCE_DIR}/src/tokenizers/Tokenizer.cpp -# ${PROJECT_SOURCE_DIR}/src/tokenizers/Unigram/Unigram.cpp -# ${PROJECT_SOURCE_DIR}/src/tokenizers/BPE/Bpe.cpp -# ${PROJECT_SOURCE_DIR}/src/processor/PreProcess.cpp -# ${PROJECT_SOURCE_DIR}/src/processor/ClipPreProcess.cpp -# ${PROJECT_SOURCE_DIR}/src/processor/FuyuPreProcess.cpp -# ) -# func_link_libaries(${target}) -# endmacro() -# macro(func_o_avlm_add_executable target) -# add_executable(${target} -# ${PROJECT_SOURCE_DIR}/examples/${target}.cpp -# ${DIR_SRC_CPU} -# ${DIR_SRC_MEM_MANAGER} -# ${DIR_SRC_EXP} -# ${DIR_SRC} -# ${PROJECT_SOURCE_DIR}/src/tokenizers/Tokenizer.cpp -# ${PROJECT_SOURCE_DIR}/src/tokenizers/Unigram/Unigram.cpp -# ${PROJECT_SOURCE_DIR}/src/tokenizers/BPE/Bpe.cpp -# ${PROJECT_SOURCE_DIR}/src/processor/PreProcess.cpp -# ${PROJECT_SOURCE_DIR}/src/processor/ClipPreProcess.cpp -# ${DIR_SRC_PROCESSOE} -# ${DIR_THIRDPARTY_AUDIO} -# ) -# func_link_libaries(${target}) -# endmacro() -# func_llm_add_executable(main_llama) -# func_llm_add_executable(main_alpaca) -# func_llm_add_executable(main_tinyllama) -# func_o_vlm_add_executable(main_llava) -# func_o_vlm_add_executable(main_fuyu) -# func_o_vlm_add_executable(main_vit) -# func_o_vlm_add_executable(main_clip) -# func_o_avlm_add_executable(main_imagebind) +endif() \ No newline at end of file diff --git a/examples/demo_showui_vtp.cpp b/examples/demo_showui_vtp.cpp new file mode 100644 index 000000000..cce2597c9 --- /dev/null +++ b/examples/demo_showui_vtp.cpp @@ -0,0 +1,64 @@ +#include +#include +#include "cmdline.h" +#include "models/qwen2_vl/configuration_qwen2_vl.hpp" +// #include "models/qwen2_vl/modeling_qwen2_vl.hpp" +#include "models/qwen2_vl/vtp/modeling_qwen2_vl.hpp" +#include "models/qwen2_vl/processing_qwen2_vl.hpp" +#include "processor/PostProcess.hpp" + +using namespace mllm; +int main(int argc, char **argv) { + cmdline::parser cmdParser; + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/showui_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/showui_merges.txt"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/showui-2b-q4_k.mllm"); + cmdParser.add("limits", 'l', "max KV cache size", false, 2000); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + int tokens_limit = cmdParser.get("limits"); + int thread_num = cmdParser.get("thread"); + CPUBackend::cpu_threads = cmdParser.get("thread"); + + ParamLoader param_loader(model_path); + int min_pixels = 256 * 28 * 28; + int max_pixels = 1344 * 28 * 28; + auto processor = Qwen2VLProcessor(vocab_path, merge_path, min_pixels, max_pixels); + Qwen2VLConfig config(tokens_limit, "1.5b"); + auto model = Qwen2VLModel(config); + model.load(model_path); + + vector in_imgs = { + "../assets/uidemo2.png"}; + vector in_strs = { + "Based on the screenshot of the page, I give a text description and you give its corresponding location. The coordinate represents a clickable location [x, y] for an element, which is a relative coordinate on the screenshot, scaled from 0 to 1.<|vision_start|><|image_pad|><|vision_end|>桌面", + }; + + for (int i = 0; i < in_strs.size(); ++i) { + auto in_str = in_strs[i]; + in_str = processor.tokenizer->apply_chat_template(in_str); + auto input_tensor = processor.process(in_str, in_imgs[i]); + std::cout << "[Q] " << in_strs[i] << std::endl; + std::cout << "[A] " << std::flush; + for (int step = 0; step < 100; step++) { + model.get_position_ids(input_tensor); + auto result = model(input_tensor); + auto outputs = processor.detokenize(result[0]); + auto out_string = outputs.first; + auto out_token = outputs.second; + auto [not_end, output_string] = processor.tokenizer->postprocess(out_string); + if (!not_end) { break; } + std::cout << output_string << std::flush; + chatPostProcessing(out_token, input_tensor[0], {&input_tensor[1], &input_tensor[2]}); + } + printf("\n"); + model.clear_kvcache(); + model.profiling(); + } + + return 0; +} \ No newline at end of file diff --git a/src/ParamLoader.cpp b/src/ParamLoader.cpp index a82fd7cf7..e22568e82 100644 --- a/src/ParamLoader.cpp +++ b/src/ParamLoader.cpp @@ -38,7 +38,7 @@ bool ParamLoader::load(mllm::Tensor *tensor) { std::pair offset = offsets_[name]; auto *p = tensor->hostPtr(); fseek(fp_, offset.first, SEEK_SET); - size_t read_size = std::min(tensor->cntSize(), offset.second); + size_t read_size = std::min(tensor->cntSize(), static_cast(offset.second)); auto _ = fread(p, sizeof(uint8_t), read_size, fp_); /* @@ -80,7 +80,7 @@ bool ParamLoader::load(mllm::Tensor *tensor) { uint8_t *source_ptr = buffer_ + offset_info.first; // 要拷贝的数据大小,取 tensor 大小和参数大小的最小值 - size_t copy_size = std::min(tensor->cntSize(), offset_info.second); + size_t copy_size = std::min(tensor->cntSize(), static_cast(offset_info.second)); // 从内存映射的 buffer_ 拷贝数据到 tensor memcpy(static_cast(p), static_cast(source_ptr), copy_size); diff --git a/src/backends/cpu/CMakeLists.txt b/src/backends/cpu/CMakeLists.txt index 1aa021689..ee3dfa26e 100644 --- a/src/backends/cpu/CMakeLists.txt +++ b/src/backends/cpu/CMakeLists.txt @@ -34,20 +34,20 @@ endif() if(${MLLM_ENABLE_PYTHON}) add_library( - MLLM_CPU + lib_mllm_cpu SHARED ${MLLM_CPU_SRC} ) else() add_library( - MLLM_CPU + lib_mllm_cpu OBJECT ${MLLM_CPU_SRC} ) endif() target_include_directories( - MLLM_CPU + lib_mllm_cpu PRIVATE ${CMAKE_CURRENT_LIST_DIR} ) @@ -56,16 +56,21 @@ if(OpenMP_FOUND) message(STATUS "found openmp") if(ARM AND NOT APK) message(STATUS "[ARM] found openmp") - target_compile_options(MLLM_CPU PUBLIC -fopenmp) - target_link_libraries(MLLM_CPU PUBLIC -fopenmp -static-openmp) + target_compile_options(lib_mllm_cpu PUBLIC -fopenmp) + # tmac or for mac + if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING) + target_link_libraries(lib_mllm_cpu PUBLIC OpenMP::OpenMP_CXX) + else() + target_link_libraries(lib_mllm_cpu PUBLIC -fopenmp -static-openmp) + endif () else() - target_link_libraries(MLLM_CPU + target_link_libraries(lib_mllm_cpu PUBLIC OpenMP::OpenMP_CXX ) endif() endif() -target_link_libraries(MLLM_CPU PUBLIC fmt::fmt-header-only) +target_link_libraries(lib_mllm_cpu PUBLIC fmt::fmt-header-only) -set_target_properties(MLLM_CPU PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) \ No newline at end of file +set_target_properties(lib_mllm_cpu PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) \ No newline at end of file diff --git a/src/backends/cpu/compute/GEMM_AArch64.cpp b/src/backends/cpu/compute/GEMM_AArch64.cpp index 708712a37..91600ed33 100644 --- a/src/backends/cpu/compute/GEMM_AArch64.cpp +++ b/src/backends/cpu/compute/GEMM_AArch64.cpp @@ -1253,11 +1253,12 @@ void mllm_gemm_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void * // "for optimal performance"); // } // #endif -#if defined(__ARM_NEON) && defined(__ARM_FEATURE_MATMUL_INT8) - assert(!(mllm_cpu_has_neon() && mllm_cpu_has_matmul_int8()) - && "__ARM_NEON and __ARM_FEATURE_MATMUL_INT8 defined, use the Q4_0_4_8 " - "quantization format for optimal performance"); -#elif defined(__ARM_NEON) && defined(__aarch64__) +// #if defined(__ARM_NEON) && defined(__ARM_FEATURE_MATMUL_INT8) +// assert(!(mllm_cpu_has_neon() && mllm_cpu_has_matmul_int8()) +// && "__ARM_NEON and __ARM_FEATURE_MATMUL_INT8 defined, use the Q4_0_4_8 " +// "quantization format for optimal performance"); +// #elif defined(__ARM_NEON) && defined(__aarch64__) +#if defined(__ARM_NEON) && defined(__aarch64__) const void *b_ptr = vx; const void *a_ptr = vy; float *res_ptr = s; @@ -1788,11 +1789,12 @@ void _mllm_gemm_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const // "for optimal performance"); // } // #endif -#if defined(__ARM_NEON) && defined(__ARM_FEATURE_MATMUL_INT8) - assert(!(mllm_cpu_has_neon() && mllm_cpu_has_matmul_int8()) - && "__ARM_NEON and __ARM_FEATURE_MATMUL_INT8 defined, use the Q4_0_4_8 " - "quantization format for optimal performance"); -#elif defined(__ARM_NEON) && defined(__aarch64__) +// #if defined(__ARM_NEON) && defined(__ARM_FEATURE_MATMUL_INT8) +// assert(!(mllm_cpu_has_neon() && mllm_cpu_has_matmul_int8()) +// && "__ARM_NEON and __ARM_FEATURE_MATMUL_INT8 defined, use the Q4_0_4_8 " +// "quantization format for optimal performance"); +// #elif defined(__ARM_NEON) && defined(__aarch64__) +#if defined(__ARM_NEON) && defined(__aarch64__) const void *b_ptr = vx; const void *a_ptr = vy; const void *bias_ptr = bias; diff --git a/src/backends/qnn/CMakeLists.txt b/src/backends/qnn/CMakeLists.txt index 1844b39d4..cb8ee5b2b 100644 --- a/src/backends/qnn/CMakeLists.txt +++ b/src/backends/qnn/CMakeLists.txt @@ -48,7 +48,7 @@ endif() add_library( - MLLM_QNN + lib_mllm_qnn OBJECT ${MLLM_QNN_SRC} ) @@ -57,12 +57,12 @@ if(OpenMP_FOUND) message(STATUS "found openmp") if(ARM AND NOT APK) message(STATUS "[ARM] found openmp") - target_compile_options(MLLM_QNN PRIVATE -fopenmp) - target_link_libraries(MLLM_QNN PUBLIC -fopenmp -static-openmp) + target_compile_options(lib_mllm_qnn PRIVATE -fopenmp) + target_link_libraries(lib_mllm_qnn PUBLIC -fopenmp -static-openmp) else() - target_link_libraries(MLLM_QNN + target_link_libraries(lib_mllm_qnn PUBLIC OpenMP::OpenMP_CXX ) endif() endif() -target_link_libraries(MLLM_QNN PUBLIC fmt::fmt-header-only) \ No newline at end of file +target_link_libraries(lib_mllm_qnn PUBLIC fmt::fmt-header-only) \ No newline at end of file diff --git a/src/backends/xnnpack/CMakeLists.txt b/src/backends/xnnpack/CMakeLists.txt index e416963b7..4192806f3 100644 --- a/src/backends/xnnpack/CMakeLists.txt +++ b/src/backends/xnnpack/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(third_party/XNNPACK) -add_library(MllmXnnpackBackend +add_library(lib_mllm_xnnpack OBJECT Utils/Logger.cpp @@ -36,7 +36,7 @@ add_library(MllmXnnpackBackend Functions/XpViewFunc.cpp Functions/XpMatmulFunc.cpp ) -target_include_directories(MllmXnnpackBackend PUBLIC third_party/XNNPACK/src/) -target_include_directories(MllmXnnpackBackend PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../) -target_link_libraries(MllmXnnpackBackend PUBLIC XNNPACK fmt::fmt-header-only) -set_target_properties(MllmXnnpackBackend PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) +target_include_directories(lib_mllm_xnnpack PUBLIC third_party/XNNPACK/src/) +target_include_directories(lib_mllm_xnnpack PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../) +target_link_libraries(lib_mllm_xnnpack PUBLIC XNNPACK fmt::fmt-header-only) +set_target_properties(lib_mllm_xnnpack PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) diff --git a/src/backends/xnnpack/Functions/XpBinaryFunc.cpp b/src/backends/xnnpack/Functions/XpBinaryFunc.cpp index b6ea6792d..19b77c541 100644 --- a/src/backends/xnnpack/Functions/XpBinaryFunc.cpp +++ b/src/backends/xnnpack/Functions/XpBinaryFunc.cpp @@ -126,7 +126,7 @@ void XpBroadcastMulFunction::execute(vector> outputs, vector< } } -void XpBroadcastDivFunction::setup(vector> outputs, vector> inputs, vector args) { +void XpBroadcastDivFunction::reshape(vector> outputs, vector> inputs, vector args) { // reshape auto input = inputs[0]; auto output = outputs[0]; @@ -166,7 +166,7 @@ void XpBroadcastDivFunction::execute(vector> outputs, vector< } } -void XpTTAddFunction::setup(vector> outputs, vector> inputs, vector args) { +void XpTTAddFunction::reshape(vector> outputs, vector> inputs, vector args) { // reshape auto input = inputs[0]; auto output = outputs[0]; @@ -197,7 +197,7 @@ void XpTTAddFunction::execute(vector> outputs, vector> outputs, vector> inputs, vector args) { +void XpTTSubFunction::reshape(vector> outputs, vector> inputs, vector args) { // reshape auto input = inputs[0]; auto output = outputs[0]; @@ -228,7 +228,7 @@ void XpTTSubFunction::execute(vector> outputs, vector> outputs, vector> inputs, vector args) { +void XpTTMulFunction::reshape(vector> outputs, vector> inputs, vector args) { // reshape auto input = inputs[0]; auto output = outputs[0]; @@ -259,7 +259,7 @@ void XpTTMulFunction::execute(vector> outputs, vector> outputs, vector> inputs, vector args) { +void XpTTDivFunction::reshape(vector> outputs, vector> inputs, vector args) { // reshape auto input = inputs[0]; auto output = outputs[0]; diff --git a/src/backends/xnnpack/XnnpackBackend.cpp b/src/backends/xnnpack/XnnpackBackend.cpp index c42514b1b..72631f480 100644 --- a/src/backends/xnnpack/XnnpackBackend.cpp +++ b/src/backends/xnnpack/XnnpackBackend.cpp @@ -1,5 +1,7 @@ #include "backends/xnnpack/XnnpackBackend.hpp" #include "Backend.hpp" +#include "Module.hpp" +#include "layer.hpp" #include "OpDefined.hpp" #include "backends/xnnpack/Utils/Logger.hpp" #include "pthreadpool.h" @@ -34,6 +36,7 @@ #include "xnnpack/subgraph.h" #include #include +#include namespace mllm { @@ -674,4 +677,491 @@ bool XnnpackBackend::enable_dynamic_shape = true; bool XnnpackBackend::enable_legacy_wrapper = false; + + + +std::vector XnnpackBackend::runFunc(std::vector out_names, + TensorFuncType type, + std::vector float_args, + std::vector> input_tensors, + bool in_place) { + Module *module = input_tensors.empty() ? mllm::Module::llm_model_ptr : input_tensors[0]->module(); + assert(module != nullptr); + auto &activation_tensors = module->activation_tensors; + auto &activation_tensors_num = module->activation_tensors_num; + + std::vector> output_ptrs; + for (const auto &out_name : out_names) { + if (activation_tensors.find(out_name) == activation_tensors.end()) { + Backend *backend_h = Backend::global_backends[MLLM_CPU]; + if (!input_tensors.empty()) { + backend_h = input_tensors[0]->backend(); + } + activation_tensors[out_name] = std::make_shared(backend_h); + activation_tensors[out_name]->setName(out_name); + activation_tensors[out_name]->setModule(module); + activation_tensors_num[out_name] = 0; + } + output_ptrs.push_back(activation_tensors[out_name]); + } + + if (module->doLoad) { + std::vector results; + for (auto &out_tensor : output_ptrs) { + results.push_back(*activation_tensors[out_tensor->name()]); + } + return results; + } + + Backend *backend_h = Backend::global_backends[MLLM_CPU]; + if (!input_tensors.empty()) { + backend_h = input_tensors[0]->backend(); + } + TensorFunction *func = backend_h->funcCreate(type); + + std::vector> input_ptrs; + for (auto &tensor : input_tensors) { + input_ptrs.push_back(activation_tensors[tensor->name()]); + } + // if (in_place) { + // for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { + // input_tensors[i]->setName(out_names[i]); + // output_ptrs.push_back(input_tensors[i]); + // } + // } + +#ifdef DEBUGOPTIME + auto start_t = mllm_time_us(); +#endif + + switch (Tensor::tensor_status) { + case TENSOR_STATIC_INIT: + func->reshape(output_ptrs, input_ptrs, float_args); + func->setUp(output_ptrs, input_ptrs, float_args); + break; + case TENSOR_STATIC_READY: + func->execute(output_ptrs, input_ptrs, float_args); + break; + case TENSOR_STATIC_TRACE: + if (backend_h->type() == BackendType::MLLM_CPU) { + Tracer::addTensorFunction(func, input_ptrs, output_ptrs, float_args); + } + break; + default: + break; + } + + // if (Backend::global_backends.size() == 1) { + // for (auto input_tensor : input_ptrs) { + // auto it = activation_tensors_num.find(input_tensor->name()); + // if (it != activation_tensors_num.end()) { + // switch (Tensor::tensor_status) { + // case TENSOR_STATIC_INIT: + // it->second += 1; + // break; + // case TENSOR_STATIC_READY: + // it->second -= 1; + // break; + // default: + // break; + // } + // if (it->second == 0 && module_tensors[input_tensor->name()]->sequence() > 1 && module_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { + // activation_tensors[input_tensor->name()]->free(); + // } + // } + // } + // } + +#ifdef DEBUGOPTIME + if (Tensor::tensor_status == TENSOR_STATIC_READY) { + auto end_t = mllm_time_us(); + std::cout << (out_names.empty() ? "" : out_names[0]) << " | " + << Tensor::tensor_status << " time: " + << (end_t - start_t) / 1000.0F << "ms" << std::endl; + } +#endif + +#ifdef DEBUGSAVETENSOR + for (auto &out_name : out_names) { + activation_tensors[out_name]->saveNData(); + } +#endif + + std::vector results; + for (auto &out_tensor : output_ptrs) { + results.emplace_back(*activation_tensors[out_tensor->name()]); + } + return results; +} +std::string name_num_to_X(const std::string &input_string) { + std::regex pattern(R"(\.\d{1,3}\.)"); // Matches any number between 1 and 100 between two dots + std::string replacement = ".X."; // The string to replace the matched pattern with + std::string output_string = std::regex_replace(input_string, pattern, replacement); + return output_string; +} +std::string name_X_to_num(const std::string &input_string, int in_idx) { + std::regex pattern(".X."); // Matches any number between 1 and 100 between two dots + std::string replacement = "." + std::to_string(in_idx) + "."; // The string to replace the matched pattern with + std::string output_string = std::regex_replace(input_string, pattern, replacement); + return output_string; +} +void init_reset_KVCache(string input_name, Module *module, int saved_list_idx, map layername_2_tensorname, Backend *backend_) { + map> &activation_tensors = module->activation_tensors; + vector renameX_names; + renameX_names.push_back(input_name); + const vector suffixs = {"-view", ".split-0", ".split-1", ".split-2", "-cat", "-split-0-48"}; + vector new_names; + bool can_break = true; + auto in_x_name = renameX_names[0]; + while (can_break) { + can_break = false; + for (const auto &suffix : suffixs) { + if (in_x_name.rfind(suffix) == (in_x_name.size() - suffix.size())) { + const auto r_name = in_x_name.substr(0, in_x_name.size() - suffix.size()); + if (std::find(renameX_names.begin(), renameX_names.end(), r_name) == renameX_names.end() && std::find(new_names.begin(), new_names.end(), r_name) == new_names.end()) { + new_names.push_back(r_name); + in_x_name = r_name; + can_break = true; + } + break; + } + } + } + renameX_names.insert(renameX_names.end(), new_names.begin(), new_names.end()); + for (const auto x_name : renameX_names) { + auto name = name_X_to_num(x_name, saved_list_idx); + layername_2_tensorname[name] = name; + activation_tensors[name] = std::make_shared(backend_); + activation_tensors[name]->initFrom(*activation_tensors[x_name]); + activation_tensors[name]->setName(name); + activation_tensors[name]->setModule(module); + } +} + +std::vector XnnpackBackend::runLayer(Layer *layer, std::vector inputs, int N) { + Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); + map> &activation_tensors = module->activation_tensors; + auto &activation_tensors_num = module->activation_tensors_num; + // Module::runlistIdx = saved_list_idx; + bool do_init = false; + + if (module->doLoad || !layer->inited_loaded) { + // set backend to current module device and try to create op + // use Module::tmp_device only when creating the op as the recersive module backend only handled in load and init stage + layer->backend_ = Backend::global_backends[Module::tmp_device]; + do_init = !layer->inited_loaded; + if (layer->op_ == nullptr) { +#ifdef USE_QNN + if ((layer->param_["type"] == KVCACHE || layer->param_["type"] == KVCACHENPU) && (Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end())) { + if (kv_cache_map.find(layer->name_) == kv_cache_map.end()) { + // for the prefill part, we need to create a new op + layer->param_["type"] = KVCACHENPU; + layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); + kv_cache_map[layer->name_] = layer->op_; + } else { +#ifdef DEBUGPRINT + std::cout << name_ << " is shared used" << std::endl; +#endif + // for the decoding part, we need to get created op from global container + layer->op_ = kv_cache_map[layer->name_]; + } + } else { + layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); + } +#else + layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); +#endif + } + if (layer->param_["type"] == SUBGRAPHFINALIZE) { + for (auto &input : inputs) { + activation_tensors[input.name()]->setTtype(GRAPH_OUTPUT); + } + } + if (module->doLoad) { + layer->op_->load(*module->loader); + layer->inited_loaded = true; + } else if (layer->loaded_param) { + layer->inited_loaded = layer->loaded_param; + } else { + if (!layer->inited_loaded) { + // module->loader = new ParamLoader(""); + // op_->load(*module->loader); + auto empty_loader = new ParamLoader(""); + layer->op_->load(*empty_loader); + layer->inited_loaded = true; + } + } + vector layer_next_names = {}; + if (N > 1) { + for (int i = 0; i < N; ++i) { + layer_next_names.push_back("out-" + layer->op_->name() + "-" + std::to_string(i)); + } + } else { + layer_next_names = {"out-" + layer->op_->name()}; + } + for (const auto &layer_next_name : layer_next_names) { + string next_name; + if (Layer::use_layername_2_tensorname) { + if (Layer::layername_2_tensorname.find(layer_next_name) == Layer::layername_2_tensorname.end()) { + if (layer->param_["type"] == KVCACHE) { + Layer::layername_2_tensorname[layer_next_name] = layer_next_name; + init_reset_KVCache(inputs[0].name(), module, layer->saved_list_idx, Layer::layername_2_tensorname, layer->backend_); + } else { + Layer::layername_2_tensorname[layer_next_name] = name_num_to_X(layer_next_name); + } + } + next_name = Layer::layername_2_tensorname[layer_next_name]; + } else if (layer_next_name.find("visual") != string::npos) { + // QNN VLM trick: visual model use act tensor sharing + if (Layer::layername_2_tensorname.find(layer_next_name) == Layer::layername_2_tensorname.end()) { + if (layer->param_["type"] == KVCACHE) { + Layer::layername_2_tensorname[layer_next_name] = layer_next_name; + init_reset_KVCache(inputs[0].name(), module, layer->saved_list_idx, Layer::layername_2_tensorname, layer->backend_); + } else { + Layer::layername_2_tensorname[layer_next_name] = name_num_to_X(layer_next_name); + } + } + next_name = Layer::layername_2_tensorname[layer_next_name]; + } else { + next_name = layer_next_name; + } + if (activation_tensors.find(next_name) == activation_tensors.end()) { + activation_tensors[next_name] = std::make_shared(layer->backend_); + activation_tensors[next_name]->setName(next_name); + activation_tensors[next_name]->setModule(module); + activation_tensors_num[next_name] = 0; + } + } + if (module->doLoad) { + vector output_result = {}; + for (const auto &layer_next_name : layer_next_names) { + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); + output_result.push_back(*activation_tensors[next_name]); + } + return output_result; + } + } + // input_tensors + vector> input_tensors; + for (auto &input : inputs) { + if (input.shouldInGraphs()) { + auto input_name = input.name(); + if (layer->param_["type"] == KVCACHE && do_init && Layer::use_layername_2_tensorname) { + input_name = name_X_to_num(input_name, layer->saved_list_idx); + } + input_tensors.push_back(activation_tensors[input_name]); + } else { + input_tensors.push_back(std::shared_ptr(&input, [](Tensor *) {})); + } + } + // output_tensors + vector layer_next_names = {}; + if (N > 1) { + for (int i = 0; i < N; ++i) { + layer_next_names.push_back("out-" + layer->op_->name() + "-" + std::to_string(i)); + } + } else { + layer_next_names = {"out-" + layer->op_->name()}; + } + vector> output_tensors = {}; + for (const auto &layer_next_name : layer_next_names) { + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); + output_tensors.push_back(activation_tensors[next_name]); + } +#ifdef DEBUGOPTIME + auto start_t = mllm_time_us(); +#endif + switch (Tensor::tensor_status) { + case TENSOR_STATIC_INIT: { + if (!Module::isFirstChunk && layer->backend_->type() == MLLM_QNN) { + } else { + layer->op_->reshape(input_tensors, output_tensors); + layer->op_->setUp(input_tensors, output_tensors); + } + break; + } + case TENSOR_STATIC_READY: { + if (!Module::isFirstChunk && layer->backend_->type() == MLLM_QNN && layer->param_["type"] != SUBGRAPHSTART) { + } else { + layer->op_->execute(input_tensors, output_tensors); + } + break; + } + case TENSOR_STATIC_TRACE: { + if (layer->backend_->type() == BackendType::MLLM_CPU) { + Tracer::addOp(layer->op_, input_tensors, output_tensors); + } else if (layer->param_["type"] == SUBGRAPHSTART) { // begin of QNN graph + Tracer::addModule(input_tensors, {}, layer->op_->name()); + } + break; + } + default: { + break; + } + } +// if (Backend::global_backends.size() == 1) { +// for (auto input_tensor : input_tensors) { +// if ((activation_tensors_num.find(input_tensor->name()) != activation_tensors_num.end())) { +// switch (Tensor::tensor_status) { +// case TENSOR_STATIC_INIT: { +// activation_tensors_num[input_tensor->name()] += 1; +// break; +// } +// case TENSOR_STATIC_READY: { +// activation_tensors_num[input_tensor->name()] -= 1; +// break; +// } +// default: { +// } +// } +// if (activation_tensors_num[input_tensor->name()] == 0 && activation_tensors[input_tensor->name()]->sequence() > 1 +// && activation_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { +// activation_tensors[input_tensor->name()]->free(); +// // std::cout << input_tensor->name() << "|" << std::endl; +// } +// } +// } +// } +#ifdef DEBUGOPTIME + if (Tensor::tensor_status == TENSOR_STATIC_READY) { + auto end_t = mllm_time_us(); + std::cout << layer->op_->name() << " | " << Tensor::tensor_status << " time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; + } +#endif + vector output_result = {}; + for (const auto &layer_next_name : layer_next_names) { + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); +#ifdef DEBUGSAVETENSOR + activation_tensors[next_name]->saveNData(layer_next_name); +#endif + output_result.push_back(*activation_tensors[next_name]); + } + return output_result; +} +std::vector XnnpackBackend::runForward(Module *module, std::vector inputs, std::vector args) { + // set static tmp_device to device_ to init layers' op + // auto previoud_device = Module::tmp_device; + // Module::tmp_device = module->device_; + // Module Loading + if (Module::llm_model_ptr && Module::llm_model_ptr->doLoad) { + auto outputs = module->Forward(inputs, args); + // for inner module, set output tensors to GRAPH_OUTPUT + // if (inputs[0].ttype() != TensorType::INPUT_TENSOR) { // XPUs' module should not be the outermost input tensor + // for (auto &output : outputs) { + // inputs[0].module()->activation_tensors[output.name()]->setTtype(GRAPH_OUTPUT); + // } + // } + // // set Module::tmp_device to previous device + // Module::tmp_device = previoud_device; + return outputs; + } + // if (false) { + // inputs[0].setTtype(TensorType::INPUT_TENSOR); + // } + // Module setUp & execute + if (inputs[0].ttype() == TensorType::INPUT_TENSOR) { + if (module->prefilling_token_size_ == 0) { // first time init + module->prefilling_token_size_ = inputs[0].sequence(); + } else if (module->decoding_token_size_ == 0) { + module->decoding_token_size_ = inputs[0].sequence(); + } + for (int i = 0; i < inputs.size(); i++) { + auto &input = inputs[i]; + input.setName("input" + std::to_string(i)); + input.setTtype(TensorType::NORMAL_TENSOR); + module->activation_tensors[input.name()] = std::shared_ptr(&input, [](Tensor *) {}); + module->activation_tensors[input.name()]->setName(input.name()); + module->activation_tensors[input.name()]->setModule(module); + } + Module::llm_model_ptr = module; + Tensor::tensor_status = TENSOR_STATIC_INIT; + + uint64_t time_start = mllm_time_us(); + module->Forward(inputs, args); + Tensor::tensor_status = TENSOR_STATIC_READY; // change to EAGER + + auto output = module->Forward(inputs, args); + uint64_t time_end = mllm_time_us(); + + double inference_time_ = (time_end - time_start) / 1000.0F; // ms + module->inference_times_.push_back(inference_time_); + + Module::llm_model_ptr->op_transposed_flag = true; + return output; + } else { // inner Modules + // offload according to the backends' info inited during loading + if (Tensor::tensor_status == TENSOR_STATIC_INIT && module->device_ != MLLM_CPU) { // backend specific module reshape & setup + if (Module::isMultiChunkPrefilling && !Module::isFirstChunk) { // set to TENSOR_UNDEFINED and SKIP executing qnn layers + Tensor::tensor_status = TENSOR_UNDEFINED; + auto outputs = module->Forward(inputs, args); + Tensor::tensor_status = TENSOR_STATIC_INIT; + return outputs; + } + auto inputs_vec = vector>(); + auto outputs_vec = vector>(); + for (auto &i : inputs) { + inputs_vec.push_back(inputs[0].module()->activation_tensors[i.name()]); + } + + Backend::global_backends[module->device_]->onSetUpStart(inputs_vec, outputs_vec, module->getUniqueName()); + + // for xnnpack currently + for (auto &i : inputs) { + i.uuid() = inputs[0].module()->activation_tensors[i.name()]->uuid(); + } + + auto outputs = module->Forward(inputs, args); + for (auto &output : outputs) { + outputs_vec.push_back(inputs[0].module()->activation_tensors[output.name()]); + } + Backend::global_backends[module->device_]->onSetUpEnd(inputs_vec, outputs_vec, module->getUniqueName()); + + // for xnnpack currently + for (auto &o : outputs) { + o.uuid() = outputs[0].module()->activation_tensors[o.name()]->uuid(); + } + + return outputs; + } else if (Tensor::tensor_status == TENSOR_STATIC_READY && module->device_ != MLLM_CPU) { // backend specific module execute + auto inputs_vec = vector>(); + auto outputs_vec = vector>(); + for (auto &i : inputs) { + inputs_vec.push_back(inputs[0].module()->activation_tensors[i.name()]); + } + + auto outputs = module->Forward(inputs, args); + + for (auto &output : outputs) { + outputs_vec.push_back(inputs[0].module()->activation_tensors[output.name()]); + } + Backend::global_backends[module->device_]->onExecuteStart(inputs_vec, outputs_vec, module->getUniqueName()); + + Backend::global_backends[module->device_]->onExecuteEnd(outputs_vec, module->getUniqueName()); + + // for xnnpack currently + for (auto &o : outputs) { + o.uuid() = outputs[0].module()->activation_tensors[o.name()]->uuid(); + o.forceResetHostPointer(outputs[0].module()->activation_tensors[o.name()]->rawHostPtr()); + } + + return outputs; + } else if (Tensor::tensor_status == TENSOR_STATIC_TRACE && module->device_ != MLLM_CPU) { + auto inputs_vec = vector>(); + auto outputs_vec = vector>(); + for (auto &i : inputs) { + inputs_vec.push_back(inputs[0].module()->activation_tensors[i.name()]); + } + + auto outputs = module->Forward(inputs, args); + + for (auto &output : outputs) { + outputs_vec.push_back(inputs[0].module()->activation_tensors[output.name()]); + } + Tracer::addModule(inputs_vec, outputs_vec, module->getUniqueName()); + return outputs; + } + return module->Forward(inputs, args); + } +} + } // namespace mllm::xnnpack \ No newline at end of file diff --git a/src/backends/xnnpack/XnnpackBackend.hpp b/src/backends/xnnpack/XnnpackBackend.hpp index 3f39d3297..6875e825e 100644 --- a/src/backends/xnnpack/XnnpackBackend.hpp +++ b/src/backends/xnnpack/XnnpackBackend.hpp @@ -18,7 +18,10 @@ #include "Types.hpp" #include "pthreadpool.h" #include "xnnpack.h" - +namespace mllm { +class Module; +class Layer; +} namespace mllm::xnnpack { class XnnpackModelRuntime { @@ -169,6 +172,16 @@ class XnnpackBackend : public Backend { void onExecuteEnd(std::vector> &outputs, const string &graph_name) override; + + std::vector runFunc( + std::vector out_names, + TensorFuncType type, + std::vector float_args, + std::vector> input_tensors, + bool in_place) override; + std::vector runLayer(Layer *layer, std::vector inputs, int N) override; + std::vector runForward(Module *module, std::vector inputs, std::vector args) override; + XnnpackCargo *getCurProcessingGraph(); static int xnn_threads; diff --git a/src/memory/SystemMemoryManager.cpp b/src/memory/SystemMemoryManager.cpp index 04929edb8..f2f94ac64 100644 --- a/src/memory/SystemMemoryManager.cpp +++ b/src/memory/SystemMemoryManager.cpp @@ -3,7 +3,13 @@ #include #include #include + +// macOS 特定的内存大小查询头文件 +#ifdef __APPLE__ +#include +#else #include +#endif namespace mllm { @@ -28,13 +34,18 @@ void SystemMemoryManager::alloc(void **ptr, size_t size, size_t alignment) { void SystemMemoryManager::free(void *ptr) { if (ptr != nullptr) { -#ifdef _WIN32 - if (_msize(((void **)ptr)[-1]) > 0) { - ::free(((void **)ptr)[-1]); + void *origin = ((void **)ptr)[-1]; // 取出原始指针 +#if defined(_WIN32) + if (_msize(origin) > 0) { + ::free(origin); } -#else - if (malloc_usable_size(((void **)ptr)[-1]) > 0) { - ::free(((void **)ptr)[-1]); +#elif defined(__APPLE__) + if (malloc_size(origin) > 0) { // macOS 平台使用 malloc_size + ::free(origin); + } +#else // Linux 和其他类 Unix 系统 + if (malloc_usable_size(origin) > 0) { + ::free(origin); } #endif } diff --git a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp index c2ebd5567..a8a6b9923 100644 --- a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp +++ b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp @@ -374,7 +374,7 @@ class MiniCPMForCausalLM final : public Module { omp_set_max_active_levels(2); // Enable OpenMP nesting #pragma omp parallel num_threads(2) if (omp_get_thread_num() == 0) { // 根据线程ID决定执行哪个函数 -#if defined(__ARM_NEON) +#if defined(__ARM_NEON) && !defined(__APPLE__) // 绑定线程到特定的CPU核心 cpu_set_t cpuset; CPU_ZERO(&cpuset); diff --git a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp index f2254cdf6..27042fdcd 100644 --- a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp +++ b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp @@ -396,7 +396,7 @@ class MiniCPMForCausalLM final : public Module { omp_set_max_active_levels(2); // Enable OpenMP nesting #pragma omp parallel num_threads(2) if (omp_get_thread_num() == 0) { // 根据线程ID决定执行哪个函数 -#if defined(__ARM_NEON) +#if defined(__ARM_NEON)&& !defined(__APPLE__) { struct sched_param param; param.sched_priority = 20; // 范围 1–99,根据设备可酌情调整 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 89b8a17eb..2ba7123bc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,7 +13,7 @@ if(MLLM_BUILD_XNNPACK_BACKEND) ${PROJECT_SOURCE_DIR}/test/xnnpack/*.cpp ) list(APPEND MLLM_XNNPACK_BACKEND_TEST_SRC ${_MLLM_XNNPACK_BACKEND_TEST_SRC}) - list(APPEND MLLM_XNNPACK_BACKEND_TEST_DEP_LIB MllmXnnpackBackend) + list(APPEND MLLM_XNNPACK_BACKEND_TEST_DEP_LIB lib_mllm_xnnpack) list(REMOVE_ITEM MLLM_XNNPACK_BACKEND_TEST_SRC ${PROJECT_SOURCE_DIR}/test/xnnpack/XpEmbeddingTest.cpp) endif() @@ -53,7 +53,7 @@ add_executable( target_link_libraries( MLLM_TEST GTest::gtest_main - MLLM_CPU + lib_mllm_cpu -fopenmp ${MLLM_XNNPACK_BACKEND_TEST_DEP_LIB} ) From 6aa288178f56318d994a41a02c4a9765af3b9f8d Mon Sep 17 00:00:00 2001 From: yirongjie Date: Wed, 11 Jun 2025 17:45:26 +0000 Subject: [PATCH 06/22] feat: add showui-cut in vtp; --- examples/CMakeLists.txt | 1 + examples/demo_qwen2_vl_vtp.cpp | 58 ++ examples/demo_showui_vtp.cpp | 3 +- src/models/qwen2_vl/modeling_qwen2_vl.hpp | 6 +- src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp | 21 +- .../qwen2_vl/vtp/processing_qwen2_vl.hpp | 640 ++++++++++++++++++ src/models/qwen2_vl/vtp/ui_tools.hpp | 86 +++ 7 files changed, 806 insertions(+), 9 deletions(-) create mode 100644 examples/demo_qwen2_vl_vtp.cpp create mode 100644 src/models/qwen2_vl/vtp/processing_qwen2_vl.hpp create mode 100644 src/models/qwen2_vl/vtp/ui_tools.hpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f12cd17bf..50287817e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -104,6 +104,7 @@ func_vlm_add_executable(demo_imagebind_1mod) func_vlm_add_executable(demo_phi3v) func_vlm_add_executable(demo_qwen2_vl) func_vlm_add_executable(demo_showui) +func_vlm_add_executable(demo_qwen2_vl_vtp) func_vlm_add_executable(demo_showui_vtp) if(QNN) diff --git a/examples/demo_qwen2_vl_vtp.cpp b/examples/demo_qwen2_vl_vtp.cpp new file mode 100644 index 000000000..f24132308 --- /dev/null +++ b/examples/demo_qwen2_vl_vtp.cpp @@ -0,0 +1,58 @@ +#include +#include "cmdline.h" +#include "models/qwen2_vl/configuration_qwen2_vl.hpp" +#include "models/qwen2_vl/vtp/modeling_qwen2_vl.hpp" +#include "models/qwen2_vl/vtp/processing_qwen2_vl.hpp" +#include "processor/PostProcess.hpp" + +using namespace mllm; +int main(int argc, char **argv) { + cmdline::parser cmdParser; + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2vl_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2vl_merges.txt"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); + cmdParser.add("limits", 'l', "max KV cache size", false, 800); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + int tokens_limit = cmdParser.get("limits"); + int thread_num = cmdParser.get("thread"); + CPUBackend::cpu_threads = cmdParser.get("thread"); + + ParamLoader param_loader(model_path); + auto processor = Qwen2VLProcessor(vocab_path, merge_path); + Qwen2VLConfig config(tokens_limit, "1.5b"); + auto model = Qwen2VLModel(config); + model.load(model_path); + + vector in_imgs = { + "../assets/bus.png"}; + vector in_strs = { + "<|vision_start|><|image_pad|><|vision_end|>Describe this image.", + }; + + for (int i = 0; i < in_strs.size(); ++i) { + auto in_str = in_strs[i]; + in_str = processor.tokenizer->apply_chat_template(in_str); + auto input_tensor = processor.process(in_str, in_imgs[i]); + std::cout << "[Q] " << in_strs[i] << std::endl; + std::cout << "[A] " << std::flush; + for (int step = 0; step < 100; step++) { + model.get_position_ids(input_tensor); + auto result = model(input_tensor); + auto outputs = processor.detokenize(result[0]); + auto out_string = outputs.first; + auto out_token = outputs.second; + auto [not_end, output_string] = processor.tokenizer->postprocess(out_string); + if (!not_end) { break; } + std::cout << output_string << std::flush; + chatPostProcessing(out_token, input_tensor[0], {&input_tensor[1], &input_tensor[2]}); + } + printf("\n"); + } + + return 0; +} \ No newline at end of file diff --git a/examples/demo_showui_vtp.cpp b/examples/demo_showui_vtp.cpp index cce2597c9..d0d5a5415 100644 --- a/examples/demo_showui_vtp.cpp +++ b/examples/demo_showui_vtp.cpp @@ -2,9 +2,8 @@ #include #include "cmdline.h" #include "models/qwen2_vl/configuration_qwen2_vl.hpp" -// #include "models/qwen2_vl/modeling_qwen2_vl.hpp" #include "models/qwen2_vl/vtp/modeling_qwen2_vl.hpp" -#include "models/qwen2_vl/processing_qwen2_vl.hpp" +#include "models/qwen2_vl/vtp/processing_qwen2_vl.hpp" #include "processor/PostProcess.hpp" using namespace mllm; diff --git a/src/models/qwen2_vl/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/modeling_qwen2_vl.hpp index 793b4a118..c9c4abad9 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl.hpp @@ -175,9 +175,9 @@ class Qwen2VisionModel final : public Module { vector Forward(vector inputs, vector args) override { auto hidden_states = patch_embed({inputs[0]})[0]; auto rotary_pos_emb = rot_pos_emb(inputs[1]); - auto grid_t = inputs[0].dataAt(0, 0, 0, 0); - auto grid_h = inputs[0].dataAt(0, 0, 0, 1); - auto grid_w = inputs[0].dataAt(0, 0, 0, 2); + auto grid_t = inputs[1].dataAt(0, 0, 0, 0); + auto grid_h = inputs[1].dataAt(0, 0, 0, 1); + auto grid_w = inputs[1].dataAt(0, 0, 0, 2); vector cu_seqlens_v = {0.0F, grid_t * grid_h * grid_w}; auto cu_seqlens = Tensor(cu_seqlens_v); for (auto &block : blocks) { diff --git a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp index 5d3c179e2..0fa959991 100644 --- a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp @@ -5,8 +5,8 @@ #define MODELING_QWEN2VL_HPP // #define VTP -#include #define NDC +#define SUC #include "Layer.hpp" #include "Module.hpp" @@ -19,8 +19,12 @@ #ifdef NDC #include "ndc_tools.hpp" #endif +#ifdef SUC +#include "ui_tools.hpp" +#endif #include #include +#include using namespace mllm; @@ -176,10 +180,19 @@ class Qwen2VisionModel final : public Module { vector Forward(vector inputs, vector args) override { auto hidden_states = patch_embed({inputs[0]})[0]; auto rotary_pos_emb = rot_pos_emb(inputs[1]); - auto grid_t = inputs[0].dataAt(0, 0, 0, 0); - auto grid_h = inputs[0].dataAt(0, 0, 0, 1); - auto grid_w = inputs[0].dataAt(0, 0, 0, 2); + auto grid_t = inputs[1].dataAt(0, 0, 0, 0); + auto grid_h = inputs[1].dataAt(0, 0, 0, 1); + auto grid_w = inputs[1].dataAt(0, 0, 0, 2); vector cu_seqlens_v = {0.0F, grid_t * grid_h * grid_w}; +#ifdef SUC + std::vector> region_masks = {UIRegionMask}; + auto selected_indices = process_region_mask(region_masks); + if (selected_indices.size() != cu_seqlens_v[1]) { + cu_seqlens_v[1] = float(selected_indices.size()); + rotary_pos_emb = rotary_pos_emb.clip(selected_indices, SEQUENCE); + hidden_states = hidden_states.clip(selected_indices, SEQUENCE); + } +#endif auto cu_seqlens = Tensor(cu_seqlens_v); for (auto &block : blocks) { hidden_states = block({hidden_states, cu_seqlens, rotary_pos_emb})[0]; diff --git a/src/models/qwen2_vl/vtp/processing_qwen2_vl.hpp b/src/models/qwen2_vl/vtp/processing_qwen2_vl.hpp new file mode 100644 index 000000000..f8214b481 --- /dev/null +++ b/src/models/qwen2_vl/vtp/processing_qwen2_vl.hpp @@ -0,0 +1,640 @@ +// +// Created by Rongjie Yi on 25-2-9. +// + +#ifndef PROCESSING_Qwen2VL_HPP +#define PROCESSING_Qwen2VL_HPP +#include +#include "OpDefined.hpp" +#include "processor/PreProcess.hpp" +#include "tokenizers/Tokenizer.hpp" +#include "models/qwen/tokenization_qwen.hpp" +#include +#include +#include +#include +#include +#include +#ifndef STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_STATIC +#define STB_IMAGE_IMPLEMENTATION +#endif +#include "stb/stb_image.h" +#ifndef STB_IMAGE_RESIZE_IMPLEMENTATION +#define STB_IMAGE_RESIZE_STATIC +#define STB_IMAGE_RESIZE_IMPLEMENTATION +#endif +#include "stb/stb_image_resize2.h" +#include "ui_tools.hpp" +#include +#include + +using namespace std; +using namespace mllm; +// 调整图像尺寸使其成为28的倍数 +std::pair smart_resize(int height, int width, int factor = 28, + int min_pixels = 3136, int max_pixels = 12845056) { + // Check aspect ratio condition + int MAX_RATIO = 200; + if (std::max(height, width) / static_cast(std::min(height, width)) > MAX_RATIO) { + throw std::invalid_argument("Absolute aspect ratio must be smaller than " + std::to_string(MAX_RATIO)); + } + + auto round_by_factor = [](int value, int f) { return ((value + f / 2) / f) * f; }; + auto floor_by_factor = [](float value, int f) { return static_cast(std::floor(value / f)) * f; }; + auto ceil_by_factor = [](float value, int f) { return static_cast(std::ceil(value / f)) * f; }; + + int h_bar = std::max(factor, round_by_factor(height, factor)); + int w_bar = std::max(factor, round_by_factor(width, factor)); + + if (h_bar * w_bar > max_pixels) { + float beta = std::sqrt((height * width) / static_cast(max_pixels)); + h_bar = floor_by_factor(height / beta, factor); + w_bar = floor_by_factor(width / beta, factor); + } else if (h_bar * w_bar < min_pixels) { + float beta = std::sqrt(min_pixels / static_cast(height * width)); + h_bar = ceil_by_factor(height * beta, factor); + w_bar = ceil_by_factor(width * beta, factor); + } + return {h_bar, w_bar}; +} +stbir_pixel_layout get_pixel_layout(int channels) { + switch (channels) { + case 1: return STBIR_1CHANNEL; + case 2: return STBIR_2CHANNEL; + case 3: return STBIR_RGB; + case 4: return STBIR_RGBA; + default: + throw std::invalid_argument("Unsupported number of channels: " + std::to_string(channels)); + } +} + +double compute_mse(const uint8_t *patch1, const uint8_t *patch2, int patch_size, int channels, int image_width_pixels) { + long long sum_sq_diff = 0; + + // 图像一行的字节数,即步长(stride) + const int stride_bytes = image_width_pixels * channels; + // patch一行的字节数 + const int patch_row_bytes = patch_size * channels; + + // 逐行遍历 patch + for (int r = 0; r < patch_size; ++r) { + // 计算当前行在 patch1 和 patch2 中的起始地址 + const uint8_t *p1_row_start = patch1 + r * stride_bytes; + const uint8_t *p2_row_start = patch2 + r * stride_bytes; + + // 比较当前行中的所有字节 + for (int c = 0; c < patch_row_bytes; ++c) { + int diff = static_cast(p1_row_start[c]) - static_cast(p2_row_start[c]); + sum_sq_diff += diff * diff; + } + } + + int num_values = patch_size * patch_size * channels; + if (num_values == 0) return 0.0; + + // 使用 double 来保证精度 + return static_cast(sum_sq_diff) / num_values; +} + +// 对应 Python 的 gen_region_masks 函数,生成一个 H x W 的像素级掩码 +// 这个函数在你最初的代码里是正确的,我们现在必须使用它。 +std::vector gen_pixel_level_region_masks(int H, int W, + const std::vector>> &rows_regions, + int patch_size) { + std::vector ret(H * W, 0); + uint32_t cnt = 0; + for (int i = 0; i < rows_regions.size(); ++i) { // i 是 patch 的行索引 + const auto ®ions = rows_regions[i]; + for (const auto ®ion : regions) { + int start_col = region.first; + int end_col = region.second; + + int y_start = i * patch_size; + int y_end = std::min((i + 1) * patch_size, H); + int x_start = start_col * patch_size; + int x_end = std::min((end_col + 1) * patch_size, W); + + for (int y = y_start; y < y_end; ++y) { + for (int x = x_start; x < x_end; ++x) { + ret[y * W + x] = cnt; + } + } + cnt++; // 每个区域使用一个独一无二的ID + } + } + return ret; +} + +// 主函数:process_image_region 的最终正确版本 +std::vector process_image_region(uint8_t *image_data, int width, int height, int channels, float threshold) { + const int patch_size = 28; + + // 步骤 1: 调整图像尺寸 (使用和 Python 一致的参数) + // 修正致命错误: max_pixels 必须与 Python 脚本中保持一致。 + const int min_pixels_val = 4 * 28 * 28; // + const int max_pixels_val = 16384 * 28 * 28; // + auto [new_height, new_width] = smart_resize(height, width, patch_size, min_pixels_val, max_pixels_val); + + // --- 图像缩放逻辑 (保持不变) --- + uint8_t *resized_data = nullptr; + uint8_t *data_ptr = image_data; + bool resized = false; + if (new_width != width || new_height != height) { + resized_data = new uint8_t[new_width * new_height * channels]; + resized = true; + stbir_pixel_layout layout = get_pixel_layout(channels); + stbir_resize(image_data, width, height, 0, resized_data, new_width, new_height, 0, layout, STBIR_TYPE_UINT8, STBIR_EDGE_CLAMP, STBIR_FILTER_DEFAULT); + data_ptr = resized_data; + width = new_width; + height = new_height; + } + + const int num_patch_rows = height / patch_size; + const int num_patch_cols = width / patch_size; + + // 步骤 2: 按行查找区域 (与之前相同,逻辑正确) + std::vector> patches(num_patch_rows, std::vector(num_patch_cols)); + for (int i = 0; i < num_patch_rows; ++i) { + for (int j = 0; j < num_patch_cols; ++j) { + patches[i][j] = data_ptr + (i * patch_size * width * channels) + (j * patch_size * channels); + } + } + + std::vector>> rows_regions; + rows_regions.reserve(num_patch_rows); + int row_index = 0; + for (const auto row_of_patches : patches) { + if (row_of_patches.empty()) { + row_index++; + continue; + } + std::vector> regions; + int start_col = 0; + for (int j = 0; j < num_patch_cols - 1; ++j) { + double mse = compute_mse(row_of_patches[j], row_of_patches[j + 1], patch_size, channels, width); + // 在这里打印关键信息 + // printf("[C++] row: %d, j: %d, mse: %.10f, mse >= threshold: %s\n", + // row_index, j, mse, (mse >= threshold ? "true" : "false")); + if (mse >= threshold) { + regions.emplace_back(start_col, j); + start_col = j + 1; + } + } + regions.emplace_back(start_col, num_patch_cols - 1); + rows_regions.push_back(regions); + } + + // 步骤 3: (必须执行) 生成与图像一样大的像素级掩码,完全复现Python行为 + std::vector pixel_mask = gen_pixel_level_region_masks(height, width, rows_regions, patch_size); + + // 步骤 4: (必须执行) 通过对像素级掩码进行采样,生成最终的块级掩码 + // 这将保证最终输出的 vector 大小是 num_patch_rows * num_patch_cols + std::vector patched_region_mask; + patched_region_mask.reserve(num_patch_rows * num_patch_cols); + + for (int i = 0; i < num_patch_rows; ++i) { + for (int j = 0; j < num_patch_cols; ++j) { + // 获取每个 patch 左上角像素的坐标 + int y_pixel = i * patch_size; + int x_pixel = j * patch_size; + // 从像素掩码中采样该点的ID,作为这个 patch 的ID + // 这等效于 Python 中的 .max(),因为同一个区域内的像素ID都相同 + patched_region_mask.push_back(pixel_mask[y_pixel * width + x_pixel]); + } + } + + if (resized) { + delete[] resized_data; + } + + return patched_region_mask; +} +// // 全局区域掩码 +// std::vector UIRegionMask; +// 定义二维点结构 + +Tensor vector3d2Tensor(vector>> img, string name = "input", BackendType type = MLLM_CPU) { + int channel = img.size(); + int height = img[0].size(); + int width = img[0][0].size(); + Tensor tensor1(1, height, channel, width, Backend::global_backends[type], true); + tensor1.setName(std::move(name)); + Tensor::tensor_status = TENSOR_STATIC_INIT; + tensor1.setTtype(INPUT_TENSOR); + for (int h = 0; h < height; ++h) { + for (int c = 0; c < channel; ++c) { + for (int w = 0; w < width; ++w) { + tensor1.setDataAt(0, h, c, w, img[c][h][w]); + } + } + } + return tensor1; +} +Tensor vector3d2Tensor(vector>> img, string name = "input", BackendType type = MLLM_CPU) { + int channel = img.size(); + int height = img[0].size(); + int width = img[0][0].size(); + Tensor tensor1(1, height, channel, width, Backend::global_backends[type], true); + tensor1.setName(std::move(name)); + Tensor::tensor_status = TENSOR_STATIC_INIT; + tensor1.setTtype(INPUT_TENSOR); + for (int h = 0; h < height; ++h) { + for (int c = 0; c < channel; ++c) { + for (int w = 0; w < width; ++w) { + tensor1.setDataAt(0, h, c, w, (float)img[c][h][w]); + } + } + } + return tensor1; +} + +class Qwen2VLImageProcessor { +public: + int merge_size = 2; + +private: + std::vector mean_ = {0.48145466, 0.4578275, 0.40821073}; + std::vector std_ = {0.26862954, 0.26130258, 0.27577711}; + int IMAGE_FACTOR = 28; + int MIN_PIXELS = 4 * 28 * 28; + int MAX_PIXELS = 16384 * 28 * 28; + int MAX_RATIO = 200; + int temporal_patch_size = 2; + int patch_size = 14; + + void viewTensor(Tensor &tensor1) { + assert(3 * 2 * 14 * 14 == tensor1.dimension()); + tensor1.reshape(tensor1.sequence(), 3, 2, 14, 14); + } + + std::pair smart_resize(int height, int width, int factor = 28, + int min_pixels = 3136, int max_pixels = 12845056) { + // Check aspect ratio condition + if (std::max(height, width) / static_cast(std::min(height, width)) > MAX_RATIO) { + throw std::invalid_argument("Absolute aspect ratio must be smaller than " + std::to_string(MAX_RATIO)); + } + + auto round_by_factor = [](int value, int f) { return ((value + f / 2) / f) * f; }; + auto floor_by_factor = [](float value, int f) { return static_cast(std::floor(value / f)) * f; }; + auto ceil_by_factor = [](float value, int f) { return static_cast(std::ceil(value / f)) * f; }; + + int h_bar = std::max(factor, round_by_factor(height, factor)); + int w_bar = std::max(factor, round_by_factor(width, factor)); + + if (h_bar * w_bar > max_pixels) { + float beta = std::sqrt((height * width) / static_cast(max_pixels)); + h_bar = floor_by_factor(height / beta, factor); + w_bar = floor_by_factor(width / beta, factor); + } else if (h_bar * w_bar < min_pixels) { + float beta = std::sqrt(min_pixels / static_cast(height * width)); + h_bar = ceil_by_factor(height * beta, factor); + w_bar = ceil_by_factor(width * beta, factor); + } + return {h_bar, w_bar}; + } + + ImageInfo fetch_image(ImageInfo &image) { + int old_height = image.height; + int old_width = image.width; + auto [new_height, new_width] = smart_resize(old_height, old_width, IMAGE_FACTOR, MIN_PIXELS, MAX_PIXELS); + std::vector temp_image_info = {image}; + auto image_n = PreProcessor::ResizeImages({temp_image_info}, new_height, new_width, true)[0]; + // delete[] image.data; + // image.data = nullptr; + return image_n; + } + + pair>, vector> convertPatches( + const vector>>> &imgs, + int temporal_patch_size, + int patch_size, + int merge_size, + int resized_height, + int resized_width) { + int batch = imgs.size(); + int channel = (batch == 0) ? 0 : imgs[0].size(); + vector shape = {0, 0, 0}; + // 检查输入有效性 + if (batch == 0 || channel == 0 || batch % temporal_patch_size != 0 || resized_height % patch_size != 0 || resized_width % patch_size != 0 || (resized_height / patch_size) % merge_size != 0 || (resized_width / patch_size) % merge_size != 0) { + return make_pair(vector>(), shape); + } + // 计算网格维度 + int grid_t = batch / temporal_patch_size; + int grid_h = resized_height / patch_size; + int grid_w = resized_width / patch_size; + shape = {grid_t, grid_h, grid_w}; + // 计算最终矩阵维度 + int rows = grid_t * grid_h * grid_w; + int cols = channel * temporal_patch_size * patch_size * patch_size; + vector> flatten_patches(rows, vector(cols, 0.0f)); + // 预处理常用值 + int ghm = grid_h / merge_size; + int gwm = grid_w / merge_size; + int ms = merge_size; + int area_per_row = ghm * gwm * ms * ms; + // 遍历所有输出元素 + for (int i = 0; i < rows; ++i) { + // 计算时空块坐标 + int d0 = i / area_per_row; + int remaining = i % area_per_row; + int d1 = remaining / (gwm * ms * ms); + remaining %= (gwm * ms * ms); + int d2 = remaining / (ms * ms); + remaining %= (ms * ms); + int d3 = remaining / ms; + int d4 = remaining % ms; + for (int j = 0; j < cols; ++j) { + // 解析通道和时间信息 + int d5 = j / (temporal_patch_size * patch_size * patch_size); + int remaining_j = j % (temporal_patch_size * patch_size * patch_size); + int d6 = remaining_j / (patch_size * patch_size); + remaining_j %= (patch_size * patch_size); + int d7 = remaining_j / patch_size; + int d8 = remaining_j % patch_size; + // 计算原始坐标 + int b = d0 * temporal_patch_size + d6; + int c = d5; + int h = ((d1 * ms + d3) * patch_size) + d7; + int w = ((d2 * ms + d4) * patch_size) + d8; + // 边界检查并赋值 + if (b < batch && c < channel && h < resized_height && w < resized_width && imgs[b].size() > c && imgs[b][c].size() > h && imgs[b][c][h].size() > w) { + flatten_patches[i][j] = imgs[b][c][h][w]; + } + } + } + + return make_pair(flatten_patches, shape); + } + +public: + explicit Qwen2VLImageProcessor() { + } + + void set_pixels(int min_pixelS = 4 * 28 * 28, int max_pixels = 16384 * 28 * 28) { + MIN_PIXELS = min_pixelS; + MAX_PIXELS = max_pixels; + } + vector> input_ids_; + pair>, vector> preprocess_images(const uint8_t *image, const size_t &image_length) { + auto imageinfos = vector(); + int width, height, channels; + auto data = stbi_load_from_memory(image, image_length, &width, &height, &channels, 0); + if (data == nullptr) { + MLLM_LOG_ERROR_STREAM << "Error: Failed to load image from memory." << std::endl; + exit(-1); + } + + // 如果是 ARGB 四通道,转换为 RGB 三通道 + if (channels == 4) { + uint8_t *rgb_data = new uint8_t[width * height * 3]; + for (int i = 0; i < width * height; ++i) { + rgb_data[i * 3 + 0] = data[i * 4 + 1]; // R + rgb_data[i * 3 + 1] = data[i * 4 + 2]; // G + rgb_data[i * 3 + 2] = data[i * 4 + 3]; // B + } + stbi_image_free(data); // 释放原始 ARGB 数据 + data = rgb_data; // 替换为 RGB 数据 + channels = 3; // 更新通道数 + } + float threshold = 10.0f; + UIRegionMask = process_image_region(data, width, height, channels, threshold); + + float *f32_data = nullptr; + f32_data = PreProcessor::RescaleImage(data, 255, width * height * channels); + stbi_image_free(data); + auto image_info = ImageInfo(f32_data, width, height, channels); + image_info = fetch_image(image_info); + imageinfos.emplace_back(image_info); + imageinfos = PreProcessor::NormalizeImages(imageinfos, mean_, std_); + imageinfos.emplace_back(imageinfos[0]); + vector>>> pixel_v; + PreProcessor::ImageInfos2Pixels(imageinfos, pixel_v); + auto result_patches = convertPatches(pixel_v, + temporal_patch_size, + patch_size, + merge_size, + imageinfos[0].height, // resized_height + imageinfos[0].width // resized_width + ); + return result_patches; + } + + pair>> process(const std::vector &image, const std::vector &image_length, bool view_img = true) { + vector>> pixel_values; + vector> vision_grid_thws; + for (int i = 0; i < image.size(); i++) { + auto data = image[i]; + auto size = image_length[i]; + auto result_patches = preprocess_images(data, size); + auto flatten_patches = result_patches.first; + auto grid_thw = result_patches.second; + pixel_values.push_back(flatten_patches); + vision_grid_thws.push_back(grid_thw); + } + auto pixel_values_tensor = vector3d2Tensor(pixel_values, "pixel_values"); + if (view_img) { + assert(3 * 2 * 14 * 14 == pixel_values_tensor.dimension()); + pixel_values_tensor.reshape(pixel_values_tensor.head(), 3, 2, 14, 14); + } + return {pixel_values_tensor, vision_grid_thws}; + } + + pair>> process(const std::vector &images_path, bool view_img = true) { + vector>> pixel_values; + vector> vision_grid_thws; + for (const auto &i : images_path) { + // read all file contents + std::ifstream file(i, std::ios::binary | std::ios::ate); + if (!file.is_open()) { + MLLM_LOG_ERROR_STREAM << "Cannot open file: " << i << std::endl; + exit(-1); + } + auto size = file.tellg(); + auto data = new uint8_t[size]; + file.seekg(0, std::ios::beg); + file.read(reinterpret_cast(data), size); + file.close(); + auto result_patches = preprocess_images(data, size); + auto flatten_patches = result_patches.first; + auto grid_thw = result_patches.second; + pixel_values.push_back(flatten_patches); + vision_grid_thws.push_back(grid_thw); + } + auto pixel_values_tensor = vector3d2Tensor(pixel_values, "pixel_values"); + if (view_img) { + assert(3 * 2 * 14 * 14 == pixel_values_tensor.dimension()); + pixel_values_tensor.reshape(pixel_values_tensor.head(), 3, 2, 14, 14); + } + return {pixel_values_tensor, vision_grid_thws}; + } +}; + +class Qwen2VLProcessor final : public PreProcessor { + unsigned int argmax(const vector &scores) { + if (scores.empty()) { + throw std::invalid_argument("Input vector is empty"); + } + return std::max_element(scores.begin(), scores.end()) - scores.begin(); + } + // 预定义需要替换的标记 + const string IMAGE_PAD = "<|image_pad|>"; + const string PLACEHOLDER = "<|placeholder|>"; + +public: + Qwen2VLImageProcessor image_processor; + QWenTokenizer *tokenizer; + + explicit Qwen2VLProcessor(const string &vocab_path, const string &merge_path = "", + int min_pixels = 4 * 28 * 28, int max_pixels = 16384 * 28 * 28) : + PreProcessor(224, 224, true, true, true, true, {0.5}, {0.5}) { + Module::initBackend(MLLM_CPU); + tokenizer = new QWenTokenizer(vocab_path, merge_path); + tokenizer->special_tokens = { + "<|endoftext|>", + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>", + }; + tokenizer->setSpecialTokenMap({{"<|image_pad|>", 151655}, {"<|video_pad|>", 151656}}); + string system_prompt_start = "<|im_start|>system\nYou are a helpful assistant.<|im_end|>\n<|im_start|>user\n"; + string system_prompt_end = "<|im_end|>\n<|im_start|>assistant\n"; + tokenizer->set_chat_template(system_prompt_start, system_prompt_end); + image_processor.set_pixels(min_pixels, max_pixels); + } + + vector process(const string text_, string img_path, bool flatten_img = true, BackendType type = MLLM_CPU) { + string new_text = text_; + if (!img_path.empty()) { + auto image_inputs = image_processor.process({std::move(img_path)}, flatten_img); + auto pixel_values = image_inputs.first; + auto image_grid_thw = image_inputs.second; + auto merge_length = image_processor.merge_size * image_processor.merge_size; + + int index = 0; // 跟踪当前使用的网格配置索引 + const int PAD_LEN = IMAGE_PAD.length(); + const int HOLDER_LEN = PLACEHOLDER.length(); + size_t pos = 0; + // 第一阶段:替换image_pad为placeholder序列 + while (true) { + // 查找下一个需要替换的位置 + size_t found = new_text.find(IMAGE_PAD, pos); + if (found == string::npos || index >= image_grid_thw.size()) break; + // 计算需要插入的placeholder数量 + int product = 1; + for (int dim : image_grid_thw[index]) { + product *= dim; + } + int replace_num = product / merge_length; + // 构建替换字符串 + string replacement; + replacement.reserve(HOLDER_LEN * replace_num); + for (int i = 0; i < replace_num; ++i) { + replacement += PLACEHOLDER; + } + // 执行替换并更新扫描位置 + new_text.replace(found, PAD_LEN, replacement); + pos = found + replacement.length(); // 跳过已处理部分 + index++; + } + // 第二阶段:将placeholder恢复为image_pad + size_t ph_pos = 0; + while ((ph_pos = new_text.find(PLACEHOLDER, ph_pos))) { + if (ph_pos == string::npos) break; + new_text.replace(ph_pos, HOLDER_LEN, IMAGE_PAD); + ph_pos += PAD_LEN; // 跳过已替换部分 + } + auto input_tensor = tokenizer->tokenize(new_text); + auto image_grid_thw_tensor = vector3d2Tensor({image_grid_thw}, "image_grid_thw"); + return {input_tensor, pixel_values, image_grid_thw_tensor}; + } else { + auto input_tensor = tokenizer->tokenize(new_text); + return {input_tensor}; + } + } + + vector process(const std::string &text_, const std::vector &images, const std::vector &image_length, bool flatten_img = true, BackendType type = MLLM_CPU) { + string new_text = text_; + if (!images.empty()) { + auto image_inputs = image_processor.process(images, image_length, flatten_img); + auto pixel_values = image_inputs.first; + auto image_grid_thw = image_inputs.second; + auto merge_length = image_processor.merge_size * image_processor.merge_size; + + int index = 0; // 跟踪当前使用的网格配置索引 + const int PAD_LEN = IMAGE_PAD.length(); + const int HOLDER_LEN = PLACEHOLDER.length(); + size_t pos = 0; + // 第一阶段:替换image_pad为placeholder序列 + while (true) { + // 查找下一个需要替换的位置 + size_t found = new_text.find(IMAGE_PAD, pos); + if (found == string::npos || index >= image_grid_thw.size()) break; + // 计算需要插入的placeholder数量 + int product = 1; + for (int dim : image_grid_thw[index]) { + product *= dim; + } + int replace_num = product / merge_length; + // 构建替换字符串 + string replacement; + replacement.reserve(HOLDER_LEN * replace_num); + for (int i = 0; i < replace_num; ++i) { + replacement += PLACEHOLDER; + } + // 执行替换并更新扫描位置 + new_text.replace(found, PAD_LEN, replacement); + pos = found + replacement.length(); // 跳过已处理部分 + index++; + } + // 第二阶段:将placeholder恢复为image_pad + size_t ph_pos = 0; + while ((ph_pos = new_text.find(PLACEHOLDER, ph_pos))) { + if (ph_pos == string::npos) break; + new_text.replace(ph_pos, HOLDER_LEN, IMAGE_PAD); + ph_pos += PAD_LEN; // 跳过已替换部分 + } + auto input_tensor = tokenizer->tokenize(new_text); + auto image_grid_thw_tensor = vector3d2Tensor({image_grid_thw}, "image_grid_thw"); + return {input_tensor, pixel_values, image_grid_thw_tensor}; + } else { + auto input_tensor = tokenizer->tokenize(new_text); + return {input_tensor}; + } + } + + void Process(const std::string &text) override{}; + void PreProcessImages(const std::vector &images, const std::vector &image_length) override{}; + void PreProcessImages(const std::vector &images_path) override{}; + + std::string detokenize(const vector &tokens) { + return tokenizer->detokenize(tokens); + } + + std::pair detokenize(Tensor &result, int seq = 0) { + assert(result.batch() == 1 && "Batch size of result is not 1. Which is not supported for now."); + assert(result.head() == 1 && "The 3rd dim of result should be one. e.g.:[1, 1, seq, hidden]"); + vector scores; + int _dims = result.dimension(); + int _seq = seq == 0 ? result.sequence() - 1 : seq - 1; + for (int i = 0; i < _dims; ++i) { + auto value = result.dataAt(0, 0, _seq, i); + scores.push_back(value); + } + auto token_idx = this->argmax(scores); + auto text = tokenizer->detokenize({token_idx}); + text = std::regex_replace(text, std::regex("▁"), " "); + return make_pair(text, token_idx); + } +}; +#endif // PROCESSING_Qwen2VL_HPP diff --git a/src/models/qwen2_vl/vtp/ui_tools.hpp b/src/models/qwen2_vl/vtp/ui_tools.hpp new file mode 100644 index 000000000..0e2bbb609 --- /dev/null +++ b/src/models/qwen2_vl/vtp/ui_tools.hpp @@ -0,0 +1,86 @@ + +#ifndef UI_TOOLS_HPP +#define UI_TOOLS_HPP + +// 全局区域掩码 +#include +#include +#include +#include +#include // 需要包含 用于 std::sort 和 std::unique +#include // 需要包含 用于 uint32_t +std::vector UIRegionMask; +// 输入类型为二维向量 [batch][patch_size] +std::vector process_region_mask(const std::vector> ®ion_masks) { + // 1. 验证批次大小是否为1 + const int batch_size = region_masks.size(); + if (batch_size != 1) { + throw std::runtime_error("Batch size must be 1"); + } + + // 存储每个唯一标签选中的索引 + std::vector selected_indices; + + // 随机数引擎 + std::random_device rd; + std::mt19937 rng(rd()); + + // 2. 处理批次 (循环只会执行一次) + for (int batch_idx = 0; batch_idx < batch_size; ++batch_idx) { + const auto ®ion_mask = region_masks[batch_idx]; + const int patch_size = region_mask.size(); + + // 3. 获取当前批次的唯一且已排序的标签 (这是关键的修改点) + //--------------------------------------------------------- + // 旧的、基于 unordered_set 的错误方法: + // std::unordered_set unique_labels; + // for (int i = 0; i < patch_size; ++i) { + // unique_labels.insert(region_mask[i]); + // } + //--------------------------------------------------------- + + // 新的、正确的、模仿 torch.unique() 的方法: + std::vector unique_labels = region_mask; // 复制一份 + std::sort(unique_labels.begin(), unique_labels.end()); // 排序 + // 移除相邻的重复元素,并调整 vector 大小 + unique_labels.erase(std::unique(unique_labels.begin(), unique_labels.end()), unique_labels.end()); + + // 4. 为每个标签随机选择一个索引 + for (uint32_t label : unique_labels) { + // 收集所有等于当前标签的索引位置 + std::vector indices; + for (int i = 0; i < patch_size; ++i) { + if (region_mask[i] == label) { + indices.push_back(i); + } + } + + // 验证是否有区域存在 (理论上不会触发,因为标签来自 region_mask 本身) + if (indices.empty()) { + throw std::runtime_error("No region mask found for a label that should exist."); + } + + // 随机选择一个索引 + std::uniform_int_distribution dist(0, indices.size() - 1); + int selected_idx = indices[dist(rng)]; + selected_indices.push_back(selected_idx); + } + } + + // 5. 扩展索引 (这部分逻辑你的实现是完全正确的) + // 对应 PyTorch 的: selected_indices.unsqueeze(1) * 4 + torch.arange(4) + // 和 .flatten() + std::vector final_indices; + // 预分配内存以提高效率 + final_indices.reserve(selected_indices.size() * 4); + + for (int idx : selected_indices) { + for (int ch = 0; ch < 4; ++ch) { + final_indices.push_back(idx * 4 + ch); + } + } + + return final_indices; +} + +#endif \ No newline at end of file From 60da3be6d686d81e232c1940592ca695ee7a84e7 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Fri, 13 Jun 2025 23:33:40 +0800 Subject: [PATCH 07/22] feat: add klaidiai linear op --- .gitmodules | 3 + CMakeLists.txt | 61 +++- examples/demo_qwen.cpp | 5 +- examples/demo_qwen2_vl.cpp | 3 +- include/Types.hpp | 7 + src/backends/cpu/CMakeLists.txt | 92 ++++- src/backends/cpu/CPUBackend.hpp | 2 +- .../cpu/compute/ActivationFunction.hpp | 4 +- .../{GEMM_AArch64.cpp => GemmAarch64.cpp} | 2 +- .../{GEMM_AArch64.hpp => GemmAarch64.hpp} | 0 src/backends/cpu/compute/GemmKleidiai.cpp | 324 ++++++++++++++++++ src/backends/cpu/compute/GemmKleidiai.hpp | 49 +++ .../{LlamafileSGEMM.cpp => GemmLlamafile.cpp} | 4 +- .../{LlamafileSGEMM.hpp => GemmLlamafile.hpp} | 0 .../cpu/compute/{SMEGEMM.hpp => GemmSme.hpp} | 0 src/backends/cpu/compute/Matmul.cpp | 6 +- src/backends/cpu/compute/MatmulElastic.cpp | 2 +- src/backends/cpu/compute/MatmulSparse.cpp | 2 +- .../cpu/{quantize => compute}/Quantize.hpp | 0 .../cpu/{quantize => compute}/QuantizeQ2.cpp | 0 .../cpu/{quantize => compute}/QuantizeQ2.hpp | 0 .../cpu/{quantize => compute}/QuantizeQ3.cpp | 0 .../cpu/{quantize => compute}/QuantizeQ3.hpp | 0 .../cpu/{quantize => compute}/QuantizeQ4.cpp | 0 .../cpu/{quantize => compute}/QuantizeQ4.hpp | 0 .../cpu/{quantize => compute}/QuantizeQ6.cpp | 0 .../cpu/{quantize => compute}/QuantizeQ6.hpp | 0 .../cpu/{quantize => compute}/QuantizeQ8.cpp | 0 .../cpu/{quantize => compute}/QuantizeQ8.hpp | 0 src/backends/cpu/compute/SIMDMemory.hpp | 1 + src/backends/cpu/compute/VecDot.hpp | 10 +- src/backends/cpu/compute/VecDotType.cpp | 6 +- src/backends/cpu/op/CPUEmbedding.cpp | 4 +- src/backends/cpu/op/CPUIRoPE.cpp | 2 +- src/backends/cpu/op/CPULinear.cpp | 93 +++-- src/backends/cpu/op/CPULinearINT8Shadow.cpp | 2 +- src/backends/cpu/op/CPUMultimodalRoPE.cpp | 2 +- .../cpu/op/CPUMultimodalRoPEPipeline.cpp | 2 +- src/backends/cpu/op/CPUNTKRoPE.cpp | 2 +- src/backends/cpu/op/CPUQuantize.cpp | 2 +- src/backends/cpu/op/CPURoPE.cpp | 2 +- src/backends/cpu/op/CPURoPETree.cpp | 2 +- src/backends/cpu/op/CPUSoftMax.cpp | 2 +- src/backends/cpu/third_party/kleidiai | 1 + src/backends/xnnpack/Ops/XpEmbedding.cpp | 4 +- src/models/qwen2_vl/vtp/ndc_tools.hpp | 3 + src/quantizer/ParamWriter.cpp | 2 +- src/quantizer/QuantWriter.cpp | 207 ++++++++++- src/quantizer/QuantWriter.hpp | 25 +- src/quantizer/main.cpp | 11 +- 50 files changed, 854 insertions(+), 97 deletions(-) rename src/backends/cpu/compute/{GEMM_AArch64.cpp => GemmAarch64.cpp} (99%) rename src/backends/cpu/compute/{GEMM_AArch64.hpp => GemmAarch64.hpp} (100%) create mode 100644 src/backends/cpu/compute/GemmKleidiai.cpp create mode 100644 src/backends/cpu/compute/GemmKleidiai.hpp rename src/backends/cpu/compute/{LlamafileSGEMM.cpp => GemmLlamafile.cpp} (99%) rename src/backends/cpu/compute/{LlamafileSGEMM.hpp => GemmLlamafile.hpp} (100%) rename src/backends/cpu/compute/{SMEGEMM.hpp => GemmSme.hpp} (100%) rename src/backends/cpu/{quantize => compute}/Quantize.hpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ2.cpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ2.hpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ3.cpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ3.hpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ4.cpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ4.hpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ6.cpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ6.hpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ8.cpp (100%) rename src/backends/cpu/{quantize => compute}/QuantizeQ8.hpp (100%) create mode 160000 src/backends/cpu/third_party/kleidiai diff --git a/.gitmodules b/.gitmodules index b52617297..7d12c9124 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "third_party/googletest"] path = third_party/googletest url = https://github.com/google/googletest.git +[submodule "src/backends/cpu/third_party/kleidiai"] + path = src/backends/cpu/third_party/kleidiai + url = https://github.com/ARM-software/kleidiai diff --git a/CMakeLists.txt b/CMakeLists.txt index c71a5e0b3..ab975ecd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) -project(mllm) +project(mllm CXX C ASM) # 添加编译选项来禁用所有警告 # if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") @@ -193,28 +193,65 @@ file(GLOB_RECURSE SRC_TOKENIZERS if(QUANT) include_directories(${PROJECT_SOURCE_DIR}/src/quantizer) file(GLOB_RECURSE MLLM_QUANT - ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/GEMM_AArch64.hpp - ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/GEMM_AArch64.cpp - ${PROJECT_SOURCE_DIR}/src/backends/cpu/quantize/*.hpp - ${PROJECT_SOURCE_DIR}/src/backends/cpu/quantize/*.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/GemmAarch64.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ8.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ4.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ6.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ3.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ2.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/GemmKleidiai.cpp ) - file(GLOB_RECURSE MLLM_QUANTIZER - ${CMAKE_CURRENT_LIST_DIR}/src/quantizer/*.cpp - ${CMAKE_CURRENT_LIST_DIR}/src/quantizer/*.hpp) - list(REMOVE_ITEM MLLM_QUANTIZER ${CMAKE_CURRENT_LIST_DIR}/src/quantizer/main.cpp) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") + # 配置 Kleidiai 库路径 + set(KLEIDIAI_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src/backends/cpu/third_party/Kleidiai) + if(NOT EXISTS ${KLEIDIAI_SOURCE_DIR}) + message(FATAL_ERROR "Kleidiai library not found! Please place it in 'third_party/Kleidiai'.") + endif() + # 添加所有源文件路径到 MLLM_QUANT + list(APPEND MLLM_QUANT + # QSI4 模块源文件 + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod_asm.S + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.c + + # FP16 模块源文件 + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon.c + + # FP32 模块源文件 + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla_asm.S + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon.c + ) + include_directories( + # # 添加所有Kleidiai源文件路径到 MLLM_QUAN + ${KLEIDIAI_SOURCE_DIR} + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_f16_f16p + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p + ) + endif() + file(GLOB_RECURSE MLLM_QUANTIZER + ${PROJECT_SOURCE_DIR}/src/quantizer/*.cpp + ${PROJECT_SOURCE_DIR}/src/quantizer/*.hpp) + list(REMOVE_ITEM MLLM_QUANTIZER ${PROJECT_SOURCE_DIR}/src/quantizer/main.cpp) add_executable( quantize ${PROJECT_SOURCE_DIR}/src/quantizer/main.cpp ${MLLM_QUANT} ${MLLM_QUANTIZER} - - # ${DIR_SRC} ${PROJECT_SOURCE_DIR}/src/ParamLoader.cpp ) - target_link_libraries(quantize fmt::fmt-header-only) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") + message(STATUS "AArch64/arm64 architecture detected. Applying FP16 compile options to the target.") + target_compile_options(quantize PRIVATE "-march=armv8.2-a+fp16") + endif() + target_link_libraries(quantize fmt::fmt-header-only) if(FROM_GGUF) add_executable( from_gguf diff --git a/examples/demo_qwen.cpp b/examples/demo_qwen.cpp index 8d326d834..b041f2902 100644 --- a/examples/demo_qwen.cpp +++ b/examples/demo_qwen.cpp @@ -20,8 +20,9 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2.5_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2.5_merges.txt"); - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-3b-instruct-q4_0_4x4.mllm"); - cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B | 3B |]", false, "3B"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-kai_q4_0.mllm"); + // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"); + cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B | 3B |]", false, "1.5B"); cmdParser.add("limits", 'l', "max KV cache size", false, 400); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); diff --git a/examples/demo_qwen2_vl.cpp b/examples/demo_qwen2_vl.cpp index d28139e5c..8fa7bcc16 100644 --- a/examples/demo_qwen2_vl.cpp +++ b/examples/demo_qwen2_vl.cpp @@ -11,7 +11,8 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2vl_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2vl_merges.txt"); - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); + // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-kai_q4_0.mllm"); cmdParser.add("limits", 'l', "max KV cache size", false, 800); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); diff --git a/include/Types.hpp b/include/Types.hpp index 6d3bb4429..2bed483f8 100644 --- a/include/Types.hpp +++ b/include/Types.hpp @@ -81,6 +81,8 @@ enum DataType { MLLM_TYPE_IQ1_S = 28, // MLLM_TYPE_IQ1_M = 29, // MLLM_TYPE_IQ2_S = 30, + + MLLM_TYPE_KLEIDIAI_Q4_0 = 31, MLLM_TYPE_COUNT, }; @@ -405,6 +407,8 @@ static string DataTypeName(DataType dataType) { return "IQ1_M"; case MLLM_TYPE_IQ2_S: return "IQ2_S"; + case MLLM_TYPE_KLEIDIAI_Q4_0: + return "KLEIDIAI_Q4_0"; case MLLM_TYPE_COUNT: return "COUNT"; default: @@ -464,6 +468,9 @@ static size_t DataTypeSize(DataType dtype, uint64_t count = 1) { return -1; case MLLM_TYPE_IQ2_S: return -1; + case MLLM_TYPE_KLEIDIAI_Q4_0: + // std::cout << "KLEIDIAI_Q4_0 is not supported yet" << std::endl; + return sizeof(uint8_t) * count ; case MLLM_TYPE_COUNT: return 0; default: diff --git a/src/backends/cpu/CMakeLists.txt b/src/backends/cpu/CMakeLists.txt index ee3dfa26e..0a6a00e7d 100644 --- a/src/backends/cpu/CMakeLists.txt +++ b/src/backends/cpu/CMakeLists.txt @@ -1,18 +1,68 @@ # CPU Backend file(GLOB MLLM_CPU_SRC ${CMAKE_CURRENT_LIST_DIR}/*.cpp - ${CMAKE_CURRENT_LIST_DIR}/*.hpp ${CMAKE_CURRENT_LIST_DIR}/compute/*.cpp - ${CMAKE_CURRENT_LIST_DIR}/compute/*.hpp - ${CMAKE_CURRENT_LIST_DIR}/function/*.hpp - ${CMAKE_CURRENT_LIST_DIR}/op/*.hpp ${CMAKE_CURRENT_LIST_DIR}/op/*.cpp - ${CMAKE_CURRENT_LIST_DIR}/quantize/*.hpp - ${CMAKE_CURRENT_LIST_DIR}/quantize/*.cpp - ${CMAKE_CURRENT_LIST_DIR}/type/*.cpp - ${CMAKE_CURRENT_LIST_DIR}/type/*.hpp + ${CMAKE_CURRENT_LIST_DIR}/function/*.cpp ) + +# --- 初始化 Kleidiai 源文件和头文件目录 --- +set(ALL_KLEIDIAI_SOURCES "") +set(ALL_KLEIDIAI_INCLUDE_DIRS "") + + +# Conditionally compile Kleidiai for ARM architectures +if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + # --- 设置 Kleidiai 库的路径 --- + set(KLEIDIAI_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/third_party/Kleidiai) + if(NOT EXISTS ${KLEIDIAI_SOURCE_DIR}) + message(FATAL_ERROR "Kleidiai library not found! Please place it in 'third_party/Kleidiai'.") + endif() + list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS ${KLEIDIAI_SOURCE_DIR}) + + message(STATUS "Enabling kleidai QSI4_C32 MatMul implementation.") + list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack + ) + + set(KLEIDIAI_SOURCES_QSI4 + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod_asm.S + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.c + ) + list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_SOURCES_QSI4}) + + message(STATUS "Enabling kleidai FP16 MatMul implementation.") + list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_f16_f16p + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack + ) + set(KLEIDIAI_SOURCES_FP16 + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon.c + ) + list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_SOURCES_FP16}) + + message(STATUS "Enabling kleidaiFP32 MatMul implementation.") + list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack + ) + set(KLEIDIAI_SOURCES_FP32 + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla_asm.S + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon.c + ) + list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_SOURCES_FP32}) + + # 将 Kleidiai 源文件添加到主源文件列表 + list(APPEND MLLM_CPU_SRC ${ALL_KLEIDIAI_SOURCES}) +endif() # End ARM check for Kleidiai sources + + if (MLLM_OPENMP) find_package(OpenMP REQUIRED) if(OpenMP_FOUND) @@ -23,13 +73,25 @@ else() message(FATAL_ERROR "openmp not found!") endif() endif() + + + +# 架构优化标志 if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") message(STATUS "ARM detected") add_compile_options(-march=armv8.2-a+dotprod+fp16+fp16fml) + + # 特殊处理:为FP16源文件添加格式标志 + if(KLAI_USE_FP16 AND CMAKE_CROSS_COMPILING) + message(STATUS "Cross-compilation for ARM detected. Applying FP16 compiler flags.") + set_source_files_properties(${KLEIDIAI_SOURCES_FP16} + PROPERTIES COMPILE_FLAGS "-mfp16-format=ieee" + ) + endif() elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "^(x86_64|i686|AMD64)$") message(STATUS "x86_64 detected") -add_compile_options(-mavx2) -add_compile_options(-march=native) + add_compile_options(-mavx2) + add_compile_options(-march=native) endif() if(${MLLM_ENABLE_PYTHON}) @@ -46,10 +108,20 @@ add_library( ) endif() +# Conditionally add Kleidiai compile definitions for ARM +if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") + target_compile_definitions(lib_mllm_cpu PUBLIC KLAI_USE_QSI4_C32) + target_compile_definitions(lib_mllm_cpu PUBLIC KLAI_USE_FP16) + target_compile_definitions(lib_mllm_cpu PUBLIC KLAI_USE_FP32) +endif() + +# 包含头文件目录 +list(REMOVE_DUPLICATES ALL_KLEIDIAI_INCLUDE_DIRS) target_include_directories( lib_mllm_cpu PRIVATE ${CMAKE_CURRENT_LIST_DIR} + ${ALL_KLEIDIAI_INCLUDE_DIRS} ) if(OpenMP_FOUND) diff --git a/src/backends/cpu/CPUBackend.hpp b/src/backends/cpu/CPUBackend.hpp index 276139af1..1745bf100 100644 --- a/src/backends/cpu/CPUBackend.hpp +++ b/src/backends/cpu/CPUBackend.hpp @@ -4,7 +4,7 @@ #include "Backend.hpp" #include "Op.hpp" #include "Types.hpp" -#include "quantize/Quantize.hpp" +#include "compute/Quantize.hpp" namespace mllm { class Module; diff --git a/src/backends/cpu/compute/ActivationFunction.hpp b/src/backends/cpu/compute/ActivationFunction.hpp index 161cf63e1..6a120fa34 100644 --- a/src/backends/cpu/compute/ActivationFunction.hpp +++ b/src/backends/cpu/compute/ActivationFunction.hpp @@ -1,9 +1,7 @@ #ifndef ACTFUNC_HPP #define ACTFUNC_HPP - -#include "quantize/Quantize.hpp" -#include "compute/VecDot.hpp" +#include "VecDot.hpp" namespace mllm { #if defined(__ARM_NEON) && defined(__aarch64__) diff --git a/src/backends/cpu/compute/GEMM_AArch64.cpp b/src/backends/cpu/compute/GemmAarch64.cpp similarity index 99% rename from src/backends/cpu/compute/GEMM_AArch64.cpp rename to src/backends/cpu/compute/GemmAarch64.cpp index 91600ed33..933f01c54 100644 --- a/src/backends/cpu/compute/GEMM_AArch64.cpp +++ b/src/backends/cpu/compute/GemmAarch64.cpp @@ -1,4 +1,4 @@ -#include "GEMM_AArch64.hpp" +#include "GemmAarch64.hpp" #include "Types.hpp" #include #include diff --git a/src/backends/cpu/compute/GEMM_AArch64.hpp b/src/backends/cpu/compute/GemmAarch64.hpp similarity index 100% rename from src/backends/cpu/compute/GEMM_AArch64.hpp rename to src/backends/cpu/compute/GemmAarch64.hpp diff --git a/src/backends/cpu/compute/GemmKleidiai.cpp b/src/backends/cpu/compute/GemmKleidiai.cpp new file mode 100644 index 000000000..eb3cc48f0 --- /dev/null +++ b/src/backends/cpu/compute/GemmKleidiai.cpp @@ -0,0 +1,324 @@ + +#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) + +#include "GemmKleidiai.hpp" +#include +#include +#include +#include +#include + +// 引入 OpenMP 头文件 +#include +//#if defined(USE_QSI4_C32) +// ###################################################################### // +// ## Implementation 1: QSI4 (INT4) ## +// ###################################################################### // +#include "kai_matmul_clamp_f32_qai8dxp_qsi4c32p_interface.h" +#include "kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.h" +#include "kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.h" +#include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.h" + +static const kai_matmul_clamp_f32_qai8dxp_qsi4c32p_ukernel qsi4_ukernel = { + .get_m_step = kai_get_m_step_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, + .get_n_step = kai_get_n_step_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, + .get_mr = kai_get_mr_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, + .get_nr = kai_get_nr_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, + .get_kr = kai_get_kr_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, + .get_sr = kai_get_sr_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, + .get_lhs_packed_offset = kai_get_lhs_packed_offset_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, + .get_rhs_packed_offset = kai_get_rhs_packed_offset_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, + .get_dst_offset = kai_get_dst_offset_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, + .run_matmul = kai_run_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, +}; + +size_t mllm_kleidai_get_packed_b_qsi4_size(int N, int K) { + const int block_len = 32; + return kai_get_rhs_packed_size_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0( + N, K, qsi4_ukernel.get_nr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), + block_len, kai_dt_bf16); +} + +size_t get_workspace_qsi4_size(int M, int K) { + return kai_get_lhs_packed_size_lhs_quant_pack_qai8dxp_f32( + M, K, qsi4_ukernel.get_mr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr()); +} + +void mllm_kleidai_pack_b_and_bias_qsi4( + uint8_t* packed_b_ptr, + const float* b_ptr, + const float* bias_ptr, + int N, + int K) { + + // 【新增】创建临时的bias(如果需要) + const float* bias_to_use = bias_ptr; + std::vector fake_bias; + if (bias_to_use == nullptr) { + fake_bias.assign(N, 0.0f); + bias_to_use = fake_bias.data(); + } + + + const int block_len = 32; + const size_t num_blocks_k = (K + block_len - 1) / block_len; + std::vector temp_quantized_b(K * N / 2); + std::vector temp_scales(N * num_blocks_k); + + for (int n = 0; n < N; ++n) { + for (size_t kb = 0; kb < num_blocks_k; ++kb) { + float amax = 0.0f; + float max_with_sign = 0.0f; + int start_k = kb * block_len; + int end_k = std::min(start_k + block_len, K); + for (int k = start_k; k < end_k; ++k) { + const float val = b_ptr[k * N + n]; + const float abs_val = std::abs(val); + if (abs_val > amax) { + amax = abs_val; + max_with_sign = val; + } + } + const float scale = max_with_sign / -8.0f; + const float inv_scale = scale != 0.0f ? 1.0f / scale : 0.0f; + temp_scales[n * num_blocks_k + kb] = kai_cast_bf16_f32(scale); + for (int k = start_k; k < end_k; ++k) { + const float val = b_ptr[k * N + n]; + int32_t q_val = static_cast(round(val * inv_scale)); + q_val = std::max(-8, std::min(7, q_val)); + uint8_t stored_val = q_val + 8; + size_t byte_idx = (k * N + n) / 2; + if ((k * N + n) % 2 == 0) { + temp_quantized_b[byte_idx] = stored_val; + } else { + temp_quantized_b[byte_idx] |= (stored_val << 4); + } + } + } + } + kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0_params params = {}; + params.lhs_zero_point = 1; + params.rhs_zero_point = 8; + params.scale_dt = kai_dt_bf16; + // kai_run_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0( + // 1, N, K, qsi4_ukernel.get_nr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), block_len, + // temp_quantized_b.data(), K/2, bias_to_use, (const uint8_t*)temp_scales.data(), num_blocks_k * sizeof(uint16_t), + // packed_b_ptr, 0, ¶ms); + kai_run_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0( + 1, N, K, qsi4_ukernel.get_nr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), block_len, + temp_quantized_b.data(), N/2, bias_to_use, (const uint8_t*)temp_scales.data(), num_blocks_k * sizeof(uint16_t), + packed_b_ptr, 0, ¶ms); +} + +void mllm_kleidai_gemm_qsi4( + float* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, + int M, int N, int K) { + + size_t workspace_size = get_workspace_qsi4_size(M, K); + std::vector workspace_data(workspace_size); + + kai_run_lhs_quant_pack_qai8dxp_f32( + M, K, + qsi4_ukernel.get_mr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), + 0, + a_ptr, K * sizeof(float), + workspace_data.data()); + + + const int m_step = qsi4_ukernel.get_m_step(); + const int n_step = qsi4_ukernel.get_n_step(); + const int block_len = 32; + + // #pragma omp parallel for + #pragma omp parallel for collapse(2) num_threads(kai_thread_count) + for (int m_start = 0; m_start < M; m_start += m_step) { + for (int n_start = 0; n_start < N; n_start += n_step) { + const int current_m = std::min(M - m_start, m_step); + const int current_n = std::min(N - n_start, n_step); + const void* a_packed_offset = (const char*)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); + const void* b_packed_offset = (const char*)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); + float* c_offset = c_ptr + m_start * N + n_start; + qsi4_ukernel.run_matmul( + current_m, current_n, K, block_len, + a_packed_offset, b_packed_offset, + c_offset, N * sizeof(float), sizeof(float), + -FLT_MAX, FLT_MAX + ); + } + } +} +// #endif + +// 【新增】 +//#if defined(USE_QSI4_TO_FP16) +// ###################################################################### // +// ## Implementation 1.5: QSI4 (INT4) -> FP16 ## +// ###################################################################### // +void mllm_kleidai_gemm_qsi4_to_fp16( + mllm_fp16_t* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, + int M, int N, int K) { + + // 1. 创建一个临时的 FP32 输出缓冲区 + std::vector c_temp(M * N); + + // 2. 运行现有的 QSI4->FP32 GEMM 计算,将结果存入临时缓冲区 + size_t workspace_size = get_workspace_qsi4_size(M, K); + std::vector workspace_data(workspace_size); + kai_run_lhs_quant_pack_qai8dxp_f32(M, K, qsi4_ukernel.get_mr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), + 0, a_ptr, K * sizeof(float), workspace_data.data()); + + const int m_step = qsi4_ukernel.get_m_step(); + const int n_step = qsi4_ukernel.get_n_step(); + const int block_len = 32; + + // #pragma omp parallel for + #pragma omp parallel for collapse(2) num_threads(kai_thread_count) + for (int m_start = 0; m_start < M; m_start += m_step) { + for (int n_start = 0; n_start < N; n_start += n_step) { + const int current_m = std::min(M - m_start, m_step); + const int current_n = std::min(N - n_start, n_step); + const void* a_packed_offset = (const char*)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); + const void* b_packed_offset = (const char*)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); + float* c_offset = c_temp.data() + m_start * N + n_start; + qsi4_ukernel.run_matmul( + current_m, current_n, K, block_len, + a_packed_offset, b_packed_offset, + c_offset, N * sizeof(float), sizeof(float), + -FLT_MAX, FLT_MAX + ); + } + } + + // 3. 并行地将 FP32 临时结果转换为 FP16 并写入最终输出 + // #pragma omp parallel for + #pragma omp parallel for collapse(1) num_threads(kai_thread_count) + for(int i = 0; i < M * N; ++i) { + c_ptr[i] = static_cast(c_temp[i]); + } +} +// #endif + + +//#if defined(USE_FP16) +// ###################################################################### // +// ## Implementation 2: FP16 ## +// ###################################################################### // +#include "kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p_interface.h" +#include "kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla.h" +#include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon.h" + +static const kai_matmul_clamp_f16_f16_f16p_ukernel fp16_ukernel = { + .get_m_step = kai_get_m_step_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla, + .get_n_step = kai_get_n_step_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla, + .get_nr = kai_get_nr_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla, + .get_kr = kai_get_kr_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla, + .get_sr = kai_get_sr_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla, + .run_matmul = kai_run_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla, +}; + +size_t mllm_kleidai_get_packed_b_fp16_size(int N, int K) { + return kai_get_rhs_packed_size_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon(N, K); +} + +void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t* packed_b_ptr, const mllm_fp16_t* b_ptr, const float* bias_ptr, int N, int K) { + std::vector bias_fp16_buffer(N); + if (bias_ptr != nullptr) { + for(int i = 0; i < N; ++i) { + bias_fp16_buffer[i] = static_cast(bias_ptr[i]); + } + } else { + std::fill(bias_fp16_buffer.begin(), bias_fp16_buffer.end(), static_cast(0.0f)); + } + kai_run_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon( + 1, N, K, fp16_ukernel.get_nr(), fp16_ukernel.get_kr(), fp16_ukernel.get_sr(), + N * sizeof(mllm_fp16_t), b_ptr, bias_fp16_buffer.data(), nullptr, packed_b_ptr, 0, nullptr); +} + +void mllm_kleidai_gemm_fp16(float* c_ptr, const float* a_ptr, const mllm_fp16_t* packed_b_ptr, int M, int N, int K) { + std::vector a_fp16(M * K); + for(int i = 0; i < M * K; ++i) { + a_fp16[i] = static_cast(a_ptr[i]); + } + + std::vector c_fp16(M * N); + const int m_step = fp16_ukernel.get_m_step(); + const int n_step = fp16_ukernel.get_n_step(); + + // #pragma omp parallel for + #pragma omp parallel for collapse(2) num_threads(kai_thread_count) + for (int m_start = 0; m_start < M; m_start += m_step) { + for (int n_start = 0; n_start < N; n_start += n_step) { + const int current_m = std::min(M - m_start, m_step); + const int current_n = std::min(N - n_start, n_step); + const mllm_fp16_t* a_offset = a_fp16.data() + m_start * K; + const mllm_fp16_t* b_offset = packed_b_ptr + (n_start * (K + 1)); + mllm_fp16_t* c_offset = c_fp16.data() + m_start * N + n_start; + fp16_ukernel.run_matmul( + current_m, current_n, K, a_offset, K * sizeof(mllm_fp16_t), + b_offset, c_offset, N * sizeof(mllm_fp16_t), sizeof(mllm_fp16_t), + -FLT_MAX, FLT_MAX ); + } + } + for(int i = 0; i < M * N; ++i) { + c_ptr[i] = static_cast(c_fp16[i]); + } +} +// #endif + + +//#if defined(USE_FP32) +// ###################################################################### // +// ## Implementation 3: FP32 ## +// ###################################################################### // +#include "kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p_interface.h" +#include "kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla.h" +#include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon.h" + +static const kai_matmul_clamp_f32_f32_f32p_ukernel fp32_ukernel = { + .get_m_step = kai_get_m_step_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla, + .get_n_step = kai_get_n_step_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla, + .get_nr = kai_get_nr_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla, + .get_kr = kai_get_kr_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla, + .get_sr = kai_get_sr_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla, + .run_matmul = kai_run_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla, +}; + +size_t mllm_kleidai_get_packed_b_fp32_size(int N, int K) { + return kai_get_rhs_packed_size_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon(N, K); +} + +void mllm_kleidai_pack_b_and_bias_fp32(float* packed_b_ptr, const float* b_ptr, const float* bias_ptr, int N, int K) { + const float* bias_to_use = bias_ptr; + std::vector fake_bias; + if (bias_to_use == nullptr) { + fake_bias.assign(N, 0.0f); + bias_to_use = fake_bias.data(); + } + kai_run_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon( + 1, N, K, fp32_ukernel.get_nr(), fp32_ukernel.get_kr(), fp32_ukernel.get_sr(), + N * sizeof(float), b_ptr, bias_to_use, nullptr, packed_b_ptr, 0, nullptr); +} + +void mllm_kleidai_gemm_fp32(float* c_ptr, const float* a_ptr, const float* packed_b_ptr, int M, int N, int K) { + const int m_step = fp32_ukernel.get_m_step(); + const int n_step = fp32_ukernel.get_n_step(); + + // #pragma omp parallel for + #pragma omp parallel for collapse(2) num_threads(kai_thread_count) + for (int m_start = 0; m_start < M; m_start += m_step) { + for (int n_start = 0; n_start < N; n_start += n_step) { + const int current_m = std::min(M - m_start, m_step); + const int current_n = std::min(N - n_start, n_step); + const float* a_offset = a_ptr + m_start * K; + const float* b_offset = packed_b_ptr + (n_start * (K + 1)); + float* c_offset = c_ptr + m_start * N + n_start; + fp32_ukernel.run_matmul( + current_m, current_n, K, + a_offset, K * sizeof(float), b_offset, + c_offset, N * sizeof(float), sizeof(float), + -FLT_MAX, FLT_MAX ); + } + } +} +// #endif +#endif \ No newline at end of file diff --git a/src/backends/cpu/compute/GemmKleidiai.hpp b/src/backends/cpu/compute/GemmKleidiai.hpp new file mode 100644 index 000000000..6f9cd4241 --- /dev/null +++ b/src/backends/cpu/compute/GemmKleidiai.hpp @@ -0,0 +1,49 @@ +#pragma once +#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) + +#include // For size_t +#include // For uint8_t +#include "Types.hpp" +// #if defined(__ARM_FP16_FORMAT_IEEE) +// typedef __fp16 mllm_fp16_t; +// #else +// typedef uint16_t mllm_fp16_t; // Fallback for non-ARM compilation +// #endif + +static int kai_thread_count = 4; + + +// --- 接口声明 --- + +//#if defined(KLAI_USE_QSI4_C32) +// --- 实现 1: float * qsi4c32 -> float (底层API) --- + +size_t mllm_kleidai_get_packed_b_qsi4_size(int N, int K); +size_t mllm_kleidai_get_workspace_qsi4_size(int M, int K); +void mllm_kleidai_pack_b_and_bias_qsi4(uint8_t* packed_b_ptr, const float* b_ptr, const float* bias_ptr, int N, int K); +void mllm_kleidai_gemm_qsi4(float* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, int M, int N, int K); + +// #endif + +// --- 实现 1.5: float * qsi4c32 -> fp16 (底层API) --- +// 打包和工作区大小计算函数可以复用 USE_QSI4_C32 的 +void mllm_kleidai_gemm_qsi4_to_fp16(mllm_fp16_t* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, int M, int N, int K); + +//#if defined(KLAI_USE_FP16) +// --- 实现 2: float * fp16 -> float (底层API) --- + +size_t mllm_kleidai_get_packed_b_fp16_size(int N, int K); +void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t* packed_b_ptr, const mllm_fp16_t* b_ptr, const float* bias_ptr, int N, int K); +void mllm_kleidai_gemm_fp16(float* c_ptr, const float* a_ptr, const mllm_fp16_t* packed_b_ptr, int M, int N, int K); + +// #endif + +//#if defined(KLAI_USE_FP32) +// --- 实现 3: float * fp32 -> float (底层API) --- + +size_t mllm_kleidai_get_packed_b_fp32_size(int N, int K); +void mllm_kleidai_pack_b_and_bias_fp32(float* packed_b_ptr, const float* b_ptr, const float* bias_ptr, int N, int K); +void mllm_kleidai_gemm_fp32(float* c_ptr, const float* a_ptr, const float* packed_b_ptr, int M, int N, int K); + +// #endif +#endif \ No newline at end of file diff --git a/src/backends/cpu/compute/LlamafileSGEMM.cpp b/src/backends/cpu/compute/GemmLlamafile.cpp similarity index 99% rename from src/backends/cpu/compute/LlamafileSGEMM.cpp rename to src/backends/cpu/compute/GemmLlamafile.cpp index 174e8ab40..21b02fcb4 100644 --- a/src/backends/cpu/compute/LlamafileSGEMM.cpp +++ b/src/backends/cpu/compute/GemmLlamafile.cpp @@ -48,8 +48,8 @@ #pragma GCC diagnostic ignored "-Wignored-attributes" #endif -#include "LlamafileSGEMM.hpp" -#include "../quantize/Quantize.hpp" +#include "GemmLlamafile.hpp" +#include "Quantize.hpp" #ifdef _MSC_VER #define NOINLINE __declspec(noinline) diff --git a/src/backends/cpu/compute/LlamafileSGEMM.hpp b/src/backends/cpu/compute/GemmLlamafile.hpp similarity index 100% rename from src/backends/cpu/compute/LlamafileSGEMM.hpp rename to src/backends/cpu/compute/GemmLlamafile.hpp diff --git a/src/backends/cpu/compute/SMEGEMM.hpp b/src/backends/cpu/compute/GemmSme.hpp similarity index 100% rename from src/backends/cpu/compute/SMEGEMM.hpp rename to src/backends/cpu/compute/GemmSme.hpp diff --git a/src/backends/cpu/compute/Matmul.cpp b/src/backends/cpu/compute/Matmul.cpp index bcf01c42c..c632f3d7e 100644 --- a/src/backends/cpu/compute/Matmul.cpp +++ b/src/backends/cpu/compute/Matmul.cpp @@ -5,11 +5,11 @@ #include "Matmul.hpp" #include "Types.hpp" #include "VecDotType.hpp" -#include "LlamafileSGEMM.hpp" +#include "GemmLlamafile.hpp" #include #include #include "Arithmetic.hpp" -#include "SMEGEMM.hpp" +#include "GemmSme.hpp" #ifdef __ARM_NEON #include @@ -29,6 +29,7 @@ ErrorCode mat_mul(Tensor *src0, Tensor *src1, Tensor *dst, bool support_bias, Te auto dst_dtype = dst->dtype(); // ----------- BEGIN SME Path Check ----------- +/* #if defined(__ARM_FEATURE_SME) if (src0->batch() == 1 && src0->head() == 1 && src1->batch() == 1 && src1->head() == 1 && dst->batch() == 1 && dst->head() == 1 && // Ensure dst also expects B=1, H=1 src1->ctype() == BSHD && dst->ctype() == BSHD && dst_dtype == MLLM_TYPE_F32) { @@ -91,6 +92,7 @@ ErrorCode mat_mul(Tensor *src0, Tensor *src1, Tensor *dst, bool support_bias, Te } } #endif // __ARM_FEATURE_SME +*/ // ----------- END SME Path Check ----------- auto vec_dot_type = type_traits[src1_dtype].vec_dot_type; diff --git a/src/backends/cpu/compute/MatmulElastic.cpp b/src/backends/cpu/compute/MatmulElastic.cpp index 1bd6cd078..88bcfdfc3 100644 --- a/src/backends/cpu/compute/MatmulElastic.cpp +++ b/src/backends/cpu/compute/MatmulElastic.cpp @@ -6,7 +6,7 @@ #include "Types.hpp" #include "VecDotType.hpp" // #include -#include "LlamafileSGEMM.hpp" +#include "GemmLlamafile.hpp" #include #include diff --git a/src/backends/cpu/compute/MatmulSparse.cpp b/src/backends/cpu/compute/MatmulSparse.cpp index 7f1d56089..5d587f992 100644 --- a/src/backends/cpu/compute/MatmulSparse.cpp +++ b/src/backends/cpu/compute/MatmulSparse.cpp @@ -6,7 +6,7 @@ #include "Types.hpp" #include "VecDotType.hpp" // #include -#include "LlamafileSGEMM.hpp" +#include "GemmLlamafile.hpp" #include #ifdef __ARM_NEON diff --git a/src/backends/cpu/quantize/Quantize.hpp b/src/backends/cpu/compute/Quantize.hpp similarity index 100% rename from src/backends/cpu/quantize/Quantize.hpp rename to src/backends/cpu/compute/Quantize.hpp diff --git a/src/backends/cpu/quantize/QuantizeQ2.cpp b/src/backends/cpu/compute/QuantizeQ2.cpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ2.cpp rename to src/backends/cpu/compute/QuantizeQ2.cpp diff --git a/src/backends/cpu/quantize/QuantizeQ2.hpp b/src/backends/cpu/compute/QuantizeQ2.hpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ2.hpp rename to src/backends/cpu/compute/QuantizeQ2.hpp diff --git a/src/backends/cpu/quantize/QuantizeQ3.cpp b/src/backends/cpu/compute/QuantizeQ3.cpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ3.cpp rename to src/backends/cpu/compute/QuantizeQ3.cpp diff --git a/src/backends/cpu/quantize/QuantizeQ3.hpp b/src/backends/cpu/compute/QuantizeQ3.hpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ3.hpp rename to src/backends/cpu/compute/QuantizeQ3.hpp diff --git a/src/backends/cpu/quantize/QuantizeQ4.cpp b/src/backends/cpu/compute/QuantizeQ4.cpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ4.cpp rename to src/backends/cpu/compute/QuantizeQ4.cpp diff --git a/src/backends/cpu/quantize/QuantizeQ4.hpp b/src/backends/cpu/compute/QuantizeQ4.hpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ4.hpp rename to src/backends/cpu/compute/QuantizeQ4.hpp diff --git a/src/backends/cpu/quantize/QuantizeQ6.cpp b/src/backends/cpu/compute/QuantizeQ6.cpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ6.cpp rename to src/backends/cpu/compute/QuantizeQ6.cpp diff --git a/src/backends/cpu/quantize/QuantizeQ6.hpp b/src/backends/cpu/compute/QuantizeQ6.hpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ6.hpp rename to src/backends/cpu/compute/QuantizeQ6.hpp diff --git a/src/backends/cpu/quantize/QuantizeQ8.cpp b/src/backends/cpu/compute/QuantizeQ8.cpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ8.cpp rename to src/backends/cpu/compute/QuantizeQ8.cpp diff --git a/src/backends/cpu/quantize/QuantizeQ8.hpp b/src/backends/cpu/compute/QuantizeQ8.hpp similarity index 100% rename from src/backends/cpu/quantize/QuantizeQ8.hpp rename to src/backends/cpu/compute/QuantizeQ8.hpp diff --git a/src/backends/cpu/compute/SIMDMemory.hpp b/src/backends/cpu/compute/SIMDMemory.hpp index 4846521ea..0e632a7b1 100644 --- a/src/backends/cpu/compute/SIMDMemory.hpp +++ b/src/backends/cpu/compute/SIMDMemory.hpp @@ -1,5 +1,6 @@ // 平台检测头文件 +#include #if defined(__AVX__) #include #elif defined(__ARM_NEON) diff --git a/src/backends/cpu/compute/VecDot.hpp b/src/backends/cpu/compute/VecDot.hpp index f96e7a2d8..826ccf37e 100644 --- a/src/backends/cpu/compute/VecDot.hpp +++ b/src/backends/cpu/compute/VecDot.hpp @@ -31,11 +31,11 @@ #include "Types.hpp" #include #include "ParamLoader.hpp" -#include "../quantize/QuantizeQ8.hpp" -#include "../quantize/QuantizeQ4.hpp" -#include "../quantize/QuantizeQ6.hpp" -#include "../quantize/QuantizeQ3.hpp" -#include "../quantize/QuantizeQ2.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ4.hpp" +#include "backends/cpu/compute/QuantizeQ6.hpp" +#include "backends/cpu/compute/QuantizeQ3.hpp" +#include "backends/cpu/compute/QuantizeQ2.hpp" #if defined(__ARM_ARCH) && defined(__ARM_FEATURE_SVE) #include diff --git a/src/backends/cpu/compute/VecDotType.cpp b/src/backends/cpu/compute/VecDotType.cpp index c7472fc81..5925e6e07 100644 --- a/src/backends/cpu/compute/VecDotType.cpp +++ b/src/backends/cpu/compute/VecDotType.cpp @@ -30,9 +30,9 @@ #include #include "VecDotType.hpp" #include "Types.hpp" -#include "quantize/Quantize.hpp" -#include "compute/VecDot.hpp" -#include "compute/GEMM_AArch64.hpp" +#include "Quantize.hpp" +#include "VecDot.hpp" +#include "GemmAarch64.hpp" void fp32_add_row_to(int n, const float *MLLM_RESTRICT src, float *MLLM_RESTRICT dst, float alpha) { int i = 0; diff --git a/src/backends/cpu/op/CPUEmbedding.cpp b/src/backends/cpu/op/CPUEmbedding.cpp index 6af2fe36a..72a836e83 100644 --- a/src/backends/cpu/op/CPUEmbedding.cpp +++ b/src/backends/cpu/op/CPUEmbedding.cpp @@ -1,7 +1,7 @@ #include "CPUEmbedding.hpp" #include "ParamLoader.hpp" -#include "quantize/QuantizeQ4.hpp" -#include "quantize/QuantizeQ8.hpp" +#include "compute/QuantizeQ4.hpp" +#include "compute/QuantizeQ8.hpp" namespace mllm { CPUEmbedding::CPUEmbedding(Backend *bn, string opName, int hiddenSize, int vocabSize, int threadCount) : diff --git a/src/backends/cpu/op/CPUIRoPE.cpp b/src/backends/cpu/op/CPUIRoPE.cpp index 95c9cd363..c29f0f74e 100644 --- a/src/backends/cpu/op/CPUIRoPE.cpp +++ b/src/backends/cpu/op/CPUIRoPE.cpp @@ -5,7 +5,7 @@ #include #include #include -#include "backends/cpu/quantize/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPULinear.cpp b/src/backends/cpu/op/CPULinear.cpp index 916484f51..d0c662999 100644 --- a/src/backends/cpu/op/CPULinear.cpp +++ b/src/backends/cpu/op/CPULinear.cpp @@ -3,6 +3,7 @@ #include "Types.hpp" #include #include +#include "../compute/GemmKleidiai.hpp" namespace mllm { @@ -44,11 +45,26 @@ ErrorCode CPULinear::reshape(vector> inputs, vector> inputs, vectorsequence() != outputs[0]->sequence() && outputs[0]->masterTensor() == nullptr) { outputs[0]->reshape(outputs[0]->batch(), outputs[0]->head(), inputs[0]->sequence(), outputs[0]->dimension()); - // outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), out_features_); outputs[0]->alloc(); } // TODO: Q8_0 KVCache can not use!! @@ -96,6 +111,29 @@ ErrorCode CPULinear::execute(vector> inputs, vectorreshape(b, h, s, d); tmp_out->setDtype(MLLM_TYPE_F32); tmp_out->alloc(); + if(weight_.dtype() == MLLM_TYPE_KLEIDIAI_Q4_0){ +#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) + kai_thread_count = thread_count; + // KLEIDIAI_Q4_0 is a packed type, we need to use a special function to handle it + auto M = inputs[0]->sequence(); + auto N = outputs[0]->dimension(); + auto K = inputs[0]->dimension(); + if (outputs[0]->dtype() == MLLM_TYPE_F16) { + mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(0, 0, 0, 0), + inputs[0]->ptrAt(0, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + }else{ + mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(0, 0, 0, 0), + inputs[0]->ptrAt(0, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } + return MLLM_NO_ERROR; +#else + std::cerr << "KLEIDIAI_Q4_0 is not supported on this platform!" << std::endl; + exit(-1); + return NOT_SUPPORT; +#endif + } mat_mul(inputs[0].get(), &weight_, tmp_out.get(), support_bias_, &bias_, false, true, thread_count); if (tmp_out->ctype() == BSHD) { #pragma omp parallel for collapse(3) num_threads(thread_count) @@ -123,34 +161,31 @@ ErrorCode CPULinear::execute(vector> inputs, vectorsequence(); + auto N = outputs[0]->dimension();//out_features_ + auto K = inputs[0]->dimension();//in_features_ + if (outputs[0]->dtype() == MLLM_TYPE_F16) { + mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(0, 0, 0, 0), + inputs[0]->ptrAt(0, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + }else{ + mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(0, 0, 0, 0), + inputs[0]->ptrAt(0, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } + return MLLM_NO_ERROR; +#else + std::cerr << "KLEIDIAI_Q4_0 is not supported on this platform!" << std::endl; + exit(-1); + return NOT_SUPPORT; +#endif + } + mat_mul(inputs[0].get(), &weight_, outputs[0].get(), support_bias_, &bias_, false, true, thread_count); } - // std::cout << name() << " CPULinear()" << std::endl; - /* - switch (weight_.dtype()) { - case MLLM_TYPE_F32: { - mat_mul_fp32(inputs[0].get(), &weight_, outputs[0].get(), support_bias_, &bias_, false, true, thread_count); - break; - } - case MLLM_TYPE_F16: break; - case MLLM_TYPE_Q4_0: { - mat_mul_fp32_q4_0(inputs[0].get(), &weight_, outputs[0].get(), support_bias_, &bias_, thread_count); - break; - } - case MLLM_TYPE_Q4_K: { - mat_mul_fp32_q4_K(inputs[0].get(), &weight_, outputs[0].get(), support_bias_, &bias_, thread_count); - break; - } - case MLLM_TYPE_Q6_K: { - mat_mul_fp32_q6_K(inputs[0].get(), &weight_, outputs[0].get(), support_bias_, &bias_, thread_count); - break; - } - default: - break; - } - */ - // auto end = mllm::mllm_time_us(); - // printf("exec time: %ld us\n", end - start); return Op::execute(inputs, outputs); } ErrorCode CPULinear::free(vector> inputs, vector> outputs) { diff --git a/src/backends/cpu/op/CPULinearINT8Shadow.cpp b/src/backends/cpu/op/CPULinearINT8Shadow.cpp index 461612002..1889db6fa 100755 --- a/src/backends/cpu/op/CPULinearINT8Shadow.cpp +++ b/src/backends/cpu/op/CPULinearINT8Shadow.cpp @@ -2,7 +2,7 @@ #include "CPULinearINT8Shadow.hpp" #include "Types.hpp" #include "../compute/VecDot.hpp" -#include "quantize/QuantizeQ8.hpp" +#include "compute/QuantizeQ8.hpp" #include namespace mllm { diff --git a/src/backends/cpu/op/CPUMultimodalRoPE.cpp b/src/backends/cpu/op/CPUMultimodalRoPE.cpp index c00f4ceb7..2cbaeceed 100644 --- a/src/backends/cpu/op/CPUMultimodalRoPE.cpp +++ b/src/backends/cpu/op/CPUMultimodalRoPE.cpp @@ -7,7 +7,7 @@ #include #include // #include -#include "backends/cpu/quantize/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp b/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp index c23b55f27..26ef4b3cb 100644 --- a/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp +++ b/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp @@ -6,7 +6,7 @@ #include #include // #include -#include "backends/cpu/quantize/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPUNTKRoPE.cpp b/src/backends/cpu/op/CPUNTKRoPE.cpp index 605761778..e7a99af2e 100644 --- a/src/backends/cpu/op/CPUNTKRoPE.cpp +++ b/src/backends/cpu/op/CPUNTKRoPE.cpp @@ -12,7 +12,7 @@ #include "Types.hpp" #include #include -#include "backends/cpu/quantize/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPUQuantize.cpp b/src/backends/cpu/op/CPUQuantize.cpp index 11207ea9d..845b18f67 100644 --- a/src/backends/cpu/op/CPUQuantize.cpp +++ b/src/backends/cpu/op/CPUQuantize.cpp @@ -4,7 +4,7 @@ #include "CPUQuantize.hpp" #include "Types.hpp" -#include "backends/cpu/quantize/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" #include #include diff --git a/src/backends/cpu/op/CPURoPE.cpp b/src/backends/cpu/op/CPURoPE.cpp index fe334b3c3..c9d63d79c 100644 --- a/src/backends/cpu/op/CPURoPE.cpp +++ b/src/backends/cpu/op/CPURoPE.cpp @@ -5,7 +5,7 @@ #include #include #include -#include "backends/cpu/quantize/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPURoPETree.cpp b/src/backends/cpu/op/CPURoPETree.cpp index 065fd72bc..f350f4ca9 100644 --- a/src/backends/cpu/op/CPURoPETree.cpp +++ b/src/backends/cpu/op/CPURoPETree.cpp @@ -6,7 +6,7 @@ #include #include #include -#include "backends/cpu/quantize/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPUSoftMax.cpp b/src/backends/cpu/op/CPUSoftMax.cpp index 9566da226..7846df0fe 100644 --- a/src/backends/cpu/op/CPUSoftMax.cpp +++ b/src/backends/cpu/op/CPUSoftMax.cpp @@ -2,7 +2,7 @@ #include "CPUSoftMax.hpp" #include #include "Tensor.hpp" -#include "quantize/Quantize.hpp" +#include "compute/Quantize.hpp" #include "../compute/ActivationFunction.hpp" namespace mllm { diff --git a/src/backends/cpu/third_party/kleidiai b/src/backends/cpu/third_party/kleidiai new file mode 160000 index 000000000..cdcff672c --- /dev/null +++ b/src/backends/cpu/third_party/kleidiai @@ -0,0 +1 @@ +Subproject commit cdcff672cc1384467c8a5fadefb0dd9b3592c95f diff --git a/src/backends/xnnpack/Ops/XpEmbedding.cpp b/src/backends/xnnpack/Ops/XpEmbedding.cpp index ac34f2e57..51c93bffb 100644 --- a/src/backends/xnnpack/Ops/XpEmbedding.cpp +++ b/src/backends/xnnpack/Ops/XpEmbedding.cpp @@ -1,6 +1,6 @@ #include "backends/xnnpack/Ops/XpEmbedding.hpp" -#include "backends/cpu/quantize/QuantizeQ4.hpp" -#include "backends/cpu/quantize/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ4.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" namespace mllm::xnnpack { diff --git a/src/models/qwen2_vl/vtp/ndc_tools.hpp b/src/models/qwen2_vl/vtp/ndc_tools.hpp index 6ada028b3..1eef503f6 100644 --- a/src/models/qwen2_vl/vtp/ndc_tools.hpp +++ b/src/models/qwen2_vl/vtp/ndc_tools.hpp @@ -93,6 +93,9 @@ class DelayComputeKVCache { const int k_size = num_heads * k_per_head; const int v_size = v_per_head; // 1. 分配临时内存 + if(cache_sequence <= pos_first){ + pos_first =0; + } vector> k_cache_data(cache_sequence - pos_first); vector>> v_cache_data(num_heads); for (int i = pos_first; i < cache_sequence; i++) { diff --git a/src/quantizer/ParamWriter.cpp b/src/quantizer/ParamWriter.cpp index f1cf39dec..246281ee2 100644 --- a/src/quantizer/ParamWriter.cpp +++ b/src/quantizer/ParamWriter.cpp @@ -29,7 +29,7 @@ void ParamWriter::writeIndex() { write_u64(fp_, param.size); write_u64(fp_, param.offset); writeInt(fp_, param.type); - std::cout<<"write param "< #include "QuantWriter.hpp" -#include "backends/cpu/compute/GEMM_AArch64.hpp" namespace mllm { QuantWriter::QuantWriter(std::string output_path, std::string input_path) : ParamWriter(output_path), output_path_(output_path) { @@ -119,7 +118,7 @@ void QuantWriter::quantParams(DataType dataType) { writeParam(name, MLLM_TYPE_F32, param, tsize); std::cout << " size:" << tsize << std::endl; - } else if (find_names(name, q6_layers)) { + } else if (find_names(name, q6_layers)&& (dataType != MLLM_TYPE_KLEIDIAI_Q4_0)) { switch (dataType) { case MLLM_TYPE_F32: std::cout << "No need to quantize FP32 params\n"; @@ -200,6 +199,54 @@ void QuantWriter::quantParams(DataType dataType) { std::cout << "No need to quantize FP32 params\n"; __exit(-1); break; + case MLLM_TYPE_KLEIDIAI_Q4_0:{ +#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) + // todo:对qwen/qwen2vl特化了,后续一定要重写 + int K = tmp_hidden_dim; + int N = size / K; + if (name.find("down_proj") != std::string::npos) { + N = tmp_hidden_dim; + K = size / N; + } + std::vector transposed_weight_data(K * N); + const float *original_weight_ptr = param; + #pragma omp parallel for collapse(2) num_threads(4) + for (int n = 0; n < N; ++n) { + for (int k = 0; k < K; ++k) { + // 核心转置逻辑:dst[k][n] = src[n][k] + transposed_weight_data[k * N + n] = original_weight_ptr[n * K + k]; + } + } + block_t = alloc_kleidiai_quant_block(MLLM_TYPE_KLEIDIAI_Q4_0, N, K); + quant_ptr = block_t.first; + // mllm_kleidai_pack_b_and_bias_qsi4 + if (name.find("weight") != std::string::npos) { + std::string bias_name = name; + bias_name.replace(bias_name.find("weight"), 6, "bias"); + auto *bias_param = getParam(bias_name); + float first_bias = bias_param[0]; + // std::cout << "【Kleidiai】======Quantize param " << name << " bias: " << first_bias << std::endl; + // if (bias_param != nullptr && name.find("o_proj") == std::string::npos&& name.find("mlp") == std::string::npos) { + if (first_bias != 0.0f) { + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), + bias_param, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; + }else{ + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), + nullptr, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; + } + } else { + throw std::runtime_error("name does not contain 'weight': " + name); + } + size = block_t.second; + break; +#else + std::cerr << "KLEIDIAI_Q4_0 is not supported on this platform!" << std::endl; + exit(-1); + return NOT_SUPPORT; +#endif + } case MLLM_TYPE_Q4_0: block_t = alloc_quant_block(size, dataType); quant_ptr = block_t.first; @@ -429,6 +476,162 @@ void QuantWriter::quantParams_q4_vl(DataType dataType) { writeIndex(); } + +vector vl_q4x4_2_q4_k_layers = { + // "wv", + // "v_proj", + ".attn.qkv", + "in_proj", + "w12", + "model.output", + "merger.mlp", + // "mlp.0", + // "mlp.2", +}; + +void QuantWriter::quantParams_kai_vl(DataType dataType) { + for (const auto &name : param_names_) { + auto size = param_loader_->offsets_[name].second / sizeof(float); + if (find_names(name, {"input_layernorm"}) && find_names(name, {"model"})) { + tmp_hidden_dim = size; + } + if (find_names(name, {"norm"}) && find_names(name, {"visual"})) { + vit_tmp_hidden_dim = size; + } + } + std::cout << "tmp_hidden_dim:" << tmp_hidden_dim << std::endl; + std::cout << "vit_tmp_hidden_dim:" << vit_tmp_hidden_dim << std::endl; + quant_type_ = dataType; + for (const auto &name : param_names_) { + auto *param = getParam(name); + if (param == nullptr) { + __exit(-1); + } + auto size = param_loader_->offsets_[name].second / sizeof(float); + // if (find_names(name, {"input_layernorm"})) { + // tmp_hidden_dim = size; + // } + void *quant_ptr = nullptr; + std::pair block_t; + if (find_names(name, fp32_layers)) { + std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_F32) << "\t"; + const auto s = param_loader_->offsets_[name].second / sizeof(float); + const auto tsize = alloc_quant_block(s, MLLM_TYPE_F32).second; + writeParam(name, MLLM_TYPE_F32, param, tsize); + std::cout << " size:" << tsize << std::endl; + } else if (find_names(name, vl_q4x4_2_q4_k_layers)) { + std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_Q4_0) << "\t"; + block_t = alloc_quant_block(size, MLLM_TYPE_Q4_0); + quant_ptr = block_t.first; + quantize_row_q4_0(param, quant_ptr, size); + size = block_t.second; + if (quant_ptr != nullptr) { + writeParam(name, MLLM_TYPE_Q4_0, quant_ptr, size); + std::cout << " size:" << size << " type:" << DataTypeName(MLLM_TYPE_Q4_0) << std::endl; + } + } else { + std::cout << "Quantize param " << name << " to " << DataTypeName(dataType) << "\t"; + block_t = alloc_quant_block(size, dataType); + quant_ptr = block_t.first; + if (find_names(name, {"visual"})) { + // int tmp_hidden_dim_q4 = vit_tmp_hidden_dim; + // if (find_names(name, {"fc2", "down_proj"})) { + // tmp_hidden_dim_q4 = (size / vit_tmp_hidden_dim); + // } + // quantize_row_q4_0_4x4(param, quant_ptr, size, tmp_hidden_dim_q4); + + + int K = vit_tmp_hidden_dim; + int N = size / K; + if (find_names(name, {"fc2", "down_proj"})) { + N = vit_tmp_hidden_dim; + K = size / N; + } + std::vector transposed_weight_data(K * N); + const float *original_weight_ptr = param; + #pragma omp parallel for collapse(2) num_threads(4) + for (int n = 0; n < N; ++n) { + for (int k = 0; k < K; ++k) { + transposed_weight_data[k * N + n] = original_weight_ptr[n * K + k]; + } + } + block_t = alloc_kleidiai_quant_block(MLLM_TYPE_KLEIDIAI_Q4_0, N, K); + quant_ptr = block_t.first; + // mllm_kleidai_pack_b_and_bias_qsi4 + if (name.find("weight") != std::string::npos) { + std::string bias_name = name; + bias_name.replace(bias_name.find("weight"), 6, "bias"); + auto *bias_param = getParam(bias_name); + float first_bias = bias_param[0]; + if (first_bias != 0.0f) { + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), + bias_param, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; + }else{ + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), + nullptr, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; + } + } else { + throw std::runtime_error("name does not contain 'weight': " + name); + } + } else { + // int tmp_hidden_dim_q4 = tmp_hidden_dim; + // if (find_names(name, {"w2", "down_proj"})) { + // tmp_hidden_dim_q4 = (size / tmp_hidden_dim); + // } + // quantize_row_q4_0_4x4(param, quant_ptr, size, tmp_hidden_dim_q4); + + int K = tmp_hidden_dim; + int N = size / K; + if (find_names(name, {"w2", "down_proj"})) { + N = tmp_hidden_dim; + K = size / N; + } + std::vector transposed_weight_data(K * N); + const float *original_weight_ptr = param; + #pragma omp parallel for collapse(2) num_threads(4) + for (int n = 0; n < N; ++n) { + for (int k = 0; k < K; ++k) { + transposed_weight_data[k * N + n] = original_weight_ptr[n * K + k]; + } + } + block_t = alloc_kleidiai_quant_block(MLLM_TYPE_KLEIDIAI_Q4_0, N, K); + quant_ptr = block_t.first; + // mllm_kleidai_pack_b_and_bias_qsi4 + if (name.find("weight") != std::string::npos) { + std::string bias_name = name; + bias_name.replace(bias_name.find("weight"), 6, "bias"); + auto *bias_param = getParam(bias_name); + float first_bias = bias_param[0]; + if (first_bias != 0.0f) { + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), + bias_param, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; + }else{ + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), + nullptr, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; + } + } else { + throw std::runtime_error("name does not contain 'weight': " + name); + } + + } + size = block_t.second; + if (quant_ptr != nullptr) { + writeParam(name, quant_type_, quant_ptr, size); + std::cout << " size:" << size << std::endl; + } +#ifndef TEST + delete[] (char *)quant_ptr; +#endif + } + } + writeIndex(); +} + + void QuantWriter::writeParam(string name, DataType type, void *data, uint64_t size) { #ifdef TEST data_[name] = (char *)data; diff --git a/src/quantizer/QuantWriter.hpp b/src/quantizer/QuantWriter.hpp index 0939420d2..e14a33233 100644 --- a/src/quantizer/QuantWriter.hpp +++ b/src/quantizer/QuantWriter.hpp @@ -1,10 +1,13 @@ #include "ParamWriter.hpp" #include "ParamLoader.hpp" -#include "backends/cpu/quantize/QuantizeQ6.hpp" -#include "backends/cpu/quantize/QuantizeQ2.hpp" -#include "backends/cpu/quantize/QuantizeQ3.hpp" -#include "backends/cpu/quantize/QuantizeQ4.hpp" -#include "backends/cpu/quantize/QuantizeQ8.hpp" +#include "backends/cpu/compute/QuantizeQ6.hpp" +#include "backends/cpu/compute/QuantizeQ2.hpp" +#include "backends/cpu/compute/QuantizeQ3.hpp" +#include "backends/cpu/compute/QuantizeQ4.hpp" +#include "backends/cpu/compute/QuantizeQ8.hpp" +#include "backends/cpu/compute/GemmAarch64.hpp" +#include "backends/cpu/compute/GemmKleidiai.hpp" +#include #include #include #ifndef MLLM_QUANTWRITER_HPP @@ -31,6 +34,16 @@ static std::pair alloc_quant_block(uint64_t count, DataType ty void *data = new char[size]; return std::make_pair(data, size); } + +static std::pair alloc_kleidiai_quant_block(DataType type, int N, int K) { + assert(type == MLLM_TYPE_KLEIDIAI_Q4_0); + uint64_t size = mllm_kleidai_get_packed_b_qsi4_size(N, K); + if (size <= 0) { + return std::make_pair(nullptr, 0); + } + void *data = new uint8_t[size]; + return std::make_pair(data, size); +} namespace mllm { class QuantWriter : public ParamWriter { public: @@ -40,6 +53,8 @@ class QuantWriter : public ParamWriter { void quantParams(DataType dataType); void quantParams_q4_(DataType dataType); void quantParams_q4_vl(DataType dataType); + void quantParams_kai_vl(DataType dataType); + #ifdef TEST std::unordered_map data_; diff --git a/src/quantizer/main.cpp b/src/quantizer/main.cpp index c91c5664c..c42582dd7 100644 --- a/src/quantizer/main.cpp +++ b/src/quantizer/main.cpp @@ -14,9 +14,11 @@ int main(int argc, char **argv) { auto input_path = std::string(argv[1]); auto output_path = std::string(argv[2]); auto quant_type = std::string(argv[3]); - // std::string input_path = "../models/showui-2b-fp32.mllm"; - // std::string output_path = "../models/showui-2b-q4_0_4_4.mllm"; - // std::string quant_type = "Q4_0_4_4"; + // std::string input_path = "../models/qwen-2.5-1.5b-instruct-fp32.mllm"; + // std::string output_path = "../models/qwen-2.5-1.5b-instruct-kai_q4_0.mllm"; + // std::string input_path = "../models/qwen-2-vl-2b-instruct-fp32.mllm"; + // std::string output_path = "../models/qwen-2-vl-2b-instruct-kai_q4_0.mllm"; + // std::string quant_type = "KAI_Q4_0"; mllm::QuantWriter quant_writer(output_path, input_path); int param_count = quant_writer.readParams(); if (param_count <= 0) { @@ -38,6 +40,9 @@ int main(int argc, char **argv) { quant_writer.quantParams(MLLM_TYPE_Q6_K); } else if (quant_type == "Q8_K") { quant_writer.quantParams(MLLM_TYPE_Q8_K); + } else if (quant_type == "KAI_Q4_0") { + // quant_writer.quantParams(MLLM_TYPE_KLEIDIAI_Q4_0); + quant_writer.quantParams_kai_vl(MLLM_TYPE_KLEIDIAI_Q4_0); } else if (quant_type == "Q4_0_4_4") { quant_writer.quantParams_q4_(MLLM_TYPE_Q4_0_4_4); } else { From ec1db947ece5ae74801c298f586839d7ca01f8fd Mon Sep 17 00:00:00 2001 From: yirongjie Date: Sat, 14 Jun 2025 09:10:39 +0000 Subject: [PATCH 08/22] fear: add qwen2-vl-7b --- CMakeLists.txt | 8 +- README.md | 4 +- examples/demo_qwen.cpp | 4 +- examples/demo_qwen2_vl.cpp | 15 +- examples/demo_qwen2_vl_vtp.cpp | 13 +- examples/demo_showui_vtp.cpp | 2 + scripts/build_android.sh | 2 +- scripts/run_qwen2_vl.sh | 4 +- src/Module.cpp | 2 +- src/backends/cpu/CMakeLists.txt | 16 +- src/backends/cpu/compute/GemmKleidiai.cpp | 186 +++++++++++------- src/backends/cpu/op/CPUMultimodalRoPE.cpp | 20 +- src/models/qwen/configuration_qwen.hpp | 15 ++ .../qwen2_vl/configuration_qwen2_vl.hpp | 45 +++-- src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp | 31 ++- src/models/qwen2_vl/vtp/ndc_tools.hpp | 30 ++- src/models/qwen2_vl/vtp/ui_tools.hpp | 2 + src/quantizer/QuantWriter.cpp | 71 ++++--- src/quantizer/QuantWriter.hpp | 5 +- src/quantizer/main.cpp | 12 +- 20 files changed, 309 insertions(+), 178 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab975ecd1..4e4e9a6af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,10 +203,10 @@ if(QUANT) ) if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") - # 配置 Kleidiai 库路径 - set(KLEIDIAI_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src/backends/cpu/third_party/Kleidiai) + # 配置 kleidiai 库路径 + set(KLEIDIAI_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src/backends/cpu/third_party/kleidiai) if(NOT EXISTS ${KLEIDIAI_SOURCE_DIR}) - message(FATAL_ERROR "Kleidiai library not found! Please place it in 'third_party/Kleidiai'.") + message(FATAL_ERROR "kleidiai library not found! Please place it in 'third_party/kleidiai'.") endif() # 添加所有源文件路径到 MLLM_QUANT list(APPEND MLLM_QUANT @@ -226,7 +226,7 @@ if(QUANT) ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon.c ) include_directories( - # # 添加所有Kleidiai源文件路径到 MLLM_QUAN + # # 添加所有kleidiai源文件路径到 MLLM_QUAN ${KLEIDIAI_SOURCE_DIR} ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack diff --git a/README.md b/README.md index 59b5645e2..bead3c3ee 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,9 @@ mllm is a lightweight, fast, and easy-to-use (multimodal) on-device LLM inferenc ```bash git clone https://github.com/UbiquitousLearning/mllm cd mllm -git submodule update --init --recursive +git submodule update --init --recursive \ + third_party/googletest \ + src/backends/cpu/third_party/kleidiai ``` ### Check prerequisites diff --git a/examples/demo_qwen.cpp b/examples/demo_qwen.cpp index b041f2902..5f7f171a1 100644 --- a/examples/demo_qwen.cpp +++ b/examples/demo_qwen.cpp @@ -20,8 +20,8 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2.5_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2.5_merges.txt"); - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-kai_q4_0.mllm"); - // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"); + // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-kai_q4_0.mllm"); cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B | 3B |]", false, "1.5B"); cmdParser.add("limits", 'l', "max KV cache size", false, 400); cmdParser.add("thread", 't', "num of threads", false, 4); diff --git a/examples/demo_qwen2_vl.cpp b/examples/demo_qwen2_vl.cpp index 8fa7bcc16..f4558f5bb 100644 --- a/examples/demo_qwen2_vl.cpp +++ b/examples/demo_qwen2_vl.cpp @@ -11,8 +11,9 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2vl_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2vl_merges.txt"); - // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-kai_q4_0.mllm"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); + // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-kai_q4_0.mllm"); + cmdParser.add("billion", 'b', "[2B | 7B |]", false, "2B"); cmdParser.add("limits", 'l', "max KV cache size", false, 800); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); @@ -20,18 +21,22 @@ int main(int argc, char **argv) { string vocab_path = cmdParser.get("vocab"); string merge_path = cmdParser.get("merge"); string model_path = cmdParser.get("model"); + string model_billion = cmdParser.get("billion") == "2B" ? "1.5b" : cmdParser.get("billion"); int tokens_limit = cmdParser.get("limits"); int thread_num = cmdParser.get("thread"); CPUBackend::cpu_threads = cmdParser.get("thread"); ParamLoader param_loader(model_path); auto processor = Qwen2VLProcessor(vocab_path, merge_path); - Qwen2VLConfig config(tokens_limit, "1.5b"); + Qwen2VLConfig config(tokens_limit, model_billion); auto model = Qwen2VLModel(config); model.load(model_path); vector in_imgs = { - "../assets/bus.png"}; + // "../assets/bus.png", + "../assets/two_cats.jpg", + // "../assets/bird_image.jpg", + }; vector in_strs = { "<|vision_start|><|image_pad|><|vision_end|>Describe this image.", }; @@ -54,6 +59,8 @@ int main(int argc, char **argv) { chatPostProcessing(out_token, input_tensor[0], {&input_tensor[1], &input_tensor[2]}); } printf("\n"); + model.clear_kvcache(); + model.profiling(); } return 0; diff --git a/examples/demo_qwen2_vl_vtp.cpp b/examples/demo_qwen2_vl_vtp.cpp index f24132308..10875f6ce 100644 --- a/examples/demo_qwen2_vl_vtp.cpp +++ b/examples/demo_qwen2_vl_vtp.cpp @@ -11,25 +11,32 @@ int main(int argc, char **argv) { cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2vl_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2vl_merges.txt"); cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); + cmdParser.add("billion", 'b', "[2B | 7B |]", false, "2B"); cmdParser.add("limits", 'l', "max KV cache size", false, 800); cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.add("premerge", 'p', "enable pre-ViT image token merging"); cmdParser.parse_check(argc, argv); string vocab_path = cmdParser.get("vocab"); string merge_path = cmdParser.get("merge"); string model_path = cmdParser.get("model"); + string model_billion = cmdParser.get("billion") == "2B" ? "1.5b" : cmdParser.get("billion"); int tokens_limit = cmdParser.get("limits"); int thread_num = cmdParser.get("thread"); CPUBackend::cpu_threads = cmdParser.get("thread"); + use_pre_vit_merge = cmdParser.exist("premerge"); ParamLoader param_loader(model_path); auto processor = Qwen2VLProcessor(vocab_path, merge_path); - Qwen2VLConfig config(tokens_limit, "1.5b"); + Qwen2VLConfig config(tokens_limit, model_billion); auto model = Qwen2VLModel(config); model.load(model_path); vector in_imgs = { - "../assets/bus.png"}; + // "../assets/bus.png", + "../assets/two_cats.jpg", + // "../assets/bird_image.jpg", + }; vector in_strs = { "<|vision_start|><|image_pad|><|vision_end|>Describe this image.", }; @@ -52,6 +59,8 @@ int main(int argc, char **argv) { chatPostProcessing(out_token, input_tensor[0], {&input_tensor[1], &input_tensor[2]}); } printf("\n"); + model.clear_kvcache(); + model.profiling(); } return 0; diff --git a/examples/demo_showui_vtp.cpp b/examples/demo_showui_vtp.cpp index d0d5a5415..940719300 100644 --- a/examples/demo_showui_vtp.cpp +++ b/examples/demo_showui_vtp.cpp @@ -14,6 +14,7 @@ int main(int argc, char **argv) { cmdParser.add("model", 'm', "specify mllm model path", false, "../models/showui-2b-q4_k.mllm"); cmdParser.add("limits", 'l', "max KV cache size", false, 2000); cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.add("premerge", 'p', "enable pre-ViT image token merging"); cmdParser.parse_check(argc, argv); string vocab_path = cmdParser.get("vocab"); @@ -22,6 +23,7 @@ int main(int argc, char **argv) { int tokens_limit = cmdParser.get("limits"); int thread_num = cmdParser.get("thread"); CPUBackend::cpu_threads = cmdParser.get("thread"); + use_pre_vit_merge = cmdParser.exist("premerge"); ParamLoader param_loader(model_path); int min_pixels = 256 * 28 * 28; diff --git a/scripts/build_android.sh b/scripts/build_android.sh index 8268543a3..68e99a119 100755 --- a/scripts/build_android.sh +++ b/scripts/build_android.sh @@ -9,7 +9,7 @@ cmake .. \ -DANDROID_ABI="arm64-v8a" \ -DNATIVE_LIBRARY_OUTPUT=. -DNATIVE_INCLUDE_OUTPUT=. $1 $2 $3 \ -DANDROID_PLATFORM=android-34 \ --DCMAKE_CXX_FLAGS="-march=armv8.6-a+dotprod+i8mm" \ +-DCMAKE_CXX_FLAGS="-march=armv8.2-a+fp16+fp16fml+dotprod" \ -DDEBUG=OFF \ -DTEST=OFF \ -DARM=ON \ diff --git a/scripts/run_qwen2_vl.sh b/scripts/run_qwen2_vl.sh index 3fd3070c5..b795db566 100755 --- a/scripts/run_qwen2_vl.sh +++ b/scripts/run_qwen2_vl.sh @@ -13,4 +13,6 @@ if [ $? -ne 0 ]; then echo "adb push failed" exit 1 fi -adb shell "cd /data/local/tmp/mllm/bin && ./demo_qwen2_vl" \ No newline at end of file +adb shell "cd /data/local/tmp/mllm/bin && ./demo_qwen2_vl" +# adb shell "cd /data/local/tmp/mllm/bin && ./demo_qwen2_vl -m ../models/qwen-2-vl-7b-instruct-kai_q4_0.mllm -b 7B " +# adb shell "cd /data/local/tmp/mllm/bin && ./demo_qwen2_vl_vtp -m ../models/qwen-2-vl-7b-instruct-kai_q4_0_eager.mllm -b 7B " \ No newline at end of file diff --git a/src/Module.cpp b/src/Module.cpp index a078ec73d..3810c81df 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -38,7 +38,7 @@ vector Module::profiling(string name) { std::cout << " Load time: " << load_time_ / 1000.0F << " s" << std::endl; if (inference_times_.size() > 1 && decoding_token_size_ != prefilling_token_size_) { double prefile_speed = 1000 * prefilling_token_size_ / inference_times_[0]; - std::cout << " Prefilling speed: " << prefile_speed << " tokens/s" << std::endl; + std::cout << " Prefilling speed: " << prefile_speed << " tokens/s , TTFT: " << inference_times_[0] / 1000.0F << " s" << std::endl; double sum_decoding_time = std::accumulate(std::begin(inference_times_) + 1, std::end(inference_times_), 0.0); double mean_decoding_time = sum_decoding_time / (inference_times_.size() - 1); double decoding_speed = 1000 / mean_decoding_time; diff --git a/src/backends/cpu/CMakeLists.txt b/src/backends/cpu/CMakeLists.txt index 0a6a00e7d..0134c36b3 100644 --- a/src/backends/cpu/CMakeLists.txt +++ b/src/backends/cpu/CMakeLists.txt @@ -7,17 +7,17 @@ file(GLOB MLLM_CPU_SRC ) -# --- 初始化 Kleidiai 源文件和头文件目录 --- +# --- 初始化 kleidiai 源文件和头文件目录 --- set(ALL_KLEIDIAI_SOURCES "") set(ALL_KLEIDIAI_INCLUDE_DIRS "") -# Conditionally compile Kleidiai for ARM architectures +# Conditionally compile kleidiai for ARM architectures if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") - # --- 设置 Kleidiai 库的路径 --- - set(KLEIDIAI_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/third_party/Kleidiai) + # --- 设置 kleidiai 库的路径 --- + set(KLEIDIAI_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/third_party/kleidiai) if(NOT EXISTS ${KLEIDIAI_SOURCE_DIR}) - message(FATAL_ERROR "Kleidiai library not found! Please place it in 'third_party/Kleidiai'.") + message(FATAL_ERROR "kleidiai library not found! Please place it in 'third_party/kleidiai'.") endif() list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS ${KLEIDIAI_SOURCE_DIR}) @@ -58,9 +58,9 @@ if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES ) list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_SOURCES_FP32}) - # 将 Kleidiai 源文件添加到主源文件列表 + # 将 kleidiai 源文件添加到主源文件列表 list(APPEND MLLM_CPU_SRC ${ALL_KLEIDIAI_SOURCES}) -endif() # End ARM check for Kleidiai sources +endif() # End ARM check for kleidiai sources if (MLLM_OPENMP) @@ -108,7 +108,7 @@ add_library( ) endif() -# Conditionally add Kleidiai compile definitions for ARM +# Conditionally add kleidiai compile definitions for ARM if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") target_compile_definitions(lib_mllm_cpu PUBLIC KLAI_USE_QSI4_C32) target_compile_definitions(lib_mllm_cpu PUBLIC KLAI_USE_FP16) diff --git a/src/backends/cpu/compute/GemmKleidiai.cpp b/src/backends/cpu/compute/GemmKleidiai.cpp index eb3cc48f0..9dd40a583 100644 --- a/src/backends/cpu/compute/GemmKleidiai.cpp +++ b/src/backends/cpu/compute/GemmKleidiai.cpp @@ -10,10 +10,10 @@ // 引入 OpenMP 头文件 #include -//#if defined(USE_QSI4_C32) -// ###################################################################### // -// ## Implementation 1: QSI4 (INT4) ## -// ###################################################################### // +// #if defined(USE_QSI4_C32) +// ###################################################################### // +// ## Implementation 1: QSI4 (INT4) ## +// ###################################################################### // #include "kai_matmul_clamp_f32_qai8dxp_qsi4c32p_interface.h" #include "kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.h" #include "kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.h" @@ -45,21 +45,19 @@ size_t get_workspace_qsi4_size(int M, int K) { } void mllm_kleidai_pack_b_and_bias_qsi4( - uint8_t* packed_b_ptr, - const float* b_ptr, - const float* bias_ptr, + uint8_t *packed_b_ptr, + const float *b_ptr, + const float *bias_ptr, int N, int K) { - // 【新增】创建临时的bias(如果需要) - const float* bias_to_use = bias_ptr; + const float *bias_to_use = bias_ptr; std::vector fake_bias; if (bias_to_use == nullptr) { fake_bias.assign(N, 0.0f); bias_to_use = fake_bias.data(); } - const int block_len = 32; const size_t num_blocks_k = (K + block_len - 1) / block_len; std::vector temp_quantized_b(K * N / 2); @@ -106,14 +104,13 @@ void mllm_kleidai_pack_b_and_bias_qsi4( // packed_b_ptr, 0, ¶ms); kai_run_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0( 1, N, K, qsi4_ukernel.get_nr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), block_len, - temp_quantized_b.data(), N/2, bias_to_use, (const uint8_t*)temp_scales.data(), num_blocks_k * sizeof(uint16_t), + temp_quantized_b.data(), N / 2, bias_to_use, (const uint8_t *)temp_scales.data(), num_blocks_k * sizeof(uint16_t), packed_b_ptr, 0, ¶ms); } void mllm_kleidai_gemm_qsi4( - float* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, + float *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, int M, int N, int K) { - size_t workspace_size = get_workspace_qsi4_size(M, K); std::vector workspace_data(workspace_size); @@ -124,85 +121,135 @@ void mllm_kleidai_gemm_qsi4( a_ptr, K * sizeof(float), workspace_data.data()); - const int m_step = qsi4_ukernel.get_m_step(); const int n_step = qsi4_ukernel.get_n_step(); const int block_len = 32; - // #pragma omp parallel for - #pragma omp parallel for collapse(2) num_threads(kai_thread_count) +// #pragma omp parallel for +#pragma omp parallel for collapse(2) num_threads(kai_thread_count) for (int m_start = 0; m_start < M; m_start += m_step) { for (int n_start = 0; n_start < N; n_start += n_step) { const int current_m = std::min(M - m_start, m_step); const int current_n = std::min(N - n_start, n_step); - const void* a_packed_offset = (const char*)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); - const void* b_packed_offset = (const char*)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); - float* c_offset = c_ptr + m_start * N + n_start; + const void *a_packed_offset = (const char *)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); + const void *b_packed_offset = (const char *)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); + float *c_offset = c_ptr + m_start * N + n_start; qsi4_ukernel.run_matmul( current_m, current_n, K, block_len, a_packed_offset, b_packed_offset, c_offset, N * sizeof(float), sizeof(float), - -FLT_MAX, FLT_MAX - ); + -FLT_MAX, FLT_MAX); } } } // #endif // 【新增】 -//#if defined(USE_QSI4_TO_FP16) +// #if defined(USE_QSI4_TO_FP16) // ###################################################################### // // ## Implementation 1.5: QSI4 (INT4) -> FP16 ## // ###################################################################### // +// void mllm_kleidai_gemm_qsi4_to_fp16( +// mllm_fp16_t* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, +// int M, int N, int K) { + +// // 1. 创建一个临时的 FP32 输出缓冲区 +// std::vector c_temp(M * N); + +// // 2. 运行现有的 QSI4->FP32 GEMM 计算,将结果存入临时缓冲区 +// size_t workspace_size = get_workspace_qsi4_size(M, K); +// std::vector workspace_data(workspace_size); +// kai_run_lhs_quant_pack_qai8dxp_f32(M, K, qsi4_ukernel.get_mr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), +// 0, a_ptr, K * sizeof(float), workspace_data.data()); + +// const int m_step = qsi4_ukernel.get_m_step(); +// const int n_step = qsi4_ukernel.get_n_step(); +// const int block_len = 32; + +// // #pragma omp parallel for +// #pragma omp parallel for collapse(2) num_threads(kai_thread_count) +// for (int m_start = 0; m_start < M; m_start += m_step) { +// for (int n_start = 0; n_start < N; n_start += n_step) { +// const int current_m = std::min(M - m_start, m_step); +// const int current_n = std::min(N - n_start, n_step); +// const void* a_packed_offset = (const char*)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); +// const void* b_packed_offset = (const char*)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); +// float* c_offset = c_temp.data() + m_start * N + n_start; +// qsi4_ukernel.run_matmul( +// current_m, current_n, K, block_len, +// a_packed_offset, b_packed_offset, +// c_offset, N * sizeof(float), sizeof(float), +// -FLT_MAX, FLT_MAX +// ); +// } +// } + +// // 3. 并行地将 FP32 临时结果转换为 FP16 并写入最终输出 +// // #pragma omp parallel for +// #pragma omp parallel for collapse(1) num_threads(kai_thread_count) +// for(int i = 0; i < M * N; ++i) { +// c_ptr[i] = static_cast(c_temp[i]); +// } +// } + void mllm_kleidai_gemm_qsi4_to_fp16( - mllm_fp16_t* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, + mllm_fp16_t *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, int M, int N, int K) { - - // 1. 创建一个临时的 FP32 输出缓冲区 + // 1. 创建一个临时的 FP32 输出缓冲区。 + // 因为您库中唯一兼容的qsi4核心只能输出FP32,所以这一步无法避免。 std::vector c_temp(M * N); - // 2. 运行现有的 QSI4->FP32 GEMM 计算,将结果存入临时缓冲区 + // 2. 运行现有的、能正常工作的 QSI4->FP32 GEMM 计算。 + // 这部分代码与您原始版本一致,确保了计算的正确性。 size_t workspace_size = get_workspace_qsi4_size(M, K); std::vector workspace_data(workspace_size); kai_run_lhs_quant_pack_qai8dxp_f32(M, K, qsi4_ukernel.get_mr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), - 0, a_ptr, K * sizeof(float), workspace_data.data()); + 0, a_ptr, K * sizeof(float), workspace_data.data()); const int m_step = qsi4_ukernel.get_m_step(); const int n_step = qsi4_ukernel.get_n_step(); const int block_len = 32; - // #pragma omp parallel for - #pragma omp parallel for collapse(2) num_threads(kai_thread_count) +#pragma omp parallel for collapse(2) num_threads(kai_thread_count) for (int m_start = 0; m_start < M; m_start += m_step) { for (int n_start = 0; n_start < N; n_start += n_step) { const int current_m = std::min(M - m_start, m_step); const int current_n = std::min(N - n_start, n_step); - const void* a_packed_offset = (const char*)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); - const void* b_packed_offset = (const char*)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); - float* c_offset = c_temp.data() + m_start * N + n_start; + const void *a_packed_offset = (const char *)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); + const void *b_packed_offset = (const char *)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); + float *c_offset = c_temp.data() + m_start * N + n_start; + qsi4_ukernel.run_matmul( current_m, current_n, K, block_len, a_packed_offset, b_packed_offset, c_offset, N * sizeof(float), sizeof(float), - -FLT_MAX, FLT_MAX - ); + -FLT_MAX, FLT_MAX); } } - - // 3. 并行地将 FP32 临时结果转换为 FP16 并写入最终输出 - // #pragma omp parallel for - #pragma omp parallel for collapse(1) num_threads(kai_thread_count) - for(int i = 0; i < M * N; ++i) { + +// 3. 【优化点】使用NEON指令并行地将FP32临时结果高速转换为FP16。 +// 这是本方案的核心优化,远快于原始的逐元素转换。 +#pragma omp parallel for num_threads(kai_thread_count) + for (int i = 0; i <= (M * N) - 4; i += 4) { + // 一次性加载4个FP32数据 + float32x4_t fp32_vec = vld1q_f32(c_temp.data() + i); + // 一次性转换为4个FP16数据 + float16x4_t fp16_vec = vcvt_f16_f32(fp32_vec); + // 一次性存入最终的目标地址 + vst1_f16(reinterpret_cast<__fp16 *>(c_ptr + i), fp16_vec); + } + + // 处理末尾剩余的不足4个的元素 + for (int i = (M * N) - ((M * N) % 4); i < M * N; ++i) { c_ptr[i] = static_cast(c_temp[i]); } } // #endif - -//#if defined(USE_FP16) -// ###################################################################### // -// ## Implementation 2: FP16 ## -// ###################################################################### // +// #if defined(USE_FP16) +// ###################################################################### // +// ## Implementation 2: FP16 ## +// ###################################################################### // #include "kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p_interface.h" #include "kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla.h" #include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon.h" @@ -220,10 +267,10 @@ size_t mllm_kleidai_get_packed_b_fp16_size(int N, int K) { return kai_get_rhs_packed_size_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon(N, K); } -void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t* packed_b_ptr, const mllm_fp16_t* b_ptr, const float* bias_ptr, int N, int K) { +void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t *packed_b_ptr, const mllm_fp16_t *b_ptr, const float *bias_ptr, int N, int K) { std::vector bias_fp16_buffer(N); if (bias_ptr != nullptr) { - for(int i = 0; i < N; ++i) { + for (int i = 0; i < N; ++i) { bias_fp16_buffer[i] = static_cast(bias_ptr[i]); } } else { @@ -234,9 +281,9 @@ void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t* packed_b_ptr, const mllm_fp1 N * sizeof(mllm_fp16_t), b_ptr, bias_fp16_buffer.data(), nullptr, packed_b_ptr, 0, nullptr); } -void mllm_kleidai_gemm_fp16(float* c_ptr, const float* a_ptr, const mllm_fp16_t* packed_b_ptr, int M, int N, int K) { +void mllm_kleidai_gemm_fp16(float *c_ptr, const float *a_ptr, const mllm_fp16_t *packed_b_ptr, int M, int N, int K) { std::vector a_fp16(M * K); - for(int i = 0; i < M * K; ++i) { + for (int i = 0; i < M * K; ++i) { a_fp16[i] = static_cast(a_ptr[i]); } @@ -244,32 +291,31 @@ void mllm_kleidai_gemm_fp16(float* c_ptr, const float* a_ptr, const mllm_fp16_t* const int m_step = fp16_ukernel.get_m_step(); const int n_step = fp16_ukernel.get_n_step(); - // #pragma omp parallel for - #pragma omp parallel for collapse(2) num_threads(kai_thread_count) +// #pragma omp parallel for +#pragma omp parallel for collapse(2) num_threads(kai_thread_count) for (int m_start = 0; m_start < M; m_start += m_step) { for (int n_start = 0; n_start < N; n_start += n_step) { const int current_m = std::min(M - m_start, m_step); const int current_n = std::min(N - n_start, n_step); - const mllm_fp16_t* a_offset = a_fp16.data() + m_start * K; - const mllm_fp16_t* b_offset = packed_b_ptr + (n_start * (K + 1)); - mllm_fp16_t* c_offset = c_fp16.data() + m_start * N + n_start; + const mllm_fp16_t *a_offset = a_fp16.data() + m_start * K; + const mllm_fp16_t *b_offset = packed_b_ptr + (n_start * (K + 1)); + mllm_fp16_t *c_offset = c_fp16.data() + m_start * N + n_start; fp16_ukernel.run_matmul( current_m, current_n, K, a_offset, K * sizeof(mllm_fp16_t), b_offset, c_offset, N * sizeof(mllm_fp16_t), sizeof(mllm_fp16_t), - -FLT_MAX, FLT_MAX ); + -FLT_MAX, FLT_MAX); } } - for(int i = 0; i < M * N; ++i) { + for (int i = 0; i < M * N; ++i) { c_ptr[i] = static_cast(c_fp16[i]); } } // #endif - -//#if defined(USE_FP32) -// ###################################################################### // -// ## Implementation 3: FP32 ## -// ###################################################################### // +// #if defined(USE_FP32) +// ###################################################################### // +// ## Implementation 3: FP32 ## +// ###################################################################### // #include "kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p_interface.h" #include "kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla.h" #include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon.h" @@ -287,8 +333,8 @@ size_t mllm_kleidai_get_packed_b_fp32_size(int N, int K) { return kai_get_rhs_packed_size_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon(N, K); } -void mllm_kleidai_pack_b_and_bias_fp32(float* packed_b_ptr, const float* b_ptr, const float* bias_ptr, int N, int K) { - const float* bias_to_use = bias_ptr; +void mllm_kleidai_pack_b_and_bias_fp32(float *packed_b_ptr, const float *b_ptr, const float *bias_ptr, int N, int K) { + const float *bias_to_use = bias_ptr; std::vector fake_bias; if (bias_to_use == nullptr) { fake_bias.assign(N, 0.0f); @@ -299,24 +345,24 @@ void mllm_kleidai_pack_b_and_bias_fp32(float* packed_b_ptr, const float* b_ptr, N * sizeof(float), b_ptr, bias_to_use, nullptr, packed_b_ptr, 0, nullptr); } -void mllm_kleidai_gemm_fp32(float* c_ptr, const float* a_ptr, const float* packed_b_ptr, int M, int N, int K) { +void mllm_kleidai_gemm_fp32(float *c_ptr, const float *a_ptr, const float *packed_b_ptr, int M, int N, int K) { const int m_step = fp32_ukernel.get_m_step(); const int n_step = fp32_ukernel.get_n_step(); - - // #pragma omp parallel for - #pragma omp parallel for collapse(2) num_threads(kai_thread_count) + +// #pragma omp parallel for +#pragma omp parallel for collapse(2) num_threads(kai_thread_count) for (int m_start = 0; m_start < M; m_start += m_step) { for (int n_start = 0; n_start < N; n_start += n_step) { const int current_m = std::min(M - m_start, m_step); const int current_n = std::min(N - n_start, n_step); - const float* a_offset = a_ptr + m_start * K; - const float* b_offset = packed_b_ptr + (n_start * (K + 1)); - float* c_offset = c_ptr + m_start * N + n_start; + const float *a_offset = a_ptr + m_start * K; + const float *b_offset = packed_b_ptr + (n_start * (K + 1)); + float *c_offset = c_ptr + m_start * N + n_start; fp32_ukernel.run_matmul( current_m, current_n, K, a_offset, K * sizeof(float), b_offset, c_offset, N * sizeof(float), sizeof(float), - -FLT_MAX, FLT_MAX ); + -FLT_MAX, FLT_MAX); } } } diff --git a/src/backends/cpu/op/CPUMultimodalRoPE.cpp b/src/backends/cpu/op/CPUMultimodalRoPE.cpp index 2cbaeceed..62cf15d55 100644 --- a/src/backends/cpu/op/CPUMultimodalRoPE.cpp +++ b/src/backends/cpu/op/CPUMultimodalRoPE.cpp @@ -8,6 +8,8 @@ #include // #include #include "backends/cpu/compute/QuantizeQ8.hpp" +#include // 用来计算 accumulate +#include // 用来断言 namespace mllm { @@ -38,6 +40,11 @@ void apply_multimodal_rotary_pos_emb( std::vector> &out_cos, std::vector> &out_sin, const std::vector &mrope_section) { + // 在函数一开始就检查尺寸! + long long total_mrope_dim = std::accumulate(mrope_section.begin(), mrope_section.end(), 0LL); + long long input_dim = in_cos[0][0].size(); + assert(total_mrope_dim <= input_dim && "CRITICAL ERROR: Sum of mrope_section exceeds input dimension!"); + int num_rows = in_cos[0].size(); int num_cols = in_cos[0][0].size(); // 初始化输出向量大小 @@ -77,6 +84,8 @@ void apply_multimodal_rotary_pos_emb( void multimodal_sinusoidal_position_embedding(shared_ptr position_ids, int seq_len, int output_dim, const vector &theta, vector> &sin, vector> &cos, float attention_scaling = 1.0, const std::vector &mrope_section = {}) { + sin.clear(); + cos.clear(); vector>> tmp_sin; vector>> tmp_cos; // assert(position_ids->dimension() == output_dim); @@ -97,6 +106,14 @@ void multimodal_sinusoidal_position_embedding(shared_ptr position_ids, i } if (!mrope_section.empty()) { apply_multimodal_rotary_pos_emb(tmp_cos, tmp_sin, cos, sin, mrope_section); + } else { + // 如果 mrope_section 为空,这是标准的 RoPE + // 需要把局部变量 tmp_cos/tmp_sin 的内容赋给输出参数 cos/sin + // 假设 batch size 为 1,所以我们取第一个元素 + if (!tmp_cos.empty()) { // 做个健壮性检查 + cos = std::move(tmp_cos[0]); // 使用 std::move 避免不必要的拷贝,效率更高 + sin = std::move(tmp_sin[0]); + } } } @@ -106,9 +123,6 @@ CPUMultimodalRoPE::CPUMultimodalRoPE(Backend *bn, string opName, float rope_thet rope_theta_ = rope_theta; pos_max_ = max_position_embeddings; mrope_section_ = mrope_section; - for (int i = 0; i < mrope_section.size(); i++) { - mrope_section_.push_back(mrope_section[i]); - } } ErrorCode CPUMultimodalRoPE::reshape(vector> inputs, vector> outputs) { diff --git a/src/models/qwen/configuration_qwen.hpp b/src/models/qwen/configuration_qwen.hpp index 686b48b46..5a5a8eba6 100644 --- a/src/models/qwen/configuration_qwen.hpp +++ b/src/models/qwen/configuration_qwen.hpp @@ -191,6 +191,21 @@ struct QWenConfig : public TransformerConfig { sliding_window = 131072; vocab_size = 151936; tie_embedding_words = false; + } else if (billionsType == "7b") { + attention_dropout = 0.0; + std::string hidden_act = "silu"; + hidden_size = 3584; + intermediate_size = 18944; + max_position_embeddings = 32768; + max_window_layers = 28; + num_attention_heads = 28; + num_hidden_layers = 28; + num_key_value_heads = 4; + rms_norm_eps = 1e-6; + rope_theta = 1000000.0; + sliding_window = 32768; + vocab_size = 151936; + tie_embedding_words = false; } else { throw std::runtime_error("Unsupported model size"); } diff --git a/src/models/qwen2_vl/configuration_qwen2_vl.hpp b/src/models/qwen2_vl/configuration_qwen2_vl.hpp index d7cce5ade..2bab7f744 100644 --- a/src/models/qwen2_vl/configuration_qwen2_vl.hpp +++ b/src/models/qwen2_vl/configuration_qwen2_vl.hpp @@ -10,34 +10,34 @@ using namespace mllm; class Qwen2VLNameConfig : public ViTNameConfig { - public: - // string token_embd_name = "model.embed_tokens"; - string patch_embed_name = ".patch_embed"; // - string _merger_name = ".merger"; // - string _ln_q_name = ".ln_q"; // - string _m_mlp_0_name = ".mlp.0"; // - string _m_mlp_2_name = ".mlp.2"; // - void init_qwen2vl() { - vison_model_name = "visual"; // - _patch_embedding_name = ".proj"; // - _layer_name = ".blocks."; // - _attn_base_name = "attn."; // - _ffn_base_name = "mlp."; // - _qkv_proj_name = "qkv"; // - _o_proj_name = "proj"; // - _up_proj_name = "fc1"; // - _down_proj_name = "fc2"; // - _attn_norm_name = "norm1"; // - _ffn_norm_name = "norm2"; // - } +public: + // string token_embd_name = "model.embed_tokens"; + string patch_embed_name = ".patch_embed"; // + string _merger_name = ".merger"; // + string _ln_q_name = ".ln_q"; // + string _m_mlp_0_name = ".mlp.0"; // + string _m_mlp_2_name = ".mlp.2"; // + void init_qwen2vl() { + vison_model_name = "visual"; // + _patch_embedding_name = ".proj"; // + _layer_name = ".blocks."; // + _attn_base_name = "attn."; // + _ffn_base_name = "mlp."; // + _qkv_proj_name = "qkv"; // + _o_proj_name = "proj"; // + _up_proj_name = "fc1"; // + _down_proj_name = "fc2"; // + _attn_norm_name = "norm1"; // + _ffn_norm_name = "norm2"; // + } }; class Qwen2VLConfig : public QWenConfig { public: int vision_embed_dim; - int spatial_merge_size= 2; + int spatial_merge_size = 2; string projection_cls; - + int bos_token_id = 151643; int eos_token_id = 151645; int vision_start_token_id = 151652; @@ -52,7 +52,6 @@ class Qwen2VLConfig : public QWenConfig { QWenConfig(token_limit, billions, type) { // names_config.init(type); projection_cls = project_cls; - hidden_size = 1536; vision_embed_dim = 1280; vision_names_config.init_qwen2vl(); } diff --git a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp index 0fa959991..a22aa147c 100644 --- a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp @@ -6,8 +6,10 @@ // #define VTP #define NDC -#define SUC +#include +#include +#include #include "Layer.hpp" #include "Module.hpp" #include "Tensor.hpp" @@ -15,16 +17,10 @@ #include "../configuration_qwen2_vl.hpp" #if defined(VTP) #include "vtp_tools.hpp" -#endif -#ifdef NDC +#elif defined(NDC) #include "ndc_tools.hpp" #endif -#ifdef SUC #include "ui_tools.hpp" -#endif -#include -#include -#include using namespace mllm; @@ -184,15 +180,18 @@ class Qwen2VisionModel final : public Module { auto grid_h = inputs[1].dataAt(0, 0, 0, 1); auto grid_w = inputs[1].dataAt(0, 0, 0, 2); vector cu_seqlens_v = {0.0F, grid_t * grid_h * grid_w}; -#ifdef SUC - std::vector> region_masks = {UIRegionMask}; - auto selected_indices = process_region_mask(region_masks); - if (selected_indices.size() != cu_seqlens_v[1]) { - cu_seqlens_v[1] = float(selected_indices.size()); - rotary_pos_emb = rotary_pos_emb.clip(selected_indices, SEQUENCE); - hidden_states = hidden_states.clip(selected_indices, SEQUENCE); + + if (use_pre_vit_merge) { + std::vector> region_masks = {UIRegionMask}; + auto selected_indices = process_region_mask(region_masks); + // std::cout << selected_indices.size() << " " << cu_seqlens_v[1] << std::endl; + if (selected_indices.size() != cu_seqlens_v[1]) { + cu_seqlens_v[1] = float(selected_indices.size()); + rotary_pos_emb = rotary_pos_emb.clip(selected_indices, SEQUENCE); + hidden_states = hidden_states.clip(selected_indices, SEQUENCE); + } } -#endif + auto cu_seqlens = Tensor(cu_seqlens_v); for (auto &block : blocks) { hidden_states = block({hidden_states, cu_seqlens, rotary_pos_emb})[0]; diff --git a/src/models/qwen2_vl/vtp/ndc_tools.hpp b/src/models/qwen2_vl/vtp/ndc_tools.hpp index 1eef503f6..0463c63ae 100644 --- a/src/models/qwen2_vl/vtp/ndc_tools.hpp +++ b/src/models/qwen2_vl/vtp/ndc_tools.hpp @@ -93,8 +93,8 @@ class DelayComputeKVCache { const int k_size = num_heads * k_per_head; const int v_size = v_per_head; // 1. 分配临时内存 - if(cache_sequence <= pos_first){ - pos_first =0; + if (cache_sequence <= pos_first) { + pos_first = 0; } vector> k_cache_data(cache_sequence - pos_first); vector>> v_cache_data(num_heads); @@ -191,14 +191,38 @@ class NdcContext { int num_head = 0; int original_kv_length = 0; int chunk_size = 4; - map pruning_place_cfg = {{3, 0.2}, {9, 0.2}, {12, 0.2}, {15, 0.2}, {18, 0.2}, {26, 0.2}}; + // map pruning_place_cfg = {{3, 0.2}, {9, 0.2}, {12, 0.6}, {15, 0.6}, {18, 0.8}, {26, 0.8}}; + // map pruning_place_cfg = {{3, 0.2}, {6, 0.8}, {12, 0.8}, {15, 0.8}, {18, 0.8}, {26, 0.8}}; + map pruning_place_cfg = {{3, 0.2}, {6, 0.2}, {12, 0.8}, {15, 0.8}, {18, 0.8}, {26, 0.8}}; // map pruning_place_cfg = {{3, 0.2}, {9, 0.2}}; public: map causal_masks; // layer_idx -> causal_mask bool prefill_stage = true; + + /** + * @brief Resets the context to its initial state. + * This function should be called to clear the state between different generation requests. + */ + void reset() { + first_img_token_pos = 0; + last_img_token_pos = 0; + last_img_token_pos_l = 0; + kvcache_ctx = DelayComputeKVCache(); // Re-initialize the KV cache context + cur_step = -1; + chosen_pos_in_each.clear(); + chosen_pos_to_delay_compute.clear(); + global_position_ids = Tensor(); // Reset to an empty tensor + num_hidden_layers = 0; + num_head = 0; + original_kv_length = 0; + causal_masks.clear(); + prefill_stage = true; + } + void init(Tensor input_ids, int num_layers, int num_attention_heads) { if (Module::llm_model_ptr->doLoad) { return; } + // reset(); num_hidden_layers = num_layers; num_head = num_attention_heads; if (kvcache_ctx.hidden_states_cache.empty()) { diff --git a/src/models/qwen2_vl/vtp/ui_tools.hpp b/src/models/qwen2_vl/vtp/ui_tools.hpp index 0e2bbb609..d9e367aa4 100644 --- a/src/models/qwen2_vl/vtp/ui_tools.hpp +++ b/src/models/qwen2_vl/vtp/ui_tools.hpp @@ -9,6 +9,8 @@ #include #include // 需要包含 用于 std::sort 和 std::unique #include // 需要包含 用于 uint32_t +bool use_pre_vit_merge = false; + std::vector UIRegionMask; // 输入类型为二维向量 [batch][patch_size] std::vector process_region_mask(const std::vector> ®ion_masks) { diff --git a/src/quantizer/QuantWriter.cpp b/src/quantizer/QuantWriter.cpp index 54044bf4e..91fa43829 100644 --- a/src/quantizer/QuantWriter.cpp +++ b/src/quantizer/QuantWriter.cpp @@ -118,7 +118,7 @@ void QuantWriter::quantParams(DataType dataType) { writeParam(name, MLLM_TYPE_F32, param, tsize); std::cout << " size:" << tsize << std::endl; - } else if (find_names(name, q6_layers)&& (dataType != MLLM_TYPE_KLEIDIAI_Q4_0)) { + } else if (find_names(name, q6_layers) && (dataType != MLLM_TYPE_KLEIDIAI_Q4_0)) { switch (dataType) { case MLLM_TYPE_F32: std::cout << "No need to quantize FP32 params\n"; @@ -199,7 +199,7 @@ void QuantWriter::quantParams(DataType dataType) { std::cout << "No need to quantize FP32 params\n"; __exit(-1); break; - case MLLM_TYPE_KLEIDIAI_Q4_0:{ + case MLLM_TYPE_KLEIDIAI_Q4_0: { #if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) // todo:对qwen/qwen2vl特化了,后续一定要重写 int K = tmp_hidden_dim; @@ -210,7 +210,7 @@ void QuantWriter::quantParams(DataType dataType) { } std::vector transposed_weight_data(K * N); const float *original_weight_ptr = param; - #pragma omp parallel for collapse(2) num_threads(4) +#pragma omp parallel for collapse(2) num_threads(4) for (int n = 0; n < N; ++n) { for (int k = 0; k < K; ++k) { // 核心转置逻辑:dst[k][n] = src[n][k] @@ -225,16 +225,16 @@ void QuantWriter::quantParams(DataType dataType) { bias_name.replace(bias_name.find("weight"), 6, "bias"); auto *bias_param = getParam(bias_name); float first_bias = bias_param[0]; - // std::cout << "【Kleidiai】======Quantize param " << name << " bias: " << first_bias << std::endl; + // std::cout << "【Kleidiai】======Quantize param " << name << " bias: " << first_bias << std::endl; // if (bias_param != nullptr && name.find("o_proj") == std::string::npos&& name.find("mlp") == std::string::npos) { if (first_bias != 0.0f) { - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), - bias_param, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; - }else{ - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), - nullptr, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), + bias_param, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; + } else { + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), + nullptr, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; } } else { throw std::runtime_error("name does not contain 'weight': " + name); @@ -242,9 +242,8 @@ void QuantWriter::quantParams(DataType dataType) { size = block_t.second; break; #else - std::cerr << "KLEIDIAI_Q4_0 is not supported on this platform!" << std::endl; - exit(-1); - return NOT_SUPPORT; + std::cerr << "KLEIDIAI_Q4_0 is not supported on this platform!" << std::endl; + exit(-1); #endif } case MLLM_TYPE_Q4_0: @@ -476,10 +475,9 @@ void QuantWriter::quantParams_q4_vl(DataType dataType) { writeIndex(); } - vector vl_q4x4_2_q4_k_layers = { // "wv", - // "v_proj", + // "v_proj", //eager mode ".attn.qkv", "in_proj", "w12", @@ -488,8 +486,8 @@ vector vl_q4x4_2_q4_k_layers = { // "mlp.0", // "mlp.2", }; - void QuantWriter::quantParams_kai_vl(DataType dataType) { +#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) for (const auto &name : param_names_) { auto size = param_loader_->offsets_[name].second / sizeof(float); if (find_names(name, {"input_layernorm"}) && find_names(name, {"model"})) { @@ -540,7 +538,6 @@ void QuantWriter::quantParams_kai_vl(DataType dataType) { // } // quantize_row_q4_0_4x4(param, quant_ptr, size, tmp_hidden_dim_q4); - int K = vit_tmp_hidden_dim; int N = size / K; if (find_names(name, {"fc2", "down_proj"})) { @@ -549,7 +546,7 @@ void QuantWriter::quantParams_kai_vl(DataType dataType) { } std::vector transposed_weight_data(K * N); const float *original_weight_ptr = param; - #pragma omp parallel for collapse(2) num_threads(4) +#pragma omp parallel for collapse(2) num_threads(4) for (int n = 0; n < N; ++n) { for (int k = 0; k < K; ++k) { transposed_weight_data[k * N + n] = original_weight_ptr[n * K + k]; @@ -564,13 +561,13 @@ void QuantWriter::quantParams_kai_vl(DataType dataType) { auto *bias_param = getParam(bias_name); float first_bias = bias_param[0]; if (first_bias != 0.0f) { - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), - bias_param, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; - }else{ - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), - nullptr, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), + bias_param, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; + } else { + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), + nullptr, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; } } else { throw std::runtime_error("name does not contain 'weight': " + name); @@ -590,7 +587,7 @@ void QuantWriter::quantParams_kai_vl(DataType dataType) { } std::vector transposed_weight_data(K * N); const float *original_weight_ptr = param; - #pragma omp parallel for collapse(2) num_threads(4) +#pragma omp parallel for collapse(2) num_threads(4) for (int n = 0; n < N; ++n) { for (int k = 0; k < K; ++k) { transposed_weight_data[k * N + n] = original_weight_ptr[n * K + k]; @@ -605,18 +602,17 @@ void QuantWriter::quantParams_kai_vl(DataType dataType) { auto *bias_param = getParam(bias_name); float first_bias = bias_param[0]; if (first_bias != 0.0f) { - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), - bias_param, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; - }else{ - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t*)quant_ptr, transposed_weight_data.data(), - nullptr, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K <<", \t"; + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), + bias_param, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; + } else { + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), + nullptr, N, K); + std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; } } else { throw std::runtime_error("name does not contain 'weight': " + name); } - } size = block_t.second; if (quant_ptr != nullptr) { @@ -629,9 +625,12 @@ void QuantWriter::quantParams_kai_vl(DataType dataType) { } } writeIndex(); +#else + std::cerr << "KLEIDIAI_Q4_0 is not supported on this platform!" << std::endl; + exit(-1); +#endif } - void QuantWriter::writeParam(string name, DataType type, void *data, uint64_t size) { #ifdef TEST data_[name] = (char *)data; diff --git a/src/quantizer/QuantWriter.hpp b/src/quantizer/QuantWriter.hpp index e14a33233..a341f80a8 100644 --- a/src/quantizer/QuantWriter.hpp +++ b/src/quantizer/QuantWriter.hpp @@ -35,6 +35,7 @@ static std::pair alloc_quant_block(uint64_t count, DataType ty return std::make_pair(data, size); } +#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) static std::pair alloc_kleidiai_quant_block(DataType type, int N, int K) { assert(type == MLLM_TYPE_KLEIDIAI_Q4_0); uint64_t size = mllm_kleidai_get_packed_b_qsi4_size(N, K); @@ -44,7 +45,10 @@ static std::pair alloc_kleidiai_quant_block(DataType type, int void *data = new uint8_t[size]; return std::make_pair(data, size); } +#endif namespace mllm { +extern std::vector vl_q4x4_2_q4_k_layers; + class QuantWriter : public ParamWriter { public: ~QuantWriter(); @@ -55,7 +59,6 @@ class QuantWriter : public ParamWriter { void quantParams_q4_vl(DataType dataType); void quantParams_kai_vl(DataType dataType); - #ifdef TEST std::unordered_map data_; diff --git a/src/quantizer/main.cpp b/src/quantizer/main.cpp index c42582dd7..7a9a145cb 100644 --- a/src/quantizer/main.cpp +++ b/src/quantizer/main.cpp @@ -7,13 +7,14 @@ #include "QuantWriter.hpp" int main(int argc, char **argv) { - if (argc != 4) { + if (argc < 4) { std::cout << "Usage: ./quantize \n"; return -1; } auto input_path = std::string(argv[1]); auto output_path = std::string(argv[2]); auto quant_type = std::string(argv[3]); + auto other_flag = std::string(argv[4]); // std::string input_path = "../models/qwen-2.5-1.5b-instruct-fp32.mllm"; // std::string output_path = "../models/qwen-2.5-1.5b-instruct-kai_q4_0.mllm"; // std::string input_path = "../models/qwen-2-vl-2b-instruct-fp32.mllm"; @@ -42,9 +43,16 @@ int main(int argc, char **argv) { quant_writer.quantParams(MLLM_TYPE_Q8_K); } else if (quant_type == "KAI_Q4_0") { // quant_writer.quantParams(MLLM_TYPE_KLEIDIAI_Q4_0); + if (other_flag == "eager") { + vl_q4x4_2_q4_k_layers.push_back("v_proj"); + } quant_writer.quantParams_kai_vl(MLLM_TYPE_KLEIDIAI_Q4_0); } else if (quant_type == "Q4_0_4_4") { - quant_writer.quantParams_q4_(MLLM_TYPE_Q4_0_4_4); + if (other_flag == "vl") { + quant_writer.quantParams_q4_vl(MLLM_TYPE_Q4_0_4_4); + } else { + quant_writer.quantParams_q4_(MLLM_TYPE_Q4_0_4_4); + } } else { std::cout << "Quant type " << quant_type << " is not supported\n"; return -1; From 42e5bb78969fcbaa375fdc3a06d71554a8e80ea0 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Sat, 14 Jun 2025 14:34:56 +0000 Subject: [PATCH 09/22] feat: add i8mm kleidai for a32bi4 --- .gitignore | 6 +- CMakeLists.txt | 22 +- examples/CMakeLists.txt | 23 +- examples/demo_ds_qwen2.cpp | 4 +- examples/demo_showui.cpp | 1 + ...o_qwen2_vl_npu.cpp => demo_showui_npu.cpp} | 0 include/Types.hpp | 8 + scripts/build_android.sh | 2 +- scripts/run_qwen2_vl.sh | 1 + ...{run_qwen2_vl_qnn.sh => run_showui_qnn.sh} | 4 +- src/Tensor.cpp | 8 +- src/Tensor.hpp | 247 +++- src/backends/cpu/CMakeLists.txt | 26 +- src/backends/cpu/CPUBackend.cpp | 227 ++-- src/backends/cpu/compute/FeatureCheck.hpp | 78 ++ src/backends/cpu/compute/FlashAttention2.hpp | 113 +- src/backends/cpu/compute/FlashAttention2H.hpp | 1054 +++++++++++++++++ src/backends/cpu/compute/GemmKleidiai.cpp | 382 ++++-- src/backends/cpu/compute/GemmKleidiai.hpp | 12 +- .../compute/{GemmAarch64.cpp => GemmPack.cpp} | 162 ++- .../compute/{GemmAarch64.hpp => GemmPack.hpp} | 0 src/backends/cpu/compute/Split.hpp | 111 ++ src/backends/cpu/compute/Transpose2D.hpp | 262 ++++ src/backends/cpu/compute/Transpose3D.hpp | 220 ++++ src/backends/cpu/compute/VecDotType.cpp | 2 +- .../cpu/function/CPUFlashAttention2Func.hpp | 64 +- src/backends/cpu/function/CPUMatmulFunc.hpp | 1 - src/backends/cpu/function/CPUSplitFunc.hpp | 167 +-- .../cpu/function/CPUTransposeFunc.hpp | 65 + src/backends/cpu/op/CPUKVCache.cpp | 62 +- src/backends/cpu/op/CPULinear.cpp | 60 +- src/backends/cpu/op/CPULinear.hpp | 1 + src/backends/qnn/CMakeLists.txt | 10 +- src/backends/xnnpack/CMakeLists.txt | 10 +- src/models/bert/modeling_bert.hpp | 2 +- src/models/clip/modeling_clip.hpp | 4 +- src/models/dclm/modeling_dclm.hpp | 6 +- src/models/fuyu/modeling_fuyu.hpp | 6 +- src/models/gemma/modeling_gemma.hpp | 6 +- src/models/imagebind/modeling_imagebind.hpp | 5 +- src/models/llama/modeling_elastic_llama.hpp | 36 +- src/models/llama/modeling_llama.hpp | 4 +- src/models/llama/modeling_sparse_llama.hpp | 4 +- src/models/minicpm/modeling_minicpm.hpp | 5 +- .../mbm/modeling_minicpm_moe_mbm.hpp | 5 +- .../mbp/modeling_minicpm_moe_mbp.hpp | 5 +- .../minicpm_moe/modeling_minicpm_moe.hpp | 5 +- src/models/mistral/modeling_mistral.hpp | 5 +- src/models/opt/modeling_opt.hpp | 4 +- src/models/phi3/modeling_phi3.hpp | 2 +- src/models/qwen/modeling_qwen.hpp | 105 +- src/models/qwen2_vl/modeling_qwen2_vl.hpp | 22 +- src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp | 22 +- src/models/qwen3/configuration_qwen3.hpp | 17 +- src/models/qwen3/modeling_qwen3.hpp | 119 +- src/models/smollm/modeling_smollm.hpp | 2 +- src/models/stablelm/modeling_stablelm.hpp | 28 +- src/models/tinyllama/modeling_tinyllama.hpp | 4 +- .../transformer/modeling_transformer.hpp | 101 +- src/models/vit/modeling_vit.hpp | 6 +- src/quantizer/QuantWriter.cpp | 2 +- src/quantizer/QuantWriter.hpp | 2 +- src/quantizer/{main.cpp => main_quantize.cpp} | 14 +- test/CMakeLists.txt | 4 +- test/xnnpack/XpLlamaMHATest.cpp | 22 +- 65 files changed, 3192 insertions(+), 797 deletions(-) rename examples/{demo_qwen2_vl_npu.cpp => demo_showui_npu.cpp} (100%) rename scripts/{run_qwen2_vl_qnn.sh => run_showui_qnn.sh} (94%) create mode 100644 src/backends/cpu/compute/FeatureCheck.hpp create mode 100644 src/backends/cpu/compute/FlashAttention2H.hpp rename src/backends/cpu/compute/{GemmAarch64.cpp => GemmPack.cpp} (95%) rename src/backends/cpu/compute/{GemmAarch64.hpp => GemmPack.hpp} (100%) create mode 100644 src/backends/cpu/compute/Split.hpp create mode 100644 src/backends/cpu/compute/Transpose2D.hpp create mode 100644 src/backends/cpu/compute/Transpose3D.hpp rename src/quantizer/{main.cpp => main_quantize.cpp} (84%) diff --git a/.gitignore b/.gitignore index 549dbb44e..3c53830cc 100644 --- a/.gitignore +++ b/.gitignore @@ -32,9 +32,7 @@ tmp/ py-build-out/ mllm.egg-info/ -examples/demo_deepseek.cpp -src/models/deepseek/* -examples/demo.cpp - src/backends/qnn/sdk/* .DS_Store +src/models/ling/modeling_bailing_moe.hpp +src/models/ling/configuration_bailing_moe.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e4e9a6af..a8697b2ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,8 @@ endif () if (ARM) if(QNN) set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin-arm-qnn) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING) +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin) else() set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin-arm) endif() @@ -46,7 +48,7 @@ endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") # 默认使用 armv8.2-a+dotprod,除非用户自定义了 CMAKE_CXX_FLAGS if(NOT DEFINED CMAKE_CXX_FLAGS OR CMAKE_CXX_FLAGS STREQUAL "") - set(CMAKE_CXX_FLAGS "-march=armv8.6-a+dotprod+i8mm") + set(CMAKE_CXX_FLAGS "-march=armv8.2-a+fp16+fp16fml+dotprod+i8mm") endif() endif() else () @@ -193,7 +195,7 @@ file(GLOB_RECURSE SRC_TOKENIZERS if(QUANT) include_directories(${PROJECT_SOURCE_DIR}/src/quantizer) file(GLOB_RECURSE MLLM_QUANT - ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/GemmAarch64.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/GemmPack.cpp ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ8.cpp ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ4.cpp ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ6.cpp @@ -213,6 +215,8 @@ if(QUANT) # QSI4 模块源文件 ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod_asm.S + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm_asm.S ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.c @@ -238,10 +242,10 @@ if(QUANT) file(GLOB_RECURSE MLLM_QUANTIZER ${PROJECT_SOURCE_DIR}/src/quantizer/*.cpp ${PROJECT_SOURCE_DIR}/src/quantizer/*.hpp) - list(REMOVE_ITEM MLLM_QUANTIZER ${PROJECT_SOURCE_DIR}/src/quantizer/main.cpp) + list(REMOVE_ITEM MLLM_QUANTIZER ${PROJECT_SOURCE_DIR}/src/quantizer/main_quantize.cpp) add_executable( quantize - ${PROJECT_SOURCE_DIR}/src/quantizer/main.cpp + ${PROJECT_SOURCE_DIR}/src/quantizer/main_quantize.cpp ${MLLM_QUANT} ${MLLM_QUANTIZER} ${PROJECT_SOURCE_DIR}/src/ParamLoader.cpp @@ -308,24 +312,24 @@ if(APK) # models/smollm/tokenization_smollm.hpp # tokenizers/Unigram/Unigram.hpp ) - target_link_libraries(mllm_lib lib_mllm_cpu) + target_link_libraries(mllm_lib mllm_cpu) if(QNN) - target_link_libraries(mllm_lib lib_mllm_qnn) + target_link_libraries(mllm_lib mllm_qnn) endif() endif() if(MLLM_ENABLE_PYTHON) - target_compile_options(lib_mllm_cpu PRIVATE -fPIC) + target_compile_options(mllm_cpu PRIVATE -fPIC) find_package(Python3 COMPONENTS Interpreter Development) include_directories(${Python3_INCLUDE_DIRS}) add_subdirectory(${PROJECT_SOURCE_DIR}/third_party/pybind11) set(_py_dep_libs - lib_mllm_cpu + mllm_cpu - # lib_mllm_qnn + # mllm_qnn # ${CMAKE_DL_LIBS} ) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 50287817e..b6f450b9a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -28,7 +28,7 @@ macro(func_set_compile_opts_defs target) endmacro() macro(func_link_libs target) - target_link_libraries(${target} PUBLIC lib_mllm_cpu fmt::fmt-header-only) + target_link_libraries(${target} PUBLIC mllm_cpu fmt::fmt-header-only) if (MLLM_OPENMP) if (ARM AND NOT (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING)) # 非Mac的ARM,静态链接OpenMP @@ -39,30 +39,30 @@ macro(func_link_libs target) endif() endif() if (QNN) - target_link_libraries(${target} PUBLIC lib_mllm_qnn ${CMAKE_DL_LIBS}) + target_link_libraries(${target} PUBLIC mllm_qnn ${CMAKE_DL_LIBS}) endif() if (MLLM_BUILD_XNNPACK_BACKEND) - target_link_libraries(${target} PRIVATE lib_mllm_xnnpack) + target_link_libraries(${target} PRIVATE mllm_xnnpack) endif() endmacro() -add_library(lib_mllm_common_llm STATIC ${COMMON_SRC}) -func_set_compile_opts_defs(lib_mllm_common_llm) +add_library(mllm_llm STATIC ${COMMON_SRC}) +func_set_compile_opts_defs(mllm_llm) -add_library(lib_mllm_vlm STATIC ${VLM_SPECIFIC_SRC}) -target_link_libraries(lib_mllm_vlm PUBLIC lib_mllm_common_llm) -func_set_compile_opts_defs(lib_mllm_vlm) +add_library(mllm_vlm STATIC ${VLM_SPECIFIC_SRC}) +target_link_libraries(mllm_vlm PUBLIC mllm_llm) +func_set_compile_opts_defs(mllm_vlm) macro(func_llm_add_executable target) add_executable(${target} ${PROJECT_SOURCE_DIR}/examples/${target}.cpp) - target_link_libraries(${target} PUBLIC lib_mllm_common_llm) + target_link_libraries(${target} PUBLIC mllm_llm) func_set_compile_opts_defs(${target}) func_link_libs(${target}) endmacro() macro(func_vlm_add_executable target) add_executable(${target} ${PROJECT_SOURCE_DIR}/examples/${target}.cpp) - target_link_libraries(${target} PUBLIC lib_mllm_vlm) + target_link_libraries(${target} PUBLIC mllm_vlm) func_set_compile_opts_defs(${target}) func_link_libs(${target}) endmacro() @@ -111,7 +111,8 @@ if(QNN) func_llm_add_executable(demo_qwen_npu) func_llm_add_executable(demo_phonelm_npu) func_llm_add_executable(demo_qwen2.5_npu) - func_vlm_add_executable(demo_qwen2_vl_npu) + # func_vlm_add_executable(demo_qwen2_vl_npu) + func_vlm_add_executable(demo_showui_npu) endif() if(MLLM_BUILD_XNNPACK_BACKEND) diff --git a/examples/demo_ds_qwen2.cpp b/examples/demo_ds_qwen2.cpp index 36ef9ee6d..afa588790 100644 --- a/examples/demo_ds_qwen2.cpp +++ b/examples/demo_ds_qwen2.cpp @@ -23,7 +23,7 @@ int main(int argc, char **argv) { cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/ds_qwen2_merges.txt"); cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ds-qwen-2-1.5b-q4_k.mllm"); cmdParser.add("billion", 'b', "only support ds-1.5B right now", false, "ds-1.5B"); - cmdParser.add("limits", 'l', "max KV cache size", false, 400); + cmdParser.add("limits", 'l', "max KV cache size", false, 1040); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); @@ -47,7 +47,7 @@ int main(int argc, char **argv) { std::cout << "[A] " << std::flush; LlmTextGeneratorOpts opt{ - .max_new_tokens = 300, + .max_new_tokens = 1000, .do_sample = true, .temperature = 0.3F, .top_k = 50, diff --git a/examples/demo_showui.cpp b/examples/demo_showui.cpp index 54bfd809a..aa099e268 100644 --- a/examples/demo_showui.cpp +++ b/examples/demo_showui.cpp @@ -13,6 +13,7 @@ int main(int argc, char **argv) { cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/showui_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/showui_merges.txt"); cmdParser.add("model", 'm', "specify mllm model path", false, "../models/showui-2b-q4_k.mllm"); + // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/showui-2b-kai_q4_0.mllm"); cmdParser.add("limits", 'l', "max KV cache size", false, 2000); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); diff --git a/examples/demo_qwen2_vl_npu.cpp b/examples/demo_showui_npu.cpp similarity index 100% rename from examples/demo_qwen2_vl_npu.cpp rename to examples/demo_showui_npu.cpp diff --git a/include/Types.hpp b/include/Types.hpp index 2bed483f8..78e7b127a 100644 --- a/include/Types.hpp +++ b/include/Types.hpp @@ -89,6 +89,7 @@ enum DataType { enum ChlType { BSHD = 0, + BHSD, BHDS = 2, BCTHW = 3, @@ -105,6 +106,7 @@ inline std::map, ChlType> Chls2Type = { {{0, 2, 3, 1}, BDHS}, {{0, 1, 3, 2}, BHDS}, {{0, 2, 1, 3}, BSHD}, + {{0, 1, 2, 3}, BHSD}, {{1, 2, 0, 3}, SBHD}, {{0, 3, 2, 1}, BDSH}, {{1, 2, 3, 0}, DBHS}, @@ -144,6 +146,12 @@ enum AttnQKVSplitType { SPLIT_D_HD = Chl::D_HD, }; +enum AttnPostQkvNormType { + PostQkv_NONE = 0, + PostQkv_LayerNorm, + PostQkv_RMSNorm, +}; + #define ANYDIM -198098 enum PaddingType { diff --git a/scripts/build_android.sh b/scripts/build_android.sh index 68e99a119..4e4a5391d 100755 --- a/scripts/build_android.sh +++ b/scripts/build_android.sh @@ -9,7 +9,7 @@ cmake .. \ -DANDROID_ABI="arm64-v8a" \ -DNATIVE_LIBRARY_OUTPUT=. -DNATIVE_INCLUDE_OUTPUT=. $1 $2 $3 \ -DANDROID_PLATFORM=android-34 \ --DCMAKE_CXX_FLAGS="-march=armv8.2-a+fp16+fp16fml+dotprod" \ +-DCMAKE_CXX_FLAGS="-march=armv8.2-a+fp16+fp16fml+dotprod+i8mm" \ -DDEBUG=OFF \ -DTEST=OFF \ -DARM=ON \ diff --git a/scripts/run_qwen2_vl.sh b/scripts/run_qwen2_vl.sh index b795db566..4f20b0317 100755 --- a/scripts/run_qwen2_vl.sh +++ b/scripts/run_qwen2_vl.sh @@ -4,6 +4,7 @@ adb shell mkdir /data/local/tmp/mllm adb shell mkdir /data/local/tmp/mllm/bin adb shell mkdir /data/local/tmp/mllm/models adb shell mkdir /data/local/tmp/mllm/vocab +adb shell mkdir /data/local/tmp/mllm/assets adb push ../vocab/* /data/local/tmp/mllm/vocab/ adb push ../assets/* /data/local/tmp/mllm/assets/ adb push ../bin-arm/demo_qwen2_vl /data/local/tmp/mllm/bin/ diff --git a/scripts/run_qwen2_vl_qnn.sh b/scripts/run_showui_qnn.sh similarity index 94% rename from scripts/run_qwen2_vl_qnn.sh rename to scripts/run_showui_qnn.sh index 0af243172..cb99dbd01 100755 --- a/scripts/run_qwen2_vl_qnn.sh +++ b/scripts/run_showui_qnn.sh @@ -48,5 +48,5 @@ if [ $? -ne 0 ]; then exit 1 fi # adb shell "rm /data/local/tmp/mllm/bin/qnn_context.bin" -adb push ../bin-arm-qnn/demo_qwen2_vl_npu /data/local/tmp/mllm/bin/ -adb shell "cd /data/local/tmp/mllm/bin && export LD_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && export ADSP_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && ./demo_qwen2_vl_npu" \ No newline at end of file +adb push ../bin-arm-qnn/demo_showui_npu /data/local/tmp/mllm/bin/ +adb shell "cd /data/local/tmp/mllm/bin && export LD_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && export ADSP_LIBRARY_PATH=/data/local/tmp/mllm/qnn-lib && ./demo_showui_npu" \ No newline at end of file diff --git a/src/Tensor.cpp b/src/Tensor.cpp index 40955d557..28bce496b 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -271,8 +271,14 @@ Tensor Tensor::transpose(vector> axiss) { axis_s.push_back((float)axis.first); axis_s.push_back((float)axis.second); } + bool in_place = (master_tensor_ == nullptr); + // for BSHD attention start + if(axiss.size() == 1 && axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { + in_place = false; // in-place transpose + } + // for BSHD attention end return runFunc({name() + "-transpose"}, FUNC_TRANPOSE, axis_s, - {std::shared_ptr(this, [](Tensor *) {})}, master_tensor_ == nullptr)[0]; + {std::shared_ptr(this, [](Tensor *) {})}, in_place)[0]; } Tensor Tensor::clip(vector b, vector h, vector s, vector d) { diff --git a/src/Tensor.hpp b/src/Tensor.hpp index c21518d59..de4ea9b17 100644 --- a/src/Tensor.hpp +++ b/src/Tensor.hpp @@ -71,6 +71,7 @@ class Tensor { // AggregatedTensor相关 bool aggregated_ = false; + bool allow_aggregated_ = true; // 是否不聚合,主要用于分割操作 vector> aggregated_tensors_; Tensor *deaggregated_tensor_ = nullptr; Chl aggregated_dim_; @@ -237,6 +238,8 @@ class Tensor { auto s_ = (s + shape_offset_[2]) % base_sequence_; auto d_ = (d + shape_offset_[3]) % base_dimension_; switch (impl_->ctype_) { + case BHSD: + return ((b_ * base_head_ + h_) * base_sequence_ + s_) * base_dimension_ + d_; case BSHD: return ((b_ * base_sequence_ + s_) * base_head_ + h_) * base_dimension_ + d_; case BHDS: @@ -252,6 +255,8 @@ class Tensor { } } else { switch (impl_->ctype_) { + case BHSD: + return ((b * impl_->shape_[1] + h) * impl_->shape_[2] + s) * impl_->shape_[3] + d; case BSHD: return ((b * impl_->shape_[1] + s) * impl_->shape_[2] + h) * impl_->shape_[3] + d; case BHDS: @@ -533,6 +538,12 @@ class Tensor { void setCtype(ChlType type) { impl_->ctype_ = type; switch (impl_->ctype_) { + case BHSD: + impl_->chls()[BATCH] = 0; + impl_->chls()[HEAD] = 1; + impl_->chls()[SEQUENCE] = 2; + impl_->chls()[DIMENSION] = 3; + break; case BSHD: impl_->chls()[BATCH] = 0; impl_->chls()[SEQUENCE] = 1; @@ -813,6 +824,7 @@ class Tensor { * \param head_rep the repeat number of heads of ChildTensor compared to MasterTensor. * used for repeat the head of K/V in Transformer-based LLMs. Default is 1. */ + /* void shallowCopyFrom(Tensor *source, bool copyshape = true, const vector &shape_offset = {}, int head_rep = 1) { if (!shape_offset.empty()) { copyshape = false; @@ -901,7 +913,9 @@ class Tensor { (uint64_t)shape_offset[1], (uint64_t)shape_offset[2], (uint64_t)shape_offset[3]}; - if (!std::equal(source->impl_->chls_.begin(), source->impl_->chls_.end(), impl_->chls_.begin()) && impl_->chls()[SEQUENCE] == source->impl_->chls()[DIMENSION] && source->impl_->chls()[SEQUENCE] == impl_->chls()[DIMENSION]) { + if (!std::equal(source->impl_->chls_.begin(), source->impl_->chls_.end(), impl_->chls_.begin()) + && impl_->chls()[SEQUENCE] == source->impl_->chls()[DIMENSION] + && source->impl_->chls()[SEQUENCE] == impl_->chls()[DIMENSION]) { shape_master_ = {(uint64_t)source->batch(), (uint64_t)source->head(), (uint64_t)source->dimension(), @@ -943,6 +957,54 @@ class Tensor { } source->addChildTensor(this); } + */ + /** + * @brief 使当前 Tensor 成为 source Tensor 的一个子 Tensor (Shallow Copy)。 + * 它不分配新内存,而是共享 source 的内存。 + * @param source 将要成为父 Tensor 的张量。 + * @param copyshape 如果为 true 且 shape_offset 为空,则直接复制 source 的形状。 + * @param shape_offset 定义子 Tensor 相对于父 Tensor 的维度偏移,用于创建切片(slice)。 + * @param head_rep 用于分组查询注意力(GQA),表示K/V头的重复次数。 + */ + void shallowCopyFrom(Tensor *source, bool copyshape = true, const vector &shape_offset = {}, int head_rep = 1) { + // 步骤 0: 初始设置 + // 如果提供了偏移量,则子张量有自己的独立形状,不应复制父张量的形状。 + if (!shape_offset.empty()) { + copyshape = false; + } + setMasterTensor(source); // 建立父子关系的第一步 + + // 步骤 1: 同步父子 Tensor 间的内存布局 (ctype) + // 这是原始代码中最复杂的部分,我们将其拆分到一个独立的辅助函数中。 + reconcileLayouts(source); + + // 步骤 2: 核心浅拷贝操作 - 共享数据指针和元数据 + impl_->host_ptr_ = source->hostPtr(); + impl_->owns_host_ptr_ = false; // 子 Tensor 不拥有内存所有权,不负责释放 + impl_->capacity_ = source->impl_->capacity_; + impl_->count_ = source->impl_->count_; + impl_->allocated_ = source->impl_->allocated_; + impl_->dtype_ = source->impl_->dtype_; + if (copyshape) { + impl_->shape_ = source->impl_->shape_; + } + + // 步骤 3: 处理切片(offset)和GQA逻辑 + if (!shape_offset.empty()) { + // 如果提供了 shape_offset,则当前 Tensor 是一个 "view" 或 "slice" + setupShapeForView(source, shape_offset, head_rep); + } + + // 步骤 4: 维护张量层级结构 (处理孙张量) + // 如果当前 Tensor 在此之前有自己的子 Tensor(即 source 的孙张量), + // 必须将这些孙张量重新“过继”给 source,成为 source 的直接子 Tensor。 + reparentChildTensors(source, shape_offset, head_rep); + + // 步骤 5: 在父 Tensor 中注册自己 + // 完成所有设置后,将当前 Tensor 正式添加到 source 的子张量列表中。 + source->addChildTensor(this); + } + void shallowCopyFrom(Tensor &source, bool copyshape = true, const vector &shape_offset = {}, int head_rep = 1) { shallowCopyFrom(&source, copyshape, shape_offset, head_rep); } @@ -1062,6 +1124,13 @@ class Tensor { vector> &aggregatedTensors() { return aggregated_tensors_; } + void removeAggregatedTensors() { + aggregated_tensors_.clear(); + aggregated_ = false; + aggregated_dim_ = BATCH; + aggregated_dims_.clear(); + deaggregated_tensor_ = nullptr; + } Tensor *deaggregatedTensor() const { return deaggregated_tensor_; } @@ -1173,6 +1242,175 @@ class Tensor { } private: + + + /** + * @brief (辅助函数) 处理父子 Tensor 之间的内存布局 (ctype) 同步。 + * 这段逻辑直接从原始的 shallowCopyFrom 中提取,保留了所有边缘情况的处理。 + * @param master_tensor 新的父 Tensor。 + */ + void reconcileLayouts(Tensor *master_tensor) { + // 情况 1: 通用的4D张量布局同步 (非5D视觉张量) + // 条件: 父子 ctype 不一致,且允许布局变化从子张量“扩散”到父张量。 + if (impl_->ctype_ != BCTHW && impl_->ctype_ != BTHWC + && impl_->ctype_ != master_tensor->ctype() && !impl_->undiffusion_) { + if (impl_->transed_) { // 如果子张量(this)已被转置,则强制父张量跟随子的布局 + auto b = master_tensor->batch(); + auto h = master_tensor->head(); + auto d = master_tensor->dimension(); + auto s = master_tensor->sequence(); + master_tensor->impl_->ctype_ = impl_->ctype_; + master_tensor->impl_->chls_ = impl_->chls_; + master_tensor->reshape(b, h, s, d); + } else { // 否则,子张量跟随父张量的布局 + auto b = batch(); + auto h = head(); + auto d = dimension(); + auto s = sequence(); + impl_->ctype_ = master_tensor->impl_->ctype_; + impl_->chls_ = master_tensor->impl_->chls_; + reshape(b, h, s, d); + } + } + // 情况 2: 处理三层张量结构中的布局冲突 (祖父 -> this -> 孙子) + // 条件: this 只有一个子节点,且该子节点与新的父节点(master_tensor)布局相同,但 this 与它们不同。 + else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == master_tensor->impl_->ctype_ + && ctype() != master_tensor->impl_->ctype_) { + auto b = child_tensors_[0]->batch(); + auto h = child_tensors_[0]->head(); + auto s = child_tensors_[0]->sequence(); + auto d = child_tensors_[0]->dimension(); + + // 将 this 和其子节点的布局统一为 master_tensor 的布局 + impl_->chls_ = master_tensor->impl_->chls_; + child_tensors_[0]->impl_->chls_ = master_tensor->impl_->chls_; + + // 逆向应用之前记录的变换,以恢复到正确的逻辑形状 + for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { + auto tf = impl_->trans_from_[i]; + auto axis0 = tf.first; + auto axis1 = tf.second; + // 交换 chls_ 中的维度索引 + std::swap(child_tensors_[0]->impl_->chls()[axis0], child_tensors_[0]->impl_->chls()[axis1]); + } + changeCtype(); // 根据 chls_ 更新 ctype + child_tensors_[0]->changeCtype(); + child_tensors_[0]->reshape(b, h, s, d); + transCopyShape(child_tensors_[0]->shape()); + } + // 情况 3: 处理从4D (LLM) 到5D (Vision) 张量的特殊布局转换 + // 条件: this 的子节点是5D (BCTHW),新的父节点是4D (BSHD),而 this 不是 BCTHW。 + else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == BCTHW + && master_tensor->impl_->ctype_ == BSHD && ctype() != BCTHW) { + auto b = child_tensors_[0]->batch(); + auto c = child_tensors_[0]->channel(); + auto t = child_tensors_[0]->time(); + auto h = child_tensors_[0]->height(); + auto w = child_tensors_[0]->width(); + + // 强制重置为标准的5D布局 + impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; + child_tensors_[0]->impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; + + // 同样,逆向应用变换 + for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { + auto tf = impl_->trans_from_[i]; + std::swap(child_tensors_[0]->impl_->chls()[tf.first], child_tensors_[0]->impl_->chls()[tf.second]); + } + changeCtype(); + child_tensors_[0]->changeCtype(); + child_tensors_[0]->reshape(b, c, t, h, w); + transCopyShape(child_tensors_[0]->shape()); + } + } + + + /** + * @brief (辅助函数) 为作为 "View" 的子 Tensor 设置形状和偏移信息。 + * @param source 父 Tensor + * @param shape_offset 维度偏移 + * @param head_rep GQA 的头重复次数 + */ + void setupShapeForView(Tensor *source, const vector &shape_offset, int head_rep) { + // 记录父张量的原始维度,用于后续计算 offset + shape_master_ = {(uint64_t)source->batch(), (uint64_t)source->head(), + (uint64_t)source->sequence(), (uint64_t)source->dimension()}; + shape_offset_ = {(uint64_t)shape_offset[0], (uint64_t)shape_offset[1], + (uint64_t)shape_offset[2], (uint64_t)shape_offset[3]}; + + // 如果父子布局转置了 (例如 BSHD vs BHDS), 需要同步调整 shape_master_ 和 shape_offset_ 的记录顺序 + if (!std::equal(source->impl_->chls_.begin(), source->impl_->chls_.end(), impl_->chls_.begin()) + && impl_->chls_[SEQUENCE] == source->impl_->chls_[DIMENSION] + && source->impl_->chls_[SEQUENCE] == impl_->chls_[DIMENSION]) { + std::swap(shape_master_[2], shape_master_[3]); // 交换 sequence 和 dimension + std::swap(shape_offset_[2], shape_offset_[3]); + } + + // 特殊处理 GQA (Grouped-Query Attention) + // 当子张量的头数量与父张量不同时,通常意味着 K/V cache 的共享。 + // 我们需要调整 shape_master_ 的 dimension 来反映这一点,确保偏移计算正确。 + if (source->head() != head()) { + if (head() == 1 && head_rep == 1) { // 可能是 MQA (Multi-Query Attention) + shape_master_ = {(uint64_t)source->batch(), (uint64_t)head(), (uint64_t)source->sequence(), (uint64_t)source->dimension() * source->head() / head()}; + } else if (head() == 1 && head_rep > 1) { // GQA + shape_master_ = {(uint64_t)source->batch(), (uint64_t)head(), (uint64_t)source->sequence(), (uint64_t)source->dimension() * source->head() / head_rep}; + } + } + } + + + /** + * @brief (辅助函数) 重新指定当前 Tensor 的子 Tensor (孙张量) 的父节点。 + * 将它们从 this 的子节点变为 source 的直接子节点。 + * @param source 新的父(祖父)节点 + * @param shape_offset + * @param head_rep + */ + void reparentChildTensors(Tensor* source, const vector& shape_offset, int head_rep) { + auto it = child_tensors_.begin(); + while (it != child_tensors_.end()) { + auto &child_tensor = *it; + + // 1. 先计算出最终要传递的 offset + vector final_offset; + auto origin_shape_offset = child_tensor->shapeOffset(); + if (!origin_shape_offset.empty()) { + final_offset = origin_shape_offset; + // ...应用那个奇怪的索引[2]的逻辑... + } else if (!shape_offset.empty()) { + final_offset = shape_offset; + } + + // 2. 只调用一次 + child_tensor->shallowCopyFrom(source, false, final_offset, head_rep); + + it = child_tensors_.erase(it); + } + } + // void reparentChildTensors(Tensor* source, const vector& shape_offset, int head_rep) { + // auto it = child_tensors_.begin(); + // while (it != child_tensors_.end()) { + // auto &child_tensor = *it; + // auto origin_shape_offset = child_tensor->shapeOffset(); + + // // 递归调用,将孙张量直接挂到新的祖父 source 下 + // if (!origin_shape_offset.empty()) { + // if (!shape_offset.empty()) { + // origin_shape_offset[2] = shape_offset[2]; // 这个逻辑比较特殊,保留原始行为 + // } + // child_tensor->shallowCopyFrom(source, false, origin_shape_offset, head_rep); + // } else if (!shape_offset.empty()) { + // child_tensor->shallowCopyFrom(source, false, shape_offset, head_rep); + // } else { + // child_tensor->shallowCopyFrom(source, false, {}, head_rep); + // } + + // // 从 this 的子节点列表中移除,因为它已经被“过继”了 + // it = child_tensors_.erase(it); + // } + // } + + int checkDim(int &b, int &h, int &s, int &d) { if (!aggregated_) { return -1; @@ -1302,6 +1540,10 @@ class Tensor { TensorType &xnnTensorType(); + bool &allowAggregated() { + return allow_aggregated_; + } + void forceResetHostPointer(void *ptr); float i8_scale = 1.f; @@ -1864,6 +2106,9 @@ class Tensor { void printCtype() { std::string ctype; switch (impl_->ctype_) { + case BHSD: + ctype = "BHSD"; + break; case BSHD: ctype = "BSHD"; break; diff --git a/src/backends/cpu/CMakeLists.txt b/src/backends/cpu/CMakeLists.txt index 0134c36b3..cb742ec4f 100644 --- a/src/backends/cpu/CMakeLists.txt +++ b/src/backends/cpu/CMakeLists.txt @@ -30,6 +30,8 @@ if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES set(KLEIDIAI_SOURCES_QSI4 ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod_asm.S + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm_asm.S ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.c ) @@ -96,13 +98,13 @@ endif() if(${MLLM_ENABLE_PYTHON}) add_library( - lib_mllm_cpu + mllm_cpu SHARED ${MLLM_CPU_SRC} ) else() add_library( - lib_mllm_cpu + mllm_cpu OBJECT ${MLLM_CPU_SRC} ) @@ -110,15 +112,15 @@ endif() # Conditionally add kleidiai compile definitions for ARM if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") - target_compile_definitions(lib_mllm_cpu PUBLIC KLAI_USE_QSI4_C32) - target_compile_definitions(lib_mllm_cpu PUBLIC KLAI_USE_FP16) - target_compile_definitions(lib_mllm_cpu PUBLIC KLAI_USE_FP32) + target_compile_definitions(mllm_cpu PUBLIC KLAI_USE_QSI4_C32) + target_compile_definitions(mllm_cpu PUBLIC KLAI_USE_FP16) + target_compile_definitions(mllm_cpu PUBLIC KLAI_USE_FP32) endif() # 包含头文件目录 list(REMOVE_DUPLICATES ALL_KLEIDIAI_INCLUDE_DIRS) target_include_directories( - lib_mllm_cpu + mllm_cpu PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${ALL_KLEIDIAI_INCLUDE_DIRS} @@ -128,21 +130,21 @@ if(OpenMP_FOUND) message(STATUS "found openmp") if(ARM AND NOT APK) message(STATUS "[ARM] found openmp") - target_compile_options(lib_mllm_cpu PUBLIC -fopenmp) + target_compile_options(mllm_cpu PUBLIC -fopenmp) # tmac or for mac if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING) - target_link_libraries(lib_mllm_cpu PUBLIC OpenMP::OpenMP_CXX) + target_link_libraries(mllm_cpu PUBLIC OpenMP::OpenMP_CXX) else() - target_link_libraries(lib_mllm_cpu PUBLIC -fopenmp -static-openmp) + target_link_libraries(mllm_cpu PUBLIC -fopenmp -static-openmp) endif () else() - target_link_libraries(lib_mllm_cpu + target_link_libraries(mllm_cpu PUBLIC OpenMP::OpenMP_CXX ) endif() endif() -target_link_libraries(lib_mllm_cpu PUBLIC fmt::fmt-header-only) +target_link_libraries(mllm_cpu PUBLIC fmt::fmt-header-only) -set_target_properties(lib_mllm_cpu PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) \ No newline at end of file +set_target_properties(mllm_cpu PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) \ No newline at end of file diff --git a/src/backends/cpu/CPUBackend.cpp b/src/backends/cpu/CPUBackend.cpp index 712bfe60c..c4e4dec70 100644 --- a/src/backends/cpu/CPUBackend.cpp +++ b/src/backends/cpu/CPUBackend.cpp @@ -310,57 +310,81 @@ std::vector CPUBackend::runFunc( if (activation_tensors.find(out_tensor->name()) != activation_tensors.end() && !activation_tensors[out_tensor->name()]->aggregatedTensors().empty()) { // 存在aggregatedTensors - vector> shared_outputs = {}; - auto split_dim = activation_tensors[out_tensor->name()]->aggregatedDim(); - for (int id = 0; id < activation_tensors[out_tensor->name()]->aggregatedTensors().size(); id++) { - auto shared_ot = std::make_shared(backend); - shared_ot->setName(out_tensor->name() + ".split-" + std::to_string(id)); - shared_ot->setModule(module); - auto ot = activation_tensors[out_tensor->name()]->aggregatedTensors()[id]; - shared_ot->setCtype(ot->ctype()); - switch (split_dim) { - case Chl::HEAD: { - shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), out_tensor->dimension()); - break; - } - case Chl::SEQUENCE: { - shared_ot->reshape(out_tensor->batch(), out_tensor->head(), ot->sequence(), out_tensor->dimension()); - break; - } - case Chl::DIMENSION: { - shared_ot->reshape(out_tensor->batch(), out_tensor->head(), out_tensor->sequence(), ot->dimension()); - break; - } - case Chl::D_HD: - case Chl::HD: { - shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), ot->dimension()); - break; - } - default: { - break; - } + + bool remove_f = true; + if (activation_tensors[out_tensor->name()]->aggregatedDim() > 3) { + remove_f = false; // 不能移除 + } else { + for (auto &agtensor : activation_tensors[out_tensor->name()]->aggregatedTensors()) { + bool check_m = (agtensor->masterTensor() != nullptr + && agtensor->masterTensor()->name().find("Cache") != std::string::npos); + if (agtensor->ctype() != activation_tensors[out_tensor->name()]->aggregatedTensors()[0]->ctype()) { + remove_f = false; + } else if (check_m) { + remove_f = false; + } } - if (activation_tensors[shared_ot->name()]->masterTensor() != nullptr - && activation_tensors[shared_ot->name()]->masterTensor()->name().find("Cache") != std::string::npos) { - auto cache_seq_len_ = activation_tensors[shared_ot->name()]->shapeOffset()[2]; - if (shared_ot->name().find("cache") == std::string::npos) { // KVcahe的输出不设置,只有输入设置 - cache_seq_len_ = activation_tensors[shared_ot->name()]->masterTensor()->cache_seq_len_; - auto cpuBackend = dynamic_cast(backend); - if (cpuBackend->isUsingDraft()) { - unsigned int last_draft_length = cpuBackend->getLastDraftLength(); - const std::vector &last_verified_position_ids = cpuBackend->getLastVerifiedPositionIds(); - cache_seq_len_ = cache_seq_len_ - (last_draft_length) + last_verified_position_ids.size(); + } + // if (remove_f) { + // inputs[0]->removeAggregatedTensors(); + // inputs[0]->allowAggregated() = false; + // } + if (!remove_f) { + vector> shared_outputs = {}; + auto split_dim = activation_tensors[out_tensor->name()]->aggregatedDim(); + for (int id = 0; id < activation_tensors[out_tensor->name()]->aggregatedTensors().size(); id++) { + auto shared_ot = std::make_shared(backend); + shared_ot->setName(out_tensor->name() + ".split-" + std::to_string(id)); + shared_ot->setModule(module); + auto ot = activation_tensors[out_tensor->name()]->aggregatedTensors()[id]; + shared_ot->setCtype(ot->ctype()); + switch (split_dim) { + case Chl::HEAD: { + shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), out_tensor->dimension()); + break; + } + case Chl::SEQUENCE: { + shared_ot->reshape(out_tensor->batch(), out_tensor->head(), ot->sequence(), out_tensor->dimension()); + break; + } + case Chl::DIMENSION: { + shared_ot->reshape(out_tensor->batch(), out_tensor->head(), out_tensor->sequence(), ot->dimension()); + break; + } + case Chl::D_HD: + case Chl::HD: { + shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), ot->dimension()); + break; + } + default: { + break; + } + } + if (activation_tensors[shared_ot->name()]->masterTensor() != nullptr + && activation_tensors[shared_ot->name()]->masterTensor()->name().find("Cache") != std::string::npos) { + auto cache_seq_len_ = activation_tensors[shared_ot->name()]->shapeOffset()[2]; + if (shared_ot->name().find("cache") == std::string::npos) { // KVcahe的输出不设置,只有输入设置 + cache_seq_len_ = activation_tensors[shared_ot->name()]->masterTensor()->cache_seq_len_; + auto cpuBackend = dynamic_cast(backend); + if (cpuBackend->isUsingDraft()) { + unsigned int last_draft_length = cpuBackend->getLastDraftLength(); + const std::vector &last_verified_position_ids = cpuBackend->getLastVerifiedPositionIds(); + cache_seq_len_ = cache_seq_len_ - (last_draft_length) + last_verified_position_ids.size(); + } } + shared_ot->setDtype(activation_tensors[shared_ot->name()]->masterTensor()->dtype()); + // masterTensor() 是Cache所以shape没有问题 + shared_ot->shallowCopyFrom(activation_tensors[shared_ot->name()]->masterTensor(), false, {0, 0, cache_seq_len_, 0}); + } else { + shared_ot->alloc(); } - shared_ot->setDtype(activation_tensors[shared_ot->name()]->masterTensor()->dtype()); - // masterTensor() 是Cache所以shape没有问题 - shared_ot->shallowCopyFrom(activation_tensors[shared_ot->name()]->masterTensor(), false, {0, 0, cache_seq_len_, 0}); - } else { - shared_ot->alloc(); + shared_outputs.push_back(shared_ot); } - shared_outputs.push_back(shared_ot); + out_tensor->addTensors(shared_outputs, split_dim); + } else { + out_tensor->allowAggregated() = false; + out_tensor->alloc(); } - out_tensor->addTensors(shared_outputs, split_dim); } else if (activation_tensors.find(out_tensor->name()) != activation_tensors.end() && activation_tensors[out_tensor->name()]->masterTensor() != nullptr && activation_tensors[out_tensor->name()]->masterTensor()->name().find("Cache") != std::string::npos) { @@ -478,57 +502,76 @@ std::vector CPUBackend::runLayer(Layer *layer, std::vector input if (activation_tensors.find(out_tensor->name()) != activation_tensors.end() && !activation_tensors[out_tensor->name()]->aggregatedTensors().empty()) { // 存在aggregatedTensors - vector> shared_outputs = {}; - auto split_dim = activation_tensors[out_tensor->name()]->aggregatedDim(); - for (int id = 0; id < activation_tensors[out_tensor->name()]->aggregatedTensors().size(); id++) { - auto shared_ot = std::make_shared(layer->backend_); - shared_ot->setName(out_tensor->name() + ".split-" + std::to_string(id)); - shared_ot->setModule(module); - auto ot = activation_tensors[out_tensor->name()]->aggregatedTensors()[id]; - shared_ot->setCtype(ot->ctype()); - switch (split_dim) { - case Chl::HEAD: { - shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), out_tensor->dimension()); - break; - } - case Chl::SEQUENCE: { - shared_ot->reshape(out_tensor->batch(), out_tensor->head(), ot->sequence(), out_tensor->dimension()); - break; - } - case Chl::DIMENSION: { - shared_ot->reshape(out_tensor->batch(), out_tensor->head(), out_tensor->sequence(), ot->dimension()); - break; - } - case Chl::D_HD: - case Chl::HD: { - shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), ot->dimension()); - break; - } - default: { - break; - } + bool remove_f = true; + if (activation_tensors[out_tensor->name()]->aggregatedDim() > 3) { + remove_f = false; // 不能移除 + } else { + for (auto &agtensor : activation_tensors[out_tensor->name()]->aggregatedTensors()) { + bool check_m = (agtensor->masterTensor() != nullptr + && agtensor->masterTensor()->name().find("Cache") != std::string::npos); + if (agtensor->ctype() != activation_tensors[out_tensor->name()]->aggregatedTensors()[0]->ctype()) { + remove_f = false; + } else if (check_m) { + remove_f = false; + } } - if (activation_tensors[shared_ot->name()]->masterTensor() != nullptr - && activation_tensors[shared_ot->name()]->masterTensor()->name().find("Cache") != std::string::npos) { - auto cache_seq_len_ = activation_tensors[shared_ot->name()]->shapeOffset()[2]; - if (shared_ot->name().find("cache") == std::string::npos) { // KVcahe的输出不设置,只有输入设置 - cache_seq_len_ = activation_tensors[shared_ot->name()]->masterTensor()->cache_seq_len_; - auto cpuBackend = dynamic_cast(layer->backend_); - if (cpuBackend->isUsingDraft()) { - unsigned int last_draft_length = cpuBackend->getLastDraftLength(); - const std::vector &last_verified_position_ids = cpuBackend->getLastVerifiedPositionIds(); - cache_seq_len_ = cache_seq_len_ - (last_draft_length) + last_verified_position_ids.size(); + } + if (!remove_f) { + vector> shared_outputs = {}; + auto split_dim = activation_tensors[out_tensor->name()]->aggregatedDim(); + for (int id = 0; id < activation_tensors[out_tensor->name()]->aggregatedTensors().size(); id++) { + auto shared_ot = std::make_shared(layer->backend_); + shared_ot->setName(out_tensor->name() + ".split-" + std::to_string(id)); + shared_ot->setModule(module); + auto ot = activation_tensors[out_tensor->name()]->aggregatedTensors()[id]; + shared_ot->setCtype(ot->ctype()); + switch (split_dim) { + case Chl::HEAD: { + shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), out_tensor->dimension()); + break; + } + case Chl::SEQUENCE: { + shared_ot->reshape(out_tensor->batch(), out_tensor->head(), ot->sequence(), out_tensor->dimension()); + break; + } + case Chl::DIMENSION: { + shared_ot->reshape(out_tensor->batch(), out_tensor->head(), out_tensor->sequence(), ot->dimension()); + break; + } + case Chl::D_HD: + case Chl::HD: { + shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), ot->dimension()); + break; + } + default: { + break; + } + } + if (activation_tensors[shared_ot->name()]->masterTensor() != nullptr + && activation_tensors[shared_ot->name()]->masterTensor()->name().find("Cache") != std::string::npos) { + auto cache_seq_len_ = activation_tensors[shared_ot->name()]->shapeOffset()[2]; + if (shared_ot->name().find("cache") == std::string::npos) { // KVcahe的输出不设置,只有输入设置 + cache_seq_len_ = activation_tensors[shared_ot->name()]->masterTensor()->cache_seq_len_; + auto cpuBackend = dynamic_cast(layer->backend_); + if (cpuBackend->isUsingDraft()) { + unsigned int last_draft_length = cpuBackend->getLastDraftLength(); + const std::vector &last_verified_position_ids = cpuBackend->getLastVerifiedPositionIds(); + cache_seq_len_ = cache_seq_len_ - (last_draft_length) + last_verified_position_ids.size(); + } } + shared_ot->setDtype(activation_tensors[shared_ot->name()]->masterTensor()->dtype()); + // masterTensor() 是Cache所以shape没有问题 + shared_ot->shallowCopyFrom(activation_tensors[shared_ot->name()]->masterTensor(), false, {0, 0, cache_seq_len_, 0}); + } else { + shared_ot->alloc(); } - shared_ot->setDtype(activation_tensors[shared_ot->name()]->masterTensor()->dtype()); - // masterTensor() 是Cache所以shape没有问题 - shared_ot->shallowCopyFrom(activation_tensors[shared_ot->name()]->masterTensor(), false, {0, 0, cache_seq_len_, 0}); - } else { - shared_ot->alloc(); + shared_outputs.push_back(shared_ot); } - shared_outputs.push_back(shared_ot); + out_tensor->addTensors(shared_outputs, split_dim); + } else { + out_tensor->allowAggregated() = false; + out_tensor->alloc(); } - out_tensor->addTensors(shared_outputs, split_dim); } else if (activation_tensors.find(out_tensor->name()) != activation_tensors.end() && activation_tensors[out_tensor->name()]->masterTensor() != nullptr && activation_tensors[out_tensor->name()]->masterTensor()->name().find("Cache") != std::string::npos) { diff --git a/src/backends/cpu/compute/FeatureCheck.hpp b/src/backends/cpu/compute/FeatureCheck.hpp new file mode 100644 index 000000000..7f2e0838b --- /dev/null +++ b/src/backends/cpu/compute/FeatureCheck.hpp @@ -0,0 +1,78 @@ + +#if defined(__linux__) +#include +// #if defined(__aarch64__) && !defined(HWCAP_I8MM) +#include // 确保定义 HWCAP_I8MM +// #endif +#elif defined(__APPLE__) +#include +#include +#endif + +#include +#include +#include +#include + +#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) +// 读取 ID_AA64ISAR1_EL1 寄存器 +static inline uint64_t read_id_aa64isar1_el1() { + uint64_t value; + asm volatile("mrs %0, ID_AA64ISAR1_EL1" : "=r"(value)); + return value; +} +#endif + +static bool arm_is_i8mm_supported() { + // std::cout << "Starting i8mm detection..." << std::endl; + + // 1. macOS 专用检测(不受影响) +#if defined(__APPLE__) && defined(__aarch64__) + // std::cout << "Using macOS sysctl detection" << std::endl; + int supported = 0; + size_t size = sizeof(supported); + const int result = sysctlbyname("hw.optional.arm.FEAT_I8MM", + &supported, &size, NULL, 0); + if (result == 0 && supported) { + // std::cout << "sysctl detection: I8MM supported!" << std::endl; + return true; + } + // std::cerr << "sysctl detection " + // << (result ? "failed" : "I8MM not supported") << std::endl; +#endif + + // 2. 优先使用 CPU 寄存器检测(ARM64通用) +#if defined(__aarch64__) && (defined(__GNUC__) || defined(__clang__)) + // std::cout << "Using ARM64 register detection method" << std::endl; + const uint64_t isar1 = read_id_aa64isar1_el1(); + const uint8_t i8mm_field = (isar1 >> 52) & 0xF; // 位52-55 + // std::cout << "ID_AA64ISAR1_EL1 = 0x" << std::hex << isar1 << std::dec << ", I8MM field = " << static_cast(i8mm_field) << std::endl; + // 值1或2表示支持i8mm + if (i8mm_field == 1 || i8mm_field == 2) { + // std::cout << "Register detection: I8MM supported!" << std::endl; + return true; + } + // std::cout << "Register detection: I8MM not supported" << std::endl; +#endif + +// 3. /proc/cpuinfo 后备检测 +#if defined(__linux__) + // std::cout << "Using /proc/cpuinfo detection" << std::endl; + FILE *cpuinfo = fopen("/proc/cpuinfo", "r"); + if (cpuinfo) { + char line[512]; + while (fgets(line, sizeof(line), cpuinfo)) { + // 检查包含"Features"的行 + if (strstr(line, "Features") && strstr(line, "i8mm")) { + fclose(cpuinfo); + // std::cout << "CPUinfo detection: I8MM supported!" << std::endl; + return true; + } + } + fclose(cpuinfo); + } + // std::cout << "CPUinfo detection: I8MM not found or file access failed" << std::endl; +#endif + // std::cout << "No I8MM support detected" << std::endl; + return false; +} diff --git a/src/backends/cpu/compute/FlashAttention2.hpp b/src/backends/cpu/compute/FlashAttention2.hpp index ee10fc3ff..027d6edf3 100644 --- a/src/backends/cpu/compute/FlashAttention2.hpp +++ b/src/backends/cpu/compute/FlashAttention2.hpp @@ -2519,6 +2519,7 @@ struct NEON_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } + /* // 输入Q为FP32,但在函数内动态转为FP16,以使用最高效的 vfmlalq_f16 指令进行计算 inline void mma0(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, @@ -2604,6 +2605,78 @@ struct NEON_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } + */ + // 【最终正确优化版】 + // 核心思路: + // 1. 在处理每一行Q (b_r_idx) 时,先将其从 FP32 一次性完整转换为 FP16,并存入一个临时缓冲区 q_f16_buf。 + // 2. 在内层循环 (b_c_idx) 中,重复使用这个转换好的 q_f16_buf。 + // 3. 这样就将转换开销均摊,使得内层循环可以零开销地、最高效地执行 FP16 * FP16 -> FP32 的乘加运算。 + inline void mma0(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t q_stride_size, const int32_t kv_stride_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + + __fp16 q_f16_buf[dim_size]; + + + for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + const dtype_q_in_t *q_block_line = q_block + b_r_idx * q_stride_size; + + int k = 0; + for (; k <= dim_size - 8; k += 8) { + float32x4_t q_f32_0 = vld1q_f32(q_block_line + k); + float32x4_t q_f32_1 = vld1q_f32(q_block_line + k + 4); + float16x8_t q_f16 = vcombine_f16(vcvt_f16_f32(q_f32_0), vcvt_f16_f32(q_f32_1)); + vst1q_f16(q_f16_buf + k, q_f16); + } + for (; k < dim_size; ++k) { + q_f16_buf[k] = (__fp16)q_block_line[k]; + } + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum0 = vdupq_n_f32(0.0f); + float32x4_t sum1 = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 16; i += 16) { + float16x8_t q_f16_0 = vld1q_f16(q_f16_buf + i); + float16x8_t q_f16_1 = vld1q_f16(q_f16_buf + i + 8); + float16x8_t k_f16_0 = vld1q_f16((const __fp16 *)k_block_line + i); + float16x8_t k_f16_1 = vld1q_f16((const __fp16 *)k_block_line + i + 8); + sum0 = vfmlalq_low_f16(sum0, q_f16_0, k_f16_0); + sum0 = vfmlalq_high_f16(sum0, q_f16_0, k_f16_0); + sum1 = vfmlalq_low_f16(sum1, q_f16_1, k_f16_1); + sum1 = vfmlalq_high_f16(sum1, q_f16_1, k_f16_1); + } + sum0 = vaddq_f32(sum0, sum1); + if (i <= dim_size - 8) { + float16x8_t q_f16 = vld1q_f16(q_f16_buf + i); + float16x8_t k_f16 = vld1q_f16((const __fp16 *)k_block_line + i); + sum0 = vfmlalq_low_f16(sum0, q_f16, k_f16); + sum0 = vfmlalq_high_f16(sum0, q_f16, k_f16); + i += 8; + } + acc_dtype_t total = vaddvq_f32(sum0); + for (; i < dim_size; ++i) { + total += (float)q_f16_buf[i] * (float)k_block_line[i]; + } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { + for (int i = 0; i < Br; ++i) { + for (int j = 0; j < Bc; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } + } // (与FP32版本相同) inline void softmax(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, @@ -2657,7 +2730,7 @@ struct NEON_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } - // (混合精度修改版) + /* inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, @@ -2679,7 +2752,45 @@ struct NEON_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } + */ + inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + + const int32_t v_stride_size = kv_head_size * dim_size; + // 循环结构 (Br, dim_size, Bc) 对 acc_o 的读写更友好 + for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 4) { + // 加载128位的FP32累加器 + float32x4_t acc_vec = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + // 从w_block直接读取FP32的P标量 + const float p_scalar_f32 = w_block[b_r_idx * Bc + b_c_idx]; + // 将FP32标量广播为一个128位向量 + const float32x4_t p_vec_f32 = vdupq_n_f32(p_scalar_f32); + + // 加载FP16的V向量 + const __fp16 *v_ptr = (const __fp16 *)v_block + b_c_idx * v_stride_size + d_base; + const float16x4_t v_vec_f16 = vld1_f16(v_ptr); + + // 将V向量从FP16转换为FP32 + const float32x4_t v_vec_f32 = vcvt_f32_f16(v_vec_f16); + + // 执行FP32的融合乘加 + acc_vec = vfmaq_f32(acc_vec, p_vec_f32, v_vec_f32); + } + // 将结果写回内存 + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc_vec); + } + } + } // (与FP32版本相同) inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, diff --git a/src/backends/cpu/compute/FlashAttention2H.hpp b/src/backends/cpu/compute/FlashAttention2H.hpp new file mode 100644 index 000000000..c4f75f1c8 --- /dev/null +++ b/src/backends/cpu/compute/FlashAttention2H.hpp @@ -0,0 +1,1054 @@ +#ifndef MLLM_FA2H_CAL_HPP +#define MLLM_FA2H_CAL_HPP + +#include +#include +#include +#include +#include +#include +#include "Types.hpp" +#include "VecDot.hpp" + +// 平台相关的头文件和宏定义 +#ifdef __AVX2__ +#include +#define NEG_INF_F32 (-std::numeric_limits::infinity()) + +// Horizontal max of a __m256 vector +inline float hmax_ps_avx(__m256 x) { + __m128 lo = _mm256_castps256_ps128(x); + __m128 hi = _mm256_extractf128_ps(x, 1); + __m128 max_val = _mm_max_ps(lo, hi); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 2, 2))); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 0, 1))); + return _mm_cvtss_f32(max_val); +} + +// Horizontal sum of a __m256 vector +inline float hadd_ps_avx(__m256 x) { + __m128 lo = _mm256_castps256_ps128(x); + __m128 hi = _mm256_extractf128_ps(x, 1); + __m128 sum = _mm_add_ps(lo, hi); + sum = _mm_hadd_ps(sum, sum); + sum = _mm_hadd_ps(sum, sum); + return _mm_cvtss_f32(sum); +} + +#elif __ARM_NEON +#include +#define NEG_INF_F32 (-std::numeric_limits::infinity()) + +// NEON版本:水平最大值 (Horizontal max of a float32x4_t vector) +inline float hmax_ps_neon(float32x4_t x) { + return vmaxvq_f32(x); +} + +// NEON版本:水平求和 (Horizontal sum of a float32x4_t vector) +inline float hadd_ps_neon(float32x4_t x) { + return vaddvq_f32(x); +} + +#else +#error "Unsupported architecture. Please define __AVX2__ or __ARM_NEON." +#endif + +// Common aligned allocation/free functions +inline void platform_aligned_alloc(void **ptr, size_t required_bytes, size_t align) { + if (align % sizeof(void *) != 0 || (align & (align - 1)) != 0) { + *ptr = nullptr; + return; + } + if (posix_memalign(ptr, align, required_bytes) != 0) { + *ptr = nullptr; + } +} + +inline void platform_aligned_free(void *ptr) { + free(ptr); +} + + +namespace mobi_attn { + +// ======================================== +// FlashAttention2 核心实现 (FP32版本) - BHSD Layout +// ======================================== +struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { + using dtype_q_in_t = float; + using dtype_kv_in_t = dtype_q_in_t; + using dtype_out_t = dtype_q_in_t; + using dtype_t = dtype_out_t; + using acc_dtype_t = float; + + int32_t Br; + int32_t Bc; + int32_t Q_Head; + int32_t KV_Head; + int32_t threads; + bool high_precision; + + // Workspace pointers + acc_dtype_t *acc_o_; + acc_dtype_t *acc_s_; + acc_dtype_t *logsum_; + acc_dtype_t *scoremax_; + acc_dtype_t *scoremax_prev_; + acc_dtype_t *score_scale_; + acc_dtype_t *score_sum_; + + void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_, bool high_precision_) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_Head_; + KV_Head = KV_Head_; + threads = threads_; + high_precision = high_precision_; + } + + void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, + acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum) { + acc_o_ = acc_o; + acc_s_ = acc_s; + logsum_ = logsum; + scoremax_ = scoremax; + scoremax_prev_ = scoremax_prev; + score_scale_ = score_scale; + score_sum_ = score_sum; + } + + void fa2(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, const int32_t batch_size, + const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask, + int32_t q_head_skp, int32_t k_head_skp, int32_t v_head_skp) { + assert(Br == Bc); + assert(Q_Head % KV_Head == 0); + assert(head_size % threads == 0); + #ifdef __AVX2__ + assert(dim_size % 8 == 0); + #elif __ARM_NEON + assert(dim_size % 4 == 0); + #endif + + if (seq_size_q != 1) { + __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, q_head_skp, k_head_skp, v_head_skp); + } else { + __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, q_head_skp, k_head_skp, v_head_skp); + } + } + +private: + inline void __fa2_prefill_append(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask, + int32_t q_head_skp, int32_t k_head_skp, int32_t v_head_skp) { + const int32_t Tr = (seq_size_q + Br - 1) / Br; + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = Q_Head / KV_Head; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + const dtype_t *q_batch_base = Q + b_idx * head_size * q_head_skp; + const dtype_t *k_batch_base = K + b_idx * KV_Head * k_head_skp; + const dtype_t *v_batch_base = V + b_idx * KV_Head * v_head_skp; + dtype_t *o_batch_base = O + b_idx * head_size * q_head_skp; + + for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { + const int32_t Br_n_fixed = (t_r_idx == Tr - 1) ? (seq_size_q - t_r_idx * Br) : Br; + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, + acc_o_ + thread_id * Br * dim_size, Br_n_fixed, dim_size); + + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const int32_t Bc_n_fixed = (t_c_idx == Tc - 1) ? (seq_size_k - t_c_idx * Bc) : Bc; + + const dtype_t *tile_q = q_batch_base + this_thread_head * q_head_skp + t_r_idx * Br * dim_size; + const dtype_t *tile_k = k_batch_base + this_thread_kv_head * k_head_skp + t_c_idx * Bc * dim_size; + const dtype_t *tile_v = v_batch_base + this_thread_kv_head * v_head_skp + t_c_idx * Bc * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + + mma0(Br_n_fixed, Bc_n_fixed, tile_q, tile_k, tile_acc_s, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax(Br_n_fixed, Bc_n_fixed, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale); + rescale(Br_n_fixed, acc_o, score_scale_ + thread_id * Br, dim_size); + mma1(Br_n_fixed, Bc_n_fixed, tile_acc_s, tile_v, acc_o, dim_size); + } + + dtype_t* o_block_ptr = o_batch_base + this_thread_head * q_head_skp + t_r_idx * Br * dim_size; + scale_and_store(Br_n_fixed, acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, o_block_ptr, dim_size); + } + } + } + } + + inline void __fa2_decode(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask, + int32_t q_head_skp, int32_t k_head_skp, int32_t v_head_skp) { + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + init_temp_d(logsum_ + thread_id, scoremax_ + thread_id, acc_o_ + thread_id * dim_size, dim_size); + + const dtype_t *q_batch_base = Q + b_idx * head_size * q_head_skp; + const dtype_t *k_batch_base = K + b_idx * KV_Head * k_head_skp; + const dtype_t *v_batch_base = V + b_idx * KV_Head * v_head_skp; + dtype_t *o_batch_base = O + b_idx * head_size * q_head_skp; + + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const int32_t Bc_n_fixed = (t_c_idx == Tc - 1) ? (seq_size_k - t_c_idx * Bc) : Bc; + + const dtype_t *tile_q = q_batch_base + this_thread_head * q_head_skp; + const dtype_t *tile_k = k_batch_base + this_thread_kv_head * k_head_skp + t_c_idx * Bc * dim_size; + const dtype_t *tile_v = v_batch_base + this_thread_kv_head * v_head_skp + t_c_idx * Bc * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * dim_size; + + mma0_d(Bc_n_fixed, tile_q, tile_k, tile_acc_s, dim_size, t_c_idx, seq_size_k, causal_mask); + softmax_d(Bc_n_fixed, tile_acc_s, scoremax_ + thread_id, scoremax_prev_ + thread_id, score_scale_ + thread_id, score_sum_ + thread_id, logsum_ + thread_id, local_scale); + rescale_d(acc_o, score_scale_ + thread_id, dim_size); + mma1_d(Bc_n_fixed, tile_acc_s, tile_v, acc_o, dim_size); + } + + dtype_t* o_block_ptr = o_batch_base + this_thread_head * q_head_skp; + scale_and_store_d(acc_o_ + thread_id * dim_size, logsum_ + thread_id, o_block_ptr, dim_size); + } + } + } + + inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t Br_n_fixed, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF_F32; + } + #ifdef __AVX2__ + __m256 zero_vec = _mm256_setzero_ps(); + for (int j = 0; j < Br_n_fixed * dim_size; j += 8) { + _mm256_storeu_ps(acc_o + j, zero_vec); + } + #elif __ARM_NEON + float32x4_t zero_vec = vdupq_n_f32(0.0f); + for (int j = 0; j < Br_n_fixed * dim_size; j += 4) { + vst1q_f32(acc_o + j, zero_vec); + } + #endif + } + + inline void mma0(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + const int32_t delta_pos = seq_size_k - seq_size_q; + + for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + const dtype_t *q_block_line = q_block + b_r_idx * dim_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const int32_t global_r_idx = global_r_start + b_r_idx; + const int32_t global_c_idx = global_c_start + b_c_idx; + if (causal_mask && (global_c_idx > global_r_idx + delta_pos)) { + acc_s[b_r_idx * Bc + b_c_idx] = NEG_INF_F32; + continue; + } + const dtype_t *k_block_line = k_block + b_c_idx * dim_size; + #ifdef __AVX2__ + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + __m256 q_vec = _mm256_loadu_ps(q_block_line + i); + __m256 k_vec = _mm256_loadu_ps(k_block_line + i); + sum_vec = _mm256_fmadd_ps(q_vec, k_vec, sum_vec); + } + acc_dtype_t total = hadd_ps_avx(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + #elif __ARM_NEON + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), vld1q_f32(k_block_line + i)); + } + acc_dtype_t total = hadd_ps_neon(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + #endif + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + } + + inline void softmax(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale) { + memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); + + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float block_max = NEG_INF_F32; + for(int bc = 0; bc < Bc_n_fixed; ++bc) { + block_max = fmaxf(block_max, row[bc]); + } + scoremax[br] = fmaxf(scoremax[br], block_max); + } + + for (int br = 0; br < Br_n_fixed; ++br) { + score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); + } + + for (int br = 0; br < Br_n_fixed; ++br) { + const float current_max = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + if(row[bc] == NEG_INF_F32) { + row[bc] = 0.0f; + continue; + } + float val = expf((row[bc] - current_max) * scale); + row[bc] = val; + sum += val; + } + score_sum[br] = sum; + } + + for (int br = 0; br < Br_n_fixed; ++br) { + logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; + } + } + + inline void rescale(const int32_t Br_n_fixed, acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + #ifdef __AVX2__ + __m256 scale_v = _mm256_set1_ps(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 8) { + __m256 acc = _mm256_loadu_ps(row_ptr + j); + _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(acc, scale_v)); + } + #elif __ARM_NEON + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 4) { + float32x4_t acc = vld1q_f32(row_ptr + j); + vst1q_f32(row_ptr + j, vmulq_f32(acc, scale_v)); + } + #endif + } + } + + inline void mma1(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t dim_size) { + const int32_t v_stride_size = dim_size; + + for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + #ifdef __AVX2__ + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + acc = _mm256_fmadd_ps(_mm256_set1_ps(w_block[b_r_idx * Bc + b_c_idx]), _mm256_loadu_ps(v_block + b_c_idx * v_stride_size + d_base), acc); + } + _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); + } + #elif __ARM_NEON + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + acc = vfmaq_f32(acc, vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]), vld1q_f32(v_block + b_c_idx * v_stride_size + d_base)); + } + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + } + #endif + } + } + + inline void scale_and_store(const int32_t Br_n_fixed, const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, + dtype_t *__restrict__ o_block, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + dtype_t *o_block_line = o_block + i * dim_size; + float reciprocal_logsum = (logsum[i] == 0.0f) ? 0.0f : 1.0f / logsum[i]; + #ifdef __AVX2__ + __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); + for (int j = 0; j <= dim_size - 8; j += 8) { + __m256 vec_acc_o = _mm256_loadu_ps(acc_o + i * dim_size + j); + _mm256_storeu_ps(o_block_line + j, _mm256_mul_ps(vec_acc_o, reciprocal_logsum_vec)); + } + for (int j = dim_size - (dim_size % 8); j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } + #elif __ARM_NEON + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + for (int j = 0; j <= dim_size - 4; j += 4) { + float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); + vst1q_f32(o_block_line + j, vmulq_f32(vec_acc_o, reciprocal_logsum_vec)); + } + for (int j = dim_size - (dim_size % 4); j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } + #endif + } + } + + inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { + logsum[0] = 0.0f; + scoremax[0] = NEG_INF_F32; + #ifdef __AVX2__ + __m256 zero_vec = _mm256_setzero_ps(); + for (int i = 0; i < dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } + #elif __ARM_NEON + float32x4_t zero_vec = vdupq_n_f32(0.0f); + for (int i = 0; i < dim_size; i += 4) { vst1q_f32(acc_o + i, zero_vec); } + #endif + } + + inline void mma0_d(const int32_t Bc_n_fixed, const dtype_t *__restrict__ q_block, + const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, + const int32_t dim_size, const int32_t t_c_idx, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_c_start = t_c_idx * Bc; + const int32_t global_r_idx = seq_size_k - 1; + + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const int32_t global_c_idx = global_c_start + b_c_idx; + if(causal_mask && global_c_idx > global_r_idx) { + acc_s[b_c_idx] = NEG_INF_F32; + continue; + } + const dtype_t *k_block_line = k_block + b_c_idx * dim_size; + #ifdef __AVX2__ + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + sum_vec = _mm256_fmadd_ps(_mm256_loadu_ps(q_block + i), _mm256_loadu_ps(k_block_line + i), sum_vec); + } + acc_dtype_t total = hadd_ps_avx(sum_vec); + for (int i = dim_size - (dim_size % 8); i < dim_size; ++i) { total += q_block[i] * k_block_line[i]; } + #elif __ARM_NEON + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block + i), vld1q_f32(k_block_line + i)); + } + acc_dtype_t total = hadd_ps_neon(sum_vec); + for (int i = dim_size - (dim_size % 4); i < dim_size; ++i) { total += q_block[i] * k_block_line[i]; } + #endif + acc_s[b_c_idx] = total; + } + } + + inline void softmax_d(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_s, + acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale) { + scoremax_prev[0] = scoremax[0]; + + float block_max = NEG_INF_F32; + for (int bc = 0; bc < Bc_n_fixed; ++bc) block_max = fmaxf(block_max, acc_s[bc]); + scoremax[0] = fmaxf(scoremax[0], block_max); + + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + if(acc_s[bc] == NEG_INF_F32) { + acc_s[bc] = 0.0f; + continue; + } + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size) { + #ifdef __AVX2__ + __m256 scale_v = _mm256_set1_ps(score_scale[0]); + for (int j = 0; j < dim_size; j += 8) { + _mm256_storeu_ps(acc_o + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), scale_v)); + } + #elif __ARM_NEON + float32x4_t scale_v = vdupq_n_f32(score_scale[0]); + for (int j = 0; j < dim_size; j += 4) { + vst1q_f32(acc_o + j, vmulq_f32(vld1q_f32(acc_o + j), scale_v)); + } + #endif + } + + inline void mma1_d(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, + const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t dim_size) { + const int32_t v_stride_size = dim_size; + #ifdef __AVX2__ + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + acc = _mm256_fmadd_ps(_mm256_set1_ps(w_block[b_c_idx]), _mm256_loadu_ps(v_block + b_c_idx * v_stride_size + d_base), acc); + } + _mm256_storeu_ps(acc_o + d_base, acc); + } + #elif __ARM_NEON + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + acc = vfmaq_f32(acc, vdupq_n_f32(w_block[b_c_idx]), vld1q_f32(v_block + b_c_idx * v_stride_size + d_base)); + } + vst1q_f32(acc_o + d_base, acc); + } + #endif + } + + inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, + dtype_t *__restrict__ o_block, const int32_t dim_size) { + float reciprocal_logsum = (logsum[0] == 0.0f) ? 0.0f : 1.0f / logsum[0]; + #ifdef __AVX2__ + __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); + for (int j = 0; j <= dim_size - 8; j += 8) { + _mm256_storeu_ps(o_block + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), reciprocal_logsum_vec)); + } + for (int j = dim_size - (dim_size % 8); j < dim_size; ++j) { o_block[j] = acc_o[j] * reciprocal_logsum; } + #elif __ARM_NEON + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + for (int j = 0; j <= dim_size - 4; j += 4) { + vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); + } + for (int j = dim_size - (dim_size % 4); j < dim_size; ++j) { o_block[j] = acc_o[j] * reciprocal_logsum; } + #endif + } +}; + +// ======================================== +// FlashAttention2 核心实现 ( Q FP32/KV FP16 输入,FP32 输出版本) - BHSD Layout +// ======================================== +struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { + using dtype_q_in_t = float; + using dtype_kv_in_t = mllm_fp16_t; + using dtype_out_t = float; + using acc_dtype_t = float; + + int32_t Br, Bc, Q_Head, KV_Head, threads; + bool high_precision; + + acc_dtype_t *acc_o_; + acc_dtype_t *acc_s_; + acc_dtype_t *logsum_; + acc_dtype_t *scoremax_; + acc_dtype_t *scoremax_prev_; + acc_dtype_t *score_scale_; + acc_dtype_t *score_sum_; + + void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_, bool high_precision_) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_Head_; + KV_Head = KV_Head_; + threads = threads_; + high_precision = high_precision_; + } + + void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, + acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum) { + acc_o_ = acc_o; + acc_s_ = acc_s; + logsum_ = logsum; + scoremax_ = scoremax; + scoremax_prev_ = scoremax_prev; + score_scale_ = score_scale; + score_sum_ = score_sum; + } + + void fa2(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, const int32_t batch_size, + const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask, + int32_t q_head_skp, int32_t k_head_skp, int32_t v_head_skp) { + assert(Br == Bc); + assert(head_size % threads == 0); + assert(Q_Head % KV_Head == 0); + + #ifdef __AVX2__ + assert(dim_size % 8 == 0); + #elif __ARM_NEON + assert(dim_size % 4 == 0); + #endif + + if (seq_size_q != 1) { + __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, q_head_skp, k_head_skp, v_head_skp); + } else { + __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, q_head_skp, k_head_skp, v_head_skp); + } + } + +private: + inline void __fa2_prefill_append(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask, + int32_t q_head_skp, int32_t k_head_skp, int32_t v_head_skp) { + const int32_t Tr = (seq_size_q + Br - 1) / Br; + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + const dtype_q_in_t *q_batch_base = Q + b_idx * head_size * q_head_skp; + const dtype_kv_in_t *k_batch_base = K + b_idx * KV_Head * k_head_skp; + const dtype_kv_in_t *v_batch_base = V + b_idx * KV_Head * v_head_skp; + dtype_out_t *o_batch_base = O + b_idx * head_size * q_head_skp; + + for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { + const int32_t Br_n_fixed = (t_r_idx == Tr - 1) ? (seq_size_q - t_r_idx * Br) : Br; + init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, + acc_o_ + thread_id * Br * dim_size, Br_n_fixed, dim_size); + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const int32_t Bc_n_fixed = (t_c_idx == Tc - 1) ? (seq_size_k - t_c_idx * Bc) : Bc; + + const dtype_q_in_t *tile_q = q_batch_base + this_thread_head * q_head_skp + t_r_idx * Br * dim_size; + const dtype_kv_in_t *tile_k = k_batch_base + this_thread_kv_head * k_head_skp + t_c_idx * Bc * dim_size; + const dtype_kv_in_t *tile_v = v_batch_base + this_thread_kv_head * v_head_skp + t_c_idx * Bc * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; + + mma0(Br_n_fixed, Bc_n_fixed, tile_q, tile_k, tile_acc_s, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); + softmax(Br_n_fixed, Bc_n_fixed, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale); + rescale(Br_n_fixed, acc_o, score_scale_ + thread_id * Br, dim_size); + mma1(Br_n_fixed, Bc_n_fixed, tile_acc_s, tile_v, acc_o, dim_size); + } + dtype_out_t *o_block_ptr = o_batch_base + this_thread_head * q_head_skp + t_r_idx * Br * dim_size; + scale_and_store(Br_n_fixed, acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, o_block_ptr, dim_size); + } + } + } + } + + inline void __fa2_decode(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask, + int32_t q_head_skp, int32_t k_head_skp, int32_t v_head_skp) { + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_head = h_idx; + const int32_t this_thread_kv_head = this_thread_head / kv_group_size; + + init_temp_d(logsum_ + thread_id, scoremax_ + thread_id, acc_o_ + thread_id * dim_size, dim_size); + + const dtype_q_in_t *q_batch_base = Q + b_idx * head_size * q_head_skp; + const dtype_kv_in_t *k_batch_base = K + b_idx * KV_Head * k_head_skp; + const dtype_kv_in_t *v_batch_base = V + b_idx * KV_Head * v_head_skp; + dtype_out_t *o_batch_base = O + b_idx * head_size * q_head_skp; + + for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + const int32_t Bc_n_fixed = (t_c_idx == Tc - 1) ? (seq_size_k - t_c_idx * Bc) : Bc; + + const dtype_q_in_t *tile_q = q_batch_base + this_thread_head * q_head_skp; + const dtype_kv_in_t *tile_k = k_batch_base + this_thread_kv_head * k_head_skp + t_c_idx * Bc * dim_size; + const dtype_kv_in_t *tile_v = v_batch_base + this_thread_kv_head * v_head_skp + t_c_idx * Bc * dim_size; + + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Bc; + acc_dtype_t *acc_o = acc_o_ + thread_id * dim_size; + + mma0_d(Bc_n_fixed, tile_q, tile_k, tile_acc_s, dim_size, t_c_idx, seq_size_k, causal_mask); + softmax_d(Bc_n_fixed, tile_acc_s, scoremax_ + thread_id, scoremax_prev_ + thread_id, score_scale_ + thread_id, score_sum_ + thread_id, logsum_ + thread_id, local_scale); + rescale_d(acc_o, score_scale_ + thread_id, dim_size); + mma1_d(Bc_n_fixed, tile_acc_s, tile_v, acc_o, dim_size); + } + dtype_out_t* o_block_ptr = o_batch_base + this_thread_head * q_head_skp; + scale_and_store_d(acc_o_ + thread_id * dim_size, logsum_ + thread_id, o_block_ptr, dim_size); + } + } + } + + inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t Br_n_fixed, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF_F32; + } + #ifdef __AVX2__ + __m256 zero_vec = _mm256_setzero_ps(); + for (int j = 0; j < Br_n_fixed * dim_size; j += 8) { + _mm256_storeu_ps(acc_o + j, zero_vec); + } + #elif __ARM_NEON + float32x4_t zero_vec = vdupq_n_f32(0.0f); + for (int j = 0; j < Br_n_fixed * dim_size; j += 4) { + vst1q_f32(acc_o + j, zero_vec); + } + #endif + } + + inline void mma0(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, + acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, + const int32_t t_r_idx, const int32_t t_c_idx, + const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + const int32_t delta_pos = seq_size_k - seq_size_q; + + for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + const dtype_q_in_t *q_block_line = q_block + b_r_idx * dim_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const int32_t global_r_idx = global_r_start + b_r_idx; + const int32_t global_c_idx = global_c_start + b_c_idx; + if (causal_mask && (global_c_idx > global_r_idx + delta_pos)) { + acc_s[b_r_idx * Bc + b_c_idx] = NEG_INF_F32; + continue; + } + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * dim_size; + #ifdef __AVX2__ + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + __m256 q_vec = _mm256_loadu_ps(q_block_line + i); + __m256 k_vec = MLLM_F32Cx8_LOAD(k_block_line + i); + sum_vec = _mm256_fmadd_ps(q_vec, k_vec, sum_vec); + } + acc_dtype_t total = hadd_ps_avx(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + #elif __ARM_NEON + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + float32x4_t q_vec = vld1q_f32(q_block_line + i); + float32x4_t k_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)(k_block_line + i))); + sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); + } + acc_dtype_t total = hadd_ps_neon(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + #endif + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + } + + inline void softmax(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale) { + memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); + for (int br = 0; br < Br_n_fixed; ++br) { + acc_dtype_t *row = acc_s + br * Bc; + float block_max = NEG_INF_F32; + for(int bc = 0; bc < Bc_n_fixed; ++bc) block_max = fmaxf(block_max, row[bc]); + scoremax[br] = fmaxf(scoremax[br], block_max); + } + for (int br = 0; br < Br_n_fixed; ++br) score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); + for (int br = 0; br < Br_n_fixed; ++br) { + const float current_max = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + if(row[bc] == NEG_INF_F32) { row[bc] = 0.0f; continue; } + float val = expf((row[bc] - current_max) * scale); + row[bc] = val; + sum += val; + } + score_sum[br] = sum; + } + for (int br = 0; br < Br_n_fixed; ++br) logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; + } + + inline void rescale(const int32_t Br_n_fixed, acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + #ifdef __AVX2__ + __m256 scale_v = _mm256_set1_ps(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 8) _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + j), scale_v)); + #elif __ARM_NEON + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 4) vst1q_f32(row_ptr + j, vmulq_f32(vld1q_f32(row_ptr + j), scale_v)); + #endif + } + } + + inline void mma1(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, + const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, + acc_dtype_t *__restrict__ acc_o, const int32_t dim_size) { + const int32_t v_stride_size = dim_size; + for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + #ifdef __AVX2__ + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + acc = _mm256_fmadd_ps(_mm256_set1_ps(w_block[b_r_idx * Bc + b_c_idx]), MLLM_F32Cx8_LOAD(v_block + b_c_idx * v_stride_size + d_base), acc); + } + _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); + } + #elif __ARM_NEON + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); + float32x4_t v_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)(v_block + b_c_idx * v_stride_size + d_base))); + acc = vfmaq_f32(acc, w_vec, v_vec); + } + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + } + #endif + } + } + + inline void scale_and_store(const int32_t Br_n_fixed, const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, + dtype_out_t *__restrict__ o_block, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + dtype_out_t *o_block_line = o_block + i * dim_size; + float reciprocal_logsum = (logsum[i] == 0.0f) ? 0.0f : 1.0f / logsum[i]; + #ifdef __AVX2__ + __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); + for (int j = 0; j <= dim_size - 8; j += 8) _mm256_storeu_ps(o_block_line + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + i * dim_size + j), reciprocal_logsum_vec)); + for (int j = dim_size - (dim_size % 8); j < dim_size; ++j) o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; + #elif __ARM_NEON + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + for (int j = 0; j <= dim_size - 4; j += 4) vst1q_f32(o_block_line + j, vmulq_f32(vld1q_f32(acc_o + i * dim_size + j), reciprocal_logsum_vec)); + for (int j = dim_size - (dim_size % 4); j < dim_size; ++j) o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; + #endif + } + } + + inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { + logsum[0] = 0.0f; + scoremax[0] = NEG_INF_F32; + #ifdef __AVX2__ + __m256 zero_vec = _mm256_setzero_ps(); + for (int i = 0; i < dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } + #elif __ARM_NEON + float32x4_t zero_vec = vdupq_n_f32(0.0f); + for (int i = 0; i < dim_size; i += 4) { vst1q_f32(acc_o + i, zero_vec); } + #endif + } + + inline void mma0_d(const int32_t Bc_n_fixed, const dtype_q_in_t *__restrict__ q_block, + const dtype_kv_in_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, + const int32_t dim_size, const int32_t t_c_idx, + const int32_t seq_size_k, bool causal_mask) { + const int32_t global_c_start = t_c_idx * Bc; + const int32_t global_r_idx = seq_size_k - 1; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const int32_t global_c_idx = global_c_start + b_c_idx; + if(causal_mask && global_c_idx > global_r_idx) { + acc_s[b_c_idx] = NEG_INF_F32; + continue; + } + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * dim_size; + #ifdef __AVX2__ + __m256 sum_vec = _mm256_setzero_ps(); + int i = 0; + for (; i <= dim_size - 8; i += 8) sum_vec = _mm256_fmadd_ps(_mm256_loadu_ps(q_block + i), MLLM_F32Cx8_LOAD(k_block_line + i), sum_vec); + acc_dtype_t total = hadd_ps_avx(sum_vec); + for (; i < dim_size; ++i) total += q_block[i] * MLLM_FP16_TO_FP32(k_block_line[i]); + #elif __ARM_NEON + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + float32x4_t q_vec = vld1q_f32(q_block + i); + float32x4_t k_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)(k_block_line + i))); + sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); + } + acc_dtype_t total = hadd_ps_neon(sum_vec); + for (; i < dim_size; ++i) total += q_block[i] * MLLM_FP16_TO_FP32(k_block_line[i]); + #endif + acc_s[b_c_idx] = total; + } + } + + inline void softmax_d(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_s, + acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, + const float scale) { + scoremax_prev[0] = scoremax[0]; + float block_max = NEG_INF_F32; + for (int bc = 0; bc < Bc_n_fixed; ++bc) block_max = fmaxf(block_max, acc_s[bc]); + scoremax[0] = fmaxf(scoremax[0], block_max); + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + float current_sum = 0.0f; + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + if(acc_s[bc] == NEG_INF_F32) { acc_s[bc] = 0.0f; continue; } + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + } + + inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size) { + #ifdef __AVX2__ + __m256 scale_v = _mm256_set1_ps(score_scale[0]); + for (int j = 0; j < dim_size; j += 8) _mm256_storeu_ps(acc_o + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), scale_v)); + #elif __ARM_NEON + float32x4_t scale_v = vdupq_n_f32(score_scale[0]); + for (int j = 0; j < dim_size; j += 4) vst1q_f32(acc_o + j, vmulq_f32(vld1q_f32(acc_o + j), scale_v)); + #endif + } + + inline void mma1_d(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, + const dtype_kv_in_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t dim_size) { + const int32_t v_stride_size = dim_size; + #ifdef __AVX2__ + for (int d_base = 0; d_base < dim_size; d_base += 8) { + __m256 acc = _mm256_loadu_ps(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + acc = _mm256_fmadd_ps(_mm256_set1_ps(w_block[b_c_idx]), MLLM_F32Cx8_LOAD(v_block + b_c_idx * v_stride_size + d_base), acc); + } + _mm256_storeu_ps(acc_o + d_base, acc); + } + #elif __ARM_NEON + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); + float32x4_t v_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)(v_block + b_c_idx * v_stride_size + d_base))); + acc = vfmaq_f32(acc, w_vec, v_vec); + } + vst1q_f32(acc_o + d_base, acc); + } + #endif + } + + inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, + dtype_out_t *__restrict__ o_block, const int32_t dim_size) { + float reciprocal_logsum = (logsum[0] == 0.0f) ? 0.0f : 1.0f / logsum[0]; + #ifdef __AVX2__ + __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); + for (int j = 0; j <= dim_size - 8; j += 8) _mm256_storeu_ps(o_block + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), reciprocal_logsum_vec)); + for (int j = dim_size-(dim_size%8); j < dim_size; ++j) o_block[j] = acc_o[j] * reciprocal_logsum; + #elif __ARM_NEON + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + for (int j = 0; j <= dim_size - 4; j += 4) vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); + for (int j = dim_size-(dim_size%4); j < dim_size; ++j) o_block[j] = acc_o[j] * reciprocal_logsum; + #endif + } +}; + +template +struct FlashAttn2HeadFirstT { +public: + using dtype_q_in_t = typename Impl::dtype_q_in_t; + using dtype_kv_in_t = typename Impl::dtype_kv_in_t; + using dtype_out_t = typename Impl::dtype_out_t; + using acc_dtype_t = typename Impl::acc_dtype_t; + + void configure(int32_t Br, int32_t Bc, int32_t Q_Head, int32_t KV_Head, int32_t threads, bool high_precision) { + impl_.configure(Br, Bc, Q_Head, KV_Head, threads, high_precision); + } + + void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, + acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, + acc_dtype_t *score_scale, acc_dtype_t *score_sum) { + impl_.init_workspace(acc_o, acc_s, logsum, scoremax, scoremax_prev, score_scale, score_sum); + } + + void operator()(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, + const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, + const int32_t batch_size, const int32_t head_size, + const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask, + int32_t q_head_skp, int32_t k_head_skp, int32_t v_head_skp) { + impl_.fa2(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, q_head_skp, k_head_skp, v_head_skp); + } + +private: + Impl impl_; +}; + +} // namespace mobi_attn + +inline void flash_attention_2_forward_h( + const void *Q, const void *K, const void *V, void *O, + int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, + bool causal_mask, bool use_fp32, int32_t threads, int32_t br, int32_t bc, + int32_t q_head, int32_t kv_head, bool high_precision_exp, + int32_t q_head_skp, int32_t k_head_skp, int32_t v_head_skp) { + + const size_t align = 32; + const size_t acc_o_size = threads * br * dim_size * sizeof(float); + const size_t acc_s_size = threads * br * bc * sizeof(float); + const size_t logsum_size = threads * br * sizeof(float); + const size_t scoremax_size = threads * br * sizeof(float); + const size_t scoremax_prev_size = threads * br * sizeof(float); + const size_t score_scale_size = threads * br * sizeof(float); + const size_t score_sum_size = threads * br * sizeof(float); + + void *workspace_ptr = nullptr; + size_t total_workspace_size = acc_o_size + acc_s_size + logsum_size + scoremax_size + scoremax_prev_size + score_scale_size + score_sum_size; + + platform_aligned_alloc(&workspace_ptr, total_workspace_size, align); + if(workspace_ptr == nullptr) { + return; + } + + float* acc_o = static_cast(workspace_ptr); + float* acc_s = acc_o + threads * br * dim_size; + float* logsum = acc_s + threads * br * bc; + float* scoremax = logsum + threads * br; + float* scoremax_prev = scoremax + threads * br; + float* score_scale = scoremax_prev + threads * br; + float* score_sum = score_scale + threads * br; + + if (use_fp32) { + mobi_attn::FlashAttn2HeadFirstT op; + op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); + op.init_workspace(acc_o, acc_s, logsum, scoremax, scoremax_prev, score_scale, score_sum); + op(static_cast(Q), static_cast(K), static_cast(V), + static_cast(O), + batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, + q_head_skp, k_head_skp, v_head_skp); + } else { + mobi_attn::FlashAttn2HeadFirstT op; + op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); + op.init_workspace(acc_o, acc_s, logsum, scoremax, scoremax_prev, score_scale, score_sum); + op(static_cast(Q), + static_cast(K), + static_cast(V), + static_cast(O), + batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, + q_head_skp, k_head_skp, v_head_skp); + } + + if (workspace_ptr) { + platform_aligned_free(workspace_ptr); + } +} + +#endif // MLLM_FA2H_CAL_HPP \ No newline at end of file diff --git a/src/backends/cpu/compute/GemmKleidiai.cpp b/src/backends/cpu/compute/GemmKleidiai.cpp index 9dd40a583..db3bc7658 100644 --- a/src/backends/cpu/compute/GemmKleidiai.cpp +++ b/src/backends/cpu/compute/GemmKleidiai.cpp @@ -2,6 +2,7 @@ #if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) #include "GemmKleidiai.hpp" +#include "FeatureCheck.hpp" #include #include #include @@ -10,16 +11,112 @@ // 引入 OpenMP 头文件 #include -// #if defined(USE_QSI4_C32) // ###################################################################### // // ## Implementation 1: QSI4 (INT4) ## +// ###################################################################### //// 【新增】线程局部的全局工作区,用于内存复用 +// 【新增】一个为OpenMP设计的、线程安全的工作区管理器 +class WorkspaceManager { +public: + // 构造函数:获取OpenMP最大线程数,并为每个线程创建一个工作区 + WorkspaceManager() { + int max_threads = kai_thread_count; // 获取当前线程数; +#ifdef _OPENMP + max_threads = omp_get_max_threads(); +#endif + qsi4_workspaces_.resize(max_threads); + qsi4_c_temp_buffers_.resize(max_threads); + fp16_a_buffers_.resize(max_threads); + fp16_c_buffers_.resize(max_threads); + } + + // 获取当前线程的 QSI4 工作区 + std::vector &get_qsi4_workspace() { + int thread_id = 0; +#ifdef _OPENMP + thread_id = omp_get_thread_num(); +#endif + return qsi4_workspaces_[thread_id]; + } + + // 获取当前线程的 QSI4->FP16 临时C区 + std::vector &get_qsi4_c_temp_buffer() { + int thread_id = 0; +#ifdef _OPENMP + thread_id = omp_get_thread_num(); +#endif + return qsi4_c_temp_buffers_[thread_id]; + } + + // 获取当前线程的 FP16 临时A区 + std::vector &get_fp16_a_buffer() { + int thread_id = 0; +#ifdef _OPENMP + thread_id = omp_get_thread_num(); +#endif + return fp16_a_buffers_[thread_id]; + } + + // 获取当前线程的 FP16 临时C区 + std::vector &get_fp16_c_buffer() { + int thread_id = 0; +#ifdef _OPENMP + thread_id = omp_get_thread_num(); +#endif + return fp16_c_buffers_[thread_id]; + } + +private: + std::vector> qsi4_workspaces_; + std::vector> qsi4_c_temp_buffers_; + std::vector> fp16_a_buffers_; + std::vector> fp16_c_buffers_; +}; + +// 创建一个全局唯一的管理器实例 +static WorkspaceManager g_workspace_manager; + // ###################################################################### // +// ## Implementation 1: QSI4 (INT4) ## +// ###################################################################### // + +// 【新增】包含用于map和CPU特性检测的头文件 +#include +#if defined(__linux__) +#include +#include +#endif + +// 【新增】包含所有需要的计算核心头文件,特别是 i8mm 版本 #include "kai_matmul_clamp_f32_qai8dxp_qsi4c32p_interface.h" #include "kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.h" #include "kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.h" #include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.h" +#include "kai_lhs_quant_pack_qai8dxp_f32.h" +#include "kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.h" +#include "kai_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm.h" +#include "kai_matmul_clamp_f32_qai8dxp_qsi4c32p_interface.h" +#include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.h" + +// 【新增】在.cpp内部定义核心配置的枚举,外部不可见 +enum class KleidiaiQsi4Tile { + k1x8_4x8_1x4x32_dotprod, // 兼容性最好的 dotprod 核心 + k4x8_4x8_8x4x32_i8mm, // 高性能的 i8mm 核心 +}; + +// 【新增】为KleidiaiQsi4Tile定义哈希函数以用于unordered_map +namespace std { +template <> +struct hash { + std::size_t operator()(const KleidiaiQsi4Tile &k) const noexcept { + return std::hash::type>()( + static_cast::type>(k)); + } +}; +} // namespace std -static const kai_matmul_clamp_f32_qai8dxp_qsi4c32p_ukernel qsi4_ukernel = { +// 【新增】在.cpp内部定义一个静态map,存储所有可用的计算核心 +// 【新增】第一步:将每个 ukernel 定义为独立的静态常量 +static const kai_matmul_clamp_f32_qai8dxp_qsi4c32p_ukernel dotprod_ukernel = { .get_m_step = kai_get_m_step_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, .get_n_step = kai_get_n_step_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, .get_mr = kai_get_mr_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, @@ -29,35 +126,67 @@ static const kai_matmul_clamp_f32_qai8dxp_qsi4c32p_ukernel qsi4_ukernel = { .get_lhs_packed_offset = kai_get_lhs_packed_offset_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, .get_rhs_packed_offset = kai_get_rhs_packed_offset_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, .get_dst_offset = kai_get_dst_offset_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, - .run_matmul = kai_run_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, -}; - + .run_matmul = kai_run_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod}; + +static const kai_matmul_clamp_f32_qai8dxp_qsi4c32p_ukernel i8mm_ukernel = { + .get_m_step = kai_get_m_step_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, + .get_n_step = kai_get_n_step_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, + .get_mr = kai_get_mr_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, + .get_nr = kai_get_nr_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, + .get_kr = kai_get_kr_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, + .get_sr = kai_get_sr_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, + .get_lhs_packed_offset = kai_get_lhs_packed_offset_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, + .get_rhs_packed_offset = kai_get_rhs_packed_offset_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, + .get_dst_offset = kai_get_dst_offset_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, + .run_matmul = kai_run_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm}; + +// 第二步:使用定义好的常量来初始化 map,语法更简洁清晰 +static const std::unordered_map qsi4_ukernels = { + {KleidiaiQsi4Tile::k1x8_4x8_1x4x32_dotprod, dotprod_ukernel}, + {KleidiaiQsi4Tile::k4x8_4x8_8x4x32_i8mm, i8mm_ukernel}}; + +// 【新增】根据CPU能力自动选择最佳核心,并缓存结果 +static KleidiaiQsi4Tile kleidiai_get_best_qsi4_tile_config() { + // 使用静态变量,这样CPU检测的逻辑只会在第一次调用时执行一次 + static const KleidiaiQsi4Tile best_tile = arm_is_i8mm_supported() ? + KleidiaiQsi4Tile::k4x8_4x8_8x4x32_i8mm : + KleidiaiQsi4Tile::k1x8_4x8_1x4x32_dotprod; + return best_tile; +} size_t mllm_kleidai_get_packed_b_qsi4_size(int N, int K) { + const auto tile_cfg = kleidiai_get_best_qsi4_tile_config(); + const auto &ukernel = qsi4_ukernels.at(tile_cfg); const int block_len = 32; return kai_get_rhs_packed_size_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0( - N, K, qsi4_ukernel.get_nr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), + N, K, ukernel.get_nr(), ukernel.get_kr(), ukernel.get_sr(), block_len, kai_dt_bf16); } size_t get_workspace_qsi4_size(int M, int K) { + const auto tile_cfg = kleidiai_get_best_qsi4_tile_config(); + const auto &ukernel = qsi4_ukernels.at(tile_cfg); return kai_get_lhs_packed_size_lhs_quant_pack_qai8dxp_f32( - M, K, qsi4_ukernel.get_mr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr()); + M, K, ukernel.get_mr(), ukernel.get_kr(), ukernel.get_sr()); } void mllm_kleidai_pack_b_and_bias_qsi4( - uint8_t *packed_b_ptr, - const float *b_ptr, - const float *bias_ptr, + uint8_t* packed_b_ptr, + const float* b_ptr, + const float* bias_ptr, int N, int K) { + const auto tile_cfg = kleidiai_get_best_qsi4_tile_config(); + const auto &ukernel = qsi4_ukernels.at(tile_cfg); + // 【新增】创建临时的bias(如果需要) - const float *bias_to_use = bias_ptr; + const float* bias_to_use = bias_ptr; std::vector fake_bias; if (bias_to_use == nullptr) { fake_bias.assign(N, 0.0f); bias_to_use = fake_bias.data(); } + const int block_len = 32; const size_t num_blocks_k = (K + block_len - 1) / block_len; std::vector temp_quantized_b(K * N / 2); @@ -103,38 +232,51 @@ void mllm_kleidai_pack_b_and_bias_qsi4( // temp_quantized_b.data(), K/2, bias_to_use, (const uint8_t*)temp_scales.data(), num_blocks_k * sizeof(uint16_t), // packed_b_ptr, 0, ¶ms); kai_run_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0( - 1, N, K, qsi4_ukernel.get_nr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), block_len, - temp_quantized_b.data(), N / 2, bias_to_use, (const uint8_t *)temp_scales.data(), num_blocks_k * sizeof(uint16_t), + 1, N, K, ukernel.get_nr(), ukernel.get_kr(), ukernel.get_sr(), block_len, + temp_quantized_b.data(), N/2, bias_to_use, (const uint8_t*)temp_scales.data(), num_blocks_k * sizeof(uint16_t), packed_b_ptr, 0, ¶ms); } +// --- 【替换】旧的 mllm_kleidai_gemm_qsi4 函数 ---// --- 【替换】旧的 mllm_kleidai_gemm_qsi4 函数 --- void mllm_kleidai_gemm_qsi4( float *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, int M, int N, int K) { - size_t workspace_size = get_workspace_qsi4_size(M, K); - std::vector workspace_data(workspace_size); + // 1. 内部自动选择最佳计算核心 (i8mm 或 dotprod) + const auto tile_cfg = kleidiai_get_best_qsi4_tile_config(); + const auto &ukernel = qsi4_ukernels.at(tile_cfg); + + // 2. 从全局管理器获取当前线程专属的工作区,如果空间不足则自动扩容 + auto &workspace_data = g_workspace_manager.get_qsi4_workspace(); + size_t required_workspace_size = get_workspace_qsi4_size(M, K); + if (workspace_data.size() < required_workspace_size) { + workspace_data.resize(required_workspace_size); + } + // 3. 在获取到的工作区中,对左手矩阵 A 进行量化和打包 kai_run_lhs_quant_pack_qai8dxp_f32( M, K, - qsi4_ukernel.get_mr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), + ukernel.get_mr(), ukernel.get_kr(), ukernel.get_sr(), 0, a_ptr, K * sizeof(float), workspace_data.data()); - const int m_step = qsi4_ukernel.get_m_step(); - const int n_step = qsi4_ukernel.get_n_step(); + const int m_step = ukernel.get_m_step(); + const int n_step = ukernel.get_n_step(); const int block_len = 32; -// #pragma omp parallel for + // 4. 使用选择的最佳核心,在 OpenMP 并行循环中执行矩阵乘法 #pragma omp parallel for collapse(2) num_threads(kai_thread_count) for (int m_start = 0; m_start < M; m_start += m_step) { for (int n_start = 0; n_start < N; n_start += n_step) { const int current_m = std::min(M - m_start, m_step); const int current_n = std::min(N - n_start, n_step); - const void *a_packed_offset = (const char *)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); - const void *b_packed_offset = (const char *)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); + + // 使用来自工作区的指针 + const void *a_packed_offset = (const char *)workspace_data.data() + ukernel.get_lhs_packed_offset(m_start, K); + const void *b_packed_offset = (const char *)packed_b_ptr + ukernel.get_rhs_packed_offset(n_start, K, block_len); float *c_offset = c_ptr + m_start * N + n_start; - qsi4_ukernel.run_matmul( + + ukernel.run_matmul( current_m, current_n, K, block_len, a_packed_offset, b_packed_offset, c_offset, N * sizeof(float), sizeof(float), @@ -142,111 +284,30 @@ void mllm_kleidai_gemm_qsi4( } } } -// #endif - -// 【新增】 -// #if defined(USE_QSI4_TO_FP16) -// ###################################################################### // -// ## Implementation 1.5: QSI4 (INT4) -> FP16 ## -// ###################################################################### // -// void mllm_kleidai_gemm_qsi4_to_fp16( -// mllm_fp16_t* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, -// int M, int N, int K) { - -// // 1. 创建一个临时的 FP32 输出缓冲区 -// std::vector c_temp(M * N); - -// // 2. 运行现有的 QSI4->FP32 GEMM 计算,将结果存入临时缓冲区 -// size_t workspace_size = get_workspace_qsi4_size(M, K); -// std::vector workspace_data(workspace_size); -// kai_run_lhs_quant_pack_qai8dxp_f32(M, K, qsi4_ukernel.get_mr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), -// 0, a_ptr, K * sizeof(float), workspace_data.data()); - -// const int m_step = qsi4_ukernel.get_m_step(); -// const int n_step = qsi4_ukernel.get_n_step(); -// const int block_len = 32; - -// // #pragma omp parallel for -// #pragma omp parallel for collapse(2) num_threads(kai_thread_count) -// for (int m_start = 0; m_start < M; m_start += m_step) { -// for (int n_start = 0; n_start < N; n_start += n_step) { -// const int current_m = std::min(M - m_start, m_step); -// const int current_n = std::min(N - n_start, n_step); -// const void* a_packed_offset = (const char*)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); -// const void* b_packed_offset = (const char*)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); -// float* c_offset = c_temp.data() + m_start * N + n_start; -// qsi4_ukernel.run_matmul( -// current_m, current_n, K, block_len, -// a_packed_offset, b_packed_offset, -// c_offset, N * sizeof(float), sizeof(float), -// -FLT_MAX, FLT_MAX -// ); -// } -// } - -// // 3. 并行地将 FP32 临时结果转换为 FP16 并写入最终输出 -// // #pragma omp parallel for -// #pragma omp parallel for collapse(1) num_threads(kai_thread_count) -// for(int i = 0; i < M * N; ++i) { -// c_ptr[i] = static_cast(c_temp[i]); -// } -// } void mllm_kleidai_gemm_qsi4_to_fp16( mllm_fp16_t *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, int M, int N, int K) { - // 1. 创建一个临时的 FP32 输出缓冲区。 - // 因为您库中唯一兼容的qsi4核心只能输出FP32,所以这一步无法避免。 - std::vector c_temp(M * N); - - // 2. 运行现有的、能正常工作的 QSI4->FP32 GEMM 计算。 - // 这部分代码与您原始版本一致,确保了计算的正确性。 - size_t workspace_size = get_workspace_qsi4_size(M, K); - std::vector workspace_data(workspace_size); - kai_run_lhs_quant_pack_qai8dxp_f32(M, K, qsi4_ukernel.get_mr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), - 0, a_ptr, K * sizeof(float), workspace_data.data()); - - const int m_step = qsi4_ukernel.get_m_step(); - const int n_step = qsi4_ukernel.get_n_step(); - const int block_len = 32; - -#pragma omp parallel for collapse(2) num_threads(kai_thread_count) - for (int m_start = 0; m_start < M; m_start += m_step) { - for (int n_start = 0; n_start < N; n_start += n_step) { - const int current_m = std::min(M - m_start, m_step); - const int current_n = std::min(N - n_start, n_step); - const void *a_packed_offset = (const char *)workspace_data.data() + qsi4_ukernel.get_lhs_packed_offset(m_start, K); - const void *b_packed_offset = (const char *)packed_b_ptr + qsi4_ukernel.get_rhs_packed_offset(n_start, K, block_len); - float *c_offset = c_temp.data() + m_start * N + n_start; - - qsi4_ukernel.run_matmul( - current_m, current_n, K, block_len, - a_packed_offset, b_packed_offset, - c_offset, N * sizeof(float), sizeof(float), - -FLT_MAX, FLT_MAX); - } + // 【优化】为临时的FP32输出缓冲区使用线程局部存储 + auto &c_temp = g_workspace_manager.get_qsi4_c_temp_buffer(); + if (c_temp.size() < M * N) { + c_temp.resize(M * N); } -// 3. 【优化点】使用NEON指令并行地将FP32临时结果高速转换为FP16。 -// 这是本方案的核心优化,远快于原始的逐元素转换。 + mllm_kleidai_gemm_qsi4(c_temp.data(), a_ptr, packed_b_ptr, M, N, K); + + // ... 后续的 FP32 -> FP16 转换代码保持不变 ... #pragma omp parallel for num_threads(kai_thread_count) for (int i = 0; i <= (M * N) - 4; i += 4) { - // 一次性加载4个FP32数据 float32x4_t fp32_vec = vld1q_f32(c_temp.data() + i); - // 一次性转换为4个FP16数据 float16x4_t fp16_vec = vcvt_f16_f32(fp32_vec); - // 一次性存入最终的目标地址 vst1_f16(reinterpret_cast<__fp16 *>(c_ptr + i), fp16_vec); } - - // 处理末尾剩余的不足4个的元素 for (int i = (M * N) - ((M * N) % 4); i < M * N; ++i) { c_ptr[i] = static_cast(c_temp[i]); } } -// #endif -// #if defined(USE_FP16) // ###################################################################### // // ## Implementation 2: FP16 ## // ###################################################################### // @@ -281,38 +342,56 @@ void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t *packed_b_ptr, const mllm_fp1 N * sizeof(mllm_fp16_t), b_ptr, bias_fp16_buffer.data(), nullptr, packed_b_ptr, 0, nullptr); } +// --- 【替换】旧的 mllm_kleidai_gemm_fp16 函数 --- +// --- 【替换】旧的 mllm_kleidai_gemm_fp16 函数 --- void mllm_kleidai_gemm_fp16(float *c_ptr, const float *a_ptr, const mllm_fp16_t *packed_b_ptr, int M, int N, int K) { - std::vector a_fp16(M * K); + // 【优化】从全局管理器中,获取当前线程专属的缓冲区 + // a_fp16 用于存放 a_ptr 从 FP32 转换到 FP16 的结果 + auto &a_fp16 = g_workspace_manager.get_fp16_a_buffer(); + if (a_fp16.size() < M * K) { + a_fp16.resize(M * K); + } + + // c_fp16 用于存放 FP16 矩阵乘法的中间结果 + auto &c_fp16 = g_workspace_manager.get_fp16_c_buffer(); + if (c_fp16.size() < M * N) { + c_fp16.resize(M * N); + } + + // 1. 将输入的 FP32 矩阵 A 并行转换为 FP16,存入线程专属的 a_fp16 缓冲区 +#pragma omp parallel for num_threads(kai_thread_count) for (int i = 0; i < M * K; ++i) { a_fp16[i] = static_cast(a_ptr[i]); } - std::vector c_fp16(M * N); const int m_step = fp16_ukernel.get_m_step(); const int n_step = fp16_ukernel.get_n_step(); -// #pragma omp parallel for + // 2. 执行 FP16 矩阵乘法,结果存入线程专属的 c_fp16 缓冲区 #pragma omp parallel for collapse(2) num_threads(kai_thread_count) for (int m_start = 0; m_start < M; m_start += m_step) { for (int n_start = 0; n_start < N; n_start += n_step) { const int current_m = std::min(M - m_start, m_step); const int current_n = std::min(N - n_start, n_step); + + // 计算时使用缓冲区的指针 const mllm_fp16_t *a_offset = a_fp16.data() + m_start * K; const mllm_fp16_t *b_offset = packed_b_ptr + (n_start * (K + 1)); mllm_fp16_t *c_offset = c_fp16.data() + m_start * N + n_start; + fp16_ukernel.run_matmul( current_m, current_n, K, a_offset, K * sizeof(mllm_fp16_t), b_offset, c_offset, N * sizeof(mllm_fp16_t), sizeof(mllm_fp16_t), -FLT_MAX, FLT_MAX); } } + + // 3. 将 FP16 的中间结果并行转换为最终的 FP32 输出 +#pragma omp parallel for num_threads(kai_thread_count) for (int i = 0; i < M * N; ++i) { c_ptr[i] = static_cast(c_fp16[i]); } } -// #endif - -// #if defined(USE_FP32) // ###################################################################### // // ## Implementation 3: FP32 ## // ###################################################################### // @@ -366,5 +445,74 @@ void mllm_kleidai_gemm_fp32(float *c_ptr, const float *a_ptr, const float *packe } } } -// #endif + +// --- BEGIN: Transpose-and-Pack Functions --- +#include "Transpose2D.hpp" +void mllm_kleidai_pack_b_and_bias_fp32_transpose(float *packed_b_ptr, const float *b_ptr_nxk, const float *bias_ptr, int N, int K) { + // 1. Create a temporary buffer for the transposed KxN matrix + std::vector b_temp_kxn(K * N); + + // 2. Call the efficient transpose function to fill the buffer + transpose_matrix_efficient(b_ptr_nxk, b_temp_kxn.data(), N, K); + + // 3. Call the original packing function with the now correctly-ordered data + mllm_kleidai_pack_b_and_bias_fp32(packed_b_ptr, b_temp_kxn.data(), bias_ptr, N, K); +} + +void mllm_kleidai_pack_b_and_bias_fp16_transpose(mllm_fp16_t *packed_b_ptr, const mllm_fp16_t *b_ptr_nxk, const float *bias_ptr, int N, int K) { + // 1. Create a temporary buffer + std::vector b_temp_kxn(K * N); + + // 2. Perform a cache-friendly transpose for fp16 + // (transpose_matrix_efficient is for float32, so we use its blocking logic here) +#if defined(__aarch64__) + // 2. 【高效路径】在ARM平台上,调用为__fp16优化的NEON SIMD转置函数 + transpose_matrix_efficient_fp16(b_ptr_nxk, b_temp_kxn.data(), N, K); +#else + // 2. 【通用路径】在非ARM平台,使用缓存优化的C++转置 + const int BLOCK_DIM = 32; + for (int i = 0; i < N; i += BLOCK_DIM) { + for (int j = 0; j < K; j += BLOCK_DIM) { + for (int bi = i; bi < i + BLOCK_DIM && bi < N; ++bi) { + for (int bj = j; j < K && bj < j + BLOCK_DIM; ++bj) { + b_temp_kxn[bj * N + bi] = b_ptr_nxk[bi * K + bj]; + } + } + } + } +#endif + + // 3. Call the original fp16 packing function + mllm_kleidai_pack_b_and_bias_fp16(packed_b_ptr, b_temp_kxn.data(), bias_ptr, N, K); +} + +// --- END: Transpose-and-Pack Functions --- +// --- BEGIN: High-Level Transposed GEMM APIs --- + +void mllm_kleidai_gemm_fp32_transpose(float *c_ptr, const float *a_ptr, const float *b_ptr_nxk, const float *bias_ptr, int M, int N, int K) { + // Allocate space for the packed B matrix + size_t packed_b_size = mllm_kleidai_get_packed_b_fp32_size(N, K); + std::vector packed_b_data(packed_b_size); + + // Call the new transpose-and-pack function + mllm_kleidai_pack_b_and_bias_fp32_transpose(packed_b_data.data(), b_ptr_nxk, bias_ptr, N, K); + + // Call the original GEMM compute function with the packed data + mllm_kleidai_gemm_fp32(c_ptr, a_ptr, packed_b_data.data(), M, N, K); +} + +void mllm_kleidai_gemm_fp16_transpose(float *c_ptr, const float *a_ptr, const mllm_fp16_t *b_ptr_nxk, const float *bias_ptr, int M, int N, int K) { + // Allocate space for the packed B matrix + size_t packed_b_size = mllm_kleidai_get_packed_b_fp16_size(N, K); + std::vector packed_b_data(packed_b_size / sizeof(mllm_fp16_t)); + + // Call the new transpose-and-pack function + mllm_kleidai_pack_b_and_bias_fp16_transpose(packed_b_data.data(), b_ptr_nxk, bias_ptr, N, K); + + // Call the original GEMM compute function with the packed data + mllm_kleidai_gemm_fp16(c_ptr, a_ptr, packed_b_data.data(), M, N, K); +} + +// --- END: High-Level Transposed GEMM APIs --- + #endif \ No newline at end of file diff --git a/src/backends/cpu/compute/GemmKleidiai.hpp b/src/backends/cpu/compute/GemmKleidiai.hpp index 6f9cd4241..1b533ff14 100644 --- a/src/backends/cpu/compute/GemmKleidiai.hpp +++ b/src/backends/cpu/compute/GemmKleidiai.hpp @@ -15,7 +15,6 @@ static int kai_thread_count = 4; // --- 接口声明 --- -//#if defined(KLAI_USE_QSI4_C32) // --- 实现 1: float * qsi4c32 -> float (底层API) --- size_t mllm_kleidai_get_packed_b_qsi4_size(int N, int K); @@ -23,27 +22,26 @@ size_t mllm_kleidai_get_workspace_qsi4_size(int M, int K); void mllm_kleidai_pack_b_and_bias_qsi4(uint8_t* packed_b_ptr, const float* b_ptr, const float* bias_ptr, int N, int K); void mllm_kleidai_gemm_qsi4(float* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, int M, int N, int K); -// #endif // --- 实现 1.5: float * qsi4c32 -> fp16 (底层API) --- // 打包和工作区大小计算函数可以复用 USE_QSI4_C32 的 void mllm_kleidai_gemm_qsi4_to_fp16(mllm_fp16_t* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, int M, int N, int K); -//#if defined(KLAI_USE_FP16) // --- 实现 2: float * fp16 -> float (底层API) --- size_t mllm_kleidai_get_packed_b_fp16_size(int N, int K); void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t* packed_b_ptr, const mllm_fp16_t* b_ptr, const float* bias_ptr, int N, int K); void mllm_kleidai_gemm_fp16(float* c_ptr, const float* a_ptr, const mllm_fp16_t* packed_b_ptr, int M, int N, int K); -// #endif - -//#if defined(KLAI_USE_FP32) // --- 实现 3: float * fp32 -> float (底层API) --- size_t mllm_kleidai_get_packed_b_fp32_size(int N, int K); void mllm_kleidai_pack_b_and_bias_fp32(float* packed_b_ptr, const float* b_ptr, const float* bias_ptr, int N, int K); void mllm_kleidai_gemm_fp32(float* c_ptr, const float* a_ptr, const float* packed_b_ptr, int M, int N, int K); -// #endif + +// --- APIs for Transposed Right-Hand Matrix Multiplication --- +void mllm_kleidai_gemm_fp32_transpose(float* c_ptr, const float* a_ptr, const float* b_ptr_nxk, const float* bias_ptr, int M, int N, int K); +void mllm_kleidai_gemm_fp16_transpose(float* c_ptr, const float* a_ptr, const mllm_fp16_t* b_ptr_nxk, const float* bias_ptr, int M, int N, int K); + #endif \ No newline at end of file diff --git a/src/backends/cpu/compute/GemmAarch64.cpp b/src/backends/cpu/compute/GemmPack.cpp similarity index 95% rename from src/backends/cpu/compute/GemmAarch64.cpp rename to src/backends/cpu/compute/GemmPack.cpp index 933f01c54..93f2f2200 100644 --- a/src/backends/cpu/compute/GemmAarch64.cpp +++ b/src/backends/cpu/compute/GemmPack.cpp @@ -1,4 +1,4 @@ -#include "GemmAarch64.hpp" +#include "GemmPack.hpp" #include "Types.hpp" #include #include @@ -396,12 +396,78 @@ void mllm_gemv_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void * // "for optimal performance"); // } // #endif -// #if defined(__ARM_NEON) && defined(__ARM_FEATURE_MATMUL_INT8) -// assert(!(mllm_cpu_has_neon() && mllm_cpu_has_matmul_int8()) -// && "__ARM_NEON and __ARM_FEATURE_MATMUL_INT8 defined, use the Q4_0_4_8 " -// "quantization format for optimal performance"); -// #elif defined(__ARM_NEON) && defined(__aarch64__) -#if defined(__ARM_NEON) && defined(__aarch64__) +#if defined(__ARM_NEON) && defined(__ARM_FEATURE_MATMUL_INT8) + const block_q8_0 *a_ptr_base = (const block_q8_0 *)vy; + const block_q4_0x4 *b_ptr_base = (const block_q4_0x4 *)vx; + + for (int i_nc = 0; i_nc < nc; i_nc += ncols_interleaved) { + float *s_ptr = s + i_nc; + const block_q4_0x4 *b_ptr = b_ptr_base + (i_nc / ncols_interleaved) * nb; + const block_q8_0 *a_ptr = a_ptr_base; + __asm__ __volatile__( + "movi v16.4s, #0\n" // v16 = acc0 = [0, 0, 0, 0] (32-bit accumulators for 4 outputs) + "movi v17.4s, #0\n" // v17 = acc1 + "mov x5, %x[nb]\n" // x5 = nb (block counter) + "1:\n" // Main loop over blocks (nb) + // --- 加载 Scales --- + "ldrh w6, [%x[a_ptr], #0]\n" // Load d_a (fp16 scale) + "ldr s18, [%x[b_ptr], #0]\n" // Load d_b0, d_b1 + "ldr s19, [%x[b_ptr], #4]\n" // Load d_b2, d_b3 + "fmov s20, w6\n" // Move d_a to float register + "fcvtl v18.2s, v18.2h\n" // Convert d_b0, d_b1 to fp32 + "fcvtl v19.2s, v19.2h\n" // Convert d_b2, d_b3 to fp32 + "fcvtl v20.2s, v20.2h\n" // Convert d_a to fp32 + "dup v18.4s, v18.s[0]\n" // Broadcast d_b0 + "dup v19.4s, v19.s[0]\n" // Broadcast d_b2 + "dup v20.4s, v20.s[0]\n" // Broadcast d_a + // --- Q8向量数据加载 (a) --- + "ldr q0, [%x[a_ptr], #2]\n" // Load first 16 bytes of a->qs + "ldr q1, [%x[a_ptr], #18]\n" // Load second 16 bytes of a->qs + // --- Q4权重数据加载 (b) --- + "ldr q2, [%x[b_ptr], #8]\n" // Load first 16 bytes of b->qs + "ldr q3, [%x[b_ptr], #24]\n" // Load second 16 bytes of b->qs + // --- 解包 Q4.0 权重到 Q8.0 --- + // Unpack first 32x 4-bit quants into 32x 8-bit quants + "movi v21.16b, #0x0f\n" // low nibble mask + "movi v22.16b, #-8\n" // subtraction value + "and v4.16b, v2.16b, v21.16b\n" // low nibbles + "ushr v5.16b, v2.16b, #4\n" // high nibbles + "add v4.16b, v4.16b, v22.16b\n" // v4 = unpacked b quants 0..15 + "add v5.16b, v5.16b, v22.16b\n" // v5 = unpacked b quants 16..31 + // Unpack second 32x 4-bit quants + "and v6.16b, v3.16b, v21.16b\n" + "ushr v7.16b, v3.16b, #4\n" + "add v6.16b, v6.16b, v22.16b\n" // v6 + "add v7.16b, v7.16b, v22.16b\n" // v7 + // --- 执行 4x4 矩阵乘法 --- + // smmla acc, w, v + // The 4x4 matrix is formed by the 16 bytes in the register. + // We are doing a row-vector * matrix multiplication. The vector 'a' needs + // to be treated as rows of a matrix. + "smmla v16.4s, v4.16b, v0.16b\n" // acc0 += mat(v4) * mat(v0) + "smmla v17.4s, v5.16b, v0.16b\n" // acc1 += mat(v5) * mat(v0) + "smmla v16.4s, v6.16b, v1.16b\n" + "smmla v17.4s, v7.16b, v1.16b\n" + // --- 累加和转换 --- + "add v16.4s, v16.4s, v17.4s\n" // v16 has the final int32 sums for this block + "scvtf v17.4s, v16.4s\n" // Convert int32 sums to float32 + "fmul v18.4s, v18.4s, v20.4s\n" // multiply scales d_a * d_b + "fmla %v[sum].4s, v17.4s, v18.4s\n" // FMLA into final sum register + // --- 循环控制 --- + "add %x[a_ptr], %x[a_ptr], #34\n" // sizeof(block_q8_0) = 2+32 + "add %x[b_ptr], %x[b_ptr], #72\n" // sizeof(block_q4_0x4) = 8+64 + "subs x5, x5, #1\n" + "bne 1b\n" + // --- 存储结果 --- + "str q[sum], [%x[s_ptr]]\n" + : [sum] "+w"(s_ptr) // using "+w" for NEON registers + : [a_ptr] "r"(a_ptr), [b_ptr] "r"(b_ptr), [nb] "r"(nb), [s_ptr] "r"(s_ptr) + : "cc", "memory", "x5", "x6", + "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", + "v16", "v17", "v18", "v19", "v20", "v21", "v22"); + } +// AArch64 NEON (包括 Apple Silicon) 使用点积内联函数 +#elif defined(__ARM_NEON) && defined(__aarch64__) const void *b_ptr = vx; const void *a_ptr = vy; float *res_ptr = s; @@ -457,6 +523,88 @@ void mllm_gemv_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void * : [a_ptr] "r"(a_ptr), [nb] "r"(nb) : "memory", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", "x20", "x21", "x22"); +// x86 AVX-VNNI 和 AVX2 实现 +#elif defined(__AVX2__) +#define CALC_SUMI_PARTIAL(V_B_Q4, V_A0_S16, V_A1_S16) \ + ({ \ + /* v0 = (int8_t)(L<<4), v1 = (int8_t)(H<<4) */ \ + const __m128i low_nib_mask = _mm_set1_epi8(0x0F); \ + const __m128i v_L_nibbles = _mm_and_si128((V_B_Q4), low_nib_mask); \ + const __m128i v0s_u8 = _mm_slli_epi16(v_L_nibbles, 4); \ + const __m128i v1s_u8 = _mm_andnot_si128(low_nib_mask, (V_B_Q4)); \ + \ + /* 符号扩展到16位 */ \ + const __m128i v0s_s16 = _mm_cvtepi8_epi16(v0s_u8); \ + const __m128i v1s_s16 = _mm_cvtepi8_epi16(v1s_u8); \ + \ + /* 核心计算: (v0*a0 + v1*a1) >> 4 */ \ + const __m128i prod0 = _mm_mullo_epi16(v0s_s16, (V_A0_S16)); \ + const __m128i prod1 = _mm_mullo_epi16(v1s_s16, (V_A1_S16)); \ + const __m128i sum_prods_s16 = _mm_add_epi16(prod0, prod1); \ + const __m128i terms_s16 = _mm_srai_epi16(sum_prods_s16, 4); \ + \ + /* 水平求和 */ \ + const __m128i ones = _mm_set1_epi16(1); \ + const __m128i sums_s32 = _mm_madd_epi16(terms_s16, ones); \ + _mm_extract_epi32(sums_s32, 0) + _mm_extract_epi32(sums_s32, 1); \ + }) + + const block_q8_0 *a_ptr_base = (const block_q8_0 *)vy; + const block_q4_0x4 *b_ptr_base = (const block_q4_0x4 *)vx; + + // 外层循环:处理不同的4列输出组 + for (int x = 0; x < nc / ncols_interleaved; x++) { + const block_q4_0x4 *b_ptr = b_ptr_base + x * nb; + const block_q8_0 *a_ptr = a_ptr_base; + + float sumf[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + // 中层循环:处理数据块 + for (int l = 0; l < nb; l++) { + int32_t sumi_cols[4] = {0, 0, 0, 0}; + + // 内层循环:处理块内的子区域 (k) + for (int k = 0; k < (qk / (2 * blocklen)); k++) { + // 加载 a 向量的两个部分并符号扩展到16位 + const __m128i v_a0_s16 = _mm_cvtepi8_epi16(_mm_loadu_si32(a_ptr[l].qs + k * blocklen)); + const __m128i v_a1_s16 = _mm_cvtepi8_epi16(_mm_loadu_si32(a_ptr[l].qs + k * blocklen + qk / 2)); + + // 加载 b 权重的4x4字节区域 + const __m128i v_b_block = _mm_loadu_si128((const __m128i *)(b_ptr[l].qs + k * 16)); + + // ---- 循环展开: 手动处理 j = 0, 1, 2, 3 ---- + + // j = 0 + sumi_cols[0] += CALC_SUMI_PARTIAL(v_b_block, v_a0_s16, v_a1_s16); + + // j = 1 + sumi_cols[1] += CALC_SUMI_PARTIAL(_mm_srli_si128(v_b_block, 4), v_a0_s16, v_a1_s16); + + // j = 2 + sumi_cols[2] += CALC_SUMI_PARTIAL(_mm_srli_si128(v_b_block, 8), v_a0_s16, v_a1_s16); + + // j = 3 + sumi_cols[3] += CALC_SUMI_PARTIAL(_mm_srli_si128(v_b_block, 12), v_a0_s16, v_a1_s16); + } + + // --- 应用缩放因子并累加到浮点和 --- + const __m128i sumi_vec = _mm_loadu_si128((const __m128i *)sumi_cols); + const __m128 sumi_f = _mm_cvtepi32_ps(sumi_vec); + + const float d_a = MLLM_FP16_TO_FP32(a_ptr[l].d); + const __m128 d_b = _mm_cvtph_ps(_mm_loadu_si128((const __m128i *)b_ptr[l].d)); + const __m128 scales = _mm_mul_ps(_mm_set1_ps(d_a), d_b); + + __m128 current_sumf = _mm_loadu_ps(sumf); + current_sumf = _mm_add_ps(current_sumf, _mm_mul_ps(sumi_f, scales)); + _mm_storeu_ps(sumf, current_sumf); + } + + // 存储最终结果 + _mm_storeu_ps(s + x * ncols_interleaved, _mm_loadu_ps(sumf)); + } + // 确保宏只在当前代码块生效 +#undef CALC_SUMI_PARTIAL #else float sumf[4]; int sumi; diff --git a/src/backends/cpu/compute/GemmAarch64.hpp b/src/backends/cpu/compute/GemmPack.hpp similarity index 100% rename from src/backends/cpu/compute/GemmAarch64.hpp rename to src/backends/cpu/compute/GemmPack.hpp diff --git a/src/backends/cpu/compute/Split.hpp b/src/backends/cpu/compute/Split.hpp new file mode 100644 index 000000000..99f3c19e6 --- /dev/null +++ b/src/backends/cpu/compute/Split.hpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include // for memcpy + +// 引入 OpenMP 头文件 +#include + +// 引入SIMD头文件 +#if defined(__AVX__) +#include +#elif defined(__ARM_NEON) +#include +#endif + +/** + * @brief 高效地将一个4D张量按指定维度分割 (OpenMP并行版本) + * @param origin 输入的4D张量的裸指针 + * @param origin_dims 输入张量的维度信息,大小为4的数组,例如 {N, C, H, W} + * @param out 输出张量指针的向量 + * @param split_dims 每个输出张量在分割维度上的大小 + * @param dim_id 要进行分割的维度索引 (0到3) + */ +void efficient_split(const float *origin, const int *origin_dims, + std::vector &out, const std::vector &split_dims, + int dim_id) { + // --- 1. 输入验证 --- + if (dim_id < 0 || dim_id > 3) { + throw std::invalid_argument("Error: dim_id must be between 0 and 3."); + } + + int total_split_dim = std::accumulate(split_dims.begin(), split_dims.end(), 0); + if (total_split_dim != origin_dims[dim_id]) { + throw std::invalid_argument("Error: Sum of split_dims must be equal to the dimension size of origin tensor."); + } + + if (out.size() != split_dims.size()) { + throw std::invalid_argument("Error: The size of 'out' vector must be equal to the size of 'split_dims' vector."); + } + + // --- 2. 计算步长和循环尺寸 --- + int strides[4]; + strides[3] = 1; + for (int i = 2; i >= 0; --i) { + strides[i] = strides[i + 1] * origin_dims[i + 1]; + } + + int outer_loop_size = 1; + for (int i = 0; i < dim_id; ++i) { + outer_loop_size *= origin_dims[i]; + } + + int inner_loop_size = strides[dim_id]; + int original_dim_size_at_split_axis = origin_dims[dim_id] * inner_loop_size; + + // --- 3. 为并行计算预先计算偏移量 --- + // 为了使主循环能够并行化,我们需要为每个输出张量预先计算其在源张量中的起始偏移量。 + // 这避免了在循环中依赖于前一次迭代结果的顺序更新。 + std::vector split_offsets(split_dims.size() + 1, 0); + for (size_t i = 0; i < split_dims.size(); ++i) { + split_offsets[i + 1] = split_offsets[i] + split_dims[i]; + } + + // --- 4. 并行处理 --- + // 使用 OpenMP 对主循环进行并行化。 + // OpenMP 会自动根据系统配置或 OMP_NUM_THREADS 环境变量来决定使用的线程数。 + // 循环变量 'i' 默认是私有的。所有在循环外声明的变量都是共享的, + // 这在这里是安全的,因为它们在并行区域内是只读的(除了 'out',但每个线程访问 out[i],不会冲突)。 + #pragma omp parallel for + for (size_t i = 0; i < out.size(); ++i) { + float *out_ptr = out[i]; + const int split_size = split_dims[i]; + const int offset_in_dim = split_offsets[i]; + + // 遍历所有不被分割的外部维度 + for (int outer_idx = 0; outer_idx < outer_loop_size; ++outer_idx) { + // 计算源和目标在当前外部维度块的基地址 + const float *src_base = origin + outer_idx * original_dim_size_at_split_axis + offset_in_dim * inner_loop_size; + float *dst_base = out_ptr + outer_idx * split_size * inner_loop_size; + + // 沿着分割轴,拷贝 'split_size' 个大小为 'inner_loop_size' 的数据块 + for (int split_idx = 0; split_idx < split_size; ++split_idx) { + const float *src = src_base + split_idx * inner_loop_size; + float *dst = dst_base + split_idx * inner_loop_size; + int count = inner_loop_size; + + // 使用SIMD指令集进行高效的内存拷贝 +#if defined(__AVX__) + for (; count >= 8; count -= 8) { + __m256 data = _mm256_loadu_ps(src); + _mm256_storeu_ps(dst, data); + src += 8; + dst += 8; + } +#elif defined(__ARM_NEON) + for (; count >= 4; count -= 4) { + float32x4_t data = vld1q_f32(src); + vst1q_f32(dst, data); + src += 4; + dst += 4; + } +#endif + // 处理剩余不足一个SIMD寄存器大小的数据 + for (; count > 0; --count) { + *dst++ = *src++; + } + } + } + } +} \ No newline at end of file diff --git a/src/backends/cpu/compute/Transpose2D.hpp b/src/backends/cpu/compute/Transpose2D.hpp new file mode 100644 index 000000000..055066032 --- /dev/null +++ b/src/backends/cpu/compute/Transpose2D.hpp @@ -0,0 +1,262 @@ +#pragma once +#include +#include "Types.hpp" + +// 为不同平台引入对应的 SIMD 指令集头文件 +#if defined(__AVX__) || defined(__AVX2__) +#include // Intel/AMD AVX 指令集 +#elif defined(__aarch64__) +#include // ARM NEON 指令集 +#endif + +/** + * @brief 使用 SIMD 指令 (AVX) 转置一个 8x8 的浮点数矩阵块。 + * @param src 指向源数据块左上角的指针 + * @param dst 指向目标数据块左上角的指针 + * @param src_stride 源矩阵的行步长 (即列数) + * @param dst_stride 目标矩阵的行步长 (即转置前的行数) + */ +#if defined(__AVX__) || defined(__AVX2__) +static inline void transpose_block_8x8_avx(const float* src, float* dst, const int src_stride, const int dst_stride) { + // 1. 从源矩阵加载8行数据到8个AVX寄存器 + __m256 row0 = _mm256_loadu_ps(src + 0 * src_stride); + __m256 row1 = _mm256_loadu_ps(src + 1 * src_stride); + __m256 row2 = _mm256_loadu_ps(src + 2 * src_stride); + __m256 row3 = _mm256_loadu_ps(src + 3 * src_stride); + __m256 row4 = _mm256_loadu_ps(src + 4 * src_stride); + __m256 row5 = _mm256_loadu_ps(src + 5 * src_stride); + __m256 row6 = _mm256_loadu_ps(src + 6 * src_stride); + __m256 row7 = _mm256_loadu_ps(src + 7 * src_stride); + + // 2. 在寄存器内进行 8x8 矩阵的转置 (这是一个标准的多步shuffle操作) + __m256 t0, t1, t2, t3, t4, t5, t6, t7; + t0 = _mm256_unpacklo_ps(row0, row1); + t1 = _mm256_unpackhi_ps(row0, row1); + t2 = _mm256_unpacklo_ps(row2, row3); + t3 = _mm256_unpackhi_ps(row2, row3); + t4 = _mm256_unpacklo_ps(row4, row5); + t5 = _mm256_unpackhi_ps(row4, row5); + t6 = _mm256_unpacklo_ps(row6, row7); + t7 = _mm256_unpackhi_ps(row6, row7); + + __m256 tt0, tt1, tt2, tt3, tt4, tt5, tt6, tt7; + tt0 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(1, 0, 1, 0)); + tt1 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 2, 3, 2)); + tt2 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(1, 0, 1, 0)); + tt3 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(3, 2, 3, 2)); + tt4 = _mm256_shuffle_ps(t4, t6, _MM_SHUFFLE(1, 0, 1, 0)); + tt5 = _mm256_shuffle_ps(t4, t6, _MM_SHUFFLE(3, 2, 3, 2)); + tt6 = _mm256_shuffle_ps(t5, t7, _MM_SHUFFLE(1, 0, 1, 0)); + tt7 = _mm256_shuffle_ps(t5, t7, _MM_SHUFFLE(3, 2, 3, 2)); + + row0 = _mm256_permute2f128_ps(tt0, tt4, 0x20); + row1 = _mm256_permute2f128_ps(tt1, tt5, 0x20); + row2 = _mm256_permute2f128_ps(tt2, tt6, 0x20); + row3 = _mm256_permute2f128_ps(tt3, tt7, 0x20); + row4 = _mm256_permute2f128_ps(tt0, tt4, 0x31); + row5 = _mm256_permute2f128_ps(tt1, tt5, 0x31); + row6 = _mm256_permute2f128_ps(tt2, tt6, 0x31); + row7 = _mm256_permute2f128_ps(tt3, tt7, 0x31); + + // 3. 将转置后的8个寄存器(现在是8列)写回到目标矩阵 + _mm256_storeu_ps(dst + 0 * dst_stride, row0); + _mm256_storeu_ps(dst + 1 * dst_stride, row1); + _mm256_storeu_ps(dst + 2 * dst_stride, row2); + _mm256_storeu_ps(dst + 3 * dst_stride, row3); + _mm256_storeu_ps(dst + 4 * dst_stride, row4); + _mm256_storeu_ps(dst + 5 * dst_stride, row5); + _mm256_storeu_ps(dst + 6 * dst_stride, row6); + _mm256_storeu_ps(dst + 7 * dst_stride, row7); +} +#endif + +/** + * @brief 使用 SIMD 指令 (NEON) 转置一个 4x4 的浮点数矩阵块。 + * @param src 指向源数据块左上角的指针 + * @param dst 指向目标数据块左上角的指针 + * @param src_stride 源矩阵的行步长 (即列数) + * @param dst_stride 目标矩阵的行步长 (即转置前的行数) + */ +#if defined(__aarch64__) +static inline void transpose_block_4x4_neon(const float* src, float* dst, const int src_stride, const int dst_stride) { + // 1. 从源矩阵加载4行数据,每行4个float + float32x4_t row0 = vld1q_f32(src + 0 * src_stride); + float32x4_t row1 = vld1q_f32(src + 1 * src_stride); + float32x4_t row2 = vld1q_f32(src + 2 * src_stride); + float32x4_t row3 = vld1q_f32(src + 3 * src_stride); + + // 2. 使用 VTRN 指令对 4x4 矩阵进行转置 + // 第一次 VTRN, 两两交换元素 + float32x4x2_t p01 = vtrnq_f32(row0, row1); // p01.val[0] = {r0[0], r1[0], r0[2], r1[2]}, p01.val[1] = {r0[1], r1[1], r0[3], r1[3]} + float32x4x2_t p23 = vtrnq_f32(row2, row3); // p23.val[0] = {r2[0], r3[0], r2[2], r3[2]}, p23.val[1] = {r2[1], r3[1], r2[3], r3[3]} + + // 3. 提取并组合成最终的转置结果 + // 从 p01 和 p23 中提取低位的 64bit (2个float) 并组合 + // res0 = {r0[0], r1[0], r2[0], r3[0]} + float32x4_t res0 = vcombine_f32(vget_low_f32(p01.val[0]), vget_low_f32(p23.val[0])); + // 从 p01 和 p23 中提取高位的 64bit (2个float) 并组合 + // res1 = {r0[1], r1[1], r2[1], r3[1]} + float32x4_t res1 = vcombine_f32(vget_low_f32(p01.val[1]), vget_low_f32(p23.val[1])); + float32x4_t res2 = vcombine_f32(vget_high_f32(p01.val[0]), vget_high_f32(p23.val[0])); + float32x4_t res3 = vcombine_f32(vget_high_f32(p01.val[1]), vget_high_f32(p23.val[1])); + + // 4. 将转置后的4个寄存器(现在是4列)写回到目标矩阵 + vst1q_f32(dst + 0 * dst_stride, res0); + vst1q_f32(dst + 1 * dst_stride, res1); + vst1q_f32(dst + 2 * dst_stride, res2); + vst1q_f32(dst + 3 * dst_stride, res3); +} +#endif + +/** + * @brief 对一个二维浮点数矩阵进行高效转置 (dst = src^T)。 + * 自动检测平台并使用 AVX 或 NEON 指令进行加速。 + * 如果平台不支持,则回退到缓存优化的C++实现。 + * @param src 指向源矩阵 (N x M) 的指针 + * @param dst 指向目标矩阵 (M x N) 的指针 + * @param N 源矩阵的行数 + * @param M 源矩阵的列数 + */ +void transpose_matrix_efficient(const float* src, float* dst, const int N, const int M) { +#if defined(__AVX__) || defined(__AVX2__) + const int BLOCK_DIM = 8; + // 使用8x8分块处理大部分矩阵 + for (int i = 0; i < N / BLOCK_DIM * BLOCK_DIM; i += BLOCK_DIM) { + for (int j = 0; j < M / BLOCK_DIM * BLOCK_DIM; j += BLOCK_DIM) { + transpose_block_8x8_avx(src + i * M + j, dst + j * N + i, M, N); + } + } + // 处理右侧和下方的剩余部分 + for (int i = 0; i < N; ++i) { + for (int j = M / BLOCK_DIM * BLOCK_DIM; j < M; ++j) { + dst[j * N + i] = src[i * M + j]; + } + } + for (int i = N / BLOCK_DIM * BLOCK_DIM; i < N; ++i) { + for (int j = 0; j < M / BLOCK_DIM * BLOCK_DIM; ++j) { + dst[j * N + i] = src[i * M + j]; + } + } + +#elif defined(__aarch64__) + const int BLOCK_DIM = 4; + // 使用4x4分块处理大部分矩阵 + for (int i = 0; i < N / BLOCK_DIM * BLOCK_DIM; i += BLOCK_DIM) { + for (int j = 0; j < M / BLOCK_DIM * BLOCK_DIM; j += BLOCK_DIM) { + transpose_block_4x4_neon(src + i * M + j, dst + j * N + i, M, N); + } + } + // 处理剩余部分 + for (int i = 0; i < N; ++i) { + for (int j = M / BLOCK_DIM * BLOCK_DIM; j < M; ++j) { + dst[j * N + i] = src[i * M + j]; + } + } + for (int i = N / BLOCK_DIM * BLOCK_DIM; i < N; ++i) { + for (int j = 0; j < M / BLOCK_DIM * BLOCK_DIM; ++j) { + dst[j * N + i] = src[i * M + j]; + } + } + +#else + // 通用C++回退方案 (无SIMD,但有缓存分块优化) + const int BLOCK_DIM = 16; + for (int i = 0; i < N; i += BLOCK_DIM) { + for (int j = 0; j < M; j += BLOCK_DIM) { + // 转置当前块 + for (int bi = i; bi < i + BLOCK_DIM && bi < N; ++bi) { + for (int bj = j; bj < j + BLOCK_DIM && bj < M; ++bj) { + dst[bj * N + bi] = src[bi * M + bj]; + } + } + } + } +#endif +} + + +// --- BEGIN: High-Performance FP16 Transpose Function for ARM NEON --- + +#if defined(__aarch64__) + +/** + * @brief 使用ARM NEON指令高效转置一个 8x8 的 __fp16 矩阵块。 + * 【已修正】使用了正确的 VTRN/VZIP 指令序列,避免了 vtrnq_f64 错误。 + * @param src 指向源数据块左上角的指针 (__fp16) + * @param dst 指向目标数据块左上角的指针 (__fp16) + * @param src_stride 源矩阵的行步长 (即列数) + * @param dst_stride 目标矩阵的行步长 (即转置前的行数) + */ +static inline void transpose_block_8x8_neon_fp16(const __fp16* src, __fp16* dst, const int src_stride, const int dst_stride) { + // 1. Load 8 rows from source matrix into 8 NEON registers + float16x8_t r0 = vld1q_f16(src + 0 * src_stride); + float16x8_t r1 = vld1q_f16(src + 1 * src_stride); + float16x8_t r2 = vld1q_f16(src + 2 * src_stride); + float16x8_t r3 = vld1q_f16(src + 3 * src_stride); + float16x8_t r4 = vld1q_f16(src + 4 * src_stride); + float16x8_t r5 = vld1q_f16(src + 5 * src_stride); + float16x8_t r6 = vld1q_f16(src + 6 * src_stride); + float16x8_t r7 = vld1q_f16(src + 7 * src_stride); + + // 2. Perform in-register transpose using VTRN and VZIP + // Stage 1: Transpose 2x2 blocks of __fp16 elements + float16x8x2_t t01 = vtrnq_f16(r0, r1); + float16x8x2_t t23 = vtrnq_f16(r2, r3); + float16x8x2_t t45 = vtrnq_f16(r4, r5); + float16x8x2_t t67 = vtrnq_f16(r6, r7); + + // Stage 2: Transpose 4x4 blocks by zipping 32-bit (2x fp16) chunks + float32x4x2_t z02 = vzipq_f32(vreinterpretq_f32_f16(t01.val[0]), vreinterpretq_f32_f16(t23.val[0])); + float32x4x2_t z13 = vzipq_f32(vreinterpretq_f32_f16(t01.val[1]), vreinterpretq_f32_f16(t23.val[1])); + float32x4x2_t z46 = vzipq_f32(vreinterpretq_f32_f16(t45.val[0]), vreinterpretq_f32_f16(t67.val[0])); + float32x4x2_t z57 = vzipq_f32(vreinterpretq_f32_f16(t45.val[1]), vreinterpretq_f32_f16(t67.val[1])); + + // 3. Store the transposed 8x8 block to the destination matrix + vst1q_f16(dst + 0 * dst_stride, vreinterpretq_f16_f32(z02.val[0])); + vst1q_f16(dst + 1 * dst_stride, vreinterpretq_f16_f32(z13.val[0])); + vst1q_f16(dst + 2 * dst_stride, vreinterpretq_f16_f32(z02.val[1])); + vst1q_f16(dst + 3 * dst_stride, vreinterpretq_f16_f32(z13.val[1])); + vst1q_f16(dst + 4 * dst_stride, vreinterpretq_f16_f32(z46.val[0])); + vst1q_f16(dst + 5 * dst_stride, vreinterpretq_f16_f32(z57.val[0])); + vst1q_f16(dst + 6 * dst_stride, vreinterpretq_f16_f32(z46.val[1])); + vst1q_f16(dst + 7 * dst_stride, vreinterpretq_f16_f32(z57.val[1])); +} +/** + * @brief 对一个 mllm_fp16_t 矩阵进行高效转置 (dst = src^T)。 + * 在 aarch64 平台上,此函数使用 NEON SIMD 指令进行极致加速。 + * 在其他平台,回退到缓存优化的C++实现。 + * @param src 指向源矩阵 (N x M) 的指针 + * @param dst 指向目标矩阵 (M x N) 的指针 + * @param N 源矩阵的行数 + * @param M 源矩阵的列数 + */ +void transpose_matrix_efficient_fp16(const mllm_fp16_t* src, mllm_fp16_t* dst, const int N, const int M) { + const int BLOCK_DIM = 8; + // Use an 8x8 block loop to process the majority of the matrix + for (int i = 0; i < N / BLOCK_DIM * BLOCK_DIM; i += BLOCK_DIM) { + for (int j = 0; j < M / BLOCK_DIM * BLOCK_DIM; j += BLOCK_DIM) { + // On ARM, mllm_fp16_t is __fp16, so we can call the NEON helper directly + transpose_block_8x8_neon_fp16( + (const __fp16*)(src + i * M + j), + (__fp16*)(dst + j * N + i), + M, N + ); + } + } + + // Process the remaining rows and columns on the edges using standard C++ + for (int i = 0; i < N; ++i) { + for (int j = M / BLOCK_DIM * BLOCK_DIM; j < M; ++j) { + dst[j * N + i] = src[i * M + j]; + } + } + for (int i = N / BLOCK_DIM * BLOCK_DIM; i < N; ++i) { + for (int j = 0; j < M / BLOCK_DIM * BLOCK_DIM; ++j) { + dst[j * N + i] = src[i * M + j]; + } + } +} + +#endif // __aarch64__ + +// --- END: High-Performance FP16 Transpose Function for ARM NEON --- \ No newline at end of file diff --git a/src/backends/cpu/compute/Transpose3D.hpp b/src/backends/cpu/compute/Transpose3D.hpp new file mode 100644 index 000000000..229ba4edd --- /dev/null +++ b/src/backends/cpu/compute/Transpose3D.hpp @@ -0,0 +1,220 @@ +#pragma once + +#include +#include +#include +#include +#include // 用于 memcpy + +// 为不同平台引入对应的 SIMD 指令集头文件 +#if defined(__AVX__) || defined(__AVX2__) +#include // Intel/AMD AVX & AVX2 指令集 +#elif defined(__aarch64__) +#include // ARM NEON 指令集 +#endif + +// 引入 OpenMP 头文件以支持多线程并行 +#include + +/** + * @brief 定义一个命名空间来组织张量操作相关函数 + */ +// namespace TensorOps { + +// --- BEGIN: 高性能 2D 转置核心 (从 Transpose2D.hpp 集成) --- +// 这部分代码与上一版完全相同,此处为了完整性而保留。 +// SIMD指令集优化代码... +#if defined(__AVX__) || defined(__AVX2__) +static inline void transpose_block_8x8_avx(const float *src, float *dst, const int src_stride, const int dst_stride) { + __m256 row0 = _mm256_loadu_ps(src + 0 * src_stride); + __m256 row1 = _mm256_loadu_ps(src + 1 * src_stride); + __m256 row2 = _mm256_loadu_ps(src + 2 * src_stride); + __m256 row3 = _mm256_loadu_ps(src + 3 * src_stride); + __m256 row4 = _mm256_loadu_ps(src + 4 * src_stride); + __m256 row5 = _mm256_loadu_ps(src + 5 * src_stride); + __m256 row6 = _mm256_loadu_ps(src + 6 * src_stride); + __m256 row7 = _mm256_loadu_ps(src + 7 * src_stride); + __m256 t0, t1, t2, t3, t4, t5, t6, t7; + t0 = _mm256_unpacklo_ps(row0, row1); + t1 = _mm256_unpackhi_ps(row0, row1); + t2 = _mm256_unpacklo_ps(row2, row3); + t3 = _mm256_unpackhi_ps(row2, row3); + t4 = _mm256_unpacklo_ps(row4, row5); + t5 = _mm256_unpackhi_ps(row4, row5); + t6 = _mm256_unpacklo_ps(row6, row7); + t7 = _mm256_unpackhi_ps(row6, row7); + __m256 tt0, tt1, tt2, tt3, tt4, tt5, tt6, tt7; + tt0 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(1, 0, 1, 0)); + tt1 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 2, 3, 2)); + tt2 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(1, 0, 1, 0)); + tt3 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(3, 2, 3, 2)); + tt4 = _mm256_shuffle_ps(t4, t6, _MM_SHUFFLE(1, 0, 1, 0)); + tt5 = _mm256_shuffle_ps(t4, t6, _MM_SHUFFLE(3, 2, 3, 2)); + tt6 = _mm256_shuffle_ps(t5, t7, _MM_SHUFFLE(1, 0, 1, 0)); + tt7 = _mm256_shuffle_ps(t5, t7, _MM_SHUFFLE(3, 2, 3, 2)); + row0 = _mm256_permute2f128_ps(tt0, tt4, 0x20); + row1 = _mm256_permute2f128_ps(tt1, tt5, 0x20); + row2 = _mm256_permute2f128_ps(tt2, tt6, 0x20); + row3 = _mm256_permute2f128_ps(tt3, tt7, 0x20); + row4 = _mm256_permute2f128_ps(tt0, tt4, 0x31); + row5 = _mm256_permute2f128_ps(tt1, tt5, 0x31); + row6 = _mm256_permute2f128_ps(tt2, tt6, 0x31); + row7 = _mm256_permute2f128_ps(tt3, tt7, 0x31); + _mm256_storeu_ps(dst + 0 * dst_stride, row0); + _mm256_storeu_ps(dst + 1 * dst_stride, row1); + _mm256_storeu_ps(dst + 2 * dst_stride, row2); + _mm256_storeu_ps(dst + 3 * dst_stride, row3); + _mm256_storeu_ps(dst + 4 * dst_stride, row4); + _mm256_storeu_ps(dst + 5 * dst_stride, row5); + _mm256_storeu_ps(dst + 6 * dst_stride, row6); + _mm256_storeu_ps(dst + 7 * dst_stride, row7); +} +#endif +#if defined(__aarch64__) +static inline void transpose_block_4x4_neon(const float *src, float *dst, const int src_stride, const int dst_stride) { + float32x4_t row0 = vld1q_f32(src + 0 * src_stride); + float32x4_t row1 = vld1q_f32(src + 1 * src_stride); + float32x4_t row2 = vld1q_f32(src + 2 * src_stride); + float32x4_t row3 = vld1q_f32(src + 3 * src_stride); + float32x4x2_t p01 = vtrnq_f32(row0, row1); + float32x4x2_t p23 = vtrnq_f32(row2, row3); + float32x4_t res0 = vcombine_f32(vget_low_f32(p01.val[0]), vget_low_f32(p23.val[0])); + float32x4_t res1 = vcombine_f32(vget_low_f32(p01.val[1]), vget_low_f32(p23.val[1])); + float32x4_t res2 = vcombine_f32(vget_high_f32(p01.val[0]), vget_high_f32(p23.val[0])); + float32x4_t res3 = vcombine_f32(vget_high_f32(p01.val[1]), vget_high_f32(p23.val[1])); + vst1q_f32(dst + 0 * dst_stride, res0); + vst1q_f32(dst + 1 * dst_stride, res1); + vst1q_f32(dst + 2 * dst_stride, res2); + vst1q_f32(dst + 3 * dst_stride, res3); +} +#endif +static inline void transpose_matrix_2d_efficient(const float *src, float *dst, const int N, const int M) { +#if defined(__AVX__) || defined(__AVX2__) + const int BLOCK_DIM = 8; + for (int i = 0; i < N - (N % BLOCK_DIM); i += BLOCK_DIM) { + for (int j = 0; j < M - (M % BLOCK_DIM); j += BLOCK_DIM) { + transpose_block_8x8_avx(src + i * M + j, dst + j * N + i, M, N); + } + } + for (int i = 0; i < N; ++i) { + for (int j = M - (M % BLOCK_DIM); j < M; ++j) { dst[j * N + i] = src[i * M + j]; } + } + for (int i = N - (N % BLOCK_DIM); i < N; ++i) { + for (int j = 0; j < M - (M % BLOCK_DIM); ++j) { dst[j * N + i] = src[i * M + j]; } + } +#elif defined(__aarch64__) + const int BLOCK_DIM = 4; + for (int i = 0; i < N - (N % BLOCK_DIM); i += BLOCK_DIM) { + for (int j = 0; j < M - (M % BLOCK_DIM); j += BLOCK_DIM) { + transpose_block_4x4_neon(src + i * M + j, dst + j * N + i, M, N); + } + } + for (int i = 0; i < N; ++i) { + for (int j = M - (M % BLOCK_DIM); j < M; ++j) { dst[j * N + i] = src[i * M + j]; } + } + for (int i = N - (N % BLOCK_DIM); i < N; ++i) { + for (int j = 0; j < M - (M % BLOCK_DIM); ++j) { dst[j * N + i] = src[i * M + j]; } + } +#else + const int BLOCK_DIM = 16; + for (int i = 0; i < N; i += BLOCK_DIM) { + for (int j = 0; j < M; j += BLOCK_DIM) { + for (int bi = i; bi < i + BLOCK_DIM && bi < N; ++bi) { + for (int bj = j; bj < j + BLOCK_DIM && bj < M; ++bj) { + dst[bj * N + bi] = src[bi * M + bj]; + } + } + } + } +#endif +} + +// --- END: 高性能 2D 转置核心 --- + +/** + * @brief 对一个三维浮点数张量进行高效转置 (终极版: SIMD + OpenMP)。 + * 该函数根据指定的维度置换 (permutation) 来重新排列数据。 + * + * @param src 指向源张量数据的指针。数据布局为 (D1, D2, D3) 的稠密行主序。 + * @param dst 指向目标张量数据的指针。其维度根据 perm 计算得出。 + * @param d1 源张量的第 1 维大小 + * @param d2 源张量的第 2 维大小 + * @param d3 源张量的第 3 维大小 + * @param perm 一个包含 {0, 1, 2} 的置换向量,定义了转置方式。 + */ +void transpose3d_efficient(const float *src, float *dst, int d1, int d2, int d3, const std::vector &perm) { + // --- 1. 输入验证 --- + if (perm.size() != 3) { + throw std::invalid_argument("Permutation vector must contain 3 elements."); + } + std::vector sorted_perm = perm; + std::sort(sorted_perm.begin(), sorted_perm.end()); + if (sorted_perm[0] != 0 || sorted_perm[1] != 1 || sorted_perm[2] != 2) { + throw std::invalid_argument("Permutation vector must be a permutation of {0, 1, 2}."); + } + + const int src_dims[3] = {d1, d2, d3}; + + // --- 2. 处理特殊情况:无需转置 --- + if (perm[0] == 0 && perm[1] == 1 && perm[2] == 2) { + const size_t total_elements = static_cast(d1) * d2 * d3; + if (src != dst) { + memcpy(dst, src, total_elements * sizeof(float)); + } + return; + } + + // --- 3. 性能最优路径:只交换最后两个维度 (e.g., NHW -> NWH) --- + // 【OpenMP + SIMD 加速】 + // OpenMP 将d1个二维切片的转置任务分配给多个线程,每个线程内部使用SIMD指令高速完成自己的任务。 + if (perm[0] == 0 && perm[1] == 2 && perm[2] == 1) { + const int N = d2; + const int M = d3; +#pragma omp parallel for schedule(static) + for (int i = 0; i < d1; ++i) { + const float *src_slice = src + i * (N * M); + float *dst_slice = dst + i * (M * N); + transpose_matrix_2d_efficient(src_slice, dst_slice, N, M); + } + return; + } + + // --- 4. 通用路径:处理所有其他维度置换 --- + // 【OpenMP 加速】 + // OpenMP 将最外层循环并行化,每个线程负责处理目标张量的一个或多个“块板”(slab of blocks)。 + // 内部依然使用缓存分块来优化每个线程的执行效率。 + const int dst_dims[3] = {src_dims[perm[0]], src_dims[perm[1]], src_dims[perm[2]]}; + const int BLOCK_DIM = 16; + + long src_strides[3] = {(long)d2 * d3, d3, 1}; + long dst_strides[3] = {(long)dst_dims[1] * dst_dims[2], dst_dims[2], 1}; + + int p_inv[3]; + p_inv[perm[0]] = 0; + p_inv[perm[1]] = 1; + p_inv[perm[2]] = 2; + +#pragma omp parallel for schedule(static) + for (int i0 = 0; i0 < dst_dims[0]; i0 += BLOCK_DIM) { + for (int j0 = 0; j0 < dst_dims[1]; j0 += BLOCK_DIM) { + for (int k0 = 0; k0 < dst_dims[2]; k0 += BLOCK_DIM) { + for (int i = i0; i < i0 + BLOCK_DIM && i < dst_dims[0]; ++i) { + for (int j = j0; j < j0 + BLOCK_DIM && j < dst_dims[1]; ++j) { + for (int k = k0; k < k0 + BLOCK_DIM && k < dst_dims[2]; ++k) { + long dst_idx = (long)i * dst_strides[0] + (long)j * dst_strides[1] + k; + int dst_coords[3] = {i, j, k}; + int src_coords[3]; + src_coords[p_inv[0]] = dst_coords[0]; + src_coords[p_inv[1]] = dst_coords[1]; + src_coords[p_inv[2]] = dst_coords[2]; + long src_idx = (long)src_coords[0] * src_strides[0] + (long)src_coords[1] * src_strides[1] + src_coords[2]; + dst[dst_idx] = src[src_idx]; + } + } + } + } + } + } +} + +// } // namespace TensorOps \ No newline at end of file diff --git a/src/backends/cpu/compute/VecDotType.cpp b/src/backends/cpu/compute/VecDotType.cpp index 5925e6e07..9548be4bb 100644 --- a/src/backends/cpu/compute/VecDotType.cpp +++ b/src/backends/cpu/compute/VecDotType.cpp @@ -32,7 +32,7 @@ #include "Types.hpp" #include "Quantize.hpp" #include "VecDot.hpp" -#include "GemmAarch64.hpp" +#include "GemmPack.hpp" void fp32_add_row_to(int n, const float *MLLM_RESTRICT src, float *MLLM_RESTRICT dst, float alpha) { int i = 0; diff --git a/src/backends/cpu/function/CPUFlashAttention2Func.hpp b/src/backends/cpu/function/CPUFlashAttention2Func.hpp index 6ae558982..a45cf1949 100644 --- a/src/backends/cpu/function/CPUFlashAttention2Func.hpp +++ b/src/backends/cpu/function/CPUFlashAttention2Func.hpp @@ -8,6 +8,7 @@ #include "Tensor.hpp" #include "Types.hpp" #include "../compute/FlashAttention2.hpp" +#include "../compute/FlashAttention2H.hpp" namespace mllm { class Tensor; @@ -23,6 +24,11 @@ class CPUFlashAttention2Func : public TensorFunction { int q_head = q_tensor->head(); int q_sequence = q_tensor->sequence(); int dimension = q_tensor->dimension(); + // for BSHD attention start + if(inputs[0]->ctype()==BHSD && inputs[1]->ctype()==BHSD && inputs[1]->ctype()==BHSD ){ + o_tensor->setCtype(q_tensor->ctype()); + } + // for BSHD attention end o_tensor->reshape(batch_size, q_head, q_sequence, dimension); o_tensor->setDtype(inputs[0]->dtype()); o_tensor->alloc(); @@ -50,24 +56,46 @@ class CPUFlashAttention2Func : public TensorFunction { int32_t br = q_sequence >= 4 ? 4 : 1; int32_t bc = q_sequence >= 4 ? 4 : 1; constexpr bool high_precision_exp = false; - // q_tensor->saveData(); - // k_tensor->saveData(); - // v_tensor->saveData(); - // GQA is not ready - flash_attention_2_forward( - q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), - o_tensor->hostPtr(), // 输入输出张量 - batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 - causal_mask, // 使用因果掩码 - kv_use_fp32, // 使用FP32(x86必须) - threads, // 使用4线程 - br, // 查询分块大小64 - bc, // 键值分块大小128 - q_head, // 查询头数12 - k_head, // 键值头数4 - high_precision_exp // 使用快速指数近似 - ); - // o_tensor->saveData(); + // for BSHD attention start + if(inputs[0]->ctype()==BHSD && inputs[1]->ctype()==BHSD && inputs[1]->ctype()==BHSD ){ + int km = k_sequence; + int vm = v_sequence; + if(k_tensor->masterTensor()!=nullptr && v_tensor->masterTensor()!=nullptr){ + km = k_tensor->masterTensor()->sequence(); + vm = v_tensor->masterTensor()->sequence(); + } + flash_attention_2_forward_h( + q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), + o_tensor->hostPtr(), // 输入输出张量 + batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 + causal_mask, // 使用因果掩码 + kv_use_fp32, // 使用FP32(x86必须) + threads, // 使用4线程 + br, // 查询分块大小64 + bc, // 键值分块大小128 + q_head, // 查询头数12 + k_head, // 键值头数4 + high_precision_exp, // 使用快速指数近似 + q_sequence*dimension, + km*dimension, + vm*dimension + ); + // for BSHD attention end + }else{ + flash_attention_2_forward( + q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), + o_tensor->hostPtr(), // 输入输出张量 + batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 + causal_mask, // 使用因果掩码 + kv_use_fp32, // 使用FP32(x86必须) + threads, // 使用4线程 + br, // 查询分块大小64 + bc, // 键值分块大小128 + q_head, // 查询头数12 + k_head, // 键值头数4 + high_precision_exp // 使用快速指数近似 + ); + } } }; } // namespace mllm diff --git a/src/backends/cpu/function/CPUMatmulFunc.hpp b/src/backends/cpu/function/CPUMatmulFunc.hpp index 647d20b9e..2702752c2 100644 --- a/src/backends/cpu/function/CPUMatmulFunc.hpp +++ b/src/backends/cpu/function/CPUMatmulFunc.hpp @@ -9,7 +9,6 @@ #include "Types.hpp" #include "../compute/Matmul.hpp" #include - namespace mllm { class Tensor; diff --git a/src/backends/cpu/function/CPUSplitFunc.hpp b/src/backends/cpu/function/CPUSplitFunc.hpp index 7b7ac0131..088d3b9c9 100644 --- a/src/backends/cpu/function/CPUSplitFunc.hpp +++ b/src/backends/cpu/function/CPUSplitFunc.hpp @@ -6,7 +6,8 @@ #define CPUSPLITFUNC_HPP #include "Tensor.hpp" #include "Types.hpp" - +#include "../compute/Split.hpp" +#include namespace mllm { class Tensor; @@ -70,90 +71,96 @@ class CPUsplitFunction : public TensorFunction { break; } } - vector> shared_outputs = {}; - for (const auto &output : outputs) { - output->alloc(); - shared_outputs.push_back(output); - } - if (inputs[0]->masterTensor() == nullptr && !inputs[0]->childTensors().empty()) { - inputs[0]->free(); + if (inputs[0]->allowAggregated()) { + vector> shared_outputs = {}; + for (const auto &output : outputs) { + output->alloc(); + shared_outputs.push_back(output); + } + if (inputs[0]->masterTensor() == nullptr && !inputs[0]->childTensors().empty()) { + inputs[0]->free(); + } + inputs[0]->addTensors(shared_outputs, split_dim); } - inputs[0]->addTensors(shared_outputs, split_dim); } void reshape(vector> outputs, vector> inputs, vector args) override { - // auto aggregatedTensorsSize = inputs[0]->aggregatedTensors().size(); - // for (int i = 0; i < aggregatedTensorsSize; i++) { - // outputs[i] = inputs[0]->aggregatedTensors()[i].get(); - // } - - // int size = args.size(); - // std::vector each_dims; - // for (int i = 0; i < size - 2; i++) { - // each_dims.push_back(args[i]); - // } - // Chl split_dim = (Chl)args[size - 2]; - // int head_size = (int)args[size - 1]; - // int split_num_ = each_dims.size(); - // // store each dims - // int split_dim_size_ = 0; - // std::vector each_dims_; - // for (size_t i = 0; i < each_dims.size(); ++i) { - // each_dims_.push_back((float)each_dims[i]); - // split_dim_size_ += each_dims[i]; - // } - // assert(split_num_ == outputs.size()); - // return; - // switch (split_dim) { - // case Chl::HEAD: { - // assert(inputs[0]->head() == split_dim_size_); - // for (int i = 0; i < split_num_; i++) { - // outputs[i]->reshape(inputs[0]->batch(), each_dims_[i], inputs[0]->sequence(), inputs[0]->dimension()); - // } - // break; - // } - // case Chl::SEQUENCE: { - // assert(inputs[0]->sequence() == split_dim_size_); - // for (int i = 0; i < split_num_; i++) { - // outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), each_dims_[i], inputs[0]->dimension()); - // } - // break; - // } - // case Chl::DIMENSION: { - // assert(inputs[0]->dimension() == split_dim_size_); - // for (int i = 0; i < split_num_; i++) { - // outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), each_dims_[i]); - // } - // break; - // } - // case Chl::D_HD: { - // assert(inputs[0]->dimension() == split_dim_size_ * head_size); - // for (int i = 0; i < split_num_; i++) { - // outputs[i]->reshape(inputs[0]->batch(), head_size, inputs[0]->sequence(), each_dims_[i]); - // } - // break; - // } - // case Chl::HD: { - // assert(inputs[0]->dimension() == split_dim_size_ * head_size); - // for (int i = 0; i < split_num_; i++) { - // outputs[i]->reshape(inputs[0]->batch(), head_size, inputs[0]->sequence(), each_dims_[i]); - // } - // break; - // } - // default: { - // break; - // } - // } - // vector> shared_outputs = {}; - // for (const auto &output : outputs) { - // output->alloc(); - // shared_outputs.push_back(std::shared_ptr(output, [](Tensor *) {})); - // } - // if (inputs[0]->masterTensor() == nullptr && !inputs[0]->childTensors().empty()) { - // inputs[0]->free(); - // } - // inputs[0]->addTensors(shared_outputs, split_dim); + int size = args.size(); + std::vector each_dims; + for (int i = 0; i < size - 2; i++) { + each_dims.push_back(args[i]); + } + Chl split_dim = (Chl)args[size - 2]; + int head_size = (int)args[size - 1]; + int split_num_ = each_dims.size(); + // store each dims + int split_dim_size_ = 0; + std::vector each_dims_; + for (size_t i = 0; i < each_dims.size(); ++i) { + each_dims_.push_back((float)each_dims[i]); + split_dim_size_ += each_dims[i]; + } + assert(split_num_ == outputs.size()); + switch (split_dim) { + case Chl::HEAD: { + // assert(inputs[0]->head() == split_dim_size_); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), each_dims_[i], inputs[0]->sequence(), inputs[0]->dimension()); + } + break; + } + case Chl::SEQUENCE: { + // assert(inputs[0]->sequence() == split_dim_size_); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), each_dims_[i], inputs[0]->dimension()); + } + break; + } + case Chl::DIMENSION: { + // assert(inputs[0]->dimension() == split_dim_size_); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), each_dims_[i]); + } + break; + } + case Chl::D_HD: { + // assert(inputs[0]->dimension() == split_dim_size_ * head_size); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), head_size, inputs[0]->sequence(), each_dims_[i]); + } + break; + } + case Chl::HD: { + // assert(inputs[0]->dimension() == split_dim_size_ * head_size); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), head_size, inputs[0]->sequence(), each_dims_[i]); + } + break; + } + default: { + break; + } + } } void execute(vector> outputs, vector> inputs, vector args) override { + if (inputs[0]->aggregatedTensors().empty()) { + int size = args.size(); + std::vector each_dims; + std::vector out_pointers; + assert(size - 2 == outputs.size()); + for (int i = 0; i < size - 2; i++) { + each_dims.push_back(args[i]); + out_pointers.push_back(outputs[i]->ptrAt(0, 0, 0, 0)); + } + Chl split_dim = (Chl)args[size - 2]; + int head_size = (int)args[size - 1]; + int split_num_ = each_dims.size(); + const int origin_dims[4] = {inputs[0]->batch(), inputs[0]->sequence(), inputs[0]->head(), inputs[0]->dimension()}; + efficient_split(inputs[0]->ptrAt(0, 0, 0, 0), + origin_dims, + out_pointers, + each_dims, + split_dim); + } } }; diff --git a/src/backends/cpu/function/CPUTransposeFunc.hpp b/src/backends/cpu/function/CPUTransposeFunc.hpp index 0906a5f66..5d87f2132 100644 --- a/src/backends/cpu/function/CPUTransposeFunc.hpp +++ b/src/backends/cpu/function/CPUTransposeFunc.hpp @@ -7,6 +7,8 @@ #include "Tensor.hpp" #include "Types.hpp" #include "Module.hpp" +#include "compute/Quantize.hpp" +#include #include namespace mllm { @@ -19,6 +21,18 @@ class CPUtransposeFunction : public TensorFunction { for (int i = 0; i < args.size(); i += 2) { axiss.push_back({(Chl)args[i], (Chl)args[i + 1]}); } + // for BSHD attention start + if(axiss.size() == 1&& axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { + if(inputs[0]->ctype() == BSHD){ + outputs[0]->chls() = {{BATCH, 0}, {HEAD, 1}, {SEQUENCE, 2}, {DIMENSION, 3}}; + }else{ + outputs[0]->chls() = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}}; + } + outputs[0]->changeCtype(4); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + return; + } + // for BSHD attention swnd if (!outputs[0]->undiffusion()) { outputs[0]->transCopyShape(inputs[0]->shape()); std::map origin_chls = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; @@ -57,6 +71,11 @@ class CPUtransposeFunction : public TensorFunction { for (int i = 0; i < args.size(); i += 2) { axiss.push_back({(Chl)args[i], (Chl)args[i + 1]}); } + // for BSHD attention start + if(axiss.size() == 1&& axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { + return; + } + // for BSHD attention send std::map origin_chls = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; auto origin_s = inputs[0]->shape().size(); outputs[0]->transCopyShape(inputs[0]->shape()); @@ -84,6 +103,52 @@ class CPUtransposeFunction : public TensorFunction { } } void execute(vector> outputs, vector> inputs, vector args) override { + vector> axiss; + // for BSHD attention start + for (int i = 0; i < args.size(); i += 2) { + axiss.push_back({(Chl)args[i], (Chl)args[i + 1]}); + } + if(axiss.size() == 1&& axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { + if(inputs[0]->ctype() == BSHD){ + outputs[0]->chls() = {{BATCH, 0}, {HEAD, 1}, {SEQUENCE, 2}, {DIMENSION, 3}}; + }else{ + outputs[0]->chls() = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}}; + } + outputs[0]->changeCtype(4); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), + inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->alloc(); + //BSHD -> BSHD + { //真转置 + assert(inputs[0]->batch() == 1); + assert(outputs[0]->batch() == 1); + assert(inputs[0]->head() == outputs[0]->head()); + assert(inputs[0]->sequence() == outputs[0]->sequence()); + assert(outputs[0]->ctype() == BHSD || outputs[0]->ctype() == BSHD); + if(inputs[0]->dtype() == outputs[0]->dtype()){ + #pragma omp parallel for + for (int h = 0; h < inputs[0]->head(); ++h) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); + auto output_ptr = outputs[0]->ptrAt(0, h, s, 0); + memcpy(output_ptr, input_ptr, inputs[0]->dimension() * sizeof(float)); + } + } + }else{ + #pragma omp parallel for + for (int h = 0; h < inputs[0]->head(); ++h) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); + auto output_ptr = outputs[0]->ptrAt(0, h, s, 0); + for (int d = 0; d < inputs[0]->dimension(); ++d) { + output_ptr[d] = MLLM_FP32_TO_FP16(input_ptr[d]); + } + } + } + } + } + } + // for BSHD attention end } }; } // namespace mllm diff --git a/src/backends/cpu/op/CPUKVCache.cpp b/src/backends/cpu/op/CPUKVCache.cpp index d4ea8fb14..0c64193f6 100644 --- a/src/backends/cpu/op/CPUKVCache.cpp +++ b/src/backends/cpu/op/CPUKVCache.cpp @@ -218,6 +218,17 @@ ErrorCode CPUKVCache::free(vector> inputs, vector> inputs, vector> outputs) { assert(inputs.size() == 1); assert(outputs.size() == 1); + // for BSHD attention start + if(inputs[0]->ctype() == BHSD && cache_.ctype() == BSHD) { + auto origin_b = cache_.batch(); + auto origin_h = cache_.head(); + auto origin_s = cache_.sequence(); + auto origin_d = cache_.dimension(); + cache_.setCtype(BHSD); + cache_.reshape(origin_b, origin_h, origin_s + cache_seq_len_, origin_d); + cache_.alloc(); + } + // for BSHD attention end outputs[0]->setDtype(cache_.dtype()); outputs[0]->shallowCopyFrom(cache_, false, {0, 0, cache_seq_len_ / cache_limit_, 0}); if (inputs[0]->sequence() + cache_seq_len_ > cache_limit_) { @@ -294,57 +305,6 @@ ErrorCode CPUKVCache::updateVerifiedKVCache(const std::vector &ver } else { std::cout << "ERROR Ctype in KVCcache;" << std::endl; } - - // clear kv cache - // if (cache_seq_len_ < cache_seq_len_old) { - // if (n_rep_ > 1) { - // if (cache_.ctype() == BSHD) { - // for (int b = 0; b < cache_.batch(); ++b) { - // for (int h = cache_.head() - 1; h >= 0; --h) { - // // #pragma omp parallel for collapse(2) num_threads(thread_count) - // for (int seq = cache_seq_len_; seq < cache_seq_len_old; ++seq) { - // for (int i_rep = 0; i_rep < n_rep_; ++i_rep) { - // auto cache_head = h * n_rep_ + i_rep; - // if (cache_.dtype() == MLLM_TYPE_F32) { - // auto dest_ptr = cache_.ptrAt(b, cache_head, seq, 0); - // int copy_size = cache_.dimension(); - // memset(dest_ptr, 0, copy_size * sizeof(float)); - // } else if (cache_.dtype() == MLLM_TYPE_F16) { - // auto dest_ptr = cache_.ptrAt(b, cache_head, seq, 0); - // int copy_size = cache_.dimension(); - // memset(dest_ptr, 0, copy_size * sizeof(mllm_fp16_t)); - // } - // } - // } - // } - // } - // } else if (cache_.ctype() == BHDS) { - // for (int b = 0; b < cache_.batch(); ++b) { - // for (int h = cache_.head() - 1; h >= 0; --h) { - // // #pragma omp parallel for collapse(2) num_threads(thread_count) - // for (int d = 0; d < cache_.dimension(); ++d) { - // for (int i_rep = 0; i_rep < n_rep_; ++i_rep) { - // auto cache_head = h * n_rep_ + i_rep; - // if (cache_.dtype() == MLLM_TYPE_F32) { - // auto dest_ptr = - // cache_.ptrAt(b, cache_head, cache_seq_len_, d); - // int copy_size = cache_seq_len_old - cache_seq_len_; - // memset(dest_ptr, 0, copy_size * sizeof(float)); - // } else if (cache_.dtype() == MLLM_TYPE_F16) { - // auto dest_ptr = - // cache_.ptrAt(b, cache_head, cache_seq_len_, d); - // int copy_size = cache_seq_len_old - cache_seq_len_; - // memset(dest_ptr, 0, copy_size * sizeof(mllm_fp16_t)); - // } - // } - // } - // } - // } - // } else { - // std::cout << "ERROR Ctype in KVCcache;" << std::endl; - // } - // } - // } return MLLM_NO_ERROR; } diff --git a/src/backends/cpu/op/CPULinear.cpp b/src/backends/cpu/op/CPULinear.cpp index d0c662999..21d666087 100644 --- a/src/backends/cpu/op/CPULinear.cpp +++ b/src/backends/cpu/op/CPULinear.cpp @@ -49,12 +49,12 @@ ErrorCode CPULinear::load(AbstructLoader &loader) { weight_.setName(name() + ".weight"); weight_.reshape(1, 1, out_features_, in_features_); if (loader.getDataType(weight_.name()) != MLLM_TYPE_COUNT) { - if(loader.getDataType(weight_.name()) == MLLM_TYPE_KLEIDIAI_Q4_0) { + if (loader.getDataType(weight_.name()) == MLLM_TYPE_KLEIDIAI_Q4_0) { #if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) kai_thread_count = thread_count; kai_flag = true; - //out_features_:N - //in_features_:K + // out_features_:N + // in_features_:K size_t packed_b_size = mllm_kleidai_get_packed_b_qsi4_size(out_features_, in_features_); weight_.reshape(1, 1, 1, packed_b_size); #else @@ -64,7 +64,7 @@ ErrorCode CPULinear::load(AbstructLoader &loader) { #endif } weight_.setDtype(loader.getDataType(weight_.name())); - weight_.alloc(); + weight_.alloc(); loader.load(&weight_); } else { if (weight_.name().find('v') != std::string::npos && Op::noLoadWeightsDtype() == MLLM_TYPE_Q4_0_4_4) { @@ -111,7 +111,7 @@ ErrorCode CPULinear::execute(vector> inputs, vectorreshape(b, h, s, d); tmp_out->setDtype(MLLM_TYPE_F32); tmp_out->alloc(); - if(weight_.dtype() == MLLM_TYPE_KLEIDIAI_Q4_0){ + if (weight_.dtype() == MLLM_TYPE_KLEIDIAI_Q4_0) { #if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) kai_thread_count = thread_count; // KLEIDIAI_Q4_0 is a packed type, we need to use a special function to handle it @@ -119,13 +119,13 @@ ErrorCode CPULinear::execute(vector> inputs, vectordimension(); auto K = inputs[0]->dimension(); if (outputs[0]->dtype() == MLLM_TYPE_F16) { - mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(0, 0, 0, 0), - inputs[0]->ptrAt(0, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); - }else{ - mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(0, 0, 0, 0), - inputs[0]->ptrAt(0, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); + mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(0, 0, 0, 0), + inputs[0]->ptrAt(0, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } else { + mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(0, 0, 0, 0), + inputs[0]->ptrAt(0, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); } return MLLM_NO_ERROR; #else @@ -133,7 +133,7 @@ ErrorCode CPULinear::execute(vector> inputs, vectorctype() == BSHD) { #pragma omp parallel for collapse(3) num_threads(thread_count) @@ -161,20 +161,20 @@ ErrorCode CPULinear::execute(vector> inputs, vectorsequence(); - auto N = outputs[0]->dimension();//out_features_ - auto K = inputs[0]->dimension();//in_features_ + auto N = outputs[0]->dimension(); // out_features_ + auto K = inputs[0]->dimension(); // in_features_ if (outputs[0]->dtype() == MLLM_TYPE_F16) { - mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(0, 0, 0, 0), - inputs[0]->ptrAt(0, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); - }else{ - mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(0, 0, 0, 0), - inputs[0]->ptrAt(0, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); + mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(0, 0, 0, 0), + inputs[0]->ptrAt(0, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } else { + mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(0, 0, 0, 0), + inputs[0]->ptrAt(0, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); } return MLLM_NO_ERROR; #else @@ -182,12 +182,22 @@ ErrorCode CPULinear::execute(vector> inputs, vector> inputs, vector> outputs) { + for (auto &output : outputs) { + output->setDtype(activation_dtype_); + output->alloc(); + // if (weight_.dtype() == MLLM_TYPE_KLEIDIAI_Q4_0 || weight_.dtype() == MLLM_TYPE_Q4_0_4_4) { + // output->allowAggregated() = false; + // } + } + return MLLM_NO_ERROR; +} ErrorCode CPULinear::free(vector> inputs, vector> outputs) { weight_.free(); if (support_bias_) { diff --git a/src/backends/cpu/op/CPULinear.hpp b/src/backends/cpu/op/CPULinear.hpp index 200903196..33f2e4347 100644 --- a/src/backends/cpu/op/CPULinear.hpp +++ b/src/backends/cpu/op/CPULinear.hpp @@ -16,6 +16,7 @@ class CPULinear final : public Op { virtual ErrorCode load(AbstructLoader &loader) override; virtual ErrorCode execute(vector> inputs, vector> outputs) override; virtual ErrorCode free(vector> inputs, vector> outputs) override; + virtual ErrorCode setUp(vector> inputs, vector> outputs) override; Tensor &weight() { return weight_; diff --git a/src/backends/qnn/CMakeLists.txt b/src/backends/qnn/CMakeLists.txt index cb8ee5b2b..7c033020d 100644 --- a/src/backends/qnn/CMakeLists.txt +++ b/src/backends/qnn/CMakeLists.txt @@ -48,7 +48,7 @@ endif() add_library( - lib_mllm_qnn + mllm_qnn OBJECT ${MLLM_QNN_SRC} ) @@ -57,12 +57,12 @@ if(OpenMP_FOUND) message(STATUS "found openmp") if(ARM AND NOT APK) message(STATUS "[ARM] found openmp") - target_compile_options(lib_mllm_qnn PRIVATE -fopenmp) - target_link_libraries(lib_mllm_qnn PUBLIC -fopenmp -static-openmp) + target_compile_options(mllm_qnn PRIVATE -fopenmp) + target_link_libraries(mllm_qnn PUBLIC -fopenmp -static-openmp) else() - target_link_libraries(lib_mllm_qnn + target_link_libraries(mllm_qnn PUBLIC OpenMP::OpenMP_CXX ) endif() endif() -target_link_libraries(lib_mllm_qnn PUBLIC fmt::fmt-header-only) \ No newline at end of file +target_link_libraries(mllm_qnn PUBLIC fmt::fmt-header-only) \ No newline at end of file diff --git a/src/backends/xnnpack/CMakeLists.txt b/src/backends/xnnpack/CMakeLists.txt index 4192806f3..b353d093c 100644 --- a/src/backends/xnnpack/CMakeLists.txt +++ b/src/backends/xnnpack/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(third_party/XNNPACK) -add_library(lib_mllm_xnnpack +add_library(mllm_xnnpack OBJECT Utils/Logger.cpp @@ -36,7 +36,7 @@ add_library(lib_mllm_xnnpack Functions/XpViewFunc.cpp Functions/XpMatmulFunc.cpp ) -target_include_directories(lib_mllm_xnnpack PUBLIC third_party/XNNPACK/src/) -target_include_directories(lib_mllm_xnnpack PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../) -target_link_libraries(lib_mllm_xnnpack PUBLIC XNNPACK fmt::fmt-header-only) -set_target_properties(lib_mllm_xnnpack PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) +target_include_directories(mllm_xnnpack PUBLIC third_party/XNNPACK/src/) +target_include_directories(mllm_xnnpack PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../) +target_link_libraries(mllm_xnnpack PUBLIC XNNPACK fmt::fmt-header-only) +set_target_properties(mllm_xnnpack PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) diff --git a/src/models/bert/modeling_bert.hpp b/src/models/bert/modeling_bert.hpp index d2f9012c5..02793acd9 100644 --- a/src/models/bert/modeling_bert.hpp +++ b/src/models/bert/modeling_bert.hpp @@ -39,7 +39,7 @@ class BertLayer : public Module { BertLayer() = default; BertLayer(const BertConfig &config, const string &base_name) { // base_name: encoder.layer.n. - attention = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_attention_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, RoPEType::NONE, -1, -1, 0, false, true, config.attn_implementation, config.names_config, base_name + config.names_config._attn_base_name); + attention = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_attention_heads, config.hidden_size / config.num_attention_heads, SPLIT_NONE, PostQkv_NONE, false, RoPEType::NONE, -1, -1, 0, false, true, true, config.attn_implementation, config.names_config, base_name + config.names_config._attn_base_name); feed_forward = FeedForward(config.hidden_size, config.intermediate_size, config.hidden_act, true, config.names_config, base_name); diff --git a/src/models/clip/modeling_clip.hpp b/src/models/clip/modeling_clip.hpp index c47996b9e..0feb8dd7e 100644 --- a/src/models/clip/modeling_clip.hpp +++ b/src/models/clip/modeling_clip.hpp @@ -90,8 +90,8 @@ class ClipTextBlock final : public Module { ClipTextBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, string attn_implementation, const ClipTextNameConfig &names, const string &base_name) { attention = MultiHeadAttention(hidden_dim, head_size, head_size, - hidden_dim / head_size, SPLIT_NONE, false, false, - RoPEType::NONE, -1, -1, 0, true, true, attn_implementation, + hidden_dim / head_size, SPLIT_NONE, PostQkv_NONE, false, + RoPEType::NONE, -1, -1, 0, true, true, true, attn_implementation, names, base_name + names._attn_base_name); mlp = ClipTextMLP(hidden_dim, ffn_hidden, act_fn_type, names, base_name + names._ffn_base_name); down_proj = Linear(ffn_hidden, hidden_dim, true, base_name + names._down_proj_name); diff --git a/src/models/dclm/modeling_dclm.hpp b/src/models/dclm/modeling_dclm.hpp index 99e805702..e1f52cfa9 100644 --- a/src/models/dclm/modeling_dclm.hpp +++ b/src/models/dclm/modeling_dclm.hpp @@ -55,7 +55,7 @@ class DCLMAttention final : public Module { KVCache v_cache; Softmax softmax; - int attn_hidden_dim_; + int hidden_dim_; int head_dim_; int n_heads_; string attn_implementation_; @@ -64,7 +64,7 @@ class DCLMAttention final : public Module { DCLMAttention() = default; DCLMAttention(const DCLMConfig &cfg, const std::string &base_name) { int head_dim = cfg.dim / cfg.n_heads; - attn_hidden_dim_ = cfg.n_heads * head_dim; + hidden_dim_ = cfg.n_heads * head_dim; head_dim_ = head_dim; n_heads_ = cfg.n_heads; attn_implementation_ = cfg.attn_implementation; @@ -81,7 +81,7 @@ class DCLMAttention final : public Module { std::vector Forward(std::vector inputs, std::vector args) override { auto qkv = in_proj(inputs[0]); - auto qkv_sp = qkv.split({attn_hidden_dim_, attn_hidden_dim_, attn_hidden_dim_}, DIMENSION); + auto qkv_sp = qkv.split({hidden_dim_, hidden_dim_, hidden_dim_}, DIMENSION); Tensor q, k, v; q = qkv_sp[0]; diff --git a/src/models/fuyu/modeling_fuyu.hpp b/src/models/fuyu/modeling_fuyu.hpp index 4ae3e7f98..ec36fc324 100644 --- a/src/models/fuyu/modeling_fuyu.hpp +++ b/src/models/fuyu/modeling_fuyu.hpp @@ -8,6 +8,7 @@ #include "Backend.hpp" #include "Layer.hpp" #include "Module.hpp" +#include "Types.hpp" #include "configuration_fuyu.hpp" #include @@ -26,8 +27,9 @@ class PersimmonBlock final : public Module { string attn_implementation, const FuyuNameConfig &names, const string &base_name) { attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, - SPLIT_D_HD, true, false, - PERSIMMONROPE, rope_theta, max_position_embeddings, cache_limit, true, true, + SPLIT_D_HD, PostQkv_LayerNorm, false, + PERSIMMONROPE, rope_theta, max_position_embeddings, cache_limit, + true, true, true, attn_implementation, names, base_name + names._attn_base_name); mlp = FeedForward(hidden_dim, ffn_hidden, "ReLU2", true, diff --git a/src/models/gemma/modeling_gemma.hpp b/src/models/gemma/modeling_gemma.hpp index 8ebd491f8..88d23cecd 100644 --- a/src/models/gemma/modeling_gemma.hpp +++ b/src/models/gemma/modeling_gemma.hpp @@ -55,8 +55,10 @@ class GemmaDecoder final : public Module { GemmaDecoder(const GemmaConfig &config, const GemmaNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, true, false, + config.hidden_size / config.num_attention_heads, + SPLIT_NONE, PostQkv_NONE, false, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, + config.cache_limit, true, false, false, config.attn_implementation, names, base_name + names._attn_base_name); mlp = GemmaMLP(config.hidden_size, config.intermediate_size, names, base_name + names._ffn_base_name); diff --git a/src/models/imagebind/modeling_imagebind.hpp b/src/models/imagebind/modeling_imagebind.hpp index be8179dc7..4f27e764b 100644 --- a/src/models/imagebind/modeling_imagebind.hpp +++ b/src/models/imagebind/modeling_imagebind.hpp @@ -7,6 +7,7 @@ #include "Layer.hpp" #include "Module.hpp" +#include "Types.hpp" #include "configuration_imagebind.hpp" #include "models/transformer/modeling_transformer.hpp" @@ -31,8 +32,8 @@ class EncoderBlock final : public Module { bias_kv_cat = true; } attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, - SPLIT_HD, false, bias_kv_cat, - RoPEType::NONE, -1, -1, 0, do_mask, true, + SPLIT_HD, PostQkv_NONE, bias_kv_cat, + RoPEType::NONE, -1, -1, 0, do_mask, true, true, attn_implementation, names, base_name + names._attn_base_name); ffn = FeedForward(hidden_dim, ffn_hidden, "GELU", true, diff --git a/src/models/llama/modeling_elastic_llama.hpp b/src/models/llama/modeling_elastic_llama.hpp index a4211d454..1be63ad7b 100644 --- a/src/models/llama/modeling_elastic_llama.hpp +++ b/src/models/llama/modeling_elastic_llama.hpp @@ -25,43 +25,43 @@ class ElasticMultiHeadAttention final : public Module { ElasticLinear o_proj; int head_size_{}; int kv_head_size_{}; - int attn_hidden_dim_{}; + int head_dim_{}; public: ElasticMultiHeadAttention() = default; - ElasticMultiHeadAttention(int hidden_dim, int head_size, int kv_head_size, int attn_hidden_dim, + ElasticMultiHeadAttention(int hidden_dim, int head_size, int kv_head_size, int head_dim, RoPEType RoPE_type, int cache_limit, bool do_mask, bool bias, const TransformerNameConfig &names, const string &base_name) { assert(kv_head_size_ == head_size_); - attn_hidden_dim_ = attn_hidden_dim; + head_dim_ = head_dim; head_size_ = head_size; kv_head_size_ = kv_head_size; - q_proj = ElasticLinear(hidden_dim, head_size * attn_hidden_dim, bias, base_name + names._q_proj_name); - k_proj = ElasticLinear(hidden_dim, kv_head_size * attn_hidden_dim, bias, base_name + names._k_proj_name); - v_proj = ElasticLinear(hidden_dim, kv_head_size * attn_hidden_dim, bias, base_name + names._v_proj_name); + q_proj = ElasticLinear(hidden_dim, head_size * head_dim, bias, base_name + names._q_proj_name); + k_proj = ElasticLinear(hidden_dim, kv_head_size * head_dim, bias, base_name + names._k_proj_name); + v_proj = ElasticLinear(hidden_dim, kv_head_size * head_dim, bias, base_name + names._v_proj_name); if (RoPE_type > 0) { q_rope = RoPE(RoPE_type, base_name + "q_rope"); k_rope = RoPE(RoPE_type, base_name + "k_rope"); } if (cache_limit > 0) { - k_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, base_name + "k_cache"); - v_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, base_name + "v_cache"); + k_cache = KVCache(kv_head_size, head_dim, head_size / kv_head_size, cache_limit, base_name + "k_cache"); + v_cache = KVCache(kv_head_size, head_dim, head_size / kv_head_size, cache_limit, base_name + "v_cache"); } softmax = Softmax(DIMENSION, do_mask, base_name + "softmax"); - o_proj = ElasticLinear(head_size * attn_hidden_dim, hidden_dim, bias, base_name + names._o_proj_name); + o_proj = ElasticLinear(head_size * head_dim, hidden_dim, bias, base_name + names._o_proj_name); } vector Forward(vector inputs, vector args) override { vector activate_head_dims = std::any_cast>(args[0]); int activate_head_dim = activate_head_dims[0]; activate_head_dim = (activate_head_dim == -1) ? kv_head_size_ : (activate_head_dim); Tensor q, k, v; - q = q_proj(inputs[0], -1, activate_head_dim * attn_hidden_dim_); - k = k_proj(inputs[1], -1, activate_head_dim * attn_hidden_dim_); - v = v_proj(inputs[2], -1, activate_head_dim * attn_hidden_dim_); - q = q.view(-1, activate_head_dim, -1, attn_hidden_dim_); - k = k.view(-1, activate_head_dim, -1, attn_hidden_dim_); - v = v.view(-1, activate_head_dim, -1, attn_hidden_dim_); + q = q_proj(inputs[0], -1, activate_head_dim * head_dim_); + k = k_proj(inputs[1], -1, activate_head_dim * head_dim_); + v = v_proj(inputs[2], -1, activate_head_dim * head_dim_); + q = q.view(-1, activate_head_dim, -1, head_dim_); + k = k.view(-1, activate_head_dim, -1, head_dim_); + v = v.view(-1, activate_head_dim, -1, head_dim_); if (q_rope.ready() && k_rope.ready()) { q = q_rope(q); k = k_rope(k); @@ -72,15 +72,15 @@ class ElasticMultiHeadAttention final : public Module { } k = k.transpose(SEQUENCE, DIMENSION); auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(attn_hidden_dim_); // attn_hidden_dim_ + qk = qk / std::sqrt(head_dim_); // head_dim_ if (k_cache.ready() && v_cache.ready()) { qk = softmax(qk, k_cache.getCacheSeqLen()); } else { qk = softmax(qk); } auto o = Tensor::mm(qk, v); - o = o.view(-1, 1, -1, attn_hidden_dim_ * activate_head_dim); - o = o_proj(o, activate_head_dim * attn_hidden_dim_, -1); + o = o.view(-1, 1, -1, head_dim_ * activate_head_dim); + o = o_proj(o, activate_head_dim * head_dim_, -1); return {o}; } vector get_cache() { diff --git a/src/models/llama/modeling_llama.hpp b/src/models/llama/modeling_llama.hpp index 7d8eabe26..58883581c 100644 --- a/src/models/llama/modeling_llama.hpp +++ b/src/models/llama/modeling_llama.hpp @@ -49,8 +49,8 @@ class LLaMABlock final : public Module { string attn_implementation, const LLaMANameConfig &names, const string &base_name) { attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, - SPLIT_NONE, false, false, - RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, + SPLIT_NONE, PostQkv_NONE, false, + RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, false, attn_implementation, names, base_name + names._attn_base_name); mlp = LLaMAMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); diff --git a/src/models/llama/modeling_sparse_llama.hpp b/src/models/llama/modeling_sparse_llama.hpp index d59363239..17616bc5c 100644 --- a/src/models/llama/modeling_sparse_llama.hpp +++ b/src/models/llama/modeling_sparse_llama.hpp @@ -51,8 +51,8 @@ class SparseLLaMABlock final : public Module { SparseLLaMABlock() = default; SparseLLaMABlock(bool is_down_sparse, int hidden_dim, int head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const LLaMANameConfig &names, const string &base_name) { attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, - SPLIT_NONE, false, false, - RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, + SPLIT_NONE, PostQkv_NONE, false, + RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, false, attn_implementation, names, base_name + names._attn_base_name); mlp = SparseLLaMAMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name, is_down_sparse); diff --git a/src/models/minicpm/modeling_minicpm.hpp b/src/models/minicpm/modeling_minicpm.hpp index 502357032..383a62121 100644 --- a/src/models/minicpm/modeling_minicpm.hpp +++ b/src/models/minicpm/modeling_minicpm.hpp @@ -43,9 +43,10 @@ class MiniCPMDecoder final : public Module { MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, + config.hidden_size / config.num_attention_heads, + SPLIT_NONE, PostQkv_NONE, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, + true, false,false, config.attn_implementation, names, base_name + names._attn_base_name); mlp = MiniCPMMLP(config.hidden_size, config.intermediate_size, names, base_name + names._ffn_base_name); diff --git a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp index a8a6b9923..9be253d34 100644 --- a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp +++ b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp @@ -287,9 +287,10 @@ class MiniCPMDecoder final : public Module { MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, + config.hidden_size / config.num_attention_heads, + SPLIT_NONE, PostQkv_NONE, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, + true, false,false, config.attn_implementation, names, base_name + names._attn_base_name); moe = MiniCPMMoE(config, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); diff --git a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp index 27042fdcd..0f808110c 100644 --- a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp +++ b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp @@ -294,9 +294,10 @@ class MiniCPMDecoder final : public Module { MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, + config.hidden_size / config.num_attention_heads, + SPLIT_NONE, PostQkv_NONE, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, + true, false,false, config.attn_implementation, names, base_name + names._attn_base_name); moe = MiniCPMMoE(config, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); diff --git a/src/models/minicpm_moe/modeling_minicpm_moe.hpp b/src/models/minicpm_moe/modeling_minicpm_moe.hpp index 96b10f25a..e65d494ec 100644 --- a/src/models/minicpm_moe/modeling_minicpm_moe.hpp +++ b/src/models/minicpm_moe/modeling_minicpm_moe.hpp @@ -108,9 +108,10 @@ class MiniCPMDecoder final : public Module { MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, + config.hidden_size / config.num_attention_heads, + SPLIT_NONE, PostQkv_NONE, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, + true, false,false, config.attn_implementation, names, base_name + names._attn_base_name); moe = MiniCPMMoE(config, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); diff --git a/src/models/mistral/modeling_mistral.hpp b/src/models/mistral/modeling_mistral.hpp index a04ae91ff..c7741a063 100644 --- a/src/models/mistral/modeling_mistral.hpp +++ b/src/models/mistral/modeling_mistral.hpp @@ -53,9 +53,10 @@ class MistralDecoder final : public Module { MistralDecoder(const MistralConfig &config, const MistralNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, SPLIT_NONE, false, false, + config.hidden_size / config.num_attention_heads, + SPLIT_NONE, PostQkv_NONE, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false, + true, false,false, config.attn_implementation, names, base_name + names._attn_base_name); mlp = MistralMLP(config.hidden_size, config.intermediate_size, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); diff --git a/src/models/opt/modeling_opt.hpp b/src/models/opt/modeling_opt.hpp index ca1b5bbca..b83f879be 100644 --- a/src/models/opt/modeling_opt.hpp +++ b/src/models/opt/modeling_opt.hpp @@ -19,8 +19,8 @@ class OPTBlock final : public Module { OPTBlock(int hidden_dim, int head_size, int ffn_hidden, int cache_limit, string attn_implementation, const optNameConfig &names, const string &base_name) { attention = MultiHeadAttention(hidden_dim, head_size, head_size, - hidden_dim / head_size, SPLIT_NONE, false, false, - NONE, -1, -1, cache_limit, true, true, + hidden_dim / head_size, SPLIT_NONE, PostQkv_NONE, false, + NONE, -1, -1, cache_limit, true, true, true, attn_implementation, names, base_name + names._attn_base_name); mlp = FeedForward(hidden_dim, ffn_hidden, "ReLU", true, diff --git a/src/models/phi3/modeling_phi3.hpp b/src/models/phi3/modeling_phi3.hpp index c5a2719cc..fc0899156 100644 --- a/src/models/phi3/modeling_phi3.hpp +++ b/src/models/phi3/modeling_phi3.hpp @@ -46,7 +46,7 @@ class Phi3Block final : public Module { public: Phi3Block() = default; Phi3Block(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const Phi3NameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_HD, false, false, RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, attn_implementation, names, base_name + names._attn_base_name); + attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_HD, PostQkv_NONE, false, RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, false,attn_implementation, names, base_name + names._attn_base_name); mlp = Phi3MLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); norm2 = RMSNorm(hidden_dim, 1e-6, base_name + names._ffn_norm_name); diff --git a/src/models/qwen/modeling_qwen.hpp b/src/models/qwen/modeling_qwen.hpp index 90bdfefc8..689eb4312 100644 --- a/src/models/qwen/modeling_qwen.hpp +++ b/src/models/qwen/modeling_qwen.hpp @@ -17,6 +17,7 @@ #include "Module.hpp" #include "Tensor.hpp" #include "configuration_qwen.hpp" +#include "models/transformer/modeling_transformer.hpp" #include using namespace mllm; @@ -51,101 +52,19 @@ class QWenMLP final : public Module { Layer silu; }; -// Copied from GemmaAttention with Gemma->Qwen and using SWA -class QWenAttention final : public Module { -public: - QWenAttention() = default; - QWenAttention(const QWenConfig &config, const QWenNameConfig &names, const string &base_name) { - hidden_size = config.hidden_size; - num_heads = config.num_attention_heads; - head_dim = config.hidden_size / num_heads; - num_key_value_heads = config.num_key_value_heads; - num_key_value_groups = num_heads / num_key_value_heads; - attn_impl = config.attn_implementation; - // init layers - q_proj = Linear(hidden_size, num_heads * head_dim, true, base_name + names._q_proj_name); - k_proj = Linear(hidden_size, num_key_value_heads * head_dim, true, - base_name + names._k_proj_name); - v_proj = Linear(hidden_size, num_key_value_heads * head_dim, true, - base_name + names._v_proj_name); - o_proj = Linear(num_heads * head_dim, hidden_size, false, base_name + names._o_proj_name); - q_rope = RoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, - base_name + "q_rope"); - k_rope = RoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, - base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "v_cache"); - softmax = Softmax(DIMENSION, true, base_name + "softmax"); - } - - std::vector Forward(std::vector inputs, std::vector args) override { - auto query_states = q_proj(inputs[0]); - auto key_states = k_proj(inputs[1]); - auto value_states = v_proj(inputs[2]); - - // [batch, heads, sequence, dims] - query_states = query_states.view(-1, num_heads, -1, head_dim); - key_states = key_states.view(-1, num_key_value_heads, -1, head_dim); - value_states = value_states.view(-1, num_key_value_heads, -1, head_dim); - - // embedding - query_states = q_rope(query_states); - key_states = k_rope(key_states); - - // kv cache - key_states = k_cache(key_states); - value_states = v_cache(value_states); - - Tensor atten_output; - if (attn_impl == "flash_attention_2") { - atten_output = Tensor::flash_attention2_forward(query_states, key_states, value_states, true); - } else { // eager implementation - auto atten_weight = - Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) - / std::sqrt(head_dim); - // atten_weight = mask(atten_weight, k_cache.getCacheSeqLen()); - atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); - auto atten_output = Tensor::mm(atten_weight, value_states); - } - - // attention output - atten_output = atten_output.view(-1, 1, -1, head_dim * num_heads); - atten_output = o_proj(atten_output); - return {atten_output}; - } - - vector get_cache() { - return {&k_cache, &v_cache}; - } - vector get_rope() { - return {&q_rope, &k_rope}; - } - -private: - int hidden_size; - int num_heads; - int head_dim; - int num_key_value_heads; - int num_key_value_groups; - Layer q_proj; - Layer k_proj; - Layer v_proj; - Layer o_proj; - RoPE q_rope; - RoPE k_rope; - KVCache k_cache; - KVCache v_cache; - // Causalmask mask; - Softmax softmax; - string attn_impl; -}; - -// Copied from GemmaDecoder with Gemma->Qwen and set RmsNorm(without add_unit_offset) class QWenDecoder final : public Module { public: QWenDecoder() = default; QWenDecoder(const QWenConfig &config, const QWenNameConfig &names, const string &base_name) { - self_atten = QWenAttention(config, names, base_name + names._attn_base_name); + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, config.hidden_size / config.num_attention_heads, + SPLIT_NONE, PostQkv_NONE, false, + config.RoPE_type, config.rope_theta, + config.max_position_embeddings, + config.cache_limit, + true, true, false, + config.attn_implementation, names, + base_name + names._attn_base_name); mlp = QWenMLP(config.hidden_size, config.intermediate_size, names, base_name + names._ffn_base_name); input_layernorm = @@ -164,12 +83,12 @@ class QWenDecoder final : public Module { return {x}; } - QWenAttention &get_attention() { + MultiHeadAttention &get_attention() { return self_atten; } private: - QWenAttention self_atten; + MultiHeadAttention self_atten; QWenMLP mlp; Layer input_layernorm; Layer post_attention_layernorm; diff --git a/src/models/qwen2_vl/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/modeling_qwen2_vl.hpp index c9c4abad9..01d71f05b 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl.hpp @@ -39,21 +39,21 @@ class VisionAttention final : public Module { Layer o_proj; int head_size_{}; int kv_head_size_{}; - int attn_hidden_dim_{}; + int head_dim_{}; string attn_impl; public: VisionAttention() = default; - VisionAttention(int hidden_dim, int head_size, int kv_head_size, int attn_hidden_dim, bool bias, string attn_implementation, + VisionAttention(int hidden_dim, int head_size, int kv_head_size, int head_dim, bool bias, string attn_implementation, const TransformerNameConfig &names, const string &base_name) { - attn_hidden_dim_ = attn_hidden_dim; + head_dim_ = head_dim; head_size_ = head_size; kv_head_size_ = kv_head_size; attn_impl = attn_implementation; - qkv_proj = Linear(hidden_dim, head_size * attn_hidden_dim * 3, bias, base_name + names._qkv_proj_name); + qkv_proj = Linear(hidden_dim, head_size * head_dim * 3, bias, base_name + names._qkv_proj_name); softmax = Softmax(DIMENSION, false, base_name + "softmax"); - o_proj = Linear(head_size * attn_hidden_dim, hidden_dim, bias, base_name + names._o_proj_name); + o_proj = Linear(head_size * head_dim, hidden_dim, bias, base_name + names._o_proj_name); } vector Forward(vector inputs, vector args) override { auto cu_seqlens = inputs[1]; @@ -61,13 +61,13 @@ class VisionAttention final : public Module { auto seq_length = inputs[0].sequence(); Tensor q, k, v; auto qkv = qkv_proj(inputs[0]); - auto qkv_sp = qkv.split({attn_hidden_dim_ * head_size_, attn_hidden_dim_ * head_size_, attn_hidden_dim_ * head_size_}, DIMENSION); + auto qkv_sp = qkv.split({head_dim_ * head_size_, head_dim_ * head_size_, head_dim_ * head_size_}, DIMENSION); q = qkv_sp[0]; k = qkv_sp[1]; v = qkv_sp[2]; - q = q.view(-1, head_size_, -1, attn_hidden_dim_); - k = k.view(-1, head_size_, -1, attn_hidden_dim_); - v = v.view(-1, head_size_, -1, attn_hidden_dim_); + q = q.view(-1, head_size_, -1, head_dim_); + k = k.view(-1, head_size_, -1, head_dim_); + v = v.view(-1, head_size_, -1, head_dim_); q = Tensor::apply_rotary_pos_emb_vision(q, rotary_pos_emb); k = Tensor::apply_rotary_pos_emb_vision(k, rotary_pos_emb); Tensor o; @@ -76,12 +76,12 @@ class VisionAttention final : public Module { } else { // eager implementation k = k.transpose(SEQUENCE, DIMENSION); auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(attn_hidden_dim_); + qk = qk / std::sqrt(head_dim_); // mask qk = softmax(qk); o = Tensor::mm(qk, v); } - o = o.view(-1, 1, -1, attn_hidden_dim_ * head_size_); + o = o.view(-1, 1, -1, head_dim_ * head_size_); o = o_proj(o); return {o}; } diff --git a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp index a22aa147c..9465838df 100644 --- a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp @@ -47,19 +47,19 @@ class VisionAttention final : public Module { Layer o_proj; int head_size_{}; int kv_head_size_{}; - int attn_hidden_dim_{}; + int head_dim_{}; public: VisionAttention() = default; - VisionAttention(int hidden_dim, int head_size, int kv_head_size, int attn_hidden_dim, bool bias, + VisionAttention(int hidden_dim, int head_size, int kv_head_size, int head_dim, bool bias, const TransformerNameConfig &names, const string &base_name) { - attn_hidden_dim_ = attn_hidden_dim; + head_dim_ = head_dim; head_size_ = head_size; kv_head_size_ = kv_head_size; - qkv_proj = Linear(hidden_dim, head_size * attn_hidden_dim * 3, bias, base_name + names._qkv_proj_name); + qkv_proj = Linear(hidden_dim, head_size * head_dim * 3, bias, base_name + names._qkv_proj_name); softmax = Softmax(DIMENSION, false, base_name + "softmax"); - o_proj = Linear(head_size * attn_hidden_dim, hidden_dim, bias, base_name + names._o_proj_name); + o_proj = Linear(head_size * head_dim, hidden_dim, bias, base_name + names._o_proj_name); } vector Forward(vector inputs, vector args) override { auto cu_seqlens = inputs[1]; @@ -67,22 +67,22 @@ class VisionAttention final : public Module { auto seq_length = inputs[0].sequence(); Tensor q, k, v; auto qkv = qkv_proj(inputs[0]); - auto qkv_sp = qkv.split({attn_hidden_dim_ * head_size_, attn_hidden_dim_ * head_size_, attn_hidden_dim_ * head_size_}, DIMENSION); + auto qkv_sp = qkv.split({head_dim_ * head_size_, head_dim_ * head_size_, head_dim_ * head_size_}, DIMENSION); q = qkv_sp[0]; k = qkv_sp[1]; v = qkv_sp[2]; - q = q.view(-1, head_size_, -1, attn_hidden_dim_); - k = k.view(-1, head_size_, -1, attn_hidden_dim_); - v = v.view(-1, head_size_, -1, attn_hidden_dim_); + q = q.view(-1, head_size_, -1, head_dim_); + k = k.view(-1, head_size_, -1, head_dim_); + v = v.view(-1, head_size_, -1, head_dim_); q = Tensor::apply_rotary_pos_emb_vision(q, rotary_pos_emb); k = Tensor::apply_rotary_pos_emb_vision(k, rotary_pos_emb); k = k.transpose(SEQUENCE, DIMENSION); auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(attn_hidden_dim_); + qk = qk / std::sqrt(head_dim_); // mask qk = softmax(qk); auto o = Tensor::mm(qk, v); - o = o.view(-1, 1, -1, attn_hidden_dim_ * head_size_); + o = o.view(-1, 1, -1, head_dim_ * head_size_); o = o_proj(o); return {o}; } diff --git a/src/models/qwen3/configuration_qwen3.hpp b/src/models/qwen3/configuration_qwen3.hpp index 138c758c6..3712ff2f7 100644 --- a/src/models/qwen3/configuration_qwen3.hpp +++ b/src/models/qwen3/configuration_qwen3.hpp @@ -67,6 +67,8 @@ class QWen3NameConfig : public TransformerNameConfig { throw std::runtime_error("Unsupported gemma RoPE type"); } } + _q_norm_name = "q_norm"; + _k_norm_name = "k_norm"; } std::string blk_name; @@ -103,8 +105,7 @@ struct QWen3Config : public TransformerConfig { rope_theta = 1000000.0; vocab_size = 151936; tie_embedding_words = true; - } - else if(billionsType == "4b"){ + } else if (billionsType == "4b") { attention_bias = false; attention_dropout = 0.0; bos_token_id = 151643; @@ -124,15 +125,14 @@ struct QWen3Config : public TransformerConfig { rope_theta = 1000000.0; vocab_size = 151936; tie_embedding_words = true; - } - else { + } else { throw std::runtime_error("Unsupported model size"); } RoPE_type = type; }; - //这下面是赋初始默认值,上面是构造函数,构造函数中的值会覆盖掉初始默认值 - + // 这下面是赋初始默认值,上面是构造函数,构造函数中的值会覆盖掉初始默认值 + bool attention_bias = false; float attention_dropout = 0.0; int bos_token_id = 151643; @@ -151,12 +151,11 @@ struct QWen3Config : public TransformerConfig { double rms_norm_eps = 1e-6; float rope_theta = 1000000.0; int vocab_size = 151936; - bool tie_embedding_words = true; - + bool tie_embedding_words = true; int cache_limit; RoPEType RoPE_type = RoPEType::HFHUBROPE; QWen3NameConfig names_config; }; -#endif +#endif diff --git a/src/models/qwen3/modeling_qwen3.hpp b/src/models/qwen3/modeling_qwen3.hpp index 9da5c49e9..1ed6a27a1 100644 --- a/src/models/qwen3/modeling_qwen3.hpp +++ b/src/models/qwen3/modeling_qwen3.hpp @@ -16,8 +16,10 @@ #include "Layer.hpp" #include "Module.hpp" #include "Tensor.hpp" +#include "Types.hpp" #include "configuration_qwen3.hpp" #include +#include "models/transformer/modeling_transformer.hpp" using namespace mllm; class QWen3MLP final : public Module { @@ -50,113 +52,20 @@ class QWen3MLP final : public Module { Layer silu; }; -class QWen3Attention final : public Module { -public: - QWen3Attention() = default; - QWen3Attention(const QWen3Config &config, const QWen3NameConfig &names, const string &base_name) { - hidden_size = config.hidden_size; - num_heads = config.num_attention_heads; - head_dim = config.head_dim; // 这里config中有head_dim,不等于相除的结果 - num_key_value_heads = config.num_key_value_heads; - num_key_value_groups = num_heads / num_key_value_heads; - rms_norm_eps = config.rms_norm_eps; - attn_impl = config.attn_implementation; - // init layers - q_proj = Linear(hidden_size, num_heads * head_dim, config.attention_bias, base_name + names._q_proj_name); - k_proj = Linear(hidden_size, num_key_value_heads * head_dim, config.attention_bias, - base_name + names._k_proj_name); - v_proj = Linear(hidden_size, num_key_value_heads * head_dim, config.attention_bias, - base_name + names._v_proj_name); - o_proj = Linear(num_heads * head_dim, hidden_size, false, base_name + names._o_proj_name); - - // 增加了RMSNorm - q_norm = RMSNorm(head_dim, rms_norm_eps, base_name + "q_norm"); - k_norm = RMSNorm(head_dim, rms_norm_eps, base_name + "k_norm"); - // 滑动窗口禁用 - - q_rope = RoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, - base_name + "q_rope"); - k_rope = RoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, - base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); - softmax = Softmax(DIMENSION, true, base_name + "softmax"); - } - - std::vector Forward(std::vector inputs, std::vector args) override { - auto query_states = q_proj(inputs[0]); - auto key_states = k_proj(inputs[1]); - auto value_states = v_proj(inputs[2]); - - // [batch, heads, sequence, dims] - query_states = query_states.view(-1, num_heads, -1, head_dim); - key_states = key_states.view(-1, num_key_value_heads, -1, head_dim); - value_states = value_states.view(-1, num_key_value_heads, -1, head_dim); - - // 加正则化 - query_states = q_norm(query_states); - key_states = k_norm(key_states); - - // embedding - query_states = q_rope(query_states); - key_states = k_rope(key_states); - - // kv cache - key_states = k_cache(key_states); - value_states = v_cache(value_states); - - Tensor atten_output; - if (attn_impl == "flash_attention_2") { - atten_output = Tensor::flash_attention2_forward(query_states, key_states, value_states, true); - } else { // eager implementation - // attention weight - auto atten_weight = - Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) - / std::sqrt(head_dim); - atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); - - // attention output - atten_output = Tensor::mm(atten_weight, value_states); - } - atten_output = atten_output.view(-1, 1, -1, head_dim * num_heads); - atten_output = o_proj(atten_output); - return {atten_output}; - } - - vector get_cache() { - return {&k_cache, &v_cache}; - } - vector get_rope() { - return {&q_rope, &k_rope}; - } - -private: - int hidden_size; - int num_heads; - int head_dim; - int num_key_value_heads; - int num_key_value_groups; - double rms_norm_eps; - Layer q_proj; - Layer k_proj; - Layer v_proj; - Layer o_proj; - Layer q_norm; - Layer k_norm; - RoPE q_rope; - RoPE k_rope; - KVCache k_cache; - KVCache v_cache; - // Causalmask mask; - Softmax softmax; - string attn_impl; -}; - class QWen3Decoder final : public Module { public: QWen3Decoder() = default; QWen3Decoder(const QWen3Config &config, const QWen3NameConfig &names, const string &base_name) { - self_atten = QWen3Attention(config, names, base_name + names._attn_base_name); + // 这里config中有head_dim,不等于相除的结果 + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, config.head_dim, + SPLIT_NONE, PostQkv_RMSNorm, false, + config.RoPE_type, config.rope_theta, + config.max_position_embeddings, + config.cache_limit, + true, config.attention_bias, false, + config.attn_implementation, names, + base_name + names._attn_base_name); mlp = QWen3MLP(config.hidden_size, config.intermediate_size, names, base_name + names._ffn_base_name); input_layernorm = @@ -175,12 +84,12 @@ class QWen3Decoder final : public Module { return {x}; } - QWen3Attention &get_attention() { + MultiHeadAttention &get_attention() { return self_atten; } private: - QWen3Attention self_atten; + MultiHeadAttention self_atten; QWen3MLP mlp; Layer input_layernorm; Layer post_attention_layernorm; diff --git a/src/models/smollm/modeling_smollm.hpp b/src/models/smollm/modeling_smollm.hpp index c09621a42..2526d57a1 100644 --- a/src/models/smollm/modeling_smollm.hpp +++ b/src/models/smollm/modeling_smollm.hpp @@ -51,7 +51,7 @@ class SmolLMBlock final : public Module { public: SmolLMBlock() = default; SmolLMBlock(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const SmolLMNameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_NONE, false, false, RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, attn_implementation, names, base_name + names._attn_base_name); + attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_NONE, PostQkv_NONE, false, RoPE_type, rope_theta, max_position_embeddings, cache_limit, true, false, false, attn_implementation, names, base_name + names._attn_base_name); mlp = SmolLMMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); norm2 = RMSNorm(hidden_dim, 1e-6, base_name + names._ffn_norm_name); diff --git a/src/models/stablelm/modeling_stablelm.hpp b/src/models/stablelm/modeling_stablelm.hpp index 6a0acc582..0f9bf2f9b 100644 --- a/src/models/stablelm/modeling_stablelm.hpp +++ b/src/models/stablelm/modeling_stablelm.hpp @@ -20,41 +20,41 @@ class StableLMMultiHeadAttention final : public Module { Layer o_proj; int head_size_{}; int kv_head_size_{}; - int attn_hidden_dim_{}; + int head_dim_{}; Chl split_chl_{}; string attn_impl; public: StableLMMultiHeadAttention() = default; - StableLMMultiHeadAttention(int hidden_dim, int head_size, int kv_head_size, int attn_hidden_dim, + StableLMMultiHeadAttention(int hidden_dim, int head_size, int kv_head_size, int head_dim, RoPEType RoPE_type, int cache_limit, bool do_mask, bool bias, string attn_implementation, const TransformerNameConfig &names, const string &base_name) { - attn_hidden_dim_ = attn_hidden_dim; + head_dim_ = head_dim; head_size_ = head_size; kv_head_size_ = kv_head_size; attn_impl = attn_implementation; - q_proj = Linear(hidden_dim, head_size * attn_hidden_dim, bias, base_name + names._q_proj_name); - k_proj = Linear(hidden_dim, kv_head_size * attn_hidden_dim, bias, base_name + names._k_proj_name); - v_proj = Linear(hidden_dim, kv_head_size * attn_hidden_dim, bias, base_name + names._v_proj_name); + q_proj = Linear(hidden_dim, head_size * head_dim, bias, base_name + names._q_proj_name); + k_proj = Linear(hidden_dim, kv_head_size * head_dim, bias, base_name + names._k_proj_name); + v_proj = Linear(hidden_dim, kv_head_size * head_dim, bias, base_name + names._v_proj_name); if (RoPE_type > 0) { q_rope = RoPE(RoPE_type, 10000, 0.25, 4096, base_name + "q_rope"); k_rope = RoPE(RoPE_type, 10000, 0.25, 4096, base_name + "k_rope"); } if (cache_limit > 0) { - k_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(kv_head_size, attn_hidden_dim, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); + k_cache = KVCache(kv_head_size, head_dim, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); + v_cache = KVCache(kv_head_size, head_dim, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); } softmax = Softmax(DIMENSION, do_mask, base_name + "softmax"); - o_proj = Linear(head_size * attn_hidden_dim, hidden_dim, false, base_name + names._o_proj_name); + o_proj = Linear(head_size * head_dim, hidden_dim, false, base_name + names._o_proj_name); } vector Forward(vector inputs, vector args) override { Tensor q, k, v; q = q_proj(inputs[0]); k = k_proj(inputs[1]); v = v_proj(inputs[2]); - q = q.view(-1, head_size_, -1, attn_hidden_dim_); - k = k.view(-1, kv_head_size_, -1, attn_hidden_dim_); - v = v.view(-1, kv_head_size_, -1, attn_hidden_dim_); + q = q.view(-1, head_size_, -1, head_dim_); + k = k.view(-1, kv_head_size_, -1, head_dim_); + v = v.view(-1, kv_head_size_, -1, head_dim_); if (q_rope.ready() && k_rope.ready()) { q = q_rope(q); k = k_rope(k); @@ -70,11 +70,11 @@ class StableLMMultiHeadAttention final : public Module { } else { // eager implementation k = k.transpose(SEQUENCE, DIMENSION); auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(attn_hidden_dim_); + qk = qk / std::sqrt(head_dim_); qk = softmax(qk, k_cache.getCacheSeqLen()); o = Tensor::mm(qk, v); } - o = o.view(-1, 1, -1, attn_hidden_dim_ * head_size_); + o = o.view(-1, 1, -1, head_dim_ * head_size_); o = o_proj(o); return {o}; } diff --git a/src/models/tinyllama/modeling_tinyllama.hpp b/src/models/tinyllama/modeling_tinyllama.hpp index 69facdf51..6ee6e335b 100644 --- a/src/models/tinyllama/modeling_tinyllama.hpp +++ b/src/models/tinyllama/modeling_tinyllama.hpp @@ -22,9 +22,9 @@ class TinyLLaMABlock final : public Module { TinyLLaMABlock() = default; TinyLLaMABlock(int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, string attn_implementation, const LLaMANameConfig &names, const string &base_name) { attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, - hidden_dim / head_size, SPLIT_NONE, false, false, + hidden_dim / head_size, SPLIT_NONE, PostQkv_NONE, false, RoPE_type, rope_theta, max_position_embeddings, - cache_limit, true, false, + cache_limit, true, false, false, attn_implementation, names, base_name + names._attn_base_name); mlp = LLaMAMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); diff --git a/src/models/transformer/modeling_transformer.hpp b/src/models/transformer/modeling_transformer.hpp index b243f46d5..a0ec1d9bb 100644 --- a/src/models/transformer/modeling_transformer.hpp +++ b/src/models/transformer/modeling_transformer.hpp @@ -12,6 +12,24 @@ using namespace mllm; +struct MultiHeadAttentionConfig { + int hidden_dim; + int num_heads; + int num_key_value_heads; + int head_dim; + AttnQKVSplitType do_qkv_proj = SPLIT_NONE; // Options: SPLIT_NONE, SPLIT_HD, SPLIT_D_HD + AttnPostQkvNormType post_qkv_norm = PostQkv_NONE; + bool bias_kv_cat = false; // Only used when do_qkv_proj > 0 + RoPEType RoPE_type = RoPEType::NONE; // Options: NONE, ALIBI, ROPE, PERSIMMONROPE + float rope_theta; + int max_position_embeddings; + int cache_limit; + bool is_causal; + bool qkv_bias; + bool o_bias; + string attn_implementation = "flash_attention_2"; // Options: "flash_attention_2", "eager" +}; + class MultiHeadAttention final : public Module { Layer qkv_proj; Layer q_proj; @@ -27,62 +45,75 @@ class MultiHeadAttention final : public Module { Layer o_proj; Parameter bias_k; Parameter bias_v; - int head_size_{}; - int kv_head_size_{}; - int attn_hidden_dim_{}; + int num_heads_{}; + int num_key_value_heads_{}; + int head_dim_{}; Chl split_chl_{}; bool causal_mask = true; string attn_implementation_ = "flash_attention_2"; // Options: "flash_attention_2", "eager" + bool head_first_attn = false; // 是否是head-first的注意力排布实现 public: MultiHeadAttention() = default; - MultiHeadAttention(int hidden_dim, int head_size, int kv_head_size, int attn_hidden_dim, - AttnQKVSplitType do_qkv_proj, bool post_qkv_norm, bool bias_kv_cat, + MultiHeadAttention(MultiHeadAttentionConfig config, + const TransformerNameConfig &names, const string &base_name) { + MultiHeadAttention(config.hidden_dim, config.num_heads, + config.num_key_value_heads, config.head_dim, + config.do_qkv_proj, config.post_qkv_norm, config.bias_kv_cat, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, + config.cache_limit, config.is_causal, config.qkv_bias, config.o_bias, + config.attn_implementation, names, base_name); + } + MultiHeadAttention(int hidden_dim, int num_heads, int num_key_value_heads, int head_dim, + AttnQKVSplitType do_qkv_proj, AttnPostQkvNormType post_qkv_norm, bool bias_kv_cat, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, - int cache_limit, bool do_mask, bool bias, + int cache_limit, bool is_causal, bool qkv_bias, bool o_bias, string attn_implementation, const TransformerNameConfig &names, const string &base_name) { - attn_hidden_dim_ = attn_hidden_dim; - head_size_ = head_size; - kv_head_size_ = kv_head_size; - causal_mask = do_mask; + head_dim_ = head_dim; + num_heads_ = num_heads; + num_key_value_heads_ = num_key_value_heads; + causal_mask = is_causal; attn_implementation_ = attn_implementation; if (do_qkv_proj > 0) { - qkv_proj = Linear(hidden_dim, head_size * attn_hidden_dim * 3, bias, base_name + names._qkv_proj_name); + qkv_proj = Linear(hidden_dim, num_heads * head_dim * 3, qkv_bias, base_name + names._qkv_proj_name); split_chl_ = (Chl)do_qkv_proj; } else { - q_proj = Linear(hidden_dim, head_size * attn_hidden_dim, bias, base_name + names._q_proj_name); - k_proj = Linear(hidden_dim, kv_head_size * attn_hidden_dim, bias, base_name + names._k_proj_name); - v_proj = Linear(hidden_dim, kv_head_size * attn_hidden_dim, bias, base_name + names._v_proj_name); + q_proj = Linear(hidden_dim, num_heads * head_dim, qkv_bias, base_name + names._q_proj_name); + k_proj = Linear(hidden_dim, num_key_value_heads * head_dim, qkv_bias, base_name + names._k_proj_name); + v_proj = Linear(hidden_dim, num_key_value_heads * head_dim, qkv_bias, base_name + names._v_proj_name); } - if (post_qkv_norm) { - q_norm = LayerNorm(attn_hidden_dim, true, 1e-6, base_name + names._q_norm_name); - k_norm = LayerNorm(attn_hidden_dim, true, 1e-6, base_name + names._k_norm_name); + if (post_qkv_norm == PostQkv_LayerNorm) { + q_norm = LayerNorm(head_dim, true, 1e-6, base_name + names._q_norm_name); + k_norm = LayerNorm(head_dim, true, 1e-6, base_name + names._k_norm_name); + }else if (post_qkv_norm == PostQkv_RMSNorm) { + q_norm = RMSNorm(head_dim, 1e-6, base_name + names._q_norm_name); + k_norm = RMSNorm(head_dim, 1e-6, base_name + names._k_norm_name); } if (RoPE_type > 0) { q_rope = RoPE(RoPE_type, rope_theta, max_position_embeddings, base_name + "q_rope"); k_rope = RoPE(RoPE_type, rope_theta, max_position_embeddings, base_name + "k_rope"); } if (cache_limit > 0) { - k_cache = KVCache(kv_head_size, attn_hidden_dim, - head_size / kv_head_size, cache_limit, + k_cache = KVCache(num_key_value_heads, head_dim, + num_heads / num_key_value_heads, cache_limit, (attn_implementation_ == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(kv_head_size, attn_hidden_dim, - head_size / kv_head_size, cache_limit, + v_cache = KVCache(num_key_value_heads, head_dim, + num_heads / num_key_value_heads, cache_limit, (attn_implementation_ == "flash_attention_2"), base_name + "v_cache"); } - softmax = Softmax(DIMENSION, do_mask, base_name + "softmax"); - o_proj = Linear(head_size * attn_hidden_dim, hidden_dim, bias, base_name + names._o_proj_name); + softmax = Softmax(DIMENSION, is_causal, base_name + "softmax"); + o_proj = Linear(num_heads * head_dim, hidden_dim, o_bias, base_name + names._o_proj_name); if (bias_kv_cat) { - bias_k = Parameter(1, 1, head_size, attn_hidden_dim, base_name + "bias_k"); - bias_v = Parameter(1, 1, head_size, attn_hidden_dim, base_name + "bias_v"); + bias_k = Parameter(1, 1, num_heads, head_dim, base_name + "bias_k"); + bias_v = Parameter(1, 1, num_heads, head_dim, base_name + "bias_v"); } } vector Forward(vector inputs, vector args) override { Tensor q, k, v; if (qkv_proj.ready()) { auto qkv = qkv_proj(inputs[0]); - auto qkv_sp = qkv.split({attn_hidden_dim_, attn_hidden_dim_, attn_hidden_dim_}, split_chl_, head_size_); + auto qkv_sp = qkv.split({head_dim_, head_dim_, head_dim_}, split_chl_, num_heads_); q = qkv_sp[0]; k = qkv_sp[1]; v = qkv_sp[2]; @@ -90,9 +121,9 @@ class MultiHeadAttention final : public Module { q = q_proj(inputs[0]); k = k_proj(inputs[1]); v = v_proj(inputs[2]); - q = q.view(-1, head_size_, -1, attn_hidden_dim_); - k = k.view(-1, kv_head_size_, -1, attn_hidden_dim_); - v = v.view(-1, kv_head_size_, -1, attn_hidden_dim_); + q = q.view(-1, num_heads_, -1, head_dim_); + k = k.view(-1, num_key_value_heads_, -1, head_dim_); + v = v.view(-1, num_key_value_heads_, -1, head_dim_); } if (q_norm.ready() && k_norm.ready()) { q = q_norm(q); @@ -106,6 +137,11 @@ class MultiHeadAttention final : public Module { q = q_rope(q); k = k_rope(k); } + if(head_first_attn){ + q = q.transpose(HEAD, SEQUENCE); + k = k.transpose(HEAD, SEQUENCE); + v = v.transpose(HEAD, SEQUENCE); + } if (k_cache.ready() && v_cache.ready()) { k = k_cache(k); v = v_cache(v); @@ -116,7 +152,7 @@ class MultiHeadAttention final : public Module { } else { // eager implementation k = k.transpose(SEQUENCE, DIMENSION); auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(attn_hidden_dim_); + qk = qk / std::sqrt(head_dim_); if (k_cache.ready() && v_cache.ready()) { qk = softmax(qk, k_cache.getCacheSeqLen()); } else { @@ -124,7 +160,10 @@ class MultiHeadAttention final : public Module { } o = Tensor::mm(qk, v); } - o = o.view(-1, 1, -1, attn_hidden_dim_ * head_size_); + if(head_first_attn){ + o = o.transpose(HEAD, SEQUENCE); + } + o = o.view(-1, 1, -1, head_dim_ * num_heads_); o = o_proj(o); return {o}; } diff --git a/src/models/vit/modeling_vit.hpp b/src/models/vit/modeling_vit.hpp index a26634132..ec78678ce 100644 --- a/src/models/vit/modeling_vit.hpp +++ b/src/models/vit/modeling_vit.hpp @@ -39,9 +39,9 @@ class ViTBlock final : public Module { ViTBlock() = default; ViTBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, string attn_implementation, const ViTNameConfig &names, const string &base_name) { - attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, SPLIT_NONE, - false, false, RoPEType::NONE, - -1, -1, 0, false, true, attn_implementation, + attention = MultiHeadAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, + SPLIT_NONE,PostQkv_NONE, false, RoPEType::NONE, + -1, -1, 0, false, true, true, attn_implementation, names, base_name + names._attn_base_name); mlp = ViTMLP(hidden_dim, ffn_hidden, act_fn_type, names, base_name + names._ffn_base_name); down_proj = Linear(ffn_hidden, hidden_dim, true, base_name + names._down_proj_name); diff --git a/src/quantizer/QuantWriter.cpp b/src/quantizer/QuantWriter.cpp index 91fa43829..13b839d27 100644 --- a/src/quantizer/QuantWriter.cpp +++ b/src/quantizer/QuantWriter.cpp @@ -478,7 +478,7 @@ void QuantWriter::quantParams_q4_vl(DataType dataType) { vector vl_q4x4_2_q4_k_layers = { // "wv", // "v_proj", //eager mode - ".attn.qkv", + // ".attn.qkv", "in_proj", "w12", "model.output", diff --git a/src/quantizer/QuantWriter.hpp b/src/quantizer/QuantWriter.hpp index a341f80a8..df2967383 100644 --- a/src/quantizer/QuantWriter.hpp +++ b/src/quantizer/QuantWriter.hpp @@ -5,7 +5,7 @@ #include "backends/cpu/compute/QuantizeQ3.hpp" #include "backends/cpu/compute/QuantizeQ4.hpp" #include "backends/cpu/compute/QuantizeQ8.hpp" -#include "backends/cpu/compute/GemmAarch64.hpp" +#include "backends/cpu/compute/GemmPack.hpp" #include "backends/cpu/compute/GemmKleidiai.hpp" #include #include diff --git a/src/quantizer/main.cpp b/src/quantizer/main_quantize.cpp similarity index 84% rename from src/quantizer/main.cpp rename to src/quantizer/main_quantize.cpp index 7a9a145cb..428860d32 100644 --- a/src/quantizer/main.cpp +++ b/src/quantizer/main_quantize.cpp @@ -14,9 +14,19 @@ int main(int argc, char **argv) { auto input_path = std::string(argv[1]); auto output_path = std::string(argv[2]); auto quant_type = std::string(argv[3]); - auto other_flag = std::string(argv[4]); + string other_flag = ""; // "vl" or "eager" + if(argc == 5) { + if (std::string(argv[4]) == "vl" || std::string(argv[4]) == "eager") { + other_flag = std::string(argv[4]); + } else { + std::cout << "Invalid other flag. Use 'vl' or 'eager'.\n"; + return -1; + } + } + // auto other_flag = std::string(argv[4]); // std::string input_path = "../models/qwen-2.5-1.5b-instruct-fp32.mllm"; - // std::string output_path = "../models/qwen-2.5-1.5b-instruct-kai_q4_0.mllm"; + // std::string output_path = "../models/qwen-2.5-1.5b-instruct-kai_q4_0_.mllm"; + // string other_flag = ""; // "vl" or "eager" // std::string input_path = "../models/qwen-2-vl-2b-instruct-fp32.mllm"; // std::string output_path = "../models/qwen-2-vl-2b-instruct-kai_q4_0.mllm"; // std::string quant_type = "KAI_Q4_0"; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2ba7123bc..8984fec20 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,7 +13,7 @@ if(MLLM_BUILD_XNNPACK_BACKEND) ${PROJECT_SOURCE_DIR}/test/xnnpack/*.cpp ) list(APPEND MLLM_XNNPACK_BACKEND_TEST_SRC ${_MLLM_XNNPACK_BACKEND_TEST_SRC}) - list(APPEND MLLM_XNNPACK_BACKEND_TEST_DEP_LIB lib_mllm_xnnpack) + list(APPEND MLLM_XNNPACK_BACKEND_TEST_DEP_LIB mllm_xnnpack) list(REMOVE_ITEM MLLM_XNNPACK_BACKEND_TEST_SRC ${PROJECT_SOURCE_DIR}/test/xnnpack/XpEmbeddingTest.cpp) endif() @@ -53,7 +53,7 @@ add_executable( target_link_libraries( MLLM_TEST GTest::gtest_main - lib_mllm_cpu + mllm_cpu -fopenmp ${MLLM_XNNPACK_BACKEND_TEST_DEP_LIB} ) diff --git a/test/xnnpack/XpLlamaMHATest.cpp b/test/xnnpack/XpLlamaMHATest.cpp index 540f441ad..e8f656c8c 100644 --- a/test/xnnpack/XpLlamaMHATest.cpp +++ b/test/xnnpack/XpLlamaMHATest.cpp @@ -28,7 +28,7 @@ class XpLLaMAMHA final : public Module { int head_size_ = 0; int kv_head_size_ = 0; - int attn_hidden_dim_ = 0; + int head_dim_ = 0; public: XpLLaMAMHA() = default; @@ -37,16 +37,16 @@ class XpLLaMAMHA final : public Module { int hidden_dim, int head_size, int kv_head_size, - int attn_hidden_dim, + int head_dim, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, const XpLLaMAMHANameCfg &names, const string &base_name) { - q_proj = Linear(hidden_dim, head_size * attn_hidden_dim, false, base_name + names._q_proj_name); - k_proj = Linear(hidden_dim, kv_head_size * attn_hidden_dim, false, base_name + names._k_proj_name); - v_proj = Linear(hidden_dim, kv_head_size * attn_hidden_dim, false, base_name + names._v_proj_name); + q_proj = Linear(hidden_dim, head_size * head_dim, false, base_name + names._q_proj_name); + k_proj = Linear(hidden_dim, kv_head_size * head_dim, false, base_name + names._k_proj_name); + v_proj = Linear(hidden_dim, kv_head_size * head_dim, false, base_name + names._v_proj_name); q_rope = RoPE(RoPE_type, rope_theta, max_position_embeddings, base_name + "q_rope"); k_rope = RoPE(RoPE_type, rope_theta, max_position_embeddings, base_name + "k_rope"); @@ -54,13 +54,13 @@ class XpLLaMAMHA final : public Module { k_cache = XP_KVCache(head_size / kv_head_size, cache_limit, base_name + "k_cache"); v_cache = XP_KVCache(head_size / kv_head_size, cache_limit, base_name + "v_cache"); - o_proj = Linear(head_size * attn_hidden_dim, hidden_dim, false, base_name + names._o_proj_name); + o_proj = Linear(head_size * head_dim, hidden_dim, false, base_name + names._o_proj_name); sdpa = ScaledDotProductAttention("sdpa"); head_size_ = head_size; kv_head_size_ = kv_head_size; - attn_hidden_dim_ = attn_hidden_dim; + head_dim_ = head_dim; } vector @@ -73,9 +73,9 @@ class XpLLaMAMHA final : public Module { // q = q.view(bsz, q_len, num_heads, head_dim) // [B, S, H=heads, D=dim] - q = q.view(-1, head_size_, -1, attn_hidden_dim_); - k = k.view(-1, kv_head_size_, -1, attn_hidden_dim_); - v = v.view(-1, kv_head_size_, -1, attn_hidden_dim_); + q = q.view(-1, head_size_, -1, head_dim_); + k = k.view(-1, kv_head_size_, -1, head_dim_); + v = v.view(-1, kv_head_size_, -1, head_dim_); q = q_rope(q); k = k_rope(k); @@ -94,7 +94,7 @@ class XpLLaMAMHA final : public Module { // [B, H, S, D] -> [B, S, H, D] o = o.transpose(SEQUENCE, HEAD); // [B, S, H, D] -> [B, S, 1, H * D] - o = o.view(-1, 1, -1, attn_hidden_dim_ * head_size_); + o = o.view(-1, 1, -1, head_dim_ * head_size_); o = o_proj(o); return {o}; From 012bfa604cc4ef267f433f6a91f1abced4402167 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Wed, 25 Jun 2025 13:32:30 +0800 Subject: [PATCH 10/22] fix: cpubackend --- include/OpDefined.hpp | 107 +- src/Backend.hpp | 16 +- src/Layer.hpp | 44 +- src/Module.cpp | 3 - src/Module.hpp | 3 + src/ParamLoader.cpp | 206 +- src/ParamLoader.hpp | 1 + src/Tensor.cpp | 438 ++- src/Tensor.hpp | 306 +- src/TensorImpl.hpp | 22 +- src/backends/cpu/CPUBackend.cpp | 670 ++-- src/backends/cpu/CPUBackend.hpp | 22 +- src/backends/cpu/compute/FlashAttention2.hpp | 2695 ++++++----------- src/backends/cpu/function/CPUSplitFunc.hpp | 2 + .../cpu/function/CPUTransposeFunc.hpp | 2 +- src/backends/cpu/op/CPUArgSortFunc.hpp | 71 + src/backends/cpu/op/CPUBinCountFunc.hpp | 81 + src/backends/cpu/op/CPUBinaryFunc.hpp | 379 +++ src/backends/cpu/op/CPUCatFunc.hpp | 328 ++ src/backends/cpu/op/CPUClipFunc.hpp | 357 +++ src/backends/cpu/op/CPUExpandFunc.hpp | 103 + .../cpu/op/CPUFlashAttention2Func.hpp | 126 + src/backends/cpu/op/CPUFlattenFunc.hpp | 126 + src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp | 77 + src/backends/cpu/op/CPUIndexPutFunc.hpp | 148 + src/backends/cpu/op/CPULikeFunc.hpp | 48 + src/backends/cpu/op/CPUMatmulFunc.hpp | 116 + src/backends/cpu/op/CPUMeanFunc.hpp | 140 + src/backends/cpu/op/CPUNormFunc.hpp | 80 + src/backends/cpu/op/CPUPhi3VhdmergeFunc.hpp | 102 + src/backends/cpu/op/CPURangeFunc.hpp | 57 + src/backends/cpu/op/CPURepeatFunc.hpp | 106 + src/backends/cpu/op/CPUScatterReduceFunc.hpp | 67 + src/backends/cpu/op/CPUSplitFunc.hpp | 206 ++ src/backends/cpu/op/CPUSumFunc.hpp | 133 + src/backends/cpu/op/CPUTopkFunc.hpp | 87 + src/backends/cpu/op/CPUTransposeFunc.hpp | 182 ++ src/backends/cpu/op/CPUViewFunc.hpp | 147 + src/backends/cpu/op/CPUVisionRoPEFunc.hpp | 168 + src/backends/cpu/op/CPUWhereFunc.hpp | 115 + src/backends/cpu/third_party/kleidiai | 2 +- src/backends/qnn/QNNBackend.cpp | 279 +- src/backends/qnn/QNNBackend.hpp | 2 +- src/backends/xnnpack/XnnpackBackend.cpp | 444 ++- src/backends/xnnpack/XnnpackBackend.hpp | 7 +- 45 files changed, 5823 insertions(+), 2998 deletions(-) create mode 100644 src/backends/cpu/op/CPUArgSortFunc.hpp create mode 100644 src/backends/cpu/op/CPUBinCountFunc.hpp create mode 100644 src/backends/cpu/op/CPUBinaryFunc.hpp create mode 100644 src/backends/cpu/op/CPUCatFunc.hpp create mode 100644 src/backends/cpu/op/CPUClipFunc.hpp create mode 100644 src/backends/cpu/op/CPUExpandFunc.hpp create mode 100644 src/backends/cpu/op/CPUFlashAttention2Func.hpp create mode 100644 src/backends/cpu/op/CPUFlattenFunc.hpp create mode 100644 src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp create mode 100644 src/backends/cpu/op/CPUIndexPutFunc.hpp create mode 100644 src/backends/cpu/op/CPULikeFunc.hpp create mode 100644 src/backends/cpu/op/CPUMatmulFunc.hpp create mode 100644 src/backends/cpu/op/CPUMeanFunc.hpp create mode 100644 src/backends/cpu/op/CPUNormFunc.hpp create mode 100644 src/backends/cpu/op/CPUPhi3VhdmergeFunc.hpp create mode 100644 src/backends/cpu/op/CPURangeFunc.hpp create mode 100644 src/backends/cpu/op/CPURepeatFunc.hpp create mode 100644 src/backends/cpu/op/CPUScatterReduceFunc.hpp create mode 100644 src/backends/cpu/op/CPUSplitFunc.hpp create mode 100644 src/backends/cpu/op/CPUSumFunc.hpp create mode 100644 src/backends/cpu/op/CPUTopkFunc.hpp create mode 100644 src/backends/cpu/op/CPUTransposeFunc.hpp create mode 100644 src/backends/cpu/op/CPUViewFunc.hpp create mode 100644 src/backends/cpu/op/CPUVisionRoPEFunc.hpp create mode 100644 src/backends/cpu/op/CPUWhereFunc.hpp diff --git a/include/OpDefined.hpp b/include/OpDefined.hpp index 76b8a35c0..20b5c30f9 100644 --- a/include/OpDefined.hpp +++ b/include/OpDefined.hpp @@ -82,78 +82,45 @@ enum OpType { // for speculative decoding ROPETREE, CAUSALTREEMASK, -}; -static const vector OpNames = { - "INVALID_VALUE", - "Parameter", - "Add", - "SoftMax", - "SiLU", - "MatMul", - "MatMulINT8", - "Scale", - "RoPE", - "RMSNorm", - "CausalMask", - "SlidingWindowMask", - "Linear", - "LinearINT8", - "LinearINT8Shadow", - "Embedding", - "Mul", - "VIEW", - "KVCACHE", - "KVCACHENPU", - "ReLU", - "ReLUSquaredActivation", - "GELU", - "QuickGELU", - "LayerNorm", - "Split", - "Gqther", - "Convolution2D", - "Convolution3D", - "VisonRoPE", - "MultimodalRoPEPipeline", - "MultimodalRoPE", - "AvgPool2D", - "MaxPool2D", - "Cat", - "Transpose", - "SubDim", - "Division", - "Norm", - "Shape", - "Mean", - "Range", - "Where", - "Replace", - "Predictor", - "SparseLinear", - "SparseIdLinear", - "ElasticLinear", - "Position", - "WNop", - "Quantize", - "Dequantize", - "MergeOutput", - "SplitInput", - "IRoPE", - "OP_NUM", - // in xnnpack - "Direct", - "Dispatch", - "SubgraphStart", - "SubgraphFinalize", - "D2H", - "XP_KVCACHE", - "SDPA", - "SuperSiLU", - "HeadLinear", - "RoPETree", - "CausalTreeMask", + // + F_ADD, + F_SUB, + F_MUL, + F_DIV, + F_DIVINT, + F_TTADD, + F_TTSUB, + F_TTMUL, + F_TTDIV, + F_MM, + F_NORM, + F_MEAN, + F_CAT, + F_VIEW, + F_TRANPOSE, + F_FLATTEN, + F_CLIP, + F_CLIPAXIS, + F_CLIPTENSOR, + F_RANGE, + F_WHERE, + F_INDEX_PUT, + F_SPLIT, + F_SUM, + F_TOPK, + F_EXPPAND, + F_ARGSORT, + F_BINCOUNT, + F_REPEAT, + F_LIKE, + F_SCATTERREDUCE, + F_APPLY_VISIOROPE, + F_FA2, + // models use only + F_FUYU_GATHER_EMBD, + F_PHI3V_HD_MERGE, }; enum TensorFuncType { diff --git a/src/Backend.hpp b/src/Backend.hpp index a0ac69bdb..38af3f146 100644 --- a/src/Backend.hpp +++ b/src/Backend.hpp @@ -18,9 +18,7 @@ class Module; class Layer; // KVCache map for QNN-CPU KVCache sharing -#ifdef USE_QNN static std::unordered_map kv_cache_map; -#endif class TensorFunction { public: @@ -73,13 +71,15 @@ class Backend { * @param in_place Whether to run the function in place. * @return std::vector The output tensors. */ - virtual std::vector runFunc( - std::vector out_names, - TensorFuncType type, - std::vector float_args, - std::vector> input_tensors, - bool in_place) = 0; + // virtual std::vector runFunc( + // std::vector out_names, + // TensorFuncType type, + // std::vector float_args, + // std::vector input_tensors, + // bool in_place) = 0; virtual std::vector runLayer(Layer *layer, std::vector inputs, int N) = 0; + + virtual std::vector runOp(Op *op, std::vector input, std::vector out_names, bool in_place) = 0; virtual std::vector runForward(Module *module, std::vector inputs, std::vector args) = 0; virtual void onSetUpStart(vector> &inputs, vector> &outputs, string graphName = ""){}; diff --git a/src/Layer.hpp b/src/Layer.hpp index 56b40c3c8..aca011d90 100644 --- a/src/Layer.hpp +++ b/src/Layer.hpp @@ -63,31 +63,29 @@ class Layer { return ts[0]; } - void load() { - if (inited_loaded && loaded_param) - return; - if (op_ == nullptr) { -#ifdef USE_QNN - if ((param_["type"] == KVCACHE || param_["type"] == KVCACHENPU) && (Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end())) { + void initOp(){ + if (op_ == nullptr) { + if ((param_["type"] == KVCACHE || param_["type"] == KVCACHENPU) + && (Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end())) { if (kv_cache_map.find(name_) == kv_cache_map.end()) { // for the prefill part, we need to create a new op param_["type"] = KVCACHENPU; op_ = backend_->opCreate(param_, name_); kv_cache_map[name_] = op_; } else { -#ifdef DEBUGPRINT - std::cout << name_ << " is shared used" << std::endl; -#endif // for the decoding part, we need to get created op from global container op_ = kv_cache_map[name_]; } } else { op_ = backend_->opCreate(param_, name_); } -#else - op_ = backend_->opCreate(param_, name_); -#endif } + } + + void load() { + initOp(); + if (inited_loaded && loaded_param) + return; op_->load(*Module::llm_model_ptr->loader); loaded_param = true; } @@ -101,11 +99,31 @@ class Layer { protected: vector run(vector inputs, int N = 1) { + initOp(); + Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); + if (module->doLoad || !inited_loaded) {//load + if (module->doLoad) { + op_->load(*module->loader); + inited_loaded = true; + } else if (loaded_param) { + inited_loaded = loaded_param; + } else if (!inited_loaded) { + auto empty_loader = new ParamLoader(""); + op_->load(*empty_loader); + inited_loaded = true; + } + } auto backend = inputs.empty() ? Backend::global_backends[MLLM_CPU] : inputs[0].backend(); if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { backend = Backend::global_backends[MLLM_QNN]; } - return backend->runLayer(this, inputs, N); + vector out_names; + int count = (N > 1) ? N : 1; + for (int i = 0; i < count; ++i) { + std::string tensor_name = (N > 1) ? "out-" + op_->name() + "-" + std::to_string(i) : "out-" + op_->name(); + out_names.push_back(tensor_name); + } + return backend->runOp(op_, inputs, out_names, false); } public: diff --git a/src/Module.cpp b/src/Module.cpp index 3810c81df..85260222e 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -8,9 +8,6 @@ namespace mllm { -// AbstructLoader *Module::loader; -// TensorStatus Tensor::tensor_status; -// bool Module::doLoad = false; // The llm_model_ptr is a pointer to the outmost module Module *Module::llm_model_ptr; diff --git a/src/Module.hpp b/src/Module.hpp index d7d9fb9a3..f4999f37a 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -56,6 +56,7 @@ class Module { map activation_tensors_num; AbstructLoader *loader; bool doLoad = false; + bool doTrace = false; bool op_transposed_flag = false; static Module *llm_model_ptr; @@ -148,6 +149,7 @@ class Module { loader = ¶m_loader; doLoad = true; + doTrace = true; vector tmps; int max_in_size = 5; for (int i = 0; i < max_in_size; ++i) { @@ -184,6 +186,7 @@ class Module { uint64_t time_end = mllm_time_us(); load_time_ = (time_end - time_start) / 1000.0F; // ms doLoad = false; + doTrace = false; } virtual vector Forward(vector inputs, vector args) = 0; diff --git a/src/ParamLoader.cpp b/src/ParamLoader.cpp index e22568e82..98b743674 100644 --- a/src/ParamLoader.cpp +++ b/src/ParamLoader.cpp @@ -30,6 +30,8 @@ * Weights File Structure */ namespace mllm { + +/* bool ParamLoader::load(mllm::Tensor *tensor) { string name = tensor->name(); if (!use_mmap_) { @@ -41,49 +43,95 @@ bool ParamLoader::load(mllm::Tensor *tensor) { size_t read_size = std::min(tensor->cntSize(), static_cast(offset.second)); auto _ = fread(p, sizeof(uint8_t), read_size, fp_); - /* + return true; + } else { // USE_MMAP is defined + if (mmap_buffer_ == nullptr || offsets_.find(name) == offsets_.end()) { + return false; + } + std::lock_guard lock(mtx); + auto offset_info = offsets_[name]; + + // --- 在这里加入对齐诊断代码 --- + int required_alignment = DataTypeSize(tensor->dtype()); // 获取数据类型的大小,如 float 是 4 + if (required_alignment == 0) required_alignment = 1; // 避免除零 + + bool is_aligned = (offset_info.first % required_alignment == 0); + + if (!is_aligned) { + fprintf(stderr, "[ALIGNMENT ERROR] Tensor: '%s', DataType: %d, Offset: %llu, Required Alignment: %d. DATA IS MISALIGNED!\n", + name.c_str(), + tensor->dtype(), + (unsigned long long)offset_info.first, + required_alignment); + } else { + // (可选) 打印出对齐正确的信息,用于确认 + // fprintf(stdout, "[ALIGNMENT OK] Tensor: '%s', Offset: %llu, Alignment: %d.\n", + // name.c_str(), (unsigned long long)offset_info.first, required_alignment); + } + // --- 诊断代码结束 --- + + // 如果不对齐,直接返回失败,因为我们不允许拷贝 + if (!is_aligned) { + return false; + } + + // 只有在对齐检查通过后,才执行零拷贝的指针赋值 + if (tensor->cntSize() != offset_info.second) { return false; } + uint8_t* source_ptr = mmap_buffer_.get() + offset_info.first; + tensor->setHostPtr(source_ptr, mmap_buffer_); + + return true; + } +} + */ +// 在 ParamLoader.cpp 中 +bool ParamLoader::load(mllm::Tensor *tensor) { + string name = tensor->name(); + if (!use_mmap_) { + // --- 非 mmap 模式,逻辑保持不变 --- + // 确保 Tensor 已经分配内存 + // if (tensor->rawHostPtr() == nullptr) { + // tensor->alloc(); + // } + std::lock_guard lock(mtx); if (offsets_.find(name) == offsets_.end()) { return false; } std::pair offset = offsets_[name]; - uint8_t *data = new uint8_t[offset.second]; - fseek(fp_, offset.first, SEEK_SET); - auto _ = fread(data, sizeof(uint8_t), offset.second, fp_); - // TODO:Data? - // tenor. = data; auto *p = tensor->hostPtr(); - - if (tensor->cntSize() >= offset.second) - memcpy(static_cast(p), static_cast(data), - offset.second); // Cast pointers to void* - else - memcpy(static_cast(p), static_cast(data), - tensor->cntSize()); // Cast pointers to void* - delete[] data; // Free the memory allocated by new - */ + fseek(fp_, offset.first, SEEK_SET); + size_t read_size = std::min(tensor->cntSize(), static_cast(offset.second)); + auto _ = fread(p, sizeof(uint8_t), read_size, fp_); return true; - } else { // USE_MMAP is defined - // 确保 buffer_ 和 offsets_ 已经为 mmap 正确初始化 - if (!use_mmap_ || buffer_ == nullptr || offsets_.find(name) == offsets_.end()) { - // 可以选择打印错误信息或返回 false - // TODO - // if (offsets_.find(name) == offsets_.end()) { - // fprintf(stderr, "Tensor name '%s' not found in offsets.\n", name.c_str()); - // } else { - // fprintf(stderr, "Buffer is null or mmap not initialized.\n"); - // } + } else { + // --- mmap 模式,实现智能选择 --- + if (mmap_buffer_ == nullptr || offsets_.find(name) == offsets_.end()) { return false; } - std::lock_guard lock(mtx); // mmap 访问也可能需要同步,取决于使用场景 - std::pair offset_info = offsets_[name]; - auto *p = tensor->hostPtr(); // 获取 tensor 的主机指针 - - // 计算源数据指针 - uint8_t *source_ptr = buffer_ + offset_info.first; + std::lock_guard lock(mtx); + auto offset_info = offsets_[name]; - // 要拷贝的数据大小,取 tensor 大小和参数大小的最小值 - size_t copy_size = std::min(tensor->cntSize(), static_cast(offset_info.second)); + // 1. 检查对齐 + int required_alignment = DataTypeSize(tensor->dtype()); + if (required_alignment == 0) required_alignment = 1; + bool is_aligned = (offset_info.first % required_alignment == 0); - // 从内存映射的 buffer_ 拷贝数据到 tensor - memcpy(static_cast(p), static_cast(source_ptr), copy_size); + // 2. 尺寸检查 + if (tensor->cntSize() != offset_info.second) { + fprintf(stderr, "Error: Tensor '%s' size mismatch. Code wants %zu, file has %llu.\n", + name.c_str(), tensor->cntSize(), (unsigned long long)offset_info.second); + return false; + } + is_aligned = false; + if (is_aligned) { + // -- 对齐:执行零拷贝 -- + uint8_t* source_ptr = mmap_buffer_.get() + offset_info.first; + // setHostPtr 会处理好一切(包括释放之前 alloc 的内存) + tensor->setHostPtr(source_ptr, mmap_buffer_); + } else { + // -- 未对齐:回退到 memcpy -- + // 从 mmap 区域拷贝数据到 Tensor 自己拥有的内存中 + uint8_t* source_ptr = mmap_buffer_.get() + offset_info.first; + memcpy(tensor->rawHostPtr(), source_ptr, tensor->cntSize()); + } return true; } @@ -108,89 +156,91 @@ ParamLoader::ParamLoader(std::string filename, bool use_mmap_param) : path_(std::move(filename)), use_mmap_(use_mmap_param), fp_(nullptr), buffer_(nullptr), size_(0) { // Initialize new members if (use_mmap_) { - // 1. 打开文件 + // --- 1. 打开文件并获取文件描述符 --- FILE *temp_fp = fopen(this->path_.c_str(), "rb"); if (temp_fp == nullptr) { // perror(("Error opening file for mmap: " + this->path_).c_str()); - // exit(1); // Or handle error differently + // 无法打开文件,直接返回,保持 ParamLoader 为不可用状态 return; } - // 2. 获取文件大小 + // --- 2. 获取文件大小 --- fseek(temp_fp, 0, SEEK_END); size_ = ftell(temp_fp); - fseek(temp_fp, 0, SEEK_SET); // Reset to beginning - - // 3. 内存映射 (示例使用 POSIX mmap) - // #include - // #include - // #include - int fd = fileno(temp_fp); // Get file descriptor - buffer_ = (uint8_t *)mmap(NULL, size_, PROT_READ, MAP_PRIVATE, fd, 0); - if (buffer_ == MAP_FAILED) { + // fseek(temp_fp, 0, SEEK_SET); // mmap不需要重置文件指针 + + // --- 3. 执行内存映射 --- + int fd = fileno(temp_fp); // 获取文件描述符 + uint8_t* mapped_ptr = (uint8_t *)mmap(NULL, size_, PROT_READ, MAP_PRIVATE, fd, 0); + + // mmap完成后,文件描述符即可关闭,映射关系依然存在 + fclose(temp_fp); + + if (mapped_ptr == MAP_FAILED) { perror("mmap failed"); - fclose(temp_fp); // Close the temporary file pointer - buffer_ = nullptr; // Mark buffer as invalid - use_mmap_ = false; // Fallback or indicate error - // exit(1); // Or handle error differently + use_mmap_ = false; // mmap失败,可以考虑回退到非mmap模式或标记为失败 return; } - // 文件描述符可以关闭了,mmap 会保持映射 - // fclose(temp_fp); // Or keep fp_ as the original file pointer if needed for non-mmap fallback - // 4. 从 buffer_ 读取元数据 (类似于 readInt, readString 等,但操作指针) - uint8_t *current_ptr = buffer_; + // --- 4. 将 mmap 指针包装到带自定义删除器的 shared_ptr 中 --- + auto mmap_size = this->size_; + this->mmap_buffer_ = std::shared_ptr(mapped_ptr, [mmap_size](uint8_t *p) { + // 自定义删除器:当 shared_ptr 引用计数归零时,调用 munmap + munmap(p, mmap_size); + }); + + // ==================================================================== + // --- 5. 从 mmap 内存区域中解析元数据 --- + // ==================================================================== + + // 定义一系列在内存指针上操作的辅助 lambda 函数,用于替代原先在 FILE* 上的操作 auto mmap_readInt = [&](uint8_t *&ptr) { int32_t val; memcpy(&val, ptr, sizeof(int32_t)); - ptr += sizeof(int32_t); + ptr += sizeof(int32_t); // 移动指针 return val; }; auto mmap_readu64 = [&](uint8_t *&ptr) { uint64_t val; memcpy(&val, ptr, sizeof(uint64_t)); - ptr += sizeof(uint64_t); + ptr += sizeof(uint64_t); // 移动指针 return val; }; auto mmap_readString = [&](uint8_t *&ptr) { int len = mmap_readInt(ptr); - std::string str((char *)ptr, len); - ptr += len; + if (len == 0) return std::string(""); + std::string str(reinterpret_cast(ptr), len); + ptr += len; // 移动指针 return str; }; + // 获取指向 mmap 区域开头的当前指针 + uint8_t *current_ptr = mmap_buffer_.get(); + + // a. 读取并验证幻数 int magic = mmap_readInt(current_ptr); if (magic != _MAGIC_NUMBER) { fprintf(stderr, "Mmap: magic number error\n"); - munmap(buffer_, size_); // Unmap memory - buffer_ = nullptr; + this->mmap_buffer_.reset(); // 释放 shared_ptr,触发 munmap use_mmap_ = false; - // exit(1); // Or handle error return; } + // b. 读取索引区域的总长度 uint64_t index_size = mmap_readu64(current_ptr); + + // c. 计算索引区域的结束地址 uint8_t *index_end_ptr = current_ptr + index_size; + // d. 循环读取所有张量的元信息,直到遍历完整个索引区域 while (current_ptr < index_end_ptr) { std::string name = mmap_readString(current_ptr); uint64_t length = mmap_readu64(current_ptr); - // 对于 mmap,offset 通常是相对于 buffer_ 开始的偏移 - // 如果文件格式中的 offset 是相对于文件数据区的绝对偏移,需要调整 - uint64_t offset_in_file = mmap_readu64(current_ptr); // This is the offset as stored in the file - offsets_[name] = std::make_pair(offset_in_file, length); // Store the original offset from file - data_type_[name] = mmap_readInt(current_ptr); - } - // Mmap is set up, fp_ might not be needed or could be temp_fp if kept open - // If you want to keep fp_ for potential non-mmap operations or cleanup: - this->fp_ = temp_fp; // Assign after successful mmap, or keep it as NULL - // If keeping temp_fp, ensure it's closed in destructor if mmap was used. - // Alternatively, just close temp_fp here if all mmap ops are done. - // fclose(temp_fp) was already called if mmap failed. If successful, and you don't need fp_ for mmap path: - // fclose(temp_fp); // Or defer to destructor. For mmap, fd is what mattered. - // Let's assume we close it here if mmap succeeded and fp_ isn't used by mmap logic itself - if (buffer_ != MAP_FAILED) { // if mmap succeeded - // fclose(temp_fp); // Decide on fp_ lifecycle. If mmap is primary, fp_ might be set to nullptr + uint64_t offset_in_file = mmap_readu64(current_ptr); + + // 将解析出的信息存入 map + offsets_[name] = std::make_pair(offset_in_file, length); + data_type_[name] = static_cast(mmap_readInt(current_ptr)); } } else { // USE_MMAP is NOT defined diff --git a/src/ParamLoader.hpp b/src/ParamLoader.hpp index 94e987e61..4fdec25be 100644 --- a/src/ParamLoader.hpp +++ b/src/ParamLoader.hpp @@ -105,6 +105,7 @@ class ParamLoader : public AbstructLoader { std::map> offsets_; // offsets,length std::map data_type_; bool use_mmap_; + std::shared_ptr mmap_buffer_; }; /** diff --git a/src/Tensor.cpp b/src/Tensor.cpp index 28bce496b..2e665fed1 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -5,6 +5,7 @@ #include #include #include "Backend.hpp" +#include "Op.hpp" #include "OpDefined.hpp" #include "Timing.hpp" #include "Types.hpp" @@ -183,136 +184,288 @@ Tensor &Tensor::to(BackendType backend_type) { return *this; }; -// TensorFuctions + + +bool is_kvcached_tensor(const std::shared_ptr &tensor) { + return tensor!= nullptr &&tensor->masterTensor() != nullptr && tensor->masterTensor()->name().find("Cache") != std::string::npos; +} + +/** + * @brief Allocates a single, non-aggregated tensor, deciding between KVCache or standard allocation. + * @param module The current module. + * @param backend The current backend. + * @param standard_alloc_func The function to call for standard allocation. + */ +void Tensor::_allocate_final_tensor( + const std::shared_ptr &template_tensor, + Backend *backend) { + if (is_kvcached_tensor(template_tensor)) { + // It's a KVCache view + auto master_tensor = template_tensor->masterTensor(); + auto cache_seq_len_ = template_tensor->shapeOffset()[2]; + // If this tensor is an input to a KVCache operation, adjust sequence length based on draft tokens + if (name().find("cache") == std::string::npos) { + cache_seq_len_ = master_tensor->cache_seq_len_; + auto cpu_backend = dynamic_cast(backend); + if (cpu_backend->isUsingDraft()) { + unsigned int last_draft_length = cpu_backend->getLastDraftLength(); + const auto &last_verified_position_ids = cpu_backend->getLastVerifiedPositionIds(); + cache_seq_len_ = cache_seq_len_ - last_draft_length + last_verified_position_ids.size(); + } + } + setDtype(master_tensor->dtype()); + shallowCopyFrom(master_tensor, false, {0, 0, cache_seq_len_, 0}); + // } else if (template_tensor!= nullptr &&template_tensor->masterTensor() != nullptr) { + // auto master_tensor = template_tensor->masterTensor(); + // auto cache_seq_len_ = template_tensor->shapeOffset(); + // setDtype(master_tensor->dtype()); + // shallowCopyFrom(master_tensor, false, cache_seq_len_); + } + else { + alloc(); + } +} +/** + * @brief Handles the allocation and setup for an output tensor that is part of an aggregated tensor structure. + * @param template_tensor The corresponding tensor from the activation map, which holds aggregation info. + * @param module The current module. + * @param backend The current backend. + */ +void Tensor::_allocate_aggregated_tensor( + const std::shared_ptr &template_tensor, + Module *module, + Backend *backend) { + bool keep_aggregated_structure = false; + if (template_tensor->aggregatedDim() > 3) { + keep_aggregated_structure = true; // Cannot handle dimensions > 3 + } else { + for (const auto &ag_tensor : template_tensor->aggregatedTensors()) { + if (ag_tensor->ctype() != template_tensor->aggregatedTensors()[0]->ctype() || is_kvcached_tensor(ag_tensor)) { + keep_aggregated_structure = true; + break; + } + } + } + if (keep_aggregated_structure) { + vector> shared_outputs; + auto split_dim = template_tensor->aggregatedDim(); + const auto &ag_tensor = template_tensor->aggregatedTensors(); + for (int id = 0; id < ag_tensor.size(); ++id) { + const auto &child_tt = ag_tensor[id]; + auto shared_ot = std::make_shared(backend); + // shared_ot->setName(out_tensor->name() + ".split-" + std::to_string(id)); + assert(child_tt->name() == name() + ".split-" + std::to_string(id)); + shared_ot->setName(child_tt->name()); + shared_ot->setModule(module); + shared_ot->setCtype(child_tt->ctype()); + // Reshape based on the split dimension and the template tensor + switch (split_dim) { + case Chl::HEAD: + shared_ot->reshape(batch(), child_tt->head(), sequence(), dimension()); + break; + case Chl::SEQUENCE: + shared_ot->reshape(this->batch(), head(), child_tt->sequence(), dimension()); + break; + case Chl::DIMENSION: + shared_ot->reshape(batch(), head(), sequence(), child_tt->dimension()); + break; + case Chl::D_HD: + case Chl::HD: + shared_ot->reshape(batch(), child_tt->head(), sequence(), child_tt->dimension()); + break; + default: + break; // Should not happen + } + shared_ot->_allocate_final_tensor(child_tt, backend); + shared_outputs.push_back(shared_ot); + } + addTensors(shared_outputs, split_dim); + } else { + allowAggregated() = false; + alloc(); + } +} + +/** + * @brief Allocates memory for a tensor based on a template tensor. + * If the template tensor is aggregated, it allocates an aggregated tensor. + * Otherwise, it allocates a final tensor. + * @param template_tensor The template tensor to base the allocation on. + */ +void Tensor::allocFromTemplate(shared_ptr template_tensor){ + assert(module() != nullptr); + assert(backend() != nullptr); + if (template_tensor!= nullptr && !template_tensor->aggregatedTensors().empty()) { + _allocate_aggregated_tensor(template_tensor, module(), backend()); + } else { + _allocate_final_tensor(template_tensor, backend()); + } +} + +/** + * @brief Runs a tensor function with the specified parameters. + * @param out_names The names for the output tensors. + * @param type The type of the tensor function to run. + * @param param The parameters for the tensor function. + * @param input_tensors The input tensors to the function. + * @param in_place Whether to run the function in-place. + * @return A vector of output tensors. + */ std::vector Tensor::runFunc(std::vector out_names, - TensorFuncType type, - std::vector float_args, - std::vector> input_tensors, - bool in_place) { - auto backend = input_tensors.empty() ? Backend::global_backends[MLLM_CPU] : input_tensors[0]->backend(); + OpType type, + OpParam param, + std::vector input_tensors, + bool in_place) { + auto backend = input_tensors.empty() ? Backend::global_backends[MLLM_CPU] : input_tensors[0].backend(); if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { backend = Backend::global_backends[MLLM_QNN]; } - return backend->runFunc(out_names, type, float_args, input_tensors, in_place); + param["type"] = type; + Op *op_ = backend->opCreate(param, ""); + return backend->runOp(op_, input_tensors, out_names, in_place); } Tensor Tensor::operator+(float data) { - return runFunc({name() + "-add"}, FUNC_ADD, {data}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["data"] = data; + return runFunc({name() + "-add"}, F_ADD, param, + {*this})[0]; } Tensor Tensor::operator-(float data) { - return runFunc({name() + "-sub"}, FUNC_SUB, {data}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["data"] = data; + return runFunc({name() + "-sub"}, F_SUB, param, + {*this})[0]; } Tensor Tensor::operator*(float data) { - return runFunc({name() + "-mul"}, FUNC_MUL, {data}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["data"] = data; + return runFunc({name() + "-mul"}, F_MUL, param, + {*this})[0]; } Tensor Tensor::operator/(float data) { - return runFunc({name() + "-div"}, FUNC_DIV, {data}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["data"] = data; + return runFunc({name() + "-div"}, F_DIV, param, + {*this})[0]; } Tensor Tensor::operator/(double data) { - return runFunc({name() + "-div"}, FUNC_DIV, {static_cast(data)}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["data"] = static_cast(data); + return runFunc({name() + "-div"}, F_DIV, param, + {*this})[0]; } Tensor Tensor::operator/(int data) { - return runFunc({name() + "-div"}, FUNC_DIVINT, {static_cast(data)}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["data"] = (float)data; + return runFunc({name() + "-div"}, F_DIVINT, param, + {*this})[0]; } Tensor Tensor::operator+(Tensor other) { - return runFunc({name() + "-TTadd"}, FUNC_TTADD, {}, - {std::shared_ptr(this, [](Tensor *) {}), - std::shared_ptr(&other, [](Tensor *) {})})[0]; + return runFunc({name() + "-TTadd"}, F_TTADD, {}, + {*this,other})[0]; } Tensor Tensor::operator-(Tensor other) { - return runFunc({name() + "-TTsub"}, FUNC_TTSUB, {}, - {std::shared_ptr(this, [](Tensor *) {}), - std::shared_ptr(&other, [](Tensor *) {})})[0]; + return runFunc({name() + "-TTsub"}, F_TTSUB, {}, + {*this,other})[0]; } Tensor Tensor::operator*(Tensor other) { - return runFunc({name() + "-TTmul"}, FUNC_TTMUL, {}, - {std::shared_ptr(this, [](Tensor *) {}), - std::shared_ptr(&other, [](Tensor *) {})})[0]; + return runFunc({name() + "-TTmul"}, F_TTMUL, {}, + {*this,other})[0]; } Tensor Tensor::operator/(Tensor other) { - return runFunc({name() + "-TTdiv"}, FUNC_TTDIV, {}, - {std::shared_ptr(this, [](Tensor *) {}), - std::shared_ptr(&other, [](Tensor *) {})})[0]; + return runFunc({name() + "-TTdiv"}, F_TTDIV, {}, + {*this,other})[0]; } Tensor Tensor::mean(Chl axis) { - return runFunc({name() + "-mean"}, FUNC_MEAN, {(float)axis}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["axis"] = (float)axis; + return runFunc({name() + "-mean"}, F_MEAN, param, + {*this})[0]; } Tensor Tensor::view(int b, int h, int s, int d) { - return runFunc({name() + "-view"}, FUNC_VIEW, {(float)b, (float)h, (float)s, (float)d}, - {std::shared_ptr(this, [](Tensor *) {})}, true)[0]; + OpParam param; + param["b"] = (float)b; + param["h"] = (float)h; + param["s"] = (float)s; + param["d"] = (float)d; + return runFunc({name() + "-view"}, F_VIEW, param, + {*this}, true)[0]; } Tensor Tensor::flatten(Chl axis_start, Chl axis_end) { - return runFunc({name() + "-flatten"}, FUNC_FLATTEN, {(float)axis_start, (float)axis_end}, - {std::shared_ptr(this, [](Tensor *) {})}, true)[0]; + OpParam param; + param["axis_start"] = (float)axis_start; + param["axis_end"] = (float)axis_end; + return runFunc({name() + "-flatten"}, F_FLATTEN, param, + {*this}, true)[0]; } Tensor Tensor::transpose(vector> axiss) { - vector axis_s; + OpParam param; + param["num_pairs"] = (float)axiss.size(); + int idx = 0; for (auto &axis : axiss) { - axis_s.push_back((float)axis.first); - axis_s.push_back((float)axis.second); + param["axis1_" + std::to_string(idx)] = (float)axis.first; + param["axis2_" + std::to_string(idx)] = (float)axis.second; + idx ++; } - bool in_place = (master_tensor_ == nullptr); + bool in_place = (master_tensor_ == nullptr) || + (master_tensor_->name().find("Cache") == std::string::npos && + master_tensor_->name().find("weight") != std::string::npos); // for BSHD attention start if(axiss.size() == 1 && axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { in_place = false; // in-place transpose } // for BSHD attention end - return runFunc({name() + "-transpose"}, FUNC_TRANPOSE, axis_s, - {std::shared_ptr(this, [](Tensor *) {})}, in_place)[0]; + return runFunc({name() + "-transpose"}, F_TRANPOSE, param, + {*this}, in_place)[0]; } Tensor Tensor::clip(vector b, vector h, vector s, vector d) { - vector axis_s; - axis_s.push_back(b.size()); - axis_s.push_back(h.size()); - axis_s.push_back(s.size()); - axis_s.push_back(d.size()); - for (auto &axis : b) { axis_s.push_back((float)axis); } - for (auto &axis : h) { axis_s.push_back((float)axis); } - for (auto &axis : s) { axis_s.push_back((float)axis); } - for (auto &axis : d) { axis_s.push_back((float)axis); } + OpParam param; + param["b_size"] = (float)b.size(); + param["h_size"] = (float)h.size(); + param["s_size"] = (float)s.size(); + param["d_size"] = (float)d.size(); + for(int i=0; i(this, [](Tensor *) {})})[0]; + return runFunc({name() + name_su}, F_CLIP, param, + {*this})[0]; } Tensor Tensor::clip(Chl keep_axis, vector b, vector h, vector s, vector d) { - vector axis_s = {(float)keep_axis}; - axis_s.push_back(b.size()); - axis_s.push_back(h.size()); - axis_s.push_back(s.size()); - axis_s.push_back(d.size()); - for (auto &axis : b) { axis_s.push_back((float)axis); } - for (auto &axis : h) { axis_s.push_back((float)axis); } - for (auto &axis : s) { axis_s.push_back((float)axis); } - for (auto &axis : d) { axis_s.push_back((float)axis); } - return runFunc({name() + "-clipaxis"}, FUNC_CLIPAXIS, axis_s, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["axis"] = (float)keep_axis; + param["b_size"] = (float)b.size(); + param["h_size"] = (float)h.size(); + param["s_size"] = (float)s.size(); + param["d_size"] = (float)d.size(); + for(int i=0; i index, Chl dim) { @@ -322,141 +475,168 @@ Tensor Tensor::clip(vector index, Chl dim) { index_tensor.setDataAt(0, 0, 0, i, static_cast(index[i])); } index_tensor.setName(name() + "-cliptensor-index"); - return runFunc({name() + "-cliptensor"}, FUNC_CLIPTENSOR, {(float)dim}, - {std::shared_ptr(this, [](Tensor *) {}), - std::shared_ptr(&index_tensor, [](Tensor *) {})})[0]; + OpParam param; + param["dim"] = (float)dim; + return runFunc({name() + "-cliptensor"}, F_CLIPTENSOR, param, + {*this,index_tensor})[0]; } Tensor Tensor::clip(Tensor index, Chl dim) { - return runFunc({name() + "-cliptensor"}, FUNC_CLIPTENSOR, {(float)dim}, - {std::shared_ptr(this, [](Tensor *) {}), - std::shared_ptr(&index, [](Tensor *) {})})[0]; + OpParam param; + param["dim"] = (float)dim; + return runFunc({name() + "-cliptensor"}, F_CLIPTENSOR, param, + {*this,index})[0]; } Tensor Tensor::expand(int b, int h, int s, int d) { - return runFunc({name() + "-expand"}, FUNC_EXPPAND, {(float)b, (float)h, (float)s, (float)d}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["b"] = (float)b; + param["h"] = (float)h; + param["s"] = (float)s; + param["d"] = (float)d; + return runFunc({name() + "-expand"}, F_EXPPAND, param, + {*this})[0]; } Tensor Tensor::norm(int L_n) { - return runFunc({name() + "-norm"}, FUNC_NORM, {(float)L_n}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["L_n"] = (float)L_n; + return runFunc({name() + "-norm"}, F_NORM, param, + {*this})[0]; } Tensor Tensor::where(float value, Chl axis) { - return runFunc({name() + "-where"}, FUNC_WHERE, {(float)value, (float)axis}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["value"] = value; + param["axis"] = axis; + return runFunc({name() + "-where"}, F_WHERE, param, + {*this})[0]; } Tensor Tensor::index_put(Tensor value, Tensor indices, bool accumulate) { - return runFunc({name() + "-index_put"}, FUNC_INDEX_PUT, {(float)accumulate}, - {std::shared_ptr(this, [](Tensor *) {}), - std::shared_ptr(&value, [](Tensor *) {}), - std::shared_ptr(&indices, [](Tensor *) {})}, + OpParam param; + param["accumulate"] = (float)accumulate; + return runFunc({name() + "-index_put"}, F_INDEX_PUT, param, + {*this,value, indices}, !accumulate)[0]; } void Tensor::scatter_reduce(Tensor value, Tensor indices) { - runFunc({name()}, FUNC_SCATTERREDUCE, {}, - {std::shared_ptr(this, [](Tensor *) {}), - std::shared_ptr(&value, [](Tensor *) {}), - std::shared_ptr(&indices, [](Tensor *) {})})[0]; + OpParam param; + runFunc({name()}, F_SCATTERREDUCE, param, + {*this,value, indices})[0]; } Tensor Tensor::cat(vector input_tensors, Chl axis) { + OpParam param; + param["axis"] = (float)axis; Module *module = input_tensors[0].module(); - vector> inputs = {}; + vector inputs = {}; for (auto &input_tensor : input_tensors) { - inputs.push_back(std::shared_ptr(&input_tensor, [](Tensor *) {})); + inputs.push_back(input_tensor); } - return runFunc({input_tensors[0].name() + "-cat"}, FUNC_CAT, {(float)axis}, inputs)[0]; + return runFunc({input_tensors[0].name() + "-cat"}, F_CAT, param, inputs)[0]; } Tensor Tensor::mm(Tensor input0, Tensor input1) { Module *module = input0.module(); string nname = input0.name() + "-mm-" + input1.name(); return runFunc( - {nname}, FUNC_MM, {}, - {std::shared_ptr(&input0, [](Tensor *) {}), - std::shared_ptr(&input1, [](Tensor *) {})})[0]; + {nname}, F_MM, {}, + {input0, input1})[0]; } Tensor Tensor::range(int start, int end) { - return runFunc({"range-" + std::to_string(start) + "-" + std::to_string(end)}, FUNC_RANGE, - {(float)start, (float)end}, {})[0]; + OpParam param; + param["start"] = (float)start; + param["end"] = (float)end; + return runFunc({"range-" + std::to_string(start) + "-" + std::to_string(end)}, F_RANGE, + param, {})[0]; } vector Tensor::split(Tensor input, std::vector each_dims, Chl split_dim, int same_dim_size) { + OpParam param; vector next_names; - std::vector args; - for (int i = 0; i < each_dims.size(); ++i) { - args.push_back(each_dims[i]); + param["num_splits"] = (float)each_dims.size(); + for(int i=0; i(&input, [](Tensor *) {})}); + return runFunc(next_names, F_SPLIT, param, + {input}); } vector Tensor::topk(Tensor input, int k, Chl dim) { Module *module = input.module(); + OpParam param; + param["k"] = (float)k; + param["dim"] = (float)dim; return runFunc({input.name() + "-top" + std::to_string(k) + "-value", input.name() + "-top" + std::to_string(k) + "-idx"}, - FUNC_TOPK, - {(float)k, (float)dim}, - {std::shared_ptr(&input, [](Tensor *) {})}); + F_TOPK, + param, + {input}); } Tensor Tensor::sum(Chl dim) { - return runFunc({name() + "sum"}, FUNC_SUM, {(float)dim}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["dim"] = (float)dim; + return runFunc({name() + "sum"}, F_SUM, param, + {*this})[0]; } Tensor Tensor::argsort() { - return runFunc({name() + "argsort"}, FUNC_ARGSORT, {}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + return runFunc({name() + "argsort"}, F_ARGSORT, {}, + {*this})[0]; } Tensor Tensor::bincount() { - return runFunc({name() + "bincount"}, FUNC_BINCOUNT, {}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + return runFunc({name() + "bincount"}, F_BINCOUNT, {}, + {*this})[0]; } Tensor Tensor::repeat(Chl dim, int dim_size) { - return runFunc({name() + "repeat"}, FUNC_REPEAT, {(float)dim, (float)dim_size}, - {std::shared_ptr(this, [](Tensor *) {})})[0]; + OpParam param; + param["dim"] = (float)dim; + param["dim_size"] = (float)dim_size; + return runFunc({name() + "repeat"}, F_REPEAT, param, + {*this})[0]; } Tensor Tensor::zero_like(Tensor input) { Module *module = input.module(); - return runFunc({input.name() + "-zero_like"}, FUNC_LIKE, {0.0}, - {std::shared_ptr(&input, [](Tensor *) {})})[0]; + OpParam param; + param["like_value"] = 0.0f; + return runFunc({input.name() + "-zero_like"}, F_LIKE, param, + {input})[0]; } Tensor Tensor::flash_attention2_forward(Tensor q, Tensor k, Tensor v, bool causal_mask) { Module *module = q.module(); - return runFunc({q.name() + "-" + k.name() + "-fa2"}, FUNC_FA2, {causal_mask ? 1.0f : 0.0f}, - {std::shared_ptr(&q, [](Tensor *) {}), - std::shared_ptr(&k, [](Tensor *) {}), - std::shared_ptr(&v, [](Tensor *) {})})[0]; + OpParam param; + param["causal_mask"] = causal_mask ? 1.0f : 0.0f; + return runFunc({q.name() + "-" + k.name() + "-fa2"}, F_FA2, param, + {q, k,v})[0]; }; Tensor Tensor::apply_rotary_pos_emb_vision(Tensor input, Tensor rotary_pos_emb) { Module *module = input.module(); - return runFunc({input.name() + "-apply_rotary_pos_emb"}, FUNC_APPLY_VISIOROPE, + return runFunc({input.name() + "-apply_rotary_pos_emb"}, F_APPLY_VISIOROPE, {}, - {std::shared_ptr(&input, [](Tensor *) {}), - std::shared_ptr(&rotary_pos_emb, [](Tensor *) {})})[0]; + {input,rotary_pos_emb})[0]; } Tensor Tensor::fuyu_gather_embd(Tensor word, Tensor image_patches, Tensor image_patches_indices) { Module *module = word.module(); - return runFunc({word.name() + ".fuyu_gather_embd"}, FUNC_FUYU_GATHER_EMBD, + return runFunc({word.name() + ".fuyu_gather_embd"}, F_FUYU_GATHER_EMBD, {}, - {std::shared_ptr(&word, [](Tensor *) {}), - std::shared_ptr(&image_patches, [](Tensor *) {}), - std::shared_ptr(&image_patches_indices, [](Tensor *) {})}, + {word, image_patches, image_patches_indices}, true)[0]; } Tensor Tensor::phi3v_hd_merge(Tensor input, int h_crop, int w_crop) { Module *module = input.module(); - return runFunc({input.name() + ".phi3v_hd_merge"}, FUNC_PHI3V_HD_MERGE, - {(float)h_crop, (float)w_crop}, - {std::shared_ptr(&input, [](Tensor *) {})})[0]; + OpParam param; + param["h_crop"] = (float)h_crop; + param["w_crop"] = (float)w_crop; + // The input tensor should be in BTHWC format + return runFunc({input.name() + ".phi3v_hd_merge"}, F_PHI3V_HD_MERGE, + param, + {input})[0]; } } // namespace mllm \ No newline at end of file diff --git a/src/Tensor.hpp b/src/Tensor.hpp index de4ea9b17..e9b298cfb 100644 --- a/src/Tensor.hpp +++ b/src/Tensor.hpp @@ -1,8 +1,6 @@ #ifndef MLLM_TENSOR_H #define MLLM_TENSOR_H -#include -#include "Backend.hpp" -#include "OpDefined.hpp" +// #include #include #include #include @@ -83,6 +81,9 @@ class Tensor { public: int cache_seq_len_; + bool inited() { + return impl_ != nullptr && impl_->host_ptr_ != nullptr && impl_->name_ != ""; + } public: // 拷贝语义:默认浅拷贝(共享实现) @@ -817,155 +818,29 @@ class Tensor { * - addChildTensor */ - /** - * \brief this Tensor is a DEEPCOPY of source, only used for ChildTensor. - * \param source MasterTensor. - * \param shape_offset the offset of each dimension of ChildTensor compared to MasterTensor. - * \param head_rep the repeat number of heads of ChildTensor compared to MasterTensor. - * used for repeat the head of K/V in Transformer-based LLMs. Default is 1. - */ - /* - void shallowCopyFrom(Tensor *source, bool copyshape = true, const vector &shape_offset = {}, int head_rep = 1) { - if (!shape_offset.empty()) { - copyshape = false; - } - setMasterTensor(source); - if (impl_->ctype_ != BCTHW && impl_->ctype_ != BTHWC && impl_->ctype_ != master_tensor_->ctype() && impl_->undiffusion_ == false) { - if (impl_->transed_) { // child tensor have been transed(BSHD->BHDS); - auto b = master_tensor_->batch(); - auto h = master_tensor_->head(); - auto d = master_tensor_->dimension(); - auto s = master_tensor_->sequence(); - master_tensor_->impl_->ctype_ = impl_->ctype_; - master_tensor_->impl_->chls_ = impl_->chls_; - master_tensor_->reshape(b, h, s, d); - } else { - auto b = batch(); - auto h = head(); - auto d = dimension(); - auto s = sequence(); - impl_->ctype_ = master_tensor_->impl_->ctype_; - impl_->chls_ = master_tensor_->impl_->chls_; - reshape(b, h, s, d); - } - } else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == master_tensor_->impl_->ctype_ && ctype() != master_tensor_->impl_->ctype_) { - auto b = child_tensors_[0]->batch(); - auto h = child_tensors_[0]->head(); - auto s = child_tensors_[0]->sequence(); - auto d = child_tensors_[0]->dimension(); - auto origin_c_0 = child_tensors_[0]->impl_->chls_; - auto origin_c_1 = impl_->chls_; - impl_->chls_ = master_tensor_->impl_->chls_; - child_tensors_[0]->impl_->chls_ = master_tensor_->impl_->chls_; - for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { - auto tf = impl_->trans_from_[i]; - auto axis0 = tf.first; - auto axis1 = tf.second; - auto ori_0_idx = child_tensors_[0]->impl_->chls()[axis0]; - auto ori_1_idx = child_tensors_[0]->impl_->chls()[axis1]; - child_tensors_[0]->impl_->chls()[axis0] = ori_1_idx; - child_tensors_[0]->impl_->chls()[axis1] = ori_0_idx; - } - changeCtype(); - child_tensors_[0]->changeCtype(); - child_tensors_[0]->reshape(b, h, s, d); - transCopyShape(child_tensors_[0]->shape()); - } else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == BCTHW && master_tensor_->impl_->ctype_ == BSHD && ctype() != BCTHW) { - auto b = child_tensors_[0]->batch(); - auto c = child_tensors_[0]->channel(); - auto t = child_tensors_[0]->time(); - auto h = child_tensors_[0]->height(); - auto w = child_tensors_[0]->width(); - auto origin_c_0 = child_tensors_[0]->impl_->chls_; - auto origin_c_1 = impl_->chls_; - impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; - child_tensors_[0]->impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; - for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { - auto tf = impl_->trans_from_[i]; - auto axis0 = tf.first; - auto axis1 = tf.second; - auto ori_0_idx = child_tensors_[0]->impl_->chls()[axis0]; - auto ori_1_idx = child_tensors_[0]->impl_->chls()[axis1]; - child_tensors_[0]->impl_->chls()[axis0] = ori_1_idx; - child_tensors_[0]->impl_->chls()[axis1] = ori_0_idx; - } - changeCtype(); - child_tensors_[0]->changeCtype(); - child_tensors_[0]->reshape(b, c, t, h, w); - transCopyShape(child_tensors_[0]->shape()); - } - impl_->host_ptr_ = source->hostPtr(); - impl_->owns_host_ptr_ = false; // 子Tensor不拥有所有权 - impl_->capacity_ = source->impl_->capacity_; - impl_->count_ = source->impl_->count_; - if (copyshape) { - impl_->shape_ = source->impl_->shape_; - } - impl_->allocated_ = source->impl_->allocated_; - impl_->dtype_ = source->impl_->dtype_; - if (!shape_offset.empty()) { - shape_master_ = {(uint64_t)source->batch(), - (uint64_t)source->head(), - (uint64_t)source->sequence(), - (uint64_t)source->dimension()}; - shape_offset_ = {(uint64_t)shape_offset[0], - (uint64_t)shape_offset[1], - (uint64_t)shape_offset[2], - (uint64_t)shape_offset[3]}; - if (!std::equal(source->impl_->chls_.begin(), source->impl_->chls_.end(), impl_->chls_.begin()) - && impl_->chls()[SEQUENCE] == source->impl_->chls()[DIMENSION] - && source->impl_->chls()[SEQUENCE] == impl_->chls()[DIMENSION]) { - shape_master_ = {(uint64_t)source->batch(), - (uint64_t)source->head(), - (uint64_t)source->dimension(), - (uint64_t)source->sequence()}; - shape_offset_ = {(uint64_t)shape_offset[0], - (uint64_t)shape_offset[1], - (uint64_t)shape_offset[3], - (uint64_t)shape_offset[2]}; - } - if (source->head() != head()) { // TODO: need to check - if (head() == 1 && head_rep == 1) { - shape_master_ = {(uint64_t)source->batch(), - (uint64_t)head(), - (uint64_t)source->sequence(), - (uint64_t)source->dimension() * source->head() / head()}; - } else if (head() == 1 && head_rep > 1) { - shape_master_ = {(uint64_t)source->batch(), - (uint64_t)head(), - (uint64_t)source->sequence(), - (uint64_t)source->dimension() * source->head() / head_rep}; - } - } - } - auto it = child_tensors_.begin(); - while (it != child_tensors_.end()) { - auto &child_tensor = *it; - auto origin_shape_offset = child_tensor->shapeOffset(); - if (!origin_shape_offset.empty()) { - if (!shape_offset.empty()) { - origin_shape_offset[2] = shape_offset[2]; - } - child_tensor->shallowCopyFrom(source, false, origin_shape_offset, head_rep); - } else if (!shape_offset.empty()) { - child_tensor->shallowCopyFrom(source, false, shape_offset, head_rep); - } else { - child_tensor->shallowCopyFrom(source, false, {}, head_rep); - } - it = child_tensors_.erase(it); + // 新增一个方法,用于强制设置指针并转移所有权句柄 + // 这是比将 ParamLoader 设为友元类更清晰的做法 + void setHostPtr(void *ptr, std::shared_ptr memory_handle) { + // 如果 Tensor 已经持有自己分配的内存,则先释放它 + if (impl_->host_ptr_ != nullptr && impl_->owns_host_ptr_) { + impl_->free(); } - source->addChildTensor(this); + // 接管来自 mmap 的新指针和内存句柄 + impl_->host_ptr_ = ptr; + impl_->owns_host_ptr_ = false; // 标记内存为外部管理 + impl_->memory_handle_ = std::move(memory_handle); // 持有 mmap 句柄 + impl_->allocated_ = count(); // 标记为已分配状态 } - */ + /** - * @brief 使当前 Tensor 成为 source Tensor 的一个子 Tensor (Shallow Copy)。 - * 它不分配新内存,而是共享 source 的内存。 - * @param source 将要成为父 Tensor 的张量。 - * @param copyshape 如果为 true 且 shape_offset 为空,则直接复制 source 的形状。 - * @param shape_offset 定义子 Tensor 相对于父 Tensor 的维度偏移,用于创建切片(slice)。 - * @param head_rep 用于分组查询注意力(GQA),表示K/V头的重复次数。 - */ + * @brief 使当前 Tensor 成为 source Tensor 的一个子 Tensor (Shallow Copy)。 + * 它不分配新内存,而是共享 source 的内存。 + * @param source 将要成为父 Tensor 的张量。 + * @param copyshape 如果为 true 且 shape_offset 为空,则直接复制 source 的形状。 + * @param shape_offset 定义子 Tensor 相对于父 Tensor 的维度偏移,用于创建切片(slice)。 + * @param head_rep 用于分组查询注意力(GQA),表示K/V头的重复次数。 + */ void shallowCopyFrom(Tensor *source, bool copyshape = true, const vector &shape_offset = {}, int head_rep = 1) { // 步骤 0: 初始设置 // 如果提供了偏移量,则子张量有自己的独立形状,不应复制父张量的形状。 @@ -994,7 +869,7 @@ class Tensor { // 如果提供了 shape_offset,则当前 Tensor 是一个 "view" 或 "slice" setupShapeForView(source, shape_offset, head_rep); } - + // 步骤 4: 维护张量层级结构 (处理孙张量) // 如果当前 Tensor 在此之前有自己的子 Tensor(即 source 的孙张量), // 必须将这些孙张量重新“过继”给 source,成为 source 的直接子 Tensor。 @@ -1161,6 +1036,31 @@ class Tensor { static void reshapeAllocCrossBn(Tensor &src_t, Tensor &dst_t); static void copyDataCrossBn(Tensor &src_t, Tensor &dst_t); +public: + uint32_t &uuid(); + + TensorType &xnnTensorType(); + + bool &allowAggregated() { + return allow_aggregated_; + } + + void forceResetHostPointer(void *ptr); + + float i8_scale = 1.f; + + void allocFromTemplate(shared_ptr template_tensor); + +private: + void _allocate_final_tensor( + const std::shared_ptr &template_tensor, + Backend *backend); + void _allocate_aggregated_tensor( + const std::shared_ptr &template_tensor, + Module *module, + Backend *backend); +public: + /* Functions used for 5-D Tensor: * - reshape * - channel @@ -1242,17 +1142,15 @@ class Tensor { } private: - - /** - * @brief (辅助函数) 处理父子 Tensor 之间的内存布局 (ctype) 同步。 - * 这段逻辑直接从原始的 shallowCopyFrom 中提取,保留了所有边缘情况的处理。 - * @param master_tensor 新的父 Tensor。 - */ + * @brief (辅助函数) 处理父子 Tensor 之间的内存布局 (ctype) 同步。 + * 这段逻辑直接从原始的 shallowCopyFrom 中提取,保留了所有边缘情况的处理。 + * @param master_tensor 新的父 Tensor。 + */ void reconcileLayouts(Tensor *master_tensor) { // 情况 1: 通用的4D张量布局同步 (非5D视觉张量) // 条件: 父子 ctype 不一致,且允许布局变化从子张量“扩散”到父张量。 - if (impl_->ctype_ != BCTHW && impl_->ctype_ != BTHWC + if (impl_->ctype_ != BCTHW && impl_->ctype_ != BTHWC && impl_->ctype_ != master_tensor->ctype() && !impl_->undiffusion_) { if (impl_->transed_) { // 如果子张量(this)已被转置,则强制父张量跟随子的布局 auto b = master_tensor->batch(); @@ -1274,17 +1172,17 @@ class Tensor { } // 情况 2: 处理三层张量结构中的布局冲突 (祖父 -> this -> 孙子) // 条件: this 只有一个子节点,且该子节点与新的父节点(master_tensor)布局相同,但 this 与它们不同。 - else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == master_tensor->impl_->ctype_ - && ctype() != master_tensor->impl_->ctype_) { + else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == master_tensor->impl_->ctype_ + && ctype() != master_tensor->impl_->ctype_) { auto b = child_tensors_[0]->batch(); auto h = child_tensors_[0]->head(); auto s = child_tensors_[0]->sequence(); auto d = child_tensors_[0]->dimension(); - + // 将 this 和其子节点的布局统一为 master_tensor 的布局 impl_->chls_ = master_tensor->impl_->chls_; child_tensors_[0]->impl_->chls_ = master_tensor->impl_->chls_; - + // 逆向应用之前记录的变换,以恢复到正确的逻辑形状 for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { auto tf = impl_->trans_from_[i]; @@ -1300,8 +1198,8 @@ class Tensor { } // 情况 3: 处理从4D (LLM) 到5D (Vision) 张量的特殊布局转换 // 条件: this 的子节点是5D (BCTHW),新的父节点是4D (BSHD),而 this 不是 BCTHW。 - else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == BCTHW - && master_tensor->impl_->ctype_ == BSHD && ctype() != BCTHW) { + else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == BCTHW + && master_tensor->impl_->ctype_ == BSHD && ctype() != BCTHW) { auto b = child_tensors_[0]->batch(); auto c = child_tensors_[0]->channel(); auto t = child_tensors_[0]->time(); @@ -1311,7 +1209,7 @@ class Tensor { // 强制重置为标准的5D布局 impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; child_tensors_[0]->impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; - + // 同样,逆向应用变换 for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { auto tf = impl_->trans_from_[i]; @@ -1324,23 +1222,22 @@ class Tensor { } } - /** - * @brief (辅助函数) 为作为 "View" 的子 Tensor 设置形状和偏移信息。 - * @param source 父 Tensor - * @param shape_offset 维度偏移 - * @param head_rep GQA 的头重复次数 - */ + * @brief (辅助函数) 为作为 "View" 的子 Tensor 设置形状和偏移信息。 + * @param source 父 Tensor + * @param shape_offset 维度偏移 + * @param head_rep GQA 的头重复次数 + */ void setupShapeForView(Tensor *source, const vector &shape_offset, int head_rep) { // 记录父张量的原始维度,用于后续计算 offset shape_master_ = {(uint64_t)source->batch(), (uint64_t)source->head(), - (uint64_t)source->sequence(), (uint64_t)source->dimension()}; - shape_offset_ = {(uint64_t)shape_offset[0], (uint64_t)shape_offset[1], - (uint64_t)shape_offset[2], (uint64_t)shape_offset[3]}; + (uint64_t)source->sequence(), (uint64_t)source->dimension()}; + shape_offset_ = {(uint64_t)shape_offset[0], (uint64_t)shape_offset[1], + (uint64_t)shape_offset[2], (uint64_t)shape_offset[3]}; // 如果父子布局转置了 (例如 BSHD vs BHDS), 需要同步调整 shape_master_ 和 shape_offset_ 的记录顺序 if (!std::equal(source->impl_->chls_.begin(), source->impl_->chls_.end(), impl_->chls_.begin()) - && impl_->chls_[SEQUENCE] == source->impl_->chls_[DIMENSION] + && impl_->chls_[SEQUENCE] == source->impl_->chls_[DIMENSION] && source->impl_->chls_[SEQUENCE] == impl_->chls_[DIMENSION]) { std::swap(shape_master_[2], shape_master_[3]); // 交换 sequence 和 dimension std::swap(shape_offset_[2], shape_offset_[3]); @@ -1358,19 +1255,18 @@ class Tensor { } } - /** - * @brief (辅助函数) 重新指定当前 Tensor 的子 Tensor (孙张量) 的父节点。 - * 将它们从 this 的子节点变为 source 的直接子节点。 - * @param source 新的父(祖父)节点 - * @param shape_offset - * @param head_rep - */ - void reparentChildTensors(Tensor* source, const vector& shape_offset, int head_rep) { + * @brief (辅助函数) 重新指定当前 Tensor 的子 Tensor (孙张量) 的父节点。 + * 将它们从 this 的子节点变为 source 的直接子节点。 + * @param source 新的父(祖父)节点 + * @param shape_offset + * @param head_rep + */ + void reparentChildTensors(Tensor *source, const vector &shape_offset, int head_rep) { auto it = child_tensors_.begin(); while (it != child_tensors_.end()) { auto &child_tensor = *it; - + // 1. 先计算出最终要传递的 offset vector final_offset; auto origin_shape_offset = child_tensor->shapeOffset(); @@ -1380,36 +1276,13 @@ class Tensor { } else if (!shape_offset.empty()) { final_offset = shape_offset; } - + // 2. 只调用一次 child_tensor->shallowCopyFrom(source, false, final_offset, head_rep); - + it = child_tensors_.erase(it); } } - // void reparentChildTensors(Tensor* source, const vector& shape_offset, int head_rep) { - // auto it = child_tensors_.begin(); - // while (it != child_tensors_.end()) { - // auto &child_tensor = *it; - // auto origin_shape_offset = child_tensor->shapeOffset(); - - // // 递归调用,将孙张量直接挂到新的祖父 source 下 - // if (!origin_shape_offset.empty()) { - // if (!shape_offset.empty()) { - // origin_shape_offset[2] = shape_offset[2]; // 这个逻辑比较特殊,保留原始行为 - // } - // child_tensor->shallowCopyFrom(source, false, origin_shape_offset, head_rep); - // } else if (!shape_offset.empty()) { - // child_tensor->shallowCopyFrom(source, false, shape_offset, head_rep); - // } else { - // child_tensor->shallowCopyFrom(source, false, {}, head_rep); - // } - - // // 从 this 的子节点列表中移除,因为它已经被“过继”了 - // it = child_tensors_.erase(it); - // } - // } - int checkDim(int &b, int &h, int &s, int &d) { if (!aggregated_) { @@ -1530,24 +1403,13 @@ class Tensor { // in_place=true: 只有输入, 输出==输入,返回输入 static std::vector runFunc(std::vector out_names, - TensorFuncType type, - std::vector float_args, - std::vector> input_tensors = {}, + OpType type, + OpParam param, + std::vector input_tensors = {}, bool in_place = false); -public: - uint32_t &uuid(); - - TensorType &xnnTensorType(); - - bool &allowAggregated() { - return allow_aggregated_; - } - - void forceResetHostPointer(void *ptr); - - float i8_scale = 1.f; +public: /* Functions used for TEST & DEBUG * - checkData * - printShape diff --git a/src/TensorImpl.hpp b/src/TensorImpl.hpp index bfe3c4081..a9a430071 100644 --- a/src/TensorImpl.hpp +++ b/src/TensorImpl.hpp @@ -1,32 +1,34 @@ #ifndef MLLM_TENSORIMPL_H #define MLLM_TENSORIMPL_H -#include -#include "Backend.hpp" -#include "OpDefined.hpp" -#include #include -#include -#include -#include #include #include -#include +// #include #ifdef _WIN32 #include #else #include #endif -#include #include +// #include +// #include +// #include +// #include +// #include // #include +#include "OpDefined.hpp" +#include "Backend.hpp" +#include + namespace mllm { class Backend; class Module; class TensorImpl { public: - bool owns_host_ptr_ = true; // 新增标志位 + bool owns_host_ptr_ = true; + std::shared_ptr memory_handle_ = nullptr; std::map chls_ = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; string name_; diff --git a/src/backends/cpu/CPUBackend.cpp b/src/backends/cpu/CPUBackend.cpp index c4e4dec70..4486888a0 100644 --- a/src/backends/cpu/CPUBackend.cpp +++ b/src/backends/cpu/CPUBackend.cpp @@ -1,5 +1,8 @@ #include "CPUBackend.hpp" +#include +#include #include +#include #include #include #include "Backend.hpp" @@ -68,32 +71,59 @@ #include "op/CPUKVCacheNPU.hpp" #include "op/CPUKVCacheXp.hpp" -#include "function/CPUBinaryFunc.hpp" -#include "function/CPUCatFunc.hpp" -#include "function/CPUClipFunc.hpp" -#include "function/CPUExpandFunc.hpp" -#include "function/CPUFlattenFunc.hpp" -#include "function/CPUMatmulFunc.hpp" -#include "function/CPUMeanFunc.hpp" -#include "function/CPUNormFunc.hpp" -#include "function/CPURangeFunc.hpp" -#include "function/CPUSplitFunc.hpp" -#include "function/CPUSumFunc.hpp" -#include "function/CPUTopkFunc.hpp" -#include "function/CPUTransposeFunc.hpp" -#include "function/CPUViewFunc.hpp" -#include "function/CPUWhereFunc.hpp" -#include "function/CPUIndexPutFunc.hpp" -#include "function/CPUArgSortFunc.hpp" -#include "function/CPUBinCountFunc.hpp" -#include "function/CPURepeatFunc.hpp" -#include "function/CPULikeFunc.hpp" -#include "function/CPUScatterReduceFunc.hpp" -#include "function/CPUVisionRoPEFunc.hpp" -#include "function/CPUFlashAttention2Func.hpp" +#include "op/CPUBinaryFunc.hpp" +#include "op/CPUCatFunc.hpp" +#include "op/CPUClipFunc.hpp" +#include "op/CPUExpandFunc.hpp" +#include "op/CPUFlattenFunc.hpp" +#include "op/CPUMatmulFunc.hpp" +#include "op/CPUMeanFunc.hpp" +#include "op/CPUNormFunc.hpp" +#include "op/CPURangeFunc.hpp" +#include "op/CPUSplitFunc.hpp" +#include "op/CPUSumFunc.hpp" +#include "op/CPUTopkFunc.hpp" +#include "op/CPUTransposeFunc.hpp" +#include "op/CPUViewFunc.hpp" +#include "op/CPUWhereFunc.hpp" +#include "op/CPUIndexPutFunc.hpp" +#include "op/CPUArgSortFunc.hpp" +#include "op/CPUBinCountFunc.hpp" +#include "op/CPURepeatFunc.hpp" +#include "op/CPULikeFunc.hpp" +#include "op/CPUScatterReduceFunc.hpp" +#include "op/CPUVisionRoPEFunc.hpp" +#include "op/CPUFlashAttention2Func.hpp" -#include "function/CPUFuyuGatherEmbdFunc.hpp" -#include "function/CPUPhi3VhdmergeFunc.hpp" +#include "op/CPUFuyuGatherEmbdFunc.hpp" +#include "op/CPUPhi3VhdmergeFunc.hpp" + +// #include "function/CPUBinaryFunc.hpp" +// #include "function/CPUCatFunc.hpp" +// #include "function/CPUClipFunc.hpp" +// #include "function/CPUExpandFunc.hpp" +// #include "function/CPUFlattenFunc.hpp" +// #include "function/CPUMatmulFunc.hpp" +// #include "function/CPUMeanFunc.hpp" +// #include "function/CPUNormFunc.hpp" +// #include "function/CPURangeFunc.hpp" +// #include "function/CPUSplitFunc.hpp" +// #include "function/CPUSumFunc.hpp" +// #include "function/CPUTopkFunc.hpp" +// #include "function/CPUTransposeFunc.hpp" +// #include "function/CPUViewFunc.hpp" +// #include "function/CPUWhereFunc.hpp" +// #include "function/CPUIndexPutFunc.hpp" +// #include "function/CPUArgSortFunc.hpp" +// #include "function/CPUBinCountFunc.hpp" +// #include "function/CPURepeatFunc.hpp" +// #include "function/CPULikeFunc.hpp" +// #include "function/CPUScatterReduceFunc.hpp" +// #include "function/CPUVisionRoPEFunc.hpp" +// #include "function/CPUFlashAttention2Func.hpp" + +// #include "function/CPUFuyuGatherEmbdFunc.hpp" +// #include "function/CPUPhi3VhdmergeFunc.hpp" namespace mllm { class CPUBackendCreator : public BackendCreator { @@ -192,6 +222,44 @@ void CPUBackend::registerOps() { addCreator(XP_KVCACHE, (CPUBackend::Creator *)(new CPUKVCacheXpCreator())); addCreator(NTKROPE, (CPUBackend::Creator *)(new CPUNTKRoPECreator())); addCreator(HEADLINEAR, (CPUBackend::Creator *)(new CPUHeadLinearCreator())); + + // funsction + addCreator(F_ADD, (CPUBackend::Creator *)(new CPUaddFunctionCreator())); + addCreator(F_SUB, (CPUBackend::Creator *)(new CPUsubFunctionCreator())); + addCreator(F_MUL, (CPUBackend::Creator *)(new CPUmulFunctionCreator())); + addCreator(F_DIV, (CPUBackend::Creator *)(new CPUdivFunctionCreator())); + addCreator(F_DIVINT, (CPUBackend::Creator *)(new CPUdivintFunctionCreator())); + addCreator(F_TTADD, (CPUBackend::Creator *)(new CPUaddTwoFunctionCreator())); + addCreator(F_TTSUB, (CPUBackend::Creator *)(new CPUsubTwoFunctionCreator())); + addCreator(F_TTMUL, (CPUBackend::Creator *)(new CPUmulTwoFunctionCreator())); + addCreator(F_TTDIV, (CPUBackend::Creator *)(new CPUdivTwoFunctionCreator())); + addCreator(F_MM, (CPUBackend::Creator *)(new CPUmmFunctionCreator())); + addCreator(F_NORM, (CPUBackend::Creator *)(new CPUnormFunctionCreator())); + addCreator(F_MEAN, (CPUBackend::Creator *)(new CPUmeanFunctionCreator())); + addCreator(F_CAT, (CPUBackend::Creator *)(new CPUcatFunctionCreator())); + addCreator(F_VIEW, (CPUBackend::Creator *)(new CPUviewFunctionCreator())); + addCreator(F_TRANPOSE, (CPUBackend::Creator *)(new CPUtransposeFunctionCreator())); + addCreator(F_FLATTEN, (CPUBackend::Creator *)(new CPUflattenFunctionCreator())); + addCreator(F_CLIP, (CPUBackend::Creator *)(new CPUclipFunctionCreator())); + addCreator(F_CLIPAXIS, (CPUBackend::Creator *)(new CPUclipaxisFunctionCreator())); + addCreator(F_CLIPTENSOR, (CPUBackend::Creator *)(new CPUcliptensorFunctionCreator())); + addCreator(F_RANGE, (CPUBackend::Creator *)(new CPURangeFunctionCreator())); + addCreator(F_WHERE, (CPUBackend::Creator *)(new CPUwhereFunctionCreator())); + addCreator(F_INDEX_PUT, (CPUBackend::Creator *)(new CPUIndexPutFunctionCreator())); + addCreator(F_SPLIT, (CPUBackend::Creator *)(new CPUsplitFunctionCreator())); + addCreator(F_SUM, (CPUBackend::Creator *)(new CPUsumFunctionCreator())); + addCreator(F_TOPK, (CPUBackend::Creator *)(new CPUtopkFunctionCreator())); + addCreator(F_EXPPAND, (CPUBackend::Creator *)(new CPUexpandFunctionCreator())); + addCreator(F_ARGSORT, (CPUBackend::Creator *)(new CPUargsortFunctionCreator())); + addCreator(F_BINCOUNT, (CPUBackend::Creator *)(new CPUbincountFunctionCreator())); + addCreator(F_REPEAT, (CPUBackend::Creator *)(new CPUrepeatFunctionCreator())); + addCreator(F_LIKE, (CPUBackend::Creator *)(new CPUlikeFunctionCreator())); + addCreator(F_SCATTERREDUCE, (CPUBackend::Creator *)(new CPUScatterReduceFunctionCreator())); + addCreator(F_APPLY_VISIOROPE, (CPUBackend::Creator *)(new CPUVisionRoPEFuncFunctionCreator())); + addCreator(F_FA2, (CPUBackend::Creator *)(new CPUFlashAttention2FuncCreator())); + // models use only + addCreator(F_FUYU_GATHER_EMBD, (CPUBackend::Creator *)(new CPUFuyuGatherEmbdFuncCreator())); + addCreator(F_PHI3V_HD_MERGE, (CPUBackend::Creator *)(new CPUPhi3VhdmergeFunctionCreator())); } TensorFunction *CPUBackend::funcCreate(const TensorFuncType type) { auto iter = map_function_.find(type); @@ -202,270 +270,185 @@ TensorFunction *CPUBackend::funcCreate(const TensorFuncType type) { return iter->second; } -void CPUBackend::registerFuncs() { - map_function_[TensorFuncType::FUNC_ADD] = new CPUaddFunction(); - map_function_[TensorFuncType::FUNC_SUB] = new CPUsubFunction(); - map_function_[TensorFuncType::FUNC_MUL] = new CPUmulFunction(); - map_function_[TensorFuncType::FUNC_DIV] = new CPUdivFunction(); - map_function_[TensorFuncType::FUNC_DIVINT] = new CPUdivintFunction(); - map_function_[TensorFuncType::FUNC_TTADD] = new CPUaddTwoFunction(); - map_function_[TensorFuncType::FUNC_TTSUB] = new CPUsubTwoFunction(); - map_function_[TensorFuncType::FUNC_TTMUL] = new CPUmulTwoFunction(); - map_function_[TensorFuncType::FUNC_TTDIV] = new CPUdivTwoFunction(); - map_function_[TensorFuncType::FUNC_MM] = new CPUmmFunction(); - map_function_[TensorFuncType::FUNC_NORM] = new CPUnormFunction(); - map_function_[TensorFuncType::FUNC_MEAN] = new CPUmeanFunction(); - map_function_[TensorFuncType::FUNC_CAT] = new CPUcatFunction(); - map_function_[TensorFuncType::FUNC_VIEW] = new CPUviewFunction(); - map_function_[TensorFuncType::FUNC_TRANPOSE] = new CPUtransposeFunction(); - map_function_[TensorFuncType::FUNC_FLATTEN] = new CPUflattenFunction(); - map_function_[TensorFuncType::FUNC_CLIP] = new CPUclipFunction(); - map_function_[TensorFuncType::FUNC_CLIPAXIS] = new CPUclipaxisFunction(); - map_function_[TensorFuncType::FUNC_CLIPTENSOR] = new CPUcliptensorFunction(); - map_function_[TensorFuncType::FUNC_RANGE] = new CPURangeFunction(); - map_function_[TensorFuncType::FUNC_WHERE] = new CPUwhereFunction(); - map_function_[TensorFuncType::FUNC_INDEX_PUT] = new CPUIndexPutFunction(); - map_function_[TensorFuncType::FUNC_SPLIT] = new CPUsplitFunction(); - map_function_[TensorFuncType::FUNC_SUM] = new CPUsumFunction(); - map_function_[TensorFuncType::FUNC_TOPK] = new CPUtopkFunction(); - map_function_[TensorFuncType::FUNC_EXPPAND] = new CPUexpandFunction(); - map_function_[TensorFuncType::FUNC_ARGSORT] = new CPUargsortFunction(); - map_function_[TensorFuncType::FUNC_BINCOUNT] = new CPUbincountFunction(); - map_function_[TensorFuncType::FUNC_REPEAT] = new CPUrepeatFunction(); - map_function_[TensorFuncType::FUNC_LIKE] = new CPUlikeFunction(); - map_function_[TensorFuncType::FUNC_SCATTERREDUCE] = new CPUScatterReduceFunction(); - map_function_[TensorFuncType::FUNC_APPLY_VISIOROPE] = new CPUVisionRoPEFuncFunction(); - map_function_[TensorFuncType::FUNC_FA2] = new CPUFlashAttention2Func(); - // models use only - map_function_[TensorFuncType::FUNC_FUYU_GATHER_EMBD] = new CPUFuyuGatherEmbdFunc(); - map_function_[TensorFuncType::FUNC_PHI3V_HD_MERGE] = new CPUPhi3VhdmergeFunction(); +void CPUBackend::registerFuncs(){ + // map_function_[TensorFuncType::FUNC_ADD] = new CPUaddFunction(); + // map_function_[TensorFuncType::FUNC_SUB] = new CPUsubFunction(); + // map_function_[TensorFuncType::FUNC_MUL] = new CPUmulFunction(); + // map_function_[TensorFuncType::FUNC_DIV] = new CPUdivFunction(); + // map_function_[TensorFuncType::FUNC_DIVINT] = new CPUdivintFunction(); + // map_function_[TensorFuncType::FUNC_TTADD] = new CPUaddTwoFunction(); + // map_function_[TensorFuncType::FUNC_TTSUB] = new CPUsubTwoFunction(); + // map_function_[TensorFuncType::FUNC_TTMUL] = new CPUmulTwoFunction(); + // map_function_[TensorFuncType::FUNC_TTDIV] = new CPUdivTwoFunction(); + // map_function_[TensorFuncType::FUNC_MM] = new CPUmmFunction(); + // map_function_[TensorFuncType::FUNC_NORM] = new CPUnormFunction(); + // map_function_[TensorFuncType::FUNC_MEAN] = new CPUmeanFunction(); + // map_function_[TensorFuncType::FUNC_CAT] = new CPUcatFunction(); + // map_function_[TensorFuncType::FUNC_VIEW] = new CPUviewFunction(); + // map_function_[TensorFuncType::FUNC_TRANPOSE] = new CPUtransposeFunction(); + // map_function_[TensorFuncType::FUNC_FLATTEN] = new CPUflattenFunction(); + // map_function_[TensorFuncType::FUNC_CLIP] = new CPUclipFunction(); + // map_function_[TensorFuncType::FUNC_CLIPAXIS] = new CPUclipaxisFunction(); + // map_function_[TensorFuncType::FUNC_CLIPTENSOR] = new CPUcliptensorFunction(); + // map_function_[TensorFuncType::FUNC_RANGE] = new CPURangeFunction(); + // map_function_[TensorFuncType::FUNC_WHERE] = new CPUwhereFunction(); + // map_function_[TensorFuncType::FUNC_INDEX_PUT] = new CPUIndexPutFunction(); + // map_function_[TensorFuncType::FUNC_SPLIT] = new CPUsplitFunction(); + // map_function_[TensorFuncType::FUNC_SUM] = new CPUsumFunction(); + // map_function_[TensorFuncType::FUNC_TOPK] = new CPUtopkFunction(); + // map_function_[TensorFuncType::FUNC_EXPPAND] = new CPUexpandFunction(); + // map_function_[TensorFuncType::FUNC_ARGSORT] = new CPUargsortFunction(); + // map_function_[TensorFuncType::FUNC_BINCOUNT] = new CPUbincountFunction(); + // map_function_[TensorFuncType::FUNC_REPEAT] = new CPUrepeatFunction(); + // map_function_[TensorFuncType::FUNC_LIKE] = new CPUlikeFunction(); + // map_function_[TensorFuncType::FUNC_SCATTERREDUCE] = new CPUScatterReduceFunction(); + // map_function_[TensorFuncType::FUNC_APPLY_VISIOROPE] = new CPUVisionRoPEFuncFunction(); + // map_function_[TensorFuncType::FUNC_FA2] = new CPUFlashAttention2Func(); + // // models use only + // map_function_[TensorFuncType::FUNC_FUYU_GATHER_EMBD] = new CPUFuyuGatherEmbdFunc(); + // map_function_[TensorFuncType::FUNC_PHI3V_HD_MERGE] = new CPUPhi3VhdmergeFunction(); }; int CPUBackend::cpu_threads = 4; -std::vector CPUBackend::runFunc( - std::vector out_names, - TensorFuncType type, - std::vector float_args, - std::vector> input_tensors, - bool in_place) { - Module *module = input_tensors.empty() ? Module::llm_model_ptr : input_tensors[0]->module(); - auto &activation_tensors = module->activation_tensors; - assert(module != nullptr); - Backend *backend = input_tensors.empty() ? Backend::global_backends[MLLM_CPU] : input_tensors[0]->backend(); - TensorFunction *func = backend->funcCreate(type); - - if (module->doLoad) { - auto &activation_tensors_num = module->activation_tensors_num; +/************************************************************************************************/ +/* Refactored Helper Functions */ +/************************************************************************************************/ +/** + * @brief Creates the initial output tensor objects (shells), either from an aggregated input or from a list of names. + * @param out_tensors The vector of output tensors to be populated. + * @param input_tensors The vector of input tensors, checked for aggregation. + * @param out_names The names for the output tensors if not from an aggregated input. + * @param module The current module. + * @param backend The current backend. + */ +void CPUBackend::_create_output_tensors( + std::vector> &out_tensors, + const std::vector> &input_tensors, + const std::vector &out_names, + Module *module, + map> &activation_tensors, + Backend *backend) { + if (input_tensors.size() == 1 && !input_tensors[0]->aggregatedTensors().empty()) { + const auto &aggregated_tensors = input_tensors[0]->aggregatedTensors(); + out_tensors.insert(out_tensors.end(), aggregated_tensors.begin(), aggregated_tensors.end()); + } else { for (const auto &out_name : out_names) { - if (activation_tensors.find(out_name) == activation_tensors.end()) { - activation_tensors[out_name] = std::make_shared(backend); - activation_tensors[out_name]->setName(out_name); - activation_tensors[out_name]->setModule(module); - activation_tensors_num[out_name] = 0; + auto out_tensor = std::make_shared(backend); + out_tensor->setName(out_name); + out_tensor->setModule(module); + auto it = activation_tensors.find(out_name); + if (it != activation_tensors.end() && out_name.find("-transpose") == std::string::npos && out_tensor->ctype() != it->second->ctype()) { + out_tensor->chls() = it->second->chls(); + out_tensor->setCtype(it->second->ctype()); } + out_tensors.push_back(out_tensor); } - std::vector> inPtrs; - for (auto &t : input_tensors) inPtrs.push_back(activation_tensors[t->name()]); - std::vector> outPtrs; - for (auto &name : out_names) outPtrs.push_back(activation_tensors[name]); - func->setUp(outPtrs, inPtrs, float_args); - std::vector results; - for (auto &name : out_names) results.push_back(*activation_tensors[name]); - return results; } +} -#ifdef DEBUGOPTIME - auto start_t = mllm_time_us(); -#endif - std::vector> out_tensors; - if (in_place) { - for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { - input_tensors[i]->setName(out_names[i]); - out_tensors.push_back(input_tensors[i]); - } - } else { - if (input_tensors.size() == 1 && !input_tensors[0]->aggregatedTensors().empty()) { - auto aggregatedTensorsSize = input_tensors[0]->aggregatedTensors().size(); - for (int i = 0; i < aggregatedTensorsSize; i++) { - out_tensors.push_back(input_tensors[0]->aggregatedTensors()[i]); - } - } else { - for (auto out_name : out_names) { - auto out_tensor = std::make_shared(backend); - out_tensor->setName(out_name); - out_tensor->setModule(module); - auto it = activation_tensors.find(out_name); - if (it != activation_tensors.end() && out_tensor->name().find("-transpose") == std::string::npos - && out_tensor->ctype() != it->second->ctype()) { - out_tensor->chls() = it->second->chls(); - out_tensor->setCtype(it->second->ctype()); - } - out_tensors.push_back(out_tensor); - } - } - } - func->reshape(out_tensors, input_tensors, float_args); - for (auto &out_tensor : out_tensors) { - if (activation_tensors.find(out_tensor->name()) != activation_tensors.end() - && !activation_tensors[out_tensor->name()]->aggregatedTensors().empty()) { - // 存在aggregatedTensors +/** + * @brief Creates and allocates memory for all output tensors based on various strategies (standard, aggregated, KVCache). + * @param out_tensors The vector to populate with prepared output tensors. + * @param input_tensors The vector of input tensors. + * @param out_names The names of the output tensors. + * @param module The current module. + * @param backend The current backend. + */ +// std::vector CPUBackend::runFunc( +// std::vector out_names, +// TensorFuncType type, +// std::vector float_args, +// std::vector inputs, +// bool in_place) { +// Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); +// auto &activation_tensors = module->activation_tensors; +// assert(module != nullptr); +// Backend *backend = inputs.empty() ? Backend::global_backends[MLLM_CPU] : inputs[0].backend(); +// TensorFunction *func = backend->funcCreate(type); +// if (module->doTrace) { // trace +// for (const auto &out_name : out_names) { +// if (activation_tensors.find(out_name) == activation_tensors.end()) { +// activation_tensors[out_name] = std::make_shared(backend); +// activation_tensors[out_name]->setName(out_name); +// activation_tensors[out_name]->setModule(module); +// } +// } +// std::vector> inPtrs; +// for (auto &input : inputs) { +// inPtrs.push_back(input.shouldInGraphs() ? activation_tensors[input.name()] : +// std::shared_ptr(&input, [](Tensor *) {})); +// } +// std::vector> outPtrs; +// for (auto &name : out_names) outPtrs.push_back(activation_tensors[name]); +// func->setUp(outPtrs, inPtrs, float_args); +// std::vector results; +// for (auto &name : out_names) results.push_back(*activation_tensors[name]); +// return results; +// } +// #ifdef DEBUGOPTIME +// auto start_t = mllm_time_us(); +// #endif +// vector> input_tensors; +// for (auto &input : inputs) { +// input_tensors.push_back(std::shared_ptr(&input, [](Tensor *) {})); +// } +// std::vector> out_tensors; +// // Part 1: Create tensor shells (but don't allocate yet) +// if (!in_place) { +// _create_output_tensors(out_tensors, input_tensors, out_names, module, activation_tensors, backend); +// } else { +// // If in-place, we already have out_tensors filled with input tensors. +// for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { +// input_tensors[i]->setName(out_names[i]); +// out_tensors.push_back(input_tensors[i]); +// } +// } +// // Part 2: Reshape the tensors to determine their dimensions +// func->reshape(out_tensors, input_tensors, float_args); +// // Part 3: Allocate memory for the now-reshaped tensors +// if (!in_place) { +// for (auto &out_tensor : out_tensors) { +// auto act_it = activation_tensors.find(out_tensor->name()); +// auto template_it = act_it != activation_tensors.end()? act_it->second:nullptr; +// out_tensor->allocFromTemplate(template_it); +// } +// } +// // Part 4: Execute the operation +// func->execute(out_tensors, input_tensors, float_args); - bool remove_f = true; - if (activation_tensors[out_tensor->name()]->aggregatedDim() > 3) { - remove_f = false; // 不能移除 - } else { - for (auto &agtensor : activation_tensors[out_tensor->name()]->aggregatedTensors()) { - bool check_m = (agtensor->masterTensor() != nullptr - && agtensor->masterTensor()->name().find("Cache") != std::string::npos); - if (agtensor->ctype() != activation_tensors[out_tensor->name()]->aggregatedTensors()[0]->ctype()) { - remove_f = false; - } else if (check_m) { - remove_f = false; - } - } - } - // if (remove_f) { - // inputs[0]->removeAggregatedTensors(); - // inputs[0]->allowAggregated() = false; - // } - if (!remove_f) { - vector> shared_outputs = {}; - auto split_dim = activation_tensors[out_tensor->name()]->aggregatedDim(); - for (int id = 0; id < activation_tensors[out_tensor->name()]->aggregatedTensors().size(); id++) { - auto shared_ot = std::make_shared(backend); - shared_ot->setName(out_tensor->name() + ".split-" + std::to_string(id)); - shared_ot->setModule(module); - auto ot = activation_tensors[out_tensor->name()]->aggregatedTensors()[id]; - shared_ot->setCtype(ot->ctype()); - switch (split_dim) { - case Chl::HEAD: { - shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), out_tensor->dimension()); - break; - } - case Chl::SEQUENCE: { - shared_ot->reshape(out_tensor->batch(), out_tensor->head(), ot->sequence(), out_tensor->dimension()); - break; - } - case Chl::DIMENSION: { - shared_ot->reshape(out_tensor->batch(), out_tensor->head(), out_tensor->sequence(), ot->dimension()); - break; - } - case Chl::D_HD: - case Chl::HD: { - shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), ot->dimension()); - break; - } - default: { - break; - } - } - if (activation_tensors[shared_ot->name()]->masterTensor() != nullptr - && activation_tensors[shared_ot->name()]->masterTensor()->name().find("Cache") != std::string::npos) { - auto cache_seq_len_ = activation_tensors[shared_ot->name()]->shapeOffset()[2]; - if (shared_ot->name().find("cache") == std::string::npos) { // KVcahe的输出不设置,只有输入设置 - cache_seq_len_ = activation_tensors[shared_ot->name()]->masterTensor()->cache_seq_len_; - auto cpuBackend = dynamic_cast(backend); - if (cpuBackend->isUsingDraft()) { - unsigned int last_draft_length = cpuBackend->getLastDraftLength(); - const std::vector &last_verified_position_ids = cpuBackend->getLastVerifiedPositionIds(); - cache_seq_len_ = cache_seq_len_ - (last_draft_length) + last_verified_position_ids.size(); - } - } - shared_ot->setDtype(activation_tensors[shared_ot->name()]->masterTensor()->dtype()); - // masterTensor() 是Cache所以shape没有问题 - shared_ot->shallowCopyFrom(activation_tensors[shared_ot->name()]->masterTensor(), false, {0, 0, cache_seq_len_, 0}); - } else { - shared_ot->alloc(); - } - shared_outputs.push_back(shared_ot); - } - out_tensor->addTensors(shared_outputs, split_dim); - } else { - out_tensor->allowAggregated() = false; - out_tensor->alloc(); - } - } else if (activation_tensors.find(out_tensor->name()) != activation_tensors.end() - && activation_tensors[out_tensor->name()]->masterTensor() != nullptr - && activation_tensors[out_tensor->name()]->masterTensor()->name().find("Cache") != std::string::npos) { - // output_tensor的master是KVCache - auto cache_seq_len_ = activation_tensors[out_tensor->name()]->shapeOffset()[2]; - if (out_tensor->name().find("cache") == std::string::npos) { // KVcahe的输出不设置,只有输入设置 - cache_seq_len_ = activation_tensors[out_tensor->name()]->masterTensor()->cache_seq_len_; - auto cpuBackend = dynamic_cast(backend); - if (cpuBackend->isUsingDraft()) { - unsigned int last_draft_length = cpuBackend->getLastDraftLength(); - const std::vector &last_verified_position_ids = cpuBackend->getLastVerifiedPositionIds(); - cache_seq_len_ = cache_seq_len_ - (last_draft_length) + last_verified_position_ids.size(); - } - } - out_tensor->setDtype(activation_tensors[out_tensor->name()]->masterTensor()->dtype()); - out_tensor->shallowCopyFrom(activation_tensors[out_tensor->name()]->masterTensor(), false, {0, 0, cache_seq_len_, 0}); - } else { - out_tensor->alloc(); - } - } - func->execute(out_tensors, input_tensors, float_args); -#ifdef DEBUGOPTIME - auto end_t = mllm_time_us(); - std::cout << out_names[0] << " | time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; -#endif - vector results; - for (const auto &out_tensor : out_tensors) { results.push_back(*out_tensor); } - return results; -} +// #ifdef DEBUGOPTIME +// auto end_t = mllm_time_us(); +// std::cout << out_names[0] << " | time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; +// #endif +// vector results; +// for (const auto &out_tensor : out_tensors) { results.push_back(*out_tensor); } +// return results; +// } -std::vector CPUBackend::runLayer(Layer *layer, std::vector inputs, int N) { +std::vector CPUBackend::runOp(Op *op, std::vector inputs, std::vector out_names, bool in_place) { Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); map> &activation_tensors = module->activation_tensors; - bool do_init = false; - if (module->doLoad || !layer->inited_loaded) { - // set backend to current module device and try to create op - // use Module::tmp_device only when creating the op as the recersive module backend only handled in load and init stage - layer->backend_ = Backend::global_backends[MLLM_CPU]; - do_init = !layer->inited_loaded; - if (layer->op_ == nullptr) { - layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); - } - if (module->doLoad) { - layer->op_->load(*module->loader); - layer->inited_loaded = true; - } else if (layer->loaded_param) { - layer->inited_loaded = layer->loaded_param; - } else { - if (!layer->inited_loaded) { - auto empty_loader = new ParamLoader(""); - layer->op_->load(*empty_loader); - layer->inited_loaded = true; - } - } - vector out_names = {}; - int count = (N > 1) ? N : 1; - for (int i = 0; i < count; ++i) { - std::string out_name = (N > 1) ? "out-" + layer->op_->name() + "-" + std::to_string(i) : "out-" + layer->op_->name(); - out_names.push_back(out_name); + if (module->doTrace) { // trace + for (const auto &out_name : out_names) { if (activation_tensors.find(out_name) == activation_tensors.end()) { - activation_tensors[out_name] = std::make_shared(layer->backend_); + activation_tensors[out_name] = std::make_shared(op->backend()); activation_tensors[out_name]->setName(out_name); activation_tensors[out_name]->setModule(module); } } - if (module->doLoad) { - // input_tensors - vector> inPtrs; - for (auto &input : inputs) { - inPtrs.push_back(input.shouldInGraphs() ? activation_tensors[input.name()] : std::shared_ptr(&input, [](Tensor *) {})); - } - // output_tensors - vector> outPtrs = {}; - for (auto &name : out_names) outPtrs.push_back(activation_tensors[name]); - layer->op_->setUp(inPtrs, outPtrs); - vector results = {}; - for (auto &name : out_names) results.push_back(*activation_tensors[name]); - return results; + vector> inPtrs; + for (auto &input : inputs) { + inPtrs.push_back(input.shouldInGraphs() ? activation_tensors[input.name()] : + std::shared_ptr(&input, [](Tensor *) {})); } + vector> outPtrs = {}; + for (auto &name : out_names) outPtrs.push_back(activation_tensors[name]); + op->setUp(inPtrs, outPtrs); + vector results = {}; + for (auto &name : out_names) results.push_back(*activation_tensors[name]); + return results; } - // NEW START #ifdef DEBUGOPTIME uint64_t time_start = mllm_time_us(); @@ -475,137 +458,52 @@ std::vector CPUBackend::runLayer(Layer *layer, std::vector input input_tensors.push_back(std::shared_ptr(&input, [](Tensor *) {})); } vector> out_tensors; - if (input_tensors.size() == 1 && !input_tensors[0]->aggregatedTensors().empty()) { - auto aggregatedTensorsSize = input_tensors[0]->aggregatedTensors().size(); - for (int i = 0; i < aggregatedTensorsSize; i++) { - out_tensors.push_back(input_tensors[0]->aggregatedTensors()[i]); - } + // Part 1: Create tensor shells + if (!in_place) { + _create_output_tensors(out_tensors, input_tensors, out_names, module, activation_tensors, op->backend()); } else { - int count = (N > 1) ? N : 1; - for (int i = 0; i < count; ++i) { - std::string tensor_name = (N > 1) ? "out-" + layer->op_->name() + "-" + std::to_string(i) : "out-" + layer->op_->name(); - auto out_tensor = std::make_shared(layer->backend_); - out_tensor->setName(tensor_name); - out_tensor->setModule(module); - if (out_tensor->name().find("-transpose") == std::string::npos - && out_tensor->ctype() != activation_tensors.at(out_tensor->name())->ctype()) { - out_tensor->chls() = activation_tensors.at(out_tensor->name())->chls(); - out_tensor->setCtype(activation_tensors.at(out_tensor->name())->ctype()); - } - out_tensors.push_back(out_tensor); + // If in-place, we already have out_tensors filled with input tensors. + for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { + input_tensors[i]->setName(out_names[i]); + out_tensors.push_back(input_tensors[i]); } } - // 直接使用 out_tensors 进行 reshape - layer->op_->reshape(input_tensors, out_tensors); - // 直接使用 out_tensors 进行 alloc - for (auto &out_tensor : out_tensors) { - if (activation_tensors.find(out_tensor->name()) != activation_tensors.end() - && !activation_tensors[out_tensor->name()]->aggregatedTensors().empty()) { - // 存在aggregatedTensors - bool remove_f = true; - if (activation_tensors[out_tensor->name()]->aggregatedDim() > 3) { - remove_f = false; // 不能移除 - } else { - for (auto &agtensor : activation_tensors[out_tensor->name()]->aggregatedTensors()) { - bool check_m = (agtensor->masterTensor() != nullptr - && agtensor->masterTensor()->name().find("Cache") != std::string::npos); - if (agtensor->ctype() != activation_tensors[out_tensor->name()]->aggregatedTensors()[0]->ctype()) { - remove_f = false; - } else if (check_m) { - remove_f = false; - } - } - } - if (!remove_f) { - vector> shared_outputs = {}; - auto split_dim = activation_tensors[out_tensor->name()]->aggregatedDim(); - for (int id = 0; id < activation_tensors[out_tensor->name()]->aggregatedTensors().size(); id++) { - auto shared_ot = std::make_shared(layer->backend_); - shared_ot->setName(out_tensor->name() + ".split-" + std::to_string(id)); - shared_ot->setModule(module); - auto ot = activation_tensors[out_tensor->name()]->aggregatedTensors()[id]; - shared_ot->setCtype(ot->ctype()); - switch (split_dim) { - case Chl::HEAD: { - shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), out_tensor->dimension()); - break; - } - case Chl::SEQUENCE: { - shared_ot->reshape(out_tensor->batch(), out_tensor->head(), ot->sequence(), out_tensor->dimension()); - break; - } - case Chl::DIMENSION: { - shared_ot->reshape(out_tensor->batch(), out_tensor->head(), out_tensor->sequence(), ot->dimension()); - break; - } - case Chl::D_HD: - case Chl::HD: { - shared_ot->reshape(out_tensor->batch(), ot->head(), out_tensor->sequence(), ot->dimension()); - break; - } - default: { - break; - } - } - if (activation_tensors[shared_ot->name()]->masterTensor() != nullptr - && activation_tensors[shared_ot->name()]->masterTensor()->name().find("Cache") != std::string::npos) { - auto cache_seq_len_ = activation_tensors[shared_ot->name()]->shapeOffset()[2]; - if (shared_ot->name().find("cache") == std::string::npos) { // KVcahe的输出不设置,只有输入设置 - cache_seq_len_ = activation_tensors[shared_ot->name()]->masterTensor()->cache_seq_len_; - auto cpuBackend = dynamic_cast(layer->backend_); - if (cpuBackend->isUsingDraft()) { - unsigned int last_draft_length = cpuBackend->getLastDraftLength(); - const std::vector &last_verified_position_ids = cpuBackend->getLastVerifiedPositionIds(); - cache_seq_len_ = cache_seq_len_ - (last_draft_length) + last_verified_position_ids.size(); - } - } - shared_ot->setDtype(activation_tensors[shared_ot->name()]->masterTensor()->dtype()); - // masterTensor() 是Cache所以shape没有问题 - shared_ot->shallowCopyFrom(activation_tensors[shared_ot->name()]->masterTensor(), false, {0, 0, cache_seq_len_, 0}); - } else { - shared_ot->alloc(); - } - shared_outputs.push_back(shared_ot); - } - out_tensor->addTensors(shared_outputs, split_dim); - } else { - out_tensor->allowAggregated() = false; - out_tensor->alloc(); - } - } else if (activation_tensors.find(out_tensor->name()) != activation_tensors.end() - && activation_tensors[out_tensor->name()]->masterTensor() != nullptr - && activation_tensors[out_tensor->name()]->masterTensor()->name().find("Cache") != std::string::npos) { - // output_tensor的master是KVCache - auto cache_seq_len_ = activation_tensors[out_tensor->name()]->shapeOffset()[2]; - if (out_tensor->name().find("cache") == std::string::npos) { // KVcahe的输出不设置,只有输入设置 - cache_seq_len_ = activation_tensors[out_tensor->name()]->masterTensor()->cache_seq_len_; - auto cpuBackend = dynamic_cast(layer->backend_); - if (cpuBackend->isUsingDraft()) { - unsigned int last_draft_length = cpuBackend->getLastDraftLength(); - const std::vector &last_verified_position_ids = cpuBackend->getLastVerifiedPositionIds(); - cache_seq_len_ = cache_seq_len_ - (last_draft_length) + last_verified_position_ids.size(); - } - } - out_tensor->setDtype(activation_tensors[out_tensor->name()]->masterTensor()->dtype()); - out_tensor->shallowCopyFrom(activation_tensors[out_tensors[0]->name()]->masterTensor(), false, {0, 0, cache_seq_len_, 0}); - } else { - out_tensor->setDtype(MLLM_TYPE_F32); - out_tensor->alloc(); + // Part 2: Reshape the tensors + op->reshape(input_tensors, out_tensors); + // Part 3: Allocate memory + if (!in_place) { + for (auto &out_tensor : out_tensors) { + auto act_it = activation_tensors.find(out_tensor->name()); + auto template_it = act_it != activation_tensors.end() ? act_it->second : nullptr; + out_tensor->allocFromTemplate(template_it); } } - // 直接使用 out_tensors 进行 execute - layer->op_->execute(input_tensors, out_tensors); + // Part 4: Execute the operation + op->execute(input_tensors, out_tensors); #ifdef DEBUGOPTIME uint64_t time_end = mllm_time_us(); double inference_time_ = (time_end - time_start) / 1000.0F; // ms - std::cout << op_->name() << " | time: " << inference_time_ << "ms" << std::endl; + std::cout << layer->op_->name() << " | time: " << inference_time_ << "ms" << std::endl; #endif - // 将 shared_ptr 转换为 Tensor 返回 + vector results; for (const auto &out_tensor : out_tensors) { results.push_back(*out_tensor); } return results; } + +std::vector CPUBackend::runLayer(Layer *layer, std::vector inputs, int N) { + Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); + map> &activation_tensors = module->activation_tensors; + vector out_names; + int count = (N > 1) ? N : 1; + for (int i = 0; i < count; ++i) { + std::string tensor_name = (N > 1) ? "out-" + layer->op_->name() + "-" + std::to_string(i) : "out-" + layer->op_->name(); + out_names.push_back(tensor_name); + } + return runOp(layer->op_, inputs, out_names, false); +} + std::vector CPUBackend::runForward(Module *module, std::vector inputs, std::vector args) { if (mllm::Module::llm_model_ptr && mllm::Module::llm_model_ptr->doLoad) { auto outputs = module->Forward(inputs, args); diff --git a/src/backends/cpu/CPUBackend.hpp b/src/backends/cpu/CPUBackend.hpp index 1745bf100..0ae291e1f 100644 --- a/src/backends/cpu/CPUBackend.hpp +++ b/src/backends/cpu/CPUBackend.hpp @@ -32,13 +32,15 @@ class CPUBackend final : public Backend { void registerOps() override; void registerFuncs() override; - std::vector runFunc( - std::vector out_names, - TensorFuncType type, - std::vector float_args, - std::vector> input_tensors, - bool in_place) override; + // std::vector runFunc( + // std::vector out_names, + // TensorFuncType type, + // std::vector float_args, + // std::vector input_tensors, + // bool in_place) override{}; std::vector runLayer(Layer *layer, std::vector inputs, int N) override; + + std::vector runOp(Op *op, std::vector input, std::vector out_names, bool in_place) override; std::vector runForward(Module *module, std::vector inputs, std::vector args) override; static int cpu_threads; @@ -76,7 +78,6 @@ class CPUBackend final : public Backend { } // #endif - // #ifdef USE_SD void setLastDraftLength(unsigned int draft_length) { last_draft_length = draft_length; @@ -117,6 +118,13 @@ class CPUBackend final : public Backend { unsigned int last_draft_length = 0; // #endif + void _create_output_tensors( + std::vector> &out_tensors, + const std::vector> &input_tensors, + const std::vector &out_names, + Module *module, + map> &activation_tensors, + Backend *backend); }; } // namespace mllm diff --git a/src/backends/cpu/compute/FlashAttention2.hpp b/src/backends/cpu/compute/FlashAttention2.hpp index 027d6edf3..17dbfab20 100644 --- a/src/backends/cpu/compute/FlashAttention2.hpp +++ b/src/backends/cpu/compute/FlashAttention2.hpp @@ -1,13 +1,7 @@ - #ifndef MLLM_FA2_CAL_HPP #define MLLM_FA2_CAL_HPP -// #include -// #include -// #include -#ifdef __AVX2__ #include -#include #include #include #include @@ -16,12 +10,20 @@ #include "Types.hpp" #include "VecDot.hpp" +#ifdef __AVX2__ +#include +#elif __ARM_NEON__ +#include +#endif + namespace mobi_attn { // ======================================== // 数学函数和工具 // ======================================== #define NEG_INF std::numeric_limits::lowest() + +#ifdef __AVX2__ // Horizontal max of a __m256 vector inline float _mm256_hmax_ps(__m256 x) { __m128 lo = _mm256_castps256_ps128(x); @@ -41,12 +43,25 @@ inline float _mm256_hadd_ps(__m256 x) { sum = _mm_hadd_ps(sum, sum); return _mm_cvtss_f32(sum); } +#elif __ARM_NEON__ +// NEON版本:水平最大值 (Horizontal max of a float32x4_t vector) +// float32x4_t 中包含4个float, vmaxvq_f32可以直接找到这4个float中的最大值 +inline float _vmaxvq_f32_hmax(float32x4_t x) { + return vmaxvq_f32(x); +} + +// NEON版本:水平求和 (Horizontal sum of a float32x4_t vector) +// float32x4_t 中包含4个float, vaddvq_f32可以直接将这4个float相加 +inline float _vaddvq_f32_hadd(float32x4_t x) { + return vaddvq_f32(x); +} +#endif // ======================================== // 内存对齐分配函数 // ======================================== // 使用 posix_memalign 进行分配 -void x86_align_alloc(void **ptr, size_t required_bytes, size_t align) { +void aligned_alloc(void **ptr, size_t required_bytes, size_t align) { // posix_memalign 要求 alignment 必须是 void* 大小的整数倍,并且是 2 的幂 if (align % sizeof(void *) != 0 || (align & (align - 1)) != 0) { *ptr = nullptr; @@ -60,14 +75,14 @@ void x86_align_alloc(void **ptr, size_t required_bytes, size_t align) { } // 直接使用标准 free 进行释放 -void x86_align_free(void *ptr) { +void aligned_free(void *ptr) { free(ptr); } // ======================================== // FlashAttention2 核心实现 (FP32版本) // ======================================== -struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { +struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { using dtype_q_in_t = float; using dtype_kv_in_t = dtype_q_in_t; using dtype_out_t = dtype_q_in_t; @@ -102,6 +117,28 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { score_sum_ = score_sum; } + void fa2(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, + const dtype_t *__restrict__ V, dtype_t *__restrict__ O, const int32_t batch_size, + const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, + const int32_t dim_size, bool causal_mask = true) { + assert(Br == Bc); + assert(Q_Head % KV_Head == 0); + assert(head_size % threads == 0); +#ifdef __AVX2__ + assert(dim_size % 8 == 0); // AVX processes 8 floats at a time +#elif __ARM_NEON__ + assert(dim_size % 4 == 0); // NEON processes 4 floats at a time +#endif + if (seq_size_q != 1) { + __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, + causal_mask); + } else { + __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, + causal_mask); + } + } + +private: // 核心计算函数 inline void __fa2_prefill_append(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, const dtype_t *__restrict__ V, dtype_t *__restrict__ O, @@ -246,38 +283,8 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } - void fa2(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, - const dtype_t *__restrict__ V, dtype_t *__restrict__ O, const int32_t batch_size, - const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, - const int32_t dim_size, bool causal_mask = true) { - assert(Br == Bc); - // assert(Br % 4 == 0); - // FIX: Assert that Q_Head is a multiple of KV_Head for valid GQA/MHA. - assert(Q_Head % KV_Head == 0); - assert(head_size % threads == 0); - assert(dim_size % 8 == 0); // AVX processes 8 floats at a time - - if (seq_size_q != 1) { - __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, - causal_mask); - } else { - __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, - causal_mask); - } - } - -private: - // inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, - // const int32_t dim_size) { - // __m256 zero_vec = _mm256_set1_ps(0.0f); - // __m256 neg_inf_vec = _mm256_set1_ps(NEG_INF); - - // for (int i = 0; i < Br; i += 8) { _mm256_storeu_ps(logsum + i, zero_vec); } - // for (int i = 0; i < Br; i += 8) { _mm256_storeu_ps(scoremax + i, neg_inf_vec); } - // for (int i = 0; i < Br * dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } - // } - inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { +#ifdef __AVX2__ __m256 zero_vec = _mm256_set1_ps(0.0f); __m256 neg_inf_vec = _mm256_set1_ps(NEG_INF); @@ -297,6 +304,27 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (int j = 0; j < Br * dim_size; j += 8) { _mm256_storeu_ps(acc_o + j, zero_vec); } +#elif __ARM_NEON__ + float32x4_t zero_vec = vdupq_n_f32(0.0f); + float32x4_t neg_inf_vec = vdupq_n_f32(NEG_INF); + + int i = 0; + // NEON 一次处理4个 + for (; i <= Br - 4; i += 4) { + vst1q_f32(logsum + i, zero_vec); + vst1q_f32(scoremax + i, neg_inf_vec); + } + // 处理剩余的元素(如果Br不是4的倍数) + for (; i < Br; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF; + } + + // acc_o 的初始化, 调用者保证了 dim_size % 4 == 0 + for (int j = 0; j < Br * dim_size; j += 4) { + vst1q_f32(acc_o + j, zero_vec); + } +#endif } // 【关键修改】函数签名增加 kv_stride_size 参数,用于区分Q和K的步长 @@ -305,6 +333,7 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t q_stride_size, const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_r_end = global_r_start + Br; const int32_t global_c_start = t_c_idx * Bc; @@ -344,6 +373,58 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + + for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + // 为了性能,可以一次处理8个或更多元素,这里保持与AVX版本类似的逻辑,但向量宽度减半 + for (; i <= dim_size - 8; i += 8) { + // 预取数据到缓存 + __builtin_prefetch(q_block_line + i + 64); + __builtin_prefetch(k_block_line + i + 64); + // 加载两组4个float数据 + float32x4_t q_vec0 = vld1q_f32(q_block_line + i); + float32x4_t k_vec0 = vld1q_f32(k_block_line + i); + float32x4_t q_vec1 = vld1q_f32(q_block_line + i + 4); + float32x4_t k_vec1 = vld1q_f32(k_block_line + i + 4); + // 融合乘加 + sum_vec = vfmaq_f32(sum_vec, q_vec0, k_vec0); + sum_vec = vfmaq_f32(sum_vec, q_vec1, k_vec1); + } + // 处理 dim_size % 8 剩下的部分 + for (; i <= dim_size - 4; i += 4) { + float32x4_t q_vec = vld1q_f32(q_block_line + i); + float32x4_t k_vec = vld1q_f32(k_block_line + i); + sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); + } + + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + // 处理最后不足4个的元素 + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + // 应用因果掩码 + if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { + for (int i = 0; i < Br; ++i) { + for (int j = 0; j < Bc; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } +#endif } inline void softmax(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, @@ -351,6 +432,7 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const float scale, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -378,11 +460,57 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { score_sum[br] = sum; } for (int br = 0; br < Br; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + + memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); + + // 1. 找到每行的最大值 m_i + for (int br = 0; br < Br; ++br) { + float32x4_t max_vec = vdupq_n_f32(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 4; bc += 4) { + max_vec = vmaxq_f32(max_vec, vld1q_f32(row + bc)); + } + float max_val = _vmaxvq_f32_hmax(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } + + // 2. 计算缩放因子 s_i = exp((m_i_prev - m_i) * scale) + for (int br = 0; br < Br; ++br) { + score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); + } + + // 3. 计算 P_ij = exp((S_ij - m_i) * scale) 和 l_i = sum(P_ij) + for (int br = 0; br < Br; ++br) { + const float sm = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + // 这里可以进一步用NEON优化expf, 但expf的SIMD实现复杂,暂用标量 + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((row[bc] - sm) * scale); + row[bc] = val; // 更新 acc_s 为 P_ij + sum += val; + } + score_sum[br] = sum; + } + + // 4. 更新 logsum: l_i_new = l_i_prev * s_i + l_i + for (int br = 0; br < Br; ++br) { + logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; + } +#endif } inline void rescale(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -398,6 +526,22 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(row_ptr + j, acc); } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + + for (int i = 0; i < Br; ++i) { + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 4) { + float32x4_t acc = vld1q_f32(row_ptr + j); + acc = vmulq_f32(acc, scale_v); + vst1q_f32(row_ptr + j, acc); + } + } +#endif } // 【关键修改】函数签名增加 kv_head_size 参数,用于计算V的内部步长 @@ -405,6 +549,7 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -428,12 +573,34 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + + const int32_t v_stride_size = kv_head_size * dim_size; + + for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); + const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + float32x4_t v_vec = vld1q_f32(v_ptr); + acc = vfmaq_f32(acc, w_vec, v_vec); + } + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + } + } +#endif } inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, dtype_t *__restrict__ o_block, const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { +#ifdef __AVX2__ #pragma unroll for (int i = 0; i < Br; ++i) { dtype_t *o_block_line = o_block + i * head_size * dim_size; @@ -449,10 +616,25 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } } +#elif __ARM_NEON__ + for (int i = 0; i < Br; ++i) { + dtype_t *o_block_line = o_block + i * head_size * dim_size; + float reciprocal_logsum = 1.0f / logsum[i]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); + float32x4_t result_vec = vmulq_f32(vec_acc_o, reciprocal_logsum_vec); + vst1q_f32(o_block_line + j, result_vec); + } + for (; j < dim_size; ++j) { + o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; + } + } +#endif } // N-fixed functions for handling leftovers - // FIX: Modified mma0_pa_n_fixed to accept separate strides. inline void mma0_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, @@ -460,6 +642,7 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_r_end = global_r_start + Br_n_fixed; const int32_t global_c_start = t_c_idx * Bc; @@ -488,6 +671,36 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br_n_fixed; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + + for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), vld1q_f32(k_block_line + i)); + } + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + + if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { + for (int i = 0; i < Br_n_fixed; ++i) { + for (int j = 0; j < Bc_n_fixed; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } +#endif } inline void softmax_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, @@ -530,6 +743,7 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -542,9 +756,22 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + j), scale_v)); } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + + for (int i = 0; i < Br_n_fixed; ++i) { + float *row_ptr = acc_o + i * dim_size; + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + for (int j = 0; j < dim_size; j += 4) { + vst1q_f32(row_ptr + j, vmulq_f32(vld1q_f32(row_ptr + j), scale_v)); + } + } +#endif } - // FIX: Modified mma1_pa_n_fixed to accept kv_head_size. inline void mma1_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, @@ -552,6 +779,7 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -570,6 +798,26 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + + const int32_t v_stride_size = kv_head_size * dim_size; + + for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); + const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = vfmaq_f32(acc, w_vec, vld1q_f32(v_ptr)); + } + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + } + } +#endif } inline void scale_and_store_pa_n_fixed(const int32_t Br_n_fixed, @@ -577,6 +825,7 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const acc_dtype_t *__restrict__ logsum, dtype_t *__restrict__ o_block, const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { +#ifdef __AVX2__ for (int i = 0; i < Br_n_fixed; ++i) { dtype_t *o_block_line = o_block + i * head_size * dim_size; float reciprocal_logsum = 1.0f / logsum[i]; @@ -590,22 +839,47 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } } +#elif __ARM_NEON__ + for (int i = 0; i < Br_n_fixed; ++i) { + dtype_t *o_block_line = o_block + i * head_size * dim_size; + float reciprocal_logsum = 1.0f / logsum[i]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); + vst1q_f32(o_block_line + j, vmulq_f32(vec_acc_o, reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { + o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; + } + } +#endif } // Decode mode functions inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { +#ifdef __AVX2__ logsum[0] = 0.0f; scoremax[0] = NEG_INF; __m256 zero_vec = _mm256_setzero_ps(); for (int i = 0; i < 1 * dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } +#elif __ARM_NEON__ + logsum[0] = 0.0f; + scoremax[0] = NEG_INF; + float32x4_t zero_vec = vdupq_n_f32(0.0f); + // Br 在 decode 模式下为 1 + for (int i = 0; i < 1 * dim_size; i += 4) { + vst1q_f32(acc_o + i, zero_vec); + } +#endif } - // FIX: Modified mma0_d to accept kv_stride_size. inline void mma0_d(const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const dtype_t *q_block_line = q_block; #pragma unroll for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { @@ -619,6 +893,20 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } acc_s[b_c_idx] = total; } +#elif __ARM_NEON__ + const dtype_t *q_block_line = q_block; // q 只有一个向量 + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), vld1q_f32(k_block_line + i)); + } + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + acc_s[b_c_idx] = total; + } +#endif } inline void softmax_d(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, @@ -646,19 +934,28 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ __m256 scale_v = _mm256_set1_ps(score_scale[0]); for (int j = 0; j < dim_size; j += 8) { __m256 acc = _mm256_loadu_ps(acc_o + j); acc = _mm256_mul_ps(acc, scale_v); _mm256_storeu_ps(acc_o + j, acc); } +#elif __ARM_NEON__ + float32x4_t scale_v = vdupq_n_f32(score_scale[0]); + for (int j = 0; j < dim_size; j += 4) { + float32x4_t acc = vld1q_f32(acc_o + j); + acc = vmulq_f32(acc, scale_v); + vst1q_f32(acc_o + j, acc); + } +#endif } - // FIX: Modified mma1_d to accept kv_head_size. inline void mma1_d(const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t v_stride_size = kv_head_size * dim_size; for (int d_base = 0; d_base < dim_size; d_base += 8) { __m256 acc = _mm256_loadu_ps(acc_o + d_base); @@ -669,12 +966,25 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } _mm256_storeu_ps(acc_o + d_base, acc); } +#elif __ARM_NEON__ + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); + const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = vfmaq_f32(acc, w_vec, vld1q_f32(v_ptr)); + } + vst1q_f32(acc_o + d_base, acc); + } +#endif } inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, dtype_t *__restrict__ o_block, const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { +#ifdef __AVX2__ float reciprocal_logsum = 1.0f / logsum[0]; __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); int j = 0; @@ -684,10 +994,20 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (; j < dim_size; ++j) { o_block[j] = acc_o[j] * reciprocal_logsum; } +#elif __ARM_NEON__ + float reciprocal_logsum = 1.0f / logsum[0]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { + o_block[j] = acc_o[j] * reciprocal_logsum; + } +#endif } // Decode n-fixed functions - // FIX: Modified mma0_d_n_fixed to accept kv_stride_size. inline void mma0_d_n_fixed(const int32_t Bc_n_fixed, const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, const int32_t kv_stride_size, @@ -735,7 +1055,6 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } - // FIX: Modified mma1_d_n_fixed to accept kv_head_size. inline void mma1_d_n_fixed(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, @@ -764,7 +1083,7 @@ struct AVX_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { // ======================================== // FlashAttention2 核心实现 ( Q FP32/KV FP16 输入,FP32 输出版本) // ======================================== -struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { +struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { // 【修改】定义多种输入类型 using dtype_q_in_t = float; using dtype_kv_in_t = mllm_fp16_t; @@ -800,9 +1119,13 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, const int32_t dim_size, bool causal_mask = true) { assert(Br == Bc); - // assert(Br % 4 == 0); assert(head_size % threads == 0); +#ifdef __AVX2__ assert(dim_size % 8 == 0); +#elif __ARM_NEON__ + assert(dim_size % 4 == 0); + assert(Q_Head % KV_Head == 0); +#endif if (seq_size_q != 1) { __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); @@ -812,6 +1135,12 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } private: +#if __ARM_NEON__ + // 定义一个宏,用于从内存加载4个fp16, 并转换为一个fp32向量 + // 这需要 ARMv8.2-A FP16 指令支持 +#define MLLM_NEON_F32x4_FROM_FP16(addr) vcvt_f32_f16(vld1_f16((const __fp16 *)(addr))) +#endif + inline void __fa2_prefill_append(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, const int32_t batch_size, const int32_t head_size, @@ -944,6 +1273,7 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { +#ifdef __AVX2__ __m256 zero_vec = _mm256_set1_ps(0.0f); __m256 neg_inf_vec = _mm256_set1_ps(NEG_INF); @@ -963,6 +1293,22 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (int j = 0; j < Br * dim_size; j += 8) { _mm256_storeu_ps(acc_o + j, zero_vec); } +#elif __ARM_NEON__ + float32x4_t zero_vec = vdupq_n_f32(0.0f); + float32x4_t neg_inf_vec = vdupq_n_f32(NEG_INF); + int i = 0; + for (; i <= Br - 4; i += 4) { + vst1q_f32(logsum + i, zero_vec); + vst1q_f32(scoremax + i, neg_inf_vec); + } + for (; i < Br; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF; + } + for (int j = 0; j < Br * dim_size; j += 4) { + vst1q_f32(acc_o + j, zero_vec); + } +#endif } inline void mma0(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, @@ -970,6 +1316,7 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t q_stride_size, const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br, global_r_end = global_r_start + Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -997,6 +1344,236 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + + // --- 优化核心 --- + // 策略: 采用4x4微内核,结合深度循环展开,最大化利用NEON指令。 + // + // 步骤 1: 将当前需要的Q块从FP32转换为FP16。 + // 这是为了能够使用最高效的FP16 FMA指令 (vfmlalq_f16)。 + // 使用alignas确保缓冲区内存对齐,有利于SIMD加载。 + alignas(16) __fp16 q_f16_buf[Br * dim_size]; + for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + const dtype_q_in_t *q_line_f32 = q_block + b_r_idx * q_stride_size; + __fp16 *q_line_f16 = q_f16_buf + b_r_idx * dim_size; + int d = 0; + // 一次转换8个float + for (; d <= dim_size - 8; d += 8) { + // 加载两组FP32数据 + float32x4_t f32_vec_0 = vld1q_f32(q_line_f32 + d); + float32x4_t f32_vec_1 = vld1q_f32(q_line_f32 + d + 4); + // 转换为一个FP16x8向量并存储 + float16x8_t f16_vec = vcombine_f16(vcvt_f16_f32(f32_vec_0), vcvt_f16_f32(f32_vec_1)); + vst1q_f16(q_line_f16 + d, f16_vec); + } + // 处理末尾不足8个的元素 + for (; d < dim_size; ++d) { + q_line_f16[d] = (__fp16)q_line_f32[d]; + } + } + + const int32_t br_4_end = (Br / 4) * 4; + const int32_t bc_4_end = (Bc / 4) * 4; + + // 步骤 2: 4x4 微内核主循环。处理Br和Bc是4的倍数的部分。 + int32_t b_r_idx = 0; + for (; b_r_idx < br_4_end; b_r_idx += 4) { + int32_t b_c_idx = 0; + for (; b_c_idx < bc_4_end; b_c_idx += 4) { + // 定义 4x4=16 个FP32累加器向量,用于存储中间结果 + float32x4_t acc00, acc01, acc02, acc03; + float32x4_t acc10, acc11, acc12, acc13; + float32x4_t acc20, acc21, acc22, acc23; + float32x4_t acc30, acc31, acc32, acc33; + + // 初始化累加器为0 + acc00 = vdupq_n_f32(0.0f); + acc01 = vdupq_n_f32(0.0f); + acc02 = vdupq_n_f32(0.0f); + acc03 = vdupq_n_f32(0.0f); + acc10 = vdupq_n_f32(0.0f); + acc11 = vdupq_n_f32(0.0f); + acc12 = vdupq_n_f32(0.0f); + acc13 = vdupq_n_f32(0.0f); + acc20 = vdupq_n_f32(0.0f); + acc21 = vdupq_n_f32(0.0f); + acc22 = vdupq_n_f32(0.0f); + acc23 = vdupq_n_f32(0.0f); + acc30 = vdupq_n_f32(0.0f); + acc31 = vdupq_n_f32(0.0f); + acc32 = vdupq_n_f32(0.0f); + acc33 = vdupq_n_f32(0.0f); + + // 获取当前4x4 tile对应的Q和K的行指针 + const __fp16 *q0_ptr = q_f16_buf + (b_r_idx + 0) * dim_size; + const __fp16 *q1_ptr = q_f16_buf + (b_r_idx + 1) * dim_size; + const __fp16 *q2_ptr = q_f16_buf + (b_r_idx + 2) * dim_size; + const __fp16 *q3_ptr = q_f16_buf + (b_r_idx + 3) * dim_size; + + const __fp16 *k0_ptr = (const __fp16 *)k_block + (b_c_idx + 0) * kv_stride_size; + const __fp16 *k1_ptr = (const __fp16 *)k_block + (b_c_idx + 1) * kv_stride_size; + const __fp16 *k2_ptr = (const __fp16 *)k_block + (b_c_idx + 2) * kv_stride_size; + const __fp16 *k3_ptr = (const __fp16 *)k_block + (b_c_idx + 3) * kv_stride_size; + + // 沿向量维度 (dim_size) 进行循环计算 + int k = 0; + // 深度展开,一次处理8个元素 (float16x8_t) + for (; k <= dim_size - 8; k += 8) { + // 数据预取,减少内存访问延迟 + __builtin_prefetch(q0_ptr + k + 64); + __builtin_prefetch(q1_ptr + k + 64); + __builtin_prefetch(k0_ptr + k + 64); + __builtin_prefetch(k1_ptr + k + 64); + + // 加载4行Q的数据 + float16x8_t q0_vec = vld1q_f16(q0_ptr + k); + float16x8_t q1_vec = vld1q_f16(q1_ptr + k); + float16x8_t q2_vec = vld1q_f16(q2_ptr + k); + float16x8_t q3_vec = vld1q_f16(q3_ptr + k); + + // 加载K并进行外积计算 + float16x8_t k0_vec = vld1q_f16(k0_ptr + k); + acc00 = vfmlalq_low_f16(acc00, q0_vec, k0_vec); + acc00 = vfmlalq_high_f16(acc00, q0_vec, k0_vec); + acc10 = vfmlalq_low_f16(acc10, q1_vec, k0_vec); + acc10 = vfmlalq_high_f16(acc10, q1_vec, k0_vec); + acc20 = vfmlalq_low_f16(acc20, q2_vec, k0_vec); + acc20 = vfmlalq_high_f16(acc20, q2_vec, k0_vec); + acc30 = vfmlalq_low_f16(acc30, q3_vec, k0_vec); + acc30 = vfmlalq_high_f16(acc30, q3_vec, k0_vec); + + float16x8_t k1_vec = vld1q_f16(k1_ptr + k); + acc01 = vfmlalq_low_f16(acc01, q0_vec, k1_vec); + acc01 = vfmlalq_high_f16(acc01, q0_vec, k1_vec); + acc11 = vfmlalq_low_f16(acc11, q1_vec, k1_vec); + acc11 = vfmlalq_high_f16(acc11, q1_vec, k1_vec); + acc21 = vfmlalq_low_f16(acc21, q2_vec, k1_vec); + acc21 = vfmlalq_high_f16(acc21, q2_vec, k1_vec); + acc31 = vfmlalq_low_f16(acc31, q3_vec, k1_vec); + acc31 = vfmlalq_high_f16(acc31, q3_vec, k1_vec); + + float16x8_t k2_vec = vld1q_f16(k2_ptr + k); + acc02 = vfmlalq_low_f16(acc02, q0_vec, k2_vec); + acc02 = vfmlalq_high_f16(acc02, q0_vec, k2_vec); + acc12 = vfmlalq_low_f16(acc12, q1_vec, k2_vec); + acc12 = vfmlalq_high_f16(acc12, q1_vec, k2_vec); + acc22 = vfmlalq_low_f16(acc22, q2_vec, k2_vec); + acc22 = vfmlalq_high_f16(acc22, q2_vec, k2_vec); + acc32 = vfmlalq_low_f16(acc32, q3_vec, k2_vec); + acc32 = vfmlalq_high_f16(acc32, q3_vec, k2_vec); + + float16x8_t k3_vec = vld1q_f16(k3_ptr + k); + acc03 = vfmlalq_low_f16(acc03, q0_vec, k3_vec); + acc03 = vfmlalq_high_f16(acc03, q0_vec, k3_vec); + acc13 = vfmlalq_low_f16(acc13, q1_vec, k3_vec); + acc13 = vfmlalq_high_f16(acc13, q1_vec, k3_vec); + acc23 = vfmlalq_low_f16(acc23, q2_vec, k3_vec); + acc23 = vfmlalq_high_f16(acc23, q2_vec, k3_vec); + acc33 = vfmlalq_low_f16(acc33, q3_vec, k3_vec); + acc33 = vfmlalq_high_f16(acc33, q3_vec, k3_vec); + } + + // 水平求和,将向量累加器中的4个float相加,得到最终的16个标量结果 + float *c_ptr; + c_ptr = acc_s + (b_r_idx + 0) * Bc + b_c_idx; + c_ptr[0] = vaddvq_f32(acc00); + c_ptr[1] = vaddvq_f32(acc01); + c_ptr[2] = vaddvq_f32(acc02); + c_ptr[3] = vaddvq_f32(acc03); + c_ptr = acc_s + (b_r_idx + 1) * Bc + b_c_idx; + c_ptr[0] = vaddvq_f32(acc10); + c_ptr[1] = vaddvq_f32(acc11); + c_ptr[2] = vaddvq_f32(acc12); + c_ptr[3] = vaddvq_f32(acc13); + c_ptr = acc_s + (b_r_idx + 2) * Bc + b_c_idx; + c_ptr[0] = vaddvq_f32(acc20); + c_ptr[1] = vaddvq_f32(acc21); + c_ptr[2] = vaddvq_f32(acc22); + c_ptr[3] = vaddvq_f32(acc23); + c_ptr = acc_s + (b_r_idx + 3) * Bc + b_c_idx; + c_ptr[0] = vaddvq_f32(acc30); + c_ptr[1] = vaddvq_f32(acc31); + c_ptr[2] = vaddvq_f32(acc32); + c_ptr[3] = vaddvq_f32(acc33); + + // 处理末尾不足8个的元素 + for (; k < dim_size; ++k) { + acc_s[(b_r_idx + 0) * Bc + b_c_idx + 0] += (float)q0_ptr[k] * (float)k0_ptr[k]; + acc_s[(b_r_idx + 0) * Bc + b_c_idx + 1] += (float)q0_ptr[k] * (float)k1_ptr[k]; + acc_s[(b_r_idx + 0) * Bc + b_c_idx + 2] += (float)q0_ptr[k] * (float)k2_ptr[k]; + acc_s[(b_r_idx + 0) * Bc + b_c_idx + 3] += (float)q0_ptr[k] * (float)k3_ptr[k]; + + acc_s[(b_r_idx + 1) * Bc + b_c_idx + 0] += (float)q1_ptr[k] * (float)k0_ptr[k]; + acc_s[(b_r_idx + 1) * Bc + b_c_idx + 1] += (float)q1_ptr[k] * (float)k1_ptr[k]; + acc_s[(b_r_idx + 1) * Bc + b_c_idx + 2] += (float)q1_ptr[k] * (float)k2_ptr[k]; + acc_s[(b_r_idx + 1) * Bc + b_c_idx + 3] += (float)q1_ptr[k] * (float)k3_ptr[k]; + + acc_s[(b_r_idx + 2) * Bc + b_c_idx + 0] += (float)q2_ptr[k] * (float)k0_ptr[k]; + acc_s[(b_r_idx + 2) * Bc + b_c_idx + 1] += (float)q2_ptr[k] * (float)k1_ptr[k]; + acc_s[(b_r_idx + 2) * Bc + b_c_idx + 2] += (float)q2_ptr[k] * (float)k2_ptr[k]; + acc_s[(b_r_idx + 2) * Bc + b_c_idx + 3] += (float)q2_ptr[k] * (float)k3_ptr[k]; + + acc_s[(b_r_idx + 3) * Bc + b_c_idx + 0] += (float)q3_ptr[k] * (float)k0_ptr[k]; + acc_s[(b_r_idx + 3) * Bc + b_c_idx + 1] += (float)q3_ptr[k] * (float)k1_ptr[k]; + acc_s[(b_r_idx + 3) * Bc + b_c_idx + 2] += (float)q3_ptr[k] * (float)k2_ptr[k]; + acc_s[(b_r_idx + 3) * Bc + b_c_idx + 3] += (float)q3_ptr[k] * (float)k3_ptr[k]; + } + } + } + + // 步骤 3: Fallback - 处理所有剩余的行和列。 + // 这部分确保了即使Br, Bc不是4的倍数,计算依然正确。 + for (b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + // 如果行已经被4x4内核处理过,则只处理剩余的列 + if (b_r_idx < br_4_end) { + for (int32_t b_c_idx = bc_4_end; b_c_idx < Bc; ++b_c_idx) { + const __fp16 *q_f16_line = q_f16_buf + b_r_idx * dim_size; + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + float16x8_t q_vec = vld1q_f16(q_f16_line + i); + float16x8_t k_vec = vld1q_f16((const __fp16 *)k_block_line + i); + sum_vec = vfmlalq_low_f16(sum_vec, q_vec, k_vec); + sum_vec = vfmlalq_high_f16(sum_vec, q_vec, k_vec); + } + acc_dtype_t total = vaddvq_f32(sum_vec); + for (; i < dim_size; ++i) { total += (float)q_f16_line[i] * (float)k_block_line[i]; } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } else { // 否则,处理整行 + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const __fp16 *q_f16_line = q_f16_buf + b_r_idx * dim_size; + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 8; i += 8) { + float16x8_t q_vec = vld1q_f16(q_f16_line + i); + float16x8_t k_vec = vld1q_f16((const __fp16 *)k_block_line + i); + sum_vec = vfmlalq_low_f16(sum_vec, q_vec, k_vec); + sum_vec = vfmlalq_high_f16(sum_vec, q_vec, k_vec); + } + acc_dtype_t total = vaddvq_f32(sum_vec); + for (; i < dim_size; ++i) { total += (float)q_f16_line[i] * (float)k_block_line[i]; } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + } + + // 步骤 4: 应用因果掩码 (逻辑保持不变) + if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { + for (int i = 0; i < Br; ++i) { + for (int j = 0; j < Bc; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } +#endif } inline void softmax(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, @@ -1008,6 +1585,7 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { int delta_pos = seq_size_k - seq_size_q; if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); +#ifdef __AVX2__ for (int br = 0; br < Br; ++br) { __m256 max_vec = _mm256_set1_ps(scoremax[br]); acc_dtype_t *row = acc_s + br * Bc; @@ -1017,6 +1595,17 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } scoremax[br] = max_val; } +#elif __ARM_NEON__ + for (int br = 0; br < Br; ++br) { + float32x4_t max_vec = vdupq_n_f32(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 4; bc += 4) { max_vec = vmaxq_f32(max_vec, vld1q_f32(row + bc)); } + float max_val = _vmaxvq_f32_hmax(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } +#endif for (int br = 0; br < Br; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } for (int br = 0; br < Br; ++br) { const float sm = scoremax[br]; @@ -1035,6 +1624,7 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { inline void rescale(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ // (无变化) const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; @@ -1049,12 +1639,28 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(row_ptr + j, acc); } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + for (int i = 0; i < Br; ++i) { + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + float *row_ptr = acc_o + i * dim_size; + for (int j = 0; j < dim_size; j += 4) { + float32x4_t acc = vld1q_f32(row_ptr + j); + acc = vmulq_f32(acc, scale_v); + vst1q_f32(row_ptr + j, acc); + } + } +#endif } inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -1072,6 +1678,35 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + const int32_t v_stride_size = kv_head_size * dim_size; + // 循环结构 (Br, dim_size, Bc) 对 acc_o 的读写更友好 + for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 4) { + // 加载128位的FP32累加器 + float32x4_t acc_vec = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + // 从w_block直接读取FP32的P标量 + const float p_scalar_f32 = w_block[b_r_idx * Bc + b_c_idx]; + // 将FP32标量广播为一个128位向量 + const float32x4_t p_vec_f32 = vdupq_n_f32(p_scalar_f32); + // 加载FP16的V向量 + const __fp16 *v_ptr = (const __fp16 *)v_block + b_c_idx * v_stride_size + d_base; + const float16x4_t v_vec_f16 = vld1_f16(v_ptr); + // 将V向量从FP16转换为FP32 + const float32x4_t v_vec_f32 = vcvt_f32_f16(v_vec_f16); + // 执行FP32的融合乘加 + acc_vec = vfmaq_f32(acc_vec, p_vec_f32, v_vec_f32); + } + // 将结果写回内存 + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc_vec); + } + } +#endif } inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, @@ -1083,7 +1718,7 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { // 正确的行步进已经由外层循环的 o_block 指针计算好了 // 我们只需要在此基础上按行写入即可 dtype_out_t *o_block_line = o_block + i * head_size * dim_size; // << 保持 BSHD 的行步长 - +#ifdef __AVX2__ __m256 reciprocal_logsum_vec = _mm256_set1_ps(1.0f / logsum[i]); int j = 0; for (; j <= dim_size - 8; j += 8) { @@ -1093,6 +1728,15 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } float reciprocal_logsum = 1.0f / logsum[i]; for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } +#elif __ARM_NEON__ + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(1.0f / logsum[i]); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + vst1q_f32(o_block_line + j, vmulq_f32(vld1q_f32(acc_o + i * dim_size + j), reciprocal_logsum_vec)); + } + float reciprocal_logsum = 1.0f / logsum[i]; + for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } +#endif } } @@ -1102,6 +1746,7 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t q_stride_size, const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_r_end = global_r_start + Br_n_fixed; const int32_t global_c_start = t_c_idx * Bc; @@ -1128,6 +1773,33 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br, global_r_end = global_r_start + Br_n_fixed; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } + for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + const dtype_q_in_t *q_block_line = q_block + b_r_idx * q_stride_size; + for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), MLLM_NEON_F32x4_FROM_FP16(k_block_line + i)); + } + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_s[b_r_idx * Bc + b_c_idx] = total; + } + } + if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { + for (int i = 0; i < Br_n_fixed; ++i) { + for (int j = 0; j < Bc_n_fixed; ++j) { + if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + } + } + } +#endif } inline void softmax_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, @@ -1166,6 +1838,7 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -1177,6 +1850,19 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + j), scale_v)); } } +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + for (int i = 0; i < Br_n_fixed; ++i) { + float *row_ptr = acc_o + i * dim_size; + float32x4_t scale_v = vdupq_n_f32(score_scale[i]); + for (int j = 0; j < dim_size; j += 4) { + vst1q_f32(row_ptr + j, vmulq_f32(vld1q_f32(row_ptr + j), scale_v)); + } + } +#endif } inline void mma1_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, @@ -1184,6 +1870,7 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -1200,23 +1887,51 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } } - } - - inline void scale_and_store_pa_n_fixed(const int32_t Br_n_fixed, const acc_dtype_t *__restrict__ acc_o, - const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, - const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { - for (int i = 0; i < Br_n_fixed; ++i) { - // 【修正】同上,这里的行步进计算也是错误的 - dtype_out_t *o_block_line = o_block + i * head_size * dim_size; // << 保持 BSHD 的行步长 - - float reciprocal_logsum = 1.0f / logsum[i]; - __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); - int j = 0; +#elif __ARM_NEON__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; + const int32_t v_stride_size = kv_head_size * dim_size; + for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); + const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); + } + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + } + } +#endif + } + + inline void scale_and_store_pa_n_fixed(const int32_t Br_n_fixed, const acc_dtype_t *__restrict__ acc_o, + const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, + const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { + for (int i = 0; i < Br_n_fixed; ++i) { + // 【修正】同上,这里的行步进计算也是错误的 + dtype_out_t *o_block_line = o_block + i * head_size * dim_size; // << 保持 BSHD 的行步长 +#ifdef __AVX2__ + float reciprocal_logsum = 1.0f / logsum[i]; + __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); + int j = 0; for (; j <= dim_size - 8; j += 8) { __m256 vec_acc_o = _mm256_loadu_ps(acc_o + i * dim_size + j); _mm256_storeu_ps(o_block_line + j, _mm256_mul_ps(vec_acc_o, reciprocal_logsum_vec)); } for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } +#elif __ARM_NEON__ + float reciprocal_logsum = 1.0f / logsum[i]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); + vst1q_f32(o_block_line + j, vmulq_f32(vec_acc_o, reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } +#endif } } @@ -1224,14 +1939,20 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { logsum[0] = 0.0f; scoremax[0] = NEG_INF; +#ifdef __AVX2__ __m256 zero_vec = _mm256_setzero_ps(); for (int i = 0; i < 1 * dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } +#elif __ARM_NEON__ + float32x4_t zero_vec = vdupq_n_f32(0.0f); + for (int i = 0; i < 1 * dim_size; i += 4) { vst1q_f32(acc_o + i, zero_vec); } +#endif } inline void mma0_d(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const dtype_q_in_t *q_block_line = q_block; for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; @@ -1244,6 +1965,20 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } acc_s[b_c_idx] = total; } +#elif __ARM_NEON__ + const dtype_q_in_t *q_block_line = q_block; + for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + int i = 0; + for (; i <= dim_size - 4; i += 4) { + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), MLLM_NEON_F32x4_FROM_FP16(k_block_line + i)); + } + acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); + for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_s[b_c_idx] = total; + } +#endif } inline void softmax_d(acc_dtype_t *__restrict__ acc_s, @@ -1270,18 +2005,26 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ __m256 scale_v = _mm256_set1_ps(score_scale[0]); for (int j = 0; j < dim_size; j += 8) { __m256 acc = _mm256_loadu_ps(acc_o + j); acc = _mm256_mul_ps(acc, scale_v); _mm256_storeu_ps(acc_o + j, acc); } +#elif __ARM_NEON__ + float32x4_t scale_v = vdupq_n_f32(score_scale[0]); + for (int j = 0; j < dim_size; j += 4) { + vst1q_f32(acc_o + j, vmulq_f32(vld1q_f32(acc_o + j), scale_v)); + } +#endif } inline void mma1_d(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ const int32_t v_stride_size = kv_head_size * dim_size; for (int d_base = 0; d_base < dim_size; d_base += 8) { __m256 acc = _mm256_loadu_ps(acc_o + d_base); @@ -1293,6 +2036,18 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } _mm256_storeu_ps(acc_o + d_base, acc); } +#elif __ARM_NEON__ + const int32_t v_stride_size = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc = vld1q_f32(acc_o + d_base); + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); + const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); + } + vst1q_f32(acc_o + d_base, acc); + } +#endif } // (此函数无变化,但为完整性一并提供) inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, @@ -1300,11 +2055,19 @@ struct AVX_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { float reciprocal_logsum = 1.0f / logsum[0]; +#ifdef __AVX2__ __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); int j = 0; for (; j <= dim_size - 8; j += 8) { _mm256_storeu_ps(o_block + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), reciprocal_logsum_vec)); } +#elif __ARM_NEON__ + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); + } +#endif for (; j < dim_size; ++j) { o_block[j] = acc_o[j] * reciprocal_logsum; } @@ -1415,13 +2178,52 @@ struct FlashAttn2T { Impl impl_; }; -} // namespace mobi_attn +class WorkspaceManager { +public: + // 构造函数:初始化所有指针和大小 + WorkspaceManager() : + workspace_{}, current_sizes_{} { + } -// ======================================== -// 用户接口函数 -// ======================================== + // 析构函数:在线程退出时自动释放所有内存,防止内存泄漏 + ~WorkspaceManager() { + for (int i = 0; i < 7; ++i) { + if (workspace_[i]) { + aligned_free(workspace_[i]); + } + } + } + + // 获取工作空间的核心函数 + void **get_workspace(const size_t *required_sizes) { + for (int i = 0; i < 7; ++i) { + // 如果需要的尺寸大于当前分配的尺寸,则重新分配 + if (required_sizes[i] > current_sizes_[i]) { + // 释放旧的(如果存在) + if (workspace_[i]) { + aligned_free(workspace_[i]); + } + // 分配新的 + aligned_alloc(&workspace_[i], required_sizes[i], 32); + // 更新当前尺寸 + current_sizes_[i] = required_sizes[i]; + } + } + return workspace_; + } + +private: + // 禁止拷贝和赋值,确保每个实例的唯一性 + WorkspaceManager(const WorkspaceManager &) = delete; + WorkspaceManager &operator=(const WorkspaceManager &) = delete; + + void *workspace_[7]; + size_t current_sizes_[7]; +}; + +} // namespace mobi_attn -// 【修改】用户接口函数,增加FP16输入分支 +/* void flash_attention_2_forward( const void *Q, const void *K, const void *V, void *O, int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, @@ -1439,17 +2241,17 @@ void flash_attention_2_forward( // 分配对齐的工作空间 void *workspace[7]; - mobi_attn::x86_align_alloc(&workspace[0], acc_o_size, 32); - mobi_attn::x86_align_alloc(&workspace[1], acc_s_size, 32); - mobi_attn::x86_align_alloc(&workspace[2], logsum_size, 32); - mobi_attn::x86_align_alloc(&workspace[3], scoremax_size, 32); - mobi_attn::x86_align_alloc(&workspace[4], scoremax_prev_size, 32); - mobi_attn::x86_align_alloc(&workspace[5], score_scale_size, 32); - mobi_attn::x86_align_alloc(&workspace[6], score_sum_size, 32); + mobi_attn::aligned_alloc(&workspace[0], acc_o_size, 32); + mobi_attn::aligned_alloc(&workspace[1], acc_s_size, 32); + mobi_attn::aligned_alloc(&workspace[2], logsum_size, 32); + mobi_attn::aligned_alloc(&workspace[3], scoremax_size, 32); + mobi_attn::aligned_alloc(&workspace[4], scoremax_prev_size, 32); + mobi_attn::aligned_alloc(&workspace[5], score_scale_size, 32); + mobi_attn::aligned_alloc(&workspace[6], score_sum_size, 32); if (use_fp32) { // 使用纯FP32实现 - mobi_attn::FlashAttn2T op; + mobi_attn::FlashAttn2T op; op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); op.init_workspace( @@ -1463,7 +2265,7 @@ void flash_attention_2_forward( batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); } else { // 使用FP16输入,FP32输出的实现 - mobi_attn::FlashAttn2T op; + mobi_attn::FlashAttn2T op; op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); op.init_workspace( @@ -1477,1712 +2279,67 @@ void flash_attention_2_forward( batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); } - // 释放工作空间 for (void *ptr : workspace) { - if (ptr) mobi_attn::x86_align_free(ptr); + if (ptr) mobi_attn::aligned_free(ptr); } } -#elif __ARM_NEON -#include -// 核心修改:将 x86 的 immintrin.h 替换为 ARM 的 arm_neon.h -#include -#include -#include -#include -#include -#include -#include "Types.hpp" -#include "VecDot.hpp" - -namespace mobi_attn { - -// ======================================== -// 数学函数和工具 (NEON版本) -// ======================================== -#define NEG_INF std::numeric_limits::lowest() - -// NEON版本:水平最大值 (Horizontal max of a float32x4_t vector) -// float32x4_t 中包含4个float, vmaxvq_f32可以直接找到这4个float中的最大值 -inline float _vmaxvq_f32_hmax(float32x4_t x) { - return vmaxvq_f32(x); -} - -// NEON版本:水平求和 (Horizontal sum of a float32x4_t vector) -// float32x4_t 中包含4个float, vaddvq_f32可以直接将这4个float相加 -inline float _vaddvq_f32_hadd(float32x4_t x) { - return vaddvq_f32(x); -} +*/ +// 文件位置: FlashAttention2.hpp +// 这是文件最末尾的函数 -// ======================================== -// 高性能NEON数学函数 (新增) -// ======================================== - -// 基于多项式逼近的快速exp实现 (NEON版本) -inline float32x4_t vexpq_fast_f32(float32x4_t x) { - // 定义常量 - const float32x4_t c0 = vdupq_n_f32(1.0f); - const float32x4_t c1 = vdupq_n_f32(0.0416598990559578f); - const float32x4_t c2 = vdupq_n_f32(0.166664719581604f); - const float32x4_t c3 = vdupq_n_f32(0.5000005960464478f); - const float32x4_t log2e = vdupq_n_f32(1.4426950408889634f); - const float32x4_t ln2_hi = vdupq_n_f32(0.693145751953125f); - const float32x4_t ln2_lo = vdupq_n_f32(1.428606765330187e-06f); - const int32x4_t M_126 = vdupq_n_s32(126); - - // 计算 y = x * log2(e) - float32x4_t y = vmulq_f32(x, log2e); - - // 对y取整, n = round(y) - int32x4_t n = vcvtaq_s32_f32(y); - - // 计算 z = x - n * ln2 - float32x4_t n_f = vcvtq_f32_s32(n); - float32x4_t z = vmlsq_f32(x, n_f, ln2_hi); - z = vmlsq_f32(z, n_f, ln2_lo); - - // 多项式逼近 exp(z) ~= 1 + z + z^2/2! + ... - float32x4_t poly = c1; - poly = vmlaq_f32(c2, poly, z); - poly = vmlaq_f32(c3, poly, z); - poly = vmlaq_f32(c0, poly, z); - poly = vmlaq_f32(poly, vmulq_f32(z, z), poly); - - // 组合结果: poly * 2^n - int32x4_t m = vaddq_s32(n, M_126); - m = vshlq_n_s32(m, 23); - - return vmulq_f32(poly, vreinterpretq_f32_s32(m)); -} - -// ======================================== -// 内存对齐分配函数 (重命名以去除x86特定性) -// ======================================== -// 使用 posix_memalign 进行分配,此函数在支持POSIX的系统(如Linux)上是通用的 -void aligned_alloc(void **ptr, size_t required_bytes, size_t align) { - // posix_memalign 要求 alignment 必须是 void* 大小的整数倍,并且是 2 的幂 - if (align % sizeof(void *) != 0 || (align & (align - 1)) != 0) { - *ptr = nullptr; - return; - } +// 【替换此函数】 +void flash_attention_2_forward( + const void *Q, const void *K, const void *V, void *O, + int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, + bool causal_mask, bool use_fp32, int32_t threads, int32_t br, int32_t bc, + int32_t q_head, int32_t kv_head, bool high_precision_exp) { + thread_local mobi_attn::WorkspaceManager manager; - // posix_memalign 返回 0 表示成功,否则返回错误码 - if (posix_memalign(ptr, align, required_bytes) != 0) { - *ptr = nullptr; - } -} + // 计算当前调用所需的各个工作空间大小 + const size_t acc_o_size = threads * br * dim_size * sizeof(float); + const size_t acc_s_size = threads * br * bc * sizeof(float); + const size_t logsum_size = threads * br * sizeof(float); + const size_t scoremax_size = threads * br * sizeof(float); + const size_t scoremax_prev_size = threads * br * sizeof(float); + const size_t score_scale_size = threads * br * sizeof(float); + const size_t score_sum_size = threads * br * sizeof(float); -// 直接使用标准 free 进行释放 -void aligned_free(void *ptr) { - free(ptr); -} + const size_t required_sizes[7] = { + acc_o_size, acc_s_size, logsum_size, scoremax_size, + scoremax_prev_size, score_scale_size, score_sum_size}; -// ======================================== -// FlashAttention2 核心实现 (FP32版本, NEON) -// ======================================== -struct NEON_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { - using dtype_q_in_t = float; - using dtype_kv_in_t = dtype_q_in_t; - using dtype_out_t = dtype_q_in_t; - using dtype_t = dtype_out_t; - using acc_dtype_t = float; + // 【修改2】通过 manager 获取工作空间指针 + // manager 会自动处理内存的复用和按需重新分配 + void **workspace = manager.get_workspace(required_sizes); - // 添加配置参数作为成员变量 - int32_t Br; - int32_t Bc; - int32_t Q_Head; - int32_t KV_Head; - int32_t threads; - bool high_precision; + if (use_fp32) { + // 使用纯FP32实现 + mobi_attn::FlashAttn2T op; + op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); - // 配置参数初始化 - void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_, bool high_precision_) { - Br = Br_; - Bc = Bc_; - Q_Head = Q_Head_; - KV_Head = KV_Head_; - threads = threads_; - high_precision = high_precision_; - } + op.init_workspace( + static_cast(workspace[0]), static_cast(workspace[1]), + static_cast(workspace[2]), static_cast(workspace[3]), + static_cast(workspace[4]), static_cast(workspace[5]), + static_cast(workspace[6])); - // 初始化工作空间指针 - void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, - acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, - acc_dtype_t *score_scale, acc_dtype_t *score_sum) { - acc_o_ = acc_o; - acc_s_ = acc_s; - logsum_ = logsum; - scoremax_ = scoremax; - scoremax_prev_ = scoremax_prev; - score_scale_ = score_scale; - score_sum_ = score_sum; - } + op(static_cast(Q), static_cast(K), static_cast(V), + static_cast(O), + batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); + } else { + // 使用FP16输入,FP32输出的实现 + mobi_attn::FlashAttn2T op; + op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); - // fa2 主函数,根据Q的序列长度分发到 prefill/append 或 decode 模式 - void fa2(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, - const dtype_t *__restrict__ V, dtype_t *__restrict__ O, const int32_t batch_size, - const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, - const int32_t dim_size, bool causal_mask = true) { - assert(Br == Bc); - // NEON 一次处理 4 个 float - assert(dim_size % 4 == 0); - // 确保Q头是KV头的整数倍,这是GQA/MHA的有效性要求 - assert(Q_Head % KV_Head == 0); - assert(head_size % threads == 0); + op.init_workspace( + static_cast(workspace[0]), static_cast(workspace[1]), + static_cast(workspace[2]), static_cast(workspace[3]), + static_cast(workspace[4]), static_cast(workspace[5]), + static_cast(workspace[6])); - if (seq_size_q != 1) { - __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, - causal_mask); - } else { - __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, - causal_mask); - } - } - - // ========================================================================================= - // 以下是 NEON_FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL 结构体内部的私有函数实现 - // 承接第一部分的代码 - // ========================================================================================= - -private: - // 核心计算函数 (prefill/append 模式, 适用于 seq_size_q > 1) - inline void __fa2_prefill_append(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, - const dtype_t *__restrict__ V, dtype_t *__restrict__ O, - const int32_t batch_size, const int32_t head_size, // head_size 就是 Q_Head - const int32_t seq_size_q, const int32_t seq_size_k, - const int32_t dim_size, bool causal_mask = true) { - // Tr, Tc 分别是 Q 和 K/V 在序列长度维度上被切分成的块数 - const int32_t Tr = seq_size_q / Br; - const int32_t Tr_left = seq_size_q % Br; - const int32_t Tc = seq_size_k / Bc; - const int32_t Tc_left = seq_size_k % Bc; - - const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); - - // 计算Q头与KV头的分组对应关系 (GQA) - const int32_t kv_group_size = Q_Head / KV_Head; - - for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { -#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) - for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { // h_idx 是当前Q头的索引 - const int32_t thread_id = omp_get_thread_num(); - const int32_t this_thread_head = h_idx; - - // 计算当前Q头 (h_idx) 对应的KV头索引 - const int32_t this_thread_kv_head = this_thread_head / kv_group_size; - - // --- 主循环 (处理完整的块) --- - for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { - // 初始化该线程的临时工作空间 - init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, - acc_o_ + thread_id * Br * dim_size, dim_size); - - for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { - // Q 的指针计算,它有 Q_Head (==head_size) 个头 - const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; - - // K 和 V 的指针计算,必须使用 KV_Head 和映射后的 this_thread_kv_head - const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - - // Step 1: Q * K^T - mma0(tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - // Step 2: Softmax - softmax(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - // Step 3: Rescale O - rescale(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - // Step 4: P * V - mma1(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - } - // --- 处理 K/V 序列的剩余部分 (Tc_left) --- - if (Tc_left) { - const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; - const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0_pa_n_fixed(Br, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - softmax_pa_n_fixed(Br, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - rescale_pa_n_fixed(Br, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - mma1_pa_n_fixed(Br, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - } - // Step 5: 将最终结果缩放并存回输出 O - scale_and_store(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); - } - // --- 处理 Q 序列的剩余部分 (Tr_left) --- - if (Tr_left) { - init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); - for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { - const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; - const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0_pa_n_fixed(Tr_left, Bc, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); - softmax_pa_n_fixed(Tr_left, Bc, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); - rescale_pa_n_fixed(Tr_left, Bc, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); - mma1_pa_n_fixed(Tr_left, Bc, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); - } - if (Tc_left) { - const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; - const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0_pa_n_fixed(Tr_left, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); - softmax_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, Tc, seq_size_q, seq_size_k, causal_mask); - rescale_pa_n_fixed(Tr_left, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); - mma1_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); - } - scale_and_store_pa_n_fixed(Tr_left, acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size, Tr, head_size, dim_size); - } - } - } - } - inline void __fa2_decode(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, - const dtype_t *__restrict__ V, dtype_t *__restrict__ O, - const int32_t batch_size, const int32_t head_size, - const int32_t seq_size_q, const int32_t seq_size_k, - const int32_t dim_size, bool causal_mask = true) { - // 在 decode 模式下, Q 的序列长度固定为 1, 因此 Tr = 1, Br = 1 - const int32_t Tr = 1; - const int32_t Tc = seq_size_k / Bc; - const int32_t Tc_left = seq_size_k % Bc; - - const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); - const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; - - for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { -#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) - for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { - const int32_t thread_id = omp_get_thread_num(); - const int32_t this_thread_head = h_idx; - const int32_t this_thread_kv_head = this_thread_head / kv_group_size; - - const int t_r_idx = 0; - - init_temp_d(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); - - for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { - const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; - const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - - mma0_d(tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - softmax_d(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - rescale_d(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - mma1_d(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - } - - if (Tc_left) { - const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; - const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0_d_n_fixed(Tc_left, tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - softmax_d_n_fixed(Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - rescale_d_n_fixed(Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - mma1_d_n_fixed(Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - } - - scale_and_store_d(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); - } - } - } - - // 初始化临时工作区 (NEON 版本) - inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { - float32x4_t zero_vec = vdupq_n_f32(0.0f); - float32x4_t neg_inf_vec = vdupq_n_f32(NEG_INF); - - int i = 0; - // NEON 一次处理4个 - for (; i <= Br - 4; i += 4) { - vst1q_f32(logsum + i, zero_vec); - vst1q_f32(scoremax + i, neg_inf_vec); - } - // 处理剩余的元素(如果Br不是4的倍数) - for (; i < Br; ++i) { - logsum[i] = 0.0f; - scoremax[i] = NEG_INF; - } - - // acc_o 的初始化, 调用者保证了 dim_size % 4 == 0 - for (int j = 0; j < Br * dim_size; j += 4) { - vst1q_f32(acc_o + j, zero_vec); - } - } - - // Q * K^T 计算 (NEON 版本) - inline void mma0(const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, - acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, - const int32_t q_stride_size, const int32_t kv_stride_size, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_r_end = global_r_start + Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - - if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } - - for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; - for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; - - float32x4_t sum_vec = vdupq_n_f32(0.0f); - int i = 0; - // 为了性能,可以一次处理8个或更多元素,这里保持与AVX版本类似的逻辑,但向量宽度减半 - for (; i <= dim_size - 8; i += 8) { - // 预取数据到缓存 - __builtin_prefetch(q_block_line + i + 64); - __builtin_prefetch(k_block_line + i + 64); - // 加载两组4个float数据 - float32x4_t q_vec0 = vld1q_f32(q_block_line + i); - float32x4_t k_vec0 = vld1q_f32(k_block_line + i); - float32x4_t q_vec1 = vld1q_f32(q_block_line + i + 4); - float32x4_t k_vec1 = vld1q_f32(k_block_line + i + 4); - // 融合乘加 - sum_vec = vfmaq_f32(sum_vec, q_vec0, k_vec0); - sum_vec = vfmaq_f32(sum_vec, q_vec1, k_vec1); - } - // 处理 dim_size % 8 剩下的部分 - for (; i <= dim_size - 4; i += 4) { - float32x4_t q_vec = vld1q_f32(q_block_line + i); - float32x4_t k_vec = vld1q_f32(k_block_line + i); - sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); - } - - acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); - // 处理最后不足4个的元素 - for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } - - acc_s[b_r_idx * Bc + b_c_idx] = total; - } - } - // 应用因果掩码 - if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { - for (int i = 0; i < Br; ++i) { - for (int j = 0; j < Bc; ++j) { - if (j > i) { acc_s[i * Bc + j] = NEG_INF; } - } - } - } - } - - // Softmax (NEON 版本) - inline void softmax(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, - acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, - const float scale, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - - memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); - - // 1. 找到每行的最大值 m_i - for (int br = 0; br < Br; ++br) { - float32x4_t max_vec = vdupq_n_f32(scoremax[br]); - acc_dtype_t *row = acc_s + br * Bc; - int bc = 0; - for (; bc <= Bc - 4; bc += 4) { - max_vec = vmaxq_f32(max_vec, vld1q_f32(row + bc)); - } - float max_val = _vmaxvq_f32_hmax(max_vec); - for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } - scoremax[br] = max_val; - } - - // 2. 计算缩放因子 s_i = exp((m_i_prev - m_i) * scale) - for (int br = 0; br < Br; ++br) { - score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); - } - - // 3. 计算 P_ij = exp((S_ij - m_i) * scale) 和 l_i = sum(P_ij) - for (int br = 0; br < Br; ++br) { - const float sm = scoremax[br]; - acc_dtype_t *row = acc_s + br * Bc; - float sum = 0.0f; - // 这里可以进一步用NEON优化expf, 但expf的SIMD实现复杂,暂用标量 - for (int bc = 0; bc < Bc; ++bc) { - float val = expf((row[bc] - sm) * scale); - row[bc] = val; // 更新 acc_s 为 P_ij - sum += val; - } - score_sum[br] = sum; - } - - // 4. 更新 logsum: l_i_new = l_i_prev * s_i + l_i - for (int br = 0; br < Br; ++br) { - logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; - } - } - - // 重缩放累加的输出 O (NEON 版本) - inline void rescale(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, - const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - - for (int i = 0; i < Br; ++i) { - float32x4_t scale_v = vdupq_n_f32(score_scale[i]); - float *row_ptr = acc_o + i * dim_size; - for (int j = 0; j < dim_size; j += 4) { - float32x4_t acc = vld1q_f32(row_ptr + j); - acc = vmulq_f32(acc, scale_v); - vst1q_f32(row_ptr + j, acc); - } - } - } - - // P * V 计算 (NEON 版本) - inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, - acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, - const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - - const int32_t v_stride_size = kv_head_size * dim_size; - - for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); - for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); - const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - float32x4_t v_vec = vld1q_f32(v_ptr); - acc = vfmaq_f32(acc, w_vec, v_vec); - } - vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); - } - } - } - - // 缩放并存储最终结果 (NEON 版本) - inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, - const acc_dtype_t *__restrict__ logsum, - dtype_t *__restrict__ o_block, const int32_t t_r_idx, - const int32_t head_size, const int32_t dim_size) { - for (int i = 0; i < Br; ++i) { - dtype_t *o_block_line = o_block + i * head_size * dim_size; - float reciprocal_logsum = 1.0f / logsum[i]; - float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); - int j = 0; - for (; j <= dim_size - 4; j += 4) { - float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); - float32x4_t result_vec = vmulq_f32(vec_acc_o, reciprocal_logsum_vec); - vst1q_f32(o_block_line + j, result_vec); - } - for (; j < dim_size; ++j) { - o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; - } - } - } - - // --- 处理剩余块的 N-fixed 函数 (NEON 版本) --- - inline void mma0_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, - const dtype_t *__restrict__ q_block, - const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, - const int32_t dim_size, const int32_t q_stride_size, const int32_t kv_stride_size, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, - bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_r_end = global_r_start + Br_n_fixed; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } - - for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { - const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; - for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; - float32x4_t sum_vec = vdupq_n_f32(0.0f); - int i = 0; - for (; i <= dim_size - 4; i += 4) { - sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), vld1q_f32(k_block_line + i)); - } - acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); - for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } - acc_s[b_r_idx * Bc + b_c_idx] = total; - } - } - - if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { - for (int i = 0; i < Br_n_fixed; ++i) { - for (int j = 0; j < Bc_n_fixed; ++j) { - if (j > i) { acc_s[i * Bc + j] = NEG_INF; } - } - } - } - } - - // (这里的逻辑主要是标量,和AVX版本基本一致) - inline void softmax_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, - acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, - acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, - acc_dtype_t *score_sum, acc_dtype_t *logsum, - const float scale, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; - - memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); - - for (int br = 0; br < Br_n_fixed; ++br) { - acc_dtype_t *row = acc_s + br * Bc; - float max_val = NEG_INF; - for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, row[bc]); - scoremax[br] = fmaxf(max_val, scoremax[br]); - } - for (int br = 0; br < Br_n_fixed; ++br) { - score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); - } - for (int br = 0; br < Br_n_fixed; ++br) { - acc_dtype_t *row = acc_s + br * Bc; - float current_sum = 0.0f; - for (int bc = 0; bc < Bc_n_fixed; ++bc) { - float val = expf((row[bc] - scoremax[br]) * scale); - row[bc] = val; - current_sum += val; - } - score_sum[br] = current_sum; - } - for (int br = 0; br < Br_n_fixed; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } - } - - inline void rescale_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, - acc_dtype_t *__restrict__ acc_o, - acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, - bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; - - for (int i = 0; i < Br_n_fixed; ++i) { - float *row_ptr = acc_o + i * dim_size; - float32x4_t scale_v = vdupq_n_f32(score_scale[i]); - for (int j = 0; j < dim_size; j += 4) { - vst1q_f32(row_ptr + j, vmulq_f32(vld1q_f32(row_ptr + j), scale_v)); - } - } - } - - inline void mma1_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, - const acc_dtype_t *__restrict__ w_block, - const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, - const int32_t kv_head_size, const int32_t dim_size, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, - bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; - - const int32_t v_stride_size = kv_head_size * dim_size; - - for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { - for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); - for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); - const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - acc = vfmaq_f32(acc, w_vec, vld1q_f32(v_ptr)); - } - vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); - } - } - } - - inline void scale_and_store_pa_n_fixed(const int32_t Br_n_fixed, - const acc_dtype_t *__restrict__ acc_o, - const acc_dtype_t *__restrict__ logsum, - dtype_t *__restrict__ o_block, const int32_t t_r_idx, - const int32_t head_size, const int32_t dim_size) { - for (int i = 0; i < Br_n_fixed; ++i) { - dtype_t *o_block_line = o_block + i * head_size * dim_size; - float reciprocal_logsum = 1.0f / logsum[i]; - float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); - int j = 0; - for (; j <= dim_size - 4; j += 4) { - float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); - vst1q_f32(o_block_line + j, vmulq_f32(vec_acc_o, reciprocal_logsum_vec)); - } - for (; j < dim_size; ++j) { - o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; - } - } - } - - // --- Decode 模式的辅助函数 (NEON 版本) --- - - inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, - const int32_t dim_size) { - logsum[0] = 0.0f; - scoremax[0] = NEG_INF; - float32x4_t zero_vec = vdupq_n_f32(0.0f); - // Br 在 decode 模式下为 1 - for (int i = 0; i < 1 * dim_size; i += 4) { - vst1q_f32(acc_o + i, zero_vec); - } - } - - inline void mma0_d(const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, - acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, - const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const dtype_t *q_block_line = q_block; // q 只有一个向量 - for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; - float32x4_t sum_vec = vdupq_n_f32(0.0f); - int i = 0; - for (; i <= dim_size - 4; i += 4) { - sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), vld1q_f32(k_block_line + i)); - } - acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); - for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } - acc_s[b_c_idx] = total; - } - } - - inline void softmax_d(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, - acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, - acc_dtype_t *score_sum, acc_dtype_t *logsum, - const float scale, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - scoremax_prev[0] = scoremax[0]; - - float max_val = scoremax[0]; - for (int bc = 0; bc < Bc; ++bc) { - max_val = fmaxf(max_val, acc_s[bc]); - } - scoremax[0] = max_val; - - score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); - - float current_sum = 0.0f; - for (int bc = 0; bc < Bc; ++bc) { - float val = expf((acc_s[bc] - scoremax[0]) * scale); - acc_s[bc] = val; - current_sum += val; - } - score_sum[0] = current_sum; - - logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; - } - - inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, - const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - float32x4_t scale_v = vdupq_n_f32(score_scale[0]); - for (int j = 0; j < dim_size; j += 4) { - float32x4_t acc = vld1q_f32(acc_o + j); - acc = vmulq_f32(acc, scale_v); - vst1q_f32(acc_o + j, acc); - } - } - - inline void mma1_d(const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, - acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, - const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t v_stride_size = kv_head_size * dim_size; - for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + d_base); - for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); - const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - acc = vfmaq_f32(acc, w_vec, vld1q_f32(v_ptr)); - } - vst1q_f32(acc_o + d_base, acc); - } - } - - inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, - const acc_dtype_t *__restrict__ logsum, - dtype_t *__restrict__ o_block, const int32_t t_r_idx, - const int32_t head_size, const int32_t dim_size) { - float reciprocal_logsum = 1.0f / logsum[0]; - float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); - int j = 0; - for (; j <= dim_size - 4; j += 4) { - vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); - } - for (; j < dim_size; ++j) { - o_block[j] = acc_o[j] * reciprocal_logsum; - } - } - - // --- Decode N-fixed 函数 (NEON 版本, 逻辑多为标量) --- - inline void mma0_d_n_fixed(const int32_t Bc_n_fixed, const dtype_t *__restrict__ q_block, - const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, - const int32_t dim_size, const int32_t kv_stride_size, - const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const dtype_t *q_block_line = q_block; - for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; - float total = 0.0f; - for (int i = 0; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } - acc_s[b_c_idx] = total; - } - } - - inline void softmax_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_s, - acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, - acc_dtype_t *score_scale, acc_dtype_t *score_sum, - acc_dtype_t *logsum, - const float scale, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - scoremax_prev[0] = scoremax[0]; - float max_val = scoremax[0]; - for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, acc_s[bc]); - scoremax[0] = max_val; - - score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); - - float current_sum = 0.0f; - for (int bc = 0; bc < Bc_n_fixed; ++bc) { - float val = expf((acc_s[bc] - scoremax[0]) * scale); - acc_s[bc] = val; - current_sum += val; - } - score_sum[0] = current_sum; - - logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; - } - - inline void rescale_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_o, - acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, - bool causal_mask) { - float scale = score_scale[0]; - for (int j = 0; j < dim_size; ++j) { - acc_o[j] *= scale; - } - } - - inline void mma1_d_n_fixed(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, - const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, - const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, - const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const int32_t v_stride_size = kv_head_size * dim_size; - for (int d_base = 0; d_base < dim_size; ++d_base) { - float acc = acc_o[d_base]; - for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - acc += w_block[b_c_idx] * v_block[b_c_idx * v_stride_size + d_base]; - } - acc_o[d_base] = acc; - } - } - -private: - // 私有成员,用于存储工作空间的指针 - acc_dtype_t *acc_o_; - acc_dtype_t *acc_s_; - acc_dtype_t *logsum_; - acc_dtype_t *scoremax_; - acc_dtype_t *scoremax_prev_; - acc_dtype_t *score_scale_; - acc_dtype_t *score_sum_; -}; -// ======================================== -// FlashAttention2 核心实现 (Q FP32/KV FP16 输入, FP32 输出, NEON 版本) -// 【注意:本版本为完整、未省略代码的版本】 -// ======================================== -struct NEON_FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { - // 定义不同的输入数据类型 - using dtype_q_in_t = float; - using dtype_kv_in_t = mllm_fp16_t; // K和V是FP16 - using dtype_out_t = float; - using acc_dtype_t = float; - - // 配置参数 - int32_t Br, Bc, Q_Head, KV_Head, threads; - bool high_precision; - - void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_, bool high_precision_) { - Br = Br_; - Bc = Bc_; - Q_Head = Q_Head_; - KV_Head = KV_Head_; - threads = threads_; - high_precision = high_precision_; - } - - void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, - acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, - acc_dtype_t *score_scale, acc_dtype_t *score_sum) { - acc_o_ = acc_o; - acc_s_ = acc_s; - logsum_ = logsum; - scoremax_ = scoremax; - scoremax_prev_ = scoremax_prev; - score_scale_ = score_scale; - score_sum_ = score_sum; - } - - // 主函数 fa2, 注意 K 和 V 的类型是 dtype_kv_in_t - void fa2(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, - const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, const int32_t batch_size, - const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, - const int32_t dim_size, bool causal_mask = true) { - assert(Br == Bc); - assert(dim_size % 4 == 0); - assert(Q_Head % KV_Head == 0); - assert(head_size % threads == 0); - - if (seq_size_q != 1) { - __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); - } else { - __fa2_decode(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); - } - } - -private: - // 定义一个宏,用于从内存加载4个fp16, 并转换为一个fp32向量 - // 这需要 ARMv8.2-A FP16 指令支持 -#define MLLM_NEON_F32x4_FROM_FP16(addr) vcvt_f32_f16(vld1_f16((const __fp16 *)(addr))) - - // Prefill/Append 主循环 (混合精度) - 完整版 - inline void __fa2_prefill_append(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, - const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, - const int32_t batch_size, const int32_t head_size, - const int32_t seq_size_q, const int32_t seq_size_k, - const int32_t dim_size, bool causal_mask = true) { - const int32_t Tr = seq_size_q / Br; - const int32_t Tr_left = seq_size_q % Br; - const int32_t Tc = seq_size_k / Bc; - const int32_t Tc_left = seq_size_k % Bc; - - const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); - const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; - - for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { -#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) - for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { - const int32_t thread_id = omp_get_thread_num(); - const int32_t this_thread_head = h_idx; - const int32_t this_thread_kv_head = this_thread_head / kv_group_size; - - // --- 主循环 (Tr) --- - for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { - init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); - for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { - const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; - const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0(tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - softmax(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - rescale(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - mma1(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - } - if (Tc_left) { - const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; - const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0_pa_n_fixed(Br, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - softmax_pa_n_fixed(Br, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - rescale_pa_n_fixed(Br, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - mma1_pa_n_fixed(Br, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - } - scale_and_store(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); - } - // --- 处理 Q 序列的剩余部分 (Tr_left) - 完整版 --- - if (Tr_left) { - init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); - for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { - const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; - const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0_pa_n_fixed(Tr_left, Bc, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); - softmax_pa_n_fixed(Tr_left, Bc, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); - rescale_pa_n_fixed(Tr_left, Bc, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); - mma1_pa_n_fixed(Tr_left, Bc, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, t_c_idx, seq_size_q, seq_size_k, causal_mask); - } - if (Tc_left) { - const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size; - const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0_pa_n_fixed(Tr_left, Tc_left, tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); - softmax_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, Tr, Tc, seq_size_q, seq_size_k, causal_mask); - rescale_pa_n_fixed(Tr_left, Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); - mma1_pa_n_fixed(Tr_left, Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, Tr, Tc, seq_size_q, seq_size_k, causal_mask); - } - scale_and_store_pa_n_fixed(Tr_left, acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + Tr * Br * head_size * dim_size + this_thread_head * dim_size, Tr, head_size, dim_size); - } - } - } - } - - // Decode 主循环 (混合精度) - 完整版 - inline void __fa2_decode(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, - const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, - const int32_t batch_size, const int32_t head_size, - const int32_t seq_size_q, const int32_t seq_size_k, - const int32_t dim_size, bool causal_mask = true) { - const int32_t Tr = 1; - const int32_t Tc = seq_size_k / Bc; - const int32_t Tc_left = seq_size_k % Bc; - - const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); - const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; - - for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { -#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) - for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { - const int32_t thread_id = omp_get_thread_num(); - const int32_t this_thread_head = h_idx; - const int32_t this_thread_kv_head = this_thread_head / kv_group_size; - - const int t_r_idx = 0; - init_temp_d(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); - for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { - const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; - const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0_d(tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - softmax_d(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - rescale_d(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - mma1_d(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - } - if (Tc_left) { - const dtype_q_in_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; - const dtype_kv_in_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + Tc * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; - acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; - acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - mma0_d_n_fixed(Tc_left, tile_q, tile_k, tile_acc_s, dim_size, KV_Head * dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - softmax_d_n_fixed(Tc_left, tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - rescale_d_n_fixed(Tc_left, acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - mma1_d_n_fixed(Tc_left, tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, Tc, seq_size_q, seq_size_k, causal_mask); - } - scale_and_store_d(acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size, t_r_idx, head_size, dim_size); - } - } - } - - // --- 完整版辅助函数 --- - - // (与FP32版本相同) - inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { - float32x4_t zero_vec = vdupq_n_f32(0.0f); - float32x4_t neg_inf_vec = vdupq_n_f32(NEG_INF); - int i = 0; - for (; i <= Br - 4; i += 4) { - vst1q_f32(logsum + i, zero_vec); - vst1q_f32(scoremax + i, neg_inf_vec); - } - for (; i < Br; ++i) { - logsum[i] = 0.0f; - scoremax[i] = NEG_INF; - } - for (int j = 0; j < Br * dim_size; j += 4) { - vst1q_f32(acc_o + j, zero_vec); - } - } - - /* - // 输入Q为FP32,但在函数内动态转为FP16,以使用最高效的 vfmlalq_f16 指令进行计算 - inline void mma0(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, - acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, - const int32_t q_stride_size, const int32_t kv_stride_size, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - // 因果掩码的前置检查 - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_r_end = global_r_start + Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - - if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } - - // 遍历Br x Bc的块 - for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - const dtype_q_in_t *q_block_line = q_block + b_r_idx * q_stride_size; - for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; - - // 使用多个FP32累加器,借鉴自您提供的参考文件 - float32x4_t sum0 = vdupq_n_f32(0.0f); - float32x4_t sum1 = vdupq_n_f32(0.0f); - - int i = 0; - // 主循环,一次处理16个元素 (两个float16x8_t向量) - for (; i <= dim_size - 16; i += 16) { - __builtin_prefetch(q_block_line + i + 64); - __builtin_prefetch(k_block_line + i + 64); - - // 1. 加载16个 FP32 的 Q - float32x4_t q_f32_0 = vld1q_f32(q_block_line + i); - float32x4_t q_f32_1 = vld1q_f32(q_block_line + i + 4); - float32x4_t q_f32_2 = vld1q_f32(q_block_line + i + 8); - float32x4_t q_f32_3 = vld1q_f32(q_block_line + i + 12); - - // 2. 【核心修改】将加载的 FP32 Q 动态转换为 FP16 - float16x8_t q_f16_0 = vcombine_f16(vcvt_f16_f32(q_f32_0), vcvt_f16_f32(q_f32_1)); - float16x8_t q_f16_1 = vcombine_f16(vcvt_f16_f32(q_f32_2), vcvt_f16_f32(q_f32_3)); - - // 3. 加载16个 FP16 的 K - float16x8_t k_f16_0 = vld1q_f16((const __fp16 *)k_block_line + i); - float16x8_t k_f16_1 = vld1q_f16((const __fp16 *)k_block_line + i + 8); - - // 4. 【核心修改】直接对两个FP16向量进行乘加,结果累加到FP32寄存器 - sum0 = vfmlalq_low_f16(sum0, q_f16_0, k_f16_0); - sum0 = vfmlalq_high_f16(sum0, q_f16_0, k_f16_0); - sum1 = vfmlalq_low_f16(sum1, q_f16_1, k_f16_1); - sum1 = vfmlalq_high_f16(sum1, q_f16_1, k_f16_1); - } - - sum0 = vaddq_f32(sum0, sum1); // 合并累加器 - - // 处理剩余的8个元素 - if (i <= dim_size - 8) { - float32x4_t q_f32_0 = vld1q_f32(q_block_line + i); - float32x4_t q_f32_1 = vld1q_f32(q_block_line + i + 4); - float16x8_t q_f16 = vcombine_f16(vcvt_f16_f32(q_f32_0), vcvt_f16_f32(q_f32_1)); - float16x8_t k_f16 = vld1q_f16((const __fp16 *)k_block_line + i); - - sum0 = vfmlalq_low_f16(sum0, q_f16, k_f16); - sum0 = vfmlalq_high_f16(sum0, q_f16, k_f16); - i += 8; - } - - // 水平求和,得到最终的点积结果 - acc_dtype_t total = vaddvq_f32(sum0); - - // 用标量方式处理最后不足8个的元素 - for (; i < dim_size; ++i) { - total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); - } - acc_s[b_r_idx * Bc + b_c_idx] = total; - } - } - - // 应用因果掩码的后处理 - if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { - for (int i = 0; i < Br; ++i) { - for (int j = 0; j < Bc; ++j) { - if (j > i) { acc_s[i * Bc + j] = NEG_INF; } - } - } - } - } - */ - // 【最终正确优化版】 - // 核心思路: - // 1. 在处理每一行Q (b_r_idx) 时,先将其从 FP32 一次性完整转换为 FP16,并存入一个临时缓冲区 q_f16_buf。 - // 2. 在内层循环 (b_c_idx) 中,重复使用这个转换好的 q_f16_buf。 - // 3. 这样就将转换开销均摊,使得内层循环可以零开销地、最高效地执行 FP16 * FP16 -> FP32 的乘加运算。 - inline void mma0(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, - acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, - const int32_t q_stride_size, const int32_t kv_stride_size, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_r_end = global_r_start + Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - - if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } - - __fp16 q_f16_buf[dim_size]; - - - for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - const dtype_q_in_t *q_block_line = q_block + b_r_idx * q_stride_size; - - int k = 0; - for (; k <= dim_size - 8; k += 8) { - float32x4_t q_f32_0 = vld1q_f32(q_block_line + k); - float32x4_t q_f32_1 = vld1q_f32(q_block_line + k + 4); - float16x8_t q_f16 = vcombine_f16(vcvt_f16_f32(q_f32_0), vcvt_f16_f32(q_f32_1)); - vst1q_f16(q_f16_buf + k, q_f16); - } - for (; k < dim_size; ++k) { - q_f16_buf[k] = (__fp16)q_block_line[k]; - } - for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; - float32x4_t sum0 = vdupq_n_f32(0.0f); - float32x4_t sum1 = vdupq_n_f32(0.0f); - int i = 0; - for (; i <= dim_size - 16; i += 16) { - float16x8_t q_f16_0 = vld1q_f16(q_f16_buf + i); - float16x8_t q_f16_1 = vld1q_f16(q_f16_buf + i + 8); - float16x8_t k_f16_0 = vld1q_f16((const __fp16 *)k_block_line + i); - float16x8_t k_f16_1 = vld1q_f16((const __fp16 *)k_block_line + i + 8); - sum0 = vfmlalq_low_f16(sum0, q_f16_0, k_f16_0); - sum0 = vfmlalq_high_f16(sum0, q_f16_0, k_f16_0); - sum1 = vfmlalq_low_f16(sum1, q_f16_1, k_f16_1); - sum1 = vfmlalq_high_f16(sum1, q_f16_1, k_f16_1); - } - sum0 = vaddq_f32(sum0, sum1); - if (i <= dim_size - 8) { - float16x8_t q_f16 = vld1q_f16(q_f16_buf + i); - float16x8_t k_f16 = vld1q_f16((const __fp16 *)k_block_line + i); - sum0 = vfmlalq_low_f16(sum0, q_f16, k_f16); - sum0 = vfmlalq_high_f16(sum0, q_f16, k_f16); - i += 8; - } - acc_dtype_t total = vaddvq_f32(sum0); - for (; i < dim_size; ++i) { - total += (float)q_f16_buf[i] * (float)k_block_line[i]; - } - acc_s[b_r_idx * Bc + b_c_idx] = total; - } - } - if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { - for (int i = 0; i < Br; ++i) { - for (int j = 0; j < Bc; ++j) { - if (j > i) { acc_s[i * Bc + j] = NEG_INF; } - } - } - } - } - // (与FP32版本相同) - inline void softmax(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, - acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, - const float scale, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); - for (int br = 0; br < Br; ++br) { - float32x4_t max_vec = vdupq_n_f32(scoremax[br]); - acc_dtype_t *row = acc_s + br * Bc; - int bc = 0; - for (; bc <= Bc - 4; bc += 4) { max_vec = vmaxq_f32(max_vec, vld1q_f32(row + bc)); } - float max_val = _vmaxvq_f32_hmax(max_vec); - for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } - scoremax[br] = max_val; - } - for (int br = 0; br < Br; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } - for (int br = 0; br < Br; ++br) { - const float sm = scoremax[br]; - acc_dtype_t *row = acc_s + br * Bc; - float sum = 0.0f; - for (int bc = 0; bc < Bc; ++bc) { - float val = expf((row[bc] - sm) * scale); - row[bc] = val; - sum += val; - } - score_sum[br] = sum; - } - for (int br = 0; br < Br; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } - } - - // (与FP32版本相同) - inline void rescale(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, - const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - for (int i = 0; i < Br; ++i) { - float32x4_t scale_v = vdupq_n_f32(score_scale[i]); - float *row_ptr = acc_o + i * dim_size; - for (int j = 0; j < dim_size; j += 4) { - float32x4_t acc = vld1q_f32(row_ptr + j); - acc = vmulq_f32(acc, scale_v); - vst1q_f32(row_ptr + j, acc); - } - } - } - - /* - inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, - acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, - const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - const int32_t v_stride_size = kv_head_size * dim_size; - for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); - for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); - const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); - } - vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); - } - } - } - */ - inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, - acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, - const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - - const int32_t v_stride_size = kv_head_size * dim_size; - - // 循环结构 (Br, dim_size, Bc) 对 acc_o 的读写更友好 - for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - for (int d_base = 0; d_base < dim_size; d_base += 4) { - // 加载128位的FP32累加器 - float32x4_t acc_vec = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); - - for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - // 从w_block直接读取FP32的P标量 - const float p_scalar_f32 = w_block[b_r_idx * Bc + b_c_idx]; - // 将FP32标量广播为一个128位向量 - const float32x4_t p_vec_f32 = vdupq_n_f32(p_scalar_f32); - - // 加载FP16的V向量 - const __fp16 *v_ptr = (const __fp16 *)v_block + b_c_idx * v_stride_size + d_base; - const float16x4_t v_vec_f16 = vld1_f16(v_ptr); - - // 将V向量从FP16转换为FP32 - const float32x4_t v_vec_f32 = vcvt_f32_f16(v_vec_f16); - - // 执行FP32的融合乘加 - acc_vec = vfmaq_f32(acc_vec, p_vec_f32, v_vec_f32); - } - // 将结果写回内存 - vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc_vec); - } - } - } - // (与FP32版本相同) - inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, - dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, - const int32_t head_size, const int32_t dim_size) { - for (int i = 0; i < Br; ++i) { - dtype_out_t *o_block_line = o_block + i * head_size * dim_size; - float reciprocal_logsum = 1.0f / logsum[i]; - float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); - int j = 0; - for (; j <= dim_size - 4; j += 4) { - vst1q_f32(o_block_line + j, vmulq_f32(vld1q_f32(acc_o + i * dim_size + j), reciprocal_logsum_vec)); - } - for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } - } - } - - // (混合精度修改版) - inline void mma0_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, - const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, - acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, - const int32_t q_stride_size, const int32_t kv_stride_size, - const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br, global_r_end = global_r_start + Br_n_fixed; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } - for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { - const dtype_q_in_t *q_block_line = q_block + b_r_idx * q_stride_size; - for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; - float32x4_t sum_vec = vdupq_n_f32(0.0f); - int i = 0; - for (; i <= dim_size - 4; i += 4) { - sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), MLLM_NEON_F32x4_FROM_FP16(k_block_line + i)); - } - acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); - for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } - acc_s[b_r_idx * Bc + b_c_idx] = total; - } - } - if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { - for (int i = 0; i < Br_n_fixed; ++i) { - for (int j = 0; j < Bc_n_fixed; ++j) { - if (j > i) { acc_s[i * Bc + j] = NEG_INF; } - } - } - } - } - - // (与FP32版本相同) - inline void softmax_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, - acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, - acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, - acc_dtype_t *score_sum, acc_dtype_t *logsum, - const float scale, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; - memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); - for (int br = 0; br < Br_n_fixed; ++br) { - acc_dtype_t *row = acc_s + br * Bc; - float max_val = NEG_INF; - for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, row[bc]); - scoremax[br] = fmaxf(max_val, scoremax[br]); - } - for (int br = 0; br < Br_n_fixed; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } - for (int br = 0; br < Br_n_fixed; ++br) { - acc_dtype_t *row = acc_s + br * Bc; - float current_sum = 0.0f; - for (int bc = 0; bc < Bc_n_fixed; ++bc) { - float val = expf((row[bc] - scoremax[br]) * scale); - row[bc] = val; - current_sum += val; - } - score_sum[br] = current_sum; - } - for (int br = 0; br < Br_n_fixed; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } - } - - // (与FP32版本相同) - inline void rescale_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, - acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, - const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; - for (int i = 0; i < Br_n_fixed; ++i) { - float *row_ptr = acc_o + i * dim_size; - float32x4_t scale_v = vdupq_n_f32(score_scale[i]); - for (int j = 0; j < dim_size; j += 4) { - vst1q_f32(row_ptr + j, vmulq_f32(vld1q_f32(row_ptr + j), scale_v)); - } - } - } - - // (混合精度修改版) - inline void mma1_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, - const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, - acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, - const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; - const int32_t v_stride_size = kv_head_size * dim_size; - for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { - for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); - for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); - const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); - } - vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); - } - } - } - - // (与FP32版本相同) - inline void scale_and_store_pa_n_fixed(const int32_t Br_n_fixed, const acc_dtype_t *__restrict__ acc_o, - const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, - const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { - for (int i = 0; i < Br_n_fixed; ++i) { - dtype_out_t *o_block_line = o_block + i * head_size * dim_size; - float reciprocal_logsum = 1.0f / logsum[i]; - float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); - int j = 0; - for (; j <= dim_size - 4; j += 4) { - vst1q_f32(o_block_line + j, vmulq_f32(vld1q_f32(acc_o + i * dim_size + j), reciprocal_logsum_vec)); - } - for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } - } - } - - // --- Decode 模式函数 (完整版) --- - - // (与FP32版本相同) - inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { - logsum[0] = 0.0f; - scoremax[0] = NEG_INF; - float32x4_t zero_vec = vdupq_n_f32(0.0f); - for (int i = 0; i < 1 * dim_size; i += 4) { vst1q_f32(acc_o + i, zero_vec); } - } - - // (混合精度修改版) - inline void mma0_d(const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, - acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, - const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - const dtype_q_in_t *q_block_line = q_block; - for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; - float32x4_t sum_vec = vdupq_n_f32(0.0f); - int i = 0; - for (; i <= dim_size - 4; i += 4) { - sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), MLLM_NEON_F32x4_FROM_FP16(k_block_line + i)); - } - acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); - for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } - acc_s[b_c_idx] = total; - } - } - - // (与FP32版本相同) - inline void softmax_d(acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, - acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, - const float scale, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - scoremax_prev[0] = scoremax[0]; - float max_val = scoremax[0]; - for (int bc = 0; bc < Bc; ++bc) max_val = fmaxf(max_val, acc_s[bc]); - scoremax[0] = max_val; - score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); - float current_sum = 0.0f; - for (int bc = 0; bc < Bc; ++bc) { - float val = expf((acc_s[bc] - scoremax[0]) * scale); - acc_s[bc] = val; - current_sum += val; - } - score_sum[0] = current_sum; - logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; - } - - // (与FP32版本相同) - inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, - const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - float32x4_t scale_v = vdupq_n_f32(score_scale[0]); - for (int j = 0; j < dim_size; j += 4) { - vst1q_f32(acc_o + j, vmulq_f32(vld1q_f32(acc_o + j), scale_v)); - } - } - - // (混合精度修改版) - inline void mma1_d(const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, - acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, - const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const int32_t v_stride_size = kv_head_size * dim_size; - for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + d_base); - for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); - const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); - } - vst1q_f32(acc_o + d_base, acc); - } - } - - // (与FP32版本相同) - inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, - dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, - const int32_t head_size, const int32_t dim_size) { - float reciprocal_logsum = 1.0f / logsum[0]; - float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); - int j = 0; - for (; j <= dim_size - 4; j += 4) { - vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); - } - for (; j < dim_size; ++j) { o_block[j] = acc_o[j] * reciprocal_logsum; } - } - - // (混合精度修改版) - inline void mma0_d_n_fixed(const int32_t Bc_n_fixed, const dtype_q_in_t *__restrict__ q_block, - const dtype_kv_in_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, - const int32_t dim_size, const int32_t kv_stride_size, - const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const dtype_q_in_t *q_block_line = q_block; - for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; - float total = 0.0f; - for (int i = 0; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } - acc_s[b_c_idx] = total; - } - } - - // (与FP32版本相同) - inline void softmax_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_s, - acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, - acc_dtype_t *score_scale, acc_dtype_t *score_sum, - acc_dtype_t *logsum, const float scale, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { - scoremax_prev[0] = scoremax[0]; - float max_val = scoremax[0]; - for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, acc_s[bc]); - scoremax[0] = max_val; - score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); - float current_sum = 0.0f; - for (int bc = 0; bc < Bc_n_fixed; ++bc) { - float val = expf((acc_s[bc] - scoremax[0]) * scale); - acc_s[bc] = val; - current_sum += val; - } - score_sum[0] = current_sum; - logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; - } - - // (与FP32版本相同) - inline void rescale_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_o, - acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, - const int32_t t_r_idx, const int32_t t_c_idx, - const int32_t seq_size_q, const int32_t seq_size_k, - bool causal_mask) { - float scale = score_scale[0]; - for (int j = 0; j < dim_size; ++j) { acc_o[j] *= scale; } - } - - // (混合精度修改版) - inline void mma1_d_n_fixed(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, - const dtype_kv_in_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, - const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, - const int32_t t_c_idx, const int32_t seq_size_q, - const int32_t seq_size_k, bool causal_mask) { - const int32_t v_stride_size = kv_head_size * dim_size; - for (int d_base = 0; d_base < dim_size; ++d_base) { - float acc = acc_o[d_base]; - for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - acc += w_block[b_c_idx] * MLLM_FP16_TO_FP32(v_block[b_c_idx * v_stride_size + d_base]); - } - acc_o[d_base] = acc; - } - } - -private: - acc_dtype_t *acc_o_; - acc_dtype_t *acc_s_; - acc_dtype_t *logsum_; - acc_dtype_t *scoremax_; - acc_dtype_t *scoremax_prev_; - acc_dtype_t *score_scale_; - acc_dtype_t *score_sum_; -}; - -template -struct FlashAttn2T { -public: - using dtype_q_in_t = typename Impl::dtype_q_in_t; - using dtype_kv_in_t = typename Impl::dtype_kv_in_t; - using dtype_out_t = typename Impl::dtype_out_t; - using acc_dtype_t = typename Impl::acc_dtype_t; - - void configure(int32_t Br, int32_t Bc, int32_t Q_Head, int32_t KV_Head, int32_t threads, bool high_precision) { - impl_.configure(Br, Bc, Q_Head, KV_Head, threads, high_precision); - } - - void init_workspace(acc_dtype_t *acc_o, acc_dtype_t *acc_s, - acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, - acc_dtype_t *score_scale, acc_dtype_t *score_sum) { - impl_.init_workspace(acc_o, acc_s, logsum, scoremax, scoremax_prev, score_scale, score_sum); - } - - void operator()(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, - const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, - const int32_t batch_size, const int32_t head_size, - const int32_t seq_size_q, const int32_t seq_size_k, - const int32_t dim_size, bool causal_mask = true) { - impl_.fa2(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); - } - -private: - Impl impl_; -}; - -} // namespace mobi_attn - -void flash_attention_2_forward( - const void *Q, const void *K, const void *V, void *O, - int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, - bool causal_mask, bool use_fp32, int32_t threads, int32_t br, int32_t bc, - int32_t q_head, int32_t kv_head, bool high_precision_exp) { - const size_t acc_o_size = threads * br * dim_size * sizeof(float); - const size_t acc_s_size = threads * br * bc * sizeof(float); - const size_t logsum_size = threads * br * sizeof(float); - const size_t scoremax_size = threads * br * sizeof(float); - const size_t scoremax_prev_size = threads * br * sizeof(float); - const size_t score_scale_size = threads * br * sizeof(float); - const size_t score_sum_size = threads * br * sizeof(float); - - // TODO 改为只分配一次 - void *workspace[7]; - mobi_attn::aligned_alloc(&workspace[0], acc_o_size, 32); - mobi_attn::aligned_alloc(&workspace[1], acc_s_size, 32); - mobi_attn::aligned_alloc(&workspace[2], logsum_size, 32); - mobi_attn::aligned_alloc(&workspace[3], scoremax_size, 32); - mobi_attn::aligned_alloc(&workspace[4], scoremax_prev_size, 32); - mobi_attn::aligned_alloc(&workspace[5], score_scale_size, 32); - mobi_attn::aligned_alloc(&workspace[6], score_sum_size, 32); - - if (use_fp32) { - // 使用纯FP32 NEON实现 - mobi_attn::FlashAttn2T op; - op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); - - op.init_workspace( - static_cast(workspace[0]), static_cast(workspace[1]), - static_cast(workspace[2]), static_cast(workspace[3]), - static_cast(workspace[4]), static_cast(workspace[5]), - static_cast(workspace[6])); - - op(static_cast(Q), static_cast(K), static_cast(V), - static_cast(O), - batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); - } else { - // 使用FP16输入,FP32输出的NEON实现 - mobi_attn::FlashAttn2T op; - op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); - - op.init_workspace( - static_cast(workspace[0]), static_cast(workspace[1]), - static_cast(workspace[2]), static_cast(workspace[3]), - static_cast(workspace[4]), static_cast(workspace[5]), - static_cast(workspace[6])); - - op(static_cast(Q), static_cast(K), static_cast(V), - static_cast(O), - batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); - } - - for (void *ptr : workspace) { - if (ptr) mobi_attn::aligned_free(ptr); + op(static_cast(Q), static_cast(K), static_cast(V), + static_cast(O), + batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); } } - -#endif // AVX2 - #endif // MLLM_FA2_CAL_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUSplitFunc.hpp b/src/backends/cpu/function/CPUSplitFunc.hpp index 088d3b9c9..15fcf49d7 100644 --- a/src/backends/cpu/function/CPUSplitFunc.hpp +++ b/src/backends/cpu/function/CPUSplitFunc.hpp @@ -22,6 +22,8 @@ class CPUsplitFunction : public TensorFunction { } Chl split_dim = (Chl)args[size - 2]; int head_size = (int)args[size - 1]; + + int split_num_ = each_dims.size(); // store each dims int split_dim_size_ = 0; diff --git a/src/backends/cpu/function/CPUTransposeFunc.hpp b/src/backends/cpu/function/CPUTransposeFunc.hpp index 5d87f2132..f0b2a0151 100644 --- a/src/backends/cpu/function/CPUTransposeFunc.hpp +++ b/src/backends/cpu/function/CPUTransposeFunc.hpp @@ -103,7 +103,7 @@ class CPUtransposeFunction : public TensorFunction { } } void execute(vector> outputs, vector> inputs, vector args) override { - vector> axiss; + vector> axiss; // for BSHD attention start for (int i = 0; i < args.size(); i += 2) { axiss.push_back({(Chl)args[i], (Chl)args[i + 1]}); diff --git a/src/backends/cpu/op/CPUArgSortFunc.hpp b/src/backends/cpu/op/CPUArgSortFunc.hpp new file mode 100644 index 000000000..6ac6e74c2 --- /dev/null +++ b/src/backends/cpu/op/CPUArgSortFunc.hpp @@ -0,0 +1,71 @@ +// +// Created by Rongjie Yi on 24-12-16. +// + +#ifndef CPUARGSORTKFUNC_HPP +#define CPUARGSORTKFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" // For Op and Creator +#include +#include +#include +#include + +namespace mllm { +class Tensor; + +class CPUargsortFunction : public Op { +private: + int thread_count = 4; + + // 自定义比较函数,用于对索引进行排序 + bool compareIndices(const std::pair &a, const std::pair &b) { + return a.second < b.second; + } + + void argsort(float *input, int size, float *out_indices) { + std::vector> indexedInput(size); + for (int i = 0; i < size; ++i) { + indexedInput[i] = std::make_pair(i, input[i]); + } + std::sort(indexedInput.begin(), indexedInput.end(), [this](const std::pair &a, const std::pair &b) { + return compareIndices(a, b); + }); + for (int i = 0; i < size; ++i) { + out_indices[i] = static_cast(indexedInput[i].first); + } + } + +public: + CPUargsortFunction(Backend *bn, string name, int threadCount) + : thread_count(threadCount), Op(bn, name) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + assert(inputs[0]->sequence() == 1); + assert(inputs[0]->head() == 1); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); // argsortk_values + return ErrorCode::MLLM_NO_ERROR; + } + ErrorCode execute(vector> inputs, vector> outputs) override { + int size = inputs[0]->dimension(); + for (int b = 0; b < inputs[0]->batch(); b++) { + float *data = inputs[0]->ptrAt(b, 0, 0, 0); + float *out = outputs[0]->ptrAt(b, 0, 0, 0); + argsort(data, size, out); + } + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUargsortFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new CPUargsortFunction(bn, name, threadCount); + } +}; + +} // namespace mllm +#endif // CPUARGSORTKFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUBinCountFunc.hpp b/src/backends/cpu/op/CPUBinCountFunc.hpp new file mode 100644 index 000000000..327622cd6 --- /dev/null +++ b/src/backends/cpu/op/CPUBinCountFunc.hpp @@ -0,0 +1,81 @@ +// +// Created by Rongjie Yi on 24-12-16. +// + +#ifndef CPUBINCOUNTKFUNC_HPP +#define CPUBINCOUNTKFUNC_HPP +#include "Tensor.hpp" +#include "Types.hpp" +#include +#include +#include "CPUBackend.hpp" + +namespace mllm { +class Tensor; + +class CPUbincountFunction : public Op { +private: + int thread_count = 4; + + void bincount(float *input, int size, float *out, int max_val) { + // 初始化输出数组 +#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) + for (int i = 0; i <= max_val; ++i) { + out[i] = 0; + } + + // 计算每个值的出现次数 + // #pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) + for (int i = 0; i < size; ++i) { + int index = static_cast(input[i]); + if (index >= 0 && index <= max_val) { + out[index] += 1; + } + } + } + +public: + CPUbincountFunction(Backend *bn, string name, int threadCount) : + thread_count(threadCount), Op(bn, name) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + assert(inputs[0]->batch() == 1); + assert(inputs[0]->sequence() == 1); + assert(inputs[0]->head() == 1); + // For dynamic-shape ops, reshape sets what's known. Final shape is set in execute. + outputs[0]->reshape(1, 1, 1, 0); + outputs[0]->setDtype(MLLM_TYPE_F32); + return ErrorCode::MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + int size = inputs[0]->dimension(); + int max_val = 0; + for (int i = 0; i < size; ++i) { + int val = static_cast(inputs[0]->dataAt(0, 0, 0, i)); + if (val > max_val) { + max_val = val; + } + } + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), max_val + 1); + outputs[0]->setDtype(inputs[0]->dtype()); // bincountk_values + outputs[0]->alloc(); + float *data = inputs[0]->hostPtr(); + float *out = outputs[0]->hostPtr(); + if (max_val > 0) { + bincount(data, size, out, max_val); + } + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUbincountFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new CPUbincountFunction(bn, name, threadCount); + } +}; + +} // namespace mllm +#endif // CPUBINCOUNTKFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUBinaryFunc.hpp b/src/backends/cpu/op/CPUBinaryFunc.hpp new file mode 100644 index 000000000..3c7ec52a7 --- /dev/null +++ b/src/backends/cpu/op/CPUBinaryFunc.hpp @@ -0,0 +1,379 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUBINARYFUNC_HPP +#define CPUBINARYFUNC_HPP +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include "../compute/Arithmetic.hpp" + +namespace mllm { +class Tensor; + + +class CPUaddFunction : public Op { +private: + int thread_count = 4; + float data = 0.0f; // The data to be added +public: + CPUaddFunction(Backend *bn, string name, float data, int threadCount) + : thread_count(threadCount), Op(bn, name) { + this->data = data; + } + ErrorCode reshape(vector> inputs, vector> outputs) override { + auto input = inputs[0]; + auto output = outputs[0]; + output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); + output->setDtype(input->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + ErrorCode execute(vector> inputs, vector> outputs) override { + auto input = inputs[0]; +#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) + for (int n = 0; n < input->batch(); ++n) { + for (int c = 0; c < input->head(); ++c) { + for (int h = 0; h < input->sequence(); ++h) { + mllm_add_fp32(input->ptrAt(n, c, h, 0), data, + outputs[0]->ptrAt(n, c, h, 0), input->dimension()); + } + } + } + return ErrorCode::MLLM_NO_ERROR; + } +}; +class CPUaddFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + float data = (float)op_param.find("data")->second; + return new CPUaddFunction(bn, name, data, threadCount); + } +}; + +class CPUsubFunction : public Op { +private: + int thread_count = 4; + float data = 0.0f; +public: + CPUsubFunction(Backend *bn, string name, float data, int threadCount) + : thread_count(threadCount), Op(bn, name) { + this->data = data; + } + ErrorCode reshape(vector> inputs, vector> outputs) override { + auto input = inputs[0]; + auto output = outputs[0]; + output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); + output->setDtype(input->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + ErrorCode execute(vector> inputs, vector> outputs) override { + auto input = inputs[0]; +#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) + for (int n = 0; n < input->batch(); ++n) { + for (int c = 0; c < input->head(); ++c) { + for (int h = 0; h < input->sequence(); ++h) { + mllm_sub_fp32(input->ptrAt(n, c, h, 0), data, + outputs[0]->ptrAt(n, c, h, 0), input->dimension()); + } + } + } + return ErrorCode::MLLM_NO_ERROR; + } +}; +class CPUsubFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + float data = (float)op_param.find("data")->second; + return new CPUsubFunction(bn, name, data, threadCount); + } +}; + +class CPUmulFunction : public Op { +private: + int thread_count = 4; + float data = 0.0f; +public: + CPUmulFunction(Backend *bn, string name, float data, int threadCount) + : thread_count(threadCount), Op(bn, name) { + this->data = data; + } + ErrorCode reshape(vector> inputs, vector> outputs) override { + auto input = inputs[0]; + auto output = outputs[0]; + output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); + output->setDtype(input->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + ErrorCode execute(vector> inputs, vector> outputs) override { + auto input = inputs[0]; +#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) + for (int n = 0; n < input->batch(); ++n) { + for (int c = 0; c < input->head(); ++c) { + for (int h = 0; h < input->sequence(); ++h) { + mllm_mul_fp32(input->ptrAt(n, c, h, 0), data, + outputs[0]->ptrAt(n, c, h, 0), input->dimension()); + } + } + } + return ErrorCode::MLLM_NO_ERROR; + } +}; +class CPUmulFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + float data = (float)op_param.find("data")->second; + return new CPUmulFunction(bn, name, data, threadCount); + } +}; + +class CPUdivFunction : public Op { +private: + int thread_count = 4; + float data = 0.0f; +public: + CPUdivFunction(Backend *bn, string name, float data, int threadCount) + : thread_count(threadCount), Op(bn, name) { + this->data = data; + } + ErrorCode reshape(vector> inputs, vector> outputs) override { + auto input = inputs[0]; + auto output = outputs[0]; + output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); + output->setDtype(input->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + ErrorCode execute(vector> inputs, vector> outputs) override { + auto input = inputs[0]; +#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) + for (int n = 0; n < input->batch(); ++n) { + for (int c = 0; c < input->head(); ++c) { + for (int h = 0; h < input->sequence(); ++h) { + mllm_div_fp32(input->ptrAt(n, c, h, 0), data, + outputs[0]->ptrAt(n, c, h, 0), input->dimension()); + } + } + } + return ErrorCode::MLLM_NO_ERROR; + } +}; +class CPUdivFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + float data = (float)op_param.find("data")->second; + return new CPUdivFunction(bn, name, data, threadCount); + } +}; + +class CPUdivintFunction : public Op { +private: + int thread_count = 4; + float data = 0.0f; +public: + CPUdivintFunction(Backend *bn, string name, float data, int threadCount) + : thread_count(threadCount), Op(bn, name) { + this->data = data; + } + ErrorCode reshape(vector> inputs, vector> outputs) override { + auto input = inputs[0]; + auto output = outputs[0]; + output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); + output->setDtype(input->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + ErrorCode execute(vector> inputs, vector> outputs) override { + auto input = inputs[0]; +#pragma omp parallel for collapse(4) num_threads(CPUBackend::cpu_threads) + for (int n = 0; n < input->batch(); ++n) { + for (int c = 0; c < input->head(); ++c) { + for (int h = 0; h < input->sequence(); ++h) { + for (int d = 0; d < input->dimension(); ++d) { + outputs[0]->setDataAt(n, c, h, d, + static_cast(input->dataAt(n, c, h, d) / data)); + } + } + } + } + return ErrorCode::MLLM_NO_ERROR; + } +}; +class CPUdivintFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + float data = (float)op_param.find("data")->second; + return new CPUdivintFunction(bn, name, data, threadCount); + } +}; + +class CPUaddTwoFunction : public Op { +private: + int thread_count = 4; +public: + CPUaddTwoFunction(Backend *bn, string name, int threadCount) + : thread_count(threadCount), Op(bn, name) {} + ErrorCode reshape(vector> inputs, vector> outputs) override { + outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), + inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + }; + ErrorCode execute(vector> inputs, vector> outputs) override { + auto input0 = inputs[0]; + auto input1 = inputs[1]; + int batch_ = std::max(input0->batch(), input1->batch()); + for (int n = 0; n < batch_; ++n) { + auto n_0 = std::min(n, input0->batch() - 1); + auto n_1 = std::min(n, input1->batch() - 1); +#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) + for (int c = 0; c < input0->head(); ++c) { + for (int h = 0; h < input0->sequence(); ++h) { + mllm_add_fp32(input0->ptrAt(n_0, c, h, 0), + input1->ptrAt(n_1, c, h, 0), + outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); + } + } + } + return ErrorCode::MLLM_NO_ERROR; + }; +}; +class CPUaddTwoFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + return new CPUaddTwoFunction(bn, name, threadCount); + } +}; + +class CPUsubTwoFunction : public Op { +private: + int thread_count = 4; +public: + CPUsubTwoFunction(Backend *bn, string name, int threadCount) + : thread_count(threadCount), Op(bn, name) {} + ErrorCode reshape(vector> inputs, vector> outputs) override { + outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), + inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + }; + ErrorCode execute(vector> inputs, vector> outputs) override { + auto input0 = inputs[0]; + auto input1 = inputs[1]; + int batch_ = std::max(input0->batch(), input1->batch()); + for (int n = 0; n < batch_; ++n) { + auto n_0 = std::min(n, input0->batch() - 1); + auto n_1 = std::min(n, input1->batch() - 1); +#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) + for (int c = 0; c < input0->head(); ++c) { + for (int h = 0; h < input0->sequence(); ++h) { + mllm_sub_fp32(input0->ptrAt(n_0, c, h, 0), + input1->ptrAt(n_1, c, h, 0), + outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); + } + } + } + return ErrorCode::MLLM_NO_ERROR; + }; +}; +class CPUsubTwoFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + return new CPUsubTwoFunction(bn, name, threadCount); + } +}; + +class CPUmulTwoFunction : public Op { +private: + int thread_count = 4; +public: + CPUmulTwoFunction(Backend *bn, string name, int threadCount) + : thread_count(threadCount), Op(bn, name) {} + ErrorCode reshape(vector> inputs, vector> outputs) override { + outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), + inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + }; + ErrorCode execute(vector> inputs, vector> outputs) override { + if (outputs[0]->sequence() == 0 + || inputs[0]->sequence() != outputs[0]->sequence()) { + outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), + inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->alloc(); + } + auto input0 = inputs[0]; + auto input1 = inputs[1]; + int batch_ = std::max(input0->batch(), input1->batch()); + for (int n = 0; n < batch_; ++n) { + auto n_0 = std::min(n, input0->batch() - 1); + auto n_1 = std::min(n, input1->batch() - 1); +#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) + for (int c = 0; c < input0->head(); ++c) { + for (int h = 0; h < input0->sequence(); ++h) { + if (input1->dimension() == 1) { + mllm_mul_fp32(input0->ptrAt(n_0, c, h, 0), + input1->dataAt(n_1, c, h, 0), + outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); + } else { + mllm_mul_fp32(input0->ptrAt(n_0, c, h, 0), + input1->ptrAt(n_1, c, h, 0), + outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); + } + } + } + } + return ErrorCode::MLLM_NO_ERROR; + }; +}; +class CPUmulTwoFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + return new CPUmulTwoFunction(bn, name, threadCount); + } +}; + +class CPUdivTwoFunction : public Op { +private: + int thread_count = 4; +public: + CPUdivTwoFunction(Backend *bn, string name, int threadCount) + : thread_count(threadCount), Op(bn, name) {} + ErrorCode reshape(vector> inputs, vector> outputs) override { + outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), + inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + }; + ErrorCode execute(vector> inputs, vector> outputs) override { + auto input0 = inputs[0]; + auto input1 = inputs[1]; + int batch_ = std::max(input0->batch(), input1->batch()); + for (int n = 0; n < batch_; ++n) { + auto n_0 = std::min(n, input0->batch() - 1); + auto n_1 = std::min(n, input1->batch() - 1); +#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) + for (int c = 0; c < input0->head(); ++c) { + for (int h = 0; h < input0->sequence(); ++h) { + if (input1->dimension() == 1) { + mllm_div_fp32(input0->ptrAt(n_0, c, h, 0), + input1->dataAt(n_1, c, h, 0), + outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); + } else { + mllm_div_fp32(input0->ptrAt(n_0, c, h, 0), + input1->ptrAt(n_1, c, h, 0), + outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); + } + } + } + } + return ErrorCode::MLLM_NO_ERROR; + }; +}; +class CPUdivTwoFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + return new CPUdivTwoFunction(bn, name, threadCount); + } +}; + +} // namespace mllm +#endif // CPUBINARYFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUCatFunc.hpp b/src/backends/cpu/op/CPUCatFunc.hpp new file mode 100644 index 000000000..57fa66f4e --- /dev/null +++ b/src/backends/cpu/op/CPUCatFunc.hpp @@ -0,0 +1,328 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUCATFUNC_HPP +#define CPUCATFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include +#include +#include + +namespace mllm { +class Tensor; + +class CPUcatFunction : public Op { +private: + int thread_count = 4; + Chl axis_; + +public: + CPUcatFunction(Backend *bn, string name, int threadCount, Chl axis) : + Op(bn, name), thread_count(threadCount), axis_(axis) { + } + + + ErrorCode setUp(vector> inputs, vector> outputs) override { + if (outputs[0]->shape().empty()) { + int expd_batch_ = inputs[0]->batch(); + for (int ii = 0; ii < inputs.size(); ++ii) { + auto input = inputs[ii]; + if (input->batch() > expd_batch_) { + expd_batch_ = input->batch(); + } + } + int dim_b = expd_batch_; + int dim_h = inputs[0]->head(); + int dim_s = inputs[0]->sequence(); + int dim_d = inputs[0]->dimension(); + int sizes[] = {0, 0, 0, 0}; + Chl axes[] = {BATCH, HEAD, SEQUENCE, DIMENSION}; + int *dims[] = {&dim_b, &dim_h, &dim_s, &dim_d}; + for (int i = 0; i < 4; i++) { + if (axis_ == axes[i]) { + for (auto input : inputs) { + sizes[i] += (i == 0) ? input->batch() : (i == 1) ? input->head() : + (i == 2) ? input->sequence() : + input->dimension(); + } + *dims[i] = sizes[i]; + break; + } + } + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + } + if (axis_ == HEAD) { + int cbatch = 0; + int chead = 0; + int cseq = 0; + int cdim = 0; + if (inputs[0]->hostPtr() == inputs[1]->hostPtr()) { + if (inputs[0]->masterTensor() == nullptr) { + inputs[0]->free(); + } + inputs[0]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); + } else { + for (int idx = 0; idx < inputs.size(); idx++) { + if (inputs[idx]->masterTensor() == nullptr) { + inputs[idx]->free(); + } + if (idx > 0) { + chead += inputs[idx - 1]->head(); + } + inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d + } + } + } else if (axis_ == SEQUENCE && inputs[0]->head() != 1) { + int cbatch = 0; + int chead = 0; + int cseq = 0; + int cdim = 0; + for (int idx = 0; idx < inputs.size(); idx++) { + if (inputs[idx]->masterTensor() == nullptr) { + inputs[idx]->free(); + } + if (idx > 0) { + cseq += inputs[idx - 1]->sequence(); + } + inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d + } + } else if (axis_ == DIMENSION && inputs[0]->head() != 1) { + int cbatch = 0; + int chead = 0; + int cseq = 0; + int cdim = 0; + for (int idx = 0; idx < inputs.size(); idx++) { + if (inputs[idx]->masterTensor() == nullptr) { + inputs[idx]->free(); + } + if (idx > 0) { + cdim += inputs[idx - 1]->dimension(); + } + int tmp_agg_idx; + if (inputs[idx]->deaggregatedTensor() != nullptr) { + for (int t = 0; t < inputs[idx]->deaggregatedTensor()->aggregatedTensors().size(); t++) { + if (inputs[idx]->deaggregatedTensor()->aggregatedTensors()[t] == inputs[idx]) { + tmp_agg_idx = t; + continue; + } + } + } + inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d + if (inputs[idx]->deaggregatedTensor() != nullptr) { + vector> shared_outputs = {}; + for (int t = 0; t < inputs[idx]->deaggregatedTensor()->aggregatedTensors().size(); t++) { + if (t == tmp_agg_idx) { + inputs[idx]->deaggregatedTensor()->aggregatedTensors()[t] = inputs[idx]; + // std::shared_ptr(inputs[idx], [](Tensor *) {}); + } + } + } + } + } + return MLLM_NO_ERROR; + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + int expd_batch_ = inputs[0]->batch(); + for (int ii = 0; ii < inputs.size(); ++ii) { + auto input = inputs[ii]; + if (input->batch() > expd_batch_) { + expd_batch_ = input->batch(); + } + } + int dim_b = expd_batch_; + int dim_h = inputs[0]->head(); + int dim_s = inputs[0]->sequence(); + int dim_d = inputs[0]->dimension(); + int sizes[] = {0, 0, 0, 0}; + Chl axes[] = {BATCH, HEAD, SEQUENCE, DIMENSION}; + int *dims[] = {&dim_b, &dim_h, &dim_s, &dim_d}; + for (int i = 0; i < 4; i++) { + if (axis_ == axes[i]) { + for (auto input : inputs) { + sizes[i] += (i == 0) ? input->batch() : (i == 1) ? input->head() : + (i == 2) ? input->sequence() : + input->dimension(); + } + *dims[i] = sizes[i]; + break; + } + } + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + if (outputs[0]->masterTensor() == nullptr) { + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + } + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + int expd_batch_ = inputs[0]->batch(); + int expd_batch_input_idx = 0; + // int expd_head_ = inputs[0]->head(); + // int expd_head_input_idx = 0; + for (int ii = 0; ii < inputs.size(); ++ii) { + auto input = inputs[ii]; + if (input->batch() > expd_batch_) { + expd_batch_ = input->batch(); + expd_batch_input_idx = ii; + } + // if (input->head() > expd_head_) { + // expd_head_ = input->head(); + // expd_head_input_idx = ii; + // } + } + if (axis_ == BATCH) { + for (int n = 0; n < inputs.size(); ++n) { + auto copysize = inputs[0]->batch() * inputs[0]->head() * inputs[0]->sequence() * inputs[0]->dimension(); + memcpy(outputs[0]->ptrAt(n * inputs[0]->batch(), 0, 0, 0), + inputs[n]->ptrAt(0, 0, 0, 0), + sizeof(float) * copysize); + } + } else if (axis_ == DIMENSION) { + for (int n = 0; n < expd_batch_; ++n) { + for (int c = 0; c < inputs[0]->head(); ++c) { + for (int h = 0; h < inputs[0]->sequence(); ++h) { + int w = 0; + for (int idx = 0; idx < inputs.size(); idx++) { + int dim_size = inputs[idx]->dimension(); + auto n_ = n; + if (idx != expd_batch_input_idx) { + n_ = 0; + } + assert(inputs[0]->dtype() == outputs[0]->dtype()); + if (inputs[0]->dtype() == MLLM_TYPE_F32) { + memcpy(outputs[0]->ptrAt(n, c, h, w), + inputs[idx]->ptrAt(n_, c, h, 0), + sizeof(float) * (dim_size)); + } else if (inputs[0]->dtype() == MLLM_TYPE_F16) { + memcpy(outputs[0]->ptrAt(n, c, h, w), + inputs[idx]->ptrAt(n_, c, h, 0), + sizeof(mllm_fp16_t) * (dim_size)); + } + w += dim_size; + } + } + } + } + } else if ((axis_ == SEQUENCE) && inputs[0]->head() != 1) { + // #pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) .//TODO优化 + assert(inputs[0]->head() == inputs[1]->head()); + assert(outputs[0]->ctype() == inputs[0]->ctype()); + for (int n = 0; n < expd_batch_; ++n) { + for (int h = 0; h < inputs[0]->head(); ++h) { + if (inputs[0]->ctype() == BSHD) { + int s_base = 0; + for (int idx = 0; idx < inputs.size(); idx++) { + auto n_ = (idx == expd_batch_input_idx) ? n : 0; + for (int s = 0; s < inputs[idx]->sequence(); ++s) { + if (inputs[0]->dtype() == MLLM_TYPE_F32) { + memcpy(outputs[0]->ptrAt(n, h, s_base + s, 0), + inputs[idx]->ptrAt(n_, h, s, 0), + sizeof(float) * (inputs[idx]->dimension())); + } else if (inputs[0]->dtype() == MLLM_TYPE_F16) { + memcpy(outputs[0]->ptrAt(n, h, s_base + s, 0), + inputs[idx]->ptrAt(n_, h, s, 0), + sizeof(mllm_fp16_t) * (inputs[idx]->dimension())); + } + } + s_base += inputs[idx]->sequence(); + } + } else if (inputs[0]->ctype() == BHDS) { + int s_base = 0; + for (int idx = 0; idx < inputs.size(); idx++) { + auto n_ = (idx == expd_batch_input_idx) ? n : 0; + if (inputs[idx]->ctype() == BSHD) { + for (int s = 0; s < inputs[idx]->sequence(); ++s) { + for (int d = 0; d < inputs[idx]->dimension(); ++d) { + outputs[0]->setDataAt(n, h, s_base + s, d, + inputs[idx]->dataAt(n_, h, s, d)); + } + } + } else { + for (int d = 0; d < inputs[idx]->dimension(); ++d) { + if (inputs[0]->dtype() == MLLM_TYPE_F32) { + memcpy(outputs[0]->ptrAt(n, h, s_base, d), + inputs[idx]->ptrAt(n_, h, 0, d), + sizeof(float) * (inputs[idx]->sequence())); + } else if (inputs[0]->dtype() == MLLM_TYPE_F16) { + memcpy(outputs[0]->ptrAt(n, h, s_base, d), + inputs[idx]->ptrAt(n_, h, 0, d), + sizeof(mllm_fp16_t) * (inputs[idx]->sequence())); + } + } + } + s_base += inputs[idx]->sequence(); + } + } + } + } + } else if ((axis_ == SEQUENCE) && inputs[0]->head() == 1) { + for (int n = 0; n < expd_batch_; ++n) { + int h = 0; + for (int idx = 0; idx < inputs.size(); idx++) { + auto n_ = n; + if (idx != expd_batch_input_idx) { + n_ = 0; + } + memcpy(outputs[0]->ptrAt(n, 0, h, 0), + inputs[idx]->ptrAt(n_, 0, 0, 0), + sizeof(float) * (inputs[idx]->sequence() * inputs[idx]->dimension())); + h += inputs[idx]->sequence(); + } + } + } else if (axis_ == HEAD) { + if (inputs[0]->hostPtr() == inputs[1]->hostPtr()) { + for (int b = 0; b < outputs[0]->batch(); ++b) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + for (int h_ = 1; h_ < outputs[0]->head(); ++h_) { + int dim_size = inputs[0]->dimension(); + memcpy(outputs[0]->ptrAt(b, h_, s, 0), + outputs[0]->ptrAt(b, 0, s, 0), + sizeof(float) * (dim_size)); + } + } + } + return MLLM_NO_ERROR; + } + for (int b = 0; b < expd_batch_; ++b) { +#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) + for (int s = 0; s < inputs[0]->sequence(); ++s) { + // for (int h = 0; h < inputs[0]->head(); ++h) { + int head_i = 0; + for (int idx = 0; idx < inputs.size(); idx++) { + auto b_ = b; + if (idx != expd_batch_input_idx) { + b_ = 0; + } + int dim_size = inputs[idx]->dimension() * inputs[idx]->head(); + memcpy(outputs[0]->ptrAt(b, head_i, s, 0), + inputs[idx]->ptrAt(b_, 0, s, 0), + sizeof(float) * (dim_size)); + head_i += inputs[idx]->head(); + } + // } + } + } + } + return MLLM_NO_ERROR; + } +}; + +class CPUcatFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + Chl axis = (Chl)op_param.at("axis"); + return new CPUcatFunction(bn, name, threadCount, axis); + } +}; + +} // namespace mllm +#endif // CPUCATFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUClipFunc.hpp b/src/backends/cpu/op/CPUClipFunc.hpp new file mode 100644 index 000000000..72c6a0a81 --- /dev/null +++ b/src/backends/cpu/op/CPUClipFunc.hpp @@ -0,0 +1,357 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUCLIPFUNC_HPP +#define CPUCLIPFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include +#include + +namespace mllm { +class Tensor; + +class CPUclipFunction : public Op { +private: + int thread_count = 4; + std::vector b_; + std::vector h_; + std::vector s_; + std::vector d_; + +public: + CPUclipFunction(Backend *bn, string name, int threadCount, + const std::vector &b, const std::vector &h, + const std::vector &s, const std::vector &d) : + Op(bn, name), + thread_count(threadCount), b_(b), h_(h), s_(s), d_(d) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + int dim_b = inputs[0]->batch(); + int dim_h = inputs[0]->head(); + int dim_s = inputs[0]->sequence(); + int dim_d = inputs[0]->dimension(); + + std::vector *, int *>> data = {{&b_, &dim_b}, {&h_, &dim_h}, {&s_, &dim_s}, {&d_, &dim_d}}; + for (auto &pair : data) { + if (pair.first->size() == 2) { + *pair.second = (*pair.first)[1] - (*pair.first)[0]; + } else if (pair.first->size() == 1) { + *pair.second = 1; + } + } + + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + outputs[0]->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + int dim_b = inputs[0]->batch(); + int dim_h = inputs[0]->head(); + int dim_s = inputs[0]->sequence(); + int dim_d = inputs[0]->dimension(); + std::vector, int *>> data = {{b_, &dim_b}, {h_, &dim_h}, {s_, &dim_s}, {d_, &dim_d}}; + for (auto &pair : data) { + if (pair.first.size() == 2) { + *pair.second = pair.first[1] - pair.first[0]; + } else if (pair.first.size() == 1) { + *pair.second = 1; + } + } + if (outputs[0]->dimension() * outputs[0]->sequence() * outputs[0]->head() * outputs[0]->batch() == 0 + || outputs[0]->shape().empty() + || dim_d != outputs[0]->dimension()) { + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + outputs[0]->alloc(); + } + + if (s_.size() == 2) { +#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) + for (int b = 0; b < inputs[0]->batch(); ++b) { + memcpy(outputs[0]->hostPtr() + outputs[0]->offset(b, 0, 0, 0), + inputs[0]->hostPtr() + inputs[0]->offset(b, 0, s_[0], 0), + inputs[0]->head() * (s_[1] - s_[0]) * inputs[0]->dimension() * sizeof(float)); + } + } else if (s_.size() == 1) { + int seq_idx = s_[0]; + if (seq_idx < 0) { + seq_idx = inputs[0]->sequence() + seq_idx; + } +#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) + for (int b = 0; b < inputs[0]->batch(); ++b) { + memcpy(outputs[0]->hostPtr() + outputs[0]->offset(b, 0, 0, 0), + inputs[0]->hostPtr() + inputs[0]->offset(b, 0, seq_idx, 0), + inputs[0]->head() * 1 * inputs[0]->dimension() * sizeof(float)); + } + } else if (b_.size() == 1) { + int bth_idx = b_[0]; + if (bth_idx < 0) { + bth_idx = inputs[0]->batch() + bth_idx; + } + memcpy(outputs[0]->hostPtr(), + inputs[0]->hostPtr() + inputs[0]->offset(bth_idx, 0, 0, 0), + inputs[0]->head() * inputs[0]->sequence() * inputs[0]->dimension() * sizeof(float)); + } else if (b_.size() == 2) { + assert(b_[1] - b_[0] > 0); + memcpy(outputs[0]->hostPtr(), + inputs[0]->hostPtr() + inputs[0]->offset(b_[0], 0, 0, 0), + (b_[1] - b_[0]) * inputs[0]->head() * inputs[0]->sequence() * inputs[0]->dimension() * sizeof(float)); + } else if (d_.size() == 2) { +#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) + for (int b = 0; b < inputs[0]->batch(); ++b) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + for (int h = 0; h < inputs[0]->head(); ++h) { + memcpy(outputs[0]->hostPtr() + outputs[0]->offset(b, h, s, 0), + inputs[0]->hostPtr() + inputs[0]->offset(b, h, s, d_[0]), + (d_[1] - d_[0]) * sizeof(float)); + } + } + } + } else if (d_.size() == 1) { + int seq_idx = d_[0]; + if (seq_idx < 0) { + seq_idx = inputs[0]->dimension() + seq_idx; + } +#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) + for (int b = 0; b < inputs[0]->batch(); ++b) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + for (int h = 0; h < inputs[0]->head(); ++h) { + memcpy(outputs[0]->hostPtr() + outputs[0]->offset(b, h, s, 0), + inputs[0]->hostPtr() + inputs[0]->offset(b, h, s, seq_idx), + sizeof(float)); + } + } + } + } else { + std::cout << "[TODO]Tensor.CLip not support!!!!" << std::endl; + } + + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUclipFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam is structured to reconstruct the vectors. + // Example structure: {"b_size": 1, "b_0": 5, "h_size": 0, ...} + int b_size = op_param.at("b_size"); + int h_size = op_param.at("h_size"); + int s_size = op_param.at("s_size"); + int d_size = op_param.at("d_size"); + + std::vector b, h, s, d; + for (int i = 0; i < b_size; ++i) b.push_back(op_param.at("b_" + std::to_string(i))); + for (int i = 0; i < h_size; ++i) h.push_back(op_param.at("h_" + std::to_string(i))); + for (int i = 0; i < s_size; ++i) s.push_back(op_param.at("s_" + std::to_string(i))); + for (int i = 0; i < d_size; ++i) d.push_back(op_param.at("d_" + std::to_string(i))); + + return new CPUclipFunction(bn, name, threadCount, b, h, s, d); + } +}; + +class CPUclipaxisFunction : public Op { +private: + int thread_count = 4; + Chl axis_; + std::vector b_; + std::vector h_; + std::vector s_; + std::vector d_; + +public: + CPUclipaxisFunction(Backend *bn, string name, int threadCount, Chl axis, + const std::vector &b, const std::vector &h, + const std::vector &s, const std::vector &d) : + Op(bn, name), + thread_count(threadCount), axis_(axis), b_(b), h_(h), s_(s), d_(d) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + int dim_b = inputs[0]->batch(); + int dim_h = inputs[0]->head(); + int dim_s = inputs[0]->sequence(); + int dim_d = inputs[0]->dimension(); + switch (axis_) { + case BATCH: { + std::vector, int *>> data = {{h_, &dim_h}, {s_, &dim_s}, {d_, &dim_d}}; + for (auto &pair : data) { + if (!pair.first.empty()) { + *pair.second = 1; + } + } + break; + } + case HEAD: { + std::vector, int *>> data = {{b_, &dim_b}, {s_, &dim_s}, {d_, &dim_d}}; + for (auto &pair : data) { + if (!pair.first.empty()) { + *pair.second = 1; + } + } + break; + } + case SEQUENCE: { + std::vector, int *>> data = {{b_, &dim_b}, {h_, &dim_h}, {d_, &dim_d}}; + for (auto &pair : data) { + if (!pair.first.empty()) { + *pair.second = 1; + } + } + break; + } + case DIMENSION: { + std::vector, int *>> data = {{b_, &dim_b}, {h_, &dim_h}, {s_, &dim_s}}; + for (auto &pair : data) { + if (!pair.first.empty()) { + *pair.second = 1; + } + } + break; + } + default: + break; + } + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + outputs[0]->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + ErrorCode execute(vector> inputs, vector> outputs) override { + if (axis_ == BATCH) { + if (!s_.empty()) { + for (int i = 0; i < s_.size(); ++i) { + auto seq_idx = s_[i]; + memcpy(outputs[0]->hostPtr() + outputs[0]->offset(i, 0, 0, 0), + inputs[0]->hostPtr() + inputs[0]->offset(i, 0, seq_idx, 0), + inputs[0]->head() * 1 * inputs[0]->dimension() * sizeof(float)); + } + } + } else { + std::cout << "[TODO]Tensor.CLip axis not support!!!!" << std::endl; + } + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUclipaxisFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + Chl axis = (Chl)op_param.at("axis"); + int b_size = op_param.count("b_size") ? op_param.at("b_size") : 0; + int h_size = op_param.count("h_size") ? op_param.at("h_size") : 0; + int s_size = op_param.count("s_size") ? op_param.at("s_size") : 0; + int d_size = op_param.count("d_size") ? op_param.at("d_size") : 0; + + std::vector b, h, s, d; + for (int i = 0; i < b_size; ++i) b.push_back(op_param.at("b_" + std::to_string(i))); + for (int i = 0; i < h_size; ++i) h.push_back(op_param.at("h_" + std::to_string(i))); + for (int i = 0; i < s_size; ++i) s.push_back(op_param.at("s_" + std::to_string(i))); + for (int i = 0; i < d_size; ++i) d.push_back(op_param.at("d_" + std::to_string(i))); + + return new CPUclipaxisFunction(bn, name, threadCount, axis, b, h, s, d); + } +}; + +class CPUcliptensorFunction : public Op { +private: + int thread_count = 4; + Chl dim_; + +public: + CPUcliptensorFunction(Backend *bn, string name, int threadCount, Chl dim) : + Op(bn, name), thread_count(threadCount), dim_(dim) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + if (dim_ == SEQUENCE) { + int new_seq = inputs[1]->dimension(); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), new_seq, inputs[0]->dimension()); + } else if (dim_ == DIMENSION) { + int new_dim = inputs[1]->dimension(); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), new_dim); + } else { + std::cout << "[TODO]Tensor.Clip tensor not support!!!!" << std::endl; + } + outputs[0]->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + if (dim_ == SEQUENCE) { + if (inputs[0]->ctype() == BHDS) { + outputs[0]->chls() = inputs[0]->chls(); + outputs[0]->setCtype(BHDS); + int new_seq = inputs[1]->dimension(); + if (outputs[0]->sequence() == 0 || outputs[0]->shape().empty() + || new_seq != outputs[0]->sequence()) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), new_seq, inputs[0]->dimension()); + outputs[0]->alloc(); + } + +#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) + for (int b = 0; b < inputs[0]->batch(); ++b) { + for (int d = 0; d < inputs[0]->dimension(); ++d) { + for (int s = 0; s < new_seq; ++s) { + auto selected_idx = (int)inputs[1]->dataAt(0, 0, 0, s); + outputs[0]->setDataAt(b, 0, s, d, + inputs[0]->dataAt(b, 0, selected_idx, d)); + } + } + } + return MLLM_NO_ERROR; + } + int new_seq = inputs[1]->dimension(); + if (outputs[0]->sequence() == 0 || outputs[0]->shape().empty() + || new_seq != outputs[0]->sequence()) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), new_seq, inputs[0]->dimension()); + outputs[0]->alloc(); + } +#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) + for (int b = 0; b < inputs[0]->batch(); ++b) { + for (int s = 0; s < inputs[1]->dimension(); ++s) { + auto selected_idx = (int)inputs[1]->dataAt(0, 0, 0, s); + memcpy(outputs[0]->ptrAt(b, 0, s, 0), + inputs[0]->ptrAt(b, 0, selected_idx, 0), + inputs[0]->head() * inputs[0]->dimension() * sizeof(float)); + } + } + } else if (dim_ == DIMENSION) { + int new_seq = inputs[1]->dimension(); + if (outputs[0]->sequence() == 0 || outputs[0]->shape().empty() + || new_seq != outputs[0]->sequence()) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), new_seq); + outputs[0]->alloc(); + } +#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) + for (int b = 0; b < inputs[0]->batch(); ++b) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + for (int d = 0; d < inputs[1]->dimension(); ++d) { + auto selected_idx = (int)inputs[1]->dataAt(0, 0, 0, d); + outputs[0]->setDataAt(b, 0, s, d, + inputs[0]->dataAt(b, 0, s, selected_idx)); + } + } + } + } else { + std::cout << "[TODO]Tensor.CLip not support!!!!" << std::endl; + } + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUcliptensorFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + Chl dim = (Chl)op_param.at("dim"); + return new CPUcliptensorFunction(bn, name, threadCount, dim); + } +}; + +} // namespace mllm +#endif // CPUCLIPFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUExpandFunc.hpp b/src/backends/cpu/op/CPUExpandFunc.hpp new file mode 100644 index 000000000..a4221b024 --- /dev/null +++ b/src/backends/cpu/op/CPUExpandFunc.hpp @@ -0,0 +1,103 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUEXPANDFUNC_HPP +#define CPUEXPANDFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include + +namespace mllm { +class Tensor; + +class CPUexpandFunction : public Op { +private: + int thread_count = 4; + int b_, h_, s_, d_; + +public: + CPUexpandFunction(Backend *bn, string name, int threadCount, int b, int h, int s, int d) + : Op(bn, name), thread_count(threadCount), b_(b), h_(h), s_(s), d_(d) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + // The original assert seems to imply only one dimension can be expanded at a time. + // Let's ensure a similar check but allow -1 for non-expanded dims. + // Example: b=5, h=-1, s=-1, d=-1. (5 * -1 * -1 * -1) = -5 < 0. This logic is preserved. + assert(b_ * h_ * s_ * d_ < 0); + + int dim_b = inputs[0]->batch(); + int dim_h = inputs[0]->head(); + int dim_s = inputs[0]->sequence(); + int dim_d = inputs[0]->dimension(); + + if (b_ != -1) { + assert(dim_b == 1); + dim_b = b_; + } else if (s_ != -1) { + assert(dim_s == 1); + dim_s = s_; + } else if (h_ != -1) { + assert(dim_h == 1); + dim_h = h_; + } else if (d_ != -1) { + assert(dim_d == 1); + dim_d = d_; + } + + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + outputs[0]->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + int dim_b = inputs[0]->batch(); + int dim_s = inputs[0]->sequence(); + int dim_h = inputs[0]->head(); + int dim_d = inputs[0]->dimension(); + + if (b_ != -1) { + std::cerr << "expand for BATCH not support" << std::endl; + } else if (s_ != -1) { +#pragma omp parallel for collapse(2) num_threads(thread_count) + for (int b = 0; b < dim_b; ++b) { + for (int s = 0; s < s_; ++s) { + memcpy(outputs[0]->ptrAt(b, 0, s, 0), + inputs[0]->ptrAt(b, 0, 0, 0), + dim_d * dim_h * inputs[0]->dtypeSize()); + } + } + } else if (h_ != -1) { +#pragma omp parallel for collapse(3) num_threads(thread_count) + for (int b = 0; b < dim_b; ++b) { + for (int s = 0; s < dim_s; ++s) { + for (int h = 0; h < h_; ++h) { + memcpy(outputs[0]->ptrAt(b, h, s, 0), + inputs[0]->ptrAt(b, 0, s, 0), // Assumes input head is 1 + dim_d * inputs[0]->dtypeSize()); + } + } + } + } else if (d_ != -1) { + std::cerr << "expand for DIMENSION not support" << std::endl; + } + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUexpandFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam contains keys "b", "h", "s", "d" + int b = static_cast(op_param.at("b")) ; + int h = static_cast(op_param.at("h")) ; + int s = static_cast(op_param.at("s")) ; + int d = static_cast(op_param.at("d")) ; + return new CPUexpandFunction(bn, name, threadCount, b, h, s, d); + } +}; + +} // namespace mllm +#endif // CPUEXPANDFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUFlashAttention2Func.hpp b/src/backends/cpu/op/CPUFlashAttention2Func.hpp new file mode 100644 index 000000000..77b7414ff --- /dev/null +++ b/src/backends/cpu/op/CPUFlashAttention2Func.hpp @@ -0,0 +1,126 @@ +// +// Created by Rongjie Yi on 25-2-16. +// + +#ifndef CPUFA2FUNC_HPP +#define CPUFA2FUNC_HPP + +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include "../compute/FlashAttention2.hpp" +#include "../compute/FlashAttention2H.hpp" +#include + +namespace mllm { +class Tensor; + +class CPUFlashAttention2Func : public Op { +private: + int thread_count = 4; + bool causal_mask_; + +public: + CPUFlashAttention2Func(Backend *bn, string name, int threadCount, bool causal_mask) + : Op(bn, name), thread_count(threadCount), causal_mask_(causal_mask) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + auto q_tensor = inputs[0]; + auto o_tensor = outputs[0]; + + int batch_size = q_tensor->batch(); + int q_head = q_tensor->head(); + int q_sequence = q_tensor->sequence(); + int dimension = q_tensor->dimension(); + + // for BSHD attention start + if(inputs[0]->ctype() == BHSD && inputs[1]->ctype() == BHSD && inputs[2]->ctype() == BHSD ){ + o_tensor->setCtype(q_tensor->ctype()); + } + // for BSHD attention end + + o_tensor->reshape(batch_size, q_head, q_sequence, dimension); + o_tensor->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + auto q_tensor = inputs[0]; + auto k_tensor = inputs[1]; + auto v_tensor = inputs[2]; + auto o_tensor = outputs[0]; + + int batch_size = q_tensor->batch(); + int q_head = q_tensor->head(); + int q_sequence = q_tensor->sequence(); + int dimension = q_tensor->dimension(); + int k_head = k_tensor->head(); + int k_sequence = k_tensor->sequence(); + int v_head = v_tensor->head(); + int v_sequence = v_tensor->sequence(); + + assert(v_head == k_head && v_sequence == k_sequence); + + bool kv_use_fp32 = (k_tensor->dtype() == MLLM_TYPE_F32); // x86只支持FP32 + + int threads = thread_count; + threads = std::min(threads, v_head); + + int32_t br = q_sequence >= 4 ? 4 : 1; + int32_t bc = q_sequence >= 4 ? 4 : 1; + constexpr bool high_precision_exp = false; + + // for BSHD attention start + if(inputs[0]->ctype()==BHSD && inputs[1]->ctype()==BHSD && inputs[2]->ctype()==BHSD ){ + int km = k_sequence; + int vm = v_sequence; + if(k_tensor->masterTensor()!=nullptr && v_tensor->masterTensor()!=nullptr){ + km = k_tensor->masterTensor()->sequence(); + vm = v_tensor->masterTensor()->sequence(); + } + flash_attention_2_forward_h( + q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), + o_tensor->hostPtr(), // 输入输出张量 + batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 + causal_mask_, // 使用因果掩码 + kv_use_fp32, // 使用FP32(x86必须) + threads, // 线程数 + br, // 查询分块大小 + bc, // 键值分块大小 + q_head, // 查询头数 + k_head, // 键值头数 + high_precision_exp, // 使用快速指数近似 + q_sequence*dimension, + km*dimension, + vm*dimension + ); + // for BSHD attention end + } else { + flash_attention_2_forward( + q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), + o_tensor->hostPtr(), // 输入输出张量 + batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 + causal_mask_, // 使用因果掩码 + kv_use_fp32, // 使用FP32(x86必须) + threads, // 线程数 + br, // 查询分块大小 + bc, // 键值分块大小 + q_head, // 查询头数 + k_head, // 键值头数 + high_precision_exp // 使用快速指数近似 + ); + } + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUFlashAttention2FuncCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + bool causal_mask = (bool)op_param.at("causal_mask"); + return new CPUFlashAttention2Func(bn, name, threadCount, causal_mask); + } +}; + +} // namespace mllm +#endif // CPUFA2FUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUFlattenFunc.hpp b/src/backends/cpu/op/CPUFlattenFunc.hpp new file mode 100644 index 000000000..0348475f9 --- /dev/null +++ b/src/backends/cpu/op/CPUFlattenFunc.hpp @@ -0,0 +1,126 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUFLATTENFUNC_HPP +#define CPUFLATTENFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include +#include "Module.hpp" + +namespace mllm { +class Tensor; + +class CPUflattenFunction : public Op { +private: + int thread_count = 4; + Chl axis_start_; + Chl axis_end_; + +public: + CPUflattenFunction(Backend *bn, string name, int threadCount, Chl axis_start, Chl axis_end) : + Op(bn, name), thread_count(threadCount), axis_start_(axis_start), axis_end_(axis_end) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + auto input = inputs[0]; + auto output = outputs[0]; + + int dim_b = input->batch(); + int dim_h = 0; + int dim_s = 0; + int dim_d = 0; + + if (inputs[0]->shape().size() == 4) { + dim_h = inputs[0]->head(); + dim_s = inputs[0]->sequence(); + dim_d = inputs[0]->dimension(); + if (axis_start_ == BATCH & axis_end_ == SEQUENCE) { + dim_b = 1; + dim_s = inputs[0]->sequence() * inputs[0]->batch(); + } else if (axis_start_ == HEAD & axis_end_ == SEQUENCE) { + dim_h = 1; + dim_s = inputs[0]->sequence() * inputs[0]->head(); + } else if (axis_start_ == HEAD & axis_end_ == DIMENSION) { + dim_h = 1; + dim_d = inputs[0]->dimension() * inputs[0]->head(); + } else { + std::cout << "ERROR: flatten " << axis_start_ << "&" << axis_end_ << std::endl; + } + } else if (inputs[0]->shape().size() == 5) { + if (axis_start_ == CHANNLE & axis_end_ == HEIGHT) { + dim_h = 1; + dim_s = inputs[0]->channel() * inputs[0]->height() * inputs[0]->time(); + dim_d = inputs[0]->width(); + } else if (axis_start_ == HEIGHT & axis_end_ == CHANNLE) { + dim_h = 1; + dim_s = inputs[0]->channel() * inputs[0]->height() * inputs[0]->width(); + dim_d = inputs[0]->time(); + } + } + assert(dim_d + dim_s + dim_h > 0); + if (inputs[0]->ctype() == BCTHW) { // TODOTMPA + outputs[0]->chls()[BATCH] = 0; + outputs[0]->chls()[SEQUENCE] = 1; + outputs[0]->chls()[HEAD] = 2; + outputs[0]->chls()[DIMENSION] = 3; + outputs[0]->setCtype(BSHD); + } + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + return ErrorCode::MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + // No data movement needed, all work done in reshape by creating a view. + return ErrorCode::MLLM_NO_ERROR; + } + + ErrorCode setUp(vector> inputs, vector> outputs) override { + // inputs[0]->shallowCopyFrom(outputs[0].get(), false); + // Chl axis_start = (Chl)args[0]; + // Chl axis_end = (Chl)args[1]; + if ((axis_start_ == TIME & axis_end_ == WIDTH && inputs[0]->ctype() == BCTHW) + || (axis_start_ == CHANNLE & axis_end_ == HEIGHT && inputs[0]->ctype() == BWCTH) + || (axis_start_ == HEIGHT & axis_end_ == CHANNLE && inputs[0]->ctype() == BTHWC) + || (axis_start_ == BATCH & axis_end_ == SEQUENCE && inputs[0]->ctype() != BCTHW) + || (axis_start_ == HEAD & axis_end_ == SEQUENCE && inputs[0]->ctype() == BSHD) + || (axis_start_ == HEAD & axis_end_ == SEQUENCE && inputs[0]->ctype() == BHDS) + || (axis_start_ == HEAD & axis_end_ == DIMENSION && inputs[0]->ctype() == BSHD) + || (axis_start_ == HEAD & axis_end_ == DIMENSION && inputs[0]->ctype() == BHDS) + || (axis_start_ == HEAD & axis_end_ == SEQUENCE && inputs[0]->ctype() == BDSH)) { + if (inputs[0]->masterTensor() == nullptr) { + inputs[0]->free(); + } + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + inputs[0]->shallowCopyFrom(outputs[0].get(), false); + } else if (Module::llm_model_ptr->op_transposed_flag) { + if (inputs[0]->masterTensor() == nullptr) { + inputs[0]->free(); + } + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + inputs[0]->shallowCopyFrom(outputs[0].get(), false); + } else { + std::cout << "[TODO]Tensor.Flatten not support!!!!" << std::endl; + } + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUflattenFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam contains keys "axis_start" and "axis_end" + Chl axis_start = (Chl)op_param.at("axis_start"); + Chl axis_end = (Chl)op_param.at("axis_end"); + return new CPUflattenFunction(bn, name, threadCount, axis_start, axis_end); + } +}; + +} // namespace mllm +#endif // CPUFLATTENFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp b/src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp new file mode 100644 index 000000000..5de1d33ed --- /dev/null +++ b/src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp @@ -0,0 +1,77 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUFUYUGATHEREMBDFUNC_HPP +#define CPUFUYUGATHEREMBDFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include + +namespace mllm { +class Tensor; + +class CPUFuyuGatherEmbdFunc : public Op { +private: + int thread_count = 4; + +public: + CPUFuyuGatherEmbdFunc(Backend *bn, string name, int threadCount) : + Op(bn, name), thread_count(threadCount) { + } + + + ErrorCode setUp(vector> inputs, vector> outputs) override { + if (inputs[0]->masterTensor() == nullptr) { + inputs[0]->free(); + } + outputs[0]->alloc(); + inputs[0]->shallowCopyFrom(outputs[0].get(), false); + return MLLM_NO_ERROR; + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + assert(inputs.size() == 3); + assert(inputs[0]->batch() == inputs[1]->batch()); + assert(inputs[0]->head() == inputs[1]->head()); + assert(inputs[0]->head() == 1); + assert(inputs[0]->dimension() == inputs[1]->dimension()); + assert(inputs[2]->dimension() == 1); + + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + if (inputs[1]->batch() == 0) { + return MLLM_NO_ERROR; + } + assert(inputs[0]->ctype() == BSHD); + assert(inputs[1]->ctype() == BSHD); + + auto input_indices = inputs[2]; + int hiddenSize = inputs[0]->dimension(); + for (int batch = 0; batch < inputs[0]->batch(); ++batch) { + for (int seq = 0; seq < inputs[0]->sequence(); ++seq) { + if (input_indices->dataAt(batch, 0, seq, 0) >= 0) { + memcpy(inputs[0]->hostPtr() + inputs[0]->offset(batch, 0, seq, 0), + inputs[1]->hostPtr() + (int)inputs[1]->offset(batch, 0, input_indices->dataAt(batch, 0, seq, 0), 0), + inputs[1]->dtypeSize() * hiddenSize); + } + } + } + return MLLM_NO_ERROR; + } +}; + +class CPUFuyuGatherEmbdFuncCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new CPUFuyuGatherEmbdFunc(bn, name, threadCount); + } +}; + +} // namespace mllm +#endif // CPUFUYUGATHEREMBDFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUIndexPutFunc.hpp b/src/backends/cpu/op/CPUIndexPutFunc.hpp new file mode 100644 index 000000000..2013516c6 --- /dev/null +++ b/src/backends/cpu/op/CPUIndexPutFunc.hpp @@ -0,0 +1,148 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUINDEXPUTFUNC_HPP +#define CPUINDEXPUTFUNC_HPP +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include + +namespace mllm { +class Tensor; + +class CPUIndexPutFunction : public Op { +private: + int thread_count = 4; + bool accumulate_; + +public: + CPUIndexPutFunction(Backend *bn, string name, int threadCount, bool accumulate) + : Op(bn, name), thread_count(threadCount), accumulate_(accumulate) {} + + + ErrorCode setUp(vector> inputs, vector> outputs) override { + if (!accumulate_) { + if (inputs[0]->masterTensor() == nullptr) { + inputs[0]->free(); + } + outputs[0]->alloc(); + inputs[0]->shallowCopyFrom(outputs[0].get(), false); + } + return MLLM_NO_ERROR; + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + if (inputs.size() > 1 && inputs[1]->batch() == 0) { + outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), inputs[0]->dimension()); + if (!accumulate_) { + if (inputs[0]->masterTensor() == nullptr) { + inputs[0]->free(); + } + outputs[0]->alloc(); + inputs[0]->shallowCopyFrom(outputs[0].get(), false); + } + return MLLM_NO_ERROR; + } + // reshape + assert(inputs.size() == 3); + auto dest_input = inputs[0]; + auto src_input = inputs[1]; + assert(dest_input->batch() == 1); + assert(dest_input->head() == 1); + assert(src_input->head() == 1); + assert(dest_input->dimension() == src_input->dimension()); + + if (!accumulate_) { + outputs[0]->reshape(dest_input->batch(), dest_input->head(), dest_input->sequence(), dest_input->dimension()); + } else { + int origin_s = dest_input->sequence(); + int replace_s = src_input->sequence(); + int replace_size = src_input->batch(); + int seq = origin_s - replace_size + (replace_size * replace_s); + outputs[0]->reshape(dest_input->batch(), dest_input->head(), seq, dest_input->dimension()); + outputs[0]->alloc(); + } + + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + if (inputs.size() > 1 && inputs[1]->batch() == 0) { + return MLLM_NO_ERROR; + } + + assert(inputs.size() == 3); + auto dest_input = inputs[0]; + auto src_input = inputs[1]; + auto replace_idx = inputs[2]; + assert(replace_idx->batch() == 1); + assert(replace_idx->sequence() == 1); + assert(replace_idx->head() == 1); + if (!accumulate_) { + for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { + auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); + auto dst_ptr = inputs[0]->ptrAt(0, 0, replace_seq, 0); + auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); + memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); + } + } else if (replace_idx->dimension() == src_input->batch()) { + int replace_s = src_input->sequence(); + int replace_size = src_input->batch(); + auto start_dest_seq = 0; + int in0_d = 0; + int in1_batch = 0; +#pragma omp parallel for num_threads(CPUBackend::cpu_threads) + for (int i = 0; i < replace_size; ++i) { + auto start_src_seq = (int)replace_idx->dataAt(0, 0, 0, i) + (i * replace_s); + auto end_dest_seq = start_src_seq; + auto end_src_seq = start_src_seq + replace_s; + + auto dst_ptr = outputs[0]->ptrAt(0, 0, start_dest_seq, 0); + auto src_ptr = inputs[0]->ptrAt(0, 0, in0_d, 0); + memcpy(dst_ptr, src_ptr, sizeof(float) * dest_input->dimension() * (end_dest_seq - start_dest_seq)); + in0_d += end_dest_seq - start_dest_seq; + + dst_ptr = outputs[0]->ptrAt(0, 0, start_src_seq, 0); + src_ptr = inputs[1]->ptrAt(0, 0, 0, 0); + memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension() * replace_s); + in1_batch++; + in0_d += 1; + + start_dest_seq = end_src_seq; + } + auto dst_ptr = outputs[0]->ptrAt(0, 0, start_dest_seq, 0); + auto src_ptr = inputs[0]->ptrAt(0, 0, in0_d, 0); + memcpy(dst_ptr, src_ptr, sizeof(float) * dest_input->dimension() * (outputs[0]->sequence() - start_dest_seq)); + } else if (replace_idx->dimension() == src_input->sequence()) { + for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { + auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); + auto dst_ptr = outputs[0]->ptrAt(0, 0, replace_seq, 0); + auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); + memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); + } + } else { + for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { + auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); + auto dst_ptr = outputs[0]->ptrAt(0, 0, replace_seq, 0); + auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); + memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); + } + } + return MLLM_NO_ERROR; + } +}; + +class CPUIndexPutFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + bool accumulate = (bool)op_param.at("accumulate"); + return new CPUIndexPutFunction(bn, name, threadCount, accumulate); + } +}; + +} // namespace mllm +#endif // CPUINDEXPUTFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPULikeFunc.hpp b/src/backends/cpu/op/CPULikeFunc.hpp new file mode 100644 index 000000000..a93ae72b4 --- /dev/null +++ b/src/backends/cpu/op/CPULikeFunc.hpp @@ -0,0 +1,48 @@ +// +// Created by Rongjie Yi on 24-12-16. +// + +#ifndef CPULIKEFUNC_HPP +#define CPULIKEFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include + +namespace mllm { +class Tensor; + +class CPUlikeFunction : public Op { +private: + int thread_count = 4; + float like_value_; + +public: + CPUlikeFunction(Backend *bn, string name, int threadCount, float like_value) : + Op(bn, name), thread_count(threadCount), like_value_(like_value) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); // like_values + return ErrorCode::MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + memset(outputs[0]->hostPtr(), like_value_, outputs[0]->count() * sizeof(float)); + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUlikeFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam contains the key "like_value" + float like_value = op_param.at("like_value"); + return new CPUlikeFunction(bn, name, threadCount, like_value); + } +}; + +} // namespace mllm +#endif // CPULIKEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUMatmulFunc.hpp b/src/backends/cpu/op/CPUMatmulFunc.hpp new file mode 100644 index 000000000..241eec527 --- /dev/null +++ b/src/backends/cpu/op/CPUMatmulFunc.hpp @@ -0,0 +1,116 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUMATMULFUNC_HPP +#define CPUMATMULFUNC_HPP + +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include "../compute/Matmul.hpp" +#include +#include +#include +#include // For std::equal + +namespace mllm { +class Tensor; + +class CPUmmFunction : public Op { +private: + int thread_count = 4; + + static void tranTensorChl(Tensor &input) { + assert(input.ctype() == BSHD); + auto b = input.batch(); + auto h = input.head(); + auto d = input.dimension(); + auto s = input.sequence(); + auto ori_seq_idx = input.chls()[SEQUENCE]; + auto ori_head_idx = input.chls()[HEAD]; + auto ori_dim_idx = input.chls()[DIMENSION]; + input.chls()[HEAD] = ori_seq_idx; + input.chls()[DIMENSION] = ori_head_idx; + input.chls()[SEQUENCE] = ori_dim_idx; + input.changeCtype(); + input.reshape(b, h, s, d); + input.transed() = true; + input.undiffusion() = false; + // if no TENSOR_STATIC_SHAPED + if (input.masterTensor() != nullptr) { + auto b_m = input.masterTensor()->batch(); + auto h_m = input.masterTensor()->head(); + auto d_m = input.masterTensor()->dimension(); + auto s_m = input.masterTensor()->sequence(); + input.masterTensor()->chls() = input.chls(); + input.masterTensor()->changeCtype(); + input.masterTensor()->reshape(b_m, h_m, s_m, d_m); + for (auto &child : input.masterTensor()->childTensors()) { + auto b_c = child->batch(); + auto h_c = child->head(); + auto d_c = child->dimension(); + auto s_c = child->sequence(); + child->chls() = input.chls(); + child->changeCtype(); + child->reshape(b_c, h_c, s_c, d_c); + } + } else { + for (auto &child : input.childTensors()) { + auto b_c = child->batch(); + auto h_c = child->head(); + auto d_c = child->dimension(); + auto s_c = child->sequence(); + child->chls() = input.chls(); + child->changeCtype(); + child->reshape(b_c, h_c, s_c, d_c); + } + } + } + +public: + CPUmmFunction(Backend *bn, string name, int threadCount) + : Op(bn, name), thread_count(threadCount) {} + + + ErrorCode setUp(vector> inputs, vector> outputs) override { + if (inputs[1]->chls()[SEQUENCE] != 3) { + tranTensorChl(*inputs[1]); + } + if (!inputs[1]->shape().empty() && !inputs[0]->shape().empty()) { + assert(inputs[0]->dimension() == inputs[1]->sequence()); + } + outputs[0]->alloc(); + return MLLM_NO_ERROR; + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + if (inputs[1]->chls()[SEQUENCE] != 3) { + tranTensorChl(*inputs[1]); + assert(inputs[1]->chls()[SEQUENCE] == 3); + } + assert(inputs[0]->dimension() == inputs[1]->sequence()); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[1]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + bool isSame = std::equal(inputs[0]->chls().begin(), inputs[0]->chls().end(), inputs[1]->chls().begin()); + assert(inputs[0]->dtype() == MLLM_TYPE_F32); + mat_mul(inputs[0].get(), inputs[1].get(), outputs[0].get(), false, nullptr, false, isSame, thread_count); + return MLLM_NO_ERROR; + } +}; + +class CPUmmFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new CPUmmFunction(bn, name, threadCount); + } +}; + +} // namespace mllm +#endif // CPUMATMULFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUMeanFunc.hpp b/src/backends/cpu/op/CPUMeanFunc.hpp new file mode 100644 index 000000000..efc3f8bcf --- /dev/null +++ b/src/backends/cpu/op/CPUMeanFunc.hpp @@ -0,0 +1,140 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUMEANFUNC_HPP +#define CPUMEANFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include + +namespace mllm { +class Tensor; + +class CPUmeanFunction : public Op { +private: + int thread_count = 4; + Chl axis_; + +public: + CPUmeanFunction(Backend *bn, string name, int threadCount, Chl axis) + : Op(bn, name), thread_count(threadCount), axis_(axis) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + int batch = inputs[0]->batch(); + int head = inputs[0]->head(); + int sequence = inputs[0]->sequence(); + int dimension = inputs[0]->dimension(); + switch (axis_) { + case BATCH: + batch = 1; + break; + case HEAD: + head = 1; + break; + case SEQUENCE: + sequence = 1; + break; + case DIMENSION: + dimension = 1; + break; + default: + break; + } + outputs[0]->reshape(batch, head, sequence, dimension); + outputs[0]->setDtype(inputs[0]->dtype()); + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + int batch = inputs[0]->batch(); + int dim = inputs[0]->dimension(); + int seq = inputs[0]->sequence(); + int head = inputs[0]->head(); + + // Note: OpenMP might be beneficial here for larger tensors. + // Adding it would be an optimization over the original direct translation. + + switch (axis_) { + case BATCH: { + for (int h = 0; h < head; h++) { + for (int s = 0; s < seq; ++s) { + for (int d = 0; d < dim; d++) { + float sum = 0.0f; + for (int n = 0; n < batch; n++) { + sum += inputs[0]->dataAt(n, h, s, d); + } + // Bug fix: was sum / seq, should be sum / batch + outputs[0]->setDataAt(0, h, s, d, sum / batch); + } + } + } + break; + } + case HEAD: { + for (int n = 0; n < batch; n++) { + for (int s = 0; s < seq; ++s) { + for (int d = 0; d < dim; d++) { + float sum = 0.0f; + for (int h = 0; h < head; h++) { + sum += inputs[0]->dataAt(n, h, s, d); + } + // Bug fix: was sum / seq, should be sum / head + outputs[0]->setDataAt(n, 0, s, d, sum / head); + } + } + } + break; + } + case SEQUENCE: { + for (int n = 0; n < batch; n++) { + for (int h = 0; h < head; h++) { + for (int d = 0; d < dim; d++) { + float sum = 0.0f; + for (int s = 0; s < seq; ++s) { + sum += inputs[0]->dataAt(n, h, s, d); + } + // This was correct + outputs[0]->setDataAt(n, h, 0, d, sum / seq); + } + } + } + break; + } + case DIMENSION: { + for (int n = 0; n < batch; n++) { + for (int h = 0; h < head; h++) { + for (int s = 0; s < seq; s++) { + float sum = 0.0f; + for (int d = 0; d < dim; ++d) { + sum += inputs[0]->dataAt(n, h, s, d); + } + // This was correct + outputs[0]->setDataAt(n, h, s, 0, sum / dim); + } + } + } + break; + } + default: + break; + } + return MLLM_NO_ERROR; + } +}; + +class CPUmeanFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam contains the key "axis" + Chl axis = (Chl)op_param.at("axis"); + return new CPUmeanFunction(bn, name, threadCount, axis); + } +}; + +} // namespace mllm +#endif // CPUMEANFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUNormFunc.hpp b/src/backends/cpu/op/CPUNormFunc.hpp new file mode 100644 index 000000000..864afa865 --- /dev/null +++ b/src/backends/cpu/op/CPUNormFunc.hpp @@ -0,0 +1,80 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUNORMFUNC_HPP +#define CPUNORMFUNC_HPP + +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include // For std::sqrt and std::abs +#include + +namespace mllm { +class Tensor; + +class CPUnormFunction : public Op { +private: + int thread_count = 4; + int L_n_; + +public: + CPUnormFunction(Backend *bn, string name, int threadCount, int L_n) + : Op(bn, name), thread_count(threadCount), L_n_(L_n) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + // Parallelize the outer loops for better efficiency + #pragma omp parallel for collapse(3) num_threads(thread_count) + for (int n = 0; n < inputs[0]->batch(); n++) { + for (int h = 0; h < inputs[0]->head(); h++) { + for (int s = 0; s < inputs[0]->sequence(); s++) { + if (L_n_ == 2) { // L2 Norm + float sum_of_squares = 0.0f; + for (int d = 0; d < inputs[0]->dimension(); ++d) { + float val = inputs[0]->dataAt(n, h, s, d); + sum_of_squares += val * val; + } + float l2_norm = std::sqrt(sum_of_squares); + + // Broadcast the norm value across the dimension + for (int d = 0; d < inputs[0]->dimension(); d++) { + outputs[0]->setDataAt(n, h, s, d, l2_norm); + } + } else { // L1 Norm (or other) + float sum_of_abs_values = 0.0f; + for (int d = 0; d < inputs[0]->dimension(); ++d) { + sum_of_abs_values += std::abs(inputs[0]->dataAt(n, h, s, d)); + } + + // Broadcast the norm value across the dimension + for (int d = 0; d < inputs[0]->dimension(); d++) { + outputs[0]->setDataAt(n, h, s, d, sum_of_abs_values); + } + } + } + } + } + return MLLM_NO_ERROR; + } +}; + +class CPUnormFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam contains the key "L_n" + int L_n = static_cast(op_param.at("L_n")); + return new CPUnormFunction(bn, name, threadCount, L_n); + } +}; + +} // namespace mllm +#endif // CPUNORMFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUPhi3VhdmergeFunc.hpp b/src/backends/cpu/op/CPUPhi3VhdmergeFunc.hpp new file mode 100644 index 000000000..61e1f06a8 --- /dev/null +++ b/src/backends/cpu/op/CPUPhi3VhdmergeFunc.hpp @@ -0,0 +1,102 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUPHI3VHDMERGEEFUNC_HPP +#define CPUPHI3VHDMERGEEFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include // For std::sqrt + +namespace mllm { +class Tensor; + +class CPUPhi3VhdmergeFunction : public Op { +private: + int thread_count = 4; + int h_crop_; + int w_crop_; + +public: + CPUPhi3VhdmergeFunction(Backend *bn, string name, int threadCount, int h_crop, int w_crop) + : Op(bn, name), thread_count(threadCount), h_crop_(h_crop), w_crop_(w_crop) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + int N = inputs[0]->batch(); + int L = inputs[0]->sequence(); + int C = inputs[0]->dimension(); + assert(L == 24 * 24); + assert(C == 1024); + assert(N % (h_crop_ * w_crop_) == 0); + + int num_images = N / (h_crop_ * w_crop_); + int H = static_cast(std::sqrt(L)); + + int b = num_images; + int s = h_crop_ * H / 2; + int h = w_crop_ * H / 2; + int d = 4 * C; + + outputs[0]->reshape(b, h, s, d); + outputs[0]->setDtype(inputs[0]->dtype()); + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + int N = inputs[0]->batch(); + int L = inputs[0]->sequence(); + int C = inputs[0]->dimension(); + int num_images = N / (h_crop_ * w_crop_); + int H = static_cast(std::sqrt(L)); + + int b = num_images; + int s = h_crop_ * H / 2; + int h = w_crop_ * H / 2; + int d = 4 * C; + + #pragma omp parallel for collapse(3) num_threads(thread_count) + for (int ob = 0; ob < b; ob++) { + for (int os = 0; os < s; os++) { + for (int oh = 0; oh < h; oh++) { + int base_s = ((oh / 12) * (24 * 24)) + (os * 48) + (2 * (oh % 12)); + int hed = base_s % L; + int btch = (ob * (h_crop_ * w_crop_)) + (base_s / L); + + auto i_ptr_0 = inputs[0]->ptrAt(btch, 0, hed, 0); + auto i_ptr_1 = inputs[0]->ptrAt(btch, 0, hed + 1, 0); + auto i_ptr_2 = inputs[0]->ptrAt(btch, 0, hed + 24, 0); + auto i_ptr_3 = inputs[0]->ptrAt(btch, 0, hed + 25, 0); + + size_t copy_size = (size_t)C * inputs[0]->dtypeSize(); + + memcpy(outputs[0]->ptrAt(ob, oh, os, 0), + i_ptr_0, copy_size); + memcpy(outputs[0]->ptrAt(ob, oh, os, C), + i_ptr_1, copy_size); + memcpy(outputs[0]->ptrAt(ob, oh, os, C * 2), + i_ptr_2, copy_size); + memcpy(outputs[0]->ptrAt(ob, oh, os, C * 3), + i_ptr_3, copy_size); + } + } + } + return MLLM_NO_ERROR; + } +}; + +class CPUPhi3VhdmergeFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + int h_crop = static_cast(op_param.at("h_crop")); + int w_crop = static_cast(op_param.at("w_crop")); + return new CPUPhi3VhdmergeFunction(bn, name, threadCount, h_crop, w_crop); + } +}; + +} // namespace mllm +#endif // CPUPHI3VHDMERGEEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPURangeFunc.hpp b/src/backends/cpu/op/CPURangeFunc.hpp new file mode 100644 index 000000000..0e9da6aa6 --- /dev/null +++ b/src/backends/cpu/op/CPURangeFunc.hpp @@ -0,0 +1,57 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPURANGEFUNC_HPP +#define CPURANGEFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include + +namespace mllm { +class Tensor; + +class CPURangeFunction : public Op { +private: + int thread_count = 4; + int start_; + int end_; + +public: + CPURangeFunction(Backend *bn, string name, int threadCount, int start, int end) + : Op(bn, name), thread_count(threadCount), start_(start), end_(end) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + outputs[0]->reshape(1, 1, end_ - start_, 1); + outputs[0]->setDtype(MLLM_TYPE_F32); + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + int length = end_ - start_; + #pragma omp parallel for num_threads(thread_count) + for (int i = 0; i < length; ++i) { + // Bug fix: Index should be 'i', value should be 'start_ + i'. + // Original code had `setDataAt(..., i + start_, ..., (float)i)`, which was incorrect. + outputs[0]->setDataAt(0, 0, i, 0, (float)(start_ + i)); + } + return MLLM_NO_ERROR; + } +}; + +class CPURangeFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam contains keys "start" and "end" + int start = static_cast(op_param.at("start")); + int end = static_cast(op_param.at("end")); + return new CPURangeFunction(bn, name, threadCount, start, end); + } +}; + +} // namespace mllm +#endif // CPURANGEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPURepeatFunc.hpp b/src/backends/cpu/op/CPURepeatFunc.hpp new file mode 100644 index 000000000..6c361108f --- /dev/null +++ b/src/backends/cpu/op/CPURepeatFunc.hpp @@ -0,0 +1,106 @@ +// +// Created by Rongjie Yi on 24-12-16. +// + +#ifndef CPUREPEATEFUNC_HPP +#define CPUREPEATEFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include +// #include +#include + +namespace mllm { +class Tensor; + +class CPUrepeatFunction : public Op { +private: + int thread_count = 4; + Chl dim_; + int size_; + +public: + CPUrepeatFunction(Backend *bn, string name, int threadCount, Chl dim, int size) + : Op(bn, name), thread_count(threadCount), dim_(dim), size_(size) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + int batch = inputs[0]->batch(); + int head = inputs[0]->head(); + int sequence = inputs[0]->sequence(); + int dimension = inputs[0]->dimension(); + + switch (dim_) { + case Chl::BATCH: + batch = size_; + break; + case Chl::HEAD: + head = size_; + break; + case Chl::SEQUENCE: + sequence = size_; + break; + case Chl::DIMENSION: + dimension = size_; + break; + default: + break; + } + + outputs[0]->reshape(batch, head, sequence, dimension); + outputs[0]->setDtype(inputs[0]->dtype()); + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + switch (dim_) { + case Chl::BATCH: { + std::cerr << "Repeat Not implemented for BATCH" << std::endl; + break; + } + case Chl::HEAD: { + std::cerr << "Repeat Not implemented for HEAD" << std::endl; + break; + } + case Chl::SEQUENCE: { + std::cerr << "Repeat Not implemented for SEQUENCE" << std::endl; + break; + } + case Chl::DIMENSION: { +#pragma omp parallel for collapse(3) num_threads(thread_count) + for (int b = 0; b < inputs[0]->batch(); b++) { + for (int h = 0; h < inputs[0]->head(); h++) { + for (int s = 0; s < inputs[0]->sequence(); s++) { + // Assuming the input dimension to repeat is 1 + float data = inputs[0]->dataAt(b, h, s, 0); + for (int d = 0; d < size_; d++) { + outputs[0]->setDataAt(b, h, s, d, data); + } + } + } + } + break; + } + default: + break; + } + return MLLM_NO_ERROR; + } +}; + +class CPUrepeatFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam contains keys "dim" and "size" + Chl dim = (Chl)op_param.at("dim"); + int size = static_cast(op_param.at("size")); + return new CPUrepeatFunction(bn, name, threadCount, dim, size); + } +}; + +} // namespace mllm +#endif // CPUREPEATEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUScatterReduceFunc.hpp b/src/backends/cpu/op/CPUScatterReduceFunc.hpp new file mode 100644 index 000000000..7079ff63a --- /dev/null +++ b/src/backends/cpu/op/CPUScatterReduceFunc.hpp @@ -0,0 +1,67 @@ +// +// Created by Rongjie Yi on 24-12-26. +// + +#ifndef CPUSCATTERREDUCEFUNC_HPP +#define CPUSCATTERREDUCEFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include "../compute/Arithmetic.hpp" +#include + +namespace mllm { +class Tensor; + +class CPUScatterReduceFunction : public Op { +private: + int thread_count = 4; + +public: + CPUScatterReduceFunction(Backend *bn, string name, int threadCount) : + Op(bn, name), thread_count(threadCount) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + if (inputs[1]->batch() == 0) { + return MLLM_NO_ERROR; + } + assert(inputs.size() == 3); + assert(inputs[0]->batch() == 1); + assert(inputs[0]->head() == 1); + auto dest_input = inputs[0]; + auto src_input = inputs[1]; + auto replace_idx = inputs[2]; + assert(replace_idx->batch() == 1); + assert(replace_idx->sequence() == 1); + assert(replace_idx->head() == 1); + // #pragma omp parallel for num_threads(CPUBackend::cpu_threads) + for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { + auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); + auto dst_ptr = dest_input->ptrAt(0, 0, replace_seq, 0); + auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); + // memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); + float tmp[src_input->dimension()]; + memcpy(tmp, dst_ptr, sizeof(float) * dest_input->dimension()); + mllm_add_fp32(tmp, + src_ptr, + dst_ptr, dest_input->dimension()); + } + return MLLM_NO_ERROR; + } +}; + +class CPUScatterReduceFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new CPUScatterReduceFunction(bn, name, threadCount); + } +}; + +} // namespace mllm +#endif // CPUSCATTERREDUCEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUSplitFunc.hpp b/src/backends/cpu/op/CPUSplitFunc.hpp new file mode 100644 index 000000000..9c1d558c5 --- /dev/null +++ b/src/backends/cpu/op/CPUSplitFunc.hpp @@ -0,0 +1,206 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUSPLITFUNC_HPP +#define CPUSPLITFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include "../compute/Split.hpp" +#include +#include + +namespace mllm { +class Tensor; + +class CPUsplitFunction : public Op { +private: + int thread_count = 4; + std::vector each_dims_; + Chl split_dim_; + int head_size_; + +public: + CPUsplitFunction(Backend *bn, string name, int threadCount, + const std::vector& each_dims, Chl split_dim, int head_size) + : Op(bn, name), thread_count(threadCount), each_dims_(each_dims), + split_dim_(split_dim), head_size_(head_size) {} + + ErrorCode setUp(vector> inputs, vector> outputs) override { + int split_num_ = each_dims_.size(); + // store each dims + int split_dim_size_ = 0; + for (size_t i = 0; i < each_dims_.size(); ++i) { + split_dim_size_ += each_dims_[i]; + } + assert(split_num_ == outputs.size()); + switch (split_dim_) { + case Chl::HEAD: { + // assert(inputs[0]->head() == split_dim_size_); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), each_dims_[i], inputs[0]->sequence(), inputs[0]->dimension()); + } + break; + } + case Chl::SEQUENCE: { + // assert(inputs[0]->sequence() == split_dim_size_); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), each_dims_[i], inputs[0]->dimension()); + } + break; + } + case Chl::DIMENSION: { + // assert(inputs[0]->dimension() == split_dim_size_); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), each_dims_[i]); + } + break; + } + case Chl::D_HD: { + // assert(inputs[0]->dimension() == split_dim_size_ * head_size); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), head_size_, inputs[0]->sequence(), each_dims_[i]); + } + break; + } + case Chl::HD: { + // assert(inputs[0]->dimension() == split_dim_size_ * head_size); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), head_size_, inputs[0]->sequence(), each_dims_[i]); + } + break; + } + default: { + break; + } + } + if (inputs[0]->allowAggregated()) { + vector> shared_outputs = {}; + for (const auto &output : outputs) { + output->alloc(); + shared_outputs.push_back(output); + } + if (inputs[0]->masterTensor() == nullptr && !inputs[0]->childTensors().empty()) { + inputs[0]->free(); + } + inputs[0]->addTensors(shared_outputs, split_dim_); + } + return MLLM_NO_ERROR; + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + int split_num_ = each_dims_.size(); + // store each dims + int split_dim_size_ = 0; + for (size_t i = 0; i < each_dims_.size(); ++i) { + split_dim_size_ += each_dims_[i]; + } + assert(split_num_ == outputs.size()); + switch (split_dim_) { + case Chl::HEAD: { + // assert(inputs[0]->head() == split_dim_size_); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), each_dims_[i], inputs[0]->sequence(), inputs[0]->dimension()); + } + break; + } + case Chl::SEQUENCE: { + // assert(inputs[0]->sequence() == split_dim_size_); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), each_dims_[i], inputs[0]->dimension()); + } + break; + } + case Chl::DIMENSION: { + // assert(inputs[0]->dimension() == split_dim_size_); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), each_dims_[i]); + } + break; + } + case Chl::D_HD: { + // assert(inputs[0]->dimension() == split_dim_size_ * head_size); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), head_size_, inputs[0]->sequence(), each_dims_[i]); + } + break; + } + case Chl::HD: { + // assert(inputs[0]->dimension() == split_dim_size_ * head_size); + for (int i = 0; i < split_num_; i++) { + outputs[i]->reshape(inputs[0]->batch(), head_size_, inputs[0]->sequence(), each_dims_[i]); + } + break; + } + default: { + break; + } + } + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + // This path is taken only if the memory aggregation in setUp was not performed. + if (inputs[0]->aggregatedTensors().empty()) { + std::vector out_pointers; + assert(each_dims_.size() == outputs.size()); + for (const auto& output : outputs) { + // Ensure output is allocated if not already + if(output->hostPtr() == nullptr) { + output->alloc(); + } + out_pointers.push_back(output->ptrAt(0, 0, 0, 0)); + } + const int origin_dims[4] = {inputs[0]->batch(), inputs[0]->sequence(), inputs[0]->head(), inputs[0]->dimension()}; + + efficient_split(inputs[0]->ptrAt(0, 0, 0, 0), + origin_dims, + out_pointers, + each_dims_, + split_dim_); + } + + if (inputs[0]->aggregatedTensors().empty()) { + // int size = args_.size(); + std::vector out_pointers; + // assert(size - 2 == outputs.size()); + for (int i = 0; i < outputs.size(); i++) { + // each_dims_.push_back(args[i]); + out_pointers.push_back(outputs[i]->ptrAt(0, 0, 0, 0)); + } + // Chl split_dim = (Chl)args[size - 2]; + // int head_size = (int)args[size - 1]; + int split_num_ = each_dims_.size(); + const int origin_dims[4] = {inputs[0]->batch(), inputs[0]->sequence(), inputs[0]->head(), inputs[0]->dimension()}; + efficient_split(inputs[0]->ptrAt(0, 0, 0, 0), + origin_dims, + out_pointers, + each_dims_, + split_dim_); + } + + return MLLM_NO_ERROR; + } +}; + +class CPUsplitFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam is structured to pass the split parameters. + // Example: {"num_splits": 2, "dim_0": 64, "dim_1": 64, "split_dim": 3, "head_size": 12} + int num_splits = static_cast(op_param.at("num_splits")); + std::vector each_dims; + for (int i = 0; i < num_splits; ++i) { + each_dims.push_back(static_cast(op_param.at("dim_" + std::to_string(i)))); + } + Chl split_dim = (Chl)op_param.at("split_dim"); + int head_size = static_cast(op_param.at("head_size")); + + return new CPUsplitFunction(bn, name, threadCount, each_dims, split_dim, head_size); + } +}; + +} // namespace mllm +#endif // CPUSPLITFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUSumFunc.hpp b/src/backends/cpu/op/CPUSumFunc.hpp new file mode 100644 index 000000000..afda1431e --- /dev/null +++ b/src/backends/cpu/op/CPUSumFunc.hpp @@ -0,0 +1,133 @@ +// +// Created by Rongjie Yi on 24-12-16. +// + +#ifndef CPUSUMFUNC_HPP +#define CPUSUMFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +// #include +#include + +namespace mllm { +class Tensor; + +class CPUsumFunction : public Op { +private: + int thread_count = 4; + Chl axis_; + +public: + CPUsumFunction(Backend *bn, string name, int threadCount, Chl axis) : + Op(bn, name), thread_count(threadCount), axis_(axis) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + int batch = inputs[0]->batch(); + int head = inputs[0]->head(); + int sequence = inputs[0]->sequence(); + int dimension = inputs[0]->dimension(); + switch (axis_) { + case BATCH: + batch = 1; + break; + case HEAD: + head = 1; + break; + case SEQUENCE: + sequence = 1; + break; + case DIMENSION: + dimension = 1; + break; + default: + break; + } + outputs[0]->reshape(batch, head, sequence, dimension); + outputs[0]->setDtype(inputs[0]->dtype()); + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + int batch = inputs[0]->batch(); + int dim = inputs[0]->dimension(); + int seq = inputs[0]->sequence(); + int head = inputs[0]->head(); + switch (axis_) { + case BATCH: { + for (int h = 0; h < head; h++) { + for (int s = 0; s < seq; ++s) { + for (int d = 0; d < dim; d++) { + float sum = 0.0f; + for (int n = 0; n < batch; n++) { + sum += inputs[0]->dataAt(n, h, s, d); + } + outputs[0]->setDataAt(0, h, s, d, sum); + } + } + } + break; + } + case HEAD: { + for (int n = 0; n < batch; n++) { + for (int s = 0; s < seq; ++s) { + for (int d = 0; d < dim; d++) { + float sum = 0.0f; + for (int h = 0; h < head; h++) { + sum += inputs[0]->dataAt(n, h, s, d); + } + outputs[0]->setDataAt(n, 0, s, d, sum); + } + } + } + break; + } + case SEQUENCE: { + for (int n = 0; n < batch; n++) { + for (int h = 0; h < head; h++) { + for (int d = 0; d < dim; d++) { + float sum = 0.0f; + for (int s = 0; s < seq; ++s) { + sum += inputs[0]->dataAt(n, h, s, d); + } + outputs[0]->setDataAt(n, h, 0, d, sum); + } + } + } + break; + } + case DIMENSION: { + for (int n = 0; n < batch; n++) { + for (int h = 0; h < head; h++) { + for (int s = 0; s < seq; s++) { + float sum = 0.0f; + for (int d = 0; d < inputs[0]->dimension(); ++d) { + sum += inputs[0]->dataAt(n, h, s, d); + } + outputs[0]->setDataAt(n, h, s, 0, sum); + } + } + } + break; + } + default: + break; + } + return MLLM_NO_ERROR; + } +}; + +class CPUsumFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + Chl axis = (Chl)op_param.at("dim"); + return new CPUsumFunction(bn, name, threadCount, axis); + } +}; + +} // namespace mllm +#endif // CPUSUMFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUTopkFunc.hpp b/src/backends/cpu/op/CPUTopkFunc.hpp new file mode 100644 index 000000000..f3193e4f3 --- /dev/null +++ b/src/backends/cpu/op/CPUTopkFunc.hpp @@ -0,0 +1,87 @@ +// +// Created by Rongjie Yi on 24-12-16. +// + +#ifndef CPUTOPKFUNC_HPP +#define CPUTOPKFUNC_HPP + +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include +#include +#include +#include + +namespace mllm { +class Tensor; + +class CPUtopkFunction : public Op { +private: + int thread_count = 4; + int k_; + Chl dim_; + +public: + CPUtopkFunction(Backend *bn, string name, int threadCount, int k, Chl dim) : + Op(bn, name), thread_count(threadCount), k_(k), dim_(dim) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + assert(outputs.size() == 2); // topk returns values and indices + if (dim_ == DIMENSION) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), k_); + outputs[1]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), k_); + } + // NOTE: Add cases for other dimensions if needed. + + outputs[0]->setDtype(inputs[0]->dtype()); // topk_values + outputs[1]->setDtype(inputs[0]->dtype()); // topk_indices are typically int, but float is used here + + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + // outputs[1]->alloc(); + + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + if (dim_ == DIMENSION) { +#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) + for (int n = 0; n < inputs[0]->batch(); n++) { + for (int h = 0; h < inputs[0]->head(); h++) { + for (int s = 0; s < inputs[0]->sequence(); s++) { + std::priority_queue, std::vector>, std::greater<>> topk_value_indices; + for (int d = 0; d < inputs[0]->dimension(); ++d) { + float value = inputs[0]->dataAt(n, h, s, d); + topk_value_indices.push({value, d}); + if (topk_value_indices.size() > k_) { + topk_value_indices.pop(); + } + } + for (int d = k_ - 1; d >= 0; --d) { + auto top = topk_value_indices.top(); + topk_value_indices.pop(); + outputs[0]->setDataAt(n, h, s, d, top.first); + outputs[1]->setDataAt(n, h, s, d, top.second); + } + } + } + } + } + // NOTE: Add cases for other dimensions if needed. + return MLLM_NO_ERROR; + } +}; + +class CPUtopkFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + int k = static_cast(op_param.at("k")); + Chl dim = (Chl)op_param.at("dim"); + return new CPUtopkFunction(bn, name, threadCount, k, dim); + } +}; + +} // namespace mllm +#endif // CPUTOPKFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUTransposeFunc.hpp b/src/backends/cpu/op/CPUTransposeFunc.hpp new file mode 100644 index 000000000..6813182ed --- /dev/null +++ b/src/backends/cpu/op/CPUTransposeFunc.hpp @@ -0,0 +1,182 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUTRANSPOSEFUNC_HPP +#define CPUTRANSPOSEFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +// #include "Module.hpp" +#include "CPUBackend.hpp" +#include "compute/Quantize.hpp" +#include +// #include +#include +#include +#include // For std::pair +#include // For std::equal + +namespace mllm { +class Tensor; + +class CPUtransposeFunction : public Op { +private: + int thread_count = 4; + vector> axiss_; + +public: + CPUtransposeFunction(Backend *bn, string name, int threadCount, const vector>& axiss) + : Op(bn, name), thread_count(threadCount), axiss_(axiss) {} + + + ErrorCode setUp(vector> inputs, vector> outputs) override { + // for BSHD attention start + if(axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { + if(inputs[0]->ctype() == BSHD){ + outputs[0]->chls() = {{BATCH, 0}, {HEAD, 1}, {SEQUENCE, 2}, {DIMENSION, 3}}; + } else { + outputs[0]->chls() = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}}; + } + outputs[0]->changeCtype(4); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + return MLLM_NO_ERROR; + } + // for BSHD attention end + + if (!outputs[0]->undiffusion()) { + outputs[0]->transCopyShape(inputs[0]->shape()); + std::map origin_chls = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; + if (std::equal(outputs[0]->chls().begin(), outputs[0]->chls().end(), origin_chls.begin())) { + outputs[0]->chls() = inputs[0]->chls(); + for (auto axis : axiss_) { + auto axis0 = axis.first; + auto axis1 = axis.second; + auto ori_0_idx = outputs[0]->chls()[axis0]; + auto ori_1_idx = outputs[0]->chls()[axis1]; + outputs[0]->chls()[axis0] = ori_1_idx; + outputs[0]->chls()[axis1] = ori_0_idx; + } + outputs[0]->changeCtype(inputs[0]->shape().size()); + outputs[0]->undiffusion() = true; + } + } + + if (inputs[0]->masterTensor() != nullptr && (inputs[0]->masterTensor()->name().find("Cache") != std::string::npos || inputs[0]->masterTensor()->name().find("weight") != std::string::npos)) { + if (outputs[0]->masterTensor() == nullptr) { + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->shallowCopyFrom(inputs[0].get(), false); + } + } else { + if (inputs[0]->masterTensor() == nullptr) { + inputs[0]->free(); + } + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + inputs[0]->setUndiffusion(true); + inputs[0]->shallowCopyFrom(outputs[0].get(), false); + outputs[0]->transFrom() = axiss_; + } + return MLLM_NO_ERROR; + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + // for BSHD attention start + if(axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { + outputs[0]->transCopyShape(inputs[0]->shape()); + outputs[0]->chls() = inputs[0]->chls(); + std::swap(outputs[0]->chls()[HEAD], outputs[0]->chls()[SEQUENCE]); + outputs[0]->changeCtype(inputs[0]->shape().size()); + return MLLM_NO_ERROR; + } + // for BSHD attention end + + std::map origin_chls = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; + auto origin_s = inputs[0]->shape().size(); + outputs[0]->transCopyShape(inputs[0]->shape()); + + if (inputs[0]->masterTensor() == nullptr || std::equal(outputs[0]->chls().begin(), outputs[0]->chls().end(), origin_chls.begin())) { + outputs[0]->chls() = inputs[0]->chls(); + for (auto axis : axiss_) { + auto axis0 = axis.first; + auto axis1 = axis.second; + std::swap(outputs[0]->chls()[axis0], outputs[0]->chls()[axis1]); + } + outputs[0]->changeCtype(origin_s); + outputs[0]->undiffusion() = true; + } + + if (inputs[0]->masterTensor() != nullptr && (inputs[0]->masterTensor()->name().find("Cache") != std::string::npos || inputs[0]->masterTensor()->name().find("weight") != std::string::npos)) { + if (outputs[0]->masterTensor() == nullptr) { + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->shallowCopyFrom(inputs[0].get(), false); + } + } + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + // for BSHD attention start + if(axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { + // This is a physical transpose, allocate and copy + if (outputs[0]->hostPtr() == nullptr) { + outputs[0]->alloc(); + } + //BSHD -> BHSD (transpose S and H) + if (true) { //真转置 + assert(inputs[0]->batch() == 1); + assert(outputs[0]->batch() == 1); + // After reshape, H and S dimensions are swapped in the output tensor's shape + assert(inputs[0]->head() == outputs[0]->sequence()); + assert(inputs[0]->sequence() == outputs[0]->head()); + + if(inputs[0]->dtype() == outputs[0]->dtype()){ + #pragma omp parallel for num_threads(thread_count) + for (int h = 0; h < inputs[0]->head(); ++h) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); + // Swap h and s for output access + auto output_ptr = outputs[0]->ptrAt(0, s, h, 0); + memcpy(output_ptr, input_ptr, inputs[0]->dimension() * inputs[0]->dtypeSize()); + } + } + } else { // With quantization + #pragma omp parallel for num_threads(thread_count) + for (int h = 0; h < inputs[0]->head(); ++h) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); + // Swap h and s for output access + auto output_ptr = outputs[0]->ptrAt(0, s, h, 0); + for (int d = 0; d < inputs[0]->dimension(); ++d) { + output_ptr[d] = MLLM_FP32_TO_FP16(input_ptr[d]); + } + } + } + } + } + } + // for BSHD attention end + // Note: The general transpose case is handled by metadata changes in reshape/setUp + // and does not require data movement in execute. + return MLLM_NO_ERROR; + } +}; + +class CPUtransposeFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam is structured to pass the axis pairs. + // Example: {"num_pairs": 1, "axis1_0": 2, "axis2_0": 1} (HEAD, SEQUENCE) + int num_pairs = static_cast(op_param.at("num_pairs")); + vector> axiss; + for (int i = 0; i < num_pairs; ++i) { + Chl axis1 = (Chl)op_param.at("axis1_" + std::to_string(i)); + Chl axis2 = (Chl)op_param.at("axis2_" + std::to_string(i)); + axiss.push_back({axis1, axis2}); + } + return new CPUtransposeFunction(bn, name, threadCount, axiss); + } +}; + +} // namespace mllm +#endif // CPUTRANSPOSEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUViewFunc.hpp b/src/backends/cpu/op/CPUViewFunc.hpp new file mode 100644 index 000000000..333211a67 --- /dev/null +++ b/src/backends/cpu/op/CPUViewFunc.hpp @@ -0,0 +1,147 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUVIEWFUNC_HPP +#define CPUVIEWFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include +#include + +namespace mllm { +class Tensor; + +class CPUviewFunction : public Op { +private: + int thread_count = 4; + int b, h, s, d; + +public: + CPUviewFunction(Backend *bn, string name, int threadCount, int b_, int h_, int s_, int d_) + : Op(bn, name), thread_count(threadCount), b(b_), h(h_), s(s_), d(d_) {} + + + ErrorCode setUp(vector> inputs, vector> outputs) override { + if ((b == -1 && s == -1 && inputs[0]->ctype() != BCTHW) // head & dimension + || (b == 1 && h == 1 && inputs[0]->ctype() == BCTHW) // head & dimension + || (b == 1 && h == 1 && inputs[0]->ctype() == BSHD) // head & dimension + || (b == -1 && d == -1 && inputs[0]->ctype() == BSHD) // head & sequence + || (h == -1 && d == -1 && inputs[0]->ctype() == BSHD) // batch & sequence + || (b == -1 && h == 1 && s == 1 && d == -1 && inputs[0]->ctype() == BSHD) // sequence & head & dimension -> dimension + || (b == -1 && h == -1 && s == 1 && d == 1 && inputs[0]->ctype() == BSHD) // sequence & head & dimension -> sequence + ) { + if (inputs[0]->masterTensor() == nullptr) { + inputs[0]->free(); + } + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + inputs[0]->shallowCopyFrom(outputs[0].get(), false); + } else { + std::cout << "[TODO]Tensor.View alloc not support!!!!" << std::endl; + } + return MLLM_NO_ERROR; + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + int dim_b = inputs[0]->batch(); + int dim_h = inputs[0]->head(); + int dim_s = inputs[0]->sequence(); + int dim_d = inputs[0]->dimension(); + if (b == -1 && h == 1 && s == 1 && d == -1) { // sequence & head & dimension -> dimension + dim_s = 1; + dim_h = 1; + dim_d = inputs[0]->sequence() * inputs[0]->head() * inputs[0]->dimension(); + } else if (b == -1 && h == -1 && s == 1 && d == 1) { // sequence & head & dimension -> sequence + dim_s = inputs[0]->sequence() * inputs[0]->head() * inputs[0]->dimension(); + dim_h = 1; + dim_d = 1; + } else if (b == 1 && h == 1 && s == -1 && d != -1 && inputs[0]->ctype() == BCTHW) { // batch & head & sequence -> sequence + dim_b = 1; + dim_s = inputs[0]->channel() * inputs[0]->time() * inputs[0]->batch() * inputs[0]->height() * inputs[0]->width() / d; + dim_h = 1; + dim_d = d; + } else if (b == 1 && h == 1 && s == -1 && d != -1) { // batch & head & sequence -> sequence + dim_b = 1; + dim_s = inputs[0]->sequence() * inputs[0]->batch() * inputs[0]->head() * inputs[0]->dimension() / d; + dim_h = 1; + dim_d = d; + } else if (b == -1 && h != -1 && s == -1 && d != -1) { // head & dimension + if (h != ANYDIM && d != ANYDIM) { + assert(inputs[0]->dimension() * inputs[0]->head() == h * d); + dim_h = h; + dim_d = d; + } else if (h != ANYDIM) { + dim_h = h; + dim_d = inputs[0]->dimension() * inputs[0]->head() / h; + } else if (d != ANYDIM) { + dim_h = inputs[0]->dimension() * inputs[0]->head() / d; + dim_d = d; + } else { + std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + } + } else if (b == -1 && h != -1 && s != -1 && d == -1) { // head & sequence + if (h != ANYDIM && s != ANYDIM) { + assert(inputs[0]->sequence() * inputs[0]->head() == h * s); + dim_h = h; + dim_s = s; + } else if (h != ANYDIM) { + dim_h = h; + dim_s = inputs[0]->sequence() * inputs[0]->head() / h; + } else if (s != ANYDIM) { + dim_h = inputs[0]->sequence() * inputs[0]->head() / s; + dim_s = s; + } else { + std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + } + } else if (b != -1 && h == -1 && s != -1 && d == -1) { // batch & sequence + if (b != ANYDIM && s != ANYDIM) { + assert(inputs[0]->sequence() * inputs[0]->batch() == b * s); + dim_b = b; + dim_s = s; + } else if (b != ANYDIM) { + dim_b = b; + dim_s = inputs[0]->sequence() * inputs[0]->batch() / b; + } else if (s != ANYDIM) { + dim_b = inputs[0]->sequence() * inputs[0]->batch() / s; + dim_s = s; + } else { + std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + } + } else { + std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + } + if (inputs[0]->ctype() == BCTHW && inputs[0]->name() == outputs[0]->name()) { + outputs[0]->setCtype(BSHD); + } + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + if (inputs[0]->masterTensor() != nullptr && inputs[0]->name() == outputs[0]->name()) { + inputs[0]->shallowCopyFrom(inputs[0]->masterTensor(), false, inputs[0]->shapeOffset()); + } + + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + // View is a metadata-only operation, no data movement is needed in execute. + return MLLM_NO_ERROR; + } +}; + +class CPUviewFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Assumes OpParam contains keys "b", "h", "s", "d" + int b = static_cast(op_param.at("b")); + int h = static_cast(op_param.at("h")); + int s = static_cast(op_param.at("s")); + int d = static_cast(op_param.at("d")); + return new CPUviewFunction(bn, name, threadCount, b, h, s, d); + } +}; + +} // namespace mllm +#endif // CPUVIEWFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUVisionRoPEFunc.hpp b/src/backends/cpu/op/CPUVisionRoPEFunc.hpp new file mode 100644 index 000000000..64466373e --- /dev/null +++ b/src/backends/cpu/op/CPUVisionRoPEFunc.hpp @@ -0,0 +1,168 @@ +// +// Created by Rongjie Yi on 25-2-16. +// + +#ifndef CPUAPPLYVISIONROPEFUNC_HPP +#define CPUAPPLYVISIONROPEFUNC_HPP + +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include +#include // For std::sin, std::cos + +namespace mllm { +class Tensor; + +class CPUVisionRoPEFuncFunction : public Op { +private: + int thread_count = 4; + + void rope_hf(shared_ptr input, shared_ptr rotary_pos_emb, shared_ptr output, + int thread_count) { + auto out_dtype = output->dtype(); + int partial_dimension = input->dimension(); + int half = (partial_dimension / 2); + assert(partial_dimension % 2 == 0); + if (output->ctype() == BSHD) { + if (input->dtype() == MLLM_TYPE_F16) { +#pragma omp parallel for collapse(4) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { // sequance + for (int d = 0; d < partial_dimension / 2; ++d) { + auto v = input->ptrAt(n, h, s, d); + auto o = output->ptrAt(n, h, s, d); + float in_value = static_cast(v[0]); + float in_value_2 = static_cast(v[half]); + auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); + float sin_value = std::sin(rope_d); // sin_[s][d]; + float cos_value = std::cos(rope_d); // cos_[s][d]; + auto value = (in_value * cos_value) - (in_value_2 * sin_value); + auto value2 = (in_value * sin_value) + (in_value_2 * cos_value); + o[0] = MLLM_FP32_TO_FP16(value); + o[half] = MLLM_FP32_TO_FP16(value2); + } + } + } + } + + } else { + if (out_dtype == MLLM_TYPE_F32) { +#pragma omp parallel for collapse(4) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { // sequance + for (int d = 0; d < partial_dimension / 2; ++d) { + auto v = input->ptrAt(n, h, s, d); + auto o = output->ptrAt(n, h, s, d); + float in_value = v[0]; + float in_value_2 = v[half]; + auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); + float sin_value = std::sin(rope_d); // sin_[s][d]; + float cos_value = std::cos(rope_d); // cos_[s][d]; + auto value = (in_value * cos_value) - (in_value_2 * sin_value); + auto value2 = (in_value * sin_value) + (in_value_2 * cos_value); + o[0] = value; + o[half] = value2; + } + } + } + } + } else if (out_dtype == MLLM_TYPE_F16) { +#pragma omp parallel for collapse(4) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { // sequance + for (int d = 0; d < partial_dimension / 2; ++d) { + auto v = input->ptrAt(n, h, s, d); + auto o = output->ptrAt(n, h, s, d); + float in_value = v[0]; + float in_value_2 = v[half]; + auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); + float sin_value = std::sin(rope_d); // sin_[s][d]; + float cos_value = std::cos(rope_d); // cos_[s][d]; + auto value = (in_value * cos_value) - (in_value_2 * sin_value); + auto value2 = (in_value * sin_value) + (in_value_2 * cos_value); + o[0] = MLLM_FP32_TO_FP16(value); + o[half] = MLLM_FP32_TO_FP16(value2); + } + } + } + } + } + } + return; + } +#pragma omp parallel for collapse(4) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { // sequance + for (int d = 0; d < partial_dimension / 2; ++d) { + if (input->dtype() == MLLM_TYPE_F16) { + float in_value = static_cast(input->dataAt(n, h, s, d)); + float in_value_2 = static_cast(input->dataAt(n, h, s, d + (partial_dimension / 2))); + auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); + float sin_value = std::sin(rope_d); // sin_[s][d]; + float cos_value = std::cos(rope_d); // cos_[s][d]; + auto value = (in_value * cos_value) - (in_value_2 * sin_value); + auto value2 = (in_value * sin_value) + (in_value_2 * cos_value); + if (out_dtype == MLLM_TYPE_F32) { + output->setDataAt(n, h, s, d, value); + output->setDataAt(n, h, s, d + (partial_dimension / 2), value2); + } else if (out_dtype == MLLM_TYPE_F16) { + output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); + output->setDataAt(n, h, s, d + (partial_dimension / 2), MLLM_FP32_TO_FP16(value2)); + } + + } else { + float in_value = input->dataAt(n, h, s, d); + float in_value_2 = input->dataAt(n, h, s, d + (partial_dimension / 2)); + auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); + float sin_value = std::sin(rope_d); // sin_[s][d]; + float cos_value = std::cos(rope_d); // cos_[s][d]; + auto value = (in_value * cos_value) - (in_value_2 * sin_value); + auto value2 = (in_value * sin_value) + (in_value_2 * cos_value); + if (out_dtype == MLLM_TYPE_F32) { + output->setDataAt(n, h, s, d, value); + output->setDataAt(n, h, s, d + (partial_dimension / 2), value2); + } else if (out_dtype == MLLM_TYPE_F16) { + output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); + output->setDataAt(n, h, s, d + (partial_dimension / 2), MLLM_FP32_TO_FP16(value2)); + } + } + } + } + } + } + } + +public: + CPUVisionRoPEFuncFunction(Backend *bn, string name, int threadCount) + : Op(bn, name), thread_count(threadCount) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + auto input = inputs[0]; + auto rotary_pos_emb = inputs[1]; + rope_hf(input, rotary_pos_emb, outputs[0], thread_count); + return MLLM_NO_ERROR; + } +}; + +class CPUVisionRoPEFuncFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new CPUVisionRoPEFuncFunction(bn, name, threadCount); + } +}; + +} // namespace mllm +#endif // CPUAPPLYVISIONROPEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUWhereFunc.hpp b/src/backends/cpu/op/CPUWhereFunc.hpp new file mode 100644 index 000000000..78a855a03 --- /dev/null +++ b/src/backends/cpu/op/CPUWhereFunc.hpp @@ -0,0 +1,115 @@ +// +// Created by Rongjie Yi on 24-2-26. +// + +#ifndef CPUWHEREFUNC_HPP +#define CPUWHEREFUNC_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include + +namespace mllm { +class Tensor; + +class CPUwhereFunction : public Op { +private: + int thread_count = 4; + float value_; + Chl axis_; + +public: + CPUwhereFunction(Backend *bn, string name, int threadCount, float value, Chl axis) + : Op(bn, name), thread_count(threadCount), value_(value), axis_(axis) {} + + ErrorCode reshape(vector> inputs, vector> outputs) override { + // Shape is data-dependent and will be determined in execute. + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + std::vector b_vec; + std::vector s_vec; + std::vector h_vec; + std::vector d_vec; + + // NOTE: The original parallel implementation was thread-unsafe due to race conditions + // on shared vectors. Using the sequential version for correctness. + for (int b = 0; b < inputs[0]->batch(); b++) { + for (auto s = 0; s < inputs[0]->sequence(); s++) { + for (auto h = 0; h < inputs[0]->head(); h++) { + for (auto d = 0; d < inputs[0]->dimension(); d++) { + if (inputs[0]->dataAt(b, h, s, d) == value_) { + b_vec.push_back(b); + s_vec.push_back(s); + h_vec.push_back(h); + d_vec.push_back(d); + } + } + } + } + } + + int num = b_vec.size(); + if ((int)axis_ == -1) { + outputs[0]->reshape(1, 1, 4, num); + outputs[0]->setDtype(MLLM_TYPE_F32); + outputs[0]->alloc(); + for (int i = 0; i < 4; ++i) { + auto dest_ptr = outputs[0]->hostPtr() + outputs[0]->offset(0, 0, i, 0); + switch (i) { + case 0: + memcpy(dest_ptr, b_vec.data(), num * sizeof(float)); + break; + case 1: + memcpy(dest_ptr, h_vec.data(), num * sizeof(float)); + break; + case 2: + memcpy(dest_ptr, s_vec.data(), num * sizeof(float)); + break; + case 3: + memcpy(dest_ptr, d_vec.data(), num * sizeof(float)); + break; + default: + break; + } + } + } else { + outputs[0]->reshape(1, 1, 1, num); + outputs[0]->setDtype(MLLM_TYPE_F32); + outputs[0]->alloc(); + auto dest_ptr = outputs[0]->hostPtr(); + switch (axis_) { + case BATCH: + memcpy(dest_ptr, b_vec.data(), num * sizeof(float)); + break; + case HEAD: + memcpy(dest_ptr, h_vec.data(), num * sizeof(float)); + break; + case SEQUENCE: + memcpy(dest_ptr, s_vec.data(), num * sizeof(float)); + break; + case DIMENSION: + memcpy(dest_ptr, d_vec.data(), num * sizeof(float)); + break; + default: + break; + } + } + return MLLM_NO_ERROR; + } +}; + +class CPUwhereFunctionCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + float value = op_param.at("value"); + Chl axis = (Chl)op_param.at("axis"); + return new CPUwhereFunction(bn, name, threadCount, value, axis); + } +}; + +} // namespace mllm +#endif // CPUWHEREFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/third_party/kleidiai b/src/backends/cpu/third_party/kleidiai index cdcff672c..bb8523387 160000 --- a/src/backends/cpu/third_party/kleidiai +++ b/src/backends/cpu/third_party/kleidiai @@ -1 +1 @@ -Subproject commit cdcff672cc1384467c8a5fadefb0dd9b3592c95f +Subproject commit bb8523387d2ddb69b505add0cdf4ea9f8c38bbed diff --git a/src/backends/qnn/QNNBackend.cpp b/src/backends/qnn/QNNBackend.cpp index 793a21b06..b17e49532 100755 --- a/src/backends/qnn/QNNBackend.cpp +++ b/src/backends/qnn/QNNBackend.cpp @@ -920,119 +920,119 @@ StatusCode QNNBackend::retrieveQNNContext() { return returnStatus; } -std::vector QNNBackend::runFunc(std::vector out_names, - TensorFuncType type, - std::vector float_args, - std::vector> input_tensors, - bool in_place) { - Module *module = input_tensors.empty() ? Module::llm_model_ptr : input_tensors[0]->module(); - assert(module != nullptr); - auto &activation_tensors = module->activation_tensors; - auto &activation_tensors_num = module->activation_tensors_num; - - std::vector> output_ptrs; - for (const auto &out_name : out_names) { - if (activation_tensors.find(out_name) == activation_tensors.end()) { - Backend *backend_h = Backend::global_backends[MLLM_CPU]; - if (!input_tensors.empty()) { - backend_h = input_tensors[0]->backend(); - } - activation_tensors[out_name] = std::make_shared(backend_h); - activation_tensors[out_name]->setName(out_name); - activation_tensors[out_name]->setModule(module); - activation_tensors_num[out_name] = 0; - } - output_ptrs.push_back(activation_tensors[out_name]); - } - - if (module->doLoad) { - std::vector results; - for (auto &out_tensor : output_ptrs) { - results.push_back(*activation_tensors[out_tensor->name()]); - } - return results; - } - - Backend *backend_h = Backend::global_backends[MLLM_CPU]; - if (!input_tensors.empty()) { - backend_h = input_tensors[0]->backend(); - } - TensorFunction *func = backend_h->funcCreate(type); - - std::vector> input_ptrs; - for (auto &tensor : input_tensors) { - input_ptrs.push_back(activation_tensors[tensor->name()]); - } - // if (in_place) { - // for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { - // input_tensors[i]->setName(out_names[i]); - // output_ptrs.push_back(input_tensors[i]); - // } - // } +// std::vector QNNBackend::runFunc(std::vector out_names, +// TensorFuncType type, +// std::vector float_args, +// std::vector input_tensors, +// bool in_place) { +// Module *module = input_tensors.empty() ? Module::llm_model_ptr : input_tensors[0].module(); +// assert(module != nullptr); +// auto &activation_tensors = module->activation_tensors; +// auto &activation_tensors_num = module->activation_tensors_num; + +// std::vector> output_ptrs; +// for (const auto &out_name : out_names) { +// if (activation_tensors.find(out_name) == activation_tensors.end()) { +// Backend *backend_h = Backend::global_backends[MLLM_CPU]; +// if (!input_tensors.empty()) { +// backend_h = input_tensors[0].backend(); +// } +// activation_tensors[out_name] = std::make_shared(backend_h); +// activation_tensors[out_name]->setName(out_name); +// activation_tensors[out_name]->setModule(module); +// activation_tensors_num[out_name] = 0; +// } +// output_ptrs.push_back(activation_tensors[out_name]); +// } -#ifdef DEBUGOPTIME - auto start_t = mllm_time_us(); -#endif +// if (module->doLoad) { +// std::vector results; +// for (auto &out_tensor : output_ptrs) { +// results.push_back(*activation_tensors[out_tensor->name()]); +// } +// return results; +// } - switch (Tensor::tensor_status) { - case TENSOR_STATIC_INIT: - func->reshape(output_ptrs, input_ptrs, float_args); - func->setUp(output_ptrs, input_ptrs, float_args); - break; - case TENSOR_STATIC_READY: - func->execute(output_ptrs, input_ptrs, float_args); - break; - case TENSOR_STATIC_TRACE: - if (backend_h->type() == BackendType::MLLM_CPU) { - Tracer::addTensorFunction(func, input_ptrs, output_ptrs, float_args); - } - break; - default: - break; - } +// Backend *backend_h = Backend::global_backends[MLLM_CPU]; +// if (!input_tensors.empty()) { +// backend_h = input_tensors[0].backend(); +// } +// TensorFunction *func = backend_h->funcCreate(type); - // if (Backend::global_backends.size() == 1) { - // for (auto input_tensor : input_ptrs) { - // auto it = activation_tensors_num.find(input_tensor->name()); - // if (it != activation_tensors_num.end()) { - // switch (Tensor::tensor_status) { - // case TENSOR_STATIC_INIT: - // it->second += 1; - // break; - // case TENSOR_STATIC_READY: - // it->second -= 1; - // break; - // default: - // break; - // } - // if (it->second == 0 && module_tensors[input_tensor->name()]->sequence() > 1 && module_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { - // activation_tensors[input_tensor->name()]->free(); - // } - // } - // } - // } +// std::vector> input_ptrs; +// for (auto &tensor : input_tensors) { +// input_ptrs.push_back(activation_tensors[tensor.name()]); +// } +// // if (in_place) { +// // for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { +// // input_tensors[i].setName(out_names[i]); +// // output_ptrs.push_back(input_tensors[i]); +// // } +// // } + +// #ifdef DEBUGOPTIME +// auto start_t = mllm_time_us(); +// #endif + +// switch (Tensor::tensor_status) { +// case TENSOR_STATIC_INIT: +// func->reshape(output_ptrs, input_ptrs, float_args); +// func->setUp(output_ptrs, input_ptrs, float_args); +// break; +// case TENSOR_STATIC_READY: +// func->execute(output_ptrs, input_ptrs, float_args); +// break; +// case TENSOR_STATIC_TRACE: +// if (backend_h->type() == BackendType::MLLM_CPU) { +// Tracer::addTensorFunction(func, input_ptrs, output_ptrs, float_args); +// } +// break; +// default: +// break; +// } -#ifdef DEBUGOPTIME - if (Tensor::tensor_status == TENSOR_STATIC_READY) { - auto end_t = mllm_time_us(); - std::cout << (out_names.empty() ? "" : out_names[0]) << " | " - << Tensor::tensor_status << " time: " - << (end_t - start_t) / 1000.0F << "ms" << std::endl; - } -#endif +// // if (Backend::global_backends.size() == 1) { +// // for (auto input_tensor : input_ptrs) { +// // auto it = activation_tensors_num.find(input_tensor->name()); +// // if (it != activation_tensors_num.end()) { +// // switch (Tensor::tensor_status) { +// // case TENSOR_STATIC_INIT: +// // it->second += 1; +// // break; +// // case TENSOR_STATIC_READY: +// // it->second -= 1; +// // break; +// // default: +// // break; +// // } +// // if (it->second == 0 && module_tensors[input_tensor->name()]->sequence() > 1 && module_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { +// // activation_tensors[input_tensor->name()]->free(); +// // } +// // } +// // } +// // } + +// #ifdef DEBUGOPTIME +// if (Tensor::tensor_status == TENSOR_STATIC_READY) { +// auto end_t = mllm_time_us(); +// std::cout << (out_names.empty() ? "" : out_names[0]) << " | " +// << Tensor::tensor_status << " time: " +// << (end_t - start_t) / 1000.0F << "ms" << std::endl; +// } +// #endif -#ifdef DEBUGSAVETENSOR - for (auto &out_name : out_names) { - activation_tensors[out_name]->saveNData(); - } -#endif +// #ifdef DEBUGSAVETENSOR +// for (auto &out_name : out_names) { +// activation_tensors[out_name]->saveNData(); +// } +// #endif - std::vector results; - for (auto &out_tensor : output_ptrs) { - results.emplace_back(*activation_tensors[out_tensor->name()]); - } - return results; -} +// std::vector results; +// for (auto &out_tensor : output_ptrs) { +// results.emplace_back(*activation_tensors[out_tensor->name()]); +// } +// return results; +// } std::string name_num_to_X(const std::string &input_string) { std::regex pattern(R"(\.\d{1,3}\.)"); // Matches any number between 1 and 100 between two dots std::string replacement = ".X."; // The string to replace the matched pattern with @@ -1084,53 +1084,31 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input auto &activation_tensors_num = module->activation_tensors_num; // Module::runlistIdx = saved_list_idx; bool do_init = false; - if (module->doLoad || !layer->inited_loaded) { // set backend to current module device and try to create op // use Module::tmp_device only when creating the op as the recersive module backend only handled in load and init stage layer->backend_ = Backend::global_backends[Module::tmp_device]; do_init = !layer->inited_loaded; - if (layer->op_ == nullptr) { -#ifdef USE_QNN - if ((layer->param_["type"] == KVCACHE || layer->param_["type"] == KVCACHENPU) && (Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end())) { - if (kv_cache_map.find(layer->name_) == kv_cache_map.end()) { - // for the prefill part, we need to create a new op - layer->param_["type"] = KVCACHENPU; - layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); - kv_cache_map[layer->name_] = layer->op_; - } else { -#ifdef DEBUGPRINT - std::cout << name_ << " is shared used" << std::endl; -#endif - // for the decoding part, we need to get created op from global container - layer->op_ = kv_cache_map[layer->name_]; - } - } else { - layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); - } -#else - layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); -#endif - } + if (layer->param_["type"] == SUBGRAPHFINALIZE) { for (auto &input : inputs) { activation_tensors[input.name()]->setTtype(GRAPH_OUTPUT); } } - if (module->doLoad) { - layer->op_->load(*module->loader); - layer->inited_loaded = true; - } else if (layer->loaded_param) { - layer->inited_loaded = layer->loaded_param; - } else { - if (!layer->inited_loaded) { - // module->loader = new ParamLoader(""); - // op_->load(*module->loader); - auto empty_loader = new ParamLoader(""); - layer->op_->load(*empty_loader); - layer->inited_loaded = true; - } - } + // if (module->doLoad) { + // layer->op_->load(*module->loader); + // layer->inited_loaded = true; + // } else if (layer->loaded_param) { + // layer->inited_loaded = layer->loaded_param; + // } else { + // if (!layer->inited_loaded) { + // // module->loader = new ParamLoader(""); + // // op_->load(*module->loader); + // auto empty_loader = new ParamLoader(""); + // layer->op_->load(*empty_loader); + // layer->inited_loaded = true; + // } + // } vector layer_next_names = {}; if (N > 1) { for (int i = 0; i < N; ++i) { @@ -1172,14 +1150,13 @@ std::vector QNNBackend::runLayer(Layer *layer, std::vector input activation_tensors_num[next_name] = 0; } } - if (module->doLoad) { - vector output_result = {}; - for (const auto &layer_next_name : layer_next_names) { - string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); - output_result.push_back(*activation_tensors[next_name]); - } - return output_result; + + vector output_result = {}; + for (const auto &layer_next_name : layer_next_names) { + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); + output_result.push_back(*activation_tensors[next_name]); } + return output_result; } // input_tensors vector> input_tensors; diff --git a/src/backends/qnn/QNNBackend.hpp b/src/backends/qnn/QNNBackend.hpp index 6e5835a49..aaf1a98e4 100644 --- a/src/backends/qnn/QNNBackend.hpp +++ b/src/backends/qnn/QNNBackend.hpp @@ -90,7 +90,7 @@ class QNNBackend : public Backend { std::vector out_names, TensorFuncType type, std::vector float_args, - std::vector> input_tensors, + std::vector input_tensors, bool in_place) override; std::vector runLayer(Layer *layer, std::vector inputs, int N) override; std::vector runForward(Module *module, std::vector inputs, std::vector args) override; diff --git a/src/backends/xnnpack/XnnpackBackend.cpp b/src/backends/xnnpack/XnnpackBackend.cpp index 72631f480..fc431fff0 100644 --- a/src/backends/xnnpack/XnnpackBackend.cpp +++ b/src/backends/xnnpack/XnnpackBackend.cpp @@ -677,122 +677,119 @@ bool XnnpackBackend::enable_dynamic_shape = true; bool XnnpackBackend::enable_legacy_wrapper = false; +// std::vector XnnpackBackend::runFunc(std::vector out_names, +// TensorFuncType type, +// std::vector float_args, +// std::vector input_tensors, +// bool in_place) { +// Module *module = input_tensors.empty() ? mllm::Module::llm_model_ptr : input_tensors[0].module(); +// assert(module != nullptr); +// auto &activation_tensors = module->activation_tensors; +// auto &activation_tensors_num = module->activation_tensors_num; + +// std::vector> output_ptrs; +// for (const auto &out_name : out_names) { +// if (activation_tensors.find(out_name) == activation_tensors.end()) { +// Backend *backend_h = Backend::global_backends[MLLM_CPU]; +// if (!input_tensors.empty()) { +// backend_h = input_tensors[0].backend(); +// } +// activation_tensors[out_name] = std::make_shared(backend_h); +// activation_tensors[out_name]->setName(out_name); +// activation_tensors[out_name]->setModule(module); +// activation_tensors_num[out_name] = 0; +// } +// output_ptrs.push_back(activation_tensors[out_name]); +// } +// if (module->doLoad) { +// std::vector results; +// for (auto &out_tensor : output_ptrs) { +// results.push_back(*activation_tensors[out_tensor->name()]); +// } +// return results; +// } +// Backend *backend_h = Backend::global_backends[MLLM_CPU]; +// if (!input_tensors.empty()) { +// backend_h = input_tensors[0].backend(); +// } +// TensorFunction *func = backend_h->funcCreate(type); -std::vector XnnpackBackend::runFunc(std::vector out_names, - TensorFuncType type, - std::vector float_args, - std::vector> input_tensors, - bool in_place) { - Module *module = input_tensors.empty() ? mllm::Module::llm_model_ptr : input_tensors[0]->module(); - assert(module != nullptr); - auto &activation_tensors = module->activation_tensors; - auto &activation_tensors_num = module->activation_tensors_num; - - std::vector> output_ptrs; - for (const auto &out_name : out_names) { - if (activation_tensors.find(out_name) == activation_tensors.end()) { - Backend *backend_h = Backend::global_backends[MLLM_CPU]; - if (!input_tensors.empty()) { - backend_h = input_tensors[0]->backend(); - } - activation_tensors[out_name] = std::make_shared(backend_h); - activation_tensors[out_name]->setName(out_name); - activation_tensors[out_name]->setModule(module); - activation_tensors_num[out_name] = 0; - } - output_ptrs.push_back(activation_tensors[out_name]); - } - - if (module->doLoad) { - std::vector results; - for (auto &out_tensor : output_ptrs) { - results.push_back(*activation_tensors[out_tensor->name()]); - } - return results; - } - - Backend *backend_h = Backend::global_backends[MLLM_CPU]; - if (!input_tensors.empty()) { - backend_h = input_tensors[0]->backend(); - } - TensorFunction *func = backend_h->funcCreate(type); - - std::vector> input_ptrs; - for (auto &tensor : input_tensors) { - input_ptrs.push_back(activation_tensors[tensor->name()]); - } - // if (in_place) { - // for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { - // input_tensors[i]->setName(out_names[i]); - // output_ptrs.push_back(input_tensors[i]); - // } - // } - -#ifdef DEBUGOPTIME - auto start_t = mllm_time_us(); -#endif - - switch (Tensor::tensor_status) { - case TENSOR_STATIC_INIT: - func->reshape(output_ptrs, input_ptrs, float_args); - func->setUp(output_ptrs, input_ptrs, float_args); - break; - case TENSOR_STATIC_READY: - func->execute(output_ptrs, input_ptrs, float_args); - break; - case TENSOR_STATIC_TRACE: - if (backend_h->type() == BackendType::MLLM_CPU) { - Tracer::addTensorFunction(func, input_ptrs, output_ptrs, float_args); - } - break; - default: - break; - } - - // if (Backend::global_backends.size() == 1) { - // for (auto input_tensor : input_ptrs) { - // auto it = activation_tensors_num.find(input_tensor->name()); - // if (it != activation_tensors_num.end()) { - // switch (Tensor::tensor_status) { - // case TENSOR_STATIC_INIT: - // it->second += 1; - // break; - // case TENSOR_STATIC_READY: - // it->second -= 1; - // break; - // default: - // break; - // } - // if (it->second == 0 && module_tensors[input_tensor->name()]->sequence() > 1 && module_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { - // activation_tensors[input_tensor->name()]->free(); - // } - // } - // } - // } +// std::vector> input_ptrs; +// for (auto &tensor : input_tensors) { +// input_ptrs.push_back(activation_tensors[tensor.name()]); +// } +// // if (in_place) { +// // for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { +// // input_tensors[i].setName(out_names[i]); +// // output_ptrs.push_back(input_tensors[i]); +// // } +// // } + +// #ifdef DEBUGOPTIME +// auto start_t = mllm_time_us(); +// #endif + +// switch (Tensor::tensor_status) { +// case TENSOR_STATIC_INIT: +// func->reshape(output_ptrs, input_ptrs, float_args); +// func->setUp(output_ptrs, input_ptrs, float_args); +// break; +// case TENSOR_STATIC_READY: +// func->execute(output_ptrs, input_ptrs, float_args); +// break; +// case TENSOR_STATIC_TRACE: +// if (backend_h->type() == BackendType::MLLM_CPU) { +// Tracer::addTensorFunction(func, input_ptrs, output_ptrs, float_args); +// } +// break; +// default: +// break; +// } -#ifdef DEBUGOPTIME - if (Tensor::tensor_status == TENSOR_STATIC_READY) { - auto end_t = mllm_time_us(); - std::cout << (out_names.empty() ? "" : out_names[0]) << " | " - << Tensor::tensor_status << " time: " - << (end_t - start_t) / 1000.0F << "ms" << std::endl; - } -#endif +// // if (Backend::global_backends.size() == 1) { +// // for (auto input_tensor : input_ptrs) { +// // auto it = activation_tensors_num.find(input_tensor->name()); +// // if (it != activation_tensors_num.end()) { +// // switch (Tensor::tensor_status) { +// // case TENSOR_STATIC_INIT: +// // it->second += 1; +// // break; +// // case TENSOR_STATIC_READY: +// // it->second -= 1; +// // break; +// // default: +// // break; +// // } +// // if (it->second == 0 && module_tensors[input_tensor->name()]->sequence() > 1 && module_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { +// // activation_tensors[input_tensor->name()]->free(); +// // } +// // } +// // } +// // } + +// #ifdef DEBUGOPTIME +// if (Tensor::tensor_status == TENSOR_STATIC_READY) { +// auto end_t = mllm_time_us(); +// std::cout << (out_names.empty() ? "" : out_names[0]) << " | " +// << Tensor::tensor_status << " time: " +// << (end_t - start_t) / 1000.0F << "ms" << std::endl; +// } +// #endif -#ifdef DEBUGSAVETENSOR - for (auto &out_name : out_names) { - activation_tensors[out_name]->saveNData(); - } -#endif +// #ifdef DEBUGSAVETENSOR +// for (auto &out_name : out_names) { +// activation_tensors[out_name]->saveNData(); +// } +// #endif - std::vector results; - for (auto &out_tensor : output_ptrs) { - results.emplace_back(*activation_tensors[out_tensor->name()]); - } - return results; -} +// std::vector results; +// for (auto &out_tensor : output_ptrs) { +// results.emplace_back(*activation_tensors[out_tensor->name()]); +// } +// return results; +// } std::string name_num_to_X(const std::string &input_string) { std::regex pattern(R"(\.\d{1,3}\.)"); // Matches any number between 1 and 100 between two dots std::string replacement = ".X."; // The string to replace the matched pattern with @@ -850,47 +847,28 @@ std::vector XnnpackBackend::runLayer(Layer *layer, std::vector i // use Module::tmp_device only when creating the op as the recersive module backend only handled in load and init stage layer->backend_ = Backend::global_backends[Module::tmp_device]; do_init = !layer->inited_loaded; - if (layer->op_ == nullptr) { -#ifdef USE_QNN - if ((layer->param_["type"] == KVCACHE || layer->param_["type"] == KVCACHENPU) && (Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end())) { - if (kv_cache_map.find(layer->name_) == kv_cache_map.end()) { - // for the prefill part, we need to create a new op - layer->param_["type"] = KVCACHENPU; - layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); - kv_cache_map[layer->name_] = layer->op_; - } else { -#ifdef DEBUGPRINT - std::cout << name_ << " is shared used" << std::endl; -#endif - // for the decoding part, we need to get created op from global container - layer->op_ = kv_cache_map[layer->name_]; - } - } else { - layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); - } -#else - layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); -#endif - } + // if (layer->op_ == nullptr) { + // layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); + // } if (layer->param_["type"] == SUBGRAPHFINALIZE) { for (auto &input : inputs) { activation_tensors[input.name()]->setTtype(GRAPH_OUTPUT); } } - if (module->doLoad) { - layer->op_->load(*module->loader); - layer->inited_loaded = true; - } else if (layer->loaded_param) { - layer->inited_loaded = layer->loaded_param; - } else { - if (!layer->inited_loaded) { - // module->loader = new ParamLoader(""); - // op_->load(*module->loader); - auto empty_loader = new ParamLoader(""); - layer->op_->load(*empty_loader); - layer->inited_loaded = true; - } - } + // if (module->doLoad) { + // layer->op_->load(*module->loader); + // layer->inited_loaded = true; + // } else if (layer->loaded_param) { + // layer->inited_loaded = layer->loaded_param; + // } else { + // if (!layer->inited_loaded) { + // // module->loader = new ParamLoader(""); + // // op_->load(*module->loader); + // auto empty_loader = new ParamLoader(""); + // layer->op_->load(*empty_loader); + // layer->inited_loaded = true; + // } + // } vector layer_next_names = {}; if (N > 1) { for (int i = 0; i < N; ++i) { @@ -1038,6 +1016,180 @@ std::vector XnnpackBackend::runLayer(Layer *layer, std::vector i } return output_result; } + +std::vector XnnpackBackend::runOp(Op *op, std::vector inputs, std::vector out_names, bool in_place) { + Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); + map> &activation_tensors = module->activation_tensors; + auto &activation_tensors_num = module->activation_tensors_num; + // Module::runlistIdx = saved_list_idx; + bool do_init = false; + + if (module->doTrace) { + // set backend to current module device and try to create op + // use Module::tmp_device only when creating the op as the recersive module backend only handled in load and init stage + op->backend() = Backend::global_backends[Module::tmp_device]; + // do_init = !layer->inited_loaded; + // if (layer->op_ == nullptr) { + // layer->op_ = layer->backend_->opCreate(layer->param_, layer->name_); + // } + if (op->type() == SUBGRAPHFINALIZE) { + for (auto &input : inputs) { + activation_tensors[input.name()]->setTtype(GRAPH_OUTPUT); + } + } + // if (module->doLoad) { + // layer->op_->load(*module->loader); + // layer->inited_loaded = true; + // } else if (layer->loaded_param) { + // layer->inited_loaded = layer->loaded_param; + // } else { + // if (!layer->inited_loaded) { + // // module->loader = new ParamLoader(""); + // // op_->load(*module->loader); + // auto empty_loader = new ParamLoader(""); + // layer->op_->load(*empty_loader); + // layer->inited_loaded = true; + // } + // } + vector layer_next_names = {}; + if (N > 1) { + for (int i = 0; i < N; ++i) { + layer_next_names.push_back("out-" + op->name() + "-" + std::to_string(i)); + } + } else { + layer_next_names = {"out-" + op->name()}; + } + for (const auto &layer_next_name : layer_next_names) { + string next_name; + if (Layer::use_layername_2_tensorname) { + if (Layer::layername_2_tensorname.find(layer_next_name) == Layer::layername_2_tensorname.end()) { + if (layer->param_["type"] == KVCACHE) { + Layer::layername_2_tensorname[layer_next_name] = layer_next_name; + init_reset_KVCache(inputs[0].name(), module, layer->saved_list_idx, Layer::layername_2_tensorname, layer->backend_); + } else { + Layer::layername_2_tensorname[layer_next_name] = name_num_to_X(layer_next_name); + } + } + next_name = Layer::layername_2_tensorname[layer_next_name]; + } else if (layer_next_name.find("visual") != string::npos) { + // QNN VLM trick: visual model use act tensor sharing + if (Layer::layername_2_tensorname.find(layer_next_name) == Layer::layername_2_tensorname.end()) { + if (layer->param_["type"] == KVCACHE) { + Layer::layername_2_tensorname[layer_next_name] = layer_next_name; + init_reset_KVCache(inputs[0].name(), module, layer->saved_list_idx, Layer::layername_2_tensorname, layer->backend_); + } else { + Layer::layername_2_tensorname[layer_next_name] = name_num_to_X(layer_next_name); + } + } + next_name = Layer::layername_2_tensorname[layer_next_name]; + } else { + next_name = layer_next_name; + } + if (activation_tensors.find(next_name) == activation_tensors.end()) { + activation_tensors[next_name] = std::make_shared(op->backend()); + activation_tensors[next_name]->setName(next_name); + activation_tensors[next_name]->setModule(module); + activation_tensors_num[next_name] = 0; + } + } + vector output_result = {}; + for (const auto &layer_next_name : layer_next_names) { + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); + output_result.push_back(*activation_tensors[next_name]); + } + return output_result; + } + // input_tensors + vector> input_tensors; + for (auto &input : inputs) { + if (input.shouldInGraphs()) { + auto input_name = input.name(); + if (layer->param_["type"] == KVCACHE && do_init && Layer::use_layername_2_tensorname) { + input_name = name_X_to_num(input_name, layer->saved_list_idx); + } + input_tensors.push_back(activation_tensors[input_name]); + } else { + input_tensors.push_back(std::shared_ptr(&input, [](Tensor *) {})); + } + } + // output_tensors + vector layer_next_names = {}; + if (N > 1) { + for (int i = 0; i < N; ++i) { + layer_next_names.push_back("out-" + op->name() + "-" + std::to_string(i)); + } + } else { + layer_next_names = {"out-" + op->name()}; + } + vector> output_tensors = {}; + for (const auto &layer_next_name : layer_next_names) { + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); + output_tensors.push_back(activation_tensors[next_name]); + } +#ifdef DEBUGOPTIME + auto start_t = mllm_time_us(); +#endif + switch (Tensor::tensor_status) { + case TENSOR_STATIC_INIT: { + op->reshape(input_tensors, output_tensors); + op->setUp(input_tensors, output_tensors); + break; + } + case TENSOR_STATIC_READY: { + op->execute(input_tensors, output_tensors); + break; + } + case TENSOR_STATIC_TRACE: { + if (op->backend()->type() == BackendType::MLLM_CPU) { + Tracer::addOp(op, input_tensors, output_tensors); + } else if (op->type() == SUBGRAPHSTART) { // begin of QNN graph + Tracer::addModule(input_tensors, {}, op->name()); + } + break; + } + default: { + break; + } + } + if (Backend::global_backends.size() == 1) { + for (auto input_tensor : input_tensors) { + if ((activation_tensors_num.find(input_tensor->name()) != activation_tensors_num.end())) { + switch (Tensor::tensor_status) { + case TENSOR_STATIC_INIT: { + activation_tensors_num[input_tensor->name()] += 1; + break; + } + case TENSOR_STATIC_READY: { + activation_tensors_num[input_tensor->name()] -= 1; + break; + } + default: { + } + } + if (activation_tensors_num[input_tensor->name()] == 0 && activation_tensors[input_tensor->name()]->sequence() > 1 + && activation_tensors[input_tensor->name()]->ttype() != GRAPH_OUTPUT) { + activation_tensors[input_tensor->name()]->free(); + // std::cout << input_tensor->name() << "|" << std::endl; + } + } + } + } +#ifdef DEBUGOPTIME + if (Tensor::tensor_status == TENSOR_STATIC_READY) { + auto end_t = mllm_time_us(); + std::cout << op->name() << " | " << Tensor::tensor_status << " time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; + } +#endif + vector output_result = {}; + for (const auto &layer_next_name : layer_next_names) { + string next_name = Layer::use_layername_2_tensorname ? Layer::layername_2_tensorname[layer_next_name] : (layer_next_name.find("visual") != string::npos ? Layer::layername_2_tensorname[layer_next_name] : layer_next_name); +#ifdef DEBUGSAVETENSOR + activation_tensors[next_name]->saveNData(layer_next_name); +#endif + output_result.push_back(*activation_tensors[next_name]); + } + return output_result; +} std::vector XnnpackBackend::runForward(Module *module, std::vector inputs, std::vector args) { // set static tmp_device to device_ to init layers' op // auto previoud_device = Module::tmp_device; diff --git a/src/backends/xnnpack/XnnpackBackend.hpp b/src/backends/xnnpack/XnnpackBackend.hpp index 6875e825e..14fa0eba5 100644 --- a/src/backends/xnnpack/XnnpackBackend.hpp +++ b/src/backends/xnnpack/XnnpackBackend.hpp @@ -21,7 +21,7 @@ namespace mllm { class Module; class Layer; -} +} // namespace mllm namespace mllm::xnnpack { class XnnpackModelRuntime { @@ -172,14 +172,15 @@ class XnnpackBackend : public Backend { void onExecuteEnd(std::vector> &outputs, const string &graph_name) override; - std::vector runFunc( std::vector out_names, TensorFuncType type, std::vector float_args, - std::vector> input_tensors, + std::vector input_tensors, bool in_place) override; std::vector runLayer(Layer *layer, std::vector inputs, int N) override; + + std::vector runOp(Op *op, std::vector input, std::vector out_names, bool in_place) override; std::vector runForward(Module *module, std::vector inputs, std::vector args) override; XnnpackCargo *getCurProcessingGraph(); From 00948f7a1fad1118f3957e5569157aee69455186 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Thu, 26 Jun 2025 16:40:01 +0800 Subject: [PATCH 11/22] feat: add openclbackend --- .gitignore | 1 + CMakeLists.txt | 47 +- examples/CMakeLists.txt | 28 +- include/Types.hpp | 2 +- src/Backend.hpp | 24 +- src/Module.hpp | 8 + src/Tensor.cpp | 30 +- src/Tensor.hpp | 74 ++- src/TensorImpl.hpp | 132 ++++- src/backends/cpu/CPUBackend.cpp | 62 +-- src/backends/cpu/CPUBackend.hpp | 2 + src/backends/cpu/function/CPUArgSortFunc.hpp | 51 -- src/backends/cpu/function/CPUBinCountFunc.hpp | 72 --- src/backends/cpu/function/CPUBinaryFunc.hpp | 264 --------- src/backends/cpu/function/CPUCatFunc.hpp | 377 ------------- src/backends/cpu/function/CPUClipFunc.hpp | 344 ------------ src/backends/cpu/function/CPUExpandFunc.hpp | 80 --- .../cpu/function/CPUFlashAttention2Func.hpp | 102 ---- src/backends/cpu/function/CPUFlattenFunc.hpp | 128 ----- .../cpu/function/CPUFuyuGatherEmbdFunc.hpp | 65 --- src/backends/cpu/function/CPUIndexPutFunc.hpp | 139 ----- src/backends/cpu/function/CPULikeFunc.hpp | 27 - src/backends/cpu/function/CPUMatmulFunc.hpp | 89 --- src/backends/cpu/function/CPUMeanFunc.hpp | 111 ---- src/backends/cpu/function/CPUNormFunc.hpp | 53 -- .../cpu/function/CPUPhi3VhdmergeFunc.hpp | 78 --- src/backends/cpu/function/CPURangeFunc.hpp | 34 -- src/backends/cpu/function/CPURepeatFunc.hpp | 87 --- .../cpu/function/CPUScatterReduceFunc.hpp | 48 -- src/backends/cpu/function/CPUSplitFunc.hpp | 170 ------ src/backends/cpu/function/CPUSumFunc.hpp | 111 ---- src/backends/cpu/function/CPUTopkFunc.hpp | 60 -- .../cpu/function/CPUTransposeFunc.hpp | 155 ------ src/backends/cpu/function/CPUViewFunc.hpp | 145 ----- .../cpu/function/CPUVisionRoPEFunc.hpp | 147 ----- src/backends/cpu/function/CPUWhereFunc.hpp | 107 ---- src/backends/opencl/CMakeLists.txt | 31 ++ src/backends/opencl/OpenCLBackend.cpp | 524 ++++++++++++++++++ src/backends/opencl/OpenCLBackend.hpp | 121 ++++ src/backends/opencl/OpenCLMemoryManager.cpp | 28 + src/backends/opencl/OpenCLMemoryManager.hpp | 32 ++ src/backends/opencl/kernel/add.cl | 109 ++++ src/backends/opencl/kernel/convert.cl | 115 ++++ src/backends/opencl/op/OpenCLAddFuncOp.cpp | 174 ++++++ src/backends/opencl/op/OpenCLAddFuncOp.hpp | 42 ++ src/backends/opencl/utils/OpenCLTools.hpp | 112 ++++ test/CMakeLists.txt | 4 + 47 files changed, 1602 insertions(+), 3144 deletions(-) delete mode 100644 src/backends/cpu/function/CPUArgSortFunc.hpp delete mode 100644 src/backends/cpu/function/CPUBinCountFunc.hpp delete mode 100644 src/backends/cpu/function/CPUBinaryFunc.hpp delete mode 100644 src/backends/cpu/function/CPUCatFunc.hpp delete mode 100644 src/backends/cpu/function/CPUClipFunc.hpp delete mode 100644 src/backends/cpu/function/CPUExpandFunc.hpp delete mode 100644 src/backends/cpu/function/CPUFlashAttention2Func.hpp delete mode 100644 src/backends/cpu/function/CPUFlattenFunc.hpp delete mode 100644 src/backends/cpu/function/CPUFuyuGatherEmbdFunc.hpp delete mode 100644 src/backends/cpu/function/CPUIndexPutFunc.hpp delete mode 100644 src/backends/cpu/function/CPULikeFunc.hpp delete mode 100644 src/backends/cpu/function/CPUMatmulFunc.hpp delete mode 100644 src/backends/cpu/function/CPUMeanFunc.hpp delete mode 100644 src/backends/cpu/function/CPUNormFunc.hpp delete mode 100644 src/backends/cpu/function/CPUPhi3VhdmergeFunc.hpp delete mode 100644 src/backends/cpu/function/CPURangeFunc.hpp delete mode 100644 src/backends/cpu/function/CPURepeatFunc.hpp delete mode 100644 src/backends/cpu/function/CPUScatterReduceFunc.hpp delete mode 100644 src/backends/cpu/function/CPUSplitFunc.hpp delete mode 100644 src/backends/cpu/function/CPUSumFunc.hpp delete mode 100644 src/backends/cpu/function/CPUTopkFunc.hpp delete mode 100644 src/backends/cpu/function/CPUTransposeFunc.hpp delete mode 100644 src/backends/cpu/function/CPUViewFunc.hpp delete mode 100644 src/backends/cpu/function/CPUVisionRoPEFunc.hpp delete mode 100644 src/backends/cpu/function/CPUWhereFunc.hpp create mode 100644 src/backends/opencl/CMakeLists.txt create mode 100644 src/backends/opencl/OpenCLBackend.cpp create mode 100644 src/backends/opencl/OpenCLBackend.hpp create mode 100644 src/backends/opencl/OpenCLMemoryManager.cpp create mode 100644 src/backends/opencl/OpenCLMemoryManager.hpp create mode 100644 src/backends/opencl/kernel/add.cl create mode 100644 src/backends/opencl/kernel/convert.cl create mode 100644 src/backends/opencl/op/OpenCLAddFuncOp.cpp create mode 100644 src/backends/opencl/op/OpenCLAddFuncOp.hpp create mode 100644 src/backends/opencl/utils/OpenCLTools.hpp diff --git a/.gitignore b/.gitignore index 3c53830cc..413bfd3a6 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ src/backends/qnn/sdk/* .DS_Store src/models/ling/modeling_bailing_moe.hpp src/models/ling/configuration_bailing_moe.hpp +examples/test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a8697b2ec..ae09aff5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,6 +95,21 @@ if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") cmake_policy(SET CMP0135 NEW) endif () +option(OPENCL "Enable OpenCL Backend" ON) +if(OPENCL) + find_package(OpenCL) + if(NOT OpenCL_FOUND) + message(STATUS "OpenCl backend not found。") + set(OPENCL OFF CACHE BOOL "Enable OpenCL Backend" FORCE) + endif() +endif() +if(OPENCL) + message(STATUS "OpenCL backend enabled.") + add_definitions(-DUSE_OPENCL) +endif() + + + # for XNNPACK, avoid invovle googltest twice. set(GOOGLETEST_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/third_party/googletest) add_subdirectory(third_party/googletest EXCLUDE_FROM_ALL) @@ -155,6 +170,12 @@ include_directories(${PROJECT_SOURCE_DIR}/third_party/pybind11/include) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/backends/cpu) + +if(OPENCL) + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/backends/opencl) +endif() +# ========= + if(QNN) # QNN lib include_directories( # $ENV{QNN_SDK_ROOT}/include/QNN # QNN SDK include @@ -275,8 +296,6 @@ if(TEST) add_subdirectory(test) endif() -# add_executable(demo examples/demo.cpp) -# target_link_libraries(demo fmt::fmt-header-only) add_subdirectory(examples) if(APK) @@ -284,35 +303,17 @@ if(APK) ${DIR_THIRDPARTY_AUDIO} src/tokenizers/Tokenizer.cpp tools/jni/LibHelper.cpp - - # src/tokenizers/Tokenizer.hpp - # src/tokenizers/Unigram/Unigram.hpp src/tokenizers/Unigram/Unigram.cpp - - # src/tokenizers/Unigram/trie.hpp src/tokenizers/BPE/Bpe.cpp - - # src/tokenizers/BPE/Bpe.hpp src/tokenizers/Unicode.cpp src/tokenizers/UnicodeData.cpp src/tokenizers/BPE/Bpe.cpp src/tokenizers/WordPiece/WordPiece.cpp - - # models/bert/configuration_bert.hpp - # models/bert/modeling_bert.hpp - # models/bert/tokenization_bert.hpp - # models/fuyu/configuration_fuyu.hpp - # models/fuyu/modeling_fuyu.hpp - # models/fuyu/processing_fuyu.hpp - # models/phonelm/configuration_phonelm.hpp - # models/phonelm/modeling_phonelm.hpp - # models/qwen/configuration_qwen.hpp - # models/qwen/modeling_qwen.hpp - # models/qwen/tokenization_qwen.hpp - # models/smollm/tokenization_smollm.hpp - # tokenizers/Unigram/Unigram.hpp ) target_link_libraries(mllm_lib mllm_cpu) + if (OPENCL) + target_link_libraries(mllm_lib mllm_opencl) + endif() if(QNN) target_link_libraries(mllm_lib mllm_qnn) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b6f450b9a..b2c314126 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -38,6 +38,9 @@ macro(func_link_libs target) target_link_libraries(${target} PUBLIC -fopenmp) endif() endif() + if(OPENCL) + target_link_libraries(${target} PRIVATE mllm_opencl ${CMAKE_DL_LIBS}) + endif() if (QNN) target_link_libraries(${target} PUBLIC mllm_qnn ${CMAKE_DL_LIBS}) endif() @@ -54,17 +57,25 @@ target_link_libraries(mllm_vlm PUBLIC mllm_llm) func_set_compile_opts_defs(mllm_vlm) macro(func_llm_add_executable target) - add_executable(${target} ${PROJECT_SOURCE_DIR}/examples/${target}.cpp) - target_link_libraries(${target} PUBLIC mllm_llm) - func_set_compile_opts_defs(${target}) - func_link_libs(${target}) + if(EXISTS "${PROJECT_SOURCE_DIR}/examples/${target}.cpp") + add_executable(${target} ${PROJECT_SOURCE_DIR}/examples/${target}.cpp) + target_link_libraries(${target} PUBLIC mllm_llm) + func_set_compile_opts_defs(${target}) + func_link_libs(${target}) + else() + message(WARNING "Skip ${target}: ${PROJECT_SOURCE_DIR}/examples/${target}.cpp not found") + endif() endmacro() macro(func_vlm_add_executable target) - add_executable(${target} ${PROJECT_SOURCE_DIR}/examples/${target}.cpp) - target_link_libraries(${target} PUBLIC mllm_vlm) - func_set_compile_opts_defs(${target}) - func_link_libs(${target}) + if(EXISTS "${PROJECT_SOURCE_DIR}/examples/${target}.cpp") + add_executable(${target} ${PROJECT_SOURCE_DIR}/examples/${target}.cpp) + target_link_libraries(${target} PUBLIC mllm_vlm) + func_set_compile_opts_defs(${target}) + func_link_libs(${target}) + else() + message(WARNING "Skip ${target}: ${PROJECT_SOURCE_DIR}/examples/${target}.cpp not found") + endif() endmacro() func_llm_add_executable(mllm_benchmark) @@ -94,6 +105,7 @@ func_llm_add_executable(demo_llama3) func_llm_add_executable(demo_minicpm_moe_mbm) func_llm_add_executable(demo_qwen_sd) func_llm_add_executable(demo_minicpm_moe_mbp) +func_llm_add_executable(test) func_vlm_add_executable(demo_llava) func_vlm_add_executable(demo_fuyu) diff --git a/include/Types.hpp b/include/Types.hpp index 78e7b127a..1f1611310 100644 --- a/include/Types.hpp +++ b/include/Types.hpp @@ -487,7 +487,7 @@ static size_t DataTypeSize(DataType dtype, uint64_t count = 1) { } #ifdef __cplusplus namespace mllm { -// TODO: copy from MNN; need to recode +// TODO: copy from MNN; need to recode #UNUSED struct BackendConfig { enum MemoryMode { Memory_Normal = 0, diff --git a/src/Backend.hpp b/src/Backend.hpp index 38af3f146..ccd75dda7 100644 --- a/src/Backend.hpp +++ b/src/Backend.hpp @@ -4,6 +4,7 @@ #include "MemoryManager.hpp" #include "OpDefined.hpp" #include "Types.hpp" +#include #include #include #include @@ -16,6 +17,7 @@ class Tensor; class Backend; class Module; class Layer; +struct DeviceMemory; // KVCache map for QNN-CPU KVCache sharing static std::unordered_map kv_cache_map; @@ -28,6 +30,7 @@ class TensorFunction { }; class Backend { public: + Backend(){}; Backend(shared_ptr &mm) : mem_manager_(mm) { } @@ -51,6 +54,21 @@ class Backend { mem_manager_->free(ptr); } + virtual void alloc_device(DeviceMemory &mem, DataType dtype){ + assert(type_ != MLLM_CPU && "alloc_device should not be called on CPU backend"); + } + virtual void free_device(DeviceMemory &mem) { + assert(type_ != MLLM_CPU && "free_device should not be called on CPU backend"); + } + virtual void copy_from_host(const DeviceMemory &dest, const void *src) { + assert(type_ != MLLM_CPU && "copy_from_host should be handled by specific backends"); + } + virtual void copy_to_host(void *dest, const DeviceMemory &src) { + assert(type_ != MLLM_CPU && "copy_to_host should be handled by specific backends"); + } + + virtual void convert_fp_data(Tensor *src, Tensor *dest) {}; + /** * \brief Creates an operation(Op) with the given parameters. * \param op_param The parameters for the operation to be created. @@ -71,12 +89,6 @@ class Backend { * @param in_place Whether to run the function in place. * @return std::vector The output tensors. */ - // virtual std::vector runFunc( - // std::vector out_names, - // TensorFuncType type, - // std::vector float_args, - // std::vector input_tensors, - // bool in_place) = 0; virtual std::vector runLayer(Layer *layer, std::vector inputs, int N) = 0; virtual std::vector runOp(Op *op, std::vector input, std::vector out_names, bool in_place) = 0; diff --git a/src/Module.hpp b/src/Module.hpp index f4999f37a..a2bc37af7 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -13,6 +13,7 @@ #include "Trace.hpp" #include "Types.hpp" #include "backends/cpu/CPUBackend.hpp" +#include "backends/opencl/OpenCLBackend.hpp" #include #include #include @@ -114,6 +115,13 @@ class Module { Backend::global_backends[MLLM_CPU] = new CPUBackend(mm); break; } +#ifdef USE_OPENCL + case BackendType::MLLM_OPENCL: { + BackendConfig config; + Backend::global_backends[MLLM_OPENCL] = new OpenCLBackend(config); + break; + } +#endif #ifdef USE_QNN case BackendType::MLLM_QNN: { Backend::global_backends.emplace(MLLM_QNN, GetBackendCreator(MLLM_QNN)->create({})); diff --git a/src/Tensor.cpp b/src/Tensor.cpp index 2e665fed1..9d03b0b67 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -2,26 +2,27 @@ #include #include -#include +// #include #include #include "Backend.hpp" #include "Op.hpp" #include "OpDefined.hpp" -#include "Timing.hpp" +#include "TensorImpl.hpp" +// #include "Timing.hpp" #include "Types.hpp" #include #include -#include +// #include #include #include namespace mllm { /* Tensor类构造函数实现(对应头文件中的声明)*/ -Tensor::Tensor(const int batch, const int head, const int sequence, const int dimension) : - impl_(std::make_shared()) { // 初始化impl_ - reshape(batch, head, sequence, dimension); -} +// Tensor::Tensor(const int batch, const int head, const int sequence, const int dimension) : +// impl_(std::make_shared()) { // 初始化impl_ +// reshape(batch, head, sequence, dimension); +// } Tensor::Tensor(int batch, int head, int sequence, int dimension, Backend *bn, bool do_alloc) : impl_(std::make_shared(bn)) { // 使用带Backend的TensorImpl构造函数 @@ -34,6 +35,9 @@ Tensor::Tensor(int batch, int head, int sequence, int dimension, Backend *bn, bo Tensor::Tensor(int batch, int head, int sequence, int dimension, BackendType bn_type, bool do_alloc) : impl_(std::make_shared()) { + if (Backend::global_backends.find(bn_type) == Backend::global_backends.end()) { + Module::initBackend(bn_type); + } impl_->dtype_ = MLLM_TYPE_F32; impl_->backend_ = Backend::global_backends[bn_type]; reshape(batch, head, sequence, dimension); @@ -180,7 +184,16 @@ Tensor &Tensor::to(BackendType backend_type) { this->setBackend(Backend::global_backends[backend_type]); return *this; } - + Backend* target_backend = Backend::global_backends[backend_type]; + if (target_backend == nullptr) { + Module::initBackend(backend_type); + target_backend = Backend::global_backends[backend_type]; + assert(target_backend != nullptr && "Target backend is not initialized."); + } + // if (backend_type = MLLM_OPENCL){ + // impl_->location_ = TensorImpl::ON_DEVICE; // OpenCL backend should always be on device + // } + impl_->to(target_backend); return *this; }; @@ -293,7 +306,6 @@ void Tensor::_allocate_aggregated_tensor( * @param template_tensor The template tensor to base the allocation on. */ void Tensor::allocFromTemplate(shared_ptr template_tensor){ - assert(module() != nullptr); assert(backend() != nullptr); if (template_tensor!= nullptr && !template_tensor->aggregatedTensors().empty()) { _allocate_aggregated_tensor(template_tensor, module(), backend()); diff --git a/src/Tensor.hpp b/src/Tensor.hpp index e9b298cfb..d43a6f9c1 100644 --- a/src/Tensor.hpp +++ b/src/Tensor.hpp @@ -110,7 +110,7 @@ class Tensor { * \param sequence tokens numbers in a sequence * \param dimension the hidden size */ - explicit Tensor(int batch, int head, int sequence, int dimension); + // explicit Tensor(int batch, int head, int sequence, int dimension); explicit Tensor(int batch, int head, int sequence, int dimension, Backend *bn, bool do_alloc = true); explicit Tensor(int batch, int head, int sequence, int dimension, BackendType bn_type = MLLM_CPU, bool do_alloc = true); /** @@ -358,6 +358,27 @@ class Tensor { return (Dtype *)impl_->host_ptr_; } + /** + * @brief 获取设备内存的通用描述符。 + * @return DeviceMemory& 对设备内存描述符的引用。 + */ + DeviceMemory& device_memory() { + if(backend() == nullptr || backend()->type() == MLLM_CPU) { + throw std::runtime_error("Device memory is not available for CPU backend."); + } + return impl_->device_memory_; + } + + /** + * @brief 获取设备内存的通用描述符 (const 版本)。 + * @return const DeviceMemory& 对设备内存描述符的常量引用。 + */ + const DeviceMemory& device_memory() const { + if(backend() == nullptr || backend()->type() == MLLM_CPU) { + throw std::runtime_error("Device memory is not available for CPU backend."); + } + return impl_->device_memory_; + } /** * \brief Get the data at the specified position. * \tparam Dtype Data type, such as float, mllm_fp16_t, etc. @@ -1018,12 +1039,61 @@ class Tensor { } Tensor &to(BackendType backend_type); + + Tensor &cpu() { + return to(MLLM_CPU); + } + Tensor &qnn() { + return to(MLLM_QNN); + } + Tensor &cl() { + return to(MLLM_OPENCL); + } + + Tensor half() { + if (dtype() == MLLM_TYPE_F16) { + return *this; + } + assert(dtype() == MLLM_TYPE_F32 && "Tensor::half() can only be called on an FP32 tensor."); + assert(master_tensor_ == nullptr && "Conversion not supported for child tensors."); + if(allocted()) { + Tensor half_tensor(batch(), head(), sequence(), dimension(), backend(), false); + half_tensor.setDtype(MLLM_TYPE_F16); + half_tensor.alloc(); + backend()->convert_fp_data(this, &half_tensor); + return half_tensor; + }else { + impl_->dtype_ = MLLM_TYPE_F16; + return *this; + } + } + Tensor fp16() { + return half(); + } + Tensor fp32() { + if (dtype() == MLLM_TYPE_F32) { + return *this; + } + assert(dtype() == MLLM_TYPE_F16 && "Tensor::fp32() can only be called on an FP16 tensor."); + assert(master_tensor_ == nullptr && "Conversion not supported for child tensors."); + if(allocted()) { + Tensor fp32_tensor(batch(), head(), sequence(), dimension(), backend(), false); + fp32_tensor.setDtype(MLLM_TYPE_F32); + fp32_tensor.alloc(); + backend()->convert_fp_data(this, &fp32_tensor); + return fp32_tensor; + }else { + impl_->dtype_ = MLLM_TYPE_F16; + return *this; + } + } + static vector toDevice(vector inputs, BackendType backend_type) { for (auto &input : inputs) { if (input.device() != backend_type) { input.to(backend_type); } - } + } return inputs; }; static vector toCPU(vector inputs) { diff --git a/src/TensorImpl.hpp b/src/TensorImpl.hpp index a9a430071..e480d105a 100644 --- a/src/TensorImpl.hpp +++ b/src/TensorImpl.hpp @@ -10,12 +10,6 @@ #include #endif #include -// #include -// #include -// #include -// #include -// #include -// #include #include "OpDefined.hpp" #include "Backend.hpp" @@ -25,18 +19,55 @@ namespace mllm { class Backend; class Module; +enum DeviceMemType { + MEM_TYPE_GENERIC, // 通用设备指针 (可用于 CUDA 的 `cudaMalloc` 结果) + MEM_TYPE_BUFFER, // OpenCL 缓冲区 (cl_buffer) + MEM_TYPE_IMAGE_2D, // OpenCL 2D图像 (cl_image) + MEM_TYPE_IMAGE_3D, // OpenCL 3D图像 (cl_image) + MEM_TYPE_TEXTURE, // 没用 +}; + +// 通用设备内存描述符结构体 +struct DeviceMemory { + void* handle = nullptr; // 通用句柄 (存放 cl_mem, cuda pointer, etc.) + DeviceMemType type = MEM_TYPE_BUFFER; // 内存类型,默认为 Buffer + + // 后端无关的元数据 + size_t size_in_bytes = 0; + + // 专门为 Image 类型准备的元数据 + size_t image_width = 0; + size_t image_height = 0; + size_t image_depth = 0; // 用于 3D 图像 + + size_t image_row_pitch_in_bytes = 0; +}; + + class TensorImpl { public: + + + void *host_ptr_ = nullptr; bool owns_host_ptr_ = true; std::shared_ptr memory_handle_ = nullptr; + //=====GPU====== + enum Location { + UNSPECIFIED, // 未指定位置 + ON_HOST, // 在主机 (CPU) 内存中 + ON_DEVICE // 在设备 (如 OpenCL GPU) 内存中 + }; + Location location_ = ON_HOST; // 默认位置设为 ON_HOST, + DeviceMemory device_memory_; + //=====GPU====== + std::map chls_ = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; string name_; DataType dtype_ = MLLM_TYPE_F32; ChlType ctype_ = BSHD; Backend *backend_ = nullptr; - void *host_ptr_ = nullptr; vector shape_; uint64_t capacity_ = 0; @@ -55,6 +86,9 @@ class TensorImpl { TensorImpl() = default; TensorImpl(Backend *bn) : backend_(bn) { + if(backend_->type() == MLLM_OPENCL) { + location_ = ON_DEVICE; + } } // 析构函数负责资源释放 @@ -63,6 +97,10 @@ class TensorImpl { if (backend_) { backend_->free(host_ptr_); } + }else if (device_memory_.handle != nullptr) { + if (backend_) { + backend_->free_device(device_memory_); // 通过 backend 释放 + } } } @@ -74,6 +112,17 @@ class TensorImpl { return DataTypeSize(dtype_, count_); } void alloc() { + if (location_ == ON_DEVICE) { + if (device_memory_.handle != nullptr) return; + if (host_ptr_ != nullptr && owns_host_ptr_) { + backend_->free(host_ptr_); + host_ptr_ = nullptr; + allocated_ = 0; + } + device_memory_.size_in_bytes = cntSize(); + backend_->alloc_device(device_memory_, dtype_); + return; + } if (allocated_ != count_) { if (host_ptr_ != nullptr && owns_host_ptr_) { backend_->free(host_ptr_); @@ -86,16 +135,75 @@ class TensorImpl { } } + void free_memory() { + if (location_ == ON_HOST && host_ptr_ != nullptr && owns_host_ptr_) { + if (backend_) backend_->free(host_ptr_); + } + else if (location_ == ON_DEVICE && device_memory_.handle != nullptr) { + if (backend_) backend_->free_device(device_memory_); + device_memory_.handle = nullptr; // 清理句柄 + } + host_ptr_ = nullptr; + allocated_ = 0; + } + + // 保留旧的 free() 接口,但让它调用新的 free_memory() void free() { - if (host_ptr_ != nullptr && owns_host_ptr_) { // 直接访问成员变量 - if (backend_) { - backend_->free(host_ptr_); + free_memory(); + } + + // void free() { + // if (host_ptr_ != nullptr && owns_host_ptr_) { // 直接访问成员变量 + // if (backend_) { + // backend_->free(host_ptr_); + // } + // host_ptr_ = nullptr; + // allocated_ = 0; + // } + // } + + + void to(Backend *target_backend) { + if (backend_ == target_backend) { + return; + } + // 路径1: 从任何后端迁移到主机 (CPU) + if (target_backend->type() == MLLM_CPU) { + if (location_ == ON_DEVICE) { // 从设备迁移到Host + void* new_host_ptr = nullptr; + target_backend->alloc(&new_host_ptr, cntSize() + 16, 128); + backend_->copy_to_host(new_host_ptr, device_memory_); + backend_->free_device(device_memory_); + host_ptr_ = new_host_ptr; + // cl_device_buffer_ = nullptr; + device_memory_.handle = nullptr; + location_ = ON_HOST; + allocated_ = count_; + } + } + // 路径2: 从主机 (CPU) 迁移到某个设备 + else if (backend_->type() == MLLM_CPU) { + if (location_ == ON_HOST) { + device_memory_.size_in_bytes = cntSize(); + target_backend->alloc_device(device_memory_, dtype_); + target_backend->copy_from_host(device_memory_, host_ptr_); + if (owns_host_ptr_) { + backend_->free(host_ptr_); + } + host_ptr_ = nullptr; + location_ = ON_DEVICE; + allocated_ = 0; } - host_ptr_ = nullptr; - allocated_ = 0; } + else { + std::cout << "Device -> Device migration via Host" << std::endl; + this->to(Backend::global_backends[MLLM_CPU]); + this->to(target_backend); + } + backend_ = target_backend; } + // int canonicalAxisIndex(int axis_index) const { if (axis_index < 0) { diff --git a/src/backends/cpu/CPUBackend.cpp b/src/backends/cpu/CPUBackend.cpp index 4486888a0..29c0d69e0 100644 --- a/src/backends/cpu/CPUBackend.cpp +++ b/src/backends/cpu/CPUBackend.cpp @@ -152,7 +152,7 @@ CPUBackend::CPUBackend(shared_ptr &mm) : Backend(mm) { type_ = BackendType::MLLM_CPU; registerOps(); - registerFuncs(); + // registerFuncs(); } Op *CPUBackend::opCreate(const OpParam &op_param, string name, int threadCount) { @@ -271,46 +271,29 @@ TensorFunction *CPUBackend::funcCreate(const TensorFuncType type) { } void CPUBackend::registerFuncs(){ - // map_function_[TensorFuncType::FUNC_ADD] = new CPUaddFunction(); - // map_function_[TensorFuncType::FUNC_SUB] = new CPUsubFunction(); - // map_function_[TensorFuncType::FUNC_MUL] = new CPUmulFunction(); - // map_function_[TensorFuncType::FUNC_DIV] = new CPUdivFunction(); - // map_function_[TensorFuncType::FUNC_DIVINT] = new CPUdivintFunction(); - // map_function_[TensorFuncType::FUNC_TTADD] = new CPUaddTwoFunction(); - // map_function_[TensorFuncType::FUNC_TTSUB] = new CPUsubTwoFunction(); - // map_function_[TensorFuncType::FUNC_TTMUL] = new CPUmulTwoFunction(); - // map_function_[TensorFuncType::FUNC_TTDIV] = new CPUdivTwoFunction(); - // map_function_[TensorFuncType::FUNC_MM] = new CPUmmFunction(); - // map_function_[TensorFuncType::FUNC_NORM] = new CPUnormFunction(); - // map_function_[TensorFuncType::FUNC_MEAN] = new CPUmeanFunction(); - // map_function_[TensorFuncType::FUNC_CAT] = new CPUcatFunction(); - // map_function_[TensorFuncType::FUNC_VIEW] = new CPUviewFunction(); - // map_function_[TensorFuncType::FUNC_TRANPOSE] = new CPUtransposeFunction(); - // map_function_[TensorFuncType::FUNC_FLATTEN] = new CPUflattenFunction(); - // map_function_[TensorFuncType::FUNC_CLIP] = new CPUclipFunction(); - // map_function_[TensorFuncType::FUNC_CLIPAXIS] = new CPUclipaxisFunction(); - // map_function_[TensorFuncType::FUNC_CLIPTENSOR] = new CPUcliptensorFunction(); - // map_function_[TensorFuncType::FUNC_RANGE] = new CPURangeFunction(); - // map_function_[TensorFuncType::FUNC_WHERE] = new CPUwhereFunction(); - // map_function_[TensorFuncType::FUNC_INDEX_PUT] = new CPUIndexPutFunction(); - // map_function_[TensorFuncType::FUNC_SPLIT] = new CPUsplitFunction(); - // map_function_[TensorFuncType::FUNC_SUM] = new CPUsumFunction(); - // map_function_[TensorFuncType::FUNC_TOPK] = new CPUtopkFunction(); - // map_function_[TensorFuncType::FUNC_EXPPAND] = new CPUexpandFunction(); - // map_function_[TensorFuncType::FUNC_ARGSORT] = new CPUargsortFunction(); - // map_function_[TensorFuncType::FUNC_BINCOUNT] = new CPUbincountFunction(); - // map_function_[TensorFuncType::FUNC_REPEAT] = new CPUrepeatFunction(); - // map_function_[TensorFuncType::FUNC_LIKE] = new CPUlikeFunction(); - // map_function_[TensorFuncType::FUNC_SCATTERREDUCE] = new CPUScatterReduceFunction(); - // map_function_[TensorFuncType::FUNC_APPLY_VISIOROPE] = new CPUVisionRoPEFuncFunction(); - // map_function_[TensorFuncType::FUNC_FA2] = new CPUFlashAttention2Func(); - // // models use only - // map_function_[TensorFuncType::FUNC_FUYU_GATHER_EMBD] = new CPUFuyuGatherEmbdFunc(); - // map_function_[TensorFuncType::FUNC_PHI3V_HD_MERGE] = new CPUPhi3VhdmergeFunction(); + ; }; int CPUBackend::cpu_threads = 4; +void CPUBackend::convert_fp_data(Tensor *src, Tensor *dest) { + // 根据源和目标的类型,执行相应的CPU循环转换 + if (src->dtype() == MLLM_TYPE_F32 && dest->dtype() == MLLM_TYPE_F16) { + float* src_ptr = src->hostPtr(); + mllm_fp16_t* dst_ptr = dest->hostPtr(); + for (int i = 0; i < src->count(); i++) { + dst_ptr[i] = MLLM_FP32_TO_FP16(src_ptr[i]); + } + } else if (src->dtype() == MLLM_TYPE_F16 && dest->dtype() == MLLM_TYPE_F32) { + mllm_fp16_t* src_ptr = src->hostPtr(); + float* dst_ptr = dest->hostPtr(); + for (int i = 0; i < src->count(); i++) { + dst_ptr[i] = MLLM_FP16_TO_FP32(src_ptr[i]); + } + } else { + throw std::runtime_error("Unsupported conversion types for CPU backend."); + } +} /************************************************************************************************/ /* Refactored Helper Functions */ /************************************************************************************************/ @@ -428,8 +411,9 @@ void CPUBackend::_create_output_tensors( std::vector CPUBackend::runOp(Op *op, std::vector inputs, std::vector out_names, bool in_place) { Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); - map> &activation_tensors = module->activation_tensors; - if (module->doTrace) { // trace + static map> empty_activation_tensors; + map> &activation_tensors = module ? module->activation_tensors : empty_activation_tensors; + if (module && module->doTrace) { // trace for (const auto &out_name : out_names) { if (activation_tensors.find(out_name) == activation_tensors.end()) { activation_tensors[out_name] = std::make_shared(op->backend()); diff --git a/src/backends/cpu/CPUBackend.hpp b/src/backends/cpu/CPUBackend.hpp index 0ae291e1f..49ad327c4 100644 --- a/src/backends/cpu/CPUBackend.hpp +++ b/src/backends/cpu/CPUBackend.hpp @@ -97,6 +97,8 @@ class CPUBackend final : public Backend { bool isUsingDraft() { return usingDraft; } + + void convert_fp_data(Tensor *src, Tensor *dest) override; // #endif private: std::map map_creator_; diff --git a/src/backends/cpu/function/CPUArgSortFunc.hpp b/src/backends/cpu/function/CPUArgSortFunc.hpp deleted file mode 100644 index f1a3976a4..000000000 --- a/src/backends/cpu/function/CPUArgSortFunc.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// -// Created by Rongjie Yi on 24-12-16. -// - -#ifndef CPUARGSORTKFUNC_HPP -#define CPUARGSORTKFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include - -namespace mllm { -class Tensor; - -class CPUargsortFunction : public TensorFunction { - // 自定义比较函数,用于对索引进行排序 - bool compareIndices(const std::pair &a, const std::pair &b) { - return a.second < b.second; - } - void argsort(float *input, int size, float *out_indices) { - std::vector> indexedInput(size); - for (int i = 0; i < size; ++i) { - indexedInput[i] = std::make_pair(i, input[i]); - } - std::sort(indexedInput.begin(), indexedInput.end(), [this](const std::pair &a, const std::pair &b) { - return compareIndices(a, b); - }); - for (int i = 0; i < size; ++i) { - out_indices[i] = static_cast(indexedInput[i].first); - } - } - -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - assert(args.empty()); - assert(inputs[0]->sequence() == 1); - assert(inputs[0]->head() == 1); - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->setDtype(inputs[0]->dtype()); // argsortk_values - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - int size = inputs[0]->dimension(); - for (int b = 0; b < inputs[0]->batch(); b++) { - float *data = inputs[0]->ptrAt(b, 0, 0, 0); - float *out = outputs[0]->ptrAt(b, 0, 0, 0); - argsort(data, size, out); - } - } -}; -} // namespace mllm -#endif // CPUARGSORTKFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUBinCountFunc.hpp b/src/backends/cpu/function/CPUBinCountFunc.hpp deleted file mode 100644 index 7d834cf06..000000000 --- a/src/backends/cpu/function/CPUBinCountFunc.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// -// Created by Rongjie Yi on 24-12-16. -// - -#ifndef CPUBINCOUNTKFUNC_HPP -#define CPUBINCOUNTKFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include -#include "CPUBackend.hpp" - -namespace mllm { -class Tensor; - -class CPUbincountFunction : public TensorFunction { - void bincount(float *input, int size, float *out, int max_val) { - // 找到输入数组中的最大值 - // int max_val = 0; - // for (int i = 0; i < size; ++i) { - // int val = static_cast(input[i]); - // if (val > max_val) { - // max_val = val; - // } - // } - - // 初始化输出数组 -#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) - for (int i = 0; i <= max_val; ++i) { - out[i] = 0; - } - - // 计算每个值的出现次数 - // #pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) - for (int i = 0; i < size; ++i) { - int index = static_cast(input[i]); - if (index >= 0 && index <= max_val) { - out[index] += 1; - } - } - } - -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - assert(args.empty()); - assert(inputs[0]->batch() == 1); - assert(inputs[0]->sequence() == 1); - assert(inputs[0]->head() == 1); - outputs[0]->reshape(1, 1, 1, 0); - // outputs[0]->setDtype(inputs[0]->dtype()); // bincountk_values - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - int size = inputs[0]->dimension(); - int max_val = 0; - for (int i = 0; i < size; ++i) { - int val = static_cast(inputs[0]->dataAt(0, 0, 0, i)); - if (val > max_val) { - max_val = val; - } - } - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), max_val + 1); - outputs[0]->setDtype(inputs[0]->dtype()); // bincountk_values - outputs[0]->alloc(); - float *data = inputs[0]->hostPtr(); - float *out = outputs[0]->hostPtr(); - if (max_val > 0) { - bincount(data, size, out, max_val); - } - } -}; -} // namespace mllm -#endif // CPUBINCOUNTKFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUBinaryFunc.hpp b/src/backends/cpu/function/CPUBinaryFunc.hpp deleted file mode 100644 index 446fa84e0..000000000 --- a/src/backends/cpu/function/CPUBinaryFunc.hpp +++ /dev/null @@ -1,264 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUBINARYFUNC_HPP -#define CPUBINARYFUNC_HPP -#include "CPUBackend.hpp" -#include "Tensor.hpp" -#include "Types.hpp" -#include "../compute/Arithmetic.hpp" - -namespace mllm { -class Tensor; - -class CPUaddFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - // float data = (float)args[0]; - auto input = inputs[0]; - auto output = outputs[0]; - output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); - output->setDtype(input->dtype()); - output->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - float data = (float)args[0]; - auto input = inputs[0]; - auto output = outputs[0]; -#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) - for (int n = 0; n < input->batch(); ++n) { - for (int c = 0; c < input->head(); ++c) { - for (int h = 0; h < input->sequence(); ++h) { - mllm_add_fp32(input->ptrAt(n, c, h, 0), data, - outputs[0]->ptrAt(n, c, h, 0), input->dimension()); - } - } - } - } -}; -class CPUsubFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - auto input = inputs[0]; - auto output = outputs[0]; - output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); - output->setDtype(input->dtype()); - output->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - float data = (float)args[0]; - auto input = inputs[0]; - auto output = outputs[0]; -#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) - for (int n = 0; n < input->batch(); ++n) { - for (int c = 0; c < input->head(); ++c) { - for (int h = 0; h < input->sequence(); ++h) { - mllm_sub_fp32(input->ptrAt(n, c, h, 0), data, - outputs[0]->ptrAt(n, c, h, 0), input->dimension()); - } - } - } - } -}; -class CPUmulFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - auto input = inputs[0]; - auto output = outputs[0]; - output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); - output->setDtype(input->dtype()); - output->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - float data = (float)args[0]; - auto input = inputs[0]; - auto output = outputs[0]; -#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) - for (int n = 0; n < input->batch(); ++n) { - for (int c = 0; c < input->head(); ++c) { - for (int h = 0; h < input->sequence(); ++h) { - mllm_mul_fp32(input->ptrAt(n, c, h, 0), data, - outputs[0]->ptrAt(n, c, h, 0), input->dimension()); - } - } - } - } -}; -class CPUdivFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - auto input = inputs[0]; - auto output = outputs[0]; - output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); - output->setDtype(input->dtype()); - output->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - float data = (float)args[0]; - auto input = inputs[0]; - auto output = outputs[0]; -#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) - for (int n = 0; n < input->batch(); ++n) { - for (int c = 0; c < input->head(); ++c) { - for (int h = 0; h < input->sequence(); ++h) { - mllm_div_fp32(input->ptrAt(n, c, h, 0), data, - outputs[0]->ptrAt(n, c, h, 0), input->dimension()); - } - } - } - } -}; - -class CPUdivintFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - auto input = inputs[0]; - auto output = outputs[0]; - output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); - output->setDtype(input->dtype()); - output->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - float data = (float)args[0]; - auto input = inputs[0]; - auto output = outputs[0]; -#pragma omp parallel for collapse(4) num_threads(CPUBackend::cpu_threads) - for (int n = 0; n < input->batch(); ++n) { - for (int c = 0; c < input->head(); ++c) { - for (int h = 0; h < input->sequence(); ++h) { - for (int d = 0; d < input->dimension(); ++d) { - outputs[0]->setDataAt(n, c, h, d, - static_cast(input->dataAt(n, c, h, d) / data)); - } - } - } - } - } -}; - -class CPUaddTwoFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), - inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - }; - void execute(vector> outputs, vector> inputs, vector args) override { - auto input0 = inputs[0]; - auto input1 = inputs[1]; - int batch_ = std::max(input0->batch(), input1->batch()); - for (int n = 0; n < batch_; ++n) { - auto n_0 = std::min(n, input0->batch() - 1); - auto n_1 = std::min(n, input1->batch() - 1); -#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) - for (int c = 0; c < input0->head(); ++c) { - for (int h = 0; h < input0->sequence(); ++h) { - mllm_add_fp32(input0->ptrAt(n_0, c, h, 0), - input1->ptrAt(n_1, c, h, 0), - outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); - } - } - } - }; -}; -class CPUsubTwoFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), - inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - }; - void execute(vector> outputs, vector> inputs, vector args) override { - auto input0 = inputs[0]; - auto input1 = inputs[1]; - int batch_ = std::max(input0->batch(), input1->batch()); - for (int n = 0; n < batch_; ++n) { - auto n_0 = std::min(n, input0->batch() - 1); - auto n_1 = std::min(n, input1->batch() - 1); -#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) - for (int c = 0; c < input0->head(); ++c) { - for (int h = 0; h < input0->sequence(); ++h) { - mllm_sub_fp32(input0->ptrAt(n_0, c, h, 0), - input1->ptrAt(n_1, c, h, 0), - outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); - } - } - } - }; -}; -class CPUmulTwoFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), - inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - }; - void execute(vector> outputs, vector> inputs, vector args) override { - if (outputs[0]->sequence() == 0 - || inputs[0]->sequence() != outputs[0]->sequence()) { - outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), - inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->alloc(); - } - auto input0 = inputs[0]; - auto input1 = inputs[1]; - int batch_ = std::max(input0->batch(), input1->batch()); - for (int n = 0; n < batch_; ++n) { - auto n_0 = std::min(n, input0->batch() - 1); - auto n_1 = std::min(n, input1->batch() - 1); -#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) - for (int c = 0; c < input0->head(); ++c) { - for (int h = 0; h < input0->sequence(); ++h) { - if (input1->dimension() == 1) { - mllm_mul_fp32(input0->ptrAt(n_0, c, h, 0), - input1->dataAt(n_1, c, h, 0), - outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); - } else { - mllm_mul_fp32(input0->ptrAt(n_0, c, h, 0), - input1->ptrAt(n_1, c, h, 0), - outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); - } - } - } - } - }; -}; -class CPUdivTwoFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), - inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - }; - void execute(vector> outputs, vector> inputs, vector args) override { - auto input0 = inputs[0]; - auto input1 = inputs[1]; - int batch_ = std::max(input0->batch(), input1->batch()); - for (int n = 0; n < batch_; ++n) { - auto n_0 = std::min(n, input0->batch() - 1); - auto n_1 = std::min(n, input1->batch() - 1); -#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) - for (int c = 0; c < input0->head(); ++c) { - for (int h = 0; h < input0->sequence(); ++h) { - if (input1->dimension() == 1) { - mllm_div_fp32(input0->ptrAt(n_0, c, h, 0), - input1->dataAt(n_1, c, h, 0), - outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); - } else { - mllm_div_fp32(input0->ptrAt(n_0, c, h, 0), - input1->ptrAt(n_1, c, h, 0), - outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); - } - } - } - } - }; -}; - -} // namespace mllm -#endif // CPUBINARYFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUCatFunc.hpp b/src/backends/cpu/function/CPUCatFunc.hpp deleted file mode 100644 index 381bb56fd..000000000 --- a/src/backends/cpu/function/CPUCatFunc.hpp +++ /dev/null @@ -1,377 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUCATFUNC_HPP -#define CPUCATFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "CPUBackend.hpp" -#include - -namespace mllm { -class Tensor; - -class CPUcatFunction : public TensorFunction { -public: - void setUp(vector> outputs, vector> inputs, vector args) override { - Chl axis = (Chl)args[0]; - if (outputs[0]->shape().empty()) { - int expd_batch_ = inputs[0]->batch(); - for (int ii = 0; ii < inputs.size(); ++ii) { - auto input = inputs[ii]; - if (input->batch() > expd_batch_) { - expd_batch_ = input->batch(); - } - } - int dim_b = expd_batch_; - int dim_h = inputs[0]->head(); - int dim_s = inputs[0]->sequence(); - int dim_d = inputs[0]->dimension(); - int sizes[] = {0, 0, 0, 0}; - Chl axes[] = {BATCH, HEAD, SEQUENCE, DIMENSION}; - int *dims[] = {&dim_b, &dim_h, &dim_s, &dim_d}; - for (int i = 0; i < 4; i++) { - if (axis == axes[i]) { - for (auto input : inputs) { - sizes[i] += (i == 0) ? input->batch() : (i == 1) ? input->head() : - (i == 2) ? input->sequence() : - input->dimension(); - } - *dims[i] = sizes[i]; - break; - } - } - outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - if (axis == HEAD) { - int cbatch = 0; - int chead = 0; - int cseq = 0; - int cdim = 0; - if (inputs[0]->hostPtr() == inputs[1]->hostPtr()) { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - inputs[0]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); - } else { - for (int idx = 0; idx < inputs.size(); idx++) { - if (inputs[idx]->masterTensor() == nullptr) { - inputs[idx]->free(); - } - if (idx > 0) { - chead += inputs[idx - 1]->head(); - } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d - } - } - } else if (axis == SEQUENCE && inputs[0]->head() != 1) { - int cbatch = 0; - int chead = 0; - int cseq = 0; - int cdim = 0; - for (int idx = 0; idx < inputs.size(); idx++) { - if (inputs[idx]->masterTensor() == nullptr) { - inputs[idx]->free(); - } - if (idx > 0) { - cseq += inputs[idx - 1]->sequence(); - } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d - } - } else if (axis == DIMENSION && inputs[0]->head() != 1) { - int cbatch = 0; - int chead = 0; - int cseq = 0; - int cdim = 0; - for (int idx = 0; idx < inputs.size(); idx++) { - if (inputs[idx]->masterTensor() == nullptr) { - inputs[idx]->free(); - } - if (idx > 0) { - cdim += inputs[idx - 1]->dimension(); - } - int tmp_agg_idx; - if (inputs[idx]->deaggregatedTensor() != nullptr) { - for (int t = 0; t < inputs[idx]->deaggregatedTensor()->aggregatedTensors().size(); t++) { - if (inputs[idx]->deaggregatedTensor()->aggregatedTensors()[t] == inputs[idx]) { - tmp_agg_idx = t; - continue; - } - } - } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d - if (inputs[idx]->deaggregatedTensor() != nullptr) { - vector> shared_outputs = {}; - for (int t = 0; t < inputs[idx]->deaggregatedTensor()->aggregatedTensors().size(); t++) { - if (t == tmp_agg_idx) { - inputs[idx]->deaggregatedTensor()->aggregatedTensors()[t] = inputs[idx]; - // std::shared_ptr(inputs[idx], [](Tensor *) {}); - } - } - } - } - } - } - - void reshape(vector> outputs, vector> inputs, vector args) override { - Chl axis = (Chl)args[0]; - int expd_batch_ = inputs[0]->batch(); - for (int ii = 0; ii < inputs.size(); ++ii) { - auto input = inputs[ii]; - if (input->batch() > expd_batch_) { - expd_batch_ = input->batch(); - } - } - int dim_b = expd_batch_; - int dim_h = inputs[0]->head(); - int dim_s = inputs[0]->sequence(); - int dim_d = inputs[0]->dimension(); - int sizes[] = {0, 0, 0, 0}; - Chl axes[] = {BATCH, HEAD, SEQUENCE, DIMENSION}; - int *dims[] = {&dim_b, &dim_h, &dim_s, &dim_d}; - for (int i = 0; i < 4; i++) { - if (axis == axes[i]) { - for (auto input : inputs) { - sizes[i] += (i == 0) ? input->batch() : (i == 1) ? input->head() : - (i == 2) ? input->sequence() : - input->dimension(); - } - *dims[i] = sizes[i]; - break; - } - } - outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); - if (outputs[0]->masterTensor() == nullptr) { - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - /* - if (axis == HEAD){ - int cbatch = 0; - int chead = 0; - int cseq = 0; - int cdim = 0; - if(inputs[0]->hostPtr() == inputs[1]->hostPtr()){ - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - inputs[0]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); - }else{ - for (int idx = 0; idx < inputs.size(); idx++) { - if (inputs[idx]->masterTensor() == nullptr) { - inputs[idx]->free(); - } - if (idx > 0) { - chead += inputs[idx - 1]->head(); - } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d - } - } - }else if (axis == SEQUENCE && inputs[0]->head() != 1) { - int cbatch = 0; - int chead = 0; - int cseq = 0; - int cdim = 0; - for (int idx = 0; idx < inputs.size(); idx++) { - if (inputs[idx]->masterTensor() == nullptr) { - inputs[idx]->free(); - } - if (idx > 0) { - cseq += inputs[idx - 1]->sequence(); - } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d - } - } else if (axis == DIMENSION && inputs[0]->head() != 1) { - int cbatch = 0; - int chead = 0; - int cseq = 0; - int cdim = 0; - for (int idx = 0; idx < inputs.size(); idx++) { - if (inputs[idx]->masterTensor() == nullptr) { - inputs[idx]->free(); - } - if (idx > 0) { - cdim += inputs[idx - 1]->dimension(); - } - int tmp_agg_idx; - if (inputs[idx]->deaggregatedTensor() != nullptr) { - for (int t = 0; t < inputs[idx]->deaggregatedTensor()->aggregatedTensors().size(); t++) { - if (inputs[idx]->deaggregatedTensor()->aggregatedTensors()[t].get() == inputs[idx]) { - tmp_agg_idx = t; - continue; - } - } - } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d - if (inputs[idx]->deaggregatedTensor() != nullptr) { - vector> shared_outputs = {}; - for (int t = 0; t < inputs[idx]->deaggregatedTensor()->aggregatedTensors().size(); t++) { - if (t == tmp_agg_idx) { - inputs[idx]->deaggregatedTensor()->aggregatedTensors()[t] = - std::shared_ptr(inputs[idx], [](Tensor *) {}); - } - } - } - } - } - */ - } - void execute(vector> outputs, vector> inputs, vector args) override { - // TOD : FIX THIS WHEN NO MEMCPY - Chl axis = (Chl)args[0]; - int expd_batch_ = inputs[0]->batch(); - int expd_batch_input_idx = 0; - // int expd_head_ = inputs[0]->head(); - // int expd_head_input_idx = 0; - for (int ii = 0; ii < inputs.size(); ++ii) { - auto input = inputs[ii]; - if (input->batch() > expd_batch_) { - expd_batch_ = input->batch(); - expd_batch_input_idx = ii; - } - // if (input->head() > expd_head_) { - // expd_head_ = input->head(); - // expd_head_input_idx = ii; - // } - } - if (axis == BATCH) { - for (int n = 0; n < inputs.size(); ++n) { - auto copysize = inputs[0]->batch() * inputs[0]->head() * inputs[0]->sequence() * inputs[0]->dimension(); - memcpy(outputs[0]->ptrAt(n * inputs[0]->batch(), 0, 0, 0), - inputs[n]->ptrAt(0, 0, 0, 0), - sizeof(float) * copysize); - } - } else if (axis == DIMENSION) { - for (int n = 0; n < expd_batch_; ++n) { - for (int c = 0; c < inputs[0]->head(); ++c) { - for (int h = 0; h < inputs[0]->sequence(); ++h) { - int w = 0; - for (int idx = 0; idx < inputs.size(); idx++) { - int dim_size = inputs[idx]->dimension(); - auto n_ = n; - if (idx != expd_batch_input_idx) { - n_ = 0; - } - assert(inputs[0]->dtype() == outputs[0]->dtype()); - if (inputs[0]->dtype() == MLLM_TYPE_F32) { - memcpy(outputs[0]->ptrAt(n, c, h, w), - inputs[idx]->ptrAt(n_, c, h, 0), - sizeof(float) * (dim_size)); - } else if (inputs[0]->dtype() == MLLM_TYPE_F16) { - memcpy(outputs[0]->ptrAt(n, c, h, w), - inputs[idx]->ptrAt(n_, c, h, 0), - sizeof(mllm_fp16_t) * (dim_size)); - } - w += dim_size; - } - } - } - } - } else if ((axis == SEQUENCE) && inputs[0]->head() != 1) { - // #pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) .//TODO优化 - assert(inputs[0]->head() == inputs[1]->head()); - assert(outputs[0]->ctype() == inputs[0]->ctype()); - for (int n = 0; n < expd_batch_; ++n) { - for (int h = 0; h < inputs[0]->head(); ++h) { - if (inputs[0]->ctype() == BSHD) { - int s_base = 0; - for (int idx = 0; idx < inputs.size(); idx++) { - auto n_ = (idx == expd_batch_input_idx) ? n : 0; - for (int s = 0; s < inputs[idx]->sequence(); ++s) { - if (inputs[0]->dtype() == MLLM_TYPE_F32) { - memcpy(outputs[0]->ptrAt(n, h, s_base + s, 0), - inputs[idx]->ptrAt(n_, h, s, 0), - sizeof(float) * (inputs[idx]->dimension())); - } else if (inputs[0]->dtype() == MLLM_TYPE_F16) { - memcpy(outputs[0]->ptrAt(n, h, s_base + s, 0), - inputs[idx]->ptrAt(n_, h, s, 0), - sizeof(mllm_fp16_t) * (inputs[idx]->dimension())); - } - } - s_base += inputs[idx]->sequence(); - } - } else if (inputs[0]->ctype() == BHDS) { - int s_base = 0; - for (int idx = 0; idx < inputs.size(); idx++) { - auto n_ = (idx == expd_batch_input_idx) ? n : 0; - if (inputs[idx]->ctype() == BSHD) { - for (int s = 0; s < inputs[idx]->sequence(); ++s) { - for (int d = 0; d < inputs[idx]->dimension(); ++d) { - outputs[0]->setDataAt(n, h, s_base + s, d, - inputs[idx]->dataAt(n_, h, s, d)); - } - } - } else { - for (int d = 0; d < inputs[idx]->dimension(); ++d) { - if (inputs[0]->dtype() == MLLM_TYPE_F32) { - memcpy(outputs[0]->ptrAt(n, h, s_base, d), - inputs[idx]->ptrAt(n_, h, 0, d), - sizeof(float) * (inputs[idx]->sequence())); - } else if (inputs[0]->dtype() == MLLM_TYPE_F16) { - memcpy(outputs[0]->ptrAt(n, h, s_base, d), - inputs[idx]->ptrAt(n_, h, 0, d), - sizeof(mllm_fp16_t) * (inputs[idx]->sequence())); - } - } - } - s_base += inputs[idx]->sequence(); - } - } - } - } - } else if ((axis == SEQUENCE) && inputs[0]->head() == 1) { - for (int n = 0; n < expd_batch_; ++n) { - int h = 0; - for (int idx = 0; idx < inputs.size(); idx++) { - auto n_ = n; - if (idx != expd_batch_input_idx) { - n_ = 0; - } - memcpy(outputs[0]->ptrAt(n, 0, h, 0), - inputs[idx]->ptrAt(n_, 0, 0, 0), - sizeof(float) * (inputs[idx]->sequence() * inputs[idx]->dimension())); - h += inputs[idx]->sequence(); - } - } - } else if (axis == HEAD) { - if (inputs[0]->hostPtr() == inputs[1]->hostPtr()) { - for (int b = 0; b < outputs[0]->batch(); ++b) { - for (int s = 0; s < inputs[0]->sequence(); ++s) { - for (int h_ = 1; h_ < outputs[0]->head(); ++h_) { - int dim_size = inputs[0]->dimension(); - memcpy(outputs[0]->ptrAt(b, h_, s, 0), - outputs[0]->ptrAt(b, 0, s, 0), - sizeof(float) * (dim_size)); - } - } - } - return; - } - for (int b = 0; b < expd_batch_; ++b) { -#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) - for (int s = 0; s < inputs[0]->sequence(); ++s) { - // for (int h = 0; h < inputs[0]->head(); ++h) { - int head_i = 0; - for (int idx = 0; idx < inputs.size(); idx++) { - auto b_ = b; - if (idx != expd_batch_input_idx) { - b_ = 0; - } - int dim_size = inputs[idx]->dimension() * inputs[idx]->head(); - memcpy(outputs[0]->ptrAt(b, head_i, s, 0), - inputs[idx]->ptrAt(b_, 0, s, 0), - sizeof(float) * (dim_size)); - head_i += inputs[idx]->head(); - } - // } - } - } - } - } -}; - -} // namespace mllm -#endif // CPUCATFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUClipFunc.hpp b/src/backends/cpu/function/CPUClipFunc.hpp deleted file mode 100644 index d43cb7c72..000000000 --- a/src/backends/cpu/function/CPUClipFunc.hpp +++ /dev/null @@ -1,344 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUCLIPFUNC_HPP -#define CPUCLIPFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "CPUBackend.hpp" - -namespace mllm { -class Tensor; - -class CPUclipFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - int b_size = args[0]; - int h_size = args[1]; - int s_size = args[2]; - int d_size = args[3]; - vector b = {}; - vector h = {}; - vector s = {}; - vector d = {}; - for (int i = 0; i < b_size; i++) { - b.push_back(args[4 + i]); - } - for (int i = 0; i < h_size; i++) { - h.push_back(args[4 + b_size + i]); - } - for (int i = 0; i < s_size; i++) { - s.push_back(args[4 + b_size + h_size + i]); - } - for (int i = 0; i < d_size; i++) { - d.push_back(args[4 + b_size + h_size + s_size + i]); - } - int dim_b = inputs[0]->batch(); - int dim_h = inputs[0]->head(); - int dim_s = inputs[0]->sequence(); - int dim_d = inputs[0]->dimension(); - std::vector, int *>> data = {{b, &dim_b}, {h, &dim_h}, {s, &dim_s}, {d, &dim_d}}; - for (auto &pair : data) { - if (pair.first.size() == 2) { - *pair.second = pair.first[1] - pair.first[0]; - } else if (pair.first.size() == 1) { - *pair.second = 1; - } - } - outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - int b_size = args[0]; - int h_size = args[1]; - int s_size = args[2]; - int d_size = args[3]; - vector b = {}; - vector h = {}; - vector s = {}; - vector d = {}; - for (int i = 0; i < b_size; i++) { - b.push_back(args[4 + i]); - } - for (int i = 0; i < h_size; i++) { - h.push_back(args[4 + b_size + i]); - } - for (int i = 0; i < s_size; i++) { - s.push_back(args[4 + b_size + h_size + i]); - } - for (int i = 0; i < d_size; i++) { - d.push_back(args[4 + b_size + h_size + s_size + i]); - } - int dim_b = inputs[0]->batch(); - int dim_h = inputs[0]->head(); - int dim_s = inputs[0]->sequence(); - int dim_d = inputs[0]->dimension(); - std::vector, int *>> data = {{b, &dim_b}, {h, &dim_h}, {s, &dim_s}, {d, &dim_d}}; - for (auto &pair : data) { - if (pair.first.size() == 2) { - *pair.second = pair.first[1] - pair.first[0]; - } else if (pair.first.size() == 1) { - *pair.second = 1; - } - } - if (outputs[0]->dimension() * outputs[0]->sequence() * outputs[0]->head() * outputs[0]->batch() == 0 - || outputs[0]->shape().empty() - || dim_d != outputs[0]->dimension()) { - outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); - outputs[0]->alloc(); - } - - if (s.size() == 2) { -#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) - for (int b = 0; b < inputs[0]->batch(); ++b) { - memcpy(outputs[0]->hostPtr() + outputs[0]->offset(b, 0, 0, 0), - inputs[0]->hostPtr() + inputs[0]->offset(b, 0, s[0], 0), - inputs[0]->head() * (s[1] - s[0]) * inputs[0]->dimension() * sizeof(float)); - } - } else if (s.size() == 1) { - int seq_idx = s[0]; - if (seq_idx < 0) { - seq_idx = inputs[0]->sequence() + seq_idx; - } -#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) - for (int b = 0; b < inputs[0]->batch(); ++b) { - memcpy(outputs[0]->hostPtr() + outputs[0]->offset(b, 0, 0, 0), - inputs[0]->hostPtr() + inputs[0]->offset(b, 0, seq_idx, 0), - inputs[0]->head() * 1 * inputs[0]->dimension() * sizeof(float)); - } - } else if (b.size() == 1) { - int bth_idx = b[0]; - if (bth_idx < 0) { - bth_idx = inputs[0]->batch() + bth_idx; - } - memcpy(outputs[0]->hostPtr(), - inputs[0]->hostPtr() + inputs[0]->offset(bth_idx, 0, 0, 0), - inputs[0]->head() * inputs[0]->sequence() * inputs[0]->dimension() * sizeof(float)); - } else if (b.size() == 2) { - assert(b[1] - b[0] > 0); - memcpy(outputs[0]->hostPtr(), - inputs[0]->hostPtr() + inputs[0]->offset(b[0], 0, 0, 0), - (b[1] - b[0]) * inputs[0]->head() * inputs[0]->sequence() * inputs[0]->dimension() * sizeof(float)); - } else if (d.size() == 2) { -#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) - for (int b = 0; b < inputs[0]->batch(); ++b) { - for (int s = 0; s < inputs[0]->sequence(); ++s) { - for (int h = 0; h < inputs[0]->head(); ++h) { - memcpy(outputs[0]->hostPtr() + outputs[0]->offset(b, h, s, 0), - inputs[0]->hostPtr() + inputs[0]->offset(b, h, s, d[0]), - (d[1] - d[0]) * sizeof(float)); - } - } - } - } else if (d.size() == 1) { - int seq_idx = d[0]; - if (seq_idx < 0) { - seq_idx = inputs[0]->dimension() + seq_idx; - } -#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) - for (int b = 0; b < inputs[0]->batch(); ++b) { - for (int s = 0; s < inputs[0]->sequence(); ++s) { - for (int h = 0; h < inputs[0]->head(); ++h) { - memcpy(outputs[0]->hostPtr() + outputs[0]->offset(b, h, s, 0), - inputs[0]->hostPtr() + inputs[0]->offset(b, h, s, seq_idx), - sizeof(float)); - } - } - } - } else { - std::cout << "[TODO]Tensor.CLip not support!!!!" << std::endl; - } - } -}; - -class CPUclipaxisFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - Chl axis = (Chl)args[0]; - int b_size = args[1]; - int h_size = args[2]; - int s_size = args[3]; - int d_size = args[4]; - vector b = {}; - vector h = {}; - vector s = {}; - vector d = {}; - for (int i = 0; i < b_size; i++) { - b.push_back(args[5 + i]); - } - for (int i = 0; i < h_size; i++) { - h.push_back(args[5 + b_size + i]); - } - for (int i = 0; i < s_size; i++) { - s.push_back(args[5 + b_size + h_size + i]); - } - for (int i = 0; i < d_size; i++) { - d.push_back(args[5 + b_size + h_size + s_size + i]); - } - int dim_b = inputs[0]->batch(); - int dim_h = inputs[0]->head(); - int dim_s = inputs[0]->sequence(); - int dim_d = inputs[0]->dimension(); - switch (axis) { - case BATCH: { - std::vector, int *>> data = {{h, &dim_h}, {s, &dim_s}, {d, &dim_d}}; - for (auto &pair : data) { - if (!pair.first.empty()) { - *pair.second = 1; - } - } - break; - } - case HEAD: { - std::vector, int *>> data = {{b, &dim_b}, {s, &dim_s}, {d, &dim_d}}; - for (auto &pair : data) { - if (!pair.first.empty()) { - *pair.second = 1; - } - } - break; - } - case SEQUENCE: { - std::vector, int *>> data = {{b, &dim_b}, {h, &dim_h}, {d, &dim_d}}; - for (auto &pair : data) { - if (!pair.first.empty()) { - *pair.second = 1; - } - } - break; - } - case DIMENSION: { - std::vector, int *>> data = {{b, &dim_b}, {h, &dim_h}, {s, &dim_s}}; - for (auto &pair : data) { - if (!pair.first.empty()) { - *pair.second = 1; - } - } - break; - } - default: - break; - } - outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - Chl axis = (Chl)args[0]; - int b_size = args[1]; - int h_size = args[2]; - int s_size = args[3]; - int d_size = args[4]; - vector b = {}; - vector h = {}; - vector s = {}; - vector d = {}; - for (int i = 0; i < b_size; i++) { - b.push_back(args[5 + i]); - } - for (int i = 0; i < h_size; i++) { - h.push_back(args[5 + b_size + i]); - } - for (int i = 0; i < s_size; i++) { - s.push_back(args[5 + b_size + h_size + i]); - } - for (int i = 0; i < d_size; i++) { - d.push_back(args[5 + b_size + h_size + s_size + i]); - } - if (axis == BATCH) { - if (!s.empty()) { - for (int i = 0; i < s.size(); ++i) { - auto seq_idx = s[i]; - memcpy(outputs[0]->hostPtr() + outputs[0]->offset(i, 0, 0, 0), - inputs[0]->hostPtr() + inputs[0]->offset(i, 0, seq_idx, 0), - inputs[0]->head() * 1 * inputs[0]->dimension() * sizeof(float)); - } - } - } else { - std::cout << "[TODO]Tensor.CLip not support!!!!" << std::endl; - } - } -}; - -class CPUcliptensorFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - Chl dim = (Chl)args[0]; - if (dim == SEQUENCE) { - int new_seq = inputs[1]->dimension(); - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), new_seq, inputs[0]->dimension()); - } else if (dim == DIMENSION) { - int new_seq = inputs[1]->dimension(); - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), new_seq); - } else { - std::cout << "[TODO]Tensor.CLip not support!!!!" << std::endl; - } - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - Chl dim = (Chl)args[0]; - if (dim == SEQUENCE) { - if (inputs[0]->ctype() == BHDS) { - outputs[0]->chls() = inputs[0]->chls(); - outputs[0]->setCtype(BHDS); - int new_seq = inputs[1]->dimension(); - if (outputs[0]->sequence() == 0 || outputs[0]->shape().empty() - || new_seq != outputs[0]->sequence()) { - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), new_seq, inputs[0]->dimension()); - outputs[0]->alloc(); - } - -#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) - for (int b = 0; b < inputs[0]->batch(); ++b) { - for (int d = 0; d < inputs[0]->dimension(); ++d) { - for (int s = 0; s < new_seq; ++s) { - auto selected_idx = (int)inputs[1]->dataAt(0, 0, 0, s); - outputs[0]->setDataAt(b, 0, s, d, - inputs[0]->dataAt(b, 0, selected_idx, d)); - } - } - } - return; - } - int new_seq = inputs[1]->dimension(); - if (outputs[0]->sequence() == 0 || outputs[0]->shape().empty() - || new_seq != outputs[0]->sequence()) { - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), new_seq, inputs[0]->dimension()); - outputs[0]->alloc(); - } -#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) - for (int b = 0; b < inputs[0]->batch(); ++b) { - for (int s = 0; s < inputs[1]->dimension(); ++s) { - auto selected_idx = (int)inputs[1]->dataAt(0, 0, 0, s); - memcpy(outputs[0]->ptrAt(b, 0, s, 0), - inputs[0]->ptrAt(b, 0, selected_idx, 0), - inputs[0]->head() * inputs[0]->dimension() * sizeof(float)); - } - } - } else if (dim == DIMENSION) { - int new_seq = inputs[1]->dimension(); - if (outputs[0]->sequence() == 0 || outputs[0]->shape().empty() - || new_seq != outputs[0]->sequence()) { - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), new_seq); - outputs[0]->alloc(); - } -#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) - for (int b = 0; b < inputs[0]->batch(); ++b) { - for (int s = 0; s < inputs[0]->sequence(); ++s) { - for (int d = 0; d < inputs[1]->dimension(); ++d) { - auto selected_idx = (int)inputs[1]->dataAt(0, 0, 0, d); - outputs[0]->setDataAt(b, 0, s, d, - inputs[0]->dataAt(b, 0, s, selected_idx)); - } - } - } - } else { - std::cout << "[TODO]Tensor.CLip not support!!!!" << std::endl; - } - } -}; -} // namespace mllm -#endif // CPUCLIPFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUExpandFunc.hpp b/src/backends/cpu/function/CPUExpandFunc.hpp deleted file mode 100644 index 3a86bf953..000000000 --- a/src/backends/cpu/function/CPUExpandFunc.hpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUEXPANDFUNC_HPP -#define CPUEXPANDFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "CPUBackend.hpp" - -namespace mllm { -class Tensor; - -class CPUexpandFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - int b = (int)args[0]; - int h = (int)args[1]; - int s = (int)args[2]; - int d = (int)args[3]; - assert(b * h * d * s < 0); - int dim_b = inputs[0]->batch(); - int dim_h = inputs[0]->head(); - int dim_s = inputs[0]->sequence(); - int dim_d = inputs[0]->dimension(); - if (b != -1) { - assert(dim_b == 1); - dim_b = b; - } else if (s != -1) { - assert(dim_s == 1); - dim_s = s; - } else if (h != -1) { - assert(dim_h == 1); - dim_h = h; - } else if (d != -1) { - assert(dim_d == 1); - dim_d = d; - } - outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - int b = (int)args[0]; - int h = (int)args[1]; - int s = (int)args[2]; - int d = (int)args[3]; - int dim_b = inputs[0]->batch(); - int dim_s = inputs[0]->sequence(); - int dim_h = inputs[0]->head(); - int dim_d = inputs[0]->dimension(); - if (b != -1) { - std::cerr << "expand tp support" << std::endl; - } else if (s != -1) { -#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) - for (int b_ = 0; b_ < dim_b; ++b_) { - for (int s_ = 0; s_ < s; ++s_) { - memcpy(outputs[0]->ptrAt(b_, 0, s_, 0), - inputs[0]->ptrAt(b_, 0, 0, 0), - dim_d * dim_h * sizeof(float)); - } - } - } else if (h != -1) { -#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) - for (int b_ = 0; b_ < dim_b; ++b_) { - for (int s_ = 0; s_ < dim_s; ++s_) { - for (int h_ = 0; h_ < h; ++h_) { - memcpy(outputs[0]->ptrAt(b_, h_, s_, 0), - inputs[0]->ptrAt(b_, h_, 0, 0), - dim_d * sizeof(float)); - } - } - } - } else if (d != -1) { - std::cerr << "expand tp support" << std::endl; - } - } -}; - -} // namespace mllm -#endif // CPUEXPANDFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUFlashAttention2Func.hpp b/src/backends/cpu/function/CPUFlashAttention2Func.hpp deleted file mode 100644 index a45cf1949..000000000 --- a/src/backends/cpu/function/CPUFlashAttention2Func.hpp +++ /dev/null @@ -1,102 +0,0 @@ -// -// Created by Rongjie Yi on 25-2-16. -// - -#ifndef CPUFA2FUNC_HPP -#define CPUFA2FUNC_HPP -#include "CPUBackend.hpp" -#include "Tensor.hpp" -#include "Types.hpp" -#include "../compute/FlashAttention2.hpp" -#include "../compute/FlashAttention2H.hpp" - -namespace mllm { -class Tensor; - -class CPUFlashAttention2Func : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - auto q_tensor = inputs[0]; - auto k_tensor = inputs[1]; - auto v_tensor = inputs[2]; - auto o_tensor = outputs[0]; - int batch_size = q_tensor->batch(); - int q_head = q_tensor->head(); - int q_sequence = q_tensor->sequence(); - int dimension = q_tensor->dimension(); - // for BSHD attention start - if(inputs[0]->ctype()==BHSD && inputs[1]->ctype()==BHSD && inputs[1]->ctype()==BHSD ){ - o_tensor->setCtype(q_tensor->ctype()); - } - // for BSHD attention end - o_tensor->reshape(batch_size, q_head, q_sequence, dimension); - o_tensor->setDtype(inputs[0]->dtype()); - o_tensor->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - auto q_tensor = inputs[0]; - auto k_tensor = inputs[1]; - auto v_tensor = inputs[2]; - auto o_tensor = outputs[0]; - bool causal_mask = (bool)args[0]; - int batch_size = q_tensor->batch(); - int q_head = q_tensor->head(); - int q_sequence = q_tensor->sequence(); - int dimension = q_tensor->dimension(); - int k_head = k_tensor->head(); - int k_sequence = k_tensor->sequence(); - int v_head = v_tensor->head(); - int v_sequence = v_tensor->sequence(); - assert(v_head == k_head && v_sequence == k_sequence); - bool kv_use_fp32 = k_tensor->dtype() == MLLM_TYPE_F32 ? true : false; // x86只支持FP32 - int threads = CPUBackend::cpu_threads; - if (threads > v_head) { - threads = v_head; // 线程数不能超过头数 - } - int32_t br = q_sequence >= 4 ? 4 : 1; - int32_t bc = q_sequence >= 4 ? 4 : 1; - constexpr bool high_precision_exp = false; - // for BSHD attention start - if(inputs[0]->ctype()==BHSD && inputs[1]->ctype()==BHSD && inputs[1]->ctype()==BHSD ){ - int km = k_sequence; - int vm = v_sequence; - if(k_tensor->masterTensor()!=nullptr && v_tensor->masterTensor()!=nullptr){ - km = k_tensor->masterTensor()->sequence(); - vm = v_tensor->masterTensor()->sequence(); - } - flash_attention_2_forward_h( - q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), - o_tensor->hostPtr(), // 输入输出张量 - batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 - causal_mask, // 使用因果掩码 - kv_use_fp32, // 使用FP32(x86必须) - threads, // 使用4线程 - br, // 查询分块大小64 - bc, // 键值分块大小128 - q_head, // 查询头数12 - k_head, // 键值头数4 - high_precision_exp, // 使用快速指数近似 - q_sequence*dimension, - km*dimension, - vm*dimension - ); - // for BSHD attention end - }else{ - flash_attention_2_forward( - q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), - o_tensor->hostPtr(), // 输入输出张量 - batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 - causal_mask, // 使用因果掩码 - kv_use_fp32, // 使用FP32(x86必须) - threads, // 使用4线程 - br, // 查询分块大小64 - bc, // 键值分块大小128 - q_head, // 查询头数12 - k_head, // 键值头数4 - high_precision_exp // 使用快速指数近似 - ); - } - } -}; -} // namespace mllm -#endif // CPUFA2FUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUFlattenFunc.hpp b/src/backends/cpu/function/CPUFlattenFunc.hpp deleted file mode 100644 index 900eecff8..000000000 --- a/src/backends/cpu/function/CPUFlattenFunc.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUFLATTENFUNC_HPP -#define CPUFLATTENFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "Module.hpp" - -namespace mllm { -class Tensor; - -class CPUflattenFunction : public TensorFunction { -public: - void setUp(vector> outputs, vector> inputs, vector args) override { - // inputs[0]->shallowCopyFrom(outputs[0].get(), false); - Chl axis_start = (Chl)args[0]; - Chl axis_end = (Chl)args[1]; - if ((axis_start == TIME & axis_end == WIDTH && inputs[0]->ctype() == BCTHW) - || (axis_start == CHANNLE & axis_end == HEIGHT && inputs[0]->ctype() == BWCTH) - || (axis_start == HEIGHT & axis_end == CHANNLE && inputs[0]->ctype() == BTHWC) - || (axis_start == BATCH & axis_end == SEQUENCE && inputs[0]->ctype() != BCTHW) - || (axis_start == HEAD & axis_end == SEQUENCE && inputs[0]->ctype() == BSHD) - || (axis_start == HEAD & axis_end == SEQUENCE && inputs[0]->ctype() == BHDS) - || (axis_start == HEAD & axis_end == SEQUENCE && inputs[0]->ctype() == BDHS) - || (axis_start == HEAD & axis_end == DIMENSION && inputs[0]->ctype() == BSHD) - || (axis_start == HEAD & axis_end == DIMENSION && inputs[0]->ctype() == BHDS) - || (axis_start == HEAD & axis_end == SEQUENCE && inputs[0]->ctype() == BDSH)) { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); - } else if (Module::llm_model_ptr->op_transposed_flag) { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); - } else { - std::cout << "[TODO]Tensor.Flatten not support!!!!" << std::endl; - } - } - - void reshape(vector> outputs, vector> inputs, vector args) override { - Chl axis_start = (Chl)args[0]; - Chl axis_end = (Chl)args[1]; - int dim_b = inputs[0]->batch(); - int dim_h = 0; - int dim_s = 0; - int dim_d = 0; - if (inputs[0]->shape().size() == 4) { - dim_h = inputs[0]->head(); - dim_s = inputs[0]->sequence(); - dim_d = inputs[0]->dimension(); - if (axis_start == BATCH & axis_end == SEQUENCE) { - dim_b = 1; - dim_s = inputs[0]->sequence() * inputs[0]->batch(); - } else if (axis_start == HEAD & axis_end == SEQUENCE) { - dim_h = 1; - dim_s = inputs[0]->sequence() * inputs[0]->head(); - } else if (axis_start == HEAD & axis_end == DIMENSION) { - dim_h = 1; - dim_d = inputs[0]->dimension() * inputs[0]->head(); - } else { - std::cout << "ERROR: flatten " << axis_start << "&" << axis_end << std::endl; - } - } else if (inputs[0]->shape().size() == 5) { - if (axis_start == CHANNLE & axis_end == HEIGHT) { - dim_h = 1; - dim_s = inputs[0]->channel() * inputs[0]->height() * inputs[0]->time(); - dim_d = inputs[0]->width(); - } else if (axis_start == HEIGHT & axis_end == CHANNLE) { - dim_h = 1; - dim_s = inputs[0]->channel() * inputs[0]->height() * inputs[0]->width(); - dim_d = inputs[0]->time(); - } - } - assert(dim_d + dim_s + dim_h > 0); - if (inputs[0]->ctype() == BCTHW) { // TODOTMPA - outputs[0]->chls()[BATCH] = 0; - outputs[0]->chls()[SEQUENCE] = 1; - outputs[0]->chls()[HEAD] = 2; - outputs[0]->chls()[DIMENSION] = 3; - outputs[0]->setCtype(BSHD); - } - outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); - - /* - if ((axis_start == TIME & axis_end == WIDTH && inputs[0]->ctype() == BCTHW) - || (axis_start == CHANNLE & axis_end == HEIGHT && inputs[0]->ctype() == BWCTH) - || (axis_start == HEIGHT & axis_end == CHANNLE && inputs[0]->ctype() == BTHWC) - || (axis_start == BATCH & axis_end == SEQUENCE && inputs[0]->ctype() != BCTHW) - || (axis_start == HEAD & axis_end == SEQUENCE && inputs[0]->ctype() == BSHD) - || (axis_start == HEAD & axis_end == SEQUENCE && inputs[0]->ctype() == BHDS) - || (axis_start == HEAD & axis_end == SEQUENCE && inputs[0]->ctype() == BDHS) - || (axis_start == HEAD & axis_end == DIMENSION && inputs[0]->ctype() == BSHD) - || (axis_start == HEAD & axis_end == DIMENSION && inputs[0]->ctype() == BHDS) - || (axis_start == HEAD & axis_end == SEQUENCE && inputs[0]->ctype() == BDSH)) { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); - } else if (Module::llm_model_ptr->op_transposed_flag) { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); - return; - } else { - std::cout << "[TODO]Tensor.Flatten not support!!!!" << std::endl; - } - */ - } - - void execute(vector> outputs, vector> inputs, vector args) override { - } -}; - -} // namespace mllm -#endif // CPUFLATTENFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUFuyuGatherEmbdFunc.hpp b/src/backends/cpu/function/CPUFuyuGatherEmbdFunc.hpp deleted file mode 100644 index 00decd0cf..000000000 --- a/src/backends/cpu/function/CPUFuyuGatherEmbdFunc.hpp +++ /dev/null @@ -1,65 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUFUYUGATHEREMBDFUNC_HPP -#define CPUFUYUGATHEREMBDFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" - -namespace mllm { -class Tensor; - -class CPUFuyuGatherEmbdFunc : public TensorFunction { -public: - void setUp(vector> outputs, vector> inputs, vector args) override { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); - } - void reshape(vector> outputs, vector> inputs, vector args) override { - assert(inputs.size() == 3); - // assert(outputs.size() == 1); - // if (inputs[1]->batch() == 0) { - // outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), inputs[0]->dimension()); - // } - assert(inputs[0]->batch() == inputs[1]->batch()); - assert(inputs[0]->head() == inputs[1]->head()); - assert(inputs[0]->head() == 1); - assert(inputs[0]->dimension() == inputs[1]->dimension()); - assert(inputs[2]->dimension() == 1); - // outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), inputs[0]->dimension()); - // alloc - - // if (inputs[0]->masterTensor() == nullptr) { - // inputs[0]->free(); - // } - // outputs[0]->alloc(); - // inputs[0]->shallowCopyFrom(outputs[0].get(), false); - } - void execute(vector> outputs, vector> inputs, vector args) override { - if (inputs[1]->batch() == 0) { - return; - } - assert(inputs[0]->ctype() == BSHD); - assert(inputs[1]->ctype() == BSHD); - - // assert(outputs[0]->ctype() == BSHD); - auto input_indices = inputs[2]; - int hiddenSize = inputs[0]->dimension(); - for (int batch = 0; batch < inputs[0]->batch(); ++batch) { - for (int seq = 0; seq < inputs[0]->sequence(); ++seq) { - if (input_indices->dataAt(batch, 0, seq, 0) >= 0) { - memcpy(inputs[0]->hostPtr() + inputs[0]->offset(batch, 0, seq, 0), - inputs[1]->hostPtr() + (int)inputs[1]->offset(batch, 0, input_indices->dataAt(batch, 0, seq, 0), 0), - inputs[1]->dtypeSize() * hiddenSize); - } - } - } - } -}; - -} // namespace mllm -#endif // CPUFUYUGATHEREMBDFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUIndexPutFunc.hpp b/src/backends/cpu/function/CPUIndexPutFunc.hpp deleted file mode 100644 index 388bcf3ff..000000000 --- a/src/backends/cpu/function/CPUIndexPutFunc.hpp +++ /dev/null @@ -1,139 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUINDEXPUTFUNC_HPP -#define CPUINDEXPUTFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "CPUBackend.hpp" - -namespace mllm { -class Tensor; - -class CPUIndexPutFunction : public TensorFunction { -public: - void setUp(vector> outputs, vector> inputs, vector args) override { - bool accumulate = (bool)args[0]; - if (!accumulate) { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); - } - } - void reshape(vector> outputs, vector> inputs, vector args) override { - bool accumulate = (bool)args[0]; - if (inputs[1]->batch() == 0) { - outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), inputs[0]->dimension()); - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - inputs[0]->shallowCopyFrom(outputs[0].get(), false); - outputs[0]->alloc(); - return; - } - // reshape - assert(inputs.size() == 3); - // assert(outputs.size() == 1); - auto dest_input = inputs[0]; - auto src_input = inputs[1]; - assert(dest_input->batch() == 1); - assert(dest_input->head() == 1); - assert(src_input->head() == 1); - assert(dest_input->dimension() == src_input->dimension()); - int origin_s = dest_input->sequence(); - int replace_s = src_input->sequence(); - int replace_size = src_input->batch(); - int seq = origin_s - replace_size + replace_size * replace_s; - if (!accumulate) { - outputs[0]->reshape(dest_input->batch(), dest_input->head(), dest_input->sequence(), dest_input->dimension()); // 1, 1, 595, 4096 - } else { - outputs[0]->reshape(dest_input->batch(), dest_input->head(), seq, dest_input->dimension()); // 1, 1, 595, 4096 - } - // alloc - if (!accumulate) { - // outputs[0]->shallowCopyFrom(inputs[0], false); - } else { - outputs[0]->alloc(); - } - - // if (!accumulate) { - // if (inputs[0]->masterTensor() == nullptr) { - // inputs[0]->free(); - // } - // outputs[0]->alloc(); - // inputs[0]->shallowCopyFrom(outputs[0].get(), false); - // } else { - // outputs[0]->alloc(); - // } - } - void execute(vector> outputs, vector> inputs, vector args) override { - bool accumulate = (bool)args[0]; - if (inputs[1]->batch() == 0) { - return; - } - assert(inputs.size() == 3); - // assert(outputs.size() == 1); - auto dest_input = inputs[0]; - auto src_input = inputs[1]; - auto replace_idx = inputs[2]; - assert(replace_idx->batch() == 1); - assert(replace_idx->sequence() == 1); - assert(replace_idx->head() == 1); - if (!accumulate) { - for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { - auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); - auto dst_ptr = inputs[0]->ptrAt(0, 0, replace_seq, 0); - auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); - memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); - } - } else if (replace_idx->dimension() == src_input->batch()) { - int replace_s = src_input->sequence(); - int replace_size = src_input->batch(); - auto start_dest_seq = 0; - int in0_d = 0; - int in1_batch = 0; -#pragma omp parallel for num_threads(CPUBackend::cpu_threads) - for (int i = 0; i < replace_size; ++i) { - auto start_src_seq = (int)replace_idx->dataAt(0, 0, 0, i) + i * replace_s; - auto end_dest_seq = start_src_seq; - auto end_src_seq = start_src_seq + replace_s; - - auto dst_ptr = outputs[0]->ptrAt(0, 0, start_dest_seq, 0); - auto src_ptr = inputs[0]->ptrAt(0, 0, in0_d, 0); - memcpy(dst_ptr, src_ptr, sizeof(float) * dest_input->dimension() * (end_dest_seq - start_dest_seq)); - in0_d += end_dest_seq - start_dest_seq; - - dst_ptr = outputs[0]->ptrAt(0, 0, start_src_seq, 0); - src_ptr = inputs[1]->ptrAt(0, 0, 0, 0); - memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension() * replace_s); - in1_batch++; - in0_d += 1; - - start_dest_seq = end_src_seq; - } - auto dst_ptr = outputs[0]->ptrAt(0, 0, start_dest_seq, 0); - auto src_ptr = inputs[0]->ptrAt(0, 0, in0_d, 0); - memcpy(dst_ptr, src_ptr, sizeof(float) * dest_input->dimension() * (outputs[0]->sequence() - start_dest_seq)); - } else if (replace_idx->dimension() == src_input->sequence()) { - for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { - auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); - auto dst_ptr = outputs[0]->ptrAt(0, 0, replace_seq, 0); - auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); - memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); - } - } else { - for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { - auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); - auto dst_ptr = outputs[0]->ptrAt(0, 0, replace_seq, 0); - auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); - memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); - } - } - } -}; - -} // namespace mllm -#endif // CPUINDEXPUTFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPULikeFunc.hpp b/src/backends/cpu/function/CPULikeFunc.hpp deleted file mode 100644 index 25d4af51d..000000000 --- a/src/backends/cpu/function/CPULikeFunc.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// Created by Rongjie Yi on 24-12-16. -// - -#ifndef CPULIKEFUNC_HPP -#define CPULIKEFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -namespace mllm { -class Tensor; - -class CPUlikeFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - float like_value = args[0]; - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->setDtype(inputs[0]->dtype()); // like_values - outputs[0]->alloc(); - memset(outputs[0]->hostPtr(), like_value, outputs[0]->count() * sizeof(float)); - } - void execute(vector> outputs, vector> inputs, vector args) override { - float like_value = args[0]; - memset(outputs[0]->hostPtr(), like_value, outputs[0]->count() * sizeof(float)); - } -}; -} // namespace mllm -#endif // CPULIKEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUMatmulFunc.hpp b/src/backends/cpu/function/CPUMatmulFunc.hpp deleted file mode 100644 index 2702752c2..000000000 --- a/src/backends/cpu/function/CPUMatmulFunc.hpp +++ /dev/null @@ -1,89 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUMATMULFUNC_HPP -#define CPUMATMULFUNC_HPP -#include "CPUBackend.hpp" -#include "Tensor.hpp" -#include "Types.hpp" -#include "../compute/Matmul.hpp" -#include -namespace mllm { -class Tensor; - -class CPUmmFunction : public TensorFunction { - static void tranTensorChl(Tensor &input) { - assert(input.ctype() == BSHD); - auto b = input.batch(); - auto h = input.head(); - auto d = input.dimension(); - auto s = input.sequence(); - auto ori_seq_idx = input.chls()[SEQUENCE]; - auto ori_head_idx = input.chls()[HEAD]; - auto ori_dim_idx = input.chls()[DIMENSION]; - input.chls()[HEAD] = ori_seq_idx; - input.chls()[DIMENSION] = ori_head_idx; - input.chls()[SEQUENCE] = ori_dim_idx; - input.changeCtype(); - input.reshape(b, h, s, d); - input.transed() = true; - input.undiffusion() = false; - // if no TENSOR_STATIC_SHAPED - if (input.masterTensor() != nullptr) { - auto b = input.masterTensor()->batch(); - auto h = input.masterTensor()->head(); - auto d = input.masterTensor()->dimension(); - auto s = input.masterTensor()->sequence(); - input.masterTensor()->chls() = input.chls(); - input.masterTensor()->changeCtype(); - input.masterTensor()->reshape(b, h, s, d); - for (auto child : input.masterTensor()->childTensors()) { - auto b = child->batch(); - auto h = child->head(); - auto d = child->dimension(); - auto s = child->sequence(); - child->chls() = input.chls(); - child->changeCtype(); - child->reshape(b, h, s, d); - } - } else { - for (auto child : input.childTensors()) { - auto b = child->batch(); - auto h = child->head(); - auto d = child->dimension(); - auto s = child->sequence(); - child->chls() = input.chls(); - child->changeCtype(); - child->reshape(b, h, s, d); - } - } - } - -public: - void setUp(vector> outputs, vector> inputs, vector args) override { - if (inputs[1]->chls()[SEQUENCE] != 3) { - tranTensorChl(*inputs[1]); - } - if (!inputs[1]->shape().empty() && !inputs[0]->shape().empty()) { - assert(inputs[0]->dimension() == inputs[1]->sequence()); - } - } - void reshape(vector> outputs, vector> inputs, vector args) override { - if (inputs[1]->chls()[SEQUENCE] != 3) { - tranTensorChl(*inputs[1]); - assert(inputs[1]->chls()[SEQUENCE] == 3); - } - assert(inputs[0]->dimension() == inputs[1]->sequence()); - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[1]->dimension()); - // outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - bool isSame = std::equal(inputs[0]->chls().begin(), inputs[0]->chls().end(), inputs[1]->chls().begin()); - assert(inputs[0]->dtype() == MLLM_TYPE_F32); - mat_mul(inputs[0].get(), inputs[1].get(), outputs[0].get(), false, nullptr, false, isSame, CPUBackend::cpu_threads); - } -}; -} // namespace mllm -#endif // CPUMATMULFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUMeanFunc.hpp b/src/backends/cpu/function/CPUMeanFunc.hpp deleted file mode 100644 index 46084f122..000000000 --- a/src/backends/cpu/function/CPUMeanFunc.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUMEANFUNC_HPP -#define CPUMEANFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" - -namespace mllm { -class Tensor; - -class CPUmeanFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - Chl axis = (Chl)args[0]; - int batch = inputs[0]->batch(); - int head = inputs[0]->head(); - int sequence = inputs[0]->sequence(); - int dimension = inputs[0]->dimension(); - switch (axis) { - case BATCH: - batch = 1; - break; - case HEAD: - head = 1; - break; - case SEQUENCE: - sequence = 1; - break; - case DIMENSION: - dimension = 1; - break; - default: - break; - } - outputs[0]->reshape(batch, head, sequence, dimension); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - Chl axis = (Chl)args[0]; - int batch = inputs[0]->batch(); - int dim = inputs[0]->dimension(); - int seq = inputs[0]->sequence(); - int head = inputs[0]->head(); - switch (axis) { - case BATCH: { - for (int h = 0; h < head; h++) { - for (int s = 0; s < seq; ++s) { - for (int d = 0; d < dim; d++) { - float sum = 0.0f; - for (int n = 0; n < batch; n++) { - sum += inputs[0]->dataAt(n, h, s, d); - } - outputs[0]->setDataAt(0, h, s, d, sum / seq); - } - } - } - break; - } - case HEAD: { - for (int n = 0; n < batch; n++) { - for (int s = 0; s < seq; ++s) { - for (int d = 0; d < dim; d++) { - float sum = 0.0f; - for (int h = 0; h < head; h++) { - sum += inputs[0]->dataAt(n, h, s, d); - } - outputs[0]->setDataAt(n, 0, s, d, sum / seq); - } - } - } - break; - } - case SEQUENCE: { - for (int n = 0; n < batch; n++) { - for (int h = 0; h < head; h++) { - for (int d = 0; d < dim; d++) { - float sum = 0.0f; - for (int s = 0; s < seq; ++s) { - sum += inputs[0]->dataAt(n, h, s, d); - } - outputs[0]->setDataAt(n, h, 0, d, sum / seq); - } - } - } - break; - } - case DIMENSION: { - for (int n = 0; n < batch; n++) { - for (int h = 0; h < head; h++) { - for (int s = 0; s < seq; s++) { - float sum = 0.0f; - for (int d = 0; d < inputs[0]->dimension(); ++d) { - sum += inputs[0]->dataAt(n, h, s, d); - } - outputs[0]->setDataAt(n, h, s, 0, sum / inputs[0]->dimension()); - } - } - } - break; - } - default: - break; - } - } -}; - -} // namespace mllm -#endif // CPUMEANFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUNormFunc.hpp b/src/backends/cpu/function/CPUNormFunc.hpp deleted file mode 100644 index 7a97b1b1d..000000000 --- a/src/backends/cpu/function/CPUNormFunc.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUNORMFUNC_HPP -#define CPUNORMFUNC_HPP -#include "CPUBackend.hpp" -#include "Tensor.hpp" -#include "Types.hpp" - -namespace mllm { -class Tensor; - -class CPUnormFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - int L_n = (int)args[0]; - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - int L_n = (int)args[0]; - for (int h = 0; h < inputs[0]->head(); h++) { - for (int n = 0; n < inputs[0]->batch(); n++) { - for (int s = 0; s < inputs[0]->sequence(); s++) { - if (L_n == 2) { - float sum_of_squares = 0.0f; - for (int d = 0; d < inputs[0]->dimension(); ++d) { - sum_of_squares += inputs[0]->dataAt(n, h, s, d) * inputs[0]->dataAt(n, h, s, d); - } - float l2_norm = std::sqrt(sum_of_squares); -#pragma omp parallel for num_threads(CPUBackend::cpu_threads) - for (int d = 0; d < inputs[0]->dimension(); d++) { - outputs[0]->setDataAt(n, h, s, d, l2_norm); - } - } else { - float sum_of_abs_values = 0.0f; - for (int d = 0; d < inputs[0]->dimension(); ++d) { - sum_of_abs_values += std::abs(inputs[0]->dataAt(n, h, s, d)); - } -#pragma omp parallel for num_threads(CPUBackend::cpu_threads) - for (int d = 0; d < inputs[0]->dimension(); d++) { - outputs[0]->setDataAt(n, h, s, d, sum_of_abs_values); - } - } - } - } - } - } -}; -} // namespace mllm -#endif // CPUNORMFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUPhi3VhdmergeFunc.hpp b/src/backends/cpu/function/CPUPhi3VhdmergeFunc.hpp deleted file mode 100644 index f27370bd5..000000000 --- a/src/backends/cpu/function/CPUPhi3VhdmergeFunc.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUPHI3VHDMERGEEFUNC_HPP -#define CPUPHI3VHDMERGEEFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "CPUBackend.hpp" - -namespace mllm { -class Tensor; - -class CPUPhi3VhdmergeFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - assert(args.size() == 2); - int h_crop = (int)args[0]; - int w_crop = (int)args[1]; - int N = inputs[0]->batch(); - int L = inputs[0]->sequence(); - int C = inputs[0]->dimension(); - assert(L == 24 * 24); - assert(C == 1024); - assert(N % (h_crop * w_crop) == 0); - int num_images = N / (h_crop * w_crop); - int H = static_cast(std::sqrt(L)); - - int b = num_images; - int s = h_crop * H / 2; - int h = w_crop * H / 2; - int d = 4 * C; - - outputs[0]->reshape(b, h, s, d); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - int h_crop = (int)args[0]; - int w_crop = (int)args[1]; - int N = inputs[0]->batch(); - int L = inputs[0]->sequence(); - int C = inputs[0]->dimension(); - int num_images = N / (h_crop * w_crop); - int H = static_cast(std::sqrt(L)); - - int b = num_images; - int s = h_crop * H / 2; - int h = w_crop * H / 2; - int d = 4 * C; - -#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) - for (int ob = 0; ob < b; ob++) { - for (int os = 0; os < s; os++) { - for (int oh = 0; oh < h; oh++) { - int base_s = int(oh / 12) * (24 * 24) + os * 48 + 2 * (oh % 12); - int hed = base_s % L; - int btch = int(base_s / L); - auto i_ptr_0 = inputs[0]->ptrAt(btch, hed, 0, 0); - auto i_ptr_1 = inputs[0]->ptrAt(btch, hed + 1, 0, 0); - auto i_ptr_2 = inputs[0]->ptrAt(btch, hed + 24, 0, 0); - auto i_ptr_3 = inputs[0]->ptrAt(btch, hed + 25, 0, 0); - memcpy(outputs[0]->ptrAt(ob, oh, os, 0), - i_ptr_0, C * sizeof(float)); - memcpy(outputs[0]->ptrAt(ob, oh, os, C), - i_ptr_1, C * sizeof(float)); - memcpy(outputs[0]->ptrAt(ob, oh, os, C * 2), - i_ptr_2, C * sizeof(float)); - memcpy(outputs[0]->ptrAt(ob, oh, os, C * 3), - i_ptr_3, C * sizeof(float)); - } - } - } - } -}; - -} // namespace mllm -#endif // CPUPHI3VHDMERGEEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPURangeFunc.hpp b/src/backends/cpu/function/CPURangeFunc.hpp deleted file mode 100644 index fa0bc7f84..000000000 --- a/src/backends/cpu/function/CPURangeFunc.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPURANGEFUNC_HPP -#define CPURANGEFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "CPUBackend.hpp" - -namespace mllm { -class Tensor; - -class CPURangeFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - int start = (int)args[0]; - int end = (int)args[1]; - outputs[0]->reshape(1, 1, end - start, 1); - outputs[0]->setDtype(MLLM_TYPE_F32); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - int start = (int)args[0]; - int end = (int)args[1]; -#pragma omp parallel for collapse(1) num_threads(CPUBackend::cpu_threads) - for (int i = 0; i < end - start; ++i) { - outputs[0]->setDataAt(0, 0, i + start, 0, (float)i); - } - } -}; - -} // namespace mllm -#endif // CPURANGEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPURepeatFunc.hpp b/src/backends/cpu/function/CPURepeatFunc.hpp deleted file mode 100644 index 319d66a0a..000000000 --- a/src/backends/cpu/function/CPURepeatFunc.hpp +++ /dev/null @@ -1,87 +0,0 @@ -// -// Created by Rongjie Yi on 24-12-16. -// - -#ifndef CPUREPEATEFUNC_HPP -#define CPUREPEATEFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include -#include -#include "CPUBackend.hpp" - -namespace mllm { -class Tensor; - -class CPUrepeatFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - assert(args.size() == 2); - Chl dim = (Chl)args[0]; - int size = (int)args[1]; - int batch = inputs[0]->batch(); - int head = inputs[0]->head(); - int sequence = inputs[0]->sequence(); - int dimension = inputs[0]->dimension(); - switch (dim) { - case Chl::BATCH: { - batch = size; - break; - } - case Chl::HEAD: { - head = size; - break; - } - case Chl::SEQUENCE: { - sequence = size; - break; - } - case Chl::DIMENSION: { - dimension = size; - break; - } - default: - break; - } - outputs[0]->reshape(batch, head, sequence, dimension); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - assert(args.size() == 2); - Chl dim = (Chl)args[0]; - int size = (int)args[1]; - switch (dim) { - case Chl::BATCH: { - std::cerr << "Repeat Not implemented" << std::endl; - break; - } - case Chl::HEAD: { - std::cerr << "Repeat Not implemented" << std::endl; - break; - } - case Chl::SEQUENCE: { - std::cerr << "Repeat Not implemented" << std::endl; - break; - } - case Chl::DIMENSION: { -#pragma omp parallel for collapse(4) num_threads(CPUBackend::cpu_threads) - for (int b = 0; b < inputs[0]->batch(); b++) { - for (int s = 0; s < inputs[0]->sequence(); s++) { - for (int h = 0; h < inputs[0]->head(); h++) { - for (int d = 0; d < size; d++) { - float data = inputs[0]->dataAt(b, h, s, 0); - outputs[0]->setDataAt(b, h, s, d, data); - } - } - } - } - break; - } - default: - break; - } - } -}; -} // namespace mllm -#endif // CPUREPEATEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUScatterReduceFunc.hpp b/src/backends/cpu/function/CPUScatterReduceFunc.hpp deleted file mode 100644 index 1b04e8136..000000000 --- a/src/backends/cpu/function/CPUScatterReduceFunc.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// -// Created by Rongjie Yi on 24-12-26. -// - -#ifndef CPUSCATTERREDUCEFUNC_HPP -#define CPUSCATTERREDUCEFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -// #include "CPUBackend.hpp" -#include "../compute/Arithmetic.hpp" - -namespace mllm { -class Tensor; - -class CPUScatterReduceFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - } - void execute(vector> outputs, vector> inputs, vector args) override { - if (inputs[1]->batch() == 0) { - return; - } - assert(inputs.size() == 3); - assert(inputs[0]->batch() == 1); - assert(inputs[0]->head() == 1); - auto dest_input = inputs[0]; - auto src_input = inputs[1]; - auto replace_idx = inputs[2]; - assert(replace_idx->batch() == 1); - assert(replace_idx->sequence() == 1); - assert(replace_idx->head() == 1); - // #pragma omp parallel for num_threads(CPUBackend::cpu_threads) - for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { - auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); - auto dst_ptr = dest_input->ptrAt(0, 0, replace_seq, 0); - auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); - // memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); - float tmp[src_input->dimension()]; - memcpy(tmp, dst_ptr, sizeof(float) * dest_input->dimension()); - mllm_add_fp32(tmp, - src_ptr, - dst_ptr, dest_input->dimension()); - } - } -}; - -} // namespace mllm -#endif // CPUSCATTERREDUCEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUSplitFunc.hpp b/src/backends/cpu/function/CPUSplitFunc.hpp deleted file mode 100644 index 15fcf49d7..000000000 --- a/src/backends/cpu/function/CPUSplitFunc.hpp +++ /dev/null @@ -1,170 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUSPLITFUNC_HPP -#define CPUSPLITFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "../compute/Split.hpp" -#include -namespace mllm { -class Tensor; - -class CPUsplitFunction : public TensorFunction { -public: - void setUp(vector> outputs, vector> inputs, vector args) override { - // inputs[0]->shallowCopyFrom(outputs[0], false); - int size = args.size(); - std::vector each_dims; - for (int i = 0; i < size - 2; i++) { - each_dims.push_back(args[i]); - } - Chl split_dim = (Chl)args[size - 2]; - int head_size = (int)args[size - 1]; - - - int split_num_ = each_dims.size(); - // store each dims - int split_dim_size_ = 0; - std::vector each_dims_; - for (size_t i = 0; i < each_dims.size(); ++i) { - each_dims_.push_back((float)each_dims[i]); - split_dim_size_ += each_dims[i]; - } - assert(split_num_ == outputs.size()); - switch (split_dim) { - case Chl::HEAD: { - // assert(inputs[0]->head() == split_dim_size_); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), each_dims_[i], inputs[0]->sequence(), inputs[0]->dimension()); - } - break; - } - case Chl::SEQUENCE: { - // assert(inputs[0]->sequence() == split_dim_size_); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), each_dims_[i], inputs[0]->dimension()); - } - break; - } - case Chl::DIMENSION: { - // assert(inputs[0]->dimension() == split_dim_size_); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), each_dims_[i]); - } - break; - } - case Chl::D_HD: { - // assert(inputs[0]->dimension() == split_dim_size_ * head_size); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), head_size, inputs[0]->sequence(), each_dims_[i]); - } - break; - } - case Chl::HD: { - // assert(inputs[0]->dimension() == split_dim_size_ * head_size); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), head_size, inputs[0]->sequence(), each_dims_[i]); - } - break; - } - default: { - break; - } - } - if (inputs[0]->allowAggregated()) { - vector> shared_outputs = {}; - for (const auto &output : outputs) { - output->alloc(); - shared_outputs.push_back(output); - } - if (inputs[0]->masterTensor() == nullptr && !inputs[0]->childTensors().empty()) { - inputs[0]->free(); - } - inputs[0]->addTensors(shared_outputs, split_dim); - } - } - void reshape(vector> outputs, vector> inputs, vector args) override { - int size = args.size(); - std::vector each_dims; - for (int i = 0; i < size - 2; i++) { - each_dims.push_back(args[i]); - } - Chl split_dim = (Chl)args[size - 2]; - int head_size = (int)args[size - 1]; - int split_num_ = each_dims.size(); - // store each dims - int split_dim_size_ = 0; - std::vector each_dims_; - for (size_t i = 0; i < each_dims.size(); ++i) { - each_dims_.push_back((float)each_dims[i]); - split_dim_size_ += each_dims[i]; - } - assert(split_num_ == outputs.size()); - switch (split_dim) { - case Chl::HEAD: { - // assert(inputs[0]->head() == split_dim_size_); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), each_dims_[i], inputs[0]->sequence(), inputs[0]->dimension()); - } - break; - } - case Chl::SEQUENCE: { - // assert(inputs[0]->sequence() == split_dim_size_); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), each_dims_[i], inputs[0]->dimension()); - } - break; - } - case Chl::DIMENSION: { - // assert(inputs[0]->dimension() == split_dim_size_); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), each_dims_[i]); - } - break; - } - case Chl::D_HD: { - // assert(inputs[0]->dimension() == split_dim_size_ * head_size); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), head_size, inputs[0]->sequence(), each_dims_[i]); - } - break; - } - case Chl::HD: { - // assert(inputs[0]->dimension() == split_dim_size_ * head_size); - for (int i = 0; i < split_num_; i++) { - outputs[i]->reshape(inputs[0]->batch(), head_size, inputs[0]->sequence(), each_dims_[i]); - } - break; - } - default: { - break; - } - } - } - void execute(vector> outputs, vector> inputs, vector args) override { - if (inputs[0]->aggregatedTensors().empty()) { - int size = args.size(); - std::vector each_dims; - std::vector out_pointers; - assert(size - 2 == outputs.size()); - for (int i = 0; i < size - 2; i++) { - each_dims.push_back(args[i]); - out_pointers.push_back(outputs[i]->ptrAt(0, 0, 0, 0)); - } - Chl split_dim = (Chl)args[size - 2]; - int head_size = (int)args[size - 1]; - int split_num_ = each_dims.size(); - const int origin_dims[4] = {inputs[0]->batch(), inputs[0]->sequence(), inputs[0]->head(), inputs[0]->dimension()}; - efficient_split(inputs[0]->ptrAt(0, 0, 0, 0), - origin_dims, - out_pointers, - each_dims, - split_dim); - } - } -}; - -} // namespace mllm -#endif // CPUSPLITFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUSumFunc.hpp b/src/backends/cpu/function/CPUSumFunc.hpp deleted file mode 100644 index 2fac8e77a..000000000 --- a/src/backends/cpu/function/CPUSumFunc.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// Created by Rongjie Yi on 24-12-16. -// - -#ifndef CPUSUMFUNC_HPP -#define CPUSUMFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" - -namespace mllm { -class Tensor; - -class CPUsumFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - Chl axis = (Chl)args[0]; - int batch = inputs[0]->batch(); - int head = inputs[0]->head(); - int sequence = inputs[0]->sequence(); - int dimension = inputs[0]->dimension(); - switch (axis) { - case BATCH: - batch = 1; - break; - case HEAD: - head = 1; - break; - case SEQUENCE: - sequence = 1; - break; - case DIMENSION: - dimension = 1; - break; - default: - break; - } - outputs[0]->reshape(batch, head, sequence, dimension); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - Chl axis = (Chl)args[0]; - int batch = inputs[0]->batch(); - int dim = inputs[0]->dimension(); - int seq = inputs[0]->sequence(); - int head = inputs[0]->head(); - switch (axis) { - case BATCH: { - for (int h = 0; h < head; h++) { - for (int s = 0; s < seq; ++s) { - for (int d = 0; d < dim; d++) { - float sum = 0.0f; - for (int n = 0; n < batch; n++) { - sum += inputs[0]->dataAt(n, h, s, d); - } - outputs[0]->setDataAt(0, h, s, d, sum); - } - } - } - break; - } - case HEAD: { - for (int n = 0; n < batch; n++) { - for (int s = 0; s < seq; ++s) { - for (int d = 0; d < dim; d++) { - float sum = 0.0f; - for (int h = 0; h < head; h++) { - sum += inputs[0]->dataAt(n, h, s, d); - } - outputs[0]->setDataAt(n, 0, s, d, sum); - } - } - } - break; - } - case SEQUENCE: { - for (int n = 0; n < batch; n++) { - for (int h = 0; h < head; h++) { - for (int d = 0; d < dim; d++) { - float sum = 0.0f; - for (int s = 0; s < seq; ++s) { - sum += inputs[0]->dataAt(n, h, s, d); - } - outputs[0]->setDataAt(n, h, 0, d, sum); - } - } - } - break; - } - case DIMENSION: { - for (int n = 0; n < batch; n++) { - for (int h = 0; h < head; h++) { - for (int s = 0; s < seq; s++) { - float sum = 0.0f; - for (int d = 0; d < inputs[0]->dimension(); ++d) { - sum += inputs[0]->dataAt(n, h, s, d); - } - outputs[0]->setDataAt(n, h, s, 0, sum); - } - } - } - break; - } - default: - break; - } - } -}; - -} // namespace mllm -#endif // CPUSUMFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUTopkFunc.hpp b/src/backends/cpu/function/CPUTopkFunc.hpp deleted file mode 100644 index 0e01ace3c..000000000 --- a/src/backends/cpu/function/CPUTopkFunc.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// Created by Rongjie Yi on 24-12-16. -// - -#ifndef CPUTOPKFUNC_HPP -#define CPUTOPKFUNC_HPP -#include "CPUBackend.hpp" -#include "Tensor.hpp" -#include "Types.hpp" -#include -#include - -namespace mllm { -class Tensor; - -class CPUtopkFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - assert(args.size() == 2); - int k = (int)args[0]; - Chl dim = (Chl)args[1]; - if (dim == DIMENSION) { - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), k); - outputs[1]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), k); - } - outputs[0]->setDtype(inputs[0]->dtype()); // topk_values - outputs[0]->alloc(); - outputs[1]->setDtype(inputs[0]->dtype()); // topk_indices - outputs[1]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - int k = (int)args[0]; - Chl dim = (Chl)args[1]; - if (dim == DIMENSION) { -#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) - for (int n = 0; n < inputs[0]->batch(); n++) { - for (int h = 0; h < inputs[0]->head(); h++) { - for (int s = 0; s < inputs[0]->sequence(); s++) { - std::priority_queue, std::vector>, std::greater<>> topk_value_indices; - for (int d = 0; d < inputs[0]->dimension(); ++d) { - float value = inputs[0]->dataAt(n, h, s, d); - topk_value_indices.push({value, d}); - if (topk_value_indices.size() > k) { - topk_value_indices.pop(); - } - } - for (int d = k - 1; d >= 0; --d) { - auto top = topk_value_indices.top(); - topk_value_indices.pop(); - outputs[0]->setDataAt(n, h, s, d, top.first); - outputs[1]->setDataAt(n, h, s, d, top.second); - } - } - } - } - } - } -}; -} // namespace mllm -#endif // CPUTOPKFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUTransposeFunc.hpp b/src/backends/cpu/function/CPUTransposeFunc.hpp deleted file mode 100644 index f0b2a0151..000000000 --- a/src/backends/cpu/function/CPUTransposeFunc.hpp +++ /dev/null @@ -1,155 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUTRANSPOSEFUNC_HPP -#define CPUTRANSPOSEFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "Module.hpp" -#include "compute/Quantize.hpp" -#include -#include - -namespace mllm { -class Tensor; - -class CPUtransposeFunction : public TensorFunction { -public: - void setUp(vector> outputs, vector> inputs, vector args) override { - vector> axiss; - for (int i = 0; i < args.size(); i += 2) { - axiss.push_back({(Chl)args[i], (Chl)args[i + 1]}); - } - // for BSHD attention start - if(axiss.size() == 1&& axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { - if(inputs[0]->ctype() == BSHD){ - outputs[0]->chls() = {{BATCH, 0}, {HEAD, 1}, {SEQUENCE, 2}, {DIMENSION, 3}}; - }else{ - outputs[0]->chls() = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}}; - } - outputs[0]->changeCtype(4); - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - return; - } - // for BSHD attention swnd - if (!outputs[0]->undiffusion()) { - outputs[0]->transCopyShape(inputs[0]->shape()); - std::map origin_chls = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; - if (std::equal(outputs[0]->chls().begin(), outputs[0]->chls().end(), origin_chls.begin())) { - outputs[0]->chls() = inputs[0]->chls(); - for (auto axis : axiss) { - auto axis0 = axis.first; - auto axis1 = axis.second; - auto ori_0_idx = outputs[0]->chls()[axis0]; - auto ori_1_idx = outputs[0]->chls()[axis1]; - outputs[0]->chls()[axis0] = ori_1_idx; - outputs[0]->chls()[axis1] = ori_0_idx; - } - outputs[0]->changeCtype(inputs[0]->shape().size()); - outputs[0]->undiffusion() = true; - } - } - if (inputs[0]->masterTensor() != nullptr && (inputs[0]->masterTensor()->name().find("Cache") != std::string::npos || inputs[0]->masterTensor()->name().find("weight") != std::string::npos)) { - if (outputs[0]->masterTensor() == nullptr) { - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->shallowCopyFrom(inputs[0].get(), false); - } - } else { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - inputs[0]->setUndiffusion(true); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); - outputs[0]->transFrom() = axiss; - } - } - void reshape(vector> outputs, vector> inputs, vector args) override { - vector> axiss; - for (int i = 0; i < args.size(); i += 2) { - axiss.push_back({(Chl)args[i], (Chl)args[i + 1]}); - } - // for BSHD attention start - if(axiss.size() == 1&& axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { - return; - } - // for BSHD attention send - std::map origin_chls = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; - auto origin_s = inputs[0]->shape().size(); - outputs[0]->transCopyShape(inputs[0]->shape()); - if (inputs[0]->masterTensor() == nullptr - || std::equal(outputs[0]->chls().begin(), outputs[0]->chls().end(), origin_chls.begin())) { - outputs[0]->chls() = inputs[0]->chls(); - for (auto axis : axiss) { - auto axis0 = axis.first; - auto axis1 = axis.second; - auto ori_0_idx = outputs[0]->chls()[axis0]; - auto ori_1_idx = outputs[0]->chls()[axis1]; - outputs[0]->chls()[axis0] = ori_1_idx; - outputs[0]->chls()[axis1] = ori_0_idx; - } - outputs[0]->changeCtype(origin_s); - outputs[0]->undiffusion() = true; - } - if (inputs[0]->masterTensor() != nullptr - && (inputs[0]->masterTensor()->name().find("Cache") != std::string::npos || inputs[0]->masterTensor()->name().find("weight") != std::string::npos)) { - // outputs[0]->shallowCopyFrom(inputs[0]->masterTensor(), false, inputs[0]->shapeOffset()); - if (outputs[0]->masterTensor() == nullptr) { - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->shallowCopyFrom(inputs[0].get(), false); - } - } - } - void execute(vector> outputs, vector> inputs, vector args) override { - vector> axiss; - // for BSHD attention start - for (int i = 0; i < args.size(); i += 2) { - axiss.push_back({(Chl)args[i], (Chl)args[i + 1]}); - } - if(axiss.size() == 1&& axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { - if(inputs[0]->ctype() == BSHD){ - outputs[0]->chls() = {{BATCH, 0}, {HEAD, 1}, {SEQUENCE, 2}, {DIMENSION, 3}}; - }else{ - outputs[0]->chls() = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}}; - } - outputs[0]->changeCtype(4); - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), - inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->alloc(); - //BSHD -> BSHD - { //真转置 - assert(inputs[0]->batch() == 1); - assert(outputs[0]->batch() == 1); - assert(inputs[0]->head() == outputs[0]->head()); - assert(inputs[0]->sequence() == outputs[0]->sequence()); - assert(outputs[0]->ctype() == BHSD || outputs[0]->ctype() == BSHD); - if(inputs[0]->dtype() == outputs[0]->dtype()){ - #pragma omp parallel for - for (int h = 0; h < inputs[0]->head(); ++h) { - for (int s = 0; s < inputs[0]->sequence(); ++s) { - auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); - auto output_ptr = outputs[0]->ptrAt(0, h, s, 0); - memcpy(output_ptr, input_ptr, inputs[0]->dimension() * sizeof(float)); - } - } - }else{ - #pragma omp parallel for - for (int h = 0; h < inputs[0]->head(); ++h) { - for (int s = 0; s < inputs[0]->sequence(); ++s) { - auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); - auto output_ptr = outputs[0]->ptrAt(0, h, s, 0); - for (int d = 0; d < inputs[0]->dimension(); ++d) { - output_ptr[d] = MLLM_FP32_TO_FP16(input_ptr[d]); - } - } - } - } - } - } - // for BSHD attention end - } -}; -} // namespace mllm -#endif // CPUTRANSPOSEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUViewFunc.hpp b/src/backends/cpu/function/CPUViewFunc.hpp deleted file mode 100644 index 346b51d04..000000000 --- a/src/backends/cpu/function/CPUViewFunc.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUVIEWFUNC_HPP -#define CPUVIEWFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" - -namespace mllm { -class Tensor; - -class CPUviewFunction : public TensorFunction { -public: - void setUp(vector> outputs, vector> inputs, vector args) override { - // inputs[0]->shallowCopyFrom(outputs[0].get(), false); - int b = (int)args[0]; - int h = (int)args[1]; - int s = (int)args[2]; - int d = (int)args[3]; - if ((b == -1 && s == -1 && inputs[0]->ctype() != BCTHW) // head & dimension - || (b == 1 && h == 1 && inputs[0]->ctype() == BCTHW) // head & dimension - || (b == 1 && h == 1 && inputs[0]->ctype() == BSHD) // head & dimension - || (b == -1 && d == -1 && inputs[0]->ctype() == BSHD) // head & sequence - || (h == -1 && d == -1 && inputs[0]->ctype() == BSHD) // batch & sequence - || (b == -1 && h == 1 && s == 1 && d == -1 && inputs[0]->ctype() == BSHD) // sequence & head & dimension -> dimension - || (b == -1 && h == -1 && s == 1 && d == 1 && inputs[0]->ctype() == BSHD) // sequence & head & dimension -> sequence - ) { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); - } else { - std::cout << "[TODO]Tensor.View alloc not support!!!!" << std::endl; - } - } - void reshape(vector> outputs, vector> inputs, vector args) override { - int b = (int)args[0]; - int h = (int)args[1]; - int s = (int)args[2]; - int d = (int)args[3]; - int dim_b = inputs[0]->batch(); - int dim_h = inputs[0]->head(); - int dim_s = inputs[0]->sequence(); - int dim_d = inputs[0]->dimension(); - if (b == -1 && h == 1 && s == 1 && d == -1) { // sequence & head & dimension -> dimension - dim_s = 1; - dim_h = 1; - dim_d = inputs[0]->sequence() * inputs[0]->head() * inputs[0]->dimension(); - } else if (b == -1 && h == -1 && s == 1 && d == 1) { // sequence & head & dimension -> sequence - dim_s = inputs[0]->sequence() * inputs[0]->head() * inputs[0]->dimension(); - dim_h = 1; - dim_d = 1; - } else if (b == 1 && h == 1 && s == -1 && d != -1 && inputs[0]->ctype() == BCTHW) { // batch & head & sequence -> sequence - dim_b = 1; - dim_s = inputs[0]->channel() * inputs[0]->time() * inputs[0]->batch() * inputs[0]->height() * inputs[0]->width() / d; - dim_h = 1; - dim_d = d; - } else if (b == 1 && h == 1 && s == -1 && d != -1) { // batch & head & sequence -> sequence - dim_b = 1; - dim_s = inputs[0]->sequence() * inputs[0]->batch() * inputs[0]->head() * inputs[0]->dimension() / d; - dim_h = 1; - dim_d = d; - } else if (b == -1 && h != -1 && s == -1 && d != -1) { // head & dimension - if (h != ANYDIM && d != ANYDIM) { - assert(inputs[0]->dimension() * inputs[0]->head() == h * d); - dim_h = h; - dim_d = d; - } else if (h != ANYDIM) { - dim_h = h; - dim_d = inputs[0]->dimension() * inputs[0]->head() / h; - } else if (d != ANYDIM) { - dim_h = inputs[0]->dimension() * inputs[0]->head() / d; - dim_d = d; - } else { - std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; - } - } else if (b == -1 && h != -1 && s != -1 && d == -1) { // head & sequence - if (h != ANYDIM && s != ANYDIM) { - assert(inputs[0]->sequence() * inputs[0]->head() == h * s); - dim_h = h; - dim_s = s; - } else if (h != ANYDIM) { - dim_h = h; - dim_s = inputs[0]->sequence() * inputs[0]->head() / h; - } else if (s != ANYDIM) { - dim_h = inputs[0]->sequence() * inputs[0]->head() / s; - dim_s = s; - } else { - std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; - } - } else if (b != -1 && h == -1 && s != -1 && d == -1) { // batch & sequence - if (b != ANYDIM && s != ANYDIM) { - assert(inputs[0]->sequence() * inputs[0]->batch() == b * s); - dim_b = b; - dim_s = s; - } else if (b != ANYDIM) { - dim_b = b; - dim_s = inputs[0]->sequence() * inputs[0]->batch() / b; - } else if (s != ANYDIM) { - dim_b = inputs[0]->sequence() * inputs[0]->batch() / s; - dim_s = s; - } else { - std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; - } - } else { - std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; - } - if (inputs[0]->ctype() == BCTHW && inputs[0]->name() == outputs[0]->name()) { - outputs[0]->setCtype(BSHD); - } - outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); - if (inputs[0]->masterTensor() != nullptr && inputs[0]->name() == outputs[0]->name()) { - inputs[0]->shallowCopyFrom(inputs[0]->masterTensor(), false, inputs[0]->shapeOffset()); - } - - /* - outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); - if ((b == -1 && s == -1 && inputs[0]->ctype() != BCTHW) // head & dimension - || (b == 1 && h == 1 && inputs[0]->ctype() == BCTHW) // head & dimension - || (b == 1 && h == 1 && inputs[0]->ctype() == BSHD) // head & dimension - || (b == -1 && d == -1 && inputs[0]->ctype() == BSHD) // head & sequence - || (h == -1 && d == -1 && inputs[0]->ctype() == BSHD) // batch & sequence - || (b == -1 && h == 1 && s == 1 && d == -1 && inputs[0]->ctype() == BSHD) // sequence & head & dimension -> dimension - || (b == -1 && h == -1 && s == 1 && d == 1 && inputs[0]->ctype() == BSHD) // sequence & head & dimension -> sequence - ) { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0], false); - } else { - std::cout << "[TODO]Tensor.View alloc not support!!!!" << std::endl; - } - */ - } - void execute(vector> outputs, vector> inputs, vector args) override { - } -}; - -} // namespace mllm -#endif // CPUVIEWFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUVisionRoPEFunc.hpp b/src/backends/cpu/function/CPUVisionRoPEFunc.hpp deleted file mode 100644 index 9b1337a10..000000000 --- a/src/backends/cpu/function/CPUVisionRoPEFunc.hpp +++ /dev/null @@ -1,147 +0,0 @@ -// -// Created by Rongjie Yi on 25-2-16. -// - -#ifndef CPUAPPLYVISIONROPEFUNC_HPP -#define CPUAPPLYVISIONROPEFUNC_HPP -#include "CPUBackend.hpp" -#include "Tensor.hpp" -#include "Types.hpp" - -namespace mllm { -class Tensor; - -class CPUVisionRoPEFuncFunction : public TensorFunction { - void rope_hf(shared_ptr input, shared_ptr rotary_pos_emb, shared_ptr output, - int thread_count = 4) { - auto out_dtype = output->dtype(); - int partial_dimension = input->dimension(); - int half = (int)(partial_dimension / 2); - assert(partial_dimension % 2 == 0); - if (output->ctype() == BSHD) { - if (input->dtype() == MLLM_TYPE_F16) { -#pragma omp parallel for collapse(4) num_threads(thread_count) - for (int n = 0; n < input->batch(); ++n) { - for (int h = 0; h < input->head(); ++h) { - for (int s = 0; s < input->sequence(); ++s) { // sequance - for (int d = 0; d < partial_dimension / 2; ++d) { - auto v = input->ptrAt(n, h, s, d); - auto o = output->ptrAt(n, h, s, d); - float in_value = static_cast(v[0]); - float in_value_2 = static_cast(v[half]); - auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); - float sin_value = std::sin(rope_d); // sin_[s][d]; - float cos_value = std::cos(rope_d); // cos_[s][d]; - auto value = in_value * cos_value - in_value_2 * sin_value; - auto value2 = in_value * sin_value + in_value_2 * cos_value; - o[0] = MLLM_FP32_TO_FP16(value); - o[half] = MLLM_FP32_TO_FP16(value2); - } - } - } - } - - } else { - if (out_dtype == MLLM_TYPE_F32) { -#pragma omp parallel for collapse(4) num_threads(thread_count) - for (int n = 0; n < input->batch(); ++n) { - for (int h = 0; h < input->head(); ++h) { - for (int s = 0; s < input->sequence(); ++s) { // sequance - for (int d = 0; d < partial_dimension / 2; ++d) { - auto v = input->ptrAt(n, h, s, d); - auto o = output->ptrAt(n, h, s, d); - float in_value = v[0]; - float in_value_2 = v[half]; - auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); - float sin_value = std::sin(rope_d); // sin_[s][d]; - float cos_value = std::cos(rope_d); // cos_[s][d]; - auto value = in_value * cos_value - in_value_2 * sin_value; - auto value2 = in_value * sin_value + in_value_2 * cos_value; - o[0] = value; - o[half] = value2; - } - } - } - } - } else if (out_dtype == MLLM_TYPE_F16) { -#pragma omp parallel for collapse(4) num_threads(thread_count) - for (int n = 0; n < input->batch(); ++n) { - for (int h = 0; h < input->head(); ++h) { - for (int s = 0; s < input->sequence(); ++s) { // sequance - for (int d = 0; d < partial_dimension / 2; ++d) { - auto v = input->ptrAt(n, h, s, d); - auto o = output->ptrAt(n, h, s, d); - float in_value = v[0]; - float in_value_2 = v[half]; - auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); - float sin_value = std::sin(rope_d); // sin_[s][d]; - float cos_value = std::cos(rope_d); // cos_[s][d]; - auto value = in_value * cos_value - in_value_2 * sin_value; - auto value2 = in_value * sin_value + in_value_2 * cos_value; - o[0] = MLLM_FP32_TO_FP16(value); - o[half] = MLLM_FP32_TO_FP16(value2); - } - } - } - } - } - } - return; - } -#pragma omp parallel for collapse(4) num_threads(thread_count) - for (int n = 0; n < input->batch(); ++n) { - for (int h = 0; h < input->head(); ++h) { - for (int s = 0; s < input->sequence(); ++s) { // sequance - for (int d = 0; d < partial_dimension / 2; ++d) { - if (input->dtype() == MLLM_TYPE_F16) { - float in_value = static_cast(input->dataAt(n, h, s, d)); - float in_value_2 = static_cast(input->dataAt(n, h, s, d + partial_dimension / 2)); - auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); - float sin_value = std::sin(rope_d); // sin_[s][d]; - float cos_value = std::cos(rope_d); // cos_[s][d]; - auto value = in_value * cos_value - in_value_2 * sin_value; - auto value2 = in_value * sin_value + in_value_2 * cos_value; - if (out_dtype == MLLM_TYPE_F32) { - output->setDataAt(n, h, s, d, value); - output->setDataAt(n, h, s, d + partial_dimension / 2, value2); - } else if (out_dtype == MLLM_TYPE_F16) { - output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); - output->setDataAt(n, h, s, d + partial_dimension / 2, MLLM_FP32_TO_FP16(value2)); - } - - } else { - float in_value = input->dataAt(n, h, s, d); - float in_value_2 = input->dataAt(n, h, s, d + partial_dimension / 2); - auto rope_d = rotary_pos_emb->dataAt(0, 0, s, d); - float sin_value = std::sin(rope_d); // sin_[s][d]; - float cos_value = std::cos(rope_d); // cos_[s][d]; - auto value = in_value * cos_value - in_value_2 * sin_value; - auto value2 = in_value * sin_value + in_value_2 * cos_value; - if (out_dtype == MLLM_TYPE_F32) { - output->setDataAt(n, h, s, d, value); - output->setDataAt(n, h, s, d + partial_dimension / 2, value2); - } else if (out_dtype == MLLM_TYPE_F16) { - output->setDataAt(n, h, s, d, MLLM_FP32_TO_FP16(value)); - output->setDataAt(n, h, s, d + partial_dimension / 2, MLLM_FP32_TO_FP16(value2)); - } - } - } - } - } - } - } - -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - } - void execute(vector> outputs, vector> inputs, vector args) override { - auto input = inputs[0]; - auto rotary_pos_emb = inputs[1]; - rope_hf(input, rotary_pos_emb, outputs[0], CPUBackend::cpu_threads); - } -}; -} // namespace mllm -#endif // CPUAPPLYVISIONROPEFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/function/CPUWhereFunc.hpp b/src/backends/cpu/function/CPUWhereFunc.hpp deleted file mode 100644 index bb10397b6..000000000 --- a/src/backends/cpu/function/CPUWhereFunc.hpp +++ /dev/null @@ -1,107 +0,0 @@ -// -// Created by Rongjie Yi on 24-2-26. -// - -#ifndef CPUWHEREFUNC_HPP -#define CPUWHEREFUNC_HPP -#include "Tensor.hpp" -#include "Types.hpp" -#include "CPUBackend.hpp" - -namespace mllm { -class Tensor; - -class CPUwhereFunction : public TensorFunction { -public: - void reshape(vector> outputs, vector> inputs, vector args) override { - } - void execute(vector> outputs, vector> inputs, vector args) override { - float value = args[0]; - Chl axis = (Chl)args[1]; - vector b_vec = {}; - vector s_vec = {}; - vector h_vec = {}; - vector d_vec = {}; - if (inputs[0]->count() % CPUBackend::cpu_threads == 0) { -#pragma omp parallel for collapse(4) num_threads(CPUBackend::cpu_threads) - for (int b = 0; b < inputs[0]->batch(); b++) { - for (auto s = 0; s < inputs[0]->sequence(); s++) { - for (auto h = 0; h < inputs[0]->head(); h++) { - for (auto d = 0; d < inputs[0]->dimension(); d++) { - if (inputs[0]->dataAt(b, h, s, d) == value) { - b_vec.push_back(b); - s_vec.push_back(s); - h_vec.push_back(h); - d_vec.push_back(d); - } - } - } - } - } - } else { - for (int b = 0; b < inputs[0]->batch(); b++) { - for (auto s = 0; s < inputs[0]->sequence(); s++) { - for (auto h = 0; h < inputs[0]->head(); h++) { - for (auto d = 0; d < inputs[0]->dimension(); d++) { - if (inputs[0]->dataAt(b, h, s, d) == value) { - b_vec.push_back(b); - s_vec.push_back(s); - h_vec.push_back(h); - d_vec.push_back(d); - } - } - } - } - } - } - int num = b_vec.size(); - if ((int)axis == -1) { - outputs[0]->reshape(1, 1, 4, num); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - for (int i = 0; i < 4; ++i) { - auto dest_ptr = outputs[0]->hostPtr() + outputs[0]->offset(0, 0, i, 0); - switch (i) { - case 0: - memcpy(dest_ptr, b_vec.data(), num * sizeof(float)); - break; - case 1: - memcpy(dest_ptr, h_vec.data(), num * sizeof(float)); - break; - case 2: - memcpy(dest_ptr, s_vec.data(), num * sizeof(float)); - break; - case 3: - memcpy(dest_ptr, d_vec.data(), num * sizeof(float)); - break; - default: - break; - } - } - } else { - outputs[0]->reshape(1, 1, 1, num); - outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->alloc(); - auto dest_ptr = outputs[0]->hostPtr(); - switch (axis) { - case BATCH: - memcpy(dest_ptr, b_vec.data(), num * sizeof(float)); - break; - case HEAD: - memcpy(dest_ptr, h_vec.data(), num * sizeof(float)); - break; - case SEQUENCE: - memcpy(dest_ptr, s_vec.data(), num * sizeof(float)); - break; - case DIMENSION: - memcpy(dest_ptr, d_vec.data(), num * sizeof(float)); - break; - default: - break; - } - } - } -}; - -} // namespace mllm -#endif // CPUWHEREFUNC_HPP \ No newline at end of file diff --git a/src/backends/opencl/CMakeLists.txt b/src/backends/opencl/CMakeLists.txt new file mode 100644 index 000000000..94f668bf2 --- /dev/null +++ b/src/backends/opencl/CMakeLists.txt @@ -0,0 +1,31 @@ +# 查找 OpenCL 库 +find_package(OpenCL REQUIRED) +if(OpenCL_FOUND) + message(STATUS "Found OpenCL library: ${OpenCL_LIBRARIES}") + message(STATUS "Found OpenCL include directory: ${OpenCL_INCLUDE_DIRS}") +else() + message(FATAL_ERROR "OpenCL library not found.") +endif() + +# 包含 OpenCL 头文件目录 +include_directories(${OpenCL_INCLUDE_DIRS}) + +# 收集所有 OpenCL 源文件 +file(GLOB OPENCL_SRC + ${CMAKE_CURRENT_LIST_DIR}/*.cpp + ${CMAKE_CURRENT_LIST_DIR}/op/*.cpp +) + +# 定义 OpenCL 后端库 +add_library(mllm_opencl STATIC + ${OPENCL_SRC} +) + +# 链接 OpenCL 库 +target_link_libraries(mllm_opencl PRIVATE OpenCL::OpenCL) + +# 将 mllm_opencl 库的头文件目录设为 public +# 这样其他目标链接到 mllm_opencl 时就能自动找到头文件 +target_include_directories(mllm_opencl PUBLIC + ${CMAKE_CURRENT_LIST_DIR} +) \ No newline at end of file diff --git a/src/backends/opencl/OpenCLBackend.cpp b/src/backends/opencl/OpenCLBackend.cpp new file mode 100644 index 000000000..7550265d5 --- /dev/null +++ b/src/backends/opencl/OpenCLBackend.cpp @@ -0,0 +1,524 @@ +#include "OpenCLBackend.hpp" +#include +#include +#include +#include "Tensor.hpp" + +#include "./op/OpenCLAddFuncOp.hpp" +#include "utils/OpenCLTools.hpp" + +// 错误检查函数 +void check_cl_error(cl_int err, const std::string& operation) { + if (err != CL_SUCCESS) { + std::cerr << "OpenCL Error during " << operation << " (" << err << ")" << std::endl; + //应该调度到cpu + throw std::runtime_error("OpenCL Error: " + operation); + } +} + +// 从文件加载内核源码的辅助函数 +std::string load_file_contents(const char* filename) { + std::ifstream in(filename, std::ios::in | std::ios::binary); + if (in) { + return std::string((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + } + throw std::runtime_error(std::string("Could not open file: ") + filename); +} + + +namespace mllm { + +// 静态辅助函数,用于在构造函数初始化列表中创建 MemoryManager +// 这样可以确保在调用基类构造函数之前,context 和 device 已经被正确初始化 +std::shared_ptr OpenCLBackend::createMemoryManager(cl_context& context, cl_device_id& device) { + cl_int err; + cl_platform_id platform; + + // 1. 获取平台 + err = clGetPlatformIDs(1, &platform, nullptr); + check_cl_error(err, "clGetPlatformIDs"); + + // 2. 获取设备 (优先GPU) + err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, nullptr); + if (err != CL_SUCCESS) { + err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &device, nullptr); + } + check_cl_error(err, "clGetDeviceIDs"); + + // 3. 创建上下文 + context = clCreateContext(nullptr, 1, &device, nullptr, nullptr, &err); + check_cl_error(err, "clCreateContext"); + + // 4. 创建并返回 OpenCLMemoryManager + return std::make_shared(context); +} // namespace mllm + +OpenCLBackend::OpenCLBackend(const BackendConfig &config) : Backend() { + mem_manager_ = createMemoryManager(context_, device_); + cl_int err; + queue_ = clCreateCommandQueue(context_, device_, 0, &err); + check_cl_error(err, "clCreateCommandQueue"); + + + // ======================================================================= + // ========== 检查扩展支持和获取对齐值 ========== + // ======================================================================= + size_t extensions_size; + // 获取扩展字符串的长度 + clGetDeviceInfo(device_, CL_DEVICE_EXTENSIONS, 0, nullptr, &extensions_size); + std::string extensions(extensions_size, ' '); + // 获取完整的扩展字符串 + clGetDeviceInfo(device_, CL_DEVICE_EXTENSIONS, extensions_size, &extensions[0], nullptr); + + if (extensions.find("cl_khr_fp16") != std::string::npos) { + this->has_fp16_support_ = true; + } else { + this->has_fp16_support_ = false; + } + // 检查是否包含我们需要的扩展 + if (extensions.find("cl_khr_image2d_from_buffer") != std::string::npos) { + this->image_from_buffer_supported_ = true; + + // 如果支持,则进一步查询行间距对齐要求(单位:字节) + // CL_DEVICE_IMAGE_PITCH_ALIGNMENT 返回的是像素单位,需要转换,不如此处直接查询字节对齐可靠。 + // CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 是一个更通用的字节对齐保证。 + clGetDeviceInfo(device_, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT, sizeof(cl_uint), &this->image_pitch_alignment_bytes_, nullptr); + + // 根据规范,如果返回0,则表示没有特殊的对齐要求,我们可以认为是1字节对齐。 + if (this->image_pitch_alignment_bytes_ == 0) { + this->image_pitch_alignment_bytes_ = 1; + } + } else { + // 如果不支持,明确设置为false + this->image_from_buffer_supported_ = false; + this->image_pitch_alignment_bytes_ = 0; + } + // ======================================================================= + const std::string convert_kernel_path = get_kernel_path(__FILE__, "./kernel/convert.cl"); + std::string build_options = ""; + + // 如果硬件支持FP16,我们通过宏定义告诉编译器去编译高性能版本的内核 + if (this->has_fp16_support_) { + build_options += " -DSUPPORTS_FP16"; + } + + cl_program convert_program = getProgram(convert_kernel_path, build_options); + + // --- 根据硬件能力,创建并加载相应版本的内核 --- + if (this->has_fp16_support_) { + // **高性能路径**: 加载使用原生 `half` 的内核 + kernel_fp32_to_fp16_buffer_ = clCreateKernel(convert_program, "convert_fp32_to_fp16_buffer_ext", &err); + check_cl_error(err, "CreateKernel: convert_fp32_to_fp16_buffer_ext"); + kernel_fp16_to_fp32_buffer_ = clCreateKernel(convert_program, "convert_fp16_to_fp32_buffer_ext", &err); + check_cl_error(err, "CreateKernel: convert_fp16_to_fp32_buffer_ext"); + + // Image内核只有在支持FP16时才有意义 + kernel_fp32_to_fp16_image_ = clCreateKernel(convert_program, "convert_fp32_to_fp16_image2d", &err); + check_cl_error(err, "CreateKernel: convert_fp32_to_fp16_image2d"); + kernel_fp16_to_fp32_image_ = clCreateKernel(convert_program, "convert_fp16_to_fp32_image2d", &err); + check_cl_error(err, "CreateKernel: convert_fp16_to_fp32_image2d"); + + } else { + // **兼容性路径**: 加载使用 `ushort` 模拟的内核 + kernel_fp32_to_fp16_buffer_ = clCreateKernel(convert_program, "convert_fp32_to_fp16_buffer_compat", &err); + check_cl_error(err, "CreateKernel: convert_fp32_to_fp16_buffer_compat"); + kernel_fp16_to_fp32_buffer_ = clCreateKernel(convert_program, "convert_fp16_to_fp32_buffer_compat", &err); + check_cl_error(err, "CreateKernel: convert_fp16_to_fp32_buffer_compat"); + // 在不原生支持FP16的设备上,Image转换通常也不可行或无意义,所以不加载Image内核 + } + + sampler_ = clCreateSampler(context_, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler in Backend"); + + this->type_ = MLLM_OPENCL; + registerOps(); +} + +OpenCLBackend::~OpenCLBackend() { + // 释放所有缓存的 cl_program + if (kernel_fp32_to_fp16_buffer_) clReleaseKernel(kernel_fp32_to_fp16_buffer_); + if (kernel_fp16_to_fp32_buffer_) clReleaseKernel(kernel_fp16_to_fp32_buffer_); + if (kernel_fp32_to_fp16_image_) clReleaseKernel(kernel_fp32_to_fp16_image_); + if (kernel_fp16_to_fp32_image_) clReleaseKernel(kernel_fp16_to_fp32_image_); + if (sampler_) clReleaseSampler(sampler_); + + // (保留原有释放 program 和 queue 的代码) + for (auto const& [key, program] : program_cache_) { + if (program) { + clReleaseProgram(program); + } + } + if (queue_) clReleaseCommandQueue(queue_); + if (context_) clReleaseContext(context_); + // std::cout << "OpenCLBackend cleaned up." << std::endl; +} + +void OpenCLBackend::finishQueue() { + if(queue_) { + clFinish(queue_); + } +} + +cl_program OpenCLBackend::getProgram(const std::string& program_name, const std::string& build_options) { + // 检查缓存 + auto it = program_cache_.find(program_name); + if (it != program_cache_.end()) { + return it->second; + } + + // 加载和编译 + std::string kernel_source = load_file_contents(program_name.c_str()); + const char* source_ptr = kernel_source.c_str(); + size_t source_len = kernel_source.length(); + cl_int err; + + cl_program program = clCreateProgramWithSource(context_, 1, &source_ptr, &source_len, &err); + check_cl_error(err, "clCreateProgramWithSource"); + + err = clBuildProgram(program, 1, &device_, build_options.c_str(), nullptr, nullptr); + if (err != CL_SUCCESS) { + size_t log_size; + clGetProgramBuildInfo(program, device_, CL_PROGRAM_BUILD_LOG, 0, nullptr, &log_size); + std::vector log(log_size); + clGetProgramBuildInfo(program, device_, CL_PROGRAM_BUILD_LOG, log_size, log.data(), nullptr); + std::string error_msg = "Kernel build error for " + program_name + ":\n" + log.data(); + throw std::runtime_error(error_msg); + } + + // 存入缓存并返回 + program_cache_[program_name] = program; + return program; +} +void OpenCLBackend::alloc_device(DeviceMemory &mem, DataType dtype) { + if (context_ == nullptr) throw std::runtime_error("OpenCL context is not initialized."); + cl_int err; + switch (mem.type) { + case MEM_TYPE_BUFFER: { + // **新增逻辑**:检查是否是创建 Image 兼容 Buffer 的特殊请求 + if (mem.image_width > 0 && mem.image_height > 0 && image_from_buffer_supported_) { + // === 创建 Image 兼容的、带行间距对齐的 Buffer === + + // 1. 计算满足硬件对齐要求的行间距(字节单位) + const size_t pixel_width = mem.image_width; // 此时 image_width 是像素数 + const cl_uint pitch_alignment = image_pitch_alignment_bytes_; + + size_t row_pitch = pixel_width * 4 * sizeof(float); // 理论行间距 + if (pitch_alignment > 0 && row_pitch % pitch_alignment != 0) { + row_pitch = (row_pitch + pitch_alignment - 1) / pitch_alignment * pitch_alignment; + } + + // 2. 计算带填充的总 buffer 大小 + const size_t padded_buffer_size = mem.image_height * row_pitch; + + // 3. 更新 DeviceMemory 结构体,保存关键信息 + mem.size_in_bytes = padded_buffer_size; // 使用计算出的、更大的尺寸 + mem.image_row_pitch_in_bytes = row_pitch; // **保存行间距,为零拷贝做准备** + + // 4. 使用新的总大小创建 Buffer + mem.handle = clCreateBuffer(context_, CL_MEM_READ_WRITE, padded_buffer_size, nullptr, &err); + check_cl_error(err, "clCreateBuffer for Image-Compatible Buffer"); + + } else { + // === 创建一个标准的、紧密排列的 Buffer === + mem.handle = clCreateBuffer(context_, CL_MEM_READ_WRITE, mem.size_in_bytes, nullptr, &err); + check_cl_error(err, "clCreateBuffer for Standard Buffer"); + } + break; + } + case MEM_TYPE_IMAGE_2D: { + // cl_image_format format = {CL_RGBA, CL_FLOAT}; + cl_image_format format = {CL_RGBA}; // 通道顺序不变 + + // **核心修改:根据dtype设置通道数据类型** + switch (dtype) { + case MLLM_TYPE_F32: + format.image_channel_data_type = CL_FLOAT; + break; + case MLLM_TYPE_F16: + format.image_channel_data_type = CL_HALF_FLOAT; + break; + default: + throw std::runtime_error("Unsupported data type for Image2D creation."); + } + cl_image_desc desc = {}; + desc.image_type = CL_MEM_OBJECT_IMAGE2D; + desc.image_width = mem.image_width; + desc.image_height = mem.image_height; + mem.handle = clCreateImage(context_, CL_MEM_READ_WRITE, &format, &desc, nullptr, &err); + check_cl_error(err, "clCreateImage"); + break; + } + default: throw std::runtime_error("Unsupported device memory type for OpenCL."); + } +} + +void OpenCLBackend::free_device(DeviceMemory &mem) { + if (mem.handle != nullptr) { + clReleaseMemObject(static_cast(mem.handle)); + mem.handle = nullptr; + } +} + +void OpenCLBackend::copy_from_host(const DeviceMemory &dest, const void *src) { + if (dest.handle == nullptr || src == nullptr) return; + cl_mem dest_handle = static_cast(dest.handle); + switch (dest.type) { + case MEM_TYPE_BUFFER:{ + // 检查这个Buffer是否是Image兼容的 + if (dest.image_row_pitch_in_bytes > 0 && dest.image_height > 0) { + // **使用 clEnqueueWriteBufferRect 来处理行间距** + const size_t buffer_origin[3] = {0, 0, 0}; + const size_t host_origin[3] = {0, 0, 0}; + + // region_in_bytes: {width, height, depth} + const size_t region_in_bytes[3] = { + dest.image_width * 4 * sizeof(float), // 拷贝区域的宽度(字节) + dest.image_height, // 拷贝区域的高度(行数) + 1 // 深度为1 + }; + + clEnqueueWriteBufferRect( + queue_, + dest_handle, + CL_TRUE, // 阻塞调用 + buffer_origin, + host_origin, + region_in_bytes, + dest.image_row_pitch_in_bytes, // Buffer中的行间距 + 0, // Buffer中的切片间距 + dest.image_width * 4 * sizeof(float), // Host内存中的行间距(假设紧密排列) + 0, // Host内存中的切片间距 + src, + 0, nullptr, nullptr); + } else { + // 标准的Buffer拷贝 + clEnqueueWriteBuffer(queue_, dest_handle, CL_TRUE, 0, dest.size_in_bytes, src, 0, nullptr, nullptr); + } + break; + } + case MEM_TYPE_IMAGE_2D: { + const size_t origin[3] = {0, 0, 0}; + const size_t region[3] = {dest.image_width, dest.image_height, 1}; + clEnqueueWriteImage(queue_, dest_handle, CL_TRUE, origin, region, 0, 0, src, 0, nullptr, nullptr); + break; + } + default: throw std::runtime_error("Unsupported copy for this memory type."); + } +} + +void OpenCLBackend::copy_to_host(void *dest, const DeviceMemory &src) { + if (dest == nullptr || src.handle == nullptr) return; + cl_mem src_handle = static_cast(src.handle); + switch (src.type) { + case MEM_TYPE_BUFFER: + clEnqueueReadBuffer(queue_, src_handle, CL_TRUE, 0, src.size_in_bytes, dest, 0, nullptr, nullptr); + break; + case MEM_TYPE_IMAGE_2D: { + const size_t origin[3] = {0, 0, 0}; + const size_t region[3] = {src.image_width, src.image_height, 1}; + clEnqueueReadImage(queue_, src_handle, CL_TRUE, origin, region, 0, 0, dest, 0, nullptr, nullptr); + break; + } + default: throw std::runtime_error("Unsupported copy for this memory type."); + } +} + +cl_mem OpenCLBackend::get_cl_mem(const Tensor &tensor) const { + if (tensor.backend() != this) throw std::runtime_error("Tensor is not on this backend."); + const auto& mem = tensor.device_memory(); + if (mem.handle == nullptr) throw std::runtime_error("Tensor CL handle is null."); + return static_cast(mem.handle); +} + + +Op *OpenCLBackend::opCreate(const OpParam &op_param, std::string name, int threadCount) { + OpType type = (OpType)op_param.find("type")->second; + auto it = op_creator_map_.find(type); + if (it == op_creator_map_.end()) { + throw std::runtime_error("Op type " + std::to_string(type) + " not supported by OpenCLBackend"); + } + return it->second->create(op_param, this, name, threadCount); +} + +TensorFunction *OpenCLBackend::funcCreate(TensorFuncType type) { + throw std::runtime_error("funcCreate not implemented for OpenCLBackend"); + return nullptr; +} + +void OpenCLBackend::registerOps() { + // 在这里注册该后端支持的所有 Op + op_creator_map_[F_TTADD] = std::make_shared(); + // std::cout << "OpenCLBackend ops registered." << std::endl; +} + +void OpenCLBackend::registerFuncs() { + std::cout << "OpenCLBackend funcs is abanded." << std::endl; +} + + +// 用以下最终完整版替换您的 convert_fp_data 函数 +void OpenCLBackend::convert_fp_data(Tensor *src, Tensor *dest) { + if (src->device() != MLLM_OPENCL || dest->device() != MLLM_OPENCL) { + throw std::runtime_error("Type conversion on GPU requires both tensors to be on OpenCL backend."); + } + + // 获取源和目标的内存描述符 + auto& src_mem = src->device_memory(); + auto& dest_mem = dest->device_memory(); + + // =================================================== + // ============ 第一层决策:根据内存类型 ============ + // =================================================== + + if (src_mem.type == MEM_TYPE_BUFFER) { + // ========== Buffer-to-Buffer 转换路径 ========== + if (dest_mem.type != MEM_TYPE_BUFFER) throw std::runtime_error("Destination must be a Buffer for Buffer conversion."); + + cl_kernel kernel_to_use = nullptr; + if (src->dtype() == MLLM_TYPE_F32 && dest->dtype() == MLLM_TYPE_F16) { + kernel_to_use = kernel_fp32_to_fp16_buffer_; + } else if (src->dtype() == MLLM_TYPE_F16 && dest->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp16_to_fp32_buffer_; + } else { + if(src->dtype() == dest->dtype()) return; + throw std::runtime_error("Unsupported Buffer conversion types."); + } + + cl_mem src_buf = get_cl_mem(*src); + cl_mem dest_buf = get_cl_mem(*dest); + int count = src->count(); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &src_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &dest_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(int), &count); + + const size_t global_work_size[1] = { (size_t)count }; + clEnqueueNDRangeKernel(queue_, kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + + } else if (src_mem.type == MEM_TYPE_IMAGE_2D) { + + if (dest_mem.type != MEM_TYPE_IMAGE_2D) throw std::runtime_error("Destination must be an Image for Image conversion."); + + cl_kernel kernel_to_use = nullptr; + + if (src->dtype() == MLLM_TYPE_F32 && dest->dtype() == MLLM_TYPE_F16) { + kernel_to_use = kernel_fp32_to_fp16_image_; + } else if (src->dtype() == MLLM_TYPE_F16 && dest->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp16_to_fp32_image_; + } else { + if(src->dtype() == dest->dtype()) return; + throw std::runtime_error("Unsupported Image conversion types."); + } + + // **新增**: 健壮性检查,如果内核未创建(例如硬件不支持FP16),则报错 + if (!kernel_to_use) { + throw std::runtime_error("Image conversion kernel is not available. This may be due to lack of FP16 hardware support."); + } + + cl_mem src_img = get_cl_mem(*src); + cl_mem dest_img = get_cl_mem(*dest); + const int width = src_mem.image_width; + const int height = src_mem.image_height; + + // **修改**: 取消注释并使用成员变量 sampler_ + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &src_img); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &dest_img); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &height); + + const size_t global_work_size[2] = { (size_t)width, (size_t)height }; + clEnqueueNDRangeKernel(queue_, kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } +} + +void registerOpenCLBackendCreator() { + InsertBackendCreatorMap(MLLM_OPENCL, std::make_shared()); +} + + +std::vector OpenCLBackend::runLayer(Layer *layer, std::vector inputs, int N) { + throw std::runtime_error("runLayer not implemented for OpenCLBackend"); + return {}; +} + +std::vector OpenCLBackend::runOp(Op *op, std::vector inputs, std::vector out_names, bool in_place) { + Module *module = inputs[0].module(); + // map> &actime] = std::make_shared(op->backend()); + // activation_tensors[out_name]->setName(out_name); + // activation_tensors[out_name]->setModule(module); + // }vation_tensors = module->activation_tensors; + // if (module->doTrace) { // trace + // for (const auto &out_name : out_names) { + // if (activation_tensors.find(out_name) == activation_tensors.end()) { + // activation_tensors[out_na + // } + // vector> inPtrs; + // for (auto &input : inputs) { + // inPtrs.push_back(input.shouldInGraphs() ? activation_tensors[input.name()] : + // std::shared_ptr(&input, [](Tensor *) {})); + // } + // vector> outPtrs = {}; + // for (auto &name : out_names) outPtrs.push_back(activation_tensors[name]); + // op->setUp(inPtrs, outPtrs); + // vector results = {}; + // for (auto &name : out_names) results.push_back(*activation_tensors[name]); + // return results; + // } + +#ifdef DEBUGOPTIME + uint64_t time_start = mllm_time_us(); +#endif + vector> input_tensors; + for (auto &input : inputs) { + input_tensors.push_back(std::shared_ptr(&input, [](Tensor *) {})); + } + vector> out_tensors; + // Part 1: Create tensor shells + for (const auto &out_name : out_names) { + auto out_tensor = std::make_shared(op->backend()); + out_tensor->setName(out_name); + // out_tensor->setModule(module); + out_tensors.push_back(out_tensor); + } + // if (!in_place) { + // _create_output_tensors(out_tensors, input_tensors, out_names, module, activation_tensors, op->backend()); + // } else { + // // If in-place, we already have out_tensors filled with input tensors. + // for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { + // input_tensors[i]->setName(out_names[i]); + // out_tensors.push_back(input_tensors[i]); + // } + // } + // Part 2: Reshape the tensors + op->reshape(input_tensors, out_tensors); + // Part 3: Allocate memory + op->setUp(input_tensors, out_tensors); + // if (!in_place) { + // for (auto &out_tensor : out_tensors) { + // auto act_it = activation_tensors.find(out_tensor->name()); + // auto template_it = act_it != activation_tensors.end() ? act_it->second : nullptr; + // out_tensor->allocFromTemplate(template_it); + // } + // } + // Part 4: Execute the operation + op->execute(input_tensors, out_tensors); + +#ifdef DEBUGOPTIME + uint64_t time_end = mllm_time_us(); + double inference_time_ = (time_end - time_start) / 1000.0F; // ms + std::cout << layer->op_->name() << " | time: " << inference_time_ << "ms" << std::endl; +#endif + + vector results; + for (const auto &out_tensor : out_tensors) { results.push_back(*out_tensor); } + return results; +} + +std::vector OpenCLBackend::runForward(Module *module, std::vector inputs, std::vector args) { + throw std::runtime_error("runForward not implemented for OpenCLBackend"); + return {}; +} + + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/OpenCLBackend.hpp b/src/backends/opencl/OpenCLBackend.hpp new file mode 100644 index 000000000..985e30209 --- /dev/null +++ b/src/backends/opencl/OpenCLBackend.hpp @@ -0,0 +1,121 @@ +#ifndef OPENCL_BACKEND_H +#define OPENCL_BACKEND_H + +#include "Backend.hpp" +#include "OpenCLMemoryManager.hpp" +#include +#include +#include +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif + +// 外部函数声明,用于错误检查 +// void check_cl_error(cl_int err, const std::string& operation); + +namespace mllm { +struct DeviceMemory; +class Tensor; + +class OpenCLBackend : public Backend { +public: + + // 为工厂模式定义的 Creator 基类 + class Creator { + public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const = 0; + virtual ~Creator() = default; + }; + + + OpenCLBackend(const BackendConfig &config); + ~OpenCLBackend() override; + + // --- OpenCL 特有方法 --- + cl_context getContext() const { return context_; } + cl_device_id getDevice() const { return device_; } + cl_command_queue getQueue() const { return queue_; } + void finishQueue(); + // 获取或编译并缓存 Kernel Program + cl_program getProgram(const std::string& program_name, const std::string& build_options = ""); + + // --- 实现基类的纯虚函数 --- + Op *opCreate(const OpParam &op_param, std::string name = "", int threadCount = 4) override; + TensorFunction *funcCreate(TensorFuncType type) override; + + void alloc_device(DeviceMemory &mem, DataType dtype) override; + void free_device(DeviceMemory &mem) override; + void copy_from_host(const DeviceMemory &dest, const void *src) override; + void copy_to_host(void *dest, const DeviceMemory &src) override; + + // 注意:下面几个函数的具体实现依赖于你的框架逻辑,这里暂时提供桩实现 (stub) + std::vector runLayer(Layer *layer, std::vector inputs, int N) override; + std::vector runOp(Op *op, std::vector input, std::vector out_names, bool in_place) override; + std::vector runForward(Module *module, std::vector inputs, std::vector args) override; + + void registerOps() override; + void registerFuncs() override; + void convert_fp_data(Tensor *src, Tensor *dest) override; + + cl_mem get_cl_mem(const Tensor &tensor) const; + /** + * @brief 检查当前设备是否支持从Buffer创建Image的零拷贝扩展。 + */ + bool is_image_from_buffer_supported() const { return image_from_buffer_supported_; } + + /** + * @brief 获取设备要求的Image行间距对齐字节数。 + */ + cl_uint get_image_pitch_alignment_in_bytes() const { return image_pitch_alignment_bytes_; } + + + +private: + // 构造函数辅助函数,用于解决基类和子类成员的初始化顺序问题 + static std::shared_ptr createMemoryManager(cl_context& context, cl_device_id& device); + + cl_context context_ = nullptr; + cl_device_id device_ = nullptr; + cl_command_queue queue_ = nullptr; + + // 内核程序缓存 + std::map program_cache_; + std::map> op_creator_map_; + + /** + * @brief 标记设备是否支持 cl_khr_image2d_from_buffer 扩展。 + */ + bool image_from_buffer_supported_ = false; + + /** + * @brief 存储硬件要求的Image行间距对齐字节数。 + */ + cl_uint image_pitch_alignment_bytes_ = 0; + /** + * @brief 标记设备是否支持 cl_khr_fp16 扩展。 + */ + bool has_fp16_support_ = false; +private: + cl_kernel kernel_fp32_to_fp16_buffer_ = nullptr; + cl_kernel kernel_fp16_to_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_to_fp16_image_ = nullptr; // 新增 + cl_kernel kernel_fp16_to_fp32_image_ = nullptr; // 新增 + cl_sampler sampler_ = nullptr; +}; + + +class OpenCLBackendCreator : public BackendCreator { +public: + Backend *create(BackendConfig config) override { + return new OpenCLBackend(config); + } +}; + + +} // namespace mllm + +#endif // OPENCL_BACKEND_H \ No newline at end of file diff --git a/src/backends/opencl/OpenCLMemoryManager.cpp b/src/backends/opencl/OpenCLMemoryManager.cpp new file mode 100644 index 000000000..0db3dd32c --- /dev/null +++ b/src/backends/opencl/OpenCLMemoryManager.cpp @@ -0,0 +1,28 @@ +#include "OpenCLMemoryManager.hpp" +#include + +namespace mllm { + +OpenCLMemoryManager::OpenCLMemoryManager(cl_context context) : context_(context) { + assert(context_ != nullptr); +} + +void OpenCLMemoryManager::alloc(void **ptr, size_t size, size_t alignment) { + assert(ptr != nullptr); + assert(size > 0); + + cl_int err; + // 分配一个可供GPU内核读写的设备缓冲区 + cl_mem buffer = clCreateBuffer(context_, CL_MEM_READ_WRITE, size, nullptr, &err); + check_cl_error(err, "OpenCLMemoryManager::clCreateBuffer"); + *ptr = buffer; +} + +void OpenCLMemoryManager::free(void *ptr) { + if (ptr != nullptr) { + cl_mem buffer = static_cast(ptr); + clReleaseMemObject(buffer); + } +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/OpenCLMemoryManager.hpp b/src/backends/opencl/OpenCLMemoryManager.hpp new file mode 100644 index 000000000..77571a6bd --- /dev/null +++ b/src/backends/opencl/OpenCLMemoryManager.hpp @@ -0,0 +1,32 @@ +#ifndef OPENCL_MEMORY_MANAGER_H +#define OPENCL_MEMORY_MANAGER_H + +#include "MemoryManager.hpp" +#include // For std::string in check_cl_error + +#ifdef __APPLE__ +#include +#else +#include +#endif + +// 前向声明,实现在 backend.cpp 中 +void check_cl_error(cl_int err, const std::string& operation); + +namespace mllm { + +class OpenCLMemoryManager : public MemoryManager { +public: + explicit OpenCLMemoryManager(cl_context context); + ~OpenCLMemoryManager() override = default; + + void alloc(void **ptr, size_t size, size_t alignment) override; + void free(void *ptr) override; + +private: + cl_context context_; // 需要OpenCL上下文来创建缓冲区 +}; + +} // namespace mllm + +#endif // OPENCL_MEMORY_MANAGER_H \ No newline at end of file diff --git a/src/backends/opencl/kernel/add.cl b/src/backends/opencl/kernel/add.cl new file mode 100644 index 000000000..06529f25b --- /dev/null +++ b/src/backends/opencl/kernel/add.cl @@ -0,0 +1,109 @@ +__kernel void add_float( + __global const float* A, + __global const float* B, + __global float* C) { + size_t index = get_global_id(0); + C[index] = A[index] + B[index]; +} + + +/* + * 定义一个全局的采样器(sampler)。采样器是用于配置如何从图像对象中读取数据的。 + * CLK_NORMALIZED_COORDS_FALSE: 使用非归一化的整数坐标(像素坐标),而不是[0.0, 1.0]的浮点坐标。 + * CLK_ADDRESS_CLAMP_TO_EDGE: 当读取坐标超出图像边界时,自动返回最接近的边界上的像素值,可有效防止越界读取。 + * CLK_FILTER_NEAREST: 读取最接近坐标的那个像素,不做任何插值,这对于数据计算是必须的。 + */ +// const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST; +/** + * @brief 使用 image2d_t 对两个 float 类型的张量进行高效的元素级相加。 + * @param sampler 用于读取图像的采样器对象。 + * @param inputA 输入张量 A,作为只读的 2D 图像对象。 + * @param inputB 输入张量 B,作为只读的 2D 图像对象。 + * @param output 输出张量 C,作为只写的 2D 图像对象。 + * @param width 图像的逻辑宽度(单位:像素)。 + * @param height 图像的逻辑高度(单位:像素)。 + */ +__kernel void add_float_image2d( + sampler_t sampler, // 采样器现在是第一个参数 + __read_only image2d_t inputA, + __read_only image2d_t inputB, + __write_only image2d_t output, + const int width, + const int height) +{ + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + + if (pos.x >= width || pos.y >= height) { + return; + } + + float4 inA = read_imagef(inputA, sampler, pos); + float4 inB = read_imagef(inputB, sampler, pos); + float4 result = inA + inB; + write_imagef(output, pos, result); +} + + + + + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +/** + * @brief [FP16 Buffer版] 使用向量指令对两个 half 类型的张量进行高效的元素级相加。 + * 内核利用 vload4/vstore4 一次处理4个 half 元素。 + * @param A 输入张量 A (__global const half*) + * @param B 输入张量 B (__global const half*) + * @param C 输出张量 C (__global half*) + */ +__kernel void add_fp16_vector( + __global const half* A, + __global const half* B, + __global half* C) +{ + const int i = get_global_id(0); + + // 高效地加载 4 个 half (共64位) 数据 + half4 a_vec = vload4(i, A); + half4 b_vec = vload4(i, B); + + // 向量加法 + half4 c_vec = a_vec + b_vec; + + // 高效地写回 4 个 half 数据 + vstore4(c_vec, i, C); +} + +/** + * @brief [FP16 Image版] 使用 image2d_t 对两个 half 类型的张量进行高效的元素级相加。 + * 利用硬件纹理缓存和 read_imageh/write_imageh 函数。 + * @param sampler 用于读取图像的采样器对象。 + * @param inputA 输入张量 A,作为只读的 2D 图像对象 (数据类型为 half)。 + * @param inputB 输入张量 B,作为只读的 2D 图像对象 (数据类型为 half)。 + * @param output 输出张量 C,作为只写的 2D 图像对象 (数据类型为 half)。 + * @param width 图像的逻辑宽度(单位:像素)。 + * @param height 图像的逻辑高度(单位:像素)。 + */ +__kernel void add_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + __read_only image2d_t inputB, + __write_only image2d_t output, + const int width, + const int height) +{ + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + + if (pos.x >= width || pos.y >= height) { + return; + } + + // 使用 read_imageh 读取 half4 向量 + half4 inA = read_imageh(inputA, sampler, pos); + half4 inB = read_imageh(inputB, sampler, pos); + + half4 result = inA + inB; + + // 使用 write_imageh 写回 half4 向量 + write_imageh(output, pos, result); +} diff --git a/src/backends/opencl/kernel/convert.cl b/src/backends/opencl/kernel/convert.cl new file mode 100644 index 000000000..d1e3a3314 --- /dev/null +++ b/src/backends/opencl/kernel/convert.cl @@ -0,0 +1,115 @@ + +// 将一个32位float转换为16位ushort (模拟FP16) +ushort float_to_half_bits(const float f) { + const uint u = as_uint(f); + const uint sign = (u >> 16) & 0x8000; + uint exponent = ((u >> 23) & 0xff) - 127; + uint mantissa = u & 0x7fffff; + + if (exponent > 15) return sign | 0x7c00; + if (exponent >= -14) { + exponent = (exponent + 15) << 10; + mantissa >>= 13; + return sign | exponent | mantissa; + } + if (exponent >= -24) { + mantissa = (mantissa | 0x800000) >> (14 - (-exponent)); + return sign | mantissa; + } + return sign; +} + +// 将一个16位ushort (模拟FP16) 转换回32位float +float half_bits_to_float(const ushort h) { + const uint sign = (h >> 15) & 1; + uint exponent = (h >> 10) & 0x1f; + uint mantissa = h & 0x3ff; + + if (exponent == 0x1f) return as_float((sign << 31) | 0x7f800000 | (mantissa << 13)); + if (exponent == 0) { + if (mantissa == 0) return as_float(sign << 31); + mantissa <<= 1; + while ((mantissa & 0x400) == 0) { mantissa <<= 1; exponent--; } + mantissa &= 0x3ff; exponent += 1; + } + exponent = exponent + (127 - 15); + mantissa <<= 13; + return as_float((sign << 31) | (exponent << 23) | mantissa); +} + +__kernel void convert_fp32_to_fp16_buffer_compat( // 兼容版内核 + __global const float* input, + __global ushort* output, + const int count) +{ + int i = get_global_id(0); + if (i < count) output[i] = float_to_half_bits(input[i]); +} + +__kernel void convert_fp16_to_fp32_buffer_compat( // 兼容版内核 + __global const ushort* input, + __global float* output, + const int count) +{ + int i = get_global_id(0); + if (i < count) output[i] = half_bits_to_float(input[i]); +} + +// =================================================================== +// **部分二:高性能内核(需要硬件原生支持FP16)** +// 只有在C++端定义了 "SUPPORTS_FP16" 宏时,这部分代码才会被编译。 +// =================================================================== +#ifdef SUPPORTS_FP16 + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// --- Buffer Kernels (高性能版) --- +__kernel void convert_fp32_to_fp16_buffer_ext( // 高性能版内核 + __global const float* input, + __global half* output, + const int count) +{ + int i = get_global_id(0); + if (i < count) output[i] = convert_half(input[i]); +} + +__kernel void convert_fp16_to_fp32_buffer_ext( // 高性能版内核 + __global const half* input, + __global float* output, + const int count) +{ + int i = get_global_id(0); + if (i < count) output[i] = vload_half(i, input); +} + +// --- Image Kernels (高性能版) --- +// Image的FP16转换本身就依赖硬件支持,所以它只在高性能路径下才有意义。 +__kernel void convert_fp32_to_fp16_image2d( + sampler_t sampler, + __read_only image2d_t input_fp32, + __write_only image2d_t output_fp16, + const int width, + const int height) +{ + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) return; + float4 data_fp32 = read_imagef(input_fp32, sampler, pos); + half4 data_fp16 = convert_half4(data_fp32); + write_imageh(output_fp16, pos, data_fp16); +} + +__kernel void convert_fp16_to_fp32_image2d( + sampler_t sampler, + __read_only image2d_t input_fp16, + __write_only image2d_t output_fp32, + const int width, + const int height) +{ + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) return; + half4 data_fp16 = read_imageh(input_fp16, sampler, pos); + float4 data_fp32 = convert_float4(data_fp16); + write_imagef(output_fp32, pos, data_fp32); +} + +#endif // SUPPORTS_FP16 \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLAddFuncOp.cpp b/src/backends/opencl/op/OpenCLAddFuncOp.cpp new file mode 100644 index 000000000..fa579af30 --- /dev/null +++ b/src/backends/opencl/op/OpenCLAddFuncOp.cpp @@ -0,0 +1,174 @@ +#include "OpenCLAddFuncOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" + +namespace mllm { + + +OpenCLAddFuncOp::OpenCLAddFuncOp(Backend *bn, std::string name) : Op(bn, std::move(name)) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + // 只获取一次 Program + const std::string kernel_path_str = get_kernel_path(__FILE__, "../kernel/add.cl"); + cl_program program = ocl_backend_->getProgram(kernel_path_str); + + cl_int err; + // --- 创建全部四个内核 --- + kernel_fp32_buffer_ = clCreateKernel(program, "add_float", &err); + check_cl_error(err, "clCreateKernel for add_float"); + + kernel_fp32_image_ = clCreateKernel(program, "add_float_image2d", &err); + check_cl_error(err, "clCreateKernel for add_float_image2d"); + + kernel_fp16_buffer_ = clCreateKernel(program, "add_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for add_fp16_vector"); + + kernel_fp16_image_ = clCreateKernel(program, "add_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for add_fp16_image2d"); + + // --- 创建 Sampler --- + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +// 替换您的析构函数 +OpenCLAddFuncOp::~OpenCLAddFuncOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLAddFuncOp::reshape(vector> inputs, vector> outputs) { + // 加法操作要求输入和输出的形状一致 + auto input0_shape = inputs[0]->shape(); + outputs[0]->reshape(input0_shape[0], input0_shape[1], input0_shape[2], input0_shape[3]); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLAddFuncOp::setUp(vector> inputs, vector> outputs) { + // 确保输入在设备上 + for(auto& input : inputs) { + input->to(MLLM_OPENCL); + } + auto output = outputs[0]; + + // 根据输入设置输出的数据类型 + output->setDtype(inputs[0]->dtype()); + + auto& out_mem = output->device_memory(); + + // **核心修改:直接决策为 Image 或 Buffer** + if (output->dimension() % 4 == 0) { + // 条件满足,直接为输出张量申请 Image2D 类型的内存 + out_mem.type = MEM_TYPE_IMAGE_2D; // **直接设为 Image2D** + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + // 条件不满足,回退到普通 Buffer + out_mem.type = MEM_TYPE_BUFFER; + } + + // alloc() 现在会根据 out_mem.type 直接创建出 Image 或 Buffer + output->alloc(); + return MLLM_NO_ERROR; +} + +// in OpenCLAddFuncOp.cpp + +ErrorCode OpenCLAddFuncOp::execute(vector> inputs, vector> outputs) { + // 1. 获取输入数据类型和输出张量 + auto input_dtype = inputs[0]->dtype(); + auto output = outputs[0]; + + // 2. 根据输出张量的内存类型,决定执行“Image优化路径”还是“普通Buffer路径” + // 这个类型是在 setUp 函数中根据维度是否为4的倍数决定的。 + if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { + // =================================================== + // ================ Image 优化路径 =================== + // =================================================== + + // a. 选择内核:根据数据类型选择FP32或FP16的Image内核 + cl_kernel kernel_to_use = nullptr; + if (input_dtype == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_image_; + } else if (input_dtype == MLLM_TYPE_F16) { + kernel_to_use = kernel_fp16_image_; + } else { + throw std::runtime_error("Unsupported data type for OpenCLAddFuncOp Image Path"); + } + + // b. 准备内核参数 + // - 输入张量(inputs): 它们是由默认的 .cl() 方法创建的Buffer,所以必须通过工具函数进行拷贝转换。 + // - 输出张量(output): 它在setUp中已经被直接创建为Image,所以可以直接获取其句柄。 + + // 创建一个临时存储vector,用于管理为“输入”转换而来的临时Image的生命周期 + std::vector temp_tensor_storage; + + cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); + cl_mem inB_mem = get_image_from_tensor(inputs[1], ocl_backend_, temp_tensor_storage); + + // 输出张量已经是Image,直接获取句柄,无需转换! + cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); + + // c. 设置内核参数 + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &inB_mem); + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); + + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + + // d. 设置工作维度并执行内核 + const size_t global_work_size[2] = { (size_t)width, (size_t)height }; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + + } else { + // =================================================== + // ============= 普通 Buffer 回退路径 ================ + // =================================================== + + // a. 选择内核:根据数据类型选择FP32或FP16的Buffer内核 + cl_kernel kernel_to_use = nullptr; + if (input_dtype == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_buffer_; + } else if (input_dtype == MLLM_TYPE_F16) { + kernel_to_use = kernel_fp16_buffer_; + } else { + throw std::runtime_error("Unsupported data type for OpenCLAddFuncOp Buffer Path"); + } + + // b. 准备内核参数 (所有张量都是Buffer,直接获取句柄) + cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); + cl_mem in1_buf = ocl_backend_->get_cl_mem(*inputs[1]); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &in1_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + + // c. 计算工作项数量 + size_t count = inputs[0]->count(); + // FP16的Buffer内核是向量化的,工作项数量是总元素数除以4 + if (input_dtype == MLLM_TYPE_F16) { + if (count % 4 != 0) { + throw std::runtime_error("For FP16 vector kernel, tensor count must be a multiple of 4."); + } + count /= 4; + } + + // d. 设置工作维度并执行内核 + const size_t global_work_size[1] = {count}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } + + return MLLM_NO_ERROR; +} +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLAddFuncOp.hpp b/src/backends/opencl/op/OpenCLAddFuncOp.hpp new file mode 100644 index 000000000..1173528ff --- /dev/null +++ b/src/backends/opencl/op/OpenCLAddFuncOp.hpp @@ -0,0 +1,42 @@ +#ifndef OPENCL_ADD_FUNC_OP_HPP +#define OPENCL_ADD_FUNC_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLAddFuncOp : public Op { +public: + OpenCLAddFuncOp(Backend *bn, std::string name); + ~OpenCLAddFuncOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + // cl_kernel buffer_kernel_ = nullptr; + // cl_kernel image_kernel_ = nullptr; // 新的 Image2D kernel + + cl_kernel kernel_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp16_buffer_ = nullptr; + cl_kernel kernel_fp16_image_ = nullptr; + + cl_sampler sampler_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +// OpenCLAddFuncOp 的创建器,用于工厂模式 +class OpenCLAddFuncOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // 对于简单的加法,我们可能不需要 op_param 和 threadCount + return new OpenCLAddFuncOp(bn, name); + } +}; + +} // namespace mllm + +#endif // OPENCL_ADD_FUNC_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/utils/OpenCLTools.hpp b/src/backends/opencl/utils/OpenCLTools.hpp new file mode 100644 index 000000000..cc04941b3 --- /dev/null +++ b/src/backends/opencl/utils/OpenCLTools.hpp @@ -0,0 +1,112 @@ +#ifndef OPENCL_TOOLS_HPP +#define OPENCL_TOOLS_HPP + +#include "Tensor.hpp" +#include "../OpenCLBackend.hpp" +#include + +namespace mllm { + + + +std::string inline get_kernel_path(const std::string& current_file, const std::string& relative_kernel_path) { + // 将源文件路径转换为 filesystem::path 对象 + std::filesystem::path source_path(current_file); + // 获取源文件所在的目录 + std::filesystem::path source_dir = source_path.parent_path(); + // 组合目录和相对内核路径,生成绝对路径 + std::filesystem::path kernel_path = source_dir / relative_kernel_path; + // 返回字符串格式的路径 + return kernel_path.string(); +} + + +/** + * @brief 从一个已在设备上的Tensor获取一个可用于内核计算的Image2D句柄。 + * 该函数是算子内部使用的核心工具。 + * + * 工作流程: + * 1. 检查输入Tensor是否已经是Image2D类型,如果是,直接返回其句柄。 + * 2. 如果输入Tensor是Buffer类型,则在设备上创建一个临时的Image2D对象。 + * 3. 执行一次设备内的Buffer-to-Image内存拷贝。 + * 4. 返回新创建的临时Image2D的句柄。 + * + * @param input_tensor 一个指向已在OpenCL设备上的Tensor的共享指针。 + * @param ocl_backend OpenCL后端实例,用于执行OpenCL命令。 + * @param temp_storage 一个Tensor的vector引用,用于存储函数内部创建的临时Image Tensor, + * 以确保其生命周期至少持续到内核执行完毕。调用者必须管理此vector的生命周期。 + * @return 一个可用于 clSetKernelArg 的 cl_mem 句柄(指向一个Image2D对象)。 + */ +static inline cl_mem get_image_from_tensor( + const std::shared_ptr& input_tensor, + OpenCLBackend* ocl_backend, + std::vector& temp_storage) +{ + auto& dev_mem = input_tensor->device_memory(); + + if (dev_mem.type == MEM_TYPE_IMAGE_2D) { + return ocl_backend->get_cl_mem(*input_tensor); + } + if (dev_mem.type != MEM_TYPE_BUFFER) { + throw std::runtime_error("Input must be a Buffer or Image type on device."); + } + + // ================== 零拷贝路径 ================== + // 条件:硬件支持扩展,且输入Buffer是带有正确行间距信息创建的。 + if (ocl_backend->is_image_from_buffer_supported() && dev_mem.image_row_pitch_in_bytes > 0) { + cl_image_format format = {CL_RGBA, CL_FLOAT}; + cl_image_desc desc = {}; + desc.image_type = CL_MEM_OBJECT_IMAGE2D; + desc.image_width = dev_mem.image_width; // 使用创建时保存的元数据 + desc.image_height = dev_mem.image_height; + desc.image_row_pitch = dev_mem.image_row_pitch_in_bytes; + desc.buffer = ocl_backend->get_cl_mem(*input_tensor); + + cl_int err; + cl_mem image_view = clCreateImage(ocl_backend->getContext(), CL_MEM_READ_ONLY, &format, &desc, nullptr, &err); + check_cl_error(err, "clCreateImage from buffer (Zero-Copy)"); + + Tensor wrapper_tensor(ocl_backend); + wrapper_tensor.device_memory().handle = image_view; + wrapper_tensor.device_memory().type = MEM_TYPE_IMAGE_2D; + temp_storage.push_back(std::move(wrapper_tensor)); + + return image_view; + } + + // ==================================================================================== + // 最终推荐的实现:直接、高效的内存拷贝路径 + // + // 这是在无法从源头控制Buffer创建方式时,最简单、最高效的解决方案。 + // ==================================================================================== + { + Tensor temp_image(input_tensor->batch(), input_tensor->head(), input_tensor->sequence(), input_tensor->dimension(), ocl_backend, false); + auto& img_mem = temp_image.device_memory(); + img_mem.type = MEM_TYPE_IMAGE_2D; + img_mem.image_width = input_tensor->dimension() / 4; + img_mem.image_height = input_tensor->batch() * input_tensor->head() * input_tensor->sequence(); + temp_image.alloc(); + + cl_mem src_buffer = ocl_backend->get_cl_mem(*input_tensor); + cl_mem dst_image = ocl_backend->get_cl_mem(temp_image); + + const size_t origin[3] = {0, 0, 0}; + const size_t region[3] = {img_mem.image_width, img_mem.image_height, 1}; + cl_int err = clEnqueueCopyBufferToImage( + ocl_backend->getQueue(), + src_buffer, dst_image, + 0, origin, region, + 0, nullptr, nullptr + ); + check_cl_error(err, "clEnqueueCopyBufferToImage (Fallback Copy)"); + + temp_storage.push_back(std::move(temp_image)); + return dst_image; + } +} + + + +} // namespace mllm + +#endif // OPENCL_TOOLS_HPP \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8984fec20..b6950eca5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -57,6 +57,10 @@ target_link_libraries( -fopenmp ${MLLM_XNNPACK_BACKEND_TEST_DEP_LIB} ) + +if(OPENCL) + target_link_libraries(MLLM_TEST mllm_opencl) +endif() # add_executable( # memoryPoolTest # ${PROJECT_SOURCE_DIR}/test/TestMemoryPoolManager.cpp From dab4d9d7ecf3541f18b88c66ca2c81a3dcec5318 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Thu, 26 Jun 2025 17:45:17 +0800 Subject: [PATCH 12/22] fix: add openclbackend --- src/backends/opencl/OpenCLBackend.cpp | 2 +- src/backends/opencl/kernel/{convert.cl => convert_fp.cl} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/backends/opencl/kernel/{convert.cl => convert_fp.cl} (100%) diff --git a/src/backends/opencl/OpenCLBackend.cpp b/src/backends/opencl/OpenCLBackend.cpp index 7550265d5..1cdf86213 100644 --- a/src/backends/opencl/OpenCLBackend.cpp +++ b/src/backends/opencl/OpenCLBackend.cpp @@ -94,7 +94,7 @@ OpenCLBackend::OpenCLBackend(const BackendConfig &config) : Backend() { this->image_pitch_alignment_bytes_ = 0; } // ======================================================================= - const std::string convert_kernel_path = get_kernel_path(__FILE__, "./kernel/convert.cl"); + const std::string convert_kernel_path = get_kernel_path(__FILE__, "./kernel/convert_fp.cl"); std::string build_options = ""; // 如果硬件支持FP16,我们通过宏定义告诉编译器去编译高性能版本的内核 diff --git a/src/backends/opencl/kernel/convert.cl b/src/backends/opencl/kernel/convert_fp.cl similarity index 100% rename from src/backends/opencl/kernel/convert.cl rename to src/backends/opencl/kernel/convert_fp.cl From de00d801a862e7e0a2288904b62e2f78b1d709f8 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Thu, 26 Jun 2025 14:54:52 +0000 Subject: [PATCH 13/22] feat: sage attention && ling-lite-moe --- .gitignore | 5 +- CMakeLists.txt | 63 +- README.md | 2 +- examples/CMakeLists.txt | 4 +- examples/demo_bailing_moe.cpp | 78 + examples/demo_bailing_moe_mbp.cpp | 81 + examples/demo_minicpm_moe_mbm.cpp | 1 + examples/demo_minicpm_moe_mbp.cpp | 1 + examples/demo_phonelm_npu.cpp | 29 +- examples/demo_qwen.cpp | 6 +- examples/demo_qwen2.5_npu.cpp | 18 +- examples/demo_qwen2.5_pipeline.cpp | 20 +- examples/demo_qwen2_vl.cpp | 5 +- examples/demo_qwen_npu.cpp | 32 +- examples/demo_qwen_pipeline.cpp | 20 +- examples/demo_showui.cpp | 5 +- examples/demo_showui_npu.cpp | 22 +- examples/demo_sparse_llama.cpp | 4 +- examples/demo_tinyllama.cpp | 2 + examples/mllm_benchmark.cpp | 2 +- include/DataType.hpp | 181 + include/OpDefined.hpp | 5 +- include/Types.hpp | 205 +- scripts/run_ling.sh | 21 + src/Backend.cpp | 4 +- src/Backend.hpp | 16 +- src/Layer.hpp | 39 +- src/Module.cpp | 1 + src/Module.hpp | 64 +- src/Parallel.hpp | 9 +- src/ParamLoader.cpp | 131 +- src/ParamLoader.hpp | 10 + src/Tensor.cpp | 168 +- src/Tensor.hpp | 269 +- src/TensorImpl.hpp | 67 +- src/backends/cpu/CMakeLists.txt | 65 +- src/backends/cpu/CPUBackend.cpp | 151 +- src/backends/cpu/CPUBackend.hpp | 16 +- .../cpu/compute/ActivationFunction.hpp | 2 +- src/backends/cpu/compute/Convolution.cpp | 1 + src/backends/cpu/compute/Convolution.hpp | 16 +- src/backends/cpu/compute/FlashAttention2.hpp | 1080 +- src/backends/cpu/compute/FlashAttention2H.hpp | 275 +- src/backends/cpu/compute/GemmKleidiai.cpp | 422 +- src/backends/cpu/compute/GemmKleidiai.hpp | 44 +- src/backends/cpu/compute/GemmPack.hpp | 43 - src/backends/cpu/compute/GemmQ2K.cpp | 348 + src/backends/cpu/compute/GemmQ2K.hpp | 45 + src/backends/cpu/compute/Matmul.cpp | 128 +- src/backends/cpu/compute/Matmul.hpp | 4 +- src/backends/cpu/compute/MatmulElastic.cpp | 10 +- src/backends/cpu/compute/MatmulElastic.hpp | 3 +- src/backends/cpu/compute/MatmulSparse.cpp | 4 +- src/backends/cpu/compute/MatmulSparse.hpp | 3 +- src/backends/cpu/compute/Pooling.cpp | 1 + src/backends/cpu/compute/Pooling.hpp | 3 +- src/backends/cpu/compute/SageAttention.hpp | 1610 + .../cpu/compute/SageAttentionKVQ8.hpp | 700 + src/backends/cpu/compute/SageAttentionPT.hpp | 834 + src/backends/cpu/compute/SageQuantize.hpp | 138 + src/backends/cpu/compute/Split.hpp | 234 +- src/backends/cpu/compute/VecDot.cpp | 4422 - src/backends/cpu/op/CPUCat.cpp | 2 +- src/backends/cpu/op/CPUCatFunc.hpp | 9 +- src/backends/cpu/op/CPUCausalMask.cpp | 26 +- src/backends/cpu/op/CPUEmbedding.cpp | 4 +- .../cpu/op/CPUFlashAttention2Func.hpp | 42 +- src/backends/cpu/op/CPUFlattenFunc.hpp | 4 +- src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp | 3 +- src/backends/cpu/op/CPUGELU.cpp | 22 +- src/backends/cpu/op/CPUGather.cpp | 16 +- src/backends/cpu/op/CPUHeadLinear.cpp | 5 +- src/backends/cpu/op/CPUIRoPE.cpp | 2 +- src/backends/cpu/op/CPUIndexPutFunc.hpp | 16 +- src/backends/cpu/op/CPUKVCache.cpp | 171 +- src/backends/cpu/op/CPUKVCache.hpp | 4 +- src/backends/cpu/op/CPUKVCacheNPU.cpp | 68 +- src/backends/cpu/op/CPUKVCacheNPU.hpp | 3 +- src/backends/cpu/op/CPUKVCacheSage.cpp | 129 + src/backends/cpu/op/CPUKVCacheSage.hpp | 60 + src/backends/cpu/op/CPULinear.cpp | 9 +- src/backends/cpu/op/CPULinearINT8Shadow.cpp | 5 +- src/backends/cpu/op/CPULinearInt8.cpp | 2 + src/backends/cpu/op/CPUMatmulFunc.hpp | 68 +- src/backends/cpu/op/CPUMergeOutput.cpp | 4 +- src/backends/cpu/op/CPUMultimodalRoPE.cpp | 2 +- .../cpu/op/CPUMultimodalRoPEPipeline.cpp | 7 +- src/backends/cpu/op/CPUNTKRoPE.cpp | 2 +- src/backends/cpu/op/CPUParameter.cpp | 32 +- src/backends/cpu/op/CPUParameter.hpp | 9 +- src/backends/cpu/op/CPUPredictor.cpp | 2 +- src/backends/cpu/op/CPUQuantize.cpp | 2 +- src/backends/cpu/op/CPUQuickGELU.cpp | 20 +- src/backends/cpu/op/CPURMSNorm.cpp | 75 +- src/backends/cpu/op/CPUReplace.cpp | 2 +- src/backends/cpu/op/CPURoPE.cpp | 2 +- src/backends/cpu/op/CPURoPETree.cpp | 2 +- src/backends/cpu/op/CPUSageAttentionFunc.hpp | 153 + src/backends/cpu/op/CPUScale.cpp | 2 +- ...erReduceFunc.hpp => CPUScatterAddFunc.hpp} | 14 +- src/backends/cpu/op/CPUSlidingWindowMask.cpp | 2 +- src/backends/cpu/op/CPUSoftMax.cpp | 3 +- src/backends/cpu/op/CPUSplitFunc.hpp | 49 +- src/backends/cpu/op/CPUSplitInput.cpp | 4 +- src/backends/cpu/op/CPUTranspose.cpp | 27 +- src/backends/cpu/op/CPUTransposeFunc.hpp | 46 +- src/backends/cpu/op/CPUView.cpp | 120 +- src/backends/cpu/op/CPUViewFunc.hpp | 10 +- src/backends/cpu/op/CPUVisionRoPEFunc.hpp | 8 +- .../ggml/ComputeUtils.hpp} | 71 +- .../ggml}/GemmLlamafile.cpp | 2 +- .../ggml}/GemmLlamafile.hpp | 2 - .../ggml}/GemmPack.cpp | 97 +- .../cpu/third_party/ggml/GemmPack.hpp | 44 + .../ggml}/Quantize.hpp | 102 +- .../cpu/third_party/ggml/QuantizeFP16.hpp | 147 + .../ggml}/QuantizeQ2.cpp | 53 + .../ggml}/QuantizeQ2.hpp | 3 + .../ggml}/QuantizeQ3.cpp | 0 .../ggml}/QuantizeQ3.hpp | 0 .../ggml}/QuantizeQ4.cpp | 0 .../ggml}/QuantizeQ4.hpp | 0 .../ggml}/QuantizeQ6.cpp | 0 .../ggml}/QuantizeQ6.hpp | 0 .../ggml}/QuantizeQ8.cpp | 0 .../ggml}/QuantizeQ8.hpp | 0 .../cpu/third_party/ggml/VecDotFP16.cpp | 64 + .../cpu/third_party/ggml/VecDotFP16.hpp | 33 + .../cpu/third_party/ggml/VecDotFP32.cpp | 177 + .../cpu/third_party/ggml/VecDotFP32.hpp | 76 + .../cpu/third_party/ggml/VecDotQ2.cpp | 1526 + .../cpu/third_party/ggml/VecDotQ2.hpp | 34 + .../cpu/third_party/ggml/VecDotQ3.cpp | 1282 + .../cpu/third_party/ggml/VecDotQ3.hpp | 31 + .../cpu/third_party/ggml/VecDotQ4.cpp | 702 + .../cpu/third_party/ggml/VecDotQ4.hpp | 82 + .../cpu/third_party/ggml/VecDotQ6.cpp | 682 + .../cpu/third_party/ggml/VecDotQ6.hpp | 31 + .../cpu/third_party/ggml/VecDotQ8.cpp | 230 + .../cpu/third_party/ggml/VecDotQ8.hpp | 33 + .../ggml}/VecDotType.cpp | 50 +- .../ggml}/VecDotType.hpp | 12 +- src/backends/qnn/QNNBackend.cpp | 4 +- src/backends/qnn/op/QNNLinearINT8.cpp | 12 +- src/backends/xnnpack/Ops/XpEmbedding.cpp | 4 +- src/backends/xnnpack/XnnpackBackend.cpp | 4 +- src/memory/MemoryPoolManager.hpp | 82 +- src/models/clip/processing_clip.hpp | 2 +- src/models/dclm/modeling_dclm.hpp | 6 +- src/models/fuyu/processing_fuyu.hpp | 4 +- src/models/gemma2/modeling_gemma2.hpp | 6 +- src/models/imagebind/processing_imagebind.hpp | 6 +- src/models/ling/configuration_bailing_moe.hpp | 67 + src/models/ling/mbp/modeling_bailing_moe.hpp | 492 + .../ling/mbp/settings_bailing_moe_mbp.hpp | 98 + src/models/ling/modeling_bailing_moe.hpp | 239 + src/models/ling/tokenizer_bailing.hpp | 194 + src/models/llama3/modeling_llama3.hpp | 4 +- .../mbm/modeling_minicpm_moe_mbm.hpp | 7 +- .../mbp/modeling_minicpm_moe_mbp.hpp | 9 +- .../minicpm_moe/modeling_minicpm_moe.hpp | 6 +- src/models/openelm/modeling_openelm.hpp | 4 +- src/models/phi3v/processing_phi3v.hpp | 6 +- src/models/phonelm/modeling_phonelm.hpp | 4 +- src/models/qwen/modeling_qwen_sd.hpp | 12 +- src/models/qwen2_vl/modeling_qwen2_vl.hpp | 10 +- src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp | 4 +- src/models/qwen2_vl/processing_qwen2_vl.hpp | 14 +- src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp | 4 +- .../qwen2_vl/vtp/processing_qwen2_vl.hpp | 10 +- src/models/stablelm/modeling_stablelm.hpp | 4 +- src/models/tinyllama/modeling_tinyllama.hpp | 13 +- .../transformer/modeling_transformer.hpp | 55 +- src/models/vit/processing_vit.hpp | 6 +- src/processor/AudioProcess.cpp | 2 +- src/processor/FuyuPreProcess.cpp | 4 +- src/quantizer/ParamWriter.cpp | 64 - src/quantizer/QuantWriter.cpp | 641 - src/quantizer/main_quantize.cpp | 71 - src/tokenizers/Tokenizer.hpp | 7 +- test/quantizer/WriterTest.cpp | 100 +- tools/convertor/converter.py | 3 +- tools/jni/LibHelper.cpp | 78 +- tools/quantizer/ParamWriter.cpp | 84 + {src => tools}/quantizer/ParamWriter.hpp | 35 +- tools/quantizer/QuantWriter.cpp | 310 + {src => tools}/quantizer/QuantWriter.hpp | 44 +- tools/quantizer/main_quantize.cpp | 67 + vocab/ling_merges.txt | 125824 +++++++++++++++ vocab/ling_vocab.mllm | Bin 0 -> 2772094 bytes 190 files changed, 139900 insertions(+), 7853 deletions(-) create mode 100644 examples/demo_bailing_moe.cpp create mode 100644 examples/demo_bailing_moe_mbp.cpp create mode 100644 include/DataType.hpp create mode 100755 scripts/run_ling.sh delete mode 100644 src/backends/cpu/compute/GemmPack.hpp create mode 100644 src/backends/cpu/compute/GemmQ2K.cpp create mode 100644 src/backends/cpu/compute/GemmQ2K.hpp create mode 100644 src/backends/cpu/compute/SageAttention.hpp create mode 100644 src/backends/cpu/compute/SageAttentionKVQ8.hpp create mode 100644 src/backends/cpu/compute/SageAttentionPT.hpp create mode 100644 src/backends/cpu/compute/SageQuantize.hpp delete mode 100644 src/backends/cpu/compute/VecDot.cpp create mode 100644 src/backends/cpu/op/CPUKVCacheSage.cpp create mode 100644 src/backends/cpu/op/CPUKVCacheSage.hpp create mode 100644 src/backends/cpu/op/CPUSageAttentionFunc.hpp rename src/backends/cpu/op/{CPUScatterReduceFunc.hpp => CPUScatterAddFunc.hpp} (84%) rename src/backends/cpu/{compute/VecDot.hpp => third_party/ggml/ComputeUtils.hpp} (85%) rename src/backends/cpu/{compute => third_party/ggml}/GemmLlamafile.cpp (99%) rename src/backends/cpu/{compute => third_party/ggml}/GemmLlamafile.hpp (92%) rename src/backends/cpu/{compute => third_party/ggml}/GemmPack.cpp (98%) create mode 100644 src/backends/cpu/third_party/ggml/GemmPack.hpp rename src/backends/cpu/{compute => third_party/ggml}/Quantize.hpp (94%) create mode 100644 src/backends/cpu/third_party/ggml/QuantizeFP16.hpp rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ2.cpp (92%) rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ2.hpp (92%) rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ3.cpp (100%) rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ3.hpp (100%) rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ4.cpp (100%) rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ4.hpp (100%) rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ6.cpp (100%) rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ6.hpp (100%) rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ8.cpp (100%) rename src/backends/cpu/{compute => third_party/ggml}/QuantizeQ8.hpp (100%) create mode 100644 src/backends/cpu/third_party/ggml/VecDotFP16.cpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotFP16.hpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotFP32.cpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotFP32.hpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ2.cpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ2.hpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ3.cpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ3.hpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ4.cpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ4.hpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ6.cpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ6.hpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ8.cpp create mode 100644 src/backends/cpu/third_party/ggml/VecDotQ8.hpp rename src/backends/cpu/{compute => third_party/ggml}/VecDotType.cpp (87%) rename src/backends/cpu/{compute => third_party/ggml}/VecDotType.hpp (86%) create mode 100644 src/models/ling/configuration_bailing_moe.hpp create mode 100644 src/models/ling/mbp/modeling_bailing_moe.hpp create mode 100644 src/models/ling/mbp/settings_bailing_moe_mbp.hpp create mode 100644 src/models/ling/modeling_bailing_moe.hpp create mode 100644 src/models/ling/tokenizer_bailing.hpp delete mode 100644 src/quantizer/ParamWriter.cpp delete mode 100644 src/quantizer/QuantWriter.cpp delete mode 100644 src/quantizer/main_quantize.cpp create mode 100644 tools/quantizer/ParamWriter.cpp rename {src => tools}/quantizer/ParamWriter.hpp (50%) create mode 100644 tools/quantizer/QuantWriter.cpp rename {src => tools}/quantizer/QuantWriter.hpp (67%) create mode 100644 tools/quantizer/main_quantize.cpp create mode 100644 vocab/ling_merges.txt create mode 100644 vocab/ling_vocab.mllm diff --git a/.gitignore b/.gitignore index 413bfd3a6..ddf80d2f0 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,8 @@ py-build-out/ mllm.egg-info/ src/backends/qnn/sdk/* + + + .DS_Store -src/models/ling/modeling_bailing_moe.hpp -src/models/ling/configuration_bailing_moe.hpp examples/test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ae09aff5a..af1ec0c68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,29 @@ project(mllm CXX C ASM) cmake_policy(SET CMP0074 NEW) set(CMAKE_CXX_STANDARD 17) + + +# 添加Address Sanitizer选项 +option(USE_ASAN "Enable AddressSanitizer for memory leak detection" OFF) + +if(USE_ASAN) + message(STATUS "Enabling AddressSanitizer") + # 确保包含调试符号 + if(NOT MSVC) + add_compile_options(-g) + endif() + + # 设置ASan编译选项 + if(MSVC) + add_compile_options(/fsanitize=address) + add_link_options(/fsanitize:address) + else() + add_compile_options(-fsanitize=address -fno-omit-frame-pointer) + add_link_options(-fsanitize=address) + endif() +endif() + + option(ARM "build on ARM" OFF) set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) @@ -214,15 +237,15 @@ file(GLOB_RECURSE SRC_TOKENIZERS # if compile to x86_64 if(QUANT) - include_directories(${PROJECT_SOURCE_DIR}/src/quantizer) + include_directories(${PROJECT_SOURCE_DIR}/tools/quantizer) file(GLOB_RECURSE MLLM_QUANT - ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/GemmPack.cpp - ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ8.cpp - ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ4.cpp - ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ6.cpp - ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ3.cpp - ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/QuantizeQ2.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/third_party/ggml/GemmPack.cpp ${PROJECT_SOURCE_DIR}/src/backends/cpu/compute/GemmKleidiai.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/third_party/ggml/QuantizeQ8.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/third_party/ggml/QuantizeQ4.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/third_party/ggml/QuantizeQ6.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/third_party/ggml/QuantizeQ3.cpp + ${PROJECT_SOURCE_DIR}/src/backends/cpu/third_party/ggml/QuantizeQ2.cpp ) if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64") @@ -232,8 +255,8 @@ if(QUANT) message(FATAL_ERROR "kleidiai library not found! Please place it in 'third_party/kleidiai'.") endif() # 添加所有源文件路径到 MLLM_QUANT - list(APPEND MLLM_QUANT - # QSI4 模块源文件 + list(APPEND MLLM_QUANT + # QSI4_C32P (to FP32) 模块源文件 ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod_asm.S ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm.c @@ -241,19 +264,27 @@ if(QUANT) ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.c - # FP16 模块源文件 + # [新增] QSI4_CXP (to FP16) 模块源文件 + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod_asm.S + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm_asm.S + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f16_neon.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4cxp_qs4cxs1s0.c + + # FP16 (f16*f16) 模块源文件 ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon.c - # FP32 模块源文件 + # FP32 (f32*f32) 模块源文件 ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla_asm.S ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon.c ) include_directories( - # # 添加所有kleidiai源文件路径到 MLLM_QUAN ${KLEIDIAI_SOURCE_DIR} ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_f16_f16p ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p @@ -261,12 +292,12 @@ if(QUANT) endif() file(GLOB_RECURSE MLLM_QUANTIZER - ${PROJECT_SOURCE_DIR}/src/quantizer/*.cpp - ${PROJECT_SOURCE_DIR}/src/quantizer/*.hpp) - list(REMOVE_ITEM MLLM_QUANTIZER ${PROJECT_SOURCE_DIR}/src/quantizer/main_quantize.cpp) + ${PROJECT_SOURCE_DIR}/tools/quantizer/*.cpp + ${PROJECT_SOURCE_DIR}/tools/quantizer/*.hpp) + list(REMOVE_ITEM MLLM_QUANTIZER ${PROJECT_SOURCE_DIR}/tools/quantizer/main_quantize.cpp) add_executable( quantize - ${PROJECT_SOURCE_DIR}/src/quantizer/main_quantize.cpp + ${PROJECT_SOURCE_DIR}/tools/quantizer/main_quantize.cpp ${MLLM_QUANT} ${MLLM_QUANTIZER} ${PROJECT_SOURCE_DIR}/src/ParamLoader.cpp diff --git a/README.md b/README.md index bead3c3ee..588ffb6ce 100644 --- a/README.md +++ b/README.md @@ -359,7 +359,7 @@ You can convert vocabulary to mllm vocabulary as followed. ```bash cd tools/convertor -python vocab.py --input_file=tokenizer.json --output_file=vocab.mllm --type=Unigram +python vocab.py --input_file=tokenizer.json --output_file=vocab.mllm --type=BPE ``` ### Quantize models diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b2c314126..db060177b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -28,7 +28,7 @@ macro(func_set_compile_opts_defs target) endmacro() macro(func_link_libs target) - target_link_libraries(${target} PUBLIC mllm_cpu fmt::fmt-header-only) + target_link_libraries(${target} PUBLIC mllm_cpu fmt) if (MLLM_OPENMP) if (ARM AND NOT (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING)) # 非Mac的ARM,静态链接OpenMP @@ -105,6 +105,8 @@ func_llm_add_executable(demo_llama3) func_llm_add_executable(demo_minicpm_moe_mbm) func_llm_add_executable(demo_qwen_sd) func_llm_add_executable(demo_minicpm_moe_mbp) +func_llm_add_executable(demo_bailing_moe) +func_llm_add_executable(demo_bailing_moe_mbp) func_llm_add_executable(test) func_vlm_add_executable(demo_llava) diff --git a/examples/demo_bailing_moe.cpp b/examples/demo_bailing_moe.cpp new file mode 100644 index 000000000..9fd1bee02 --- /dev/null +++ b/examples/demo_bailing_moe.cpp @@ -0,0 +1,78 @@ +/** + * @file demo_bailing_moe.cpp + * @brief A demo for using Bailing MoE model. + * @author Rongjie Yi + * @date 2025-07-01 + * + */ +#include "cmdline.h" +#include "models/ling/configuration_bailing_moe.hpp" +#include "models/ling/modeling_bailing_moe.hpp" +#include "models/ling/tokenizer_bailing.hpp" + +using namespace mllm; + +int main(int argc, char **argv) { + std::iostream::sync_with_stdio(false); + + cmdline::parser cmdParser; + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/ling_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/ling_merges.txt"); +#ifdef ARM + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-kai_q4_0.mllm"); +#else + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-q4_0.mllm"); +#endif + cmdParser.add("limits", 'l', "max KV cache size", false, 500); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + int tokens_limit = cmdParser.get("limits"); + CPUBackend::cpu_threads = cmdParser.get("thread"); + + auto tokenizer = BaiLingTokenizer(vocab_path, merge_path); + BailingMoeConfig config(tokens_limit); + // config.attn_implementation = "sage_attention"; + auto model = BailingMoeForCausalLM(config); + model.load(model_path); + + vector in_strs = { + "怎样计算1+2+...+100的和?", + "Who are you?", + "Give me a short introduction to large language model.", + "背诵天下第一骈文", + "夕焼けとコオロギが一斉に飛び、秋水は共に天一色になる。上面句子翻译成中文", + "你写一首七言绝句。", + "背诵一下水调歌头。", + "清晨的阳光透过薄纱窗帘,懒洋洋地洒在木地板上,空气中飘散着咖啡豆研磨后特有的醇厚香气。窗外传来几声清脆的鸟鸣,伴随着远处隐约的车流声,构成这座都市尚未完全苏醒的独特交响。书桌上摊开着昨夜未读完的书,书页边缘已微微卷起。厨房里,水壶正发出细密的声响,预示着一天的热饮即将就绪。昨日的计划表贴在冰箱门上,几个重要的待办事项用红笔醒目地圈出。公园里晨练的人们身影绰绰,有节奏的脚步声和太极音乐交织。一只橘猫敏捷地跃上围墙,在晨光中伸展着腰肢,神态悠闲得仿佛它是这片领地的主人。街角的面包店刚拉开铁门,新鲜出炉的面包香气迫不及待地涌向街头。公交站台上,等待的乘客低头刷着手机屏幕,神情各异。云朵缓慢地在湛蓝的天空中移动,时间似乎被拉长了片刻。生活就在这些微小的、平凡的细节里徐徐展开,既不惊天动地,却也充满细碎的温暖和实在的步履。新的一天开始了。\n​​请在以上文本中找出描述“气味”的句子(复制出来),然后判断叙述者对“橘猫”的态度是正面还是负面,最后请用三个成语概括文中描绘的早晨氛围。", + "项羽已杀卿子冠军,威震楚国,名闻诸侯。乃遣当阳君、蒲将军将卒二万渡河,救巨鹿。战少利,陈馀复请兵。项羽乃悉引兵渡河,皆沉船,破釜甑,烧庐舍,持三日粮,以示士卒必死,无一还心。于是至则围王离,与秦军遇,九战,绝其甬道,大破之,杀苏角,虏王离。涉间不降楚,自烧杀。当是时,楚兵冠诸侯。诸侯军救巨鹿下者十余壁,莫敢纵兵。及楚击秦,诸将皆从壁上观。楚战士无不一以当十,楚兵呼声动天,诸侯军无不人人惴恐。于是已破秦军,项羽召见诸侯将,入辕门,无不膝行而前,莫敢仰视。项羽由是始为诸侯上将军,诸侯皆属焉。 问题:结合项羽在巨鹿之战中的战术决策与心理威慑手段,分析其如何实现『楚战士无不一以当十』的战斗效应,并论述这种军事心理学实践对诸侯将领『膝行而前,莫敢仰视』行为模式的生成机制。", + }; + for (int i = 0; i < in_strs.size(); ++i) { + auto input_str = tokenizer.apply_chat_template(in_strs[i]); + auto input_tensor = tokenizer.tokenize(input_str); + // std::cout << "[tks]" << input_tensor.sequence() << " tokens" << std::endl; + std::cout << "[Q] " << in_strs[i] << std::endl; + std::cout << "[A] " << std::flush; + + LlmTextGeneratorOpts opt{ + .max_new_tokens = static_cast(tokens_limit - input_tensor.sequence()), + .do_sample = false, + .temperature = 0.3F, + .top_k = 50, + .top_p = 0.F, + }; + model.generate(input_tensor, opt, [&](unsigned int out_token) -> bool { + auto out_string = tokenizer.detokenize({out_token}); + auto [not_end, output_string] = tokenizer.postprocess(out_string); + if (!not_end) { return false; } + std::cout << output_string << std::flush; + return true; + }); + std::cout << "\n"; + model.clear_kvcache(); + model.profiling(); + } +} diff --git a/examples/demo_bailing_moe_mbp.cpp b/examples/demo_bailing_moe_mbp.cpp new file mode 100644 index 000000000..9a6b383db --- /dev/null +++ b/examples/demo_bailing_moe_mbp.cpp @@ -0,0 +1,81 @@ +/** + * @file demo_bailing_moe.cpp + * @brief A demo for using Bailing MoE model. + * @author Rongjie Yi + * @date 2025-07-01 + * + */ +#include "Module.hpp" +#include "cmdline.h" +#include "models/ling/configuration_bailing_moe.hpp" +#include "models/ling/mbp/modeling_bailing_moe.hpp" +#include "models/ling/tokenizer_bailing.hpp" +#include + +using namespace mllm; + +int main(int argc, char **argv) { + std::iostream::sync_with_stdio(false); + Module::alloc_mmap = false; + + cmdline::parser cmdParser; + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/ling_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/ling_merges.txt"); +#ifdef ARM + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-kai_q4_0.mllm"); +#else + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-q4_0.mllm"); +#endif + cmdParser.add("limits", 'l', "max KV cache size", false, 500); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + int tokens_limit = cmdParser.get("limits"); + CPUBackend::cpu_threads = cmdParser.get("thread"); + + auto tokenizer = BaiLingTokenizer(vocab_path, merge_path); + BailingMoeConfig config(tokens_limit); + auto model = BailingMoeForCausalLM(config); + model.load(model_path); + + vector in_strs = { + "怎样计算1+2+...+100的和?", + "Who are you?", + "Give me a short introduction to large language model.", + "夕焼けとコオロギが一斉に飛び、秋水は共に天一色になる。上面句子翻译成中文", + "你写一首七言绝句。", + "背诵一下水调歌头。", + "清晨的阳光透过薄纱窗帘,懒洋洋地洒在木地板上,空气中飘散着咖啡豆研磨后特有的醇厚香气。窗外传来几声清脆的鸟鸣,伴随着远处隐约的车流声,构成这座都市尚未完全苏醒的独特交响。书桌上摊开着昨夜未读完的书,书页边缘已微微卷起。厨房里,水壶正发出细密的声响,预示着一天的热饮即将就绪。昨日的计划表贴在冰箱门上,几个重要的待办事项用红笔醒目地圈出。公园里晨练的人们身影绰绰,有节奏的脚步声和太极音乐交织。一只橘猫敏捷地跃上围墙,在晨光中伸展着腰肢,神态悠闲得仿佛它是这片领地的主人。街角的面包店刚拉开铁门,新鲜出炉的面包香气迫不及待地涌向街头。公交站台上,等待的乘客低头刷着手机屏幕,神情各异。云朵缓慢地在湛蓝的天空中移动,时间似乎被拉长了片刻。生活就在这些微小的、平凡的细节里徐徐展开,既不惊天动地,却也充满细碎的温暖和实在的步履。新的一天开始了。\n​​请在以上文本中找出描述“气味”的句子(复制出来),然后判断叙述者对“橘猫”的态度是正面还是负面,最后请用三个成语概括文中描绘的早晨氛围。", + "项羽已杀卿子冠军,威震楚国,名闻诸侯。乃遣当阳君、蒲将军将卒二万渡河,救巨鹿。战少利,陈馀复请兵。项羽乃悉引兵渡河,皆沉船,破釜甑,烧庐舍,持三日粮,以示士卒必死,无一还心。于是至则围王离,与秦军遇,九战,绝其甬道,大破之,杀苏角,虏王离。涉间不降楚,自烧杀。当是时,楚兵冠诸侯。诸侯军救巨鹿下者十余壁,莫敢纵兵。及楚击秦,诸将皆从壁上观。楚战士无不一以当十,楚兵呼声动天,诸侯军无不人人惴恐。于是已破秦军,项羽召见诸侯将,入辕门,无不膝行而前,莫敢仰视。项羽由是始为诸侯上将军,诸侯皆属焉。 问题:结合项羽在巨鹿之战中的战术决策与心理威慑手段,分析其如何实现『楚战士无不一以当十』的战斗效应,并论述这种军事心理学实践对诸侯将领『膝行而前,莫敢仰视』行为模式的生成机制。", + }; + + minicpmmoe_mbp_init(config.num_hidden_layers, config.num_experts); + for (int i = 0; i < in_strs.size(); ++i) { + auto input_str = tokenizer.apply_chat_template(in_strs[i]); + auto input_tensor = tokenizer.tokenize(input_str); + std::cout << "[Q] " << in_strs[i] << std::endl; + std::cout << "[A] " << std::flush; + + LlmTextGeneratorOpts opt{ + .max_new_tokens = static_cast(tokens_limit - input_tensor.sequence()), + .do_sample = false, + .temperature = 0.3F, + .top_k = 50, + .top_p = 0.F, + }; + model.generate(input_tensor, opt, [&](unsigned int out_token) -> bool { + auto out_string = tokenizer.detokenize({out_token}); + auto [not_end, output_string] = tokenizer.postprocess(out_string); + if (!not_end) { return false; } + std::cout << output_string << std::flush; + return true; + }); + std::cout << "\n"; + model.clear_kvcache(); + model.profiling(); + // prinMBPtimes(); + } +} diff --git a/examples/demo_minicpm_moe_mbm.cpp b/examples/demo_minicpm_moe_mbm.cpp index 6cd876429..44773c5f2 100644 --- a/examples/demo_minicpm_moe_mbm.cpp +++ b/examples/demo_minicpm_moe_mbm.cpp @@ -8,6 +8,7 @@ using namespace mllm; int main(int argc, char **argv) { + Module::alloc_mmap = false; cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/minicpm_vocab.mllm"); cmdParser.add("model", 'm', "specify mllm model path", false, "../models/minicpm-moe-8x2b-q4_k.mllm"); diff --git a/examples/demo_minicpm_moe_mbp.cpp b/examples/demo_minicpm_moe_mbp.cpp index be85a8d8c..e2da3876c 100644 --- a/examples/demo_minicpm_moe_mbp.cpp +++ b/examples/demo_minicpm_moe_mbp.cpp @@ -8,6 +8,7 @@ using namespace mllm; int main(int argc, char **argv) { + Module::alloc_mmap = false; cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/minicpm_vocab.mllm"); cmdParser.add("model", 'm', "specify mllm model path", false, "../models/minicpm-moe-8x2b-q4_k.mllm"); diff --git a/examples/demo_phonelm_npu.cpp b/examples/demo_phonelm_npu.cpp index 608ffab53..13d721bf1 100644 --- a/examples/demo_phonelm_npu.cpp +++ b/examples/demo_phonelm_npu.cpp @@ -57,9 +57,9 @@ int main(int argc, char **argv) { return true; }); Module::isFirstChunk = false; - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); // turn on the multi-chunk prefilling Module::isMultiChunkPrefilling = true; @@ -69,7 +69,6 @@ int main(int argc, char **argv) { static_cast(Backend::global_backends[MLLM_QNN])->saveQNNContext(); } - vector in_strs = { "Give me a short introduction to large language model.", "What is the Beijing University of Posts and Telecommunications.", @@ -90,9 +89,9 @@ int main(int argc, char **argv) { std::cout << "[A] " << std::flush; // set total seq length for HeadLinear execute, which can not get the real seq length from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setTotalSequenceLength(real_seq_length); // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + static_cast(Backend::global_backends[MLLM_CPU].get())->setChunkSize(chunk_size); // tensor vectors to save the chunked tensors of the QNN prefilling input vector chunked_tensors(chunk_num); @@ -105,7 +104,7 @@ int main(int argc, char **argv) { }; for (int chunk_id = 0; chunk_id < chunk_num; ++chunk_id) { - chunked_tensors[chunk_id].setBackend(Backend::global_backends[MLLM_CPU]); + chunked_tensors[chunk_id].setBackend(Backend::global_backends[MLLM_CPU].get()); chunked_tensors[chunk_id].setTtype(INPUT_TENSOR); chunked_tensors[chunk_id].reshape(1, 1, chunk_size, 1); chunked_tensors[chunk_id].setName("input-chunk-" + to_string(chunk_id)); @@ -115,7 +114,7 @@ int main(int argc, char **argv) { // if (i != 0 && !isSwitched && chunk_id == 0) { if (!isSwitched && chunk_id == 0) { // turn off switching at the first chunk of following inputs - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } auto out_string = tokenizer.detokenize({out_token}); @@ -130,9 +129,9 @@ int main(int argc, char **argv) { } // turn on switching, set sequence length and execution type - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); LlmTextGeneratorOpts decoding_opt{ .max_new_tokens = 100, @@ -145,7 +144,7 @@ int main(int argc, char **argv) { isSwitched = false; decoding_model.generate(chunked_tensors.back(), decoding_opt, [&](unsigned int out_token) -> bool { if (!isSwitched) { // turn off switching - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } auto out_string = tokenizer.detokenize({out_token}); @@ -156,9 +155,9 @@ int main(int argc, char **argv) { }); // turn on switching, set sequence length and execution type - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); std::cout << "\n"; } } \ No newline at end of file diff --git a/examples/demo_qwen.cpp b/examples/demo_qwen.cpp index 5f7f171a1..a1e61ab49 100644 --- a/examples/demo_qwen.cpp +++ b/examples/demo_qwen.cpp @@ -20,8 +20,11 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2.5_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2.5_merges.txt"); +#ifdef ARM + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-kai_q4_0.mllm"); +#else cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"); - // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-kai_q4_0.mllm"); +#endif cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B | 3B |]", false, "1.5B"); cmdParser.add("limits", 'l', "max KV cache size", false, 400); cmdParser.add("thread", 't', "num of threads", false, 4); @@ -36,6 +39,7 @@ int main(int argc, char **argv) { auto tokenizer = QWenTokenizer(vocab_path, merge_path); QWenConfig config(tokens_limit, model_billion, RoPEType::HFHUBROPE); + // config.attn_implementation = "sage_attention"; // 使用Sage Attention实现 auto model = QWenForCausalLM(config); model.load(model_path); diff --git a/examples/demo_qwen2.5_npu.cpp b/examples/demo_qwen2.5_npu.cpp index b86bef3b9..42e5bddc3 100644 --- a/examples/demo_qwen2.5_npu.cpp +++ b/examples/demo_qwen2.5_npu.cpp @@ -48,7 +48,7 @@ int main(int argc, char **argv) { std::cout << "[A] " << std::flush; // set total seq length for HeadLinear execute, which can not get the real seq length from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setTotalSequenceLength(real_seq_length); LlmTextGeneratorOpts opt{ .max_new_tokens = 1, @@ -65,9 +65,9 @@ int main(int argc, char **argv) { return true; }); - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); LlmTextGeneratorOpts decoding_opt{ .max_new_tokens = 50, @@ -81,7 +81,7 @@ int main(int argc, char **argv) { decoding_model.generate(input_tensor, decoding_opt, [&](unsigned int out_token) -> bool { // call only once of switchDecodeTag if (!isSwitched) { - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } @@ -96,13 +96,13 @@ int main(int argc, char **argv) { }); // turn on switching, set sequence length and execution type - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); std::cout << "\n"; if (!std::filesystem::exists("qnn_context.bin")) { - static_cast(Backend::global_backends[MLLM_QNN])->saveQNNContext(); + static_cast(Backend::global_backends[MLLM_QNN].get())->saveQNNContext(); } } } diff --git a/examples/demo_qwen2.5_pipeline.cpp b/examples/demo_qwen2.5_pipeline.cpp index 5bc99cfcc..d0a286ded 100644 --- a/examples/demo_qwen2.5_pipeline.cpp +++ b/examples/demo_qwen2.5_pipeline.cpp @@ -53,9 +53,9 @@ int main(int argc, char **argv) { auto [real_seq_length, input_tensor] = tokenizer.tokenizePaddingByChunk(input_str, chunk_size, config.vocab_size); // set total seq length for HeadLinear execute, which can not get the real seq length from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setTotalSequenceLength(real_seq_length); // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + static_cast(Backend::global_backends[MLLM_CPU].get())->setChunkSize(chunk_size); std::cout << "[Q] " << in_strs[i] << std::endl; std::cout << "[A] " << std::flush; @@ -78,9 +78,9 @@ int main(int argc, char **argv) { Module::isMultiChunkPrefilling = true; Module::isFirstChunk = false; - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); LlmTextGeneratorOpts decoding_opt{ .max_new_tokens = 100, @@ -93,7 +93,7 @@ int main(int argc, char **argv) { isSwitched = false; Tensor decoding_input; - decoding_input.setBackend(Backend::global_backends[MLLM_CPU]); + decoding_input.setBackend(Backend::global_backends[MLLM_CPU].get()); decoding_input.setTtype(INPUT_TENSOR); decoding_input.reshape(1, 1, 1, 1); decoding_input.setName("input0"); @@ -102,7 +102,7 @@ int main(int argc, char **argv) { decoding_model.generate(decoding_input, decoding_opt, [&](unsigned int out_token) -> bool { // call only once of switchDecodeTag if (!isSwitched) { - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } auto out_string = tokenizer.detokenize({out_token}); @@ -116,9 +116,9 @@ int main(int argc, char **argv) { }); // turn on switching, set sequence length and execution type - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); std::cout << "\n"; } } \ No newline at end of file diff --git a/examples/demo_qwen2_vl.cpp b/examples/demo_qwen2_vl.cpp index f4558f5bb..8a238e887 100644 --- a/examples/demo_qwen2_vl.cpp +++ b/examples/demo_qwen2_vl.cpp @@ -11,8 +11,11 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2vl_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2vl_merges.txt"); +#ifdef ARM + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-kai_q4_0.mllm"); +#else cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); - // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-kai_q4_0.mllm"); +#endif cmdParser.add("billion", 'b', "[2B | 7B |]", false, "2B"); cmdParser.add("limits", 'l', "max KV cache size", false, 800); cmdParser.add("thread", 't', "num of threads", false, 4); diff --git a/examples/demo_qwen_npu.cpp b/examples/demo_qwen_npu.cpp index 4ac0ede23..fab850790 100644 --- a/examples/demo_qwen_npu.cpp +++ b/examples/demo_qwen_npu.cpp @@ -54,9 +54,9 @@ int main(int argc, char **argv) { return true; }); Module::isFirstChunk = false; - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); // turn on the multi-chunk prefilling Module::isMultiChunkPrefilling = true; // warmup END @@ -81,8 +81,8 @@ int main(int argc, char **argv) { std::cout << "[A] " << std::flush; // set total seq length for HeadLinear execute, which can not get the real seq length from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + static_cast(Backend::global_backends[MLLM_CPU].get())->setTotalSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setChunkSize(chunk_size); LlmTextGeneratorOpts opt{ .max_new_tokens = 1, @@ -96,16 +96,16 @@ int main(int argc, char **argv) { bool isSwitched = false; vector chunked_tensors(chunk_num); for (int chunk_id = 0; chunk_id < chunk_num; ++chunk_id) { - chunked_tensors[chunk_id].setBackend(Backend::global_backends[MLLM_CPU]); + chunked_tensors[chunk_id].setBackend(Backend::global_backends[MLLM_CPU].get()); chunked_tensors[chunk_id].setTtype(INPUT_TENSOR); chunked_tensors[chunk_id].reshape(1, 1, chunk_size, 1); chunked_tensors[chunk_id].setName("input-chunk-" + to_string(chunk_id)); - chunked_tensors[chunk_id].shallowCopyFrom(&input_tensor, false, {0, 0, chunk_id * chunk_size, 0}); + chunked_tensors[chunk_id].shallowCopyFrom(input_tensor, false, {0, 0, chunk_id * chunk_size, 0}); model.generate(chunked_tensors[chunk_id], opt, [&](unsigned int out_token) -> bool { - if (!isSwitched && chunk_id == 0 && static_cast(Backend::global_backends[MLLM_CPU])->isStageSwitching()) { + if (!isSwitched && chunk_id == 0 && static_cast(Backend::global_backends[MLLM_CPU].get())->isStageSwitching()) { // turn off switching at the first chunk of following inputs - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } auto out_string = tokenizer.detokenize({out_token}); @@ -119,9 +119,9 @@ int main(int argc, char **argv) { Module::isFirstChunk = false; } - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); exit(0); @@ -137,7 +137,7 @@ int main(int argc, char **argv) { decoding_model.generate(chunked_tensors.back(), decoding_opt, [&](unsigned int out_token) -> bool { // call only once of switchDecodeTag if (!isSwitched) { - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } auto out_string = tokenizer.detokenize({out_token}); @@ -151,9 +151,9 @@ int main(int argc, char **argv) { }); // turn on switching, set sequence length and execution type - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); std::cout << "\n"; } } \ No newline at end of file diff --git a/examples/demo_qwen_pipeline.cpp b/examples/demo_qwen_pipeline.cpp index 1d632d7df..af3816a43 100644 --- a/examples/demo_qwen_pipeline.cpp +++ b/examples/demo_qwen_pipeline.cpp @@ -53,9 +53,9 @@ int main(int argc, char **argv) { auto [real_seq_length, input_tensor] = tokenizer.tokenizePaddingByChunk(input_str, chunk_size, config.vocab_size); // set total seq length for HeadLinear execute, which can not get the real seq length from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setTotalSequenceLength(real_seq_length); // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + static_cast(Backend::global_backends[MLLM_CPU].get())->setChunkSize(chunk_size); std::cout << "[Q] " << in_strs[i] << std::endl; std::cout << "[A] " << std::flush; @@ -78,9 +78,9 @@ int main(int argc, char **argv) { Module::isMultiChunkPrefilling = true; Module::isFirstChunk = false; - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); LlmTextGeneratorOpts decoding_opt{ .max_new_tokens = 100, @@ -93,7 +93,7 @@ int main(int argc, char **argv) { isSwitched = false; Tensor decoding_input; - decoding_input.setBackend(Backend::global_backends[MLLM_CPU]); + decoding_input.setBackend(Backend::global_backends[MLLM_CPU].get()); decoding_input.setTtype(INPUT_TENSOR); decoding_input.reshape(1, 1, 1, 1); decoding_input.setName("input0"); @@ -102,7 +102,7 @@ int main(int argc, char **argv) { decoding_model.generate(decoding_input, decoding_opt, [&](unsigned int out_token) -> bool { // call only once of switchDecodeTag if (!isSwitched) { - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } auto out_string = tokenizer.detokenize({out_token}); @@ -116,9 +116,9 @@ int main(int argc, char **argv) { }); // turn on switching, set sequence length and execution type - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); std::cout << "\n"; } } \ No newline at end of file diff --git a/examples/demo_showui.cpp b/examples/demo_showui.cpp index aa099e268..c529bd72c 100644 --- a/examples/demo_showui.cpp +++ b/examples/demo_showui.cpp @@ -12,8 +12,11 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/showui_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/showui_merges.txt"); +#ifdef ARM + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/showui-2b-kai_q4_0.mllm"); +#else cmdParser.add("model", 'm', "specify mllm model path", false, "../models/showui-2b-q4_k.mllm"); - // cmdParser.add("model", 'm', "specify mllm model path", false, "../models/showui-2b-kai_q4_0.mllm"); +#endif cmdParser.add("limits", 'l', "max KV cache size", false, 2000); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); diff --git a/examples/demo_showui_npu.cpp b/examples/demo_showui_npu.cpp index 15e7723b5..d54943705 100644 --- a/examples/demo_showui_npu.cpp +++ b/examples/demo_showui_npu.cpp @@ -82,14 +82,14 @@ int main(int argc, char **argv) { std::cout << "warm up " << warm_end - warm_start << " ms" << std::endl; Module::isFirstChunk = false; - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); // set total seq length for HeadLinear execute, which can not get the real seq length from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setTotalSequenceLength(real_seq_length); // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + static_cast(Backend::global_backends[MLLM_CPU].get())->setChunkSize(chunk_size); for (auto &t : input_tensors) { t.setTtype(INPUT_TENSOR); @@ -132,7 +132,7 @@ int main(int argc, char **argv) { auto result = prefill_body(prefill_input); if (i == 0) { // turn off switching to avoid RoPE h_cnt_ reset to curSequenceLength in next chunk - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); } if (i == 1) { @@ -149,9 +149,9 @@ int main(int argc, char **argv) { chatPostProcessing(out_token, input_tensors[0], {&input_tensors[1], &input_tensors[2]}); - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); // 3. CPU LLM Decoding for (auto &t : input_tensors) { // set to INPUT_TENSOR to let decoding module update act @@ -172,13 +172,13 @@ int main(int argc, char **argv) { std::cout << output_string << std::flush; chatPostProcessing(out_token, input_tensors[0], {&input_tensors[1], &input_tensors[2]}); - if (step == 0) static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + if (step == 0) static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); } std::cout << std::endl; if (!std::filesystem::exists("qnn_context.bin")) { - static_cast(Backend::global_backends[MLLM_QNN])->saveQNNContext(); + static_cast(Backend::global_backends[MLLM_QNN].get())->saveQNNContext(); } return 0; diff --git a/examples/demo_sparse_llama.cpp b/examples/demo_sparse_llama.cpp index 74b6a4045..7af99032b 100644 --- a/examples/demo_sparse_llama.cpp +++ b/examples/demo_sparse_llama.cpp @@ -30,9 +30,7 @@ int main(int argc, char **argv) { LLaMAConfig config(tokens_limit, "7B", HFHUBROPE); auto is_down_sparse = true; auto model = SparseLLaMAModel(config, is_down_sparse); - // MultiFileParamLoader param_loader({model_path, predictor_path, "../ReLULlama_q4_k.mllm"}); - MultiFileParamLoader param_loader({model_path, "../models/ReLULlama_q4_k.mllm"}); - model.load(param_loader); + model.load_multifile({model_path, "../models/ReLULlama_q4_k.mllm"}); vector in_strs = { " Hello, who are you?", diff --git a/examples/demo_tinyllama.cpp b/examples/demo_tinyllama.cpp index c2984685b..1af994819 100644 --- a/examples/demo_tinyllama.cpp +++ b/examples/demo_tinyllama.cpp @@ -29,6 +29,7 @@ int main(int argc, char **argv) { tokenizer.set_chat_template(system_prompt_start, system_prompt_end); TinyLLaMAConfig config(tokens_limit, "1.5B", HFHUBROPE); + // config.attn_implementation = "sage_attention"; auto model = TinyLLaMAModel(config); model.load(model_path); @@ -51,6 +52,7 @@ int main(int argc, char **argv) { } printf("\n"); model.profiling(); + model.clear_kvcache(); } return 0; diff --git a/examples/mllm_benchmark.cpp b/examples/mllm_benchmark.cpp index 64939c2ff..e2e81781d 100644 --- a/examples/mllm_benchmark.cpp +++ b/examples/mllm_benchmark.cpp @@ -39,7 +39,7 @@ using namespace mllm; Tensor tokens2Input(int tokens_size, string name = "input", BackendType type = MLLM_CPU) { - Tensor tensor1(1, 1, tokens_size, 1, Backend::global_backends[type], true); + Tensor tensor1(1, 1, tokens_size, 1, Backend::global_backends[type].get(), true); tensor1.setName(name); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); diff --git a/include/DataType.hpp b/include/DataType.hpp new file mode 100644 index 000000000..063f5dd7a --- /dev/null +++ b/include/DataType.hpp @@ -0,0 +1,181 @@ +#pragma once + +#include + +/** + * fp 16 type + */ +#if defined(__ARM_NEON) && !defined(_MSC_VER) +typedef __fp16 mllm_fp16_t; +#else +typedef uint16_t mllm_fp16_t; +#endif + +/** + * k quantization + */ + +// #define MLLM_QKK_64 +#ifdef MLLM_QKK_64 +#define QK_K 64 +#define K_SCALE_SIZE 4 +#else +#define QK_K 256 +#define K_SCALE_SIZE 12 +#endif + +/** + * 2-bits quantization + */ +#define QK2_0 32 +#pragma pack(1) +typedef struct { + mllm_fp16_t d; // delta + uint8_t qs[QK2_0 / 4]; // 2-bit quants +} block_q2_0; +#pragma pack() +static_assert(sizeof(block_q2_0) == sizeof(mllm_fp16_t) + QK2_0 / 4, "wrong q2_0 block size/padding"); + +#pragma pack(1) +typedef struct { + uint8_t scales[QK_K / 16]; // scales and mins, quantized with 4 bits + uint8_t qs[QK_K / 4]; // quants + mllm_fp16_t d; // super-block scale for quantized scales + mllm_fp16_t dmin; // super-block scale for quantized mins +} block_q2_K; +#pragma pack() +static_assert(sizeof(block_q2_K) == 2 * sizeof(mllm_fp16_t) + QK_K / 16 + QK_K / 4, "wrong q2_K block size/padding"); + +#pragma pack(1) +typedef struct { + mllm_fp16_t d; + uint16_t qs[QK_K / 8]; +} block_iq2_xxs; +#pragma pack() +static_assert(sizeof(block_iq2_xxs) == sizeof(mllm_fp16_t) + QK_K / 8 * sizeof(uint16_t), "wrong iq2_xxs block size/padding"); + +/** + * 3-bits quantization + */ +#pragma pack(1) +typedef struct { + uint8_t hmask[QK_K / 8]; // quants - high bit + uint8_t qs[QK_K / 4]; // quants - low 2 bits + uint8_t scales[12]; // scales, quantized with 6 bits + mllm_fp16_t d; // super-block scale +} block_q3_K; +#pragma pack() +static_assert(sizeof(block_q3_K) == sizeof(mllm_fp16_t) + QK_K / 4 + QK_K / 8 + 12, "wrong q3_K block size/padding"); + +/** + * 4-bits quantization + */ +#define QK4_0 32 +#pragma pack(1) +typedef struct { + mllm_fp16_t d; // delta + uint8_t qs[QK4_0 / 2]; // nibbles / quants +} block_q4_0; +#pragma pack() + +// 4-bit quantization; 16 blocks of 32 elements each weight is represented as x = a * q + b; Effectively 4.5 bits per weight +#ifdef MLLM_QKK_64 +#pragma pack(1) +typedef struct { + mllm_fp16_t d[2]; // super-block scales/mins + uint8_t scales[2]; // 4-bit block scales/mins + uint8_t qs[QK_K / 2]; // 4--bit quants +} block_q4_K; +#pragma pack() +static_assert(sizeof(block_q4_K) == 2 * sizeof(uint16_t) + QK_K / 2 + 2, "wrong q4_K block size/padding"); +#else +#pragma pack(1) +typedef struct { + mllm_fp16_t d; // super-block scale for quantized scales + mllm_fp16_t dmin; // super-block scale for quantized mins + uint8_t scales[K_SCALE_SIZE]; // scales and mins, quantized with 6 bits + uint8_t qs[QK_K / 2]; // 4--bit quants +} block_q4_K; +#pragma pack() +static_assert(sizeof(block_q4_K) == 2 * sizeof(mllm_fp16_t) + K_SCALE_SIZE + QK_K / 2, "wrong q4_K block size/padding"); +#endif + +#pragma pack(1) +typedef struct { + mllm_fp16_t d[4]; // deltas for 4 q4_0 blocks + uint8_t qs[QK4_0 * 2]; // nibbles / quants for 4 q4_0 blocks +} block_q4_0x4; +#pragma pack() +static_assert(sizeof(block_q4_0x4) == 4 * sizeof(mllm_fp16_t) + QK4_0 * 2, "wrong q4_0x4 block size/padding"); + +#pragma pack(1) +typedef struct { + mllm_fp16_t d[8]; // deltas for 8 q4_0 blocks + uint8_t qs[QK4_0 * 4]; // nibbles / quants for 8 q4_0 blocks +} block_q4_0x8; +#pragma pack() +static_assert(sizeof(block_q4_0x8) == 8 * sizeof(mllm_fp16_t) + QK4_0 * 4, "wrong q4_0x8 block size/padding"); + +/** + * 6-bits quantization + */ +#pragma pack(1) +typedef struct { + uint8_t ql[QK_K / 2]; // quants, lower 4 bits + uint8_t qh[QK_K / 4]; // quants, upper 2 bits + int8_t scales[QK_K / 16]; // scales, quantized with 8 bits + mllm_fp16_t d; // super-block scale +} block_q6_K; +#pragma pack() +static_assert(sizeof(block_q6_K) == sizeof(mllm_fp16_t) + QK_K / 16 + 3 * QK_K / 4, "wrong q6_K block size/padding"); + +/** + * 8-bits quantization + */ +#define QK8_0 32 +#pragma pack(1) +typedef struct { + mllm_fp16_t d; // delta + int8_t qs[QK8_0]; // quants +} block_q8_0; +#pragma pack() + +#pragma pack(1) +typedef struct { + int8_t qs[QK8_0]; // quants +} block_q8_per_tensor; // used in vecdot_i8_i8, TODO: remove +#pragma pack() + +#define QK8_0F 32 +#pragma pack(1) +typedef struct { + float scale; // delta + int8_t qs[QK8_0F]; // quants +} block_q8_0f; +#pragma pack() + +// This is only used for intermediate quantization and dot products +#pragma pack(1) +typedef struct { + float d; // delta + int8_t qs[QK_K]; // quants + int16_t bsums[QK_K / 16]; // sum of quants in groups of 16 +} block_q8_K; +#pragma pack() +static_assert(sizeof(block_q8_K) == sizeof(float) + QK_K + QK_K / 16 * sizeof(int16_t), "wrong q8_K block size/padding"); + +#pragma pack(1) +typedef struct { + mllm_fp16_t d[4]; // deltas for 4 q8_0 blocks + int8_t qs[QK8_0 * 4]; // quants for 4 q8_0 blocks +} block_q8_0x4; +#pragma pack() +static_assert(sizeof(block_q8_0x4) == 4 * sizeof(mllm_fp16_t) + QK8_0 * 4, "wrong q8_0x4 block size/padding"); + +#pragma pack(1) +typedef struct { + mllm_fp16_t d[8]; // deltas for 8 q8_0 blocks + int8_t qs[QK8_0 * 8]; // quants for 8 q8_0 blocks +} block_q8_0x8; +#pragma pack() +static_assert(sizeof(block_q8_0x8) == 8 * sizeof(mllm_fp16_t) + QK8_0 * 8, "wrong q8_0x8 block size/padding"); diff --git a/include/OpDefined.hpp b/include/OpDefined.hpp index 20b5c30f9..85d235938 100644 --- a/include/OpDefined.hpp +++ b/include/OpDefined.hpp @@ -82,7 +82,7 @@ enum OpType { // for speculative decoding ROPETREE, CAUSALTREEMASK, - + KVCACHESAGE, // F_ADD, @@ -115,9 +115,10 @@ enum OpType { F_BINCOUNT, F_REPEAT, F_LIKE, - F_SCATTERREDUCE, + F_SCATTERRADD, F_APPLY_VISIOROPE, F_FA2, + F_SAGEATTN, // models use only F_FUYU_GATHER_EMBD, F_PHI3V_HD_MERGE, diff --git a/include/Types.hpp b/include/Types.hpp index 1f1611310..879400f84 100644 --- a/include/Types.hpp +++ b/include/Types.hpp @@ -2,6 +2,7 @@ #ifndef MLLM_TYPES_H #define MLLM_TYPES_H #include "OpDefined.hpp" +#include "DataType.hpp" #include #include #include @@ -24,6 +25,7 @@ typedef map OpParam; #define LLAMAFILE_SGEMM inline int KVCache_TYPE = 16; +inline int KVCacheSageDtypeBit = 8; // 8 or 16 typedef enum { MLLM_CPU, MLLM_OPENCL, @@ -72,7 +74,7 @@ enum DataType { MLLM_TYPE_Q4_0_4_8 = 20, MLLM_TYPE_Q4_0_8_8 = 21, MLLM_TYPE_Q8_0_4_4 = 22, - + // 2-bit quantizations MLLM_TYPE_Q3_K = 23, // MLLM_TYPE_Q2_K = 24, MLLM_TYPE_Q1_K = 25, // @@ -81,8 +83,10 @@ enum DataType { MLLM_TYPE_IQ1_S = 28, // MLLM_TYPE_IQ1_M = 29, // MLLM_TYPE_IQ2_S = 30, - + MLLM_TYPE_KLEIDIAI_Q4_0 = 31, + MLLM_TYPE_Q8_0F = 32, // quantized with float scale + MLLM_TYPE_Q2_0 = 33, // 2-bits quantization MLLM_TYPE_COUNT, }; @@ -178,191 +182,6 @@ enum ExecutionType { AUTOREGRESSIVE = 1, }; -/* - * This code is based on ggml(https://github.com/ggerganov/ggml), - * please see https://github.com/ggerganov/ggml/blob/master/src/ggml.c - * ggml is licensed under MIT Copyright (c) 2022 Georgi Gerganov: - * - * MIT License - * Copyright (c) 2022 Georgi Gerganov - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifdef _MSC_VER -#define MLLM_EXTENSION -#else // _MSC_VER -#define MLLM_EXTENSION __extension__ -#endif // _MSC_VER - -typedef uint32_t mllm_half32; - -#if defined(__ARM_NEON) && !defined(_MSC_VER) -typedef __fp16 mllm_fp16_t; -#else -typedef uint16_t mllm_fp16_t; -#endif - -// #define MLLM_QKK_64 -#ifdef MLLM_QKK_64 -#define QK_K 64 -#define K_SCALE_SIZE 4 -#else -#define QK_K 256 -#define K_SCALE_SIZE 12 -#endif -#define QK4_0 32 - -#pragma pack(1) -typedef struct { - mllm_fp16_t d; // delta - uint8_t qs[QK4_0 / 2]; // nibbles / quants -} block_q4_0; -#pragma pack() - -// 4-bit quantization -// 16 blocks of 32 elements each -// weight is represented as x = a * q + b -// Effectively 4.5 bits per weight -#ifdef MLLM_QKK_64 -#pragma pack(1) -typedef struct { - mllm_fp16_t d[2]; // super-block scales/mins - uint8_t scales[2]; // 4-bit block scales/mins - uint8_t qs[QK_K / 2]; // 4--bit quants -} block_q4_K; -#pragma pack() -static_assert(sizeof(block_q4_K) == 2 * sizeof(uint16_t) + QK_K / 2 + 2, "wrong q4_K block size/padding"); -#else -#pragma pack(1) -typedef struct { - mllm_fp16_t d; // super-block scale for quantized scales - mllm_fp16_t dmin; // super-block scale for quantized mins - uint8_t scales[K_SCALE_SIZE]; // scales and mins, quantized with 6 bits - uint8_t qs[QK_K / 2]; // 4--bit quants -} block_q4_K; -#pragma pack() -static_assert(sizeof(block_q4_K) == 2 * sizeof(mllm_fp16_t) + K_SCALE_SIZE + QK_K / 2, "wrong q4_K block size/padding"); -#endif - -#pragma pack(1) -typedef struct { - uint8_t ql[QK_K / 2]; // quants, lower 4 bits - uint8_t qh[QK_K / 4]; // quants, upper 2 bits - int8_t scales[QK_K / 16]; // scales, quantized with 8 bits - mllm_fp16_t d; // super-block scale -} block_q6_K; -#pragma pack() -static_assert(sizeof(block_q6_K) == sizeof(mllm_fp16_t) + QK_K / 16 + 3 * QK_K / 4, "wrong q6_K block size/padding"); - -#define QK8_0 32 -#pragma pack(1) -typedef struct { - mllm_fp16_t d; // delta - int8_t qs[QK8_0]; // quants -} block_q8_0; -#pragma pack() -#pragma pack(1) -typedef struct { - int8_t qs[QK8_0]; // quants -} block_q8_per_tensor; // used in vecdot_i8_i8, TODO: remove -#pragma pack() - -// This is only used for intermediate quantization and dot products -#pragma pack(1) -typedef struct { - float d; // delta - int8_t qs[QK_K]; // quants - int16_t bsums[QK_K / 16]; // sum of quants in groups of 16 -} block_q8_K; -#pragma pack() -static_assert(sizeof(block_q8_K) == sizeof(float) + QK_K + QK_K / 16 * sizeof(int16_t), "wrong q8_K block size/padding"); - -#pragma pack(1) -typedef struct { - mllm_fp16_t d[4]; // deltas for 4 q4_0 blocks - uint8_t qs[QK4_0 * 2]; // nibbles / quants for 4 q4_0 blocks -} block_q4_0x4; -#pragma pack() -static_assert(sizeof(block_q4_0x4) == 4 * sizeof(mllm_fp16_t) + QK4_0 * 2, "wrong q4_0x4 block size/padding"); - -#pragma pack(1) -typedef struct { - mllm_fp16_t d[8]; // deltas for 8 q4_0 blocks - uint8_t qs[QK4_0 * 4]; // nibbles / quants for 8 q4_0 blocks -} block_q4_0x8; -#pragma pack() -static_assert(sizeof(block_q4_0x8) == 8 * sizeof(mllm_fp16_t) + QK4_0 * 4, "wrong q4_0x8 block size/padding"); - -#pragma pack(1) -typedef struct { - mllm_fp16_t d[4]; // deltas for 4 q8_0 blocks - int8_t qs[QK8_0 * 4]; // quants for 4 q8_0 blocks -} block_q8_0x4; -#pragma pack() -static_assert(sizeof(block_q8_0x4) == 4 * sizeof(mllm_fp16_t) + QK8_0 * 4, "wrong q8_0x4 block size/padding"); - -#pragma pack(1) -typedef struct { - mllm_fp16_t d[8]; // deltas for 8 q8_0 blocks - int8_t qs[QK8_0 * 8]; // quants for 8 q8_0 blocks -} block_q8_0x8; -#pragma pack() -static_assert(sizeof(block_q8_0x8) == 8 * sizeof(mllm_fp16_t) + QK8_0 * 8, "wrong q8_0x8 block size/padding"); - -#pragma pack(1) -typedef struct { - uint8_t scales[QK_K / 16]; // scales and mins, quantized with 4 bits - uint8_t qs[QK_K / 4]; // quants - // MLLM_EXTENSION union { - // struct { - // mllm_fp16_t d; // super-block scale for quantized scales - // mllm_fp16_t dmin; // super-block scale for quantized mins - // } MLLM_COMMON_AGGR_S; - // mllm_half32 dm; - // } MLLM_COMMON_AGGR_U; - mllm_fp16_t d; // super-block scale for quantized scales - mllm_fp16_t dmin; // super-block scale for quantized mins -} block_q2_K; -#pragma pack() -static_assert(sizeof(block_q2_K) == 2 * sizeof(mllm_fp16_t) + QK_K / 16 + QK_K / 4, "wrong q2_K block size/padding"); - -#pragma pack(1) -typedef struct { - uint8_t hmask[QK_K / 8]; // quants - high bit - uint8_t qs[QK_K / 4]; // quants - low 2 bits - uint8_t scales[12]; // scales, quantized with 6 bits - mllm_fp16_t d; // super-block scale -} block_q3_K; -#pragma pack() -static_assert(sizeof(block_q3_K) == sizeof(mllm_fp16_t) + QK_K / 4 + QK_K / 8 + 12, "wrong q3_K block size/padding"); - -#pragma pack(1) -typedef struct { - mllm_fp16_t d; - uint16_t qs[QK_K / 8]; -} block_iq2_xxs; -#pragma pack() -static_assert(sizeof(block_iq2_xxs) == sizeof(mllm_fp16_t) + QK_K / 8 * sizeof(uint16_t), "wrong iq2_xxs block size/padding"); - -// - static string DataTypeName(DataType dataType) { switch (dataType) { case MLLM_TYPE_F32: @@ -417,6 +236,10 @@ static string DataTypeName(DataType dataType) { return "IQ2_S"; case MLLM_TYPE_KLEIDIAI_Q4_0: return "KLEIDIAI_Q4_0"; + case MLLM_TYPE_Q8_0F: + return "Q8_0F"; + case MLLM_TYPE_Q2_0: + return "Q2_0"; case MLLM_TYPE_COUNT: return "COUNT"; default: @@ -459,7 +282,6 @@ static size_t DataTypeSize(DataType dtype, uint64_t count = 1) { return (sizeof(block_q4_0x8)) * count / (QK4_0 * 8); case MLLM_TYPE_Q8_0_4_4: return (sizeof(block_q8_0x4)) * count / (QK8_0 * 4); - case MLLM_TYPE_Q3_K: return (sizeof(block_q3_K)) * count / (QK_K); case MLLM_TYPE_Q2_K: @@ -477,8 +299,11 @@ static size_t DataTypeSize(DataType dtype, uint64_t count = 1) { case MLLM_TYPE_IQ2_S: return -1; case MLLM_TYPE_KLEIDIAI_Q4_0: - // std::cout << "KLEIDIAI_Q4_0 is not supported yet" << std::endl; - return sizeof(uint8_t) * count ; + return sizeof(uint8_t) * count; + case MLLM_TYPE_Q8_0F: + return (sizeof(block_q8_0f)) * count / (QK8_0F); + case MLLM_TYPE_Q2_0: + return (sizeof(block_q2_0)) * count / (QK2_0); case MLLM_TYPE_COUNT: return 0; default: diff --git a/scripts/run_ling.sh b/scripts/run_ling.sh new file mode 100755 index 000000000..15cc60670 --- /dev/null +++ b/scripts/run_ling.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +adb shell mkdir /data/local/tmp/mllm +adb shell mkdir /data/local/tmp/mllm/bin +adb shell mkdir /data/local/tmp/mllm/models +adb shell mkdir /data/local/tmp/mllm/vocab +adb push ../vocab/ling_vocab.mllm /data/local/tmp/mllm/vocab/ +adb push ../vocab/ling_merges.txt /data/local/tmp/mllm/vocab/ +adb push ../bin-arm/demo_bailing_moe /data/local/tmp/mllm/bin/ +adb push ../bin-arm/demo_bailing_moe_mbp /data/local/tmp/mllm/bin/ +adb push ../models/ling-lite-1.5-kai_q4_0.mllm /data/local/tmp/mllm/models/ +# adb push ../models/ling-lite-1.5-kai_q4_0_e2.mllm /data/local/tmp/mllm/models/ +# if push failed, exit +if [ $? -ne 0 ]; then + echo "adb push failed" + exit 1 +fi +adb shell "cd /data/local/tmp/mllm/bin && ./demo_bailing_moe -m ../models/ling-lite-1.5-kai_q4_0.mllm" +adb shell "cd /data/local/tmp/mllm/bin && ./demo_bailing_moe_mbp -m ../models/ling-lite-1.5-kai_q4_0.mllm" +# adb shell "cd /data/local/tmp/mllm/bin && ./demo_bailing_moe -m ../models/ling-lite-1.5-kai_q4_0_e2.mllm" +# adb shell "cd /data/local/tmp/mllm/bin && ./demo_bailing_moe_mbp -m ../models/ling-lite-1.5-kai_q4_0_e2.mllm" \ No newline at end of file diff --git a/src/Backend.cpp b/src/Backend.cpp index d42bd85e1..7d2daf567 100644 --- a/src/Backend.cpp +++ b/src/Backend.cpp @@ -20,7 +20,7 @@ void registerBackend() { #ifdef USE_QNN registerQNNBackendCreator(); #elif defined(MLLM_BUILD_XNNPACK_BACKEND) - registerXNNBackendCreator(); + registerXNNBackendCreator(); #endif }); } @@ -59,6 +59,6 @@ bool InsertBackendCreatorMap(BackendType type, shared_ptr creato return true; } -map Backend::global_backends; +map> Backend::global_backends; } // namespace mllm \ No newline at end of file diff --git a/src/Backend.hpp b/src/Backend.hpp index ccd75dda7..e16b141db 100644 --- a/src/Backend.hpp +++ b/src/Backend.hpp @@ -25,12 +25,12 @@ static std::unordered_map kv_cache_map; class TensorFunction { public: virtual void reshape(vector> outputs, vector> inputs, vector args) = 0; - virtual void setUp(vector> outputs, vector> inputs, vector args){}; + virtual void setUp(vector> outputs, vector> inputs, vector args) {}; virtual void execute(vector> outputs, vector> inputs, vector args) = 0; }; class Backend { public: - Backend(){}; + Backend() {}; Backend(shared_ptr &mm) : mem_manager_(mm) { } @@ -54,7 +54,7 @@ class Backend { mem_manager_->free(ptr); } - virtual void alloc_device(DeviceMemory &mem, DataType dtype){ + virtual void alloc_device(DeviceMemory &mem, DataType dtype) { assert(type_ != MLLM_CPU && "alloc_device should not be called on CPU backend"); } virtual void free_device(DeviceMemory &mem) { @@ -94,10 +94,10 @@ class Backend { virtual std::vector runOp(Op *op, std::vector input, std::vector out_names, bool in_place) = 0; virtual std::vector runForward(Module *module, std::vector inputs, std::vector args) = 0; - virtual void onSetUpStart(vector> &inputs, vector> &outputs, string graphName = ""){}; - virtual void onSetUpEnd(vector> &inputs, vector> &outputs, string graphName = ""){}; - virtual void onExecuteStart(vector> &inputs, vector> &outputs, string graphName = ""){}; - virtual void onExecuteEnd(std::vector> &outputs, const string &graph_name = ""){}; + virtual void onSetUpStart(vector> &inputs, vector> &outputs, string graphName = "") {}; + virtual void onSetUpEnd(vector> &inputs, vector> &outputs, string graphName = "") {}; + virtual void onExecuteStart(vector> &inputs, vector> &outputs, string graphName = "") {}; + virtual void onExecuteEnd(std::vector> &outputs, const string &graph_name = "") {}; /** * \brief Registers all the operations supported by the backend. @@ -109,7 +109,7 @@ class Backend { BackendType type() const { return type_; } - static map global_backends; + static map> global_backends; protected: BackendType type_; diff --git a/src/Layer.hpp b/src/Layer.hpp index aca011d90..1cc5228b6 100644 --- a/src/Layer.hpp +++ b/src/Layer.hpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -29,11 +30,15 @@ namespace mllm { class Layer { public: Layer() = default; + ~Layer() { + delete op_; // 手动添加 delete + op_ = nullptr; + } void init(std::string name, OpType type) { name_ = std::move(name); param_["type"] = type; Module::initBackend(MLLM_CPU); - backend_ = Backend::global_backends[MLLM_CPU]; + backend_ = Backend::global_backends[MLLM_CPU].get(); saved_list_idx = Module::listIdx; init_ = true; } @@ -63,10 +68,10 @@ class Layer { return ts[0]; } - void initOp(){ - if (op_ == nullptr) { - if ((param_["type"] == KVCACHE || param_["type"] == KVCACHENPU) - && (Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end())) { + void initOp() { + if (op_ == nullptr) { + if ((param_["type"] == KVCACHE || param_["type"] == KVCACHENPU) + && (Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end())) { if (kv_cache_map.find(name_) == kv_cache_map.end()) { // for the prefill part, we need to create a new op param_["type"] = KVCACHENPU; @@ -88,6 +93,7 @@ class Layer { return; op_->load(*Module::llm_model_ptr->loader); loaded_param = true; + inited_loaded = true; } bool &loaded() { return loaded_param; @@ -95,27 +101,29 @@ class Layer { void free() { op_->free({}, {}); loaded_param = false; + inited_loaded = false; } protected: vector run(vector inputs, int N = 1) { initOp(); Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); - if (module->doLoad || !inited_loaded) {//load + if (module->doLoad || !inited_loaded) { // load if (module->doLoad) { op_->load(*module->loader); inited_loaded = true; } else if (loaded_param) { inited_loaded = loaded_param; } else if (!inited_loaded) { - auto empty_loader = new ParamLoader(""); - op_->load(*empty_loader); + // auto empty_loader = new ParamLoader(""); + ParamLoader empty_loader(""); + op_->load(empty_loader); inited_loaded = true; } } - auto backend = inputs.empty() ? Backend::global_backends[MLLM_CPU] : inputs[0].backend(); + auto backend = inputs.empty() ? Backend::global_backends[MLLM_CPU].get() : inputs[0].backend(); if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { - backend = Backend::global_backends[MLLM_QNN]; + backend = Backend::global_backends[MLLM_QNN].get(); } vector out_names; int count = (N > 1) ? N : 1; @@ -569,14 +577,19 @@ class KVCache final : public Layer { param_["for_xnn"] = false; init(std::move(name), OpType::KVCACHE); } - explicit KVCache(int head, int hidden, int n_rep, int cache_max, bool fa2, std::string name) { + + explicit KVCache(int head, int hidden, int n_rep, int cache_max, string attn_impl, std::string name) { param_["head"] = head; param_["hidden"] = hidden; param_["n_rep"] = n_rep; param_["cache_max"] = cache_max; param_["for_xnn"] = false; - param_["fa2"] = fa2; - init(std::move(name), OpType::KVCACHE); + param_["fa2"] = (attn_impl == "flash_attention_2" || attn_impl == "sage_attention"); + if (attn_impl == "sage_attention" && hidden % QK8_0F == 0 && KVCacheSageDtypeBit == 8) { + init(std::move(name), OpType::KVCACHESAGE); + } else { + init(std::move(name), OpType::KVCACHE); + } } explicit KVCache(int cache_max, std::string name) { diff --git a/src/Module.cpp b/src/Module.cpp index 85260222e..7e9f84fc1 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -20,6 +20,7 @@ std::stack Module::listIdxStack; // TensorStatus Tensor::tensor_status; BackendType Module::tmp_device = MLLM_CPU; std::unordered_map> Module::tensor_func_ops; +bool Module::alloc_mmap = true; int Module::graphIdx = 0; diff --git a/src/Module.hpp b/src/Module.hpp index a2bc37af7..7baf9e7d5 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -13,7 +13,9 @@ #include "Trace.hpp" #include "Types.hpp" #include "backends/cpu/CPUBackend.hpp" +#ifdef USE_OPENCL #include "backends/opencl/OpenCLBackend.hpp" +#endif #include #include #include @@ -55,7 +57,7 @@ class Module { map> activation_tensors; map activation_tensors_num; - AbstructLoader *loader; + std::shared_ptr loader; bool doLoad = false; bool doTrace = false; bool op_transposed_flag = false; @@ -74,6 +76,7 @@ class Module { static BackendType tmp_device; static std::unordered_map> tensor_func_ops; // use for QNN + static bool alloc_mmap; private: template @@ -112,13 +115,13 @@ class Module { shared_ptr mm = nullptr; // mm = std::make_shared(); mm = std::make_shared(); // todomm - Backend::global_backends[MLLM_CPU] = new CPUBackend(mm); + Backend::global_backends[MLLM_CPU] = std::make_unique(mm); break; } #ifdef USE_OPENCL case BackendType::MLLM_OPENCL: { BackendConfig config; - Backend::global_backends[MLLM_OPENCL] = new OpenCLBackend(config); + Backend::global_backends[MLLM_OPENCL] = std::make_unique(config); break; } #endif @@ -148,20 +151,59 @@ class Module { void load(string path) { // create global loader and save to llm_model_ptr.loader as QNNBackend needs to load weights in runtime - loader = new ParamLoader(std::move(path), true); // TODO mmap - load(*loader); + loader = std::make_unique(std::move(path), alloc_mmap); // todo + Tensor::tensor_status = TENSOR_STATIC_INIT; + mllm_time_init(); + doLoad = true; + doTrace = true; + vector tmps; + int max_in_size = 5; + for (int i = 0; i < max_in_size; ++i) { + Tensor t(Backend::global_backends[MLLM_CPU].get()); + t.setName("input" + std::to_string(i)); + t.reshape(1, 1, 1, 10); + t.alloc(); + t.setModule(this); + tmps.push_back(t); + } + llm_model_ptr = this; + vector alternate_args = { + {}, + vector{0, 0}, + std::vector>(32, std::vector(2))}; + uint64_t time_start = 0; + for (auto args : alternate_args) { + time_start = mllm_time_us(); + try { + operator()(tmps, args); + break; + } catch (const std::exception &e) { +#if not defined(__ARM_NEON) + if (std::string("bad any_cast") != e.what()) { + MLLM_LOG_ERROR_STREAM << e.what() << std::endl; + exit(0); + } +#endif + } catch (...) { + MLLM_LOG_ERROR_STREAM << "load error" << std::endl; + exit(0); + } + } + uint64_t time_end = mllm_time_us(); + load_time_ = (time_end - time_start) / 1000.0F; // ms + doLoad = false; + doTrace = false; } - void load(AbstructLoader ¶m_loader) { + void load_multifile(const std::initializer_list path) { + loader = std::make_unique(std::move(path)); Tensor::tensor_status = TENSOR_STATIC_INIT; mllm_time_init(); - - loader = ¶m_loader; doLoad = true; doTrace = true; vector tmps; int max_in_size = 5; for (int i = 0; i < max_in_size; ++i) { - Tensor t(Backend::global_backends[MLLM_CPU]); + Tensor t(Backend::global_backends[MLLM_CPU].get()); t.setName("input" + std::to_string(i)); t.reshape(1, 1, 1, 10); t.alloc(); @@ -210,9 +252,9 @@ class Module { template vector operator()(vector inputs, Args... args) { vector anyArgs = convertArgsToAnyVector(args...); - auto backend = inputs.empty() ? Backend::global_backends[MLLM_CPU] : inputs[0].backend(); + auto backend = inputs.empty() ? Backend::global_backends[MLLM_CPU].get() : inputs[0].backend(); if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { - backend = Backend::global_backends[MLLM_QNN]; + backend = Backend::global_backends[MLLM_QNN].get(); } return backend->runForward(this, inputs, anyArgs); } diff --git a/src/Parallel.hpp b/src/Parallel.hpp index ea014b88b..a84764129 100644 --- a/src/Parallel.hpp +++ b/src/Parallel.hpp @@ -8,6 +8,7 @@ #include "Types.hpp" #include "tokenizers/Tokenizer.hpp" #include +#include namespace mllm { @@ -23,16 +24,20 @@ class ChunkPipeline { } shared_ptr run(Tensor &input_tensor, LlmTextGeneratorOpts &opt, Tokenizer &tokenizer, Module &model, bool &isSwitched, const vector &clean_tensors = {}) { + auto input_copy_sp = std::make_shared(); + input_copy_sp->initFrom(input_tensor); // 初始化形状和数据类型 + input_copy_sp->copyFrom(input_tensor); // 深拷贝数据 + const int num_graph = Tracer::model_.size(); Tensor::tensor_status = TENSOR_STATIC_READY; std::cout << "num_graph: " << num_graph << std::endl; for (int chunk_id = 0; chunk_id < chunk_num; ++chunk_id) { - chunked_tensors.push_back(std::make_shared(Backend::global_backends[MLLM_CPU])); + chunked_tensors.push_back(std::make_shared(Backend::global_backends[MLLM_CPU].get())); chunked_tensors[chunk_id]->setTtype(INPUT_TENSOR); chunked_tensors[chunk_id]->setName(input_tensor.name()); chunked_tensors[chunk_id]->reshape(1, 1, chunk_size, 1); - chunked_tensors[chunk_id]->shallowCopyFrom(&input_tensor, false, {0, 0, chunk_id * chunk_size, 0}); + chunked_tensors[chunk_id]->shallowCopyFrom(input_copy_sp, false, {0, 0, chunk_id * chunk_size, 0}, 1); } std::function executeFunc = [&](int chunk_id, int graphIdx) { diff --git a/src/ParamLoader.cpp b/src/ParamLoader.cpp index 98b743674..90c9cdbcd 100644 --- a/src/ParamLoader.cpp +++ b/src/ParamLoader.cpp @@ -88,11 +88,6 @@ bool ParamLoader::load(mllm::Tensor *tensor) { bool ParamLoader::load(mllm::Tensor *tensor) { string name = tensor->name(); if (!use_mmap_) { - // --- 非 mmap 模式,逻辑保持不变 --- - // 确保 Tensor 已经分配内存 - // if (tensor->rawHostPtr() == nullptr) { - // tensor->alloc(); - // } std::lock_guard lock(mtx); if (offsets_.find(name) == offsets_.end()) { return false; } std::pair offset = offsets_[name]; @@ -101,6 +96,7 @@ bool ParamLoader::load(mllm::Tensor *tensor) { size_t read_size = std::min(tensor->cntSize(), static_cast(offset.second)); auto _ = fread(p, sizeof(uint8_t), read_size, fp_); return true; + } else { // --- mmap 模式,实现智能选择 --- if (mmap_buffer_ == nullptr || offsets_.find(name) == offsets_.end()) { @@ -109,28 +105,31 @@ bool ParamLoader::load(mllm::Tensor *tensor) { std::lock_guard lock(mtx); auto offset_info = offsets_[name]; - // 1. 检查对齐 - int required_alignment = DataTypeSize(tensor->dtype()); - if (required_alignment == 0) required_alignment = 1; - bool is_aligned = (offset_info.first % required_alignment == 0); - - // 2. 尺寸检查 + // 1. 尺寸检查 (保持不变) if (tensor->cntSize() != offset_info.second) { fprintf(stderr, "Error: Tensor '%s' size mismatch. Code wants %zu, file has %llu.\n", name.c_str(), tensor->cntSize(), (unsigned long long)offset_info.second); return false; } - is_aligned = false; + + // 2. 检查对齐 + int required_alignment = DataTypeSize(tensor->dtype()); + if (required_alignment == 0) required_alignment = 1; + bool is_aligned = (offset_info.first % required_alignment == 0); + if (is_aligned) { // -- 对齐:执行零拷贝 -- - uint8_t* source_ptr = mmap_buffer_.get() + offset_info.first; - // setHostPtr 会处理好一切(包括释放之前 alloc 的内存) - tensor->setHostPtr(source_ptr, mmap_buffer_); + // fprintf(stdout, "[MMAP ZERO-COPY] Tensor: '%s'\n", name.c_str()); + uint8_t *source_ptr = mmap_buffer_.get() + offset_info.first; + tensor->setHostPtr(source_ptr, mmap_buffer_); // setHostPtr 会处理好一切 } else { - // -- 未对齐:回退到 memcpy -- - // 从 mmap 区域拷贝数据到 Tensor 自己拥有的内存中 - uint8_t* source_ptr = mmap_buffer_.get() + offset_info.first; - memcpy(tensor->rawHostPtr(), source_ptr, tensor->cntSize()); + // -- 未对齐:回退到 fread 普通加载 -- + // fprintf(stdout, "[MMAP FALLBACK to FREAD] Tensor: '%s' is not aligned.\n", name.c_str()); + + // 因为 fp_ 现在是有效的,我们可以直接使用普通加载逻辑 + auto *p = tensor->hostPtr(); + fseek(fp_, offset_info.first, SEEK_SET); + auto _ = fread(p, sizeof(uint8_t), tensor->cntSize(), fp_); } return true; @@ -142,11 +141,10 @@ ParamLoader::~ParamLoader() { munmap(buffer_, size_); buffer_ = nullptr; } - } else { - if (fp_ != nullptr) { - fclose(fp_); - fp_ = nullptr; - } + } + if (fp_ != nullptr) { + fclose(fp_); + fp_ = nullptr; } } // #ifdef ANDROID_API @@ -156,43 +154,50 @@ ParamLoader::ParamLoader(std::string filename, bool use_mmap_param) : path_(std::move(filename)), use_mmap_(use_mmap_param), fp_(nullptr), buffer_(nullptr), size_(0) { // Initialize new members if (use_mmap_) { - // --- 1. 打开文件并获取文件描述符 --- - FILE *temp_fp = fopen(this->path_.c_str(), "rb"); - if (temp_fp == nullptr) { - // perror(("Error opening file for mmap: " + this->path_).c_str()); - // 无法打开文件,直接返回,保持 ParamLoader 为不可用状态 + // --- 1. 打开文件并获取文件描述符,直接使用成员变量 fp_ --- + this->fp_ = fopen(this->path_.c_str(), "rb"); // 直接赋值给 this->fp_ + if (!this->path_.empty() && this->fp_ == nullptr) { + perror(("Error opening file: " + this->path_).c_str()); + exit(1); // 报错并立即退出程序 + return; // 打开失败,直接返回 + } + if (this->path_.empty()) { return; } // --- 2. 获取文件大小 --- - fseek(temp_fp, 0, SEEK_END); - size_ = ftell(temp_fp); - // fseek(temp_fp, 0, SEEK_SET); // mmap不需要重置文件指针 + fseek(this->fp_, 0, SEEK_END); + size_ = ftell(this->fp_); + // 注意:这里不要将文件指针移回开头,fseek 和 mmap 的 offset 是独立的 // --- 3. 执行内存映射 --- - int fd = fileno(temp_fp); // 获取文件描述符 - uint8_t* mapped_ptr = (uint8_t *)mmap(NULL, size_, PROT_READ, MAP_PRIVATE, fd, 0); + int fd = fileno(this->fp_); + uint8_t *mapped_ptr = (uint8_t *)mmap(NULL, size_, PROT_READ, MAP_PRIVATE, fd, 0); - // mmap完成后,文件描述符即可关闭,映射关系依然存在 - fclose(temp_fp); + // --- 关键:不要关闭文件!--- + // fclose(this->fp_); // <-- 注释或删除这一行 if (mapped_ptr == MAP_FAILED) { perror("mmap failed"); - use_mmap_ = false; // mmap失败,可以考虑回退到非mmap模式或标记为失败 + // mmap 失败,但文件还开着,可以考虑退回到纯文件模式或标记失败 + use_mmap_ = false; + // 清理已打开的文件 + fclose(this->fp_); + this->fp_ = nullptr; + // 也许这里应该重新走一遍非 mmap 的初始化逻辑,或者直接返回让对象不可用 return; } - // --- 4. 将 mmap 指针包装到带自定义删除器的 shared_ptr 中 --- + // --- 4. 包装 mmap 指针 --- auto mmap_size = this->size_; this->mmap_buffer_ = std::shared_ptr(mapped_ptr, [mmap_size](uint8_t *p) { - // 自定义删除器:当 shared_ptr 引用计数归零时,调用 munmap munmap(p, mmap_size); }); // ==================================================================== // --- 5. 从 mmap 内存区域中解析元数据 --- // ==================================================================== - + // 定义一系列在内存指针上操作的辅助 lambda 函数,用于替代原先在 FILE* 上的操作 auto mmap_readInt = [&](uint8_t *&ptr) { int32_t val; @@ -216,7 +221,7 @@ ParamLoader::ParamLoader(std::string filename, bool use_mmap_param) : // 获取指向 mmap 区域开头的当前指针 uint8_t *current_ptr = mmap_buffer_.get(); - + // a. 读取并验证幻数 int magic = mmap_readInt(current_ptr); if (magic != _MAGIC_NUMBER) { @@ -228,7 +233,7 @@ ParamLoader::ParamLoader(std::string filename, bool use_mmap_param) : // b. 读取索引区域的总长度 uint64_t index_size = mmap_readu64(current_ptr); - + // c. 计算索引区域的结束地址 uint8_t *index_end_ptr = current_ptr + index_size; @@ -237,7 +242,7 @@ ParamLoader::ParamLoader(std::string filename, bool use_mmap_param) : std::string name = mmap_readString(current_ptr); uint64_t length = mmap_readu64(current_ptr); uint64_t offset_in_file = mmap_readu64(current_ptr); - + // 将解析出的信息存入 map offsets_[name] = std::make_pair(offset_in_file, length); data_type_[name] = static_cast(mmap_readInt(current_ptr)); @@ -247,9 +252,12 @@ ParamLoader::ParamLoader(std::string filename, bool use_mmap_param) : // Original logic when USE_MMAP is not defined (ensures use_mmap_param is ignored) use_mmap_ = false; // Force false if USE_MMAP macro is not defined this->fp_ = fopen(this->path_.c_str(), "rb"); - if (this->fp_ == nullptr) { - // perror(("Error opening file: " + this->path_).c_str()); - // exit(1); + if (!this->path_.empty() && this->fp_ == nullptr) { + perror(("Error opening file: " + this->path_).c_str()); + exit(1); + return; + } + if (this->path_.empty()) { return; } fseek(fp_, 0, SEEK_SET); @@ -291,18 +299,23 @@ std::tuple ParamLoader::load(string name) { auto _ = fread(data, sizeof(uint8_t), length, fp_); return std::make_tuple(data, length); } + DataType ParamLoader::getDataType(string name) { if (data_type_.count(name) != 1) { - if (!this->path_.empty() && this->fp_ == nullptr) { - MLLM_LOG_ERROR_STREAM << this->path_ << " not found" << std::endl; + if (!use_mmap_ && !this->path_.empty() && this->fp_ == nullptr) { + MLLM_LOG_ERROR_STREAM << "File IO mode: " << this->path_ << " not found or failed to open." << std::endl; exit(0); - } else if (this->fp_ != nullptr && !this->path_.empty()) { - MLLM_LOG_ERROR_STREAM << name << " not found" << std::endl; } + + // if (use_mmap_) { + // MLLM_LOG_WARNING_STREAM << "Mmap mode: Tensor '" << name << "' not found in model metadata." << std::endl; + // } else { + // MLLM_LOG_WARNING_STREAM << "File IO mode: Tensor '" << name << "' not found in model metadata." << std::endl; + // } + return DataType::MLLM_TYPE_COUNT; } int type = data_type_[name]; - // check if exists return static_cast(type); } @@ -446,4 +459,20 @@ bool ParamLoader::partialLoad(mllm::Tensor *tensor, std::set validRow, int return true; } } + +ParamMetadata ParamLoader::getParamMetadata(const std::string &name) { + if (offsets_.find(name) == offsets_.end()) { + throw std::runtime_error("Parameter '" + name + "' not found in offsets map."); + } + auto &offset_pair = offsets_.at(name); + return {offset_pair.first, offset_pair.second}; +} + +FILE *ParamLoader::getInputStream() { + return this->fp_; +} + +std::string ParamLoader::getParamPath() const { + return this->path_; +} } // namespace mllm \ No newline at end of file diff --git a/src/ParamLoader.hpp b/src/ParamLoader.hpp index 4fdec25be..54450260b 100644 --- a/src/ParamLoader.hpp +++ b/src/ParamLoader.hpp @@ -51,6 +51,7 @@ static std::string readString(mllm_file *fp_) { */ class AbstructLoader { public: + virtual ~AbstructLoader() = default; virtual bool load(mllm::Tensor *tensor) = 0; virtual bool load(std::shared_ptr tensor) = 0; @@ -64,6 +65,11 @@ class AbstructLoader { // virtual bool partialLoad(mllm::Tensor *tensor, std::set validRow, int rowNum, int colNum) = 0; }; +struct ParamMetadata { + uint64_t offset; // 参数在文件中的起始偏移 + uint64_t size; // 参数占用的字节数 +}; + /** * \brief The ParamLoader class is the default and only(currently) implementation of the AbstructLoader class. */ @@ -96,6 +102,10 @@ class ParamLoader : public AbstructLoader { return offsets_.size(); } + ParamMetadata getParamMetadata(const std::string &name); + FILE *getInputStream(); + std::string getParamPath() const; + protected: std::mutex mtx; mllm_file *fp_; diff --git a/src/Tensor.cpp b/src/Tensor.cpp index 9d03b0b67..c296accc4 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -39,7 +39,7 @@ Tensor::Tensor(int batch, int head, int sequence, int dimension, BackendType bn_ Module::initBackend(bn_type); } impl_->dtype_ = MLLM_TYPE_F32; - impl_->backend_ = Backend::global_backends[bn_type]; + impl_->backend_ = Backend::global_backends[bn_type].get(); reshape(batch, head, sequence, dimension); if (do_alloc) { alloc(); @@ -64,7 +64,7 @@ Tensor::Tensor(int value, Backend *bn) : Tensor::Tensor(int value, BackendType bn_type) : impl_(std::make_shared()) { impl_->dtype_ = MLLM_TYPE_F32; - impl_->backend_ = Backend::global_backends[bn_type]; + impl_->backend_ = Backend::global_backends[bn_type].get(); reshape(1, 1, 1, 1); alloc(); impl_->should_in_graphs_ = false; @@ -74,7 +74,7 @@ Tensor::Tensor(int value, BackendType bn_type) : Tensor::Tensor(std::vector values, BackendType bn_type) : impl_(std::make_shared()) { impl_->dtype_ = MLLM_TYPE_F32; - impl_->backend_ = Backend::global_backends[bn_type]; + impl_->backend_ = Backend::global_backends[bn_type].get(); reshape(1, 1, 1, values.size()); alloc(); impl_->should_in_graphs_ = false; @@ -99,7 +99,7 @@ void Tensor::alloc() { // std::cout << "alloc " << name() << std::endl; if (aggregated_) return; assert(impl_->backend_ != nullptr); - if (master_tensor_ != nullptr) return; + if (!master_tensor_.expired()) return; if (!shape_offset_.empty() && !shape_master_.empty()) return; impl_->alloc(); @@ -170,24 +170,24 @@ Tensor &Tensor::to(BackendType backend_type) { // realloc the tensor if (backend_type == MLLM_QNN && device() == MLLM_CPU) { this->free(); - module()->activation_tensors[name()]->setBackend(Backend::global_backends[backend_type]); - this->setBackend(Backend::global_backends[backend_type]); + module()->activation_tensors[name()]->setBackend(Backend::global_backends[backend_type].get()); + this->setBackend(Backend::global_backends[backend_type].get()); return *this; } if (backend_type == MLLM_CPU && device() == MLLM_XNNPACK) { - module()->activation_tensors[name()]->setBackend(Backend::global_backends[backend_type]); - this->setBackend(Backend::global_backends[backend_type]); + module()->activation_tensors[name()]->setBackend(Backend::global_backends[backend_type].get()); + this->setBackend(Backend::global_backends[backend_type].get()); return *this; } if (backend_type == MLLM_XNNPACK && device() == MLLM_CPU) { - module()->activation_tensors[name()]->setBackend(Backend::global_backends[backend_type]); - this->setBackend(Backend::global_backends[backend_type]); + module()->activation_tensors[name()]->setBackend(Backend::global_backends[backend_type].get()); + this->setBackend(Backend::global_backends[backend_type].get()); return *this; } - Backend* target_backend = Backend::global_backends[backend_type]; + Backend *target_backend = Backend::global_backends[backend_type].get(); if (target_backend == nullptr) { Module::initBackend(backend_type); - target_backend = Backend::global_backends[backend_type]; + target_backend = Backend::global_backends[backend_type].get(); assert(target_backend != nullptr && "Target backend is not initialized."); } // if (backend_type = MLLM_OPENCL){ @@ -197,10 +197,12 @@ Tensor &Tensor::to(BackendType backend_type) { return *this; }; - - bool is_kvcached_tensor(const std::shared_ptr &tensor) { - return tensor!= nullptr &&tensor->masterTensor() != nullptr && tensor->masterTensor()->name().find("Cache") != std::string::npos; + if (tensor == nullptr) return false; + if (auto master = tensor->masterTensor()) { // 调用新的 masterTensor() + return master->name().find("Cache") != std::string::npos; + } + return false; } /** @@ -213,28 +215,24 @@ void Tensor::_allocate_final_tensor( const std::shared_ptr &template_tensor, Backend *backend) { if (is_kvcached_tensor(template_tensor)) { - // It's a KVCache view - auto master_tensor = template_tensor->masterTensor(); - auto cache_seq_len_ = template_tensor->shapeOffset()[2]; - // If this tensor is an input to a KVCache operation, adjust sequence length based on draft tokens - if (name().find("cache") == std::string::npos) { - cache_seq_len_ = master_tensor->cache_seq_len_; - auto cpu_backend = dynamic_cast(backend); - if (cpu_backend->isUsingDraft()) { - unsigned int last_draft_length = cpu_backend->getLastDraftLength(); - const auto &last_verified_position_ids = cpu_backend->getLastVerifiedPositionIds(); - cache_seq_len_ = cache_seq_len_ - last_draft_length + last_verified_position_ids.size(); + if (auto master_tensor_sp = template_tensor->masterTensor()) { + auto cache_seq_len_ = template_tensor->shapeOffset()[2]; + + if (name().find("cache") == std::string::npos) { + cache_seq_len_ = master_tensor_sp->cache_seq_len_; + auto cpu_backend = dynamic_cast(backend); + if (cpu_backend && cpu_backend->isUsingDraft()) { + unsigned int last_draft_length = cpu_backend->getLastDraftLength(); + const auto &last_verified_position_ids = cpu_backend->getLastVerifiedPositionIds(); + cache_seq_len_ = cache_seq_len_ - last_draft_length + last_verified_position_ids.size(); + } } + setDtype(master_tensor_sp->dtype()); + shallowCopyFrom(master_tensor_sp, false, {0, 0, (int)cache_seq_len_, 0}); + } else { + alloc(); } - setDtype(master_tensor->dtype()); - shallowCopyFrom(master_tensor, false, {0, 0, cache_seq_len_, 0}); - // } else if (template_tensor!= nullptr &&template_tensor->masterTensor() != nullptr) { - // auto master_tensor = template_tensor->masterTensor(); - // auto cache_seq_len_ = template_tensor->shapeOffset(); - // setDtype(master_tensor->dtype()); - // shallowCopyFrom(master_tensor, false, cache_seq_len_); - } - else { + } else { alloc(); } } @@ -253,7 +251,7 @@ void Tensor::_allocate_aggregated_tensor( keep_aggregated_structure = true; // Cannot handle dimensions > 3 } else { for (const auto &ag_tensor : template_tensor->aggregatedTensors()) { - if (ag_tensor->ctype() != template_tensor->aggregatedTensors()[0]->ctype() || is_kvcached_tensor(ag_tensor)) { + if (ag_tensor->ctype() != template_tensor->aggregatedTensors()[0]->ctype()) { //???我什么这么写?因为quant keep_aggregated_structure = true; break; } @@ -289,7 +287,7 @@ void Tensor::_allocate_aggregated_tensor( default: break; // Should not happen } - shared_ot->_allocate_final_tensor(child_tt, backend); + shared_ot->_allocate_final_tensor(child_tt, backend); shared_outputs.push_back(shared_ot); } addTensors(shared_outputs, split_dim); @@ -305,9 +303,9 @@ void Tensor::_allocate_aggregated_tensor( * Otherwise, it allocates a final tensor. * @param template_tensor The template tensor to base the allocation on. */ -void Tensor::allocFromTemplate(shared_ptr template_tensor){ +void Tensor::allocFromTemplate(shared_ptr template_tensor) { assert(backend() != nullptr); - if (template_tensor!= nullptr && !template_tensor->aggregatedTensors().empty()) { + if (template_tensor != nullptr && !template_tensor->aggregatedTensors().empty()) { _allocate_aggregated_tensor(template_tensor, module(), backend()); } else { _allocate_final_tensor(template_tensor, backend()); @@ -315,26 +313,31 @@ void Tensor::allocFromTemplate(shared_ptr template_tensor){ } /** - * @brief Runs a tensor function with the specified parameters. - * @param out_names The names for the output tensors. - * @param type The type of the tensor function to run. - * @param param The parameters for the tensor function. - * @param input_tensors The input tensors to the function. - * @param in_place Whether to run the function in-place. - * @return A vector of output tensors. + * @brief Runs a tensor function with the specified parameters. + * @param out_names The names for the output tensors. + * @param type The type of the tensor function to run. + * @param param The parameters for the tensor function. + * @param input_tensors The input tensors to the function. + * @param in_place Whether to run the function in-place. + * @return A vector of output tensors. */ std::vector Tensor::runFunc(std::vector out_names, - OpType type, - OpParam param, - std::vector input_tensors, - bool in_place) { - auto backend = input_tensors.empty() ? Backend::global_backends[MLLM_CPU] : input_tensors[0].backend(); + OpType type, + OpParam param, + std::vector input_tensors, + bool in_place) { + auto backend = input_tensors.empty() ? Backend::global_backends[MLLM_CPU].get() : input_tensors[0].backend(); if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { - backend = Backend::global_backends[MLLM_QNN]; + backend = Backend::global_backends[MLLM_QNN].get(); } param["type"] = type; - Op *op_ = backend->opCreate(param, ""); - return backend->runOp(op_, input_tensors, out_names, in_place); + // Op *op_ = backend->opCreate(param, ""); + std::unique_ptr op_(backend->opCreate(param, "")); + if (!op_) { + // 如果 opCreate 失败,可以提前返回或抛出异常 + return {}; + } + return backend->runOp(op_.get(), input_tensors, out_names, in_place); } Tensor Tensor::operator+(float data) { @@ -381,22 +384,22 @@ Tensor Tensor::operator/(int data) { Tensor Tensor::operator+(Tensor other) { return runFunc({name() + "-TTadd"}, F_TTADD, {}, - {*this,other})[0]; + {*this, other})[0]; } Tensor Tensor::operator-(Tensor other) { return runFunc({name() + "-TTsub"}, F_TTSUB, {}, - {*this,other})[0]; + {*this, other})[0]; } Tensor Tensor::operator*(Tensor other) { return runFunc({name() + "-TTmul"}, F_TTMUL, {}, - {*this,other})[0]; + {*this, other})[0]; } Tensor Tensor::operator/(Tensor other) { return runFunc({name() + "-TTdiv"}, F_TTDIV, {}, - {*this,other})[0]; + {*this, other})[0]; } Tensor Tensor::mean(Chl axis) { @@ -431,13 +434,11 @@ Tensor Tensor::transpose(vector> axiss) { for (auto &axis : axiss) { param["axis1_" + std::to_string(idx)] = (float)axis.first; param["axis2_" + std::to_string(idx)] = (float)axis.second; - idx ++; + idx++; } - bool in_place = (master_tensor_ == nullptr) || - (master_tensor_->name().find("Cache") == std::string::npos && - master_tensor_->name().find("weight") != std::string::npos); + bool in_place = (master_tensor_.expired() || (master_tensor_.lock()->name().find("Cache") == std::string::npos && master_tensor_.lock()->name().find("weight") != std::string::npos)); // for BSHD attention start - if(axiss.size() == 1 && axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { + if (axiss.size() == 1 && axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { in_place = false; // in-place transpose } // for BSHD attention end @@ -451,10 +452,10 @@ Tensor Tensor::clip(vector b, vector h, vector s, vector d) param["h_size"] = (float)h.size(); param["s_size"] = (float)s.size(); param["d_size"] = (float)d.size(); - for(int i=0; i b, vector h, vector s, param["h_size"] = (float)h.size(); param["s_size"] = (float)s.size(); param["d_size"] = (float)d.size(); - for(int i=0; i index, Chl dim) { OpParam param; param["dim"] = (float)dim; return runFunc({name() + "-cliptensor"}, F_CLIPTENSOR, param, - {*this,index_tensor})[0]; + {*this, index_tensor})[0]; } Tensor Tensor::clip(Tensor index, Chl dim) { OpParam param; param["dim"] = (float)dim; return runFunc({name() + "-cliptensor"}, F_CLIPTENSOR, param, - {*this,index})[0]; + {*this, index})[0]; } Tensor Tensor::expand(int b, int h, int s, int d) { OpParam param; @@ -527,13 +528,13 @@ Tensor Tensor::index_put(Tensor value, Tensor indices, bool accumulate) { OpParam param; param["accumulate"] = (float)accumulate; return runFunc({name() + "-index_put"}, F_INDEX_PUT, param, - {*this,value, indices}, + {*this, value, indices}, !accumulate)[0]; } -void Tensor::scatter_reduce(Tensor value, Tensor indices) { +void Tensor::scatter_add(Tensor value, Tensor indices) { OpParam param; - runFunc({name()}, F_SCATTERREDUCE, param, - {*this,value, indices})[0]; + runFunc({name()}, F_SCATTERRADD, param, + {*this, value, indices})[0]; } Tensor Tensor::cat(vector input_tensors, Chl axis) { @@ -568,7 +569,7 @@ vector Tensor::split(Tensor input, std::vector each_dims, OpParam param; vector next_names; param["num_splits"] = (float)each_dims.size(); - for(int i=0; i { std::shared_ptr impl_; // 核心:使用shared_ptr管理实现 // used for ChildTensor vector shape_offset_; vector shape_master_; - Tensor *master_tensor_ = nullptr; - vector child_tensors_; + std::weak_ptr master_tensor_; + vector> child_tensors_; // AggregatedTensor相关 bool aggregated_ = false; - bool allow_aggregated_ = true; // 是否不聚合,主要用于分割操作 + bool allow_aggregated_ = true; vector> aggregated_tensors_; Tensor *deaggregated_tensor_ = nullptr; Chl aggregated_dim_; vector aggregated_dims_; + vector seq_means_; + TensorType ttype_ = NORMAL_TENSOR; uint32_t uuid_ = 4294967295U; TensorType xnn_tensor_type_ = TensorType::NORMAL_TENSOR; @@ -127,7 +129,17 @@ class Tensor { Tensor(vector values, BackendType bn_type = MLLM_CPU); - ~Tensor() = default; + ~Tensor() { + if (auto master = master_tensor_.lock()) { + auto &children = master->childTensors(); + children.erase( + std::remove_if(children.begin(), children.end(), + [this](const std::weak_ptr &wp) { + return wp.expired() || wp.lock().get() == this; + }), + children.end()); + } + } public: static TensorStatus tensor_status; @@ -162,6 +174,11 @@ class Tensor { impl_->free(); } } + void unload() { + if (impl_) { + impl_->unload(); + } + } /** * \brief get the number of bytes occupied by Tensor's data in memory. @@ -295,26 +312,28 @@ class Tensor { } int sequenceSkipDim() const { - if (master_tensor_ != NULL) { - if (master_tensor_->master_tensor_ != NULL) { - auto shape = master_tensor_->master_tensor_->impl_->shape_; - if (master_tensor_->master_tensor_->impl_->ctype_ == BSHD) { + if (!master_tensor_.expired()) { + auto master = master_tensor_.lock(); + if (master && !master->master_tensor_.expired()) { + auto grandmaster = master->master_tensor_.lock(); + auto shape = grandmaster->impl_->shape_; + if (grandmaster->impl_->ctype_ == BSHD) { return shape[3] * shape[2]; - } else if (master_tensor_->master_tensor_->impl_->ctype_ == BHDS) { + } else if (grandmaster->impl_->ctype_ == BHDS) { return shape[3]; - } else if (master_tensor_->master_tensor_->impl_->ctype_ == BDHS) { + } else if (grandmaster->impl_->ctype_ == BDHS) { return shape[3] * impl_->shape_[2]; } else { std::cout << "sequenceSkipDim() only support for BSHD and BHDS" << std::endl; return -1; } - } else { - auto shape = master_tensor_->impl_->shape_; - if (master_tensor_->impl_->ctype_ == BSHD) { + } else if (master) { + auto shape = master->impl_->shape_; + if (master->impl_->ctype_ == BSHD) { return shape[3] * shape[2]; - } else if (master_tensor_->impl_->ctype_ == BHDS) { + } else if (master->impl_->ctype_ == BHDS) { return shape[3]; - } else if (master_tensor_->impl_->ctype_ == BDHS) { + } else if (master->impl_->ctype_ == BDHS) { return shape[3] * impl_->shape_[2]; } else { std::cout << "sequenceSkipDim() only support for BSHD and BHDS" << std::endl; @@ -338,6 +357,7 @@ class Tensor { } // return shape_[3]*shape_[2]; } + return -1; } /** @@ -359,22 +379,22 @@ class Tensor { } /** - * @brief 获取设备内存的通用描述符。 - * @return DeviceMemory& 对设备内存描述符的引用。 - */ - DeviceMemory& device_memory() { - if(backend() == nullptr || backend()->type() == MLLM_CPU) { + * @brief 获取设备内存的通用描述符。 + * @return DeviceMemory& 对设备内存描述符的引用。 + */ + DeviceMemory &device_memory() { + if (backend() == nullptr || backend()->type() == MLLM_CPU) { throw std::runtime_error("Device memory is not available for CPU backend."); } return impl_->device_memory_; } /** - * @brief 获取设备内存的通用描述符 (const 版本)。 - * @return const DeviceMemory& 对设备内存描述符的常量引用。 - */ - const DeviceMemory& device_memory() const { - if(backend() == nullptr || backend()->type() == MLLM_CPU) { + * @brief 获取设备内存的通用描述符 (const 版本)。 + * @return const DeviceMemory& 对设备内存描述符的常量引用。 + */ + const DeviceMemory &device_memory() const { + if (backend() == nullptr || backend()->type() == MLLM_CPU) { throw std::runtime_error("Device memory is not available for CPU backend."); } return impl_->device_memory_; @@ -744,7 +764,9 @@ class Tensor { void setUndiffusion(bool undiffusion) { impl_->undiffusion_ = undiffusion; for (auto &child_tensor : child_tensors_) { - child_tensor->impl_->undiffusion_ = undiffusion; + if (!child_tensor.expired()) { + child_tensor.lock()->impl_->undiffusion_ = undiffusion; + } } } @@ -756,6 +778,13 @@ class Tensor { return impl_->should_in_graphs_; } + vector &seqMeans() { + if (!master_tensor_.expired()) { + return master_tensor_.lock()->seq_means_; + } + return seq_means_; + } + static Tensor zeros(int batch, int head, int sequence, int dimension, BackendType bn_type = MLLM_CPU) { Tensor tensor1(batch, head, sequence, dimension, bn_type, true); memset(tensor1.hostPtr(), 0, tensor1.count() * sizeof(float)); @@ -815,7 +844,7 @@ class Tensor { return split(*this, each_dims, split_dim, same_dim_size); } Tensor index_put(Tensor value, Tensor indices, bool accumulate); - void scatter_reduce(Tensor value, Tensor indices); + void scatter_add(Tensor value, Tensor indices); static vector topk(Tensor input, int k, Chl dim); Tensor sum(Chl dim); Tensor argsort(); @@ -823,6 +852,7 @@ class Tensor { Tensor repeat(Chl dim, int dim_size); static Tensor zero_like(Tensor input); static Tensor flash_attention2_forward(Tensor q, Tensor k, Tensor v, bool is_causal = true); + static Tensor sage_attention_forward(Tensor q, Tensor k, Tensor v, bool causal_mask = false); static Tensor apply_rotary_pos_emb_vision(Tensor input, Tensor rotary_pos_emb); // models use only @@ -839,7 +869,6 @@ class Tensor { * - addChildTensor */ - // 新增一个方法,用于强制设置指针并转移所有权句柄 // 这是比将 ParamLoader 设为友元类更清晰的做法 void setHostPtr(void *ptr, std::shared_ptr memory_handle) { @@ -849,9 +878,9 @@ class Tensor { } // 接管来自 mmap 的新指针和内存句柄 impl_->host_ptr_ = ptr; - impl_->owns_host_ptr_ = false; // 标记内存为外部管理 + impl_->owns_host_ptr_ = false; // 标记内存为外部管理 impl_->memory_handle_ = std::move(memory_handle); // 持有 mmap 句柄 - impl_->allocated_ = count(); // 标记为已分配状态 + impl_->allocated_ = count(); // 标记为已分配状态 } /** @@ -862,7 +891,7 @@ class Tensor { * @param shape_offset 定义子 Tensor 相对于父 Tensor 的维度偏移,用于创建切片(slice)。 * @param head_rep 用于分组查询注意力(GQA),表示K/V头的重复次数。 */ - void shallowCopyFrom(Tensor *source, bool copyshape = true, const vector &shape_offset = {}, int head_rep = 1) { + void shallowCopyFrom(std::shared_ptr source, bool copyshape = true, const vector &shape_offset = {}, int head_rep = 1) { // 步骤 0: 初始设置 // 如果提供了偏移量,则子张量有自己的独立形状,不应复制父张量的形状。 if (!shape_offset.empty()) { @@ -872,11 +901,11 @@ class Tensor { // 步骤 1: 同步父子 Tensor 间的内存布局 (ctype) // 这是原始代码中最复杂的部分,我们将其拆分到一个独立的辅助函数中。 - reconcileLayouts(source); + reconcileLayouts(source.get()); // 步骤 2: 核心浅拷贝操作 - 共享数据指针和元数据 impl_->host_ptr_ = source->hostPtr(); - impl_->owns_host_ptr_ = false; // 子 Tensor 不拥有内存所有权,不负责释放 + impl_->owns_host_ptr_ = false; impl_->capacity_ = source->impl_->capacity_; impl_->count_ = source->impl_->count_; impl_->allocated_ = source->impl_->allocated_; @@ -887,24 +916,18 @@ class Tensor { // 步骤 3: 处理切片(offset)和GQA逻辑 if (!shape_offset.empty()) { - // 如果提供了 shape_offset,则当前 Tensor 是一个 "view" 或 "slice" - setupShapeForView(source, shape_offset, head_rep); + setupShapeForView(source.get(), shape_offset, head_rep); } // 步骤 4: 维护张量层级结构 (处理孙张量) - // 如果当前 Tensor 在此之前有自己的子 Tensor(即 source 的孙张量), - // 必须将这些孙张量重新“过继”给 source,成为 source 的直接子 Tensor。 reparentChildTensors(source, shape_offset, head_rep); - - // 步骤 5: 在父 Tensor 中注册自己 - // 完成所有设置后,将当前 Tensor 正式添加到 source 的子张量列表中。 - source->addChildTensor(this); - } - - void shallowCopyFrom(Tensor &source, bool copyshape = true, const vector &shape_offset = {}, int head_rep = 1) { - shallowCopyFrom(&source, copyshape, shape_offset, head_rep); + source->addChildTensor(shared_from_this()); } + // void shallowCopyFrom(Tensor &source, bool copyshape, const vector &shape_offset = {}, int head_rep = 1) { + // // 使用 source.shared_from_this() 从一个已经被 shared_ptr 管理的对象引用中,安全地获取其 shared_ptr。否则有use-after-free 的风险 + // shallowCopyFrom(source.shared_from_this(), copyshape, shape_offset, head_rep); + // } vector shapeOffset() const { std::vector shape_int(shape_offset_.size()); std::transform(shape_offset_.begin(), shape_offset_.end(), shape_int.begin(), [](uint64_t val) { @@ -923,18 +946,23 @@ class Tensor { return shape_master_; } - Tensor *masterTensor() const { - return master_tensor_; + std::shared_ptr masterTensor() const { + return master_tensor_.lock(); } - void setMasterTensor(Tensor *master_tensor) { + void setMasterTensor(shared_ptr master_tensor) { master_tensor_ = master_tensor; } - vector &childTensors() { + vector> &childTensors() { return child_tensors_; } - void addChildTensor(Tensor *child) { - auto it = std::find(child_tensors_.begin(), child_tensors_.end(), child); + + void addChildTensor(std::shared_ptr child) { + auto it = std::find_if(child_tensors_.begin(), child_tensors_.end(), + [&](const std::weak_ptr &wp) { + return !wp.expired() && wp.lock() == child; + }); + if (it == child_tensors_.end()) { child_tensors_.push_back(child); } @@ -1055,14 +1083,14 @@ class Tensor { return *this; } assert(dtype() == MLLM_TYPE_F32 && "Tensor::half() can only be called on an FP32 tensor."); - assert(master_tensor_ == nullptr && "Conversion not supported for child tensors."); - if(allocted()) { + assert(master_tensor_.expired() && "Conversion not supported for child tensors."); + if (allocted()) { Tensor half_tensor(batch(), head(), sequence(), dimension(), backend(), false); half_tensor.setDtype(MLLM_TYPE_F16); half_tensor.alloc(); backend()->convert_fp_data(this, &half_tensor); return half_tensor; - }else { + } else { impl_->dtype_ = MLLM_TYPE_F16; return *this; } @@ -1075,14 +1103,14 @@ class Tensor { return *this; } assert(dtype() == MLLM_TYPE_F16 && "Tensor::fp32() can only be called on an FP16 tensor."); - assert(master_tensor_ == nullptr && "Conversion not supported for child tensors."); - if(allocted()) { + assert(master_tensor_.expired() && "Conversion not supported for child tensors."); + if (allocted()) { Tensor fp32_tensor(batch(), head(), sequence(), dimension(), backend(), false); fp32_tensor.setDtype(MLLM_TYPE_F32); fp32_tensor.alloc(); backend()->convert_fp_data(this, &fp32_tensor); return fp32_tensor; - }else { + } else { impl_->dtype_ = MLLM_TYPE_F16; return *this; } @@ -1093,7 +1121,7 @@ class Tensor { if (input.device() != backend_type) { input.to(backend_type); } - } + } return inputs; }; static vector toCPU(vector inputs) { @@ -1118,7 +1146,7 @@ class Tensor { void forceResetHostPointer(void *ptr); float i8_scale = 1.f; - + void allocFromTemplate(shared_ptr template_tensor); private: @@ -1129,8 +1157,8 @@ class Tensor { const std::shared_ptr &template_tensor, Module *module, Backend *backend); -public: +public: /* Functions used for 5-D Tensor: * - reshape * - channel @@ -1240,55 +1268,52 @@ class Tensor { reshape(b, h, s, d); } } + // 情况 2 和 情况 3 都需要访问 child_tensors_,所以需要保护 + if (child_tensors_.empty()) { + return; + } // 情况 2: 处理三层张量结构中的布局冲突 (祖父 -> this -> 孙子) - // 条件: this 只有一个子节点,且该子节点与新的父节点(master_tensor)布局相同,但 this 与它们不同。 - else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == master_tensor->impl_->ctype_ - && ctype() != master_tensor->impl_->ctype_) { - auto b = child_tensors_[0]->batch(); - auto h = child_tensors_[0]->head(); - auto s = child_tensors_[0]->sequence(); - auto d = child_tensors_[0]->dimension(); - - // 将 this 和其子节点的布局统一为 master_tensor 的布局 - impl_->chls_ = master_tensor->impl_->chls_; - child_tensors_[0]->impl_->chls_ = master_tensor->impl_->chls_; - - // 逆向应用之前记录的变换,以恢复到正确的逻辑形状 - for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { - auto tf = impl_->trans_from_[i]; - auto axis0 = tf.first; - auto axis1 = tf.second; - // 交换 chls_ 中的维度索引 - std::swap(child_tensors_[0]->impl_->chls()[axis0], child_tensors_[0]->impl_->chls()[axis1]); + if (auto child_sp = child_tensors_[0].lock()) { + Tensor *child = child_sp.get(); + + if (child->ctype() == master_tensor->impl_->ctype_ && ctype() != master_tensor->impl_->ctype_) { + auto b = child->batch(); + auto h = child->head(); + auto s = child->sequence(); + auto d = child->dimension(); + + impl_->chls_ = master_tensor->impl_->chls_; + child->impl_->chls_ = master_tensor->impl_->chls_; + + for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { + auto tf = impl_->trans_from_[i]; + std::swap(child->impl_->chls()[tf.first], child->impl_->chls()[tf.second]); + } + changeCtype(); + child->changeCtype(); + child->reshape(b, h, s, d); + transCopyShape(child->shape()); } - changeCtype(); // 根据 chls_ 更新 ctype - child_tensors_[0]->changeCtype(); - child_tensors_[0]->reshape(b, h, s, d); - transCopyShape(child_tensors_[0]->shape()); - } - // 情况 3: 处理从4D (LLM) 到5D (Vision) 张量的特殊布局转换 - // 条件: this 的子节点是5D (BCTHW),新的父节点是4D (BSHD),而 this 不是 BCTHW。 - else if (child_tensors_.size() == 1 && child_tensors_[0]->ctype() == BCTHW - && master_tensor->impl_->ctype_ == BSHD && ctype() != BCTHW) { - auto b = child_tensors_[0]->batch(); - auto c = child_tensors_[0]->channel(); - auto t = child_tensors_[0]->time(); - auto h = child_tensors_[0]->height(); - auto w = child_tensors_[0]->width(); - - // 强制重置为标准的5D布局 - impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; - child_tensors_[0]->impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; - - // 同样,逆向应用变换 - for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { - auto tf = impl_->trans_from_[i]; - std::swap(child_tensors_[0]->impl_->chls()[tf.first], child_tensors_[0]->impl_->chls()[tf.second]); + // 情况 3: 处理从4D (LLM) 到5D (Vision) 张量的特殊布局转换 + else if (child->ctype() == BCTHW && master_tensor->impl_->ctype_ == BSHD && ctype() != BCTHW) { + auto b = child->batch(); + auto c = child->channel(); + auto t = child->time(); + auto h = child->height(); + auto w = child->width(); + + impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; + child->impl_->chls_ = {{BATCH, 0}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; + + for (int i = impl_->trans_from_.size() - 1; i >= 0; --i) { + auto tf = impl_->trans_from_[i]; + std::swap(child->impl_->chls()[tf.first], child->impl_->chls()[tf.second]); + } + changeCtype(); + child->changeCtype(); + child->reshape(b, c, t, h, w); + transCopyShape(child->shape()); } - changeCtype(); - child_tensors_[0]->changeCtype(); - child_tensors_[0]->reshape(b, c, t, h, w); - transCopyShape(child_tensors_[0]->shape()); } } @@ -1332,25 +1357,24 @@ class Tensor { * @param shape_offset * @param head_rep */ - void reparentChildTensors(Tensor *source, const vector &shape_offset, int head_rep) { + void reparentChildTensors(std::shared_ptr source, const vector &shape_offset, int head_rep) { auto it = child_tensors_.begin(); while (it != child_tensors_.end()) { - auto &child_tensor = *it; - - // 1. 先计算出最终要传递的 offset - vector final_offset; - auto origin_shape_offset = child_tensor->shapeOffset(); - if (!origin_shape_offset.empty()) { - final_offset = origin_shape_offset; - // ...应用那个奇怪的索引[2]的逻辑... - } else if (!shape_offset.empty()) { - final_offset = shape_offset; - } + if (auto child_sp = it->lock()) { + vector final_offset; + auto origin_shape_offset = child_sp->shapeOffset(); + if (!origin_shape_offset.empty()) { + final_offset = origin_shape_offset; + } else if (!shape_offset.empty()) { + final_offset = shape_offset; + } - // 2. 只调用一次 - child_tensor->shallowCopyFrom(source, false, final_offset, head_rep); + child_sp->shallowCopyFrom(source, false, final_offset, head_rep); - it = child_tensors_.erase(it); + it = child_tensors_.erase(it); + } else { + it = child_tensors_.erase(it); + } } } @@ -1478,7 +1502,6 @@ class Tensor { std::vector input_tensors = {}, bool in_place = false); - public: /* Functions used for TEST & DEBUG * - checkData diff --git a/src/TensorImpl.hpp b/src/TensorImpl.hpp index e480d105a..82eefbd63 100644 --- a/src/TensorImpl.hpp +++ b/src/TensorImpl.hpp @@ -20,21 +20,21 @@ class Backend; class Module; enum DeviceMemType { - MEM_TYPE_GENERIC, // 通用设备指针 (可用于 CUDA 的 `cudaMalloc` 结果) - MEM_TYPE_BUFFER, // OpenCL 缓冲区 (cl_buffer) - MEM_TYPE_IMAGE_2D, // OpenCL 2D图像 (cl_image) - MEM_TYPE_IMAGE_3D, // OpenCL 3D图像 (cl_image) + MEM_TYPE_GENERIC, // 通用设备指针 (可用于 CUDA 的 `cudaMalloc` 结果) + MEM_TYPE_BUFFER, // OpenCL 缓冲区 (cl_buffer) + MEM_TYPE_IMAGE_2D, // OpenCL 2D图像 (cl_image) + MEM_TYPE_IMAGE_3D, // OpenCL 3D图像 (cl_image) MEM_TYPE_TEXTURE, // 没用 }; // 通用设备内存描述符结构体 struct DeviceMemory { - void* handle = nullptr; // 通用句柄 (存放 cl_mem, cuda pointer, etc.) + void *handle = nullptr; // 通用句柄 (存放 cl_mem, cuda pointer, etc.) DeviceMemType type = MEM_TYPE_BUFFER; // 内存类型,默认为 Buffer - + // 后端无关的元数据 size_t size_in_bytes = 0; - + // 专门为 Image 类型准备的元数据 size_t image_width = 0; size_t image_height = 0; @@ -43,23 +43,20 @@ struct DeviceMemory { size_t image_row_pitch_in_bytes = 0; }; - class TensorImpl { public: - - void *host_ptr_ = nullptr; bool owns_host_ptr_ = true; std::shared_ptr memory_handle_ = nullptr; - //=====GPU====== + //=====GPU====== enum Location { UNSPECIFIED, // 未指定位置 ON_HOST, // 在主机 (CPU) 内存中 ON_DEVICE // 在设备 (如 OpenCL GPU) 内存中 - }; + }; Location location_ = ON_HOST; // 默认位置设为 ON_HOST, - DeviceMemory device_memory_; + DeviceMemory device_memory_; //=====GPU====== std::map chls_ = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; @@ -86,22 +83,14 @@ class TensorImpl { TensorImpl() = default; TensorImpl(Backend *bn) : backend_(bn) { - if(backend_->type() == MLLM_OPENCL) { + if (backend_->type() == MLLM_OPENCL) { location_ = ON_DEVICE; } } // 析构函数负责资源释放 ~TensorImpl() { - if (host_ptr_ != nullptr && owns_host_ptr_) { - if (backend_) { - backend_->free(host_ptr_); - } - }else if (device_memory_.handle != nullptr) { - if (backend_) { - backend_->free_device(device_memory_); // 通过 backend 释放 - } - } + free_memory(); } // 禁止拷贝(使用shared_ptr管理) @@ -113,7 +102,7 @@ class TensorImpl { } void alloc() { if (location_ == ON_DEVICE) { - if (device_memory_.handle != nullptr) return; + if (device_memory_.handle != nullptr) return; if (host_ptr_ != nullptr && owns_host_ptr_) { backend_->free(host_ptr_); host_ptr_ = nullptr; @@ -138,20 +127,29 @@ class TensorImpl { void free_memory() { if (location_ == ON_HOST && host_ptr_ != nullptr && owns_host_ptr_) { if (backend_) backend_->free(host_ptr_); - } - else if (location_ == ON_DEVICE && device_memory_.handle != nullptr) { + } else if (location_ == ON_DEVICE && device_memory_.handle != nullptr) { if (backend_) backend_->free_device(device_memory_); device_memory_.handle = nullptr; // 清理句柄 } host_ptr_ = nullptr; allocated_ = 0; } - + + void unload() { + memory_handle_.reset(); + if (owns_host_ptr_ && host_ptr_ != nullptr) { + free_memory(); + } + host_ptr_ = nullptr; + allocated_ = 0; + owns_host_ptr_ = true; + } + // 保留旧的 free() 接口,但让它调用新的 free_memory() void free() { free_memory(); } - + // void free() { // if (host_ptr_ != nullptr && owns_host_ptr_) { // 直接访问成员变量 // if (backend_) { @@ -162,17 +160,16 @@ class TensorImpl { // } // } - void to(Backend *target_backend) { if (backend_ == target_backend) { - return; + return; } // 路径1: 从任何后端迁移到主机 (CPU) if (target_backend->type() == MLLM_CPU) { if (location_ == ON_DEVICE) { // 从设备迁移到Host - void* new_host_ptr = nullptr; + void *new_host_ptr = nullptr; target_backend->alloc(&new_host_ptr, cntSize() + 16, 128); - backend_->copy_to_host(new_host_ptr, device_memory_); + backend_->copy_to_host(new_host_ptr, device_memory_); backend_->free_device(device_memory_); host_ptr_ = new_host_ptr; // cl_device_buffer_ = nullptr; @@ -194,16 +191,14 @@ class TensorImpl { location_ = ON_DEVICE; allocated_ = 0; } - } - else { + } else { std::cout << "Device -> Device migration via Host" << std::endl; - this->to(Backend::global_backends[MLLM_CPU]); + this->to(Backend::global_backends[MLLM_CPU].get()); this->to(target_backend); } backend_ = target_backend; } - // int canonicalAxisIndex(int axis_index) const { if (axis_index < 0) { diff --git a/src/backends/cpu/CMakeLists.txt b/src/backends/cpu/CMakeLists.txt index cb742ec4f..bd03fb1a3 100644 --- a/src/backends/cpu/CMakeLists.txt +++ b/src/backends/cpu/CMakeLists.txt @@ -2,6 +2,7 @@ file(GLOB MLLM_CPU_SRC ${CMAKE_CURRENT_LIST_DIR}/*.cpp ${CMAKE_CURRENT_LIST_DIR}/compute/*.cpp + ${CMAKE_CURRENT_LIST_DIR}/third_party/ggml/*.cpp ${CMAKE_CURRENT_LIST_DIR}/op/*.cpp ${CMAKE_CURRENT_LIST_DIR}/function/*.cpp ) @@ -21,46 +22,69 @@ if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES endif() list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS ${KLEIDIAI_SOURCE_DIR}) - message(STATUS "Enabling kleidai QSI4_C32 MatMul implementation.") - list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS - ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p - ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack - ) - - set(KLEIDIAI_SOURCES_QSI4 + + # --- Section for QSI4_C32P (FP32 output) kernels --- + message(STATUS "Enabling kleidiai QSI4_C32 MatMul implementation.") + list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p + ) + set(KLEIDIAI_SOURCES_QSI4_C32P ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod_asm.S ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_qai8dxp_qsi4c32p/kai_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm_asm.S - ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.c - ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.c ) - list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_SOURCES_QSI4}) + list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_SOURCES_QSI4_C32P}) + + # --- Section for QSI4_CXP (FP16 output) kernels --- + message(STATUS "Enabling kleidiai QSI4_CXP (to FP16) MatMul implementation.") + list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp + ) + set(KLEIDIAI_SOURCES_QSI4_CXP + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod_asm.S + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm_asm.S + ) + list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_SOURCES_QSI4_CXP}) - message(STATUS "Enabling kleidai FP16 MatMul implementation.") + # --- Section for FP16 (f16*f16) kernels --- + message(STATUS "Enabling kleidiai FP16 MatMul implementation.") list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_f16_f16p - ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack ) set(KLEIDIAI_SOURCES_FP16 ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla.c - ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon.c ) list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_SOURCES_FP16}) - message(STATUS "Enabling kleidaiFP32 MatMul implementation.") + # --- Section for FP32 (f32*f32) kernels --- + message(STATUS "Enabling kleidiai FP32 MatMul implementation.") list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p - ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack ) set(KLEIDIAI_SOURCES_FP32 ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla.c ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla_asm.S - ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon.c ) list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_SOURCES_FP32}) - # 将 kleidiai 源文件添加到主源文件列表 + # --- Section for all packing functions --- + list(APPEND ALL_KLEIDIAI_INCLUDE_DIRS + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack + ) + set(KLEIDIAI_PACK_SOURCES + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f16_neon.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4cxp_qs4cxs1s0.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon.c + ${KLEIDIAI_SOURCE_DIR}/kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon.c + ) + list(APPEND ALL_KLEIDIAI_SOURCES ${KLEIDIAI_PACK_SOURCES}) + + # 将所有 kleidiai 源文件添加到主源文件列表 list(APPEND MLLM_CPU_SRC ${ALL_KLEIDIAI_SOURCES}) endif() # End ARM check for kleidiai sources @@ -82,11 +106,11 @@ endif() if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") message(STATUS "ARM detected") add_compile_options(-march=armv8.2-a+dotprod+fp16+fp16fml) - + # 特殊处理:为FP16源文件添加格式标志 if(KLAI_USE_FP16 AND CMAKE_CROSS_COMPILING) message(STATUS "Cross-compilation for ARM detected. Applying FP16 compiler flags.") - set_source_files_properties(${KLEIDIAI_SOURCES_FP16} + set_source_files_properties(${KLEIDIAI_FP16_SOURCES} ${KLEIDIAI_SOURCES_QSI4_CXP} PROPERTIES COMPILE_FLAGS "-mfp16-format=ieee" ) endif() @@ -113,6 +137,7 @@ endif() # Conditionally add kleidiai compile definitions for ARM if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") target_compile_definitions(mllm_cpu PUBLIC KLAI_USE_QSI4_C32) + target_compile_definitions(mllm_cpu PUBLIC KLAI_USE_QSI4_CXP) target_compile_definitions(mllm_cpu PUBLIC KLAI_USE_FP16) target_compile_definitions(mllm_cpu PUBLIC KLAI_USE_FP32) endif() @@ -147,4 +172,4 @@ endif() target_link_libraries(mllm_cpu PUBLIC fmt::fmt-header-only) -set_target_properties(mllm_cpu PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) \ No newline at end of file +set_target_properties(mllm_cpu PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE) diff --git a/src/backends/cpu/CPUBackend.cpp b/src/backends/cpu/CPUBackend.cpp index 29c0d69e0..cb397ff75 100644 --- a/src/backends/cpu/CPUBackend.cpp +++ b/src/backends/cpu/CPUBackend.cpp @@ -70,6 +70,7 @@ #include "op/CPUKVCacheNPU.hpp" #include "op/CPUKVCacheXp.hpp" +#include "op/CPUKVCacheSage.hpp" #include "op/CPUBinaryFunc.hpp" #include "op/CPUCatFunc.hpp" @@ -91,55 +92,20 @@ #include "op/CPUBinCountFunc.hpp" #include "op/CPURepeatFunc.hpp" #include "op/CPULikeFunc.hpp" -#include "op/CPUScatterReduceFunc.hpp" +#include "op/CPUScatterAddFunc.hpp" #include "op/CPUVisionRoPEFunc.hpp" #include "op/CPUFlashAttention2Func.hpp" +#include "op/CPUSageAttentionFunc.hpp" #include "op/CPUFuyuGatherEmbdFunc.hpp" #include "op/CPUPhi3VhdmergeFunc.hpp" -// #include "function/CPUBinaryFunc.hpp" -// #include "function/CPUCatFunc.hpp" -// #include "function/CPUClipFunc.hpp" -// #include "function/CPUExpandFunc.hpp" -// #include "function/CPUFlattenFunc.hpp" -// #include "function/CPUMatmulFunc.hpp" -// #include "function/CPUMeanFunc.hpp" -// #include "function/CPUNormFunc.hpp" -// #include "function/CPURangeFunc.hpp" -// #include "function/CPUSplitFunc.hpp" -// #include "function/CPUSumFunc.hpp" -// #include "function/CPUTopkFunc.hpp" -// #include "function/CPUTransposeFunc.hpp" -// #include "function/CPUViewFunc.hpp" -// #include "function/CPUWhereFunc.hpp" -// #include "function/CPUIndexPutFunc.hpp" -// #include "function/CPUArgSortFunc.hpp" -// #include "function/CPUBinCountFunc.hpp" -// #include "function/CPURepeatFunc.hpp" -// #include "function/CPULikeFunc.hpp" -// #include "function/CPUScatterReduceFunc.hpp" -// #include "function/CPUVisionRoPEFunc.hpp" -// #include "function/CPUFlashAttention2Func.hpp" - -// #include "function/CPUFuyuGatherEmbdFunc.hpp" -// #include "function/CPUPhi3VhdmergeFunc.hpp" - namespace mllm { class CPUBackendCreator : public BackendCreator { Backend *create(BackendConfig config) { shared_ptr mm = nullptr; + // mm = std::make_shared(); mm = std::make_shared(); // todomm - // switch (config.memory) { - // case BackendConfig::Memory_High: - // mm = std::make_shared(); - // // mm = std::make_shared(); // todomm - // break; - // default: - // mm = std::make_shared(); - // // mm = std::make_shared(); // todomm - // break; - // } return new CPUBackend(mm); }; }; @@ -222,6 +188,7 @@ void CPUBackend::registerOps() { addCreator(XP_KVCACHE, (CPUBackend::Creator *)(new CPUKVCacheXpCreator())); addCreator(NTKROPE, (CPUBackend::Creator *)(new CPUNTKRoPECreator())); addCreator(HEADLINEAR, (CPUBackend::Creator *)(new CPUHeadLinearCreator())); + addCreator(KVCACHESAGE, (CPUBackend::Creator *)(new CPUKVCacheSageCreator())); // funsction addCreator(F_ADD, (CPUBackend::Creator *)(new CPUaddFunctionCreator())); @@ -254,9 +221,10 @@ void CPUBackend::registerOps() { addCreator(F_BINCOUNT, (CPUBackend::Creator *)(new CPUbincountFunctionCreator())); addCreator(F_REPEAT, (CPUBackend::Creator *)(new CPUrepeatFunctionCreator())); addCreator(F_LIKE, (CPUBackend::Creator *)(new CPUlikeFunctionCreator())); - addCreator(F_SCATTERREDUCE, (CPUBackend::Creator *)(new CPUScatterReduceFunctionCreator())); + addCreator(F_SCATTERRADD, (CPUBackend::Creator *)(new CPUScatterAddFunctionCreator())); addCreator(F_APPLY_VISIOROPE, (CPUBackend::Creator *)(new CPUVisionRoPEFuncFunctionCreator())); addCreator(F_FA2, (CPUBackend::Creator *)(new CPUFlashAttention2FuncCreator())); + addCreator(F_SAGEATTN, (CPUBackend::Creator *)(new CPUSageAttentionFuncCreator())); // models use only addCreator(F_FUYU_GATHER_EMBD, (CPUBackend::Creator *)(new CPUFuyuGatherEmbdFuncCreator())); addCreator(F_PHI3V_HD_MERGE, (CPUBackend::Creator *)(new CPUPhi3VhdmergeFunctionCreator())); @@ -270,7 +238,7 @@ TensorFunction *CPUBackend::funcCreate(const TensorFuncType type) { return iter->second; } -void CPUBackend::registerFuncs(){ +void CPUBackend::registerFuncs() { ; }; @@ -279,14 +247,14 @@ int CPUBackend::cpu_threads = 4; void CPUBackend::convert_fp_data(Tensor *src, Tensor *dest) { // 根据源和目标的类型,执行相应的CPU循环转换 if (src->dtype() == MLLM_TYPE_F32 && dest->dtype() == MLLM_TYPE_F16) { - float* src_ptr = src->hostPtr(); - mllm_fp16_t* dst_ptr = dest->hostPtr(); + float *src_ptr = src->hostPtr(); + mllm_fp16_t *dst_ptr = dest->hostPtr(); for (int i = 0; i < src->count(); i++) { dst_ptr[i] = MLLM_FP32_TO_FP16(src_ptr[i]); } } else if (src->dtype() == MLLM_TYPE_F16 && dest->dtype() == MLLM_TYPE_F32) { - mllm_fp16_t* src_ptr = src->hostPtr(); - float* dst_ptr = dest->hostPtr(); + mllm_fp16_t *src_ptr = src->hostPtr(); + float *dst_ptr = dest->hostPtr(); for (int i = 0; i < src->count(); i++) { dst_ptr[i] = MLLM_FP16_TO_FP32(src_ptr[i]); } @@ -330,85 +298,6 @@ void CPUBackend::_create_output_tensors( } } -/** - * @brief Creates and allocates memory for all output tensors based on various strategies (standard, aggregated, KVCache). - * @param out_tensors The vector to populate with prepared output tensors. - * @param input_tensors The vector of input tensors. - * @param out_names The names of the output tensors. - * @param module The current module. - * @param backend The current backend. - */ -// std::vector CPUBackend::runFunc( -// std::vector out_names, -// TensorFuncType type, -// std::vector float_args, -// std::vector inputs, -// bool in_place) { -// Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); -// auto &activation_tensors = module->activation_tensors; -// assert(module != nullptr); -// Backend *backend = inputs.empty() ? Backend::global_backends[MLLM_CPU] : inputs[0].backend(); -// TensorFunction *func = backend->funcCreate(type); -// if (module->doTrace) { // trace -// for (const auto &out_name : out_names) { -// if (activation_tensors.find(out_name) == activation_tensors.end()) { -// activation_tensors[out_name] = std::make_shared(backend); -// activation_tensors[out_name]->setName(out_name); -// activation_tensors[out_name]->setModule(module); -// } -// } -// std::vector> inPtrs; -// for (auto &input : inputs) { -// inPtrs.push_back(input.shouldInGraphs() ? activation_tensors[input.name()] : -// std::shared_ptr(&input, [](Tensor *) {})); -// } -// std::vector> outPtrs; -// for (auto &name : out_names) outPtrs.push_back(activation_tensors[name]); -// func->setUp(outPtrs, inPtrs, float_args); -// std::vector results; -// for (auto &name : out_names) results.push_back(*activation_tensors[name]); -// return results; -// } -// #ifdef DEBUGOPTIME -// auto start_t = mllm_time_us(); -// #endif -// vector> input_tensors; -// for (auto &input : inputs) { -// input_tensors.push_back(std::shared_ptr(&input, [](Tensor *) {})); -// } -// std::vector> out_tensors; -// // Part 1: Create tensor shells (but don't allocate yet) -// if (!in_place) { -// _create_output_tensors(out_tensors, input_tensors, out_names, module, activation_tensors, backend); -// } else { -// // If in-place, we already have out_tensors filled with input tensors. -// for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { -// input_tensors[i]->setName(out_names[i]); -// out_tensors.push_back(input_tensors[i]); -// } -// } -// // Part 2: Reshape the tensors to determine their dimensions -// func->reshape(out_tensors, input_tensors, float_args); -// // Part 3: Allocate memory for the now-reshaped tensors -// if (!in_place) { -// for (auto &out_tensor : out_tensors) { -// auto act_it = activation_tensors.find(out_tensor->name()); -// auto template_it = act_it != activation_tensors.end()? act_it->second:nullptr; -// out_tensor->allocFromTemplate(template_it); -// } -// } -// // Part 4: Execute the operation -// func->execute(out_tensors, input_tensors, float_args); - -// #ifdef DEBUGOPTIME -// auto end_t = mllm_time_us(); -// std::cout << out_names[0] << " | time: " << (end_t - start_t) / 1000.0F << "ms" << std::endl; -// #endif -// vector results; -// for (const auto &out_tensor : out_tensors) { results.push_back(*out_tensor); } -// return results; -// } - std::vector CPUBackend::runOp(Op *op, std::vector inputs, std::vector out_names, bool in_place) { Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); static map> empty_activation_tensors; @@ -468,11 +357,23 @@ std::vector CPUBackend::runOp(Op *op, std::vector inputs, std::v #ifdef DEBUGOPTIME uint64_t time_end = mllm_time_us(); double inference_time_ = (time_end - time_start) / 1000.0F; // ms - std::cout << layer->op_->name() << " | time: " << inference_time_ << "ms" << std::endl; + if (op->name().empty()) { + if (out_names.size() > 0) + std::cout << out_names[0] << " | time: " << inference_time_ << "ms" << std::endl; + else + std::cout << "Unnamed Op | time: " << inference_time_ << "ms" << std::endl; + } else { + std::cout << op->name() << " | time: " << inference_time_ << "ms" << std::endl; + } #endif vector results; - for (const auto &out_tensor : out_tensors) { results.push_back(*out_tensor); } + for (const auto &out_tensor : out_tensors) { + results.push_back(*out_tensor); +#ifdef DEBUGSAVETENSOR + out_tensor->saveData(); +#endif + } return results; } diff --git a/src/backends/cpu/CPUBackend.hpp b/src/backends/cpu/CPUBackend.hpp index 49ad327c4..b4767fdac 100644 --- a/src/backends/cpu/CPUBackend.hpp +++ b/src/backends/cpu/CPUBackend.hpp @@ -4,7 +4,7 @@ #include "Backend.hpp" #include "Op.hpp" #include "Types.hpp" -#include "compute/Quantize.hpp" +// #include "backends/cpu/third_party/ggml/Quantize.hpp" namespace mllm { class Module; @@ -12,10 +12,16 @@ class Layer; class CPUBackend final : public Backend { public: explicit CPUBackend(shared_ptr &mm); - ~CPUBackend() override = default; + ~CPUBackend() { + for (auto &creator_pair : map_creator_) { + delete creator_pair.second; // 手动删除用 new 创建的 Creator 对象 + } + map_creator_.clear(); + } class Creator { public: + virtual ~Creator() = default; virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const = 0; }; bool addCreator(OpType t, Creator *c) { @@ -32,12 +38,6 @@ class CPUBackend final : public Backend { void registerOps() override; void registerFuncs() override; - // std::vector runFunc( - // std::vector out_names, - // TensorFuncType type, - // std::vector float_args, - // std::vector input_tensors, - // bool in_place) override{}; std::vector runLayer(Layer *layer, std::vector inputs, int N) override; std::vector runOp(Op *op, std::vector input, std::vector out_names, bool in_place) override; diff --git a/src/backends/cpu/compute/ActivationFunction.hpp b/src/backends/cpu/compute/ActivationFunction.hpp index 6a120fa34..2dcf147e1 100644 --- a/src/backends/cpu/compute/ActivationFunction.hpp +++ b/src/backends/cpu/compute/ActivationFunction.hpp @@ -1,7 +1,7 @@ #ifndef ACTFUNC_HPP #define ACTFUNC_HPP -#include "VecDot.hpp" +#include "backends/cpu/third_party/ggml/ComputeUtils.hpp" namespace mllm { #if defined(__ARM_NEON) && defined(__aarch64__) diff --git a/src/backends/cpu/compute/Convolution.cpp b/src/backends/cpu/compute/Convolution.cpp index b5d5ef2f4..14b36858b 100644 --- a/src/backends/cpu/compute/Convolution.cpp +++ b/src/backends/cpu/compute/Convolution.cpp @@ -3,6 +3,7 @@ // #include "Convolution.hpp" +#include "backends/cpu/third_party/ggml/VecDotFP32.hpp" float **reshape_conv2d_kernal_fp32(Tensor *kernel) { int in_channel = kernel->sequence(); diff --git a/src/backends/cpu/compute/Convolution.hpp b/src/backends/cpu/compute/Convolution.hpp index c89418f6b..149e3eafb 100644 --- a/src/backends/cpu/compute/Convolution.hpp +++ b/src/backends/cpu/compute/Convolution.hpp @@ -5,19 +5,17 @@ #ifndef CONVOLUTION2D_HPP #define CONVOLUTION2D_HPP - - -#include "VecDot.hpp" +#include "Tensor.hpp" +#include "Types.hpp" using namespace mllm; -float ** reshape_conv2d_kernal_fp32(Tensor* kernel); - -void conv2d_fp32_VALID(Tensor* input, Tensor* output, float** k_new, int kernel_h, int kernel_w, bool support_bias, Tensor* bias, int stride_h, int stride_w, int thread_count=4); -void conv2d_fp32_SAME(Tensor* input, Tensor* output, float** k_new, int kernel_h, int kernel_w, bool support_bias, Tensor* bias, int stride_h, int stride_w, int padding_h, int padding_w, int thread_count=4); +float **reshape_conv2d_kernal_fp32(Tensor *kernel); +void conv2d_fp32_VALID(Tensor *input, Tensor *output, float **k_new, int kernel_h, int kernel_w, bool support_bias, Tensor *bias, int stride_h, int stride_w, int thread_count = 4); +void conv2d_fp32_SAME(Tensor *input, Tensor *output, float **k_new, int kernel_h, int kernel_w, bool support_bias, Tensor *bias, int stride_h, int stride_w, int padding_h, int padding_w, int thread_count = 4); float **reshape_conv3d_kernal_fp32(Tensor *kernel); -void conv3d_fp32_VALID(Tensor* input, Tensor *output, float** k_new, int kernel_t, int kernel_h, int kernel_w, bool support_bias, Tensor* bias, int stride_t, int stride_h, int stride_w, int thread_count=4); +void conv3d_fp32_VALID(Tensor *input, Tensor *output, float **k_new, int kernel_t, int kernel_h, int kernel_w, bool support_bias, Tensor *bias, int stride_t, int stride_h, int stride_w, int thread_count = 4); -#endif //CONVOLUTION2D_HPP +#endif // CONVOLUTION2D_HPP diff --git a/src/backends/cpu/compute/FlashAttention2.hpp b/src/backends/cpu/compute/FlashAttention2.hpp index 17dbfab20..639684de5 100644 --- a/src/backends/cpu/compute/FlashAttention2.hpp +++ b/src/backends/cpu/compute/FlashAttention2.hpp @@ -8,11 +8,12 @@ #include #include #include "Types.hpp" -#include "VecDot.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" +#include "backends/cpu/third_party/ggml/ComputeUtils.hpp" #ifdef __AVX2__ #include -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) #include #endif @@ -43,42 +44,43 @@ inline float _mm256_hadd_ps(__m256 x) { sum = _mm_hadd_ps(sum, sum); return _mm_cvtss_f32(sum); } -#elif __ARM_NEON__ -// NEON版本:水平最大值 (Horizontal max of a float32x4_t vector) -// float32x4_t 中包含4个float, vmaxvq_f32可以直接找到这4个float中的最大值 +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) inline float _vmaxvq_f32_hmax(float32x4_t x) { return vmaxvq_f32(x); } -// NEON版本:水平求和 (Horizontal sum of a float32x4_t vector) -// float32x4_t 中包含4个float, vaddvq_f32可以直接将这4个float相加 inline float _vaddvq_f32_hadd(float32x4_t x) { return vaddvq_f32(x); } #endif -// ======================================== -// 内存对齐分配函数 -// ======================================== -// 使用 posix_memalign 进行分配 void aligned_alloc(void **ptr, size_t required_bytes, size_t align) { - // posix_memalign 要求 alignment 必须是 void* 大小的整数倍,并且是 2 的幂 if (align % sizeof(void *) != 0 || (align & (align - 1)) != 0) { *ptr = nullptr; return; } - - // posix_memalign 返回 0 表示成功,否则返回错误码 if (posix_memalign(ptr, align, required_bytes) != 0) { *ptr = nullptr; } } -// 直接使用标准 free 进行释放 void aligned_free(void *ptr) { free(ptr); } +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) +inline float32x4_t exp_ps_f32(float32x4_t x) { + float32x4_t a = vdupq_n_f32(12102203.0f); // (1 << 23) / ln(2) + float32x4_t b = vdupq_n_f32(1065353216.0f); // (1 << 23) * (0.5 - 0.04165) + (127 << 23) + int32x4_t m = vdupq_n_s32(0x7f); + float32x4_t y = vmlaq_f32(b, a, x); + int32x4_t r = vreinterpretq_s32_f32(y); + r = vandq_s32(r, vdupq_n_s32(0xffffff)); + r = vorrq_s32(r, vdupq_n_s32(0x3f800000)); + return vreinterpretq_f32_s32(r); +} +#endif + // ======================================== // FlashAttention2 核心实现 (FP32版本) // ======================================== @@ -88,14 +90,14 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { using dtype_out_t = dtype_q_in_t; using dtype_t = dtype_out_t; using acc_dtype_t = float; - // 添加配置参数作为成员变量 + int32_t Br; int32_t Bc; int32_t Q_Head; int32_t KV_Head; int32_t threads; bool high_precision; - // 配置参数初始化 + void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_, bool high_precision_) { Br = Br_; Bc = Bc_; @@ -126,7 +128,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { assert(head_size % threads == 0); #ifdef __AVX2__ assert(dim_size % 8 == 0); // AVX processes 8 floats at a time -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) assert(dim_size % 4 == 0); // NEON processes 4 floats at a time #endif if (seq_size_q != 1) { @@ -139,7 +141,6 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } private: - // 核心计算函数 inline void __fa2_prefill_append(const dtype_t *__restrict__ Q, const dtype_t *__restrict__ K, const dtype_t *__restrict__ V, dtype_t *__restrict__ O, const int32_t batch_size, const int32_t head_size, // head_size 就是 Q_Head @@ -152,38 +153,30 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); - // 【关键修改 1】计算Q头与KV头的分组对应关系 const int32_t kv_group_size = Q_Head / KV_Head; for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { #pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) - for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { // h_idx 是当前Q头的索引 + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { const int32_t thread_id = omp_get_thread_num(); const int32_t this_thread_head = h_idx; - // 【关键修改 1】计算当前Q头 (h_idx) 对应的KV头索引 const int32_t this_thread_kv_head = this_thread_head / kv_group_size; - // --- 主循环 (Tr) --- for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { init_temp(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { - // Q 的指针计算保持不变,因为它有 Q_Head 个头 const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + this_thread_head * dim_size; - - // 【关键修改 2】K 和 V 的指针计算,必须使用 KV_Head 和映射后的 this_thread_kv_head const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Br * Bc; acc_dtype_t *acc_o = acc_o_ + thread_id * Br * dim_size; - // 【关键修改 3】为 mma0 传入Q和K各自的正确步长 mma0(tile_q, tile_k, tile_acc_s, dim_size, head_size * dim_size, KV_Head * dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); softmax(tile_acc_s, scoremax_ + thread_id * Br, scoremax_prev_ + thread_id * Br, score_scale_ + thread_id * Br, score_sum_ + thread_id * Br, logsum_ + thread_id * Br, local_scale, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); rescale(acc_o, score_scale_ + thread_id * Br, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); - // 【关键修改 3】为 mma1 传入 KV_Head 作为V的头数量,用于计算其内部步长 mma1(tile_acc_s, tile_v, acc_o, KV_Head, dim_size, t_r_idx, t_c_idx, seq_size_q, seq_size_k, causal_mask); } if (Tc_left) { @@ -239,7 +232,6 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t Tc_left = seq_size_k % Bc; const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); - // FIX: Calculate the ratio of Q_Head to KV_Head to handle GQA/MHA correctly. const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { @@ -247,14 +239,12 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { const int32_t thread_id = omp_get_thread_num(); const int32_t this_thread_head = h_idx; - // FIX: Map the current query head 'h_idx' to its corresponding KV head. const int32_t this_thread_kv_head = this_thread_head / kv_group_size; for (int t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { init_temp_d(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { const dtype_t *tile_q = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * 1 * head_size * dim_size + this_thread_head * dim_size; - // FIX: Corrected pointer arithmetic for K and V. const dtype_t *tile_k = K + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; const dtype_t *tile_v = V + b_idx * seq_size_k * KV_Head * dim_size + t_c_idx * Bc * KV_Head * dim_size + this_thread_kv_head * dim_size; @@ -288,52 +278,46 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { __m256 zero_vec = _mm256_set1_ps(0.0f); __m256 neg_inf_vec = _mm256_set1_ps(NEG_INF); - // 【最终修正】使用安全的循环来确保完全初始化,不再依赖Br是8的倍数 int i = 0; for (; i <= Br - 8; i += 8) { _mm256_storeu_ps(logsum + i, zero_vec); _mm256_storeu_ps(scoremax + i, neg_inf_vec); } - // 处理剩余的元素(如果Br不是8的倍数) for (; i < Br; ++i) { logsum[i] = 0.0f; scoremax[i] = NEG_INF; } - // acc_o 的初始化是安全的,因为调用者保证了 dim_size % 8 == 0 for (int j = 0; j < Br * dim_size; j += 8) { _mm256_storeu_ps(acc_o + j, zero_vec); } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) float32x4_t zero_vec = vdupq_n_f32(0.0f); float32x4_t neg_inf_vec = vdupq_n_f32(NEG_INF); int i = 0; - // NEON 一次处理4个 for (; i <= Br - 4; i += 4) { vst1q_f32(logsum + i, zero_vec); vst1q_f32(scoremax + i, neg_inf_vec); } - // 处理剩余的元素(如果Br不是4的倍数) for (; i < Br; ++i) { logsum[i] = 0.0f; scoremax[i] = NEG_INF; } - // acc_o 的初始化, 调用者保证了 dim_size % 4 == 0 for (int j = 0; j < Br * dim_size; j += 4) { vst1q_f32(acc_o + j, zero_vec); } #endif } - // 【关键修改】函数签名增加 kv_stride_size 参数,用于区分Q和K的步长 inline void mma0(const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, const int32_t q_stride_size, const int32_t kv_stride_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { #ifdef __AVX2__ + // AVX2 implementation remains unchanged. const int32_t global_r_start = t_r_idx * Br; const int32_t global_r_end = global_r_start + Br; const int32_t global_c_start = t_c_idx * Bc; @@ -343,11 +327,9 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { #pragma unroll for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - // 【关键修改】使用传入的 q_stride_size const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; #pragma unroll for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - // 【关键修改】使用传入的 kv_stride_size const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; __m256 sum_vec = _mm256_setzero_ps(); @@ -373,7 +355,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_r_end = global_r_start + Br; const int32_t global_c_start = t_c_idx * Bc; @@ -381,46 +363,64 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } - for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; - for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; - - float32x4_t sum_vec = vdupq_n_f32(0.0f); - int i = 0; - // 为了性能,可以一次处理8个或更多元素,这里保持与AVX版本类似的逻辑,但向量宽度减半 - for (; i <= dim_size - 8; i += 8) { - // 预取数据到缓存 - __builtin_prefetch(q_block_line + i + 64); - __builtin_prefetch(k_block_line + i + 64); - // 加载两组4个float数据 - float32x4_t q_vec0 = vld1q_f32(q_block_line + i); - float32x4_t k_vec0 = vld1q_f32(k_block_line + i); - float32x4_t q_vec1 = vld1q_f32(q_block_line + i + 4); - float32x4_t k_vec1 = vld1q_f32(k_block_line + i + 4); - // 融合乘加 - sum_vec = vfmaq_f32(sum_vec, q_vec0, k_vec0); - sum_vec = vfmaq_f32(sum_vec, q_vec1, k_vec1); - } - // 处理 dim_size % 8 剩下的部分 - for (; i <= dim_size - 4; i += 4) { - float32x4_t q_vec = vld1q_f32(q_block_line + i); - float32x4_t k_vec = vld1q_f32(k_block_line + i); - sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); + for (int32_t b_r_base = 0; b_r_base < Br; b_r_base += 4) { + for (int32_t b_c_base = 0; b_c_base < Bc; b_c_base += 4) { + float32x4_t accumulators[16]; + for (int i = 0; i < 16; ++i) { + accumulators[i] = vdupq_n_f32(0.0f); } - acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); - // 处理最后不足4个的元素 - for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } + const dtype_t *q0_ptr = q_block + (b_r_base + 0) * q_stride_size; + const dtype_t *q1_ptr = q_block + (b_r_base + 1) * q_stride_size; + const dtype_t *q2_ptr = q_block + (b_r_base + 2) * q_stride_size; + const dtype_t *q3_ptr = q_block + (b_r_base + 3) * q_stride_size; + + for (int k = 0; k < dim_size; k += 4) { + float32x4_t q_vec0 = vld1q_f32(q0_ptr + k); + float32x4_t q_vec1 = vld1q_f32(q1_ptr + k); + float32x4_t q_vec2 = vld1q_f32(q2_ptr + k); + float32x4_t q_vec3 = vld1q_f32(q3_ptr + k); + + float32x4_t k_vec; + + k_vec = vld1q_f32(k_block + (b_c_base + 0) * kv_stride_size + k); + accumulators[0] = vfmaq_f32(accumulators[0], q_vec0, k_vec); + accumulators[4] = vfmaq_f32(accumulators[4], q_vec1, k_vec); + accumulators[8] = vfmaq_f32(accumulators[8], q_vec2, k_vec); + accumulators[12] = vfmaq_f32(accumulators[12], q_vec3, k_vec); + + k_vec = vld1q_f32(k_block + (b_c_base + 1) * kv_stride_size + k); + accumulators[1] = vfmaq_f32(accumulators[1], q_vec0, k_vec); + accumulators[5] = vfmaq_f32(accumulators[5], q_vec1, k_vec); + accumulators[9] = vfmaq_f32(accumulators[9], q_vec2, k_vec); + accumulators[13] = vfmaq_f32(accumulators[13], q_vec3, k_vec); + + k_vec = vld1q_f32(k_block + (b_c_base + 2) * kv_stride_size + k); + accumulators[2] = vfmaq_f32(accumulators[2], q_vec0, k_vec); + accumulators[6] = vfmaq_f32(accumulators[6], q_vec1, k_vec); + accumulators[10] = vfmaq_f32(accumulators[10], q_vec2, k_vec); + accumulators[14] = vfmaq_f32(accumulators[14], q_vec3, k_vec); + + k_vec = vld1q_f32(k_block + (b_c_base + 3) * kv_stride_size + k); + accumulators[3] = vfmaq_f32(accumulators[3], q_vec0, k_vec); + accumulators[7] = vfmaq_f32(accumulators[7], q_vec1, k_vec); + accumulators[11] = vfmaq_f32(accumulators[11], q_vec2, k_vec); + accumulators[15] = vfmaq_f32(accumulators[15], q_vec3, k_vec); + } - acc_s[b_r_idx * Bc + b_c_idx] = total; + for (int i = 0; i < 4; ++i) { + for (int j = 0; j < 4; ++j) { + acc_s[(b_r_base + i) * Bc + (b_c_base + j)] = vaddvq_f32(accumulators[i * 4 + j]); + } + } } } - // 应用因果掩码 - if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { + if (causal_mask) { for (int i = 0; i < Br; ++i) { for (int j = 0; j < Bc; ++j) { - if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + if ((global_c_start + j) > (global_r_start + i + delta_pos)) { + acc_s[i * Bc + j] = NEG_INF; + } } } } @@ -432,79 +432,146 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const float scale, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { + if (high_precision) { #ifdef __AVX2__ - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); - for (int br = 0; br < Br; ++br) { - __m256 max_vec = _mm256_set1_ps(scoremax[br]); - acc_dtype_t *row = acc_s + br * Bc; - int bc = 0; - for (; bc <= Bc - 8; bc += 8) { max_vec = _mm256_max_ps(max_vec, _mm256_loadu_ps(row + bc)); } - float max_val = _mm256_hmax_ps(max_vec); - for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } - scoremax[br] = max_val; - } - for (int br = 0; br < Br; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } - for (int br = 0; br < Br; ++br) { - const float sm = scoremax[br]; - acc_dtype_t *row = acc_s + br * Bc; - float sum = 0.0f; - for (int bc = 0; bc < Bc; ++bc) { - float val = expf((row[bc] - sm) * scale); - row[bc] = val; - sum += val; + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); + for (int br = 0; br < Br; ++br) { + __m256 max_vec = _mm256_set1_ps(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 8; bc += 8) { max_vec = _mm256_max_ps(max_vec, _mm256_loadu_ps(row + bc)); } + float max_val = _mm256_hmax_ps(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } + for (int br = 0; br < Br; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } + for (int br = 0; br < Br; ++br) { + const float sm = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((row[bc] - sm) * scale); + row[bc] = val; + sum += val; + } + score_sum[br] = sum; + } + for (int br = 0; br < Br; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); + for (int br = 0; br < Br; ++br) { + float32x4_t max_vec = vdupq_n_f32(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 4; bc += 4) { + max_vec = vmaxq_f32(max_vec, vld1q_f32(row + bc)); + } + float max_val = _vmaxvq_f32_hmax(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } + for (int br = 0; br < Br; ++br) { + score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); + } + for (int br = 0; br < Br; ++br) { + const float sm = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((row[bc] - sm) * scale); + row[bc] = val; + sum += val; + } + score_sum[br] = sum; } - score_sum[br] = sum; - } - for (int br = 0; br < Br; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } -#elif __ARM_NEON__ - const int32_t global_r_start = t_r_idx * Br; - const int32_t global_c_start = t_c_idx * Bc; - int delta_pos = seq_size_k - seq_size_q; - if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - - memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); - - // 1. 找到每行的最大值 m_i - for (int br = 0; br < Br; ++br) { - float32x4_t max_vec = vdupq_n_f32(scoremax[br]); - acc_dtype_t *row = acc_s + br * Bc; - int bc = 0; - for (; bc <= Bc - 4; bc += 4) { - max_vec = vmaxq_f32(max_vec, vld1q_f32(row + bc)); + for (int br = 0; br < Br; ++br) { + logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } - float max_val = _vmaxvq_f32_hmax(max_vec); - for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } - scoremax[br] = max_val; - } - - // 2. 计算缩放因子 s_i = exp((m_i_prev - m_i) * scale) - for (int br = 0; br < Br; ++br) { - score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); - } - - // 3. 计算 P_ij = exp((S_ij - m_i) * scale) 和 l_i = sum(P_ij) - for (int br = 0; br < Br; ++br) { - const float sm = scoremax[br]; - acc_dtype_t *row = acc_s + br * Bc; - float sum = 0.0f; - // 这里可以进一步用NEON优化expf, 但expf的SIMD实现复杂,暂用标量 - for (int bc = 0; bc < Bc; ++bc) { - float val = expf((row[bc] - sm) * scale); - row[bc] = val; // 更新 acc_s 为 P_ij - sum += val; +#endif + } else { +#ifdef __AVX2__ + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); + for (int br = 0; br < Br; ++br) { + __m256 max_vec = _mm256_set1_ps(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 8; bc += 8) { max_vec = _mm256_max_ps(max_vec, _mm256_loadu_ps(row + bc)); } + float max_val = _mm256_hmax_ps(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } + for (int br = 0; br < Br; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } + for (int br = 0; br < Br; ++br) { + const float sm = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float sum = 0.0f; + for (int bc = 0; bc < Bc; ++bc) { + float val = expf((row[bc] - sm) * scale); + row[bc] = val; + sum += val; + } + score_sum[br] = sum; + } + for (int br = 0; br < Br; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_c_start = t_c_idx * Bc; + int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; + memcpy(scoremax_prev, scoremax, Br * sizeof(acc_dtype_t)); + for (int br = 0; br < Br; ++br) { + float32x4_t max_vec = vdupq_n_f32(scoremax[br]); + acc_dtype_t *row = acc_s + br * Bc; + int bc = 0; + for (; bc <= Bc - 4; bc += 4) { + max_vec = vmaxq_f32(max_vec, vld1q_f32(row + bc)); + } + float max_val = vmaxvq_f32(max_vec); + for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } + scoremax[br] = max_val; + } + for (int br = 0; br < Br; ++br) { + score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); + } + for (int br = 0; br < Br; ++br) { + const float sm = scoremax[br]; + acc_dtype_t *row = acc_s + br * Bc; + float32x4_t sum_vec = vdupq_n_f32(0.0f); + const float32x4_t sm_vec = vdupq_n_f32(sm); + const float32x4_t scale_vec = vdupq_n_f32(scale); + int bc = 0; + for (; bc <= Bc - 4; bc += 4) { + float32x4_t s_vec = vld1q_f32(row + bc); + float32x4_t scaled_s_vec = vmulq_f32(vsubq_f32(s_vec, sm_vec), scale_vec); + float32x4_t p_vec = exp_ps_f32(scaled_s_vec); + vst1q_f32(row + bc, p_vec); + sum_vec = vaddq_f32(sum_vec, p_vec); + } + float sum = vaddvq_f32(sum_vec); + for (; bc < Bc; ++bc) { + float val = expf((row[bc] - sm) * scale); + row[bc] = val; + sum += val; + } + score_sum[br] = sum; + } + for (int br = 0; br < Br; ++br) { + logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } - score_sum[br] = sum; - } - - // 4. 更新 logsum: l_i_new = l_i_prev * s_i + l_i - for (int br = 0; br < Br; ++br) { - logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; - } #endif + } } inline void rescale(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, @@ -526,7 +593,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(row_ptr + j, acc); } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -544,18 +611,17 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { #endif } - // 【关键修改】函数签名增加 kv_head_size 参数,用于计算V的内部步长 inline void mma1(const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t kv_head_size, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { #ifdef __AVX2__ + // AVX2 implementation remains unchanged. const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - // 【关键修改】使用传入的 kv_head_size 来计算 V 的步长 const int32_t v_stride_size = kv_head_size * dim_size; #pragma unroll @@ -565,7 +631,6 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { #pragma unroll for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { __m256 w_vec = _mm256_set1_ps(w_block[b_r_idx * Bc + b_c_idx]); - // 【关键修改】使用计算出的 v_stride_size const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; __m256 v_vec = _mm256_loadu_ps(v_ptr); acc = _mm256_fmadd_ps(w_vec, v_vec, acc); @@ -573,7 +638,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -581,17 +646,35 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t v_stride_size = kv_head_size * dim_size; - for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); - for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); - const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - float32x4_t v_vec = vld1q_f32(v_ptr); - acc = vfmaq_f32(acc, w_vec, v_vec); - } - vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + for (int d_base = 0; d_base < dim_size; d_base += 4) { + float32x4_t acc0 = vld1q_f32(acc_o + 0 * dim_size + d_base); + float32x4_t acc1 = vld1q_f32(acc_o + 1 * dim_size + d_base); + float32x4_t acc2 = vld1q_f32(acc_o + 2 * dim_size + d_base); + float32x4_t acc3 = vld1q_f32(acc_o + 3 * dim_size + d_base); + + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + const dtype_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; + float32x4_t v_vec = vld1q_f32(v_ptr); + + float32x4_t w_vec; + + w_vec = vdupq_n_f32(w_block[0 * Bc + b_c_idx]); // P[0][b_c_idx] + acc0 = vfmaq_f32(acc0, v_vec, w_vec); + + w_vec = vdupq_n_f32(w_block[1 * Bc + b_c_idx]); // P[1][b_c_idx] + acc1 = vfmaq_f32(acc1, v_vec, w_vec); + + w_vec = vdupq_n_f32(w_block[2 * Bc + b_c_idx]); // P[2][b_c_idx] + acc2 = vfmaq_f32(acc2, v_vec, w_vec); + + w_vec = vdupq_n_f32(w_block[3 * Bc + b_c_idx]); // P[3][b_c_idx] + acc3 = vfmaq_f32(acc3, v_vec, w_vec); } + + vst1q_f32(acc_o + 0 * dim_size + d_base, acc0); + vst1q_f32(acc_o + 1 * dim_size + d_base, acc1); + vst1q_f32(acc_o + 2 * dim_size + d_base, acc2); + vst1q_f32(acc_o + 3 * dim_size + d_base, acc3); } #endif } @@ -616,17 +699,17 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) for (int i = 0; i < Br; ++i) { dtype_t *o_block_line = o_block + i * head_size * dim_size; - float reciprocal_logsum = 1.0f / logsum[i]; - float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(1.0f / logsum[i]); int j = 0; for (; j <= dim_size - 4; j += 4) { float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); float32x4_t result_vec = vmulq_f32(vec_acc_o, reciprocal_logsum_vec); vst1q_f32(o_block_line + j, result_vec); } + float reciprocal_logsum = 1.0f / logsum[i]; for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } @@ -634,7 +717,6 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { #endif } - // N-fixed functions for handling leftovers inline void mma0_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, @@ -671,32 +753,37 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_r_end = global_r_start + Br_n_fixed; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } - for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { const dtype_t *q_block_line = q_block + b_r_idx * q_stride_size; for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; + float32x4_t sum_vec = vdupq_n_f32(0.0f); - int i = 0; - for (; i <= dim_size - 4; i += 4) { - sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), vld1q_f32(k_block_line + i)); + int k = 0; + for (; k <= dim_size - 4; k += 4) { + float32x4_t q_vec = vld1q_f32(q_block_line + k); + float32x4_t k_vec = vld1q_f32(k_block_line + k); + sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); + } + acc_dtype_t total = vaddvq_f32(sum_vec); + for (; k < dim_size; ++k) { + total += q_block_line[k] * k_block_line[k]; } - acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); - for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } acc_s[b_r_idx * Bc + b_c_idx] = total; } } - - if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { + if (causal_mask) { for (int i = 0; i < Br_n_fixed; ++i) { for (int j = 0; j < Bc_n_fixed; ++j) { - if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + if ((global_c_start + j) > (global_r_start + i + delta_pos)) { + acc_s[i * Bc + j] = NEG_INF; + } } } } @@ -756,7 +843,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + j), scale_v)); } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -798,7 +885,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -808,13 +895,13 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + float32x4_t acc_vec = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - acc = vfmaq_f32(acc, w_vec, vld1q_f32(v_ptr)); + acc_vec = vfmaq_f32(acc_vec, vld1q_f32(v_ptr), w_vec); } - vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc_vec); } } #endif @@ -839,7 +926,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) for (int i = 0; i < Br_n_fixed; ++i) { dtype_t *o_block_line = o_block + i * head_size * dim_size; float reciprocal_logsum = 1.0f / logsum[i]; @@ -864,11 +951,10 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { scoremax[0] = NEG_INF; __m256 zero_vec = _mm256_setzero_ps(); for (int i = 0; i < 1 * dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) logsum[0] = 0.0f; scoremax[0] = NEG_INF; float32x4_t zero_vec = vdupq_n_f32(0.0f); - // Br 在 decode 模式下为 1 for (int i = 0; i < 1 * dim_size; i += 4) { vst1q_f32(acc_o + i, zero_vec); } @@ -893,8 +979,8 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } acc_s[b_c_idx] = total; } -#elif __ARM_NEON__ - const dtype_t *q_block_line = q_block; // q 只有一个向量 +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const dtype_t *q_block_line = q_block; for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { const dtype_t *k_block_line = k_block + b_c_idx * kv_stride_size; float32x4_t sum_vec = vdupq_n_f32(0.0f); @@ -916,6 +1002,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { +#ifdef __AVX2__ scoremax_prev[0] = scoremax[0]; float max_val = NEG_INF; for (int bc = 0; bc < Bc; ++bc) max_val = fmaxf(max_val, acc_s[bc]); @@ -929,6 +1016,40 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } score_sum[0] = current_sum; logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; + +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + scoremax_prev[0] = scoremax[0]; + float32x4_t max_vec = vdupq_n_f32(scoremax[0]); + int bc = 0; + for (; bc <= Bc - 4; bc += 4) { + max_vec = vmaxq_f32(max_vec, vld1q_f32(acc_s + bc)); + } + float max_val = vmaxvq_f32(max_vec); + for (; bc < Bc; ++bc) { + max_val = fmaxf(max_val, acc_s[bc]); + } + scoremax[0] = max_val; + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); + float32x4_t sum_vec = vdupq_n_f32(0.0f); + const float32x4_t sm_vec = vdupq_n_f32(scoremax[0]); + const float32x4_t scale_vec = vdupq_n_f32(scale); + bc = 0; + for (; bc <= Bc - 4; bc += 4) { + float32x4_t s_vec = vld1q_f32(acc_s + bc); + float32x4_t scaled_s_vec = vmulq_f32(vsubq_f32(s_vec, sm_vec), scale_vec); + float32x4_t p_vec = exp_ps_f32(scaled_s_vec); + vst1q_f32(acc_s + bc, p_vec); + sum_vec = vaddq_f32(sum_vec, p_vec); + } + float current_sum = vaddvq_f32(sum_vec); + for (; bc < Bc; ++bc) { + float val = expf((acc_s[bc] - scoremax[0]) * scale); + acc_s[bc] = val; + current_sum += val; + } + score_sum[0] = current_sum; + logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; +#endif } inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, @@ -941,7 +1062,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { acc = _mm256_mul_ps(acc, scale_v); _mm256_storeu_ps(acc_o + j, acc); } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) float32x4_t scale_v = vdupq_n_f32(score_scale[0]); for (int j = 0; j < dim_size; j += 4) { float32x4_t acc = vld1q_f32(acc_o + j); @@ -966,16 +1087,24 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } _mm256_storeu_ps(acc_o + d_base, acc); } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t v_stride_size = kv_head_size * dim_size; - for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + d_base); + int d_base = 0; + for (; d_base <= dim_size - 4; d_base += 4) { + float32x4_t acc_vec = vld1q_f32(acc_o + d_base); for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); const float *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - acc = vfmaq_f32(acc, w_vec, vld1q_f32(v_ptr)); + acc_vec = vfmaq_f32(acc_vec, vld1q_f32(v_ptr), w_vec); } - vst1q_f32(acc_o + d_base, acc); + vst1q_f32(acc_o + d_base, acc_vec); + } + for (; d_base < dim_size; ++d_base) { + float acc = acc_o[d_base]; + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + acc += w_block[b_c_idx] * v_block[b_c_idx * v_stride_size + d_base]; + } + acc_o[d_base] = acc; } #endif } @@ -994,7 +1123,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (; j < dim_size; ++j) { o_block[j] = acc_o[j] * reciprocal_logsum; } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) float reciprocal_logsum = 1.0f / logsum[0]; float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); int j = 0; @@ -1080,11 +1209,7 @@ struct FA_2_GQA_QKV_FP32_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { acc_dtype_t *score_sum_; }; -// ======================================== -// FlashAttention2 核心实现 ( Q FP32/KV FP16 输入,FP32 输出版本) -// ======================================== struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { - // 【修改】定义多种输入类型 using dtype_q_in_t = float; using dtype_kv_in_t = mllm_fp16_t; using dtype_out_t = float; @@ -1122,7 +1247,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { assert(head_size % threads == 0); #ifdef __AVX2__ assert(dim_size % 8 == 0); -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) assert(dim_size % 4 == 0); assert(Q_Head % KV_Head == 0); #endif @@ -1135,9 +1260,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } private: -#if __ARM_NEON__ - // 定义一个宏,用于从内存加载4个fp16, 并转换为一个fp32向量 - // 这需要 ARMv8.2-A FP16 指令支持 +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) #define MLLM_NEON_F32x4_FROM_FP16(addr) vcvt_f32_f16(vld1_f16((const __fp16 *)(addr))) #endif @@ -1155,7 +1278,6 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { -// Note: OpenMP is not applied to the head_size loop in the prefill reference #pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { const int32_t thread_id = omp_get_thread_num(); @@ -1226,7 +1348,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t batch_size, const int32_t head_size, const int32_t seq_size_q, const int32_t seq_size_k, const int32_t dim_size, bool causal_mask = true) { - const int32_t Tr = 1; // In decode, seq_size_q is always 1 + const int32_t Tr = 1; const int32_t Tc = seq_size_k / Bc; const int32_t Tc_left = seq_size_k % Bc; @@ -1240,7 +1362,6 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t this_thread_head = h_idx; const int32_t this_thread_kv_head = this_thread_head / kv_group_size; - // In decode mode, t_r_idx is always 0 as we process one token const int t_r_idx = 0; init_temp_d(logsum_ + thread_id * Br, scoremax_ + thread_id * Br, acc_o_ + thread_id * Br * dim_size, dim_size); for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { @@ -1277,23 +1398,20 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { __m256 zero_vec = _mm256_set1_ps(0.0f); __m256 neg_inf_vec = _mm256_set1_ps(NEG_INF); - // 【最终修正】使用安全的循环来确保完全初始化,不再依赖Br是8的倍数 int i = 0; for (; i <= Br - 8; i += 8) { _mm256_storeu_ps(logsum + i, zero_vec); _mm256_storeu_ps(scoremax + i, neg_inf_vec); } - // 处理剩余的元素(如果Br不是8的倍数) for (; i < Br; ++i) { logsum[i] = 0.0f; scoremax[i] = NEG_INF; } - // acc_o 的初始化是安全的,因为调用者保证了 dim_size % 8 == 0 for (int j = 0; j < Br * dim_size; j += 8) { _mm256_storeu_ps(acc_o + j, zero_vec); } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) float32x4_t zero_vec = vdupq_n_f32(0.0f); float32x4_t neg_inf_vec = vdupq_n_f32(NEG_INF); int i = 0; @@ -1344,232 +1462,91 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_r_end = global_r_start + Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; + if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } - // --- 优化核心 --- - // 策略: 采用4x4微内核,结合深度循环展开,最大化利用NEON指令。 - // - // 步骤 1: 将当前需要的Q块从FP32转换为FP16。 - // 这是为了能够使用最高效的FP16 FMA指令 (vfmlalq_f16)。 - // 使用alignas确保缓冲区内存对齐,有利于SIMD加载。 alignas(16) __fp16 q_f16_buf[Br * dim_size]; - for (int32_t b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - const dtype_q_in_t *q_line_f32 = q_block + b_r_idx * q_stride_size; - __fp16 *q_line_f16 = q_f16_buf + b_r_idx * dim_size; - int d = 0; - // 一次转换8个float - for (; d <= dim_size - 8; d += 8) { - // 加载两组FP32数据 - float32x4_t f32_vec_0 = vld1q_f32(q_line_f32 + d); - float32x4_t f32_vec_1 = vld1q_f32(q_line_f32 + d + 4); - // 转换为一个FP16x8向量并存储 - float16x8_t f16_vec = vcombine_f16(vcvt_f16_f32(f32_vec_0), vcvt_f16_f32(f32_vec_1)); - vst1q_f16(q_line_f16 + d, f16_vec); - } - // 处理末尾不足8个的元素 - for (; d < dim_size; ++d) { - q_line_f16[d] = (__fp16)q_line_f32[d]; - } - } - - const int32_t br_4_end = (Br / 4) * 4; - const int32_t bc_4_end = (Bc / 4) * 4; - - // 步骤 2: 4x4 微内核主循环。处理Br和Bc是4的倍数的部分。 - int32_t b_r_idx = 0; - for (; b_r_idx < br_4_end; b_r_idx += 4) { - int32_t b_c_idx = 0; - for (; b_c_idx < bc_4_end; b_c_idx += 4) { - // 定义 4x4=16 个FP32累加器向量,用于存储中间结果 - float32x4_t acc00, acc01, acc02, acc03; - float32x4_t acc10, acc11, acc12, acc13; - float32x4_t acc20, acc21, acc22, acc23; - float32x4_t acc30, acc31, acc32, acc33; - - // 初始化累加器为0 - acc00 = vdupq_n_f32(0.0f); - acc01 = vdupq_n_f32(0.0f); - acc02 = vdupq_n_f32(0.0f); - acc03 = vdupq_n_f32(0.0f); - acc10 = vdupq_n_f32(0.0f); - acc11 = vdupq_n_f32(0.0f); - acc12 = vdupq_n_f32(0.0f); - acc13 = vdupq_n_f32(0.0f); - acc20 = vdupq_n_f32(0.0f); - acc21 = vdupq_n_f32(0.0f); - acc22 = vdupq_n_f32(0.0f); - acc23 = vdupq_n_f32(0.0f); - acc30 = vdupq_n_f32(0.0f); - acc31 = vdupq_n_f32(0.0f); - acc32 = vdupq_n_f32(0.0f); - acc33 = vdupq_n_f32(0.0f); - - // 获取当前4x4 tile对应的Q和K的行指针 - const __fp16 *q0_ptr = q_f16_buf + (b_r_idx + 0) * dim_size; - const __fp16 *q1_ptr = q_f16_buf + (b_r_idx + 1) * dim_size; - const __fp16 *q2_ptr = q_f16_buf + (b_r_idx + 2) * dim_size; - const __fp16 *q3_ptr = q_f16_buf + (b_r_idx + 3) * dim_size; - - const __fp16 *k0_ptr = (const __fp16 *)k_block + (b_c_idx + 0) * kv_stride_size; - const __fp16 *k1_ptr = (const __fp16 *)k_block + (b_c_idx + 1) * kv_stride_size; - const __fp16 *k2_ptr = (const __fp16 *)k_block + (b_c_idx + 2) * kv_stride_size; - const __fp16 *k3_ptr = (const __fp16 *)k_block + (b_c_idx + 3) * kv_stride_size; - - // 沿向量维度 (dim_size) 进行循环计算 - int k = 0; - // 深度展开,一次处理8个元素 (float16x8_t) - for (; k <= dim_size - 8; k += 8) { - // 数据预取,减少内存访问延迟 - __builtin_prefetch(q0_ptr + k + 64); - __builtin_prefetch(q1_ptr + k + 64); - __builtin_prefetch(k0_ptr + k + 64); - __builtin_prefetch(k1_ptr + k + 64); - - // 加载4行Q的数据 - float16x8_t q0_vec = vld1q_f16(q0_ptr + k); - float16x8_t q1_vec = vld1q_f16(q1_ptr + k); - float16x8_t q2_vec = vld1q_f16(q2_ptr + k); - float16x8_t q3_vec = vld1q_f16(q3_ptr + k); - - // 加载K并进行外积计算 - float16x8_t k0_vec = vld1q_f16(k0_ptr + k); - acc00 = vfmlalq_low_f16(acc00, q0_vec, k0_vec); - acc00 = vfmlalq_high_f16(acc00, q0_vec, k0_vec); - acc10 = vfmlalq_low_f16(acc10, q1_vec, k0_vec); - acc10 = vfmlalq_high_f16(acc10, q1_vec, k0_vec); - acc20 = vfmlalq_low_f16(acc20, q2_vec, k0_vec); - acc20 = vfmlalq_high_f16(acc20, q2_vec, k0_vec); - acc30 = vfmlalq_low_f16(acc30, q3_vec, k0_vec); - acc30 = vfmlalq_high_f16(acc30, q3_vec, k0_vec); - - float16x8_t k1_vec = vld1q_f16(k1_ptr + k); - acc01 = vfmlalq_low_f16(acc01, q0_vec, k1_vec); - acc01 = vfmlalq_high_f16(acc01, q0_vec, k1_vec); - acc11 = vfmlalq_low_f16(acc11, q1_vec, k1_vec); - acc11 = vfmlalq_high_f16(acc11, q1_vec, k1_vec); - acc21 = vfmlalq_low_f16(acc21, q2_vec, k1_vec); - acc21 = vfmlalq_high_f16(acc21, q2_vec, k1_vec); - acc31 = vfmlalq_low_f16(acc31, q3_vec, k1_vec); - acc31 = vfmlalq_high_f16(acc31, q3_vec, k1_vec); - - float16x8_t k2_vec = vld1q_f16(k2_ptr + k); - acc02 = vfmlalq_low_f16(acc02, q0_vec, k2_vec); - acc02 = vfmlalq_high_f16(acc02, q0_vec, k2_vec); - acc12 = vfmlalq_low_f16(acc12, q1_vec, k2_vec); - acc12 = vfmlalq_high_f16(acc12, q1_vec, k2_vec); - acc22 = vfmlalq_low_f16(acc22, q2_vec, k2_vec); - acc22 = vfmlalq_high_f16(acc22, q2_vec, k2_vec); - acc32 = vfmlalq_low_f16(acc32, q3_vec, k2_vec); - acc32 = vfmlalq_high_f16(acc32, q3_vec, k2_vec); - - float16x8_t k3_vec = vld1q_f16(k3_ptr + k); - acc03 = vfmlalq_low_f16(acc03, q0_vec, k3_vec); - acc03 = vfmlalq_high_f16(acc03, q0_vec, k3_vec); - acc13 = vfmlalq_low_f16(acc13, q1_vec, k3_vec); - acc13 = vfmlalq_high_f16(acc13, q1_vec, k3_vec); - acc23 = vfmlalq_low_f16(acc23, q2_vec, k3_vec); - acc23 = vfmlalq_high_f16(acc23, q2_vec, k3_vec); - acc33 = vfmlalq_low_f16(acc33, q3_vec, k3_vec); - acc33 = vfmlalq_high_f16(acc33, q3_vec, k3_vec); - } - - // 水平求和,将向量累加器中的4个float相加,得到最终的16个标量结果 - float *c_ptr; - c_ptr = acc_s + (b_r_idx + 0) * Bc + b_c_idx; - c_ptr[0] = vaddvq_f32(acc00); - c_ptr[1] = vaddvq_f32(acc01); - c_ptr[2] = vaddvq_f32(acc02); - c_ptr[3] = vaddvq_f32(acc03); - c_ptr = acc_s + (b_r_idx + 1) * Bc + b_c_idx; - c_ptr[0] = vaddvq_f32(acc10); - c_ptr[1] = vaddvq_f32(acc11); - c_ptr[2] = vaddvq_f32(acc12); - c_ptr[3] = vaddvq_f32(acc13); - c_ptr = acc_s + (b_r_idx + 2) * Bc + b_c_idx; - c_ptr[0] = vaddvq_f32(acc20); - c_ptr[1] = vaddvq_f32(acc21); - c_ptr[2] = vaddvq_f32(acc22); - c_ptr[3] = vaddvq_f32(acc23); - c_ptr = acc_s + (b_r_idx + 3) * Bc + b_c_idx; - c_ptr[0] = vaddvq_f32(acc30); - c_ptr[1] = vaddvq_f32(acc31); - c_ptr[2] = vaddvq_f32(acc32); - c_ptr[3] = vaddvq_f32(acc33); - - // 处理末尾不足8个的元素 - for (; k < dim_size; ++k) { - acc_s[(b_r_idx + 0) * Bc + b_c_idx + 0] += (float)q0_ptr[k] * (float)k0_ptr[k]; - acc_s[(b_r_idx + 0) * Bc + b_c_idx + 1] += (float)q0_ptr[k] * (float)k1_ptr[k]; - acc_s[(b_r_idx + 0) * Bc + b_c_idx + 2] += (float)q0_ptr[k] * (float)k2_ptr[k]; - acc_s[(b_r_idx + 0) * Bc + b_c_idx + 3] += (float)q0_ptr[k] * (float)k3_ptr[k]; - - acc_s[(b_r_idx + 1) * Bc + b_c_idx + 0] += (float)q1_ptr[k] * (float)k0_ptr[k]; - acc_s[(b_r_idx + 1) * Bc + b_c_idx + 1] += (float)q1_ptr[k] * (float)k1_ptr[k]; - acc_s[(b_r_idx + 1) * Bc + b_c_idx + 2] += (float)q1_ptr[k] * (float)k2_ptr[k]; - acc_s[(b_r_idx + 1) * Bc + b_c_idx + 3] += (float)q1_ptr[k] * (float)k3_ptr[k]; - - acc_s[(b_r_idx + 2) * Bc + b_c_idx + 0] += (float)q2_ptr[k] * (float)k0_ptr[k]; - acc_s[(b_r_idx + 2) * Bc + b_c_idx + 1] += (float)q2_ptr[k] * (float)k1_ptr[k]; - acc_s[(b_r_idx + 2) * Bc + b_c_idx + 2] += (float)q2_ptr[k] * (float)k2_ptr[k]; - acc_s[(b_r_idx + 2) * Bc + b_c_idx + 3] += (float)q2_ptr[k] * (float)k3_ptr[k]; - - acc_s[(b_r_idx + 3) * Bc + b_c_idx + 0] += (float)q3_ptr[k] * (float)k0_ptr[k]; - acc_s[(b_r_idx + 3) * Bc + b_c_idx + 1] += (float)q3_ptr[k] * (float)k1_ptr[k]; - acc_s[(b_r_idx + 3) * Bc + b_c_idx + 2] += (float)q3_ptr[k] * (float)k2_ptr[k]; - acc_s[(b_r_idx + 3) * Bc + b_c_idx + 3] += (float)q3_ptr[k] * (float)k3_ptr[k]; - } + for (int32_t i = 0; i < Br; ++i) { + const float *q_line_f32 = q_block + i * q_stride_size; + __fp16 *q_line_f16 = q_f16_buf + i * dim_size; + for (int j = 0; j < dim_size; ++j) { + q_line_f16[j] = (__fp16)q_line_f32[j]; } } - // 步骤 3: Fallback - 处理所有剩余的行和列。 - // 这部分确保了即使Br, Bc不是4的倍数,计算依然正确。 - for (b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - // 如果行已经被4x4内核处理过,则只处理剩余的列 - if (b_r_idx < br_4_end) { - for (int32_t b_c_idx = bc_4_end; b_c_idx < Bc; ++b_c_idx) { - const __fp16 *q_f16_line = q_f16_buf + b_r_idx * dim_size; - const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; - float32x4_t sum_vec = vdupq_n_f32(0.0f); - int i = 0; - for (; i <= dim_size - 8; i += 8) { - float16x8_t q_vec = vld1q_f16(q_f16_line + i); - float16x8_t k_vec = vld1q_f16((const __fp16 *)k_block_line + i); - sum_vec = vfmlalq_low_f16(sum_vec, q_vec, k_vec); - sum_vec = vfmlalq_high_f16(sum_vec, q_vec, k_vec); + for (int32_t b_r_base = 0; b_r_base < Br; b_r_base += 4) { + for (int32_t b_c_base = 0; b_c_base < Bc; b_c_base += 4) { + const __fp16 *q_base_ptr = q_f16_buf + b_r_base * dim_size; + const __fp16 *k_base_ptr = (const __fp16 *)k_block + b_c_base * kv_stride_size; + float *acc_s_base_ptr = acc_s + b_r_base * Bc + b_c_base; + +#pragma unroll + for (int32_t b_r_offset = 0; b_r_offset < 4; ++b_r_offset) { + const __fp16 *q_row = q_base_ptr + b_r_offset * dim_size; + + const __fp16 *k_row0 = k_base_ptr + 0 * kv_stride_size; + const __fp16 *k_row1 = k_base_ptr + 1 * kv_stride_size; + const __fp16 *k_row2 = k_base_ptr + 2 * kv_stride_size; + const __fp16 *k_row3 = k_base_ptr + 3 * kv_stride_size; + + float32x4_t sum0 = vdupq_n_f32(0.0f); + float32x4_t sum1 = vdupq_n_f32(0.0f); + float32x4_t sum2 = vdupq_n_f32(0.0f); + float32x4_t sum3 = vdupq_n_f32(0.0f); + + int32_t k = 0; + for (; k <= dim_size - 8; k += 8) { + float16x8_t q_vec = vld1q_f16(q_row + k); + + float16x8_t k_vec0 = vld1q_f16(k_row0 + k); + sum0 = vfmlalq_low_f16(sum0, q_vec, k_vec0); + sum0 = vfmlalq_high_f16(sum0, q_vec, k_vec0); + + float16x8_t k_vec1 = vld1q_f16(k_row1 + k); + sum1 = vfmlalq_low_f16(sum1, q_vec, k_vec1); + sum1 = vfmlalq_high_f16(sum1, q_vec, k_vec1); + + float16x8_t k_vec2 = vld1q_f16(k_row2 + k); + sum2 = vfmlalq_low_f16(sum2, q_vec, k_vec2); + sum2 = vfmlalq_high_f16(sum2, q_vec, k_vec2); + + float16x8_t k_vec3 = vld1q_f16(k_row3 + k); + sum3 = vfmlalq_low_f16(sum3, q_vec, k_vec3); + sum3 = vfmlalq_high_f16(sum3, q_vec, k_vec3); } - acc_dtype_t total = vaddvq_f32(sum_vec); - for (; i < dim_size; ++i) { total += (float)q_f16_line[i] * (float)k_block_line[i]; } - acc_s[b_r_idx * Bc + b_c_idx] = total; - } - } else { // 否则,处理整行 - for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - const __fp16 *q_f16_line = q_f16_buf + b_r_idx * dim_size; - const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; - float32x4_t sum_vec = vdupq_n_f32(0.0f); - int i = 0; - for (; i <= dim_size - 8; i += 8) { - float16x8_t q_vec = vld1q_f16(q_f16_line + i); - float16x8_t k_vec = vld1q_f16((const __fp16 *)k_block_line + i); - sum_vec = vfmlalq_low_f16(sum_vec, q_vec, k_vec); - sum_vec = vfmlalq_high_f16(sum_vec, q_vec, k_vec); + + float total0 = vaddvq_f32(sum0); + float total1 = vaddvq_f32(sum1); + float total2 = vaddvq_f32(sum2); + float total3 = vaddvq_f32(sum3); + + for (; k < dim_size; ++k) { + total0 += (float)q_row[k] * (float)k_row0[k]; + total1 += (float)q_row[k] * (float)k_row1[k]; + total2 += (float)q_row[k] * (float)k_row2[k]; + total3 += (float)q_row[k] * (float)k_row3[k]; } - acc_dtype_t total = vaddvq_f32(sum_vec); - for (; i < dim_size; ++i) { total += (float)q_f16_line[i] * (float)k_block_line[i]; } - acc_s[b_r_idx * Bc + b_c_idx] = total; + + float *acc_s_row = acc_s_base_ptr + b_r_offset * Bc; + acc_s_row[0] = total0; + acc_s_row[1] = total1; + acc_s_row[2] = total2; + acc_s_row[3] = total3; } } } - // 步骤 4: 应用因果掩码 (逻辑保持不变) - if (causal_mask && (global_r_end == (t_c_idx * Bc + Bc) - delta_pos)) { + if (causal_mask) { for (int i = 0; i < Br; ++i) { for (int j = 0; j < Bc; ++j) { - if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + if ((global_c_start + j) > (global_r_start + i + delta_pos)) { + acc_s[i * Bc + j] = NEG_INF; + } } } } @@ -1595,7 +1572,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (; bc < Bc; ++bc) { max_val = fmaxf(max_val, row[bc]); } scoremax[br] = max_val; } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) for (int br = 0; br < Br; ++br) { float32x4_t max_vec = vdupq_n_f32(scoremax[br]); acc_dtype_t *row = acc_s + br * Bc; @@ -1639,7 +1616,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(row_ptr + j, acc); } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -1678,33 +1655,59 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br - 1))) return; - const int32_t v_stride_size = kv_head_size * dim_size; - // 循环结构 (Br, dim_size, Bc) 对 acc_o 的读写更友好 - for (int b_r_idx = 0; b_r_idx < Br; ++b_r_idx) { - for (int d_base = 0; d_base < dim_size; d_base += 4) { - // 加载128位的FP32累加器 - float32x4_t acc_vec = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); - for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { - // 从w_block直接读取FP32的P标量 - const float p_scalar_f32 = w_block[b_r_idx * Bc + b_c_idx]; - // 将FP32标量广播为一个128位向量 - const float32x4_t p_vec_f32 = vdupq_n_f32(p_scalar_f32); - // 加载FP16的V向量 - const __fp16 *v_ptr = (const __fp16 *)v_block + b_c_idx * v_stride_size + d_base; - const float16x4_t v_vec_f16 = vld1_f16(v_ptr); - // 将V向量从FP16转换为FP32 - const float32x4_t v_vec_f32 = vcvt_f32_f16(v_vec_f16); - // 执行FP32的融合乘加 - acc_vec = vfmaq_f32(acc_vec, p_vec_f32, v_vec_f32); - } - // 将结果写回内存 - vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc_vec); + + alignas(16) __fp16 w_f16_buf[Br * Bc]; + for (int i = 0; i < Br * Bc; ++i) { + w_f16_buf[i] = (__fp16)w_block[i]; + } + + const int32_t v_stride = kv_head_size * dim_size; + for (int d_base = 0; d_base < dim_size; d_base += 8) { + float32x4_t acc0[2], acc1[2], acc2[2], acc3[2]; + + acc0[0] = vld1q_f32(acc_o + 0 * dim_size + d_base); + acc0[1] = vld1q_f32(acc_o + 0 * dim_size + d_base + 4); + acc1[0] = vld1q_f32(acc_o + 1 * dim_size + d_base); + acc1[1] = vld1q_f32(acc_o + 1 * dim_size + d_base + 4); + acc2[0] = vld1q_f32(acc_o + 2 * dim_size + d_base); + acc2[1] = vld1q_f32(acc_o + 2 * dim_size + d_base + 4); + acc3[0] = vld1q_f32(acc_o + 3 * dim_size + d_base); + acc3[1] = vld1q_f32(acc_o + 3 * dim_size + d_base + 4); + +#pragma unroll + for (int k_inner = 0; k_inner < Bc; ++k_inner) { + const float16x8_t v_vec = vld1q_f16((const __fp16 *)v_block + k_inner * v_stride + d_base); + + const float16x8_t w0_vec = vdupq_n_f16(w_f16_buf[0 * Bc + k_inner]); + acc0[0] = vfmlalq_low_f16(acc0[0], v_vec, w0_vec); + acc0[1] = vfmlalq_high_f16(acc0[1], v_vec, w0_vec); + + const float16x8_t w1_vec = vdupq_n_f16(w_f16_buf[1 * Bc + k_inner]); + acc1[0] = vfmlalq_low_f16(acc1[0], v_vec, w1_vec); + acc1[1] = vfmlalq_high_f16(acc1[1], v_vec, w1_vec); + + const float16x8_t w2_vec = vdupq_n_f16(w_f16_buf[2 * Bc + k_inner]); + acc2[0] = vfmlalq_low_f16(acc2[0], v_vec, w2_vec); + acc2[1] = vfmlalq_high_f16(acc2[1], v_vec, w2_vec); + + const float16x8_t w3_vec = vdupq_n_f16(w_f16_buf[3 * Bc + k_inner]); + acc3[0] = vfmlalq_low_f16(acc3[0], v_vec, w3_vec); + acc3[1] = vfmlalq_high_f16(acc3[1], v_vec, w3_vec); } + + vst1q_f32(acc_o + 0 * dim_size + d_base, acc0[0]); + vst1q_f32(acc_o + 0 * dim_size + d_base + 4, acc0[1]); + vst1q_f32(acc_o + 1 * dim_size + d_base, acc1[0]); + vst1q_f32(acc_o + 1 * dim_size + d_base + 4, acc1[1]); + vst1q_f32(acc_o + 2 * dim_size + d_base, acc2[0]); + vst1q_f32(acc_o + 2 * dim_size + d_base + 4, acc2[1]); + vst1q_f32(acc_o + 3 * dim_size + d_base, acc3[0]); + vst1q_f32(acc_o + 3 * dim_size + d_base + 4, acc3[1]); } #endif } @@ -1712,11 +1715,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { inline void scale_and_store(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { - // (无变化,输出O是fp32) for (int i = 0; i < Br; ++i) { - // 【修正】这里的 o_block_line 计算是错误的,它没有正确处理 BSHD 布局下的行步进 - // 正确的行步进已经由外层循环的 o_block 指针计算好了 - // 我们只需要在此基础上按行写入即可 dtype_out_t *o_block_line = o_block + i * head_size * dim_size; // << 保持 BSHD 的行步长 #ifdef __AVX2__ __m256 reciprocal_logsum_vec = _mm256_set1_ps(1.0f / logsum[i]); @@ -1728,14 +1727,20 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } float reciprocal_logsum = 1.0f / logsum[i]; for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } -#elif __ARM_NEON__ - float32x4_t reciprocal_logsum_vec = vdupq_n_f32(1.0f / logsum[i]); - int j = 0; - for (; j <= dim_size - 4; j += 4) { - vst1q_f32(o_block_line + j, vmulq_f32(vld1q_f32(acc_o + i * dim_size + j), reciprocal_logsum_vec)); +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + for (int i = 0; i < Br; ++i) { + dtype_out_t *o_block_line = o_block + i * head_size * dim_size; + float reciprocal_logsum = 1.0f / logsum[i]; + float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); + int j = 0; + for (; j <= dim_size - 4; j += 4) { + float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); + vst1q_f32(o_block_line + j, vmulq_f32(vec_acc_o, reciprocal_logsum_vec)); + } + for (; j < dim_size; ++j) { + o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; + } } - float reciprocal_logsum = 1.0f / logsum[i]; - for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } #endif } } @@ -1773,8 +1778,9 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } } -#elif __ARM_NEON__ - const int32_t global_r_start = t_r_idx * Br, global_r_end = global_r_start + Br_n_fixed; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const int32_t global_r_start = t_r_idx * Br; + const int32_t global_r_end = global_r_start + Br_n_fixed; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; if (causal_mask && (global_c_start - delta_pos > (global_r_end - 1))) { return; } @@ -1785,17 +1791,23 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { float32x4_t sum_vec = vdupq_n_f32(0.0f); int i = 0; for (; i <= dim_size - 4; i += 4) { - sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), MLLM_NEON_F32x4_FROM_FP16(k_block_line + i)); + float32x4_t q_vec = vld1q_f32(q_block_line + i); + float32x4_t k_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)k_block_line + i)); + sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); + } + acc_dtype_t total = vaddvq_f32(sum_vec); + for (; i < dim_size; ++i) { + total += q_block_line[i] * (float)k_block_line[i]; } - acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); - for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } acc_s[b_r_idx * Bc + b_c_idx] = total; } } - if (causal_mask && (global_r_end == (global_c_start + Bc_n_fixed) - delta_pos)) { + if (causal_mask) { for (int i = 0; i < Br_n_fixed; ++i) { for (int j = 0; j < Bc_n_fixed; ++j) { - if (j > i) { acc_s[i * Bc + j] = NEG_INF; } + if ((global_c_start + j) > (global_r_start + i + delta_pos)) { + acc_s[i * Bc + j] = NEG_INF; + } } } } @@ -1814,26 +1826,32 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { if (causal_mask && (global_c_start - delta_pos > (global_r_start + Br_n_fixed - 1))) return; memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); for (int br = 0; br < Br_n_fixed; ++br) { + float max_val = scoremax[br]; acc_dtype_t *row = acc_s + br * Bc; - float max_val = NEG_INF; - for (int bc = 0; bc < Bc_n_fixed; ++bc) max_val = fmaxf(max_val, row[bc]); - scoremax[br] = fmaxf(max_val, scoremax[br]); + for (int bc = 0; bc < Bc_n_fixed; ++bc) { + max_val = fmaxf(max_val, row[bc]); + } + scoremax[br] = max_val; } - for (int br = 0; br < Br_n_fixed; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } for (int br = 0; br < Br_n_fixed; ++br) { + score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); + } + for (int br = 0; br < Br_n_fixed; ++br) { + const float sm = scoremax[br]; acc_dtype_t *row = acc_s + br * Bc; float current_sum = 0.0f; for (int bc = 0; bc < Bc_n_fixed; ++bc) { - float val = expf((row[bc] - scoremax[br]) * scale); + float val = expf((row[bc] - sm) * scale); row[bc] = val; current_sum += val; } score_sum[br] = current_sum; } - for (int br = 0; br < Br_n_fixed; ++br) { logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; } + for (int br = 0; br < Br_n_fixed; ++br) { + logsum[br] = logsum[br] * score_scale[br] + score_sum[br]; + } } - // (无变化) inline void rescale_pa_n_fixed(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, @@ -1850,7 +1868,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + j), scale_v)); } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -1887,7 +1905,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; int delta_pos = seq_size_k - seq_size_q; @@ -1895,13 +1913,14 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const int32_t v_stride_size = kv_head_size * dim_size; for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); + float32x4_t acc_vec = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { float32x4_t w_vec = vdupq_n_f32(w_block[b_r_idx * Bc + b_c_idx]); const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); + float32x4_t v_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)v_ptr)); + acc_vec = vfmaq_f32(acc_vec, v_vec, w_vec); } - vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); + vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc_vec); } } #endif @@ -1911,8 +1930,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { for (int i = 0; i < Br_n_fixed; ++i) { - // 【修正】同上,这里的行步进计算也是错误的 - dtype_out_t *o_block_line = o_block + i * head_size * dim_size; // << 保持 BSHD 的行步长 + dtype_out_t *o_block_line = o_block + i * head_size * dim_size; #ifdef __AVX2__ float reciprocal_logsum = 1.0f / logsum[i]; __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); @@ -1922,7 +1940,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { _mm256_storeu_ps(o_block_line + j, _mm256_mul_ps(vec_acc_o, reciprocal_logsum_vec)); } for (; j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) float reciprocal_logsum = 1.0f / logsum[i]; float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); int j = 0; @@ -1935,14 +1953,13 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } } - // (此函数无变化,但为完整性一并提供) inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { logsum[0] = 0.0f; scoremax[0] = NEG_INF; #ifdef __AVX2__ __m256 zero_vec = _mm256_setzero_ps(); for (int i = 0; i < 1 * dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) float32x4_t zero_vec = vdupq_n_f32(0.0f); for (int i = 0; i < 1 * dim_size; i += 4) { vst1q_f32(acc_o + i, zero_vec); } #endif @@ -1965,17 +1982,16 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } acc_s[b_c_idx] = total; } -#elif __ARM_NEON__ - const dtype_q_in_t *q_block_line = q_block; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) for (int32_t b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { const dtype_kv_in_t *k_block_line = k_block + b_c_idx * kv_stride_size; float32x4_t sum_vec = vdupq_n_f32(0.0f); int i = 0; for (; i <= dim_size - 4; i += 4) { - sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block_line + i), MLLM_NEON_F32x4_FROM_FP16(k_block_line + i)); + sum_vec = vfmaq_f32(sum_vec, vld1q_f32(q_block + i), vcvt_f32_f16(vld1_f16((const __fp16 *)k_block_line + i))); } - acc_dtype_t total = _vaddvq_f32_hadd(sum_vec); - for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } + acc_dtype_t total = vaddvq_f32(sum_vec); + for (; i < dim_size; ++i) { total += q_block[i] * (float)k_block_line[i]; } acc_s[b_c_idx] = total; } #endif @@ -2001,7 +2017,6 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; } - // (此函数无变化,但为完整性一并提供) inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, const int32_t seq_size_q, const int32_t seq_size_k, bool causal_mask) { @@ -2012,7 +2027,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { acc = _mm256_mul_ps(acc, scale_v); _mm256_storeu_ps(acc_o + j, acc); } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) float32x4_t scale_v = vdupq_n_f32(score_scale[0]); for (int j = 0; j < dim_size; j += 4) { vst1q_f32(acc_o + j, vmulq_f32(vld1q_f32(acc_o + j), scale_v)); @@ -2036,34 +2051,41 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { } _mm256_storeu_ps(acc_o + d_base, acc); } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) const int32_t v_stride_size = kv_head_size * dim_size; - for (int d_base = 0; d_base < dim_size; d_base += 4) { - float32x4_t acc = vld1q_f32(acc_o + d_base); + int d_base = 0; + for (; d_base <= dim_size - 4; d_base += 4) { + float32x4_t acc_vec = vld1q_f32(acc_o + d_base); for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); - const dtype_kv_in_t *v_ptr = v_block + b_c_idx * v_stride_size + d_base; - acc = vfmaq_f32(acc, w_vec, MLLM_NEON_F32x4_FROM_FP16(v_ptr)); + const __fp16 *v_ptr = (const __fp16 *)v_block + b_c_idx * v_stride_size + d_base; + acc_vec = vfmaq_f32(acc_vec, vcvt_f32_f16(vld1_f16(v_ptr)), w_vec); } - vst1q_f32(acc_o + d_base, acc); + vst1q_f32(acc_o + d_base, acc_vec); + } + for (; d_base < dim_size; ++d_base) { + float acc = acc_o[d_base]; + for (int b_c_idx = 0; b_c_idx < Bc; ++b_c_idx) { + acc += w_block[b_c_idx] * (float)v_block[b_c_idx * v_stride_size + d_base]; + } + acc_o[d_base] = acc; } #endif } - // (此函数无变化,但为完整性一并提供) + inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, const int32_t t_r_idx, const int32_t head_size, const int32_t dim_size) { float reciprocal_logsum = 1.0f / logsum[0]; + int j = 0; #ifdef __AVX2__ __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); - int j = 0; for (; j <= dim_size - 8; j += 8) { _mm256_storeu_ps(o_block + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), reciprocal_logsum_vec)); } -#elif __ARM_NEON__ +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); - int j = 0; for (; j <= dim_size - 4; j += 4) { vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); } @@ -2108,7 +2130,6 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; } - // (此函数无变化,但为完整性一并提供) inline void rescale_d_n_fixed(const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size, const int32_t t_r_idx, const int32_t t_c_idx, @@ -2127,7 +2148,6 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { for (int d_base = 0; d_base < dim_size; ++d_base) { float acc = acc_o[d_base]; for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - // Scalar fallback for leftover dimensions acc += w_block[b_c_idx] * MLLM_FP16_TO_FP32(v_block[b_c_idx * v_stride_size + d_base]); } acc_o[d_base] = acc; @@ -2145,8 +2165,6 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BSHD_O_FP32_BSHD_ACC_FP32_IMPL { acc_dtype_t *score_sum_; }; -// ======================================== -// 【修改】统一的FlashAttention2接口,改为模板以支持不同实现 template struct FlashAttn2T { public: @@ -2180,12 +2198,10 @@ struct FlashAttn2T { class WorkspaceManager { public: - // 构造函数:初始化所有指针和大小 WorkspaceManager() : workspace_{}, current_sizes_{} { } - // 析构函数:在线程退出时自动释放所有内存,防止内存泄漏 ~WorkspaceManager() { for (int i = 0; i < 7; ++i) { if (workspace_[i]) { @@ -2194,18 +2210,13 @@ class WorkspaceManager { } } - // 获取工作空间的核心函数 void **get_workspace(const size_t *required_sizes) { for (int i = 0; i < 7; ++i) { - // 如果需要的尺寸大于当前分配的尺寸,则重新分配 if (required_sizes[i] > current_sizes_[i]) { - // 释放旧的(如果存在) if (workspace_[i]) { aligned_free(workspace_[i]); } - // 分配新的 aligned_alloc(&workspace_[i], required_sizes[i], 32); - // 更新当前尺寸 current_sizes_[i] = required_sizes[i]; } } @@ -2213,7 +2224,6 @@ class WorkspaceManager { } private: - // 禁止拷贝和赋值,确保每个实例的唯一性 WorkspaceManager(const WorkspaceManager &) = delete; WorkspaceManager &operator=(const WorkspaceManager &) = delete; @@ -2223,71 +2233,6 @@ class WorkspaceManager { } // namespace mobi_attn -/* -void flash_attention_2_forward( - const void *Q, const void *K, const void *V, void *O, - int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, - bool causal_mask, bool use_fp32, int32_t threads, int32_t br, int32_t bc, - int32_t q_head, int32_t kv_head, bool high_precision_exp) { - // 工作空间大小与输入数据类型无关,因为内部累加器总是float32 - // acc_s_cast is no longer needed as the intermediate softmax result is kept in float32 - const size_t acc_o_size = threads * br * dim_size * sizeof(float); - const size_t acc_s_size = threads * br * bc * sizeof(float); - const size_t logsum_size = threads * br * sizeof(float); - const size_t scoremax_size = threads * br * sizeof(float); - const size_t scoremax_prev_size = threads * br * sizeof(float); - const size_t score_scale_size = threads * br * sizeof(float); - const size_t score_sum_size = threads * br * sizeof(float); - - // 分配对齐的工作空间 - void *workspace[7]; - mobi_attn::aligned_alloc(&workspace[0], acc_o_size, 32); - mobi_attn::aligned_alloc(&workspace[1], acc_s_size, 32); - mobi_attn::aligned_alloc(&workspace[2], logsum_size, 32); - mobi_attn::aligned_alloc(&workspace[3], scoremax_size, 32); - mobi_attn::aligned_alloc(&workspace[4], scoremax_prev_size, 32); - mobi_attn::aligned_alloc(&workspace[5], score_scale_size, 32); - mobi_attn::aligned_alloc(&workspace[6], score_sum_size, 32); - - if (use_fp32) { - // 使用纯FP32实现 - mobi_attn::FlashAttn2T op; - op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); - - op.init_workspace( - static_cast(workspace[0]), static_cast(workspace[1]), - static_cast(workspace[2]), static_cast(workspace[3]), - static_cast(workspace[4]), static_cast(workspace[5]), - static_cast(workspace[6])); - - op(static_cast(Q), static_cast(K), static_cast(V), - static_cast(O), - batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); - } else { - // 使用FP16输入,FP32输出的实现 - mobi_attn::FlashAttn2T op; - op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); - - op.init_workspace( - static_cast(workspace[0]), static_cast(workspace[1]), - static_cast(workspace[2]), static_cast(workspace[3]), - static_cast(workspace[4]), static_cast(workspace[5]), - static_cast(workspace[6])); - - op(static_cast(Q), static_cast(K), static_cast(V), - static_cast(O), - batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); - } - - for (void *ptr : workspace) { - if (ptr) mobi_attn::aligned_free(ptr); - } -} -*/ -// 文件位置: FlashAttention2.hpp -// 这是文件最末尾的函数 - -// 【替换此函数】 void flash_attention_2_forward( const void *Q, const void *K, const void *V, void *O, int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, @@ -2295,7 +2240,6 @@ void flash_attention_2_forward( int32_t q_head, int32_t kv_head, bool high_precision_exp) { thread_local mobi_attn::WorkspaceManager manager; - // 计算当前调用所需的各个工作空间大小 const size_t acc_o_size = threads * br * dim_size * sizeof(float); const size_t acc_s_size = threads * br * bc * sizeof(float); const size_t logsum_size = threads * br * sizeof(float); @@ -2308,12 +2252,9 @@ void flash_attention_2_forward( acc_o_size, acc_s_size, logsum_size, scoremax_size, scoremax_prev_size, score_scale_size, score_sum_size}; - // 【修改2】通过 manager 获取工作空间指针 - // manager 会自动处理内存的复用和按需重新分配 void **workspace = manager.get_workspace(required_sizes); if (use_fp32) { - // 使用纯FP32实现 mobi_attn::FlashAttn2T op; op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); @@ -2327,7 +2268,6 @@ void flash_attention_2_forward( static_cast(O), batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask); } else { - // 使用FP16输入,FP32输出的实现 mobi_attn::FlashAttn2T op; op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); diff --git a/src/backends/cpu/compute/FlashAttention2H.hpp b/src/backends/cpu/compute/FlashAttention2H.hpp index c4f75f1c8..d7e00377c 100644 --- a/src/backends/cpu/compute/FlashAttention2H.hpp +++ b/src/backends/cpu/compute/FlashAttention2H.hpp @@ -8,7 +8,8 @@ #include #include #include "Types.hpp" -#include "VecDot.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" +#include "backends/cpu/third_party/ggml/ComputeUtils.hpp" // 平台相关的头文件和宏定义 #ifdef __AVX2__ @@ -68,7 +69,6 @@ inline void platform_aligned_free(void *ptr) { free(ptr); } - namespace mobi_attn { // ======================================== @@ -126,11 +126,11 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { assert(Br == Bc); assert(Q_Head % KV_Head == 0); assert(head_size % threads == 0); - #ifdef __AVX2__ +#ifdef __AVX2__ assert(dim_size % 8 == 0); - #elif __ARM_NEON +#elif __ARM_NEON assert(dim_size % 4 == 0); - #endif +#endif if (seq_size_q != 1) { __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, q_head_skp, k_head_skp, v_head_skp); @@ -171,7 +171,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { const int32_t Bc_n_fixed = (t_c_idx == Tc - 1) ? (seq_size_k - t_c_idx * Bc) : Bc; - + const dtype_t *tile_q = q_batch_base + this_thread_head * q_head_skp + t_r_idx * Br * dim_size; const dtype_t *tile_k = k_batch_base + this_thread_kv_head * k_head_skp + t_c_idx * Bc * dim_size; const dtype_t *tile_v = v_batch_base + this_thread_kv_head * v_head_skp + t_c_idx * Bc * dim_size; @@ -184,8 +184,8 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { rescale(Br_n_fixed, acc_o, score_scale_ + thread_id * Br, dim_size); mma1(Br_n_fixed, Bc_n_fixed, tile_acc_s, tile_v, acc_o, dim_size); } - - dtype_t* o_block_ptr = o_batch_base + this_thread_head * q_head_skp + t_r_idx * Br * dim_size; + + dtype_t *o_block_ptr = o_batch_base + this_thread_head * q_head_skp + t_r_idx * Br * dim_size; scale_and_store(Br_n_fixed, acc_o_ + thread_id * Br * dim_size, logsum_ + thread_id * Br, o_block_ptr, dim_size); } } @@ -209,9 +209,9 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { const int32_t thread_id = omp_get_thread_num(); const int32_t this_thread_head = h_idx; const int32_t this_thread_kv_head = this_thread_head / kv_group_size; - + init_temp_d(logsum_ + thread_id, scoremax_ + thread_id, acc_o_ + thread_id * dim_size, dim_size); - + const dtype_t *q_batch_base = Q + b_idx * head_size * q_head_skp; const dtype_t *k_batch_base = K + b_idx * KV_Head * k_head_skp; const dtype_t *v_batch_base = V + b_idx * KV_Head * v_head_skp; @@ -219,7 +219,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { const int32_t Bc_n_fixed = (t_c_idx == Tc - 1) ? (seq_size_k - t_c_idx * Bc) : Bc; - + const dtype_t *tile_q = q_batch_base + this_thread_head * q_head_skp; const dtype_t *tile_k = k_batch_base + this_thread_kv_head * k_head_skp + t_c_idx * Bc * dim_size; const dtype_t *tile_v = v_batch_base + this_thread_kv_head * v_head_skp + t_c_idx * Bc * dim_size; @@ -232,8 +232,8 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { rescale_d(acc_o, score_scale_ + thread_id, dim_size); mma1_d(Bc_n_fixed, tile_acc_s, tile_v, acc_o, dim_size); } - - dtype_t* o_block_ptr = o_batch_base + this_thread_head * q_head_skp; + + dtype_t *o_block_ptr = o_batch_base + this_thread_head * q_head_skp; scale_and_store_d(acc_o_ + thread_id * dim_size, logsum_ + thread_id, o_block_ptr, dim_size); } } @@ -244,17 +244,17 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { logsum[i] = 0.0f; scoremax[i] = NEG_INF_F32; } - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 zero_vec = _mm256_setzero_ps(); for (int j = 0; j < Br_n_fixed * dim_size; j += 8) { - _mm256_storeu_ps(acc_o + j, zero_vec); + _mm256_storeu_ps(acc_o + j, zero_vec); } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t zero_vec = vdupq_n_f32(0.0f); for (int j = 0; j < Br_n_fixed * dim_size; j += 4) { vst1q_f32(acc_o + j, zero_vec); } - #endif +#endif } inline void mma0(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, @@ -276,7 +276,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { continue; } const dtype_t *k_block_line = k_block + b_c_idx * dim_size; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 sum_vec = _mm256_setzero_ps(); int i = 0; for (; i <= dim_size - 8; i += 8) { @@ -286,7 +286,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } acc_dtype_t total = hadd_ps_avx(sum_vec); for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t sum_vec = vdupq_n_f32(0.0f); int i = 0; for (; i <= dim_size - 4; i += 4) { @@ -294,39 +294,39 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } acc_dtype_t total = hadd_ps_neon(sum_vec); for (; i < dim_size; ++i) { total += q_block_line[i] * k_block_line[i]; } - #endif +#endif acc_s[b_r_idx * Bc + b_c_idx] = total; } } } - + inline void softmax(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, acc_dtype_t *__restrict__ acc_s, acc_dtype_t *scoremax, acc_dtype_t *scoremax_prev, acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, const float scale) { memcpy(scoremax_prev, scoremax, Br_n_fixed * sizeof(acc_dtype_t)); - + for (int br = 0; br < Br_n_fixed; ++br) { acc_dtype_t *row = acc_s + br * Bc; float block_max = NEG_INF_F32; - for(int bc = 0; bc < Bc_n_fixed; ++bc) { + for (int bc = 0; bc < Bc_n_fixed; ++bc) { block_max = fmaxf(block_max, row[bc]); } scoremax[br] = fmaxf(scoremax[br], block_max); } - + for (int br = 0; br < Br_n_fixed; ++br) { score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); } - + for (int br = 0; br < Br_n_fixed; ++br) { const float current_max = scoremax[br]; acc_dtype_t *row = acc_s + br * Bc; float sum = 0.0f; for (int bc = 0; bc < Bc_n_fixed; ++bc) { - if(row[bc] == NEG_INF_F32) { - row[bc] = 0.0f; - continue; + if (row[bc] == NEG_INF_F32) { + row[bc] = 0.0f; + continue; } float val = expf((row[bc] - current_max) * scale); row[bc] = val; @@ -342,21 +342,21 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { inline void rescale(const int32_t Br_n_fixed, acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size) { for (int i = 0; i < Br_n_fixed; ++i) { - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 scale_v = _mm256_set1_ps(score_scale[i]); float *row_ptr = acc_o + i * dim_size; for (int j = 0; j < dim_size; j += 8) { __m256 acc = _mm256_loadu_ps(row_ptr + j); _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(acc, scale_v)); } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t scale_v = vdupq_n_f32(score_scale[i]); float *row_ptr = acc_o + i * dim_size; for (int j = 0; j < dim_size; j += 4) { float32x4_t acc = vld1q_f32(row_ptr + j); vst1q_f32(row_ptr + j, vmulq_f32(acc, scale_v)); } - #endif +#endif } } @@ -366,7 +366,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { const int32_t v_stride_size = dim_size; for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { - #ifdef __AVX2__ +#ifdef __AVX2__ for (int d_base = 0; d_base < dim_size; d_base += 8) { __m256 acc = _mm256_loadu_ps(acc_o + b_r_idx * dim_size + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { @@ -374,7 +374,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } - #elif __ARM_NEON +#elif __ARM_NEON for (int d_base = 0; d_base < dim_size; d_base += 4) { float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { @@ -382,7 +382,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); } - #endif +#endif } } @@ -392,36 +392,36 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { for (int i = 0; i < Br_n_fixed; ++i) { dtype_t *o_block_line = o_block + i * dim_size; float reciprocal_logsum = (logsum[i] == 0.0f) ? 0.0f : 1.0f / logsum[i]; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); for (int j = 0; j <= dim_size - 8; j += 8) { __m256 vec_acc_o = _mm256_loadu_ps(acc_o + i * dim_size + j); _mm256_storeu_ps(o_block_line + j, _mm256_mul_ps(vec_acc_o, reciprocal_logsum_vec)); } for (int j = dim_size - (dim_size % 8); j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); for (int j = 0; j <= dim_size - 4; j += 4) { float32x4_t vec_acc_o = vld1q_f32(acc_o + i * dim_size + j); vst1q_f32(o_block_line + j, vmulq_f32(vec_acc_o, reciprocal_logsum_vec)); } for (int j = dim_size - (dim_size % 4); j < dim_size; ++j) { o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; } - #endif +#endif } } - + inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { logsum[0] = 0.0f; scoremax[0] = NEG_INF_F32; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 zero_vec = _mm256_setzero_ps(); for (int i = 0; i < dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t zero_vec = vdupq_n_f32(0.0f); for (int i = 0; i < dim_size; i += 4) { vst1q_f32(acc_o + i, zero_vec); } - #endif +#endif } - + inline void mma0_d(const int32_t Bc_n_fixed, const dtype_t *__restrict__ q_block, const dtype_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, const int32_t t_c_idx, @@ -431,12 +431,12 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { const int32_t global_c_idx = global_c_start + b_c_idx; - if(causal_mask && global_c_idx > global_r_idx) { + if (causal_mask && global_c_idx > global_r_idx) { acc_s[b_c_idx] = NEG_INF_F32; continue; } const dtype_t *k_block_line = k_block + b_c_idx * dim_size; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 sum_vec = _mm256_setzero_ps(); int i = 0; for (; i <= dim_size - 8; i += 8) { @@ -444,7 +444,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } acc_dtype_t total = hadd_ps_avx(sum_vec); for (int i = dim_size - (dim_size % 8); i < dim_size; ++i) { total += q_block[i] * k_block_line[i]; } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t sum_vec = vdupq_n_f32(0.0f); int i = 0; for (; i <= dim_size - 4; i += 4) { @@ -452,7 +452,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } acc_dtype_t total = hadd_ps_neon(sum_vec); for (int i = dim_size - (dim_size % 4); i < dim_size; ++i) { total += q_block[i] * k_block_line[i]; } - #endif +#endif acc_s[b_c_idx] = total; } } @@ -462,16 +462,16 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { acc_dtype_t *score_scale, acc_dtype_t *score_sum, acc_dtype_t *logsum, const float scale) { scoremax_prev[0] = scoremax[0]; - + float block_max = NEG_INF_F32; for (int bc = 0; bc < Bc_n_fixed; ++bc) block_max = fmaxf(block_max, acc_s[bc]); scoremax[0] = fmaxf(scoremax[0], block_max); - + score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); - + float current_sum = 0.0f; for (int bc = 0; bc < Bc_n_fixed; ++bc) { - if(acc_s[bc] == NEG_INF_F32) { + if (acc_s[bc] == NEG_INF_F32) { acc_s[bc] = 0.0f; continue; } @@ -482,25 +482,25 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { score_sum[0] = current_sum; logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; } - + inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size) { - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 scale_v = _mm256_set1_ps(score_scale[0]); for (int j = 0; j < dim_size; j += 8) { _mm256_storeu_ps(acc_o + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), scale_v)); } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t scale_v = vdupq_n_f32(score_scale[0]); for (int j = 0; j < dim_size; j += 4) { vst1q_f32(acc_o + j, vmulq_f32(vld1q_f32(acc_o + j), scale_v)); } - #endif +#endif } - + inline void mma1_d(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, const dtype_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t dim_size) { const int32_t v_stride_size = dim_size; - #ifdef __AVX2__ +#ifdef __AVX2__ for (int d_base = 0; d_base < dim_size; d_base += 8) { __m256 acc = _mm256_loadu_ps(acc_o + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { @@ -508,7 +508,7 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } _mm256_storeu_ps(acc_o + d_base, acc); } - #elif __ARM_NEON +#elif __ARM_NEON for (int d_base = 0; d_base < dim_size; d_base += 4) { float32x4_t acc = vld1q_f32(acc_o + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { @@ -516,25 +516,25 @@ struct FA_2_GQA_QKV_FP32_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } vst1q_f32(acc_o + d_base, acc); } - #endif +#endif } inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, dtype_t *__restrict__ o_block, const int32_t dim_size) { float reciprocal_logsum = (logsum[0] == 0.0f) ? 0.0f : 1.0f / logsum[0]; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); for (int j = 0; j <= dim_size - 8; j += 8) { _mm256_storeu_ps(o_block + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), reciprocal_logsum_vec)); } for (int j = dim_size - (dim_size % 8); j < dim_size; ++j) { o_block[j] = acc_o[j] * reciprocal_logsum; } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); for (int j = 0; j <= dim_size - 4; j += 4) { vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); } for (int j = dim_size - (dim_size % 4); j < dim_size; ++j) { o_block[j] = acc_o[j] * reciprocal_logsum; } - #endif +#endif } }; @@ -588,11 +588,11 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { assert(head_size % threads == 0); assert(Q_Head % KV_Head == 0); - #ifdef __AVX2__ +#ifdef __AVX2__ assert(dim_size % 8 == 0); - #elif __ARM_NEON +#elif __ARM_NEON assert(dim_size % 4 == 0); - #endif +#endif if (seq_size_q != 1) { __fa2_prefill_append(Q, K, V, O, batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, q_head_skp, k_head_skp, v_head_skp); @@ -632,7 +632,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { acc_o_ + thread_id * Br * dim_size, Br_n_fixed, dim_size); for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { const int32_t Bc_n_fixed = (t_c_idx == Tc - 1) ? (seq_size_k - t_c_idx * Bc) : Bc; - + const dtype_q_in_t *tile_q = q_batch_base + this_thread_head * q_head_skp + t_r_idx * Br * dim_size; const dtype_kv_in_t *tile_k = k_batch_base + this_thread_kv_head * k_head_skp + t_c_idx * Bc * dim_size; const dtype_kv_in_t *tile_v = v_batch_base + this_thread_kv_head * v_head_skp + t_c_idx * Bc * dim_size; @@ -662,14 +662,14 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; - + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { #pragma omp parallel for num_threads(threads) schedule(dynamic, 1) if (threads > 1) for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { const int32_t thread_id = omp_get_thread_num(); const int32_t this_thread_head = h_idx; const int32_t this_thread_kv_head = this_thread_head / kv_group_size; - + init_temp_d(logsum_ + thread_id, scoremax_ + thread_id, acc_o_ + thread_id * dim_size, dim_size); const dtype_q_in_t *q_batch_base = Q + b_idx * head_size * q_head_skp; @@ -679,41 +679,41 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { for (int t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { const int32_t Bc_n_fixed = (t_c_idx == Tc - 1) ? (seq_size_k - t_c_idx * Bc) : Bc; - + const dtype_q_in_t *tile_q = q_batch_base + this_thread_head * q_head_skp; const dtype_kv_in_t *tile_k = k_batch_base + this_thread_kv_head * k_head_skp + t_c_idx * Bc * dim_size; const dtype_kv_in_t *tile_v = v_batch_base + this_thread_kv_head * v_head_skp + t_c_idx * Bc * dim_size; - + acc_dtype_t *tile_acc_s = acc_s_ + thread_id * Bc; acc_dtype_t *acc_o = acc_o_ + thread_id * dim_size; - + mma0_d(Bc_n_fixed, tile_q, tile_k, tile_acc_s, dim_size, t_c_idx, seq_size_k, causal_mask); softmax_d(Bc_n_fixed, tile_acc_s, scoremax_ + thread_id, scoremax_prev_ + thread_id, score_scale_ + thread_id, score_sum_ + thread_id, logsum_ + thread_id, local_scale); rescale_d(acc_o, score_scale_ + thread_id, dim_size); mma1_d(Bc_n_fixed, tile_acc_s, tile_v, acc_o, dim_size); } - dtype_out_t* o_block_ptr = o_batch_base + this_thread_head * q_head_skp; + dtype_out_t *o_block_ptr = o_batch_base + this_thread_head * q_head_skp; scale_and_store_d(acc_o_ + thread_id * dim_size, logsum_ + thread_id, o_block_ptr, dim_size); } } } - + inline void init_temp(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t Br_n_fixed, const int32_t dim_size) { for (int i = 0; i < Br_n_fixed; ++i) { logsum[i] = 0.0f; scoremax[i] = NEG_INF_F32; } - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 zero_vec = _mm256_setzero_ps(); for (int j = 0; j < Br_n_fixed * dim_size; j += 8) { - _mm256_storeu_ps(acc_o + j, zero_vec); + _mm256_storeu_ps(acc_o + j, zero_vec); } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t zero_vec = vdupq_n_f32(0.0f); for (int j = 0; j < Br_n_fixed * dim_size; j += 4) { vst1q_f32(acc_o + j, zero_vec); } - #endif +#endif } inline void mma0(const int32_t Br_n_fixed, const int32_t Bc_n_fixed, @@ -724,7 +724,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { const int32_t global_r_start = t_r_idx * Br; const int32_t global_c_start = t_c_idx * Bc; const int32_t delta_pos = seq_size_k - seq_size_q; - + for (int32_t b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { const dtype_q_in_t *q_block_line = q_block + b_r_idx * dim_size; for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { @@ -735,7 +735,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { continue; } const dtype_kv_in_t *k_block_line = k_block + b_c_idx * dim_size; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 sum_vec = _mm256_setzero_ps(); int i = 0; for (; i <= dim_size - 8; i += 8) { @@ -745,7 +745,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } acc_dtype_t total = hadd_ps_avx(sum_vec); for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t sum_vec = vdupq_n_f32(0.0f); int i = 0; for (; i <= dim_size - 4; i += 4) { @@ -755,7 +755,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } acc_dtype_t total = hadd_ps_neon(sum_vec); for (; i < dim_size; ++i) { total += q_block_line[i] * MLLM_FP16_TO_FP32(k_block_line[i]); } - #endif +#endif acc_s[b_r_idx * Bc + b_c_idx] = total; } } @@ -769,7 +769,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { for (int br = 0; br < Br_n_fixed; ++br) { acc_dtype_t *row = acc_s + br * Bc; float block_max = NEG_INF_F32; - for(int bc = 0; bc < Bc_n_fixed; ++bc) block_max = fmaxf(block_max, row[bc]); + for (int bc = 0; bc < Bc_n_fixed; ++bc) block_max = fmaxf(block_max, row[bc]); scoremax[br] = fmaxf(scoremax[br], block_max); } for (int br = 0; br < Br_n_fixed; ++br) score_scale[br] = expf((scoremax_prev[br] - scoremax[br]) * scale); @@ -778,7 +778,10 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { acc_dtype_t *row = acc_s + br * Bc; float sum = 0.0f; for (int bc = 0; bc < Bc_n_fixed; ++bc) { - if(row[bc] == NEG_INF_F32) { row[bc] = 0.0f; continue; } + if (row[bc] == NEG_INF_F32) { + row[bc] = 0.0f; + continue; + } float val = expf((row[bc] - current_max) * scale); row[bc] = val; sum += val; @@ -790,15 +793,15 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { inline void rescale(const int32_t Br_n_fixed, acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size) { for (int i = 0; i < Br_n_fixed; ++i) { - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 scale_v = _mm256_set1_ps(score_scale[i]); float *row_ptr = acc_o + i * dim_size; for (int j = 0; j < dim_size; j += 8) _mm256_storeu_ps(row_ptr + j, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + j), scale_v)); - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t scale_v = vdupq_n_f32(score_scale[i]); float *row_ptr = acc_o + i * dim_size; for (int j = 0; j < dim_size; j += 4) vst1q_f32(row_ptr + j, vmulq_f32(vld1q_f32(row_ptr + j), scale_v)); - #endif +#endif } } @@ -807,7 +810,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { acc_dtype_t *__restrict__ acc_o, const int32_t dim_size) { const int32_t v_stride_size = dim_size; for (int b_r_idx = 0; b_r_idx < Br_n_fixed; ++b_r_idx) { - #ifdef __AVX2__ +#ifdef __AVX2__ for (int d_base = 0; d_base < dim_size; d_base += 8) { __m256 acc = _mm256_loadu_ps(acc_o + b_r_idx * dim_size + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { @@ -815,7 +818,7 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } _mm256_storeu_ps(acc_o + b_r_idx * dim_size + d_base, acc); } - #elif __ARM_NEON +#elif __ARM_NEON for (int d_base = 0; d_base < dim_size; d_base += 4) { float32x4_t acc = vld1q_f32(acc_o + b_r_idx * dim_size + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { @@ -825,39 +828,39 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } vst1q_f32(acc_o + b_r_idx * dim_size + d_base, acc); } - #endif +#endif } } - + inline void scale_and_store(const int32_t Br_n_fixed, const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, const int32_t dim_size) { for (int i = 0; i < Br_n_fixed; ++i) { dtype_out_t *o_block_line = o_block + i * dim_size; float reciprocal_logsum = (logsum[i] == 0.0f) ? 0.0f : 1.0f / logsum[i]; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); for (int j = 0; j <= dim_size - 8; j += 8) _mm256_storeu_ps(o_block_line + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + i * dim_size + j), reciprocal_logsum_vec)); for (int j = dim_size - (dim_size % 8); j < dim_size; ++j) o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); for (int j = 0; j <= dim_size - 4; j += 4) vst1q_f32(o_block_line + j, vmulq_f32(vld1q_f32(acc_o + i * dim_size + j), reciprocal_logsum_vec)); for (int j = dim_size - (dim_size % 4); j < dim_size; ++j) o_block_line[j] = acc_o[i * dim_size + j] * reciprocal_logsum; - #endif +#endif } } inline void init_temp_d(acc_dtype_t *logsum, acc_dtype_t *scoremax, acc_dtype_t *acc_o, const int32_t dim_size) { logsum[0] = 0.0f; scoremax[0] = NEG_INF_F32; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 zero_vec = _mm256_setzero_ps(); for (int i = 0; i < dim_size; i += 8) { _mm256_storeu_ps(acc_o + i, zero_vec); } - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t zero_vec = vdupq_n_f32(0.0f); for (int i = 0; i < dim_size; i += 4) { vst1q_f32(acc_o + i, zero_vec); } - #endif +#endif } - + inline void mma0_d(const int32_t Bc_n_fixed, const dtype_q_in_t *__restrict__ q_block, const dtype_kv_in_t *__restrict__ k_block, acc_dtype_t *__restrict__ acc_s, const int32_t dim_size, const int32_t t_c_idx, @@ -866,28 +869,28 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { const int32_t global_r_idx = seq_size_k - 1; for (int32_t b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { const int32_t global_c_idx = global_c_start + b_c_idx; - if(causal_mask && global_c_idx > global_r_idx) { + if (causal_mask && global_c_idx > global_r_idx) { acc_s[b_c_idx] = NEG_INF_F32; continue; } const dtype_kv_in_t *k_block_line = k_block + b_c_idx * dim_size; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 sum_vec = _mm256_setzero_ps(); int i = 0; for (; i <= dim_size - 8; i += 8) sum_vec = _mm256_fmadd_ps(_mm256_loadu_ps(q_block + i), MLLM_F32Cx8_LOAD(k_block_line + i), sum_vec); acc_dtype_t total = hadd_ps_avx(sum_vec); for (; i < dim_size; ++i) total += q_block[i] * MLLM_FP16_TO_FP32(k_block_line[i]); - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t sum_vec = vdupq_n_f32(0.0f); int i = 0; for (; i <= dim_size - 4; i += 4) { - float32x4_t q_vec = vld1q_f32(q_block + i); - float32x4_t k_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)(k_block_line + i))); - sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); + float32x4_t q_vec = vld1q_f32(q_block + i); + float32x4_t k_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)(k_block_line + i))); + sum_vec = vfmaq_f32(sum_vec, q_vec, k_vec); } acc_dtype_t total = hadd_ps_neon(sum_vec); for (; i < dim_size; ++i) total += q_block[i] * MLLM_FP16_TO_FP32(k_block_line[i]); - #endif +#endif acc_s[b_c_idx] = total; } } @@ -903,7 +906,10 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { score_scale[0] = expf((scoremax_prev[0] - scoremax[0]) * scale); float current_sum = 0.0f; for (int bc = 0; bc < Bc_n_fixed; ++bc) { - if(acc_s[bc] == NEG_INF_F32) { acc_s[bc] = 0.0f; continue; } + if (acc_s[bc] == NEG_INF_F32) { + acc_s[bc] = 0.0f; + continue; + } float val = expf((acc_s[bc] - scoremax[0]) * scale); acc_s[bc] = val; current_sum += val; @@ -911,21 +917,21 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { score_sum[0] = current_sum; logsum[0] = logsum[0] * score_scale[0] + score_sum[0]; } - + inline void rescale_d(acc_dtype_t *__restrict__ acc_o, acc_dtype_t *__restrict__ score_scale, const int32_t dim_size) { - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 scale_v = _mm256_set1_ps(score_scale[0]); for (int j = 0; j < dim_size; j += 8) _mm256_storeu_ps(acc_o + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), scale_v)); - #elif __ARM_NEON +#elif __ARM_NEON float32x4_t scale_v = vdupq_n_f32(score_scale[0]); for (int j = 0; j < dim_size; j += 4) vst1q_f32(acc_o + j, vmulq_f32(vld1q_f32(acc_o + j), scale_v)); - #endif +#endif } - + inline void mma1_d(const int32_t Bc_n_fixed, const acc_dtype_t *__restrict__ w_block, const dtype_kv_in_t *__restrict__ v_block, acc_dtype_t *__restrict__ acc_o, const int32_t dim_size) { const int32_t v_stride_size = dim_size; - #ifdef __AVX2__ +#ifdef __AVX2__ for (int d_base = 0; d_base < dim_size; d_base += 8) { __m256 acc = _mm256_loadu_ps(acc_o + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { @@ -933,31 +939,31 @@ struct FA_2_GQA_Q_FP32_KV_FP16_BHSD_O_FP32_BHSD_ACC_FP32_IMPL { } _mm256_storeu_ps(acc_o + d_base, acc); } - #elif __ARM_NEON +#elif __ARM_NEON for (int d_base = 0; d_base < dim_size; d_base += 4) { float32x4_t acc = vld1q_f32(acc_o + d_base); for (int b_c_idx = 0; b_c_idx < Bc_n_fixed; ++b_c_idx) { - float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); - float32x4_t v_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)(v_block + b_c_idx * v_stride_size + d_base))); - acc = vfmaq_f32(acc, w_vec, v_vec); + float32x4_t w_vec = vdupq_n_f32(w_block[b_c_idx]); + float32x4_t v_vec = vcvt_f32_f16(vld1_f16((const __fp16 *)(v_block + b_c_idx * v_stride_size + d_base))); + acc = vfmaq_f32(acc, w_vec, v_vec); } vst1q_f32(acc_o + d_base, acc); } - #endif +#endif } - + inline void scale_and_store_d(const acc_dtype_t *__restrict__ acc_o, const acc_dtype_t *__restrict__ logsum, dtype_out_t *__restrict__ o_block, const int32_t dim_size) { float reciprocal_logsum = (logsum[0] == 0.0f) ? 0.0f : 1.0f / logsum[0]; - #ifdef __AVX2__ +#ifdef __AVX2__ __m256 reciprocal_logsum_vec = _mm256_set1_ps(reciprocal_logsum); for (int j = 0; j <= dim_size - 8; j += 8) _mm256_storeu_ps(o_block + j, _mm256_mul_ps(_mm256_loadu_ps(acc_o + j), reciprocal_logsum_vec)); - for (int j = dim_size-(dim_size%8); j < dim_size; ++j) o_block[j] = acc_o[j] * reciprocal_logsum; - #elif __ARM_NEON + for (int j = dim_size - (dim_size % 8); j < dim_size; ++j) o_block[j] = acc_o[j] * reciprocal_logsum; +#elif __ARM_NEON float32x4_t reciprocal_logsum_vec = vdupq_n_f32(reciprocal_logsum); for (int j = 0; j <= dim_size - 4; j += 4) vst1q_f32(o_block + j, vmulq_f32(vld1q_f32(acc_o + j), reciprocal_logsum_vec)); - for (int j = dim_size-(dim_size%4); j < dim_size; ++j) o_block[j] = acc_o[j] * reciprocal_logsum; - #endif + for (int j = dim_size - (dim_size % 4); j < dim_size; ++j) o_block[j] = acc_o[j] * reciprocal_logsum; +#endif } }; @@ -1000,7 +1006,6 @@ inline void flash_attention_2_forward_h( bool causal_mask, bool use_fp32, int32_t threads, int32_t br, int32_t bc, int32_t q_head, int32_t kv_head, bool high_precision_exp, int32_t q_head_skp, int32_t k_head_skp, int32_t v_head_skp) { - const size_t align = 32; const size_t acc_o_size = threads * br * dim_size * sizeof(float); const size_t acc_s_size = threads * br * bc * sizeof(float); @@ -1012,19 +1017,19 @@ inline void flash_attention_2_forward_h( void *workspace_ptr = nullptr; size_t total_workspace_size = acc_o_size + acc_s_size + logsum_size + scoremax_size + scoremax_prev_size + score_scale_size + score_sum_size; - + platform_aligned_alloc(&workspace_ptr, total_workspace_size, align); - if(workspace_ptr == nullptr) { + if (workspace_ptr == nullptr) { return; } - - float* acc_o = static_cast(workspace_ptr); - float* acc_s = acc_o + threads * br * dim_size; - float* logsum = acc_s + threads * br * bc; - float* scoremax = logsum + threads * br; - float* scoremax_prev = scoremax + threads * br; - float* score_scale = scoremax_prev + threads * br; - float* score_sum = score_scale + threads * br; + + float *acc_o = static_cast(workspace_ptr); + float *acc_s = acc_o + threads * br * dim_size; + float *logsum = acc_s + threads * br * bc; + float *scoremax = logsum + threads * br; + float *scoremax_prev = scoremax + threads * br; + float *score_scale = scoremax_prev + threads * br; + float *score_sum = score_scale + threads * br; if (use_fp32) { mobi_attn::FlashAttn2HeadFirstT op; @@ -1038,14 +1043,14 @@ inline void flash_attention_2_forward_h( mobi_attn::FlashAttn2HeadFirstT op; op.configure(br, bc, q_head, kv_head, threads, high_precision_exp); op.init_workspace(acc_o, acc_s, logsum, scoremax, scoremax_prev, score_scale, score_sum); - op(static_cast(Q), - static_cast(K), + op(static_cast(Q), + static_cast(K), static_cast(V), static_cast(O), batch_size, head_size, seq_size_q, seq_size_k, dim_size, causal_mask, q_head_skp, k_head_skp, v_head_skp); } - + if (workspace_ptr) { platform_aligned_free(workspace_ptr); } diff --git a/src/backends/cpu/compute/GemmKleidiai.cpp b/src/backends/cpu/compute/GemmKleidiai.cpp index db3bc7658..d7a0e4ee5 100644 --- a/src/backends/cpu/compute/GemmKleidiai.cpp +++ b/src/backends/cpu/compute/GemmKleidiai.cpp @@ -9,17 +9,18 @@ #include #include -// 引入 OpenMP 头文件 #include -// ###################################################################### // -// ## Implementation 1: QSI4 (INT4) ## -// ###################################################################### //// 【新增】线程局部的全局工作区,用于内存复用 -// 【新增】一个为OpenMP设计的、线程安全的工作区管理器 + class WorkspaceManager { public: - // 构造函数:获取OpenMP最大线程数,并为每个线程创建一个工作区 + static WorkspaceManager &get_instance() { + static WorkspaceManager instance; + return instance; + } + +private: WorkspaceManager() { - int max_threads = kai_thread_count; // 获取当前线程数; + int max_threads = kai_thread_count; #ifdef _OPENMP max_threads = omp_get_max_threads(); #endif @@ -29,7 +30,10 @@ class WorkspaceManager { fp16_c_buffers_.resize(max_threads); } - // 获取当前线程的 QSI4 工作区 +public: + WorkspaceManager(const WorkspaceManager &) = delete; + WorkspaceManager &operator=(const WorkspaceManager &) = delete; + std::vector &get_qsi4_workspace() { int thread_id = 0; #ifdef _OPENMP @@ -38,7 +42,6 @@ class WorkspaceManager { return qsi4_workspaces_[thread_id]; } - // 获取当前线程的 QSI4->FP16 临时C区 std::vector &get_qsi4_c_temp_buffer() { int thread_id = 0; #ifdef _OPENMP @@ -47,7 +50,6 @@ class WorkspaceManager { return qsi4_c_temp_buffers_[thread_id]; } - // 获取当前线程的 FP16 临时A区 std::vector &get_fp16_a_buffer() { int thread_id = 0; #ifdef _OPENMP @@ -56,7 +58,6 @@ class WorkspaceManager { return fp16_a_buffers_[thread_id]; } - // 获取当前线程的 FP16 临时C区 std::vector &get_fp16_c_buffer() { int thread_id = 0; #ifdef _OPENMP @@ -72,21 +73,12 @@ class WorkspaceManager { std::vector> fp16_c_buffers_; }; -// 创建一个全局唯一的管理器实例 -static WorkspaceManager g_workspace_manager; - -// ###################################################################### // -// ## Implementation 1: QSI4 (INT4) ## -// ###################################################################### // - -// 【新增】包含用于map和CPU特性检测的头文件 #include #if defined(__linux__) #include #include #endif -// 【新增】包含所有需要的计算核心头文件,特别是 i8mm 版本 #include "kai_matmul_clamp_f32_qai8dxp_qsi4c32p_interface.h" #include "kai_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod.h" #include "kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f32.h" @@ -97,13 +89,17 @@ static WorkspaceManager g_workspace_manager; #include "kai_matmul_clamp_f32_qai8dxp_qsi4c32p_interface.h" #include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0.h" -// 【新增】在.cpp内部定义核心配置的枚举,外部不可见 +#include "kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp_qsi4cxp_interface.h" +#include "kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod.h" +#include "kai/ukernels/matmul/matmul_clamp_f16_qai8dxp_qsi4cxp/kai_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm.h" +#include "kai/ukernels/matmul/pack/kai_lhs_quant_pack_qai8dxp_f16_neon.h" +#include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_qsi4cxp_qs4cxs1s0.h" + enum class KleidiaiQsi4Tile { - k1x8_4x8_1x4x32_dotprod, // 兼容性最好的 dotprod 核心 - k4x8_4x8_8x4x32_i8mm, // 高性能的 i8mm 核心 + k1x8_4x8_1x4x32_dotprod, + k4x8_4x8_8x4x32_i8mm, }; -// 【新增】为KleidiaiQsi4Tile定义哈希函数以用于unordered_map namespace std { template <> struct hash { @@ -114,8 +110,6 @@ struct hash { }; } // namespace std -// 【新增】在.cpp内部定义一个静态map,存储所有可用的计算核心 -// 【新增】第一步:将每个 ukernel 定义为独立的静态常量 static const kai_matmul_clamp_f32_qai8dxp_qsi4c32p_ukernel dotprod_ukernel = { .get_m_step = kai_get_m_step_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, .get_n_step = kai_get_n_step_matmul_clamp_f32_qai8dxp1x8_qsi4c32p4x8_1x4x32_neon_dotprod, @@ -140,19 +134,67 @@ static const kai_matmul_clamp_f32_qai8dxp_qsi4c32p_ukernel i8mm_ukernel = { .get_dst_offset = kai_get_dst_offset_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm, .run_matmul = kai_run_matmul_clamp_f32_qai8dxp4x8_qsi4c32p4x8_8x4x32_neon_i8mm}; -// 第二步:使用定义好的常量来初始化 map,语法更简洁清晰 static const std::unordered_map qsi4_ukernels = { {KleidiaiQsi4Tile::k1x8_4x8_1x4x32_dotprod, dotprod_ukernel}, {KleidiaiQsi4Tile::k4x8_4x8_8x4x32_i8mm, i8mm_ukernel}}; - -// 【新增】根据CPU能力自动选择最佳核心,并缓存结果 + static KleidiaiQsi4Tile kleidiai_get_best_qsi4_tile_config() { - // 使用静态变量,这样CPU检测的逻辑只会在第一次调用时执行一次 static const KleidiaiQsi4Tile best_tile = arm_is_i8mm_supported() ? KleidiaiQsi4Tile::k4x8_4x8_8x4x32_i8mm : KleidiaiQsi4Tile::k1x8_4x8_1x4x32_dotprod; return best_tile; } + +enum class KleidiaiQsi4TileF16 { + k1x8_4x8_1x4_dotprod, + k4x8_4x8_16x4_i8mm, +}; + +namespace std { +template <> +struct hash { + std::size_t operator()(const KleidiaiQsi4TileF16 &k) const noexcept { + return std::hash::type>()( + static_cast::type>(k)); + } +}; +} // namespace std + +static const kai_matmul_clamp_f16_qai8dxp_qsi4cxp_ukernel f16_dotprod_ukernel = { + .get_m_step = kai_get_m_step_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod, + .get_n_step = kai_get_n_step_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod, + .get_mr = kai_get_mr_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod, + .get_nr = kai_get_nr_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod, + .get_kr = kai_get_kr_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod, + .get_sr = kai_get_sr_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod, + .get_lhs_packed_offset = kai_get_lhs_packed_offset_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod, + .get_rhs_packed_offset = kai_get_rhs_packed_offset_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod, + .get_dst_offset = kai_get_dst_offset_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod, + .run_matmul = kai_run_matmul_clamp_f16_qai8dxp1x8_qsi4cxp4x8_1x4_neon_dotprod}; + +static const kai_matmul_clamp_f16_qai8dxp_qsi4cxp_ukernel f16_i8mm_ukernel = { + .get_m_step = kai_get_m_step_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm, + .get_n_step = kai_get_n_step_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm, + .get_mr = kai_get_mr_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm, + .get_nr = kai_get_nr_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm, + .get_kr = kai_get_kr_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm, + .get_sr = kai_get_sr_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm, + .get_lhs_packed_offset = kai_get_lhs_packed_offset_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm, + .get_rhs_packed_offset = kai_get_rhs_packed_offset_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm, + .get_dst_offset = kai_get_dst_offset_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm, + .run_matmul = kai_run_matmul_clamp_f16_qai8dxp4x8_qsi4cxp4x8_16x4_neon_i8mm}; + +static const std::unordered_map qsi4_f16_ukernels = { + {KleidiaiQsi4TileF16::k1x8_4x8_1x4_dotprod, f16_dotprod_ukernel}, + {KleidiaiQsi4TileF16::k4x8_4x8_16x4_i8mm, f16_i8mm_ukernel}}; + +static KleidiaiQsi4TileF16 kleidiai_get_best_qsi4_tile_config_f16() { + static const KleidiaiQsi4TileF16 best_tile = arm_is_i8mm_supported() ? + KleidiaiQsi4TileF16::k4x8_4x8_16x4_i8mm : + KleidiaiQsi4TileF16::k1x8_4x8_1x4_dotprod; + return best_tile; +} + size_t mllm_kleidai_get_packed_b_qsi4_size(int N, int K) { const auto tile_cfg = kleidiai_get_best_qsi4_tile_config(); const auto &ukernel = qsi4_ukernels.at(tile_cfg); @@ -170,23 +212,21 @@ size_t get_workspace_qsi4_size(int M, int K) { } void mllm_kleidai_pack_b_and_bias_qsi4( - uint8_t* packed_b_ptr, - const float* b_ptr, - const float* bias_ptr, + uint8_t *packed_b_ptr, + const float *b_ptr, + const float *bias_ptr, int N, int K) { const auto tile_cfg = kleidiai_get_best_qsi4_tile_config(); const auto &ukernel = qsi4_ukernels.at(tile_cfg); - // 【新增】创建临时的bias(如果需要) - const float* bias_to_use = bias_ptr; + const float *bias_to_use = bias_ptr; std::vector fake_bias; if (bias_to_use == nullptr) { fake_bias.assign(N, 0.0f); bias_to_use = fake_bias.data(); } - const int block_len = 32; const size_t num_blocks_k = (K + block_len - 1) / block_len; std::vector temp_quantized_b(K * N / 2); @@ -227,32 +267,32 @@ void mllm_kleidai_pack_b_and_bias_qsi4( params.lhs_zero_point = 1; params.rhs_zero_point = 8; params.scale_dt = kai_dt_bf16; - // kai_run_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0( - // 1, N, K, qsi4_ukernel.get_nr(), qsi4_ukernel.get_kr(), qsi4_ukernel.get_sr(), block_len, - // temp_quantized_b.data(), K/2, bias_to_use, (const uint8_t*)temp_scales.data(), num_blocks_k * sizeof(uint16_t), - // packed_b_ptr, 0, ¶ms); kai_run_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0( 1, N, K, ukernel.get_nr(), ukernel.get_kr(), ukernel.get_sr(), block_len, - temp_quantized_b.data(), N/2, bias_to_use, (const uint8_t*)temp_scales.data(), num_blocks_k * sizeof(uint16_t), + temp_quantized_b.data(), N / 2, bias_to_use, (const uint8_t *)temp_scales.data(), num_blocks_k * sizeof(uint16_t), packed_b_ptr, 0, ¶ms); } -// --- 【替换】旧的 mllm_kleidai_gemm_qsi4 函数 ---// --- 【替换】旧的 mllm_kleidai_gemm_qsi4 函数 --- +#ifndef KAI_FP16_CAL void mllm_kleidai_gemm_qsi4( float *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, int M, int N, int K) { - // 1. 内部自动选择最佳计算核心 (i8mm 或 dotprod) - const auto tile_cfg = kleidiai_get_best_qsi4_tile_config(); - const auto &ukernel = qsi4_ukernels.at(tile_cfg); + kai_matmul_clamp_f32_qai8dxp_qsi4c32p_ukernel ukernel; + if (M == 1) { + ukernel = qsi4_ukernels.at(KleidiaiQsi4Tile::k1x8_4x8_1x4x32_dotprod); + } else { + const auto tile_cfg = arm_is_i8mm_supported() ? + KleidiaiQsi4Tile::k4x8_4x8_8x4x32_i8mm : + KleidiaiQsi4Tile::k1x8_4x8_1x4x32_dotprod; + ukernel = qsi4_ukernels.at(tile_cfg); + } - // 2. 从全局管理器获取当前线程专属的工作区,如果空间不足则自动扩容 - auto &workspace_data = g_workspace_manager.get_qsi4_workspace(); + auto &workspace_data = WorkspaceManager::get_instance().get_qsi4_workspace(); size_t required_workspace_size = get_workspace_qsi4_size(M, K); if (workspace_data.size() < required_workspace_size) { workspace_data.resize(required_workspace_size); } - // 3. 在获取到的工作区中,对左手矩阵 A 进行量化和打包 kai_run_lhs_quant_pack_qai8dxp_f32( M, K, ukernel.get_mr(), ukernel.get_kr(), ukernel.get_sr(), @@ -260,43 +300,236 @@ void mllm_kleidai_gemm_qsi4( a_ptr, K * sizeof(float), workspace_data.data()); - const int m_step = ukernel.get_m_step(); const int n_step = ukernel.get_n_step(); const int block_len = 32; - // 4. 使用选择的最佳核心,在 OpenMP 并行循环中执行矩阵乘法 -#pragma omp parallel for collapse(2) num_threads(kai_thread_count) - for (int m_start = 0; m_start < M; m_start += m_step) { - for (int n_start = 0; n_start < N; n_start += n_step) { - const int current_m = std::min(M - m_start, m_step); - const int current_n = std::min(N - n_start, n_step); +#pragma omp parallel for num_threads(kai_thread_count) + for (int n_start = 0; n_start < N; n_start += n_step) { + const int current_n = std::min(N - n_start, n_step); + + const void *a_packed_ptr = workspace_data.data(); + const void *b_packed_offset = (const char *)packed_b_ptr + ukernel.get_rhs_packed_offset(n_start, K, block_len); + float *c_offset = c_ptr + n_start; + + ukernel.run_matmul( + M, current_n, K, block_len, + a_packed_ptr, b_packed_offset, + c_offset, N * sizeof(float), + sizeof(float), + -FLT_MAX, FLT_MAX); + } +} - // 使用来自工作区的指针 - const void *a_packed_offset = (const char *)workspace_data.data() + ukernel.get_lhs_packed_offset(m_start, K); - const void *b_packed_offset = (const char *)packed_b_ptr + ukernel.get_rhs_packed_offset(n_start, K, block_len); - float *c_offset = c_ptr + m_start * N + n_start; +#else +void mllm_kleidai_gemm_qsi4_f16_compute( + mllm_fp16_t *c_ptr, const mllm_fp16_t *a_ptr, const uint8_t *packed_b_ptr, + int M, int N, int K) { + kai_matmul_clamp_f16_qai8dxp_qsi4cxp_ukernel ukernel; + if (M == 1) { + ukernel = qsi4_f16_ukernels.at(KleidiaiQsi4TileF16::k1x8_4x8_1x4_dotprod); + } else { + const auto tile_cfg = arm_is_i8mm_supported() ? + KleidiaiQsi4TileF16::k4x8_4x8_16x4_i8mm : + KleidiaiQsi4TileF16::k1x8_4x8_1x4_dotprod; + ukernel = qsi4_f16_ukernels.at(tile_cfg); + } - ukernel.run_matmul( - current_m, current_n, K, block_len, - a_packed_offset, b_packed_offset, - c_offset, N * sizeof(float), sizeof(float), - -FLT_MAX, FLT_MAX); + auto &workspace_data = WorkspaceManager::get_instance().get_qsi4_workspace(); + + size_t required_workspace_size = kai_get_lhs_packed_size_lhs_quant_pack_qai8dxp_f16_neon( + M, K, ukernel.get_mr(), ukernel.get_kr(), ukernel.get_sr()); + if (workspace_data.size() < required_workspace_size) { + workspace_data.resize(required_workspace_size); + } + + kai_run_lhs_quant_pack_qai8dxp_f16_neon( + M, K, + ukernel.get_mr(), ukernel.get_kr(), ukernel.get_sr(), + 0, + a_ptr, + K * sizeof(mllm_fp16_t), + workspace_data.data()); + + const int n_step = ukernel.get_n_step(); + +#pragma omp parallel for num_threads(kai_thread_count) + for (int n_start = 0; n_start < N; n_start += n_step) { + const int current_n = std::min(N - n_start, n_step); + const void *a_packed_ptr = workspace_data.data(); + const void *b_packed_offset = (const char *)packed_b_ptr + ukernel.get_rhs_packed_offset(n_start, K); + void *c_offset = c_ptr + n_start; + + ukernel.run_matmul( + M, current_n, K, + a_packed_ptr, b_packed_offset, + c_offset, N * sizeof(mllm_fp16_t), + sizeof(mllm_fp16_t), + -FLT_MAX, FLT_MAX); + } +} + +void mllm_kleidai_gemm_qsi4( + float *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, + int M, int N, int K) { + auto &a_fp16 = WorkspaceManager::get_instance().get_fp16_a_buffer(); + if (a_fp16.size() < M * K) { + a_fp16.resize(M * K); + } + + auto &c_fp16 = WorkspaceManager::get_instance().get_fp16_c_buffer(); + if (c_fp16.size() < M * N) { + c_fp16.resize(M * N); + } + +#pragma omp parallel for num_threads(kai_thread_count) + for (int i = 0; i < M * K; ++i) { + a_fp16[i] = static_cast(a_ptr[i]); + } + + mllm_kleidai_gemm_qsi4_f16_compute(c_fp16.data(), a_fp16.data(), packed_b_ptr, M, N, K); + +#pragma omp parallel for num_threads(kai_thread_count) + for (int i = 0; i <= (M * N) - 8; i += 8) { + float16x8_t fp16_vec = vld1q_f16(reinterpret_cast(c_fp16.data() + i)); + + float32x4_t fp32_vec_low = vcvt_f32_f16(vget_low_f16(fp16_vec)); + float32x4_t fp32_vec_high = vcvt_f32_f16(vget_high_f16(fp16_vec)); + + vst1q_f32(c_ptr + i, fp32_vec_low); + vst1q_f32(c_ptr + i + 4, fp32_vec_high); + } + for (int i = (M * N) - ((M * N) % 8); i < M * N; ++i) { + c_ptr[i] = static_cast(c_fp16[i]); + } +} +#endif + +size_t mllm_kleidai_get_packed_b_qsi4_size_to_fp16(int N, int K) { + const auto tile_cfg = kleidiai_get_best_qsi4_tile_config_f16(); + const auto &ukernel = qsi4_f16_ukernels.at(tile_cfg); + + return kai_get_rhs_packed_size_rhs_pack_kxn_qsi4cxp_qs4cxs1s0( + N, K, ukernel.get_nr(), ukernel.get_kr(), ukernel.get_sr()); +} + +void mllm_kleidai_pack_b_and_bias_qsi4_to_fp16( + uint8_t *packed_b_ptr, + const float *b_ptr, + const float *bias_ptr, + int N, + int K) { + const auto tile_cfg = kleidiai_get_best_qsi4_tile_config_f16(); + const auto &ukernel = qsi4_f16_ukernels.at(tile_cfg); + + const float *bias_to_use = bias_ptr; + std::vector fake_bias; + if (bias_to_use == nullptr) { + fake_bias.assign(N, 0.0f); + bias_to_use = fake_bias.data(); + } + + const size_t quantized_b_size = (size_t)K * N / 2; + std::vector temp_quantized_b(quantized_b_size, 0); + std::vector temp_scales_fp32(N); + + for (int n = 0; n < N; ++n) { + float amax = 0.0f; + for (int k = 0; k < K; ++k) { + amax = std::max(amax, std::abs(b_ptr[k * N + n])); + } + + const float scale = amax / 7.0f; + temp_scales_fp32[n] = scale; + const float inv_scale = (scale != 0.0f) ? 1.0f / scale : 0.0f; + + for (int k = 0; k < K; ++k) { + const float val = b_ptr[k * N + n]; + int32_t q_val = static_cast(roundf(val * inv_scale)); + q_val = std::max(-8, std::min(7, q_val)); + + uint8_t stored_val = static_cast(q_val + 8); + + size_t byte_idx = (k * N + n) / 2; + if ((k * N + n) % 2 == 0) { + temp_quantized_b[byte_idx] = stored_val; + } else { + temp_quantized_b[byte_idx] |= (stored_val << 4); + } } } + + struct kai_rhs_pack_kxn_qsi4cxp_qs4cxs1s0_params kxn_params = {}; + kxn_params.lhs_zero_point = 1; + kxn_params.rhs_zero_point = 8; + kai_run_rhs_pack_kxn_qsi4cxp_qs4cxs1s0( + 1, N, K, ukernel.get_nr(), ukernel.get_kr(), ukernel.get_sr(), + temp_quantized_b.data(), // Pointer to quantized data + bias_to_use, // Pointer to bias data + temp_scales_fp32.data(), // Pointer to fp32 scale data + packed_b_ptr, // Output packed data + 0, // Output stride (0 for contiguous) + &kxn_params); } +void mllm_kleidai_gemm_qsi4_f16_internal( + mllm_fp16_t *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, + int M, int N, int K) { + kai_matmul_clamp_f16_qai8dxp_qsi4cxp_ukernel ukernel; + if (M == 1) { + ukernel = qsi4_f16_ukernels.at(KleidiaiQsi4TileF16::k1x8_4x8_1x4_dotprod); + } else { + const auto tile_cfg = arm_is_i8mm_supported() ? + KleidiaiQsi4TileF16::k4x8_4x8_16x4_i8mm : + KleidiaiQsi4TileF16::k1x8_4x8_1x4_dotprod; + ukernel = qsi4_f16_ukernels.at(tile_cfg); + } + + auto &workspace_data = WorkspaceManager::get_instance().get_qsi4_workspace(); + + size_t required_workspace_size = kai_get_lhs_packed_size_lhs_quant_pack_qai8dxp_f16_neon( + M, K, ukernel.get_mr(), ukernel.get_kr(), ukernel.get_sr()); + if (workspace_data.size() < required_workspace_size) { + workspace_data.resize(required_workspace_size); + } + kai_run_lhs_quant_pack_qai8dxp_f16_neon( + M, K, + ukernel.get_mr(), ukernel.get_kr(), ukernel.get_sr(), + 0, + reinterpret_cast(a_ptr), + K * sizeof(float), + workspace_data.data()); + + const int n_step = ukernel.get_n_step(); + +#pragma omp parallel for num_threads(kai_thread_count) + for (int n_start = 0; n_start < N; n_start += n_step) { + const int current_n = std::min(N - n_start, n_step); + + const void *a_packed_ptr = workspace_data.data(); + const void *b_packed_offset = (const char *)packed_b_ptr + ukernel.get_rhs_packed_offset(n_start, K); + + uint16_t *c_offset = reinterpret_cast(c_ptr) + n_start * N + n_start; + + ukernel.run_matmul( + M, current_n, K, + a_packed_ptr, b_packed_offset, + c_offset, N * sizeof(uint16_t), + sizeof(uint16_t), + -FLT_MAX, FLT_MAX); + } +} + +#ifndef KAI_FP16_CAL void mllm_kleidai_gemm_qsi4_to_fp16( mllm_fp16_t *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, int M, int N, int K) { - // 【优化】为临时的FP32输出缓冲区使用线程局部存储 - auto &c_temp = g_workspace_manager.get_qsi4_c_temp_buffer(); + auto &c_temp = WorkspaceManager::get_instance().get_qsi4_c_temp_buffer(); if (c_temp.size() < M * N) { c_temp.resize(M * N); } mllm_kleidai_gemm_qsi4(c_temp.data(), a_ptr, packed_b_ptr, M, N, K); - // ... 后续的 FP32 -> FP16 转换代码保持不变 ... #pragma omp parallel for num_threads(kai_thread_count) for (int i = 0; i <= (M * N) - 4; i += 4) { float32x4_t fp32_vec = vld1q_f32(c_temp.data() + i); @@ -307,10 +540,14 @@ void mllm_kleidai_gemm_qsi4_to_fp16( c_ptr[i] = static_cast(c_temp[i]); } } +#else +void mllm_kleidai_gemm_qsi4_to_fp16( + mllm_fp16_t *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, + int M, int N, int K) { + mllm_kleidai_gemm_qsi4_f16_internal(c_ptr, a_ptr, packed_b_ptr, M, N, K); +} +#endif -// ###################################################################### // -// ## Implementation 2: FP16 ## -// ###################################################################### // #include "kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p_interface.h" #include "kai/ukernels/matmul/matmul_clamp_f16_f16_f16p/kai_matmul_clamp_f16_f16_f16p16x1biasf16_6x16x8_neon_mla.h" #include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f16p16x1biasf16_f16_f16_neon.h" @@ -342,23 +579,17 @@ void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t *packed_b_ptr, const mllm_fp1 N * sizeof(mllm_fp16_t), b_ptr, bias_fp16_buffer.data(), nullptr, packed_b_ptr, 0, nullptr); } -// --- 【替换】旧的 mllm_kleidai_gemm_fp16 函数 --- -// --- 【替换】旧的 mllm_kleidai_gemm_fp16 函数 --- void mllm_kleidai_gemm_fp16(float *c_ptr, const float *a_ptr, const mllm_fp16_t *packed_b_ptr, int M, int N, int K) { - // 【优化】从全局管理器中,获取当前线程专属的缓冲区 - // a_fp16 用于存放 a_ptr 从 FP32 转换到 FP16 的结果 - auto &a_fp16 = g_workspace_manager.get_fp16_a_buffer(); + auto &a_fp16 = WorkspaceManager::get_instance().get_fp16_a_buffer(); if (a_fp16.size() < M * K) { a_fp16.resize(M * K); } - // c_fp16 用于存放 FP16 矩阵乘法的中间结果 - auto &c_fp16 = g_workspace_manager.get_fp16_c_buffer(); + auto &c_fp16 = WorkspaceManager::get_instance().get_fp16_c_buffer(); if (c_fp16.size() < M * N) { c_fp16.resize(M * N); } - // 1. 将输入的 FP32 矩阵 A 并行转换为 FP16,存入线程专属的 a_fp16 缓冲区 #pragma omp parallel for num_threads(kai_thread_count) for (int i = 0; i < M * K; ++i) { a_fp16[i] = static_cast(a_ptr[i]); @@ -367,14 +598,12 @@ void mllm_kleidai_gemm_fp16(float *c_ptr, const float *a_ptr, const mllm_fp16_t const int m_step = fp16_ukernel.get_m_step(); const int n_step = fp16_ukernel.get_n_step(); - // 2. 执行 FP16 矩阵乘法,结果存入线程专属的 c_fp16 缓冲区 #pragma omp parallel for collapse(2) num_threads(kai_thread_count) for (int m_start = 0; m_start < M; m_start += m_step) { for (int n_start = 0; n_start < N; n_start += n_step) { const int current_m = std::min(M - m_start, m_step); const int current_n = std::min(N - n_start, n_step); - // 计算时使用缓冲区的指针 const mllm_fp16_t *a_offset = a_fp16.data() + m_start * K; const mllm_fp16_t *b_offset = packed_b_ptr + (n_start * (K + 1)); mllm_fp16_t *c_offset = c_fp16.data() + m_start * N + n_start; @@ -386,15 +615,12 @@ void mllm_kleidai_gemm_fp16(float *c_ptr, const float *a_ptr, const mllm_fp16_t } } - // 3. 将 FP16 的中间结果并行转换为最终的 FP32 输出 #pragma omp parallel for num_threads(kai_thread_count) for (int i = 0; i < M * N; ++i) { c_ptr[i] = static_cast(c_fp16[i]); } } -// ###################################################################### // -// ## Implementation 3: FP32 ## -// ###################################################################### // + #include "kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p_interface.h" #include "kai/ukernels/matmul/matmul_clamp_f32_f32_f32p/kai_matmul_clamp_f32_f32_f32p8x1biasf32_6x8x4_neon_mla.h" #include "kai/ukernels/matmul/pack/kai_rhs_pack_kxn_f32p8x1biasf32_f32_f32_neon.h" @@ -428,7 +654,6 @@ void mllm_kleidai_gemm_fp32(float *c_ptr, const float *a_ptr, const float *packe const int m_step = fp32_ukernel.get_m_step(); const int n_step = fp32_ukernel.get_n_step(); -// #pragma omp parallel for #pragma omp parallel for collapse(2) num_threads(kai_thread_count) for (int m_start = 0; m_start < M; m_start += m_step) { for (int n_start = 0; n_start < N; n_start += n_step) { @@ -446,30 +671,19 @@ void mllm_kleidai_gemm_fp32(float *c_ptr, const float *a_ptr, const float *packe } } -// --- BEGIN: Transpose-and-Pack Functions --- #include "Transpose2D.hpp" void mllm_kleidai_pack_b_and_bias_fp32_transpose(float *packed_b_ptr, const float *b_ptr_nxk, const float *bias_ptr, int N, int K) { - // 1. Create a temporary buffer for the transposed KxN matrix std::vector b_temp_kxn(K * N); - - // 2. Call the efficient transpose function to fill the buffer transpose_matrix_efficient(b_ptr_nxk, b_temp_kxn.data(), N, K); - - // 3. Call the original packing function with the now correctly-ordered data mllm_kleidai_pack_b_and_bias_fp32(packed_b_ptr, b_temp_kxn.data(), bias_ptr, N, K); } void mllm_kleidai_pack_b_and_bias_fp16_transpose(mllm_fp16_t *packed_b_ptr, const mllm_fp16_t *b_ptr_nxk, const float *bias_ptr, int N, int K) { - // 1. Create a temporary buffer std::vector b_temp_kxn(K * N); - // 2. Perform a cache-friendly transpose for fp16 - // (transpose_matrix_efficient is for float32, so we use its blocking logic here) #if defined(__aarch64__) - // 2. 【高效路径】在ARM平台上,调用为__fp16优化的NEON SIMD转置函数 transpose_matrix_efficient_fp16(b_ptr_nxk, b_temp_kxn.data(), N, K); #else - // 2. 【通用路径】在非ARM平台,使用缓存优化的C++转置 const int BLOCK_DIM = 32; for (int i = 0; i < N; i += BLOCK_DIM) { for (int j = 0; j < K; j += BLOCK_DIM) { @@ -482,37 +696,21 @@ void mllm_kleidai_pack_b_and_bias_fp16_transpose(mllm_fp16_t *packed_b_ptr, cons } #endif - // 3. Call the original fp16 packing function mllm_kleidai_pack_b_and_bias_fp16(packed_b_ptr, b_temp_kxn.data(), bias_ptr, N, K); } -// --- END: Transpose-and-Pack Functions --- -// --- BEGIN: High-Level Transposed GEMM APIs --- - void mllm_kleidai_gemm_fp32_transpose(float *c_ptr, const float *a_ptr, const float *b_ptr_nxk, const float *bias_ptr, int M, int N, int K) { - // Allocate space for the packed B matrix size_t packed_b_size = mllm_kleidai_get_packed_b_fp32_size(N, K); std::vector packed_b_data(packed_b_size); - - // Call the new transpose-and-pack function mllm_kleidai_pack_b_and_bias_fp32_transpose(packed_b_data.data(), b_ptr_nxk, bias_ptr, N, K); - - // Call the original GEMM compute function with the packed data mllm_kleidai_gemm_fp32(c_ptr, a_ptr, packed_b_data.data(), M, N, K); } void mllm_kleidai_gemm_fp16_transpose(float *c_ptr, const float *a_ptr, const mllm_fp16_t *b_ptr_nxk, const float *bias_ptr, int M, int N, int K) { - // Allocate space for the packed B matrix size_t packed_b_size = mllm_kleidai_get_packed_b_fp16_size(N, K); std::vector packed_b_data(packed_b_size / sizeof(mllm_fp16_t)); - - // Call the new transpose-and-pack function mllm_kleidai_pack_b_and_bias_fp16_transpose(packed_b_data.data(), b_ptr_nxk, bias_ptr, N, K); - - // Call the original GEMM compute function with the packed data mllm_kleidai_gemm_fp16(c_ptr, a_ptr, packed_b_data.data(), M, N, K); } -// --- END: High-Level Transposed GEMM APIs --- - #endif \ No newline at end of file diff --git a/src/backends/cpu/compute/GemmKleidiai.hpp b/src/backends/cpu/compute/GemmKleidiai.hpp index 1b533ff14..208545117 100644 --- a/src/backends/cpu/compute/GemmKleidiai.hpp +++ b/src/backends/cpu/compute/GemmKleidiai.hpp @@ -4,44 +4,34 @@ #include // For size_t #include // For uint8_t #include "Types.hpp" -// #if defined(__ARM_FP16_FORMAT_IEEE) -// typedef __fp16 mllm_fp16_t; -// #else -// typedef uint16_t mllm_fp16_t; // Fallback for non-ARM compilation -// #endif - -static int kai_thread_count = 4; +// #define KAI_FP16_CAL -// --- 接口声明 --- - -// --- 实现 1: float * qsi4c32 -> float (底层API) --- +static int kai_thread_count = 4; +// --- 实现 1: float * qsi4c32 -> float--- size_t mllm_kleidai_get_packed_b_qsi4_size(int N, int K); -size_t mllm_kleidai_get_workspace_qsi4_size(int M, int K); -void mllm_kleidai_pack_b_and_bias_qsi4(uint8_t* packed_b_ptr, const float* b_ptr, const float* bias_ptr, int N, int K); -void mllm_kleidai_gemm_qsi4(float* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, int M, int N, int K); +void mllm_kleidai_pack_b_and_bias_qsi4(uint8_t *packed_b_ptr, const float *b_ptr, const float *bias_ptr, int N, int K); +void mllm_kleidai_gemm_qsi4(float *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, int M, int N, int K); +// --- 实现 1.5: float * qsi4c32 -> fp16--- +size_t mllm_kleidai_get_packed_b_qsi4_size_to_fp16(int N, int K); +void mllm_kleidai_pack_b_and_bias_qsi4_to_fp16(uint8_t *packed_b_ptr, const float *b_ptr, const float *bias_ptr, int N, int K); +void mllm_kleidai_gemm_qsi4_to_fp16(mllm_fp16_t *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, int M, int N, int K); -// --- 实现 1.5: float * qsi4c32 -> fp16 (底层API) --- -// 打包和工作区大小计算函数可以复用 USE_QSI4_C32 的 -void mllm_kleidai_gemm_qsi4_to_fp16(mllm_fp16_t* c_ptr, const float* a_ptr, const uint8_t* packed_b_ptr, int M, int N, int K); - -// --- 实现 2: float * fp16 -> float (底层API) --- +// --- 实现 2: float * fp16 -> float--- size_t mllm_kleidai_get_packed_b_fp16_size(int N, int K); -void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t* packed_b_ptr, const mllm_fp16_t* b_ptr, const float* bias_ptr, int N, int K); -void mllm_kleidai_gemm_fp16(float* c_ptr, const float* a_ptr, const mllm_fp16_t* packed_b_ptr, int M, int N, int K); - -// --- 实现 3: float * fp32 -> float (底层API) --- +void mllm_kleidai_pack_b_and_bias_fp16(mllm_fp16_t *packed_b_ptr, const mllm_fp16_t *b_ptr, const float *bias_ptr, int N, int K); +void mllm_kleidai_gemm_fp16(float *c_ptr, const float *a_ptr, const mllm_fp16_t *packed_b_ptr, int M, int N, int K); +// --- 实现 3: float * fp32 -> float--- size_t mllm_kleidai_get_packed_b_fp32_size(int N, int K); -void mllm_kleidai_pack_b_and_bias_fp32(float* packed_b_ptr, const float* b_ptr, const float* bias_ptr, int N, int K); -void mllm_kleidai_gemm_fp32(float* c_ptr, const float* a_ptr, const float* packed_b_ptr, int M, int N, int K); - +void mllm_kleidai_pack_b_and_bias_fp32(float *packed_b_ptr, const float *b_ptr, const float *bias_ptr, int N, int K); +void mllm_kleidai_gemm_fp32(float *c_ptr, const float *a_ptr, const float *packed_b_ptr, int M, int N, int K); // --- APIs for Transposed Right-Hand Matrix Multiplication --- -void mllm_kleidai_gemm_fp32_transpose(float* c_ptr, const float* a_ptr, const float* b_ptr_nxk, const float* bias_ptr, int M, int N, int K); -void mllm_kleidai_gemm_fp16_transpose(float* c_ptr, const float* a_ptr, const mllm_fp16_t* b_ptr_nxk, const float* bias_ptr, int M, int N, int K); +void mllm_kleidai_gemm_fp32_transpose(float *c_ptr, const float *a_ptr, const float *b_ptr_nxk, const float *bias_ptr, int M, int N, int K); +void mllm_kleidai_gemm_fp16_transpose(float *c_ptr, const float *a_ptr, const mllm_fp16_t *b_ptr_nxk, const float *bias_ptr, int M, int N, int K); #endif \ No newline at end of file diff --git a/src/backends/cpu/compute/GemmPack.hpp b/src/backends/cpu/compute/GemmPack.hpp deleted file mode 100644 index cb829cec6..000000000 --- a/src/backends/cpu/compute/GemmPack.hpp +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef MLLM_GEMM_AARCH64_HPP -#define MLLM_GEMM_AARCH64_HPP - -#include "VecDot.hpp" -using namespace mllm; - -// Quantization -void quantize_q8_0_4x4(const float *__restrict x, void *__restrict y, int64_t k); -void quantize_q8_0_4x8(const float *__restrict x, void *__restrict y, int64_t k); - -void quantize_mat_q8_0(const float *__restrict x, void *__restrict y, int64_t nrows, int64_t n_per_row, int64_t blck_size_interleave); - -// Quantization utilizing an importance matrix (a.k.a. "Activation aWare Quantization") -size_t quantize_q4_0_4x4(const float *__restrict src, void *__restrict dst, int64_t nrows, int64_t n_per_row, const float *imatrix); -size_t quantize_q4_0_4x8(const float *__restrict src, void *__restrict dst, int64_t nrows, int64_t n_per_row, const float *imatrix); -size_t quantize_q4_0_8x8(const float *__restrict src, void *__restrict dst, int64_t nrows, int64_t n_per_row, const float *imatrix); - -//===----------------------------------------------------------------------===// -// GEMV -//===----------------------------------------------------------------------===// -void mllm_gemv_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); -void mllm_gemv_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); -void mllm_gemv_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); - -// NOTE: Do not add a bias flag in mllm_gemv_q4_0_4x4_q8_0. It may cause branch miss hit problem. -void _mllm_gemv_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); -void _mllm_gemv_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); -void _mllm_gemv_q4_0_8x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); - -//===----------------------------------------------------------------------===// -// GEMM -//===----------------------------------------------------------------------===// -void mllm_gemm_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); -void mllm_gemm_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); -void mllm_gemm_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); -void _mllm_gemm_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); -void _mllm_gemm_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); -void _mllm_gemm_q4_0_8x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); - -void quantize_row_q4_0_4x4(const float *__restrict x, void *__restrict y, int k); -void quantize_row_q4_0_4x4(const float *__restrict x, void *__restrict y, int k, int raw); - -#endif // MLLM_GEMM_HPP \ No newline at end of file diff --git a/src/backends/cpu/compute/GemmQ2K.cpp b/src/backends/cpu/compute/GemmQ2K.cpp new file mode 100644 index 000000000..3ed03a7fb --- /dev/null +++ b/src/backends/cpu/compute/GemmQ2K.cpp @@ -0,0 +1,348 @@ +#include "GemmQ2K.hpp" + +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" + +#include +#include +#include +#include + +#if defined(__ARM_NEON) +#include +#endif + +#define M_BLOCK_SIZE 8 +#define N_BLOCK_SIZE 16 + +/** + * @brief 为 GEMM 操作对 float 矩阵 B(KxN) 进行 Q8_K 量化和打包。 + * + * 原始的打包方式导致在 GEMM 内核中访问数据时是跨步的 (strided access), + * 这严重破坏了缓存局部性。新的打包方式将微内核所需的数据块连续存储。 + * + * 原始布局 (逻辑上): [N 块][列偏移][K 块] + * 访问模式: `base + n_idx * K_blocks` -> 步长巨大! + * + * 优化后布局 (逻辑上): [N 块][K 块][列偏移] + * 访问模式: `base + n_idx` -> 完美连续访问! + * + * @param B_packed 输出,打包好的 Q8_K 矩阵。 + * @param B_float 输入,行主序的 float 矩阵 (KxN)。 + * @param K 矩阵 B 的行数。 + * @param N 矩阵 B 的列数。 + */ +void quantize_and_pack_q8_k_for_gemm( + block_q8_K *B_packed, + const float *B_float, + int K, + int N) { + assert(K % QK_K == 0); + assert(N % N_BLOCK_SIZE == 0); + const int K_blocks = K / QK_K; + const int N_chunks = N / N_BLOCK_SIZE; + +#pragma omp parallel for num_threads(4) + for (int j_chunk = 0; j_chunk < N_chunks; ++j_chunk) { + std::vector temp_col(QK_K); + for (int k_block = 0; k_block < K_blocks; ++k_block) { + for (int col_offset = 0; col_offset < N_BLOCK_SIZE; ++col_offset) { + const int j = j_chunk * N_BLOCK_SIZE; + for (int k_inner = 0; k_inner < QK_K; ++k_inner) { + const int row_idx = (k_block * QK_K) + k_inner; + const int col_idx = j + col_offset; + temp_col[k_inner] = B_float[(row_idx * N) + col_idx]; + } + // 核心改动:调整写入位置,确保 N_BLOCK_SIZE 这个维度的数据是连续的 + block_q8_K *dest_block = B_packed + (j_chunk * (K_blocks * N_BLOCK_SIZE)) + (k_block * N_BLOCK_SIZE) + col_offset; + quantize_row_q8_K(temp_col.data(), dest_block, QK_K); + } + } + } +} + +#if defined(__ARM_NEON) +/** + * @brief 8x16 NEON 微内核 + * + * 1. 一次性处理一个 8x16 的输出块,共 128 个 float 累加器。 + * 2. 使用 32 个 NEON 向量寄存器中的大部分来保存这些累加器。 + * 3. 对 A 矩阵的数据(scales, quants)在 K 维度内循环前进行预加载和预处理, + * 在 B 矩阵的数据(quants, bsums)在 N 维度上进行向量化加载。 + * 4. 通过精心设计的指令序列,最大化浮点乘加 (FMLA) 指令的吞吐量。 + * 5. 循环展开和指令重排以减少依赖和流水线停顿。 + */ +static inline void micro_kernel_8x16_neon( + float acc[M_BLOCK_SIZE][N_BLOCK_SIZE], + const block_q2_K *a_blocks[M_BLOCK_SIZE], + const block_q8_K *b_block_base) { + // 8x16 = 128 个累加器,用 32 个 float32x4_t 向量寄存器表示 + float32x4_t acc_vecs[8][4]; + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 4; ++j) { + acc_vecs[i][j] = vld1q_f32(&acc[i][j * 4]); + } + } + + // 预加载 B 矩阵的 d + float32x4_t d_b_vecs[4]; + float d_b_vals[16]; + for (int n = 0; n < 16; ++n) d_b_vals[n] = b_block_base[n].d; + for (int j = 0; j < 4; ++j) d_b_vecs[j] = vld1q_f32(&d_b_vals[j * 4]); + + // 预加载 A 矩阵的 d 和 dmin + float d_a_vals[8], dmin_a_vals[8]; + for (int m = 0; m < 8; ++m) { + d_a_vals[m] = MLLM_FP16_TO_FP32(a_blocks[m]->d); + dmin_a_vals[m] = MLLM_FP16_TO_FP32(a_blocks[m]->dmin); + } + + // 内部循环处理一个 QK_K 大小的块 + for (int sub_block_idx = 0; sub_block_idx < QK_K / 16; ++sub_block_idx) { + // --- 1. 处理 dmin * bsums 部分 --- + int16_t bsums_vals[16]; + for (int n = 0; n < 16; ++n) bsums_vals[n] = b_block_base[n].bsums[sub_block_idx]; + + const int16x8_t bsums_vec_lo = vld1q_s16(bsums_vals); + const int16x8_t bsums_vec_hi = vld1q_s16(bsums_vals + 8); + + for (int m = 0; m < 8; ++m) { + const int16_t m_val = (int16_t)(a_blocks[m]->scales[sub_block_idx] >> 4); + + float32x4_t summs_f[4]; + summs_f[0] = vcvtq_f32_s32(vmull_n_s16(vget_low_s16(bsums_vec_lo), m_val)); + summs_f[1] = vcvtq_f32_s32(vmull_n_s16(vget_high_s16(bsums_vec_lo), m_val)); + summs_f[2] = vcvtq_f32_s32(vmull_n_s16(vget_low_s16(bsums_vec_hi), m_val)); + summs_f[3] = vcvtq_f32_s32(vmull_n_s16(vget_high_s16(bsums_vec_hi), m_val)); + + for (int j = 0; j < 4; ++j) { + float32x4_t dmin_a_d_b = vmulq_n_f32(d_b_vecs[j], -dmin_a_vals[m]); + acc_vecs[m][j] = vmlaq_f32(acc_vecs[m][j], dmin_a_d_b, summs_f[j]); + } + } + + // --- 2. 处理主点积部分 --- + // 预加载 B 矩阵的 quants + int8x16_t q8_vecs[16]; + for (int n = 0; n < 16; ++n) { + q8_vecs[n] = vld1q_s8(b_block_base[n].qs + sub_block_idx * 16); + } + + // 对 A 矩阵的每一行 + for (int m = 0; m < 8; ++m) { + const int s_val = a_blocks[m]->scales[sub_block_idx] & 0x0F; + if (s_val == 0) continue; + + uint8_t l_bytes[16]; + for (int k = 0; k < 16; ++k) { + int k_inner = sub_block_idx * 16 + k; + const int ib = k_inner / 128, iib = k_inner % 128, iic = iib % 32, cic = iib / 32; + l_bytes[k] = (a_blocks[m]->qs[ib * 32 + iic] >> (cic * 2)) & 3; + } + const int8x16_t l_vec = vreinterpretq_s8_u8(vld1q_u8(l_bytes)); + + // 计算一行 A 和 16 列 B 的点积 + int32_t s_dot_vals[16]; + for (int n = 0; n < 16; ++n) { + const int16x8_t p_lo = vmull_s8(vget_low_s8(l_vec), vget_low_s8(q8_vecs[n])); + const int16x8_t p_hi = vmull_s8(vget_high_s8(l_vec), vget_high_s8(q8_vecs[n])); + s_dot_vals[n] = vaddvq_s32(vpaddlq_s16(vaddq_s16(p_lo, p_hi))); + } + + // 向量化乘法和累加 + const float32x4_t scale_factor = vdupq_n_f32((float)s_val * d_a_vals[m]); + for (int j = 0; j < 4; ++j) { + float32x4_t isum_f32 = vcvtq_f32_s32(vld1q_s32(&s_dot_vals[j * 4])); + float32x4_t term = vmulq_f32(scale_factor, d_b_vecs[j]); + acc_vecs[m][j] = vmlaq_f32(acc_vecs[m][j], term, isum_f32); + } + } + } + + // 写回累加器 + for (int i = 0; i < 8; ++i) { + for (int j = 0; j < 4; ++j) { + vst1q_f32(&acc[i][j * 4], acc_vecs[i][j]); + } + } +} +#else +// C++ and AVX2 Fallback +static inline void micro_kernel_8x16_reference( + float acc[M_BLOCK_SIZE][N_BLOCK_SIZE], + const block_q2_K *a_blocks[M_BLOCK_SIZE], + const block_q8_K *b_block_base) { + float d_all[M_BLOCK_SIZE][N_BLOCK_SIZE], d_min[M_BLOCK_SIZE][N_BLOCK_SIZE]; + for (int m = 0; m < M_BLOCK_SIZE; ++m) { + for (int n = 0; n < N_BLOCK_SIZE; ++n) { + d_all[m][n] = MLLM_FP16_TO_FP32(a_blocks[m]->d) * b_block_base[n].d; + d_min[m][n] = MLLM_FP16_TO_FP32(a_blocks[m]->dmin) * b_block_base[n].d; + } + } + + for (int sub_block_idx = 0; sub_block_idx < QK_K / 16; ++sub_block_idx) { + int32_t isum_tile[M_BLOCK_SIZE][N_BLOCK_SIZE] = {{0}}; + + for (int k_in_subblock = 0; k_in_subblock < 16; ++k_in_subblock) { + const int k_inner = sub_block_idx * 16 + k_in_subblock; + + int s_vals[M_BLOCK_SIZE], l_vals[M_BLOCK_SIZE]; + for (int m = 0; m < M_BLOCK_SIZE; ++m) { + s_vals[m] = a_blocks[m]->scales[sub_block_idx] & 0x0F; + const int ib = k_inner / 128, iib = k_inner % 128, iic = iib % 32, cic = iib / 32; + l_vals[m] = (a_blocks[m]->qs[ib * 32 + iic] >> (cic * 2)) & 3; + } + + int8_t q_vals[N_BLOCK_SIZE]; + for (int n = 0; n < N_BLOCK_SIZE; ++n) { + q_vals[n] = b_block_base[n].qs[k_inner]; + } + + for (int m = 0; m < M_BLOCK_SIZE; ++m) { + for (int n = 0; n < N_BLOCK_SIZE; ++n) { + isum_tile[m][n] += s_vals[m] * l_vals[m] * q_vals[n]; + } + } + } + + for (int m = 0; m < M_BLOCK_SIZE; ++m) { + const int m_val = a_blocks[m]->scales[sub_block_idx] >> 4; + for (int n = 0; n < N_BLOCK_SIZE; ++n) { + const int32_t summs = m_val * b_block_base[n].bsums[sub_block_idx]; + acc[m][n] += d_all[m][n] * isum_tile[m][n] - d_min[m][n] * summs; + } + } + } +} +#endif + +void gemv_q2_k_q8_k( + float *y, + const block_q2_K *A, + const block_q8_K *x, + int M, + int K) { + assert(K % QK_K == 0); + const int K_blocks = K / QK_K; +#pragma omp parallel for num_threads(4) + for (int i = 0; i < M; ++i) { + float row_sum = 0.0f; + const block_q2_K *A_row = A + i * K_blocks; + for (int k_block = 0; k_block < K_blocks; ++k_block) { + const block_q2_K *a_block = A_row + k_block; + const block_q8_K *x_block = x + k_block; +#if defined(__ARM_NEON__) || defined(__ARM_NEON) + // ... (gemv NEON code remains the same as it was already efficient) + const float d = x_block->d * MLLM_FP16_TO_FP32(a_block->d); + const float dmin = -x_block->d * MLLM_FP16_TO_FP32(a_block->dmin); + + int32_t summs32_total = 0; + { + const uint8x16_t mins_and_scales = vld1q_u8(a_block->scales); + const uint8x16_t mins = vshrq_n_u8(mins_and_scales, 4); + const int16x8_t q8sums_lo = vld1q_s16(x_block->bsums); + const int16x8_t q8sums_hi = vld1q_s16(x_block->bsums + 8); + const int16x8_t mins_lo = vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(mins))); + const int16x8_t mins_hi = vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(mins))); + int32x4_t summs32 = vmull_s16(vget_low_s16(mins_lo), vget_low_s16(q8sums_lo)); + summs32 = vmlal_s16(summs32, vget_high_s16(mins_lo), vget_high_s16(q8sums_lo)); + summs32 = vmlal_s16(summs32, vget_low_s16(mins_hi), vget_low_s16(q8sums_hi)); + summs32 = vmlal_s16(summs32, vget_high_s16(mins_hi), vget_high_s16(q8sums_hi)); + summs32_total = vaddvq_s32(summs32); + } + row_sum += dmin * summs32_total; + + int32_t isum = 0; + { + uint8_t scales_s[16]; + vst1q_u8(scales_s, vandq_u8(vld1q_u8(a_block->scales), vdupq_n_u8(0xF))); + for (int sub_block_idx = 0; sub_block_idx < QK_K / 16; ++sub_block_idx) { + uint8_t l_bytes[16]; + for (int k = 0; k < 16; ++k) { + int k_inner = sub_block_idx * 16 + k; + const int ib = k_inner / 128, iib = k_inner % 128, iic = iib % 32, cic = iib / 32; + l_bytes[k] = (a_block->qs[ib * 32 + iic] >> (cic * 2)) & 3; + } + const int8x16_t l_vec = vreinterpretq_s8_u8(vld1q_u8(l_bytes)); + const int8x16_t q8_vec = vld1q_s8(x_block->qs + sub_block_idx * 16); + const int16x8_t p_lo = vmull_s8(vget_low_s8(l_vec), vget_low_s8(q8_vec)); + const int16x8_t p_hi = vmull_s8(vget_high_s8(l_vec), vget_high_s8(q8_vec)); + isum += vaddvq_s32(vpaddlq_s16(vaddq_s16(p_lo, p_hi))) * scales_s[sub_block_idx]; + } + } + row_sum += d * isum; +#else + for (int k_inner = 0; k_inner < QK_K; ++k_inner) { + const float d = MLLM_FP16_TO_FP32(a_block->d); + const float dmin = MLLM_FP16_TO_FP32(a_block->dmin); + const int sub_block_idx = k_inner / 16; + const uint8_t sm_byte = a_block->scales[sub_block_idx]; + const float s = (float)(sm_byte & 0x0F); + const float m = (float)(sm_byte >> 4); + const int ib = k_inner / 128, iib = k_inner % 128, iic = iib % 32, c_idx = iib / 32; + const uint8_t p_byte = a_block->qs[ib * 32 + iic]; + const int L = (p_byte >> (c_idx * 2)) & 3; + const float a_val = (d * s) * L - (dmin * m); + const float x_val = x_block->d * (float)x_block->qs[k_inner]; + row_sum += a_val * x_val; + } +#endif + } + y[i] = row_sum; + } +} + +/** + * @brief矩阵-矩阵乘法 (GEMM): C = A * B + * + * 1. 采用三层循环分块策略 (i, j, k),并使用 OpenMP 对最外层 j 循环进行并行化, + * 这是 GEMM 优化的经典且高效的并行策略。 + * 2. 主循环以更大的 M_BLOCK_SIZE x N_BLOCK_SIZE (8x16) 的步长进行, + * 处理更大的数据块,提高了计算密度。 + * 3. 在 K 维度上,一次处理一个 QK_K 大小的块,这与数据的量化方式天然契合。 + * 4. 调用上面优化过的 `micro_kernel_8x16` 来执行核心计算。 + * 5. 对 A 和 B 矩阵中参与计算的块地址进行预计算和传递,使微内核的调用更简洁高效。 + */ +void gemm_q2_k_q8_k( + float *C, + const block_q2_K *A, + const block_q8_K *B_packed, + int M, + int N, + int K) { + assert(M % M_BLOCK_SIZE == 0); + assert(N % N_BLOCK_SIZE == 0); + assert(K % QK_K == 0); + + const int K_blocks = K / QK_K; + +#pragma omp parallel for num_threads(4) + for (int j = 0; j < N; j += N_BLOCK_SIZE) { + for (int i = 0; i < M; i += M_BLOCK_SIZE) { + float acc[M_BLOCK_SIZE][N_BLOCK_SIZE] = {{0.0f}}; + + for (int k_block = 0; k_block < K_blocks; ++k_block) { + // --- 优化点 3: 干净利落地传递数据指针 --- + const block_q2_K *a_blocks[M_BLOCK_SIZE]; + for (int m_idx = 0; m_idx < M_BLOCK_SIZE; ++m_idx) { + a_blocks[m_idx] = A + (i + m_idx) * K_blocks + k_block; + } + + // 关键改动:得益于新的 packing 方式,B 矩阵块的地址是连续的 + const block_q8_K *b_block_base = B_packed + (j / N_BLOCK_SIZE) * (K_blocks * N_BLOCK_SIZE) + k_block * N_BLOCK_SIZE; + +#if defined(__ARM_NEON__) || defined(__ARM_NEON) + micro_kernel_8x16_neon(acc, a_blocks, b_block_base); +#else + micro_kernel_8x16_reference(acc, a_blocks, b_block_base); +#endif + } + + // --- 将累加结果写回 C 矩阵 --- + for (int m_idx = 0; m_idx < M_BLOCK_SIZE; ++m_idx) { + for (int n_idx = 0; n_idx < N_BLOCK_SIZE; ++n_idx) { + C[(i + m_idx) * N + (j + n_idx)] = acc[m_idx][n_idx]; + } + } + } + } +} \ No newline at end of file diff --git a/src/backends/cpu/compute/GemmQ2K.hpp b/src/backends/cpu/compute/GemmQ2K.hpp new file mode 100644 index 000000000..8c2ca4d56 --- /dev/null +++ b/src/backends/cpu/compute/GemmQ2K.hpp @@ -0,0 +1,45 @@ +#pragma once +#include "DataType.hpp" + +/** + * @brief 为 GEMM 操作,对 float 矩阵 B(KxN) 进行 Q8_K 量化和打包。 + * 将行主序的 float 矩阵 B(KxN) 转换为适合微内核高效列式访问的打包格式。 + * @param B_packed 输出,打包好的 Q8_K 矩阵。 + * @param B_float 输入,行主序的 float 矩阵 (KxN)。 + * @param K 矩阵 B 的行数。 + * @param N 矩阵 B 的列数。 + */ +void quantize_and_pack_q8_k_for_gemm( + block_q8_K *B_packed, + const float *B_float, + int K, + int N); + +/** + * @brief 矩阵-向量乘法 (GEMV): y = A * x + * @param y 输出向量 (M x 1), float + * @param A 输入矩阵 (M x K), Q2_K 格式, 按行主序存储 + * @param x 输入向量 (K x 1), Q8_K 格式 + * @param M, K 矩阵/向量维度 + */ +void gemv_q2_k_q8_k( + float *y, + const block_q2_K *A, + const block_q8_K *x, + int M, + int K); + +/** + * @brief 矩阵-矩阵乘法 (GEMM): C = A * B + * @param C 输出矩阵 (M x N), float, 列主序 + * @param A 输入矩阵 (M x K), Q2_K 格式, 行主序 + * @param B_packed 输入矩阵 (K x N), 已被 quantize_and_pack 处理过 + * @param M, N, K 矩阵维度 + */ +void gemm_q2_k_q8_k( + float *C, + const block_q2_K *A, + const block_q8_K *B_packed, + int M, + int N, + int K); diff --git a/src/backends/cpu/compute/Matmul.cpp b/src/backends/cpu/compute/Matmul.cpp index c632f3d7e..4e3ac4d03 100644 --- a/src/backends/cpu/compute/Matmul.cpp +++ b/src/backends/cpu/compute/Matmul.cpp @@ -4,8 +4,8 @@ #include "Matmul.hpp" #include "Types.hpp" -#include "VecDotType.hpp" -#include "GemmLlamafile.hpp" +#include "backends/cpu/third_party/ggml/VecDotType.hpp" +#include "backends/cpu/third_party/ggml/GemmLlamafile.hpp" #include #include #include "Arithmetic.hpp" @@ -29,78 +29,78 @@ ErrorCode mat_mul(Tensor *src0, Tensor *src1, Tensor *dst, bool support_bias, Te auto dst_dtype = dst->dtype(); // ----------- BEGIN SME Path Check ----------- -/* -#if defined(__ARM_FEATURE_SME) - if (src0->batch() == 1 && src0->head() == 1 && src1->batch() == 1 && src1->head() == 1 && dst->batch() == 1 && dst->head() == 1 && // Ensure dst also expects B=1, H=1 - src1->ctype() == BSHD && dst->ctype() == BSHD && dst_dtype == MLLM_TYPE_F32) { - // Calculate base pointers for b=0, h=0 - // Assuming blck_size is 1 for F32/F16, so division by blck_size is not strictly needed here - // but kept for consistency if it could be > 1 for some packed types. - const void *p_src0_base = (const char *)src0->rawHostPtr() + src0->offset(0, 0, 0, 0) * type_size(src0_dtype) / blck_size(src0_dtype); - const void *p_src1_base = (const char *)src1->rawHostPtr() + src1->offset(0, 0, 0, 0) * type_size(src1_dtype) / blck_size(src1_dtype); - float *p_dst_base = (float *)((char *)dst->rawHostPtr() + dst->offset(0, 0, 0, 0) * type_size(dst_dtype) / blck_size(dst_dtype)); - - // Leading dimensions (number of columns for row-major) - // For A (src0) M x K: lda = K - // For B (src1, which is W) K x N: ldb = N (cols of W) - // For C (dst) M x N: ldc = N - int lda = K; - int ldb = N; // src1 (W) has N columns - int ldc = N; - - bool sme_path_taken = false; - - if (src0_dtype == MLLM_TYPE_F32 && src1_dtype == MLLM_TYPE_F32) { - // Call SME F32 x F32^T -> F32 - sme_gemm_f32f32_f32( - static_cast(p_src0_base), - static_cast(p_src1_base), - p_dst_base, - M, K, N, lda, ldb, ldc); - sme_path_taken = true; - } else if (src0_dtype == MLLM_TYPE_F16 && src1_dtype == MLLM_TYPE_F16) { -#if MLLM_FP16_SUPPORTED // Ensure mllm_fp16_t is usable - // Call SME F16 x F16^T -> F32 - sme_gemm_f16f16_f32( - static_cast(p_src0_base), - static_cast(p_src1_base), - p_dst_base, - M, K, N, lda, ldb, ldc); - sme_path_taken = true; -#else -// std::cerr << "Warning: MLLM_TYPE_F16 SME path requested but mllm_fp16_t support is limited/dummy." << std::endl; -#endif - } + /* + #if defined(__ARM_FEATURE_SME) + if (src0->batch() == 1 && src0->head() == 1 && src1->batch() == 1 && src1->head() == 1 && dst->batch() == 1 && dst->head() == 1 && // Ensure dst also expects B=1, H=1 + src1->ctype() == BSHD && dst->ctype() == BSHD && dst_dtype == MLLM_TYPE_F32) { + // Calculate base pointers for b=0, h=0 + // Assuming blck_size is 1 for F32/F16, so division by blck_size is not strictly needed here + // but kept for consistency if it could be > 1 for some packed types. + const void *p_src0_base = (const char *)src0->rawHostPtr() + src0->offset(0, 0, 0, 0) * type_size(src0_dtype) / blck_size(src0_dtype); + const void *p_src1_base = (const char *)src1->rawHostPtr() + src1->offset(0, 0, 0, 0) * type_size(src1_dtype) / blck_size(src1_dtype); + float *p_dst_base = (float *)((char *)dst->rawHostPtr() + dst->offset(0, 0, 0, 0) * type_size(dst_dtype) / blck_size(dst_dtype)); + + // Leading dimensions (number of columns for row-major) + // For A (src0) M x K: lda = K + // For B (src1, which is W) K x N: ldb = N (cols of W) + // For C (dst) M x N: ldc = N + int lda = K; + int ldb = N; // src1 (W) has N columns + int ldc = N; + + bool sme_path_taken = false; + + if (src0_dtype == MLLM_TYPE_F32 && src1_dtype == MLLM_TYPE_F32) { + // Call SME F32 x F32^T -> F32 + sme_gemm_f32f32_f32( + static_cast(p_src0_base), + static_cast(p_src1_base), + p_dst_base, + M, K, N, lda, ldb, ldc); + sme_path_taken = true; + } else if (src0_dtype == MLLM_TYPE_F16 && src1_dtype == MLLM_TYPE_F16) { + #if MLLM_FP16_SUPPORTED // Ensure mllm_fp16_t is usable + // Call SME F16 x F16^T -> F32 + sme_gemm_f16f16_f32( + static_cast(p_src0_base), + static_cast(p_src1_base), + p_dst_base, + M, K, N, lda, ldb, ldc); + sme_path_taken = true; + #else + // std::cerr << "Warning: MLLM_TYPE_F16 SME path requested but mllm_fp16_t support is limited/dummy." << std::endl; + #endif + } - if (sme_path_taken) { - if (support_bias && bias != nullptr) { -// Bias addition: Iterating through the single batch/head/sequence -// Assuming bias is [1,1,1,N] or compatible and needs to be added to each M row of C. -// The existing bias logic seems to add bias[0,0,0,n] to C[b,h,s,n]. -// For B=1,H=1, this means C[0,0,s,n] += bias[0,0,0,n]. -// This effectively adds the bias vector to each row of the computed C matrix. -// This can be parallelized if M is large. -#pragma omp parallel for num_threads(thread_count) - for (int m_idx = 0; m_idx < M; ++m_idx) { - mllm_add_fp32(dst->ptrAt(0, 0, m_idx, 0), - bias->ptrAt(0, 0, 0, 0), // Assuming bias is [1,1,1,N] - dst->ptrAt(0, 0, m_idx, 0), - N); // N is dst->dimension() in this context if dst is M seq, N dim + if (sme_path_taken) { + if (support_bias && bias != nullptr) { + // Bias addition: Iterating through the single batch/head/sequence + // Assuming bias is [1,1,1,N] or compatible and needs to be added to each M row of C. + // The existing bias logic seems to add bias[0,0,0,n] to C[b,h,s,n]. + // For B=1,H=1, this means C[0,0,s,n] += bias[0,0,0,n]. + // This effectively adds the bias vector to each row of the computed C matrix. + // This can be parallelized if M is large. + #pragma omp parallel for num_threads(thread_count) + for (int m_idx = 0; m_idx < M; ++m_idx) { + mllm_add_fp32(dst->ptrAt(0, 0, m_idx, 0), + bias->ptrAt(0, 0, 0, 0), // Assuming bias is [1,1,1,N] + dst->ptrAt(0, 0, m_idx, 0), + N); // N is dst->dimension() in this context if dst is M seq, N dim + } } + return MLLM_NO_ERROR; } - return MLLM_NO_ERROR; } - } -#endif // __ARM_FEATURE_SME -*/ + #endif // __ARM_FEATURE_SME + */ // ----------- END SME Path Check ----------- auto vec_dot_type = type_traits[src1_dtype].vec_dot_type; auto vec_dot = type_traits[src1_dtype].vec_dot; auto x_to_vec_dot_type = type_traits[vec_dot_type].from_float; auto from_float_to_mat = type_traits[vec_dot_type].from_float_to_mat; - mllm_gemv_func const gemv = type_traits[src1_dtype].gemv; - mllm_gemm_func const gemm = type_traits[src1_dtype].gemm; + gemv_func const gemv = type_traits[src1_dtype].gemv; + gemm_func const gemm = type_traits[src1_dtype].gemm; auto blck_size_interleave = type_traits[src1_dtype].blck_size_interleave; auto src1_type_size = type_size(src1_dtype); diff --git a/src/backends/cpu/compute/Matmul.hpp b/src/backends/cpu/compute/Matmul.hpp index 7cafe4766..34336b7a6 100644 --- a/src/backends/cpu/compute/Matmul.hpp +++ b/src/backends/cpu/compute/Matmul.hpp @@ -5,7 +5,9 @@ #ifndef MLLM_MATMUL_HPP #define MLLM_MATMUL_HPP -#include "VecDot.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include "backends/cpu/third_party/ggml/Quantize.hpp" using namespace mllm; ErrorCode mat_mul(Tensor *src0_, Tensor *src1, Tensor *dst, bool support_bias, Tensor *bias = nullptr, bool transpose0 = false, bool transpose1 = true, int thread_count = 4); diff --git a/src/backends/cpu/compute/MatmulElastic.cpp b/src/backends/cpu/compute/MatmulElastic.cpp index 88bcfdfc3..5cc3fbad4 100644 --- a/src/backends/cpu/compute/MatmulElastic.cpp +++ b/src/backends/cpu/compute/MatmulElastic.cpp @@ -4,9 +4,9 @@ #include "MatmulElastic.hpp" #include "Types.hpp" -#include "VecDotType.hpp" -// #include -#include "GemmLlamafile.hpp" +#include "backends/cpu/third_party/ggml/VecDotType.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" +#include "backends/cpu/third_party/ggml/GemmLlamafile.hpp" #include #include @@ -31,8 +31,8 @@ ErrorCode mat_mul_elastic(Tensor *src0, Tensor *src1, Tensor *dst, bool support_ auto x_to_vec_dot_type = type_traits[vec_dot_type].from_float; auto from_float_to_mat = type_traits[vec_dot_type].from_float_to_mat; - mllm_gemv_func const gemv = type_traits[src1_dtype].gemv; - mllm_gemm_func const gemm = type_traits[src1_dtype].gemm; + gemv_func const gemv = type_traits[src1_dtype].gemv; + gemm_func const gemm = type_traits[src1_dtype].gemm; auto blck_size_interleave = type_traits[src1_dtype].blck_size_interleave; auto src1_type_size = type_size(src1_dtype); auto src1_blck_size = blck_size(src1_dtype); diff --git a/src/backends/cpu/compute/MatmulElastic.hpp b/src/backends/cpu/compute/MatmulElastic.hpp index b098451c2..47c67df62 100644 --- a/src/backends/cpu/compute/MatmulElastic.hpp +++ b/src/backends/cpu/compute/MatmulElastic.hpp @@ -5,7 +5,8 @@ #ifndef MLLM_MATMULELASTIC_HPP #define MLLM_MATMULELASTIC_HPP -#include "VecDot.hpp" +#include "Tensor.hpp" +#include "Types.hpp" using namespace mllm; ErrorCode mat_mul_elastic(Tensor *src0_, Tensor *src1, Tensor *dst, bool support_bias, Tensor *bias = nullptr, int activate_input_dim = -1, int activate_output_dim = -1, bool transpose0 = false, bool transpose1 = true, int thread_count = 4); diff --git a/src/backends/cpu/compute/MatmulSparse.cpp b/src/backends/cpu/compute/MatmulSparse.cpp index 5d587f992..88145bcf0 100644 --- a/src/backends/cpu/compute/MatmulSparse.cpp +++ b/src/backends/cpu/compute/MatmulSparse.cpp @@ -4,9 +4,9 @@ #include "MatmulSparse.hpp" #include "Types.hpp" -#include "VecDotType.hpp" +#include "backends/cpu/third_party/ggml/VecDotType.hpp" // #include -#include "GemmLlamafile.hpp" +#include "backends/cpu/third_party/ggml/GemmLlamafile.hpp" #include #ifdef __ARM_NEON diff --git a/src/backends/cpu/compute/MatmulSparse.hpp b/src/backends/cpu/compute/MatmulSparse.hpp index ba4798cf2..1523c8374 100644 --- a/src/backends/cpu/compute/MatmulSparse.hpp +++ b/src/backends/cpu/compute/MatmulSparse.hpp @@ -5,7 +5,8 @@ #ifndef MLLM_MATMULSPARSE_HPP #define MLLM_MATMULSPARSE_HPP -#include "VecDot.hpp" +#include "Tensor.hpp" +#include "Types.hpp" using namespace mllm; ErrorCode sparse_mat_mul_id(Tensor *x, Tensor *W, Tensor *ids, Tensor *dst, int thread_count = 4); diff --git a/src/backends/cpu/compute/Pooling.cpp b/src/backends/cpu/compute/Pooling.cpp index 18444eb00..633587a85 100644 --- a/src/backends/cpu/compute/Pooling.cpp +++ b/src/backends/cpu/compute/Pooling.cpp @@ -3,6 +3,7 @@ // #include "Pooling.hpp" +#include "backends/cpu/third_party/ggml/VecDotFP32.hpp" void avgpool2d_fp32_VALID(Tensor *input, Tensor *output, int kernel_h, int kernel_w, int stride_h, int stride_w, int thread_count) { int in_height = input->head(); int in_width = input->dimension(); diff --git a/src/backends/cpu/compute/Pooling.hpp b/src/backends/cpu/compute/Pooling.hpp index e58b0f94f..e30d8c5b7 100644 --- a/src/backends/cpu/compute/Pooling.hpp +++ b/src/backends/cpu/compute/Pooling.hpp @@ -5,7 +5,8 @@ #ifndef POOLING_HPP #define POOLING_HPP -#include "VecDot.hpp" +#include "Tensor.hpp" +#include "Types.hpp" using namespace mllm; void avgpool2d_fp32_VALID(Tensor *input, Tensor *output, int kernel_h, int kernel_w, int stride_h, int stride_w, int thread_count = 4); diff --git a/src/backends/cpu/compute/SageAttention.hpp b/src/backends/cpu/compute/SageAttention.hpp new file mode 100644 index 000000000..69990d58a --- /dev/null +++ b/src/backends/cpu/compute/SageAttention.hpp @@ -0,0 +1,1610 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// --- SIMD Intrinsics --- +#ifdef __AVX2__ +#include +#include +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) +#include +#if defined(__ARM_FP16_FORMAT_IEEE) && !defined(_MSC_VER) +#include +#endif +#endif + +#include "Types.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" +#include "../compute/SageQuantize.hpp" + +#define SAGE_V_I8 + +#ifdef SAGE_V_I8 + +namespace sage_attn_cpu { +const int QK_K_BLOCK_SIZE = QK8_0F; +#define NEG_INF std::numeric_limits::lowest() + +template +inline float to_float(T val); +template <> +inline float to_float(float val) { + return val; +} +template <> +inline float to_float(mllm_fp16_t val) { + return MLLM_FP16_TO_FP32(val); +} + +#if defined(_WIN32) +#include +inline void aligned_alloc(void **ptr, size_t r, size_t a) { + *ptr = _aligned_malloc(r, a); +} +inline void aligned_free(void *ptr) { + _aligned_free(ptr); +} +#else +inline void aligned_alloc(void **ptr, size_t r, size_t a) { + if (a % sizeof(void *) != 0 || (a & (a - 1)) != 0 || posix_memalign(ptr, a, r) != 0) *ptr = nullptr; +} +inline void aligned_free(void *ptr) { + free(ptr); +} +#endif + +#ifdef __AVX2__ +inline float _mm256_hmax_ps(__m256 x) { + __m128 lo = _mm256_castps256_ps128(x); + __m128 hi = _mm256_extractf128_ps(x, 1); + __m128 max_val = _mm_max_ps(lo, hi); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 2, 2))); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 0, 1))); + return _mm_cvtss_f32(max_val); +} +inline int32_t hsum_i32(__m256i v) { + __m128i vlo = _mm256_castsi256_si128(v); + __m128i vhi = _mm256_extracti128_si256(v, 1); + __m128i vsum = _mm_add_epi32(vlo, vhi); + vsum = _mm_add_epi32(vsum, _mm_shuffle_epi32(vsum, _MM_SHUFFLE(1, 0, 3, 2))); + vsum = _mm_add_epi32(vsum, _mm_shuffle_epi32(vsum, _MM_SHUFFLE(2, 3, 0, 1))); + return _mm_cvtsi128_si32(vsum); +} +inline __m256 load_and_convert_to_fp32_vec(const float *ptr) { + return _mm256_loadu_ps(ptr); +} +#ifdef __F16C__ +inline __m256 load_and_convert_to_fp32_vec(const mllm_fp16_t *ptr) { + return _mm256_cvtph_ps(_mm_loadu_si128((const __m128i *)ptr)); +} +#endif +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) +inline void load_and_convert_to_fp32x4x2(const float *ptr, float32x4_t &out_lo, float32x4_t &out_hi) { + out_lo = vld1q_f32(ptr); + out_hi = vld1q_f32(ptr + 4); +} +#if defined(__ARM_FP16_FORMAT_IEEE) +inline void load_and_convert_to_fp32x4x2(const mllm_fp16_t *ptr, float32x4_t &out_lo, float32x4_t &out_hi) { + float16x8_t v_f16 = vld1q_f16(reinterpret_cast(ptr)); + out_lo = vcvt_f32_f16(vget_low_f16(v_f16)); + out_hi = vcvt_f32_f16(vget_high_f16(v_f16)); +} +#endif +#endif + +void quantize_row_per_group_simd(const float *float_row, int8_t *int8_row, float *scales, int dim_size, float sm_scale, float *temp_buf) { + const int num_groups = dim_size / QK_K_BLOCK_SIZE; + for (int g = 0; g < num_groups; ++g) { + const int group_start_idx = g * QK_K_BLOCK_SIZE; + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) temp_buf[d] = float_row[group_start_idx + d] * sm_scale; + float max_abs_val = 0.0f; +#if defined(__AVX2__) + __m256 max_vec = _mm256_setzero_ps(); + const __m256 abs_mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7FFFFFFF)); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 8; d += 8) max_vec = _mm256_max_ps(max_vec, _mm256_and_ps(_mm256_loadu_ps(temp_buf + d), abs_mask)); + max_abs_val = _mm256_hmax_ps(max_vec); + for (; d < QK_K_BLOCK_SIZE; ++d) max_abs_val = std::max(max_abs_val, fabsf(temp_buf[d])); +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t max_vec = vdupq_n_f32(0.0f); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 4; d += 4) max_vec = vmaxq_f32(max_vec, vabsq_f32(vld1q_f32(temp_buf + d))); + max_abs_val = vmaxvq_f32(max_vec); + for (; d < QK_K_BLOCK_SIZE; ++d) max_abs_val = std::max(max_abs_val, fabsf(temp_buf[d])); +#else + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) max_abs_val = std::max(max_abs_val, fabsf(temp_buf[d])); +#endif + const float scale = (max_abs_val > 1e-9f) ? max_abs_val / 127.0f : 0.0f; + scales[g] = scale; + const float inv_scale = (scale > 1e-9f) ? 1.0f / scale : 0.0f; + int8_t *group_int8_row = int8_row + group_start_idx; +#if defined(__AVX2__) + __m256 inv_scale_vec = _mm256_set1_ps(inv_scale); + d = 0; + for (; d <= QK_K_BLOCK_SIZE - 8; d += 8) { + __m256i val_i32 = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_loadu_ps(temp_buf + d), inv_scale_vec)); + __m128i val_i16 = _mm_packs_epi32(_mm256_castsi256_si128(val_i32), _mm256_extracti128_si256(val_i32, 1)); + __m128i val_i8 = _mm_packs_epi16(val_i16, val_i16); + *(int64_t *)(group_int8_row + d) = _mm_cvtsi128_si64(val_i8); + } + for (; d < QK_K_BLOCK_SIZE; ++d) group_int8_row[d] = static_cast(roundf(temp_buf[d] * inv_scale)); +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t inv_scale_vec = vdupq_n_f32(inv_scale); + d = 0; + for (; d <= QK_K_BLOCK_SIZE - 16; d += 16) { + int32x4_t i32_0 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 0), inv_scale_vec)); + int32x4_t i32_1 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 4), inv_scale_vec)); + int32x4_t i32_2 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 8), inv_scale_vec)); + int32x4_t i32_3 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 12), inv_scale_vec)); + int16x8_t i16_0 = vcombine_s16(vqmovn_s32(i32_0), vqmovn_s32(i32_1)); + int16x8_t i16_1 = vcombine_s16(vqmovn_s32(i32_2), vqmovn_s32(i32_3)); + vst1q_s8(group_int8_row + d, vcombine_s8(vqmovn_s16(i16_0), vqmovn_s16(i16_1))); + } + for (; d < QK_K_BLOCK_SIZE; ++d) group_int8_row[d] = static_cast(roundf(temp_buf[d] * inv_scale)); +#else + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) group_int8_row[d] = static_cast(roundf(temp_buf[d] * inv_scale)); +#endif + } +} + +template +void compute_mean_and_quantize_tensor( + const T *tensor_bshd, float *mean_tensor_bhd, int8_t *quant_global_bhsd, + float *scale_global_bhsn, int batch_size, int head_size, int seq_size, + int dim_size, int threads, float *temp_sum, float *temp_smoothed, + float *temp_head_buffer) { +#pragma omp parallel for num_threads(threads) collapse(2) + for (int b = 0; b < batch_size; ++b) { + for (int h = 0; h < head_size; ++h) { + const int thread_id = omp_get_thread_num(); + float *thread_sum_buf = temp_sum + thread_id * dim_size; + float *thread_smoothed_buf = temp_smoothed + thread_id * dim_size; + float *thread_head_buf_bhsd = temp_head_buffer + thread_id * seq_size * dim_size; + + float *target_mean = mean_tensor_bhd + (b * head_size + h) * dim_size; + const int num_blocks = dim_size / QK_K_BLOCK_SIZE; + int8_t *target_quant_bhsd = quant_global_bhsd + (b * head_size + h) * seq_size * dim_size; + float *target_scale_bhsn = scale_global_bhsn + (b * head_size + h) * seq_size * num_blocks; + + memset(thread_sum_buf, 0, dim_size * sizeof(float)); + + for (int s = 0; s < seq_size; ++s) { + const T *row_global_bshd = tensor_bshd + (size_t)b * seq_size * head_size * dim_size + (size_t)s * head_size * dim_size + (size_t)h * dim_size; + float *row_buffered_bhsd = thread_head_buf_bhsd + s * dim_size; +#if defined(__AVX2__) + int d = 0; + for (; d <= dim_size - 8; d += 8) { + const __m256 val_vec = load_and_convert_to_fp32_vec(row_global_bshd + d); + _mm256_storeu_ps(row_buffered_bhsd + d, val_vec); + __m256 sum_vec = _mm256_loadu_ps(thread_sum_buf + d); + sum_vec = _mm256_add_ps(sum_vec, val_vec); + _mm256_storeu_ps(thread_sum_buf + d, sum_vec); + } + for (; d < dim_size; ++d) { + float val = to_float(row_global_bshd[d]); + row_buffered_bhsd[d] = val; + thread_sum_buf[d] += val; + } +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + int d = 0; + for (; d <= dim_size - 8; d += 8) { + float32x4_t val_lo, val_hi; + load_and_convert_to_fp32x4x2(row_global_bshd + d, val_lo, val_hi); + vst1q_f32(row_buffered_bhsd + d, val_lo); + vst1q_f32(row_buffered_bhsd + d + 4, val_hi); + float32x4_t sum_lo = vld1q_f32(thread_sum_buf + d); + float32x4_t sum_hi = vld1q_f32(thread_sum_buf + d + 4); + vst1q_f32(thread_sum_buf + d, vaddq_f32(sum_lo, val_lo)); + vst1q_f32(thread_sum_buf + d + 4, vaddq_f32(sum_hi, val_hi)); + } + for (; d < dim_size; ++d) { + float val = to_float(row_global_bshd[d]); + row_buffered_bhsd[d] = val; + thread_sum_buf[d] += val; + } +#else + for (int d = 0; d < dim_size; ++d) { + float val = to_float(row_global_bshd[d]); + row_buffered_bhsd[d] = val; + thread_sum_buf[d] += val; + } +#endif + } + + const float inv_seq_len = 1.0f / seq_size; +#if defined(__AVX2__) + const __m256 inv_len_vec = _mm256_set1_ps(inv_seq_len); + int d = 0; + for (; d <= dim_size - 8; d += 8) _mm256_storeu_ps(target_mean + d, _mm256_mul_ps(_mm256_loadu_ps(thread_sum_buf + d), inv_len_vec)); + for (; d < dim_size; ++d) target_mean[d] = thread_sum_buf[d] * inv_seq_len; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const float32x4_t inv_len_vec = vdupq_n_f32(inv_seq_len); + int d = 0; + for (; d <= dim_size - 4; d += 4) vst1q_f32(target_mean + d, vmulq_f32(vld1q_f32(thread_sum_buf + d), inv_len_vec)); + for (; d < dim_size; ++d) target_mean[d] = thread_sum_buf[d] * inv_seq_len; +#else + for (int d = 0; d < dim_size; ++d) target_mean[d] = thread_sum_buf[d] * inv_seq_len; +#endif + + for (int s = 0; s < seq_size; ++s) { + const float *row_buffered_bhsd = thread_head_buf_bhsd + s * dim_size; +#if defined(__AVX2__) + int d = 0; + for (; d <= dim_size - 8; d += 8) _mm256_storeu_ps(thread_smoothed_buf + d, _mm256_sub_ps(_mm256_loadu_ps(row_buffered_bhsd + d), _mm256_loadu_ps(target_mean + d))); + for (; d < dim_size; ++d) thread_smoothed_buf[d] = row_buffered_bhsd[d] - target_mean[d]; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + int d = 0; + for (; d <= dim_size - 4; d += 4) vst1q_f32(thread_smoothed_buf + d, vsubq_f32(vld1q_f32(row_buffered_bhsd + d), vld1q_f32(target_mean + d))); + for (; d < dim_size; ++d) thread_smoothed_buf[d] = row_buffered_bhsd[d] - target_mean[d]; +#else + for (int d = 0; d < dim_size; ++d) thread_smoothed_buf[d] = row_buffered_bhsd[d] - target_mean[d]; +#endif + quantize_row_per_group_simd(thread_smoothed_buf, target_quant_bhsd + s * dim_size, target_scale_bhsn + s * num_blocks, dim_size, 1.0f, thread_sum_buf); + } + } + } +} + +class WorkspaceManager { +public: + WorkspaceManager() = default; + ~WorkspaceManager() { + for (auto &p : workspace_) + if (p) aligned_free(p); + } + void **get_workspace(const std::vector &s) { + if (workspace_.empty()) { + workspace_.resize(s.size(), nullptr); + current_sizes_.resize(s.size(), 0); + } + for (size_t i = 0; i < s.size(); ++i) { + if (s[i] > current_sizes_[i]) { + if (workspace_[i]) aligned_free(workspace_[i]); + aligned_alloc(&workspace_[i], s[i], 64); + current_sizes_[i] = s[i]; + } + } + return workspace_.data(); + } + +private: + std::vector workspace_; + std::vector current_sizes_; +}; + +template +struct SAGE_CPU_IMPL { + using TQ = float; + using TKV = KVDtype; + using TO = float; + int32_t Br, Bc, Q_Head, KV_Head, threads; + float *acc_o, *acc_s, *logsum, *scoremax, *scoremax_prev, *score_scale, *score_sum; + int8_t *q_quant, *k_quant_global, *v_quant_global; + float *q_scale, *k_scale_global, *v_scale_global, *k_smoothed_buf, *q_scaled_buf; + + int8_t *p_quant; + float *p_scale; + + void configure(int32_t Br_, int32_t Bc_, int32_t Q_H, int32_t KV_H, int32_t T) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_H; + KV_Head = KV_H; + threads = T; + } + + void init_workspace(void **ws) { + acc_o = static_cast(ws[0]); + acc_s = static_cast(ws[1]); + logsum = static_cast(ws[2]); + scoremax = static_cast(ws[3]); + scoremax_prev = static_cast(ws[4]); + score_scale = static_cast(ws[5]); + score_sum = static_cast(ws[6]); + q_quant = static_cast(ws[7]); + k_quant_global = static_cast(ws[8]); + q_scale = static_cast(ws[9]); + k_scale_global = static_cast(ws[10]); + k_smoothed_buf = static_cast(ws[11]); + q_scaled_buf = static_cast(ws[12]); + v_quant_global = static_cast(ws[15]); + v_scale_global = static_cast(ws[16]); + + p_quant = static_cast(ws[18]); + p_scale = static_cast(ws[19]); + } + + void init_temp(float *l, float *sm, float *o, int Br_f, int D) { + for (int i = 0; i < Br_f; ++i) { + l[i] = 0.0f; + sm[i] = -std::numeric_limits::infinity(); + } + if (o) memset(o, 0, Br_f * D * sizeof(float)); + } + + void quantize_p_rows(int Br_f, int Bc_f, const float *p_float_block, int8_t *p_quant_block, float *p_scale_block) { + for (int r = 0; r < Br_f; ++r) { + const float *p_float_row = p_float_block + r * Bc; + int8_t *p_quant_row = p_quant_block + r * Bc; + + float max_abs_val = 0.0f; + for (int c = 0; c < Bc_f; ++c) { + max_abs_val = std::max(max_abs_val, fabsf(p_float_row[c])); + } + + const float scale = (max_abs_val > 1e-9f) ? max_abs_val / 127.0f : 0.0f; + p_scale_block[r] = scale; + const float inv_scale = (scale > 1e-9f) ? 1.0f / scale : 0.0f; + + for (int c = 0; c < Bc_f; ++c) { + p_quant_row[c] = static_cast(roundf(p_float_row[c] * inv_scale)); + } + } + } + + void sage_attn_prefill(const TQ *Q, TO *O, const float *K_mean, const float *V_mean, int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, bool causal) { + const int32_t Tr = (seq_size_q + Br - 1) / Br, Tc = (seq_size_k + Bc - 1) / Bc; + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + const int32_t num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + for (int32_t b = 0; b < batch_size; ++b) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) + for (int32_t h = 0; h < head_size; ++h) { + const int32_t tid = omp_get_thread_num(); + const int32_t kvh = h / kv_group; + float *po = acc_o + tid * Br * dim_size, *ps = acc_s + tid * Br * Bc; + float *plog = logsum + tid * Br, *pmax = scoremax + tid * Br, *pmax_p = scoremax_prev + tid * Br; + float *pscale = score_scale + tid * Br, *psum = score_sum + tid * Br; + int8_t *p_q_q = q_quant + tid * Br * dim_size; + const int8_t *p_k_q_g = k_quant_global + (b * KV_Head + kvh) * seq_size_k * dim_size; + const int8_t *p_v_q_g = v_quant_global + (b * KV_Head + kvh) * seq_size_k * dim_size; + float *p_q_s = q_scale + tid * Br * num_k_blocks; + const float *p_k_s_g = k_scale_global + (b * KV_Head + kvh) * seq_size_k * num_k_blocks; + const float *p_v_s_g = v_scale_global + (b * KV_Head + kvh) * seq_size_k * num_k_blocks; + float *p_q_scaled = q_scaled_buf + tid * dim_size; + const float *p_V_m = V_mean + (b * KV_Head + kvh) * dim_size; + + int8_t *p_p_q = p_quant + tid * Br * Bc; + float *p_p_s = p_scale + tid * Br; + + for (int32_t tr = 0; tr < Tr; ++tr) { + int32_t Br_f = std::min(Br, seq_size_q - tr * Br); + init_temp(plog, pmax, po, Br_f, dim_size); + const TQ *tile_q_bshd = Q + (size_t)b * seq_size_q * head_size * dim_size + (size_t)tr * Br * head_size * dim_size + (size_t)h * dim_size; + for (int r = 0; r < Br_f; ++r) quantize_row_per_group_simd(tile_q_bshd + (size_t)r * head_size * dim_size, p_q_q + r * dim_size, p_q_s + r * num_k_blocks, dim_size, local_scale, p_q_scaled); + for (int32_t tc = 0; tc < Tc; ++tc) { + int32_t Bc_f = std::min(Bc, seq_size_k - tc * Bc); + const int kv_offset = seq_size_k - seq_size_q; + quantize_and_mma0_sdot(Br_f, Bc_f, p_q_q, p_k_q_g + tc * Bc * dim_size, ps, p_q_s, p_k_s_g + tc * Bc * num_k_blocks, dim_size, tr * Br + kv_offset, tc * Bc, causal); + softmax(Br_f, Bc_f, ps, pmax, pmax_p, pscale, psum, plog); + rescale(Br_f, po, pscale, dim_size); + + quantize_p_rows(Br_f, Bc_f, ps, p_p_q, p_p_s); + + const int8_t *v_q = p_v_q_g + tc * Bc * dim_size; + const float *v_s = p_v_s_g + tc * Bc * num_k_blocks; + + mma1(Br_f, Bc_f, p_p_q, p_p_s, v_q, v_s, po, dim_size); + } + TO *tile_o_bshd = O + (size_t)b * seq_size_q * head_size * dim_size + (size_t)tr * Br * head_size * dim_size + (size_t)h * dim_size; + scale_and_store(Br_f, po, plog, p_V_m, tile_o_bshd, head_size, dim_size); + } + } + } + } + void sage_attn_decode(const TQ *Q, TO *O, const float *K_mean, const float *V_mean, int32_t batch_size, int32_t head_size, int32_t seq_size_k, int32_t dim_size, bool causal) { + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + const int32_t num_k_blocks = dim_size / QK_K_BLOCK_SIZE; +#pragma omp parallel for num_threads(threads) collapse(2) + for (int32_t b = 0; b < batch_size; ++b) { + for (int32_t h = 0; h < head_size; ++h) { + const int32_t Br_f = 1; + const int32_t tid = omp_get_thread_num(); + const int32_t kvh = h / kv_group; + float *po = acc_o + tid * Br_f * dim_size, *ps = acc_s + tid * Br_f * Bc; + float *plog = logsum + tid * Br_f, *pmax = scoremax + tid * Br_f, *pmax_p = scoremax_prev + tid * Br_f; + float *pscale = score_scale + tid * Br_f, *psum = score_sum + tid * Br_f; + int8_t *p_q_q = q_quant + tid * Br_f * dim_size; + const int8_t *p_k_q_g = k_quant_global + (b * KV_Head + kvh) * seq_size_k * dim_size; + const int8_t *p_v_q_g = v_quant_global + (b * KV_Head + kvh) * seq_size_k * dim_size; + float *p_q_s = q_scale + tid * Br_f * num_k_blocks; + const float *p_k_s_g = k_scale_global + (b * KV_Head + kvh) * seq_size_k * num_k_blocks; + const float *p_v_s_g = v_scale_global + (b * KV_Head + kvh) * seq_size_k * num_k_blocks; + float *p_q_scaled = q_scaled_buf + tid * dim_size; + const float *p_V_m = V_mean + (b * KV_Head + kvh) * dim_size; + + // [新增] 获取量化P矩阵的工作区指针 + int8_t *p_p_q = p_quant + tid * Br_f * Bc; + float *p_p_s = p_scale + tid * Br_f; + + const TQ *tile_q_bshd = Q + (size_t)b * 1 * head_size * dim_size + (size_t)0 * head_size * dim_size + (size_t)h * dim_size; + quantize_row_per_group_simd(tile_q_bshd, p_q_q, p_q_s, dim_size, local_scale, p_q_scaled); + init_temp(plog, pmax, po, Br_f, dim_size); + for (int32_t tc = 0; tc < Tc; ++tc) { + int32_t Bc_f = std::min(Bc, seq_size_k - tc * Bc); + quantize_and_mma0_sdot(Br_f, Bc_f, p_q_q, p_k_q_g + tc * Bc * dim_size, ps, p_q_s, p_k_s_g + tc * Bc * num_k_blocks, dim_size, seq_size_k - 1, tc * Bc, causal); + softmax(Br_f, Bc_f, ps, pmax, pmax_p, pscale, psum, plog); + rescale(Br_f, po, pscale, dim_size); + + quantize_p_rows(Br_f, Bc_f, ps, p_p_q, p_p_s); + + const int8_t *v_q = p_v_q_g + tc * Bc * dim_size; + const float *v_s = p_v_s_g + tc * Bc * num_k_blocks; + + mma1(Br_f, Bc_f, p_p_q, p_p_s, v_q, v_s, po, dim_size); + } + TO *tile_o_bshd = O + (size_t)b * 1 * head_size * dim_size + (size_t)0 * head_size * dim_size + (size_t)h * dim_size; + scale_and_store(Br_f, po, plog, p_V_m, tile_o_bshd, head_size, dim_size); + } + } + } + void quantize_and_mma0_sdot(int Br_f, int Bc_f, const int8_t *q_q, const int8_t *k_q, float *s, const float *q_s, const float *k_s, int D, int grs, int gcs, bool causal) { + const int num_k_blocks = D / QK_K_BLOCK_SIZE; + for (int r = 0; r < Br_f; ++r) + for (int c = 0; c < Bc_f; ++c) { + if (causal && (gcs + c) > (grs + r)) { + s[r * Bc + c] = NEG_INF; + continue; + } + const int8_t *q_ql = q_q + r * D, *k_ql = k_q + c * D; + const float *q_sl = q_s + r * num_k_blocks, *k_sl = k_s + c * num_k_blocks; + float total_f32 = 0.0f; + for (int g = 0; g < num_k_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + int32_t g_dot = 0; +#if defined(__AVX2__) + __m256i acc_i32_v = _mm256_setzero_si256(); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 16; d += 16) { + __m128i q_i8_v = _mm_loadu_si128((const __m128i *)(q_ql + g_start + d)); + __m128i k_i8_v = _mm_loadu_si128((const __m128i *)(k_ql + g_start + d)); + __m256i q_i16_v = _mm256_cvtepi8_epi16(q_i8_v); + __m256i k_i16_v = _mm256_cvtepi8_epi16(k_i8_v); + __m256i prod_i32_v = _mm256_madd_epi16(k_i16_v, q_i16_v); + acc_i32_v = _mm256_add_epi32(acc_i32_v, prod_i32_v); + } + g_dot = hsum_i32(acc_i32_v); + for (; d < QK_K_BLOCK_SIZE; ++d) g_dot += (q_ql + g_start)[d] * (k_ql + g_start)[d]; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FEATURE_DOTPROD) + int32x4_t acc_i32_vec = vdupq_n_s32(0); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 16; d += 16) acc_i32_vec = vdotq_s32(acc_i32_vec, vld1q_s8(q_ql + g_start + d), vld1q_s8(k_ql + g_start + d)); + g_dot = vaddvq_s32(acc_i32_vec); + for (; d < QK_K_BLOCK_SIZE; ++d) g_dot += (q_ql + g_start)[d] * (k_ql + g_start)[d]; +#else + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) g_dot += (q_ql + g_start)[d] * (k_ql + g_start)[d]; +#endif + total_f32 += (float)g_dot * q_sl[g] * k_sl[g]; + } + s[r * Bc + c] = total_f32; + } + } + void softmax(int Br_f, int Bc_f, float *acc_s, float *sm, float *sm_p, float *ss, float *sum, float *l) { + memcpy(sm_p, sm, Br_f * sizeof(float)); + for (int r = 0; r < Br_f; ++r) { + float *row = acc_s + r * Bc, cmax = sm[r]; + for (int c = 0; c < Bc_f; ++c) cmax = std::max(cmax, row[c]); + sm[r] = cmax; + } + for (int r = 0; r < Br_f; ++r) ss[r] = expf(sm_p[r] - sm[r]); + for (int r = 0; r < Br_f; ++r) { + float *row = acc_s + r * Bc; + float smax = sm[r], s = 0.f; + for (int c = 0; c < Bc_f; ++c) row[c] = (row[c] > NEG_INF / 2) ? (s += row[c] = expf(row[c] - smax), row[c]) : 0.f; + sum[r] = s; + } + for (int r = 0; r < Br_f; ++r) l[r] = l[r] * ss[r] + sum[r]; + } + void rescale(int Br_f, float *acc_o, const float *ss, int D) { + for (int r = 0; r < Br_f; ++r) { + float s_val = ss[r], *r_ptr = acc_o + r * D; +#if defined(__AVX2__) + __m256 s_vec = _mm256_set1_ps(s_val); + int d = 0; + for (; d <= D - 8; d += 8) _mm256_storeu_ps(r_ptr + d, _mm256_mul_ps(_mm256_loadu_ps(r_ptr + d), s_vec)); + for (; d < D; ++d) r_ptr[d] *= s_val; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t s_vec = vdupq_n_f32(s_val); + int d = 0; + for (; d <= D - 4; d += 4) vst1q_f32(r_ptr + d, vmulq_f32(vld1q_f32(r_ptr + d), s_vec)); + for (; d < D; ++d) r_ptr[d] *= s_val; +#else + for (int d = 0; d < D; ++d) r_ptr[d] *= s_val; +#endif + } + } + + void mma1(int Br_f, int Bc_f, const int8_t *p_quant_block, const float *p_scale_block, const int8_t *v_quant_block, const float *v_scale_block, float *acc_o, int D) { + const int num_v_blocks = D / QK_K_BLOCK_SIZE; + for (int r = 0; r < Br_f; ++r) { + const float p_row_scale = p_scale_block[r]; + if (fabsf(p_row_scale) < 1e-9) continue; + + const int8_t *p_quant_row = p_quant_block + r * Bc; + float *o_row = acc_o + r * D; + + for (int c = 0; c < Bc_f; ++c) { + const int8_t p_quant_scalar = p_quant_row[c]; + if (p_quant_scalar == 0) continue; + + const float p_dequant_val = (float)p_quant_scalar * p_row_scale; + + const int8_t *v_q_row = v_quant_block + c * D; + const float *v_s_row = v_scale_block + c * num_v_blocks; + +#if defined(__AVX2__) && defined(__FMA__) + const __m256 p_vec = _mm256_set1_ps(p_dequant_val); + for (int g = 0; g < num_v_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + const __m256 v_scale_vec = _mm256_set1_ps(v_s_row[g]); + for (int d_group = 0; d_group < QK_K_BLOCK_SIZE; d_group += 8) { + const int d = g_start + d_group; + __m128i v_i8_vec_part = _mm_loadl_epi64((const __m128i *)(v_q_row + d)); + __m256i v_i32_vec = _mm256_cvtepi8_epi32(v_i8_vec_part); + __m256 v_f32_vec = _mm256_cvtepi32_ps(v_i32_vec); + __m256 dequant_v_vec = _mm256_mul_ps(v_f32_vec, v_scale_vec); + __m256 o_vec = _mm256_loadu_ps(o_row + d); + o_vec = _mm256_fmadd_ps(p_vec, dequant_v_vec, o_vec); + _mm256_storeu_ps(o_row + d, o_vec); + } + } +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const float32x4_t p_vec = vdupq_n_f32(p_dequant_val); + for (int g = 0; g < num_v_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + const float32x4_t v_scale_vec = vdupq_n_f32(v_s_row[g]); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 8; d += 8) { + int8x8_t v_i8 = vld1_s8(v_q_row + g_start + d); + int16x8_t v_i16 = vmovl_s8(v_i8); + int32x4_t v_i32_lo = vmovl_s16(vget_low_s16(v_i16)); + int32x4_t v_i32_hi = vmovl_s16(vget_high_s16(v_i16)); + float32x4_t v_f32_lo = vcvtq_f32_s32(v_i32_lo); + float32x4_t v_f32_hi = vcvtq_f32_s32(v_i32_hi); + v_f32_lo = vmulq_f32(v_f32_lo, v_scale_vec); + v_f32_hi = vmulq_f32(v_f32_hi, v_scale_vec); + float32x4_t o_f32_lo = vld1q_f32(o_row + g_start + d); + float32x4_t o_f32_hi = vld1q_f32(o_row + g_start + d + 4); + // FMA: O += P * V_dequant + o_f32_lo = vfmaq_f32(o_f32_lo, p_vec, v_f32_lo); + o_f32_hi = vfmaq_f32(o_f32_hi, p_vec, v_f32_hi); + vst1q_f32(o_row + g_start + d, o_f32_lo); + vst1q_f32(o_row + g_start + d + 4, o_f32_hi); + } + for (; d < QK_K_BLOCK_SIZE; ++d) { + o_row[g_start + d] += p_dequant_val * ((float)v_q_row[g_start + d] * v_s_row[g]); + } + } +#else + for (int g = 0; g < num_v_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + const float v_s = v_s_row[g]; + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) { + o_row[g_start + d] += p_dequant_val * ((float)v_q_row[g_start + d] * v_s); + } + } +#endif + } + } + } + + void scale_and_store(int Br_f, const float *acc_o, const float *logsum, const float *v_mean, TO *O, int H, int D) { + int o_stride = H * D; + for (int r = 0; r < Br_f; ++r) { + float inv_logsum = (logsum[r] > 1e-9f) ? 1.f / logsum[r] : 0.f; + const float *o_row = acc_o + r * D; + float *O_row = O + (size_t)r * o_stride; +#if defined(__AVX2__) && defined(__FMA__) + const __m256 inv_l_vec = _mm256_set1_ps(inv_logsum); + int d = 0; + for (; d <= D - 8; d += 8) { + const __m256 o_vec = _mm256_loadu_ps(o_row + d); + const __m256 vm_vec = _mm256_loadu_ps(v_mean + d); + _mm256_storeu_ps(O_row + d, _mm256_fmadd_ps(o_vec, inv_l_vec, vm_vec)); + } + for (; d < D; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const float32x4_t inv_l_vec = vdupq_n_f32(inv_logsum); + int d = 0; + for (; d <= D - 4; d += 4) { + const float32x4_t o_vec = vld1q_f32(o_row + d); + const float32x4_t vm_vec = vld1q_f32(v_mean + d); + vst1q_f32(O_row + d, vfmaq_f32(vm_vec, o_vec, inv_l_vec)); + } + for (; d < D; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#else + for (int d = 0; d < D; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#endif + } + } +}; + +template +void sage_attention_forward_cpu_dispatch( + const float *Q, const void *K_in, const void *V_in, const float *K_mean_ext, + const float *V_mean_ext, float *O, int32_t batch_size, int32_t q_head, + int32_t kv_head, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, + bool causal_mask, int32_t threads, int32_t br, int32_t bc, + int32_t cache_stride_s) { + if (dim_size % QK_K_BLOCK_SIZE != 0) { + std::cerr << "Error: dim_size must be divisible by QK_K_BLOCK_SIZE\n"; + return; + } + const int32_t num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + + thread_local WorkspaceManager manager; + SAGE_CPU_IMPL op; + op.configure(br, bc, q_head, kv_head, threads); + + const int32_t current_br = (seq_size_q > 1) ? br : 1; + + const std::vector ws_sizes = { + (size_t)threads * current_br * dim_size * sizeof(float), // 0: acc_o + (size_t)threads * current_br * bc * sizeof(float), // 1: acc_s + (size_t)threads * current_br * sizeof(float), // 2: logsum + (size_t)threads * current_br * sizeof(float), // 3: scoremax + (size_t)threads * current_br * sizeof(float), // 4: scoremax_prev + (size_t)threads * current_br * sizeof(float), // 5: score_scale + (size_t)threads * current_br * sizeof(float), // 6: score_sum + (size_t)threads * current_br * dim_size * sizeof(int8_t), // 7: q_quant + (size_t)batch_size * kv_head * seq_size_k * dim_size * sizeof(int8_t), // 8: k_quant_global + (size_t)threads * current_br * num_k_blocks * sizeof(float), // 9: q_scale + (size_t)batch_size * kv_head * seq_size_k * num_k_blocks * sizeof(float), // 10: k_scale_global + (size_t)threads * dim_size * sizeof(float), // 11: k_smoothed_buf + (size_t)threads * dim_size * sizeof(float), // 12: q_scaled_buf + (size_t)threads * dim_size * sizeof(float), // 13: temp_k_sum + (size_t)threads * seq_size_k * dim_size * sizeof(float), // 14: temp_k_head_buffer + (size_t)batch_size * kv_head * seq_size_k * dim_size * sizeof(int8_t), // 15: v_quant_global + (size_t)batch_size * kv_head * seq_size_k * num_k_blocks * sizeof(float), // 16: v_scale_global + (size_t)threads * seq_size_k * dim_size * sizeof(float), // 17: temp_v_head_buffer + (size_t)threads * current_br * bc * sizeof(int8_t), // 18: p_quant [新增] + (size_t)threads * current_br * sizeof(float) // 19: p_scale [新增] + }; + void **workspace = manager.get_workspace(ws_sizes); + op.init_workspace(workspace); + + if constexpr (std::is_same_v) { + const auto *k_blocks_bhsd = reinterpret_cast(K_in); + const auto *v_blocks_bhsd = reinterpret_cast(V_in); + +#pragma omp parallel for collapse(3) num_threads(threads) + for (int b = 0; b < batch_size; ++b) { + for (int h = 0; h < kv_head; ++h) { + for (int s = 0; s < seq_size_k; ++s) { + size_t sparse_offset = ((size_t)b * kv_head + h) * cache_stride_s + s; + const block_q8_0f *k_block_src = k_blocks_bhsd + sparse_offset * num_k_blocks; + const block_q8_0f *v_block_src = v_blocks_bhsd + sparse_offset * num_k_blocks; + + size_t dense_offset = ((size_t)b * kv_head + h) * seq_size_k + s; + int8_t *k_quant_dest = op.k_quant_global + dense_offset * dim_size; + float *k_scale_dest = op.k_scale_global + dense_offset * num_k_blocks; + int8_t *v_quant_dest = op.v_quant_global + dense_offset * dim_size; + float *v_scale_dest = op.v_scale_global + dense_offset * num_k_blocks; + + for (int g = 0; g < num_k_blocks; ++g) { + k_scale_dest[g] = k_block_src[g].scale; + memcpy(k_quant_dest + g * QK8_0F, k_block_src[g].qs, QK8_0F); + v_scale_dest[g] = v_block_src[g].scale; + memcpy(v_quant_dest + g * QK8_0F, v_block_src[g].qs, QK8_0F); + } + } + } + } + if (seq_size_q > 1) { + op.sage_attn_prefill(Q, O, K_mean_ext, V_mean_ext, batch_size, q_head, + seq_size_q, seq_size_k, dim_size, causal_mask); + } else { + op.sage_attn_decode(Q, O, K_mean_ext, V_mean_ext, batch_size, q_head, + seq_size_k, dim_size, causal_mask); + } + } else { + std::vector K_mean_internal((size_t)batch_size * kv_head * dim_size); + std::vector V_mean_internal((size_t)batch_size * kv_head * dim_size); + const auto *K = static_cast(K_in); + const auto *V = static_cast(V_in); + compute_mean_and_quantize_tensor( + K, K_mean_internal.data(), op.k_quant_global, op.k_scale_global, + batch_size, kv_head, seq_size_k, dim_size, threads, + (float *)workspace[13], (float *)workspace[11], (float *)workspace[14]); + compute_mean_and_quantize_tensor( + V, V_mean_internal.data(), op.v_quant_global, op.v_scale_global, + batch_size, kv_head, seq_size_k, dim_size, threads, + (float *)workspace[13], (float *)workspace[11], (float *)workspace[17]); + + if (seq_size_q > 1) { + op.sage_attn_prefill(Q, O, K_mean_internal.data(), V_mean_internal.data(), + batch_size, q_head, seq_size_q, seq_size_k, dim_size, + causal_mask); + } else { + op.sage_attn_decode(Q, O, K_mean_internal.data(), V_mean_internal.data(), + batch_size, q_head, seq_size_k, dim_size, + causal_mask); + } + } +} +} // namespace sage_attn_cpu + +#else +namespace sage_attn_cpu { +const int QK_K_BLOCK_SIZE = 128; +#define NEG_INF std::numeric_limits::lowest() + +template +inline float to_float(T val); +template <> +inline float to_float(float val) { + return val; +} +template <> +inline float to_float(mllm_fp16_t val) { + return MLLM_FP16_TO_FP32(val); +} + +// ======================= SIMD HELPERS ======================= +#ifdef __AVX2__ +inline float _mm256_hmax_ps(__m256 x) { + __m128 lo = _mm256_castps256_ps128(x); + __m128 hi = _mm256_extractf128_ps(x, 1); + __m128 max_val = _mm_max_ps(lo, hi); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 2, 2))); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 0, 1))); + return _mm_cvtss_f32(max_val); +} +inline float hsum_ps(__m256 v) { + __m128 vlow = _mm256_castps256_ps128(v); + __m128 vhigh = _mm256_extractf128_ps(v, 1); + vlow = _mm_add_ps(vlow, vhigh); + __m128 shuf = _mm_movehdup_ps(vlow); + __m128 sums = _mm_add_ps(vlow, shuf); + shuf = _mm_movehl_ps(shuf, sums); + sums = _mm_add_ss(sums, shuf); + return _mm_cvtss_f32(sums); +} +inline int32_t hsum_i32(__m256i v) { + __m128i vlo = _mm256_castsi256_si128(v); + __m128i vhi = _mm256_extracti128_si256(v, 1); + __m128i vsum = _mm_add_epi32(vlo, vhi); + vsum = _mm_add_epi32(vsum, _mm_shuffle_epi32(vsum, _MM_SHUFFLE(1, 0, 3, 2))); + vsum = _mm_add_epi32(vsum, _mm_shuffle_epi32(vsum, _MM_SHUFFLE(2, 3, 0, 1))); + return _mm_cvtsi128_si32(vsum); +} + +inline __m256 load_and_convert_to_fp32_vec(const float *ptr) { + return _mm256_loadu_ps(ptr); +} +#ifdef __F16C__ +inline __m256 load_and_convert_to_fp32_vec(const mllm_fp16_t *ptr) { + return _mm256_cvtph_ps(_mm_loadu_si128((const __m128i *)ptr)); +} +#endif +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) +inline float _vmaxvq_f32_hmax(float32x4_t x) { + return vmaxvq_f32(x); +} +inline void load_and_convert_to_fp32x4x2(const float *ptr, float32x4_t &out_lo, float32x4_t &out_hi) { + out_lo = vld1q_f32(ptr); + out_hi = vld1q_f32(ptr + 4); +} +#if defined(__ARM_FP16_FORMAT_IEEE) +inline void load_and_convert_to_fp32x4x2(const mllm_fp16_t *ptr, float32x4_t &out_lo, float32x4_t &out_hi) { + float16x8_t v_f16 = vld1q_f16(reinterpret_cast(ptr)); + out_lo = vcvt_f32_f16(vget_low_f16(v_f16)); + out_hi = vcvt_f32_f16(vget_high_f16(v_f16)); +} +#endif +#endif + +inline void aligned_alloc(void **ptr, size_t required_bytes, size_t align) { + if (align % sizeof(void *) != 0 || (align & (align - 1)) != 0) { + *ptr = nullptr; + return; + } + if (posix_memalign(ptr, align, required_bytes) != 0) { *ptr = nullptr; } +} +inline void aligned_free(void *ptr) { + free(ptr); +} + +inline void quantize_row_per_group_simd(const float *float_row, int8_t *int8_row, float *scales, int dim_size, float sm_scale, float *temp_buf) { + const int num_groups = dim_size / QK_K_BLOCK_SIZE; + + for (int g = 0; g < num_groups; ++g) { + const int group_start_idx = g * QK_K_BLOCK_SIZE; + const float *group_float_row = float_row + group_start_idx; + float *group_temp_buf = temp_buf; // reuse the same temp buffer + + // Apply softmax scale if needed (only for Q) + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) { + group_temp_buf[d] = group_float_row[d] * sm_scale; + } + + float max_abs_val = 0.0f; +#if defined(__AVX2__) + __m256 max_vec = _mm256_setzero_ps(); + const __m256 abs_mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7FFFFFFF)); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 8; d += 8) { + max_vec = _mm256_max_ps(max_vec, _mm256_and_ps(_mm256_loadu_ps(group_temp_buf + d), abs_mask)); + } + max_abs_val = _mm256_hmax_ps(max_vec); + for (; d < QK_K_BLOCK_SIZE; ++d) max_abs_val = std::max(max_abs_val, fabsf(group_temp_buf[d])); +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t max_vec = vdupq_n_f32(0.0f); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 4; d += 4) { + max_vec = vmaxq_f32(max_vec, vabsq_f32(vld1q_f32(group_temp_buf + d))); + } + max_abs_val = vmaxvq_f32(max_vec); + for (; d < QK_K_BLOCK_SIZE; ++d) max_abs_val = std::max(max_abs_val, fabsf(group_temp_buf[d])); +#else + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) max_abs_val = std::max(max_abs_val, fabsf(group_temp_buf[d])); +#endif + + const float scale = (max_abs_val > 1e-9f) ? max_abs_val / 127.0f : 0.0f; + scales[g] = scale; + const float inv_scale = (scale > 1e-9f) ? 1.0f / scale : 0.0f; + + int8_t *group_int8_row = int8_row + group_start_idx; + +#if defined(__AVX2__) + __m256 inv_scale_vec = _mm256_set1_ps(inv_scale); + for (int d = 0; d <= QK_K_BLOCK_SIZE - 8; d += 8) { + __m256i val_i32 = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_loadu_ps(group_temp_buf + d), inv_scale_vec)); + __m128i val_i16 = _mm_packs_epi32(_mm256_castsi256_si128(val_i32), _mm256_extracti128_si256(val_i32, 1)); + __m128i val_i8 = _mm_packs_epi16(val_i16, val_i16); + *(int64_t *)(group_int8_row + d) = _mm_cvtsi128_si64(val_i8); + } + for (; d < QK_K_BLOCK_SIZE; ++d) group_int8_row[d] = static_cast(roundf(group_temp_buf[d] * inv_scale)); +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t inv_scale_vec = vdupq_n_f32(inv_scale); + d = 0; + for (; d <= QK_K_BLOCK_SIZE - 16; d += 16) { + int32x4_t i32_0 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(group_temp_buf + d + 0), inv_scale_vec)); + int32x4_t i32_1 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(group_temp_buf + d + 4), inv_scale_vec)); + int32x4_t i32_2 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(group_temp_buf + d + 8), inv_scale_vec)); + int32x4_t i32_3 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(group_temp_buf + d + 12), inv_scale_vec)); + int16x8_t i16_0 = vcombine_s16(vqmovn_s32(i32_0), vqmovn_s32(i32_1)); + int16x8_t i16_1 = vcombine_s16(vqmovn_s32(i32_2), vqmovn_s32(i32_3)); + vst1q_s8(group_int8_row + d, vcombine_s8(vqmovn_s16(i16_0), vqmovn_s16(i16_1))); + } + for (; d < QK_K_BLOCK_SIZE; ++d) group_int8_row[d] = static_cast(roundf(group_temp_buf[d] * inv_scale)); +#else + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) group_int8_row[d] = static_cast(roundf(group_temp_buf[d] * inv_scale)); +#endif + } +} + +template +void compute_channel_means(const KVDtype *tensor, float *mean_tensor, int batch_size, int head_size, int seq_len, int dim_size) { +#pragma omp parallel for collapse(3) + for (int b = 0; b < batch_size; ++b) { + for (int h = 0; h < head_size; ++h) { + for (int d = 0; d < dim_size; d += 8) { // AVX2 processes 8 floats at a time +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FP16_FORMAT_IEEE) + float32x4_t sum_vec = vdupq_n_f32(0.0f); + for (int s = 0; s < seq_len; ++s) { + int idx = b * (seq_len * head_size * dim_size) + s * (head_size * dim_size) + h * (dim_size) + d; + float32x4_t val_vec; + if constexpr (std::is_same_v) { + val_vec = vcvt_f32_f16(vld1_f16(reinterpret_cast(tensor + idx))); + } else { + val_vec = vld1q_f32(tensor + idx); + } + sum_vec = vaddq_f32(sum_vec, val_vec); + } + float inv_seq_len = 1.0f / seq_len; + float32x4_t mean_vec = vmulq_f32(sum_vec, vdupq_n_f32(inv_seq_len)); + // Note: Original code used d+=4, but NEON loop processed only 4 floats. + // Assuming it should be d+=4 for the NEON part. Let's stick to the original logic. + vst1q_f32(mean_tensor + b * head_size * dim_size + h * dim_size + d, mean_vec); +#elif defined(__AVX2__) + // =========== AVX2 IMPLEMENTATION START =========== + if (d + 8 > dim_size) { // Handle remainder + for (int i = 0; i < (dim_size - d); ++i) { + double sum = 0.0; + for (int s = 0; s < seq_len; ++s) { + int idx = b * (seq_len * head_size * dim_size) + s * (head_size * dim_size) + h * (dim_size) + d + i; + sum += to_float(tensor[idx]); + } + mean_tensor[b * head_size * dim_size + h * dim_size + d + i] = static_cast(sum / seq_len); + } + continue; // Skip to next d in the outer loop + } + + __m256 sum_vec = _mm256_setzero_ps(); + for (int s = 0; s < seq_len; ++s) { + const KVDtype *current_row = tensor + b * (seq_len * head_size * dim_size) + s * (head_size * dim_size) + h * (dim_size) + d; + __m256 val_vec = load_and_convert_to_fp32_vec(current_row); + sum_vec = _mm256_add_ps(sum_vec, val_vec); + } + const float inv_seq_len = 1.0f / seq_len; + __m256 inv_len_vec = _mm256_set1_ps(inv_seq_len); + __m256 mean_vec = _mm256_mul_ps(sum_vec, inv_len_vec); + _mm256_storeu_ps(mean_tensor + b * head_size * dim_size + h * dim_size + d, mean_vec); + // =========== AVX2 IMPLEMENTATION END =========== +#else + // Fallback for non-AVX2/NEON + double sum[8] = {0.0}; + for (int s = 0; s < seq_len; ++s) { + for (int i = 0; i < 8; ++i) { + if (d + i < dim_size) { + int idx = b * (seq_len * head_size * dim_size) + s * (head_size * dim_size) + h * (dim_size) + d + i; + sum[i] += to_float(tensor[idx]); + } + } + } + for (int i = 0; i < 8; ++i) { + if (d + i < dim_size) { + mean_tensor[b * head_size * dim_size + h * dim_size + d + i] = static_cast(sum[i] / seq_len); + } + } +#endif + } + } + } +} + +template +void compute_mean_and_quantize_k( + const KVDtype *K, + float *mean_tensor, + int8_t *k_quant_global, + float *k_scale_global, + int batch_size, int kv_head_size, int seq_size_k, int dim_size, + int threads, + float *temp_k_sum, // [threads * dim_size] + float *temp_k_smoothed, // [threads * dim_size] + float *temp_k_head_buffer) { // [threads * seq_size_k * dim_size] + +#pragma omp parallel for num_threads(threads) collapse(2) + for (int b = 0; b < batch_size; ++b) { + for (int h = 0; h < kv_head_size; ++h) { + const int thread_id = omp_get_thread_num(); + float *thread_sum_buf = temp_k_sum + thread_id * dim_size; + float *thread_smoothed_buf = temp_k_smoothed + thread_id * dim_size; + float *thread_k_head_buf = temp_k_head_buffer + thread_id * seq_size_k * dim_size; + + float *target_mean = mean_tensor + b * kv_head_size * dim_size + h * dim_size; + const int num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + int8_t *target_k_quant = k_quant_global + (b * kv_head_size + h) * seq_size_k * dim_size; + float *target_k_scale = k_scale_global + (b * kv_head_size + h) * seq_size_k * num_k_blocks; + + const int k_stride = kv_head_size * dim_size; + + memset(thread_sum_buf, 0, dim_size * sizeof(float)); + + for (int s = 0; s < seq_size_k; ++s) { + const KVDtype *k_row_global = K + b * seq_size_k * k_stride + s * k_stride + h * dim_size; + float *k_row_buffered = thread_k_head_buf + s * dim_size; + +#if defined(__AVX2__) + int d = 0; + for (; d <= dim_size - 8; d += 8) { + const __m256 val_vec = load_and_convert_to_fp32_vec(k_row_global + d); + _mm256_storeu_ps(k_row_buffered + d, val_vec); + __m256 sum_vec = _mm256_loadu_ps(thread_sum_buf + d); + sum_vec = _mm256_add_ps(sum_vec, val_vec); + _mm256_storeu_ps(thread_sum_buf + d, sum_vec); + } + for (; d < dim_size; ++d) { + float val = to_float(k_row_global[d]); + k_row_buffered[d] = val; + thread_sum_buf[d] += val; + } +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + int d = 0; + for (; d <= dim_size - 8; d += 8) { + float32x4_t val_vec_lo, val_vec_hi; + load_and_convert_to_fp32x4x2(k_row_global + d, val_vec_lo, val_vec_hi); + + vst1q_f32(k_row_buffered + d, val_vec_lo); + vst1q_f32(k_row_buffered + d + 4, val_vec_hi); + + float32x4_t sum_vec_lo = vld1q_f32(thread_sum_buf + d); + float32x4_t sum_vec_hi = vld1q_f32(thread_sum_buf + d + 4); + + vst1q_f32(thread_sum_buf + d, vaddq_f32(sum_vec_lo, val_vec_lo)); + vst1q_f32(thread_sum_buf + d + 4, vaddq_f32(sum_vec_hi, val_vec_hi)); + } + for (; d < dim_size; ++d) { + float val = to_float(k_row_global[d]); + k_row_buffered[d] = val; + thread_sum_buf[d] += val; + } +#else + for (int d = 0; d < dim_size; ++d) { + float val = to_float(k_row_global[d]); + k_row_buffered[d] = val; + thread_sum_buf[d] += val; + } +#endif + } + + const float inv_seq_len = 1.0f / seq_size_k; +#if defined(__AVX2__) + const __m256 inv_len_vec = _mm256_set1_ps(inv_seq_len); + int d = 0; + for (; d <= dim_size - 8; d += 8) { + __m256 sum_vec = _mm256_loadu_ps(thread_sum_buf + d); + __m256 mean_vec = _mm256_mul_ps(sum_vec, inv_len_vec); + _mm256_storeu_ps(target_mean + d, mean_vec); + } + for (; d < dim_size; ++d) { + target_mean[d] = thread_sum_buf[d] * inv_seq_len; + } +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const float32x4_t inv_len_vec = vdupq_n_f32(inv_seq_len); + int d = 0; + for (; d <= dim_size - 4; d += 4) { + float32x4_t sum_vec = vld1q_f32(thread_sum_buf + d); + float32x4_t mean_vec = vmulq_f32(sum_vec, inv_len_vec); + vst1q_f32(target_mean + d, mean_vec); + } + for (; d < dim_size; ++d) { + target_mean[d] = thread_sum_buf[d] * inv_seq_len; + } +#else + for (int d = 0; d < dim_size; ++d) { + target_mean[d] = thread_sum_buf[d] * inv_seq_len; + } +#endif + + for (int s = 0; s < seq_size_k; ++s) { + const float *k_row_buffered = thread_k_head_buf + s * dim_size; + +#if defined(__AVX2__) + int d = 0; + for (; d <= dim_size - 8; d += 8) { + const __m256 k_vec = _mm256_loadu_ps(k_row_buffered + d); + const __m256 mean_vec = _mm256_loadu_ps(target_mean + d); + const __m256 smoothed_vec = _mm256_sub_ps(k_vec, mean_vec); + _mm256_storeu_ps(thread_smoothed_buf + d, smoothed_vec); + } + for (; d < dim_size; ++d) { + thread_smoothed_buf[d] = k_row_buffered[d] - target_mean[d]; + } +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + int d = 0; + for (; d <= dim_size - 4; d += 4) { + const float32x4_t k_vec = vld1q_f32(k_row_buffered + d); + const float32x4_t mean_vec = vld1q_f32(target_mean + d); + const float32x4_t smoothed_vec = vsubq_f32(k_vec, mean_vec); + vst1q_f32(thread_smoothed_buf + d, smoothed_vec); + } + for (; d < dim_size; ++d) { + thread_smoothed_buf[d] = k_row_buffered[d] - target_mean[d]; + } +#else + for (int d = 0; d < dim_size; ++d) { + thread_smoothed_buf[d] = k_row_buffered[d] - target_mean[d]; + } +#endif + quantize_row_per_group_simd(thread_smoothed_buf, + target_k_quant + s * dim_size, + target_k_scale + s * num_k_blocks, + dim_size, 1.0f, thread_sum_buf); + } + } + } +} + +class WorkspaceManager { +public: + WorkspaceManager() = default; + ~WorkspaceManager() { + for (auto &ptr : workspace_) { + if (ptr) aligned_free(ptr); + } + } + void **get_workspace(const std::vector &required_sizes) { + if (workspace_.empty()) { + workspace_.resize(required_sizes.size(), nullptr); + current_sizes_.resize(required_sizes.size(), 0); + } + for (size_t i = 0; i < required_sizes.size(); ++i) { + if (required_sizes[i] > current_sizes_[i]) { + if (workspace_[i]) aligned_free(workspace_[i]); + aligned_alloc(&workspace_[i], required_sizes[i], 64); + current_sizes_[i] = required_sizes[i]; + } + } + return workspace_.data(); + } + +private: + std::vector workspace_; + std::vector current_sizes_; +}; + +template +struct SAGE_CPU_IMPL { + using dtype_q_in_t = float; + using dtype_kv_in_t = KVDtype; + using dtype_out_t = float; + int32_t Br, Bc, Q_Head, KV_Head, threads; + float *acc_o_, *acc_s_, *logsum_, *scoremax_, *scoremax_prev_, *score_scale_, *score_sum_; + int8_t *q_quant_tile_, *k_quant_tile_; + float *q_scale_, *k_scale_, *k_smoothed_row_buf_, *q_scaled_row_buf_; + + void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_Head_; + KV_Head = KV_Head_; + threads = threads_; + } + void init_workspace(void **workspace) { + acc_o_ = static_cast(workspace[0]); + acc_s_ = static_cast(workspace[1]); + logsum_ = static_cast(workspace[2]); + scoremax_ = static_cast(workspace[3]); + scoremax_prev_ = static_cast(workspace[4]); + score_scale_ = static_cast(workspace[5]); + score_sum_ = static_cast(workspace[6]); + q_quant_tile_ = static_cast(workspace[7]); + k_quant_tile_ = static_cast(workspace[8]); + q_scale_ = static_cast(workspace[9]); + k_scale_ = static_cast(workspace[10]); + k_smoothed_row_buf_ = static_cast(workspace[11]); + q_scaled_row_buf_ = static_cast(workspace[12]); + } + + void sage_attn_prefill(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, const float *K_mean, const float *V_mean, int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, bool causal_mask) { + const int32_t Tr = (seq_size_q + Br - 1) / Br; + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + const int32_t num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_kv_head = h_idx / kv_group_size; + + float *p_acc_o = acc_o_ + thread_id * Br * dim_size; + float *p_acc_s = acc_s_ + thread_id * Br * Bc; + float *p_logsum = logsum_ + thread_id * Br; + float *p_scoremax = scoremax_ + thread_id * Br; + float *p_scoremax_prev = scoremax_prev_ + thread_id * Br; + float *p_score_scale = score_scale_ + thread_id * Br; + float *p_score_sum = score_sum_ + thread_id * Br; + int8_t *p_q_quant = q_quant_tile_ + thread_id * Br * dim_size; + const int8_t *p_k_quant_global = k_quant_tile_ + (b_idx * KV_Head + this_thread_kv_head) * seq_size_k * dim_size; + float *p_q_scale = q_scale_ + thread_id * Br * num_k_blocks; + const float *p_k_scale_global = k_scale_ + (b_idx * KV_Head + this_thread_kv_head) * seq_size_k * num_k_blocks; + float *p_q_scaled = q_scaled_row_buf_ + thread_id * dim_size; + + const float *p_V_mean = V_mean + b_idx * KV_Head * dim_size + this_thread_kv_head * dim_size; + const int k_stride = KV_Head * dim_size; + + for (int32_t t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { + int32_t Br_fixed = std::min(Br, seq_size_q - t_r_idx * Br); + init_temp(p_logsum, p_scoremax, p_acc_o, Br_fixed, dim_size); + + const dtype_q_in_t *tile_q_main = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + h_idx * dim_size; + for (int r = 0; r < Br_fixed; ++r) { + quantize_row_per_group_simd(tile_q_main + r * (head_size * dim_size), p_q_quant + r * dim_size, p_q_scale + r * num_k_blocks, dim_size, local_scale, p_q_scaled); + } + + for (int32_t t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + int32_t Bc_fixed = std::min(Bc, seq_size_k - t_c_idx * Bc); + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * k_stride + t_c_idx * Bc * k_stride + this_thread_kv_head * dim_size; + + quantize_and_mma0_sdot(Br_fixed, Bc_fixed, p_q_quant, p_k_quant_global + t_c_idx * Bc * dim_size, p_acc_s, p_q_scale, p_k_scale_global + t_c_idx * Bc * num_k_blocks, dim_size, t_r_idx * Br, t_c_idx * Bc, causal_mask); + softmax(Br_fixed, Bc_fixed, p_acc_s, p_scoremax, p_scoremax_prev, p_score_scale, p_score_sum, p_logsum); + rescale(Br_fixed, p_acc_o, p_score_scale, dim_size); + mma1(Br_fixed, Bc_fixed, p_acc_s, tile_v, p_V_mean, p_acc_o, KV_Head, dim_size); + } + + dtype_out_t *tile_o = O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + h_idx * dim_size; + scale_and_store(Br_fixed, p_acc_o, p_logsum, p_V_mean, tile_o, head_size, dim_size); + } + } + } + } + + void sage_attn_decode(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, const float *K_mean, const float *V_mean, int32_t batch_size, int32_t head_size, int32_t seq_size_k, int32_t dim_size, bool causal_mask) { + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + const int32_t num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t Br_fixed = 1; + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_kv_head = h_idx / kv_group_size; + + float *p_acc_o = acc_o_ + thread_id * Br_fixed * dim_size; + float *p_acc_s = acc_s_ + thread_id * Br_fixed * Bc; + float *p_logsum = logsum_ + thread_id * Br_fixed; + float *p_scoremax = scoremax_ + thread_id * Br_fixed; + float *p_scoremax_prev = scoremax_prev_ + thread_id * Br_fixed; + float *p_score_scale = score_scale_ + thread_id * Br_fixed; + float *p_score_sum = score_sum_ + thread_id * Br_fixed; + int8_t *p_q_quant = q_quant_tile_ + thread_id * Br_fixed * dim_size; + const int8_t *p_k_quant_global = k_quant_tile_ + (b_idx * KV_Head + this_thread_kv_head) * seq_size_k * dim_size; + float *p_q_scale = q_scale_ + thread_id * Br_fixed * num_k_blocks; + const float *p_k_scale_global = k_scale_ + (b_idx * KV_Head + this_thread_kv_head) * seq_size_k * num_k_blocks; + float *p_q_scaled = q_scaled_row_buf_ + thread_id * dim_size; + + const float *p_V_mean = V_mean + b_idx * KV_Head * dim_size + this_thread_kv_head * dim_size; + const int k_stride = KV_Head * dim_size; + + const dtype_q_in_t *tile_q_decode = Q + b_idx * head_size * dim_size + h_idx * dim_size; + quantize_row_per_group_simd(tile_q_decode, p_q_quant, p_q_scale, dim_size, local_scale, p_q_scaled); + + init_temp(p_logsum, p_scoremax, p_acc_o, Br_fixed, dim_size); + + for (int32_t t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + int32_t Bc_fixed = std::min(Bc, seq_size_k - t_c_idx * Bc); + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * k_stride + t_c_idx * Bc * k_stride + this_thread_kv_head * dim_size; + + quantize_and_mma0_sdot(Br_fixed, Bc_fixed, p_q_quant, p_k_quant_global + t_c_idx * Bc * dim_size, p_acc_s, p_q_scale, p_k_scale_global + t_c_idx * Bc * num_k_blocks, dim_size, seq_size_k - 1, t_c_idx * Bc, causal_mask); + softmax(Br_fixed, Bc_fixed, p_acc_s, p_scoremax, p_scoremax_prev, p_score_scale, p_score_sum, p_logsum); + rescale(Br_fixed, p_acc_o, p_score_scale, dim_size); + mma1(Br_fixed, Bc_fixed, p_acc_s, tile_v, p_V_mean, p_acc_o, KV_Head, dim_size); + } + dtype_out_t *tile_o = O + b_idx * head_size * dim_size + h_idx * dim_size; + scale_and_store(Br_fixed, p_acc_o, p_logsum, p_V_mean, tile_o, head_size, dim_size); + } + } + } + + void init_temp(float *logsum, float *scoremax, float *acc_o, int Br_fixed, int dim_size) { + for (int i = 0; i < Br_fixed; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF; + } + memset(acc_o, 0, Br_fixed * dim_size * sizeof(float)); + } + + void quantize_and_mma0_sdot(int Br_fixed, int Bc_fixed, const int8_t *q_quant_tile, const int8_t *k_quant_tile, float *acc_s, const float *q_scale, const float *k_scale, int dim_size, int global_r_start, int global_c_start, bool causal) { + const int num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + + for (int r = 0; r < Br_fixed; ++r) { + for (int c = 0; c < Bc_fixed; ++c) { + if (causal && (global_c_start + c) > (global_r_start + r)) { + acc_s[r * Bc + c] = NEG_INF; + continue; + } + + const int8_t *q_quant_line = q_quant_tile + r * dim_size; + const int8_t *k_quant_line = k_quant_tile + c * dim_size; + const float *q_scale_line = q_scale + r * num_k_blocks; + const float *k_scale_line = k_scale + c * num_k_blocks; + + float total_f32 = 0.0f; + + // Loop over groups/blocks + for (int g = 0; g < num_k_blocks; ++g) { + const int group_start_idx = g * QK_K_BLOCK_SIZE; + const int8_t *q_group_ptr = q_quant_line + group_start_idx; + const int8_t *k_group_ptr = k_quant_line + group_start_idx; + + int32_t group_dot_product_i32 = 0; +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FEATURE_DOTPROD) + int32x4_t acc_i32_vec = vdupq_n_s32(0); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 16; d += 16) { + acc_i32_vec = vdotq_s32(acc_i32_vec, vld1q_s8(q_group_ptr + d), vld1q_s8(k_group_ptr + d)); + } + group_dot_product_i32 = vaddvq_s32(acc_i32_vec); + for (; d < QK_K_BLOCK_SIZE; ++d) { + group_dot_product_i32 += q_group_ptr[d] * k_group_ptr[d]; + } +#elif defined(__AVX2__) + __m256i acc_i32_v = _mm256_setzero_si256(); + int d = 0; + // Process 16 bytes (16 pairs of signed int8) at a time + for (; d <= QK_K_BLOCK_SIZE - 16; d += 16) { + // Load 16 int8 values for q and k + __m128i q_i8_v = _mm_loadu_si128((const __m128i *)(q_group_ptr + d)); + __m128i k_i8_v = _mm_loadu_si128((const __m128i *)(k_group_ptr + d)); + __m256i q_i16_v = _mm256_cvtepi8_epi16(q_i8_v); + __m256i k_i16_v = _mm256_cvtepi8_epi16(k_i8_v); + __m256i prod_i32_v = _mm256_madd_epi16(q_i16_v, k_i16_v); + acc_i32_v = _mm256_add_epi32(acc_i32_v, prod_i32_v); + } + + group_dot_product_i32 = hsum_i32(acc_i32_v); + + // Process any remaining elements + for (; d < QK_K_BLOCK_SIZE; ++d) { + group_dot_product_i32 += q_group_ptr[d] * k_group_ptr[d]; + } +#else + // Fallback for other platforms + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) { + group_dot_product_i32 += q_group_ptr[d] * k_group_ptr[d]; + } +#endif + // Accumulate the scaled result of this group + total_f32 += (float)group_dot_product_i32 * q_scale_line[g] * k_scale_line[g]; + } + + acc_s[r * Bc + c] = total_f32; + } + } + } + + void softmax(int Br_fixed, int Bc_fixed, float *acc_s, float *scoremax, float *scoremax_prev, float *score_scale, float *score_sum, float *logsum) { + memcpy(scoremax_prev, scoremax, Br_fixed * sizeof(float)); + for (int r = 0; r < Br_fixed; ++r) { + float *row = acc_s + r * Bc; + float current_max = scoremax[r]; + for (int c = 0; c < Bc_fixed; ++c) current_max = std::max(current_max, row[c]); + scoremax[r] = current_max; + } + for (int r = 0; r < Br_fixed; ++r) score_scale[r] = expf(scoremax_prev[r] - scoremax[r]); + for (int r = 0; r < Br_fixed; ++r) { + float *row = acc_s + r * Bc; + float sm = scoremax[r]; + float sum = 0.f; + for (int c = 0; c < Bc_fixed; ++c) { + if (row[c] > NEG_INF / 2) { + float val = expf(row[c] - sm); + row[c] = val; + sum += val; + } else { + row[c] = 0.f; + } + } + score_sum[r] = sum; + } + for (int r = 0; r < Br_fixed; ++r) logsum[r] = logsum[r] * score_scale[r] + score_sum[r]; + } + void rescale(int Br_fixed, float *acc_o, const float *score_scale, int dim_size) { + for (int r = 0; r < Br_fixed; ++r) { + float scale_val = score_scale[r]; + float *row_ptr = acc_o + r * dim_size; +#if defined(__AVX2__) + __m256 scale_vec = _mm256_set1_ps(scale_val); + int d = 0; + for (; d <= dim_size - 8; d += 8) _mm256_storeu_ps(row_ptr + d, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + d), scale_vec)); + for (; d < dim_size; ++d) row_ptr[d] *= scale_val; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t scale_vec = vdupq_n_f32(scale_val); + int d = 0; + for (; d <= dim_size - 4; d += 4) vst1q_f32(row_ptr + d, vmulq_f32(vld1q_f32(row_ptr + d), scale_vec)); + for (; d < dim_size; ++d) row_ptr[d] *= scale_val; +#else + for (int d = 0; d < dim_size; ++d) row_ptr[d] *= scale_val; +#endif + } + } + + void mma1(int Br_fixed, int Bc_fixed, const float *p_block, const dtype_kv_in_t *v_block, const float *v_mean, float *acc_o, int kv_head_size, int dim_size) { + int v_stride = kv_head_size * dim_size; + +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FP16_FORMAT_IEEE) + for (int r = 0; r < Br_fixed; ++r) { + float *o_row = acc_o + r * dim_size; + const float *p_row = p_block + r * Bc; + + for (int d = 0; d < dim_size; d += 4) { + float32x4_t o_acc_vec = vld1q_f32(o_row + d); + const float32x4_t vm_vec = vld1q_f32(v_mean + d); + + int c = 0; + for (; c <= Bc_fixed - 4; c += 4) { + __builtin_prefetch(v_block + (c + 8) * v_stride + d, 0, 0); + + const float p0 = p_row[c + 0]; + const float p1 = p_row[c + 1]; + const float p2 = p_row[c + 2]; + const float p3 = p_row[c + 3]; + + const dtype_kv_in_t *v_row0 = v_block + (c + 0) * v_stride; + const dtype_kv_in_t *v_row1 = v_block + (c + 1) * v_stride; + const dtype_kv_in_t *v_row2 = v_block + (c + 2) * v_stride; + const dtype_kv_in_t *v_row3 = v_block + (c + 3) * v_stride; + + float32x4_t v_vec0, v_vec1, v_vec2, v_vec3; + if constexpr (std::is_same_v) { + v_vec0 = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row0 + d))); + v_vec1 = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row1 + d))); + v_vec2 = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row2 + d))); + v_vec3 = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row3 + d))); + } else { // float + v_vec0 = vld1q_f32(v_row0 + d); + v_vec1 = vld1q_f32(v_row1 + d); + v_vec2 = vld1q_f32(v_row2 + d); + v_vec3 = vld1q_f32(v_row3 + d); + } + o_acc_vec = vfmaq_n_f32(o_acc_vec, vsubq_f32(v_vec0, vm_vec), p0); + o_acc_vec = vfmaq_n_f32(o_acc_vec, vsubq_f32(v_vec1, vm_vec), p1); + o_acc_vec = vfmaq_n_f32(o_acc_vec, vsubq_f32(v_vec2, vm_vec), p2); + o_acc_vec = vfmaq_n_f32(o_acc_vec, vsubq_f32(v_vec3, vm_vec), p3); + } + + for (; c < Bc_fixed; ++c) { + const float p_scalar = p_row[c]; + const float32x4_t p_vec = vdupq_n_f32(p_scalar); + const dtype_kv_in_t *v_row = v_block + c * v_stride; + float32x4_t v_vec; + if constexpr (std::is_same_v) { + v_vec = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row + d))); + } else { + v_vec = vld1q_f32(v_row + d); + } + float32x4_t v_smoothed = vsubq_f32(v_vec, vm_vec); + o_acc_vec = vfmaq_f32(o_acc_vec, p_vec, v_smoothed); + } + + vst1q_f32(o_row + d, o_acc_vec); + } + } +#elif defined(__AVX2__) && defined(__FMA__) + for (int r = 0; r < Br_fixed; ++r) { + float *o_row = acc_o + r * dim_size; + for (int c = 0; c < Bc_fixed; ++c) { + const float p_scalar = p_block[r * Bc + c]; + if (fabsf(p_scalar) < 1e-9) continue; + + const __m256 p_vec = _mm256_set1_ps(p_scalar); + const dtype_kv_in_t *v_row = v_block + c * v_stride; + + int d = 0; + for (; d <= dim_size - 8; d += 8) { + const __m256 vm_vec = _mm256_loadu_ps(v_mean + d); + const __m256 v_vec = load_and_convert_to_fp32_vec(v_row + d); + + __m256 o_vec = _mm256_loadu_ps(o_row + d); + __m256 v_smoothed = _mm256_sub_ps(v_vec, vm_vec); + + // Fused Multiply-Add: o_vec = (p_vec * v_smoothed) + o_vec + o_vec = _mm256_fmadd_ps(p_vec, v_smoothed, o_vec); + + _mm256_storeu_ps(o_row + d, o_vec); + } + // Remainder loop + for (; d < dim_size; ++d) { + o_row[d] += p_scalar * (to_float(v_row[d]) - v_mean[d]); + } + } + } +#else + // Fallback for other platforms + for (int r = 0; r < Br_fixed; ++r) { + float *o_row = acc_o + r * dim_size; + for (int c = 0; c < Bc_fixed; ++c) { + const float p = p_block[r * Bc + c]; + if (fabsf(p) < 1e-9) continue; + const dtype_kv_in_t *v_row = v_block + c * v_stride; + for (int d = 0; d < dim_size; ++d) { o_row[d] += p * (to_float(v_row[d]) - v_mean[d]); } + } + } +#endif + } + + void scale_and_store(int Br_fixed, const float *acc_o, const float *logsum, const float *v_mean, float *O, int head_size, int dim_size) { + int o_stride = head_size * dim_size; + for (int r = 0; r < Br_fixed; ++r) { + float inv_logsum = (logsum[r] > 1e-9f) ? 1.f / logsum[r] : 0.f; + const float *o_row = acc_o + r * dim_size; + float *O_row = O + r * o_stride; +#if defined(__AVX2__) && defined(__FMA__) + const __m256 inv_logsum_vec = _mm256_set1_ps(inv_logsum); + int d = 0; + for (; d <= dim_size - 8; d += 8) { + const __m256 o_vec = _mm256_loadu_ps(o_row + d); + const __m256 vm_vec = _mm256_loadu_ps(v_mean + d); + _mm256_storeu_ps(O_row + d, _mm256_fmadd_ps(o_vec, inv_logsum_vec, vm_vec)); + } + for (; d < dim_size; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t inv_logsum_vec = vdupq_n_f32(inv_logsum); + int d = 0; + for (; d <= dim_size - 4; d += 4) { + float32x4_t o_vec = vld1q_f32(o_row + d); + float32x4_t vm_vec = vld1q_f32(v_mean + d); + vst1q_f32(O_row + d, vfmaq_f32(vm_vec, o_vec, inv_logsum_vec)); + } + for (; d < dim_size; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#else + for (int d = 0; d < dim_size; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#endif + } + } +}; + +template +void sage_attention_forward_cpu_dispatch(const float *Q, const KVDtype *K, const KVDtype *V, float *O, int32_t batch_size, int32_t q_head, int32_t kv_head, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, bool causal_mask, int32_t threads, int32_t br, int32_t bc) { + // 确保 dim_size 可以被块大小整除 + if (dim_size % QK_K_BLOCK_SIZE != 0) { + std::cerr << "Error: dim_size must be divisible by QK_K_BLOCK_SIZE (" << QK_K_BLOCK_SIZE << ")" << std::endl; + return; + } + const int32_t num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + + std::vector V_mean(batch_size * kv_head * dim_size); + compute_channel_means(V, V_mean.data(), batch_size, kv_head, seq_size_k, dim_size); + + thread_local WorkspaceManager manager; + + std::vector K_mean(batch_size * kv_head * dim_size); + + if (seq_size_q > 1) { // Prefill 阶段 + const std::vector required_sizes = { + (size_t)threads * br * dim_size * sizeof(float), // 0: acc_o_ + (size_t)threads * br * bc * sizeof(float), // 1: acc_s_ + (size_t)threads * br * sizeof(float), // 2: logsum_ + (size_t)threads * br * sizeof(float), // 3: scoremax_ + (size_t)threads * br * sizeof(float), // 4: scoremax_prev_ + (size_t)threads * br * sizeof(float), // 5: score_scale_ + (size_t)threads * br * sizeof(float), // 6: score_sum_ + (size_t)threads * br * dim_size * sizeof(int8_t), // 7: q_quant_tile_ + (size_t)batch_size * kv_head * seq_size_k * dim_size * sizeof(int8_t), // 8: k_quant_tile_ (global) + (size_t)threads * br * num_k_blocks * sizeof(float), // 9: q_scale_ + (size_t)batch_size * kv_head * seq_size_k * num_k_blocks * sizeof(float), // 10: k_scale_ (global) + (size_t)threads * dim_size * sizeof(float), // 11: k_smoothed_row_buf_ + (size_t)threads * dim_size * sizeof(float), // 12: q_scaled_row_buf_ + (size_t)threads * dim_size * sizeof(float), // 13: temp_k_sum + (size_t)threads * seq_size_k * dim_size * sizeof(float) // 14: temp_k_head_buffer + }; + void **workspace = manager.get_workspace(required_sizes); + + int8_t *k_quant_global_buffer = static_cast(workspace[8]); + float *k_scale_global_buffer = static_cast(workspace[10]); + + compute_mean_and_quantize_k(K, K_mean.data(), k_quant_global_buffer, k_scale_global_buffer, + batch_size, kv_head, seq_size_k, dim_size, threads, + static_cast(workspace[13]), + static_cast(workspace[11]), + static_cast(workspace[14])); + + SAGE_CPU_IMPL op; + op.configure(br, bc, q_head, kv_head, threads); + op.init_workspace(workspace); + op.sage_attn_prefill(Q, K, V, O, K_mean.data(), V_mean.data(), batch_size, q_head, seq_size_q, seq_size_k, dim_size, causal_mask); + + } else { + const int32_t decode_br = 1; + const std::vector required_sizes = { + (size_t)threads * decode_br * dim_size * sizeof(float), + (size_t)threads * decode_br * bc * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * dim_size * sizeof(int8_t), + (size_t)batch_size * kv_head * seq_size_k * dim_size * sizeof(int8_t), + (size_t)threads * decode_br * num_k_blocks * sizeof(float), + (size_t)batch_size * kv_head * seq_size_k * num_k_blocks * sizeof(float), + (size_t)threads * dim_size * sizeof(float), + (size_t)threads * dim_size * sizeof(float), + (size_t)threads * dim_size * sizeof(float), + (size_t)threads * seq_size_k * dim_size * sizeof(float)}; + void **workspace = manager.get_workspace(required_sizes); + + int8_t *k_quant_global_buffer = static_cast(workspace[8]); + float *k_scale_global_buffer = static_cast(workspace[10]); + + compute_mean_and_quantize_k(K, K_mean.data(), k_quant_global_buffer, k_scale_global_buffer, + batch_size, kv_head, seq_size_k, dim_size, threads, + static_cast(workspace[13]), + static_cast(workspace[11]), + static_cast(workspace[14])); + + SAGE_CPU_IMPL op; + op.configure(br, bc, q_head, kv_head, threads); + op.init_workspace(workspace); + op.sage_attn_decode(Q, K, V, O, K_mean.data(), V_mean.data(), batch_size, q_head, seq_size_k, dim_size, causal_mask); + } +} +} // namespace sage_attn_cpu +#endif // SAGE_ATTENTION_CPU_HPP \ No newline at end of file diff --git a/src/backends/cpu/compute/SageAttentionKVQ8.hpp b/src/backends/cpu/compute/SageAttentionKVQ8.hpp new file mode 100644 index 000000000..71abbcc47 --- /dev/null +++ b/src/backends/cpu/compute/SageAttentionKVQ8.hpp @@ -0,0 +1,700 @@ +#ifndef SAGE_ATTENTION_KVQ8_HPP +#define SAGE_ATTENTION_KVQ8_HPP + +#include "Types.hpp" +#include +#include +#include +#include +#include +#include + +#ifdef __AVX2__ +#include +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) +#include +#endif + +namespace seq_attn_kvq8 { + +const int QK_K_BLOCK_SIZE = QK8_0F; +#define NEG_INF std::numeric_limits::lowest() + +namespace { // 匿名空间,限制作用域 +#ifdef __AVX2__ +inline float _mm256_hmax_ps(__m256 x) { + __m128 lo = _mm256_castps256_ps128(x); + __m128 hi = _mm256_extractf128_ps(x, 1); + __m128 max_val = _mm_max_ps(lo, hi); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 2, 2))); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 0, 1))); + return _mm_cvtss_f32(max_val); +} + +inline int32_t hsum_i32(__m256i v) { + __m128i vlo = _mm256_castsi256_si128(v); + __m128i vhi = _mm256_extracti128_si256(v, 1); + __m128i vsum = _mm_add_epi32(vlo, vhi); + vsum = _mm_add_epi32(vsum, _mm_shuffle_epi32(vsum, _MM_SHUFFLE(1, 0, 3, 2))); + vsum = _mm_add_epi32(vsum, _mm_shuffle_epi32(vsum, _MM_SHUFFLE(2, 3, 0, 1))); + return _mm_cvtsi128_si32(vsum); +} +#endif // __AVX2__ +} // namespace + +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) +inline float32x4_t exp_ps_f32(float32x4_t x) { + float32x4_t a = vdupq_n_f32(12102203.0f); // (1 << 23) / ln(2) + float32x4_t b = vdupq_n_f32(1065353216.0f); // (1 << 23) * (0.5 - 0.04165) + (127 << 23) + int32x4_t m = vdupq_n_s32(0x7f); + float32x4_t y = vmlaq_f32(b, a, x); + int32x4_t r = vreinterpretq_s32_f32(y); + r = vandq_s32(r, vdupq_n_s32(0xffffff)); + r = vorrq_s32(r, vdupq_n_s32(0x3f800000)); + return vreinterpretq_f32_s32(r); +} +#endif + +class WorkspaceManager { +public: + WorkspaceManager() = default; + ~WorkspaceManager() { + for (auto &p : workspace_) + if (p) free(p); + } + void **get_workspace(const std::vector &s) { + if (workspace_.empty()) { + workspace_.resize(s.size(), nullptr); + current_sizes_.resize(s.size(), 0); + } + for (size_t i = 0; i < s.size(); ++i) { + if (s[i] > current_sizes_[i]) { + if (workspace_[i]) free(workspace_[i]); + posix_memalign(&workspace_[i], 64, s[i]); + current_sizes_[i] = s[i]; + } + } + return workspace_.data(); + } + +private: + std::vector workspace_; + std::vector current_sizes_; +}; + +struct SAGE_CPU_IMPL_KVQ8 { + using TQ = float; + using TO = float; + int32_t Br, Bc, Q_Head, KV_Head, threads; + float *acc_o, *acc_s, *logsum, *scoremax, *scoremax_prev, *score_scale, *score_sum; + int8_t *q_quant; + float *q_scale, *q_scaled_buf; + int8_t *p_quant; + float *p_scale; + + void configure(int32_t Br_, int32_t Bc_, int32_t Q_H, int32_t KV_H, int32_t T) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_H; + KV_Head = KV_H; + threads = T; + } + + void init_workspace(void **ws) { + acc_o = static_cast(ws[0]); + acc_s = static_cast(ws[1]); + logsum = static_cast(ws[2]); + scoremax = static_cast(ws[3]); + scoremax_prev = static_cast(ws[4]); + score_scale = static_cast(ws[5]); + score_sum = static_cast(ws[6]); + q_quant = static_cast(ws[7]); + q_scale = static_cast(ws[8]); + q_scaled_buf = static_cast(ws[9]); + p_quant = static_cast(ws[10]); + p_scale = static_cast(ws[11]); + } + + void init_temp(float *l, float *sm, float *o, int Br_f, int D) { + for (int i = 0; i < Br_f; ++i) { + l[i] = 0.0f; + sm[i] = -std::numeric_limits::infinity(); + } + if (o) memset(o, 0, Br_f * D * sizeof(float)); + } + + void quantize_q_row(const float *float_row, int8_t *int8_row, float *scales, int dim_size, float sm_scale, float *temp_buf) { + const int num_groups = dim_size / QK_K_BLOCK_SIZE; + for (int g = 0; g < num_groups; ++g) { + const int group_start_idx = g * QK_K_BLOCK_SIZE; + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) temp_buf[d] = float_row[group_start_idx + d] * sm_scale; + float max_abs_val = 0.0f; +#if defined(__AVX2__) + __m256 max_vec = _mm256_setzero_ps(); + const __m256 abs_mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7FFFFFFF)); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 8; d += 8) max_vec = _mm256_max_ps(max_vec, _mm256_and_ps(_mm256_loadu_ps(temp_buf + d), abs_mask)); + max_abs_val = _mm256_hmax_ps(max_vec); + for (; d < QK_K_BLOCK_SIZE; ++d) max_abs_val = std::max(max_abs_val, fabsf(temp_buf[d])); +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t max_vec = vdupq_n_f32(0.0f); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 4; d += 4) max_vec = vmaxq_f32(max_vec, vabsq_f32(vld1q_f32(temp_buf + d))); + max_abs_val = vmaxvq_f32(max_vec); + for (; d < QK_K_BLOCK_SIZE; ++d) max_abs_val = std::max(max_abs_val, fabsf(temp_buf[d])); +#else + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) max_abs_val = std::max(max_abs_val, fabsf(temp_buf[d])); +#endif + const float scale = (max_abs_val > 1e-9f) ? max_abs_val / 127.0f : 0.0f; + scales[g] = scale; + const float inv_scale = (scale > 1e-9f) ? 1.0f / scale : 0.0f; + int8_t *group_int8_row = int8_row + group_start_idx; +#if defined(__AVX2__) + __m256 inv_scale_vec = _mm256_set1_ps(inv_scale); + d = 0; + for (; d <= QK_K_BLOCK_SIZE - 8; d += 8) { + __m256i val_i32 = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_loadu_ps(temp_buf + d), inv_scale_vec)); + __m128i val_i16 = _mm_packs_epi32(_mm256_castsi256_si128(val_i32), _mm256_extracti128_si256(val_i32, 1)); + __m128i val_i8 = _mm_packs_epi16(val_i16, val_i16); + *(int64_t *)(group_int8_row + d) = _mm_cvtsi128_si64(val_i8); + } + for (; d < QK_K_BLOCK_SIZE; ++d) group_int8_row[d] = static_cast(roundf(temp_buf[d] * inv_scale)); +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t inv_scale_vec = vdupq_n_f32(inv_scale); + d = 0; + for (; d <= QK_K_BLOCK_SIZE - 16; d += 16) { + int32x4_t i32_0 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 0), inv_scale_vec)); + int32x4_t i32_1 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 4), inv_scale_vec)); + int32x4_t i32_2 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 8), inv_scale_vec)); + int32x4_t i32_3 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 12), inv_scale_vec)); + int16x8_t i16_0 = vcombine_s16(vqmovn_s32(i32_0), vqmovn_s32(i32_1)); + int16x8_t i16_1 = vcombine_s16(vqmovn_s32(i32_2), vqmovn_s32(i32_3)); + vst1q_s8(group_int8_row + d, vcombine_s8(vqmovn_s16(i16_0), vqmovn_s16(i16_1))); + } + for (; d < QK_K_BLOCK_SIZE; ++d) group_int8_row[d] = static_cast(roundf(temp_buf[d] * inv_scale)); +#else + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) group_int8_row[d] = static_cast(roundf(temp_buf[d] * inv_scale)); +#endif + } + } + + void mma0_sdot(int Br_f, int Bc_f, const int8_t *q_q_tile, const block_q8_0f *k_cache_tile, float *s, const float *q_s_tile, int D, int grs, int gcs, bool causal) { +#if defined(__AVX2__) + const int num_k_blocks = D / QK_K_BLOCK_SIZE; + for (int r = 0; r < Br_f; ++r) { + for (int c = 0; c < Bc_f; ++c) { + if (causal && (gcs + c) > (grs + r)) { + s[r * Bc + c] = NEG_INF; + continue; + } + const int8_t *q_quant_line = q_q_tile + r * D; + const block_q8_0f *k_block_line = k_cache_tile + c * KV_Head * num_k_blocks; + const float *q_scale_line = q_s_tile + r * num_k_blocks; + float total_f32 = 0.0f; + + for (int g = 0; g < num_k_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + const int8_t *q_group_ptr = q_quant_line + g_start; + const int8_t *k_group_ptr = k_block_line[g].qs; + const float k_group_scale = k_block_line[g].scale; + const float q_group_scale = q_scale_line[g]; + + int32_t g_dot = 0; + __m256i acc_i32_v = _mm256_setzero_si256(); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 16; d += 16) { + __m128i q_i8_v = _mm_loadu_si128((const __m128i *)(q_group_ptr + d)); + __m128i k_i8_v = _mm_loadu_si128((const __m128i *)(k_group_ptr + d)); + __m256i q_i16_v = _mm256_cvtepi8_epi16(q_i8_v); + __m256i k_i16_v = _mm256_cvtepi8_epi16(k_i8_v); + __m256i prod_i32_v = _mm256_madd_epi16(k_i16_v, q_i16_v); + acc_i32_v = _mm256_add_epi32(acc_i32_v, prod_i32_v); + } + g_dot = hsum_i32(acc_i32_v); + for (; d < QK_K_BLOCK_SIZE; ++d) g_dot += q_group_ptr[d] * k_group_ptr[d]; + + total_f32 += (float)g_dot * q_group_scale * k_group_scale; + } + s[r * Bc + c] = total_f32; + } + } + +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FEATURE_DOTPROD) + const int num_k_blocks = D / QK_K_BLOCK_SIZE; + + for (int br_base = 0; br_base < Br_f; br_base += 4) { + for (int bc_base = 0; bc_base < Bc_f; bc_base += 4) { + int br_limit = std::min(4, Br_f - br_base); + int bc_limit = std::min(4, Bc_f - bc_base); + float accumulators[16] = {0.0f}; + + for (int g = 0; g < num_k_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + const int8_t *q_rows[4]; + float q_scales[4]; + for (int i = 0; i < br_limit; ++i) { + q_rows[i] = q_q_tile + (br_base + i) * D + g_start; + q_scales[i] = q_s_tile[(br_base + i) * num_k_blocks + g]; + } + + const int8_t *k_rows[4]; + float k_scales[4]; + for (int i = 0; i < bc_limit; ++i) { + k_rows[i] = k_cache_tile[(bc_base + i) * KV_Head * num_k_blocks + g].qs; + k_scales[i] = k_cache_tile[(bc_base + i) * KV_Head * num_k_blocks + g].scale; + } + + for (int r_i = 0; r_i < br_limit; ++r_i) { + for (int c_i = 0; c_i < bc_limit; ++c_i) { + int32x4_t acc_s32 = vdupq_n_s32(0); + int d = 0; + for (; d <= QK_K_BLOCK_SIZE - 16; d += 16) { + int8x16_t q_s8 = vld1q_s8(q_rows[r_i] + d); + int8x16_t k_s8 = vld1q_s8(k_rows[c_i] + d); + acc_s32 = vdotq_s32(acc_s32, q_s8, k_s8); + } + int32_t dot_prod = vaddvq_s32(acc_s32); + for (; d < QK_K_BLOCK_SIZE; ++d) { dot_prod += q_rows[r_i][d] * k_rows[c_i][d]; } + + accumulators[r_i * 4 + c_i] += (float)dot_prod * q_scales[r_i] * k_scales[c_i]; + } + } + } + + for (int r_i = 0; r_i < br_limit; ++r_i) { + for (int c_i = 0; c_i < bc_limit; ++c_i) { + const int gr = grs + br_base + r_i; + const int gc = gcs + bc_base + c_i; + if (causal && gc > gr) { + s[(br_base + r_i) * Bc + (bc_base + c_i)] = NEG_INF; + } else { + s[(br_base + r_i) * Bc + (bc_base + c_i)] = accumulators[r_i * 4 + c_i]; + } + } + } + } + } + +#else + const int num_k_blocks = D / QK_K_BLOCK_SIZE; + for (int r = 0; r < Br_f; ++r) { + for (int c = 0; c < Bc_f; ++c) { + if (causal && (gcs + c) > (grs + r)) { + s[r * Bc + c] = NEG_INF; + continue; + } + const int8_t *q_quant_line = q_q_tile + r * D; + const block_q8_0f *k_block_line = k_cache_tile + c * KV_Head * num_k_blocks; + const float *q_scale_line = q_s_tile + r * num_k_blocks; + float total_f32 = 0.0f; + + for (int g = 0; g < num_k_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + const int8_t *q_group_ptr = q_quant_line + g_start; + const int8_t *k_group_ptr = k_block_line[g].qs; + const float k_group_scale = k_block_line[g].scale; + const float q_group_scale = q_scale_line[g]; + + int32_t g_dot = 0; + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) { + g_dot += q_group_ptr[d] * k_group_ptr[d]; + } + total_f32 += (float)g_dot * q_group_scale * k_group_scale; + } + s[r * Bc + c] = total_f32; + } + } +#endif + } + + void quantize_p_rows(int Br_f, int Bc_f, const float *p_float_block, int8_t *p_quant_block, float *p_scale_block) { + for (int r = 0; r < Br_f; ++r) { + const float *p_float_row = p_float_block + r * Bc; + int8_t *p_quant_row = p_quant_block + r * Bc; + + float max_abs_val = 0.0f; + for (int c = 0; c < Bc_f; ++c) { + max_abs_val = std::max(max_abs_val, fabsf(p_float_row[c])); + } + + const float scale = (max_abs_val > 1e-9f) ? max_abs_val / 127.0f : 0.0f; + p_scale_block[r] = scale; + const float inv_scale = (scale > 1e-9f) ? 1.0f / scale : 0.0f; + + for (int c = 0; c < Bc_f; ++c) { + p_quant_row[c] = static_cast(roundf(p_float_row[c] * inv_scale)); + } + } + } + + void mma1(int Br_f, int Bc_f, const int8_t *p_quant_block, const float *p_scale_block, const block_q8_0f *v_cache_tile, float *acc_o, int D) { +#if defined(__AVX2__) && defined(__FMA__) + const int num_v_blocks = D / QK_K_BLOCK_SIZE; + for (int r = 0; r < Br_f; ++r) { + const float p_row_scale = p_scale_block[r]; + if (fabsf(p_row_scale) < 1e-9) continue; + + float *o_row = acc_o + r * D; + const int8_t *p_quant_row = p_quant_block + r * Bc; + + for (int c = 0; c < Bc_f; ++c) { + const int8_t p_quant_scalar = p_quant_row[c]; + if (p_quant_scalar == 0) continue; + + const float p_dequant_val = (float)p_quant_scalar * p_row_scale; + const block_q8_0f *v_block_line = v_cache_tile + c * KV_Head * num_v_blocks; + + const __m256 p_vec = _mm256_set1_ps(p_dequant_val); + for (int g = 0; g < num_v_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + const float v_scale_scalar = v_block_line[g].scale; + const __m256 v_scale_vec = _mm256_set1_ps(v_scale_scalar); + for (int d_group = 0; d_group < QK_K_BLOCK_SIZE; d_group += 8) { + const int d = g_start + d_group; + __m128i v_i8_vec_part = _mm_loadl_epi64((const __m128i *)(v_block_line[g].qs + d_group)); + __m256i v_i32_vec = _mm256_cvtepi8_epi32(v_i8_vec_part); + __m256 v_f32_vec = _mm256_cvtepi32_ps(v_i32_vec); + __m256 dequant_v_vec = _mm256_mul_ps(v_f32_vec, v_scale_vec); + __m256 o_vec = _mm256_loadu_ps(o_row + d); + o_vec = _mm256_fmadd_ps(p_vec, dequant_v_vec, o_vec); + _mm256_storeu_ps(o_row + d, o_vec); + } + } + } + } + +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const int num_v_blocks = D / QK_K_BLOCK_SIZE; + + for (int r = 0; r < Br_f; ++r) { + float *o_row = acc_o + r * D; + const float p_row_scale = p_scale_block[r]; + if (fabsf(p_row_scale) < 1e-9) continue; + + for (int g = 0; g < num_v_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + + for (int d = 0; d < QK_K_BLOCK_SIZE; d += 8) { + float32x4_t acc0 = vld1q_f32(o_row + g_start + d); + float32x4_t acc1 = vld1q_f32(o_row + g_start + d + 4); + for (int c = 0; c < Bc_f; ++c) { + const int8_t p_quant_scalar = p_quant_block[r * Bc + c]; + if (p_quant_scalar == 0) continue; + + const float32x4_t p_vec = vdupq_n_f32((float)p_quant_scalar * p_row_scale); + + const block_q8_0f *v_block = v_cache_tile + c * KV_Head * num_v_blocks + g; + const float32x4_t v_scale_vec = vdupq_n_f32(v_block->scale); + const int8_t *v_qs = v_block->qs + d; + + int8x8_t v_s8 = vld1_s8(v_qs); + int16x8_t v_s16 = vmovl_s8(v_s8); + + float32x4_t v_f32_lo = vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_low_s16(v_s16))), v_scale_vec); + float32x4_t v_f32_hi = vmulq_f32(vcvtq_f32_s32(vmovl_s16(vget_high_s16(v_s16))), v_scale_vec); + + acc0 = vfmaq_f32(acc0, p_vec, v_f32_lo); + acc1 = vfmaq_f32(acc1, p_vec, v_f32_hi); + } + + vst1q_f32(o_row + g_start + d, acc0); + vst1q_f32(o_row + g_start + d + 4, acc1); + } + } + } + +#else + const int num_v_blocks = D / QK_K_BLOCK_SIZE; + for (int r = 0; r < Br_f; ++r) { + const float p_row_scale = p_scale_block[r]; + if (fabsf(p_row_scale) < 1e-9) continue; + + float *o_row = acc_o + r * D; + const int8_t *p_quant_row = p_quant_block + r * Bc; + + for (int c = 0; c < Bc_f; ++c) { + const int8_t p_quant_scalar = p_quant_row[c]; + if (p_quant_scalar == 0) continue; + + const float p_dequant_val = (float)p_quant_scalar * p_row_scale; + const block_q8_0f *v_block_line = v_cache_tile + c * KV_Head * num_v_blocks; + + for (int g = 0; g < num_v_blocks; ++g) { + const int g_start = g * QK_K_BLOCK_SIZE; + const float v_s = v_block_line[g].scale; + const int8_t *v_qs = v_block_line[g].qs; + for (int d = 0; d < QK_K_BLOCK_SIZE; ++d) { + o_row[g_start + d] += p_dequant_val * ((float)v_qs[d] * v_s); + } + } + } + } +#endif + } + + void softmax(int Br_f, int Bc_f, float *acc_s, float *sm, float *sm_p, float *ss, float *sum, float *l) { + memcpy(sm_p, sm, Br_f * sizeof(float)); + for (int r = 0; r < Br_f; ++r) { + float *row = acc_s + r * Bc, cmax = sm[r]; + for (int c = 0; c < Bc_f; ++c) cmax = std::max(cmax, row[c]); + sm[r] = cmax; + } + for (int r = 0; r < Br_f; ++r) ss[r] = expf(sm_p[r] - sm[r]); + for (int r = 0; r < Br_f; ++r) { + float *row = acc_s + r * Bc; + float smax = sm[r], s = 0.f; + for (int c = 0; c < Bc_f; ++c) row[c] = (row[c] > NEG_INF / 2) ? (s += row[c] = expf(row[c] - smax), row[c]) : 0.f; + sum[r] = s; + } + for (int r = 0; r < Br_f; ++r) l[r] = l[r] * ss[r] + sum[r]; + } + + /* + void softmax(int Br_f, int Bc_f, float *acc_s, float *sm, float *sm_p, float *ss, float *sum, float *l) { + memcpy(sm_p, sm, Br_f * sizeof(float)); + + for (int r = 0; r < Br_f; ++r) { + float *row = acc_s + r * Bc; + float cmax = sm[r]; +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t max_vec = vdupq_n_f32(cmax); + int c = 0; + for (; c <= Bc_f - 4; c += 4) { + max_vec = vmaxq_f32(max_vec, vld1q_f32(row + c)); + } + cmax = vmaxvq_f32(max_vec); + for (; c < Bc_f; ++c) cmax = std::max(cmax, row[c]); +#else + for (int c = 0; c < Bc_f; ++c) cmax = std::max(cmax, row[c]); +#endif + sm[r] = cmax; + } + + for (int r = 0; r < Br_f; ++r) ss[r] = expf(sm_p[r] - sm[r]); + + for (int r = 0; r < Br_f; ++r) { + float *row = acc_s + r * Bc; + float smax = sm[r]; + float current_sum = 0.f; +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t sum_vec = vdupq_n_f32(0.0f); + const float32x4_t smax_vec = vdupq_n_f32(smax); + int c = 0; + for (; c <= Bc_f - 4; c += 4) { + float32x4_t val_vec = vld1q_f32(row + c); + val_vec = vsubq_f32(val_vec, smax_vec); + val_vec = exp_ps_f32(val_vec); // 使用快速exp + vst1q_f32(row + c, val_vec); + sum_vec = vaddq_f32(sum_vec, val_vec); + } + current_sum = vaddvq_f32(sum_vec); + for (; c < Bc_f; ++c) + if (row[c] > NEG_INF / 2) + current_sum += row[c] = expf(row[c] - smax); + else + row[c] = 0.f; +#else + for (int c = 0; c < Bc_f; ++c) + if (row[c] > NEG_INF / 2) + current_sum += row[c] = expf(row[c] - smax); + else + row[c] = 0.f; +#endif + sum[r] = current_sum; + } + for (int r = 0; r < Br_f; ++r) l[r] = l[r] * ss[r] + sum[r]; + } + */ + + void rescale(int Br_f, float *acc_o, const float *ss, int D) { + for (int r = 0; r < Br_f; ++r) { + float s_val = ss[r], *r_ptr = acc_o + r * D; +#if defined(__AVX2__) + __m256 s_vec = _mm256_set1_ps(s_val); + int d = 0; + for (; d <= D - 8; d += 8) _mm256_storeu_ps(r_ptr + d, _mm256_mul_ps(_mm256_loadu_ps(r_ptr + d), s_vec)); + for (; d < D; ++d) r_ptr[d] *= s_val; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t s_vec = vdupq_n_f32(s_val); + int d = 0; + for (; d <= D - 4; d += 4) vst1q_f32(r_ptr + d, vmulq_f32(vld1q_f32(r_ptr + d), s_vec)); + for (; d < D; ++d) r_ptr[d] *= s_val; +#else + for (int d = 0; d < D; ++d) r_ptr[d] *= s_val; +#endif + } + } + + void scale_and_store(int Br_f, const float *acc_o, const float *logsum, const float *v_mean, TO *O, int H, int D) { + int o_stride = H * D; + for (int r = 0; r < Br_f; ++r) { + float inv_logsum = (logsum[r] > 1e-9f) ? 1.f / logsum[r] : 0.f; + const float *o_row = acc_o + r * D; + float *O_row = O + (size_t)r * o_stride; +#if defined(__AVX2__) && defined(__FMA__) + const __m256 inv_l_vec = _mm256_set1_ps(inv_logsum); + int d = 0; + for (; d <= D - 8; d += 8) { + const __m256 o_vec = _mm256_loadu_ps(o_row + d); + const __m256 vm_vec = _mm256_loadu_ps(v_mean + d); + _mm256_storeu_ps(O_row + d, _mm256_fmadd_ps(o_vec, inv_l_vec, vm_vec)); + } + for (; d < D; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + const float32x4_t inv_l_vec = vdupq_n_f32(inv_logsum); + int d = 0; + for (; d <= D - 4; d += 4) { + const float32x4_t o_vec = vld1q_f32(o_row + d); + const float32x4_t vm_vec = vld1q_f32(v_mean + d); + vst1q_f32(O_row + d, vfmaq_f32(vm_vec, o_vec, inv_l_vec)); + } + for (; d < D; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#else + for (int d = 0; d < D; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#endif + } + } + + void sage_attn_prefill(const TQ *Q, const block_q8_0f *K_cache, const block_q8_0f *V_cache, TO *O, const float *K_mean, const float *V_mean, int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, bool causal) { + const int32_t Tr = (seq_size_q + Br - 1) / Br, Tc = (seq_size_k + Bc - 1) / Bc; + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + const int32_t num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) + for (int32_t b_h = 0; b_h < batch_size * head_size; ++b_h) { + int b = b_h / head_size; + int h = b_h % head_size; + const int32_t tid = omp_get_thread_num(); + const int32_t kvh = h / kv_group; + float *po = acc_o + tid * Br * dim_size, *ps = acc_s + tid * Br * Bc; + float *plog = logsum + tid * Br, *pmax = scoremax + tid * Br, *pmax_p = scoremax_prev + tid * Br; + float *pscale = score_scale + tid * Br, *psum = score_sum + tid * Br; + int8_t *p_q_q = q_quant + tid * Br * dim_size; + float *p_q_s = q_scale + tid * Br * num_k_blocks; + float *p_q_scaled = q_scaled_buf + tid * dim_size; + + int8_t *p_p_q = p_quant + tid * Br * Bc; + float *p_p_s = p_scale + tid * Br; + + const float *p_V_m = V_mean + (b * KV_Head + kvh) * dim_size; + + for (int32_t tr = 0; tr < Tr; ++tr) { + int32_t Br_f = std::min(Br, seq_size_q - tr * Br); + init_temp(plog, pmax, po, Br_f, dim_size); + const TQ *tile_q_bshd = Q + (size_t)b * seq_size_q * head_size * dim_size + (size_t)tr * Br * head_size * dim_size + (size_t)h * dim_size; + + for (int r = 0; r < Br_f; ++r) { + quantize_q_row(tile_q_bshd + r * head_size * dim_size, p_q_q + r * dim_size, p_q_s + r * num_k_blocks, dim_size, local_scale, p_q_scaled); + } + + for (int32_t tc = 0; tc < Tc; ++tc) { + int32_t Bc_f = std::min(Bc, seq_size_k - tc * Bc); + const int kv_offset = seq_size_k - seq_size_q; + + const block_q8_0f *k_cache_tile = K_cache + ((size_t)b * seq_size_k * KV_Head + (tc * Bc) * KV_Head + kvh) * num_k_blocks; + const block_q8_0f *v_cache_tile = V_cache + ((size_t)b * seq_size_k * KV_Head + (tc * Bc) * KV_Head + kvh) * num_k_blocks; + + mma0_sdot(Br_f, Bc_f, p_q_q, k_cache_tile, ps, p_q_s, dim_size, tr * Br + kv_offset, tc * Bc, causal); + softmax(Br_f, Bc_f, ps, pmax, pmax_p, pscale, psum, plog); + rescale(Br_f, po, pscale, dim_size); + + quantize_p_rows(Br_f, Bc_f, ps, p_p_q, p_p_s); + + mma1(Br_f, Bc_f, p_p_q, p_p_s, v_cache_tile, po, dim_size); + } + TO *tile_o_bshd = O + (size_t)b * seq_size_q * head_size * dim_size + (size_t)tr * Br * head_size * dim_size + (size_t)h * dim_size; + scale_and_store(Br_f, po, plog, p_V_m, tile_o_bshd, head_size, dim_size); + } + } + } + void sage_attn_decode(const TQ *Q, const block_q8_0f *K_cache, const block_q8_0f *V_cache, TO *O, const float *K_mean, const float *V_mean, int32_t batch_size, int32_t head_size, int32_t seq_size_k, int32_t dim_size, bool causal) { + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + const int32_t num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) + for (int32_t b_h = 0; b_h < batch_size * head_size; ++b_h) { + int b = b_h / head_size; + int h = b_h % head_size; + const int32_t Br_f = 1; + const int32_t tid = omp_get_thread_num(); + const int32_t kvh = h / kv_group; + float *po = acc_o + tid * Br_f * dim_size, *ps = acc_s + tid * Br_f * Bc; + float *plog = logsum + tid * Br_f, *pmax = scoremax + tid * Br_f, *pmax_p = scoremax_prev + tid * Br_f; + float *pscale = score_scale + tid * Br_f, *psum = score_sum + tid * Br_f; + int8_t *p_q_q = q_quant + tid * Br_f * dim_size; + float *p_q_s = q_scale + tid * Br_f * num_k_blocks; + float *p_q_scaled = q_scaled_buf + tid * dim_size; + const float *p_V_m = V_mean + (b * KV_Head + kvh) * dim_size; + + int8_t *p_p_q = p_quant + tid * Br_f * Bc; + float *p_p_s = p_scale + tid * Br_f; + + const TQ *tile_q_decode = Q + (size_t)b * head_size * dim_size + (size_t)h * dim_size; + quantize_q_row(tile_q_decode, p_q_q, p_q_s, dim_size, local_scale, p_q_scaled); + init_temp(plog, pmax, po, Br_f, dim_size); + + for (int32_t tc = 0; tc < Tc; ++tc) { + int32_t Bc_f = std::min(Bc, seq_size_k - tc * Bc); + const block_q8_0f *k_cache_tile = K_cache + ((size_t)b * seq_size_k * KV_Head + (tc * Bc) * KV_Head + kvh) * num_k_blocks; + const block_q8_0f *v_cache_tile = V_cache + ((size_t)b * seq_size_k * KV_Head + (tc * Bc) * KV_Head + kvh) * num_k_blocks; + mma0_sdot(Br_f, Bc_f, p_q_q, k_cache_tile, ps, p_q_s, dim_size, seq_size_k - 1, tc * Bc, causal); + softmax(Br_f, Bc_f, ps, pmax, pmax_p, pscale, psum, plog); + rescale(Br_f, po, pscale, dim_size); + + quantize_p_rows(Br_f, Bc_f, ps, p_p_q, p_p_s); + + mma1(Br_f, Bc_f, p_p_q, p_p_s, v_cache_tile, po, dim_size); + } + TO *tile_o_bshd = O + (size_t)b * head_size * dim_size + (size_t)h * dim_size; + scale_and_store(Br_f, po, plog, p_V_m, tile_o_bshd, head_size, dim_size); + } + } +}; + +inline void sage_attention_forward_cpu_dispatch( + const float *Q, const void *K_in, const void *V_in, const float *K_mean_ext, + const float *V_mean_ext, float *O, int32_t batch_size, int32_t q_head, + int32_t kv_head, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, + bool causal_mask, int32_t threads, int32_t br, int32_t bc) { + if (dim_size % QK_K_BLOCK_SIZE != 0) { + std::cerr << "Error: dim_size must be divisible by QK_K_BLOCK_SIZE" << std::endl; + return; + } + const int32_t num_k_blocks = dim_size / QK_K_BLOCK_SIZE; + + thread_local WorkspaceManager manager; + SAGE_CPU_IMPL_KVQ8 op; + op.configure(br, bc, q_head, kv_head, threads); + + const int32_t current_br = (seq_size_q > 1) ? br : 1; + const std::vector ws_sizes = { + (size_t)threads * current_br * dim_size * sizeof(float), // 0: acc_o + (size_t)threads * current_br * bc * sizeof(float), // 1: acc_s + (size_t)threads * current_br * sizeof(float), // 2: logsum + (size_t)threads * current_br * sizeof(float), // 3: scoremax + (size_t)threads * current_br * sizeof(float), // 4: scoremax_prev + (size_t)threads * current_br * sizeof(float), // 5: score_scale + (size_t)threads * current_br * sizeof(float), // 6: score_sum + (size_t)threads * current_br * dim_size * sizeof(int8_t), // 7: q_quant + (size_t)threads * current_br * num_k_blocks * sizeof(float), // 8: q_scale + (size_t)threads * dim_size * sizeof(float), // 9: q_scaled_buf (for quantize_q_row) + (size_t)threads * current_br * bc * sizeof(int8_t), // 10: p_quant [NEW] + (size_t)threads * current_br * sizeof(float), // 11: p_scale [NEW] + }; + void **workspace = manager.get_workspace(ws_sizes); + op.init_workspace(workspace); + + if (seq_size_q > 1) { + op.sage_attn_prefill(Q, (const block_q8_0f *)K_in, (const block_q8_0f *)V_in, O, K_mean_ext, V_mean_ext, batch_size, q_head, + seq_size_q, seq_size_k, dim_size, causal_mask); + } else { + op.sage_attn_decode(Q, (const block_q8_0f *)K_in, (const block_q8_0f *)V_in, O, K_mean_ext, V_mean_ext, batch_size, q_head, + seq_size_k, dim_size, causal_mask); + } +} + +} // namespace seq_attn_kvq8 +#endif // SAGE_ATTENTION_KVQ8_HPP \ No newline at end of file diff --git a/src/backends/cpu/compute/SageAttentionPT.hpp b/src/backends/cpu/compute/SageAttentionPT.hpp new file mode 100644 index 000000000..a89230664 --- /dev/null +++ b/src/backends/cpu/compute/SageAttentionPT.hpp @@ -0,0 +1,834 @@ +// 文件名: sage_attention_unified_final_with_simd.cpp +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#include +// #include +#include +#include + +// --- SIMD Intrinsics --- +#ifdef __AVX2__ +#include +#include +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) +#include +#if defined(__ARM_FP16_FORMAT_IEEE) && !defined(_MSC_VER) +#include +#endif +#endif + +#include "Types.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" + +namespace sage_attn_pt_cpu { + +#define NEG_INF std::numeric_limits::lowest() + +template +inline float to_float(T val); +template <> +inline float to_float(float val) { + return val; +} +template <> +inline float to_float(mllm_fp16_t val) { + return MLLM_FP16_TO_FP32(val); +} + +#ifdef __AVX2__ +inline float _mm256_hmax_ps(__m256 x) { + __m128 lo = _mm256_castps256_ps128(x); + __m128 hi = _mm256_extractf128_ps(x, 1); + __m128 max_val = _mm_max_ps(lo, hi); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 2, 2))); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 0, 1))); + return _mm_cvtss_f32(max_val); +} +inline float hsum_ps(__m256 v) { + __m128 vlow = _mm256_castps256_ps128(v); + __m128 vhigh = _mm256_extractf128_ps(v, 1); + vlow = _mm_add_ps(vlow, vhigh); + __m128 shuf = _mm_movehdup_ps(vlow); + __m128 sums = _mm_add_ps(vlow, shuf); + shuf = _mm_movehl_ps(shuf, sums); + sums = _mm_add_ss(sums, shuf); + return _mm_cvtss_f32(sums); +} +inline int32_t hsum_i32(__m256i v) { + __m128i vlo = _mm256_castsi256_si128(v); + __m128i vhi = _mm256_extracti128_si256(v, 1); + __m128i vsum = _mm_add_epi32(vlo, vhi); + vsum = _mm_add_epi32(vsum, _mm_shuffle_epi32(vsum, _MM_SHUFFLE(1, 0, 3, 2))); + vsum = _mm_add_epi32(vsum, _mm_shuffle_epi32(vsum, _MM_SHUFFLE(2, 3, 0, 1))); + return _mm_cvtsi128_si32(vsum); +} + +inline __m256 load_and_convert_to_fp32_vec(const float *ptr) { + return _mm256_loadu_ps(ptr); +} +#ifdef __F16C__ +inline __m256 load_and_convert_to_fp32_vec(const mllm_fp16_t *ptr) { + return _mm256_cvtph_ps(_mm_loadu_si128((const __m128i *)ptr)); +} +#endif +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) +inline float _vmaxvq_f32_hmax(float32x4_t x) { + return vmaxvq_f32(x); +} +inline void load_and_convert_to_fp32x4x2(const float *ptr, float32x4_t &out_lo, float32x4_t &out_hi) { + out_lo = vld1q_f32(ptr); + out_hi = vld1q_f32(ptr + 4); +} +#if defined(__ARM_FP16_FORMAT_IEEE) +inline void load_and_convert_to_fp32x4x2(const mllm_fp16_t *ptr, float32x4_t &out_lo, float32x4_t &out_hi) { + float16x8_t v_f16 = vld1q_f16(reinterpret_cast(ptr)); + out_lo = vcvt_f32_f16(vget_low_f16(v_f16)); + out_hi = vcvt_f32_f16(vget_high_f16(v_f16)); +} +#endif +#endif + +inline void aligned_alloc(void **ptr, size_t required_bytes, size_t align) { + if (align % sizeof(void *) != 0 || (align & (align - 1)) != 0) { + *ptr = nullptr; + return; + } + if (posix_memalign(ptr, align, required_bytes) != 0) { *ptr = nullptr; } +} +inline void aligned_free(void *ptr) { + free(ptr); +} + +inline void quantize_row_simd(const float *float_row, int8_t *int8_row, float *scale, int dim_size, float sm_scale, float *temp_buf) { + for (int d = 0; d < dim_size; ++d) { temp_buf[d] = float_row[d] * sm_scale; } + float max_abs_val = 0.0f; +#if defined(__AVX2__) + __m256 max_vec = _mm256_setzero_ps(); + const __m256 abs_mask = _mm256_castsi256_ps(_mm256_set1_epi32(0x7FFFFFFF)); + int d = 0; + for (; d <= dim_size - 8; d += 8) max_vec = _mm256_max_ps(max_vec, _mm256_and_ps(_mm256_loadu_ps(temp_buf + d), abs_mask)); + max_abs_val = _mm256_hmax_ps(max_vec); + for (; d < dim_size; ++d) max_abs_val = std::max(max_abs_val, fabsf(temp_buf[d])); +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t max_vec = vdupq_n_f32(0.0f); + int d = 0; + for (; d <= dim_size - 4; d += 4) max_vec = vmaxq_f32(max_vec, vabsq_f32(vld1q_f32(temp_buf + d))); + max_abs_val = vmaxvq_f32(max_vec); + for (; d < dim_size; ++d) max_abs_val = std::max(max_abs_val, fabsf(temp_buf[d])); +#else + for (int d = 0; d < dim_size; ++d) max_abs_val = std::max(max_abs_val, fabsf(temp_buf[d])); +#endif + *scale = (max_abs_val > 1e-9f) ? max_abs_val / 127.0f : 0.0f; + const float inv_scale = (*scale > 1e-9f) ? 1.0f / *scale : 0.0f; +#if defined(__AVX2__) + __m256 inv_scale_vec = _mm256_set1_ps(inv_scale); + d = 0; + for (; d <= dim_size - 8; d += 8) { + __m256i val_i32 = _mm256_cvtps_epi32(_mm256_mul_ps(_mm256_loadu_ps(temp_buf + d), inv_scale_vec)); + __m128i val_i16 = _mm_packs_epi32(_mm256_castsi256_si128(val_i32), _mm256_extracti128_si256(val_i32, 1)); + __m128i val_i8 = _mm_packs_epi16(val_i16, val_i16); + *(int64_t *)(int8_row + d) = _mm_cvtsi128_si64(val_i8); + } + for (; d < dim_size; ++d) int8_row[d] = static_cast(roundf(temp_buf[d] * inv_scale)); +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t inv_scale_vec = vdupq_n_f32(inv_scale); + d = 0; + for (; d <= dim_size - 16; d += 16) { + int32x4_t i32_0 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 0), inv_scale_vec)); + int32x4_t i32_1 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 4), inv_scale_vec)); + int32x4_t i32_2 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 8), inv_scale_vec)); + int32x4_t i32_3 = vcvtaq_s32_f32(vmulq_f32(vld1q_f32(temp_buf + d + 12), inv_scale_vec)); + int16x8_t i16_0 = vcombine_s16(vqmovn_s32(i32_0), vqmovn_s32(i32_1)); + int16x8_t i16_1 = vcombine_s16(vqmovn_s32(i32_2), vqmovn_s32(i32_3)); + vst1q_s8(int8_row + d, vcombine_s8(vqmovn_s16(i16_0), vqmovn_s16(i16_1))); + } + for (; d < dim_size; ++d) int8_row[d] = static_cast(roundf(temp_buf[d] * inv_scale)); +#else + for (int d = 0; d < dim_size; ++d) int8_row[d] = static_cast(roundf(temp_buf[d] * inv_scale)); +#endif +} + +template +void compute_channel_means(const KVDtype *tensor, float *mean_tensor, int batch_size, int head_size, int seq_len, int dim_size) { +#pragma omp parallel for collapse(3) + for (int b = 0; b < batch_size; ++b) { + for (int h = 0; h < head_size; ++h) { + for (int d = 0; d < dim_size; d += 8) { // AVX2 processes 8 floats at a time +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FP16_FORMAT_IEEE) + float32x4_t sum_vec = vdupq_n_f32(0.0f); + for (int s = 0; s < seq_len; ++s) { + int idx = b * (seq_len * head_size * dim_size) + s * (head_size * dim_size) + h * (dim_size) + d; + float32x4_t val_vec; + if constexpr (std::is_same_v) { + val_vec = vcvt_f32_f16(vld1_f16(reinterpret_cast(tensor + idx))); + } else { + val_vec = vld1q_f32(tensor + idx); + } + sum_vec = vaddq_f32(sum_vec, val_vec); + } + float inv_seq_len = 1.0f / seq_len; + float32x4_t mean_vec = vmulq_f32(sum_vec, vdupq_n_f32(inv_seq_len)); + // Note: Original code used d+=4, but NEON loop processed only 4 floats. + // Assuming it should be d+=4 for the NEON part. Let's stick to the original logic. + vst1q_f32(mean_tensor + b * head_size * dim_size + h * dim_size + d, mean_vec); +#elif defined(__AVX2__) + // =========== AVX2 IMPLEMENTATION START =========== + if (d + 8 > dim_size) { // Handle remainder + for (int i = 0; i < (dim_size - d); ++i) { + double sum = 0.0; + for (int s = 0; s < seq_len; ++s) { + int idx = b * (seq_len * head_size * dim_size) + s * (head_size * dim_size) + h * (dim_size) + d + i; + sum += to_float(tensor[idx]); + } + mean_tensor[b * head_size * dim_size + h * dim_size + d + i] = static_cast(sum / seq_len); + } + continue; // Skip to next d in the outer loop + } + + __m256 sum_vec = _mm256_setzero_ps(); + for (int s = 0; s < seq_len; ++s) { + const KVDtype *current_row = tensor + b * (seq_len * head_size * dim_size) + s * (head_size * dim_size) + h * (dim_size) + d; + __m256 val_vec = load_and_convert_to_fp32_vec(current_row); + sum_vec = _mm256_add_ps(sum_vec, val_vec); + } + const float inv_seq_len = 1.0f / seq_len; + __m256 inv_len_vec = _mm256_set1_ps(inv_seq_len); + __m256 mean_vec = _mm256_mul_ps(sum_vec, inv_len_vec); + _mm256_storeu_ps(mean_tensor + b * head_size * dim_size + h * dim_size + d, mean_vec); + // =========== AVX2 IMPLEMENTATION END =========== +#else + // Fallback for non-AVX2/NEON + double sum[8] = {0.0}; + for (int s = 0; s < seq_len; ++s) { + for (int i = 0; i < 8; ++i) { + if (d + i < dim_size) { + int idx = b * (seq_len * head_size * dim_size) + s * (head_size * dim_size) + h * (dim_size) + d + i; + sum[i] += to_float(tensor[idx]); + } + } + } + for (int i = 0; i < 8; ++i) { + if (d + i < dim_size) { + mean_tensor[b * head_size * dim_size + h * dim_size + d + i] = static_cast(sum[i] / seq_len); + } + } +#endif + } + } + } +} + +template +void compute_mean_and_quantize_k( + const KVDtype *K, + float *mean_tensor, + int8_t *k_quant_global, + float *k_scale_global, + int batch_size, int kv_head_size, int seq_size_k, int dim_size, + int threads, + float *temp_k_sum, + float *temp_k_smoothed) { +#pragma omp parallel for num_threads(threads) collapse(2) + for (int b = 0; b < batch_size; ++b) { + for (int h = 0; h < kv_head_size; ++h) { + const int thread_id = omp_get_thread_num(); + float *thread_sum_buf = temp_k_sum + thread_id * dim_size; + float *thread_smoothed_buf = temp_k_smoothed + thread_id * dim_size; + + float *target_mean = mean_tensor + b * kv_head_size * dim_size + h * dim_size; + int8_t *target_k_quant = k_quant_global + (b * kv_head_size + h) * seq_size_k * dim_size; + float *target_k_scale = k_scale_global + (b * kv_head_size + h) * seq_size_k; + + const int k_stride = kv_head_size * dim_size; + + memset(thread_sum_buf, 0, dim_size * sizeof(float)); + + for (int s = 0; s < seq_size_k; ++s) { + const KVDtype *k_row = K + b * seq_size_k * k_stride + s * k_stride + h * dim_size; + for (int d = 0; d < dim_size; ++d) { + thread_sum_buf[d] += to_float(k_row[d]); + } + } + + float inv_seq_len = 1.0f / seq_size_k; + for (int d = 0; d < dim_size; ++d) { + target_mean[d] = thread_sum_buf[d] * inv_seq_len; + } + + for (int s = 0; s < seq_size_k; ++s) { + const KVDtype *k_row = K + b * seq_size_k * k_stride + s * k_stride + h * dim_size; + for (int d = 0; d < dim_size; ++d) { + thread_smoothed_buf[d] = to_float(k_row[d]) - target_mean[d]; + } + quantize_row_simd(thread_smoothed_buf, target_k_quant + s * dim_size, &target_k_scale[s], dim_size, 1.0f, thread_sum_buf); + } + } + } +} + +class WorkspaceManager { +public: + WorkspaceManager() = default; + ~WorkspaceManager() { + for (auto &ptr : workspace_) { + if (ptr) aligned_free(ptr); + } + } + void **get_workspace(const std::vector &required_sizes) { + if (workspace_.empty()) { + workspace_.resize(required_sizes.size(), nullptr); + current_sizes_.resize(required_sizes.size(), 0); + } + for (size_t i = 0; i < required_sizes.size(); ++i) { + if (required_sizes[i] > current_sizes_[i]) { + if (workspace_[i]) aligned_free(workspace_[i]); + aligned_alloc(&workspace_[i], required_sizes[i], 64); + current_sizes_[i] = required_sizes[i]; + } + } + return workspace_.data(); + } + +private: + std::vector workspace_; + std::vector current_sizes_; +}; + +template +struct SAGE_CPU_IMPL { + using dtype_q_in_t = float; + using dtype_kv_in_t = KVDtype; + using dtype_out_t = float; + int32_t Br, Bc, Q_Head, KV_Head, threads; + float *acc_o_, *acc_s_, *logsum_, *scoremax_, *scoremax_prev_, *score_scale_, *score_sum_; + int8_t *q_quant_tile_, *k_quant_tile_; + float *q_scale_, *k_scale_, *k_smoothed_row_buf_, *q_scaled_row_buf_; + + void configure(int32_t Br_, int32_t Bc_, int32_t Q_Head_, int32_t KV_Head_, int32_t threads_) { + Br = Br_; + Bc = Bc_; + Q_Head = Q_Head_; + KV_Head = KV_Head_; + threads = threads_; + } + void init_workspace(void **workspace) { + acc_o_ = static_cast(workspace[0]); + acc_s_ = static_cast(workspace[1]); + logsum_ = static_cast(workspace[2]); + scoremax_ = static_cast(workspace[3]); + scoremax_prev_ = static_cast(workspace[4]); + score_scale_ = static_cast(workspace[5]); + score_sum_ = static_cast(workspace[6]); + q_quant_tile_ = static_cast(workspace[7]); + k_quant_tile_ = static_cast(workspace[8]); + q_scale_ = static_cast(workspace[9]); + k_scale_ = static_cast(workspace[10]); + k_smoothed_row_buf_ = static_cast(workspace[11]); + q_scaled_row_buf_ = static_cast(workspace[12]); + } + + void sage_attn_prefill(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, const float *K_mean, const float *V_mean, int32_t batch_size, int32_t head_size, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, bool causal_mask) { + const int32_t Tr = (seq_size_q + Br - 1) / Br; + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_kv_head = h_idx / kv_group_size; + + float *p_acc_o = acc_o_ + thread_id * Br * dim_size; + float *p_acc_s = acc_s_ + thread_id * Br * Bc; + float *p_logsum = logsum_ + thread_id * Br; + float *p_scoremax = scoremax_ + thread_id * Br; + float *p_scoremax_prev = scoremax_prev_ + thread_id * Br; + float *p_score_scale = score_scale_ + thread_id * Br; + float *p_score_sum = score_sum_ + thread_id * Br; + int8_t *p_q_quant = q_quant_tile_ + thread_id * Br * dim_size; + const int8_t *p_k_quant_global = k_quant_tile_ + (b_idx * KV_Head + this_thread_kv_head) * seq_size_k * dim_size; + float *p_q_scale = q_scale_ + thread_id * Br; + const float *p_k_scale_global = k_scale_ + (b_idx * KV_Head + this_thread_kv_head) * seq_size_k; + float *p_q_scaled = q_scaled_row_buf_ + thread_id * dim_size; + + const float *p_V_mean = V_mean + b_idx * KV_Head * dim_size + this_thread_kv_head * dim_size; + const int k_stride = KV_Head * dim_size; + + for (int32_t t_r_idx = 0; t_r_idx < Tr; ++t_r_idx) { + int32_t Br_fixed = std::min(Br, seq_size_q - t_r_idx * Br); + init_temp(p_logsum, p_scoremax, p_acc_o, Br_fixed, dim_size); + + const dtype_q_in_t *tile_q_main = Q + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + h_idx * dim_size; + for (int r = 0; r < Br_fixed; ++r) { + quantize_row_simd(tile_q_main + r * (head_size * dim_size), p_q_quant + r * dim_size, &p_q_scale[r], dim_size, local_scale, p_q_scaled); + } + + for (int32_t t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + int32_t Bc_fixed = std::min(Bc, seq_size_k - t_c_idx * Bc); + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * k_stride + t_c_idx * Bc * k_stride + this_thread_kv_head * dim_size; + + quantize_and_mma0_sdot(Br_fixed, Bc_fixed, p_q_quant, p_k_quant_global + t_c_idx * Bc * dim_size, p_acc_s, p_q_scale, p_k_scale_global + t_c_idx * Bc, dim_size, t_r_idx * Br, t_c_idx * Bc, causal_mask); + softmax(Br_fixed, Bc_fixed, p_acc_s, p_scoremax, p_scoremax_prev, p_score_scale, p_score_sum, p_logsum); + rescale(Br_fixed, p_acc_o, p_score_scale, dim_size); + mma1(Br_fixed, Bc_fixed, p_acc_s, tile_v, p_V_mean, p_acc_o, KV_Head, dim_size); + } + + dtype_out_t *tile_o = O + b_idx * seq_size_q * head_size * dim_size + t_r_idx * Br * head_size * dim_size + h_idx * dim_size; + scale_and_store(Br_fixed, p_acc_o, p_logsum, p_V_mean, tile_o, head_size, dim_size); + } + } + } + } + + void sage_attn_decode(const dtype_q_in_t *__restrict__ Q, const dtype_kv_in_t *__restrict__ K, const dtype_kv_in_t *__restrict__ V, dtype_out_t *__restrict__ O, const float *K_mean, const float *V_mean, int32_t batch_size, int32_t head_size, int32_t seq_size_k, int32_t dim_size, bool causal_mask) { + const int32_t Tc = (seq_size_k + Bc - 1) / Bc; + const float local_scale = 1.0f / sqrtf(static_cast(dim_size)); + const int32_t kv_group_size = (Q_Head > 0 && KV_Head > 0) ? Q_Head / KV_Head : 1; + + for (int32_t b_idx = 0; b_idx < batch_size; ++b_idx) { +#pragma omp parallel for num_threads(threads) schedule(dynamic, 1) + for (int32_t h_idx = 0; h_idx < head_size; ++h_idx) { + const int32_t Br_fixed = 1; + const int32_t thread_id = omp_get_thread_num(); + const int32_t this_thread_kv_head = h_idx / kv_group_size; + + float *p_acc_o = acc_o_ + thread_id * Br_fixed * dim_size; + float *p_acc_s = acc_s_ + thread_id * Br_fixed * Bc; + float *p_logsum = logsum_ + thread_id * Br_fixed; + float *p_scoremax = scoremax_ + thread_id * Br_fixed; + float *p_scoremax_prev = scoremax_prev_ + thread_id * Br_fixed; + float *p_score_scale = score_scale_ + thread_id * Br_fixed; + float *p_score_sum = score_sum_ + thread_id * Br_fixed; + int8_t *p_q_quant = q_quant_tile_ + thread_id * Br_fixed * dim_size; + const int8_t *p_k_quant_global = k_quant_tile_ + (b_idx * KV_Head + this_thread_kv_head) * seq_size_k * dim_size; + float *p_q_scale = q_scale_ + thread_id * Br_fixed; + const float *p_k_scale_global = k_scale_ + (b_idx * KV_Head + this_thread_kv_head) * seq_size_k; + float *p_q_scaled = q_scaled_row_buf_ + thread_id * dim_size; + + const float *p_V_mean = V_mean + b_idx * KV_Head * dim_size + this_thread_kv_head * dim_size; + const int k_stride = KV_Head * dim_size; + + const dtype_q_in_t *tile_q_decode = Q + b_idx * head_size * dim_size + h_idx * dim_size; + quantize_row_simd(tile_q_decode, p_q_quant, p_q_scale, dim_size, local_scale, p_q_scaled); + + init_temp(p_logsum, p_scoremax, p_acc_o, Br_fixed, dim_size); + + for (int32_t t_c_idx = 0; t_c_idx < Tc; ++t_c_idx) { + int32_t Bc_fixed = std::min(Bc, seq_size_k - t_c_idx * Bc); + const dtype_kv_in_t *tile_v = V + b_idx * seq_size_k * k_stride + t_c_idx * Bc * k_stride + this_thread_kv_head * dim_size; + + quantize_and_mma0_sdot(Br_fixed, Bc_fixed, p_q_quant, p_k_quant_global + t_c_idx * Bc * dim_size, p_acc_s, p_q_scale, p_k_scale_global + t_c_idx * Bc, dim_size, seq_size_k - 1, t_c_idx * Bc, causal_mask); + softmax(Br_fixed, Bc_fixed, p_acc_s, p_scoremax, p_scoremax_prev, p_score_scale, p_score_sum, p_logsum); + rescale(Br_fixed, p_acc_o, p_score_scale, dim_size); + mma1(Br_fixed, Bc_fixed, p_acc_s, tile_v, p_V_mean, p_acc_o, KV_Head, dim_size); + } + dtype_out_t *tile_o = O + b_idx * head_size * dim_size + h_idx * dim_size; + scale_and_store(Br_fixed, p_acc_o, p_logsum, p_V_mean, tile_o, head_size, dim_size); + } + } + } + + void init_temp(float *logsum, float *scoremax, float *acc_o, int Br_fixed, int dim_size) { + for (int i = 0; i < Br_fixed; ++i) { + logsum[i] = 0.0f; + scoremax[i] = NEG_INF; + } + memset(acc_o, 0, Br_fixed * dim_size * sizeof(float)); + } + + void quantize_and_mma0_sdot(int Br_fixed, int Bc_fixed, const int8_t *q_quant_tile, const int8_t *k_quant_tile, float *acc_s, const float *q_scale, const float *k_scale, int dim_size, int global_r_start, int global_c_start, bool causal) { +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FEATURE_DOTPROD) + constexpr int MR = 4; + constexpr int NR = 4; + const int br_4_end = (Br_fixed / MR) * MR; + const int bc_4_end = (Bc_fixed / NR) * NR; + + int r = 0; + for (; r < br_4_end; r += MR) { + int c = 0; + for (; c < bc_4_end; c += NR) { + int32x4_t vacc[MR][NR]; + for (int i = 0; i < MR; ++i) + for (int j = 0; j < NR; ++j) vacc[i][j] = vdupq_n_s32(0); + + const int8_t *q_ptr[MR]; + for (int i = 0; i < MR; ++i) q_ptr[i] = q_quant_tile + (r + i) * dim_size; + const int8_t *k_ptr[NR]; + for (int j = 0; j < NR; ++j) k_ptr[j] = k_quant_tile + (c + j) * dim_size; + + int d = 0; + for (; d <= dim_size - 16; d += 16) { + int8x16_t k0 = vld1q_s8(k_ptr[0] + d); + int8x16_t k1 = vld1q_s8(k_ptr[1] + d); + int8x16_t k2 = vld1q_s8(k_ptr[2] + d); + int8x16_t k3 = vld1q_s8(k_ptr[3] + d); + for (int i = 0; i < MR; ++i) { + int8x16_t q_vec = vld1q_s8(q_ptr[i] + d); + vacc[i][0] = vdotq_s32(vacc[i][0], q_vec, k0); + vacc[i][1] = vdotq_s32(vacc[i][1], q_vec, k1); + vacc[i][2] = vdotq_s32(vacc[i][2], q_vec, k2); + vacc[i][3] = vdotq_s32(vacc[i][3], q_vec, k3); + } + } + + for (int i = 0; i < MR; ++i) { + for (int j = 0; j < NR; ++j) { + int32_t total_i32 = vaddvq_s32(vacc[i][j]); + for (int d_tail = d; d_tail < dim_size; ++d_tail) total_i32 += q_ptr[i][d_tail] * k_ptr[j][d_tail]; + if (causal && (global_c_start + c + j) > (global_r_start + r + i)) { + acc_s[(r + i) * Bc + c + j] = NEG_INF; + } else { + acc_s[(r + i) * Bc + c + j] = (float)total_i32 * q_scale[r + i] * k_scale[c + j]; + } + } + } + } + } + + for (r = 0; r < Br_fixed; ++r) { + int start_c = (r < br_4_end) ? bc_4_end : 0; + for (int c = start_c; c < Bc_fixed; ++c) { + if (causal && (global_c_start + c) > (global_r_start + r)) { + acc_s[r * Bc + c] = NEG_INF; + continue; + } + const int8_t *q_quant_line = q_quant_tile + r * dim_size; + const int8_t *k_quant_line = k_quant_tile + c * dim_size; + int32x4_t acc_i32_vec = vdupq_n_s32(0); + int d = 0; + for (; d <= dim_size - 16; d += 16) acc_i32_vec = vdotq_s32(acc_i32_vec, vld1q_s8(q_quant_line + d), vld1q_s8(k_quant_line + d)); + int32_t total_i32 = vaddvq_s32(acc_i32_vec); + for (; d < dim_size; ++d) total_i32 += q_quant_line[d] * k_quant_line[d]; + acc_s[r * Bc + c] = (float)total_i32 * q_scale[r] * k_scale[c]; + } + } +#elif defined(__AVX2__) + // =========== AVX2 IMPLEMENTATION START (FIXED) =========== + for (int r = 0; r < Br_fixed; ++r) { + for (int c = 0; c < Bc_fixed; ++c) { + if (causal && (global_c_start + c) > (global_r_start + r)) { + acc_s[r * Bc + c] = NEG_INF; + continue; + } + const int8_t *q_quant_line = q_quant_tile + r * dim_size; + const int8_t *k_quant_line = k_quant_tile + c * dim_size; + + // Accumulator for 8x 32-bit integers + __m256i acc_i32_v = _mm256_setzero_si256(); + int d = 0; + + // Process 16 bytes at a time, as we expand 8-bit to 16-bit + for (; d <= dim_size - 16; d += 16) { + // Load 16 int8 values from Q and K + __m128i q_i8_v = _mm_loadu_si128((const __m128i *)(q_quant_line + d)); + __m128i k_i8_v = _mm_loadu_si128((const __m128i *)(k_quant_line + d)); + + // Convert signed 8-bit integers to signed 16-bit integers + __m256i q_i16_v = _mm256_cvtepi8_epi16(q_i8_v); + __m256i k_i16_v = _mm256_cvtepi8_epi16(k_i8_v); + + // Multiply signed 16-bit integers and horizontally add adjacent pairs + // This computes dot products of 2-element chunks and stores them in 32-bit lanes + __m256i prod_i32_v = _mm256_madd_epi16(q_i16_v, k_i16_v); + + // Accumulate the 32-bit results + acc_i32_v = _mm256_add_epi32(acc_i32_v, prod_i32_v); + } + + // Horizontally sum the 8 integer results in the accumulator vector + int32_t total_i32 = hsum_i32(acc_i32_v); + + // Handle remainder + for (; d < dim_size; ++d) { + total_i32 += q_quant_line[d] * k_quant_line[d]; + } + + acc_s[r * Bc + c] = (float)total_i32 * q_scale[r] * k_scale[c]; + } + } + // =========== AVX2 IMPLEMENTATION END =========== +#else + // Fallback for other platforms + for (int r = 0; r < Br_fixed; ++r) { + for (int c = 0; c < Bc_fixed; ++c) { + if (causal && (global_c_start + c) > (global_r_start + r)) { + acc_s[r * Bc + c] = NEG_INF; + continue; + } + const int8_t *q_quant_line = q_quant_tile + r * dim_size; + const int8_t *k_quant_line = k_quant_tile + c * dim_size; + int32_t total_i32 = 0; + for (int d = 0; d < dim_size; ++d) total_i32 += q_quant_line[d] * k_quant_line[d]; + acc_s[r * Bc + c] = (float)total_i32 * q_scale[r] * k_scale[c]; + } + } +#endif + } + + void softmax(int Br_fixed, int Bc_fixed, float *acc_s, float *scoremax, float *scoremax_prev, float *score_scale, float *score_sum, float *logsum) { + memcpy(scoremax_prev, scoremax, Br_fixed * sizeof(float)); + for (int r = 0; r < Br_fixed; ++r) { + float *row = acc_s + r * Bc; + float current_max = scoremax[r]; + for (int c = 0; c < Bc_fixed; ++c) current_max = std::max(current_max, row[c]); + scoremax[r] = current_max; + } + for (int r = 0; r < Br_fixed; ++r) score_scale[r] = expf(scoremax_prev[r] - scoremax[r]); + for (int r = 0; r < Br_fixed; ++r) { + float *row = acc_s + r * Bc; + float sm = scoremax[r]; + float sum = 0.f; + for (int c = 0; c < Bc_fixed; ++c) { + if (row[c] > NEG_INF / 2) { + float val = expf(row[c] - sm); + row[c] = val; + sum += val; + } else { + row[c] = 0.f; + } + } + score_sum[r] = sum; + } + for (int r = 0; r < Br_fixed; ++r) logsum[r] = logsum[r] * score_scale[r] + score_sum[r]; + } + void rescale(int Br_fixed, float *acc_o, const float *score_scale, int dim_size) { + for (int r = 0; r < Br_fixed; ++r) { + float scale_val = score_scale[r]; + float *row_ptr = acc_o + r * dim_size; +#if defined(__AVX2__) + __m256 scale_vec = _mm256_set1_ps(scale_val); + int d = 0; + for (; d <= dim_size - 8; d += 8) _mm256_storeu_ps(row_ptr + d, _mm256_mul_ps(_mm256_loadu_ps(row_ptr + d), scale_vec)); + for (; d < dim_size; ++d) row_ptr[d] *= scale_val; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t scale_vec = vdupq_n_f32(scale_val); + int d = 0; + for (; d <= dim_size - 4; d += 4) vst1q_f32(row_ptr + d, vmulq_f32(vld1q_f32(row_ptr + d), scale_vec)); + for (; d < dim_size; ++d) row_ptr[d] *= scale_val; +#else + for (int d = 0; d < dim_size; ++d) row_ptr[d] *= scale_val; +#endif + } + } + + void mma1(int Br_fixed, int Bc_fixed, const float *p_block, const dtype_kv_in_t *v_block, const float *v_mean, float *acc_o, int kv_head_size, int dim_size) { + int v_stride = kv_head_size * dim_size; + +#if (defined(__ARM_NEON) || defined(__ARM_NEON__)) && defined(__ARM_FP16_FORMAT_IEEE) + for (int r = 0; r < Br_fixed; ++r) { + float *o_row = acc_o + r * dim_size; + const float *p_row = p_block + r * Bc; + + for (int d = 0; d < dim_size; d += 4) { + float32x4_t o_acc_vec = vld1q_f32(o_row + d); + const float32x4_t vm_vec = vld1q_f32(v_mean + d); + + int c = 0; + for (; c <= Bc_fixed - 4; c += 4) { + // 预取更远的数据 + __builtin_prefetch(v_block + (c + 8) * v_stride + d, 0, 0); + + // 加载 4 个 P 标量 + const float p0 = p_row[c + 0]; + const float p1 = p_row[c + 1]; + const float p2 = p_row[c + 2]; + const float p3 = p_row[c + 3]; + + // 加载 4 个 V 向量 + const dtype_kv_in_t *v_row0 = v_block + (c + 0) * v_stride; + const dtype_kv_in_t *v_row1 = v_block + (c + 1) * v_stride; + const dtype_kv_in_t *v_row2 = v_block + (c + 2) * v_stride; + const dtype_kv_in_t *v_row3 = v_block + (c + 3) * v_stride; + + float32x4_t v_vec0, v_vec1, v_vec2, v_vec3; + if constexpr (std::is_same_v) { + v_vec0 = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row0 + d))); + v_vec1 = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row1 + d))); + v_vec2 = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row2 + d))); + v_vec3 = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row3 + d))); + } else { // float + v_vec0 = vld1q_f32(v_row0 + d); + v_vec1 = vld1q_f32(v_row1 + d); + v_vec2 = vld1q_f32(v_row2 + d); + v_vec3 = vld1q_f32(v_row3 + d); + } + + // 4组独立的 FMA 运算 + o_acc_vec = vfmaq_n_f32(o_acc_vec, vsubq_f32(v_vec0, vm_vec), p0); + o_acc_vec = vfmaq_n_f32(o_acc_vec, vsubq_f32(v_vec1, vm_vec), p1); + o_acc_vec = vfmaq_n_f32(o_acc_vec, vsubq_f32(v_vec2, vm_vec), p2); + o_acc_vec = vfmaq_n_f32(o_acc_vec, vsubq_f32(v_vec3, vm_vec), p3); + } + + // 处理剩余的循环 + for (; c < Bc_fixed; ++c) { + const float p_scalar = p_row[c]; + const float32x4_t p_vec = vdupq_n_f32(p_scalar); + const dtype_kv_in_t *v_row = v_block + c * v_stride; + float32x4_t v_vec; + if constexpr (std::is_same_v) { + v_vec = vcvt_f32_f16(vld1_f16(reinterpret_cast(v_row + d))); + } else { + v_vec = vld1q_f32(v_row + d); + } + float32x4_t v_smoothed = vsubq_f32(v_vec, vm_vec); + o_acc_vec = vfmaq_f32(o_acc_vec, p_vec, v_smoothed); + } + + vst1q_f32(o_row + d, o_acc_vec); + } + } +#elif defined(__AVX2__) && defined(__FMA__) + // =========== AVX2 IMPLEMENTATION START =========== + for (int r = 0; r < Br_fixed; ++r) { + float *o_row = acc_o + r * dim_size; + for (int c = 0; c < Bc_fixed; ++c) { + const float p_scalar = p_block[r * Bc + c]; + if (fabsf(p_scalar) < 1e-9) continue; + + const __m256 p_vec = _mm256_set1_ps(p_scalar); + const dtype_kv_in_t *v_row = v_block + c * v_stride; + + int d = 0; + for (; d <= dim_size - 8; d += 8) { + const __m256 vm_vec = _mm256_loadu_ps(v_mean + d); + const __m256 v_vec = load_and_convert_to_fp32_vec(v_row + d); + + __m256 o_vec = _mm256_loadu_ps(o_row + d); + __m256 v_smoothed = _mm256_sub_ps(v_vec, vm_vec); + + // Fused Multiply-Add: o_vec = (p_vec * v_smoothed) + o_vec + o_vec = _mm256_fmadd_ps(p_vec, v_smoothed, o_vec); + + _mm256_storeu_ps(o_row + d, o_vec); + } + // Remainder loop + for (; d < dim_size; ++d) { + o_row[d] += p_scalar * (to_float(v_row[d]) - v_mean[d]); + } + } + } + // =========== AVX2 IMPLEMENTATION END =========== +#else + // Fallback for other platforms + for (int r = 0; r < Br_fixed; ++r) { + float *o_row = acc_o + r * dim_size; + for (int c = 0; c < Bc_fixed; ++c) { + const float p = p_block[r * Bc + c]; + if (fabsf(p) < 1e-9) continue; + const dtype_kv_in_t *v_row = v_block + c * v_stride; + for (int d = 0; d < dim_size; ++d) { o_row[d] += p * (to_float(v_row[d]) - v_mean[d]); } + } + } +#endif + } + + void scale_and_store(int Br_fixed, const float *acc_o, const float *logsum, const float *v_mean, float *O, int head_size, int dim_size) { + int o_stride = head_size * dim_size; + for (int r = 0; r < Br_fixed; ++r) { + float inv_logsum = (logsum[r] > 1e-9f) ? 1.f / logsum[r] : 0.f; + const float *o_row = acc_o + r * dim_size; + float *O_row = O + r * o_stride; +#if defined(__AVX2__) && defined(__FMA__) + const __m256 inv_logsum_vec = _mm256_set1_ps(inv_logsum); + int d = 0; + for (; d <= dim_size - 8; d += 8) { + const __m256 o_vec = _mm256_loadu_ps(o_row + d); + const __m256 vm_vec = _mm256_loadu_ps(v_mean + d); + _mm256_storeu_ps(O_row + d, _mm256_fmadd_ps(o_vec, inv_logsum_vec, vm_vec)); + } + for (; d < dim_size; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#elif (defined(__ARM_NEON) || defined(__ARM_NEON__)) + float32x4_t inv_logsum_vec = vdupq_n_f32(inv_logsum); + int d = 0; + for (; d <= dim_size - 4; d += 4) { + float32x4_t o_vec = vld1q_f32(o_row + d); + float32x4_t vm_vec = vld1q_f32(v_mean + d); + vst1q_f32(O_row + d, vfmaq_f32(vm_vec, o_vec, inv_logsum_vec)); + } + for (; d < dim_size; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#else + for (int d = 0; d < dim_size; ++d) O_row[d] = o_row[d] * inv_logsum + v_mean[d]; +#endif + } + } +}; + +template +void sage_attention_forward_cpu_dispatch(const float *Q, const KVDtype *K, const KVDtype *V, float *O, int32_t batch_size, int32_t q_head, int32_t kv_head, int32_t seq_size_q, int32_t seq_size_k, int32_t dim_size, bool causal_mask, int32_t threads, int32_t br, int32_t bc) { + std::vector V_mean(batch_size * kv_head * dim_size); + compute_channel_means(V, V_mean.data(), batch_size, kv_head, seq_size_k, dim_size); + + thread_local WorkspaceManager manager; + + std::vector K_mean(batch_size * kv_head * dim_size); + + if (seq_size_q > 1) { // Prefill + const std::vector required_sizes = { + (size_t)threads * br * dim_size * sizeof(float), + (size_t)threads * br * bc * sizeof(float), + (size_t)threads * br * sizeof(float), + (size_t)threads * br * sizeof(float), + (size_t)threads * br * sizeof(float), + (size_t)threads * br * sizeof(float), + (size_t)threads * br * sizeof(float), + (size_t)threads * br * dim_size * sizeof(int8_t), + (size_t)batch_size * kv_head * seq_size_k * dim_size * sizeof(int8_t), + (size_t)threads * br * sizeof(float), + (size_t)batch_size * kv_head * seq_size_k * sizeof(float), + (size_t)threads * dim_size * sizeof(float), + (size_t)threads * dim_size * sizeof(float), + (size_t)threads * dim_size * sizeof(float), + }; + void **workspace = manager.get_workspace(required_sizes); + + int8_t *k_quant_global_buffer = static_cast(workspace[8]); + float *k_scale_global_buffer = static_cast(workspace[10]); + + compute_mean_and_quantize_k(K, K_mean.data(), k_quant_global_buffer, k_scale_global_buffer, batch_size, kv_head, seq_size_k, dim_size, threads, static_cast(workspace[13]), static_cast(workspace[11])); + + SAGE_CPU_IMPL op; + op.configure(br, bc, q_head, kv_head, threads); + op.init_workspace(workspace); + op.sage_attn_prefill(Q, K, V, O, K_mean.data(), V_mean.data(), batch_size, q_head, seq_size_q, seq_size_k, dim_size, causal_mask); + } else { // Decode + const int32_t decode_br = 1; + const std::vector required_sizes = { + (size_t)threads * decode_br * dim_size * sizeof(float), + (size_t)threads * decode_br * bc * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * sizeof(float), + (size_t)threads * decode_br * dim_size * sizeof(int8_t), + (size_t)batch_size * kv_head * seq_size_k * dim_size * sizeof(int8_t), + (size_t)threads * decode_br * sizeof(float), + (size_t)batch_size * kv_head * seq_size_k * sizeof(float), + (size_t)threads * dim_size * sizeof(float), + (size_t)threads * dim_size * sizeof(float), + (size_t)threads * dim_size * sizeof(float), + }; + void **workspace = manager.get_workspace(required_sizes); + + int8_t *k_quant_global_buffer = static_cast(workspace[8]); + float *k_scale_global_buffer = static_cast(workspace[10]); + + compute_mean_and_quantize_k(K, K_mean.data(), k_quant_global_buffer, k_scale_global_buffer, batch_size, kv_head, seq_size_k, dim_size, threads, static_cast(workspace[13]), static_cast(workspace[11])); + + SAGE_CPU_IMPL op; + op.configure(br, bc, q_head, kv_head, threads); + op.init_workspace(workspace); + op.sage_attn_decode(Q, K, V, O, K_mean.data(), V_mean.data(), batch_size, q_head, seq_size_k, dim_size, causal_mask); + } +} +} // namespace sage_attn_pt_cpu diff --git a/src/backends/cpu/compute/SageQuantize.hpp b/src/backends/cpu/compute/SageQuantize.hpp new file mode 100644 index 000000000..9d33f0b48 --- /dev/null +++ b/src/backends/cpu/compute/SageQuantize.hpp @@ -0,0 +1,138 @@ +#ifndef SAGE_QUANT_H +#define SAGE_QUANT_H + +#include +#include +#include +#include +#include +#include +#include +#include "Types.hpp" + +// --- SIMD Intrinsics (依赖项) --- +#ifdef __AVX2__ +#include +#endif + +// 外部依赖,确保QK8_0F在包含此文件前已定义 +// 或者直接在这里定义 +// #ifndef QK8_0F +// #define QK8_0F 128 +// #endif + +// 为了让工具函数独立,把 hmax_ps 这种辅助函数也移过来 +#ifdef __AVX2__ +namespace { // 放在匿名空间中,使其为内部链接 +inline float _mm256_hmax_ps(__m256 x) { + __m128 lo = _mm256_castps256_ps128(x); + __m128 hi = _mm256_extractf128_ps(x, 1); + __m128 max_val = _mm_max_ps(lo, hi); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 2, 2))); + max_val = _mm_max_ps(max_val, _mm_shuffle_ps(max_val, max_val, _MM_SHUFFLE(0, 0, 0, 1))); + return _mm_cvtss_f32(max_val); +} +} // namespace +#endif + +// struct block_q8_0f { +// float scale; +// int8_t qs[QK8_0F]; +// }; +#pragma region "SAGE KV Cache Utils" +namespace sage_kv_cache { +inline void compute_sage_mean_vector(const float *head_start_ptr, float *out_mean, + int seq_size_k, int dim_size, size_t stride_s) { + if (seq_size_k == 0) + return; + std::vector sum(dim_size, 0.0); +#pragma omp parallel + { + std::vector local_sum(dim_size, 0.0); +#pragma omp for + for (int s = 0; s < seq_size_k; ++s) { + const float *row_ptr = head_start_ptr + s * stride_s; + for (int d = 0; d < dim_size; ++d) + local_sum[d] += row_ptr[d]; + } +#pragma omp critical + { + for (int d = 0; d < dim_size; ++d) + sum[d] += local_sum[d]; + } + } + const float inv_seq_len = 1.0f / static_cast(seq_size_k); +#pragma omp parallel for + for (int d = 0; d < dim_size; ++d) + out_mean[d] = sum[d] * inv_seq_len; +} + +inline void update_sage_mean_vector_incremental(float *mean_vector_io, + const float *new_token_vector, + int old_seq_len, int dim_size) { + if (old_seq_len <= 0) { + memcpy(mean_vector_io, new_token_vector, dim_size * sizeof(float)); + return; + } + const float N = static_cast(old_seq_len); + const float factor1 = N / (N + 1.0f); + const float factor2 = 1.0f / (N + 1.0f); +#pragma omp parallel for + for (int d = 0; d < dim_size; ++d) + mean_vector_io[d] = + mean_vector_io[d] * factor1 + new_token_vector[d] * factor2; +} + +template +inline void quantize_new_token_to_sage_blocks(const float *new_token_vector, + const float *current_mean_data, + T *out_blocks_for_token, int dim_size) { + static_assert(std::is_same_v, + "This function can only quantize to block_q8_0f."); + block_q8_0f *out_ptr = reinterpret_cast(out_blocks_for_token); + const int num_k_blocks = dim_size / QK8_0F; + std::vector smoothed_row(dim_size); + for (int d = 0; d < dim_size; ++d) + smoothed_row[d] = new_token_vector[d] - current_mean_data[d]; + for (int g = 0; g < num_k_blocks; ++g) { + const int offset = g * QK8_0F; + const float *smoothed_block_ptr = smoothed_row.data() + offset; + float max_abs_val = 0.0f; + for (int d = 0; d < QK8_0F; ++d) + max_abs_val = std::max(max_abs_val, fabsf(smoothed_block_ptr[d])); + const float scale = (max_abs_val > 1e-9f) ? max_abs_val / 127.0f : 0.0f; + out_ptr[g].scale = scale; + const float inv_scale = (scale > 1e-9f) ? 1.0f / scale : 0.0f; + for (int d = 0; d < QK8_0F; ++d) + out_ptr[g].qs[d] = + static_cast(roundf(smoothed_block_ptr[d] * inv_scale)); + } +} + +// [修正] 改为只为单个头计算均值 +inline void compute_sage_mean_for_one_head_bshd( + const float *head_start_ptr, // 指向单个头的起始地址 + float *out_mean_for_head, // 指向该头对应的均值输出位置 + int seq_size, int dim_size, + size_t s_stride // BSHD布局下,序列方向的步长 +) { + if (seq_size == 0) return; + + std::vector sum(dim_size, 0.0); + for (int s = 0; s < seq_size; ++s) { + // 直接通过步长访问一个头内的所有序列 + const float *row_ptr = head_start_ptr + s * s_stride; + for (int d = 0; d < dim_size; ++d) { + sum[d] += row_ptr[d]; + } + } + + const float inv_seq_len = 1.0f / static_cast(seq_size); + for (int d = 0; d < dim_size; ++d) { + out_mean_for_head[d] = sum[d] * inv_seq_len; + } +} + +} // namespace sage_kv_cache +#pragma endregion +#endif // SAGE_QUANT_H \ No newline at end of file diff --git a/src/backends/cpu/compute/Split.hpp b/src/backends/cpu/compute/Split.hpp index 99f3c19e6..9c10ab3b0 100644 --- a/src/backends/cpu/compute/Split.hpp +++ b/src/backends/cpu/compute/Split.hpp @@ -1,3 +1,117 @@ +// #include +// #include +// #include +// #include +// #include // for memcpy + +// // 引入 OpenMP 头文件 +// #include + +// // 引入SIMD头文件 +// #if defined(__AVX__) +// #include +// #elif defined(__ARM_NEON) +// #include +// #endif + +// /** +// * @brief 高效地将一个4D张量按指定维度分割 (OpenMP并行版本) +// * @param origin 输入的4D张量的裸指针 +// * @param origin_dims 输入张量的维度信息,大小为4的数组,例如 {N, C, H, W} +// * @param out 输出张量指针的向量 +// * @param split_dims 每个输出张量在分割维度上的大小 +// * @param dim_id 要进行分割的维度索引 (0到3) +// */ +// void efficient_split(const float *origin, const int *origin_dims, +// std::vector &out, const std::vector &split_dims, +// int dim_id) { +// // --- 1. 输入验证 --- +// if (dim_id < 0 || dim_id > 3) { +// throw std::invalid_argument("Error: dim_id must be between 0 and 3."); +// } + +// int total_split_dim = std::accumulate(split_dims.begin(), split_dims.end(), 0); +// if (total_split_dim != origin_dims[dim_id]) { +// throw std::invalid_argument("Error: Sum of split_dims must be equal to the dimension size of origin tensor."); +// } + +// if (out.size() != split_dims.size()) { +// throw std::invalid_argument("Error: The size of 'out' vector must be equal to the size of 'split_dims' vector."); +// } + +// // --- 2. 计算步长和循环尺寸 --- +// int strides[4]; +// strides[3] = 1; +// for (int i = 2; i >= 0; --i) { +// strides[i] = strides[i + 1] * origin_dims[i + 1]; +// } + +// int outer_loop_size = 1; +// for (int i = 0; i < dim_id; ++i) { +// outer_loop_size *= origin_dims[i]; +// } + +// int inner_loop_size = strides[dim_id]; +// int original_dim_size_at_split_axis = origin_dims[dim_id] * inner_loop_size; + +// // --- 3. 为并行计算预先计算偏移量 --- +// // 为了使主循环能够并行化,我们需要为每个输出张量预先计算其在源张量中的起始偏移量。 +// // 这避免了在循环中依赖于前一次迭代结果的顺序更新。 +// std::vector split_offsets(split_dims.size() + 1, 0); +// for (size_t i = 0; i < split_dims.size(); ++i) { +// split_offsets[i + 1] = split_offsets[i] + split_dims[i]; +// } + +// // --- 4. 并行处理 --- +// // 使用 OpenMP 对主循环进行并行化。 +// // OpenMP 会自动根据系统配置或 OMP_NUM_THREADS 环境变量来决定使用的线程数。 +// // 循环变量 'i' 默认是私有的。所有在循环外声明的变量都是共享的, +// // 这在这里是安全的,因为它们在并行区域内是只读的(除了 'out',但每个线程访问 out[i],不会冲突)。 +// #pragma omp parallel for +// for (size_t i = 0; i < out.size(); ++i) { +// float *out_ptr = out[i]; +// const int split_size = split_dims[i]; +// const int offset_in_dim = split_offsets[i]; + +// // 遍历所有不被分割的外部维度 +// for (int outer_idx = 0; outer_idx < outer_loop_size; ++outer_idx) { +// // 计算源和目标在当前外部维度块的基地址 +// const float *src_base = origin + outer_idx * original_dim_size_at_split_axis + offset_in_dim * inner_loop_size; +// float *dst_base = out_ptr + outer_idx * split_size * inner_loop_size; + +// // 沿着分割轴,拷贝 'split_size' 个大小为 'inner_loop_size' 的数据块 +// for (int split_idx = 0; split_idx < split_size; ++split_idx) { +// const float *src = src_base + split_idx * inner_loop_size; +// float *dst = dst_base + split_idx * inner_loop_size; +// int count = inner_loop_size; + +// // 使用SIMD指令集进行高效的内存拷贝 +// #if defined(__AVX__) +// for (; count >= 8; count -= 8) { +// __m256 data = _mm256_loadu_ps(src); +// _mm256_storeu_ps(dst, data); +// src += 8; +// dst += 8; +// } +// #elif defined(__ARM_NEON) +// for (; count >= 4; count -= 4) { +// float32x4_t data = vld1q_f32(src); +// vst1q_f32(dst, data); +// src += 4; +// dst += 4; +// } +// #endif +// // 处理剩余不足一个SIMD寄存器大小的数据 +// for (; count > 0; --count) { +// *dst++ = *src++; +// } +// } +// } +// } +// } + +// Split.hpp + #include #include #include @@ -14,16 +128,22 @@ #include #endif +// 新增:引入项目所需的数据类型和转换定义 +#include "Types.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" + /** - * @brief 高效地将一个4D张量按指定维度分割 (OpenMP并行版本) - * @param origin 输入的4D张量的裸指针 + * @brief 高效地将一个4D张量按指定维度分割 (OpenMP并行版本),支持混合输出类型(float/fp16) + * @param origin 输入的4D张量的裸指针 (必须是 float 类型) * @param origin_dims 输入张量的维度信息,大小为4的数组,例如 {N, C, H, W} - * @param out 输出张量指针的向量 + * @param out 输出张量裸指针的向量 (void*) + * @param out_types 每个输出张量的数据类型 * @param split_dims 每个输出张量在分割维度上的大小 * @param dim_id 要进行分割的维度索引 (0到3) */ void efficient_split(const float *origin, const int *origin_dims, - std::vector &out, const std::vector &split_dims, + std::vector &out, const std::vector &out_types, // 修改点 + const std::vector &split_dims, int dim_id) { // --- 1. 输入验证 --- if (dim_id < 0 || dim_id > 3) { @@ -35,8 +155,8 @@ void efficient_split(const float *origin, const int *origin_dims, throw std::invalid_argument("Error: Sum of split_dims must be equal to the dimension size of origin tensor."); } - if (out.size() != split_dims.size()) { - throw std::invalid_argument("Error: The size of 'out' vector must be equal to the size of 'split_dims' vector."); + if (out.size() != split_dims.size() || out.size() != out_types.size()) { // 修改点 + throw std::invalid_argument("Error: The size of 'out', 'out_types', and 'split_dims' vectors must be equal."); } // --- 2. 计算步长和循环尺寸 --- @@ -55,56 +175,94 @@ void efficient_split(const float *origin, const int *origin_dims, int original_dim_size_at_split_axis = origin_dims[dim_id] * inner_loop_size; // --- 3. 为并行计算预先计算偏移量 --- - // 为了使主循环能够并行化,我们需要为每个输出张量预先计算其在源张量中的起始偏移量。 - // 这避免了在循环中依赖于前一次迭代结果的顺序更新。 std::vector split_offsets(split_dims.size() + 1, 0); for (size_t i = 0; i < split_dims.size(); ++i) { split_offsets[i + 1] = split_offsets[i] + split_dims[i]; } - // --- 4. 并行处理 --- - // 使用 OpenMP 对主循环进行并行化。 - // OpenMP 会自动根据系统配置或 OMP_NUM_THREADS 环境变量来决定使用的线程数。 - // 循环变量 'i' 默认是私有的。所有在循环外声明的变量都是共享的, - // 这在这里是安全的,因为它们在并行区域内是只读的(除了 'out',但每个线程访问 out[i],不会冲突)。 - #pragma omp parallel for +// --- 4. 并行处理 --- +#pragma omp parallel for for (size_t i = 0; i < out.size(); ++i) { - float *out_ptr = out[i]; + void *out_ptr_void = out[i]; const int split_size = split_dims[i]; const int offset_in_dim = split_offsets[i]; + const DataType out_type = out_types[i]; // 遍历所有不被分割的外部维度 for (int outer_idx = 0; outer_idx < outer_loop_size; ++outer_idx) { - // 计算源和目标在当前外部维度块的基地址 + // 计算源在当前外部维度块的基地址 const float *src_base = origin + outer_idx * original_dim_size_at_split_axis + offset_in_dim * inner_loop_size; - float *dst_base = out_ptr + outer_idx * split_size * inner_loop_size; - - // 沿着分割轴,拷贝 'split_size' 个大小为 'inner_loop_size' 的数据块 - for (int split_idx = 0; split_idx < split_size; ++split_idx) { - const float *src = src_base + split_idx * inner_loop_size; - float *dst = dst_base + split_idx * inner_loop_size; - int count = inner_loop_size; - // 使用SIMD指令集进行高效的内存拷贝 + // --- 修改点:根据输出类型选择不同的处理路径 --- + if (out_type == MLLM_TYPE_F32) { + float *out_ptr = static_cast(out_ptr_void); + float *dst_base = out_ptr + outer_idx * split_size * inner_loop_size; + const size_t copy_bytes = split_size * inner_loop_size * sizeof(float); + // memcpy(dst_base, src_base, copy_bytes); + for (int split_idx = 0; split_idx < split_size; ++split_idx) { + const float *src = src_base + split_idx * inner_loop_size; + float *dst = dst_base + split_idx * inner_loop_size; + int count = inner_loop_size; #if defined(__AVX__) - for (; count >= 8; count -= 8) { - __m256 data = _mm256_loadu_ps(src); - _mm256_storeu_ps(dst, data); - src += 8; - dst += 8; - } + for (; count >= 8; count -= 8) { + __m256 data = _mm256_loadu_ps(src); + _mm256_storeu_ps(dst, data); + src += 8; + dst += 8; + } #elif defined(__ARM_NEON) - for (; count >= 4; count -= 4) { - float32x4_t data = vld1q_f32(src); - vst1q_f32(dst, data); - src += 4; - dst += 4; + for (; count >= 4; count -= 4) { + float32x4_t data = vld1q_f32(src); + vst1q_f32(dst, data); + src += 4; + dst += 4; + } +#endif + for (; count > 0; --count) *dst++ = *src++; } + + } else if (out_type == MLLM_TYPE_F16) { + mllm_fp16_t *out_ptr = static_cast(out_ptr_void); + mllm_fp16_t *dst_base = out_ptr + outer_idx * split_size * inner_loop_size; + + for (int split_idx = 0; split_idx < split_size; ++split_idx) { + const float *src = src_base + split_idx * inner_loop_size; + mllm_fp16_t *dst = dst_base + split_idx * inner_loop_size; + int count = inner_loop_size; + +// 使用SIMD指令集进行高效的转换和内存拷贝 +#if defined(__AVX__) && defined(__F16C__) + for (; count >= 8; count -= 8) { + // 从内存加载 8 个 float + __m256 float_vec = _mm256_loadu_ps(src); + // 将 8 个 float 转换为 8 个 fp16 + __m128i fp16_vec = _mm256_cvtps_ph(float_vec, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); + // 存储 8 个 fp16 (128 bits) + _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), fp16_vec); + src += 8; + dst += 8; + } +#elif defined(__ARM_NEON) + for (; count >= 4; count -= 4) { + // 从内存加载 4 个 float + float32x4_t float_vec = vld1q_f32(src); + // 将 4 个 float 转换为 4 个 fp16 + float16x4_t fp16_vec = vcvt_f16_f32(float_vec); + // 存储 4 个 fp16 + vst1_f16(reinterpret_cast(dst), fp16_vec); + src += 4; + dst += 4; + } #endif - // 处理剩余不足一个SIMD寄存器大小的数据 - for (; count > 0; --count) { - *dst++ = *src++; + + // 处理剩余不足一个SIMD寄存器大小的数据 + for (; count > 0; --count) { + *dst++ = MLLM_FP32_TO_FP16(*src++); + } } + } else { + // 如果将来支持更多类型,可以在此添加 + // 为了安全,可以抛出异常或打印错误日志 } } } diff --git a/src/backends/cpu/compute/VecDot.cpp b/src/backends/cpu/compute/VecDot.cpp deleted file mode 100644 index 9b55b71da..000000000 --- a/src/backends/cpu/compute/VecDot.cpp +++ /dev/null @@ -1,4422 +0,0 @@ -/* - * This code is based on ggml(https://github.com/ggerganov/ggml), - * please see https://github.com/ggerganov/ggml/blob/master/src/ggml.c - * ggml is licensed under MIT Copyright (c) 2022 Georgi Gerganov: - * - * MIT License - * Copyright (c) 2022 Georgi Gerganov - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "VecDot.hpp" - -#ifdef __AVX2__ -static void vec_dot_fp32_avx2(const int n, float *__restrict s, const float *__restrict x, const float *__restrict y) { - float sumf = 0.0F; - const int np = (n & ~(MLLM_F32_STEP - 1)); - - MLLM_F32_VEC sum[MLLM_F32_ARR] = {MLLM_F32_VEC_ZERO}; - - MLLM_F32_VEC ax[MLLM_F32_ARR]; - MLLM_F32_VEC ay[MLLM_F32_ARR]; - - for (int i = 0; i < np; i += MLLM_F32_STEP) { - for (int j = 0; j < MLLM_F32_ARR; j++) { - ax[j] = MLLM_F32_VEC_LOAD(x + i + j * MLLM_F32_EPR); - ay[j] = MLLM_F32_VEC_LOAD(y + i + j * MLLM_F32_EPR); - - sum[j] = MLLM_F32_VEC_FMA(sum[j], ax[j], ay[j]); - } - } - - // reduce sum0..sum3 to sum0 - MLLM_F32_VEC_REDUCE(sumf, sum); - - // leftovers - for (int i = np; i < n; ++i) { - sumf += x[i] * y[i]; - } - - *s = sumf; -} -#endif - -#ifdef __ARM_NEON -static void vec_dot_fp32_arm(const int n, float *__restrict s, const float *__restrict x, const float *__restrict y) { - float sumf = 0.0F; - const int np = (n & ~(16 - 1)); - - F32_VEC sum[4] = {vdupq_n_f32(0.0F)}; - - F32_VEC ax[F32_ARR]; - F32_VEC ay[F32_ARR]; - - for (int i = 0; i < np; i += F32_STEP) { - for (int j = 0; j < F32_ARR; j++) { - ax[j] = vld1q_f32(x + i + j * F32_REG); - ay[j] = vld1q_f32(y + i + j * F32_REG); - sum[j] = vfmaq_f32(sum[j], ax[j], ay[j]); - // sum[j] = vmlaq_lane_f32(sum[j], ax[j], ay[0], - } - } - - // reduce sum0..sum3 to sum0 - F32_VEC_REDUCE(sumf, sum); - - // leftovers - for (int i = np; i < n; ++i) { - sumf += x[i] * y[i]; - } - - *s = sumf; -} -#endif - -void vec_dot_fp32(const int n, float *__restrict s, const float *__restrict vx, const float *__restrict vy) { -#ifdef __AVX2__ - vec_dot_fp32_avx2(n, s, vx, vy); -#elif defined(__ARM_NEON) - vec_dot_fp32_arm(n, s, vx, vy); -#endif -} - -void vec_dot_fp16(const int n, float *__restrict s, const mllm_fp16_t *__restrict vx, const mllm_fp16_t *__restrict vy) { - float sumf = 0.0; - -#if defined(__AVX2__) || defined(__ARM_NEON) - const int np = (n & ~(MLLM_F16_STEP - 1)); - - MLLM_F16_VEC sum[MLLM_F16_ARR] = {MLLM_F16_VEC_ZERO}; - - MLLM_F16_VEC ax[MLLM_F16_ARR]; - MLLM_F16_VEC ay[MLLM_F16_ARR]; - - for (int i = 0; i < np; i += MLLM_F16_STEP) { - for (int j = 0; j < MLLM_F16_ARR; j++) { - ax[j] = MLLM_F16_VEC_LOAD(vx + i + j * MLLM_F16_EPR, j); - ay[j] = MLLM_F16_VEC_LOAD(vy + i + j * MLLM_F16_EPR, j); - - sum[j] = MLLM_F16_VEC_FMA(sum[j], ax[j], ay[j]); - } - } - - // reduce sum0..sum3 to sum0 - MLLM_F16_VEC_REDUCE(sumf, sum); - - // leftovers - for (int i = np; i < n; ++i) { - sumf += (float)(MLLM_FP16_TO_FP32(vx[i]) * MLLM_FP16_TO_FP32(vy[i])); - } -#else - for (int i = 0; i < n; ++i) { - sumf += (float)(MLLM_FP16_TO_FP32(vx[i]) * MLLM_FP16_TO_FP32(vy[i])); - } -#endif - - *s = sumf; -} - -#ifdef __AVX2__ -static void vec_dot_q4_0_q8_0_avx(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { - const int qk = QK8_0; - const int nb = n / qk; - - assert(n % qk == 0); - - const block_q4_0 *__restrict x = (block_q4_0 *)vx; - const block_q8_0 *__restrict y = (block_q8_0 *)vy; - // Initialize accumulator with zeros - __m256 acc = _mm256_setzero_ps(); - - // Main loop - for (int i = 0; i < nb; ++i) { - /* Compute combined scale for the block */ - const __m256 d = _mm256_set1_ps(MLLM_FP16_TO_FP32(x[i].d) * MLLM_FP16_TO_FP32(y[i].d)); - - __m256i bx = bytes_from_nibbles_32(x[i].qs); - - // Now we have a vector with bytes in [ 0 .. 15 ] interval. Offset them into [ -8 .. +7 ] interval. - const __m256i off = _mm256_set1_epi8(8); - bx = _mm256_sub_epi8(bx, off); - - __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); - - const __m256 q = mul_sum_i8_pairs_float(bx, by); - - /* Multiply q with scale and accumulate */ - acc = _mm256_fmadd_ps(d, q, acc); - } - *s = hsum_float_8(acc); -} -#endif - -#ifdef __ARM_NEON -// COPY FROMN -static void vec_dot_q4_0_q8_0_arm(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { - const int qk = QK8_0; - const int nb = n / qk; - - assert(n % qk == 0); - - const block_q4_0 *__restrict x = (block_q4_0 *)vx; - const block_q8_0 *__restrict y = (block_q8_0 *)vy; - -#if defined(__ARM_FEATURE_MATMUL_INT8) - { - size_t bs = 0; - size_t bx = 0; - size_t by = 0; - const block_q4_0 *__restrict vx0 = (const block_q4_0 *)vx; - const block_q4_0 *__restrict vx1 = (const block_q4_0 *)((const uint8_t *)vx + bx); - const block_q8_0 *__restrict vy0 = (const block_q8_0 *)vy; - const block_q8_0 *__restrict vy1 = (const block_q8_0 *)((const uint8_t *)vy + by); - - float32x4_t sumv0 = vdupq_n_f32(0.0f); - - for (int i = 0; i < nb; i++) { - const block_q4_0 *__restrict b_x0 = &vx0[i]; - const block_q4_0 *__restrict b_x1 = &vx1[i]; - const block_q8_0 *__restrict b_y0 = &vy0[i]; - const block_q8_0 *__restrict b_y1 = &vy1[i]; - - const uint8x16_t m4b = vdupq_n_u8(0x0F); - const int8x16_t s8b = vdupq_n_s8(0x8); - - const uint8x16_t v0_0 = vld1q_u8(b_x0->qs); - const uint8x16_t v0_1 = vld1q_u8(b_x1->qs); - - // 4-bit -> 8-bit - const int8x16_t v0_0l = vreinterpretq_s8_u8(vandq_u8(v0_0, m4b)); - const int8x16_t v0_0h = vreinterpretq_s8_u8(vshrq_n_u8(v0_0, 4)); - const int8x16_t v0_1l = vreinterpretq_s8_u8(vandq_u8(v0_1, m4b)); - const int8x16_t v0_1h = vreinterpretq_s8_u8(vshrq_n_u8(v0_1, 4)); - - // sub 8 - const int8x16_t x0_l = vsubq_s8(v0_0l, s8b); - const int8x16_t x0_h = vsubq_s8(v0_0h, s8b); - const int8x16_t x1_l = vsubq_s8(v0_1l, s8b); - const int8x16_t x1_h = vsubq_s8(v0_1h, s8b); - - // load y - const int8x16_t y0_l = vld1q_s8(b_y0->qs); - const int8x16_t y0_h = vld1q_s8(b_y0->qs + 16); - const int8x16_t y1_l = vld1q_s8(b_y1->qs); - const int8x16_t y1_h = vld1q_s8(b_y1->qs + 16); - - float32_t _scale[4] = { - MLLM_FP16_TO_FP32(b_x0->d) * MLLM_FP16_TO_FP32(b_y0->d), - MLLM_FP16_TO_FP32(b_x0->d) * MLLM_FP16_TO_FP32(b_y1->d), - MLLM_FP16_TO_FP32(b_x1->d) * MLLM_FP16_TO_FP32(b_y0->d), - MLLM_FP16_TO_FP32(b_x1->d) * MLLM_FP16_TO_FP32(b_y1->d)}; - float32x4_t scale = vld1q_f32(_scale); - - int8x16_t l0 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(x0_l), vreinterpretq_s64_s8(x1_l))); - int8x16_t l1 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(x0_l), vreinterpretq_s64_s8(x1_l))); - - int8x16_t l2 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(x0_h), vreinterpretq_s64_s8(x1_h))); - int8x16_t l3 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(x0_h), vreinterpretq_s64_s8(x1_h))); - - int8x16_t r0 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(y0_l), vreinterpretq_s64_s8(y1_l))); - int8x16_t r1 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(y0_l), vreinterpretq_s64_s8(y1_l))); - - int8x16_t r2 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(y0_h), vreinterpretq_s64_s8(y1_h))); - int8x16_t r3 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(y0_h), vreinterpretq_s64_s8(y1_h))); - - sumv0 = vmlaq_f32(sumv0, (vcvtq_f32_s32(vmmlaq_s32((vmmlaq_s32((vmmlaq_s32((vmmlaq_s32(vdupq_n_s32(0), l0, r0)), l1, r1)), l2, r2)), l3, r3))), scale); - } - - float32x4_t sumv1 = vextq_f32(sumv0, sumv0, 2); - float32x4_t sumv2 = vzip1q_f32(sumv0, sumv1); - - vst1_f32(s, vget_low_f32(sumv2)); - vst1_f32(s + bs, vget_high_f32(sumv2)); - - return; - } -#endif - - float32x4_t sumv0 = vdupq_n_f32(0.0F); - float32x4_t sumv1 = vdupq_n_f32(0.0F); - - assert(nb % 2 == 0); // TODO: handle odd nb - for (int i = 0; i < nb; i += 2) { - const block_q4_0 *__restrict x0 = &x[i + 0]; - const block_q4_0 *__restrict x1 = &x[i + 1]; - const block_q8_0 *__restrict y0 = &y[i + 0]; - const block_q8_0 *__restrict y1 = &y[i + 1]; - - const uint8x16_t m4b = vdupq_n_u8(0x0F); - const int8x16_t s8b = vdupq_n_s8(0x8); - - const uint8x16_t v0_0 = vld1q_u8(x0->qs); - const uint8x16_t v0_1 = vld1q_u8(x1->qs); - - // 4-bit -> 8-bit - const int8x16_t v0_0l = vreinterpretq_s8_u8(vandq_u8(v0_0, m4b)); - const int8x16_t v0_0h = vreinterpretq_s8_u8(vshrq_n_u8(v0_0, 4)); - const int8x16_t v0_1l = vreinterpretq_s8_u8(vandq_u8(v0_1, m4b)); - const int8x16_t v0_1h = vreinterpretq_s8_u8(vshrq_n_u8(v0_1, 4)); - - // sub 8 - const int8x16_t v0_0ls = vsubq_s8(v0_0l, s8b); - const int8x16_t v0_0hs = vsubq_s8(v0_0h, s8b); - const int8x16_t v0_1ls = vsubq_s8(v0_1l, s8b); - const int8x16_t v0_1hs = vsubq_s8(v0_1h, s8b); - - // load y - const int8x16_t v1_0l = vld1q_s8(y0->qs); - const int8x16_t v1_0h = vld1q_s8(y0->qs + 16); - const int8x16_t v1_1l = vld1q_s8(y1->qs); - const int8x16_t v1_1h = vld1q_s8(y1->qs + 16); - -#if defined(__ARM_FEATURE_DOTPROD) - // dot product into int32x4_t - const int32x4_t p_0 = vdotq_s32(vdotq_s32(vdupq_n_s32(0), v0_0ls, v1_0l), v0_0hs, v1_0h); - const int32x4_t p_1 = vdotq_s32(vdotq_s32(vdupq_n_s32(0), v0_1ls, v1_1l), v0_1hs, v1_1h); - - sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(p_0), MLLM_FP16_TO_FP32(x0->d) * MLLM_FP16_TO_FP32(y0->d)); - sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(p_1), MLLM_FP16_TO_FP32(x1->d) * MLLM_FP16_TO_FP32(y1->d)); -#else - const int16x8_t pl0l = vmull_s8(vget_low_s8(v0_0ls), vget_low_s8(v1_0l)); - const int16x8_t pl0h = vmull_s8(vget_high_s8(v0_0ls), vget_high_s8(v1_0l)); - const int16x8_t ph0l = vmull_s8(vget_low_s8(v0_0hs), vget_low_s8(v1_0h)); - const int16x8_t ph0h = vmull_s8(vget_high_s8(v0_0hs), vget_high_s8(v1_0h)); - - const int16x8_t pl1l = vmull_s8(vget_low_s8(v0_1ls), vget_low_s8(v1_1l)); - const int16x8_t pl1h = vmull_s8(vget_high_s8(v0_1ls), vget_high_s8(v1_1l)); - const int16x8_t ph1l = vmull_s8(vget_low_s8(v0_1hs), vget_low_s8(v1_1h)); - const int16x8_t ph1h = vmull_s8(vget_high_s8(v0_1hs), vget_high_s8(v1_1h)); - - const int32x4_t pl0 = vaddq_s32(vpaddlq_s16(pl0l), vpaddlq_s16(pl0h)); - const int32x4_t ph0 = vaddq_s32(vpaddlq_s16(ph0l), vpaddlq_s16(ph0h)); - const int32x4_t pl1 = vaddq_s32(vpaddlq_s16(pl1l), vpaddlq_s16(pl1h)); - const int32x4_t ph1 = vaddq_s32(vpaddlq_s16(ph1l), vpaddlq_s16(ph1h)); - - sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(pl0, ph0)), MLLM_FP16_TO_FP32(x0->d) * MLLM_FP16_TO_FP32(y0->d)); - sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(pl1, ph1)), MLLM_FP16_TO_FP32(x1->d) * MLLM_FP16_TO_FP32(y1->d)); -#endif - } - - *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1); -} -#endif - -void vec_dot_q4_0_q8_0(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { -#ifdef __AVX2__ - vec_dot_q4_0_q8_0_avx(n, s, vx, vy); -#elif defined(__ARM_NEON) - vec_dot_q4_0_q8_0_arm(n, s, vx, vy); -#endif -} -void vec_dot_q4_0_q8_0(const void *__restrict src0, const void *__restrict src1, Tensor *dst, bool support_bias, Tensor *bias, int hid_len, int batch, int head, int src0_inf, int sec1_outf) { - float value = 0; -#ifdef __AVX2__ - vec_dot_q4_0_q8_0_avx(hid_len, &value, src1, src0); -#elif defined(__ARM_NEON) - vec_dot_q4_0_q8_0_arm(hid_len, &value, src1, src0); -#endif - if (support_bias) { - value += bias->dataAt(0, head, 0, sec1_outf); - } - dst->setDataAt({batch, head, src0_inf, sec1_outf}, value); -} - -#if QK_K == 256 -void vec_dot_q4_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { - assert(n % QK_K == 0); - - const block_q4_K *__restrict x = (block_q4_K *)vx; - const block_q8_K *__restrict y = (block_q8_K *)vy; - - const int nb = n / QK_K; - - static const uint32_t kmask1 = 0x3f3f3f3f; - static const uint32_t kmask2 = 0x0f0f0f0f; - static const uint32_t kmask3 = 0x03030303; - - uint32_t utmp[4]; - -#ifdef __ARM_FEATURE_SVE - float sumf = 0; - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - - const int16x8_t q8sums = vpaddq_s16(vld1q_s16(y[i].bsums), vld1q_s16(y[i].bsums + 8)); - - memcpy(utmp, x[i].scales, K_SCALE_SIZE); - - uint32x2_t mins8 = {0}; - mins8 = vset_lane_u32(utmp[1] & kmask1, mins8, 0); - mins8 = vset_lane_u32(((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4), mins8, 1); - - utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); - utmp[0] &= kmask1; - - const int16x8_t mins = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(mins8))); - const int32x4_t prod = vaddq_s32(vmull_s16(vget_low_s16(q8sums), vget_low_s16(mins)), - vmull_s16(vget_high_s16(q8sums), vget_high_s16(mins))); - sumf -= dmin * vaddvq_s32(prod); - - const uint8_t *scales = (const uint8_t *)utmp; - - const uint8_t *__restrict q4 = (const uint8_t *)x[i].qs; - const int8_t *__restrict q8 = (const int8_t *)y[i].qs; - - const int vector_length = mllm_cpu_get_sve_cnt() * 8; - const svuint8_t m4b = svdup_n_u8(0xf); - const svint32_t mzero = svdup_n_s32(0); - svint32_t sumi1 = svdup_n_s32(0); - svint32_t sumi1_1 = svdup_n_s32(0); - svint32_t sumi1_2 = svdup_n_s32(0); - svint32_t sumi2 = svdup_n_s32(0); - svint32_t sumi2_1 = svdup_n_s32(0); - svint32_t sumi2_2 = svdup_n_s32(0); - switch (vector_length) { - case 128: { - for (int j = 0; j < QK_K / 64; ++j) { - svint8_t q4bytes = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svld1_u8(svptrue_b8(), q4), m4b)); - svint8_t q8bytes = svld1_s8(svptrue_b8(), q8); - q8 += 16; - sumi1_1 = svmla_n_s32_x(svptrue_b32(), sumi1_1, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 0]); - q4bytes = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svld1_u8(svptrue_b8(), q4 + 16), m4b)); - q8bytes = svld1_s8(svptrue_b8(), q8); - q8 += 16; - sumi1_2 = svmla_n_s32_x(svptrue_b32(), sumi1_2, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 0]); - - q4bytes = svreinterpret_s8_u8(svlsr_n_u8_x(svptrue_b8(), svld1_u8(svptrue_b8(), q4), 4)); - q8bytes = svld1_s8(svptrue_b8(), q8); - q8 += 16; - sumi2_1 = svmla_n_s32_x(svptrue_b32(), sumi2_1, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 1]); - q4bytes = svreinterpret_s8_u8(svlsr_n_u8_x(svptrue_b8(), svld1_u8(svptrue_b8(), q4 + 16), 4)); - q8bytes = svld1_s8(svptrue_b8(), q8); - q8 += 16; - sumi2_2 = svmla_n_s32_x(svptrue_b32(), sumi2_2, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 1]); - q4 += 32; - } - sumi1 = svadd_s32_x(svptrue_b32(), sumi1_1, sumi1_2); - sumi2 = svadd_s32_x(svptrue_b32(), sumi2_1, sumi2_2); - sumf += d * (svaddv_s32(svptrue_b32(), svadd_s32_x(svptrue_b32(), sumi1, sumi2))); - } break; - case 256: - case 512: { - for (int j = 0; j < QK_K / 64; ++j) { - const svuint8_t q4bits = svld1_u8(svptrue_pat_b8(SV_VL32), q4); - q4 += 32; - svint8_t q4bytes = svreinterpret_s8_u8(svand_u8_x(svptrue_pat_b8(SV_VL32), q4bits, m4b)); - svint8_t q8bytes = svld1_s8(svptrue_pat_b8(SV_VL32), q8); - q8 += 32; - sumi1 = svmla_n_s32_x(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 0]); - - q4bytes = svreinterpret_s8_u8(svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q4bits, 4)); - q8bytes = svld1_s8(svptrue_pat_b8(SV_VL32), q8); - q8 += 32; - sumi2 = svmla_n_s32_x(svptrue_pat_b32(SV_VL8), sumi2, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 1]); - } - sumf += d * (svaddv_s32(svptrue_pat_b32(SV_VL8), svadd_s32_x(svptrue_pat_b32(SV_VL8), sumi1, sumi2))); - } break; - default: - assert(false && "Unsupported vector length"); - break; - } - } - *s = sumf; -#elif defined __ARM_NEON - - const uint8x16_t m4b = vdupq_n_u8(0xf); -#ifdef __ARM_FEATURE_DOTPROD - const int32x4_t mzero = vdupq_n_s32(0); -#endif - - int8x16x2_t q4bytes; - int8x16x2_t q8bytes; - - float sumf = 0; - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - - const int16x8_t q8sums = vpaddq_s16(vld1q_s16(y[i].bsums), vld1q_s16(y[i].bsums + 8)); - - memcpy(utmp, x[i].scales, 12); - - const uint32x2_t mins8 = {utmp[1] & kmask1, ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4)}; - utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); - utmp[0] &= kmask1; - - const int16x8_t mins = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(mins8))); - const int32x4_t prod = vaddq_s32(vmull_s16(vget_low_s16(q8sums), vget_low_s16(mins)), - vmull_s16(vget_high_s16(q8sums), vget_high_s16(mins))); - sumf -= dmin * vaddvq_s32(prod); - - const uint8_t *scales = (const uint8_t *)utmp; - - const uint8_t *__restrict q4 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - // int32x4_t isum = mzero; - - int32_t sumi1 = 0; - int32_t sumi2 = 0; - - for (int j = 0; j < QK_K / 64; ++j) { - const uint8x16x2_t q4bits = vld1q_u8_x2(q4); - q4 += 32; - -#ifdef __ARM_FEATURE_DOTPROD - q8bytes = vld1q_s8_x2(q8); - q8 += 32; - q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[0], m4b)); - q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[1], m4b)); - - const int32x4_t p1 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[0]), q4bytes.val[1], q8bytes.val[1]); - sumi1 += vaddvq_s32(p1) * scales[2 * j + 0]; - - q8bytes = vld1q_s8_x2(q8); - q8 += 32; - q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); - q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); - - const int32x4_t p2 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[0]), q4bytes.val[1], q8bytes.val[1]); - - sumi2 += vaddvq_s32(p2) * scales[2 * j + 1]; -#else - q8bytes = vld1q_s8_x2(q8); - q8 += 32; - q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[0], m4b)); - q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[1], m4b)); - const int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[0]), vget_low_s8(q8bytes.val[0])), - vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[0]))); - const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[1]), vget_low_s8(q8bytes.val[1])), - vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[1]))); - sumi1 += vaddvq_s16(vaddq_s16(p0, p1)) * scales[2 * j + 0]; - - q8bytes = vld1q_s8_x2(q8); - q8 += 32; - q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); - q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); - const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[0]), vget_low_s8(q8bytes.val[0])), - vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[0]))); - const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[1]), vget_low_s8(q8bytes.val[1])), - vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[1]))); - sumi2 += vaddvq_s16(vaddq_s16(p2, p3)) * scales[2 * j + 1]; - -#endif - } - - sumf += d * (sumi1 + sumi2); - } - - *s = sumf; - -#elif defined __AVX2__ - - const __m256i m4 = _mm256_set1_epi8(0xF); - - __m256 acc = _mm256_setzero_ps(); - __m128 acc_m = _mm_setzero_ps(); - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - - memcpy(utmp, x[i].scales, 12); - utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); - const uint32_t uaux = utmp[1] & kmask1; - utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); - utmp[2] = uaux; - utmp[0] &= kmask1; - - const uint8_t *__restrict q4 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - const __m256i mins_and_scales = _mm256_cvtepu8_epi16(_mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0])); - - const __m256i q8sums = _mm256_loadu_si256((const __m256i *)y[i].bsums); - const __m128i q8s = _mm_hadd_epi16(_mm256_extracti128_si256(q8sums, 0), _mm256_extracti128_si256(q8sums, 1)); - const __m128i prod = _mm_madd_epi16(_mm256_extracti128_si256(mins_and_scales, 1), q8s); - acc_m = _mm_fmadd_ps(_mm_set1_ps(dmin), _mm_cvtepi32_ps(prod), acc_m); - - const __m128i sc128 = _mm256_extracti128_si256(mins_and_scales, 0); - const __m256i scales = MM256_SET_M128I(sc128, sc128); - - __m256i sumi = _mm256_setzero_si256(); - - for (int j = 0; j < QK_K / 64; ++j) { - const __m256i scale_l = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2 * j + 0)); - const __m256i scale_h = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2 * j + 1)); - - const __m256i q4bits = _mm256_loadu_si256((const __m256i *)q4); - q4 += 32; - const __m256i q4l = _mm256_and_si256(q4bits, m4); - const __m256i q4h = _mm256_and_si256(_mm256_srli_epi16(q4bits, 4), m4); - - const __m256i q8l = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - __m256i p16l = _mm256_maddubs_epi16(q4l, q8l); - p16l = _mm256_madd_epi16(scale_l, p16l); - - const __m256i q8h = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - __m256i p16h = _mm256_maddubs_epi16(q4h, q8h); - p16h = _mm256_madd_epi16(scale_h, p16h); - const __m256i sumj = _mm256_add_epi32(p16l, p16h); - - sumi = _mm256_add_epi32(sumi, sumj); - } - - __m256 vd = _mm256_set1_ps(d); - acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(sumi), acc); - } - - acc_m = _mm_add_ps(acc_m, _mm_movehl_ps(acc_m, acc_m)); - acc_m = _mm_add_ss(acc_m, _mm_movehdup_ps(acc_m)); - - *s = hsum_float_8(acc) + _mm_cvtss_f32(acc_m); - -#else - const uint8_t *scales = (const uint8_t *)&utmp[0]; - const uint8_t *mins = (const uint8_t *)&utmp[2]; - - int8_t aux8[QK_K]; - int16_t aux16[8]; - float sums[8]; - int32_t aux32[8]; - memset(sums, 0, 8 * sizeof(float)); - - float sumf = 0; - for (int i = 0; i < nb; ++i) { - const uint8_t *__restrict q4 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - memset(aux32, 0, 8 * sizeof(int32_t)); - int8_t *__restrict a = aux8; - for (int j = 0; j < QK_K / 64; ++j) { - for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] & 0xF); - a += 32; - for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] >> 4); - a += 32; - q4 += 32; - } - memcpy(utmp, x[i].scales, 12); - utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); - const uint32_t uaux = utmp[1] & kmask1; - utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); - utmp[2] = uaux; - utmp[0] &= kmask1; - - int sumi = 0; - for (int j = 0; j < QK_K / 16; ++j) sumi += y[i].bsums[j] * mins[j / 2]; - a = aux8; - int is = 0; - for (int j = 0; j < QK_K / 32; ++j) { - int32_t scale = scales[is++]; - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; - q8 += 8; - a += 8; - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; - q8 += 8; - a += 8; - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; - q8 += 8; - a += 8; - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; - q8 += 8; - a += 8; - } - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; - const float dmin = MLLM_FP16_TO_FP32(x[i].dmin) * y[i].d; - sumf -= dmin * sumi; - } - for (int l = 0; l < 8; ++l) sumf += sums[l]; - *s = sumf; -#endif -} -#else -void vec_dot_q4_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { - assert(n % QK_K == 0); - - const block_q4_K *__restrict x = (block_q4_K *)vx; - const block_q8_K *__restrict y = (block_q8_K *)vy; - - const int nb = n / QK_K; - -#ifdef __ARM_NEON - - const uint8x16_t m4b = vdupq_n_u8(0xf); - -#ifdef __ARM_FEATURE_DOTPROD - const int32x4_t mzero = vdupq_n_s32(0); -#endif - - float sumf = 0; - - int8x16x2_t q4bytes; - int8x16x4_t q8bytes; - - float sum_mins = 0.f; - - uint16_t aux16[2]; - const uint8_t *__restrict scales = (const uint8_t *)aux16; - - for (int i = 0; i < nb; ++i) { - const uint8_t *__restrict q4 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - const uint16_t *__restrict a = (const uint16_t *)x[i].scales; - aux16[0] = a[0] & 0x0f0f; - aux16[1] = (a[0] >> 4) & 0x0f0f; - - const int32_t summi = scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3]); - sum_mins += y[i].d * (float)x[i].d[1] * summi; - - const float d = y[i].d * (float)x[i].d[0]; - - const uint8x16x2_t q4bits = vld1q_u8_x2(q4); - -#ifdef __ARM_FEATURE_DOTPROD - q8bytes = vld1q_s8_x4(q8); - q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[0], m4b)); - q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[1], m4b)); - - const int32x4_t p1 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[0]), q4bytes.val[1], q8bytes.val[1]); - const int32_t sumi1 = vaddvq_s32(p1) * scales[0]; - - q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); - q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); - - const int32x4_t p2 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[2]), q4bytes.val[1], q8bytes.val[3]); - const int32_t sumi2 = vaddvq_s32(p2) * scales[1]; - -#else - q8bytes = vld1q_s8_x4(q8); - q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[0], m4b)); - q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[1], m4b)); - const int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[0]), vget_low_s8(q8bytes.val[0])), - vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[0]))); - const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[1]), vget_low_s8(q8bytes.val[1])), - vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[1]))); - int32_t sumi1 = vaddvq_s16(vaddq_s16(p0, p1)) * scales[0]; - - q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); - q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); - const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[0]), vget_low_s8(q8bytes.val[2])), - vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[2]))); - const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[1]), vget_low_s8(q8bytes.val[3])), - vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[3]))); - int32_t sumi2 = vaddvq_s16(vaddq_s16(p2, p3)) * scales[1]; - -#endif - sumf += d * (sumi1 + sumi2); - } - - *s = sumf - sum_mins; - -#elif defined __AVX2__ - - const __m256i m4 = _mm256_set1_epi8(0xF); - - __m256 acc = _mm256_setzero_ps(); - - float summs = 0; - - uint16_t aux16[2]; - const uint8_t *scales = (const uint8_t *)aux16; - - for (int i = 0; i < nb; ++i) { - const float d = MLLM_FP16_TO_FP32(x[i].d[0]) * y[i].d; - const float m = MLLM_FP16_TO_FP32(x[i].d[1]) * y[i].d; - const __m256 vd = _mm256_set1_ps(d); - - const uint16_t *a = (const uint16_t *)x[i].scales; - aux16[0] = a[0] & 0x0f0f; - aux16[1] = (a[0] >> 4) & 0x0f0f; - - summs += m * (scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3])); - - const uint8_t *__restrict q4 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - const __m256i q4bits = _mm256_loadu_si256((const __m256i *)q4); - const __m256i q4l = _mm256_and_si256(q4bits, m4); - const __m256i q4h = _mm256_and_si256(_mm256_srli_epi16(q4bits, 4), m4); - - const __m256i q8l = _mm256_loadu_si256((const __m256i *)(q8 + 0)); - const __m256i q8h = _mm256_loadu_si256((const __m256i *)(q8 + 32)); - - const __m256i p16l = _mm256_maddubs_epi16(q4l, q8l); - const __m256i p16h = _mm256_maddubs_epi16(q4h, q8h); - - const __m256i p32l = _mm256_madd_epi16(_mm256_set1_epi16(scales[0]), p16l); - acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(p32l), acc); - - const __m256i p32h = _mm256_madd_epi16(_mm256_set1_epi16(scales[1]), p16h); - acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(p32h), acc); - } - - *s = hsum_float_8(acc) - summs; - -#else - - uint8_t aux8[QK_K]; - int16_t aux16[16]; - float sums[8]; - memset(sums, 0, 8 * sizeof(float)); - - uint16_t s16[2]; - const uint8_t *__restrict scales = (const uint8_t *)s16; - - float sumf = 0; - for (int i = 0; i < nb; ++i) { - const uint8_t *__restrict q4 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - uint8_t *__restrict a = aux8; - for (int l = 0; l < 32; ++l) a[l + 0] = q4[l] & 0xF; - for (int l = 0; l < 32; ++l) a[l + 32] = q4[l] >> 4; - - const uint16_t *__restrict b = (const uint16_t *)x[i].scales; - s16[0] = b[0] & 0x0f0f; - s16[1] = (b[0] >> 4) & 0x0f0f; - - sumf -= y[i].d * MLLM_FP16_TO_FP32(x[i].d[1]) * (scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3])); - - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d[0]); - - for (int j = 0; j < QK_K / 32; ++j) { - for (int l = 0; l < 16; ++l) aux16[l] = q8[l] * a[l]; - q8 += 16; - a += 16; - for (int l = 0; l < 16; ++l) aux16[l] += q8[l] * a[l]; - q8 += 16; - a += 16; - const float dl = d * scales[j]; - for (int l = 0; l < 8; ++l) sums[l] += dl * (aux16[l] + aux16[l + 8]); - } - } - for (int l = 0; l < 8; ++l) sumf += sums[l]; - *s = sumf; -#endif -} -#endif - -void vec_dot_q4_K_q8_K(const void *__restrict src0, const void *__restrict src1, Tensor *dst, bool support_bias, Tensor *bias, int hid_len, int batch, int head, int src0_inf, int sec1_outf) { - float value = 0; - vec_dot_q4_K_q8_K(hid_len, dst->ptrAt(batch, head, src0_inf, sec1_outf), src1, src0); - if (support_bias) { - dst->setDataAt({batch, head, src0_inf, sec1_outf}, dst->dataAt(batch, head, src0_inf, sec1_outf) + bias->dataAt(0, head, 0, sec1_outf)); - } -} - -#if QK_K == 256 -void vec_dot_q6_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { - assert(n % QK_K == 0); - - const block_q6_K *__restrict x = (block_q6_K *)vx; - const block_q8_K *__restrict y = (block_q8_K *)vy; - - const int nb = n / QK_K; - -#ifdef __ARM_NEON - - float sum = 0; - - const uint8x16_t m4b = vdupq_n_u8(0xF); -#if defined(__ARM_FEATURE_DOTPROD) - const int32x4_t vzero = vdupq_n_s32(0); -#endif - // const int8x16_t m32s = vdupq_n_s8(32); - - const uint8x16_t mone = vdupq_n_u8(3); - - int8x16x4_t q6bytes; - uint8x16x4_t q6h; - - for (int i = 0; i < nb; ++i) { - const float d_all = MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *__restrict q6 = x[i].ql; - const uint8_t *__restrict qh = x[i].qh; - const int8_t *__restrict q8 = y[i].qs; - - const int8_t *__restrict scale = x[i].scales; - - const int16x8x2_t q8sums = vld1q_s16_x2(y[i].bsums); - const int8x16_t scales = vld1q_s8(scale); - const int16x8x2_t q6scales = {vmovl_s8(vget_low_s8(scales)), vmovl_s8(vget_high_s8(scales))}; - - const int32x4_t prod = vaddq_s32(vaddq_s32(vmull_s16(vget_low_s16(q8sums.val[0]), vget_low_s16(q6scales.val[0])), - vmull_s16(vget_high_s16(q8sums.val[0]), vget_high_s16(q6scales.val[0]))), - vaddq_s32(vmull_s16(vget_low_s16(q8sums.val[1]), vget_low_s16(q6scales.val[1])), - vmull_s16(vget_high_s16(q8sums.val[1]), vget_high_s16(q6scales.val[1])))); - int32_t isum_mins = vaddvq_s32(prod); - - int32_t isum = 0; - - for (int j = 0; j < QK_K / 128; ++j) { - uint8x16x2_t qhbits = vld1q_u8_x2(qh); - qh += 32; - uint8x16x4_t q6bits = vld1q_u8_x4(q6); - q6 += 64; - int8x16x4_t q8bytes = vld1q_s8_x4(q8); - q8 += 64; - - q6h.val[0] = vshlq_n_u8(vandq_u8(mone, qhbits.val[0]), 4); - q6h.val[1] = vshlq_n_u8(vandq_u8(mone, qhbits.val[1]), 4); - uint8x16_t shifted = vshrq_n_u8(qhbits.val[0], 2); - q6h.val[2] = vshlq_n_u8(vandq_u8(mone, shifted), 4); - shifted = vshrq_n_u8(qhbits.val[1], 2); - q6h.val[3] = vshlq_n_u8(vandq_u8(mone, shifted), 4); - - // q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])), m32s); - // q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])), m32s); - // q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[2], m4b), q6h.val[2])), m32s); - // q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[3], m4b), q6h.val[3])), m32s); - q6bytes.val[0] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])); - q6bytes.val[1] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])); - q6bytes.val[2] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[2], m4b), q6h.val[2])); - q6bytes.val[3] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[3], m4b), q6h.val[3])); - -#if defined(__ARM_FEATURE_DOTPROD) - - isum += vaddvq_s32(vdotq_s32(vzero, q6bytes.val[0], q8bytes.val[0])) * scale[0] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[1], q8bytes.val[1])) * scale[1] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[2], q8bytes.val[2])) * scale[2] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[3], q8bytes.val[3])) * scale[3]; - scale += 4; - -#else - - int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[0]), vget_low_s8(q8bytes.val[0])), - vmull_s8(vget_high_s8(q6bytes.val[0]), vget_high_s8(q8bytes.val[0]))); - int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[1]), vget_low_s8(q8bytes.val[1])), - vmull_s8(vget_high_s8(q6bytes.val[1]), vget_high_s8(q8bytes.val[1]))); - isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1]; - scale += 2; - - int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[2]), vget_low_s8(q8bytes.val[2])), - vmull_s8(vget_high_s8(q6bytes.val[2]), vget_high_s8(q8bytes.val[2]))); - int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[3]), vget_low_s8(q8bytes.val[3])), - vmull_s8(vget_high_s8(q6bytes.val[3]), vget_high_s8(q8bytes.val[3]))); - isum += vaddvq_s16(p2) * scale[0] + vaddvq_s16(p3) * scale[1]; - scale += 2; -#endif - - q8bytes = vld1q_s8_x4(q8); - q8 += 64; - - shifted = vshrq_n_u8(qhbits.val[0], 4); - q6h.val[0] = vshlq_n_u8(vandq_u8(mone, shifted), 4); - shifted = vshrq_n_u8(qhbits.val[1], 4); - q6h.val[1] = vshlq_n_u8(vandq_u8(mone, shifted), 4); - shifted = vshrq_n_u8(qhbits.val[0], 6); - q6h.val[2] = vshlq_n_u8(vandq_u8(mone, shifted), 4); - shifted = vshrq_n_u8(qhbits.val[1], 6); - q6h.val[3] = vshlq_n_u8(vandq_u8(mone, shifted), 4); - - // q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[0])), m32s); - // q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[1])), m32s); - // q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[2], 4), q6h.val[2])), m32s); - // q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[3], 4), q6h.val[3])), m32s); - q6bytes.val[0] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[0])); - q6bytes.val[1] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[1])); - q6bytes.val[2] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[2], 4), q6h.val[2])); - q6bytes.val[3] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[3], 4), q6h.val[3])); - -#if defined(__ARM_FEATURE_DOTPROD) - - isum += vaddvq_s32(vdotq_s32(vzero, q6bytes.val[0], q8bytes.val[0])) * scale[0] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[1], q8bytes.val[1])) * scale[1] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[2], q8bytes.val[2])) * scale[2] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[3], q8bytes.val[3])) * scale[3]; - scale += 4; - - // for (int l = 0; l < 4; ++l) { - // const int32x4_t p = vdotq_s32(vzero, q6bytes.val[l], q8bytes.val[l]); - // isum += vaddvq_s32(p) * *scale++; - // } -#else - p0 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[0]), vget_low_s8(q8bytes.val[0])), - vmull_s8(vget_high_s8(q6bytes.val[0]), vget_high_s8(q8bytes.val[0]))); - p1 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[1]), vget_low_s8(q8bytes.val[1])), - vmull_s8(vget_high_s8(q6bytes.val[1]), vget_high_s8(q8bytes.val[1]))); - isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1]; - scale += 2; - - p2 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[2]), vget_low_s8(q8bytes.val[2])), - vmull_s8(vget_high_s8(q6bytes.val[2]), vget_high_s8(q8bytes.val[2]))); - p3 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[3]), vget_low_s8(q8bytes.val[3])), - vmull_s8(vget_high_s8(q6bytes.val[3]), vget_high_s8(q8bytes.val[3]))); - isum += vaddvq_s16(p2) * scale[0] + vaddvq_s16(p3) * scale[1]; - scale += 2; -#endif - } - // sum += isum * d_all * y[i].d; - sum += d_all * y[i].d * (isum - 32 * isum_mins); - } - *s = sum; - -#elif defined __AVX2__ - - const __m256i m4 = _mm256_set1_epi8(0xF); - const __m256i m2 = _mm256_set1_epi8(3); - const __m256i m32s = _mm256_set1_epi8(32); - - __m256 acc = _mm256_setzero_ps(); - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *__restrict q4 = x[i].ql; - const uint8_t *__restrict qh = x[i].qh; - const int8_t *__restrict q8 = y[i].qs; - - const __m128i scales = _mm_loadu_si128((const __m128i *)x[i].scales); - - __m256i sumi = _mm256_setzero_si256(); - - int is = 0; - - for (int j = 0; j < QK_K / 128; ++j) { - const __m128i scale_0 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 0)); - const __m128i scale_1 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 1)); - const __m128i scale_2 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 2)); - const __m128i scale_3 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 3)); - is += 4; - - const __m256i q4bits1 = _mm256_loadu_si256((const __m256i *)q4); - q4 += 32; - const __m256i q4bits2 = _mm256_loadu_si256((const __m256i *)q4); - q4 += 32; - const __m256i q4bitsH = _mm256_loadu_si256((const __m256i *)qh); - qh += 32; - - const __m256i q4h_0 = _mm256_slli_epi16(_mm256_and_si256(q4bitsH, m2), 4); - const __m256i q4h_1 = _mm256_slli_epi16(_mm256_and_si256(_mm256_srli_epi16(q4bitsH, 2), m2), 4); - const __m256i q4h_2 = _mm256_slli_epi16(_mm256_and_si256(_mm256_srli_epi16(q4bitsH, 4), m2), 4); - const __m256i q4h_3 = _mm256_slli_epi16(_mm256_and_si256(_mm256_srli_epi16(q4bitsH, 6), m2), 4); - - const __m256i q4_0 = _mm256_or_si256(_mm256_and_si256(q4bits1, m4), q4h_0); - const __m256i q4_1 = _mm256_or_si256(_mm256_and_si256(q4bits2, m4), q4h_1); - const __m256i q4_2 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits1, 4), m4), q4h_2); - const __m256i q4_3 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits2, 4), m4), q4h_3); - - const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_3 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - - __m256i q8s_0 = _mm256_maddubs_epi16(m32s, q8_0); - __m256i q8s_1 = _mm256_maddubs_epi16(m32s, q8_1); - __m256i q8s_2 = _mm256_maddubs_epi16(m32s, q8_2); - __m256i q8s_3 = _mm256_maddubs_epi16(m32s, q8_3); - - __m256i p16_0 = _mm256_maddubs_epi16(q4_0, q8_0); - __m256i p16_1 = _mm256_maddubs_epi16(q4_1, q8_1); - __m256i p16_2 = _mm256_maddubs_epi16(q4_2, q8_2); - __m256i p16_3 = _mm256_maddubs_epi16(q4_3, q8_3); - - p16_0 = _mm256_sub_epi16(p16_0, q8s_0); - p16_1 = _mm256_sub_epi16(p16_1, q8s_1); - p16_2 = _mm256_sub_epi16(p16_2, q8s_2); - p16_3 = _mm256_sub_epi16(p16_3, q8s_3); - - p16_0 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_0), p16_0); - p16_1 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_1), p16_1); - p16_2 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_2), p16_2); - p16_3 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_3), p16_3); - - sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_1)); - sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_2, p16_3)); - } - - acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); - } - -#if defined(_MSC_VER) || defined(__MINGW32__) - float arr[8]; - _mm256_storeu_ps(arr, acc); - - // for(float i : arr) { - // printf("%f ", i); - // } - // printf("\n"); -#endif - - *s = hsum_float_8(acc); - -#elif defined __AVX__ - const __m128i m4 = _mm_set1_epi8(0xF); - const __m128i m3 = _mm_set1_epi8(3); - const __m128i m32s = _mm_set1_epi8(32); - const __m128i m2 = _mm_set1_epi8(2); - - __m256 acc = _mm256_setzero_ps(); - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *__restrict q4 = x[i].ql; - const uint8_t *__restrict qh = x[i].qh; - const int8_t *__restrict q8 = y[i].qs; - - const __m128i scales = _mm_loadu_si128((const __m128i *)x[i].scales); - - __m128i sumi_0 = _mm_setzero_si128(); - __m128i sumi_1 = _mm_setzero_si128(); - - __m128i shuffle = _mm_set_epi64x(0x0101010101010101, 0x0000000000000000); - for (int j = 0; j < QK_K / 128; ++j) { - const __m128i q4bitsH_0 = _mm_loadu_si128((const __m128i *)qh); - qh += 16; - const __m128i q4bitsH_1 = _mm_loadu_si128((const __m128i *)qh); - qh += 16; - - const __m128i q4h_0 = _mm_slli_epi16(_mm_and_si128(q4bitsH_0, m3), 4); - const __m128i q4h_1 = _mm_slli_epi16(_mm_and_si128(q4bitsH_1, m3), 4); - const __m128i q4h_2 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_0, 2), m3), 4); - const __m128i q4h_3 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_1, 2), m3), 4); - const __m128i q4h_4 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_0, 4), m3), 4); - const __m128i q4h_5 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_1, 4), m3), 4); - const __m128i q4h_6 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_0, 6), m3), 4); - const __m128i q4h_7 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_1, 6), m3), 4); - - const __m128i q4bits1_0 = _mm_loadu_si128((const __m128i *)q4); - q4 += 16; - const __m128i q4bits1_1 = _mm_loadu_si128((const __m128i *)q4); - q4 += 16; - const __m128i q4bits2_0 = _mm_loadu_si128((const __m128i *)q4); - q4 += 16; - const __m128i q4bits2_1 = _mm_loadu_si128((const __m128i *)q4); - q4 += 16; - - const __m128i q4_0 = _mm_or_si128(_mm_and_si128(q4bits1_0, m4), q4h_0); - const __m128i q4_1 = _mm_or_si128(_mm_and_si128(q4bits1_1, m4), q4h_1); - const __m128i q4_2 = _mm_or_si128(_mm_and_si128(q4bits2_0, m4), q4h_2); - const __m128i q4_3 = _mm_or_si128(_mm_and_si128(q4bits2_1, m4), q4h_3); - const __m128i q4_4 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits1_0, 4), m4), q4h_4); - const __m128i q4_5 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits1_1, 4), m4), q4h_5); - const __m128i q4_6 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits2_0, 4), m4), q4h_6); - const __m128i q4_7 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits2_1, 4), m4), q4h_7); - - const __m128i q8_0 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_1 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_2 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_3 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_4 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_5 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_6 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_7 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - - __m128i q8s_0 = _mm_maddubs_epi16(m32s, q8_0); - __m128i q8s_1 = _mm_maddubs_epi16(m32s, q8_1); - __m128i q8s_2 = _mm_maddubs_epi16(m32s, q8_2); - __m128i q8s_3 = _mm_maddubs_epi16(m32s, q8_3); - __m128i q8s_4 = _mm_maddubs_epi16(m32s, q8_4); - __m128i q8s_5 = _mm_maddubs_epi16(m32s, q8_5); - __m128i q8s_6 = _mm_maddubs_epi16(m32s, q8_6); - __m128i q8s_7 = _mm_maddubs_epi16(m32s, q8_7); - - __m128i p16_0 = _mm_maddubs_epi16(q4_0, q8_0); - __m128i p16_1 = _mm_maddubs_epi16(q4_1, q8_1); - __m128i p16_2 = _mm_maddubs_epi16(q4_2, q8_2); - __m128i p16_3 = _mm_maddubs_epi16(q4_3, q8_3); - __m128i p16_4 = _mm_maddubs_epi16(q4_4, q8_4); - __m128i p16_5 = _mm_maddubs_epi16(q4_5, q8_5); - __m128i p16_6 = _mm_maddubs_epi16(q4_6, q8_6); - __m128i p16_7 = _mm_maddubs_epi16(q4_7, q8_7); - - p16_0 = _mm_sub_epi16(p16_0, q8s_0); - p16_1 = _mm_sub_epi16(p16_1, q8s_1); - p16_2 = _mm_sub_epi16(p16_2, q8s_2); - p16_3 = _mm_sub_epi16(p16_3, q8s_3); - p16_4 = _mm_sub_epi16(p16_4, q8s_4); - p16_5 = _mm_sub_epi16(p16_5, q8s_5); - p16_6 = _mm_sub_epi16(p16_6, q8s_6); - p16_7 = _mm_sub_epi16(p16_7, q8s_7); - - const __m128i scale_0 = _mm_shuffle_epi8(scales, shuffle); - shuffle = _mm_add_epi8(shuffle, m2); - const __m128i scale_1 = _mm_shuffle_epi8(scales, shuffle); - shuffle = _mm_add_epi8(shuffle, m2); - const __m128i scale_2 = _mm_shuffle_epi8(scales, shuffle); - shuffle = _mm_add_epi8(shuffle, m2); - const __m128i scale_3 = _mm_shuffle_epi8(scales, shuffle); - shuffle = _mm_add_epi8(shuffle, m2); - - p16_0 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_0), p16_0); - p16_1 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_0, scale_0)), p16_1); - p16_2 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_1), p16_2); - p16_3 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_1, scale_1)), p16_3); - p16_4 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_2), p16_4); - p16_5 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_2, scale_2)), p16_5); - p16_6 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_3), p16_6); - p16_7 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_3, scale_3)), p16_7); - - sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); - sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_1, p16_3)); - sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_4, p16_6)); - sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_5, p16_7)); - } - - __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); - acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi)), acc); - } - - *s = hsum_float_8(acc); - -#else - - int8_t aux8[QK_K]; - int16_t aux16[8]; - float sums[8]; - int32_t aux32[8]; - memset(sums, 0, 8 * sizeof(float)); - - float sumf = 0; - for (int i = 0; i < nb; ++i) { - const uint8_t *__restrict q4 = x[i].ql; - const uint8_t *__restrict qh = x[i].qh; - const int8_t *__restrict q8 = y[i].qs; - memset(aux32, 0, 8 * sizeof(int32_t)); - int8_t *__restrict a = aux8; - for (int j = 0; j < QK_K; j += 128) { - for (int l = 0; l < 32; ++l) { - a[l + 0] = (int8_t)((q4[l + 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32; - a[l + 32] = (int8_t)((q4[l + 32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32; - a[l + 64] = (int8_t)((q4[l + 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32; - a[l + 96] = (int8_t)((q4[l + 32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32; - } - a += 128; - q4 += 64; - qh += 32; - } - a = aux8; - int is = 0; - for (int j = 0; j < QK_K / 16; ++j) { - int scale = x[i].scales[is++]; - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; - q8 += 8; - a += 8; - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; - q8 += 8; - a += 8; - } - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; - } - for (int l = 0; l < 8; ++l) sumf += sums[l]; - *s = sumf; -#endif -} - -#else - -void vec_dot_q6_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { - assert(n % QK_K == 0); - - const block_q6_K *__restrict x = vx; - const block_q8_K *__restrict y = vy; - - const int nb = n / QK_K; - -#ifdef __ARM_NEON - - float sum = 0; - - const uint8x16_t m4b = vdupq_n_u8(0xF); - const int8x16_t m32s = vdupq_n_s8(32); -#if defined(__ARM_FEATURE_DOTPROD) - const int32x4_t vzero = vdupq_n_s32(0); -#endif - - const uint8x16_t mone = vdupq_n_u8(3); - - int8x16x4_t q6bytes; - uint8x16x4_t q6h; - - for (int i = 0; i < nb; ++i) { - const float d_all = (float)x[i].d; - - const uint8_t *__restrict q6 = x[i].ql; - const uint8_t *__restrict qh = x[i].qh; - const int8_t *__restrict q8 = y[i].qs; - - const int8_t *__restrict scale = x[i].scales; - - int32_t isum = 0; - - uint8x16_t qhbits = vld1q_u8(qh); - uint8x16x2_t q6bits = vld1q_u8_x2(q6); - int8x16x4_t q8bytes = vld1q_s8_x4(q8); - - q6h.val[0] = vshlq_n_u8(vandq_u8(mone, qhbits), 4); - uint8x16_t shifted = vshrq_n_u8(qhbits, 2); - q6h.val[1] = vshlq_n_u8(vandq_u8(mone, shifted), 4); - shifted = vshrq_n_u8(qhbits, 4); - q6h.val[2] = vshlq_n_u8(vandq_u8(mone, shifted), 4); - shifted = vshrq_n_u8(qhbits, 6); - q6h.val[3] = vshlq_n_u8(vandq_u8(mone, shifted), 4); - - q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])), m32s); - q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])), m32s); - q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[2])), m32s); - q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[3])), m32s); - -#if defined(__ARM_FEATURE_DOTPROD) - - isum += vaddvq_s32(vdotq_s32(vzero, q6bytes.val[0], q8bytes.val[0])) * scale[0] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[1], q8bytes.val[1])) * scale[1] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[2], q8bytes.val[2])) * scale[2] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[3], q8bytes.val[3])) * scale[3]; -#else - - int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[0]), vget_low_s8(q8bytes.val[0])), - vmull_s8(vget_high_s8(q6bytes.val[0]), vget_high_s8(q8bytes.val[0]))); - int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[1]), vget_low_s8(q8bytes.val[1])), - vmull_s8(vget_high_s8(q6bytes.val[1]), vget_high_s8(q8bytes.val[1]))); - isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1]; - - int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[2]), vget_low_s8(q8bytes.val[2])), - vmull_s8(vget_high_s8(q6bytes.val[2]), vget_high_s8(q8bytes.val[2]))); - int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[3]), vget_low_s8(q8bytes.val[3])), - vmull_s8(vget_high_s8(q6bytes.val[3]), vget_high_s8(q8bytes.val[3]))); - isum += vaddvq_s16(p2) * scale[2] + vaddvq_s16(p3) * scale[3]; -#endif - - sum += isum * d_all * y[i].d; - } - *s = sum; - -#elif defined __AVX2__ - - const __m256i m4 = _mm256_set1_epi8(0xF); - const __m256i m2 = _mm256_set1_epi8(3); - const __m256i m32s = _mm256_set1_epi8(32); - - __m256 acc = _mm256_setzero_ps(); - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *__restrict q4 = x[i].ql; - const uint8_t *__restrict qh = x[i].qh; - const int8_t *__restrict q8 = y[i].qs; - - const __m64 scales_1 = _mm_set1_pi8(x[i].scales[0]); - const __m64 scales_2 = _mm_set1_pi8(x[i].scales[1]); - const __m64 scales_3 = _mm_set1_pi8(x[i].scales[2]); - const __m64 scales_4 = _mm_set1_pi8(x[i].scales[3]); - - __m256i sumi = _mm256_setzero_si256(); - - const __m128i scale_0 = _mm_set_epi64(scales_2, scales_1); - const __m128i scale_1 = _mm_set_epi64(scales_4, scales_3); - - const __m256i q4bits1 = _mm256_loadu_si256((const __m256i *)q4); - const __m128i q4bitsH = _mm_loadu_si128((const __m128i *)qh); - - const __m256i q4h_0 = _mm256_slli_epi16(_mm256_and_si256(MM256_SET_M128I(_mm_srli_epi16(q4bitsH, 2), q4bitsH), m2), 4); - const __m256i q4h_1 = _mm256_slli_epi16(_mm256_and_si256(MM256_SET_M128I(_mm_srli_epi16(q4bitsH, 6), _mm_srli_epi16(q4bitsH, 4)), m2), 4); - - const __m256i q4_0 = _mm256_or_si256(_mm256_and_si256(q4bits1, m4), q4h_0); - const __m256i q4_1 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits1, 4), m4), q4h_1); - - const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)(q8 + 0)); - const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)(q8 + 32)); - - __m256i q8s_0 = _mm256_maddubs_epi16(m32s, q8_0); - __m256i q8s_1 = _mm256_maddubs_epi16(m32s, q8_1); - - __m256i p16_0 = _mm256_maddubs_epi16(q4_0, q8_0); - __m256i p16_1 = _mm256_maddubs_epi16(q4_1, q8_1); - - p16_0 = _mm256_sub_epi16(p16_0, q8s_0); - p16_1 = _mm256_sub_epi16(p16_1, q8s_1); - - p16_0 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_0), p16_0); - p16_1 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_1), p16_1); - - sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_1)); - - acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); - } - - *s = hsum_float_8(acc); - -#elif defined __AVX__ - - const __m128i m4 = _mm_set1_epi8(0xF); - const __m128i m2 = _mm_set1_epi8(3); - const __m128i m32s = _mm_set1_epi8(32); - - __m256 acc = _mm256_setzero_ps(); - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *__restrict q4 = x[i].ql; - const uint8_t *__restrict qh = x[i].qh; - const int8_t *__restrict q8 = y[i].qs; - - const __m64 scales_1 = _mm_set1_pi8(x[i].scales[0]); - const __m64 scales_2 = _mm_set1_pi8(x[i].scales[1]); - const __m64 scales_3 = _mm_set1_pi8(x[i].scales[2]); - const __m64 scales_4 = _mm_set1_pi8(x[i].scales[3]); - - __m128i sumi_0 = _mm_setzero_si128(); - __m128i sumi_1 = _mm_setzero_si128(); - - const __m128i scale_0 = _mm_set_epi64(scales_2, scales_1); - const __m128i scale_1 = _mm_set_epi64(scales_4, scales_3); - - const __m256i q4bits1 = _mm256_loadu_si256((const __m256i *)q4); - const __m128i q4bitsH = _mm_loadu_si128((const __m128i *)qh); - - const __m128i q4h_0 = _mm_slli_epi16(_mm_and_si128(q4bitsH, m2), 4); - const __m128i q4h_1 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH, 2), m2), 4); - const __m128i q4h_2 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH, 4), m2), 4); - const __m128i q4h_3 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH, 6), m2), 4); - - const __m128i q4_0 = _mm_or_si128(_mm_and_si128(_mm256_extractf128_si256(q4bits1, 0), m4), q4h_0); - const __m128i q4_1 = _mm_or_si128(_mm_and_si128(_mm256_extractf128_si256(q4bits1, 1), m4), q4h_1); - const __m128i q4_2 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(_mm256_extractf128_si256(q4bits1, 0), 4), m4), q4h_2); - const __m128i q4_3 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(_mm256_extractf128_si256(q4bits1, 1), 4), m4), q4h_3); - - const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)(q8 + 0)); - const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)(q8 + 32)); - - __m128i q8s_0 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_0, 0)); - __m128i q8s_1 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_0, 1)); - __m128i q8s_2 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_1, 0)); - __m128i q8s_3 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_1, 1)); - - __m128i p16_0 = _mm_maddubs_epi16(q4_0, _mm256_extractf128_si256(q8_0, 0)); - __m128i p16_1 = _mm_maddubs_epi16(q4_1, _mm256_extractf128_si256(q8_0, 1)); - __m128i p16_2 = _mm_maddubs_epi16(q4_2, _mm256_extractf128_si256(q8_1, 0)); - __m128i p16_3 = _mm_maddubs_epi16(q4_3, _mm256_extractf128_si256(q8_1, 1)); - - p16_0 = _mm_sub_epi16(p16_0, q8s_0); - p16_1 = _mm_sub_epi16(p16_1, q8s_1); - p16_2 = _mm_sub_epi16(p16_2, q8s_2); - p16_3 = _mm_sub_epi16(p16_3, q8s_3); - - p16_0 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_0), p16_0); - p16_1 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_0, scale_0)), p16_1); - p16_2 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_1), p16_2); - p16_3 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_1, scale_1)), p16_3); - - sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); - sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_1, p16_3)); - - acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(MM256_SET_M128I(sumi_1, sumi_0))), acc); - } - - *s = hsum_float_8(acc); - -#else - - int8_t aux8[QK_K]; - int16_t aux16[8]; - float sums[8]; - int32_t aux32[8]; - memset(sums, 0, 8 * sizeof(float)); - - float sumf = 0; - for (int i = 0; i < nb; ++i) { - const uint8_t *__restrict q4 = x[i].ql; - const uint8_t *__restrict qh = x[i].qh; - const int8_t *__restrict q8 = y[i].qs; - memset(aux32, 0, 8 * sizeof(int32_t)); - int8_t *__restrict a = aux8; - for (int l = 0; l < 16; ++l) { - a[l + 0] = (int8_t)((q4[l + 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32; - a[l + 16] = (int8_t)((q4[l + 16] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32; - a[l + 32] = (int8_t)((q4[l + 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32; - a[l + 48] = (int8_t)((q4[l + 16] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32; - } - int is = 0; - for (int j = 0; j < QK_K / 16; ++j) { - int scale = x[i].scales[is++]; - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; - q8 += 8; - a += 8; - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; - q8 += 8; - a += 8; - } - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; - } - for (int l = 0; l < 8; ++l) sumf += sums[l]; - *s = sumf; -#endif -} -#endif - -void vec_dot_q6_K_q8_K(const void *__restrict src0, const void *__restrict src1, Tensor *dst, bool support_bias, Tensor *bias, int hid_len, int batch, int head, int src0_inf, int sec1_outf) { - float value = 0; - - vec_dot_q6_K_q8_K(hid_len, &value, src1, src0); - - if (support_bias) { - value += bias->dataAt(0, head, 0, sec1_outf); - } - dst->setDataAt({batch, head, src0_inf, sec1_outf}, value); -} - -void vec_dot_q8_0_q8_0(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy, size_t bs, size_t bx, size_t by) { - const int qk = QK8_0; - const int nb = n / qk; // number of blocks - - assert(n % qk == 0); - - const auto *__restrict x = static_cast(vx); - const auto *__restrict y = static_cast(vy); - -#if defined(__ARM_FEATURE_MATMUL_INT8) - // if (nrc == 2) - { - const block_q8_0 *__restrict vx0 = (const block_q8_0 *)vx; - const block_q8_0 *__restrict vx1 = (const block_q8_0 *)((const uint8_t *)vx + bx); - const block_q8_0 *__restrict vy0 = (const block_q8_0 *)vy; - const block_q8_0 *__restrict vy1 = (const block_q8_0 *)((const uint8_t *)vy + by); - - float32x4_t sumv0 = vdupq_n_f32(0.0f); - - for (int i = 0; i < nb; i++) { - const block_q8_0 *__restrict b_x0 = &vx0[i]; - const block_q8_0 *__restrict b_y0 = &vy0[i]; - - const block_q8_0 *__restrict b_x1 = &vx1[i]; - const block_q8_0 *__restrict b_y1 = &vy1[i]; - - const int8x16_t x0_l = vld1q_s8(b_x0->qs); - const int8x16_t x0_h = vld1q_s8(b_x0->qs + 16); - const int8x16_t x1_l = vld1q_s8(b_x1->qs); - const int8x16_t x1_h = vld1q_s8(b_x1->qs + 16); - - // load y - const int8x16_t y0_l = vld1q_s8(b_y0->qs); - const int8x16_t y0_h = vld1q_s8(b_y0->qs + 16); - const int8x16_t y1_l = vld1q_s8(b_y1->qs); - const int8x16_t y1_h = vld1q_s8(b_y1->qs + 16); - - float32_t _scale[4] = { - MLLM_FP16_TO_FP32(b_x0->d) * MLLM_FP16_TO_FP32(b_y0->d), - MLLM_FP16_TO_FP32(b_x0->d) * MLLM_FP16_TO_FP32(b_y1->d), - MLLM_FP16_TO_FP32(b_x1->d) * MLLM_FP16_TO_FP32(b_y0->d), - MLLM_FP16_TO_FP32(b_x1->d) * MLLM_FP16_TO_FP32(b_y1->d)}; - float32x4_t scale = vld1q_f32(_scale); - - int8x16_t l0 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(x0_l), vreinterpretq_s64_s8(x1_l))); - int8x16_t l1 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(x0_l), vreinterpretq_s64_s8(x1_l))); - - int8x16_t l2 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(x0_h), vreinterpretq_s64_s8(x1_h))); - int8x16_t l3 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(x0_h), vreinterpretq_s64_s8(x1_h))); - - int8x16_t r0 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(y0_l), vreinterpretq_s64_s8(y1_l))); - int8x16_t r1 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(y0_l), vreinterpretq_s64_s8(y1_l))); - - int8x16_t r2 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(y0_h), vreinterpretq_s64_s8(y1_h))); - int8x16_t r3 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(y0_h), vreinterpretq_s64_s8(y1_h))); - - sumv0 = vmlaq_f32(sumv0, (vcvtq_f32_s32(vmmlaq_s32((vmmlaq_s32((vmmlaq_s32((vmmlaq_s32(vdupq_n_s32(0), l0, r0)), l1, r1)), l2, r2)), l3, r3))), scale); - } - - float32x4_t sumv1 = vextq_f32(sumv0, sumv0, 2); - float32x4_t sumv2 = vzip1q_f32(sumv0, sumv1); - - vst1_f32(s, vget_low_f32(sumv2)); - vst1_f32(s + bs, vget_high_f32(sumv2)); - - return; - } -#elif defined(__ARM_NEON) - float32x4_t sumv0 = vdupq_n_f32(0.0f); - float32x4_t sumv1 = vdupq_n_f32(0.0f); - - assert(nb % 2 == 0); // TODO: handle odd nb - - for (int i = 0; i < nb; i += 2) { - const block_q8_0 *x0 = &x[i + 0]; - const block_q8_0 *x1 = &x[i + 1]; - const block_q8_0 *y0 = &y[i + 0]; - const block_q8_0 *y1 = &y[i + 1]; - - const int8x16_t x0_0 = vld1q_s8(x0->qs); - const int8x16_t x0_1 = vld1q_s8(x0->qs + 16); - const int8x16_t x1_0 = vld1q_s8(x1->qs); - const int8x16_t x1_1 = vld1q_s8(x1->qs + 16); - - // load y - const int8x16_t y0_0 = vld1q_s8(y0->qs); - const int8x16_t y0_1 = vld1q_s8(y0->qs + 16); - const int8x16_t y1_0 = vld1q_s8(y1->qs); - const int8x16_t y1_1 = vld1q_s8(y1->qs + 16); - - sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(mllm_vdotq_s32(vdupq_n_s32(0), x0_0, y0_0), mllm_vdotq_s32(vdupq_n_s32(0), x0_1, y0_1))), MLLM_FP16_TO_FP32(x0->d) * MLLM_FP16_TO_FP32(y0->d)); - - sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(mllm_vdotq_s32(vdupq_n_s32(0), x1_0, y1_0), mllm_vdotq_s32(vdupq_n_s32(0), x1_1, y1_1))), MLLM_FP16_TO_FP32(x1->d) * MLLM_FP16_TO_FP32(y1->d)); - } - - *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1); -#elif defined(__AVX2__) || defined(__AVX__) - // Initialize accumulator with zeros - __m256 acc = _mm256_setzero_ps(); - - // Main loop - for (int i = 0; i < nb; ++i) { - // Compute combined scale for the block - const __m256 d = _mm256_set1_ps(MLLM_FP16_TO_FP32(x[i].d) * MLLM_FP16_TO_FP32(y[i].d)); - __m256i bx = _mm256_loadu_si256((const __m256i *)x[i].qs); - __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); - - const __m256 q = mul_sum_i8_pairs_float(bx, by); - - // Multiply q with scale and accumulate -#if defined(__AVX2__) - acc = _mm256_fmadd_ps(d, q, acc); -#else - acc = _mm256_add_ps(_mm256_mul_ps(d, q), acc); -#endif - } - - *s = hsum_float_8(acc); -#endif -} - -void vec_dot_i8_i8(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy, float scale1, float scale2) { - const int qk = QK8_0; - const int nb = n / qk; - - const float scale = scale1 * scale2; - - assert(n % qk == 0); - - const block_q8_per_tensor *__restrict x = (block_q8_per_tensor *)vx; - const block_q8_per_tensor *__restrict y = (block_q8_per_tensor *)vy; - -#if defined(__ARM_NEON) - float32x4_t sumv0 = vdupq_n_f32(0.0f); - float32x4_t sumv1 = vdupq_n_f32(0.0f); - - assert(nb % 2 == 0); // TODO: handle odd nb - - for (int i = 0; i < nb; i += 2) { - const block_q8_per_tensor *__restrict x0 = &x[i + 0]; - const block_q8_per_tensor *__restrict x1 = &x[i + 1]; - const block_q8_per_tensor *__restrict y0 = &y[i + 0]; - const block_q8_per_tensor *__restrict y1 = &y[i + 1]; - - const int8x16_t x0_0 = vld1q_s8(x0->qs); - const int8x16_t x0_1 = vld1q_s8(x0->qs + 16); - const int8x16_t x1_0 = vld1q_s8(x1->qs); - const int8x16_t x1_1 = vld1q_s8(x1->qs + 16); - - // load y - const int8x16_t y0_0 = vld1q_s8(y0->qs); - const int8x16_t y0_1 = vld1q_s8(y0->qs + 16); - const int8x16_t y1_0 = vld1q_s8(y1->qs); - const int8x16_t y1_1 = vld1q_s8(y1->qs + 16); - - sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(mllm_vdotq_s32(vdupq_n_s32(0), x0_0, y0_0), mllm_vdotq_s32(vdupq_n_s32(0), x0_1, y0_1))), scale); - - sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(mllm_vdotq_s32(vdupq_n_s32(0), x1_0, y1_0), mllm_vdotq_s32(vdupq_n_s32(0), x1_1, y1_1))), scale); - } - - *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1); -#elif defined(__AVX2__) || defined(__AVX__) - // Initialize accumulator with zeros - __m256 acc = _mm256_setzero_ps(); - - // Main loop - for (int i = 0; i < nb; ++i) { - // Compute combined scale for the block - const __m256 d = _mm256_set1_ps(scale); - __m256i qx = _mm256_loadu_si256((const __m256i *)x[i].qs); - __m256i qy = _mm256_loadu_si256((const __m256i *)y[i].qs); - - const __m256 q = mul_sum_i8_pairs_float(qx, qy); - - // Multiply q with scale and accumulate -#if defined(__AVX2__) - acc = _mm256_fmadd_ps(d, q, acc); -#else - acc = _mm256_add_ps(_mm256_mul_ps(d, q), acc); -#endif - } - - *s = hsum_float_8(acc); -#else - // scalar - float sumf = 0.0; - - for (int i = 0; i < nb; i++) { - int sumi = 0; - - for (int j = 0; j < qk; j++) { - sumi += x[i].qs[j] * y[i].qs[j]; - } - - sumf += sumi * scale; - } - - *s = sumf; -#endif -} - -#ifdef __AVX2__ -static void vec_value_dot_fp32_avx2(const int n, float *__restrict s, const float *__restrict x, const float *__restrict y, bool addition) { - float sumf = 0.0F; - const int np = (n & ~(MLLM_F32_STEP - 1)); - - MLLM_F32_VEC sum[MLLM_F32_ARR] = {MLLM_F32_VEC_ZERO}; - - MLLM_F32_VEC ax[MLLM_F32_ARR]; - MLLM_F32_VEC ay[MLLM_F32_ARR]; - - for (int i = 0; i < np; i += MLLM_F32_STEP) { - for (int j = 0; j < MLLM_F32_ARR; j++) { - ax[j] = MLLM_F32_VEC_LOAD(x + i + j * MLLM_F32_EPR); - ay[j] = MLLM_F32_VEC_LOAD(y + i + j * MLLM_F32_EPR); - - sum[j] = MLLM_F32_VEC_FMA(sum[j], ax[j], ay[j]); - } - } - - // reduce sum0..sum3 to sum0 - MLLM_F32_VEC_REDUCE(sumf, sum); - - // leftovers - for (int i = np; i < n; ++i) { - sumf += x[i] * y[i]; - } - - *s = sumf; -} -#endif - -#ifdef __ARM_NEON -// s:vector k -// x:value -// y:vector k -static void vec_value_dot_fp32_arm(const int n, float *__restrict s, const float x, const float *__restrict y, bool addition) { - int i; - float32x4_t vec_x; - float32x4_t vec_y; - float32x4_t vec_s; - - vec_x = vdupq_n_f32(x); - - int n_aligned = n & -4; - - if (addition) { - for (i = 0; i < n_aligned; i += 4) { - vec_y = vld1q_f32(y + i); - vec_s = vmulq_f32(vec_x, vec_y); - vec_s = vaddq_f32(vec_s, vld1q_f32(s + i)); - vst1q_f32(s + i, vec_s); - } - } else { - for (i = 0; i < n_aligned; i += 4) { - vec_y = vld1q_f32(y + i); - vec_s = vmulq_f32(vec_x, vec_y); - vst1q_f32(s + i, vec_s); - } - } - for (; i < n; ++i) { - if (addition) - s[i] += x * y[i]; - else { - s[i] = x * y[i]; - } - } -} -#endif - -#ifdef __AVX2__ -void vec_value_dot_fp32(const int n, float *__restrict s, const float *x, const float *__restrict vy, bool addition) { - vec_value_dot_fp32_avx2(n, s, x, vy, addition); -} -#elif defined(__ARM_NEON) -void vec_value_dot_fp32(const int n, float *__restrict s, const float x, const float *__restrict vy, bool addition) { - vec_value_dot_fp32_arm(n, s, x, vy, addition); -} -#endif - -void vec_dot_q2_K_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { - const block_q2_K *__restrict x = (block_q2_K *)vx; - const block_q8_K *__restrict y = (block_q8_K *)vy; - - const int nb = n / QK_K; - -#ifdef __ARM_FEATURE_SVE - const int vector_length = svcntb() * 8; - const svuint8_t m3s = svdup_n_u8(0x3); - const svuint32_t m4s = svdup_n_u32(0xF); - const svint32_t vzero_sv = svdup_n_s32(0); - svfloat32_t acc_sum = svdup_n_f32(0); - svbool_t pred_s32 = svptrue_pat_b32(SV_VL4); - - switch (vector_length) { - case 128: - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - svfloat32_t d_broad = svdup_n_f32((float32_t)d); - const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - svfloat32_t dmin_broad = svdup_n_f32((float32_t)dmin); - - const uint8_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8_sv = y[i].qs; - const uint8_t *__restrict sc = x[i].scales; - - svuint32_t mins_and_scales_sve = svld1ub_u32(svptrue_b32(), sc); - const svint32_t mins_sv_1 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_b32(), mins_and_scales_sve, 4)); - - mins_and_scales_sve = svld1ub_u32(svptrue_b32(), sc + 4); - const svint32_t mins_sv_2 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_b32(), mins_and_scales_sve, 4)); - - svint32_t q8sums_sv_1 = svld1sh_s32(svptrue_b32(), y[i].bsums); - svint32_t q8sums_sv_2 = svld1sh_s32(svptrue_b32(), y[i].bsums + 4); - - const svint32_t s0 = svadd_s32_x(svptrue_b32(), svmul_s32_x(svptrue_b32(), mins_sv_1, q8sums_sv_1), svmul_s32_x(svptrue_b32(), mins_sv_2, q8sums_sv_2)); - - mins_and_scales_sve = svld1ub_u32(svptrue_b32(), sc + 8); - const svint32_t mins_sv_3 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_b32(), mins_and_scales_sve, 4)); - - mins_and_scales_sve = svld1ub_u32(svptrue_b32(), sc + 12); - const svint32_t mins_sv_4 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_b32(), mins_and_scales_sve, 4)); - - q8sums_sv_1 = svld1sh_s32(svptrue_b32(), y[i].bsums + 8); - q8sums_sv_2 = svld1sh_s32(svptrue_b32(), y[i].bsums + 12); - - svint32_t s1 = svadd_s32_x(svptrue_b32(), svmul_s32_x(svptrue_b32(), mins_sv_3, q8sums_sv_1), svmul_s32_x(svptrue_b32(), mins_sv_4, q8sums_sv_2)); - - svfloat32_t temp = svcvt_f32_s32_x(svptrue_b32(), svadd_s32_x(svptrue_b32(), s0, s1)); - - acc_sum = svmla_f32_m(svptrue_b32(), acc_sum, temp, dmin_broad); - - svint32_t sumi1 = svdup_n_s32(0); - - { - const svuint8_t q2bits_1 = svld1_u8(svptrue_b8(), q2); - svint8_t q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), q2bits_1, m3s)); - svint8_t q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - const svint32_t scales_sv = svreinterpret_s32_u32(svand_u32_m(svptrue_b32(), svld1ub_u32(svptrue_b32(), sc), m4s)); - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv, 0)); - - const svuint8_t q2bits_3 = svld1_u8(svptrue_b8(), q2 + 16); - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), q2bits_3, m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv, 1)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_1, 2), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv, 2)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_3, 2), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv, 3)); - - const svint32_t scales_sv_1 = svreinterpret_s32_u32(svand_u32_m(svptrue_b32(), svld1ub_u32(svptrue_b32(), sc + 4), m4s)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_1, 4), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_1, 0)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_3, 4), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_1, 1)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_1, 6), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_1, 2)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_3, 6), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_1, 3)); - - //------------------------------- - - q2 += 32; - const svint32_t scales_sv_2 = svreinterpret_s32_u32(svand_u32_m(svptrue_b32(), svld1ub_u32(svptrue_b32(), sc + 8), m4s)); - const svuint8_t q2bits_2 = svld1_u8(svptrue_b8(), q2); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), q2bits_2, m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_2, 0)); - - const svuint8_t q2bits_4 = svld1_u8(svptrue_b8(), q2 + 16); - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), q2bits_4, m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_2, 1)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_2, 2), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_2, 2)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_4, 2), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_2, 3)); - - const svint32_t scales_sv_3 = svreinterpret_s32_u32(svand_u32_m(svptrue_b32(), svld1ub_u32(svptrue_b32(), sc + 12), m4s)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_2, 4), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_3, 0)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_4, 4), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_3, 1)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_2, 6), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_3, 2)); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_4, 6), m3s)); - q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_3, 3)); - } - acc_sum = svmla_f32_m(svptrue_b32(), acc_sum, svcvt_f32_s32_x(svptrue_b32(), sumi1), d_broad); - } - *s = svaddv_f32(svptrue_b32(), acc_sum); - break; - - case 256: - case 512: - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - svfloat32_t d_broad = svdup_n_f32((float32_t)d); - const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - svfloat32_t dmin_broad = svdup_n_f32((float32_t)dmin); - - const uint8_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8_sv = y[i].qs; - const uint8_t *__restrict sc = x[i].scales; - - const svuint32_t mins_and_scales_sve = svld1ub_u32(svptrue_pat_b32(SV_VL8), sc); - sc += 8; - const svint32_t scales_sv = svreinterpret_s32_u32(svand_u32_m(svptrue_pat_b32(SV_VL8), mins_and_scales_sve, m4s)); - const svint32_t mins_sv_1 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_pat_b32(SV_VL8), mins_and_scales_sve, 4)); - svint32_t q8sums_sv_1 = svld1sh_s32(svptrue_pat_b32(SV_VL8), y[i].bsums); - - const svuint32_t mins_and_scales_sve_1 = svld1ub_u32(svptrue_pat_b32(SV_VL8), sc); - const svint32_t scales_sv_1 = svreinterpret_s32_u32(svand_u32_m(svptrue_pat_b32(SV_VL8), mins_and_scales_sve_1, m4s)); - const svint32_t mins_sv_2 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_pat_b32(SV_VL8), mins_and_scales_sve_1, 4)); - - svint32_t q8sums_sv_2 = svld1sh_s32(svptrue_pat_b32(SV_VL8), y[i].bsums + 8); - - svfloat32_t temp = svcvt_f32_s32_x(svptrue_pat_b32(SV_VL8), svadd_s32_x(svptrue_pat_b32(SV_VL8), svmul_s32_x(svptrue_pat_b32(SV_VL8), mins_sv_1, q8sums_sv_1), svmul_s32_x(svptrue_pat_b32(SV_VL8), mins_sv_2, q8sums_sv_2))); - - acc_sum = svmla_f32_m(svptrue_pat_b32(SV_VL8), acc_sum, temp, dmin_broad); - - svint32_t sumi1 = svdup_n_s32(0); - - { - const svuint8_t q2bits_1 = svld1_u8(svptrue_pat_b8(SV_VL32), q2); - svint8_t q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), q2bits_1, m3s)); - svint8_t q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - svint32_t scale_1 = svsel(pred_s32, svdup_lane_s32(scales_sv, 0), svdup_lane_s32(scales_sv, 1)); - sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_1); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_1, 2), m3s)); - q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - svint32_t scale_2 = svsel(pred_s32, svdup_lane_s32(scales_sv, 2), svdup_lane_s32(scales_sv, 3)); - sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(svdup_n_s32(0), q2bytes_sv, q8bytes_sv), scale_2); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_1, 4), m3s)); - q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - scale_1 = svsel(pred_s32, svdup_lane_s32(scales_sv, 4), svdup_lane_s32(scales_sv, 5)); - sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_1); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_1, 6), m3s)); - q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - scale_2 = svsel(pred_s32, svdup_lane_s32(scales_sv, 6), svdup_lane_s32(scales_sv, 7)); - sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_2); - - q2 += 32; - - const svuint8_t q2bits_2 = svld1_u8(svptrue_pat_b8(SV_VL32), q2); - q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), q2bits_2, m3s)); - q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - scale_1 = svsel(pred_s32, svdup_lane_s32(scales_sv_1, 0), svdup_lane_s32(scales_sv_1, 1)); - sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_1); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_2, 2), m3s)); - q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - scale_2 = svsel(pred_s32, svdup_lane_s32(scales_sv_1, 2), svdup_lane_s32(scales_sv_1, 3)); - sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_2); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_2, 4), m3s)); - q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - scale_1 = svsel(pred_s32, svdup_lane_s32(scales_sv_1, 4), svdup_lane_s32(scales_sv_1, 5)); - sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_1); - - q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_2, 6), m3s)); - q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - scale_2 = svsel(pred_s32, svdup_lane_s32(scales_sv_1, 6), svdup_lane_s32(scales_sv_1, 7)); - sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_2); - } - acc_sum = svmla_f32_m(svptrue_pat_b32(SV_VL8), acc_sum, svcvt_f32_s32_x(svptrue_pat_b32(SV_VL8), sumi1), d_broad); - } - *s = svaddv_f32(svptrue_pat_b32(SV_VL8), acc_sum); - break; - - default: - assert(false && "Unsupported vector length"); - break; - } - -#elif __ARM_NEON - const uint8x16_t m3 = vdupq_n_u8(0x3); - const uint8x16_t m4 = vdupq_n_u8(0xF); - - const int32x4_t vzero = vdupq_n_s32(0); - - mllm_int8x16x2_t q2bytes; - uint8_t aux[16]; - - float sum = 0; - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - - const uint8_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - const uint8_t *__restrict sc = x[i].scales; - - const uint8x16_t mins_and_scales = vld1q_u8(sc); - const uint8x16_t scales = vandq_u8(mins_and_scales, m4); - vst1q_u8(aux, scales); - - const uint8x16_t mins = vshrq_n_u8(mins_and_scales, 4); - const mllm_int16x8x2_t q8sums = mllm_vld1q_s16_x2(y[i].bsums); - const mllm_int16x8x2_t mins16 = {{vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(mins))), vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(mins)))}}; - const int32x4_t s0 = vaddq_s32(vmull_s16(vget_low_s16(mins16.val[0]), vget_low_s16(q8sums.val[0])), - vmull_s16(vget_high_s16(mins16.val[0]), vget_high_s16(q8sums.val[0]))); - const int32x4_t s1 = vaddq_s32(vmull_s16(vget_low_s16(mins16.val[1]), vget_low_s16(q8sums.val[1])), - vmull_s16(vget_high_s16(mins16.val[1]), vget_high_s16(q8sums.val[1]))); - sum += dmin * vaddvq_s32(vaddq_s32(s0, s1)); - - int isum = 0; - int is = 0; - - // We use this macro instead of a function call because for some reason - // the code runs 2-3% slower, even if the function is declared inline -#define MULTIPLY_ACCUM_WITH_SCALE(index) \ - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q2bytes.val[0], q8bytes.val[0])) * aux[is + (index)]; \ - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q2bytes.val[1], q8bytes.val[1])) * aux[is + 1 + (index)]; - -#define SHIFT_MULTIPLY_ACCUM_WITH_SCALE(shift, index) \ - q8bytes = mllm_vld1q_s8_x2(q8); \ - q8 += 32; \ - q2bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits.val[0], (shift)), m3)); \ - q2bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits.val[1], (shift)), m3)); \ - MULTIPLY_ACCUM_WITH_SCALE((index)); - - for (int j = 0; j < QK_K / 128; ++j) { - const mllm_uint8x16x2_t q2bits = mllm_vld1q_u8_x2(q2); - q2 += 32; - - mllm_int8x16x2_t q8bytes = mllm_vld1q_s8_x2(q8); - q8 += 32; - q2bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q2bits.val[0], m3)); - q2bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q2bits.val[1], m3)); - - MULTIPLY_ACCUM_WITH_SCALE(0); - - SHIFT_MULTIPLY_ACCUM_WITH_SCALE(2, 2); - SHIFT_MULTIPLY_ACCUM_WITH_SCALE(4, 4); - SHIFT_MULTIPLY_ACCUM_WITH_SCALE(6, 6); - - is += 8; - } - - sum += d * isum; - } - - *s = sum; - -#elif defined __AVX2__ - - const __m256i m3 = _mm256_set1_epi8(3); - const __m128i m4 = _mm_set1_epi8(0xF); - - __m256 acc = _mm256_setzero_ps(); - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - - const uint8_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - const __m128i mins_and_scales = _mm_loadu_si128((const __m128i *)x[i].scales); - const __m128i scales8 = _mm_and_si128(mins_and_scales, m4); - const __m128i mins8 = _mm_and_si128(_mm_srli_epi16(mins_and_scales, 4), m4); - const __m256i mins = _mm256_cvtepi8_epi16(mins8); - const __m256i prod = _mm256_madd_epi16(mins, _mm256_loadu_si256((const __m256i *)y[i].bsums)); - - acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&dmin), _mm256_cvtepi32_ps(prod), acc); - - const __m256i all_scales = _mm256_cvtepi8_epi16(scales8); - const __m128i l_scales = _mm256_extracti128_si256(all_scales, 0); - const __m128i h_scales = _mm256_extracti128_si256(all_scales, 1); - const __m256i scales[2] = {MM256_SET_M128I(l_scales, l_scales), MM256_SET_M128I(h_scales, h_scales)}; - - __m256i sumi = _mm256_setzero_si256(); - - for (int j = 0; j < QK_K / 128; ++j) { - const __m256i q2bits = _mm256_loadu_si256((const __m256i *)q2); - q2 += 32; - - const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_3 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - - const __m256i q2_0 = _mm256_and_si256(q2bits, m3); - const __m256i q2_1 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 2), m3); - const __m256i q2_2 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 4), m3); - const __m256i q2_3 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 6), m3); - - __m256i p0 = _mm256_maddubs_epi16(q2_0, q8_0); - __m256i p1 = _mm256_maddubs_epi16(q2_1, q8_1); - __m256i p2 = _mm256_maddubs_epi16(q2_2, q8_2); - __m256i p3 = _mm256_maddubs_epi16(q2_3, q8_3); - - p0 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(0)), p0); - p1 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(1)), p1); - p2 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(2)), p2); - p3 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(3)), p3); - - p0 = _mm256_add_epi32(p0, p1); - p2 = _mm256_add_epi32(p2, p3); - - sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p0, p2)); - } - - acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); - } - - *s = hsum_float_8(acc); - -#elif defined __AVX__ - - const __m128i m3 = _mm_set1_epi8(0x3); - const __m128i m4 = _mm_set1_epi8(0xF); - const __m128i m2 = _mm_set1_epi8(0x2); - - __m256 acc = _mm256_setzero_ps(); - - for (int i = 0; i < nb; ++i) { - const float dall = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - - const uint8_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - // load mins and scales from block_q2_K.scales[QK_K/16] - const __m128i mins_and_scales = _mm_loadu_si128((const __m128i *)x[i].scales); - const __m128i scales16 = _mm_and_si128(mins_and_scales, m4); - const __m128i mins16 = _mm_and_si128(_mm_srli_epi16(mins_and_scales, 4), m4); - const __m128i mins_0 = _mm_cvtepi8_epi16(mins16); - const __m128i mins_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(mins16, mins16)); - - // summs = y[i].bsums * (x[i].scales >> 4) in 16bits*8*2 to 32bits*4*2 - const __m128i summs_0 = _mm_madd_epi16(mins_0, _mm_loadu_si128((const __m128i *)&y[i].bsums[0])); - const __m128i summs_1 = _mm_madd_epi16(mins_1, _mm_loadu_si128((const __m128i *)&y[i].bsums[8])); - - // sumf += -dmin * summs in 32bits*8 - acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&dmin), _mm256_cvtepi32_ps(MM256_SET_M128I(summs_1, summs_0))), acc); - - const __m128i scales_0 = _mm_cvtepi8_epi16(scales16); - const __m128i scales_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(scales16, scales16)); - const __m128i scales[2] = {scales_0, scales_1}; - - __m128i sumi_0 = _mm_setzero_si128(); - __m128i sumi_1 = _mm_setzero_si128(); - - for (int j = 0; j < QK_K / 128; ++j) { - // load Q8 quants int8*16*8 from block_q8_K.qs[QK_K] - const __m128i q8_0 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_1 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_2 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_3 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_4 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_5 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_6 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_7 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - - // load 2bits*16*8 from block_q2_K.qs[QK_K/4] - __m128i q2bits = _mm_loadu_si128((const __m128i *)q2); - q2 += 16; - const __m128i q2_0 = _mm_and_si128(q2bits, m3); - const __m128i q2_2 = _mm_and_si128(_mm_srli_epi16(q2bits, 2), m3); - const __m128i q2_4 = _mm_and_si128(_mm_srli_epi16(q2bits, 4), m3); - const __m128i q2_6 = _mm_and_si128(_mm_srli_epi16(q2bits, 6), m3); - q2bits = _mm_loadu_si128((const __m128i *)q2); - q2 += 16; - const __m128i q2_1 = _mm_and_si128(q2bits, m3); - const __m128i q2_3 = _mm_and_si128(_mm_srli_epi16(q2bits, 2), m3); - const __m128i q2_5 = _mm_and_si128(_mm_srli_epi16(q2bits, 4), m3); - const __m128i q2_7 = _mm_and_si128(_mm_srli_epi16(q2bits, 6), m3); - - // isuml = q8[l] * ((q2[l] >> shift) & 3) in 8bits*16*8 to 16bits*8*8 - __m128i p0 = _mm_maddubs_epi16(q2_0, q8_0); - __m128i p1 = _mm_maddubs_epi16(q2_1, q8_1); - __m128i p2 = _mm_maddubs_epi16(q2_2, q8_2); - __m128i p3 = _mm_maddubs_epi16(q2_3, q8_3); - __m128i p4 = _mm_maddubs_epi16(q2_4, q8_4); - __m128i p5 = _mm_maddubs_epi16(q2_5, q8_5); - __m128i p6 = _mm_maddubs_epi16(q2_6, q8_6); - __m128i p7 = _mm_maddubs_epi16(q2_7, q8_7); - - // isum += (x[i].scales[is++] & 0xF) * isuml in 16bits*8*8 to 32bits*4*8 - __m128i shuffle = _mm_set1_epi16(0x0100); - p0 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p0); - shuffle = _mm_add_epi16(shuffle, m2); - p1 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p1); - shuffle = _mm_add_epi16(shuffle, m2); - p2 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p2); - shuffle = _mm_add_epi16(shuffle, m2); - p3 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p3); - shuffle = _mm_add_epi16(shuffle, m2); - p4 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p4); - shuffle = _mm_add_epi16(shuffle, m2); - p5 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p5); - shuffle = _mm_add_epi16(shuffle, m2); - p6 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p6); - shuffle = _mm_add_epi16(shuffle, m2); - p7 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p7); - - p0 = _mm_add_epi32(p0, p1); - p2 = _mm_add_epi32(p2, p3); - p4 = _mm_add_epi32(p4, p5); - p6 = _mm_add_epi32(p6, p7); - - // isum in 32bits*4*2 - sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p0, p2)); - sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p4, p6)); - } - - // sumf += dall * isum - dmin * summs in 32bits - __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); - acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&dall), _mm256_cvtepi32_ps(sumi)), acc); - } - - *s = hsum_float_8(acc); - -#elif defined __wasm_simd128__ - float sumf = 0; - - for (int i = 0; i < nb; ++i) { - const uint8_t *q2 = x[i].qs; - const int8_t *q8 = y[i].qs; - const uint8_t *sc = x[i].scales; - - // Vectorized summs calculation - v128_t summs_vec = wasm_i32x4_splat(0); - { - v128_t sc_vec = wasm_v128_load(sc); - v128_t sc_upper = wasm_u8x16_shr(sc_vec, 4); - - v128_t sc_low = wasm_u16x8_extend_low_u8x16(sc_upper); - v128_t sc_high = wasm_u16x8_extend_high_u8x16(sc_upper); - - v128_t bsums1 = wasm_v128_load(&y[i].bsums[0]); - v128_t bsums2 = wasm_v128_load(&y[i].bsums[8]); - - summs_vec = wasm_i32x4_add( - wasm_i32x4_add(wasm_i32x4_dot_i16x8(sc_low, bsums1), - wasm_i32x4_dot_i16x8(sc_high, bsums2)), - summs_vec); - - summs_vec = wasm_i32x4_add(summs_vec, wasm_i32x4_shuffle(summs_vec, summs_vec, 2, 3, 0, 1)); - summs_vec = wasm_i32x4_add(summs_vec, wasm_i32x4_shuffle(summs_vec, summs_vec, 1, 0, 3, 2)); - } - int32_t summs = wasm_i32x4_extract_lane(summs_vec, 0); - - // Vectorized isum calculation - int32_t isum = 0; - const uint8_t *sc_ptr = sc; - const int k_iters = QK_K / 128; - - for (int k = 0; k < k_iters; ++k) { - v128_t isum_vec = wasm_i32x4_splat(0); - int shift = 0; - - for (int j = 0; j < 4; ++j) { - const int d0 = (sc_ptr[0] & 0xF); - const int d1 = (sc_ptr[1] & 0xF); - sc_ptr += 2; - - // Process first 16 elements - v128_t q2_0 = wasm_v128_load(q2); - v128_t q8_0 = wasm_v128_load(q8); - v128_t q2_shift_0 = wasm_u8x16_shr(q2_0, shift); - v128_t q2_bits_0 = wasm_v128_and(q2_shift_0, wasm_i8x16_splat(0x03)); - - // Process next 16 elements - v128_t q2_1 = wasm_v128_load(q2 + 16); - v128_t q8_1 = wasm_v128_load(q8 + 16); - v128_t q2_shift_1 = wasm_u8x16_shr(q2_1, shift); - v128_t q2_bits_1 = wasm_v128_and(q2_shift_1, wasm_i8x16_splat(0x03)); - - // Calculate dot products - v128_t p0 = wasm_i32x4_dot_i16x8( - wasm_i16x8_extend_low_i8x16(q8_0), - wasm_i16x8_extend_low_i8x16(q2_bits_0)); - v128_t p1 = wasm_i32x4_dot_i16x8( - wasm_i16x8_extend_high_i8x16(q8_0), - wasm_i16x8_extend_high_i8x16(q2_bits_0)); - v128_t p2 = wasm_i32x4_dot_i16x8( - wasm_i16x8_extend_low_i8x16(q8_1), - wasm_i16x8_extend_low_i8x16(q2_bits_1)); - v128_t p3 = wasm_i32x4_dot_i16x8( - wasm_i16x8_extend_high_i8x16(q8_1), - wasm_i16x8_extend_high_i8x16(q2_bits_1)); - - // Accumulate scaled results - v128_t scaled = wasm_i32x4_add( - wasm_i32x4_mul(wasm_i32x4_add(p0, p1), wasm_i32x4_splat(d0)), - wasm_i32x4_mul(wasm_i32x4_add(p2, p3), wasm_i32x4_splat(d1))); - - isum_vec = wasm_i32x4_add(isum_vec, scaled); - q8 += 32; - shift += 2; - } - q2 += 32; - - // Horizontal sum of isum_vec - isum_vec = wasm_i32x4_add(isum_vec, wasm_i32x4_shuffle(isum_vec, isum_vec, 2, 3, 0, 1)); - isum_vec = wasm_i32x4_add(isum_vec, wasm_i32x4_shuffle(isum_vec, isum_vec, 1, 0, 3, 2)); - isum += wasm_i32x4_extract_lane(isum_vec, 0); - } - - const float dall = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - const float dmin = MLLM_FP16_TO_FP32(x[i].dmin) * y[i].d; - sumf += dall * isum - dmin * summs; - } - - *s = sumf; - -#elif defined __riscv_v_intrinsic - - const int vector_length = __riscv_vlenb() * 8; - float sumf = 0; - - uint8_t temp_01[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; - uint8_t atmp[16]; - - switch (vector_length) { - case 256: - for (int i = 0; i < nb; ++i) { - const uint8_t *q2 = x[i].qs; - const int8_t *q8 = y[i].qs; - const uint8_t *sc = x[i].scales; - - const float dall = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - - size_t vl = 16; - - vuint8m1_t scales = __riscv_vle8_v_u8m1(sc, vl); - vuint8m1_t aux = __riscv_vand_vx_u8m1(scales, 0x0F, vl); - - vint16m1_t q8sums = __riscv_vle16_v_i16m1(y[i].bsums, vl); - - vuint8mf2_t scales_2 = __riscv_vle8_v_u8mf2(sc, vl); - vuint8mf2_t mins8 = __riscv_vsrl_vx_u8mf2(scales_2, 0x4, vl); - vint16m1_t mins = __riscv_vreinterpret_v_u16m1_i16m1(__riscv_vzext_vf2_u16m1(mins8, vl)); - vint32m2_t prod = __riscv_vwmul_vv_i32m2(q8sums, mins, vl); - vint32m1_t vsums = __riscv_vredsum_vs_i32m2_i32m1(prod, __riscv_vmv_v_x_i32m1(0, 1), vl); - - sumf += dmin * __riscv_vmv_x_s_i32m1_i32(vsums); - - vl = 32; - - vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); - vuint8m1_t v_b = __riscv_vle8_v_u8m1(temp_01, vl); - - uint8_t is = 0; - int isum = 0; - - for (int j = 0; j < QK_K / 128; ++j) { - // load Q2 - vuint8m1_t q2_x = __riscv_vle8_v_u8m1(q2, vl); - - vuint8m1_t q2_0 = __riscv_vand_vx_u8m1(q2_x, 0x03, vl); - vuint8m1_t q2_1 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q2_x, 0x2, vl), 0x03, vl); - vuint8m1_t q2_2 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q2_x, 0x4, vl), 0x03, vl); - vuint8m1_t q2_3 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q2_x, 0x6, vl), 0x03, vl); - - // duplicate scale elements for product - vuint8m1_t sc0 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 0 + is, vl), vl); - vuint8m1_t sc1 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 2 + is, vl), vl); - vuint8m1_t sc2 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 4 + is, vl), vl); - vuint8m1_t sc3 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 6 + is, vl), vl); - - vint16m2_t p0 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_0, sc0, vl)); - vint16m2_t p1 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_1, sc1, vl)); - vint16m2_t p2 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_2, sc2, vl)); - vint16m2_t p3 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_3, sc3, vl)); - - // load Q8 - vint8m1_t q8_0 = __riscv_vle8_v_i8m1(q8, vl); - vint8m1_t q8_1 = __riscv_vle8_v_i8m1(q8 + 32, vl); - vint8m1_t q8_2 = __riscv_vle8_v_i8m1(q8 + 64, vl); - vint8m1_t q8_3 = __riscv_vle8_v_i8m1(q8 + 96, vl); - - vint32m4_t s0 = __riscv_vwmul_vv_i32m4(p0, __riscv_vwcvt_x_x_v_i16m2(q8_0, vl), vl); - vint32m4_t s1 = __riscv_vwmul_vv_i32m4(p1, __riscv_vwcvt_x_x_v_i16m2(q8_1, vl), vl); - vint32m4_t s2 = __riscv_vwmul_vv_i32m4(p2, __riscv_vwcvt_x_x_v_i16m2(q8_2, vl), vl); - vint32m4_t s3 = __riscv_vwmul_vv_i32m4(p3, __riscv_vwcvt_x_x_v_i16m2(q8_3, vl), vl); - - vint32m1_t isum0 = __riscv_vredsum_vs_i32m4_i32m1(__riscv_vadd_vv_i32m4(s0, s1, vl), vzero, vl); - vint32m1_t isum1 = __riscv_vredsum_vs_i32m4_i32m1(__riscv_vadd_vv_i32m4(s2, s3, vl), isum0, vl); - - isum += __riscv_vmv_x_s_i32m1_i32(isum1); - - q2 += 32; - q8 += 128; - is = 8; - } - - sumf += dall * isum; - } - break; - case 128: - for (int i = 0; i < nb; ++i) { - const uint8_t *q2 = x[i].qs; - const int8_t *q8 = y[i].qs; - const uint8_t *sc = x[i].scales; - const float dall = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - uint8_t *patmp = atmp; - int vsums; - int tmp; - __asm__ __volatile__( - "vsetivli zero, 16, e8, m1\n\t" - "vmv.v.x v8, zero\n\t" - "vle8.v v1, (%[sc])\n\t" - "vand.vi v0, v1, 0xF\n\t" - "vsrl.vi v1, v1, 4\n\t" - "vse8.v v0, (%[scale])\n\t" - "vsetivli zero, 16, e16, m2\n\t" - "vle16.v v2, (%[bsums])\n\t" - "vzext.vf2 v0, v1\n\t" - "vwmul.vv v4, v0, v2\n\t" - "vsetivli zero, 16, e32, m4\n\t" - "vredsum.vs v8, v4, v8\n\t" - "vmv.x.s %[vsums], v8" - : [tmp] "=&r"(tmp), [vsums] "=&r"(vsums) - : [sc] "r"(sc), [scale] "r"(atmp), [bsums] "r"(y[i].bsums) - : "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); - sumf += dmin * vsums; - int isum = 0; - - for (int j = 0; j < QK_K / 128; ++j) { - __asm__ __volatile__( - "vsetvli zero, %[vl32], e8, m2\n\t" - "vle8.v v0, (%[q2])\n\t" - "vsrl.vi v2, v0, 2\n\t" - "vsrl.vi v4, v0, 4\n\t" - "vsrl.vi v6, v0, 6\n\t" - "vand.vi v0, v0, 0x3\n\t" - "vand.vi v2, v2, 0x3\n\t" - "vand.vi v4, v4, 0x3\n\t" - "vsetvli zero, %[vl128], e8, m8\n\t" - "vle8.v v8, (%[q8])\n\t" - "vsetvli zero, %[vl64], e8, m4\n\t" - "vwmul.vv v16, v0, v8\n\t" - "vwmul.vv v24, v4, v12\n\t" - "vsetivli zero, 16, e16, m2\n\t" - "vmv.v.x v0, zero\n\t" - "vwredsum.vs v10, v16, v0\n\t" - "vwredsum.vs v9, v18, v0\n\t" - "vwredsum.vs v8, v20, v0\n\t" - "vwredsum.vs v7, v22, v0\n\t" - "vwredsum.vs v11, v24, v0\n\t" - "vwredsum.vs v12, v26, v0\n\t" - "vwredsum.vs v13, v28, v0\n\t" - "vwredsum.vs v14, v30, v0\n\t" - "vsetivli zero, 4, e32, m1\n\t" - "vslideup.vi v10, v9, 1\n\t" - "vslideup.vi v8, v7, 1\n\t" - "vslideup.vi v11, v12, 1\n\t" - "vslideup.vi v13, v14, 1\n\t" - "vslideup.vi v10, v8, 2\n\t" - "vslideup.vi v11, v13, 2\n\t" - "vsetivli zero, 8, e32, m2\n\t" - "vle8.v v15, (%[scale])\n\t" - "vzext.vf4 v12, v15\n\t" - "vmul.vv v10, v10, v12\n\t" - "vredsum.vs v0, v10, v0\n\t" - "vmv.x.s %[tmp], v0\n\t" - "add %[isum], %[isum], %[tmp]" - : [tmp] "=&r"(tmp), [isum] "+&r"(isum) - : [q2] "r"(q2), [scale] "r"(patmp), [q8] "r"(q8), [vl32] "r"(32), [vl64] "r"(64), [vl128] "r"(128) - : "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); - q2 += 32; - q8 += 128; - patmp += 8; - } - - sumf += dall * isum; - } - break; - default: - assert(false && "Unsupported vector length"); - break; - } - - *s = sumf; - -#elif defined(__POWER9_VECTOR__) - const vector signed char lowMask = vec_splats((signed char)0x3); - const vector signed char lowScaleMask = vec_splats((signed char)0xF); - const vector int v0 = vec_splats((int32_t)0); - const vector unsigned char v2 = vec_splats((unsigned char)0x2); - const vector unsigned char v6 = vec_splats((unsigned char)0x6); - const vector unsigned char v4 = vec_splats((unsigned char)0x4); - - vector float vsumf0 = vec_splats(0.0f); - vector float vsumf1 = vec_splats(0.0f); - vector float vsumf2 = vec_splats(0.0f); - vector float vsumf3 = vec_splats(0.0f); - - for (int i = 0; i < nb; ++i) { - vector float vxd = vec_splats(MLLM_FP16_TO_FP32(x[i].d)); - vector float vyd = vec_splats(y[i].d); - vector float vd = vec_mul(vxd, vyd); - - vector float vxmin = vec_splats(MLLM_FP16_TO_FP32(x[i].dmin)); - vector float vdmin = vec_mul(vxmin, vyd); - - vector signed short q8ysums0 = vec_xl(0, y[i].bsums); - vector signed short q8ysums1 = vec_xl(16, y[i].bsums); - - vector signed char q2xmins = (vector signed char)vec_xl(0, x[i].scales); - vector signed char vscales = vec_and(q2xmins, lowScaleMask); - - q2xmins = vec_sr(q2xmins, v4); - vector signed short q2xmins0 = vec_unpackh(q2xmins); - vector signed short q2xmins1 = vec_unpackl(q2xmins); - - vector signed int prod0 = vec_mule(q2xmins0, q8ysums0); - vector signed int prod1 = vec_mulo(q2xmins0, q8ysums0); - vector signed int prod2 = vec_mule(q2xmins1, q8ysums1); - vector signed int prod3 = vec_mulo(q2xmins1, q8ysums1); - - vsumf0 = vec_nmsub(vec_ctf(prod0, 0), vdmin, vsumf0); - vsumf1 = vec_nmsub(vec_ctf(prod1, 0), vdmin, vsumf1); - vsumf2 = vec_nmsub(vec_ctf(prod2, 0), vdmin, vsumf2); - vsumf3 = vec_nmsub(vec_ctf(prod3, 0), vdmin, vsumf3); - - vector signed int vsumi0 = v0; - vector signed int vsumi1 = v0; - vector signed int vsumi2 = v0; - vector signed int vsumi3 = v0; - vector signed int vsumi4 = v0; - vector signed int vsumi5 = v0; - vector signed int vsumi6 = v0; - vector signed int vsumi7 = v0; - - const uint8_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - for (int j = 0; j < QK_K / 128; ++j) { - __builtin_prefetch(q2, 0, 1); - __builtin_prefetch(q8, 0, 1); - - vector signed char qxs0 = (vector signed char)vec_xl(0, q2); - vector signed char qxs1 = (vector signed char)vec_xl(16, q2); - q2 += 32; - - vector unsigned char q2x00 = (vector unsigned char)vec_and(qxs0, lowMask); - vector unsigned char q2x01 = (vector unsigned char)vec_and(vec_sr(qxs0, v2), lowMask); - vector unsigned char q2x02 = (vector unsigned char)vec_and(vec_sr(qxs0, v4), lowMask); - vector unsigned char q2x03 = (vector unsigned char)vec_and(vec_sr(qxs0, v6), lowMask); - vector unsigned char q2x10 = (vector unsigned char)vec_and(qxs1, lowMask); - vector unsigned char q2x11 = (vector unsigned char)vec_and(vec_sr(qxs1, v2), lowMask); - vector unsigned char q2x12 = (vector unsigned char)vec_and(vec_sr(qxs1, v4), lowMask); - vector unsigned char q2x13 = (vector unsigned char)vec_and(vec_sr(qxs1, v6), lowMask); - - vector signed char q8y00 = vec_xl(0, q8); - vector signed char q8y10 = vec_xl(16, q8); - vector signed char q8y01 = vec_xl(32, q8); - vector signed char q8y11 = vec_xl(48, q8); - vector signed char q8y02 = vec_xl(64, q8); - vector signed char q8y12 = vec_xl(80, q8); - vector signed char q8y03 = vec_xl(96, q8); - vector signed char q8y13 = vec_xl(112, q8); - q8 += 128; - - vector signed int qv0 = vec_msum(q8y00, q2x00, v0); - vector signed int qv1 = vec_msum(q8y01, q2x01, v0); - vector signed int qv2 = vec_msum(q8y02, q2x02, v0); - vector signed int qv3 = vec_msum(q8y03, q2x03, v0); - vector signed int qv4 = vec_msum(q8y10, q2x10, v0); - vector signed int qv5 = vec_msum(q8y11, q2x11, v0); - vector signed int qv6 = vec_msum(q8y12, q2x12, v0); - vector signed int qv7 = vec_msum(q8y13, q2x13, v0); - - vector signed short vscales_07 = vec_unpackh(vscales); - vector signed int vscales_03 = vec_unpackh(vscales_07); - vector signed int vscales_47 = vec_unpackl(vscales_07); - vector signed int vs0 = vec_splat(vscales_03, 0); - vector signed int vs1 = vec_splat(vscales_03, 1); - vector signed int vs2 = vec_splat(vscales_03, 2); - vector signed int vs3 = vec_splat(vscales_03, 3); - vector signed int vs4 = vec_splat(vscales_47, 0); - vector signed int vs5 = vec_splat(vscales_47, 1); - vector signed int vs6 = vec_splat(vscales_47, 2); - vector signed int vs7 = vec_splat(vscales_47, 3); - vscales = vec_sld(vscales, vscales, 8); - - vsumi0 = vec_add(vec_mul(qv0, vs0), vsumi0); - vsumi1 = vec_add(vec_mul(qv1, vs2), vsumi1); - vsumi2 = vec_add(vec_mul(qv2, vs4), vsumi2); - vsumi3 = vec_add(vec_mul(qv3, vs6), vsumi3); - vsumi4 = vec_add(vec_mul(qv4, vs1), vsumi4); - vsumi5 = vec_add(vec_mul(qv5, vs3), vsumi5); - vsumi6 = vec_add(vec_mul(qv6, vs5), vsumi6); - vsumi7 = vec_add(vec_mul(qv7, vs7), vsumi7); - } - - vsumi0 = vec_add(vsumi0, vsumi4); - vsumi1 = vec_add(vsumi1, vsumi5); - vsumi2 = vec_add(vsumi2, vsumi6); - vsumi3 = vec_add(vsumi3, vsumi7); - - vsumf0 = vec_madd(vec_ctf(vsumi0, 0), vd, vsumf0); - vsumf1 = vec_madd(vec_ctf(vsumi1, 0), vd, vsumf1); - vsumf2 = vec_madd(vec_ctf(vsumi2, 0), vd, vsumf2); - vsumf3 = vec_madd(vec_ctf(vsumi3, 0), vd, vsumf3); - } - - vsumf0 = vec_add(vsumf0, vsumf2); - vsumf1 = vec_add(vsumf1, vsumf3); - - vsumf0 = vec_add(vsumf0, vsumf1); - - vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 4)); - vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 8)); - - *s = vec_extract(vsumf0, 0); - -#elif defined __loongarch_asx - - __m256 acc = (__m256)__lasx_xvldi(0); - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - - const uint8_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - const __m128i mins_and_scales128 = __lsx_vld((const __m128i *)x[i].scales, 0); - const __m128i scales128 = __lsx_vandi_b(mins_and_scales128, 0xf); - const __m256i mins = lasx_ext8_16(__lsx_vsrli_b(mins_and_scales128, 4)); - const __m256i prod = lasx_madd_h(mins, __lasx_xvld((const __m256i *)y[i].bsums, 0)); - - acc = __lasx_xvfmadd_s(__lasx_xvreplfr2vr_s(dmin), __lasx_xvffint_s_w(prod), acc); - - const v16i8 shuffle_mask = {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15}; - const __m256i scales_shuffled = lasx_ext8_16(__lsx_vshuf_b(scales128, scales128, (__m128i)shuffle_mask)); - - __m256i sumi = __lasx_xvldi(0); - - for (int j = 0; j < QK_K / 128; ++j) { - const __m256i q2bits = __lasx_xvld((const __m256i *)q2, 0); - q2 += 32; - - const __m256i q8_0 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - const __m256i q8_1 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - const __m256i q8_2 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - const __m256i q8_3 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - - const __m256i q2_0 = __lasx_xvandi_b(q2bits, 3); - const __m256i q2_1 = __lasx_xvandi_b(__lasx_xvsrli_b(q2bits, 2), 3); - const __m256i q2_2 = __lasx_xvandi_b(__lasx_xvsrli_b(q2bits, 4), 3); - const __m256i q2_3 = __lasx_xvsrli_b(q2bits, 6); - - __m256i p0 = lasx_madd_h_b(q2_0, q8_0); - __m256i p1 = lasx_madd_h_b(q2_1, q8_1); - __m256i p2 = lasx_madd_h_b(q2_2, q8_2); - __m256i p3 = lasx_madd_h_b(q2_3, q8_3); - - p0 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 0), p0); - p1 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 1), p1); - p2 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 2), p2); - p3 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 3), p3); - - p0 = __lasx_xvadd_w(p0, p1); - p2 = __lasx_xvadd_w(p2, p3); - - sumi = __lasx_xvadd_w(sumi, __lasx_xvadd_w(p0, p2)); - } - - acc = __lasx_xvfmadd_s(__lasx_xvreplfr2vr_s(d), __lasx_xvffint_s_w(sumi), acc); - } - - *s = hsum_float_8(acc); - -#else - - float sumf = 0; - - for (int i = 0; i < nb; ++i) { - const uint8_t *q2 = x[i].qs; - const int8_t *q8 = y[i].qs; - const uint8_t *sc = x[i].scales; - - int summs = 0; - for (int j = 0; j < 16; ++j) { - summs += y[i].bsums[j] * (sc[j] >> 4); - } - - const float dall = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const float dmin = y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); - - int isum = 0; - int is = 0; - int d; - for (int k = 0; k < QK_K / 128; ++k) { - int shift = 0; - for (int j = 0; j < 4; ++j) { - d = sc[is++] & 0xF; - int isuml = 0; - for (int l = 0; l < 16; ++l) isuml += q8[l] * ((q2[l] >> shift) & 3); - isum += d * isuml; - d = sc[is++] & 0xF; - isuml = 0; - for (int l = 16; l < 32; ++l) isuml += q8[l] * ((q2[l] >> shift) & 3); - isum += d * isuml; - shift += 2; - q8 += 32; - } - q2 += 32; - } - sumf += dall * isum - dmin * summs; - } - *s = sumf; -#endif -} - -void vec_dot_q3_K_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { - assert(n % QK_K == 0); - - const uint32_t kmask1 = 0x03030303; - const uint32_t kmask2 = 0x0f0f0f0f; - - const block_q3_K *__restrict x = (block_q3_K *)vx; - const block_q8_K *__restrict y = (block_q8_K *)vy; - - const int nb = n / QK_K; - -#if defined(__ARM_FEATURE_SVE) - - uint32_t aux[3]; - uint32_t utmp[4]; - - const int8_t m32 = 32; - const int vector_length = svcntb() * 8; - const svuint8_t m3b_sv = svdup_n_u8(0x3); - const svint32_t vzero_sv = svdup_n_s32(0); - - const svuint8_t m0_sv = svdup_n_u8(1); - const svuint8_t m1_sv = svlsl_n_u8_x(svptrue_b8(), m0_sv, 1); - const svuint8_t m2_sv = svlsl_n_u8_x(svptrue_b8(), m0_sv, 2); - const svuint8_t m3_sv = svlsl_n_u8_x(svptrue_b8(), m0_sv, 3); - - float sum = 0; - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *__restrict q3_sv = x[i].qs; - const uint8_t *__restrict qh_sv = x[i].hmask; - const int8_t *__restrict q8_sv = y[i].qs; - - // Set up scales - memcpy(aux, x[i].scales, 12); - utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); - utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); - utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); - utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); - - int8_t *scale = (int8_t *)utmp; - - for (int j = 0; j < 16; ++j) scale[j] -= m32; - - switch (vector_length) { - case 128: { - svuint8_t qhbits_sv_1 = svld1_u8(svptrue_b8(), qh_sv); - svuint8_t qhbits_sv_2 = svld1_u8(svptrue_b8(), qh_sv + 16); - svuint8_t q3h_sv; - - svint32_t sumi1_1 = svdup_n_s32(0); - svint8_t q3bytes_sv; - - for (int j = 0; j < QK_K / 128; ++j) { - const svuint8_t q3bits_sv = svld1_u8(svptrue_b8(), q3_sv); - q3_sv += 16; - const svuint8_t q3bits_sv_1 = svld1_u8(svptrue_b8(), q3_sv); - q3_sv += 16; - svint8_t q8bytes_1_sv_1 = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - svint8_t q8bytes_1_sv_2 = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - q3h_sv = svlsl_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m0_sv, qhbits_sv_1), 2); - q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), q3bits_sv, m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), svdup_n_s32((int32_t)scale[0])); - - q3h_sv = svlsl_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m0_sv, qhbits_sv_2), 2); - q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), q3bits_sv_1, m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), svdup_n_s32((int32_t)scale[1])); - - q8bytes_1_sv_1 = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - q8bytes_1_sv_2 = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - q3h_sv = svlsl_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m1_sv, qhbits_sv_1), 1); - q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv, 2), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), svdup_n_s32((int32_t)scale[2])); - - q3h_sv = svlsl_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m1_sv, qhbits_sv_2), 1); - q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv_1, 2), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), svdup_n_s32((int32_t)scale[3])); - - scale += 4; - q8bytes_1_sv_1 = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - q8bytes_1_sv_2 = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - q3h_sv = svbic_u8_x(svptrue_b8(), m2_sv, qhbits_sv_1); - q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv, 4), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), svdup_n_s32((int32_t)scale[0])); - - q3h_sv = svbic_u8_x(svptrue_b8(), m2_sv, qhbits_sv_2); - q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv_1, 4), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), svdup_n_s32((int32_t)scale[1])); - - q8bytes_1_sv_1 = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - q8bytes_1_sv_2 = svld1_s8(svptrue_b8(), q8_sv); - q8_sv += 16; - - q3h_sv = svlsr_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m3_sv, qhbits_sv_1), 1); - q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv, 6), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), svdup_n_s32((int32_t)scale[2])); - - q3h_sv = svlsr_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m3_sv, qhbits_sv_2), 1); - q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv_1, 6), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), svdup_n_s32((int32_t)scale[3])); - - if (j == 0) { - qhbits_sv_1 = svlsr_n_u8_x(svptrue_b8(), qhbits_sv_1, 4); - qhbits_sv_2 = svlsr_n_u8_x(svptrue_b8(), qhbits_sv_2, 4); - } - - scale += 4; - } - - sum += d * (svaddv_s32(svptrue_b32(), sumi1_1)); - } break; - case 256: - case 512: { - svuint8_t qhbits_sv = svld1_u8(svptrue_pat_b8(SV_VL32), qh_sv); - svuint8_t q3h_sv; - - svint32_t sumi1_1 = svdup_n_s32(0); - svint8_t q3bytes_sv; - - for (int j = 0; j < QK_K / 128; ++j) { - const svuint8_t q3bits_sv = svld1_u8(svptrue_pat_b8(SV_VL32), q3_sv); - q3_sv += 32; - svint8_t q8bytes_1_sv_1 = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - svint8_t q8bytes_1_sv_2 = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - q3h_sv = svlsl_n_u8_x(svptrue_pat_b8(SV_VL32), svbic_u8_x(svptrue_pat_b8(SV_VL32), m0_sv, qhbits_sv), 2); - q3bytes_sv = svsub_s8_x(svptrue_pat_b8(SV_VL32), svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), q3bits_sv, m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - svint32_t scale_1 = svsel_s32(svptrue_pat_b32(SV_VL4), svdup_n_s32((int32_t)scale[0]), svdup_n_s32((int32_t)scale[1])); - sumi1_1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), scale_1); - - q3h_sv = svlsl_n_u8_x(svptrue_pat_b8(SV_VL32), svbic_u8_x(svptrue_pat_b8(SV_VL32), m1_sv, qhbits_sv), 1); - q3bytes_sv = svsub_s8_x(svptrue_pat_b8(SV_VL32), svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q3bits_sv, 2), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - scale_1 = svsel_s32(svptrue_pat_b32(SV_VL4), svdup_n_s32((int32_t)scale[2]), svdup_n_s32((int32_t)scale[3])); - sumi1_1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), scale_1); - - scale += 4; - q8bytes_1_sv_1 = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - q8bytes_1_sv_2 = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); - q8_sv += 32; - - q3h_sv = svbic_u8_x(svptrue_pat_b8(SV_VL32), m2_sv, qhbits_sv); - q3bytes_sv = svsub_s8_x(svptrue_pat_b8(SV_VL32), svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q3bits_sv, 4), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - scale_1 = svsel_s32(svptrue_pat_b32(SV_VL4), svdup_n_s32((int32_t)scale[0]), svdup_n_s32((int32_t)scale[1])); - sumi1_1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), scale_1); - - q3h_sv = svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), svbic_u8_x(svptrue_pat_b8(SV_VL32), m3_sv, qhbits_sv), 1); - q3bytes_sv = svsub_s8_x(svptrue_pat_b8(SV_VL32), svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q3bits_sv, 6), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); - - scale_1 = svsel_s32(svptrue_pat_b32(SV_VL4), svdup_n_s32((int32_t)scale[2]), svdup_n_s32((int32_t)scale[3])); - sumi1_1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), scale_1); - - if (j == 0) { - qhbits_sv = svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), qhbits_sv, 4); - } - - scale += 4; - } - - sum += d * (svaddv_s32(svptrue_pat_b32(SV_VL8), sumi1_1)); - } break; - default: - assert(false && "Unsupported vector length"); - break; - } - } - *s = sum; - -#elif __ARM_NEON - - uint32_t aux[3]; - uint32_t utmp[4]; - - const uint8x16_t m3b = vdupq_n_u8(0x3); - const int32x4_t vzero = vdupq_n_s32(0); - - const uint8x16_t m0 = vdupq_n_u8(1); - const uint8x16_t m1 = vshlq_n_u8(m0, 1); - const uint8x16_t m2 = vshlq_n_u8(m0, 2); - const uint8x16_t m3 = vshlq_n_u8(m0, 3); - const int8_t m32 = 32; - - mllm_int8x16x4_t q3bytes; - - float sum = 0; - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *__restrict q3 = x[i].qs; - const uint8_t *__restrict qh = x[i].hmask; - const int8_t *__restrict q8 = y[i].qs; - - mllm_uint8x16x2_t qhbits = mllm_vld1q_u8_x2(qh); - - mllm_uint8x16x4_t q3h; - - int32_t isum = 0; - - // Set up scales - memcpy(aux, x[i].scales, 12); - utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); - utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); - utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); - utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); - - int8_t *scale = (int8_t *)utmp; - for (int j = 0; j < 16; ++j) scale[j] -= m32; - - for (int j = 0; j < QK_K / 128; ++j) { - const mllm_uint8x16x2_t q3bits = mllm_vld1q_u8_x2(q3); - q3 += 32; - const mllm_int8x16x4_t q8bytes_1 = mllm_vld1q_s8_x4(q8); - q8 += 64; - const mllm_int8x16x4_t q8bytes_2 = mllm_vld1q_s8_x4(q8); - q8 += 64; - - q3h.val[0] = vshlq_n_u8(vbicq_u8(m0, qhbits.val[0]), 2); - q3h.val[1] = vshlq_n_u8(vbicq_u8(m0, qhbits.val[1]), 2); - q3h.val[2] = vshlq_n_u8(vbicq_u8(m1, qhbits.val[0]), 1); - q3h.val[3] = vshlq_n_u8(vbicq_u8(m1, qhbits.val[1]), 1); - - q3bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(q3bits.val[0], m3b)), vreinterpretq_s8_u8(q3h.val[0])); - q3bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(q3bits.val[1], m3b)), vreinterpretq_s8_u8(q3h.val[1])); - q3bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[0], 2), m3b)), vreinterpretq_s8_u8(q3h.val[2])); - q3bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[1], 2), m3b)), vreinterpretq_s8_u8(q3h.val[3])); - - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[0], q8bytes_1.val[0])) * scale[0]; - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[1], q8bytes_1.val[1])) * scale[1]; - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[2], q8bytes_1.val[2])) * scale[2]; - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[3], q8bytes_1.val[3])) * scale[3]; - - scale += 4; - - q3h.val[0] = vbicq_u8(m2, qhbits.val[0]); - q3h.val[1] = vbicq_u8(m2, qhbits.val[1]); - q3h.val[2] = vshrq_n_u8(vbicq_u8(m3, qhbits.val[0]), 1); - q3h.val[3] = vshrq_n_u8(vbicq_u8(m3, qhbits.val[1]), 1); - - q3bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[0], 4), m3b)), vreinterpretq_s8_u8(q3h.val[0])); - q3bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[1], 4), m3b)), vreinterpretq_s8_u8(q3h.val[1])); - q3bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[0], 6), m3b)), vreinterpretq_s8_u8(q3h.val[2])); - q3bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[1], 6), m3b)), vreinterpretq_s8_u8(q3h.val[3])); - - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[0], q8bytes_2.val[0])) * scale[0]; - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[1], q8bytes_2.val[1])) * scale[1]; - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[2], q8bytes_2.val[2])) * scale[2]; - isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[3], q8bytes_2.val[3])) * scale[3]; - - scale += 4; - - if (j == 0) { - qhbits.val[0] = vshrq_n_u8(qhbits.val[0], 4); - qhbits.val[1] = vshrq_n_u8(qhbits.val[1], 4); - } - } - sum += d * isum; - } - - *s = sum; - -#elif defined __AVX2__ - - const __m256i m3 = _mm256_set1_epi8(3); - const __m256i mone = _mm256_set1_epi8(1); - const __m128i m32 = _mm_set1_epi8(32); - - __m256 acc = _mm256_setzero_ps(); - - uint32_t aux[3]; - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *__restrict q3 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - // Set up scales - memcpy(aux, x[i].scales, 12); - __m128i scales128 = _mm_set_epi32( - ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4), - ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4), - (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4), - (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4)); - scales128 = _mm_sub_epi8(scales128, m32); - const __m256i all_scales = _mm256_cvtepi8_epi16(scales128); - const __m128i l_scales = _mm256_extracti128_si256(all_scales, 0); - const __m128i h_scales = _mm256_extracti128_si256(all_scales, 1); - const __m256i scales[2] = {MM256_SET_M128I(l_scales, l_scales), MM256_SET_M128I(h_scales, h_scales)}; - - // high bit - const __m256i hbits = _mm256_loadu_si256((const __m256i *)x[i].hmask); - - // integer accumulator - __m256i sumi = _mm256_setzero_si256(); - - int bit = 0; - int is = 0; - - for (int j = 0; j < QK_K / 128; ++j) { - // load low 2 bits - const __m256i q3bits = _mm256_loadu_si256((const __m256i *)q3); - q3 += 32; - - // prepare low and high bits - const __m256i q3l_0 = _mm256_and_si256(q3bits, m3); - const __m256i q3h_0 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); - ++bit; - - const __m256i q3l_1 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 2), m3); - const __m256i q3h_1 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); - ++bit; - - const __m256i q3l_2 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 4), m3); - const __m256i q3h_2 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); - ++bit; - - const __m256i q3l_3 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 6), m3); - const __m256i q3h_3 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); - ++bit; - - // load Q8 quants - const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_3 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - - // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm256_maddubs_epi16, - // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set, - // and 2 if the high bit was set) - __m256i q8s_0 = _mm256_maddubs_epi16(q3h_0, q8_0); - __m256i q8s_1 = _mm256_maddubs_epi16(q3h_1, q8_1); - __m256i q8s_2 = _mm256_maddubs_epi16(q3h_2, q8_2); - __m256i q8s_3 = _mm256_maddubs_epi16(q3h_3, q8_3); - - __m256i p16_0 = _mm256_maddubs_epi16(q3l_0, q8_0); - __m256i p16_1 = _mm256_maddubs_epi16(q3l_1, q8_1); - __m256i p16_2 = _mm256_maddubs_epi16(q3l_2, q8_2); - __m256i p16_3 = _mm256_maddubs_epi16(q3l_3, q8_3); - - p16_0 = _mm256_sub_epi16(p16_0, q8s_0); - p16_1 = _mm256_sub_epi16(p16_1, q8s_1); - p16_2 = _mm256_sub_epi16(p16_2, q8s_2); - p16_3 = _mm256_sub_epi16(p16_3, q8s_3); - - // multiply with scales - p16_0 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 0)), p16_0); - p16_1 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 1)), p16_1); - p16_2 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 2)), p16_2); - p16_3 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 3)), p16_3); - - // accumulate - p16_0 = _mm256_add_epi32(p16_0, p16_1); - p16_2 = _mm256_add_epi32(p16_2, p16_3); - sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_2)); - } - - // multiply with block scale and accumulate - acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); - } - - *s = hsum_float_8(acc); - -#elif defined __AVX__ - - const __m128i m3 = _mm_set1_epi8(3); - const __m128i mone = _mm_set1_epi8(1); - const __m128i m32 = _mm_set1_epi8(32); - const __m128i m2 = _mm_set1_epi8(2); - - __m256 acc = _mm256_setzero_ps(); - - const uint32_t *aux; - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *__restrict q3 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - // Set up scales - aux = (const uint32_t *)x[i].scales; - __m128i scales128 = _mm_set_epi32( - ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4), - ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4), - (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4), - (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4)); - scales128 = _mm_sub_epi8(scales128, m32); - const __m128i scales_0 = _mm_cvtepi8_epi16(scales128); - const __m128i scales_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(scales128, scales128)); - const __m128i scales[2] = {scales_0, scales_1}; - - // high bit *128*2 from block_q3_K.hmask[QK_K/8] - const __m128i hbits_0 = _mm_loadu_si128((const __m128i *)&x[i].hmask[0]); - const __m128i hbits_1 = _mm_loadu_si128((const __m128i *)&x[i].hmask[16]); - - // integer accumulator - __m128i sumi_0 = _mm_setzero_si128(); - __m128i sumi_1 = _mm_setzero_si128(); - - for (int j = 0; j < QK_K / 128; ++j) { - // load low 2 bits *64*2 from block_q3_K.qs[QK_K/4] - const __m128i q3bits_0 = _mm_loadu_si128((const __m128i *)q3); - q3 += 16; - const __m128i q3bits_1 = _mm_loadu_si128((const __m128i *)q3); - q3 += 16; - - // prepare low and high bits - const int bit = j << 2; - - const __m128i q3l_0 = _mm_and_si128(q3bits_0, m3); - const __m128i q3l_1 = _mm_and_si128(q3bits_1, m3); - const __m128i q3h_0 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit)), bit), 2); - const __m128i q3h_1 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit)), bit), 2); - - const __m128i q3l_2 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 2), m3); - const __m128i q3l_3 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 2), m3); - const __m128i q3h_2 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit + 1)), bit + 1), 2); - const __m128i q3h_3 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit + 1)), bit + 1), 2); - - const __m128i q3l_4 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 4), m3); - const __m128i q3l_5 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 4), m3); - const __m128i q3h_4 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit + 2)), bit + 2), 2); - const __m128i q3h_5 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit + 2)), bit + 2), 2); - - const __m128i q3l_6 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 6), m3); - const __m128i q3l_7 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 6), m3); - const __m128i q3h_6 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit + 3)), bit + 3), 2); - const __m128i q3h_7 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit + 3)), bit + 3), 2); - - // load Q8 quants from block_q8_K.qs[QK_K] - const __m128i q8_0 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_1 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_2 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_3 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_4 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_5 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_6 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_7 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - - // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm256_maddubs_epi16, - // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set, - // and 2 if the high bit was set) - __m128i q8s_0 = _mm_maddubs_epi16(q3h_0, q8_0); - __m128i q8s_1 = _mm_maddubs_epi16(q3h_1, q8_1); - __m128i q8s_2 = _mm_maddubs_epi16(q3h_2, q8_2); - __m128i q8s_3 = _mm_maddubs_epi16(q3h_3, q8_3); - __m128i q8s_4 = _mm_maddubs_epi16(q3h_4, q8_4); - __m128i q8s_5 = _mm_maddubs_epi16(q3h_5, q8_5); - __m128i q8s_6 = _mm_maddubs_epi16(q3h_6, q8_6); - __m128i q8s_7 = _mm_maddubs_epi16(q3h_7, q8_7); - - __m128i p16_0 = _mm_maddubs_epi16(q3l_0, q8_0); - __m128i p16_1 = _mm_maddubs_epi16(q3l_1, q8_1); - __m128i p16_2 = _mm_maddubs_epi16(q3l_2, q8_2); - __m128i p16_3 = _mm_maddubs_epi16(q3l_3, q8_3); - __m128i p16_4 = _mm_maddubs_epi16(q3l_4, q8_4); - __m128i p16_5 = _mm_maddubs_epi16(q3l_5, q8_5); - __m128i p16_6 = _mm_maddubs_epi16(q3l_6, q8_6); - __m128i p16_7 = _mm_maddubs_epi16(q3l_7, q8_7); - - p16_0 = _mm_sub_epi16(p16_0, q8s_0); - p16_1 = _mm_sub_epi16(p16_1, q8s_1); - p16_2 = _mm_sub_epi16(p16_2, q8s_2); - p16_3 = _mm_sub_epi16(p16_3, q8s_3); - p16_4 = _mm_sub_epi16(p16_4, q8s_4); - p16_5 = _mm_sub_epi16(p16_5, q8s_5); - p16_6 = _mm_sub_epi16(p16_6, q8s_6); - p16_7 = _mm_sub_epi16(p16_7, q8s_7); - - // multiply with scales - __m128i shuffle = _mm_set1_epi16(0x0100); - p16_0 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_0); - shuffle = _mm_add_epi16(shuffle, m2); - p16_1 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_1); - shuffle = _mm_add_epi16(shuffle, m2); - p16_2 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_2); - shuffle = _mm_add_epi16(shuffle, m2); - p16_3 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_3); - shuffle = _mm_add_epi16(shuffle, m2); - p16_4 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_4); - shuffle = _mm_add_epi16(shuffle, m2); - p16_5 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_5); - shuffle = _mm_add_epi16(shuffle, m2); - p16_6 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_6); - shuffle = _mm_add_epi16(shuffle, m2); - p16_7 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_7); - - // accumulate - p16_0 = _mm_add_epi32(p16_0, p16_1); - p16_2 = _mm_add_epi32(p16_2, p16_3); - p16_4 = _mm_add_epi32(p16_4, p16_5); - p16_6 = _mm_add_epi32(p16_6, p16_7); - sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); - sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_4, p16_6)); - } - - // multiply with block scale and accumulate - __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); - acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi)), acc); - } - - *s = hsum_float_8(acc); - -#elif defined __wasm_simd128__ - int8_t aux8[QK_K]; - float sums[8] = {0}; - uint32_t auxs[4]; - - float sumf = 0; - for (int i = 0; i < nb; ++i) { - const uint8_t *__restrict q3 = x[i].qs; - const uint8_t *__restrict hm = x[i].hmask; - const int8_t *__restrict q8 = y[i].qs; - - // Process blocks with SIMD - int8_t *a = aux8; - uint8_t m = 1; - for (int j = 0; j < QK_K; j += 128) { - for (int shift = 0; shift <= 6; shift += 2) { - v128_t v_m = wasm_i8x16_splat(m); - for (int l = 0; l < 32; l += 16) { - v128_t v_q3 = wasm_v128_load(q3 + l); - v128_t v_shift = wasm_i8x16_shr(v_q3, shift); - v128_t v_low2 = wasm_v128_and(v_shift, wasm_i8x16_splat(0x03)); - - v128_t v_hm = wasm_v128_load(hm + l); - v128_t v_mask = wasm_v128_and(v_hm, v_m); - v_mask = wasm_i8x16_ne(v_mask, wasm_i8x16_splat(0)); - - v_low2 = wasm_i8x16_sub(v_low2, wasm_v128_and(wasm_i8x16_splat(4), wasm_v128_not(v_mask))); - wasm_v128_store(a + l, v_low2); - } - a += 32; - m <<= 1; - } - q3 += 32; - } - - // Extract scales - memcpy(auxs, x[i].scales, 12); - uint32_t tmp = auxs[2]; - auxs[2] = ((auxs[0] >> 4) & kmask2) | (((tmp >> 4) & kmask1) << 4); - auxs[3] = ((auxs[1] >> 4) & kmask2) | (((tmp >> 6) & kmask1) << 4); - auxs[0] = (auxs[0] & kmask2) | (((tmp >> 0) & kmask1) << 4); - auxs[1] = (auxs[1] & kmask2) | (((tmp >> 2) & kmask1) << 4); - const int8_t *scales = (const int8_t *)auxs; - - // SIMD dot product with register accumulators - v128_t v_acc0 = wasm_i32x4_splat(0); - v128_t v_acc1 = wasm_i32x4_splat(0); - a = aux8; - for (int j = 0; j < QK_K / 16; ++j) { - const v128_t v_scale = wasm_i16x8_splat(scales[j] - 32); - - // Process 16 elements per iteration - for (int k = 0; k < 2; ++k) { - const v128_t v_q8 = wasm_i16x8_load8x8(q8); - const v128_t v_a = wasm_i16x8_load8x8(a); - - v128_t v_prod = wasm_i16x8_mul(v_q8, v_a); - v_prod = wasm_i16x8_mul(v_prod, v_scale); - - v_acc0 = wasm_i32x4_add(v_acc0, wasm_i32x4_extend_low_i16x8(v_prod)); - v_acc1 = wasm_i32x4_add(v_acc1, wasm_i32x4_extend_high_i16x8(v_prod)); - - q8 += 8; - a += 8; - } - } - - // Accumulate results - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - const v128_t v_d = wasm_f32x4_splat(d); - v128_t v_sum = wasm_f32x4_add( - wasm_f32x4_mul(wasm_f32x4_convert_i32x4(v_acc0), v_d), - wasm_f32x4_mul(wasm_f32x4_convert_i32x4(v_acc1), v_d)); - - // Accumulate into sums vector - wasm_v128_store(sums, wasm_f32x4_add(wasm_v128_load(sums), v_sum)); - } - - // Horizontal sum - v128_t v_sum = wasm_f32x4_add(wasm_v128_load(sums), wasm_v128_load(sums + 4)); - sumf = wasm_f32x4_extract_lane(v_sum, 0) + wasm_f32x4_extract_lane(v_sum, 1) + wasm_f32x4_extract_lane(v_sum, 2) + wasm_f32x4_extract_lane(v_sum, 3); - - *s = sumf; - -#elif defined __riscv_v_intrinsic - - uint32_t aux[3]; - uint32_t utmp[4]; - - const int vector_length = __riscv_vlenb() * 8; - float sumf = 0; - - switch (vector_length) { - case 256: - for (int i = 0; i < nb; ++i) { - const uint8_t *__restrict q3 = x[i].qs; - const uint8_t *__restrict qh = x[i].hmask; - const int8_t *__restrict q8 = y[i].qs; - - memcpy(aux, x[i].scales, 12); - utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); - utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); - utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); - utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); - - int8_t *scale = (int8_t *)utmp; - for (int j = 0; j < 16; ++j) scale[j] -= 32; - - size_t vl = 32; - uint8_t m = 1; - - vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); - vuint8m1_t vqh = __riscv_vle8_v_u8m1(qh, vl); - - int sum_t = 0; - - for (int j = 0; j < QK_K; j += 128) { - vl = 32; - - // load Q3 - vuint8m1_t q3_x = __riscv_vle8_v_u8m1(q3, vl); - - vint8m1_t q3_0 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(q3_x, 0x03, vl)); - vint8m1_t q3_1 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q3_x, 0x2, vl), 0x03, vl)); - vint8m1_t q3_2 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q3_x, 0x4, vl), 0x03, vl)); - vint8m1_t q3_3 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q3_x, 0x6, vl), 0x03, vl)); - - // compute mask for subtraction - vuint8m1_t qh_m0 = __riscv_vand_vx_u8m1(vqh, m, vl); - vbool8_t vmask_0 = __riscv_vmseq_vx_u8m1_b8(qh_m0, 0, vl); - vint8m1_t q3_m0 = __riscv_vsub_vx_i8m1_mu(vmask_0, q3_0, q3_0, 0x4, vl); - m <<= 1; - - vuint8m1_t qh_m1 = __riscv_vand_vx_u8m1(vqh, m, vl); - vbool8_t vmask_1 = __riscv_vmseq_vx_u8m1_b8(qh_m1, 0, vl); - vint8m1_t q3_m1 = __riscv_vsub_vx_i8m1_mu(vmask_1, q3_1, q3_1, 0x4, vl); - m <<= 1; - - vuint8m1_t qh_m2 = __riscv_vand_vx_u8m1(vqh, m, vl); - vbool8_t vmask_2 = __riscv_vmseq_vx_u8m1_b8(qh_m2, 0, vl); - vint8m1_t q3_m2 = __riscv_vsub_vx_i8m1_mu(vmask_2, q3_2, q3_2, 0x4, vl); - m <<= 1; - - vuint8m1_t qh_m3 = __riscv_vand_vx_u8m1(vqh, m, vl); - vbool8_t vmask_3 = __riscv_vmseq_vx_u8m1_b8(qh_m3, 0, vl); - vint8m1_t q3_m3 = __riscv_vsub_vx_i8m1_mu(vmask_3, q3_3, q3_3, 0x4, vl); - m <<= 1; - - // load Q8 and take product with Q3 - vint16m2_t a0 = __riscv_vwmul_vv_i16m2(q3_m0, __riscv_vle8_v_i8m1(q8, vl), vl); - vint16m2_t a1 = __riscv_vwmul_vv_i16m2(q3_m1, __riscv_vle8_v_i8m1(q8 + 32, vl), vl); - vint16m2_t a2 = __riscv_vwmul_vv_i16m2(q3_m2, __riscv_vle8_v_i8m1(q8 + 64, vl), vl); - vint16m2_t a3 = __riscv_vwmul_vv_i16m2(q3_m3, __riscv_vle8_v_i8m1(q8 + 96, vl), vl); - - vl = 16; - - // retrieve lane to multiply with scale - vint32m2_t aux0_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a0, 0), (scale[0]), vl); - vint32m2_t aux0_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a0, 1), (scale[1]), vl); - vint32m2_t aux1_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a1, 0), (scale[2]), vl); - vint32m2_t aux1_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a1, 1), (scale[3]), vl); - vint32m2_t aux2_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a2, 0), (scale[4]), vl); - vint32m2_t aux2_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a2, 1), (scale[5]), vl); - vint32m2_t aux3_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a3, 0), (scale[6]), vl); - vint32m2_t aux3_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a3, 1), (scale[7]), vl); - - vint32m1_t isum0 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux0_0, aux0_1, vl), vzero, vl); - vint32m1_t isum1 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux1_0, aux1_1, vl), isum0, vl); - vint32m1_t isum2 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux2_0, aux2_1, vl), isum1, vl); - vint32m1_t isum3 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux3_0, aux3_1, vl), isum2, vl); - - sum_t += __riscv_vmv_x_s_i32m1_i32(isum3); - - q3 += 32; - q8 += 128; - scale += 8; - } - - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - - sumf += d * sum_t; - } - break; - case 128: - for (int i = 0; i < nb; ++i) { - const uint8_t *restrict q3 = x[i].qs; - const uint8_t *restrict qh = x[i].hmask; - const int8_t *restrict q8 = y[i].qs; - - int8_t *scale = (int8_t *)utmp; - int tmp; - __asm__ __volatile__( - "vsetivli zero, 12, e8, m1\n\t" - "vle8.v v0, (%[s6b])\n\t" - "vmv1r.v v2, v0\n\t" - "vsetivli zero, 2, e64, m1\n\t" - "vmv.v.x v9, %[sh]\n\t" - "vslidedown.vi v1, v0, 1\n\t" - "vslide1up.vx v8, v9, zero\n\t" // {0, 0, 4, 4} - "vslideup.vi v0, v2, 1\n\t" // {aux[0], aux[1], aux[0], aux[1]} - "vsetivli zero, 4, e32, m1\n\t" - "vid.v v9\n\t" - "vmv.x.s %[tmp], v1\n\t" - "vsll.vi v9, v9, 1\n\t" // {0, 2, 4, 6} - "vmv.v.x v1, %[tmp]\n\t" // {aux[2], aux[2], aux[2], aux[2]} - "vsrl.vv v4, v1, v9\n\t" - "vsrl.vv v2, v0, v8\n\t" - "vand.vx v5, v4, %[kmask1]\n\t" - "vand.vx v3, v2, %[kmask2]\n\t" - "vsll.vi v6, v5, 4\n\t" - "vor.vv v7, v6, v3\n\t" - "vsetivli zero, 16, e8, m1\n\t" - "vsub.vx v0, v7, %[c]\n\t" - "vse8.v v0, (%[scale])" - : [tmp] "=&r"(tmp) - : [sh] "r"(0x0000000400000004), [s6b] "r"(x[i].scales), [c] "r"(32), [scale] "r"(scale), [kmask1] "r"(kmask1), [kmask2] "r"(kmask2) - : "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); - - uint8_t m = 1; - int isum = 0; - for (int j = 0; j < QK_K; j += 128) { - __asm__ __volatile__( - "vsetvli zero, %[vl32], e8, m2, ta, mu\n\t" - "vle8.v v8, (%[q3])\n\t" - "vsrl.vi v10, v8, 2\n\t" - "vsrl.vi v12, v8, 4\n\t" - "vsrl.vi v14, v8, 6\n\t" - "vand.vi v8, v8, 3\n\t" - "vand.vi v10, v10, 3\n\t" - "vand.vi v12, v12, 3\n\t" - "vle8.v v2, (%[qh])\n\t" - "vand.vx v4, v2, %[m]\n\t" - "slli %[m], %[m], 1\n\t" - "vmseq.vx v0, v4, zero\n\t" - "vadd.vi v8, v8, -4, v0.t\n\t" - "vand.vx v4, v2, %[m]\n\t" - "slli %[m], %[m], 1\n\t" - "vmseq.vx v0, v4, zero\n\t" - "vadd.vi v10, v10, -4, v0.t\n\t" - "vand.vx v4, v2, %[m]\n\t" - "slli %[m], %[m], 1\n\t" - "vmseq.vx v0, v4, zero\n\t" - "vadd.vi v12, v12, -4, v0.t\n\t" - "vand.vx v4, v2, %[m]\n\t" - "slli %[m], %[m], 1\n\t" - "vmseq.vx v0, v4, zero\n\t" - "vadd.vi v14, v14, -4, v0.t\n\t" - "vsetvli zero, %[vl128], e8, m8\n\t" - "vle8.v v0, (%[q8])\n\t" - "vsetvli zero, %[vl64], e8, m4\n\t" - "vwmul.vv v16, v0, v8\n\t" - "vwmul.vv v24, v4, v12\n\t" - "vsetivli zero, 16, e16, m2\n\t" - "vmv.v.x v0, zero\n\t" - "vwredsum.vs v10, v16, v0\n\t" - "vwredsum.vs v9, v18, v0\n\t" - "vwredsum.vs v8, v20, v0\n\t" - "vwredsum.vs v7, v22, v0\n\t" - "vwredsum.vs v11, v24, v0\n\t" - "vwredsum.vs v12, v26, v0\n\t" - "vwredsum.vs v13, v28, v0\n\t" - "vwredsum.vs v14, v30, v0\n\t" - "vsetivli zero, 4, e32, m1\n\t" - "vslideup.vi v10, v9, 1\n\t" - "vslideup.vi v8, v7, 1\n\t" - "vslideup.vi v11, v12, 1\n\t" - "vslideup.vi v13, v14, 1\n\t" - "vslideup.vi v10, v8, 2\n\t" - "vslideup.vi v11, v13, 2\n\t" - "vsetivli zero, 8, e32, m2\n\t" - "vle8.v v15, (%[scale])\n\t" - "vsext.vf4 v12, v15\n\t" - "vmul.vv v10, v10, v12\n\t" - "vredsum.vs v0, v10, v0\n\t" - "vmv.x.s %[tmp], v0\n\t" - "add %[isum], %[isum], %[tmp]" - : [tmp] "=&r"(tmp), [m] "+&r"(m), [isum] "+&r"(isum) - : [vl128] "r"(128), [vl64] "r"(64), [vl32] "r"(32), [q3] "r"(q3), [qh] "r"(qh), [scale] "r"(scale), [q8] "r"(q8) - : "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); - q3 += 32; - q8 += 128; - scale += 8; - } - - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - sumf += d * isum; - } - break; - default: - assert(false && "Unsupported vector length"); - break; - } - - *s = sumf; - -#elif defined(__POWER9_VECTOR__) - const vector signed char lowMask = vec_splats((signed char)0x3); - const vector signed char lowMask1 = vec_splats((int8_t)0xf); - const vector signed char lowMask2 = vec_splats((int8_t)0x30); - const vector int v0 = vec_splats((int32_t)0); - const vector signed char v1 = vec_splats((signed char)0x1); - const vector unsigned char v2 = vec_splats((unsigned char)0x2); - const vector unsigned char v3 = vec_splats((unsigned char)0x3); - const vector unsigned char v4 = vec_splats((unsigned char)0x4); - const vector unsigned char v6 = vec_splats((unsigned char)0x6); - const vector signed char off = vec_splats((signed char)0x20); - - vector float vsumf0 = vec_splats(0.0f); - vector float vsumf1 = vec_splats(0.0f); - vector float vsumf2 = vec_splats(0.0f); - vector float vsumf3 = vec_splats(0.0f); - - for (int i = 0; i < nb; ++i) { - vector float vxd = vec_splats(MLLM_FP16_TO_FP32(x[i].d)); - vector float vyd = vec_splats(y[i].d); - vector float vd = vec_mul(vxd, vyd); - - UNUSED(kmask1); - UNUSED(kmask2); - - vector signed char u0 = (vector signed char)vec_xl_len(x[i].scales, 8); - vector signed char u1 = vec_and(u0, lowMask1); - vector signed char u2 = (vector signed char)vec_xl_len(x[i].scales + 8, 4); - vector signed char u3 = (vector signed char)vec_mergeh((vector signed int)u2, (vector signed int)vec_sr(u2, v2)); - vector signed char u30 = vec_sl(vec_and(u3, lowMask), v4); - vector signed char u31 = vec_and(u3, lowMask2); - - u1 = vec_or(u1, u30); - u2 = vec_or(vec_sr(u0, v4), u31); - - vector signed char vscales = (vector signed char)vec_mergeh((vector signed long long)u1, (vector signed long long)u2); - vector signed char qxhs0 = (vector signed char)vec_xl(0, x[i].hmask); - vector signed char qxhs1 = (vector signed char)vec_xl(16, x[i].hmask); - - vscales = vec_sub(vscales, off); - - vector signed int vsumi0 = v0; - vector signed int vsumi1 = v0; - vector signed int vsumi2 = v0; - vector signed int vsumi3 = v0; - vector signed int vsumi4 = v0; - vector signed int vsumi5 = v0; - vector signed int vsumi6 = v0; - vector signed int vsumi7 = v0; - - const uint8_t *__restrict q3 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - for (int j = 0; j < QK_K / 128; ++j) { - __builtin_prefetch(q3, 0, 1); - __builtin_prefetch(q8, 0, 1); - - vector signed char qxs0 = (vector signed char)vec_xl(0, q3); - vector signed char qxs1 = (vector signed char)vec_xl(16, q3); - q3 += 32; - - // the low 2 bits - vector signed char qxs00 = vec_and(qxs0, lowMask); - vector signed char qxs01 = vec_and(vec_sr(qxs0, v2), lowMask); - vector signed char qxs02 = vec_and(vec_sr(qxs0, v4), lowMask); - vector signed char qxs03 = vec_and(vec_sr(qxs0, v6), lowMask); - vector signed char qxs10 = vec_and(qxs1, lowMask); - vector signed char qxs11 = vec_and(vec_sr(qxs1, v2), lowMask); - vector signed char qxs12 = vec_and(vec_sr(qxs1, v4), lowMask); - vector signed char qxs13 = vec_and(vec_sr(qxs1, v6), lowMask); - - // the 3rd bit - vector signed char qxh00 = vec_sl(vec_andc(v1, qxhs0), v2); - vector signed char qxh01 = vec_sl(vec_andc(v1, vec_sr(qxhs0, (vector unsigned char)v1)), v2); - vector signed char qxh02 = vec_sl(vec_andc(v1, vec_sr(qxhs0, v2)), v2); - vector signed char qxh03 = vec_sl(vec_andc(v1, vec_sr(qxhs0, v3)), v2); - vector signed char qxh10 = vec_sl(vec_andc(v1, qxhs1), v2); - vector signed char qxh11 = vec_sl(vec_andc(v1, vec_sr(qxhs1, (vector unsigned char)v1)), v2); - vector signed char qxh12 = vec_sl(vec_andc(v1, vec_sr(qxhs1, v2)), v2); - vector signed char qxh13 = vec_sl(vec_andc(v1, vec_sr(qxhs1, v3)), v2); - qxhs0 = vec_sr(qxhs0, v4); - qxhs1 = vec_sr(qxhs1, v4); - - vector signed char q3x00 = vec_sub(qxs00, qxh00); - vector signed char q3x01 = vec_sub(qxs01, qxh01); - vector signed char q3x02 = vec_sub(qxs02, qxh02); - vector signed char q3x03 = vec_sub(qxs03, qxh03); - vector signed char q3x10 = vec_sub(qxs10, qxh10); - vector signed char q3x11 = vec_sub(qxs11, qxh11); - vector signed char q3x12 = vec_sub(qxs12, qxh12); - vector signed char q3x13 = vec_sub(qxs13, qxh13); - - vector signed char q8y00 = vec_xl(0, q8); - vector signed char q8y10 = vec_xl(16, q8); - vector signed char q8y01 = vec_xl(32, q8); - vector signed char q8y11 = vec_xl(48, q8); - vector signed char q8y02 = vec_xl(64, q8); - vector signed char q8y12 = vec_xl(80, q8); - vector signed char q8y03 = vec_xl(96, q8); - vector signed char q8y13 = vec_xl(112, q8); - q8 += 128; - - vector signed short vscales_h = vec_unpackh(vscales); - vector signed short vs0 = vec_splat(vscales_h, 0); - vector signed short vs1 = vec_splat(vscales_h, 1); - vector signed short vs2 = vec_splat(vscales_h, 2); - vector signed short vs3 = vec_splat(vscales_h, 3); - vector signed short vs4 = vec_splat(vscales_h, 4); - vector signed short vs5 = vec_splat(vscales_h, 5); - vector signed short vs6 = vec_splat(vscales_h, 6); - vector signed short vs7 = vec_splat(vscales_h, 7); - vscales = vec_sld(vscales, vscales, 8); - - vector signed short qv00 = vec_add(vec_mule(q3x00, q8y00), vec_mulo(q3x00, q8y00)); - vector signed short qv01 = vec_add(vec_mule(q3x01, q8y01), vec_mulo(q3x01, q8y01)); - vector signed short qv02 = vec_add(vec_mule(q3x02, q8y02), vec_mulo(q3x02, q8y02)); - vector signed short qv03 = vec_add(vec_mule(q3x03, q8y03), vec_mulo(q3x03, q8y03)); - vector signed short qv10 = vec_add(vec_mule(q3x10, q8y10), vec_mulo(q3x10, q8y10)); - vector signed short qv11 = vec_add(vec_mule(q3x11, q8y11), vec_mulo(q3x11, q8y11)); - vector signed short qv12 = vec_add(vec_mule(q3x12, q8y12), vec_mulo(q3x12, q8y12)); - vector signed short qv13 = vec_add(vec_mule(q3x13, q8y13), vec_mulo(q3x13, q8y13)); - - vsumi0 = vec_msum(qv00, vs0, vsumi0); - vsumi1 = vec_msum(qv01, vs2, vsumi1); - vsumi2 = vec_msum(qv02, vs4, vsumi2); - vsumi3 = vec_msum(qv03, vs6, vsumi3); - vsumi4 = vec_msum(qv10, vs1, vsumi4); - vsumi5 = vec_msum(qv11, vs3, vsumi5); - vsumi6 = vec_msum(qv12, vs5, vsumi6); - vsumi7 = vec_msum(qv13, vs7, vsumi7); - } - - vsumi0 = vec_add(vsumi0, vsumi4); - vsumi1 = vec_add(vsumi1, vsumi5); - vsumi2 = vec_add(vsumi2, vsumi6); - vsumi3 = vec_add(vsumi3, vsumi7); - - vsumf0 = vec_madd(vec_ctf(vsumi0, 0), vd, vsumf0); - vsumf1 = vec_madd(vec_ctf(vsumi1, 0), vd, vsumf1); - vsumf2 = vec_madd(vec_ctf(vsumi2, 0), vd, vsumf2); - vsumf3 = vec_madd(vec_ctf(vsumi3, 0), vd, vsumf3); - } - - vsumf0 = vec_add(vsumf0, vsumf2); - vsumf1 = vec_add(vsumf1, vsumf3); - - vsumf0 = vec_add(vsumf0, vsumf1); - - vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 4)); - vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 8)); - - *s = vec_extract(vsumf0, 0); - -#elif defined __loongarch_asx - - const __m128i m32 = __lsx_vreplgr2vr_b(32); - - __m256 acc = (__m256)__lasx_xvldi(0); - - uint32_t aux[3]; - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - const uint8_t *__restrict q3 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - // Set up scales - memcpy(aux, x[i].scales, 12); - __m128i scales128 = lsx_set_w( - ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4), - ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4), - (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4), - (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4)); - scales128 = __lsx_vsub_b(scales128, m32); - - const v16i8 shuffle_mask = {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15}; - const __m256i scales_shuffled = lasx_ext8_16(__lsx_vshuf_b(scales128, scales128, (__m128i)shuffle_mask)); - - // high bit - const __m256i hbits = __lasx_xvld((const __m256i *)x[i].hmask, 0); - - // integer accumulator - __m256i sumi = __lasx_xvldi(0); - - for (int j = 0; j < QK_K / 128; ++j) { - // load low 2 bits - const __m256i q3bits = __lasx_xvld((const __m256i *)q3, 0); - q3 += 32; - - // prepare low and high bits - const __m256i q3l_0 = __lasx_xvandi_b(q3bits, 3); - const __m256i q3l_1 = __lasx_xvandi_b(__lasx_xvsrli_b(q3bits, 2), 3); - const __m256i q3l_2 = __lasx_xvandi_b(__lasx_xvsrli_b(q3bits, 4), 3); - const __m256i q3l_3 = __lasx_xvsrli_b(q3bits, 6); - const __m256i q3h_0 = __lasx_xvslli_b(__lasx_xvseqi_b(lasx_xvandi_b_bit(hbits, 4 * j + 0), 0), 2); - const __m256i q3h_1 = __lasx_xvslli_b(__lasx_xvseqi_b(lasx_xvandi_b_bit(hbits, 4 * j + 1), 0), 2); - const __m256i q3h_2 = __lasx_xvslli_b(__lasx_xvseqi_b(lasx_xvandi_b_bit(hbits, 4 * j + 2), 0), 2); - const __m256i q3h_3 = __lasx_xvslli_b(__lasx_xvseqi_b(lasx_xvandi_b_bit(hbits, 4 * j + 3), 0), 2); - const __m256i q3_0 = __lasx_xvor_v(q3h_0, q3l_0); - const __m256i q3_1 = __lasx_xvor_v(q3h_1, q3l_1); - const __m256i q3_2 = __lasx_xvor_v(q3h_2, q3l_2); - const __m256i q3_3 = __lasx_xvor_v(q3h_3, q3l_3); - - // load Q8 quants - const __m256i q8_0 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - const __m256i q8_1 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - const __m256i q8_2 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - const __m256i q8_3 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - - __m256i p16_0 = lasx_madd_h_b(q8_0, q3_0); - __m256i p16_1 = lasx_madd_h_b(q8_1, q3_1); - __m256i p16_2 = lasx_madd_h_b(q8_2, q3_2); - __m256i p16_3 = lasx_madd_h_b(q8_3, q3_3); - - // multiply with scales - p16_0 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 0), p16_0); - p16_1 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 1), p16_1); - p16_2 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 2), p16_2); - p16_3 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 3), p16_3); - - // accumulate - p16_0 = __lasx_xvadd_w(p16_0, p16_1); - p16_2 = __lasx_xvadd_w(p16_2, p16_3); - sumi = __lasx_xvadd_w(sumi, __lasx_xvadd_w(p16_0, p16_2)); - } - // multiply with block scale and accumulate - acc = __lasx_xvfmadd_s(__lasx_xvreplfr2vr_s(d), __lasx_xvffint_s_w(sumi), acc); - } - - *s = hsum_float_8(acc); -#elif defined(__VXE__) || defined(__VXE2__) - uint32_t aux[3]; - uint32_t utmp[4]; - - const int32x4_t v_z = vec_splat_s32(0); - const uint8x16_t v_3m = vec_splat_u8(0x03); - - const uint8x16_t v_0c = vec_splat_u8(1); - const uint8x16_t v_1c = vec_sl(v_0c, 1); - const uint8x16_t v_2c = vec_sl(v_0c, 2); - const uint8x16_t v_3c = vec_sl(v_0c, 3); - - uint8x16_t q3h[4]; - uint8x16_t q3b[2]; - int8x16_t q3bytes[4]; - int8x16_t q8bytes[4]; - uint8x16_t qhbits[2]; - - float sum = 0; - - for (int i = 0; i < nb; ++i) { - const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); - - const uint8_t *restrict x0l = x[i].qs; - const uint8_t *restrict x0h = x[i].hmask; - const int8_t *restrict y0 = y[i].qs; - - qhbits[0] = vec_xl(0, x0h); - qhbits[1] = vec_xl(16, x0h); - - int32_t isum = 0; - - memcpy(aux, x[i].scales, 12); - utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); - utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); - utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); - utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); - - int8_t *scale = (int8_t *)utmp; - for (int j = 0; j < 16; ++j) scale[j] -= 32; - - for (int j = 0; j < QK_K / 128; ++j) { - int32x4_t isum0, isum1, isum2, isum3; - - q3b[0] = vec_xl(0, x0l); - q3b[1] = vec_xl(16, x0l); - x0l += 32; - - q8bytes[0] = vec_xl(0, y0); - q8bytes[1] = vec_xl(16, y0); - q8bytes[2] = vec_xl(32, y0); - q8bytes[3] = vec_xl(48, y0); - q8bytes[4] = vec_xl(64, y0); - q8bytes[5] = vec_xl(80, y0); - q8bytes[6] = vec_xl(96, y0); - q8bytes[7] = vec_xl(112, y0); - y0 += 128; - - q3h[0] = vec_sl(vec_andc(v_0c, qhbits[0]), 2); - q3h[1] = vec_sl(vec_andc(v_0c, qhbits[1]), 2); - q3h[2] = vec_sl(vec_andc(v_1c, qhbits[0]), 1); - q3h[3] = vec_sl(vec_andc(v_1c, qhbits[1]), 1); - - q3bytes[0] = vec_sub((int8x16_t)vec_and(q3b[0], v_3m), (int8x16_t)q3h[0]); - q3bytes[1] = vec_sub((int8x16_t)vec_and(q3b[1], v_3m), (int8x16_t)q3h[1]); - q3bytes[2] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[0], 2), v_3m), (int8x16_t)q3h[2]); - q3bytes[3] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[1], 2), v_3m), (int8x16_t)q3h[3]); - - isum0 = mllm_vec_dot(v_z, q3bytes[0], q8bytes[0]); - isum1 = mllm_vec_dot(v_z, q3bytes[1], q8bytes[1]); - isum2 = mllm_vec_dot(v_z, q3bytes[2], q8bytes[2]); - isum3 = mllm_vec_dot(v_z, q3bytes[3], q8bytes[3]); - - isum += (isum0[0] + isum0[1] + isum0[2] + isum0[3]) * scale[0]; - isum += (isum1[0] + isum1[1] + isum1[2] + isum1[3]) * scale[1]; - isum += (isum2[0] + isum2[1] + isum2[2] + isum2[3]) * scale[2]; - isum += (isum3[0] + isum3[1] + isum3[2] + isum3[3]) * scale[3]; - - scale += 4; - - q3h[0] = vec_andc(v_2c, qhbits[0]); - q3h[1] = vec_andc(v_2c, qhbits[1]); - q3h[2] = vec_sr(vec_andc(v_3c, qhbits[0]), 1); - q3h[3] = vec_sr(vec_andc(v_3c, qhbits[1]), 1); - - q3bytes[0] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[0], 4), v_3m), (int8x16_t)q3h[0]); - q3bytes[1] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[1], 4), v_3m), (int8x16_t)q3h[1]); - q3bytes[2] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[0], 6), v_3m), (int8x16_t)q3h[2]); - q3bytes[3] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[1], 6), v_3m), (int8x16_t)q3h[3]); - - isum0 = mllm_vec_dot(v_z, q3bytes[0], q8bytes[4]); - isum1 = mllm_vec_dot(v_z, q3bytes[1], q8bytes[5]); - isum2 = mllm_vec_dot(v_z, q3bytes[2], q8bytes[6]); - isum3 = mllm_vec_dot(v_z, q3bytes[3], q8bytes[7]); - - isum += (isum0[0] + isum0[1] + isum0[2] + isum0[3]) * scale[0]; - isum += (isum1[0] + isum1[1] + isum1[2] + isum1[3]) * scale[1]; - isum += (isum2[0] + isum2[1] + isum2[2] + isum2[3]) * scale[2]; - isum += (isum3[0] + isum3[1] + isum3[2] + isum3[3]) * scale[3]; - - scale += 4; - - if (j == 0) { - qhbits[0] = vec_sr(qhbits[0], 4); - qhbits[1] = vec_sr(qhbits[1], 4); - } - } - - sum += d * isum; - } - - *s = sum; -#else - // scalar version - // This function is written like this so the compiler can manage to vectorize most of it - // Using -Ofast, GCC and clang manage to produce code that is within a factor of 2 or so from the - // manually vectorized version above. Every other version I tried would run at least 4 times slower. - // The ideal situation would be if we could just write the code once, and the compiler would - // automatically produce the best possible set of machine instructions, instead of us having to manually - // write vectorized versions for AVX, ARM_NEON, etc. - - int8_t aux8[QK_K]; - int16_t aux16[8]; - float sums[8]; - int32_t aux32[8]; - memset(sums, 0, 8 * sizeof(float)); - - uint32_t auxs[4]; - const int8_t *scales = (const int8_t *)auxs; - - float sumf = 0; - for (int i = 0; i < nb; ++i) { - const uint8_t *__restrict q3 = x[i].qs; - const uint8_t *__restrict hm = x[i].hmask; - const int8_t *__restrict q8 = y[i].qs; - memset(aux32, 0, 8 * sizeof(int32_t)); - int8_t *__restrict a = aux8; - uint8_t m = 1; - for (int j = 0; j < QK_K; j += 128) { - for (int l = 0; l < 32; ++l) a[l] = q3[l] & 3; - for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); - a += 32; - m <<= 1; - for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 2) & 3; - for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); - a += 32; - m <<= 1; - for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 4) & 3; - for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); - a += 32; - m <<= 1; - for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 6) & 3; - for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); - a += 32; - m <<= 1; - q3 += 32; - } - a = aux8; - - memcpy(auxs, x[i].scales, 12); - uint32_t tmp = auxs[2]; - auxs[2] = ((auxs[0] >> 4) & kmask2) | (((tmp >> 4) & kmask1) << 4); - auxs[3] = ((auxs[1] >> 4) & kmask2) | (((tmp >> 6) & kmask1) << 4); - auxs[0] = (auxs[0] & kmask2) | (((tmp >> 0) & kmask1) << 4); - auxs[1] = (auxs[1] & kmask2) | (((tmp >> 2) & kmask1) << 4); - for (int j = 0; j < QK_K / 16; ++j) { - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += (scales[j] - 32) * aux16[l]; - q8 += 8; - a += 8; - for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; - for (int l = 0; l < 8; ++l) aux32[l] += (scales[j] - 32) * aux16[l]; - q8 += 8; - a += 8; - } - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; - } - for (int l = 0; l < 8; ++l) sumf += sums[l]; - *s = sumf; - -#endif -} - -void vec_dot_iq2_xxs_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { - assert(n % QK_K == 0); - - const block_iq2_xxs *__restrict x = (block_iq2_xxs *)vx; - const block_q8_K *__restrict y = (block_q8_K *)vy; - - const int nb = n / QK_K; - -#if defined(__ARM_NEON) - - const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; - - uint32_t aux32[4]; - const uint8_t *aux8 = (const uint8_t *)aux32; - - mllm_int8x16x4_t q2u; - mllm_int8x16x4_t q2s; - mllm_int8x16x4_t q8b; - - float sumf = 0; - for (int i = 0; i < nb; ++i) { - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - const uint16_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - float sumf1 = 0, sumf2 = 0; - for (int ib32 = 0; ib32 < QK_K / 32; ib32 += 2) { - q8b = mllm_vld1q_s8_x4(q8); - q8 += 64; - memcpy(aux32, q2, 4 * sizeof(uint32_t)); - q2 += 8; - q2u.val[0] = vcombine_s8(vld1_s8((const int8_t *)(iq2xxs_grid + aux8[0])), vld1_s8((const int8_t *)(iq2xxs_grid + aux8[1]))); - q2u.val[1] = vcombine_s8(vld1_s8((const int8_t *)(iq2xxs_grid + aux8[2])), vld1_s8((const int8_t *)(iq2xxs_grid + aux8[3]))); - q2u.val[2] = vcombine_s8(vld1_s8((const int8_t *)(iq2xxs_grid + aux8[8])), vld1_s8((const int8_t *)(iq2xxs_grid + aux8[9]))); - q2u.val[3] = vcombine_s8(vld1_s8((const int8_t *)(iq2xxs_grid + aux8[10])), vld1_s8((const int8_t *)(iq2xxs_grid + aux8[11]))); - q2s.val[0] = vcombine_s8(vld1_s8((const int8_t *)(signs64 + ((aux32[1] >> 0) & 127))), vld1_s8((const int8_t *)(signs64 + ((aux32[1] >> 7) & 127)))); - q2s.val[1] = vcombine_s8(vld1_s8((const int8_t *)(signs64 + ((aux32[1] >> 14) & 127))), vld1_s8((const int8_t *)(signs64 + ((aux32[1] >> 21) & 127)))); - q2s.val[2] = vcombine_s8(vld1_s8((const int8_t *)(signs64 + ((aux32[3] >> 0) & 127))), vld1_s8((const int8_t *)(signs64 + ((aux32[3] >> 7) & 127)))); - q2s.val[3] = vcombine_s8(vld1_s8((const int8_t *)(signs64 + ((aux32[3] >> 14) & 127))), vld1_s8((const int8_t *)(signs64 + ((aux32[3] >> 21) & 127)))); - q2u.val[0] = vmulq_s8(q2u.val[0], q2s.val[0]); - q2u.val[1] = vmulq_s8(q2u.val[1], q2s.val[1]); - q2u.val[2] = vmulq_s8(q2u.val[2], q2s.val[2]); - q2u.val[3] = vmulq_s8(q2u.val[3], q2s.val[3]); - const int32x4_t p1 = mllm_vdotq_s32(mllm_vdotq_s32(vdupq_n_s32(0), q2u.val[0], q8b.val[0]), q2u.val[1], q8b.val[1]); - const int32x4_t p2 = mllm_vdotq_s32(mllm_vdotq_s32(vdupq_n_s32(0), q2u.val[2], q8b.val[2]), q2u.val[3], q8b.val[3]); - sumf1 += vaddvq_s32(p1) * (0.5f + (aux32[1] >> 28)); - sumf2 += vaddvq_s32(p2) * (0.5f + (aux32[3] >> 28)); - } - sumf += d * (sumf1 + sumf2); - } - *s = 0.25f * sumf; - -#elif defined(__AVX2__) - - const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; - - uint32_t aux32[4]; - const uint8_t *aux8 = (const uint8_t *)aux32; - - __m256 accumf = _mm256_setzero_ps(); - for (int i = 0; i < nb; ++i) { - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - const uint16_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - __m256i sumi1 = _mm256_setzero_si256(); - __m256i sumi2 = _mm256_setzero_si256(); - for (int ib32 = 0; ib32 < QK_K / 32; ib32 += 2) { - const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); - q8 += 32; - memcpy(aux32, q2, 4 * sizeof(uint32_t)); - q2 += 8; - const __m256i q2_1 = _mm256_set_epi64x(iq2xxs_grid[aux8[3]], iq2xxs_grid[aux8[2]], iq2xxs_grid[aux8[1]], iq2xxs_grid[aux8[0]]); - const __m256i q2_2 = _mm256_set_epi64x(iq2xxs_grid[aux8[11]], iq2xxs_grid[aux8[10]], iq2xxs_grid[aux8[9]], iq2xxs_grid[aux8[8]]); - const __m256i s2_1 = _mm256_set_epi64x(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127], - signs64[(aux32[1] >> 7) & 127], signs64[(aux32[1] >> 0) & 127]); - const __m256i s2_2 = _mm256_set_epi64x(signs64[(aux32[3] >> 21) & 127], signs64[(aux32[3] >> 14) & 127], - signs64[(aux32[3] >> 7) & 127], signs64[(aux32[3] >> 0) & 127]); - const __m256i q8s_1 = _mm256_sign_epi8(q8_1, s2_1); - const __m256i q8s_2 = _mm256_sign_epi8(q8_2, s2_2); - const __m256i dot1 = _mm256_maddubs_epi16(q2_1, q8s_1); - const __m256i dot2 = _mm256_maddubs_epi16(q2_2, q8s_2); - const uint16_t ls1 = aux32[1] >> 28; - const uint16_t ls2 = aux32[3] >> 28; - const __m256i p1 = _mm256_madd_epi16(dot1, _mm256_set1_epi16(2 * ls1 + 1)); - const __m256i p2 = _mm256_madd_epi16(dot2, _mm256_set1_epi16(2 * ls2 + 1)); - sumi1 = _mm256_add_epi32(sumi1, p1); - sumi2 = _mm256_add_epi32(sumi2, p2); - } - - accumf = _mm256_fmadd_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(_mm256_add_epi32(sumi1, sumi2)), accumf); - } - - *s = 0.125f * hsum_float_8(accumf); - -#elif defined(__AVX__) - const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; - - uint32_t aux32[4]; - const uint8_t *aux8 = (const uint8_t *)aux32; - - __m256 accumf = _mm256_setzero_ps(); - for (int i = 0; i < nb; ++i) { - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - const uint16_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - __m128i sumi1_0 = _mm_setzero_si128(); - __m128i sumi1_1 = _mm_setzero_si128(); - __m128i sumi2_0 = _mm_setzero_si128(); - __m128i sumi2_1 = _mm_setzero_si128(); - for (int ib32 = 0; ib32 < QK_K / 32; ib32 += 2) { - const __m128i q8_1_0 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_1_1 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_2_0 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - const __m128i q8_2_1 = _mm_loadu_si128((const __m128i *)q8); - q8 += 16; - memcpy(aux32, q2, 4 * sizeof(uint32_t)); - q2 += 8; - const __m128i q2_1_0 = _mm_set_epi64x(iq2xxs_grid[aux8[1]], iq2xxs_grid[aux8[0]]); - const __m128i q2_1_1 = _mm_set_epi64x(iq2xxs_grid[aux8[3]], iq2xxs_grid[aux8[2]]); - const __m128i q2_2_0 = _mm_set_epi64x(iq2xxs_grid[aux8[9]], iq2xxs_grid[aux8[8]]); - const __m128i q2_2_1 = _mm_set_epi64x(iq2xxs_grid[aux8[11]], iq2xxs_grid[aux8[10]]); - const __m128i s2_1_0 = _mm_set_epi64x(signs64[(aux32[1] >> 7) & 127], signs64[(aux32[1] >> 0) & 127]); - const __m128i s2_1_1 = _mm_set_epi64x(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127]); - const __m128i s2_2_0 = _mm_set_epi64x(signs64[(aux32[3] >> 7) & 127], signs64[(aux32[3] >> 0) & 127]); - const __m128i s2_2_1 = _mm_set_epi64x(signs64[(aux32[3] >> 21) & 127], signs64[(aux32[3] >> 14) & 127]); - const __m128i q8s_1_0 = _mm_sign_epi8(q8_1_0, s2_1_0); - const __m128i q8s_1_1 = _mm_sign_epi8(q8_1_1, s2_1_1); - const __m128i q8s_2_0 = _mm_sign_epi8(q8_2_0, s2_2_0); - const __m128i q8s_2_1 = _mm_sign_epi8(q8_2_1, s2_2_1); - const __m128i dot1_0 = _mm_maddubs_epi16(q2_1_0, q8s_1_0); - const __m128i dot1_1 = _mm_maddubs_epi16(q2_1_1, q8s_1_1); - const __m128i dot2_0 = _mm_maddubs_epi16(q2_2_0, q8s_2_0); - const __m128i dot2_1 = _mm_maddubs_epi16(q2_2_1, q8s_2_1); - const uint16_t ls1 = aux32[1] >> 28; - const uint16_t ls2 = aux32[3] >> 28; - const __m128i p1_0 = _mm_madd_epi16(dot1_0, _mm_set1_epi16(2 * ls1 + 1)); - const __m128i p1_1 = _mm_madd_epi16(dot1_1, _mm_set1_epi16(2 * ls1 + 1)); - const __m128i p2_0 = _mm_madd_epi16(dot2_0, _mm_set1_epi16(2 * ls2 + 1)); - const __m128i p2_1 = _mm_madd_epi16(dot2_1, _mm_set1_epi16(2 * ls2 + 1)); - sumi1_0 = _mm_add_epi32(sumi1_0, p1_0); - sumi1_1 = _mm_add_epi32(sumi1_1, p1_1); - sumi2_0 = _mm_add_epi32(sumi2_0, p2_0); - sumi2_1 = _mm_add_epi32(sumi2_1, p2_1); - } - - accumf = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(MM256_SET_M128I(_mm_add_epi32(sumi1_1, sumi2_1), _mm_add_epi32(sumi1_0, sumi2_0)))), accumf); - } - - *s = 0.125f * hsum_float_8(accumf); - -#elif defined(__POWER9_VECTOR__) - const vector int v0 = vec_splats((int32_t)0); - vector float vsumf0 = vec_splats(0.0f); - vector float vsumf1 = vec_splats(0.0f); - vector float vsumf2 = vec_splats(0.0f); - vector float vsumf3 = vec_splats(0.0f); - - const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; - - for (int i = 0; i < nb; ++i) { - vector float vxd = vec_splats(MLLM_FP16_TO_FP32(x[i].d)); - vector float vyd = vec_splats(y[i].d); - vector float vd = vec_mul(vxd, vyd); - - vector signed int vsumi0 = v0; - vector signed int vsumi1 = v0; - vector signed int vsumi2 = v0; - vector signed int vsumi3 = v0; - - const uint16_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - - for (int j = 0; j < QK_K / 32; j += 2) { - __builtin_prefetch(q2, 0, 1); - __builtin_prefetch(q8, 0, 1); - - uint32_t aux32[4]; - const uint8_t *aux8 = (const uint8_t *)aux32; - - memcpy(aux32, q2, 4 * sizeof(uint32_t)); - q2 += 8; - - vector signed long long aux64x2_0 = {*(const int64_t *)(iq2xxs_grid + aux8[0]), *(const int64_t *)(iq2xxs_grid + aux8[1])}; - vector signed long long aux64x2_1 = {*(const int64_t *)(iq2xxs_grid + aux8[2]), *(const int64_t *)(iq2xxs_grid + aux8[3])}; - vector signed long long aux64x2_2 = {*(const int64_t *)(iq2xxs_grid + aux8[8]), *(const int64_t *)(iq2xxs_grid + aux8[9])}; - vector signed long long aux64x2_3 = {*(const int64_t *)(iq2xxs_grid + aux8[10]), *(const int64_t *)(iq2xxs_grid + aux8[11])}; - - vector signed long long vsigns0 = {*(const int64_t *)(signs64 + ((aux32[1] >> 0) & 127)), *(const int64_t *)(signs64 + ((aux32[1] >> 7) & 127))}; - vector signed long long vsigns1 = {*(const int64_t *)(signs64 + ((aux32[1] >> 14) & 127)), *(const int64_t *)(signs64 + ((aux32[1] >> 21) & 127))}; - vector signed long long vsigns2 = {*(const int64_t *)(signs64 + ((aux32[3] >> 0) & 127)), *(const int64_t *)(signs64 + ((aux32[3] >> 7) & 127))}; - vector signed long long vsigns3 = {*(const int64_t *)(signs64 + ((aux32[3] >> 14) & 127)), *(const int64_t *)(signs64 + ((aux32[3] >> 21) & 127))}; - - vector signed char q2x0 = (vector signed char)vec_mul((vector signed char)vsigns0, (vector signed char)aux64x2_0); - vector signed char q2x1 = (vector signed char)vec_mul((vector signed char)vsigns1, (vector signed char)aux64x2_1); - vector signed char q2x2 = (vector signed char)vec_mul((vector signed char)vsigns2, (vector signed char)aux64x2_2); - vector signed char q2x3 = (vector signed char)vec_mul((vector signed char)vsigns3, (vector signed char)aux64x2_3); - - vector signed char q8y0 = vec_xl(0, q8); - vector signed char q8y1 = vec_xl(16, q8); - vector signed char q8y2 = vec_xl(32, q8); - vector signed char q8y3 = vec_xl(48, q8); - q8 += 64; - - vector signed short qv0 = vec_add(vec_mule(q2x0, q8y0), vec_mulo(q2x0, q8y0)); - vector signed short qv1 = vec_add(vec_mule(q2x1, q8y1), vec_mulo(q2x1, q8y1)); - vector signed short qv2 = vec_add(vec_mule(q2x2, q8y2), vec_mulo(q2x2, q8y2)); - vector signed short qv3 = vec_add(vec_mule(q2x3, q8y3), vec_mulo(q2x3, q8y3)); - - const uint16_t ls0 = aux32[1] >> 28; - const uint16_t ls1 = aux32[3] >> 28; - - vector signed short vscales01 = vec_splats((int16_t)(2 * ls0 + 1)); - vector signed short vscales23 = vec_splats((int16_t)(2 * ls1 + 1)); - - vsumi0 = vec_msum(qv0, vscales01, vsumi0); - vsumi1 = vec_msum(qv1, vscales01, vsumi1); - vsumi2 = vec_msum(qv2, vscales23, vsumi2); - vsumi3 = vec_msum(qv3, vscales23, vsumi3); - } - - vsumf0 = vec_madd(vec_ctf(vsumi0, 0), vd, vsumf0); - vsumf1 = vec_madd(vec_ctf(vsumi1, 0), vd, vsumf1); - vsumf2 = vec_madd(vec_ctf(vsumi2, 0), vd, vsumf2); - vsumf3 = vec_madd(vec_ctf(vsumi3, 0), vd, vsumf3); - } - - vsumf0 = vec_add(vsumf0, vsumf2); - vsumf1 = vec_add(vsumf1, vsumf3); - - vsumf0 = vec_add(vsumf0, vsumf1); - - vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 4)); - vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 8)); - - *s = 0.125f * vec_extract(vsumf0, 0); - -#elif defined(__loongarch_asx) - - const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; - - uint32_t aux32[4]; - const uint8_t *aux8 = (const uint8_t *)aux32; - - __m256 accumf = (__m256)__lasx_xvldi(0); - for (int i = 0; i < nb; ++i) { - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - const uint16_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - __m256i sumi1 = __lasx_xvldi(0); - __m256i sumi2 = __lasx_xvldi(0); - for (int ib32 = 0; ib32 < QK_K / 32; ib32 += 2) { - const __m256i q8_1 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - const __m256i q8_2 = __lasx_xvld((const __m256i *)q8, 0); - q8 += 32; - memcpy(aux32, q2, 4 * sizeof(uint32_t)); - q2 += 8; - - const __m256i q2_1 = lasx_set_d(iq2xxs_grid[aux8[3]], iq2xxs_grid[aux8[2]], iq2xxs_grid[aux8[1]], iq2xxs_grid[aux8[0]]); - const __m256i q2_2 = lasx_set_d(iq2xxs_grid[aux8[11]], iq2xxs_grid[aux8[10]], iq2xxs_grid[aux8[9]], iq2xxs_grid[aux8[8]]); - const __m256i s2_1 = lasx_set_d(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127], - signs64[(aux32[1] >> 7) & 127], signs64[(aux32[1] >> 0) & 127]); - const __m256i s2_2 = lasx_set_d(signs64[(aux32[3] >> 21) & 127], signs64[(aux32[3] >> 14) & 127], - signs64[(aux32[3] >> 7) & 127], signs64[(aux32[3] >> 0) & 127]); - const __m256i q8s_1 = __lasx_xvsigncov_b(s2_1, q8_1); - const __m256i q8s_2 = __lasx_xvsigncov_b(s2_2, q8_2); - const __m256i dot1 = lasx_maddubs_h(q2_1, q8s_1); - const __m256i dot2 = lasx_maddubs_h(q2_2, q8s_2); - const uint16_t ls1 = aux32[1] >> 28; - const uint16_t ls2 = aux32[3] >> 28; - const __m256i p1 = lasx_madd_h(dot1, __lasx_xvreplgr2vr_h(2 * ls1 + 1)); - const __m256i p2 = lasx_madd_h(dot2, __lasx_xvreplgr2vr_h(2 * ls2 + 1)); - sumi1 = __lasx_xvadd_w(sumi1, p1); - sumi2 = __lasx_xvadd_w(sumi2, p2); - } - - accumf = __lasx_xvfmadd_s(__lasx_xvreplfr2vr_s(d), __lasx_xvffint_s_w(__lasx_xvadd_w(sumi1, sumi2)), accumf); - } - - *s = 0.125f * hsum_float_8(accumf); -// #elif defined(__VXE__) || defined(__VXE2__) -// const uint64_t * signs64 = (const uint64_t *)keven_signs_q2xs; -// -// uint32_t aux32[4]; -// const uint8_t * aux8 = (const uint8_t *)aux32; -// -// float sumf = 0; -// -// for (int i = 0; i < nb; ++i) { -// const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; -// const uint16_t * __restrict q2 = x[i].qs; -// const int8_t * __restrict q8 = y[i].qs; -// -// float sumf1 = 0, sumf2 = 0; -// -// for (int ib32 = 0; ib32 < QK_K/32; ib += 2) { -// int8x16_t q8b0 = vec_xl( 0, q8); -// int8x16_t qb81 = vec_xl(16, q8); -// int8x16_t q8b2 = vec_xl(32, q8); -// int8x16_t q8b3 = vec_xl(48, q8); -// q8 += 64; -// -// memcpy(aux32, q2, 4 * sizeof(uint32_t)); -// q2 += 8; -// -// int8x16_t q2u0 = { *(const int64_t *)(iq2xxs_grid + aux8[ 0]), *(const int64_t *)(iq2xxs_grid + aux8[ 1]) }; -// int8x16_t q2u1 = { *(const int64_t *)(iq2xxs_grid + aux8[ 2]), *(const int64_t *)(iq2xxs_grid + aux8[ 3]) }; -// int8x16_t q2u2 = { *(const int64_t *)(iq2xxs_grid + aux8[ 8]), *(const int64_t *)(iq2xxs_grid + aux8[ 9]) }; -// int8x16_t q2u3 = { *(const int64_t *)(iq2xxs_grid + aux8[10]), *(const int64_t *)(iq2xxs_grid + aux8[11]) }; -// -// int8x16_t q2s0 = { *(const int64_t *)(signs64 + ((aux32[1] >> 0) & 127)), *(const int64_t *)(signs64 + ((aux32[1] >> 7) & 127)) }; -// int8x16_t q2s1 = { *(const int64_t *)(signs64 + ((aux32[1] >> 14) & 127)), *(const int64_t *)(signs64 + ((aux32[1] >> 21) & 127)) }; -// int8x16_t q2s2 = { *(const int64_t *)(signs64 + ((aux32[3] >> 0) & 127)), *(const int64_t *)(signs64 + ((aux32[3] >> 7) & 127)) }; -// int8x16_t q2s3 = { *(const int64_t *)(signs64 + ((aux32[3] >> 14) & 127)), *(const int64_t *)(signs64 + ((aux32[3] >> 21) & 127)) }; -// -// q2u0 = vec_mul(q2u0, q2s0); -// q2u1 = vec_mul(q2u1, q2s1); -// q2u2 = vec_mul(q2u2, q2s2); -// q2u3 = vec_mul(q2u3, q2s3); -// -// const int32x4_t p1 = mllm_vec_dot(mllm_vec_dot(vec_splat_s32(0), q2u0, q8b0), q2u1, q8b1); -// const int32x4_t p2 = mllm_vec_dot(mllm_vec_dot(vec_splat_s32(0), q2u2, q8b2), q2u3, q8b3); -// -// sumf1 += (p1[0] + p1[1] + p1[2] + p1[3]) * (0.5f + (aux32[1] >> 28)); -// sumf2 += (p2[0] + p2[1] + p2[2] + p2[3]) * (0.5f + (aux32[3] >> 28)); -// } -// -// sumf += d * (sumf1 + sumf2); -// } -// -// *s = 0.25f * sumf; -#else - - uint32_t aux32[2]; - const uint8_t *aux8 = (const uint8_t *)aux32; - - float sumf = 0.f; - for (int i = 0; i < nb; ++i) { - const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; - const uint16_t *__restrict q2 = x[i].qs; - const int8_t *__restrict q8 = y[i].qs; - int32_t bsum = 0; - for (int ib32 = 0; ib32 < QK_K / 32; ++ib32) { - memcpy(aux32, q2, 2 * sizeof(uint32_t)); - q2 += 4; - const uint32_t ls = 2 * (aux32[1] >> 28) + 1; - int32_t sumi = 0; - for (int l = 0; l < 4; ++l) { - const uint8_t *grid = (const uint8_t *)(iq2xxs_grid + aux8[l]); - const uint8_t signs = ksigns_iq2xs[(aux32[1] >> 7 * l) & 127]; - for (int j = 0; j < 8; ++j) { - sumi += grid[j] * q8[j] * (signs & kmask_iq2xs[j] ? -1 : 1); - } - q8 += 8; - } - bsum += sumi * ls; - } - sumf += d * bsum; - } - *s = 0.125f * sumf; -#endif -} diff --git a/src/backends/cpu/op/CPUCat.cpp b/src/backends/cpu/op/CPUCat.cpp index 8372889cd..d4775c3b3 100644 --- a/src/backends/cpu/op/CPUCat.cpp +++ b/src/backends/cpu/op/CPUCat.cpp @@ -124,7 +124,7 @@ ErrorCode CPUCat::setUp(vector> inputs, vector 0) { cseq += inputs[idx - 1]->sequence(); } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d + inputs[idx]->shallowCopyFrom(outputs[0], false, {cbatch, chead, cseq, cdim}, 1); // b,h,s,d } return MLLM_NO_ERROR; } else { diff --git a/src/backends/cpu/op/CPUCatFunc.hpp b/src/backends/cpu/op/CPUCatFunc.hpp index 57fa66f4e..f329da8a6 100644 --- a/src/backends/cpu/op/CPUCatFunc.hpp +++ b/src/backends/cpu/op/CPUCatFunc.hpp @@ -26,7 +26,6 @@ class CPUcatFunction : public Op { Op(bn, name), thread_count(threadCount), axis_(axis) { } - ErrorCode setUp(vector> inputs, vector> outputs) override { if (outputs[0]->shape().empty()) { int expd_batch_ = inputs[0]->batch(); @@ -67,7 +66,7 @@ class CPUcatFunction : public Op { if (inputs[0]->masterTensor() == nullptr) { inputs[0]->free(); } - inputs[0]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); + inputs[0]->shallowCopyFrom(outputs[0], false, {cbatch, chead, cseq, cdim}); } else { for (int idx = 0; idx < inputs.size(); idx++) { if (inputs[idx]->masterTensor() == nullptr) { @@ -76,7 +75,7 @@ class CPUcatFunction : public Op { if (idx > 0) { chead += inputs[idx - 1]->head(); } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d + inputs[idx]->shallowCopyFrom(outputs[0], false, {cbatch, chead, cseq, cdim}); // b,h,s,d } } } else if (axis_ == SEQUENCE && inputs[0]->head() != 1) { @@ -91,7 +90,7 @@ class CPUcatFunction : public Op { if (idx > 0) { cseq += inputs[idx - 1]->sequence(); } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d + inputs[idx]->shallowCopyFrom(outputs[0], false, {cbatch, chead, cseq, cdim}); // b,h,s,d } } else if (axis_ == DIMENSION && inputs[0]->head() != 1) { int cbatch = 0; @@ -114,7 +113,7 @@ class CPUcatFunction : public Op { } } } - inputs[idx]->shallowCopyFrom(outputs[0].get(), false, {cbatch, chead, cseq, cdim}); // b,h,s,d + inputs[idx]->shallowCopyFrom(outputs[0], false, {cbatch, chead, cseq, cdim}); // b,h,s,d if (inputs[idx]->deaggregatedTensor() != nullptr) { vector> shared_outputs = {}; for (int t = 0; t < inputs[idx]->deaggregatedTensor()->aggregatedTensors().size(); t++) { diff --git a/src/backends/cpu/op/CPUCausalMask.cpp b/src/backends/cpu/op/CPUCausalMask.cpp index 5ede7400a..199dd11b2 100644 --- a/src/backends/cpu/op/CPUCausalMask.cpp +++ b/src/backends/cpu/op/CPUCausalMask.cpp @@ -4,30 +4,30 @@ namespace mllm { - -CPUCausalMask::CPUCausalMask(Backend *bn, string opName, int threadCount) : thread_count(threadCount), +CPUCausalMask::CPUCausalMask(Backend *bn, string opName, int threadCount) : + thread_count(threadCount), Op(bn, opName) { } ErrorCode CPUCausalMask::reshape(vector> inputs, vector> outputs) { - //std::cout << "CPUMask reshape" << std::endl; - // assert(inputs.size() == 1); + // std::cout << "CPUMask reshape" << std::endl; + // assert(inputs.size() == 1); assert(outputs.size() == 1); outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); return Op::reshape(inputs, outputs); } ErrorCode CPUCausalMask::execute(vector> inputs, vector> outputs) { - if(inputs[0]->sequence() >1 ) { + if (inputs[0]->sequence() > 1) { int batch_size = inputs[0]->batch(); int head_num = inputs[0]->head(); int sequence = inputs[0]->sequence(); int dimension = inputs[0]->dimension(); // memset(outputs[0]->hostPtr(),-INFINITY,outputs[0]->count() * sizeof(float)); int old_dim = 0; - if (inputs.size()>1) { - old_dim = (int)inputs[1]->dataAt(0,0,0,0)-sequence; - }else{ + if (inputs.size() > 1) { + old_dim = (int)inputs[1]->dataAt(0, 0, 0, 0) - sequence; + } else { #ifndef LLAMAFILE_SGEMM old_dim = dimension - sequence; #endif @@ -39,16 +39,14 @@ ErrorCode CPUCausalMask::execute(vector> inputs, vectordimension(); ++d) { if (d > s + old_dim) { outputs[0]->setDataAt({n, h, s, d}, -INFINITY); - } - else{ + } else { outputs[0]->setDataAt({n, h, s, d}, inputs[0]->dataAt(n, h, s, d)); } } } } } - } - else{ + } else { outputs[0]->copyFrom(inputs[0]); } return Op::execute(inputs, outputs); @@ -57,12 +55,12 @@ ErrorCode CPUCausalMask::execute(vector> inputs, vector> inputs, vector> outputs) { // assert(inputs.size() == 1); assert(outputs.size() == 1); - if(inputs[0]->masterTensor() == nullptr) { + if (inputs[0]->masterTensor() == nullptr) { inputs[0]->free(); // TODO remove } outputs[0]->setDtype(activation_dtype()); outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); return MLLM_NO_ERROR; } } // namespace mllm diff --git a/src/backends/cpu/op/CPUEmbedding.cpp b/src/backends/cpu/op/CPUEmbedding.cpp index 72a836e83..8195b8bb7 100644 --- a/src/backends/cpu/op/CPUEmbedding.cpp +++ b/src/backends/cpu/op/CPUEmbedding.cpp @@ -1,7 +1,7 @@ #include "CPUEmbedding.hpp" #include "ParamLoader.hpp" -#include "compute/QuantizeQ4.hpp" -#include "compute/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ4.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" namespace mllm { CPUEmbedding::CPUEmbedding(Backend *bn, string opName, int hiddenSize, int vocabSize, int threadCount) : diff --git a/src/backends/cpu/op/CPUFlashAttention2Func.hpp b/src/backends/cpu/op/CPUFlashAttention2Func.hpp index 77b7414ff..6ed62aebe 100644 --- a/src/backends/cpu/op/CPUFlashAttention2Func.hpp +++ b/src/backends/cpu/op/CPUFlashAttention2Func.hpp @@ -21,35 +21,36 @@ class CPUFlashAttention2Func : public Op { bool causal_mask_; public: - CPUFlashAttention2Func(Backend *bn, string name, int threadCount, bool causal_mask) - : Op(bn, name), thread_count(threadCount), causal_mask_(causal_mask) {} + CPUFlashAttention2Func(Backend *bn, string name, int threadCount, bool causal_mask) : + Op(bn, name), thread_count(threadCount), causal_mask_(causal_mask) { + } ErrorCode reshape(vector> inputs, vector> outputs) override { auto q_tensor = inputs[0]; auto o_tensor = outputs[0]; - + int batch_size = q_tensor->batch(); int q_head = q_tensor->head(); int q_sequence = q_tensor->sequence(); int dimension = q_tensor->dimension(); - + // for BSHD attention start - if(inputs[0]->ctype() == BHSD && inputs[1]->ctype() == BHSD && inputs[2]->ctype() == BHSD ){ + if (inputs[0]->ctype() == BHSD && inputs[1]->ctype() == BHSD && inputs[2]->ctype() == BHSD) { o_tensor->setCtype(q_tensor->ctype()); } // for BSHD attention end - + o_tensor->reshape(batch_size, q_head, q_sequence, dimension); o_tensor->setDtype(inputs[0]->dtype()); return ErrorCode::MLLM_NO_ERROR; } - + ErrorCode execute(vector> inputs, vector> outputs) override { auto q_tensor = inputs[0]; auto k_tensor = inputs[1]; auto v_tensor = inputs[2]; auto o_tensor = outputs[0]; - + int batch_size = q_tensor->batch(); int q_head = q_tensor->head(); int q_sequence = q_tensor->sequence(); @@ -58,23 +59,23 @@ class CPUFlashAttention2Func : public Op { int k_sequence = k_tensor->sequence(); int v_head = v_tensor->head(); int v_sequence = v_tensor->sequence(); - + assert(v_head == k_head && v_sequence == k_sequence); - + bool kv_use_fp32 = (k_tensor->dtype() == MLLM_TYPE_F32); // x86只支持FP32 - + int threads = thread_count; threads = std::min(threads, v_head); - + int32_t br = q_sequence >= 4 ? 4 : 1; int32_t bc = q_sequence >= 4 ? 4 : 1; - constexpr bool high_precision_exp = false; - + constexpr bool high_precision_exp = true; + // for BSHD attention start - if(inputs[0]->ctype()==BHSD && inputs[1]->ctype()==BHSD && inputs[2]->ctype()==BHSD ){ + if (inputs[0]->ctype() == BHSD && inputs[1]->ctype() == BHSD && inputs[2]->ctype() == BHSD) { int km = k_sequence; int vm = v_sequence; - if(k_tensor->masterTensor()!=nullptr && v_tensor->masterTensor()!=nullptr){ + if (k_tensor->masterTensor() != nullptr && v_tensor->masterTensor() != nullptr) { km = k_tensor->masterTensor()->sequence(); vm = v_tensor->masterTensor()->sequence(); } @@ -90,11 +91,10 @@ class CPUFlashAttention2Func : public Op { q_head, // 查询头数 k_head, // 键值头数 high_precision_exp, // 使用快速指数近似 - q_sequence*dimension, - km*dimension, - vm*dimension - ); - // for BSHD attention end + q_sequence * dimension, + km * dimension, + vm * dimension); + // for BSHD attention end } else { flash_attention_2_forward( q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), diff --git a/src/backends/cpu/op/CPUFlattenFunc.hpp b/src/backends/cpu/op/CPUFlattenFunc.hpp index 0348475f9..128fc7d67 100644 --- a/src/backends/cpu/op/CPUFlattenFunc.hpp +++ b/src/backends/cpu/op/CPUFlattenFunc.hpp @@ -97,14 +97,14 @@ class CPUflattenFunction : public Op { } outputs[0]->setDtype(inputs[0]->dtype()); outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); } else if (Module::llm_model_ptr->op_transposed_flag) { if (inputs[0]->masterTensor() == nullptr) { inputs[0]->free(); } outputs[0]->setDtype(inputs[0]->dtype()); outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); } else { std::cout << "[TODO]Tensor.Flatten not support!!!!" << std::endl; } diff --git a/src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp b/src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp index 5de1d33ed..f398df20c 100644 --- a/src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp +++ b/src/backends/cpu/op/CPUFuyuGatherEmbdFunc.hpp @@ -23,13 +23,12 @@ class CPUFuyuGatherEmbdFunc : public Op { Op(bn, name), thread_count(threadCount) { } - ErrorCode setUp(vector> inputs, vector> outputs) override { if (inputs[0]->masterTensor() == nullptr) { inputs[0]->free(); } outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); return MLLM_NO_ERROR; } diff --git a/src/backends/cpu/op/CPUGELU.cpp b/src/backends/cpu/op/CPUGELU.cpp index dbda9de23..560aee320 100644 --- a/src/backends/cpu/op/CPUGELU.cpp +++ b/src/backends/cpu/op/CPUGELU.cpp @@ -1,10 +1,12 @@ #include "CPUGELU.hpp" +#include "backends/cpu/third_party/ggml/Quantize.hpp" #include #include namespace mllm { -CPUGELU::CPUGELU(Backend *bn, string opName, int threadCount):thread_count(threadCount), Op(bn, std::move(opName)) { +CPUGELU::CPUGELU(Backend *bn, string opName, int threadCount) : + thread_count(threadCount), Op(bn, std::move(opName)) { if (!init_table_gelu_f16_flag) { init_table_gelu_f16(); init_table_gelu_f16_flag = true; @@ -26,17 +28,17 @@ ErrorCode CPUGELU::execute(vector> inputs, vectorsequence(); int dim = input->dimension(); #pragma omp parallel for collapse(3) num_threads(thread_count) - for (int b = 0; b dataAt(b, h, s, d); -// // output->setDataAt(b, h, s, d, 0.5 * value * (1 + std::tanh(std::sqrt(2 / M_PI) * (value + 0.044715 * std::pow(value, 3))))); -// output->setDataAt(b, h, s, d, 0.5 * value * (1 + std::tanh(std::sqrt(2 / M_PI) * (0.7978845608 * (value + 0.044715 * std::pow(value, 3)))))); -//; -// } - mllm_vec_gelu_f32(dim, outputs[0]->ptrAt(b, h, s,0), - inputs[0]->ptrAt(b, h, s,0)); + // for (int d = 0; d < dim; ++d) { + // float value = input->dataAt(b, h, s, d); + // // output->setDataAt(b, h, s, d, 0.5 * value * (1 + std::tanh(std::sqrt(2 / M_PI) * (value + 0.044715 * std::pow(value, 3))))); + // output->setDataAt(b, h, s, d, 0.5 * value * (1 + std::tanh(std::sqrt(2 / M_PI) * (0.7978845608 * (value + 0.044715 * std::pow(value, 3)))))); + //; + // } + mllm_vec_gelu_f32(dim, outputs[0]->ptrAt(b, h, s, 0), + inputs[0]->ptrAt(b, h, s, 0)); } } } diff --git a/src/backends/cpu/op/CPUGather.cpp b/src/backends/cpu/op/CPUGather.cpp index e79ba9040..c00a5933f 100644 --- a/src/backends/cpu/op/CPUGather.cpp +++ b/src/backends/cpu/op/CPUGather.cpp @@ -3,15 +3,15 @@ namespace mllm { -CPUGather::CPUGather(Backend *bn, string opName, int threadCount) : thread_count(threadCount), +CPUGather::CPUGather(Backend *bn, string opName, int threadCount) : + thread_count(threadCount), Op(bn, opName) { } ErrorCode CPUGather::reshape(vector> inputs, vector> outputs) { - assert(inputs.size() == 3); assert(outputs.size() == 1); - if(inputs[1]->batch() == 0) { + if (inputs[1]->batch() == 0) { outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), inputs[0]->dimension()); return Op::reshape(inputs, outputs); } @@ -25,7 +25,7 @@ ErrorCode CPUGather::reshape(vector> inputs, vector> inputs, vector> outputs) { - if(inputs[1]->batch() == 0) { + if (inputs[1]->batch() == 0) { return Op::execute(inputs, outputs); } @@ -36,7 +36,7 @@ ErrorCode CPUGather::execute(vector> inputs, vectordimension(); for (int batch = 0; batch < inputs[0]->batch(); ++batch) { for (int seq = 0; seq < inputs[0]->sequence(); ++seq) { - if(input_indices->dataAt(batch, 0, seq, 0) >= 0) { + if (input_indices->dataAt(batch, 0, seq, 0) >= 0) { memcpy(outputs[0]->hostPtr() + outputs[0]->offset(batch, 0, seq, 0), inputs[1]->hostPtr() + (int)inputs[1]->offset(batch, 0, input_indices->dataAt(batch, 0, seq, 0), 0), inputs[1]->dtypeSize() * hiddenSize); @@ -47,14 +47,12 @@ ErrorCode CPUGather::execute(vector> inputs, vector> inputs, vector> outputs) { - - if(inputs[0]->masterTensor() == nullptr) { + if (inputs[0]->masterTensor() == nullptr) { inputs[0]->free(); } outputs[0]->setDtype(activation_dtype()); outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); return MLLM_NO_ERROR; } } // namespace mllm - diff --git a/src/backends/cpu/op/CPUHeadLinear.cpp b/src/backends/cpu/op/CPUHeadLinear.cpp index 3612e4a57..72166c9a4 100644 --- a/src/backends/cpu/op/CPUHeadLinear.cpp +++ b/src/backends/cpu/op/CPUHeadLinear.cpp @@ -3,6 +3,7 @@ #include "Types.hpp" #include #include +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" namespace mllm { @@ -80,10 +81,10 @@ ErrorCode CPUHeadLinear::execute(vector> inputs, vector tmp_in = std::make_shared(backend_); tmp_in->reshape(1, 1, 1, inputs[0]->dimension()); - tmp_in->shallowCopyFrom(inputs[0].get(), false, {0, 0, seqLength % chunk_size - 1, 0}); + tmp_in->shallowCopyFrom(inputs[0], false, {0, 0, seqLength % chunk_size - 1, 0}); shared_ptr tmp_out = std::make_shared(backend_); tmp_out->reshape(1, 1, 1, out_features_); - tmp_out->shallowCopyFrom(outputs[0].get(), false, {0, 0, seqLength % chunk_size - 1, 0}); + tmp_out->shallowCopyFrom(outputs[0], false, {0, 0, seqLength % chunk_size - 1, 0}); // auto start = mllm::mllm_time_us(); if (inputs[0]->count() == 0) { diff --git a/src/backends/cpu/op/CPUIRoPE.cpp b/src/backends/cpu/op/CPUIRoPE.cpp index c29f0f74e..89bd2d7c7 100644 --- a/src/backends/cpu/op/CPUIRoPE.cpp +++ b/src/backends/cpu/op/CPUIRoPE.cpp @@ -5,7 +5,7 @@ #include #include #include -#include "backends/cpu/compute/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPUIndexPutFunc.hpp b/src/backends/cpu/op/CPUIndexPutFunc.hpp index 2013516c6..3d0c2a789 100644 --- a/src/backends/cpu/op/CPUIndexPutFunc.hpp +++ b/src/backends/cpu/op/CPUIndexPutFunc.hpp @@ -19,17 +19,17 @@ class CPUIndexPutFunction : public Op { bool accumulate_; public: - CPUIndexPutFunction(Backend *bn, string name, int threadCount, bool accumulate) - : Op(bn, name), thread_count(threadCount), accumulate_(accumulate) {} + CPUIndexPutFunction(Backend *bn, string name, int threadCount, bool accumulate) : + Op(bn, name), thread_count(threadCount), accumulate_(accumulate) { + } - ErrorCode setUp(vector> inputs, vector> outputs) override { if (!accumulate_) { if (inputs[0]->masterTensor() == nullptr) { inputs[0]->free(); } outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); } return MLLM_NO_ERROR; } @@ -42,7 +42,7 @@ class CPUIndexPutFunction : public Op { inputs[0]->free(); } outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); } return MLLM_NO_ERROR; } @@ -54,7 +54,7 @@ class CPUIndexPutFunction : public Op { assert(dest_input->head() == 1); assert(src_input->head() == 1); assert(dest_input->dimension() == src_input->dimension()); - + if (!accumulate_) { outputs[0]->reshape(dest_input->batch(), dest_input->head(), dest_input->sequence(), dest_input->dimension()); } else { @@ -65,7 +65,7 @@ class CPUIndexPutFunction : public Op { outputs[0]->reshape(dest_input->batch(), dest_input->head(), seq, dest_input->dimension()); outputs[0]->alloc(); } - + outputs[0]->setDtype(inputs[0]->dtype()); return MLLM_NO_ERROR; } @@ -74,7 +74,7 @@ class CPUIndexPutFunction : public Op { if (inputs.size() > 1 && inputs[1]->batch() == 0) { return MLLM_NO_ERROR; } - + assert(inputs.size() == 3); auto dest_input = inputs[0]; auto src_input = inputs[1]; diff --git a/src/backends/cpu/op/CPUKVCache.cpp b/src/backends/cpu/op/CPUKVCache.cpp index 0c64193f6..20318e4bb 100644 --- a/src/backends/cpu/op/CPUKVCache.cpp +++ b/src/backends/cpu/op/CPUKVCache.cpp @@ -8,28 +8,28 @@ int n_pack = 16; namespace mllm { CPUKVCache::CPUKVCache(Backend *bn, string opName, int hidden, int head, int n_rep, bool fa2, int cache_max, int threadCount) : thread_count(threadCount), Op(bn, opName) { + cache_ = std::make_shared(1, head * n_rep, cache_max, hidden, bn, false); fa2_ = fa2; - cache_.setBackend(bn); switch (KVCache_TYPE) { case 16: { - cache_.setDtype(MLLM_TYPE_F16); + cache_->setDtype(MLLM_TYPE_F16); break; } case 8: { if (opName.find("k_cache") != std::string::npos) { - cache_.setDtype(MLLM_TYPE_Q8_0); + cache_->setDtype(MLLM_TYPE_Q8_0); n_pack = QK8_0; } else { - cache_.setDtype(MLLM_TYPE_F16); + cache_->setDtype(MLLM_TYPE_F16); } break; } case 32: { - cache_.setDtype(MLLM_TYPE_F32); + cache_->setDtype(MLLM_TYPE_F32); break; } default: { - cache_.setDtype(MLLM_TYPE_F32); + cache_->setDtype(MLLM_TYPE_F32); break; } } @@ -43,27 +43,27 @@ CPUKVCache::CPUKVCache(Backend *bn, string opName, int hidden, int head, int n_r cache_limit_ = cache_max; n_rep_ = n_rep; if (head > 0) { - if (for_xnn_) cache_.setDtype(MLLM_TYPE_F32); + if (for_xnn_) cache_->setDtype(MLLM_TYPE_F32); - cache_.reshape(1, head * n_rep_, cache_limit_, hidden); - cache_.setName(name() + ".Cache"); - cache_.alloc(); + cache_->reshape(1, head * n_rep_, cache_limit_, hidden); + cache_->setName(name() + ".Cache"); + cache_->alloc(); - switch (cache_.dtype()) { + switch (cache_->dtype()) { case MLLM_TYPE_F32: - memset(cache_.hostPtr(), 0, cache_.count() * sizeof(float)); + memset(cache_->hostPtr(), 0, cache_->count() * sizeof(float)); break; case MLLM_TYPE_F16: - memset(cache_.hostPtr(), 0, cache_.count() * sizeof(mllm_fp16_t)); + memset(cache_->hostPtr(), 0, cache_->count() * sizeof(mllm_fp16_t)); break; case MLLM_TYPE_Q8_0: - memset((char *)cache_.rawHostPtr(), 0, cache_.count() * sizeof(block_q8_0) / QK8_0); + memset((char *)cache_->rawHostPtr(), 0, cache_->count() * sizeof(block_q8_0) / QK8_0); break; default: break; }; cache_seq_len_ = 0; - cache_.cache_seq_len_ = cache_seq_len_; + cache_->cache_seq_len_ = cache_seq_len_; } } @@ -72,28 +72,28 @@ ErrorCode CPUKVCache::reshape(vector> inputs, assert(inputs.size() == 1); assert(outputs.size() == 1); if (cache_seq_len_ < 0) { - if (for_xnn_) cache_.setDtype(MLLM_TYPE_F32); + if (for_xnn_) cache_->setDtype(MLLM_TYPE_F32); - cache_.reshape(inputs[0]->batch(), inputs[0]->head() * n_rep_, cache_limit_, - inputs[0]->dimension()); - cache_.setName(name() + ".Cache"); - cache_.alloc(); + cache_->reshape(inputs[0]->batch(), inputs[0]->head() * n_rep_, cache_limit_, + inputs[0]->dimension()); + cache_->setName(name() + ".Cache"); + cache_->alloc(); - switch (cache_.dtype()) { + switch (cache_->dtype()) { case MLLM_TYPE_F32: - memset(cache_.hostPtr(), 0, cache_.count() * sizeof(float)); + memset(cache_->hostPtr(), 0, cache_->count() * sizeof(float)); break; case MLLM_TYPE_F16: - memset(cache_.hostPtr(), 0, cache_.count() * sizeof(mllm_fp16_t)); + memset(cache_->hostPtr(), 0, cache_->count() * sizeof(mllm_fp16_t)); break; case MLLM_TYPE_Q8_0: - memset((char *)cache_.rawHostPtr(), 0, cache_.count() * sizeof(block_q8_0) / QK8_0); + memset((char *)cache_->rawHostPtr(), 0, cache_->count() * sizeof(block_q8_0) / QK8_0); break; default: break; }; cache_seq_len_ = 0; - cache_.cache_seq_len_ = cache_seq_len_; + cache_->cache_seq_len_ = cache_seq_len_; } // for sd @@ -102,7 +102,7 @@ ErrorCode CPUKVCache::reshape(vector> inputs, unsigned int last_draft_length = cpuBackend->getLastDraftLength(); const std::vector &last_verified_position_ids = cpuBackend->getLastVerifiedPositionIds(); cache_seq_len_ = cache_seq_len_ - (last_draft_length) + last_verified_position_ids.size(); - cache_.cache_seq_len_ = cache_seq_len_; + cache_->cache_seq_len_ = cache_seq_len_; } int sequence = inputs[0]->sequence() + cache_seq_len_; @@ -142,62 +142,62 @@ ErrorCode CPUKVCache::execute(vector> inputs, int cache_seq_len_old = cache_seq_len_; cache_seq_len_ += inputs[0]->sequence(); - cache_.cache_seq_len_ = cache_seq_len_; + cache_->cache_seq_len_ = cache_seq_len_; if (n_rep_ > 1) { - if (cache_.ctype() == BSHD) { - for (int b = 0; b < cache_.batch(); ++b) { + if (cache_->ctype() == BSHD) { + for (int b = 0; b < cache_->batch(); ++b) { for (int h = inputs[0]->head() - 1; h >= 0; --h) { #pragma omp parallel for collapse(2) num_threads(thread_count) for (int seq = cache_seq_len_old; seq < cache_seq_len_; ++seq) { for (int i_rep = 0; i_rep < n_rep_; ++i_rep) { auto cache_head = h * n_rep_ + i_rep; - if (cache_.dtype() == MLLM_TYPE_F32) { + if (cache_->dtype() == MLLM_TYPE_F32) { auto src_ptr = inputs[0]->ptrAt(b, h, seq - cache_seq_len_old, 0); - auto dest_ptr = cache_.ptrAt(b, cache_head, seq, 0); - int copy_size = cache_.dimension(); + auto dest_ptr = cache_->ptrAt(b, cache_head, seq, 0); + int copy_size = cache_->dimension(); memcpy(dest_ptr, src_ptr, copy_size * sizeof(float)); - } else if (cache_.dtype() == MLLM_TYPE_F16) { + } else if (cache_->dtype() == MLLM_TYPE_F16) { auto src_ptr = inputs[0]->ptrAt(b, h, seq - cache_seq_len_old, 0); - auto dest_ptr = cache_.ptrAt(b, cache_head, seq, 0); - int copy_size = cache_.dimension(); + auto dest_ptr = cache_->ptrAt(b, cache_head, seq, 0); + int copy_size = cache_->dimension(); memcpy(dest_ptr, src_ptr, copy_size * sizeof(mllm_fp16_t)); - } else if (cache_.dtype() == MLLM_TYPE_Q8_0) { + } else if (cache_->dtype() == MLLM_TYPE_Q8_0) { auto src_ptr = (char *)inputs[0]->rawHostPtr() + inputs[0]->offset(b, h, seq - cache_seq_len_old, 0) * sizeof(block_q8_0) / QK8_0; - auto dest_ptr = (char *)cache_.rawHostPtr() + cache_.offset(b, cache_head, seq, 0) * sizeof(block_q8_0) / QK8_0; - int copy_size = cache_.dimension(); + auto dest_ptr = (char *)cache_->rawHostPtr() + cache_->offset(b, cache_head, seq, 0) * sizeof(block_q8_0) / QK8_0; + int copy_size = cache_->dimension(); memcpy(dest_ptr, src_ptr, copy_size * sizeof(block_q8_0) / QK8_0); } } } } } - } else if (cache_.ctype() == BHDS) { - for (int b = 0; b < cache_.batch(); ++b) { + } else if (cache_->ctype() == BHDS) { + for (int b = 0; b < cache_->batch(); ++b) { for (int h = inputs[0]->head() - 1; h >= 0; --h) { #pragma omp parallel for collapse(2) num_threads(thread_count) for (int d = 0; d < inputs[0]->dimension(); ++d) { for (int i_rep = 0; i_rep < n_rep_; ++i_rep) { auto cache_head = h * n_rep_ + i_rep; - if (cache_.dtype() == MLLM_TYPE_F32) { + if (cache_->dtype() == MLLM_TYPE_F32) { auto src_ptr = inputs[0]->ptrAt(b, h, 0, d); auto dest_ptr = - cache_.ptrAt(b, cache_head, cache_seq_len_old, d); + cache_->ptrAt(b, cache_head, cache_seq_len_old, d); int copy_size = cache_seq_len_ - cache_seq_len_old; memcpy(dest_ptr, src_ptr, copy_size * sizeof(float)); - } else if (cache_.dtype() == MLLM_TYPE_F16) { + } else if (cache_->dtype() == MLLM_TYPE_F16) { auto src_ptr = inputs[0]->ptrAt(b, h, 0, d); auto dest_ptr = - cache_.ptrAt(b, cache_head, cache_seq_len_old, d); + cache_->ptrAt(b, cache_head, cache_seq_len_old, d); int copy_size = cache_seq_len_ - cache_seq_len_old; memcpy(dest_ptr, src_ptr, copy_size * sizeof(mllm_fp16_t)); - } else if (cache_.dtype() == MLLM_TYPE_Q8_0) { + } else if (cache_->dtype() == MLLM_TYPE_Q8_0) { auto src_ptr = (char *)inputs[0]->rawHostPtr() + inputs[0]->offset(b, h, 0, d) * sizeof(block_q8_0) / QK8_0; - auto dest_ptr = (char *)cache_.rawHostPtr() + cache_.offset(b, cache_head, cache_seq_len_old, d) * sizeof(block_q8_0) / QK8_0; - int copy_size = cache_.dimension(); + auto dest_ptr = (char *)cache_->rawHostPtr() + cache_->offset(b, cache_head, cache_seq_len_old, d) * sizeof(block_q8_0) / QK8_0; + int copy_size = cache_->dimension(); memcpy(dest_ptr, src_ptr, copy_size * sizeof(block_q8_0) / QK8_0); } } @@ -219,17 +219,17 @@ ErrorCode CPUKVCache::setUp(vector> inputs, vectorctype() == BHSD && cache_.ctype() == BSHD) { - auto origin_b = cache_.batch(); - auto origin_h = cache_.head(); - auto origin_s = cache_.sequence(); - auto origin_d = cache_.dimension(); - cache_.setCtype(BHSD); - cache_.reshape(origin_b, origin_h, origin_s + cache_seq_len_, origin_d); - cache_.alloc(); + if (inputs[0]->ctype() == BHSD && cache_->ctype() == BSHD) { + auto origin_b = cache_->batch(); + auto origin_h = cache_->head(); + auto origin_s = cache_->sequence(); + auto origin_d = cache_->dimension(); + cache_->setCtype(BHSD); + cache_->reshape(origin_b, origin_h, origin_s + cache_seq_len_, origin_d); + cache_->alloc(); } // for BSHD attention end - outputs[0]->setDtype(cache_.dtype()); + outputs[0]->setDtype(cache_->dtype()); outputs[0]->shallowCopyFrom(cache_, false, {0, 0, cache_seq_len_ / cache_limit_, 0}); if (inputs[0]->sequence() + cache_seq_len_ > cache_limit_) { outputs[0]->shallowCopyFrom(cache_, false, {0, 0, cache_seq_len_ % cache_limit_ + 1, 0}); @@ -239,8 +239,9 @@ ErrorCode CPUKVCache::setUp(vector> inputs, vector &verified_position_ids) { - if (cache_.ctype() == BSHD) { + if (cache_->ctype() == BSHD) { unsigned int dest_pid = cache_seq_len_ - verified_position_ids.size(); for (unsigned int src_pid : verified_position_ids) { if (src_pid == dest_pid) { @@ -248,29 +249,29 @@ ErrorCode CPUKVCache::updateVerifiedKVCache(const std::vector &ver continue; } // #pragma omp parallel for collapse(1) num_threads(thread_count) - for (int b = 0; b < cache_.batch(); ++b) { - if (cache_.dtype() == MLLM_TYPE_F32) { - auto src_ptr = cache_.ptrAt(b, 0, src_pid, 0); - auto dest_ptr = cache_.ptrAt(b, 0, dest_pid, 0); - int copy_size = cache_.dimension() * cache_.head(); + for (int b = 0; b < cache_->batch(); ++b) { + if (cache_->dtype() == MLLM_TYPE_F32) { + auto src_ptr = cache_->ptrAt(b, 0, src_pid, 0); + auto dest_ptr = cache_->ptrAt(b, 0, dest_pid, 0); + int copy_size = cache_->dimension() * cache_->head(); memcpy(dest_ptr, src_ptr, copy_size * sizeof(float)); - } else if (cache_.dtype() == MLLM_TYPE_F16) { - auto src_ptr = cache_.ptrAt(b, 0, src_pid, 0); - auto dest_ptr = cache_.ptrAt(b, 0, dest_pid, 0); - int copy_size = cache_.dimension() * cache_.head(); + } else if (cache_->dtype() == MLLM_TYPE_F16) { + auto src_ptr = cache_->ptrAt(b, 0, src_pid, 0); + auto dest_ptr = cache_->ptrAt(b, 0, dest_pid, 0); + int copy_size = cache_->dimension() * cache_->head(); memcpy(dest_ptr, src_ptr, copy_size * sizeof(mllm_fp16_t)); - } else if (cache_.dtype() == MLLM_TYPE_Q8_0) { + } else if (cache_->dtype() == MLLM_TYPE_Q8_0) { // TODO: Q8 Check auto src_ptr = - (char *)cache_.rawHostPtr() + cache_.offset(b, 0, src_pid, 0) * sizeof(block_q8_0) / QK8_0; - auto dest_ptr = (char *)cache_.rawHostPtr() + cache_.offset(b, 0, dest_pid, 0) * sizeof(block_q8_0) / QK8_0; - int copy_size = cache_.dimension() * cache_.head(); + (char *)cache_->rawHostPtr() + cache_->offset(b, 0, src_pid, 0) * sizeof(block_q8_0) / QK8_0; + auto dest_ptr = (char *)cache_->rawHostPtr() + cache_->offset(b, 0, dest_pid, 0) * sizeof(block_q8_0) / QK8_0; + int copy_size = cache_->dimension() * cache_->head(); memcpy(dest_ptr, src_ptr, copy_size * sizeof(block_q8_0) / QK8_0); } } dest_pid += 1; } - } else if (cache_.ctype() == BHDS) { + } else if (cache_->ctype() == BHDS) { unsigned int dest_pid = cache_seq_len_ - verified_position_ids.size(); for (unsigned int src_pid : verified_position_ids) { if (src_pid == dest_pid) { @@ -278,22 +279,22 @@ ErrorCode CPUKVCache::updateVerifiedKVCache(const std::vector &ver continue; } #pragma omp parallel for collapse(3) num_threads(thread_count) - for (int b = 0; b < cache_.batch(); ++b) { - for (int h = 0; h < cache_.head(); ++h) { - for (int d = 0; d < cache_.dimension(); ++d) { - if (cache_.dtype() == MLLM_TYPE_F32) { - auto src_data = cache_.dataAt(b, h, src_pid, d); - cache_.setDataAt(b, h, dest_pid, d, src_data); - } else if (cache_.dtype() == MLLM_TYPE_F16) { - auto src_data = cache_.dataAt(b, h, src_pid, d); - cache_.setDataAt(b, h, dest_pid, d, src_data); - } else if (cache_.dtype() == MLLM_TYPE_Q8_0) { + for (int b = 0; b < cache_->batch(); ++b) { + for (int h = 0; h < cache_->head(); ++h) { + for (int d = 0; d < cache_->dimension(); ++d) { + if (cache_->dtype() == MLLM_TYPE_F32) { + auto src_data = cache_->dataAt(b, h, src_pid, d); + cache_->setDataAt(b, h, dest_pid, d, src_data); + } else if (cache_->dtype() == MLLM_TYPE_F16) { + auto src_data = cache_->dataAt(b, h, src_pid, d); + cache_->setDataAt(b, h, dest_pid, d, src_data); + } else if (cache_->dtype() == MLLM_TYPE_Q8_0) { // TODO: Q8 Check 不知道q8能不能直接setDataAt - // auto src_data = cache_.dataAt(b, h, src_pid, d); - // cache_.setDataAt(b, h, dest_pid, d, src_data); + // auto src_data = cache_->dataAt(b, h, src_pid, d); + // cache_->setDataAt(b, h, dest_pid, d, src_data); auto src_ptr = - (char *)cache_.rawHostPtr() + cache_.offset(b, h, src_pid, d) * sizeof(block_q8_0) / QK8_0; - auto dest_ptr = (char *)cache_.rawHostPtr() + cache_.offset(b, h, dest_pid, d) * sizeof(block_q8_0) / QK8_0; + (char *)cache_->rawHostPtr() + cache_->offset(b, h, src_pid, d) * sizeof(block_q8_0) / QK8_0; + auto dest_ptr = (char *)cache_->rawHostPtr() + cache_->offset(b, h, dest_pid, d) * sizeof(block_q8_0) / QK8_0; int copy_size = 1; memcpy(dest_ptr, src_ptr, copy_size * sizeof(block_q8_0) / QK8_0); } diff --git a/src/backends/cpu/op/CPUKVCache.hpp b/src/backends/cpu/op/CPUKVCache.hpp index 5177fa54d..476b4f0dc 100644 --- a/src/backends/cpu/op/CPUKVCache.hpp +++ b/src/backends/cpu/op/CPUKVCache.hpp @@ -18,14 +18,14 @@ class CPUKVCache final : public Op { virtual ErrorCode free(vector> inputs, vector> outputs) override; virtual ErrorCode setUp(vector> inputs, vector> outputs) override; - Tensor cache_; + shared_ptr cache_; int getCacheSeqLen() override { return cache_seq_len_; } void clearCache() override { cache_seq_len_ = 0; - cache_.cache_seq_len_ = cache_seq_len_; + cache_->cache_seq_len_ = cache_seq_len_; } void setForXnn(bool for_xnn) { diff --git a/src/backends/cpu/op/CPUKVCacheNPU.cpp b/src/backends/cpu/op/CPUKVCacheNPU.cpp index 6015976e0..9d5f2ca71 100644 --- a/src/backends/cpu/op/CPUKVCacheNPU.cpp +++ b/src/backends/cpu/op/CPUKVCacheNPU.cpp @@ -8,10 +8,10 @@ namespace mllm { CPUKVCacheNPU::CPUKVCacheNPU(Backend *bn, string opName, int n_rep, int cache_max, int threadCount) : thread_count(threadCount), Op(bn, opName) { - cache_.setBackend(bn); + cache_ = std::make_shared(bn); // TODO: Chaning it to FP16 - cache_.setDtype(MLLM_TYPE_F16); + cache_->setDtype(MLLM_TYPE_F16); cache_limit_ = cache_max; n_rep_ = n_rep; } @@ -20,9 +20,9 @@ ErrorCode CPUKVCacheNPU::reshape(vector> inputs, vectorbatch(), inputs[0]->head() * n_rep_, cache_limit_, inputs[0]->dimension()); - cache_.setName(name() + ".Cache"); - cache_.alloc(); + cache_->reshape(inputs[0]->batch(), inputs[0]->head() * n_rep_, cache_limit_, inputs[0]->dimension()); + cache_->setName(name() + ".Cache"); + cache_->alloc(); cache_seq_len_ = 0; // when using the old frontend, the V will be transposed here; while in the module API, the V will be transposed in the QNNTranspose @@ -68,46 +68,46 @@ ErrorCode CPUKVCacheNPU::execute(vector> inputs, vector 1) { - if (cache_.ctype() == BSHD) { - for (int b = 0; b < cache_.batch(); ++b) { + if (cache_->ctype() == BSHD) { + for (int b = 0; b < cache_->batch(); ++b) { for (int h = inputs[0]->head() - 1; h >= 0; --h) { #pragma omp parallel for collapse(2) num_threads(thread_count) for (int seq = cache_seq_len_old; seq < cache_seq_len_; ++seq) { for (int i_rep = 0; i_rep < n_rep_; ++i_rep) { auto cache_head = h * n_rep_ + i_rep; - if (cache_.dtype() == MLLM_TYPE_F32) { + if (cache_->dtype() == MLLM_TYPE_F32) { auto src_ptr = inputs[0]->ptrAt(b, h, seq - cache_seq_len_old, 0); - auto dest_ptr = cache_.ptrAt(b, cache_head, seq, 0); - int copy_size = cache_.dimension(); + auto dest_ptr = cache_->ptrAt(b, cache_head, seq, 0); + int copy_size = cache_->dimension(); memcpy(dest_ptr, src_ptr, copy_size * sizeof(float)); - } else if (cache_.dtype() == MLLM_TYPE_F16) { + } else if (cache_->dtype() == MLLM_TYPE_F16) { auto src_ptr = inputs[0]->ptrAt(b, h, seq - cache_seq_len_old, 0); - auto dest_ptr = cache_.ptrAt(b, cache_head, seq, 0); - int copy_size = cache_.dimension(); + auto dest_ptr = cache_->ptrAt(b, cache_head, seq, 0); + int copy_size = cache_->dimension(); memcpy(dest_ptr, src_ptr, copy_size * sizeof(mllm_fp16_t)); } } } } } - } else if (cache_.ctype() == BHDS) { - for (int b = 0; b < cache_.batch(); ++b) { + } else if (cache_->ctype() == BHDS) { + for (int b = 0; b < cache_->batch(); ++b) { for (int h = inputs[0]->head() - 1; h >= 0; --h) { #pragma omp parallel for collapse(2) num_threads(thread_count) for (int d = 0; d < inputs[0]->dimension(); ++d) { for (int i_rep = 0; i_rep < n_rep_; ++i_rep) { auto cache_head = h * n_rep_ + i_rep; - if (cache_.dtype() == MLLM_TYPE_F32) { + if (cache_->dtype() == MLLM_TYPE_F32) { auto src_ptr = inputs[0]->ptrAt(b, h, 0, d); auto dest_ptr = - cache_.ptrAt(b, cache_head, cache_seq_len_old, d); + cache_->ptrAt(b, cache_head, cache_seq_len_old, d); memcpy(dest_ptr, src_ptr, input_seq * sizeof(float)); - } else if (cache_.dtype() == MLLM_TYPE_F16) { + } else if (cache_->dtype() == MLLM_TYPE_F16) { auto src_ptr = inputs[0]->ptrAt(b, h, 0, d); auto dest_ptr = - cache_.ptrAt(b, cache_head, cache_seq_len_old, d); + cache_->ptrAt(b, cache_head, cache_seq_len_old, d); memcpy(dest_ptr, src_ptr, input_seq * sizeof(mllm_fp16_t)); } } @@ -123,44 +123,44 @@ ErrorCode CPUKVCacheNPU::execute(vector> inputs, vectorctype() == BSHD) { + for (int b = 0; b < cache_->batch(); ++b) { for (int h = 0; h < inputs[0]->head(); ++h) { #pragma omp parallel for collapse(2) num_threads(thread_count) for (int seq = 0; seq < inputs[0]->sequence(); ++seq) { for (int i_rep = 0; i_rep < n_rep_; ++i_rep) { auto cache_head = h * n_rep_ + i_rep; - if (cache_.dtype() == MLLM_TYPE_F32) { + if (cache_->dtype() == MLLM_TYPE_F32) { auto src_ptr = inputs[0]->ptrAt(b, h, seq, 0); - auto dest_ptr = cache_.ptrAt(b, cache_head, cache_seq_len_old + seq, 0); + auto dest_ptr = cache_->ptrAt(b, cache_head, cache_seq_len_old + seq, 0); memcpy(dest_ptr, src_ptr, inputs[0]->dimension() * sizeof(float)); - } else if (cache_.dtype() == MLLM_TYPE_F16) { + } else if (cache_->dtype() == MLLM_TYPE_F16) { auto src_ptr = inputs[0]->ptrAt(b, h, seq, 0); - auto dest_ptr = cache_.ptrAt(b, cache_head, cache_seq_len_old + seq, 0); + auto dest_ptr = cache_->ptrAt(b, cache_head, cache_seq_len_old + seq, 0); memcpy(dest_ptr, src_ptr, inputs[0]->dimension() * sizeof(mllm_fp16_t)); } } } } } - } else if (cache_.ctype() == BHDS) { - for (int b = 0; b < cache_.batch(); ++b) { + } else if (cache_->ctype() == BHDS) { + for (int b = 0; b < cache_->batch(); ++b) { for (int h = 0; h < inputs[0]->head(); ++h) { #pragma omp parallel for collapse(2) num_threads(thread_count) for (int d = 0; d < inputs[0]->dimension(); ++d) { for (int i_rep = 0; i_rep < n_rep_; ++i_rep) { auto cache_head = h * n_rep_ + i_rep; - if (cache_.dtype() == MLLM_TYPE_F32) { + if (cache_->dtype() == MLLM_TYPE_F32) { auto src_ptr = inputs[0]->ptrAt(b, h, 0, d); auto dest_ptr = - cache_.ptrAt(b, cache_head, cache_seq_len_old, d); + cache_->ptrAt(b, cache_head, cache_seq_len_old, d); memcpy(dest_ptr, src_ptr, inputs[0]->sequence() * sizeof(float)); - } else if (cache_.dtype() == MLLM_TYPE_F16) { + } else if (cache_->dtype() == MLLM_TYPE_F16) { auto src_ptr = inputs[0]->ptrAt(b, h, 0, d); auto dest_ptr = - cache_.ptrAt(b, cache_head, cache_seq_len_old, d); + cache_->ptrAt(b, cache_head, cache_seq_len_old, d); memcpy(dest_ptr, src_ptr, inputs[0]->sequence() * sizeof(mllm_fp16_t)); } } @@ -184,7 +184,7 @@ ErrorCode CPUKVCacheNPU::setUp(vector> inputs, vectorsetDtype(cache_.dtype()); + outputs[0]->setDtype(cache_->dtype()); outputs[0]->shallowCopyFrom(cache_, false, {0, 0, cache_seq_len_ / cache_limit_, 0}); if (inputs[0]->sequence() + cache_seq_len_ > cache_limit_) { outputs[0]->shallowCopyFrom(cache_, false, {0, 0, cache_seq_len_ % cache_limit_ + 1, 0}); @@ -197,13 +197,13 @@ ErrorCode CPUKVCacheNPU::setUp(vector> inputs, vectorsetDtype(cache_.dtype()); + outputs[0]->setDtype(cache_->dtype()); outputs[0]->shallowCopyFrom(cache_, false, {0, 0, cache_seq_len_ / cache_limit_, 0}); if (inputs[0]->sequence() + cache_seq_len_ > cache_limit_) { outputs[0]->shallowCopyFrom(cache_, false, {0, 0, cache_seq_len_ % cache_limit_ + 1, 0}); } - inputs[0]->setDtype(cache_.dtype()); + inputs[0]->setDtype(cache_->dtype()); return MLLM_NO_ERROR; } } // namespace mllm \ No newline at end of file diff --git a/src/backends/cpu/op/CPUKVCacheNPU.hpp b/src/backends/cpu/op/CPUKVCacheNPU.hpp index 54cf0a3af..c9bd26bb2 100644 --- a/src/backends/cpu/op/CPUKVCacheNPU.hpp +++ b/src/backends/cpu/op/CPUKVCacheNPU.hpp @@ -5,6 +5,7 @@ #include "Op.hpp" #include "../CPUBackend.hpp" #include "ParamLoader.hpp" +#include namespace mllm { /** @@ -24,7 +25,7 @@ class CPUKVCacheNPU final : public Op { virtual ErrorCode free(vector> inputs, vector> outputs) override; virtual ErrorCode setUp(vector> inputs, vector> outputs) override; - Tensor cache_; + shared_ptr cache_; int getCacheSeqLen() override { return cache_seq_len_; diff --git a/src/backends/cpu/op/CPUKVCacheSage.cpp b/src/backends/cpu/op/CPUKVCacheSage.cpp new file mode 100644 index 000000000..b8c09bd53 --- /dev/null +++ b/src/backends/cpu/op/CPUKVCacheSage.cpp @@ -0,0 +1,129 @@ + + +#include "CPUKVCacheSage.hpp" +#include "ParamLoader.hpp" +#include "Types.hpp" +#include "../compute/SageQuantize.hpp" +#include + +// int n_pack = 16; +namespace mllm { +CPUKVCacheSage::CPUKVCacheSage(Backend *bn, string opName, int hidden, int head, int n_rep, bool fa2, int cache_max, int threadCount) : + thread_count(threadCount), Op(bn, opName) { + cache_ = std::make_shared(bn); + cache_->setDtype(MLLM_TYPE_Q8_0F); + n_rep = 1; + + cache_limit_ = cache_max; + n_rep_ = n_rep; + if (head > 0) { + // cache_->setCtype(BHSD); + cache_->reshape(1, head * n_rep_, cache_limit_, hidden); + cache_->setName(name() + ".Cache"); + cache_->alloc(); + + // memset((char *)cache_->rawHostPtr(), 0, cache_->count() * sizeof(block_q8_0f) / QK8_0F); + cache_->seqMeans().resize(1 * head * hidden); + cache_seq_len_ = 0; + cache_->cache_seq_len_ = cache_seq_len_; + } +} + +ErrorCode CPUKVCacheSage::reshape(vector> inputs, + vector> outputs) { + assert(inputs.size() == 1); + assert(outputs.size() == 1); + if (cache_seq_len_ < 0) { + // cache_->setCtype(BHSD); + cache_->reshape(inputs[0]->batch(), inputs[0]->head() * n_rep_, cache_limit_, + inputs[0]->dimension()); + cache_->setName(name() + ".Cache"); + cache_->alloc(); + + // memset((char *)cache_->rawHostPtr(), 0, cache_->count() * sizeof(block_q8_0f) / QK8_0F); + cache_->seqMeans().resize(inputs[0]->batch() * inputs[0]->head() * inputs[0]->dimension()); + cache_seq_len_ = 0; + cache_->cache_seq_len_ = cache_seq_len_; + } + + int sequence = inputs[0]->sequence() + cache_seq_len_; + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head() * n_rep_, sequence, + inputs[0]->dimension()); + if (sequence > cache_limit_) { + MLLM_LOG_ERROR_STREAM << "\n[ERROR]: Current tokens exceed cache limit: " << sequence << ">" + << cache_limit_ << ";" + << "\n Please set args `--limits` >" << cache_limit_ << std::endl; + + exit(1); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head() * n_rep_, cache_limit_, + inputs[0]->dimension()); + } + return Op::reshape(inputs, outputs); +} + +ErrorCode CPUKVCacheSage::load(AbstructLoader &loader) { + return Op::load(loader); +} + +ErrorCode CPUKVCacheSage::execute(vector> inputs, + vector> outputs) { + int cache_seq_len_old = cache_seq_len_; + + auto new_tokens = inputs[0]; + const int batch_size = new_tokens->batch(); + const int kv_head = new_tokens->head(); + const int seq_len = new_tokens->sequence(); + const int dim = new_tokens->dimension(); + const int num_k_blocks = dim / QK8_0F; +#pragma omp parallel for collapse(2) num_threads(thread_count) + for (int b = 0; b < batch_size; ++b) { + for (int h = 0; h < kv_head; ++h) { + float *p_mean = &cache_->seqMeans()[(b * kv_head + h) * dim]; + + if (seq_len > 1) { // Prefill 阶段 + const size_t bshd_s_stride = (size_t)new_tokens->head() * new_tokens->dimension(); + const float *head_start_ptr = new_tokens->ptrAt(b, h, 0, 0); + + sage_kv_cache::compute_sage_mean_for_one_head_bshd(head_start_ptr, p_mean, seq_len, dim, bshd_s_stride); + + for (int s = 0; s < seq_len; ++s) { + const float *token_to_quantize = new_tokens->ptrAt(b, h, s, 0); + + size_t block_offset = ((size_t)b * cache_->sequence() + s) * cache_->head() + h; + block_q8_0f *p_dest = reinterpret_cast(cache_->rawHostPtr()) + block_offset * num_k_blocks; + + sage_kv_cache::quantize_new_token_to_sage_blocks(token_to_quantize, p_mean, p_dest, dim); + } + } else { // Decode 阶段 + const float *p_new_token = new_tokens->ptrAt(b, h, 0, 0); + sage_kv_cache::update_sage_mean_vector_incremental(p_mean, p_new_token, cache_seq_len_old, dim); + + size_t block_offset = ((size_t)b * cache_->sequence() + cache_seq_len_old) * cache_->head() + h; + block_q8_0f *p_dest = reinterpret_cast(cache_->rawHostPtr()) + block_offset * num_k_blocks; + + sage_kv_cache::quantize_new_token_to_sage_blocks(p_new_token, p_mean, p_dest, dim); + } + } + } + + cache_seq_len_ += inputs[0]->sequence(); + cache_->cache_seq_len_ = cache_seq_len_; + return Op::execute(inputs, outputs); +} + +ErrorCode CPUKVCacheSage::free(vector> inputs, vector> outputs) { + return Op::free(inputs, outputs); +} + +ErrorCode CPUKVCacheSage::setUp(vector> inputs, vector> outputs) { + assert(inputs.size() == 1); + assert(outputs.size() == 1); + + // for BSHD attention end + outputs[0]->setDtype(cache_->dtype()); + outputs[0]->shallowCopyFrom(cache_, false, {0, 0, 0, 0}); + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/cpu/op/CPUKVCacheSage.hpp b/src/backends/cpu/op/CPUKVCacheSage.hpp new file mode 100644 index 000000000..13d646126 --- /dev/null +++ b/src/backends/cpu/op/CPUKVCacheSage.hpp @@ -0,0 +1,60 @@ + +#ifndef MLLM_CPUKVCACHESAGE_H +#define MLLM_CPUKVCACHESAGE_H + +#include "Op.hpp" +#include "../CPUBackend.hpp" +#include "ParamLoader.hpp" +#include + +namespace mllm { + +class CPUKVCacheSage final : public Op { +public: + CPUKVCacheSage(Backend *bn, string opName, int hidden, int head, int n_rep, bool fa2, int cache_max = 100, int threadCount = 4); + virtual ~CPUKVCacheSage() = default; + virtual ErrorCode reshape(vector> inputs, vector> outputs) override; + virtual ErrorCode load(AbstructLoader &loader) override; + virtual ErrorCode execute(vector> inputs, vector> outputs) override; + virtual ErrorCode free(vector> inputs, vector> outputs) override; + virtual ErrorCode setUp(vector> inputs, vector> outputs) override; + + shared_ptr cache_; + + int getCacheSeqLen() override { + return cache_seq_len_; + } + void clearCache() override { + cache_seq_len_ = 0; + cache_->cache_seq_len_ = cache_seq_len_; + } + +private: + int thread_count = 4; + + int cache_seq_len_ = -999; + int n_rep_ = 1; + + bool for_xnn_ = false; + int cache_limit_; + + // bool fa2_ = false; // not_fa2 +}; + +class CPUKVCacheSageCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + int n_rep = (int)op_param["n_rep"]; + int cache_max = (int)op_param["cache_max"]; + bool for_xnn = (bool)op_param["for_xnn"]; + int hidden = (int)op_param["hidden"]; + int head = (int)op_param["head"]; + bool fa2 = (bool)op_param["fa2"]; + auto ret = new CPUKVCacheSage(bn, name, hidden, head, n_rep, fa2, cache_max, threadCount); + return ret; + } +}; + +} // namespace mllm + +#endif // MLLM_CPUKVCACHESAGE_H \ No newline at end of file diff --git a/src/backends/cpu/op/CPULinear.cpp b/src/backends/cpu/op/CPULinear.cpp index 21d666087..b3c1b2547 100644 --- a/src/backends/cpu/op/CPULinear.cpp +++ b/src/backends/cpu/op/CPULinear.cpp @@ -4,6 +4,7 @@ #include #include #include "../compute/GemmKleidiai.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" namespace mllm { @@ -55,7 +56,11 @@ ErrorCode CPULinear::load(AbstructLoader &loader) { kai_flag = true; // out_features_:N // in_features_:K +#ifndef KAI_FP16_CAL size_t packed_b_size = mllm_kleidai_get_packed_b_qsi4_size(out_features_, in_features_); +#else + size_t packed_b_size = mllm_kleidai_get_packed_b_qsi4_size_to_fp16(out_features_, in_features_); +#endif weight_.reshape(1, 1, 1, packed_b_size); #else std::cerr << "KLEIDIAI_Q4_0 is not supported on this platform!" << std::endl; @@ -199,9 +204,9 @@ ErrorCode CPULinear::setUp(vector> inputs, vector> inputs, vector> outputs) { - weight_.free(); + weight_.unload(); if (support_bias_) { - bias_.free(); + bias_.unload(); } return Op::free(inputs, outputs); } diff --git a/src/backends/cpu/op/CPULinearINT8Shadow.cpp b/src/backends/cpu/op/CPULinearINT8Shadow.cpp index 1889db6fa..bda13abc0 100755 --- a/src/backends/cpu/op/CPULinearINT8Shadow.cpp +++ b/src/backends/cpu/op/CPULinearINT8Shadow.cpp @@ -1,8 +1,9 @@ #include "CPULinearINT8Shadow.hpp" #include "Types.hpp" -#include "../compute/VecDot.hpp" -#include "compute/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/VecDotFP32.hpp" +#include "backends/cpu/third_party/ggml/VecDotFP16.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" #include namespace mllm { diff --git a/src/backends/cpu/op/CPULinearInt8.cpp b/src/backends/cpu/op/CPULinearInt8.cpp index fa0431007..194abf329 100644 --- a/src/backends/cpu/op/CPULinearInt8.cpp +++ b/src/backends/cpu/op/CPULinearInt8.cpp @@ -4,6 +4,8 @@ #include #include #include +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/VecDotQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPUMatmulFunc.hpp b/src/backends/cpu/op/CPUMatmulFunc.hpp index 241eec527..09b4ddd45 100644 --- a/src/backends/cpu/op/CPUMatmulFunc.hpp +++ b/src/backends/cpu/op/CPUMatmulFunc.hpp @@ -37,42 +37,50 @@ class CPUmmFunction : public Op { input.reshape(b, h, s, d); input.transed() = true; input.undiffusion() = false; - // if no TENSOR_STATIC_SHAPED - if (input.masterTensor() != nullptr) { - auto b_m = input.masterTensor()->batch(); - auto h_m = input.masterTensor()->head(); - auto d_m = input.masterTensor()->dimension(); - auto s_m = input.masterTensor()->sequence(); - input.masterTensor()->chls() = input.chls(); - input.masterTensor()->changeCtype(); - input.masterTensor()->reshape(b_m, h_m, s_m, d_m); - for (auto &child : input.masterTensor()->childTensors()) { - auto b_c = child->batch(); - auto h_c = child->head(); - auto d_c = child->dimension(); - auto s_c = child->sequence(); - child->chls() = input.chls(); - child->changeCtype(); - child->reshape(b_c, h_c, s_c, d_c); + + // [FIX] Correctly handle the master tensor and its children + if (auto master = input.masterTensor()) { // master is now a shared_ptr + master->chls() = input.chls(); + master->changeCtype(); + master->reshape(master->batch(), master->head(), master->sequence(), master->dimension()); + + // Loop through the master's children + for (auto &child_wp : master->childTensors()) { + // Lock the weak_ptr to get a shared_ptr + if (auto child_sp = child_wp.lock()) { + // Now, use the shared_ptr to access members + auto b_c = child_sp->batch(); + auto h_c = child_sp->head(); + auto d_c = child_sp->dimension(); + auto s_c = child_sp->sequence(); + child_sp->chls() = input.chls(); + child_sp->changeCtype(); + child_sp->reshape(b_c, h_c, s_c, d_c); + } } } else { - for (auto &child : input.childTensors()) { - auto b_c = child->batch(); - auto h_c = child->head(); - auto d_c = child->dimension(); - auto s_c = child->sequence(); - child->chls() = input.chls(); - child->changeCtype(); - child->reshape(b_c, h_c, s_c, d_c); + // [FIX] Correctly handle this tensor's own children + for (auto &child_wp : input.childTensors()) { + // Lock the weak_ptr to get a shared_ptr + if (auto child_sp = child_wp.lock()) { + // Now, use the shared_ptr to access members + auto b_c = child_sp->batch(); + auto h_c = child_sp->head(); + auto d_c = child_sp->dimension(); + auto s_c = child_sp->sequence(); + child_sp->chls() = input.chls(); + child_sp->changeCtype(); + child_sp->reshape(b_c, h_c, s_c, d_c); + } } } } public: - CPUmmFunction(Backend *bn, string name, int threadCount) - : Op(bn, name), thread_count(threadCount) {} - - + CPUmmFunction(Backend *bn, string name, int threadCount) : + Op(bn, name), thread_count(threadCount) { + } + ErrorCode setUp(vector> inputs, vector> outputs) override { if (inputs[1]->chls()[SEQUENCE] != 3) { tranTensorChl(*inputs[1]); @@ -96,7 +104,7 @@ class CPUmmFunction : public Op { // outputs[0]->alloc(); return MLLM_NO_ERROR; } - + ErrorCode execute(vector> inputs, vector> outputs) override { bool isSame = std::equal(inputs[0]->chls().begin(), inputs[0]->chls().end(), inputs[1]->chls().begin()); assert(inputs[0]->dtype() == MLLM_TYPE_F32); diff --git a/src/backends/cpu/op/CPUMergeOutput.cpp b/src/backends/cpu/op/CPUMergeOutput.cpp index 2e39ad0e4..27b474bed 100644 --- a/src/backends/cpu/op/CPUMergeOutput.cpp +++ b/src/backends/cpu/op/CPUMergeOutput.cpp @@ -24,13 +24,13 @@ ErrorCode CPUMergeOutput::reshape(vector> inputs, vector> inputs, vector> outputs) { for (int i = 0; i < inputs.size(); i++) { if (inputs[i]->device() == MLLM_QNN || (inputs[i]->masterTensor() && inputs[i]->masterTensor()->device() == MLLM_QNN)) { - outputs[i]->shallowCopyFrom(inputs[i].get(), true); + outputs[i]->shallowCopyFrom(inputs[i], true); // set output backend to QNN to let the device() be QNN outputs[i]->setBackend(inputs[i]->backend()); } else { if (inputs[i]->allocted() != 0) inputs[i]->free(); outputs[i]->alloc(); - inputs[i]->shallowCopyFrom(outputs[i].get(), true); + inputs[i]->shallowCopyFrom(outputs[i], true); // set inputput backend to QNN to let the device() be QNN inputs[i]->setBackend(outputs[i]->backend()); } diff --git a/src/backends/cpu/op/CPUMultimodalRoPE.cpp b/src/backends/cpu/op/CPUMultimodalRoPE.cpp index 62cf15d55..a80d451a6 100644 --- a/src/backends/cpu/op/CPUMultimodalRoPE.cpp +++ b/src/backends/cpu/op/CPUMultimodalRoPE.cpp @@ -7,7 +7,7 @@ #include #include // #include -#include "backends/cpu/compute/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" #include // 用来计算 accumulate #include // 用来断言 diff --git a/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp b/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp index 26ef4b3cb..46088e4cc 100644 --- a/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp +++ b/src/backends/cpu/op/CPUMultimodalRoPEPipeline.cpp @@ -6,7 +6,7 @@ #include #include // #include -#include "backends/cpu/compute/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" namespace mllm { @@ -131,16 +131,15 @@ ErrorCode CPUMultimodalRoPEPipeline::reshape(vector> inputs, } // if in switching, reset the h_cnt_ - auto cpuBackend = static_cast(backend_); + auto cpuBackend = static_cast(backend_); if (cpuBackend->isStageSwitching()) { - if(cpuBackend->getExecutionType() == PROMPT) { + if (cpuBackend->getExecutionType() == PROMPT) { // set to 0/chunk_size*iter when in prefill stage h_cnt_ = cpuBackend->getCurSequenceLength(); } else { // when switch to decoding, reset the h_cnt_ to 0 h_cnt_ = 0; } - } return Op::reshape(inputs, outputs); } diff --git a/src/backends/cpu/op/CPUNTKRoPE.cpp b/src/backends/cpu/op/CPUNTKRoPE.cpp index e7a99af2e..fa323cbbb 100644 --- a/src/backends/cpu/op/CPUNTKRoPE.cpp +++ b/src/backends/cpu/op/CPUNTKRoPE.cpp @@ -12,7 +12,7 @@ #include "Types.hpp" #include #include -#include "backends/cpu/compute/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPUParameter.cpp b/src/backends/cpu/op/CPUParameter.cpp index 5bd0650f0..debd5a2fb 100644 --- a/src/backends/cpu/op/CPUParameter.cpp +++ b/src/backends/cpu/op/CPUParameter.cpp @@ -11,14 +11,14 @@ CPUParameter::CPUParameter(Backend *bn, string opName, int batch, int head, int head_ = head; seq_ = seq; dim_ = dim; - weight_.setBackend(bn); + weight_ = std::make_shared(bn); } ErrorCode CPUParameter::reshape(vector> inputs, vector> outputs) { // outputs[0] = std::make_shared(weight_); if (outputs[0]->masterTensor() == nullptr) { - outputs[0]->shallowCopyFrom(&weight_, false); + outputs[0]->shallowCopyFrom(weight_, false); } outputs[0]->reshape(batch_, head_, seq_, dim_); @@ -26,15 +26,15 @@ ErrorCode CPUParameter::reshape(vector> inputs, vectorsetName(name()); + weight_->reshape(batch_, head_, seq_, dim_); + if (loader.getDataType(weight_->name()) != MLLM_TYPE_COUNT) { + weight_->setDtype(loader.getDataType(weight_->name())); + weight_->alloc(); + loader.load(weight_); } else { - weight_.setDtype(MLLM_TYPE_F32); - weight_.alloc(); + weight_->setDtype(MLLM_TYPE_F32); + weight_->alloc(); } return Op::load(loader); } @@ -42,20 +42,20 @@ ErrorCode CPUParameter::load(AbstructLoader &loader) { ErrorCode CPUParameter::execute(vector> inputs, vector> outputs) { // outputs[0] = std::make_shared(weight_); - if (outputs[0]->masterTensor()->name() != weight_.name()) { + if (outputs[0]->masterTensor()->name() != weight_->name()) { if (outputs[0]->masterTensor() == nullptr) { // outputs[0]->copyFrom(weight_); for (int n = 0; n < outputs[0]->batch(); ++n) { for (int c = 0; c < outputs[0]->head(); ++c) { for (int h = 0; h < outputs[0]->sequence(); ++h) { for (int w = 0; w < outputs[0]->dimension(); ++w) { - outputs[0]->setDataAt(n, c, h, w, weight_.dataAt(n, c, h, w)); + outputs[0]->setDataAt(n, c, h, w, weight_->dataAt(n, c, h, w)); } } } } } else { - if (weight_.batch() == 1) { + if (weight_->batch() == 1) { auto off = outputs[0]->shapeOffset(); auto off_b = off[0]; auto off_h = off[1]; @@ -65,7 +65,7 @@ ErrorCode CPUParameter::execute(vector> inputs, vectorhead(); ++c) { for (int h = 0; h < outputs[0]->sequence(); ++h) { for (int w = 0; w < outputs[0]->dimension(); ++w) { - outputs[0]->masterTensor()->setDataAt(n + off_b, c + off_h, h + off_s_, w + off_d, weight_.dataAt(0, c, h, w)); + outputs[0]->masterTensor()->setDataAt(n + off_b, c + off_h, h + off_s_, w + off_d, weight_->dataAt(0, c, h, w)); } } } @@ -78,12 +78,12 @@ ErrorCode CPUParameter::execute(vector> inputs, vector> inputs, vector> outputs) { - weight_.free(); + weight_->free(); return Op::free(inputs, outputs); } ErrorCode CPUParameter::setUp(vector> inputs, vector> outputs) { - outputs[0]->shallowCopyFrom(&weight_, false); + outputs[0]->shallowCopyFrom(weight_, false); return MLLM_NO_ERROR; } } // namespace mllm diff --git a/src/backends/cpu/op/CPUParameter.hpp b/src/backends/cpu/op/CPUParameter.hpp index 20dc7eae3..7b0d3dbe7 100644 --- a/src/backends/cpu/op/CPUParameter.hpp +++ b/src/backends/cpu/op/CPUParameter.hpp @@ -4,6 +4,7 @@ #include "Op.hpp" #include "../CPUBackend.hpp" +#include namespace mllm { @@ -17,13 +18,13 @@ class CPUParameter final : public Op { virtual ErrorCode free(vector> inputs, vector> outputs) override; virtual ErrorCode setUp(vector> inputs, vector> outputs) override; - Tensor &weight() { - return weight_; - } + // Tensor &weight() { + // return weight_; + // } private: int thread_count = 4; - Tensor weight_; + shared_ptr weight_; int batch_; int head_; int seq_; diff --git a/src/backends/cpu/op/CPUPredictor.cpp b/src/backends/cpu/op/CPUPredictor.cpp index d3e17c1b7..6c44ec010 100644 --- a/src/backends/cpu/op/CPUPredictor.cpp +++ b/src/backends/cpu/op/CPUPredictor.cpp @@ -1,6 +1,6 @@ #include "CPUPredictor.hpp" -#include "../compute/VecDotType.hpp" +#include "backends/cpu/third_party/ggml/VecDotType.hpp" #include "../compute/Matmul.hpp" #include diff --git a/src/backends/cpu/op/CPUQuantize.cpp b/src/backends/cpu/op/CPUQuantize.cpp index 845b18f67..e997cd16a 100644 --- a/src/backends/cpu/op/CPUQuantize.cpp +++ b/src/backends/cpu/op/CPUQuantize.cpp @@ -4,7 +4,7 @@ #include "CPUQuantize.hpp" #include "Types.hpp" -#include "backends/cpu/compute/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" #include #include diff --git a/src/backends/cpu/op/CPUQuickGELU.cpp b/src/backends/cpu/op/CPUQuickGELU.cpp index d7bc7092a..00671ffb6 100644 --- a/src/backends/cpu/op/CPUQuickGELU.cpp +++ b/src/backends/cpu/op/CPUQuickGELU.cpp @@ -1,9 +1,11 @@ #include "CPUQuickGELU.hpp" +#include "backends/cpu/third_party/ggml/Quantize.hpp" namespace mllm { -CPUQuickGELU::CPUQuickGELU(Backend *bn, string opName, int threadCount) : thread_count(threadCount), +CPUQuickGELU::CPUQuickGELU(Backend *bn, string opName, int threadCount) : + thread_count(threadCount), Op(bn, opName) { if (!init_table_gelu_quick_f16_flag) { init_table_gelu_quick_f16(); @@ -18,7 +20,6 @@ ErrorCode CPUQuickGELU::reshape(vector> inputs, vector> inputs, vector> outputs) { auto input = inputs[0]; auto output = outputs[0]; @@ -27,15 +28,15 @@ ErrorCode CPUQuickGELU::execute(vector> inputs, vectorsequence(); int dim = input->dimension(); #pragma omp parallel for collapse(3) num_threads(thread_count) - for (int b = 0; b dataAt(b, h, s, d); -// output->setDataAt(b, h, s, d, value * (1 / (1 + std::exp(-1.702 * value)))); -// } - mllm_vec_gelu_quick_f32(dim, outputs[0]->ptrAt(b, h, s,0), - inputs[0]->ptrAt(b, h, s,0)); + // for (int d = 0; d < dim; ++d) { + // float value = input->dataAt(b, h, s, d); + // output->setDataAt(b, h, s, d, value * (1 / (1 + std::exp(-1.702 * value)))); + // } + mllm_vec_gelu_quick_f32(dim, outputs[0]->ptrAt(b, h, s, 0), + inputs[0]->ptrAt(b, h, s, 0)); } } } @@ -43,4 +44,3 @@ ErrorCode CPUQuickGELU::execute(vector> inputs, vector> inputs, vector(0, 0, 0, d); +// if (add_unit_offset_) { +// *outputs[0]->ptrAt(n, h, s, d) *= (1 + weight); +// } else { +// *outputs[0]->ptrAt(n, h, s, d) *= (weight); +// } +// } +// } +// } +// } +// 第二部分:应用权重乘法 +#pragma omp parallel for collapse(3) num_threads(thread_count) for (int h = 0; h < head; h++) { for (int n = 0; n < batch; n++) { for (int s = 0; s < seq; s++) { - for (int d = 0; d < dim; d++) { - float weight = weight_.dataAt(0, 0, 0, d); + float *output_vec_ptr = outputs[0]->ptrAt(n, h, s, 0); + + // 根据 weight_ 的数据类型处理 + if (weight_.dtype() == MLLM_TYPE_F32) { + // 如果权重是FP32类型 + float *weight_vec_ptr = weight_.ptrAt(0, 0, 0, 0); + if (add_unit_offset_) { + // 如果需要加1,创建 (1 + weight) 的临时向量 + float *adjusted_weight_vec = new float[dim]; + for (int d_idx = 0; d_idx < dim; ++d_idx) { + adjusted_weight_vec[d_idx] = 1.0f + weight_vec_ptr[d_idx]; + } + // 进行逐元素乘法:output_vec_ptr *= adjusted_weight_vec + vec_mul_fp32(dim, output_vec_ptr, output_vec_ptr, adjusted_weight_vec); + delete[] adjusted_weight_vec; // 释放临时内存 + } else { + // 直接使用 vec_mul_fp32 进行逐元素乘法:output_vec_ptr *= weight_vec_ptr + vec_mul_fp32(dim, output_vec_ptr, output_vec_ptr, weight_vec_ptr); + } + } else if (weight_.dtype() == MLLM_TYPE_Q4_0) { + // 如果权重是 Q4_0 类型 + if (add_unit_offset_) { - *outputs[0]->ptrAt(n, h, s, d) *= (1 + weight); + // 场景:output_fp32[i] = output_fp32_original[i] * (1.0f + Dequantize(weight_q4_0[i])) + // 这里的 `+1` 操作需要浮点数精度,因此必须先反量化 Q4_0 权重。 + // 这将导致操作回到 FP32 * FP32 的逐元素乘法。 + float *dequantized_and_adjusted_weight_fp32 = new float[dim]; + // 反量化 Q4_0 权重 + dequantize_row_q4_0(weight_.ptrAt(0, 0, 0, 0), dequantized_and_adjusted_weight_fp32, dim); + // 逐元素添加 1 + for (int i = 0; i < dim; ++i) { + dequantized_and_adjusted_weight_fp32[i] = 1.0f + dequantized_and_adjusted_weight_fp32[i]; + } + // 执行 FP32 向量的逐元素乘法:output_vec_ptr *= dequantized_and_adjusted_weight_fp32 + vec_mul_fp32(dim, output_vec_ptr, output_vec_ptr, dequantized_and_adjusted_weight_fp32); + delete[] dequantized_and_adjusted_weight_fp32; // 释放临时内存 + } else { - *outputs[0]->ptrAt(n, h, s, d) *= (weight); + // 场景:output_fp32[i] = Dequantize(output_q8_0[i]) * Dequantize(weight_q4_0[i]) + // 这是用户期望的 Q4_0 * Q8_0 混合精度逐元素乘法。 + // 首先,将当前 FP32 输出向量量化为临时的 Q8_0 缓冲区。 + block_q8_0 *temp_output_q8_0 = new block_q8_0[dim / QK8_0]; + quantize_row_q8_0(output_vec_ptr, temp_output_q8_0, dim); + + // 执行 Q4_0 权重和 Q8_0 量化输出之间的逐元素乘法 + // 结果直接存储回 output_vec_ptr (FP32) + vec_mul_q4_0_q8_0(dim, output_vec_ptr, weight_.hostPtr(), temp_output_q8_0); + + delete[] temp_output_q8_0; // 释放临时内存 } + } else { + // 对于不支持的权重类型,此处断言以指示错误。 + assert(false && "Unsupported weight_ dtype in CPURMSNorm::execute"); } } } diff --git a/src/backends/cpu/op/CPUReplace.cpp b/src/backends/cpu/op/CPUReplace.cpp index 85f87e752..7d94ae129 100644 --- a/src/backends/cpu/op/CPUReplace.cpp +++ b/src/backends/cpu/op/CPUReplace.cpp @@ -102,7 +102,7 @@ ErrorCode CPUReplace::setUp(vector> inputs, vectorsetDtype(activation_dtype()); outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); return MLLM_NO_ERROR; } else { diff --git a/src/backends/cpu/op/CPURoPE.cpp b/src/backends/cpu/op/CPURoPE.cpp index c9d63d79c..cc9cdad40 100644 --- a/src/backends/cpu/op/CPURoPE.cpp +++ b/src/backends/cpu/op/CPURoPE.cpp @@ -5,7 +5,7 @@ #include #include #include -#include "backends/cpu/compute/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPURoPETree.cpp b/src/backends/cpu/op/CPURoPETree.cpp index f350f4ca9..54aa9bf58 100644 --- a/src/backends/cpu/op/CPURoPETree.cpp +++ b/src/backends/cpu/op/CPURoPETree.cpp @@ -6,7 +6,7 @@ #include #include #include -#include "backends/cpu/compute/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPUSageAttentionFunc.hpp b/src/backends/cpu/op/CPUSageAttentionFunc.hpp new file mode 100644 index 000000000..5767ef038 --- /dev/null +++ b/src/backends/cpu/op/CPUSageAttentionFunc.hpp @@ -0,0 +1,153 @@ +// +// Created by Rongjie Yi on 25-2-16, with adaptations by Gemini. +// + +#ifndef CPUSAGEATTENTIONFUNC_HPP +#define CPUSAGEATTENTIONFUNC_HPP + +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include +#include +#include "../compute/SageAttention.hpp" +#include "../compute/SageAttentionPT.hpp" +#include "../compute/SageAttentionKVQ8.hpp" + +namespace mllm { + +class CPUSageAttentionFunc : public Op { +private: + int thread_count_ = 4; + bool causal_mask_; + +public: + CPUSageAttentionFunc(Backend *bn, string name, int threadCount, bool causal_mask) : + Op(bn, name), thread_count_(threadCount), causal_mask_(causal_mask) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + auto q_tensor = inputs[0]; + auto o_tensor = outputs[0]; + + int batch_size = q_tensor->batch(); + int q_head = q_tensor->head(); + int q_sequence = q_tensor->sequence(); + int dimension = q_tensor->dimension(); + + o_tensor->setCtype(q_tensor->ctype()); + o_tensor->reshape(batch_size, q_head, q_sequence, dimension); + o_tensor->setDtype(inputs[0]->dtype()); + return ErrorCode::MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + auto q_tensor = inputs[0]; + auto k_tensor = inputs[1]; + auto v_tensor = inputs[2]; + auto o_tensor = outputs[0]; + + int batch_size = q_tensor->batch(); + int q_head = q_tensor->head(); + int q_sequence = q_tensor->sequence(); + int dimension = q_tensor->dimension(); + + int k_head = k_tensor->head(); + int k_sequence = k_tensor->sequence(); + + assert(v_tensor->head() == k_head); + assert(v_tensor->sequence() == k_sequence); + + bool kv_use_fp32 = (k_tensor->dtype() == MLLM_TYPE_F32); + + int threads = thread_count_; + threads = std::min(threads, q_head); + + int32_t br = q_sequence >= 4 ? 4 : q_sequence; + int32_t bc = q_sequence >= 4 ? 4 : q_sequence; + if (dimension % QK8_0F != 0) { + if (kv_use_fp32) { + sage_attn_pt_cpu::sage_attention_forward_cpu_dispatch( + q_tensor->hostPtr(), + k_tensor->hostPtr(), + v_tensor->hostPtr(), + o_tensor->hostPtr(), + batch_size, q_head, k_head, + q_sequence, k_sequence, dimension, + causal_mask_, + threads, + br, bc); + } else { + sage_attn_pt_cpu::sage_attention_forward_cpu_dispatch( + q_tensor->hostPtr(), + k_tensor->hostPtr(), + v_tensor->hostPtr(), + o_tensor->hostPtr(), + batch_size, q_head, k_head, + q_sequence, k_sequence, dimension, + causal_mask_, + threads, + br, bc); + } + return ErrorCode::MLLM_NO_ERROR; + } + if (k_tensor->dtype() == MLLM_TYPE_F32 || k_tensor->dtype() == MLLM_TYPE_F16) { + if (kv_use_fp32) { + sage_attn_cpu::sage_attention_forward_cpu_dispatch( + q_tensor->hostPtr(), + k_tensor->hostPtr(), + v_tensor->hostPtr(), + nullptr, + nullptr, + o_tensor->hostPtr(), + batch_size, q_head, k_head, + q_sequence, k_sequence, dimension, + causal_mask_, + threads, + br, bc, k_sequence); + } else { + sage_attn_cpu::sage_attention_forward_cpu_dispatch( + q_tensor->hostPtr(), + k_tensor->hostPtr(), + v_tensor->hostPtr(), + nullptr, + nullptr, + o_tensor->hostPtr(), + batch_size, q_head, k_head, + q_sequence, k_sequence, dimension, + causal_mask_, + threads, + br, bc, k_sequence); + } + } else if (k_tensor->dtype() == MLLM_TYPE_Q8_0F) { + const float *k_mean_ptr = k_tensor->seqMeans().data(); + const float *v_mean_ptr = v_tensor->seqMeans().data(); + seq_attn_kvq8::sage_attention_forward_cpu_dispatch( + q_tensor->hostPtr(), + k_tensor->hostPtr(), + v_tensor->hostPtr(), + k_mean_ptr, + v_mean_ptr, + o_tensor->hostPtr(), + batch_size, q_head, k_head, q_sequence, k_sequence, dimension, + causal_mask_, threads, br, bc); + } else { + std::cout << "Unsupported K/V dtype: " << k_tensor->dtype() << std::endl; + return MLLM_NO_ERROR; + } + + return ErrorCode::MLLM_NO_ERROR; + } +}; + +class CPUSageAttentionFuncCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // 从op_param中获取参数 + bool causal_mask = op_param.find("causal_mask") != op_param.end() ? (bool)op_param.at("causal_mask") : true; + return new CPUSageAttentionFunc(bn, name, threadCount, causal_mask); + } +}; + +} // namespace mllm +#endif // CPUSAGEATTENTIONFUNC_HPP diff --git a/src/backends/cpu/op/CPUScale.cpp b/src/backends/cpu/op/CPUScale.cpp index 3e088657b..305430b11 100644 --- a/src/backends/cpu/op/CPUScale.cpp +++ b/src/backends/cpu/op/CPUScale.cpp @@ -78,7 +78,7 @@ ErrorCode CPUScale::setUp(vector> inputs, vectorsetDtype(activation_dtype()); outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); return MLLM_NO_ERROR; } diff --git a/src/backends/cpu/op/CPUScatterReduceFunc.hpp b/src/backends/cpu/op/CPUScatterAddFunc.hpp similarity index 84% rename from src/backends/cpu/op/CPUScatterReduceFunc.hpp rename to src/backends/cpu/op/CPUScatterAddFunc.hpp index 7079ff63a..8cf188b76 100644 --- a/src/backends/cpu/op/CPUScatterReduceFunc.hpp +++ b/src/backends/cpu/op/CPUScatterAddFunc.hpp @@ -2,8 +2,8 @@ // Created by Rongjie Yi on 24-12-26. // -#ifndef CPUSCATTERREDUCEFUNC_HPP -#define CPUSCATTERREDUCEFUNC_HPP +#ifndef CPUSCATTEADDFUNC_HPP +#define CPUSCATTEADDFUNC_HPP #include "Tensor.hpp" #include "Types.hpp" @@ -14,12 +14,12 @@ namespace mllm { class Tensor; -class CPUScatterReduceFunction : public Op { +class CPUScatterAddFunction : public Op { private: int thread_count = 4; public: - CPUScatterReduceFunction(Backend *bn, string name, int threadCount) : + CPUScatterAddFunction(Backend *bn, string name, int threadCount) : Op(bn, name), thread_count(threadCount) { } @@ -56,12 +56,12 @@ class CPUScatterReduceFunction : public Op { } }; -class CPUScatterReduceFunctionCreator : public CPUBackend::Creator { +class CPUScatterAddFunctionCreator : public CPUBackend::Creator { public: virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { - return new CPUScatterReduceFunction(bn, name, threadCount); + return new CPUScatterAddFunction(bn, name, threadCount); } }; } // namespace mllm -#endif // CPUSCATTERREDUCEFUNC_HPP \ No newline at end of file +#endif // CPUSCATTEADDFUNC_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUSlidingWindowMask.cpp b/src/backends/cpu/op/CPUSlidingWindowMask.cpp index aa4e8d2e6..b182e9b50 100644 --- a/src/backends/cpu/op/CPUSlidingWindowMask.cpp +++ b/src/backends/cpu/op/CPUSlidingWindowMask.cpp @@ -69,7 +69,7 @@ ErrorCode CPUSlidingWindowMask::setUp(vector> inputs, vector< } outputs[0]->setDtype(activation_dtype()); outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); return MLLM_NO_ERROR; } } // namespace mllm diff --git a/src/backends/cpu/op/CPUSoftMax.cpp b/src/backends/cpu/op/CPUSoftMax.cpp index 7846df0fe..4f586b474 100644 --- a/src/backends/cpu/op/CPUSoftMax.cpp +++ b/src/backends/cpu/op/CPUSoftMax.cpp @@ -2,7 +2,8 @@ #include "CPUSoftMax.hpp" #include #include "Tensor.hpp" -#include "compute/Quantize.hpp" +#include "backends/cpu/third_party/ggml/Quantize.hpp" +#include "backends/cpu/third_party/ggml/VecDotFP32.hpp" #include "../compute/ActivationFunction.hpp" namespace mllm { diff --git a/src/backends/cpu/op/CPUSplitFunc.hpp b/src/backends/cpu/op/CPUSplitFunc.hpp index 9c1d558c5..47f99636c 100644 --- a/src/backends/cpu/op/CPUSplitFunc.hpp +++ b/src/backends/cpu/op/CPUSplitFunc.hpp @@ -23,13 +23,14 @@ class CPUsplitFunction : public Op { int head_size_; public: - CPUsplitFunction(Backend *bn, string name, int threadCount, - const std::vector& each_dims, Chl split_dim, int head_size) - : Op(bn, name), thread_count(threadCount), each_dims_(each_dims), - split_dim_(split_dim), head_size_(head_size) {} + CPUsplitFunction(Backend *bn, string name, int threadCount, + const std::vector &each_dims, Chl split_dim, int head_size) : + Op(bn, name), thread_count(threadCount), each_dims_(each_dims), + split_dim_(split_dim), head_size_(head_size) { + } ErrorCode setUp(vector> inputs, vector> outputs) override { - int split_num_ = each_dims_.size(); + int split_num_ = each_dims_.size(); // store each dims int split_dim_size_ = 0; for (size_t i = 0; i < each_dims_.size(); ++i) { @@ -144,39 +145,27 @@ class CPUsplitFunction : public Op { ErrorCode execute(vector> inputs, vector> outputs) override { // This path is taken only if the memory aggregation in setUp was not performed. if (inputs[0]->aggregatedTensors().empty()) { - std::vector out_pointers; + std::vector out_pointers; + std::vector out_types; + assert(each_dims_.size() == outputs.size()); - for (const auto& output : outputs) { - // Ensure output is allocated if not already - if(output->hostPtr() == nullptr) { + for (const auto &output : outputs) { + if (output->hostPtr() == nullptr) { output->alloc(); } - out_pointers.push_back(output->ptrAt(0, 0, 0, 0)); + if (output->dtype() == MLLM_TYPE_F32) { + out_pointers.push_back(output->ptrAt(0, 0, 0, 0)); + } else if (output->dtype() == MLLM_TYPE_F16) { + out_pointers.push_back(output->ptrAt(0, 0, 0, 0)); + } + out_types.push_back(output->dtype()); } const int origin_dims[4] = {inputs[0]->batch(), inputs[0]->sequence(), inputs[0]->head(), inputs[0]->dimension()}; - - efficient_split(inputs[0]->ptrAt(0, 0, 0, 0), - origin_dims, - out_pointers, - each_dims_, - split_dim_); - } - if (inputs[0]->aggregatedTensors().empty()) { - // int size = args_.size(); - std::vector out_pointers; - // assert(size - 2 == outputs.size()); - for (int i = 0; i < outputs.size(); i++) { - // each_dims_.push_back(args[i]); - out_pointers.push_back(outputs[i]->ptrAt(0, 0, 0, 0)); - } - // Chl split_dim = (Chl)args[size - 2]; - // int head_size = (int)args[size - 1]; - int split_num_ = each_dims_.size(); - const int origin_dims[4] = {inputs[0]->batch(), inputs[0]->sequence(), inputs[0]->head(), inputs[0]->dimension()}; efficient_split(inputs[0]->ptrAt(0, 0, 0, 0), origin_dims, out_pointers, + out_types, each_dims_, split_dim_); } @@ -197,7 +186,7 @@ class CPUsplitFunctionCreator : public CPUBackend::Creator { } Chl split_dim = (Chl)op_param.at("split_dim"); int head_size = static_cast(op_param.at("head_size")); - + return new CPUsplitFunction(bn, name, threadCount, each_dims, split_dim, head_size); } }; diff --git a/src/backends/cpu/op/CPUSplitInput.cpp b/src/backends/cpu/op/CPUSplitInput.cpp index 19b2066b0..423ce5174 100644 --- a/src/backends/cpu/op/CPUSplitInput.cpp +++ b/src/backends/cpu/op/CPUSplitInput.cpp @@ -19,10 +19,9 @@ ErrorCode CPUSplitInput::reshape(vector> inputs, vector> inputs, vector> outputs) { for (int i = 0; i < inputs.size(); i++) { - outputs[i]->shallowCopyFrom(inputs[i].get(), true); + outputs[i]->shallowCopyFrom(inputs[i], true); // the split output is CPU backend by default, set output backend to QNN to let the device() be QNN outputs[i]->setBackend(inputs[i]->backend()); - } return MLLM_NO_ERROR; } @@ -31,4 +30,3 @@ ErrorCode CPUSplitInput::execute(vector> inputs, vector> inputs, vector> outputs) { - // inputs[0]->transShape(SEQUENCE, DIMENSION); - if(axis0_ == SEQUENCE && axis1_ == DIMENSION) { - if(inputs[0]->ctype() == BSHD) { + if (axis0_ == SEQUENCE && axis1_ == DIMENSION) { + if (inputs[0]->ctype() == BSHD) { outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->dimension(), inputs[0]->sequence()); } - } - else if(axis0_ == THW && axis1_ == CHANNLE) { - if(inputs[0]->ctype() == BCTHW) { + } else if (axis0_ == THW && axis1_ == CHANNLE) { + if (inputs[0]->ctype() == BCTHW) { outputs[0]->reshape(inputs[0]->batch(), inputs[0]->time(), inputs[0]->height(), inputs[0]->width(), inputs[0]->channel()); } - } - else if(axis0_ == BATCH && axis1_ == SEQUENCE) { - if(inputs[0]->ctype() == BSHD) { + } else if (axis0_ == BATCH && axis1_ == SEQUENCE) { + if (inputs[0]->ctype() == BSHD) { outputs[0]->reshape(inputs[0]->sequence(), inputs[0]->head(), inputs[0]->batch(), inputs[0]->dimension()); } } @@ -31,30 +29,26 @@ ErrorCode CPUTranspose::reshape(vector> inputs, vector> inputs, vector> outputs) { - return Op::execute(inputs, outputs); } ErrorCode CPUTranspose::free(vector> inputs, vector> outputs) { - return Op::free(inputs, outputs); } ErrorCode CPUTranspose::setUp(vector> inputs, vector> outputs) { - // return Op::setUp(inputs, outputs); - if(inputs[0]->masterTensor() == nullptr) { + if (inputs[0]->masterTensor() == nullptr) { inputs[0]->free(); } outputs[0]->setDtype(activation_dtype()); outputs[0]->alloc(); // outputs[0]->transShape(SEQUENCE, DIMENSION); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); inputs[0]->transShape(axis0_, axis1_, true); // if(inputs[0]->ctype() == BSHD) { // inputs[0]->transShape(SEQUENCE, DIMENSION, true); @@ -65,4 +59,3 @@ ErrorCode CPUTranspose::setUp(vector> inputs, vector // #include #include #include -#include // For std::pair +#include // For std::pair #include // For std::equal namespace mllm { @@ -26,24 +26,24 @@ class CPUtransposeFunction : public Op { vector> axiss_; public: - CPUtransposeFunction(Backend *bn, string name, int threadCount, const vector>& axiss) - : Op(bn, name), thread_count(threadCount), axiss_(axiss) {} + CPUtransposeFunction(Backend *bn, string name, int threadCount, const vector> &axiss) : + Op(bn, name), thread_count(threadCount), axiss_(axiss) { + } - ErrorCode setUp(vector> inputs, vector> outputs) override { // for BSHD attention start - if(axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { - if(inputs[0]->ctype() == BSHD){ + if (axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { + if (inputs[0]->ctype() == BSHD) { outputs[0]->chls() = {{BATCH, 0}, {HEAD, 1}, {SEQUENCE, 2}, {DIMENSION, 3}}; } else { outputs[0]->chls() = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}}; } - outputs[0]->changeCtype(4); + outputs[0]->changeCtype(4); outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); return MLLM_NO_ERROR; } // for BSHD attention end - + if (!outputs[0]->undiffusion()) { outputs[0]->transCopyShape(inputs[0]->shape()); std::map origin_chls = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; @@ -65,7 +65,7 @@ class CPUtransposeFunction : public Op { if (inputs[0]->masterTensor() != nullptr && (inputs[0]->masterTensor()->name().find("Cache") != std::string::npos || inputs[0]->masterTensor()->name().find("weight") != std::string::npos)) { if (outputs[0]->masterTensor() == nullptr) { outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->shallowCopyFrom(inputs[0].get(), false); + outputs[0]->shallowCopyFrom(inputs[0], false); } } else { if (inputs[0]->masterTensor() == nullptr) { @@ -74,7 +74,7 @@ class CPUtransposeFunction : public Op { outputs[0]->setDtype(inputs[0]->dtype()); outputs[0]->alloc(); inputs[0]->setUndiffusion(true); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); outputs[0]->transFrom() = axiss_; } return MLLM_NO_ERROR; @@ -82,7 +82,7 @@ class CPUtransposeFunction : public Op { ErrorCode reshape(vector> inputs, vector> outputs) override { // for BSHD attention start - if(axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { + if (axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { outputs[0]->transCopyShape(inputs[0]->shape()); outputs[0]->chls() = inputs[0]->chls(); std::swap(outputs[0]->chls()[HEAD], outputs[0]->chls()[SEQUENCE]); @@ -90,11 +90,11 @@ class CPUtransposeFunction : public Op { return MLLM_NO_ERROR; } // for BSHD attention end - + std::map origin_chls = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}, {CHANNLE, 1}, {TIME, 2}, {HEIGHT, 3}, {WIDTH, 4}}; auto origin_s = inputs[0]->shape().size(); outputs[0]->transCopyShape(inputs[0]->shape()); - + if (inputs[0]->masterTensor() == nullptr || std::equal(outputs[0]->chls().begin(), outputs[0]->chls().end(), origin_chls.begin())) { outputs[0]->chls() = inputs[0]->chls(); for (auto axis : axiss_) { @@ -109,7 +109,7 @@ class CPUtransposeFunction : public Op { if (inputs[0]->masterTensor() != nullptr && (inputs[0]->masterTensor()->name().find("Cache") != std::string::npos || inputs[0]->masterTensor()->name().find("weight") != std::string::npos)) { if (outputs[0]->masterTensor() == nullptr) { outputs[0]->setDtype(inputs[0]->dtype()); - outputs[0]->shallowCopyFrom(inputs[0].get(), false); + outputs[0]->shallowCopyFrom(inputs[0], false); } } return MLLM_NO_ERROR; @@ -117,21 +117,21 @@ class CPUtransposeFunction : public Op { ErrorCode execute(vector> inputs, vector> outputs) override { // for BSHD attention start - if(axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { + if (axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { // This is a physical transpose, allocate and copy if (outputs[0]->hostPtr() == nullptr) { outputs[0]->alloc(); } - //BSHD -> BHSD (transpose S and H) - if (true) { //真转置 + // BSHD -> BHSD (transpose S and H) + if (true) { // 真转置 assert(inputs[0]->batch() == 1); assert(outputs[0]->batch() == 1); // After reshape, H and S dimensions are swapped in the output tensor's shape assert(inputs[0]->head() == outputs[0]->sequence()); assert(inputs[0]->sequence() == outputs[0]->head()); - - if(inputs[0]->dtype() == outputs[0]->dtype()){ - #pragma omp parallel for num_threads(thread_count) + + if (inputs[0]->dtype() == outputs[0]->dtype()) { +#pragma omp parallel for num_threads(thread_count) for (int h = 0; h < inputs[0]->head(); ++h) { for (int s = 0; s < inputs[0]->sequence(); ++s) { auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); @@ -141,11 +141,11 @@ class CPUtransposeFunction : public Op { } } } else { // With quantization - #pragma omp parallel for num_threads(thread_count) +#pragma omp parallel for num_threads(thread_count) for (int h = 0; h < inputs[0]->head(); ++h) { for (int s = 0; s < inputs[0]->sequence(); ++s) { auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); - // Swap h and s for output access + // Swap h and s for output access auto output_ptr = outputs[0]->ptrAt(0, s, h, 0); for (int d = 0; d < inputs[0]->dimension(); ++d) { output_ptr[d] = MLLM_FP32_TO_FP16(input_ptr[d]); diff --git a/src/backends/cpu/op/CPUView.cpp b/src/backends/cpu/op/CPUView.cpp index 203ee4a09..cc92dc537 100644 --- a/src/backends/cpu/op/CPUView.cpp +++ b/src/backends/cpu/op/CPUView.cpp @@ -4,7 +4,8 @@ namespace mllm { -CPUView::CPUView(Backend *bn, string opName,vector dims, vectordata_dims, int threadCount) : thread_count(threadCount), +CPUView::CPUView(Backend *bn, string opName, vector dims, vector data_dims, int threadCount) : + thread_count(threadCount), Op(bn, opName) { dim0_ = dims[0]; dim1_ = dims[1]; @@ -23,7 +24,6 @@ CPUView::CPUView(Backend *bn, string opName,vector dims, vectordata_d } ErrorCode CPUView::reshape(vector> inputs, vector> outputs) { - // if(data_dim4_ != -999) { // int dim0 = inputs[0]->batch(); // int dim1 = inputs[0]->channel(); @@ -34,62 +34,62 @@ ErrorCode CPUView::reshape(vector> inputs, vectorreshape(dim0, dim1, dim2, dim3, dim4); // } else { - int dim0 = inputs[0]->batch(); - int dim1 = inputs[0]->head(); - int dim2 = inputs[0]->sequence(); - int dim3 = inputs[0]->dimension(); - if(data_dim0_ == BATCH && data_dim1_ == DIMENSION && data_dim2_ == SEQUENCE && data_dim3_ == DIMENSION) { - dim1 = dim1_; - dim3 = inputs[0]->dimension()/ dim1_; - } else if(data_dim0_ == BATCH && data_dim1_ == -1 && data_dim2_ == SEQUENCE && data_dim3_ == HEAD+DIMENSION){ - dim1 = 1; - dim3 = inputs[0]->dimension() * inputs[0]->head(); - } else if(data_dim0_ == BATCH && data_dim1_ == -1 && data_dim2_ == SEQUENCE+HEAD && data_dim3_ == DIMENSION){ - dim1 = 1; - dim2 = inputs[0]->sequence()* inputs[0]->head(); - } else if (data_dim0_ == BATCH && data_dim1_ == -1 && data_dim2_ == CHANNLE && data_dim3_ == TIME + HEIGHT + WIDTH) { - // assert(inputs[0]->ctype() == BCTHW); + int dim0 = inputs[0]->batch(); + int dim1 = inputs[0]->head(); + int dim2 = inputs[0]->sequence(); + int dim3 = inputs[0]->dimension(); + if (data_dim0_ == BATCH && data_dim1_ == DIMENSION && data_dim2_ == SEQUENCE && data_dim3_ == DIMENSION) { + dim1 = dim1_; + dim3 = inputs[0]->dimension() / dim1_; + } else if (data_dim0_ == BATCH && data_dim1_ == -1 && data_dim2_ == SEQUENCE && data_dim3_ == HEAD + DIMENSION) { + dim1 = 1; + dim3 = inputs[0]->dimension() * inputs[0]->head(); + } else if (data_dim0_ == BATCH && data_dim1_ == -1 && data_dim2_ == SEQUENCE + HEAD && data_dim3_ == DIMENSION) { + dim1 = 1; + dim2 = inputs[0]->sequence() * inputs[0]->head(); + } else if (data_dim0_ == BATCH && data_dim1_ == -1 && data_dim2_ == CHANNLE && data_dim3_ == TIME + HEIGHT + WIDTH) { + // assert(inputs[0]->ctype() == BCTHW); + dim1 = 1; + dim2 = inputs[0]->channel(); + dim3 = inputs[0]->time() * inputs[0]->height() * inputs[0]->width(); + } else if (data_dim0_ == BATCH && data_dim1_ == -1 && data_dim2_ == TIME + HEIGHT + WIDTH && data_dim3_ == CHANNLE) { + if (inputs[0]->ctype() == BTHWC) { dim1 = 1; - dim2 = inputs[0]->channel(); - dim3 = inputs[0]->time() * inputs[0]->height() * inputs[0]->width(); - } else if (data_dim0_ == BATCH && data_dim1_ == -1 && data_dim2_ == TIME + HEIGHT + WIDTH && data_dim3_ == CHANNLE ) { - if(inputs[0]->ctype() == BTHWC) { - dim1 = 1; - dim2 = inputs[0]->time() * inputs[0]->height() * inputs[0]->width(); - dim3 = inputs[0]->channel(); - }else { - dim1 = 1; - dim2 = inputs[0]->time() * inputs[0]->height() * inputs[0]->channel(); - dim3 = inputs[0]->width(); - } - } else if (data_dim0_ == SEQUENCE && data_dim1_ == HEAD && data_dim2_ == BATCH && data_dim3_ ==DIMENSION) { - dim0 = inputs[0]->sequence(); - dim1 = inputs[0]->head(); - dim2 = inputs[0]->batch(); - dim3 = inputs[0]->dimension(); - } else if (data_dim0_ == BATCH && data_dim1_ == HEAD && data_dim2_ == BATCH && data_dim3_ ==DIMENSION) { - dim0 = inputs[0]->batch()/dim2_; - dim1 = inputs[0]->head(); - dim2 = dim2_; - dim3 = inputs[0]->dimension(); - } else if (data_dim0_ == BATCH && data_dim1_ == HEAD && data_dim2_ == SEQUENCE && data_dim3_ ==DIMENSION) { - dim0 = dim0_; - dim1 = dim1_; - dim2 = dim2_; - dim3 = dim3_; + dim2 = inputs[0]->time() * inputs[0]->height() * inputs[0]->width(); + dim3 = inputs[0]->channel(); } else { - std::cout<<"CPUView not support!!!!"<time() * inputs[0]->height() * inputs[0]->channel(); + dim3 = inputs[0]->width(); } - outputs[0]->reshape(dim0, dim1, dim2, dim3); + } else if (data_dim0_ == SEQUENCE && data_dim1_ == HEAD && data_dim2_ == BATCH && data_dim3_ == DIMENSION) { + dim0 = inputs[0]->sequence(); + dim1 = inputs[0]->head(); + dim2 = inputs[0]->batch(); + dim3 = inputs[0]->dimension(); + } else if (data_dim0_ == BATCH && data_dim1_ == HEAD && data_dim2_ == BATCH && data_dim3_ == DIMENSION) { + dim0 = inputs[0]->batch() / dim2_; + dim1 = inputs[0]->head(); + dim2 = dim2_; + dim3 = inputs[0]->dimension(); + } else if (data_dim0_ == BATCH && data_dim1_ == HEAD && data_dim2_ == SEQUENCE && data_dim3_ == DIMENSION) { + dim0 = dim0_; + dim1 = dim1_; + dim2 = dim2_; + dim3 = dim3_; + } else { + std::cout << "CPUView not support!!!!" << std::endl; + } + outputs[0]->reshape(dim0, dim1, dim2, dim3); // } return Op::reshape(inputs, outputs); } ErrorCode CPUView::execute(vector> inputs, vector> outputs) { - if(noNeedEx_){ + if (noNeedEx_) { return Op::execute(inputs, outputs); } else { - std::cout<<"CPUView not support!!!!"<> inputs, vectordtype(); - - if ( (data_dim0_ == BATCH && data_dim2_ ==SEQUENCE && inputs[0]->ctype()!=BCTHW) // head & dimension - || (data_dim0_ == BATCH && data_dim3_ ==DIMENSION && inputs[0]->ctype()==BSHD) // head & sequence - || (data_dim0_ == SEQUENCE && data_dim1_ == HEAD && data_dim2_ == BATCH && data_dim3_ ==DIMENSION && inputs[0]->ctype()==BSHD) // head & sequence - || (data_dim0_ == BATCH && inputs[0]->ctype()==BCTHW) // - || (data_dim1_ == HEAD && data_dim3_ ==DIMENSION && inputs[0]->ctype()==BSHD // batch & sequence - || (data_dim0_ == BATCH && data_dim1_ == HEAD && data_dim2_ == SEQUENCE && data_dim3_ ==DIMENSION)) // batch & sequence & head & dimension + + if ((data_dim0_ == BATCH && data_dim2_ == SEQUENCE && inputs[0]->ctype() != BCTHW) // head & dimension + || (data_dim0_ == BATCH && data_dim3_ == DIMENSION && inputs[0]->ctype() == BSHD) // head & sequence + || (data_dim0_ == SEQUENCE && data_dim1_ == HEAD && data_dim2_ == BATCH && data_dim3_ == DIMENSION && inputs[0]->ctype() == BSHD) // head & sequence + || (data_dim0_ == BATCH && inputs[0]->ctype() == BCTHW) // + || (data_dim1_ == HEAD && data_dim3_ == DIMENSION && inputs[0]->ctype() == BSHD // batch & sequence + || (data_dim0_ == BATCH && data_dim1_ == HEAD && data_dim2_ == SEQUENCE && data_dim3_ == DIMENSION)) // batch & sequence & head & dimension // || (data_dim0_ == BATCH && data_dim3_ == CHANNLE && inputs[0]->ctype()==BTHWC) // - ){ + ) { noNeedEx_ = true; if (inputs[0]->masterTensor() == nullptr) { inputs[0]->free(); } outputs[0]->setDtype(activation_dtype()); outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); return MLLM_NO_ERROR; - } - else { - std::cout<<"CPUView not support!!!!"<> inputs, vector> outputs) override { if ((b == -1 && s == -1 && inputs[0]->ctype() != BCTHW) // head & dimension || (b == 1 && h == 1 && inputs[0]->ctype() == BCTHW) // head & dimension @@ -39,7 +39,7 @@ class CPUviewFunction : public Op { } outputs[0]->setDtype(inputs[0]->dtype()); outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0].get(), false); + inputs[0]->shallowCopyFrom(outputs[0], false); } else { std::cout << "[TODO]Tensor.View alloc not support!!!!" << std::endl; } @@ -124,7 +124,7 @@ class CPUviewFunction : public Op { return MLLM_NO_ERROR; } - + ErrorCode execute(vector> inputs, vector> outputs) override { // View is a metadata-only operation, no data movement is needed in execute. return MLLM_NO_ERROR; diff --git a/src/backends/cpu/op/CPUVisionRoPEFunc.hpp b/src/backends/cpu/op/CPUVisionRoPEFunc.hpp index 64466373e..7f6a6528e 100644 --- a/src/backends/cpu/op/CPUVisionRoPEFunc.hpp +++ b/src/backends/cpu/op/CPUVisionRoPEFunc.hpp @@ -10,6 +10,7 @@ #include "Types.hpp" #include #include // For std::sin, std::cos +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" namespace mllm { class Tensor; @@ -138,9 +139,10 @@ class CPUVisionRoPEFuncFunction : public Op { } public: - CPUVisionRoPEFuncFunction(Backend *bn, string name, int threadCount) - : Op(bn, name), thread_count(threadCount) {} - + CPUVisionRoPEFuncFunction(Backend *bn, string name, int threadCount) : + Op(bn, name), thread_count(threadCount) { + } + ErrorCode reshape(vector> inputs, vector> outputs) override { outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); outputs[0]->setDtype(inputs[0]->dtype()); diff --git a/src/backends/cpu/compute/VecDot.hpp b/src/backends/cpu/third_party/ggml/ComputeUtils.hpp similarity index 85% rename from src/backends/cpu/compute/VecDot.hpp rename to src/backends/cpu/third_party/ggml/ComputeUtils.hpp index 826ccf37e..fefcf03e4 100644 --- a/src/backends/cpu/compute/VecDot.hpp +++ b/src/backends/cpu/third_party/ggml/ComputeUtils.hpp @@ -24,18 +24,16 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - -#ifndef MLLM_VECDOT_HPP -#define MLLM_VECDOT_HPP -#include "Tensor.hpp" +#pragma once +// #include "Tensor.hpp" #include "Types.hpp" #include #include "ParamLoader.hpp" -#include "backends/cpu/compute/QuantizeQ8.hpp" -#include "backends/cpu/compute/QuantizeQ4.hpp" -#include "backends/cpu/compute/QuantizeQ6.hpp" -#include "backends/cpu/compute/QuantizeQ3.hpp" -#include "backends/cpu/compute/QuantizeQ2.hpp" +#include "QuantizeQ8.hpp" +#include "QuantizeQ4.hpp" +#include "QuantizeQ6.hpp" +#include "QuantizeQ3.hpp" +#include "QuantizeQ2.hpp" #if defined(__ARM_ARCH) && defined(__ARM_FEATURE_SVE) #include @@ -375,10 +373,10 @@ inline int mllm_cpu_get_sve_cnt(void) { // ref: https://github.com/mllm-org/llama.cpp/pull/5404 #ifdef _MSC_VER #define mllm_vld1q_u32(w, x, y, z) \ - { ((w) + ((uint64_t)(x) << 32)), ((y) + ((uint64_t)(z) << 32)) } + {((w) + ((uint64_t)(x) << 32)), ((y) + ((uint64_t)(z) << 32))} #else #define mllm_vld1q_u32(w, x, y, z) \ - { (w), (x), (y), (z) } + {(w), (x), (y), (z)} #endif // _MSC_VER #if !defined(__aarch64__) @@ -608,54 +606,3 @@ inline static uint8x16_t mllm_vqtbl1q_u8(uint8x16_t a, uint8x16_t b) { #endif // !defined(__aarch64__) #endif // !defined(__ARM_NEON) - -using namespace mllm; - -inline static void vec_scale_f32(const int n, float *y, const float v) { - const int np = (n & ~(MLLM_F32_STEP - 1)); - - MLLM_F32_VEC vx = MLLM_F32_VEC_SET1(v); - - MLLM_F32_VEC ay[MLLM_F32_ARR]; - - for (int i = 0; i < np; i += MLLM_F32_STEP) { - for (int j = 0; j < MLLM_F32_ARR; j++) { - ay[j] = MLLM_F32_VEC_LOAD(y + i + j * MLLM_F32_EPR); - ay[j] = MLLM_F32_VEC_MUL(ay[j], vx); - - MLLM_F32_VEC_STORE(y + i + j * MLLM_F32_EPR, ay[j]); - } - } - - // leftovers - for (int i = np; i < n; ++i) { - y[i] *= v; - } - - // for (int i = 0; i < n; ++i) { - // y[i] *= v; - // } -} - -// void vec_dot_fp32(const float * __restrict src0, const float * __restrict src1, Tensor *dst, bool support_bias, Tensor *bias, int hid_len, int batch, int head, int src0_inf, int sec1_outf); -void vec_dot_q4_0_q8_0(const void *__restrict src0, const void *__restrict src1, Tensor *dst, bool support_bias, Tensor *bias, int hid_len, int batch, int head, int src0_inf, int sec1_outf); -void vec_dot_q4_K_q8_K(const void *__restrict src0, const void *__restrict src1, Tensor *dst, bool support_bias, Tensor *bias, int hid_len, int batch, int head, int src0_inf, int sec1_outf); -void vec_dot_q6_K_q8_K(const void *__restrict src0, const void *__restrict src1, Tensor *dst, bool support_bias, Tensor *bias, int hid_len, int batch, int head, int src0_inf, int sec1_outf); - -void vec_dot_q4_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); -void vec_dot_q6_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); -void vec_dot_q4_0_q8_0(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); -void vec_dot_fp32(const int n, float *__restrict s, const float *__restrict vx, const float *__restrict vy); -void vec_dot_fp16(const int n, float *__restrict s, const mllm_fp16_t *__restrict vx, const mllm_fp16_t *__restrict vy); -void vec_dot_q8_0_q8_0(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy, size_t bs = 0, size_t bx = 0, size_t by = 0); - -void vec_dot_q2_K_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); -void vec_dot_q3_K_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); -void vec_dot_iq2_xxs_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); - -// for sparse linear -void vec_value_dot_fp32(const int n, float *__restrict s, const float x, const float *__restrict vy, bool addition); -// for per-tensor i8, currently not suitable for vecdot trait -void vec_dot_i8_i8(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy, float scale1 = 1, float scale2 = 1); - -#endif // MLLM_VECDOT_HPP diff --git a/src/backends/cpu/compute/GemmLlamafile.cpp b/src/backends/cpu/third_party/ggml/GemmLlamafile.cpp similarity index 99% rename from src/backends/cpu/compute/GemmLlamafile.cpp rename to src/backends/cpu/third_party/ggml/GemmLlamafile.cpp index 21b02fcb4..358744400 100644 --- a/src/backends/cpu/compute/GemmLlamafile.cpp +++ b/src/backends/cpu/third_party/ggml/GemmLlamafile.cpp @@ -48,7 +48,7 @@ #pragma GCC diagnostic ignored "-Wignored-attributes" #endif -#include "GemmLlamafile.hpp" +#include "backends/cpu/third_party/ggml/GemmLlamafile.hpp" #include "Quantize.hpp" #ifdef _MSC_VER diff --git a/src/backends/cpu/compute/GemmLlamafile.hpp b/src/backends/cpu/third_party/ggml/GemmLlamafile.hpp similarity index 92% rename from src/backends/cpu/compute/GemmLlamafile.hpp rename to src/backends/cpu/third_party/ggml/GemmLlamafile.hpp index 3b0942970..1b2af37b8 100644 --- a/src/backends/cpu/compute/GemmLlamafile.hpp +++ b/src/backends/cpu/third_party/ggml/GemmLlamafile.hpp @@ -5,8 +5,6 @@ #ifndef MLLM_GEMM_HPP #define MLLM_GEMM_HPP -// #include "VecDot.hpp" -// #include "Tensor.hpp" #include "Types.hpp" using namespace mllm; diff --git a/src/backends/cpu/compute/GemmPack.cpp b/src/backends/cpu/third_party/ggml/GemmPack.cpp similarity index 98% rename from src/backends/cpu/compute/GemmPack.cpp rename to src/backends/cpu/third_party/ggml/GemmPack.cpp index 93f2f2200..38c81946f 100644 --- a/src/backends/cpu/compute/GemmPack.cpp +++ b/src/backends/cpu/third_party/ggml/GemmPack.cpp @@ -7,6 +7,7 @@ #include // for assert #include // for qsort #include +#include "ComputeUtils.hpp" int mllm_cpu_has_sve(void) { #if defined(__ARM_FEATURE_SVE) @@ -363,11 +364,11 @@ size_t quantize_q4_0_8x8(const float *__restrict src, void *__restrict dst, int6 return 0; } -void mllm_gemv_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void gemv_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { if (bias != nullptr) { - _mllm_gemv_q4_0_4x4_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); + _gemv_q4_0_4x4_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); return; } @@ -533,17 +534,17 @@ void mllm_gemv_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void * const __m128i v0s_u8 = _mm_slli_epi16(v_L_nibbles, 4); \ const __m128i v1s_u8 = _mm_andnot_si128(low_nib_mask, (V_B_Q4)); \ \ - /* 符号扩展到16位 */ \ + /* 符号扩展到16位 */ \ const __m128i v0s_s16 = _mm_cvtepi8_epi16(v0s_u8); \ const __m128i v1s_s16 = _mm_cvtepi8_epi16(v1s_u8); \ \ - /* 核心计算: (v0*a0 + v1*a1) >> 4 */ \ + /* 核心计算: (v0*a0 + v1*a1) >> 4 */ \ const __m128i prod0 = _mm_mullo_epi16(v0s_s16, (V_A0_S16)); \ const __m128i prod1 = _mm_mullo_epi16(v1s_s16, (V_A1_S16)); \ const __m128i sum_prods_s16 = _mm_add_epi16(prod0, prod1); \ const __m128i terms_s16 = _mm_srai_epi16(sum_prods_s16, 4); \ \ - /* 水平求和 */ \ + /* 水平求和 */ \ const __m128i ones = _mm_set1_epi16(1); \ const __m128i sums_s32 = _mm_madd_epi16(terms_s16, ones); \ _mm_extract_epi32(sums_s32, 0) + _mm_extract_epi32(sums_s32, 1); \ @@ -641,9 +642,9 @@ void mllm_gemv_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void * #endif } -void _mllm_gemv_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void _gemv_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { const int qk = QK8_0; const int nb = n / qk; const int ncols_interleaved = 4; @@ -780,11 +781,11 @@ void _mllm_gemv_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const #endif } -void mllm_gemv_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void gemv_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { if (bias != nullptr) { - _mllm_gemv_q4_0_4x8_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); + _gemv_q4_0_4x8_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); return; } @@ -916,9 +917,9 @@ void mllm_gemv_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void * #endif } -void _mllm_gemv_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void _gemv_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { const int qk = QK8_0; const int nb = n / qk; const int ncols_interleaved = 4; @@ -1056,11 +1057,11 @@ void _mllm_gemv_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const #endif } -void mllm_gemv_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void gemv_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { if (bias != nullptr) { - _mllm_gemv_q4_0_8x8_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); + _gemv_q4_0_8x8_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); return; } @@ -1206,9 +1207,9 @@ void mllm_gemv_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void * #endif } -void _mllm_gemv_q4_0_8x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void _gemv_q4_0_8x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { const int qk = QK8_0; const int nb = n / qk; const int ncols_interleaved = 8; @@ -1363,13 +1364,13 @@ void _mllm_gemv_q4_0_8x8_q8_0_bias(int n, float *__restrict s, size_t bs, const } // lhs: q8_0, rhs: q4_0x4 -void mllm_gemm_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void gemm_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { if (bias != nullptr) { - _mllm_gemm_q4_0_4x4_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); + _gemm_q4_0_4x4_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); #if defined(__ARM_NEON) - std::cout << "_mllm_gemm_q4_0_4x4_q8_0_bias not implemented"; + std::cout << "_gemm_q4_0_4x4_q8_0_bias not implemented"; abort(); #endif return; @@ -1908,9 +1909,9 @@ void mllm_gemm_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void * #endif } -void _mllm_gemm_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void _gemm_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { const int qk = QK8_0; const int nb = n / qk; const int ncols_interleaved = 4; @@ -2472,15 +2473,15 @@ void _mllm_gemm_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const #endif } -void mllm_gemm_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void gemm_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { if (bias != nullptr) { #if defined(__ARM_NEON) - std::cout << "_mllm_gemm_q4_0_4x8_q8_0_bias not implemented"; + std::cout << "_gemm_q4_0_4x8_q8_0_bias not implemented"; abort(); #endif - _mllm_gemm_q4_0_4x8_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); + _gemm_q4_0_4x8_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); return; } @@ -2957,9 +2958,9 @@ void mllm_gemm_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void * #endif } -void _mllm_gemm_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void _gemm_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { const int qk = QK8_0; const int nb = n / qk; const int ncols_interleaved = 4; @@ -3437,15 +3438,15 @@ void _mllm_gemm_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const #endif } -void mllm_gemm_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void gemm_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { if (bias != nullptr) { #if defined(__ARM_NEON) - std::cout << "_mllm_gemm_q4_0_8x8_q8_0_bias not implemented"; + std::cout << "_gemm_q4_0_8x8_q8_0_bias not implemented"; abort(); #endif - _mllm_gemm_q4_0_8x8_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); + _gemm_q4_0_8x8_q8_0_bias(n, s, bs, vx, vy, nr, nc, bias); return; } @@ -3948,9 +3949,9 @@ void mllm_gemm_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void * #endif } -void _mllm_gemm_q4_0_8x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, - const void *__restrict vy, int nr, int nc, - const void *__restrict bias) { +void _gemm_q4_0_8x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, + const void *__restrict vy, int nr, int nc, + const void *__restrict bias) { const int qk = QK8_0; const int nb = n / qk; const int ncols_interleaved = 8; diff --git a/src/backends/cpu/third_party/ggml/GemmPack.hpp b/src/backends/cpu/third_party/ggml/GemmPack.hpp new file mode 100644 index 000000000..ca5ecb8a2 --- /dev/null +++ b/src/backends/cpu/third_party/ggml/GemmPack.hpp @@ -0,0 +1,44 @@ +#ifndef MLLM_GEMM_AARCH64_HPP +#define MLLM_GEMM_AARCH64_HPP + +#include +#include +// using namespace mllm; + +// Quantization +void quantize_q8_0_4x4(const float *__restrict x, void *__restrict y, int64_t k); +void quantize_q8_0_4x8(const float *__restrict x, void *__restrict y, int64_t k); + +void quantize_mat_q8_0(const float *__restrict x, void *__restrict y, int64_t nrows, int64_t n_per_row, int64_t blck_size_interleave); + +// Quantization utilizing an importance matrix (a.k.a. "Activation aWare Quantization") +size_t quantize_q4_0_4x4(const float *__restrict src, void *__restrict dst, int64_t nrows, int64_t n_per_row, const float *imatrix); +size_t quantize_q4_0_4x8(const float *__restrict src, void *__restrict dst, int64_t nrows, int64_t n_per_row, const float *imatrix); +size_t quantize_q4_0_8x8(const float *__restrict src, void *__restrict dst, int64_t nrows, int64_t n_per_row, const float *imatrix); + +//===----------------------------------------------------------------------===// +// GEMV +//===----------------------------------------------------------------------===// +void gemv_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); +void gemv_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); +void gemv_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); + +// NOTE: Do not add a bias flag in gemv_q4_0_4x4_q8_0. It may cause branch miss hit problem. +void _gemv_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); +void _gemv_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); +void _gemv_q4_0_8x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); + +//===----------------------------------------------------------------------===// +// GEMM +//===----------------------------------------------------------------------===// +void gemm_q4_0_4x4_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); +void gemm_q4_0_4x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); +void gemm_q4_0_8x8_q8_0(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias = nullptr); +void _gemm_q4_0_4x4_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); +void _gemm_q4_0_4x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); +void _gemm_q4_0_8x8_q8_0_bias(int n, float *__restrict s, size_t bs, const void *__restrict vx, const void *__restrict vy, int nr, int nc, const void *__restrict bias); + +void quantize_row_q4_0_4x4(const float *__restrict x, void *__restrict y, int k); +void quantize_row_q4_0_4x4(const float *__restrict x, void *__restrict y, int k, int raw); + +#endif // MLLM_GEMM_HPP \ No newline at end of file diff --git a/src/backends/cpu/compute/Quantize.hpp b/src/backends/cpu/third_party/ggml/Quantize.hpp similarity index 94% rename from src/backends/cpu/compute/Quantize.hpp rename to src/backends/cpu/third_party/ggml/Quantize.hpp index b2a0abc8f..b41b77ce2 100644 --- a/src/backends/cpu/compute/Quantize.hpp +++ b/src/backends/cpu/third_party/ggml/Quantize.hpp @@ -32,13 +32,13 @@ #include "assert.h" #include "math.h" #include -#include #include "Types.hpp" #include +#include "QuantizeFP16.hpp" -// #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) -// #include -// #endif +#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) +#include +#endif #undef MIN #undef MAX @@ -71,89 +71,6 @@ #endif #endif -#if defined(__ARM_NEON) && !defined(_MSC_VER) -#include -#define MLLM_COMPUTE_FP16_TO_FP32(x) ((float)(x)) -#define MLLM_COMPUTE_FP32_TO_FP16(x) ((mllm_fp16_t)x) - -#define MLLM_FP16_TO_FP32(x) ((float)(x)) -#define MLLM_FP32_TO_FP16(x) ((mllm_fp16_t)x) - -#elif defined _MSC_VER -#define MLLM_COMPUTE_FP16_TO_FP32(x) _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(x))) -#define MLLM_COMPUTE_FP32_TO_FP16(x) _mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(x), 0), 0) - -static float table_f32_f16[1 << 16]; -static bool table_f32_f16_init = false; - -inline static float lookup_fp16_to_fp32(uint16_t f) { - if (!table_f32_f16_init) { - uint16_t ii; - for (int i = 0; i < (1 << 16); ++i) { - uint16_t ui = i; - memcpy(&ii, &ui, sizeof(ii)); - table_f32_f16[i] = MLLM_COMPUTE_FP16_TO_FP32(ii); - } - table_f32_f16_init = true; - } - uint16_t s; - memcpy(&s, &f, sizeof(uint16_t)); - return table_f32_f16[s]; -} - -#define MLLM_FP16_TO_FP32(x) lookup_fp16_to_fp32(x) -#define MLLM_FP32_TO_FP16(x) MLLM_COMPUTE_FP32_TO_FP16(x) - -#else -#define MLLM_COMPUTE_FP16_TO_FP32(x) _cvtsh_ss(x) -#define MLLM_COMPUTE_FP32_TO_FP16(x) _cvtss_sh(x, 0) - -static float table_f32_f16[1 << 16]; -static bool table_f32_f16_init = false; - -inline static float lookup_fp16_to_fp32(uint16_t f) { - if (!table_f32_f16_init) { - uint16_t ii; - for (int i = 0; i < (1 << 16); ++i) { - uint16_t ui = i; - memcpy(&ii, &ui, sizeof(ii)); - table_f32_f16[i] = MLLM_COMPUTE_FP16_TO_FP32(ii); - } - table_f32_f16_init = true; - } - uint16_t s; - memcpy(&s, &f, sizeof(uint16_t)); - return table_f32_f16[s]; -} - -#define MLLM_FP16_TO_FP32(x) lookup_fp16_to_fp32(x) -#define MLLM_FP32_TO_FP16(x) MLLM_COMPUTE_FP32_TO_FP16(x) -#endif - -static mllm_fp16_t table_exp_f16[1 << 16]; -static bool init_table_exp_f16_flag = false; -inline void init_table_exp_f16() { - mllm_fp16_t ii; - for (int i = 0; i < (1 << 16); ++i) { - uint16_t ui = i; - memcpy(&ii, &ui, sizeof(ii)); - const float f = MLLM_COMPUTE_FP16_TO_FP32(ii); - table_exp_f16[i] = MLLM_FP32_TO_FP16(expf(f)); - // float val = MLLM_FP16_TO_FP32(expf(f)); - // std::cout< +#include "Types.hpp" +#include + +// #if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) +// #include +// #endif + +#undef MIN +#undef MAX +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + +// 16-bit float +// on Arm, we use __fp16 +// on x86, we use uint16_t +#ifdef __ARM_NEON + +#else + +#ifdef __wasm_simd128__ +#include +#else +#ifdef __POWER9_VECTOR__ +#include +#undef bool +#define bool _Bool +#else +#if defined(_MSC_VER) || defined(__MINGW32__) +#include +#else +#if !defined(__riscv) +#include +#endif +#endif +#endif +#endif +#endif + +// fp32<->fp16 start // +#if defined(__ARM_NEON) && !defined(_MSC_VER) +#include +#define MLLM_COMPUTE_FP16_TO_FP32(x) ((float)(x)) +#define MLLM_COMPUTE_FP32_TO_FP16(x) ((mllm_fp16_t)x) + +#define MLLM_FP16_TO_FP32(x) ((float)(x)) +#define MLLM_FP32_TO_FP16(x) ((mllm_fp16_t)x) + +#elif defined _MSC_VER +#define MLLM_COMPUTE_FP16_TO_FP32(x) _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(x))) +#define MLLM_COMPUTE_FP32_TO_FP16(x) _mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(x), 0), 0) + +static float table_f32_f16[1 << 16]; +static bool table_f32_f16_init = false; + +inline static float lookup_fp16_to_fp32(uint16_t f) { + if (!table_f32_f16_init) { + uint16_t ii; + for (int i = 0; i < (1 << 16); ++i) { + uint16_t ui = i; + memcpy(&ii, &ui, sizeof(ii)); + table_f32_f16[i] = MLLM_COMPUTE_FP16_TO_FP32(ii); + } + table_f32_f16_init = true; + } + uint16_t s; + memcpy(&s, &f, sizeof(uint16_t)); + return table_f32_f16[s]; +} + +#define MLLM_FP16_TO_FP32(x) lookup_fp16_to_fp32(x) +#define MLLM_FP32_TO_FP16(x) MLLM_COMPUTE_FP32_TO_FP16(x) + +#else +#define MLLM_COMPUTE_FP16_TO_FP32(x) _cvtsh_ss(x) +#define MLLM_COMPUTE_FP32_TO_FP16(x) _cvtss_sh(x, 0) + +static float table_f32_f16[1 << 16]; +static bool table_f32_f16_init = false; + +inline static float lookup_fp16_to_fp32(uint16_t f) { + if (!table_f32_f16_init) { + uint16_t ii; + for (int i = 0; i < (1 << 16); ++i) { + uint16_t ui = i; + memcpy(&ii, &ui, sizeof(ii)); + table_f32_f16[i] = MLLM_COMPUTE_FP16_TO_FP32(ii); + } + table_f32_f16_init = true; + } + uint16_t s; + memcpy(&s, &f, sizeof(uint16_t)); + return table_f32_f16[s]; +} + +#define MLLM_FP16_TO_FP32(x) lookup_fp16_to_fp32(x) +#define MLLM_FP32_TO_FP16(x) MLLM_COMPUTE_FP32_TO_FP16(x) +#endif + +static mllm_fp16_t table_exp_f16[1 << 16]; +static bool init_table_exp_f16_flag = false; +inline void init_table_exp_f16() { + mllm_fp16_t ii; + for (int i = 0; i < (1 << 16); ++i) { + uint16_t ui = i; + memcpy(&ii, &ui, sizeof(ii)); + const float f = MLLM_COMPUTE_FP16_TO_FP32(ii); + table_exp_f16[i] = MLLM_FP32_TO_FP16(expf(f)); + } +} + +// fp32<->fp16 end // + +#endif // MLLM_QUANTIZEFP16_HPP \ No newline at end of file diff --git a/src/backends/cpu/compute/QuantizeQ2.cpp b/src/backends/cpu/third_party/ggml/QuantizeQ2.cpp similarity index 92% rename from src/backends/cpu/compute/QuantizeQ2.cpp rename to src/backends/cpu/third_party/ggml/QuantizeQ2.cpp index 713cde23a..74cbf61e6 100644 --- a/src/backends/cpu/compute/QuantizeQ2.cpp +++ b/src/backends/cpu/third_party/ggml/QuantizeQ2.cpp @@ -29,6 +29,59 @@ #include #include "QuantizeQ2.hpp" #include "Quantize.hpp" +#include // For std::min/max on some platforms + +// 修正后的量化函数 +void quantize_row_q2_0_reference(const float *__restrict x, block_q2_0 *__restrict y, int k) { + static const int QK = QK2_0; + assert(k % QK == 0); + const int nb = k / QK; + + for (int i = 0; i < nb; i++) { + float amax = 0.0f; // absolute max + for (int j = 0; j < QK; j++) { + amax = std::max(amax, fabsf(x[i * QK + j])); + } + + const float d = -amax / 1.0f; // d is negative or zero + const float id = (d != 0.0f) ? 1.0f / d : 0.0f; + + y[i].d = MLLM_FP32_TO_FP16(d); + + for (int j = 0; j < QK / 4; ++j) { + y[i].qs[j] = 0; + for (int l = 0; l < 4; ++l) { + const float x0 = x[i * QK + j * 4 + l] * id; + const uint8_t xi0 = static_cast(fminf(3, roundf(x0 + 2.0f))); + y[i].qs[j] |= (xi0 << (l * 2)); + } + } + } +} + +void quantize_row_q2_0(const float *__restrict x, void *__restrict y, int k) { + quantize_row_q2_0_reference(x, (block_q2_0 *)y, k); +} + +// 修正后的反量化函数 +void dequantize_row_q2_0(const void *__restrict vx, float *__restrict y, int k) { + static const int QK = QK2_0; + assert(k % QK == 0); + + const block_q2_0 *__restrict x = (const block_q2_0 *)vx; + const int nb = k / QK; + + for (int i = 0; i < nb; i++) { + const float d = MLLM_FP16_TO_FP32(x[i].d); + + for (int j = 0; j < QK / 4; ++j) { + for (int l = 0; l < 4; ++l) { + const int x0 = ((x[i].qs[j] >> (l * 2)) & 0x03) - 2; + y[i * QK + j * 4 + l] = x0 * d; + } + } + } +} static float make_qkx2_quants(int n, int nmax, const float *__restrict x, const float *__restrict weights, uint8_t *__restrict L, float *__restrict the_min, uint8_t *__restrict Laux, diff --git a/src/backends/cpu/compute/QuantizeQ2.hpp b/src/backends/cpu/third_party/ggml/QuantizeQ2.hpp similarity index 92% rename from src/backends/cpu/compute/QuantizeQ2.hpp rename to src/backends/cpu/third_party/ggml/QuantizeQ2.hpp index c1034a0e2..bd4f8b636 100644 --- a/src/backends/cpu/compute/QuantizeQ2.hpp +++ b/src/backends/cpu/third_party/ggml/QuantizeQ2.hpp @@ -30,6 +30,9 @@ #include "Types.hpp" +void quantize_row_q2_0(const float *__restrict x, void *__restrict y, int k); +void dequantize_row_q2_0(const void *__restrict x, float *__restrict y, int k); + void quantize_row_q2_K(const float *__restrict x, void *__restrict y, int k); void dequantize_row_q2_K(const block_q2_K *__restrict x, float *__restrict y, int64_t k); diff --git a/src/backends/cpu/compute/QuantizeQ3.cpp b/src/backends/cpu/third_party/ggml/QuantizeQ3.cpp similarity index 100% rename from src/backends/cpu/compute/QuantizeQ3.cpp rename to src/backends/cpu/third_party/ggml/QuantizeQ3.cpp diff --git a/src/backends/cpu/compute/QuantizeQ3.hpp b/src/backends/cpu/third_party/ggml/QuantizeQ3.hpp similarity index 100% rename from src/backends/cpu/compute/QuantizeQ3.hpp rename to src/backends/cpu/third_party/ggml/QuantizeQ3.hpp diff --git a/src/backends/cpu/compute/QuantizeQ4.cpp b/src/backends/cpu/third_party/ggml/QuantizeQ4.cpp similarity index 100% rename from src/backends/cpu/compute/QuantizeQ4.cpp rename to src/backends/cpu/third_party/ggml/QuantizeQ4.cpp diff --git a/src/backends/cpu/compute/QuantizeQ4.hpp b/src/backends/cpu/third_party/ggml/QuantizeQ4.hpp similarity index 100% rename from src/backends/cpu/compute/QuantizeQ4.hpp rename to src/backends/cpu/third_party/ggml/QuantizeQ4.hpp diff --git a/src/backends/cpu/compute/QuantizeQ6.cpp b/src/backends/cpu/third_party/ggml/QuantizeQ6.cpp similarity index 100% rename from src/backends/cpu/compute/QuantizeQ6.cpp rename to src/backends/cpu/third_party/ggml/QuantizeQ6.cpp diff --git a/src/backends/cpu/compute/QuantizeQ6.hpp b/src/backends/cpu/third_party/ggml/QuantizeQ6.hpp similarity index 100% rename from src/backends/cpu/compute/QuantizeQ6.hpp rename to src/backends/cpu/third_party/ggml/QuantizeQ6.hpp diff --git a/src/backends/cpu/compute/QuantizeQ8.cpp b/src/backends/cpu/third_party/ggml/QuantizeQ8.cpp similarity index 100% rename from src/backends/cpu/compute/QuantizeQ8.cpp rename to src/backends/cpu/third_party/ggml/QuantizeQ8.cpp diff --git a/src/backends/cpu/compute/QuantizeQ8.hpp b/src/backends/cpu/third_party/ggml/QuantizeQ8.hpp similarity index 100% rename from src/backends/cpu/compute/QuantizeQ8.hpp rename to src/backends/cpu/third_party/ggml/QuantizeQ8.hpp diff --git a/src/backends/cpu/third_party/ggml/VecDotFP16.cpp b/src/backends/cpu/third_party/ggml/VecDotFP16.cpp new file mode 100644 index 000000000..286db0f01 --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotFP16.cpp @@ -0,0 +1,64 @@ +/* + * This code is based on ggml(https://github.com/ggerganov/ggml), + * please see https://github.com/ggerganov/ggml/blob/master/src/ggml.c + * ggml is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "VecDotFP16.hpp" + +void vec_dot_fp16(const int n, float *__restrict s, const mllm_fp16_t *__restrict vx, const mllm_fp16_t *__restrict vy) { + float sumf = 0.0; + +#if defined(__AVX2__) || defined(__ARM_NEON) + const int np = (n & ~(MLLM_F16_STEP - 1)); + + MLLM_F16_VEC sum[MLLM_F16_ARR] = {MLLM_F16_VEC_ZERO}; + + MLLM_F16_VEC ax[MLLM_F16_ARR]; + MLLM_F16_VEC ay[MLLM_F16_ARR]; + + for (int i = 0; i < np; i += MLLM_F16_STEP) { + for (int j = 0; j < MLLM_F16_ARR; j++) { + ax[j] = MLLM_F16_VEC_LOAD(vx + i + j * MLLM_F16_EPR, j); + ay[j] = MLLM_F16_VEC_LOAD(vy + i + j * MLLM_F16_EPR, j); + + sum[j] = MLLM_F16_VEC_FMA(sum[j], ax[j], ay[j]); + } + } + + // reduce sum0..sum3 to sum0 + MLLM_F16_VEC_REDUCE(sumf, sum); + + // leftovers + for (int i = np; i < n; ++i) { + sumf += (float)(MLLM_FP16_TO_FP32(vx[i]) * MLLM_FP16_TO_FP32(vy[i])); + } +#else + for (int i = 0; i < n; ++i) { + sumf += (float)(MLLM_FP16_TO_FP32(vx[i]) * MLLM_FP16_TO_FP32(vy[i])); + } +#endif + + *s = sumf; +} diff --git a/src/backends/cpu/third_party/ggml/VecDotFP16.hpp b/src/backends/cpu/third_party/ggml/VecDotFP16.hpp new file mode 100644 index 000000000..a53d78567 --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotFP16.hpp @@ -0,0 +1,33 @@ +/* + * This code is based on mllm(https://github.com/ggerganov/mllm), + * please see https://github.com/ggerganov/mllm/blob/master/src/mllm.c + * mllm is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once +#include "ComputeUtils.hpp" + +// using namespace mllm; + +void vec_dot_fp16(const int n, float *__restrict s, const mllm_fp16_t *__restrict vx, const mllm_fp16_t *__restrict vy); \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotFP32.cpp b/src/backends/cpu/third_party/ggml/VecDotFP32.cpp new file mode 100644 index 000000000..ae54ddc2c --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotFP32.cpp @@ -0,0 +1,177 @@ +/* + * This code is based on ggml(https://github.com/ggerganov/ggml), + * please see https://github.com/ggerganov/ggml/blob/master/src/ggml.c + * ggml is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "VecDotFP32.hpp" + +#ifdef __AVX2__ +static void vec_dot_fp32_avx2(const int n, float *__restrict s, const float *__restrict x, const float *__restrict y) { + float sumf = 0.0F; + const int np = (n & ~(MLLM_F32_STEP - 1)); + + MLLM_F32_VEC sum[MLLM_F32_ARR] = {MLLM_F32_VEC_ZERO}; + + MLLM_F32_VEC ax[MLLM_F32_ARR]; + MLLM_F32_VEC ay[MLLM_F32_ARR]; + + for (int i = 0; i < np; i += MLLM_F32_STEP) { + for (int j = 0; j < MLLM_F32_ARR; j++) { + ax[j] = MLLM_F32_VEC_LOAD(x + i + j * MLLM_F32_EPR); + ay[j] = MLLM_F32_VEC_LOAD(y + i + j * MLLM_F32_EPR); + + sum[j] = MLLM_F32_VEC_FMA(sum[j], ax[j], ay[j]); + } + } + + // reduce sum0..sum3 to sum0 + MLLM_F32_VEC_REDUCE(sumf, sum); + + // leftovers + for (int i = np; i < n; ++i) { + sumf += x[i] * y[i]; + } + + *s = sumf; +} +#endif + +#ifdef __ARM_NEON +static void vec_dot_fp32_arm(const int n, float *__restrict s, const float *__restrict x, const float *__restrict y) { + float sumf = 0.0F; + const int np = (n & ~(16 - 1)); + + F32_VEC sum[4] = {vdupq_n_f32(0.0F)}; + + F32_VEC ax[F32_ARR]; + F32_VEC ay[F32_ARR]; + + for (int i = 0; i < np; i += F32_STEP) { + for (int j = 0; j < F32_ARR; j++) { + ax[j] = vld1q_f32(x + i + j * F32_REG); + ay[j] = vld1q_f32(y + i + j * F32_REG); + sum[j] = vfmaq_f32(sum[j], ax[j], ay[j]); + // sum[j] = vmlaq_lane_f32(sum[j], ax[j], ay[0], + } + } + + // reduce sum0..sum3 to sum0 + F32_VEC_REDUCE(sumf, sum); + + // leftovers + for (int i = np; i < n; ++i) { + sumf += x[i] * y[i]; + } + + *s = sumf; +} +#endif + +void vec_dot_fp32(const int n, float *__restrict s, const float *__restrict vx, const float *__restrict vy) { +#ifdef __AVX2__ + vec_dot_fp32_avx2(n, s, vx, vy); +#elif defined(__ARM_NEON) + vec_dot_fp32_arm(n, s, vx, vy); +#endif +} + +#ifdef __AVX2__ +static void vec_value_dot_fp32_avx2(const int n, float *__restrict s, const float *__restrict x, const float *__restrict y, bool addition) { + float sumf = 0.0F; + const int np = (n & ~(MLLM_F32_STEP - 1)); + + MLLM_F32_VEC sum[MLLM_F32_ARR] = {MLLM_F32_VEC_ZERO}; + + MLLM_F32_VEC ax[MLLM_F32_ARR]; + MLLM_F32_VEC ay[MLLM_F32_ARR]; + + for (int i = 0; i < np; i += MLLM_F32_STEP) { + for (int j = 0; j < MLLM_F32_ARR; j++) { + ax[j] = MLLM_F32_VEC_LOAD(x + i + j * MLLM_F32_EPR); + ay[j] = MLLM_F32_VEC_LOAD(y + i + j * MLLM_F32_EPR); + + sum[j] = MLLM_F32_VEC_FMA(sum[j], ax[j], ay[j]); + } + } + + // reduce sum0..sum3 to sum0 + MLLM_F32_VEC_REDUCE(sumf, sum); + + // leftovers + for (int i = np; i < n; ++i) { + sumf += x[i] * y[i]; + } + + *s = sumf; +} +#endif + +#ifdef __ARM_NEON +// s:vector k +// x:value +// y:vector k +static void vec_value_dot_fp32_arm(const int n, float *__restrict s, const float x, const float *__restrict y, bool addition) { + int i; + float32x4_t vec_x; + float32x4_t vec_y; + float32x4_t vec_s; + + vec_x = vdupq_n_f32(x); + + int n_aligned = n & -4; + + if (addition) { + for (i = 0; i < n_aligned; i += 4) { + vec_y = vld1q_f32(y + i); + vec_s = vmulq_f32(vec_x, vec_y); + vec_s = vaddq_f32(vec_s, vld1q_f32(s + i)); + vst1q_f32(s + i, vec_s); + } + } else { + for (i = 0; i < n_aligned; i += 4) { + vec_y = vld1q_f32(y + i); + vec_s = vmulq_f32(vec_x, vec_y); + vst1q_f32(s + i, vec_s); + } + } + for (; i < n; ++i) { + if (addition) + s[i] += x * y[i]; + else { + s[i] = x * y[i]; + } + } +} +#endif + +#ifdef __AVX2__ +void vec_value_dot_fp32(const int n, float *__restrict s, const float *x, const float *__restrict vy, bool addition) { + vec_value_dot_fp32_avx2(n, s, x, vy, addition); +} +#elif defined(__ARM_NEON) +void vec_value_dot_fp32(const int n, float *__restrict s, const float x, const float *__restrict vy, bool addition) { + vec_value_dot_fp32_arm(n, s, x, vy, addition); +} +#endif diff --git a/src/backends/cpu/third_party/ggml/VecDotFP32.hpp b/src/backends/cpu/third_party/ggml/VecDotFP32.hpp new file mode 100644 index 000000000..e9adb24c4 --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotFP32.hpp @@ -0,0 +1,76 @@ +/* + * This code is based on mllm(https://github.com/ggerganov/mllm), + * please see https://github.com/ggerganov/mllm/blob/master/src/mllm.c + * mllm is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once +#include "ComputeUtils.hpp" + +// using namespace mllm; + +inline static void vec_scale_f32(const int n, float *y, const float v) { + const int np = (n & ~(MLLM_F32_STEP - 1)); + + MLLM_F32_VEC vx = MLLM_F32_VEC_SET1(v); + + MLLM_F32_VEC ay[MLLM_F32_ARR]; + + for (int i = 0; i < np; i += MLLM_F32_STEP) { + for (int j = 0; j < MLLM_F32_ARR; j++) { + ay[j] = MLLM_F32_VEC_LOAD(y + i + j * MLLM_F32_EPR); + ay[j] = MLLM_F32_VEC_MUL(ay[j], vx); + + MLLM_F32_VEC_STORE(y + i + (j * MLLM_F32_EPR), ay[j]); + } + } + + // leftovers + for (int i = np; i < n; ++i) { + y[i] *= v; + } +} + +inline void vec_mul_fp32(const int n, float *__restrict s, const float *__restrict x, const float *__restrict y) { + int i = 0; + const int np = (n & ~(MLLM_F32_STEP - 1)); + MLLM_F32_VEC ax[MLLM_F32_ARR]; + MLLM_F32_VEC ay[MLLM_F32_ARR]; + MLLM_F32_VEC as[MLLM_F32_ARR]; + for (i = 0; i < np; i += MLLM_F32_STEP) { + for (int j = 0; j < MLLM_F32_ARR; j++) { + ax[j] = MLLM_F32_VEC_LOAD(x + i + j * MLLM_F32_EPR); + ay[j] = MLLM_F32_VEC_LOAD(y + i + j * MLLM_F32_EPR); + as[j] = MLLM_F32_VEC_MUL(ax[j], ay[j]); + MLLM_F32_VEC_STORE(s + i + (j * MLLM_F32_EPR), as[j]); + } + } + for (; i < n; ++i) { + s[i] = x[i] * y[i]; + } +} + +void vec_dot_fp32(const int n, float *__restrict s, const float *__restrict vx, const float *__restrict vy); +// for sparse linear +void vec_value_dot_fp32(const int n, float *__restrict s, const float x, const float *__restrict vy, bool addition); \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ2.cpp b/src/backends/cpu/third_party/ggml/VecDotQ2.cpp new file mode 100644 index 000000000..089be4674 --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ2.cpp @@ -0,0 +1,1526 @@ +/* + * This code is based on ggml(https://github.com/ggerganov/ggml), + * please see https://github.com/ggerganov/ggml/blob/master/src/ggml.c + * ggml is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "VecDotQ2.hpp" +#include "ComputeUtils.hpp" + +void vec_dot_q2_0_q8_0(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + const int qk = QK8_0; + const int nb = n / qk; + + assert(n % qk == 0); + + const auto *__restrict x = static_cast(vx); + const auto *__restrict y = static_cast(vy); + +#if defined(__AVX2__) + // AVX2 implementation + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + const __m256 d_vec = _mm256_set1_ps(MLLM_FP16_TO_FP32(x[i].d) * MLLM_FP16_TO_FP32(y[i].d)); + + const __m128i q2_packed = _mm_loadl_epi64(reinterpret_cast(x[i].qs)); + + const __m256i pshufb_mask = _mm256_setr_epi8( + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7); + const __m256i q2_bytes = _mm256_shuffle_epi8(_mm256_set_m128i(_mm_setzero_si128(), q2_packed), pshufb_mask); + + const __m256i shift_const = _mm256_set_epi32(0, 2, 4, 6, 0, 2, 4, 6); + const __m256i q2_shifted = _mm256_srlv_epi32(q2_bytes, shift_const); + const __m256i q2_isolated = _mm256_and_si256(q2_shifted, _mm256_set1_epi8(0x03)); + const __m256i q2_final = _mm256_sub_epi8(q2_isolated, _mm256_set1_epi8(2)); + + const __m256i q8_data = _mm256_loadu_si256(reinterpret_cast(y[i].qs)); + + const __m256i products = _mm256_maddubs_epi16(q2_final, q8_data); + const __m256i sum_lanes = _mm256_madd_epi16(_mm256_set1_epi16(1), products); + + acc = _mm256_fmadd_ps(_mm256_cvtepi32_ps(sum_lanes), d_vec, acc); + } + *s = hsum_float_8(acc); + +#elif defined(__ARM_NEON) + // ARM NEON implementation + float32x4_t sumv = vdupq_n_f32(0.0f); + + for (int i = 0; i < nb; i++) { + const float d = MLLM_FP16_TO_FP32(x[i].d) * MLLM_FP16_TO_FP32(y[i].d); + const float32x4_t d_vec = vdupq_n_f32(d); + + int32x4_t isum_block = vdupq_n_s32(0); + + const uint8_t *q2_ptr = x[i].qs; + const int8_t *q8_ptr = y[i].qs; + + // Unpack 8 bytes of Q2 data into a temporary 32-byte array + int8_t q2_unpacked[32]; + for (int j = 0; j < 8; ++j) { + uint8_t b = q2_ptr[j]; + q2_unpacked[j * 4 + 0] = ((b >> 0) & 3) - 2; + q2_unpacked[j * 4 + 1] = ((b >> 2) & 3) - 2; + q2_unpacked[j * 4 + 2] = ((b >> 4) & 3) - 2; + q2_unpacked[j * 4 + 3] = ((b >> 6) & 3) - 2; + } + + // Perform dot product on unpacked data + const int8x16_t q2_v0 = vld1q_s8(&q2_unpacked[0]); + const int8x16_t q2_v1 = vld1q_s8(&q2_unpacked[16]); + + const int8x16_t q8_v0 = vld1q_s8(q8_ptr); + const int8x16_t q8_v1 = vld1q_s8(q8_ptr + 16); + + const int16x8_t p0 = vmull_s8(vget_low_s8(q2_v0), vget_low_s8(q8_v0)); + const int16x8_t p1 = vmull_s8(vget_high_s8(q2_v0), vget_high_s8(q8_v0)); + const int16x8_t p2 = vmull_s8(vget_low_s8(q2_v1), vget_low_s8(q8_v1)); + const int16x8_t p3 = vmull_s8(vget_high_s8(q2_v1), vget_high_s8(q8_v1)); + + isum_block = vcombine_s32( + vpadd_s32(vpaddl_s16(vget_low_s16(p0)), vpaddl_s16(vget_high_s16(p0))), + vpadd_s32(vpaddl_s16(vget_low_s16(p1)), vpaddl_s16(vget_high_s16(p1)))); + isum_block = vaddq_s32(isum_block, vcombine_s32( + vpadd_s32(vpaddl_s16(vget_low_s16(p2)), vpaddl_s16(vget_high_s16(p2))), + vpadd_s32(vpaddl_s16(vget_low_s16(p3)), vpaddl_s16(vget_high_s16(p3))))); + + sumv = vmlaq_f32(sumv, vcvtq_f32_s32(isum_block), d_vec); + } + *s = vaddvq_f32(sumv); + +#else + // Fallback scalar implementation + float sumf = 0.0; + for (int i = 0; i < nb; ++i) { + const float d = MLLM_FP16_TO_FP32(x[i].d) * MLLM_FP16_TO_FP32(y[i].d); + int32_t isum = 0; + for (int j = 0; j < qk / 4; ++j) { + uint8_t packed_q2 = x[i].qs[j]; + for (int l = 0; l < 4; ++l) { + const int8_t x0 = ((packed_q2 >> (l * 2)) & 3) - 2; + isum += x0 * y[i].qs[j * 4 + l]; + } + } + sumf += d * isum; + } + *s = sumf; +#endif +} + +void vec_dot_q2_K_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + const block_q2_K *__restrict x = (block_q2_K *)vx; + const block_q8_K *__restrict y = (block_q8_K *)vy; + + const int nb = n / QK_K; + +#ifdef __ARM_FEATURE_SVE + const int vector_length = svcntb() * 8; + const svuint8_t m3s = svdup_n_u8(0x3); + const svuint32_t m4s = svdup_n_u32(0xF); + const svint32_t vzero_sv = svdup_n_s32(0); + svfloat32_t acc_sum = svdup_n_f32(0); + svbool_t pred_s32 = svptrue_pat_b32(SV_VL4); + + switch (vector_length) { + case 128: + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + svfloat32_t d_broad = svdup_n_f32((float32_t)d); + const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + svfloat32_t dmin_broad = svdup_n_f32((float32_t)dmin); + + const uint8_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8_sv = y[i].qs; + const uint8_t *__restrict sc = x[i].scales; + + svuint32_t mins_and_scales_sve = svld1ub_u32(svptrue_b32(), sc); + const svint32_t mins_sv_1 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_b32(), mins_and_scales_sve, 4)); + + mins_and_scales_sve = svld1ub_u32(svptrue_b32(), sc + 4); + const svint32_t mins_sv_2 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_b32(), mins_and_scales_sve, 4)); + + svint32_t q8sums_sv_1 = svld1sh_s32(svptrue_b32(), y[i].bsums); + svint32_t q8sums_sv_2 = svld1sh_s32(svptrue_b32(), y[i].bsums + 4); + + const svint32_t s0 = svadd_s32_x(svptrue_b32(), svmul_s32_x(svptrue_b32(), mins_sv_1, q8sums_sv_1), svmul_s32_x(svptrue_b32(), mins_sv_2, q8sums_sv_2)); + + mins_and_scales_sve = svld1ub_u32(svptrue_b32(), sc + 8); + const svint32_t mins_sv_3 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_b32(), mins_and_scales_sve, 4)); + + mins_and_scales_sve = svld1ub_u32(svptrue_b32(), sc + 12); + const svint32_t mins_sv_4 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_b32(), mins_and_scales_sve, 4)); + + q8sums_sv_1 = svld1sh_s32(svptrue_b32(), y[i].bsums + 8); + q8sums_sv_2 = svld1sh_s32(svptrue_b32(), y[i].bsums + 12); + + svint32_t s1 = svadd_s32_x(svptrue_b32(), svmul_s32_x(svptrue_b32(), mins_sv_3, q8sums_sv_1), svmul_s32_x(svptrue_b32(), mins_sv_4, q8sums_sv_2)); + + svfloat32_t temp = svcvt_f32_s32_x(svptrue_b32(), svadd_s32_x(svptrue_b32(), s0, s1)); + + acc_sum = svmla_f32_m(svptrue_b32(), acc_sum, temp, dmin_broad); + + svint32_t sumi1 = svdup_n_s32(0); + + { + const svuint8_t q2bits_1 = svld1_u8(svptrue_b8(), q2); + svint8_t q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), q2bits_1, m3s)); + svint8_t q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + const svint32_t scales_sv = svreinterpret_s32_u32(svand_u32_m(svptrue_b32(), svld1ub_u32(svptrue_b32(), sc), m4s)); + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv, 0)); + + const svuint8_t q2bits_3 = svld1_u8(svptrue_b8(), q2 + 16); + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), q2bits_3, m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv, 1)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_1, 2), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv, 2)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_3, 2), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv, 3)); + + const svint32_t scales_sv_1 = svreinterpret_s32_u32(svand_u32_m(svptrue_b32(), svld1ub_u32(svptrue_b32(), sc + 4), m4s)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_1, 4), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_1, 0)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_3, 4), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_1, 1)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_1, 6), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_1, 2)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_3, 6), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_1, 3)); + + //------------------------------- + + q2 += 32; + const svint32_t scales_sv_2 = svreinterpret_s32_u32(svand_u32_m(svptrue_b32(), svld1ub_u32(svptrue_b32(), sc + 8), m4s)); + const svuint8_t q2bits_2 = svld1_u8(svptrue_b8(), q2); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), q2bits_2, m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_2, 0)); + + const svuint8_t q2bits_4 = svld1_u8(svptrue_b8(), q2 + 16); + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), q2bits_4, m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_2, 1)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_2, 2), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_2, 2)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_4, 2), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_2, 3)); + + const svint32_t scales_sv_3 = svreinterpret_s32_u32(svand_u32_m(svptrue_b32(), svld1ub_u32(svptrue_b32(), sc + 12), m4s)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_2, 4), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_3, 0)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_4, 4), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_3, 1)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_2, 6), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_3, 2)); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q2bits_4, 6), m3s)); + q8bytes_sv = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + sumi1 = svmla_s32_m(svptrue_b32(), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), svdup_lane_s32(scales_sv_3, 3)); + } + acc_sum = svmla_f32_m(svptrue_b32(), acc_sum, svcvt_f32_s32_x(svptrue_b32(), sumi1), d_broad); + } + *s = svaddv_f32(svptrue_b32(), acc_sum); + break; + + case 256: + case 512: + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + svfloat32_t d_broad = svdup_n_f32((float32_t)d); + const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + svfloat32_t dmin_broad = svdup_n_f32((float32_t)dmin); + + const uint8_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8_sv = y[i].qs; + const uint8_t *__restrict sc = x[i].scales; + + const svuint32_t mins_and_scales_sve = svld1ub_u32(svptrue_pat_b32(SV_VL8), sc); + sc += 8; + const svint32_t scales_sv = svreinterpret_s32_u32(svand_u32_m(svptrue_pat_b32(SV_VL8), mins_and_scales_sve, m4s)); + const svint32_t mins_sv_1 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_pat_b32(SV_VL8), mins_and_scales_sve, 4)); + svint32_t q8sums_sv_1 = svld1sh_s32(svptrue_pat_b32(SV_VL8), y[i].bsums); + + const svuint32_t mins_and_scales_sve_1 = svld1ub_u32(svptrue_pat_b32(SV_VL8), sc); + const svint32_t scales_sv_1 = svreinterpret_s32_u32(svand_u32_m(svptrue_pat_b32(SV_VL8), mins_and_scales_sve_1, m4s)); + const svint32_t mins_sv_2 = svreinterpret_s32_u32(svlsr_n_u32_x(svptrue_pat_b32(SV_VL8), mins_and_scales_sve_1, 4)); + + svint32_t q8sums_sv_2 = svld1sh_s32(svptrue_pat_b32(SV_VL8), y[i].bsums + 8); + + svfloat32_t temp = svcvt_f32_s32_x(svptrue_pat_b32(SV_VL8), svadd_s32_x(svptrue_pat_b32(SV_VL8), svmul_s32_x(svptrue_pat_b32(SV_VL8), mins_sv_1, q8sums_sv_1), svmul_s32_x(svptrue_pat_b32(SV_VL8), mins_sv_2, q8sums_sv_2))); + + acc_sum = svmla_f32_m(svptrue_pat_b32(SV_VL8), acc_sum, temp, dmin_broad); + + svint32_t sumi1 = svdup_n_s32(0); + + { + const svuint8_t q2bits_1 = svld1_u8(svptrue_pat_b8(SV_VL32), q2); + svint8_t q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), q2bits_1, m3s)); + svint8_t q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + svint32_t scale_1 = svsel(pred_s32, svdup_lane_s32(scales_sv, 0), svdup_lane_s32(scales_sv, 1)); + sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_1); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_1, 2), m3s)); + q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + svint32_t scale_2 = svsel(pred_s32, svdup_lane_s32(scales_sv, 2), svdup_lane_s32(scales_sv, 3)); + sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(svdup_n_s32(0), q2bytes_sv, q8bytes_sv), scale_2); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_1, 4), m3s)); + q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + scale_1 = svsel(pred_s32, svdup_lane_s32(scales_sv, 4), svdup_lane_s32(scales_sv, 5)); + sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_1); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_1, 6), m3s)); + q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + scale_2 = svsel(pred_s32, svdup_lane_s32(scales_sv, 6), svdup_lane_s32(scales_sv, 7)); + sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_2); + + q2 += 32; + + const svuint8_t q2bits_2 = svld1_u8(svptrue_pat_b8(SV_VL32), q2); + q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), q2bits_2, m3s)); + q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + scale_1 = svsel(pred_s32, svdup_lane_s32(scales_sv_1, 0), svdup_lane_s32(scales_sv_1, 1)); + sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_1); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_2, 2), m3s)); + q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + scale_2 = svsel(pred_s32, svdup_lane_s32(scales_sv_1, 2), svdup_lane_s32(scales_sv_1, 3)); + sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_2); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_2, 4), m3s)); + q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + scale_1 = svsel(pred_s32, svdup_lane_s32(scales_sv_1, 4), svdup_lane_s32(scales_sv_1, 5)); + sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_1); + + q2bytes_sv = svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q2bits_2, 6), m3s)); + q8bytes_sv = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + scale_2 = svsel(pred_s32, svdup_lane_s32(scales_sv_1, 6), svdup_lane_s32(scales_sv_1, 7)); + sumi1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(vzero_sv, q2bytes_sv, q8bytes_sv), scale_2); + } + acc_sum = svmla_f32_m(svptrue_pat_b32(SV_VL8), acc_sum, svcvt_f32_s32_x(svptrue_pat_b32(SV_VL8), sumi1), d_broad); + } + *s = svaddv_f32(svptrue_pat_b32(SV_VL8), acc_sum); + break; + + default: + assert(false && "Unsupported vector length"); + break; + } + +#elif __ARM_NEON + const uint8x16_t m3 = vdupq_n_u8(0x3); + const uint8x16_t m4 = vdupq_n_u8(0xF); + + const int32x4_t vzero = vdupq_n_s32(0); + + mllm_int8x16x2_t q2bytes; + uint8_t aux[16]; + + float sum = 0; + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + + const uint8_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + const uint8_t *__restrict sc = x[i].scales; + + const uint8x16_t mins_and_scales = vld1q_u8(sc); + const uint8x16_t scales = vandq_u8(mins_and_scales, m4); + vst1q_u8(aux, scales); + + const uint8x16_t mins = vshrq_n_u8(mins_and_scales, 4); + const mllm_int16x8x2_t q8sums = mllm_vld1q_s16_x2(y[i].bsums); + const mllm_int16x8x2_t mins16 = {{vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(mins))), vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(mins)))}}; + const int32x4_t s0 = vaddq_s32(vmull_s16(vget_low_s16(mins16.val[0]), vget_low_s16(q8sums.val[0])), + vmull_s16(vget_high_s16(mins16.val[0]), vget_high_s16(q8sums.val[0]))); + const int32x4_t s1 = vaddq_s32(vmull_s16(vget_low_s16(mins16.val[1]), vget_low_s16(q8sums.val[1])), + vmull_s16(vget_high_s16(mins16.val[1]), vget_high_s16(q8sums.val[1]))); + sum += dmin * vaddvq_s32(vaddq_s32(s0, s1)); + + int isum = 0; + int is = 0; + + // We use this macro instead of a function call because for some reason + // the code runs 2-3% slower, even if the function is declared inline +#define MULTIPLY_ACCUM_WITH_SCALE(index) \ + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q2bytes.val[0], q8bytes.val[0])) * aux[is + (index)]; \ + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q2bytes.val[1], q8bytes.val[1])) * aux[is + 1 + (index)]; + +#define SHIFT_MULTIPLY_ACCUM_WITH_SCALE(shift, index) \ + q8bytes = mllm_vld1q_s8_x2(q8); \ + q8 += 32; \ + q2bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits.val[0], (shift)), m3)); \ + q2bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q2bits.val[1], (shift)), m3)); \ + MULTIPLY_ACCUM_WITH_SCALE((index)); + + for (int j = 0; j < QK_K / 128; ++j) { + const mllm_uint8x16x2_t q2bits = mllm_vld1q_u8_x2(q2); + q2 += 32; + + mllm_int8x16x2_t q8bytes = mllm_vld1q_s8_x2(q8); + q8 += 32; + q2bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q2bits.val[0], m3)); + q2bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q2bits.val[1], m3)); + + MULTIPLY_ACCUM_WITH_SCALE(0); + + SHIFT_MULTIPLY_ACCUM_WITH_SCALE(2, 2); + SHIFT_MULTIPLY_ACCUM_WITH_SCALE(4, 4); + SHIFT_MULTIPLY_ACCUM_WITH_SCALE(6, 6); + + is += 8; + } + + sum += d * isum; + } + + *s = sum; + +#elif defined __AVX2__ + + const __m256i m3 = _mm256_set1_epi8(3); + const __m128i m4 = _mm_set1_epi8(0xF); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + + const uint8_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + const __m128i mins_and_scales = _mm_loadu_si128((const __m128i *)x[i].scales); + const __m128i scales8 = _mm_and_si128(mins_and_scales, m4); + const __m128i mins8 = _mm_and_si128(_mm_srli_epi16(mins_and_scales, 4), m4); + const __m256i mins = _mm256_cvtepi8_epi16(mins8); + const __m256i prod = _mm256_madd_epi16(mins, _mm256_loadu_si256((const __m256i *)y[i].bsums)); + + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&dmin), _mm256_cvtepi32_ps(prod), acc); + + const __m256i all_scales = _mm256_cvtepi8_epi16(scales8); + const __m128i l_scales = _mm256_extracti128_si256(all_scales, 0); + const __m128i h_scales = _mm256_extracti128_si256(all_scales, 1); + const __m256i scales[2] = {MM256_SET_M128I(l_scales, l_scales), MM256_SET_M128I(h_scales, h_scales)}; + + __m256i sumi = _mm256_setzero_si256(); + + for (int j = 0; j < QK_K / 128; ++j) { + const __m256i q2bits = _mm256_loadu_si256((const __m256i *)q2); + q2 += 32; + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_3 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + + const __m256i q2_0 = _mm256_and_si256(q2bits, m3); + const __m256i q2_1 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 2), m3); + const __m256i q2_2 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 4), m3); + const __m256i q2_3 = _mm256_and_si256(_mm256_srli_epi16(q2bits, 6), m3); + + __m256i p0 = _mm256_maddubs_epi16(q2_0, q8_0); + __m256i p1 = _mm256_maddubs_epi16(q2_1, q8_1); + __m256i p2 = _mm256_maddubs_epi16(q2_2, q8_2); + __m256i p3 = _mm256_maddubs_epi16(q2_3, q8_3); + + p0 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(0)), p0); + p1 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(1)), p1); + p2 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(2)), p2); + p3 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(3)), p3); + + p0 = _mm256_add_epi32(p0, p1); + p2 = _mm256_add_epi32(p2, p3); + + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p0, p2)); + } + + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + + const __m128i m3 = _mm_set1_epi8(0x3); + const __m128i m4 = _mm_set1_epi8(0xF); + const __m128i m2 = _mm_set1_epi8(0x2); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + const float dall = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + + const uint8_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + // load mins and scales from block_q2_K.scales[QK_K/16] + const __m128i mins_and_scales = _mm_loadu_si128((const __m128i *)x[i].scales); + const __m128i scales16 = _mm_and_si128(mins_and_scales, m4); + const __m128i mins16 = _mm_and_si128(_mm_srli_epi16(mins_and_scales, 4), m4); + const __m128i mins_0 = _mm_cvtepi8_epi16(mins16); + const __m128i mins_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(mins16, mins16)); + + // summs = y[i].bsums * (x[i].scales >> 4) in 16bits*8*2 to 32bits*4*2 + const __m128i summs_0 = _mm_madd_epi16(mins_0, _mm_loadu_si128((const __m128i *)&y[i].bsums[0])); + const __m128i summs_1 = _mm_madd_epi16(mins_1, _mm_loadu_si128((const __m128i *)&y[i].bsums[8])); + + // sumf += -dmin * summs in 32bits*8 + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&dmin), _mm256_cvtepi32_ps(MM256_SET_M128I(summs_1, summs_0))), acc); + + const __m128i scales_0 = _mm_cvtepi8_epi16(scales16); + const __m128i scales_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(scales16, scales16)); + const __m128i scales[2] = {scales_0, scales_1}; + + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + for (int j = 0; j < QK_K / 128; ++j) { + // load Q8 quants int8*16*8 from block_q8_K.qs[QK_K] + const __m128i q8_0 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_1 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_2 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_3 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_4 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_5 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_6 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_7 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + + // load 2bits*16*8 from block_q2_K.qs[QK_K/4] + __m128i q2bits = _mm_loadu_si128((const __m128i *)q2); + q2 += 16; + const __m128i q2_0 = _mm_and_si128(q2bits, m3); + const __m128i q2_2 = _mm_and_si128(_mm_srli_epi16(q2bits, 2), m3); + const __m128i q2_4 = _mm_and_si128(_mm_srli_epi16(q2bits, 4), m3); + const __m128i q2_6 = _mm_and_si128(_mm_srli_epi16(q2bits, 6), m3); + q2bits = _mm_loadu_si128((const __m128i *)q2); + q2 += 16; + const __m128i q2_1 = _mm_and_si128(q2bits, m3); + const __m128i q2_3 = _mm_and_si128(_mm_srli_epi16(q2bits, 2), m3); + const __m128i q2_5 = _mm_and_si128(_mm_srli_epi16(q2bits, 4), m3); + const __m128i q2_7 = _mm_and_si128(_mm_srli_epi16(q2bits, 6), m3); + + // isuml = q8[l] * ((q2[l] >> shift) & 3) in 8bits*16*8 to 16bits*8*8 + __m128i p0 = _mm_maddubs_epi16(q2_0, q8_0); + __m128i p1 = _mm_maddubs_epi16(q2_1, q8_1); + __m128i p2 = _mm_maddubs_epi16(q2_2, q8_2); + __m128i p3 = _mm_maddubs_epi16(q2_3, q8_3); + __m128i p4 = _mm_maddubs_epi16(q2_4, q8_4); + __m128i p5 = _mm_maddubs_epi16(q2_5, q8_5); + __m128i p6 = _mm_maddubs_epi16(q2_6, q8_6); + __m128i p7 = _mm_maddubs_epi16(q2_7, q8_7); + + // isum += (x[i].scales[is++] & 0xF) * isuml in 16bits*8*8 to 32bits*4*8 + __m128i shuffle = _mm_set1_epi16(0x0100); + p0 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p0); + shuffle = _mm_add_epi16(shuffle, m2); + p1 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p1); + shuffle = _mm_add_epi16(shuffle, m2); + p2 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p2); + shuffle = _mm_add_epi16(shuffle, m2); + p3 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p3); + shuffle = _mm_add_epi16(shuffle, m2); + p4 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p4); + shuffle = _mm_add_epi16(shuffle, m2); + p5 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p5); + shuffle = _mm_add_epi16(shuffle, m2); + p6 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p6); + shuffle = _mm_add_epi16(shuffle, m2); + p7 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p7); + + p0 = _mm_add_epi32(p0, p1); + p2 = _mm_add_epi32(p2, p3); + p4 = _mm_add_epi32(p4, p5); + p6 = _mm_add_epi32(p6, p7); + + // isum in 32bits*4*2 + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p0, p2)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p4, p6)); + } + + // sumf += dall * isum - dmin * summs in 32bits + __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&dall), _mm256_cvtepi32_ps(sumi)), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __wasm_simd128__ + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + const uint8_t *q2 = x[i].qs; + const int8_t *q8 = y[i].qs; + const uint8_t *sc = x[i].scales; + + // Vectorized summs calculation + v128_t summs_vec = wasm_i32x4_splat(0); + { + v128_t sc_vec = wasm_v128_load(sc); + v128_t sc_upper = wasm_u8x16_shr(sc_vec, 4); + + v128_t sc_low = wasm_u16x8_extend_low_u8x16(sc_upper); + v128_t sc_high = wasm_u16x8_extend_high_u8x16(sc_upper); + + v128_t bsums1 = wasm_v128_load(&y[i].bsums[0]); + v128_t bsums2 = wasm_v128_load(&y[i].bsums[8]); + + summs_vec = wasm_i32x4_add( + wasm_i32x4_add(wasm_i32x4_dot_i16x8(sc_low, bsums1), + wasm_i32x4_dot_i16x8(sc_high, bsums2)), + summs_vec); + + summs_vec = wasm_i32x4_add(summs_vec, wasm_i32x4_shuffle(summs_vec, summs_vec, 2, 3, 0, 1)); + summs_vec = wasm_i32x4_add(summs_vec, wasm_i32x4_shuffle(summs_vec, summs_vec, 1, 0, 3, 2)); + } + int32_t summs = wasm_i32x4_extract_lane(summs_vec, 0); + + // Vectorized isum calculation + int32_t isum = 0; + const uint8_t *sc_ptr = sc; + const int k_iters = QK_K / 128; + + for (int k = 0; k < k_iters; ++k) { + v128_t isum_vec = wasm_i32x4_splat(0); + int shift = 0; + + for (int j = 0; j < 4; ++j) { + const int d0 = (sc_ptr[0] & 0xF); + const int d1 = (sc_ptr[1] & 0xF); + sc_ptr += 2; + + // Process first 16 elements + v128_t q2_0 = wasm_v128_load(q2); + v128_t q8_0 = wasm_v128_load(q8); + v128_t q2_shift_0 = wasm_u8x16_shr(q2_0, shift); + v128_t q2_bits_0 = wasm_v128_and(q2_shift_0, wasm_i8x16_splat(0x03)); + + // Process next 16 elements + v128_t q2_1 = wasm_v128_load(q2 + 16); + v128_t q8_1 = wasm_v128_load(q8 + 16); + v128_t q2_shift_1 = wasm_u8x16_shr(q2_1, shift); + v128_t q2_bits_1 = wasm_v128_and(q2_shift_1, wasm_i8x16_splat(0x03)); + + // Calculate dot products + v128_t p0 = wasm_i32x4_dot_i16x8( + wasm_i16x8_extend_low_i8x16(q8_0), + wasm_i16x8_extend_low_i8x16(q2_bits_0)); + v128_t p1 = wasm_i32x4_dot_i16x8( + wasm_i16x8_extend_high_i8x16(q8_0), + wasm_i16x8_extend_high_i8x16(q2_bits_0)); + v128_t p2 = wasm_i32x4_dot_i16x8( + wasm_i16x8_extend_low_i8x16(q8_1), + wasm_i16x8_extend_low_i8x16(q2_bits_1)); + v128_t p3 = wasm_i32x4_dot_i16x8( + wasm_i16x8_extend_high_i8x16(q8_1), + wasm_i16x8_extend_high_i8x16(q2_bits_1)); + + // Accumulate scaled results + v128_t scaled = wasm_i32x4_add( + wasm_i32x4_mul(wasm_i32x4_add(p0, p1), wasm_i32x4_splat(d0)), + wasm_i32x4_mul(wasm_i32x4_add(p2, p3), wasm_i32x4_splat(d1))); + + isum_vec = wasm_i32x4_add(isum_vec, scaled); + q8 += 32; + shift += 2; + } + q2 += 32; + + // Horizontal sum of isum_vec + isum_vec = wasm_i32x4_add(isum_vec, wasm_i32x4_shuffle(isum_vec, isum_vec, 2, 3, 0, 1)); + isum_vec = wasm_i32x4_add(isum_vec, wasm_i32x4_shuffle(isum_vec, isum_vec, 1, 0, 3, 2)); + isum += wasm_i32x4_extract_lane(isum_vec, 0); + } + + const float dall = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + const float dmin = MLLM_FP16_TO_FP32(x[i].dmin) * y[i].d; + sumf += dall * isum - dmin * summs; + } + + *s = sumf; + +#elif defined __riscv_v_intrinsic + + const int vector_length = __riscv_vlenb() * 8; + float sumf = 0; + + uint8_t temp_01[32] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + uint8_t atmp[16]; + + switch (vector_length) { + case 256: + for (int i = 0; i < nb; ++i) { + const uint8_t *q2 = x[i].qs; + const int8_t *q8 = y[i].qs; + const uint8_t *sc = x[i].scales; + + const float dall = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + + size_t vl = 16; + + vuint8m1_t scales = __riscv_vle8_v_u8m1(sc, vl); + vuint8m1_t aux = __riscv_vand_vx_u8m1(scales, 0x0F, vl); + + vint16m1_t q8sums = __riscv_vle16_v_i16m1(y[i].bsums, vl); + + vuint8mf2_t scales_2 = __riscv_vle8_v_u8mf2(sc, vl); + vuint8mf2_t mins8 = __riscv_vsrl_vx_u8mf2(scales_2, 0x4, vl); + vint16m1_t mins = __riscv_vreinterpret_v_u16m1_i16m1(__riscv_vzext_vf2_u16m1(mins8, vl)); + vint32m2_t prod = __riscv_vwmul_vv_i32m2(q8sums, mins, vl); + vint32m1_t vsums = __riscv_vredsum_vs_i32m2_i32m1(prod, __riscv_vmv_v_x_i32m1(0, 1), vl); + + sumf += dmin * __riscv_vmv_x_s_i32m1_i32(vsums); + + vl = 32; + + vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); + vuint8m1_t v_b = __riscv_vle8_v_u8m1(temp_01, vl); + + uint8_t is = 0; + int isum = 0; + + for (int j = 0; j < QK_K / 128; ++j) { + // load Q2 + vuint8m1_t q2_x = __riscv_vle8_v_u8m1(q2, vl); + + vuint8m1_t q2_0 = __riscv_vand_vx_u8m1(q2_x, 0x03, vl); + vuint8m1_t q2_1 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q2_x, 0x2, vl), 0x03, vl); + vuint8m1_t q2_2 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q2_x, 0x4, vl), 0x03, vl); + vuint8m1_t q2_3 = __riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q2_x, 0x6, vl), 0x03, vl); + + // duplicate scale elements for product + vuint8m1_t sc0 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 0 + is, vl), vl); + vuint8m1_t sc1 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 2 + is, vl), vl); + vuint8m1_t sc2 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 4 + is, vl), vl); + vuint8m1_t sc3 = __riscv_vrgather_vv_u8m1(aux, __riscv_vadd_vx_u8m1(v_b, 6 + is, vl), vl); + + vint16m2_t p0 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_0, sc0, vl)); + vint16m2_t p1 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_1, sc1, vl)); + vint16m2_t p2 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_2, sc2, vl)); + vint16m2_t p3 = __riscv_vreinterpret_v_u16m2_i16m2(__riscv_vwmulu_vv_u16m2(q2_3, sc3, vl)); + + // load Q8 + vint8m1_t q8_0 = __riscv_vle8_v_i8m1(q8, vl); + vint8m1_t q8_1 = __riscv_vle8_v_i8m1(q8 + 32, vl); + vint8m1_t q8_2 = __riscv_vle8_v_i8m1(q8 + 64, vl); + vint8m1_t q8_3 = __riscv_vle8_v_i8m1(q8 + 96, vl); + + vint32m4_t s0 = __riscv_vwmul_vv_i32m4(p0, __riscv_vwcvt_x_x_v_i16m2(q8_0, vl), vl); + vint32m4_t s1 = __riscv_vwmul_vv_i32m4(p1, __riscv_vwcvt_x_x_v_i16m2(q8_1, vl), vl); + vint32m4_t s2 = __riscv_vwmul_vv_i32m4(p2, __riscv_vwcvt_x_x_v_i16m2(q8_2, vl), vl); + vint32m4_t s3 = __riscv_vwmul_vv_i32m4(p3, __riscv_vwcvt_x_x_v_i16m2(q8_3, vl), vl); + + vint32m1_t isum0 = __riscv_vredsum_vs_i32m4_i32m1(__riscv_vadd_vv_i32m4(s0, s1, vl), vzero, vl); + vint32m1_t isum1 = __riscv_vredsum_vs_i32m4_i32m1(__riscv_vadd_vv_i32m4(s2, s3, vl), isum0, vl); + + isum += __riscv_vmv_x_s_i32m1_i32(isum1); + + q2 += 32; + q8 += 128; + is = 8; + } + + sumf += dall * isum; + } + break; + case 128: + for (int i = 0; i < nb; ++i) { + const uint8_t *q2 = x[i].qs; + const int8_t *q8 = y[i].qs; + const uint8_t *sc = x[i].scales; + const float dall = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + uint8_t *patmp = atmp; + int vsums; + int tmp; + __asm__ __volatile__( + "vsetivli zero, 16, e8, m1\n\t" + "vmv.v.x v8, zero\n\t" + "vle8.v v1, (%[sc])\n\t" + "vand.vi v0, v1, 0xF\n\t" + "vsrl.vi v1, v1, 4\n\t" + "vse8.v v0, (%[scale])\n\t" + "vsetivli zero, 16, e16, m2\n\t" + "vle16.v v2, (%[bsums])\n\t" + "vzext.vf2 v0, v1\n\t" + "vwmul.vv v4, v0, v2\n\t" + "vsetivli zero, 16, e32, m4\n\t" + "vredsum.vs v8, v4, v8\n\t" + "vmv.x.s %[vsums], v8" + : [tmp] "=&r"(tmp), [vsums] "=&r"(vsums) + : [sc] "r"(sc), [scale] "r"(atmp), [bsums] "r"(y[i].bsums) + : "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); + sumf += dmin * vsums; + int isum = 0; + + for (int j = 0; j < QK_K / 128; ++j) { + __asm__ __volatile__( + "vsetvli zero, %[vl32], e8, m2\n\t" + "vle8.v v0, (%[q2])\n\t" + "vsrl.vi v2, v0, 2\n\t" + "vsrl.vi v4, v0, 4\n\t" + "vsrl.vi v6, v0, 6\n\t" + "vand.vi v0, v0, 0x3\n\t" + "vand.vi v2, v2, 0x3\n\t" + "vand.vi v4, v4, 0x3\n\t" + "vsetvli zero, %[vl128], e8, m8\n\t" + "vle8.v v8, (%[q8])\n\t" + "vsetvli zero, %[vl64], e8, m4\n\t" + "vwmul.vv v16, v0, v8\n\t" + "vwmul.vv v24, v4, v12\n\t" + "vsetivli zero, 16, e16, m2\n\t" + "vmv.v.x v0, zero\n\t" + "vwredsum.vs v10, v16, v0\n\t" + "vwredsum.vs v9, v18, v0\n\t" + "vwredsum.vs v8, v20, v0\n\t" + "vwredsum.vs v7, v22, v0\n\t" + "vwredsum.vs v11, v24, v0\n\t" + "vwredsum.vs v12, v26, v0\n\t" + "vwredsum.vs v13, v28, v0\n\t" + "vwredsum.vs v14, v30, v0\n\t" + "vsetivli zero, 4, e32, m1\n\t" + "vslideup.vi v10, v9, 1\n\t" + "vslideup.vi v8, v7, 1\n\t" + "vslideup.vi v11, v12, 1\n\t" + "vslideup.vi v13, v14, 1\n\t" + "vslideup.vi v10, v8, 2\n\t" + "vslideup.vi v11, v13, 2\n\t" + "vsetivli zero, 8, e32, m2\n\t" + "vle8.v v15, (%[scale])\n\t" + "vzext.vf4 v12, v15\n\t" + "vmul.vv v10, v10, v12\n\t" + "vredsum.vs v0, v10, v0\n\t" + "vmv.x.s %[tmp], v0\n\t" + "add %[isum], %[isum], %[tmp]" + : [tmp] "=&r"(tmp), [isum] "+&r"(isum) + : [q2] "r"(q2), [scale] "r"(patmp), [q8] "r"(q8), [vl32] "r"(32), [vl64] "r"(64), [vl128] "r"(128) + : "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); + q2 += 32; + q8 += 128; + patmp += 8; + } + + sumf += dall * isum; + } + break; + default: + assert(false && "Unsupported vector length"); + break; + } + + *s = sumf; + +#elif defined(__POWER9_VECTOR__) + const vector signed char lowMask = vec_splats((signed char)0x3); + const vector signed char lowScaleMask = vec_splats((signed char)0xF); + const vector int v0 = vec_splats((int32_t)0); + const vector unsigned char v2 = vec_splats((unsigned char)0x2); + const vector unsigned char v6 = vec_splats((unsigned char)0x6); + const vector unsigned char v4 = vec_splats((unsigned char)0x4); + + vector float vsumf0 = vec_splats(0.0f); + vector float vsumf1 = vec_splats(0.0f); + vector float vsumf2 = vec_splats(0.0f); + vector float vsumf3 = vec_splats(0.0f); + + for (int i = 0; i < nb; ++i) { + vector float vxd = vec_splats(MLLM_FP16_TO_FP32(x[i].d)); + vector float vyd = vec_splats(y[i].d); + vector float vd = vec_mul(vxd, vyd); + + vector float vxmin = vec_splats(MLLM_FP16_TO_FP32(x[i].dmin)); + vector float vdmin = vec_mul(vxmin, vyd); + + vector signed short q8ysums0 = vec_xl(0, y[i].bsums); + vector signed short q8ysums1 = vec_xl(16, y[i].bsums); + + vector signed char q2xmins = (vector signed char)vec_xl(0, x[i].scales); + vector signed char vscales = vec_and(q2xmins, lowScaleMask); + + q2xmins = vec_sr(q2xmins, v4); + vector signed short q2xmins0 = vec_unpackh(q2xmins); + vector signed short q2xmins1 = vec_unpackl(q2xmins); + + vector signed int prod0 = vec_mule(q2xmins0, q8ysums0); + vector signed int prod1 = vec_mulo(q2xmins0, q8ysums0); + vector signed int prod2 = vec_mule(q2xmins1, q8ysums1); + vector signed int prod3 = vec_mulo(q2xmins1, q8ysums1); + + vsumf0 = vec_nmsub(vec_ctf(prod0, 0), vdmin, vsumf0); + vsumf1 = vec_nmsub(vec_ctf(prod1, 0), vdmin, vsumf1); + vsumf2 = vec_nmsub(vec_ctf(prod2, 0), vdmin, vsumf2); + vsumf3 = vec_nmsub(vec_ctf(prod3, 0), vdmin, vsumf3); + + vector signed int vsumi0 = v0; + vector signed int vsumi1 = v0; + vector signed int vsumi2 = v0; + vector signed int vsumi3 = v0; + vector signed int vsumi4 = v0; + vector signed int vsumi5 = v0; + vector signed int vsumi6 = v0; + vector signed int vsumi7 = v0; + + const uint8_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + for (int j = 0; j < QK_K / 128; ++j) { + __builtin_prefetch(q2, 0, 1); + __builtin_prefetch(q8, 0, 1); + + vector signed char qxs0 = (vector signed char)vec_xl(0, q2); + vector signed char qxs1 = (vector signed char)vec_xl(16, q2); + q2 += 32; + + vector unsigned char q2x00 = (vector unsigned char)vec_and(qxs0, lowMask); + vector unsigned char q2x01 = (vector unsigned char)vec_and(vec_sr(qxs0, v2), lowMask); + vector unsigned char q2x02 = (vector unsigned char)vec_and(vec_sr(qxs0, v4), lowMask); + vector unsigned char q2x03 = (vector unsigned char)vec_and(vec_sr(qxs0, v6), lowMask); + vector unsigned char q2x10 = (vector unsigned char)vec_and(qxs1, lowMask); + vector unsigned char q2x11 = (vector unsigned char)vec_and(vec_sr(qxs1, v2), lowMask); + vector unsigned char q2x12 = (vector unsigned char)vec_and(vec_sr(qxs1, v4), lowMask); + vector unsigned char q2x13 = (vector unsigned char)vec_and(vec_sr(qxs1, v6), lowMask); + + vector signed char q8y00 = vec_xl(0, q8); + vector signed char q8y10 = vec_xl(16, q8); + vector signed char q8y01 = vec_xl(32, q8); + vector signed char q8y11 = vec_xl(48, q8); + vector signed char q8y02 = vec_xl(64, q8); + vector signed char q8y12 = vec_xl(80, q8); + vector signed char q8y03 = vec_xl(96, q8); + vector signed char q8y13 = vec_xl(112, q8); + q8 += 128; + + vector signed int qv0 = vec_msum(q8y00, q2x00, v0); + vector signed int qv1 = vec_msum(q8y01, q2x01, v0); + vector signed int qv2 = vec_msum(q8y02, q2x02, v0); + vector signed int qv3 = vec_msum(q8y03, q2x03, v0); + vector signed int qv4 = vec_msum(q8y10, q2x10, v0); + vector signed int qv5 = vec_msum(q8y11, q2x11, v0); + vector signed int qv6 = vec_msum(q8y12, q2x12, v0); + vector signed int qv7 = vec_msum(q8y13, q2x13, v0); + + vector signed short vscales_07 = vec_unpackh(vscales); + vector signed int vscales_03 = vec_unpackh(vscales_07); + vector signed int vscales_47 = vec_unpackl(vscales_07); + vector signed int vs0 = vec_splat(vscales_03, 0); + vector signed int vs1 = vec_splat(vscales_03, 1); + vector signed int vs2 = vec_splat(vscales_03, 2); + vector signed int vs3 = vec_splat(vscales_03, 3); + vector signed int vs4 = vec_splat(vscales_47, 0); + vector signed int vs5 = vec_splat(vscales_47, 1); + vector signed int vs6 = vec_splat(vscales_47, 2); + vector signed int vs7 = vec_splat(vscales_47, 3); + vscales = vec_sld(vscales, vscales, 8); + + vsumi0 = vec_add(vec_mul(qv0, vs0), vsumi0); + vsumi1 = vec_add(vec_mul(qv1, vs2), vsumi1); + vsumi2 = vec_add(vec_mul(qv2, vs4), vsumi2); + vsumi3 = vec_add(vec_mul(qv3, vs6), vsumi3); + vsumi4 = vec_add(vec_mul(qv4, vs1), vsumi4); + vsumi5 = vec_add(vec_mul(qv5, vs3), vsumi5); + vsumi6 = vec_add(vec_mul(qv6, vs5), vsumi6); + vsumi7 = vec_add(vec_mul(qv7, vs7), vsumi7); + } + + vsumi0 = vec_add(vsumi0, vsumi4); + vsumi1 = vec_add(vsumi1, vsumi5); + vsumi2 = vec_add(vsumi2, vsumi6); + vsumi3 = vec_add(vsumi3, vsumi7); + + vsumf0 = vec_madd(vec_ctf(vsumi0, 0), vd, vsumf0); + vsumf1 = vec_madd(vec_ctf(vsumi1, 0), vd, vsumf1); + vsumf2 = vec_madd(vec_ctf(vsumi2, 0), vd, vsumf2); + vsumf3 = vec_madd(vec_ctf(vsumi3, 0), vd, vsumf3); + } + + vsumf0 = vec_add(vsumf0, vsumf2); + vsumf1 = vec_add(vsumf1, vsumf3); + + vsumf0 = vec_add(vsumf0, vsumf1); + + vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 4)); + vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 8)); + + *s = vec_extract(vsumf0, 0); + +#elif defined __loongarch_asx + + __m256 acc = (__m256)__lasx_xvldi(0); + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + + const uint8_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + const __m128i mins_and_scales128 = __lsx_vld((const __m128i *)x[i].scales, 0); + const __m128i scales128 = __lsx_vandi_b(mins_and_scales128, 0xf); + const __m256i mins = lasx_ext8_16(__lsx_vsrli_b(mins_and_scales128, 4)); + const __m256i prod = lasx_madd_h(mins, __lasx_xvld((const __m256i *)y[i].bsums, 0)); + + acc = __lasx_xvfmadd_s(__lasx_xvreplfr2vr_s(dmin), __lasx_xvffint_s_w(prod), acc); + + const v16i8 shuffle_mask = {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15}; + const __m256i scales_shuffled = lasx_ext8_16(__lsx_vshuf_b(scales128, scales128, (__m128i)shuffle_mask)); + + __m256i sumi = __lasx_xvldi(0); + + for (int j = 0; j < QK_K / 128; ++j) { + const __m256i q2bits = __lasx_xvld((const __m256i *)q2, 0); + q2 += 32; + + const __m256i q8_0 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + const __m256i q8_1 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + const __m256i q8_2 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + const __m256i q8_3 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + + const __m256i q2_0 = __lasx_xvandi_b(q2bits, 3); + const __m256i q2_1 = __lasx_xvandi_b(__lasx_xvsrli_b(q2bits, 2), 3); + const __m256i q2_2 = __lasx_xvandi_b(__lasx_xvsrli_b(q2bits, 4), 3); + const __m256i q2_3 = __lasx_xvsrli_b(q2bits, 6); + + __m256i p0 = lasx_madd_h_b(q2_0, q8_0); + __m256i p1 = lasx_madd_h_b(q2_1, q8_1); + __m256i p2 = lasx_madd_h_b(q2_2, q8_2); + __m256i p3 = lasx_madd_h_b(q2_3, q8_3); + + p0 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 0), p0); + p1 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 1), p1); + p2 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 2), p2); + p3 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 3), p3); + + p0 = __lasx_xvadd_w(p0, p1); + p2 = __lasx_xvadd_w(p2, p3); + + sumi = __lasx_xvadd_w(sumi, __lasx_xvadd_w(p0, p2)); + } + + acc = __lasx_xvfmadd_s(__lasx_xvreplfr2vr_s(d), __lasx_xvffint_s_w(sumi), acc); + } + + *s = hsum_float_8(acc); + +#else + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + const uint8_t *q2 = x[i].qs; + const int8_t *q8 = y[i].qs; + const uint8_t *sc = x[i].scales; + + int summs = 0; + for (int j = 0; j < 16; ++j) { + summs += y[i].bsums[j] * (sc[j] >> 4); + } + + const float dall = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + + int isum = 0; + int is = 0; + int d; + for (int k = 0; k < QK_K / 128; ++k) { + int shift = 0; + for (int j = 0; j < 4; ++j) { + d = sc[is++] & 0xF; + int isuml = 0; + for (int l = 0; l < 16; ++l) isuml += q8[l] * ((q2[l] >> shift) & 3); + isum += d * isuml; + d = sc[is++] & 0xF; + isuml = 0; + for (int l = 16; l < 32; ++l) isuml += q8[l] * ((q2[l] >> shift) & 3); + isum += d * isuml; + shift += 2; + q8 += 32; + } + q2 += 32; + } + sumf += dall * isum - dmin * summs; + } + *s = sumf; +#endif +} + +void vec_dot_iq2_xxs_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + assert(n % QK_K == 0); + + const block_iq2_xxs *__restrict x = (block_iq2_xxs *)vx; + const block_q8_K *__restrict y = (block_q8_K *)vy; + + const int nb = n / QK_K; + +#if defined(__ARM_NEON) + + const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; + + uint32_t aux32[4]; + const uint8_t *aux8 = (const uint8_t *)aux32; + + mllm_int8x16x4_t q2u; + mllm_int8x16x4_t q2s; + mllm_int8x16x4_t q8b; + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + const uint16_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + float sumf1 = 0, sumf2 = 0; + for (int ib32 = 0; ib32 < QK_K / 32; ib32 += 2) { + q8b = mllm_vld1q_s8_x4(q8); + q8 += 64; + memcpy(aux32, q2, 4 * sizeof(uint32_t)); + q2 += 8; + q2u.val[0] = vcombine_s8(vld1_s8((const int8_t *)(iq2xxs_grid + aux8[0])), vld1_s8((const int8_t *)(iq2xxs_grid + aux8[1]))); + q2u.val[1] = vcombine_s8(vld1_s8((const int8_t *)(iq2xxs_grid + aux8[2])), vld1_s8((const int8_t *)(iq2xxs_grid + aux8[3]))); + q2u.val[2] = vcombine_s8(vld1_s8((const int8_t *)(iq2xxs_grid + aux8[8])), vld1_s8((const int8_t *)(iq2xxs_grid + aux8[9]))); + q2u.val[3] = vcombine_s8(vld1_s8((const int8_t *)(iq2xxs_grid + aux8[10])), vld1_s8((const int8_t *)(iq2xxs_grid + aux8[11]))); + q2s.val[0] = vcombine_s8(vld1_s8((const int8_t *)(signs64 + ((aux32[1] >> 0) & 127))), vld1_s8((const int8_t *)(signs64 + ((aux32[1] >> 7) & 127)))); + q2s.val[1] = vcombine_s8(vld1_s8((const int8_t *)(signs64 + ((aux32[1] >> 14) & 127))), vld1_s8((const int8_t *)(signs64 + ((aux32[1] >> 21) & 127)))); + q2s.val[2] = vcombine_s8(vld1_s8((const int8_t *)(signs64 + ((aux32[3] >> 0) & 127))), vld1_s8((const int8_t *)(signs64 + ((aux32[3] >> 7) & 127)))); + q2s.val[3] = vcombine_s8(vld1_s8((const int8_t *)(signs64 + ((aux32[3] >> 14) & 127))), vld1_s8((const int8_t *)(signs64 + ((aux32[3] >> 21) & 127)))); + q2u.val[0] = vmulq_s8(q2u.val[0], q2s.val[0]); + q2u.val[1] = vmulq_s8(q2u.val[1], q2s.val[1]); + q2u.val[2] = vmulq_s8(q2u.val[2], q2s.val[2]); + q2u.val[3] = vmulq_s8(q2u.val[3], q2s.val[3]); + const int32x4_t p1 = mllm_vdotq_s32(mllm_vdotq_s32(vdupq_n_s32(0), q2u.val[0], q8b.val[0]), q2u.val[1], q8b.val[1]); + const int32x4_t p2 = mllm_vdotq_s32(mllm_vdotq_s32(vdupq_n_s32(0), q2u.val[2], q8b.val[2]), q2u.val[3], q8b.val[3]); + sumf1 += vaddvq_s32(p1) * (0.5f + (aux32[1] >> 28)); + sumf2 += vaddvq_s32(p2) * (0.5f + (aux32[3] >> 28)); + } + sumf += d * (sumf1 + sumf2); + } + *s = 0.25f * sumf; + +#elif defined(__AVX2__) + + const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; + + uint32_t aux32[4]; + const uint8_t *aux8 = (const uint8_t *)aux32; + + __m256 accumf = _mm256_setzero_ps(); + for (int i = 0; i < nb; ++i) { + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + const uint16_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + __m256i sumi1 = _mm256_setzero_si256(); + __m256i sumi2 = _mm256_setzero_si256(); + for (int ib32 = 0; ib32 < QK_K / 32; ib32 += 2) { + const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + memcpy(aux32, q2, 4 * sizeof(uint32_t)); + q2 += 8; + const __m256i q2_1 = _mm256_set_epi64x(iq2xxs_grid[aux8[3]], iq2xxs_grid[aux8[2]], iq2xxs_grid[aux8[1]], iq2xxs_grid[aux8[0]]); + const __m256i q2_2 = _mm256_set_epi64x(iq2xxs_grid[aux8[11]], iq2xxs_grid[aux8[10]], iq2xxs_grid[aux8[9]], iq2xxs_grid[aux8[8]]); + const __m256i s2_1 = _mm256_set_epi64x(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127], + signs64[(aux32[1] >> 7) & 127], signs64[(aux32[1] >> 0) & 127]); + const __m256i s2_2 = _mm256_set_epi64x(signs64[(aux32[3] >> 21) & 127], signs64[(aux32[3] >> 14) & 127], + signs64[(aux32[3] >> 7) & 127], signs64[(aux32[3] >> 0) & 127]); + const __m256i q8s_1 = _mm256_sign_epi8(q8_1, s2_1); + const __m256i q8s_2 = _mm256_sign_epi8(q8_2, s2_2); + const __m256i dot1 = _mm256_maddubs_epi16(q2_1, q8s_1); + const __m256i dot2 = _mm256_maddubs_epi16(q2_2, q8s_2); + const uint16_t ls1 = aux32[1] >> 28; + const uint16_t ls2 = aux32[3] >> 28; + const __m256i p1 = _mm256_madd_epi16(dot1, _mm256_set1_epi16(2 * ls1 + 1)); + const __m256i p2 = _mm256_madd_epi16(dot2, _mm256_set1_epi16(2 * ls2 + 1)); + sumi1 = _mm256_add_epi32(sumi1, p1); + sumi2 = _mm256_add_epi32(sumi2, p2); + } + + accumf = _mm256_fmadd_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(_mm256_add_epi32(sumi1, sumi2)), accumf); + } + + *s = 0.125f * hsum_float_8(accumf); + +#elif defined(__AVX__) + const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; + + uint32_t aux32[4]; + const uint8_t *aux8 = (const uint8_t *)aux32; + + __m256 accumf = _mm256_setzero_ps(); + for (int i = 0; i < nb; ++i) { + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + const uint16_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + __m128i sumi1_0 = _mm_setzero_si128(); + __m128i sumi1_1 = _mm_setzero_si128(); + __m128i sumi2_0 = _mm_setzero_si128(); + __m128i sumi2_1 = _mm_setzero_si128(); + for (int ib32 = 0; ib32 < QK_K / 32; ib32 += 2) { + const __m128i q8_1_0 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_1_1 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_2_0 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_2_1 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + memcpy(aux32, q2, 4 * sizeof(uint32_t)); + q2 += 8; + const __m128i q2_1_0 = _mm_set_epi64x(iq2xxs_grid[aux8[1]], iq2xxs_grid[aux8[0]]); + const __m128i q2_1_1 = _mm_set_epi64x(iq2xxs_grid[aux8[3]], iq2xxs_grid[aux8[2]]); + const __m128i q2_2_0 = _mm_set_epi64x(iq2xxs_grid[aux8[9]], iq2xxs_grid[aux8[8]]); + const __m128i q2_2_1 = _mm_set_epi64x(iq2xxs_grid[aux8[11]], iq2xxs_grid[aux8[10]]); + const __m128i s2_1_0 = _mm_set_epi64x(signs64[(aux32[1] >> 7) & 127], signs64[(aux32[1] >> 0) & 127]); + const __m128i s2_1_1 = _mm_set_epi64x(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127]); + const __m128i s2_2_0 = _mm_set_epi64x(signs64[(aux32[3] >> 7) & 127], signs64[(aux32[3] >> 0) & 127]); + const __m128i s2_2_1 = _mm_set_epi64x(signs64[(aux32[3] >> 21) & 127], signs64[(aux32[3] >> 14) & 127]); + const __m128i q8s_1_0 = _mm_sign_epi8(q8_1_0, s2_1_0); + const __m128i q8s_1_1 = _mm_sign_epi8(q8_1_1, s2_1_1); + const __m128i q8s_2_0 = _mm_sign_epi8(q8_2_0, s2_2_0); + const __m128i q8s_2_1 = _mm_sign_epi8(q8_2_1, s2_2_1); + const __m128i dot1_0 = _mm_maddubs_epi16(q2_1_0, q8s_1_0); + const __m128i dot1_1 = _mm_maddubs_epi16(q2_1_1, q8s_1_1); + const __m128i dot2_0 = _mm_maddubs_epi16(q2_2_0, q8s_2_0); + const __m128i dot2_1 = _mm_maddubs_epi16(q2_2_1, q8s_2_1); + const uint16_t ls1 = aux32[1] >> 28; + const uint16_t ls2 = aux32[3] >> 28; + const __m128i p1_0 = _mm_madd_epi16(dot1_0, _mm_set1_epi16(2 * ls1 + 1)); + const __m128i p1_1 = _mm_madd_epi16(dot1_1, _mm_set1_epi16(2 * ls1 + 1)); + const __m128i p2_0 = _mm_madd_epi16(dot2_0, _mm_set1_epi16(2 * ls2 + 1)); + const __m128i p2_1 = _mm_madd_epi16(dot2_1, _mm_set1_epi16(2 * ls2 + 1)); + sumi1_0 = _mm_add_epi32(sumi1_0, p1_0); + sumi1_1 = _mm_add_epi32(sumi1_1, p1_1); + sumi2_0 = _mm_add_epi32(sumi2_0, p2_0); + sumi2_1 = _mm_add_epi32(sumi2_1, p2_1); + } + + accumf = _mm256_add_ps(_mm256_mul_ps(_mm256_set1_ps(d), _mm256_cvtepi32_ps(MM256_SET_M128I(_mm_add_epi32(sumi1_1, sumi2_1), _mm_add_epi32(sumi1_0, sumi2_0)))), accumf); + } + + *s = 0.125f * hsum_float_8(accumf); + +#elif defined(__POWER9_VECTOR__) + const vector int v0 = vec_splats((int32_t)0); + vector float vsumf0 = vec_splats(0.0f); + vector float vsumf1 = vec_splats(0.0f); + vector float vsumf2 = vec_splats(0.0f); + vector float vsumf3 = vec_splats(0.0f); + + const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; + + for (int i = 0; i < nb; ++i) { + vector float vxd = vec_splats(MLLM_FP16_TO_FP32(x[i].d)); + vector float vyd = vec_splats(y[i].d); + vector float vd = vec_mul(vxd, vyd); + + vector signed int vsumi0 = v0; + vector signed int vsumi1 = v0; + vector signed int vsumi2 = v0; + vector signed int vsumi3 = v0; + + const uint16_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + for (int j = 0; j < QK_K / 32; j += 2) { + __builtin_prefetch(q2, 0, 1); + __builtin_prefetch(q8, 0, 1); + + uint32_t aux32[4]; + const uint8_t *aux8 = (const uint8_t *)aux32; + + memcpy(aux32, q2, 4 * sizeof(uint32_t)); + q2 += 8; + + vector signed long long aux64x2_0 = {*(const int64_t *)(iq2xxs_grid + aux8[0]), *(const int64_t *)(iq2xxs_grid + aux8[1])}; + vector signed long long aux64x2_1 = {*(const int64_t *)(iq2xxs_grid + aux8[2]), *(const int64_t *)(iq2xxs_grid + aux8[3])}; + vector signed long long aux64x2_2 = {*(const int64_t *)(iq2xxs_grid + aux8[8]), *(const int64_t *)(iq2xxs_grid + aux8[9])}; + vector signed long long aux64x2_3 = {*(const int64_t *)(iq2xxs_grid + aux8[10]), *(const int64_t *)(iq2xxs_grid + aux8[11])}; + + vector signed long long vsigns0 = {*(const int64_t *)(signs64 + ((aux32[1] >> 0) & 127)), *(const int64_t *)(signs64 + ((aux32[1] >> 7) & 127))}; + vector signed long long vsigns1 = {*(const int64_t *)(signs64 + ((aux32[1] >> 14) & 127)), *(const int64_t *)(signs64 + ((aux32[1] >> 21) & 127))}; + vector signed long long vsigns2 = {*(const int64_t *)(signs64 + ((aux32[3] >> 0) & 127)), *(const int64_t *)(signs64 + ((aux32[3] >> 7) & 127))}; + vector signed long long vsigns3 = {*(const int64_t *)(signs64 + ((aux32[3] >> 14) & 127)), *(const int64_t *)(signs64 + ((aux32[3] >> 21) & 127))}; + + vector signed char q2x0 = (vector signed char)vec_mul((vector signed char)vsigns0, (vector signed char)aux64x2_0); + vector signed char q2x1 = (vector signed char)vec_mul((vector signed char)vsigns1, (vector signed char)aux64x2_1); + vector signed char q2x2 = (vector signed char)vec_mul((vector signed char)vsigns2, (vector signed char)aux64x2_2); + vector signed char q2x3 = (vector signed char)vec_mul((vector signed char)vsigns3, (vector signed char)aux64x2_3); + + vector signed char q8y0 = vec_xl(0, q8); + vector signed char q8y1 = vec_xl(16, q8); + vector signed char q8y2 = vec_xl(32, q8); + vector signed char q8y3 = vec_xl(48, q8); + q8 += 64; + + vector signed short qv0 = vec_add(vec_mule(q2x0, q8y0), vec_mulo(q2x0, q8y0)); + vector signed short qv1 = vec_add(vec_mule(q2x1, q8y1), vec_mulo(q2x1, q8y1)); + vector signed short qv2 = vec_add(vec_mule(q2x2, q8y2), vec_mulo(q2x2, q8y2)); + vector signed short qv3 = vec_add(vec_mule(q2x3, q8y3), vec_mulo(q2x3, q8y3)); + + const uint16_t ls0 = aux32[1] >> 28; + const uint16_t ls1 = aux32[3] >> 28; + + vector signed short vscales01 = vec_splats((int16_t)(2 * ls0 + 1)); + vector signed short vscales23 = vec_splats((int16_t)(2 * ls1 + 1)); + + vsumi0 = vec_msum(qv0, vscales01, vsumi0); + vsumi1 = vec_msum(qv1, vscales01, vsumi1); + vsumi2 = vec_msum(qv2, vscales23, vsumi2); + vsumi3 = vec_msum(qv3, vscales23, vsumi3); + } + + vsumf0 = vec_madd(vec_ctf(vsumi0, 0), vd, vsumf0); + vsumf1 = vec_madd(vec_ctf(vsumi1, 0), vd, vsumf1); + vsumf2 = vec_madd(vec_ctf(vsumi2, 0), vd, vsumf2); + vsumf3 = vec_madd(vec_ctf(vsumi3, 0), vd, vsumf3); + } + + vsumf0 = vec_add(vsumf0, vsumf2); + vsumf1 = vec_add(vsumf1, vsumf3); + + vsumf0 = vec_add(vsumf0, vsumf1); + + vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 4)); + vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 8)); + + *s = 0.125f * vec_extract(vsumf0, 0); + +#elif defined(__loongarch_asx) + + const uint64_t *signs64 = (const uint64_t *)keven_signs_q2xs; + + uint32_t aux32[4]; + const uint8_t *aux8 = (const uint8_t *)aux32; + + __m256 accumf = (__m256)__lasx_xvldi(0); + for (int i = 0; i < nb; ++i) { + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + const uint16_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + __m256i sumi1 = __lasx_xvldi(0); + __m256i sumi2 = __lasx_xvldi(0); + for (int ib32 = 0; ib32 < QK_K / 32; ib32 += 2) { + const __m256i q8_1 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + const __m256i q8_2 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + memcpy(aux32, q2, 4 * sizeof(uint32_t)); + q2 += 8; + + const __m256i q2_1 = lasx_set_d(iq2xxs_grid[aux8[3]], iq2xxs_grid[aux8[2]], iq2xxs_grid[aux8[1]], iq2xxs_grid[aux8[0]]); + const __m256i q2_2 = lasx_set_d(iq2xxs_grid[aux8[11]], iq2xxs_grid[aux8[10]], iq2xxs_grid[aux8[9]], iq2xxs_grid[aux8[8]]); + const __m256i s2_1 = lasx_set_d(signs64[(aux32[1] >> 21) & 127], signs64[(aux32[1] >> 14) & 127], + signs64[(aux32[1] >> 7) & 127], signs64[(aux32[1] >> 0) & 127]); + const __m256i s2_2 = lasx_set_d(signs64[(aux32[3] >> 21) & 127], signs64[(aux32[3] >> 14) & 127], + signs64[(aux32[3] >> 7) & 127], signs64[(aux32[3] >> 0) & 127]); + const __m256i q8s_1 = __lasx_xvsigncov_b(s2_1, q8_1); + const __m256i q8s_2 = __lasx_xvsigncov_b(s2_2, q8_2); + const __m256i dot1 = lasx_maddubs_h(q2_1, q8s_1); + const __m256i dot2 = lasx_maddubs_h(q2_2, q8s_2); + const uint16_t ls1 = aux32[1] >> 28; + const uint16_t ls2 = aux32[3] >> 28; + const __m256i p1 = lasx_madd_h(dot1, __lasx_xvreplgr2vr_h(2 * ls1 + 1)); + const __m256i p2 = lasx_madd_h(dot2, __lasx_xvreplgr2vr_h(2 * ls2 + 1)); + sumi1 = __lasx_xvadd_w(sumi1, p1); + sumi2 = __lasx_xvadd_w(sumi2, p2); + } + + accumf = __lasx_xvfmadd_s(__lasx_xvreplfr2vr_s(d), __lasx_xvffint_s_w(__lasx_xvadd_w(sumi1, sumi2)), accumf); + } + + *s = 0.125f * hsum_float_8(accumf); +// #elif defined(__VXE__) || defined(__VXE2__) +// const uint64_t * signs64 = (const uint64_t *)keven_signs_q2xs; +// +// uint32_t aux32[4]; +// const uint8_t * aux8 = (const uint8_t *)aux32; +// +// float sumf = 0; +// +// for (int i = 0; i < nb; ++i) { +// const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; +// const uint16_t * __restrict q2 = x[i].qs; +// const int8_t * __restrict q8 = y[i].qs; +// +// float sumf1 = 0, sumf2 = 0; +// +// for (int ib32 = 0; ib32 < QK_K/32; ib += 2) { +// int8x16_t q8b0 = vec_xl( 0, q8); +// int8x16_t qb81 = vec_xl(16, q8); +// int8x16_t q8b2 = vec_xl(32, q8); +// int8x16_t q8b3 = vec_xl(48, q8); +// q8 += 64; +// +// memcpy(aux32, q2, 4 * sizeof(uint32_t)); +// q2 += 8; +// +// int8x16_t q2u0 = { *(const int64_t *)(iq2xxs_grid + aux8[ 0]), *(const int64_t *)(iq2xxs_grid + aux8[ 1]) }; +// int8x16_t q2u1 = { *(const int64_t *)(iq2xxs_grid + aux8[ 2]), *(const int64_t *)(iq2xxs_grid + aux8[ 3]) }; +// int8x16_t q2u2 = { *(const int64_t *)(iq2xxs_grid + aux8[ 8]), *(const int64_t *)(iq2xxs_grid + aux8[ 9]) }; +// int8x16_t q2u3 = { *(const int64_t *)(iq2xxs_grid + aux8[10]), *(const int64_t *)(iq2xxs_grid + aux8[11]) }; +// +// int8x16_t q2s0 = { *(const int64_t *)(signs64 + ((aux32[1] >> 0) & 127)), *(const int64_t *)(signs64 + ((aux32[1] >> 7) & 127)) }; +// int8x16_t q2s1 = { *(const int64_t *)(signs64 + ((aux32[1] >> 14) & 127)), *(const int64_t *)(signs64 + ((aux32[1] >> 21) & 127)) }; +// int8x16_t q2s2 = { *(const int64_t *)(signs64 + ((aux32[3] >> 0) & 127)), *(const int64_t *)(signs64 + ((aux32[3] >> 7) & 127)) }; +// int8x16_t q2s3 = { *(const int64_t *)(signs64 + ((aux32[3] >> 14) & 127)), *(const int64_t *)(signs64 + ((aux32[3] >> 21) & 127)) }; +// +// q2u0 = vec_mul(q2u0, q2s0); +// q2u1 = vec_mul(q2u1, q2s1); +// q2u2 = vec_mul(q2u2, q2s2); +// q2u3 = vec_mul(q2u3, q2s3); +// +// const int32x4_t p1 = mllm_vec_dot(mllm_vec_dot(vec_splat_s32(0), q2u0, q8b0), q2u1, q8b1); +// const int32x4_t p2 = mllm_vec_dot(mllm_vec_dot(vec_splat_s32(0), q2u2, q8b2), q2u3, q8b3); +// +// sumf1 += (p1[0] + p1[1] + p1[2] + p1[3]) * (0.5f + (aux32[1] >> 28)); +// sumf2 += (p2[0] + p2[1] + p2[2] + p2[3]) * (0.5f + (aux32[3] >> 28)); +// } +// +// sumf += d * (sumf1 + sumf2); +// } +// +// *s = 0.25f * sumf; +#else + + uint32_t aux32[2]; + const uint8_t *aux8 = (const uint8_t *)aux32; + + float sumf = 0.f; + for (int i = 0; i < nb; ++i) { + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + const uint16_t *__restrict q2 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + int32_t bsum = 0; + for (int ib32 = 0; ib32 < QK_K / 32; ++ib32) { + memcpy(aux32, q2, 2 * sizeof(uint32_t)); + q2 += 4; + const uint32_t ls = 2 * (aux32[1] >> 28) + 1; + int32_t sumi = 0; + for (int l = 0; l < 4; ++l) { + const uint8_t *grid = (const uint8_t *)(iq2xxs_grid + aux8[l]); + const uint8_t signs = ksigns_iq2xs[(aux32[1] >> 7 * l) & 127]; + for (int j = 0; j < 8; ++j) { + sumi += grid[j] * q8[j] * (signs & kmask_iq2xs[j] ? -1 : 1); + } + q8 += 8; + } + bsum += sumi * ls; + } + sumf += d * bsum; + } + *s = 0.125f * sumf; +#endif +} \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ2.hpp b/src/backends/cpu/third_party/ggml/VecDotQ2.hpp new file mode 100644 index 000000000..ef4e4b489 --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ2.hpp @@ -0,0 +1,34 @@ +/* + * This code is based on mllm(https://github.com/ggerganov/mllm), + * please see https://github.com/ggerganov/mllm/blob/master/src/mllm.c + * mllm is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once +#include + +void vec_dot_q2_0_q8_0(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); + +void vec_dot_q2_K_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); +void vec_dot_iq2_xxs_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ3.cpp b/src/backends/cpu/third_party/ggml/VecDotQ3.cpp new file mode 100644 index 000000000..fb036e936 --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ3.cpp @@ -0,0 +1,1282 @@ +/* + * This code is based on ggml(https://github.com/ggerganov/ggml), + * please see https://github.com/ggerganov/ggml/blob/master/src/ggml.c + * ggml is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "VecDotQ3.hpp" +#include "ComputeUtils.hpp" + +void vec_dot_q3_K_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + assert(n % QK_K == 0); + + const uint32_t kmask1 = 0x03030303; + const uint32_t kmask2 = 0x0f0f0f0f; + + const block_q3_K *__restrict x = (block_q3_K *)vx; + const block_q8_K *__restrict y = (block_q8_K *)vy; + + const int nb = n / QK_K; + +#if defined(__ARM_FEATURE_SVE) + + uint32_t aux[3]; + uint32_t utmp[4]; + + const int8_t m32 = 32; + const int vector_length = svcntb() * 8; + const svuint8_t m3b_sv = svdup_n_u8(0x3); + const svint32_t vzero_sv = svdup_n_s32(0); + + const svuint8_t m0_sv = svdup_n_u8(1); + const svuint8_t m1_sv = svlsl_n_u8_x(svptrue_b8(), m0_sv, 1); + const svuint8_t m2_sv = svlsl_n_u8_x(svptrue_b8(), m0_sv, 2); + const svuint8_t m3_sv = svlsl_n_u8_x(svptrue_b8(), m0_sv, 3); + + float sum = 0; + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *__restrict q3_sv = x[i].qs; + const uint8_t *__restrict qh_sv = x[i].hmask; + const int8_t *__restrict q8_sv = y[i].qs; + + // Set up scales + memcpy(aux, x[i].scales, 12); + utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); + utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); + utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); + utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); + + int8_t *scale = (int8_t *)utmp; + + for (int j = 0; j < 16; ++j) scale[j] -= m32; + + switch (vector_length) { + case 128: { + svuint8_t qhbits_sv_1 = svld1_u8(svptrue_b8(), qh_sv); + svuint8_t qhbits_sv_2 = svld1_u8(svptrue_b8(), qh_sv + 16); + svuint8_t q3h_sv; + + svint32_t sumi1_1 = svdup_n_s32(0); + svint8_t q3bytes_sv; + + for (int j = 0; j < QK_K / 128; ++j) { + const svuint8_t q3bits_sv = svld1_u8(svptrue_b8(), q3_sv); + q3_sv += 16; + const svuint8_t q3bits_sv_1 = svld1_u8(svptrue_b8(), q3_sv); + q3_sv += 16; + svint8_t q8bytes_1_sv_1 = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + svint8_t q8bytes_1_sv_2 = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + q3h_sv = svlsl_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m0_sv, qhbits_sv_1), 2); + q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), q3bits_sv, m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), svdup_n_s32((int32_t)scale[0])); + + q3h_sv = svlsl_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m0_sv, qhbits_sv_2), 2); + q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), q3bits_sv_1, m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), svdup_n_s32((int32_t)scale[1])); + + q8bytes_1_sv_1 = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + q8bytes_1_sv_2 = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + q3h_sv = svlsl_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m1_sv, qhbits_sv_1), 1); + q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv, 2), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), svdup_n_s32((int32_t)scale[2])); + + q3h_sv = svlsl_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m1_sv, qhbits_sv_2), 1); + q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv_1, 2), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), svdup_n_s32((int32_t)scale[3])); + + scale += 4; + q8bytes_1_sv_1 = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + q8bytes_1_sv_2 = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + q3h_sv = svbic_u8_x(svptrue_b8(), m2_sv, qhbits_sv_1); + q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv, 4), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), svdup_n_s32((int32_t)scale[0])); + + q3h_sv = svbic_u8_x(svptrue_b8(), m2_sv, qhbits_sv_2); + q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv_1, 4), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), svdup_n_s32((int32_t)scale[1])); + + q8bytes_1_sv_1 = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + q8bytes_1_sv_2 = svld1_s8(svptrue_b8(), q8_sv); + q8_sv += 16; + + q3h_sv = svlsr_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m3_sv, qhbits_sv_1), 1); + q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv, 6), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), svdup_n_s32((int32_t)scale[2])); + + q3h_sv = svlsr_n_u8_x(svptrue_b8(), svbic_u8_x(svptrue_b8(), m3_sv, qhbits_sv_2), 1); + q3bytes_sv = svsub_s8_x(svptrue_b8(), svreinterpret_s8_u8(svand_u8_m(svptrue_b8(), svlsr_n_u8_x(svptrue_b8(), q3bits_sv_1, 6), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + sumi1_1 = svmla_s32_m(svptrue_b32(), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), svdup_n_s32((int32_t)scale[3])); + + if (j == 0) { + qhbits_sv_1 = svlsr_n_u8_x(svptrue_b8(), qhbits_sv_1, 4); + qhbits_sv_2 = svlsr_n_u8_x(svptrue_b8(), qhbits_sv_2, 4); + } + + scale += 4; + } + + sum += d * (svaddv_s32(svptrue_b32(), sumi1_1)); + } break; + case 256: + case 512: { + svuint8_t qhbits_sv = svld1_u8(svptrue_pat_b8(SV_VL32), qh_sv); + svuint8_t q3h_sv; + + svint32_t sumi1_1 = svdup_n_s32(0); + svint8_t q3bytes_sv; + + for (int j = 0; j < QK_K / 128; ++j) { + const svuint8_t q3bits_sv = svld1_u8(svptrue_pat_b8(SV_VL32), q3_sv); + q3_sv += 32; + svint8_t q8bytes_1_sv_1 = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + svint8_t q8bytes_1_sv_2 = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + q3h_sv = svlsl_n_u8_x(svptrue_pat_b8(SV_VL32), svbic_u8_x(svptrue_pat_b8(SV_VL32), m0_sv, qhbits_sv), 2); + q3bytes_sv = svsub_s8_x(svptrue_pat_b8(SV_VL32), svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), q3bits_sv, m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + svint32_t scale_1 = svsel_s32(svptrue_pat_b32(SV_VL4), svdup_n_s32((int32_t)scale[0]), svdup_n_s32((int32_t)scale[1])); + sumi1_1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), scale_1); + + q3h_sv = svlsl_n_u8_x(svptrue_pat_b8(SV_VL32), svbic_u8_x(svptrue_pat_b8(SV_VL32), m1_sv, qhbits_sv), 1); + q3bytes_sv = svsub_s8_x(svptrue_pat_b8(SV_VL32), svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q3bits_sv, 2), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + scale_1 = svsel_s32(svptrue_pat_b32(SV_VL4), svdup_n_s32((int32_t)scale[2]), svdup_n_s32((int32_t)scale[3])); + sumi1_1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), scale_1); + + scale += 4; + q8bytes_1_sv_1 = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + q8bytes_1_sv_2 = svld1_s8(svptrue_pat_b8(SV_VL32), q8_sv); + q8_sv += 32; + + q3h_sv = svbic_u8_x(svptrue_pat_b8(SV_VL32), m2_sv, qhbits_sv); + q3bytes_sv = svsub_s8_x(svptrue_pat_b8(SV_VL32), svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q3bits_sv, 4), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + scale_1 = svsel_s32(svptrue_pat_b32(SV_VL4), svdup_n_s32((int32_t)scale[0]), svdup_n_s32((int32_t)scale[1])); + sumi1_1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_1), scale_1); + + q3h_sv = svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), svbic_u8_x(svptrue_pat_b8(SV_VL32), m3_sv, qhbits_sv), 1); + q3bytes_sv = svsub_s8_x(svptrue_pat_b8(SV_VL32), svreinterpret_s8_u8(svand_u8_m(svptrue_pat_b8(SV_VL32), svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q3bits_sv, 6), m3b_sv)), svreinterpret_s8_u8(q3h_sv)); + + scale_1 = svsel_s32(svptrue_pat_b32(SV_VL4), svdup_n_s32((int32_t)scale[2]), svdup_n_s32((int32_t)scale[3])); + sumi1_1 = svmla_s32_m(svptrue_pat_b32(SV_VL8), sumi1_1, svdot_s32(vzero_sv, q3bytes_sv, q8bytes_1_sv_2), scale_1); + + if (j == 0) { + qhbits_sv = svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), qhbits_sv, 4); + } + + scale += 4; + } + + sum += d * (svaddv_s32(svptrue_pat_b32(SV_VL8), sumi1_1)); + } break; + default: + assert(false && "Unsupported vector length"); + break; + } + } + *s = sum; + +#elif __ARM_NEON + + uint32_t aux[3]; + uint32_t utmp[4]; + + const uint8x16_t m3b = vdupq_n_u8(0x3); + const int32x4_t vzero = vdupq_n_s32(0); + + const uint8x16_t m0 = vdupq_n_u8(1); + const uint8x16_t m1 = vshlq_n_u8(m0, 1); + const uint8x16_t m2 = vshlq_n_u8(m0, 2); + const uint8x16_t m3 = vshlq_n_u8(m0, 3); + const int8_t m32 = 32; + + mllm_int8x16x4_t q3bytes; + + float sum = 0; + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *__restrict q3 = x[i].qs; + const uint8_t *__restrict qh = x[i].hmask; + const int8_t *__restrict q8 = y[i].qs; + + mllm_uint8x16x2_t qhbits = mllm_vld1q_u8_x2(qh); + + mllm_uint8x16x4_t q3h; + + int32_t isum = 0; + + // Set up scales + memcpy(aux, x[i].scales, 12); + utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); + utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); + utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); + utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); + + int8_t *scale = (int8_t *)utmp; + for (int j = 0; j < 16; ++j) scale[j] -= m32; + + for (int j = 0; j < QK_K / 128; ++j) { + const mllm_uint8x16x2_t q3bits = mllm_vld1q_u8_x2(q3); + q3 += 32; + const mllm_int8x16x4_t q8bytes_1 = mllm_vld1q_s8_x4(q8); + q8 += 64; + const mllm_int8x16x4_t q8bytes_2 = mllm_vld1q_s8_x4(q8); + q8 += 64; + + q3h.val[0] = vshlq_n_u8(vbicq_u8(m0, qhbits.val[0]), 2); + q3h.val[1] = vshlq_n_u8(vbicq_u8(m0, qhbits.val[1]), 2); + q3h.val[2] = vshlq_n_u8(vbicq_u8(m1, qhbits.val[0]), 1); + q3h.val[3] = vshlq_n_u8(vbicq_u8(m1, qhbits.val[1]), 1); + + q3bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(q3bits.val[0], m3b)), vreinterpretq_s8_u8(q3h.val[0])); + q3bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(q3bits.val[1], m3b)), vreinterpretq_s8_u8(q3h.val[1])); + q3bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[0], 2), m3b)), vreinterpretq_s8_u8(q3h.val[2])); + q3bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[1], 2), m3b)), vreinterpretq_s8_u8(q3h.val[3])); + + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[0], q8bytes_1.val[0])) * scale[0]; + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[1], q8bytes_1.val[1])) * scale[1]; + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[2], q8bytes_1.val[2])) * scale[2]; + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[3], q8bytes_1.val[3])) * scale[3]; + + scale += 4; + + q3h.val[0] = vbicq_u8(m2, qhbits.val[0]); + q3h.val[1] = vbicq_u8(m2, qhbits.val[1]); + q3h.val[2] = vshrq_n_u8(vbicq_u8(m3, qhbits.val[0]), 1); + q3h.val[3] = vshrq_n_u8(vbicq_u8(m3, qhbits.val[1]), 1); + + q3bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[0], 4), m3b)), vreinterpretq_s8_u8(q3h.val[0])); + q3bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[1], 4), m3b)), vreinterpretq_s8_u8(q3h.val[1])); + q3bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[0], 6), m3b)), vreinterpretq_s8_u8(q3h.val[2])); + q3bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vandq_u8(vshrq_n_u8(q3bits.val[1], 6), m3b)), vreinterpretq_s8_u8(q3h.val[3])); + + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[0], q8bytes_2.val[0])) * scale[0]; + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[1], q8bytes_2.val[1])) * scale[1]; + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[2], q8bytes_2.val[2])) * scale[2]; + isum += vaddvq_s32(mllm_vdotq_s32(vzero, q3bytes.val[3], q8bytes_2.val[3])) * scale[3]; + + scale += 4; + + if (j == 0) { + qhbits.val[0] = vshrq_n_u8(qhbits.val[0], 4); + qhbits.val[1] = vshrq_n_u8(qhbits.val[1], 4); + } + } + sum += d * isum; + } + + *s = sum; + +#elif defined __AVX2__ + + const __m256i m3 = _mm256_set1_epi8(3); + const __m256i mone = _mm256_set1_epi8(1); + const __m128i m32 = _mm_set1_epi8(32); + + __m256 acc = _mm256_setzero_ps(); + + uint32_t aux[3]; + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *__restrict q3 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + // Set up scales + memcpy(aux, x[i].scales, 12); + __m128i scales128 = _mm_set_epi32( + ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4), + ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4), + (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4), + (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4)); + scales128 = _mm_sub_epi8(scales128, m32); + const __m256i all_scales = _mm256_cvtepi8_epi16(scales128); + const __m128i l_scales = _mm256_extracti128_si256(all_scales, 0); + const __m128i h_scales = _mm256_extracti128_si256(all_scales, 1); + const __m256i scales[2] = {MM256_SET_M128I(l_scales, l_scales), MM256_SET_M128I(h_scales, h_scales)}; + + // high bit + const __m256i hbits = _mm256_loadu_si256((const __m256i *)x[i].hmask); + + // integer accumulator + __m256i sumi = _mm256_setzero_si256(); + + int bit = 0; + int is = 0; + + for (int j = 0; j < QK_K / 128; ++j) { + // load low 2 bits + const __m256i q3bits = _mm256_loadu_si256((const __m256i *)q3); + q3 += 32; + + // prepare low and high bits + const __m256i q3l_0 = _mm256_and_si256(q3bits, m3); + const __m256i q3h_0 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); + ++bit; + + const __m256i q3l_1 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 2), m3); + const __m256i q3h_1 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); + ++bit; + + const __m256i q3l_2 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 4), m3); + const __m256i q3h_2 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); + ++bit; + + const __m256i q3l_3 = _mm256_and_si256(_mm256_srli_epi16(q3bits, 6), m3); + const __m256i q3h_3 = _mm256_slli_epi16(_mm256_srli_epi16(_mm256_andnot_si256(hbits, _mm256_slli_epi16(mone, bit)), bit), 2); + ++bit; + + // load Q8 quants + const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_3 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + + // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm256_maddubs_epi16, + // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set, + // and 2 if the high bit was set) + __m256i q8s_0 = _mm256_maddubs_epi16(q3h_0, q8_0); + __m256i q8s_1 = _mm256_maddubs_epi16(q3h_1, q8_1); + __m256i q8s_2 = _mm256_maddubs_epi16(q3h_2, q8_2); + __m256i q8s_3 = _mm256_maddubs_epi16(q3h_3, q8_3); + + __m256i p16_0 = _mm256_maddubs_epi16(q3l_0, q8_0); + __m256i p16_1 = _mm256_maddubs_epi16(q3l_1, q8_1); + __m256i p16_2 = _mm256_maddubs_epi16(q3l_2, q8_2); + __m256i p16_3 = _mm256_maddubs_epi16(q3l_3, q8_3); + + p16_0 = _mm256_sub_epi16(p16_0, q8s_0); + p16_1 = _mm256_sub_epi16(p16_1, q8s_1); + p16_2 = _mm256_sub_epi16(p16_2, q8s_2); + p16_3 = _mm256_sub_epi16(p16_3, q8s_3); + + // multiply with scales + p16_0 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 0)), p16_0); + p16_1 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 1)), p16_1); + p16_2 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 2)), p16_2); + p16_3 = _mm256_madd_epi16(_mm256_shuffle_epi8(scales[j], get_scale_shuffle_q3k(is + 3)), p16_3); + + // accumulate + p16_0 = _mm256_add_epi32(p16_0, p16_1); + p16_2 = _mm256_add_epi32(p16_2, p16_3); + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_2)); + } + + // multiply with block scale and accumulate + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + + const __m128i m3 = _mm_set1_epi8(3); + const __m128i mone = _mm_set1_epi8(1); + const __m128i m32 = _mm_set1_epi8(32); + const __m128i m2 = _mm_set1_epi8(2); + + __m256 acc = _mm256_setzero_ps(); + + const uint32_t *aux; + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *__restrict q3 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + // Set up scales + aux = (const uint32_t *)x[i].scales; + __m128i scales128 = _mm_set_epi32( + ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4), + ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4), + (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4), + (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4)); + scales128 = _mm_sub_epi8(scales128, m32); + const __m128i scales_0 = _mm_cvtepi8_epi16(scales128); + const __m128i scales_1 = _mm_cvtepi8_epi16(_mm_unpackhi_epi64(scales128, scales128)); + const __m128i scales[2] = {scales_0, scales_1}; + + // high bit *128*2 from block_q3_K.hmask[QK_K/8] + const __m128i hbits_0 = _mm_loadu_si128((const __m128i *)&x[i].hmask[0]); + const __m128i hbits_1 = _mm_loadu_si128((const __m128i *)&x[i].hmask[16]); + + // integer accumulator + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + for (int j = 0; j < QK_K / 128; ++j) { + // load low 2 bits *64*2 from block_q3_K.qs[QK_K/4] + const __m128i q3bits_0 = _mm_loadu_si128((const __m128i *)q3); + q3 += 16; + const __m128i q3bits_1 = _mm_loadu_si128((const __m128i *)q3); + q3 += 16; + + // prepare low and high bits + const int bit = j << 2; + + const __m128i q3l_0 = _mm_and_si128(q3bits_0, m3); + const __m128i q3l_1 = _mm_and_si128(q3bits_1, m3); + const __m128i q3h_0 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit)), bit), 2); + const __m128i q3h_1 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit)), bit), 2); + + const __m128i q3l_2 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 2), m3); + const __m128i q3l_3 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 2), m3); + const __m128i q3h_2 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit + 1)), bit + 1), 2); + const __m128i q3h_3 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit + 1)), bit + 1), 2); + + const __m128i q3l_4 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 4), m3); + const __m128i q3l_5 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 4), m3); + const __m128i q3h_4 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit + 2)), bit + 2), 2); + const __m128i q3h_5 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit + 2)), bit + 2), 2); + + const __m128i q3l_6 = _mm_and_si128(_mm_srli_epi16(q3bits_0, 6), m3); + const __m128i q3l_7 = _mm_and_si128(_mm_srli_epi16(q3bits_1, 6), m3); + const __m128i q3h_6 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_0, _mm_slli_epi16(mone, bit + 3)), bit + 3), 2); + const __m128i q3h_7 = _mm_slli_epi16(_mm_srli_epi16(_mm_andnot_si128(hbits_1, _mm_slli_epi16(mone, bit + 3)), bit + 3), 2); + + // load Q8 quants from block_q8_K.qs[QK_K] + const __m128i q8_0 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_1 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_2 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_3 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_4 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_5 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_6 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_7 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + + // Dot product: we multiply the 2 low bits and 1 high bit part separately, so we can use _mm256_maddubs_epi16, + // and then subtract. The high bit part has the 2 already subtracted (and so, it is zero if the high bit was not set, + // and 2 if the high bit was set) + __m128i q8s_0 = _mm_maddubs_epi16(q3h_0, q8_0); + __m128i q8s_1 = _mm_maddubs_epi16(q3h_1, q8_1); + __m128i q8s_2 = _mm_maddubs_epi16(q3h_2, q8_2); + __m128i q8s_3 = _mm_maddubs_epi16(q3h_3, q8_3); + __m128i q8s_4 = _mm_maddubs_epi16(q3h_4, q8_4); + __m128i q8s_5 = _mm_maddubs_epi16(q3h_5, q8_5); + __m128i q8s_6 = _mm_maddubs_epi16(q3h_6, q8_6); + __m128i q8s_7 = _mm_maddubs_epi16(q3h_7, q8_7); + + __m128i p16_0 = _mm_maddubs_epi16(q3l_0, q8_0); + __m128i p16_1 = _mm_maddubs_epi16(q3l_1, q8_1); + __m128i p16_2 = _mm_maddubs_epi16(q3l_2, q8_2); + __m128i p16_3 = _mm_maddubs_epi16(q3l_3, q8_3); + __m128i p16_4 = _mm_maddubs_epi16(q3l_4, q8_4); + __m128i p16_5 = _mm_maddubs_epi16(q3l_5, q8_5); + __m128i p16_6 = _mm_maddubs_epi16(q3l_6, q8_6); + __m128i p16_7 = _mm_maddubs_epi16(q3l_7, q8_7); + + p16_0 = _mm_sub_epi16(p16_0, q8s_0); + p16_1 = _mm_sub_epi16(p16_1, q8s_1); + p16_2 = _mm_sub_epi16(p16_2, q8s_2); + p16_3 = _mm_sub_epi16(p16_3, q8s_3); + p16_4 = _mm_sub_epi16(p16_4, q8s_4); + p16_5 = _mm_sub_epi16(p16_5, q8s_5); + p16_6 = _mm_sub_epi16(p16_6, q8s_6); + p16_7 = _mm_sub_epi16(p16_7, q8s_7); + + // multiply with scales + __m128i shuffle = _mm_set1_epi16(0x0100); + p16_0 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_0); + shuffle = _mm_add_epi16(shuffle, m2); + p16_1 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_1); + shuffle = _mm_add_epi16(shuffle, m2); + p16_2 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_2); + shuffle = _mm_add_epi16(shuffle, m2); + p16_3 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_3); + shuffle = _mm_add_epi16(shuffle, m2); + p16_4 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_4); + shuffle = _mm_add_epi16(shuffle, m2); + p16_5 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_5); + shuffle = _mm_add_epi16(shuffle, m2); + p16_6 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_6); + shuffle = _mm_add_epi16(shuffle, m2); + p16_7 = _mm_madd_epi16(_mm_shuffle_epi8(scales[j], shuffle), p16_7); + + // accumulate + p16_0 = _mm_add_epi32(p16_0, p16_1); + p16_2 = _mm_add_epi32(p16_2, p16_3); + p16_4 = _mm_add_epi32(p16_4, p16_5); + p16_6 = _mm_add_epi32(p16_6, p16_7); + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_4, p16_6)); + } + + // multiply with block scale and accumulate + __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi)), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __wasm_simd128__ + int8_t aux8[QK_K]; + float sums[8] = {0}; + uint32_t auxs[4]; + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t *__restrict q3 = x[i].qs; + const uint8_t *__restrict hm = x[i].hmask; + const int8_t *__restrict q8 = y[i].qs; + + // Process blocks with SIMD + int8_t *a = aux8; + uint8_t m = 1; + for (int j = 0; j < QK_K; j += 128) { + for (int shift = 0; shift <= 6; shift += 2) { + v128_t v_m = wasm_i8x16_splat(m); + for (int l = 0; l < 32; l += 16) { + v128_t v_q3 = wasm_v128_load(q3 + l); + v128_t v_shift = wasm_i8x16_shr(v_q3, shift); + v128_t v_low2 = wasm_v128_and(v_shift, wasm_i8x16_splat(0x03)); + + v128_t v_hm = wasm_v128_load(hm + l); + v128_t v_mask = wasm_v128_and(v_hm, v_m); + v_mask = wasm_i8x16_ne(v_mask, wasm_i8x16_splat(0)); + + v_low2 = wasm_i8x16_sub(v_low2, wasm_v128_and(wasm_i8x16_splat(4), wasm_v128_not(v_mask))); + wasm_v128_store(a + l, v_low2); + } + a += 32; + m <<= 1; + } + q3 += 32; + } + + // Extract scales + memcpy(auxs, x[i].scales, 12); + uint32_t tmp = auxs[2]; + auxs[2] = ((auxs[0] >> 4) & kmask2) | (((tmp >> 4) & kmask1) << 4); + auxs[3] = ((auxs[1] >> 4) & kmask2) | (((tmp >> 6) & kmask1) << 4); + auxs[0] = (auxs[0] & kmask2) | (((tmp >> 0) & kmask1) << 4); + auxs[1] = (auxs[1] & kmask2) | (((tmp >> 2) & kmask1) << 4); + const int8_t *scales = (const int8_t *)auxs; + + // SIMD dot product with register accumulators + v128_t v_acc0 = wasm_i32x4_splat(0); + v128_t v_acc1 = wasm_i32x4_splat(0); + a = aux8; + for (int j = 0; j < QK_K / 16; ++j) { + const v128_t v_scale = wasm_i16x8_splat(scales[j] - 32); + + // Process 16 elements per iteration + for (int k = 0; k < 2; ++k) { + const v128_t v_q8 = wasm_i16x8_load8x8(q8); + const v128_t v_a = wasm_i16x8_load8x8(a); + + v128_t v_prod = wasm_i16x8_mul(v_q8, v_a); + v_prod = wasm_i16x8_mul(v_prod, v_scale); + + v_acc0 = wasm_i32x4_add(v_acc0, wasm_i32x4_extend_low_i16x8(v_prod)); + v_acc1 = wasm_i32x4_add(v_acc1, wasm_i32x4_extend_high_i16x8(v_prod)); + + q8 += 8; + a += 8; + } + } + + // Accumulate results + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + const v128_t v_d = wasm_f32x4_splat(d); + v128_t v_sum = wasm_f32x4_add( + wasm_f32x4_mul(wasm_f32x4_convert_i32x4(v_acc0), v_d), + wasm_f32x4_mul(wasm_f32x4_convert_i32x4(v_acc1), v_d)); + + // Accumulate into sums vector + wasm_v128_store(sums, wasm_f32x4_add(wasm_v128_load(sums), v_sum)); + } + + // Horizontal sum + v128_t v_sum = wasm_f32x4_add(wasm_v128_load(sums), wasm_v128_load(sums + 4)); + sumf = wasm_f32x4_extract_lane(v_sum, 0) + wasm_f32x4_extract_lane(v_sum, 1) + wasm_f32x4_extract_lane(v_sum, 2) + wasm_f32x4_extract_lane(v_sum, 3); + + *s = sumf; + +#elif defined __riscv_v_intrinsic + + uint32_t aux[3]; + uint32_t utmp[4]; + + const int vector_length = __riscv_vlenb() * 8; + float sumf = 0; + + switch (vector_length) { + case 256: + for (int i = 0; i < nb; ++i) { + const uint8_t *__restrict q3 = x[i].qs; + const uint8_t *__restrict qh = x[i].hmask; + const int8_t *__restrict q8 = y[i].qs; + + memcpy(aux, x[i].scales, 12); + utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); + utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); + utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); + utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); + + int8_t *scale = (int8_t *)utmp; + for (int j = 0; j < 16; ++j) scale[j] -= 32; + + size_t vl = 32; + uint8_t m = 1; + + vint32m1_t vzero = __riscv_vmv_v_x_i32m1(0, 1); + vuint8m1_t vqh = __riscv_vle8_v_u8m1(qh, vl); + + int sum_t = 0; + + for (int j = 0; j < QK_K; j += 128) { + vl = 32; + + // load Q3 + vuint8m1_t q3_x = __riscv_vle8_v_u8m1(q3, vl); + + vint8m1_t q3_0 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(q3_x, 0x03, vl)); + vint8m1_t q3_1 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q3_x, 0x2, vl), 0x03, vl)); + vint8m1_t q3_2 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q3_x, 0x4, vl), 0x03, vl)); + vint8m1_t q3_3 = __riscv_vreinterpret_v_u8m1_i8m1(__riscv_vand_vx_u8m1(__riscv_vsrl_vx_u8m1(q3_x, 0x6, vl), 0x03, vl)); + + // compute mask for subtraction + vuint8m1_t qh_m0 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_0 = __riscv_vmseq_vx_u8m1_b8(qh_m0, 0, vl); + vint8m1_t q3_m0 = __riscv_vsub_vx_i8m1_mu(vmask_0, q3_0, q3_0, 0x4, vl); + m <<= 1; + + vuint8m1_t qh_m1 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_1 = __riscv_vmseq_vx_u8m1_b8(qh_m1, 0, vl); + vint8m1_t q3_m1 = __riscv_vsub_vx_i8m1_mu(vmask_1, q3_1, q3_1, 0x4, vl); + m <<= 1; + + vuint8m1_t qh_m2 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_2 = __riscv_vmseq_vx_u8m1_b8(qh_m2, 0, vl); + vint8m1_t q3_m2 = __riscv_vsub_vx_i8m1_mu(vmask_2, q3_2, q3_2, 0x4, vl); + m <<= 1; + + vuint8m1_t qh_m3 = __riscv_vand_vx_u8m1(vqh, m, vl); + vbool8_t vmask_3 = __riscv_vmseq_vx_u8m1_b8(qh_m3, 0, vl); + vint8m1_t q3_m3 = __riscv_vsub_vx_i8m1_mu(vmask_3, q3_3, q3_3, 0x4, vl); + m <<= 1; + + // load Q8 and take product with Q3 + vint16m2_t a0 = __riscv_vwmul_vv_i16m2(q3_m0, __riscv_vle8_v_i8m1(q8, vl), vl); + vint16m2_t a1 = __riscv_vwmul_vv_i16m2(q3_m1, __riscv_vle8_v_i8m1(q8 + 32, vl), vl); + vint16m2_t a2 = __riscv_vwmul_vv_i16m2(q3_m2, __riscv_vle8_v_i8m1(q8 + 64, vl), vl); + vint16m2_t a3 = __riscv_vwmul_vv_i16m2(q3_m3, __riscv_vle8_v_i8m1(q8 + 96, vl), vl); + + vl = 16; + + // retrieve lane to multiply with scale + vint32m2_t aux0_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a0, 0), (scale[0]), vl); + vint32m2_t aux0_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a0, 1), (scale[1]), vl); + vint32m2_t aux1_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a1, 0), (scale[2]), vl); + vint32m2_t aux1_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a1, 1), (scale[3]), vl); + vint32m2_t aux2_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a2, 0), (scale[4]), vl); + vint32m2_t aux2_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a2, 1), (scale[5]), vl); + vint32m2_t aux3_0 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a3, 0), (scale[6]), vl); + vint32m2_t aux3_1 = __riscv_vwmul_vx_i32m2(__riscv_vget_v_i16m2_i16m1(a3, 1), (scale[7]), vl); + + vint32m1_t isum0 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux0_0, aux0_1, vl), vzero, vl); + vint32m1_t isum1 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux1_0, aux1_1, vl), isum0, vl); + vint32m1_t isum2 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux2_0, aux2_1, vl), isum1, vl); + vint32m1_t isum3 = __riscv_vredsum_vs_i32m2_i32m1(__riscv_vadd_vv_i32m2(aux3_0, aux3_1, vl), isum2, vl); + + sum_t += __riscv_vmv_x_s_i32m1_i32(isum3); + + q3 += 32; + q8 += 128; + scale += 8; + } + + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + + sumf += d * sum_t; + } + break; + case 128: + for (int i = 0; i < nb; ++i) { + const uint8_t *restrict q3 = x[i].qs; + const uint8_t *restrict qh = x[i].hmask; + const int8_t *restrict q8 = y[i].qs; + + int8_t *scale = (int8_t *)utmp; + int tmp; + __asm__ __volatile__( + "vsetivli zero, 12, e8, m1\n\t" + "vle8.v v0, (%[s6b])\n\t" + "vmv1r.v v2, v0\n\t" + "vsetivli zero, 2, e64, m1\n\t" + "vmv.v.x v9, %[sh]\n\t" + "vslidedown.vi v1, v0, 1\n\t" + "vslide1up.vx v8, v9, zero\n\t" // {0, 0, 4, 4} + "vslideup.vi v0, v2, 1\n\t" // {aux[0], aux[1], aux[0], aux[1]} + "vsetivli zero, 4, e32, m1\n\t" + "vid.v v9\n\t" + "vmv.x.s %[tmp], v1\n\t" + "vsll.vi v9, v9, 1\n\t" // {0, 2, 4, 6} + "vmv.v.x v1, %[tmp]\n\t" // {aux[2], aux[2], aux[2], aux[2]} + "vsrl.vv v4, v1, v9\n\t" + "vsrl.vv v2, v0, v8\n\t" + "vand.vx v5, v4, %[kmask1]\n\t" + "vand.vx v3, v2, %[kmask2]\n\t" + "vsll.vi v6, v5, 4\n\t" + "vor.vv v7, v6, v3\n\t" + "vsetivli zero, 16, e8, m1\n\t" + "vsub.vx v0, v7, %[c]\n\t" + "vse8.v v0, (%[scale])" + : [tmp] "=&r"(tmp) + : [sh] "r"(0x0000000400000004), [s6b] "r"(x[i].scales), [c] "r"(32), [scale] "r"(scale), [kmask1] "r"(kmask1), [kmask2] "r"(kmask2) + : "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); + + uint8_t m = 1; + int isum = 0; + for (int j = 0; j < QK_K; j += 128) { + __asm__ __volatile__( + "vsetvli zero, %[vl32], e8, m2, ta, mu\n\t" + "vle8.v v8, (%[q3])\n\t" + "vsrl.vi v10, v8, 2\n\t" + "vsrl.vi v12, v8, 4\n\t" + "vsrl.vi v14, v8, 6\n\t" + "vand.vi v8, v8, 3\n\t" + "vand.vi v10, v10, 3\n\t" + "vand.vi v12, v12, 3\n\t" + "vle8.v v2, (%[qh])\n\t" + "vand.vx v4, v2, %[m]\n\t" + "slli %[m], %[m], 1\n\t" + "vmseq.vx v0, v4, zero\n\t" + "vadd.vi v8, v8, -4, v0.t\n\t" + "vand.vx v4, v2, %[m]\n\t" + "slli %[m], %[m], 1\n\t" + "vmseq.vx v0, v4, zero\n\t" + "vadd.vi v10, v10, -4, v0.t\n\t" + "vand.vx v4, v2, %[m]\n\t" + "slli %[m], %[m], 1\n\t" + "vmseq.vx v0, v4, zero\n\t" + "vadd.vi v12, v12, -4, v0.t\n\t" + "vand.vx v4, v2, %[m]\n\t" + "slli %[m], %[m], 1\n\t" + "vmseq.vx v0, v4, zero\n\t" + "vadd.vi v14, v14, -4, v0.t\n\t" + "vsetvli zero, %[vl128], e8, m8\n\t" + "vle8.v v0, (%[q8])\n\t" + "vsetvli zero, %[vl64], e8, m4\n\t" + "vwmul.vv v16, v0, v8\n\t" + "vwmul.vv v24, v4, v12\n\t" + "vsetivli zero, 16, e16, m2\n\t" + "vmv.v.x v0, zero\n\t" + "vwredsum.vs v10, v16, v0\n\t" + "vwredsum.vs v9, v18, v0\n\t" + "vwredsum.vs v8, v20, v0\n\t" + "vwredsum.vs v7, v22, v0\n\t" + "vwredsum.vs v11, v24, v0\n\t" + "vwredsum.vs v12, v26, v0\n\t" + "vwredsum.vs v13, v28, v0\n\t" + "vwredsum.vs v14, v30, v0\n\t" + "vsetivli zero, 4, e32, m1\n\t" + "vslideup.vi v10, v9, 1\n\t" + "vslideup.vi v8, v7, 1\n\t" + "vslideup.vi v11, v12, 1\n\t" + "vslideup.vi v13, v14, 1\n\t" + "vslideup.vi v10, v8, 2\n\t" + "vslideup.vi v11, v13, 2\n\t" + "vsetivli zero, 8, e32, m2\n\t" + "vle8.v v15, (%[scale])\n\t" + "vsext.vf4 v12, v15\n\t" + "vmul.vv v10, v10, v12\n\t" + "vredsum.vs v0, v10, v0\n\t" + "vmv.x.s %[tmp], v0\n\t" + "add %[isum], %[isum], %[tmp]" + : [tmp] "=&r"(tmp), [m] "+&r"(m), [isum] "+&r"(isum) + : [vl128] "r"(128), [vl64] "r"(64), [vl32] "r"(32), [q3] "r"(q3), [qh] "r"(qh), [scale] "r"(scale), [q8] "r"(q8) + : "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"); + q3 += 32; + q8 += 128; + scale += 8; + } + + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + sumf += d * isum; + } + break; + default: + assert(false && "Unsupported vector length"); + break; + } + + *s = sumf; + +#elif defined(__POWER9_VECTOR__) + const vector signed char lowMask = vec_splats((signed char)0x3); + const vector signed char lowMask1 = vec_splats((int8_t)0xf); + const vector signed char lowMask2 = vec_splats((int8_t)0x30); + const vector int v0 = vec_splats((int32_t)0); + const vector signed char v1 = vec_splats((signed char)0x1); + const vector unsigned char v2 = vec_splats((unsigned char)0x2); + const vector unsigned char v3 = vec_splats((unsigned char)0x3); + const vector unsigned char v4 = vec_splats((unsigned char)0x4); + const vector unsigned char v6 = vec_splats((unsigned char)0x6); + const vector signed char off = vec_splats((signed char)0x20); + + vector float vsumf0 = vec_splats(0.0f); + vector float vsumf1 = vec_splats(0.0f); + vector float vsumf2 = vec_splats(0.0f); + vector float vsumf3 = vec_splats(0.0f); + + for (int i = 0; i < nb; ++i) { + vector float vxd = vec_splats(MLLM_FP16_TO_FP32(x[i].d)); + vector float vyd = vec_splats(y[i].d); + vector float vd = vec_mul(vxd, vyd); + + UNUSED(kmask1); + UNUSED(kmask2); + + vector signed char u0 = (vector signed char)vec_xl_len(x[i].scales, 8); + vector signed char u1 = vec_and(u0, lowMask1); + vector signed char u2 = (vector signed char)vec_xl_len(x[i].scales + 8, 4); + vector signed char u3 = (vector signed char)vec_mergeh((vector signed int)u2, (vector signed int)vec_sr(u2, v2)); + vector signed char u30 = vec_sl(vec_and(u3, lowMask), v4); + vector signed char u31 = vec_and(u3, lowMask2); + + u1 = vec_or(u1, u30); + u2 = vec_or(vec_sr(u0, v4), u31); + + vector signed char vscales = (vector signed char)vec_mergeh((vector signed long long)u1, (vector signed long long)u2); + vector signed char qxhs0 = (vector signed char)vec_xl(0, x[i].hmask); + vector signed char qxhs1 = (vector signed char)vec_xl(16, x[i].hmask); + + vscales = vec_sub(vscales, off); + + vector signed int vsumi0 = v0; + vector signed int vsumi1 = v0; + vector signed int vsumi2 = v0; + vector signed int vsumi3 = v0; + vector signed int vsumi4 = v0; + vector signed int vsumi5 = v0; + vector signed int vsumi6 = v0; + vector signed int vsumi7 = v0; + + const uint8_t *__restrict q3 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + for (int j = 0; j < QK_K / 128; ++j) { + __builtin_prefetch(q3, 0, 1); + __builtin_prefetch(q8, 0, 1); + + vector signed char qxs0 = (vector signed char)vec_xl(0, q3); + vector signed char qxs1 = (vector signed char)vec_xl(16, q3); + q3 += 32; + + // the low 2 bits + vector signed char qxs00 = vec_and(qxs0, lowMask); + vector signed char qxs01 = vec_and(vec_sr(qxs0, v2), lowMask); + vector signed char qxs02 = vec_and(vec_sr(qxs0, v4), lowMask); + vector signed char qxs03 = vec_and(vec_sr(qxs0, v6), lowMask); + vector signed char qxs10 = vec_and(qxs1, lowMask); + vector signed char qxs11 = vec_and(vec_sr(qxs1, v2), lowMask); + vector signed char qxs12 = vec_and(vec_sr(qxs1, v4), lowMask); + vector signed char qxs13 = vec_and(vec_sr(qxs1, v6), lowMask); + + // the 3rd bit + vector signed char qxh00 = vec_sl(vec_andc(v1, qxhs0), v2); + vector signed char qxh01 = vec_sl(vec_andc(v1, vec_sr(qxhs0, (vector unsigned char)v1)), v2); + vector signed char qxh02 = vec_sl(vec_andc(v1, vec_sr(qxhs0, v2)), v2); + vector signed char qxh03 = vec_sl(vec_andc(v1, vec_sr(qxhs0, v3)), v2); + vector signed char qxh10 = vec_sl(vec_andc(v1, qxhs1), v2); + vector signed char qxh11 = vec_sl(vec_andc(v1, vec_sr(qxhs1, (vector unsigned char)v1)), v2); + vector signed char qxh12 = vec_sl(vec_andc(v1, vec_sr(qxhs1, v2)), v2); + vector signed char qxh13 = vec_sl(vec_andc(v1, vec_sr(qxhs1, v3)), v2); + qxhs0 = vec_sr(qxhs0, v4); + qxhs1 = vec_sr(qxhs1, v4); + + vector signed char q3x00 = vec_sub(qxs00, qxh00); + vector signed char q3x01 = vec_sub(qxs01, qxh01); + vector signed char q3x02 = vec_sub(qxs02, qxh02); + vector signed char q3x03 = vec_sub(qxs03, qxh03); + vector signed char q3x10 = vec_sub(qxs10, qxh10); + vector signed char q3x11 = vec_sub(qxs11, qxh11); + vector signed char q3x12 = vec_sub(qxs12, qxh12); + vector signed char q3x13 = vec_sub(qxs13, qxh13); + + vector signed char q8y00 = vec_xl(0, q8); + vector signed char q8y10 = vec_xl(16, q8); + vector signed char q8y01 = vec_xl(32, q8); + vector signed char q8y11 = vec_xl(48, q8); + vector signed char q8y02 = vec_xl(64, q8); + vector signed char q8y12 = vec_xl(80, q8); + vector signed char q8y03 = vec_xl(96, q8); + vector signed char q8y13 = vec_xl(112, q8); + q8 += 128; + + vector signed short vscales_h = vec_unpackh(vscales); + vector signed short vs0 = vec_splat(vscales_h, 0); + vector signed short vs1 = vec_splat(vscales_h, 1); + vector signed short vs2 = vec_splat(vscales_h, 2); + vector signed short vs3 = vec_splat(vscales_h, 3); + vector signed short vs4 = vec_splat(vscales_h, 4); + vector signed short vs5 = vec_splat(vscales_h, 5); + vector signed short vs6 = vec_splat(vscales_h, 6); + vector signed short vs7 = vec_splat(vscales_h, 7); + vscales = vec_sld(vscales, vscales, 8); + + vector signed short qv00 = vec_add(vec_mule(q3x00, q8y00), vec_mulo(q3x00, q8y00)); + vector signed short qv01 = vec_add(vec_mule(q3x01, q8y01), vec_mulo(q3x01, q8y01)); + vector signed short qv02 = vec_add(vec_mule(q3x02, q8y02), vec_mulo(q3x02, q8y02)); + vector signed short qv03 = vec_add(vec_mule(q3x03, q8y03), vec_mulo(q3x03, q8y03)); + vector signed short qv10 = vec_add(vec_mule(q3x10, q8y10), vec_mulo(q3x10, q8y10)); + vector signed short qv11 = vec_add(vec_mule(q3x11, q8y11), vec_mulo(q3x11, q8y11)); + vector signed short qv12 = vec_add(vec_mule(q3x12, q8y12), vec_mulo(q3x12, q8y12)); + vector signed short qv13 = vec_add(vec_mule(q3x13, q8y13), vec_mulo(q3x13, q8y13)); + + vsumi0 = vec_msum(qv00, vs0, vsumi0); + vsumi1 = vec_msum(qv01, vs2, vsumi1); + vsumi2 = vec_msum(qv02, vs4, vsumi2); + vsumi3 = vec_msum(qv03, vs6, vsumi3); + vsumi4 = vec_msum(qv10, vs1, vsumi4); + vsumi5 = vec_msum(qv11, vs3, vsumi5); + vsumi6 = vec_msum(qv12, vs5, vsumi6); + vsumi7 = vec_msum(qv13, vs7, vsumi7); + } + + vsumi0 = vec_add(vsumi0, vsumi4); + vsumi1 = vec_add(vsumi1, vsumi5); + vsumi2 = vec_add(vsumi2, vsumi6); + vsumi3 = vec_add(vsumi3, vsumi7); + + vsumf0 = vec_madd(vec_ctf(vsumi0, 0), vd, vsumf0); + vsumf1 = vec_madd(vec_ctf(vsumi1, 0), vd, vsumf1); + vsumf2 = vec_madd(vec_ctf(vsumi2, 0), vd, vsumf2); + vsumf3 = vec_madd(vec_ctf(vsumi3, 0), vd, vsumf3); + } + + vsumf0 = vec_add(vsumf0, vsumf2); + vsumf1 = vec_add(vsumf1, vsumf3); + + vsumf0 = vec_add(vsumf0, vsumf1); + + vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 4)); + vsumf0 = vec_add(vsumf0, vec_sld(vsumf0, vsumf0, 8)); + + *s = vec_extract(vsumf0, 0); + +#elif defined __loongarch_asx + + const __m128i m32 = __lsx_vreplgr2vr_b(32); + + __m256 acc = (__m256)__lasx_xvldi(0); + + uint32_t aux[3]; + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const uint8_t *__restrict q3 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + // Set up scales + memcpy(aux, x[i].scales, 12); + __m128i scales128 = lsx_set_w( + ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4), + ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4), + (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4), + (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4)); + scales128 = __lsx_vsub_b(scales128, m32); + + const v16i8 shuffle_mask = {0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15}; + const __m256i scales_shuffled = lasx_ext8_16(__lsx_vshuf_b(scales128, scales128, (__m128i)shuffle_mask)); + + // high bit + const __m256i hbits = __lasx_xvld((const __m256i *)x[i].hmask, 0); + + // integer accumulator + __m256i sumi = __lasx_xvldi(0); + + for (int j = 0; j < QK_K / 128; ++j) { + // load low 2 bits + const __m256i q3bits = __lasx_xvld((const __m256i *)q3, 0); + q3 += 32; + + // prepare low and high bits + const __m256i q3l_0 = __lasx_xvandi_b(q3bits, 3); + const __m256i q3l_1 = __lasx_xvandi_b(__lasx_xvsrli_b(q3bits, 2), 3); + const __m256i q3l_2 = __lasx_xvandi_b(__lasx_xvsrli_b(q3bits, 4), 3); + const __m256i q3l_3 = __lasx_xvsrli_b(q3bits, 6); + const __m256i q3h_0 = __lasx_xvslli_b(__lasx_xvseqi_b(lasx_xvandi_b_bit(hbits, 4 * j + 0), 0), 2); + const __m256i q3h_1 = __lasx_xvslli_b(__lasx_xvseqi_b(lasx_xvandi_b_bit(hbits, 4 * j + 1), 0), 2); + const __m256i q3h_2 = __lasx_xvslli_b(__lasx_xvseqi_b(lasx_xvandi_b_bit(hbits, 4 * j + 2), 0), 2); + const __m256i q3h_3 = __lasx_xvslli_b(__lasx_xvseqi_b(lasx_xvandi_b_bit(hbits, 4 * j + 3), 0), 2); + const __m256i q3_0 = __lasx_xvor_v(q3h_0, q3l_0); + const __m256i q3_1 = __lasx_xvor_v(q3h_1, q3l_1); + const __m256i q3_2 = __lasx_xvor_v(q3h_2, q3l_2); + const __m256i q3_3 = __lasx_xvor_v(q3h_3, q3l_3); + + // load Q8 quants + const __m256i q8_0 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + const __m256i q8_1 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + const __m256i q8_2 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + const __m256i q8_3 = __lasx_xvld((const __m256i *)q8, 0); + q8 += 32; + + __m256i p16_0 = lasx_madd_h_b(q8_0, q3_0); + __m256i p16_1 = lasx_madd_h_b(q8_1, q3_1); + __m256i p16_2 = lasx_madd_h_b(q8_2, q3_2); + __m256i p16_3 = lasx_madd_h_b(q8_3, q3_3); + + // multiply with scales + p16_0 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 0), p16_0); + p16_1 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 1), p16_1); + p16_2 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 2), p16_2); + p16_3 = lasx_madd_h(lasx_xvrepl128vei_h(scales_shuffled, 4 * j + 3), p16_3); + + // accumulate + p16_0 = __lasx_xvadd_w(p16_0, p16_1); + p16_2 = __lasx_xvadd_w(p16_2, p16_3); + sumi = __lasx_xvadd_w(sumi, __lasx_xvadd_w(p16_0, p16_2)); + } + // multiply with block scale and accumulate + acc = __lasx_xvfmadd_s(__lasx_xvreplfr2vr_s(d), __lasx_xvffint_s_w(sumi), acc); + } + + *s = hsum_float_8(acc); +#elif defined(__VXE__) || defined(__VXE2__) + uint32_t aux[3]; + uint32_t utmp[4]; + + const int32x4_t v_z = vec_splat_s32(0); + const uint8x16_t v_3m = vec_splat_u8(0x03); + + const uint8x16_t v_0c = vec_splat_u8(1); + const uint8x16_t v_1c = vec_sl(v_0c, 1); + const uint8x16_t v_2c = vec_sl(v_0c, 2); + const uint8x16_t v_3c = vec_sl(v_0c, 3); + + uint8x16_t q3h[4]; + uint8x16_t q3b[2]; + int8x16_t q3bytes[4]; + int8x16_t q8bytes[4]; + uint8x16_t qhbits[2]; + + float sum = 0; + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *restrict x0l = x[i].qs; + const uint8_t *restrict x0h = x[i].hmask; + const int8_t *restrict y0 = y[i].qs; + + qhbits[0] = vec_xl(0, x0h); + qhbits[1] = vec_xl(16, x0h); + + int32_t isum = 0; + + memcpy(aux, x[i].scales, 12); + utmp[3] = ((aux[1] >> 4) & kmask2) | (((aux[2] >> 6) & kmask1) << 4); + utmp[2] = ((aux[0] >> 4) & kmask2) | (((aux[2] >> 4) & kmask1) << 4); + utmp[1] = (aux[1] & kmask2) | (((aux[2] >> 2) & kmask1) << 4); + utmp[0] = (aux[0] & kmask2) | (((aux[2] >> 0) & kmask1) << 4); + + int8_t *scale = (int8_t *)utmp; + for (int j = 0; j < 16; ++j) scale[j] -= 32; + + for (int j = 0; j < QK_K / 128; ++j) { + int32x4_t isum0, isum1, isum2, isum3; + + q3b[0] = vec_xl(0, x0l); + q3b[1] = vec_xl(16, x0l); + x0l += 32; + + q8bytes[0] = vec_xl(0, y0); + q8bytes[1] = vec_xl(16, y0); + q8bytes[2] = vec_xl(32, y0); + q8bytes[3] = vec_xl(48, y0); + q8bytes[4] = vec_xl(64, y0); + q8bytes[5] = vec_xl(80, y0); + q8bytes[6] = vec_xl(96, y0); + q8bytes[7] = vec_xl(112, y0); + y0 += 128; + + q3h[0] = vec_sl(vec_andc(v_0c, qhbits[0]), 2); + q3h[1] = vec_sl(vec_andc(v_0c, qhbits[1]), 2); + q3h[2] = vec_sl(vec_andc(v_1c, qhbits[0]), 1); + q3h[3] = vec_sl(vec_andc(v_1c, qhbits[1]), 1); + + q3bytes[0] = vec_sub((int8x16_t)vec_and(q3b[0], v_3m), (int8x16_t)q3h[0]); + q3bytes[1] = vec_sub((int8x16_t)vec_and(q3b[1], v_3m), (int8x16_t)q3h[1]); + q3bytes[2] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[0], 2), v_3m), (int8x16_t)q3h[2]); + q3bytes[3] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[1], 2), v_3m), (int8x16_t)q3h[3]); + + isum0 = mllm_vec_dot(v_z, q3bytes[0], q8bytes[0]); + isum1 = mllm_vec_dot(v_z, q3bytes[1], q8bytes[1]); + isum2 = mllm_vec_dot(v_z, q3bytes[2], q8bytes[2]); + isum3 = mllm_vec_dot(v_z, q3bytes[3], q8bytes[3]); + + isum += (isum0[0] + isum0[1] + isum0[2] + isum0[3]) * scale[0]; + isum += (isum1[0] + isum1[1] + isum1[2] + isum1[3]) * scale[1]; + isum += (isum2[0] + isum2[1] + isum2[2] + isum2[3]) * scale[2]; + isum += (isum3[0] + isum3[1] + isum3[2] + isum3[3]) * scale[3]; + + scale += 4; + + q3h[0] = vec_andc(v_2c, qhbits[0]); + q3h[1] = vec_andc(v_2c, qhbits[1]); + q3h[2] = vec_sr(vec_andc(v_3c, qhbits[0]), 1); + q3h[3] = vec_sr(vec_andc(v_3c, qhbits[1]), 1); + + q3bytes[0] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[0], 4), v_3m), (int8x16_t)q3h[0]); + q3bytes[1] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[1], 4), v_3m), (int8x16_t)q3h[1]); + q3bytes[2] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[0], 6), v_3m), (int8x16_t)q3h[2]); + q3bytes[3] = vec_sub((int8x16_t)vec_and(vec_sr(q3b[1], 6), v_3m), (int8x16_t)q3h[3]); + + isum0 = mllm_vec_dot(v_z, q3bytes[0], q8bytes[4]); + isum1 = mllm_vec_dot(v_z, q3bytes[1], q8bytes[5]); + isum2 = mllm_vec_dot(v_z, q3bytes[2], q8bytes[6]); + isum3 = mllm_vec_dot(v_z, q3bytes[3], q8bytes[7]); + + isum += (isum0[0] + isum0[1] + isum0[2] + isum0[3]) * scale[0]; + isum += (isum1[0] + isum1[1] + isum1[2] + isum1[3]) * scale[1]; + isum += (isum2[0] + isum2[1] + isum2[2] + isum2[3]) * scale[2]; + isum += (isum3[0] + isum3[1] + isum3[2] + isum3[3]) * scale[3]; + + scale += 4; + + if (j == 0) { + qhbits[0] = vec_sr(qhbits[0], 4); + qhbits[1] = vec_sr(qhbits[1], 4); + } + } + + sum += d * isum; + } + + *s = sum; +#else + // scalar version + // This function is written like this so the compiler can manage to vectorize most of it + // Using -Ofast, GCC and clang manage to produce code that is within a factor of 2 or so from the + // manually vectorized version above. Every other version I tried would run at least 4 times slower. + // The ideal situation would be if we could just write the code once, and the compiler would + // automatically produce the best possible set of machine instructions, instead of us having to manually + // write vectorized versions for AVX, ARM_NEON, etc. + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums[8]; + int32_t aux32[8]; + memset(sums, 0, 8 * sizeof(float)); + + uint32_t auxs[4]; + const int8_t *scales = (const int8_t *)auxs; + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t *__restrict q3 = x[i].qs; + const uint8_t *__restrict hm = x[i].hmask; + const int8_t *__restrict q8 = y[i].qs; + memset(aux32, 0, 8 * sizeof(int32_t)); + int8_t *__restrict a = aux8; + uint8_t m = 1; + for (int j = 0; j < QK_K; j += 128) { + for (int l = 0; l < 32; ++l) a[l] = q3[l] & 3; + for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); + a += 32; + m <<= 1; + for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 2) & 3; + for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); + a += 32; + m <<= 1; + for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 4) & 3; + for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); + a += 32; + m <<= 1; + for (int l = 0; l < 32; ++l) a[l] = (q3[l] >> 6) & 3; + for (int l = 0; l < 32; ++l) a[l] -= (hm[l] & m ? 0 : 4); + a += 32; + m <<= 1; + q3 += 32; + } + a = aux8; + + memcpy(auxs, x[i].scales, 12); + uint32_t tmp = auxs[2]; + auxs[2] = ((auxs[0] >> 4) & kmask2) | (((tmp >> 4) & kmask1) << 4); + auxs[3] = ((auxs[1] >> 4) & kmask2) | (((tmp >> 6) & kmask1) << 4); + auxs[0] = (auxs[0] & kmask2) | (((tmp >> 0) & kmask1) << 4); + auxs[1] = (auxs[1] & kmask2) | (((tmp >> 2) & kmask1) << 4); + for (int j = 0; j < QK_K / 16; ++j) { + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += (scales[j] - 32) * aux16[l]; + q8 += 8; + a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += (scales[j] - 32) * aux16[l]; + q8 += 8; + a += 8; + } + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; + +#endif +} \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ3.hpp b/src/backends/cpu/third_party/ggml/VecDotQ3.hpp new file mode 100644 index 000000000..b0ded910d --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ3.hpp @@ -0,0 +1,31 @@ +/* + * This code is based on mllm(https://github.com/ggerganov/mllm), + * please see https://github.com/ggerganov/mllm/blob/master/src/mllm.c + * mllm is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once +#include + +void vec_dot_q3_K_q8_K(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ4.cpp b/src/backends/cpu/third_party/ggml/VecDotQ4.cpp new file mode 100644 index 000000000..513191b6a --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ4.cpp @@ -0,0 +1,702 @@ +/* + * This code is based on ggml(https://github.com/ggerganov/ggml), + * please see https://github.com/ggerganov/ggml/blob/master/src/ggml.c + * ggml is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "VecDotQ4.hpp" +#include "ComputeUtils.hpp" + +#if QK_K == 256 +void vec_dot_q4_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + assert(n % QK_K == 0); + + const block_q4_K *__restrict x = (block_q4_K *)vx; + const block_q8_K *__restrict y = (block_q8_K *)vy; + + const int nb = n / QK_K; + + static const uint32_t kmask1 = 0x3f3f3f3f; + static const uint32_t kmask2 = 0x0f0f0f0f; + static const uint32_t kmask3 = 0x03030303; + + uint32_t utmp[4]; + +#ifdef __ARM_FEATURE_SVE + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + + const int16x8_t q8sums = vpaddq_s16(vld1q_s16(y[i].bsums), vld1q_s16(y[i].bsums + 8)); + + memcpy(utmp, x[i].scales, K_SCALE_SIZE); + + uint32x2_t mins8 = {0}; + mins8 = vset_lane_u32(utmp[1] & kmask1, mins8, 0); + mins8 = vset_lane_u32(((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4), mins8, 1); + + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[0] &= kmask1; + + const int16x8_t mins = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(mins8))); + const int32x4_t prod = vaddq_s32(vmull_s16(vget_low_s16(q8sums), vget_low_s16(mins)), + vmull_s16(vget_high_s16(q8sums), vget_high_s16(mins))); + sumf -= dmin * vaddvq_s32(prod); + + const uint8_t *scales = (const uint8_t *)utmp; + + const uint8_t *__restrict q4 = (const uint8_t *)x[i].qs; + const int8_t *__restrict q8 = (const int8_t *)y[i].qs; + + const int vector_length = mllm_cpu_get_sve_cnt() * 8; + const svuint8_t m4b = svdup_n_u8(0xf); + const svint32_t mzero = svdup_n_s32(0); + svint32_t sumi1 = svdup_n_s32(0); + svint32_t sumi1_1 = svdup_n_s32(0); + svint32_t sumi1_2 = svdup_n_s32(0); + svint32_t sumi2 = svdup_n_s32(0); + svint32_t sumi2_1 = svdup_n_s32(0); + svint32_t sumi2_2 = svdup_n_s32(0); + switch (vector_length) { + case 128: { + for (int j = 0; j < QK_K / 64; ++j) { + svint8_t q4bytes = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svld1_u8(svptrue_b8(), q4), m4b)); + svint8_t q8bytes = svld1_s8(svptrue_b8(), q8); + q8 += 16; + sumi1_1 = svmla_n_s32_x(svptrue_b32(), sumi1_1, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 0]); + q4bytes = svreinterpret_s8_u8(svand_u8_x(svptrue_b8(), svld1_u8(svptrue_b8(), q4 + 16), m4b)); + q8bytes = svld1_s8(svptrue_b8(), q8); + q8 += 16; + sumi1_2 = svmla_n_s32_x(svptrue_b32(), sumi1_2, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 0]); + + q4bytes = svreinterpret_s8_u8(svlsr_n_u8_x(svptrue_b8(), svld1_u8(svptrue_b8(), q4), 4)); + q8bytes = svld1_s8(svptrue_b8(), q8); + q8 += 16; + sumi2_1 = svmla_n_s32_x(svptrue_b32(), sumi2_1, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 1]); + q4bytes = svreinterpret_s8_u8(svlsr_n_u8_x(svptrue_b8(), svld1_u8(svptrue_b8(), q4 + 16), 4)); + q8bytes = svld1_s8(svptrue_b8(), q8); + q8 += 16; + sumi2_2 = svmla_n_s32_x(svptrue_b32(), sumi2_2, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 1]); + q4 += 32; + } + sumi1 = svadd_s32_x(svptrue_b32(), sumi1_1, sumi1_2); + sumi2 = svadd_s32_x(svptrue_b32(), sumi2_1, sumi2_2); + sumf += d * (svaddv_s32(svptrue_b32(), svadd_s32_x(svptrue_b32(), sumi1, sumi2))); + } break; + case 256: + case 512: { + for (int j = 0; j < QK_K / 64; ++j) { + const svuint8_t q4bits = svld1_u8(svptrue_pat_b8(SV_VL32), q4); + q4 += 32; + svint8_t q4bytes = svreinterpret_s8_u8(svand_u8_x(svptrue_pat_b8(SV_VL32), q4bits, m4b)); + svint8_t q8bytes = svld1_s8(svptrue_pat_b8(SV_VL32), q8); + q8 += 32; + sumi1 = svmla_n_s32_x(svptrue_pat_b32(SV_VL8), sumi1, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 0]); + + q4bytes = svreinterpret_s8_u8(svlsr_n_u8_x(svptrue_pat_b8(SV_VL32), q4bits, 4)); + q8bytes = svld1_s8(svptrue_pat_b8(SV_VL32), q8); + q8 += 32; + sumi2 = svmla_n_s32_x(svptrue_pat_b32(SV_VL8), sumi2, svdot_s32(mzero, q4bytes, q8bytes), scales[2 * j + 1]); + } + sumf += d * (svaddv_s32(svptrue_pat_b32(SV_VL8), svadd_s32_x(svptrue_pat_b32(SV_VL8), sumi1, sumi2))); + } break; + default: + assert(false && "Unsupported vector length"); + break; + } + } + *s = sumf; +#elif defined __ARM_NEON + + const uint8x16_t m4b = vdupq_n_u8(0xf); +#ifdef __ARM_FEATURE_DOTPROD + const int32x4_t mzero = vdupq_n_s32(0); +#endif + + int8x16x2_t q4bytes; + int8x16x2_t q8bytes; + + float sumf = 0; + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + + const int16x8_t q8sums = vpaddq_s16(vld1q_s16(y[i].bsums), vld1q_s16(y[i].bsums + 8)); + + memcpy(utmp, x[i].scales, 12); + + const uint32x2_t mins8 = {utmp[1] & kmask1, ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4)}; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[0] &= kmask1; + + const int16x8_t mins = vreinterpretq_s16_u16(vmovl_u8(vreinterpret_u8_u32(mins8))); + const int32x4_t prod = vaddq_s32(vmull_s16(vget_low_s16(q8sums), vget_low_s16(mins)), + vmull_s16(vget_high_s16(q8sums), vget_high_s16(mins))); + sumf -= dmin * vaddvq_s32(prod); + + const uint8_t *scales = (const uint8_t *)utmp; + + const uint8_t *__restrict q4 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + // int32x4_t isum = mzero; + + int32_t sumi1 = 0; + int32_t sumi2 = 0; + + for (int j = 0; j < QK_K / 64; ++j) { + const uint8x16x2_t q4bits = vld1q_u8_x2(q4); + q4 += 32; + +#ifdef __ARM_FEATURE_DOTPROD + q8bytes = vld1q_s8_x2(q8); + q8 += 32; + q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[0], m4b)); + q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[1], m4b)); + + const int32x4_t p1 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[0]), q4bytes.val[1], q8bytes.val[1]); + sumi1 += vaddvq_s32(p1) * scales[2 * j + 0]; + + q8bytes = vld1q_s8_x2(q8); + q8 += 32; + q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); + q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); + + const int32x4_t p2 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[0]), q4bytes.val[1], q8bytes.val[1]); + + sumi2 += vaddvq_s32(p2) * scales[2 * j + 1]; +#else + q8bytes = vld1q_s8_x2(q8); + q8 += 32; + q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[0], m4b)); + q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[1], m4b)); + const int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[0]), vget_low_s8(q8bytes.val[0])), + vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[1]), vget_low_s8(q8bytes.val[1])), + vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + sumi1 += vaddvq_s16(vaddq_s16(p0, p1)) * scales[2 * j + 0]; + + q8bytes = vld1q_s8_x2(q8); + q8 += 32; + q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); + q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); + const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[0]), vget_low_s8(q8bytes.val[0])), + vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[1]), vget_low_s8(q8bytes.val[1])), + vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + sumi2 += vaddvq_s16(vaddq_s16(p2, p3)) * scales[2 * j + 1]; + +#endif + } + + sumf += d * (sumi1 + sumi2); + } + + *s = sumf; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + + __m256 acc = _mm256_setzero_ps(); + __m128 acc_m = _mm_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + const float dmin = -y[i].d * MLLM_FP16_TO_FP32(x[i].dmin); + + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + const uint8_t *__restrict q4 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + const __m256i mins_and_scales = _mm256_cvtepu8_epi16(_mm_set_epi32(utmp[3], utmp[2], utmp[1], utmp[0])); + + const __m256i q8sums = _mm256_loadu_si256((const __m256i *)y[i].bsums); + const __m128i q8s = _mm_hadd_epi16(_mm256_extracti128_si256(q8sums, 0), _mm256_extracti128_si256(q8sums, 1)); + const __m128i prod = _mm_madd_epi16(_mm256_extracti128_si256(mins_and_scales, 1), q8s); + acc_m = _mm_fmadd_ps(_mm_set1_ps(dmin), _mm_cvtepi32_ps(prod), acc_m); + + const __m128i sc128 = _mm256_extracti128_si256(mins_and_scales, 0); + const __m256i scales = MM256_SET_M128I(sc128, sc128); + + __m256i sumi = _mm256_setzero_si256(); + + for (int j = 0; j < QK_K / 64; ++j) { + const __m256i scale_l = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2 * j + 0)); + const __m256i scale_h = _mm256_shuffle_epi8(scales, get_scale_shuffle_k4(2 * j + 1)); + + const __m256i q4bits = _mm256_loadu_si256((const __m256i *)q4); + q4 += 32; + const __m256i q4l = _mm256_and_si256(q4bits, m4); + const __m256i q4h = _mm256_and_si256(_mm256_srli_epi16(q4bits, 4), m4); + + const __m256i q8l = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + __m256i p16l = _mm256_maddubs_epi16(q4l, q8l); + p16l = _mm256_madd_epi16(scale_l, p16l); + + const __m256i q8h = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + __m256i p16h = _mm256_maddubs_epi16(q4h, q8h); + p16h = _mm256_madd_epi16(scale_h, p16h); + const __m256i sumj = _mm256_add_epi32(p16l, p16h); + + sumi = _mm256_add_epi32(sumi, sumj); + } + + __m256 vd = _mm256_set1_ps(d); + acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(sumi), acc); + } + + acc_m = _mm_add_ps(acc_m, _mm_movehl_ps(acc_m, acc_m)); + acc_m = _mm_add_ss(acc_m, _mm_movehdup_ps(acc_m)); + + *s = hsum_float_8(acc) + _mm_cvtss_f32(acc_m); + +#else + const uint8_t *scales = (const uint8_t *)&utmp[0]; + const uint8_t *mins = (const uint8_t *)&utmp[2]; + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums[8]; + int32_t aux32[8]; + memset(sums, 0, 8 * sizeof(float)); + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t *__restrict q4 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + memset(aux32, 0, 8 * sizeof(int32_t)); + int8_t *__restrict a = aux8; + for (int j = 0; j < QK_K / 64; ++j) { + for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] & 0xF); + a += 32; + for (int l = 0; l < 32; ++l) a[l] = (int8_t)(q4[l] >> 4); + a += 32; + q4 += 32; + } + memcpy(utmp, x[i].scales, 12); + utmp[3] = ((utmp[2] >> 4) & kmask2) | (((utmp[1] >> 6) & kmask3) << 4); + const uint32_t uaux = utmp[1] & kmask1; + utmp[1] = (utmp[2] & kmask2) | (((utmp[0] >> 6) & kmask3) << 4); + utmp[2] = uaux; + utmp[0] &= kmask1; + + int sumi = 0; + for (int j = 0; j < QK_K / 16; ++j) sumi += y[i].bsums[j] * mins[j / 2]; + a = aux8; + int is = 0; + for (int j = 0; j < QK_K / 32; ++j) { + int32_t scale = scales[is++]; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; + a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; + a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; + a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; + a += 8; + } + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + const float dmin = MLLM_FP16_TO_FP32(x[i].dmin) * y[i].d; + sumf -= dmin * sumi; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} +#else +void vec_dot_q4_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + assert(n % QK_K == 0); + + const block_q4_K *__restrict x = (block_q4_K *)vx; + const block_q8_K *__restrict y = (block_q8_K *)vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + const uint8x16_t m4b = vdupq_n_u8(0xf); + +#ifdef __ARM_FEATURE_DOTPROD + const int32x4_t mzero = vdupq_n_s32(0); +#endif + + float sumf = 0; + + int8x16x2_t q4bytes; + int8x16x4_t q8bytes; + + float sum_mins = 0.f; + + uint16_t aux16[2]; + const uint8_t *__restrict scales = (const uint8_t *)aux16; + + for (int i = 0; i < nb; ++i) { + const uint8_t *__restrict q4 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + const uint16_t *__restrict a = (const uint16_t *)x[i].scales; + aux16[0] = a[0] & 0x0f0f; + aux16[1] = (a[0] >> 4) & 0x0f0f; + + const int32_t summi = scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3]); + sum_mins += y[i].d * (float)x[i].d[1] * summi; + + const float d = y[i].d * (float)x[i].d[0]; + + const uint8x16x2_t q4bits = vld1q_u8_x2(q4); + +#ifdef __ARM_FEATURE_DOTPROD + q8bytes = vld1q_s8_x4(q8); + q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[0], m4b)); + q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[1], m4b)); + + const int32x4_t p1 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[0]), q4bytes.val[1], q8bytes.val[1]); + const int32_t sumi1 = vaddvq_s32(p1) * scales[0]; + + q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); + q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); + + const int32x4_t p2 = vdotq_s32(vdotq_s32(mzero, q4bytes.val[0], q8bytes.val[2]), q4bytes.val[1], q8bytes.val[3]); + const int32_t sumi2 = vaddvq_s32(p2) * scales[1]; + +#else + q8bytes = vld1q_s8_x4(q8); + q4bytes.val[0] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[0], m4b)); + q4bytes.val[1] = vreinterpretq_s8_u8(vandq_u8(q4bits.val[1], m4b)); + const int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[0]), vget_low_s8(q8bytes.val[0])), + vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + const int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[1]), vget_low_s8(q8bytes.val[1])), + vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + int32_t sumi1 = vaddvq_s16(vaddq_s16(p0, p1)) * scales[0]; + + q4bytes.val[0] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[0], 4)); + q4bytes.val[1] = vreinterpretq_s8_u8(vshrq_n_u8(q4bits.val[1], 4)); + const int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[0]), vget_low_s8(q8bytes.val[2])), + vmull_s8(vget_high_s8(q4bytes.val[0]), vget_high_s8(q8bytes.val[2]))); + const int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8(q4bytes.val[1]), vget_low_s8(q8bytes.val[3])), + vmull_s8(vget_high_s8(q4bytes.val[1]), vget_high_s8(q8bytes.val[3]))); + int32_t sumi2 = vaddvq_s16(vaddq_s16(p2, p3)) * scales[1]; + +#endif + sumf += d * (sumi1 + sumi2); + } + + *s = sumf - sum_mins; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + + __m256 acc = _mm256_setzero_ps(); + + float summs = 0; + + uint16_t aux16[2]; + const uint8_t *scales = (const uint8_t *)aux16; + + for (int i = 0; i < nb; ++i) { + const float d = MLLM_FP16_TO_FP32(x[i].d[0]) * y[i].d; + const float m = MLLM_FP16_TO_FP32(x[i].d[1]) * y[i].d; + const __m256 vd = _mm256_set1_ps(d); + + const uint16_t *a = (const uint16_t *)x[i].scales; + aux16[0] = a[0] & 0x0f0f; + aux16[1] = (a[0] >> 4) & 0x0f0f; + + summs += m * (scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3])); + + const uint8_t *__restrict q4 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + + const __m256i q4bits = _mm256_loadu_si256((const __m256i *)q4); + const __m256i q4l = _mm256_and_si256(q4bits, m4); + const __m256i q4h = _mm256_and_si256(_mm256_srli_epi16(q4bits, 4), m4); + + const __m256i q8l = _mm256_loadu_si256((const __m256i *)(q8 + 0)); + const __m256i q8h = _mm256_loadu_si256((const __m256i *)(q8 + 32)); + + const __m256i p16l = _mm256_maddubs_epi16(q4l, q8l); + const __m256i p16h = _mm256_maddubs_epi16(q4h, q8h); + + const __m256i p32l = _mm256_madd_epi16(_mm256_set1_epi16(scales[0]), p16l); + acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(p32l), acc); + + const __m256i p32h = _mm256_madd_epi16(_mm256_set1_epi16(scales[1]), p16h); + acc = _mm256_fmadd_ps(vd, _mm256_cvtepi32_ps(p32h), acc); + } + + *s = hsum_float_8(acc) - summs; + +#else + + uint8_t aux8[QK_K]; + int16_t aux16[16]; + float sums[8]; + memset(sums, 0, 8 * sizeof(float)); + + uint16_t s16[2]; + const uint8_t *__restrict scales = (const uint8_t *)s16; + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t *__restrict q4 = x[i].qs; + const int8_t *__restrict q8 = y[i].qs; + uint8_t *__restrict a = aux8; + for (int l = 0; l < 32; ++l) a[l + 0] = q4[l] & 0xF; + for (int l = 0; l < 32; ++l) a[l + 32] = q4[l] >> 4; + + const uint16_t *__restrict b = (const uint16_t *)x[i].scales; + s16[0] = b[0] & 0x0f0f; + s16[1] = (b[0] >> 4) & 0x0f0f; + + sumf -= y[i].d * MLLM_FP16_TO_FP32(x[i].d[1]) * (scales[2] * (y[i].bsums[0] + y[i].bsums[1]) + scales[3] * (y[i].bsums[2] + y[i].bsums[3])); + + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d[0]); + + for (int j = 0; j < QK_K / 32; ++j) { + for (int l = 0; l < 16; ++l) aux16[l] = q8[l] * a[l]; + q8 += 16; + a += 16; + for (int l = 0; l < 16; ++l) aux16[l] += q8[l] * a[l]; + q8 += 16; + a += 16; + const float dl = d * scales[j]; + for (int l = 0; l < 8; ++l) sums[l] += dl * (aux16[l] + aux16[l + 8]); + } + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} +#endif +#ifdef __AVX2__ +static void vec_dot_q4_0_q8_0_avx(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + const int qk = QK8_0; + const int nb = n / qk; + + assert(n % qk == 0); + + const block_q4_0 *__restrict x = (block_q4_0 *)vx; + const block_q8_0 *__restrict y = (block_q8_0 *)vy; + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + + // Main loop + for (int i = 0; i < nb; ++i) { + /* Compute combined scale for the block */ + const __m256 d = _mm256_set1_ps(MLLM_FP16_TO_FP32(x[i].d) * MLLM_FP16_TO_FP32(y[i].d)); + + __m256i bx = bytes_from_nibbles_32(x[i].qs); + + // Now we have a vector with bytes in [ 0 .. 15 ] interval. Offset them into [ -8 .. +7 ] interval. + const __m256i off = _mm256_set1_epi8(8); + bx = _mm256_sub_epi8(bx, off); + + __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); + + const __m256 q = mul_sum_i8_pairs_float(bx, by); + + /* Multiply q with scale and accumulate */ + acc = _mm256_fmadd_ps(d, q, acc); + } + *s = hsum_float_8(acc); +} +#endif +#ifdef __ARM_NEON +static void vec_dot_q4_0_q8_0_arm(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + const int qk = QK8_0; + const int nb = n / qk; + + assert(n % qk == 0); + + const block_q4_0 *__restrict x = (block_q4_0 *)vx; + const block_q8_0 *__restrict y = (block_q8_0 *)vy; + +#if defined(__ARM_FEATURE_MATMUL_INT8) + { + size_t bs = 0; + size_t bx = 0; + size_t by = 0; + const block_q4_0 *__restrict vx0 = (const block_q4_0 *)vx; + const block_q4_0 *__restrict vx1 = (const block_q4_0 *)((const uint8_t *)vx + bx); + const block_q8_0 *__restrict vy0 = (const block_q8_0 *)vy; + const block_q8_0 *__restrict vy1 = (const block_q8_0 *)((const uint8_t *)vy + by); + + float32x4_t sumv0 = vdupq_n_f32(0.0f); + + for (int i = 0; i < nb; i++) { + const block_q4_0 *__restrict b_x0 = &vx0[i]; + const block_q4_0 *__restrict b_x1 = &vx1[i]; + const block_q8_0 *__restrict b_y0 = &vy0[i]; + const block_q8_0 *__restrict b_y1 = &vy1[i]; + + const uint8x16_t m4b = vdupq_n_u8(0x0F); + const int8x16_t s8b = vdupq_n_s8(0x8); + + const uint8x16_t v0_0 = vld1q_u8(b_x0->qs); + const uint8x16_t v0_1 = vld1q_u8(b_x1->qs); + + // 4-bit -> 8-bit + const int8x16_t v0_0l = vreinterpretq_s8_u8(vandq_u8(v0_0, m4b)); + const int8x16_t v0_0h = vreinterpretq_s8_u8(vshrq_n_u8(v0_0, 4)); + const int8x16_t v0_1l = vreinterpretq_s8_u8(vandq_u8(v0_1, m4b)); + const int8x16_t v0_1h = vreinterpretq_s8_u8(vshrq_n_u8(v0_1, 4)); + + // sub 8 + const int8x16_t x0_l = vsubq_s8(v0_0l, s8b); + const int8x16_t x0_h = vsubq_s8(v0_0h, s8b); + const int8x16_t x1_l = vsubq_s8(v0_1l, s8b); + const int8x16_t x1_h = vsubq_s8(v0_1h, s8b); + + // load y + const int8x16_t y0_l = vld1q_s8(b_y0->qs); + const int8x16_t y0_h = vld1q_s8(b_y0->qs + 16); + const int8x16_t y1_l = vld1q_s8(b_y1->qs); + const int8x16_t y1_h = vld1q_s8(b_y1->qs + 16); + + float32_t _scale[4] = { + MLLM_FP16_TO_FP32(b_x0->d) * MLLM_FP16_TO_FP32(b_y0->d), + MLLM_FP16_TO_FP32(b_x0->d) * MLLM_FP16_TO_FP32(b_y1->d), + MLLM_FP16_TO_FP32(b_x1->d) * MLLM_FP16_TO_FP32(b_y0->d), + MLLM_FP16_TO_FP32(b_x1->d) * MLLM_FP16_TO_FP32(b_y1->d)}; + float32x4_t scale = vld1q_f32(_scale); + + int8x16_t l0 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(x0_l), vreinterpretq_s64_s8(x1_l))); + int8x16_t l1 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(x0_l), vreinterpretq_s64_s8(x1_l))); + + int8x16_t l2 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(x0_h), vreinterpretq_s64_s8(x1_h))); + int8x16_t l3 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(x0_h), vreinterpretq_s64_s8(x1_h))); + + int8x16_t r0 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(y0_l), vreinterpretq_s64_s8(y1_l))); + int8x16_t r1 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(y0_l), vreinterpretq_s64_s8(y1_l))); + + int8x16_t r2 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(y0_h), vreinterpretq_s64_s8(y1_h))); + int8x16_t r3 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(y0_h), vreinterpretq_s64_s8(y1_h))); + + sumv0 = vmlaq_f32(sumv0, (vcvtq_f32_s32(vmmlaq_s32((vmmlaq_s32((vmmlaq_s32((vmmlaq_s32(vdupq_n_s32(0), l0, r0)), l1, r1)), l2, r2)), l3, r3))), scale); + } + + float32x4_t sumv1 = vextq_f32(sumv0, sumv0, 2); + float32x4_t sumv2 = vzip1q_f32(sumv0, sumv1); + + vst1_f32(s, vget_low_f32(sumv2)); + vst1_f32(s + bs, vget_high_f32(sumv2)); + + return; + } +#endif + + float32x4_t sumv0 = vdupq_n_f32(0.0F); + float32x4_t sumv1 = vdupq_n_f32(0.0F); + + assert(nb % 2 == 0); // TODO: handle odd nb + for (int i = 0; i < nb; i += 2) { + const block_q4_0 *__restrict x0 = &x[i + 0]; + const block_q4_0 *__restrict x1 = &x[i + 1]; + const block_q8_0 *__restrict y0 = &y[i + 0]; + const block_q8_0 *__restrict y1 = &y[i + 1]; + + const uint8x16_t m4b = vdupq_n_u8(0x0F); + const int8x16_t s8b = vdupq_n_s8(0x8); + + const uint8x16_t v0_0 = vld1q_u8(x0->qs); + const uint8x16_t v0_1 = vld1q_u8(x1->qs); + + // 4-bit -> 8-bit + const int8x16_t v0_0l = vreinterpretq_s8_u8(vandq_u8(v0_0, m4b)); + const int8x16_t v0_0h = vreinterpretq_s8_u8(vshrq_n_u8(v0_0, 4)); + const int8x16_t v0_1l = vreinterpretq_s8_u8(vandq_u8(v0_1, m4b)); + const int8x16_t v0_1h = vreinterpretq_s8_u8(vshrq_n_u8(v0_1, 4)); + + // sub 8 + const int8x16_t v0_0ls = vsubq_s8(v0_0l, s8b); + const int8x16_t v0_0hs = vsubq_s8(v0_0h, s8b); + const int8x16_t v0_1ls = vsubq_s8(v0_1l, s8b); + const int8x16_t v0_1hs = vsubq_s8(v0_1h, s8b); + + // load y + const int8x16_t v1_0l = vld1q_s8(y0->qs); + const int8x16_t v1_0h = vld1q_s8(y0->qs + 16); + const int8x16_t v1_1l = vld1q_s8(y1->qs); + const int8x16_t v1_1h = vld1q_s8(y1->qs + 16); + +#if defined(__ARM_FEATURE_DOTPROD) + // dot product into int32x4_t + const int32x4_t p_0 = vdotq_s32(vdotq_s32(vdupq_n_s32(0), v0_0ls, v1_0l), v0_0hs, v1_0h); + const int32x4_t p_1 = vdotq_s32(vdotq_s32(vdupq_n_s32(0), v0_1ls, v1_1l), v0_1hs, v1_1h); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(p_0), MLLM_FP16_TO_FP32(x0->d) * MLLM_FP16_TO_FP32(y0->d)); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(p_1), MLLM_FP16_TO_FP32(x1->d) * MLLM_FP16_TO_FP32(y1->d)); +#else + const int16x8_t pl0l = vmull_s8(vget_low_s8(v0_0ls), vget_low_s8(v1_0l)); + const int16x8_t pl0h = vmull_s8(vget_high_s8(v0_0ls), vget_high_s8(v1_0l)); + const int16x8_t ph0l = vmull_s8(vget_low_s8(v0_0hs), vget_low_s8(v1_0h)); + const int16x8_t ph0h = vmull_s8(vget_high_s8(v0_0hs), vget_high_s8(v1_0h)); + + const int16x8_t pl1l = vmull_s8(vget_low_s8(v0_1ls), vget_low_s8(v1_1l)); + const int16x8_t pl1h = vmull_s8(vget_high_s8(v0_1ls), vget_high_s8(v1_1l)); + const int16x8_t ph1l = vmull_s8(vget_low_s8(v0_1hs), vget_low_s8(v1_1h)); + const int16x8_t ph1h = vmull_s8(vget_high_s8(v0_1hs), vget_high_s8(v1_1h)); + + const int32x4_t pl0 = vaddq_s32(vpaddlq_s16(pl0l), vpaddlq_s16(pl0h)); + const int32x4_t ph0 = vaddq_s32(vpaddlq_s16(ph0l), vpaddlq_s16(ph0h)); + const int32x4_t pl1 = vaddq_s32(vpaddlq_s16(pl1l), vpaddlq_s16(pl1h)); + const int32x4_t ph1 = vaddq_s32(vpaddlq_s16(ph1l), vpaddlq_s16(ph1h)); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(pl0, ph0)), MLLM_FP16_TO_FP32(x0->d) * MLLM_FP16_TO_FP32(y0->d)); + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(pl1, ph1)), MLLM_FP16_TO_FP32(x1->d) * MLLM_FP16_TO_FP32(y1->d)); +#endif + } + + *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1); +} +#endif + +void vec_dot_q4_0_q8_0(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { +#ifdef __AVX2__ + vec_dot_q4_0_q8_0_avx(n, s, vx, vy); +#elif defined(__ARM_NEON) + vec_dot_q4_0_q8_0_arm(n, s, vx, vy); +#endif +} \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ4.hpp b/src/backends/cpu/third_party/ggml/VecDotQ4.hpp new file mode 100644 index 000000000..8d8558bd2 --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ4.hpp @@ -0,0 +1,82 @@ +/* + * This code is based on mllm(https://github.com/ggerganov/mllm), + * please see https://github.com/ggerganov/mllm/blob/master/src/mllm.c + * mllm is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once +#include "DataType.hpp" +#include "QuantizeFP16.hpp" +#include +#include + +inline void vec_mul_q4_0_q8_0(const int n, float *__restrict result_fp32, const void *__restrict q4_operand_ptr, const void *__restrict q8_operand_ptr) { + // QK4_0 和 QK8_0 在 ggml 中通常是 32,表示每个量化块的元素数量。 + // 确保维度 n 是块大小的倍数。 + assert(n % QK4_0 == 0); // Q4_0 block size + assert(n % QK8_0 == 0); // Q8_0 block size + + // 计算总的块数量 + const int num_blocks = n / QK4_0; // 假设 QK4_0 == QK8_0 或它们是兼容的块大小 + + const block_q4_0 *q4_blocks = static_cast(q4_operand_ptr); + const block_q8_0 *q8_blocks = static_cast(q8_operand_ptr); + + int current_fp32_idx = 0; // 用于跟踪 FP32 结果数组中的当前位置 + + for (int i = 0; i < num_blocks; ++i) { + // 获取当前 Q4_0 和 Q8_0 块的尺度因子 + const float d_q4 = MLLM_FP16_TO_FP32(q4_blocks[i].d); + const float d_q8 = MLLM_FP16_TO_FP32(q8_blocks[i].d); + const float combined_scale = d_q4 * d_q8; // 组合尺度 + + // 获取当前块的量化数据指针 + const uint8_t *qs_q4 = q4_blocks[i].qs; + const int8_t *qs_q8 = q8_blocks[i].qs; + + // 逐元素处理块内的量化数据 + // QK4_0 / 2 是因为 Q4_0 的每个 uint8_t 存储了两个 4-bit 元素(nibbles) + for (int j = 0; j < QK4_0 / 2; ++j) { + // 处理第一个 4-bit 元素 + // (value - 8) 是 Q4_0 的反量化零点调整 + const int q4_val_low_nibble = (qs_q4[j] & 0x0F) - 8; + // Q8_0 直接使用 8-bit 值 + const int q8_val_first_byte = qs_q8[j * 2]; + + // 逐元素相乘并乘以组合尺度,结果存入 FP32 数组 + result_fp32[current_fp32_idx + j] = (float)q4_val_low_nibble * (float)q8_val_first_byte * combined_scale; + + // 处理第二个 4-bit 元素 + const int q4_val_high_nibble = (qs_q4[j] >> 4) - 8; + const int q8_val_second_byte = qs_q8[j * 2 + 1]; + + result_fp32[current_fp32_idx + j + QK4_0 / 2] = (float)q4_val_high_nibble * (float)q8_val_second_byte * combined_scale; + } + // 更新 FP32 结果数组的索引,移动到下一个块的起始位置 + current_fp32_idx += QK4_0; + } +} + +void vec_dot_q4_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); +void vec_dot_q4_0_q8_0(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ6.cpp b/src/backends/cpu/third_party/ggml/VecDotQ6.cpp new file mode 100644 index 000000000..b14bf3e44 --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ6.cpp @@ -0,0 +1,682 @@ +/* + * This code is based on ggml(https://github.com/ggerganov/ggml), + * please see https://github.com/ggerganov/ggml/blob/master/src/ggml.c + * ggml is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "VecDotQ6.hpp" +#include "ComputeUtils.hpp" + +#if QK_K == 256 +void vec_dot_q6_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + assert(n % QK_K == 0); + + const block_q6_K *__restrict x = (block_q6_K *)vx; + const block_q8_K *__restrict y = (block_q8_K *)vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + float sum = 0; + + const uint8x16_t m4b = vdupq_n_u8(0xF); +#if defined(__ARM_FEATURE_DOTPROD) + const int32x4_t vzero = vdupq_n_s32(0); +#endif + // const int8x16_t m32s = vdupq_n_s8(32); + + const uint8x16_t mone = vdupq_n_u8(3); + + int8x16x4_t q6bytes; + uint8x16x4_t q6h; + + for (int i = 0; i < nb; ++i) { + const float d_all = MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *__restrict q6 = x[i].ql; + const uint8_t *__restrict qh = x[i].qh; + const int8_t *__restrict q8 = y[i].qs; + + const int8_t *__restrict scale = x[i].scales; + + const int16x8x2_t q8sums = vld1q_s16_x2(y[i].bsums); + const int8x16_t scales = vld1q_s8(scale); + const int16x8x2_t q6scales = {vmovl_s8(vget_low_s8(scales)), vmovl_s8(vget_high_s8(scales))}; + + const int32x4_t prod = vaddq_s32(vaddq_s32(vmull_s16(vget_low_s16(q8sums.val[0]), vget_low_s16(q6scales.val[0])), + vmull_s16(vget_high_s16(q8sums.val[0]), vget_high_s16(q6scales.val[0]))), + vaddq_s32(vmull_s16(vget_low_s16(q8sums.val[1]), vget_low_s16(q6scales.val[1])), + vmull_s16(vget_high_s16(q8sums.val[1]), vget_high_s16(q6scales.val[1])))); + int32_t isum_mins = vaddvq_s32(prod); + + int32_t isum = 0; + + for (int j = 0; j < QK_K / 128; ++j) { + uint8x16x2_t qhbits = vld1q_u8_x2(qh); + qh += 32; + uint8x16x4_t q6bits = vld1q_u8_x4(q6); + q6 += 64; + int8x16x4_t q8bytes = vld1q_s8_x4(q8); + q8 += 64; + + q6h.val[0] = vshlq_n_u8(vandq_u8(mone, qhbits.val[0]), 4); + q6h.val[1] = vshlq_n_u8(vandq_u8(mone, qhbits.val[1]), 4); + uint8x16_t shifted = vshrq_n_u8(qhbits.val[0], 2); + q6h.val[2] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits.val[1], 2); + q6h.val[3] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + + // q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])), m32s); + // q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])), m32s); + // q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[2], m4b), q6h.val[2])), m32s); + // q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[3], m4b), q6h.val[3])), m32s); + q6bytes.val[0] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])); + q6bytes.val[1] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])); + q6bytes.val[2] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[2], m4b), q6h.val[2])); + q6bytes.val[3] = vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[3], m4b), q6h.val[3])); + +#if defined(__ARM_FEATURE_DOTPROD) + + isum += vaddvq_s32(vdotq_s32(vzero, q6bytes.val[0], q8bytes.val[0])) * scale[0] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[1], q8bytes.val[1])) * scale[1] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[2], q8bytes.val[2])) * scale[2] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[3], q8bytes.val[3])) * scale[3]; + scale += 4; + +#else + + int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[0]), vget_low_s8(q8bytes.val[0])), + vmull_s8(vget_high_s8(q6bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[1]), vget_low_s8(q8bytes.val[1])), + vmull_s8(vget_high_s8(q6bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1]; + scale += 2; + + int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[2]), vget_low_s8(q8bytes.val[2])), + vmull_s8(vget_high_s8(q6bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[3]), vget_low_s8(q8bytes.val[3])), + vmull_s8(vget_high_s8(q6bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + isum += vaddvq_s16(p2) * scale[0] + vaddvq_s16(p3) * scale[1]; + scale += 2; +#endif + + q8bytes = vld1q_s8_x4(q8); + q8 += 64; + + shifted = vshrq_n_u8(qhbits.val[0], 4); + q6h.val[0] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits.val[1], 4); + q6h.val[1] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits.val[0], 6); + q6h.val[2] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits.val[1], 6); + q6h.val[3] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + + // q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[0])), m32s); + // q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[1])), m32s); + // q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[2], 4), q6h.val[2])), m32s); + // q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[3], 4), q6h.val[3])), m32s); + q6bytes.val[0] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[0])); + q6bytes.val[1] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[1])); + q6bytes.val[2] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[2], 4), q6h.val[2])); + q6bytes.val[3] = vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[3], 4), q6h.val[3])); + +#if defined(__ARM_FEATURE_DOTPROD) + + isum += vaddvq_s32(vdotq_s32(vzero, q6bytes.val[0], q8bytes.val[0])) * scale[0] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[1], q8bytes.val[1])) * scale[1] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[2], q8bytes.val[2])) * scale[2] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[3], q8bytes.val[3])) * scale[3]; + scale += 4; + + // for (int l = 0; l < 4; ++l) { + // const int32x4_t p = vdotq_s32(vzero, q6bytes.val[l], q8bytes.val[l]); + // isum += vaddvq_s32(p) * *scale++; + // } +#else + p0 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[0]), vget_low_s8(q8bytes.val[0])), + vmull_s8(vget_high_s8(q6bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + p1 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[1]), vget_low_s8(q8bytes.val[1])), + vmull_s8(vget_high_s8(q6bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1]; + scale += 2; + + p2 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[2]), vget_low_s8(q8bytes.val[2])), + vmull_s8(vget_high_s8(q6bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + p3 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[3]), vget_low_s8(q8bytes.val[3])), + vmull_s8(vget_high_s8(q6bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + isum += vaddvq_s16(p2) * scale[0] + vaddvq_s16(p3) * scale[1]; + scale += 2; +#endif + } + // sum += isum * d_all * y[i].d; + sum += d_all * y[i].d * (isum - 32 * isum_mins); + } + *s = sum; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + const __m256i m2 = _mm256_set1_epi8(3); + const __m256i m32s = _mm256_set1_epi8(32); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *__restrict q4 = x[i].ql; + const uint8_t *__restrict qh = x[i].qh; + const int8_t *__restrict q8 = y[i].qs; + + const __m128i scales = _mm_loadu_si128((const __m128i *)x[i].scales); + + __m256i sumi = _mm256_setzero_si256(); + + int is = 0; + + for (int j = 0; j < QK_K / 128; ++j) { + const __m128i scale_0 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 0)); + const __m128i scale_1 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 1)); + const __m128i scale_2 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 2)); + const __m128i scale_3 = _mm_shuffle_epi8(scales, get_scale_shuffle(is + 3)); + is += 4; + + const __m256i q4bits1 = _mm256_loadu_si256((const __m256i *)q4); + q4 += 32; + const __m256i q4bits2 = _mm256_loadu_si256((const __m256i *)q4); + q4 += 32; + const __m256i q4bitsH = _mm256_loadu_si256((const __m256i *)qh); + qh += 32; + + const __m256i q4h_0 = _mm256_slli_epi16(_mm256_and_si256(q4bitsH, m2), 4); + const __m256i q4h_1 = _mm256_slli_epi16(_mm256_and_si256(_mm256_srli_epi16(q4bitsH, 2), m2), 4); + const __m256i q4h_2 = _mm256_slli_epi16(_mm256_and_si256(_mm256_srli_epi16(q4bitsH, 4), m2), 4); + const __m256i q4h_3 = _mm256_slli_epi16(_mm256_and_si256(_mm256_srli_epi16(q4bitsH, 6), m2), 4); + + const __m256i q4_0 = _mm256_or_si256(_mm256_and_si256(q4bits1, m4), q4h_0); + const __m256i q4_1 = _mm256_or_si256(_mm256_and_si256(q4bits2, m4), q4h_1); + const __m256i q4_2 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits1, 4), m4), q4h_2); + const __m256i q4_3 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits2, 4), m4), q4h_3); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_2 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + const __m256i q8_3 = _mm256_loadu_si256((const __m256i *)q8); + q8 += 32; + + __m256i q8s_0 = _mm256_maddubs_epi16(m32s, q8_0); + __m256i q8s_1 = _mm256_maddubs_epi16(m32s, q8_1); + __m256i q8s_2 = _mm256_maddubs_epi16(m32s, q8_2); + __m256i q8s_3 = _mm256_maddubs_epi16(m32s, q8_3); + + __m256i p16_0 = _mm256_maddubs_epi16(q4_0, q8_0); + __m256i p16_1 = _mm256_maddubs_epi16(q4_1, q8_1); + __m256i p16_2 = _mm256_maddubs_epi16(q4_2, q8_2); + __m256i p16_3 = _mm256_maddubs_epi16(q4_3, q8_3); + + p16_0 = _mm256_sub_epi16(p16_0, q8s_0); + p16_1 = _mm256_sub_epi16(p16_1, q8s_1); + p16_2 = _mm256_sub_epi16(p16_2, q8s_2); + p16_3 = _mm256_sub_epi16(p16_3, q8s_3); + + p16_0 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_0), p16_0); + p16_1 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_1), p16_1); + p16_2 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_2), p16_2); + p16_3 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_3), p16_3); + + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_1)); + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_2, p16_3)); + } + + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); + } + +#if defined(_MSC_VER) || defined(__MINGW32__) + float arr[8]; + _mm256_storeu_ps(arr, acc); + + // for(float i : arr) { + // printf("%f ", i); + // } + // printf("\n"); +#endif + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + const __m128i m4 = _mm_set1_epi8(0xF); + const __m128i m3 = _mm_set1_epi8(3); + const __m128i m32s = _mm_set1_epi8(32); + const __m128i m2 = _mm_set1_epi8(2); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *__restrict q4 = x[i].ql; + const uint8_t *__restrict qh = x[i].qh; + const int8_t *__restrict q8 = y[i].qs; + + const __m128i scales = _mm_loadu_si128((const __m128i *)x[i].scales); + + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + __m128i shuffle = _mm_set_epi64x(0x0101010101010101, 0x0000000000000000); + for (int j = 0; j < QK_K / 128; ++j) { + const __m128i q4bitsH_0 = _mm_loadu_si128((const __m128i *)qh); + qh += 16; + const __m128i q4bitsH_1 = _mm_loadu_si128((const __m128i *)qh); + qh += 16; + + const __m128i q4h_0 = _mm_slli_epi16(_mm_and_si128(q4bitsH_0, m3), 4); + const __m128i q4h_1 = _mm_slli_epi16(_mm_and_si128(q4bitsH_1, m3), 4); + const __m128i q4h_2 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_0, 2), m3), 4); + const __m128i q4h_3 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_1, 2), m3), 4); + const __m128i q4h_4 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_0, 4), m3), 4); + const __m128i q4h_5 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_1, 4), m3), 4); + const __m128i q4h_6 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_0, 6), m3), 4); + const __m128i q4h_7 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH_1, 6), m3), 4); + + const __m128i q4bits1_0 = _mm_loadu_si128((const __m128i *)q4); + q4 += 16; + const __m128i q4bits1_1 = _mm_loadu_si128((const __m128i *)q4); + q4 += 16; + const __m128i q4bits2_0 = _mm_loadu_si128((const __m128i *)q4); + q4 += 16; + const __m128i q4bits2_1 = _mm_loadu_si128((const __m128i *)q4); + q4 += 16; + + const __m128i q4_0 = _mm_or_si128(_mm_and_si128(q4bits1_0, m4), q4h_0); + const __m128i q4_1 = _mm_or_si128(_mm_and_si128(q4bits1_1, m4), q4h_1); + const __m128i q4_2 = _mm_or_si128(_mm_and_si128(q4bits2_0, m4), q4h_2); + const __m128i q4_3 = _mm_or_si128(_mm_and_si128(q4bits2_1, m4), q4h_3); + const __m128i q4_4 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits1_0, 4), m4), q4h_4); + const __m128i q4_5 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits1_1, 4), m4), q4h_5); + const __m128i q4_6 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits2_0, 4), m4), q4h_6); + const __m128i q4_7 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(q4bits2_1, 4), m4), q4h_7); + + const __m128i q8_0 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_1 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_2 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_3 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_4 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_5 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_6 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + const __m128i q8_7 = _mm_loadu_si128((const __m128i *)q8); + q8 += 16; + + __m128i q8s_0 = _mm_maddubs_epi16(m32s, q8_0); + __m128i q8s_1 = _mm_maddubs_epi16(m32s, q8_1); + __m128i q8s_2 = _mm_maddubs_epi16(m32s, q8_2); + __m128i q8s_3 = _mm_maddubs_epi16(m32s, q8_3); + __m128i q8s_4 = _mm_maddubs_epi16(m32s, q8_4); + __m128i q8s_5 = _mm_maddubs_epi16(m32s, q8_5); + __m128i q8s_6 = _mm_maddubs_epi16(m32s, q8_6); + __m128i q8s_7 = _mm_maddubs_epi16(m32s, q8_7); + + __m128i p16_0 = _mm_maddubs_epi16(q4_0, q8_0); + __m128i p16_1 = _mm_maddubs_epi16(q4_1, q8_1); + __m128i p16_2 = _mm_maddubs_epi16(q4_2, q8_2); + __m128i p16_3 = _mm_maddubs_epi16(q4_3, q8_3); + __m128i p16_4 = _mm_maddubs_epi16(q4_4, q8_4); + __m128i p16_5 = _mm_maddubs_epi16(q4_5, q8_5); + __m128i p16_6 = _mm_maddubs_epi16(q4_6, q8_6); + __m128i p16_7 = _mm_maddubs_epi16(q4_7, q8_7); + + p16_0 = _mm_sub_epi16(p16_0, q8s_0); + p16_1 = _mm_sub_epi16(p16_1, q8s_1); + p16_2 = _mm_sub_epi16(p16_2, q8s_2); + p16_3 = _mm_sub_epi16(p16_3, q8s_3); + p16_4 = _mm_sub_epi16(p16_4, q8s_4); + p16_5 = _mm_sub_epi16(p16_5, q8s_5); + p16_6 = _mm_sub_epi16(p16_6, q8s_6); + p16_7 = _mm_sub_epi16(p16_7, q8s_7); + + const __m128i scale_0 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi8(shuffle, m2); + const __m128i scale_1 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi8(shuffle, m2); + const __m128i scale_2 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi8(shuffle, m2); + const __m128i scale_3 = _mm_shuffle_epi8(scales, shuffle); + shuffle = _mm_add_epi8(shuffle, m2); + + p16_0 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_0), p16_0); + p16_1 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_0, scale_0)), p16_1); + p16_2 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_1), p16_2); + p16_3 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_1, scale_1)), p16_3); + p16_4 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_2), p16_4); + p16_5 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_2, scale_2)), p16_5); + p16_6 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_3), p16_6); + p16_7 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_3, scale_3)), p16_7); + + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_1, p16_3)); + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_4, p16_6)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_5, p16_7)); + } + + __m256i sumi = MM256_SET_M128I(sumi_1, sumi_0); + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi)), acc); + } + + *s = hsum_float_8(acc); + +#else + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums[8]; + int32_t aux32[8]; + memset(sums, 0, 8 * sizeof(float)); + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t *__restrict q4 = x[i].ql; + const uint8_t *__restrict qh = x[i].qh; + const int8_t *__restrict q8 = y[i].qs; + memset(aux32, 0, 8 * sizeof(int32_t)); + int8_t *__restrict a = aux8; + for (int j = 0; j < QK_K; j += 128) { + for (int l = 0; l < 32; ++l) { + a[l + 0] = (int8_t)((q4[l + 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32; + a[l + 32] = (int8_t)((q4[l + 32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32; + a[l + 64] = (int8_t)((q4[l + 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32; + a[l + 96] = (int8_t)((q4[l + 32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32; + } + a += 128; + q4 += 64; + qh += 32; + } + a = aux8; + int is = 0; + for (int j = 0; j < QK_K / 16; ++j) { + int scale = x[i].scales[is++]; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; + a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; + a += 8; + } + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} + +#else + +void vec_dot_q6_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy) { + assert(n % QK_K == 0); + + const block_q6_K *__restrict x = (block_q6_K *)vx; + const block_q8_K *__restrict y = (block_q8_K *)vy; + + const int nb = n / QK_K; + +#ifdef __ARM_NEON + + float sum = 0; + + const uint8x16_t m4b = vdupq_n_u8(0xF); + const int8x16_t m32s = vdupq_n_s8(32); +#if defined(__ARM_FEATURE_DOTPROD) + const int32x4_t vzero = vdupq_n_s32(0); +#endif + + const uint8x16_t mone = vdupq_n_u8(3); + + int8x16x4_t q6bytes; + uint8x16x4_t q6h; + + for (int i = 0; i < nb; ++i) { + const float d_all = (float)x[i].d; + + const uint8_t *__restrict q6 = x[i].ql; + const uint8_t *__restrict qh = x[i].qh; + const int8_t *__restrict q8 = y[i].qs; + + const int8_t *__restrict scale = x[i].scales; + + int32_t isum = 0; + + uint8x16_t qhbits = vld1q_u8(qh); + uint8x16x2_t q6bits = vld1q_u8_x2(q6); + int8x16x4_t q8bytes = vld1q_s8_x4(q8); + + q6h.val[0] = vshlq_n_u8(vandq_u8(mone, qhbits), 4); + uint8x16_t shifted = vshrq_n_u8(qhbits, 2); + q6h.val[1] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits, 4); + q6h.val[2] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + shifted = vshrq_n_u8(qhbits, 6); + q6h.val[3] = vshlq_n_u8(vandq_u8(mone, shifted), 4); + + q6bytes.val[0] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[0], m4b), q6h.val[0])), m32s); + q6bytes.val[1] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vandq_u8(q6bits.val[1], m4b), q6h.val[1])), m32s); + q6bytes.val[2] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[0], 4), q6h.val[2])), m32s); + q6bytes.val[3] = vsubq_s8(vreinterpretq_s8_u8(vorrq_u8(vshrq_n_u8(q6bits.val[1], 4), q6h.val[3])), m32s); + +#if defined(__ARM_FEATURE_DOTPROD) + + isum += vaddvq_s32(vdotq_s32(vzero, q6bytes.val[0], q8bytes.val[0])) * scale[0] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[1], q8bytes.val[1])) * scale[1] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[2], q8bytes.val[2])) * scale[2] + vaddvq_s32(vdotq_s32(vzero, q6bytes.val[3], q8bytes.val[3])) * scale[3]; +#else + + int16x8_t p0 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[0]), vget_low_s8(q8bytes.val[0])), + vmull_s8(vget_high_s8(q6bytes.val[0]), vget_high_s8(q8bytes.val[0]))); + int16x8_t p1 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[1]), vget_low_s8(q8bytes.val[1])), + vmull_s8(vget_high_s8(q6bytes.val[1]), vget_high_s8(q8bytes.val[1]))); + isum += vaddvq_s16(p0) * scale[0] + vaddvq_s16(p1) * scale[1]; + + int16x8_t p2 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[2]), vget_low_s8(q8bytes.val[2])), + vmull_s8(vget_high_s8(q6bytes.val[2]), vget_high_s8(q8bytes.val[2]))); + int16x8_t p3 = vaddq_s16(vmull_s8(vget_low_s8(q6bytes.val[3]), vget_low_s8(q8bytes.val[3])), + vmull_s8(vget_high_s8(q6bytes.val[3]), vget_high_s8(q8bytes.val[3]))); + isum += vaddvq_s16(p2) * scale[2] + vaddvq_s16(p3) * scale[3]; +#endif + + sum += isum * d_all * y[i].d; + } + *s = sum; + +#elif defined __AVX2__ + + const __m256i m4 = _mm256_set1_epi8(0xF); + const __m256i m2 = _mm256_set1_epi8(3); + const __m256i m32s = _mm256_set1_epi8(32); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *__restrict q4 = x[i].ql; + const uint8_t *__restrict qh = x[i].qh; + const int8_t *__restrict q8 = y[i].qs; + + const __m64 scales_1 = _mm_set1_pi8(x[i].scales[0]); + const __m64 scales_2 = _mm_set1_pi8(x[i].scales[1]); + const __m64 scales_3 = _mm_set1_pi8(x[i].scales[2]); + const __m64 scales_4 = _mm_set1_pi8(x[i].scales[3]); + + __m256i sumi = _mm256_setzero_si256(); + + const __m128i scale_0 = _mm_set_epi64(scales_2, scales_1); + const __m128i scale_1 = _mm_set_epi64(scales_4, scales_3); + + const __m256i q4bits1 = _mm256_loadu_si256((const __m256i *)q4); + const __m128i q4bitsH = _mm_loadu_si128((const __m128i *)qh); + + const __m256i q4h_0 = _mm256_slli_epi16(_mm256_and_si256(MM256_SET_M128I(_mm_srli_epi16(q4bitsH, 2), q4bitsH), m2), 4); + const __m256i q4h_1 = _mm256_slli_epi16(_mm256_and_si256(MM256_SET_M128I(_mm_srli_epi16(q4bitsH, 6), _mm_srli_epi16(q4bitsH, 4)), m2), 4); + + const __m256i q4_0 = _mm256_or_si256(_mm256_and_si256(q4bits1, m4), q4h_0); + const __m256i q4_1 = _mm256_or_si256(_mm256_and_si256(_mm256_srli_epi16(q4bits1, 4), m4), q4h_1); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)(q8 + 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)(q8 + 32)); + + __m256i q8s_0 = _mm256_maddubs_epi16(m32s, q8_0); + __m256i q8s_1 = _mm256_maddubs_epi16(m32s, q8_1); + + __m256i p16_0 = _mm256_maddubs_epi16(q4_0, q8_0); + __m256i p16_1 = _mm256_maddubs_epi16(q4_1, q8_1); + + p16_0 = _mm256_sub_epi16(p16_0, q8s_0); + p16_1 = _mm256_sub_epi16(p16_1, q8s_1); + + p16_0 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_0), p16_0); + p16_1 = _mm256_madd_epi16(_mm256_cvtepi8_epi16(scale_1), p16_1); + + sumi = _mm256_add_epi32(sumi, _mm256_add_epi32(p16_0, p16_1)); + + acc = _mm256_fmadd_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(sumi), acc); + } + + *s = hsum_float_8(acc); + +#elif defined __AVX__ + + const __m128i m4 = _mm_set1_epi8(0xF); + const __m128i m2 = _mm_set1_epi8(3); + const __m128i m32s = _mm_set1_epi8(32); + + __m256 acc = _mm256_setzero_ps(); + + for (int i = 0; i < nb; ++i) { + const float d = y[i].d * MLLM_FP16_TO_FP32(x[i].d); + + const uint8_t *__restrict q4 = x[i].ql; + const uint8_t *__restrict qh = x[i].qh; + const int8_t *__restrict q8 = y[i].qs; + + const __m64 scales_1 = _mm_set1_pi8(x[i].scales[0]); + const __m64 scales_2 = _mm_set1_pi8(x[i].scales[1]); + const __m64 scales_3 = _mm_set1_pi8(x[i].scales[2]); + const __m64 scales_4 = _mm_set1_pi8(x[i].scales[3]); + + __m128i sumi_0 = _mm_setzero_si128(); + __m128i sumi_1 = _mm_setzero_si128(); + + const __m128i scale_0 = _mm_set_epi64(scales_2, scales_1); + const __m128i scale_1 = _mm_set_epi64(scales_4, scales_3); + + const __m256i q4bits1 = _mm256_loadu_si256((const __m256i *)q4); + const __m128i q4bitsH = _mm_loadu_si128((const __m128i *)qh); + + const __m128i q4h_0 = _mm_slli_epi16(_mm_and_si128(q4bitsH, m2), 4); + const __m128i q4h_1 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH, 2), m2), 4); + const __m128i q4h_2 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH, 4), m2), 4); + const __m128i q4h_3 = _mm_slli_epi16(_mm_and_si128(_mm_srli_epi16(q4bitsH, 6), m2), 4); + + const __m128i q4_0 = _mm_or_si128(_mm_and_si128(_mm256_extractf128_si256(q4bits1, 0), m4), q4h_0); + const __m128i q4_1 = _mm_or_si128(_mm_and_si128(_mm256_extractf128_si256(q4bits1, 1), m4), q4h_1); + const __m128i q4_2 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(_mm256_extractf128_si256(q4bits1, 0), 4), m4), q4h_2); + const __m128i q4_3 = _mm_or_si128(_mm_and_si128(_mm_srli_epi16(_mm256_extractf128_si256(q4bits1, 1), 4), m4), q4h_3); + + const __m256i q8_0 = _mm256_loadu_si256((const __m256i *)(q8 + 0)); + const __m256i q8_1 = _mm256_loadu_si256((const __m256i *)(q8 + 32)); + + __m128i q8s_0 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_0, 0)); + __m128i q8s_1 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_0, 1)); + __m128i q8s_2 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_1, 0)); + __m128i q8s_3 = _mm_maddubs_epi16(m32s, _mm256_extractf128_si256(q8_1, 1)); + + __m128i p16_0 = _mm_maddubs_epi16(q4_0, _mm256_extractf128_si256(q8_0, 0)); + __m128i p16_1 = _mm_maddubs_epi16(q4_1, _mm256_extractf128_si256(q8_0, 1)); + __m128i p16_2 = _mm_maddubs_epi16(q4_2, _mm256_extractf128_si256(q8_1, 0)); + __m128i p16_3 = _mm_maddubs_epi16(q4_3, _mm256_extractf128_si256(q8_1, 1)); + + p16_0 = _mm_sub_epi16(p16_0, q8s_0); + p16_1 = _mm_sub_epi16(p16_1, q8s_1); + p16_2 = _mm_sub_epi16(p16_2, q8s_2); + p16_3 = _mm_sub_epi16(p16_3, q8s_3); + + p16_0 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_0), p16_0); + p16_1 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_0, scale_0)), p16_1); + p16_2 = _mm_madd_epi16(_mm_cvtepi8_epi16(scale_1), p16_2); + p16_3 = _mm_madd_epi16(_mm_cvtepi8_epi16(_mm_unpackhi_epi64(scale_1, scale_1)), p16_3); + + sumi_0 = _mm_add_epi32(sumi_0, _mm_add_epi32(p16_0, p16_2)); + sumi_1 = _mm_add_epi32(sumi_1, _mm_add_epi32(p16_1, p16_3)); + + acc = _mm256_add_ps(_mm256_mul_ps(_mm256_broadcast_ss(&d), _mm256_cvtepi32_ps(MM256_SET_M128I(sumi_1, sumi_0))), acc); + } + + *s = hsum_float_8(acc); + +#else + + int8_t aux8[QK_K]; + int16_t aux16[8]; + float sums[8]; + int32_t aux32[8]; + memset(sums, 0, 8 * sizeof(float)); + + float sumf = 0; + for (int i = 0; i < nb; ++i) { + const uint8_t *__restrict q4 = x[i].ql; + const uint8_t *__restrict qh = x[i].qh; + const int8_t *__restrict q8 = y[i].qs; + memset(aux32, 0, 8 * sizeof(int32_t)); + int8_t *__restrict a = aux8; + for (int l = 0; l < 16; ++l) { + a[l + 0] = (int8_t)((q4[l + 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32; + a[l + 16] = (int8_t)((q4[l + 16] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32; + a[l + 32] = (int8_t)((q4[l + 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32; + a[l + 48] = (int8_t)((q4[l + 16] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32; + } + int is = 0; + for (int j = 0; j < QK_K / 16; ++j) { + int scale = x[i].scales[is++]; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; + a += 8; + for (int l = 0; l < 8; ++l) aux16[l] = q8[l] * a[l]; + for (int l = 0; l < 8; ++l) aux32[l] += scale * aux16[l]; + q8 += 8; + a += 8; + } + const float d = MLLM_FP16_TO_FP32(x[i].d) * y[i].d; + for (int l = 0; l < 8; ++l) sums[l] += d * aux32[l]; + } + for (int l = 0; l < 8; ++l) sumf += sums[l]; + *s = sumf; +#endif +} +#endif \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ6.hpp b/src/backends/cpu/third_party/ggml/VecDotQ6.hpp new file mode 100644 index 000000000..7a12c584c --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ6.hpp @@ -0,0 +1,31 @@ +/* + * This code is based on mllm(https://github.com/ggerganov/mllm), + * please see https://github.com/ggerganov/mllm/blob/master/src/mllm.c + * mllm is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once +#include + +void vec_dot_q6_K_q8_K(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy); \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ8.cpp b/src/backends/cpu/third_party/ggml/VecDotQ8.cpp new file mode 100644 index 000000000..b1f97690d --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ8.cpp @@ -0,0 +1,230 @@ +/* + * This code is based on ggml(https://github.com/ggerganov/ggml), + * please see https://github.com/ggerganov/ggml/blob/master/src/ggml.c + * ggml is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "VecDotQ8.hpp" +#include "ComputeUtils.hpp" + +void vec_dot_q8_0_q8_0(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy, size_t bs, size_t bx, size_t by) { + const int qk = QK8_0; + const int nb = n / qk; // number of blocks + + assert(n % qk == 0); + + const auto *__restrict x = static_cast(vx); + const auto *__restrict y = static_cast(vy); + +#if defined(__ARM_FEATURE_MATMUL_INT8) + // if (nrc == 2) + { + const block_q8_0 *__restrict vx0 = (const block_q8_0 *)vx; + const block_q8_0 *__restrict vx1 = (const block_q8_0 *)((const uint8_t *)vx + bx); + const block_q8_0 *__restrict vy0 = (const block_q8_0 *)vy; + const block_q8_0 *__restrict vy1 = (const block_q8_0 *)((const uint8_t *)vy + by); + + float32x4_t sumv0 = vdupq_n_f32(0.0f); + + for (int i = 0; i < nb; i++) { + const block_q8_0 *__restrict b_x0 = &vx0[i]; + const block_q8_0 *__restrict b_y0 = &vy0[i]; + + const block_q8_0 *__restrict b_x1 = &vx1[i]; + const block_q8_0 *__restrict b_y1 = &vy1[i]; + + const int8x16_t x0_l = vld1q_s8(b_x0->qs); + const int8x16_t x0_h = vld1q_s8(b_x0->qs + 16); + const int8x16_t x1_l = vld1q_s8(b_x1->qs); + const int8x16_t x1_h = vld1q_s8(b_x1->qs + 16); + + // load y + const int8x16_t y0_l = vld1q_s8(b_y0->qs); + const int8x16_t y0_h = vld1q_s8(b_y0->qs + 16); + const int8x16_t y1_l = vld1q_s8(b_y1->qs); + const int8x16_t y1_h = vld1q_s8(b_y1->qs + 16); + + float32_t _scale[4] = { + MLLM_FP16_TO_FP32(b_x0->d) * MLLM_FP16_TO_FP32(b_y0->d), + MLLM_FP16_TO_FP32(b_x0->d) * MLLM_FP16_TO_FP32(b_y1->d), + MLLM_FP16_TO_FP32(b_x1->d) * MLLM_FP16_TO_FP32(b_y0->d), + MLLM_FP16_TO_FP32(b_x1->d) * MLLM_FP16_TO_FP32(b_y1->d)}; + float32x4_t scale = vld1q_f32(_scale); + + int8x16_t l0 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(x0_l), vreinterpretq_s64_s8(x1_l))); + int8x16_t l1 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(x0_l), vreinterpretq_s64_s8(x1_l))); + + int8x16_t l2 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(x0_h), vreinterpretq_s64_s8(x1_h))); + int8x16_t l3 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(x0_h), vreinterpretq_s64_s8(x1_h))); + + int8x16_t r0 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(y0_l), vreinterpretq_s64_s8(y1_l))); + int8x16_t r1 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(y0_l), vreinterpretq_s64_s8(y1_l))); + + int8x16_t r2 = vreinterpretq_s8_s64(vzip1q_s64(vreinterpretq_s64_s8(y0_h), vreinterpretq_s64_s8(y1_h))); + int8x16_t r3 = vreinterpretq_s8_s64(vzip2q_s64(vreinterpretq_s64_s8(y0_h), vreinterpretq_s64_s8(y1_h))); + + sumv0 = vmlaq_f32(sumv0, (vcvtq_f32_s32(vmmlaq_s32((vmmlaq_s32((vmmlaq_s32((vmmlaq_s32(vdupq_n_s32(0), l0, r0)), l1, r1)), l2, r2)), l3, r3))), scale); + } + + float32x4_t sumv1 = vextq_f32(sumv0, sumv0, 2); + float32x4_t sumv2 = vzip1q_f32(sumv0, sumv1); + + vst1_f32(s, vget_low_f32(sumv2)); + vst1_f32(s + bs, vget_high_f32(sumv2)); + + return; + } +#elif defined(__ARM_NEON) + float32x4_t sumv0 = vdupq_n_f32(0.0f); + float32x4_t sumv1 = vdupq_n_f32(0.0f); + + assert(nb % 2 == 0); // TODO: handle odd nb + + for (int i = 0; i < nb; i += 2) { + const block_q8_0 *x0 = &x[i + 0]; + const block_q8_0 *x1 = &x[i + 1]; + const block_q8_0 *y0 = &y[i + 0]; + const block_q8_0 *y1 = &y[i + 1]; + + const int8x16_t x0_0 = vld1q_s8(x0->qs); + const int8x16_t x0_1 = vld1q_s8(x0->qs + 16); + const int8x16_t x1_0 = vld1q_s8(x1->qs); + const int8x16_t x1_1 = vld1q_s8(x1->qs + 16); + + // load y + const int8x16_t y0_0 = vld1q_s8(y0->qs); + const int8x16_t y0_1 = vld1q_s8(y0->qs + 16); + const int8x16_t y1_0 = vld1q_s8(y1->qs); + const int8x16_t y1_1 = vld1q_s8(y1->qs + 16); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(mllm_vdotq_s32(vdupq_n_s32(0), x0_0, y0_0), mllm_vdotq_s32(vdupq_n_s32(0), x0_1, y0_1))), MLLM_FP16_TO_FP32(x0->d) * MLLM_FP16_TO_FP32(y0->d)); + + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(mllm_vdotq_s32(vdupq_n_s32(0), x1_0, y1_0), mllm_vdotq_s32(vdupq_n_s32(0), x1_1, y1_1))), MLLM_FP16_TO_FP32(x1->d) * MLLM_FP16_TO_FP32(y1->d)); + } + + *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1); +#elif defined(__AVX2__) || defined(__AVX__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + + // Main loop + for (int i = 0; i < nb; ++i) { + // Compute combined scale for the block + const __m256 d = _mm256_set1_ps(MLLM_FP16_TO_FP32(x[i].d) * MLLM_FP16_TO_FP32(y[i].d)); + __m256i bx = _mm256_loadu_si256((const __m256i *)x[i].qs); + __m256i by = _mm256_loadu_si256((const __m256i *)y[i].qs); + + const __m256 q = mul_sum_i8_pairs_float(bx, by); + + // Multiply q with scale and accumulate +#if defined(__AVX2__) + acc = _mm256_fmadd_ps(d, q, acc); +#else + acc = _mm256_add_ps(_mm256_mul_ps(d, q), acc); +#endif + } + + *s = hsum_float_8(acc); +#endif +} + +void vec_dot_i8_i8(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy, float scale1, float scale2) { + const int qk = QK8_0; + const int nb = n / qk; + + const float scale = scale1 * scale2; + + assert(n % qk == 0); + + const block_q8_per_tensor *__restrict x = (block_q8_per_tensor *)vx; + const block_q8_per_tensor *__restrict y = (block_q8_per_tensor *)vy; + +#if defined(__ARM_NEON) + float32x4_t sumv0 = vdupq_n_f32(0.0f); + float32x4_t sumv1 = vdupq_n_f32(0.0f); + + assert(nb % 2 == 0); // TODO: handle odd nb + + for (int i = 0; i < nb; i += 2) { + const block_q8_per_tensor *__restrict x0 = &x[i + 0]; + const block_q8_per_tensor *__restrict x1 = &x[i + 1]; + const block_q8_per_tensor *__restrict y0 = &y[i + 0]; + const block_q8_per_tensor *__restrict y1 = &y[i + 1]; + + const int8x16_t x0_0 = vld1q_s8(x0->qs); + const int8x16_t x0_1 = vld1q_s8(x0->qs + 16); + const int8x16_t x1_0 = vld1q_s8(x1->qs); + const int8x16_t x1_1 = vld1q_s8(x1->qs + 16); + + // load y + const int8x16_t y0_0 = vld1q_s8(y0->qs); + const int8x16_t y0_1 = vld1q_s8(y0->qs + 16); + const int8x16_t y1_0 = vld1q_s8(y1->qs); + const int8x16_t y1_1 = vld1q_s8(y1->qs + 16); + + sumv0 = vmlaq_n_f32(sumv0, vcvtq_f32_s32(vaddq_s32(mllm_vdotq_s32(vdupq_n_s32(0), x0_0, y0_0), mllm_vdotq_s32(vdupq_n_s32(0), x0_1, y0_1))), scale); + + sumv1 = vmlaq_n_f32(sumv1, vcvtq_f32_s32(vaddq_s32(mllm_vdotq_s32(vdupq_n_s32(0), x1_0, y1_0), mllm_vdotq_s32(vdupq_n_s32(0), x1_1, y1_1))), scale); + } + + *s = vaddvq_f32(sumv0) + vaddvq_f32(sumv1); +#elif defined(__AVX2__) || defined(__AVX__) + // Initialize accumulator with zeros + __m256 acc = _mm256_setzero_ps(); + + // Main loop + for (int i = 0; i < nb; ++i) { + // Compute combined scale for the block + const __m256 d = _mm256_set1_ps(scale); + __m256i qx = _mm256_loadu_si256((const __m256i *)x[i].qs); + __m256i qy = _mm256_loadu_si256((const __m256i *)y[i].qs); + + const __m256 q = mul_sum_i8_pairs_float(qx, qy); + + // Multiply q with scale and accumulate +#if defined(__AVX2__) + acc = _mm256_fmadd_ps(d, q, acc); +#else + acc = _mm256_add_ps(_mm256_mul_ps(d, q), acc); +#endif + } + + *s = hsum_float_8(acc); +#else + // scalar + float sumf = 0.0; + + for (int i = 0; i < nb; i++) { + int sumi = 0; + + for (int j = 0; j < qk; j++) { + sumi += x[i].qs[j] * y[i].qs[j]; + } + + sumf += sumi * scale; + } + + *s = sumf; +#endif +} \ No newline at end of file diff --git a/src/backends/cpu/third_party/ggml/VecDotQ8.hpp b/src/backends/cpu/third_party/ggml/VecDotQ8.hpp new file mode 100644 index 000000000..d0f44c52c --- /dev/null +++ b/src/backends/cpu/third_party/ggml/VecDotQ8.hpp @@ -0,0 +1,33 @@ +/* + * This code is based on mllm(https://github.com/ggerganov/mllm), + * please see https://github.com/ggerganov/mllm/blob/master/src/mllm.c + * mllm is licensed under MIT Copyright (c) 2022 Georgi Gerganov: + * + * MIT License + * Copyright (c) 2022 Georgi Gerganov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once +#include + +void vec_dot_q8_0_q8_0(int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy, size_t bs = 0, size_t bx = 0, size_t by = 0); + +void vec_dot_i8_i8(const int n, float *__restrict s, const void *__restrict vx, const void *__restrict vy, float scale1 = 1, float scale2 = 1); \ No newline at end of file diff --git a/src/backends/cpu/compute/VecDotType.cpp b/src/backends/cpu/third_party/ggml/VecDotType.cpp similarity index 87% rename from src/backends/cpu/compute/VecDotType.cpp rename to src/backends/cpu/third_party/ggml/VecDotType.cpp index 9548be4bb..641767880 100644 --- a/src/backends/cpu/compute/VecDotType.cpp +++ b/src/backends/cpu/third_party/ggml/VecDotType.cpp @@ -31,7 +31,13 @@ #include "VecDotType.hpp" #include "Types.hpp" #include "Quantize.hpp" -#include "VecDot.hpp" +#include "VecDotFP32.hpp" +#include "VecDotFP16.hpp" +#include "VecDotQ2.hpp" +#include "VecDotQ3.hpp" +#include "VecDotQ4.hpp" +#include "VecDotQ6.hpp" +#include "VecDotQ8.hpp" #include "GemmPack.hpp" void fp32_add_row_to(int n, const float *MLLM_RESTRICT src, float *MLLM_RESTRICT dst, float alpha) { @@ -126,6 +132,7 @@ static inline void get_scale_min_k4(int j, const uint8_t *__restrict q, uint8_t #endif void q4_k_add_row_to(int n, const block_q4_K *MLLM_RESTRICT src, float *MLLM_RESTRICT dst, float alpha) { +#if QK_K == 256 assert(n % QK_K == 0); assert(QK_K == 256); // TODO: It is wired here for now const int nb = n / QK_K; @@ -158,6 +165,7 @@ void q4_k_add_row_to(int n, const block_q4_K *MLLM_RESTRICT src, float *MLLM_RES is += 2; } } +#endif } void q6_k_add_row_to(int n, const block_q6_K *MLLM_RESTRICT src, float *MLLM_RESTRICT dst, float alpha) { @@ -222,6 +230,23 @@ void q8_k_add_row_to(int n, const block_q8_K *MLLM_RESTRICT src, float *MLLM_RES } } +/*** + * This is the type traits for different data types used in MLLM. + * It defines the size, block size, conversion functions, vector dot product functions, + * and row addition functions for each data type. + * + * The `type_traits` array is indexed by the `mllm_type` enum values. + * Each entry in the array corresponds to a specific data type and contains + * the necessary information to handle that type. * The `to_float` and `from_float` functions are used to convert between + * the data type and float representation. + * The `vec_dot` function is used to compute the dot product of two vectors of the + * specified data type. + * The `add_row_to` function is used to add a row of the specified data type to a destination vector. + * The `vec_dot_type` field specifies the data type used for the dot product. + * The `size` field specifies the size of the data type in bytes. + * The `blck_size` field specifies the block size of the data type. + */ + type_traits_t type_traits[] = { /*[MLLM_TYPE_F32] = */ { .size = sizeof(float), @@ -311,8 +336,8 @@ type_traits_t type_traits[] = { .vec_dot_type = MLLM_TYPE_Q8_0, // .nrows = 1, // .ncols = 4, - .gemv = (mllm_gemv_func)mllm_gemv_q4_0_4x4_q8_0, - .gemm = (mllm_gemm_func)mllm_gemm_q4_0_4x4_q8_0, + .gemv = (gemv_func)gemv_q4_0_4x4_q8_0, + .gemm = (gemm_func)gemm_q4_0_4x4_q8_0, }, /*[MLLM_TYPE_Q4_0_4_8] = */ { .size = sizeof(block_q4_0), @@ -325,8 +350,8 @@ type_traits_t type_traits[] = { .vec_dot_type = MLLM_TYPE_Q8_0, // .nrows = 1, // .ncols = 4, - .gemv = (mllm_gemv_func)mllm_gemv_q4_0_4x8_q8_0, - .gemm = (mllm_gemm_func)mllm_gemm_q4_0_4x8_q8_0, + .gemv = (gemv_func)gemv_q4_0_4x8_q8_0, + .gemm = (gemm_func)gemm_q4_0_4x8_q8_0, }, /*[MLLM_TYPE_Q4_0_8_8] = */ { .size = sizeof(block_q4_0), @@ -339,8 +364,8 @@ type_traits_t type_traits[] = { .vec_dot_type = MLLM_TYPE_Q8_0, // .nrows = 1, // .ncols = 8, - .gemv = (mllm_gemv_func)mllm_gemv_q4_0_8x8_q8_0, - .gemm = (mllm_gemm_func)mllm_gemm_q4_0_8x8_q8_0, + .gemv = (gemv_func)gemv_q4_0_8x8_q8_0, + .gemm = (gemm_func)gemm_q4_0_8x8_q8_0, }, {}, /*MLLM_TYPE_Q3_K = */ { @@ -377,5 +402,16 @@ type_traits_t type_traits[] = { {}, {}, /*MLLM_TYPE_IQ2_S = */ {}, + /*MLLM_TYPE_KLEIDIAI_Q4_0 = */ {}, + /*MLLM_TYPE_Q8_0F = */ {}, + /*MLLM_TYPE_Q2_0 = */ { + .size = sizeof(block_q2_0), + .blck_size = QK_K, + .to_float = (mllm_to_float_func)dequantize_row_q2_0, + .from_float = (mllm_from_float_func)quantize_row_q2_0, + .vec_dot = (mllm_vec_dot_func)vec_dot_q2_0_q8_0, + .vec_dot_type = MLLM_TYPE_Q8_0, + .add_row_to = NULL, //(mllm_vec_add_row_func)q2_k_add_row_to, + }, // TODO: add support to more type }; diff --git a/src/backends/cpu/compute/VecDotType.hpp b/src/backends/cpu/third_party/ggml/VecDotType.hpp similarity index 86% rename from src/backends/cpu/compute/VecDotType.hpp rename to src/backends/cpu/third_party/ggml/VecDotType.hpp index 62757484a..e02ba6898 100644 --- a/src/backends/cpu/compute/VecDotType.hpp +++ b/src/backends/cpu/third_party/ggml/VecDotType.hpp @@ -36,10 +36,10 @@ typedef void (*mllm_from_float_func)(const float *src, void *dst, const int n); typedef void (*mllm_vec_dot_func)(const int n, float *MLLM_RESTRICT dst, const void *MLLM_RESTRICT x, const void *MLLM_RESTRICT y); typedef void (*mllm_from_float_to_mat_func)(const float *MLLM_RESTRICT x, void *MLLM_RESTRICT y, int64_t nr, int64_t k, int64_t bs); typedef void (*mllm_vec_add_row_func)(const int n, const void *MLLM_RESTRICT src, float *MLLM_RESTRICT dst, const float alpha); -typedef void (*mllm_gemv_func)(int n, float *MLLM_RESTRICT s, size_t bs, const void *MLLM_RESTRICT x, - const void *MLLM_RESTRICT y, int nr, int nc, const void *MLLM_RESTRICT bias); -typedef void (*mllm_gemm_func)(int n, float *MLLM_RESTRICT s, size_t bs, const void *MLLM_RESTRICT x, - const void *MLLM_RESTRICT y, int nr, int nc, const void *MLLM_RESTRICT bias); +typedef void (*gemv_func)(int n, float *MLLM_RESTRICT s, size_t bs, const void *MLLM_RESTRICT x, + const void *MLLM_RESTRICT y, int nr, int nc, const void *MLLM_RESTRICT bias); +typedef void (*gemm_func)(int n, float *MLLM_RESTRICT s, size_t bs, const void *MLLM_RESTRICT x, + const void *MLLM_RESTRICT y, int nr, int nc, const void *MLLM_RESTRICT bias); typedef struct type_traits_t { size_t size; // type size @@ -51,8 +51,8 @@ typedef struct type_traits_t { mllm_vec_dot_func vec_dot; DataType vec_dot_type; // vec_dot do dot product between two DataType, this is the other type mllm_vec_add_row_func add_row_to; // add alpha * row to a row of float - mllm_gemv_func gemv; - mllm_gemm_func gemm; + gemv_func gemv; + gemm_func gemm; } type_traits_t; extern type_traits_t type_traits[]; diff --git a/src/backends/qnn/QNNBackend.cpp b/src/backends/qnn/QNNBackend.cpp index b17e49532..27a614b20 100755 --- a/src/backends/qnn/QNNBackend.cpp +++ b/src/backends/qnn/QNNBackend.cpp @@ -933,7 +933,7 @@ StatusCode QNNBackend::retrieveQNNContext() { // std::vector> output_ptrs; // for (const auto &out_name : out_names) { // if (activation_tensors.find(out_name) == activation_tensors.end()) { -// Backend *backend_h = Backend::global_backends[MLLM_CPU]; +// Backend *backend_h = Backend::global_backends[MLLM_CPU].get(); // if (!input_tensors.empty()) { // backend_h = input_tensors[0].backend(); // } @@ -953,7 +953,7 @@ StatusCode QNNBackend::retrieveQNNContext() { // return results; // } -// Backend *backend_h = Backend::global_backends[MLLM_CPU]; +// Backend *backend_h = Backend::global_backends[MLLM_CPU].get(); // if (!input_tensors.empty()) { // backend_h = input_tensors[0].backend(); // } diff --git a/src/backends/qnn/op/QNNLinearINT8.cpp b/src/backends/qnn/op/QNNLinearINT8.cpp index 33b313f2a..1c8d43261 100755 --- a/src/backends/qnn/op/QNNLinearINT8.cpp +++ b/src/backends/qnn/op/QNNLinearINT8.cpp @@ -10,12 +10,12 @@ namespace mllm { QNNLinearINT8::QNNLinearINT8(Backend *bn, string opName, int in_features, int out_features, bool bias) : QNNCommonOp(bn, opName), in_features_(in_features), out_features_(out_features), support_bias_(bias) { - weight_.setBackend(Backend::global_backends[MLLM_CPU]); - bias_.setBackend(Backend::global_backends[MLLM_CPU]); + weight_.setBackend(Backend::global_backends[MLLM_CPU].get()); + bias_.setBackend(Backend::global_backends[MLLM_CPU].get()); - weightScale_.setBackend(Backend::global_backends[MLLM_CPU]); - biasScale_.setBackend(Backend::global_backends[MLLM_CPU]); - outputScale_.setBackend(Backend::global_backends[MLLM_CPU]); + weightScale_.setBackend(Backend::global_backends[MLLM_CPU].get()); + biasScale_.setBackend(Backend::global_backends[MLLM_CPU].get()); + outputScale_.setBackend(Backend::global_backends[MLLM_CPU].get()); } ErrorCode QNNLinearINT8::reshape(vector> inputs, vector> outputs) { @@ -203,7 +203,7 @@ ErrorCode QNNLinearINT8::setUpW8A8(vector> &inputs, vector> output_ptrs; // for (const auto &out_name : out_names) { // if (activation_tensors.find(out_name) == activation_tensors.end()) { -// Backend *backend_h = Backend::global_backends[MLLM_CPU]; +// Backend *backend_h = Backend::global_backends[MLLM_CPU].get(); // if (!input_tensors.empty()) { // backend_h = input_tensors[0].backend(); // } @@ -710,7 +710,7 @@ bool XnnpackBackend::enable_legacy_wrapper = false; // return results; // } -// Backend *backend_h = Backend::global_backends[MLLM_CPU]; +// Backend *backend_h = Backend::global_backends[MLLM_CPU].get(); // if (!input_tensors.empty()) { // backend_h = input_tensors[0].backend(); // } diff --git a/src/memory/MemoryPoolManager.hpp b/src/memory/MemoryPoolManager.hpp index 17d3a25a6..e44871f58 100644 --- a/src/memory/MemoryPoolManager.hpp +++ b/src/memory/MemoryPoolManager.hpp @@ -7,15 +7,18 @@ #include #include #include +#include namespace mllm { // 高性能临时内存池,仅服务 activation 分配,模型权重/KV Cache 请使用系统分配 class MemoryPoolManager : public MemoryManager { private: + std::vector raw_blocks_allocated_; struct Header { - void *raw_ptr; // 新增原始指针 - size_t size; + void *raw_ptr; // 系统分配时的原始指针 + size_t size; // 用户请求的大小 + size_t padding; // 为对齐产生的填充大小 bool is_sys; }; @@ -50,18 +53,19 @@ class MemoryPoolManager : public MemoryManager { uintptr_t base = reinterpret_cast(raw) + sizeof(Header); uintptr_t aligned = (base + alignment - 1) & ~(alignment - 1); Header *hdr = reinterpret_cast
(aligned - sizeof(Header)); - hdr->raw_ptr = raw; // 记录原始指针 + hdr->raw_ptr = raw; hdr->size = size; hdr->is_sys = true; + hdr->padding = 0; *ptr = reinterpret_cast(aligned); } void sys_free(void *ptr) { if (!ptr) return; uintptr_t user_ptr = reinterpret_cast(ptr); - Header *hdr = reinterpret_cast
(user_ptr - sizeof(Header)); // 找到Header + Header *hdr = reinterpret_cast
(user_ptr - sizeof(Header)); #if defined(_WIN32) - _aligned_free(hdr->raw_ptr); // 释放原始指针 + _aligned_free(hdr->raw_ptr); #else std::free(hdr->raw_ptr); #endif @@ -77,6 +81,7 @@ class MemoryPoolManager : public MemoryManager { posix_memalign(&raw, alignment_, alloc_size); #endif assert(raw); + raw_blocks_allocated_.push_back(raw); auto *blk = new Block{reinterpret_cast(raw), alloc_size, nullptr, free_head_}; if (free_head_) free_head_->prev = blk; free_head_ = blk; @@ -107,14 +112,19 @@ class MemoryPoolManager : public MemoryManager { else free_head_ = blk; if (cur) cur->prev = blk; + // 向前合并 if (blk->prev && blk->prev->addr + blk->prev->size == blk->addr) { - blk->prev->size += blk->size; - blk->prev->next = blk->next; - if (blk->next) blk->next->prev = blk->prev; + Block *prev_block = blk->prev; // 在delete之前,安全地缓存 prev 指针 + prev_block->size += blk->size; + prev_block->next = blk->next; + if (blk->next) { + blk->next->prev = prev_block; + } delete blk; - blk = blk->prev; + blk = prev_block; // 使用缓存的、安全的指针进行赋值 } + // 向后合并 if (blk->next && blk->addr + blk->size == blk->next->addr) { blk->size += blk->next->size; @@ -130,51 +140,62 @@ class MemoryPoolManager : public MemoryManager { pool_size_(0), alignment_(align) { expand(init); } - ~MemoryPoolManager() override { std::lock_guard lg(mutex_); + for (auto *b = free_head_; b;) { auto *next = b->next; + delete b; + b = next; + } + free_head_ = nullptr; + + for (void *raw_block : raw_blocks_allocated_) { #if defined(_WIN32) - _aligned_free(reinterpret_cast(b->addr)); + _aligned_free(raw_block); #else - std::free(reinterpret_cast(b->addr)); + std::free(raw_block); #endif - delete b; // 释放 Block 对象 - b = next; } + raw_blocks_allocated_.clear(); } void alloc(void **ptr, size_t size, size_t alignment) override { assert(size > 0); std::lock_guard lg(mutex_); - size_t req = size + sizeof(Header); - // 大块走系统 - if (req > pool_size_ * LARGE_RATIO) { + + size_t req_total = size + sizeof(Header); + + if (req_total > pool_size_ * LARGE_RATIO) { sys_alloc(ptr, size, alignment); return; } - // 小块服务,需要空间时线性扩容 - if (total_free() < req || total_free() < pool_size_ * POOL_THRESHOLD) { - expand(req); + if (total_free() < req_total || total_free() < pool_size_ * POOL_THRESHOLD) { + expand(req_total); } - // 首适应分配 + for (auto *b = free_head_; b; b = b->next) { uintptr_t start = b->addr; uintptr_t base = start + sizeof(Header); uintptr_t aligned = (base + alignment - 1) & ~(alignment - 1); + size_t padding = aligned - start - sizeof(Header); - if (b->size >= padding + req) { + size_t total_consumed = req_total + padding; + + if (b->size >= total_consumed) { uintptr_t user = aligned; auto *hdr = reinterpret_cast
(user - sizeof(Header)); + + hdr->raw_ptr = nullptr; hdr->size = size; hdr->is_sys = false; + hdr->padding = padding; + *ptr = reinterpret_cast(user); - // 更新块 - uintptr_t next = user + size; - size_t remain = b->size - (padding + req); + + size_t remain = b->size - total_consumed; if (remain > sizeof(Header)) { - b->addr = next; + b->addr = start + total_consumed; b->size = remain; } else { if (b->prev) @@ -187,16 +208,19 @@ class MemoryPoolManager : public MemoryManager { return; } } - // 再回退系统 sys_alloc(ptr, size, alignment); } void free(void *ptr) override { if (!ptr) return; std::lock_guard lg(mutex_); + auto *hdr = hdr_of(ptr); + if (!hdr->is_sys) { - insert_block(reinterpret_cast(hdr), hdr->size + sizeof(Header)); + uintptr_t block_start = reinterpret_cast(ptr) - sizeof(Header) - hdr->padding; + size_t block_size = hdr->size + sizeof(Header) + hdr->padding; + insert_block(block_start, block_size); } else { sys_free(ptr); } @@ -205,4 +229,4 @@ class MemoryPoolManager : public MemoryManager { } // namespace mllm -#endif // MLLM_MEMORY_POOL_H +#endif // MLLM_MEMORY_POOL_H \ No newline at end of file diff --git a/src/models/clip/processing_clip.hpp b/src/models/clip/processing_clip.hpp index 690f80f65..c738e94d5 100644 --- a/src/models/clip/processing_clip.hpp +++ b/src/models/clip/processing_clip.hpp @@ -29,7 +29,7 @@ class ClipProcessor : public PreProcessor { int channel = img.size(); int height = img[0].size(); int width = img[0][0].size(); - Tensor tensor1(1, height, channel, width, Backend::global_backends[type], true); + Tensor tensor1(1, height, channel, width, Backend::global_backends[type].get(), true); tensor1.setName(std::move(name)); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); diff --git a/src/models/dclm/modeling_dclm.hpp b/src/models/dclm/modeling_dclm.hpp index e1f52cfa9..efd7a90f4 100644 --- a/src/models/dclm/modeling_dclm.hpp +++ b/src/models/dclm/modeling_dclm.hpp @@ -74,8 +74,8 @@ class DCLMAttention final : public Module { k_norm = LayerNorm(cfg.n_heads * head_dim, false, cfg.norm_eps, base_name + "k_norm"); q_rope = RoPE(cfg.RoPE_type, 10000, cfg.seq_len, base_name + "q_rope"); k_rope = RoPE(cfg.RoPE_type, 10000, cfg.seq_len, base_name + "k_rope"); - k_cache = KVCache(cfg.n_heads, head_dim, 1, cfg.cache_limit, (cfg.attn_implementation == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(cfg.n_heads, head_dim, 1, cfg.cache_limit, (cfg.attn_implementation == "flash_attention_2"), base_name + "v_cache"); + k_cache = KVCache(cfg.n_heads, head_dim, 1, cfg.cache_limit, cfg.attn_implementation, base_name + "k_cache"); + v_cache = KVCache(cfg.n_heads, head_dim, 1, cfg.cache_limit, cfg.attn_implementation, base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } @@ -103,6 +103,8 @@ class DCLMAttention final : public Module { Tensor o; if (attn_implementation_ == "flash_attention_2") { o = Tensor::flash_attention2_forward(q, k, v, true); + } else if (attn_implementation_ == "sage_attention") { + o = Tensor::sage_attention_forward(q, k, v, true); } else { // eager implementation k = k.transpose(SEQUENCE, DIMENSION); auto qk = Tensor::mm(q, k); diff --git a/src/models/fuyu/processing_fuyu.hpp b/src/models/fuyu/processing_fuyu.hpp index eebc51a42..0b618ddf5 100644 --- a/src/models/fuyu/processing_fuyu.hpp +++ b/src/models/fuyu/processing_fuyu.hpp @@ -188,7 +188,7 @@ class FuyuProcessor final : public PreProcessor { seq = image_patches[0].size(); dims = image_patches[0][0].size(); } - Tensor tensor1(batch, 1, seq, dims, Backend::global_backends[type], true); + Tensor tensor1(batch, 1, seq, dims, Backend::global_backends[type].get(), true); tensor1.setName(name); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); @@ -209,7 +209,7 @@ class FuyuProcessor final : public PreProcessor { batch = image_patches_indices.size(); seq = image_patches_indices[0].size(); } - Tensor tensor1(batch, 1, seq, 1, Backend::global_backends[type], true); + Tensor tensor1(batch, 1, seq, 1, Backend::global_backends[type].get(), true); tensor1.setName(name); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); diff --git a/src/models/gemma2/modeling_gemma2.hpp b/src/models/gemma2/modeling_gemma2.hpp index 6f5042ab7..933bdb8bf 100644 --- a/src/models/gemma2/modeling_gemma2.hpp +++ b/src/models/gemma2/modeling_gemma2.hpp @@ -32,8 +32,8 @@ class Gemma2Attention final : public Module { base_name + "q_rope"); k_rope = RoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "v_cache"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, config.attn_implementation, base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, config.attn_implementation, base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } @@ -59,6 +59,8 @@ class Gemma2Attention final : public Module { Tensor atten_output; if (attn_impl == "flash_attention_2") { atten_output = Tensor::flash_attention2_forward(query_states, key_states, value_states, true); + } else if (attn_impl == "sage_attention") { + atten_output = Tensor::sage_attention_forward(query_states, key_states, value_states, true); } else { // eager implementation // attention weight auto atten_weight = diff --git a/src/models/imagebind/processing_imagebind.hpp b/src/models/imagebind/processing_imagebind.hpp index d2ba8bcc3..75b53e032 100644 --- a/src/models/imagebind/processing_imagebind.hpp +++ b/src/models/imagebind/processing_imagebind.hpp @@ -14,7 +14,7 @@ using namespace mllm; class ImagebindProcessor final : public ClipProcessor { static Tensor tokens2Input(vector> tokens, int max_pos, string name = "input", BackendType type = MLLM_CPU) { const auto bsize = static_cast(tokens.size()); - Tensor tensor1(bsize, 1, max_pos, 1, Backend::global_backends[type], true); + Tensor tensor1(bsize, 1, max_pos, 1, Backend::global_backends[type].get(), true); tensor1.setName(name); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); @@ -33,7 +33,7 @@ class ImagebindProcessor final : public ClipProcessor { int channel = imgs[0].size(); int height = imgs[0][0].size(); int width = imgs[0][0][0].size(); - Tensor tensor1(Backend::global_backends[type]); + Tensor tensor1(Backend::global_backends[type].get()); tensor1.reshape(imgs.size(), channel, 2, height, width); tensor1.setDtype(MLLM_TYPE_F32); tensor1.alloc(); @@ -65,7 +65,7 @@ class ImagebindProcessor final : public ClipProcessor { int height = audio_new[0].size(); int width = audio_new[0][0].size(); - Tensor tensor1(batch, height, channel, width, Backend::global_backends[type], true); + Tensor tensor1(batch, height, channel, width, Backend::global_backends[type].get(), true); tensor1.setName(std::move(name)); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); diff --git a/src/models/ling/configuration_bailing_moe.hpp b/src/models/ling/configuration_bailing_moe.hpp new file mode 100644 index 000000000..ecfb077a4 --- /dev/null +++ b/src/models/ling/configuration_bailing_moe.hpp @@ -0,0 +1,67 @@ +#pragma once +#include "models/transformer/configuration_transformer.hpp" + +using namespace mllm; + +class BailingMoeNameConfig : public TransformerNameConfig { +public: + std::string blk_name; + std::string token_embd_name; + std::string post_norm_name; + std::string lm_head_name; + std::string _gate_proj_name; + + void init() { + blk_name = "model.layers."; + _attn_base_name = "attention."; + _ffn_base_name = "mlp."; + _qkv_proj_name = "query_key_value"; + _o_proj_name = "dense"; + _gate_proj_name = "gate_proj"; + _up_proj_name = "up_proj"; + _down_proj_name = "down_proj"; + _attn_norm_name = "input_layernorm"; + _ffn_norm_name = "post_attention_layernorm"; + token_embd_name = "model.word_embeddings"; + post_norm_name = "model.norm"; + lm_head_name = "lm_head"; + } +}; + +struct BailingMoeConfig : public TransformerConfig { + explicit BailingMoeConfig(int token_limit) : + cache_limit(token_limit) { + names_config.init(); + } + + int num_experts = 64; // 64 + int num_experts_per_tok = 6; // 6` + int num_shared_experts = 2; // 2 + bool norm_topk_prob = true; // true + bool use_cache = true; // true + bool use_bias = false; // false + bool use_qkv_bias = false; // false + bool tie_word_embeddings = false; // false + + float attention_dropout = 0.0; + int bos_token_id = 1; + int eos_token_id = 126081; // 126081 + std::string hidden_act = "silu"; + int hidden_size = 2048; // 2048 + float initializer_range = 0.006; // 0.006 + int intermediate_size = 1408; // 1408 + int moe_intermediate_size = 1408; // 1408 + int max_position_embeddings = 32768; // 32768 + std::string model_type = "ling_moe"; // "ling_moe" + int num_attention_heads = 16; // 16 + int num_hidden_layers = 28; // 28 + int num_key_value_heads = 4; // 4 + double rms_norm_eps = 1e-06; // 1e-06 + float rope_theta = 600000.0; // 600000 + int vocab_size = 126464; // 126464 + int head_dim = hidden_size / num_attention_heads; //2048/16= 128 + + int cache_limit; + RoPEType RoPE_type = RoPEType::HFHUBROPE; + BailingMoeNameConfig names_config; +}; \ No newline at end of file diff --git a/src/models/ling/mbp/modeling_bailing_moe.hpp b/src/models/ling/mbp/modeling_bailing_moe.hpp new file mode 100644 index 000000000..74cae4fa3 --- /dev/null +++ b/src/models/ling/mbp/modeling_bailing_moe.hpp @@ -0,0 +1,492 @@ +#pragma once +#include "Layer.hpp" +#include "Module.hpp" +#include "Tensor.hpp" +#include "Trace.hpp" +#include "Types.hpp" +#include "../configuration_bailing_moe.hpp" +#include "settings_bailing_moe_mbp.hpp" +#include "models/transformer/modeling_transformer.hpp" +#include +#include +#include +#include +#include + +#define MBP_THREAD + +using namespace mllm; + +class BailingMoeMLP final : public Module { +public: + BailingMoeMLP() = default; + BailingMoeMLP(int hidden_size, int intermediate_size, const BailingMoeNameConfig &names, const std::string &base_name) { + gate_proj = Linear(hidden_size, intermediate_size, false, base_name + names._gate_proj_name); + silu = SiLU(base_name + "act"); + up_proj = Linear(hidden_size, intermediate_size, false, base_name + names._up_proj_name); + down_proj = Linear(intermediate_size, hidden_size, false, base_name + names._down_proj_name); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto x = gate_proj(inputs[0]); + x = silu(x); + auto y = up_proj(inputs[0]); // ERROR + x = x * y; + x = down_proj(x); + return {x}; + } + + void load() { + gate_proj.load(); + up_proj.load(); + down_proj.load(); + } + bool loaded() { + return gate_proj.loaded() && up_proj.loaded() && down_proj.loaded(); + } + void free() { + gate_proj.free(); + up_proj.free(); + down_proj.free(); + } + +private: + Layer gate_proj; + Layer up_proj; + Layer down_proj; + Layer silu; +}; + +class BailingMoeGate final : public Module { +public: + BailingMoeGate() = default; + BailingMoeGate(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const std::string &base_name) { + gate = Linear(config.hidden_size, config.num_experts, false, base_name + "gate"); + softmax = Softmax(DIMENSION, false, base_name + "softmax"); + num_experts_per_tok = config.num_experts_per_tok; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto scores = softmax(gate(inputs[0])); + auto experts_w_i = Tensor::topk(scores, num_experts_per_tok, DIMENSION); + auto topk_weight = experts_w_i[0]; // 1, batch*seq, 1, k + auto topk_idx = experts_w_i[1]; // 1, batch*seq, 1, k + topk_idx = topk_idx.view(-1, 1, 1, -1); // 1, 1, 1, k* batch*seq + topk_weight = topk_weight / topk_weight.sum(DIMENSION); // 1, batch*seq, 1, k + return {scores, topk_weight, topk_idx}; + } + +private: + Layer gate; + Softmax softmax; + int num_experts_per_tok{}; +}; + +class BailingMoeSparseMoeBlock final : public Module { +public: + BailingMoeSparseMoeBlock() = default; + BailingMoeSparseMoeBlock(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + experts = List(config.num_experts, config.hidden_size, config.moe_intermediate_size, names, base_name + "experts."); + gate = BailingMoeGate(config, names, base_name); + num_experts_per_tok = config.num_experts_per_tok; + num_shared_experts = config.num_shared_experts; + if (num_shared_experts > 0) { + shared_experts = BailingMoeMLP(config.hidden_size, + config.moe_intermediate_size * config.num_shared_experts, + names, base_name + "shared_experts."); + } + num_hidden_layers = config.num_hidden_layers; + } + // receive embeds + std::vector Forward(std::vector inputs, std::vector args) override { + int layer_idx = std::any_cast(args[0]); + auto hidden_states = inputs[0]; + auto identity = hidden_states; + if (hidden_states.batch() > 1) { + hidden_states = hidden_states.view(1, -1, ANYDIM, -1); // 1, batch*seq, 1, hidden + } + auto gates_t = gate({hidden_states}); // 1, batch*seq, 1, num_experts + auto scores = gates_t[0]; // 1, batch*seq, 1, num_experts + auto topk_weight = gates_t[1]; // 1, batch*seq, + auto topk_idx = gates_t[2]; // 1, batch*seq, 1, k + hidden_states = moe_infer(hidden_states, topk_weight, topk_idx, layer_idx); // 1, batch*seq, 1, hidden + if (num_shared_experts) { + hidden_states = hidden_states + shared_experts({identity})[0]; // add shared experts + } + if (hidden_states.batch() > 1) { + // expert_cache.view(ANYDIM, seq, -1, -1);//TODO + } + return {hidden_states}; + } + Tensor moe_infer(Tensor hidden_states, + Tensor &topk_weight, + Tensor &topk_idx, + int layer_idx) { + auto idxs = topk_idx.argsort(); // 1, 1, 1, k* batch*seq + auto tokens_per_expert = topk_idx.bincount(); // (1, 1, 1, 0) 1, 1, 1, k + auto token_idxs = idxs / num_experts_per_tok; // 1, 1, 1, k* batch*seq + int start_idx = 0; + int end_idx = start_idx; + auto expert_cache = Tensor::zero_like(hidden_states); // 1, batch*seq, 1, hidden + map exp_token_idx_list, exp_idx_list; + std::vector sorted_keys; // 根据 exp_token_idx_list[i].dimension() 对键值排序 + for (int i = 0; i < experts.size(); ++i) { + if (i >= tokens_per_expert.dimension()) break; // 全部专家计算完 + int this_token_num = tokens_per_expert.dimension() ? tokens_per_expert.d(0, 0, 0, i) : 0; + if (!this_token_num) continue; + end_idx = start_idx + this_token_num; + // + auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + topk_weight = topk_weight.view(-1, -1, 1, 1); + + exp_token_idx_list[i] = exp_token_idx; + sorted_keys.push_back(i); + exp_idx_list[i] = exp_idx; + start_idx = end_idx; + } + // std::sort(sorted_keys.begin(), sorted_keys.end(), [&](int a, int b) { + // return exp_token_idx_list[a].dimension() > exp_token_idx_list[b].dimension(); + // }); + if (!sorted_keys.empty()) { + int mv_i = 0; + if (std::find(sorted_keys.begin(), sorted_keys.end(), mv_i) != sorted_keys.end()) { + sorted_keys.erase(std::remove(sorted_keys.begin(), sorted_keys.end(), mv_i), sorted_keys.end()); + sorted_keys.insert(sorted_keys.begin(), mv_i); + } + + if (!experts[sorted_keys[0]].loaded()) { + double time_start = (mllm_time_us() - start_time) / 1000.0F; // ms + + experts[sorted_keys[0]].load(); + + string expert_name = std::to_string(layer_idx) + "_" + std::to_string(sorted_keys[0]); + double time_end = (mllm_time_us() - start_time) / 1000.0F; // ms + load_times[expert_name] = {time_start, time_end}; + // std::cout << "load: " << layer_idx << " " << sorted_keys[0] << std::endl; + } + + // std::cout << layer_idx << "_sorted_keys ["; + for (auto s : sorted_keys) { + // std::cout << s << " "; + } + // std::cout << "]" << std::endl; + } + for (int ii = 0; ii < sorted_keys.size(); ii++) { + int expert_id = sorted_keys[ii]; + if (exp_token_idx_list.find(expert_id) == exp_token_idx_list.end()) continue; // 退出 + if (Module::doLoad) continue; // 退出 + + // step.0 + if ((ii < sorted_keys.size() - 1 && exp_token_idx_list[sorted_keys[ii + 1]].dimension() > 0) + || (ii == sorted_keys.size() - 1 && layer_idx < num_hidden_layers - 1)) { +#ifdef MBP_THREAD + int q_layer_idx, q_expert_id; + if (ii == sorted_keys.size() - 1 && layer_idx < num_hidden_layers - 1) { + q_layer_idx = layer_idx + 1; + q_expert_id = 0; + } else { + q_layer_idx = layer_idx; + q_expert_id = sorted_keys[ii + 1]; + } + LoadRequest req{q_layer_idx, q_expert_id}; + { + lock_guard lk(queue_mutex); + load_requests.push(req); + // std::cout << "load_requests.push: " << q_layer_idx << " " << q_expert_id << std::endl; + } + queue_cv.notify_one(); // 通知加载线程 +#else + if (ii < sorted_keys.size() - 1 && exp_token_idx_list[sorted_keys[ii + 1]].dimension() > 0) { + auto time_start___ = (mllm_time_us()); // ms + double time_start = (time_start___ - start_time) / 1000.0F; // ms + + experts[sorted_keys[ii + 1]].load(); + + dones[layer_idx][sorted_keys[ii + 1]].store(true, std::memory_order_release); + string expert_name = std::to_string(layer_idx) + "_" + std::to_string(sorted_keys[ii + 1]); + + auto time_end__ = (mllm_time_us()); // ms + double time_end = (time_end__ - start_time) / 1000.0F; // ms + load_times[expert_name] = {time_start, time_end}; + double tt_t = (time_end__ - time_start___) / 1000.0F; + // std::cout << "load: " << layer_idx << " " << sorted_keys[ii + 1] << " " << tt_t << std::endl; + } +#endif + } +#if defined(MBP_THREAD) && defined(MBP_THREAD_PP) + } + for (int ii = 0; ii < sorted_keys.size(); ii++) { + int expert_id = sorted_keys[ii]; + if (exp_token_idx_list.find(expert_id) == exp_token_idx_list.end()) continue; // 退出 +#endif + + // step.1 + double time_start_ = (mllm_time_us() - start_time) / 1000.0F; // ms + + auto exp_token_idx = exp_token_idx_list[expert_id]; //(1, 1, 1, 0) 1, 1, 1, e-s + auto exp_idx = exp_idx_list[expert_id]; //(1, 1, 1, 0) 1, 1, 1, e-s + auto expert_tokens = hidden_states.clip(exp_token_idx, SEQUENCE); //(1, 0, 1, hidden) 1, e-s, 1, hidden + auto topk_weight_clip = topk_weight.clip(exp_idx, SEQUENCE); //(1, 0, 1, 1) 1, e-s, 1, 1 + + string expert_name_ = std::to_string(layer_idx) + "_" + std::to_string(expert_id); + double time_end_ = (mllm_time_us() - start_time) / 1000.0F; // ms + expert_clip_times[expert_name_] = {time_start_, time_end_}; + +#ifdef MBP_THREAD + // std::cout << "wait: " << layer_idx << " " << expert_id << std::endl; + double time_start_w = (mllm_time_us() - start_time) / 1000.0F; // ms + if (layer_idx + ii > 0 && !experts[expert_id].loaded()) { + // std::cout << "wait-: " << layer_idx << " " << expert_id << std::endl; + unique_lock lock(*mtxs[layer_idx][expert_id]); // 局部锁 + cvs[layer_idx][expert_id]->wait(lock, [&] { + return dones[layer_idx][expert_id].load(memory_order_acquire); + }); + assert(dones[layer_idx][expert_id]); + } + double time_end_w = (mllm_time_us() - start_time) / 1000.0F; // ms + expert_wait_times[expert_name_] = {time_start_w, time_end_w}; + // std::cout << "waited: " << layer_idx << " " << expert_id << std::endl; +#endif + auto time_start__ = (mllm_time_us()); // ms + double time_start = (time_start__ - start_time) / 1000.0F; // ms + + // step.2 + auto expert_out = experts[expert_id]({expert_tokens})[0]; //(1, 0, 1, hidden) 1, e-s, 1, + expert_out = expert_out * topk_weight_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden + expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden + experts[expert_id].free(); + // std::cout << "free: " << layer_idx << " " << expert_id << std::endl; + + string expert_name = std::to_string(layer_idx) + "_" + std::to_string(expert_id); + auto time_end__ = (mllm_time_us()); // ms + double time_end = (time_end__ - start_time) / 1000.0F; // ms + expert_cal_times[expert_name] = {time_start, time_end}; + // std::cout << "calc: " << layer_idx << " " << expert_id << " " << (time_end__ - time_start__) / (1000.0F * expert_tokens.sequence()) << std::endl; +#ifdef MBP_THREAD + // std::cout << "dones: " << layer_idx << " " << expert_id << std::endl; + dones[layer_idx][expert_id] = false; // 重置状态 +#endif + } + return expert_cache; // 1, batch*seq, 1, hidden + } + + void load_experts(int expert_idx) { + int result; + experts[expert_idx].load(); + } + +private: + BailingMoeMLP shared_experts; + std::vector experts; + BailingMoeGate gate; + int num_shared_experts{}; + int num_experts_per_tok{}; + int num_hidden_layers{}; +}; + +class BailingMoeDecoder final : public Module { +public: + BailingMoeDecoder() = default; + BailingMoeDecoder(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, + config.hidden_size / config.num_attention_heads, + SPLIT_HD, PostQkv_NONE, false, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, + config.cache_limit, config.use_cache, config.use_qkv_bias, config.use_bias, + config.attn_implementation, names, base_name + names._attn_base_name); + moe = BailingMoeSparseMoeBlock(config, names, base_name + names._ffn_base_name); + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); + num_hidden_layers = config.num_hidden_layers; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = input_layernorm(inputs[0]); + int layer_idx = std::any_cast(args[0]); + hidden_states = self_atten({hidden_states, hidden_states, hidden_states})[0]; + auto tmp = hidden_states + inputs[0]; + hidden_states = post_attention_layernorm(tmp); + hidden_states = moe({hidden_states}, layer_idx)[0]; + hidden_states = hidden_states + tmp; + return {hidden_states}; + } + + void load_experts(int expert_idx) { + moe.load_experts(expert_idx); + } + + MultiHeadAttention &get_attention() { + return self_atten; + } + +private: + MultiHeadAttention self_atten; + BailingMoeSparseMoeBlock moe; + Layer input_layernorm; + Layer post_attention_layernorm; + int num_hidden_layers; +}; + +class BailingMoeModel final : public Module { +public: + BailingMoeModel() = default; + BailingMoeModel(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + blocks = List(config.num_hidden_layers, config, names, base_name); + norm = RMSNorm(config.hidden_size, config.rms_norm_eps, names.post_norm_name); + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + int layer_idx = 0; + for (auto &block : blocks) { + hidden_states = block({hidden_states}, layer_idx)[0]; + layer_idx++; + } + hidden_states = norm(hidden_states); + return {hidden_states}; + } + + void load_experts(int layer_idx, int expert_idx) { + blocks[layer_idx].load_experts(expert_idx); + } + void clear_kvcache() override { + for (auto &block : blocks) { + auto kvcache = block.get_attention().get_cache(); + for (auto &cache : kvcache) { cache->clearCache(); } + auto ropes = block.get_attention().get_rope(); + for (auto &rope : ropes) { rope->clearCache(); } + } + } + +private: + std::vector blocks; + Layer norm; +}; + +class BailingMoeForCausalLM final : public Module { +public: + BailingMoeForCausalLM(BailingMoeConfig &config) { + auto names = config.names_config; + hidden_size = config.hidden_size; + embedding = Embedding(config.vocab_size, config.hidden_size, names.token_embd_name); + model = BailingMoeModel(config, names, names.blk_name); + lm_head = Linear(config.hidden_size, config.vocab_size, false, names.lm_head_name); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + std::vector outputs; + clearMBPtimes(); +#ifdef MBP_THREAD + start_time = mllm_time_us(); + mbp_finish.store(false, std::memory_order_relaxed); + if (inputs[0].dimension() == 1) { + // OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead. + // omp_set_nested(1); // 等价于设置环境变量 OMP_NESTED=TRUE + omp_set_max_active_levels(2); // Enable OpenMP nesting +#pragma omp parallel num_threads(2) + if (omp_get_thread_num() == 0) { // 根据线程ID决定执行哪个函数 +#if defined(__ARM_NEON) && !defined(__APPLE__) + { + struct sched_param param; + param.sched_priority = 20; // 范围 1–99,根据设备可酌情调整 + pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + } + // ─── 2. 绑定到大核(big cluster)以减少与小核的资源争用 ────────────── + { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + // 假设大核是 CPU 2–3,按实际设备改为合适的核号 + CPU_SET(2, &cpuset); + CPU_SET(3, &cpuset); + // CPU_SET(6, &cpuset); // 假设小核心是CPU 6 + sched_setaffinity(pthread_self(), sizeof(cpuset), &cpuset); + // sched_setaffinity(gettid(), sizeof(cpu_set_t), &cpuset); + } +#endif + mbp_load(); + } else { + outputs = do_Forward(inputs, args); + } + } else { +#endif + outputs = do_Forward(inputs, args); +#ifdef MBP_THREAD + } +#endif + return outputs; + } + void clear_kvcache() override { + model.clear_kvcache(); + } + + std::vector do_Forward(std::vector inputs, std::vector args) { + auto x = embedding(inputs[0]); + auto outputs = model({x})[0]; + if (outputs.sequence() > 1) { + outputs = outputs.clip({}, {}, {-1}, {}); + } + outputs = lm_head(outputs); + +#ifdef MBP_THREAD + // 设置 mbp_finish 为 true,结束 mbp_load 线程 + // 1. 设置内存序保证可见性 + mbp_finish.store(true, std::memory_order_release); // 改为 release 内存序 + // 2. 主动唤醒所有等待线程 + { + std::lock_guard lk(queue_mutex); + queue_cv.notify_all(); // 必须加锁后通知 + } + // 3. 添加二次状态检查(可选) + std::atomic_thread_fence(std::memory_order_seq_cst); + // std::cout << "do_Forward finish " << load_requests.size() << std::endl; +#endif + return {outputs}; + } + void load_experts(int layer_idx, int expert_idx) { + model.load_experts(layer_idx, expert_idx); + } + void mbp_load() { + while (!mbp_finish.load(std::memory_order_acquire)) { + std::unique_lock lk(queue_mutex); + queue_cv.wait(lk, [this] { + return !load_requests.empty() || mbp_finish.load(std::memory_order_acquire); + }); + + if (mbp_finish.load(std::memory_order_acquire)) { + break; + } + + while (!load_requests.empty()) { + auto req = load_requests.front(); + load_requests.pop(); + lk.unlock(); // 释放锁以便其他线程入队 + { // 执行加载 + std::unique_lock expert_lk(*mtxs[req.layer][req.expert]); + if (!dones[req.layer][req.expert].load(std::memory_order_acquire)) { + double time_start = (mllm_time_us() - start_time) / 1000.0F; // ms + + // std::cout << "load_requests.load_: " << req.layer << " " << req.expert << std::endl; + load_experts(req.layer, req.expert); + // std::cout << "load_requests.load_d: " << req.layer << " " << req.expert << std::endl; + dones[req.layer][req.expert].store(true, std::memory_order_release); + + string expert_name = std::to_string(req.layer) + "_" + std::to_string(req.expert); + double time_end = (mllm_time_us() - start_time) / 1000.0F; // ms + load_times[expert_name] = {time_start, time_end}; + } + } + cvs[req.layer][req.expert]->notify_all(); + lk.lock(); // 重新获取锁处理下一个请求 + } + } + // std::cout << "mbp_load finish" << std::endl; + } + +private: + int hidden_size; + bool tie_embedding_words; + Layer embedding; + Layer lm_head; + BailingMoeModel model; +}; diff --git a/src/models/ling/mbp/settings_bailing_moe_mbp.hpp b/src/models/ling/mbp/settings_bailing_moe_mbp.hpp new file mode 100644 index 000000000..4f9f7f86c --- /dev/null +++ b/src/models/ling/mbp/settings_bailing_moe_mbp.hpp @@ -0,0 +1,98 @@ +#ifndef MAP_MINICPMMOE_MBP_HPP +#define MAP_MINICPMMOE_MBP_HPP +// #include +// #include +#include +#include +// #include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +int mbp_load_layer_idx; +int mbp_load_expert_idx; + +struct LoadRequest { + int layer; + int expert; +}; + +queue load_requests; // 替换原do_mbp_load相关变量 +mutex queue_mutex; // 队列互斥锁 +condition_variable queue_cv; // 队列条件变量 +atomic mbp_finish{false}; // 改为原子布尔 + +vector>> mtxs; // 每个层和专家一个互斥锁 +vector>> cvs; // 每个层和专家一个条件变量 +vector>> dones; // 原子布尔保证可见性 + +// 修改 MAP_MINICPMMOE_MBP_HPP 中的相关部分 + +inline void reset_syntax_mbm(int layer_idx, int expert_idx) { + // 使用原子操作重置状态 + dones[layer_idx][expert_idx].store(false, std::memory_order_release); +} + +inline void minicpmmoe_mbp_init(int num_layers, int num_experts) { + mtxs.resize(num_layers); + cvs.resize(num_layers); + dones.resize(num_layers); + + for (int i = 0; i < num_layers; ++i) { + mtxs[i].resize(num_experts); + cvs[i].resize(num_experts); + dones[i] = std::vector>(num_experts); // Step 2: 显式构造 + + for (int j = 0; j < num_experts; ++j) { + mtxs[i][j] = make_unique(); + cvs[i][j] = make_unique(); + dones[i][j].store(false, std::memory_order_relaxed); // 显式原子初始化 + } + } +} + +map> load_times; +map> expert_cal_times; +map> expert_clip_times; +map> expert_wait_times; +uint64_t start_time; +void clearMBPtimes() { + load_times.clear(); + expert_cal_times.clear(); + expert_clip_times.clear(); + expert_wait_times.clear(); + start_time = 0; +} +void prinMBPtimes() { + double load_times_cal = 0; + cout << "load_times = [" << endl; + for (const auto &entry : load_times) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + load_times_cal += entry.second.second - entry.second.first; + } + cout << "]" << endl; + cout << "calc_times = [" << endl; + for (const auto &entry : expert_cal_times) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + cout << "]" << endl; + cout << "clip_times = [" << endl; + for (const auto &entry : expert_clip_times) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + cout << "]" << endl; + cout << "wait_times = [" << endl; + for (const auto &entry : expert_wait_times) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + cout << "]" << endl; + std::cout << "load_times_cal = " << load_times_cal << "ms" << endl; +} +#endif // MAP_MINICPMMOE_MBP_HPP \ No newline at end of file diff --git a/src/models/ling/modeling_bailing_moe.hpp b/src/models/ling/modeling_bailing_moe.hpp new file mode 100644 index 000000000..e4bdfce7b --- /dev/null +++ b/src/models/ling/modeling_bailing_moe.hpp @@ -0,0 +1,239 @@ +#pragma once +#include "Layer.hpp" +#include "Module.hpp" +#include "Tensor.hpp" +#include "Trace.hpp" +#include "Types.hpp" +#include "configuration_bailing_moe.hpp" +#include "models/transformer/modeling_transformer.hpp" +#include +#include +#include + +using namespace mllm; + +class BailingMoeMLP final : public Module { +public: + BailingMoeMLP() = default; + BailingMoeMLP(int hidden_size, int intermediate_size, const BailingMoeNameConfig &names, const std::string &base_name) { + gate_proj = Linear(hidden_size, intermediate_size, false, base_name + names._gate_proj_name); + silu = SiLU(base_name + "act"); + up_proj = Linear(hidden_size, intermediate_size, false, base_name + names._up_proj_name); + down_proj = Linear(intermediate_size, hidden_size, false, base_name + names._down_proj_name); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto x = gate_proj(inputs[0]); + x = silu(x); + auto y = up_proj(inputs[0]); // ERROR + x = x * y; + x = down_proj(x); + return {x}; + } + +private: + Layer gate_proj; + Layer up_proj; + Layer down_proj; + Layer silu; +}; + +class BailingMoeGate final : public Module { +public: + BailingMoeGate() = default; + BailingMoeGate(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const std::string &base_name) { + gate = Linear(config.hidden_size, config.num_experts, false, base_name + "gate"); + softmax = Softmax(DIMENSION, false, base_name + "softmax"); + num_experts_per_tok = config.num_experts_per_tok; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto scores = softmax(gate(inputs[0])); + auto experts_w_i = Tensor::topk(scores, num_experts_per_tok, DIMENSION); + auto topk_weight = experts_w_i[0]; // 1, batch*seq, 1, k + auto topk_idx = experts_w_i[1]; // 1, batch*seq, 1, k + topk_idx = topk_idx.view(-1, 1, 1, -1); // 1, 1, 1, k* batch*seq + topk_weight = topk_weight / topk_weight.sum(DIMENSION); // 1, batch*seq, 1, k + return {scores, topk_weight, topk_idx}; + } + +private: + Layer gate; + Softmax softmax; + int num_experts_per_tok{}; +}; + +class BailingMoeSparseMoeBlock final : public Module { +public: + BailingMoeSparseMoeBlock() = default; + BailingMoeSparseMoeBlock(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + experts = List(config.num_experts, config.hidden_size, config.moe_intermediate_size, names, base_name + "experts."); + gate = BailingMoeGate(config, names, base_name); + num_experts_per_tok = config.num_experts_per_tok; + num_shared_experts = config.num_shared_experts; + if (num_shared_experts > 0) { + shared_experts = BailingMoeMLP(config.hidden_size, + config.moe_intermediate_size * config.num_shared_experts, + names, base_name + "shared_experts."); + } + } + // receive embeds + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + auto identity = hidden_states; + if (hidden_states.batch() > 1) { + hidden_states = hidden_states.view(1, -1, ANYDIM, -1); // 1, batch*seq, 1, hidden + } + auto gates_t = gate({hidden_states}); // 1, batch*seq, 1, num_experts + auto scores = gates_t[0]; // 1, batch*seq, 1, num_experts + auto topk_weight = gates_t[1]; // 1, batch*seq, + auto topk_idx = gates_t[2]; // 1, batch*seq, 1, k + hidden_states = moe_infer(hidden_states, topk_weight, topk_idx); // 1, batch*seq, 1, hidden + if (num_shared_experts) { + hidden_states = hidden_states + shared_experts({identity})[0]; // add shared experts + } + if (hidden_states.batch() > 1) { + // expert_cache.view(ANYDIM, seq, -1, -1);//TODO + } + return {hidden_states}; + } + Tensor moe_infer(Tensor hidden_states, + Tensor &topk_weight, + Tensor &topk_idx) { + auto idxs = topk_idx.argsort(); // 1, 1, 1, k* batch*seq + auto tokens_per_expert = topk_idx.bincount(); // (1, 1, 1, 0) 1, 1, 1, k + auto token_idxs = idxs / num_experts_per_tok; // 1, 1, 1, k* batch*seq + int start_idx = 0; + int end_idx = start_idx; + auto expert_cache = Tensor::zero_like(hidden_states); // 1, batch*seq, 1, hidden + for (int i = 0; i < experts.size(); ++i) { + if (tokens_per_expert.dimension() != 0 && i >= tokens_per_expert.dimension()) + break; + int this_token_num = tokens_per_expert.dimension() == 0 ? + 0 : + tokens_per_expert.d(0, 0, 0, i); + if (tokens_per_expert.dimension() != 0 && this_token_num == 0) + continue; + end_idx = start_idx + this_token_num; + // + auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto expert_tokens = hidden_states.clip(exp_token_idx, SEQUENCE); //(1, 0, 1, hidden) 1, e-s, 1, hidden + auto expert_out = experts[i]({expert_tokens})[0]; //(1, 0, 1, hidden) 1, e-s, 1, + topk_weight = topk_weight.view(-1, -1, 1, 1); // 1, k* batch*seq, 1, 1 + auto expert_weights_clip = topk_weight.clip(exp_idx, SEQUENCE); //(1, 0, 1, 1) 1, e-s, 1, 1 + expert_out = expert_out * expert_weights_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden + expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden + // + start_idx = end_idx; + } + return expert_cache; // 1, batch*seq, 1, hidden + } + +private: + BailingMoeMLP shared_experts; + std::vector experts; + BailingMoeGate gate; + int num_shared_experts{}; + int num_experts_per_tok{}; +}; + +class BailingMoeDecoder final : public Module { +public: + BailingMoeDecoder() = default; + BailingMoeDecoder(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, + config.hidden_size / config.num_attention_heads, + SPLIT_HD, PostQkv_NONE, false, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, + config.cache_limit, config.use_cache, config.use_qkv_bias, config.use_bias, + config.attn_implementation, names, base_name + names._attn_base_name); + moe = BailingMoeSparseMoeBlock(config, names, base_name + names._ffn_base_name); + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); + num_hidden_layers = config.num_hidden_layers; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = input_layernorm(inputs[0]); + hidden_states = self_atten({hidden_states, hidden_states, hidden_states})[0]; + auto tmp = hidden_states + inputs[0]; + hidden_states = post_attention_layernorm(tmp); + hidden_states = moe({hidden_states})[0]; + hidden_states = hidden_states + tmp; + return {hidden_states}; + } + + MultiHeadAttention &get_attention() { + return self_atten; + } + +private: + MultiHeadAttention self_atten; + BailingMoeSparseMoeBlock moe; + Layer input_layernorm; + Layer post_attention_layernorm; + int num_hidden_layers; +}; + +class BailingMoeModel final : public Module { +public: + BailingMoeModel() = default; + BailingMoeModel(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + blocks = List(config.num_hidden_layers, config, names, base_name); + norm = RMSNorm(config.hidden_size, config.rms_norm_eps, names.post_norm_name); + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + for (auto &block : blocks) { + hidden_states = block({hidden_states})[0]; + } + hidden_states = norm(hidden_states); + return {hidden_states}; + } + + void clear_kvcache() override { + for (auto &block : blocks) { + auto kvcache = block.get_attention().get_cache(); + for (auto &cache : kvcache) { cache->clearCache(); } + auto ropes = block.get_attention().get_rope(); + for (auto &rope : ropes) { rope->clearCache(); } + } + } + +private: + std::vector blocks; + Layer norm; +}; + +class BailingMoeForCausalLM final : public Module { +public: + BailingMoeForCausalLM(BailingMoeConfig &config) { + auto names = config.names_config; + hidden_size = config.hidden_size; + embedding = Embedding(config.vocab_size, config.hidden_size, names.token_embd_name); + model = BailingMoeModel(config, names, names.blk_name); + lm_head = Linear(config.hidden_size, config.vocab_size, false, names.lm_head_name); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto x = embedding(inputs[0]); + auto outputs = model({x})[0]; + if (outputs.sequence() > 1) { + outputs = outputs.clip({}, {}, {-1}, {}); + } + outputs = lm_head(outputs); + return {outputs}; + } + void clear_kvcache() override { + model.clear_kvcache(); + } + +private: + int hidden_size; + bool tie_embedding_words; + Layer embedding; + Layer lm_head; + BailingMoeModel model; +}; diff --git a/src/models/ling/tokenizer_bailing.hpp b/src/models/ling/tokenizer_bailing.hpp new file mode 100644 index 000000000..5ed0cb5bc --- /dev/null +++ b/src/models/ling/tokenizer_bailing.hpp @@ -0,0 +1,194 @@ +#ifndef TOKENIZATION_BAILING_LITE_HPP +#define TOKENIZATION_BAILING_LITE_HPP + +#include "tokenizers/BPE/Bpe.hpp" +#include +#include +#include +#include +#include +#include +#include + +using namespace mllm; + +class BaiLingTokenizer final : public BPETokenizer { +public: + explicit BaiLingTokenizer(const std::string &vocab_file, const std::string &merge_file) : + BPETokenizer(vocab_file) { + initialize_byte_to_char_map(); + for (const auto &pair : byte_to_char_map_) { + char_to_byte_map_[pair.second] = pair.first; + } + id_to_token_string_.resize(vocab_map_.size() + 1); + for (const auto &pair : vocab_map_) { + if (pair.second < id_to_token_string_.size()) { + id_to_token_string_[pair.second] = pair.first; + } + } + auto merge_file_stream = std::ifstream(merge_file); + if (!merge_file_stream.good()) { + std::cout << "merge file is broken\n"; + exit(0); + } + std::string line; + unsigned rank = 0; + std::unordered_map bpe_ranks_; + std::getline(merge_file_stream, line); + while (std::getline(merge_file_stream, line)) { + if (line.empty() || line[0] == '#') { + continue; + } + bpe_ranks_[line] = rank; + rank++; + } + BPETokenizer::setMergeRank(bpe_ranks_); + chat_template_pre = "SYSTEMYou are Ling, an assistant created by inclusionAIHUMAN"; + chat_template_end = "ASSISTANT"; + + special_tokens_ = { + bos_token_string_, eos_token_string_, "[CLS]", "[gMASK]", + "", "", + "<|arithmetic_start|>", "<|arithmetic_end|>", + "<|number_start|>", "<|number_end|>"}; + for (int i = 0; i <= 100; ++i) { + special_tokens_.push_back("<|reserved_token_" + std::to_string(i) + "|>"); + } + special_tokens_.push_back("SYSTEM"); + special_tokens_.push_back("HUMAN"); + special_tokens_.push_back("BOT"); + } + + Tensor tokenize(const std::string &text, string name = "input_ids", BackendType type = MLLM_CPU) override { + std::vector tokens_id; + auto parts = _splitWithDelimiters(text, special_tokens_); + + for (const auto &part : parts) { + if (part.empty()) continue; + + auto it = vocab_map_.find(part); + if (it != vocab_map_.end()) { + tokens_id.push_back(it->second); + } else { + std::string byte_level_string; + for (unsigned char byte : part) { + byte_level_string += u32string_to_utf8({byte_to_char_map_[byte]}); + } + std::vector bpe_pieces = BPETokenizer::bpe(byte_level_string, ""); + for (const auto &piece : bpe_pieces) { + auto vocab_it = vocab_map_.find(piece); + if (vocab_it != vocab_map_.end()) { + tokens_id.push_back(vocab_it->second); + } else { + std::cerr << "Fatal Error: BPE piece not found in vocab_map_: " << piece << std::endl; + } + } + } + } + return Tokenizer::tokens2Input(tokens_id, name, type); + } + + std::string detokenize(const std::vector &tokens) override { + std::string byte_chars_str; + for (token_id_t token_id : tokens) { + if (token_id < id_to_token_string_.size()) { + byte_chars_str += id_to_token_string_[token_id]; + } + } + std::u32string u32_byte_chars_str = utf8_to_u32string(byte_chars_str); + std::vector byte_buffer; + for (char32_t c : u32_byte_chars_str) { + auto it = char_to_byte_map_.find(c); + if (it != char_to_byte_map_.end()) { + byte_buffer.push_back(static_cast(it->second)); + } + } + return std::string(byte_buffer.begin(), byte_buffer.end()); + } + + std::pair detokenize(Tensor &result) override { + assert(result.batch() == 1); + assert(result.head() == 1); + vector scores; + for (int i = 0; i < result.dimension(); ++i) { + scores.push_back(result.dataAt(0, 0, result.sequence() - 1, i)); + } + auto token_idx = this->argmax(scores); + return {this->detokenize({token_idx}), token_idx}; + } + + std::pair postprocess(std::string &text) override { + if (text == this->eos_token_string_) return {false, ""}; + if (text == "" || text.rfind("", 0) == 0) { + return {false, ""}; + } + if (text == this->bos_token_string_ || text == "" || text == "" || text.rfind("<|reserved_token_", 0) == 0 || text.rfind("", 0) == 0) return {true, ""}; + return {true, text}; + } + +private: + const std::string bos_token_string_ = "<|startoftext|>"; + const std::string eos_token_string_ = "<|endoftext|>"; + std::vector special_tokens_; + + std::unordered_map byte_to_char_map_; + std::unordered_map char_to_byte_map_; + std::vector id_to_token_string_; + + std::vector _splitWithDelimiters(const std::string &str, const std::vector &delimiters) const { + std::vector result; + size_t last = 0; + while (last < str.size()) { + size_t min_pos = std::string::npos; + std::string best_delim; + for (const auto &delim : delimiters) { + if (!delim.empty()) { + size_t found_pos = str.find(delim, last); + if (found_pos != std::string::npos && (min_pos == std::string::npos || found_pos < min_pos)) { + min_pos = found_pos; + best_delim = delim; + } + } + } + if (min_pos != std::string::npos) { + if (min_pos > last) result.push_back(str.substr(last, min_pos - last)); + result.push_back(best_delim); + last = min_pos + best_delim.length(); + } else { + result.push_back(str.substr(last)); + break; + } + } + return result; + } + + static std::u32string utf8_to_u32string(const std::string &s) { + try { + std::wstring_convert, char32_t> conv; + return conv.from_bytes(s); + } catch (const std::range_error &) { return {}; } + } + static std::string u32string_to_utf8(const std::u32string &s) { + try { + std::wstring_convert, char32_t> conv; + return conv.to_bytes(s); + } catch (const std::range_error &) { return ""; } + } + + void initialize_byte_to_char_map() { + std::vector chars; + for (int i = 0; i < 256; ++i) { chars.push_back(static_cast(i)); } + int n = 0; + for (int i = 0; i < 256; ++i) { + if (!((i >= 33 && i <= 126) || (i >= 161 && i <= 172) || (i >= 174 && i <= 255))) { + chars[i] = 256 + n; + n++; + } + } + for (int i = 0; i < 256; ++i) { + byte_to_char_map_[static_cast(i)] = chars[i]; + } + } +}; + +#endif // TOKENIZATION_BAILING_LITE_HPP \ No newline at end of file diff --git a/src/models/llama3/modeling_llama3.hpp b/src/models/llama3/modeling_llama3.hpp index 63eeb10b4..59e364fdf 100644 --- a/src/models/llama3/modeling_llama3.hpp +++ b/src/models/llama3/modeling_llama3.hpp @@ -75,8 +75,8 @@ class Llama3Attention final : public Module { // Initialize KV cache if (cache_limit > 0) { - k_cache = KVCache(kv_head_size, hidden_dim / head_size, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(kv_head_size, hidden_dim / head_size, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); + k_cache = KVCache(kv_head_size, hidden_dim / head_size, head_size / kv_head_size, cache_limit, attn_impl, base_name + "k_cache"); + v_cache = KVCache(kv_head_size, hidden_dim / head_size, head_size / kv_head_size, cache_limit, attn_impl, base_name + "v_cache"); } // Initialize softmax diff --git a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp index 9be253d34..217b90bef 100644 --- a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp +++ b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp @@ -14,6 +14,7 @@ // #include #include // #include +#include #include #include #include @@ -261,7 +262,7 @@ class MiniCPMMoE final : public Module { auto expert_weights_clip = expert_weights.clip(exp_idx, SEQUENCE); //(1, 0, 1, 1) 1, e-s, 1, 1 expert_out = expert_out * expert_weights_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden - expert_cache.scatter_reduce(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden + expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden start_idx = end_idx; } if (hidden_states.batch() > 1) { @@ -287,10 +288,10 @@ class MiniCPMDecoder final : public Module { MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, + config.hidden_size / config.num_attention_heads, SPLIT_NONE, PostQkv_NONE, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false,false, + true, false, false, config.attn_implementation, names, base_name + names._attn_base_name); moe = MiniCPMMoE(config, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); diff --git a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp index 0f808110c..65ad96e4f 100644 --- a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp +++ b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp @@ -12,6 +12,7 @@ #include #include // #include +#include #include #include // #include @@ -216,7 +217,7 @@ class MiniCPMMoE final : public Module { // step.2 auto expert_out = experts[expert_id]({expert_tokens})[0]; //(1, 0, 1, hidden) 1, e-s, 1, expert_out = expert_out * expert_weights_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden - expert_cache.scatter_reduce(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden + expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden experts[expert_id].free(); // std::cout << "free: " << layer_idx << " " << expert_id << std::endl; @@ -294,10 +295,10 @@ class MiniCPMDecoder final : public Module { MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, + config.hidden_size / config.num_attention_heads, SPLIT_NONE, PostQkv_NONE, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false,false, + true, false, false, config.attn_implementation, names, base_name + names._attn_base_name); moe = MiniCPMMoE(config, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); @@ -397,7 +398,7 @@ class MiniCPMForCausalLM final : public Module { omp_set_max_active_levels(2); // Enable OpenMP nesting #pragma omp parallel num_threads(2) if (omp_get_thread_num() == 0) { // 根据线程ID决定执行哪个函数 -#if defined(__ARM_NEON)&& !defined(__APPLE__) +#if defined(__ARM_NEON) && !defined(__APPLE__) { struct sched_param param; param.sched_priority = 20; // 范围 1–99,根据设备可酌情调整 diff --git a/src/models/minicpm_moe/modeling_minicpm_moe.hpp b/src/models/minicpm_moe/modeling_minicpm_moe.hpp index e65d494ec..bf47c4390 100644 --- a/src/models/minicpm_moe/modeling_minicpm_moe.hpp +++ b/src/models/minicpm_moe/modeling_minicpm_moe.hpp @@ -84,7 +84,7 @@ class MiniCPMMoE final : public Module { auto expert_out = experts[i]({expert_tokens})[0]; //(1, 0, 1, hidden) 1, e-s, 1, auto expert_weights_clip = expert_weights.clip(exp_idx, SEQUENCE); //(1, 0, 1, 1) 1, e-s, 1, 1 expert_out = expert_out * expert_weights_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden - expert_cache.scatter_reduce(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden + expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden // start_idx = end_idx; } @@ -108,10 +108,10 @@ class MiniCPMDecoder final : public Module { MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, + config.hidden_size / config.num_attention_heads, SPLIT_NONE, PostQkv_NONE, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false,false, + true, false, false, config.attn_implementation, names, base_name + names._attn_base_name); moe = MiniCPMMoE(config, names, base_name + names._ffn_base_name); input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); diff --git a/src/models/openelm/modeling_openelm.hpp b/src/models/openelm/modeling_openelm.hpp index 14904a7dd..12168fc76 100644 --- a/src/models/openelm/modeling_openelm.hpp +++ b/src/models/openelm/modeling_openelm.hpp @@ -72,8 +72,8 @@ class OpenELMMultiHeadCausalAttention final : public Module { out_proj = Linear(q_heads_ * head_dim_, cfg.model_dim, false, base_name + "out_proj"); - k_cache = KVCache(k_heads_, head_dim_, q_heads_ / k_heads_, cfg.cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(v_heads_, head_dim_, q_heads_ / v_heads_, cfg.cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); + k_cache = KVCache(k_heads_, head_dim_, q_heads_ / k_heads_, cfg.cache_limit, attn_impl, base_name + "k_cache"); + v_cache = KVCache(v_heads_, head_dim_, q_heads_ / v_heads_, cfg.cache_limit, attn_impl, base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } diff --git a/src/models/phi3v/processing_phi3v.hpp b/src/models/phi3v/processing_phi3v.hpp index 9e1bb6d02..bbcf2d024 100644 --- a/src/models/phi3v/processing_phi3v.hpp +++ b/src/models/phi3v/processing_phi3v.hpp @@ -162,7 +162,7 @@ class Phi3VImageProcessor { time_all = times; } } - Tensor tensor1(Backend::global_backends[type]); + Tensor tensor1(Backend::global_backends[type].get()); tensor1.reshape(batch_size, imgs[0].size(), time_all, 336, 336); tensor1.alloc(); memset(tensor1.hostPtr(), 0, tensor1.count() * sizeof(float)); @@ -222,7 +222,7 @@ class Phi3VImageProcessor { time_all = times; } } - Tensor tensor1(Backend::global_backends[type]); + Tensor tensor1(Backend::global_backends[type].get()); tensor1.reshape(batch_size * time_all, 336, imgs[0].size(), 336); tensor1.alloc(); memset(tensor1.hostPtr(), 0, tensor1.count() * sizeof(float)); @@ -344,7 +344,7 @@ class Phi3VProcessor final { //} : public PreProcessor { static Tensor tokens2Input(vector> tokens, string name = "input", BackendType type = MLLM_CPU) { const auto bsize = static_cast(tokens.size()); - Tensor tensor1(bsize, 1, static_cast(tokens[0].size()), 1, Backend::global_backends[type], true); + Tensor tensor1(bsize, 1, static_cast(tokens[0].size()), 1, Backend::global_backends[type].get(), true); tensor1.setName(name); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); diff --git a/src/models/phonelm/modeling_phonelm.hpp b/src/models/phonelm/modeling_phonelm.hpp index ccb719a73..8da748dd8 100644 --- a/src/models/phonelm/modeling_phonelm.hpp +++ b/src/models/phonelm/modeling_phonelm.hpp @@ -63,8 +63,8 @@ class PhoneLMAttention final : public Module { base_name + "q_rope"); k_rope = IRoPE(config.RoPE_type, config.rope_theta, config.max_position_embeddings, base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, attn_impl, base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, attn_impl, base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } diff --git a/src/models/qwen/modeling_qwen_sd.hpp b/src/models/qwen/modeling_qwen_sd.hpp index d4d15b30f..9a6b9698c 100644 --- a/src/models/qwen/modeling_qwen_sd.hpp +++ b/src/models/qwen/modeling_qwen_sd.hpp @@ -307,9 +307,9 @@ class QWenForCausalLM final : public Module { tree_ancestors.setName("tree_ancestors"); tree_ancestors.setDtype(MLLM_TYPE_I32); tp.is_decoding = false; - static_cast(Backend::global_backends[MLLM_CPU])->setUsingDraft(false); // prefill时不使用 - static_cast(Backend::global_backends[MLLM_CPU])->setLastDraftLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setLastVerifiedPositionIds({}); + static_cast(Backend::global_backends[MLLM_CPU].get())->setUsingDraft(false); // prefill时不使用 + static_cast(Backend::global_backends[MLLM_CPU].get())->setLastDraftLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setLastVerifiedPositionIds({}); unsigned int cur_seq_length = input_ids.sequence(); std::vector predicted_token_ids; @@ -354,10 +354,10 @@ class QWenForCausalLM final : public Module { post_processing_for_SD(new_token_ids, tree_anc, draft_len + 1, input_ids, tree_ancestors, {}); if (step == 0) { - static_cast(Backend::global_backends[MLLM_CPU])->setUsingDraft(true); + static_cast(Backend::global_backends[MLLM_CPU].get())->setUsingDraft(true); } - static_cast(Backend::global_backends[MLLM_CPU])->setLastDraftLength(tp.last_draft_length); - static_cast(Backend::global_backends[MLLM_CPU])->setLastVerifiedPositionIds(tp.last_accept_position_ids); + static_cast(Backend::global_backends[MLLM_CPU].get())->setLastDraftLength(tp.last_draft_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setLastVerifiedPositionIds(tp.last_accept_position_ids); } tp.reset(); sa.reset(); diff --git a/src/models/qwen2_vl/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/modeling_qwen2_vl.hpp index 01d71f05b..9d5b382df 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl.hpp @@ -237,8 +237,8 @@ class QWen2Attention final : public Module { o_proj = Linear(num_heads * head_dim, hidden_size, false, base_name + names._o_proj_name); q_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "q_rope"); k_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, (config.attn_implementation == "flash_attention_2"), base_name + "v_cache"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, config.attn_implementation, base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, config.attn_implementation, base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } @@ -258,6 +258,8 @@ class QWen2Attention final : public Module { Tensor atten_output; if (attn_impl == "flash_attention_2") { atten_output = Tensor::flash_attention2_forward(query_states, key_states, value_states, true); + } else if (attn_impl == "sage_attention") { + atten_output = Tensor::sage_attention_forward(query_states, key_states, value_states, true); } else { // eager implementation auto atten_weight = Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) @@ -440,8 +442,8 @@ class Qwen2VLModel final : public Module { } const size_t batch_size = input_ids.batch(); // input_ids.size(); const size_t seq_len = batch_size > 0 ? input_ids.sequence() : 0; // batch_size > 0 ? input_ids[0].size() : 0; - Tensor position_ids(3, 1, batch_size, seq_len, Backend::global_backends[MLLM_CPU], true); - Tensor mrope_position_deltas(1, 1, 1, batch_size, Backend::global_backends[MLLM_CPU], true); + Tensor position_ids(3, 1, batch_size, seq_len, Backend::global_backends[MLLM_CPU].get(), true); + Tensor mrope_position_deltas(1, 1, 1, batch_size, Backend::global_backends[MLLM_CPU].get(), true); bool has_vision = (image_grid_thw.sequence() > 0) || (video_grid_thw.sequence() > 0); // image_grid_thw || video_grid_thw; if (!has_vision) { // Pure text case diff --git a/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp b/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp index e5025d65c..9beffd6e6 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp @@ -686,8 +686,8 @@ class Qwen2VL_ImagePatchAndEmbedding final : public Module { // NOTE: changed from original const size_t seq_len = batch_size > 0 ? (padding_to > input_ids.sequence() ? padding_to : input_ids.sequence()) : 0; // batch_size > 0 ? input_ids[0].size() : 0; - Tensor position_ids(3, 1, batch_size, seq_len, Backend::global_backends[MLLM_CPU], true); - Tensor mrope_position_deltas(1, 1, 1, batch_size, Backend::global_backends[MLLM_CPU], true); + Tensor position_ids(3, 1, batch_size, seq_len, Backend::global_backends[MLLM_CPU].get(), true); + Tensor mrope_position_deltas(1, 1, 1, batch_size, Backend::global_backends[MLLM_CPU].get(), true); bool has_vision = (image_grid_thw.sequence() > 0) || (video_grid_thw.sequence() > 0); // image_grid_thw || video_grid_thw; if (!has_vision) { // Pure text case diff --git a/src/models/qwen2_vl/processing_qwen2_vl.hpp b/src/models/qwen2_vl/processing_qwen2_vl.hpp index bed3638be..398d22deb 100644 --- a/src/models/qwen2_vl/processing_qwen2_vl.hpp +++ b/src/models/qwen2_vl/processing_qwen2_vl.hpp @@ -31,7 +31,7 @@ Tensor vector3d2Tensor(vector>> img, string name = "input", int channel = img.size(); int height = img[0].size(); int width = img[0][0].size(); - Tensor tensor1(1, height, channel, width, Backend::global_backends[type], true); + Tensor tensor1(1, height, channel, width, Backend::global_backends[type].get(), true); tensor1.setName(std::move(name)); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); @@ -48,7 +48,7 @@ Tensor vector3d2Tensor(vector>> img, string name = "input", B int channel = img.size(); int height = img[0].size(); int width = img[0][0].size(); - Tensor tensor1(1, height, channel, width, Backend::global_backends[type], true); + Tensor tensor1(1, height, channel, width, Backend::global_backends[type].get(), true); tensor1.setName(std::move(name)); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); @@ -112,9 +112,7 @@ class Qwen2VLImageProcessor { int old_width = image.width; auto [new_height, new_width] = smart_resize(old_height, old_width, IMAGE_FACTOR, MIN_PIXELS, MAX_PIXELS); std::vector temp_image_info = {image}; - auto image_n = PreProcessor::ResizeImages({temp_image_info}, new_height, new_width, true)[0]; - // delete[] image.data; - // image.data = nullptr; + auto image_n = PreProcessor::ResizeImages({temp_image_info}, new_height, new_width, true, false, ResizeFitEdge::none, ResampleType::BICUBIC)[0]; return image_n; } @@ -429,9 +427,9 @@ class Qwen2VLProcessor final : public PreProcessor { } } - void Process(const std::string &text) override{}; - void PreProcessImages(const std::vector &images, const std::vector &image_length) override{}; - void PreProcessImages(const std::vector &images_path) override{}; + void Process(const std::string &text) override {}; + void PreProcessImages(const std::vector &images, const std::vector &image_length) override {}; + void PreProcessImages(const std::vector &images_path) override {}; std::string detokenize(const vector &tokens) { return tokenizer->detokenize(tokens); diff --git a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp index 9465838df..e65c5601d 100644 --- a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp @@ -544,8 +544,8 @@ class Qwen2VLModel final : public Module { } const size_t batch_size = input_ids.batch(); // input_ids.size(); const size_t seq_len = batch_size > 0 ? input_ids.sequence() : 0; // batch_size > 0 ? input_ids[0].size() : 0; - Tensor position_ids(3, 1, batch_size, seq_len, Backend::global_backends[MLLM_CPU], true); - Tensor mrope_position_deltas(1, 1, 1, batch_size, Backend::global_backends[MLLM_CPU], true); + Tensor position_ids(3, 1, batch_size, seq_len, Backend::global_backends[MLLM_CPU].get(), true); + Tensor mrope_position_deltas(1, 1, 1, batch_size, Backend::global_backends[MLLM_CPU].get(), true); bool has_vision = (image_grid_thw.sequence() > 0) || (video_grid_thw.sequence() > 0); // image_grid_thw || video_grid_thw; if (!has_vision) { // Pure text case diff --git a/src/models/qwen2_vl/vtp/processing_qwen2_vl.hpp b/src/models/qwen2_vl/vtp/processing_qwen2_vl.hpp index f8214b481..1d3bec083 100644 --- a/src/models/qwen2_vl/vtp/processing_qwen2_vl.hpp +++ b/src/models/qwen2_vl/vtp/processing_qwen2_vl.hpp @@ -218,7 +218,7 @@ Tensor vector3d2Tensor(vector>> img, string name = "input", int channel = img.size(); int height = img[0].size(); int width = img[0][0].size(); - Tensor tensor1(1, height, channel, width, Backend::global_backends[type], true); + Tensor tensor1(1, height, channel, width, Backend::global_backends[type].get(), true); tensor1.setName(std::move(name)); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); @@ -235,7 +235,7 @@ Tensor vector3d2Tensor(vector>> img, string name = "input", B int channel = img.size(); int height = img[0].size(); int width = img[0][0].size(); - Tensor tensor1(1, height, channel, width, Backend::global_backends[type], true); + Tensor tensor1(1, height, channel, width, Backend::global_backends[type].get(), true); tensor1.setName(std::move(name)); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); @@ -613,9 +613,9 @@ class Qwen2VLProcessor final : public PreProcessor { } } - void Process(const std::string &text) override{}; - void PreProcessImages(const std::vector &images, const std::vector &image_length) override{}; - void PreProcessImages(const std::vector &images_path) override{}; + void Process(const std::string &text) override {}; + void PreProcessImages(const std::vector &images, const std::vector &image_length) override {}; + void PreProcessImages(const std::vector &images_path) override {}; std::string detokenize(const vector &tokens) { return tokenizer->detokenize(tokens); diff --git a/src/models/stablelm/modeling_stablelm.hpp b/src/models/stablelm/modeling_stablelm.hpp index 0f9bf2f9b..a0c652a83 100644 --- a/src/models/stablelm/modeling_stablelm.hpp +++ b/src/models/stablelm/modeling_stablelm.hpp @@ -41,8 +41,8 @@ class StableLMMultiHeadAttention final : public Module { k_rope = RoPE(RoPE_type, 10000, 0.25, 4096, base_name + "k_rope"); } if (cache_limit > 0) { - k_cache = KVCache(kv_head_size, head_dim, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "k_cache"); - v_cache = KVCache(kv_head_size, head_dim, head_size / kv_head_size, cache_limit, (attn_impl == "flash_attention_2"), base_name + "v_cache"); + k_cache = KVCache(kv_head_size, head_dim, head_size / kv_head_size, cache_limit, attn_impl, base_name + "k_cache"); + v_cache = KVCache(kv_head_size, head_dim, head_size / kv_head_size, cache_limit, attn_impl, base_name + "v_cache"); } softmax = Softmax(DIMENSION, do_mask, base_name + "softmax"); o_proj = Linear(head_size * head_dim, hidden_dim, false, base_name + names._o_proj_name); diff --git a/src/models/tinyllama/modeling_tinyllama.hpp b/src/models/tinyllama/modeling_tinyllama.hpp index 6ee6e335b..eb7b7e0da 100644 --- a/src/models/tinyllama/modeling_tinyllama.hpp +++ b/src/models/tinyllama/modeling_tinyllama.hpp @@ -24,7 +24,7 @@ class TinyLLaMABlock final : public Module { attention = MultiHeadAttention(hidden_dim, head_size, kv_head_size, hidden_dim / head_size, SPLIT_NONE, PostQkv_NONE, false, RoPE_type, rope_theta, max_position_embeddings, - cache_limit, true, false, false, + cache_limit, true, false, false, attn_implementation, names, base_name + names._attn_base_name); mlp = LLaMAMLP(hidden_dim, ffn_hidden, names, base_name + names._ffn_base_name); norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); @@ -39,6 +39,9 @@ class TinyLLaMABlock final : public Module { x = x + tmp; return {x}; } + MultiHeadAttention &get_attention() { + return attention; + } }; class TinyLLaMAModel final : public Module { @@ -70,6 +73,14 @@ class TinyLLaMAModel final : public Module { x = lm_head(x); return {x}; } + void clear_kvcache() override { + for (auto &block : blocks) { + auto kvcache = block.get_attention().get_cache(); + for (auto &cache : kvcache) { cache->clearCache(); } + auto ropes = block.get_attention().get_rope(); + for (auto &rope : ropes) { rope->clearCache(); } + } + } }; #endif // MODELING_TINYLLAMA_HPP diff --git a/src/models/transformer/modeling_transformer.hpp b/src/models/transformer/modeling_transformer.hpp index a0ec1d9bb..ce186908f 100644 --- a/src/models/transformer/modeling_transformer.hpp +++ b/src/models/transformer/modeling_transformer.hpp @@ -19,7 +19,7 @@ struct MultiHeadAttentionConfig { int head_dim; AttnQKVSplitType do_qkv_proj = SPLIT_NONE; // Options: SPLIT_NONE, SPLIT_HD, SPLIT_D_HD AttnPostQkvNormType post_qkv_norm = PostQkv_NONE; - bool bias_kv_cat = false; // Only used when do_qkv_proj > 0 + bool bias_kv_cat = false; // Only used when do_qkv_proj > 0 RoPEType RoPE_type = RoPEType::NONE; // Options: NONE, ALIBI, ROPE, PERSIMMONROPE float rope_theta; int max_position_embeddings; @@ -51,18 +51,18 @@ class MultiHeadAttention final : public Module { Chl split_chl_{}; bool causal_mask = true; string attn_implementation_ = "flash_attention_2"; // Options: "flash_attention_2", "eager" - bool head_first_attn = false; // 是否是head-first的注意力排布实现 + bool head_first_attn = false; // 是否是head-first的注意力排布实现 public: MultiHeadAttention() = default; MultiHeadAttention(MultiHeadAttentionConfig config, const TransformerNameConfig &names, const string &base_name) { - MultiHeadAttention(config.hidden_dim, config.num_heads, - config.num_key_value_heads, config.head_dim, - config.do_qkv_proj, config.post_qkv_norm, config.bias_kv_cat, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, - config.cache_limit, config.is_causal, config.qkv_bias, config.o_bias, - config.attn_implementation, names, base_name); + MultiHeadAttention(config.hidden_dim, config.num_heads, + config.num_key_value_heads, config.head_dim, + config.do_qkv_proj, config.post_qkv_norm, config.bias_kv_cat, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, + config.cache_limit, config.is_causal, config.qkv_bias, config.o_bias, + config.attn_implementation, names, base_name); } MultiHeadAttention(int hidden_dim, int num_heads, int num_key_value_heads, int head_dim, AttnQKVSplitType do_qkv_proj, AttnPostQkvNormType post_qkv_norm, bool bias_kv_cat, @@ -76,8 +76,12 @@ class MultiHeadAttention final : public Module { causal_mask = is_causal; attn_implementation_ = attn_implementation; if (do_qkv_proj > 0) { - qkv_proj = Linear(hidden_dim, num_heads * head_dim * 3, qkv_bias, base_name + names._qkv_proj_name); split_chl_ = (Chl)do_qkv_proj; + if (do_qkv_proj == SPLIT_HD) { + qkv_proj = Linear(hidden_dim, (num_heads_ + num_key_value_heads_ + num_key_value_heads_) * head_dim, qkv_bias, base_name + names._qkv_proj_name); + } else { + qkv_proj = Linear(hidden_dim, num_heads * head_dim * 3, qkv_bias, base_name + names._qkv_proj_name); + } } else { q_proj = Linear(hidden_dim, num_heads * head_dim, qkv_bias, base_name + names._q_proj_name); k_proj = Linear(hidden_dim, num_key_value_heads * head_dim, qkv_bias, base_name + names._k_proj_name); @@ -86,7 +90,7 @@ class MultiHeadAttention final : public Module { if (post_qkv_norm == PostQkv_LayerNorm) { q_norm = LayerNorm(head_dim, true, 1e-6, base_name + names._q_norm_name); k_norm = LayerNorm(head_dim, true, 1e-6, base_name + names._k_norm_name); - }else if (post_qkv_norm == PostQkv_RMSNorm) { + } else if (post_qkv_norm == PostQkv_RMSNorm) { q_norm = RMSNorm(head_dim, 1e-6, base_name + names._q_norm_name); k_norm = RMSNorm(head_dim, 1e-6, base_name + names._k_norm_name); } @@ -97,10 +101,10 @@ class MultiHeadAttention final : public Module { if (cache_limit > 0) { k_cache = KVCache(num_key_value_heads, head_dim, num_heads / num_key_value_heads, cache_limit, - (attn_implementation_ == "flash_attention_2"), base_name + "k_cache"); + attn_implementation_, base_name + "k_cache"); v_cache = KVCache(num_key_value_heads, head_dim, num_heads / num_key_value_heads, cache_limit, - (attn_implementation_ == "flash_attention_2"), base_name + "v_cache"); + attn_implementation_, base_name + "v_cache"); } softmax = Softmax(DIMENSION, is_causal, base_name + "softmax"); o_proj = Linear(num_heads * head_dim, hidden_dim, o_bias, base_name + names._o_proj_name); @@ -113,10 +117,23 @@ class MultiHeadAttention final : public Module { Tensor q, k, v; if (qkv_proj.ready()) { auto qkv = qkv_proj(inputs[0]); - auto qkv_sp = qkv.split({head_dim_, head_dim_, head_dim_}, split_chl_, num_heads_); - q = qkv_sp[0]; - k = qkv_sp[1]; - v = qkv_sp[2]; + if (split_chl_ == HD) { + auto qkv_sp = qkv.split({head_dim_ * num_heads_, + head_dim_ * num_key_value_heads_, + head_dim_ * num_key_value_heads_}, + DIMENSION); + q = qkv_sp[0]; + k = qkv_sp[1]; + v = qkv_sp[2]; + q = q.view(-1, num_heads_, -1, head_dim_); + k = k.view(-1, num_key_value_heads_, -1, head_dim_); + v = v.view(-1, num_key_value_heads_, -1, head_dim_); + } else { + auto qkv_sp = qkv.split({head_dim_, head_dim_, head_dim_}, split_chl_, num_heads_); + q = qkv_sp[0]; + k = qkv_sp[1]; + v = qkv_sp[2]; + } } else { q = q_proj(inputs[0]); k = k_proj(inputs[1]); @@ -137,7 +154,7 @@ class MultiHeadAttention final : public Module { q = q_rope(q); k = k_rope(k); } - if(head_first_attn){ + if (head_first_attn) { q = q.transpose(HEAD, SEQUENCE); k = k.transpose(HEAD, SEQUENCE); v = v.transpose(HEAD, SEQUENCE); @@ -149,6 +166,8 @@ class MultiHeadAttention final : public Module { Tensor o; if (attn_implementation_ == "flash_attention_2") { o = Tensor::flash_attention2_forward(q, k, v, causal_mask); + } else if (attn_implementation_ == "sage_attention") { + o = Tensor::sage_attention_forward(q, k, v, causal_mask); } else { // eager implementation k = k.transpose(SEQUENCE, DIMENSION); auto qk = Tensor::mm(q, k); @@ -160,7 +179,7 @@ class MultiHeadAttention final : public Module { } o = Tensor::mm(qk, v); } - if(head_first_attn){ + if (head_first_attn) { o = o.transpose(HEAD, SEQUENCE); } o = o.view(-1, 1, -1, head_dim_ * num_heads_); diff --git a/src/models/vit/processing_vit.hpp b/src/models/vit/processing_vit.hpp index acf0d27f6..2ed67704b 100644 --- a/src/models/vit/processing_vit.hpp +++ b/src/models/vit/processing_vit.hpp @@ -16,7 +16,7 @@ using namespace mllm; class ViTProcessor final : public PreProcessor { Tensor img2Tensor(float *img, int height, int width, int channel, string name = "input", BackendType type = MLLM_CPU) { - Tensor tensor1(1, height, channel, width, Backend::global_backends[type], true); + Tensor tensor1(1, height, channel, width, Backend::global_backends[type].get(), true); tensor1.setName(std::move(name)); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); @@ -78,8 +78,8 @@ class ViTProcessor final : public PreProcessor { return token_idx; } - void PreProcessImages(const std::vector &images, const std::vector &image_length) override{}; - void Process(const std::string &text) override{}; + void PreProcessImages(const std::vector &images, const std::vector &image_length) override {}; + void Process(const std::string &text) override {}; }; #endif // TOKENIZATION_VIT_HPP diff --git a/src/processor/AudioProcess.cpp b/src/processor/AudioProcess.cpp index 9d1619cc2..520948a07 100644 --- a/src/processor/AudioProcess.cpp +++ b/src/processor/AudioProcess.cpp @@ -13,7 +13,7 @@ #include "wenet_audio/params.h" #include "wenet_audio/wav.h" #include "wenet_audio/feature_pipeline.h" -#include "backends/cpu/compute/VecDot.hpp" +#include "backends/cpu/third_party/ggml/VecDotFP32.hpp" class Fraction { public: diff --git a/src/processor/FuyuPreProcess.cpp b/src/processor/FuyuPreProcess.cpp index a99b52e07..ddae928dc 100644 --- a/src/processor/FuyuPreProcess.cpp +++ b/src/processor/FuyuPreProcess.cpp @@ -263,7 +263,7 @@ Tensor FuyuPreProcess::vector3d2Tensor(vector>> image_patch seq = image_patches[0].size(); dims = image_patches[0][0].size(); } - Tensor tensor1(batch, 1, seq, dims, Backend::global_backends[type], true); + Tensor tensor1(batch, 1, seq, dims, Backend::global_backends[type].get(), true); tensor1.setName(name); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); @@ -284,7 +284,7 @@ Tensor FuyuPreProcess::vector2d2Tensor(vector> image_patches_indices batch = image_patches_indices.size(); seq = image_patches_indices[0].size(); } - Tensor tensor1(batch, 1, seq, 1, Backend::global_backends[type], true); + Tensor tensor1(batch, 1, seq, 1, Backend::global_backends[type].get(), true); tensor1.setName(name); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); diff --git a/src/quantizer/ParamWriter.cpp b/src/quantizer/ParamWriter.cpp deleted file mode 100644 index 246281ee2..000000000 --- a/src/quantizer/ParamWriter.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// Created by Xiang Li on 23-10-30. -// - -#include "ParamWriter.hpp" -#include - -ParamWriter::ParamWriter(std::string filename) : - path_(std::move(filename)) { - fp_ = fopen(path_.c_str(), "wb"); - writeInt(fp_, _MAGIC_NUMBER); -} -ParamWriter::~ParamWriter() { - if (fp_ != nullptr) - fclose(fp_); -} -int ParamWriter::calcIndexSize(const vector names) { - int size = 0; - for (const auto &name : names) { - // One Tensor Index Item Contains: Name_Len(Int)+Name(str)+Weights_Len(UInt64)+Offset(UInt64)+DataType(Int) - size += sizeof(int) + name.size() + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(int); - } - return size; -} -void ParamWriter::writeIndex() { - fseek(fp_, sizeof(int32_t) + sizeof(uint64_t), SEEK_SET); - for (const auto ¶m : param_info_) { - writeString(fp_, param.name); - write_u64(fp_, param.size); - write_u64(fp_, param.offset); - writeInt(fp_, param.type); - // std::cout<<"write param "< names) { - param_info_.resize(names.size()); - // write 0 padding to preserve space for index - int index_size = calcIndexSize(names); - write_u64(fp_, index_size); - char i[index_size]; - fwrite(&i, sizeof(char), index_size, fp_); -} diff --git a/src/quantizer/QuantWriter.cpp b/src/quantizer/QuantWriter.cpp deleted file mode 100644 index 13b839d27..000000000 --- a/src/quantizer/QuantWriter.cpp +++ /dev/null @@ -1,641 +0,0 @@ -#include "ParamWriter.hpp" -#include "ParamLoader.hpp" -#include "Types.hpp" -#include -#include "QuantWriter.hpp" -namespace mllm { -QuantWriter::QuantWriter(std::string output_path, std::string input_path) : - ParamWriter(output_path), output_path_(output_path) { - param_loader_ = new mllm::ParamLoader(std::move(input_path)); - if (param_loader_ == nullptr) { - __exit(-1); - } -} -QuantWriter::~QuantWriter() { -#ifdef TEST - for (auto &item : data_) { - delete[] item.second; - } -#endif -}; -int QuantWriter::readParams() { - param_names_ = param_loader_->getParamNames(); - paddingIndex(param_names_); - return param_names_.size(); -} -float *QuantWriter::getParam(std::string param_name) { - auto type = param_loader_->data_type_[param_name]; - if (type != DataType::MLLM_TYPE_F32) { - return nullptr; - } - auto [data, size] = param_loader_->load(param_name); - return static_cast((void *)data); -} -bool find_names(const string &name, const vector &layer_names) { - if ("vision_embed_tokens" == name) { // for FUYU - return true; - } - for (const auto &layer : layer_names) { - if (name.find(layer) != std::string::npos) { - return true; - } - } - return false; -} - -vector fp32_layers = { - "norm", - "rope", - "bias", - "rotary_emb", - "embed_tokens", - "_GN", - "class_embedding", - // "vision_embed_tokens", - "embeddings", - "logit_scale", - //"tok_embeddings", - "modality_preprocessors", - "modality_heads", - "modality_postprocessors", - "pre_transformer_layer", - "pos_embed.inv_freq", - "ln_q", - "patch_embed.proj", - "lm_head.weight", - // MoE - "mlp.gate.", -}; -vector q6_layers = { - "w2", - "wv", - "dense_h_to_4h", - "v_proj", - "down_proj", -}; -vector q2k_layers = { - // "mlp.experts", -}; - -vector q3k_layers = { - // "mlp.experts", -}; - -int tmp_hidden_dim = -1; -void QuantWriter::quantParams(DataType dataType) { - quant_type_ = dataType; - for (const auto &name : param_names_) { - // int force_quant_type = -1; - auto *param = getParam(name); - if (param == nullptr) { - __exit(-1); - } - auto size = param_loader_->offsets_[name].second / sizeof(float); - if (find_names(name, {"input_layernorm"})) { - tmp_hidden_dim = size; - } - void *quant_ptr = nullptr; - std::pair block_t; - if (find_names(name, q6_layers) && (dataType == MLLM_TYPE_Q6_K || dataType == MLLM_TYPE_Q4_K || dataType == MLLM_TYPE_Q2_K || dataType == MLLM_TYPE_Q3_K)) { - if (tmp_hidden_dim > 0 && (size / tmp_hidden_dim) % 256 != 0) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_Q4_0) << "\t"; - block_t = alloc_quant_block(size, MLLM_TYPE_Q4_0); - quant_ptr = block_t.first; - quantize_row_q4_0(param, quant_ptr, size); - size = block_t.second; - if (quant_ptr != nullptr) { - writeParam(name, MLLM_TYPE_Q4_0, quant_ptr, size); - std::cout << " size:" << size << " type:" << DataTypeName(MLLM_TYPE_Q4_0) << std::endl; - } - - continue; - } - } - if (find_names(name, fp32_layers)) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_F32) << "\t"; - const auto s = param_loader_->offsets_[name].second / sizeof(float); - const auto tsize = alloc_quant_block(s, MLLM_TYPE_F32).second; - writeParam(name, MLLM_TYPE_F32, param, tsize); - std::cout << " size:" << tsize << std::endl; - - } else if (find_names(name, q6_layers) && (dataType != MLLM_TYPE_KLEIDIAI_Q4_0)) { - switch (dataType) { - case MLLM_TYPE_F32: - std::cout << "No need to quantize FP32 params\n"; - __exit(-1); - break; - case MLLM_TYPE_Q4_0: - std::cout << "Quantize param " << name << " to " << DataTypeName(dataType) << "\t"; - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q4_0(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_Q4_K: - case MLLM_TYPE_Q6_K: - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_Q6_K) << "\t"; - block_t = alloc_quant_block(size, MLLM_TYPE_Q6_K); - quant_ptr = block_t.first; - quantize_row_q6_K(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_Q8_0: - std::cout << "Quantize param " << name << " to " << DataTypeName(dataType) << "\t"; - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q8_0(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_Q8_K: - std::cout << "Quantize param " << name << " to " << DataTypeName(dataType) << "\t"; - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q8_K(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_Q4_0_4_4: - std::cout << "Quantize param " << name << " to " << DataTypeName(dataType) << "\t"; - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q4_0_4x4(param, quant_ptr, size); - size = block_t.second; - break; - default: - break; - } - if (quant_ptr != nullptr) { - if ((dataType == MLLM_TYPE_Q4_K) | (dataType == MLLM_TYPE_Q6_K)) { - writeParam(name, MLLM_TYPE_Q6_K, quant_ptr, size); - std::cout << " size:" << size << " type:" << DataTypeName(MLLM_TYPE_Q6_K) << std::endl; - } else { - writeParam(name, quant_type_, quant_ptr, size); - std::cout << " size:" << size << " type:" << DataTypeName(quant_type_) << std::endl; - } - } - } else if (find_names(name, q3k_layers)) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_Q3_K) << "\t"; - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q3_K(param, quant_ptr, size); - size = block_t.second; - if (quant_ptr != nullptr) { - writeParam(name, MLLM_TYPE_Q3_K, quant_ptr, size); - std::cout << " size:" << size << " type:" << DataTypeName(MLLM_TYPE_Q3_K) << std::endl; - } - } else if (find_names(name, q2k_layers)) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_Q2_K) << "\t"; - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q2_K(param, quant_ptr, size); - size = block_t.second; - if (quant_ptr != nullptr) { - writeParam(name, MLLM_TYPE_Q2_K, quant_ptr, size); - std::cout << " size:" << size << " type:" << DataTypeName(MLLM_TYPE_Q2_K) << std::endl; - } - } else { - std::cout << "Quantize param " << name << " to " << DataTypeName(dataType) << "\t"; - switch (dataType) { - case MLLM_TYPE_F32: - std::cout << "No need to quantize FP32 params\n"; - __exit(-1); - break; - case MLLM_TYPE_KLEIDIAI_Q4_0: { -#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) - // todo:对qwen/qwen2vl特化了,后续一定要重写 - int K = tmp_hidden_dim; - int N = size / K; - if (name.find("down_proj") != std::string::npos) { - N = tmp_hidden_dim; - K = size / N; - } - std::vector transposed_weight_data(K * N); - const float *original_weight_ptr = param; -#pragma omp parallel for collapse(2) num_threads(4) - for (int n = 0; n < N; ++n) { - for (int k = 0; k < K; ++k) { - // 核心转置逻辑:dst[k][n] = src[n][k] - transposed_weight_data[k * N + n] = original_weight_ptr[n * K + k]; - } - } - block_t = alloc_kleidiai_quant_block(MLLM_TYPE_KLEIDIAI_Q4_0, N, K); - quant_ptr = block_t.first; - // mllm_kleidai_pack_b_and_bias_qsi4 - if (name.find("weight") != std::string::npos) { - std::string bias_name = name; - bias_name.replace(bias_name.find("weight"), 6, "bias"); - auto *bias_param = getParam(bias_name); - float first_bias = bias_param[0]; - // std::cout << "【Kleidiai】======Quantize param " << name << " bias: " << first_bias << std::endl; - // if (bias_param != nullptr && name.find("o_proj") == std::string::npos&& name.find("mlp") == std::string::npos) { - if (first_bias != 0.0f) { - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), - bias_param, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; - } else { - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), - nullptr, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; - } - } else { - throw std::runtime_error("name does not contain 'weight': " + name); - } - size = block_t.second; - break; -#else - std::cerr << "KLEIDIAI_Q4_0 is not supported on this platform!" << std::endl; - exit(-1); -#endif - } - case MLLM_TYPE_Q4_0: - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q4_0(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_Q8_0: - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q8_0(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_Q4_K: - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q4_K(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_Q6_K: - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q6_K(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_Q8_K: - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q8_K(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_Q4_0_4_4: - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - quantize_row_q4_0_4x4(param, quant_ptr, size); - size = block_t.second; - break; - case MLLM_TYPE_I8: - case MLLM_TYPE_Q4_1: - case MLLM_TYPE_Q8_1: - case MLLM_TYPE_I16: - case MLLM_TYPE_I32: - case MLLM_TYPE_F16: - NOT_IMPLEMENTED(dataType); - break; - case MLLM_TYPE_COUNT: - UNREACHABLE() - break; - default: - break; - } - if (quant_ptr != nullptr) { - writeParam(name, quant_type_, quant_ptr, size); - std::cout << " size:" << size << std::endl; - } - // writeParam(name, quant_type_, quant_ptr, size); -#ifndef TEST - delete[] (char *)quant_ptr; -#endif - } - } - writeIndex(); -} -vector q4x4_2_q4_layers = { - "wv", - "v_proj", - "qkv_proj", - // dclm - "in_proj", - "w12", - "model.output", -}; -bool dclm_flag = false; -void QuantWriter::quantParams_q4_(DataType dataType) { - bool do_quantParams_q4_vl = false; - for (const auto &name : param_names_) { - auto size = param_loader_->offsets_[name].second / sizeof(float); - if (find_names(name, {"visual"})) { - do_quantParams_q4_vl = true; - } - } - if (do_quantParams_q4_vl) { - return quantParams_q4_vl(dataType); - } - - for (const auto &name : param_names_) { - auto size = param_loader_->offsets_[name].second / sizeof(float); - if (find_names(name, {"norm"})) { - tmp_hidden_dim = size; - } - if (find_names(name, {"w12"})) { - dclm_flag = true; - } - } - quant_type_ = dataType; - for (const auto &name : param_names_) { - auto *param = getParam(name); - if (param == nullptr) { - __exit(-1); - } - auto size = param_loader_->offsets_[name].second / sizeof(float); - if (find_names(name, {"norm"})) { - tmp_hidden_dim = size; - } - void *quant_ptr = nullptr; - std::pair block_t; - if (find_names(name, fp32_layers)) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_F32) << "\t"; - const auto s = param_loader_->offsets_[name].second / sizeof(float); - const auto tsize = alloc_quant_block(s, MLLM_TYPE_F32).second; - writeParam(name, MLLM_TYPE_F32, param, tsize); - std::cout << " size:" << tsize << std::endl; - } else if (find_names(name, q4x4_2_q4_layers)) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_Q4_0) << "\t"; - block_t = alloc_quant_block(size, MLLM_TYPE_Q4_0); - quant_ptr = block_t.first; - quantize_row_q4_0(param, quant_ptr, size); - size = block_t.second; - if (quant_ptr != nullptr) { - writeParam(name, MLLM_TYPE_Q4_0, quant_ptr, size); - std::cout << " size:" << size << " type:" << DataTypeName(MLLM_TYPE_Q4_0) << std::endl; - } - } else { - std::cout << "Quantize param " << name << " to " << DataTypeName(dataType) << "\t"; - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - int tmp_hidden_dim_q4 = tmp_hidden_dim; - if (find_names(name, {"w2", "down_proj"}) || (dclm_flag && find_names(name, {"w3"}))) { - tmp_hidden_dim_q4 = (size / tmp_hidden_dim); - } - quantize_row_q4_0_4x4(param, quant_ptr, size, tmp_hidden_dim_q4); - size = block_t.second; - if (quant_ptr != nullptr) { - writeParam(name, quant_type_, quant_ptr, size); - std::cout << " size:" << size << std::endl; - } -#ifndef TEST - delete[] (char *)quant_ptr; -#endif - } - } - writeIndex(); -} - -vector vl_q4x4_2_q4_layers = { - "wv", - "v_proj", - ".attn.qkv", - "in_proj", - "w12", - "model.output", - // "embed_tokens", - "mlp.0", - "mlp.2", - - // "visual", - // "q_proj", - // "model", -}; -int vit_tmp_hidden_dim = -1; -void QuantWriter::quantParams_q4_vl(DataType dataType) { - for (const auto &name : param_names_) { - auto size = param_loader_->offsets_[name].second / sizeof(float); - if (find_names(name, {"input_layernorm"}) && find_names(name, {"model"})) { - tmp_hidden_dim = size; - } - if (find_names(name, {"norm"}) && find_names(name, {"visual"})) { - vit_tmp_hidden_dim = size; - } - } - std::cout << "tmp_hidden_dim:" << tmp_hidden_dim << std::endl; - std::cout << "vit_tmp_hidden_dim:" << vit_tmp_hidden_dim << std::endl; - quant_type_ = dataType; - for (const auto &name : param_names_) { - auto *param = getParam(name); - if (param == nullptr) { - __exit(-1); - } - auto size = param_loader_->offsets_[name].second / sizeof(float); - // if (find_names(name, {"input_layernorm"})) { - // tmp_hidden_dim = size; - // } - void *quant_ptr = nullptr; - std::pair block_t; - if (find_names(name, fp32_layers)) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_F32) << "\t"; - const auto s = param_loader_->offsets_[name].second / sizeof(float); - const auto tsize = alloc_quant_block(s, MLLM_TYPE_F32).second; - writeParam(name, MLLM_TYPE_F32, param, tsize); - std::cout << " size:" << tsize << std::endl; - } else if (find_names(name, vl_q4x4_2_q4_layers)) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_Q4_0) << "\t"; - block_t = alloc_quant_block(size, MLLM_TYPE_Q4_0); - quant_ptr = block_t.first; - quantize_row_q4_0(param, quant_ptr, size); - size = block_t.second; - if (quant_ptr != nullptr) { - writeParam(name, MLLM_TYPE_Q4_0, quant_ptr, size); - std::cout << " size:" << size << " type:" << DataTypeName(MLLM_TYPE_Q4_0) << std::endl; - } - } else { - std::cout << "Quantize param " << name << " to " << DataTypeName(dataType) << "\t"; - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - if (find_names(name, {"visual"})) { - int tmp_hidden_dim_q4 = vit_tmp_hidden_dim; - if (find_names(name, {"fc2", "down_proj"})) { - tmp_hidden_dim_q4 = (size / vit_tmp_hidden_dim); - } - quantize_row_q4_0_4x4(param, quant_ptr, size, tmp_hidden_dim_q4); - } else { - int tmp_hidden_dim_q4 = tmp_hidden_dim; - if (find_names(name, {"w2", "down_proj"})) { - tmp_hidden_dim_q4 = (size / tmp_hidden_dim); - } - quantize_row_q4_0_4x4(param, quant_ptr, size, tmp_hidden_dim_q4); - } - size = block_t.second; - if (quant_ptr != nullptr) { - writeParam(name, quant_type_, quant_ptr, size); - std::cout << " size:" << size << std::endl; - } -#ifndef TEST - delete[] (char *)quant_ptr; -#endif - } - } - writeIndex(); -} - -vector vl_q4x4_2_q4_k_layers = { - // "wv", - // "v_proj", //eager mode - // ".attn.qkv", - "in_proj", - "w12", - "model.output", - "merger.mlp", - // "mlp.0", - // "mlp.2", -}; -void QuantWriter::quantParams_kai_vl(DataType dataType) { -#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) - for (const auto &name : param_names_) { - auto size = param_loader_->offsets_[name].second / sizeof(float); - if (find_names(name, {"input_layernorm"}) && find_names(name, {"model"})) { - tmp_hidden_dim = size; - } - if (find_names(name, {"norm"}) && find_names(name, {"visual"})) { - vit_tmp_hidden_dim = size; - } - } - std::cout << "tmp_hidden_dim:" << tmp_hidden_dim << std::endl; - std::cout << "vit_tmp_hidden_dim:" << vit_tmp_hidden_dim << std::endl; - quant_type_ = dataType; - for (const auto &name : param_names_) { - auto *param = getParam(name); - if (param == nullptr) { - __exit(-1); - } - auto size = param_loader_->offsets_[name].second / sizeof(float); - // if (find_names(name, {"input_layernorm"})) { - // tmp_hidden_dim = size; - // } - void *quant_ptr = nullptr; - std::pair block_t; - if (find_names(name, fp32_layers)) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_F32) << "\t"; - const auto s = param_loader_->offsets_[name].second / sizeof(float); - const auto tsize = alloc_quant_block(s, MLLM_TYPE_F32).second; - writeParam(name, MLLM_TYPE_F32, param, tsize); - std::cout << " size:" << tsize << std::endl; - } else if (find_names(name, vl_q4x4_2_q4_k_layers)) { - std::cout << "Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_Q4_0) << "\t"; - block_t = alloc_quant_block(size, MLLM_TYPE_Q4_0); - quant_ptr = block_t.first; - quantize_row_q4_0(param, quant_ptr, size); - size = block_t.second; - if (quant_ptr != nullptr) { - writeParam(name, MLLM_TYPE_Q4_0, quant_ptr, size); - std::cout << " size:" << size << " type:" << DataTypeName(MLLM_TYPE_Q4_0) << std::endl; - } - } else { - std::cout << "Quantize param " << name << " to " << DataTypeName(dataType) << "\t"; - block_t = alloc_quant_block(size, dataType); - quant_ptr = block_t.first; - if (find_names(name, {"visual"})) { - // int tmp_hidden_dim_q4 = vit_tmp_hidden_dim; - // if (find_names(name, {"fc2", "down_proj"})) { - // tmp_hidden_dim_q4 = (size / vit_tmp_hidden_dim); - // } - // quantize_row_q4_0_4x4(param, quant_ptr, size, tmp_hidden_dim_q4); - - int K = vit_tmp_hidden_dim; - int N = size / K; - if (find_names(name, {"fc2", "down_proj"})) { - N = vit_tmp_hidden_dim; - K = size / N; - } - std::vector transposed_weight_data(K * N); - const float *original_weight_ptr = param; -#pragma omp parallel for collapse(2) num_threads(4) - for (int n = 0; n < N; ++n) { - for (int k = 0; k < K; ++k) { - transposed_weight_data[k * N + n] = original_weight_ptr[n * K + k]; - } - } - block_t = alloc_kleidiai_quant_block(MLLM_TYPE_KLEIDIAI_Q4_0, N, K); - quant_ptr = block_t.first; - // mllm_kleidai_pack_b_and_bias_qsi4 - if (name.find("weight") != std::string::npos) { - std::string bias_name = name; - bias_name.replace(bias_name.find("weight"), 6, "bias"); - auto *bias_param = getParam(bias_name); - float first_bias = bias_param[0]; - if (first_bias != 0.0f) { - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), - bias_param, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; - } else { - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), - nullptr, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; - } - } else { - throw std::runtime_error("name does not contain 'weight': " + name); - } - } else { - // int tmp_hidden_dim_q4 = tmp_hidden_dim; - // if (find_names(name, {"w2", "down_proj"})) { - // tmp_hidden_dim_q4 = (size / tmp_hidden_dim); - // } - // quantize_row_q4_0_4x4(param, quant_ptr, size, tmp_hidden_dim_q4); - - int K = tmp_hidden_dim; - int N = size / K; - if (find_names(name, {"w2", "down_proj"})) { - N = tmp_hidden_dim; - K = size / N; - } - std::vector transposed_weight_data(K * N); - const float *original_weight_ptr = param; -#pragma omp parallel for collapse(2) num_threads(4) - for (int n = 0; n < N; ++n) { - for (int k = 0; k < K; ++k) { - transposed_weight_data[k * N + n] = original_weight_ptr[n * K + k]; - } - } - block_t = alloc_kleidiai_quant_block(MLLM_TYPE_KLEIDIAI_Q4_0, N, K); - quant_ptr = block_t.first; - // mllm_kleidai_pack_b_and_bias_qsi4 - if (name.find("weight") != std::string::npos) { - std::string bias_name = name; - bias_name.replace(bias_name.find("weight"), 6, "bias"); - auto *bias_param = getParam(bias_name); - float first_bias = bias_param[0]; - if (first_bias != 0.0f) { - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), - bias_param, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " has [bias] to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; - } else { - mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), - nullptr, N, K); - std::cout << "【Kleidiai】Quantize param " << name << " to " << DataTypeName(MLLM_TYPE_KLEIDIAI_Q4_0) << " N:" << N << " K:" << K << ", \t"; - } - } else { - throw std::runtime_error("name does not contain 'weight': " + name); - } - } - size = block_t.second; - if (quant_ptr != nullptr) { - writeParam(name, quant_type_, quant_ptr, size); - std::cout << " size:" << size << std::endl; - } -#ifndef TEST - delete[] (char *)quant_ptr; -#endif - } - } - writeIndex(); -#else - std::cerr << "KLEIDIAI_Q4_0 is not supported on this platform!" << std::endl; - exit(-1); -#endif -} - -void QuantWriter::writeParam(string name, DataType type, void *data, uint64_t size) { -#ifdef TEST - data_[name] = (char *)data; -#endif - ParamWriter::writeParam(name, type, data, size); -} - -} // namespace mllm \ No newline at end of file diff --git a/src/quantizer/main_quantize.cpp b/src/quantizer/main_quantize.cpp deleted file mode 100644 index 428860d32..000000000 --- a/src/quantizer/main_quantize.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// Created by Xiang Li on 23-10-31. -// -#include "ParamWriter.hpp" -#include "ParamLoader.hpp" -#include -#include "QuantWriter.hpp" - -int main(int argc, char **argv) { - if (argc < 4) { - std::cout << "Usage: ./quantize \n"; - return -1; - } - auto input_path = std::string(argv[1]); - auto output_path = std::string(argv[2]); - auto quant_type = std::string(argv[3]); - string other_flag = ""; // "vl" or "eager" - if(argc == 5) { - if (std::string(argv[4]) == "vl" || std::string(argv[4]) == "eager") { - other_flag = std::string(argv[4]); - } else { - std::cout << "Invalid other flag. Use 'vl' or 'eager'.\n"; - return -1; - } - } - // auto other_flag = std::string(argv[4]); - // std::string input_path = "../models/qwen-2.5-1.5b-instruct-fp32.mllm"; - // std::string output_path = "../models/qwen-2.5-1.5b-instruct-kai_q4_0_.mllm"; - // string other_flag = ""; // "vl" or "eager" - // std::string input_path = "../models/qwen-2-vl-2b-instruct-fp32.mllm"; - // std::string output_path = "../models/qwen-2-vl-2b-instruct-kai_q4_0.mllm"; - // std::string quant_type = "KAI_Q4_0"; - mllm::QuantWriter quant_writer(output_path, input_path); - int param_count = quant_writer.readParams(); - if (param_count <= 0) { - std::cout << "No params to quantize\n"; - return -1; - } - std::cout << "Quantize " << param_count << " params to " << quant_type << "\n"; - if (quant_type == "Q4_0") { - quant_writer.quantParams(MLLM_TYPE_Q4_0); - } else if (quant_type == "Q8_0") { - quant_writer.quantParams(MLLM_TYPE_Q8_0); - } else if (quant_type == "Q2_K") { - quant_writer.quantParams(MLLM_TYPE_Q2_K); - } else if (quant_type == "Q3_K") { - quant_writer.quantParams(MLLM_TYPE_Q3_K); - } else if (quant_type == "Q4_K") { - quant_writer.quantParams(MLLM_TYPE_Q4_K); - } else if (quant_type == "Q6_K") { - quant_writer.quantParams(MLLM_TYPE_Q6_K); - } else if (quant_type == "Q8_K") { - quant_writer.quantParams(MLLM_TYPE_Q8_K); - } else if (quant_type == "KAI_Q4_0") { - // quant_writer.quantParams(MLLM_TYPE_KLEIDIAI_Q4_0); - if (other_flag == "eager") { - vl_q4x4_2_q4_k_layers.push_back("v_proj"); - } - quant_writer.quantParams_kai_vl(MLLM_TYPE_KLEIDIAI_Q4_0); - } else if (quant_type == "Q4_0_4_4") { - if (other_flag == "vl") { - quant_writer.quantParams_q4_vl(MLLM_TYPE_Q4_0_4_4); - } else { - quant_writer.quantParams_q4_(MLLM_TYPE_Q4_0_4_4); - } - } else { - std::cout << "Quant type " << quant_type << " is not supported\n"; - return -1; - } - return 0; -} \ No newline at end of file diff --git a/src/tokenizers/Tokenizer.hpp b/src/tokenizers/Tokenizer.hpp index cb0a85e32..1ffe3b441 100644 --- a/src/tokenizers/Tokenizer.hpp +++ b/src/tokenizers/Tokenizer.hpp @@ -51,7 +51,7 @@ class Tokenizer { std::string chat_template_end; public: - Tokenizer(){ + Tokenizer() { // do nothing } explicit Tokenizer(const std::string &vocab_file); @@ -76,7 +76,8 @@ class Tokenizer { static void token2Tensor(Net *net, vector tokens, shared_ptr input_tensor); static void tokens2Tensor(Net *net, vector> tokens, shared_ptr input_tensor); static Tensor tokens2Input(vector tokens_id, string name = "input", BackendType type = MLLM_CPU) { - Tensor tensor1(1, 1, tokens_id.size(), 1, Backend::global_backends[type], true); + Module::initBackend(type); + Tensor tensor1(1, 1, tokens_id.size(), 1, Backend::global_backends[type].get(), true); tensor1.setName(name); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); @@ -87,7 +88,7 @@ class Tokenizer { } static Tensor tokens2Input(vector> tokens, string name = "input", BackendType type = MLLM_CPU) { const auto bsize = static_cast(tokens.size()); - Tensor tensor1(bsize, 1, static_cast(tokens[0].size()), 1, Backend::global_backends[type], true); + Tensor tensor1(bsize, 1, static_cast(tokens[0].size()), 1, Backend::global_backends[type].get(), true); tensor1.setName(name); Tensor::tensor_status = TENSOR_STATIC_INIT; tensor1.setTtype(INPUT_TENSOR); diff --git a/test/quantizer/WriterTest.cpp b/test/quantizer/WriterTest.cpp index d6916ac48..82294d4e7 100644 --- a/test/quantizer/WriterTest.cpp +++ b/test/quantizer/WriterTest.cpp @@ -3,12 +3,17 @@ // #include "gtest/gtest.h" #include +#include // #include "ParamLoader.hpp" #include "ParamWriter.hpp" #include "QuantWriter.hpp" #include "QuantTest.hpp" #include "Types.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ4.hpp" // For manual quantization + namespace mllm { + +// ReadTest 不需要修改,因为 ParamLoader 的读取接口保持兼容 TEST_F(QuantTest, ReadTest) { auto loader = ParamLoader("../bin/quant_test.mllm"); auto tensor_name = loader.getParamNames(); @@ -17,44 +22,95 @@ TEST_F(QuantTest, ReadTest) { auto [data, size] = loader.load("weight_f0"); ASSERT_EQ(data[0], 0.0); ASSERT_EQ(data[1], 0.0); + delete[] data; // 释放 loader.load 返回的内存 } + +// ** [修改] ** WriteTest 使用新的流式写入 API TEST_F(QuantTest, WriteTest) { auto *loader = new ParamLoader("../bin/quant_test.mllm"); auto *writer = new ParamWriter("../bin/quant_result.mllm"); auto tensor_name = loader->getParamNames(); writer->paddingIndex(tensor_name); ASSERT_EQ(tensor_name.size(), 2); - std::unordered_map ori_data; - for (auto tensor : tensor_name) { + + // 使用 vector 来管理内存,避免手动 new/delete + std::unordered_map> ori_data; + + for (const auto &tensor : tensor_name) { auto [data, size] = loader->load(tensor); - ori_data[tensor] = data; - writer->writeParam(tensor, DataType::MLLM_TYPE_F32, data, size); + + // 存储原始数据以供后续比较 + ori_data[tensor].resize(size); + memcpy(ori_data[tensor].data(), data, size); + + // ** 使用新的三段式流式写入 ** + writer->beginWriteParam(tensor, DataType::MLLM_TYPE_F32); + writer->writeChunk(data, size); + writer->endWriteParam(); + + delete[] data; // 释放 loader->load 返回的内存 } + writer->writeIndex(); delete writer; delete loader; + + // 验证写入的文件 auto loader2 = ParamLoader("../bin/quant_result.mllm"); auto tensor_name2 = loader2.getParamNames(); ASSERT_EQ(tensor_name2.size(), 2); - ASSERT_EQ(loader2.getDataType(tensor_name2[0]), DataType::MLLM_TYPE_F32); - auto [data, size] = loader2.load("weight_f1"); - float *fdata = (float *)data; - for (int i = 0; i < size / sizeof(float); i++) { - ASSERT_EQ(fdata[i], ori_data["weight_f1"][i]); + ASSERT_EQ(loader2.getDataType("weight_f1"), DataType::MLLM_TYPE_F32); + + auto [data2, size2] = loader2.load("weight_f1"); + float *fdata = (float *)data2; + unsigned char *original_raw_data = ori_data["weight_f1"].data(); + + // 逐字节比较 + for (size_t i = 0; i < size2; i++) { + ASSERT_EQ(data2[i], original_raw_data[i]); } + delete[] data2; } + +// ** [修改] ** QuantTest 不再依赖 QuantWriter 内部状态,而是测试端到端的文件输出 TEST_F(QuantTest, QuantTest) { - auto *quant = new QuantWriter("../bin/quant_result.mllm", "../bin/quant_test.mllm"); - ASSERT_EQ(quant->readParams(), 2); - quant->quantParams(DataType::MLLM_TYPE_Q4_0); - ASSERT_EQ(quant->data_.size(), 2); - // delete quant; - auto loader = ParamLoader("../bin/quant_result.mllm"); - auto tensor_name = loader.getParamNames(); - ASSERT_EQ(tensor_name.size(), 2); - ASSERT_EQ(loader.getDataType(tensor_name[0]), DataType::MLLM_TYPE_Q4_0); - auto [data, size] = loader.load("weight_f1"); - auto *ori_data = quant->data_["weight_f1"]; - ASSERT_TRUE(compare_eq(reinterpret_cast(ori_data), reinterpret_cast(data))); + const std::string input_path = "../bin/quant_test.mllm"; + const std::string output_path = "../bin/quant_result.mllm"; + const std::string target_tensor_name = "weight_f1"; + + // 1. 执行量化,生成输出文件 + auto *quant_writer = new QuantWriter(output_path, input_path); + ASSERT_EQ(quant_writer->readParams(), 2); + quant_writer->quantize(DataType::MLLM_TYPE_Q4_0, ""); // 使用新的 quantize API + delete quant_writer; + + // 2. 加载原始的 FP32 数据,用于生成“期望”的量化结果 + auto *original_loader = new ParamLoader(input_path); + auto [original_data_ptr, original_size] = original_loader->load(target_tensor_name); + + // 3. 在测试中手动进行量化,得到期望的结果 + uint64_t num_floats = original_size / sizeof(float); + auto block_t = alloc_quant_block(num_floats, DataType::MLLM_TYPE_Q4_0); + void *expected_quant_data = block_t.first; + quantize_row_q4_0(reinterpret_cast(original_data_ptr), expected_quant_data, num_floats); + + // 4. 从 QuantWriter 生成的文件中加载实际的量化结果 + auto result_loader = ParamLoader(output_path); + auto tensor_names_from_result = result_loader.getParamNames(); + ASSERT_EQ(tensor_names_from_result.size(), 2); + ASSERT_EQ(result_loader.getDataType(target_tensor_name), DataType::MLLM_TYPE_Q4_0); + auto [actual_quant_data_ptr, actual_quant_size] = result_loader.load(target_tensor_name); + + // 5. 比较期望的量化结果和实际的量化结果 + ASSERT_EQ(block_t.second, actual_quant_size); // 尺寸应该一致 + ASSERT_TRUE(compare_eq( + reinterpret_cast(expected_quant_data), + reinterpret_cast(actual_quant_data_ptr))); + + // 6. 清理内存 + delete[] (char *)expected_quant_data; + delete[] original_data_ptr; + delete[] actual_quant_data_ptr; + delete original_loader; } -} // namespace mllm +} // namespace mllm \ No newline at end of file diff --git a/tools/convertor/converter.py b/tools/convertor/converter.py index 3bc196800..7cc2e3b10 100644 --- a/tools/convertor/converter.py +++ b/tools/convertor/converter.py @@ -72,7 +72,8 @@ def write_tensor(self, tensor: torch.Tensor, name: str) -> [int, int]: elif tensor.dtype == torch.bool or tensor.dtype == torch.int8: # exported model for QNN int8 tensor_numpy = tensor.detach().to(torch.int8).numpy() else: - tensor_numpy = tensor.numpy() + # print(f"Write tensor {name} with dtype {tensor.dtype}") + tensor_numpy = tensor.detach().to(torch.float32).numpy() tensor_numpy.tofile(self.writer) size = self.writer.tell() - offset tensor_idx.size = size diff --git a/tools/jni/LibHelper.cpp b/tools/jni/LibHelper.cpp index cfa08047a..87b8001d5 100644 --- a/tools/jni/LibHelper.cpp +++ b/tools/jni/LibHelper.cpp @@ -115,9 +115,9 @@ bool LibHelper::setUp(const std::string &base_path, std::string weights_path, st return true; }); Module::isFirstChunk = false; - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); Module::isMultiChunkPrefilling = true; // warmup END LOGE("QNN Warmup finished."); @@ -183,9 +183,9 @@ bool LibHelper::setUp(const std::string &base_path, std::string weights_path, st return true; }); Module::isFirstChunk = false; - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); Module::isMultiChunkPrefilling = true; // warmup END LOGE("QNN Warmup finished."); @@ -224,9 +224,9 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u bool isSwitched = false; // set total seq length for HeadLinear execute, which can not get the real seq length from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setTotalSequenceLength(real_seq_length); // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + static_cast(Backend::global_backends[MLLM_CPU].get())->setChunkSize(chunk_size); LlmTextGeneratorOpts opt{ .max_new_tokens = 1, @@ -237,16 +237,16 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u }; std::vector chunked_tensors(chunk_num); for (int chunk_id = 0; chunk_id < chunk_num; ++chunk_id) { - chunked_tensors[chunk_id].setBackend(Backend::global_backends[MLLM_CPU]); + chunked_tensors[chunk_id].setBackend(Backend::global_backends[MLLM_CPU].get()); chunked_tensors[chunk_id].setTtype(INPUT_TENSOR); chunked_tensors[chunk_id].reshape(1, 1, chunk_size, 1); chunked_tensors[chunk_id].setName("input-chunk-" + to_string(chunk_id)); chunked_tensors[chunk_id].shallowCopyFrom(&input_tensor, false, {0, 0, chunk_id * chunk_size, 0}); prefill_module_->generate(chunked_tensors[chunk_id], opt, [&](unsigned int out_token) -> bool { - if (!isSwitched && chunk_id == 0 && static_cast(Backend::global_backends[MLLM_CPU])->isStageSwitching()) { + if (!isSwitched && chunk_id == 0 && static_cast(Backend::global_backends[MLLM_CPU].get())->isStageSwitching()) { // turn off switching at the first chunk of following inputs - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } // switch_flag = true; @@ -268,9 +268,9 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u }); Module::isFirstChunk = false; } - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); opt = LlmTextGeneratorOpts{ .max_new_tokens = max_new_tokens - 1, @@ -283,7 +283,7 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u isSwitched = false; module_->generate(chunked_tensors.back(), opt, [&](unsigned int out_token) -> bool { if (!isSwitched) { - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } auto out_token_string = tokenizer_->detokenize({out_token}); @@ -301,9 +301,9 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u if (!not_end) { return false; } return true; }); - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); } else { // CPU auto input_tensor = tokenizer_->tokenize(input_str); max_new_tokens = tokens_limit - input_tensor.sequence(); @@ -377,14 +377,14 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u LOGE("after warm up"); Module::isFirstChunk = false; - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); // set total seq length for HeadLinear execute, which can not get the real seq length from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setTotalSequenceLength(real_seq_length); // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + static_cast(Backend::global_backends[MLLM_CPU].get())->setChunkSize(chunk_size); for (auto &t : input_tensors) { t.setTtype(INPUT_TENSOR); @@ -424,7 +424,7 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u auto result = (*prefill_module_)(prefill_input); if (i == 0) { // turn off switching to avoid RoPE h_cnt_ reset to curSequenceLength in next chunk - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); } if (i == 1) { @@ -441,9 +441,9 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u chatPostProcessing(out_token, input_tensors[0], {&input_tensors[1], &input_tensors[2]}); - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); // 3. CPU LLM Decoding for (auto &t : input_tensors) { // set to INPUT_TENSOR to let decoding module update act @@ -464,7 +464,7 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u callback_(output_string_, !end, {}); if (!end) { break; } chatPostProcessing(out_token, input_tensors[0], {&input_tensors[1], &input_tensors[2]}); - if (step == 0) static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + if (step == 0) static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); } std::cout << std::endl; @@ -504,9 +504,9 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u bool isSwitched = false; // set total seq length for HeadLinear execute, which can not get the real seq length from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setTotalSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setTotalSequenceLength(real_seq_length); // set chunk size for the HeadLinear execute, which can not get the chunk size from Opts - static_cast(Backend::global_backends[MLLM_CPU])->setChunkSize(chunk_size); + static_cast(Backend::global_backends[MLLM_CPU].get())->setChunkSize(chunk_size); LlmTextGeneratorOpts opt{ .max_new_tokens = 1, @@ -517,7 +517,7 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u }; std::vector chunked_tensors(chunk_num); for (int chunk_id = 0; chunk_id < chunk_num; ++chunk_id) { - chunked_tensors[chunk_id].setBackend(Backend::global_backends[MLLM_CPU]); + chunked_tensors[chunk_id].setBackend(Backend::global_backends[MLLM_CPU].get()); chunked_tensors[chunk_id].setTtype(INPUT_TENSOR); chunked_tensors[chunk_id].reshape(1, 1, chunk_size, 1); chunked_tensors[chunk_id].setName("input-chunk-" + to_string(chunk_id)); @@ -527,7 +527,7 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u // if (switch_flag && !isSwitched && chunk_id == 0) { if (!isSwitched && chunk_id == 0) { // turn off switching at the first chunk of following inputs - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } // switch_flag = true; @@ -550,9 +550,9 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u }); Module::isFirstChunk = false; } - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(real_seq_length); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(AUTOREGRESSIVE); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(real_seq_length); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(AUTOREGRESSIVE); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); opt = LlmTextGeneratorOpts{ .max_new_tokens = max_new_tokens - 1, @@ -565,7 +565,7 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u isSwitched = false; module_->generate(chunked_tensors.back(), opt, [&](unsigned int out_token) -> bool { if (!isSwitched) { - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); isSwitched = true; } auto out_token_string = tokenizer_->detokenize({out_token}); @@ -583,9 +583,9 @@ void LibHelper::run(std::string &input_str, uint8_t *image, unsigned max_step, u if (!not_end) { return false; } return true; }); - static_cast(Backend::global_backends[MLLM_CPU])->setCurSequenceLength(0); - static_cast(Backend::global_backends[MLLM_CPU])->setExecutionType(PROMPT); - static_cast(Backend::global_backends[MLLM_CPU])->toggleSwitching(); + static_cast(Backend::global_backends[MLLM_CPU].get())->setCurSequenceLength(0); + static_cast(Backend::global_backends[MLLM_CPU].get())->setExecutionType(PROMPT); + static_cast(Backend::global_backends[MLLM_CPU].get())->toggleSwitching(); } else { // CPU auto input_tensor = tokenizer_->tokenize(input_str); max_new_tokens = tokens_limit - input_tensor.sequence(); diff --git a/tools/quantizer/ParamWriter.cpp b/tools/quantizer/ParamWriter.cpp new file mode 100644 index 000000000..c8928060a --- /dev/null +++ b/tools/quantizer/ParamWriter.cpp @@ -0,0 +1,84 @@ +// +// Created by Xiang Li on 23-10-30. +// +#include "ParamWriter.hpp" +#include +#include +#include +#include + +ParamWriter::ParamWriter(std::string filename) : + path_(std::move(filename)) { + fp_ = fopen(path_.c_str(), "wb"); + if (fp_ == nullptr) { + throw std::runtime_error("Failed to open file for writing: " + path_); + } + // _MAGIC_NUMBER is defined in ParamLoader.hpp + writeInt(fp_, _MAGIC_NUMBER); +} + +ParamWriter::~ParamWriter() { + if (fp_ != nullptr) + fclose(fp_); +} + +int ParamWriter::calcIndexSize(const std::vector &names) { + int size = 0; + for (const auto &name : names) { + // One Tensor Index Item Contains: Name_Len(Int)+Name(str)+Weights_Len(UInt64)+Offset(UInt64)+DataType(Int) + size += sizeof(int32_t) + name.size() + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(int32_t); + } + return size; +} + +void ParamWriter::writeIndex() { + fseek(fp_, sizeof(int32_t) + sizeof(uint64_t), SEEK_SET); + for (const auto ¶m : param_info_) { + writeString(fp_, param.name); + write_u64(fp_, param.size); + write_u64(fp_, param.offset); + write_dtype(fp_, param.type); + } + fflush(fp_); +} + +void ParamWriter::beginWriteParam(const std::string &name, DataType type) { + if (index_ >= param_info_.size()) { + throw std::runtime_error("Parameter index out of bounds. Did you call paddingIndex correctly?"); + } + auto ¶m = param_info_[index_]; + param.name = name; + param.type = type; + param.offset = ftell(fp_); + + current_param_start_offset_ = param.offset; +} + +void ParamWriter::writeChunk(const void *data, uint64_t size_in_bytes) { + if (size_in_bytes == 0) return; + auto status = fwrite(data, 1, size_in_bytes, fp_); + if (status != size_in_bytes) { + std::cout << "fwrite error: wrote " << status << " bytes instead of " << size_in_bytes << std::endl; + throw std::runtime_error("Failed to write chunk to file."); + } +} + +void ParamWriter::endWriteParam() { + fflush(fp_); + auto current_pos = ftell(fp_); + if (index_ >= param_info_.size()) { + throw std::runtime_error("Parameter index out of bounds at endWriteParam."); + } + auto ¶m = param_info_[index_]; + param.size = current_pos - current_param_start_offset_; + + index_++; +} + +void ParamWriter::paddingIndex(const std::vector &names) { + param_info_.resize(names.size()); + int index_size = calcIndexSize(names); + write_u64(fp_, index_size); + std::vector padding(index_size, 0); + fwrite(padding.data(), sizeof(char), index_size, fp_); +} \ No newline at end of file diff --git a/src/quantizer/ParamWriter.hpp b/tools/quantizer/ParamWriter.hpp similarity index 50% rename from src/quantizer/ParamWriter.hpp rename to tools/quantizer/ParamWriter.hpp index de6ed1d46..c2da5fb60 100644 --- a/src/quantizer/ParamWriter.hpp +++ b/tools/quantizer/ParamWriter.hpp @@ -5,6 +5,10 @@ #ifndef MLLM_PARAMWRITER_HPP #define MLLM_PARAMWRITER_HPP #include "ParamLoader.hpp" +#include +#include +#include + static void write_u64(FILE *fp, uint64_t val) { fwrite(&val, sizeof(uint64_t), 1, fp); } @@ -12,12 +16,13 @@ static void writeInt(FILE *fp, int32_t val) { fwrite(&val, sizeof(int32_t), 1, fp); } static void writeString(FILE *fp, const std::string &str) { - writeInt(fp, str.size()); - fwrite(str.c_str(), sizeof(char), str.size(), fp); - + writeInt(fp, static_cast(str.size())); + if (!str.empty()) { + fwrite(str.c_str(), sizeof(char), str.size(), fp); + } } static void write_dtype(FILE *fp, DataType dtype) { - writeInt(fp, dtype); + writeInt(fp, static_cast(dtype)); } struct ParmInfo { @@ -26,20 +31,28 @@ struct ParmInfo { uint64_t offset; uint64_t size; }; + class ParamWriter { public: - ~ParamWriter(); - ParamWriter(std::string filename); - int calcIndexSize(vector names); + virtual ~ParamWriter(); + explicit ParamWriter(std::string filename); + int calcIndexSize(const std::vector &names); void writeIndex(); - virtual void writeParam(string name, DataType type, void *data, uint64_t size); - void paddingIndex(vector names); -private: + void beginWriteParam(const std::string &name, DataType type); + void writeChunk(const void *data, uint64_t size_in_bytes); + void endWriteParam(); + + void paddingIndex(const std::vector &names); + +protected: uint64_t index_ = 0; FILE *fp_; std::string path_; std::vector param_info_; + +private: + uint64_t current_param_start_offset_ = 0; }; -#endif // MLLM_PARAMWRITER_HPP +#endif // MLLM_PARAMWRITER_HPP \ No newline at end of file diff --git a/tools/quantizer/QuantWriter.cpp b/tools/quantizer/QuantWriter.cpp new file mode 100644 index 000000000..f4b63beef --- /dev/null +++ b/tools/quantizer/QuantWriter.cpp @@ -0,0 +1,310 @@ +#include "QuantWriter.hpp" +#include "Types.hpp" +#include "backends/cpu/compute/GemmKleidiai.hpp" +#include +#include +#include + +namespace mllm { + +const std::vector fp32_layers = { + "norm", + "rope", + "bias", + "rotary_emb", + // "embed_tokens", + "_GN", + "class_embedding", + "embeddings", + "logit_scale", + "modality_preprocessors", + "modality_heads", + "modality_postprocessors", + "pre_transformer_layer", + "pos_embed.inv_freq", + "ln_q", + "patch_embed.proj", + // "mlp.gate.", + // "lm_head.weight", +}; +const std::vector q40_layers = { + "embed_tokens", + "word_embeddings", +}; +const std::vector q6_layers = { + // "w2", "wv", "dense_h_to_4h", "v_proj", "down_proj", +}; +const std::vector q23_layers = { + // ".experts.", +}; +const std::vector q23_to_q4_0_4x4_layers = { + "w2", + "wv", + "dense_h_to_4h", + "v_proj", + "down_proj", +}; + +const std::vector q4_0_kai_to_q4_0_4x4_layers = { + // 设置为KAI_Q4_0但不用 KAI_Q4_0 + "in_proj", + "w12", + "model.output", + "merger.mlp", + // for ling-lite-moe + // "query_key_value", + // "dense", +}; + +bool find_in_layers(const std::string &name, const std::vector &layer_names) { + if ("vision_embed_tokens" == name) return true; + for (const auto &layer : layer_names) { + if (name.find(layer) != std::string::npos) { + return true; + } + } + return false; +} + +QuantWriter::QuantWriter(std::string output_path, std::string input_path) : + ParamWriter(std::move(output_path)), output_path_(this->path_) { + param_loader_ = new mllm::ParamLoader(std::move(input_path)); + if (!param_loader_->isAvailible()) { + __exit(-1); + } +} + +QuantWriter::~QuantWriter() { + delete param_loader_; +}; + +int QuantWriter::readParams() { + param_names_ = param_loader_->getParamNames(); + paddingIndex(param_names_); + return param_names_.size(); +} + +std::vector QuantWriter::load_full_fp32_param(const std::string &name) { + if (param_loader_->getDataType(name) != MLLM_TYPE_F32) { + return {}; + } + auto [data_ptr, size] = param_loader_->load(name); + if (data_ptr == nullptr || size == 0) { + return {}; + } + std::vector param_data(size / sizeof(float)); + memcpy(param_data.data(), data_ptr, size); + delete[] data_ptr; + return param_data; +} + +DataType QuantWriter::getQuantizationTypeFor(const std::string &name, DataType target_type, const std::string &other_flag) { + if (find_in_layers(name, q40_layers)) { + return MLLM_TYPE_Q4_0; + } + if (find_in_layers(name, fp32_layers)) { + return MLLM_TYPE_F32; + } + if (find_in_layers(name, q23_layers) && (name.find("down_proj") == std::string::npos)) { + return MLLM_TYPE_Q2_K; + } + if (target_type == MLLM_TYPE_KLEIDIAI_Q4_0) { + if (find_in_layers(name, q4_0_kai_to_q4_0_4x4_layers)) { + return MLLM_TYPE_Q4_0_4_4; // MLLM_TYPE_Q4_0; // 这些层回退到Q4_0 + } + if (other_flag == "eager" && name.find("v_proj") != std::string::npos) { + return MLLM_TYPE_Q4_0; // eager模式下 v_proj 回退到Q4_0 + } + return MLLM_TYPE_KLEIDIAI_Q4_0; + } + if (target_type >= MLLM_TYPE_Q2_K && target_type <= MLLM_TYPE_Q8_K) { + if (find_in_layers(name, q6_layers)) { + return MLLM_TYPE_Q6_K; + } + } + return target_type; +} + +void QuantWriter::quantize(DataType target_quant_type, const std::string &other_flag) { + FILE *fp_in = param_loader_->getInputStream(); + if (!fp_in) { + std::cout << "Failed to get input file stream from ParamLoader." << std::endl; + __exit(-1); + } + + const int CHUNK_SIZE_FLOATS = 1024 * 1024; // 每次处理4MB + std::vector read_buffer(CHUNK_SIZE_FLOATS); + + int tmp_hidden_dim = -1; + int vit_tmp_hidden_dim = -1; + + for (const auto &name : param_names_) { + ParamMetadata meta = param_loader_->getParamMetadata(name); + const uint64_t num_floats = meta.size / sizeof(float); + + for (const auto &name : param_names_) { + if (tmp_hidden_dim != -1 && vit_tmp_hidden_dim != -1) { + break; // 如果都找到了,就提前退出预扫描 + } + /* + if (tmp_hidden_dim == -1 && find_in_layers(name, {"model.layers.0.input_layernorm"})) { + ParamMetadata meta = param_loader_->getParamMetadata(name); + tmp_hidden_dim = meta.size / sizeof(float); + } + if (vit_tmp_hidden_dim == -1 && find_in_layers(name, {"visual.patch_embed.norm"})) { + ParamMetadata meta = param_loader_->getParamMetadata(name); + vit_tmp_hidden_dim = meta.size / sizeof(float); + } + */ + if (tmp_hidden_dim == -1 && (name.find("model") != std::string::npos && name.find("norm") != std::string::npos)) { + ParamMetadata meta = param_loader_->getParamMetadata(name); + tmp_hidden_dim = meta.size / sizeof(float); + std::cout << " - Found hidden dimension (tmp_hidden_dim): " << tmp_hidden_dim << " from layer '" << name << "'" << std::endl; + } + if (vit_tmp_hidden_dim == -1 && (name.find("visual") != std::string::npos && name.find("norm") != std::string::npos)) { + ParamMetadata meta = param_loader_->getParamMetadata(name); + vit_tmp_hidden_dim = meta.size / sizeof(float); + std::cout << " - Found ViT hidden dimension (vit_tmp_hidden_dim): " << vit_tmp_hidden_dim << " from layer '" << name << "'" << std::endl; + } + } + + DataType final_quant_type = getQuantizationTypeFor(name, target_quant_type, other_flag); + + std::cout << "Processing param " << name << " -> " << DataTypeName(final_quant_type) << " ... "; + fflush(stdout); + + beginWriteParam(name, final_quant_type); + fseek(fp_in, meta.offset, SEEK_SET); + + if (final_quant_type == MLLM_TYPE_F32) { + std::vector f32_buffer(meta.size); + fread(f32_buffer.data(), 1, meta.size, fp_in); + writeChunk(f32_buffer.data(), meta.size); + } +#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) + else if (final_quant_type == MLLM_TYPE_KLEIDIAI_Q4_0) { + int H = find_in_layers(name, {"visual"}) ? vit_tmp_hidden_dim : tmp_hidden_dim; + if (H <= 0) { + std::cout << "FAIL! Hidden dimension not found for " << name << std::endl; + __exit(-1); + } + + int N, K; + if (find_in_layers(name, {"w2", "down_proj", "fc2"})) { + N = H; + K = num_floats / N; + } else { + K = H; + N = num_floats / K; + } + + // 1. 加载完整的 bias (因为它很小) + std::string bias_name = name; + bias_name.replace(bias_name.find("weight"), 6, "bias"); + std::vector bias_data = load_full_fp32_param(bias_name); + + // 2. 分配转置矩阵的内存 + std::vector transposed_weight_data(num_floats); + + // 3. 流式读取并转置 + std::vector row_buffer(K); + for (int n = 0; n < N; ++n) { + fread(row_buffer.data(), sizeof(float), K, fp_in); + for (int k = 0; k < K; ++k) { + transposed_weight_data[k * N + n] = row_buffer[k]; + } + } + + // 4. 分配量化空间并执行量化 + auto block_t = alloc_kleidiai_quant_block(final_quant_type, N, K); + void *quant_ptr = block_t.first; + +#ifndef KAI_FP16_CAL + mllm_kleidai_pack_b_and_bias_qsi4( + (uint8_t *)quant_ptr, + transposed_weight_data.data(), + bias_data.empty() ? nullptr : bias_data.data(), + N, K); +#else + mllm_kleidai_pack_b_and_bias_qsi4_to_fp16( + (uint8_t *)quant_ptr, + transposed_weight_data.data(), + bias_data.empty() ? nullptr : bias_data.data(), + N, K); +#endif + + // 5. 写入量化数据块 + writeChunk(quant_ptr, block_t.second); + delete[] (char *)quant_ptr; + + } +#endif + else if (final_quant_type == MLLM_TYPE_Q4_0_4_4) { + // 1. 为 Q4_0_4_4 加载完整的 FP32 数据 + std::vector param_data(num_floats); + fread(param_data.data(), sizeof(float), num_floats, fp_in); + + // 2. 确定维度信息 (借鉴旧代码逻辑) + // 'vl' 标志和 'visual' 层名的判断 + bool is_visual = find_in_layers(name, {"visual"}); + int H = is_visual ? vit_tmp_hidden_dim : tmp_hidden_dim; + if (H <= 0) { + std::cout << "FAIL! Hidden dimension not found for " << name << std::endl; + __exit(-1); + } + // 根据层名决定 K 的值 + int K = H; + if ((is_visual && find_in_layers(name, {"fc2", "down_proj"})) || (!is_visual && find_in_layers(name, {"w2", "down_proj"}))) { + K = num_floats / H; + } + + // 3. 分配量化空间并执行量化 + auto block_t = alloc_quant_block(num_floats, final_quant_type); + void *quant_ptr = block_t.first; + + // 调用与旧版本中类似的函数 + quantize_row_q4_0_4x4(param_data.data(), quant_ptr, num_floats, K); + + // 4. 写入量化数据块 + writeChunk(quant_ptr, block_t.second); + delete[] (char *)quant_ptr; + } else { + uint64_t floats_processed = 0; + while (floats_processed < num_floats) { + uint64_t floats_to_read = std::min((uint64_t)CHUNK_SIZE_FLOATS, num_floats - floats_processed); + if (floats_to_read == 0) break; + + fread(read_buffer.data(), sizeof(float), floats_to_read, fp_in); + + auto block_t = alloc_quant_block(floats_to_read, final_quant_type); + void *quant_ptr = block_t.first; + + switch (final_quant_type) { + case MLLM_TYPE_Q4_0: quantize_row_q4_0(read_buffer.data(), quant_ptr, floats_to_read); break; + case MLLM_TYPE_Q8_0: quantize_row_q8_0(read_buffer.data(), quant_ptr, floats_to_read); break; + case MLLM_TYPE_Q2_K: quantize_row_q2_K(read_buffer.data(), quant_ptr, floats_to_read); break; + case MLLM_TYPE_Q2_0: quantize_row_q2_0(read_buffer.data(), quant_ptr, floats_to_read); break; + case MLLM_TYPE_Q3_K: quantize_row_q3_K(read_buffer.data(), quant_ptr, floats_to_read); break; + case MLLM_TYPE_Q4_K: quantize_row_q4_K(read_buffer.data(), quant_ptr, floats_to_read); break; + case MLLM_TYPE_Q6_K: quantize_row_q6_K(read_buffer.data(), quant_ptr, floats_to_read); break; + case MLLM_TYPE_Q8_K: quantize_row_q8_K(read_buffer.data(), quant_ptr, floats_to_read); break; + default: + std::cerr << "Unsupported quantization type in streaming loop: " << DataTypeName(final_quant_type) << std::endl; + delete[] (char *)quant_ptr; // 避免内存泄漏 + __exit(-1); + } + + writeChunk(quant_ptr, block_t.second); + delete[] (char *)quant_ptr; + + floats_processed += floats_to_read; + } + } + + endWriteParam(); + std::cout << "Done." << std::endl; + } + + writeIndex(); +} +} // namespace mllm \ No newline at end of file diff --git a/src/quantizer/QuantWriter.hpp b/tools/quantizer/QuantWriter.hpp similarity index 67% rename from src/quantizer/QuantWriter.hpp rename to tools/quantizer/QuantWriter.hpp index df2967383..86ab5037e 100644 --- a/src/quantizer/QuantWriter.hpp +++ b/tools/quantizer/QuantWriter.hpp @@ -1,17 +1,21 @@ #include "ParamWriter.hpp" #include "ParamLoader.hpp" -#include "backends/cpu/compute/QuantizeQ6.hpp" -#include "backends/cpu/compute/QuantizeQ2.hpp" -#include "backends/cpu/compute/QuantizeQ3.hpp" -#include "backends/cpu/compute/QuantizeQ4.hpp" -#include "backends/cpu/compute/QuantizeQ8.hpp" -#include "backends/cpu/compute/GemmPack.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ6.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ2.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ3.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ4.hpp" +#include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" +#include "backends/cpu/third_party/ggml/GemmPack.hpp" #include "backends/cpu/compute/GemmKleidiai.hpp" #include #include #include +#include +#include + #ifndef MLLM_QUANTWRITER_HPP #define MLLM_QUANTWRITER_HPP + #define NOT_IMPLEMENTED(x) \ std::cout << "Quantize params to " << DataTypeName(x) << " is not implemented\n"; \ __exit(-1); @@ -26,6 +30,7 @@ } \ exit(status); \ } + static std::pair alloc_quant_block(uint64_t count, DataType type) { uint64_t size = DataTypeSize(type, count); if (size <= 0) { @@ -38,7 +43,12 @@ static std::pair alloc_quant_block(uint64_t count, DataType ty #if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) static std::pair alloc_kleidiai_quant_block(DataType type, int N, int K) { assert(type == MLLM_TYPE_KLEIDIAI_Q4_0); + +#ifndef KAI_FP16_CAL uint64_t size = mllm_kleidai_get_packed_b_qsi4_size(N, K); +#else + uint64_t size = mllm_kleidai_get_packed_b_qsi4_size_to_fp16(N, K); +#endif if (size <= 0) { return std::make_pair(nullptr, 0); } @@ -46,30 +56,26 @@ static std::pair alloc_kleidiai_quant_block(DataType type, int return std::make_pair(data, size); } #endif + namespace mllm { -extern std::vector vl_q4x4_2_q4_k_layers; +extern const std::vector q4_0_kai_to_q4_0_4x4_layers; class QuantWriter : public ParamWriter { public: ~QuantWriter(); explicit QuantWriter(std::string output_path, std::string input_path); int readParams(); - void quantParams(DataType dataType); - void quantParams_q4_(DataType dataType); - void quantParams_q4_vl(DataType dataType); - void quantParams_kai_vl(DataType dataType); -#ifdef TEST - std::unordered_map data_; + void quantize(DataType target_quant_type, const std::string &other_flag = ""); -#endif private: - string output_path_; - mllm::ParamLoader *param_loader_; - DataType quant_type_; + std::string output_path_; + ParamLoader *param_loader_; std::vector param_names_; - float *getParam(std::string param_name); - void writeParam(string name, DataType type, void *data, uint64_t size) override; + + DataType getQuantizationTypeFor(const std::string &name, DataType target_type, const std::string &other_flag); + + std::vector load_full_fp32_param(const std::string &name); }; } // namespace mllm #endif \ No newline at end of file diff --git a/tools/quantizer/main_quantize.cpp b/tools/quantizer/main_quantize.cpp new file mode 100644 index 000000000..3911233c8 --- /dev/null +++ b/tools/quantizer/main_quantize.cpp @@ -0,0 +1,67 @@ +// +// Created by Xiang Li on 23-10-31. +// +#include "ParamWriter.hpp" +#include "ParamLoader.hpp" +#include +#include +#include "QuantWriter.hpp" +#include "Types.hpp" + +const std::vector vl_q4x4_2_q4_k_layers; + +int main(int argc, char **argv) { + if (argc < 4) { + std::cout << "Usage: ./quantize [other_flag]\n"; + std::cout << " quant_type: Q4_0, Q8_0, Q4_K, Q6_K, Q8_K, Q4_0_4_4, KAI_Q4_0, etc.\n"; + std::cout << " other_flag (optional): 'vl' or 'eager'\n"; + return -1; + } + auto input_path = std::string(argv[1]); + auto output_path = std::string(argv[2]); + auto quant_type_str = std::string(argv[3]); + std::string other_flag = ""; + if (argc == 5) { + other_flag = std::string(argv[4]); + if (other_flag != "vl" && other_flag != "eager") { + std::cout << "Invalid other_flag. Use 'vl' or 'eager'.\n"; + return -1; + } + } + + DataType quant_type_enum = MLLM_TYPE_COUNT; + if (quant_type_str == "Q4_0") + quant_type_enum = MLLM_TYPE_Q4_0; + else if (quant_type_str == "Q8_0") + quant_type_enum = MLLM_TYPE_Q8_0; + else if (quant_type_str == "Q2_K") + quant_type_enum = MLLM_TYPE_Q2_K; + else if (quant_type_str == "Q3_K") + quant_type_enum = MLLM_TYPE_Q3_K; + else if (quant_type_str == "Q4_K") + quant_type_enum = MLLM_TYPE_Q4_K; + else if (quant_type_str == "Q6_K") + quant_type_enum = MLLM_TYPE_Q6_K; + else if (quant_type_str == "Q8_K") + quant_type_enum = MLLM_TYPE_Q8_K; + else if (quant_type_str == "KAI_Q4_0") + quant_type_enum = MLLM_TYPE_KLEIDIAI_Q4_0; + else if (quant_type_str == "Q4_0_4_4") + quant_type_enum = MLLM_TYPE_Q4_0_4_4; + else { + std::cout << "Quant type " << quant_type_str << " is not supported\n"; + return -1; + } + + mllm::QuantWriter quant_writer(output_path, input_path); + int param_count = quant_writer.readParams(); + if (param_count <= 0) { + std::cout << "No params to quantize\n"; + return -1; + } + std::cout << "Quantizing " << param_count << " params to " << quant_type_str << " with flag '" << other_flag << "'\n"; + quant_writer.quantize(quant_type_enum, other_flag); + std::cout << "Quantization finished successfully.\n"; + + return 0; +} \ No newline at end of file diff --git a/vocab/ling_merges.txt b/vocab/ling_merges.txt new file mode 100644 index 000000000..8ab6484a2 --- /dev/null +++ b/vocab/ling_merges.txt @@ -0,0 +1,125824 @@ +Ġ Ġ +Ġ t +i n +Ġ a +h e +r e +o n +ĠĠ ĠĠ +e r +a t +ä ¸ +Ġ s +Ġt he +o r +ï ¼ +e n +Ġ c +e s +Ġ w +i t +i s +o u +a n +ï¼ Į +a l +Ġ f +Ġ p +in g +Ġ o +Ġ b +e d +a r +ç ļ +Ġa n +çļ Ħ +ã Ģ +Ġ m +i on +ä º +l e +Ġ in +Ġt o +i c +Ġ d +Ġo f +Ġan d +a s +â Ģ +r o +ĠĠ Ġ +e t +Ġ h +Ġt h +c t +en t +ãĢ Ĥ +ä » +s t +å ı +æ ľ +e l +ĠĠĠĠ ĠĠĠĠ +o m +i l +Ġ n +Ġ re +Ġ l +è ¿ +å ¤ +å ħ +Ġ e +i d +æ ĺ +v e +a m +Ġ I +Ġ T +Ġ g +Ġ S +o t +å ® +å Ī +i m +ä ½ +Ġ y +Ġ is +o l +å IJ +c e +å ľ +i g +s e +Ġ C +u t +ä ¹ +ä¸ Ģ +Ġf or +o w +a d +Ġ A +at ion +a y +æ Ī +u r +l y +c h +Ġy ou +Ġ ( +æĺ ¯ +Ġ u +Ġ on +Ġb e +ç Ķ +å ° +v er +i f +Ġs t +Ġ = +è ¯ +u l +ç » +it h +Ġth at +å Ĭ +äº Ĩ +ä¸ į +o d +a g +æ Ĺ +Ġ M +æ Ŀ +i r +Ġ P +ãĢ ģ +t er +Ġw ith +æ ĸ +at e +ĠĠĠĠ ĠĠĠ +å Ľ +æ ī +r a +- - +æľ ī +å Ń +åľ ¨ +Ġc on +Ġ it +ä ¼ +å į +e m +è ® +a b +Ġa s +Ġp ro +u n +r i +Ġ B +c k +he r +u m +p e +Ġa l +es t +äº º +å ¹ +Ġ v +âĢ Ļ +âĢ ľ +es s +ou t +er s +å ¾ +q u +é ĩ +p p +å ĩ +n d +is t +Ġ D +u s +Ġw h +Ġw e +å ¥ +å · +il l +Ġ F +e w +t h +å ¼ +Ġ W +âĢ Ŀ +k e +Ġa re +re s +å Ĩ +ou r +Ġ or +Ġ R +è Ģ +ĉ ĉ +an d +Ġc om +ĥ ½ +å ¸ +Ġ H +o re +n t +Ġ he +or t +Ġe x +å º +ĠT he +o p +h t +Ġ L +m ent +Ġd e +è¿ Ļ +o s +æĪ ij +Ġ " +é Ģ +å ¯ +* * +it y +Ġa t +è ¡ +ç Ľ +p t +en d +è µ +l d +ä¸ ª +e ct +. . +/ / +Ġ N +Ġh a +ro m +an t +Ġ { +Ġ r +ä¸ Ń +Ġ * +Ġth is +l o +a in +æ ķ +Ġ E +æ Ģ +è § +Ġ G +å¤ § +æ Ĭ +å Ĵ +æ ł +ar t +Ġs u +ä¸ º +ç İ +i v +å ¿ +å Į +ä¸ Ĭ +ç ľ +i ve +å İ +i es +Ġs e +Ġn ot +Ġb y +æ Ń +Ġw as +é Ĺ +ä» ¥ +æĿ ¥ +in e +ig ht +e x +è ĩ +Ġ - +åĴ Į +u st +ç § +Ġ O +ĠĠĠĠĠĠĠĠ ĠĠĠ +ag e +ä» ĸ +è ´ +Ġf rom +am e +Ġs h +¦ ģ +é Ŀ +u d +u e +Ġc h +æ ĥ +ct ion +æ ² +al l +Ġ $ +æĹ ¶ +Ġc an +Ġha ve +u re +Ġyou r +åĪ ° +æ ° +o o +è ¦ģ +ç ī +i al +i z +p er +å ½ +o c +å ± +é Ļ +æ İ +æ Ķ +åı ¯ +f f +o st +p l +å ij +æ ŀ +u b +å° ± +Ġ le +re d +a c +ä¼ ļ +ar d +æ ³ +ç º +g e +çĶ ¨ +è ĥ½ +el l +ou ld +as s +åĩ º +ab le +âĢĻ s +é ģ +a ck +-- -- +om e +in d +r ou +è ½ +çĶ Ł + ł +Ġu s +id e +in t +ä ¿ +c l +Ġin t +Ġ j +ä¹ Ł +ç Ŀ +æ ĭ +ä» ¬ +ä¸ ĭ +Ġa b +Ġ if +or m +å¯ ¹ +Ġw ill +ic e +ï¼ ļ +ul t +as t +Ġ J +å¹ ´ +æ µ +è ¾ +Ġ k +æ ¯ +a p +å ¦ +Ġd o +Ġp l +a k +ur n +Ġ } +æ Ħ +Ġw or +a re +i p +ç ¬ +å ĵ +ä½ ł +Ġ U +ĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠ +Ġal l +as e +im p +åľ ° +è¿ ĩ +at ed +åIJ İ +b er +åı ij +ç IJ +ç Ń +im e +èĩ ª +Ġa d +å ī +o g +åŃ IJ +ion s +Ġt r +i le +é ¢ +äº İ +Ġn e +ç « +T he +on e +oo k +Ġw he +Ġc l +é ĺ +al ly +è¡ Į +a ct +è¯ ´ +Ġ âĢľ +Ġ ' +æ Į +an s +çĿ Ģ +ic h +c c +t her +Ġm e +c on +' s +Ġcom p +åĽ ½ +it e +e p +åŃ ¦ +æĪ IJ +Ġcon t +Ġre s +å¤ ļ +l ic +ä ¾ +ar y +ä½ ľ +e f +ä¹ ĭ +Ġ en +æī Ģ +æĸ ¹ +a il +ĠI n +å® ¶ +i b +ig n +an ce +Ġh as +e re +e ar +on g +é Ĥ +Ġg o +éģ ĵ +a ce +Ġb ut +å¥ ½ +Ġ out +ç ® +ĠS t +a v +a ke +æ ¬ +( ) +Ġs o +å¾ Ĺ +é ĥ½ +ĠT h +ex t +åĬ ¨ +è Ĥ +r u +ç ½ +g et +r ing +å° ı +ç Ħ +åĪ Ĩ +ç Ĥ +ä¸ ļ +ou s +éĿ ¢ +å Ł +r y +Ġu p +d u +f orm +s o +t urn +æ ¸ +ä¹ Ī +çİ ° +ation s +i re +g h += = +åħ ¬ +æ ± +at a +or d +èĢ Į +ç Ł +Ġm ore +res s +an g +Ġ + +Ġn ew +è · +i a +æľ ¬ +å¿ ĥ +è¿ ĺ +çľ ĭ +å¼ Ģ +a ch +ver y +Ġthe y +å ģ +å Ģ +Ġ \ +æ ´ +Ġ < +ĠĠĠĠ Ġ +el f +éĤ £ +ou nt +Ġthe ir +å® ŀ +çĦ ¶ +S t +çIJ Ĩ +å¦ Ĥ +å® ļ +Ġ V +Ġon e +Ġm y +ent s +l l +æ Ľ +ic al +ç» ı +è¿ Ľ +Ġwh ich +it ion +å¤ © +at h +en ce +å· ¥ +en s +Ġ K +Ġ qu +ï¼ Ł +er v +é ĥ +æ² ¡ +Ġ [ +Ġu n +y pe +Ġg et +j ect +é ķ +ç¬ ¬ +Ġ Y +Ġa r +c om +v el +re e +éĩ Į +é « +i e +I n +Ġ âĢ +od e +åħ ¶ +Ġ & +é« ĺ +é ¡ +è ° +Ġp er +- > +Ġl i +äº ĭ +æ³ ķ +ï¼ ģ +Ġd is +Ġm an +åĬ Ľ +ä½ ĵ +ä¸ İ +** ** +Ġab out +o ve +or y +Ġ our +åī į +æ ı +Ġa pp +ow n +k s +Ġe v +Ġs p +é Ľ +æ į +a u +Ġo ther +p h +il d +on t +å Ŀ +åIJ Į +ä¸Ģ 个 +çŃ ī +æ Ļ +åİ » +éĹ ´ +é £ +çĤ ¹ +ay s +or s +re at +æľ º +Ġan y +Ġt ime +el y +Ġh is +Ġwh o +åIJ Ī +Ġ imp +ou nd +ç ¨ +i ew +é ļ +æĥ ħ +èµ · +ro w +Ġal so +è ī +er t +Ġp art +Ġs c +éĥ ¨ +ar k +å § +è ¶ +ä¸ » +ĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠ +iz e +åħ ¨ +å¾ Ī +ç Ļ +ub lic +f t +Ġof f +Ġwe re +æĸ ° +) . +t e +ing s +æ ģ +è Ĭ +æĹ ¥ +æĥ ³ +e c +ic k +Ġp re +Ġ // +in k +) , +Ġre turn +Ġa g +ç§ į +Ġthe re +äº § +æī ĭ +Ġwhe n +e g +æĢ § +åĨ ħ +: : +ĠC h +ç ¾ +---- ---- +èĢ ħ +o b +å¥ ¹ +å £ +Ġwor k +ĠI t +è º +éķ ¿ +æľ Ģ +éĢ ļ +cl ud +åħ ³ +çĶ µ +Ġs ome +Ġk n +åĮ ĸ +æĹ ł +l ow +ver s +æĦ ı +äº Ľ +å½ ĵ +å° Ĩ += " +Âł Âł +è ¢ +åĬ ł +Ġt e +ç ¤ +åº ¦ +al ue +Ġthe m +ç © +Ġf un +é Ķ +ç Ī +Ġs a +åº Ķ +æ ¶ +Ġo ver +æ Ł +æł · +if f +åı¯ 以 +o v +æĸ ĩ +æĺ İ +o se +é ľ +Ġbe en +et h +o ol +éĩ į +ir st +æķ ° +c es +ä½ Ĩ +å· ± +ri b +Ġw ould +ä¸ ī +pe c +Ġy ear +èº « +ï¼ ī +ol d +Ġa m +è ģ +ç ¥ +è ĭ +Ġh ad +Ġli ke +åı ª +Ġa cc +ï¼ Ī +è Ħ +Ġ ro +æ° ´ +çĽ ¸ +Ġn o +_ t +ul l +Ġth an +ï¼ Ľ +è® ¾ +å¸ Ĥ +w e +u al +å » +èĩª å·± +ter n +le ct +Ġne ed +ä½ į +" , +Ġwh at +åĽ ł +å¤ ĸ +if ic +pt ion +åħ ¥ +æľ Ī +å ķ +_ _ +nd er +y st +åĵ ģ +æİ ¥ +æĪij 们 +y s +at es +Ġp e +( " +Ġu se +ç ĥ +r ic +Ġcom m +ç ķ +éĩ ı +ĠTh is +æŀ ľ +ä» İ +èµ Ħ +at er +é ħ +is h +è IJ +çŁ ¥ +Ġin d +E R +Ġad d +æı IJ +am p +åĪ ¶ +# # +Ġde f +Ġ her +Ġd es +ç ³ +Ġit s +Ġe m +Ġh ow +åı Ĭ +äº Į +Ġf e +a x +ĠW e +æ¯ Ķ +c he +âĢĻ t +å ¢ +r am +pe ct +æĽ ´ +en er +éĩ ij +s et +Ġm ay +æŃ ¤ +Ġs et +o int +Ġint o +å¹ ¶ +w o +åı ¸ +çī © +on s +Ġj ust +åľ º +r it +Ġ i +ç ģ +ç ł +没 æľī +b s +l i +å¤ ´ +é Ĵ +è ĥ +ig h +ment s +n e +æ¬ ¡ +er m +p s +è¢ « +å® ī +ç ¼ +f ter +Ġc ol +yst em +Ġb et +ç® ¡ +p ort +.. . +ä¿ ¡ +c ess +p ut +æ · +ç ± +æŃ £ +ç ´ +s s +åĬ ¡ +æľ Ł +ä¸ ¤ +I N +è¡ ¨ +t y +çĽ ® +Ġre c +æ° Ķ +Ġpro v +ad e +è Ī +ä¿ Ŀ +n ing +ç ĸ +Ġ / +Ġ : +op le +is s +is e +å· ² +c re +i ous +Ġcon s +è £ +an ge +i an +on d +au se +å ĸ +Ġon ly +Ġ @ +æĪ ĸ +T h +l es +åIJ į +æ ¡ +Ġu nder +å¸ ¸ +Ġbe c +ãĢĤ âĢĿ +è® © +Ġas s +ç ¡ +è® ¡ +ä½ ¿ +åĽ ŀ +Ġd iff +at ing +e v +ri v +ar am +a w +Ġp r +ç ² +i x +O N +Ġf irst +ĠâĢ ĵ +Ġa ct +Ġ | +Ġb u +i el +u p +éĹ ® +f ul +' t +Ġhe l +å¹ ³ +ç¨ ĭ +ä» Ģ +t ing +åį ģ +o id +ç³ » +åĮ º +rou nd +åħ¬ åı¸ +ä» ¶ +ç Ĺ +å» º +Ġkn ow +æĦ Ł +Ġt ra +ä»Ģ ä¹Ī +n g +çī ¹ +Ġcl ass +Ġp os +Ġ . +åĪ © +er r +Ġm ake +Ġre g +Ġpe ople +rou gh +è½ ¦ +åIJ ij +b le +Ġ # +Ġthe se +åģ ļ +< / +ãĢ ĭ +al s +èĢ ģ +ãĢ Ĭ +æ » +ç» Ļ +é © +il ity +Ġp ublic +Ġm od +âĢ ¦ +âĢ Ķ +è į +c ed +é ĵ +Ġ im +è§ £ +p r +p ro +it ies +Ġc o +Ġs he +ï¼ļ âĢľ +ç¾ İ +åı £ +æ Ĥ +ĠH e +l ine +s h +å¼ ı +pp ort +Ġin clud +ĉĉ ĉĉ +i ent +o od +åij ĺ +æį ® +h at +è¯ Ŀ +Ġp h +Ġ ke +æ´ » +é ª +Ġt wo +Ġn um +iel d +Ġthe n +çľ Ł +ç» ĵ +ib le +ic s +== == +Ġb ack +b ject +i o +åŁ º +u g +å± ķ +or k +m er +é ¦ +Ġm ost +ra ct +Ġre qu +ot h +Ġsh ould +å¤ Ħ +it s +ul ar +Ġat t +ic t +Ġcon st +å ŀ +Ġpro du +é » +Ġse e +ç ¦ +' , +o k +at ive +èī ² +Ġl ook +Ġs elf +è¿ ° +Ġst ud +æķ Ļ +æī ĵ +ou gh +Ġth rough +ru ct +Ġd ata +Ġf in +ĠC om +w n +ar g +Ġw ant +Ġin v +s elf +ï¼Į è¿Ļ +as ed +R E +ä» £ +Ġv ar +Ġw ell +i ed +ol og +é£ İ +at ch +Ġ* / +u res +åħ ĥ +è Ļ +Ġhel p +ic es +é¢ ĺ +Ġre m +Ġe very +å Ļ +è· ¯ +ar ch +Ġin st +at ic +çĽ ´ +Ġwhe re +f ore +Ġ end +re ad +u es +ĠP ro +d ay +éĹ ¨ +åĪ « +å° ij +æĬ Ĭ +le t +Ġfun ction +ĠY ou +Ġre l +Ġc ould +he d +è§ ģ +S T +å¥ ³ +åı ĺ +Ġs erv +Ġs pec +å Ķ +ol low +ers on +d ef +æĶ ¶ +Ġ el +e ad +æľ ¯ +åİ Ł +A T +il y +d er +ä¸ ľ +form ation +åı Ī +¥ ¿ +he n +Ġsa id +ä»ĸ 们 +åį ķ +ur re +Ġtr ans +**** **** +c y +ä» » +Ġsu ch +Ġ ent +è İ +Ġdiff ere +ĠU n +Ġus ed +o ck +å°± æĺ¯ +rib ut +äº ¤ +Ġex per +çĶ ± +æµ ģ +æ° ij +Ġe ff +ç½ ij +) ) +æĬ Ģ +E x +id ent +èĩ ³ +u ch +åĨ į +éľ Ģ +Ġa fter +if e +as h +è ¥¿ +Ġre ad +m s +Ġin ter +_ d +ow er +æī į +Ġs m +s p +Ġ very +æľ į +o x +çĻ ½ +è£ ħ +en g +çº ¿ +at or +æĶ ¾ +å¼ º +åĻ ¨ +åħ ī +in ess +Ġr ight +çľ ¼ +n ce +Ġw ay +ĉĉ ĉ +Ġst art +Ġres ult +Ġf ind +Ġd et +Ġa c +Ġman y +it t +an y +r ay +( ' +c ri +ï¼Į ä¸į +Ġev en +ç ĭ +p os +ï¼Į æĪij +Ġgo od +a ve +ã ģ +w ard +æ ® +n ame +.. .. +P ro +è´ ¨ +ation al +éĢ ī +a ir +å Ħ +e e +åIJ Ħ +ag es +Ġbec ause +å® ¹ +ç½ ® +Ġl ong +n er +A R +ç¥ ŀ +ak ing +Ġ x +ä¼ ł +å® Į +al th +å£ ° +t o +i ence +ar s +æĮ ģ +ĠI f +_ s +åı Ĺ +åħ Ī +{ \ +Ġdo es +æµ · +vel op +ĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠ +a pp +å¸ Ī +Ġc all +Ġn ow +åĩ ł +å¸ ¦ +æ± Ĥ +t t +è¯ ¥ +Ġd id +å·¥ ä½ľ +Ġm in +d d +åħ · +lo ck +ç« ĭ +æ º +Ġex t +å¤ ĩ +åŀ ĭ +Ġ ra +ur ing +Ġpl ay +Ġf ollow +è½ ¬ +Ġp res +` ` +f ig +åĦ ¿ +E N +our ce +Ġp ol +Ġc he +ä¹ ¦ +æł ĩ +ut h +è¿Ļ 个 +it ed +an k +l ed +æł ¼ +en se +æĢ » +å½ ¢ +ä¸ ĩ +rou p +lo g +Ġyear s +ot her +ï¼Į ä½Ĩ +Ġl oc +ç» Ħ +è¿Ľ è¡Į +O R +Ġd on +åĽ Ľ +é Ł +al e +ç§ ij +c o +Ġh igh +in s +Ġsh ow +è¿ ŀ +ç» Ł +Ġg reat +Ġ= = +t he +us iness +t s +æĬ ¥ +åĢ Ļ +æĮ ĩ +Ġt est +èµ ° +æ¸ ħ +Ġg u +å± ± +æ £ +le ment +Ġfor m +åĮ ħ +éĿ ŀ +è Į +el s +ç± » +Ġc re +ire ct +Ġd own +åĽ ¾ +ect ion +th is +. com +Ġ _ +ä» · +æĪ ĺ +v iew +g ram +Ġo wn +å¤ ª +è¿ IJ +ç¤ º +e ver +v ent +é¡ ¹ +Ġs ystem +Ġh im +m a +Ġhe re +Ġde c +urre nt +æģ ¯ +æ¯ ı +p en +Ġus ing +we en +ol ut +ä½ ķ +æ ¨ +I t +å½ ± +I T +Ġv alue +Ġm uch +Ġe ach +W e +Ġex p +å¯ ¼ +æ ¼ +Ġm on +C ont +iz ed +ç© º +t r +eth od +å ² +A L +imp ort +in es +³³ Âł +ä¸ ĸ +at ure +Ġst r +Ġimp ort +Ġre f +re turn +_ p +æĶ ¿ +Ġc our +åķ Ĩ +è® ¤ +Ġin formation +Ġth ink +è ± +_ f +I D +am es +è§ ī +Ġb el +con d +_ m +æĹ¶ éĹ´ +çİ ĭ +Ġs ign +åŁ İ +Ġsu b +ĠA nd +ç¡ ® +ä¸ ĵ +æ ij +Ġn ame +è° ĥ +Ġf l +èĢ ĥ +in ed +Ġd ist +. get +ä¸į æĺ¯ +_ c +æŃ ¥ +è¾ ¹ +Ġp erson +ce pt +å ĥ +ç ħ +o f +Ġdiffere nt +-------- -------- +æĸ Ļ +è§ Ħ +æķ ´ +ĠA n +S E +Ġch ar +ĠF or +å¿ « +Ġb est +è® ° +Ġbet ween +Ġl ist +Ġs ur +o y +Ġbe fore +Ġag ain +an n +éĻ ¢ +y m +æīĢ è¿° +è¯ ģ +g ht +ä¾ ¿ +èĬ Ĥ +Ġh and +g an +ark et +p on +Ġc or +f o +ĠE x +u ally +re f +ç® Ĺ +ad d +èĤ ¡ +Ġa v +äºĨ ä¸Ģ +æ ¢ +Ġc ase +Ġbe ing +ç Ĭ +t en +æĪ · +Ġg ener +im es +çº § +ä¸Ń åĽ½ +em ent +å ¨ +å·² ç»ı +y n +i red +Ġnum ber +in ce +er y +æĹ¶ åĢĻ +åı ĸ +æķ Ī +y p +ar n +æł ¹ +N ame +ä¸ Ķ +ch n +Ġg r +Ġt ake +C om +Ġth ose +ĠA r +L E +as on +å® ĥ +C h +ï¼Į åľ¨ +A N +æ³ ¨ +t on +Ġd ay +ĠA l +Ġ ! +Ġwh ile +å¼ ł +ä» Ĭ +Ġv al +an c +éĽ Ĩ +em ber +çŁ¥ éģĵ +- b +e k +ĠS h +Ġp oint +åį Ĺ +Ġpro cess +Ġm ed +T ype +ust om +. m +Ġ Q +od y +Ġin s +åĩ Ĩ +ĠN ew +å¦Ĥ æŀľ +Ġs er +Ġb l +id er +Ġde velop +. S +re n +éĺ Ł +e b +ç¬ ij +. s +Ġf act +Ġm ade +éĢ ł +Ġs ame +åĨ Ľ +èģ Ķ +Ġst ate +amp le +ï¼Į ä»ĸ +è ħ +çļĦ 人 +ate g +æĿ ¡ +é ¥ +Ġs om +al ity +n ess +iv es +åı į +Ġsu pport +C on +h ip +èĬ ± +åį ´ +åŃ ĺ +åĥ ı +ou se +e qu +第 ä¸Ģ +åı ° +al k +Ġp ost +ç ª +è§ Ĩ +ang u +w ay +çĪ ± +éļ ¾ +æĺ ĵ +è¾ ¾ +æ ħ +Ġv is +r ight +ction s +St ring +é© ¬ +if y +ra ph +æŀ Ħ +åĮ » +Ġc ar +åĽł 为 +ä½ ı +ç¦ » +. " +æĶ ¯ +_ { +Ġf il +æĿ ĥ +Ġf ound +çݰ åľ¨ +è´ ¹ +çIJ ĥ +äº Ķ +Ġc ount +ĠĠĠĠĠĠĠĠ Ġ +æĬ ķ +ç² ¾ +Ġ ed +ç¤ ¾ +t ain +Th is +v al +Ġp at +i et +I d +è¾ ĥ +lo ad +Ġar t +æİ § +å¤ į +Ġwor ld +éĻ IJ +i er +e red +at her +w are +ant s +åı · +åĢ ¼ +æĸ ½ +a z +Ġel se +å§ ĭ +Ġ > +ch ool +Ġb oth +æ ļ +Ġl ast +è¿ ij +Ġb usiness +_ C +Ġ ï¼Į +æĪ ¿ +çķ Į +ï¼Į ä¸Ģ +ï¼Į èĢĮ +Ġf am +re am +le ase +åĬ Ł +Ġ= > +åĨ µ +Ġprodu ct +a h +ĠA s +çĥ Ń +ro l +Ġl ife +al se +æĢ Ŀ +_ b +æĸ ¯ +ä¾ Ľ +éĹ® é¢ĺ +l and +æ¨ ¡ +a ult +Ġprov id +åĪ Ļ +v en +Ġa p +ion al +åŃ Ĺ +æ· ± +ä¾ ĭ +åı Ĥ +åĪ Ľ +æ² » +Ġre p +Ġ err +ak es +èIJ ¥ +Ġle t +- s +åIJ ¬ +éľĢ è¦ģ +åĮ Ĺ +å¢ ŀ +ter s +åĬ ŀ +Ġr un +çĹ ħ +Ġh ome +æĿ ¿ +. p +Ġs k +éĢļ è¿ĩ +æ¶ Ī +çİ ¯ +. c +æĢ İ +åĨ ³ +è¯ · +Ġb ook +riv ate +ï¼Į ä½ł +ä¼ ģ +angu age +m in +Ġc le +åij ¨ +Ġm ust +Ġt ype +çī ĩ +åij Ĭ +æ Ĵ +a red +è¶ Ĭ +as k +e y +i vers +ou n +Ġdes ign +æº IJ +um ent +Ġde p +. d +éĺ ² +ot e +Ġeff ect +æ¸ ¸ +R es +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +ĠĠĠĠ ĠĠ +Ġch ild +olog y +è¯ Ń +çļĦ ä¸Ģ +Ġapp ro +cc ess +Ġle ad +ç« ł +u c +åį ³ +çł Ķ +Ġpro gram +ere st +å® ¢ +é¢ Ĩ +æĶ ¹ +ar m +he s +Ġin f +l ess +Ġre ally +ï¼Į ä¹Ł +使 ç͍ +Ġpart ic +: // +è® º +ĠH ow +s on +Ġe qu +st r +w ays +Ġp ur +ä¼ ĺ +ĠB ut +Ġpos s +å¹ ² +å¸ ĥ +ent ial +éħ į +in al +ess age +er n +å ĭ +T o +è¿ĺ æĺ¯ +è§ Ĥ +et s +ist s +è¯ Ĩ +Ġwith out +åı¯ èĥ½ +Ġto p +管 çIJĨ +æ¡ Ī +åıij å±ķ +it al +ä¹ ł +è ¨ +å¹ ¿ +Ġtr ue +if ied +Ġm ain +æİ ¨ +Ġo b +Ġb re +Ġm at +Ġst ill +æŀ Ĺ +Ġcomm un +æĬĢ æľ¯ +ä½ İ +I C +Ġd el +æŁ ¥ +æľ ª +è® ® +Ġc are +E S +Ġv oid +éĢ Ł +åİ ĭ +ĠD e +f or +iv en +A C +ĠC l +æł ¡ +" > +Ġdis c +iz ation +æ ¥ +è¯ ķ +Ġa round +Ġre al +è® ¸ +Ġ z +us s +as es +Ġqu est +ĠC on +u ff +æ» ¡ +ro ss +åIJ § +ĠT r +é ¾ +è¨ Ģ +ri end +æīĢ ä»¥ +éļ ı +Ġpro f +å¿ ħ +} } +Ġe as +éŁ ³ +åij ½ +c ent +- t +åΰ äºĨ +Ġtr y +g g +A r +op y +p aram +Ġf ree +st and +Ġl o +Ġgo ing +Ġo pt +Ġpro per +in ing +lo y +ä¼ģ ä¸ļ +åŃ © +å° Ķ +v ing +è½ » +ĠP l +Ġ$ \ +ç ı +åį İ +er g +å¤ Ł +ä¹ IJ +ce ption +ĠS e +ç» Ń +] . +o ot +æĺ ¾ +eng th +åħ ± +m ber +çĻ ¾ +æľ Ľ +- d +Ġm arket +Ġm em +Ġw rit +Ġs ay +Ġp ass +Ġcon f +çİ ĩ +ç« Ļ +Ġin cre +// // +r id +æľį åĬ¡ +å¾ ® +Ġ ) +è¿Ļ æł· +æ IJ +. , +æŃ » +ĠW h +is ion +æĬ ¤ +åĽ ¢ +Ġt ri +b ers +r ite +Ġto o +os s +m an +éĻ ¤ +æĢ ģ +are nt +_ S +Ġte chn +Ġle vel +Ġad v +L ist +ĠS o +Ġor der +he re +ĠThe y +o ver +Ġpl ace +i qu +Ġall ow +æŀ ģ +un d +Ġhe alth +èĤ ² +ail able +Ġpro ble +Ġc urrent +m l +å¼ ķ +åIJ ĥ +i k +çº ¢ +Ġo per +Ġsm all +æĸ Ń +Ġcont in +å¾ · +## ## +ĠThe re +Ġse cond +å ĺ +Ġpro t +en cy +_ P +æĢİ ä¹Ī +le ction +i ents +Ġper form +ver t +Ġth ree +" : +Ġmon th +æµ ĭ +] , +is hed +s c +Ġ % +å£ « +è· Ł +ind ow +Ġha pp +Ġte am +ç ¢ +åĬ © +is m +èµ Ľ +us h +å¤ ± +Ġt erm +w ork +Ġl anguage +Ġf ile +v ed +==== ==== +ab ility +人 çļĦ + · +ur al +Ġd uring +Ġl ot +Ġo pen +çģ « +y le +Ġis s +itt le +le x +s w +ar ly +ou ght +èĩªå·± çļĦ +Ġbu ild +åı ĭ +ut e +Ġl ove +Ġ Z +- f +ro ll +å ¡ +Ġ X +æĭ ī +è ı +ar get +åħ ĭ +Ġl ine +u le +ä¸Ń çļĦ +åĵ į +bs ite +um m +æĥħ åĨµ +t ext +Ġc ent +Ġm ethod +Ġn ext +b e +ä¹ ī +å¾ Ģ +éª Į +çħ § +æ® µ +n ot +em s +Ġ , +cri pt +ä¿ ® +m p +Ġf ew +m ath +D ata +re m +è¶ ³ +æ¸ © +th ing +Ġc ustom +def ine +é£ Ł +Ġre port +ĠR es +iv id +Ġ est +Ġan al +ï¼Į å¹¶ +æ ¹ +A S +Ġth ings +åº ķ +[ ' +W hat +Ġre st +Ġm et +w w +eth ing +Ġre ce +第 äºĮ +uth or +A n +å± Ģ +æĺ¯ ä¸Ģ +è¿ ľ +Ġhe ad +_ l +âĢĻ re +a j +le te +Ġd irect +èµ· æĿ¥ +æī ¾ +ç Į +Ġp ay +it ions +r ation +r al +D E +r r +p ar +ç§ ° +pon se +ï¼Į éĤ£ +å¢ ĥ +Ġint erest +at t +ra w +èİ · +o ard +éĢ Ĥ +Ġst ring +Ġpro ject +ä» ½ +n ect +ĠR e +è± ¡ +at us +Ġke ep +A M +Ġ et +Ġpl an +ĠT o +re g +ab el +Ġbet ter +Ġst and +æİ Ĵ +é¦ ĸ +Ġfe el +iv ing +d s +r on +äº ² +mer ic +st ring +. h +æĿ İ +ĠI nd +èIJ ½ +cl ass +åĪ ĩ +A s +" ) +çľ ģ +å± ŀ +l ing +ç© ¶ +Ġ ide +er ing +a ut +Ġm ight +s er +åĸ ľ +éĺ ³ +pl ay +Ġal ways +çĬ ¶ +ot t +iss ion +ï¼Į å°± +çĶ · +ert ain +ä¼ Ĺ +G et +ĠI s +- m +Ġn ull +ç» Ĩ +i or +Ġs it +. C +åķ Ĭ +ic ally +b y +Ġche ck +R O +æĿ IJ +L L +Ġwe ek +éĥ½ æĺ¯ +Ġf r +åij ¢ +Ġs l +Ġex pl +n ew +éĩ ĩ +åIJ Ĺ +v es +å· ŀ +Ġimport ant +ĠO n +æ± Ł +éĻ ħ +. t +b ack +æ¬ ¾ +Y ou +èĩ ´ +Ġc r +com m +' ] +S h +ic le +ç» ´ +ra c +ç± ³ +å± Ĥ +lo b +æ ĵ +Ġex pect +äº ij +_ T +åĬ ¿ +Ġ â +Ġs ize +çļĦ æĹ¶åĢĻ +Ġke y +Ġs im +产 åĵģ +è¶ ħ +Ġs oc +åħ » +å¼Ģ å§ĭ +çº ¦ +Ġinclud ing +. f +Ġexper ience +ç» Ī +Ġn on +ç« ¯ +ç´ ł +I f +Ġc ook +I S +Ġl ittle +â̦ â̦ +} $ +Ġp ut +Ġfollow ing +é¢ Ħ +Ġsom ething +Ġav ailable +I ON +( $ +çŁ ³ +Ġan other +Ġ// / +åį ĩ +Ġp ower +Ġpres ent +ĠS p +Ġb r +Ġs ince +c al +ĠC ol +Ġcon d +ĠA ll +ç³» 绣 +at ely +ç ¿ +Ġserv ice +Ġor gan +vers ion +Ġg row +iv ely +ç® Ģ +i um +o h +åı Į +Ġa ut +Ġapp lic +Ġf ield +å © +éĿ Ĵ +or n +f ace +at s +, âĢĿ +Ġar g +æĺ Ł +åħ¶ ä»ĸ +r ist +èĦ ¸ +et er +ar ge +F or +d ate +Ġp rivate +- c +ï¼Į 以 +æ¬ ¢ +Ġl aw +oc i +çĶŁ æ´» +ä¿¡ æģ¯ +olut ion +it ive +Ġa ff +Ġprov ide +Ġw ater +åİ Ĩ +Ġo bject +Ġwith in +è ŀ +re en +ï¼Ł âĢĿ +Ġd i +Ġsu re +ĠS he +. g +a f +one y +ĠP h +******** ******** +E D +v ious +å Ĥ +Ġsu pp +u ck +å ł +Ġ -- +g er +Ġo ld +_ M +re qu +ï¼Į âĢľ +C T +_ n +Ġinv est +æķ° æį® +Ġon line +Ġde v +ĠW hat +ir on +æĹ © +åĩ » +Ġg roup +F F +è¿Ļ äºĽ +è¡ Ģ +ere nce +Ġ ve +# define +av a +Ġcom e +Ġl ess +ç§ ¯ +U T +Ġ! = +ã Ĥ +or ies +Ġc ost +Ġm ult +Ġv iew +ĠS c +åį Ĭ +Ġman ag +a it +Ġne ver +Ġadd ition +Ġwe bsite +é¾ Ļ +ĠA d +/ * +ail s +Ġs imp +du ct +æĿ ij +æķ ħ +åĪ ļ +ht t +å® Ŀ +æĮ ī +æ£ Ģ +Ġt em +um p +ĠA meric +Ġin c +in ation +çļĦ æĺ¯ +é» ij +) ; +Ġem p +V iew +Ġf riend +Ġcomp any +Ġg ot +Ġb ig +è´ £ +é Ń +iv ity +éĻ © +con st +Ġs pe +^ { +Ġacc ess +m ed +Ġg ive +ain s +re t +åŃ© åŃIJ +it le +èģ Į +æĻ ¯ +C l +èĻ ½ +ro p +v ar +Ġc ell +Ġfam ily +å¾Ī å¤ļ +un ction +Ġch ange +å¸Ĥ åľº +èĭ ± +od el +ä¸Ĭ çļĦ +è§ Ĵ +Ġmod el +Ġm ov +u ild +åĪ Ĺ +ĠâĢ ĺ +ä» ħ +clud e +Ġunder stand +大 çļĦ +éĶ Ļ +V alue +T r +Ġg iven +our s +Ġ Ð +a pe +Ġap pe +ra p +C ol +èĪ ¬ +l er +ivers ity +Ġch ang +ä¾ Ŀ +âĢĶ âĢĶ +A P +ent ion +ï¼ģ âĢĿ +Ġst ruct +( f +g le +o pe +v alue +Ġs chool +åĽ ´ +Ġfin al +ke y +åĿ Ĺ +w it +erv ice +Ġres p +un e +Ġh ard +i en +- p +u se +a im +ĠU S +Ġab le +Ġre se +æĭ © +ial ly +ï¼Į æľī +Ġf ull +Ġs ing +æıIJ ä¾Ľ +( s +好 çļĦ +a pt +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠ +ac y +åĪ Ĵ +Ġst atic +iv ed +Ġl im +ĠA pp +id th +ic y +, " +æĭ ¬ +ur s +an ag +as ter +( t +Ġg ame +Ġas k +éĶ Ģ +主 è¦ģ +c ul +ä¹Ł æĺ¯ +ater ial +åIJĮ æĹ¶ +Ġp op +æ² ¹ +in ter +è ij +æł¹ æį® +E T +éĢ ģ +å§ Ķ +ä¸į èĥ½ +an e +end ing +ress ion +éĿŀ 常 +éħ Ĵ +æ¼ Ķ +Ġloc al +ent ly +if t +Ġcre ate +ĠT e +p or +Ġin tern +ĠS u +åĩº æĿ¥ +A D +Ġle g +Ġd ays +è´ Ł +Ġd em +Ġw om +å¸ ® +ç Ĩ +èį ¯ +it or +大 å®¶ +Ġf alse +ä»ĸ çļĦ +æī ¿ +Ġus er +ï¼Į åıª +éĴ ± ++ + +ç´ § +Ġl og +çĽ Ĭ +èĮ ĥ +Ġt urn +é£ ŀ +op t +u f +ä¸į ä¼ļ +Ġh um +å® ¤ +åĨ · +è¿ĺ æľī +Ġbe h +B y +ess ion +Ġg l +U n +ĠCom m +åĪ Ŀ +åĨ Ļ +ä¸ĸ çķĮ +Ġagain st +ï¼Į æĺ¯ +é» Ħ +Ġev ent +Ġb as +åŁ Ł +ä¹ĭ åIJİ +æµ İ +Ġ  +Ġimp ro +Ġ ` +ic ense +ir d +it her +æĸ¹ æ³ķ +is ter +èĥ½ å¤Ł +Ġen g +res ent +ot s +Ġ ident +Ġl ight +ft ware +é ¸ +éĢī æĭ© +åĮħ æĭ¬ +Ġex ample +`` ` +rr or +act er +Ġ& & +Ġstud y +ab ly +cri ption +ac he +Ġre t +à © +Ġb ased +Ġc ap +a ction +Ġb en +è¾ ĵ +ĠB e +ä¹ ° +åĵ ª +in a +åı ¤ +çķ Ļ +Ġcont rol +con t +Ġle ft +ri es +项 缮 +Ġposs ible +Ġspec ific +l ish +çĸ Ĺ +Ġn et +oc us +äº ¬ +. A +ie ve +lo se +ide o +对 äºİ +è¦ģ æ±Ĥ +ord ing +Ġs ol +çłĶ ç©¶ +Ġp ar +is ed +å° ½ +Ġt yp +at ures +åħ Ń +Ġs ite +che s +ä¸į åIJĮ +Ġacc ount +åĪ » +ï¼Į åħ¶ +ou ble +ä¼ ¤ +v iron +Ġresult s +Ġcour se +åĽ½ å®¶ +H E +Ġme an +æĬķ èµĦ +ĠL et +d ata +Ġ es +è¯ Ħ +çª ģ +é¢ Ŀ +æīĢ æľī +å¯ Ĩ +ä¼ ¼ +ĠâĢ Ķ +} \ +ĠO r +äº ļ +b r +ĠN o +ĠC ont +ric t +} { +c rib +Ġserv ices +å± ħ +æĸ¹ å¼ı +_ F +Ġu nt +åį ¡ +Ġc al +pl ace +Ġgo ver +åº Ĺ +_ id +å® ĺ +åĿ ĩ +Ġsu ccess +ivid ual +Ġj ob +Ġp ract +ãĢ Ģ +æį ¢ +Ġp a +Ġare a +v oid +out h +éĩį è¦ģ +åħ ħ +çŃ Ķ +id d +çī Į +ç½ Ĺ +our ces +åº ľ +æ´» åĬ¨ +A l +æĤ ¨ +åħ ´ +âĢĻ ve +ar ing +end ed +å· ® +lob al +ur y +Ġ Î +Ġpro m +è¯ » +t a +an ces +Ġt ext +iqu e +le g +åĨ ľ +ir c +Ġt reat +ç» Ŀ +设 计 +Ġin it +Ġwork ing +æİ§ åζ +社 ä¼ļ +Ġcont ent +Ġm us +ãĢĤ åľ¨ +U R +m e +r ad +ĠSt ring +ç¾ ¤ +o ber +I nt +pl es +Ġre view +um n +å®ī åħ¨ +åı ² +ure d +åį ĥ +Ġf ac +éĥ¨ åĪĨ +ĠB l +u ly +åĽ º +ã ĥ +ç¼ ĸ +ific ation +read y +çĽ ij +ill s +. l +Ġb ro +b ook +f rac +ĠM ay +o le +c ode +å½± åĵį +çļ ® +E n +åľ Ł +in c +Ġle arn +O T +Ġp ot +or g +ul ation +Ġrequ ire +I M +两 个 +çī Ī +ĠTh at +w ord +ard s +ra in +æĸ¹ éĿ¢ +Ġbre ak +Ġh ist +ill ion +å¾ ħ +S et +èī º +ï¼Į 她 +oc ument +I nd +in it +æŃ ¦ +Ġemp loy +Ġex c +he ad +Ġm aking +æŃ ¢ +O bject +. b +Ġe lect +am b +Ġt imes +ag s +ur ity +åĩ ı +åħ « +åIJ ¦ +ä¸Ģ äºĽ +g in +u ro +åĽ Ń +H ow +Ġo cc +Ġcons ider +ä¹ İ +æĪij çļĦ +Ġwh y +ore d +è¿Ļ ç§į +èĭ ¥ +Ġinclud e +O n +ap s +is ing +um e +åħ į +I m +为 äºĨ +Ð ° +é¦ Ļ +æĪ ı +åѦ ä¹ł +id ence +çİ © +åij ³ +IN G +i ke +Ġm oney +å¤ « +Ġse c +ur ther +Ġan sw +I G +en e +åѦ çĶŁ +Ġth ought +Ġb it +i ver +éĻ į +åı ¦ +æĻ º +Ġs ays +Ġli k +åİ ¿ +Ġk ind +iet y +_ st +âĢĻ m +å® ³ +èϽ çĦ¶ +o ff +ĠW hen +æ¯ į +id s +ä» ¤ +æŁ IJ +åı « +æķĻ èĤ² +ne y +Ġf our +ä¸ ¥ +ip s +al es +Ġre du +Ġspec ial +Ġchild ren +' m +ä½ľ 为 +Ġind ividual +ĠW ith +çĶ » +Ġl ow +Ð ¾ +_ D +å¿ µ +Ġc ode +Ġf lo +W h +il es +Ġl arge +o ice +åıij çݰ +and s +é ² +æĭ ¿ +Ġf ood +. n +n ment +Ġrequ est +Ġto t +Ġa way +Ġrec ord +æ² ³ +A B +åĨħ 容 +Ġme ans +çģ µ +ag n +Ġst ep +Ġb ody +Ġproble m +è´ Ń +f er +Ġpro b +ut ure +åģ ¥ +Ġth ing +H e +viron ment +is k +ain t +__ __ +Ġd one +åĩº çݰ +Ġsh ort +() . +ut il +Ġph ot +ct or +çĦ¶ åIJİ +æĿ Ģ +pp ed +Ġp aram +ĠThe se +å¼ Ĥ +( self +pp ing +éĻ Ī +lo c +Ġc reat +Ġquest ion +ign ed +ir t +ĠCh rist +Ġstud ents +è´ ¢ +Ġcall ed +L O +Ġha ving +or th +ys is +ç»ı æµİ +Ġme as +äº ī +Ġal ong +ĠR ep +ĠHow ever +Ġp ast +Ġp ath +åº · +åı ¶ +Ġadd ress +aj or +Ġc ertain +ĠS ystem +pl ic +çł ´ +ect ed +er c +' re +in clude +ä¸Ģ å®ļ +å¤Ħ çIJĨ +ff ic +Ġr ange +Ġme et +i od +ä½ Ļ +Ġlook ing +ĠE n +Ġro om +Ġh ig +ĠM ar +è¿Ļ ä¹Ī +ï¼Į æĪij们 +æĪĸ èĢħ +it er +çĭ ¬ +le y +S S +ç¦ ı +è¿Ļ ä¸Ģ +Ġor ig +æ ¿ +ic ro +Ġerr or +y l +è Ĵ +âĢ ĵ +Ġm ove +A G +.... .... +( m +éĵ ¶ +O M +èŀ į +Ġal ready +E rror +åħ ļ +âĢĻ ll +å¸ Į +Ġse ver +R e +Ġt ell +ä» ĭ +B ut +Ġcomm on +æł ¸ +( p +åį ı +ab les +ight s +ĠC an +Ġof ten +å¥ ĩ +é Ĩ +Ġab ove +S e +Ġrese arch +Ġl a +Ġunt il +ï¼Į åı¯ +A nd +ä¸ ĥ +å¿ Ĺ +ĠE ng +[ i +g round +Ġto day +con om +æĻ ® +è® ² +um ber +æĹ ı +人 åijĺ +m b +éĺ ¿ +che d +Ġdet erm +a i +Ġan n +Ġsa f +K ey +ar ning +èĭ ı +Ġto get +Ġpr int +Ġtoget her +a ff +åĨ ² +Ġ/ * +æľī éĻIJ +ç ĵ +ĠL e +ĠA t +Ġsu per +è Ľ +Ġpartic ular +æĻ ļ +U S +ear ch +c er +Ġf ore +Ġvis it +W ith +Ġperson al +ay er +d e +end s +P l +pr int +è¯ ¾ +Ġp age +è½ ® +èĥ½ åĬĽ +缸 åħ³ +Ġle ast +çļĦ è¯Ŀ +Ġs ide +Ġneed s +åIJ ¸ +ac es +ĠP r +Ġbu y +. j +ä¸ ¾ +å¾ ĭ +Ġre ason +åºĶ 该 +äºĭ æĥħ +ç« Ł +ribut e +è§ī å¾Ĺ +P E +åı ¥ +çľĭ åΰ +al f +ĠA ss +åıij çĶŁ +ĠG od +Ġ id +t ype +re c +l ished +Ġm aterial +Ġan t +Ð µ +Ġp ack +åº ı +åħ µ +id es +Ġwhe ther +s ide +åIJ « +ĠM y +æ ¦ +æĭ ħ +æĿ¥ çļĦ +åį « +F ile +è¡ £ +Ġh old +çŃ ĸ +ar i +l u +os ed +umm ary +ç ŀ +å¦ Ī +åĿ IJ +å¯ Į +c ol +Ġsoc ial +以 åıĬ +s el +en n +Ġsp ace +æľ ¨ +le v +Ġind ust +çĶŁ 产 +Ġben ef +Ġproduct s +j oy +ç» § +Ġp ort +ä¸Ģ æł· +ib ility +Ġd ri +è¿Ļ éĩĮ +æ ¤ +g s +å· ´ +Ġsign ific +åģ ľ +个 人 +ä¸į è¿ĩ +æĵ į +ä¸ĵ ä¸ļ +ĠC ent +å½ ķ +un c +Ġf ocus +ç» ĩ +Ġvar i +åĶ ® +Ġsever al +oh n +orm al +T ext +Ġm en +ur l +in o +. D +ĠD o +ĠM ed +Ġen ough +le an +Ex ception +åĢ Ĵ +æ¿ Ģ +Ġen c +ord er +çĽ ĺ +ver age +Ġf ar +设 å¤ĩ +Ġh ouse +ur ation +æĢ ķ +Ġm ot +. set +Ġtr ad +Ġother s +éĿ Ļ +ar r +Ġd r +æľ Ŀ +oo gle +) $ +ent al +an ks +. M +I s +Ġt arget +Ġm ax +w h +Ġe ither +_ B +缴 æİ¥ +Ġm akes +Ġrequ ired +æĽ ¾ +os p +é º +ä½ł çļĦ +a us +ä¹ Ŀ +ç £ +og raph +çĪ ¶ +) : +res h +ib r +æ¯Ķ è¾ĥ +ĠP ol +åº § +çł ģ +æŀ IJ +Ġ ? +L et +or ld +Ġp ub +Ġinv ol +ä» ĺ +é¡ » +r c +re l +m m +( \ +Ġsing le +Ġact ually +ĠC o +lect ed +Ġ version +Ġcom b +Ġp o +è½ ½ +Ġdevelop ment +ro om +ut es +( d +pp er +å®ŀ æĸ½ +il ar +èĥ Į +U N +é ¼ +st ruct +Ġa uthor +Ġv ol +em pt +äº Ĵ +ä¸ Ŀ +å¾ ģ +Ġ ess +ove mber +en c +ĠCom p +> < +Ġrel ations +Ġ< < +Ġst ory +ĠUn iversity +Ġbec ome +æī § +EN T +è Ĩ +è¿ĩ ç¨ĭ +ä¹ĭ éĹ´ +ä¹ ħ +Ġwor ks +per ty +åŃ £ +ï¼Įä½Ĩ æĺ¯ +eg in +re ct +ĠI nt +ç§ » +. _ +Ġqu ality +éĵ ģ +Ġen erg +I P +. âĢĿ +çݯ å¢ĥ +æ³ ¢ +éĤ£ ä¹Ī +çı Ń +Ġint eg +Ġd ue +ĠI N +Ġoff er +å¤ ľ +åĵ ¥ +Ġdid n +Ġcommun ity +Ġf ail +Ġeas y +è¿ŀ æİ¥ +ä½Ĩ æĺ¯ +åĿ ļ +çľĭ çĿĢ +Ġ: = +ri or +f ect +Ġcon nect +æĪIJ 为 +_ N +im ate +le ft +---------------- ---------------- +大 åѦ +æĸĩ åĮĸ +è´ § +A dd +Ġb ring +sp an +Ġ ... +åħ· æľī +Ġt alk +Ġcl aim +T est +ward s +ĠC he +Ġm ajor +Ġcont ain +æ ½ +( - +Ġto ol +Ġw in +ĠQ u +I L +[ ] +oo se +çŁ Ń +æĦ ¿ +ä¹Ł ä¸į +Ġa ir +e ed +è¡ ¥ +Ġb lock +åĸ Ħ +\ n +Ġo bs +èĦ ij +Ġcour t +Ġ< / +æĺ ¥ +Ġdoes n +.. / +# include +un ity +b b +} , +C H +m it +_ in +on es +å¥ Ĺ +n ow +Ġm ar +Ġdo ing +æ¥ ¼ +Ġe ver +Ġm om +ĠY our +N ew +Ġdist ribut +Ġstr ong +çļ ĩ +y t +Ġpos ition +ens ion +( x +Ġam ount +ĠF r +- l +åħ ° +ä¸Ģ èµ· +ĠC al +建 设 +ip le +å· ¦ +è Ń +Ġt re +Ġmonth s +f ile +u ation +ç© ¿ +Ġm ind +d iv +p le +Ġac ross +cl us +ul es +T ime +t d +O L +Ġem ail +ç͍ æĪ· +Ġa ction +ĠL icense +The re +æĥ Ĭ +Ġh tt +Ġ| | +t ies +ĠSt ate +( n +é ½ +åĸľ 欢 +ĠG et +è° ģ +Ġhum an +ĠĠĠĠĠĠĠĠ ĠĠĠĠĠ +Ġth ough +Ġsignific ant +Ġt able +Ġget ting +æħ ¢ +Ġval ues +æľ ĭ +Ġdisc uss +m ost +åį ° +ĠIn st +Ġrep resent +å¦Ĥ ä½ķ +Ġopt ions +St ate +è Ĺ +åī ¯ +Ġs ource +è® Ń +In fo +å§ IJ +Ġass oci +âĢĿ ï¼Į +æĭ Ľ +ä¸Ń å¿ĥ +ç» ĥ +Ġansw er +o in +åĽł æŃ¤ +çĶ ļ +Ġf uture +le ments +at ors +Ġcomp let +f ort +èĩª çĦ¶ +an u +p x +èī ¯ +Ġon ce +Ġmem bers +Ġbel ow +. P +( c +åĪ ĺ +åħ³ ç³» +é¡ ¾ +ict ion +Ġl ater +Q u +æĢ ¥ +å®ŀ çݰ +et a +Ġres pect +ind ex +ra ft +Ġde al +Ġcol or +Ġcook ies +av or +Ġed uc +ct ober +il ities +ĠA N +Ġex ist +Ġenerg y +ĠC ar +og n +A ll +Ġproper ty +Ġsu gg +A pp +æľī äºĽ +Ġchar acter +ec ut +èŃ ¦ +å® ¡ +Ġsh are +Ġsugg est +åı ³ +Ġs ent +Ġcount ry +Ġc ou +D e +Ġab s +Ġkn own +im al +Ġen joy +ç¥ ¨ +Ġph ys +end er +çº ª +Ġp arent +Ġbe gin +ĠG u +ï¼Į æīĢ以 +åľ° æĸ¹ +ir l +ï¼Į ä»İ +Ġch all +us er +Ġwom en +å² ģ +ro id +u x +Ġl ive +O P +ic ation +æľĢ åIJİ +ak en +ir m +è ĵ +Ġd ig +ä¾ § +//// //// +c le +pr il +ï¼Į 对 +ï¼Į 让 +( b +Ġne cess +Ġar ray +Ġre d +åī § +Ġoff ic +ru ction +Ġen s +R equ +' ve +Ġact iv +Ġ __ +Ġh ours +Ġcont act +æľĭ åıĭ +Ġcom es +Ð ¸ +Ġso ftware +ĠN ot +åį ļ +人 æ°ij +Ġpot ential +éķ ĩ +Ġper iod +O r +ä¸Ģ ä¸ĭ +o ad +Ġtot al +Ġc ur +il t +ãĢ IJ +è¯ ī +U LL +æĿ ¾ +ĠB y +pt ember +ç ij +ce mber +ort s +åŃĺ åľ¨ +å¤ ı +è° ¢ +Ġqu ick +Ġp ress +ãĢ ij +] [ +Ġo pport +is on +Ġcomp ut +ç»ĵ æŀĦ +æŀ ¶ +Ġst re +R ead +ĠO ne +éĴ Ł +ä¸ ´ +in ary +Ġse arch +Ġo ption +at form +ï¼Į è¿ĺ +æĦŁ è§ī +ä¸Ģ èά +éľ ² +r t +ĠD es +Ġb log +ĠUn ited +Ġpat ients +ep end +æ± ī +Ġex am +çķ ¥ +im um +itt ed +Ġcon c +Ġterm s +举 西 +Ġo p +as ing +ri x +r m +- g +( ( +Ġg en +Ġl and +Ġn ight +p ace +E M +Ġimpro ve +Ġass ert +Ġy et +åĵ Ī +æł ij +it es +ug ust +Ġpre vious +çº ³ +ĠA dd +é¢ ij +P h +il i +ol l +Ġe y +Ñ Ĥ +æ¶ ² +Ġpr ice +Ġv ideo +Ġin put +Ġf urther +ç» ľ +åŁ ¹ +r s +Ġim age +ç ĩ +Ġob tain +æį Ł +Ġgover nment +ãĢĤ æĪij +- in +et ers +Ġ à +m y +Ġresp ons +Ġfe atures +op s +Ġl ink +t ime +å·¥ ç¨ĭ +Ġhapp en +è½ ¯ +æ¯ ķ +æ¥ ļ +ro du +Ġc opy +i res +èĦ ļ +Ġdes crib +n ers +Ġc rit +æĶ » +ä¸Ģ ç§į +art ment +err or +Ġrelations hip +' : +Ġen vironment +æľīéĻIJ åħ¬åı¸ +un g +Ġwe b +ĠD is +Ġth row +at ural +anu ary +åıª æĺ¯ +Ġse ason +ĠĠĠĠĠĠĠĠ ĠĠ +åģ ĩ +ç»Ħ ç»ĩ +å¯ Ł +ound s +Ġstr ateg +! ! +Ġdef ault +ra ck +led ge +u ed +Ġprovid ed +éģ ĩ +th ough +- w +é¡ º +Ġres ponse +ç´ ¢ +n ection +od es +ĠG ener +Ġyou ng +ht ml +ãĢĤ è¿Ļ +çĶ ³ +ĠU s +游 æĪı +Ġc red +æıIJ é«ĺ +èĤ ī +éĿ ł +. w +äº ® +ç͍ äºİ +Ġbe aut +说 éģĵ +Ġc ult +ç ¯ +Ġs ym +Ġc ame +at ter +N ot +Ġstart ed +m od +It em +er o +äº « +æĤ £ +ab or +c ing +ur ance +ï¼Į æīĢè¿° +æŃ Į +_ g +our n +g ress +O S +anc ial +Ġm essage +Ġb ase +com p +t ings +å¸ Ŀ +ä¸Ģ 缴 +äºĨ è§£ +_ h +ç¨ ³ +Ġam ong +an ies +åį ł +èĭ ¦ +S o +ä»» ä½ķ +z e +Ġse en +羣 çļĦ +å ³ +åѦ æł¡ +è ĸ +è¯ į +åĩº äºĨ +éĽ ¨ +ou d +ä½ł 们 +Ġgener al +ĠM ore +Ġre comm +Ġvar ious +un ch +- h +Ġr ate +缮 åīį +Ġf ace +ect or +on y +æķ £ +ĠIn tern +Ġsu bject +Ġnew s +pl ate +Ġc amp +认 为 +Ġc ut +Ġe conom +it ut +Ġinst all +æĹ ħ +A d +Ġcon fig +$ $ +Ġag o +æĶ¿ åºľ +N o +Ġpoint s +Ġsim ilar +Ġt ax +å¸Į æľĽ +Ġs w +m at +ĠAmeric an +ess ional +E X +ĠJ ohn +é¡ ¶ +Ġcle an +Ġhe art +indow s +S u +ä»Ĭ 天 +it em +âĢ ¢ +i ans +Ġsimp le +ĠM e +è¡Į ä¸ļ +_ name +Ġth ird +Ġiss ues +Ġe arly +Ġh ot +W hen +ç¾İ åĽ½ +P ath +um ents +Ġh ope +æī ¹ +Ġind ic +anag er +Ġp red +' ll +, æĪij +Ġp ick +éĺ µ +ok en +_ w +å® Ī +Ġl arg +. F +éĢ Ģ +éĽ ª +rou ps +第 ä¸ī +Ġr ad +Ġperform ance +her s +åĬŁ èĥ½ +Ġcomp et +Ġpur ch +P ost +äº ¿ +Ġwho le +Ġmed ia +con fig +æĿIJ æĸĻ +æĿ ¨ +Ġanal ysis +Ġmus ic +b ox +çĸ ij += ' +N ode +åŁº æľ¬ +å¥ ĸ +éĻ Ħ +um b +D es +åĩ Ģ +çİ ī +æľº æŀĦ +. org +Ġapplic ation +Ġrem ain +Ġcom ment +å° Ħ +设 ç½® +çͱ äºİ +æĸ Ĺ +Ġne g +ä¸ĭ æĿ¥ +注 æĦı +ic ult +Ġwrit ing +Ġcle ar +ition al +Ind ex +çĹ Ľ +ç² ī +èı ľ +Ġw rite +s u +Ġper fect +htt p +Ġto ok +ann el +======== ======== +Ġ( ! +Ġc ity +in ks +C C +#### #### +st er +Ġs at +Ġw on +å° ģ +表 示 +ĠR eg +S ize +è´ µ +> +st ance +æ´ Ĺ +Ġw ent +ç¤ ¼ +ĠI m +P aram +ĠA g +æĭ į +Ġhig her +Ġtra ck +éħ ¸ +d o +l t +å¼ Ł +us ing +er al +æĿ¥ 说 +it ing +Ġst ay +è´¨ éĩı +pec ially +O D +ig ure +Con fig +n ces +iv al +Ġquest ions +s ub +Ġsome one +Ġser ies +ix ed +ist ic +ĠO ur +èİ· å¾Ĺ +Ġh ost +c ome +re w +å¨ ģ +ĠP art +Ġro le +ĠĠĠĠĠĠĠĠ ĠĠĠĠ +Ġchang es +éĹ » +èµĦ 产 +åįķ ä½į +è ¸ +å® ģ +Ġm illion +d ing +ov ed +çĸ « +erv ed +ud e +uro pe +y d +Ġd om +éĽ · +èģ ļ +çļĦ 大 +Ġiss ue +æ¢ ¦ +Ġindust ry +æĴ Ń +Ġcan not +f rom +å ª +åŁİ å¸Ĥ +p ose +Ġide a +Ġneed ed +ĠA b +Ġst ore +Ġcont ext +Cont ext +Ġr isk +éĻ Ĩ +è· ij +Ġc ard +Ġbel ieve +Ġd ate +E qu +Ġm or +er a +and om +Ġhist ory +t est +ä¸Ģ 次 +Ġpartic ip +Ġl oss +Ġhow ever +. add +Ġa ge +Ġprovid es +ĠP ost +Ġmin utes +æ¯ Ĵ +Ġmanag ement +Ġv ia +eb ru +U p +å¿ħ é¡» +ĠM in +if ul +éĴ ¢ +Ġw alk +éĤ£ 个 +Ġg ames +åĩĨ å¤ĩ +Ġt aking +I R +Ġc lose +å® £ +æĬ Ĺ +Ġtreat ment +Ġany thing +çĶ ² +ĉĉĉĉ ĉ +ell ing +èĥ ľ +ob ile +T R +yn c +le ge +ebru ary +ï¼Į 为 +\ \ +ç½ij 绾 +L og +ĠSt ates +ph a +or age +Ġcond itions +Ġtra ining +æ¯ Ľ +Ġimp act +Ġout put +Ġst d +Ġs um +h ing +è¿Ľ åħ¥ +ic les +d a +l ist +re p +- st +èĮ ¶ +' ) +Ġde g +ĠR ev +. st +lic k +ĠE d +Ġm ach +çĶļ èĩ³ +ur ch +ä¹ĭ åīį +g ed +ĠA ct +身 ä½ĵ +ä¹ ¡ +Ġf ive +ï¼Į å°Ĩ +æĵį ä½ľ +Ġind ex +A t +å® « +Ġf low +ĠS ee +æİ ī +Ġart icle +uff er +] ( +Ġm iss +åĽ½ éĻħ +Ġb i +æĽ ² +olog ical +æĭ ¥ +. R +Ġd at +Ġnet work +Ġd ouble +Ġup on +ĠG r +Ġf all +ri ed +h ib +Ġac cept +S c +âĢĿ çļĦ +Ġcontin ue +ast ic +ateg ory +çĽ ĸ +æĢ Ģ +Ġincre ase +Ġp ie +ï¼Į å½ĵ +re ate +ç»§ ç»Ń +% % +n a +se c +ĠM arch +Requ est +å¾Ĺ åΰ +ĠA fter +Ð ½ +Ġdet ails +e le +ce ed +Ġimp lement +Ġb ar +Ġcl os +ĠC ount +A b +b egin +b ar +Ġcomp lete +è° Ī +p ack +iz ing +ä»· æł¼ +Ġcomp anies +Ġse em +Ġpa per +Ġper cent +Ġent ire +Ġadd ed +Ġm ass +Ġa ud +Ġw ond +å½ Ĵ +Ġc ases +Ġc irc +Ġpol it +b ol +çī¹ åĪ« +e es +P I +Ġc aus +ĠN ovember +è§£ åĨ³ +ĠS et +Ġtechn ology +b all +缮 æłĩ +ï¼Į å¦Ĥæŀľ +Ġlik ely +Cl ass +Ġreg ard +Ġsystem s +Ġ ver +Ġp rior +æķ ¢ +åIJĦ ç§į +æłĩ åĩĨ +çĻ » +Ġdiff icult +ch o +å¦Ĥ æŃ¤ +Ġp ain +U L +A tt +i ol +y th +ĠD r +æ ĩ +ä¸Ģ æŃ¥ +he l +Ġb ad +D ef +æĹł æ³ķ +Ġlo ad +Ġb o +æ²» çĸĹ +å¼ ¹ +g ing +Ġa ch +sel ves +Ġd am +ĠJ une +Com p +Ġc oun +ç¨ İ +ç¬ ¦ +il s +Ġh alf +Ġpr im +Ġd er +åŁº ç¡ +F ield +Ġne ar +um er +ï¼Į åı¯ä»¥ +Ġst yle +Ġmat ter +åĤ ¨ +m ail +Ġb row +æ± ½ +Ġfriend s +é ± +Ġr ather +id ed +产 çĶŁ +Ġu nd +an ced +ç§ Ģ +i ate +ag ing +Ġwe ight +¤ IJ +Ġproble ms +Ġd ocument +ä¸ ° +O f +av ing +er ver +Ġw ait +åºĶ ç͍ +Ġapp ly +æĽ´ å¤ļ +æ· · +p i +Ġl ength +ig ation +Ġm atch +O ver +b l +Ġto ld +Ġev ents +æ´ ¾ +æķĪ æŀľ +il it +åŁºç¡ Ģ +g o +al t +Ġh om +å° ¼ +å®Į åħ¨ +Ġd en +çī Ľ +htt ps +å© ļ +\ x +Ġwor ds +ãĢĤ ä»ĸ +Ġs ens +åĬ ³ +st atic +ac c +Ġbuild ing +çļĦ å°ı +ç¼ º +ach ing +å½ © +æ² Ļ +é± ¼ +Ġag re +åİ Ĥ +Ġtry ing +ï¼Į ä»ĸ们 +Ġacc ording +éģ ¿ +el t +ç¼ ĵ +çŃ ij +æĹ ¢ +ab led +Ġpre t +åıª æľī +Ġw ays +Ġl ower +L oc +Ġcell s +res ult +éĢ ı +æ° ¸ +F rom +å¿ Ļ +Ġbl ack +lo od +ar ray +ad a +M y +ay out +å¹³ åı° +ace book +Ġt aken +ä¿Ŀ æĬ¤ +åģ¥ åº· +Ġp lease +åĢ Ł +at est +ï¼Į çĦ¶åIJİ +Ġtra vel +è§ ¦ +op er +åĮ» éĻ¢ +æļ Ĺ +min ist +ĠP er +ens ive +åĮĹ äº¬ +èĹ ı +Ġtyp es +ĠSt ud +E L +i ef +Ġle arning +_ H +ĠJ uly +æĢ ª +帮 åĬ© +, åľ¨ +o on +Ġcre ated +åį ĸ +æ» ij +Ġ q +å®ī è£ħ +æĿ Ĥ +or ks +_ r +M ap +S ub +at ory +Ñ Ģ +ĠA pril +Ġd est +Ġa w +æĶ¯ æĮģ +Ġfr ont +ĠO ctober +åħ¶ ä¸Ń +oo lean +un k +ĠC our +Ġcol l +$ , +ĠD ep +ra ce +ass ert +åĽº å®ļ +ç» į +Ġal most +æ¬ § +è¿ĩ åİ» +j ust +çĨ Ł +Ġexper ien +Ġsimp ly +ĠC ity +c ast +O ut +éĶ ® +åĢ º +ac hed +æŁ ĵ +i am +Ġqu ite +s ummary +ĠC or +) ( +å¹´ çļĦ +ç¬ Ķ +op h +åĪ ¤ +) / +ç» ¿ +éĩĩ ç͍ +an a +_t ype +Ġg lobal +se qu +Ġmult iple +tern al +Ġexpect ed +ä¸ļ åĬ¡ +B e +or ing +_ L +çĪ · +Ġem b +Ġb ed +Ġrece ived +O V +o res +客 æĪ· +Ġw atch +å¢ŀ åĬł +. e +ä¸Ģ çĤ¹ +Ġdev ice +Ġs ection +r ong +她 çļĦ +Ġes pecially +Ar ray +èĢģ å¸Ī +ĠE urope +åº Ń +ä½ Ľ +v is +E nt +T M +åħ¶ å®ŀ +Ġor g +a ur +Ġext ra +éĴ Ī +Ġ+ = +å « +ï¼Į åĽłä¸º +代 表 +åĺ ´ +Ġp ict +Ġshow s +æķ ij +Ġoff ers +Ġst e +ĠAr t +éļ ľ +åĵģ çīĮ +ĠC ons +olut ions +wit ter +Ġp ers +m on +m ission +_ IN +ĠSe ptember +计 ç®Ĺ +åī Ĥ +ä¸į çŁ¥éģĵ +ä¹ ± +ĠHe alth +Ġcomp on +ç§ij æĬĢ +å®ŀ éĻħ +ĠDe cember +ĠS m +Ġstand ard +I V +Ġet c +I F +é ¹ +Ġt w +åº Ĭ +é¡ ¿ +Ġs olution +èµĦ æºIJ +容 æĺĵ +æĮ ¥ +Ġdis play +ch an +Ġest ab +yn am +Ġorig inal +Ġcor rect +éĩ Ĭ +ĠR ec +ag ed +ĠW orld +C R +Ġcomp lex +å¼Ģ åıij +om et +éĤ£ äºĽ +erv ices +_ RE +åł Ĥ +b oard +Ġ ãĢĤ +èĦ ± +Ġcom pl +è¯ Ĺ +ä» į +et y +Ġknow ledge +H and +Ġrel ated +R eg +l ight +è ľ +åŃ Ķ +uf act +R ef +pl it +Ġun ique +ç²¾ ç¥ŀ +P L +交 æĺĵ +Ġaddition al +ä»· å̼ +éĿ¢ çļĦ +R ec +åħ³ äºİ +Ġn il +ott om +Ġb ool +ou ch +et ic +å¹ ¸ +ĠM an +E d +éĺ ¶ +se e +L e +åIJ ¯ +å¨ ĺ +Ġnecess ary +Ġb ox +Ġare as +Ġf avor +Ġprob ably +ibr ary +. T +Ġaut om +èĤ ¯ +é ¤IJ +ĠS ome +è¯ ¯ +ï¼Į 大 +- y +ĠA ugust +Ñ ģ +Ġcont ract +åº ĵ +以 ä¸Ĭ +che ck +è· Ŀ +r ame +å½¢ æĪIJ +ĠJ anuary +il ter +ist ance +æİ Į +Ġsec urity +æĺ¯ åIJ¦ +Ġappro ach +V al +lo at +è§Ħ å®ļ +Ġexp ress +ĠL ist +p m +åĨ ° +le ep +ĠS chool +Ġevery one +æ¦ Ĥ +C E +ĠN ULL +w here +ãĢĤ èĢĮ +pt ions +Ġpol icy +å· ¨ +Ġev idence +æĺ¯ ä¸Ģ个 +ï¼Į åıĪ +_ {\ +Ġdown load +et urn +P S +C L +åİĨ åı² +oc ol +n o +é¥ Ń +Ġprof essional +è¯ ¢ +Ġlim it +o ke +Ġim m +Ġcustom ers +Ġn atural +m d +ĠN ow +ç§ij åѦ +çŁ¥ è¯Ĩ +In ter +Ġread ing +Ġfor ward +Ġeng ine +ĠR ead +Ġnot hing +æĪIJ åĬŁ +ä½į ç½® +Ġis n +æ¸ IJ +Ġpos itive +éŃ Ķ +èµ µ +ï¼ĮèĢĮ ä¸Ķ +å Ĺ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠ +æİ ¢ +Ġf it +ver se +Ġcal cul +Ġe p +D is +Ġc ause +res p +Ġwor d +Ġl iving +Ġval id +à ¤ +ĠY ork +åŁº éĩij +roll er +å» ¶ +ç»ı èIJ¥ +éļ IJ +A A +å® Ĺ +æĺ¯ åľ¨ +re st +ĠO ut +ĠA cc +Ġus ers +æ· ¡ +Ġj ud +Ġfe ature +åħ· ä½ĵ +ç®Ģ åįķ +au gh +Ġ Ï +Ġwh ite +åħ ¸ +Ġst op +idd le +Ġgrow th +计 åĪĴ +Ġex act +ï¼ī ï¼Į +Ġse par +Ġpl atform +Ġst at +ail y +Ġlevel s +åį Ī +Ġit em +æĿ¡ ä»¶ +ĠF in +f ield +t es +åĪ Ģ +Ġinclud es +_ R +Ġch oose +Tr ans +q l +ic on +Ġfin ancial +f l +空 éĹ´ +åĶ IJ +å° ļ +U ser +ä¸į æĸŃ +s y +ove red +Ġens ure +ap ter +am ed +Ġrec ogn +çĶ ° +Ġs ix +ĠO F +Ġc as +F orm +Ġrun ning +Ġev al +ĠNew s +åĪ© ç͍ +åİŁ åĽł +åī ij +ä¼ Ļ +åĪ ¸ +è¡ Ĺ +g en +Ġt itle +è¿ İ +Ġinst ead +Ġd iv +ĠM c +ç® ± +çĿ ¡ +æľ « +ac ed +é½ IJ +S p +e ks +æĽ´ åĬł +åĸ Ŀ +re ak +m ing +C ode +Ġinst ance +Ġbeaut iful +ï¼Į è¦ģ +com ing +èĻ ij +Ġâ Ī +Ġsh own +( & +é¦ Ĩ +Ġm ark +Ġwant ed +Ġyour self +Ġdis e +Ġbeh av +Ġask ed +ĠG e +_ V +Ġt akes +Ġg irl +åIJĪ ä½ľ +Ġg round +Ġrece ive +ĠO ff +éª ¨ +Ġgr ad +/ s +N A +p oint +m ap +ï¼Į åį´ +Ġint rodu +è¿Ļæł· çļĦ +Ġm ap +ĠO R +Ġmom ent +çĬ¶ æĢģ +Ġso on +éĿ © +Ġco ver +air s +n ov +ol id +Res ult +M essage +ĠW ill +ĠP res +Ġins ide +i ation +ĠT ra +ĠP ar +Ġ ill +er ve +âĢ ĺ +qu e +ĠU p +çŃ ¾ +Ġse lect +Ġpart y +Ġsh all +Ġeff ic +â ij +h old +Ġse ems +S ervice +çĥ Ł +ç¿ » +åĿ ı +å ´ +Ġf ul +Ġsc he +ĠP e +ĠA m +ĠN ational +Ġess ential +Ġf oot +g r +O ne +说 æĺİ +x y +æĿ Ĩ +ers ion +en u +ç» ¼ +è¿IJ åĬ¨ +irt ual +å¥ ¥ +èĻ ļ +åį ± +Ġg roups +åľ £ +æ¸ ¯ +Ġn ormal +éĩĮ çļĦ +-b ased +ä¼ ij +é¢ ľ +æĸ° çļĦ +Ġus ually +ĠThe n +s igned +un t +ĠB r +Ġit ems +人 们 +arg s +æĥ³ è¦ģ +Ġc y +ĠH ere +Ġcom ing +Ġde ath +Ġinit ial +Ġdec ision +Ġassoci ated +æĸ¹ åIJij +åľ Ĩ +_d ata +ĠS ec +. B +è´Ł è´£ +ĠN one +éŁ © +æĿ¥ äºĨ +g es +U E +ĠD ef +Ġlong er +Ġh ref +Ġinclud ed +at ur +Ġf ast +Ġback ground +$ \ +yth on +Ġout side +ĠS outh +许 å¤ļ +Ġright s +li ent +è¶ £ +Ġs ense +æĹ § +Ġpre p +C ount +ç« ŀ +çªģ çĦ¶ +, èĢĮ +Ġpret ty +Ġ( ( +éĽĨ åĽ¢ +ĠH is +çģ ¯ +. W +éĩ İ +pt y +æ¤ į +èĪ ª +" ] +ç¡ ¬ +Ġd raw +ob ject +以 ä¸ĭ +ak er +Ġpop ular +b f +an el +çī Ļ +[ " +l im +Ġp m +d own +AT E +Ġreg ular +Ġcond ition +Ġwrit ten +èİ « +ĠT HE +ur b +riv acy +l in +éĨ Ĵ +æ¶ ¦ +æİ Ī +ĠJ ust +cre ate +éĥ¨ éŨ +ĠTr ans +**************** **************** +çĹ ĩ +æŃ£ åľ¨ +æĬ ĵ +ï¼ İ +Ġe lement +ĠA ust +st ate +n own +Ġm ember +éĺ ´ +ourn al +Ġstruct ure +ch ar +æıIJ åįĩ +声 éŁ³ +Ġoff ice +Ġst atus +Ġconc ern +ĠS un +i pe +Ġfe ed +ub e +w ise +ĠP ublic +Ġb al +Ġcl ient +ĠR ed +> > +Ġo il +ä»ĭ ç»į +åĽ ° +ç¡® å®ļ +ç͵ è¯Ŀ +Ġse qu +Ġ 第 +I I +ide red +æģ ¶ +g y +Ġrec ent +tr ans +l abel +ĠO f +Ġchall eng +Ġpre vent +ĠGener al +Ġpro pos +ä¸ĩ åħĥ +ar c +æĺ¾ 示 +é¥ ® +T E +èĢ ³ +æĿ Ł +é¢Ĩ åŁŁ +$ . +ä½ ³ +æĬ¥ åijĬ +é» ĺ +о Ð +æĭ¥ æľī +建 çŃij +Ġst aff +æı ¡ +Ġ ** +u i +ĠT est +Ġeduc ation +åħ¨ åĽ½ +Ġmeas ure +O ur +ĠN orth +Ġprodu ction +ĠIn c +Ġf ire +Ġbeh ind +导 èĩ´ +åľ° åĮº +ç§ ĭ +è£ħ ç½® +é² ľ +Ġmethod s +çĥ Ī +èĮĥ åĽ´ +åĩł 个 +Ġpract ice +ĠF ree +ire ction +k en +åĪ º +Ġs qu +åıĺ åĮĸ +Ġus es +Ġloc ation +Ġmain tain +ch ange +ï¼Į å¦Ĥ +ä¸į å¾Ĺ +éļı çĿĢ +èĽ ĭ +li ed +éĢ IJ +wit ch +u k +Ġmed ical +æĮī çħ§ +M odel +åľ Ī +éľĢ æ±Ĥ +Ġf requ +Ġact ivity +ï ½ +æ´ Ľ +æ § +产 ä¸ļ +éĶĢ åĶ® +C K +Ġcl ick +M S +c d +Ġacc om +ĠA f +Ġn ames +os ition +ail ed +Ġb oard +æľī æķĪ +. html +ab ase +Ġ åľ¨ +åIJ Ľ +Ġph one +Ġeffect s +åĨ³ å®ļ +us ed +o e +Ġdef ined +ç» © +Ġ ï¼Ī +ĠF ebruary +Ġappe ar +Ġeffect ive +Ġn ode +Ġwe eks +èĵ Ŀ +. L +com es +æī§ è¡Į +Ġwor th +Ġo pp +_ ST +çº ¸ +é¥ ° +ain ed +å¸ ģ +Ġle ave +Ġcons idered +Ġsc reen +- to +æij ĩ +en ces +Ġc ross +M A +ev ice +æ¶Ī è´¹ +æ´ ² +in fo +è´£ ä»» +Ġcred it +Ġtr ust +ac hes +éϤ äºĨ +p art +is f +è´ ¥ +è¡Į 为 +èµ ¶ +av es +éļ Ķ +ang le +è½ ´ +[ @ +f unction +N S +Ġve h +Col or +val id +åį · +ä¸į åΰ +å½ĵ çĦ¶ +Ġav oid +ist ics +f unc +Ġor d += \ +æľī åħ³ +åı¯ æĺ¯ +O W +å¯ » +Ġhe ld +im ent +à ¤ +Ġde ep +Ġup d +ĠP a +è Ķ +ãĢĤ âĢľ +en ing +ry pt +o es +å¥ ¶ +AN T +Ġdesign ed +Ġs ound +Ġcons ist +l ink +P r +we et +æĬ ĺ +Im age +Ġ ] +æģ © +li er +em p +åĨ ł +ä¼ ° +Ġcustom er +ind ing +ç« ¥ +p ri +表 çݰ +ol ve +æľº ä¼ļ +è¿Ļ æĺ¯ +C he +at al +ç¼ © +il le +è´ ¦ +Ġin j +d is +Ġcont ribut +sh ip +ew ork +em ic +Ġst ates +Ġb lood +ĠF rom +iz es +èį £ +为 ä»Ģä¹Ī +Ġfil es +æ± ł +Ġallow s +ä¸į åı¯ +ç§ ĺ +Ġab ility +åĩº çļĦ +ãĢ Į +ĠI S +ä¸Ĭ æµ· +æĸĩ ä»¶ +Ġsk ills +q rt +ĠG oogle +çĿ Ľ +ĠD on +_ G +Ġw indow +èĤ ¤ +ï¼Į æ¯ı +Ġh on +åIJİ çļĦ +Ġh it +åİ ļ +l en +å± ĭ +T able +Ġs end +an ch +h ood +M anager +ist ry +çͳ 请 +Ġ æĪij +am ent +ĠD ata +u ge +Ġstud ies +Ġtem per +, ä½Ĩ +m iss +æķ´ 个 +Ġfil m +ĠN et +H el +æīĭ æľº +æĥ³ åΰ +Ġits elf +) \ +ï¼Į åĨį +che n +ĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠ +. app +ĠS oc +Ġprot ect +Ġa verage +Ġpub lished +( i +Ġmod els +æĸ¹ æ¡Ī +Ġsa ve +Ġbr and +åıĤ åĬł +Î ± +m et +Ġro ad +ä¼ļ è®® +Ġ( $ +åijĬ è¯ī +Ġm ention +æĮ ij +Ġcurrent ly +P C +æĹ ģ +éĽ ¶ +ä¿Ŀ æĮģ +am a +Ġany one +模 å¼ı +Ġrecomm end +å· Ŀ +Ġmarket ing +çĪ ¸ +Ġpat tern +à ¡ +æīį èĥ½ +è¿ĩ æĿ¥ +å³ ° +é£İ éĻ© +æĻº èĥ½ +Ġcon duct +d f +u ate +ĠP M +Ġd ru +Ġw all +Ġr out +li ke +b it +Ġsu bs +a res +_s ize +U M +åİ ħ +èĥ ¡ +le ased +åŃ Ļ +Ġspe ed +Ġup date +Ġch oice +éĵ¶ è¡Į +if ier +ph p +( this +Ġwond er +Ġcent er +ç§ ¦ +ur g +å¯ Ĵ +éĽ ħ +ï¼Į éĥ½ +Ġins urance +èµĦ éĩij +z on +ĠCour t +ç͵ åŃIJ +åĪĨ éĴŁ +Ġcom ments +Ġide as +p ublic +Th at +as ons +I B +Ġactiv ities +âĢĻ d +ell ow +Ġatt ack +epend ent +æł· çļĦ +uild er +ĠM on +Ġopport unity +_ i +åĩ ¡ +el se +æ±½ 车 +ç ¦ģ +éº » +re et +es e +Ġinf lu +åģ ı +æĬ ± +è¿ · +in put +ap i +Ġs il +ip ment +ï¼Į å®ĥ +z z +opy right +A Y +ĠJ ava +è· ³ +è¾¾ åΰ +å® ľ +Ġdiffere nce +ä¹ĭ ä¸Ģ +Ġex ecut +Ġres ources +ä¸ĭ çļĦ +æĤ£ èĢħ +æ¯ « +Ġreport ed +à ¸ +çĪ Ĩ +- n +Ġs n +ĠP ark +T H +èĪ ŀ +é ¬ +è® ¨ +ri ef +æ°´ å¹³ +ä¿ ĥ +ĠCent er +Ġw rong +Ġp ric +å° ¤ +am ples +èĪ ¹ +Ġfact ors +ef ore +Ġtri al +ä¼ ¸ +ĠP at +Ġman ufact +om s +ĠE l +æĪij们 çļĦ +// / +M od +pt r +. x +çĽ Ł +æģ IJ +ĠH igh +Ġde cl +Ġon es +ç»ı è¿ĩ +R ep +s ize +æ¯Ķ èµĽ +/ d +ar ies +åª Ĵ +iz er +åº Ĩ +Ġdirect ly +Ġg ra +Ġthrough out +Pro perty +çĸ ¾ +Ġbook s +em plate +Ġsa w +æľī ä¸Ģ +ers hip +at ives +Ġread y +å¿ĥ éĩĮ +åħĪ çĶŁ +port s +Ġsk in +ĠB ar +ir it +os ing +ç ĺ +Ġhtt p +m itted +- C +å°± ä¼ļ +èij £ +Ġk ids +~ ~ +E O +s k +æĶ¶ åħ¥ +Ġhapp y +ed eral +ir th +ĠD ay +act ive +Ġreg ion +g ment +al ing +éĢł æĪIJ +Ġv iol +åĬ ª +al pha +ä½ľ åĵģ +b or +" . +Ġleg al +çľ¼ çĿĽ +u y +w ith +åħ³ 注 +b ody +i us +æĢ§ çļĦ +ä¿Ŀ è¯ģ +ĠWh ile +ĠS k +å¼ ± +åĶ ¿ +def ault +å® ĩ +Ġeas ily +èīº æľ¯ +è¯ º +æī ¬ +Ġs ales +m ore +ĠV al +h a +C all +i j +Ġlook s +Ġinvol ved +è¾ Ĩ +' d +Ġatt empt +ç´ ¯ +Ġnum bers +. is +Ġc and +so ft +ve y +: " +Ġl ives +å±ŀ äºİ +ä» ª +ill ing +a ctions +åIJ ´ +E lement +Ġ å¹´ +Ġt im +ä¼ ´ +åĪĨ åĪ« +Ġim med +lic ation +ç Ĵ +æ ¾ +éĵ ¾ +Ġam az +Ġqu ant +ä» Ļ +ĠIn ter +å² Ľ +å¦ ¹ +cre t +ĠS ervice +Ġhe av +, ä¸į +Ġcom fort +Ġthem selves +Ġex cept +æľī 人 +Ġc am +d om +Ġs low +resp ond +Ġ row +ï¼Į 使 +ĠM r +Ġg raph +m as +Ġass ess +g or +ar ter +Ġbu ilt +Ġfunction s +ç½ ª +Ġd im +æĿ ¯ +éĺ » +è® ¿ +h am +AR T +../ ../ +Ġst ri +è´ ´ +P R +éĩij èŀį +Ġplay ers +Ġfun d +è¿Ľ ä¸ĢæŃ¥ +éľ ĩ +ĠL aw +Ġsur face +rid ge +pro t +æı ı +Ġg ives +Ġm ix +Ġe lements +åIJ ī +Ġs ort +Ġcol lect +ä»» åĬ¡ +, \ +U t +Ġbenef its +Ġt ask +pon ent +Ġpre c +çĿ £ +Ġw ar +( int +Ġd riv +ac ity +is ions +Ġcou ple +a ign +er ies +Ġphys ical +ĠCount y +ãĢĤ å¦Ĥæŀľ +p ath +l ation +ð Ł +èī² çļĦ +å¤ļ å°ij +Ġent er +Ġs us +ir ing +Ġpart s +ĠA M +éķ ľ +Ġdig ital +Ġb ank +åĨ Į +ĠI D +ĠF irst +Ġcomm it +ot o +Ġpro te +Ġs ell +Ġre lease +çĽ Ľ +ly ing +æij Ħ +Ġcomp ared +Ġtool s +Ġch o +in ition +åѦ éĻ¢ +Ġh or +Ġquick ly +éĽ Ħ +ĠCl ass +pos ition +ç»ĵ åIJĪ +以 åIJİ +åįģ åĪĨ +çĤ İ +le ar +åĬĽ éĩı +çº · +çĥ § +ï¼Į æľ¬ +Ġunderstand ing +ĠC ON +å¢ Ļ +ĠA re +ĠAmeric a +Ġ ; +( a +Ġr ound +Ġl atest +- up +el ta +e q +B C +it ch +Ġrem ember +ere nces +åĽ½ åĨħ +å¼Ģ å±ķ +Ġj ava +Ġrec ently +综 åIJĪ +è° ĵ +çļĦ æĥħåĨµ +_ W +T ER +r ast +æIJ Ń +ĠD av +äº Ī +离 å¼Ģ +n y +éģ Ĺ +çļĦ äºĭ +Ġpl ant +ec ause +Ġst ream +æķĻ åѦ +amb da +Ġdri ve +ab y +å¿ į +Ġm other +Ġgo al +ĠS ch +Ġpro ced +Ġb ound +in ate +å¹ ķ +Ġar ch +建 è®® +Ġdem on +å°ı æĹ¶ +Ġme chan +Ġsit es +ĠW est +Ġcon cept +Res ponse +çº ¯ +u int +Ġstre ng +Ġincre ased +ul a +Ġcost s +éĺ ħ +m t +缸 ä¿¡ +u el +Ġcomput er +Ġprogram s +å® ½ +Ġl ate +-y ear +å¾ Ħ +ens es +éĹ Ń +se mb +Ġs ong +* / +Ġsaf e +æł¹ æľ¬ +Ġext rem +ang er +ä¼ł 绣 +Ġqu e +m ax +er ial +est s +en ge +St ream +ç§ Ł +ug in +Ġst ock +im age +ä¼¼ ä¹İ +Ġc ool +æĪIJ æľ¬ +Ġu int +Ġl ines +Ġl ost +ul ations +Ġst ra +è¿ĩç¨ĭ ä¸Ń +å¹¶ ä¸į +P oint +æ£Ģ æµĭ +åħ¨ éĥ¨ +ĠH ouse +Ġcol lection +du c +Ġmach ine +Ġm icro +/ or +Ġser ver +å¡ Ķ +it able +Ġsub st +Ġcomm and +ç¨ĭ åºı +ĠA c +Ġbas ic +n es +ot al +æ³ķ å¾ĭ +é¡ µ +Ġre li +s g +Com m +I O +æ¡ ¥ +æµ ª +S ystem +Ġc ert +ograph y +æ£Ģ æŁ¥ +çī¹ å¾ģ +åıĹ åΰ +- M +U P +ç§ ģ +å¸ Ń +å®ŀæĸ½ ä¾ĭ +Ġindividual s +........ ........ +ĠCh ar +co ver +æļ ĸ +Ġ util +ï¼Į åį³ +åĬŀ æ³ķ +ï¼Į çľĭ +ic a +Ġgo es +ç¼ ĺ +Ġoffic ial +ex p +Ġ ä¸Ģ +Ġatt ention +G ener +交 éĢļ +æľī çļĦ +Ġun it +Ġnot e +äº ¦ +ĠB ro +Ġuse ful +Ġ è¿Ļ +å¹ ħ +æ± ĩ +cont ent +____ ____ +ar ily +form at +ĠD irect +建 ç«ĭ +gor ith +Ġs y +ĠB usiness +èĩª åĬ¨ +çª Ĺ +n s +Ġg e +Ġn ice +Ġplay ing +as c +ĠS ub +Ġexp ression +åİ» äºĨ +/ c +Ġmy self +Ġse x +Ġn ature +å¿ ĺ +åĬª åĬĽ +Ġlead ing +Ġact ive +Ġstud ent +åŃIJ çļĦ +Ġprot ected +ĠR E +æĶ¿ çŃĸ +r ate +Ġin sp +act ory +ĠBl ack +Ġwom an +ï¼Į æĹł +æĪIJ äºĨ +Ġform at +Ġconst ant +ĠM arket +. Get +女 人 +eb ug +å£ ģ +Ġwork ed +st d +Ġqu al +ãĢ į +tr ue +O DE +æ± ¡ +v est +èĤ¡ 份 +Ġre place +ĠF acebook +S P +Ġch arg +æ¶ ī +æļ ´ +Ġinterest ing +ru pt +i i +() ) +æĹ¶ 代 +å¿ ½ +Ġy es +ï¼Į æľĢ +h aps +} ( +Ġn ational +Ġs al +ĠS ervices +d b +æ´ ĭ +S C +ell ent +Ġm ode +Ġpur pose +é¬ ¼ +Ġfact or +] ) +èĤ¯ å®ļ +ĠRev iew +/ m +le vel +æķ Į +Ġf re +Ġdise ase +ĠM anag +å¡ ŀ +Ġs olutions +Ġproject s +åĪĽ æĸ° +èĢ IJ +an cy +ĠSu pp +Ġnot ice +Ġsat isf +ĠR em +æĬ ½ +ĠEng lish +羣 æŃ£ +Ġsit uation +Ġproper ties +Ġvar iety +éĢŁ 度 +el ine +r is +St art +è¯ ¸ +å·¦ åı³ +St atus +Ġmaterial s +ol es +æľª æĿ¥ +Ġplay er +Ġcount ries +Ġcl in +her n +Ġflo at +Ġcontin u +i ance +it ute +ä¼ Ĭ +ff ect +æĦı æĢĿ +S cript +Ġal tern +çĬ ¯ +( new +Ġaff ect +ç¯ ĩ +pect ed +im ately +çIJĨ è§£ +ĠF ound +Ġim ages +id get +é¸ ¡ +ĠTe chn +eg er +Ġcl ients +å° Ĭ +Ġha ir +Ġacc ur +æĻ® éĢļ +ç͵ å½± +ash ing +ram ework +æĹ¥ æľ¬ +å± Ĭ +Ġpr inc +r ated +ç±» åŀĭ +Ġhel ps +om en +Tr ue +Ġcon nection +_ v +æ£ ® +D ate +Ġim pl +ĠM us +Ġcol umn +o om +æľº åύ +Ġan im +Ġb all +ou b +Ġhe ight +lev ant +ag ue +i ber +çļĦ äºĭæĥħ +Ġpress ure +èĢĥ èĻij +Ġm ag +Ġad minist +od ing +å® ĭ +ad es +åıį åºĶ +L ine +act ers +Ġc atch +è¶Ĭ æĿ¥ +身 ä¸Ĭ +Ġst ress +T T +N ow +Ġhand s +id ing +ĠH ome +yp es +Ġmem ory +è¯ ļ +U s +è® ¢ +) * +ri al +Ġenc our +Ġb us +æĮ Ĥ +è°ĥ æķ´ +Ġstate ment +Ġto wards +Ġsom et +Ġto wn +ç»ı éªĮ +F l +Ġre ve +èĪ Ĵ +Ġlim ited +Ġw idth +Ġs un +åħ Ħ +çĮ ® +æ¯Ķ å¦Ĥ +Ġabs olut +Ġre v +è¶ĬæĿ¥ è¶Ĭ +A cc +æĮģ ç»Ń +积 æŀģ +o oth +ev ent +math cal +ĠPres ident +Ex p +æī © +l ib +Y PE +osp ital +è¶ħ è¿ĩ +æŃ£ 常 +缮 çļĦ +Ġappro pri +Ġcomplet ely +Ġthink ing +se ction +A ct +ãĢĤ ä½Ĩ +è¯ ¦ +P O +. r +Ġch ance +éĶ ģ +ff er +OR T +$ { +åĮº åŁŁ +éĥ½ ä¸į +Ġdemon str +Ġcons um +Ġser ious +Post ed +a a +it ude +Ġm is +\ end +ĠL og +ç³ ĸ +A fter +Ġsaf ety +Ġw ide +Ġdo or +S ource +ot es +Ġhigh ly +Ġk it +, ä¹Ł +Ġdep end +ĠU se +ar row +à IJ +æķħ äºĭ +am ily +åħ³ éĶ® +g n +åĶ ¯ +ro s +Ġparent s +Ġget s +C D +id a +r l +ĠN e +he t +ï¼Į å°ı +æ° § +å· § +ĠS T +Ġm ess +Ġey es +å¾ IJ +æ´ ģ +pack age +old er +æij Ĩ +t op +Ġfor mer +Ġhe ar +âĢĿ ãĢĤ +Ġf air +ol ar +æİ¥ åıĹ +b ut +} ) +ĠAf ric +ĠAss oci +èĥ ¶ +d es +æ° ı +Ġocc ur +ĠL a +Ġstart ing +å¼ ĥ +å¢ŀ éķ¿ +Ġorgan ization +ag ram +Ġdevelop ed +al ed +éĹ ª +ib ly +ĠB ook +ĠH ar +ish ing +G roup +ĠPro gram +P er +rap y +Ġr at +è® ¯ +rou ght +Ġl ack +Ġent ry +ĠG roup +è¾ ij +Ġd aily +æŁ Ķ +Ġmor ning +ï¼Į æĽ´ +Ġr andom +Ġd ark +Ġl iter +op en +Ġmod ern +Ġintern ational +g est +Ġcor respond +att le +Ġdef end +os is +Ab out +Ġresp ond +Ġprovid ing +Ġex erc +éĩĮ éĿ¢ +èģĶ ç³» +sy ch +é© ¾ +è¯ Ĭ +Ġhand le +å¦ ĩ +Ġs leep +éĥ½ æľī +æĺİ æĺ¾ +åĩ Į +_ set +ial og +æ¶ ¨ +对 æĸ¹ +é¢Ĩ 导 +ĠU K +Ġ vers +Ġfor ce +Ġcare er +rit er +Ġbas is +ï¼Įä¸į è¿ĩ +_ pro +ĠW ar +for ce +) { +Ġl en +lo cal +Ġloc ated +Ġgreat er +Ġg reen +p re +ĠT V +Ġsee k +b on +å¤ ® +çĶŁ åij½ +以 为 +æ¶Ī æģ¯ +init ely +F A +æ¸ħ æ¥ļ +éĢ Ķ +åİĭ åĬĽ +Ġbec ame +/ b +row n +å± ı +it ation +ĠO ver +Ġtrans fer +Ġb ud +f low +rid ay +l a +In put +åº Ħ +Ġres ource +Ġass ist +ĠAust ral +} ^ +s um +带 çĿĢ +ĠD et +Ġc ele +åıij è¡Į +å®¶ åºŃ +Ġpurch ase +ĠM at +è ª +æİ ª +Ġdeterm ine +t able +Ġcont ains +ith ub +con text +n et +ars er +Ġl abel +Ġhtt ps +ç¥ ĸ +he st +ç´ « +A V +ĠR uss +Ġpro gress +Ġt ouch +Ġl if +稳 å®ļ +Ġmult i +Ġc apt +Ġf elt +ous ly +è´ Ŀ +D F +Ġin fo +Ġintern al +æľŁ éĹ´ +éģ į +Ġdescrib ed +Ġspe ak +Ġrequire ments +S he +R el +ob j +Ġpre m +IT Y +Ġac qu +Ġach ieve +i ant +æ§ ½ +st ract +ar a +Ġpolit ical +C P +Ġbro ad +æĶ¹ åıĺ +ES S +Ġt en +ĠInd ia +Ġdec ided +çļĦ å¿ĥ +好 äºĨ +Ġdistribut ion +Ġre ach +if orn +è¿ Ŀ +O UT +ĠW ork +Ġmeet ing +wo od +Ġag ree +> ( +ä¾ĭ å¦Ĥ +Ġexact ly +Ġrem ove +end if +Ġincre asing +? " +Ġte ac +æ¢ ģ +Ġe arn +ĠH el +Ġpat ient +ĠB est +ç½ij ç«Ļ +ĠChe ck +ĠH er +_ DE +å·¥ ä¸ļ +Ġt our +p ite +Ġm obile +Ġapplic ations +u id +èIJ § +b and +Ġin form +ĠB rit +ter m +H ead +åĩı å°ij +Ġpl ans +ic ks +Ġamaz ing +ĠA ir +Ġbe gan +idd en +ron ic +åı¦ å¤ĸ +ĠM ich +åıĤ ä¸İ +ĠP lease +F T +åĨ ¬ +S D +ens ity +æĺİ çϽ +Ġsur pr +clus ion +: ( +ap an +ä½ľ èĢħ +çľĭ çľĭ +Ġst ru +Ġg ave +åĩ Ŀ +Ġs ample +Ġredu ce +ĠWe b +çļĦ éĹ®é¢ĺ +Ġadv ant +k nown +l s +äºİ æĺ¯ +Ġwas n +Ġar r +Ġg as +èĴ Ļ +un ities +as ks +æĴ ij +Ġfield s +_ E +åıij å¸ĥ +ç£ ¨ +AM E +ä¸Ģ个 人 +/ p +ĠT ime +Ġro ll +ab s +ĠG erm +Ġset ting +Ġass um +icro soft +requ est +Ġp ull +çľ ī +le ctions +Ġact ual +C lient +ĠS w +ä¸ ģ +Equ al +çļĦ æĹ¶éĹ´ +ed ia +ang ed +e ch +Q L +Ġs em +é ŀ +. ex +ĠIntern ational +éĥ½ ä¼ļ +åĿ Ģ +at ively +Ġm id +æĦı è¯Ĩ +Ġmean ing +èĨ ľ +åıª èĥ½ +out put +éĩį çĤ¹ +Ġdeg ree +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ +\ " +ur t +æŃ¤ æĹ¶ +B lock +am s +i os +in ner +Ġen h +Ġn av +Ġest im +Ġf a +pec ial +Ġcreat ing +å¢ ¨ +ĠS an +- S +ä»ĸ们 çļĦ +æĪ ª +ĠT ype +ĠA ng +Ġsomet imes +Ġsuccess ful +Ġh y +O ff +c her +iforn ia +cl ient +æĹ ĭ +Ġparam eters +Ġro ot +x x +ä¸ ¹ +Ġ ir +Ġful ly +ç³» åĪĹ +Ġkn ew +Ġident ify +ĠIn s +Che ck +å½ĵ æĹ¶ +Ġf ight +Ġallow ed +But ton +N umber +Ġne igh +ï¼Į çİ°åľ¨ +ĠA ut +ĠCh ina +ĠR ef +Ġthere fore +AT ION +æĺ¯ ä¸į +en ame +Ġchar ge +B A +æĩ Ĥ +ar ant +U I +çı ł +æĸ° åŀĭ +ER S +\ begin +ond on +æĭ Ł +Ġr ates +Ġst age +D o +Ġprim ary +ĠAl so +çݰ 代 +o pping +Ġg iving +Ġm agn +åĿļ æĮģ +d ev +Ġexper t +Ġw ood +//////// //////// +ul ated +äº ¡ +çݰ åľº +c il +ent y +Ġst orage +çĶ· 人 +B ox +Ġfavor ite +ï¼Į å°±æĺ¯ +Ġsay ing +Ġa ware +Ġem erg +a el +æ¢ ħ +Ġr ules +Ġ( ) +] { +Ġm ut +çĸ« æĥħ +ä¼ ¦ +math bb +Ġf resh +i very +ER R +ĠSt e +AL L +ï¼ĮéĤ£ ä¹Ī +æ¼ « +è·Ŀ 离 +enc ies +äºĮ åįģ +Ġd ed +Ġref erence +ĠO ther +æ¹ ¿ +Ġtri ed +K E +åº Ł +Ġcan cer +é© ± +Ã Ĺ +è ¹ +Ġt al +äºĨ ä¸Ģ个 +Ġcamp aign +åĪ« 人 +Ġsum mer +Ġpop ulation +è ļ +S earch +iz ations +åĨħ éĥ¨ +éĩı çļĦ +ir us +Ġp et +Ġstep s +çĦ¶ èĢĮ +Ġaut o +ĠC oun +ep s +Ġstrateg y +ï¼Įåħ¶ ä¸Ń +ç§» åĬ¨ +ĠDep artment +ol or +Ġst uff +Ġchang ed +Ġhe ard +ĠC opyright +Ġs ale +l or +ĠK ing +æĢ Ĵ +Ġnum er +ust er +å®ŀ ç͍ +ot ion +Ġde ad +çģ Ń +é² ģ +_t o +åĬ ± +çĭ Ĥ +Ġf ix +Ġs pect +Ġ ä»ĸ +E nd +Ġequ ipment +Ġanal y +Ġl ed +åıij æĺİ +æĻ ĵ +set s +Ġconst ruct +æı Ĵ +Ġw ish +I Z +ig ma +app ing +Ġp le +软 ä»¶ +Ġp ark +am ma +Ġop in +, è¿Ļ +au ght +in ated +æ¨ ª +Ġm ount +ĠDe velop + ° +â Ī +. util +ĠP re +ä¸į ä»ħ +ï¼Į åIJĮæĹ¶ +ĠAN D +P T +Ġdistribut ed +ï¼Į 便 +Ġpart ners +åıĬ æĹ¶ +Ã Ń +çĩ ĥ +Ġt ree +Ġl ock +Ġemploy ees +s qrt +éĿ¢ 对 +âĢĿ , +çļĦ åľ°æĸ¹ +Ġrequ ires +il er +æĹħ 游 +éĢ Ĵ +ĠO pen +åıĸ å¾Ĺ +æŀ ª +Ġsc ale +çŃĶ æ¡Ī +Ġpred ict +æ³ ° +Ġpie ce +æĺ¯ä¸Ģ ç§į +ä½į äºİ +g a +Ġpl aces +ro te +Y our +åĩº åİ» +å½ » +ĠM od +ĠD ist +ro y +ad o +å° ĺ +Ġcult ure +H ere +Ġde cre +Ġa im +æĿ ° +r an +# if +çĤ ¼ +. ) +ri ver +æĽ ¿ +éĿ¢ 积 +Ġas pect +Ġhim self +Ġcar ry +P art +ä¸į å°ij +_l ist +Ġ[ ] +èµĦ æĸĻ +æĥ ¯ +Ġinvest ig +Ġoper ation +ra z +Ġcon v +own load +ĠA tt +arg in +p c +å¿« éĢŁ +AB LE +ç͵ è§Ĩ +Ġche m +Ġh our +é¼ ĵ +Ġse lected +çĥ ¦ +Ġd oc +ens ions +Ġtemper ature +. N +ä¼ ¯ +Ġa f +Ġf ine +Ġinter face +Ġreg ist +Î ¿ +åĩł ä¹İ +ĠPol icy +g l +ï¼Į æĬĬ +s m +åĩº çīĪ +ĠE very +.l ength +ms g +_ re +éģ¿ åħį +ä¸ī 个 +èĤ ¥ +ï¼Į ç͍ +du le +- B +f ord +, å¹¶ +åĪ · +Ġg old +é¦ĸ åħĪ +Ġinter view +qu ery +ä¹ĭ ä¸Ń +ç»Ī äºİ +Ġref er +èĻ İ +Ġs on +è¢ ĭ +а Ð +Ġre levant +g ar +æľī çĤ¹ +Ġre pl +å½¢ å¼ı +Ġb and +ä¸įåIJĮ çļĦ +Ġro ck +ä¸į éĶĻ +r im +so le +ĠG o +Ġmov ing +Ġexist ing +Ġre pe +ä¸į 好 +ãĢĭ ï¼Į +Ġh uge +è± Ĩ +ri ve +Ġad just +Ġb ottom +Ġbehav ior +el come +ï¼Į 没æľī +Ġj o +æī¾ åΰ +说 çļĦ +ard en +ens or +ic ip +ĠK e +i as +丰 å¯Į +I LE +åĮ» çĸĹ +Ġth us +ma zon +å§Ķ åijĺ +å¹´ è½» +Ġcertain ly +æĺ¯ ä»Ģä¹Ī +Ġs witch +Ġover all +h ost +è®° èĢħ +æĽ ° +Ġtrans form +Ġd irection +or ge +æĬ µ +å®¶ çļĦ +M ethod +æ¬ ² +ty p +çĭ Ĺ +Ġparticular ly +Ġhe at +两 人 +è¿ ¹ +od ay +Ġs old +ffic ient +ĠD ec +åζ éĢł +ä¸Ĭ äºĨ +P re +Ġeconom ic +Over ride +åı¦ ä¸Ģ +ĠR eturn +ress ed +ĠS ince +åľ¨ äºİ +i ately +Ġarg ument +ĠM ost +éĺ¶ æ®µ +( r +Ġfin ally +Ġno vel +ynam ic +ä¿¡ åı· +il ies +it ect +Ġopt im +Ġchar acters +Ġt er +c p +Ġcomp ar +Ġdist ance +身 è¾¹ +-t ime +Ġpa id +Ex t +åħ± åIJĮ +x t +Ġ ~ +Ġhealth y +Ġs ession +ĠManag ement +ri p +æµ ĵ +è¿ Ķ +åŁ¹ è®Ń +åĭ ĩ +éĢ ĥ +Ġexc ellent +ol y +满 è¶³ +Ġad ult +ï¼Įå¹¶ ä¸Ķ +C A +In st +Ġf ather +åĶ ± +ä»Ĭ å¹´ +Ġim ag +ay ers +ames pace +èĦ ī +æķĻ å¸Ī +al d +åIJ¬ åΰ +ateg ories +Ġp ages +Ġdem and +çļĦ é«ĺ +Ġinterest ed +Ġlook ed +Ġal one +ï¼Į ä¸İ +Cont act +è° · +Ġregard ing +æķ ı +A X +çº ¹ +ĠF e +åζ 度 +åζ ä½ľ +认 è¯Ĩ +æ´ ŀ +ĠO bject +# endif +å¦Ī å¦Ī +ĠAn y +-t ype +Ġappropri ate +åIJĪ åIJĮ +te e +å° ¾ +Cont ent +C S +Ġbl ue +åĬł åħ¥ +( l +( [ +主 ä¹ī +( const +å§ ĵ +ĠR el +Ġappro x +à ³ +Ġintern et +Ġpre f +èģĮ ä¸ļ +ed ding +B ase +opt ions +Ġplan ning +s l +ä¸Ĭ è¿° +Ġin nov +Ġfr ame +ribut es +Ġturn ed +id ents +ĠT witter +èĤ¡ 举 +åªĴ ä½ĵ +Ġshow ed +éķ¿ æľŁ +æ¡ £ +åIJĮ åѦ +ru it +o ch +åı ¬ +Ġre asons +Ġother wise +in st +Ġf irm +D R +ĠRes earch +æ® ĭ +c ount +u it +anc ing +Ġwho se +è´¹ ç͍ +Ġmov ie +温 度 +Ġfil ter +ĠE v +iqu es +- pro +Ġad vert +ä» ¿ +æĥ ł +å¿ Ĩ +ĠT op +Ġst ar +亿 åħĥ +ild ren +Ġr ule +Ġst ories +é© ¶ +ä¼ĺ åĬ¿ +Ġsur v +pect ive +Ġbe y +Ġperform ed +ĉĉĉĉ ĉĉ +ren ch +ä¼ļ æľī +è¡ ¡ +v ille +Ġtrad itional +å¿ĥ çļĦ +ĠSo ftware +Ġv ict +Ġmay be +il ing +m ar +ãĢĤ " +Ġc ategory +M ay +æµĭ è¯ķ +çĶŁ çī© +Ġbey ond +Ġpol ice +说 è¯Ŀ +ĠL oc +M ore +Ġconst ruction +åΰ åºķ +c el +严 éĩį +, ä¸Ģ +m u +In stance +i pping +åĬŀ åħ¬ +Ġa x +Ġbegin ning +k a +å¤ļ 个 +Hand ler +ĠJ es +A ction +m ark +Ġpre fer +è§Ĩ é¢ij +Ġcon cent +ear n +ï¼Įè¿Ļ 个 +b um +Ġdev ices +ul ate +ar se +æ² Ī +Ġb rought +ä¿Ŀ éĻ© +æ¯ı 个 +Ġs av +Ġf em +Î ¹ +Ġcons ent +羣 æĺ¯ +Qu ery +Ġre leased +ag on +èħ ¿ +.app end +Ġcand id +Ġd ream +å®ŀ åĬĽ +ĠD em +åĬł 强 +C lick +_ get +ic o +iv il +Ġex pos +éĢĤ åIJĪ +l am +N ext +æķ ¬ +å¥ ĭ +é«ĺ çļĦ +ä¿Ŀ éļľ +åħ¨ çIJĥ +Ġdel iver +ĠV iew +ä¹ ĺ +ur d +èį IJ +å¤ļ çļĦ +c m +æī « +Ġdef initely +Ġdo g +Ġdam age +åıª è¦ģ +I ST +ER T +æ² ¿ +å·¥ åħ· +ĠP ort +B ack +è¡Į åĬ¨ +ĠS en +Ġtrans port +st art +Ġbel ie +ä¹Ł æľī +ĠCal ifornia +ĠN OT +ç¨ĭ 度 +ol ic +"> < +éŃ Ĥ +Ġgu ide +Ġb oolean +Ġtra in +Ġm er +èĩ £ +ord s +竣 çĦ¶ +D A +ear s +erv ation +ĠDes ign +en ed +Ġplay ed +ĠD el +Ġcrit ical +Ġgo als +Ġsh ape +Ġinvest ment +ĠSt reet +Ġpresent ed +Ġb irth +èŀ º +ç»ĵ æĿŁ +c ial +Ġcommun ication +oun ced +çŁ ¿ +Ġal though +å¹ ¼ +ist ory +ric s +Ġbenef it +Ġv irtual +Ġd ro +Ġadv ice +Ġneg ative +Ġ ign +Ġveh icle +ĠE ven +Ġp ow +æ¯ķ 竣 +æ¢ ° +atic ally +æ® Ĭ +, å°± +Ġfeel ing +å¡ ij +Ġlarg er +ç¢ İ +ĠComp any +å°¤ åħ¶ +_p ath +ĠPro f +çĤ¹ 头 +ä¸ĭ åİ» +åĢ į +è§Ħ åĪĴ +Ġimport ance +ool s +ra ction +es h +Ġbut ton +人 ç±» +ĠA p +æ¡ Į +æij ¸ +oo st +ac ing +æĿ¥ èĩª +æĢĿ æĥ³ +Ġfail ed +il ed +Ġpict ure +è¿ ª +Ġtri p +Ġsc ience +éŁ³ ä¹IJ +w idth +Ġan g +éĹ ² +- F +T oken +## # +w orks +å¿ĥ ä¸Ń +èij£ äºĭ +us ion +ĠI d +åıĤ èĢĥ +æ¶ Ĥ +缸 对 +éĿ¢ åīį +Ġ= == +G L +ot hes +T op +por ate +æĸĩ 竳 +} _ +表 éĿ¢ +Ġequ al +n cy +, æĺ¯ +ĠS im +AN D +Ġset s +æľ ± +Ġgrow ing +ä¹ĭéĹ´ çļĦ +ic ate +P A +Ġsp end +åıĺ å¾Ĺ +æ· » +in y +und red +. sh +æĹ Ĺ +Ġpost s +ï¼Į åĽłæŃ¤ +E C +O K +Ġ* ) +好 åĥı +Ġimmed iately +Ġstra ight +对 象 +G B +Ġapp lied +ond ay +Sh are +ä¸į äºĨ +ast e +Ġfollow s +O ptions +è¿IJ è¡Į +ç» ª +af e +Ġg ain +ĠJ apan +d ir +ç»ı 常 +ash ion +olog ies +ä¸į ä½ı +Ġcons ult +ï½ ŀ +Ġfind ing +Ġn amed +èĩ³ å°ij +ou l +- r +åŃĺ åĤ¨ +ĠM em +Ġthe ory +符 åIJĪ +V is +ãĢģ ãĢĬ +_f ile +æĮ ¯ +ĠPl an +æ³ ½ +Ġsh ared +ra int +Ġw arm +æ³ ¡ +Ġstreng th +i ency +M e +æĤ ī +交 æµģ +ign ment +ĠIn formation +èµ ŀ +F irst +Ġhist or +Ġobtain ed +æŃ£ ç¡® +Ġm iddle +çij ŀ +æ± ¤ +ow s +Ġ\ [ +æ¹ ¾ +ilit ary +Ġ< - +ĠW ell +ĠL ondon +æij © +IN T +B uffer +Ġv s +Ġfollow ed +ĠE duc +Ġprodu ce +U B +ol f +ï¼Į åĪĻ +ï¼Į è¿ĺæľī +Ġsu st +æĺ ł +åĽ¢ éĺŁ +Ġgr ant +æĿĥ åĪ© +Ġreturn s +Ġsc ient +N et +Ġgener ally +s es +Ġpric es +st ream +Ġbusiness es +our ney +Ġtr ade +æŁ ± +ĠG over +Ġn p +è®Ń ç»ĥ +Ġd ry +Ġcomm erc +Ġeff ort +- A +ĠFound ation +al y +C an +ĠT H +ãĢĤ ä½Ĩæĺ¯ +ĠF orm +ate ver +con s +Ġd oub +à ¶ +è¯Ń è¨Ģ +Ġflo or +ĠG reen +Ġth ous +as ure +a e +çĦ ¦ +Ġth reat +Ġsc ore +Ġb order +Ġapp rec +Ø § +ĠF riday +Ġc ash +å®ī æİĴ +as y +ç» ķ +è ¦ +Ġpass ed +D B +Ġdi agn +augh ter +es tern +Ġu lt +åĨħ çļĦ +ĠB oard +ä¸ĵ å®¶ +on ly +ä½ĵ çļĦ +ä½ĵ éªĮ +Ġmax imum +ä½ĵ ç³» +æĸ¹ 便 +çŀ ¬ +Ġpack age +¹ ģ +Ġcon vers +ĠCol lege +è´Ń ä¹° +Ġorig in +åIJİ æĿ¥ +åħ¨ éĿ¢ +a per +èIJ ¨ +ic ated +å¦ » +Ġe at +Ġsol id +Ġopport unities +he nt +Ġear lier +Ġmat rix +Ġal gorith +æµ ® +ç»Ŀ 对 +Ġparam eter +Ġc ru +Ġchalleng es +çļĦ æīĭ +ind er +Ġ> = +M L +Ġhig hest +ad ata +Ġro t +ve re +() ; +M at +O C +ĠM or +The y +- \ +æ³ Ľ +( g +èĦ Ĥ +èĥ ŀ +Ġj oin +ä» ģ +} ^{ +æĻ ¶ +ĠG reat +æ² Ł +éĥ ij +Ġh ous +om b +ĠPro ject +è· Į +让 人 +éª ij +åij Ī +atur day +Ġgu id +} . +Ġse lection +E mail +身 份 +æīĵ å¼Ģ +éª ¤ +ĠB en +ĠCan ada +Ġwant s +C al +Ġbrow ser +Ġexp and +semb ly +con nect +Ġcol lege +çIJĨ 论 +v ider +Ġfe et +æĶ¿ æ²» +ä¼ Ł +we b +B uilder +Ġcap ital +Ġm ill +Ġreview s +Ġt ick +èĢĥ è¯ķ +ĠTh anks +éĶ ħ +y ing +Ġ ut +Ġ :: +Ġar riv +Ġsupp ly +in n +( v +Ġf igure +% , +æĪ ´ +åĩ ī +Ġant i +æł· åŃIJ +######## ######## +AR R +z a +Ġl ab +Ġsp ent +åĽŀ çŃĶ +ct x +è¾ ħ +Ġsm art +Ġobs erved +Ġa ctions +L ast +r ont +çĶŁ çļĦ +M ode +Ġphot os +Ġw rote +èģ Ĭ +Ġsu ff +ĠE X +AG E +ĠâĢ ¢ +Ġc at +oc r +Ġtest ing +ĠC ook +ific ate +ĠA nt +D S +çζ æ¯į +am ing +ĠG ood +Ġreport s +Ġre nt +æļ Ĥ +Ġc ore +E E +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +Ġra ise +Ġ( - +Ġsp irit +æĦı ä¹ī +IT H +ĠJ ack +. to +åºĶ çļĦ +èĪ į +ĠDav id +Ġsequ ence +P lease +aint iff +j son +æģ ¢ +Ġmod ule +Ġind ependent +M P +ĠC are +èµ ı +co pe +Ġn ut +h o +Ġdes cription +以 æĿ¥ +Ġmot ion +ĠW indows +ĠChrist mas +çļ® èĤ¤ +Ġex ception +Ġtre nd +Ġey e +ĠF ile +ov ing +éĴΠ坹 +Ġrest aur +i ers +ot ed +æĮ º +he ight +Ġeas ier +Ġd ie +Ġtr uth +in ct +Ġ vert +P age +Ġb rain +Ġf at +Ġcompon ents +ĠWh ite +åı¥ è¯Ŀ +hen s +éĻį ä½İ +, ä»ĸ +Ch ar +or row +ĠA R +Ġset tings +A ss +ĠOn line +Ġoper ations +ç ¹ģ +è± ª +èı Į +_ ex +Ġd rop +åĩ Ń +Ġpres ence +åģļ 好 +çģ ° +ĠEx p +Ġarg s +E m +u ps +ic ations +ĠG l +é¢ Ĺ +åĴ ¨ +Ġinc ome +. re +ĠL ife +( h +con tain +æĢ§ èĥ½ +up date +p ret +ar p +ĠE m +ï¼Į 说 +Ġd iet +Ġchall enge +æĪIJ ç«ĭ +( S +, æľī +Ġcent ral +Ġt ag +å§ ij +å®ĥ 们 +cre en +ĠM ake +_ add +Ġstru gg +. assert +è¿ ħ +ell ig +Ġpo or +Ġref lect +Ġd ivid +c an +Ġcoun ter +模 åĿĹ +Ġch annel +Ġ · +æ¯ı 天 +ĠN S +Su pp +l ies +è£ Ĥ +c are +u a +um an +Ġlet ter +( _ +ĠH ot +åĸ · +Ġh yp +ou nce +_in fo +Ġpay ment +Ġrel ig +ĠAN Y +è§Ħ 模 +Ġ er +Ġrest rict +宣 ä¼ł +add ing +ç»Ļ æĪij +Ġve ctor +ãĢĤ ä¸Ģ +åį« çĶŁ +Ġbud get +é¾ Ħ +Ġext ends +èĢ Ĺ +Ġreturn ed +Ġf ixed +Ġp en +æŁ ³ +Ġfor ms +Ġrespons ible +åĨį æ¬¡ +Ġcas ino +Ġl oved +se lect +Ġinst itut +Ġpres ident +AC T +çĸ¾ çĹħ +ï¼Į 请 +ä¸ĭ éĿ¢ +è¯ģ åΏ +Ġp air +Cont roller +B l +ex as +ph one +O per +Ġs rc +ĠSu per +Ġcompon ent +Ġa ward +åĽł ç´ł +èµ° äºĨ +ä¹ Į +ashing ton +ĠEurope an +T e +åĽŀ æĿ¥ +æĬ ¬ +L oad +æķ° åŃĹ +r d +vent ion +å¼ķ èµ· +ï¼Į éĢļè¿ĩ +Ġthan k +Ġ" $ +ĠAn n +ĠJes us +æĸ½ å·¥ +por ary +Ġclass es +ï¼Į 被 +ym bol +ar th +Ġh op +Ġpl us +D C +Ġtalk ing +æ½ ľ +Ġsp read +Ġfam ilies +Ġgl ass +Wh y +ç«ŀ äºī +æĻ ¨ +Ġ ing +æĶ¾ åľ¨ +å¼ Ħ +th at +Ġelect ric +ĠThere fore +Ġco ord +R em +åĵ Ń +èħ ¾ +" " +Ġcommerc ial +åķĨ ä¸ļ +ic ine +çĽ IJ +ĠWh y +UL T +Ġser ve +Ġro b +åĬĽ çļĦ +å°± åľ¨ +è´ · +ph i +æĺ¯ 个 +ing er +èĸ Ħ +om ic +æľī ä»Ģä¹Ī +Ġclaim s +ĠM ac +ĠInd ian +å®ŀ éªĮ +åij µ +ri pt +X X +é½ ¿ +Ġd ating +_ k +ãģ ® +z er +èĩª çͱ +yd ro +per ties +ĠChrist ian +Ġem pty +åĨ Ĵ +D on +æIJ ľ +.s ize +Ġl ayer +f s +ç»Ħ æĪIJ +Ġb ath +ĠA mazon +ide os +Ġh undred +I A +æģ¢ å¤į +éĻ · +æĮĩ 导 +Ġra ce +Ġne arly +Ġw ild +b a +EX T +Ġw ife +x ff +s cript +Add ress +Ġz ero +wh ich +æ¯ķ ä¸ļ +g ithub +ï¼Į 该 +ed s +ĠM et +å© Ĩ +Ġh arm +. > +æı ´ +ï¼Įè¿Ļ æł· +c ite +ĠO nce +Ġc overed +ĠAustral ia +é£Ł çī© +Ġident ified +Ġstrateg ies +math bf +st on +. id +Ġprep ared +Ġbro ther +Ġto ward +æİ¨ è¿Ľ +Ġopen ing +åħ¬ éĩĮ +æĿ¥ åΰ +ri age +Ġproced ure +ĠFl or +Ġsh ift +ĠEx t +f e +ĠT R +Ġdef inition +Ġf ear +n amespace +Ġb oy +. name +ä¸Ģå®ļ è¦ģ +Ġrel ative +P P +Ġpol y +ĠComm ission +L abel +Ġfin ish +åΤ æĸŃ +æĪĺ æĸĹ +Ġd ress +å¥ Ī +L ayout +el ines +iction ary +åħ´ è¶£ +Ġs weet +Ġsm ooth +Ġsym pt +Ġach ie +Ġmiss ing +ï¼ī ãĢĤ +Ġinflu ence +re hens +å¥ Ķ +ĠE qu +Ġst ored +Ġdevelop ing +æ´ ª +o or +at in +ĠSt r +çī© è´¨ +Ġimplement ation +çİ » +æĹ¶ æľŁ +ig ital +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠ +Ġwh atever +ct ors +Ġl ose +E CT +ãĢĤ åĽłæŃ¤ +Ġb ill +ï¼Į æīį +Ġst ation +Ġsom ew +ĠL ong +Ġm ental +un ately +ĠR ob +ri an +åŃ ¤ +æĪij åĽ½ +åĩºæĿ¥ çļĦ +ĠH ol +_ ID +ĠG NU +Ġwould n +ä¼ļ 计 +èģ ĺ +è§Ħ èĮĥ +u ations +Ġest ate +am in +Ġlead ers +< < +Ġmanag er +æĭ ³ +Ġthem e +ob s +æ¶ī åıĬ +ĠW ater +ĠC D +OR D +ĠE nd +å¤ļ æķ° +K e +ĠY es +ĠR oad +è° ĭ +. pro +åIJį ç§° +-------------------------------- -------------------------------- +Ġart icles +Ġann ual +pec ific +Ġsol ve +驱 åĬ¨ +Ġqu arter +Ġdist rict +/ t +Ġpract ices +ĠF ig +å±ħ çĦ¶ +ĠN ote +ĠM art +Ġh ab +Ġdefend ant +/ g +sp ace +_ j +è¿ Ł +is ode +erson al +as et +Ġvisit ors +ç« ¹ +éĥ½ åľ¨ +å¤į æĿĤ +å® ¿ +os h +ĠBrit ish +_ sh +ĠP ay +Ġthrow s +os es +第ä¸Ģ 次 +Ġbe g +æ°ij æĹı +é¸ Ł +< ? +C o +Ġpl ants +l ong +Ġoper ator +ro ad +F ilter +Ġdet ail +Ġatt end +ve c +is c +oun ter +æľī çĿĢ +çļĦ 女 +ï¼Įè¿Ļ æĺ¯ +æĵ ¦ +Ġtem plate +ĠB uild +" } +ĠS al +ĠCh urch +E ST +k y +Ġpre par +Ġes c +éĩij é¢Ŀ +ç¾İ åħĥ +Ġmot or +åĿ ¦ +ĠW ITH +anc el +Ġinj ury +S ign +ï¼Į 没 +Ï ģ +æ¼ ı +Ġf ans +Ġserv ed +天 ä¸ĭ +天 çļĦ +b lock +åĵĪ åĵĪ +Ġcommun ities +Ġac ad +ĠT om +Col umn +. class +Ġpie ces +æģ ¨ +. J +L ength +æĺİ ç¡® +- the +Ġfin ished +ç»ı çIJĨ +éĥ½ 没æľī +ĠEx per +ĠâĪ Ĵ +Ġme ant +F C +_ un +se y +ĠT ext +Ġf ol +åĪ ij +p u +Ġch ain +Ġext ract +çº µ +Ġwe ar +åĬł ä¸Ĭ +æĪĺ çķ¥ +Ġmed ium +æ¡ ĥ +åIJ ¹ +äºĴ èģĶç½ij +Ġgu ys +ĠO h +^{ - +æĥħ 绪 +]( # +b i +st e +P ress +åľŁ åľ° +' . +Ġex ists +ĠM icrosoft +A ccess +( * +Ġear th +Ġn uc +å¤Ħ äºİ +ĠS l +个 æľĪ +( R +广 åijĬ +å®ŀ è·µ +è¾ ° +æŃ£ æĺ¯ +en v +ĠB as +Ġpost ed +Ġwait ing +ic it +å² ¸ +ad ow +er ry +Ġupd ated +ĠM iss +ien ces +ed om +Ġdiscuss ion +S erver +Ġ § +if orm +é£İ æł¼ +ĠInst itute +ï¼Įä¹Ł æĺ¯ +ARR ANT +ãĢĤ ä»İ +ĠS am +, æīĢ以 +ï¼Į æĥ³ +ĠY ear +tt p +Ġsp ring +ĠL ord +Equ als +Ġeconom y +åħ ¼ +çļĦ æĸ¹æ³ķ +Ġfor g +P U +ĠPh il +ç½ ² +â ĸ +Ġerr ors +åĪĽ ä¸ļ +Ġb ra +ä¹ ³ +U rl +- old +M T +Ġabsolut ely +Ġ » +Ġarch itect +è¿ « +/ w +ad y +è¿ĩ äºĨ +ĠCom ments +缸 åIJĮ +æĤ ² +缮 åħī +rom e +çļĦ ä¸į +ï¼Į èĥ½ +Des cription +å̼ å¾Ĺ +ãĢĤ æľ¬ +Ġsc ene +ĠO per +ç± į +Ġc up +å£ ® +Ġcon ven +Ġchang ing +val ues +ĠW ARRANT +éģĵ è·¯ +Ġdis cover +ber g +Ġinc red +Ġmen u +es ome +æĭ Ķ +ol ved +è² Į +ĠB et +end ar +Ġanim als +Ġlead s +', ' +Ġess ay +ef t +åħĥ ç´ł +çݰ 象 +ĠA D +ï¼Į éļı +ĠI P +ï¼Į åħ¨ +ill er +os ite +_ a +éĻIJ åζ +ĠP RO +çĩ ķ +Ġtr ig +Ġar m +åĽŀ åΰ +äºĭ å®ŀ +y a +ĠS O +ä¼ ı +M in +åı£ æ°Ķ +B ook +Ġsqu are +ĠR et +an o +å§Ķåijĺ ä¼ļ +ä» Ķ +Ġc ry +art s +^ {\ +ĠDirect or +k in +ĠSt and +æ¼ Ĥ +Ġcoff ee +èį ¡ +Ġl uck +Ġadv ance +Ġgu y +Ġra re +Ġmeas ures +el ess +Ġst ick +Ġy ield +ĠE lect +c a +Ġj ournal +æµ © +çĽ Ī +Ġaud ience +Ġtyp ically +æĪ¿ éĹ´ +Ġcomfort able +. create +ĠIs rael +Ent ry +ĠL ove +â Ķ +Ġhe aring +\ [ +表 è¾¾ +Ġdiffere nces +Ġb rief +ĠF igure +M et +Ġcreat ive +.n et +çݰ éĩij +Ġ ãĢĬ +Ġm ission +the ta +Ġlead er +ĠMich ael +çļĦ ä¸ľè¥¿ +ec ess +ĠPl ay +è¿Ļ 次 +æĻ ĭ +模 åŀĭ +Ġtrans l +çº ¤ +åİŁ åĪĻ +ĠM ary +Ġfore ign +éĥ İ +è· ¨ +â Ħ +èħ ¹ +let s +d oc +æĸĩ æĺİ +ĠTh om +Ġb ag +ft y +all s +äº ķ +èĭ± åĽ½ +æľī æīĢ +M enu +yt ics +çļĦ æĸ¹å¼ı +ä¸Ĭ åİ» +åĽ° éļ¾ +æĿ¥ æºIJ +å°± è¦ģ +çļĦ 好 +å® ¾ +éĽĨ ä¸Ń +Ġwrit er +c ore +çī¹ èī² +å½ ¼ +_ e +å¤ļ äºĨ +éĤ ® +ĠP ress +Ġdirect or +è¿ħ éĢŁ +Ġill ust +P tr +ĠB ay +Ġknow s +Ġfun ds +æŁ ľ +Ġcour ses +go ing +Ġw arrant +åħį è´¹ +æĭ Ĵ +ĠC amp +Ġhom es +ess ions +p y +åĪļ æīį +F in +He ight +ĠB log +l ast +Ġconfig uration +ĠA PI +æ» ´ +ap ache +ult i +Ġmet al +æĹ¢ çĦ¶ +Ġ[ ... +Ġp anel +sc ribe +åįı è®® +Ġsent ence +ul ed +by te +M D +ĠPr ice +Ġgener ation +éģĩ åΰ +Ġs ector +Ġj oint +è¿IJ èIJ¥ +Ġstand ards +L ike +Ġagre ed +ï ¿ +Ġ" \ +ç¡® 认 +t imes +ĠL ead +ĠF ood +M em +ĠV alue +ig ration +/ j +åħħ 满 +ĠS ection +do or +Ġcorrespond ing +ĠAd v +说 äºĨ +Ġwe ak +çļĦ 主 +èĬ ¯ +& # +ï¼Į å¾Ī +ç¬ij çĿĢ +Ġac id +è· ĥ +Ġaw ait +Ġfl at +Ġdec ide +Ġsus p +çľĭ è§ģ +åĵª äºĽ +ern el +word s +æīĵ éĢł +åIJ IJ +n bsp +Ġcl imate +ĠRep ort +åĭ ¤ +åIJ¸ å¼ķ +ĠR ober +clud ed +Ġrun s +å¿ § +æĹ¶ çļĦ +rem ove +è¿ŀ ç»Ń +Ġpolic ies +Ġspecific ally +math rm +Ġcol ors +at abase +Ġs and +Ġg un +Ĥ ¬ +und le +å° ¸ +ent ity +ï¼Į ä¼ļ +_t ime +åı¯èĥ½ ä¼ļ +å¦ ĸ +an ner +/ L +- ch +Ġb ow +çŃ ¹ +Ġcent ury +ad er +æ± Ĺ +Ġla unch +Ġt or +Ġfl u +ĠJ ew +è§Ĥ å¯Ł +Ġf av +æİĮ æı¡ +ic ial +Ġ[ [ +éŀ ĭ +详 ç»Ĩ +èį · +æľº åħ³ +Ġrel ax +Ġkeep ing +å®ļ ä½į +E ng +çĽij çĿ£ +r ical +çĿĢ ä¸Ģ +ĠU N +ç«ĭ åį³ +æĹł 论 +éĵ ľ +Ġf an +ĠE mp +ent er +ï¼Įåıª è¦ģ +ä¾Ŀ çĦ¶ +ual ity +C ON +åľ¨ è¿ĻéĩĮ +Ġlaw s +ag ement +p ost +Ġinst r +ĠL o +Ġex change +ĠApp le +O B +Head er +ip es +åĬŀ çIJĨ +å®¶ éĩĮ +f ast +ĠT wo +_ key +_p aram +Ġm o +Ġident ity +ĠSh ow +Ġcontain ing +ant a +Ġun c +Ġdo ctor +èĩ Ĥ +ä¸į ç͍ +lic t +Ġoper ating +or a +as p +âĢĿ . +is ms +ĠTe am +ĠU ser +d raw +ç² Ĺ +åł Ĩ +Ġl abor +ä¸Ń åįİ +æīĢæľī çļĦ +Ġent ertain +ou ter +ad ing +大 ä¼ļ +Ġadv anced +un time +Ġr ich +c urrent +W ork +Ġag ent +ç² ® +严 æł¼ +Le vel +Ġte aching +ĠF urther +in ue +Ġto ken +P os +O b +æĪIJ éķ¿ +_T YPE +Ġex ternal +Ġsubst ant +ĠCl ub +èĢĮ è¨Ģ +åĴ± 们 +Ġparticip ants +un te +ĠSec urity +C ase +ĠS y +å¼Ģ åı£ +- R +åīį çļĦ +om y +ä¸į æĥ³ +ĠL ook +Ġpr ime +çļĦ å£°éŁ³ +åħĦ å¼Ł +ĠM ax +H ER +az ine +Ġapplic able +ore m +Ġdoc uments +ner gy +urs or +ev en +t ure +ĠO N +ĠAcc ording +Ġstart s +Ġ[ ' +im ation +Ġsche dule +TM L +P ol +Ġm ole +å¹³ åĿĩ +b uild +Ġwe bsites +O ST +éĢIJ æ¸IJ +ref ix +èĤ º +ç»Ħ ä»¶ +Ġthe rapy +çݰ å®ŀ +çİ» çĴĥ +驾 é©¶ +ï¼Į 对äºİ +éĺ Ģ +åĮħ åIJ« +åį± éĻ© +Ġlist ed +Ġnumer ous +ĠG en +Pro cess +æį · +绣 ä¸Ģ +ĠAfric a +Ġs ch +çļĦ éĩįè¦ģ +Ġfl ag +Ġd aughter +Ġsc hed +( data +ĠRes ult +IN D +æĭ Ĩ +ab et +t hen +( struct +Ġob j +R eturn +if ts +ä¿ Ħ +Ġinter pret +or ry +Ġb ond +ud d +sec ut +ĠF ire +çī© çļĦ +- se +and er +ĠA uthor +Ġfun c +åıĮ æĸ¹ +Ġf ashion +z en +åľ° çļĦ +éª Ĺ +Ġrat io +Ġenvironment al +Ġgirl s +èĭ± è¯Ń +v as +æ Ĩ +æĹ¥ 常 +é¦Ļ 港 +èĪ ° +Ġline ar +Ġra ised +Ġfocus ed +F alse +S L +Ġ icon +å°½ 管 +AP I +éĩĩ åıĸ +Ġhon est +ãĢĤ ä¸įè¿ĩ +å§ ľ +æ·± åħ¥ +å² © +, 以 +æĽ ¹ +ĠCh inese +Ġr ing +, ' +她 们 +F ollow +as er +od ies +ick en +æĸ ij +C urrent +ĠM ont +çĭ ¼ +Ġf ish +Ġsy nt +ĠComm it +Ġ"" " +æĪIJ åijĺ +ç͵ è·¯ +Ġ æľĪ +IL ITY +åľ° ä¸Ĭ +st yle +IC E +Ġman ner +ç¬ij éģĵ +ç¢ ³ +ĠH am +ãĢĢ ãĢĢ +ition ally +Ġsu fficient +ain er +Ġ$ $\ +ĠSt ar +Ġprov ider +çĵ ľ +all ed +ĠSu pport +ed y +Ð ² +_ ERR +ĠA lex +å®Į åĸĦ +) = +J ust +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠ +Ġre ached +Th ank +èĥ ĥ +ï¼Į 好 +Ġt asks +ov es +æ°¸ è¿ľ +Ġleg is +- a +ä¸Ģ å¹´ +æľ¬ åıijæĺİ +! " +Ġa uthors +è·Ł çĿĢ +çIJĥ éĺŁ +Ġwh om +Pro vider +Ar t +ä¸ ¢ +_d ir +Ġalgorith m +ç»´ æĬ¤ +F ig +åħ¬ åħ± +å¼Ģ äºĨ +erm s +i ples +Ġp al +çłĶ åıij +å¿« ä¹IJ +ĠEng land +- H +D irect +Ñ ı +Ġchem ical +èµ ĸ +ir ation +ĠP age +ĠDist rict +ï¼Į åıį +ĠB re +Ġst ack +Ġ il +Ġin du +ĠM ath +åĪĨ 为 +ĠAng el +æ¢ ¯ +ri e +Ġr id +åĪĽ 建 +b ra +åĽ¾ çīĩ +w in +ĠTechn ology +LO G +or ation +red ients +å°ij å¹´ +ĠE N +ĠComm unity +] ] +åĨľ æĿij +éļ¾ éģĵ +eg a +çľĭ æĿ¥ +Ġv ill +Ġv ideos +W indow +åij Ĩ +æį٠失 +New s +_ str +è¿ĺ åľ¨ +Ġfeed back +. print +Ġmess ages +åıĬ åħ¶ +Ġopen ed +ili ar +å°± èĥ½ +Ġ ãĢģ +ĠP et +Ġinteg er +g reg +åľ¨ äºĨ +Ġwill ing +Ġc itiz +ĠSupp ose +Ġdes pite +Ġfe es +form ance +Ġtrans ition +å¾Ģ å¾Ģ +.j s +åľ ³ +R C +éĶ ¦ +æİ¥ çĿĢ +ç«ĭ åĪ» +Ġret ail +èĥĮ æĻ¯ +P osition +g age +Rel ated +æľ¬ 身 +ç¯ ® +- N +å͝ ä¸Ģ +è¿ ģ +éĿĴ å¹´ +çĤ ī +Ġ} , +Ġu pper +Ġfor get +% ) +Ġm ail +ĠJ ournal +åī ² +_ index +y ou +ä¸ĭ éĻį +' ). +èIJ¥ åħ» +ad s +icens ed +ï¼Į æŃ¤ +it a +c ase +çĬ¶ åĨµ +omet ry +è¾ ī +ĠPro t +æĥ ij +çļĦ æĸ° +Ġd ied +loy ment +Ġlist en +V ector +F ind +ä¸ ² +ç» ĺ +Ġint ended +Ġpro ve +æĺ Į +Ġequ ival +é¢ľ èī² +æī ° +, ä»İ +Ġdel ay +at o +æķĻ æİĪ +ĠTh ank +âĢĿ ãĢģâĢľ +Ġexper ts +T arget +Ġra pid +æĭ ĵ +N um +计ç®Ĺ æľº +度 çļĦ +ĠAb out +ix el +Ġdivid ed +ach ine +, 对 +å¢ŀ 强 +y e +åij¨ åĽ´ +Ġbe coming +ĠFlor ida +èĥ½ æºIJ +åį³ åı¯ +Ġs yn +æ·± åľ³ +Ġsecond s +ĠM ap +è¯Ħ ä»· +æĦŁ åıĹ +å®¶ ä¼Ļ +ĠD i +ĠGover nment +Ġb onus +Ġm ac +认 羣 +ä¹Ł 没 +Ġrep air +b in +è°ĥ èĬĤ +å®¶ éķ¿ +å¼Ģ æĶ¾ +M on +ä¹Ł åı¯ä»¥ +åŃ ķ +Ġt iss +èĤ ł +Ġbel ong +Ġdep th +å¹ ½ +ĠG ame +åģļ åΰ +st ances +st atus +Ġs umm +O ctober +( { +ĠN ov +ĠSp ring +ĠA S +å¸ ħ +u zz +Ġ ice +èIJ¥ éĶĢ +S ec +ĠSt ep +ĠF alse +Ġmot iv +åľ¨ è¿Ļ +Ġtre ated +ident ial +am pl +Ġbuy ing +ĠC ard +Ġstre et +_st ate +马 ä¸Ĭ +æĦ Ī +re ne +å¼ ¯ +ro t +Ġdescrib e +on ym +Ġread ers +Ġj ump +享 åıĹ +ĠJ an +ĠNet work +ĠC H +rou d +è¿ĩ çļĦ +Ġk id +ï¼Į åΰ +P e +Ġthous ands +ãĢģ é«ĺ +Ġfrequ ency +太 éĺ³ +"> +_ init +Ġcall back +ç¨ ¿ +Ġcomp ens +âĢľ æĪij +Ġres istance +f a +Ġan gle +æĦŁ è°¢ +ç±» ä¼¼ +Ġvol unte +ĠT ur +èį Ĵ +çĹħ æ¯Ĵ +çϽçĻ ľé£İ +è¢ ģ +æ³ķ éĻ¢ +T ube +Ġprovid ers +Ġclass ic +å¹¼ åĦ¿ +æĦı åij³ +am m +æıIJ åīį +Ġh idden +åıij åĬ¨ +ist ent +n c +leg ate +- ex +b our +åħ¬ åijĬ +ĠLe ague +H z +lev ision +说 çĿĢ +æĦ £ +à § +ä¿® æĶ¹ +D P +omet imes +ĠRep ly +dd en +Ġindic ate +Ġ ri +å¾Ī æľī +Ġro of +ress ive +æĬ ļ +ĠD NA +W rite +é«ĺ åħ´ +åĪĨ å¸ĥ +èµĽ åŃ£ +D M +Ġcor rel +Ġke ys +æľŁ çļĦ +Ï Ĥ +ĠK ore +æĸ¹ çļĦ +Ġmar riage +èµ Ķ +æĢ§ åĴĮ +D evice +al i +Ġd ir +Ġk illed +Cont ainer +éĺŁ ä¼į +A uthor +Ġr ide +ãĢĭ çļĦ +å® ł +_ , +éĤ£ ç§į +Ġg ather +ĠO k +return s +ĠW estern +ĠIm age +Ġdo gs +d en +Ġcharg es +Ġto w +Ġfac ility +Ġexc iting +åĹ ¯ +æİ¥ åı£ +~ \ +Ġk ill +Ġbus y +èĬĤ 缮 +T O +Ġs an +çļĦ æł·åŃIJ +Ġaccom mod +èĦ¸ èī² +Ġdel ivered +å µ +è´ ¤ +ĠK now +ĠCh icago +) çļĦ +ç®Ģ ä»ĭ +éĢ » +éģ ¥ +æĮ ĸ +å½ĵ ä¸Ń +Ġrecord ed +Ġpl ate +Ġm ale +- line +in ating +Ġt y +³³ ³³ +Ġelect ronic +Ġbe ach +Ġstate ments +Pro t +æīĵ ç®Ĺ +ĠBe ach +ce ived +Ġlo ans +Ġt ight +Ġk ick +Ġfre edom +co very +Ġdeg rees +ĠAss ert +M M +Ġappear ance +_S IZE +E l +m g +ãĢģ 大 +k it +失 è´¥ +å¨ ±ä¹IJ +Ġhas h +ï¼Įåıª æľī +. ch +Ġb attle +æIJ º +ĠC EO +ĠD ev +Ġd a +in ates +ä¾Ŀ æĹ§ +Ġgl ad +Ġmar ried +ä¸Ĭ ä¸ĭ +Ġbig ger +çľ ł +æĪ Ĵ +Ġtrans action +ĠU t +G u +æĮĩ æłĩ +Ġing redients +Ï Ģ +E ach +ä¸ § +Ġm al +Ġimprove ment +Ġfour th +( N +Ġrece iving +Ġequival ent +Ġv el +Ġso le +广 大 +èĤ ĥ +åįģ äºĶ += > +s v +ĠAd minist +F ebruary +åĩ ¶ +* x +çľ¼ åīį +çĽ Ĺ +-c olor +_ O +m i +- related +Ġj u +Ġst opped +两 ç§į +Ġdi am +f ill +ok ing +Ġliqu id +æIJ ¬ +ç½ij åıĭ +orm s +iz ont +* ( +Ġpub lish +m odel +çªģ çł´ +åĪĽ ä½ľ +Ġ" / +am ental +åIJĪ éĢĤ +aut o +Ġst one +Ġun iversity +Ġrequest s +ï¼Į ä¸Ń +ä¼° 计 +çĥ Ĥ +éĥ½ èĥ½ +ï¼Ł æĪij +è¿Ķ åĽŀ +Ġval uable +mer ce +è¿ĺ 没æľī +Ġd b +ĠG al +Q ue +Ġsu dden +act s +Ġre venue +, è¦ģ +Ġc lock +av en +çĽ ¯ +人 åı£ +éĵ Ŀ +éĢļ éģĵ +Ġkind s +Ġl es +ost er +TT P +m osp +Ġsuggest s +Ġ rom +in er +çī¹å¾ģ åľ¨äºİ +En c +App lication +( : +_ error +éĻ µ +Ġtell s +sh ow +b uf +ä¸į å¤ļ +Ġsh ares +EN SE +Ġ' ' +- level +Ġexp lo +ĠE nergy +ä¿¡ ç͍ +åIJ Ĭ +Ġpar se +Ġsc r +l ength +-------- ---- +ĠO ptions +Ġconsum ers +ĠÎ ± +E P +Ġaccept ed +ĠN av +* n +Ġabsolut e +Ġatt orney +Ġdis p +Ġp riv +ins ert +å¯ Ħ +Ġemerg ency +s ource +ĠSec ret +Ġspe ech +ĠK it +Ġproced ures +Ġse gment +æ¤ ħ +ost on +in ite +Ġdocument ation +æĿĥ çĽĬ +O G +ĠM A +D elta +Ġbre ast +ĠWITH OUT +éĢĤ åºĶ +Ġveh icles +ĠAfric an +Ġne ut +æĥ ¨ +Ġper mission +ãĢĤ åħ¶ +Ġ éĤ£ +Ġa id +im ary +im ens +人æ°ij å¸ģ +ãģ « +Ġre pro +Ġyou th +C or +G o +H ash +ook ie +å´ ĩ +ĠV irgin +ĠV ideo +à ¥ +ĠA ction +, åı¯ä»¥ +Sh ow +U SE +Ġind eed +ï¼Įåħ¶ å®ŀ +ab els +请 æ±Ĥ +" çļĦ +Ġ Ø +qu are +ãĢĤ éĤ£ +Ġofficial s +éĨ ī +ter day +l ights +åľ¨ ä¸Ģ +ĠD ownload +urb an +rep rene +ä¸Ģå®ļ çļĦ +å¹´ é¾Ħ +os oph +Ġa cknow +è¯Ĩ åĪ« +æīĢ ç¤º +åĤ ² +Ġc ir +ãĥ ¼ +An other +M any +Ġart ists +Hand le +x FF +ä¾Ŀ æį® +Ġwor se +çĪ ¬ +Ġext ent +ĠE conom +m essage +Ġinvest igation +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +a ul +èģĮ å·¥ +et her +Acc ording +Call back +éĢĤ ç͍ +{ eq +Ġend s +iver se +第 äºĶ +Ġeval uation +ä¸į è§ģ +i est +é¼ ł +é»Ħ éĩij +B I +æĻ ´ +éĿ© åij½ +Ġ ä¸ī +ĠW all +ĠA P +nd ef +Ġcomp rehensive +Ġreli able +Ġsche me +ä»ħ ä»ħ +è£ħ å¤ĩ +ä¼ł æĴŃ +ĠSe lect +* t +Ġplatform s +Ar gs +Ġdoll ars +Ġany where +Ġestim ated +Ġtyp ical +è§Ĥ ä¼Ĺ +Ġprom pt +æĥħåĨµ ä¸ĭ +Ġexpos ure +代 çIJĨ +ï¼Įä»ĸ çļĦ +in stance +re v +ĠO ct +g ers +ĠAt l +åĪº æ¿Ģ +inter face +ï¼Į âĢĿ +Ġoffic er +ire ment +Ġhous ing +ĠP eter +ç¼ĸ è¾ij +ä¼ĺ è´¨ +çī¹åĪ« æĺ¯ +Ġst ret +åĩº çĶŁ +Ġsh ock +................ ................ +ç¥ ¥ +x ml +Ġgood s +ail ability +èĤ¡ æĿĥ +ir al +èĽ ĩ +Ġl ayout +ĠO S +Ġcharacter istics +Ġm it +Ġconcern ed +Ġ[ " +ĠM ot +æĤ Ħ +ST R +h and +_c ode +æĶ¾ å¿ĥ +åĽĽ 个 +C ar +ĠD igital +Ġmat ters +Ġco ach +æ» ĭ +æĢİä¹Ī æł· +æħ İ +æĥ § +) ãĢĤ +ä¸Ģ èĩ´ +Ġgu ests +çļĦ æ°Ķ +çĦ Ĭ +Ġapprec iate +æľŁ å¾ħ +B efore +è§Ĥ çĤ¹ +________ ________ +. prot +) ^ +h op +ribut ion +Ġk ing +Ġm g +Ġus ual +it ems +Ġiss ued +ynam ics +Ġm ilk +ĠB er +çļĦ åİŁåĽł +Ġcandid ate +Ġfrequ ently +ĠTr ust +é«ĺ 度 +Ġcomp r +ut ton +J son +ref erence +æĥ³ 象 +em pl +ç¬ij äºĨ +æij ĺ +S ave +æĬ Ľ +Ġf ellow +m ain +Ġengine ering +Ġrelig ious +Ġsav ed +å§IJ å§IJ +æĭĴ ç»Ŀ +ï¼Į ä¸ĭ +éĥ¨ çļĦ +IT E +ĠUp date +è´¸ æĺĵ +Ġpay ing +Ġsong s +Ġ( \ +r ho +li k +an ish +; ; +æį ķ +. put +æ³ µ +ç͵ åĬ¨ +Ġemploy ment +ag raph +Ġhealth care +ĠE U +Ġemot ional +Ġ' / +Ġturn s +麻 çĥ¦ +ãĢĤ 该 +ĠRober t +ĠAr g +ol umn +ĠP ract +Ġfurn iture +æĬ¥ åIJį +Ġmov ies +éĿ¢ ä¸Ĭ +Ġne arest +å°ı å¿ĥ +æĪĸ 许 +å¹³ æĹ¶ +ï¼Į çͱäºİ +Ġgr ade +se ct +çĥ ¤ +è´Ł åĢº +åįģ ä¸ī +Ġcitiz ens +ĠEx ception +Ġs ac +Ġmach ines +Com ment +_f l +Ġencour age +Ġ æĿİ +Ġ Ñģ +åħ¬ å®ī +åĽ¾ 书 +u ing +æ¼ Ĩ +ĠThom as +Val ues +or ough +ĠLoc al +ĠAmeric ans +_t est +Ġserv ing +Pl ayer +* d +åIJ¸ æĶ¶ +ï¼Į åIJij +m o +V D +Ġm and +åIJĮ æĦı +ï¼Į æ¯Ķå¦Ĥ +Ġout comes +* s +Ġinstall ation +åĢº åΏ +Ġant ib +r ary +ĠC ost +ä½ĵ çݰ +> & +Ġeduc ational +â̦â̦ âĢĿ +Ġfant astic +Ġentire ly +æ· ĺ +Ġpand emic +ult y +Ġspe aking +Ġr an +Â Ń +Ġm ath +- k +Ġcris is +Ġcru cial +ĠC up +Ġn odes +æĮĩ æĮ¥ +åIJİ éĿ¢ +ï¼Į æľĢåIJİ +raph ics +r b +Ġhistor ical +Ġ 第äºĮ +* p +çļĦ 主è¦ģ +r un +ush ing +æģ ° +Ġblock s +å¹¶ ä¸Ķ +typ es +u ction +ä¹Ł 许 +Ġsit uations +Ġposs ibility +En ter +Ġf ruit +) ). +ĠA L +大 人 +ĠEx ecut +ĠS er +or se +ĠS H +ä¹Ł è¦ģ +Ġcalcul ated +æ£ Ĵ +å¾Īå¤ļ 人 +äºĨ 个 +Ġus age +im ize +d ouble +Ġadminist r +ï¼Į åħĪ +- like +Ġun known +ĠR ight +ial s +çĩ ¥ +" ; +By tes +Ġc ere +äºĭ æķħ +og a +ome ga +Ġev olution +. new +æĭ Į +Ġfore st +æŃ» äºĨ +ĠB ob +åħ³ èģĶ +n ormal +ĠL ibrary +ĠCon nect +ä¸į åĩº +. on +, åı¯ +ĠJ un +Ġep isode +Ġc aught +_ log +Ġfab ric +Ġc abin +åł ¡ +顺 åĪ© +æ¡ ij +og rap +ell ant +.S et +Ġfl ight +th let +ap pe +ĠInst ead +æ¼Ķ åijĺ +ĠN eed +": " +Ġexpl icit +C ell +ĠOb ama +ç͵ åİĭ +* m +ç»Ļ ä»ĸ +å¾· åĽ½ +çī© æµģ +æIJŃ éħį +ĠC R +/ S +à ¨ +çĽij 管 +erv es +ĠInst agram +ï¼Įåħ¶ çī¹å¾ģåľ¨äºİ +ĠI r +çļĦ åIJĮæĹ¶ +ĠA I +up le +Ġpol l +Ġconf irmed +æĮĩ åĩº +åĤ ¬ +æĭ ¨ +纷 纷 +说 å®Į +igh ter +ãĢĤ ãĢĤ +W S +< div +ig r +æķ° åѦ +æµĻ æ±Ł +B UG +è¿ĺ ä¸į +ä¿ © +èŀį èµĦ +ĠF ederal +ä¸Ģ æĿ¡ +å¼ķ 导 +Ġcr ime +pl an +C ore +æĿ Ń +Ġdes ired +t ml +Su pport +Ġgr id +çIJĨ æĥ³ +åį³ ä½¿ +Ġs ad +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠ +è° ¨ +å« Į +du ction +Ġ ip +æ¼Ĥ 亮 +ĠW ay +è¦ģ æĺ¯ +ul ous +J ohn +æĮĩ æķ° +åŁ ĭ +è¦Ĩ çĽĸ +Le ave +大 å°ı +m ega +abet es +A v +åĢĴ æĺ¯ +. out +******************************** ******************************** +ĠF ollow +ĠB ur +åĪĨ åŃIJ +Ġpay ments +ok es +ĠB ox +ï¼Į åIJĦ +( X +大 åĪ© +å± Ī +æ°Ķ çļĦ +Ġcrim inal +女 åŃIJ +ä» ĩ +fo ot +Ġlink ed +æĢĿ ç»´ +Ġsk ill +è¡¥ åħħ +éĢļ ä¿¡ +çī § +Ġthe rm +æĸ ¤ +k ins +Ġoccur red +] : +angu ages +_ AD +Y S +Ġdec ades +/ l +Ġch annels +Ġfor ced +ul f +Ġknow ing +ĠVal ley +p ol +ĠS ource +å¿ Į +åij³ éģĵ +Id ent +ĠS QL +Ġfor th +ĠPH P +Ġ$ {\ +Ġag ents +B uild +æħ ° +Ġplan e +Ġam b +ĠL im +ĠS pe +èĽĭ çϽ +ere n +åĽ¾ åĥı +av as +clos ure +Ñ Į +AS K +Ġris ks +u ous +ĠLou is +comm on +åĩºçīĪ ç¤¾ +å¥ ´ +T ags +ĠAn other +Ġtrou ble +Ġr ough +èī ³ +Ġc ache +F igure +ocol ate +Ġex port +Ġp ump +Ġlo vely +åĩł å¹´ +( void +T wo +åħ¬ åĽŃ +ur se +ĠRuss ia +_b ack +èĬ Ĵ += ( +æľĢ 好çļĦ +Ġadv is +Ġliter ature +æ¶ Į +n ap +Ġinv al +lo or +OM P +ir ms +Ġper man +Ġpur su +ist or +Ġmass ive +t arget +Ġdesign s +N N +ĠC S +F P +Ġgen es +Ġp adding +Ġsh ipping +è´¡ çĮ® +Ġindust rial +Ġclos er +, 她 +Ï ħ +. Is +B it +大 éĥ¨åĪĨ +umm y +æīĭ 段 +Ġcontinu ous +b rid +Ġprinc iples +广 å·ŀ +Ġjud ge +转 æį¢ +ist ical +Ġser ial +ï¼Į ä¸ī +æŁ¥ 询 +å¹³ è¡¡ +ĉĉĉĉ ĉĉĉ +Ġass ign +åī ª +Ġf ell +å¨ ĩ +* b +Ġt ut +Ġmonth ly +æİ¥ æĶ¶ +ĠKe ep +è£ħ 饰 +çĵ · +Exp ression +åķĨ åĬ¡ +æİĴ åIJį +ä¸Ģ ç¬ij +Ġax is +{ " +ĠRuss ian +F ound +a fter +ãĢĤ ãĢĬ +ĠWhe ther +( L +ge bra +/ ( +.f ind +ç§į æ¤į +ĠB efore +ç¢ Ĺ +æĹ© å°± +ĠOr der +Ġs ister +æľ¬ æĿ¥ +Ġco vers +ĠH y +Ġsub t +G A +Ġal cohol +Im pl +å®ŀéĻħ ä¸Ĭ +Ġfav our +CT ION +By te +ap h +Ġcontrol s +ĠIns urance +ĠSh ould +Ġbeg ins +ĠW il +ĠW al +Ġt mp +Ġmain ly +Ġaccur acy +è¿ĺ èĥ½ +å·¥ä½ľ çļĦ +ĠJ o +Ġan s +M ain +Ġcontain ed +åĮ» åѦ +Ch annel +åIJ ķ +满 æĦı +Ġj ur +G en +Ġd raft +t au +Ġm el +Ġjust ice +ĠS C +æľĢ æĸ° +ĠO ption +åįļ 士 +Ġexpert ise +Ġdep art +Ġz one +Ġpercent age +t ag +ch ain +_N AME +I E +b urg +åį § +强 è°ĥ +D ownload +èģ ª +æ¸ ¡ +åľ° 说 +c uss +å°± ä¸ļ +Ġcharg ed +Ġprof it +å¤ĸ éĿ¢ +on a +sh ould +Ġann ounce +æĹĭ 转 +FA ULT +ï¼Į æĤ¨ +Ġfac ilit +ĠT own +Ġher self +) arg +èᝠçī© +Ġis land +Ġneg ot +é¥ ± +éĹ · +Ġsol ar +Ġgu ard +play er +åħģ 许 +M ake +v a +ä¸į åı¯èĥ½ +Ġcol our +åŃ Ŀ +ĠMay be +ict or +æĪ¿ åŃIJ +n el +. \ +. sp +ãĤ ĭ +å¹² åĩĢ +ip eline +æıIJ 示 +s he +ï¼Į æķħ +Ġdest ination +id ers +ĠS up +ĠD O +Ġv oc +G oogle +* c +Ġ äºĮ +çļĦ ä½ľç͍ +,èĢĮ ä¸Ķ +i pt +ĠB lock +Ġrecogn ized +ãĢĤ ï¼Ī +Ġcont ents +Ġt ough +Al so +âĶ Ģ +Î » +Ġc ategories +* i +Pro perties +Ġindic ates +Ġ å¦Ĥæŀľ +Ġn urs +åİ» å¹´ +ï¼Į èĥ½å¤Ł +Ġp in +å½ ¹ +åĵ¥ åĵ¥ +}$ , +Ġcriter ia +举 åĬŀ +第 ä¸Ģ个 +ĠD C +说 è¿ĩ +se cond +S ession +ul ner +_l en +Ġreli ef +t emplate +Ġest imate +æĺ¯ è°ģ +On ly +Ġeval uate +åı ł +Ġinter act +l ers +Ġhouse hold +R ect +* f +Ġ ä½Ĩ +Ġanaly ze +æĪIJ éĥ½ +è¾ ¨ +* y +ro g +Ġmat ches +æµ ´ +Ġhundred s +çĤ¹ çļĦ +raz y +èµ¶ ç´§ +Ġimag ine +r ance +m ond +æ³ Ħ +Ġe lev +ï¼Į å¼ł +à ¦ +Ġto m +ĠF re +Ġindic ated +åı¬ å¼Ģ +ĠMore over +Ġpers ons +Ġas ync +æIJľ ç´¢ +à ¢ +Ġse ed +èµ° åΰ +. k +è¿Ļ ä½į +( z +us es +ç»ı åħ¸ +Ġsc an +Ġcomm ission +Ġsu c +A ST +à £ +çī© çIJĨ +æĦ ¤ +Ġvers ions +çļĦ 第ä¸Ģ +Ġform ation +- W +Ġbring ing +å¼Ģ åħ³ +_ res +put e +.t xt +çİ°åľ¨ çļĦ +å°½ éĩı +Ġâ ī +ĠÏ Ħ +Ġappro aches +ãģ Ĺ +pen ame +çĭ¬ çī¹ +æĢ» ç»ĵ +è± « +ĠCont act +Ġcreat es +åįĥ ä¸ĩ +ä¼ļ åľ¨ +Ġc rack +B ig +âĢĶâĢĶ âĢĶâĢĶ +IC ENSE +d ict +ĠS E +Ġex ceed +ĠSt at +ä¸ĵ éŨ +sw er +Ġwe alth +Ġexist ence +Ġrefer red +ĠE R +Ob j +. V +å¼Ģ å¿ĥ +ac le +Ut il +* r +ä¾ į +产åĵģ çļĦ +Ġocc urs +æIJ ħ +Ġl ux +ĠD u +ç½Ĺ æĸ¯ +Ġcandid ates +è¿Ľ æĿ¥ +Ġj oy +Ġbr ands +Ġf ly +P ay +çł Ĥ +ĠJohn son +ĠHot el +å°º 寸 +ĠMin ister +åĭ ¾ +Ġgrant ed +Acc ount +ĠA ward +ç»ĵ å©ļ +f ont +ä»Ķ ç»Ĩ +Ġcommit ment +Ġoccas ion +èĸ ª +riend ly +饮 é£Ł +Ed it +N e +é¢Ħ 计 +| | +çĺ ¦ +w ater +Ġinf ection +é«ĺ 级 +Ġre new +ç³»ç»Ł çļĦ +requ ire +Ġre ct +Ġdanger ous +izont al +iff erent +Ġw el +çŃī å¾ħ +iss ions +Ġout door +ãĢĤ 对 +åĴ ĸ +'] [' +od d +æķ´ çIJĨ +è¿Ľ æŃ¥ +Ġst able +åĩº çİ°åľ¨ +åħ¬ 主 +Ġinf rastructure +Ġh ook +羣æŃ£ çļĦ +/ lic +T witter +ä¼ł æĦŁ +R un +Ġmechan ism +Ġexpl an +ï¼Į å¿ĥ +ul ing +åį ¢ +çīĪ æľ¬ +ert s +å°± åĥı +Ġd ialog +ĠCom ment +åħ¬ ä¼Ĺ +) ] +r int +Ġneighbor hood +çļĦ æ°´ +çIJ ³ +Ġchalleng ing +åķ ¥ +æ³ķ åĽ½ +* a +ï¼Į æıIJé«ĺ +Ġ .. +Ġsw im +ĠFin ally +Ġde als +p ass +åŀ « +é»ij èī² +ï¼Į éģĵ +èĤ ļ +Ġimp ossible +åĪ ł +ĠPr int +æµ Ĩ +Ġg ro +U ID +åľ° ä½į +Ġun able +Ġlim its +Col lection +raint s +Ġat mosp +ĠJ im +aw ay +ä¼Ļ ä¼´ +å±ŀ æĢ§ +j i +H igh +Ġnav igation +ĠRich ard +ĠL oad +ï¼Į è°ģ +æĻ ° +add r +H ave +Ġen abled +Ġre put +I RE +红 èī² +è¿ Ī +Ġtiss ue +Ġconcent ration +Rec ord +Ñ ĩ +Ġlaun ched +å¼Ģ åIJ¯ +ä¹Ł å¾Ī +Ġli ber +ĠEn vironment +D el +str ong +contain er +Rec ent +Ġmus cle +ï¼Į éĥ½æĺ¯ +åİ Į +osp it +åĵ ¼ +ult ural +大 äºĨ +Ġpl ug +Ġel ig +tern oon +* g +Ġc ro +人 å®¶ +Ġmonitor ing +æŀľ çĦ¶ +Ġguarant ee +æĶ¶ éĽĨ +æĦı å¤ĸ +amb ling +a is +åĨł åĨĽ +* v +. âĢĻ +使 å¾Ĺ +è´Łè´£ 人 +Ġw arn +Ġ æĹ¥ +ĠL os +Ġd uty +ĠN or +é¢Ħ æµĭ +_ en +. z +Ġpresent ation +iz z +od ule +os ph +çĹĽ èĭ¦ +çł ĸ +yt es +R T +_ url +å·¨ 大çļĦ +Ġp ed +Ġh un +ĠJ ose +Ġmed icine +天 æ°Ķ +Ġpr ison +Ġarriv ed +eng er +èĦ Ĩ +Ġn ine +um es +ed it +Ġb es +Ġrespons es +Ġconf lict +{ d +.s ub +r ition +IG N +åħ¶ å®ĥ +Ġv en +Ġhe ro +Ġs izes +Ġen v +主 æĮģ +que ue +Ġresearc hers +rodu ction +a ver +æ¡ Ĥ +G ood +Ġb an +Ġmanufact uring +def ined +ĠTh rough +å¾ĭ å¸Ī +Ġco ast +Ġcalcul ate +ï¼Į çİĭ +Ġcons c +Ġsupp lement +çħ ® +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠ +Ġsu p +Ġne ck +ĠE p +our se +ĠâĢ ¦ +Ġord ered +j u +ãĤ Ĵ +it z +pro ject +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠ +ãģ Ł +avas cript +* h +Ġsp ons +Ġph arm +çľĭ èµ·æĿ¥ +Ġout come +Ġrequest ed +* k +.c ore +人 士 +in em +n umber +设置 æľī +åıij éĢģ +æħ Į +Ġdet ection +_ array +ĠJapan ese +reg ion +Ġvis ible +qu ir +çģ Į +æĪIJ çĨŁ +ĠP ass +* w +ï¼Į 缴æİ¥ +* z +Ġlight s +H ost +éħ · +B ody +ad min +à ¥ +å¿Ĺ æĦ¿ +æĴ Ĵ +è´¢ æĶ¿ +Ġin n +Ġso il +ip her +_ class +Ġnames pace +n ic +ĠC y +åIJĮ ä¸Ģ +Ġbrow n +Ġfood s +Ġexecut ive +. res +Ġinform ed +Ġb acter +åħ¬ è·¯ +管 éģĵ +? : +}} \ +Ġte a +åŃ©åŃIJ çļĦ +Ġparticip ate +Ġen force +Ġcent re +IM E +Ġtell ing +ç͵ æºIJ +åIJĦ ç±» +è¯ķ éªĮ +举 è¡Į +ĠCont ent +N C +å®¶ æĹı +Mat rix +Ġachie ved +åıijè¡Į 人 +* l +Ġreal ized +Ġreport ing +_t ext +* q +èĤ ¾ +w as +Ġ{ } +Ġreg ulations +å¥ĩ æĢª +Ġcont ribute +_ read +Ġinvol ves +çħ ³ +re ens +Ch anged +е н +åĨľ æ°ij +% çļĦ +Ar ch +l ass +* u +Ġdri vers +Ġb ike +Ref erence +AL SE +举 æĸ¹ +Ġnecess arily +Ġo x +, - +ï¼Į æł¹æį® +äºĨ åĩł +Ġatt ributes +åı¯ä»¥ åľ¨ +缴 æĴŃ +åĶ ¤ +ĠM useum +( u +.... .. +ĠAs ia +Ġd ict +ç®Ģ 缴 +æĺ¯ æĮĩ +It ems +ï¼Į åĬł +Ġwe aring +åĽĽ å·Ŀ +çļĦ åŁºç¡Ģ +éĺ ģ +//////////////// //////////////// +r ig +ĠS ports +纤 ç»´ +Ġme at +Ġstud ied +Ġcap able +Ġch art +ĠS ar +Ġmod ified +Ġinvest ors +Ġinsp ired +* j +ï¼Į 为äºĨ +ub y +Ġext ensive +Ġimplement ed +Ġcorrect ly +ï¼Į æīĭ +Ġinstitut ions +um ps +ĠS ite +æĬ ¼ +Ġb inding +ĠO p +å» ī +Ġrepe ated +ãĢĤ èϽçĦ¶ +Ġman ual +Ġcompet itive +u ilt +el ly +ic an +ĠL ive +ion e +Ġ\ " +æĬĢ å·§ +ä¹Ł åľ¨ +_P RO +Ġcont rolled +ä¸ « +âij ł +åı ī +_C H +Ġcl ar +çĤ¹ äºĨ +l ife +å²Ĺ ä½į +ä¸Ģ å®¶ +åįģ åĽĽ +大 å¤ļæķ° +æ¬ º +ĠÐ ² +éĶ IJ +æĴ ¤ +Ġalleg ed +ĠConf erence +I ter +ĠAnal ysis +主 ä½ĵ +Ġb atch +Ġnot iced +ç¬ij 容 +Ġres id +Ġch ief +Wh o +ĠB O +Ġplan et +st ood +(f unction +Ġorgan ic +é¢ ĩ +ĠTra vel +Ġb its +ang o +Ġe c +and on +( F +hel p +Ġinv ent +Ġcrow d +Ġbl ess +W idget +äºĭ åĬ¡ +Ġp apers +Ġcomp at +et ry +ĠL ee +V ol +Act ivity +and roid +Ġj ury +å°Ŀ è¯ķ +æĪ¿ å±ĭ +åIJĪ å¹¶ +app oint +ĠR un +Ġs oul +è¡ ° +G S +å¿į ä¸įä½ı +âĢľ The +Ġacc ord +c ar +ä¸į ä¸Ĭ +åł ª +ĠCent re +G r +( true +ĠAr ts +ãĢĤ è¿ĻäºĽ +ó n +åĪ© äºİ +ire ctions +Ġhappen ing +_m ap +Ġm ur +Ġor ient +æĪij æĺ¯ +ĠPl us +ĠW in +Ġregist ration +åĨ » +p ub +èŀį åIJĪ +ĠU I +ĠF L +Ġar bit +Ġre ward +ĠT our +T emplate +Ġfor t +Ġperfect ly +å·¥ èµĦ +æī ® +Ġpurch ased +大 æ¦Ĥ +ĠSystem s +è£ ¤ +ï¼Į åĽł +ï¼Į åīį +ĠI L +åįģ åħ« +Ġpro port +Ġme al +ãĢĤ å¦Ĥ +æī ĩ +ĠM en +æİ © +çIJĨ çͱ +毫 æĹł +u an +ĠT ax +çļĦ 身 +ĠB oston +ĠPl ace +æ³ķ è§Ħ +ic ing +Ġl ib +Ġunc ertain +J oin +çĶŁ éķ¿ +ur able +t ab +Ġwarrant y +线 ä¸Ĭ +Ġassoci ation +æĭħ ä»» +He alth +åĬ Ŀ +ï¼Į æĸ° +Ġoffic ers +V M +Ġcare fully +il ton +ï¼Į æ¯ķ竣 +ateg y +oper ator +åIJĥ é¥Ń +_ EX +* o +_ user +Ġcon clusion +æİ¢ ç´¢ +ĠC ross +ĠReview s +Ġder ived +Ġgrow n +Ġhard ware +ĠC irc +L eft +Ġup load +cent er +Ġcert ificate +Ġregular ly +æĺ Ĩ +Ġkeep s +Ġform al +æµ ij +èĭ ¹ +Ġdes c +Ġhum ans +å© ´ +Ġrepe at +t ons +Ġsuc ceed +éĩĩ è´Ń +çļĦ æĬĢæľ¯ +Ġs ick +Ġco e +çĮ İ +åıĮ æīĭ +Ġmom ents +Ġguid ance +Ġadv oc +æŁ¥ çľĭ +ĠW H +ï¼Į åºĶ +( ! +is a +-m ail +Ġde posit +åĽ Ĭ +æħ Ī +åijĪ çݰ +ow nt +est yle +åįģ å¹´ +.A pp +èº º +[ j +ĠG ive +们 çļĦ +ä¹Ł ä¸įä¼ļ +{ R +Ġfig ures +p ons +s im +Ġcl uster +om es +Ġj ack +äºĨ åIJ§ +è¡Ĺ éģĵ +æ£ ī +ĠTh ose +- off +Ġcapt ure +ab b +Ġbelie ved +çŃī 级 +ĠC urrent +åıij çļĦ +Ed itor +Ġrepresent ed +Ġt aught +oper ation +åIJĦ 项 +ĠArt icle +pon ents +f riend +Ġp or +æ²³ åįĹ +é¢Ħ éĺ² +ĠI F +Ġt ast +atur ally +Ġ\ \ +Ġ ä¸įè¿ĩ +åħ¬ å¸ĥ +äºĨ ä¸ĭæĿ¥ +Ġpart ial +Ġk m +ĠL i +éĺ Ķ +ï¼Įä¸į è¦ģ +åħļ åijĺ +ĠF ROM +Ġbr anch +ĠCh ildren +Ġpark ing +Ġafford able +Ġcut ting +ĠE ss +_ X +low er +Ġprogram ming +Ġconsequ ences +is p +vent ional +ĠP op +Ġcons ists +Ġsubject s +othes is +éĢ» è¾ij +èij ¡ +ĠCh ief +ãģ ¦ +æĹ¶ å°ļ +ĠApp lication +ut ter +Ġ å¼ł +Ġviol ence +ĠUS B +å¾ ½ +Ġrecogn ize +-s ize +ser ver +Ġg ender +å² ³ +äºĨä¸Ģ äºĽ +e en +Ġshe ll +æĹ º +Ġinst ruction +ĠE mail +æī¿ 诺 +Ġar ms +ĠWARRANT IES +equ als +i ary +ĠJ ones +Ġfl ags +Ġd ance +Ġtest im +Sub scribe +P RO +强 度 +Ġinnov ative +è´ ¾ +ĠW atch +/ C +s d +éĥ½ 没 +Ġconstant ly +Ġwhe el +Ġch apter +oc ial +Ġs ections +( string +c ard +fig ure +se m +ï¼Į 转 +D ocument +åı¦ ä¸Ģ个 +Ġguid elines +Ġcrit ic +ä¸Ģ ä½į +ĠH en +ï¼Į å¸ĮæľĽ +大 åŀĭ +Ġown ed +æģ ¼ +Ġpass ing +ãĢĤ å®ĥ +G reat +Ġprem ium +Ġexp ansion +ĠW rite +æ±Ł èĭı +rit ten +Ġfil ms +Ġsh oes +çĥ ¯ +å¯Ĩ å°ģ +ï¼ī çļĦ +çķĻ ä¸ĭ +Ġbuild ings +èĢĮ ä¸Ķ +_T R +Ġatt ached +ĠH aw +æĪIJ å°± +Ġb read +Ġbo ys +ãĢĤæŃ¤ å¤ĸ +Ġre plic +Ġexpect ations +å®ĺ æĸ¹ +ĠSt ore +c ap +ĠÎ ¼ +Ġdim ension +c raft +F ull +ä»İ æĿ¥ +åİŁ çIJĨ +Ġshe et +åģľ æŃ¢ +æ¯ı 次 +Ġf o +ï¼Į éϤäºĨ +Ġfund amental +we ek +ach ment +ĠMart in +Ġsex ual +å¢ ĵ +æĦıåij³ çĿĢ +æĭį æijĦ +Ġcook ing +å¼ ¥ +Ġslow ly +f c +çŁ Ľ +åı¯èĥ½ æĺ¯ +Ġs essions +çĸ ² +æİ¥ ä¸ĭæĿ¥ +æµ ¸ +太 å¤ļ +ar ation +é ³ +or al +ul s +æµĭ éĩı +Ġf old +onym ous +ĠÐ ½ +访 éĹ® +ãĢĭ ï¼Ī +Ġch icken +P N +çϾ å§ĵ +ĠS elf +å°ı åĮº +Ġdecre ase +at re +éĿ¢ 临 +Ġm ock +Ġinteg rated +Ñģ ÑĤ +av ed +Ġinstr ument +åºĶ该 æĺ¯ +AR D +ä¸Ģ éĺµ +Ġte ch +fol io +Ġg lo +En abled +è¾ ½ +Ġun iform +it led +! âĢĿ +ex tern +ĠP ART +_ERR OR +ãĢĤ åı¯ +Ġdig it +å¤Ħ çļĦ +Ġd ump +ä¸Ģ åIJį +Ġdo ors +åł µ +ĠB ible +ur i +_st art +ãĢĤ è¿Ļ个 +r ase +M ark +ĠGe org +Ġconsider ation +ĠTra ining +Ġn om +ath y +ä¸Ń åѦ +RE S +æĹł æķ° +éĥ¨ éĺŁ +ĠS ize +As ync +st ore +çĥĪ çļĦ +ian a +s in +åº ŀ +. a +æĽ´ 好çļĦ +l ate +Ġte eth +.print ln +æīĢè¿° çļĦ +y es +æ¸ħ æĻ° +Ġcou pl +as ic +Ġ river +N ames +èĩª 主 +cer ning +çĭ ± +Ġg al +æŃ¦ åύ +} (\ +_n um +ĠCan adian +示 æĦı +ä¼ģä¸ļ çļĦ +ĠA rab +ĠP ath +Ġro les +Ġl unch +çł´ åĿı +Ġsurround ing +çĽ Ĩ +ï¼Ł ä½ł +åĪĻ æĺ¯ +Ġrout ine +Oper ation +室 åĨħ +çŃ ĭ +ç»Ĩ èĬĤ +ĠAngel es +Ġy ellow +w est +A pi +at i +- E +ï¼Į æ¯Ķ +ĠEngine ering +èĨ Ģ +ĠMex ico +ĠG ar +æ± ģ +Ġwall s +ĠComm on +ĠCol l +k es +ĠE st +ä¸į 管 +æŃ¦ æ±ī +åĮº åĪ« +ãĢĤ çİ°åľ¨ +Ġ/ > +Ġnorm ally +éĩį åºĨ +ĠL ess +强 åĮĸ +Ġnuc lear +ĠP rivacy +æ²» çIJĨ +. text +ĠP S +Ġl atter +Ġgu est +è¢ ĸ +it is +Ġact s +å±ķ å¼Ģ +Ġoper ate +ĠP DF +Ġmiss ed +æĺİ å¤© +å« ģ +ĠFin ancial +erm an +. In +Ġpotential ly +Ġp it +Ġinteg ration +w ing +æİ¥ è¿ij +Ġind epend +Dis play +Ġaccess ible +对 åºĶçļĦ +æĪIJ çļĦ +ield s +ĠH ard +çļĦä¸Ģ äºĽ +Ġexperim ents +ĠD eb +åĺ ¿ +Ġwid ely +ist ed +o op +ĠF unction +# ' +ĠSc ot +Ġprior ity +Ġaf ternoon +ĠC lean +åįĹ äº¬ +ategor ized +Ġfac ing +Ġ `` +Se cond +天 çĦ¶ +æ· ĭ +Ġpl anned +Ġa st +Ġrepl aced +c or +ä¸Ģ çīĩ +ç»Ļ äºĪ +h av +enc ing +è´ º +éĥ½ åı¯ä»¥ +ick et +Ġelect ron +Ġequ ations +è´ ¼ +C lose +Ġf ro +Ġun ion +ĠC BD +Ġf ib +An al +Ġbath room +ä» ² +Ġcontinu ing +ãĢĤ æį® +_ per +it ar +; &# +Ġcur ve +Ġcirc uit +èĦ ¾ +Ġ" , +Ġattack s +æŁIJ äºĽ +Ġv eter +ĠW orks +il arly +æľ¬ 人 +Ġdis miss +ce ive +]{ } +è¯ ± +Ġi Phone +æĺ ı +ä¸Ĭ åįĩ +åİī 害 +x i +Ġsubstant ial +Ġdi verse +Ġ å½ĵ +ĠG ames +èĭ¹ æŀľ +ĠO il +ap se +åIJ ŀ +ĠC ir +ĠDef ault +Ġclos ely +éĨ ĩ +ä¾Ŀ æ³ķ +ç© Ĩ +or gan +Ġcon crete +è° IJ +ĠL ow +_ UN +Ġel if +Ù ħ +ru g +åĨ³ çŃĸ +çľ ¸ +æĥħ æĦŁ +æ¸ł éģĵ +b rief +/lic enses +P arser +V er +ĠP enn +Ġt ou +Ġab use +æľī å¤ļ +Ġ æĺ¯ +Ġinnov ation +Ġ( [ +ç©¶ 竣 +ĠS erver +at he +ç¥ Ń +clud es +. __ +Ġte levision +ĠFurther more +Ġpen al +è°¢ è°¢ +ã o +LO CK +ious ly +çŀ § +I AL +hold er +Ġconven ient +ĠW alk +}$ . +Ġobject ive +hold ers +Ġadd s +æĤ Ķ +èĢ ¶ +ĠYou ng +ax is +éĥ¨ ä»¶ +-> _ +è´§ å¸ģ +å¨ ĥ +Ġbo at +_ of +T rack +ac ific +ad v +ä¸Ĭ åįĪ +Ġult imately +F loat +临 åºĬ +Ġfeel ings +g b +æij Ĭ +i ac +ĠB E +ore t +æĻ ĥ +Ġhor se +Ġfound ation +: \ +f oo +ĠV ector +, å°Ĩ +Ġprom ise +Ġsc al +V ideo +as hed +Ġinc ident +ĠC ast +ãĢĤ 对äºİ +èī ° +Ġconcept s +ĠPar is +è§£ æŀIJ +ĠAre a +Ġn a +æĪ¿ åľ°äº§ +r ink +ter y +const ruct +Pl ay +Ġs au +st al +( G +t ed +ï¼Į äºİæĺ¯ +Ġdise ases +\ _ +Ġj e +{ } +Ġconnect ions +Ġinst ruct +ä¸Ģ ä½ĵ +ç͍ æĿ¥ +Ġsecond ary +.d e +Ġad j +Ġinter ior +Ġtrans formation +ĠCh ris +ï¼Į éķ¿ +' | +æĪij 说 +å²ģ çļĦ +æķ ² +Ġposs ess +_ con +( err +Ġfol ks +åij¨ æľŁ +.n ext +F E +Ġopp osite +ĠB al +b ur +w s +re nt +æ¯ı ä¸Ģ个 +Ġdel icious +é¼ĵ åĬ± +Ġrequire ment +/ M +S im +å·® å¼Ĥ +Ġl ift +Ġt ub +l ot +ãģ ª +Ġ\ < +sh ot +ĠT ry +ĠM D +est ions +论 æĸĩ +ĠVirgin ia +ç» µ +Ġne ither +æĪIJ åĪĨ +_n ode +åĩºçݰ äºĨ +Ġwor st +al igned +ĠS uch +Ġsc ores +W riter +Ġth in +äºĨ ä»ĸ +ĠRes ources +Ġamount s +ĠC ase +âĢľ ä½ł +Hel p +å¥ ij +Ġab stract +S QL +Ġm ouse +èĩ³ ä»Ĭ +Ġen roll +Ex ecut +W ill +Wh ich +åѦ æľ¯ +re ement +çĬ¯ 罪 +ĠP ersonal +éĥ ¡ +Ð ¼ +B B +re land +_b y +èĢĥ çĶŁ +Ġthem es +ç¼ ¸ +éĩį çļĦ +éĹ®é¢ĺ çļĦ +人 ä½ĵ +ä¸İ æīĢè¿° +ĠM ult +) + +ãĢĤ çͱäºİ +æľī å¾Īå¤ļ +Ġbe ar +St orage +Ġper mit +f rame +ï¼Į ä¾ĭå¦Ĥ +Ġsens itive +Ġv irt +od s +t age +Ġaware ness +Ġturn ing +pl ore +Ġreg ional +Ġdis h +AP P +åľ° çIJĥ +Ġworld wide +产çĶŁ çļĦ +Ġon going +og ether +ç±» çļĦ +Ġhand ling +ä¿® å¤į +害 æĢķ +Ġv ulner +Ġsurpr ise +h us +æľĽ çĿĢ +âij ¡ +è¾ ĸ +d et +è¯Ħ 论 +æĢ§ æł¼ +ep th +ĠYou Tube +åĬ¨ çļĦ +åĩ ¸ +ĠAdd itionally +æ¶Ī éĺ² +ĠL earning +r as +ĠM a +Ġeng age +T L +ĠR oom +Ġag encies +å·¥ä½ľ 人åijĺ +ĠWord Press +梦 æĥ³ +AV E +Ġcl othes +ĠL td +Ġs ys +Ġne uro +un ctions +ĠH ospital +Ġbed room +åıį æĺł +èģĶ çĽŁ +Ġmet ab +Ġr ig +che dule +ĠLe vel +cl ip +ential s +i ot +çϽ èī² +Ġcommon ly +ĠR o +äºĨ åIJĹ +st one +åįı è°ĥ +çļĦ åĨħ容 +Ġm ice +Ġvisit ing +æĪª èĩ³ +it ivity +Ġunder lying +W orld +ĠCal culate +èĩª è¡Į +éŃ ħ +ĠP o +Ġdeal ing +AN G +acc ount +èIJ Ħ +é¢ ¤ +k m +带 æĿ¥çļĦ +Ġp il +ĠJ oe +æ¸ħ æ´ģ +ãĢĤ çĦ¶èĢĮ +let on +Ġcr usher +l ay +Ġtrend s +çĶŁæ´» ä¸Ń +ç»´ æĮģ +A IL +Ġv ast +Ġb odies +æ¶ Ľ +Ġinter actions +âĢľ We +Ġstand s +æ£ ĭ +ä¹Ł èĥ½ +C F +ĠM ike +Ġfair ly +Ġw arning +ie ce +转 ç§» +ab il +æ² ĥ +èĩ Ń +Ġlist s +åİ ¦ +V I +Ġre cept +Ġr ating +Ġex clusive +æ¸ħ æ´Ĺ +Ġincred ible +ĠW ild +ç®Ģåįķ çļĦ +ä¼¼ çļĦ +ä¸Ģæł· çļĦ +æľī 个 +B log +S M +头 çļĦ +ãĢģ ä¸Ń +UL AR +表 æĺİ +éĶ » +åįĬ å¹´ +å¾Ī 大çļĦ +é¢ Ī +æĢİä¹Ī åĬŀ +Ġanx iety +rib le +Ġsk y +' ], +ï¼Įä¸Ģ èά +Ġn arrow +Ġwhere as +b reak +T otal +è¿ĺ ä¼ļ +c f +æģIJ æĢķ +ĠC ur +Ġl osing +Ġmov es +ĠP ot +ĠB ow +. con +ĠP ut +U ST +but ton +Ġlik ed +ĠR ights +Ġimpro ving +} = +Ġrem ark +ess ages +Ġyes terday +, y +ĠSup reme +ĠPro perty +as tern +Pre vious +m ic +Ġl ip +使ç͍ çļĦ +RE SS +ĠStud ents +Ġlist ening +ĠAcad emy +Ġoption al +Ġv ital +Ġ âĢĿ +é¦ ¨ +D ialog +as ters +ĠG D +_ OP +Ġg rew +Ġinval id +çŀ ª +Ġarr ang +èij¡ èIJĦ +æľī 没æľī +Ġquant um +ãģ ¯ +ĠJe ff +P ublic +æī© 大 +èĥ ģ +P arent +è¶³ çIJĥ +n n +ĠInd ex +T V +åįģ åħŃ +Ġserv es +Ġcont roller +ial ize +Ġh urt +ack s +ol ving +ç¢ ij +Ġ! == +Ġt ip +ol ver +Ġl augh +Ġconsum ption +Ġh ate +çĽij æµĭ +n ab +ç²¾ 彩 +åķ ¡ +ĠCarol ina +L a +ĠU k +ä½Ļ é¢Ŀ +Ġdemonstr ated +Ġqu ote +å°ij 女 +Ġcirc le +ĠJ SON +Ġintrodu ction +ĠM ur +çĿĢ çļĦ +ï¼ģ æĪij +æıIJä¾Ľ äºĨ +par se +Ġtax es +id x +Ġprim arily +æĶ¹ éĢł +ra id +t mp +ãĢĭ ãĢĬ +æĢ ľ +æĹģ è¾¹ +% . +åĿ ij +çľĭ åΰäºĨ +Ð ´ +_f or +Ġe ase +ä¸ Ļ +Ġth reshold +认 è¯ģ +éĢĤ å½ĵ +Ġs pl +æľĪ 份 +ut ch +u ce +Ġdirect ed +æ¯ ħ +Pr int +缸åħ³ çļĦ +pl us +ann a +Ġs ou += False +Ġt error +ä¼łæĦŁ åύ +Ġs ending +ĠSt ock +ĠAdd ress +( key +æ¤ Ĵ +as ant +çݯ èĬĤ +丰å¯Į çļĦ +{ align +if er +å°ı ç»Ħ +æł¡ åĽŃ +g ener +çº ½ +P op +Ġass igned +P anel +Ġbirth day +Ġimmed iate +it ative +ĠI ss +Ġredu cing +Ä ģ +èµ ł +ef ined +(f alse +.t ype +\ left +S erial +_t able +ï¼Į åĪ« +ãģ ¨ +åĨħ å¿ĥ +ul er +åĩº æīĭ +ĠStand ard +. Text +ãĢĤ è¦ģ +E rr +Ġl ayers +æ¡ ¶ +Ġintellig ence +Ġtra ined +Ġapply ing +Al though +ĠI de +r ick +æŁ ı +ĠW at +è¿ĺ åı¯ä»¥ +_l ength +Ġin line +Ġbas ically +Ġed it +( ctx +çļĦ ç¥ŀ +Ġpolit ics +说 ä»Ģä¹Ī +c ur +ç§ij çłĶ +Con f +L Y +ä¸į åıĬ +act iv +æĺ Ĥ +æĥ³ çĿĢ +ap ing +M sg +ĠM id +Î º +D own +ĠSt ory +åѦ ç§ij +d i +è¿ĩ 滤 +n am +Hel lo +lis her +ï¼Į æĿ¥ +C ategory +ãģ § +ĠIt alian +ict ed +Ġflow ers +æł¹æį® æĿĥåĪ©è¦ģæ±Ĥ +Ġbl ank +H as +Ġl ies +Ġin ches +. Error +ĠN ever +å¤ļ 次 +D IT +éĻ Į +il ly +Ġst yles +Ġperform ing +çĥŃ æĥħ +Ġsil ver +Ġs ight +Ġp p +B R +ï¼Į çľ¼ +end or +_s ub +两个 人 +, b +éľ² åĩº +des cription +ç¢ § +ä¼Ĺ å¤ļ +ç»ĥ ä¹ł +æŃ¤ 次 +éĤĢ è¯· +H ttp +æĺ¨ 天 +V C +è¾ħ åĬ© +ĠP aram +åĴ ³ +Rev iew +Ġstrong ly +lement ary +Ù Ĩ +æ¡Ī ä»¶ +r ange +O U +导 æ¼Ķ +Ġth orough +å¿ĥ æĥħ +ĠM essage +ĠM ic +森 æŀĹ +ĠS P +Ġ ± +let ion +Ġexp enses +are n +Ġ' \ +or ne +_ out +æ¸IJ æ¸IJ +AR Y +Ġcontribut ion +ä¼ļ åijĺ +ĠÃ Ĺ +ost ic +ãĢģ ä¸į +ĠAut o +Ġsustain able +Ġarchitect ure +Ġ ë +Ġcho osing +èļ Ģ +ay lor +Ġtrans mission +ï¼Į çľĭçĿĢ +it o +强 大çļĦ +ç¼ ł +ric es +Ġext end +W ARE +主 å¸Ń +eps ilon +ĠMed icine +un a +Ġbreak fast +Ġinvol ving +è¾ © +w d +em on +er red +çļĦ ä½įç½® +Ġ 第ä¸Ģ +Ġorigin ally +Ġhous es +çŃĶ åºĶ +Ġcount y +ĠL ab +审 计 +âĢ IJ +in f +ber ry +åĴĸ åķ¡ +RE F +åĸ Ĥ +F ont +æľ¬ 书 +typ edef +t k +Ġbut ter +ãģ Ļ +. To +ĠL I +Ġless ons +ĠInt eger +Ġl ie +s i +å°Ĩ ä¼ļ +Ġte en +il a +人 æķ° +le ases +åĪĨ 离 +Ġmagn etic +ĠC ath +Ġsm ile +Ġspirit ual +åħ³ å¿ĥ +col umn +ĠAg ain +us r +ĠP A +á ĥ +ĠSp irit +ĠF ed +è¯ģ 书 +带 åĬ¨ +éģĵ çIJĨ +reg ister +åΰ è¾¾ +éŁ µ +Ġill ness +z y +ĠL LC +ĠAustral ian +Ġmill ions +æĺ¯ è¦ģ +æı Ń +D D +èĪ Į +åľ° çĤ¹ +OD O +B L +æĸ © +Ġanal ys +M r +#if ndef +æĺİ çļĦ +çĸ Ĩ +Ġphot ograph +N ESS +ev al +ãĢĤèĢĮ ä¸Ķ +ç®Ĺ æ³ķ +Ġm i +ĠM iddle +Ġad m +å§ » +å±ı å¹ķ +ĠT ri +æĢĢ çĸij +Ġpet ition +åį° è±¡ +æĭ ¾ +Ġpres ents +> , +N O +in ator +ĠH TML +) -> +ä¹Ł å°±æĺ¯ +强 大 +åĬł çĥŃ +$ this +Ġregard less +Ġtal ent +Ġperson ally +AT US +an al +ol ly +表 æ¼Ķ +çĭ IJ +Ġt ill +_c ast +ĠWe bsite +R ad +LE D +宣 å¸ĥ +ĠSm all +Ġcollabor ation +ĠF our +Ġexperim ental +ï¼Į æīĵ +os c +åį³ å°Ĩ +ra pe +å¸ ķ +Ġign ore +Ġcheck ing +Ġprote ins +_RE G +èĥľ åĪ© +Ġb anks +Ġpe ak +ok ed +cl oud +ĠI ran +Ġh ole +ĠI II +Ġmin imal +ĠS at +éĵģ è·¯ +空 è°ĥ +Ġfind s +å¹³æĸ¹ ç±³ +Ġ urban +Ġdraw ing +ï¼Į åIJ¦åĪĻ +Ġqual ified +åº Ļ +Ġd ates +Ġ ä¸Ń + ® +edd ed +Ġprefer red +Ġn arr +M I +ĠO pt +ç³ ķ +ç½ IJ +ĠIs lam +Que ue +éĶ Ī +ĠCl oud +Ġver ify +- com +the re +ä¸įå¾Ĺ ä¸į +èĪĴ éĢĤ +o ices +on al +Q UE +èĶ ¬ +ĠS ep +ble m +身 åIJİ +åīį éĿ¢ +ch i +ĠSp ace +Ad vert +Ġcon cerning +T oday +ag ues +èĦij è¢ĭ +ĠSh are +Ġvill age +èģĶ èµĽ +Ġhab it +Ġstat istics +æķĮ 人 +æ¯ı å¹´ +Ġre verse +U nder +ĠS ales +çĽ¯ çĿĢ +æĮ £ +èĥ Ģ +_st atus +ĠT reat +. end +æĶ¶ åΰ +imens ional +ĠCl in +ĠE ll +åŀĭ çļĦ +åĿĩ åĮĢ +ä¸į 太 +` , +im ages +Ġyoung er +线 çļĦ +ĠA ug +Ġrec over +Ġb one +ik es +温 æļĸ +Ġ çİĭ +im m +ist ing +Ġcaus ing +_ on +éģ ® +å¤ ķ +Ġden ied +ag en +Ġstrateg ic +å§Ķ ä¼ļ +ĠWilliam s +J ob +%%%% %%%% +åĬ « +Ġany way +头 åıij +åĵª 个 +ĠT w +m ake +ç²ī ä¸Ŀ +ĠA ri +D raw +Ġeng agement +ãĢĤ åħ¶ä¸Ń +Ġwhen ever +PO SE +Ġsomew hat +没 æĥ³åΰ +éĿĴ æĺ¥ +Ġmeasure ment +Ġunder stood +/ (- +Ġcol le +ï¼Į 缮åīį +, ä»ĸ们 +â Ĥ¬ +Ġra il +( result +Ġinj uries +Ġto x +r ich +Ġc odes +Ġcon version +åİŁ æĸĻ +Ġal ter +æľįåĬ¡ åύ +åīį å¾Ģ +OR Y +ĠP L +å® Ļ +Ġche ese +B N +å® ´ +Ġfe at +Ġsub mitted +{ x +ç´ł è´¨ +_C L +Ġf ault +ĠF air +ï¼Į çϽ +ãĢĤ è¿Ļç§į +æĺ¯ çͱ +è¶ħ 级 +Ġdiv ision +pp ers +f d +Ġanc ient +ĠSp anish +èī² å½© +çªģ åĩº +æĺİ æĺŁ +ä¼ĺ éĢī +è£ Ļ +åIJĮ æ¯Ķ +Ġm aps +Ġas set +Ġdet ected +im a +æłĩ å¿Ĺ +éľ ľ +roll ing +Ġsearch ing +Ġdr ag +p a +ans as +Ġpl ain +k o +ä½ł æĺ¯ +ä¹ī åĬ¡ +at omic +Param eters +Ġfight ing +os a +æ¡Ī ä¾ĭ +æľī æľº +Ġtr ick +æ·¡ æ·¡ +æ¬ ł +* , +éļı åIJİ +åĵģ ç§į +, 大 +· · +Ġcop ies +ĠN ight +ĠStud ies +Ġt iny +çĪ ¹ +ï¼Įä¸į æĺ¯ +Ġinter val +Ġdemonstr ate +E ven +ĠC ore +æ» ¨ +. X +Ġremain der +at ial +Ġent reprene +at ile +Ġst ability +ĠR oman +å°± ç®Ĺ +çļĦ ç¾İ +广 åľº +on na +èħ º +PE CT +Ġlif estyle +èµ ģ +Ġpo inter +Ġg ap +Ġdis appoint +E ffect +ond er +ĠM ill +d ec +é¥ ¼ +f ind +Ġ ä»İ +Ġ( _ +Ġjur is +or able +读 书 +Ġb asket +Ġdom estic +å¸ĥ å±Ģ +Ġmag ic +ĠD ie +) [ +ä¾ ł +çĺ ¤ +åħħ ç͵ +sec urity +op ic +èĬĤ çĤ¹ +æīĢ å¾Ĺ +Ġdisplay ed +çĿ ģ +Ġpartners hip +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠ +Ġmeet ings +åı¯ éĿł +f i +Arg ument +Ġtick ets +åħ± åĴĮ +Ġdisc ipl +' ), +Ġover w +ar ry +Ġtrack ing +çļĦ ç¡® +u ct +f ront +Fl ags +Ġent ries +Ġrem ind +åĽŀ æĶ¶ +et ing +ä¸į å¤Ł +Ġspect rum +åįģ ä¹Ŀ +ĠV an +Eng ine +ĠF IT +ane ous +. un +Ġmanag ing +Ġdeb ug +- ind +el i +ä¸į å¦Ĥ +ãĢĤ \ +ï¼Įä¸Ģ å®ļ +Ġlab els +K ind +_d ict +Ġed ition +en ess +ERS ION +R ule +ff ff +( in +åģļ æ³ķ +ä¸Ĭ 涨 +Ġphen omen +ĠI O +r ine +for ward +Ġpar allel +J SON +çĦ ° +, n +Ġstud io +ãĢģ æĸ° +Ġres olve +_ end +_M AX +æģ Ń +Ġentertain ment +ĠI reland +Ġfr ust +Ġh at +æ² IJ +Ġdiagn osis +w args +ain ts +ä¿¡ å¿ĥ +ru ption +Ġcheck ed +å¾Ĺ åΰäºĨ +å¾Ĺ äºĨ +åĨ ¯ +Ġsp oke +ĠM ember +çĸ«æĥħ éĺ²æİ§ +ç§Ł èµģ +L earn +é¸ ¿ +ä¸ĵä¸ļ çļĦ +Ġben ch +s ql +Ġserious ly +mat rix +ĠIt aly +Ġf raction +çŃī 人 +f n +ob by +In valid +Ġrestaur ants +Ġrec ording +_ u +åħ¨ ä½ĵ +Ġp y +ac her +å±ħ ä½ı +Ġres et +Ġevery day +å¸ ½ +Ġfact ory +Ġs ed +ĠG irl +end ant +Ġdo se +å¾Ī 好çļĦ +ï¼Įä¸į èĥ½ +n or +çļĦ æķ°æį® +å½¼ æŃ¤ +Ġc tx +æĻ Ĵ +Ġobvious ly +n av +æĪ Ī +at ar +åĮ Ĩ +è§ģ è¿ĩ +æī ¯ +Ġdro pped +, çĦ¶åIJİ +â ĺ +p o +Ġl ad +Ġrecogn ition +Ġcommun icate +te en +n i +or ters +ĠAp ache +point s +Ġrecommend ations +Ġmeasure ments +åIJ« æľī +Fe ature +ä¹Ł ä¸įæĺ¯ +Ġvert ical +ĠTh ree +Ġw et +åĪ© çİĩ +Ġintrodu ce +el lect +çļĦ èĢģ +requ ired +ĠE ffect +èľ Ĥ +L P +ang ers +Ġdra wn +Ġdat aset +Ġact ing +olog ist +ant ed +ĠC redit +Ġprov en +Ġsurv ival +äº Ń +éĺ² æĬ¤ +Ġf older +_ I +ĠK en +çĶ» éĿ¢ +ï¼ĮæĹł 论 +_ arg +Re al +Ġbu f +Cal culate +J ava +Ġcommit tee +è Ł +R NA +Ġauthor ities +Ġant icip +Ġsubsequ ent +_f rom +S O +Ġwalk ed +Ġdisc rim +ater n +æī¹ åĩĨ +åIJ ¾ +Ġincor por +Ġexpos ed +C G +Ġmount ain +çݰ æľī +ir a +éħ ± +æļĤ æĹ¶ +ç» ³ +it age +ĠJust ice +ï¼Į ãĢĬ +ĠL ittle +omet ric +ĠExecut ive +Ø ± +ĠH ope +O k +Ġmin ing +ĠP UR +OL D +ee k +Ġcommun ications +å±ķ çݰ +ĠJ on +Ġsym met +Ġc razy +D id +ick er +ï¼Į ä¼¼ä¹İ +顾 客 +we red +Ġst ake +: b +Ġper missions +Ġre form +B usiness +C ategories +à ł +am ber +Ġprepar ation +空 ä¸Ń +Ġsurpr ised +æİĪ æĿĥ +æµ ¦ +åIJĪ è®¡ +ĠM obile +Ġb le +ĠT urn +um a +èµ Į +Ġsomew here +ra k +ĠH as +Ġmod er +app er +ä¸į 对 +çħ§ 顾 +om ething +ç¿ ł +ast s +Ġd ust +ĠPol ice +Ġfra ud +Ġphil osoph +Ġcomplet ion +Ġappro val +ent le +Ġr h +æĪij å°± +à ® +ĠF ac +app end +Ġconf ident +Ġpartic les +çĽij æİ§ +.g oogle +ĠN C +u ced +c ers +Ġtarget s +Ġmanufacture r +çī© åĵģ +_ result +ch arge +e an +ç§ĺ å¯Ĩ +Ġpain ting +Ġh ur +P UT +ĠDan iel +. æł¹æį®æĿĥåĪ©è¦ģæ±Ĥ +( __ +èµ ´ +r at +ĠV ictor +éĤ£ ä¸Ģ +rec ord +L ock +ï¼Įå½ĵ çĦ¶ +eth yl +ri ers +d k +ĠCook ie +ĠMc C +Ġacc um +Ġrem oval +Ġ{ " +失 åİ» +_ z +èij£äºĭ ä¼ļ +åĬ¨ æĢģ +Ġland scape +Ġorgan ized +ly mp +Ġd ining +ha ust +Ġf asc +Ġad equ +Ġg aming +ins on +Ġdef e +Ġbrow s +èİ İ +Ġsens or +åijµ åijµ +ä¼ ª +-p arty +å®ŀ è¡Į +Ġfun ny +Ġnear by +Ġweek ly +Ġprocess ed +l ang +ĠT erms +Ġshould n +Ġins ights +Ġinit ially +é£ŀ æľº +Ġgra v +Ġb low +j ava +Ġsched uled +ĠD og +Ġfl uid +ch ild +æıIJä¾Ľ çļĦ +Ġg ate +æĻ ķ +T ool +Ġdi abetes +设 ç«ĭ +Ġlik es +is er +.p arse +åħ´ å¥ĭ +ke ep +asc ular +飩 åĽ½ +æ¼ ł +ĠN ode +被 人 +èī¯ å¥½ +UN D +ps ilon +Ġcl imb +é¹ ı +an es +R oot +Ġfin ite +p rivate +å¯ Ĥ +. co +ĠE s +èĸ ĩ +ĠF ar +缸 åºĶçļĦ +Ġmat hemat +Act ive +åĨĽ éĺŁ +Ġb are +ĠE th +ĠSte ve +ĠK n +Pr ice +it an +Ġp ill +ï » +Ġap artment +Ġl oves +Ġcon clude +Ġfl ash +Ġcolumn s +S ection +. New +åį ¿ +Ġprom ot +Ġag es +I LL +Ġ" < +Ġstring s +b ound +ear ing +Ġvis ited +ãĢĭ ãĢĤ +ic ity +the less +.m odel +Ġstrugg le +Ġfit ness +Ù Ī +ĠD id +Ġs ampl +Ġw est +Ġcy cl +c b +Ġf le +app lication +ĠM att +Ġfac es +ĠA C +äºĨä¸Ģ 声 +ç®Ģ ç§° +Ġtreat ments +çģµ éŃĤ +Ġdel ight +Ġt ack +ï» ¿ +缮 å½ķ +Ġwrit ers +å¤ ¸ +Ġtra il +åĨ² åĩ» +æĬĬ æı¡ +li ers +ĠO K +èµ· 身 +st ack +Ġgen u +)/ (- +Ġup coming +Ġappoint ment +çĨ Ļ +声 æĺİ +De lete +ps i +Ġt ank +ï¼Į 第ä¸Ģ +s f +åŃIJ ä¸Ĭ +g ments +ĠS olutions +æ¹ĸ åįĹ +Ġabs ence +Ġw ra +ens us +Ļ Ĥ +Ġre in +ĠCor poration +Ġwith draw +il ation +Ġm ob +èĢ ķ +çĪ µ +ç»Ī 端 +Ġesc ape +Ġch ose +it ting +åħ± 享 +çļĦ æľºä¼ļ +çľĭ åIJij +og gle +ä¸Ģ åľº +Ġbound ary +Ġob lig +Ġopt imal +ific ial +ĠJack son +ĠOh io +Ġag greg +ç¡ ħ +Ġdevelop ers +å°± æľī +pro of +Ġcomplic ated +ĠCon fig +al o +ĠF eb +ĠMon th +Ġl at +Ġtick et +s en +Ġfin ance +æĮĩ å®ļ +æĹł å¥Ī +ĠN a +å¡ij æĸĻ +ĠR om +Ġsupp lies +raz il +åľº æīĢ +Ġhost ing +A ng +ĠD aily +ul um +ĠB Y +Ġent itled +Ġfeature d +Ġad min +åľ¨ è¿Ļ个 +é¦ Ī +Ġmin i +Ġi o +ĠL abor +pro duct +Ġdescrib es +Ġh all +Ġatmosp here +å¦ ® +âĢ ĭ +Ġcan cel +!! !! +in cluding +Ġb at +åħ¬ åŃIJ +Ġexecut ion +Ġ åı¯ +Ġstrong er +åºĶ 对 +éĩį éĩı +ãĢĤ 缮åīį +è¿ij æĹ¥ +让 æĪij们 +U V +åĽŀ 头 +") ; +è´¢ 产 +f ilter +è¿Ľ åı£ +ä¸Ģ çľĭ +èĶ ¡ +è¯ ŀ +ug s +ĠF estival +Ġdeb ate +ort ed +Ġg ambling +_ ext +èѦ å¯Ł +æ·± åĪ» +æĥħ å½¢ +< li +è¿Ŀ æ³ķ +妻 åŃIJ +æ° ¨ +çļĦ 说 +W he +ev in +çİ ² +æ·± 度 + » +æĮģ æľī +Ġmort gage +Ġdriv en +èĪ Ł +Ġsuff ering +ãĢĤ ä¾ĭå¦Ĥ +ER V +士 åħµ +Ġextrem e +ĠCh apter +< int +çļĦ éķ¿ +ath an +Ġl anguages +äºĨ æĪij +å¿ĺ è®° +Ġs orry +ra ine +Ġt f +amp s +ĠT em +缺 ä¹ı +Ġn ob +ï¼Į 羣 +Ġc oc +Pol icy +ĠStud y +Ġoper ators +Ġnew sp +è¡ į +util s +es is +, åıĪ +a ire +oid s +Ġmatch ing +ï¼Į å·² +.W rite +ĠProduct s +med iate +ĠM achine +ï¼Į éĻĪ +-b y +åĨĽ äºĭ +Ġelect ro +Ġlow est +ru le +Ġsh arp +Ġas ide +ç͵ æµģ +o a +å¨ģ èĥģ +æĩ Ĵ +Ġcont emporary +S pace +ä¸Ń åĮ» +Ġprinc iple +Ġpr ay +çĶŁ åŃĺ +éļı æĹ¶ +ï¼Į ä»Ĭ天 +Ġre ly +ãĢģ æľī +_ is +Ġbuild er +ä¸ĵ åĪ© +ĠM ER +. as +åľ¨ æĪij +ï¼Į åİ» +Î ¯ +ĠP an +Ġremain ed +Ġflex ible +ĠT er +-b e +Ġelect rical +éĹ´ çļĦ +æĢ ĸ +Ġw ww +\ t +ĠR oyal +éĩį å¤į +( get +ç¬ ¼ +ĠCh air +Ġclaim ed +Ġaccord ance +æīĭ ä¸Ń +Ġch ronic +I mp +ĠE state +对 çĿĢ +æŁ ´ +ĠM aterial +ä¹ĭ ä¸Ĭ +Ġfl av +ĠA ud +P G +å¸ IJ +v in +ĠB ased +D O +Ġj ew +Ġdec ade +gy pt +Ġcap abilities +c ut +妹 妹 +ĠUn it +ä¼ł éĢĴ +æľº åľº +cl osed +Ġbox es +y y +ĠCol umb +Ġv ot +ï¼Į äºĮ +Ġlight ing +T im +ä¸ļ 绩 +Ab stract + ± +Ġsign ature +Ġent hus +åĬŁ çİĩ +Ġtom orrow +å®Į ç¾İ +Ġt ags +_ object +Ġmix ture +z ure +@ " +ro x +ï¼Įä¸į ä»ħ +Ġed ges +Ġstret ch +Ġtransport ation +ç© ´ +OM M +ãĢģ æ°´ +åľ¨ ä»ĸ +Ġrow s +(f ile +l ie +Ġcamp us +æıIJ 交 +ian o +çļĦ ä¸Ĭ +- x +Ġg ram +- con +å¦ ¥ +ĠCh ild +ĠM rs +et ary +G lobal +Ġb ridge +ä¿Ŀ åŃĺ +Ġincreasing ly +ter ior +M edia +ç¼ĵ ç¼ĵ +çª Ŀ +Ġ ठ+Ġeng aged +оР² +AS H +亲 èĩª +ï¼Į æŀĹ +Ġtext ure +å®ļ æľŁ +ed In +est roy +er as +.j oin +çº ± +at aset +ĠR en +è ¤ +Ġrelig ion +Ġmembers hip +UN T +, å°±æĺ¯ +Ġhe nce +éģĵ å¾· +ä¹ĭ å¤Ħ +大 éĻĨ +p ool +åĢº åĬ¡ +G ame +h r +pos ed +ĠB ed +Ġb urd +çļĦ åħī +Ġa thlet +éĩĬ æĶ¾ +T F +< string +æİ¨ åĩº +f ree +ï¼Įæľī äºĽ +Ġsign als +Ġc ake +Ġp airs +ĠR am +, åĨį +ĠH D +Ġpull ed +åIJĦ ä½į +Ġneigh b +ä¸ĸçķĮ ä¸Ĭ +Ġpack ages +åIJĪ æł¼ +ĠCh ampions +################ ################ +Ġexpl ains +磼 çĽ¾ +ä¼ IJ +Ġtw enty +æĬ« éľ² +æľ ´ +Ġb in +} [ +âĢĻ , +ĠH on +Ġpros pect +Ġprov ision +am era +.st art +w ar +æŃ¤ åĪ» +_ var +ĠSaf ety +å¸Ĥ æ°ij +ĠS ol +æī¿ 认 +è® ¶ +Ġgr ass +ĠM il +l ive +Ġag ric +æ¸ Ĺ +_b lock +FT WARE +Ġ æľī +ĠH im +. se +ott ed +ĠÏ Ģ +Ġlog ic +æĢ§ è´¨ +ĠPUR POSE +è¿Ľ æĶ» +Ġd iversity +Ġc ute +ON G +å¿ħ çĦ¶ +个 æĢ§ +S end +Ġquant ity +ï¼Į使 å¾Ĺ +Ġtrig ger +atch ing +PI O +é¦ĸ 次 +z ym +ĠF oot +ï¼Į å®ŀçݰ +Ġperman ent +( str +åĩº åıij +åľ° éĿ¢ +æ´ Ĵ +is ition +Ġrec ip +ĠMich igan +æŀĦ 建 +ad or +ant ly +å² Ń +OW N +ä¸Ĭ æĿ¥ +Ġnav igate +èĴ ĭ +å§ ¨ +Ġn aturally +cle ar +_m ode +om atic +Ġcomp ute +â Ĩ +åľ° ä¸ĭ +B M +enn is +Ġexam ine +Ġins ight +车 çļĦ +Ġearn ed +CH ANT +Ġmere ly +- res +C opy +åŃ©åŃIJ 们 +æĥ³ èµ· +O pt += - +Ġshoot ing +å±Ĥ 次 +åIJ« éĩı +第 åħŃ +Ġpar agraph +è¾ĥ 大 +Ġcol on +âĢĿ âĢľ +åħ¥ äºĨ +çļĦ 产åĵģ +.t est +çŁ¥ åIJį +èIJ Ŀ +Ġli ability +天 æ´¥ +Ġaf raid +çŁ £ +åݨ æĪ¿ +Ġcomp osition +ĠChar les +Ġelig ible +Ġav ailability +æİ ĺ +ĠT ag +Ġst ages +We bsite +Def inition +Ġpow der +ĠPART IC +åį ¸ +erv ing +ĠCons ider +临 æĹ¶ +ĠE r +Ġas sembly +Ġdist ingu +Com mon +ĠTe ch +Ġanaly zed +- z +æĹł 人 +ĠJ ac +Ä ± +. ed +Ġcare ful +éĽĨ ä½ĵ +èĪĴ æľį +end ers +(" % +Ġinsp iration +end ment +æĦ ģ +Us ing +Ġgover ning +Ġfore ver +Ġh ire +å·¥ åİĤ +) ), +pro p +ĠB ul +åı¯ä»¥ éĢļè¿ĩ +Ġlarg ely +åĽŀ äºĭ +ĠDes cription +æī Ķ +æĮĩ 令 +Ġt all +_m ax +Ġload ed +èĢĮ ä¸į +Trans form +Ġst ood +iz able +-st yle +对 åºĶ +ä½İ äºİ +èĵ Ħ +xy gen +ra cy +A F +. The +n ote +] ). +Ġco al +å¼ı çļĦ +il ty +Ġtrans actions +åĵ Ģ +re nd +Ġob st +Ġre nd +Ad apter +大 äºİ +(t ype +ĠBuild ing +ĠY et +Ġreg ulation +ribut ed +Ġsl ots +_tr ans +乡 æĿij +两 å¹´ +éĥ¨ ç½² +_ comp +G amma +Ġimm un +are a +æį IJ +ig ger +Ġn an +in itions +. Name +Ġcompens ation +- end +ul ator +ï¼Į èĩªçĦ¶ +æīį ä¼ļ +æĽ´ 为 +Ġh ospit +çij ¶ +Ġwin ner +é¢ ĸ +åįģ ä¸ĥ +ĠIn put +ĠT ask +Ġch ocolate +s is +D ay +D T +ĠS ale +_add r +Ġinf lam +ont o +add ress +G raph +Ġimp lements +åıijçĶŁ äºĨ +D uring +m al +ä¸Ģ åıª +Ġimm une +v c +d y +æĹ© å·² +å¯ ĵ +èij Ľ +Ġapp end +Ġbott le +Ġmag azine +Ġu l +æĹħ è¡Į +O wn +claim er +å±¥ è¡Į +Ġal pha +Ġhe aling +å¹² çĩ¥ +E vents +en um +osit ory +ul ating +el le +ä¸ Ľ +éħį å¥Ĺ +ĠN E +Ġbe er +èĬ¯ çīĩ +I con +è¯ģ æį® +æĭĽ èģĺ +Ġr ub +Ġinst ances +Ġadvent ure +æĹł æ¯Ķ +p ir +ĠF arm +it ud +De cl +ãĢĤ 为 +åĬł å¿« +Ġex ecute +pl ugin +åį° åº¦ +æŀ ļ +ãĢĤ å½ĵçĦ¶ +ä¼ĺ æĥł +Ġrent al +ä¸į è¡Į +Ġapp lies +CHANT ABILITY +#if def +on th +or ce +ç¾ ŀ +Ġdis k +Result s +ĠBook s +åĽ´ ç»ķ +W E +éķ¿ æĹ¶éĹ´ +ic ient +ĠCol lection +读 èĢħ +Ġcomp act +çĬ¹ 豫 +çī¹ æĢ§ +ä¸Ģ 人 +Ġtestim ony +Ġp arser +è¶ ģ +d p +èĬ Ŀ +Ġvel ocity +åİĤ å®¶ +Ġtem porary +Ġhon or +Ġun w +ĠStud ent +ãĢĤ åı¦å¤ĸ +Ġsp an +ax y +ï¼Į åħ·æľī +Ġactiv ation +è¯Ĭ æĸŃ +Log ger +åIJ ¼ +Ġkn ock +å®ĩ å®Ļ +Ġbre aking +P ool +Ġen ables +ov ie +ãĢĭ ä¸Ń +_ U +( std +èĽ ® +Ġle ague +èĪª 空 +ch or +. config +Ġr u +ï¼Į åIJ¬ +ĠP ak +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠ +id en +Ġs aving +Ġpublic ation +Ġ" % +ä¹ ĸ +az e +æ¸ Ĭ +Ġpropos al +R et +y nt +hes is +Ġbet ting +ĠT ips +ĠPARTIC ULAR +f all +Ġf irms +æĻ® éģį +æĺ¯ æľĢ +Ġg ifts +ä¸ĵ 项 +æ°´ çļĦ +ä¿Ħ ç½Ĺæĸ¯ +ï¼Į ä½ľä¸º +et he +Im port +人 群 +A K +Ġg ear +åĪł éϤ +ĠFIT NESS +让 她 +Ġto ler +O mega +ĠA LL +ĠS outhern +Ġfunction ality +_S H +ĠG iven +ä»ĸ 人 +. load +ãģ Į +大 éĩıçļĦ +ç»´ ä¿® +o ir +M ember +é¼ İ +_w ith +ink ing +Ġcre w +R est +主 人 +Ġtalk ed +æIJħ æĭĮ +Ġsau ce +å¤į åIJĪ +Ġemploy ed +. Data +Ġ{ { +ä¸į åĬ¨ +in ar +Ġdis abled +Ġch ances +Ġ ãĢĮ +ĠMe an +åºĶ æĶ¶ +çļĦ ä¸Ń +el a +Ġcarry ing +常 常 +Ġdim ensions +ĠReg ister +Ġprinc ipal +åİ ĺ +itut ional +(p ath +em o +Ġv i +åŁº åĽł +Ġst uck +Ġleg it +çļĦ åĨħ +Ġsus pect +æ² « +å¼ķ ç͍ +Ġter rit +r angle +Ġdep ression +Ġleg s +æľŁ æľ« +ĠðŁ ĻĤ +Ġil legal +Ġst ead +éŁ ¦ +Ġimp ressive +ä¸Ģ åı¥ +ï¼ĮæľĢ ç»Ī +Ġlaw yer +mer cial +å½ĵ å¹´ +æ£Ģ éªĮ +Ġcorrel ation +éĥ¨ ä½į +St at +Ch rist +åģļ ä»Ģä¹Ī +éĶ ¡ +ibr aries +Ġnew ly +çģµ æ´» +ĠSe a +ĠS EO +* - +sh ips +)$ , +Ġaddress es +AA AA +{ aligned +D ouble +å² Ĥ +im ents +ĠM P +- K +éĿł è¿ij +Ġout standing +Ġt un +Ġcompl aint +ĠG ra +å ¬ +ãĢĤ éĢļè¿ĩ +Ġpref erences +w hat +åıĺ åĬ¨ +çļĦä¸Ģ åĪĩ +à ¹ +Net work +åı¤ 代 +ĠEv ents +Des criptor +æŃ ī +ç¿» è¯ij +trans form +åĩ ij +ä¿¡ ä»» +Ġadopt ed +ĠAdminist ration +çĤ Ń +D oc +ĠJew ish +m id +Ġar ts +Î ² +Ġover come +ĠAnd rew +lo om +ç͵ åĬĽ +n p +ĠU lt +au x +ap ore +Ġtum or +as hes +uck y +P ad +Ġpre v +Reg ister +ĠI mm +æľĿ çĿĢ +ĠV eg +Ġadvant ages +he et +Ġpow ers +å®ŀæĸ½ä¾ĭ ä¸Ń +ĠCo ast +Ġv ess +Ġprodu cing +ä¸ ij +ĠP y +_in put +模 æĭŁ +cript ions +ĠFranc isco +od els +Ġrapid ly +ç©¿ çĿĢ +éĵ ¸ +Ġ{ ' +ĠK ar +Ġsav ings +Ġ 第ä¸ī +Ġp ra +Ġmo ist +C ard +ĠFor ce +Ġ era +Ġsuper ior +here nt +ail ing +Ġgen etic +Ġscen ario +çļĦ èĥ½åĬĽ +没 ä»Ģä¹Ī +çļĦ è¦ģæ±Ĥ +å¾Ĺ å¾Ī +大 å¸Ī +Ġk ernel +åķĨ æłĩ +Ġexplan ation +Pe ople +Ġtra ce +Ġl icensed +Ġvict im +Ġà IJ +社 交 +ï¼Į åĥı +ĠD ub +ed ing +ĠS em +èĥĮ åIJİ +Ġdepend ent +In tern +b uffer +ĠD ouble +ĠÏ ĥ +! [ +op l +Ġhand ler +M eta +G rid +Ġvers us +W ORD +åIJĦ èĩª +. info +Ġtor ch +Ġb orrow +ä»Ģä¹Ī æĹ¶åĢĻ +å©ļ å§» +irc raft +Ġre n +åıĪ æĺ¯ +æĭ ¦ +Ġdep loy +åĮº çļĦ +Ġestim ates +_ LO +ra ined +Ġvac ation +Ġlegis l +Ġlegis lation +Ġbehavi our +åį ľ +çϾ åĪĨ +att ribute +模 æł· +In v +/ A +M ock +å·¨ 大 +M ult +_F L +è§Ĩ è§ī +æĶ¶ èİ· +ĠD own +, åħ¶ +ĠKing dom +æĥ ¹ +ç¥ ¸ +Ġhop ing +èIJ Į +Ġmar ks +Ġany more +äºĨ åĩºæĿ¥ +li ament +Ġple asure +Ġl apt +_param s +is ely +æģIJ æĢĸ +av irus +åŁºæľ¬ ä¸Ĭ +åħļ å§Ķ +ĠSch olar +ĠSen ate +è¡ ¬ +u v +Ġsmall est +C ap +is ement +ãĥ ³ +Ġt ro +Ġque ue +ĠOffic er +enn y +Ġc able +c hers +а н +ĠS on +åIJ » +åIJĪ æ³ķ +ain e +ä¸į åģľ +Ġs ought +' )) +é¢Ħ æľŁ +and ed +Gener al +Ġ âĢĻ +Ġdi agram +Ġe ast +äºĴ åĬ¨ +æĬĵ ä½ı +h y +Ġ ), +ĠWith out +Ġsatisf ied +il st +æ° ¢ +ä¸Ģ æĬĬ +éĢī 项 +èĮ « +S R +ä¼ł è¾ĵ +Ġ& = +)/ ( +Ġde ck +å½¢ æĢģ +ï¼Į è¿Ľ +Ġdis appe +.j pg +çŃ Ľ +æľŁ åĨħ +Ġessential ly +Met adata +Ġpick ing +( q +ym ph +Ġund efined +èħ » +Ġmechan isms +av ax +ak a +åĿ Ĭ +vis or +çĶŁ ç´ł +B E +å§Ķ æīĺ +Ġbeh alf +.prot otype +ï¼ģ ï¼ģ +çļĦ åħ³ç³» +.m ax +Ġmaintain ing +Ġh ide +转 让 +ä½ı æĪ¿ +æ¯ı 个人 +ix els +Ġvict ory +ĠSm art +è¾ĵ éĢģ +Ġmet a +Ġcover ing +Ph oto +Ġclos ing +ĠCert ificate +Ġc md +Ġund ert +Ġb ird +ãĢĤ 以 +end a +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠ +Ġcon ventional +Ġtal ks +IM IT +Ġ 对 +åĶ¿ åIJ¸ +ĠR ay +Ġrad ius +Ġd il +Ġman ip +ãĢĤ ( +ĠMus lim +S I +crib ed +ï¼Įåį³ ä½¿ +prot ected +b el +Ġal ive +ĠGeorg ia +.h as +Ġdeterm ination +éģ Ĥ +Ġ æŀĹ +çļĦ çľĭçĿĢ +éļ Ļ +Ġde eper +ĠS ometimes +Ġcontribut ions +ĠSO FTWARE +ist a +Ġinvestig ate +Ġsurpr ising +Ġassum ing +Ġp itch +é¹ ¿ +b g +ĠF ather +d c +not ation +Res ources +in line +Ġre ar +i ology +å£ ¤ +Rep ort +â ĨĴ +.assert Equal +ĠC at +æº ¢ +Ġenter prise +-qu ality +åħ Ķ +æĿ¿ åĿĹ +ä¼ĺ åħĪ +Ġev il +B ecause +Ġstat istical +M R +meric an +ET H +ç¡ « +Ġrepresent ing +v are +åĽŀ å¿Ĩ +ĠL iving +æĶ¾ åħ¥ +if iers +ĠMER CHANTABILITY +Ġobserv ations +Ġdrink ing +åħļ çļĦ +认 åı¯ +ç« ĸ +è§Ħ å¾ĭ +å« © +èĩª ä¿¡ +æĺ¯ 对 +ĠRequ est +å§ ¬ +ì Ŀ +h ome +éĵ Ń +ĠO lymp +i ón +En um +Ġcon j +og ram +Ġmus ical +Ġacc eler +Ġpur s +S ur +D ebug +ĠL ED +Ġ éĻĪ +ir ty +c irc +åħį çĸ« +N G +äºĴ 缸 +Ġh ang +Ġsuggest ions +Ġreturn ing +- class +ĠSh ort +éĢIJ æŃ¥ +å¤ı 天 +Ġdec ent +èµ° åIJij +ĠH un +ĠRead ing +Ġal ert +right arrow +é£İ æĻ¯ +ç¾İ æľ¯ +æĺ Ń +Ġha ck +ĠB rad +é Ħ +çļĦ 天 +Ġthous and +, 没æľī +Ġrec ipes +许 åı¯ +ĠM ajor +T ab +Ġcl othing +Ġemploy er +Ġbelie ves +ĠRes ource +éĢł åŀĭ +j ud +Ġrestrict ions +çļĦ å°±æĺ¯ +åij½ è¿IJ +Ġref erences +éĥ½ å¾Ī +æľ¬ æĸĩ +Ġgrad uate +åħ» èĢģ +=" ../../ +pe ction +å¹¶ éĿŀ +ĠJ ob +Ġp leased +viron ments +ĠResult s +Ġgener ic +ur ities +-s pecific +_ US +Ġrepresent ative +æ· Ģ +毫 ä¸į +OR S +éªĮ è¯ģ +Ġc urrency +çĶŁæ´» çļĦ +æĹ¥ èµ· +éļľ ç¢į +å¾® ç¬ij +Ġdam ages +Ġor al +å¸Ĥåľº çļĦ +Ġprogram me +su pport +主 管 +ĠS us +ĠO wn +ino is +ä¿Ŀ çķĻ +- per +ï¼Į åģļ +om orph +Ġhyp othesis +w an +Ġhead s +lo op +æīĢè¿° 第ä¸Ģ +Ġvis its +ĠCons ult +è¿Ļä¸Ģ çĤ¹ +åī Ĭ +ĠP acific +s a +Ġaccompl ish +Ġb irds +Ġless on +u h +ç¿ Ķ +çļĦ 两 +Ġput s +_ err +P ar +ç¥ŀ ç§ĺ +带 é¢Ĩ +åѦçĶŁ çļĦ +Ġstr ange +Ġres c +çĶŁ æĦı +Ġb ars +å´ © +示 èĮĥ +çĤ¹äºĨ çĤ¹å¤´ +t ilde +ill iant +ĠCh all +ĠM ir +ad ed +su per +ãĢĤ æł¹æį® +ãĢĭ çŃī +Ġreput ation +ail ure +çľĭ åĩº +Stud ents +ãĢĤ 为äºĨ +Ġpoint ed +ç» ij +Ġoverw hel +éĤ ĵ +çŁ¥éģĵ äºĨ +Ġfac ed +äºĨä¸Ģ çľ¼ +éĻ ķ +N D +Ġtrans lation +以 ä¸ĬçļĦ +é© ° +Ġp ars +便 å®ľ +åĵª æĢķ +æĺ Ĭ +å®¶ åħ· +é»ij æļĹ +Ġcheck s +Direct ory +ab eth +Ġ-- > +Ġad mit +() : +åħ ¹ +raw ing +åĭ ĥ +d l +å¥ĸ åĬ± +_ KEY +ĠM oney +st ar +Ġpass age +Ġmanag ers +Ġl oyal +J ECT +Ġre q +ï¼Į æĪIJ为 +Ġc ogn +C reat +orge ous +Ġ( @ +Ġd ynamics +å¹´è½» 人 +åı Ļ +ĠProf essor +ä¸ŃåĽ½ çļĦ +ik ing +ĠDiv ision +é¤IJ åİħ +r ating +Ġconsc ious +ĠS ummer +Ġdef ect +Ġf inger +clus ions +âij ¢ +ĠInt eg +ater al +ĠS ave +Å ¡ +ac on +Ġcal endar +ĠSecret ary +Ġre act +Ġhas n +( input +av id +S un +Ġret irement +Ġmur der +, t +HER E +Ġimpl ies +ï¼Į æ°´ +ar on +ĠJer sey +注 éĩį +ĠU SE +A W +ãĢĤ 大 +, ç͍ +y ers +Ġopin ions +_ cl +Ù Ĭ +ä¼ĺ çĤ¹ +ä¿ ± +ĠF all +Ġem ails +ĠC T +Ġ$ _ +( context +_M ODE +èͬ èıľ +ĠV ill +Ġwat ched +æ¶Ī èĢĹ +Ġ ## +ĠM om +ĠAg reement +å§ ļ +éĵ ĥ +Ġbu ff +Ġdo ctors +)* ( +Ġ åħ¬åı¸ +é«ĺ ä¸Ń +C ond +erv ative +ĠT ree +æĸ¯ çī¹ +Ġfor um +ĠT rack +å»¶ 伸 +å· ¾ +åIJĦ åľ° +ĠM icro +å¯ ¨ +Ġtrack s +ĠS her +Ġ ä½Ĩæĺ¯ +寿 åij½ +ĠMem bers +ourn ament +Ġm apping +åĩ ¹ +Ġcelebr ate +设 å®ļ +Ġsudden ly +åį± æľº +/ lib +Ġd ental +Ġindust ries +游 客 +Pl ugin +çļĦ æľĭåıĭ +审 æł¸ +Ġsur ve +æijĦ å½± +ç´¯ 计 +ä¼ij éĹ² +Ġt one +int on +Ġperiod s +ĠK im +Ġpro secut +åIJĮ å¿Ĺ +au g +° C +Gener ic +. remove +H R +Pro gram +çĻ « +ĠSh op +åıį 对 +eal and +Ġanal og +Ġdream s +ĠAs sembly +è´ ª +OP Y +Ġfore ach +éħ ¬ +ĠP sych +æķĻ ç»ĥ +æĺŁ æľŁ +.W indows +ro le +ĠG a +ä»ĸ åľ¨ +Ġtri als +Ï ī +Ġst orm +ä½ IJ +ĠColor ado +èĮĥåĽ´ åĨħ +å¤Ħ ç½® +Ident ifier +Field s +Ġpro hib +Ġ| = +ä¸ĩ 人 +and ler +Ġp ounds +ç¿ ° +Ġprov ed +Ġevery where +Ġsk ip +Ġmanufacture rs +equ ence +Ġgu itar +ä½ĵ åĨħ +az y +ä¼ł æĿ¥ +Ġforg ot +转 åĮĸ +Ġcor on +æķħ éļľ +her it +ĠDet ails +Ġlux ury +ĠP en +Ġport folio +ro vers +ĠC ancel +Ġc yt +iet ies +_ com +Ass ert +ĠC HECK +ĠC ivil +P erm +Ġle ct +zon a +ĠBe aut +re ation +Ġscient ists +Ġint ention +Ġfl avor +ist ration +ag ger +Ġhigh lights +Ġacqu ired +说 ä¸į +ï¼Įåıª èĥ½ +{ p +ĠCas ino +ĠChe m +æĦŁè§ī åΰ +ub s +D oes +d el +Ġegg s +æĢ» ç»ıçIJĨ +Ġc ov +F unc +ĠT y +Ġfac ulty +_w rite +Ġf is +级 çļĦ +Ġassist ant +Ġf ake +ĠP erson +å¿« çļĦ +æĥĬ è®¶ +Ġcour ts +åºķ éĥ¨ +Ġme als +ĠH a +æĹ¥ çļĦ +ĠS imple +Ġmem br +Ġl ic +å°ı åŃIJ +Ġbow l +_ lock +line ar +v y +ĠCustom er +éĤ£ è¾¹ +Ġsh ower +Sc ale +对 æ¯Ķ +st ers +ĠR ule +Ġâ ĸ +Ġfall s +g lobal +Ġlog ger +æ²³ åĮĹ +/ T +æľīæķĪ çļĦ +Ġfil ename +Ġab und +_V AL +âĶĢ âĶĢ +ew ise +åĪĿ å§ĭ +ĠÐ ¸ +, $ +ĠC G +as ma +éħ ¯ +Ġend ing +ĠAr my +Ġcl ust +ĠB ad +ï¼Į 身 +Ġex haust +çļĦ åĬĽéĩı +Ġd ownt +u ating +> :: +ãĢĤ éĤ£ä¹Ī +> \ +b m +åĭ ī +å°Ĩ åħ¶ +Ġresult ed +N av +ĠâĪ Ī +ĠE gypt +AR N +ĠGD PR +Cl oud +art icle +- check +cret ion +æĭħ ä¿Ŀ +. ui +are t +æİ§ èĤ¡ +Ġd ual +, éĤ£ä¹Ī +åĨ· åį´ +ä¸Ģ è·¯ +ag ent +ä¸į çͱ +Ġmem ories +Ġdis covery +Ġt ur +ãĢĤ èĭ¥ +åIJ µ +() ). +ĠR ose +主è¦ģ æĺ¯ +åĬ £ +Ġun iverse +èij ± +W ord +è¾ĥ 为 +åħ³ éĹŃ +æĺ¯ æĢİä¹Ī +Ġ outer +æĿij æ°ij +Ġjo ining +交 æį¢ +AM P +对 æĪij +äºĨ 两 +Ġstudy ing +Ad v +ĠI V +S w +å¹³ éĿĻ +Ġluck y +Ġro ots +åħ±åĴĮ åĽ½ +Ġred ist +Ġrob ust +back ground +ç° § +å¹´ 人 +@ property +ĠH ence +Ġacknow led +Ġh its +线 è·¯ +èĢĥ æł¸ +aw a +Ġinter f +ĠPol it +iz za +ort ion +H D +ĠS anta +æ¶ ¯ +Ġgreat ly +Ġpath s +Ġf ishing +Ġeval uated +ĠD rive +Ġst er +éĢ Ĭ +and y +_ AL +le ting +ĠG row +ï¼Į å¤ĸ +å°Ĩ åľ¨ +åģľ è½¦ +**************************************************************** ******** +Ġr ising +ent h +int age +Ġinteg ral +ĠSc iences +Ġincred ibly +yn om +, å¦Ĥ +æ»ij åĬ¨ +Ġm ic +F ILE +}} $ +ï¼Į æŃ¤æĹ¶ +Ġp ig +æīĵ åĩ» +posit ory +åIJĮ æŃ¥ +OM E +ä¼ļ çļĦ +ra q +åij¨ è¾¹ +H L +ĠB all +Ġbroad cast +Ġfavour ite +Ġtra v +d iction +ĠT aylor +çij Ł +æ ª +ä¿ ±ä¹IJ +èĹ ¤ +G ER +I ED +æ²ī é»ĺ +? . +åĥ µ +Ġmer ch +æĦ ī +d x +un icip +]\ ]. +ä¸ĭ åĪĹ +S chema +re ction +M O +Ġattract ive +w hen +çķ ı +b c +Ġfl our +ĠG arden +Det ails +æľĢ ä½İ +ï¼Į éϤ +Ġequ ally +L icense +Ġmist akes +Ġal gebra +Ġup grade +é s +ĠC ru +åİĭ 缩 +T ake +ä¼ļ ä¸Ĭ +Ġg olf +Ġclos est +. view +; >> +éŃĶ æ³ķ +Ġfollow ers +ä¸ĵ ç͍ +Ġres ort +Ġpenal ty +ĠCond itions +å½± è§Ĩ +Ġdeath s +Ġredist ribute +çĶ· 女 +æľº åĬ¨ +âij £ +O ld +ä¸Ģ 线 +ç½Ĺ 马 +t rack +import ant +r ank +EN CE +å°½ å¿« +{ $ +亿 ç¾İåħĥ +Ġexp ense +ig s +èº ģ +èĢĮ åĩº +IEL D +åĬŀ äºĭ +f x +ãĤ ¹ +Ġconcent rations +Ġcoord inate +Ġpregn ant +Pat tern +ĠG allery +ic iency +er ge +åħ¬ åħģ +çļĦ åıĺåĮĸ +ĠK ong +ĠP ast +b ind +ĠCONDIT IONS +d on +< td +II I +è§Ħ æł¼ +op ed +éĶĪ éĴ¢ +ĠAct iv +ä¸Ńåįİ人æ°ij åħ±åĴĮåĽ½ +åŃĺåľ¨ çļĦ +{ A +yt ical +ĠSk y +Ġbound aries +Ġper t +è¾Ľ èĭ¦ +è¶³ 以 +yn chron +Ġhost ed +ĠP O +riv en +åľ° éĵģ +Ġvalid ate +ĠCh oose +Ġde leted +Ġspeak ers +æ¡£ æ¡Ī +Ġstream ing +è ¥ +uck s +ĠS a +Ġconc ert +ĠCour se +åĬĽ åĴĮ +[ - +Ġorient ation +Ġart ificial +S elf +ĠK evin +lement ation +Ġt ang +Ġc ub +ä¸ ¨ +Ġent rance +åĽ½ æľī +ĠColumb ia +T erm +Ġgra b +Ġp ills +éĩĮ éĿ¢çļĦ +Ġb aking +人 大 +çĿ¡ çľł +Ġt u +æĬ¥ èѦ +ĠS L +åĮĹ京 å¸Ĥ +D ev +s ince +Ġsal ary +éĴ Ļ +Ġrepl ied +Ġc ats +Ġuncertain ty +å· · +Y ear +éĴ © +C ert +订 åįķ +Ġb att +L ife +. init +_n umber +å®Ĺ æķĻ +Sh ould +CR IP +å¢ ħ +_F ILE +Ġoper ational +_ST ATUS +çħ Į +it ate +M iss +Ġmembr ane +å® ° +. equals +åİ» æī¾ +epend ency +W in +% ï¼Ľ +Ġparticip ating +D im +ĠL O +广 æĴŃ +ob b +æľ¬ è´¨ +Ġsupp liers +Ġhead ed +rapeut ic +åľ° çľĭçĿĢ +Ġlog ical +, k +çͱ æŃ¤ +ĠDemocr atic +Ġbrows ing +Ġpart ition +Ġprevent ion +Ġemploy ers +r v +Ġh ol +Ġsh adow +Ġsupp ress +R F +ï¼Į å®ī +ĠEvery thing +便 åĪ© +Ġ\ , +丫 头 +Ġenthus i +æĪIJåĬŁ çļĦ +ens ure +D uration +e lect +.D rawing +Ġconvers ations +åĽ½å®¶ çļĦ +Ġpres cription +t emp +M apping +ĠP ick +Ġwis dom +ç»ĵ 论 +ĠGold en +ĠG ets +erv let +Ġ" # +f in +umm ies +Wh ite +Pro v +opt ional +Ġt ie +S ample +æ··åĩĿ åľŁ +Ġter rible +Å ¾ +.m d +Ġsure ly +Ġint ellectual +Ġ ---- +ĠD ise +çļĦ éĿ¢ +é¢Ħ 设 +st op +ĠM oon +Ġnewsp aper +S ocial +. Un +Ġgr an +ç²® é£Ł +Ġdiff er +ous es +_T O +äºĨ è¿ĩæĿ¥ +en z +鸡 èĽĭ +æį٠害 +Ġe cosystem +转 è½½ +C enter +g ly +Ġagre ements +æĽ´ æľī +t w +Ġ æĸ° +ing ton +çĽĪ åĪ© +æĥ © +èµĶ åģ¿ +Ġefficient ly +p erson +Ġtri ps +_ entry +.spring framework +Ġel der +Ġa ver +ï¼Į ä¸ĩ +cal ar +Ġstreng then +U IL +ĠJud ge +çŁ³ 头 +é¥ ¶ +æĬ Ħ +; i +ĠW inter +使 åij½ +Ġbasket ball +Ġw x +Ġwe igh +çľ ¨ +ĠD VD +ãĢĤ å°± +转 åŀĭ +back s +ä¸Ĭ çıŃ +Ġd ot +åī© ä¸ĭ +åı« åģļ +S B +ri um +ä¸ī è§Ĵ +Ġfound er +S imple +ĠS ug +åľ° æĿ¿ +Op ens +res ource +Ġnarr ative +, ä¹Łæĺ¯ +Ġprodu cer +ï¼ļ åľ¨ +Ġapp li +éĶĢ éĩı +ĠVal id +ul pt +- Z +Ġvulner able +ĠBas ic +åıĺ å½¢ +çıŃ çīĻ +ĠB ru +Ġcomp ounds +Ġconsult ation +H er +re place +Ġact ively +ĠDe ep +Ġch unk +Ġdifferent ial +U C += self +m art +Ġwh ilst +Ġaccept able +ol n +Re lease +Ġcapt ured +cy cl +Ġbr ush +Ġ µ +Ġstock s +et ition +( arg +_n o +Ġearn ings +s ite +Ġst ats +ä¹ĭ è·¯ +Ġcomp ound +Ġhad n +à ª +ĠEl izabeth +- content +èį Ĩ +_ request +å® ª +nt il +Ġs lic +è¹ Ī +text bf +èº ¯ +Ġcam eras +Ġpe pper +å´ Ķ +èĭ¥ å¹² +Ġqu eries +çļĦ人 çĶŁ +- form +æŁIJ æŁIJ +ĠO cean +E Y +èĩªåĬ¨ åĮĸ +G T +ĠTh read +Ġre leases +ĠSt orage +ĠMot or +ĠLeg al +oun ces +ĠS ong +.l ist +ĠArch itect +两 ä¾§ +é«ĺ äºİ +_ options +t ra +åķĨ å®¶ +Id x +认 çŁ¥ +ous ing +Ġneg lig +an ches +æĶ¯ æŀ¶ +ffic ients +rop ri +审 è®® +ãĢĤ ä½ľä¸º +equ ality +ç µ +å¤ļ åħĥ +ĠAp pe +? ) +Us ers +Ġcreat ivity +Ġc ust +Ġnull ptr +D avid +Ġdef ines +éĢ Ľ +ï¼Į çī¹åĪ«æĺ¯ +ter min +v i +ï¼Įè¿Ļ ä¸Ģ +ĠSc ient +Pro p +E F +ĠO ak +w t +Ġcomp osed +.r un +Point s +ak i +çĥ · +ï¼Į æīĢ +è¡ Ķ +Ġful fill +åĩł åįģ +æIJ ı +à ² +âĢĿ ) +Pack et +ç¦ı åĪ© +ile t +Ġin clusion +å·® çĤ¹ +. height +Ġsuggest ing +Ġd f +ĠC ut +Ġfacilit ate +æĬij åζ +ç¼ĸ åζ +èİ·å¾Ĺ äºĨ +åĩº åĶ® +AR CH +Ġsumm ar +Des ign +Ġz ip +Ġdispl ays +, åĽłæŃ¤ +Ġk in +out ing +En able +Ġ. = +ox y +æĦ¤ æĢĴ +Ġtim ing +å¤ĸ åĽ½ +Ġnerv ous +ãĢĤ èĩª +Ġmind s +åĵį èµ· +轨 éģĵ +ag g +å¾Ĺ çŁ¥ +s end +æĭ¿ åĩº +ï¼Į çĦ¶èĢĮ +Ġcogn itive +èIJ¥ éĢł +Ġcas ual +Ġcap s +Ġy oga +Ġaccom p +S ingle +åıijçĶŁ çļĦ +ï¼ĮéĤ£ äºĽ +ĠC P +IN S +Ġapprec iated +åŃĺåĤ¨ åύ +Ġposs ession +é¡¶ éĥ¨ +Ñ ħ +Ġl on +å£ ¶ +ĠBAS IS +Ġburn ing +ĠA h +èĥ º +b ec +书 æ³ķ +ç¾ ¡ +Ġref used +Ġ å°± +çĽ ¼ +Ġdriv es +ĠG as +ord inary +P refix +ĠCON TR +ic ator +æīĭ ä¸ŃçļĦ +\ pi +**** ** +ĠJ ordan +Ġvot ers +Ġad mission +ç§ © +Ġtransl ate +h ops +Ġsampl ing +(' / +En vironment +Ġg ay +ĠBet ter +Ġp ixel +look ing +X ml +ç Ģ +ĠM iami +Ġeng ines +A udio +çĶ· æĢ§ +Ġcult iv +身 ä¸ĬçļĦ +OL OR +çļĦ å®īåħ¨ +广 西 +Id s +âĢĿ çŃī +容 éĩı +о ÑĢ +ĠP ain +Ġve c +Ġimplement ing +çļĦ çĬ¶æĢģ +Ġblog s +r ays +ĠApp ly +{ b +th s +ï¼Į 两人 +ï¼ ij +cons in +ou st +ç¨į å¾® +Ġassum ption +ond s +åĴĮ å°ı +Ġcharacter istic +s ave +l ings +Ġhe m +p ot +å¤ĸ è§Ĥ +Ġsh apes +Ġrob ot +( pro +Ġsleep ing +Ġm igration +( uint +å½± çīĩ +æŃ£ 好 +ç»Ļ èĩªå·± +orne ys +Ġpl asma +Ġreg ime +Ġdifferent ly +_id s +å½ ¦ +ï¼ĮéĤ£ å°± +_ header +Ġthrow n +ï¼Įåıį èĢĮ +Ġlabor atory +ĠC V +Ġge ometry +èİ ¹ +i ating +ĠH istor +Ġimportant ly +qu ot +çļĦ éľĢæ±Ĥ +ä¼ł å¥ĩ +ä»ĸ 说 +è°ĥ çłĶ +Ġrece iver +ĠTh ink +ĠN othing +ï¼Į èµ° +he ll +m aster +ĠA udio +Ġun likely +Ġbed s +æĹ© æľŁ +Ġpurch ases +ç¨İ åĬ¡ +ĠW HERE +Ġdefend ants +å®ŀ çļĦ +æĬ¬ èµ· +Ġcollect ive +C V +Ġcult ures +Ġt ons +Ġsche ma +/ > +Ġdel ta +ãĢ Ķ +Ġrough ly +Ġn g +Ġview ing +ï¼Į éļ¾éģĵ +Ġexplo res +å¯Ĩ åĪĩ +sh ared +Ġcol lections +Ġcert ification +Ġr anging +ä¸Ģ 段æĹ¶éĹ´ +d evice +Ġh anging +Ġstru ck +ant e +Ġp uzz +Ġple asant +ĠÎ º +Ġassess ed +ä¸ī 大 +åıĺ éĩı +ĠOver view +ĠEnvironment al +F ire +ãĢ ķ +åĩº è¡Į +ĠF low +ab a +ĠUS D +riter ia +Ġb omb +éķ Ģ +ct rl +åį Ĵ +D i +Ġrespond ed +没æľī 人 +ï¼Į 说éģĵ +x c +è¿Ļä¸Ģ 次 +Ġexhib ition +èµ° åİ» +ï¼Į 好åĥı +åijĬè¯ī ä½ł +对 åħ¶ +ï¼Į åıij +Ġcar rier +pl ane +. List +æĻ¯ è§Ĥ +, c +PH ONE +ĠJ am +ä¸ĭ è·Į +离 å©ļ +g ood +Ġhor izontal +åĮ ł +Ġdesk top +ĠR T +çĶŁ æĹ¥ +ä¸Ģ 大 +Ġco aching +Ġsh irt +èIJ½ åľ° +å® Ľ +ĠD ays +oc hem +Ġs wit +.s end +Ġgener ating +N ormal +ĠSt ories +Ġcontract or +_ equal +W rapper +.t ime +em ia +, è¿Ļæł· +om er +Î ¸ +Ġgold en +o ft +ĠG ard +unn el +Ġs b +, ä¼ļ +++ ++ +Ġrestrict ed +è§ģ éĿ¢ +Or igin +å®¶ å±ħ +è¡Įä¸ļ çļĦ +Ġflow er +æİ¥ åΰ +ĠCom b +Ġm il +Ġsm ell +Ġmac ro +î Ĺ +æķĪ çĽĬ +ä¸Ĭ æľī +Ġthere by +Ġtri es +Ġmet ers +Ġl ung +Ġbank ing +è¾ IJ +Ġvolunte ers +Ġinf lation +ç͵è§Ĩ åī§ +âĺ ħ +Ġdestroy ed +ĠF inal +å·® è·Ŀ +缸 ä¼¼ +Ġprem ise +/b in +ne ed +D b +Ġamong st +m ates +ĠDe ath +ĠPh ilipp +_V ERSION +ç¬Ķ è®° +aa aa +Ġc ursor +us al +Ġemphas is +ĠConst ruction +åĩł 次 +èī ĺ +e ff +Ġsur f +ĠL ady +ĠR ow +t le +Ġbe am +ä¸Ģ个 å°ı +.b egin +.st atus +å°± å·²ç»ı +ï¼Į æµ· +Ġt ournament +常 è§Ħ +æĿĢ äºĨ +ä¸į å®ī +èĤ¿ çĺ¤ +ä¹Łä¸į çŁ¥éģĵ +Ġround ed +Ġp ipeline +s pec +强 çĥĪ +ĠL IMIT +M aterial +Ġ( [@ +客 è§Ĥ +Ġrequ iring +ä¸ĭ æĸ¹ +ĠCreat ive +ĠG reg +Ġhe ter +Ġsepar ation +é«ĺ çŃī +-b it +s ervice +_r ange +åIJİ æľŁ +Ġpres erve +Ġsimult aneously +ĠM ort +ĠH ay +ä¸Ģ 项 +urch ase +_P ATH +Ġpr ide +Ġpil ot +éº Ł +ç͍ éĢĶ +ï¼Į åħ± +,å¹¶ ä¸Ķ +Ġorgan isation +åĦ¿ çļĦ +ãĢĬ åħ³äºİ +U CC +ï¼Į å¾Ĺåΰ +Pl ace +审 æī¹ +Ġt we +Ġdiv orce +ä¸Ģä¸ĭ åŃIJ +m ay +ĠHolly wood +Ġbut tons +å¯Ĩ 度 +n ed +Ġfing ers +Ġboard s +éĺ» æŃ¢ +Ġf er +âĢĶ and +D L +Ġt err +.st ate +} )$ +Ġpro xy +ock ey +è¡Į äºĨ +Ġinvolve ment +æī¾ åΰäºĨ +Ġbas eline +Ġc ul +ç« Ń +æĸ Į +Ġoper ated +å±Ģ éĥ¨ +æįŁ çĽĬ +ĠC SS +æĮ ½ +ĠC reek +è§īå¾Ĺ èĩªå·± +å¦ĩ 女 +irect ory +ï¼ĮæĪij çļĦ +天 空 +Ġimp ression +Ġ èĭı +é«ĺ æīĭ +ĠC ategory +æĮij éĢī +æĽ´ é«ĺ +Ġg oogle +Ġwood en +S W +Ġatt ending +Ġroll ing +ï¼Įè¿Ļ 次 +Ġd w +lo pe +, è¿ĺæĺ¯ +, ä¸ŃåĽ½ +Ġcons ervation +, p +ç´§ æĢ¥ +Ġsk illed +ï¼Į å®Įåħ¨ +æijĦ åĥı +ĠH ttp +new s +建 æĪIJ +ãģ Ĩ +åѦ å®¶ +S cope +Ġref lection +Ġapp et +ĠEn c +åīį åIJİ +V ec +b ad +Ġacc used +é¢ĺ 缮 +大 éģĵ +å¤ · +åĽ½åĬ¡ éĻ¢ +: - +èģļ éĽĨ +Ġr um +Ġhab its +满 äºĨ +z h +Ġauthor ized +Ġb undle +ĠStep hen +ãĢĤ ä¸ī +Ġd ont +ä¹Ł ä¸įèĥ½ +Ġcere mony +ä¸įæĸŃ çļĦ +讲 è¯Ŀ +au c +valid ate +Ġw ise +åĩĢ åĪ©æ¶¦ +çĵ £ +Ġreve als +Ġ © +Not ification +/ re +æĺ¥ èĬĤ +em an +åİ ¢ +æ¢ ³ +为 æŃ¢ +D omain +ĠAd vent +åĨĽ çļĦ +ãĥ Ī +温 馨 +Ġth ro +Con vert +{ {\ +ĠSt op +åĨĴ éĻ© +te ch +Inter val +] ), +Ġve ctors +ĠL OG +ist ered +m ask +m enu +ĠEvery one +Ġprof its +Not ify +_ default +{ P +å¹´ åºķ +åĴ Ĵ +åĸ ĥ +Ġs ink +ĠL oss +Ġh ip +åģĩ å¦Ĥ +оР» +att ributes +Ġhost s +ah oo +ãĢĤ äºĮ +N AME +- he +åħħ满 äºĨ +ch ildren +C r +d ers +ç͵ åύ +Ġinf ections +M ulti +æİĴ éϤ +Ġ ä¸İ +ï¼Įæ¯ı 个 +ĠPh arm +u rop +m ove +elf are +Ġl oose +Ġphys ically +We ight +.d b +_b uf +ĠAdv anced +åĩ ° +Ġd ictionary +Ġres ident +pr ice +( out +çļĦ éĢīæĭ© +Ø ¯ +Ġvari ations +æķĪ åºĶ +Ġl ibraries +Ġcan vas +( item +å¾Ī ä¹ħ +Ġpsych ological +_L EN +ãĢĤ æĺ¯ +é¢ ł +éļı æĦı +N ET +ï¼Į åĨ· +éªij 士 +( request +Ġc v +Th rough +ĠM ind +ä¹ĭ åĬĽ +Ġhand led +çļĦ æĸ¹åIJij +Ġcur ious +ĠL inks +. Type +D iv +ĠH ong +Ġun like +带 æĿ¥äºĨ +Ġsold iers +Ġhard ly +Ġst ops +re nce +.d ebug +Ġrad ical +Ġs el +\ item +éĿĴ å²Ľ +Ġac ute +w ait +çļĦ 第äºĮ +\ < +_IN FO +ffect ive +ĠTh ird +é£İ æľº +大 èµĽ +_l abel +åĿļ å®ļ +ĠJ enn +æĥĬ åĸľ +ach uset +Int roduction +主 è§Ĵ +è®° ä½ı +Ġres olved +F amily +(f inal +èŀº 纹 +ĠM L +Ġe lections +è¿Ļ个 æĹ¶åĢĻ +ĠB at +ĠH appy +Ġvirt ually +NS String +L imit +Ġhar vest +Ġexpress ions +æ¼Ķ åĩº +ĠM ail +Ġcap ability +æľ¬ æľŁ +èĤ Ĩ +u ates +ï¼Į å¿ĥä¸Ń +end o +Ġv oting +æŀ ¢ +åı¯èĥ½ æĢ§ +P ut +achuset ts +åĩº ç§Ł +a ired +agn etic +Ġ/ >< +ĠWork ing +èĩ´ åĬĽäºİ +ĠCont inue +Ġfil ing +æ´» æĢ§ +èĵĿ èī² +ĠAust in +_c ol +çķ ľ +ID E +Ġam pl +è̳ æľµ +Ġentreprene ur +Ġdram a +yd ney +æĺİçϽ äºĨ +Ġe igen +åĪĩ åī² +èħIJ èļĢ +Ġbro ker +ap ters +Ġnut rition +. Test +ct l +h d +m ember +Ġtempl ates +æĢ ¡ +h ave +w indow +Ġf est +æ²Ļ åıij +off ee +çļĦ æľī +ï¼Įå®ĥ 们 +以 å¤ĸ +ç§į åŃIJ +M aster +.p df +Ġcool ing +.S ize +æİĴ æĶ¾ +ys ical +hent ication +Ġbal anced +mar ks +Ġconf lic +å¥ ¢ +ĠD R +B en +è°¨ æħİ +åº ¸ +åIJĮ æł·çļĦ +Ġh ub +ĠM E +大 约 +th rows +åĿ ª +身份 è¯ģ +Ġn orthern +ï¼Įä¸į ä¼ļ +被 åijĬ +åıĤ è§Ĥ +æĦıè¯Ĩ åΰ +Ġstom ach +Ġexpl os +è§Ħå®ļ çļĦ +ç£ · +ĠMin nesota +ĠM T +Sc ore +ï¼ĮæĪij æĥ³ +éģŃ éģĩ +èĶ ½ +Ġm ig +Ġ äºĶ +Whe ther +Ġpos it +t ail +ell ar +E p +Ġg ray +_f e +ä» Ĩ +åĽĽ åij¨ +å·¥ç¨ĭ å¸Ī +Ġcrypt o +ache lor +è¿Ľ å±ķ +æį٠伤 +è´« åĽ° +F older +éĴ ĵ +åĽŀ æĬ¥ +Ġtok ens +ast y +Ġw ider +ĠC ould +in v +s cription +Ġengine er +G F +_T IM +çĿĢ ä»ĸ +t ip +Ġatt ach +äºĨ ä¸įå°ij +æĬĬ æĪij +å®ŀ ä¾ĭ +ĠM ade +Ġoffic ially +ĠO regon +Reg ion +F ix +ä¿® çĤ¼ +Ġsw ing +Ġra cing +åĽŀ æĿ¥äºĨ +çļĩ åIJİ +ĠM C +Ġcell ular +åħ¬ 积 +æıIJ åĩºäºĨ +! ( +Ġtest ified +Ġmole cules +èĥ½ ä¸įèĥ½ +åī ¥ +_C O +ï¼Į ç¥ŀ +èĢģ åħ¬ +è´§ çī© +f rak +Ġattempt ed +èĭ¥ æĺ¯ +ä¸Ģ个 æľĪ +Ġperform ances +åĪĨ çļĦ +èı Ĭ +ä¸į å·² +åľ¨ å®¶ +ï¼Į ç»ıè¿ĩ +ĠDemocr ats +ĠD ifferent +è¿ľ å¤Ħ +产 éĩı +çļĦ çݯå¢ĥ +çħ İ +ethe less +E mp +unicip al +Ġox id +_l ink +Ġpar ad +Ġuser name +des c +al so +s ession +re tt +is ons +k l +ETH OD + £ +ĠK enn +Ġt ens +ast ed +Ġd ial +_DE V +' ; +Ġ ---------------------------------------------------------------- +Ġfrag ment +il ib +ĠLew is +Ġpri ze +ç¼ĸ åı· +ord ered +Ġad option +缺 çĤ¹ +çļĦ ä¸ĸçķĮ +å¿ĥ èĦı +åĴĮ 社ä¼ļ +èĵ ī +( user +æ¶² ä½ĵ +让 èĩªå·± +. content +Ġdis aster +æ©¡ èĥ¶ +çļĦ 缮æłĩ +UT E +h ire +_ create +ĠR uby +Ġnumer ical +av y +Ġsent ences +åĩı èĤ¥ +åŁİ éķĩ +éĽĨ åIJĪ +ï¼Į ç»§ç»Ń +Ġar c +ĠS i +ĠR NA +çīĩ åĪ» +w er +ge red +è¦ģ ç´ł +ey ond +è¶ħ å¸Ĥ +ou ri +Ġep isodes +æ¯ı æĹ¥ +R ender +aw ays +ĠSe attle +a uth +Ġas semb +eq ref +ç¾İ 容 +ï¼Įä¸į çĦ¶ +ĠT ools +ĠS ure +.s c +op ts +Ġg el +ĠD er +app ly +D ictionary +ĠA mb +Ġt ension +field s +æľŁ è´§ +ĠTur key +X ML +Ġsu ite +ond a +ĠV irtual +.g ov +Qu ick +C ost +åĺ ² +ãĢĤè¿Ļ æĺ¯ +æĿĥ åĬĽ +ry ing +Ġaccom pan +Ġreg ards +æµĵ 度 +- en +. ( +Ġphys ician +Ġn m +ç¬ijäºĨ ç¬ij +ĠN ation +é«ĺ 端 +Co ord +客 åİħ +客 人 +è¾ħ 导 +ĠB ridge +Ġpush ing +ï¼Įå°± åĥı +ĠSu ite +ass ign +k ind +con nection +, åħ¶ä¸Ń +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ +Ġs ectors +è¿IJ ä½ľ +çĹħ ä¾ĭ +í ķ +operator name +che m +éĻĽ ä¸ĭ +åĺ » +-h our +Ġcry stal +Ġlad ies +Ġf uck +Ġhospit als +Ġpromin ent +on omy +ï¼Į åĴ±ä»¬ +Ġven ue +Ġcharacter ized +éĢĶ å¾Ħ +Art icle +åĿ ł +un ks +Vol ume +Ġthe ories +å¸ ĸ +ï¼Į æķ´ +, éĥ½ +Ġtype of +çĭ¬çī¹ çļĦ +S ite +åıij èĤ² +N eed +Res earch +Ġpro x +_S Y +Ġlegit imate +ï¼Į ä»» +Ġp overty +Un known +LO C +ä¸Ŀ 毫 +{ E +éĨ ĭ +è´µ å·ŀ +Ġbase ball +Ġsh orter +ĠInt ellig +èĤļ åŃIJ +è§Ĩ 线 +è¦ģ 注æĦı +Ġ åħĥ +Ġdialog ue +C ancel +ĠOption al +Ù ĩ +Ġgr at +æ² ¸ +ess ment +o pp +-b ottom +ĠÎ ´ +仪 åύ +Ġleg acy +建 éĢł +Ġproceed ings +Ġmort ality +Ġass ault +çĥ « +ä¸į åİ» +Ġp od +ĠC ome +ĠBro ther +osp el +ĠF a +å°± 好 +çĨ ĺ +Ġfin ancing +anc ell +Ġb anner +or iginal +.d at +h ard +ĠS umm +çİ « +ãĢģ åľ¨ +pr ime +ï¼Į æ°Ķ +ĠCl inton +ĠP interest +Ġp ending +西 åĮĹ +Ġmoder ate +Ġcompet e +ä¸ļ 主 +çģ ¿ +îĹ ¥ +r ins +Ġthreat s +éķľ å¤´ +itud es +Ġres erve +æħ ¨ +å®ĮæĪIJ äºĨ +Ġsol o +r and +Ġdevelop ments +, s +om al +æľ¬ åħ¬åı¸ +Ġden omin +g it +åīį è¿Ľ +ĠCon c +Ġcomput ed +Ġgener ations +çļĦ 表æĥħ +un ate +ol icy +Ġhand les +ï¼Įä¹Ł 许 +su it +äºĨä¸Ģ åı¥ +éĻ· åħ¥ +ĠS peed +-w idth +è¾ Ĭ +Ġconsider able +om p +ĠB aby +éģµ å®Ī +次 æķ° +w orld +Ġwas hing +Ġf ur +ä»¶ äºĭæĥħ +Ġpr on +ĠN AS +ä¸Ģ ä¼ļåĦ¿ +çļĦ 缸åħ³ +Const ants +Ġpassion ate +æ´¾ åĩº +Ġsc ar +ou ds +Ġ' % +i ological +ä¸Ģèά çļĦ +å°¸ ä½ĵ +D iff +åĩĢ åĮĸ +Ġarg ued +Y P +âĹ ı +ĠEconom ic +ĠChall enge +ut o +Ġpro l +Comp any +ĠW ire +çľĭ æ³ķ +cont inue +ĠB L +ĠFoot ball +èĤ¡ä¸ľ 大ä¼ļ +æ°´ ä¸Ń +ĠIn cre +ï¼Į ç»Īäºİ +éĻĮ çĶŁ +åIJİ ç»Ń +æĹł çĸij +Ġn u +Ġdes per +Ġpredict ions +å¼ķ æĵİ +æŀģ åħ¶ +_ level +绣 æ²» +_N OT +è¾¾ æĪIJ +Ġbel t +, èϽçĦ¶ +Ġb reat +ĠT am +Ġl as +Ġpublish ing +ĠJ oin +l ah +Ġexclus ively +Ġr anges +å½ķ åıĸ +ĠD iet +~~~~ ~~~~ +on ed +Ġunivers ities +Ġ ï¼ļ +Ġinf inite +.Col lections +Ġrom antic +ä¸Ģ çϾ +Ġcharg ing +Ġreject ed +设置 åľ¨ +ĠPost ed +ĠBro ok +l f +ï¼ ı +ĠM ach +æĩĤ å¾Ĺ +Ġb ounds +Ġf ired +_d ec +äºī åıĸ +om as +ç͵ éĺ» +- name +Ġact ors +ï¼Į ä¿Ŀè¯ģ +est one +ĠL ev +ç͵ 梯 +Per formance +^ n +ï¼Įå¹¶ åľ¨ +æĶ¾ 大 +w rap +ĠFollow ing +, è¿Ļæĺ¯ +) ? +åİŁ æĸĩ +.c all +c ategorized +级 åĪ« +æIJº 带 +ãĢ İ +ty pename +W M +AG ES +ï¼Į以 åIJİ +- I +é¥ ² +ĠMethod s +åĺ´ éĩĮ +Ġg allery +iss a +ĠS aint +çIJĨ äºĭ +çĶ· çĶŁ +åįģ åĩł +end ors +å¸Ī èĮĥ +-c alled +è¡ · +åıijçݰ äºĨ +Ġcontact s +ol o +ig ious +Ġcrypt oc +åīį æĿ¥ +em ies +æī« æıı +S ummary +ogen ic +Ġ ï¼İ +æ¡ © +im estamp +è¯ķ åĽ¾ +}, \ +Ġconf used +Ġl un +ĠThe atre +Ġutil ized +Ġc ups +Ġs orts +çļĦ ç²¾ç¥ŀ +ä¸į æ¸ħ +è¿Ŀ åıį +; & +ĠY ears +Ġlock ed +Ġg est +Ġtheoret ical +Ġremark able +am ination +æĺ¯ä¸Ģ 款 +éĩijèŀį èµĦ产 +Ġc her +Sk ip +èĪ ± +ĠO s +ir able +t l +================================ ================================ +Ġtim ely +Ġt ied +grad uate +æİ ı +çļĦ åİĨåı² +Ġp ython +çĥŃ éĹ¹ +Ġr uling +Ġrece ipt +und ry +Ġsy ndrome +ãģ ĵ +å®Į æ¯ķ +as ync +Ġse am +Ġal ignment +ï¼ĮéĤ£ å°±æĺ¯ +Ġ第 åĽĽ +ĠDo ctor +奥 è¿IJ +Ġrece ives +, âĢĻ +T imer +å± ł +Ġcan nab +Ġarbit rary +åĽ½ çİĭ +Ġnot ion +ache l +Ġc ra +" We +西 çıŃçīĻ +ĠGr ant +Ġconfig ured +说 å¾Ĺ +æ² ¾ +Ġphotograph s +k wargs +ĠC reated +ĠF IG +h is +ç²¾ èĩ´ +Ġse gments +( V +Ġscen arios +{ F +ĠD ave +re r +AC C +è° ħ +çļĦ çłĶç©¶ +åĮ» å¸Ī +( len +ĠV ice +Ġen orm +è¦ģ åİ» +ĠD AM +- comp +åıij å°Ħ +éĥ½ å¸Ĥ +ERR OR +ĠE arly +m ation +åİļ 度 +Ġmed ian +Ġmand atory +Ġdesign ers +è¯ļ ä¿¡ +b ie +Î Ń +Ġrel ate +igr ants +ĠLead ership +éĺ² æ²» +. check +Ġ ä¸ĩåħĥ +k ers +f p +Ġco operation +lic ense +ĠL at +Ġaltern atives +失 åİ»äºĨ +ĠðŁ ĺ +èĨ ¨ +çļĦåŁºç¡Ģ ä¸Ĭ +ĠAuthor ity +Ġpat ent +b ed +ne ver +Ġdownt own +å±ķ è§Ī +åı· çłģ +åı£ 罩 +åįķ 纯 +_ client +out ube +çļĦ æľįåĬ¡ +Ġdifficult ies +, d +ĠC ash +äºĨ è¿ĩåİ» +Ġvac uum +Ġsing ing +Ġsub set +åĽŃ åĮº +. trans +Ġmass age +-b ox +ĠChrist ians +çļĦ åŃ©åŃIJ +P rivate +ä¸Ģ çĶŁ +ad get +ĠI ron +Ġg athered +Ġ çİ°åľ¨ +é«ĺ è´¨éĩı +çļĦ åĪĨ +Ġmount ains +Ġannounce ment +el ve +æĸĩ èīº +et ooth +- ray +çļĦ ä¼ģä¸ļ +Ġind ices +Ñ ĸ +h l +ĠVis ual +èĥ½ åľ¨ +g rid +çIJĨ è´¢ +Ġman ually +ä½ £ +Ġcomp aring +Ġep id +erc ise +Ġmark er +ĠIm ages +er os +t p +å¿ħè¦ģ çļĦ +Ġautom ated +b ul +G reen +id o +Ġco h +æĿĥ å¨ģ +åī¯ ä¸»ä»» +Ġdro ps +ãĤ ī +Custom er +ï¼Į æ¸ħ +/ R +." " +ick ing +Ġexc it +Ġhold er +W ait +Add itional +T YPE +F B +æłij èĦĤ +Ġmotiv ation +èµĦ è´¨ +éĢĢ ä¼ij +éĢı è¿ĩ +天 天 +ä¸į åıĺ +çª ĥ +ãĢĤ éļıçĿĢ +æĴ ° +ĠE ar +Ġdec ay +å·²ç»ı æĺ¯ +è®® æ¡Ī +Ġdist ribute +èµ· çļĦ +Ñ Ĩ +太 å¹³ +åĽ¢ ç»ĵ +w ear +us cript +Ġse vent +ä¸Ģ çķª +U ri +( E +Ġexhib it +Ġk iss +åŁİ çļĦ +Ġadjust ed +åĨį 说 +ï¼Į 车 +åģ¶ å°Ķ +ĠTreat ment +Exp and +VAL ID +éħ µ +Ġde ar +æ¶² åİĭ +Ġins pection +ä¸Ģ æĹ¶ +Ġe q +ĠR ome +Ġlimit ation +ish op +c ence +åĨ³ å¿ĥ +Ġident ifier +pect ives +Ġindepend ently +顾 éĹ® +ĠS PE +ï¼Į èµµ +Char acter +{ n +: [ +èħ ķ +ç±»åŀĭ çļĦ +Ġmeas uring +.re place +Ġstead y +Ġu m +Ġwor ship +) +ow ered +ãĢĤ æľĢåIJİ +Ġland ing +åħħ è¶³ +çļĦ åı¯ +-g roup +Ġed ited +Z ero +å¨ ¶ +æŀĦ éĢł +ĠProm ise +igen ous +ĠP ed +è¾IJ å°Ħ +Ġcoe fficients +èĢĮ åİ» +.sh ow +ens itive +ĠSp ot +rec ated +Ġsing er +Fe atures +Ġst abil +Av ailable +f ound +rop ical +Ġce iling +The me +SE D +è¿Ļ 两个 +p assword +{ H +Ġres il +Ġc yl +çĿĢ æĢ¥ +æ³ ¼ +f b +V ery +çĹ Ĵ +äºĮ 次 +Ġrat ings +Ġadv ised +L ead +èĪ ħ +) | +éħ ¿ +çļĦä¸Ģ éĥ¨åĪĨ +è¾ Ł +Ġcomp leting +Ġauthent ic +ack son +ĠJ ane +Ġcur riculum +D an +ĠL E +åĩºçݰ çļĦ +Ġen abling +_ J +Ġ ä»ĸ们 +ĠCov id +Ġl ying +pp y +Ġm ari +Ġdi pl +Ġexcess ive +_ ind +ĠC opy +Ġchemical s +ï¼Į æ·± +Ġst amp +å¦ Ħ +Ġmodel ing +ĠCon vert +Ġcoron avirus +ĠDeterm ine +çĭ Ń +_ content +说 æĪij +ç½ ķ +_f rame +Object s +on ing +end ants +为 人 +_ update +Ġmathemat ical +E st +åįł æ¯Ķ +Ġsurg ical +t ures +( is +Ġwal ks +Ġencour aging +Ġspecial ized +Y eah +æĺ¯ 被 +T om +ĠMar c +åıij æĶ¾ +Ġgen re +ä¸į å¿ħ +ç¾İ丽 çļĦ +Ġpopular ity +Ġ èĢģ +Ġar ise +on ut +èĥ½ åIJ¦ +r h +W D +Ġrout es +} ; +g ba +fl ag +Ġ@ " +ĠL yn +ĠSt ay +Ġcy cles +Ġin equality +ĠRest aur +Ġpast e +èĢIJ å¿ĥ +ju ana +st all +Ġche aper +Ġprec ious +åħ³éĶ® è¯į +bour ne +_VAL UE +ĠN orm +Ġcoupl ed +Ġint ake +çİ© ç¬ij +Ġ èµµ +as ive +Ġw rt +ä¸į ç¦ģ +æ±Ł æ¹ĸ +_ format +åĬł æ²¹ +Ġg ang +ou ver +ä¹Ł 被 +ĠAl ice +Ġapp le +N ECT +Ġcabin et +in ely +[ index +å½¢ 容 +æĪĺ åľº +Ġpl ates +宿 èĪį +oen ix +课 é¢ĺ +ac ular +西 åįĹ +ĠMat hemat +å½¢ çļĦ +ĠGl ass +èĩªèº« çļĦ +ä»Ģä¹Ī æĺ¯ +@g mail +ĠR ange +ĠC I +Ġcour age +own ers +ĠA bs +. Ed +Ġ 人 +ab ama +Ġs ender +å¾Ĺ 以 +éħį å¤ĩ +E duc +Ġbl ame +Ġ) ; +ĠB B +ĠAll en +Ġl ands +. query +P air +Ġincor porate +ï¼Įä¹Ł æľī +Ġv on +ĠIndian a +. insert +Ġcur ves +Ġgrad ient +Ġsurround ed +{ array +ĠSchool s +M ill +æijĩ äºĨ +Ġcor rection +Ġlaw yers +Ġemb race +Ġp ixels +Ġattempt ing +Ġag enda +.com mon +Ġins pect +ãĤ Ĭ +qu ire +Advert isement +re ach +_ load +Ġp H +G P +ï¼Įä¸Ģ æĹ¦ +Ġconsist ing +ĠB an +ot imes +Ġint u +ãĢĤ ä¸ŃåĽ½ +Ġreli ability +è§£ çŃĶ +Ġbr anches +Ġl l +Ġdiscrim ination +ap or +ĠDis play +pr imary +ï¼Į 尽管 +ĠAl ways +âĢľ ä¸Ģ +. format +ï¼Į éĿŀ +Ph i +Ġprom ised +p atch +ĠR ail +{ N +ĠC F +Id entity +ï¼ī ï¼ļ +gn ore +è¦ģ æľī +Ġindic ator +ĠMal ays +own ed +S igma +é¹ ħ +æĺ Ķ +ä½ľ æĸĩ +å°Ĩ æĿ¥ +æ¡ IJ +åħ¬ æ°ij +æĿ¡ ä¾ĭ +ä¸Ģ éĥ¨åĪĨ +缸å½ĵ äºİ +ĠS ant +è¶ Ł +v ia +çºł 纷 +Ġs ync +ï¼ī ï¼Ľ +Ġresc ue +Ġparticip ant +éĢłæĪIJ çļĦ +Ġeleg ant +çIJĥ è¿· +Ġsmart phone +主 æ¼Ķ +æĺ¯ 大 +Ġun p +Ġg auge +ä¾ £ +ĠH u +Ġcompar able +ĠN ations +File Name +åĪĨ æķ£ +Ġdiagn ostic +è¡¥ è´´ +ä¼ļ éķ¿ +æķ · +æŀ ķ +Ġpl acing +å½ĵ äºĭ +Ġbur st +åħ¨ æĸ° +B oth +There fore +Ġadj acent +c ategory +ĠB arn +è¿ij å¹³ +ï¼Ł " +çļĦ ç»ĵæŀĦ +Ġad vers +åIJİ æĤĶ +Ġc otton +åĩı è½» +Ġmat ched +ost ics +rict ion +Ġrecommend ation +ag an +ex pr +UP D +ag le +um bers +åĮĹ æĸ¹ +Ġgluc ose +ĠShe ll +Des pite +L abels +Ġreal istic +Ġt ar +Ġthe sis +ĠB R +- O +é© ³ +ick ed +Ġtem pt +æĥħ çļĦ +æĪª æŃ¢ +c ellent +Ġs ne +çĥŃ æ°´ +çŃī çļĦ +ï¼Į æĹ© +Ġvert ices +å« Ĥ +ĠF loor +åįł æį® +ï¼Į以 便 +Ġsc oring +ĠJ ay +( index +Ġcol ours +æ² § +Ġt v +bl ue +, æĹł +èµĽ äºĭ +, 对äºİ +éĺ IJ +Ġ åı¶ +. equal +, åħ¶å®ŀ +C md +æĢİä¹Ī ä¼ļ +ï¼Į 两个 +ĠAtl anta +ĠMass achusetts +å»¶ éķ¿ +og y +缺 éĻ· +éĶ ¤ +å¼ķ é¢Ĩ +ol ine +è§ģ äºĨ +Ġin ev +Ġis instance +b us +Ġem ission +_f unc +æĸ¯ åĿ¦ +ĠM enu +Ġchar ity +Ġathlet es +W ater +at on +ĠS erial +ĠS TR +ĠAn swer +ĠKore an +ĠD raw +Ġsk i +Te am +á º +ru p +_N UM +N Y +âĹ ĭ +Ġden ote +Z one +人æ°ij æ³ķéĻ¢ +Inst all +S ql +H ub +åı¯ä»¥ 帮åĬ© +ĠB irth +åĽŀ äºĨ +å®Ī æĬ¤ +ribut ions +éĢ ¾ +Ġbare ly +å¼Ĥ çļĦ +ï¼Į èĬ± +Eng lish +Ġa uth +apt ure +Ġgu ides +Ġt ent +Ġvent ure +è® ½ +Ġconsequ ence +Ġvol unt +_h andle +ĠB io +Ġsubst itute +è¿ĺ 羣 +ç² ¥ +ĠJe an +ãĢģ å¤ļ +Ġb ass +æĬĬ èĩªå·± +_ const +Ġcou ples +ur ches +ut ex +UCC ESS +Ġf ract +Ġind oor +A bs +ä¸Ģ 级 +èľ Ģ +æ½ ĩ +r ade +é¼» åŃIJ +ĠS A +ä¸įä»ħ ä»ħ +) ** +w riter +Ch apter +ä¹° åįĸ +ï¼ī åĴĮ +do ors +ac co +Ġdesign ated +L anguage +ä¹ł è¿ijå¹³ +_c ache +é ij +Ġsustain ability +Ġobl igation +æ¿Ģ åıij +ĠS olution +L ive +Ġa qu +æķij æı´ +ĠG ree +ç±» åĪ« +ä¸Ĭ æĸ¹ +ä¸į åĸľæ¬¢ +Ġf ool +éĺ¿ å°Ķ +' S +ĠEd ge +D NA +积 åĪĨ +å° ī +Ġcoe fficient +æľįåĬ¡ çļĦ +ul se +Ġaff irm +\ times +b urn +æĮ ¨ +Ġdis pute +æķ´ æ²» +éŁ³ é¢ij +- al +Ġst ere +æĭ ĺ +Ġth irty +a que +UR I +Ġlik ewise +身 æĿIJ +ä¸įè¿ĩ æĺ¯ +lish ing +æĹ¥ æĬ¥ +Ġbab ies +F urther +Ġtri angle +hab ilit +Ġbehavi ors +å·´ é»İ +-d ate +ĠDef ense +ASS ERT +Ġg rain +åĮ ª +Ġne ural +纳 ç¨İ +N ov +è¿ĩ 度 +add y +æīĵ çł´ +ar ma +i op +Ġflow s +ä»İ å°ı +Ġaccomp any +Ġinflam mation +ä¸į ä½Ĩ +Ġ å°Ĩ +ç͵ æŀģ +Ġth y +Ġ 以 +G od +æľīä¸Ģ 天 +l on +Ġtiss ues +Ġany body +C ent +Ġf s +n ut +R P +ĠF ilter +åįĹ æĸ¹ +Ġorder ing +Ġrestrict ion +.C ount +ĠG olf +Ġp ets +Ġag gressive +æī¾ ä¸įåΰ +åij ľ +Ġproduct ive +æ´»åĬ¨ çļĦ +(' # +Ġrec ru +- align +} : +ition er +ï¼Į èĩ³å°ij +ĠReg ion +ĠM aking +æĺ¯ æĪij们 +doc s +ĠR oss +web kit +ĠA ve +vent ory +Ġpaint ed +ĠC ool +( config +ar o +! \ +ĠA F +åij¼ åIJ¸ +Ġnum py +A IM +IS S +Ġc ord +ï¼Į é¡¿æĹ¶ +Ġch ips +ĠC ra +us hes +ç¥ Ī +re a +Ġv oted +Ġsubsequ ently +Ġdis closure +Ġaccompan ied +ãĤ Ĥ +Ġinter section +Ġsc ream +å®ł çī© +F actor +ï¼ģ " +æĹ¥ èĩ³ +æĤĦ æĤĦ +Ġd urable +ï¼Į åĨħ +æĿ ı +åħ¸ åŀĭ +è¿ĩ 头 +éľĢè¦ģ çļĦ +ĠRec ords +ï¼ļ ãĢĮ +æľĢ åĪĿ +Ġt ears +ĠA st +å°ģ éĹŃ +æŃ¤ åIJĮæĹ¶ +å¤į åζ +ï¼Į æĭ¥æľī +if act +åı ® +çĿĢ å¤´ +ãĢĤ åIJİæĿ¥ +at ers +åľ¨ åľ° +ï¼Į ä»Ĭ +ä¹ĭ éĻħ +Ġshort ly +åĮĸ åIJĪçī© +ĠH ind +Ġpart ially +am ount +åĽ¾ä¹¦ é¦Ĩ +好 åIJ§ +ãĢĤ ä»ĸçļĦ +æĹ ¬ +Ġr ug +Ġarr anged +B undle +Ġpublic ly +åĭĩ æ°Ķ +å©´ åĦ¿ +_ Y +empl ates +F il +Ġ éĩij +Ġpref erence +ĠE C +B al +ĠU V +Ġre wards +ĠH art +æł¼ å±Ģ +Ġform ats +Ġref riger +ĠNot es +g ency +ric ts +els on +Ġvis itor +Ġaddress ing +enc il +éĢĤ éĩı +- ph +Ġopt s +æĭ IJ +åIJ¬ çĿĢ +ĠEX P +Ġloc ate +ï¼Į éĢīæĭ© +_ def +A ir +\ to +ĠL arge +å¡ Į +Ġprom ises +åĨ¬ åŃ£ +lu x +.Error f +SS ION +æľīéĻIJ 责任 +Ġoverwhel ming +ab ases +æį ŀ +âĢĿ ï¼Ī +ç¾İ 好çļĦ +Ġbar rier +! = +f ly +ä¸ĵ é¢ĺ +ĠAtl antic +Ġport able +R oute +p aper +ag ra +ç² ¹ +çļĦ æĢģ度 +so ck +) åĴĮ +(' . +ĠL ot +b ot +ãĥ « +ĠH o +è¿ĩ åIJİ +ĠRep resent +Ġport ions +ç»ĵ ç®Ĺ +May be +ä¾Ŀ 次 +ä»» æĦı +ĠE L +ĠP ear +Ġtable t +Ġclin ic +R andom +çŁ ® +ĠPh D +IC T +ï¼Į æıIJä¾Ľ +Ġdram atic +ü r +ç¨ĭ度 ä¸Ĭ +ĠMin i +_ IM +æĬĬ å®ĥ +ĠER R +ĠVictor ia +ĠReg ional +T ech +ĠMary land +é¢Ĩ åıĸ +è¿Ļ æīį +con n +AN GE +å¹² æī° +Ġequ ality +é«ĺ åİĭ +äºĮ 级 +V ENT +å· ¢ +id al +Ġlist ener +m ont +Ġext ensions +A xis +Ġimm igration +èĪŀ è¹Ī +Ġbu cket +Ġtra iler +ĠQu ant +Ġoblig ations +æħķ 容 +è´¦ éĿ¢ +_h ash +æĺ¯ 没æľī +Ġlik elihood +ĠR oll +-st ep +Ġre pository +Ġpow ered +ï¼Į èİ« +Ġco pper +åķ ¸ +ï¼Įä¸į å¾Ĺ +éļ¾ å¾Ĺ +. object +Ġy eah +Ġrep airs +Ġoccas ions +Ġscr atch +Ġle ak +Ġdescrib ing +m ate +m c +Ġtrem end +emp loyment +ĠFe ature +ĠG M +身 çļĦ +plic ity +ĠC lose +ç§į ç§į +LO W +Ġacknow ledge +éĿĴ å°ijå¹´ +Ġdesign ing +Ġat om +B egin +Ġvit amin +Ġwhe els +ot ypes +cre ated +w p +=" ../ +Ġs li +åı¯ æĥľ +Ġsp oken +Ġhe x +Ġ åıª +æĪ¿ 产 +æĺİ æĺİ +_p ack +åħ±äº§ åħļ +. annotation +ĠH old +.L ength +Ġinv ari +_r ate +Ġj s +çľ¼ 泪 +ĠHarr is +ĠT E +Ph ot +ĠPro b +/ G +result s +ĠInvest ment +z o +Ġencour ages +å®¶ ä¸Ń +comm it +- only +Ġsub mission +éĺ³ å¸Ĥ +" It +_arg ument +Ġcar pet +å³ » +AD ER +ĠMe eting +Ġb ot +_D IS +å¿ĥ æĢģ +Ġv ine +ap on +Ġtrans mit +_ qu +ĠRepublic ans +Ġsch ol +ut ory +d ots +èĦ¾ æ°Ķ +, åį³ +ĠInit ial +ĠMo ore +Ġfe as +her lands +Ġhit ting +è¶ĬæĿ¥è¶Ĭ å¤ļ +Ġ* , +unn els +Ġthe rapeutic +ĠI owa +ĠEnter tainment +Ġcon secutive +_C ODE +å°ı åŃ© +Ġcannab is +大 åѦçĶŁ +ac o +ĠAf ghan +èIJĿ åįľ +Ġ اÙĦ +Ġqual ify +Ġp izza +æķ°æį® çļĦ +ĠEN D +æĬķ 票 +ca ption +{ B +sequ ently +ĠW E +èĦ± 离 +ine craft +_t ypes +Ġinf ected +Sub mit +Ġmin istry +Ġgar lic +åıĸå¾Ĺ äºĨ +Ġb lo +Ġstake holders +åıij è¾¾ +ï¼Į é£İ +ĠSim on +ï¼Įå½ĵ æĹ¶ +Ġfasc inating +sk ip +Pl atform +æ¼Ķ åͱ +ĠDe al +rypt ed +åįĬ 天 +id i +ĠAlex ander +Rend erer +ä¸Ģ ç³»åĪĹ +Ġcorrespond s +J ul +con c +al g +Ġwra pped +d n +Ġk g +atter y +Ġconfig ure +J an +æ½ Ń +Ġco in +ĠD oc +Ġaccompl ished +å°ij çļĦ +o T +åĩº ä¸Ģ个 +åĿĩ 为 +æĹłè®º æĺ¯ +æĮĸ æİĺ +Ġhydro gen +èĢģ 大 +ï¼Įæ¯ı 天 +Ġin sect +Ġcor poration +ĠH ills +St atic +导 å¸Ī +Ġengine ers +Ġdom ains +Ġoutput s +add le +æĺ¯ çļĦ +ĠIndust rial +æ° ® +ĠPort ug +{ a +Stand ard +U F +æĢ Ķ +Ġ' # +es ign +Ġemp ower +Ġ' - +ĠNiger ia +ç¿ ģ +Ġmotiv ated +Ġher itage +å±Ģ éĿ¢ +att ed +ï¼Įä¸į çŁ¥ +Ġtrans cript +Ġpersonal ized +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠ +es y +ill ance +Ġfranch ise +ä¼ĺç§Ģ çļĦ +Ġmake up +Ġco inc +Ġcompl aints +ĠAl b +æŀ £ +åĺ ± +Ġtrad em +Ġdiscount s +ç͍æĪ· çļĦ +Ġc ited +Ġan ger +讨 åİĮ +y r +Ġh oney +ĠIM PLIED +å¤ı åŃ£ +ĠLIMIT ED +ĠPat rick +ä¸Ģ å¼Ģå§ĭ +èŀį åħ¥ +Ġanc est +Ġi Pad +.c lear +{ L +大 æĪĺ +ĠV AL +å¾ħ éģĩ +plic it +çĶŁ 涯 +å¤ļ å¹´çļĦ +ç²¾ å¿ĥ +åİ ķ +W orks +Ġsc ulpt +P F +m atic +Ġpro pri +Ġper ception +ï¼Įä½Ĩ ä»ĸ +Ġkey word +çļĦ åĬŁèĥ½ +- weight +çļĦ åŃĺåľ¨ +çļĦ éĢŁåº¦ +ï¼Į å¾Ĺ +d iff +Ġbe aring +Ġread ily +Ġwork out +ï¼Į 举 +åĩº åħ· +Ġflo ating +ï¼Ł è¿Ļ +R ob +çŀ Ĵ +éļ¾ é¢ĺ +, . +Test s +ĠS everal +å°¼ äºļ +init ial +ed er +sub section +Ġcompet itors +s ure +ĠW olf +æĪij ä¼ļ +æĥ³ äºĨ +% ãĢģ +-h and +大 声 +Up dated +å¸Ĥåľº ä¸Ĭ +éľĩ æĥĬ +Ġsens ors +l ayout +Ġfit ting +_ END +pr ises +Ġac ids +-l ife +Ġ å½ĵçĦ¶ +Pl us +ro se +模 åħ· +H aving +åħ·ä½ĵ çļĦ +çī© æĸĻ +ãĢĤ ä¸Ģèά +Ġextra ordinary +åĵª åĦ¿ +å°½ åı¯èĥ½ +Ġblock chain +ur face +å¢ŀ å̼ +Ġpoll ution +att ice +ä½ĵ åζ +æĬ¥ èĢĥ +èŁ ¹ +èī° éļ¾ +Ġcomp lement +Ġp se +Not Null +Ġd irt +è¿Ļ个 人 +_f unction +Ġto ys +in th +ĠCom mercial +è§£ éϤ +Ġcr imes +çĭ Ħ +ï¼Į éĿŀ常 +Ġmount ed +è¿ŀ å¿Ļ +çīĻ é½¿ +Ġdir ty +Ġhun ting +Ġm old +æ´» çĿĢ +ĠEV ENT +ĠB M +ĠCo ord +ä»İ æľª +æķĻ å®¤ +Ġb rack +And roid +Ġre ception +Ġqu it +Ġorganis ations +Ġp up +çļĦ å½¢å¼ı +好 åıĭ +ç͵ æ°Ķ +( text +çģ¯ åħī +ãĢĤ ä¸Ģ个 +ï¼Į 羣æĺ¯ +Ġout s +æķ° åįģ +Ġaffect ing +ĠFore ign +, m +h ang +å¾Ī é«ĺ +ĠS ydney +ĠE M +ar ound +_ co +å¿ĥ æĢĿ +第ä¸Ģ æĹ¶éĹ´ +is l +Ġdest ruction +ĠT el +Ġc av +ç«ŀ èµĽ +_W R +Ġн а +u ccess +ä»Ģä¹Ī æł·çļĦ +Ġle mon +r ans +没 äºĨ +ä½ł å°± +Ġmin imize +Ġintellig ent +u its +, v +åĪĿ æŃ¥ +, èĥ½ +Ġr ings +ĠC OM +Ġsh ips +F ill +Ġyield s +Sh op +cont act +b log +Ġform ing +Ġd t +æĺ¯ä¸Ģ å®¶ +Ġpursu ant +Ġvari ance +} ' +Ġe ager +Ġbe ef +on ical +ur red +Ġconv in +æ°´ æ³¥ +O F +nc ies +ath on +ĠP E +Ġf ut +ĠPar liament +éĹ» è¨Ģ +ĠS ex +] -> +ĠJew s +ĠSim ilarly +Ġaccur ately +åľ°åĮº çļĦ +ig it +Ġthread s +Ġvar ied +Ġch ains +æĭī çĿĢ +Ġtransform ed +纽 约 +Ġbelong s +Ġprogress ive +ç»Ļ æĪij们 +ãĢĤ 第äºĮ +ĠW ales +ĠD iam +Ġaccommod ation +ĠAg ric +Ġclust ers +ĠAdd itional +eh icle +ï¼Į 满 +, ä¸įè¿ĩ +ĠN ev +ĠD evice +Ġl iv +p res +_ action +ĠL ie +æ¾ ¡ +æł ħ +çĦ¦ èĻij +ir q +- order +: ' +: @" +="../../ ../../ +好 çľĭ +as sembly +ä¿ ¯ +ä¸ĸçķĮ æĿ¯ +cri ber +ä¸į 满 +ol k +Ġwhere in +C ity +ĠS EC +Ġfriend ship +istic ated +Ġ: ) +æĭ¿ èµ· +æĿ¥ åΰäºĨ +ï¼ĮæĪĸ 许 +Ġse al +ĠGover nor +å¼ķç͍ æĹ¥æľŁ +Ġr ated +Ġprom ising +const ruction +Al ways +-------------------------------- ---------------- +(t arget +åij³ çļĦ +沿 çĿĢ +Ġcont rolling +è¿Ļä¸Ģ åĪĩ +# else +äºĨ 许å¤ļ +-in ch +ĠR ol +è¿Ļ æĿ¡ +诸 å¤ļ +Att r +客 æľį +- int +z ero +ç͵ ç¼Ĩ +ï¼Į è¿Ľè¡Į +åĨ¬ 天 +Ġtox ic +ĠComp lete +ER Y +ĠP itt +, 大家 +st ock +be ing +-be ing +Ġret ired +Ġforg iveness +ä¹ĭ äºĭ +g al +Ġbreath ing +Ġrank ed +Ġv intage +èĢ ¸ +ex ception +å¹³ 常 +ï¼Įä¸Ģ åĪĩ +Ġin cl +Ġh ill +S outh +ï¼Į åIJĮ +ĠD om +ï¼Įæľī çļĦ +ĠIntern al +ĠMag ic +Ġsp am +Ġoccasion ally +ĠF ocus +Ġconv iction +Ġconf usion +ç»Ĩ èıĮ +on i +Ġtack le +ç¢ Į +çľģ 级 +ard ed +éĿĻ éĿĻ +ĠV eter +æĸ° æĹ¶ä»£ +Ġvary ing +æĦŁ åºĶ +aud i +Ġdro ve +ĠD utch +re ason +æĿĢ äºº +è¹ ² +ĠE c +åĩł åĪĨ +帮 ä½ł +ä¾Ľ ç»Ļ +Ġcar b +Ġh ired +管çIJĨ 人åijĺ +Ġdel iber +寻 æ±Ĥ +Ġjew elry +ER N +Ġmari juana +å§IJ 妹 +lah oma +F ragment +ĠM ission +ĠIn n +ĠR isk +, : +- item +/ $ +Ġd ip +ag ers +çļĦ åħ·ä½ĵ +ĠViet nam +èĢ » +代 è°¢ +b ib +ĠW ait +ç²¾ 度 +et adata +ĠB iden +ĠComp anies +[ ( +ä½ĵ 积 +Ġup set +ç§ijæĬĢ æľīéĻIJåħ¬åı¸ +& \ +Ġcr ushing +èı © +ĠG i +L ower +æįŁ åĿı +Ġrub ber +{ ( +vert ed +幸 è¿IJ +ä¼ĺ éĽħ +ï¼Į å¦Ĥä½ķ +stand ard +ĠMic hel +Ġpublic ations +LE S +Ġarrang ements +æµ· åįĹ +ĠG ift +å¢ĥ åĨħ +/ O +严éĩį çļĦ +D IR +mb ox +Ġdem o +ĠR ap +ch annel +am ous +Ġgr ants +(" # +ĠMat rix +Own er +__ , +- ad +Ġincorpor ated +R aw +" ], +åΰ ä½į +ä¸į ä¸ĭ +ï¼Į é»Ħ +el and +Ġfl ights +Ġsil ent +m other +åĢŁ åĬ© +ĠAd vis +ed itor +( () +En v +{ figure +G ui +as ures +ĠM ock +our t +d ale +Ġt ong +ĠE lement +Ġ åı· +Ġsing ular +rac le +Ð ³ +å¹¶ æľª +ĠDel hi +ĠPro file +Ġindepend ence +Ġj et +.c ol +Ġt ender +Ġinteg rate +M c +åºĵ åŃĺ +Ġp d +åħ¨ çľģ +Ġhe al +Ġblock ed +Ġdis rupt +å·² æľī +以 å¾Ģ +T x +ĠCom pl +G G +ĠÐ · +æĦ ļ +æĿ¥ 讲 +æ°Ķ è´¨ +ab e +C hat +åıĪ æľī +ãĢĤ åı¯ä»¥ +èĢĮ æĪIJ +ï¼Į è¿Ľä¸ĢæŃ¥ +оР´ +Ġn urse +书 ç±į +纪 å½ķ +帮 æĪij +äºĽ ä»Ģä¹Ī +Ġh ierarch +Ġcons olid +_ OUT +N E +ï¼Įè¿Ļ æł·çļĦ +éķ¿ æ±Ł +\ text +N ational +ĠSur vey +éŁ § +Ġinsp ire +ĠY outh +e in +ĠBen efits +Ġch ampion +åĽ½åĨħ å¤ĸ +ĠTechn ologies +B ro +: h +åĿ İ +çļĦä¸Ģ 端 +åħ¬ åĬ¡ +èĬ Ļ +ĠD im +_ query +H P +Ġdiscuss ing +åĽ¾ æ¡Ī +urre ncies +çľĭ ä¸Ĭåİ» +ĠAg ent +Ġwin ners +åºı åĪĹ +åī© ä½Ļ +per ature +Ġres ist +Ġspeak s +Ġm l +Ġphenomen on +ç» Ĵ +éĴ ł +AN K +Ġp ose +ĠCol lect +am az +Ġstart up +Ġres erv +ĠÎ ³ +æĿ ł +o ks +è¿ĩåİ» äºĨ +æĽ² 线 +ĠH um +大 å¤ļ +æİ¢ 讨 +æĿĥ éĻIJ +Ġdom inant +èĤ¡ å¸Ĥ +æĺ¯ä¸Ģ äºĽ +EM ENT +Ġsee ks +ĠPe ace +æıĴ åħ¥ +Ġf ears +rec ision +Ġh o +åħ¬ å¯ĵ +ĠH ur +åľ¨ éĤ£ +ä¼ ŀ +Ġsim ulations +å´ ĸ +ĠM oh +çļĦ 表çݰ +h line +ĠD rug +Ġwor n +ĠA bb +Ġ ä¸Ģ个 +V T +( cl +Ġsec ured +ce iver +, æ¯Ķå¦Ĥ +Ġbe ans +è¶³å¤Ł çļĦ +AT OR +ĠCommun ication +éĥ½ ä¸įä¼ļ +ĠP D +ç§° åı· +çļĦ 女人 +èĦij æµ· +_ST ATE +_fl ags +æļ´ éľ² +Ġdenomin ator +S en +æĹł åħ³ +ĠRes pons +æĢĢ åŃķ +ĠLook ing +Ġassum ptions +or izontal +an ia +.s ave +_G ET +ï¼Įçľĭ æĿ¥ +ç¼´ 纳 +.c ss +аР» +Ġnot ifications +Ġ åįķä½į +Ġcl ause +ir s +æĪij è§īå¾Ĺ +.c pp +_ view +Ġw ing +Ġr ust +ĠB us +ĠR aj +éĢ Ĺ +æŃ ª +Ġold est +, a +/ - +Ġben e +线 ä¸ĭ +èı ĩ +Ġins ulin +éĻ Ģ +æĭ ± +Com put +H appy +ĠT ennessee +en ue +éĺ² çģ« +Mem bers +sh are +ĠH al +M onday +ĠN urs +Ġnew est +西 äºļ +Ġprior it +å°± å¼Ģå§ĭ + Ĥ +Ġpharm ac +ä½ł æĥ³ +Ġdecre asing +éĴ¢ éĵģ +çļĦ æĥħ +ï¼Į åĪ©ç͍ +ĠHall ow +æī® æ¼Ķ +Ġend orse +L ow +Ġhuman ity +н о +æĢĢ éĩĮ +ĠS ession +åĬ© åĬĽ +th ur +ö r +ĠD J +èĭ ij +Ġsoc cer +å¦Ĥ åĽ¾ +eb ook +Ġcon ce +Ġend point +ĠRef erence +缸åIJĮ çļĦ +Ġam plit +ï¼Į æĹ¶ +åįģ è¶³ +B ool +Ġman uscript +-l ink +Ġfin ishing +åºĶ ç͍äºİ +ĠThe ory +è¿Ľ 度 +èѦ æĸ¹ +ex pect +Ġpr inter +Ġkey words +å· © +Ġpo etry +f ather +Ġdead line +æ´» åĬĽ +Ġe ars +åIJĦ 大 +M ichael +Ġfab ulous +Ġtext s +ï¼Į åįķ +exp ression +_ ACT +anc ouver +èĶ ĵ +å½ĵ 代 +Ġscal ar +ĠTra il +éķ¿ å®ī +vel ope +/ st +Ġprotect ive +ï¼Į æĹ¥ +éĢļ ç͍ +ï¼ IJ +_t itle +Ġmoist ure +èĢĥèĻij åΰ +-d ependent +Ä « +ĠS ay +Ġcook ed +ĠS ET +lo ve +, è¿ĻäºĽ +èł ¢ +Ġinter mediate +å¼Ģ 车 +æ¶Ĥ æĸĻ +_EN ABLE +çļĦ 对 +N a +ĠIss ue +ĠF at +ĠLa ure +ä¸ĩ åIJ¨ +( ` +ĠM I +ener ate +çļĦ åħ³éĶ® +ãĢĤ ä¸Ĭ +ä¸į çĦ¶ +ott a +ĠC rim +pe g +m n +ĠApp lications +Ġoper ates +ĠM and +Ġflo ors +ï¼Į äºĶ +v ation +æ£ µ +Ġcollect ing +_ values +ĠT yp +Ġbeg un +æĭĽ åĶ¿ +Ġn n +Ġworks hops +rb an +pt ic +æĬµ æĬĹ +_ Q +f ox +ĠR andom +at tern +Ġpre jud +ãĢģ çϽ +强 åζ +umb ing +Ġharm ful +ï¼Į æİ¥çĿĢ +èµ·æĿ¥ äºĨ +ĠF ellow +Ġdig est +ys ql +åħ¶ä»ĸ 人 +ĠS amsung +Ġg reet +ipher al +ä¼ł éĢģ +A li +Ġv iral +z i +çłĶç©¶ éĻ¢ +Ġb arg +çļĦ人 çī© +æĸ° èĥ½æºIJ +prot ocol +ç»ĵæĿŁ åIJİ +EE E +ï¼ĮæĪij ä¼ļ +ĠPart icip +g ame +ential ly +ĠL eft +ä¼Ł 大 +� � +ĠPro perties +Ġinc ub +_DE BUG +F riday +åı¯ æĢľ +oo oo +Ġred irect +: ` +ĠO cc +Ġint ra +ï¼Į æĮĩ +vis ible +æį ¡ +æıIJ èµ· +- trans +Ġsell er +Ġd ivers +aff e +åIJ ı +dom ain +Ġsett le +ĠD atabase +w riting +, å¤ļ +Th ose +ĠR ain +ĠB esides +ï¼Į æĶ¾ +æµ· åĨĽ +-min ute +el eration +è¿ĻéĩĮ çļĦ +ï¼Į æĹ¢çĦ¶ +ï¼Į ä¹ĥ +ĠI ce +W eek +Ġv endors +åıĸ 代 +西 éĥ¨ +) ^{ +è° Ń +ãĢģ ä¸Ģ +éĤ£ æĺ¯ +个 ä½ĵ +Ġcomplic ations +oles ter +Ġport al +æłĩ è®° +Ġclos ure +å¹¿ä¸ľ çľģ +ilib rium +Ġra ces +éij « +ĠE T +èİ ŀ +å½ĵ 天 +åĩĨ åĪĻ +åŁ¹ èĤ² +ag ine +ĠMat thew +æij© æĵ¦ +æī ģ +ï¼Į ä¿ĥè¿Ľ +Ġnot ify +ent o +/ a +_ if +Ġfl ip +Ġf et +Ġconsist ency +çķĮ çļĦ +ĠC E +Ġsubs crib +人 ä¹ĭ +ic ating +éŀ Ń +åı³ æīĭ +Com b +æĹ¶éĹ´ çļĦ +rem ote +çݰ代 åĮĸ +ï¼ĮæĽ´ æĺ¯ +ĠR id +Ġj aw +Ġwork force +ĠAr k +ĠB oot +åºĶç͍ ç¨ĭåºı +IN FO +Ġ" _ +ĠR ES +è¯Ŀ 说 +èļ ģ +Ġ é¡¹çĽ® +Ġplaintiff s +A merican +ĠC ry +Ġdefe at +ĠC ele +ĠPer fect +Ġextract ed +OUR CE +Ġhonest ly +çķĻ è¨Ģ +end l +x d +V E +ä¹Ł æĺ¯ä¸Ģ +ï¼Į åIJĥ +伤 åı£ +ï¼Į让 ä»ĸ +çݰ çĬ¶ +_d im +t f +Ġj ail +ĠÎ » +ï¼Į å°¤åħ¶ +å· ħ +Ġfund ed +ä¸Ģ åįĬ +- reg +ï¼Ľ åľ¨ +ps y +æĸĹ äºī +å½¢æĪIJ çļĦ +ï¼Į é¦ĸåħĪ +S peed +åĩº äºİ +_c md +ĠMan chester +è´µ æĹı +_ Get +æľīéĻIJ责任 åħ¬åı¸ +Ġvis ibility +ĠRE G +Ġ åħ¶å®ŀ +Ġdef ensive +Ġexpect ing +éķ¿ èĢģ +o il +ĠP ret +Ġp el +ç¬ ¨ +Ġre aches +Ñ İ +åıij è¨Ģ +off s +è¿IJ 转 +cc a +çĦ ī +è¿Ļ éĥ¨ +Ġp tr +Ġkn ife +åĩĿ èģļ +ãĢĤ è¿ĺæľī +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠ +ï¼Į è¶Ĭ +F ood +s ort +Ġdes ert +ĠMem orial +_P ER +Ġunn ecessary +Ġbre ach +å²ģ æľĪ +ynt ax +l ag +ï¼Į å¹´ +æĸ¯ çļĦ +éĢĢ åĩº +åĺ¿ åĺ¿ + ½ +Ġg host +ï¼Į åıĮ +æłij ç«ĭ +Ġauthent ication +详 æĥħ +ĠC offee +ç»Ī æŃ¢ +缸 å¤Ħ +Ġmut ual +çİ© æ³ķ +ĠAm endment +åݦ éŨ +ĠG il +log in +åĪĨ æķ° +ĠY eah +ä¸į æĦ¿æĦı +-s m +å¸Ĥ å§Ķ +稳å®ļ æĢ§ +L R +Ġsh o +å¯ ¡ +客æĪ· 端 +ess ed +æĢ¥ å¿Ļ +hel per +Ġcar ing +Ġpers u +Ġprevent ing +æ·· ä¹± +Ġin k +Ġcompl iment +åľ¨ å¤ĸ +ĠB ureau +è£ ´ +b p +Ġ< !-- +ä¸ī ç§į +è¿Ļ å°±æĺ¯ +ĠMon itor +è¯Ń æĸĩ +ĠProgram s +Ġsou p +ĠInter view +( list +åŁºç¡Ģ 设æĸ½ +ï¼Į æģIJæĢķ +Ġdistribut ions +Ġout line +Ġfo am +( url +忽 çķ¥ +Ġm eth +Ġt ends +Ġver ified +çľ¼ éķľ +ĠMor gan +_f ilter +Ġex cluded +Ġex terior +ĠS S +æ±ĩ æĬ¥ +Ġfall en +ĠInt roduction +ig ue +emp loy +ç³» æķ° +{ D +_RE S +ĠIN T +sh ape +Ġcon ve +Ġpro pose +ent ine +' \ +ation ally +ï¼Į æį® +ç³ Ĭ +ĠEd ward +.g ithub +o j +( response +çĥ¦ æģ¼ + « +{ Z +ĠClass ic +Ġoptim ize +_C HECK +注æĦı åΰ +Ġ æł¹æį® +Ġb other +Ġsil ence +大 æ°Ķ +u ity +W est +C ast +Ġang les +ï¼Į åĪĨåĪ« +ĠNav y +.m odels +åĨ ¶ +Ġrun time +AT URE +M ouse +.f irst +Ġcontinu ously +Ġdel ivers +ĠAd vert +äºĭ åĦ¿ +Ġsubstant ially +Ġrid ic +Ġc od +ãĢģ é»Ħ +P DF +Control s +ä¿¡ ä»° +ĠRep air +DE D +Ġsol ved +Ġdis charge +象 å¾ģ +Ġenorm ous +em it +oun ge +, 被 +An im +Ġto ilet +太 åIJİ +ion ed +æĹ¥ ä¸ĬåįĪ +d m +Ġadd iction +ĠM ode +Ġenjoy able +设计 å¸Ī +以ä¸ĭ ç®Ģç§° +æĸĩ çī© +çīĽ å¥¶ +åĪĿ ä¸Ń +> ) +ord on +ĠClin ical +Ġprodu cers +оР¼ +åľ¨ åľ°ä¸Ĭ +Ġrem ed +çŁŃ ä¿¡ +ĠOr ange +ĠR ate +Ġpro ps +åijĬ çŁ¥ +ĠT ok +åŁºéĩij 管çIJĨ +åĨ· éĿĻ +åĪĨ æ³Į +ĠM IT +Ġmark ers +Ġdo ctrine +ä¸į æŃ¢ +å®ŀ ä¹ł +S an +: = +ĠS K +ãĢĤ æĿİ +éŨ å¤ĸ +Valid ation +ĠH ad +oles ale ++ ( +æµģ çļĦ +ĠOx ford +ĠVol ume +Ġt ear +å¥ ¸ +Ġsusp ension +Ġhor ror +ap olis +ensure math +ĠH ub +edd ings +out ine +éĴ ¦ +Ġut ter +_t arget +éĥ Ĭ +åľĨ å½¢ +è¿Ļ åľº +ure rs +代 ä»· +comm ended +å¾Ĺ å¤ļ +ĠS olar +rif ice +ï¼ĮæĪij æĺ¯ +Ġa ug +che ll +Ġ ell +çѾ ç½² +å°± æĬĬ +com b +åŀĭ åı· +[ å¼ķç͍æĹ¥æľŁ +ĠJ ess +ãĢĢãĢĢ ãĢĢ +ul ates +è¿ĺ åĮħæĭ¬ +T ry +UR N +Ġdiscipl ine +Ġsc ales +åĴ ª +å¼Ģ çļĦ +æĮ « +交æĺĵ æīĢ +ï¼Į é»ij +c n +-l ist +P erson +æ£ į +æ£ ł +çĶ « +å±± åĮº +è¿IJåĬ¨ åijĺ +è°Ī åΤ +ĠCal cul +c ule +Ġagric ultural +C ould +Cl uster +è¯ķ è¯ķ +Ġrepl acing +ï¼Į没 æĥ³åΰ +L ib +Ġsh it +_ ip +Ġtarget ing +' } +Input Stream +Ġpros pective +Ġsh aped +ï¼Įè¿Ľ èĢĮ +æĸŃ äºĨ +_f iles +éĢīæĭ© äºĨ +ĠChampions hip +(b uf +æīĵ äºĨ +Enc oding +Ġimp osed +icens ing +Ġrock s +. u +çļĦ æ¶Īæģ¯ +ĠÐ ¼ +Ù İ +Ġgrav ity +ĠAd ult +æĮ£ æīİ +漫 çĶ» +ES C +H TTP +ĠDise ase +ï¼Į 积æŀģ +ĠP odcast +æīĢæľī 人 +ĠT ai +/ test +AL S +Ġtechn ological +ï¼Į èĦ¸ä¸Ĭ +ĠHolid ay +ak h +Ġ[ ], +_P R +Ġpass engers +ä½ķ åĨµ +b age +Ġch amber +E lect +art ed +ï¼Į æıIJåįĩ +é¢Ħ 约 +åįĩ éĻį +g un +Ġcar ries +in ters +åĩ¤ åĩ° +ä¸Ĭ éŨ +Ġcomb inations +ä¹ĭåīį çļĦ +it arian +Ġdecl are +Ġper ceived +ĠM ut +ĠD ictionary +Ġth umb +ĠF if +触 åıij +ĠBer lin +Ġloyal ty +ãĢĤ ä»Ĭ天 +ug g +emb ered +ĠR ub +Ġdef ining +ov ies +Ġw are +Ġregard ed +éĿŀ æ³ķ +-d riven +ç»Ļ 人 +ĠNever theless +ĠTem ple +ä¸Ģ åı£ +and ra +ĠPre vious +ĠImpro ve +Ġpolynom ial +Ġbene ath +sequ ence +Ġfis cal +éĺ¿ éĩĮ +N R +rit is +ĠHallow een +è§Ĩ éĩİ +éĺ² çĸ« +Ġflu ct +Ġsh ame +:b efore +ĠPro du +åľ¨ åĵªéĩĮ +Ġg ig +ĠJac ob +ĠCl aim +æĸĩåĮĸ çļĦ +å¹´ 级 +Ġco ins +Ġactiv ated +p io +($ _ +r ific +Ġin verse +ÃIJ µ +Ġcoll apse +线 ç¨ĭ +Return s +å©ļ 礼 +an ne +Ġo live +Ġdirect ors +æ© Ļ +éĩį ç»Ħ +Ġviol ent +Ġgun s +ĠD ebug +èĬĤ çľģ +t ask +_T H +_d is +, æĪĸèĢħ +æĿĥ çļĦ +éĿ¢ æĿ¿ +ig o +Ġd ying +Function al +Ġgr inding +Ġdeal er +arc el +ch ing + § +comm un +ĠCr usher +è´¦ åı· +Head ers +Ġaff airs +Ġd é +ç«ĭ 马 +ا Ø +èĮ Ħ +ĠR oy +é¡ ½ +rac ing +ĠG A +Ġcom edy +æijĩäºĨ æijĩ头 +Ġv oices +Ġde emed +æľī æĹ¶ +er als +第 ä¹Ŀ +N orth +Ġo scill +ĠM agn +ct ic +Ġrank ing +ï¼Įè¿ĺ è¦ģ +.r andom +å¼ Ĭ +Ġaccommod ate +ĠIslam ic +åıĤ èµĽ +ann on +ch at +âĢĶâĢĶâĢĶâĢĶ âĢĶâĢĶâĢĶâĢĶ +.com p +åĽºå®ļ èµĦ产 +ãĢĤ åħ¨ +åĸĿ éħĴ +ë ĭ +ĠC ow +Ġprov ince +Ġimplic it +_M EM +Ñ Ī +ĠT oy +ig est +ab ul +对 她 +Ġcl s +Const ant +ĠBy te +ä¸Ģ è¡Į +æĶ¶ åĽŀ +Us age +ĠC hen +ĠC raft +计 æıIJ +_t ag +G rad +(m essage +Ġarch ive +åħī æĺİ +Sm all +ĠR ot +( msg +Ġconvin ced +it i +Ġult ra +对æĸ¹ çļĦ +ç¡® è¯Ĭ +** ( +è¿ľ çļĦ +Ġsign aling +Ġal uminum +oo g +ĠCl ark +! < +w he +ĠM ovie +Ġexcit ement +å¼ķ åħ¥ +主 åĬŀ +åıij ä½ľ +äºı æįŁ +Ġdelay ed +è§£åĨ³ äºĨ +Y Y +为ä»Ģä¹Ī è¦ģ +Ġrefer ring +缴 å¾Ħ +ãĢģ æĬĢæľ¯ +è¾½ å®ģ +is ite +Ġsh ade +åıį æŃ£ +ĠCl imate +> : +Ġdepart ments +en ities +èĦĸ åŃIJ +ĠIntellig ence +ĠP os +ä¸Ĭæµ· å¸Ĥ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠ +Ġt el +Å Ĥ +ĠG h +. U +Ġtrou bles +.util s +ĠTechn ical +ç ão +, 缮åīį +B inding +æĺ¯ åı¯ä»¥ +åѤ çĭ¬ +Ġin herent +r ison +Ġwal let +à ª +å°± è¿Ļæł· +Ġ\ ( +è¯Ĺ 人 +"} ). +æĪIJ åŀĭ +æĢİä¹Ī äºĨ +Ġ' @ +F X +ĠQu ery +æİ ł +æ¾ Ħ +co res +Oper ator +.b ase +åĿIJ æłĩ +ific ates +Ġsp ouse +sp ring +ï¼Į è½» +ç¼ĸ åĨĻ +Ġdo zen +æĽ´ 大 +ĠLe on +form ing +ĠL incoln +ï¼į ï¼į +äºĨä¸Ģ åı£æ°Ķ +ur u +Ġtrans cription +im en +ĠFl ash +ropri ate +ail and +è¿Ļä¹Ī 说 +æİ Ģ +Ġ 马 +è¿ĻäºĽ 人 +ount ered +åĵ ij +Ġgrow s +Ġatt orneys +å»¶ ç»Ń +红 çļĦ +Ġ èĩª +è·Ł ä»ĸ +æľĢ éĩįè¦ģçļĦ +/ index +ï¼Į èĤ¯å®ļ +Ġm ales +åı° ä¸Ĭ +B asic +LE TE +s n +uff le +Ġs ake +ĠDe lete +_m odule +act ic +Ġperm its +art z +ĠAll iance +åĩı å̼ +Ġpar ks +宽 度 +( state +support ed +å¿« éĢĴ +Ġu i +< tr +Ġestablish ing +Ġan onymous +Ġautom ation +ĠG ET +壳 ä½ĵ +ell ers +Ġse q +lot te +- cl +è¡¥ åĬ© +ĠA RE +ĠB BC +Ġdeg rad +Ġconst itutional +L o +m ad +ï¼Į åĬłä¸Ĭ +Ġpain ful +ĠFriend s +Ġir rit +æł¼ åħ° +æīĢ å±ŀ +注æĦı åĬĽ +Ġn est +.n um +-c ol +Ġm aker +Ġra ises +åŁİ 乡 +ul ent +Ġsynt hesis +ar ance +tr im +ĠH op +å¬ · +To String +èľ ¡ +Ġrom ance +羣çļĦ å¾Ī +Ġspecial ists +xx xx +ĠF ashion +P ython +s chema +èĬĤ 约 +bar a +# pragma +Ġd p +å¸Ī çĶŁ +éĤ µ +ä»¶ çļĦ +é¾Ļ 头 +éĢī 举 +Ġcirc ular +ä¸į éĶĪéĴ¢ +Ġsat ellite +_ Z +ĠInt el +ĠL ag +ä¹° äºĨ +ĠV it +Ġcent uries +ä¸Ģ æĿ¥ +Ġg ast +Ġpro gression +Ġag ing +ĠWith in +éĹ ¸ +ĠF ace +åΰ å¤Ħ +ex it +çī© ä½ĵ +ãĢģ 人 +åΰ çİ°åľ¨ +åįİ å¤ı +Sp ring +Up load +Ġo re +Ġr ats +Ġin e +Ġsuggest ion +åIJĪçIJĨ çļĦ +ĠThe rapy +æĪij çŁ¥éģĵ +ĠCamb ridge +æĽ´ 大çļĦ +ĠDef endant +ĠL ICENSE +Ġbu ck +m ade +if iable +éĻĨ ç»Ń +g ot +è¯ Ģ +eg u +ĠN J +ï¼Į åıĹ +æĪ· å¤ĸ +ĠAnth ony +äºĨ èĩªå·±çļĦ +ï¼Į åĪļ +Ġtro ops +Ð ¹ +Ġsl ip +__ _ +Ġliber al +-F i +æīĭ ä¸Ĭ +Ġconsult ing +Ġsp are +con sole +ft en +, å¸ĮæľĽ +强 èĢħ +ĠR ather +ject ion +Ġnon pro +Ġlast ing +æħ¢ æĢ§ +Ġro d +ĠS ort +, 以åıĬ +åį« æĺŁ +Ġconfirm ation +åıij ç͵ +j avascript +æŀ¶ æŀĦ +{ T +Ġsp ir +ĠJ son +Ġflo od +éĹ´ éļĶ +æ¼Ķ 讲 +Ġp ays +fore ach +Ġforgot ten +Ġinitial ize +身 为 +çα å¿ĥ +v able +B its +æľī ä¸Ģç§į +åıª 好 +US B +=" " +ä»ĺ 款 +社ä¼ļ çļĦ +æİĴ æ°´ +Ġra ck +N I +饮 æĸĻ +_P L +Ġpro be +Ġbank ruptcy +Ġadv ise +R ich +çļĦ é£İéĻ© +ivid ually +_ height +arr ass +Ġinter vals +ĠNS String +çļĦå¿ĥ çIJĨ +Ġsynt ax +Un iversity +Ġ Ì +ĠLI ABILITY +è± ¹ +ĠD a +. contains +ãĢĤ æĸ° +饰 æ¼Ķ +Ġvess el +ï¼Ľ èĢĮ +RO UP +p read +as a +ĠF R +char acter +åīį æĻ¯ +C red +ÑĢ Ð°Ð +ĠN A +å½ĵ æľŁ +åĿ Ŀ +Ġo ils +an ol +æĻ® åıĬ +Ġpoint ing +å¦ į +ut her +设计 çļĦ +od o +Ġd ess +Ġun e +ĠP ier +inem a +åĴ ķ +. empty +éĴ¢ 管 +Ġdon ation +æĿ¡ä»¶ çļĦ +ĠG P +et ics +S V +Ġc ure +Ġsupp orters +Ġl ips +ä¸į è¶ħè¿ĩ +ĠAl abama +l g +é» ı +p air +-pro fit +ĠCh at +ĠChar acter +_d et +un ting +f inal +Ġsoph isticated +åĪĨ è§£ +ĠE P +Ġpre view +ãĢģ å¼ł +Ġwell ness +æĪij åĴĮ +ĠQ ual +Ġchem istry +ew ard +åĽĽ 大 +ç»ıæµİ åıijå±ķ +ĠRed ist +Ġenc ountered +Ġmob ility +Ġmat rices +ãĤ ĵ +i w +< std +åħ¬ åħĥ +b efore +Ġconst raint +oc ytes +çľĭ äºĨä¸Ģçľ¼ +Ġg em +产çĶŁ äºĨ +ï¼Į 常 +us age +ï¼Įè¿Ļ å°±æĺ¯ +H older +, åıªè¦ģ +ĠIS O +æŃ£å¸¸ çļĦ +åĬ© çIJĨ +le ans +Ġwork flow +ocr atic +ĠR ick +b one +Intern ational +L ibrary +n orm +âĢľ ä¸ī +ĠE rr +è´¦ 款 +åľº åľ° +Ġfin est +b oy +æĬķ æłĩ +ĠA BC +Ġsw ap +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠ +i ator +è§Ĵ èIJ½ +Ġcal ories +Ġcontribut ing +ï¼ĮæĪij ä¹Ł +app rox +b es +ç͵è§Ĩ åı° +ĠMiss ouri +æĭħ å¿§ +ĠEnter prise +çĥ ¹ +Ġd ynam +Ġso ap +ol ph +A h +çļĦ æĹł +Ġet ern +ad os +Ġproject ion +ĠStat istics +Ġreason ing +ol as +N P +Ġqual ities +çħ§ æĺİ +éķ¿ æ²Ļ +主 åĬĽ +å®ŀçݰ äºĨ +Tra vel +代 æĽ¿ +qu es +Ġrep orter +æ± ° +åħ¶ ä¸ŃçļĦ +ĠP as +Ġachieve ment +ä¾Ľ ç͵ +Ġdem ocracy +-s ite +è¿Ļ 段 +# [ +游 æ³³ +D ict +Ġelder ly +], [@ +* \ +ç² ¤ +UN CTION +åľ¨ æĦı +ĠNet herlands +Ġ ---------------- +) _ +äºĭ çļĦ +æķ´ æĶ¹ +ĠP u +ment ed +Ġ .... +In vest +ang les +CP U +ĠTre nd +ĠJ u +éĵ ħ +Int eg +ç»Ŀ ç¼ĺ +Ġexcept ions +ï¼Į 竣 +ĠS ym +^ ^ +çħ ŀ +over nment +ç´§ å¯Ĩ +Ġconf idential +' > +ĠOr iginal +Ġvol umes +N EW +Ġ 该 +Ġmin eral +è´¢åĬ¡ æĬ¥è¡¨ +æĮ ª +ï¼Į 秦 +Res et +ĠD or +éĺ² èĮĥ +åĺ´ å·´ +, çͱ +ä½ ij +un ique +ir atory +=" $ +Ġt ours +äºĭ çī© +çĿĢ å¥¹ +Ġhand y +i per +模 æĿ¿ +Comm unity +Ġu pt +P arse +ãģ ķ +Ġat oms +ĠT oo +arn ings +çļĦ å¤ļ +Ġcritic ism +èĢģ 头 +éĨ Ľ +Ġfem ales +Ġfem in +åıª ä¼ļ +ï¼Įè¿Ļ æīį +Ġperform s +Ġn ick +ĠT ogether +åĴ ¯ +Ġex ec +-g o +æ³ » +ol er +Ġcomp iled +Ġâī ¤ +. default +羣 空 +å°ij çĪ· +Ġtim estamp +åķ ª +is ure +ĠAct ivity +l as +åŃĺ æ¬¾ +. be +åıį å°Ħ +ĠV M +æĿ¡ 款 +ip h +b ecause +> . +æķ° ç»Ħ +åIJ« ä¹ī +Ġcomp ression +[ key +éľ Ħ +Ġinsp iring +ĠWh it +åĬł 以 +å®ŀ è´¨ +C ross +" github +Ġhighlight ed +ĠT oken +Ġaccept ing +- value +Ġcoupl ing +æĹ¥ ä¸ĭåįĪ +åıij èµ· +ãĢĤ è¿Ļä¸Ģ +olester ol +ï¼Į è¿ĩ +Ġcontain ers +è¿ĺ 好 +Ġr ounds +( var +и Ñı +Ġrandom ly +Ġthrow ing +- way +åĨ· çļĦ +ĠCapt ain +ï¼Į éĩį +è¿Ļ 份 +Ġfig ured +ID S +ĠB alt +Ġst ays +α ι +Ġd ough +O ct +èĨ Ĭ +Ġbe ings +s App +Ġir re +ĠS ac +Ġ åĨį +ĠA qu +èĥĸ åŃIJ +ä¸Ń åįĪ +åIJĦ 级 +ĠS Y +pe ople +Ġpull ing +Ġmy th +éĥ½ å·²ç»ı +.com m +k appa +èĨ¨ èĥĢ +Ġpl t +Ġsp rint +t wo +触 æij¸ +æ¸Ĺ éĢı +{ M +ï¼Į çĽ¸ä¿¡ +Ġwild life +ä½ĵ éĩį +ong o +ĠB ol +对 äºĨ +_ queue +n one +. Log +è¿ĩ æĿ¥çļĦ +P aul +Ġdep loyment +ĠTrans fer +Ġover flow +æľºåĬ¨ 车 +z ens +Ġhere in +SS L +Ġappet ite +Ġaccording ly +Ġbroad er +ä¸Ģ èµ·æĿ¥ +/ en +X Y +Ġtour ism +Ġar med +Ġrel ates +Ġmar ine +çļĦ çī¹çĤ¹ +ĠS urg +ĠS afe +C OM +ell i +ĠUs ers +ä¹Ļ çĥ¯ +åľ¨ 她 +ãĢĭ åĴĮ +Ġpresident ial +ĠW ind +ĠCh i +Cont ents +Ġjust ify +Ġconscious ness +äºĨ 她 +ï¼Įè¦ģ æĺ¯ +ogene ous +ĠMe et +ĠPack age +As k +Ġw age +ĠP ages +ĠOper ations +Ġpre lim +( K +cd ots +V O +ph ant +ĠW indow +Ġ -------- +. o +rins ic +um ing +Ġquant ities +ï¼Į ä¸ĭéĿ¢ +Ġatt achment +ĠCol umn +Ġbott les +Ġfunction ing +Ġtr ash +Ġstri king +ä¸ ŀ +Ġpoly mer +Ġun a +Ġpath ways +Ġcitiz en +åħ¶ 次 +纳 åħ¥ +] ], +æł· æľ¬ +g ent +/ api +Ġal ike +Ġcon clusions +.t itle +Ġch lor +Ġw elfare +Ġt ire +Ġen emies +Cont ains +Un ited +ä¼ ½ +Ġsubt le +ĠL ux +èµ° çļĦ +qu et +è¿Ļ ç±» +å¸Į èħĬ +_b ytes +æµģ æ°´ +æĭħ å½ĵ +Ġextra ction +to String +[: , +ç¥ Ľ +åĨ³ è®® +ann ers +Ġst raw +æĸ° æĬĢæľ¯ +Ġmag ical +ĠS leep +ï¼Į åĿĩ +IC AL +Ġsu its +å®īè£ħ åľ¨ +ĠObject ive +=" _ +Ġâ Ĩ +y g +roll ers +Ġneigh bour +交 åıī +conom ic +åĩº èµĦ +伸 缩 +Ġend less +åĭŁéĽĨ èµĦéĩij +æľĭåıĭ 们 +.p ost +è¿Ľ çIJĥ +符 åı· +Ġdeterm ines +èħ¾ 讯 +her ited +st able +羡 æħķ +Ġelev ated +Ġv endor +L oop +è¯ ı +Ġbar riers +F eed +ï¼Įä½ł çļĦ +ac er +ock ets +çģ« ç®Ń +æ¶ ¡ +Ġgener ous +B ank +urs ive +ĠB attle +ĠP rior +é϶ çĵ· +Ġdri ed +Ġcap ac +çĽijçĿ£ 管çIJĨ +è´Ŀ å°Ķ +_ valid +çĥŃ çļĦ +- ups +çİ« çij° +Ġal igned +_T EST +æĹ¥ åĨħ +B ound +anc ies +ï¼Į æŃ£æĺ¯ +Ġc um +ĠFrank lin +[ x +ener gy +, [ +ä¸Ĭ ä¼ł +ĠS ummary +ï¸ ı +. Generic +_B IT +Sp an +å± ¡ +æĭĽ æłĩ +åĬł å¯Ĩ +_RE AD +天 使 +人 äºĨ +Ġhom ework +åī© ä¸ĭçļĦ +-w ide +- use +ä¹Ł å°Ĩ +äºĭåĬ¡ æīĢ +ç²¾ åĵģ +Ġbuild s +at tered +ĠA z +ĠN ik +æĽ¹ æĵį +Ġ] ; +Ġcorpor ations +å¼Ģ éŨ +ä»Ģä¹Ī çļĦ +æĸĩ æ¡£ +# ! +es ity +par ator +éģµ å¾ª +Ġsal ad +åIJĮæ¯Ķ å¢ŀéķ¿ +Ġrh yth +éĺµ å®¹ +é e +交 äºĴ +ï¼Į ä½ľèĢħ +p in +F our +说 åĩº +æ·±åľ³ å¸Ĥ +Ch ina +wit zer +Ġf ence +Ġ « +ç«ĭ ä½ĵ +åĶ ī +羣 缸 +è° İ +è¿IJ ç®Ĺ +åĭ ĭ +ĠH an +è¯ µ +éĶ ¥ +Ġdec iding +åĪij äºĭ +ä¸Ĭ å¸Ŀ +Ġn ov +éĻª ä¼´ +ï¼Į åºĶå½ĵ +Ġto y +缮 çļĦæĺ¯ +ĠDE FAULT +ï¼Į她 çļĦ +Post s +Ġadapt ed +缸 ç»ĵåIJĪ +ĠO w +anal ysis +d ed +p n +æĤ£èĢħ çļĦ +éĻĦ åĬł +Ġso ck +ĠT rain +Ġn erve +olog ically +ig ator +æĤ į +Ġass ured +Rem ember +èĮ¶ åı¶ +åŃĹ符 串 +Ġsust ained +Ag ent +ur ious +IC ATION +æī¶ è´« +èĥ ³ +Ġport s +hel lo +ĠL emma +å®īåħ¨ çĶŁäº§ +Ġ æį® +j ack +ç²¾ çģµ +Ġs ends +_t rain +Ġd ancing +人 éĹ´ +C N +Ġto ss +_T X +æĹģ çļĦ +F ac +ĠRes erve +Ġb ib +b oolean +åįĥ å¹´ +Ġdecl aration +Ġabund ance +åĭ ĺ +ï¼Į åĶIJ +Ġb ones +cp u +大 èĦij +ï¼Įåıª è§ģ +åºķ 座 +Ġh unt +ĠBel ow +ãĢĤ çݰ +Ġal location +Cons ider +b led +Ġshe d +Ġparticip ated +åĨį 度 +åıĤ çħ§ +for ced +E v +æIJŃ å»º +d one +Ġpresent ing +ï¼Į 带 +åĤ¨ å¤ĩ +at able +Ġprotocol s +Ġwhere ver +åĵ Ħ +æĿ¥ å¾Ĺ +ï¼Į åĩıå°ij +æ°Ķ 温 +Ġ ç͍ +Ġcons ume +ag u +çĶŁ çIJĨ +_T EXT +á n +Ġint rig +åŃ¦æł¡ çļĦ +Rem ote +åĵ ĩ +ĠP ref +w id +D istance +ĠC B +ãĢģ 对 +大 夫 +Ġsu icide +Ġm amm +便 æį· +' ( +Ġbatter ies +ĠMod ule +F I +Ġ" ( +P ersonal +ĠAssoci ate +W A +Ġre cess +Ġun fortunately +Ġc b +V A +Ġst ainless +çķĻ åѦ +D igital +çļĦ åħ¬åı¸ +ĠUt ah +Con verter +.f ile +豪 åįİ +大 äºĭ +ï¼Į 缸 +D river +Ġa u +down load +æĿ¡ä»¶ ä¸ĭ +. al +Ġrepeated ly +æĹ¥ åľ¨ +_ attr +user name +大 åĬĽ +Ġfast est +ĠCon nection +Sub ject +ĠT ut +-m ade +@ @ +ä½ł ä¸į +ch ant +è§ģ çļĦ +ather ine +et work +ĠEx amples +irc le +Ġadjust ment +_c olumn +ĠOver all +V S +ress ions +Ġa er +_C OMP +ï¼Įè¿Ļ ä¹Ī +te am +. ), +ra ining +ä½į çļĦ +Ġout fit +ठ¾ +æ½ľ åľ¨ +ä¼ļ åĩºçݰ +am ar +Cond ition +ĠT ab +OD ULE +Al loc +æĽĿ åħī +.m essage +ç®Ĺ äºĨ +ch anged +C ounter +å¤į ä¹ł +Ġadvert is +è¦ģ åľ¨ +reg ular +== = +Ġdo i +ä½łä»¬ çļĦ +ï¼Įåį´ æĺ¯ +cond s +èIJ į +åģ· åģ· +red ient +ĠMex ican +Ġphotograp her +_FL AG +Ġcon n +æĺ¥ 天 +Don ald +æľº éģĩ +æĴ ¼ +ĠH ERE +ä»ĵ åºĵ +el ay +Ġph ases +%%%%%%%% %%%%%%%% +æĹ¶ æľº +æ¥ ł +Ġs s +èĬĤ æĹ¥ +æİĪ äºĪ +ourn als +ï¼Į çŁ¥éģĵ +habilit ation +ĠS R +Ġc c +Vis ual +oth y +æ°Ķ æ°Ľ +æĭĽ åķĨ +\ leq +ĠForm at +ä¸Ģ åĬ¨ +m os +ä¸Ģ éģį +P y +Ġcompet ing +Ġc p +å¼ķèµ· çļĦ +sp ot +check ed +æł Ī +æ³ķå¾ĭ æ³ķè§Ħ +ĠGrow th +æļ ¨ +ä¸Ń æīĢ +ä¸Ģ åIJĮ +æ¹ Ľ +Ġa uction +Ġdistingu ish +ay ment +um ble +绿 åĮĸ +æİ¥ å¾ħ +j an +Ġm as +æŃ£ éĿ¢ +è¿IJ æ°Ķ +Ġsche mes +ĠCurrent ly +Int erest +Ġglass es +Â Ģ +çĶŁ èĤ² +ĠR ace +æĿ¿ ä¸Ĭ +ĠL ane +_s ession +Ġpro to +æ° Ł +ĠPrem ier +. Object +T emp +Ġmarket place +ĠN BA +ä¸ī 天 +o vers +ä¹ĭ å¿ĥ +res et +æ¤ İ +_ up +Book s +g oogle +Ġt une +Ġend e +_ rec +æ·± å¤Ħ +ï¼Į æĺ¾çĦ¶ +.d raw +ï¼Ľ æīĢè¿° +h ad +Ġexplain ing +渴 æľĽ +. of ++ " +客 æ°Ķ +-d epth +çŁ « +çļĦ èĬ± +ĠIn novation +ĠO pport +Ġdemonstr ates +ĠAn imal +Ġstrugg les +å·® åĪ« +åħ¨ éĥ½ +AR GET +åĤ¨ åŃĺ +ĠV ent +in ars +åIJĮ æľŁ +ãĢģ " +Ġcare ers +oll ar +Ġlog ged +ï¼Į åĮĹ +% ), +å¾Ī ä¸į +igh ters +Ġde leg +id el +M IN +. url +Ġ' _ +Ġke en +å¹´ åĪĿ +Am ount +Ġdisappoint ed +é« ĵ +% ; +ell ular +é£Ł æĿIJ +ï¼Į åĵªæĢķ +第äºĮ 次 +Ġroll ed +ç§» æ°ij +Ġj a +èĢģ å¹´ +ĠS creen +P resent +ĠP anel +C U +èĭı å·ŀ +c ss +Ġsecre ts +Ġtown s +Ġ åı¯æĺ¯ +å¾Ĺåΰ çļĦ +Ġ åĶIJ +ul k +M usic +\ r +su pp +Ġdis advant +åIJ © +pe red +大 éŨ +åįı åIJĮ +ä¼ł åªĴ +J ames +St ay +ãĢĤ å½ĵæĹ¶ +åĩł 个人 +Ġemerg ed +ä¸ĵ è¾ij +ides pread +Ġpers pectives +ress ing +( val +ĠBet ween +äºī è®® +Ġra bb +Ġgu ided +Ġpur ple +Ġv ig +åij¨ å¹´ +o ons +ul ly +çļĦ è´¨éĩı +Ġaud iences +ï¼Į åĽŀ +ç§ģ 人 +Ġcelebr ated +ĠF ly +_st ream +ĠG PS +-b lock +Ġtra its +ĠDe cl +-f amily +err ors +l ice +LO B +em ph +ä¸Ĭ 课 +èµ¢ å¾Ĺ +å®ŀ è¯Ŀ +D rop +竳 ç¨ĭ +ç͍ åĬĽ +Ġrem inder +æ°´ åĪĨ +Ġboot s +æijĺ è¦ģ +ç»ĺ çĶ» +ãĢĤ çİĭ +ç¦ Ħ +ĠF le +ãĥ » +ĠC ars +d est +çĦ¶ çļĦ +Ġsatisf ying +ç¼ĵ æħ¢ +æĮģ èĤ¡ +å®ŀ åľ° +ï¼Į 红 +As set +art ial +ãĢĤ æ¯ı +æĹ ± +æĪĺ èĥľ +Ġl ap +oc a +Ġc s +ä¹Ł éĥ½ +æķ ŀ +et erm +çļĦ åIJį +ĠW el +åĨħ å¤ĸ +r ases +ç¥ŀ å¥ĩ +ãĢģ äºĮ +{ t +Option al +ï¼ļ A +çĭ¬ èĩª +Ġthe ater +am on +Ġcl oth +Ġr ush +Ġconst itute +Ġh ug +,èĢĮ æĺ¯ +大 ç¬ij +æĮĩ åįĹ +.l ast +M apper +æ± Ŀ +Ġout let +(n p +Ġhaz ard +] )) +ĠHealth care +æ³ £ +)* (- +å¤ļ 人 +ĠD ur +ann ah +witzer land +åħ¬ å¼ı +" ]. +忽 è§Ĩ +èµ· çĤ¹ +身边 çļĦ +ĠV ert +ĠH yp +(m odel +ĠGirl s +W arning +x a +Ġcount ing +S ch +ĠSe pt +Ġcomp elling +è¾ĥ 大çļĦ +Ġstruct ured +ãĢģ çİĭ +Ġc ant +碰 åΰ +ãĢģ æĿİ +ĠPat tern +åı¥ åŃIJ +port ed +Ġcon vention +GB T +éģĹ ä¼ł +. for +ĠT IM +ipp i +es ian +å¾Ĺ ä¸Ĭ +æĵħ éķ¿ +, ä¸įè¦ģ +qu arters +p ed +ĠMe chan +Ġimag ination +. or +æıIJ åĩºçļĦ +EN ER +Ġapprox imation +ï¼Į åı« +ä»ĭç»į äºĨ +è¿ŀ éĢļ +åħ¬å®ī å±Ģ +åİĨåı² ä¸Ĭ +éĴ¥ åĮĻ +Ġswitch ing +çĥŃ çα +èįī åİŁ +{eq n +Ġdi ver +ĠMaterial s +, âĢľ +ĠF ant +ĠThanks giving +æĹł åı¯ +ä¿¡æģ¯ åĮĸ +\ { +å¡« åĨĻ +Process or +å±± çļĦ +ä¸Ģ åı¥è¯Ŀ +Ġwat ches +ĠL abel +ĠD ick +å¥ī çĮ® +he ets +ern et +åĤ¬ åĮĸ +åĮħ 裹 +ark er +F inal +æİ¥ ç§į +ãĢĤ åıĪ +Ġaggreg ate +ä¹ĭ 为 +ble ms +åĽŃ æŀĹ +ĠGet ting +at om +çѾ 约 +Ġs its +Ġmod ifications +ä¸į æĺĵ +iss ue +Ġr s +æĸ° çĶŁ +åı£ æĦŁ +Ġpass enger +ç¯ĩ æĸĩ竳 +æĥ³ çļĦ +Ġexpl ored +ĠD rop +ol itan +åĶ® åIJİ +Ġref use +B ay +æľī ä¸ĢäºĽ +Th ursday +ĠG B +ĠD river +æĹł æīĢ +å¯Į æľī +li est +te in +or ious +ĠHow ard +plug ins +Ġte aches +Ġpolit icians +ident ifier +/ pro +Ġf ancy +Ġobst acles +èİ· å¥ĸ +æĻ®éĢļ çļĦ +][ " +ĠL in +Execut ion +äºĨ ä¸ĭ +ĠB uilder +Pro ps +umn i +Ġep it +ĠEmp ire +Ġm elt +对 éĿ¢ +ĠM atch +ĠCoun sel +ï¼Į 身ä½ĵ +,ä»İ èĢĮ +ur ring +ours es +R untime +-s ide +V EL +åīį æıIJ +om ing +Ġbi ology +ĠW edding +nab la +Ġ( (( +ĠIn clude +身 å½± +æĬ¥åijĬ æľŁåĨħ +Ġapp ar +æĺ¯ ä¸ŃåĽ½ +à ¯ +B Y +_s ource +约 æĿŁ +B ad +ĠT ags +Arch ives +åı¯ä»¥ ç͍ +ĠBel g +Ġstream s +ab i +åİĤ åķĨ +_p ost +Ġprospect s +ç«ŀ æĬĢ +( os +Ġglob ally +éľ Ĩ +çļĦå¿ĥ æĥħ +Ġpropos als +-b utton +Ġar row +Ġback ed +ç²¾ èĭ± +ĠEx cel +Ġ ê +éĥ Ŀ +没 åĬŀæ³ķ +Ġdepend ence +ox ic +v et +ĠF O +åħ¬ æĸ¤ +ĠRev olution +æ³ķ çļĦ +am ents +ĠF ont +. IO +ĠB ot +iov ascular +ĠAnt i +Ġsymmet ry +param eter +Ġabs ent +ĠGal axy +ĠWalk er +Ġrec overed +I ENT +, T +ĠMar ine +-s ized +lic al +Ġrecip ient +å᧠室 +è±Ĩ èħIJ +ï¼Į 顺 +Ġshel f +_ ctx +æİĴ åºı +Ġsynt hetic +ĠP ool +çĥ ģ +ä¸į çĿĢ +说 ä»ĸ +Ġval ve +IS H +, ( +Ġbes ides +Ġpe ers +å¨ ħ +f its +D ER +> (" +åħĭ æľį +Ġver ification +Ġprof ound +@ end +i ere +å¤įæĿĤ çļĦ +ĠT emplate +ĠPh ill +ï¼Į 建ç«ĭ +ĠH it +Ġtra uma +ï¼Įåıį æŃ£ +. op +Ps i +ĠJ oy +èĻ ŀ +ract ed +Sc ene +Ġtyp edef +åľ¨ æľ¬ +å§¿ æĢģ +ens ively +Ġl ig +ä¸Ģ æĹ¥ +çļĦ ç¬ij +_ response +èijĹ åIJį +ĠM erc +ĠK EY +æĹĹ ä¸ĭ +ĠJ S += true +-w inning +ï¼Į 带çĿĢ +. arg +çα ä½ł +_h andler +ï¼Į å¿ħ +Ġ" ' +ï¼Į éĿ¢ +Ġmax im +Ġsim ilarly +Ġvari ants +Ġmass es +ĠBow l +ç«ŀäºī åĬĽ +ĠM ars +ç¼ĵ åĨ² +åĻ ¬ +ä¸Ģ ä¼ļ +Ġassoci ations +æµİ åįĹ +Ġz oom +æīĭ ä¸ĭ +èĢĥ éªĮ +S ound +ĠG all +Ġen jo +åĹ ½ +Ġart istic +Ġf itted +] ^ +_ ad +Ġcust ody +ĠInd ividual +éĩĮ æĸ¯ +Ġc er +Ġc ement +Ġp iano +Ġper pet +Th us +Ġw ard +ç¦ ½ +Ġbar rel +æī© å¼ł +Ġdownload ed +Ġsit uated +w alk +æł¸ éħ¸ +DE BUG +qu ote +第ä¸ī æĸ¹ +.p op +W ow +Ġinvest ed +颤 æĬĸ +ĠMar ia +Ġsurve ys +ĠDe an +_ enc +å½ ¬ +ï¼Į èϽ +ä¸Ń èᝠ+æıIJé«ĺ äºĨ +åĽĽ åįģ +Ġsystem atic +说 ä½ł +ï¼Į éĻĨ +ĠL ater +b tn +roph y +Ġinstall ing +ĠTur k +ĠDen ver +è¿İ æİ¥ +ien e +ĠCh rome +With out +il ateral +Ġe uro +P rom +Ġmethod ology +in ion +Ġhand ed +çļĦ 管çIJĨ +M esh +æī¿ åĮħ +Ġret ro +ump y +ĠBeaut y +_ form +Ġindu ction +ĠDI Y +Ġpul se +äºĨè§£ åΰ +. Equal +F oot +åĬł æĭ¿ +_ order +åı£ èħĶ +_sh ape +ER VER +Ġpub lisher +å¿ħé¡» è¦ģ +Ġthere of +ã İ +ĠIsrael i +Ġcom ic +èĪ Ĩ +ĠW orth +Ġsubstr ate +avel ength +ĠPhys ics +大家 éĥ½ +çĬ¹ å¦Ĥ +éķ¿ å¤§ +åľ° éľĩ +е л +Ġr ic +im on +{ s +Ġb ay +Ġfre ely +Ġfund ra +Inst agram +Ġsc aling +èĥ³ èĨĬ +p ond +åĭ º +ĠCam era +çļĦ 头 +Ġdev oted +Ġpen et +_S C +Ġagric ulture +Ġtow er +act ors +Ġp as +ĠR d +select or +ï¼Ī ä¸Ģ +G old +e as +å¼Ģ 设 +Ġd ense +Ġland sc +m aking +ĠB u +ĠRep orts +V irtual +Ġcor ruption +ĠG rid +mon th +ãĢĤ å°Ĩ +Ġ? ? +Ġconflic ts +is an +( [] +con sc +Menu Item +åĮĨ åĮĨ +ç͍ æ°´ +ĠSpring s +ç§ijåѦ å®¶ +åij¨ æľ« +(f loat +ĠB ull +Ġport ray +éĽĨåĽ¢ æľīéĻIJåħ¬åı¸ +Ġs ib +Ġillust rated +Ġaccess ed +, æ¯ı +æľī åºı +æĥ³ è¿ĩ +ï¼Į ç¾İ +R a +äº ¨ +é¢ij ç¹ģ +润 æ»ij +Ġt ies +Ġshel ter +Ġt ale +å¤ļå°ij éĴ± +C ursor +-t ext +Ġa ux +æľª èĥ½ +ĠLoad ing +Ġrem embered +act ual +æ¾³ 大åĪ© +Ġint end +åĹ ĵ +TR L +Ġrelax ed +Ġh i +_f n +Ġin clusive +Ġcol ored +Ġcred entials +ic ting +çļĦ çľ¼çĿĽ +Ġcl one +ĠT ouch +Ġp icks +ĠCal endar +Ġoccur ring +Ġvis a +çľ¼ åħī +è´¯ ç©¿ +ĠS pect +ï¼Į åı¦å¤ĸ +Ġin cons +^ + +-w orld +Ġ çľĭçĿĢ +tain ing +ä¹IJ è§Ĥ +Ġun iqu +Ġimpro ves +C ong +åįģ åŃĹ +ĠG re +cont ents +ac hers +Ġtoler ance +ĠH andle +A lex +ĠO FF +è¾ĥ å¤ļ +ograph ical +Ġmax imize +è·ij åΰ +ä¸į åıĹ +Ġstat utory +Ġentertain ing +åħ» çĶŁ +_s ign +è¿Ŀ è§Ħ +Ġtw elve +Ġmother s +人åĬĽ èµĦæºIJ +om it +ĠF DA +æĿIJæĸĻ çļĦ +ĠS witch +æĻ¯ çĤ¹ +________________ ________________ +èĩªæ²» åĮº +çĩĥ æĸĻ +Ġbless ed +ĠKent ucky +ĠR ank +çıį æĥľ +澳大åĪ© äºļ +Ġp ants +ĠFranc is +x s +éĤ£ 天 +oc he +Ġmagn et +Ġestim ation +rit es +åįĥ éĩĮ +大 éĺŁ +IC S +EO F +åĽĽ å¹´ +举 京 +_ thread +ĠCo ach +Ġco aches +ĠDirect ory +ĠB rew +æĴ ĩ +Not Found +Ġind ividually +æģ į +Method s +Ġdis put +ï¼ĮæīĢè¿° 第ä¸Ģ +ï¼ Ĵ +Ġsusp ended +Act iv +bb ed +ĠDet roit +åĽ½ 产 +rit ers +éĹ® æĪij +Ġam id +Ġbound ed +Ġ çĦ¶åIJİ +Ġstrength s +T ri +åIJİ æŀľ +B G +æĺ¯ è¿Ļæł· +Ġsix th +Ġinter ventions +ot or +ĠUn like +Ġd ur +An notation +Ġ ä¸ĩ +对 æĬĹ +Trans fer +ä¸Ń æľĢ +he ld +Ġorgan izational +Ġstra ins +out heast +Ġcru ise +ĠS ustain +ä¸į åĪ© +ĠOpt im +çĮľ æµĭ +Det ail +Ġret rieve +Ġspect acular +强 åĬ¿ +çļĦ çľ¼ç¥ŀ +A f +æĸ° çĸĨ +EN C +ĠS U +æĶ¾ åΰ +Ġl ambda +Off ice +ä¸Ģ å¥Ĺ +Ġc ous +em ale +çļĦ åIJįåŃĹ +Ġch arts +Ġint im +ä¸ĵ ç§ij +é²ľ è¡Ģ +ĠW ant +Ġlaw suit +_l oss +b rew +ĠF M +Ġgrad uated +Ġveter an +导 ä½ĵ +ĠG ib +d eg +ç¨İ æĶ¶ +Ġisol ation +ĠB rid +c out +lim it +Ġpo ison +Ġindic ators +ĠNet flix +ĠS in +åīį æĸ¹ +å̼ çļĦ +çŀ ³ +ï¼Į èIJ§ +UPD ATE +S aturday +sh ore +c am +. android +Ġrecruit ment +Ġmetabol ism +éĢĤ å®ľ +param eters +ĠA CC +åľ¨ éĤ£éĩĮ +Ġvess els +i u +Ġblock ing +æ°Ķ 象 +缺 å°ij +" }, +Con n +ĠA zure +æį Ĥ +- foot +rel ation +ĠOk lahoma +æĿ ī +Ġal le +çİĭ çĪ· +od a +at ility +Ñģ к +. input +-l abel +æ¿Ģ çĥĪ +pt s +éĺ´ éĺ³ +ign ore +Ind ent +Ġin hab +Ġconst ants +Ġconduct ing +Ġb ases +äºĨ èĩªå·± +ĠF ish +åŁºç¡Ģ ä¸Ĭ +主 å¼ł +åIJ© åĴIJ +ãĢģ 第äºĮ +Ġclaim ing +-t est +å¸ § +èĦ¸ ä¸ĬçļĦ +åįķ è¯į +ĠMedic are +约 ç¿° +Ġg low +èŀº æĹĭ +ãĢĭï¼Į ãĢĬ +C amera +âĢĻ ï¼Į +Ġsupport ive +ro ck +Ġretail ers +Ġass ay +Str ategy +. On +ĠT ell +Ġcomp ile +Ġnic ely +Ġch urches +åĪĨ å¼Ģ +认 åIJĮ +è¶ ´ +Ġm urd +ï¼Įä½Ĩ åľ¨ +ä¸Ģ èĤ¡ +Ġseem ingly +è§£ 读 +ĠMc G +Ġp iv +Ġat omic +Ġalloc ated +ĠK al +.A ss +çļĦ 空éĹ´ +ç§ij 缮 +Ġinc idence +C lear +ä¹IJ è¶£ +ä¹ħ çļĦ +Ġabs orption +net work +_ EXT +A mazon +Ġl ang +Ġ 好 +ï¼Į åĩĨå¤ĩ +ĠRober ts +Ġemb arrass +om ed +ä¸Ģ 座 +è° £ +媳 å¦ĩ +è¿ĩ å¤ļ +ãĤ ¯ +Ġpo em +Ġremind ed +unk nown +Follow ing +æĹ© é¤IJ +inn ed +åı£ çļĦ +ĠD un +Ġ è¿Ļæĺ¯ +Ext ra +Ġany time +ĠH ero +art icles +åĥı ç´ł +ĠV ac +Ġb ol +æĢİ æł·çļĦ +G TH +e ach +ĠPhilipp ines +.b ody +}} ( +ĠS F +交 å¾Ģ +duct ive +o is +Ï Ĩ +- user +ov iet +ãģ ı +Ġrend ered +ĠASS ERT +ĠShe l +/s rc +ST EM +å̾ åIJij +im ental +æľĢåIJİ çļĦ +UFF ER +æīĢ è¯´çļĦ +List en +人们 çļĦ +ï¼Į å¤ı +æķ£ åıij +åķĨ åľº +Ġin box +IS O +ä¾§ éĿ¢ +IC ES +Ġp t +Ġhand ful +æĬĬ ä½ł +éĥij å·ŀ +_ [ +uff ix +Ġden y +Ġ æŃ£ +æ¸ħ åįķ +Ġgl ory +ï¼Į å¾Īå¿« +ĉĉĉĉ ĉĉĉĉĉ +ew orks +车 ä¸Ĭ +ï¼Įè¿ĺ åı¯ä»¥ +ĠMc K +å° § +Ġproceed ing +ĠâĪ ļ +Ġdark ness +Ġind ication +Mon th +ï¼Į 许å¤ļ +, åıªæĺ¯ +Ġanticip ated +è£ ¸ +Ġpe pt +d og +åİ» éϤ +Ġtable ts +ĠR F +or us +æķ Ľ +Ġex tern +Ġcir cles +Ġman if +I ss +è¾ī çħĮ +M obile +ï¼Įä¹Ł 没æľī +ï¼Į让 人 +Ġbas ics +éĽ ģ +_h ost +Ġdes ires +- def +ĠEn able +_US ER +èĬ± è´¹ +è¿ Ń +ric ks +Ġli able +å² ļ +ov en +S ame +h ill +ex per +B ottom +ï¼Į åĬłå¼º +æĥħ æĬ¥ +Ġbonus es +So ftware +ĠG ram +Ġb ite +Ġcl im +é¢ Ĭ +Ġr uled +sc opy +Ġin quiry +Ġblog ging +çļĦ æµ· +/ æĪĸ +ire ments +Ġ é»Ħ +åĩ» è´¥ +Comp are +Ġcons ensus +æľī æľºä¼ļ +/ W +Ġmathemat ics +çİ© åħ· +çĶŁ æŃ» +åľº åIJĪ +ĠL iver +Ġmain stream +ud ge +les h +Ġspecific ations +. File +Ġrest oration +Ġres istant +x b +w atch +Educ ation +Ġexist ed +\ ": +( W +Ġspect ral +_DE FAULT +A ff +Ġl azy +Ġc rown +ĠMan ual +åıĶ åıĶ +t ry +dis c +大 èĩ£ +Ġan th +Ġprelim inary +åįı ä½ľ +_ alloc +Ġst olen +è¯ŀ çĶŁ +ĠIn sp +æ· ij +(n um +Qu ant +å§Ĩ æĸ¯ +çĤ « +ro log +èѦ åijĬ +ĠConfig uration +N ever +ĠTest ing +Ġinvest or +com ponent +ock s +Ġsus cept +Ġdev ast +Ġinteg ers +éĽ ¯ +Å Ł +Ġint ro +åľ° éģĵ +Ġbr ick +Ġleg ally +add ed +æľĢ æĹ© +pos ite +ĠD ATA +ä¾µ æĿĥ +we alth +Ġac res +ãĢĤ 尽管 +ĠCons umer +p iece +ä¸Ĭ 线 +ĠE S +Ġworth y +Ġf atal +ĠA WS +Ġprior ities +_fl ag +h ou +æĪĸèĢħ æĺ¯ +ĠP il +Ġtrad itions +åĩº åľº +æĬ¥ ä»· +Ġthe atre +太 大 +Ġdist inction +M o +ä¸į åłª +ä¸Ģ个 个 +ik ed +level and +n an +Ġprint s +> " +j or +p refix +Ġs lope +Ġstri ve +c fg +ç» ½ +ĠB ron +ãĢĤ åıª +ĠR AM +Anal ysis +ĠCOPY RIGHT +ment ation +aus es +Ġw ound +Ġl obby +Ġw idespread +读 åıĸ +Ġ åıĤèĢĥ +. View +Ġte asp +åĭī 强 +B ounds +Ġbul let +Ġspeed s +ï¼Į çĶ· +mod els +çļĦé«ĺ 度 +å¿ĥ ä¸ŃçļĦ +Ġsqu ad +D irection +Ġam ino +ä½İ 头 +å¹² èĦĨ +åĬĽ æ°Ķ +Ġ åIJĪ计 +.j unit +ãĢģ 社ä¼ļ +Ġs urre +主 æĦı +( output +Ġgro cery +æĭī æĸ¯ +ĠTe a +åĻ ¼ +ĠMet al +Ġam end +Ġd ressed +æŁĶ 软 +Ġgener ates +ĠDef ine +f mt +åĿIJ ä¸ĭ +Ġjack et +Const raint +qu al +é» Ľ +i em +çİĭ åŃIJ +Ġcondition ing +ï¼Į çī¹åĪ« +ãĢĤ åĽł +è¡Į èµ° +B inary +Ġprivile ge +ĠAn ne +常 ç͍ +å§Ķ å±Ī +éĤ£ ä½į +ï¼Įå°± è¿ŀ +æĹ¶ä»£ çļĦ +in x +ĠTr ading +sc r +ä¼ĺ èī¯ +ict ions +ãĢĤ ä¸Ń +ĠB uck +Ġtruck s +ĠJ en +K now +ĠL eb +æĭį åįĸ +) }{ +/c ore +Ġan chor +çľĭ è¿ĩ +åIJ ģ +Ġsufficient ly +im ore +ãģ į +ĠM ORE +Ġkid ney +ard less +er on +Ġout doors +Ġd y +åį³ ä¾¿ +å®Įæķ´ çļĦ +gg reg +T uesday +Ġequ als +ï¼Į ç¡®å®ļ +å¸Ī çζ +Ġl ately +ut ed +sk y +Ġexc ell +p d +TE GER +ä¼ļ 对 +ãĢģ éĩij +W ant +ãĢĭ ( +iss ippi +con duct +Ġlog s +äºĭä¸ļ åįķä½į +Ġcomp iler +æķĻ è®Ń +è¾ĸ åĮº +r ang +P red +çļĦ é¦ĸ +and al +ĠFA Q +Ġcalc ium +Ġsup ra +Ġ' " +p us +ĠR ing +C s +ĠèĢĮ ä¸Ķ +l ated +Ġwarm ing +Ġ çŃī +Ġdecl ined +ĠF urn +Ġth rew +Ġgovern ance +åĴ³ åĹ½ +æĬ¥ 纸 +Ġlic enses +è¯ģ å®ŀ +便 äºİ +æĹ¥ çĽĬ +Ã Ł +ĠSy ria +çŁ¥è¯Ĩ 产æĿĥ +åĮº åĿĹ +å°Ķ æĸ¯ +ä½ĵ æ£Ģ +âĢ ĥ +Ġswe ep +被 称为 +.M essage +éĶ Ĥ +augh ters +Ġconsult ant +Ġexp end +çĹķ 迹 +_ ep +Ġcompan ion +_P ORT +Ġcounter part +_ -> +. web +ĠSo ft +Ġoffer ings +S ide +.b ind +Ġsac rifice +ĠR ent +Ġm asks +Ġun limited +ç½ij 页 +Ġas h +éĶĢ åķĨ +Ġm akers +do i +è§Ħ 磩 +ä¸Ģ æī¹ +å± ¯ +ac ión +Ġwitness es +ï¼Įä¸Ģå®ļ è¦ģ +温 åĴĮ +ract or +èģļ çĦ¦ +éķ¿ å¾Ĺ +ĠE ve +Ġtransl ated +Ġtremend ous +Ġview ers +ĠP red +çϽ 天 +Ġt iles +ition ers +ĠLet ter +Pr imary +Ġneur ons +Ġgraph s +³³³³ ³³³³ +çļĦ éģĵ +æ¡Į åŃIJ +read er +Ġf ought +çģ ¶ +ĠSt ack +åIJī æŀĹ +å¼Ģå§ĭ äºĨ +-p erson +.g roup +ĠLess er +comfort able +Ġdivis or +åĪĿ æľŁ +èĩªè¡Į 车 +ĠS UB +åĢ © +æ½ľ åĬĽ +èĽ Ľ +Ġa apt +Ġ( + +Ġpartners hips +, åĪĻ +LO AD +ĠW y +- radius +ĠEx pl +ä»· æ¯Ķ +.p arent +, åĴĮ +Ġ çĦ¶èĢĮ +Ġpot atoes +еР´ +èᣠèĢĢ +åħ» æĪIJ +Ġc ater +ĠW ine +t m +Ġdim in +( char +çļĦåīį æıIJ +Trans port +{ g +为 ä¾ĭ +ãģ Ĥ +Ġd type +Ġtra ject +Ġf el +Ch art +Ġlit igation +Ġas p +ä¼ļ计 å¸Ī +Ġa pt +Ġsu ck +ãĢĤ æŃ£ +æĩ Ī +AL E +ic ut +Ġtit led +满 满 +ĠC ole +C amp +éģŃ åΰ +æľī è¿ĩ +Ġpreval ence +ĠMalays ia +ĠF iles +Ġdisag ree +缴 线 +对 ä¸įèµ· +ãĢĤ 请 +ï¼Į å¾ħ +B reak +Ġret ention +ĠSimp ly +Ġconnect ivity +æīĺ 管 +ä¿® 士 +çļĦ æ²»çĸĹ +he nd +Ġabandon ed +Ġacc idents +çł´ ç¢İ +Ġexpect ation +Ġdev iation +B i +ãĢĤ ç͍ +ĠRe ason +Ġ\ { +N ative +ĠLo an +æİĴ åĪĹ +ä¸Ģ ä¸Ģ +Ġsurv iv +Ġst iff +Ġact ress +Q Q +åĩł ç§į +å¤ľ æĻļ +Ġcancell ation +Ġste pped +ou p +åª Ľ +è° ľ +Ġstory t +_b it +.P rint +ang a +ĠS weet +æ¯Ķ äºļ +Ġg it +ĠH ousing +Ġâī ¥ +ĠPay ment +ĠChair man +æĺ¾ çĿĢ +åIJij çĿĢ +Ġap olog +Ġnut rients +Ġoverse as +奶 èĮ¶ +ï¼Įå°± åı¯ä»¥ +k b +ĠAl ong +çŀ İ +éĺ¶ çº§ +ĠY OUR +èģĮ èĥ½ +str ument +_d esc +å¤ĩ æ¡Ī + ² +èŀº æłĵ +Ġinstitut ional +ad ays +èĢģå¸Ī çļĦ +Ġconsider ations +. event +åħī èĬĴ +å¥ ł +æĺ¨ æĹ¥ +VI EW +Ġpres cribed +op ing +产 çī© +ä½ı åľ¨ +ä»Ĭ天 çļĦ +å°±æĺ¯ ä¸Ģ个 +ow ers +è¿İ æĿ¥ +è¿ĩåİ» çļĦ +å͝ä¸Ģ çļĦ +ĠNe uro +ogen esis +Ġs ons +w ick +ĠS chedule +keep ing +_ json +å°± ä¸įä¼ļ +åķĨ éĩı +ä¸Ģ æĸ¹ +.get Name +Ġbu gs +Ġsubst ances +ĠDel ivery +éľĩ èį¡ +igh bor +- est +Ġflo oring +ĠA w +Ġmon etary +Ġess ence +Ġdocument ed +Ġcor ners +æĬ± æĢ¨ +Ġend l +强 çĥĪçļĦ +ĠC ape +Ġqu oted +åij½ çļĦ +å¯ ŀ +ä¹Ł çŁ¥éģĵ +äºĨ 大 +çģ« éĶħ +(d ev +ed e +æī¿ è½½ +Ġintrodu cing +ï¼Į éĺ²æŃ¢ +bl ank +var iant +Ġle verage +, åıªæľī +殿 ä¸ĭ +p ages +ĠPro s +å½ĵäºĭ 人 +Ġswe at +ãĢĤ è¿ĻéĩĮ +Ġreg ulated +Ġincre ment +Ġsw ift +æĿĢ æŃ» +Ġphys icians +Ġshould ers +ĠPr imary +Ġmanufact ured +D at +Ġde com +ï¼Į 女 +Ġsc rap +Ġcon form +ĠG T +Ġapprec iation +\ rangle +ç«Ļ èµ·æĿ¥ +Ġtrans parency +olog ic +ĠS ample +åįģ 大 +m akers +Ġrot ate +Ġvoc al +âĢľ å°ı +ĠThom pson +OW ER +he ro +æ·± åĮĸ +Ġlim iting +Ġgovern or +ĠGree ce +let ters +R N +å®Į ç¾İçļĦ +ĠCon vention +Ġc iv +ç͵åŃIJ åķĨåĬ¡ +Load ing +W ednesday +å±±ä¸ľ çľģ +ĠPhot ography +_ iter +em n +åĪĨ 辨 +.To String +Ġr anks +it ual +lis hers +acc ur +P ing +Ġeval uating +ir ical +, åı¯æĺ¯ +s ample +ĠCast le +èᣠèİ· +C lean +ĠZ one +åĸĦ èī¯ +ĠU pon +âĢľ ä¸į +Ġdon ations +æīĭ èĩĤ +all ing +ä¸İ åħ¶ +en o +ãĢģ å¤ĸ +Ġsc ared +ç±³ çļĦ +ra ham +ĠF lo +Ġo z +ĠCor porate +ãĢĤ åıªæĺ¯ +Ġentreprene urs +Ġval ued +åķ ¤ +âĢĶ the +Ġart work +ĠC her +hel ial +ï¼Į 飩 +ĠCy ber +Ġar ising +Ġâ Ĭ +ãĢĤ èĩ³äºİ +eren ced +Ġcomb ining +Ġst ones +Ġpre vents +est y +Ġfrequ encies +comm end +ç¿ ĺ +Us ed +ĠOper ation +æĪij åİ» +} ] +Ġm ush +Ġann ually +ĠLu ke +App le +Ġfavor ites +ĠBe at +Ġb er +Sun day +æł Ĺ +å·²ç»ı åľ¨ +çĶŁäº§ çļĦ +Ġg ently +Ġorgan ize +ç¾İ 人 +Ġl in +ab ri +ĠPhys ical +Ġking dom +D ear +æŃ¤ åīį +Ġantib ody +ĠS ERV +ĠG it +Ġne at +AD D +Ġsqu ee +æĮ¯ åĬ¨ +Ġvar ieties +Ġresp iratory +Ġd rew +Ġbeautiful ly +ĠH omes +ĠN az +Ġb icy +ur pose +æĬ¤ 士 +ä¸Ģ é¡¿ +æł ĸ +æĥ³ ä¸įåΰ +Ġ éĻĨ +.f l +Ġquant itative +æĹ¶éĹ´ åĨħ +æ³ķ 人 +pro to +Ġe arning +ĠD elta +.g nu +Ġd s +Ġ> & +碰 æĴŀ +Ġp i +Ġtrans it +ĠRe ally +? ! +款 项 +çªĹ æĪ· +ĠF T +ÃŃ a +Ġtour ist +ĠGr ade +H H +ENT RY +> * +åĨį çĶŁ +ãİ ¡ +ĠH i +å½± åĥı +For ce +Ġbrief ly +ç͵ 容 +ĠP B + ¸ +al let +Ġst ating +B uff +{ m +å¤į åį° +C orn +ĠIss ues +un ion +Ï į +Ġfac ial +Ġdecre ases +[ string +Ġchalleng ed +ĠS ony +ĠIndones ia +Al pha +ĠBut ton +ĠPro duction +æħ¢æħ¢ çļĦ +Ġassign ments +P oly +åįķ ä¸Ģ +游æĪı ä¸Ń +IB UT +æĹ¨ åľ¨ +ĠD omin +Ġf oo +ć Ĉ +ç®Ĭ çļĦ +æŃĮ æīĭ +Ġle ver +乡 éķĩ +ĠRem ote +讲 ç©¶ +j ob +ĠR V +åħ³ç³» çļĦ +Ġtax p +& gt +ĠPart ner +Ġcompr ises +Ġjun ior +Ġcreat ures +ĠÐ ± +ĠCom ponent +æ¶µ çĽĸ +Ġ Ä +ĠComm ons +Ġupd ating +m ma +æļ ® +âĢľ 大 +ĠEnt ry +ï¼Į 建议 +主 åľº +P od +Ġcross ing +oci ated +Ġel astic +ĠÎ ¸ +Ġcoll ision +æŃ¤ äºĭ +Ġinform ative +Ġbel oved +客æĪ· çļĦ +ä¸Ģ 对 +å§¿ åĬ¿ +ĠW A +Ġlink ing +Ġad hes +Ġtw ist +Be ing +Ġpsych ology +Ġappe als +Ex plore +æ¡ĥ èĬ± +管çIJĨ çļĦ +Ġeffic acy +op les +åįı åķĨ +App ly +{ k +ĠV in +B ind +Ġtem ple +çĶĺ èĤĥ +Ġ: - +P AR +l ack +abul ary +, r +æĬĢæľ¯ é¢ĨåŁŁ +ĠEnt ity +vis it +Ġb ron +.f ilter +Ġgr asp +ç¾İ è§Ĥ +è¯Ĺ æŃĮ +ĠPhot os +S chool +Ġt id +Ġvalid ity +Ġreview ing +Ġjud ges +Ġscholar ship +çĽij ä¼ļ +Ġs isters +C reated +Ġal tered +\ cdot +Ġab ortion +, 人 +_DEV ICE +欺 è´Ł +Ġvar ies +æijĨ èĦ± +å¾Ĺ åĩº +å«Į çĸij +è´ © +Ġalleg ations +ï¼Įå¹¶ å°Ĩ +i ar +ĠK ate +=" / +æı ½ +ert ation +ĠCon sole +Ġcol leges +çĮ Ľ +End point +ãĥ¼ ãĥ +Ï ĩ +itut ed +Ġlegisl ative +åĿı äºĨ +_AD DR +Ġmusic ians +ï¼Į 令 +Ġcomb ines +z eta +Ġam er +å®Ĺ æĹ¨ +Ġwarn ed +è¿ĩ æķı +} | +ĠW R +ï¼Įä½ł åı¯ä»¥ +ĠF resh +æ·ĺ æ±° +.t arget +ĠN ash +ĠS audi +Ġclar ity +ï¼Į ç»Ŀ对 +åıĹ çĽĬ +quir ies +大 åĨĽ +ι κ +Ġsurve illance +Ġappar atus +Ġbrow se +k dir +Ġcontract ors +ï¼Į éĢļ常 +ç¥ŀ çļĦ +ĠHar vard +ĠAn na +ãĥ ĥ +ĠPalest in +. Property +Ġb ust +PE G +Ġd ated +åı¯ çŁ¥ +d it +Ġtong ue +\ / +æĺ¯ 羣çļĦ +ä¼ º +åĨħ容 çļĦ +Ġfl aw +Ġavoid ing +Or iginal +ĠOther s +ĠD ak +ä¸įæĸŃ åľ° +load ed +Ġ第 äºĶ +ãĢģ æµ· +ĠS ab +æĪIJ åĵģ +ĠD ry +票 æį® +Ġoppon ent +ï¼Į ä¹ĭåIJİ +ĠPro blem +å·´ 西 +Ġflu ores +P ages +Ġdocument ary +ĠS omething +, ä¸Ń +Ġcourt esy +çļĦ çϽ +Ġadv ances +Sh ader +. options +% 以ä¸Ĭ +Ġcross ed +伦 æķ¦ +ï¼Į ä»Ĭå¹´ +M AP +ĠK y +ĠM as +ro st +R ound +ç³ĸ å°¿ +æĦī å¿« +.S h +ĠL ength +åľ° éĿ¢ç§¯ +_t he +Ġmechan ics +ĠE aster +Ġal ien +ä¿¡æģ¯ çļĦ +å¤ĸ çķĮ +åĨľ æĪ· +äºĨ åĩºåİ» +Ġad oles +Ġcount less +ä¸Ĭ éĿ¢çļĦ +ï¼Į æĦŁè§ī +Ġhar sh +ãĢģ åī¯ +æľį ç͍ +gl as +Ġanal ytical +/ { +Im g +æī© æķ£ +Ġgirl friend +åĨ Ī +ï¼Į ç½Ĺ +缸 æľº +Ġliter ary +ç»ĵ å±Ģ +èĸ ¯ +èĥ½åĬĽ çļĦ +lo v +å̾ æĸľ +St rip +Ġex ports +ĠAl t +Ġt ennis +ï¼ŁâĢĿ âĢľ +å¼Ģ æĭĵ +Ġlong est +çģ« çģ¾ +_ IT +éĨĴ æĿ¥ +äºĨ ä»ĸçļĦ +ÃĹ ÃĹ +æ¸ħ æ°´ +æĢª çī© +Ġtou ched +ber ries +æĬĢæľ¯ æĸ¹æ¡Ī +ĠRes ort +O IN +Ù ģ +åĢ ¦ +å½ĵ ä¸ĭ +éģĹ äº§ +éĴ± çļĦ +Ġan not +ant ry +ĠV e +Ġrelax ing +ä¾Ŀ æīĺ +ä¸į ç®Ĺ +Ġsimpl er +Ġdes criptions +ĠC old +ĠK ings +å¿« æį· +ma zing +è´¢ ç»ı +U ES +Ġresid ual +Ġn ail +Ġche er +åİŁ åŃIJ +åı¯ä»¥ æĺ¯ +åħ¨ æĸ°çļĦ +Ġgard ens +Ġsh ield +Ġinflu ences +Ġdismiss ed +it us +æĬĬ æīĭ +F ixed +( % +S al +ç»Ħç»ĩ çļĦ +Ġhum or +ARN ING +ymmet ric +ĠSt rong +Ġcontact ed +ĠH AVE +W C +åıij çĥŃ +éĺŁ åıĭ +-l aw +ĠU rban +Ġeas tern +åIJij ä¸ĭ +à ´ +åĭĩ æķ¢ +ĠA part +d frac +el lo +ĠAnd y +Ġinterpret ed +ä¹ĭ ç±»çļĦ +Ġgrad es +Ġ 说 +ĠW elcome +ĠExper t +ï¼Įæĺ¯ ä¸įæĺ¯ +åģļ å¾Ĺ +Ġpeace ful +åĽ¾ å½¢ +Ġappe aring +Ġwithdraw al +(m ap +æ¿Ģ ç´ł +Ġlight weight +ĠE li +iv ari +èģĮ ä½į +æľī åĪ©äºİ +tr as +lev ance +comp ass +Ġgain ing +p ush +ert o +Ġenjo ys +_ ASSERT +Ġev olved +éĤ ± +ĠEm ily +- image +ĠSk in +Ġtr icks +Ġsp here +ĠL ower +ig ating +ch t +resp ons +ï¼Įä»ĸ å°± +Ġtw in +ĠV ancouver +// ! +ĠG race +Ġrepresent ations +ĠW ays +am ins +åĴĮ 大 +Ġde legate +Ġpers istent +å®¶ 乡 +Ġeas iest +æĹł åĬĽ +ĠD ad +æ¢ Ĺ +-l ong +_M IN +管 çļĦ +} = +ig m +ï¼Į ç»ĵåIJĪ +ĠY oga +( J +Be aut +P in +æľĪ åºķ +åĬł è½½ +_AD D +at isf +Ġspecific ation +ro c +ï¼ĮæĪij è¦ģ +, ... +) ï¼Ľ +.s ervice +Review s +个 人çļĦ +亮 çļĦ +оР³ +Ġquad r +c lock +Ġj er +rop ic +Ġbed rooms +ĠÎ ½ +Ġmed itation +è¡Į ç¨ĭ +Ġveter ans +çĭ ¸ +Dep th +pro gram +æ®ĭ çĸ¾ +åľº éĿ¢ +èĢ ½ +Ġsymmet ric +å¹³ çŃī +æĦ¿ æľĽ +idd ing +ĠP osition +Ġpresent ations +è´ ± +ĠS cal +l inks +< br +le asing +ĠCh ap +Ġm unicipal +æĸ° åįİ +è¿Ļ èά +_R X +t ool +ä¹ĺ åĿIJ +p b +force ment +æĬµ è¾¾ +ä¸Ĭ 次 +oun ters +åľ° è´¨ +ke e +ï¼Į éĹ® +Ġdis crete +v ideo +sub scribe +éĹ´ æİ¥ +k ip +-m ed +åıĤåĬł äºĨ +, çͱäºİ +avor ite +Gener ated +åıĬ åħ¶ä»ĸ +Ġreprodu ce +J un +ing o +念 头 +åħĪè¿Ľ çļĦ +é² į +ĠRestaur ant +å¾· éĩĮ +{ tab +ĠUnivers al +Ġbit coin +F un +Ġdump ster +Ġcomput ation +b ank +ĠSt ew +in ent +- new +ä¼Ł 大çļĦ +æ¸ħ éĨĴ +(s ub +Ġvit ro +ãĢĤ åıªæľī +ĠPort land +ï¼Įä¸Ģ äºĽ +Ġg aps +åı¯ éĢī +ä¸į æĢķ +arn ess +na ire +é»ij é¾Ļ +è¿ŀæİ¥ æľī +åľ¨ ä»ĸçļĦ +Ġlength s +_pro cess +Ġaw k +ï¼Į åIJ´ +ef ault +Ġdiet ary +Ch oose +ib bean +ĠMay or +ĠDu ke +ĠA my +çĸ ¤ +UP PORT +ĠâĢĶ âĢĶ +çŁŃ çŁŃ +type of +local host +_P ARAM +ä¿® æŃ£ +ä¹Łå°±æĺ¯ 说 +ä¿¡ 念 +èµ·æĿ¥ çļĦ +T ouch +row ave +Ġdepart ure +è¾ ľ +大 åİħ +ĠHe at +注æĦı äºĭ项 +Ġrespond ents +çİĩ åħĪ +å°Ĩ äºİ +, B +æĭ³ 头 +è ¤IJ +ii i +çľ¼ çļĦ +.f rame +Ġpress ed +åĴĮ 她 +Ġpan ic +Ġo mitted +ä¸į è§ī +>> > +Ġinvestig ations +ad ows +æŃ¤ ä¹ĭå¤ĸ +Ġste ep +éļ § +åĩº äºĨä¸Ģ +col l +ä¼ł æŁĵ +< n +em ade +, åΰ +Ġinsert ed +âĢĿ æĺ¯ +ĠP ok +ć Ć +- position +æĶ¶ åıĸ +& = +å¤ļ å¤ļ +ĠMean while +ĠF lu +Ġdraw s +åıĭ è°Ĭ +ric ane +åľ¨ æīĢè¿° +ĠD ance +ãĢĤ å¼ł +éª ļ +LE ASE +Ġreg istry +çľĭ ä¼¼ +ne um +Ġdig its +ĠP resent +åΤ åĨ³ +书 éĿ¢ +ĠComp lex +ĠS om +à ½ +Ġequ ilibrium +åĺ´ åĶĩ +ĠSh ipping +RE AM +. context +ost ream +ĠBud get +ĠAfghan istan +, æĢ» +Ġsuper b +æľĪ åĪĿ +Ġfund ament +Ġtra p +R R +T ok +Ġret reat +Ġanaly zing +ä¿® 为 +ï¼Į æĺ¯ä¸Ģ +ĠF alls +æ² ¥ +èĻ IJ +ĠExp ression +å« £ +× Ļ +ç²¾ ç¡® +Ġapplic ants +Pro to +ard o +è¿ŀ éĶģ +ĠAd ams +_ head +çļĦ身 å½± +ul as +ï¼Į è¦ģæ±Ĥ +ĠS witzerland +è¯ķ çĤ¹ +çļĦ éŨ +çĿĢ ä¸Ģ个 +еР¼ +ĠCond ition +Ġc ategorized +æľ¯ è¯Ń +Ġrem edy +e ature +ri k +im edia +Ġ 秦 +ï¼Į ä¼ģä¸ļ +_ST ART +æŀģ 大çļĦ +- i +å¯Ĩ éĽĨ +ipl inary +Ġrespons ive +ä» ķ +大 åݦ +éĹ º +Get ting +atern al +ĠG round +åİ» ä¸ĸ +, 说 +Ġsp ins +Ġly rics +ĠIl legal +Argument Exception +ĠH alf +æ°ij çĶŁ +Int ent +ãĢģ çľģ +Ġr amp +羣 å¿ĥ +æĮ¯ åħ´ +ä½ł åı¯ä»¥ +ĠW ang +åŁİå¸Ĥ çļĦ +ĠT rip +em and +_ OB +åıĸåĨ³ äºİ +Ġv o +ĠB right +å¦ ¾ +注 å°Ħ +oot ing +çļĦ ä¸ĵä¸ļ +ĠH ell +Sh ared +Ġhom eless +Ġappro ached +Ġwh is +Ġsem ester +Ġver dict +, ä¸Ķ +Ġconsider ably +ener ation +Ġå¹´ 度 +Ġsod ium +ĠN ormal +第äºĮ 天 +Ġcollabor ative +ä»ħä»ħ æĺ¯ +Ġadvent ures +sh a +åĴ § +Ġicon ic +åı£ ç¢ij +Ġ åīį +ï¼ĮåĽł èĢĮ +Ġg rip +åıij çĹħ +Top ic +èĽĭ ç³ķ +ĠDub ai +ä¸ŃåĽ½ 人 +ĠPRO VID +交 èѦ +æŃ¥ è¡Į +, å¾Ī +ĠS oviet +æĽ¿ æį¢ +, èĩªå·± +åıĺ çļĦ +ĠC ass +Ġab normal +ĠN T +åı¤ èĢģ +ãĢĤ åīį +Ġrender ing +Ġeconom ics +ĠM un +Ġdist ricts +å±Ĥ éĿ¢ +Ġmut ations +Sc an +åĴĮ å°ļ +Ġgot o +ot yp +ä¹ĭ æĦı +pro v +Sl ot +æ¿Ģ æĥħ +åī¯ ä¹¦è®° +ax ies +. all +Ġprof itable +å®ŀéĻħ æĥħåĨµ +è´¨ çĸij +çͲ åŁº +ne ath +red ited +åı¯ æĮģç»Ń +Ġspect ra +ĠS el +çIJĨ æĢ§ +Ġcor rupt +éªij åħµ +Ġsh ore +Ġprom oted +F ast +Ġattend ance +Ġembod iment +ĠEss ay +ĠN eb +Ġactiv ate +æŀģ éĻIJ +Ġl amp +or o +ĠLog ger +se ason +å°± 没 +' => +è·¯ çļĦ +ec ome +ï¼Į æĹłæ³ķ +pos s +å¹ħ 度 +is en +======== ==== +ãĢģ åįĹ +ĠApp ellant +å¤ļ å®¶ +å®ģ æ³¢ +Ġun comfortable +ĠB ond +Ġnew er +ä¸į åĥı +< h +çĥ Ľ +ĠCh art +ĠR at +" You +å¤Ħ å¤Ħ +ï¼Į æ±Ł +S ometimes +æĶ» åĿļ +Ġl ane +N M +æĺ¯åIJ¦ æľī +Ġatt ributed +ä¹ĭ éģĵ +æĬĬ 她 +é£İ 鼨 +äºĮ ç»´ +åİŁ æĿIJæĸĻ +çļĦ äºĨ +Ġcur tain +ĠPar se +æĦŁ æ¿Ģ +Ġres erves +æ¡Į ä¸Ĭ +Ġa str +æĺ¯ å¦Ĥä½ķ +CI AL +好 äºĭ +w ind +Ġinter pre +ç»Ħ 建 +ele m +I ll +åı£ åij³ +Ġc bd +Ġdro pping +ĠBru ce +Ġdist ant +Ġj oke +丽 çļĦ +Ġsear ches +qu estion +çļĦ大 å°ı +ĠC NN +UB L +åĬł åĿ¡ +ç»Ī ç©¶ +åĪĨ æīĭ +æŃ¦ è£ħ +Ġs ulf +, å¾Īå¤ļ +ĠFre edom +ĠQ t +Ġw ages +Ex port +为 èĩªå·± +社 ä¿Ŀ +Ġund ers +Ġbad ly +åĴ ĭ +常 åĬ¡ +èĢģ åŃIJ +ä»·å̼ è§Ĥ +ï¼Į èİ·å¾Ĺ +. image +è¿Ļç§į æĥħåĨµ +ï¼Į åĽ½å®¶ +Ġflav ors +ãĢĤ éϤäºĨ +ĠN i +ãĢģ 西 +Ġam endment +ä¸Ģ åIJ¬ +ĠW ikipedia +Ġmet all +ç»Ŀ æľĽ +Ġtyp ing +l ayer += _ +ĠB ab +ãĢĤ åIJİ +è·Ł éļı +Ġse aled +Ġp unch +Ġdat asets +ĠH ung +çıŃ çº§ +F M +èĢĥ æŁ¥ +çļĦ åıijçĶŁ +_m atch +Ġrev ision +} ` +缸 对äºİ +ĠB ird +Ġexcell ence +S witch +$ ) +æ³ķ å¸Ī +_n ext +Ġm os +ĠHer itage +ä½ł èĥ½ +Ġd ive +ĠPhil ip +Del ay +Ġr gba +对 æİ¥ +Ġf oss +Ġcl ouds +ĠCare er +è¶Ĭ 大 +ĠTh ought +度 åģĩ +ĠR ating +Ġjud icial +Ġtri ple +ĠBeaut iful +F uture +- set +Ġclean ed +Ġvibr ant +è¿Ľåħ¥ äºĨ +PE C +ĠRec overy +ĠU P +ĠOr igin +Read y +Ġmet als +ĠEmer gency +å·¥ ä¼ļ +ĠL isa +Ġscript s +åIJĦ æł·çļĦ +Ġappe aling +- round +_P IN +ĠMel bourne +Ġo ct +çļĦ åºĶç͍ +ç«ĭ åľº +æĥħ èĬĤ +;; ;; +Ġmulti pl +线 æĿ¡ +igr ant +form er +Ġfin anc +ss l +Ġm d +Ġconsum ed +ĠTag ged +or ch +Ġcreat or +_ app +ĠKnow ledge +åIJİ åĨį +ε ι +Ġworld s +Ġan ten +Ġwas hed +h ind +Ġ ï¼ģ +Ġafter wards +åĿĩ è¡¡ +åĩ Ħ +ĠT ower +ĠR oot +Ġbes ide +ãĢĤ é¦ĸåħĪ +Se q +ra h +ĠOr leans +. Q +é³ ŀ +ap a +att oo +and ise +CE PT +éļIJ ç§ģ +Ġcons pir +amp a +ãĢij ãĢIJ +åıĹ æ¬¢è¿İ +ĠT her +W T +at en +ĠReg istration +çİĭ çļĦ +ï¼Ł ä»ĸ +.t op +_ eq +Ġhop ed +Ġch rist +æĺ¯ ç͍ +l arge +ï¼Į 第 +欢 ä¹IJ +Ġpress ing +Ġfle et +ï¼Į ç®Ģ缴 +anc ers +C a +(m ax +Ġs z +Ġappli ances +k k +Ġd oses +è¿ĺ éľĢè¦ģ +S am +Ġmetab olic +Ġexc use +Ġto b +ĠB onus +â ľ +ke eper +var iable +ä¸Ĭ åѦ +Ġb orders +-f unction +åŃIJ åĴĮ +B atch +Ġcon e +in valid +åĩº è¡Ģ +éħ ° +A H +Ġriv al +æķ°åŃĹ åĮĸ +Ġpat io +Ġc fg +Ġf u +Ġtra ct +Ġconver gence +ãĢģ çĶŁäº§ +_ char +m ir +é¥ ¥ +- control +Ġvers atile +ff f +Ġt ires +Ġhar ass +ãĢģ æľįåĬ¡ +Ġpract icing +Ġn od +ä½ķ æĹ¶ +ç¯ · +li ver +Ġcho pped +æ¯ ¯ +Serial izer +ĠZ ero +èĢ ¿ +Ġ è¿Ļä¸Ģ +< script +Ġterm ination +Ġ 个 +Al ignment +å°± è¿Ļä¹Ī +åı£ ä¸Ń +京 åŁİ +Ġc d +Ġad apter +Ġin coming +主 æľº +æĭī åħĭ +ĠB ring +- co +ï¼Į çī¹ +第ä¸Ģ çϾ +}^ \ +uc lear +çł ° +éĿŀ æ´² +ĠJon athan +LO AT +ĠEp isode +Ġinst inct +çļĦ åij³éģĵ +oc o +Ġsec urities +we ights +r age +.d ec +- work +SE SSION +Ġcent ered +_ ms +ack ed +н Ñĭ +m ill +ï¼Į 忽çĦ¶ +Ġang ular +Ġlab our +E B +æĺ¯ åķĬ +l est +Ġimp ly +Ġel ite +ãĢģ æĽ´ +æĪı åī§ +.b uild +ĠRE AD +è¿ĺæĺ¯ è¦ģ +Stud ent +ĠSt age +Ġla undry +Ġnut s +ĠIn j +çļĦ å¸Ĥåľº +Ġmet aph +ĠAl aska +ĠC ards +Ġex clude +Ġmem orable +R ows +ĠS alt +ĠAssoci ates +Ġthe ft +ĠAl an +Ġrel ies +åĨĽ 人 +ĠM R +ĠE ye +Perm ission +ï¼Į çļĨ +Ġmach inery +us ive +_C MD +Sec ret +åĽŀ åΰäºĨ +Ġun clear +å¯ Ŀ +[ ^ +u ke +èĴ¸ æ±½ +ĠUp dated +zer os +oust ic +B order +ä½Ľ æķĻ +u ary +绣 çѹ +Ġrad i +åŀ Ĵ +L ess +ĠG PIO +Ġrelax ation +pat ient +å¨ģ åĬĽ +â ĭ +Ġspons ored +_b ox +sm ith +Ġm erc +è¥ Ħ +aw ait +Ġpert urb +Ġbre w +ä¸ĥ åħ« +çIJ IJ +Ġpost er +Ġr outer +Ġs ized +ĠProt ocol +Ġcryptoc urrency +Ġdo zens +ai ro +exp and +åĬŀ åѦ +Ġcomm od +æºIJ äºİ +ï¼Į åĬªåĬĽ +AR M +çĶŁåij½ çļĦ +reng th +ic i +å¤ĸ åĩº +_ command +Ġpar as +() )) +Ġenc oded +_ api +_d ebug +纳 ç±³ +Ġf usion +ï¼Į éĢłæĪIJ +Ġh iking +oz illa +ä¹ĺ 客 +.F orm +æĺ¥ ç§ĭ +. red +çľĭåΰ çļĦ +D en +ç»ĦæĪIJ çļĦ +ext ra +é¢ĺ æĿIJ +ĠS eg +ç² ª +_p refix +åķ¤ éħĴ +.R untime +Ġtreat s +: The +Ġve gan +åĵģ çļĦ +产 èĥ½ +ĠPoint s +Ġ éĺ¿ +ys ics +L aw +åħ¬ æŃ£ +Ġoptim ized +Ex ternal +Over all +ĠV PN +P ers +æķħ éĢī +ï¼Į åĩł +ĠCh oice +Ġc ave +Ġenzym e +Ġfor b +Ġh ood +_st ruct +iss ues +ĠNews letter +ĠV oice +ment ioned +ĠEx hib +if eration +çij ¾ +T alk +çļĦ çα +Ġpun ishment +Ġantib odies +AM ES +ĠO racle +羣 人 +Ġun employment +äºİ æīĢè¿° +ĠK rist +ï¼Įéļı åį³ +Ġf ate +èģĶ éĤ¦ +_ex ists +Ġcontrovers ial +ï¼Į åĵª +ĠFig ures +Ġdefect s +ic ates +ant i +_ST AT +ĠT a +Ġdiv ine +ï¼Į ä»»ä½ķ +ĠB rain +Ġsl ides +ï¼ļ C +Seg ment +k le +_F R +T urn +å¢ŀ 大 +åı¹ äºĨåı£æ°Ķ +h yd +ĠChar lotte +ĠP aint +ĠMe asure +æłĩåĩĨ åĮĸ +ĠIN C +ĠDo or +Ġle ar +ä½ł 说 +Ġtend ency +ï¼Į æī¾ +Ġproceed s +端 åı£ +ãĤ Ī +ĠB inary +äºĨ è¿Ļ +å±± å¸Ĥ +Ġ$ . +Ġhel per +Ġcand y +Sign ature +ĠAll ow +ll a +ĠD ental +ĠChar lie +l c +Ok ay +Ġref ere +. Resource +åıijçĶŁ åľ¨ +D om +纺 ç»ĩ +Ġsatisf ies +ĠCh icken +ĠLouis iana +- op +ul u +æĶ¶ 缩 +ob ic +andid ate +Ġrest art +ĠL P +ĠW oman +ãĢĤ åıªè¦ģ +Ġinter faces +çĸ ® +Con sole +H O +æ¡¥ æ¢ģ +Ġpro long +ĠB h +Ġadjust ments +Ġbet s +ah o +at ible +ï¼Į 估计 +Ph il +St ill +. at +Ġs ail +Ġlack ing +b ottom +è¿ŀ è½½ +. Re +åĽºå®ļè¿ŀæİ¥ æľī +Anal ytics +é¢ Ĥ +op ter +æīĵ éĩı +, æĪĸ +Ġsc ary +ï¼Į 欢è¿İ +Ġtour ists +board s +举 æĬ¥ +Ġout lined +åºķ ä¸ĭ +ĠL uck +ent e +ĠMult iple +ï¼Įæľī æķĪ +ć ï¼Į +ĠHun ter +opt im +class es +Ġclean er +Ġanim ated +ut t +çļĦ æķ°éĩı +èĥ½ 让 +ä¸įæĺ¯ å¾Ī +ç¥ ģ +ĠF ILE +Ġhealth ier +look up +ĠS ad +Ġan onym +éĢļ è¡Į +h ma +ĠHawai i +Ġelectron ics +{ X +_ open +b uy +ĠL ily +Ġviol ations +ä¸Ģ å±Ĥ +ĠPer iod +og ue +æĺ¯ æĥ³ +[ s +ĠCh amber +åIJĵ å¾Ĺ +Ġm M +ĠB aker +S n +B us +FA Q +ot ional +Ġb tn +L IN +æ²ī æ·Ģ +åIJĮ ä¸Ģ个 +, z +W ould +. left +é¦Ļ åij³ +Ġplug ins +åİŁ æĿ¥çļĦ +I p +Ġon click +é«ĺ å±Ĥ +åħī çļĦ +ĠChrist opher +Ġshe ep +çļĦä¸Ģ 声 +Ġatt ain +Ġcustom ize +æ¿Ģ æ´» +n ia +Ġl ighter +S ent +åģĩ æľŁ +Ġing redient +Ġfore x +ĠC leveland +ol ume +ĠL ind +{ G +ãĢģ ç͵ +.assert Equals +æİĴ æŁ¥ +c ies +Ġ å®ī +ãĢĤ ç»ıè¿ĩ +æ© ĺ +ãĢģ æľĢ +ĠC row +Ġr ally +pre v +( error +S F +ĠEx am +ĠG ordon +è¿ĺ æĥ³ +人类 çļĦ +åIJĽ åŃIJ +Ġbe aches +-A merican +书 çĶ» +ĠProject s +Ġdepend ency +æijĩ æijĩ头 +ï¼Į åľ° +çª ij +b en +erm at +ric a +ï¼Į åħħåĪĨ +ount ain +çŁ ¢ +Ġgu ilt +åįģ 竳 +.st yle +ow ski +äºĨ çļĦ +Ġcont ra +Ä ħ +ĠP ad +, éľĢè¦ģ +on ce +Ġnonpro fit +reat ment +ç¬Ķ èĢħ +Ġcabin ets +ï¼ » +ĠN H +羣 è¯ļ +ĠG ot +èĬ± çļĦ +wid et +ĠFr ame +Ġnic he +umb led +, æĥ³ +Ġ åįĹ +b ial +å°ı åŀĭ +ä¸į好 æĦıæĢĿ +ç»ı 纪 +ï¼Įä»ĸ åľ¨ +ĠBO OST +Ġlaw n +Ġ åıĪ +Ġchair man +_t op +Ġcro ps +ver ify +ill o +éļIJ éļIJ +ĠUn categorized +ĠI g +(t ime +q a +et itive +Ġjournal ist +Sep ar +Ġfavor able +Ġv ivo +Ġreplic a +èīºæľ¯ å®¶ +ĠB ah +Feature d +as ia +cont ract +ĠSt adium +Ġnever theless +Ġ èIJ§ +è¿Ľè¡Į çļĦ +I gnore +Ġph rases +Ġtact ics +ĠJenn ifer +éļı ä¹ĭ +ä¸Ģ 群 +ul atory +æĿ ĸ +- Ch +ĠO tt +ï¼Įå¹¶ ä¸į +Ġfail ures +Ġacknowled ged +Ġtail ored +aster xml +æłĩåĩĨ çļĦ +ĠF E +å°ij äºĨ +ä¸ĢçĤ¹ çĤ¹ +èĻļ åģĩ +丧 失 +æ£ ķ +Ġreg ret +ĠIN CLUDING +Ġcomp ress +/ E +Ġ" + +Ġwhe at +ĠA CT +Ġbur ied +Ġb ell +ĠCamp aign +ĠJust in +éĹª è¿ĩ +æĿ¥ æī¾ +ĠHig her +, f +ĠP CR +re nder +ound er +ĠNut rition +ĠG ray +å©Ĩ å©Ĩ +å·¦ ä¾§ +ï¼Į æį¢ +Ġper ipheral +Ġlo vers +Ġint ensive +S eries +Ġrest ored +Ġnot ing +s burgh +re ts +Ġl id +æĶ¿ åįı +ç¼ĵ åŃĺ +_B O +ĠF actory +Ġcoh ort +g ie +F ailure +Ġv iable +ï¼Į éĻįä½İ +æĪij äºĨ +Ġlist ings +Ġposit ively +ĠNew ton +-h ouse +Ġign or +æĬµ æĬ¼ +B oard +Ġenc ryption +Ġattack ed +ank a +Ġrem inds +hed ral +åİķ æīĢ +sc ar +ĠTransport ation +.ex e +- is +Ġhyper t +î Ģ +âĦĥ ï¼Į +im itive +usal em +re view +Ġfert il +åĮħ åĽ´ +ĠLaw rence +磩 éĺµ ++ = +é«ĺéĢŁ åħ¬è·¯ +好 è¯Ħ +B ACK +_STR ING +å½ĵ æĪIJ +Ġ åħ¶ä¸Ń +ĠC AN +( params +åĩº èī² +Ġque en +load er +æľºæŀĦ çļĦ +书 ä¸Ń +çģ ¼ +ĠSt ri +ä¸ĸ éĹ´ +å® µ +ĠC itiz +Ġsa fer +Ġs aves +æľī å¤ļå°ij +æľª å¿ħ +Ġwond ered +æļĹ ç¤º +L ines +èİ« åIJį +ĠF C +c v +èĦij åŃIJ +S ports +pl aces +Ġj unk +< = +ie ces +ï¼ĮéĤ£ æĺ¯ +_ access +I K +Ġhousehold s +诸 èijĽ +æij § +ustral ia +ĠR aw +Ġon ion +ĠRes erved +ĠEx ercise +ĠW ard +yl on +ĠK han +Man age +Ġin con +ä»Ĭ æĻļ +_L IST +ĠL OVE +ä¸Ģ éĿ¢ +.c ode +åħ ľ +ane an +-s ervice +ï¼Įæ¯ı 次 +åıij äºĨ +身 é«ĺ +åĨ Ģ +ĠAr c +ex ec +è£ħ éħį +æİ¥ è¿ĩ +ãģĻ ãĤĭ +build ing +Ġt orn +æĸ°åĨł èĤºçĤİ +èIJ½ åIJİ +ĠPop ular +Ġc url +åIJij äºĨ +- looking +两 èĢħ +erv able +å¢ĥ å¤ĸ +ç¼ ķ +ze ch +çļĦ æĥ³æ³ķ +ra ble +åľ¨ ä½ł +å¿Ļ ç¢Į +M achine +éĩĩç͍ äºĨ +rep ly +á s +Ġhe ated +ĠW onder +Ġdepos its +è¶Ĭ å¤ļ +ä½ĵ è´¨ +H y +St ructure +ĠF BI +çª ľ +ĠTok yo +ĠAdd ed +ä¿Ŀ å®ī +ĠS V +Ġpros per +Ġ æ±Ł +å¼Ģ 设æľī +ĠNe ither +ĠSumm it +ĠPC I +Ġw ore +ĠB or +ç»Ĩ èĩ´ +åĬł éĩį +Ġcomput ational +ï¼Įå¦Ĥæŀľ ä½ł +ç¼ Ģ +Ġcamp ing +ï¼ ½ +widet ilde +åŃĹ æ®µ +Ġins ufficient +ï¼Į åİŁæľ¬ +Ġj ar +Ġp ine +Ġar th +T y +Th ough +åĨ² åĬ¨ +çļĦ æĹ¥åŃIJ +å°ı å°ıçļĦ +ä¸Ģ éĥ¨ +Ġposition ed +ĠP ink +æĶ¾ è¿ĩ +× ķ +泡 沫 +n atural +ĠC ALL +Ġtrad ers +æľī åĬ©äºİ +Ġo g +è¿Ļæł· ä¸Ģ个 +Ġcomp romise +è̳ è¾¹ +Ġu b +Ġbreak down +T ile +Ġcircul ation +èı ± +两 大 +æµĻæ±Ł çľģ +Ġbas ement +女 人çļĦ +k ill +.is Empty +Ġobs c +ĠIn side +æ´¾åĩº æīĢ +M ail +Ø ¨ +st ick +离 åİ» +ĠOr th +ĠPol and +Ġmut ation +Ġhere by +Ġpharm aceutical +i otic +Ġi i +ĠN eg +ĠL ex +о н +op ath +å¥ĩ 迹 +Ġvacc ines +ä¸į åĩºæĿ¥ +Ġ ï¼Ľ +ï¼Į åIJĮæł· +Ġded uct +ä n +ec ycle +ä¹Ł åı¯ +Ġneed ing +åı¦ä¸Ģ 端 +Ġimm unity +å¾Īå¤ļ çļĦ +H int +_ uint +纯 ç²¹ +ä¸ĭ æ»ij +Ġrese mb +ï¼Į éĿ¢å¯¹ +omorph ism +Ġw avelength +ãĢĤ ç»ı +Ġconf using +Ġalleged ly +Ġint ens +\ }$ +Ġgar bage +Ġsurv ived +Mon itor +ĠDiam ond +Ġun ity +S ing +ĠPrem ise +Ġcreat ure +çĶŁæĢģ çݯå¢ĥ +ç¡ Ŀ +H tml +\ ]) +Ġl ag +p ic +å½ĵ ä½ľ +ĠF ramework +Ġinf erence +ĠPolit ics +ä¸ĭ ä¸Ģ个 +_SH IFT +å» ĸ +ĠD ating +ET HER +Mut able +h n +T ax +Class es +天 æīį +Ġnation wide +ä¸Ģ 带 +Ġtempor al +åºĹ çļĦ +ç´¢ å¼ķ +âĢķ âĢķ +Ġfat igue +ä¹ ŀ +Ġexpect s +å¾Ĺ åĪĨ +Ġbr ut +Ġb ubble +Ġconv icted +at ched +.Ass ert +第äºĮ 个 +ĠIs a +Ġfarm ing +Ġinnoc ent +, è¿Ļç§į +Ġen code +ãĢģ 红 +Ġinv asion +Ġoff line +ĠF ine +Ġs word +Ġeth ics +è¿ĺ åİŁ +Bit map +_ conf +ĠApp s +_d b +D K +ari ans +æĬĬ è¿Ļ +ĠThe me +å½ ¤ +çļĦ æ¨¡æł· +-r un +ä»İ ä¸ļ +-p age +éĺ¿ å§¨ +Ġco ating +IT ION +. register +æĻ¶ ä½ĵ +Ġaccess ibility +A ctions +ï¼Įçľĭ çľĭ +_ IR +Ġnon linear +Ġinflam matory +ä¸į æĺİçϽ +å¼Ģ éĢļ +as ury +æĦŁ æħ¨ +à ¨ +Output Stream +b oth +Ġgal axies +Ġsecret ary +uis ine +ios ity +ĠSc ale +( . +ãĢĬ ä¸ŃåĽ½ +Tree Node +Ġprom otes +Ġrat ios +ĠKenn edy +Ġcop ied +åĵ Ĺ +, éĥ½æĺ¯ +Ġnovel s +ĠR ab +Ġâ Ķ +Ġun ited +ĠExt ra +è¯Ħ 审 +åĴĮ æľįåĬ¡ +Ġal k +Err ors +p aces +аРº +æĹ¶ 空 +ĠPl ans +Ġdom inated +ub untu +og g +ï¼Į å±ŀäºİ +Ġtre asure +å£ģ ä¸Ĭ +楼 梯 +ĠDAM AGES +ĠH at +éģĩ åΰäºĨ +Ġ' : +âĢľ This +å¹³ åĩ¡ +Ø © +ĠMiss issippi +åŃĺ æĶ¾ +çħ ľ +w y +ĠGra ham +产ä¸ļ éĵ¾ +Ġinvestig ating +ï¼Ł éĤ£ +æ·¡æ·¡ çļĦ +() [ +大 æķ°æį® +ĠJ ere +·· ·· +M AC +.e clipse +Ġbacter ial +.ex ecute +ï¼Į ç´§ +Ġw rest +Ġen act +äºĮ æĺ¯ +客 æĪ¿ +æľīåħ³ çļĦ +Pro c +æĢİä¹Ī 说 +ï¼Į ç»Ŀ +Ġdr unk +_F ORM +ï¼Ī äºĮ +> ' +Ġval ley +æĪij们 åı¯ä»¥ +ĠFis her +ht m +)) /( +ĠL am +ï¼Įæľī 人 +id ad +ä½ł ä¼ļ +. items +ĠApp end +åı¯èĥ½ çļĦ +m ers +ĠM ining +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠ +ĠL aura +- In +ç» İ +ĠN elson + º +éľĢè¦ģ 注æĦı +Ġr hs +ESS AGE +ï¼Į æ±ī +ĠNY C +çļĦ人 éĥ½ +Ġwind s +ĠRob inson +let t +èµĭ äºĪ +Ġbre ed +éģŃ åıĹ +ä»·å̼ çļĦ +éĤ£ æł·çļĦ +ens ors +èĩªå·± åľ¨ +Ġcelebr ating +( options +ĠF er +å¨ Ł +Ġt witter +ï¼Į æĹ¶éĹ´ +ï¼Į æİ¨åĬ¨ +Ġillust rate +å¹´ åľ¨ +ra ise +失 ä¸ļ +åħ¥ éĢī +Ġh iding +æĸ ĭ +京 举 +Ġt ropical +Ġ[ - +Ġrun ner +çļ± çľī +Ġdes irable +Ġo v +M ix +b t +ĠEd it +马åħĭ æĢĿ +an on +ed a +Ġdel ays +ES CRIP +Ġ åħŃ +Ġm arch +, åģļ +ĠR C +M al +åģ¥åº· çļĦ +oint s +Ġf lesh +Ġcard iovascular +ĠC abin +åľĨ 满 +B IT +s afe +USE D +ĠB T +ĠQue ens +æĬķ è¯ī +Ġwa ited +ĠD ress +åı¦ ä¸Ģç§į +Ġprohib ited +he imer +ĠSent ence +I AN +Ġdifferent iation +Ġsus pected +Ġb ounce +ॠį +Ġmet ast +çĦ ķ +or ia +ĠSupp ly +说 说 +ĠV el +ĠWe ather +â Ļ +Ġde ce +Ġadvis or +æ²³åįĹ çľģ +Ġhorm one +ĠP K +ĠT aking +_ root +j ax +ĠB eyond +Ġassess ments +Ġveget able +Ġpoor ly +Ġsh ake +pro c +ĠF ixed + using +b x +Ġp ause +湿 度 +ĠStand ards +åħ¨ æĺ¯ +ĠT ar +ï¼Į å¾Ģå¾Ģ +Ġpract ically +Com merce +Ġas ympt +Tr ust +count ry +ä½ł åİ» +ç͍ æīĭ +Cal endar +ï¼Į å¾Ģ +ernet es +ĠInit ialize +app ropriate +ĠA DC +åľ¨ èĩªå·± +os ome +H ouse +ĠAd just +T ele +Ġunder go +åİŁ åľ° +Ġsh ine +满 èĦ¸ +ç¦ ¹ +çļ ĵ +: . +Ġroll er +èĴ ² +Ġjump ed +å°±åı¯ä»¥ äºĨ +x p +Ġbe an +j amin +_st ep +Ġf ond +ä¿ ı +im ity +Con structor +åĵ ī +- ref +Ġsim plicity +Ġboy friend +.D e +Ġtransf ers +Ġint imate +Ġp ione +ĠCar ter +ç³ĸå°¿ çĹħ +çļĦ å®ŀåĬĽ +Ġcle ans +è¢Ń åĩ» +Ġact ed +ĠA le +Ġmet er +ub ernetes +f ocus +ĠSH ALL +Ġ' ', +ĠM Y +èĦļ ä¸ĭ +ĠE SP +ç±³ åħ° +lement ed +模 çħ³ +Ġdes criptor +_E VENT +_OFF SET +èĮ İ +ir i +ĠThe mes +Ġover look +人 对 +ij ing +ass ador +ĠT i +ĠBrook lyn +ï¼Į å±± +åŁº çĿ£ +Ġ' { +ï¼Į æĭ¿ +å¼± çļĦ +é¢Ħ èѦ +Ġtomat oes +Ġp ile +ï¼Į ç¬ij +æ» ¥ +: / +èıľ åįķ +åζ åĨ· +åľ¨ åīį +Ġre nown +æľ¬ åľŁ +ĠM eta +ï¼Į äºij +对 ç§° +ĠAr thur +Ġless er +Ġdisp atch +åº ļ +_B Y +åı¬ åͤ +Ġappro aching +ĠK r +ĠMain e +ï¼Įæľ¬ æĿ¥ +L and +Ġdress ing +. ] +è°Ī è¯Ŀ +ĠLab our +, æľĢåIJİ +ĠBlu etooth +Ġreal m +ãĢģ æĸĩåĮĸ +ĠL GBT +Ġdet ector +ĠP el +å¢ŀ éĢŁ +Ġsu cc +å½±åĵį åΰ +æĦŁ çļĦ +寻 常 +ä¸Ģ åī¯ +çģ¾ å®³ +Ġob esity +æĦŁ åı¹ +Ġunder neath +èĥ¸ åı£ +æĢ§ åĪ« +f old +(s ource +_ work +St age +- section +R oom +å¡« åħħ +ĠM ental +ĠA A +Ġal ias +L T +ĠComp are +( ref +ï¼ļ B +çªģ åıij +with out +or ic +[ ... +âĢľ éĤ£ +Ġperiod ic +ĠMathemat ics +rop olitan +çĿĢ èĩªå·±çļĦ +è§Ĩ è§Ĵ +å§ ¥ +Ġshow case +UIL D +Ġtrans mitted +交 ä»ĺ +-s c +åģı åģı +ĠT ABLE +主管 éĥ¨éŨ +inst ein +èħ ¥ +-orient ed +Ġstat istically +iv als +Ġw it +çłĶ 讨 +Ġmarg inal +, 为äºĨ +ed ges +OV ER +æŃ£ ä¹ī +è¿Ļ åĦ¿ +ä¹° åħ¥ +ĠEXP RESS +P ER +ĠLog in +er ce +ä½ľä¸º ä¸Ģ个 +oun cing +G uid +ro ve +äºĨä¸Ģ ä¼ļåĦ¿ +th ink +Ġnormal ized +åĽ½å®¶ 级 +Ġsil ly +Ġconsum ing +Ġpr ayers +ç¥ŀ èī² +Ġr am +åľ¨ ä¸Ĭ +ut able +è¶Ĭ åįĹ +ç²¾ ç»Ĩ +( start +åĮĸ 为 +çļĦ åĬ¨ä½ľ +Ġpl ots +Ġfe ver +Ent ries +M ass +an gh +m x +çļĦ ä¸įåIJĮ +_ ops +Ġbl ast +ĠSt ra +XX XX +çĿĢ èĩªå·± +re ctions +ole cular +ĠBr un +çŁ¥éģĵ çļĦ +ĠW ords +Ġo l +RES ULT +Work ing +Ġbe ars +æİ¢ æµĭ +ly ph +le ading +om ent +ĠGu est +å®ī ç½® +ĠK ay +Ġded ication +Ġd ens +Ġsk etch +åİĭ åζ +m aker +Ġresil ience +ĠR achel +ĠT M +ĠM ilitary +åŃ£ æŀ« +Ġmaintain s +Ġpass ive +éħĴ ç²¾ +Ġspread ing +Ġtob acco +女 åŃ©åŃIJ +Ġclos et +é¡ · +ĠF irm +ï¼Į å¾IJ +CON T +- inc +ĠB erg +å¾Ī éĩįè¦ģ +ars ed +æłĩ çļĦ +ä¼ł è¾¾ +å½±åĵį åĬĽ +ï¼Įä½Ĩ æĪij +Ex pected +èѦ æĥķ +Ġ å¾IJ +ch r +Ġart ic +Ġsc iences +横 åIJij +Ġoverl ap +Pay ment +re ck +Sur face +/ null +Ġinhib ition +Ġpred omin +天 èµĭ +st airs +Ġstress ed +se en +ĠOr d +T yp +Ġavoid ed +æľ Ķ +Ġw ines +Ġpure ly +och ond +åĵģçīĮ çļĦ +åĿĹ éĴ± +Re q +Ġfoot age +IF Y +ĠOff er +com ponents +ent ries +ĠProcess ing +Ġdest inations +åĩºçīĪ çļĦ +us c +åĽ° æī° +åįģ ä¸ĩ +ç¼´ è´¹ +ro be +ling ton +æĮģ æľī人 +ĠMor ning +å¼Ģåıij åĮº +.c opy +Arg uments +b oot +ĠCar ibbean +ĠEconom ics +åĴ¬ çīĻ +% - +ãĢģ åı¯ +åĭIJ åľ° +. Comp +导 ç͵ +çIJĨ å·¥ +ĠArch ive +Ġreven ues +çĩĥ æ°Ķ +ĠSk ills +ĠV ideos +ith metic +大 è¡Ĺ +ĠF actor +Ġstrugg led +Ġtrans plant +éĺ Ī +çĥŃ çĤ¹ +éĩij éĴ± +Ġreg ulate +ific ant +人 ä¹Ł +åĩº åı° +Ġrespond ing +ï¼Įä¸į åIJĮ +Ġaw ful +ä¸Ģ åij¨ +Ġc it +èIJ½ çļĦ +æļĤ åģľ +ĠBe ck +_t ree +åħ¬ 示 +Ġj azz +An chor +plic ate +y ll +[ t +ä¸į æĦ¿ +Ġover head +车 åŃIJ +Ġy a +ĠJun ior +umb lr +为 åŁºç¡Ģ +ĠE ither +ĠPROVID ED +uc le +æĹł æķĪ +æ¾ Ī +Ġen rolled +ä¹ĭ ç±» +T ensor +\ mathbb +Ġcolor ful +ä¸į æĹ¶ +ä½ľ é£İ +" ãĢģ" +Ä ĩ +, èĩª +åŃķ å¦ĩ +Ä Ľ +Ġreported ly +Ġcalcul ator +ä¸į èĤ¯ +å¥ ķ +Ġ} ) +à Ĥ +éľĩ æĴ¼ +, ä¸Ģèά +Ġpack ing +亮 çĤ¹ +he im +åĵ ¨ +ĠChe l +, æĸ° +Ġang el +æŁ¥ æī¾ +Ġsubscrib ers +D eb +ig a +. User +Ġre vel +ĠR ect +æīĢ èĥ½ +ĠD ent +æijĦåĥı 头 +Ġtra ins +Ġag g +.C ode +l ad +Ġdef ence +W O +mon ary +è¿Ļ 座 +. ac +em et +.t able +Ġunf air +Ġo ste +èĢģ å®ŀ +:h over +G D +Ġdes erves +é¸ ¦ +Ġbench mark +Ġderiv atives +Ġmind set +Ġd aughters +ind ent +rav ity +ĠAl ber +ent ina +ĠY an +许åı¯ è¯ģ +Ġdeploy ed +if le +åı¯ä»¥ 说 +Column s +Ġen rich +T weet +ĠI RS +Ġloc als +Array List +Ġz u +Per iod +ĠF lex +S rc +ç«ĭ è¶³ +. not +çĶ³è¯· 人 +b ling +. Request +_p red +duct or +epend ence +æĹł 声 +æľ¬ ç«Ļ +èı ģ +ĠL ik +ver ts +Ġass ists +ree ze +ren a +ass et +Ġthro at +ä¹ĭ èī² +ãĢģ èĩª +)) / +ER O +æľįåĬ¡ ä¸Ńå¿ĥ +_F OR +Ġduplic ate +Ġ iv +Ġ( (- +ãĢĤ æŃ¤æĹ¶ +ä¸įä¼ļ æľī +å°± 好äºĨ +ĠI BM +å¦Ļ çļĦ +ĠR S +ĠDec or +ĠV ec +ĠSug ar +Ġeduc ated +br is +Will iam +al ias +g ement +Ġbu zz +æĺŁ æĺŁ +èĹ » +æľī éĴ± +ib e +U AL +Ġunderstand s +Ġab dom +éĩĩ æł· +R unning +æĺ¯ä¸Ģ ä½į +åĬ¨ éĿĻ +u cl +æ´»åĬ¨ ä¸Ń +_AT TR +éļ¾ åıĹ +é«ĺ å³° +å·¦ æīĭ +Ref erences +ï¼Į å®ŀ +Ġaest hetic +ä¸Ń æľŁ +çİ© çļĦ +ä¸Ģ æľ¬ +åıª éľĢè¦ģ +为 ä»ĸ +atin um +马 车 +Ġp anc +_N ONE +Ġsl ave +Add ed +åĵ Ł +Ġep och +Ġfif ty +ond e +. str +-sh aped +å±ģ èĤ¡ +IS A +Ġindex es +çĿĢ äºĨ +inter pret +/ kg +åı¤ åħ¸ +Ġvolunt ary +Ġconst itution +ĠClean ing +ĠM os +åħ¨ æĸ¹ä½į +äºĮ æīĭ +osc ow +ĠT ob +Ġg adget +Ġfor ums +ĠBas ics +ID TH +ä¸Ģ æĦ£ +Ġant ioxid +ĠFl ag +arch ive +- art +Ġw rapper +羣å®ŀ çļĦ +ud y +ç²¾ åįİ +. output +Ġb und +è¯Ń åı¥ +Ġhor rible +éĤ ¹ +Ġemb ry +[ idx +çĻ £ +å¹³ è¡Į +_IN TER +çĤ¹ çĤ¹ +pect or +Ġc lo +çĶŁ åĬ¨ +æ´ ½ +Ġconcent rate +ĠR SS +Ġstri kes +çļĦ æĬķèµĦ +éļı åį³ +Ġâĸ ¡ +çĦ¦ çĤ¹ +çļĦ åıĮ +åIJ¬ åΰäºĨ +Ġnow here +H I +Ġcoast al +CH AR +å®Ŀ çŁ³ +, ä¸Ĭ +æİĴ åĩº +ï¼Į åįİ +_ iterator +hat tan +PH P +ç¨ ļ +ï¼Ī å¦Ĥ +åĴĮ åıijå±ķ +_m e +éĢģ ç»Ļ +ĠSy nt +L V +åħ¬åĬ¡ åijĺ +çľĭ ä»ĸ +åıĺ éĿ© +åĬ³ åĬ¡ +æīĭ åĬ¨ +Ġcons iders +Ġind ent +ract ice +ĠScient ific +Ġunder ground +Ġfor cing +ä¸ĭ ä¸ĢæŃ¥ +Ġm RNA +F IN +çĨŁ ç»ĥ +CL U +ag ination +ï¼Į åĪĩ +Ġschol ars +TE LE +_ off +çĸĹ æ³ķ +ott age +è¿ĺæĺ¯ å¾Ī +she et +Ġapart ments +人 äºĭ +Ġst ellar +omorph ic +身 å¿ĥ +out ed +Ġtrad es +le en +Un fortunately +ĠM yst +ĠH app +Ch unk +ĠF am +éĻĦ å±ŀ +Ġhor izon +Ġoppon ents +UT C +建çŃij éĿ¢ç§¯ +_l ib +. Status +ĠHealth y +导 å¼¹ +_c urrent +_se q +Ġ 被 +ĠS ites +ili ation +ĠCreat es +-n ecessary +ĠS qu +ict s +æ´Ľ éĺ³ +_c pu +为 ä¸Ńå¿ĥ +ĠSen ator +ĠP ic +Ġlo ver +ĠH us +ï¼Į æŃ» +Ġdistinct ive +Ġbo ats +Ġrel atives +Ġconfig urations +Ġmole cule +Ġconf erences +Ġconv ince +Ġhe t +头 éĥ¨ +. http +.f ields +E A +ĠAccording ly +æĢ» 书记 +un defined +Ġsl im +P ATH +Ġmin erals +æ¶Īè´¹ èĢħçļĦ +ĠSing h +Ġm ilit +Ġco oper +Ġrev ised +Ġembod iments +{eqn array +Ġinit iated +: ** +ä¼ļ 让 +主 çļĦ +æĢ» çĽij +å·¥ä½ľ èĢħ +Ġsp a +Ġroll s +ĠT u +ĠB rief +ĠM all +ĠCON T +Ġâ̦ â̦ +Ġen compass +åįģä¸ī 竳 +ĠSpecific ally +Ch ris +H ard +åİĨ ç¨ĭ +æĺ¯ éĢļè¿ĩ +Ġguarant ees +éĺ¿ æĭī +常 ç͍çļĦ +ĠChristian ity +Ġa th +ãĢģ 管çIJĨ +ç¨ ½ +æĬ¬èµ· 头 +æĹĹ èΰ +cept or +Ġ ãĢĢ +Ġ æ°´ +ç»ıåİĨ äºĨ +ĠL CD +Ġfeas ible +å¡ij éĢł +Ġw and +Ġrevers ed +.App end +æģ ³ +ĠIN TER +ans wer +åħ¬ å¼Ģåıij +st yles +T w +_l ayer +ber y +Ġtravel ed +æĿĢ æīĭ +Ġmod est +âĢĿ åŃĹ +b as +æ°ij äºĭ +com ed +Pro of +W as +ä¾ ¨ +Ġde put +Ġapplic ant +èĥ½å¤Ł åľ¨ +âĢĿ ãĢģ +Ġlot tery +ade qu +Ġdis closed +/ e +ä¿® 订 +Ġbo iler +å¸Ī åħĦ +ä¸Ģ æµģ +re port +éĻ ¡ +ĠM IN +ist le +Ġ æĸ¹ +Ġimport ed +_set tings +Ġatt raction +umb ai +She et +Ġ è¿ĻäºĽ +å¤ĸ 交 +Ġh ike +Ġinc idents +Ġp ist +Event Listener +e em +Ġm im +rep o +E ss +æĺ¯ä¸Ģ ä»¶ +oub ted +Ġge ometric +ï ¹ +ĠC li +. item +çļĦ çĶŁäº§ +и н +æĶ¹ 为 +Ġà ¢ +ers ed +y te +ä¼ļ 导èĩ´ +S plit +_t emplate +çĶ· 人çļĦ +ach t +-c ell +. Web +ä¸Ģ æł¹ +ï¼Į åıĮæĸ¹ +P a +Ġprogram mes +管 æİ§ +Ġmon ster +K T +Ġscan ning +. ). +ç» ŀ +èĩªçĦ¶ çļĦ +msg str +Ġback ing +ä¸Ģ åĪ» +Al ert +ï¼Ľ ï¼Ī +d irect +ĠCONTR ACT +Ġcou ch +Ġr itual +du p +éļ§ éģĵ +Ġsurprising ly +.c s +åĨ· ç¬ij +Ġâ Ĺ +主 æµģ +å°± çŁ¥éģĵ +æ³ķ åħ° +åIJİ éĢĢ ++ - +_ URL +éĥ½ ä¸įçŁ¥éģĵ +Ġb urg +Ġt sp +_p art +а ÑĢ +ä¹ĥ èĩ³ +cs v +c ourse +ORD ER +ç»Ĩ èħ» +ĠBar bara +r andom +ĠUn ity +ĠNev ada +} ", +Count ry +Ġv a +p her +ron es +åĨĽ åĽ¢ +#### # +, åĽł +Ġindu ce +æ¶Ī çģŃ +æĶ¯ æı´ +å¸Ĥ åĮº +Ġcontin ually +ç¬ Ľ +åIJĪ èĤ¥ +é¡¶ 级 +Ġshow c +ĠÏĦ η +ical s +æĪij们 è¦ģ +æĶ¿ åĬ¡ +è¿Ļ个 ä¸ĸçķĮ +åĵ ® +ãĢĤ 第 +åĸĬ éģĵ +Ġassert That +( log +ï¼ī ï¼Ī +æ¯ķä¸ļ äºİ +Ġexpress ing +Ġcr ate +Ġmin s +Ġdiscuss es +åĭIJ çĦ¶ +ĠS ymbol +ĠR A +å®ı è§Ĥ +Ġcycl ing +Dec imal +& D +稳å®ļ çļĦ +主 èIJ¥ +ĠStew art +Ġch apters +å¦ Ĵ +um per +Ġdil ig +å°Ķ çļĦ +èį· åħ° +ä¸Ģ 度 +ĠIt ems +ext ension +âī ¤ +ĠW W +èĬ ¸ +.get String +追 ç©¶ +ĠT es +A ug +Ġhold ers +æ¯ģ çģŃ +ãĢĤ [ +çĥĺ å¹² +_c allback +WI SE +ĠR ole +( expected +Ġp ockets +å®ī å¿ĥ +è¯Ħ 级 +b ird +æĭ ½ +çĥŃ éŨ +J ack +pos al +-st ar +Ġsimpl ify +ĠT YPE +å¿ħ å®ļ +Ġc u +å®ĮæĪIJ åIJİ +p ing +å®īåħ¨ çļĦ +B ill +Ġsell s +Ġsubmit ting +, 好 +建ç«ĭ äºĨ +Ġpursu ing +ãĢĤ åΰ +art en +Ġf ires +ä¸ī çϾ +ĠMuslim s +çĿ ¹ +w x +ĠPre vention +äºĨ ä½ł +çļĦ æĪij +æĥ© ç½ļ +ï¼Įåıª ä¸įè¿ĩ +.d is +Mean while +Ġgood ness +Ġc ategor +w estern +_C TRL +Ġpun ct +æĺ § +ĠB eth +æ¸ħ åįİ +èĨ ³ +Ġhe d +Ġimpro per +ic ht +Ġexp ed +rad io +r x +æĿ¥ è¿Ľè¡Į +Ġsp ont +( root +pro d +Ġw ax +ä¸Ģ ä¾§ +ĠPark er +Ġoccas ional +-c ar +ĠD omain +éĢĶ ä¸Ń +Ġacc eleration +Ġlaunch ing +Manag ement +éķ ĸ +st ation +ï¼Į æŀģ +Ġdys function +åıĺ äºĨ +车 ç«Ļ +éģĵ æŃī +Ġcar riers +èĢģ 年人 +A w +è¿ĺ æľª +Ġopt ing +E urope +éĽ į +çŃĽ éĢī +æ·± çļĦ +ĠT ro +ä¹ĭ æĹ¥èµ· +author ized +. q +ĠRet ail +å¸Ĥ éķ¿ +两 åIJį +Ġapp ell +æİĮ æİ§ +Ġjump ing +e ous +èĤ¯å®ļ æĺ¯ +为 æĪij +H uman +Ġaccompany ing +åįļ 客 +h w +ï¼Į ç͍æĪ· +ĠFr an +S um +ï¼Įä½ł è¦ģ +Ġp ound +çļĦ æł¸å¿ĥ +Ġpay day +ĠM is +Ġeditor ial +åĨħ æ¶µ +çļĦä¸Ģ 次 +Ġexecut ives +ili ate +ĠP ray +ĠWar ren +Ġwa ist +ĠOffic ial +交 代 +Ġlist ened +æĹł ç©· +é£İ çļĦ +Ġconnect s +ç¿ ¡ +æ³ķ åĪĻ +èı© èIJ¨ +ãĢģ éĶĢåĶ® +ä¹ĭåIJİ çļĦ +L M +P ane +ig g +ĠP I +Ġ* = +åĩłä¸ª æľĪ +Ġd airy +ĠGu y +r p +Ġvirus es +ï¼Į é¾Ļ +_s pec +ĠAR T +Ġpromot ions +< double +- owned +Te X +ĠS HA +ator ies +/ V +ed in +rac ellular +Ch anges +om on +éĩĮ æľī +D IS +æľĿ é²ľ +Ġre nov +ĠCon struct +ãĢĤå¦Ĥæŀľ ä½ł +ä¸Ļ çĥ¯ +ä¸į å½ĵ +没æľī äºĨ +Ġon set +ç»ıæµİ åѦ +èij µ +ffic iency +ĠO ften +.s erver +N orm +: s +ä½ĵ åĬĽ +che t +ĠE ld +Ġdispos al +Ġselect or +h im +çħ¤ çĤŃ +éĿŀ常 好 +h ide +rep resent +ĠDirect ors +he art +S em +Build ing +Ġthank ful +å·² æĺ¯ +ï¼Į å°½ +k n +çļĩ åŃIJ +Ġunder graduate +ĠChe ap +in formation +Ġinv itation +w ritten +ĠPolit ical +æµģ ä¼ł +亲 åŃIJ +tr ation +ring e +Ġtherap ist +åĨħ容 ç®Ģä»ĭ +ot lin +ARR AY +Ġcoord ination +å» ĵ +æł¼ å¤ĸ +Ġdefault s +ĠJ oh +éģĩ è§ģ +Ġfl ush +大 è§Ħ模 +xx x +.c olor +-s peed +ĠClin ic +åij½ ä¸Ń +Ġjournal ists +Ġalt ogether +ï¼Į åIJĦç§į +Ġb ump +æĽ ¦ +Ġpres erved +夫 å¦ĩ +å¹» æĥ³ +B re +Ø ³ +ä¸Ģ 身 +b ased +åı¯ ä¸į +ĠS ri +ĠJer usalem +Ġsched uling +{ e +* ~ +Ġrem arks +om i +åįĵ è¶Ĭ +< Integer +it err +æķ´ é½IJ +Ġl am +ĠRead er +å¼¥ è¡¥ +Ġband width +Ġman ages +æīĢ è¯´ +çļĩ å®¶ +eh icles +, äºİæĺ¯ +éħĴ åIJ§ +.n ode +under line +_l ast +éĩį éĩį +两 æĿ¡ +çļĦéĩįè¦ģ æĢ§ +æł¸ ç®Ĺ +ĠV iol +( sc +Ġac et +åħ¬åı¸ åľ¨ +ä»ĸ们 åľ¨ +(b ool +Start ing +lo ys +ay load +_un lock +Ġd in +Ġbo il +æ¦Ĥ è¿° +ĠM ob +åŃĹ æ¯į +æIJ Ĥ +Ġlif ting +Ġso vere +ĠP OST +æ°Ķ åĬ¿ +Link edIn +Ġliter al +æł¡ åĮº +ĠHy per +ĠBalt imore +红 èī²çļĦ +ĠConnect icut +ä¸ĭ 车 +agon ist +P rem +Ġ- \ +p es +F ront +ç͵ ä¿¡ +Ġagre es +ï¼ĮæĪij åĽ½ +ï¼Į åįĬ +çļĦ èĮĥåĽ´ +Ġwood s +_ search +ï¼Į以 åħį +Ġaccess ing +主æĮģ 人 +æĹ¥ åIJİ +Ġdo ck +. position +m all +çĨ ı +ĠB ou +åīį è¾Ī +çĶ· æľĭåıĭ +ï¼Į 许 +sen al +é¢ľ å̼ +ĠC ertain +ĠA y +arent ly +æ¾³ éŨ +im o +f red +( unsigned +Emp loy +ĠBi ology +Ġdat etime +Com ponents +ĠC N +Ġd ashboard +L ab +Ġretain ed +O cc +æĭ¼ åij½ +Ġbackground s +_p olicy +Ġtravel s +Ġjoint s +æ´Ĺ è¡£ +G N +Ġp ond +ä¸Ń å¹´ +ĠA id +Ġso fa +æĻºèĥ½ åĮĸ +çī¹åĪ« çļĦ +Ġcounsel ing +å¼Ģ æĿ¥ +ĠM i +Ġp sy +Ġforg ive +Ġcontribut es +çļĦéĤ£ ç§į +Ġrespect ed +æīĢ èĩ´ +, ä¸įæĺ¯ +Ġb out +è¡Į 人 +æİ¥ ä¸ĭæĿ¥çļĦ +oh yd +Ġst airs +ag ain +ev a +æľīäºĽ ä¸į +æļ´ åĬĽ +车 éĹ´ +åĤ į +åı¯ åľ¨ +ç»Ħ çļĦ +FL AGS +æĨ ĭ +. values +åĬ¨ 漫 +ï¼Į ä¿ĿæĮģ +rem arks +.get Value +Ġsac rific +Ġaccept s +çļĦ ç¬ij容 +.m od +ic ons +Ġfol k +ĠD ra +Ġimm igrants +Ġ æ²Ī +Ġcar cin +ĠEs pecially +æIJ ģ +åł ¤ +ĠG ov +æģ¶ éŃĶ +ĠFac ulty +Ġsid ew +Ġl bs +伸 åĩº +D rag +US D +éĢĤå½ĵ çļĦ +Ġden ial +C ulture +_ API +ĠCamp bell +Ġf are +Ġvol atile +ore n +è°ĥ 度 +ä¸Ģä½ĵ åĮĸ +çŀ Ħ +Ġpar liament +åŃĶ åŃIJ +//////////////////////////////// //////////////////////////////// +ãĤ ¢ +Ġed itors +ï¼Į 顾 +f m +Ġburn ed +æľĢ é«ĺçļĦ +Ġsp ine +Ġdam n +éª Ĩ +ï¼Į 轻轻 +çļĦ éĤ£ä¸ª +ĠHash Map +ĠB uffer +è¦ģ çĤ¹ +{ v +ä¾µ çĬ¯ +Ġgal axy +å¯Ĥ å¯ŀ +ĠDak ota +æ¯Ķè¾ĥ 好 +Ġprec ip +è§ģ è¯ģ +Ġlect ure +ĠNAS A +Ġorgan izing +æľīæķĪ åľ° +Ġsm iled +ĠFl at +çļĦ æĵįä½ľ +F n +åĭĩ 士 +ï¼Į åŃ¦æł¡ +åı¯ è°ĵ +_b utton +iz ar +èIJ İ +åIJĪ çº¦ +l ord +Ġpri est +Ġdec ides +Q UI +ĠLI ABLE +æĺĨ æĺİ +ĠGener ic +} )\ +ï¼Į çľ¼çĿĽ +W omen +à¥į ठ+ä¸Ģ å¤Ħ +çļĦ é¡¹çĽ® +è¶ħ 声 +å´© æºĥ +åħļ æĶ¯éĥ¨ +ĠEngine er +åĪĨ åī² +exp ensive +ĠUnder standing +_in stance +ra ul +ï¼Į å¦ĤæŃ¤ +ä¸Ģ次 æĢ§ +Ġsent iment +Ġd angers +ifest yle +Ñ ī +ĠCar bon +.set Text +ï¼Į æ¥ļ +Ġdel icate +-d is +è§Ĩ çĿĢ +. use +åı· 线 +Ġ åĽ¾ +çĹ ° +Ġhy g +( row +. Component +å·² 被 +çļĦ çݰ象 +åıijå¸ĥ çļĦ +æĭį äºĨ +ĠS olid +be it +ĠC ann +ĠF el +ĠLabor atory +_t x +\\ \\ +ï¼Įä½Ĩ åį´ +çϾ ç§ij +ĠQ String +åĴĮ 管çIJĨ +ĠM illion +ï¼Į æĢķ +Ġscient ist +mod ules +Ġte ens +ĠMet ro +S afe +Ġ' ../ +为 åĩĨ +Ġpast a +ĠD at +read ing +è·¯ çͱ +éĴ¢ çIJ´ +åĮºåĿĹ éĵ¾ +ä½İ 温 +åįģåĽĽ 竳 +Ġup s +Ġalbum s +Ġgram mar +.st d +å¸ĪèĮĥ 大åѦ +[ p +Ġre ass +举 æİª +it ime +æĤ² 伤 +U CT +åIJĮ è¡Į +sp in +(f ilename +弯 æĽ² +L iteral +Ġprol iferation +k now +ĠAcad emic +ĠR ice +Ġchar m +éħį éĢģ +Ġcha os +è¿Ŀ 约 +Ġatt ractions +Ġacc ent +åĽŀ 顾 +Ġch ick +Ġlook up +ĠT C +æ°¨ åŁº +ĠOut door +ĠCirc le +ĠCra ig +èµ¶ åΰ +Ġemphas izes +Ġ åIJ´ +è¿ĩ 渡 +it ored +æŃ¥ ä¼IJ +ï¼Įåΰ æĹ¶åĢĻ +è§Ĩ åĽ¾ +Ġsh aft +F ort +- ins +.H as +ĠG lo +ĠCh arg +aug hed +Ġver se +Ġstim ulation +å°¼ æĸ¯ +Ġb ikes +Ġp ec +com put +仪 表 +ĠC ategories +Ġ æµ· +Ġpa ired +缩 çŁŃ +ĠConst ant +åĽĽå·Ŀ çľģ +æł¼ æŀĹ +ĠNurs ing +ç¦ ¾ +Ġ ç½Ĺ +fl am +å°Ĩ ä»ĸ +ï¼ģ è¿Ļ +ĠRes et +ï¼Į å¢ŀ强 +人 åĿĩ +Ġste al +ĠH OLD +arcel ona +Ġv inyl +佩 æĪ´ +g re +ĠG rey +æľª ç»ı +è½® èĥİ +å°±æĺ¯ åľ¨ +Q uality +Ġal i +ĠRet rieved +St ation +è£ģ åΤ +Ġ* ( +(" . +ud son +ĠG aming +ĠEffect s +{ sec +Ġ" -- +å°ļ 书 +ĠJ oint +é¥Ń åºĹ +åĪĹ è½¦ +女 æľĭåıĭ +åĿļ å®Ī +/ i +` . +é£İ åIJ¹ +ä¸ī 次 +ĠH ack +å¤ĸ 壳 +( req +ili ary +Ġpol ym +ra pped +uck er +à ¬ +Ġt unnel +m ount +å®ĥ们 çļĦ +说 èµ· +Ġshift ed +亲 æĪļ +E asy +满 æĦıçļĦ +Ġthr illed +æĥ « +Ġlift ed +Su ite +Ġimpact ed +ï¼ļ æīĢè¿° +oubted ly +_re place +ĠT ex +Ġair line +è¿Ľ åĮĸ +Ġ. / +Con v +ç³Ł ç³ķ +W P +åħ¥ ä½ı +è¡į çĶŁ +éĤ ij +æ³° åĽ½ +TELE PHONE +涨 å¹ħ +Ġbe ating +ä¸Ģ æĿ¯ +v p +Ġsuper vision +Ġneed le +,ä¸į ä»ħ +å¼Ģ åѦ +Ġposition ing +Rober t +Ġt d +Ġ éļıçĿĢ +m argin +ĠV erm +âķ IJ +le arn +建çŃij çī© +åij IJ +Ġpharm acy +ĠCommon wealth +Ap pe +ĠN V +æĢİä¹Ī åı¯èĥ½ +太éĺ³ èĥ½ +ä¸į é«ĺ +rou ter +ãĢĤ å¹¶ +Ġvan illa +å¤Ħ åľ¨ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠ +ä¸ī个 æľĪ +Ġcaut ion +ç¾İåĽ½ çļĦ +éĥ½ ä¸įæĺ¯ +åı° éĺ¶ +Ġde bris +\ subsection +æī Ľ +Ġinter pol +详ç»Ĩ çļĦ +Ġdec ode +Ġrenown ed +AR G +Ġg rap +ou rier +ภ² +åĽº ä½ĵ +Ġadministr ator +åĿı è´¦ +ĠN ep +Ñ Ĭ +Ġt a +аР² +ç®Ģ æ´ģ +_ keys +th al +æĺİ å¹´ +n ings +Ġnot ified +鼶 ä»¶ +un def +Ġmerch andise +og s +'] )) +_TR UE +ç§° ä¹ĭ为 +两 åıª +R M +åĪĨ åħ¬åı¸ +溶 åīĤ +åľ° åľ¨ +.s wing +it ational +ric ing +A ud +.M odel +oster one +æķĻèĤ² çļĦ +è¯ § +èĸª éħ¬ +Ġut f +æĪĸ å¤ļ个 +_ left +_T IME +ĠFif th +ĠUs ually +æ°¸ ä¹ħ +éª ı +_s end +ĠU ntil +at ivity +ĠLeg isl +åĺī 宾 +个 åĪ« +ç»ı è´¹ +çľĭ 好 +h ist +ĠWay ne +ä¸į æĺİ +ĠBe havior +Ġam big +on z +ĠP and +ĠMor ris +ĠAR ISING +QU AL +ĠX box +ĠI E +çݰéĩij æµģéĩı +è·¯ éĿ¢ +Ġappropri ately +Ġexam s +Ġsear ched +ãģĹ ãģ¦ +ĠW a +ï¼Įå¹¶ 没æľī +çͲ éĨĽ +æīĭ æ³ķ +Ġspecial ty +äºĨ ä¸ĭåİ» +Ġur i +ĠFed eration +è´Ł éĿ¢ +ĠB apt +ï¼Įæľī æĹ¶ +\ big +ï¼Į ç«ĭåį³ +ĠPro vider +éŃ ģ +ĠHe aven +_c all +- all +ĠA aron +å¤ļ 项 +çϾåĪĨ ä¹ĭ +Ġred emption +ĠI an +ab stract +ãĢģ 以 +ï¼Į åĮĹ京 +Ġl icensing +it ol +çİĭ æľĿ +/j avascript +Ġspec ially +Ġsh ades +IR ST +ï¼Ī åIJ« +col lect +ate ur +åѦ æľŁ +Ġf d +epend encies +ĠAd obe +ĠCoun ter +åĨľ 产åĵģ +Ġ ï¼ģâĢĿ +v n +åIJį è¯į +-in f +ä»İ ä¸Ń +ons ored +ĠSet up +_e cho +he at +Ġneglig ence +ĠColl abor +è¿Ľä¸ĢæŃ¥ çļĦ +认为 æĺ¯ +æĸ° 建 +Ġhospit ality +ias m +Ġunt o +ubb ed +ED IT +\ section +Ex ists +Ġback yard +Ġ æŃ¤æĹ¶ +DE FAULT +书 æĪ¿ +Ġteasp oon +(s rc +n ail +è¯Ĭ çĸĹ +Ġtal ents +W ORK +-b ody +ç§ij æĻ® +Ġh ind +Ġc ents +Ġenter prises +lim its +Ġtouch down +æĮ¥ æīĭ +åĩº 声 +åľ¨ 使ç͍ +.A re +ne red +m ock +ĠH amp +ï¼Į åı¤ +ĠArch ives +ĠArchitect ure +Ġder ive +åŃĺ è´§ +Ġp ale +Ġdon or +um ar +书 åĨĻ +и е +ĠPal ace +ĠD est +ĠTurk ish +{ r +çIJĨ ä¼ļ +è´Ń æĪ¿ +ï¼Į æİ§åζ +çµ ® +.app ly +app le +Ġd as +åįł æľī +Ġpuzz le +轨 迹 +Ġ( . +rient ation +k u +is ible +ï¼ļ ï¼Ī +Ġdent ist +Ġiter ator +itt en +åİ¿ å§Ķ +Re ceive +Ġhome owners +ĠR M +ãĢĤ é«ĺ +ĠNOT E +Sim ilar +Ġchar ming +å®¶ å±ŀ +æľī 害 +ï¼Į å¢ŀåĬł +- ed +çĶŁ æķĪ +Pl ot +Ġp ools +çļĦ é»ij +Ġconspir acy +åı¸ 令 +Ġmail ing +ãĢģ 马 +çļĦ æİ§åζ +[ id +Ġ åħ¨ +ä¾ĽåºĶ éĵ¾ +ĠB uilt +æ²³ æµģ +( Object +[ / +Ġ 使ç͍ += c +ev es +æ´¾ 人 +ĠM AT +ĠCont roller +olut ely +th a +Ġ[ ** +çŃī æĸ¹å¼ı +ĠB os +çĤ¹ è¯Ħ +ĠPub lishing +à µ +L AN +çº ¬ + ģ +( {\ +åįĹ åĮĹ +ĠEx pect +Ġintrodu ces +ĠS ud +Ġassist ed +omit empty +ĠWH ETHER +Ġ 飩 +æĭ¿ ä¸ĭ +åı¹ æģ¯ +Ġ< ? +Ġmagn ific +M ary +Com mit +æ² ģ +P i +å¤ĩ ç͍ +ï¼Ł ãĢį +Ġland ed +Ġtou ches +åĨħ åľ° +Ġstr ide +æīĢæľī 人éĥ½ +æĸ¹ éĴĪ +ĠO B +d id +Ġb od +Ġcall er +ä¿ ŀ +Ġassum es +_ AC +çϽ èī²çļĦ +} ). +æĥħ 人 +Ġn ested +M el +Ġmin us +çĭ® åŃIJ +Ġfor k +ah l +Ġment ions +ĠM es +Ġalloc ate +åı¯ä»¥ 说æĺ¯ +æľĢ å°ı +ï¼Į åΰäºĨ +ï¼Į å°ij +I SE +ĠD S +æĪ ³ +è¯į æ±ĩ +æ´Ĺ åĩĢ +ot on +ĠGr iff +è´Ł èį· +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +_IN VALID +, åºĶ +ĠCl ar +reg n +Ġdi agonal +Ġrecept ors +夸 å¼ł +s pecial +ĠP ant +æĸ § +box ed +çIJ ¦ +çļĦ æĪĺ +éĤ£ æĹ¶ +Ġtag ged +æŀĦ ä»¶ +æİĴ è¡Į +ĠColl ins +Ġbra ve +è¦ģ æĬĬ +广 éĺĶ +ä¸Ń åħ± +Ġenhance ment +æłij æľ¨ +è¹ Ħ +Ġk its +Ġre ck +_s rc +ä¸İ åħ¶ä»ĸ +é¦ĸ éĥ½ +æĸ¯ ç§ij +ĠCol on +å¿ĥ 头 +ast ics +E nergy +ĠCr ime +]\ ] +ä¸į å®ľ +- X +aint ed +è½½ ä½ĵ +For ward +F und +Per haps +Ġple a +ĠH end +èģĶ ç»ľ +Ġch i +äºĮ å¹´ +ot ics +Or d +Ġfat ty +h ook +unt ed +ï¼Į åĨ² +T I +å¨ģ å°Ķ +Ġautom otive +è´Ł è½½ +Ġvacc ination +åģļ è¿ĩ +è´ ¬ +em perature +ä¸Ģ è¾ĪåŃIJ +ri ors +æīĵ æī® +Ġout lets +éĥ½ æĺ¯ä¸Ģ +O s +f y +(b uffer +çļĦ é£Łçī© +. per +èĤ¡ æľ¬ +ĠExt ension +Ġexhib its +æ°´ 管 +Ġachieve ments +pre ced +æķ° çϾ +- key +çļĦ ä¸ŃåĽ½ +ĠH em +çļĦ åĨħéĥ¨ +ĠB S +ĠSet ting +man ager +Ġas leep +, åħ¨ +ĠP ent +æĢ§ åij½ +A U +Ind ust +Ġex empt +讲 座 +äºī 夺 +æIJº æīĭ +å¿ł è¯ļ +Ġsqu ares +. ID +Ġeduc ate +Ġl aughed +_m b +ĠR oof +construct or +Ġb anned +ud es +Ġtrans itions +åĿIJ çĿĢ +Ġt rivial +çIJ ¢ +éħį æĸ¹ +uk i +p riv +ĠT odd +min us +sw ers +d ump +Ġtim eline +容 纳 +Ġ" : +ĠK night +Ġo ch +Null able +Tr igger +ĠT D +m itt +åĩº 身 +æ£ ĺ +B as +é n +l ar +Ġb race +ä½ı éĻ¢ +iterr anean +äºĭ å®ľ +âĢĿ ä¹ĭ +i ates +åįĩ é«ĺ +int eg +Ġu gly +Ġsaf egu +æĺ¯ æĪijçļĦ +æ§ Ľ +Ġ[... ] +Ġpract itioners +ï¼Į çľģ +Ġh orn +èĩª åľ¨ +_ html +E mb +Ġm ant +J ournal +Ġ' $ +Set up +Ġappoint ments +ĠC ris +è§ģ ä»ĸ +Ġre levance +ĠPro gress +ï¼Į å¾® +/m aster +AB C +Ġwel comed +Ġl enders +W alk +C trl +æĬķèµĦ åŁºéĩij +ï¼Į åΰåºķ +Tim estamp +Ġher bs +ï¼ĮæĹłè®º æĺ¯ +b order +Ġc argo +es pecially +St d +Ġdeterm in +åįģäºĶ 竳 +Ġaccum ulation +ri vers +Ġco pe +å̼ 为 +aj ax +ĠGa ussian +ĠK id +Ġh ass +" \ +. connect +éľ² åĩºäºĨ +Ġear liest +ĠAgric ulture +ç¼ ļ +Not es +ï¼Įä»ĸ ä¹Ł +ANN EL +p adding +çļĦ æ¯Ķä¾ĭ +æĮ¤ åİĭ +Ġche f +S chedule +æĶ¶ å½ķ +ĠIn come +çĻĮ çĹĩ +Ġor b +ãĢģ äºĶ +Ġble eding +æķ´ å½¢ +ĠR unning +Ġcompet ent +åĪĿ å¿ĥ +ov able +Ġpe aks +.get Element +Ġdefe ated +Ġarchitect ural +# { +ĠS ame +B o +S ervlet +Ġwh it +æħĪ åĸĦ +ĠAct ually +ĠValue Error +è§£åĨ³ éĹ®é¢ĺ +ãĢģ èĬ± +ĠEv ans +åľ° çĭ± +Br and +Ġcl ay +_C OMM +Ġf ridge +æ¡ ĵ +Ġped est +ass y +Ġsimilar ity +Ġfil tered +. Int +л и +Ġhead quarters +æĸ¹ ç¨ĭ +Ġdraw ings +-p art +ç͍ èᝠ+该 å¦Ĥä½ķ +. search +ï¼Į åĪļæīį +ãĢĤ åħ·ä½ĵ +æ´» å¡ŀ +ãĢĤ æ¯ķ竣 +ç͍ åľ° +ĠT ORT +Ġatt itudes +ĠWeek ly +ĠP un +Ġmag azines +Ġcond itional += ${ +on line +Ġannoy ing +ĠFore x +ĠMar shall +Ġcon gress +are l +æĽ´ é«ĺçļĦ +Ġsh rink +座 ä½į +Ext ensions +Ġsc attering +è¿ĩ å¾Ĺ +SE L +å·® ä¸į +ĠR and +ï¼Į åħ±åIJĮ +线 æĢ§ +æĺ¾ èijĹ +t rain +. select +_ irq +åıį æĬĹ +åµ ´ +ä¸ļ åĨħ +çļĦ å¼Ģ +Adv anced +åĪĽ ç«ĭ +ĠPsych ology +w ould +åŃIJ å¼¹ +AN C +è¿Ļ çĤ¹ +ĠN am +Ġridic ulous +AC HE +b an +âĢĿ ï¼Ľ +}} _{ +ãģ¾ ãģĻ +æĥ³ åΰäºĨ +åī§ æľ¬ +l it +N ER +ograp her +åĿļ 强 +ĠInter face +th an +Ġdes cript +Ġrel ie +Ġdr um +ç»Ļ åĩº +å°ı æĹ¶åĢĻ +ĠGr an +q quad +Ġ å¤ļ +ip art +åķĨ åºĹ +æľŁ åĪĬ +sec ure +out es +å¿ĥ çĸ¼ +( se +Ġg y +åij ķ +Ġurg ent +CL K +Ġam p +IN CLUDING +Ġjournal ism +Ġansw ering +Ġsh ifting +ĠT N +Ġun ve +Ġfree ze +Ġcompar isons +ĠON E +Ġnit rogen +Ġm ud +Ġpat ches +Ġinhib it +re hend +ãĢĤ 第ä¸Ģ +ĠM ason +sh arp +hes ize +ï¼Į æ²Ī +çϽ éħĴ +Ġl ender +常 æĢģ +_ IP +ĠWh atever +æľīäºĽ 人 +Ġr ay +ï¼Įå°± ç®Ĺæĺ¯ +c ity +ç¹ģ èᣠ+, C +çī ¡ +ĠSh opping +int eger +Ġbr ide +ï¼Į 认为 +.index Of +æľ¬å®ŀç͍æĸ°åŀĭ çļĦ +ï¼Į æŀľçĦ¶ +Ġcry ing +ï¼Į ä½įäºİ +Ġret riev +Ġapprox imate +ĠDub lin +Ġch ron +LE T +US H +he res +it ated +æĹł å½¢ +è¯ģ çĽijä¼ļ +å°ı æĺİ +Ġforest s +w ent +æĭ Ĥ +模 仿 +Ġelect rons +å¤į åħ´ +èµ° åľ¨ +, ä¸įèĥ½ +-s ub +Ġse g +åĮĸå¦Ĩ åĵģ +ĠCon cept +Ä Ļ +Ex it +Ġj Query +æĭ § +æĢĿ è®® +Ġir r +ä¸Ń å±± +f amily +Exp ress +cl er +_ ph +Sh ift +çĸ² æĥ« +Ġpro st +onom ous +å¤ĸ ç§ij +çĿĢ ä½ľ +åĨį æĿ¥ +l ades +åħ¸ åŀĭçļĦ +) s +ĠDou glas +Ġenerg ies +- not +ic ion +æľīåħ³ éĥ¨éŨ +Ġgram s +_ AS +å°Ķ å¾· +Ġ ib +b ian +Ġsp ite +è¹ ¦ +审 åΤ +åı¸ å¾Ĵ +度 è¿ĩ +ãĢĭ ï¼ļâĢľ +éĹ´ éļĻ +Ag ain +struct ure +Ġfor ty +ai res +åύ å®ĺ +çĿģ å¼Ģ +çī¹ æĦı +Test Case +lect ric +Ġem it +åĸľ æĤ¦ +:: :: +w indows +op ard +éĻĦ ä»¶ +åύ 械 +f ar +åıĭ 好 +. htm +åIJİ æĸ¹ +Ġc af +const ant +Ġprov es +Ġnon etheless +loc ale +çα åĽ½ +_r un +Ġ åĮĹ京 +ï¼Į 说æĺİ +Ġ æľĢåIJİ +(t mp +å¿ĥ åºķ +ot er +che stra +Ġexam ining +o ct +åĽĽ å¤Ħ +Ġarg v +Ġ# { +C y +èİ ĵ +ĠGener ation +ĠRec ent +Ġp ork +ab etic +Ġd ign +l arg +Ġd ans +ick y +em bers +æ² ¦ +_ vector +ĠCor ps +Ġfoot print +g reat +Ġm apped +Ġpal m +æĥ³äºĨ æĥ³ +is o +Ġmem or +ï¼ĮæľĢ 好 +ĠAgain st +ĠF loat +ĠSt orm +å¾Ģ ä¸ĭ +ĠMit chell +flam matory +Ġcomment ary +ä½ı 宿 +Ġintern ationally +Ġfurn ished +itt est +ĠMad ison +è¡ Ļ +ĠSur v +Ï İ +Ġdead ly +Ġcancell ed +ĠTh ai +æĹģ è¾¹çļĦ +' $ +åĪĨ æĺİ +çĶ Ħ +, çľĭ +EM PL +EG IN +Ġprevent ed +åıĸå¾Ĺ çļĦ +Ġdisc lose +i q +Ġsmooth ly +ä¸Ģ åIJij +ĠVal ues +代表 人 +ident ity +d river +æĺ¾ç¤º å±ı +_ io +ĠC arn +Ġpursu it +Ġh ockey +}} , +ãĢĤ 天 +æĭ Ń +_ch annel +ï¼Į é£ŀ +ab lished +误 ä¼ļ +us hers +Ġdest ruct +( image +Ġg rief +ï¼Įå°± èĥ½ +ĠU b +Ġdon ate +ĠQu ote +ĠR ic +è¹ Ń +ï¼ĮåIJĮæĹ¶ ä¹Ł +ĠPal m +ĠCh ron +âĨ IJ +å°½ çļĦ +Ġdr ill +Ġtempor arily +çļĦ è§Ĵ度 +ĠT rial +Ġ å¤ı +ä¸İ ä»ĸ +ĠSk ill +åħ³èģĶ äº¤æĺĵ +ãĢģ éĻĪ +å´ Ľ +.s ource +ĠR y +OL UM +qu ant +çŀ ¥ +ĠK el +Ġslic es +IL TER +åĻª éŁ³ +çķ Ķ +Ġplan es +亲 å¯Ĩ +Ġinf ant +h p +ĠH O +Ġgrand mother +Ġfun eral +ï¼ļ D +> () +ĠRec ipe +Ġbal lo +im its +åIJ¦ 认 +Ġp g +io let +Ġface book +Ġour s +[ c +ãĢĤ æĽ´ +Ġcontext s +, D +[ assembly +, omitempty +E s +ĠRob in +Ġev olving +èģĶ åĬ¨ +ç£ ħ +ĠUlt ra +R D +ĠCon sequently +æ£ º +ĠSt ev +è¡Į æĿİ +Ġpars ed +æĸ° åħ´ +ä¾ĭ å¤ĸ +å·²ç»ı æľī +_s c +Ġspir its +åľ¨ ä¸ĭ +_c ore +iz a +æµ· ä¸Ĭ +ĠAl bert +åIJİ éĿ¢çļĦ +ï¼Į ä»·æł¼ +ä¸Ģ æīĭ +æŁ ł +Ġtr aged +@ interface +ĠF ill +- un +el if +Ù ĥ +ĠG ill +-d es +.. \ +rat ulations +表çݰ åĩº +.m ake +Ġr t +Ġdress es +ĠD al +Ġgl ance +å¥ İ +é»ij èī²çļĦ +åĩı éĢŁ +次 çļĦ +Ġ 为äºĨ +em en +ement ia +Ġkn ees +é¦ĸ å¸Ń +Ġhapp ily +Ġweight ed +Ø ¹ +Ġre leasing +Al tern +ĠTai wan +ĠArab ia +è¯Ī éªĹ +éĴ ¾ +å¿« è¦ģ +礼 è²Į +Ġex pr +çļĦ è¿Ļ +greg ation +ĠN an +çŃ · +ser ial +ĠPub lished +æľĭåıĭ åľĪ +Ġso y +_s ervice +r n +ing e +\ theta +-com merce +æľī çĽĬ +åĽ½ éĺ² +çıŃ ä¸»ä»» +Ġtrain er +ced es +æīĭ 游 +Ar r +Ġle isure +ĠSurg ery +é«ĺ éĵģ +ï¼Į éĿĴ +åĢĻ éĢī +åħ¥ åѦ +ĠTe aching +éĶ® çĽĺ +æ°´ åĪ© +çī¹ å®ļçļĦ +Ġwel coming +Ġwealth y +æĹı çļĦ +ĠDef inition +ĠChar acters +Ġwh ites +ï¼Į å¸Ĥ +å®¶ åĽŃ +View s +ĠPat ri +éĤ» å±ħ +row th +ĠT ow +ãĤ ¿ +ĠIN D +Ġb ail +åģ¶ åĥı +ĠAl pha +æī¾ 个 +Ġcount ed +Ġc el +sub ject +Ġdistingu ished +bel ie +å¹´ éĹ´ +ans hip +Ġpromot ional +ä½ ¬ +Ġtun ed +(" [ +Ġapp les +äºĶ çϾ +å͝ æľī +ĠH ab +ĠMed ium +ï¼Įè¿Ļ æĹ¶ +Ġdevelop s +ĠA uthors +Ġ å®ĭ +ĠInt o +好 å¤ļ +iss on +ene z +æĻ¯ 象 +irm ingham +ĠM ask +ĠDis count +éĴ» çŁ³ +åıĺ 为 +ĠLiver pool +çѾ åIJį +ä¸į 该 +i ang +ess a +æīİ å®ŀ +Ġpenal ties +f u +èº ¬ +Ġsell ers +Ġb a +ĠE gg +ark ing +ĠZ oom +åºĶæĶ¶ 账款 +U Int +è§ģ è¯Ĩ +æĬ± æŃī +an ic +P o +ç²¾ å¯Ĩ +Ġto ps +am as +Ġ åIJ¬åΰ +çļĦ éĴ± +ey e +Inst ruction +_IN IT +S at +- ac +åĪĽ åĬŀ +åįĬ 导ä½ĵ +pro file +ç» ¸ +En joy +Ġverb ose +S calar +ĠSe lection +Form atter +ĠDis cover +ä¸į 容 +ĠG ene +åĩ¹ æ§½ +她 åľ¨ +éĺ² èħIJ +is i +re act +ST M +æĺŁ çIJĥ +os er +Ġneg lect +at cher +ic iary +P ERT +_b atch +m ust +åİ ® +æł¸ æŁ¥ +Ġmess aging +è¦ģæ±Ĥ çļĦ +ĠPl ayers +sc opic +çģ¿ çĥĤ +å°± è¡ĮäºĨ +Ġware house +è¯Ń æ³ķ +col lection +em por +å¾ģ æĶ¶ +Ġnewsp apers +æĻ®éĢļ 人 +. Event +R otation +Ġ Ùħ +äºĨä¸Ģ åı£ +Ġprotect s +ä¿¡ æīĺ +Ġ äºİæĺ¯ +è½ § +consc ious +pro b +Ġfar ms +è¿Ļæł· åģļ +Ġent ers +æķĻ åłĤ +ç¢İ çīĩ +om eters +è¿ĺ å¾Ĺ +.ex ists +/ " +d jango +ĠGreat er +å®ŀ æĪĺ +çļĦæ°Ķ æģ¯ +ĠP ER +ĠC av +Ġx x +Ġfix ing +ĠInter ior +æĬķ å½± +ĠBo ys +rel ative +éŨ åºĹ +p ersonal +åįģåħŃ ç«ł +ĠM aj +Ġth rive +ĠEmp loyment +Ġl b +åζ åĬ¨ +ĠWorks hop +ĠWi Fi +ĠPitt sburgh +Ġover d +ãĢĤ ä¹Ł +ĠRef orm +èij¡èIJĦ éħĴ +Ġshock ed +åĨħ å¿ĥçļĦ +Ġ æĢ» +ĠKen ya +Ġgovern ed +Ġorg ans +AT T +Ġcrit ics +ĠGener ated +è·ij äºĨ +Ġhe lic +é¦ĸ åıij +Ġqual ifying +F N +Ïģ ο +ĠCl ay +çĭIJ çĭ¸ +Ġclar ify +v id +èµ° åIJ§ +Ġ$ (\ +åĬŁèĥ½ çļĦ +ĠU pper +ä¸ī åĽ½ +ä¸į ç¡®å®ļ +Ġback pack +麦 åħĭ +çļĦ å¾Ī +ĠAtt ribute +è¦ģ åģļ +Ġswit ched +K B +ĠE ST +ĠBirth day +ãĢģ ä¸Ĭ +æ°¸ æģĴ +Ġp est +Ġpropos ition +Ù Ĥ +æ³ķ æ²» +Ġl enses +ill ary +IN ST +lock s +Ġcred ibility +lis hes +Ġcov ari +al ph +Leg al +å°ı éķĩ +Ġsn ack +æĹ© æĻ¨ +Ġt et +Ġspac ious +ï¼Į便 æĺ¯ +èĩ³å°ij ä¸Ģ个 +äºĭ åħĪ +ï¼Į å®ļ +im als +ring s +Ġtast es +Ġsen iors +(type of +AAAA AAAA +Ġviol ated +太 å¤ļçļĦ +ï¼ĮåĨį æ¬¡ +Ġback s +% s +ĠFe el +F iled +te es +W ar +Ġre loc +ĠN ord +ï¼Įæĺ¯ åĽłä¸º +ä¸į ç»ı +- cont +Ġanalyst s +ĠOTHER WISE +A meric +Ġsnap shot +Ġhon ored +ãģ Ŀ +度 åĴĮ +Support ed +e u +硬 çĽĺ +inn amon +-n av +ĠCol omb +Ġpot ent +Ġpot ato +Pre view +-g ame +Ġmedic ines +缸åħ³ éĥ¨éŨ +æ»ĭ åij³ +Ä ĵ +) }$ +æ¶ ħ +ĠRec ogn +.b tn +对 èĩªå·±çļĦ +ĠTru ck +ĠC ub +æ£Ģå¯Ł éĻ¢ +åı£ è¢ĭ +ĠP ope +ĠE sc +ĠA Z +Ġ$ | +W ritten +Intern et +(b ase +Ġfound ing + ¿ +åıij åħī +Ġsubject ed +ĠEm ma +Ġearth qu +Ġform ulation +Ġ Ñĥ +ä¸Ģ åįĥ +emet ery +å®īåħ¨ æĢ§ +gg ed +h appy +ï¼Įè¿Ļ å°± +Ġb ored +.c a +Ġ第 åħŃ +æľī 两个 +ï¼Įè¿Ļ ä½į +-gener ated +Ping back +ĠMain tenance +æĶ¿åºľ çļĦ +女 ç¥ŀ +ï¼Į 表示 +D am +UT O +ä¸į 顾 +Ġprov ing +u pt +Ġremember ing +èĴ¸ åıij +pl t +ĠAny one +管 å®¶ +ãĢĤ ä¸ĭéĿ¢ +èµĦ åĬ© +Ġr ides +å© ¢ +M Y +Ġf right +è¶Ĭ é«ĺ +_c fg +( def +æŃ ¹ +åĮ Ī +ud ent +ear ly +ï¼Į æĺĵ +the ning +ĠF ried +P et +被 åĬ¨ +ï¼Į è¿Ľåħ¥ +Ġins ured +åħ¥ ä¾µ +ĠT on +Ġtomat o +ĠSte am +æĪĺ éĺŁ +Ġcontrovers y +Ġre construction +æķ°æį® æĺ¾ç¤º +ç½ļ 款 +ãĢģ èĢIJ +头 èĦij +ãĢĤ ä»Ĭ +ĠF al +æĪ· åı£ +-f ield +Ġsevent h +_ control +Ġar ter +ĠG host +och astic +éĺĪ å̼ +ĠStart ing +éħ ¥ +Ġtouch ing +OP T +un ing +åĪĨ æĪIJ +Enumer able +_ local +æĽ´ 容æĺĵ +ch y +ĠLine ar +Ġmer it +æī ³ +ĠT an +åĸ ĩ +om o +Data Source +_e lement +æī£ éϤ +Ġres ervation +ï¼Į åŃĻ +Ġad orable +ra wn +ĠY ang +ï¼Į åĬłåħ¥ +Ġinhab it +hand ler +por ter +港 åı£ +骨 头 +ĠArt ist +.M ap +ï¼Įå°± è¦ģ +çļĦ ä»»åĬ¡ +ä¸į ä¸Ģæł·çļĦ +Ġden otes +åĩł 人 +miss ible +ĠReg ular +it les +ãĢĤ 人 +Ġcre ep +Bel ow +t ri +r ift +顺 çĿĢ +Ġpri zes +éĿĻ èĦī +çļĦ éĩij +Dis claimer +åı¬ éĽĨ +Ġenh ancing +ä¸Ń äºĨ +æĮĩ çĿĢ +( op +' T +ĠV ehicle +ĠRev enue +ãĢģ çŁ³ +Ġshel ves +认 羣çļĦ +Ġexch anges +ä¹ĭ æĹħ +约 为 +åĢ ļ +大 æµ· +éĢļ åŃĶ +Ġspons or +å¤ľ éĹ´ +ĠDep uty +Ġanx ious +Ġt an +åĩĢ èµĦ产 +ch air +被 æīĵ +çĿĢ åĬĽ +rom agnetic +ĠSpe aker +. inter +ĠS even +é¡¶ 端 +ĠCamp us +常 è¯Ĩ +Ġst arter +L I +ĠA thlet +Ġtrick y +AR I +å¾Īå¿« å°± +l v +以 æŃ¤ +ä¸ĭ å±ŀ +ĠRid ge +æľĪ 亮 +ĠParam eter +ç²ī ç¢İ +ĠH az +Ġcomm ut +Ġprem ier +è¯Ħ éĢī +ĠS B +Ġdis g +ey er +ĠW riter +åijĬè¯ī ä»ĸ +æ»ij åĿĹ +_ raw +Ġur ge +_FORM AT +翼 翼 +æ°´ æĻ¶ +Ġdegrad ation +M AN +Ġc attle +个 å°ıæĹ¶ +ä¸į éĢļ +åIJį åı« +Ġfilter ing +/ her +r ar +çļĦ åĩºçݰ +ä¸ĭ æīĭ +-sh adow +ĠSw ift +Ġpl ur +æµıè§Ī åύ +Ġdis par +çļĦ女 åŃ© +oci ation +? , +ĠM asters +ĠG OP +举 éĥ¨ +Ġlog istics +Q ual +int endo +ãĢĤ åį³ +.Write Line +çļĦ å±± +梳 çIJĨ +ĠNet works +ä¸į æ¸ħæ¥ļ +Ġtradem ark +Ġexhib ited +ust ers +ochem ical +S cal +Ġathlet ic +angh ai +Ġw ars +è¾ ķ +é£Ł åłĤ +Ġ/** < +èĩª ä»İ +Ġimpl ant +äºĨä¸Ģ çĤ¹ +n il +ĠAn c +Ġam bit +Ġhero es +å®¶ åºĦ +ä¸Ĭ çľĭ +ĠJ erry +ĠS oul +è¿Ļ æĹ¶åĢĻ +ik o +Ġinev itable +Ġlaugh ing +å¤įåį° ä»¶ +ï¼Į åıĸ +ĠP s +æĸĻ çļĦ +rid es +ï¼Įä¸Ģ ç§į +Ġprot otype +éķ¿ åŁİ +ag ne +k w +Ġus eless +ĠBr anch +Ġm ethyl +ĠC bd +ï¼Įæľ¬ åıijæĺİ +ancell ation +詹 å§Ĩæĸ¯ +> / +is y +ĠL D +ĠSe an +ãĢĤ æľĢ +åħļ 建 +t race +轿 车 +Pe er +ĠT s +by e +ä¸į éĢĤ +åĶ® ä»· +ĠH orse +ï¼Įä¸Ĭ éĿ¢ +U A +Ġre imb +Ġdem ocratic +å¯ ĩ +ĠRog er +æĿ¥èĩª äºİ +ãĢĤ 大家 +åı¯ä»¥ æł¹æį® +èIJ ± +in ical +æĶ» çķ¥ +Ġfirm ly +wide hat +es ters +害 人 +ĠS yn +Ġarriv es +M ike +ĠIN TO +ç͍ 人 +Ġas pir +Ġ ou +Ġst adium +ä¸Ģ个 人çļĦ +IF I +} -\ +ĠMur ray +l ene +身ä½ĵ çļĦ +Ġten ant +ĠN AT +Ġrem ot +æľī åĬĽ +åı ¨ +Ġkind ness +Ġse xy +æ· ¹ +ï¼Į ç»ı常 +çĺ « +ĠD egree +enc oding +âĭ ¯ +ĠP eters +æ¸ħ æĸ° +åįĥä¸ĩ ä¸įè¦ģ +Ġnut ritional +æ²Ļ æ¼ł +åĢ ĺ +/ app +带 çļĦ +-ch ild +离 ä¸įå¼Ģ +Ġcert ificates +Ġfin ances +, ç¡®ä¿Ŀ +ĠM oscow +Ġfaith ful +ĠWire less +ra is +æķĻ ä¼ļ +æŀģ 端 +亲 çαçļĦ +å¾Ģ æĿ¥ +ĠExplore r +Ġse ating +h ole +ç»ıèIJ¥ æ´»åĬ¨ +泪 æ°´ +åѦ 士 +éĻĪ è¿° +ç¥ Ģ +Ġ æŃ¤ +D ue +, åħ¬åı¸ +çºł ç»ĵ +çĨŁæĤī çļĦ +Ð ¶ +ç²ī æľ« +.t witter +转åĮĸ 为 +åıĺ éĢŁ +.ex ports +Ġcru el +Ġhabit at +F r +Ġbit ter +ï¼Į äºĨè§£ +-b l +没 æ³ķ +read only +æľīåħ³ è§Ħå®ļ +ie val +ĠPart s +çŁ¥éģĵ èĩªå·± +åľ¨ æĪij们 +ĠI con +Ġex empl +ä¸į 符åIJĪ +ä½ł è¿Ļ +Ġutil s +æĢİä¹Ī åĽŀäºĭ +ç͵åŃIJ 设å¤ĩ +å·¥ä½ľ 室 +em ics +æŀģ 大 +log o +Ġtast y +am el +æ°ij åĽ½ +åΰ è¿ĻéĩĮ +. th +- Y +ĠT S +带 ä¸Ĭ +ï¼Į èµ¶ç´§ +æĹł æĦı +Ġen er +éľ ĸ +ĠP le +æıIJ éĹ® +ig ion +UR RE +_g ener +åĽŀ æĿ¥çļĦ +å¥Ī ä½ķ +Ġrect angle +Ġven ues +Corn ell +éĶħ çĤī +ens on +ï¼ĮæĪij è§īå¾Ĺ +Ind ia +ï¼Įä½ľèĢħ æĺ¯ +å¤Ł äºĨ +Ġblog ger +åĮĸ è§£ +å¤ĸ 线 +éĺIJ è¿° +åı¦ æľī +ï¼Įåį³ ä¾¿ +éħ ® +Ġsystem ic +Ġresearc her +溶 è§£ +plic a +åıĤ è§ģ +æ°´å¹³ çļĦ +Ġperman ently +Ġbless ing +ĠR ou +ram a +[ M +ĠTh an +L IB +èĥĮ å½± +ĠInd ians +çŃĶæ¡Ī æĺ¯ +Ġb om +çī¹ ç§į +è¦ģ æ¯Ķ +æĢ» ä¼ļ +æĪij èĩªå·± +åįģä¸ĥ 竳 +Ġoccup ation +, æ¯ı天 +\ ", +T imes +è·ij æŃ¥ +ĠU l +缴 æµģ +oc ard +Ge ometry +ĠPr incess +s b +Reg ular +in herit +æ· ³ +Ġ æľĢ +ãĢĤ 没æľī +Ġun ions +éĺ İ +ä»» èģĮ +Ć Ĉ +Ġu mb +im ag +R ank +ĠT B +çıį çıł +M iddle +Ġgrat itude +Ġpe oples +æĥ³ åİ» +ï¼ĮéϤ éĿŀ +L earning +æĢ¥ æĢ§ +. Z +èĪ ¶ +ĠPRO C +Ġconcent rated +ä¸į å°ıå¿ĥ +Ġhes itate +注 å®ļ +Ġfif teen +Ġlearn s +ĠGover n +Techn ology +uff y +Ġl ug +( ä¾ĭå¦Ĥ +Ġre lied +ro ved +in is +ĠL G +ĠK aren +çļĦäºĭ å®ŀ +Ġflow ing +çķĻ æĦı +{d ocument +ĠS oph +大 楼 +_t ask +ĠOper ating +游æĪı çļĦ +it ary +æµĭ å®ļ +ro d +. aw +åļ · +çİĭ èĢħ +ĠCorn ell +Ġare na +Ġlearn ers +ĠK ath +管çIJĨ å±Ģ +Ġri vers +ĠS ie +Inst ead +Un ique +Ġelse if +çī¹ èī²çļĦ +ï¼Įä¸Ģ èµ· +ar ium +à § +ĠUlt imate += false +ĠL ost +Ġh r +åķĨ 人 +Ġgrad uation +ãĢģ 天 +ä¸Ģèµ· åİ» +verb ose +agn ostic +ãĢĤ èĢģ +Ġdesper ate +Ġ/* !< +_M SG +C over +åı¶ çīĩ +ĠSo on +Trans ition +M ust +ob i +ĠDis cussion +.R em +_c opy +M en +xff ff +ä½ł èĩªå·± +, g +ï¼Į 马ä¸Ĭ +J im +ï¼Į æŃ¦ +Ġg ri +.D efault +个 å°ı +ï¼Į æīĵéĢł +éĦ Ĥ +AY S +) ' +. os +è¶Ĭ 好 +are tt +t own +ä¹Łä¸į æķ¢ +è¿ĺæľī ä¸Ģ个 +çļĦ æĢ» +Ġintu itive +ä»»ä½ķ 人 +é£İ æ°´ +çļĦ 身份 +欧 åħĥ +ä¸ī åįĥ +log ical +Ġlegend ary +ote chn +ãĢģ ä¸Ĭæµ· +_s cale +ĠDep ending +ä¸į 好çļĦ +æľį 饰 +Ġc ube +çļĦ 红 +-f old +Ġ Å +Ġic ons +l ace +Ġcount ies +åĬ© æĶ» +Ġprob able +u art +All ow +æİ¥ åľ° +Ġawk ward +, ä¸ĭ +Ġd ar +æĪij å®¶ +Ġ 西 +ens ional +Ġg i +ï¼Į æľªæĿ¥ +çĽ ı +_st ats +Mult iple +竳 èĬĤ +Ġe book +.m ain +ï¼Į è·Ŀ离 +per or +ens ed +æīį æľī +Every thing +A Z +ĠU C +{ K +Ġste ering +F ramework +re ational +ï¼Į 鼷 + ´ +åķĨ åŁİ +ç£ ķ +âĢľ ä¸ŃåĽ½ +Ġauthor ization +Fin ancial +act ly +åħĪ åīį +ĠÂł ĠÂł +N othing +ri o +Ġen velope +g ary +çݯå¢ĥ çļĦ +ĠL arry +èļ Ĭ +ĠA round +åħĪ éĶĭ +ĠERR OR +res a +Ġcorrect ed +Ġassess ing +ä¸Ģ è¾Ĩ +re x +çī© èģĶç½ij +æĢ» å±Ģ +Ġill um +转 è½´ +å°ı ç±³ +é¢Ŀ 头 +ìĿ ´ +æį £ +/ K +大 èĩ´ +ĠC red +Ġenthus iasm +ï¼Į èĥ¡ +_re q +ï¼Į æĪIJ +è¦ģ æĥ³ +ight ing +F W +F act +ivari ate +èIJ½ åΰ +ĠLo ans +Y N +ä¸į è§£ +c od +M art +At om +å®ģ éĿĻ +Ġtop ology +Ġmar ry +ĠH V +ĠB achelor +Run ner +æ² Ľ +åīį åĪĹ +Ġg ods +éª ĩ +Ġreg ex +欢 åĸľ +ier ra +Ġfoss il +æĥħ æĻ¯ +大åѦ çļĦ +éĺ´ å½± +ä¸ĩ çī© +s q +ĠSp a +ID ENT +par ing +ï¼Į æĸĩ +ç¾İ åij³ +æĦı åĽ¾ +âĸ Ī +åĿ Ł +Ġle x +注åĨĮ èµĦæľ¬ +n is +ĠAppe als +æıIJ è®® +(' ./ +C AP +i ables +-h igh +ãĢĤ ä»Ĭå¹´ +ι α +Ġc ried +ï¼Į 产åĵģ +Me asure +æĸ½ å±ķ +Ġl ending +ĠJ a +举 èİŀ +Ġdis cre +åī Ķ +Ġemp irical +ï¼ĮæŃ¤ åĪ» +Ġd ire +Ġdisappe ared +ï¼Į åħ¨éĿ¢ +ia z +_L IB +ĠP rices +温 æ³ī +Ġcatch ing +ç¦ Ģ +没 èĥ½ +pl ies +åħī 线 +_p ool +â Ĥ +ĠCrim inal +H it +ag les +Cont in +åħ³ æĢĢ +éĢīæĭ© çļĦ +人 æĸĩ +Ġsince re +ç» · +æĬ¤ èĤ¤ +æľª çŁ¥ +ãĢģ ä¸ĭ +.s w +orth y +r ise +D er +ak y +ç¬Ķè®° æľ¬ +M ag +éĥ½ éľĢè¦ģ +preced ented +Ġfib ers +å°± åİ» +anch or +E q +ĠPar ks +ï¼Į å½±åĵį +ĠRedist ributions +_d ist +ĠA W +ac ies +åĮ ¿ +Ġcur r +çĶľ èľľ +Ġin herited +æĮī æij© +ub er +羣 çIJĨ +comp are +Ġsched ules +Ġrepl ies +s ound +ĠUn iverse +太 æŀģ +Ġ" @ +ा ठ+Ġe co +.s ql +_WR ITE +, ç»Ļ +ï¼Į 缮åħī +çģ¾ éļ¾ +Ġp ics +math sf +æĬĺ 磨 +æĢİä¹Ī åģļ +ĠMar vel +Ġreward ing +Ġappear ances +Ġdon ors +åı¯ä»¥ 使ç͍ +(p arent +im mer +ĠE le +æĮĩ å¼ķ +éĵ ² +ï¼Į对 æĸ¹ +af ood +Ġcontribut or +Decl aration +éĩij åĪļ +è°ĥ æİ§ +Ġeduc ators +ç§ijåѦ æĬĢæľ¯ +Ġelim inated +_ put +她 说 +æļĹ æļĹ +Ġan notation +æĭī å¼Ģ +æ±ī è¯Ń +Ġfort une +Ġdef in +ĠV ers +é t +âĺħ âĺħ +Ġp neum +al one +ĠA PP +ĠTest s +SE C +ï¼Į æĸ¹ä¾¿ +ĠF it +ï¼ļ æĪij +Ġt anks +åį ¤ +ĠSt ructure +çļĦ åħ¨ +å¨ĥ å¨ĥ +åĩ Ľ +/ ml +st rip +Ġcourse work +ĠEn sure +-d ec +urs ion +оР± +ï¼Į èĩ³ +ç³ Ļ +Ġto dd +åĪĨ æĶ¯ +Ġlo ops +prot obuf +/ % +çļĦ ä½ľåĵģ +ç«Ļ 起身 +Ġstrong est +Loc ale +Ġcyl inder +å¾® çĶŁçī© +.C lient +app ings +bb ing +ĠFurn iture +. Id +Ġcont ends +ãĢģ åĽ½å®¶ +ĠAdvis ory +ĠOr lando +Am ong +á Ģ +ä¿® è¡Į +Ġl ined +ener y +çϽ æĸij +D ynamic +Ġener get +æĪ· åŀĭ +æī¶ æĮģ +ï¼Į æľĿ +ä¸Ń ä»ĭ +ĠRec ipes +ĠD T +å¿į åıĹ +ĠL if +Ġdu ct +inc ial +Ġkick ed +Ġadjust able +åįģåħ« 竳 +ĠA verage +ä¾ Ħ +Ġprosecut ion +Ġsac red +ï¼Įæĺ¯ åIJ¦ +bor ough +åĪļ 好 +.Are Equal +Ġc ares +Vis ibility +Ġlater al +æ¯ı æľĪ +Al ign +-f ile +ç§ijåѦ éĻ¢ +ica id +r aska +æĭĨ åᏠ+åĨħ èĴĻåı¤ +Ġblank et +p ref +Ġn as +en es +st orm +Ġr m +Ġprot ests +çŃī å¤ļç§į +Ġje ans +ï¼Į被 åijĬ +Ġincomp lete +ĠMur phy +our cing +Ġinflu ential +æľī ä½Ļ +, éϤäºĨ +_f ields +Ġsport ing +ĠD MA +ĠGener ate +Stack Trace +Ġsurround ings +Ġsan ctions +D one +, é«ĺ +äºĶ 大 +误 å·® +ym e +D ATA +ĠP i +æĹ¶éĹ´ åĴĮ +åį«çĶŁ éĹ´ +ĠArk ansas +æįIJ èµł +车 主 +æķĪ åĬĽ +OB ILE +ï¼Į å°½éĩı +Ġ ä¹Ł +dis abled +dis able +ib les +, 主è¦ģ +ç¿¡ ç¿ł +Ġlight ly +Ġinv oke +ĠMar ie +Ġap opt +ĠMan hattan +ç§ĺ书 éķ¿ +Ġline up +âĢĿ ï¼ī +Ġshall ow +Ġwitness ed +è¿Ļ äºĭ +Ġem erge +å·² æĪIJ为 +( un +æIJŃ è½½ +Ġarriv ing +åĪĽå§ĭ 人 +Ġcorrespond ence +ï¼Į å£°éŁ³ +转 头 +èĦī åĨ² +æľī æĦı +çłģ 头 +ol in +äºĮ æ°§åĮĸ +äºİ æŃ¤ +ä¸Ģ 说 +Ġreflect ing +Ġsucceed ed +Ġgrad uates +Ġ çľĭåΰ +èģĮ åľº +_S YS +çª ¦ +Ġsc am +åįł ç͍ +st o +T unes +ĠPro position +ĠO t +ĠR ust +åī¯ æľ¬ +ĠU INT +Ġp ipes +æĹ¥ è®° +TR UE +Ġrig id +æĪij æĿ¥ +_ img +du cer +ĠOwn er +ä¸Ģ åĪĨ +Ġetern al +èĭ± 寸 +Ġbook ed +. right +O ps ++ b +座 æ¤ħ +en za +Ġimp ose +\ + +主 导 +äºĨä¸Ģ æĿ¡ +C redit +Ġse iz +Ġ çͱäºİ +Ġsun light +au er +æıı ç»ĺ +éŨ åīį +Ġcompr ised +ãĢģ ç»ıæµİ +Ġv ascular +_b its +Execut or +um atic +Ġident ifies +(l ong +_ opt +Ġbel ly +ï¼Į å®ĮæĪIJ +èĮ ľ +æ¶ī å«Į +ĠN ag +çķ ´ +èį Ģ +Ġex clusion +_C OLOR +g em +Ġcl ips +æĭ ¯ +iv ia +ĠC AP +æĬķ æĶ¾ +P eter +Ġre habilitation +ĠI B +Ġren al +Ġg a +Ġclear ance +è¯į è¯Ń +w oman +ĠElect ronic +U ntil +æ·Ģ ç²ī +Ġment or +ĠCent ers +ab olic +worth y +_CL ASS +æĵį æİ§ +æµ Ĭ +Ġal erts +ĠN ice +åıį åĩ» +è¯į æĿ¡ +ĠS old +{ y +_ IO +ç»ĦæĪIJ éĥ¨åĪĨ +Ġvit amins +æİ¥ åħ¥ +-N EXT +_p arent +Ġ 没æľī +Ġdef icit +Qu ote +èĤ¡æĿĥ æĬķèµĦ +Ġcast ing +åĺ ¶ +ĠB eng +è°ĥ è¯ķ +B tn +ç¼ ħ +he w +Ġr gb +af ka +ä¾ ĥ +( Y +åŀ ¢ +if acts +Ġreg isters +. tr +riv ed +Ġar ises +comp lete +R ot +éĿ¢ èī² +ĠV i +æĬij éĥģ +_ AP +pl ess +Ġvari ability +_ red +ur st +ĠP ure +{p matrix +I ts +ĠToy ota +Ġgr ill +ï¼Įçľĭ èµ·æĿ¥ +Ġweek ends +åĪļ å¼Ģå§ĭ +Ġcon gr +ĠCry stal +es p +ä¹ħ äºĨ +æĿ¥ 临 +ä½ł 好 +诸 å¦Ĥ +ĠP G +ĠW or +Ġfort unate +Ġaff air +éĢ į +not es +ĠC ant +j oint +çļĦè¯Ŀ é¢ĺ +åIJİ åį« +ï¼Įä»ĸ们 çļĦ +-c are +F ER +Ġbo oth +Ġm L +ipp et +ĠP ump +ĠMed iterranean +æĸ¹æ³ķ çļĦ +Ġpo et +çļĦä¸Ģ çĤ¹ +åħ³èģĶ æĸ¹ +ï¼ī åľ¨ +akes pe +éĹ® ä»ĸ +æĸ° 人 +头 é¡¶ +ĠÐ ° +en code +å·¥ åºı +á ŀ +Ġgl ue +D N +} ), +è¾¹ çķĮ +d em +大 æĸ¹ +Ġqu i +å¼Ģ çİ©ç¬ij +Ġincent ives +Ġpack ets +Ġl uc +Ġcons erv +ro ps +åĨĽ å®ĺ +-d ata +å¢ŀ æ·» +Ġin adequ +Ġlength y +æ´Ĺ 澡 +æĦ ķ +Ġrep orters +w idget +ï¼Įä»ĸ æĺ¯ +ĠD ynamic +Ġback end +åIJĥ æĥĬ +P ush +ãĢĤ åĪĺ +ï¼Į è¡Į +Stat istics +ãĢģ æĬĹ +åıªæĺ¯ ä¸Ģ个 +Ġorgan isms +St ock +_ word +îĹ¥ îĹ¥ +ĠP urchase +ĠY ES +F s +æł· åĵģ +l ip +éķ¿ çĶŁ +Ġintent ions +Ġmay or +ĠEn abled +: $ +Ġbreat he +ĠJ et +ï¼Į å¸Ĥåľº +Ġcheck out +=$ ( +lass es +为 æŃ¤ +åı° åĮĹ +ĠCh a +ose x +åĩł çϾ +Ġout look +ä¸į 缸 +ĠM aps +ra red +èĢĮ ä¸įæĺ¯ +Ġterror ist +Ġcamp s +Ġvill ages +Ġcalcul ating +cons ider +Ġplant ed +ä½ĵçݰ äºĨ +Y et +iet al +.P aram +çļĦ å°± +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠ +贯彻 èIJ½å®ŀ +Ġmid st +Ġmultip ly +Ġdon ated +C at +ĠC op +Ġconcept ual +æŃ¥éª¤ S +Ġ 亿åħĥ +Every one +ad apter +IS BN +éĿ¢ éĥ¨ +åı¯ä»¥ çľĭåΰ +åĿ¦ åħĭ +c lean +er vers +Ġ 主è¦ģ +Ġ_ { +Ġupload ed +ĠGrad uate +ãĢģ æķĻèĤ² +Ġvulner ability +æĿ¥ ä¸įåıĬ +Ġinf ring +ç¡« éħ¸ +, æľĢç»Ī +éĥ½ 说 +Ġfr ank +æĹ · +她 æĺ¯ +çĶ» å®¶ +er ie +alth ough +Ġro pe +è°ĥ è§£ +æĹ© åľ¨ +ĠL en +ad ers +Ġquiet ly +Ġv ic +ĠActiv ities +ç¥ · +ï¼Į大 æ¦Ĥ +erial ization +æĤł æĤł +ï¼Įä¸į å¦Ĥ +çļĦæīĭ 段 +Ġrhyth m +æµģ çķħ +Rad io +é£İ åħī +åĢŁ åı£ +æĬĸ éŁ³ +èļ Ĥ +建 æĿIJ +Re ason +å« ī +éķ ¶ +å¼Ģ å·¥ +æ¯Ķ èµ· +âĢĻ S +ogen ous +j et +ĠP assword +Ġ ä¸ĥ +, ä»Ĭ天 +æīį çŁ¥éģĵ +ĠAd min +âĢľ You +æĽ¼ èģĶ +åİŁåĽł æĺ¯ +it ical +å¿ĥçIJĨ åѦ +ĠCost a +ĠCont ainer +Ġass ure +å·« å¸Ī +ä¿® 建 +æ¯Ķ åĪĨ +ĠSwed ish +Ġev olve +åģļ ä¸Ģ个 +Ref resh +çļĦ åİŁåĪĻ +Ġharm on +res ources +ĠG PU +Ġsh aping +raul ic +met adata +Ġmeant ime +ï¼Į å®ĭ +身ä½ĵ åģ¥åº· +Ġdiff usion +æ½® æµģ +å½ĵ ä»Ĭ +am y +éļ ĭ +ric ular +Ġhierarch y +ä¸Ģ æıIJ +D a +è·¯ 段 +å¢ŀ å¤ļ +ĠB illy +(f ield +ros is +ï¼Į åĩ¡ +f lu +è¿ ¦ +ra ud +rain ian +ä¸į åºĶ +call back +in ology +ãĢĤè¿Ļ æĹ¶ +vert ical +Ġtravel ers +èĬ± äºĨ +Ġtherap ies +ĠM oving +em ory +ä¸Ńåįİ æ°ijæĹı +st als +, 便 +ãĢĤ éļıåIJİ +ï¼Į å²Ĥ +åıĤèĢĥ åĨħ容 +Ġdef iciency +) set +ì Ĺ +Ġsl iding +Pro s +uls ion +Dis cover +è£ Ķ +èµ° è¿ĩ +?? ?? +Ġlock s +ash a +. amazon +Ġsp rink +Ġfrust ration +èĿ ´ +al ways +äºĨ è¿Ļ个 +ĠB arcelona +欲 æľĽ +Ġre write +ĠGo ing +_on ce +in q +åıij 票 +Ġl ou +ĠN ull +ĠQu arter +Ġpr one +ĠM N +c it +å°Ħ åĩ» +è¾ĥ 好 +ãĢĢãĢĢ ãĢĢãĢĢ +LE MENT +gg le +åģļ åĩºäºĨ +activ ate +ï¼ĮæĪij们 çļĦ +sl ot +Dan iel +Ġdisc our +ï¼Įå°± åľ¨ +/ z +ĠS um +ĠVal entine +rict ed +Ġ 饰 +ad der +_B LOCK +.get Instance +text it +ID s +"" " +K S +ĠåıĤèĢĥ èµĦæĸĻ +ĠST AT +... ) +ĠB row +ĠSec urities +Per cent +. Entity +Ġdim ensional +-l ength +åĬ¨ èĦī +ĠTh or +Ġdiss ertation +Event Args +æĭ¥ æĬ± +éĵ¶ åŃIJ +à¸ Ļ +Ġcr ust +Ġg amma +com merce +ç®± ä½ĵ +Ġn urt +c reat +Ġprox imity +Ġdemonstr ation +b ral +ĠE PA +ãĢģ åħ¨ +ĠB asket +åĸ Ģ +çļĦ人 群 +Ġ 许 +ä¼ļ æĺ¯ +Ġillust ration +åįģä¹Ŀ 竳 +ĠMichel le +ĠAdvert ising +ä¹ĭ æĥħ +termin al +et rics +çĤ ĸ +Ġm ate +åĴĮ é«ĺ +S ar +è¿Ļ æĺ¯ä¸Ģ个 +Ġdis comfort +æĽ´ å¿« +Ġden ying +ĠId entity +表 æł¼ +ĠK am +Ġgl imp +æķ´ 个人 +. env +Ġmiss ions +Ġfrust rating +ma jor +Ġsat ur +ĠH erm +Ġconsist ed +æĸ¯ åŁº +æĹ¥ æĻļ +Ġun cover +So ft +éŨ è¯Ĭ +ÏĦ α +_S UB +ĠMarket s +åİĭ æĬij +Ġtrad ed +B rowse +ä¸įåı¯ æĢĿè®® +é¥ ª +yt est +åĻª 声 +Part icip +ew ater +次 ä¼ļè®® +Ġpl umbing +ï¼Į åį¡ +n x +Ġf iring +al ine +Ġter rain +id ency +åīį è¡Į +riv es +ï¼Į æĶ¯æĮģ +ä½ľ äºĨ +åİŁ æ²¹ +Ġy o +è¾ĥ å°ı +R GB +çıł å®Ŀ +ä½İ çļĦ +Ġcrit ically +Ġrank ings +ĠCele br +个æĢ§ åĮĸ +建设 çļĦ +p f +.f loat +pr ising +Ġsim ulated +ac a +æĿij åºĦ +st orage +Ġfinanc ially +ĠA ld +Ġappro ve +ï¼ħ ï¼Į +.d isplay +æ³ķå®ļ 代表人 +ä¸ĸ çļĦ +éļ¾ åħį +ĠPer ry +ĠG roups +Ġ ÑĢ +ĠP icture +æķ ĸ +ãĢĤ æķħ +Ġaccount ability +re ed +ä¿ĥ 使 +å°± è¡Į +Ġnum b +Ġpro gn +iss ance +éĵ ° +Ġ ie +éĩı åŃIJ +, æīįèĥ½ +Ġpack s +åİ ¥ +åĨħ åľ¨ +ĠT erry +phas is +ç§į æĹı +h uman +Ġp ap +æīĭ å·¥ +Ġre ign +Pro b +il ters +Ġ? > +f ollow +åij¨åĽ´ çļĦ +ãĢĤ åį³ä½¿ +ï¼Į让 ä½ł +ĠR u +人 çĶŁçļĦ +ĠG PL +rec ogn +åIJİ åı° +ĠNor way +太 å¤ļäºĨ +ç»Ī 身 +Ġpost erior +Ġl od +Ġy arn +ĠN ancy +F riend +ä»ĸ ä¹Ł +Ġ ä»Ĭ天 +ĠC rown +rell a +æĢ§ åľ° +强 è¡Į +Ġst icks +Ġcent res +[ TELEPHONE +Ġcommun icating +ĠForm ula +Ġgra bbed +c ue +Obs erver +ĠB A +Pre v +there um +w eg +ä¿Ŀ å¯Ĩ +éĴ § +Ġgl uten +_f ilename +ĠSD L +Ġles ions +人æ°ij 群ä¼Ĺ +ĠAr gs +-m od +- Sh +Ġby pass +St ates +ĠÏ Ĩ +ke ley +ah n +亲 åĪĩ +社 åĽ¢ +Ġexpon ential +.F ield +ï¼Į çݩ家 +å®¶ ç͍ +饲 æĸĻ +èĿ´ èĿ¶ +æĶ¹åıĺ äºĨ +_ assert +Ġmon itored +. Thread +Ġcolor ing +_ right +do es +Ġsp y +ĠHe brew +ĠU nd +H B +Ġmit ochond +ĠLiber ty +åĮĹ éĥ¨ +/ min +osoph y +ä½ł æĢİä¹Ī +ĠB I +ä»İ èĢĮ +ï¼Į æĹ¥æľ¬ +Ġfin ishes +Ġes cal +ue z +çIJ ī +Ġrecomm ends +äºĮç»´ çłģ +.ex ample +çĿ IJ +at um +/ json +.C heck +çļĦ 游æĪı +Ġexp ose +ĠJim my +çŃī ä½ł +èį § +---- - +Ġcool er +Ġlock down +M icro +款 å¼ı +èĢ ¦ +ãĢĤ åĽĽ +è§Ĥ èµı +N AS +å± ¿ +éĺ³ åı° +åĩĢ å̼ +ï¼Įä¹Ł ä¼ļ +Ġorient ed +assert Equals +æŀľ å®ŀ +---- -- +el ong +éģĵ åħ· +st age +Ġhe mp +ä r +æ¯Ľ æ³½ +Ġglo ves +æĬĺ åıł +Miss ing +ĠH arm +èĥĮ åIJİçļĦ +ash i +Ġaffili ated +ï¼Į åĿIJ +åİ Ħ +åİŁ è°ħ +unc her +Ġb arn +çļĦ åľ¨ +irl ines +[ in +ĠManag ing +å¯Į è´µ +ä¿¡æģ¯ æĬ«éľ² +èĭ Ł +Ġund oubtedly +g res +ub le +ĠV IP +太 空 +ĠG DP +pat tern +_ position +å¼Ģ å¹ķ +ien cies +好 好çļĦ +åĴĮ æĬĢæľ¯ +ĠRequ irements +.J son +requ ently +- head +ï¼Į åѦçĶŁ +ï¼Į è¾¾åΰ +Ġent ropy +F eb +Re ceived +ä¸Ń åİŁ +p red +Met rics +ENT ER +æijĨ æĶ¾ +åĨį ä¸Ģ次 +Ġcan ada +CL AIM +Ġres ign +f ailed +åĽ ļ +çݯ å½¢ +ĠPro of +co ord +urd y +Ġobject ion +bor ne +Ġw rist +Gen re +ï¼Į åĨĻ +ĠThrough out +ĠC e +fe ature +W ords +( GL +Ġrecord ings +Ex pect +atern ity +åģ¶ çĦ¶ +if s +Th ink +Ġro ster +æľĪ èĩ³ +ãģ ij +CON FIG +Dis cussion +ç¥ŀ è¯Ŀ +ut down +Ġ\ | +Ġunw anted +èµĦ产 è´ŁåĢº +Cons umer +-r ange +ik h +Ġvoc abulary +( to +ĠHistor ical +ĠHel lo +road cast +L at +Ġb ureau +ĠBe ijing +ĠF ern +AND LE +ä¿¡ èµĸ +TM P +e or +St yles +eal ous +ç»ı éĶĢåķĨ +qu o +Ġmotor cycle +Over view +çĥ¹ 饪 +ph an +sub mit +Ġread ings +S i +Ġactiv ists +ä¸Ĭ åįĬå¹´ +åĩº åħ¥ +ĠJ ourney +Reg istration +Ġdemonstr ating +表 éĿ¢çļĦ +åľ° åŁŁ +åıĺ åİĭ +esc ape +akespe are +ï¼Į æĶ¶ +æľŁ åĪĿ +Ġconc urrent +OT E +æijĦ åħ¥ +Ġb illing +ï¼Į åŃ©åŃIJ +se min +ast ically +ä¸Ģ 头 +ä¸ĩ ç¾İåħĥ +App end +Ġcur iosity +éĴ¢ çŃĭ +Ġconj ug +ĠStud ios +'] [ +ĠMad rid +åĴ ı +ĠRead y +ĠK le +çļĦ åIJĦç§į +ãĢģ åİ¿ +ĠG ay +и м +åıĪ ä¸į +Ġjo ins +, 导èĩ´ +IN ESS +< - +_ vec +Ġg erm +Ġconve x +), ( +èĸĦ èĨľ +IST ER +b oost +w m +ãĢģ åĽĽ +è¿ij 代 +Ġneut r +é»Ħ æ²³ +åĽ° å¢ĥ +åħī æ»ij +Ġle v +? ( +Ġj ournals +V el +ï¼Į åıijè¡Į人 +æĪ¿éĹ´ éĩĮ +ä¸Ģ个 大 +_LEN GTH +, æľ¬ +Ġint act +ï¼Į æĢ»æĺ¯ +Ġref in +ä¸Ĭ ç½ij +c ould +Al t +we i +Ġmanip ulation +ä¸Ģ æĥĬ +çļĦ èĩª +ĠRec ently +Ġdesc ending +ĠS nap +-m inded +ĠC zech +çª į +æĬ½ 象 +Ġrefresh ing +Pres ident +Ġch ill +åĩŃ è¯ģ +½ åŃIJ +ĠB order +Ġ$\ { +æĹ¥ å¿Ĺ +ster dam +Ġprejud ice +Ġtra pped +Ġm ast +åıijçݰ èĩªå·± +ç¬ij è¯Ŀ +Ġ ¶ +ĠB ishop +ĠManufact uring +a udio +èĢĮ æĿ¥çļĦ +Ġgl oss +Ġun changed +Ġtechn ically +ç¥ŀ æĥħ +è¿ŀ è¿ŀ +Ġimp rison +_ one +驾驶 åijĺ +Ġconst itutes +^ [@ +Ġreson ance +ĠD NS +av an +æĪĺ çļĦ +æĪij è¿ĺ +èµ° å»Ĭ +ĠL it +Ġcont empl +_CO UNT +Ġrecip ients +ç³ĸ æŀľ +ç«ĭ æ³ķ +è¶ħ åĩº +ĠS MS +I l +æµģåĬ¨ æĢ§ +ĠSam uel +Ġf ier +/ in +N BA +Ġdist ress +ac s +é£İ æļ´ +Ġhyp othes +ĠP ictures +èΰ éĺŁ +Ġb ubb +缸 éĤ» +U pper +æĶ¶çĽĬ çİĩ +æĿ¥ åĽŀ +åĴĮ æīĢè¿° +Ġclean up +ĠExp and +Ġment ally +US ER +.m atch +Ġdisplay ing +Ġinvari ant +Aut om +S everal +st ats +ï¼Įå®ĥ çļĦ +Ġox ide +Ġg ates +Ġlocal ized +Ġinv isible +Ġelig ibility +Ġs ore +åľ¨ åħ¶ +管çIJĨ åĬŀæ³ķ +ãĢģ åħ¬åı¸ +ACT ION +æĽ´åĬł çļĦ +åıĻ è¿° +ĠStan ley +ched uled +æµ® çݰ +åĸ § +åŁºéĩij 份é¢Ŀ +éĩİ çĶŁ +奥 æĸ¯ +p ur +); " +Ġhighlight ing +客 åľº +Ġsc anner +æľĢ æľī +S af +Ġrac ism +æµģ åĩº +Ġg room +Ġview er +ug a +ĠDesign er +Ġdr agon +让 åŃ©åŃIJ +ç¼ĺ æķħ +\ % +Ġproport ional +äºĨä¸Ģ éģį +IND OW +ãĢģ å·¥ä½ľ +ĠWork ers +Ġquestion naire +D aily +Ġb on +äºĨä¸Ģ 次 +ĠBut ter +çĶŁæ´» åľ¨ +åι éĤ£ +Ġsimpl est +ĠInit iative +ãĢģ ä½İ +å¢ŀå̼ ç¨İ +ĠPlan et +ĠC OMM +u u +ĠE t +ĠFor ward +ï¼Į æİ¨ +Ġp orn +礼 仪 +ĠH il +an imation +Ġc ached +R s +J P +-h ome +er ness +Ġd ummy +çĸ¾çĹħ çļĦ +ĠVari able +Ġcast le +Ġemphas ize +Tag ged +åı« æĪij +( System +Ġdownload s +ç© Ĺ +å¡ŀ å°Ķ +å¯ ħ +im ming +åĩł çĤ¹ +缸 éģĩ +W W +åĵĪåĵĪ åĵĪ +her ical +ä¸ĩ éĩĮ +éĨĴ äºĨ +{tab ular +ä¸ĸ ä¸Ĭ +-k ind +CT L +Ġdr ift +ET ER +å¤ĸ å¥Ĺ +Ġport rait +èĶĵ å»¶ +ï¼Į让 æĪij们 +奥è¿IJ ä¼ļ +åį´ ä¸į +Comm un +ĠM OD +_b l +æ¯ıä¸Ģ ä½į +Ġfrust rated +.getElement ById +é© ´ +åļ ¼ +æľĿ éĺ³ +Sc ience +Cert ificate +以 åIJİçļĦ +é¢Ĩ è¢ĸ +Ġcelebr ity +è¶ĬæĿ¥è¶Ĭ å¤ļçļĦ +ILE D +èIJ ĥ +Ġfire place +, æĪijçļĦ +å¾Ī åĸľæ¬¢ +åºŀ 大çļĦ +æŃ£ æĸĩ +请 ä½ł +æ¯Ľæ³½ 举 +Ġlisten ers +ï¼ĮæīĢè¿° 第äºĮ +z heimer +C art +ãĢĤ å¾Īå¤ļ +åĽŀ è´Ń +ĠEval uation +Ġdownload ing +Ġadvoc acy +. line +ĠPol ish +- Type +es ium +Enc oder +Ġ éķ¿ +éķ ģ +çĤ¹ åĦ¿ +ãģ£ ãģ¦ +ĠH z +Ġins ult +Ġenzym es +ĠL inda +æĪij 没æľī +Ġhom emade +Ġp ier +Ġb aked +ĠP P +Ġrad ar +ĠAdvent ure +æ± ¹ +roph ic +å¹½ é»ĺ +') -> +Ġsn acks +ĠB P +åŃ¦ä¹ł åĴĮ +ä¸į æĿ¥ +C ut +åĵĪå°Ķ 滨 +H ex +æł· å¼ı +Ġdis charg + ¼ +ãĢĤ 好 +Ġrel uct +âĸ ¡ +åĽ½å®¶ åĴĮ +parent s +ĠC oc +or rect +æİ§åζ ç³»ç»Ł +åĬ¨ åijĺ +çļĦåīįæıIJ ä¸ĭ +T B +g el +( client +EM P +è¿Ļ ä»¶äºĭæĥħ +ĠF B +å½ĵæľŁ æįŁçĽĬ +åıªæľī ä¸Ģ个 +ST AT +lades h +磨 æįŁ +å®ŀæĸ½ä¾ĭ çļĦ +N B +è´¦éĿ¢ ä»·å̼ +èĩªçĦ¶ æĺ¯ +Ġp ear +åĩł åı¥ +Ġret ire +ï¼Įä¸į ä½Ĩ +Ġprompt ly +ä¸ĵ注 äºİ +O ffic +x F +Arch ive +åħ¥ æīĭ +åĨ· åĨ· +_F IELD +çķĻ ä¸ĭäºĨ +Ġre lying +èģļ ä¼ļ +Ġgenu inely +{ i +Ġun used +con vert +æĹ¶éĹ´ 为 +Ġ(! ( +ï¼Įä¹Ł å°± +çIJĥ åľº +èģļ åIJĪ +_ over +ĠD OM +å¿«éĢŁ çļĦ +_ print +ru ed +Ġcost ume +ï¼Į çĥŃ +_d es +R UP +Ġw ool +è§Ĥ çļĦ +um ph +空 çϽ +æ°Ķ 缸 +, åİ» +ãĢģ åĪĺ +Ġmount ing +帽 åŃIJ +/ local +ä½ĵ 温 +yst er +Ġt abs +Ġn ails +_O F +the ir +IB LE +Ġin expensive +åħī åѦ +Ġo ak +Ġbatt les +* > +ĠHe ight +çľĭ å®Į +enn a +å°Ĭ æķ¬ +èIJ¥ ä¼ģä¸ļ +Ġn aked +ĠSc i +æµĵ éĥģ +_w indow +-c ore +Ġenumer ate +m ol +ä¿ º +ĠJ azz +ĠTrans form +TERN AL +çݰ æľīçļĦ +ãĢĤ æĤ¨ +ĠH our +æ´Ĺ æīĭ +çĬ Ģ +.s upport +( json +n r +Ġl umin +andid ates +èĻļ 空 +æħ¢æħ¢ åľ° +m are +Ġorig ins +çĽij çĭ± +åIJĪä½ľ ä¼Ļä¼´ +Pay load +Ġemotion ally +åľ¨ ä¹İ +Ġext ensively +红 åĮħ +åĩº æ°´ +she ll +Ġcl ue +Ġstress ful +Ġref erenced +ĠCru z +am bers +çļĦ æłĩåĩĨ +Ġthreat ening +Ġeat en +èĶ ļ +Ġsp inal +_ return +å±ĭ éĩĮ +Ġadapt ive +ĠAll ah +-f ive +ampl ing +çłĶ åζ +ĠM ouse +Ġon ions +k an +æľī ä¸Ģå®ļçļĦ +èģĶåIJĪ åĽ½ +Ġher b +Stud y +çª ¥ +Ġconver ter +ĠÏ ģ +ĠBrother s +为 éļ¾ +é»ijé¾Ļ æ±Ł +äºĨ åij¢ +C OVID +ise conds +Ġphenomen a +Ġambit ious +Ġtra it +Ġ** * +ä¸Ģ éĹª +ed ar +éĩį 建 +Ġ[ ( +æº º +æłij æŀĹ +S ales +ĠSpecial ist +Ġpropri etary +æīĵ å·¥ +è¡Ĺ ä¸Ĭ +Ġf p +æ²Ī éĺ³ +Ġdef inite +ä¹Ł éĿŀ常 +Ġn ost +ä¸Ģ åı£æ°Ķ +ĠA CTION +N UM +Ġperf ection +\ geq +æģ¶ å¿ĥ +è´ ® +å±ĭ åŃIJ +æĮĩ åIJij +pe ak +ĠTrans action +ç¿ © +ov o +. zeros +. active +Ġgeneral ized +Product s +Ġcriter ion +Ġgen ius +ä½ł çŁ¥éģĵ +_m ult +ç»ıæµİ çļĦ +éĤ® ç®± +Ġspons ors +èĤ¯å®ļ ä¼ļ +ĠBar ry +è¦ģ 说 +ĠK an +æľī 许å¤ļ +çīĽçļ® çĻ£ +J es +éĺĢ éŨ +Ġremot ely +纪 å§Ķ +åıĪ ä¸Ģ次 +Ġinterview ed +ĠP ap +ĠGard ens +æĺ¯ä¸Ģ åIJį +æķij åĬ© +ç¹ģ åįİ +审 ç¾İ +æij©æīĺ 车 +R o +Ġtr unc +è¿ĺ å°Ĩ +é¢Ŀ å¤ĸ +è¿ĺ ç®Ĺ +æĮ ļ +Java Script +æı´ åĬ© +ä½ł ä¹Ł +é¦ĸ æŃĮ +éģĹ åĿĢ +ĠK ir +Ġimag ined +ĠDevelop er +Th ings +ĠCustom ers +é¢ĩ 为 +ä¸ļ çļĦ +çİĭ åĽ½ +å¹¶ åıij +èĭ± æł¼åħ° +ï¼Į çϾ +/w iki +ĠAs set +_s core +ĠX P +Ġhe ap +éķľ åŃIJ +Ġinnov ations +arm ing +åı¤ æĢª +T ips +av g +at iv +ar ations +æ£ ± +B rowser +Ġsoc io +Ġc rap +æŁIJ ä¸Ģ +. reg +ĠC it +al ia +äºĨ 对 +笼 罩 +Ġcare g +迹 象 +ï¼Į åĸľæ¬¢ +){ # +åıįåºĶ è¿ĩæĿ¥ +Ġcatal yst +Ġ Ñĩ +åħΠ天 +ĠCont ents +_reg ister +ĠM ack +ĠOb viously +åĿıè´¦ åĩĨå¤ĩ +åĮ» ä¿Ŀ +ĠM umbai +Ġun precedented +Ġaffili ates +Ġdecom position +Ġwh olesale +Ġaccount able +ç©¿ ä¸Ĭ +Ġdisappe ar +Ïĥ η +ĠOlymp ics +å¼ĺ æī¬ +Ġn ap +Ġsew ing +amp ed +大 èĥĨ +[ name +Second s +Ġmerg ed +T oggle +ĠH ydro +ĠT ickets +çģ° å°ĺ +Ġconver ting +Ġdeal ers +书 çļĦ +Ġdis contin +ç´ł åħ» +导èĩ´ çļĦ +Ġqual ifications +ä¹ ¾ +å½ķ éŁ³ +ĠSur face +ĠParent s +. back +rit ies +Mod els +æ¼ı æ´ŀ +èĬ± éĴ± +Ġv et +ä¿ ĺ +Ġye ast +ack age +Valid ate +Ġpal ette +/w p +_de lete +Ġdecor ated +gl ass +çīĩ 段 +Ġg ospel +TR A +æľī æľĽ +.S e +l ists +Ġterr ific +ä¸Ģ ç¯ĩ +è¿ĺ 羣æĺ¯ +åIJİ èĢħ +subset eq +è½® åĽŀ +Ġan ch +ĠMove ment +ĠK B +ï¼Į å¹² +ãĢĤ æĪijçļĦ +æĩ µ +ĠEmploy ee +ç§Ĵ éĴŁ +è̳ æľº +Ġincent ive +b ag +X T +æķĻ å¯¼ +am ation +ï¼ĮåĽłä¸º ä»ĸ +ĠE dd +管çIJĨ åĴĮ +Ġgra ve +å·²ç»ı æĪIJ为 +Ġd read +l oss +Current ly +ãĢĤ å¹¶ä¸Ķ +INS ERT +wh y +综 èīº +aw k +èµ¶ å¿« +Ġ ä½ľä¸º +èĢģ çϾå§ĵ +ãĢĤ æĽ¾ +Ġadvis ory +c amp +C AL +Ġremed ies +æīĵ çĿĢ +end ent +对 çħ§ +çģ« çļĦ +Ġad op +P OS +åŀ Ħ +Med ical +Ġ í +æĢ ¯ +天 åŃIJ +ä½ł æľī +Ġ{ : +_m ain +è£ħç½® çļĦ +Ġun set +Ġcar p +Ġdet erior +il ia +Ġ éĢļè¿ĩ +Ġmot ions +Ġcan onical +Ġhun ger +Ġrep o +Ġrout ines +室 å¤ĸ +åijĬ åĪ« +end e +åIJij å¾Ģ +ĠD IRECT +åįĹ éĥ¨ +Ġcompliment ary +p ers +èŀº æĿĨ +Ġdur ability +红 äºĨ +åIJĮ ä¼´ +Ġopen ly +You Tube +um i +ĠCreat ing +Ġaut umn +èİ·å¾Ĺ çļĦ +Ġall ies +éĥģ éĹ· +åħŃ åįģ +_m anager +ut ral +伯 çī¹ +ch art +or igin +ĠMort gage +å¤ļ åIJį +èµ· ä¼ı +æĵį 纵 +ĠL uther +ï¼Į ä¿Ŀ +PL AY +ĠPat ient +Ġarbit ration +ine e +Ġb is +å¤ľ éĩĮ +, ä¹Łä¸į +. ä¸Ģç§į +Line ar +/ sh +Ġf riction +Ġl p +Ġdess ert +ç²¾ éĢī +æīĵ çļĦ +ç¼ĸ è¯ij +Ġelev ation +st ant +éĽķ å¡ij +Ġintim id +ï¼Į让 她 +æľ¨ æĿIJ +_ exp += s +ä¹ Ĵ +ĠU r +D em +ä»ĭ åħ¥ +Ġrel ay +æĵįä½ľ ç³»ç»Ł +Ġass urance +æijĨ æīĭ +config uration +Ġsod a +ĠE lementary +un ge +{ proof +Ġsoc ieties +被åijĬ 人 +M er +ĠFood s +L iked +Ġillust rates +-m enu +åĹ £ +on avirus +\ sqrt +æIJ ĵ +éĺ» æĮ¡ +æĥ³ çŁ¥éģĵ +ĠOrgan ic +ĠH OW +å°ı å°ı +ãĢģ éķ¿ +æ´» æ³¼ +_ UP +Ġstim ulus +ï¼Į çŀ¬éĹ´ +^ - +Ġchar ter +.C ore +Ġrob ots +ãĢĭ ãĢģ +Ġcub ic +满 æĺ¯ +å°ij 许 +å½ĵ åľº +any on +åı£ æ°´ +non umber +ĠCR M +ĠR acing +we ets +æ¢ ĵ +ĠF IX +æī§ çħ§ +æĮĤ çīĮ +ĠFire fox +Ġmis under +ĠWal ter +Ġpreced ing +éĺ» ç¢į +al ert +Ġrefuge es +天 åłĤ +æĸĩ çļĦ +ĠG ospel +åĪĿ 级 +èĿ ī +çļ Ĥ +Ġ( # +丢 失 +Ġcomb o +为 åħ¶ +Ġform ulas +ish a +æļ ĩ +çļĦ æ´»åĬ¨ +... âĢĿ +ĠJ ake +_pro perty +åįģåĪĨ çļĦ +è¿Ľ åĩºåı£ +ĠSome one +åij½ åIJį +ï¼Į åĨ³å®ļ +(' \ +id av +Ġstri ps +ĠGO OD +Ġprim itive +ĠConsult ing +. form +å¼Ģåıij åķĨ +éĺ» åĬĽ +ĠMin or +ĠMod els +Ġqual itative +.n av +lock ed +ĠMax imum +} ); +Work er +çļĦä¸Ģ éĿ¢ +ç¬ij çļĦ +or ie +D u +éļ¾ è¿ĩ +ä½Ļ çļĦ +( pos +ãĢĤ éĻĪ +- % +Nav igation +ä¸İ ä¹ĭ +ĠPortug al +Ġham mer +åħ¨ åİ¿ +-cent ury +Ġy og +ENT S +Ġ 注 +ĠJess ica +ol ation +mem ory +åij Ĺ +èĩª æĿĢ +å®ŀæĸ½ æĸ¹æ¡Ī +Ġreve aling +Ġs am +çķĻ ä¸ĭçļĦ +éĴ¢ æĿ¿ +ĠTrend s +èģĮ ç§° +Ġprom o +ĠE urop +ĠS und +æľī ç§į +Ġ è§ģ +ĠRef lection +åħŃ ä¸ª +u cc +åĢĴ åħ¥ +_ empty +ĠR av +èij « +åº ¶ +举 é£İ +iqu id +æĺ¥ åŃ£ +.re nder +ĠC ultural +æº ħ +Ġref ined +æ¸ħ ç®Ĺ +, åı¯èĥ½ +_C FG +Ġattend ees +{ u +ven ile +æĺ ¼ +_G PIO +äºĨä¸Ģ 大 +Ġspec ifies +æĺ¯ èĩªå·± +èĦ Ĭ +æŀģ èĩ´ +çľ · +ra vel +ym an +Ġpill ow +è¡Ģ ç³ĸ +we ak +ç§Ł éĩij +. version +R ock +ä¸Ĭ æĺł +Ġ å¦Ĥ +æĪĺ å½¹ +Ġbelie ving +ĠT ensor +é¦ ħ +Ph ase +ĠÌ ģ +Ġarg uing +åı« 声 +åħ³ çα +产åĵģ è´¨éĩı +As sembly +Ġpetition er +Ġl ingu +Ġus b +c atch +ĠS IM +Ġtr ay +å¾Ĺ 罪 +ĠExt ract +Ġh obby +Ġselect ive +bal ance +Ġsold ier +æİ¥ 头 +Can vas +op ens +ä¹° æĪ¿ +ï¼Į å®ŀéĻħä¸Ĭ +Ġ( & +Ġur ged +åı¯ çαçļĦ +ä»Ģä¹Ī äºĭæĥħ +ĠKe ith +Ġf ür +åĩı å°ı +æĢĿ ç´¢ +è¾ĵåĩº 端 +çĽ Ķ +ĠEx cell +c nt +-B ased +Ġsumm it +å½ ª +Ġsprint f +åģ¿ è¿ĺ +Ġassemb led +ï¼Į æľ± +T or +abs olute +() ), +ĠG arc +z el +æĬĢæľ¯ åĴĮ +PRO C +ç¿ħ èĨĢ +ĠCONTR IBUT +M a +string s +Ġabund ant +èļ ķ +" + +n b +// # +ĠBelg ium +rit ic +ä¸Ń æ¯Ĵ +- St +e cca +è¾ĥ 好çļĦ +ä¸į 幸 +ĠG UI +å®¶ éĩĮçļĦ +in burgh +ĠReg ulation +Ġretail er +ĠHamp shire +å±Ģ åĬ¿ +审 çIJĨ +çł´ 产 +羣å®ŀ æĢ§ +Rich ard +åľ° å°Ĩ +ä¸į 让 +. action +常 å§Ķ +ä¸Ĭ å¹´ +< ' +身 åIJİçļĦ +ĠBen jamin +b id +ynchron ous +ï¼ ĵ +-z ero +.p re +[ width +.assert True +æıı åĨĻ +Ġutil ities +B ob +Ġshare holders +åĩº èĩª +产ä¸ļ åıijå±ķ +Ġvine gar +ĠChel sea +没æľī æĥ³åΰ +M AT +d ynamic +S yntax +ĠComput e +ĠGener ally +女 çļĦ +ever se +çļĦ人 æīį +ä¸į åı¯ä»¥ +Ġtub es +Ġo t +Dec oder +Ġqu ilt +health y +åıĪ è¦ģ +èι èζ +Ġmax imal +Ġpress ures +ĠEn h +ç½® äºİ +ĠInst ant +èµ· åºĬ +æĢ» çIJĨ +H Y +ĠR ew +ĠBack ground +-inc ome +æĺ¯ æĹł +Ġsun ny +æĺŁ è¾° +ĠI oT +å¿ħ éľĢ +i pper +ĠH S +ĠâĪ ¼ +est hes +set up +Ġind ia +ï¼Įè¿ŀ å¿Ļ +M ajor +, int +éĿł è°± +çĢ ij +ä¸į æŃ» +å¢Ļ ä¸Ĭ +Ġmagnific ent +Ġrem oves +人 æ°Ķ +åħ± 计 +欧 缣 +DE V +Ġl av +o osing +æĥ ¶ +ãĢģ 第ä¸Ģ +Ġinteract ing +ĠComp etition +Ġhe pat +Ġtrad itionally +å®¶ ç͵ +Ġterm inate +åģľ çķĻ +ĠEconom y +ĠM ovies +ĠS PI +æĿij éĩĮ +c u +_IN DEX +æĮģ æľīçļĦ +_F AIL +Ġgu ards +Ġt attoo +ä¸į ä¿¡ +åĺ İ +ĠC iv +ip ly +ĠWhe el +ï¼Į åѦ +rupt ed +x FFFF +æª ¬ +il ine +ĠAb raham +å¸Ĥ çļĦ +ĠL ate +m ine +< > +ä¸ī ä½į +Ġquick er +en ario +ĠGu arant +æ¶Ī失 äºĨ +_m utex +ĠInt ent +ĠBreak fast +et on +ï¼Į éĴĪ对 +å·²ç»ı å¼Ģå§ĭ +ãĢģ ç͵åŃIJ +Ġcous in +at ics +Ġast hma +Ġobs erver +çļĦä¸Ģ 项 +Ġ% > +ä»ĸ å°± +ä¿¡ç͍ åį¡ +Ġswit ches +_B UFFER +æģ ¤ +仲 è£ģ +ä¸Ĭ 级 +Ġred und +失 误 +æ¯ı åij¨ +M or +åŃIJ 宫 +Ġper p +) % +K ing +The ir +åĩº åĽ½ +D est +好 ä¸į好 +, ç»ĵæŀľ +ĠD ir +éĢī è´Ń +s ync +æĽ´ æĶ¹ +ĠThe ater +ãģª ãģĦ +Ġlay ing +.Form at +ĠD A +åĢ ª +Ġ è¿Ļç§į +æĪij çİ°åľ¨ +æ³ķ å®ĺ +L arge +-per formance +u ator +åIJij ä»ĸ +ĠW P +ĠD raft +éĥ½ ä¸įèĥ½ +ĠF iction +éĤ£ å¼ł +âĨ ĵ +ĠH orn +Ġbra ke +ĠBuff alo +Ġshe er +Sp ot +P aint +Ġdiscipl ines +Ġmic rowave +] / +_ space +cl uster +eng u +à ¹ +et ail +w ere +n l +ĠCon crete +ï¼Į 容æĺĵ +Ġfre ed +Ġdies el +èµ· çłģ +. No +Ġ" ./ +ä¹IJ åĽŃ +Ġassert ion +C as +US INESS +L ondon +Ġvi agra +éĻį æ¸© +天 çĶŁ +ĠH onda +ĠG abri +/c ss +â̦â̦ â̦â̦ +fl at +æľī ç͍ +Ġupgrad es +* (- +. char +å¾Ī å°ı +çª Ł +RE AT +iox ide +Ġk wargs +æĸĩ ä¸Ń +Ġop acity +Ġnorm s +.c olumn +å½ĵæĹ¶ çļĦ +Ġimport s +çĺ ¾ +Ġteach ings +ĠG ate +ä¸į è¿ľ +æĺ¯ æ¯Ķè¾ĥ +, æĪIJ为 +ĠC ODE +âĢĿ ï¼ĮâĢľ +Ġtraject ory +ĠS orry +ĠH unt +è¯ģ ä»¶ +ç»Ĩ ç»Ĩ +ĠY ahoo +Ġadvoc ates +Rec ently +çݰæľī æĬĢæľ¯ +{ }, +åľ¨ åĨħ +so ever +.X ml +èĢĮ è¿ĩ +Ġw ished +æıIJä¾Ľ ä¸Ģç§į +å¹´è½» çļĦ +t ags +Ġbet ray +++++ ++++ +Gener ate +an as +ĠW ash +Ġrecru iting +.P arse +Ġpick up +Ġsp otted +he a +, åį³ä½¿ +æĦıè¯Ĩ çļĦ +ĠCol lections +èķ ī +. local +Ġhel lo +Ġmut ant +Ġgreen house +äºĨä¸Ģ åľº +èµŀ åIJĮ +ï¼Į åħ¨åĽ½ +ĠSp ark +Ġdry ing +_en able +æĪIJ å¹´ +Ġmusic ian +Ġdem ographic +{ Q +éĻĦè¿ij çļĦ +å¾Ĺ 太 +zz le +Ġdemand ed +P icker +ret val +Th ird +B rit +å¤ļ 彩 +ï¼Į对 çĿĢ +s id +_t emp +Ġsur geon +ALL Y +ï¼Ł å¦Ĥæŀľ +ĠS au +ãĢģ é¦Ļ +ĠApp lied +Ġat he +康 çĨĻ +ç»Ļ åŃ©åŃIJ +C apt +ĠSh adow +Ġtrig gers +è± ģ +æŀģ äºĨ +Col ors +Mod ified +åĪ· æĸ° +åı¯ä»¥ 让 +Ġprest igious +ä¾į åį« +Ġb b +Ġre de +ĠR io +ĠList en +Ġsh y +A verage +åģľè½¦ åľº +æľī 两 +å»¶ è¿Ł +åľ£ è¯ŀ +ĠFour th +æĬ ¿ +ç° ¿ +ĠL ayout +æĹ¶ è¾° +ĠChem ical +] } +w en +- U +ãĢĤ ãĢIJ +ĠChem istry +ï¼Į åħ¨éĥ¨ +æ¼Ķ ç»İ +ï¼Į å®ŀåľ¨ +ĠField s +严 åİī +ĠLa unch +å¼ Ī += ` +åħ¬å®ī æľºåħ³ +åͱ æŃĮ +å®ŀéĻħ æİ§åζ +Ġcav ity +çļĦ ä»·å̼ +Ġ- *- +Ġind ul +Direct or +åı¯ è¾¾ +aret te +çłĶç©¶ ä¸Ńå¿ĥ +uzz y +Ġwarm th +Ġhint s +å¢Ļ å£ģ +op ol +In c +.C olumn +æ±ĩ çİĩ +Path s +M ad +ĠPar ad +h m +Ġfil mm +ĠI DE +åIJį ä¹ī +åĪĨ è£Ĥ +ä»Ģä¹Ī ä¸ľè¥¿ +ï¼Į ç¡®å®ŀ +_C ALL +Ġinform al +аР¼ +ï¼Įä¸į åĨį +交 è°Ī +Ġpars ing +Ġinhib itor +çĶŁäº§ 线 +å¹² çļĦ +转 éĢŁ +Aut hentication +Ġath lete +EN O +éϤ å¤ĸ +ĠString Builder +ï¼Į çŁ³ +.D ate +ĠW idget +g om +, å°¤åħ¶æĺ¯ +ï¼Į å·¥ä½ľ +鼨 æ°´ +_LE VEL +M gr +Ġjust ified +ĠC arm +æ´Ĺ 涤 +ãĢģ æ²¹ +è·¨ è¶Ĭ +ĠA irlines +éĿ ´ +ï¼Į 谢谢 +. Start +çĭ¬ç«ĭ çļĦ +ĠWat son +ul o +ĠB enn +az ing +. Controls +éĿĴ çĿIJ +/ data +Ġcustom s +Ġb g +- defined +è¿ĩ 身 +ĠEv idence +( List +×ķ × +Ġ" ../ +éĶĻ误 çļĦ +ĠProv ide +ï¼Įå¹¶ ä¸įæĺ¯ +c z +åŁºæľ¬ çļĦ +ãĢĤ å¤ļ +Ġpe el +In clude +çŃī å·¥ä½ľ +[ m +Ġcer amic +ç»ĦæĪIJ åijĺ +Ġbut t +ĠA K +æķĻ ç¨ĭ +i oc +çĤ¹ èµŀ +æĢ» çļĦ +ä¼ĺ è¶Ĭ +éĻ ĭ +d w +åģľ ä¸ĭ +P ACE +âĢĶ a +ĠCam eron +é¢ ħ +Ġur ine +浸 泡 +çĴ ĩ +Ġh alt +ĠG E +æĭĨ éϤ +ict ory +, l +Âł ä»ĸ +rodu ce +Ġin appropriate +Ġacceler ate +Ġ ### +ĠB attery +Ġexecut ing +ord able +è¿ĩ 大 +Ġexplos ion +J obs +åĢ¡ 导 +Ġvol can +åĨħ ç½® +ĠDr ag +æ¢ µ +人 æĢ§ +çļĦ主 é¢ĺ +Ġlux urious +St ub +_p re +è¶£ åij³ +Cl ip +Ġst ip +Ġfar mer +g ender +æĪIJ ä¸Ģ +ĠM ight +: m +_ IF +æīĭ 表 +导 åħ¥ +co vers +åľ° éĹ® +éĢ ® +æĿĥ éĩį +Ġinter ven +ĠDe als +ï¼Į çģ« +å¾ģ æľį +Market ing +严 è°¨ +b ay +ç»ĺ åζ +ĠU T +.l ayout +æĦŁ åĴĮ +å°ı ç¨ĭåºı +èİ ½ +åĨį ä¹Ł +lu ence +Ġpo ems +[ , +Ġc ad +ar ith +ĠY e +ap is +Com bo +ĠT CP +Ġinsect s +åħŃ å¹´ +S ure +è¿Ļ å®¶ +x C +ä¸į çŃī +, h +天çĦ¶ æ°Ķ +ĠDist ribution +æĪij们 å°± +() ); +é© ¼ +Ġf li +æĪ Ĭ +彩 èī² +é¢Ħ å®ļ +im iter +v r +.M sg +ï¼Į åįģ +Ġc uisine +Ġk om +ä½ĵ åĨħçļĦ +t u +ĠM iles +p anel +ĠZ hang +åIJĦç§į åIJĦæł·çļĦ +Ġliber ty +Ġfundra ising +Ġ é»ij +P adding +Ġdisput es +-f ocus +Ali as +- lo +Ġdiscover ing +Ġm int +itud inal +使ç͍ äºĨ +çݯå¢ĥ ä¿ĿæĬ¤ +åľŁ è±Ĩ +in ces +åħ¬å¼Ģåıij è¡Į +æĪij æľī +valid ation +Ġfact ual +Ġliter acy +Ġrid ers +Ġneg atively +åı¶ åŃIJ +èĩª æľī +åĺ» åĺ» +ç»Ħ éķ¿ +Ġqu arters +è¿ĺ è®°å¾Ĺ +åΰ 大 +ä»İ æŃ¤ +osh op +头 çĹĽ +ET A +ï¼Į æľĪ +使ç͍ 寿åij½ +åĴ ļ +Ġprompt ed +çļĦ女 åĦ¿ +^ k +ĠE sp +åħĭ åħ° +缩 å°ı +se ver +à ² +ĠHope fully +ĠFant asy +H ook +ĠIN TEGER +Ġth ou +åĩ ³ +An onymous +ĠLo op +饱 åĴĮ +Ġbre eding +Ġfle w +Ġcomp ressed +ĠPerm ission +Ġ ids +çα好 èĢħ +_l imit +ĠGuard ian +Ġca ption +[ self +Ġmand ate +çİ© æĦı +bor o +身 æĹģ +Ġrecogn ised +ĠSt eps +ç«ĭ æĸ¹ +Ġtu ition +Ġupgrad ed +_c nt +ĠS ter +ix on +CH O +Ġadvertis ements +ç³»ç»Ł ä¸Ń +æĬĽ å¼ĥ +ĠF inding +Ġsal mon +x it +Ġgra ins +Ġam ple +Ġconnect or +R eb +ç½® ä¿¡ +åĨħéĥ¨ çļĦ +Ġ ions +Ġcollabor ate +, A +ĠO liver +.s ort +, æĿİ +æĦı æĦ¿ +ä¸Ģ æĥ³ +pro f +Ġ 红 +De ep +Ġt ribute +åı¯ ä¾Ľ +c opyright +人 æľī +åĤ¬åĮĸ åīĤ +Y C +ä¹ĸ ä¹ĸ +M ir +Ġcou pons +Ġpredict ive +Ġadjust ing +éĹª ç͵ +æķ° çłģ +ra f +In i +_ch annels +æ· « +.S printf +Ġ& \ +éº Ĵ +å°Ķ çī¹ +_h w +Ġdevelopment al +ç´¯ äºĨ +Ġ 请 +activ ation +Ġparent ing +Ġuniqu ely +{ ' +< \ +R en +æľ¬ ç½ij +ĠM ills +Ġp ins +åºŁ æ°´ +çļĦ 对象 +s ame +N ice +çѾ è¯ģ +ï¼Į è¾¹ +åľ¨ åĮĹ京 +çļĦ è¡Ģ +Ġmulti plication +Ġback wards +-t able +Ġneighborhood s +ĠTest ament +ç«Ļ äºĨèµ·æĿ¥ +ï¼Įä¸į åı¯ +оР¹ +ĠI EEE +Ġback ward +è¯ Ľ +ä»İ åīį +n ik +h space +缮çļĦ åľ° +Ġ å¤ĸ +Ġ åĪ« +Ġsomet ime +认è¯Ĩ åΰ +æĺŁ çº§ +.A l +Care ers +æĪij å·²ç»ı +Be havior +åħ¨ æ°ij +ado op +Ġl d +Ġfix ture +duct ory +Ġanten na +Ġ ä¸Ĭæµ· +Ġwor ries +Ġbus es +ĠT ampa +Ġsens es +B ot +ĠF S +èij« èĬ¦ +ĠT ed +Ġmid night +par ation +çļĦ 两个 +Ġbe ats +Ġr x +ĠSh ar +è¿Ļ å¼ł +Ġ$ [ +ort ex +th ree +åłµ å¡ŀ +åľ¨ ç¾İåĽ½ +西 èĹı +l av +ä¸Ń éĥ¨ +ç½ij åĿĢ +un wrap +е к +Ġbrand ing +æŀĹ ä¸ļ +管çIJĨ å·¥ä½ľ +ĠV T +Ġbicy cle +ens en +ãĢģ åįİ +Ġhe ater +Ġst itch +c ross +ĠL ip +æĺ¯ 说 +_n et +.for Each +ĠF IF +ï¼Į æ²ī +æīĵ æī° +ok u +æİĴ éĺŁ +- read +åĨĻ åħ¥ +Ġk a +im ited +宾 é¦Ĩ +åĨį åİ» +æĶ¯ä»ĺ å®Ŀ +od ox +ä¸ī 级 +R AM +ef it +pro perties +Ġwell being +xy z +ÏĢ Î¿ +Ġconv inc +ĠF acts +Ġ' '' +C ourse +两 人çļĦ +Ġal lev +.next Int +Ġsimpl ified +F ilename +:: $ +æŃ¤ ç±» +L AB +_ connect +ä½İ ä¸ĭ +å¹³æĸ¹ åħ¬éĩĮ +ä¸į éĢĤç͍ +rest ore +çł´ äºĨ +ĠW ave +-res istant +åģĩ çļĦ +Ġutil ization +ï¼Įä¸Ģ èĦ¸ +Ġ åįİ +Ġprof ess +èĥ ¤ +' + +ĠB irmingham +âĢľ 好 +ĠIS BN +$ s +ç»´ 度 +-r isk +Ġshort age +欧 ç¾İ +, æ¯ķ竣 +sc rib +çıŃ çļĦ +V IP +åĬ³åĬ¨ åĬĽ +Im pro +ry lic +ur r +Ġfrag ments +IN TER +Ġis set +Ġsort ing +st eps +æģ¶ åĬ£ +Ġw anna +ĠEth ics +ĠC DC +ĠJ uan +, æł¹æį® +M aking +ĠL ect +)) )) +Ġe en +ĠCh ocolate +Comput er +æĭ¯ æķij +_ ) +æĻº åĬĽ +ĠP ill +ox ide +Ġac oustic +ĠRE AL +Ġb ent +_c b +ĠKind le +Ġ ä»ĸçļĦ +-s ource +um ed +Ġl ounge +/ y +Ġ åİŁ +ĠAl most +èĢģçĪ· åŃIJ +hold ing +æ¼Ĥ亮 çļĦ +à ® +ĠProgram me +ex ecute +Ġincorpor ating +ops is +ï¼Į æ±Ĥ +cast le +Ġe Cornell +å°ı æľĭåıĭ +it ches +Ġcr icket +Ġenroll ment +Ġplant ing +Ġquarter back +P riority +ant age +强 åĬ² +éĶ ¯ +è¡¡ éĩı +Spe aking +ï¼Į被åijĬ 人 +主è¦ģ çļĦ +Ġin ability +ĠF ri +for all +ç¹ģ æ®ĸ +ãĢĭ ä¸Ģ +M id +èĭ¦ ç¬ij +å°¾ å·´ +pl ash +DU CT +Ġacqu iring +Ġbo om +ĠMed icaid +.c sv +ĠAccount ing +éĽķ åĪ» +å¾Ī åı¯èĥ½ +/ ch +ĠVis a +fort unate +Ġ éĤ£ä¹Ī +Ġquestion ed +Vis itor +ĠB ee +æ¸ Ŀ +des cribe +æĬ¤ æłı +åı« éģĵ +éŀĭ åŃIJ +éĤ£ 人 +Re commended +ĠS ell +Ġenc rypted +ri en +Ġloc ale +ĠBroad way +æķ´ 天 +Block s +ï¼Į ç»Ħç»ĩ +ä¹Ł 太 +åįł é¢Ĩ +amb oo +主 ç¼ĸ +ph oto +æ°´ éĩı +çĮª èĤī +åŃĺåľ¨ çĿĢ +ãģĹ ãģŁ += / +ĠAnd re +æĴŃ åĩº +éĢļè¿ĩ äºĨ +ä¼łç»Ł æĸĩåĮĸ +åĩº èī²çļĦ +é¼ł æłĩ +Ġrenew ed +Ġn d +ĠJohn ny +æīĢæľī èĢħ +ãĢģ åĮº +f erence +æŁ ¿ +Ġp Ã¥ +Ġscr ut +i our +Ġs ins +æİ§åζ çļĦ +ä»į åľ¨ +奴 éļ¶ +Ġ äºij +ĠY u +çİĭ åºľ +ac ial +Ġterm inated +ç« £ +ä¸ļåĬ¡ çļĦ +æīĢéľĢ çļĦ +Ġins ulation +é¥ º +åħ» æĬ¤ +R atio +ĠPalestin ian +pe x +å®ĥ æĺ¯ +èĭį çϽ +ĠF err +M oney +Sc ott +ĠC able +_b ody +å¸Ĥ æĶ¿åºľ +ï¼Į ä¹ĭåīį +Ste ve +ro e +åij ĥ +åĽł åŃIJ +çŀ » +ï¼Į åıĮæīĭ +Ġmod ular +ĠL ion +ï¼Įä½ł ä¼ļ +Ġbrows ers +Ġcur v +åį ī +åĪĹ åħ¥ +Ġster oids +um en +å¢Ļ éĿ¢ +ä¸į ç»Ŀ +ä¹łè¿ijå¹³ æĢ»ä¹¦è®° +_ use +ĠPu erto +ĠPro cedure +å´ İ +ex ports +ï¼Į让 ä»ĸ们 +å¨ģ å»ī +Ġtraged y +LE X +Ġreject ion +_d f +ĠÎ · +å¼Ģ ä¸ļ +ĠUn known +Ġlect ures +Ġp ads +è£ħ çļĦ +reason able +Ġfound ations +. attr +---------------------------------------------------------------- -------- +ent ric +æľ ½ +.aw t +Ġso cks +Ġa uf +æĻ ĸ +ĠRich mond +Ġtax i +ĠTurn er +ä¸Ģ ä¸ĩ +åĽ½ åľŁ +f alls +ens ing +Ġsubs criber +è¿Ļ 项 +_ EM +Ġpub lishers +åı¯ä»¥ å°Ĩ +Ġstr len +ç¬ ĭ +æĺ¯ 她 +s elling +ĠL anc +èħ¹ éĥ¨ +w al +Ġsib lings +pan ic +Ġbeh ave +ĠEx ternal +ï¼Į æĿľ +ĠâĢ ĭ +Ġin aug +[ str +Ġsp r +L ittle +æĢ» æķ° +M G +qu est +ĠR ental +Ġcle aring +_ ALL +èĮ ¹ +åĽ¾ ä¸Ń +Ġg inger +ĠAdv ice +å¤ĦçIJĨ çļĦ +ĠN F +Ġkind a +ç¨ĭ度 çļĦ +Ġsum s +el lee +æĿ¥ å®ŀçݰ +Oper and +al er +ãĢĤãĢĤ ãĢĤ +Ġterror ism +ĠM ilk +Ġsevere ly +ä¸į åºĶ该 +æĢģ åĬ¿ +ĠInteg ration +, å¼ł +Ġsp arse +è§£ éĶģ +åıª æīĭ +W ire +大 æ¡¥ +_f irst +ĠB ass +éŨ çªĹ +Ġhass le +au kee +ĠV P +æľ¬ èĥ½ +_fe atures +- red +Ġre conc +Ġf art +comp lex +åı¯ä»¥ éĢīæĭ© +Ġinter sect +T oo +.m inecraft +Ġint rinsic +ar l +å°±æĺ¯ è¿Ļæł· +an ium +è¯ģåΏ 交æĺĵæīĢ +åĨł çĬ¶ +S napshot +/ J +RE EN +转 åıij +æĺ¯ 为 +亲 人 +& T +çļĦ åŁİå¸Ĥ +Q R +Ġincons istent +æĺ¯ å°Ĩ +ç͍ ç͵ +w r +der ived +_l abels += * +ĠN ON +Ġhum ble +ï¼Į åĩĮ +çIJĨ æĻº +Ġh arness +D OM +M ic +ĠTh row +_s ave +Ġab ort +åħ¥ éŨ +æī¾ åĩº +ç¢ Ł +æ·±åĪ» çļĦ +er d +æĶ¯ä»ĺ çļĦ +çĿĢ åIJįçļĦ +æĪĴ æĮĩ +Ġt in +å¼ķèµ· äºĨ +Vari ant +å±± ä¸Ĭ +Ġde er +Ġtr an +马 æĭī +-s chool +ï¼Į åĢŁ +çŁ¥ æĻĵ +m un +Ġbro kers +ĠEqu ity +ï¼Į åĬĽ +Ġpse udo +ॠĩ +æĿ¥ çľĭçľĭ +Ġf ame +Ġcomm erce +, å½ĵçĦ¶ +ä¸ĭ åŃIJ +åı² ä¸Ĭ +_{ {\ +ĠDis covery +åĮ»éĻ¢ çļĦ +% ). +ine a +综 ä¸Ĭ +v oke +ï¼Į æľįåĬ¡ +Ġis ot +ä¹ĭ 以 +è¯ ł +çľģ å§Ķ +ĠA SC +Ġr and +Ġen semble +-s ign +Ġsmart phones +D ao +äºĭ åIJİ +Ġrequest ing +N L +Ġcontinu ity +to Equal +Ġme g +åĪĨéĴŁ åIJİ +æĮĩ çļĦæĺ¯ +çİĩ é¢Ĩ +Ġchem otherapy +Ġoverwhel med +t ar +rel ations +ith ium +.P oint +æ¶² æĻ¶ +ĠMont ana +ï¼Ľ è´Łè´£ +ĠS eb +S omething +ĠBO OL +ĠShe et +M ont +æ¼Ķ æĬĢ +ĠM atter +ir ational +ä¸Ģ çļĦ +ĠC ad +ĠE lection +Ġform ally +-b uild +t v +Look up +Ġthought ful +-r ich +çϽ äºij +æ±ĩ èģļ +t im +ĠG em +åΤ å®ļ +Ġret rieved +ĠIm per +ĠC ache +Ġhum idity +ãĢĤ ï¼Į +.st ream +ĠOld er +ç«¥ å¹´ +çļĦ女 åŃIJ +ç» ¯ +Ġinf ants +ĠM AP +Ġm ul +Ġre vis +éĩijèŀį æľºæŀĦ +ĠTy ler +æİ IJ +ĠAltern atively +-e ffective +æł¸éħ¸ æ£Ģæµĭ +ãĢĭ 第 +Ġsc ent +åķ § +{ V +ĠR ET +b at +åı¯ä»¥ 为 +æīĭ éĩĮçļĦ +Ġquadr atic +Ġ第ä¸Ģ èĬĤ +Ġp ou +äº ¥ +Ġsou ls +Ġrot ating +æŃ£ å½ĵ +Ġd c +ownt own +è¡Į 使 +åİŁ ä»¶ +Ġsil k +çļĦ çŁ¥è¯Ĩ +ĠCons ervation +çľĭ å¾ħ +ä¼ĺéĢī çļĦ +us able +×Ļ × +Ġlack s +çļĦ éĩį +ç¬ijçĿĢ è¯´ +}^{ ( +ï¼Ī 以ä¸ĭç®Ģç§° +éģ¿ å¼Ģ +éĹ ½ +, æıIJé«ĺ +èĢģ é¼ł +åĽ½ åºĨ +Ġsm iling +ĠS it +inc ipal +代表 大ä¼ļ +æİ¨ å¼Ģ +b oss +Ġc inema +uss els +Ġbeat en +说 æľį +_m enu +Ġax es +çļĦ åĽ½å®¶ +ĠU L +An not +Th reshold +Ġf og +æľī åĪ© +æĶ¾ å¼Ģ +N amed +ï¼Įå¦Ĥ åĽ¾ +Ġrefriger ator +Ġd ots +çĽij è§Ĩ +Ġdef ending +èĢĮ èµ· +æ®ĭ éħ· +F rank +éĺ ± +ëĭ ¤ +Ġreal ise +ï¼Ł æĪij们 +O CK +_ env +Ġs ung +ĠCo in +Ġ ____ +.res et +Data Type +ĠR ates +RE T +_B L +èļĤ èļģ +the m +çIJ ħ +Ġstr anger +æĬĬ èĩªå·±çļĦ +qu in +ĠF u +Ġfl ame +ATION S +os omes +vis ual +å¹´ å¼Ģå§ĭ +- as +æľĢ å¤ļçļĦ +ï¼Į大 éĥ¨åĪĨ +客æĪ· æıIJä¾Ľ +Ġinstrument al +Ġeng lish +æĿ° åħĭ +_P REFIX +c ents +æį Ĩ +-y ard +ãĢģ åĪĨ +ĠO scar +.param s +åıį æĢĿ +db c +ENT IAL +对 æĪij们 +ĠB in +itut ions +n v +. Contains +æ¯Ķ çī¹ +Ġà ¤ +æĢĿ 念 +æ¨ Ĭ +sp ired +ĠNeb raska +广 å·ŀå¸Ĥ +åIJij å¤ĸ +åıĹ æįŁ +æłĩ 注 +ĠP apers +war f +æĬ¥ éħ¬ +çļĦ ä¼ĺåĬ¿ +ĠN athan +av our +ĠWell ness +åĪĽ æĸ°çļĦ +ud er +Ġd rought +å®ļ æĹ¶ +Ġpro state +ĠSh ape +- index +Ġdecor ation +çļĦ åı¯èĥ½æĢ§ +åµĮ åħ¥ +/m L +P ick +ï¼Į åĥıæĺ¯ +Ġw ounds +Ġnegot iate +çļĦ èĦ¸ä¸Ĭ +. ~\ +, _ +Ġw ires +ER IAL +Ġ" { +N V +èĥĮ ä¸Ĭ +ĠS AP +n ate +Ġintegr ating +ĠT ip +ĠClass es +çľĭ ä¸įè§ģ +åĩĢ é¢Ŀ +. transform +Ex ecute +Ġorgan ised +è®® 论 +çĥŃ çº¿ +Eval uate +'. $ +ĠArg uments +ĠR ivers +ä¸ĩ å¹³æĸ¹ç±³ +ĠCert ification +ĠAust ria +s ymbol +us ions +éľĩ åĬ¨ +.m ock +æ± IJ +Ġst air +_st ack +ĠAss istance +E arly +D ifferent +Å Ļ +M Hz +J on +ĠLiter ature +Ġinv oice +çģ° èī² +ĠWood s +ĠU RI +Ġball ot +ãĢģ åIJĦ +t ools +è¿ĩç¨ĭ ä¸ŃçļĦ +++ ] +ç§ī æī¿ +æ¯Ľ çĹħ +ĠP ul +Ġar tery +ur ally +\ new +Ġ åΰ +çªĹ å¤ĸ +ĠSD K +åIJī 祥 +ĠPay Pal +ĠL akes +arett es +æĦı æĸĻ +ä¸ĭ å·´ +Ġir regular +åįĸ åĩº +ĠF unctions +åIJĥ å®Į +ĠMembers hip +Ġrig orous +åģĩ æĹ¥ +æĹ¶æľŁ çļĦ +æĸ¯ æĭī +è¿ĩ åĪĨ +Ġdecor ating +âķIJ âķIJ +带 头 +ĠHe avy +e enth +å¹´ éĻIJ +-c ost +ĠCons ists +H on +ĠMarg aret +ĠDE BUG +Ġformer ly +° ÃIJ +X P +Ġinv iting +_P O +Ġvalid ated +ĠDen mark +Ġ第äºĮ èĬĤ +Ġcock tail +Ġo c +View ById +sc roll +çļĦ æĶ¯æĮģ +ĠK irk +R SS +_ ENTRY +æ¿Ģ çĥĪçļĦ +åıª æĺ¯ä¸Ģ +ĠL C +æĢ» æĶ¶åħ¥ +], [ +å°½ åĬĽ +è¿ĩ å¹´ +ĠA x +äºĨ äºĽ +Ġl ime +ĠSec ure +ab lish +ĠAb d +Ġ* _ +t ake +ãĢĤ æĪªèĩ³ +p k +çĿĢ ä»ĸçļĦ +æ¼ ĵ +ä»į æĹ§ +Ġwe aken +ues e +_result s +ĠB ever +L i +ĠStan ford +-g rade +ĠN HS +éķ¿ ä¹ħ +éĿĻ æĢģ +ah u +æĬ¥ å¤į +åħ¨ éĿ¢çļĦ +Ar rays +ĠSand ers +ĠD ialog +Ġcand le +Ġexplan ations +å¯Į åIJ« +å®ŀ ä¸ļ +Ġf ocal +ust in +- transform +ĠArg entina +Ġenc oder +Ġe g +Ġsol ic +ç¬ij ç¬ij +Ġcraft s +Ġtur key +ç®Ģ 约 +ĠCh ase +ä¸Ńå°ı ä¼ģä¸ļ +Ġ é¾Ļ +_ USE +污水 å¤ĦçIJĨ +Ġopp osing +ï¼Į éĢļ +C tx +r il +. ts +Ġcirc uits +ç¥ ł +é¦Ļ æ°Ķ +ĠDel aware +Ġmer cy +F ail +.B ase +Ġhapp ier +åº IJ +p rom +ç®Ģ åĮĸ +ial is +Ġterm ed +ĠO PT +inc inn +ĠFort unately +Mark er +åıª éľĢ +éĢĢ å½¹ +File Path +ĠP rad +-f ace +_ loc +è¡Ķ æİ¥ +Const raints +ç͵ ç«Ļ +Ġattack ing +{ lem +Ġb ang +ĠâĢ º +Sh arp +Ġexam ines +he y +Ġcyt ok +ĠM RI +in ja +F it +Ġ è¿ĺæľī +æĮĤ åľ¨ +æīį è¡Į +å¹³ æĿ¿ +}_ \ +div ision +m ouse +Ġresearch ing +Ġcal ibration +U lt +In gredients +Ġb p +ï¼Ł ï¼Ł +ĠN BC +æĺİ äº® +Ġm align +åħī ä¼ı +座 è°Ī +æľºåύ åŃ¦ä¹ł +å´Ľ èµ· +ĠOk ay +Ġabsorb ed +ï¼Į æĽ´åĬł +èľ ĺ +_g en +å¸ĥ é²ģ +Ġch unks +Ġvis ually +.D ebug +Ġencour agement +ĠE agle +Ġrecogn izing +U int +sc ore +æ© ± +ĠB ug +æľĢ æĸ°çļĦ +(std err +F ive +ä¸ĭ 次 +aly zer +pect rum +ç³ ¯ +æľī ä¸į +éĥ½æĺ¯ åľ¨ +Ġprolong ed +æ² Į +al ink +sc ience +è°ĥ åĬ¨ +Ġharm ony +Ġsuff ix +Ġsubt ract +éģ ģ +ops y +.h andle +ĠEnt reprene +èĢĮ æĺĵ +ĠStrateg ies +Ġd iving +çľĭ æĪij +Ġsynt hes +Ġdis ruption +or ate +ï¼Įæľ¬ å®ŀç͍æĸ°åŀĭ +ä¹ĭä¸Ģ çļĦ +æīĵå¼Ģ äºĨ +æī¿ åĬŀ +Ġc ough +ï¼Įè¦ģ ä¹Ī +åĨ° åĨ· +Ġt ones +交éĢļ è¿IJè¾ĵ +Ġf lee +主 æĴŃ +ä¼Ĭ æľĹ +æĵ Ĵ +ĠCONTRIBUT ORS +ĠC K +ç»ĵæŀĦ 示æĦıåĽ¾ +æĺ¯ 好 +T ell +Ġve gg +èµ¢ å¾ĹäºĨ +Ġhypert ension +Ġdis placement +ĠOut look +Ġsent enced +ĠN M +Ġfeed s +Ġ åIJį +èľĤ èľľ +Ġinv asive +Ġelim inating +å¹³ ç±³ +ĠSh aw +äºĨè§£ ä¸Ģä¸ĭ +l ibrary +Sh adow +Dep artment +声 说éģĵ +_f loat +两 åĽ½ +c pp +ĠC er +çŃ Ŀ +W IN +ge ometry +表 è¿° +Ġtechn icians +Ġparent al +ĠComput ing +Cent ral +it ably +ï¼Į é¢Ħ计 +OK EN +, è°ģ +å¹´ åĨħ +ä¸į åIJ« +äºĭ äºĨ +re lease +.value Of +äºĨä¸Ģ ä¼ļ +åħļ åı² +çļĦå¿ĥ æĢģ +ï¼Į ç«ĭ ++ x +Ġfluct uations +Ġcontin ent +åĽ° æĥij +éĤ£ åĦ¿ +Ġgate way +ä¿¡ èªī +qu it +ĠPro blems +åħĭ åĬĽ +b ug +æĸ° åĬłåĿ¡ +ï¼Į èĦ¸èī² +Ġsq ft +åıĬ 缸åħ³ +ĠIndust ries +éĽ Į +eren cing +交éĢļ äºĭæķħ +NECT ION +eng es +ï¼Įä½Ĩ ä¹Ł +è¶ģ çĿĢ +ä¿ĥ éĶĢ +Ġdown stream +级 åĪ«çļĦ +èµĦæºIJ çļĦ +Ġcr ude +Ġnom inated +æĶ¹ ç¼ĸ +[] { +ĠC ake +çݯå¢ĥ ä¸Ń +at z +Ġsal vation +Ġlaun ches +èĢĥ åı¤ +Ġwilling ness +çĤ¹ çĩĥ +å¾Ĺ èµ· +ĠPartners hip +ĠHOLD ERS +è·¯ è¾¹ +ä¼ĺ ç¾İ +Ġm uc +Click Listener +Ġinhib itors +ä¸İ 第äºĮ +g as +Ġsusp icious +ä¸ŃåĽ½ åħ±äº§åħļ +Ġiter ations +Ġquestion ing +- , +çľĭ åİ» +åIJĮ æĥħ +th m +èĽ Ļ +åĹ ¡ +åİĨåı² çļĦ +Found ation +_s um +Ġver bal +Ġelabor ate +ĠTre asury +Ġcum ulative +ä»ĸ èĩªå·± +ĠS I +éĢī åıĸ +_OB JECT +两 端 +ï¼ĮçĦ¶åIJİ åĨį +T el +Ġident ities +ĠFl ight += âĢĿ +çģ« çĪĨ +ĠWH O +s r +Ġpupp y +çĹħ æĪ¿ +Ġbrack et +ĠAl ert +Ġec ological +çĥ ¨ +æĿĤ è´¨ +ĠM eg +微微 ä¸Ģç¬ij +het ics +èĬ ¹ +/ html +LE AN +çİĽ 丽 +ap ital +Ġnob le +管çIJĨ ç³»ç»Ł +ĠOper a +çļĦè¯Ŀ è¯Ń +Ġrock et +骨 å¹² +Ġæľ¬ æľŁ +Ġprofession ally +Add itionally +é© ¿ +é¡¶ å°ĸ +åľ¨ åĨħçļĦ +ä¼Ĺ çĶŁ +Ġf ried +ew ay +F ACE +èĤ ĭ +ĠSc ar +ĠIns ert +RE ATE +çī¡ ä¸¹ +Beaut iful +Ġ" * +æ²³åĮĹ çľģ +Ġirre levant +ĠAl zheimer +ĠC atal +ner g +(d b +ä¾§ å£ģ +Ġè¿Ļ æĹ¶ +Ġcan cers +Ġreplic ation +车 身 +h om +åĬ© æīĭ +å¼Ĥ è®® +Like Liked +Ġ 产åĵģ +Ġmod al +ç± ½ +Ġexceed ed +Ġr ays +Ġsens ible +Ġper mut +两个 æľĪ +è£ ³ +ï¼Į åŃ¦ä¹ł +å°Ĩ è¿ij +_d iff +Ġvirt ue +Ġw r +incinn ati +J eff +a q +Ġblog gers +Ġrenew al +и к +ian e +éĽĨ 群 +Ġemp athy +Ġinject ed +Ġv ir +trans lation +ĠM BA +å¿ħ å¤ĩ +Ġlun gs +Ġgrand father +Ġsh ook +ç͵åĬ¨ 车 +th ood +Ġpres erving +ay ing +Ġcl icks +Ġl oses +u ite +Ġnot ably +åįĹ å®« +æĢİä¹Ī èĥ½ +èľĺ èĽĽ +ç«Ļ çĿĢ +-d o +ĠInstall ation +ĠV ista +ĠC anyon +离 å¿ĥ +Ġsequ encing +Ġcan n +R ay +çĽ² 缮 +åħĪ è¡Į +佩 æľį +ãģ ¤ +, S +å¥ĸ éĩij +Ġsc attered +å¤ĩ åıĹ +pro xy +Ġres in +Ġrest ing +ĠM t +con y +.S ub +ĠChe f +ĠA sp +å¾Ĺ ä¸į +Ġcat ast +åύ æĿIJ +æ¹ĸåįĹ çľģ +ĠS outheast +< ul +D ark +ä¹ĭ æĪĺ +Ġtow el +Ġpat ri +IB ILITY +åįĸ å®¶ +s ym +ĠD ump +Ġd ull +åŁºéĩij ä¼ļ +ĠT ours +ĠNe il +.A ct +ï¼Įåľ¨ è¿Ļ +ĠRepresent ative +篮 æĿ¿ +(c md +Ġmem orial +ĠB less +å°ı ä¼Ļä¼´ +ãĢĤ çͱ +ä¸ĵ å±ŀ +Ġtr unk +EO UT +W L +M V +åİĤ æĪ¿ +Th an +以ä¸Ĭ å°±æĺ¯ +表çݰ 为 +Exper ience +ãĢģ åĩĨç¡® +Ġ(! $ +Ġrec reation +н а +ĠC MS +ĠPress ure +æ¸ į +éĻį 临 +Ġreferr al +Ġsh irts +b ps +欺 éªĹ +al c +æł½ åŁ¹ +Ġwhat soever +oler ance +icon ductor +W ay +Ġcrowd ed +ac l +çĶŁ çĹħ +- Q +board ing +up dated +Ġsym path +央 è¡Į +n eg +Ġrail way +pl ed +ĠAD D +ç͵ ç½ij +umb ling +ï¼Į é½IJ +Ġintern ally +en cer +-c ount +é£İ æīĩ +èĢķ åľ° +Ġcont ing +ĠBapt ist +æģ ª +Ġtor que +æİ§èĤ¡ èĤ¡ä¸ľ +å½ĵ æĹ¥ +å°Ĩ æĺ¯ +Ġg rep +ä¼ļè®® 室 +Sign al +娱ä¹IJ åľĪ +A pr +ĠG len +ï¼Į æİ¥ +ĠInst ruction +éħ Į +. second +ig hed +String s +é²ľ èĬ± +Creat ing +è¿Ļä¹Ī åģļ +w aukee +èĩªå·± æĺ¯ +, æ¯Ķ +Ġphys iological +aa S +(t emp +æĪIJ 年人 +d eb +ä¸Ģ æĹģ +Ġ åħ³äºİ +ĠA ds +D rive +缮åīį çļĦ +åĽĽ åŃ£ +time out +{ I +æŁĶ åĴĮ +Ġ åIJİ +ycl ing +Ġcom ed +è·Ł 她 +追 踪 +ĠS che +Ġ第ä¸Ģ çϾ +ser ies +ä¸ĭæĿ¥ äºĨ +Ġbal ancing +è¿Ļ ä¸įæĺ¯ +æ» Ķ +Ġb ake +Ġbo asts +çĭĹ çĭĹ +è¯Ħ åĪĨ +åĩł çİĩ +( other +æµ· 岸 +User name +Ġinitial ized ++ ' +ĠC ritical +åį´ åıĪ +Ġexceed s +Ġa fore +大 çĽĺ +转 ä¼ļ +鼶 éĥ¨ä»¶ +Ġpass port +Ġamaz ed +RN As +ï¼Į 满足 +ï¼Įæĺ¯ ä¸Ģ个 +Ġsan ct +Ġmarg ins +ach i +åĩł ä½ķ +轩 è¾ķ +åĬ¨ çĿĢ +ä¸Ģ èĦļ +æĮģ ä¹ħ +.M ax +ĠS UV +èĩ³ åħ³ +ĠTe achers +ĠPot ter +ĠC ox +- axis +æĪij éĥ½ +Read ing +ï¼Įåı¯ æĥľ +or ida +Ġfro st +.C urrent +Ġanticip ate +os ion +pl aced +æĥ³ èµ·äºĨ +Ġantib iotics +Key words +{ item +åĽº åĮĸ +Ġpul monary +en umer +Ġcos metic +ï¼ĮèĢĮ åľ¨ +ãĢģ çĶŁæ´» +With in +çºł æŃ£ +ĠUt il +Ġped iatric +า ภ+åIJŀ åϬ +æģŃ æķ¬ +ä¹Ķ æ²» +Ġeconom ies +Ġt m +æ»´ æ»´ +? > +Ġadm ire +Ġrec reational +ÑĤ о +Ġpup ils +Ġwond ers +ĠAny way +Ġbegin ners +op athy +åķĬ åķĬ +æİ¨ çIJĨ +ä¸Ń çŃī +è¿ĩ æĿ¥äºĨ +Ġemb edding +çĤİ çĹĩ +æŁł 檬 +| ^ +ĠAr n +æ·± åıĹ +. root +é£İ äºij +设置 çļĦ +SE O +Ġenerget ic +Ġret ros +Ġprec aut +ĠN UM +- ne +Ġ æĺİ +âī ¥ +G H +Ġra p +ĠLe af +Ġstation ary +åħħåĪĨ åıijæĮ¥ +çħ§ å°Ħ +Interview er +Ġbath rooms +; " +R ating +. pos +åζ èᝠ+èµĦ产 çļĦ +Ġab b +_en abled +ĠJ os +å®ļ åIJij +éķ¿ äºĨ +æĹł è¯Ń +( info +Ġimpair ment +æĬ¤ åį« +èīº äºº +åįĬ åľº +Ġdam aging +èĪĨ 论 +Ġworks heets +In side +ĠIn nov +ĠP oker +.C lose +St aff +Ġab st +ï¼Į ä¸Ĭæµ· +oc on +Ġl ining +clos ures +Ġgame play +-sh irt +å¹´ 第 +ï¼Į éģĤ +å±Ģ çļĦ +说 åĩºæĿ¥ +Ġhe y +Ġ 顾 +ä¸Ń æĸŃ +p H +omb ie +Ġyear ly +åĴĮ æ°´ +rehens ion +_ active +ĠK ill +Ġc f +ä¸ĩ ä¸Ģ +ç¬ij æĦı +ĠId aho +.sub string +æĢ§ 强 +ol ia +ãĢģ C +pl ing +.cl one +ï¼Įåıª 好 +Ġproblem atic +ä»ĸ 对 +Ġphosph ory +ç»ĵ æĻ¶ +det ails +ĠNash ville +_t mp +Ġp id +ĠC BS +ĠEd wards +Part y +åºķ æĿ¿ +ien na +Ġste pping +Pub lisher +D ot +oc yte +ï¼Įä¸į æķ¢ +Not ice +ç¨ ł +ĠStrateg ic +ä¸Ģ è¶Ł +ä»· çļĦ +Ġundert aken +Ġf ights +è°ĥ åij³ +äºİ ä¸Ģ +æĺ¯ å°ı +or p +Test ing +M att +ç» ħ +岩 çŁ³ +ĠTh under +ĠS we +Ġe lem +Init ialize +åħ·ä½ĵ å®ŀæĸ½æĸ¹å¼ı +Ïī ν +æĬķ éĻį +æģ¶ æĦı +Ġd umb +æ¹ĸåĮĹ çľģ +éĤ ¢ +(N ULL +ãĢĤ åIJĦ +um bs +ä¸İ æĪij +l ining +Ġfe ather +Ġi Tunes +- play +æĿ¥ åģļ +Ġaff ection +ĠA TM +ç´« èī² +Ġdeb ts +æĺ¾ çݰ +z b +Ð Ĥ +ĠNorth west +Ġexplo it +æį¢ çĥŃ +_tr ue +ins ula +Ġplur ality +ĠMont real +Ġdevast ating +ĠK u +为ä»Ģä¹Ī ä¼ļ +æĹ¶ éķ¿ +ĠSh ared +åıĹ äºĨ +affe ine +ĠN intendo +çł Į +Pl ug +g ow +v l +Ġprefer ably +ä¸Ģ è½® +ex ists +T ick +Ġnumer ic +up iter +åįķä½į çļĦ +ä¾ Ī +Ġwh isk +Pref erences +Ġr é +, ä¸ī +ĠH udson +J apan +ĠL imit +å· į +åħĥ å¹´ +Ġn i +çı ij +Ġl akes +Z Z +诸 侯 +{ O +à ´ +Ġhon our +ä¸İ 第ä¸Ģ +ãĢģ æ³ķè§Ħ +w ic +Ġb loom +ĠTra ffic +[ d +ex pl +ĠVit amin +Ġfab rics +P ipeline +ç»ıèIJ¥ èĮĥåĽ´ +Ġpres ervation +ĠEv olution +æ¦ ´ +T OP +åŁºéĩij管çIJĨ 人 +ä¸Ģ å°ı +ĠWell s +ï¼Į ä¹Ŀ +Ġload er +Ġm all +Ġfulf illing +èĥ½ 为 +Ġdos age +ï¼Į è´Łè´£ +ãĢĤ ä¹Łè®¸ +ĠFin n +ro ts +op edia +ï¼Ī ä¸ī +ç½ij æł¼ +b uilder +é¢Ŀ 度 +ĠC el +èµ° æĿ¥ +Ġrout ing +Ġfinger print +éĴ ŀ +Prof essional +Ġind igenous +è°ĥ çIJĨ +ĠR N +ĠVol unte +è½» å¾® +.d ir +, & +ĠX CT +ĠSh ip +说 çļĦæĺ¯ +æĻ ı +ĠAb u +Ġ èĩ³äºİ +. el +* } +éĵĿ åIJĪéĩij +æįķ æįī +Ġbrid ges +ï¼Į å¿Ļ +ĠC rypto +线 åľĪ +Ġsubject ive +Comp lex +Ġdef ic +Ġinstruct ed +æĺ¯ ä¸įä¼ļ +ãĥ ķ +_time out +ant o +Ġsynchron ized +ãĢģ 产åĵģ +Christ ian +RO P +Ġhorm ones +J K +Ġ$ - +é»ij çļĦ +ĠG ear +th anks +Ġx y +ç»Ħ è£ħ +ĠJul ie +ĠN P +OBILE PHONE +è® ³ +URRE NT +ind ers +ĠS plit +!!!! !!!! +èªī 为 +人 人 +}\ , +_ select +åĪĿå§ĭ åĮĸ +.g z +: ", +Comp letion +Ġsk irt +Ġe in +Ġexc el +计åħ¥ å½ĵæľŁæįŁçĽĬ +ĠS r +Ġsurviv ors +å°± ä¸įæĺ¯ +Ġnow adays +Ġpos es +âĢĺ s +ĠEduc ational +带 èµ° +ä¿Ŀ å®Ī +Ġst aining +tras ound +Ġrecycl ed +. entity +ĠL ots +Ġcomp ilation +att a +ĠB anks +Ġsens ory +Ġhard est +Ġprison ers +ï¼Į说 ä¸įå®ļ +Ġs age +ĠN ad +ï¼Į çĶŁæ´» +æĸ IJ +ç¨į ç¨į +Ġshut down +ag ged +_C R +UBL IC +S UB +co h +ĠVeter ans +Ġlic ence +åŃĻ åŃIJ +Ġshort s +è· ĭ +Ġlip id +, ä½ľä¸º +D X +ĠDog s +ï¼ĮæĪij åľ¨ +_c lose +èĹ © +çĽijäºĭ ä¼ļ +Ġun law +- header +Ġcomplex es +è¡Ĺ 头 +ä»Ĭ å¹´çļĦ +" ][" +ĠColumb us +Ġex otic +æĭįäºĨ æĭį +_point s +ĠBrazil ian +çļĦåľ° ä½į +å°Ķ 夫 +ĠM akes +Ġc yst +Ġend if +pi pe +Ġarth ritis +åĽŀ éģ¿ +æĪ¿ éŨ +ĠTH AT +_P RE +ĠSl ot +- so +S ources +Ġac ne +( + +Ġ第 ä¸ĥ +Ġcris p +ï¼Į åŁºæľ¬ +æĺĬ 天 +ï¼Į è¡Ģ +ç¾½ æ¯Ľ +åĨ· æ¼ł +èµ· æŃ¥ +Ġcrow ds +çijŀ 士 +ĠBl ues +og onal +ãĢģ çĶŁ +Res p +åIJ¯ åıij +Ġreserv oir +åι 车 +ĠJere my +ç®Ģ åİĨ +èĮ µ +( img +se ed +_n ull +C riteria +Ġle ap +ull ivan +ĠP repare +Z oom +çļĦ说 æ³ķ +c op +Ġd ioxide +per t +æĬĺ èħ¾ +Ġhead lines +声 åĵį +ĠHon or +.d art +å°± å¾Ī +å½¢å¼ı çļĦ +æĦıä¹ī çļĦ +äºĨ æĪijçļĦ +ss on +Ġsound ed +.in ternal +per iod +ï¼Į åĪļåĪļ +G UI +P en +çģ ¸ +( O +Ġfix es +ãĢĤ å¸ĮæľĽ +åħļå§Ķ 书记 +两 岸 +ï¼Į è¾ĥ +æĻ¯ èī² +ä¹ĭ æīĢ +Ġobserv ing +ĠBM W +; < +ĠHe ader +DM I +ft est +å°Ĩ ç»§ç»Ń +è½® å»ĵ +Ġsuper visor +Th omas +f etch +è¡Į æĺŁ +å°±æĺ¯ è¦ģ +Ass ign +Ġw oke +Ġadministr ators +Ġtrans ient +ï¼Į 羣æŃ£ +åĢŁ éī´ +Ġco zy +åĪ» æĦı +æ¸ º +Ġal phabet +ig uous +ĠPort al +Ġcr ushed +ĠGro ve +ĠFred er +at omy +? ' +mit ter +.H ttp +Ġ( ** +Ġj ealous +ĠC ities +ï¼Į转 身 +èĬ · +ĠK in +ä¹Ł å¾Ĺ +Ġrandom ized +ĠJam ie +鼷 è¾¾ +ï¿ ¥ +ĠØ ¨ +çĮ ¿ +t bl +åĵģ å°Ŀ +éŨ æ§Ľ +BO X +W all +æĽ¾ åľ¨ +p ine +Ġa in +ry s +åĽĽ 人 +åĨµ ä¸Ķ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠ +ĠU TC +\ alpha +Ġrecess ion +åł ķ +ffff ff +å½Ĵ å±ŀäºİ +åħ¨ å¹´ +ang led +éĿł çĿĢ +ra ced +ĠP ra +çī¢ åĽº +ĠUk rainian +Bet ween +ï¼Į å·´ +è¿ĺ ä¸įæĺ¯ +Ġspokes man +åŁİ åł¡ +è¯Ĺ è¯į +ĠAn swers +ĠJeff erson +Ġre construct +æ¢ § +D estroy +éĢĥ è·ij +Ġdiff ers +Al gorithm +h ouses +Ġe Bay +ĠBase ball +æīĢåľ¨ çļĦ +- conf +an vas +_T AG +ur f +å½ĵ åľ°çļĦ +Ġcharacter ization +ĠÏ ī +Ġr ises +Ġsh red +Pro blem +èĢģ 太太 +ĠP ull +ï¼Įéĥ½ ä¼ļ +- space +å¿« çĤ¹ +çļĦ æŃ£ +m L +d ie +ĠN um +客 è¿IJ +ĠCo hen +åİĨ ç»ı +Ġst yl +an ese +View Model +ĠO pp +失 踪 +åĴĮ ä»ĸçļĦ +ĠCom ing +ĠCoord inator +_ ret +è¿ĺæĺ¯ æľī +æķĻ çłĶ +ut ation +Ġch ase +ä¿¡æģ¯ æĬĢæľ¯ +Ġcongr at +st en +ĠC ourses +Ġfra ctions +å·² çĦ¶ +ãĢ ī +br and +Ġ} } +éĿĴ å±± +olly wood +æīĢ æľª +ik er +æķ° 缮 +ï¼ļ æľ¬ +odd ed +Ġsuscept ible +ĠHill ary +_CL K +par able +ĠN HL +ĠInd igenous +æİ¨ è¡Į +ĠCh ile +çĽĴ åŃIJ +ĠVin cent +æ»ļ åĬ¨ +ĠZ en +- get +ĠVAL UES +ï¼Įä¸į å°ij +P rior +ĠHel en +è¿Ŀæ³ķ è¡Į为 +çļĦ æľĢ大 +ĠEffect ive +ãĢģ åĮĹ京 +( @" +g c +ãĢĤ æĮīçħ§ +æĤ² åī§ +æŃ¦ åĬŁ +Ġpump kin +op us +Ġexpress ly +ä»Ģä¹Ī éĥ½ +Ġc t +ï¼Į åħ¥ +M X +-C o +Ġno on +XX X +_g raph +W ood +Ġco il +ï¼Į ä¸Ĭè¿° +ush i +urt le +Ġatt rs +æģ¢å¤į äºĨ +_IR Q +BA SE +深深 çļĦ +ĠDou g +role um +æīĵ è´¥ +che str +èĨ Ľ +Ġrad ial +Ġsp ends +ĠDemocr at +ud get +Ġ} \ +Ġc ables +.res olve +b uff +çĿ£ ä¿ĥ +æĤ¬ æµ® +è§Ħ 竳 +read s +cond itions +see ing +幸ç¦ı çļĦ +plan ation +-d oc +) > +C am +Ġexhaust ed +æ¸ħ æĻ¨ +ĠMount ains +ar an +ãĢĤ 以ä¸ĭ +çĥŃ è¡Ģ +ë Ĭ +Ġre use +Ġim pe +.F rom +rolog y +Ġlast s +, e +é ł +.t ar +ĠHol land +p ng +è re +- o +Ġhe els +ĠIll ust +han ie +ĠB oost +By Name +H a +æľ¯ åIJİ +Ġplan ets +Separ ator +å¼Ģå±ķ äºĨ +åŁĥ åıĬ +/ web +_t otal +s ingle +Ġd ementia +_ ACC +代 çļĦ +宪 æ³ķ +ĠN ap +ï¼Į åı¦ä¸Ģ +å½ĵ ä½ł +èĢħ åĴĮ +.prot obuf +ĠA mazing +ĠPl astic +_S HA += n +å±ĭ é¡¶ +ĠT F +âĶĢâĶĢ âĶĢâĶĢ +Ġ èĭ¥ +管çIJĨ åĪ¶åº¦ +Ġun fortunate +Ġre build +ĠPol l +Ġ åħ« +rack ing +list ed +éĻ¢ åŃIJ +ï¼ļ " +åIJĮ ç±» +Ġ éĿŀ +Ġcreat ors +Ġ ------------------------------------------------ +Ġsign atures +and el +Ġv apor +Ġfulf illed +æľī 大 +ĠProf ession +ĠP ush +åΰåºķ æĺ¯ +ï¼Į æĿĢ +Ġyoung est +. offset +Y ES +æĴ¤ éĶĢ +Ġd well +ĠW AY +Ġ_ . +åĮ» æĬ¤ +ak u +ĠB ike +Ġaccum ulated +Ġsk ew +çĶ· åıĭ +Ġconsequ ently +Ġdown s +bo ys +_c ap +P romise +l ia +ĠLook s +Ġinfect ious +ï¼ĮèĢĮ åIJİ +Ġadequ ately +æĪij 对 +[ a +ï¼Į ç»Ī +ject ed +Ġaim ing +ON D +. Image +ĠD ual +æĹ¥ ç͵ +< I +i agnostics +èĢģ èĻİ +ĠHarr ison +- inter +åľ¨ 天 +ĠSh akespeare +ood le +ä¸Ģ åı° +éĹ® éĹ® +çıŃ åŃIJ +æĺİ äºĨ +B oot +ï¼Ī åĮħæĭ¬ +Ġcraft ed +( code +ĠRog ers +è¯ģåΏ æĬķèµĦåŁºéĩij +Ġgam ers +ä¸į èĥľ +æIJľç´¢ å¼ķæĵİ +Ġv ou +ï¼Įä½Ĩ è¿Ļ +ĠF ee +ï¼Į éĢģ +æļij åģĩ +G I +Ġcapt uring +cel and +Ġz eros +ĠW u +.A tt +, M +å«Įçĸij 人 +Ġseam less +æĸ° 浪 +å¹³åı° çļĦ +æīŃ æĽ² +ĠL ights +Re place +K ernel +" ( +ĠRes pond +ĠTH EN +an ie +åĬ¡ å¿ħ +åIJį 人 +Ġ äºİ +Ġbe verage +丨 丨 +Ġgener ators +çļĦ åIJĹ +Ġ ], +ï¼Įæ¯ı å¹´ +åĮĸ åĴĮ +èµ° è·¯ +b old +Ġcoll ar +ĠC RC +æ²» å®ī +ä¹Ł æ¯Ķè¾ĥ +ç§° åĶ¿ +Ġfl ies +ĠNEW S +ĠFor ces +ĠAlber ta +ĠK il +as se +ï¼Į æļĹ +. location +T OR +æĹ¶ åĪĨ +ï¼Į æŁ³ +Ġsuper market +, åIJij +Ġ ä½ľèĢħ +Ġcoll agen +_ QU +å¾Ī é«ĺçļĦ +_ App +ï¼Įä¸Ģ çĤ¹ +_n odes +Ġlad der +åĩĨå¤ĩ 好 +Ġrun ners +æŀ ī +g m +Ġprint able +ĠV S +column s +d h +ãĢĤ èĩ³ +Tr ump +Ġdr one +åĨ³å®ļ äºĨ +Ġcoal ition +Ġspecial izes +ä¸įä»ħ æĺ¯ +Ġhistor ically +æ³ķ åºŃ +Ġd are +uss ia +åĻ Ĺ +ï¼Į åģļ好 +iv ation +! . +çĿĢ ä½ł +ed i +çļĦ é¢ľèī² +æ¸ ² +Ġmanif old +. Empty +ĠK az +Ġrecogn izes +æĪ· ç±į +ĠN FT +_g rad +om ics +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠ +Ġpor ch +Ġsp o +Ġan ime +Ġm ism +Ġesc aped +Ġevolution ary +key word +Ġdep icted +_ items +èĬĿ 麻 +Ġt t +Ġvisual ization +ĠT ot +饱 满 +ud ed +о Ñģ +强 è¿« +ograph ics +ĠSERV ICES +Ġthy roid +osp ace +Ġun cle +P ast +ç§ĭ åŃ£ +Ġf ade +ï¼Į éĩįæĸ° +åĩºçĶŁ äºİ +ãĢĤ è¿Ļæł·çļĦ +ĠAm sterdam +Ġexp ired +ĠHar bor +为主 é¢ĺ +éŁ ¶ +se ys +ãĢģ æĻºèĥ½ +.object s +br as +ĠProgram ming +_ emb +_t imer +ĠRes olution +ï¼ ķ +ä¹ĭ æ°Ķ +Further more +åľ¨ åĽ½åĨħ +Ġcher ry +Ġspect ro +Ġsand wich +-m e +_ weight +Ġ åĽłæŃ¤ +æĪIJ éķ¿çļĦ +ĠWhat sApp +æµ´ 室 +m ith +æĦŁ æĤŁ +éĹŃ ä¸Ĭ +å¼¥ 漫 +Ġup ward +S ys +ĠS id +ĠW IN +å¿ĥ åĬ¨ +, ç¾İåĽ½ +Ġa ids +åħ° å·ŀ +ï¼Į åħ« +Ġc i +Ġnot ices +æķ´ æķ´ +ĠWild life +Ġsc aled +çĨ Ħ +ä¹Ł éľĢè¦ģ +L AY +Ġwith d +åĸľ åī§ +Ġeven ly +主è¦ģ æľī +Ġright eous +_d escription +gom ery +æĹ¥å¸¸ çĶŁæ´» +ĠP ORT +(" - +Ut ility +以ä¸ĭ çļĦ +, ä»ĸçļĦ +MS G +Ġw iring +ĠAd visor +Ġrespond ent +[... ] +æī§ ä¸ļ +_ only +Ġg riev +` : +_ o +Ġw ip +arg v +lo id +å°ij éĩı +(p age +Any way +å© ¶ +Class Name +çͳ è´Ń +ĠZ end +, èĥ½å¤Ł +åĽ¢ çļĦ +ĠExcell ence +Ġtra ces +Trans lation +ĠS erv +Ġ 主 +ä¸įä»ħä»ħ æĺ¯ +Ġprob abilities +ĠDoc uments +Ġre he +ĠSh ah +çī¹ çļĦ +空 çļĦ +éĿĻ ç͵ +说ä¸į å®ļ +ãĢĤ 第ä¸ī +åĪĨ å±Ģ +Ġd uck +am med +_S W +æĭ¿ åĩºæĿ¥ +åħĶ åŃIJ +鼶 é£Ł +éĢī æĭĶ +ĠJ ar +åİ» åIJ§ +ĠPet e +Ġrabb it +Ġcomm ence +好 åIJĥ +Ġm asters +e er +æ¦ » +ival ent +ĠPur pose +Ġbright ness +ĠLeg end +Ġt i +çıį è´µ +Ġf ost +m ia +éĿ ¡ +_ ctrl +(d ir +ĠSustain able +æĪĺæĸĹ åĬĽ +è¿Ł çĸij +lu a +ï¼Ī æĪĸ +ï¼Į æĺİ天 +票 æĪ¿ +åĽŀ åIJĪ +âĢĶâĢĶ âĢĿ +ĠM ak +ĠN umbers +bre aking +Ġextract s +绽 æĶ¾ +ç«Ļ çĤ¹ +> { +Ġwater proof +éĻ· éĺ± +is se +.L inq +. pl +.... ... +." ? +é¢Ħ åħĪ +AB OUT +表éĿ¢ ä¸Ĭ +KN OWN +æĹł ç¼Ŀ +çļĦ éĹ® +Ġpol ls +ĠDef endants +ãĢĤ 说 +employ ed +Ġ æ¥ļ +âĢľ There +åĽº çĦ¶ +ï¼ļ å°Ĩ +ur ry +Ġten ants +pos ure +.R ef +Ġcoord inator +B s +ï¼ļ âĢĺ +Ġbra ins +( app +( sp +sw ith +\ mathcal +åľ¨ å®¶éĩĮ +å½ĵ åģļ +G al +SD K +Ġign oring +Tr ade +é£İ æĥħ +)* - +æµģ 失 +Ġ ä¹Ŀ +å¤ĸ 表 +ĠPhill ips +ï¼Į 第ä¸ī +ĠK yle +æľĽ åİ» +ien ced +Ġcor rections +Ġimp aired +b uilt +_p riv +Ġer red +Ġdecor ative +å½° æĺ¾ +enez uel +ĠT ig +ĠCh ip +( min +Å « +è̽ 误 +/ issues +Ġtou g +ĠM oses +ab is +åIJĦ æĸ¹ +ĠE VER +% åĴĮ +ä»· éĴ± +Ġreimb urse +.f ield +Ġfuck ing +诡 å¼Ĥ +( reg +ij n +ĠIm agine +ĠWh ole +å¦Ī çļĦ +Ġhol istic +æĹ¶ 常 +F OR +ud s +说 çļĦè¯Ŀ +ç´¯ 积 +åĪĽä¸ļ æĿ¿ +ãĢģ æľ¬ +ĠS lo +.d o +ĠH oney +Ġfu els +ï¼ĮåıĪ æĺ¯ +帮 æī¶ +ä¸Ģ å¤ľ +G s +Ġcorrel ations +ĠF P +l int +éĽĨä¸Ń åľ¨ +Com parison +ä¸į å¿ĺ +çļĦ æĥħå½¢ +_ pr +é«ĺè´¨éĩı åıijå±ķ +ve h +ç¬ijçĿĢ è¯´éģĵ +é£İ åı£ +åij¨ äºĶ +Ġpron ounced +éĢį éģ¥ +ï¼Į 约 +ĠH ook +æ´¾ çļĦ +åı¯ è¡Į +Ex cellent +Jo ined +Ġmer its +Ġcom ics +人æ°ij åĮ»éĻ¢ +éĿ ¶ +ĠHe y +ï¼Į å·¦ +ĠEx cellent +Ġph y +Ġequ ip +ĠInj ury +Ġhyg iene +E VER +å®ŀåľ¨æĺ¯ 太 +( View +ï¼Į ä¸ĥ +Int o +ĠNC AA +Ġ ä½ķ +Un iform +ĠReg ardless +çĶŁ èĤĸ +.pro cess +ç į +ï¼Į è¿ľ +Ġse lections +ç¼ Ķ +Ġcompet itions +ĠD H +gu ard +ĠBal ance +æľº ä½ĵ +è¯Ŀ è¯Ń +Ġm t +@ Test +çļĦ ç½ij绾 +æ¯Ķ éĩį +Ġassoci ates +éĢŁ çİĩ +Ġper me +Ġpse ud +se ctions +m r +D H +; // +ew idth +Ġw ag +å¤ĸ æ±ĩ +idel ity +èĭ± è¶ħ +ĠM ol +Ġu pl +åľ¨ æ°´ +æĬĵ 好 +Ġharass ment +k ov +åºŁ å¼ĥ +Ġuns ure +ĠBang ladesh +女 åıĭ +åłª ç§° +Ġlast ed +ç¼ĸ åī§ +ĠR ender +H ide +é£Łåĵģ å®īåħ¨ +Ġsupp ression +Ġ 两人 +rist ol +ĠM AN +æĸ¹ å½¢ +[ r +ph alt +å¹² é¢Ħ +åĥµ å°¸ +åĹ ħ +text tt +( it +设置 为 +éĺµ éĺµ +åıijå¸ĥ ä¼ļ +æ¦Ĥ æĭ¬ +f rames +æľį ä»İ +ATE G +- container +Ġm aternal +带 ç»Ļ +触 æİ§ +èĬ Ń +S pecific +Ġout reach +Ġclin ics +èķ Ĭ +\ hline +åıĪ ä¸įæĺ¯ +æĬ¥ éĶĻ +çºł ç¼ł +Ġoptim istic +ĠL anka +Ġsens ation +ĠAppend ix +_s l +ss h +Process ing +Ġsub group +ĠR ug +Ġthere after +å´ĩ æĭľ +åıĬ 以ä¸Ĭ +ï¼Į æĢ¥ +ĠUn ique +äºĶ è¡Į +Ġcolon ial +以 åħ¶ +w ave +ãĢģ ä¸ĵä¸ļ +Ġ( < +Ġimp ress +Ġoff shore +çļĦ å®¶ +E ar +ĠFl ore +åIJIJ æ§½ +æľĪ ä¸Ń +ĠPl ugin +èĥ¡ åŃIJ +è¶ħè¿ĩ äºĨ +Vert ical +çļĦä¸Ģ 天 +sh op +åIJ¸å¼ķ äºĨ +Ġto e +t re +im i +Ġb acon +åľ¨ æĪijçļĦ +, å°±ä¼ļ +åĻ © +æĸ½ åĬł +ĠP OS +og ens +åĮħ 容 +T Y +ï¼ļ å¦Ĥæŀľ +Ġ ä¸ĭ +Ġde position +Ġex ert +Ġspec imens +Sl ice +ĠRed dit +el ist +æľī ä½ķ +æİ© 饰 +Ġc nt +Ġwa iver +Ġup side +оРº +Ġmerch ant +åıĺ å¼Ĥ +v ity +å°± æŃ¤ +s z +çĿĢ å°ı +c ounter +ä¸į åģļ +ÏĦ η +èµ· è¯ī +/ upload +ä¸į 论 +Ġ åĽ½ +.b utton +çļĦ è·¯ +Ġob ey +Ġd ash +æľŁæľ« ä½Ļé¢Ŀ +ç´ł æĿIJ +å®īå¾½ çľģ +_M AP +Ġch ina +ament e +åı¯éĿł æĢ§ +ï¼Įè¿Ļ ä¹Ł +ï¼Į åħ³ +åį« è§Ĩ +- click +_st at ++ y +å£ ¹ +(" < +.n o +u ably +åıĺå¾Ĺ æĽ´åĬł +ĠLe ather +åı· çļĦ +let al +ãĢĤ äºĭå®ŀä¸Ĭ +X L +åįĬ å¤ľ +x FFFFFFFF +ä¸ĸ å®¶ +.sh ould +Mill is +W riting +$ lang +Ġhonest y +çīµ å¼ķ +ĠAssoci ated +ĠAdv oc +ogram s +b u +Ġint ric +ĠG raphics +ĠN g +çļĦ çĶŁåij½ +ĠMc Donald +Ge orge +éĩĮ ç¨ĭ +ä»ĵ åĤ¨ +-pro cess +使 人 +ãĢĤ åIJĮ +ĠM ist +Ġnation ally +synt hesize +ç¬Ķ è¯ķ +ï¼ĮæľĢ è¿ij +Ġdoc s +ass ium +Ġmar ble +çIJĥ çļĦ +\ . +Ġph p +Ġ 页 +çĴ IJ +Iss ue +Ġ} ); +é»ij è¡£ +< typename +< uint +Sen ior +ç§ ĥ +éĴ Ľ +annot ations +åī¯ ä½ľç͍ +太 åİŁ +Ġk ills +flow er +ex us +_C OM +ãģ Ī +ï¼Į æİ¥ä¸ĭæĿ¥ +è¿· èĮ« +ï¼Į ç«Ļåľ¨ +æİĴ æ°Ķ +Ġstart ups +urre ction +ĠEx port +ruit ment +Ú © +Ġs ie +å¥Ķ è·ij +éĤ£ å°± +_P ACK +\< ^ +, q +Ġpo inters +ip ation +Ġover ly +åIJij éĩı +ru ck +Ġdirect ories +ĠT race +Com mercial +Ġpresent ly +Ġ æĮĩ +ĠL V +, L +A ctor +Check ed +m f +Ġn odded +亲 è¿ij +Ġinvestig ators +w ire +AD C +ãĢģ å¸Ĥåľº +ĠN W +Ġtight ly +åΰ ä»ĸ +è¿ŀæİ¥ çļĦ +um ption +ãĢĤ æĹłè®º +楼 çļĦ +Ġsun set +å±ħ å®¶ +ĠF X +èĮ Ĺ +C annot +=" ${ +ãĤ · +èĤ ĩ +Ġtransform ing +Cal ifornia +Ġrepro duction +ĠW es +åĩº å¤Ħ +åľ¨ å¿ĥéĩĮ +ĠGar age +SE S +Ġcom o +Âł 她 +çĸ ļ +Ġh ilar +-w ith +Ġf ict +Ġtransform ations +Ġmal icious +Ġh ay +Ġan kle +Ġval uation +âĢ Ĥ +S HA +.S upp +Ġhe ights +Rel ations +ï¼Ľ å¦Ĥæŀľ +_b uild +ä¿Ŀè¯ģ éĩij +Ġenthusi asts +p it +Ġtr illion +ĠT ik +ä»į æĺ¯ +举 èµ· += x +ĠB ir +Ġre novation +Ġr ubb +Ġb end +Ġarg c +ĠH ood +_s ys +iss ing +Ġinitial ization +好 åIJĹ +纵 åIJij +Ġworry ing +Ġ erg +èį « +è§ ħ +åĸĥ åĸĥ +Ġenc ounters +ï¼Į使 åħ¶ +å°Ĩ 她 +W ashington +åĨĻ åŃĹ +(' -- +们 åľ¨ +Track er +æľº ç͵ +Ġin accur +Ġv ivid +ĠW ag +Tra ining +ï¼Į åħį +åİŁæĸĩ åľ°åĿĢ +Ġsec uring +æĪIJ 人 +端 éĥ¨ +æ·· æ²Į +Ġe ighth +.j ackson +åľ¨ ä¸ĢäºĽ +硬 åĮĸ +E IN +"> & +åľŁ è̳ +Ġalgebra ic +æıIJ åıĬ +V ERT +UE ST +Ġcarb ohyd +ãĢģ ç¾İ +ĠNeed s +æķ° æİ§ +box es +æ²ī 浸 +ĠImport ant +ĠEgypt ian +ĠTrad itional +Ġr ushed +Ġst a +.p age +èĢĥ çĤ¹ +h or +(e lement +Ġapopt osis +Ġconsult ants +P an +ĠTyp ically +æĶ¶ 纳 +ĠD L +ĠE thereum +ï¼Į éĥ¨åĪĨ +æŃ¤ å¤Ħ +_T ABLE +Ġdeput y +Ġdr illing +Ġc ss +ä¸ŃåĽ½ 人æ°ij +ĠF uel +Ġv est +ath s +èĤł éģĵ +T rend +Ġsp acing +B in +幸 好 +Ġinc urred +çĹħ åĽł +Sp ell +head s +ä¿Ŀ ç½Ĺ +ä¸įåIJĮ äºİ +âĢľ A +åĹ ¦ +N d +Ġqu asi +Ġpl ag +缸 ç»§ +udd y +ĠL ayer +Ġfl oral +ä¸Ģ æľŁ +ãģ£ ãģŁ +ĠTes la +ter ms +News letter +çīĽ ä»Ķ +Ġreform s +Ġst ance +ĠLead ers +CE O +ĠCon n +çļĩ 马 +UT TON +åĪĨ å·¥ +Ġdec oder +åĿ ¯ +æĻ Į +Ġb ins +Ġunder going +纵 横 +æľī人 说 +iling ual +ĠTour ism +ï¼Į åĸĿ +åľ¨ èĩªå·±çļĦ +使 åħ¶ +Ġest e +< float +Ġad missions +Hot el +Ġtra ff +ĠFin land +Ġge ographic +Ġs f +ĠG onz +沿 æµ· +ĠT A +Ġwe ed +imp lementation +Ġbr ass +çļĦ ç»ıæµİ +å¼Ģ èĬ± +Ġinit iate +yl um +- em +Ġmet res +Ġrese ar +Ġlegisl ature +ĠD aw +æĪ ® +èĬ ľ +å¦ ŀ +ä¸Ģ åĪĢ +, å·²ç»ı +cent ering +主èIJ¥ ä¸ļåĬ¡ +ï¼ĮæŃ£ 好 +ASS WORD +Ġ åIJ¦ +! ). +################################ ################################ +Ġsubst itution +æĶ¹éĿ© å¼ĢæĶ¾ +Ġtast ing +, èĭ¥ +_d at +à¸ Ń +Ġsh adows +ï¼Įæľī çĿĢ +ĠSk ip +ant ics +_F E +è¿ĺæľī ä»Ģä¹Ī +Ġlocal ization +æĢ ł +Ġdecor ations +ĠL an +c ott +æµ· åħ³ +Ġmob il +çļĦ åİĭåĬĽ +" What +ĠOcc up +人 ä¸İ +r oute +çŃī 缸åħ³ +Ġmir rors +åıĮ åIJij +æī Ĵ +Ġworks pace +ĠElect rical +èģ Ĩ +è¾ŀ èģĮ +Ġb iod +èijĹ ä½ľ +诱 æĥij +Ġclass Name +Ġsens ing +ĉĉĉĉ ĉĉĉĉĉĉ +èĮĥ çķ´ +F re +Ġcollect or +_res ource +Ġn ort +ĠL odge +ä½İ è°ĥ +Ġinadequ ate +ĠV a +åı¯ä»¥ çľĭåĩº +ĠT itan +çļĦ ç͍ +ĠIran ian +{item ize +Ġmist aken +ĠSh a +ĠJul ia +åIJĥ è¿ĩ +-se ason +. ad +ĠK on +_c v +Ġaccident ally +éķ¿ è¾¾ +æĻļ äºĨ +Ġgive away +Ġweakness es +æ¼Ķ ç»ĥ +You ng +Ġ è°ģ +å¯ ¥ +.R un +æī¬ å·ŀ +Ġfree zing +Ġrel ieve +Ph ys +Ġaver aged +J oe +get Name +Ġcopy ing +Ġcommit ments +Oper ations +æĥ³ åĬŀæ³ķ +çζ åŃIJ +m ons +ä¸ĥ å¹´ +Cl aim +\ le +n as +ĠK l +æĺ¥ é£İ +åľŁè̳ åħ¶ +Ġnut rient +Ġt c +æłı 缮 +Ġcitizens hip +ä»ĭç»į ä¸Ģä¸ĭ +Ġcapt ures +ãĢĤ 马 +ä¸Ģ缴 æĺ¯ +åħĭ çļĦ +N H +Ġt ier +çīĪ çļĦ +com ments +åĬ³åĬ¨ èĢħ +ĠR X +ãĥ³ ãĥ +. Config +ORM AL +Ġreput able +ä¸į èĪĴæľį +& P +ï¼Įä¹Ł è¦ģ +ï¼Į åĵªéĩĮ +ĠNot ification +_s ample +ĠY outube +åIJĦ çķĮ +ere k +cre ens +æ²Ļåıij ä¸Ĭ +MB OL +.st op +èĭ Ľ +æĥħ æĦ¿ +两 è¾¹ +å¸Ĥ æĶ¿ +% å·¦åı³ +åıijå±ķ åĴĮ +Ġresid ue +-b ar +è¯ķ çĿĢ +Ġ çľĭ +est ock +log s +aterial s +ĠMont e +è¯ķ æİ¢ +åıĺåİĭ åύ +è¿ĺ 款 +è¶Ĭ æĺ¯ +ĠDec ision +éĿŀ åĩ¡ +ung en +, åħĪ +Ġinv ented +Ġstick ing +Ġenjoy ment +ĠEd inburgh +ar us +以åīį çļĦ +ĠR uth +Ġdoub ts +ĠP ointer +Ġaff idav +åIJĪæ³ķ æĿĥçĽĬ +c ost +Ġinterf ere +.d ll +ĠPark ing +s ch +ver ages +ĠF ourier +çļĩ 宫 +éĵ ® +udd en +æĪij å¾Ī +ĠSPE CIAL +éĺ´ è°ĭ +t ube +Ġelim ination +é» ¯ +å¤į æ´» +Ġtutorial s +Ġsl a +åħ³æ³¨ çļĦ +çĶŁ äºİ +Ġsoc ially +] " +ĠM ine +.f ramework +å¥ĸ 项 +Rec ogn +Ġagg rav +çϾåĪĨ çĤ¹ +ä¸İ ä½ł +IT LE +ĠLi u +ĠTe levision +ĠF F +B ag +, ä»Ĭå¹´ +ãĢģ åĮ»çĸĹ +åIJij æĪij +Ġpe ek +ribut or +çĻ» ä¸Ĭ +ĠP RE +ĠF oster +ros ion +, åĥı +Ġexp ans +ĠSu z +åħĭ æĭī +å¾· çļĦ +Ġbath s +åĺ Ģ +å¾Ĺ æĽ´ +Ġres ide +å¾Ī éķ¿ +( query +Can ada +und ers +'] [$ +å«ī å¦Ĵ +ĠAd apt +ĠN umer +z t +Ġp ent +衬 è¡« +鼷 éľĨ +Ġtestim on +Ġfram eworks +Americ a +P B +ĠM EM +Ġcontact ing +STR ING +. args +ãĢ Ī +åĥ ļ +ä¼ļ å½±åĵį +ĠP V +ï¼Į以 åīį +IV ER +Ġst ove +$ / +ä¹Ł åıªæĺ¯ +æľĢåIJİ ä¸Ģ个 +Ġspin ning +èĥĮæĻ¯ ä¸ĭ +Effect s +g p +楼 çĽĺ +åĨľ åľº +Ġfix tures +第 åįģ +ï¼Į æµģ +æ®ĭ çķĻ +_ record +ĠT OP +ĠOpport unities +ï¼Į åĢĴæĺ¯ +Advert ise +h all +èϽ 说 +èĻ ı +æľĢ åħ· +è¢ ľ +åºŁ çī© +类似 äºİ +process or +åĪ« 说 +Ġnan op +/ images +M IC +Ġil leg +ãĢĤ ç»ĵæŀľ +. Location +/m ain +More over +å® ¸ +ant om +没æľī åĬŀæ³ķ +ä¸Ģ æĺ¯ +Ġpay roll +Ġdu o +Ġreal ised +åºķ å±Ĥ +. Response +R B +ä¹± çļĦ +ä¼ģä¸ļ å®¶ +ĠIn cludes +çłĶç©¶ åijĺ +åºĶ åĬĽ +ç«ŀäºī 对æīĭ +ĠRe ed +ĠCor ner +å®ī å¨ľ +ank ing +Ġcont amination +æľ¬ èµĽåŃ£ +(: , +âĢ » +Ġcompr ise +ĠTH C +Ġ åŃĻ +Ġafore mentioned +ĠArab ic +Ġclust ering +ram id +ĠP IN +( Context +åľ¨ åħ¨åĽ½ +() ` +Ġb c +宽 æĿ¾ +ĠPos itive +ĠR GB +çα ä¸Ĭ +Ġelectro de +ĠSc an +Conf irm +æĺł å°Ħ +çĿĢ çľ¼ +è¦ģ ç͍ +Ġc akes +ĠSaf ari +éĶ ļ +Ġv ide +çļĦ éĢļçŁ¥ +Ġ 游æĪı +Ġintrig uing +ĠSc anner +Ġemploy ing +æĦī æĤ¦ +Ġamb ient +po ons +çĸĹ æķĪ +æ¯ķä¸ļ åIJİ +æİ · +ĠRe leases +æĮī éĶ® +ul ously +un ny +_b ar +éľ² åĩºä¸Ģ +/b lob +N ick +) & +f w +Ġfest ivals +i om +Cal cul +éĹ®é¢ĺ æĺ¯ +åŃĹ ä½ĵ +ï¼Į åħ¬ +Ġun stable +ĠB ool +Ñ Ħ +Rel ative +ack et +ret ch +ć ą +S olution +Ġpaper work +åħļ ç»Ħ +æĻļ é¥Ń +æĸ° åŁİ +å¼§ å½¢ +C apture +夹 æĮģ +Ġe urope +ĠL ed +need ed +ï¼Į ä¼¼ +ĠAl bum +ï¼Į åħ³äºİ +ĠMy SQL +ĠW ide +.C olor +严 å³» +å¹´ 以æĿ¥ +ĠDes k +ampl er +ä¹ĭ ä½Ļ +çķ ¸ +_param eters +ĠM ent +ĠOff set +Ġsub section +, çİĭ +ä¸į 便 +.b lock +çŀ ħ +erg arten +Ġf lick +âĢľ è¿Ļ +ob o +Ġto ggle +Ġcollect ively +ä»Ģä¹Ī åij¢ +躲 éģ¿ +ï¼ Ļ +et al +state ment +渲 æŁĵ +ï¼Įä¹Ł ä¸įæĺ¯ +ç§ijåѦ çļĦ +Ġteen agers +v v +Ġprosecut or +Ġb ru +æĥħ ä¾£ +ä»ĺ è´¹ +å¥Ķ é©° +é£ Ļ +Ġglimp se +.print StackTrace +âĤ¬ TM +Ġce ase +åIJĦ æľī +ï¼Į å¾· +ĠHyp othesis +ï¼Į çķĻ +Ġmill enn +Ġincub ated +ew s +Ġacc redited +许å¤ļ 人 +ä¸ĩ çļĦ +çŃī åĽłç´ł +': ' +{ z +Ġrent als +F ar +åΰ ä¸Ģ个 +qu ee +S prite +_s amples +åįĥ ç±³ +æľĪ åħī +è·µ è¡Į +éĥ¨åĪĨ çļĦ +è¿Ľ åıĸ +Ġrespond s +ear chers +çļĦ 身ä¸Ĭ +çļĦ大 åŀĭ +Draw able +Ġtop ological +äºĮ çϾ +ç§ĭ 天 +类似 çļĦ +ener ated +ĠMin imum +-f ounder +女 çİĭ +ä¸Ģ äºĭ +-m d +æīĢåľ¨ åľ° +åĿ Ĥ +Ġadm its +ãĢĤåħ¶ 次 +ĠSh anghai +ï¼Įä½Ĩæĺ¯ åľ¨ +ĠC rack +. row +J C +Ġen light +ä½Ĩ ä¸į +ĠD ennis +æİĪ è¯¾ +v or +å·® çļĦ +åīį éĶĭ +ĠA ST +ot ions +Ġe rect +Ġfold ing +Ġroof ing +åĶ®åIJİ æľįåĬ¡ +ĠC ord +Ġstreng thening +å½±åĵį çļĦ +Ġa ston +ĠSign al +ĠHe ights +Ġknock ed +ì § +n at +S ets +空éĹ´ çļĦ +å¾Ī 强 +Ġassist ing +ãĢģ ç½ij绾 +该 æĢİä¹Ī +ga e +pp le +fore st +ï¼Įä¹Ł èĥ½ +ĠTre k +E AR +æŁĵ èī² +ĠRod rig +ĠPut in +èĢģ åĮĸ +æ¼Ķ å¥ı +Ġsequ el +ĠBed room +Ġp umps +Ġco herent +Ġst ained +Key word +æĶ¾å¼ĥ äºĨ +otechn ology +ĠT ank +æĺ¯ä¸Ģ åľº +ä¹ĭéĹ´çļĦ åħ³ç³» +Ġnot ebook +çļĦå°ı 说 +ĠD ig +éĤ£ 个人 +硬 度 +å¿ĥ æĥ³ +ĠPrinc ipal +åĩºç§Ł 车 +Ġrou lette +æ¤ħ åŃIJ +åľ¨ 该 +åĩ ¿ +resh ape +Ġarch ae +st a +ï¼Į便 äºİ +Ġmerg er +Ġregul ator +\ ], +Ġrac ist +m ag +Ġab c +=" @ +ĠBe er +åħij æį¢ +.d ate +ĠT ap +æŀľ æĸŃ +æ²ī éĩį +art ifact +R V +ĠÐ ³ +éĤ® æĶ¿ +è¿ĺ ä¸įéĶĻ +ãĢĤ ãĢĮ +常 å§Ķä¼ļ +Ġdign ity +èī° èĭ¦ +ĠAdv ance +T LS +ä¹ĭ å®¶ +ï¼Įä¸Ģ éģĵ +Ġcounterpart s +Ġcheap est +Ġclick ed +ç¦ı å·ŀ +ĠMar io +æĻĭ åįĩ +åĴĮ ä¸Ģ个 +ĠLaw s +AR C +æĿ ŀ +ux e +Ġcos m +É Ļ +ç» ® +åħī ç͵ +Ġb apt +åįļ è§Ī +ï¼Įåħ¶ ä½Ļ +ï¼Į æĶ¹ +Ġconvinc ing +çļĦéķ¿ åº¦ ++ , +Ġev ac +, w +è§Ĥ æµĭ +k ar +Ġmit igate +-med iated +åħ± è¯Ĩ +æ¸ħ æĺİ +æľĢ 强 +Ġdes cent +è¶Ĭ åıij +Ġcont ention +èµ° ä¸Ĭ +å¸Ī çļĦ +ĠW ere +æīĢ ä½ľ +éĺŁ åĪĹ +.h ash +Ñģ Ñı +And rew +Ġw ounded +ãĢĤæĪij æĥ³ +åIJ ± +ĠL amb +ĠTe ams +æŃ£ ç»ı +æĹł æķĮ +å°ı äºĭ +èģĶ æīĭ +Ġinf er +åĨ² æ´Ĺ +Ġb ush +il o +Ġprop he +åī§ çĥĪ +å°± éľĢè¦ģ +_l ayout +\ int +ĠF o +å°ģ 建 +å¾Ĺ ä½ı +å¾Ĺ 好 +Ġbl own +èħ Į +ĠScholar ship +PL C +Ġwas ted +ï¼Į ç³»ç»Ł +èĤ ĺ +åĦ¿ 女 +et ta +ĠC odes +ĠAM D +æĪij 没 +.B uilder +乡æĿij æĮ¯åħ´ +Ġ æĪijçļĦ +æ¦ ¨ +åĵŃ äºĨ +.m y +-t itle +çģ«è½¦ ç«Ļ +åĪĨåĪ« æĺ¯ +Ġstretch ing +å¹³ åİŁ +Ġsub missions +t alk +åĩºçīĪçļĦ åĽ¾ä¹¦ +æīĭ åĨĮ +riter ion +( env +ere rs +rot ation +æ°¯ åĮĸ +amp oo +æĿ¥å¾Ĺ åıĬ +ph ot +ãĢģ å¿ĥ +Ġinn ings +æľ¬èº« çļĦ +为 æľ¬ +ĠSpe ech +, 没 +è°Ī 论 +åĽŀ èIJ½ +亮 缸 +åİĭ è¿« +ï¼Į åĽ½åĨħ +Ġintention ally +T uple +Ġdisc iples +ĠR oth +Ġfun nel +çĿĢ çľ¼çĿĽ +. plot +ä¸Ģ åĩº +Ġden oted +æŃ§ è§Ĩ +Ġmarket ers +åºķ 线 +æ´¾ éģ£ +Ġbill ions +ä¸į åIJĥ +Ġcolle ague +æĮī æĹ¶ +Ġper taining +è¿ĩ å¾Ģ +Ġon t +çļĦ æĥħ绪 +æ³Ħ éľ² +Ġgrav itational +Ġmon itors +ll vm +Ġin quiries +ĠS TE +è¿ģ ç§» +ĠGh ana +Ġey eb +çļĦ 书 +éĥ½ éĿŀ常 +èµ° 访 +ä¸įèĥ½ åĨį +Ġinhabit ants +çݯå¢ĥ ä¸ĭ +Ġb os +èijĹ åIJįçļĦ +好 人 +c uts +ĠE UR +-in put +_ remove +Ġinter cept +å¦ĩ ç§ij +ï¼Į 离 +ĠSch w +:: _ +è¡° èĢģ +åĴĮ 对 +O FF +Ġf ighter +å¹¶ æĹł +Ġs nd +Ġcompan ions +ï¼Į æīĵå¼Ģ +Ġcomp lementary +_class es +Ġfut ures +, ãĢĬ +ST ATE +Ġimm ense +ĠAP Is +ç¡® ç«ĭ +_p ages +ä¿ Ń +é¦ĸ æī¹ +å°ıå¿ĥ 翼翼 +Ġbl ues +éĻ¢ çļĦ +åºĹ éĩĮ +Ġ æľ± +ä¸į 为 +Tr ad +F unnels +Col lege += f +ĠSuper ior +ä¹ĭ ä¸ŃçļĦ +æ¶Ĥ å±Ĥ +Ġ$ ('# +å®ĮåĸĦ çļĦ +Ġamaz on +ĠBr andon +C lock +æĥĬ 人 +M F +ç¢ ¾ +W ild +ï¼Į çľ¼ç¥ŀ +æĢ» éĩı +cite p +qu is +Ġmetall ic +ÏĦ ε +_V ER +. so +ĠN ET +æİ º +pher d +ï¼Įæľī åĪ©äºİ +ĠParticip ants +æ± Ľ +ä»»ä½ķ ä¸Ģ个 +太 çĽij +Ġsh ar +åĨĻ äºĨ +Ġactiv ist +IS C +å±Ĥ å±Ĥ +Ġ ------------ +çļ® å¸¦ +Ġbrack ets +N il +ĠB ott +åľ° æĬĬ +æĸ ¼ +æĤ£ æľī +æľº çͲ +Ġrevolution ary +Ġasc ending +ĠPer form +æĴŀ åĩ» +C li +åĸľ 好 +PT Y +௠į +en vironment +å®ĺ åħµ +_C AP +åĽºå®ļ åľ¨ +/ config +The ta +Ġbe es +ĠMot ors +ä¼ĺè´¨ çļĦ +Ġmal ware +foot er +åįĹ æµ· +Ġâ ĺ +åĪĩ å°Ķ +Ġv ibration +Ġisol ate +ä¸Ń 级 +" A +μ α +Ġst urdy +è´¨ çļĦ +Ġ" ) +妹 åŃIJ +è·ij åİ» +PERT Y +ä¸ĭ 游 +ï¼Į C +礼 åĵģ +好 åĩł +å¤į èĭı +Pol ice +Ġbudget s +, æľīçļĦ +leg end +æķ¢ äºİ +Ġatmosp heric +ĠC uba +ĠUs age +bro ok +æ¯Ķ æĪij +m ysql +å·´ æİĮ +åı¦å¤ĸ ä¸Ģ个 +æ®ĸ æ°ij +Comp ile +I H +èĥ¡ èIJĿåįľ +ffect s +Ġtransport ed +ĠAR M +èĢĮ çŁ¥ +Ġb ore +åķĨ ä¼ļ +ĠO z +Ġse as +éĴĵ é±¼ +on o +Ġweb inar +èĿ İ +l abels +å¦Ĥ æĿĥåĪ©è¦ģæ±Ĥ +Ġmark ing +Sub scription +ãĢĤ åŃ¦æł¡ +ãĢģ åĨħ +Ġne on +Ġt ales +éĩij å¸ģ +åıijçĶŁ åıĺåĮĸ +B ed +ĠKe ys +Ġcomp rehend +æľī äºĭ +æµģåĬ¨ èµĦ产 +set minus +åįĬ çĤ¹ +åĽŀ è°ĥ +it ics +Ġ éϤäºĨ +Ġsp ice +èĢIJ 磨 +Qu est +Ġmed al +çΏ å¦Ī +Ġgrant ing +æĪIJéĥ½ å¸Ĥ +ãĢģ åij¨ +M argin +åºı åı· +æŀģ 管 +, Y +Ġxml ns +对象 çļĦ +ç²Ĺ ç³Ļ +Ġra pe +Ġsplit ting +Ġs d +Ġ ÙĪ +H orizontal +Ġv amp +.l ib +um at +Ġunder went +Ġabs urd +- led +_ insert +Ġdry er +EN U +æ± Ģ +F unctions +Ġproject ions +åīĤ çļĦ +Ġmuseum s +ï¼Į å¹³æĹ¶ +åŃ ½ +' " +éĤ£ä¸ª æĹ¶åĢĻ +Ġle uk +åıijå¸ĥ äºĨ +PL Y +åĬł çıŃ +port ion +)$ $ +éĶĢåĶ® é¢Ŀ +èİ«åIJį åħ¶ +ĠBank ing +S yn +åŁİ å¢Ļ +ĠHV AC +M IT +å°Ĩ é¢Ĩ +l ap +ï¼Įéļı æĹ¶ +Ġr het +Ġk ay +Ġgl ut +ĠElect ronics +ĠC afe +Ġincl ined +Ġopt imum +Ġclass ify +å°¤ 为 +Ġillust rations +Ä Ł +è¿ĺ 以为 +æĪij è¿ĺæĺ¯ +Ġtrans c +ê ° +æĹł æĥħ +éĤ£ åıª +ĠInf rastructure +çѾ åŃĹ +UD IO +_ account +ãĢģ å®ī +æģĴ 大 +an che +_ ps +äºĨä¸Ģ 份 +çļĦ å®¶ä¼Ļ +ĠON LY +ç¦ı建 çľģ +æĮĩ å®ļçļĦ +æľī ä¸Ģå®ļ +Ġstick y +æĹ© çĤ¹ +缸 å·® +ÏĦ ο +ï¼Į éĥij +ĠCh rom +éĢĥ éģ¿ +************************************************************************ ****** +.ex it +åĽ½ 人 +Ġturn over +Ġrec alled +Ġimag ery +Connect ed +Ġpresum ably +ä¸Ńå¿ĥ çļĦ +å·¥ 伤 +央 è§Ĩ +çĶŁ çĶŁ +ĠRe yn +ĠD anny +ab ind +_ location +ĠC lock +Ġtun ing +è¿Ļç§į æĥħåĨµä¸ĭ +ä¹Ł å¼Ģå§ĭ +ĠBer keley +was her +ar in +Ġwork load +ĠâĪ Ĩ +è¿Ļ æľ¬ä¹¦ +å°Ĩ æĪIJ为 +.f ill +ĠSy rian +Ġslee ve +Ġru in +Ġsc andal +Ġup stream +Ġdiagram s +çĭ ¡ +综åIJĪ æĢ§ +éĿĴ æµ· +и й +ĠVar ious +åħ« åįģ +U nd +Ġstr at +ĠAccess ories +ĠE ight +åĹ ľ +ĠK o +çľ ¶ +, åIJ¦åĪĻ +åľ¨ ä¸Ń +çŃī å¤ļ +èĭ Ķ +Ġkin ase +Ġstim ulate +ie u +ĠCan on +ĠBro oks +ĠD h +ĠH A +éĴ Ŀ +Min imum +äºĨ åķĬ +_d isplay +ç͵ è§£ +ĠF itz +Ġnew born +对 è¿Ļ个 +ighbor hood +çł´ è§£ +ymmet ry +activ ated +Ġpast or +_w ait +Ġant igen +AM L +Ġpept ide +Form er +art a +Ġdoub led +æĺİ æľĪ +æ² ¼ +f ood +H AL +- edge +. âĢľ +Ġg raft +pen cer +Ġmy sql +èĢģ人 å®¶ +Ġins isted +. im +at ype +注 éĩĬ +D ead +, èĢģ +æ¶īåıĬ åΰ +ĠO C +ĠGener ator +头 çĸ¼ +Ġd ye +åĮºåŁŁ çļĦ +ĠS ays +ĠIN S +ĠNav igation +æĿ¿ æĿIJ +pro cedure +_g rid +ί α +.L abel +Ġstandard ized +ãĢĬ åħ¬åı¸ +Ġ æĿ¥ +æľī æĿĥ +Ġ} ). +åΏ åķĨ +ĠE co +çĶŁ æľº +, åIJİæĿ¥ +c as +æĶ¶ çĽĺ +ĠForm s +Ġcoron ary +I r +åĴĮ èĩªå·± +楼 ä¸ĭ +ç½ij 红 +ç¥ŀ ä»Ļ +çijľ ä¼½ +-b order +Z ip +åŁİ éĩĮ +èݲ èĬ± +ĠE at +Ġt am +Ġw rink +ç»ıæµİ 社ä¼ļ +é¢Ħ å¤ĩ +Ġsent encing +Ġcry stals +Ġst ro +,ä¹Ł å°±æĺ¯ +ĠP BS +oot er +unct ure +ĠM ul +æĺ ķ +is b +ĠPhil osophy +s imple +ong s +_F UNC +ĠStart ed +place holder +ç͍ 车 +Ġp encil +éĢĴ å»¶ +ĠSp ons +und o +ĠMean ing +ä¹ĭ 大 +Ġstr angers +ä¿ĿéĻ© åħ¬åı¸ +N s +_b uff +ĠP air +失 çľł +Ġl ua +ĠSt ress +åİ¿ 级 +ãĢĤèĢĮ åľ¨ +top ic +ï¼Į ç©¿ +Ġhyp ot +ĠAut omatic +碳 éħ¸ +D ays +ĠA u +Ġadvance ment +Ġdark er +ä¸Ģ ç»Ħ +æ¯į åħ¬åı¸ +Ġ' ../../ +çıł æµ· +) ä¸Ĭ +Ġdis posed +Ġc ared +int s +_ acc +he astern +ĠI gn +Ġal mond +Ġd yn +ob a +Ġrepro ductive +ĠC atalog +Ġn b +ï¼Įæľī æĹ¶åĢĻ +ĠPlaintiff s +ãĢĤè¿Ļ 次 +r pc +ĠCap itol +éĩij èī² +ĠS low +Top ics +_AR G +ç»´ å¥ĩ +åı Ń +ĠPharm aceutical +_ utils +ä¸ŃåĮ» èᝠ+B ucket +ä¸¥æł¼ çļĦ +æī§ çĿĢ +Ġ' -- +åºŁ è¯Ŀ +å¨ ¥ +Ġtox icity +rot ate +ĠA rena +ãĢĤ éĺ¿ +æĭ ĩ +ç¥ŀ åľ£ +é£ŀ æī¬ +ĠC t +Ind icator +ä t +CRIP T +Fl ash +Ġrib bon +èĩª æĦ¿ +{b matrix +èĥ ° +çı Ģ +çķª èĮĦ +ä¿ĿæĮģ çĿĢ +Ġregul ators +Ar m +å¦Ĥ æĦı +Ġthere in +ĠBuy ing +çŁ¥è¯Ĩ çļĦ +ï¼Įä½ł 说 +.g l +ä¸Ģ çŃīå¥ĸ +Ġdis semin +çĮ´ åŃIJ +_ind ices +ar as +Ġst ub +年度 æĬ¥åijĬ +Ġi k +ä¹Łæĺ¯ ä¸Ģ个 +æĬĬ è¿Ļ个 +ĠF ailure +Ph ysical +Ġj umps +è¡£ çī© +in el +Ġd an +Ġtransform s +Ġtr agic +ठ¿ +çļĦ女 æĢ§ +> P +ĠOptim ization +=" ( +s ig +pub lished +ĠA pi +, åIJİ +Ġsw elling +Ġl aughter +UB LE +æĥħ æĢĢ +æīį åı¯ä»¥ +f uture +Ġper ceive +çĿ£ 导 +ä¸į ä¸Ģå®ļ +as gow +ĠLu cy +E U +Ġf reak +ĠN AME +, éļıçĿĢ +ç¼Ŀ éļĻ +_ IC +ric hed +çľĭçĿĢ ä»ĸ +ĠV ir +ĠP rest +æľī ä»»ä½ķ +F inding +on er +Ġall iance +社交 åªĴä½ĵ +}} ^ +ĠPl aces +Ġbe ast +ĠProt ect +Ġteen ager +çģµ æĦŁ +ul ence +_ OR +Ġmix er +Ġcurv ature +ĠB USINESS +GR AM +ĠExper ts +Ġc innamon +Ġb s +P atch +al am +èĥİ åĦ¿ +d atabase +åĴĮ æĿİ +ĠJ ama +ON S +Ġc urs +, ä¸įæĸŃ +ĠC AD +æł¸ å®ŀ +åħħåĪĨ çļĦ +Ġ èĬ± +Ġphot on +çļĦ çľ¼ +et own +Over lay +ä¼Ĺ æīĢ +Ġcart oon +æ³ķå¾ĭ 责任 +éĩįåºĨ å¸Ĥ +ĠProb ably +â Ŀ +éļIJ çŀĴ +ĠImprove ment +.m ethod +. us +Ġd jango +æ°§ æ°Ķ +ĠCon duct +Ġmar vel +ĠR oche +车 éģĵ +Ġadmin ister +v ars +St udio +å¤į å·¥ +\ caption +ç¾İ æ´² +ä¾Ľ æ°´ +Ġneighbour hood +ne apolis +ĠK om +èĤ¥ èĥĸ +Ġint r +æIJ¬ è¿IJ +] ); +Ġspring s +Ġprocess ors +ĠO dd +Ġmetaph or +.T ab +Ġes p +å®ĮæĪIJ çļĦ +B io +ç¾Ĭ èĤī +åıĪ èĥ½ +Ġsem antic +ĠD ining +Qu estions +å°Ĩ èĩªå·± +Ġkind ly +c ards +ĠH aven +èµĦ æ·± +B and +Phot os +_ Type +T er +ut er +Ġ 让 +åıij åĩºçļĦ +è¾ĥ å°ij +ĠWar ner +ent i +Ġpreval ent +æľī åĬĽçļĦ +Ġflav our +P ending +T aking +Ġ' __ +ul ators +çļĦ çģ« +äºĶ åįĥ +Ġpromot er +Ġemp ire +ĠW S +/ ex +(f unc +èİ· æĤī +ro v +ç« ¿ +ĠT emp +éĹ´ è·Ŀ +ĠVerm ont +- imp +âĢĿ ), +rep ared +è¿Ļ åĿĹ +t witter +-in flammatory +Ġgest ure +å·¥ åľ° +Ġc iting +am iliar +Ġo lig +åıij æĢ§ +_p assword +èĢģ èĢħ +å¹´ èĩ³ +åįķ 身 +, å½ĵæĹ¶ +.m ove +, 积æŀģ +Ġacceler ated +Ġs igma +ĠEqu ation +Ġpos ed +L ou +è¿ĩ ç¥ŀ +Ġundert ake +Ġ æĸĩ +Ġhead line +ĠPear l +æ¯ı ä¸Ģ次 +^ i +å¤ĩ èĢĥ +s omething +Ġclos es +æıIJ åIJį +ï¼Į ä¹° +âĢľ If +èĦĨ å¼± +Ġ< > +Ġg um +éĢłæĪIJ äºĨ +r one +rec ip +ĠP izza +t ic +âĸ ² +enc ia +Ġh over +Ġhel met +å·¥ ä»¶ +ett i +ĠCompl iance +ĠSh ows +ĠR anch +( -- +æĻļ é¤IJ +ĠEn um +est ly +æķ´ æķ° +ĠWalk ing +èħIJ è´¥ +æĮ¡ æĿ¿ +è¿Ļ 人 +Ġrepe ating +å°± åĥıæĺ¯ +æ»ij æ§½ +Ġw p +t ol +ï¼Įä¸į 论 +ĠEss ential +èĮ ī +Ġsn ake +ĠT ables +ĠB elt +Ġ 两 +模 èĮĥ +éĿł åľ¨ +åĬĽ åѦ +uff s +A ggreg +åζéĢł åķĨ +(t oken +amp ing +æııè¿° çļĦ +f lex +Ġbegin ner +Ġhed ge +.t ag +ID EO +æĺİç¡® çļĦ +Ġthe e +ĠPro tein +æĺŁ çļĦ +ism iss +he el +æģ° 好 +ĠS equ +æį¢ äºĨ +ĠC raw +ED IA +f ail +çĴ ĭ +æ¯ı个 人çļĦ +_by te +f air +Ad just +Ġart ifacts +Gu ard +CL US +ĠVer ify +ĠK os +Ġpec uli +ourn aments +éĿŀ常 éĩįè¦ģ +_RO OT +æĻĭ 级 +Ġenh ances +}^{ - +Ġass ass +ï¼Į åIJį +Ġp ir +.f asterxml +- pr +ĠLeg acy +Ġrail road +Ġindirect ly +ĠBen ch +å¤ĸ 人 +åĪĩ çļĦ +ĠT ile +å·¨ 人 +ä¹Łä¸į æĥ³ +Ġn asty +i Phone +at to +ï¼Į 严 +all enge +A èĤ¡ +Ġ æĬĬ +Ġ -------------------------------- +_f ull +Bal ance +ï¼Į èĩ´ +/ # +ĠD istance +Ġst ochastic +. result +çļĦ æĹ¶ä»£ +ĠB orn +Ġwh olly +ï¼Į ä»ĬæĹ¥ +may be +Ġcompar ative +Ġn our +ĠHamilton ian +æł¹æľ¬ 没æľī +æĺ¯ä¸Ģ éĥ¨ +Un its +Ġinv oked +od i +人 æł¼ +ear th +q r +ĠRen ew +为 æĪij们 +é¢Ħ æ¡Ī +ic one +ow ing +æ¦ Ĩ +åĪĽéĢł äºĨ +Ġsla very +ĠPol ic +åıij è§ī +æİ¨ åĩºçļĦ +Ġsp elling +ï¼Įä¹Ł ä¸įä¼ļ +- at +. ar +_M OD +ï¼ĮæīĢ以 åľ¨ +éķ ij +Ġinf inity +å¼Ģ æ°´ +Ġcoll ateral +å¾Ĺ çļĦ +Ġf ör +( | +es cope +Ġoverlook ed +, åIJĦ +æ· Į +ä¸ī ç»´ +æµģ 浪 +ĠCH AR +ĠD P +åĽ½å®¶ éĺŁ +åĨ° éĽª +Ġoxid ation +Other s +D W +ĠRe commend +æ¹ĸ 人 +R x +ĠBern ard +ĠPl ate +ĠThought s +ĠM ale +sh ots +In ner +unt il +_W IDTH +Ġmis leading +ä¹Ł æĹłæ³ķ +view ed +ãĢģ åľ° +Ġupt ake +éĤª æģ¶ +ï¼Į å®¶ +ãĢģ åħ¶ä»ĸ +Ġpost ers +Ġn y +Ġe go +ĠM aur +c ro +å·ŀ çļĦ +ï¼ĮæĪĸ æĺ¯ +ee per +éĥ¨éŨ çļĦ +ĠPub lisher +ort ium +è¿ĩ é«ĺ +åĥ » +Ġpriorit ize +ï¼ļ ä¸ŃåĽ½ +æīĵ å¾Ĺ +çݯ ç»ķ +Ġanth rop +æĮ« æĬĺ +ad ic +ï¼Ł 她 +G ot +å°ı é¾Ļ +åıĪ åľ¨ +Ġà ® +åĬ³åĬ¨ åIJĪåIJĮ +o ors +_c ss +ï¼Į å¼ķ +è¿Ļ åıª +转 åħ¥ +ĠB ak +诧 å¼Ĥ +_b e +åĿ ŀ +Sh ipping +.Rem ove +æĪij èĥ½ +( Get +Ġteen age +Ġ åĪĨ +å¾Ģ åIJİ +ç¡®å®ļ çļĦ +Ġjuris dict +L iving +Ġt ribe +b ach +tes y +å¾Ī æ¸ħæ¥ļ +ĠU g +ĠJ ur +Ġfore most +aaaa aaaa +ĠHind u +com pute +Ġthr ust +æĺ¯ éĿŀ +举 æµ· +Ġdrain age +ĠM ead +Ġdelight ful +.M odels +èĥĮæĻ¯ æĬĢæľ¯ +SD L +对 éĺµ +çĶŁäº§ ç»ıèIJ¥ +èĢģ å®¶ +Ġj okes +ĠD inner +c ert +Ġpers ist +ãĢĤ âĢĶâĢĶ +çŃī åĢĻ +_ attribute +éĿ¢ èĨľ +à¹ Ī +åıij è´§ +ĠSE LECT +ëĬ Ķ +æĻ Ł +-g rad +pe ated +çĿĢ å®ŀ +ĠC riteria +us k +_st ore +Ġexc er +Ġb reeze +g irl +Call ed +ĠNo vel +ĠS ql +ĠJ ump +æĹł æīĢè°ĵ +ĠAltern ative +ph ase +ph al +ï¼Į ** +Ġm x +太平 æ´ĭ +ä¸Ń çļĦä¸Ģ +Cap acity +ĠL av +æ¾³ æ´² +ĠOff ers +èĪ Ķ +çĭłçĭł çļĦ +å°ģ ä¿¡ +Ġaut ism +æĶ Ĵ +_L INE +. Update +ĠLe o +微信 åħ¬ä¼Ĺåı· +ĠP ere +å¤ĩ 注 +ĠSupp lement +Ġprob ation +_CH ANNEL +ol lo +ä¾Ľ åıĤèĢĥ +åħµ åĬĽ +Ġtwe ets +Ġth rom +ĠDi abetes +Ġst ain +d epth +imp ly +ĠE ther +ĠF IN +rop ract +L inux +Ġele ven +Comp leted +ne e +ï¼ģ ä»ĸ +ãĢģ æ¸ħ +éŀ į +et ails +æĬ¥åijĬ æľŁ +Ġfluores cence +æĹ¶ 段 +ah an +综åIJĪ æĶ¶çĽĬ +t ails +Ġneighb oring +Ġsympt om +ĠCitiz ens +ĠN D +Ġt ilt +IS ION +åı· åı¬ +C OD +身 ç©¿ +åĮº åĨħ +æĹł åıĮ +ä¼ļ 使 +Ġa i +åīį 端 +çļĦä¸Ģ å¹´ +Ex change +æĪ İ +ÂĤ ÃIJ +ĠP rel +D emo +trans action +çľĭ æ¸ħ +åĪĨ辨 çİĩ +è´¨ æĬ¼ +马 å°Ķ +ĠB IT +Ġcomb ust +ĠPRO F +ĠB undle +opl asm +ĠHost ing +åı¤ 人 +, ç»ı +Ġind ict +çļĦç¥ŀ èī² +C AR +à ¯ +Ġslic ed +Ġcomp artment +å±Ģ éĻIJ +Ġcas c +室 çļĦ +sh ake +åºĶæĶ¶ 款 +ä¸įçͱ å¾Ĺ +ï¼Įå¹¶ 对 +æ°´ åĩĨ +Ġconstruct ing +Help ers +Ġre load +ĠB our +ok ia +-w ise +< img +Ġext r +Ġcor rid +缺 åı£ +ĠDIS CLAIM +Ġfold ers +åŁ Ķ +ç»Ī çĤ¹ +(" _ +am o +.P ower +Ġ æĪªèĩ³ +çī¹ æķĪ +Un able +çĹħ åıĺ +详 è§ģ +rib ly +Ġ 缮åīį +ãĢĤ æľīäºĽ +Ġarm or +åijĬè¯ī è®°èĢħ +æīĵ 磨 +Met ric +om ial +åĨħ å£ģ +ĠEmploy ees +èĥĮ åıĽ +èģĮ åijĺ +ĠB ert +_ ARRAY +ĠP OL +_mem ory +Ġw iki +Ġspecific ity +UST OM +ï¼Į ä¿ĿæĬ¤ +Ġant ique +Access ibility +S uggest +æ· ¤ +** ) +主ä¹ī çļĦ +Q t +Ġsit u +èĮħ åı° +ï¼ģ ãĢį +_un it +ï¼ Ķ +commun ications +ç´ Ĭ +Ġl act +Ġqu iz +èĪĮ 头 +ĠF est +Ġunder way +ãĢĤä»ĸ 说 +F rames +ĠK ick +( ret +ï¼Į éĢĤåIJĪ +ï¼ ĭ +éĹ® ä½ł +IM P +M ount +Ġdetect ing +æĺ¾ç¤º åύ +æĺı è¿· +oc cup +ĠSt re +ces ter +ord inate +ä»ħ æľī +Ġmoist ur +çŃī æĪij +weg ian +Ġc ass +aj a +åĩº æ¼Ķ +Ch oice +åħĪ æĺ¯ +P ot +OT H +se p +Ġb achelor +å¤ļ å¹´æĿ¥ +Ġsoc ietal +L F +ĠReg istered +.set tings +L IST +Ġcompos er +ãĤ ģ +å̼ çıŃ +ï¼Į ä¼Ĺ人 +ä»İ 容 +[ v +ï¼Į 纷纷 +_ helper +骨 éª +éϤ å°ĺ +Ġworth while +å±ı èͽ +éĤ£ æĹ¶åĢĻ +è´§ 车 +çĿ « +å¿ĹæĦ¿ æľįåĬ¡ +ĠS ew +Ġst aring +Ġsun shine +_ loop +æīĵ æĸŃ +åįĬ å°ıæĹ¶ +mal ink +us a +Ġinstruct ors +оР¶ +ï¼Įä¹Łå°±æĺ¯ 说 +Ġreserv ations +,ä¸į 管 +ĠB SD +éĩı 为 +Imp lemented +Ġн е +æĭĽ åĭŁ +ĠLik ewise +Ġro ok +建设 é¡¹çĽ® +ĠL ions +Ġqual ification +Cur ve +_r x +æĺĵ äºİ +ac ious +.N ET +ä¼ļ 产çĶŁ +æīĭ ä¸Ģ +O rientation +Ġal umni +C SS +Ġplay ground +Ġaccount ed +Origin ally +(f rom +éħ± æ²¹ +Ġ åIJĮæĹ¶ +çľ © +åľ¨ æĸ° +åľ° 带 +ĠEl ite +ï¼Įåľ¨ è¿ĻéĩĮ +Ġun ified +Ġmat urity +çļĦ æĦıä¹ī +åĢĴ äºĨ +ĠC incinnati +æľº ç»Ħ +Ġun common +ĠS cheme +Âł Z +Ġprinc ip +b read +Ġbroad ly +Ġroot ed +å®Ŀ 马 +Ġformat ting +æ³ķ å®Ŀ +ï¼Į åŁºæľ¬ä¸Ĭ +æģ ķ +.d omain +Ġh ipp +ĠP atch +. cloud +ĠEng agement +Ġfree zer +is her +åĮ ķ +Ġmanip ulate +ĠC atherine +! , +Ġgra pe +çļĦ 她 +br anch +æĸ¹ æīį +ĠA ware +ä½ķ å¤Ħ +èĩª å®ļä¹ī +.get Message +ĠOak land +_v ars +Ġher bal +ï¼Į 注æĦı +_M ESSAGE +è§Ĥ åħī +P RE +ĠAn a +Ġreal izing +Ġis o +å©ļ 纱 +En code +s ent +unc an +Ġo we +ĠD ollar +ĠHy brid +ãĢĤ æĹł +æĬ Ĵ +Ġ" __ +log ging +ĠMonth ly +æİĴè¡Į æ¦ľ +Ġnom ination +for cing +Ġmicro bi +u o +åįģ ä½Ļ +åĮ» çĶŁçļĦ +ãĢģ ä¿Ŀ +ï¼Į æĵįä½ľ +Ġn aming +Ġend ors +ĠðŁĺ ī +Ġtrack ed +Ġsubsid iary +ib aba +-d egree +ãĢģ å¼Ģ +Ġplace bo +æĥħåĨµ çļĦ +ä¸ī åĽĽ +Ġpar ish +æķ´ æ´ģ +åĨłçĬ¶ çĹħæ¯Ĵ +Ġmot ors +Equal To +Ġk o +åħ¨ æĸĩ +à ³ +---- --- +.m icrosoft +ar b +æ¯ ĭ +ĠF act +Ġcan al +çļĦ æĸĩåĮĸ +Ġ[ ` +ĠA ur +r ice +ï¼Įæķ´ 个人 +contain ing +coh olic +Ġdece ased +Ġs ang +att ach +ä¸į å±ij +w l +ï¼Įåľ¨ ä»ĸ +. icon +åĮ»çĸĹ æľºæŀĦ +èĢħ åľ¨ +/ ? +å¹´ 被 +ĠGu ides +f ixed +{ q +ï¼Į æĽ¾ç»ı +Ġm b +' - +Ġgl orious +Ġbrut al +% d +ch ip +ĠBl ake +éĿŀ常 æľī +\ ,\ +ĠE agles +unn able +西 è£ħ +Ġdep ressed +S kin +ï¼Į æĺ¯ä¸Ģç§į +let es +Ġtext ures +oe ing +ä¿® 饰 +ĠAr ctic +Ġfirm ware +Ġfont s +Ġd ice +_s ystem +å¹³ æĹ¥ +åħī æºIJ +Ġvent ilation +åı¯ä»¥ 缴æİ¥ +çij ķ +æŃ¤ 人 +R om +r ill +ï¼Į èĢģå¸Ī +èĤ¡ä¸ľ çļĦ +对 ä»ĸçļĦ +Ġsurv iving +ĠÏ ĩ +被 åŃIJ +ĠReg ulations +ï¼Į è¿ħéĢŁ +it ives +ä¸į 妨 +Ġav ail +çģŃ çģ« +ens itivity +ĠQu ad +临 è¿ij +Ar c +oc co +èIJ¥ä¸ļ æī§çħ§ +. { +Ġun belie +ĠL aser +çĦ¶ 大 +ĠL OL +æĻ Ķ +ĠD ot +è¿Ļ åĩł +Ġv ag +çī¢ è®° +è§Ĥ éŁ³ +Ġnotice able +ĠL ay +-b ook +ĠAdminist rator +[ _ +ä¸į æĽ¾ +Ġ æ¯ķ竣 +Ġplace holder +Ġobst acle +åľ¨ ç½ijä¸Ĭ +Ġaut onomous +et tes +Ġassert True +B ridge +Ġsp ices +Ġsp awn +è¿Ļ个 å°ı +Ġarch ives +ĠCall ed +_ email +ä¸Ģ åıĮ +cc cc +Ġdiv isions +Ġintent ional +æ´ĭ æ´ĭ +æ²¹ èĦĤ +.m ark +ï¼Į以 ä¸ĭ +Ġbe verages +æ¯Ľ åĪ©çİĩ +ĠS ierra +_ it +ä¸į å¹³ +书 åºĹ +Ġviol ate +Ġvar s +çļĦ æ¯ĶèµĽ +åIJĪ è§Ħ +çĭ¬ç«ĭ èij£äºĭ +ring ton +Ġc age +\right arrow +该 æĢİä¹ĪåĬŀ +çļĦ åģļæ³ķ +åŀ ® +ĠB ottom +it ic +ãĢĤ ä¸ĭ +éĻIJ 度 +æĿŁ ç¼ļ +Ġd orm +ì ł +Ġmod elling +Ġearthqu ake +. Open +çĬ¹ 太 +ãĢĤ çϽ +ï¼Į 符åIJĪ +å°± å°Ĩ +èĤĿ èĦı +ï¼Į éľĢ +éħ ļ +åĴ Ķ +è¿Ļ çīĩ +åijĬè¯ī æĪij们 +Ġincon ven +Ġdraw er +å¼ Ľ +Ġg ases +Mod ern +.m odule +Ġz inc +缺 失 +ï¼Į åŁ¹åħ» +ĠS chema +ĠG ain +个 个 +oll ary +Ġtw isted +ist ries +Ġcon gest +ĠT ol +éĿ¢åīį çļĦ +éķ¿ æĺ¥ +Ġpremium s +Opt s +ĠDe ck +Ġimper ative +ï¼Įä½ł æĢİä¹Ī +åͤ éĨĴ +Ġvoc als + ĥ +Ġcomfort ably +.ext end +éĢļ çļĦ +ĠM ig +ä½ı çļĦ +ãĢģ ç͍ +Ġend ot +欧 åĨł +ä¸Ĭ æ¼Ķ +Ġ èĥ¡ +Ġwork outs +Art icles +ĠCarl os +ä¸Ģ æ³¢ +è¿Ļ å®¶ä¼Ļ +Ġre active +ĠB att +Trans late +Ġc urrencies +裤 åŃIJ +& M +èĩª è¯Ń +.A zure +Ġ åĬł +Ġtim ber +Ġamend ments +ĠDis cuss +ï¼Įä½ł æĺ¯ +ç»Ŀ对 ä¸įä¼ļ +ä½į ç§» +c art +unicip ality +Re ceiver +_RE T +Ġstoryt elling +Ġten ure +Ġw ishing +äºĨä¸Ģ ä¸Ŀ +.F ind +èĪį ä¸įå¾Ĺ +Ġ æĹ¶éĹ´ +Ġbreak through +ãĤ ¸ +ĠCru ise +åİŁ æľī +Ġth ru +_ sec +Ġrespect s +ĠAre as +å°± æĥ³ +AMP LE +空 åĨĽ +ï¼Į åĪĩå®ŀ +çļĦ è·Ŀ离 +ĠSt ats +ĠW M +se g +åįİ äºº +æ¯Ľ å·¾ +tt le +å·¡ éĢ» +_n ormal +ĠHar vey +ar at +. port +( status +test s +ä¹Į åħĭåħ° +Ġdem ol +ãĢģ 以åıĬ +or ig +ĠAppro ach +æķ£ æŃ¥ +at ient +Code c +P odcast +izar re +Ġlight ning +ERV ICE +ĠNon etheless +Jes us +ä¸į æľį +aus ible +Ġcho oses +çķı æĥ§ +. impl +们 éĥ½ +æ°ij æĶ¿ +åĴ Ļ +Ġ( { +. Inter +Ġvol atility +ĠC AR +Ġceleb rities +_RE QUEST +ĠDis able +ĠT IME +Ġcond em +Ġoper a +Ġassert ed +Ġun re +Ut ilities +å¦ĩ 人 +ar u +W arnings +ĠPl ot +Ġcontin uation +ĠL abs +å¤ļ åIJĥ +涨 åģľ +åģļ 个 +ĠGi ants +éϤ éĿŀ +ç´ł çļĦ +ä¹ĭ åŃIJ +est ure +æĸĩä»¶ 夹 +.g rid +æİī çļĦ +ä¸Ģ æĹł +ĠY am +umm ing +å¦Ĥæŀľ æĺ¯ +ï¼Į æıIJ +åĹĵ åŃIJ +Ġdepos ited +Ġm ph +en abled +col ors +èѦ 示 +, ä¸Ģ缴 +çĮ © +æ±½ æ²¹ +h ref +Ġm c +æŃ» åİ» +ä¸į åĩĨ +ä½İ 声 +ĠSub scribe +ĠM UST +Ġadv ancing +å·® é¢Ŀ +Ġkin etic +ĠX ml +ĠTake aways +Ġsp oon +h um +ĠDeb t +ĠEvent ually +He art +Res pons +lob als +C odes +ï¼Į æ´Ľ +ĠCom parison +ä¸Ģ è§ģ +çĻ«çĹ« çĹħ +梦 ä¸Ń +交éĢļ å®īåħ¨ +Ġsem inar +less ness +AP H +ĠESP N +æľī ä¸įå°ij +Ġprem iere +g mt +Ġ ç¾İåĽ½ +çŃ· åŃIJ +ï¼Įæ¯ı 个人 +eterm ined +Ġsc ans +çĻ» åľº +ĠPl aza +yl an +Ġbe e +âij ¤ +é¢Ĩ æĤŁ +whe ther +ï¼Į éħį +ĠÎ Ķ +m ass +at ia +åĩĢ æ°´ +ĠM PI +ĠP am +Loc ations +Ġwe aker +èĻļ å¼± +æīį åįİ +Ġrisk y +S ummer +çľ¼ ä¸ĭ +GR ect +" This +没 åħ³ç³» +æķ£ æĸĩ +ä¹Ł æĥ³ +ĠR an +ĠPret ty +åħħ å®ŀ +mar shal +Comm ands +åį¡ å°Ķ +Ġse ized +_s ort +äºĴ èģĶ +just ice +oss ip +S cheme +æŁ´ æ²¹ +ĠW ed +æ°´ è´¨ +论 è¿° +ĠG ates +Opt im +Ġg reens +Part s +ãĢĤ ï¼ī +ĠF D +ãĥ Ń +æµģ ä½ĵ +ĠV o +ce ans +çŃī æĸ¹éĿ¢çļĦ +ĠT un +å¢ Ł +Ġcrack s +Ġlower ing +Max imum +åıį 驳 +-st art +åªĴ ä»ĭ +ï¼Į æĮģç»Ń +isp atch +ï¼Į åįĥ +åįĩ èµ· +_F LOAT +æ³Ħ æ¼ı +Ind ices +Ġhom ogeneous +Ġâ Ļ +Ġr v +. This +-ch anging +ĠW ish +_P OS +ĠAsk ed +Ġaff inity +any a +èĤ ´ +æ¦ Ħ +åħ¸ 礼 +od b +ãĢĭ ä¸ŃçļĦ +åIJķ å¸ĥ +æĥĬ æģIJ +åŃĹ çļĦ +å¯Ĩ çļĦ +æĪIJç«ĭ äºĨ +tt i +_in st +Ġconc erts +Project s +åģı å·® +ĠV AT +奶 ç²ī +ĠLaw yers +Ġbook mark +ĠH B +Ġwar mer +Ġо ÑĤ +游 çİ© +str cmp +Ġdivid ing +erial izer +è¿ľ æĸ¹ +AB EL +æ®ĭçĸ¾ 人 +v ic +en ium +.n ow +çIJ¢ 磨 +.D iagnostics +éģĩ åΰçļĦ +( view +ä¸ĩ åĪĨ +亲 æīĭ +Ġ第ä¸ī èĬĤ +ĠS aints +_res et +Christ mas +çĤ Ļ +å¤ļ 大 +åŃĹ æķ° +ĠEx c +Ġfulfill ment +) ! +Ġent ailed +åѦ è´¹ +the se +æĭī 伸 +Ġsup ers +ĠO T +Ġfis her +ĠCabin et +ãĢģ åģ¥åº· +è¨Ģ 论 +çζæ¯į çļĦ +anal ytics +çļĦ ç͍æĪ· +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +ĠRe place +ad vert +ĠAdd ing +ĠN Z +ï¼Į åıĬ +ä¹Łä¸į ç͍ +Ġt read +Ġth under +éĽĨåĽ¢ åħ¬åı¸ +-c ode +. abs +Ġab used +åºŀ 大 +Ġtables poons +.S ervice +éĺµ åľ° +ĠS EM +ĠU ber +æ½® 湿 +ĠS ou +ĠU AE +代表 çĿĢ +ĠO ri +ĠT T +Det erm +.L oad +Ġmi R +å®ŀéĻħæİ§åζ 人 +ĠB read +ros so +D estination +W i +çĶŁæ´» æĸ¹å¼ı +饮 ç͍ +ĠIns ights +c lo +ĠK er +ï¼Į æĪĺ +J s +Ġt ex +æĿ¥ çĿĢ +и ÑĢ +_H OST +Ġsc ram +ï¼Į åĽ¾ +åıª åī©ä¸ĭ +饮 éħĴ +Ġincorpor ates +ãĢģ è¡ĮæĶ¿ +H en +Ġreal ization +Gu est +æĮĩ 纹 +æīĵ åIJ¬ +.com ponent +ãĢģ 为 +çļĦ好 å¤Ħ +æĹ¶ æĬ¥ +æ·· èĽĭ +第ä¸Ģ èĬĤ +- no +æĪIJ为 ä¸Ģ个 +æĬĵ ç´§ +_f actor +ä¸į 被 +em in +Ġdismiss al +Ġspot light +Ġd awn +m k +ĠD oll +Cl ause +ĠF emale +æij§ æ¯ģ +ãĢģ åıĮ +ĠAm anda +åŃĹ èĬĤ +æĸŃ è£Ĥ +Block ly +çĥŃ å¸¦ +{ table +ãĢĤ å®ĥ们 +Pop up +ar is +çŁŃ 线 +S ym +è¡Į 车 +æŃ¦ å¸Ŀ +èķ´ åIJ« +esthes ia +f older +èī² åĪĹ +Ġ åįķ +ãĢģ çݯå¢ĥ +èĩ Ģ +ĠHistor ic +大 åı« +ĠHug hes +Ġw ipe +ä¿® çIJĨ +çϾ éĩĮ +H om +N OW +UM P +ancell or +? The +S ig +éĥ½ä¸į æķ¢ +ri ages +on ge +ĠAl cohol += new +é¦ĸ é¢Ĩ +Ġamer ican +Ġprot agonist +åĵª å®¶ +-m ode +ram ento +ç¬ij äºĨèµ·æĿ¥ +opl us +å±ķ ä¼ļ +ï¼Įä¹Ł åı¯ +åIJij æĿ¥ +Ġdifferent iate +Ġtre k +ul p +ĠHol mes +Ġ èİ·åıĸ +it as +Ġir res +ĠBasket ball +_t ensor +Ġl ively +空æ°Ķ ä¸Ń +å¸IJ 篷 +åħĪçĶŁ çļĦ +æ¡Į éĿ¢ +èᝠåīĤ +Ġind ef +âĢľ æĺ¯ +å¼ł å®¶ +ĠX XX +å§ Ĭ +ĠVe get +ï¼Įä¹Ł ä¸įçŁ¥éģĵ +ãĢĤåľ¨ æŃ¤ +ĠDem on +æ² Ĥ +ï¼Į 温 +D isk +m oz +ribut ors +æµ· æĭĶ +arrant y +浩 çĦ¶ +Ġepid emic +ĠImm un +ĠMer cedes +. IN +.Thread ing +col on +èģļ åIJĪçī© +Ġpred icate +Ġancest ors +ĠM ann +ili ans +Any one +åĢĴ éľī +Ġstret ched +Ġemphas ized +ĠW ear +cript s +ĠKat ie +Ġr ider +on itor +æĶ¾ å°Ħ +建 åĽ½ +ãĢĤ æĿ¨ +Ġpol ish +inc are +Ġs ans +ĠSub scription +带 åΰ +Ġrecover ing +ï¼Į éŨ +ph is +æĴ° åĨĻ +RO UND +ĠBre xit +滤 æ³¢ +æ¢ ¢ +åĢĺ èĭ¥ +æĿij çļĦ +ĠC Y +æģ° å½ĵ +p icker +ge bras +.g if +Ġelect romagnetic +ï¼Į ä¸¥æł¼ +æĹĭ å¾ĭ +çĭ¬ å®¶ +_CON ST +, æķħ +æĬķèµĦ çļĦ +ï¼Įè¿Ļ个 æĹ¶åĢĻ +æ² ® +Ġ@ @ +欣 åĸľ +R G +éļĶ å£ģ +åĪĨ åĮº +ĠClaim s +Ġuniform ly +Ġenvironment ally +S ir +éĿ¢ åħ· +ç» Ĭ +ĠNe ck +åIJĦ åľ°çļĦ +å¸ ľ +Ġj our +SE QU +åĸī åĴĻ +ĠS of +ĠB urg +Ġsh aking +_ common +.get Id +in ch +没 éĹ®é¢ĺ +åIJ¸å¼ķ åĬĽ +Ġcush ion +T ur +ĠBar ack +Ġself ish +_P A +æº ī +ĠZ ip +Ġgran ite +ãĢĤ äºĶ +Ex cel +ĠCall ing +E ll +NOT E +Ġflu or +osp here +åľĨ æŁ± +_ rows +' / +æĺ¯ å¦ĤæŃ¤ +ĠCris is +, æĿ¥ +çŁ¥è¯Ĩ åĴĮ +èĩª 豪 +åı¯ä»¥ åĮħæĭ¬ +ĠW aste +Ġbroad band +ç³» çļĦ +åĨħ ä¾§ +被 è¿« +Ġinsert ion +Ġh ats +ä¼ł åĩº +Ġ å¦Ĥä½ķ +åĵ º +Ġout rage +-f i +æĺŁ åº§ +以 æĿ¥çļĦ +å·² åľ¨ +âĸ ł +ï¼Į å¤ľ +Un categorized +_ change +Ġk icks +av ier +Se ason +ĠC ob +ad as +Ġwas t +\ - +ï¼Įåį³ åı¯ +iss an +Ġcoc aine +ĠL T +åij¨ å²ģ +ï¼ģâĢĿ âĢľ +计 è¾ĥ +èµ £ +Ġvot er +L U +å̼å¾Ĺ ä¸ĢæıIJ +æĶ¿çŃĸ çļĦ +æīĭ æİĮ +éĢĤ éħį +ĠLink ed +/ env +åħī æ³½ +Ġinstall ations +U UID +åį ¯ +ä¸įè§ģ äºĨ +ĠV acc += t +çļĦ æĿIJæĸĻ +Ġs her +ãĢĤ 两 +ĠFr ag +Ġflat ten +å¹³ æ·¡ +æ¯ı个人 éĥ½ +äºĮåįģ åĽĽ +Ġinst ability +æĮĩ è´£ +Ġbron ze +çī© ç§į +论 è¯ģ +Is rael +Ġc n +ac ion +ä¸į èĪį +è¡Į äºĭ +ĠQ U +é£ŀ çļĦ +Ġrecogn ise +ï¼Į èĥĮ +御 åı² +ç²Ĵ åŃIJ +Ġdisappoint ment +S ix +åij½ é¢ĺ +ï¼Į æĪIJåĬŁ +erv ations +æķĻ çļĦ +åħ Ģ +Ġdiet s +(t able +- Up +æ±Ĺ æ°´ +ĠDev ices +åħ ¢ +Ġ" \" +çħ¤ çŁ¿ +uck ed +& lt +d ar +åİĮ æģ¶ +V s +ĠProv ince +Ġsho ppers +ĠPhot oshop +_App Compat +Ġaw ake +Ġdeliber ately +( end +Ġh ated +ç» ° +æĻ ¾ +ĠMark down +Ġcrim inals +Ġ æ¸ħ +åī§ ä¸Ń +éĻĦ å½ķ +Ġsc enery +å¤Ħ åĪĨ +åľ¨ å¤ĸéĿ¢ +.D ec +产 åIJİ +ĠReport ing +Ġwhere by +Ġundert aking +Î ¾ +äºĨä¸Ģ çķª +OV A +Default s +ĠR osen +Ġinv ites +-gener ation +P aper +vers ions +Ġtrust worthy +ãģ Ĭ +çħ³ æ¶Ĥ +K nown +ãĢģ åĽ½éĻħ +os i +çŁ¥è¯Ĩ çĤ¹ +Ġarg uably +Ġnormal ize +ĠBe an +te le +Ġ! ! +çĥŃ çĥĪ +ĠC elt +æĺİ çıł +Ġemerg ence +æĭĩ æĮĩ +åĨĻ çĿĢ +å·§ åħĭåĬĽ +det ail +ï¼Ł è¿ĺæĺ¯ +é²ľ æĺİ +ĠUn its +, å¿ħé¡» +è¾ĵ äºĨ +ro ots +az ure +éĻįä½İ äºĨ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +Ġlear nt +éĩij å±± +å¨ ´ +ĠInst ance +ï¼Įä½Ĩæĺ¯ ä»ĸ +. it +iqu it +Ġex emption +ĠC urt +- select +or ient +r ators +ä¹Ł åıªèĥ½ +æļ´ 鼨 +. exp +u pper +-p owered +å®ī å¾· +çͲ æĸ¹ +ĠPre view +Ġun available +æĬĵ ä½ıäºĨ +æĤ¬ æĮĤ +gener ate +Ïģ α +è¤ ļ +é¾Ļ çļĦ +çī¢ çī¢ +å·¨ 头 +çģ« å±± +E r +AT IVE +Ġ æĽ´ +Ġ èĤ¡ +D ataset +_ ct +ub ric +_d epth +k ernel +ĠMil waukee +Ġadvert isement +ĠS equence +( byte +æĦı åIJij +âĸĪ âĸĪ +% ï¼ī +RE QUEST +çļĦä¸Ģ çĶŁ +Ġneg lected +å±ŀäºİ èĩªå·±çļĦ +Ġcheck list +ĠIllegal ArgumentException +Ġl s +Ġexp iration +ĠC rypt +ĠP od +ĠR ico +æĭ¼ æIJı +process ing += p +_ ne +project s +Ġ 鼷 +æ°´ ç®± +Ġadd ict +Ġl anes +Ġ( ` +èĪ ľ +Ġ ä¼ģä¸ļ +æĥ³è¦ģ çļĦ +Ġillness es +j k +_c ase +ĠI A +Ġrout inely +.s ession +Ð ¡ +ä¸Ģ åħ± +ST IT +Ġve in +Ġ= ================================================================ +ï¼Ł ï¼ģ +ĠPortug uese +ä½ĵ çİ°åľ¨ +ind y +Ġintu ition +âĢĿ ä¸İ +, åīį +åħ»èĢģ ä¿ĿéĻ© +Ġcompl ained +K im +ĠBut ler +ì ŀ +Ġexpend iture +ä¹ĥ æĺ¯ +F etch +ĠRelations hip +Ġar ithmetic +ij k +M ade +PO INT +è¾¹ å¢ĥ +åŁŁ åIJį +Ġcivil ization +second s +ĠL S +ap ons +c ology +Ġ æĬķèµĦ +è¯Ŀ éŁ³ +ne a +Ġcur b +icular ly +ä¼ĹæīĢ åij¨ +Ġpred icting +: self +æĹ¥ åĨĽ +ĠW I +ĠG H +许 ä¹ħ +.N et +ĠGit Hub +ĠP ars +ĠD uration +ĠW ritten +B esides +é¬ Ł +Ġspont aneous +work er +as per +Ġsm ok +第äºĮ èĬĤ +Ġyou tube +< bool +ĠFound er +å®ŀçݰ çļĦ +ç«£ å·¥ +åĸ Ķ +åĤį æĻļ +. img +Ġs ailing +Sar ah +Ġward robe +ĠBas ically +çϽ äºĨ +æĸĩä»¶ çļĦ +ĠLaure n +é¢ĩ æľī +Ġfile Name +Load ed +ï¼Į åζå®ļ +av i +å½ĵ æĪij +ï¼Įä½Ĩ 她 +ĠD owntown +ï¼Į èĩªå·±çļĦ +峡 è°· +æµģ 转 +é¦ĸ è¦ģ +æª IJ +å¸Ŀ çİĭ +åīį æ²¿ +atern ion +å°± æĽ´ +ĠQ atar +åıĺ æĢģ +u est +Ġconvenient ly +.pro ject +Ġchar itable +æĶ¯ éħį +ĠF ear +ĠO m +CRE ATE +Ġpre y +讲述 äºĨ +Ġ æķ°æį® +ĠG ifts +æĺŁ ç©º +人 æµģ +Ġor n +ĠSh ore +Ġins ane +ple asant +ack ing +羨 çľ¼ +ĠCo aching +Ġbrid es +éģ ı +un i +è´¨ æĦŁ +æĹ© æĹ¥ +丢 äºĨ +Ġdeb it +Å į +åıĹ ä¸įäºĨ +. UI +è§Ĩ åĬĽ +ĠLet ters +éĻ· åħ¥äºĨ +Ġun related +çļĦ è¡£æľį +å°± è¯Ĭ +Ġprivile ges +åĻ ¢ +éĴ ° +å¼Ħ å¾Ĺ +ĠVictor ian +Ġle aks +ç«Ļ ç«ĭ +ãĢ ĩ +ĠBry an +h art +äºļ 马 +ĠApp arently +æļĹ ä¸Ń +Ġre per +Ġones elf +ĠBr ig +an other +ĠC AS +è¿Ń 代 +Ġinst itute +ç¼ł ç»ķ +Ġshe ar +转æį¢ 为 +Ġfract ure +feed ing +åĨľ èᝠ+Ġc itation +ĠID s +ç§Ł æĪ¿ +l ator +Ġad en +åħįçĸ« åĬĽ +æijĩ æĻĥ +ä¸į ä½³ +here nce +壮 大 +个 åŃIJ +ç© ¹ +Un less +it é +Ġn erves +ĠTop ic +ç»ıåİĨ è¿ĩ +Ġequ itable +Ġæľ¬ åħ¬åı¸ +x iety +Ġaccommod ations +éĻĦ 注 +Ġdo cker +ï¼Į å®īè£ħ +- pl +h one +in as +l iness +Ġsp iral +èģĮä¸ļ çĶŁæ¶¯ +Ġassert s +åѦ éĹ® +Ġinf il +æĹł å¿§ +_LO AD +伤 亡 +} & +ĠT ak +ãĢģ 建çŃij +ĠN ar +Y M +al ore +ï¼Įåľ¨ æŃ¤ +Ġconf irms +Ġ ঠ+Ġ ounces +/ ${ +UM M +( Z +Ġspec ifying +Ġlandsc apes +å¿ħ ä¸įåı¯ +å°± ä¸įèĥ½ +梦 å¹» +ĠC otton +Ġout dated +man aged +ĠCl uster +_N ULL +ĠQu est +ab ol +ĠMus k +åĵ Ĵ +erv ical +T en +æı ª +S leep +Ġh ose +æĭĨ è¿ģ +ĠW ILL +ĠG ender +åĸ· æ¶Ĥ +éģĵ ä¸Ĭ +Const ruction +å¯Į è£ķ +Ġdebug ging +te enth +ãĢĤ 让 +ĠP ixel +ãĢģ 举 +åIJ¬ åıĸ +ĠK oh +.C l +Ġparad igm +ĠDep osit +çļĦéĤ£ æł· +. Instance +åĪĺ å¤ĩ +èģĶ æĥ³ +ï¼Į 游æĪı +\ limits +.C md +RO LL +ĠH yd +hem atic +ĠChe ese +å¹² äºĨ +il ant +ĠOper ator +èŀº ä¸Ŀ +" { +å°ı åIJĥ +Ġstre ak +åĴĮ æĪij们 +-th rough +(b lock +èĦ± èIJ½ +ĠGl ad +ans on +Ġhope ful +éļ¾ æĢª +æł¼ å°Ķ +_st d +ĠSh oes +Ġret ry +Ġmed ieval +ĠD ow +以 å¤ĸçļĦ +Don ate +éĢĥ 离 +éĺ ľ +erg y +âĢľ In +Ġlong itudinal +Ġ è¿ĻéĩĮ +Ġpost ure +ãĢĤ 她çļĦ +Ġ æĶ¯æĮģ +çļĦå°ı ä¼Ļä¼´ +ç«¥ è¯Ŀ +ç¡®å®ŀ æĺ¯ +éĩı åĮĸ +Ġcompl iant +en ic +Ġorig inated +Ġ èİ« +ĠC arr +i ostream +Ġfreel ance +ĠD uty +ï¼Į çłĶç©¶ +ĠD D +U INT +arg uments +ĠI celand +Ġf aint +毫æĹł çĸijéĹ® +, X +ï¼Į éĩįçĤ¹ +Ġutter ly +è¿ij è§Ĩ +ĠUS ER +饮 æ°´ +Ġcol ony +çϽ éĵ¶ +æ¸ħæĻ° çļĦ +Ġfre ight +Ġlaw makers +ĠDep ression +éĺ¿æĭī 伯 +Ġ çα +éĵ¶ æ²³ +æİ¨ éĢģ +imon ials +Ġhook s +ĠImp lementation +Byte Array +{ h +Ġcor pus +éľĢæ±Ĥ çļĦ +Ġdirect ive +/p kg +Ġsurre nder +è¿Ļä¹Ī 大 +âĢĿ ä¸Ń +ä¼ģ åĽ¾ +èĨĿ çĽĸ +Ġre con +诸 ä½į +ar ial +å½ķ åζ +Ġunlaw ful +ast ian +ĠFam ilies +ãĢĤæľ¬ 次 +ç͍ åΰ +itut ing +AY ER +ham mad +а Ñģ +å¹³åı° ä¸Ĭ +Ġl ar +' _ +asp berry +ãĢĤ çͱæŃ¤ +Com pute +Ġcl ues +éĵ¸ éĢł +Ġanal ytic +Ġe u +ï¼Į æķ´ä½ĵ +is ot +åħ« å¹´ +in ers +è¿Ľ èĢĮ +olic ies +pe ctions +éĩį å¿ĥ +ĠCl are +ĠSer ge +Ġsampl ed +è¾¹ ä¸Ĭ +d ig +Perm issions +ï¼Į åħŃ +_st op +èĩª æĿ¥ +çΏçΏ å¦Īå¦Ī +su its +é² ¸ +Ġseason ed +åĮĹ京 æĹ¶éĹ´ +ĠIncre ase +, 两 +Ġjoint ly +Ġcr ush +in ished +Ġequival ence +Ġtra iling +çļĦ 温度 +W N +çŃ ± +Ġhazard ous +ĠMarc us +nav bar +å°± 说 +Ġphotograp hers +èµ ĺ +ill ery +ha o +-d ev +Ġdipl om +éĤ£ ä½ł +cre ment +å°¼ åħĭ +ĠCom fort +è£Ĥ ç¼Ŀ +Ġserv ant +uk a +ä¸Ģ ç¬Ķ +å¤į åıij +æŃ» åIJİ +_M ETHOD +çİ© èĢį +, å®ŀçݰ +ä»ĸ äºĨ +C AD +åħ¨ å±Ģ +åŃ µ +æİ¥åıĹ äºĨ +å¥ij 约 +çŁŃ æĹ¶éĹ´åĨħ +ï¼Į åIJ¬åΰ +b ench +ĠS ue +åħ¬äº¤ 车 +am ide +使 èĢħ +ĠSecond ary +igh b +Ġund erest +л Ñı +op a +Ġpay able +Ġform atted +( ", +ynt hesis +eval uate +( å¦Ĥ +Ġsp ike +/upload s +ĠS ed +ç»ıéªĮ çļĦ +lest on ++- +- +_s cope +ĠTer rit +ĠW idth +yl ene +大 å¥ĸ +æį® äºĨè§£ +Ġst rap +åĶ Ķ +Ġhaz ards +Ġsupp lying +Ġanonym ously +é«ĺ åİŁ +éĩijèŀį è´ŁåĢº +_con nection +Ġen larg +IC A +æħ° éĹ® +.H ash +Ind ividual +ur bs +âĢľ åĹ¯ +Ġaw aken +Ġ åĩº +éĺ Ļ +ä¿Ŀ éķĸ +èĢĮ ä¸ĭ +ul let +éī´ äºİ +ĠM K +ĠR ush +Ġab ol +ĠV enezuel +åĵģ åij³ +Man ufact +amp agne +. Logger +Ġperform ers +è¿IJåĬ¨ çļĦ +åºĶ èģĺ +æĸ° å¹´ +Ġpass words +çĥ§ çĥ¤ +å°± åĮ» +c ases +å¦ Ĭ +oph ag +Ġpiv ot +Ar row +æĢĴ çģ« +å© ¿ +Mod al +w b +ĠRe ality +ĠSp in +item ap +éŨ æĪ· +ãĥ Ĺ +ĠRel ief +æīŃ å¤´ +ĠNorm an +ĠAT P +ĠâĨ ij +主 è§Ĥ +el ia +Ġbod ily +对 ä»ĸ们 +ochem istry +ok a +çļĦ æĶ»åĩ» +ãĢĭ åį· +Ð Ł +um inate +æ³° å±± +r ity +(T AG +ï¼ĮåħĪ åIJİ +Ġval ign +æ¯Ķè¾ĥ å¤ļ +Ġmir acle +æĩĴ å¾Ĺ +éĻķ西 çľģ +Ġcred ible +is ch +Dis able +ï¼Į å¸ĥ +ä¸į å½Ĵ +Ġg t +Ġd d +_h as +# undef +Supp ress +ä¸Ń ç§ĭ +ãĢĤ éĿ¢å¯¹ +ä¿® åħ» +é«ĺ ä½į +_g lobal +Dis abled +çŁ¥åIJį 度 +æīĵ 车 +è°Ī è°Ī +è¿IJèIJ¥ åķĨ +ï¼Į主è¦ģ æĺ¯ +çŃĶ å¤į +ĠPract ical +ãĢĤ éĩij +åı¤ åŁİ +ĠT urb +Ġres olutions +Ġan terior +æĮĩ éĴĪ +aly ze +å¤ĸ ä¾§ +Ġabdom inal +åħ³ åį¡ +R ear +ï¼Įä¸Ģ æĸ¹éĿ¢ +_ENABLE D +Ġpain ter +ï¼ĮçŃī å¾ħ +è¸ı å®ŀ +umin ium +çŃī åIJĮ +åĩł æŃ¥ +pos able +Ġl ob +è¿Ļä¸Ģ åĪ» +es ar +Ġse afood +Ġto es +ĠPart ial +æĶ¶ åΰçļĦ +N or +å°Ĭ 严 +äº ¢ +on n +le af +çŃī æĥħåĨµ +ĠAnc ient +èŀº æ¯į +ï¼Įä¸Ģ 次 +Ġuncertain ties +Ġop i +ĠPe ak +ĠL ua +ä¹ĭ æĹ¥ +Ġsegment ation +ĠSoc cer +çѹ å¤ĩ +Un expected +Ġsim ulate +ï¼Į ä¾ĿçĦ¶ +声 ä¸Ń +Ġreli ance +Ġ éĿĴ +re z +å½ĵçĦ¶ æĺ¯ +ç»Ļ ä½łä»¬ +Ġsecure ly +Ġdecent ral +çļĦ 责任 +Ġexerc ising +Ġspec ulation +ab ove +Ġconstruct ive +** ï¼Į +Ġsp herical +s peed +æĥ³åΰ è¿ĻéĩĮ +Ġc ottage +ï¼ļ æł¹æį® +Ġgen res +ĠCle arly +Ġch ap +æŀģ 度 +çļĦ æľīæķĪ +ä¸į çα +n ick +- positive +Ġr ifle +comm unity +IM AGE +uc ing +Ġsad ly +Ġpredomin antly +Ġsquee ze +å®¶ åħ¬åı¸ +Ġgl am +red itation +æİ¨ åĩºäºĨ +ãĥ ¬ +æ³ī æ°´ +好 转 +az ione +ĠAny thing +_F ALSE +Ġmar athon +ĠWhe never +ç§° èµŀ +硬 çļĦ +_f ont +æ¾ İ +宫 殿 +åIJ¬ çļĦ +Ġinf erior +H am +ĠÎ ¿ +西 åħ° +å°± 读 +Ġang els +ĠApp lic +æŃ¦ 士 +è·Ł åīį +; / +Ġgra vel +ä»» åij½ +m and +èī² è°ĥ +ĠSte in +J oint +ogn itive +Ġp ant +ĠB ristol +æĪij çľĭ +Ġl ord +ç§ijæĬĢ åĪĽæĸ° +ĠConsider ing +å·¥ æĻºèĥ½ +Ġcig arette +çľī æ¯Ľ +Ġblow ing +=" { +Ġtri umph +ä¿¡ è´· + +Ġth igh +IV ATE +Ġde ed +Ġcand les +ï¼Į ä¹Ķ +arg est +Ġcred ited +çı Ĥ +èĬ± çĶŁ +çļĦ å¤ĦçIJĨ +. em +:% .* +Ġfun n +_HE ADER +ĠReason ing +Ġow ning +ĠLux ury +se cret +Ġg aze +ĠL OC +磷 éħ¸ +. Group +-f our +, R +e conomic +Ġfin es +æĸ¯ å¡Ķ +使ç͍ æĿĥ +Ġair lines +C ele +Ġex h +Å ¼ +E th +urre nces +æ¢ħ èĬ± +ĠD ipl +ç¬ Ļ +og o +>\ < +Ġsec ular +Ġc ensus +ï¼Į æĽ´å¤ļ +Key board +Ġscream ing +æİ¢ ç©¶ +åIJĪä¼Ļ 人 +ur istic +ĠâĢľ [ +æ¯ı èĤ¡ +b usiness +\ s +J O +çĥ· åŁº +åį³ æĹ¶ +}} ^{ +Ġ第 åħ« +ï¼Įå¦Ĥ åIJĮ +r ina +еР¹ +ĠN ames +楼 ä¸Ĭ +ĠR alph +Cred entials +åĵª ç§į +çĮ« åĴª +L G +èµĦäº§è´ŁåĢº 表 +Ġphilosoph ical +iv ities +, åºĶ该 +_M ODULE +éĻ¢ 士 +ies el +ĠC OP +æģŃ åĸľ +åijĨ äºĨ +æĴ © +èĥ ļ +,ä¹Ł 许 +æĸ° æīĭ +Ġex cluding +æı į +åύ åĴĮ +约 ä¼ļ +g ra +em e +Ġdisc ourse +K n +å®ļ çĤ¹ +å¹³ æ°ij +å½Ĵ å±ŀ +ĠOtt awa +& B +ret ty +Ġmem o +_P TR +ĠL is +é¢ģ å¥ĸ +Ġsil icon +ä¹ĭ 声 +å¤ĸ å½¢ +St mt +ठ° +èµ· æºIJ +.d evice +åį´ åľ¨ +Ġcur ved +éĻª åIJĮ +æ²ī æĢĿ +æĹłäºº æľº +ogene ity +ĠC IA +ĠCh uck +irect ed +ĠST EM +ĠP ac +C fg +ä¸Ģ æĬ¹ +å½Ĵ æĿ¥ +Ġlat ency +M Q +港 æ¾³ +Ġc ows +ĠC AM +éĿ¢ æĸĻ +x A +ĠT icket +æ£ī èĬ± +_m at +ine es +e atures +çļĦ æ¦Ĥ念 +Ġch ore +ĠSt ainless +Ġκ αι +ä¸Ĭ 游 +ï¼Į çĤ¹åĩ» +ec urity +Ġsk ull +éĩį 伤 +è·³ èĪŀ +_P AD +æĹł ä¸Ģ +Ġtaxp ayers +plot lib +äºĮ çļĦ +, è¿Ľä¸ĢæŃ¥ +Ġsty ling +un ts +ä¸įçŁ¥ ä¸įè§ī +_CONT ROL +ï¼Į åİĭ +磩 å½¢ +ĠMont gomery +Ġgrand children +å¸Ī èµĦ +-s creen +å½¼ å¾Ĺ +çļĦ æĿ¡ä»¶ +åº ĩ +trans fer +Ġtradem arks +个 çϾåĪĨçĤ¹ +æĻļ ä¼ļ +ucl ide +Ġun pack +éŀ ł +. ', +åijĪçݰ åĩº +pos er +Ġdis connect +æĪ¿åľ°äº§ å¼Ģåıij +æīĭ èħķ +ĠF ut +inen o +åľ¨ æł¡ +æīĢ éķ¿ +Ġno od +é«ĺ é«ĺ +ĠC ause +个 大 +åķĨ æĪ· +ï¼Į èĵĿ +az i +ï¼Į åŁºäºİ +èı ł +et ed +ED I +Ġmult ic +Ġ' +è¿Ľ æ°Ķ +Ġar rows +Ġwrit ings +ï¼Į å¼Ģå±ķ +ï¼Įçͱ æŃ¤ +Ġcoord inated +Ġet t +ç«ĸ 缴 +æīĵ åĩº +res pect +æķ° é¢Ŀ +Ć ï¼Į +ĠPr im +导 轨 +追 溯 +éģĵ 士 +umb nail +_pro to +èIJ¥ æĶ¶ +j ah +, åĬł +æĬĢ èīº +æīĵ 个 +ĠReg istry +Ġdivid end +L ANG +çłĶç©¶ çļĦ +Ġgast ro +ãĢģ æķ°æį® +Ġalt itude +EE K +_p arse +å¾Ģ å¤ĸ +f ony +ĠB oss +m v +ä¸ĭ çıŃ +μ m +Ġbuff ers +ĠNAT O +U Y +.w ith +Ġhyd raulic +ay an +Ġscholar ships +Ġexpon ent +. au +obb ies +Ġcompl aining +åľ¨ 第ä¸Ģ +Ġw reck +Ġtr ump +_ex it +um or +ä¹łæĥ¯ äºĨ +Ġthat s +User Id +ĠSand y +æŀ¢ 纽 +m q +High light +èĥ½ æľī +Ġkil ometers +Ġcommod ity +C atalog +ï¼Į çħ§ +Ġimpl ants +Ġmac roph +åħ¬å¼Ģ çļĦ +N atural +è¿ĺæĺ¯ æ¯Ķè¾ĥ +s udo +Ġ å§ľ +set ting +Ġto ast +Ġcompet itor +ï¼ī æĺ¯ +. It +æĢĢ ä¸Ń +é© Ń +Ġflu ids +è̦ åIJĪ +.dec ode +Ġinter im +il let +ï¼Į èī¾ +è¡ ħ +é«ĺ æĸ°æĬĢæľ¯ +Ġfresh ly +çIJĨè§£ åĴĮ +аР· +ãĢģ ç»Ħç»ĩ +ĠBul let +: A +vert ices +_S UPPORT +ï¼Į 享åıĹ +Att achment +Inst ant +ĠScript ure +ament o +çĪ¶äº² çļĦ +get s +Ġa ka +( entry +计 æķ° +develop ment +Ġpol ished +Ġell ipt +Ġhon ors +.in stance +å¥Ĺ è·¯ +ĠCover age +æĭ Ļ +Ġstuff ed +Ġdescript ive +Ġbud dy +. Char +Ġine ffective +èµİ åĽŀ +Rec ords +ge o +èĦļ æľ¬ +Ġsummar ized +ãĢĤä¸Ģ æĹ¦ +è¿Ļ ä¹Łæĺ¯ +mut able +çī¹ æľīçļĦ +Ġunp redict +ï¼ĮæĪij åĴĮ +Ġf ry +D s +k et +å°Ĩ 被 +: C +ou g +ĠA str +[ edit +-n egative +人æīį åŁ¹åħ» += d +ãĢģ é£İ +马 æĿ¥ +id y +uzz le +ï¼Į è·¯ +çľĭ 书 +ä¸ī 个人 +b asic +Ġpolar ization +[ type +ĠR ib +ell ery +æĿł æĿĨ +G ar +éĺ¶æ®µ çļĦ +( Type +è¨Ģ ä¸į +Ġrec urring +ï¼Į缴 èĩ³ +Ġexpl ode +ãĢģ çĥŃ +\ f +plan es +AN A +æŃ ¼ +åĿĩ ä»· +comp any +Ġc inem +Ġdead lines +ĠCy cle +ï¼Į å¾Īå¤ļ人 +Null Or +ert on +ï¼Į æľ¨ +Ġlug gage +å¤ĸ åįĸ +åĨĻ éģĵ +Ġ èĢħ +åĴĮ 个人 +ĠTr inity +, 人们 +_IT EM +_F UNCTION +ĠNS W +Ġerr one +/ q +Ġdiscre p +Ġpract itioner +çķħ éĢļ +ĠXCT Assert +.D is +Ġm ills +åĨ· åĩĿ +Al ong +ĠD ell +为 ä¸Ģä½ĵ +ĠX L +Ġav iation +ĠDesign s +-m odel +ãĢĤæŃ¤ 次 +comp ress +å®ŀ äºĭ +äºĨä¸Ģ éĺµ +fol k +ä¸ĭ 令 +Appe arance +Ġsatisf actory +ĠDes ktop +Ġcertain ty +ĠSt ick +Ġf res +人 æīĢ +æĩ ¿ +Ġmight y +ï¼Į ä¸ĸçķĮ +Ġste ak +gener al +Ġne p +èĹı åľ¨ +LOB AL +over flow +西 çĵľ +Ac ad +he ng +map sto +Ġhilar ious +Request s +ä¹ł ä¿Ĺ +çĿĢ å¥¹çļĦ +it ant +am os +des ign +Ġmel an +Ġpro active +Ġhook ed +Ġacc us +.pro ps +ĠW ORK +说 è¦ģ +R edd +f en +ĠF lower +æľĿ åIJij +è´§ è¿IJ +de ep +ç¡®è¯Ĭ çĹħä¾ĭ +x E +S us +Ġprofess ors +Log ic +æ·ĭ æ¼ĵ +comm ands +PH A +ent ities +Ġapp rent +Ġqu art +ĠN est +Ġ çŁ³ +ï¼Į å¤į +å°± å¾Ĺ +Ġparagraph s +ĠBath room +å°Ĩ 士 +éª¨éª ¼ +ĠE instein +ä»Ģä¹Ī åľ°æĸ¹ +Ġ// ! +å± İ +Ġt b +ys on +çģĮ æºī +Ġw ont +çļĦ ç»ıéªĮ +éĢļ è¯Ŀ +çŁ¥éģĵ ä»ĸ +Ġν α +Ġ{ }, +Ġ? > +âĢľ What +ĠRe asons +l ash +ĠG ross +失 èIJ½ +æĪ´ çĿĢ +ĠFund s +ĠQ UEST +o os +åĴ ¦ +ĠBob by +m ind +om ore +éĽĨåĽ¢ çļĦ +åĿĹ çļĦ +åĨį è§ģ +ãĢĤ 被 +æł¸ æ¡ĥ +_s ymbol +Ġk an +Ġdi abetic +G EN +Ġcaut ious +: The +åζ 约 +Ġorth ogonal +_ impl +ĠS ara +ĠBl vd +ĠE lements +ï¼Ľ æľī +è¡Ģ çļĦ +æŃ¢ æįŁ +è½´ 线 +Ġhome page +imb abwe +- error +- web +Ġwas ting +ï¼ī çŃī +ĠAdminist rative +, ä¿ĥè¿Ľ +åļ İ +og an +.D es +ĠBre ast +Ġst orms +M ODE +å°± èĥ½å¤Ł +rid ges +S el +天 åIJİ +Ġguess ing +\ sum +ãĢĤ 缴åΰ +Ġsepar ator +ĠInd ependence +Ġf ats +æīŃ çŁ© +Ġbless ings +å¤ĸ åľ° +æľīæīĢ å¸®åĬ© +ï¼Ľ åIJĮæĹ¶ +.w ikipedia +Ġgas oline +ï¼Į åģļåΰ +Ġprov incial +å±ı éļľ +åĴĮ ä»ĸ们 +Ġrecru ited +.r and +段 çļĦ +ĠIP v +ĠS pencer +ĠH ob +os omal +æĻº åķĨ +ason ic +Ġrein force +ä¸Ģå®ļ ç¨ĭ度ä¸Ĭ +Ġh ype +In ventory +Ġc affeine +èĢĥ è¯ģ +ï¼Į è¢ģ +åºĶ åľ¨ +建设 å·¥ç¨ĭ +_G R +缴 åįĩ +(d evice +Ġpers istence +W rap +ĠBroad cast +- energy +ãĢĤ æĹ¢çĦ¶ +æĭī ä¸ģ +æıĴ ä»¶ +Ġcl erk +ç¬ ĥ +=" - +ç²¾ ç¾İ +Ġhead phones +m any +åĬł åī§ +( stream +it ures +oid al +éĶħ ä¸Ń +Ġtechn ician +å¤ļ æľĪ +ä¿Ŀ åį« +Ġdet er +A x +del ay +æķħ 乡 +_fe ature +åıł åĬł +\ "> +è¿ĺ ä¸įçŁ¥éģĵ +è¿Ľ çļĦ +Ġ îĹ¥îĹ¥ +éĹ µ +Ġref usal +æĭ¨ æīĵ +ĠOpen ing +pos ing +Ġfold ed +Ġintro ductory +Ġtang ible +æīĭ æĮģ +ĠR OM +ĠSh ift +模 çī¹ +ine z +æİĮ æŁľ +åĩ¶ æīĭ +, ä¸Ģå®ļè¦ģ +- action +亲 çİĭ +å²ģ æĹ¶ +, è¿ĻéĩĮ +伸 åĩºæīĭ +. Time +Ġmom s +Ġalter ations +å°¼ 奥 +Ġrec urrence +çĶŁæ´» ä¸ŃçļĦ +æľĢ éĩįè¦ģ +ĠD iversity +ä¸įåľ¨ ä¹İ +ĠEV EN +Ġlapt ops +ĠC rew +ï¼Į ï¼Ī +( child +Ġn oun +çݯ çIJĥ +çĭ ŀ +hy per +. $$ +S ol +Ġp ix +æīĵ æŀ¶ +h aus +éĩ ī +éģį å¸ĥ +æĿij å§Ķä¼ļ +èľ Ĺ +åįķ 项 +æĪª éĿ¢ +Ġadvis ors +Ġl amps +-s ided +第äºĮ çϾ +H F +ĠS SD +æŁ¥ å¤Ħ +ãģĵ ãģ¨ +âĶģ âĶģ +Ġev angel +å¤ļ ä¸ĩ +M us +Ġfact ories +Ġengine ered +-cent ered +æĬĹ æĹ¥ +Ġ åħī +Br ush +Cong ratulations +æħ ij +æĢĿ æĺİ +ĠFab ric +st rom +Ġcompens ate +Ġdeb ates +ĠBre nd +æ¯ı 人 +çļĦä¸Ģ ä½į +ä¹³ èħº +å¦Ĭ å¨ł +ur an +fl ies +Ð Ĵ +å¼Ģ çĿĢ +Ġ è¿Ļæł· +ĠP ET +Lower Case +æ¼Ķ 示 +Ġhalf way +ĠDiv ine +ç»´ å°Ķ +åѦçĶŁ 们 +-re peat +( host +othe red +e i +m obile +æľī ä¸ī +CL A +å¼Ĥ åľ° +ch unk +ir ie +ys et +Ġremodel ing +ĠE mm +èĢĮ æĪIJçļĦ +åIJij åIJİ +ct ree +Ġcream y +b ies +çͲ çĬ¶ +Ġhas ht +Ġdepth s +/ common +V ERSION +.con cat +ĠC reation +Ġn arc +and ez +é¢Ĩ导 å°ıç»Ħ +Ep isode +ĠDis ability +ï¼ģ æĪij们 +_en code +Ġcr ashes +ĠJo el +èĦ¸ çļĦ +æĬ¢ æķij +Ġdirect ing +éĥ½ æĥ³ +S y +æ¶īåıĬ ä¸Ģç§į +çļĦ è®®æ¡Ī +Ġcry stall +ĠRes cue +ĠCal gary +æĪij ä¸įçŁ¥éģĵ +çĤ¸ å¼¹ +ĠAl loc +ï¼Į åIJĮæ¯Ķå¢ŀéķ¿ +èĵ ¦ +comp ile +Ġdef ender +Ġspecial ize +åij¨ ä¸Ģ +åĴ Ĩ +Ġexecut able +æĭ¼ æİ¥ +ĠF ib +çľĭ ä¸į +Ġback drop +isco very +Ġtrack er +ex ecut +d z +Ġdw elling +åѦ åŃIJ +` s +ĠT P +Ġfart her +æµ· é²ľ +Ġt ide +Ġmicro phone +Re ally +ĠGarc ia +æĹ¶ éĴŁ +Ġmon sters +ĠRet irement +. cont +Ġfram ed +Ġsp ill +EX P +lick r +åħ´ èµ· +åĮĸ äºĨ +Ġsatur ated +Ġdom inate +[ T +-se cond +Ġveget arian +åijĺ çļĦ +ï¼ĮæľĢ 大 +å·¡ è§Ĩ +ĠBenn ett +μ ε +r é +ï¼Įåľ¨ è¿Ļ个 +Ġtim ed +Ġtext book +ĠRem oval +ĠAlex and +Ġv ault +ĠO re +Ġcelebr ations +åĮ» åѦéĻ¢ +ĠAn imals +ĠH annah +Ġcoll apsed +æĮĤ çĿĢ +ĠSe ed +ĠG S +ĠComp ared +cl one +Ġb ou +éĵ ł +便 ä¼ļ +Ġbal cony +æĺ¯ æł¹æį® +污 æ³¥ +ĠPort able +ĠN as +红 å¤ĸ +Ġterrit ories +.en code +ï¼ĮæĪij ä¸į +å¸ · +ĠGl asgow +éħ° èĥº +Ġp oured +ï¼Į åºĶ该æĺ¯ +è£ħ ç®± +ĠMc L +å¾Ī æĥ³ +Ġdestruct ive +Ġpolynom ials +ĠCap acity +Ġadoles cents +è§£ 说 +Ġmult itude +own s +Ġow ed +\ beta +å±ķ示 äºĨ +Ġs ab +丰 çͰ +- tech +è¥ Ł +[] [] +poss ible +å£ ¬ +Ġun authorized +ÑĨ и +ï¼Į åĪ«äºº +Ġch ic +ĠRe uters +Ġgen us +Ġinstall ment +iber nate +ec d +ĠNov a +Ġs v +Ġm aid +Ġind oors +.z ip +Ġce il +rit able +.B ack +ĠRel igion +æķ´ ä½ĵçļĦ +çĬ¶æĢģ ä¸ĭ +_s plit +F lex +Ġpol es +ĠPow der +Ġgift ed +ä¸ļ çķĮ +id ian +ĠApp rox +Ġallerg ies +-f irst +ä¸ī æĺŁ +x D +åģļ æĪIJ +Ben efits +åIJĦèĩª çļĦ +ĠA ub +è¾Ĩ 车 +ĠEngine ers +mat ches +çĸ¯çĭĤ çļĦ +ç¨Ģ éĩĬ +ï¼Į æĿ¥åΰ +-f illed +ĠGr ass +å®Ľ å¦Ĥ +çIJĨæĥ³ çļĦ +Ġproud ly +Ġaccess ory +à¹ Ģ +ĠD riving +æĮĩ æİ§ +æ¯ Ļ +ĠN L +ian ces +ç͍ æ³ķ +_ACT ION +æ» ķ +è®® ä¼ļ +Ġdynam ically +Ġc afe +Ġo ps +ĠW riters +ãĢĤ æŀĹ +B lob +.ch ildren +Ġdiam onds +æĥ ¬ +ener ative +Event Handler +we ed +ä¸Ń å°ıåѦ +ĠWe alth +E mer +è¤IJ èī² +. response +Ġvers a +游 è§Ī +积æŀģ æĢ§ +Ġanaly se +Ġopt ed +çļĦä¸Ģ 大 +çϾ åIJĪ +ĠAccount s +mm m +N ear +æĪIJçĨŁ çļĦ +. ]( +Ġ__ _ +le arning +Ġcon ject +ĠW alt +/ js +Ġsuccess es +Ġlo os +br ush +cy cles +å¼Ģ åºĹ +. As +ĠN ike +ï¼ ĺ +åī¯ å±Ģéķ¿ +ĠG y +æ¶Ĥ æĬ¹ +) åľ¨ +ç½ij çļĦ +Ġf f +U i +Ġcol i +(' - +æķ° éĩıçļĦ +ä»İ ä¸į +Ġw olf +Ġn omin +é«ĺ è¡Ģåİĭ +#### ## +_W ITH +LE AR +Ġcont our +AT ES +Ġmention ing +Public ation +举 ä¾ĭ +R h +çĶľ çĶľ +ï¼Į 令人 +æ¢ħ 西 +ãĢģ éĿĴ +Ġ åı¤ +æ© Ħ +_ interface +ä¹IJ éĺŁ +ĠPolic ies +ll i +éģĩ ä¸Ĭ +ra ces +Ġstar ring +Ġass ays +ï¼Į çĶŁäº§ +æľįåĬ¡ ä¸ļ +int endent +-ass ociated +Ġjust ification +ĠSt ir +éĹ» åIJį +车 åĨħ +åĽĽ æĸ¹ +ä¸Ŀ 毫ä¸į +Ġwra pping +ĠHur ricane +ĠSU CH +c odes +use package +çİ º +ï¼Įåıª æĢķ +åĸĿ äºĨ +- derived +ĠLiber al +Ġinherit ance +Tr im +help ers +и в +éļĶ çĥŃ +åģľ ä¸ĭæĿ¥ +\ ) +Ġle mma +plic ations +ä¸įæĺ¯ ä¸Ģ个 +Ġfert ility +M EM +dec ode +Ġhead aches +ãĢģ å±± +åIJ¬ è¿ĩ +ãģ ¡ +ç¥ŀç»ı ç½ij绾 +ĠB eta +ur ve +çŁŃ è§Ĩé¢ij +Mat cher +-function al +Ġp eg +Ġstead ily +h alf +è¿ Ħ +ĠD rew +osex ual +Ġsuccess or +ĠQueens land +ĠPublic ations +ĠE A +ĠG mbH +Ġcommit ting +hol m +åĵ Ĩ +Ġvers es +. å¦ĤæĿĥåĪ©è¦ģæ±Ĥ +人 马 +åĪ© çī© +å¹´ å¤ľ +åħ¶ä¸Ń ä¸Ģ个 +Ġv oor +æ±ī åŃIJ +{{ { +im an +ï¼Į æĿ¥èĩª +çļĦ æĸĩ竳 +Ext ended +èᝠæĿIJ +è·Į å¹ħ +æĴŃ ç§į +() { +ĠTam il +å¹³ æķ´ +vol ume +T asks +s ervices +ri ad +代 è¨Ģ +ãĢģ åIJİ +Ġlim b +å¹¿æ³Ľ çļĦ +åĩ» æĿĢ +æĦŁåıĹ åΰäºĨ +Ġp ave +æ²³ éģĵ +ä¹Ļ æĸ¹ +ympt oms +ç¥Ń ç¥Ģ +t ex +Ġfresh man +Mut ex +d g +éĴ ³ +Ġinterrupt ed +ad j +ort al +cor rect +Ġshock ing +Ġ 举 +_IN PUT +ag ging +å¢ © +ï¼Į å§ĭç»Ī +Ġjud ged +ĠL ak +çľĭ 她 +Ġignor ance +_E QUAL +ĠN atal +Fil ters +Ġover t +èĦ ĵ +åijĺå·¥ çļĦ +amp us +) }, +.e ach +\in cludegraphics +lu ent +. With +Ġgentle man +çĩĥ æ²¹ +å°Ħ æīĭ +ĠMan age +ĠI MP +ä¹Ł è¶ĬæĿ¥è¶Ĭ +便 ç§ĺ +Ġaff irmed +ĠH ait +âĨ ij +é¢Ħ 订 +.d rop +Ġman eu +èµ° åΰäºĨ +hav iour +ĠD art +èĵĿ èī²çļĦ +Ġg n +ä¹IJ æĦı +ĠCh an +åģļ æ¢¦ +ob il +ĠPow ell +è¤ ª +ĠB oo +rec iation +çļĦæ°Ķ æ°Ľ +(d f +* ]{} +å¯Ĥ éĿĻ +ä»ĸ ä¼ļ +Ġs es +çĭ Ī +/ o +æ§ IJ +Ġbo iling +èıĬ èĬ± +Ġv om +æ·± æ¸Ĭ +trans late +èī² ç´ł +Ġtort ure +Ġ **** +ĠS ox +lo x +ï¼Įä¸į éľĢè¦ģ +ĠS ullivan +-c ase +ĠApp oint +ï¼Į åħ³éĶ® +un gs +_ADD RESS +Ġland lord +Ġv ibe +èįī èİĵ +Ġre open +èģļ æ°¨ +å¼Ģ æľĹ +t ensor +{ W +in se +Ġcommit tees +Ġprosper ity +ãģķ ãĤĮ +å¿Ļ çĿĢ +ĠReyn olds +an ity +ĠN om +åľ° å½¢ +è¹ Ļ +Ġpat ents +ou x +ierarch y +ĠF ees +Ex amples +âĢľ 天 +ĠF ishing +æĻĵ å¾Ĺ +ä¸įä¼ļ åĨį +äºĨä¸Ģ æĬĬ +表åĨ³ æĿĥ +_m ean +Ġn r +Ġte e +Ġsovere ign +col s +Ġdis asters +AD A +Ġhost ile +Ġcost umes +Ġbe ams +Ġcomprom ised +v b +ĠC ult +ãĢģ 交éĢļ +Ġtransfer ring +ï¼ĮåĬł å¿« +( default +- us +Ġan omal +åζå¤ĩ æĸ¹æ³ķ +Ġdestroy ing +æīĢ示 çļĦ +Ġw itch +or ah +æĸ¹åIJij çļĦ +\ mu +çŁ ¶ +ĠN amed +ï¼Į æĺ¾å¾Ĺ +_G ROUP +rais al +æĢ» æķ°çļĦ +建 äºİ +View er +åĿļ åĽº +ĠR angers +åIJ¬ åIJ¬ +身 åīį +åľĪ åŃIJ +Through out +T okens +ĠLegisl ature +Ġp u +al ks +ĠIdent ify +管çIJĨ å±Ĥ +Ġvacc inated +çīĮ åŃIJ +èİ º +ĠCont est +check box +ĠF ake +ov ic +Ġcomm issions +Ġorb ital +ï¼Į ç§° +.A uto +Ġh one +Ġpal ace +.j ar +Ġad ip +enumer ate +ĠL ives +Ġobs essed +- client +F ALSE +Ġtest ify +Ġp ok +åı¯ è§Ĩ +Pr imitive +_p ush +åŁºéĩij çļĦ +ĠTown ship +-c or +æĮĩ çͲ +è¸ ¹ +h aw +éĥ½ å°Ĩ +åħĭ éĩĮæĸ¯ +å®ĩ æĸĩ +ĠUt ility +Ġ åĩĮ +(m ethod +M otion +çļĦ åĬŀæ³ķ +Ġmil estone +on omic +éģĹ æ¼ı +Ġmean ings +ĠR EM +ĠLoc ated +ĠRec ruitment +æĢª åħ½ +Ġp ots +Ġbarg ain +ĠD ynamics +med iately +ï¼Į åĿIJåľ¨ +ĠCh arter +Ġworks heet +_DIS ABLE +ĠBrad y +åĵİ åijĢ +\ * +ĠSal v +ï¼Ł 为ä»Ģä¹Ī +è¦ģ å¤ļ +ĠN y +Ġdrive way +æŃ¦ æľ¯ +ĠFil ip +è¿ĻäºĽ éĹ®é¢ĺ +sp Net +æĪĺ èΰ +Ù IJ +ãĢĤ æĥ³ +Ġw er +Ġdep recated +Ġban ana +åĭ¤ å¥ĭ +ï¼Į å¦Īå¦Ī +Ġsh ipment +ID I +_ rt +Ġres ent +Ġappell ate +Ġpr incess +çªĹ å¸ĺ +è¿ŀ æĿĨ +Ġco res +æ¤ Ń +m ble +ĠA IDS +_a uth +od ic +人æ°ij æ£Ģå¯ŁéĻ¢ +ĠCreat or +Ġo wing +ĠT EXT +аР´ +ĠFlow ers +è²Į ä¼¼ +Ġa per +Ġn ause +éļIJ 约 +侦 æŁ¥ +ĠBr ands +st own +ĠS ync +usp end +, å¿ĥ +ĠCl os +Ġantib iotic +Ġdeal ership +æľĭåıĭ çļĦ +ĠW are +so lete +Ġu id +ĠP orter +Ġdist ract +Ø Ń +çĸ¯ äºĨ +ĠE y +Ġt ournaments +èµ· ä¹ī +ï¼Įä»ĸ 说 +æ¥ ŀ +ri z +ĠFac ility +Ġprocure ment +.n n +, æĮīçħ§ +ĠSpe aking +_m etadata +Ġabb rev +é¤IJ é¦Ĩ +Ġlif es +ĠCh ang +NotFound Exception +ĠHe ating +-p ack +Ġnight mare +face book +ï¼Į åıijå±ķ +H ours +åĪĨ ä¹ĭä¸Ģ +_d ataset +éĥ¨ åĴĮ +ä¸į æĩĪ +æľĹ æĻ® +.s ystem +Ġhuman itarian +custom er +al ty +åĩĨç¡® çļĦ +çİ ¥ +Ġ/ > ", +Ġsuspect s +ï¼Ł æĺ¯ +å®ŀ è®Ń +Ġint estinal +uclide an +ï¼ĮçŃī åΰ +太 大çļĦ +x l +ĠG W +ï¼Į æ¯Ķè¾ĥ +ob acter +æĢĿ 绪 +ĠZ ach +è¯ķ é¢ĺ +ĠColomb ia +, ç»ıè¿ĩ +âĢ Ĭ +Ġref lex +Ġmar itime +Ġcomp ose +SEQU ENTIAL +wic hes +å¼Ģåı£ éģĵ +er ate +iv ot +ä¸Ĭ éĻIJ +Ġkid n +å¼Ĥ æĢ§ +ĠH ang +mid t +ar cer +çļĦ åĦ¿åŃIJ +Ġmurd ered +è¨Ģ æĥħ +Ġfellow ship +èģĶåIJĪ ä¼ļ +ãĢģ çα +æłij çļĦ +ãĢĤ éĢļ常 +大 åıĶ +_N ODE +P ressed +iche ver +å¬ ī +ĠN GO +ç½ij æĺĵ +ãĢĤ 使ç͍ +计åĪĴ çļĦ +ĠR TC +ĠCons ervative +Ġelev ator +ä¸ĭ è¡Į +T exas +b ee +è¿Ļä¹Ī å¤ļå¹´ +Ġcan s +ĠSc roll +cal c +å̼å¾Ĺä¸ĢæıIJ çļĦæĺ¯ +r untime +æ±ī åŃĹ +. RE +Ġread able +é»ij çϽ +Ġcond o +ï¼Įè¿Ļ æĹ¶åĢĻ +ãĢģ åĽ½ +æĬ± ä½ı +Ġsle pt +o qu +çļĦ åı¯èĥ½ +ä¹Ł ç®Ĺæĺ¯ +ãĢĤ æ°´ +_c ounter +Ġtrib al +Ġcontrad iction +Ġfundament als +管çIJĨ éĥ¨éŨ +宣 讲 +åĵŃ æ³£ +æĹ¶ è¦ģ +éģĵè·¯ ä¸Ĭ +å¹ Ĥ +K evin +è¿Ļä¹Ī 大çļĦ +R outer +ï¼Ł åľ¨ +Ġ 说å®Į +åĵ © +Ġl ace +ĠPain ting +z u +ãĢģ æľ¨ +ĠL IB +cl osing +cur r +çݲ çıij +çľģ 份 +湿 润 +ĠMS G +æ°Ķ åij³ +ĠRom ney +è¿Ļ å¥Ĺ +å¢ŀ è¿Ľ +åŁİ éŨ +Ġdefin itive +Ïģ ι +建设 åĴĮ +è¿Ŀ èĥĮ +{ l +' ): +æľī 好 +ĠFeature d +Ġrec ursive +-h ost +åļ£ å¼ł +AT ER +éĺ´ æ²ī +os cope +äºĮ çŃīå¥ĸ +çīĩ åĮº +_d omain +G V +æ¦ľ æł· +åºĹ éĿ¢ +Ġm artial +Ġyog urt +Ġbad ge +. the +Ġrational e +if ty +Ġamb ition +c url +èµ· éĩį +å°ĸ éĶIJ +å°± è·Ł +é¦ĸ 页 +Ġexc av +ãĢĤ æīĢæľī +ï¼Įåı¯ä»¥ 说 +G round +Ġchrom osome +æ°¨åŁº éħ¸ +Ġspl ash +_FL AGS +åŁĥ å°Ķ +èį Ķ +åĺ² ç¬ij +Connect ing +ĠFac ilities +èĢĮ 被 +æł¼ éĩĮ +st ead +Ġtour ing +æij¸ çĿĢ +âĢľ äºĶ +Ġno isy +% ( +Ġl n +éĽ ı +微微 ä¸Ģ +ï¼Įä¸Ģ èĤ¡ +imm une +çĸ ¡ +ĠK ap +æĥ ® +cons umer +åģļ çļĦäºĭæĥħ +und ed +ĠM LS +æĶ¯ éĺŁ +ä¼ĹæīĢåij¨ çŁ¥ +] ", +ï¼Į åĩŃ +æĸĩåĮĸ éģĹ产 +Ġballo on +_d river +N ut +Ġ rip +Ġdiv or +Ġreflect ive +æĹł è¾ľ +åľ° 对 +at ra +æĥĬ èī³ +ĠValid ate +å¹´ èµ· +主 æķĻ +ï¼Į 空 +Ch annels +åı¯ æ¯Ķ +ĠV ue +ï¼Ī ä»Ĭ +SE rror +çĭ¼ çĭĪ +Ġtra ction +ä¸įæĺ¯ 说 +çļĦ èĦ¸èī² +ĠN ine +æĪij æīĢ +g ars +å±± åºĦ +ä¸ĸ 人 +ĠJul ian +ï¼Į æ°¸è¿ľ +ï¼Į åĺ´è§Ĵ +éĻĦåĽ¾ 说æĺİ +çĥ ĥ +çļĦ èīºæľ¯ +åı³ è¾¹ +. âĢĶ +è¿Ľ éŨ +ãĢĤ ä¹Łå°±æĺ¯è¯´ +ä¸ļ æľīéĻIJåħ¬åı¸ +åķĨ è´¸ +Ġswe pt +è£Ļ åŃIJ +Ġpredict able +ange red +Ġrain fall +T s +墨西 åĵ¥ +bul let +c ot +çľģ å¸Ĥ +Ġattract ing +ĠSet t +: @ +-l ight +Ġ| \ +ĠSl ots +Ġemp loys +ï¼Į 伸æīĭ +ur as +Ġl ys +t ax +-p res +Ġo var +Ġins ist +æį® 说 +ç»Ĩ åĪĨ +ï¼Į éĹ®éģĵ +Ġun rest +ĠAt hens +Ġinformation al +åīįåĪĹ èħº +ĠAware ness +ä¸ĵ å¿ĥ +Ġallow ance +çļĦ ä¿ĿæĬ¤ +ĠLO SS +E ver +æľĢ åĸľæ¬¢ +_c lear +妥 åįı +g ru +Cook ies +_ AND +_ socket +à ° +Ġindex ed +D to +Ġins urer +èģļæ°¨ éħ¯ +ï¼ĮæīĢ以 ä»ĸ +om mod +çϾ è´§ +仿 羣 +ĠT rou +éĻª çĿĢ +osc opic +_F ILTER +æı¡ çĿĢ +ĠEdd ie +Quant ity +ĠI SS +ign al +ï¼Į ä¾Ŀ +èĩ³ æŃ¤ +end icular +æ»ļ æ»ļ +åĽºå®ļ æĿ¿ +åĮΠ奴 +act ing +d B +å·¥ 夫 +Ġ éĥij +åĩł åĪĨéĴŁ +LIN ENO +Ġdoub les +g ages +åIJį 声 +apt op +st ill +Ġmod ulation +åĮĸ ä½ľ +åĬ¡ å·¥ +ĠSign ature +ç ¶ +Ġnons ense +äºĨ æĪij们 +éĢł ä»· +é¥ µ +Ġsh out +æĥĬ æħĮ +ĠR ey +UT ION +Ġecosystem s +Ġc in +ĠLess ons +åĮķ é¦ĸ +Ġkick ing +Ġoxid ative +H istor +ĠÏĦ ο +å¡ŀ ç½Ĺ +计 æĹ¶ +ĠB und +ä¸įåģľ çļĦ +ç«ĭ çļĦ +å®Ī åį« +hel f +ĠR ide +_the me +ĠE as +头 æĿ¡ +èģĶç³» æĸ¹å¼ı +names e +in cludegraphics +ĠÎ ĵ +çĶ¨äºº åįķä½į +: get +Ġdetect ive +æī¿ 天 +и Ñĩ +Ġstud ios +稳 æŃ¥ +æĪĺ åĽ½ +ĠST ART +Ġpart nered +}} }} +Ġbl oss +ä¾ ® +Ġaver aging +Ġb izarre +ress es +ĠBlog s +( label +Ġpoll ut +Ġch asing +ï¼Į æĬķèµĦ +en i +) -- +åķĨä¸ļ éĵ¶è¡Į +åįĬ å¾Ħ +Ġkn it +ãĢĤ åħĪ +Ġhel m +.get Logger +åij¨ 转 +.S elect +çł´ è£Ĥ +ĠMod ified +ĠS ys +_set up +FRING EMENT +æ± ² +æ¸ħæ¥ļ åľ° +Ġske pt +B ur +is ers +, % +åĨ² çĿĢ +un less +O A +ber ger +reg s +Ġimag in +ĠPO SS +ry stal +ãģ Ľ +ç»ı çͱ +Ġwall paper +Ġregul ating +Ġcomp ost +åĽºå®ļ çļĦ +( ä¸Ģ +Ġinf erred +åĸ µ +äºļ马 éĢĬ +Ġexport ed +_f ind +о ÑģÑĤ +ï¼Įä¸į管 æĺ¯ +åħ¶ æīĢ +_ OS +èĩª åѦ +õ es +Cl one +ĠC ere +èĽ Ĭ +åıĪ è¯´ +_b ound +è´´ åIJĪ +çģ« çĥ§ +ï¼Į èĭ±åĽ½ +ĠHe ather +Ġlog arith +äºī 论 +u uid +Ġterror ists +_in ternal +ä»ĩ æģ¨ +ig her +åı£ åı· +å°ı 人 +å®ģ å¤ı +è§£æĶ¾ åĨĽ +ich i +( Int +met ry +M om +ç¦ģ å¿Į +çļĦ ç͵影 +åıª ä¸įè¿ĩ +Ġblack jack +. Query +Ġmembr anes +Ġtang ent +) ä¸Ń +Ġfair ness +ra il +åĬłçĽŁ åķĨ +çļĦä¸Ģ èά +åī ¿ +åıĹ å®³ +Ear lier +顺 便 +Ġvegg ies +èĢĮ è¡Į +Ġcompet ence +çļĦ åıįåºĶ +ï¼ ĸ +åĩłä¹İ æĺ¯ +ä¸ī æĺ¯ +un ches +ç¨ £ +Char les +ï¼Į éĢī +ank ed +åħĭ èݱ +åī¯ æĢ»ç»ıçIJĨ +ĠThe m +he ter +åıĺ é¢ij +Ġf ox +H ence +ĠS G +ĠAl fred +Ġwild erness +. åľ¨ +ĠA J +ĠCook ing +Ġtrou bled +IC O +ï¼Įæĺ¯ æĮĩ +çļĦ 马 +çĽ İ +çijŀ åħ¸ +ï¼ĮæĹł éľĢ +ãĢĤ å¦ĤæŃ¤ +Ġg rit +-M an +Ġdefect ive +Ġin active +对 çļĦ +äºĨä¸Ģ åľĪ +Ġinf rared +Part ition +ä¼ļ ç»Ļ +ï¼Įä¸Ģ è·¯ +Ġtraff icking +ĠFellow ship +el ian +æĿ¯ åŃIJ +: d +åĸĿ æ°´ +åı¯ åĪĨ为 +Ġr im +车 åİ¢ +æī§ 导 +ĠJ OIN +-t wo +ope z +ĠÎ © +ĠD EL +ĠEr n +Ġ% % +ç´§ åĩij +ãĢģ çĽijäºĭ +Ġfraud ulent +Ġdilig ence +: ) +西 éŨ +æī¾ æĪij +ĠGo als +è¯ķ åīĤ +ï¼Įä¸į æĥ³ +ĠS hen +åıij åĬĽ +Ver b +.s lice +Ġg amb +åıij æİĺ +转 è¿ĩ身 +Ġl hs +ĠC and +ox id +ĠC ock +in ish +oper ations +_d oc +ä¸Ģ å¿ĥ +ĠS essions +Ġinstinct s +ab lo +Ġsy ll +Com pl +ä¼ģä¸ļ åĴĮ +ĠS yl +çļĦ è¯Ńæ°Ķ +æ¯Ĵ ç´ł +æĬĬ ä»ĸ们 +Sm ith +h ydro +Ġcountry side +ãĢĤ çī¹åĪ«æĺ¯ +IF ICATION +è¿İ æĿ¥äºĨ +Ġ ä¼Ĺ人 +Ġμ g +p resent +å°ı åĦ¿ +ãĤ ı +, 缴æİ¥ +Ġcelebr ates +çε 士 +Abs olute +ar ct +Ġcommand er +b ands +Ġn inth +ĠWat ers +Ġb ir +_c ookie +Ġ č +f re +Ġsub sets +åł ° +ill in +Ġexp ands +_ edge +æķı æį· +ract ive +Ġserv ants +Ġtodd ler +Ġc ath +Ġannot ations +er View +æīĢæľī æĿĥ +en ne +æIJľ éĽĨ +夺 åĨł +代表 çļĦ +åħĥç´ł çļĦ +ĠNic ole +ãĢģ éĵģ +ï¼Į å¿įä¸įä½ı +Has Column +ä¸İ ä¸ŃåĽ½ +-t reated +åĺ² è®½ +模åŀĭ çļĦ +/ day +al gorithm +th ose +ĠRes idential +Ġtransl ates +æ¤ ° +åѦçĶŁ åľ¨ +Ġout lines +æ¯Ķè¾ĥ 大 +Ġforb idden +b ars +ĠArt ists +é² ¤ +ĠV II +Ġspokes person +S ex +å¤ĸ åĽ´ +ĠAr senal +é»ĺ å¥ij +ĠSpot ify +Act ually +G it +ï¼Į åŃĹ +block s +æĵ¦ æĭŃ +_f req +åĮ» åĬ¡ +Ġcere mon +Ġsimult aneous +æľī æĹł +饺 åŃIJ +ce il +ç¾ ģ +å¤į ä½į +ĠChap el +ĠGabri el +ĠOR DER +Ġbul b +èĵĿ çīĻ +Ġm ang +Ġ å¿ĥ +èİ· åĪ© +ï¼Į çİ°åľº +åıĪ ç§° +Ġnews letters +acer b +ог о +ĠâĢ ŀ +ra ps +失 æķĪ +æķĮ 人çļĦ +诱 åıij +åĪĨ è¡Į +H V +ç¥Ī 祷 +ï¼Į è°¢ +L es +å¸Ĥ å̼ +.A ction +éĢĨ 转 +se ek +_S OURCE +è¡£ æŁľ +Ġaccum ulate +Ġno qa +导 çĥŃ +Or g +Ġbl ot +E lem +天 ä¸Ĭ +( player +åľ° å¤Ħ +Ġboard ing +w i +Ġfest ive +Ġdisc ern +è§ ij +_ rect +ĠS or +Ġsm ells +K A +Ġpsych iatric +ĠCON SEQUENTIAL +ĠPal mer +大 åħ¨ +çͲçĬ¶ èħº +åĿļ ä¿¡ +Ġterm inology +ä¹Łä¸į è¦ģ +æ³¥ åľŁ +bin om +N i +Ġenc aps +åĨ» ç»ĵ +èĶ ij +è¾ĵåħ¥ 端 +oc ado +Ġit iner +config ure +che l +Ġhom etown +ĠM Hz +âĢľ æĸ° +æµ· çļĦ +ĠEld er +_C S +ï¼ĮéĤ£ ç§į +Ġapolog ize +ï¼Ł æĢİä¹Ī +ĠAff iliate +æĬĬ è¿ĻäºĽ +== ' +) ï¼ļ +ref s +æ± ķ +olid ay +Ġprep ares +ï¼Į çĽĸ +Ġpil ots +åζ æŃ¢ +ac os +对 ä¸ŃåĽ½ +åĶ ¾ +ĠS uff +( class +Ġadd itive +ĠAr rays +B bb +G Hz +Ġweigh ing +ch lor +ĠR ud +St reet +ĠK re +åŃĺåľ¨ äºİ +ĠD ale +vel t +Ġresid ency +ĠSh ield +åįİ ä¸½ +ĠExt ended +åĸĩ åıŃ +ï¼Į æĤ£èĢħ +ĠL iz +ä»Ģä¹Ī 好 +é¦ĸ 个 +åIJĽ 主 +U IT +Ġinit iation +_f u +åĴ¬ çĿĢ +-p ath +Ġ( $\ +éĿ¢ è²Į +ä¹ĭ åĪĿ +ĠH I +Ġdisadvant ages +_DE P +ä¸Ń å¤ĸ +Ġsc i +å¾ģ æ±Ĥ +åįł åľ°éĿ¢ç§¯ +为 ä¸Ģ个 +éĢļ äºĨ +Ġdischarg ed +P reference +ĠDecl aration +ãĢĤ åĶIJ +ch ard +éķ¿æľŁ èĤ¡æĿĥæĬķèµĦ +Ġd ub +Ġphen otype +ä¹Łæĺ¯ éĿŀ常 +åĪĽéĢł æĢ§ +è¯ļ å®ŀ +ĠM g +Un ity +dir name +red uc +éģ¥ æİ§ +che mas +Ġi Pod +ft p +ĠDem and +åĽ¾ 纸 +éĥ½ è§īå¾Ĺ +ĠTrans formation +æ¡Į åŃIJä¸Ĭ +ĠDE AL +and um +ä¸Ģ åĩ» +ĠComp ensation +Ġmotiv ate +Ġdr astically +Ġcater ing +书 éĻ¢ +Ġorgan ism +al is +ĠF riendly +аÑĤ ÑĮ +R ing +æģ¯ çļĦ +Ġsw allow +ĠW ool +è§ģ è§£ +Ġfraction al +all a +( old +Ġsummar ize +ä¸į å¿į +åħ¬ åŃĻ +ous el +ï¼Į ä¿Ŀéļľ +ĠS eller +St rong +å¾Ģ äºĭ +çݯ æ¯Ķ +çŃĶåºĶ äºĨ +L if +Ġstack ed +为 她 +ï¼Į 交 +Ġcompassion ate +åĭĩ äºİ +log ic +decl are +d ating +ĠP f +ie v +Ġscal p +æĺ¯ä»Ģä¹Ī æĦıæĢĿ +cal cul +å¾Ī æĺİæĺ¾ +ĠAppe al +æī§ æĶ¿ +æŁı æŀĹ +im ed +åĩł åįĥ +ï¼Į çĤ¹ +ãĢĤ å®ĥçļĦ +æĮ Ł +Ġsal on +ĠAUTH OR +åħ¬ éĩĮçļĦ +Ġpig s +éĺ³ åİ¿ +æłij æŀĿ +ĠAct s +ĠL ore +ï¼Į 举 +ill on +çļĦ åºķ +Ġ[ _ +ë ¥ +Ġ" +Ġ} ; +(' % +em u +è·¯ è¿ĩ +ãĢĤ è¿ijå¹´æĿ¥ +Ġtow ers +ãĢĤ éĤ£äºĽ +Ġli abilities +çļĦ åºķéĥ¨ +Ġstoryt eller +ĠTrans lation +ĠIs n +æİĢ èµ· +Ġepit helial +ï¼Įæ¯ı ä¸Ģ个 +ç¿» 转 +ĠMechan ical +M OD +对 éĿ¢çļĦ +Let ter +è¯ « +è¾¾ æłĩ +Ġcareg ivers +è¯Ħ å®ļ +/ share +ï¼Į æ²¹ +ãĢģ æĪĸ +ĠH ide +ï¼Įå¦Ĥæŀľ æĺ¯ +ï¼Į äºļ +ï¼ļ åħĥ +Ġcycl ic +ĠC ay +åĺĢ åĴķ +im ilar +æīĭ ä¸ĬçļĦ +mod al += a +ĠX X +è¯ķ åį· +D og +ĠPo etry +Ġref res +Ġs orrow +ĠCost s +bo at +ĠIn cluded +ĠC rit +Def ined +è¶ ¾ +æİ§åζ åľ¨ +æīį 对 +Ġsw ear +ĠT ail +or um +Ġst ared +th ank +å®Įæķ´ æĢ§ +ĠSac ramento +ĠTh ous +Ġdiss ent +æľª æĽ¾ +ĠIndian apolis +IP P +Ġcollect s +Ġub iquit +Ġgo at +.g raph +æ°Ķ è¡Ģ +ï¼Įæĺİ æĺİ +ĠP ets +ä¸ IJ +Ġha ul +è·¯ 人 +Ġb ilateral +å² IJ +模 ç³Ĭ +amb a +> ] +çļĦ ç¨ĭ度 +ĠD od +Ġen riched +ĠEar l +_con v +D AY +uss y +çļĦä¸Ģ æł· +ï¼Į èĦļ +le ad +ĠAc id +Ġupgrad ing +åĪij æ³ķ +IDENT AL +说æĺİ çļĦæĺ¯ +GL IGENCE +Ġmagn esium +æ½ĩ æ´Ĵ +Ġbreast s +FO RE +G ames +ve ctors +_ util +åħļåijĺ å¹²éĥ¨ +ãĢģ è´¨éĩı +ï¼ī ãĢĭ +Im agine +çľĭ éĩį +Ġair plane +T our +å¼Ģ çĽĺ +ç»Ń èĪª +å¸Ĥ 级 +èĩªå·± ä¹Ł +Ġund es +ĠGriff in +Ġkn ot +ä¼ł éĹ» += m +éĵº 设 +æł¹æį® æīĢè¿° +ä¸į对 åĬ² +im eters +.n umber +Ġbom bs +_N AMES +åѦä¼ļ äºĨ +åĵį äºĨ +çļĦ ç͵ +ĠA LS +ä¸İ æĪij们 +åijĬè¯ī 她 +F an +ĠM olecular +ĠTem perature +pack et +D OWN +å¼Ģ å¿ĥçļĦ +è®® åijĺ +Ġpurs ued +ìĿ Ħ +ĠP ig +Ġd ella +w ig +Ġ' ( +çĹ ¹ +çļĦ åħ¨éĥ¨ +com a +é¢ģ åıij +ĠM int +Ġpsych iat +ç»Ī æŀģ +ĠAff ordable +ĠA CE +ĠE yes +\ def +.R ep +artifact Id +ĠK ol +Ġendors ed +ï¼Į éĺ² +Ch ars +ä¿¡æģ¯ åĴĮ +Ġa we +Ġrook ie +åĽŀ åįĩ +Ġrec urrent +p ick +è¯ ħ +/s he +ä¼ļ éĢłæĪIJ +ï¼Įä½ł åı¯ +B aby +Ġm ais +Ġac rylic +èĥ¶ åĽĬ +ĠMat ters +åħ¬ åħ¬ +ĠAw esome +åľ° ä¸ĬçļĦ +çļĦ åįķ +Col our +Ġaccomplish ments +Ġp enn +ãĢĤ åĽ¾ +As ia +ï¼Įä½Ĩæĺ¯ åį´ +äºĨè§£ æĽ´å¤ļ +Ġemb raced +** , +b ags +U CH +åĻ ľ +.get Class +ç²ī å°ĺ +Ġst akes +Ġra z +Ġз а +_s upport +Ġ åĮĹ +Ġu h +é¸ ½ +w right +_c or +Ġre name +R ew +建 å·¥ç¨ĭ +ĠA uth +å²Ľ 屿 +ed uc +åħĭ åζ +[ l +List ing +Ġfore front +Ġprotect ions +ĠSh aring +Ġ å±± +èĬ± å¼Ģ +Ġrelig ions +ink le +ä½£ åħµ +DE C +ĠS ocket +Ġfe ast +ĠS ister +Organ ization +çļĦ 羣 +ä¸Ĭ æĺ¯ +Ġz a +ĠÑģ ÑĤ +ĠP AGE +Ġdef erred +o ji +Rev ision +Ġandroid x +im ony +ãĢĤ æĹ¶ +温 室 +/d oc +ĠP ricing +è¿Ħ ä»Ĭ +è¿« ä¸įåıĬå¾ħ +æļĸ æ°Ķ +Ġpl asm +_ AV +Ġl ump +Ġdisadvant age +. iter +Ġestab lishes +å¾· å°Ķ +ĠH C +è¿ij ä¹İ +ç§ijåѦ çłĶç©¶ +ν ο +iz oph +qu id +S CR +éĺ¶ å±Ĥ +ãĢĤ è¿ĺ +ĠG az +å¥ĩæĢª çļĦ +_ch ild +ĠLu is +æģ¶ åĮĸ +åıij æĶ¹ +Ġ åį´ +Ġmodel ed +ì§ Ģ +ĠAppro aches +å°±ä¸į ç͍ +Loc ated +Ġcritic ized +ĠH ire +é£İ åij³ +æĶ¹ æĢ§ +/ log +åıĹ ä¼Ĺ +Track ing +- plus +t ion +ĠH ip +ĠBro ker +ĠPot ential +Ġw s +Saf ety +Ġ 次 +å°Ĩ 对 +c ookie +è¿Ļ åĩłä¸ª +纸 ä¸Ĭ +ä¸įå¾Ĺä¸į 说 +C os +ä¸Ń ä¹Ł +Ġendot helial +.Comp iler +Ġretriev al +éļı æīĭ +at im +() } +ĠQ R +Ġcomplex ities +ĠM ile +mer ged +ĠO mega +ĠCann abis +çα 人 +å°¼ å°Ķ +æĪª åĽ¾ +çļĦä¸Ģ 款 +_ex ception +ä¿Ŀ ä¿® +li o +el in +_f ail +Ġsour ced +F ONT +, æĮī +çŀĦ åĩĨ +æ¯ı ä¸Ģ个人 +èIJİ ç¼© +.s cale +El se +è¦ģ çľĭ +æģ ¬ +ĠV C +el o +ç£ º +人 æĥħ +f inder +Ġciv ilians +rec v +ier a +ĠStep hanie +Ġscreen ed +åĭĥ åĭĥ +IST S +eb ra +Ġpol ling +ĠFle et +ĠManufact urers +, åĪ« +åıĤ å±ķ +çļĦæĹ¶åĢĻ å°± +lt ry +G PS +Ġass ortment +çİ°åľ¨ å·²ç»ı +ç«Ļ å¼ı +Ġod or +Ġunpredict able +_trans form +Ġrust ic +å°ı 声 +åı¯ æł¹æį® +Ġmem oir +qu ired +] ï¼Į +ç»ĵ å°¾ +ĠM ong +ĠCar p +_st ates +St roke +ĠCl iff +Ġmar ital +çͰ åĽŃ +C u +Ġp ains +çļĦ è¿Ļ个 +ä½ķ å¿ħ +ĠD iss +pl ays +ĠAdd s +Ġwe ighed +ĠNE GLIGENCE +为 é¦ĸ +Ġrend erer +) }{\ +ï¼Įå°ı å¿ĥ +å®´ ä¼ļ +à¥ Ģ +St amp +Ġnav y +Ġcontract ed +Ġt bsp +ä¸Ģ æĹı +_ price +ãĢģ å®īè£ħ +çº ¶ +ç»Ļ æĤ¨ +Ġimp osing +æİĮ 声 +ĠJen kins +Ġfil tration +Ext ract +Ġr d +ĠSal ad +ï¼Į ç͵ +åľ¨ ä¸į +çİĩ çļĦ +ï¼Įè¦ģ ä¸įçĦ¶ +ĠInvest ig +Ġag gress +对 è§Ĩ +ĠOr chestra +Ġres olving +å¾ģ éĽĨ +Enter tainment +çŃĶæ¡Ī 为 +éķ¿ è¿ľ +æĵħ èĩª +ĠIndividual s +ä»ĸ ä¸į +è®° è´¦ +.S how +d agger +æĪ¿ éĩĮ +Ġlat ent +ä¸¥æł¼ æĮīçħ§ +ãĥ Ĩ +ä»· ä½į +çļ± çĿĢ +represent ed +ä¸ĩ ä½Ļ +Ġg er +-F ree +ĠH idden +Ġple asing +éĻ ĩ +èĢĮ çĶŁ +Ġp ag +éħ ī +Ġteam work +ã Ħ +çİ°åľ¨ æĺ¯ +å¸ĥ æĭī +ĠR ED +W F +ĠT ib +åģļ èµ· +Ġopp ose +åĪ¶åº¦ çļĦ +骨 æĬĺ +çļĦ æĤ£èĢħ +çķľ çī§ +Ġx xx +å°± è¶Ĭ +æŃĮ åͱ +Ġtweet ed +两 å®¶ +Ġunf amiliar +æĢ» åĨ³èµĽ +.F ont +ç´¢ æĢ§ +ĠMyst ery +Ġdis pose +稳 åĽº +p lease +ä¸ĢçĤ¹ åĦ¿ +_ import +çĻ ¸ +t om +Ġgen etics +ĠP ipe +Ġd op +æ° ĵ +ĠCheck s +注 è§Ĩ +f ake +Ġsat uration +" He +æ¶Ī æŀģ +ĠS elling +ãĢģ ä»İ +èĩª å¾ĭ +f eld +ä¸ĵ æłı +_reg ion +çļĦ å̼ +端 åįĪ +Ġeconom ically +交æĺĵ æĹ¥ +Ġcapital ism +Ġthe r +Ġcon ventions +æºĥ çĸ¡ +ç½ij çĤ¹ +Ġout ward +oot strap +_COMM AND +Ġcl iff +ä»į æľī +Ġ+ \ +Ø ´ +(g roup +ĠB oom +ĠB ecome +ĠAutom otive +åΰ ä½ł +åĽŀçŃĶ éģĵ +cos ity +éķ¿ éķ¿çļĦ +. Header +-b uilt +IGN ED +ãĢģ æĹ¥æľ¬ +mem bers +Ġ å¦Ĥä»Ĭ +å°±æĺ¯ 为äºĨ +ä½ı æīĢ +.d ocument +ĠTig ers +or ative +ĠCo pper +ra ins +å½ĵ éĢī +(f rame +Ġwh istle +Ġcont empt +Ġt ense +æ¯Ķ åĪ© +å¥Ĺ çŃĴ +ï¼Į èİ·åıĸ +,èĢĮ ä¸įæĺ¯ +Ġpenet ration +ä¸Ģ ä¸ĸ +åįł äºĨ +Ġsem inars +ç»´ æĸ¯ +åIJĪæł¼ çļĦ +_z ero +亲 æĥħ +Dis count +MA KE +ĠSh arp +ä½Ľ å±± +çļĦ ä½İ +好åĥı æĺ¯ +çļ± çº¹ +ĠSil icon +Ġreb oot +å°ij åĦ¿ +éļı 身 +Ġmed iated +æĢĴ æ°Ķ +à · +ĠO UR +éģ¥ è¿ľ +Ġ$ ("# +Ġover weight +D lg +ĠO live +ãĢĤæľ¬ 书 +Ġcup c +eg o +ĠP om +D ream +æĿ¡ 约 +åĴĮ å¼ł +æ²® 丧 +x B +Ġcontinu um +Ġplay list +讲 å¸Ī +Ġcraft ing +æĪ Į +arth y +q s +Ġadvert ised +ï¼Įå¹¶ éĿŀ +Ġdetail ing +ad al +ĠL iv +w arning +ab us +ç£ģ çĽĺ +ĠU Int +Ġenrich ment +Ġfool ish +Ġ å¤ľ +ï¼Į éķ¿æľŁ +ĠMathemat ical +çļĦ æĿĥåĪ© +ĠRef erences +IC H +ãĢģ æŀĹ +èįī æ¡Ī +è§£ å¼Ģ +Ġadvertis ers +Ġ ç¥ŀ +åį° åıij +æıIJ æ¡Ī +代çIJĨ 人 +_s ql +ĠRes ume +Ġg rac +强 åĬĽ +ĠW ife +æĢĴ åIJ¼ +Ġc ialis +Ġoccup y +_sh ared +Ġsp ans +ĠAss ignment +Develop ment +Ġcru c +ĠY ale +山西 çľģ +çĶµè·¯ æĿ¿ +Ġimper ial +, å¸Ĥåľº +Ġhe ck +æĶ¯ æŁ± +Ġcapac ities +M K +Ġr ude +æĭ¦ æĪª +Ġcar rots +. const +ç»´ äºļ +Ġrespect ful +æİ¢ éĻ© +ÃIJµ ÃIJ +ĠCor onavirus +Ġ è¿ŀ +_ container +ï¼Į è°ĥ +ĠD iana +.prot ocol +îĢ IJ +æł¼ æłħ +Cor rect +EN AME +Ġdesign ation +t ls +ch arts +ç®Ģ æĺĵ +ĠGib son +. er +Ġexam inations +大 æī¹ +Ġsy nd += int +Ġcur ated +, å·² +_th reshold +Ġ åıªè¦ģ +Mod ules +STR UCT +an mar +ï¼Įæľī äºĨ +Ġmy ocard +Ġdig estion +åı° é£İ +èµ· å§ĭ +ĠHOW EVER +crib ing +ä½ıæĪ¿ åħ¬ç§¯éĩij +ä¸Ģ åıĺ +Ġsix ty +ï¼Įè¿Ļ ä¸įæĺ¯ +ubb orn +ĠHung ary +ï¼Įè¿ĺ åĮħæĭ¬ +Ġdeliber ate +Ġw ives +Ġpur ity +n egative +Ġsk ipped +ç³»ç»Ł åĴĮ +ke es +奥 çī¹ +r uby +çļĦåľ° æŃ¥ +ĠChrist ine +ĠA ber +Ġjud gments +res olve +çļĦ çIJĨçͱ +T PL +at ography +Ġcommerc ially +çŃī å¤ļ个 +ç¾İ èģĶåĤ¨ +.S end +è§ģ 她 +éĵ¶è¡Į åį¡ +N K +Ġre ef +åħĥ æ°Ķ +Ġconsent ed +.pro perties +马åħĭæĢĿ 主ä¹ī +AN E +éĢĤåIJĪ èĩªå·±çļĦ +++ , +Ġprofessional ism +è° į +çļĦå¿ĥ æĢĿ +å¹¿æ³Ľ åºĶç͍äºİ +èĬĻ èĵī +it ating +ĠB omb +, 建议 +ä¸Ń ä¹ĭ +å¾® 软 +ĠINC IDENTAL +Ġ第 ä¹Ŀ +/ the +Ġcur se +red irect +ï¼ĮæĪĸèĢħ æĺ¯ +A WS +( ip +æĪIJ交 éĩı +Ġann ouncing +äºĨè§£ äºĨ +åĭŁéĽĨ 说æĺİ书 +h dr +ãĢĤ æĺİ +ï¼Į æĺİç¡® +第ä¸Ģ æŃ¥ +Ġjack pot +ç©¿ æ¢Ń +rim ination +Ġh urd +ark ers +ert ility +Ġdisc arded +Ġcond emn +L ee +il ic +i ott +Ġcustom ization +ĠE z +-p ost +ãĥ ĩ +high light +pres so +æľīéĻIJ çļĦ +æķ°æį® åĴĮ +ĠSupp lier +. inner +马 è·¯ +Ġprison er +ãĢģ æıIJé«ĺ +åģľ äºĨä¸ĭæĿ¥ +He at +åħļ åĴĮ +Ġimm igrant +åĽ¾ åĨĮ +ĠRec reation +ä¸Ģ个 æĸ°çļĦ +èĥ½ çľĭåΰ +èĩ³ ä¸Ĭ +As sets +ĠV ic +ĠV ern +Ġtreat y +ä¹Łä¸į éĶĻ +ens is +Ge o +trans port +说 æĿ¥ +C ash +Ġg p +Ġout per +(s ys +åľ° åİ» +s ocial +v ine +^ T +Ġ åĽ½å®¶ +Ġsm o +ĠAss ume +ĠSy ndrome +ĠC emetery +ï¼Į éħįåIJĪ +纳ç¨İ 人 +Ġciv ic +_t ool +ç² Ł +ç§ijæĬĢ å¤§åѦ +j ug +ri ke +иÑĤ е +Ġide als +TT PS +ĠUg anda +æĵ Ĥ +° F +in ement +ĠV as +De ath +ĠPop ulation +æĻ®éĢļ æĬĢæľ¯äººåijĺ +ĠCh anging +æĪij 认为 +Ġpro ton +ï¼Įè¿Ļ ä¸ĢçĤ¹ +ä¹Ŀ æľĪ +ï¼Į å¼ķ导 +ay ette +m iddle +åĽĽ éĿ¢ +ãĢĤä¸İ æŃ¤åIJĮæĹ¶ +åģľ çķĻåľ¨ +Ġm ont +am pton +å¤ļ åĬŁèĥ½ +è´´ è¿ij +容 è²Į +æŃ¦ èĢħ +éģĵ 人 +Ġexhib itions +åIJ¸ è¡Ģ +ph rase +åįĥä¸ĩ åĪ« +ĠS PD +ĠIn ventory +sl ash +ĠU FC +示 åĩº +F requency +Ġsc aff +Ġcondition er +Ġexch anged +ant ing +Ġsick ness +. % +RE AK +æİı åĩº +Indust ry +, æīĵ +åĩºå¸Ń ä¼ļè®® +çĹħ çĹĩ +æĶ¯ è¡Į +Log ging +çĨ¬ å¤ľ +ast a +Ġ çĶŁ +ch ure +ar shal +-D ay +Ġqu otation +Int el +被 æĪij +å³ ¨ +å®ī å¸Ĥ +æ·»åĬł åīĤ +æ±Ĥ åĬ© +åħį è´£ +åIJ¯ 示 +riv ia +IST R +Ġcaps ule +çŁ¥éģĵ æĪij +-n ight +ï¼Į ãĢĮ +èİ· èĥľ +Ġneck lace +æ¯Ķ çļĦ +itect ure +ĠR ams +çĦ Ļ +ĠF ailed +A uthors +Ġfav ored +_RE F +Ġh ottest +深深 åľ° +Text Field +è§īå¾Ĺ å¾Ī +ĠB D +c ia +ĠW oo +Ġmet ro +ä¿¡åı· çļĦ +ĠSimp son +: åľ¨ +D ave +ĠC AT +est e +ĠI Enumerable +æł¡ åıĭ +Ġbelong ed +åįİ å¾ĭ +um ers +ergus on +, 让æĪij +Ġ 项 +-con sum +ĠRock y +c ursor +çļĦ ä¹łæĥ¯ +æļ § +ĠAD VISED +Ġtox ins +) ', +. rest +DE LETE +ãĢĤ æ¯ı个 +å¤ ¯ +_TR ACE +n h +Con c +Dis patcher +ipl ier +ĠW L +éĩĮ åħĭ +-s upport +per ing +Ġattach ments +天 羣 +ãĤ Ħ +ĠMill enn +ï¼Įä¸Ģ åī¯ +ä¸ĢåĪĩ éĥ½ +/ user +aver n +ĠCou pon +ĠT ah +Ġpl otted +d uration +å¾® ç¬ijçĿĢ +æĴ¤ éĢĢ +redict ions +æ°Ķ å¾Ĺ +éĵ¶ å±ij +çĭ Ļ +sc ene +ĠNaz i +P repare +At Index +åĨ· åĵ¼ +ä¹ĭ äºİ +izoph ren +Ġj og +Ġc ervical +ï¼Į äºĭ +Ġadvis er +åIJĮ çŃī +Ġsecret ion +umb o +å·®ä¸į å¤ļäºĨ +ĠL unch +ä¸Ģ缴 没æľī +æĭ¥æľī çļĦ +天 èĬ± +ãĢĬ 大 +æ¯Ķè¾ĥ é«ĺ +ãĢĤ ä¸Ķ +Ġrevers al +ĠClar ke +ä¸Ģ éĹ´ +.b ottom +å°ģ éĶģ +Yes terday +Ġc sv +Type Name +åıĤ ä¿Ŀ +ä¸ĸ åŃIJ +Ġtrain ers +B all +_s uccess +æ³ ¸ +Ġen forced +ãĢĤ ä¸ĢäºĽ +æĢİ èĥ½ +ĠLog an +Ġtor rent +ç»ı纪 人 +ĠTo ast +Ġacknowled ges +æĹł åIJį +Ġcon ftest +éĩİ å¿ĥ +Ġborrow ing +åĪĩ æĸŃ +ĠAnn ie +Ġcar ved +Ġro ses +以为 æĺ¯ +S a +_in v +Ġstick ers +åĩ¸ èµ· +ä¹Ĵ ä¹ĵ +åŀ ¦ +Get ter +Ġ åIJij +Supp lementary +ĠAnn ounce +Ġb rit +Ġspec imen +è½° çĤ¸ +åįł åľ° +ï¼Ľ âĢľ +ol ith +éĻĨ åĨĽ +Ġproof s +å·¡ æŁ¥ +ĠCertain ly +æİ¨ éĶĢ +ĠTrans ition +ING LE +m anship +åı· ç§° +æŃ¦ æŀĹ +éĿĴ éĵľ +ï¼Į æıIJåĩº +Ġthr one +Ġa erial +ĠX ia +åģľ åľ¨ +Ġweigh s +ĠVert ical +伦 çIJĨ +ä¸ļ ä½Ļ +åº µ +Ġwra ps +ç§ģ åĭŁ +bi ased +Ġsur plus +gr ass +Ġ çͱ +ï¼Į åij¨åĽ´ +温 å·ŀ +Ġperp endicular +Dim ensions +Ġo mega +åĽºå®ļ å®īè£ħæľī +Ġtim eless +èĵ¬ åĭĥ +ion i +æ¹ ĥ +èĩªåĬ¨ 驾驶 +Ġ' [ +ĠE ff +Ġm igrants +Ġcomp elled +[ A +, è¿ĺè¦ģ +Ġbox ing +Ġpin ch +ell ites +ä¹Ł ä¼ļæľī +ĠIn k +éĻĮ çĶŁçļĦ +Ġpo res +® åIJĪ +ar bon +è¿· æĥij +< K +n ell +ç¥ ¯ +åī¯ éĻ¢éķ¿ +Ġbow ls +_ icon +_f d +åħ¨ å®¶ +ç»ıåħ¸ çļĦ +Ġallev iate +B er +çİ© å®¶çļĦ +稿 ä»¶ +๠ī +æľŁ æĿĥ +åĽŀ è·¯ +Ġd l +ä¹ĭ ä½ľ +ï¼Į ç®Ĺ +IR T +ĠT LS +_c ategory +psy ch +ustom ed +.m ean +Ġble w +Com posite +Ġscen ic +两 åı¥ +[] ( +éĢĴå»¶ æīĢå¾Ĺç¨İ +ĠD ocker +çħ ² +为ä¸Ģ ä½ĵçļĦ +æī« çłģ +åı¯æĮģç»Ń åıijå±ķ +ĠB uch +ãĥķ ãĤ +ĠW inn +-s ensitive +åıįæĺł äºĨ +ĠRe in +ï¼Įä¸ĩ ä¸Ģ +ĠE cho +Ġoccup ational +缸 亲 +ĠL ens +ĠWar riors +ĠC ort +åĴĮ æĸĩåĮĸ +ĠE igen +æĸ°èĥ½æºIJ 汽车 +uc ceed +åĴĮ æĶ¯æĮģ +ï¼Į åıĹåΰ +Ġde hyd +ï¼Į ç´« +Ġpart itions +转 åΰ +Ġf rench +ars ing +>> >> +ĠMar athon +Ġsett ling +Ġmean while +Ġm ould +æĹ¥æľ¬ 人 +ĠB ach +.A ll +G un +Ġf ist +Ġbreat htaking +} else +L uc +ï¼Į æĦı +Ġz oo +, 帮åĬ© +å¤ Ń +AC S +ĠHis panic +çѹ çłģ +ĠF ans +ÑĢ Ñĥ +ĠCan adians +ĠRed uce +M aker +æľ¦ èĥ§ +Ġde af +以ä¸ĭ æĺ¯ +Ġsex uality +ĠPOSS IBILITY +Ġimp ressions +ä¹ĭ æ³ķ +è¿Ļä¸Ģ 天 +Ġdynam ical +Ġa ster +Ġver te +isp here +çļĦ æĪIJåĬŁ +éĢļ ä¿Ĺ +Rect angle +Ġhe mat +ĠL il +Ġrein forced +OP S +, è¿Ļæł·çļĦ +ĠJ D +ĠTal ent +æĦŁæŁĵ èĢħ +ĠSc r +ĠRichard son +ĠCon clusion +æķij æĬ¤ +cl ub +æĭ¿ äºĨ +çļĦäºĭ çī© +çĸij ä¼¼ +çļĦ åĵģçīĮ +y ld +ĠDis closure +æī¹ 次 +åİ» åĮ»éĻ¢ +G ain +_s cript +Pos itive +-ph ase +çϽ è¡£ +ãĢģ åħī +大 å°ĨåĨĽ +ï¼Į èµ°åΰ +Ġcross es +Ġintric ate +è¾¾ å°Ķ +æľª å©ļ +çªģ åĩ» +æ»ij éĽª +ed ay +Ġn ão +å°ijæķ° æ°ijæĹı +Ġtempt ed +ĠManufact urer +çļĦ åĽłç´ł +Ġ* . +OL T +OD AY +Ġeven ings +éĢĴ ç»Ļ +ĠRodrig uez +Ġch alk +ua wei +Ġauthent icity +ĠP urch +cal endar +. Common +Ġst all +ãĢģ å¹² +ymph ony +çļĦ åIJ§ +-b ound +land er +-pro file +ric ed +ĠS ensor +Ġd ps +Ġacqu is +Ġmor ality +Ġtrust ing +ĠGu itar +ï¼Į A +æĺ¯ä¸Ģ 次 +åİ» è¿ĩ +ĠR UN +ï¼Į ç¥Ŀ +Ġha irst +Ġext inction +For Key +精彩 çļĦ +éĿ ³ +ĠR ig +çĥ¦ èºģ +Ġslow ing +Ġreluct ant +缸 è§ģ +æĹł è§Ĩ +Ġhigh s +Ġcharg er +ĠS quad +å¹´ åįİ +P ID +al an +av oid +Ġdist racted +ĠUn cle +, ä¸įä¼ļ +Ġasympt otic +c ertain +çļĦ ä¸Ńå¿ĥ +ĠÎ £ +å¾ Ļ +åģļ ä¸ĢäºĽ +ro cy +ancellation Token +.create Element +Ġcolon ies +Ġsl opes +ĠFl ags +Ġspan ning +æĪ Ł +, 缴åΰ +ãĢĤ èµµ +D ie +M ur +=- =- +f unctions +eg rees +ĠN it +ä¹Ł è·ŁçĿĢ +> č +Ġmy riad +ĠArm strong +ãĢģ ç¾İåĽ½ +å¸Ŀ åĽ½çļĦ +ĠAm ount +è° ı +ä¸ŃçļĦ ä¸Ģ个 +æ²³ æ°´ +V B +Ġchat ting +ĠChall enges +_RE SET +Up dates +è¿Ļä¹Ī å¿« +Ġdest iny +Ġn at +ĠD yn +èĤ Ľ +æł¼ æĭī +w ild +Ġfe ared +ĠSh ir +Att empt +-c ard +Ġnot ch +AM A +æĶ¾å¿ĥ åIJ§ +ÂĢ ÃIJ +ï¼Į 忽 +çģ« çĥŃ += [' +-c olumn +ag h +... , +æĢ» 线 +ask ell +ï¼Į å¹³åĿĩ +ĠR andy +å¼± åĬ¿ +åįĬ个 å°ıæĹ¶ +羣 é¢ĺ +ĠM oz +< R +j in +é¦ Ĵ +_a fter +ä½ Ł +av atar +ĠSol omon +å±± è°· +ĠM apping +çļĦæĬĢæľ¯ æĸ¹æ¡Ī +ï¼Į éĩĩåıĸ +-Co V +ant is +ĠFIX ME +_OP EN +Ġunderstand able +æİ¥ 纳 +çİ© 游æĪı +ĠTHE ORY +ip se +åľ°æĸ¹ æĶ¿åºľ +. Button +il ogy +AM D +le et +Ġlog os +Comb ine +.g raphics +表达 å¼ı +oose velt +Ġpost pon +é£İ éĩĩ +. End +Ġpl edge +( Integer +äºĮ 楼 +Ġthr illing +Ġirr igation +ĠCon figure +yy yy +ï¼Ľ å½ĵ +J ess +Ġpur se +çѹ èµĦ +_dec ode +ĠRon ald +D TO +ĠB eg +me al +ĠParad ise +ï¼Į åģĩå¦Ĥ +_ LOCK +ä¹Ł åıªæľī +æİĴ æĸ¥ +ä¹Łæĺ¯ å¾Ī +) ^{- +not ify +ĠApart ments +æİ¨ æµĭ +缸 çŃī +åİ» çľĭçľĭ +W allet +ĠG FP +æĮĩ çĤ¹ +_sign al +ess ential +.comm and +Go ing +ĠSTR ICT +Ġreb ell +ï¼Į她 å°± +è¿ĻäºĽ ä¸ľè¥¿ +Ġfet al +Ġd B +ĠP upp +çıł åŃIJ +Ġlon ge +r hs +çļĦ åĬŁæķĪ +Ġsql ite +tain s +_{ ( +- if +ä¸įåĨį æĺ¯ +Ġrain bow +æĶ¹ èī¯ +åĩº æĸĻ +ĠL ORD +骷 é«ħ +- an +ord ering +Back up +éĹ® çŃĶ +Ġinc arcer +é²ľ èī³ +Ġfrag rance +ãĢĤ æİ¥çĿĢ +ĠK ur +æļĹ èĩª +Ġgr ind +çĹĽ å¿« +Ġ${ {\ +Ġfemin ine +ĠD ear +Ġpur ified +an za +åĨħ æľī +å¼Ģ ä¼ļ +çĬ¶ çļĦ +Ġ Š+çĿ¡ çĿĢäºĨ +ï¼Į âĢĺ +ĠL ucky +Ġh d +ĠW C +车 éŨ +Ġs log +ä½Ľ ç½Ĺ +-h ow +- US +Ġanticip ation +Ġa is +Ġk ings +C ALL +Ġjud ging +Care er +ĠKle in +au f +erm on +ä¿Ŀ 湿 +è¿Ļ æĸ¹éĿ¢ +å¿ĥ æĦı +çķĻ ä¸ĭæĿ¥ +Ġco ats +Ġg ems +西 æ¹ĸ +ĠÑ į +q i +Ġ[ # +ĠP NG +ĠDet ection +Ġre ps +çϽçĻľé£İ æĤ£èĢħ +Ġle tt +çļĦ çİĭ +M otor +éĽĨ è£ħç®± +en berg +Ġtheir s +å¼± çĤ¹ +{c ases +ï¼Įçľĭ ä¸Ĭåİ» +Ġ& # +ï¼Įæľī ä»Ģä¹Ī +Ġt icks +ä¸ĭ åįĬå¹´ +çļĦç¾İ 好 +_ alpha +ãĥ ¡ +Ġdrag ged +Ġy ummy +Ġover looking +ĠUs es +ï¼Į è§£åĨ³ +带 ä½ł +ãĢĤ éħĴåºĹ +-de velop +Ġlat itude +ç¿ Ł +ct r +ãĢij ï¼ļ +ad just +Ġcalcul us +Ġf uzzy +^^ ^^ +g ue +Ġ 大家 +羸 åŃIJ +Right arrow +ĠStev ens +ĠM ega +ĠGOOD S +g old +è·Ł ä¸Ĭ +ï¼įï¼į ï¼įï¼į +Ġdis gu +-g rowing +ĠClick Funnels +åIJį çīĩ +Cl os +ç½ij绾 ä¸Ĭ +ĠDev il +ол ÑĮ +å°ı 麦 +åħļ ä¸Ń央 +Ġb ending +Ġsuper hero +ï¼Įå®ĥ æĺ¯ +ï¼ĮæĪij们 è¦ģ +ĠY ard +ĠOw en +Ġ åħĪ +ĠCele b +.f acebook +ĠGen eva +Redd it +æľī å¿ħè¦ģ +çŁ³ å®¶åºĦ +;;;; ;;;; +Ġ èĥ½ +è° ¬ +Ġseam lessly +") ). +pre ter +ĠOP EN +çļĦ åIJĮåѦ +Ġsepar ating +std lib +ĠSw an +Ġrest oring +(m odule +ãģĦ ãĤĭ +H or +Ġ è°¢ +宽 容 +åħ»èĢģ éĩij +Ġoff spring +Ad apt +èĬ ĭ +å« ¡ +ï¼Į è®°èĢħ +Ġs perm +ï¼Į èĤī +åľ¨ åŃ¦æł¡ +å¿ĥ 缮 +_s can +Ġst aple +_M AC +Ġunc overed +Ins urance +Id eas +ĠMon ica +èµĦæľ¬ 主ä¹ī +Ġfire arm +ĠPe pper +st ed +æľįåĬ¡ åijĺ +[ y +im icro +éĩį 大çļĦ +Inst ances +ĠFil ms +Ġpl aque +æ°´ ç͵ +Dist ribution +èĢĹ è´¹ +Ø ¬ +对 çŃĸ +ind ices +(l ambda +y on +Ġint e +æĺ¯ä¸Ģ æĿ¡ +æ¸ħåįİ å¤§åѦ +Dec ode +ĠMy ers +Ġind ie +Ġsne ak +.de ep +çŁ¿ ä¸ļ +轨éģĵ 交éĢļ +Ġint racellular +æł © +ãĢĤ å®ŀéĻħä¸Ĭ +Ġthreat en +ãĢģ åIJ´ +è¿Ļ ä»¶ +.res ize +Ġup stairs +ï¼Į æIJŀ +ĠR OS +Ġcapt iv +æĬļ åħ» +为 æľ¬å®ŀç͍æĸ°åŀĭ +M ah +( idx +ä¸Ĭ åįĥ +empor al +Ġrent ed +çłĶ 磨 +( Value +Ġref lections +ĠHit ler +ĠSk ype +_d elay +Ġadhere nce +éϤ åİ» +ç»ıèIJ¥ 管çIJĨ +Ġb amboo +ĠPart ies +_ " +å² ij +( at +ĠBit map +交 æĽ¿ +ĠS ense +\ @ +ĠML B +åĦ¿ åŃIJçļĦ +ĠR IGHT +Ġcircul ating +ĠB atch +åijµ æĬ¤ +) (( +ie ves +顺 çķħ +æĦļ èł¢ +Ġs igh +ig nty +ect in +(" { +Ġreimburse ment +Ġre actor +æĬ½ åĩº +çļĨ æĺ¯ +pl er +ï¼Įä»ĸ å·²ç»ı +Ġshoot er +èĸĦ çļĦ +Ġg odd +Ġpit cher +Ġm ug +ĠAlex a +Ġtrans verse +Ġtrust ee +ãĢĤ æīĢè°ĵ +åħŃ æľĪ +_ ; +大 å¸Ŀ +ĠM unicipal +Ġconflic ting +Ġ ç͍æĪ· +éľ ¾ +çķª è¯Ŀ +ĠE clipse +A st +Ġfin ely +Ġche at +èĪħ èĪħ +( col +åħ·ä½ĵ æĥħåĨµ +ĠO EM +Ġ= ~ +par allel +ãĢĤå¦Ĥæŀľ æĤ¨ +çªģ åĩºçļĦ +å°Ķ å¤ļ +äºĨ ä¸ĬæĿ¥ +ip y +_DE CL +Feed back +æīĢ åѦ +ä¸ī çĤ¹ +åݨ å¸Ī +rog ate +æľĢ å¿« +ãĢģ çĶŁçī© +ä¼ł åħ¥ +F oo +Ġy ang +ĠPast or +æľĪä¸Ń æĹ¬ +, ä¸įçŁ¥éģĵ +ag greg +Ġres orts +ig ated +( as +转 åŃIJ +ç¥ŀ åύ +ure n +ï¼Į æķĪæŀľ +ï¼Į ä¸ĵä¸ļ +ĠT uple +Ġconfront ed +Ġplay back +ĠINTER RUP +Ġdecl arations +_g roups +Prof essor +å¾ Ĭ +å½±åĵį äºĨ +åĽł æŀľ +Ġover coming +à ī +Ġcatalog ue +ï¼ Ĺ +åı © +Ġremark ably +ä¸į çIJĨ +ç»į åħ´ +轻轻 åľ° +åѦ æĬ¥ +ĠC ensus +è¿ĺæĺ¯ ä¼ļ +Ġpop up +Ġprecaut ions +Ġw ifi +æĬ¬ æīĭ +ut z +çĴ Ģ +æ¯į亲 çļĦ +ĠSustain ability +in h ++ p +éĤ£ æĿ¡ +@ b +Ġsp ider +Ġnucle i +大 大çļĦ +Ġgall ons +ĠPack et +ç¥ŀ éĢļ +ass es +Ġinflu enza +ant on +ig its +ä»ĸ å·²ç»ı +ĠL ite +, é¦ĸåħĪ +se gment +ole cules +Play ing +)) * +ĠCor inth +(cl s +\new command +çݰ 身 +aw i +ĠBet ty +éĹª éĹª +çļĦ ä¸įæĺ¯ +ĠLad ies +_cl k +æĿ¡ å½¢ +âĢĶâĢĶ âĢľ +ĠNew castle +Ġ[ : +Ġneighb ours +ï¼ĮæĪij们 å°± +Ġо б +天 çİĭ +App s +ĠB uzz +.m eta +å®ŀéĻħ è¡ĮåĬ¨ +ĠBet ting +, æİ¨åĬ¨ +æīĢ ç͍ +é¢Ħ åijĬ +Ġobject ions +å®ļ å¾ĭ +par agraph +æĥĬ åı¹ +ä½įç½® çļĦ +ç©¿ éĢı +Ġmult imedia +es an +ï¼Ł åĽłä¸º +两 çĤ¹ +æīĭ åĬ¿ +, V +Ġst alk +lu id +ĠPr ison +Ġ" ," +ĠEn forcement +ãĢĤ æĢ» +ĠM OV +Ġcont aminated +abb age +骨 æŀ¶ +/ file +ï¼Į æŀľ +èµ ¦ +æIJ¬ è¿ģ +ï¼Į ä¹IJ +Ġanalog ous +ãĢĤ åħ¶ä»ĸ +æ¸ħ æ¾Ī +çļĦä¸Ģ æĿ¡ +qu art +çī¹ æľĹæĻ® +_H OME +_ admin +Ġy y +il ers +Ġsuper f +æķ¬ ä¸ļ +æŀ¸ æĿŀ +é¦ĸ 饰 +og ical +h ub +inst on +Ġp k +ĠIns ider +Ġpermit ting +. Input +æĭĽ çīĮ +æ´Ľ åħĭ +j ournal +æĢ¥ çĿĢ +emb ed +[M OBILEPHONE +Ġfeas ibility +被 她 +ä¸Ń åIJ«æľī +Ġam mon +Ġun le +åıĮ éĩį +ĠM igration +Ġc itations +æķ°æį® éĽĨ +) init +ĠP df +Ġportray ed +Ġpost al +Ġb othered +.con current +Ġs sl +ĠPro xy +åĮħåIJ« äºĨ +Ġco arse +ï¼Į æĬĹ +è´µ 人 +åľ° éĹ®éģĵ +h c +B SD +ä¸į èµ·æĿ¥ +åħ« åŃĹ +è§£ æ¯Ĵ +( äºĮ +ton es +çŁ³ çļĦ +TR Y +format ics +Ġtherap ists +ï¼Į大 大 +éĢļ 车 +mult ic +çļĦ è¯Ńè¨Ģ +Ġcon ception +Ġpro d +Ġuser Id +Ġmot ive +st ones +æĪIJ ä¸Ģ个 +Ġmit igation +Ġhour ly +sm art +çļĦ女 çĶŁ +R yan +sv g +- Time +z ier +ric ting +ĠS ME +ãĢģ æĪij +Ġav id +B eyond +举åĬŀ çļĦ +åįİå¾ĭ ç½ij +å±± æ²³ +" There +æĹ¶ ä¼ļ +ä¹Łæ²¡ ä»Ģä¹Ī +_ rel +ĠPrint ing +оР· +ĠGe ometry +âħ ¡ +< >( +/b ash +ĠAdvent ures +ï¼Į èĦ¸ +ĠE TH +åĨľ åİĨ +第ä¸ī 次 +Ġsurf ing +鼷 诺 +èĿ ł +ĠD X +.Is NullOr +Ġnegot iating +ĠT AG +ä¸įç͍ æĭħå¿ĥ +Ġprodu ctions +Ġnanop articles +Ġsh ark +recogn ized +ĠAb ility +åīĤ éĩı +伺 åĢĻ +çī© ä»· +Ġsubst ituted +åīį ä¸ī +客 车 +å°½ äºĨ +Ġnav igating +ĠS ER +> This +æ´ ± +å®Įåħ¨ æĺ¯ +ãĢģ æīĵ +éĺµ èIJ¥ +Ġsqu ash +ĠQ B +a ñ +J ason +ĠF rost +ä¿¡æģ¯ åħ¬å¼Ģ +N eg +Ġchar ities +ä¸ĢçĤ¹ éĥ½ä¸į +Ġthr ill +in j +æ¸ħ æľĿ +< V +.T ry +Ġprov inces +_block s +å¾® æ³¢ +èĥĮ åĮħ +åħ« æľĪ +off ice +ï¼Įå¾Ī 容æĺĵ +Ġcontract ual +ĠPet erson +Ġcr ashed +int estinal +an ing +Ġn ano +Ġal ly +大 å±Ģ +èĤ¾ èĦı +\ lambda +ias is +çIJĨå·¥ 大åѦ +ge om +able View +çĬ¶æĢģ çļĦ +" ' +m esh +æ²IJ æµ´ +Ġminim izing +{ sub +Ġt art +red is +âĢĶ but +Ġinterpret ations +Ġele phant +Ġ æ¢ģ +ä½ł è¿Ļ个 +_FE ATURE +ĠV iv +Ġobs ession +ç¨İ çİĩ +åĩº 让 +æ¡ Ķ +ĠK nown +Ġspread sheet +ä¸Ĭ 设æľī +Ġh id +, åĪĺ +ĠD rawing +ĠN ak +ï¼Į为 ä½ķ +Ġd ia +Ġvolunt arily +( Http +Ġpuzz les +Ġp ushes +ç£ģ åľº +æĥ ļ +ĠRoman ia +è¯ī æ±Ĥ +P ull +樱 èĬ± +Ġun subscribe +å¾® éĩı +Ġtra umatic +%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%% +[] ) +spNet Core +Ġessential s +ä¸įèĥ½ å¤Ł +Ġ[] * +ĠWy oming +pol icy +误 åĮº +QUEST ION +è¾ĥ 强 +Ġro ast +ĠL ounge +Ġpre requ +Ġ ãĢĭ +Part ner +U AGE +n uts +Ġed itions +Ġm ater +ĠÐ Ĵ +BO OK +Ġ 表 +OLUM N +ç͍ èĩªå·±çļĦ +un o +审 è§Ĩ +F inder +ĠPar ish +Ġrep etitive +ãĢģ æķĻåѦ +ĠT ier +ĠE arn +æ¼ ¾ +n k +ä¸Ĭ ä¸Ģ个 +æĶ¹ æŃ£ +ä¹Łæĺ¯ æľī +Ġresear ched +, 羣 +è±Ĩ çĵ£ +ĠOffic ers +ï¼Įä½ł çľĭ +æľ¬ åij¨ +åīį è¿° +ith uan +_P P +Ġbefore hand +åĩĨç¡® æĢ§ +å¸ĥ å°Ķ +Status Code +车 è½½ +Ġdist ortion +F a +l ide +å¼Ģ éĩĩ +" That +ä¸ĭ 鼨 +Ġphosph ate +Ġin ode +å·§ åIJĪ +åİŁ æľīçļĦ +Ġpept ides +ĠC ats +ĠHold ings +ĠB inding +åįķ纯 çļĦ +Re act +chan ical +Ġcleans ing +Ġad ore +å®ī 举 +èµŀ åĬ© +æħİ éĩį +ĠCat hedral +ĠCl osed +Ġredund ant +Annot ations +ãĢģ å·¥ä¸ļ +ï¼Į ç»§ +æ·± åİļ +Ġem itted +Ġdeleg ates +ï¼Į å®īåħ¨ +_RE C +Ġ è¿ĺ +IL D +丽 ä¸Ŀ +IN A +Ġspread s +åħħè¶³ çļĦ +ĠM anu +B a +,ä¸Ģ æĹ¦ +æĮij è¡ħ +Ġ çĶ· +ĠGil bert +Ġhur ting +_S PI +ãĢģ åĴĮ +_ST REAM +ĠGrow ing +çķĻ ç»Ļ +_ + +ç¥ŀç§ĺ çļĦ +Ġcon ceived +ĠE PS +Ġcomm enced +è·Ł æĪij说 +ĠRe peat +ĠL LP +Ġav g +mont on +ĠF iber +ĠK otlin +s pe +ĠT it +ĠT error +}$ - +Ġst ole +_ex ec +_{ - +ĠR aid +çļĦ æĹ¶åĪ» +åħ¨ åľº +éĺ¿éĩĮ å·´å·´ +Ġinter change +print s +rack et +ric an +Ġrelie ved +_D ESC +æŃ¥ åħµ +L ists +éĹª åħī +äºĶ åħŃ +AM S +Ġ å¹³ +Ġsup rem +èĢĮ åIJİ +å®Į åIJİ +ĠG ambling +åıij èĩª +-s pec +Bit coin +G UID +è¿ĺä¸į å¤Ł +_ images +Ġfac et +_N EW +O X +arr ants +æĮĩ æľĽ +ãĢĤ æ¯ı天 +ï¼Į èĢIJ +ung al +Ġa pr +ĠC rist +人 说 +Ġmig rate +Ġestim ator +éĺ» å¡ŀ +{ enumerate +The orem +du ino +èIJ¥ åľ° +E Q +Ġpl ural +缴 è§ī +ĠYour self +Ġsupplement al +ĠE lev +ĠIter ator +ĠSynt ax +ĠW arm +çļĦ æķ´ä½ĵ +Ġserial ize +Ġun acceptable +ï¼Į ä»Ķç»Ĩ +Ġbenef iciaries +TA IN +ĠL ists +-sh irts +__ . +å¤ĸ æĿ¥ +vis ibility +èį¡ èį¡ +_D OWN +_ attributes +çļĦ éĿ¢åīį +Att rib +饮 åĵģ +ĠReal ty +Ġre arr +Ġbound ing +rown ed +ãĢĤãĢĤ ãĢĤãĢĤ +åľ¨ åħ¶ä¸Ń +ĠS ally +ï¼ī ä¸İ +ç»Ĩ å¾® +ĠWorld wide +Ġâī Ī +.net work +çļĦæĹ¶éĹ´ åĨħ +Ġboost ing +Ġt ed +å¾Ī ä½İ +çļĦäºĭ ä¸ļ +ÏĦ ικ +ĠHash Set +< void +p icture +ï¼Į çİī +ĠM G +Ignore Case +ï¼Į è°ĥæķ´ +ern els +大 èĩªçĦ¶ +Ġpr ince +å¥Ĺ é¤IJ +ï¼Į åĪĿ +åĢĻéĢī 人 +. Items +ug ht +Ġref ine +Ġx mm +宽 æķŀ +ï¼Įå¦Ĥæŀľ ä¸įæĺ¯ +ĠPatri ots +éļ¾ çľĭ +æĿĨ èıĮ +ĠCase y +ï¼Įè¿Ļ æĺ¯ä¸Ģ个 +rom pt +è§ī éĨĴ +Ġisol ates +æ°´ æĢ§ +Ġprogn osis +éĥ½ èĥ½å¤Ł +ĠCom ics +Ġh ij +ä¿Ŀ æļĸ +主 å¸ħ +çļĦ æĦıè§ģ +Ġin ning +struct ured +ä½ľç͍ ä¸ĭ +CO RE +.g enerate +èĥľ è´Ł +Ġpe as +ĠAn s +ĠH F +å±± åİ¿ +Ġprot esters +èĩªçĦ¶ ç§ijåѦ +åĩº ä¹İ +ĠAgric ultural +ĠOrgan izations +List View +ela ide +-------- -- +ĠM ON +Ġab usive +ĠDef ence +ĠN okia +ĠLand scape +Ġcent rifug +оР¿ +Ġpotential s +group Id +ĠDim ensions +Des ktop +æ¯Ķ 为 +çĥΠ士 +_ events +ï¼Į以 èĩ³äºİ +.comm ons +prising ly +ĠH ern +Red irect +_s ym +. -- +æĪĸ æľī +ä¸Ģ åľĪ +çα çļĦ人 +æ¡Ī åŃIJ +ï¼Į æķ° +rodu cing +Ġge ography +ON FIG +èĢĮ èĩ³ +ress or +è¯ħ åĴĴ +( Test +X iv +éĢĥ èĦ± +'=> ' +oci ate +erm any +ï¼Į 代表 +Ġtest ament +çľĭ ä½ľ +,å°± åĥı +d irection +Ġliqu or +çª Ĵ +æģ º +ĠDe uts +æĪij åıĪ +Ġre el +ĠHigh lights +æĹ¶ ä¸į +ç»Ħç»ĩ å®ŀæĸ½ +.m p +Ġnon atomic +Ġawait ing +è¿IJ éĢģ +dis p +ï¼Įè¿ĺ 没 +è´¨éĩı åĴĮ +Ġspecial izing +× Ķ +ï¼Į éĥŃ +ĠG oth +~~ ~ +审议 éĢļè¿ĩ +Ġdep ot +梦 å¢ĥ +é«ĺçŃī æķĻèĤ² +Ġar rog +Ġsm oked +Ġf erm +Ġwar fare +N ON +使 åĬ² +Ġthe ology +çģ« èĬ± +ï¼ĮéĤ£ éĩĮ +Ġj ohn +Pl ain +ĠAs ync +Ġcow ork +ä¼ł æİĪ +æĮī è§Ħå®ļ +cknow led +åIJį æł¡ +ç£ģ æĢ§ +A mb +æĭĴç»Ŀ äºĨ +ĠF actors +对 æīĢè¿° +/ article +e on +ï¼Į è¿ŀç»Ń +(l ength +Ġharvest ed +红 éħĴ +Ġentrepreneur ship +Ġin equalities +é» Ķ +ĠPlay Station +Ġred is +cy l +OP EN +ĠD erek +ĠM AG +ا ر +对 è¿ĻäºĽ +ĠRe ceive +åįĥ éĩij +Ġnot ions +Ġtact ical +ĠS igma +apital ize +å«ģ ç»Ļ +Ġf ru +ï¼Įå¹¶ä¸Ķ åľ¨ +Ġexp ires +if o +m ul +agn osis +ect s +Ġ'/ ' +Fl orida +æ¯ Ĺ +ĠMar sh +æ´ ¼ +ç͵ è¿ŀæİ¥ +_b ool +(m ock +ĠHigh ly +ãĢģ æ°Ķ +为 ä¸ŃåĽ½ +. ok +" If +t ops +ï¼Į ç»ıæµİ +è¯Ń ä¹ī +çļĦ åĮºåĪ« +C oun +Ġ 太 +Ġgraph ical +Ġpedest rian +Ġelect oral +our ced +, name +en ames +ï¼Į ä»ħä»ħ +ãĢģ çݯä¿Ŀ +ï¼Į æ°¸ +éķĩ åİĭ +atur ated +åĨ³å®ļ çļĦ +ĠTik Tok +r g +Ġf oul +ĠO ral +Ġgrad ual +Ġlonge vity +é¢ł è¦Ĩ +Ġallerg y +Ġfin als +_T ARGET +Ġpione er +ï¼Į æĦŁåıĹ +/ man +organ ic +ĠHind i +Ġlandsc aping +F ederal +è® ª +Manag ed +Ġtun es +. ip +ãĢģ åѦ +Ġsh ampoo +Ġd ude +ĠFIF A +ĠL ac +Ġneuro logical +, æĤ¨ +å½ĵ åį³ +åΰ èĩªå·± +ĠAff ero +L os +Ġ åįģ +çļĦ 计åĪĴ +Fe el +ĠA ctions +H ist +ĠT roy +ĠN PC +Ant i +, åħ± +Inf os +.f unction +.s qrt +ĠMe at +gorith ms +r w +Ġcontract ing +Ġcha otic +ä½ł åĴĮ +ĠMart inez +Ġre charge +åĪĩ éϤ +aps es +è§ĦèĮĥ åĮĸ +-b inding +äºĮåįģ 大 +ic us +Ġl ubric +, çľĭåΰ +çŃī åĬŁèĥ½ +li ography +ä¼ļ å°Ĩ +ĠØ ª +he ries +驱 éĢIJ +Ġ åIJĪ +un ter +以ä¸ĭ åĩłä¸ª +å© ª +-se x +:n one +var iables +ida e +åľ¨ ä¸Ĭæµ· +æ¯ı ä½į +Ġ ç¾İ +ĠM oss +è¿Ļ éģĵ +缸 ä¼ł +edd y +ĠEther net +. ** +Ġconstruct s +ĠM W +_p rivate +ÂĢ Â +. Now +M ind +红 åĪ© +Ġlayout s +Ġgrap es +Ġfire arms +Ġdem ons +OT S +_ aut +Ġj ets +Rep o +\x f +ĠE F +ĠUn icode +转 è¿ĩ头 +ä¼Ĺ å¤ļçļĦ +C oin +IT AL +ram eworks +Ġber ries +ï¼Į åħ¨çIJĥ +oa uth +.fl ags +CONT ACT +ĠAr row +ĠR ear +çĴ § +é d +Ġer ad +设å¤ĩ åĴĮ +m ov +Ġm k +åįķ ä½ĵ +åĤ» åŃIJ +_AR GS +æĶ¾ åģĩ +for um +Ġun const +Ġk on +ĠW als +ip ro +Imp act +Ġgall on +anz ania +çľ¼ çľĭ +/d at +äºĮ åŃĹ +æĶ¾ è¿Ľ +ĠSupp lies +å¤ĸ è¯Ń +Ġaut onomy +çĥŁ åı° +å¾Ī好 åľ° +龸 æ°Ķ +× ¨ +Ġun cont +ĠE ating +ãĢģ ç§ijæĬĢ +Ġaw a +æĹ¢ æĺ¯ +âĪ Ī +ï¼Į åı¦ä¸Ģæĸ¹éĿ¢ +oo o +çĤ ³ +ĠMat lab +çļĦ åĴĮ +Ġsom eday +/ include +å«Ĥ åŃIJ +_ pp +åĽ¾ 表 +Ġhack ers +Ġj avascript +oca ust +Ġag on +çļĦ æĪIJ绩 +èł ķ +Ġambig uous +åĽ½éĻħ åĮĸ +çĥŃ åº¦ +ï¼Įä»ĸ è¿ĺ +Ġ[ $ +.w orld +伯 çε +Ġh ull +ë ¦ +æ® ´ +app s +å¾Ĺ ä¸Ģ +éĢĤ æĹ¶ +ãĤ ° +éģĹ å¿ĺ +ä¸į ä¸Ģ +.t ask +RE N +Ġd ug +æŁ ļ +Ġcut off +EX PORT +ĠHand ler +âĢľ When +好 æľĭåıĭ +ract ical +ĠL opez +Ġdi ary +é¢ ĵ +Ġview point +( tr +ä¸Ń èĢĥ +ÑĢ Ð° +æľĢ ç¾İ +èĢģ äºĨ +ig t +çķħ éĶĢ +ĠM F +æĹł å¤Ħ +Ġanim ations +Ġth irst +ä¹ł é¢ĺ +è¶ĬæĿ¥è¶Ĭ 大 +å¤ļ 为 +ä¹Łä¸į 好 +,æĪij æĥ³ +Ġhe p +^ âĪĴ +ĠHe ath +Ġinherent ly +ĠH ilton +ç»Ĩ åĪĻ +ĠEVER Y +åĺ´ ä¸Ĭ +O ID +éĤ ¸ +ĠCh in +ãĢģ è¶ħ +olph ins +ä¹± äºĨ +çļĦ èĥ½éĩı +åģ· è¢Ń +ĠR ica +Ġsu do +_ rem +Ġdeliver ies +F air +dat etime +lin ewidth +ov id +Ġconst expr +df s +ur ous +æĹ¶ å°± +ç¾ ² +éĺ¿ æł¹å»· +str uments +Ġpass ions +ĠH ass +_st orage +带 äºĨ +å¸ħ æ°Ķ +ve e +ç¼ ª +Ġmaj ors +ĠT W +ĠH emp +Ġquestion able +åIJ¸ åıĸ +èµŀ èµı +Ġpo pped +f iction +çϽ èıľ +ãĤ « +Ġfl ames +, å¼Ģå§ĭ +ï¼ĮæĪij们 åľ¨ +æ²»çĸĹ æĸ¹æ³ķ +Ġin vert +é© ¯ +Gener ation +Ġge o +大 佬 +Ä Ĺ +ĠM add +åı« ä»ĸ +Ġapp arel +éģ® æĮ¡ +Ġdev ote +æĺ¯ çͱäºİ +_U INT +æĤ ¸ +S ky +( ', +, äºİ +ĠPear son +ĠTh u +M W +_st atic +_EX PORT +ĠC UR +Ġc uc +ĠQu inn +_FAIL URE +åĪ ģ +se lection +Ġ ÑĢаР+be en +C raft +w k +åĩºåħ· çļĦ +çļĦä¸Ģ å¹ķ +reg ulation +æĮ¤ åĩº +æĹ¥ åζ +ĠL EG +Ġins pections +Ġgreet ed +H u +æīį 好 +æ·± è¿ľ +pro vider +ç§° ä½ľ +d an +使ç͍ èĢħ +å¤ĸ èµĦ +d istance +.t ab +éĢī ä¸Ń +æ°´ åĴĮ +Ġsu e +Ġpop s +[ int +çļĦ æķĻåѦ +vas ive +çĺ Ģ +к а +. msg +Ġis omorphism +åĶ ij +_b us +æĹ¥ è¯Ń +_n etwork +ĠBel ieve +AL T +Ġtake aways +( local +ï¼Įä½Ĩ è¿ĺæĺ¯ +ĠSal mon +ĠPe er +ors che +ä»»åĬ¡ çļĦ +ç͵è§Ĩ æľº +forget table +Ġe ats +Ġb og +æį ħ +Ġthr iller +å¾ ĺ +éħ¸ æĢ§ +Ġs addle +ĠLead ing +. play +èµ¶ å¿Ļ +Ġqu il +ĠFor bes +-b orn +- place +Ġa y +缴 å±ŀ +ç͵åĬ¨ æľº +. State +< P +é£ŀ éĢŁ +ote ch +> ` +Ġev apor +ï¼Į å®ŀéĻħ +Ġl ush +åĮ ¡ +Ġcomp rehension +å¤ľ çļĦ +æĮº 好çļĦ +ĠDi agram +ï¼Į çŁ¥ +ï¼Į çĪ¶äº² +_l ang +ç½ķ è§ģ +çĤ¹ ç¼Ģ +Ġobsc ure +f v +F ly +æĦŁè§ī èĩªå·± +èĭ¦ æģ¼ +ĠMcC ain +- " +ĠM n +Ġre els +enc ers +Ġorgan izers +纯 åĩĢ +æ¯Ķ ä»ĸ +Ġlog istic +åı ½ +ĠB one +ãĢĤ èĭı +åľ° ä»İ +åħħ æĸ¥ +款 çļĦ +Ġer ase +Ġsuscept ibility +Ġhous ed +éħ¸ çĽIJ +Ġsc anned +Q C +ig ible +T EXT +èĥ½ æĬĬ +æľ¬ åŁºéĩij +Ġ] ]; +Ġpump ing +ĠM eyer +ï¼Į ä¿® +use ment +天津 å¸Ĥ +_P os +Ġ éĥŃ +ĠAg ents +群 å²Ľ +åĩı æĮģ +ĠCar roll +ĠG Hz +\text width +èĮĥåĽ´ åĨħçļĦ +_P AGE +Ġperform er +ĠWe apon +æĪĸ å¤ļ +code c +è´¨éĩı çļĦ +ï¼ļ https +re ements +<< " +ен ÑĤ +ä¸Ń è¿Ľè¡Į +龸 éģĵ +çĽĸ æĿ¿ +ĠSec rets +FFFFFFFF FFFFFFFF +è§Ħ模 çļĦ +å± ī +Ġul tr +Ġdom inance +æĬķ ä¿Ŀ +Sim ilarly +ĠUn limited +å¾Ĵ åĪij +-m aterial +ĠInst ructions +if a +åĽĽ ç§į +ĠSh annon +Ġpreced ent +ĠR us +acter ial +Ġdistribut or +ĠW rong +Data Set +Ġbul lying +åIJĦ å¼ı +Ġdemonstr ations +ëĭ Ī +ECT OR +isb ane +ï¼Į æĶ¾åľ¨ +Ġ èī¾ +Ġobserv able +ä¸Ĭ ä¹Ł +ç§ģ ä¸ĭ +å¿ĥ è·³ +R oad +çİ ĸ +.F at +gr pc +çļĦäºĭ åĦ¿ +Ġsurvey ed +Ġche ating +( position +ĠF unc +ov ich +çļĦ æŃ» +çļĦ æĦŁæĥħ +ĠG aza +Ġun icode +Error Code +ç§ij éķ¿ +ï¼Į ä¹ħ +B irth +ãĢģ äºij +ä¸Ģ å¹´çļĦ +tain ed +IT T +Ġp addle +åħ¬ 认 +åĩł åįģå¹´ +erent ial +å¸Ĥåľº éľĢæ±Ĥ +æĢĢ æĬ± +Ġconver ges +Ġexpend itures +ä¸į 离 +K ids +æŃ£æĺ¯ åĽłä¸º +Ġcont ests +Ġimp ulse +Ġbout ique +r ules +/ to +ï¼İ ï¼İ +大 å§IJ +M ission +.R ec +ï¼Į åı³ +æ°´ æµģ +éĵħ ç¬Ķ +_L INK +/ get +ç¿» 身 +æĹ¥æľ¬ çļĦ +éĢģ ä¸Ĭ +ç¥ĸ æ¯į +æĹ¶ æľī +éĽĨ ç»ĵ +åIJĪä½ľ åħ³ç³» +çıŃ éķ¿ +ç¥ĸ çζ +(arg v +åͱ çīĩ +ĠTh reat +@ p +ĠBeng al +ä¸Ģ çŀ¬éĹ´ +_B ITS +çľ¼ çIJĥ +ĠB od +H old +ĠCA USED +D irections +Ġcom fy +ï¼ĮæĽ´ ä½ķåĨµ +认è¯Ĩ çļĦ +ĠAD HD +_ amount +os in +ï¼Į 追 +Ġ æ´Ľ +an ical +ãĢĤ å°±æĺ¯ +è¾ Ļ +æĹłå¥Ī çļĦ +D ll +çļ± äºĨ +Ġwel ding +Ġb idding +ภ± +.T asks +asc ade +Ġd inos +Ġpa used +Ġcont amin +èϽçĦ¶ æĺ¯ +ĠY orkshire +Ġevent ual +Ġacquis itions +ĠPer cent +ib a +/ qu +åīĸ æŀIJ +èµ° è¿ĩåİ» +åİ¿ éķ¿ +主人 åħ¬ +_d own +ä¼ł 羣 +ä¸Ĭ åij¨ +ãĢĭ æĿĤå¿Ĺ +ment e +ĠExhib ition +: a +åī§ åľº +èģĺ ç͍ +ï¼Į åĪĽéĢł +Ġtra ps +Ġtrend y +B AR +ä½ĵ åŀĭ +ãĢģ æĶ¿åºľ +_st eps +Ġb ak +ENS ION +âĢľ 两 +ãĢģ åıijå±ķ +R on +Ġsafegu ard +ï¼Į 两个人 +ãĢģ æľºæ¢° +Ġext ras +éļIJ å½¢ +声 ç§° +纪 æ£Ģ +em phasis +ç͵ ç«ŀ +ĠConnect ed +p repare +Ġpath ogens +åºĶç͍ çļĦ +Ġscal able +Execut ive +å¿į èĢħ +å¤į åı¤ +Ġpredict s +ãĢĭ éĩĮ +åľ¨è¿Ļ åĦ¿ +Ġscreens hot +C nt +Ġple ad +w riters +ĠJohn s +声 èªī +èĢĮè¨Ģ ä¹ĭ +Ġbas al +ï¼Įå¦Ĥ æľī +åŁºæľ¬ ä¿¡æģ¯ +å®¶ åįıä¼ļ +( command +S ay +Ġqu o +ï¼Į æ´» +ä¸Ń æµ· +éļIJ èͽ +ĠBurn s +Ġl inen +äºĨ æĮĩ +ĠMid west +ĠEurop a +-res olution +ert ificate +åı® åĺ± +ĠAd m +Ġsett lements +c alled +大 èħ¿ +L ite +ĠTechn iques +çĥ Ļ +Ġob struct +ĠSuccess ful +Ġdecl aring +ĠSUB STITUTE +ĠSm ooth +è¿Ľ åζ +Ġa k +ĠN issan +Ġout right +åģľ é¡¿ +åŁ¹è®Ń çıŃ +ĠBro s +Ġsand wiches +èĬ± æľµ +Ġ åĽ¾çīĩ +.S c +驾 车 +.S erialization +ĠL ars +绳 åŃIJ +Ġfacilit ating +ä¸ĩ èĤ¡ +ĠS event +èĤ¥ æĸĻ +Ġport raits +Ġpl at +Ġoptim izing +" åĴĮ +ĠG in +ï¼Į åĬ¨ +åįĬ æĻĮ +è¾ĵ åĩºçļĦ +åµ © +ren ew +æ°ij åĬŀ +ĠF ry +社ä¼ļ ç§ijåѦ +ï¼Įä¸Ģ ä¸ĭåŃIJ +Ġg c +Ġk i +m us +æĥ ° +åºĶ æľīçļĦ +ĠInvest ors +hen yl +ĠSp read +ï¼Į è¯Ńæ°Ķ +gg ing +Ġconfidential ity +Strip MenuItem +ä¸Ģ å¦Ĥ +ĠSep ar +Ġord inance +C BD +ä»ĸçļĦ è¯Ŀ +纸 å¼ł +ï¼Įåħ¨ åĬĽ +u ctions +çŃī åIJĦç§į +å¿ĥ å¾Ĺ +Ġpath ology +åѵ åĮĸ +\ pm +ox icity +éĺģ ä¸ĭ +_ APP +ï¼Į ä½ľ +ĠCour ts +ĠSc out +æ¶Īéĺ² å®īåħ¨ +æĺ¯ å¤ļä¹Ī +G allery +Ġ )) +ĠH older +åѦ éģĵ +ĠBlock chain +å¼Ģ éĺĶ +ĠK erry +å¿«ä¹IJ çļĦ +Ġbas in +ĠGraph ic +Ġsympath y +ĠD F +="../../../../ ../ +ĠType Error +å¿ĥ äºĨ +è·¯ æĺĵ +ĠProv iders +Ġ 羣 +ĠRat ings +ĠSpring er +åΰ æľĢåIJİ +åĸľæ¬¢ ä½ł +Ġnumb ered +ä¸į è¯Ń +ĠFl ip +We apon +转 çľ¼ +ç»ıèIJ¥ èĢħ +èµ° è¿ĩæĿ¥ +ãĢĤ æķ´ä¸ª +åī¯ ä¼ļéķ¿ +ĠG ENER +è¡Į 礼 +åħ¬å¸ĥ çļĦ +Ġjun gle +ĠD ish +V ehicle +ĠBre nt +-y ou +Ġfluores cent +çĿĢ éĤ£ +ĠBl ank +ãĢģé«ĺ æķĪ +å·¥ä½ľ æķĪçİĩ +car bon +Ġcovari ance +åħ± 鸣 +æķ£ äºĨ +Ġf erry +Ġident ifiable +ĠT RA +ĠA ce +åŃ ¢ +Ġobs ervers +Ġreceipt s +æķ°æį® åĪĨæŀIJ +å¸Į å°Ķ +éĩijèŀį å·¥åħ· +åĩº éĻ¢ +Ġsan ction +Ġinject ions +D ar +_LO W +ion a +Ġin ception +(t ask +ĠU UID +æŀĦ æĢĿ +sk b +Ĉ ą +Ġparad ise +< Object +京 éĥ½ +a an +æķij åij½ +åĩº 头 +Ġreg eneration +ĠPROC UREMENT +åŃĺ ç»Ń +è¿ĩ å¤ļçļĦ +Ġinfring ement +Ġag ile +Ġpred ecessor +åIJ¸ åħ¥ +Q S +ä¸ĩ 亩 +Ġwar rior +Ġjurisdict ions +d os +Ġ) : +- str +æĺ¯ä¸Ģ çīĩ +AV A +tor ch +Ġempower ing +æĿij åŃIJ +av ia +Ġpri ests +-build ing +é¦Ļ çļĦ +骤 çĦ¶ +?? ? +ï¼Į æĦŁè°¢ +ç±³ å°Ķ +ins ki +ĠSter ling +ì Ĭ +ä¸į å¿ħè¦ģçļĦ +Ġin justice +åľ¨ åIJİ +ãĢĤ éĴĪ对 +Ġre hab +ra x +Ġste er +Ġcomm ute +Ġm alloc +ari at +èĮĥåĽ´ çļĦ +ĠG UID +ä»İ 头 +å®¶åºŃ çļĦ +ä¸į 稳å®ļ +ç²¾ æ¹Ľ +ï¼Įåı¯ä»¥ éĢļè¿ĩ +M ot +ĠD b +女 è£ħ +Ġinaccur ate +ale igh +EMPL ARY +i ag +ĠBay esian +åıª åī© +ĠJ ak +ĠMom ent +åĮĸ 身 +ĠEv an +çݰéĩij æµģ +ĠAmeric as +ol ics +ĠD irection +.add EventListener +Ġsuccess ion +ĠBen efit +Ġw t +å°º 度 +Ġbutter fly +Ġoptim izer +Ġrhet oric +Ġa ustralia +Ġun real +èĤ¡ åĪ© +åįİ çĽĽé¡¿ +æĹı 人 +èι åıª += & +f est +ER M +Ġrep etition +F ake +Ġst aging +æĬķèµĦ 人 +ç¾İ åѦ +ĠPresident ial +çľ¯ çľ¯ +åıĺ è¿ģ +主ä¹ī èĢħ +åıij æĬĸ +rep resentation +æķ¬ 请 +{ }) +:n il +Ġre iter +ĠIn form +Ġdipl omatic +Sc anner +Ġgu ild +( left +Ġru ins +ä½İ ä»· +_h igh +Ġren amed +el p +åĽ¾ æĸĩ +ĠST ATUS +Ġp unk +çļĦ äºĶ +åį´ è¢« +大 çīĩ +éĤ£ èά +Ġ' ') +ï¼Į æ³ķ +Pr ime +in cludes +åĪ©ç͍ çİĩ +Ġ çªģçĦ¶ +å¹ķ åIJİ +å°ı 红 +æľº 身 +èĦ IJ +_s chema +Ġn em +com pl +åIJĮ èĥŀ +(" -- +åľ°çIJĨ ä½įç½® +C rypto +ĠIn strument +-> { +ä¸Ģ 举 +_c ost +F IELD +cel ain +P ACK +ç¤ ģ +Ġattack er +"/ >< +IB UTE +è® ¥ +åľ° åĪ© +ç͍æĪ· æıIJä¾Ľ +ï¼Į éĢIJæ¸IJ +éŃĶ åħ½ +åºĶ æľī +çļĦ 帮åĬ© +èĢĮ æĹł +Ġt ended +Ġshoot s +æīĢæľī 人çļĦ +èĮ« èĮ« +ĠZ imbabwe +æµģ æĦŁ +æĬ¥åijĬ æľŁæľ« +cc oli +ĠMun ich +触 åıĬ +M u +the orem +, æĽ´æĺ¯ +åĸĿ èĮ¶ +Ġcl auses +h oot +ãĢĤåľ¨ è¿ĻéĩĮ +, çĦ¶èĢĮ +ic ans +/ util +rop olis +ä¾§ çļĦ +åħ¶ åľ¨ +% = +å¼Ģ æĪ· +åħĭ éĩĮ +éĿŀ常 éĩįè¦ģçļĦ +Ġinflu encing +个æľĪ åĨħ +Ġaver ages +ĠV ia +Ġstret ches +Ġinhib ited +Ġdis connected +ĠP resentation +_pro b +第ä¸ī 个 +æĬĹ è®® +Ġl iner +ç½ij æ°ij +Ġcor al +çķ¥ æľī +ĠW ik +atto os +Ġlong time +ĠChe st +èĹ ķ +æij¸ ç´¢ +éĿ¢ä¸´ çĿĢ +L ost +ĠO D +un ched +be ck +Ġsqu ared +æķĻ ç§ij +Pr incipal +åĽĽ æľĪ +Ġwas her +, åĬªåĬĽ +. types +, æ¯ı次 +ĠA X +åŃĺ çļĦ +ĠCarol ine +im ator +D ump +. ãĢĬ +G INE +I o +ï¼Į åħĥ +Ġcultiv ation +ob iles +åĢĴ åľ¨åľ° +Ġphil anth +ref resh +æ¾İ æ¹ĥ +qual ified +Ġw ired +È Ļ +å¾ĺ å¾Ĭ +ac re +_IM AGE +- plugin +Ġv illa +V L +-t arget +ĠR iley +Ġexc itation +çĽĬ äºİ +樱 æ¡ĥ +èİ«åIJįåħ¶ å¦Ļ +ãĢĭ åľ¨ +Ġinstruction al +ort uga +Check Box +Ġas phalt +ä¾ĿçĦ¶ æĺ¯ +Ġperturb ation +Ġtax ation +ĠL B +.c ustom +è¿ĺæľī äºĽ +ï¼Įè¿ĺ ä¼ļ +Ġre play +èĤ ½ +åĴĮ ä¸ĭ +ï¼Į 计ç®Ĺ +çļĦä¸Ģ éĥ¨ +Ġde leting +ft s +Ex ist +åı¥è¯Ŀ 说 +Ġc decl +ãĢģ æĸ½å·¥ +å¿ħé¡» åľ¨ +ĠEX EMPLARY +Ġincorrect ly +åĪĨ 级 +,æĪij å°± +) _{ +App lications +) }( +Ġf ibr +": {" +èĦļæŃ¥ 声 +èĥ½ èĢĹ +ĠKey board +åĥµ 硬 +ĠR ising +T K +ä¼Ĺ 人çļĦ +G as +Ġas ylum +qu ared +im ension +éģĵ é¢ľ +Ġr he +Ġadj ud +ä¸Ń 被 +æīĢ ä¸º +it at +H W +Ġpr inters +; j +ink er +åı° çļĦ +è¡£ è£Ļ +Ġå¹´ æľ« +ĠD odge +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +åľ¨ åģļ +å®ī åįĵ +ï¼Įä¸Ģ ä½į +ï¼Į 交éĢļ +åŃ£ åIJİ +Ġb unk +åıij åŀĭ +ĠI van +ï¼Į æĦ¿ +ĠR FC +éĢŁåº¦ å¿« +Ġsharp ly +ãĢģ é¡¹çĽ® +[ e +ĠU E +.g ame +Doc uments +ĠProp het +çļĦ è¦ģ +ro cket +çİ ® +lo ating +ç · +æĺŁ åħī +es i +que z +温æļĸ çļĦ +ju ven +ĠCom edy +Ġel ong +se udo +am d +Ġst ew +red uce +èĬĤ çļĦ +ĠSt y +================================ ================ +èī¯ ä¹ħ +ant ages +ĠPer l +è´ª 婪 +çļĦå·¥ä½ľ 人åijĺ +æŃ£ å¦Ĥ +æ·± æĥħ +Ġment oring +Ġwel comes +ĠDream s +ç¿» äºĨ +der ive +Ġhear ings +Ġins urers +ãĢĤ对 æŃ¤ +Ġrefuge e +çļĦ æĪIJæľ¬ +, è¿Ļä¸Ģ +V ictor +çĭ ° +- equ +CA ST +le ave +< A +èįī åĿª +é¦Ĵ 头 +ĠD as +ï¼ĮæĪij们 ä¼ļ +åīĬ å¼± +ï¼Į èĩ³ä»Ĭ +æ±ĩ éĽĨ +bec ue +L ER +Ġas ynchronous +麻 éĨī +ĠAut umn +_ merge +.st rip +-b ed +Ġst ubborn +IN C +ï¼Į å®¶éķ¿ +ĠÑ Ħ +Ġcon gregation +Ġlate x +ç¼ ī +. Equals +æķ´ é¡¿ +éĢı æĺİçļĦ +麻 è¾£ +ĠINTERRUP TION +æĹĹ å¸ľ +ra ke +Ġhist ories +æĬ¥ 导 +Ġm n +(t f +åı¯èĥ½ æľī +ed ic +Ġd ashed +åŀĥåľ¾ åĪĨç±» +t uple +ä¸İ åıijå±ķ +Comp iler +ä¹Łæĺ¯ å¦ĤæŃ¤ +T OC +åĿļ å®ļçļĦ +ç¥ĸ åħĪ +J D +ĠM old +å°ģ éĿ¢ +S uffix +è°ĥ ä¾ĥ +ä¼ģä¸ļ 管çIJĨ +æ¯ĶèµĽ çļĦ +Âł åľ¨ +F K +Ġdiscover ies +Ġqu ir +è¿Ľè¡Į è°ĥæķ´ +len ess +BO SS +å¹² æ´» +Ġadhes ion +Read Only +æµ· çĽĹ +T CP +\ omega +Ġmultipl ied +è¯Ħ å§Ķ +è¿Ļ ç¯ĩæĸĩ竳 +ï¼Ľ äºĮæĺ¯ +ãĢģ åīį +ãĢģ é£Łåĵģ +å¼Ģ æĶ¯ +ĠP ir +Ġshort cut +ress ure +en y +Ġt ant +为 æľŁ +, éĿŀ常 +建 模 +äºĭæĥħ çļĦ +Ġ å¹¶ +ĠP arser +é¢Ħ çķĻ +Ġrepl aces +ภ£ +å°¤ æĸĩ +åIJĮ 缣 +ä¹Ł æĹł +oll en +(j ava +åħī äºĨ +ill ation +ä¸įè¦ģ åĨį +E PS +plic ated +æĽ¾ç»ı çļĦ +" ][ +èĤ¢ ä½ĵ +å®īåħ¨ æĦŁ +Ġquant ify +ï¼Įå¦Ĥæŀľ 没æľī +çIJĨäºĭ ä¼ļ +Ġwidget s +Ġd it +Over flow +engu in +ä¸Ļçĥ¯ éħ¸ +èħ ® +ĠPort folio +å½± éĻ¢ +Ġinterpre ting +(d oc +Ġindic ations +æ¦ľ åįķ +ere o +(b ody +è¿Ļæł· çļĦè¯Ŀ +å¨ Ħ +Con vention +Ġvill ain +ĠB EST +为 缮æłĩ +Ġrel ent +rack s +Ġer osion +ä¸įç»ı æĦı +Ġle agues +æĹĹ ä¸ĭçļĦ +æķ£åıij çĿĢ +Ġlaw suits +ij u +( format +ï¼Į åIJĮæ¯Ķ +æĨ ¨ +_ % +ï¼Į å°ļ +èµ° è¿ij +å¹¶åıij çĹĩ +游 ä¹IJ +Ġsound ing +T N +uck land +_L ONG +con cat +Ĉ Ć +un ed +ä½İ åİĭ +æľ« 端 +ĠCl one +Man ifest +Ġme ga +\x e +æĵįä½ľ çļĦ +çī¹ è´¨ +ik z +-s elling +åį° èĬ± +èĦ¾ èĥĥ +M arg +ĠR oosevelt +æ·± æĢĿ +ĠV K +åζ æĪIJçļĦ +Ġ æ¯ı +æĬķ æľº +ew orthy +}} (\ +Ġf lock +Ġexplo itation +ĠPow ers +Ġ åį¡ +é»ijèī² ç´ł +å½Ĵ äºİ +èĩª ç§° +ĠG rab +çĵ¶ é¢Ī +Ġmy ths +èĩ³ å°Ĭ +C ycle +ĠDep th +Ġinto x +. If +ĠSur f +Ġp ng +Ġbe et +æµ· åºķ +å¾· æĭī +ç»ıéªĮ åĴĮ +ĠDo ors +纹 çIJĨ +Ġd un +人 身 +æº ľ +p ixel +çļĦ æĢ§æł¼ +ä¸Ģ æĪĺ +åºķ çĽĺ +d ifferent +Ġcommun icated +Pl ayers +- center +reat ing +Ex c +Ġsp rite +, F +ĠLe eds +ä¹Ł æľīäºĽ +Ġinsight ful +it on +od al +ä»Ļ 女 +Ġbread th +Ġres ides +Ġinter med +V o +å¥ĭ åĬĽ +Ġfor fe +Ġcard board +åĪĨ åĮĸ +社ä¼ļ ä¿ĿéĻ© +ãĢģ 被 +éĻª ä½ł +åħįè´¹ çļĦ +ĠPen insula +Ġt ensions +ä¸į 许 +Ġquot ient +Ġcongress ional +P CR +ĠK ra +ib s +ĠS OC +Ġinvestig ator +ĠS ax +vis ory +ĠB rowse +Ġterm inals +ĠLog o +Ġcub es +èĻ Ķ +ภģ +ï¼Į é¼ĵåĬ± +_b egin +ÏĦ ι +iv el +Ġcred ential +HasColumn Type +oc ities +M i +æĢª å¼Ĥ +st ates +åĽ½ åħ¬ +Ġbud d +' D +so ftware +Rear range +Ġtran qu +è´¢ çī© +Ġcl ash +ö n +åĪĨ 身 +ç«Ļ çļĦ +Part ners +B urn +Ġsu ites +åıĺ çݰ +æīĢ è§ģ +è§£ çłģ +èIJ½ åı¶ +\in fty +ç¬ij èĦ¸ +Ġso ak +ç¼ĺ åĪĨ +/ public +çļĦ èĤ©èĨĢ +ĠH uff +Ġdimin ished +å°Ĩ è¿Ļ +pro blem +Ġnick el +åĮºåŁŁ åĨħ +åIJİ åĭ¤ +äºĨ å¤ļå°ij +éĿĴ é¾Ļ +æĥ³ åĥı +ĠRes istance +ĠJan et +Ġmap le +åĵĪåĵΠ大ç¬ij +ĠLi ability +èĦijæµ· éĩĮ +ä¿Ĺ ç§° +M N +è¶Ĭ éĩİ +âĢĿ ; +Ġorgan izer +ast ore +ĠBry ant +ĠExper iment +Ġ} { +å¾IJ å·ŀ +ic ides +ä¸Ĭ åľº +æĥ³ æĿ¥ +Ġali ens +M agic +AP TER +Ġex quisite +Ġconst ituted +ol ang +ä¸į ä¼ij +vers ed +Ġs way +ï¼Į大家 éĥ½ +Ġl odge +block List +cc i +çĨ ł +ill as +å¤ļ 大çļĦ +l ittle +ĠPrinc eton +äºĨ åįĬ天 +Ġcol oured +_H AS +å°± æĪIJäºĨ +ç͍ åľ¨ +rote in +æĬµ 御 +_RES ULT +ç͍ 以 +Ġvulner abilities +ï¼Įæĺ¯ 个 +伪 è£ħ +çļĦ åģ¥åº· +Ġstim ulating +ĠGovern ance +Ġjour neys +计ç®Ĺæľº ç¨ĭåºı +Ġ èĩªå·± +ĠC af +J et +Ġhur ricane +Ġmiser able +\ ge +æ¼Ķ åıĺ +ĠCol our +åĩĨå¤ĩ å·¥ä½ľ +-s aving +Ġretros pective +col m +Ġrefere ndum +æĺ¯ ä»ĸçļĦ +个 æķ° +ĠL or +å¥ł å®ļäºĨ +Ġmem set +ĠSupp lementary +(f irst +æĶ¾ æīĭ +Ġhun ter +Get ty +Ġelim inates +ĠZ ion +缸å½ĵ çļĦ +Ġqu arry +ĠW ade +}} }\ +Ġrec alls +éī´ åĪ« +äºĮ æŀģ管 +AL K +_BY TE +W inter +ĠWat ches +Ġcooper ate +Cl imate +éĶĤ çĶµæ±ł +ä¸Ģ个 éĹ®é¢ĺ +- word +ĠI v +丼 æŀĹ +ï¼Įå¾Ī éļ¾ +Ġsk ies +çľĭ åľ¨ +äºĮåįģ äºĶ +è¯Ĭ æ²» +th ird +_A UTH +è¾½å®ģ çľģ +ĠL ud +åĮ» ç§ij +Config ure +æĺ¯ä¸Ģ æł·çļĦ +ĠP ATH +驾驶 è¯ģ ++ ) +ij a +Fin ance +Imp lementation +ĠAut hentication +Ġra id +è¿ŀ 带 +Ġcont raction +Ġen velop +MENT S +ç«ĭæĸ¹ ç±³ +ĠK or +.res ource +Ġra iny +åĨ² åĪº +çª ĸ +Sil ver +好 ä¸į容æĺĵ +æĪij ä¸Ģ +毫 åįĩ +ï¼Ī åĽĽ +ĠRe ach +è½» éĩį +æĻļ æľŁ +_ low +ï¼Į åŃIJ +Ġ æķ° +å¿ĥ éĩĮçļĦ +Ġinj unction +Ġseiz ure +_ edit +åѤ åįķ +é¢ĺ èĢĥæŁ¥ +ĠD irections +ĠC W +ä¸į å±ŀäºİ +Ġmechan ic +Dam age +äºĨä¸Ģ éģĵ +绵 绵 +t cp +ç¡ķ士 åѦä½į +奢 åįİ +ect omy +ident ified +Ġmac ros +avil ion +Ġso ils +_s a +ï¼ĮéĤ£ æĪij +Ġentrepreneur ial +Sw ap +ï¼Į 沿 +ãĢĤ æİ¥ä¸ĭæĿ¥ +ÃŃ n +æįIJ 款 +çŁ¥éģĵ ä½ł +è°ĥ åζ +åħļ ç»ĦæĪIJåijĺ +è¯ £ +Ġac claimed +C OPY +ĠComp et +ĠViet namese +Y Z +çļĦ 建议 +åľ° 为 +å®ļ éĩı +çļĦä¸Ģ åı¥è¯Ŀ +Ġdispos able +飩 å®ĩ +ĠK iss +Foot er +T ODO +Ġback bone +ãĢĤ åİŁ +åľ¨ 没æľī +Ġmut ants +Ġv ow +.f loor +å¹´ 以ä¸Ĭ +å¿ĥ äºĭ +P urchase +ĠChe ster +Ġelectro ly +( address +AT TR +çIJĨè§£ çļĦ +ãĢĤ ä¸įä»ħ +ï¼Į åĨĽ +ä»Ģä¹Ī æł· +è ³ +æļĸ æļĸ +èģĨ åIJ¬ +(" ./ +æĸ° é«ĺ +Ġfin ale +osc opy +Ġpay out +æľį çļĦ +ï¼Į ç»ĻæĪij +comp ressed +ä¸ŃåĽ½ è¯ģçĽijä¼ļ +Ġhum id +Ġdec oding +æŃ» 人 +t imer +è¶ģ æľº +åľ° 毯 +Ġacc ustomed +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +æµģ æĺŁ +ĠRh ode +ä¸ĵ èģĮ +ram er +ï¼ĮåIJİ èĢħ +ĠL ET +Ġconduct ivity +get Value +. player +çļĦ é¡¶éĥ¨ +æĹł å°½ +ĠL R +éģĹ è¿¹ +ĠF oo +lo o +et ween +pat ched +_s ingle +Ġded uction +.s in +mod ern +Ġdis ks +è¡Į åĪĹ +æ³ķ åĴĮ +ĠM age +å® ¦ +éĺ¶ æ¢¯ +ĠG ather +ĠBl air +æľ¬ é¢Ĩ +ing ing +Ġfriend ships +rt c +å±ĭ åŃIJéĩĮ +æIJŀ ç¬ij +ĠVis itors +é¦Ļ èķī +åįķ 车 +ĠCan al +ĠW rap +åı¯ ç͍äºİ +ĠStand ing +ath a +Ġpitch ing +( project +c ool +å¸ĥ æľĹ +ï¼Į 建 +-f lex +èĥ¡ æ¤Ĵ +lict ed +Ġretain s +Ġcol s +Ġske leton +ï¼Įä¹Ł ä¸įèĥ½ +åĩī çļĦ +D NS +ĠIraq i +å·¥ç¨ĭ æĸ½å·¥ +_ axis +æĪij æł¡ +Fix ture +两 åįĥ +ç²¾ç¥ŀ çļĦ +äºĨä¸Ģ ä»¶ +Ġmar sh +bol ic +. [@ +Ġon Click +Ġsupp orter +e ither +æĬ½ çĥŁ +ĠAndrew s +çĭ © +document class +in ality +ĠLess on +ĠBuff ered +amm ers +两 çϾ +è´µå·ŀ çľģ +伺 æľį +Ġint ellect +åįĬ 身 +ĠRoof ing +ĠVen us +æĭ¿ åΰäºĨ +Ġacad emy +Ġspons orship +åŃ ° +è§£ èĦ± +Ġch ord +N PC +ĠPref erences +ĠM ood +Ġtut or +/ month +ĠT ennis +Ġant it +Ġyield ed +Ġlear ner +åħ« 个 +åĬłå¼º 对 +æłĩå¿Ĺ çĿĢ +ĠR EL +>< ? +.Tab Index +.Fat alf +Ġg land +æĭ¼ éŁ³ +Ġwheel chair +Ġbl ends +åIJį æ°Ķ +Ġelectro des +ï¼Į å·®çĤ¹ +èģĶç³» æĪij们 +辩 论 +Ġठķ +Ġclin icians +Cele br +Ġto do +æīĵ åį¡ +士 æ°Ķ +________ ____ +çļĦ è¿IJåĬ¨ +ĠSud an +ä¸į å®Į +Ġcock tails +Ġstra ps +ç¬ij å¾Ĺ +ĠM orm +è¿ŀæİ¥ æĿĨ +oc om +post s +_N ET +çĬ¶ åħĥ +". $ +F ant +åĵģ ç±» +害 ç¾ŀ +æĥ¬ æĦı +Ġs sh +åζ çīĩ +Ġb ark +up on +åŁºæľ¬ æĥħåĨµ +å¦ĸ æĢª +åįĹ å±± +çļĦ æĪ¿éĹ´ +ä¸į ç»Ļ +èIJ ¤ +Cl inical +ãĢģ å®¶åºŃ +âĢľ They +éĩįè¦ģ æĢ§ +Json Property +FF F +ì ķ +Ġv ain +ä¸İ åIJ¦ +ĠRect angle +end id +Ġdis covers +ĠA ra +Ġch im +åħ± èµ¢ +åĪĩå°Ķ 西 +ĠKash mir +ĠH av +çĹħ çIJĨ +ĠD rivers +(t itle +end ars +p v +ä¸į è¿ľå¤Ħ +æĹł æľº +çļĦ人 æĿ¥è¯´ +O x +Ġdeep est +Ste am +Ġspecific s +, äºĮ +对 æĪĺ +ç¾İ çϽ +Ð ŀ +ï¼Į é¡¶ +çļĦ æĿİ +åĩº 示 +[ S +ĠP iece +ï¼Į çζæ¯į +, u +ĠD uck +ãĢĤ 建议 +Ġher s +ĠC ul +导 游 +ãĢĤ 西 +好 æ¶Īæģ¯ +ĠOrigin ally + Į +ç»Ĩèĥŀ çļĦ +ĠF usion +Ġpe an +å¤ļ 说 +å±Ģ å±Ģéķ¿ +åĩĿ åĽº +L ord +åľ¨ è¿Ľè¡Į +æķĻ ä½ł +ĠAss ist +erm al +çľ¼ è§Ĵ +æĪij们 æĺ¯ +ç¼ħ ç͏ +åŀ £ +Ġiter ate +Ġc trl +Ġdef enses +对 åĩĨ +Ġdisc ard +Ġmedic inal +女 主 +ball s +ĠBang alore +_ os +Ġbl ur +ĠNOT ICE +ï¼ļ éĢļè¿ĩ +Ġre consider +Pr inter +ĠSp ell +大 çģ« +ãĢģ ãĢģ +åľ° è¿Ľè¡Į +_S RC +enz ie +.f ont +t ok +Ġa ce +é¢Ŀ å®ļ +M n +Ġhistor ian +Ġ" & +ĠK urt +rap ist +éļĨ éĩį +ãĢĤ 许å¤ļ +æł¼ æł¼ +å»¶ æľŁ +Ġmon key +Ġpar ity +Ġc ate +-w ater +Ġtoler ate +Ġignor ant +ï¼Į çļ® +Ġve ins +S ounds +RE Q +Ġcode c +ĠBr ush +ĠNob le +ï¼Ľ ä½Ĩ +cre ation +Ġles ion +/p ost +ig raph +ï¼Į è´¨éĩı +è¿Ļ æĶ¯ +æĪĺ 绩 +d al +fe atures +ra ising +W K +æĸ° ä¸Ģ代 +ĠD ict +ĠDes igned +ä¸Ń è·¯ +ĠFun ny +) == +æ¼ © +åIJī å°Ķ +Ġc mp +被 è¯Ħ为 +Ġcollect ors +- string +ä¹Ł åºĶ该 +ä¸İ æŃ¤åIJĮæĹ¶ +åIJĪ å½± +æĺİ æľĿ +ðŁ Ĵ +ĠSch ol +] -- +人 ä½ĵçļĦ +Ġ æłĩé¢ĺ +Ġsu cks +åĪĢ åħ· +-t ool +çŁŃ çļĦ +ç¨İ è´¹ +Ġyoung sters +_sh ort +åĬ¿ 头 +ur on +ĠIm aging +ä¹ĺ 车 +æĬĹ ä½ĵ +.char At +Ġm unicipality +ĠA SP +.c al +Members hip +\ p +Ġs ar +以 èī²åĪĹ +(d st +J osh +ĠS oup +æĶ¹ è£ħ +ĠFarm ers +饿 äºĨ +_d ouble +æĬĵ èİ· +éĿĻéĿĻ åľ° +éĿ¢ä¸´ çļĦ +âĸ ³ +Ġlean ing +[ f +å§ij å§ij +- es +( åį³ +ĠDISCLAIM ED +T her +åĸ ½ +åĤ¨ èĵĦ +èĦ± æ°´ +æŃ¦æ±ī å¸Ĥ +Ġor phan +Look s +Ġsin us +åħ¬ è¯ģ +Ġcar riage +_ sequence +Ġbow el +ï¼Į ï¼Į +ĠL ANG +.c apitalize +¸ ÃIJ +ĠSk i +af il +  +Ġwag ering +Ġdile mma +è¶´ åľ¨ +éĩı 大 +èĹı çĿĢ +æĸ¹åIJij çĽĺ +ĠG ang +ĠSus p +ï¼ĮæīĢè¿° çļĦ +ĠSpot light +å»ī æĶ¿ +N ight +Ġstand alone +Widget s +C irc +èķ ĥ +ĠS urre +ï¼Įå½ĵ ä¸ĭ +IB M +_err ors +ï¼Į åı£ +ace y +é¢ Į +çŃī ä¿¡æģ¯ +æľī æ¯Ĵ +Ġoblig ed +èĮ ¸ +ĠAP K +æĽ ľ +ug u +ĠTra iler +ï¼Į åħ·å¤ĩ +æĥ³ 让 +Ġatt ribut +è¯ļ æĦı +ĠAthlet ic +ĠRena issance +_C TL +ç¯ ± +Ġbit es +å¤ļæł· æĢ§ +Ġfoot er +ĠCapt ure +ĠS ak +éªĹ åŃIJ +ä»Ģä¹Ī 人 +ĠIns pector +ĠC urrency +èĩªçĦ¶ èµĦæºIJ +Ġf b +èģĶç³» 人 +ï¼Į å®¶éĩĮ +æĮĤ äºĨ +, åĪĩå®ŀ +qu ito +Ġfil med +ä½İ 碳 +Ġli en +ist ani +æĺĨ èĻ« +èī° è¾Ľ +西 æĸ¯ +Ġcr an +Âł æĿİ +enc ils +ãĢģ åIJĮ +è¿Ļ åĩłå¤© +夺 å¾Ĺ +ĠA PR +Ġclass ics +ï¼Į æĶ¾åħ¥ +äºī åIJµ +è´£ 令 +ĠBre tt +ç»ĵåIJĪ èµ·æĿ¥ +c ation +Ġ" // +ĠObs ervable +æĻ®éĢļ èĤ¡ +Ġestim ating +Ġä r +Word Press +Ġ æĹ¢çĦ¶ +ĠC inema +ï¼Į 硬 +ãĢģ èīºæľ¯ +大 å°Ĩ +ĠB irds +Ġ 计 +, éĻĪ +åĪĨ æŃ§ +Ġcounsel or +ä¹Ł éĥ½æĺ¯ +è¿Ļä¹Ī ä¹ħ +Ġg h +æijĨ åĬ¨ +.S erver +-------- - +.ch annel +Ġconc aten +æĭ · +riv al +ex isting +/ types +ï¼Į 横 +äºĴ åĬ© +ĠH erald +ä¼ļ å¾Ī +-pro duct +ï¼Į åĽŀ头 +Ġcallback s +. validate +åİĨ 代 +è°ĵ ä¹ĭ +æĻ¶ èݹ +IF O +: i +ĠMay a +Ġveter inary +ĠS eth +Ġc ops +Ġoff sets +ä¸įäºĨ çļĦ +åŃ£åIJİ èµĽ +\x c +Ġur inary +ç´§ç´§ çļĦ +( http +å¡ŀç½Ĺ éĤ£ +æľĪ 饼 +ï¼Įåį³ ä¾¿æĺ¯ +Ġa le +Ġqu artz +çľ¼ ä¸ŃçļĦ +Ġfacilit ates +ãĢĤ ä¼ļè®® +ĠApp ell +C ause +Elect ric +Ġm igr +ĠSpirit ual +d ialog +ç©¿ æIJŃ +ĠRead ers +Ġbi opsy +森 纳 +Ġpour ing +-dec oration +éĤ ĥ +ĠJew elry +P ipe +Ġcre ws +ĠI G +âĢĶ that +åĴ¨è¯¢ æľįåĬ¡ +-t ask +_k ernel +fil m +ãĢĤ ä½ķ +åħ¬ é¡· +- add +ighb ors +äºĭä»¶ çļĦ +éĩĩç͍ çļĦ +Ġcraw l +Ġo le +èµĦæľ¬ å¸Ĥåľº +ãĢĤ æį¢ +漫 éķ¿ +ï¼Į åIJ« +ĠDise ases +ãĢĤ æĢ»ä¹ĭ +æµģ æ°ĵ +P ix +åĽłä¸º ä»ĸ +ĠControl s +åĩº åľŁ +.sc roll +Ġwer den +ĠD rama +åĩĨå¤ĩ äºĨ +çĭ° çĭŀ +èIJ½ äºİ +\x a +è¿ŀæİ¥ æĿ¿ +Ġspectro scopy +ä¼´ æľī +è¿ĩç¨ĭ çļĦ +åĩº åĩ» +que ous +没 è§ģè¿ĩ +åĽ¾ çļĦ +æĺ¯ä¸Ģ 项 +çĹĽèĭ¦ çļĦ +çĿ¡ äºĨ +ĠMar co +éĤ£ä¹Ī çļĦ +æŀķ 头 +ĠW inner +fl ush +Ġfashion able +-p aced +çĴĢ çĴ¨ +ãĢĤ å°±åĥı +Ġsh uffle +Âł èĢĮ +.N ull +æĶ¶ äºĨ +åħ¬ çε +_R IGHT +Ġip hone +ri pe +veh icle +åıĺ èī² +Ġal ot +é«ĺ 空 +u ard +Ġethnic ity +åĮ» ç͍ +Ġenc rypt +ĠD ana +伤 äºĨ +-consum ing +èĥ¸ èĨĽ +ĠEX T +Ġmal aria +Ġgreet ing +ĠAdult s +-d igit +Ġmill iseconds +ĠIde al +B orn +ï¼Į 微微 +-g en +V PN +id ade +pp s +èĢģå¸Ī 们 +p apers +ภĩ +ĠEm irates +ĠChar leston +ĠM ate +æ¼ ³ +ver ting +å®Ĺ çļĦ +ĠKn ox +- search +.L ayout +è´´ å¿ĥ +Ġparad ox +ĠAp ost +çķĻ åѦçĶŁ +Ġphot ons +ip ient +äºļ åİĨ +ean or +ph inx +Ġan ecd +ĠSpect rum +åĨħ 饰 +è¹ ¬ +侦 æİ¢ +æŃ» èĢħ +b ucket +Ġin h +Ġw ander +Step hen +Ġw i +ĠR as +Ġdet ached +Type Def +缮æłĩ æĺ¯ +ish na +æİ¥åıĹ çļĦ +éļĶ çĿĢ +-ch annel +æĸ° 产åĵģ +Ġfac ets +d emo += . +æĮº 好 +_d rop +ĠRob ot +: c +Type Id +Ġmar row +_ printf +åĬ¿ å¿ħ +CD C +Ġqu arantine +Ġob ese +äºĴ éĢļ +ĠManag ers +Ġm art +ĠMar ina +ench mark +M ODULE +ä»ĸ们 æĺ¯ +Ġroyal ty +æļ§ æĺ§ +ãĢģ å¦Ĥæŀľ +æľ¬ æºIJ +æĥ Ń +ĠT L +ount y +Out er +RO C +.p ack +æĥĬ å¥ĩ +æĿ¾ äºĨåı£æ°Ķ +âĢľ èĢģ +ĠAr bit +ism et +å¹´ 份 +Ġì Ŀ +ĠS cope +ĠDon na +æ²¹ æ¼Ĩ +ĠF requency +åĮº åĴĮ +ĠDra ke +Ġattract s +v iol +æĬĹ æĭĴ +Anal ytical +ID D +ĠPay ments +ĠCom ponents +et ter +.get Text +Ġo st +b ai +çī¹ åĭĴ +åĩĿ éĩį +ĠEthiop ia +ind le +ĠLouis ville +h in +) < +åŃĹ åħ¸ +èĮ ¬ +ä¸ĵéŨ çļĦ +æľĪ æľ« +Ġlif ts +Ġbe ard +ä¹Ł æĽ¾ +ĠPublic ation +æĤĦ çĦ¶ +好 ä¹ħ +( width +, å¾Ģå¾Ģ +Ġstiff ness +æİī èIJ½ +ock ing +ĠU PS +èĦij ä¸Ń +åľ¨ 她çļĦ +æ¯Ĵ åĵģ +_sh ift +çļĦ ä½ł +ä¸ĩ è¾Ĩ +c ats +P ic +.f a +å¦ ³ +天 涯 +åIJĥ åΰ +Ġwithd rawn +_ ro +ĠCor respond +缴åįĩ æľº +. level +, çݰ +Ġposs essions +S weet +Ġincub ation +Ġasp iring +ï¼ļ ** +ĠVenezuel a +ag ents +OT A +èĢĥ åľº +Ġaccident al +å¹¶ ä¸įä¼ļ +ĠD ust +Ġreb ounds +Ġprompt s +æİ¥æĶ¶ åΰ +Ġsubstant ive +Ġpand as +æµ· 峡 +ï¼Į éħĴ +SC s +Ġspin ach +Ġbur nt +Ġafter ward +CS I +unt ary +Ġlim bs +åıį 转 +éĻĨ é£İ +åĮ»çĸĹ åĻ¨æ¢° +ĠR end +é¢ij é¢ij +Ġcontext ual +ĠDo ctors +æĤ¬ å´ĸ +ĠGo al +Ġd ancers +and em +æī¶ çĿĢ +ĠA mber +ç§ĭ åĨ¬ +Ġd warf +ãĢĤ åŁºäºİ +çŃī çī¹çĤ¹ +ä¾į éĥİ +ä½ľä¸º ä¸Ģç§į +Ġbreast feeding +ist rate +# a +æĬ¤ èĪª +Ġp ests +èµŀ åı¹ +Ġ à® +amb urg +ç»Ħ åĪĨ +ãĢĤ æľīçļĦ +æľŁ å¾ĴåĪij +Europe an +Ġpar an +æĶ» åĬ¿ +Ġdid nt +$$ , +æ± ¶ +ç¼ Ń +, éĩij +O E +å°ı å§ijå¨ĺ +æ²ī åIJŁ ++ / +B rown +-t oggle +人 å¤ļ +Ġbear ings +ï¼Į é¢Ĩ +Ġso othing +pr im +æĿĢ çļĦ +Ġadvis able +Ġexpos ing +.con vert +, -- +ĠConc ert +ch oose +ie g +Al bum +ĠMag ento +ĠRedist ribution +ts y +Ġconduct or +od or +ĠDay ton +att achment +æĭ¥ æĮ¤ +S cheduler +æīŃ è½¬ +. emit +con g +ipp ets +å̾åIJij äºİ +Ġsystem atically +ĠRuntime Exception +ä¹Łä¸į åı¯èĥ½ +ä½Ĩä¸į éĻIJäºİ +åľŁ æľ¨ +Ġexcer pt +ĠH DMI +Ġ ç½ij绾 +Ob viously +Ġmethod ologies +stan bul +ĠAg es +è¦ģ å°Ĩ +_ plugin +ĠS age +å§Ķåijĺä¼ļ å§Ķåijĺ +ĠM ang +æĽ² æĬĺ +å¤ı æĹ¥ +åĵĪåĵĪ åĵĪåĵĪ +S oc +Ġpan or +ç©¿ äºĨ +iff any +, åħ¶ä»ĸ +ĠMor rison +W HERE +Ġdef er +æĪĺ æľº +Ġsoph omore +fore ign +â ¼ +é m +èįĨ å·ŀ +ĠOrth odox +Ġtruth s +- che +ä¸Ģ å¾ĭ +Ġch ars +.W idth +(res ource +_C PU +æĹ¶éĹ´ 段 +ï¼ĮåĽłä¸º å®ĥ +et ches +èĢĮ éĿŀ +ĠUN IT +ĠHig gs +ĠComm ander +K W +Ġrem ovable +ĠM inecraft +sw orth +éŃĶ çİĭ +ĠC aps +ĠCh oices +车è¾Ĩ çļĦ +ĠRecogn ition +ĠS par +Ġfollow er +per p +q t +ãĢģ 第ä¸ī +und ing +çĿ£ æŁ¥ +[ N +åħī è¾ī +_c lock +Ġwarrant ies +ĠVac ation +éĵ¶è¡Į çļĦ +Ġautom ate +rim inal +. an +Out side +åѦéĻ¢ çļĦ +æľī å°ı +ĠRed uction +ĠFreder ick +éª ¸ +T G +[ MAX +m aterial +Aut hent +âĶ Ĥ +æĬķèµĦ æľīéĻIJåħ¬åı¸ +ĠConvers ation +( addr +ï¼Į 临 +Ġviol ating +åŁ¹è®Ń æľºæŀĦ +Ġ ä¸įæĺ¯ +éĩį åıł +è¾ĥ éķ¿ +åı« çĿĢ +è¿Ļ个 æł·åŃIJ +ĠGr inding +ï¼Įå½ĵ å¹´ +it one +æĽ´å¤ļ çļĦ人 +ac ier +æľĢ å°ij +is ol +为 åħ¬åı¸ +Ġcul p +ex ico +Ġri pe +æĺ¯ä¸Ģ éģĵ +å°± è¿ŀ +åĩł åIJį +Ġassist ants +åįļ士 åѦä½į +, åıĬæĹ¶ +ĠD ylan +Ġdeleg ation +马 è¾¾ +circ le +ĠBib lical +Ġd rones +åıĹ æīĺ +Ġp iss +Creat ive +Ġ çī¹ +ty ard +èµ° åĩºæĿ¥ +æĢ§ çĸ¾çĹħ +_P I +çŃī åĨħ容 +Ġped al +èĬĤ åģĩæĹ¥ +. return +ä¸Ń 使ç͍ +Ġb ait +ĠP our +_M ULT +éĩİ åħ½ +èĥĨ åĽºéĨĩ +ç¾ Į +Ġamb assador +Ġneut ron +满æĦı 度 +æĹ© æĻļ +, åħ¨éĿ¢ +st ated +,è¿Ļ å°±æĺ¯ +ext end +è§ģ åΰäºĨ +atisf ied +ĠDru gs +- App +Ġsub license +èĩªçͱ çļĦ +æ·¡ çĦ¶ +ĠTH REE +.C OM +Ġpill ows +ĠRe agan +, å¦Ĥä½ķ +Ð Ŀ +é es +Ġrevis ions +Ġb isc +ä½ ¼ +Ġdis like +ĠCon version +ãĢģ å¹³ +inet ics +ï¼Į äºĭæĥħ +åľº åĿĩ +ä¼łè¯´ ä¸ŃçļĦ +ä¹Ł ä»İ +ĠÏĦ οÏħ +B right +Ġpercent ages +æľ¬ éĩij +æľ¨ è´¨ +ï¼Į 奥 +缸 ä¼¼çļĦ +ç»ıæµİ æķĪçĽĬ +åĨľ ä½ľçī© +ĠCS V +æł¹ åŁº +æĽ Ļ +åŁºéĩij æīĺ管 +J am +Un signed +Ġwonder fully +ঠ¾ +Ġrec ount +大 æĥĬ +Ġsched uler +Ġ æľª +æ±Ł å¸Ĥ +å¥ĸ åѦéĩij +th us +çļĦ å°Ĩ +.T ag +é»Ħ èī²çļĦ +ï¼ĮçĦ¶åIJİ åľ¨ +op last +W onder +ä½į å±ħ +æĻ¶ä½ĵ 管 +éĶĻ è¿ĩäºĨ +èģª æĺİçļĦ +f actory +n umeric +on ne +Ġhome owner +ĠL M +or por +Ġhug ely +Ġu v +æ¯Ľ åŃĶ +ä¸ĸ ä¿Ĺ +ip ort +ä¸ĸ æ°ij +Ġsolid arity +è¡ĮæĶ¿ å¤Ħç½ļ +ĠG iant +ĠBe ast +æij© å°Ķ +* { +æİĴ åľ¨ +è¿Ľ é£Ł +æĮĤ éĴ© +Ġl ust +erc ase +Ġcom eb +Ġvolunte ering +éķ¿ å¯¿ +æĢ§ æĥħ +Ġestablish ments +Ġrev olves +ĠT akes +Art ist +, è¦ģæ±Ĥ +Ġì ŀ +\ gamma +-l g +Ġp es +ä¸Ģ å¹ħ +ĠF loyd +åħ¬ ç«ĭ +ĠCor rect +Ġmultipl ier +IN IT +å¿į çĿĢ +å°ı说 ç½ij +Ġp ly +eb ooks +ĠEp ic +ĠMar shal +j ay +èµ· åΰäºĨ +第ä¸Ģ åIJį +| c +ox el +ĠBr isbane +let ely +id able +/ com +_ contents +ĠN G +Ġfore going +ä¸į è¨Ģ +åĨħ ç§ij +æĤ£ çĹħ +çļĦ æĪĺæĸĹ +best os +楼 å±Ĥ +_OP ER +ĠDom estic +Ġtop ical +åıĮ èħ¿ +大 åĸĬ +Ġhe n +ĠN RF +å¾Īæľī åı¯èĥ½ +ï¼Į åĨ° +Brit ish +è¾ĥ å·® +ĠGu inea +åĢį çļĦ +å¡« åĪĹ +ĠLast ly +ĠMax well +ä»ĸ éĤ£ +åIJĥ ä»Ģä¹Ī +Ġ... , +Rep orts +Ġ( ~ +hes es +Pref erred +å¥Ĺ æĪ¿ +çľĭ ä¸įåĩº +éĹ² ç½® +转移 åΰ +èIJ½ æĪ· +, ç»ı常 +à « +_t imestamp +夺 åıĸ +Å ³ +å®° 缸 +端 åŃIJ +ĠD AY +âĢĿ æ´»åĬ¨ +( ** +Ġ éĿ¢å¯¹ +亨 åĪ© +产 çļĦ +请 éĹ® +ĠA ggreg +ĠStar bucks +Ġw ager +Ġvert ically +, æĪij们çļĦ +ĠT x +_d one +Ġtoss ed +åĪĹ ä¸¾ +P ur +ĠAl umni +ob l +æĴķ è£Ĥ +ãĢģ ç§ijåѦ +åIJij ä½ł +Ġmim ic +ĠGet ty +E ye +. lock +ä¸įå¾Ĺ å·² +æ¯Ķ ä½ł +ï¼Įå°Ĩ åħ¶ +ãĢģ éĢļ +ï¼Į éľ²åĩº +ç͵åŃIJ éĤ®ä»¶ +Great er +.d oc +' n +m is +çľ¼ çļ® +Ġret val +Oh io +M other +ĠHam mer +ãĢĤ æľĢè¿ij +çķĮ éĻIJ +ĠFun eral +st mt +åħī çħ§ +çļĦ主 ä½ĵ +æľī è¿Ļä¹Ī +为æĤ¨ æıIJä¾Ľ +Ù ı +Ġge ared +èµ· åĪĿ +ĠHero es +ãĢĭ åıĬ +.App lication +ĠBou levard +M aps +$$ . +åıijè¡Į çļĦ +æĹł äºĭ +Ġtext ile +DU CTION +al most +ol lection +Ġpres idency +èľ ķ +ĠChev rolet +åģļ å®Į +Ġinf l +F red +表 çļĦ +å¡ij èĥ¶ +ĠR iv +ĠAbs olutely +ä¸ĩ ä¸ĩ +Ġw izard +æĽ´ åħ· +大 为 +Ġrep ent +ä¾ ¥ +ç¿»è¯ij æĪIJ +Ġgi ants +Ġt au +, åĬłä¸Ĭ +åĬŁ å¾· +追 éĹ® +éĹº èľľ +éĿĻ æŃ¢ +éĩİ å¤ĸ +-ser if +æĹł 表æĥħ +Adv ice +Ġhop eless +Un icode +S imply +麻 æľ¨ +Ġful fil +Ġcongest ion +V e +ENS OR +ĠSt a +éĻħ åħ³ç³» +Ġpain ts +æIJ¬ å®¶ +ĠPl atinum +ï¼Ľ 以åıĬ +ac ao +âĢľ åĵ¦ +Ġf use +Ġspe eches +åıijçĶŁ é¢Ŀ +Ġdream ing +Ġr ugs +èĽ Ł +.y outube +æĤ² åĵĢ +, ä»ħ +使 ä»ĸ +ï¼Į é¦ĸ +-p urpose +yn n +pl ants +, H +ï¼Į 个人 +Ġde cks +M ini +漫 éķ¿çļĦ +- loop +ĠF CC +Ġag gression +ĠC andy +âĢĿ âĢĶâĢĶ +ãĢĤ å°¤åħ¶ +宫 女 +ĠQUEST ION +F ashion +Ġà º +h arm +äºĭ 迹 +(w indow +æ¼Ĥ æµ® +ï¼ļ [ +æľī èĩªå·±çļĦ +ĠScal a +ĠRelations hips +浦 举 +åĨĻ åĩº +é¢Ŀ å¤ĸçļĦ +Ġ ç͵è¯Ŀ +è¿Ļ个 åIJįåŃĹ +and ro +æĢ§ ä¸İ +æľī èĥ½åĬĽ +Ġterr ifying +Pred icate +ĠÐ ¡ +è¿Ļ åIJį +ard on +ĠR ut +ĠCurt is +ä¹ĭ 主 +tr ad +Ġru ined +F ee +Def initions +ä¸Ģ åΰ +otyp ing +lo ver +ĠA MA +çģŃ äºĨ +ï¼Į çľ¼åīį +ap id +Ġsynthes ized +é£ĺ é£ĺ +头 æĻķ +ä¸Ģ åĽŀ +ĠD ates +Ġuniqu eness +èĩªå·± åĴĮ +Trend ing +åľ£ åľ° +æµģ æ·Į +Ġdish washer +TH IS +éĿ¢ 缸 +A zure +res ize +ĠG ir +Ġrece ivers +è¿ŀæİ¥ åΰ +Ġabs or +. we +éĢļ 红 +ĠÐ Ł +å½ĵ ä»ĸ +丰å¯Į å¤ļ彩 +Meta Data +ĠRoche ster +Ġskept ical +ï¼ħ çļĦ +( sh +S port +ĠMay o +ĠTrans it +éĹ´ æĸŃ +æĶ¾ äºĨ +ĠSee k +ĠNetwork ing +äºĽ 许 +âĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶ âĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶ +ç©¿ æĪ´ +èİ« æĸ¯ç§ij +éĶ ° +. ne +; č +ä¸į ä½ľ +æ· Ħ +Ġec ology +å®Ŀ çī© +ç»ij æŀ¶ +ĠR oh +ĠR x +, æıIJåįĩ +ot le +Ġswe ater +hy de +ters on +ãĢģ èµµ +gener ic +ĠNot Implemented +Ġto mb +Ġprob es +ĠPB X +æħ · +å·¥ç¨ĭ 建设 +S ong +ĠLoc ations +ur acy +ç¯ Ĩ +帮 她 +ï¼Įè¿ĺ éľĢè¦ģ +.st ore +ï¼Į 究竣 +ip ur +-in spired +ch in +åĩº æĪĺ +ĠMed al +ĠPil ot +Sp in +èĭ¦ éļ¾ +Ġter ribly +åķ ° +ĠAss ign +Ġchrist mas +.b uffer +æĮ¡ ä½ı +ĠM ixed +æİ¥ 线 +çłĶç©¶ åĴĮ +-s olving +æĹ¥ åŃIJéĩĮ +et z +Ġsung lasses +éŀ ĺ +Ġacqu aint +ï¼Į éĿł +che my +Ġinf amous +ĠInd oor +At A +ä»įçĦ¶ æĺ¯ +Ġincrement al +ĠC MD +Ġun even +ĠS pl +.get Type +oll a +ĠA mer +å¸Ĥ éĿ¢ä¸Ĭ +èĸ ° +åĩº ä¼Ĺ +_ ui +对 ä½łçļĦ +ST EP +宫 å»· +Ġdil uted +æ°ij èIJ¥ +.p ers +èĢģ 夫 +_RET URN +åŁºçĿ£ æķĻ +develop er +Ġstr ang +ĠP ix +Ġind emn +, E +çļĦ æ¯į亲 +æij¸ æij¸ +ï¼Į 亲 +en os +Ġgro ove +绣 绣 +Ġcoc oa +Ġgast ric +Ġra ils +éĺµ æ³ķ +ĠPark inson +ĠAd rian +th ought +å¤ļ è°¢ +( æĪĸ +Log o +Ġcytok ines +æĹ© å·²ç»ı +åĸľ çαçļĦ +(h andle +车 éĩĮ +.con v +æ¸ħ é£İ +çĸ¯ åŃIJ +Ġp add +Ġrem and +éĢı äºĨ +éĽª èĬ± +Ġvisual s +ack er +èĢIJ ç͍ +åħ¥ æĪ· +æĸ¯ èĴĤ +Ġline arly +IZ ED +åĪĩ çīĩ +. annotations +ĠG or +é¦Ļ çĥŁ +åį¡ æĭī +æĬ½ åıĸ +äºĮåįģ å¹´ +é³ Ħ +umb ent +Ġ* )( +Ġsel dom +UG H +Ass ociation +ï¼Įåį´ è¢« +æĢĢ çĿĢ +_T OKEN +-b and +æ¯ķ竣 æĺ¯ +'' ' +çļĦ æīĭæľº +_c sv +ĠIde a +æīĢ è¨Ģ +éĿŀ常 好çļĦ +Ġ ................................................................ +ch aft +ĠDem ocracy +ĠDep ot +æīĢè¿° 缮æłĩ +_ - +è´¯ éĢļ +r unning +Ġel apsed +å¢ŀéķ¿ çİĩ +ĠRew ards +Ġ á +Offic ial +- Star +ĠER P +ï¼Į AI +mod ified +T AG +ra ils +å°ı åѦçĶŁ +æµģ éĢĿ +_B E +head ing +åĽ½ ä¼ģ +aj i +ç³ ľ +ern s +ic er +ãĢĤ çľĭåΰ +ãĢģ éĺ¿ +ä¼ļ æĽ´ +ĠCounsel ing +reg istry +.N ext +Ġdivid ends +Ġscr ub +ell es +åĨĽ èIJ¥ +I gn +ĠP icks += y +èĪª æ¯į +ĠRol ling +ĠAp ollo +ãĢĤ æĪĸ许 +使ç͍ æĹ¶ +Material s +Ġend uring +ATION AL +om nia +arn a +ãĢĤ åįĹ +å¹² éļĨ +ä½Ļ åIJį +- opt +åŃ¦ä¹ł æķĻèĤ² +ĠSecond ly +claim s +ĠW WE +Ġflaw ed +Ġpreced ed +Ġday light +éº ĵ +éĶģ ç´§ +pro j +çļĦ 第 +ĠG ig +aj o +éĢļ åijĬ +é g +ä¼ ¶ +ĠSur ve +ä¹İ ä¹İ +.In ternal +NY SE +åĨĴ çĿĢ +ĠBack up +H air +çĥŃæ°´ åύ +å±Ĭ åħ¨åĽ½ +-le arning +æĿī 磶 +Ġdev otion +Ġgroup ing +Ġdetect ors +t one +um ab +Coll apsed +åıĤ æ¼Ķ +Ġdispl aced +Ġg arn +ĠPalest ine +J e +ĠA E +Ġal coholic +ãĤ Ń +亮 äºĨ +è¿IJåĬ¨ ä¼ļ +Ġobserv ational +c ause +ĠG ut +..\ ..\ +ĠD w +çĭ¬ åѤ +æIJŀ å®ļ +min imal +æĹ¶ è£ħ +ĠMar ks +_path s +ĠFore ver +å·¥ä½ľ æĹ¶ +Ġsub division +åī¯ æĢ»è£ģ +ĠB TC +l ime +roid ery +ger ies +åŁºéĩij åIJĪåIJĮ +éĹ® åĢĻ +Ġinstall er +Ġè¿Ļ 次 +ist ro +åģļ åĩºçļĦ +ĠEd en +Ġmacroph ages +æĮī åİĭ +æī¾ ä¸Ģ个 +好 çİ© +ĠMark ov +Ġmus cular +s pecific +.Char Field +å·¥ åĮł +ĸ ´ +ĠYan kees +ä¸īè§Ĵ å½¢ +åģļ 为 +ä¾µ èļĢ +Ġexped ition +Ġbl amed +Ġphys ic +respons ive +Ġv es +Ġerrone ous +æĹ§ çļĦ +Ġhyp oc +.J oin +] ãĢĤ +ĠH ist +ĠS ach +Ġsim ulator +Pro duction +Ġп о +ен ие +ĠF erguson +ĠD iane +åħī æĺ¯ +ĠB ios +ä¸Ģ è´¯ +Ġr uler +Ġexempl ary +An th +amb ia +åĨħéĥ¨ æİ§åζ +ĠAtt empt +Ġpul ses +, K +Ġafter math ++ k +ä¼ł 导 +, G +not ification +ur ate +Ġfertil izer +Ġgather ings +Ġm v +Open ing +å¢ŀ åİĭ +转 æĬĺ +第ä¸Ģ ä½į +AC A +Ġ æĸ¹æ³ķ +åıij æ³Ħ +æĸ° åĵģ +unc iation +å®ŀæĸ½ä¾ĭ ä¸ŃçļĦ +åľ¨ 对 +åľ¨ èģĮ +åķĨ éĵº +çł´ æįŁ +å±± è·¯ +Ġconstitu ents +æĬĬ æĪij们 +Ġcommod ities +Ġvac ant +èı© æıIJ +av ad +访 è°Ī +ï¼Į没æľī 人 +æ²»çĸĹ çļĦ +å¡« è¡¥ +Ġch an +æĬĹ åĩ» +:: { +æĺİ æĻº +Ġw orm +çŁ¥ ä¹İ +Ġde eds +DE P +京 å¸Ī +Ġindic ative +Ra ises +Ġ éļıåIJİ +Ġpl atinum +æIJ IJ +åħħ å½ĵ +Ġj est +æĹł è¨Ģ +å½ĵ å±Ģ +ï¼Įåı¯ è°ĵ +é« ¦ +ï¼Įå¹¶ ä¸İ +IS P +Ġom n +ruct uring +èĥĮ éĿ¢ +ï¼Į 第ä¸Ģ次 +让 å®ĥ +ĠPo isson +ON SE +\x d +åħ³éĶ® åŃĹ +åĴ Ģ +å®Ŀ èĹı +室 温 +è¿Ł è¿Ł +ĠSt amp +人们 对 +m achine +çļĦ éĿŀ +åĴĮ åĽ¾ +Ġsil icone +ä»ĸ 没æľī +UL D +Ġch ili +V ision +谢谢 ä½ł +ï¼Į å̼å¾Ĺ +е Ñģ +æĬ¥ åºŁ +\x b +Contact s +Ġbre eds +æģį æĥļ +(f p +Ġsuper v +, åij¨ +Ġlaw ful +o it +ale z +Ġmod ifier +ĠGuarant ee +Ġdiff ering +R ose +ĠW arranty +ĠExper imental +ĠM au +éĺ» çĩĥ +_ACC ESS +ĠL aur +ĠComp rehensive +ĠAc ross +æ°§åĮĸ çī© +Ġmism atch +Ġst eward +Ġbarrel s +Ġl v +æijĬ éĶĢ +ï¼Į åĽŀåΰ +鸡 èĤī +Ġbl ink +L isa +n om +ä¾µ 害 +Ġthe aters +Ġstaff ing +ĠMus ical +ä¸ĸ纪 çļĦ +Ġl ibr +绣 é¢Ĩ +_S ERVER +I ER +Ġcompress or +èĬ ¥ +ĠBr ick +åįģ åĪĨéĴŁ +Ġent r +æ® Ĩ +å¹´ å¹´ +æ¶īåıĬ çļĦ +h ir +Ġbuff et +Ġeduc ating +Ġreal izes +æĿ¥ åİĨ +Ġbl ending +帮åĬ© ä½ł +éĤ£ 份 +Ġjew ellery +ST D +I Q +ĠBank ruptcy +çĦļ çĥ§ +åºķ èķ´ +iline ar +ĠW ald +post ed +ore an +Ġsyn th +< input +å¾ģ ç¨ĭ +åĴ½ åĸī +Ġmet eor +ï¼Į ç»´æĬ¤ +ĠT emplates +Ġ" ../../ +ï¼Ľ ( +ãĢģ åģļ +ä¸į管 æĺ¯ +ï¼Įä½ķ åĨµ +. ! +ä¹Ł æĺ¯ä¸Ģç§į +åıij åĩºäºĨ +Ġna ive +èѬ å¦Ĥ +in ety +ĠR G +Ġhierarch ical +' M +, æĢİä¹Ī +ï¼Į å¿ħçĦ¶ +è°ĥ æĸĻ +æŁ¥ æĺİ ++ a +id ge +ĠIn fl +Ġsidew alk +A void +åΰ äºĨä¸Ģ +Ġgr illed +.d om +ĠD ynam +T mp +èĵĦ çĶµæ±ł +En h +Ġje opard +.C lear +èĸĦ å¼± +éķľ åĥı +ï¼ĮéĤ£ æł· +ï¼Įä½Ĩæĺ¯ æĪij +ĠÏĦη ÏĤ +Ġp w +_H ANDLE +Ġment ors +éĥ½ æľīäºĽ +for Each +gen ic +Ġprev ailing +> (). +ĠEven ing +,éĤ£ å°±æĺ¯ +, é»Ħ +ï¼Į ä¸ĵ +产ä¸ļ åĮĸ +ĠUt ils +A bb +ĠCongress ional +n ial +ION AL +Ġcompens ated +ĠNON INFRINGEMENT +çĽĹ çªĥ +uc id +对 æľ¬ +AC Y +æĺ¾ èĢĮæĺĵ +_S ERVICE +( ID +Ġche w +ĠRe vel +åħ¨åĽ½ åIJĦåľ° +Ġaug mented +æĹ¥ æľĪ +ĠInvest igation +< D +å¤ĸ è´¸ +inds ay +ĠStra ight +ighth ouse +uff ed +l ords +ess ing +do ing +sever ance +Ġmile age +èĩ³åħ³ éĩįè¦ģ +æŃ» åľ¨ +ĠG ly +ç͵ å¹³ +Ġre location +éħįç½® 为 +åĬ¨ 人 +æ°´ 稻 +ĠAss uming +Ġaccomplish ment +ãĢĤ æµ· +ET S +åIJ¬ éĹ» +å¸ħ åĵ¥ +èİī èİī +æĹłæķ° çļĦ +ãĢĤ çĦ¶ +Ġtub er +ĠWhere as +commun ication +龸 çİĭ +Ġ" ") +æĪĸ 缺 +ï¼Į 建设 +-st ream +ç͵ éĩı +ĠEl astic +ĠPok emon +Ġboot strap +, æľªæĿ¥ +çĶŁæĪIJ çļĦ +-st ory +æľī åħ´è¶£ +Ġcon qu +Ġens ured +é«ĺ å±± +ĠReg arding +ĠH ear +ex ist +c ock +Ġdipl oma +º ÃIJ +讲 çļĦ +å¤Ħ éķ¿ +Ġp ac +Ġgro cer +) ... +Pol itics +app ro +æ´ĭ èij± +ä¼łæŁĵ çĹħ +) }} +_c al +ï¼Į 读 +ä¸įä¼ļ æĺ¯ +at ts +CR M +æŃĮ èĪŀ +æ³¢ æĸ¯ +Ġsty led +ĠCh oosing +Cont ain +ç¯ĩ å°ı说 +\ sub +Ġbelong ings +ä¸ĩ è¾¾ +VID IA +\ {\ +ï¼Į çIJĥéĺŁ +ï¼Į åīij +ĠBe en +Ġh alo +æĭ± æīĭ +Ġ ä»» +该 åħ¬åı¸ +Ġcent r +ĠNort heast +k v +Ġresc ued +æĭĵ 宽 +Ġeduc ator +åĨľæ°ij å·¥ +ç®Ĺ 计 +Ab ove +Ġlif ecycle +áĥ IJ +Ġnause a +. events +N ob +ĠComp act +大 åĸľ +èģļ ä¹Ļçĥ¯ +Ġprevent ive +Ġf c +ISS ION +- active +å¾· æĸ¯ +ĠAud i +ä¸ĵä¸ļ æĬĢæľ¯ +丰 æĶ¶ +è¿Ļ个 åľ°æĸ¹ +ious ness +(i i +еР³ +Ġcorrid or +Ġdef ended +LE SS +辨 认 +I OS +æĬ¥ åĪĬ +Ġ å®ģ +åĮĸ æĪIJ +Suppress Warnings +å¼Ģåıij èĢħ +Ġfasc inated +road s +N ature +\ langle +Ġcomplet eness +qu ality +ä½ł åĪ« +ä¸Ģ å¹¶ +太 好äºĨ +éĺ² å¤ĩ +Ġund is +çļ® çļĦ +, å°¤åħ¶ +.in voke +Editor ial +éħį ç͵ +éķ¿ å¤§äºĨ +çłĶ讨 ä¼ļ +O l +n ational +/p ull +ĠUn iform +æĸ°åĨł çĹħæ¯Ĵ +ï¼Į éģĩåΰ +Be en +Que en +项 éĵ¾ +de hyde +RA W +ĠInvest ing +Ġtra ced +p ieces +èĩ³ æŀģ +ast ype +èĢĮ æľī +ĠCro atia +ä¸Ĭ è¡Į +å°½ åħ¨åĬĽ +Ġreprodu ced +辨 åĪ« +ç§ij åĪĽ +Ġmot ives +) 为 +çĶŁ åĩº +Ġge om +æĺ¯ä¸į åı¯èĥ½ +AP S +. inc +Ġ 尽管 +ĠB ali +Ġsol itary +c annot +Ġang i +Ġmind fulness +ĠB ing +ndef ined +Transform er +ä»Ģä¹Ī éĥ½ä¸į +ĠProf it +& amp +conf irm +, è·Ł +太 å°ı +st reet +R etry +Ġbelie ver +ĠContin uous +\ ( +å¯Ħ åŃĺ +qu oting +汤 å§Ĩ +å¿ĥ æĿ¥ +m ant +Requ ire +ĠDoes n +:%.* ]] +ĠCfg Vehicles +å·¥ä½ľ åĴĮ +.m ath +.s ervlet +æ¶ Ł +Ġmore over +)) $ +ä¿¡ 访 +, * +Ġsh outed +ĠSee ing +oc ide +Ġslow ed +ãĢĤ 主 +ry n +Ġcompet it +æĿ¾ äºĨä¸Ģåı£æ°Ķ +å¢ĥ çļĦ +lu etooth +人 å°± +, çŃī +马 çļĦ +两 æŃ¥ +ĠOwn ers +ĠS ilk +/j ackson +éģį åİĨ +Ġep ile +åģı åIJij +ĠDEAL INGS +Ġ iz +: Get +ud os +çIJĨæīĢ å½ĵçĦ¶ +åĮĸ çŁ³ +Ġn ude +Ġatt ained +ĠLet t +ä¸İ 管çIJĨ +åĬ¡ å®ŀ +åıĪ ä¸Ģ个 +éŁ Ń +uch ar +ĠRe plies +åĽ´ è§Ĥ +åıĤä¸İ èĢħ +-l anguage +举 è·¯ +æĬķèµĦ æĶ¶çĽĬ +人 éĢī +çľĭçĿĢ æĪij +, èĩªçĦ¶ +L AND +ĠS ymphony +Ġinterpre ter +- The +åľ¨ä¸Ģèµ· çļĦ +eral a +Ġ åıijè¡Į人 +ĠKenn eth +ĠAs ide +min ent +@ s +Ġstr and +ĠAl leg +Ġresemb les +Ġref urb +_con n +å°½ æĥħ +h agen +Ġaffili ation +å¥Ĺ 管 +为 æł¸å¿ĥ +æľº èĥ½ +å¿ĥ ç¥ŀ +å¼ĥ æĿĥ +Ġmyster ies +Ġpar al +ĠPers pective +ä»Ĭ åIJİçļĦ +ĠBar b +IR C +_pro perties +Ġpick le +Ġd m +ç½® æį¢ +Ġc oded +^{ + +Ġfram ing +Ġs ich +ib o +V ia +ic idal +åŁİ 主 +le igh +-d i +å¦ĤæŃ¤ çļĦ +Ġunw illing +Ġcontin ental +çī¹ å°Ķ +è¿Ļ ä¸ī个 +åĪĨ éļĶ +ĠZ n +éĥ½ å¾Ĺ +ê ¸ +å°ıæĹ¶ çļĦ +rac er +Sp onsored +æµ® åĬ¨ +Ġ ä¸įè¦ģ +ä¸į æĢİä¹Ī +Ġfacilit ated +éħ ĭ +Ġcool ed +rob ot +Ġexpress es +ãĢģ åı¤ +åįļ å¼Ī +åıijå±ķ æľīéĻIJåħ¬åı¸ +ĠS IZE +ä½ķ ç§į +çĹħ 人çļĦ +æ¼Ĩ é»ij +ĠS AM +ĠD y +åĢ¡ è®® +ĠCub an +, éĢīæĭ© +ĠGu ests +Ġprogram med +, åıįèĢĮ +. For +аР¿ +.T able +_op ts +Ġde form +_pro c +âĢĶ it +为ä»Ģä¹Ī ä¸į +éĹ® 她 +Ġpict ured +PR INT +fol ios +ĠPub Med +å½ĵ 羣 +Ġmat plotlib +ab l +ĠL az +Ġsew er +Ġguess ed +éĥ¨ éĥ¨éķ¿ +æĺ¯ ä»ĸ们 +ä¸ĢæŃ¥ æŃ¥ +æĶ¿çŃĸ åĴĮ +Ġun forgettable +Friend s +åĦĴ å®¶ +Ġmig rations +Ġ*) & +ĠCollect ive +å¼Ģ å°ģ +Ġemail ed +Ġbur ger +åIJį çīĮ +B attle +Ġdiver gence +Ġdeterm inant +æŀģ é«ĺ +Ġ" \\ +åĹ ĸ +Ġpupp ies +h ope +comp iler +ĠManag ed +ĠMess enger +Ġpre g +åĩ» ä¸Ń +åıª å¾Ĺ +åĬ¨ èĥ½ +> A +èĥ ± +valid ator +ĠCal if +碱 æĢ§ +æ¡ Ģ +è¿IJ ä¼ļ +) ^{\ +çİĩ åĴĮ +eg al +éĿĴ äºij +Ġdecentral ized +LE FT +åīįæīĢæľª æľīçļĦ +ĠAr ist +i OS +ud ding +cc c +Ġvalid ator +Ġkitchen s +Ġreconc iliation +ï¼Į 广 +æĩ ¦ +ĠIns ight +Ġ 缮 +ĠDel ay +çŀ³ åŃĶ +ï¼Į åģ¶å°Ķ +_input s +ï¼Į è¨Ģ +ĠA uction +åıij éŁ³ +Ġfore head +åĸ· éĽ¾ +f ruit +çĤ ¬ +Ġpar alle +åŃķ èĤ² +ï¼Įä½ł çŁ¥éģĵ +æľ¨ 头 +éĹŃ åIJĪ +-est eem +ĠMon roe +rel s +ustral ian +Num bers +Ġrese mble +Ġc ues +it zer +Ġt int +Ġn ous +éļı åľ° +Ġde x +Ġstack s +ĠC razy +ĠD ial +ï¼Įæīį ä¼ļ +Ġprohib it +m able +Ġst roll +åijĨ åijĨ +å°ı 女åŃ© +Ġfore see +li able +Ġtast ed +ĠM ond +ä¿ĿæĮģ åľ¨ +Ġsuppress ant +éĥ½æĺ¯ æľī +ãĢģ ç²¾ +é¢Ĩ导 çļĦ +çļĦä¸Ģ å®¶ +H g +çª ĺ +ĠJ ets +af er +imicro bial +ĠK as +èµ¶ æĿ¥ +Ġschol arly +çĶ» åĥı +Ġb ob +æĹł 常 +_b in +Ġ éĩį +Ġment ality +-cent ric +, çϽ +Ġpat rons +Ġdev iations +, çα +Ġcov enant +ef ul +ä¸ĭ æĦıè¯Ĩ +çŃī ä»· +æĶ¾ åѦ +ĠViol ence +ic orn +am en +ĠRel igious +æŃ» äºİ +list ing +Ġv or +/d ev +_C ACHE +å¾Ħ 缴 +è¸ı ä¸Ĭ +ĠU m +ĠCy prus +- types +cd n +ĠVolunte er +ig hest +Ġcon quer +ind rical +Ġcell ul +IM ARY +Ġexecut or +ĠR iemann +_t ry +Ġstick er +Exper t +l ider +åIJĮæł· æĺ¯ +Ġ ç³»ç»Ł +çĥŁ èįī +Ġglow ing +好 ç¬ij +妥 åĸĦ +Ġ' + +" Yes +G ene +Ġdivor ced +Ġinf usion +æĿĢ å®³ +çļĦ å¼ł +æŀĦ çŃij +Ġchlor ide +åīį ä¸Ģ +åĴĮ æĸ¹æ³ķ +â Ĭ +æIJŃ æ¡£ +åIJĪ åͱ +ç§ijåѦ ä¸İ +udd le +Ġdisturb ed +è¿Ļç§į äºĭæĥħ +ĠSim ulation +åĮĹ æµ· +Ġexerc ised +è¿Ľ æĿ¥çļĦ +æ· ¼ +Up grade +æĭľ æīĺ +Null Exception +å¾® åŀĭ +Tr uth +æī¹ å¤į +Ġthick er +_ reference +Ġneur onal +Ġecc entric +M il +ï¼Į æİ¨è¿Ľ +å®Ŀ çİī +èĭ ĵ +åĽ½ èµĦ +åı¯ ä¹IJ +-m ain +é¢Ħ è¨Ģ +g iven +ï¼Į 天ä¸ĭ +Ġurg ency +ĠAur ora +æŃ£è§Ħ çļĦ +Ġstro kes +Ġkil omet +Ġrug ged +supp lementary +人 ä¸Ģ +ì ĭ +åIJĥ å¾Ĺ +our g +Ġsa usage +å®ī å®ļ +ãĢĤ åIJ´ +æīĵ ä»Ĺ +å§ Ĺ +az ole +.M odule +. ab +k r +atic an +Ġt rophy +_per iod +Ġw oven +æĸ¯ é¡¿ +ĠV oid +Ġfore ground +ĠS z +av al +ia e +ä»»ä½ķ çļĦ +ç»ĵ çŁ³ +èģĮä¸ļ æĬĢæľ¯ +å°±æĺ¯ äºĨ +é¾Ļ éŨ +Ġh alls +Ġ æŀľçĦ¶ +Ġval ves +åķĨ è®® +éĩįè¦ģ ä½ľç͍ +è¿Ļç§į äºĭ +bl k +æľ Ń +Ġabnormal ities +Ġnood les +st ay +åĪ©æ¶¦ åĪĨéħį +ï¼Į 产çĶŁ +ep ing +Ġlay ered +Ġn l +ĠF ully +ĠSh o +Ġcustom izable +åŃĺåľ¨ çļĦéĹ®é¢ĺ +F rance +Ġav atar +Ġ ç¼ĸè¾ij +çļ Ļ +Ġa ired +rict ions +d ater +Ġv ul +çļĦ人 æ°ij +ĠSu ites +åłĤ åłĤ +il io +æĽ´ èĥ½ +-l ayer +ĠRe commended +çłĤ æµĨ +_ cont +åĬŀåħ¬ åİħ +è¿Ł æĹ© +段 èIJ½ +ĠJac obs +çŁŃæļĤ çļĦ +Res ize +,ä¸Ģ åĪĩ +G Y +n ative +t el +æĬĽ åħī +Ġmas cul +è¿Ļ ä¸ī +( port +åī§ ç»Ħ +ï¼Įè¿Ļ 款 +.T ool +Ġal gebras +åĨ· èĹı +é¦ĸ ä½į +ĠJ P +Se a +Ġpredict or +Ġg ent +ull ah +车 è½® +å±ķ åİħ +ç²ĺ è´´ +ĠT NF +IT ER +åį° å°¼ +ï¼Įä¸Ģ åIJį +ĠSad ly +ï¼Į åĺ´éĩĮ +Ġ ich +it amin +被 æĬķèµĦ +Ġph i +Ġconsolid ated +æ³ķ æľ¯ +(n on +ĠS AS +ĠK C +ä½ĵä¼ļ åΰ +pt a +åĽŀ è¿ĩ头 +(r ange +ph ony +ĠJama ica +ãĢĭ ï¼ī +ä¼ļè®® ä¸Ĭ +. Not +ĠPC s +åı¯éĿł çļĦ +B rad +re ra +æ´ª æ¶Ľ +Ġpop ul +, å¦Ĥä»Ĭ +çŃī çĹĩçĬ¶ +(t x +Coord inate +posit ories +Ġhem orrh +漩 æ¶¡ +Ġrest s +omb ies +ic ators +æĩ Ĭ +Ġl u +ï¼Į 缸æ¯Ķ +ä½ł 说çļĦ +Ġviol in +Par allel +Ġcit rus +ãĢģ 缴 +Un selected +off er +ï¼Įä»ĸ æīį +_x ml +( values +Ġrem embers +ãĢĤè¿Ļ ä½į +Str ateg +ен иÑı +Ġun just +ular ity +ðŁ ı +纯 æ´ģ +< c +" < +é r +ÃIJµ Ãij +ï¼Įä¸Ģ个 æĺ¯ +åĤ¨ çī© +( entity +è¦ģ ä»İ +Ġun ittest +FAQ s +ä¸Ĭ è·¯ +Spe aker +ĠLou ise +ä¸ĥ 个 +ĠClass ification +ĠT rees +Ġg oose +åį¡ éĢļ +EV ENT +art an +æĹłçĸij æĺ¯ +çļĦ è¾ĵåĩº +ĠUS C +缮åīį 为æŃ¢ +Ann ual +DEF INE +çļĦ éŁ³ä¹IJ +Ġ è¿ĺæĺ¯ +Ġcoinc idence +Ġreferr als +enti eth +"] ) +éĹª èĢĢ +G esture +æĸ Ł +ä¾® è¾± +pos itions +åħ« æĸ¹ +å¼Ģ æºIJ +åī¯ æķĻæİĪ +A z +Ġup front +ä¸įå¾Ĺ äºĨ +设置 äºĨ +Ġ( = +ä¸į å¤į +éĿ¢ æĿ¡ +çļĦ æīĵ +åį¡ è½¦ +è¿Ļ 对 +æ°´ ä½į +Ġé t +an os +ĠUp load +ched uling +åģı 好 +çĶŁ åĮĸ +ocument ed +ĠMach inery +Ġthrough put +ĠPerm alink +is ites +` ) +M ess +ãĢĤ ä¼ģä¸ļ +Ġun successful +ĠExecut ion +Ġ åŃIJ +ç»´ æĿĥ +æĿĤ çī© +Ġri pped +ä¸į 缸åIJĮ +B onus +åıĪ å¼Ģå§ĭ +Ġl um +WR ITE +( bytes +妨 ç¢į +, å¢ŀ强 +er i +æ· ¬ +âĢĿ ( +ĠG ren +èģĤ å͝ +Ġun biased +çĿ« æ¯Ľ +è¿Ļç§į æĸ¹å¼ı +Ġb ible +严 ç¦ģ +å®¶ 常 +н и +æīĢ æ¬² +det erm +ĠBudd hist +éĶ £ +æį¢ æĪIJ +æĦıä¹ī ä¸ĬçļĦ +) ], +Ġev t +Ġdistribut ors +k ed +ä¸į åĪĨ +ĠB ren +人 次 +ĠP VC +çŃī è¡Įä¸ļ +Ġside bar +ĠL amp +ï¼Į æľķ +Ġceil ings +æĢ» 管 +Ġwa ived +çĤĴ ä½ľ +icult y +(" $ +éķ¿æľŁ çļĦ +Operation Exception +äºĮ 代 +ê° Ģ +é¥Ń åIJİ +_p rev +Ġmalign ant +Red uce +ç¼ĵ åĴĮ +ĠC RE +ä¾¥ 幸 +abb ed +Ġcost ing +Ġfre q +ãĢģ ç§ijçłĶ +游 åĩ» +å®ģ æĦ¿ +æ²ī çļĦ +çŁŃ æľŁåĨħ +ĠK ane +Ġprof iling +æ¿Ģ åĬ¨çļĦ +Av ailability +ent in +ĠTrans actions +ĠEss entials +S umm +T ABLE +被 害人 +æĿ¿ åĴĮ +-th ird +iar ism +g z +æĤ ļ +Ġgl itter +ç»ĵæŀĦ åĴĮ +ï¼Ł ä¸ĭéĿ¢ +Ġdisc s +æĪĸèĢħ åħ¶ä»ĸ +麻 麻 +.blog spot +ĠG ap +åĤ¬ ä¿ĥ +Ġemerg encies +_ rc +说è¯Ŀ äºĨ +cul osis +Ġblank ets +åĪĹ åĩº +è´« ç©· +æ¶¡ è½® +- age +ĠB id +ç²ĺ åIJĪ +Ġmed iation +F requently +ile ts +ï¼Į æĶ¹åĸĦ +æĬ½ å±ī +Ġeleg ance +Ġpl astics +ç§ij éĻ¢ +æľī ä¸Ģ次 +æĮ¥ èĪŀ +Ġlim estone +Ġash amed +à¯į à® +é«ĺ æĸ°åĮº +est ing +Ġb ids +Ġx en +Ġan atomy +)) ** +èĥĥ åı£ +AL TH +t ouch +åħĪ æĬĬ +Ġfire wall +Ġrid ge +çĬ¯ç½ª å«Įçĸij人 +æ²» çĹħ +Ġcultiv ate +ro bl +é¢Ĩ åľŁ +( opts +èĩª ç§ģ +è¿Ľ åľº +è§Ĵ éĢIJ +HE AD +( the +ERS ON +èĬ± æł· +两个 åŃĹ +ä¼¼ä¹İ æĺ¯ +Ġrib s +Ġbi ases +ä¼° ç®Ĺ +åı¯ä»¥ 对 +ï¼Į è§ģåΰ +Jose ph +åŃĺ æ´» +(c ur +. container +åıĹ è¿ĩ +ĠW ins +ĠV ehicles +ĠLight ning +ĠD igest +Ġclaim ant +back end +sl ice +Ġnom inee +é±¼ çļĦ +Ġrein forcement +ĠG I +缸 è¿ij +便 åı¯ +Ġinf initely +ĠS ons +Ġfract ures +ĠL ift +èĢģ ç¥ĸ +.m ode +: x +å®¶ 人çļĦ +Sp acing +ĠCars on +åı° è¯į +Ġsem antics +èµ°äºĨ è¿ĩæĿ¥ +ĠIdent ification +ĠDer by +åĨĽ ä¸Ń +ag i +p oke +æĢ¥ äºĨ +ï¼Į æĪ´ +_d ep +ãĢĤäºĮ æĺ¯ +ĠW endy +Listen ers +å¸Ĥåľº ä¸Ń +can vas +ï¼Ł åħ¶å®ŀ +ï¼Įæľī ä¸Ģ个 +ĠPer th +X M +(l ast +Ġha ha +ä¿® è¡¥ +_v ideo +ä»·æł¼ çļĦ +ä½ľåĵģ çļĦ +ä¸Ģå®ļ èĥ½ +Ġnew com +C ached +å¼Ģ æľº +ap est +æĽ´å¤ļ ä¿¡æģ¯ +Ġge omet +ĠE DT +ile e +çļĦ人 æķ° +纳 æĸ¯ +.l ayer +Ġfabric ation +æĭľ ä»ģ +еР· +èħ ĭ +t body +is chen +å¯Į 豪 +åĬ¨ çī©çļĦ +æ°´ æºIJ +Ġcrack ing +-t ree +社ä¼ļ ä¿Ŀéļľ +Ġbusiness man +Ġtempt ing +_ term +ä¼ļ åıijçݰ +.com pare +Be at +Ġbat ches +åĨĽ åĮº +好 æĦŁ +èīºæľ¯ çļĦ +ï¼Į èĩ´åĬĽäºİ +Ġsubs pace +èŀº éĴī +ï¼Į éĽĨ +Ġmaneu ver +人æ°ij 代表大ä¼ļ +çļĦ åľŁåľ° +åħ° çī¹ +享 åıĹåΰ +ï¼Įè¦ģ ä¸įæĺ¯ +çŁ¿ çī©è´¨ +ĠPower Point +ï¼ĮåĽłä¸º ä»ĸ们 +åıĺå¾Ĺ æĽ´ +ç͍ é¤IJ +" $ +_H W +ä¿¡æģ¯ ç³»ç»Ł +åĹ · +åĽ½ åĢº +ĠH ex +Integ ration +Ġembarrass ed +Ġd ich +DA Q +æĺ ± +Ġfault s +æĢ» è§īå¾Ĺ +ä¹Łæĺ¯ 个 +_ an +.f etch +éķ¿ åıij +ï¼Įä¸Ģ æĹ¶éĹ´ +.r untime +/ news +æŀľ æ±ģ +.l ayers +ãĢĤ è®°èĢħ +Ġastr onom +ç¦ı çī¹ +åĢŁ è´· +íķ ľ +Ġvis cosity +Sp y +Ġsupplement ed +ĠEss ays +Ġz e +Ġus ize +åĬŀ æ¡Ī +ĠL ibraries +éĢģ è¾¾ +åı« ä»Ģä¹Ī +Ġyouth ful +Ġmamm als +.b atch +od us +åĩº è´§ +说 è¿Ļ +: f + ¬ +ĠIg G +m icro +ĠP ipeline +Ġpro gen +est ation +æĪª çĦ¶ +Ġspirit uality +Ġembarrass ing +çĤ¹ ä»Ģä¹Ī +çł º +辩 æĬ¤ +ist ine +èµ° è¿ĽäºĨ +Ġrock y +ĠVer izon +Ġo ceans +ï¼Į æĬĢæľ¯ +ĠSh ut +-ex isting +å¥ ļ +\ usepackage +] name +çĤ¹ å¿ĥ +et able +. background +i ators +Ġhel pless +ä¸ĩåħĥ çļĦ +姨 å¨ĺ +åħ¨ 书 +ARCH AR +w g +Ġgener osity +æĸĩä»¶ ä¸Ń +Ġst ark +Ġpost operative +æĢª ä¸įå¾Ĺ +豪 éŨ +èݱ åĿŀ +Ġmust ard +/ sc +:: < +_l ayers +Ġdisreg ard +k om +ï¼Į 鼨 +æ°´ éĿ¢ +åĤ¨ èĥ½ +j b +å±ķçݰ äºĨ +к и +Ġpray ed +ĠP ly +sh ield +æ²¹ çĶ» +Ġ; ; +dep recated +æĸ°éĹ» ç½ij +-th an +ĠTr im +éĻĦ çĿĢ +Ġse als +Ġconject ure +ãĢĤ åı¦ä¸Ģæĸ¹éĿ¢ +ff ield +ĠM IC +åĭIJ çļĦ +çģ¯ åħ· +ĠAv ailability +çĭĻ åĩ» +第äºĮ 竳 +å¯Ħ çĶŁ +ĠRain bow +p ointer +Ġc aramel +ĠB arr +it ars +ĠW AS +ert y +æ¸ħ æī« +- object +l if +æ¯ı天 éĥ½ +æĭĺ çķĻ +å¡« æĸĻ +åİĨåı² æĸĩåĮĸ +oc ese +æ´Ĺè¡£ æľº +_f ilters +åħ¬ ä¼ļ +. round +æ½ľ ä¼ı +æħĮ å¼ł +ç» ¥ +ï¼Įå°Ĩ æĿ¥ +ç»ĦåIJĪ çī© +S ink +ĠJ upiter +}} $, +èĩª å¦Ĥ +Ġrep ayment +\": \" +è¶³ äºĨ +åĶIJ 代 +èµĮ åįļ +ï¼Įä»ĸ ä¼ļ +ãĢģ éĵ¶ +Ġ åĽł +åıijå±ķ æĪĺçķ¥ +Ġnarr atives +飧 æĢ§ +J ud +å®Į 好 +ĠE E +,\ , +ĠRestaur ants +Ġlever aging +ĠH od +åĩĨ æĹ¶ +( opt +æ½ į +Ġneglig ible +( # +è¿« åĪĩ +å« Ķ +æĪĺ ä¸Ń +p ag +åįļ ä¼ļ +ĠO g +ĠCom posite +_ Data +Ġsh am +Ġkn itting +Ġeng ra +ĠL un +çĪĨ æĸĻ +- aware +ens able +ï¼Įè¦ģ ä¸į +Ġunt reated +ĠSau ce +ãĢĤ â̦ +art ist +ĠDis claimer +m ys +çļĦ éĩįçĤ¹ +.en able +Ġ ç»ıè¿ĩ +æİĮ éŨ +Ġgre ed +ï¼ĮçĶļèĩ³ æĺ¯ +èĪĴéĢĤ çļĦ +, ä¾ĭå¦Ĥ +çݰå®ŀ çļĦ +ĠR PG +P ART +å®¶ åĬ¡ +ĠShe pherd +U k +ĠG ummies +ow ired +.parse Int +Commun ication +_PO INT +F ox +æ¶Ī失 åľ¨ +æķĮ åĨĽ +Ġton nes +棺 æĿIJ +( [" +) +\ +-pro of +ĠOl ivia +Ġreview ers +Se ed +ĠRest oration +ĠDump ster +ï¼Į æĹ¨åľ¨ +å¼Ģåı£ 说éģĵ +åıª åľ¨ +Ġunder p +åıĸ èĥľ +ur ia +Ġaspir ations +Ġsacrific es +ĠT ill +éĩı åĴĮ +ï¼Į ç®Ģåįķ +ä¹ĭ å¤ļ +ï¼Į å¼ķèµ· +ï½ŀ ï½ŀ +Ġhomes chool +Ġg oog +eb e +ä¹ĭ åIJį +Ġ 说çĿĢ +Ġsk incare +q p +ĠIN FORMATION +åģļ çļĦäºĭ +å°ĺ åŁĥ +å®¶ åĴĮ +Ġimm ersive +åIJ Ń +(m od +ï¼ĮçĦ¶åIJİ å°Ĩ +Ġsovere ignty +ĠB oeing +ĠSer iously +å¹´ äºĨ +æī¬ èµ· +New er +Dec or +ä¸ĩ å¤ļ +ä¸įæĺ¯ ä»Ģä¹Ī +宫 éĩĮ +: \\ +** : +ĠSh ower +Ġtri angular +Ġlock er +Ġcomeb ack +ib us +b ring +ĠT ODAY +åĬ£ åĬ¿ +çĶļ ä¹Ī +Group Name +èĭ¥ æĹł +. Com +Ġfun g +è¿Ľ ä¿® +å¼Ĥ åij³ +FL AG +ĠNorm ally +US Y +Ġch op +åĩº éĿ¢ +ens ible +Ġrem n +ĠWal let +ĠMcC arthy +ä¸Ģ ä¹Ŀ +å¦Ĥæŀľ 没æľī +ĠÏ Ī +ke yp +æĨ İ +ä¸į åĩ¡ +ä»ĸ èĥ½ +AT FORM +åĪĨå¸ĥ åľ¨ +Cy ber +ĠCl ara +Rem oved +Ar n +:::: :::: +æĤł éĹ² +A round +Å ĵ +è¿ĺæĺ¯ 没æľī +ï¼Ł âĢľ +åıªæĺ¯ åľ¨ +Ġk h +< E +车 祸 +Ġcondem ned +ĠCar pet +-n ative +. Use +çļĦæīĭ æĮĩ +æŁ ¬ +Ġwrink les +Ġseiz ures +AIL ABLE +Ġl ur +çļĦç»ĵæŀĦ 示æĦıåĽ¾ +Ġnas al +ï¼Į èIJ½ +å°Ķ åħ° +osp ice +éĺ» æĭ¦ +Ġnort heast +åIJİ ä»£ +M igration +åIJ¬ ä»İ +m its +# get +B rien +Ġ// $ +åĪĨåĪ« ä¸İ +æĹł ç¼ĺ +E arth +åı¯ä»¥ åİ» +缮 çŀª +æĽ ³ +log y +è¿ŀæİ¥ ä»¶ +Poly gon +. Configuration +ĠAnn ounces +( User +(f eature +ENT ITY +f loor +St one +æĦ£ äºĨä¸Ģä¸ĭ +m uch +æ¡ ¨ +Ġext racellular +Ġencompass es +Ġ ounce +ĠG N +Ġdiarr hea +Ġw isely +é«ĺ é¢ij +Ġpr ag +Ġund ef +åĩĨå¤ĩ 好äºĨ +rim ental +æĶ¯æĮģ åĴĮ +b iz +åĩıå̼ åĩĨå¤ĩ +O Y +Ġple aded +ĠGrand e +_ append +Ġ ç´« +y i +ï¼Į æķ°æį® +ib ling +æ´¥ è´´ +bet ter +j un +ĠP hen +å®ŀ åĬ¡ +Ġserv icing +æĿ¥ å¾Ģ +Ġrestrict ive +æİ§ ä»¶ +-th irds +ç½ij绾 å®īåħ¨ +RE M +ĠF lood +P VC +è¿Ľè¡Į åĪĨæŀIJ +æĪIJ å½¢ +/c m +ĠV ERY +ĠM ama +V AR +ĠB N +N ested +Ġ éĢīæĭ© +æĤ ¯ +ĠC annot +ãĢģ åŃ¦æł¡ +åIJį å¸Ī +Ġthreshold s +第ä¸Ģ 竳 +G ap +u ously +çļĦ ä¸ļåĬ¡ +ĠCO UR +Ġnegot iated +对 æĪij说 +at u +zz a +run ner +åĽ½ å®ī +_TR ANS +éĢ® æįķ +ism ic +è´Łè´£ ä»» +Ġmail box +Ġwor s +Ġinter disciplinary +-e lect +ä¸ŃçļĦ åºĶç͍ +Ġqu ota +å±± ä¸ĭ +_m ember +åı¦ä¸Ģ è¾¹ +ç®Ģ è¦ģ +æĺ¯ 羣 +æĸ° 款 +Ġtrav ellers +èĪ µ +æŃ¦ ä¾ł +ĠAR R +éĥ½ æ¯Ķè¾ĥ +äºĨä¸Ģ åįĬ +- rated +Ġins ure +.S ecurity +å¥ĩ å¦Ļ +Ġwin nings +ĠObs erv +bel ow +ï¼Į åIJĪ +( instance +C ritical +Ġ ]. +Ġb ik +Pro ducer +( offset +_B R +Ġnick name +est ead +Ġ ï¼ +ĠP t +Ġesc ort +ĠL um +ext ensions +æĹł å°½çļĦ +Ġpo pping +: ] +× IJ +Ġbrief ing +æĸĩ 人 +Ġμ ε +ĠS aid +æł¼ æĸ¯ +âĢľ That +Pl aintiff +âĢľ æľī +ä¸į çķĻ +强 åĽ½ +ĠRef lect +et ri +Ġfault y +" Oh +éĤ ¯ +op al +æİ¨ æĸŃ +éº ¾ +åĽ½åĨħ çļĦ +Ġimplicit ly +sec ured +gg y +æĪij们 éľĢè¦ģ +示 åĩºäºĨ +ĠStr at +- ev +åĪĴ åĪĨ为 +缮æłĩ çļĦ +è§Ħ éģ¿ +Ġbel ts +Ġhist ogram +èĤ¡ æĮĩ +æī ¼ +ç¾İåĽ½ 人 +turn ed +Ġche fs +IS M +åζå®ļ äºĨ +çݰ è¡Į +çľĭäºĨ çľ¼ +ĠAd mission +_R G +第ä¸Ģ 天 +æĬ½ æIJIJ +è´« è¡Ģ +åıijå±ķ è¶ĭåĬ¿ +Med ium +为 æ°ij +Ġveter in +Ġg au +ĠÐ » +\ rho +å³ Ļ +W nd +Ġburn er +éŃĶ åĬĽ +âĢ į +_B UTTON +è£ħ æľī +ĠDet ective +åŀĭ æĿIJ +Ġgr im +Ġ ery +ä¸Ń åİ» +.ex ec +Ġsub way +.g ener +avor ites +è¦ģ 好 +æķĻèĤ² åĴĮ +æľĢåIJİ ä¸Ģ次 +åľ¨ ä¸İ +ym l +Ġconver ge +\ cap +ä¹Ł 对 +Ġin quire +Ġbra ces +">< ? +Ġpil gr +_ UPDATE +ãĢĤ åIJ¦åĪĻ +oc ular +éħ¸ 奶 +æĭī ä½ı +Wh it +å°±ä¼ļ 被 +ï¼Įä¸į åŃĺåľ¨ +ä½ł ä¸įæĺ¯ +Ġtraject ories +, 尽管 +Ġcentral ized +Ġo ve +è¾¾ ä¸įåΰ +çݯå¢ĥ åĴĮ +æĢİä¹Ī çľĭ +Ġ åIJİæĿ¥ +å§¥ å§¥ +R ain +ĠT ube +åIJį å®¶ +Ġtact ic +Ġluc rative +ï¼Į 缸åħ³ +ĠTom orrow +ä½ĵç³» çļĦ +R isk +éĢ ŀ +Ġsan it +e lements +å¹´ çīĪ +ãĢģ æīĭ +ĠVert ex +ĠSp y +æŀģ åĵģ +ĠNo ise +Ġ' ) +ãĢĤ ** +楼 å¸Ĥ +Ġ éĤ£ä¸ª +ï¼Į éļ¾ä»¥ +Advert ising +ç»ıèIJ¥ çIJĨ念 +åĽłä¸º æĪij +S hip +追 éļı +æĸĩæĺİ çļĦ +web pack +èĬĤ 课 +åѦ åΰ +{lem ma +st m +Ġ" ." +ç²¾ éĢļ +天 çĮ« +Hand lers +Ġcur ry +ä»İ ä¸Ģ个 +ĠMon o +ĠDim ension +ĠÏ Į +Ġcro re +ĠF UN +æłĩ æľ¬ +ãĢģ 绿 +åĨį ä¹Łæ²¡æľī +寺 åºĻ +æľĢ çα +èĸª èµĦ +æľī è¿Ļæł·çļĦ +d in +, æĪĸ许 +åij Ľ +æĥ³ åľ¨ +Ġsat ellites +\ Component +Ġb inds +ĠNear ly +ĠC edar +ï¼Į åĮħ +Ġilleg ally +ĠHil bert +èĤ² 人 +Ġbar red +她çļĦ æīĭ +åĨ ¢ +èIJĥ åıĸ +F ROM +çī© ä»¶ +å½Ĵ ä¸įå½Ĵ +ih ad +Cred ential +. control +åľº é¦Ĩ +pe z +次 äºİ +, æľĢ好 +åģı ç§» +Gr ant +ï¼ļ ä¸ĩåħĥ +å¡Ķ å°Ķ +鼷 ç͵ +é¢Ĩ导 å¹²éĥ¨ +ĠE scape +ãĢģ åķĨä¸ļ +æħĮ ä¹± +: N +社 群 +ĠIn clusion +Ġun b +ä»ĸ æīĢ +d estination +交 éĶĻ +ĠProm otion +Ġbenef iciary +åĮĹ ç¾İ +Ġg ithub +.g it +ĠCall s +Ġh l +ĠPat ricia +h orn +ä¸Ģ éŨ +Ġ( [] +Ġpred etermined +常æĢģ åĮĸ +ĠT ong +åħ¨ èĩªåĬ¨ +Ġdiagn ostics +J A +m ong +æĦ§ çĸļ +æĸ°åįİ ç¤¾ +顾 èĻij +ĠInit ially +Ġprint ln +ĠIns pection +åĽ°éļ¾ çļĦ +st aff +åĽ¢ è´Ń +æĪIJ åIJį +ĠIs le +å¼Ł åħĦ +Ġnorth west +@ { +Ar ts +ä¸į æĥľ +Ġ æĽ´å¤ļ +èĢģ 太 +Ġlig and +å¼ĵ ç®Ń +Ġw re +-f rom +( < +çļĦä¸Ģ 份 +\ Model +ï¼Į 严éĩį +åı¯ä»¥ æĬĬ +æī¾ ä½ł +ĠC ran +Ġspe ar +rop he +ï¼Į大 约 +Ġdetermin istic +Jenn ifer +ĠE uler +med ium +æĺ¾ å¾® +G erman +ä¹ĭ ç¥ŀ +ĠMc N +MS C +or ian +ï¼Į åī©ä¸ĭçļĦ +Ġso ber +Display Name +Ġh ath +çŁ³ æĿIJ +ĠLevel s +P ed +åħįè´£ 声æĺİ +ç¢İ äºĨ +Ġsubstr ates +en ary +Ġtrans gender +Id le +Ġi x +产 åĩº +å¸Ī å¼Ł +j ure +失 æİ§ +ĠR everse +ĠMatt ress +ĠSym posium +> type +rest rial +yst one +cript ors +Ġun con +çıį è´µçļĦ +^ [ +Ġend angered +æĸ¹å¼ı çļĦ +Ġmar riages +主 åħ¬ +Cl ub +ä¼ļ 说 +è¿Ķ è¿ĺ +-pro ject +Work flow +ç«ĭ åľ¨ +ï¼Įä½ł åĪ« +éķĩ å®ļ +S UV +ĠT as +ĠWag ner +Ġdispro portion +âĢľ As +ä½ĵ èĥ½ +è¿ĺ æĮº +èį Ł +åįĥ åħĭ +Ġart ifact +ĠConf lict +Ġpermut ation +Ġspect rom +Ġsol uble +导èĩ´ äºĨ +Ġoff ence +å¤ļå°ij 人 +Ġfurnish ings +ich igan +糯 ç±³ +ĠMor occo +, åºĶå½ĵ +[ this +Ġre cl +Ġe Commerce +, ç»§ç»Ń +F ab +令 æĪij +Ġtre asures +çļĦ ä¼łç»Ł +Ġ æŃ¤å¤ĸ +Ġs or +ç»ı è´¸ +Ġentertain ed +Ġcarbohyd rates +ãĤ µ +çĶŁçī© åѦ +ref erences +天 å®ĩ +Ġdisturb ance +Ġrepe ats +Ġmask ed +ä¾Ŀ ä¾Ŀ +ï¼Į æ¸IJæ¸IJ +ï¼Į åıijæĮ¥ +Ġrob otic +Ch an +æĨ § +åĶ ł +æ²IJ æĢĿæĺİ +å¨ģ 严 +åĿı äºĭ +Ġsib ling +or ously +C ourt +ï¼Įåį´ æ²¡æľī +oss ary +Ġboo ster +Ġinaug ural +: ', +ï¼Įå°± 好åĥı +. ms +æ¼ ª +_EN V +Ġcommission er +Ġregul ates +ĠEr in +ĠGod s +Ġpancreat ic +Ġdoes nt +Ġha unted +åıijå±ķ è§ĦåĪĴ +und ai +å®ŀç͍ æĢ§ +Ġcl er +ä¸ļ æĢģ +ĠV ote +Ġinn ate +ĠJack ie +æĺ¯ æĬĬ +âĢĭ âĢĭ +ig ens +ik u +_s peed +( el +ĠUt ilities +åľ¨ çľĭ +ĠD ew +ç§ Ĩ +iz ards +ç¦ı å¾· +| $ +ĠFl a +Ġhar bor +Ġ\ ' +Ġdish on +G W +L EN +Ġs arc +ĠEx pr +Ġcard i +DA O +Ex isting +Ġalleg es +好 ä¼¼ +ĠS YS +å®Į ç»ĵ +v ue +Ġc aul +Ġ åıªæľī +(n et +ä»ĸ è¦ģ += C +H ad +)\ , +it ra +æī§è¡Į çļĦ +oph ys +.f ail +èĩª å·² +Bl ank +ãĢĤ èĥ½ +åĬĽéĩı çļĦ +æĺ¯ ä¸İ +- ) +^ a +èĬĤ 度 +æ¤į æłª +ĠStream ing +Ġwe eds +tt a +ç¡« åĮĸ +.dir name +ä¸Ń 人 +Ġstand point +he id +Ġqu int +ed en +A ri +ma ha +Ġadv ising +ãĢĤ çľĭçĿĢ +ĠAs c +ĠS co +ĠR are +ĠUS DA +容 å¿į +" ? +ï¼Į æľĽçĿĢ +ĠCollabor ation +åħ¶ åIJİ +é£İ è²Į +Ġkind ergarten +Ġfore closure +Sp here +=" "> +* $ +ot ers +-b ut +Ġres igned +j ac +and in +çŃī ä»ĸ +产ä¸ļ çļĦ +å¿ĥ åľ° +ï¼Į æ°ij +] he +ĠT iny +èŀį åĮĸ +Ġstd err +æķ´ 车 +å¿ĥèĦı çĹħ +ãĢĤ åı¤ +ok i +re ally +åĵ¥ 们 +大 æĦı +iff e +ĠCl ip +ê ² +âĢľ Our +åıij èªĵ +S ad +èģĶ éĢļ +éĢIJ å¹´ +b ob +ç͵åĬ¨ 汽车 +Ġhepat itis +P sych +ä¸į 认è¯Ĩ +Ġ该 æĿij +I ron +ä¸įçŁ¥ æīĢ +å°Ĩ 该 +线 åŁİå¸Ĥ +Ġrug by +课 æľ¬ +Ġirrit ation +åIJį è¨Ģ +Ġsym pathetic +MM MM +åζ å®ļçļĦ +ãĢĤ 举 +ĠConst ants +Ġsanct uary +Ġbroadcast ing +Ġdraw ers +Ġwand ering +ĠKn ights +ä¸įå°ij 人 +ä¼ļ åľº +Ġdist raction +Ġvict ories +ĠBur ke +ç» « +ĠS ig +Ġdep icts +æľº æ²¹ +æ°Ķ åĴĮ +N egative +ĠB ened +Ġovar ian +表 æĢģ +Ġ åħ³ +çϾ èĬ± +ç¥Ŀ è´º +ĠFirst ly +, æ¯ı个 +Ġbas il +_AD C +åĢ Ķ +acc i +leg iate +ç¯ĩ 竳 +Ġgrap hene +is ations +天ä¸ĭ åįĪ +Ġgrad ed +em ark +ĠR outer +Ġcaps ules +èĪį å¾Ĺ +Ġsn ippet +ä¸Ģ æĭ³ +ç¿ İ +ä¸įè¶³ 以 +, éķ¿ +ĠSt yles +åŁİ åĨħ +Ġp yl +çݯ åį« +ck o +ĠAdv antage +/ **************************************************************************** +ĠR ocket +est ruct +Ġres iding +æīĢ å¸¦æĿ¥çļĦ +æīĢè¿° çļĦæĸ¹æ³ķ +.s ign +ĠIS IS +^ t +N ING +Ġj ars +åħ¨ èµĦ +ipp ers +åIJīæŀĹ çľģ +est hetic +ĠR PC +ort on +ĠCal vin +ĠLeg ends +ç´§ç´§ åľ° +ãĢģ ç³»ç»Ł +ou ched +H o +âĢľ My +ĠCiv ic +ĠS SH +æ½ľ èīĩ +_ON LY +s un +s With +çľ¼ åºķ +çļĦ æĶ¿æ²» +Ġdeduct ible +ĠK w +, éĢłæĪIJ +ĠPack ages +.st ep +(d ocument +ä¸Ĭ 端 +åIJİ ä¸ĸ +鼷 éĶĭ +âĪ ŀ +è·¯ çģ¯ +éĢī åĿĢ +иÑĤ ÑĮ +Ġsynchron ization +ä½£ éĩij +E t +ĠP OWER +èµ¶ ä¸Ĭ +Ġsouth west +ç§į çļĦ +æĢ¥ äºİ +_ACT IVE +G ermany +Ù ī +Ġturb ine +å®Ŀ è´µçļĦ +в а +Ġpit ched +ç¿» çĤĴ +æĺĶ æĹ¥ +èĤ¤ èī² +ĠCall back +ĠPalestin ians +% \ +Dir ty +ï¼Į å®ŀåĬĽ +é¢Ħ çĥŃ +ĠFAQ s +$ x +èĢĮ å®ļ +赫 çĦ¶ +ï¼Į è·Ŀ +ĠUn i +ç®Ģ缴 å°±æĺ¯ +Ġg li +rit z +W AYS +ie le +ist e +Re ce +头 çļ® +Ġ ç»ĵæŀľ +-------- --- +Ġminor ities +l j +Ġ åľ° +is ia +åĪĽä½ľ çļĦ +Ġî n +_N E +室 éĩĮ +åĩłä¹İ 没æľī +éĿ¢ åŃĶ +Ġleak age +ĠMal ta +Ġent ails +_l ineno +ĠDist ributed +. def +ç¥Ľ æĸij +Ġwip ed +é«ĺ åĩº +å°ı 康 +ä½ĵ å¤ĸ +ĠSeb astian +Ġin duct +ĠJud y +æľ¬æĿ¥ å°± +ãĢĤ åºĶ +el en +念 念 +Ġvol t +Ġa queous +ä¸Ń è¶ħ +de legate +ï¼Į好 好 +Ġpist ol +ĠR ings +èĴĭ ä»ĭ +è̏ èĤ© +Ġsix teen +f ax +èѦ æĬ¥ +G ender +æĿŃ å·ŀå¸Ĥ +ç»Ŀ ä¸į +ĠPre paration +ĠRES ULT +æĺ µ +顺 åĬ¿ +ãĢĤ åĪ« +Out Of +. up +èĩª å°Ĭ +Ġtem ples +Ġcal orie +çļĦ 交æĺĵ +T IME +CP P +æŃ¤ åľ° +Ġ[ % +çļĦ 身边 +ĠTal iban +é«ĺ ä¸ī +Ġrot ational +ãĢģ æ³ķ +oper and +ä¸Ģ åĽ¢ +Ġmot if +å·² å®ĮæĪIJ +æĪIJåĬŁ äºĨ +Ġf ountain +åħī 彩 +alloc ate +åı¦ è¡Į +ĠDe pt +ĠApp li +Ġhost name +whe el +ĠCl ause +ë¥ ¼ +Ġ æ¯Ķå¦Ĥ +M U +å½ĵ ä¸ŃçļĦ +Ġstate wide +Ġbr ushes +æŀĦæĪIJ çļĦ +é¢Ħ åζ +Ġantioxid ants +æĪĸèĢħ 说 +I EW +ĠLog istics +f ac +Ġthe or +åĴĮ éĿŀ +Ġconce aled +ãĢģ å®Įæķ´ +æ³¢ æ¾ľ +Act ual +ï¼Į æĺ¾ç¤º +ä¹Ł 让 +ä¸ĵä¸ļ çŁ¥è¯Ĩ +ï¼Į æĥĬ +Ġbl ender +_ AB +AT ING +èIJ¨ æĸ¯ +Ġrem inding +ĠS lim +ten ham +ï¼Į æīĭæľº +ä¸ĭ åľº +ĠPharm ac +ra pping +æºIJ æºIJ +ĠR D +Ġsl ash +Ġwh ichever +B LE +uls ory +Ġç¬¬åĽĽ èĬĤ +çĹĺ çĹĺ +Ġop aque +, çī¹åĪ« +Unselected Node +ing les +好 æŃ¹ +Ġass im +Ġear rings +缴æĴŃ éĹ´ +Ġsurge ons +s app +Inv ocation +å¤į è¯ķ +Ġa il +Ġimpact ing +ĠChar ity +comput er +Coll ision +/ node +éĥij éĩį +æ¹¾ åĮº +ï¼Įä¸Ń åħ± +ãĢģ åħŃ +æħ· æħ¨ +ĠDefault s +人 å®¶çļĦ +è¿Ļ 群 +Ġle aked +æīĵ è¿ĩ +ie ving +åĮĸ çĸĹ +åľ¨ è¿Ļä¸Ģ +Ġr all +ç²¾ç¥ŀ åĴĮ +Parent s +ä¸Ģ åłĨ +art e +社ä¼ļ 责任 +åħ¨éĥ¨ çļĦ +åħ¼ èģĮ +Ġdream ed +Gener ally +. Height +çģ« äºĨ +ra ises +ĠB LOCK +_d istance +Ġunbelie vable +ices ter +IL Y +Ġat op +Ġâ Ĥ +Ġarom a +Ill ust +Ġresign ation +å°Ħ 线 +Own Property +èıľ åĵģ +éĢĤ 度 +ç´Ĭ ä¹± +ĠPers ian +eb ian +Effect ive +om inated +åı¯ ä¿¡ +() - +Ġclean ers +Ġκ α +g ering +èĩ´ çļĦ +ĠS amples +èľ¡ çĥĽ +Ġsl ate +.P ost +. Generated +-s ystem +. inst +-p ower +te c +ĠN egative +Ġiss uance +èĶ Ĺ +çļĦ åĽŀçŃĶ +饥 饿 +Ġpar l +foot note +Ġs ip +ï¼Į æĺ¥ +åīį ä¸ĸ +Ġd h +æ¸ħ åĩī +Ġinsp ires +èººåľ¨ åºĬä¸Ĭ +äºĨ çĦ¶ +æĸ° å¨ĺ +ey ed +ĠM egan +_r andom +主 æķĻç»ĥ +ãĢģ æĶ¿æ²» +Ġt enth +ĠD UI +Ġn ont +åĬłçĽŁ åºĹ +Works pace +ï¼Į æĢ¥å¿Ļ +ï¼Įä»İèĢĮ 使 +_m apping +çŁ¿ çī© +æī¾ äºĨ +sl ant +raw l +Ġhum ility +Ġpop ulate +S on +éĢ Ļ +è¡£ 裳 +ic z +ï¼Į 确认 +èĩªå·±çļĦ 身ä½ĵ +_LO CAL +ï¼Į åĪĨæŀIJ +Ġk eto +S YS +Ġnull able +约 å®ļçļĦ +ç a +, 亦 +h istor +-re lease +æľºæŀĦ åĴĮ +ï¼Į åĮ»çĶŁ +Ġcor ro +æ±ī æĹı +Ġn x +éĵ¶å±ij çĹħ +æĦı å¤ĸçļĦ +æµģ 泪 +ï¼Įç´§ æİ¥çĿĢ +ï¼Į ç±³ +åĽŀ 转 +Ġampl ification +.n ull +çIJĨ论 ä¸İ +Ġfeedback s +in ia +çĸı éĢļ +_det ails +ins ured +QUI RED +combin ant +ï¼Įä½Ĩ ä»ĸ们 +Ġ 以ä¸Ĭ +ï¼Į éĵ¶ +没æľī 被 +æİ¨ è¿Ł +åıijçĶŁ è¿ĩ +Ġgrad ients +ocr ine +uns afe +om ers +è¿· 人 +IO US +Q T +æĪı æĽ² +ĠSpring field +满 éĿ¢ +两个 人çļĦ +Ġinter mitt +be aut +_H PP +izz y +Ġmattress es +\ otimes +åħ³ å¿ĥçļĦ +ĠP est +Ġkn ives +Ġfid uc +ĠD addy +add itional +OR DS +y per +驾 é©Ń +Ġc ri +Ġhum our +path s +Ġmain land +Ġwarn s +æ´ĭ 溢 +æĹ¥ åĩĮæĻ¨ +éļ¶ å±ŀäºİ +.Ab stract +Ġи з +S nap +ãĢĤ æīĢ +Al ice +æı¡ æīĭ +Ġb ast +ĠAtt ribution +ï¼Į èIJ¥éĢł +ĠH H +å© § +Ġant is +ĠD N +表 æī¬ +ĠAs sets +ĠB ACK +: set +åΤ å¤Ħ +Ġlingu istic +æĭī çļĦ +an ion +Ġbl iss +åĤ Ģ +ĠMer ge +" And +_b inary +Sub st +ĠAtt end +ĠPre viously +æĮ£ éĴ± +_ rest +æģIJæĢĸ çļĦ +Ġavoid s +ĠP ione +ĠProdu cer +Ġres urrection +ï¼Įå½¢æĪIJ äºĨ +_IN LINE +çζ çļĩ +ting ham +Inter pol +ĠEN ABLE +ar ag +Ġsl ab +( ptr +ĠTra cy +éĢļè¿ĩ 对 +æ´»æĢ§ çĤŃ +(\ [ +p ix +Know ledge +" But +C ertain +ĠCustom s +ĠEll iott +ĠG ent +(g lobal +, 使å¾Ĺ +Ġins ign +ï¼Į ç®Ĺæĺ¯ +ï¼Ī ãĢĬ +éĥ½ ç»Ļ +ĠK Y +ĠAn xiety +Ġro ds +æĬ¥ åΰ +çģ¯ çģ« +/ u +åIJĥ äºı +ĠNe o +ï¼ļ 对 +Ġmis con +ï¼Į åĩŃåĢŁ +Ġsuper conduct +Ġnumber Of +æĬĹ æĪĺ +................ ........ +(M ath +Ġfol lic +ĠDef initely +Ġcl amp +n pm +Ġcan ine +第ä¸Ģ æī¹ +.C lass +//////////////////////////////////////////////////////////////// //////// +ĠUPD ATE +å¤ĸ å©Ĩ +æĬ¤ çħ§ +ĠD isk +åIJį èªī +纤维 ç´ł +éŁ ¬ +- local +å¼ķ æµģ +ĠEth ical +< _ +Com ing +ĠHu gh +åĮº åĮº +Ġan isot +æľīå¤ļ ä¹Ī +ä¹ī è¯į +_CL IENT +( åĮħæĭ¬ +ĠU X +ãĢĤæį® æĤī +ï¼ĮæĪij çĽ¸ä¿¡ +(f n +: ${ +Ġst ool +ï¼Į éĺ´ +.query Selector +åĩ ĭ +èĢĮ 为 +ä½į æķ° +.M AX +Ġdraft ing +åĽĽ èĤ¢ +ask at +/s ystem +Ġgar ments +çϾ å®¶ +Ġsecret ly +åįļè§Ī ä¼ļ +Ġcou p +op ening +/g oogle +: focus +æĺ¯ ä½łçļĦ +ä¸Ń æŀ¢ +ff t +åıij åĶ® +F ather +ĠD estroy +Ġgre ase +åĹ Ķ +ĠTreat y +åŁİ åİ¿ +_IN S +/f asterxml +A UTH +å½ĵ æĪij们 +åĪĴ ç®Ĺ +sh it +_SE C +Ġwhis pered +G IS +çķ¸ å½¢ +ĠC ave +Ġlabor atories +è½»æĿ¾ çļĦ +p ly +æĪ¿ 举 +_ async +ä¸į åIJĪæł¼ +ĠS ections +æľ¬ é¢ĨåŁŁ +æĸĻ éħĴ +y x +in ic +ĠG F +æ± ¾ +ĠAl uminum +ĠF lying +Ġr ash +åζ åīĤ +ĠC andidates +ĠB es +æľī åĩłä¸ª +Ġarter ial +éħį åģ¶ +ĠBas in +Ġalter ing +ĠH EL +ĠÎ ¾ +éĹ « +ä»Ļ åŃIJ +Ġunexpected ly +OPT IONS +æľī åħ¶ +Ġhypot hetical +ãĢģ åħ·æľī +ĠSPE LL +éķ¿ å®ĺ +ĠL ing +ç͵ èĥ½ +Vert ices +订 è´Ń +{ Y +Ġro oft +ĠFre eman +Account s +满满 çļĦ +il is +å¾Ħ åIJij +åĪĬ çĻ» +Eval uation +çĻ¾åº¦ çϾç§ij +_FA ILED +.Get String +Ġunp aid +å¸Ĥ ä¸Ńå¿ĥ +å¿ĥçIJĨ åģ¥åº· +st ud +ĠL IST +è¿Ľè¡Į å¤ĦçIJĨ +Dis patch +è¿Ľ åĨĽ +Ġadapt ing +ćĆ ï¼Į +å¹³ çļĦ +ĠCr icket +); // +ĠGerm ans +Ġ é½IJ +积æŀģ åıĤä¸İ +Ġut er +ve ct +ä¹ĭ è¨Ģ +ĠQu ite +å¼Ĥ èĥ½ +æŀ¶ åŃIJ +æķ¬ çķı +Ġ å·¥ä½ľ +ĠH T +æĸĩ æĹħ +Ġcart ridge +èĪŀåı° ä¸Ĭ +ä¹Ŀ åįģ +\n o +ä¼ĺåħĪ çº§ +ï¼Į æ¯į亲 +Ġqu ark += */ +å·²ç»ı æľīäºĨ +ĠBudd ha +ĠA CL +g ui +ï¼Į ä¹Į +ï¼Į èĭ± +ĠR um +ath am +追 æĿĢ +V irgin +izz es +_R ATE +Ret ail +Ġsub class +çļĦå¤ĸ è§Ĥ +ĠB ASE +å¤ĦçIJĨ æĸ¹æ³ķ +Ġà ¶ +und y +_D B +Ġvom iting +è®® é¢ĺ +ä¿® éģĵ +ç»Ļ çļĦ +ĠPr inter +è¡Įä¸ļ ä¸Ń +res cent +å°ı éĺŁ +OL S +multic olumn +Ġapp raisal +] string +éķ¿ åīij +Ġschool ing +å·²ç»ı å¾Ī +Ġins ol +å®ŀéĻħ çļĦ +_g c +err al +è° ´ +èµĦéĩij çļĦ +most at +ĠFar ms +Ġmet ic +if old +ĠAtt ributes +Ġaston ishing +Ġsmo other +Ġg own +åŁºéĩij ç»ıçIJĨ +.B lock +æĬĵ çĿĢ +æĪij æĬĬ +/ http +Ġreli ably +åĨ ½ +Ġ"/ " +G AN +ĠC ycl +Ġro s +ç»ĵ æł¸ +Ġp ane +Ġp ans +çĭ¬ ä¸ĢæĹł +_N ON +Ġleg ends +ä¸ĩ 个 +Ġgar ment +Prot ect +Ġnum s +_ lookup +ĠD ermat +(n s +Ġoption ally +ks w +Ġ ä¹Łè®¸ +æŀ¶ ä¸Ĭ +失 è°ĥ +ill i +An ne +bn b +æ½ľ æ°´ +æł¼ æĸĹ +e at +ĠInf lu +Ġalign s +ĠBre aking +ĠÏĦη ν +ï¼Į çĬ¹å¦Ĥ +大 ç¥ŀ +Ġwh ale +_p ub +< List +ä¹ĭéĹ´çļĦ è·Ŀ离 +çĿĢ åĺ´ +æľīå¤ļ 大 +Ġn ond +çĶĺèĤĥ çľģ +ĠNot re +Ġfemin ist +çªģ å¦Ĥåħ¶ +Ġbenef ited +漫 æŃ¥ +ï¼Į åľ£ +.D raw +Ġdet rimental +Ġsub urban +S olid +{ split +ä¹ĭ 士 +个人 ä¿¡æģ¯ +Ġgeneral ization +Ġb ricks +Ġl one +ä¸ĵ åįĸ +è± ļ +Ġover write +夹 ç´§ +åĢŁ çĿĢ +硬 å¸ģ +ãĢĤ åģĩå¦Ĥ +ĠR osa +. Element +ä¹ĭ åĴĮ +æĭħ å¿ĥçļĦ +f an +in atory +ĠCl erk +Ġmotiv ations +ãĢģ å¾· +Âł æŀĹ +ĠAr med +ĠCG Float +çļĦ äºĨè§£ +å°± ä»İ +Ġclass dump +éĢģ ä½ł +åı« ä½ł +éĩĮ 头 +/ client +re verse +çļĦ èĩªçĦ¶ +大家 åľ¨ +ï¼Į 绿 +æľĽ è¿ľ +ĠJackson ville +Initial ized +Ġblow s +Ġp ity +åħ¥ åľº +å¦Ĥ æľī +åΰ åĵªéĩĮ +Ġspark ling +åı¯ æģ¶ +Ġcr ises +ĠCl othing +S quare +ä½į åĪĹ +Dev ices +Na N +ï¼Į ç»Ĩ +ĠContin uing +åı¯ä»¥ 使 +æĿ¥ è§£åĨ³ +ä¸ĸ 代 +åįķ åIJij +ï¼Į æī§è¡Į +ĠG ROUP +è¾ĥ éĩı +ä¹Ŀ é¾Ļ +Ġw il +Ġprogram mer +ath ic +å¿ĥ çĹħ +RO OT +ĠPet itioner +_US B +.pro duct +ĠInvest or +c ou +ãĢĤ æľªæĿ¥ +ãĢĤ ä»ĸ们çļĦ +éĥ¨ ç͵影 +Ġobst ruction +第ä¸ī 竳 +ठĤ +éĵ £ +å·²ç»ı åΰäºĨ +QUI RE +æĿ¥ 访 +å¤Ħ æĸ¹ +ĠProdu ctions +以 èµ´ +好 æĦıæĢĿ +ĠJe ep +éĵ Ĥ +ĠÎ Ń +C our +åĬ± å¿Ĺ +è·¨ åĽ½ +ites pace +en ues +Ġp ts +Ġa vec +-w est +ĠMet adata +h box +å¹² æİī +çĶ· 士 +Ġben ign +Ġsusp ense +Ġcomm its +ä¼ĺ å¼ĤçļĦ +ç¡ħ èĥ¶ +çĸ«æĥħ æľŁéĹ´ +ĠSe q +çĶŁäº§ ä¼ģä¸ļ +æ±¹ æ¶Į +Ġsens it +æ¯Ĵ æĢ§ +ç¼ ¤ +ä¹Ł èĥ½å¤Ł +åĪĨ 管 +ĠWest minster +è¶Ĭ è¿ĩ +ä¹ĭ åŁİ +èĭ¦ æ¶© +Ġp erv +èµµ æģĴ +ĠTrib une +ï¼Į ä¾Ŀæ³ķ +im ing +ä¸ĩ äºĭ +äºĶ éĩij +ï¼Įæ±ī æĹı +çī¹ æĸ¯æĭī +.set On +De leted +ha ul +Ġ_ (" +ĠHar vest +, ç¾İ +èıľ èĤ´ +Second ary +( IN +yd ia +å¼ĢåIJ¯ äºĨ +_com ment +th ora +s at +Ġch assis +æĹ¥ å¤ľ +æ£Ģæµĭ åΰ +Ġnov o +Ġclock s +çĤ¹ çģ« +è½° éļĨ +ugg ling +å¯ ° +G ROUND +H ol +ĠInst itution +Ġviol ates +T icket +äºĨä¸Ģ ä½į +Ġprop het +Ġm ás +åŁº 座 +ĠB ags +Ġent re +T u +ç©¿ çļĦ +å°¿ éħ¸ +å¼ķ èĦļ +ï¼Į éľį +Ġcondition ed +X FF +Ġun employed +Ġw arrants +ĠMut ual +Ġimm ersion +Ġachie ves +l ations +æĪij åIJĹ +Ġ// @ +mut ex +ĠH L +æĶ» æīĵ +t iny +ï¼Į 端 +Ġhe ir +çļĦ 亲 +b h +Ġper ks +ep h +- access +{ # +ĠCont ains +é̼ è¿ij +ĠUp grade +ĠB H +ĠR ack +, 让人 +ĠGr ants +ä¿ĺ èĻı +. URL +Ġtransform er +Ġclar ification +: æĪij +ĠB ars +请 æķĻ +Ġtempt ation +ĠB ills +f as +ist on +L ux +ç®Ģ 便 +ï¼Į åŃŁ +ï¼Ī ä¸ĭ +éĻį è§£ +umb ered +æ´½ è°Ī +éĢIJ ä¸Ģ +ä½ł 对 +Ġheter ogeneous +\ cl +è¿Ļ é¦ĸ +G PIO +æĶ¿åºľ è¡¥åĬ© +æµĩ æ°´ +æ¸ħ åĩĢ +ä¸Ń åŀĭ +ï¼ĮæĪij åıªæĺ¯ +\ sin +Ġbrace let +ann i +æ» ĩ +æ³¢ 纹 +è§ĦèĮĥ æĢ§ +Sub mitted +表çݰ çļĦ +exp ress +Ġl r +åıĻ åĪ©äºļ +% èĤ¡æĿĥ +Ġplay ful +Ġcar bs +. es +ä¸įåı¯ æĪĸ缺 +ãĢģ èĭı +è¾¾ 人 +Ġ ç±³ +icy cle +g able +en et +IB E +Ġadvantage ous +ĠW ol +æıĴ 座 +ĠD ong +éķ¿ éĢĶ +ãĢĤè¿Ļ ä¹Łæĺ¯ +ik k +_T ext +åħ° èĬ± +J B +å°½ æĹ© +åħļ æł¡ +trans ition +Ġ---------------------------------------------------------------- ------------ +Ġinhibit ory +ï¼Į è¿İ +ï¼Į éĿĻ +ãĢģ ç»ıèIJ¥ +Ġtrail ers +ä¸ĭ å±± +è¿ĺ åı¯ +Ġbatt ling +Ġre interpret +_N ORMAL +Ġcyt oplasm +ĠCred its +Ġstrengthen ed +ãĢģ ä½ĵèĤ² +-e ffect +æĻ®éĢļ è¯Ŀ +-s dk +åĨ· æ·¡ +ĠNav al +ï¼Įè¦ģ çŁ¥éģĵ +quee ze +å¤ļ ä½Ļ +åĩĿ ç»ĵ +.M y +\ bar +èģĬ èģĬ +å±ķçݰ åĩº +缸 çα +.assert Raises +/j query +back up +/* . +润æ»ij æ²¹ +Ġg ears +Ġy rs +( ps +Ġ æµĭè¯ķ +æľº 票 +èĥ¶ åİŁ +éĵ¸ éĵģ +è·Ł è¿Ľ +管çIJĨ æľīéĻIJåħ¬åı¸ +-d yld +ç½ ¡ +åĽ½ ä¼ļ +èĤī ç±» +r k +æĸ° åªĴä½ĵ +åı£ åijĨ +,ä¹Ł æľī +organ isms +åĵĨ åŦ +ï¼Į è·ij +å¤ĸ åĮħ +åħ¥ å¢ĥ +åĩŃ ä»Ģä¹Ī +âĢ» âĢ» +她们 çļĦ +æľŁåĪĿ ä½Ļé¢Ŀ +ud ing +.g rad +Ġsupplement ary +åı¤ éķĩ +Ġbur ial +ï¼Į å®ľ +对 åĨ³ +Ġtrend ing +æ´Ľ æĿī磶 +Ġpartner ing +ĠInvest ments +交 æīĭ +å½ĵ äºĨ +ä¿Ŀ é²ľ +C NN +åŀĭ è¯ģåΏæĬķèµĦåŁºéĩij +ĠMir anda +éĿ¢ ä¸ĬçļĦ +Ġin mates +Ġch ambers +åı¯ 羣 +ac i +iss ors +met ric +employ ee +ĠPro per +ĠB ash +ภ¡ +, é¢Ħ计 +åºĶ åıĺ +Ġspeed y +ä¹ĭ éŨ +Conn ell +_h and +å¤ļ æĺ¯ +æ²¹ ä»· +Ġoff ender +Ġsher iff +åIJ¯ èĴĻ +G ift +ï¼Įä½Ĩ å®ĥ +Ġfour teen +Ġmy el +ï¼Į åĴ± +广æĴŃ ç͵è§Ĩ +æĥ¨ åı« +adv anced +åħ¬åħģä»·å̼ 计éĩı +Ġm alf +Ġmon o +追 åĬł +å¼ĢæĶ¾ å¼ı +æĪĺ åĬĽ +åľ° æľĽçĿĢ +ĠBang kok +Ġsub process +çŁ¥ åIJįçļĦ +Ġæľ¬ æĿ¥ +_ch unk +åĬ² åĦ¿ +ĠSurv ival +urt les +$ ). +b undle +åĽŀ å®¶çļĦ +ï¼Į 墨 +ĠC HE +Ġconvey or +é¡¿ äºĨ +âĦ ¢ +é»İ æĺİ +æ¶Ī æķ£ +交 æ±ĩ +æł¡ æŃ£ +ĠN aturally +åĪĢ çīĩ +ä¹ĭ æĺŁ +æĺ¯ æĪijåĽ½ +追 åĩ» +çļĦ åĪĨæŀIJ +ãĢģ åĨľä¸ļ +éĢģ åİ» +A ds +ĠAd elaide +Ġdepend able +æĢ¥ éĢŁ +C ells +Ġ 竳 +è¿ij è·Ŀ离 +çļĦ å®ŀéĻħ +便 æIJº +_S IGN +ph ants +红 æŁ¿ +ĠAR CH +åĴĮ çϽ +ĠGe off +å¦ ĵ +æľī æĹ¶éĹ´ +ï¼Įè¿Ļ éĩĮçļĦ +at itude +ĠPy Object +d estroy +马 å¾·éĩĮ +ç¡®å®ļ äºĨ +çĤ¹ å¤ļ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +ÂĤ Ãij +ox in +Ġ% ( +Ġhun ters +" In +Ġoccup ancy +æįķ èİ· +al gebra +lo qu +èѦ å®ĺ +Ġf al +ä¸Ģ æĹģçļĦ +ĠE ra +éĩĮ è¾¹ +åĵª ä¸Ģ个 +ri zz +Ġbl ah +-f n +çĽĪ ä½Ļ +Ġd ubbed +å¿ĥ æĥĬ +Ġeight een +åīª è¾ij +Î ¶ +.Sh ould +æ¡ ¦ +vent ure +Ġphys i +process ed +滨 æµ· +ĠK athy +æľº åŀĭ +Ġphot ographic +Ġmess enger +个 好 +Ġrot or +å°±æĺ¯ åĽłä¸º +aff le +_un ique +account s +. ` +ĠCon ven +ore ct +ĠB ake +ĠA us +ï¼ļ 第ä¸Ģ +å¯Ĩ å¯Ĩ +: D +Ġ åĪĽå»º +l ake +T rip +ee ee +æĥ³ èĢĮçŁ¥ +Ġmut able +éĩı 身 +p ending +ä¿Ŀè¯ģ äºĨ +MT P +ä¸į äºĨè§£ +缸 ä¼´ +T re +é¢Ī éĥ¨ +E conom +Ġche eks +_ entries +. edit +ĠF t +-b tn +Alloc ator +Z X +\ ; +(ex pr +Ġmush room +ï¼Įèĩª ä»İ +çļĦ åı¦ä¸Ģ端 +Ġhas attr +ref lect +åĪĨ 段 +建çŃij å·¥ç¨ĭ +没 éĤ£ä¹Ī +rec ords +m alloc +A my +Ġdistribut ing +åĮĹ京 大åѦ +èĦ± é¢ĸ +çŁŃ æĿ¿ +ĠPeters burg +Ġst ray +roll ment +( ? +ï¼Įæ¯Ķå¦Ĥ 说 +å®Ŀå®Ŀ çļĦ +: , +ä¸Ģ ä¸Ń +Ġloc us +ĠL oren +Ġur ging +ãĤ ¦ +Ġpet roleum +ĠM d +WH AT +Ch ief +ä¸Ĭ éĥ½ +ac char +ott i +åıĤåĬł å·¥ä½ľ +åķ ®åIJĪ +_s ent +ä¸ļåĨħ 人士 +. Any +ãĢĤ 亦 +Ġpoly ester +A part +Ġc rossover +drop down +CT YPE +çļĦæ°Ķ è´¨ +Ġlifes pan +Ġp ytest +ish ops +é»Ħ æĺı +ert iary +éĢı çĿĢ +éĽħ çļĦ +IS IBLE +.w indow +ur ved +说è¯Ŀ çļĦ +Ġr ansom +æĺ¯ ä½ķ +éĩį çĹĩ +è¿ŀ 串 +-y our +Ġv id +åĿIJ ä¸ĭæĿ¥ +éĢī èĩª +ĠSol o +æĦı 为 +_TH READ +Ġsubsid ies +产ä¸ļ åĽŃ +-th reat +Ġcraft sm +Ġshar pen +åı« 人 +Plug ins +ym oon +-f low +Ġ' & +Ġimplic ation +aster y +ï¼Į ç§ĭ +ĠM ens +æİ© æĬ¤ +ĠEar lier +åºľ çļĦ +å®ĺæĸ¹ ç½ijç«Ļ +å¢ŀ èµĦ +综åIJĪ å¾ģ +æĮī ä¸ĭ +主è¦ģ ç͍äºİ +å¾Ĺ è¿ĩ +Ġelectron ically +ï¼ĮæĪij çľĭ +part y +Ġreminis cent +ĠA uckland +- empty +Å ¥ +i ability +Ġfor wards +ins ky +å¢ŀ çĶŁ +Ġse aling +ç»Ļ åĩºçļĦ +ais y +å®¶æĹı çļĦ +Ġsim mer +ä¾ĿæĹ§ æĺ¯ +åĵ® åĸĺ +ãĢģ åħ¨åĽ½ +ĠBel le +Ġout patient +bro ken +Ġf ries +å°± åºĶ该 +ĠColon el +大 纲 +Ġinter personal +æłı æĿĨ +éĢĽ è¡Ĺ +T ony +Ġcan opy +ä¹Ł åı¯èĥ½ +Ġher d +-w heel +_PRO C +Ġlab elled +Lock ed +ĠD DR +èĦļ è¸ı +-s k +Ġnon zero +m kdir +æłij ä¸ĭ +ĠCamb odia +ï¼Įåıª éľĢ +-section al +ï¼Į 管 +éĺŁ åľ¨ +ĠD anger +osph ate +ert e +Ġant agon +ĠEd monton +è¿ĺä¸į å¦Ĥ +Ġlaugh s +éĽĨæĪIJ çĶµè·¯ +ï¼ļ ä»İ +ä¸ĭä¸Ģ åĪ» +s ometimes +ا ت +Ġe i +åįİ ä¸ľ +ĠPerson ally +Ġstrip es +è¿ ¸ +Ġcon cluding +æĸ° 车 +Get Value +çĥŁ æ°Ķ +: _ +[ < +ï¼Į æİĮæı¡ +ãģ ĺ +. access +h urst +Ġcoord inating +她 äºĨ +åIJij 举 +å¦Ĥä»Ĭ çļĦ +ĠConf irm +DI Y +äºĨä¸Ģ æŃ¥ +Ġadd icted +å¸ĥ æĸ¯ +éķ ¯ +> package +ĠT anzania +stant ial +Col lections +Ġth irteen +Ġor chestra +æľĪ å½± +it ely +ä¸įä½ı çļĦ +æijĦå½± å¸Ī +-est ablished +ph ysical +Ġs inks +大 å°ıå§IJ +Ġauthor ize +_f low +mon itor +Environment al +éķ¶ åµĮ +åĩº äºĭ +Ġæľ¬ 书 +Ġan esthesia +ä¸ĭ 端 +ï¼Ľ èĭ¥ +å·² äºİ +è°£ è¨Ģ +: L +Ġexc uses +ĠV oc +Ġliv elihood +éĩį åIJ¯ +æĴ¤ 离 +J ay +é¢Ĩ åľ° +éͦ æłĩ +Ġkn ots +et ect +为 ä»ĸ们 +Ġan omaly +éĢĤ éĩıçļĦ +Un lock +Ġis omorphic +N m +ĠMy anmar +çϽçĻľé£İ çļĦ +ï¼Į åĩ¯ +è¿· 失 +Ġouts ourcing +Ġa ria +ä¸į æĶ¾ +ä¸Ĭ è¯ī +èĩª åįij +ãĢĤ èĬ± +åĪĨ éĩı +ĠCom ic +éĻĪ ä»£è°¢ +Ġc emetery +æĿĢ æ°Ķ +æİĴ 骨 +tr on +马ä¸Ĭ å°± +æīĵéĢł çļĦ +x space +ä¸Ģ ç±» +éĩij åħī +æ²ī éĩįçļĦ +缸 è¾ĥ +ï¼Įå¿ĥ æĥħ +çŁ³ çģ° +iam ond +_h idden +Ġincor poration +ï¼ĮçĶļèĩ³ è¿ŀ +or get +æĶ¾ çĿĢ +è°ģ èĥ½ +Thread s +åİŁ åŀĭ +åĨį çݰ +é¢Ħ å¤ĦçIJĨ +äºĨ è¿Ľåİ» +ens ely +ĠAnd ers +Ġinspect or +ĠT J +ĠE uclidean +ĠHard y +Ġm illing +äºĮ åĵ¥ +çļĦå¿ĥ çģµ +Ġde comp +åĴĮ ä¼ģä¸ļ +. ps +ä¹ĭ æīĭ +Relations hip +æĦ¿ æĻ¯ +" Well +天 éģĵ +æ·¡ å®ļ +Ġsub po +-col ored +ï¼Įä½ł è¿Ļ +èĥ½ éĩıçļĦ +éħį æĸĻ +顾 å¿Į +ĠMag gie +åıijå±ķ åΰ +ï¼ļä¸Ģ æĺ¯ +) çŃī +声 åύ +the ws +he ard +éĿĻéĿĻ çļĦ +ĠF IRST +Form s +- primary +ä¿ ¨ +-f requency +( form +( shape +ĠPier ce +Ġan te +ï¼Į 客æĪ· +éĶĢåĶ® æĶ¶åħ¥ +ĠRap ids +åį¡ æİ¥ +Ġb ipart +课åłĤ æķĻåѦ +UG E +ĠRo lex +æľĢ åĸľæ¬¢çļĦ +åħļå§Ķ åī¯ä¹¦è®° +ä¸Ģ è¾Ī +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +ĠVAL UE +OR ITY +åѤ åĦ¿ +çļĦ çī¹å¾ģ +math it +æ²³ 举 +ĠH ouses +Ġmult ivariate +ä¸į å½±åĵį +.A nd +hib ition +_l ight +X i +Ġp on +c aps +des criptor +æīĵ æĭĽåĶ¿ +è¯Ĭ æīĢ +å³ Ń +èģĶç³» ç͵è¯Ŀ +æĬķåħ¥ åΰ +æĤ¨ åľ¨ +çķĻ çĿĢ +ĠThank fully +c els +\ tau +åªĴä½ĵ æĬ¥éģĵ +ภµ +Ġk idding +éĻį èĩ³ +Ġ' \\ +.sw ift +身边 çļĦ人 +ĠRef riger +H oliday +ĠE RA +å°Ĩ è¿ĻäºĽ +çľ¼ 羸 +å·´ å¡ŀç½ĹéĤ£ +Ġyour selves +ĠMonth s +_ext ension +C op +ä¸įå°ij äºİ +Ġbag gage +en stein +ĠO W +æĸĩ æ¡Ī +ĠV irus +è¿· ä½ł +_ ED +å¾Īå¤ļ æĹ¶åĢĻ +ï¼ĮæŃ¤ å¤ĸ +ĠL INK +åĽ½ ç«ĭ +æ£Ģ çĸ« +æľĢ ä¼ĺ +太 å®Ī +ĠB eds +.A spNetCore +èµĽ åľº +p ow +ç® Ķ +-pro v +表 ä¸Ń +æ·ĭ æµ´ +ĠTele gram +_des criptor +ĠT ARGET +Ġdiscipl inary +侦 å¯Ł +- standing +ĠZ h +IN ARY +å¾Ģ 常 +ä½ł æĪij +æ°´ ä¸Ĭ +ä»Ģä¹Ī åı« +çī¹çĤ¹ æĺ¯ +Ġcl i +Ġout we +æĺ¯ä¸Ģ 座 +ï¼Į æīĢè°ĵ +ä½İä¸ĭ 头 +ï¼Įè¿Ļ 对 +ä» Ħ +Ġimp rint +èĥĥ èĤł +Car ol +å°Ĩ å®ĥ +Ġgrad ing +ãĢģ å§ľ +ĠL ose +åIJĮ å¿ĥ +ĠCom par +Ġ åΰäºĨ +.s un +ĠSand ra +缸 åĬ© +Ġdr ank +ĠSupp liers +ĠAut hent +ĠA unt +æĥħ å¢ĥ +H OW +饼 å¹² +R os +ĠS ag +西 è·¯ +# elif +奶 æ²¹ +at is +æĺ¯ æĹłæ³ķ +æ»ļ çŃĴ +s ender +ĠLes lie +ï¼ģ âĢľ +.IsNullOr Empty +ĠContin ental +ĠN K +и з +ñ o +Ġred shift +Tool bar +rem ark +èĥ½ 使 +_s ide +ace ae +æİ¥è§¦ åΰ +Ġc yn +æĦŁè§ī åΰäºĨ +it atively +Ġmon ot ++ $ +ak istan +Ġid iot +- am +, åĽ½å®¶ +Ġsc ars +Ġitiner ary +_ play +ç¢ ĺ +he tti +erv ille +OB JECT +Ġamb itions +çłĶç©¶ ä¼ļ +ĠSk etch +ãĢĤ ä½ľèĢħ +' ", +ãĢĤ åı¶ +æ¤į åħ¥ +Ġjack ets +E mitter +ĠM VP +è¡Ģæ¶² 循çݯ +ic able +ãĢģ çľĭ +èĩª 带 +ç¡ ¼ +åĩºçīĪ æĹ¶éĹ´ +Ġst o +(- \ +ĠNew sp +,ä¹Ł åı¯ä»¥ +å¼Ģ åĩº +ĠRuss ians +åIJĬ é¡¶ +ĠHay es +Ġgastro intestinal +Ġcalcul ates +Ġconf ession +ĠTr igger +åĻ© 梦 +ä¸Ģ æī« +_R ANGE +. platform +Ġh ust +å±ıå¹ķ ä¸Ĭ +ĠCar b +Ġax ial +积 æ°´ +Op inion +ĠTri angle +ĠE fficiency +æŃ¦ å°Ĩ +REF ER +å¤ļ æĥ³ +ç ões +æĶ¾ ç¼ĵ +Ġexplo ited +æ²ī 稳 +æ²¹ èħ» +.y aml +ç¾İæľ¯ é¦Ĩ +') ). +ĠR ex +ãĢĬ æĸ° +ĠLib ya +æĭĽèĤ¡ 说æĺİ书 +Ġreg imes +ING TON +Ġ æĮīçħ§ +B road +ch ief +æ¸ħ æ·¡ +è·Ł ä»ĸ们 +ĠWals h +Ġselect s +_W INDOW +å°±æĺ¯ æĪij +âĢľ ä»ĸ +ig rate +åºĦ 严 +Ġiron y +åħ¬ ç͍ +En sure +æIJľ 寻 +Ġbul lets +× ľ +.f actory +ç£ ĭ +ĠCr ushing +ĠAct ual +de al +ä¹Ł ä¸Ģæł· +ä¹ĭ æĦŁ +Hash Code +ä¸Ģ 模 +Ġv icious +è·Ł æĪij们 +Ġcatast rophic +çİĩ é«ĺ +Inter action +ä¸į æĸ¹ä¾¿ +s yn +Ġà ¥ +_ entity +Kit chen +act ively +ampl ed +Ġmon et +op o +ard e +éĽħ åħ¸ +ĠH olding +æĿ¾ å¼Ľ +帷 å¹ķ +ä¸į 符 +ä¹ĭ å¹´ +æ°ij æ³ķ +Ġlumin osity +éĻĪ åĪĿ +ML S +w ife +Ġm ens +( conn +ĠK un +_S M +å°ıæĹ¶ åIJİ +\ draw +ï¼Į æµij身 +åĺ± åĴIJ +ĠCraw ford +Ġgu i +ï¼Į æŁ¥ +om ation +" }) +ãĢģ 车 +èŁ Ĵ +Ġadmit ting +çϽ çİī +çģŃ äº¡ +马æĭī æĿ¾ +Ġpestic ides +, ä»·æł¼ +? v +ä¸ī å±Ĥ +Ġaltern ating +丹 麦 +åįķ åįķ +ä¸į è´¥ +Ġles bian +-ind ependent +æĹħè¡Į 社 +-d ist +ï½ ħ +/ U +ĠP urs +èľ Ĵ +åĶ¿ åĶ¿ +Ġalle le +Ġid ol +Ġmult in +ĠSat isf +Ġerr no +ï¼Įå°± 被 +Ġempower ment +ĠM ongo +ĠDis order +ĠW ings +Op code +ĠCh rys +.c enter +åĴĮ éĶĢåĶ® +代çIJĨ åķĨ +ĠAbb ott +Fil m +Ġpsych ologist +uc son +for ces +çĶ» çĶ» +åħ¬å¸ĥ äºĨ +ï¼Į ä¿¡ +è¿Ļä¹Ī ä¸Ģ +mar ine +çĶļèĩ³ æĺ¯ +{ J +åĮħ åĮħ +Ġgen etically +ä¼ł æĿ¥çļĦ +Ġt ak +红 楼 +ĠSe al +ĠB ytes +ent ral +CR YPT +ĠSem i +ĠR atio +é¸ ¾ +ĠR is +èᝠä¸ļ +Ġs g +Ġtrig gering +- condition +çĸ µ +Ġtel escope +çĩķ åŃIJ +主 æĿ¿ +äºĮ èĢħ +æ°Ķ 泡 +Ġdep rived +Ġpy ramid +ภ¥ +详ç»Ĩ ä»ĭç»į +Ġ åŃŁ +Ġspark ed +åĴĮ å®īåħ¨ +Ġconserv atives +Ġb ells +Ġch orus +æľī 线 +åĶ¿ åIJģ +: B +Ġmurd ers +l x +Ġfun ctor +æīĵ åıij +Ġst mt +ãĢģ æŃ£ +t ile +ĠPol ar +æĦĪ åıij +ĠStock s +L ot +Ġheaven ly +Ġst ern +ĠHelp ful +_U ART +åĴĮ åŃ©åŃIJ +Ġprogress ed +Ġavoid ance +以为 èĩªå·± +Ġwid ow +ãĤ· ãĥ +æĸ°é²ľ çļĦ +æľĢ éĢĤåIJĪ +(" ", +Instance Of +ĠSund ays +æģĭ 人 +.s ervices +ठ¨ +ĠCount ries +åħ¥ çĿ¡ +è·³ åĬ¨ +è¦ģ èµ° +æĪij æīį +åı¯ 为 +_p ar +Ġmerg ing +Ġre written +IF IC +Ġh obbies +é«ĺ åľ° +å¼Ĺ åħ° +ãĢģ D +Ġharvest ing +Ġtravel er +Ġ 导æ¼Ķ +Ġy ork +Ġsn apped +è´¢ è¿IJ +丹 èᝠ+ãĢĤ å®ī +宫 é¢Ī +æŃ£ç¡® çļĦæĺ¯ +ï¼Į æ²Ļ +Ġup hol +([ [ +åķĨåĵģ æĪ¿ +æĨ ¬ +ĠLanc aster +æĭĸ çĿĢ +Ġpropri et +Ġrevers ible +Ï Ī +åĩº åĵģ +çªģ åıĺ +, åİŁæĿ¥ +As String +çŃī ä¸Ģç³»åĪĹ +æĻ Ĺ +_H AND +ad h +ï¼ļ 大 +ĠS IGN +ï¼Įä¸Ģ åıĮ +ĠU int +çij ļ +ç¹ģ å¿Ļ +âij ¥ +Ġsqu ir +ĠHor izon +-work ers +S itemap +Ġt apping +çļĦ è¿ŀæİ¥ +äºĮ åı· +çĻ» å±± +çļĦ å®īè£ħ +Ġ[ \ +å¿« é¤IJ +>: ]< +Ġpast ry +R IC +ãĤ £ +ĠL ithuan +, ç»Īäºİ +ĠIncre ased +Ġtack les +. You +Ġtool bar +ĠU IT +ĠD j +under ing +Ġp ian +åĪ© æĸ¯ +伤 çļĦ +Ġdess erts +Ġcollabor ating +æĬ ī +Ġp antry +ĠD il +ï¼Į ç¨į +ch rome +ä¸ĭ åįķ +ï¼Į æŀĦ建 +semb ler +Ġcan ned +ï¼Į éĢĢ +Ġn ach +æĬķ 身 +缮çŀª åı£åijĨ +rom a +ç®Ģ缴 æĺ¯ +éĤ£ åıĮ +奥 æŀĹ +/ usr +以ä¸ĭ æŃ¥éª¤ +Ġliqu ids +ne ider +/* ! +åı· 为 +Pal ette +ĠL on +_j ob +Ð ł +ĠInterest ing +ï¼Į ç»ĵ +agent o +ï¼Į D +ĠG ol +ï¼ī 为 +_s lice +( server +åĩº çĶŁçļĦ +Ġtack ling +]-- [@ +åħ¥ åĽ´ +è¾ľ è´Ł +éľ ĵ +M ARK +Ġso fter +ç¾ ¹ +Ġcert ifications +R ussia +-p ass +.Print f +, ä¸ĢäºĽ +ke a +åIJij ä¸ĬçļĦ +_f ound +Ġforecast ing +å¿§ èĻij +ĠCur ry +Ġ éģĵ +Rep resentation +ë ĵ +est a +, æķ´ä¸ª +å¹½ çģµ +ç͵éĺ» R +Ġdecis ive +åı· å¡«åĪĹ +Ġfoot wear +, å¦Īå¦Ī +ï¼Įå¹¶ äºİ +ï¼Įéĥ½ è¦ģ +> ? +El izabeth +横 æ¢ģ +ï¼Įåľ¨ æĪij +åħ³ ç¨İ +.m at +ĠB iol +/ apache +anc a +ä¸Ĭ åı¤ +^ x +Ġdist al +Ġdra ined +åĽŀè¿ĩç¥ŀ æĿ¥ +P retty +Ġs add +æīĵ è¿Ľ +c urrency +d isk +ĠM ant +天 æĸĩ +ĠBl ade +ĠRep orter +个æľĪ çļĦ +人为 æľ¬ +ï¼ļ 人æ°ijå¸ģ +é«ĺ çĤ¹ +' est +Ġ åºĶä»ĺ +-ch oice +ĠCondition ing +åħŃ å¤§ +Call ing +ï¼Įä¸Ģ å¹´ +ï¼Įçľĭ äºĨ +åĴ³ åĴ³ +Ġhelp ers +åĩºåİ» çļĦ +B an +ĠDis orders +Ġgest ures +ĠY a +ç»Ŀ ä¸įä¼ļ +Ġaction able +ĠStart up +ĠVeg an +h bar +Ġc is +Ġc ured +导 éĢļ +åİĭ æł¹ +comb ination +ç® « +_F ROM +ĠHol ocaust +v ag +å²Ĥ ä¸įæĺ¯ +Ġvamp ire +çĸĹ ç¨ĭ +K R +Ġs iding +ĠHel iport +_C lick +}} $. +æĺ¯ä¸Ģ åıª +éģı åζ +Cond itions +_l ibrary +ï¼Įæį® 说 +iff erence +min i +å°Ħ åĩº +ä¸į éķ¿ +座è°Ī ä¼ļ +cloud let +ĠEvery body +P ixels +ãĥ ī +ĠSpr ay +åIJĥ 饱 +_m an +Ġprof iciency +Ġmunicipal ities +å½¢ èµĦ产 +åįĹ è·¯ +me asure +éļĶ æĿ¿ +Ġneglig ent +åIJĪä½ľ ä½ľåĵģ +in ally +J V +ï¼Į éŃı +ãĢĤ å¦Ĥä½ķ +马 ä¸ģ +表 çϽ +My SQL +F ri +ä¹Ł 说 +æ»ļ è½® +elle es +-le ading +Ġvel ocities +ommod ation +ä¸Ń æĸ° +Ġà ī +æĪIJç«ĭ çļĦ +Ġa kin +ĠExt reme +ï¼ĮæĪij éĥ½ +ĠB illion +Call s +âĢĿ ? +Ġinter connected +马æĿ¥ 西äºļ +ĠCal c +å±Ĭ ä¸ŃåĽ½ +Ġmyocard ial +èĿ Ļ +ĠImm utable +_P OWER +æĶ¯ çIJĥéĺŁ +_e ach +Ġtum our +ĠAl ready +Ġrepair ing +åģļ åΰçļĦ +åģı 离 +ï¼Į è¶³ +ï¼Į æĽ¹ +å®ĮæĪIJ ä»»åĬ¡ +ĠDevelop ers +P ARAM + ı +åĸľæ¬¢ åIJĥ +è¿ŀ èĥľ +. assign +æŀĦ æĪIJäºĨ +ĠDav ies +ä¹Łä¸į ä¾ĭå¤ĸ +Ġflo oded +Ġampl ifier +rib s +åį¡ æ§½ +é»ĺé»ĺ åľ° +åįĬ æľĪ +, çĶŁ +in cre +he ws +ĠM ozilla +ĠWh ilst +.j p +ĠR w +OT AL +-t rack +ĠCL I +. head +ä¸Ŀ æĿĨ +æİ¨ æĿĨ +åħ» çļĦ +ĠBe ef +ãĢģ åĵģçīĮ +UR ATION +管 线 +Ġfing ert +ĠPenn y +ç¾İ éĩij +Ġintim acy +ï¼Į åıĸå¾Ĺ +çĤ® å¼¹ +Ë ĭ +åĽ½ 度 +Ġin ward +éĿŀ æĺ¯ +. ic +ĠCow boys +èµĽ åIJİ +åı¶ èIJ§ +竣 æĺ¯ +ethe us +Ġno ises +éļ¾ çļĦ +Ġbuck ets +Ġrend ers +ĠD estination +Ġchrist ian +F ed +æīĭç»Ń è´¹ +ĠLat ino +æľĢåĪĿ çļĦ +è¾ĥ å¿« +大 éĿ¢ç§¯ +.... ..... +Ġvou cher +ĠCelt ic +åķĨä¸ļ 模å¼ı +æĪij 羣çļĦ +è¾ « +Ġmin ers +ĠCard inals +Ġcho ir +Ġred esign +Ġday time +ï¼ĮæĪij åİ» +Ġhydro x +ĠâĪ Ĥ +Ġnot icing +ï¼Į åIJ¸å¼ķ +Ġc rab +< th +çĥ¤ ç®± +Mac ro +èĥĮ çĿĢ +.Param eter +over n +æľīæīĢ ä¸įåIJĮ +交 éģĵ +书 æľ¬ +Ġaff ine +-f ashion +rust ed +æµģç¨ĭ åĽ¾ +çļĦ æĸĩä»¶ +Ġ- . +æĪij ä¸Ģ缴 +ä¸į çν +åįķåħĥ çļĦ +Interest ing +ĠMeasure ment +_ est +.c an +Ġscar ce +ĠRec all +çļĦ æĬĬ +,æĪij åĽ½ +ï¼ĮçĶŁ æĢķ +prot ect +Ġsub urbs +{ . +Ġne o +che ap +å¥ij åIJĪ +çIJĨäºĭ éķ¿ +EMPL ATE +S up +Ġal ley +Che ers +ĠAk ismet +ĠRoberts on +< meta +ĠF res +è¿ij åĩłå¹´ +æ¤į çī©çļĦ +çĵ¶ åŃIJ +ç«ŀ ä»· +Collect or +@ in +äºĨä¸Ģ 段 +_T OP +æķħ 宫 +ĠT ales +Ġstrateg ically +ï¼Į çͰ +ĠConsult ation +ç«Ļ起身 æĿ¥ +æ£ĭ çīĮ +_ ab +Ġf aux +c row +Ġbook ings +ocr at +ĠNS A +Ġunder mine +AD I +两 ç»Ħ +ĠComb ine +ï¼Į èĩ£ +äºĮ æľĪ +G LOB +Ġreview er +åįĪ åIJİ +æ°ĶåĢĻ åıĺåĮĸ +æ°ij ç͍ +Ġevid enced +ï¼Į æİ¥åıĹ +av igation +AS ON +åIJĦ æł· +Ġrot ated +H al +ĠAr lington +ĠHait i +j en +æ¯Ķ ä¸įä¸Ĭ +Ġstamp ed +âĢľ æĹł +ĠY emen +èµŀ æĪIJ +ĠEnter prises +ï¼Į顺 便 +æ¸ħ é¦Ļ +Red is +\ mathbf +Ġinv ocation +çļĦ天 空 +n ob +_s ummary +IR M +å®¶ éŨ +. order +Ġth o +ç§Ł 客 +èĩªçĦ¶ 人 +ĠEug ene +ä¸į 稳 +ĠBro ck +Ġread iness +Code Attribute +P oll +y led +ĠRug by +ĠP AR +æĿij èIJ½ +ĠC ec +Do ctor +åĩı åİĭ +p aste +ver bs +Ġ çͰ +Ġar che +=" ' +Ad ult +æ½ľ èĥ½ +, çĶŁæ´» +ãĢĤ æľī人 +ä¸į åIJ¬ +. entry +ime q +St an +çĶľ ç¾İ +çİĦ æŃ¦ +æŁ ij +be ans +F avorite +]. [ +ä¸Ĭ åı° +Ġinv oices +ï¼Į çģµ +å¹¶ èĤ© +SE ARCH +Ġshowc asing +沿 线 +Ġtur f +b az +Ġdest ined +Ġ å·² +ell ation +ãĢĤ éĤ£ä¸ª +ĠW id +iz ons +Ġend ogenous +ï¼ĮèĢĮ ä»ĸ +v oice +ï¼ļ http +Ġbow ling +D st +.b uilder +Hand ling +Ġrec ap +ict im +Ġpar ole +èµ° èµ° +æ¦ ķ +表 çİ°åľ¨ +Ġlo ft +å¯Ħ æīĺ +ãĢĤä½Ĩ åľ¨ +is EqualTo +ĠDi agnostic +.g lobal +ĠBur ton +è°İ è¨Ģ +-d uty +Ed ges +åı£ 头 +Ġprosecut ors +åĩº ä¸į +没 ç͍ +åĨħ æł¸ +Ġhard ship +æİ¨ ç§» +ï¼Įæĺ¯ 以 +b ill +- port +v endor +Ġâ̦ âĢĿ +Ġwh ip +Ġarchitect ures +W estern +é¢Ĩ ä¼ļ +Ġ ž +ĠIC U +Ġmort ar +çļĦ éģĵè·¯ +å°± åĴĮ +ĠEqu ations +Ġ" ^ +ĠH AS +ex c +? ), +}( {\ +omin ium +ĠCard inal +ven ous +Th rows +åĹĵ éŁ³ +ĠP recision +举 æŃ¢ +宾 客 +Ġunder gone +_ lo +åĭ ķ +Ġirres pective +æĪĺ åľºä¸Ĭ +n z +m or +ĠTh r +ĠNew port +ĠRich ards +Ġalleg ing +Ġ第ä¸Ģ 竳 +ï¼Į å®ŀåľ¨æĺ¯ +ĉĉĉĉĉĉĉĉ ĉĉĉ +ĠP orsche +åį° è®° +Ġdem ographics +ä¹ĭå¤ĸ çļĦ +ĠSuper man +Ġgen otype +åĩ¹ éĻ· +Ġ ÙĦ +ï¼Į å°ģ +Ġsk ipping +ä¸İ 她 +å¼Ĥ æŃ¥ +Ġright ly +åı¯ ç¬ij +æµĭ ç®Ĺ +ç»ĻäºĨ æĪij +éĤ£ä¸Ģ åĪ» +âĢĿ ä¸Ģ +ĠMc D +f elt +讨 好 +ĠHar old +Ġr uby +_c ard +Ġz ombie +he mer +ï¼Į éĢIJæŃ¥ +Ġh atch +-c ert +åħ³ éŨ +Ġget attr +ï¼Įä½ł èĥ½ +Ġs ag +çļĦ åĬ¨åĬĽ +Ġab ide +åζ è£ģ +ï¼Įåıª å¾Ĺ +sk in +ĠJoy ce +äºĨä¸Ģ åıª +Ġbl onde +od iac +Ġswift ly +ĠD ashboard +ĠS aving +Inter ceptor +æķij äºĨ +-grad ient +é£İ 湿 +ãĢĤ åIJĮæł· +ĠSt raw +Ġle thal +.as List +çīĪæĿĥ å½Ĵ +( im +å¤ĸ æĺŁ +ĠDevelop ing +ĠÎ Ľ +Ġadvers ely +-h op +æĶ¾åľ¨ äºĨ +- li +å¤ļ ä½į +ä½İ äºĨ +群 çļĦ +adv ance +ĠStri ke +_RE SP +çļĦ人 åı£ +S low +æĸ° æĿIJæĸĻ +ä¸Ĭ å±Ĥ +Ġs outheast +Lou is +Ġal right +y et +åĪĬ çī© +Ġcan on +_pro xy +_K ERNEL +s ell +Ġpul p +ĠS isters +åĽ¢éĺŁ çļĦ +åıĺå¾Ĺ è¶ĬæĿ¥è¶Ĭ +Ġsand y +IN AL +input s +æµ· 滩 +è´µ éĺ³ +大å¤ļæķ° 人 +èIJ§ å¹³ +æľīçĤ¹ åĦ¿ +æ¡Ĥ èĬ± +ĠW itch +ĠE ur +P ractice +åįĪ é¥Ń +ht ra +åı¹ äºĨä¸Ģåı£æ°Ķ +V V +Ġafford ed +Ġ å¾Īå¿« +len a +ï¼Į å®ĮåĸĦ +ç¡® åĪĩ +纳 åħ° +æıIJä¾Ľ ä¸Ģ个 +ĠAt om +b irds +enn ial +se o +空 å¿ĥ +ãĢį ãĢĤ +Prov ide +IN F +åħļçļĦ äºĮåįģ大 +èµĦæľ¬ åħ¬ç§¯ +ä¸Ģ æīĢ +ĠS ic +Ġbi ochemical +æĸ°åĨłèĤºçĤİ çĸ«æĥħ +Ġrec ycle +æĤ ¼ +åĮ £ +计æıIJ åĿıè´¦åĩĨå¤ĩ +_C REATE +åħ¸ èĮĥ +Ġchar coal +ï¼Į大 åĬĽ +éĽķ åĥı +ï¼Įä½ł æĥ³ +Ġterrit orial +æĬµ æī£ +ĠDE V +Ġcyt ot +ĠC GRect +ç¥ º +æĿĢ æİī +ĠPass ion +ĠM AY +æľī ç͍çļĦ +åĮ»ç§ij 大åѦ +. reshape +ĠH ollow +æ° ° +Pl ant +ĠP ale +Ġfurther more +åIJİ æīį +Ġpoison ing +-bre aking +T ail +Ġd ancer +IT IES +ĠNe ural +Ġg le +èĪª 线 +ï¼ģ ä¸įè¿ĩ +缸 æĢĿ +N umeric +Ġg ossip +Ġ èĩ³ +çľ¼ ç§ij +åĩº åĬ¨ +ï¼Į身 åŃIJ +ĠCom es +çŁ³ èĨı +ç§ģ æľī +_ AG +An imal +[ % +| null +ĠI CC +çĿģå¼Ģ çľ¼çĿĽ +ï¼Į åĮħåIJ« +ç§Ł 车 +çļĦä¸Ģ åįĬ +èĿĻ èĿł +åı¯ åı£ +ĠTerrit ory +åĬŁ è¯¾ +人 èĦ¸ +èĢħ 为 +åı² è®° +宽 带 +Ġcous ins +èѦ æĪĴ +交 ç»ĩ +Ġ åŁºæľ¬ +ĠB ac +pro ceedings +Ġuphol st +S olar +{ min +(f mt +-en abled +. pr +ĠH ers +Ġunit ary +ĠComb ined +ĠS lee +od ot +ba um +ĠFran co +礼 æĭľ +Ġim balance +éĢı éķľ +Ġauto immune +ï¼Įæľ¬ çĶ³è¯· +Ġknock ing +_f actory +Ġbl u +ĠAbb ey +-s ix +( Data +ĠIndones ian +Ġsil hou +n ice +sequ ences +Ġrecomm ending +ĠBro ken +æķĻå¸Ī çļĦ +橱 æŁľ +çĸ Ļ +Ġaddict ive +ï¼Į 讲 +Ġtext books +è¸ı åħ¥ +ĠP orts +çŀª çĿĢ +B ug +ç¨ĭ 约 +Ġcook er +}\ \ +åĴĮ æŀĹ +å®¶ ä¼ģä¸ļ +纤 ç»Ĩ +_R D +Cal c +çļĦ èµĦéĩij +æ¯Ľ åıij +åŁĭ æĢ¨ +ĠA gg +容 é¢ľ +ï¼Į ç¨ĭ +om ew +ç¬¬åĽĽ 竳 +缼 ä¸ĸ +Ġ& ( +åĨħ åĪĨæ³Į +ĠAb original +im acy +å°ı å¹ħ +åħ¬ åħ³ +åįĸ äºĨ +æĿĥçĽĬ å·¥åħ· +Conf erence +ĠNew man +ï¼ĮåĪĻ æĺ¯ +Plan ning +Ġsur geries +Ġpun ished +Dep ending +ĠCur riculum +/ sub +çĶ· çļĦ +ĠConf eder +_HE IGHT +Ġpsy cho +ä¹īåĬ¡ æķĻèĤ² +C riterion +Ġcl utter +èµ ĥ +ãĢģ è¡Įä¸ļ +Ġ 常 +ä¸Ĭ éĥ¨ +Ġident ifiers +éĹŃä¸Ĭ çľ¼çĿĽ +LE VEL +èģĮä¸ļ æķĻèĤ² +åĬŀ çļĦ +ï¼Į å½¼æŃ¤ +arr ison +èµ°äºĨ åĩºæĿ¥ +ll ib +ãĥ IJ +åĴĮ社ä¼ļ ä¿Ŀéļľ +çļĦ è¶ĭåĬ¿ +ĠH oo +ï¼ļ è¿Ļ +Ġaffirm ative +ĠS inger +åŁºç¡Ģ çŁ¥è¯Ĩ +å¾Ī大 ç¨ĭ度ä¸Ĭ +Ġ æľĢè¿ij +Ġm sm +ĠWh olesale +_P H +人åijĺ åľ¨ +$ f +ĠB F +æľ¬ å±Ĭ +_read er +åıª çŁ¥éģĵ +èĬĤ çĤ¹çļĦ +-d iscovery +ub ic +Some one +d ma +æģIJ é¾Ļ +Ġprec ursor +çļĦ æľªæĿ¥ +_dis able +Ġint ros +n atal +ï¼Į å¤ĸéĿ¢ +Ġsal ine +ä¹Ĵä¹ĵ çIJĥ +æ³ Ĺ +il age +Ġ Ùģ +_param eter +ï¼Įåıª éľĢè¦ģ +æ· Ĩ +ĠRent als +æĹ¶ 髦 +cal ing +.s ample +åıĭ 们 +ĠPa id +ĠSat ellite +Ab ility +ĠB olt +ï¼Įå¹¶ 以 +ãĢĤåľ¨ è¿Ļ +ang s +转 è´¦ +éĤ£ å°±æĺ¯ +Ġexpans ive +H arry +éħ¸ éĴł +çīĽä»Ķ 裤 +_RE Q +è´¦ é¾Ħ +ĠE Q +Ġin verted +Ġtra ctor +ÑĢ Ð°Ð½ +/ Y +.A d +Ġtw ists +çIJĥ æĺŁ +纸 è´¨ +Ġgrocer ies +Ġir reducible +Ġheter ogeneity +æķĻ å®ĺ +Ġlean ed +Ġdigit ally +Ġru pt +çľĭåIJij äºĨ +ä¸į æİī +èĦ± åı£ +- containing +è¦ģ 让 +诱 导 +人 头 +æĿľ ç»Ŀ +ĠTry ing +n os +å±ĭ åĨħ +Reg ardless +ï¼Į 汽车 +_s im +Ġa o +çĤ« èĢĢ +< M +S now +z oom +ãĢģ 综åIJĪ +.t ools +Ġforget ting +èĬ³ é¦Ļ +iph one +ãĢģ ä¸Ģ个 +ï¼Į æ¶īåıĬ +.t emplate +æī¾ 人 +转åŀĭ åįĩ级 +-w rap +åĨ¬ 奥 +olog ous +éĢļ åħ³ +ĠL OT +åĬŁ èĢĹ +åħ¬åħ± æľįåĬ¡ +ĠPro gressive +B roadcast +Ġdis joint +.F irst +èħ° éĹ´ +Ex actly +arr is +ĠEditor ial +Ġ éĽª +çݩ家 们 +Ġambig uity +è¤ ¶ +Ø ® +gu ide +\ neq +Ġpersu asive +O ffer +æŃ£ çļĦ +ĠA xis +ĠØ ¹ +å¢ŀ éĩı +ãĢģ åĬł +çľ¼ éĥ¨ +Ġdecl ines +Ġins ists +ĠEvent Args +Ġre connect +ksw agen +åı¯ æİ§ +Pub lish +$ as +S alt +ä¾Ľ çĥŃ +Ġscript ure +Ġw o +ycl erView +ĠLI KE +M RI +Ġhydro ph +æĥ³ å¿ħ +é»ijæļĹ ä¸Ń +ä¿ĿæĬ¤ åĮº +åĽŀ æµģ +ix in +Ġnot orious +å°± 缴æİ¥ +Ġburg l +åħļç»Ħ 书记 +qu a +è°ĥ åĴĮ +Ġtrust s +å®¶ å®¶ +ch apter +缴 è¾¾ +æĿĢ æĪ® +çĸij éļ¾ +Ġalter ation +Ġthrom b +计åĪĴ çĶŁèĤ² +åİ» æİī +æ¶ī æ¡Ī +缮 çĿ¹ +åĬ¨ ç͍ +Ġfall back +ä¿Ĺ è¯Ŀ说 +ãĢĤ è¦ģæĺ¯ +ï¼Įå°± è¿Ļæł· +åĺī åħ´ +ĠN MR +ost a +æ¶² çļĦ +å¸Ĥåľº 份é¢Ŀ +Ġpath ological +Lead ership +ĠW elfare +åĿļ 飧 +Ġacc ents +.m edia +ĠCreat ure +Ġob edience +大 鼨 +_P ART +PC I +éĺ² çĽĹ +Dep loyment +çļĦåIJİ æŀľ +çļĦæīĭ èĩĤ +Ġfeather s +ä¼ł è¨Ģ +c ape +ĠB ella +Ġtestimon ials +ï¼ĮæĪij æīį +ĠQu iz +n it +Ġdefic its +oglob in +Ġgam ble +ä¸į æģ¯ +ĠK ubernetes +ç§ijæĬĢ è¿ĽæŃ¥ +åħĥ å·¦åı³ +Ġth or +rang ian +Ġ= ==== +p rec +ï¼Į ä¼ļæľī +Ġret al +æĢĿæĥ³ çļĦ +Ġpres erves +太 好 +k al +éªĤ éģĵ +ä¸ĸçķĮ éĩĮ +èİ« åIJįçļĦ +åľ¨ æķ´ä¸ª +å½ķ ç͍ +_MEM ORY +ï¼Į 综åIJĪ +Ġmis use +ĠH BO +ĠPar l +ä½ĵ è´´ +äºĨåĩł åĪĨ +躺 çĿĢ +f actor +å¢ŀ åĩı +en ment +Ġ å¾Ī +使 æĪij +Ġsk ins +åºĵ éĩĮ +B oy +Ġ第äºĮ 竳 +\ over +_ users +Ġem pt +çŁ¥ æĥħ +sk a +éĵ İ +Ġä¸į 管 +å¸Ĥ åħ¬å®īå±Ģ +ĠEth an +B erry +[ * +Ġcreep y +ĠEn v +Ġm appings +ĠM olly +Ġconting ent +æŀ¯ çĩ¥ +Ġocc urrences +è¿Ļ ä¸ľè¥¿ +EE P +ĠSoph ie +ĠR H +åĽ½ ç±į +_reg s +$ data +ĠFerr ari +ĠB ind +åķ¦ åķ¦ +_ android +ï¼Į è¿ľè¿ľ +åĨ³ æĪĺ +B ron +ĠW inston +sw ick +.d ot +j d +æµ· åı£ +Ch oosing +æŀĹ çļĦ +Ġhep atic +深度 åŃ¦ä¹ł +M atching +ä¸İ 社ä¼ļ +ï¼ī 第 +åİŁåĪĻ ä¸Ĭ +zer bai +Ġcl an +æīĢ äº§çĶŁçļĦ +Ġ åľ°åĿĢ +ï¼Į äºīåıĸ +èĢģ 夫人 +Ġdet ained +Ġappell ants +æijĦåĥı æľº +ä½ł è§īå¾Ĺ +æĶ¯æĴij æĿĨ +èĶ · +åıijæĶ¹ å§Ķ +Ġnut rit +Ġrubb ish +ĠHim self +Bl end +Ġfav ors +Ġp thread +æĢ» éĿ¢ç§¯ +ç»Ļ ä»ĸçļĦ +çĺ © +S erv +çļĦæĺ¯ ä¸Ģ个 +ĠB ooth +ä»ĵ ä½į +Cons ult +aus al +Sl ide +Ġe ax +Ġ åĨ· +åĩº è·¯ +ĠEx amination +( reader +身 åľ¨ +ç¨İåĬ¡ å±Ģ +ï¼Įç͍ æĿ¥ +_log in +% E +ï¼Įæľī åĬ©äºİ +Ġinnoc ence +çļĦ è®°å¿Ĩ +ĠSher man +ä m +Ġincomp et +od ore +éľĢè¦ģ è¿Ľè¡Į +ĠSh in +Ġunlock ed +, åħ±åIJĮ +éĺ² çĪĨ +Ġsub groups +Ġtax able +ENC Y +åľĨ åľĨ +ĠBelg ian +Ġdisput ed +äºĨä¸Ģ æī¹ +Ġpresum ption +,... , +æĶ¶ 款 +éĦĻ è§Ĩ +æīĵåį° æľº +æľī åĩł +open hagen +ç͍ å¤Ħ +Ġpath ogen +_UN KNOWN +æ¸ħ çĥŃ +Ġskin ny +ĠBar on +. plugins +Ġstr ides +ĠUnivers ities +vid ia +çĽĺ çļĦ +åıijçĶŁäºĨ ä»Ģä¹Ī +å§ĭ äºİ +ä¸į èĩ³äºİ +_s erial +c ie +Ġm ah +ï¼Į æ£ĢæŁ¥ +ï¼Įä¸Ģ æĺ¯ +- author +éĩį åŀĭ +ï¼Įä½ł è¿ĺ +ĠM err +Ġdesc endants +List Item +D G +ĠR ails +大 å±± +ĠK ernel +ĠGod d +Log s +Ġmini ature +}} = +ĠNS Object +ï¼ĮåIJ¬ 说 +ĠWe bb +ı n +æĺ¯ åIJĹ +Ġmultip lying +- Al +Ġt iger +å·´ å°Ķ +^+ ^ +åİ» ä¹° +Ġfavour ites +IFI ER +åĽº æī§ +(c allback +ĠIF N +Ang el +ĠSix th +K ill +ĠH ER +åIJĮ ä¸ļ +ĠDet ail +ä¸į太 好 +_e lements +çļĦ身 åŃIJ +ĠSat urn +ĠModel ing +ç¬¬åĽĽ èĬĤ +ĠSal ary +å¤ļ åįĬ +A k +ra j +l bs +äºĨ 两个 +转 弯 +Ġre usable +ĠCorinth ians +é«ĺ 管 +ĠG oes +}{ | +æĸ¹ è¨Ģ +æ¯Ķ æĭŁ +ï¼ī ä¸Ń +ï¼Įä»ĸ åį´ +æĿ¥è¯´ æĺ¯ +ĠM um +åĿı çļĦ +ĠIn cluding +Ġbehavi ours +E sc +åĬ¨ æijĩ +requ ent +ĠGand hi +è½ ¼ +åľ¨è¿Ļ个 æĹ¶åĢĻ +ĠPro cedures +Ġget away +m ans +p ull +Ġben z +ĠD ash +ãĢĤ 秦 +ä¸į ä¸Ģèĩ´ +åĵĪ ä½Ľ +ο Ïį +æĬ¢ åĬ« +Ġinsert s +CF G +é£İ æµģ +Ġvent ures +éĢļ èĥĢ +ç½® çĸij +âħ ł +èĩªæĿ¥ æ°´ +åĦ ¡ +äºĮ æľŁ +èĢĢ çľ¼ +.get Int +è§Ĵ èī²çļĦ +天 åĨħ +Ġadvance ments +ä¹ĭ åĪĨ +v ae +Beaut y +ç²¾ é«ĵ +ud i +Ġmanage able +åİī害 çļĦ +pp ery +Ġb askets +åΰ æŃ¤ +Ġbud s +ĠBright on +è¡Ģ èħ¥ +è°¦ èĻļ +_ ring +Ġdec oded +Ġapprox im +ï¼Į å®ĺ +ĠLe an +der abad +.f ull +IL S +omb re +ĠD SL +åĵ¥ 伦 +ĠNa N +. Result +ï¼Įå½ĵ åį³ +$ {\ +H aw +Ġstream line +åĨ Ĺ +_n one +ï¼Įä»ĸ 便 +åľ¨ åħ¨çIJĥ +çļĦ æ³ķå¾ĭ +ian i +Ġus ability +åŁİ å¤ĸ +Ġartic ulate +Ġdecl ares +Ð ļ +ï¼Įå¹¶ æł¹æį® +}, { +.start swith +Ġrenov ated +prob ably +get Id +(s ql +ĠDavid son +æİĴ 污 +竣çĦ¶ æĺ¯ +éªij 马 +äºī æī§ +ĠI PO +ĠBoot s +n othing +av ar +({ ' +çĸ² å̦ +ä¿® åīª +æĪĺäºī çļĦ +ĠJud a +Ġpersu ade +Ġ çĶļèĩ³ +说 åIJ§ +Ġâ Ŀ +å¤ļæł· åĮĸ +Ġ Ú© +梦 è§ģ +oft en +Ġs lo +ï¼Į ç½ij绾 +éĴ µ +(t op +åΰ 她 +ï¼Į ä¸ģ +æĢ ħ +æIJ Ģ +ĠP AT +UR S +ï¼Į 空æ°Ķ +riv ation +ĠF rid +d ataset +| x +Ġintegr als +ĠD rain +è° Ľ +为 èĩªå·±çļĦ +-e ast +ãĢģ è§Ĩé¢ij +Ġpou ltry +èĢģ çļĦ +Ġaud itor +ĠPer forming +æĻļ æĻ´ +et ting +Ġsing ers +Sp ark +æĮ£ èĦ± +Ġins ider +åIJī ä»ĸ +è¦ģ ä¸į +Ġstring ent +宣 ç§° +Ġuniform s +åįģäºĮ æĿ¡ +ãĥ ĸ +.as px +Ġmanifest ation +A sc +_ protocol +Ġab ras +è¿Ļ ä¸Ģ个 +J oy +at ibility +Ġrefere e +带 宽 +at ri +MP a +Ġpup il +åı¤ ä»Ĭ +éĢĥ èµ° +; ) +Ġso bre +ix ture +ä¸Ģä¸ĭ åIJ§ +t al +ï¼ģ 她 +æŃ» æŃ» +ĠPed ro +ç¬ º +Ġ ä½Ļ +æĢ» åħ± +ĠRest ore +Ġp added +( Color +ï¼Įä¸į å¿ħ +Class ic +大æ¦Ĥ æĺ¯ +éĻª æĪij +ãĢģ åѦçĶŁ +Ġest rogen +ä»ĸçļĦ æīĭ +ĠIdent ifier +ĠL anguages +ĠFor ums +ĠProv idence +F UNCTION +ç¬ij èµ·æĿ¥ +ĠM ET +åľ¨ ä¸ĬéĿ¢ +å®ŀåĬĽ çļĦ +_ inc +é±¼ ç±» +Ġmicro scopic +ĠRef uge +.B ody +Ġpsych ic +æĹ¶éĹ´ éĩĮ +Ġdefault Value +å®ı ä¼Ł +Ġelev ate +ï¼Į 足以 +äºĶ ä¸Ģ +åħ¬ 社 +ä¼ĺéĢī 为 +Ġthank ed +æĥħåĨµ å¦Ĥä¸ĭ +æ¾Ħ æ¸ħ +ĠL IVE +表çݰ å¾Ĺ +åľ¨ æľªæĿ¥ +D OT +if rame +iat rics +ï¼Ľ åħ¶ä¸Ń +ĠCol leges +Ġtransl ator +ĠK aw +åĪĩ åīĬ +åĢŁ æŃ¤ +åĬ© æİ¨ +æīĵçł´ äºĨ ++ j +çŃīå¾ħ çĿĢ +impl ies +çļĦä¸Ģ åIJį +Ġmiss es +ĠP ARAM +Ġcor ps +Content Type +/ net +éĩİ èĽ® +èĮ¶ çļĦ +ï¼Į éĢŁåº¦ +E LL +ĠBi ological +åħ¬åijĬ ç¼ĸåı· +Ġsil ently +饰 åĵģ +ï¼Į说 æĺ¯ +ä¸įåIJĮ çļĦæĺ¯ +Ġm ates +Ġme ats +ĠRes idence +æĹı éķ¿ +Ins pector +ĠA TT +Ġe Book +ter ing +ĠSp an +éĽħ æĢĿ +C MS +ĠW ii +ge ar +åİ¿ çļĦ + ¡ +Ġsy nerg +æľŁéĹ´ çļĦ +çļĦ人 äºĨ +æł¸ 对 +ĠP iano +åĴĮ éĺ¿ +é¢Ħ æľŁçļĦ +Ġadoles cent +B oost +èĤ¡æĿĥ 转让 +/ my +åŁºéĩij èµĦ产 +åIJİ æĿ¥çļĦ +QUE UE +J J +m oney +our ing +Ġte lev +Ġgodd ess +ï¼Į éĹ» +ig gers +ï¼ĮåĽłä¸º æĪij +ĠGuid ance +- ro +æ·® åįĹ +_P LL +éļĶ æĸŃ +ç¥ŀ ä¹ĭ +次 æĹ¥ +Ġst riving +å¿ IJ +ä»ħ ä¾ĽåıĤèĢĥ +å®īè£ħ æĿ¿ +l é +缸åħ³ è´Łè´£äºº +Ġwild ly +èµ· èįī +ĠB ri +Ġke yp +å¿ ij +qu iet +追 èµ¶ +è¿IJè¡Į çļĦ +è¿Ļ å°ıåŃIJ +Ġ 书 +åĴĮ åĪĨæŀIJ +æĶ¶ è§Ĩ +ĠMethod ist +_load er +ï¼Įä»ĸ 对 +ri ott +Ġal uminium +ment al +-th ree +å·¥ä½ľ ç»ıéªĮ +\ centering +Ġremind ers +.sub str +Ġmerc ury +Ġeigen value +æ¯Ķ 对 +ï¼Į å®ŀè¡Į +ĠG U +ĠCou pons +[ B +Ġcann abin +ç»Ŀ 大éĥ¨åĪĨ +T W +e ffect +ëĭĪ ëĭ¤ +ipp y +{ j +ä½ĵ ä¸Ĭ +ĠSch midt +åĪ ¨ +is able +è¿ĻäºĽ å¹´ +u ador +TE CT +-P CR +.Ex ecute +Ġapprent ices +ä¸Ń åĬłåħ¥ +sign ature +LEG AL +å·¥ç¨ĭ é¡¹çĽ® +ick le +ĠAr ms +Ġes presso +èĩª åªĴä½ĵ +ä¼ĺ ç¾İçļĦ +.ex ception +_EX P +d rive +log en +_set ting +æĸŃ å¼Ģ +Ġclass mates +åħĥ çĴĭ +inger print +åħ¼ ä»» +ĠBlog ger +Ġapp ellee +Ġfun gi +Ġer u +åľ£ ç»ı +é¦ĸåħĪ è¦ģ +ic om +ãĢģ 个人 +g id +缼 å®´ +ĠH ole +ï¼Į å͝æľī +éĥ½ çĿ£ +.dat abind +ĠG ab +- analytics +çŁ¥ ä¹ĭ +æĶ¶ èµ· +Ġap ology +设计 ä¸İ +Ġju ices +Ġweak ly +ynth ia +å¹½ å¹½ +åŃ©åŃIJ åľ¨ +ä»ĸ å¦Ī +_SE L +Ġritual s +ä¼ļ å¼ķèµ· +Ġam mun +ĠM agnetic +交 æİ¥ +CH ED +ï¼Į å¯Ĵ +ï¼Įä¸į åı¯èĥ½ +æ® ĩ +çĶ· 主 +éĢĢ äºĨ +Ġepid em +Ġ 缴åΰ +çļĦä¸Ģ çīĩ +Ġmaster piece +ï¼Į S +æ³ķ åŃIJ +çķ¥ æĺ¾ +èĭ¦ èĭ¦ +.T YPE +Ġlett uce +ĠIN ST +Ġvent ricular +强 壮 +.g en +Ġsl ug +ç»ıèIJ¥ çļĦ +ĠD G +ä¸ĭ è°ĥ +_ext ra +ãĢģ åĩº +Ġmetast asis +ĠL aptop +Request ed +æķĪæŀľ 好 +ĠM ilton +ĠWinds or +/ new +int ech +çĽ¸å¯¹ åºĶçļĦ +æĥħåĨµ è¿Ľè¡Į +f usion +em ap +åĸ· åĺ´ +Ġaug ment +å°ı å¼Ł +ä»ĸ åİ» +é£İéĻ© 管çIJĨ +éĻIJåζ æĢ§ +æ¸Ķ ä¸ļ +ï¼Į åĽ´ç»ķ +ï¼Į åij½ +Ġa a +æİ ° +an an +åıª è§ģ +æķĪ èĥ½ +åħħ å̼ +AS P +æĪij们 ä¼ļ +Ġs ect +Ġconf use +æĬĦ è¢Ń +ãĢģ åĨį +(f ilter +.P I +ç͍æĪ· ä½ĵéªĮ +æĥ³ 说 +Ġfib rosis +éĵ µ +Ġquant ified +Ġr if +é£İ ä¸Ń +Ġtemp o +ä¸Ĭ åı¸ +ε ί +ï¼Įçľĭ åIJij +pp ling +å±ķ å¼ĢäºĨ +åıĪ å¦Ĥä½ķ +Target s +é¢Ī æ¤İ +ï¼Į åĩłä¸ª +没æľī ä¸Ģ个 +ĠAppoint ment +ĠMac Book +èĢħ 们 +EL Y +å¾Ī éķ¿æĹ¶éĹ´ +æĬķèµĦ èĢħçļĦ +ä¹Ł åIJĮæł· +èįī 丼 +° Ãij +ĠPak istani +åĪĨéħį åĪ©æ¶¦ +æĦĪ åIJĪ +éͦæłĩ èµĽ +åĽ½ ä¹ĭ +好 åIJİ +urn ame +äºĨä¸Ģ å¥Ĺ +夹 æĿĤ +I U +AR B +R H +åĪĩ åħ¥ +ï¼Įä½Ĩ å¦Ĥæŀľ +Ġflo ods +.p anel +ĠWes ley +ĠK enny +å¸ĮæľĽ èĥ½ +å¸Ĥåľº ç«ŀäºī +d as +iv ative +ĠÏ ķ +æĶ¾ åĩº +ĠMy th +par alle +ĠSym fony +åıĺ 身 +Ġåıª è§ģ +ä»İä¸ļ 人åijĺ +ĠZ el +ĠM ETHOD +ES CO +( Base +Ġel ucid +ĠBever ly +ä¸įæĸŃ åıijå±ķ +in fect +Ġflav ours +ĠCon verter +äºĮåįģ ä¸Ģ +ĠPack aging +ht ub +ĠCh ancellor +å½ĵ å®¶ +ĠSp aces +at y +ograp hers +Ñ į +èĮ § +ĠG ust +yst ick +Ġz oning +.P ointer +åºĬ 头 +IZ ATION +cre am +å¿į èĢIJ +, ä¿ĿæĮģ +C ube +C e +Month ly +åıĹ éĻIJ +æľ¬ å¸Ĥ +s leep +_p b +_en um +-p ub +ï¼Įä»ĸ çŁ¥éģĵ +ä¸ĸçķĮ 大æĪĺ +ï¼Į æijĨ +æµ· 绵 +^ p +åĬł æĮģ +: ãĢĬ +è¿ĩ åħ³ +Sp anish +éĹª çݰ +I OD +Ġ ia +çļĦ è§ĤçĤ¹ +}} _{\ +å¿§ éĥģ +çĤ ¯ +Ġsaf est +Ġqu oting +OR IES +ĠGe V +_WA IT +Ġradical s +c ad +åįģ æĿ¡ +Ġearn s +Ġset Timeout +n aires +çļĦ两 端 +- u +ĠM aid +éĴĪ对 æĢ§ +å½ĵ å½ĵ +é»ij æ´ŀ +-w ritten +ew ood +ĠI stanbul +ä½İ ä½į +åºŁ å¢Ł +ĠSh ane +åĴĮ èĢģ +_D AT +æ°§ åŁº +ĠTim ber +An na +-des igned +Ġcut ter +Ġple thora +}/ ${ +é£ŀè¡Į åijĺ +åħĦ 妹 +çĽĪ çĽĪ +ĠHawai ian +ï¼ĮèĢĮ è¿Ļ +çļĦä¸Ģ 段 +all ic +éķ¿ å¤§çļĦ +ĠE ston +ill ar +/b uild +ĠRel ax +Ġeffort lessly +K rist +Ġst are +ĠBulgar ia +à ĺ +Ġk ar +ĠA ES +ä¸įä¼ļ 被 +.ex pect +缸 è¿ŀæİ¥ +ç§»åĬ¨ äºĴèģĶç½ij +Ġmod ulus +ocomp lete +Ġmarket ed +建ç«ĭ åľ¨ +Ġnic otine +æĻĥ åĬ¨ +Mix in +ĠC ater +Project ion +-g overnment +å¯Ŀ 室 +Ïİ Î½ +åij ¦ +ĠRes earchers +ony ms +ä¼Ĭæĸ¯ åħ° +ĠRel ative +ĠVeter inary +åĪĩ 齿 +_PR INT +ï¼Į è¿ĩåİ» +çĬ ģ +_in f +Ġhyp ers +Ġgl or +æĺİ ä»£ +Ġthreat ens +Ġins pected +.st arts +-d rop +ï¼Įæĺ¯ åľ¨ +Ġforeign ers +Ġlook out +åIJİ èĥĮ +çļĦäºĭ 项 +Ġske letal +ä¸Ģèά æĺ¯ +s ic +à º +Ġr inse +çļĦé«ĺ 级 +åħ¨ æĹ¥åζ +åħ³ ä¸Ĭ +Ġ# : +J ew +åĬŁ åĬĽ +é¹ Ĭ +het ically +K a +å¸Ĥ 人æ°ijæĶ¿åºľ +æķij çģ¾ +Ġam using +Ġexperiment ing +ĠBern ie +åĤĢ åĦ¡ +å¿ħé¡» æĺ¯ +ãĢģ éŁ³ä¹IJ +Ġburd ens +çŁŃæľŁ èŀįèµĦ +æ²§ æ¡ij +(d ec +. ly +organ ized +ut i +ee ks +太 ä¹ħ +man ia +it ched +[ u +ĠL enn +Ġguitar ist +æ±ī 书 +L uke +Ġshowc ases +.or acle +å°± åı¯ +è¿ĺ å¾Ī +çľĭåΰ ä»ĸ +æ´ŀ å¯Ł +ä½İ çĿĢ头 +ĠDev on +[ String +ï¼Į çIJĨ +åī ĥ +Re ach +Ġopp ression +è´Ńä¹° çļĦ +Ġ åĪĿ +Ġseek ers +Mir ror +ar ie +ä¸Ĭ ä¸ĩ +æĤ¨ 好 +WH O +Ġdifferent iated +æĦŁ è§¦ +Ġsc ams +ĠNor folk +åľ¨ æīĭ +è§Ħ ç¨ĭ +éĻĪ åĪĹ +h are +Ġampl ified +f urt +s al +è°Ī æģĭçα +Ġ 两个 +è¸ Ŀ +izont ally +å±ħ 室 +åıªæĺ¯ 个 +åĵ § +ç«Ļ éķ¿ +åĨ² 天 +Sh opping +åī§ çĥĪçļĦ +ĠDent istry +ĠF amous +. email +äºĨ å¾Īä¹ħ +ĠTrans mission +_b efore +ĠEnh ance +hard t +---------------------------------------------------------------- ---------------- +Ġmethyl ation +arm ac +ĠA th +çļĦå¿ĥ ä¸Ń +ï¼Įè¿ĺ åľ¨ +t oggle +Ġderiv ation +ï¼ļ \" +vol atile +ãĢĤ çĽ¸ä¿¡ +ĠS ymptoms +çĿ¡ ä¸įçĿĢ +ï¼Į羣 çļĦæĺ¯ +w ow +èĬ± èĬ± +éĶĻ è§ī +ĠCas ual +ch urch +ãĢģ åħ« +åįķ è°ĥ +æĬ¥ éĢģ +ore ms +( header +åĵģ ä½į +f h +Ġp ods +ãĢĤ 两人 +è¯ģæĺİ äºĨ +æľĢ å¿«çļĦ +å°ı 游æĪı +ĠCh ance +_A F +æ»ij 轨 +ĠConvers ely +er ring +éĥ¨ å°ļ书 +Ġs ess +ot ent +æĦ§ æĺ¯ +d ream +éħĴ çļĦ +" çŃī +èŀ ĥ +Ġ è¯ģåΏ +ï¼Įä¸Ģ æīĭ +æĢİä¹Īæł· äºĨ +Ġc aching +Ġbond ed +åIJ¸è¡Ģ 鬼 +Ġpro j +å¦Ĥ å®ŀ +Rep ublic +ü n +è¿ĻéĩĮ æĺ¯ +温度 为 +åļ ĵ +ï¼Įä»ĸ们 åľ¨ +- less +å®ī ä¿Ŀ +éĩİçĶŁ åĬ¨çī© +S old +æĻ® æ´± +ï¼Į æ´»åĬ¨ +Ġpl a +;\ ;\ +_D BG +Sent ence +åķĨ åľĪ +g ia +Ġce ased +g uid +ch oice +M is +l k +产çĶŁçļĦ çݰéĩijæµģéĩı +梦 éĩĮ +Ġ ä¼Ĭ +å¤ļ æł·çļĦ +Ġ æŃ¤åĪ» +Ġjer seys +ĠInsp ired +éĢĴ 交 +ä¼Ļ 计 +Ġpref ers +ĠDiv orce +_d raw +æľī åIJį +å̾ åŁİ +ï¼Įä¸įçͱ å¾Ĺ +Ġ& $ +Ġsw ings +ĠVlad imir +ĠL ONG +/ , +ï¼Į 寻æī¾ +-the med +ch ini +B lood +ĠW O +ĠHor ror +è¢ĸ åŃIJ +Ġirr ational +Ġtouchdown s +ĠD ock +å¿ĥ è¡Ģ管 +æīĺ å°¼ +å¥ĩ çī¹ +ch ars +åħ¬åı¸ åĢºåΏ +_C NT +ĠP ACK +ats by +Ġbes poke +å¦Ĥ æĺ¯ +é¡¿äºĨ é¡¿ +ï¼Įåΰ å¤Ħ +ĠDaw son +纪å½ķ çīĩ +ä¸Ń åıijçݰ +st arter +æŀ Ń +An c +åħī è°± +Ġcultiv ated +Ġelect roph +W rong +Ġm ans +rac use +inv oke +ä¸Ń 书 +çļĦ åıį +çĮľ æĥ³ +Ġdivid es +/b log +ĠC ove +Ġk w +- js +æĶ ¥ +åĶIJ æľĿ +ï¼Į æķ¢ +çŃī 人çļĦ +BO OST +ç¾İ åĨĽ +çĶŁäº§ åİĤå®¶ +ethyl ene +- II +m ere +çļĦ åį±éĻ© +/ view +èµ· é£ŀ +ie red +åį³ ä¸º +C rypt +re b +ex clude +- standard +åĴĮ 建议 +èĢĮ æŃ» +_f inal +ĠBrit t +ä¸įçͱ èĩªä¸» +æĸ¹åIJij ä¸Ĭ +arm an +åĩĮ ä»Ļ +. author +ãĢģ åĨľ +Ġadvent urous +ä¸Ģ è·³ +Ġsp aced +ĠVari ables +åĵ¼ åĵ¼ +Ġted ious +ĠG CC +in z +_d ialog +c ategories +å¿ħ å°Ĩ +æ¯Ķè¾ĥ 好çļĦ +è¢ĭ åŃIJ +Ġin set +浪 æ½® +æĢ» 计 +_LO C +éľĢè¦ģ注æĦı çļĦæĺ¯ +? id +ĠSY STEM +_f etch +ॠĭ +Creat ure +ex change +âĢľ 人 +é¢Ĩ导 ä¸ĭ +å¼ł èĦ¸ +.F ore +ï¼Į ç²¾ç¥ŀ +Ġdent istry +çļĦ è´¹ç͍ +Ġamazing ly +Ġprefer able +æľī ä½ł +ru ff +ä¹ĭ äºĮ +ĠWork place +\ delta +ĠD OWN +ĠChrist ina +Ġ ç±» +gr an +I AS +Ġabst raction +ĠP ermanent +( This + ¥ +课 åIJİ +æł¹æľ¬ ä¸Ĭ +åħ±åIJĮ åĬªåĬĽ +ĠS oci +åĽ½ éģĵ +Ġh ing +uch i +Ġp als +éĿĴ éĿĴ +交 éĻħ +Ġcr ashing +Ġд а +char set +ç¡ķ士 çłĶç©¶çĶŁ +) -\ +_ rs +(' ', +æĩĤ çļĦ +Ġin comes +_G ENER +ĠDemon str +çĿĢ åij¢ +Ġ æĬĢæľ¯ +å»ī æ´ģ +çĸĻ çĺ© +ĠU CLA +tr ust +ä¸Ģ ç¢Ĺ +ï¼Įä¸Ģ åıª +Health y +Ġle asing +ĠCh and +Ġbl inds +ĠChrist ie +ĠSal em +æĪij们 对 +å¿IJ å¿ij +æŃ£ æľĪ +Ġinform ing +av ian +èĢĮ å¾Ĺ +æ³ķ åĬĽ +èĨľ çļĦ +f req +ä¸Ń éĺŁ +Ġmiss iles +Ġ ä¹Ķ +èĭ± ä¿Ĭ +ĠT ucker +ĠRe habilitation +æ±² åıĸ +.f r +Ġacid ic +, åĸľæ¬¢ +æľī 为 +_m ut +æł¹æľ¬ 就没æľī +Ġhold ings +ãĢĤ çα +Âģ Ãij +ä¸į èµ° +Ġ` [ +nc ia +æĿĢ ä¼¤ +_RE M +æľī 空 +Connect ions +Ġbroker age +å¯Łè§ī åΰ +AC TER +EM A +m ph +é«ĺ è´µ +å½ Ŀ +é»ij å¤ľ +Ġ~ = +Ġpurch aser +æĹ¶ æķĪ +amb o +ãĢģ åĮĸå·¥ +ĠSem inar +Ġcons erve +Ġc ites +č č +æĿ¥ åIJ§ +link ed +Go al +an ed +Ġra ins +ãĢģé«ĺ级 管çIJĨ人åijĺ +ä¸Ģ è¯ķ +æľĢ åħĪ +ĠAng le +Ġlock smith +ib es +Ġd end +_t okens +åı¯ä»¥ çļĦ +Ġinsert ing +_UN S + ĩ +è¾ Ĺ +ĠP OP +ann o +_ ASS +ĠF old +è¶ĭ äºİ +èĪªç©º åħ¬åı¸ +ĠJ i +ì ĸ´ +Ġob solete +Middle ware +it ian +ĠIn fect +\ $ +ĠG ore +åĽĽ æµ· +èĴĭä»ĭ çŁ³ +r arily +çħ§ æł· +åħļ æĶ¿ +ãģ ° +ĠClass ical +Ġd od +_G L +ros se +Comp act +Ġrev ival +SE E +% " +Ġsh arks +æ°ij èIJ¥ä¼ģä¸ļ +erg ic +ch annels +æĥ³ 念 +Ġre juven +AN I +ï¼Į她 ä¹Ł +è¾Ľ è¾£ +ĠGreen e +ĠRab bit +æķĻ èģĮå·¥ +ç²¾èĩ´ çļĦ +ĠC ork +Ġgr inder +ĠS ens +Ġatt enu +æłĩ æĿĨ +Ġammun ition +ãĢĤ çłĶç©¶ +Ġup hold +æł¹æľ¬ å°±ä¸į +åĴĮ å¤ĸ +AT S +Ġdet erg +loc ations +ĠEv angel +æĪĺæĸĹ æľº +ĠExhib it +åŀĥåľ¾ æ¡¶ +大 ç±³ +ç½ij绾 çļĦ +åħĦå¼Ł 们 +Ġsour cing +. Entry +æĶ¶ åī² +Inter ior +och a +ais er +大 åIJĥ +ï¼Į 表éĿ¢ +ĠW er +å¿« æŃ¥ +Ġb ien +ĠR L +quart ered +Ġ è¡Į +è¡° éĢĢ +åį¡ æĸ¯ +ĠÏĥ Ïħ +å¤ľ èī² +R oyal +ĠStr ange +ĠH oll +Ġtr am +æľĢ 强çļĦ +ĠAlb any +ĠMain tain +åĨħ è¡£ +Ġ æĸĩä»¶ +av ailability +ï¼ĮæīĢ以 æīį +Ġadul thood +ï¼ļ 以 +Ġb box +æ·· æ·Ĩ +(s ervice +äºļ 太 +ĠS MB +ĠEx planation +ä¸į åħ¨ +_h istory +ï¼Įçݰ ä»» +.set Attribute +W ed +人 以 +ãĢĤ é¡¹çĽ® +ä¸Ń å¼ı +ĠM itt +æĿij éķ¿ +æ±ī åł¡ +åĽĽ çϾ +-p ol +Ġbat ting +Ġdes p +.get Attribute +Ġsol ves +] {\ +ï¼Į æ·¡æ·¡ +_AR CH +_S D +\ cos +ĠB G +-p anel +Ġc ider +ĠC oul +ä¸Ŀ毫 没æľī +T ot +am us +ä½İ è¿· +认为 èĩªå·± +éĢĥ çĶŁ +. eval +åį¡ çļĦ +, å®ĥ们 +Ġke eper +ĠLect ure +çī¹ éķ¿ +ĠCh ambers +ĠChen nai +$ string +E le +å´ ½ +åķĨåĵģ çļĦ +< link +Test imonials +大 åIJĮ +å·® éĶĻ +太 å¿« +yl ation +-c ap +éĿŀ常 大 +Last ly +éĸ ĵ +_D IV +g ang +i ago +Ġcomfort ing +g ap +Ġconsult ations +æĹłå½¢ èµĦ产 +J ean +ãĢĤæľ¬ æĿ¥ +æĪij们 å°Ĩ +ĠMal colm +å©´ å¹¼åĦ¿ +ĠH undred +th ings +ä½ķ 以 +æĹł çŁ¥ +ĠFlo oring +åĵĪ åĪ© +Ġconce al +il m +ĠK ai +è¿ŀ è¡£è£Ļ +ï¼Į æĭŁ +çĮ Ŀ +èŀĥ èŁ¹ +und a +éĺ´ éģĵ +duc ers +.w here +optim izer +am ics +æĸ° èĤ¡ +Ġ éĥ½ +Ġc ue +马 åĬĽ +Ġbudd ies +Ġhe aled +b ash +ĠIsa iah +ĠAdvis ors +.amazon aws +æ°Ķ åİĭ +ç¹ģ çIJIJ +éĢļ讯 åijĺ +Con clusions +App rox +per fect +-m illion +, è§īå¾Ĺ +ĠMar ion +èĬĴ æŀľ +ä¼ļ æĪIJ为 +è·Ł éŀĭ +Ġ è®°èĢħ +Ġf ir +说 å®ŀè¯Ŀ +Ġapp la +æł¼ 鼷 +ĠP WM +< char +L ed +Un iversal +è¿Ļ次 çļĦ +ç»ħ 士 +ĠJ ung +æľĪ åĩºçĶŁ +è¡¥ æ°´ +ĠRail road +ĠHospit ality +orect al +Ġpres criptions +æĴĴ å¨ĩ +.S ql +Ġrighteous ness +Ġw orms +_s m +arn ation +ĠIn struments +ä¸ĵä¸ļ åĮĸ +. rs +Ġbind ings +ï¼Į åĨľæ°ij +Ġcl ot +S aved +Ġvis ions +ï¼Į åı¯èĥ½æĺ¯ +h ci +建 çļĦ +ï¼Įä½Ĩ çͱäºİ +b ows +l ift +R ussian +RO S +. expand +.p atch +d yn +Ġ æ¯Ķ +etic a +ĠG n +çݰå®ŀ ä¸Ń +- Col +èĢģ 人çļĦ +ï¼Į çİ© +su ite +ĠO VER +ĠGold man +ĠInf inity +ç´§å¼ł çļĦ +method s +_SY STEM +C MD += ] +æĿ¥ è¿ĩ +Ġpat ented +Ġamb ulance +Ġarter ies +Ġpit ches +ĠCh ronic +çϽ åıij +å¹³ å¹³ +Ġhero in +Ġfauc et +ï¼Į æĥŁ +çļĦ 形象 +³³ ³³³ +Ġcamp uses +Ġfl ats +å·´ 士 +Click ed +gin x +ĠAng ular +åĽ¢ åĽ¢ +Ġinvestig ative +大 æ£ļ +-f unded +- * +ĠSub st +ãĢģ ä¸ĩ +èĬ± 纹 +èģĮ æĿĥ +çĶĺ èįī +Ġt ucked +ct ype +Ġconv olution +ĠL INE +å¼ł åĬĽ +åĪ© 好 +Ġfl are +_g pu +if ax +éĤ£ä¹Ī 好 +Ġo val +ff i +_ State +Ġpro se +Ġal g +Ġt ester +åħ¨ 天 +宫 çļĦ +) x +çļĦä¸Ģ ç³»åĪĹ +Ġneur on +èᝠçļĦ +Ġcasc ade +Ġam ph +Ġtext ual +ĠW ARNING +Ġhistor ians +I ce +P ray +ivid ed +Ġop code +>\< ^ +IR S +æ¤ħ ä¸Ĭ +à » +ĠCommun ist +az ar +åĴ İ +ac ic +Ġannoy ed +Acad emic +å¦ © +ĠF en +Ġav ocado +_M ON +_C OL +Ġw ig +-go ing +ĠSlo ven +Ġovere xp +å¹´è½» 人çļĦ +Ġ ä½ľ +H ero +ĠScre ening +ï¼ĮæĪĸèĢħ 说 +Ġtensor flow +ãĢģ 社åĮº +Ġpred ators +Ġcomp osing +æĢ¥ éľĢ +(t ree +çĿĢ æĥ³ +ĠPl umbing +ĠRead s +ï¼Į çł´ +Ġf ec +æľĪ çIJĥ +éĺ² æ»ij +åĽŀ æĥ³ +() $ +Em ily +Ġâĺ ħ +Ġemerg es +çĮİ äºº +çŁŃ è·¯ +éĩĮ äºļ +èĦ± åıij +课 å¤ĸ +Ġscar f +T own +天 æĻļä¸Ĭ +Ġenthusi ast +Âł ä¸įè¿ĩ +rem ely +ä½ł æīĢ +ĠY o +Us ually +ãĢģ 广å·ŀ +å°ı å®¶ä¼Ļ +ãĢģ 建设 +主 å¹² +Up coming +Ġsk illet +ï¼ģ åľ¨ +-e conomic +Camp aign +Ġfor Key +ï¼ĮæĪij åıĪ +äºĶ 人 +æĬijéĥģ çĹĩ +åĩºçİ°åľ¨ äºĨ +åĴĮ åºĶç͍ +n od +ĠP rix +æ´ŀ ç©´ +äºİä¸Ģ ä½ĵçļĦ +ï¼Ľ äºĮ +åĽ´ çĿĢ +æ³¢ çī¹ +ĠLeg ion +ĠG erald +æīĵ åħ¥ +ï¼Įè¿Ļæł· æīįèĥ½ +/ **************************************************************** +-p iece +Ġì ķ +èľľ èľĤ +å°Ħ éŨ +èµ° åĩºäºĨ +ä h +a verage +å¸Ń åį· +ĠG inger +Health care +- road +Ġaccus ations +æĬī æĭ© +Ġembry os +.log ging +/ content +( resp +ï¼Į åı¦ä¸Ģ个 +Ġdivis ible +ï¼Į çĶ» +ĠD um +æĶ¯æĴij æŀ¶ +ï¼Įå°¤åħ¶ æĺ¯åľ¨ +å®ŀ åIJį +è°ĥ éħį +Ġr att +å¡ij æĢ§ +礼 æľį +Ġrehe ars +y c +ãĢģ æīĢè¿° +Ġattribut able +æĻļ å¹´ +Ġlie u +ĠM ats +Ġd if +olph in +ĠBl ind +çĽijçĿ£ç®¡çIJĨ å±Ģ +æīĢ æĮģ +ç¨Ģ åľŁ +K L +æŃ£ èĥ½éĩı +ib i +ĠRub ber +ï¼Ī ä¸Ĭ +Ġcheck sum +Ġperf ume +Mutable Array +ĠSales force +éĴĪ对 æĢ§çļĦ +i ast +Ġtrunc ated +åĬ¨ èį¡ +ãĢĤåľ¨ ä¸ĢäºĽ +Ġstory line +æĮģèĤ¡ æ¯Ķä¾ĭ +Ġst agn +ĠH tml +Ġcard io +el ic +ĠL af +大 æłij +_de cl +äºĨ çīĩåĪ» +// ================================================================ +ĠRespons es +b org +åĪĴ è¿ĩ +Ġroof s +å°ı 鼨 +.s uccess +Ġstraw berries +ng inx +Cross Ref +çĥŃ å¿ĥ +(p red +Ġwar riors +车 éĺŁ +\no indent +ï¼Į她 æĺ¯ +äºĨ 声 +Sus an +-ex ternal +å¾Ĺ åĥı +ĠSV G +ĠMan ning +åī¯ æł¡éķ¿ +Ġcat heter +Ġceremon ies +Res ume +åIJ¸ å°ĺ +ĠN PR +åĮ»çĸĹ æľįåĬ¡ +ev ol +nam ents +phant om +J M +Ġsulf ur +æ°Ķ æĦ¤ +Ġcort ical +f act +çŀ§ çŀ§ +ï¼Į å½»åºķ +_CON F +Spec ification +ĠWar rior +åįģ å¤ļ +æĭĽ æīĭ +Ġ- * +ĠCon cent +ĠID C +æĦī å¿«çļĦ +ativ istic +- MS +Å £ +ç²ī èī² +Ġborrow er +, 使ç͍ +Ġleft over +or on +å°± è§īå¾Ĺ +ï¼ĮæĢ» ä¹ĭ +ĠTax es +ep loy +å®Į ä¹ĭåIJİ +ĠElectric ity +. trim +Ġsh outing +èĢħ æĺ¯ +âĹ İ +ï¼Į æĹ©å°± +交éĢļ å·¥åħ· +æĪIJç«ĭ 以æĿ¥ +. St +ï¼ģ å¦Ĥæŀľ +Ġprev ail +é«ĺ åĪĨ +_s ig +æīĵ åΰ +S ense +ĠC BC +ĠMu eller +ä¸ĩ人 次 +Ġid i +D AT +æĿ¥ 形容 ++ m +ï¼Į R +ãĢģ ä¸ļåĬ¡ +è¯ij æĸĩ +âĢĶ I +Ġfill er +ĠBed rooms +æĶĢ åįĩ +Ġwater ing +åħµ çļĦ +ĠBar rett +Å Ħ +ĠC overed +æĺ¯ä»Ģä¹Ī åij¢ +unk y +gr p +é£ŀ ç¿Ķ +ãĢģ åıij +Ġ ips +oc ative +: id +æĦŁ å®ĺ +åŁĭ ä¼ı +erc ises +ãĢĤ æīĢè¿° +row ning +Ġcollabor ations +Cap ital +é¦Ļ æ°´ +æĽ´å¤ļ çļĦæĺ¯ +ç͵åŃIJ 产åĵģ +_P RI +æĺ¯ æľĢ好çļĦ +du al +Ġacknowled ging +æ°´å¹³ åĴĮ +ĠLit igation +K C +Ġind isp +oz yg +æĦı å¢ĥ +å½±åĵį åĬĽçļĦ +Time Millis +Ġ第ä¸ī 竳 +Ġst igma +ĠW ong +Ġle aking +åħ¬åħ± åį«çĶŁ +ï¼Į 管çIJĨ +-the me +èĭ ĩ +åł ´ +å³° å̼ +Ġbre wing +é¢ľ æĸĻ +áĥ ĺ +Ġcor p +- Year +åīį 线 +( Exception +éĵĥ 声 +åįłæį® äºĨ +ĠNort on +- arrow +Ġb inder +Ġch r +èIJ½ åľ¨äºĨ +åıĻ äºĭ +éϤ 以 +ĠS ev +Ġbeh old +ĠOdd s +et ched +.F atal +çĤ¹å¤´ éģĵ +Ġric her +get Type +& E +ĠProcess or +P IN +å°¾ éĥ¨ +Ġneutr ino +åijĬ è¾ŀ +W iki +Ġsubscrib ing +æľ¬æĿ¥ å°±æĺ¯ +Ed iting +ĠCh anged +/ : +ï¼Į 帮 +ĠG lor +_SH ORT +ĠE pid +æĪIJ äºĨä¸Ģ +ä¸ī çŃīå¥ĸ +ĠSm oke +éŁŃ èıľ +izz ard +æľīæķĪ æľŁ +ãĢĤæŃ£ å¦Ĥ +( con +Mod ify +ãĢģ æ·±åľ³ +å¨ģ å°¼æĸ¯ +å¸Ĥåľº ç»ıæµİ +pl ice +è¿ĺ ä¼ļæľī +ãĢģ 两 +å¾Ģ è¿Ķ +ĠSw imming +é»Ħ çĵľ +Ġpresum ed +Ġb ipolar +Ġv p +æİ¢ 头 +Ġfli pped +Keep ing +L aura +ä¾Ľ è´§ +åŁİ æ±ł +è¯ķ è¡Į +åĿı 人 +ĠSer bia +iju ana +IP v +t g +交 éĶĭ +ÑĤ а +D ES +T a +ĠWe ak +op hers +cal a +ro red +Ġin oc +ĠO E +å¹¶ è¡Į +che ss +_com ponent +L in +yp ed +Ġfore nsic +æ³¢ 浪 +ĠFr aser +çļĦ 空 +åıĮ èĩĤ +æŃ¦ åĬĽ +èĩª åı¤ +ä¿Ŀ å§Ĩ +cl oth +Ġdep letion +é¢Ĩ åĨĽ +åĨį çľĭ +Ġn ets +è´¦éĿ¢ ä½Ļé¢Ŀ +anc elled +ä¿ĿæĮģ ä¸Ģèĩ´ +Grid View +Ġaltern atively +çī¹ åľ° +缺 å¸Ń +åľ¨ é«ĺ +Ġbomb ing +ĠF ail +ĠAdd iction +again st +, æĭ¥æľī +ĠB JP +ä¸Ģ æĹ© +Ġsculpt ures +. Style +ãĢĤ æĸĩ +è¿Ļ 两ç§į +ĠVent ure +Ord ered +F arm +Ġcolour ful +lo oks +Present er +éŨ å°Ĩ +ç´§ è¿« +è´«åĽ° æĪ· +Ġparliament ary +H U +çģ¯ ç¬¼ +ĠInput Stream +ĠPodcast s +amar in +. plugin +æĶ¹ åĬ¨ +æĻºèĥ½ å®¶å±ħ +ï¼Ł ï¼Ī +ĠTalk ing +B oston +Ġsp ouses +ä¸ĵ 人 +ĠW rest +æĽ´ æ·± +Q P +T ogether +est ry +ãĢģ ç»ĵæŀĦ +éĿ¢ åĽ¢ +R ARY +ï¼Į å¤ĦçIJĨ +çļĦ åĬªåĬĽ +ly s +ä¸Ĭ æīĭ +å®¶ è£ħ +æµģ åŁŁ +ä¸Ń 没æľī +def s +ç»ĩ çī© +ĠSeg ment +Ġin version +b ishop +ĠV atican +Ġsn iff +Ġnarr ator +åľ¨ è¿Ļç§į +å°ij å¹´çļĦ +yn es +ĠT et +ĠSh arma +åħī 亮 +ç´¢ å°Ķ +ĠG entle +Whe never +æ´» ä¸ĭåİ» +_d ma +è¯Ń çļĦ +Ġt ails +ĠIn g +V ac +am ina +ĠDid n +çĶŁ åīį +accur acy +Pos itions +Ġen closure +ï¼Įçİ°åľ¨ çļĦ +Ġtheoret ically +.or igin +Ġm kdir +ĠSim pl +Ex ercise +ĠV inyl +Ex cept +èĤº çĻĮ +C AN +\[ [@ +Ġwarrant ed +åĸ· å°Ħ +书 åĮħ +Ġfl ashing +ä¹Ł ç½¢ +it lement +Ġillum ination +es ville +Ġbo ast +ĠDru pal +, U +åºĬ è¾¹ +.draw able +ï¼Į çļ®èĤ¤ +éĥ½æľī èĩªå·±çļĦ +Ġform ulate +urs ively +Ġacceler ating +R ON +è¿ĩ æĪij +Ġh ue +Inter rupt +occ us +æĺ¯ä¸Ģ 缴 +æ´» äºĨ +éĶħ éĩĮ +åıª è§īå¾Ĺ +åĽŀ åij³ +åĩı éľĩ +j ohn +Ġst aged +Ch ip +ny der +ay e +ठķ +. DEFAULT +Ġ è¢ģ +Ġv tk +-t rained +ãĢĤ èĩªå·± +ï¼ļ å½ĵ +_d bg +è¿Ľè¡Į æ²»çĸĹ +od ian +æĸ¹ é̏ +ĠP UBLIC +_sa ida +.f iles +Ġpet rol +ç³»åĪĹ äº§åĵģ +æģĭ æĥħ +ãĤ¹ ãĥĪ +m w +L ake +çŃ IJ +ï¼Įå°± åĥıæĺ¯ +M OS +Ġf aded +æĪij们 åİ» +Ġprof icient +ĠBook mark +ol on +CC C +ĠF ro +å¹´ 头 +Ġ æĺ¯åIJ¦ +o ise +æŀģ åĬĽ +Ġglo ve +ass er +Ġrun way +Ġd azz +ig ar +äºĨä¸Ģ æł· +ĠL ear +_ used +( pr +Ġ: , +大 è¡£ +æĪ¿ ç§Ł +Ġn ar +æł¹æį® èĩªå·±çļĦ +C IT +sh aw +Re commend +ç®Ģåįķ åľ° +çħ¤ æ°Ķ +ed ical +ĠJud gment +ĠNE VER +. Local +rit el +ãĢĤæį® äºĨè§£ +l atest +ot omy +.p arser +.T ypes +ĠP aw +é¢Ŀ çļĦ +ï¼Į æĺ¨å¤© +Ġx i +à ħ +è¾ĥ å¤ļçļĦ +Ð IJ +Ġconsult ancy +ï¼Į åħĭ +ç²ĺ ç»ĵ +Ġremark ed +åįģ åĩłå¹´ +åĶ § +ï¼Į æĥ³åΰ +ind ust +ä¸Ģèά åľ¨ +表达 äºĨ +ä¸ĩ 亿 +w yn +åIJĥ çĿĢ +Ġsp onge +ï¼ĮæĹł çĸij +For um +Show ing +ĠContract or +ãĢĤ åĮĹ +G U +ãĢĤ 以åīį +åºĶ å±Ĭ +script s +_ ap +John son +ĠCath olics +Ġnav al +agg ering +ãĢģ æİ§åζ +è¦ģ 对 +å¤ļ æĸ¹ +å®īåħ¨ åĴĮ +Ġgentle men +çļĦ éĵģ +Ġ§ § +å½Ĵ è¿ĺ +Ġqu as +纳 å¾· +åĮº æĶ¿åºľ +åIJĦ çľģ +af x +-b oard +æī¾ åĽŀ +Ġport folios +Lead ing +J ane +second ary +ãĢĤä¸Ģèά æĿ¥è¯´ +W ARD +Ġmoder ately +çĽij åIJ¬ +Ġshel ters +cl air +f at +åĴĮ è§£ +åĮħæĭ¬ 第ä¸Ģ +ĠT ort +大 ä¸ĵ +æ°ij 宿 +ï¼ĮæľĢ å¤ļ +æī ī +| _ +Ġspace craft +è¿· çħ³ +ä¸Ģèά æĿ¥è¯´ +urs ions +åĨĻ ä¸ĭ +ĠCh ick +Ġra ft +ox ia +çīĪæľ¬ çļĦ +(c fg +çĽijçĿ£ æ£ĢæŁ¥ +Ġsuperf icial +" [ +_R GB +d aughter +è¦ģ æĪij +ĠEs sex +Pro cedure +Ġexpl oded +éĥ½æľī çĿĢ +_column s +æģ¢å¤į æŃ£å¸¸ +å®¶éķ¿ ä»¬ +ast rous +严 å¯Ĩ +Ġd itch +ĠC PP +ly cer +é¤IJ åħ· +_ em +Throw able +L iber +R am +ĠH Q +åħ³ ç¾½ +ĠQ C +}) ^ +ä¸į å°± +ãĢģ åĽ¾ +Con nor +åħ³éĶ® çļĦ +æķĪæŀľ çļĦ +ĠK och +Ġha irc +(t rain +åIJ Ŀ +ĠV irt +thread s +èᣠ幏 +ĠDet ailed +ĠCut ting +çłĶç©¶ æĪIJæŀľ +Ġdownt ime +Ġwast ewater +Ġth inner +~ , +åŁİ 管 +C ases +åĬŁ æ³ķ +ç»ı常 æĢ§ +te acher +Ġann ex +èįī æľ¨ +Ġed u +èĢģ 天 +ĠPat rol +Or ange +Ġpres et +Ch rome +æľĢ大 åĮĸ +_al ias +æ¯Ķçī¹ å¸ģ +ãĤ ª +çļĦ çIJĨè§£ +form al +Ġadv ises +Ġcl ones +rel ax +Ġimplic ated +j pg +Ġconsult ed +åĶ ¬ +Ġur ges +_STAT IC +Ġd ass +æĹł èĢ» +è´µ éĩijå±ŀ +ĠB EGIN +ĠR SA +Ġs que +And y +Ġ åİŁæľ¬ +L ate +p ent +r ass +S anta +Ġmorph ological +ĠLL VM +ĠUnity Engine +Wait ing +ĠHung arian +Ġa uch +Ġexperiment ally +pat rick +忽çķ¥ äºĨ +èĪĴ çķħ +ic ism +Z E +alt ed +-- ) +Rest aur +ĠEli as +Ġse ize +åIJ¼ éģĵ +åı· 楼 +åΰ æīĭ +, 常 +ĠK eto +ï¼Įéĥ½ èĥ½ +ĠSal on +" ` +IV ITY +Ġassemb lies +Ġs ind +ãĢĤ æĪĸ +ĠMAT LAB +ĠAust rian +b ing +bol a +广 ç͵ +ĠIN PUT +ï¼Į èĮĥ +GLOB ALS +éĿ© æĸ° +ç´§ è¦ģ +伸缩 æĿĨ +Ġdepart ed +ON LY +C ro +Ġexhaust ion +Ġsen ator +ĠTer ra +umb ar +ĠI vy +æĹħ éĢĶ +Ġed ible +Ġinv itations +åľ°çIJĥ ä¸Ĭ +Ġrefund s +ĠWe ber +åħ¬åı¸ 竳ç¨ĭ +è¿Ļä¹Ī 好 +Custom ers +çļĦ æĢ§èĥ½ +çŁŃ 缺 +-z A +,è¿Ļ ä¹Łæĺ¯ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +ĠMin ute +Ġtrim med +ï¼Į çݯå¢ĥ +ĠF lickr +å¾Ĵ æŃ¥ +æĶ¶ æĶ¯ +_ angle +ĠMorm on +ãĢĤ è§ģ +In sets +Ġine fficient +_g pio +. EX +åħ¶ äºĭ +æĢ¥ ä¿ĥ +_A UTO +ï¼Į çĶ·äºº +ĠE tsy +OR N +Ġlegisl ators +带 éĺŁ +Ġal gae +Ph ysics +çŁŃæľŁèŀįèµĦ åΏ +ĠH ann +Ġmark up +Ġupload ing +åħ·æľī èī¯å¥½çļĦ +c ox +ä¼ĺ äºİ +ä¾µ åħ¥ +çļĦ æľĢåIJİ +yp se +.t ree +( settings +ĠH aus +åѦ éķ¿ +ä»ħ 代表 +oret ical +æŁľ åı° +r pm +Ġmat s +iat ry +- General +èᝠåºĹ +ãĢĤ æĹ¢ +Ġp aved +ä¹ĭ æľ¯ +_M AN +Ġco ords +Ġped ag +ĠR anger +z n +Ġo der +Ġsl am +çļĦ 对æīĭ +ĠPro posal +ĠMic he +é½IJ é½IJ +æıĴ æ§½ +ĠBudd h +ãĢģ ä¼ijéĹ² +驱åĬ¨ åύ +_z one +Ġp eren +æľª æĪIJ年人 +å¥ĭ æĪĺ +Ġtoug her +ç® į +Or Default +ĠTV s +Ġeconom ists +w arn +èĩŃ æ°§ +a ção +ä½ı æĪ· +èį£èªī ç§°åı· +Ġkilomet res +Ġ åı¸ +en h +ĠE rik +èįī åľ° +ĠD ependency +ex amples +åķĨ ç͍ +ime o +ï¼Į è¿IJç͍ +ä¸Ń å°Ĩ +( ... +Ġgre edy +.ar ange +åĪĨ æľŁ +Loc ator +ĠH uawei +åŃIJ åľ¨ +Ġco herence +_TIM ER +ĠCeleb ration +Ġpropos ing +OUT PUT +I EEE +人 æīĭ +å¿Ĺ è¿ľ +ç»ĵæŀľ çļĦ +åħ® åħ® +å̼å¾Ĺ 注æĦıçļĦæĺ¯ +" ... +æĹģ è§Ĥ +Ġb if +ãĢģ æĺİ +åħ¬åı¸ åĴĮ +æĮĩ å°ĸ +æ¯Ľ è¡£ +Ġbron ch +ç¯ ¡ +æĪIJæľ¬ ä½İ +bal anced +w rong +Ġtransform ative +伤 çĹķ +èĭ ŀ +åĩº éĶĻ +emb ourg +æĹł ä¸į +Ġais le +æ¨ Ł +åIJİ å¤© +- ext +m ins +ĠN ano +åľ¨ 第äºĮ +Ġad orn +m ala +èĦĤèĤª éħ¸ +Ġw ir +æİ¨ ä»ĭ +Ġdat as +Ġt attoos +ï¼Į è·³ +Ġprogress es +ĠG OD +çļĦ åĮºåŁŁ +Ġim minent +ĠTrack er +_F ULL +å»¶ åºĨ +ä¼ģä¸ļ åIJĪå¹¶ +Ġper severance +ĠChief s +\| _{ +èĦ¸ éĥ¨ +Ġill umin +çļĦ女 åŃ©åŃIJ +LOG Y +Ġfost ering +å¤ĸ åľ¨ +åįģ åĩłä¸ª +çģµ åĦ¿ +ĠIn gredients +ãĢĤæĪij åĽ½ +C her +å¿ĥçIJĨ åĴ¨è¯¢ +Ġaggreg ated +C HECK +pp ler +ä¸īåįģ åħŃ +S IM +ĠC ognitive +cre w +羣 æĥħ +** ]{} +åij¨ åħŃ +are th +ä¸Ń 空 +æĺŁ éĻħ +.T ask +/ etc +L ifestyle +åī¯ éĥ¨éķ¿ +ĠTor res +Ġm ansion +æ²³ è¾¹ +åIJĮ ä»ģ +Ġcomput ations +iqu ity +åĽ½å®¶ æłĩåĩĨ +èĨĢ èĥ± +è§£ æķ£ +éĺ² æ±Ľ +empt yset +æ»ĭ åħ» +ãĢģ ç½Ĺ +麻 çĹ¹ +/ con +æīĢ è¦ģ +UI Kit +太 ç¥ĸ +Ġconf inement +_se cret +c red +æ·± éĤĥ +NEW S +Ġ æľįåĬ¡ +Ġc ot +)init With +çŃĽ æŁ¥ +. property +罪 æģ¶ +Ġamer ica +Ġf oc +af a +ĠChap man +Ġl ays +主è¦ģ 为 +åĩºçݰ è¿ĩ +åıijçĶŁ çļĦäºĭæĥħ +æĸĹ å¿Ĺ +èµĭ èĥ½ +Ġattent ive +Reg arding +ĠM sg +Ġyield ing +ĠEd iting +ć ãĢģ +f unnels +çα æĪij +èĤ© ä¸Ĭ +ĠAR G +in ine +ä¸įä»ħ åı¯ä»¥ +åľ° çĽĺ +å¹³ åĿ¦ +Count s +çıĬ çijļ +æ£ķ èī² +è¶³å¤Ł äºĨ +oub t +-a fter +ï¼Į æķĻèĤ² +åħ¬ è¯ī +Ġloc om +. merge +æĪij们çļĦ çĶŁæ´» +Ġpay check +Ġachie vable +导 åĩº +ĠCong ratulations +t cl +åIJİ ä¼ļ +è¿Ļæĺ¯ ä»Ģä¹Ī +Ç İ +Ġt urtle +es ch +.r ange +çļĦ åij½ä»¤ +ãĢij : +(* ) +Ġ æľ¨ +Ġ æīĢæľī +Ġen chant +.st orage +éĽĩ ä½£ +ĠC andidate +æ¸ħ èĦĨ +åĽ¢éĺŁ æĪIJåijĺ +r ified +ãĢĤ åĮħæĭ¬ +çIJ ¥ +Ġmeaning less +Ġsav vy +-ch ain +çĨŁ çļĦ +. var +ç§° çļĦ +P ause +y ch +ĠBullet in +åī ģ +TOC OL +Ġthro ttle +å®ļ 为 +d or +Ġdisrupt ive +èIJ½ äºĨ +ä¸įèĥ½ 让 +b ins +ï¼Į åį« +ĠBath s +çĹĽ çļĦ +}} }$ +ĠBoard s +å°ı çģ« +éĹ®é¢ĺ ä¸Ĭ +æĨ§ æĨ¬ +表 åĵ¥ +Ġabdom en +ä¸Ģ缴 éĥ½ +çĵ· åύ +æĸĻ åΰ +Ġmat hematic +Ġt exas +ĠB old +æľĪ ä»» +ãĢĭ ï¼Ľ += r +Ġmod s +æľ¬èº« å°±æĺ¯ +åı¯è°ĵ æĺ¯ +åĨ· éħ· +ĠSan chez +D ub +Ġo ath +æµ· è¾¹ +ist les +AC L +N X +ï¼Į åĸľ +èϽçĦ¶ 没æľī +Ġjoy ful +ä¼ļ æīĢ +-c oll +æĢ» æĶ¯ +é²ľ æĺİçļĦ +ĠL PS +åĩıå̼ æįŁå¤± +å°ı ç»ĵ +ĠSub sequently +æį¢ 个 +_m d +Ġheight ened +ï¼Į æIJŃéħį +Rest ore +åĪĨ æµģ +ild a +åĵģ å¾· +Ġel ders +å¢ŀ é«ĺ +Ar thur +á t +d rag +大 殿 +Ġext rap +cher y +举è¡Į äºĨ +, æĽ¾ +çĭ¬ æľīçļĦ +Ġcommand ed +ãĢģ åį«çĶŁ +Ġform atter +纳 éĹ· +Enc oded +Ġancest or +åĭĴ æĸ¯ +ï¼Įæĥ³ æĿ¥ +.b in +ĠHor izontal +ï¼Į 注éĩį +( Class +Ġs lick +å¨ Ĩ +åīįæıIJ ä¸ĭ +Ġsurviv or +ç¨ ¼ +è¨Ģ èĩªè¯Ń +ĠDe er +èį· èĬ± +åĽłæŃ¤ èĢĮ +Ġprogress ively +ĠPack ers +ĠScient ists +_w rapper +-N LS +default s +Ġnurt ure +m ur +_ el +Ġwh ales +ä»» æĢ§ +åĩı åİ» +-sh aring +uls a +, ç»ĵåIJĪ +æľ¬ çĿĢ +In cludes +åıª æĢķ +Requ irements +èµ°äºĨ è¿ĽæĿ¥ +ί ν +çĮ ¾ +_OP TION +xxxx xxxx +( property +èĢģ å¦Ī +åĮĹ ä¸Ĭ +e asy +æĹ¶ æĹ¶ +çļĦç¡® æĺ¯ +h app +éĵł çͲ +çļĦ åı¤ +ï¼Įä½ł åľ¨ +ient o +.fl ush +éĴ± è´¢ +ç͵影 èĬĤ +ĠP LL +ĠK ab +DE CL +è¿Ļ æĸ¹éĿ¢çļĦ +éĥ¨ ä¸ĭ +Th ing +ï¼Įåħ¶ä¸Ń åĮħæĭ¬ +ï¼Į å¢ŀéķ¿ +her its +_object s +, æĢ»æĺ¯ +Ġc abbage +rav ings +çľ¼ äºĨ +ĠBehavior al +èĽ ¤ +Ġcoinc ide +ãĢĤ éĩĩç͍ +åıij表 äºĨ +çĿģ çĿģ +âĢĶ to +- aged +è£ ĺ +.h igh +Ġent ang +å¼¹ åĩº +ä¹IJ ä¹IJ +åĽŀ é¦ĸ +è¿ŀæİ¥ åύ +åŃĻ å¥³ +re ase +ä¼ļè®® çļĦ +oc urrency +dis patch +CON D +max imum +éĺ ij +她 åĴĮ +e el +èĢĥ éĩı +rem ember +ç§ij å°Ķ +Ġque er +Ġp pm +( Name +æ±Ł åĮº +yth m +èĮ¶ æĿ¯ +Ġinform s +K I +ĠF ork +ĠSalv ador +\ vert +ll er +çļĦ éĶĢåĶ® +æĿİ æŁIJ +-w ar +ĠR PM +Ġstraw berry +, åĩłä¹İ +ï¼ĮæĪij 没æľī +Ġprof essions +ĠD ee +Ġmulti player +人 çī©çļĦ +äºij 端 +顽 åĽº +_S PEC +æijĦ æ°ı +ĠE lim +Ġ# - +éĤ£ åIJį +M ON +CEPT ION +æĦı æĥ³ä¸įåΰ +Ġ 她çļĦ +P rep +ĠM ush +ä¼ł æĿ¥äºĨ +quo ise +equ ential +ä¸Ń æĢ§ +å®¶ éķ¿çļĦ +ĠDirect ive +ynt hetic +ä¸ĭ 楼 +çī¹ æĿĥ +Ġli ed +Ġaccount ant +çļĦ è·¯ä¸Ĭ +( word +ä»ĸ åį´ + ¦ +ä¸Ģ æĢĶ +å°ıç¼ĸ å°± +ĠAlexand ria +o ing +ous ed +Ġnomin ations +çļĩ 室 +Ġtroubles hooting +Ġ éĤ£äºĽ +ĠT I +reg ex +åįģäºĮ æľĪ +ĠSac red +Ġeng ages +Ġdr m +( ä¸ī +ï¼Į ä¾§ +å¸ĥ æĸĻ +æĥĬ 天 +Ġindex ing +éªĨ 驼 +( level +Ġ åIJ¬ +奥æĸ¯ åį¡ +.dat etime +[ C +ath i +Ġrabb its +äºĨ åĩłä¸ª +è¿Ľ åİ»äºĨ +em os +è¢ ħ +åĴĮ æĹ¶éĹ´ +Ġdefend ers +æ´ŀ åı£ +Ġsch izophrenia +lik ed +_a udio +æ°¸è¿ľ ä¸įä¼ļ +@ class +? ). +Ġ åºĶ +end point +ĠVik ings +Ch anging +Rec order +æľº å¯Ĩ +Gold en +ãĢĤæĪij è§īå¾Ĺ +ĠShe ffield +æĽ´ éĩįè¦ģ +åı£ 岸 +è¿ĺæľī ä¸ĢäºĽ +_NAMES PACE +Ġn ylon +ffff ffff +ĠJu ice +èĦļ çļĦ +Ġparas ites +ä¼ļ éĢīæĭ© +Ġposit ives +W al +ĠB out +ä¸ĭ éĥ¨ +èµĽ éģĵ +æī© 建 +åī¥ å¤º +åĮĹ è·¯ +cl ang +_in stall +BY TE +Ġsp heres +çĶŁäº§ åĬĽ +w oo +Ġsal ads +Ġemb ell +ç½ijç«Ļ ä¸Ĭ +ä¹ĭåIJİ å°± +æīĭ æŁĦ +.S pec +ï¼ Ĥ +çĹ Ĭ +It alian +pre view +ç¹ģ å¤ļ +, åģļ好 +S id +éĢļ ç͵ +U id +ee le +ĠTr ader +夯 å®ŀ +ĠMan or +Ġdoub ling +pe ek +Ġfl uffy +çļĦä¸į è¶³ +ĠIncre asing +os ke +ish able +ĠImport ance +åľ° 主 +è´¨ ä¿Ŀ +åıį æĦŁ +Ġsoft ly +Ġimproper ly +ãĢģ æ±Ł +æĶ¹éĿ© çļĦ +ĠV III +pp m +åħ« çϾ +éĢģ æĿ¥ +ç»ĻäºĨ ä»ĸ +ĠT act +æĸ¹ åı¯ +å¤ĸ å¢Ļ +Ġlink age +Ġtr out +Ġpolic ym +åħ¬å¼Ģ äºĨä¸Ģç§į +Prot ection +å±± æŀĹ +ï¼Į æļĤæĹ¶ +ĠW V +P itch +ĠV ick +" They +Form ula +çļĦ ä¿¡ +è¶³ åįı +U PS +Ġperson a +uck ing +åĩı æİĴ +çī©çIJĨ åѦ +( gl +W are +Ġsol ids +Dep loy +æĭ¥ åłµ +ï¼Į 女人 +Ġsh ines +å·ŀ åĮº +èĩ´ 使 +ant es +Ġacc ret +ï¼ĮéĤ£ æĹ¶ +SE M +ĠSw ing +] == +ï¼ĮæĹł å¥Ī +ä¾Ŀèµĸ äºİ +ĠInsp iration +ï¼Į å͝ä¸Ģ +- around +Impro ve +ĠW B +ĠG REAT +大 é£İ +å®ī åİ¿ +ah i +ï¼Įéĥ½ æľī +åı¹ æ°Ķ +éĿ¢ 容 +Âł æĿ¨ +ãĢĤåħ¨ æĿij +Ġp ore +ĠJ agu +éĩįè¦ģçļĦ ä½ľç͍ +_gener ator +æ°Ķ åĽĬ +/ open +Start up +ĠD ex +UD P +æ·ĩ æ·ĭ +ary n +Ġcommun al +æĴĩ åĺ´ +ĠGonz alez +g ene +Ġhand ing +æĸ© æĿĢ +out ines +Ġclos ures +ãĢĤæľī æĹ¶ +. Byte +$ ? +车 çīĮ +UN TER +_ sock +äºij 计ç®Ĺ +ĠSch war +Ġoblig ated +åIJİ åľ¨ +_c mp +_c ols +Ġê ° +åĢ ı +Ġdown stairs +ĠBald win +çļĦ 建设 +èĥ½å¤Ł 让 +å¿§ 伤 +åħ³èĬĤ çĤİ +Ca ption +ãĢĤ ä¸Ĭè¿° +s quare +没 å¤ļä¹ħ +æĪ´ ä¸Ĭ +-r ays +_ words +{ | +ĠG tk +- area +Ġnecess ities +Ġvol leyball +ĠPat terson +n ear +æķĻèĤ² åİħ +\ Big +Fore ground +ST A +b idden +Ġb h +Me eting +or r +Ġrec reate +d ead +ĠShe ets +Abs olutely +Ġf encing +ed ed +ĠT ian +ĠPres cription +åij¨ åĪĬ +_s z +äºĨä¸Ģ åĿĹ +群ä¼Ĺ çļĦ +Ġcarp ets +b ull +第äºĶ 竳 +: * +çĿ ij +ä¸į æīĵ +宣 è¨Ģ +éĩijèŀį æľįåĬ¡ +Ġmel ody +ï¼Į æĬ½ +Ġad missible +GR APH +k at +per haps +产åĵģ åĴĮ +åįĸ çļĦ +转æį¢ æĪIJ +ĠMoh ammed +k j +åĩº çĤī +å¼Ģ åľº +ĠSun shine +.set Value +è§ģ äºİ +åĽ´ æĶ» +æĹı èĩªæ²» +æĺ¥ æĻļ +ï¼Į æĥħ +主è¦ģ çͱ +Ġround ing +- engine +ãĢĤ çľĭæĿ¥ +ĠT weets +ï¼Į éĴŁ +æŁ¥ éªĮ +é»ij 人 +å¿ħè¦ģ æĹ¶ +out heastern +éŁ³ ç®± +for th +Cl osing +ä¸ĩ 亿åħĥ +Ġ çĤ¹åĩ» +ĠLif etime +Less on +éĩįè¦ģ 讲è¯Ŀ +ad c +, å¿ĥéĩĮ +大 çľ¼çĿĽ +åĴĮ æİ§åζ +rapeut ics +çĶŁ åŃIJ +Ġconnect ors +å¥ĭ è¿Ľ +é«ĺ级 管çIJĨ人åijĺ +Ġ åį³ +Ġpr istine +ĠTrain er +ĠC PA +to ire +_EN UM +,æľī æĹ¶ +WE B +ç§ § +Ġpur ification +ĠHigh land +ä¸įç¡®å®ļ æĢ§ +è§£ é¢ĺ +ãĢĤ åݻ年 +Ġun ite +æĹłéĻIJ çļĦ +ĠT enn +ãĢģ æĵįä½ľ +ĠTe h +æĦıè§ģ 书 +èij © +ĠS askat +è¿Ļ è¾ĪåŃIJ +åĸĺ æģ¯ +审计 æĬ¥åijĬ +, å¸Ĥ +主 æīĵ +æľ¬ 人çļĦ +H OST +Ġk b +åĬł çĽĸ +ï¼ĮèĢĮä¸Ķ åľ¨ +Ġban anas +_C TX +ĠSun set +ĠC i +ĠJ ag +ĠK ris +ï¼Įè¿Ļ çĤ¹ +Ġexpl or +AB ASE +i age +çĭ¬ åħ· +ĠT aken +Ġrel ational +A ware +pret ty +å®īéĿĻ çļĦ +Div ide +Ġalt ar +Ġant imicrobial +ĠYes terday +ë ı +_r ules +z d +ï¼Į ç§ijåѦ +ĠBi ography +个æĢ§ åĮĸçļĦ +ĠI sh +Ġ åģļ +aph ore +é«ĺ å°Ķ夫 +çľĭ çĹħ +该 æŃ»çļĦ +ĠPar ade +æĪIJæľ¬ çļĦ +åĴ¬çīĻ åĪĩ齿 +æĪij çĽ¸ä¿¡ +Ex clusive +p riority +主 æ²» +é£Ł è°± +ä¸į åĸĦ +ãĢģ 绿èī² +æĪij å°±æĺ¯ +)$ - +Ġaggrav ated +çļ ĸ +ĠN ixon +é«ĺ èģĮ +( /\ +inherit doc +ãĢģ æµĻæ±Ł +é«ĺçŃī åŃ¦æł¡ +çĭ© çĮİ +orget own +ĠA H +Ġsp ikes +ä¸Ģ次 çļĦ +AAAAAAAA AAAAAAAA +/ åIJ¨ +两 项 +Ġplanet ary +(result s +h adow +æľĽè¿ľ éķľ +Ġt sd +.com pute +è¡Ģ èĤī +Ġcris py +( column +ĠBl end +, # +ER IC +_n s +ĠRef resh +-con sc +Ġdisag reement +Ġ éķ¿æľŁ +ãĢĤ çĿĢ +Ġg ir +Ġ... ) +æĥ³è±¡ åĬĽ +ad ia +åķĨ èªī +ĠP ond +ãĢĤ 缸åıį +ï¼Į åIJĦ个 +urs ed +ãĢģ æ³ķå¾ĭ +缴 éĶĢ +bound ed +h aving +C ss +产 å¦ĩ +èįī èᝠ+å¹³åĿĩ å̼ +为 çͱ +Is lam +å¿ħ æľī +Never theless +ĠU rl +è¯ģ 人 +-m ails +Ġdiscrep ancy +} f +Ġprox imal +Ġpredict ors +Ġworkflow s +åĨį åĬłä¸Ĭ += N +ĠPC B +æ·± åİļçļĦ +ĠA val +åĿ · +Ġlong itude +åĽŀåΰ å®¶ +åĬ¨ å¼¹ +print ed +Ġstri ker +ĠÏĢ Ïģο +, æīĢæľī +_d elta +äºĨä»ĸ ä¸Ģçľ¼ +âĢľ But +ĠComb at +b idity +å¹´ æ¯ķä¸ļäºİ +ï¼Įä¹Ł 让 +ç»ĵæŀĦ è¿Ľè¡Į +ĠP DT +å¥ĩ å¹» +åįı å®ļ ++ d +. ru +çļĦ 建çŃij +Ġrest ed +åįģä¸ī æĿ¡ +ç»Ļ åĪ«äºº +æ³ī å·ŀ +il tered +ó w +ĠF ur +æľ¬çĶ³è¯· å®ŀæĸ½ä¾ĭ +ç͍ ä»Ģä¹Ī +课 æĸĩ +Ġsubs cribed +-he arted +群 éĩĮ +ä¸į èĩªè§ī +Ġ åİ» +Ġp om +å¯ IJ +dd ing +åľ¨ æİ¥åıĹ +< html +Ġ è¿Ļæł·çļĦ +æķĪçİĩ é«ĺ +Ġun install +C oe +, æīĵéĢł +ĠUn ix +æĮĩ äºĨæĮĩ +ä¹ŀ ä¸IJ +ï¼Į æĬĵ +å¥Ķ æ³¢ +ĠSpec ies +æļij æľŁ +ĠHam pton +G NU +} '. +è·¯ ç¨ĭ +rend erer +çļ® éĿ© +èĥ° å²Ľ +ĠMer cy +èĢģ æĺ¯ +if ace +åħ¨ åijĺ +Local ized +. require +ï¼Įä¸Ģ 天 +ĠAccess ibility +ĠChild hood +åΰ å®¶ +èµĽ ä¸Ń +夫 æĸ¯åŁº +ĠChe ng +Ġ å®¶ +ov i +so on +å¢ŀ æĶ¶ +TreeNode Img +Âģ ÃIJ +Ġshock s +æĭ¥æľī äºĨ +åŁºç¡Ģ设æĸ½ 建设 +éĩį è¿Ķ +åİŁ æłĩé¢ĺ +Ġh amm +ĠMat thews +Ġgu itars +P OP +æİ¥ éĢļ +PC B +è¿· 人çļĦ +éļ¾ä»¥ 置信 +ĠD OT +ĠR i +满足 äºĨ +çĤ¹ éĴŁ +ĠSupport ed +ą ï¼Į +åĿļæĮģ 以 +ãĢĤ æľ± +az ard +- cons +Ġcheck box +- att +END OR +Ġcont ag +æıIJ çĤ¼ +é£ŀ èĪŀ +Ġtit anium +åŃĹ åı· +_P OST +- To +ä¸Ģèά 人 +èĺ ¸ +Ġesc aping +çļ±çĿĢ çľī头 +- help +å·§ çļĦ +G i +W ide +ï¼Įå¦Ĥæŀľ æľī +/ Z +ï¼Į å·¥ +ãĢģ è¿ĩ +_ like +_ch anged +滥 ç͍ +Ġexpos ures +ĠV u +ä¸įåľ¨ æĦı +å¾®éĩı åħĥç´ł +Ġnutrit ious +è§£ åīĸ +_P OL +. qq +Ġinfil tr +çļĦ ä¼ĺçĤ¹ +mult iple +, ä¼ģä¸ļ +âĢ Į +ä¸İ 该 +åħ± æĮ¯ +am ac +.Get Type +ĠBig Decimal +Ġst unned +Ġin i +æĹł ä»İ +åIJĮ å¹´ +is ional +ä¸Ń éĢīæĭ© +ï¼Ł çİ°åľ¨ +_comp lete +Ġdict ate +, éĺ²æŃ¢ +è£ħ è½½ +èĭı éĨĴ +åĪ» çĶ» +ARI ABLE +æĬĬ éĤ£ +èħ¿ éĥ¨ +ĠWin ners +.sh ared +.G lobal +ĠBul ld +-g rid +Ġple as +Ġ ä¸ģ +ĠS q +ĠU nt +å°Ĩ 为 +Ġv ortex +ĠBur ger +ï¼ĮåĪĨåĪ« æĺ¯ +Ġstar red +ĠRet rieve +奴 æīį +Ġbiom arkers +(( * +Ġg ust +èĥ¡ 说 +æĩĤ äºĨ +Ġcomplic ation +ë § +_SE TT +D VD +ov irus +ä¸Ģ对 ä¸Ģ +Ġâĸ ł +- items +Ġc reek +æµģ åIJij +èᝠå¸Ī +] ]. +èĢĮ 导èĩ´ +èħ° éĥ¨ +isc iplinary +Ġintrig ued +伪 éĢł +Ġreb ound +keep ers +c amera +ï¼Į 诸 +ber ly +-f iction +Ġassign ing +Bound ary +Ġfingert ips +ĠS lovak +)) \ +å¨ © +ĠLET TER +. (* +Ġ第äºĮ çϾ +ro cal +为 以ä¸ĭ +ĠMechan ics +ãģĤ ãĤĭ +ä¼ł çIJĥ +Ġreplace ments +) p +ĠI gnore +大 涨 +ĠBel arus +Ġrock ing +Ġd ors +ĠW it +ĠSERV ICE +ĠBrow ns +ĠCare ers +ĠLe ase +å°ı å·· +(s kb +Enter prise +大 åŁİå¸Ĥ +ED TLS +宽 éĺĶ +Ġimport ing +ĠN FC +ï¼ģ éĤ£ +çİī çŁ³ +Equ ipment +ĠCong o +éĥĿ ä»ģ +- eyed +Ġex ting +å°ij æŀĹ +æĬµæĬĹ åĬĽ +è¿ľ åı¤ +Al ive +Ġconv olut +è§£ å¯Ĩ +Ġsub routine +Ġwh ipped +ĠAd apter +Ġ{} ", +ä¸į åħ¥ +Ġ æĽ¹ +âĢĿ ï¼ļ +éĶ Ń +èĢĥ ä¸Ĭ +Ġellipt ic +ä¸įæĺ¯ ä½ł +Ġn h +è¦ģ ç´§ +Min utes +ï¼Į 缸äºĴ +Ġsw ipe +th alm +åľ°æĸ¹ çļĦ +IL ER +- we +Ref lection +Ġdoctor al +弯 èħ° +Ġf ö +.S p +re on +éĤ£ä¹Ī ç®Ģåįķ ++ r +ĠLaw n +Ġexperiment ation +$ ), +_t uple +åºĶ该 åľ¨ +Ġunconst itutional +æ²¹ èĢĹ +ï¼Įè¿ĺ 没æľī +ĠEst ablish +Ġst rives +ĠCas inos +åĽºå®ļ æľī +Ġh ym +Ġre combinant +麦åħĭ é£İ +å¤ļ ä½ĻçļĦ +RES ENT +ĠInnov ative +, 她çļĦ +ä½įäºİ æīĢè¿° +Ġcov id +Ġs yst +麻çĥ¦ äºĨ +ĠPere z +ĠP ag +ï¼Į å®Ī +ä½Ļ å¹´ +èĥ¡ åIJĮ +ç¬ij çľ¯çľ¯ +Ġadvoc ating +çĦ¶ åľ° +ĠRET URN +- α +ĠSo il +ç¾Ł åŁº +åĩı åħį +Æ ° +L ayers +ãĢģ åĮĸåѦ +ä¼ļ åIJĮ +ç®Ĺ ä»Ģä¹Ī +èĮ¶ æ°´ +ent ropy +ĠU R +Ġgo ats +( None +ä½Ľç½Ĺ 伦 +Ġtall er += g +Ġ 温 +Ġamid st +æ·± æµ· +-f l +put s +å®ĥ åľ¨ +çļĦ é£İæł¼ +éħĴ 楼 +åĤ» çĵľ +Ġy acht +ĠHe arts +al on +æĹģ 人 +ï¼Į æĬ¥ +ĠK erala +Ġinc umbent +ĠPhilipp ine +Ġ ^{ +Ġm ell +Ġrot ary +Ġpave ment +åı¯ æľī +ĠRun ner +Ġf name +Ġpostpon ed +ĠSpe ak +Ġastr onaut +Ġt andem +ad apt +ĠY uk +åįĥ 人 +å¤ĸåĽ½ 人 +ĠMeet ings +头 åĥı +ĠI CE +ad ors +ĠZ ur +èĪª è¡Į +毫 åħĭ +(def n +Ġinterven e +S izes +Ġoscill ations +åł¡ åŀĴ +G lyph +çαæĥħ çļĦ +çĤĴ èĤ¡ +ĠP ing +Ġconjug ate +âĢľ åľ¨ +j c +ib ble +ĠFe et +å¼Ģ å±Ģ +-M art +åĴĮ ç»ıæµİ +èµ° åIJİ +w ifi +æĢ¨ æģ¨ +æĺ¯ æĢİæł· +Ġ çīĪ +Ġmod eration +åħ¨çIJĥ åĮĸ +Ġenlarg ed +ä½ł 没æľī +èĩ´ è¾ŀ +çŃī éĥ¨éŨ +Ġplan ar +ĠCr ash +Ġw ary +éĵ¾ è·¯ +主 线 +ĠRem ark +æµĭ éªĮ +cul ation +_f rames +Ġtheat rical +æĸ° ä¸Ģè½® +è¿· ä¿¡ +è² Ĥ +_ arch +追 æį§ +Ġspeed ing +ĠHar bour +Us es +ĠK hal +æµĵæµĵ çļĦ +mon ths +ocal ypse +Supp ly +ĠDipl oma +Ġc ps +Ġbetray al +ĠMig uel +/ res +è¿Ļ个 è¯į +_ AM +ob server +Ġp iles +N Z +æ·± çŁ¥ +ε ÏĤ +åīį åįģ +Ġexhib iting +! []( +å¹´ åΰ +èĩª èĢĥ +Ġfoot steps +ï¼Į åħ» +User Name +Ġproject ive +Property Name +åIJĥ èĭ¦ +åĶ¿ åķ¸ +K V +æĹ¥ æ¸IJ +åı¯èĥ½ åľ¨ +ĠPT SD +l od +Count y +Ġv ous +S aint +ä½ł ä¸įè¦ģ +vers ely +ï¼ĮæīĢ以 æĪij们 +-m ember +ĠM ae +ĠSan ct +Particip ants +/ Web +Ġaqu arium +Ġ èĵĿ +ĠL AN +åĽ½æ°ij ç»ıæµİ +åıij åijĨ +Ġconfident ly +T ickets +Ġd addy +n umpy +ä¸Ĭä¸ĭ æĸĩ +Ġpolym ers +âĢĵ âĢĵ +ï¼Į车 ç¨ĭ约 +Ġw agon +ĠLie utenant +Ġ ç»Īäºİ +涨 ä»· +Ġsp or +åĽ¢ å§Ķ +_DE LAY +, ä¼¼ä¹İ +Ġswing ing +Ġ éĢĤç͍ +ï¼Į æ¢ħ +ĠR he +çİ© äºĨ +å·¥ä¸ļ åĮĸ +ag ation +ĠE lections +Ġmanip ulated +-s eries +Ġdr astic +g is +éĺ¿ åĵ¥ +in ol +ump ing +O il +S ell +Ġsk b +éŨ æ´¾ +ç¾½ ç»Ĵ +Ġincomp atible +æķ ķ +ev idence +R ace +AG ER +åħ±åIJĮ çļĦ +ç»ıæµİ社ä¼ļ åıijå±ķ +Ġmil estones +ĠC NC +-off s +çĤ¼ åζ +ĠT ina +ĠMar itime +ĠBrew ing +çļ®èĤ¤ çļĦ +交éĢļ 大åѦ +S it +ĠMac ro +ç»Ļ人 ä¸Ģç§į +Ġatt ic +ä¹ı åĬĽ +çļĦ çĶ»éĿ¢ +马 æ¡¶ +æĬĹ çĶŁç´ł +,以 åħį +Che ap +/d ist +Ġ åŃ¦æł¡ +Ġr ud +ä¸İ åºĶç͍ +管 å§Ķä¼ļ +è£Ĥ 纹 +ĠPun jab +ãĢģ æ´»åĬ¨ +.c os +ï¼Įä½Ĩ çİ°åľ¨ +ĠB oulder +ull a +co e +大 å®Ĺ +Ġsw orn +Ġco ils +Ġe commerce +æĢĿæĥ³ æĶ¿æ²» +ĠM H +L ik +v ä +ĠV EG +é»ij å½± +, å®ĥçļĦ +Ge orgia +ĠN ights +lo on +ant ine +ä¹Ł åįģåĪĨ +Ġprohib ition +> - +Ġ æĹ¥æľ¬ +Ġinc ur +ĠPred iction +éĢī çļĦ +ĠFor get +M ER +ub es +Ġ/ \ +âĢĶâĢĶ âĢĶ +g oog +oo b +Ġactiv ism +-link ed +ĠD ON +Ġvit ality +Ġon c +ï¼Į åĬ©åĬĽ +åľ° çĽ¯çĿĢ +eg ie +ĠAub urn +in ions +æĹ© é¥Ń +éļĶ ç»Ŀ +æģ ĥ +Ġmand ated +åĽŀ éģĵ +(name of +Ġmin ors +ign on +ĠJ ude +éªij çĿĢ +Ġstere otypes +åħ³æ³¨ æĪij们 +ĠT inder +è¡Į è¿Ľ +ser ve +ç²ĺ 度 +æĬĽ åĩº +Ġboss es +ett ed +ãģĵ ãģ® +缸 ä½į +详 è§£ +çϾåĪĨ æ¯Ķ +Ġbegin nings +, åĮĹ京 +ĠD AC +ï¼Ł ä½łä»¬ +ï¼Į åı² +æľ¬ æĺ¯ +æľº åĴĮ +Ġpl ac +Res olve +oph age +æľī æķ° +Ġadm ired +èĮĥåĽ´ ä¹ĭåĨħ +Ġm und +ĠEmer ging +ĠS DS +Ġg s +软 çļĦ +S ections +ak is +åħµ åĽ¢ +ãĤ ¨ +ĠV ictory +åŃŠ第 +Ø µ +ĠL F +åºĶ该 å¦Ĥä½ķ +Ġbar becue +è£ħç½® åĮħæĭ¬ +Ġmed als +Ġvar char +, {\ +C ru +ĠNatal ie +OUR CES +åĭĺ å¯Ł +夹 åħ· +ĠFil ters +ĠLand ing +ï¼Į ä¸ĸ +æĬķ 产 +ĠG one +èĩª è´Ł +Ġdiscontin ued +å¤ļ è¾¾ +ĠUS ART +Ġfer mentation +æİ¨èįIJ çļĦ +åĬĿ 说 +J u +æĻ® æŁ¥ +oph one +é£Ł çĽIJ +åı¹ éģĵ +_ cond +ĠX I +éĥ½æľī ä¸Ģ个 +æ¶ § +ä¸įæĺ¯ åĽłä¸º +Char acters +Ġd z +_m ulti +IP O +å±± ä¸Ń +_ player +ï¼Į åŃĺåľ¨ +Ġbo iled +ĠC ot +ï¼Į以 使 +ins ide +ynom ial +Object ive +ĠA UD +Ġinflu x +B rain +åŁº ç«Ļ +å§ĭ çļĩ +çļĦå¤ĸ ä¾§ +ĠVent ures +Ġi od +çŁ¥ å·± +an ian +Ġpresent er +åĽĽ äºĶ +D igest +ĠHer bert +åĪ» èĭ¦ +Ć Ć +大 人çļĦ +ä»» ä¸Ģ +ĠErr ors +è¯Ńè¨Ģ çļĦ +Ġconvey ed +Ġ æĪIJ +åºĨ åħ¸ +Ġun supported +. yml +ĠR aven +ä¹Ł éļıä¹ĭ +çļĦå¤ĸ éĥ¨ +Ġg g +ĠClass room +æ¯ Ĥ +ric anes +Ġorigin ating +ek t +æĬĹ èıĮ +Ġv il +é¦ĸ 缸 +Ġwater fall +Ġcal ming +å®ĭ 代 +OD ES +Ġextract ing +ĠProm o +ĠC ST +-h ydro +, çľĭçĿĢ +ä¼ģä¸ļ ä¼ļ计åĩĨåĪĻ +ĠPattern s +æĢª çļĦ +Ġdin ners +Ġrev ise +ruct ures +, 羣æŃ£ +h b +Ġa ided +Ġ* > +_V IEW +Ġon Create +çİĭ æŁIJ +EM S +ä¸ĩ å®¶ +âĤ¬TM s +Ġaggress ively +å¤į æł¸ +Ġbr ushing +举åĬŀ äºĨ +Ġpol len +Ġε ÏĢ +ĠWhe els +Ġsulf ate +- ' +- Pro +ä»ĸ çİ°åľ¨ +åıĹæ¬¢è¿İ çļĦ +Ġfright ening +k c +ĠFilip ino +åıĬæĹ¶ çļĦ +Ġd ome +èĬ± çĵ£ +{ % +Ġpl ague +Ġdeploy ing +ĠP ole +éĥ½ ç͍ +ç½® ä¸ļ +Ġarrest s +è½½ èį· +Det ection +su v +ä¿Ŀ æ´ģ +Ġetern ity +å¯Ĩ æĸ¯ +. weight +K Y +Pr im +ï¼Į åįļ +éĤ£ å¹´ +Ġdiscour aged +ĠF ULL +æ¯Ķ èĩªå·± +è¿İ æĪĺ +-threat ening +大 åĵŃ +< class +ĠL ack +ĠAg enda +åıī 车 +Ġs aints +ãĢĤ è¿ŀ +itt ens +åij½ åIJį为 +c iting +ä¸ī åIJį +èĤī ä½ĵ +åįĹ çĵľ +Ġreb el +ï¼Į 大åѦ +æīĵ èµ¢ +.user name +Ġ icing +_r ank +å¹²åĩĢ çļĦ +Ġ" ... +åıij æĸĩ +Ġbre aches +ĠAll ison +Ġf ren +Ġtut oring +Ġstabil ize +å®ŀ æķĪ +Ġed its +åįİ ä¾¨ +Th u +ï¼Į è®°å¾Ĺ +Ġsuper visors +ĠCor al +ĠL iam +ch id +_c ur +_v ol +g ins +_ engine +it r +Ġindul ge +. ret +æĹ¶ ä¸įæĹ¶ +ĠGu ys +åºĬ åŀ« +ĠTre vor +åºĶä»ĺ 款 +ĠR ip +åIJİ å°Ĩ +ĠPro te +éļı äºij +Ġback ups +Ġt ad +ĠV ER +äºĨ ä»Ģä¹Ī +ra per +äºĨä¸Ģ 天 +AS M +æĿ¾ åĬ¨ +ĠCaf é +æĿ¥ 个 +, æŃ¤æĹ¶ +h our +èĦĸ åŃIJä¸Ĭ +.Se lected +S OURCE +é£İ ä¿Ĺ +)- ( +æŀĹ åĩ¡ +_INTER FACE +| _{ +(d at +Ġimm ersed +å±ķ åĩº +Å ¯ +æĪijçļĦ å¿ĥ +/ Q +b inding +ĠS calar +- forward +ĠL TE +æĸ° æĪ¿ +ĠFo am +ĠCl osing +ï¼Įæ¯ı æĹ¥ +Ġmetast atic +- low +b ri +æ°ij èĪª +DB G +çļĦ å¹³åı° +K ate +ĠInst itutes +Ġt roll +Ġl inger +éľ²åĩºä¸Ģ ä¸Ŀ +Ġpollut ants +ad b +çī¹ äº§ +} ', +ä¸Ĭ è¡£ +æīĭ è¶³ +-fashion ed +ĠBr ass +çļĦ çģµéŃĤ +æľįåĬ¡ äºİ +Co ords +ä½ł åĸľæ¬¢ +Ġp end +ï¼ĮèĢģ åŃIJ +uff ered +è¿ij äºĨ +ĠðŁĺ Ģ +ĠT in +å¾Ģ å¤į +ï¼Į å°¤ +Ġtom ography +Ġj ug +Ġcomp ulsory +ç͵ åİĤ +à ¬ +ä»ĸ 为 +ï¼ĮçĦ¶åIJİ åıĪ +Ġf uss +碾 åİĭ +奥æŀĹ åĮ¹ +ï¼Į ä¸ĵéŨ +UMM ARY +羣æĺ¯ 太 +st h +ĠAll an +æĥ³ æĬĬ +ä¸ī æĹ¥ +ï¼Įä½ł çİ°åľ¨ +can ner +å©ļ åIJİ +a ption +建ç«ĭ èµ· +åij¨ çļĦ +ä¸Ĭ 个 +Ġiter ative +\ subset +ä¸Ń åħ¨ä¼ļ +Ġ éļ¾éģĵ +Ġde i +.M ock +Ġtw entieth +Ġcon greg +ĠO le +ç»Ļ åĩºäºĨ +åĨĻ ä¿¡ +ï¼Į åı¦ +åĩĨç¡® åľ° +Ġon wards +åķĨ åѦéĻ¢ +ĠX u +(p refix +å·¥ä½ľ ä¼ļè®® +Ġmod em +乡 ä¸ĭ +Ġwrong ful +Ġrev ital +P ossible +ĠL ands +è´´ åľ¨ +Ġfabric ated +åıijçĶŁ åύ +_ ic +it os +ä¸Ģ æĹ¶éĹ´ +Ġcomp ass +顺 æīĭ +.L eft +Ġh u +ĠBron ze +ï¼Į 缼 +模å¼ı ä¸ĭ +åĽ½æľī ä¼ģä¸ļ +w u +UR ITY +被 åĽ° +ĠÎ ¦ +pt o +Ġpos itivity +/ sw +ï¼Į çŃīçŃī +ĠRec ording +Ġpl anners +åĽŀåİ» åIJ§ +AST ER +ï¼Į ç³» +å·¥ä½ľ æĬ¥åijĬ +Ġvac ancies +-l inux +ks i +Ġforward ed +pe e +çľ¼ è§ģ +Ġcheck er +åı¯ æĭĨåᏠ+ink i +a urs +åıĺ å¹» +(p oint +æĢĿæĥ³ åĴĮ +Min or +æĸĩ æŃ¦ +缸 è²Į +Ġdraw backs +oped ic +æıĴ æİ¥ +- ever +ut ility +aps ing +B rows +æī§ åĭ¤ +å¹³ æ»ij +å¸Ĥåľº çĽij管 +++++++++ ++++++++ +F ine +Ġin advert +讯 æģ¯ +ãĢģ æ²Ļ +Level s +Ġp v +Ġpro g +åĽĽ 级 +' a +çī¹ æĭī +åħ¶ éĹ´ +亲 身 +èĻ« åŃIJ +_ plot +ï¼Į çļĩä¸Ĭ +.N one +Leg acy +ï¼Į åħ±æľī +Ġin ex +åı£è¢ĭ éĩĮ +_ abs +Ġd v +è½° è½° +Ġç¬¬åĽĽ 竳 +est ial +ĠÎ ķ +B on +th reshold +äº Ł +" [ +Ġh ugs +is Empty +, the +ĠS ail +åıª ä¸įè¿ĩæĺ¯ +åĪĺ æµ· +Ġdis mant +é£ŀ åİ» +-f ilter +åĪĨéĴŁ å·¦åı³ +Ġfun gal +DE L +é»Ħ çļĦ +失败 çļĦ +åĩºçݰ éĹ®é¢ĺ +Ġeager ly +J R +le ader +åī¥ ç¦» +æĢ¥ è¯Ĭ +host name +IX EL +Ġvac ations +ï¼ħ ãĢĤ +çĸı æķ£ +éĢł åĮĸ +å¤ļ å°ıæĹ¶ +_H IGH +Ġstabil ization +ä»ĸ è¿ĺæĺ¯ +èģĶ åĨĽ +ĠSett lement +Ġneat ly +g rown +ĠWe i +nov a +Pat ients +ç»Ļ å®ļçļĦ +We ak +åľ¨ ä¸įåIJĮ +Ġemb ark +ed ition +Ġte al +åĵ¼ äºĨä¸Ģ声 +Ġa ry +ãĢģ å½ĵ +èµ° åĬ¨ +Ġunc ategorized +åĽ½å®¶åĴĮ åľ°åĮº +P ure +èµ· çĿĢ +Ġrest ructuring +Rot ate +åľ¨ æľĢ +Ġ{ ¶ +bel ief +Ġmetabol ites +| = +-year s +å·²ç»ı å®Įåħ¨ +and i +ES H +.M edia +Ġacqu ainted +-spe aking +Ġno zzle +let cher +Ġre building +ĠRe leased +ĠRet ro +J ackson +ä¼ģä¸ļ æĸĩåĮĸ +å°Ħ é¢ij +Ġvoy age +Ġfunn els +Ġde port +é¢Ħ åĶ® +-w ave +çĿ¡ åīį +ï¼Į åĪĢ +Ġster ile +Ġparam ount +_M S +tensor flow +æĹ¶ éĴĪ +Ne il +Ġre ap +ĠM ia +ident ally +åįĥ åı¤ +ĠTrust ees +çļĦ 个人 +Ġdump ed +ink y +è¿Ľä¸ĢæŃ¥ åĬłå¼º +æł¡ åĩĨ +ï¼ĮåIJij çĿĢ +å¿į ä½ı +Ġreact ed +ĠL ug +ĠF argo +读 åĨĻ +Ġh ikes +ĠM ons +/ download +Key Value +F req +大 åIJį +äºļ åĨĽ +ï¼Į è¯ķåĽ¾ +è£ģ å®ļ +ĠD unn +ah ah +_b ind +( LOG +羣 好 +çļĦæĹ¶éĹ´ éĩĮ +ist as +åıªèĥ½ æĺ¯ +ten ant +Ġpop corn +没 éĴ± +æ·¹ 没 +ump ed +æŃ»äº¡ çļĦ +re pr +ĠV on +çľ¼ çľ¶ +P OR +k on +Fig ures +ĠK err +Fore st +ï¼Į 示æĦı +ç¼ İ +åIJĥ ä¸ľè¥¿ +/ aws +. valid +æĶ ĺ +_c enter +ĠFal con +æľº 车 +ĠW ent +ĠProv iding +æĪIJ è¿Ļæł· +sh adow +ĠAc quisition +缸 åĮ¹éħį +ï¼Įè¿Ļ ä»¶äºĭ +Ġphys iology +Ġwa its +ãĢģ å±±ä¸ľ +èµ° åĩºåİ» +ãĢģ åİĨåı² +æĭī åįĩ +ĠT ale +loc ated +å·¨ æĺŁ +èħ¾ èħ¾ +Al an +顺 åºĶ +.P osition +ãĢģ å·¥ +ï¼Įä»İ äºĭ +ĠE FI +d ummy +åĩº åIJį +广 ä¹ī +çªģå¦Ĥåħ¶ æĿ¥çļĦ +æĦ£ ä½ıäºĨ +ĠAbs olute +ï¼ĮæľĢ é«ĺ +Met al +f ine +Ġt k +æľīæīĢ æĢĿ +Aud it +çļĦ大 éĥ¨åĪĨ +(n il +Ġcal f +Gr ade +State Exception +æĪijåĽ½ çļĦ +Ġo ss +大 åĶIJ +ĠMon key +Ġbrid al +å·´ åŁº +å¾Ģå¾Ģ æĺ¯ +un iform +éĻį æ°´ +Ġland marks +ys sey +y ellow +è¿ĩ åī© +OM EM +ï¼ĮæĪij åı¯ +å¾Ģ å¹´ +客æĪ· æľįåĬ¡ +_ex ecut +ãĢĤ æĸ¹ +Ġamplit udes +åħ³éĶ® æĹ¶åĪ» +æĮĤ åı· +ç§ij æ¯Ķ +汽车 çļĦ +at ings +ï¼Į åIJĪçIJĨ +ä¸Ģ éĶ® +ä¸į 失 +ĠLa uder +-d ensity +é Į +Ġfamiliar ity +ãĢģ åįķ +åĨ¤ æŀī +' I +< u +$ ; +æ² ħ +çĽ¸å¯¹ æĿ¥è¯´ +Infl ater +Ġwal lets +ä¸ĩ æĪ· +/h ome +ĠRh odes +ĠDo ctrine +åζéĢł çļĦ +ĠC airo +éĻį ä»· +ĠArch ived +v ir +_in ode +ĠInter views +ĠTor ah +DO CTYPE +Ġabsorb ing +M ort +ĠC yp +act ed +天 é¹ħ +çķĻ åŃĺ +ï¼Įä¸Ģ ä¼ļåĦ¿ +: not +æĽ´ éĢĤåIJĪ +" æĺ¯ +ï¼ĮæĪij 认为 +éĢī ç§Ģ +Ġsn akes +AD S +ä¸Ģå¦Ĥ æĹ¢å¾Ģ +æģĴ 温 +z an +Ġdef icient +ĠSupp lements +ĠComp letion +al ism +åıij ç»Ļ +ĠO M +è¾¹ æ¡Ĩ +ĠM AR +å¢ĥ åľ° +Ġ第äºĮ 天 +al ion +ĠCar rier +æ²ī çĿ¡ +éĺ´ æĢ§ += k +ä¹ĭ åħī +她 èĩªå·± +uy en +CA SE +天 é¾Ļ +Ġ åĪļ +ä½ĵçݰ åĩº +Ġmind ed +or is +诺 è´Ŀå°Ķ +ä¸įéĶĻçļĦ éĢīæĭ© +çĽĺ çĤ¹ +f ers +Ġsupplement ation +å±± æ´ŀ +æīĵ ä¸ĭ +K elly +t okens +çªĴ æģ¯ +å¯Ĩå¯Ĩ 麻麻 +om at +åĽ½æľī èµĦ产 +Ġrec v +éĽª å±± +Man ual +é»ijé¾Ļæ±Ł çľģ +ç»§æī¿ 人 +ĠRivers ide +.starts With +Ġstream lined +éĩij èī²çļĦ +Ġroad map +æľīä¸Ģ æĿ¡ +Ġarr anging +缤 纷 +ak ra +åģľ æ»ŀ +åĽº æĢģ +ĠAl erts +ä»ĺ åĩºäºĨ +met rics +ĠB acon +og h +_B UILD +èħ¿ ä¸Ĭ +contin uous +ï¼Įä»ĸ è¦ģ +ä¹¾ éļĨ +" => +幸ç¦ı æĦŁ +/v nd +Ġterr ified +~ $ +éĻį èIJ½ +åģļ äºĨä¸Ģ个 +å®ŀè·µ æ´»åĬ¨ +åŃ©åŃIJ 们çļĦ +At omic +OR AGE +çļĦ å·¥åħ· +Ġdep rivation +ĠRol ler +ä¸ĵ 线 +Ġprim ers +ocr ats +ĠBlock s +ĠSl ide +ĠMax im +Ġturb ulent +ov ine +ĠEn ough +Ġch ampagne +ad ol +Ġhair s +åİĭ ç´§ +ï¼Į æĬķèµĦèĢħ +æĥĬ éĨĴ +å±¥ åİĨ +++ ; +mark er +ip age +çļĦ ç»Ħç»ĩ +ç»´ åħĭ +Ġclar ified +( IS +Ġover see +ĠO A +Ġdis astrous +.F ields +ig id +ï¼ļ å°ı +ĠS ear +ĠJoh annes +åĽŀ çļĦ +ĠRespons ibility +Ġhom osexual +Ġbak ery +âĢľ ä½łä»¬ +æĪij ä»İ +Ġper ipher +¿ ÃIJ +容æĺĵ 被 +Ġrefin ement +Ġindisp ensable +åıijæĮ¥ äºĨ +-l ived +op or +æŀľ åŃIJ +Ġfile path +: text +ï¼Į æĮĩ导 +ä¸ĩ å²ģ +åįİ åĮĹ +é»ij äºĨ +æĺ¾ç¤º åĩº +.con nection +amp aign +ä¸Ģ 家人 +Ġinconven ience +ãĢĤ åĪĿ +çĭĤ 欢 +Ġcommercial s +Ġpl ung +man agement +. Info +ï¼ħ ãĢģ +åħļåı² åŃ¦ä¹łæķĻèĤ² +ï¼Į æĭį +_b ottom +ĠFar mer +Dep recated +ĠStock holm +为 ä¼ģä¸ļ +è « +Ġb our +.c fg +Ġsl aughter +Ġmut ex +ĠH OME +ak in +ĠProv ided +Ġreck less +/ status +-t ra +ĠTib et +ï¼Į äºĭå®ŀä¸Ĭ +ry an +åİ» åĵªéĩĮ +rit t +Ġkid neys +Ġpione ering +æīĵ éĢļ +ĠM ick +Need ed +åij³ ç²¾ +Ġweb inars +Ġë Ĥ +ĠH IGH +; amp +ĠSuper visor +$ ^{- +Ġwh irl +ĠF ORE +System s +æĪij è¿Ļ个 +çĥŃ æ°Ķ +λ ο +é£İæĻ¯ åĮº +ĠChurch ill +åºĶæĶ¶ 款项 +, ä¸ĭéĿ¢ +ĠF ra +_DE C +éĿ¢å¯¹ éĿ¢ +ä¼į å¾· +åĬł æĪIJ +æĥ ¦ +å±ŀ æĢ§çļĦ +< N +éĥ½ åºĶ该 +- platform +.c md +(C ONFIG +å¦Ĥæŀľ æĤ¨ +æĭĽ æĥ¹ +Ġinhib its +Ġα ÏĢ +ï¼ĮèĢĮ éĿŀ +ç´¢ å°¼ +Servlet Request +ĠRed is +ĠS uddenly +é«ĺ å°ļ +Ġmand ates +Ġm ong +ĠV oy +çģµ çļĦ +Ġfilmm aker +ç¥ Ł +AT AL +çι çι +Ġchampions hips +ap ro +Ġeconom ist +äºĨåĩł ä¸ĭ +èŀ Ĥ +Ġpriv at +ãĢĤåı¯ä»¥ 说 +w f +ãĢģ æľ± +ind ividual +éĺ³ æĺİ +æ±ł å¡ĺ +æ¡Į ä¸ĬçļĦ +ï½ ģ +st uff +ï¼Į æĸŃ +···· ···· +è¡£ è¡« +ĠBO OK +b ys +Ġt idal +æĬĢæľ¯ åĪĽæĸ° +prof essional +C Y +H um +R W +è¿Ļ ç¬Ķ +Ġinter course +ç§ijæĬĢ çļĦ +ĠBook ing +说 ä¸įåĩº +H Q +åIJĥ åĸĿ +Ġ å®ļ +_AT T +ĠWR ITE +Ġun paralleled +ĠIn structor += normal +æĺĤ è´µ +ä¸Ģ éľĩ +æĪij æĢİä¹Ī +ï¼Į没æľī ä»»ä½ķ +åıijæĺİ åĨħ容 +reg istered +Ġe ve +_pack age +Ġghost s +ï¼Į è½»æĿ¾ +çĶŁæĢģ ç³»ç»Ł +Ġreb els +å©· å©· +Japan ese +Ġ 缸åħ³ +çĨŁ äºº +tr ade +Ġg az +æķ´ æµģ +触 碰 +ç»Ħç»ĩ å¼Ģå±ķ +_y ear +ĠTrust ee +åħ¬ 竳 +lu or +ä¹ĭ å¤ľ +ãĢģ è´Łè´£ +pl ots +ĠCON ST +äºĨ æķ´ä¸ª +ä½³ çļĦ +åıijè¡Į 人çļĦ +éªļ æī° +M ETHOD +ĠB ET +模åĿĹ çļĦ +Ġett ä +mm ol +对 æĤ¨ +Ġsn ug +,\ ,\ +Ġlon eliness +Ġpo ets +Ġer upt +cl inical +ĠRespond ent +: int +ä¹ĭ ä¸į +Ġaud its +ä¿¡ç͍ é£İéĻ© +çļĦåıij çĹħ +ï¼Ł ï¼ģâĢĿ +Ġcour tyard +积 èĵĦ +-p arent +.find ViewById +è§Ħ竳 åĪ¶åº¦ +ers et +con tr +- url +Ġfull est +ä¸ī äºļ +æİĴåIJį 第 +Ġloud ly +Log ical +åIJĥ äºĨä¸Ģ +Ġlod ging +oc ab +.nd array +çIJĥéĺŁ çļĦ +ht on +头 æĿ¥ +ä¹Ł ä¸įè¿ĩ +b ounds +ren ched +é̼ è¿« +ĠL ov +è·Ł èĩªå·± +ï¼Į å¾·åĽ½ +好 è¿IJ +åıijçݰ èĩªå·±çļĦ +Ġimp lying +_ role +Ġan ts +ĠHug o +大 éħĴåºĹ +Ġuseful ness +Ġfl ap +.C ustom +æıŃ éľ² +ĠInter action +è¡Ģ èĦĤ +ĠæĪij æĥ³ +ä¸į èĢIJçĥ¦ +: k +static method +éĥ½ å·² +âĢĶ or +é Ĭ +æĢ» åħ¬åı¸ +вÐĤ TM +Ġ èµĦ产 +Ġin let +主 è½´ +ä¹ĭ ä¸ĬçļĦ +App ro +m iah +ä¸İ èĩªå·± +Ġpip elines +lem n +è¾ħ导 åijĺ +å»¶ å®ī +ä¸į 说è¯Ŀ +æıIJ çĿĢ +y ahoo +âĢľ 对 +ĠL uk +Ġheart beat +Ġring tones +Emp loyment +å© ķ +-n ext +v ac +Ġmot to +ï¼ĮæŃ£ å¦Ĥ +对åħ¶ è¿Ľè¡Į +ĠConc ord +Tri angle +Ġret iring +Ġman ic +管çIJĨ 人 +Par is +orm an +-app roved +/ Table +æĬ¢ åħĪ +_ help +ĠState ments +OB J +Ob ama +æ³ ¾ +å®ł çα +åIJĥ ä¸į +çļĦ人 æĺ¯ +ç͵ç£ģ éĺĢ +ĠWe eks +ĠGreat est +ĠM uk +ï¼Į åĵĪåĵĪ +Ġide ological +åĨ° æ·ĩæ·ĭ +m ary +ä¹ħ ä¹ħ +F ET +çľĭ å®Ī +ä¸ī 代 +ĠDomin ican +ĠP PP +T am +Ġp ess +ç¬Ķ çĶ» +x o +Ġbench marks +å°± è·ij +ï¼Įå°± æľī +cl oses +qu ist +è¿Ļ个 女人 +Ġded uce +Ġtranscription al +âĢĻ : +ãĢĤ 注æĦı +æī§ æķĻ +Ġm anga +ĠAl ibaba +ĠMem or +Ġdeterior ation +ag ements +Dis cuss +æ¯ĶåĪ© æĹ¶ +Ġel ic +/ default +se parator +éĤ£ 两个 +N at +ãĢĤ ) +th ouse +å¤ļ åĪ©äºļ +æīĵ åĬ¨ +è¥Ħ éĺ³ +ĠVern on +Ġra pport +ĠLa undry +, å¼Ģ +åIJ¸ æ°Ķ +Ġdist ort +Ġhead set +æľī åħ³ç³» +ien ne +缴 çļĦ +主è¦ģ 以 +ĠDel uxe +ĠAl arm +,让 æĪij们 +w orm +as uring +æķ°æį® å¤ĦçIJĨ +_det ail +é¡¹çĽ® ä¸Ń +Ġ ï¿¥ +im inary +h man +ãĢģ ä¼ļè®® +çĬ¯ è§Ħ +人群 ä¸Ń +顽 强 +çĿĢ ä»Ģä¹Ī +OLD ER +Ġintimid ating +other mal +Ġi os +Ġinflu encers +çŃī åİŁåĽł +Ch allenge +Ġst itches +æĿ¥ ç¡®å®ļ +Ġre visit +af ety +ĠM MA +ä¾ Ĩ +ï¼Į æĬ¬å¤´ +: NS +åıĮæĸ¹ çļĦ +-n umber +æīĭ èīº +ĠCast ro +Ġsh ores +_t s +ĠPa ula +Ġdetect s +ä¸İæīĢè¿° 第ä¸Ģ +_t ests +Background Color +Ġshut ter +åŃ ļ +èµĽ çļĦ +æľ¨ åľ°æĿ¿ +Dll Import +, W +Ġ! $ +æľª åħį +ĠH els +LO L +ãĢģ è½» +ï¼Į æıIJåīį +Ġsocial ist +åĬłåħ¥ åΰ +ĠManu el +çĸ ± +éĺ² ç©º +çIJĨ论 åĴĮ +.to LowerCase +ãĢĤ è¿ĩ +ç³»åĪĹ çļĦ + ¹ +aw esome +éľ² 天 +ç¨ĭåºı åijĺ +Prot otype +ĠBe au +Ġundes irable +) {\ +ï¼Į 毫æĹł +åľ¨ è¿ĻäºĽ +ï¼Į转 è½½ +amb i +leg acy +ç¿ Ĭ +ide press +åµĮåħ¥ å¼ı +ĠTra v +ul ant +ĠHans en +è¡ĮæĶ¿ åĮº +. rm +Ġ å¾· +ä¸ĸçķĮ åIJĦåľ° +åľ° åĿª +Ġra pper +ãĢĤæľī æĹ¶åĢĻ +Ġs aint +Ġann ih +ib ia +Ġw edge +s aid +ä¸Ķ åħ¶ +åģĩ åĨĴ +ĠM itch +As pect +éĶ» éĢł +Ġ çĤ¹ +ãĢĤ ä½łçļĦ +ic ast +ãĢĤ åŃĻ +èĢĮ åħ¥ +è°ĥ åīĤ +re peat +Ġpersecut ion +, '' +` ]( +Bre aking +Ġres umed +_t imes +yn ec +B ib +èᝠçī©çļĦ +_end point +Ġtrans p +èIJ§ æĻ¨ +ï¼Į æĸ¯ +æĪIJäºĨ ä¸Ģ个 +大 åı£ +èĬĤ缮 ä¸Ń +LOC ATION +sh irt +Ġfix ation +åīĬ åĩı +Ġdocument ing +_ Error +ar f +æ°´ éĩĮ +_c m +ĠO maha +.get Item +éĢł 纸 +ĠAg ile +Ġcheer ful +ãĢĤ åĽ½å®¶ +å·¨ åĵį +am age +Ass istant +ĠAuthor ization +ãĢģ çµģ +ud p +ĠJ R +com ings +æĹł å¿ĥ +åħ« ä¹Ŀ +.en viron +ï¼Į è´¹ +ter ror +ãĢģ ç»ı +å¹´ èİ· +Ġweaken ed +ck e +og el +ï¼Įåıªè¦ģ ä½ł +çļ® è´¨ +_in valid +Ġв Ñĭ +ï¼Įçī¹åĪ« æĺ¯åľ¨ +æĹł 害 +Ġaf rica +, èĩ³å°ij +èĥ½ å°Ĩ +ç¾İ å¾· +.p art +,ä¸Ģ è¾¹ +ĠJack et +ĠHP V +åΰäºĨ ä¸Ģ个 +ĠT emporary +Emer gency +ĠXCTAssert Equal +éĩĩ æļĸ +Ġend ured +ĠConst raint +is in +ic her +åĩº ä»» +æIJľ çĭIJ +.col lect +ç²ĺ æİ¥ +Ġsun rise +IN ES +ĠMar ian +-w rapper +Ġc uda +Ġf olds +Ġair way +éĹ® åį· +ä¸Ģ åĽŀäºĭ +è½® çļĦ +Ġfed er +S PE +Ġreconstruct ed +åĽł åħ¶ +æĿ¥ è¢Ń +ĠPost al +åĩĿ èĥ¶ +Ġs ont +Ġserial izer +èħ° 带 +mean ing +ï¼Įæ·± åıĹ +ĠJo ey +ĠDO I +Week ly +ĠMcK in +AT P +Ġfiles ystem +ĠNord ic +Ġt apes +Jon athan +ä¼ĺæĥł åΏ +ĠEn cyclopedia +Ġ$ ('. +ĠAut ism +, åĪ©ç͍ +Ġs ap +Ġe ct +è§£åĨ³ çļĦ +( com +西 åŁŁ +Ġloc ating +Vers ions +- cal +ãĢĤ æ¸ħ +Ġtool tip +åĪĽéĢł åĬĽ +çĶ º +ç§» éϤ +æķij 人 +ĠSN P +ĠS ang +è®¾ç½®åľ¨ æīĢè¿° +åΰ åĮ»éĻ¢ +çľģ çķ¥ +æĤ£èĢħ åľ¨ +ï¼Įå¾Ī æĺ¯ +Ġb illed +(h ash +åħ¨ æĿij +äºĨ好 åĩł +arch ar +éĿ¢ æĹłè¡¨æĥħ +Ġopt ic +ĠContract ors +ĠM ald +éĵ¶ èī² +Ġdet ach +溶 æĢ§ +< table +ĠAtt ention +-sh ow +å°± ç͍ +æĭ¿ åĩºä¸Ģ +Ġ" ; +éĤ£ä¹Ī 大 +Ġaggreg ates +un used +See k +Ġprice y +Ġas bestos +æīĢ åģļçļĦ +Ġæĺ¯ çļĦ +. Integer +es a +ãĢģ ç»´çĶŁç´ł +ĠSh awn +åıĹåΰ å½±åĵį +éĩĩ 纳 +ãĢĤ 游æĪı +Ġ ä½łä»¬ +æ¼Ķ åĮĸ +f und +Ù ij +çļĦ è§Ĩé¢ij +PA RE +Prem ise +ed is +Ġy aml +if lower +Ġbund led +Ġdisrupt ed +ain ting +ĠPhys ician +çļĦ äºĮ +çļĦ è¶ħ +åĪĻ åľ¨ +ĠPr ague +ĠP LC +æŃ£ åĵģ +Out line +ass a +çļĦ çŁ³ +责任 æĦŁ +å£ģ çĶ» +Ġj erk +ade on +Ġpoly g +宿 主 +B oss +çĵ¦ å°Ķ +, çªģçĦ¶ +ĠS CI +ĠL t +Op acity +åĴĮ ç²¾ç¥ŀ +ä¿® 身 +ĠPra irie +Ġdoll s +ling er +èĩªçĦ¶ èĢĮ +å°Ĩ ä»İ +ï¼Į äºĴ缸 +ĠF olk +Ġsk ating +ĠRes idents +uck ets +壮 è§Ĥ +Ġprot otypes +ĠLe icester +Ġinf used +Ġa eros +ĠThrow able +Cli ents +S even +Property Changed +ĠP sy +Ġdi ag +mark ed +Ġ" ] +Ġhash Code +便 æ°ij +çļĦ人 åľ¨ +Ġ æİ¥çĿĢ +ä½Ľ æ³ķ +æ±ł å®Ľ +est yles +. qu +为 缮çļĦ +per formance +opath ic +ĠK ang +å·¥ç¨ĭ åѦéĻ¢ +æĬĹ æ°§åĮĸ +Ġr ag +åĸ ³ +-not ch +it en +Ġloos ely +认å®ļ 为 +Ġr f +Ġal arms +Ġout ing +æĹł åĬ© +ĠEurope ans +Ġcorrupt ed +P ose +çIJ ° +ä¸į 计 +ï¼Į 设置 +享 ç͍ +æijĩ æ»ļ +ff ee +it ious +åīį åĩłå¤© +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +对 大家 +Ġcare t +好 çľĭçļĦ +ĠS word +å¦Ī åĴª +æĺ¯ å±ŀäºİ +.s lf +ĠRes ident +ĠC ubs +W ARNING +ĠIll uminate +_ require +m eth +. ge +D ash +uck le +é«ĺæķĪ çļĦ +Ġpled ged +b aby +ï¼ģ æīĢ以 +Sh aring +UN K +ä¸İ ä¼ļ +Ġ åĩı +ä¼ģ äºĭä¸ļåįķä½į +Ġflour ish +ight ed +çݰ代 åĮĸçļĦ +Ġbath ing +æ°¢ æ°§åĮĸ +åħij çݰ +G lass +ç«ĭ 项 +éĴĪ çģ¸ +è¡ĮæĶ¿ éĥ¨éŨ +ĠElect ro +èį¯çī© æ²»çĸĹ +å¤įåIJĪ æĿIJæĸĻ +her ing +ipe g +: t +Ġarbit rarily +ä¹Ļ éħ¸ +åŃŁ åŃIJ +ë¦ ¬ +b right +, ä¿Ŀè¯ģ +åĬł çĤ¹ +Ġknow ingly +å±Ĥ次 çļĦ +_H ASH +å®£ä¼ł éĥ¨ +éĵ¶ è¡Įä¸ļ +Trad itional +he arted +æį ¶ +ĠC ottage +ac ional +å°±æĺ¯ ä½ł +ç²¾ ç¾İçļĦ +Ġcruel ty +Ġà ħ +ĠPrint able +ï¼Ł ä¸į +å·¡ æĬļ +æľĪ çĶŁ +å±± åĿ¡ +_f ill +ĠC openhagen +A men +ãĢģ ä¸įåIJĮ +ï¼Ī C +Ġbutter flies +T umblr +æŃ£ å¤Ħäºİ +_ex port +Typ ed +ï¼Į æĺİæĺ¾ +Ġboost s +çīĮ çļĦ +Ġfront ier +r ush +ĠInt ellectual +åħ¬ 约 +ï¼Įä¸Ģ éĺµ +No ise +èĻ« 害 +Ġ$ |\ +, æľī人 +as an +ĠUnder ground +" fmt +è¿ij å¹´ +Ġa an +åįĹ ä¸ĭ +é¢Ĩ 主 +by ter +Ġb umps +ag ara +ä¼ļ åĴĮ +Ġhigh ways +ull en +ĠEmploy er +ï¼Į 书 +çļĦ åľºæĻ¯ +R od +çŁ ľ +Ġmeth ane +on acci +åıĸ æļĸ +æł· æĿ¿ +ĠGu ate +ĠD ET +ĠTechn ician +. errors +åħ¬ åĪĨ +ãĢį , +Ġd yst +çļĦ çĬ¶åĨµ +ĠA uss +Ġeffic iencies +ç¾ ¿ +åİļ åİļçļĦ +met al +Ġmir acles +Ġster il +du ce +ç͵ èį· +æĬµ åζ +\] ), +ĠD ob +è¸ Ĭ +åħ¨ è¿ĩç¨ĭ +æķĮ æĸ¹ +ï¼Į æĢİ +æĪij åĨį +åĬĽ äºī +Port al +Ġmon keys +å·²ç»ı 没æľī +å°Ŀ å°Ŀ +åĬł éĢŁåº¦ +Set ter +g ements +Ġl ia +ï¼Ł ä»ĸ们 +æĶ¯ æ°Ķ管 +Ġbe ad +ĠA DA +åĨĽ å·¥ +inst ead +ĠBrun swick +Ġanomal ies +ï¼Į çĩķ +åįĹ京 å¸Ĥ +ĠPent agon +å±± å³° +群 ä½ĵçļĦ +身 æīĭ +-ac re +ï¼ĮéĤ£ æĹ¶åĢĻ +ĠHel ps +çIJĨ çļĦ +æĭī å¾· +è¿Ŀ 纪 +çŃī 离åŃIJ +Ġm apper +_s ite +An alyzer +.e q +Ġsuck ed +å¾ ³ +-m ount +ç«Ļåľ¨ éĤ£éĩĮ +åħī çĽĺ +Ġdetermin ants +ĠMin eral +Can adian +. SE +Ġh an +scrib ed +çϽ çϽ +PL IC +.s chema +çĪ » +Ġag ility +(d est +Ġsl ap +Ch o +éħį ä¸Ĭ +èµŀ æī¬ +ا ÛĮ +Ġhes itant +OTT OM +æ³ķ æ¡Ī +Ġwe bs +D Y +çĤ¹ ä½į +File System +çļĦ 设å¤ĩ +ï¼ĮåıĪ èĥ½ +Ġjur ors +.be ans +_ OVER +( create +å¾ģ æĪĺ +主 å®° +è´¢åĬ¡æĬ¥è¡¨ éĻĦ注 +Ġfound ational +缸 符 +Ġclo ves +éĤ£ åĩłä¸ª +Th umb +æµĭ ç»ĺ +.log in +ćć ï¼Į +so ap +åįĩ åįİ +æĭĸ æĭī +åİ¿ æĶ¿åºľ +ach a +ãĢģ çłĶç©¶ +Ġcons oles +arm esan +éĹŃ åĺ´ +åıĤä¸İ äºĨ +Tool StripMenuItem +z k +pr ay +ĠN N +Ġcompet encies +- others +Ġ æĺĵ +éĨī äºĨ +ĠD AT +Ġh ates +è¿ĺ ä¸įèĥ½ +ĠSw im +çŁ¥éģĵ 她 +éĻ© äºĽ +.word press +åĩł åı¥è¯Ŀ +æľ« æĹ¥ +Ġsil ica +_text ure +C atch +\ quad +Ð ¢ +ro pped +Ġtransport ing +\ Core +,å¹¶ åľ¨ +Ġflow ering +äºĮåįģ åħ« +åį° ç«ł +Ġhum orous +R everse +å¦Ĥæŀľ æľī +y aml +çϽ éĽª +Ġlav ender +转 çĽĺ +Ġdiss olution +ä½Ľç½Ĺ伦 èIJ¨ +å¹´ åĴĮ +è¤ Ĵ +æĺ¯ 缮åīį +å¹² äºĭ +èĤī çľ¼ +Ġng x +Ġex its +åĨħ容 åĴĮ +ĠH utch +the l +it he +çŃ ł +åĬ³ ç´¯ +çĥŁ çģ« +ol ip +æį¢ åıĸ +im ulation +. Resources +Out door +_pro p +a ude +c ms +Ġre pr +å®ŀ å®ŀåľ¨ +gre SQL +ï¼ģ ä½łä»¬ +å§IJ 夫 +Draw ing +.Act ive +_ST ACK +ĠH ank +çĸ«æĥħ å½±åĵį +è¯ ² +æľįåĬ¡ åķĨ +per mission +ĠPas o +é£Ł æĮĩ +_u uid +ï¼Į 说è¯Ŀ +=" , +null able +ĠF etch +为 æľ¬åıijæĺİ +iment o +_var iables +, ä¹ĭåIJİ +罪 åIJį +ĠAbd ul +Dis ney +ï¼ĮæĪij æľī +ä¼ł åΰ +Ġfind ViewById +L emma +pec ified +.Debug ger +Ð Ķ +å°± æľīäºĨ +\ ! +å°Ĩ æľī +_c r +-qu arter +ç«Ļ åĩºæĿ¥ +ĠB oh +âĢĿ çļĦä¸Ģ声 +éĴ» çłĶ +L atin +om ology +Ad visor +но ÑģÑĤ +ãĢģ æĿIJæĸĻ +Ġl aps +ï¼Į éĢıè¿ĩ +åħĭ ç½Ĺ +Ġ ä»Ĭå¹´ +_int eger +åĨ° åĨ·çļĦ +çĤ º +é¸ ¥ +acc arat +Ġ åºıåı· +ãĢĤ åıĬ +ãĢĤ å·² +ĠRE VIEW +ç»Ĩ åĮĸ +ĠWh is +, åħ¨åĽ½ +RE ST +ä¸Ń éĢĶ +âķIJâķIJ âķIJâķIJ +$ result +Ġtra verse +ĠPaul o +Ġì ł +ĠMus cle +Ess ential +. aws +ï¼Į 声 +th umb +-d ark +åĮ ® +骨 é«ĵ +.int o +Ġl umber +Ġcon gru +not ice +orpor ated +ĠChron icle +ĠR unnable +.S ystem +-p resent +Ġrest raint +oc os +.S ave +NS Array +泡 泡 +ãĢģ ç²¾ç¥ŀ +好 åĩłä¸ª +åĨ² åİĭ +ä»İ åĵªéĩĮ +Int ro +è¯ŃéŁ³ è¯ĨåĪ« +( io +Ġra v +ĠI o +åİŁæĿ¥ æĺ¯ +Ġspac etime +Ġs ings +æĢ Ĥ +aren thood +, 红 +ĠPh arma +-e lement +ï¼Į åŁº +ĠT aste +Ġeffort less +(b atch +Ġ çİī +op rotein +ime Type +ĠK O +ĠClay ton +çĦ¶å¤§ æĤŁ +ï¼Į åijĬè¯ī +Ġdisp ers +g od +iw i +Ġst arch +å½ · +幸 åŃĺ +æıŃ å¼Ģ +çķ¥ å¸¦ +æīĵ æĸŃäºĨ +Ġ æıIJä¾Ľ +ur is +Ġas ymmetric +åĪĨ æł¡ +ĠRe ception +ĠArch ae +V K +Ġ åį« +ĠS UN +og ly +被 ä½ł +.A cc +me ch +Ġradio active +çĶŁæ°Ķ äºĨ +uk kit +åıĽ éĢĨ +Ġapp ended +Ġshred ded +U l +辩 è¯ģ +æħĮ å¿Ļ +éĥ ¸ +its u +ï¼Įéļı 便 +ãģĦ ãģŁ +n ets +s an +ï¼ĮæĪij å¾Ī +ĠOut standing +ĠConnect ions +æĺ¼ å¤ľ +ĠP itch +å·²ç»ı ä¸į +åĽ¾ æĸ¯ +hel m +Ġk ernels +Buy ing +åı¯éĢī åľ° +å¾Ī çŁŃ +- interest +ĠS abb +ire n +_ required +Ġpo ised +Ġactiv ating +æĿ¥ å®ĮæĪIJ +ĠWare house +çļĦ è¡ĮåĬ¨ +ãĢģ ä»·æł¼ +éĤ» è¿ij +å¼Ģ æŀª +Ġbro ccoli +Ġvel vet +ĠB race +åĴĮ åĪĺ +æĹł çĹĩçĬ¶ +忽 æĤł +C X +" ä¸ī +ï¼Į æķĻå¸Ī +åįģåĽĽ æĿ¡ +ĠEc ology +Ġmyth ology +ĠGriff ith +ç½ij åIJ§ +ðŁ ĩ +ĠL indsay +ĠN arr +çļĦ è¿ĺæĺ¯ +ĠÐ ļ +Ġphys ique +ï¼Į ç«ĭ马 +Ġsk learn +Ġovers ized +Prem ium +els ius +è±Ĩ æµĨ +re rs +åĭ¾ åĭĴ +Ġnurt uring +v f +åĩº åįĸ +ĠPs alm +ãĢģ èģļ +-pro perty +Ġprogn ostic +ĠAr bor +åı° ä¸ĭ +Ġgrand son +Ġplug ged +im et +Ġav enue +çīµ æī¯ +_VAL ID +Ġsubsid iaries +/ class +ang ible +CON DS +Ġsucceed s +åıijè¾¾ åĽ½å®¶ +ĠJ J +åĩ¡ æĺ¯ +ç¿° æŀĹ +Ġmor bidity +, 许å¤ļ +åĽ¢ åijĺ +Ġh s +Ġu c +çļĦ åı¦ä¸Ģ +çĥ ¬ +ĠNot tingham +éĶ¥ å½¢ +Ġsal ts +K aren +ï¼Į çΏçΏ +æį¢çĥŃ åύ +Ġb d +_T YPES +ĠJohn ston +Ġselect ively +Ġpunct uation +R og +ĠP U +est rian +æĺİ åªļ +ĠCar rie +ï¼Įä½ł éľĢè¦ģ +Ġphilos opher +. ph +P ods +w ant +为 空 +· åį¡ +ĠH iring +\ b +ĠD ATE +ĠJuda ism +å±ŀ ä¸ĭ +PK G +ole on +Ġmis ery +Ġplain ly +æĭ¦ ä½ı +ĠRes orts +Ġcompar atively +\ Http +ä¹Ł æ¯Ķ +Ġ å¦ĤæŃ¤ +åľ° 段 +Ġden ies +ä»ĸ æľī +_C URRENT +绿 èĮ¶ +ãĢģ æĢ» +åģ¥åº· åıijå±ķ +ï¼Įç¥ŀ èī² +ï¼Į æ²»çĸĹ +ĠP CA +è´¢ ç¨İ +F Y +ĠT WO +çī§ å¸Ī +ï¼Į åݻ年 +ãĢģ éĵľ +èĤ¡ä¸ľ æĿĥçĽĬ +代表 åĽ¢ +S amsung +T p +\ }\ +ĠTher mal +Ġubiquit ous +Ġtuber culosis +两 å¼ł +.d ispatch +CR C +S av +RO DUCTION +T reatment +Ġe agle +å¤ļ å²ģ +æľĢ ç¾İçļĦ +缸äºĴ ä½ľç͍ +两 éĥ¨åĪĨ +æ¸ħ äºĨ +Ġnumer ically +æµĵ åİļçļĦ +Ġp inned +ĠR ally +Ġmix tures +Ġstair case +ĠC indy +åĢºæĿĥ 人 +( conf +g f +D Q +æ·± æ²ī +èĩª æĪijçļĦ +满 æĢĢ +ï¼ļ æľī +ĠPri est +ï¼Įè¿ĺ 羣 +.F loat +åĪº æĿĢ +ç͵ æĦŁ +ar x +.com mit +. Vector +两 çľ¼ +ek ing +works pace +Ġju icy +ĠBrun o +Ġrenov ations +, åıĹ +App lic +< v +Sk ills +ĠStef an +ï¼Į é¦Ļ港 +Ġquir ky +Th ought +m atically +Ġpersonal ised +utter ing +pe ace +Ġe z +ri j +æĮģ ä»ĵ +ç£ģ éĵģ +Ġenv y +ĠMake up +Mon o +H ouston +åħĪ å°Ĩ +ĠSPD X +Ġper cept +Ġunivers ally +车 ä½į +( iter +Ġhor rific +æĪĸ åħ¶ +ĠMet rics +))/( (- +æĬķ 篮 +Fund ing +$ a +t ables +èĦij è¡Ģ管 +fil ters +Ġwhites pace +, æĿ¨ +大 åıĺ +ced ent +ĠWill ow +ol ta +Ġdecl ar +Ġe ch +sh i +Ġarg parse +B ern +/ de +ä¹Ł è§īå¾Ĺ +ĠSt arter +OR TH +Ġoper ative +åģļ çĶŁæĦı +ï¼Įæīĭ ä¸Ń +èªĵ è¨Ģ +å¿ĥ æĦ¿ +Ġes ac +_d ot +IM S +ï¼ļ æĮĩ +åĮĹ æŀģ +çĶ· åŃ©åŃIJ +ad ir +Ġst aggering +Ġc older +åĸ· æ´Ĵ +^ j +ee red +åıijè¨Ģ 人 +- ons +ult an +举 æīĭ +âĢľ No +çļĦ ç»ıåİĨ +ĠMe al +大 æĺİ +åįģè¶³ çļĦ +Ġspec ulative +'] ; +å¼ł æŁIJ +èĭ¥ æľī +-reg ulated +ĠSchw artz +ãĢģ çģ« +, å¹´ +cer pt +æ¯į å©´ +ĠT ul +eg g +ĠMan ifest +æİ¥ 管 +ĠTool kit +Ġs ack +çīµ çĿĢ +çŃī æľįåĬ¡ +rav o +Ø · +交 çķĮ +è¿Ļ个 æ¶Īæģ¯ +æ´Ĺ èĦ¸ +Comp anies +è§ĦåĪĴ åĴĮ +æ·± å±Ĥ +-d irected +G ary +ĠEx posure +åªĴä½ĵ çļĦ +P OL +Ġwor ding +R ol +ĠSpec ifies +è¿ĩ ä»ĸ +ä¸į åĮħæĭ¬ +.h ide +_D IRECT +çĹ £ +asion ally +黼 çİī +ä¾Ľ æļĸ +ï¼ĮæĹł æķ° +Ġv u +Ġcur ly +Ġemb roidery +ï¼ĮæīĢæľī 人éĥ½ +éĤ£ 次 +ãĢĤ ä¸įçŁ¥éģĵ +ãĢģ ä¿ĥè¿Ľ +ĠLev i +ĠTurb o +éĢĿ ä¸ĸ +ï¼Į ç¦ı +Ġpor celain +æĸ ĵ +æĿ¡ 纹 +tri angle +æĪijçļĦ è¯Ŀ +æ³Ľ èµ· +y ang +ĠSure ly +ê³ ł +.m atrix +, åįĹ +代表 æĢ§ +ï¼Įåį³ä½¿ æĺ¯ +Ġtar iffs +cho ices +Ġsign age +.sc ene +oment um +Le an +奥 åľ°åĪ© +Ġendeav ors +- On +æµ· è´¼ +Rend ering +ĠLag os +误导 æĢ§ +vis ited +ĠTh rive +åĽĽ ä½į +ç²¾ çĽĬ +as ide +ĠB ey +ä½ł åºĶ该 +E scape +æļĤ è¡Į +ĠHuman ities +ism o +ĠCompl aint +ĠSpons or +çĶŁ çĶŁçļĦ +æĦŁ æµĭ +åIJĪåIJĮ çļĦ +ĠK L +Ġless en +åĽŀå®¶ äºĨ +åijIJ åĸĬ +Ġp endant +å®īæİĴ çļĦ +G RESS +端 æŃ£ +Ġfig ur +åıĹ害 èĢħ +m agic +æ¯ı ä¸Ģ天 +ï¼ĮåĽłä¸º 她 +åĨ¥ æĥ³ +_method s +åŃ¦ä¹ł äºĨ +Ġμ M +E ither +æĶ¶åħ¥ çļĦ +ah r +ç§ĺ è¯Ģ +ä¸ĥåħ« ç³Ł +F at +Ġcon gen +Ġfright ened +- XX +åĪļ èIJ½ +Ġhorm onal +æĤł çĦ¶ +人 社 +ãĢģ ç´« +ĠD V +çͱ æĿ¥ +ĠWonder ful +Ġfib robl +and atory +ĠJ ared +Ġrooft op +å®ıè§Ĥ ç»ıæµİ +æĪij åıªæĺ¯ +èĤ¯å®ļ çļĦ +Ġ# > +太 éĥİ +çļĦ大 åĬĽ +. IS +éĥ½ å¿ħé¡» +ä»İ æĪij +åĴĮ 第ä¸Ģ +ï¼ĮåĽłæŃ¤ åľ¨ +ĠEval uate +ï¼ĮæĢİä¹Ī ä¼ļ +äºĮåįģ äºĮ +åĪĨæķ° 线 +ĠG an +æķ¦ çħĮ +A O +çļĦ ç³»ç»Ł +ĠPros pect +åľŁåľ° 使ç͍æĿĥ +V ote +y z +_ auto +ĠSh oot +ãģĦ ãģ¦ +Ġbureau cr +ï¼Įåı¯ä»¥ 说æĺ¯ +Av atar +_B AD +ä¹ĭ æŀģ +Ġkiss ed +å¼Ģå¹ķ å¼ı +_ this +éĤ£ 头 +Indust rial +åįģ éĩĮ +Ġturn around +åľ¨äºĨ åľ°ä¸Ĭ +ĠSh irt +Graph ic +éľī ç´ł +Ġgra bs +Ġrebell ion +Ġhand held +ĠCa esar +åĬŀ äºĨ +Ġpur ported +ER P +ï¼ĮçĦ¶åIJİ å°± +ï¼Į ç¬ijçĿĢ +-ij ms +ï¼Ī x +P ager +Ġinter state +æĪij åĸľæ¬¢ +Ġcol span +r ather +åĪĨ äºĨ +ĠDec imal +" % +( on +ra bb +low ing +Ġbr ushed +æ¥ Ķ +/ ap +ï¼Į æķ£ +Ġd aring +éļı å¿ĥ +leg ation +Ġautom obiles +-f at +Ġpath ogenesis +Ġr pc +over lay +çIJĨ ç§ij +ï¼Į åĿļåĨ³ +Ġdiscrim inate +EST AMP +ĠSh ark +æĬļ æij¸ +Ġcorrect ness +åIJĪçIJĨ æĢ§ +ï¼Į é¢ľèī² +éļı é£İ +è¿Ļ 天 +Ġ ä¸įçŁ¥éģĵ +Ġm ailed +Ġo at +Ġdirect s +å¯Ĩ éĹŃ +æĥ¯ ä¾ĭ +ç쵿´» æĢ§ +æĺ¯éĿŀ常 éĩįè¦ģçļĦ +ï¼ī ãĢģãĢĬ +åıªèĥ½ åľ¨ +ir is +Ġpos ing +Ġdist orted +åĶ ° +Ġe f +ãĢĤ 红 +è¡Ĺ åĮº +ä»İæĿ¥ 没 +å¾ģ ä¿¡ +å³° ä¼ļ +]: = +æľī å¾Ī大 +str len +她 å°± +Ġh uh +respons ible +( with +b lood +ï¼ĮæĪij ä¸įä¼ļ +æķ´ å¥Ĺ +ĠBr as +Ġ' .' +_d uration +t ors +ĠBened ict +Ġproject or +_D IG +Activ ities +æĬĢæľ¯ åľ¨ +计ç®Ĺæľº åı¯è¯» +Il legal +çļĦ æ°´å¹³ +èĩª åζ +éĹªè¿ĩ ä¸Ģä¸Ŀ +ï¼Į åħħ满 +ãĢģ åĬłå¼º +Ġ( %) +ï¼Įä»ĸ çİ°åľ¨ +Ġbr unch +Ġhospital ized +_PRO PERTY +éħ¿ éħĴ +ĠLag rangian +E H +ĠD iesel +.c ancel +go al +Ġsmooth ing +ãĢģ æŃ¦ +éħ Ŀ +èĥ ¥ +èĴĻ å¾· +ĠD ip +_m essages +Ġjew el +) ï¼ļãĢĬ +ĠTele phone +ĠSp end +Ġcategor ical +å·¥ç¨ĭ çļĦ +Ġbal d +, 身ä½ĵ +è¿Ľè¡Į æ£ĢæŁ¥ +Is a +è¡Į éģĵ +cre st +ĠCoc onut +bs d +Ġnov ice +积累 äºĨ +Ġrobot ics +ĠDeb bie +åĴ§ åĺ´ +ans wered +Ġ è¶ħ +/ image +åĩº åİĤ +æ±Ł 举 +ä¹ħ ä¹ĭ +Ġconfront ation +ĠK NOW +@in proceedings +Pe ace +Ġt z +æĸ° ä¸ŃåĽ½ +çŀ Ł +Not ifications +_v olume +_k ind +Ġdisappe ars +æİ¢æµĭ åύ +ĠB ore +ãĥĥ ãĤ¯ +è´¹ çļĦ +el man +ç» Ľ +æľº ç¼ĺ +.Data Frame +ï¼Į åIJ¾ +éĺ³åħī ä¸ĭ +LE Y +å¾Ĺ æĦıçļĦ +urre t +两 æł¹ +ĠBe a +Ġlow s +.app lication +. att +ä½İ æ²ī +Ġcompl iments +Pack ages +ä¸ĭ èIJ½ +do ctor +Ġan atom +.column s +åĢ Ń +åĺ´ è¾¹ +åѦ士 åѦä½į +ĠM ing +Ġbranch ing +Ġsubpo ena +op ro +ï½ ľ +åŁİå¸Ĥ 建设 +æĹ¥ å¼Ģå§ĭ +Ġsustain ing +温æŁĶ çļĦ +ĠGameObject TPL +Ġst ing +Ġpart e +ĠUn ified +p dev +åŁºç¡Ģ çļĦ +Af rica +Ġ åįĥ +ff iti +æ±Ĥ å©ļ +äºĨè§£ çļĦ +好 象 +Requ ires +V endor +ä»ĸ æĥ³ +R oman +PS C +æ´Ľ ä¼Ĭ +éĹŃ ä¸ĬäºĨ +导 æµģ +à ¶ +å¾® åĪĽ +Ġemb ro +Ġpossess ing +P ASSWORD +_s ensor +åİļ éĩį +ä¿ĿæĬ¤ çļĦ +åIJŀ åIJIJ +_s imple +ĠFO X +ä½ı å¤Ħ +ä¹Ŀ å·ŀ +_ vertex +ä¸į è´Ł +âĢĿ åľ° +aut hent +åĸĤ åħ» +Ġcy an +çĽĪåĪ© èĥ½åĬĽ +ï¼Į ä¸ĭåįĪ +al ogy +åģļ 大 +е в +Z IP +}/ { +.mod ules +_m ul +Ġduplic ates +ï¼Į æ³¢ +Ġg ums +åĨĴ åĩº +ï¼ĮæĢİä¹Ī åı¯èĥ½ +éĢĢ æ¬¾ +C andidate +麻 å°Ĩ +Ġl ament +ĠPrep ared +ä¸į éĢı +åIJį åĪĹ +èĬĤ æ°Ķ +text area +ĠNE ED +æľī 帮åĬ© +åı¯ä»¥ æıIJé«ĺ +ï¼Į她 åľ¨ +ï¼ĮåĬł 大 +äºĶ èĬ± +çļĦ èĦijè¢ĭ +èľĤ çªĿ +Ġch ores +ĠPas cal +æģį çĦ¶å¤§æĤŁ +ĠSc andin +ï¼Ł è¿Ļæĺ¯ +æĥħåĨµ åĴĮ +.M od +ä¸Ń 对 +主 ä½ĵçļĦ +Ġpre ach +ut ing +ab ella +Ġsp ur +åħ¨ æł¡ +ĠTal ks +è¢ģ æĻĶ +v x +Ġl ure +ĠC auses +ĠL una +Ġfor ged +éĢļ éĢı +ä¸ĭ æĸ¹çļĦ +ys s +leg ant +ãĢģ åİ» +Ref lect +Ġ\ > +Mar shal +,ä¸į çĦ¶ +se ud +ĠJ C +æİ¨ å´ĩ +èı² å°Ķå¾· +å°ıå§IJ å§IJ +æĸĩ ä½ĵ +M g +.S ource +Ġarch ived +Ġhar b +ĠK eller +Ġhor izontally +ä½ł å·²ç»ı +_b ucket +æľįåĬ¡ åĴĮ +Ġtend encies +éĤ£ è¾¹çļĦ +计ç®Ĺ çļĦ +ĠTh y +pro g +æĹ© æľī +_s creen +çİĦ å¹» +elect ric +ik en +ç»ĵå©ļ äºĨ +ä½ł åı¯ +A wards +j ee +æ¯ı个 æľĪ +èħIJ çĥĤ +å¥ĩ èij© +Ġse gregation +Ġnot withstanding +çļĦ å½¢çĬ¶ +Address es +度 é«ĺ +ठ¤ +mel on +_ ORDER +鼶 鼶 +mar shaller +诡 å¼ĤçļĦ +Ġw ird +Ġdisappe arance +大 è±Ĩ +åºķ 端 +é¸ ³ +IB C +è¿ĩ ä¸Ģ个 +表 çļ® +ĠFlex ible +Ġp uff +Ġgroom ing +ĠT ire +ĠCS R +æīĵ 好 +ĠPers ons +ar ak +å°ı é±¼ +ä½ł å®¶ +ĠSt ones +æ½į åĿĬ +å¿ĥçģµ çļĦ +éĽª åĦ¿ +èĤļ åŃIJéĩĮ +åIJİæĸ¹ åı¯ +Ġg lands +ãĢģ èĥ½ +伤 çĹħ +ä¸į å̼ +yp ass +çĶ· 主è§Ĵ +ox o +ï¼Į ç©¿çĿĢ +áĥIJ áĥ +çļĦ åĪ¶ä½ľ +è° § +por a +å°±ä¼ļ æľī +çģĮ æľ¨ +ĠBor is +Ġopt ics +æĹ¥ åħĥ +ï¼Įéĥ½ åı¯ä»¥ +ãĢĤ 缸æ¯Ķ +ĠT ac +ĠTR ANS +ä¸Ģ åĪĨéĴŁ +Ġwhit ening +ĠO bl +Pat rick +% 以ä¸ĬçļĦ +æľ¨ é½IJ +å§ĵ æ°ı +Dist rict +åĩº 轨 +ภļ +Ġst ash +ï¼Į æ¶Īè´¹èĢħ +_s witch +åľ¨ 被 +ous se +ç»§ç»Ń 说éģĵ +æ¯ıèĤ¡ æĶ¶çĽĬ +ãĢĤ åĮĹ京 +çº Ĥ +åĨĽ è®Ń + Ĵ +ï¼Į æīĵç®Ĺ +åħ» åĪĨ +ĠCour tesy +ć ĈĈ +éĹº 女 +çĹĬ æĦĪ +æĦıè¯Ĩ å½¢æĢģ +åĹ Ĵ +: T +çijķ çĸµ +èĭı å®ģ +ĠP irates +齿 æĿ¡ +urg ery +w art +çļĦ ç®Ĭ +Enc ryption +" }. +Ġcaf é +( uri +K i +æľ¬ ç½ijç«Ļ +comm ons +ï¼Įåľ¨ ä¸į +uc chini +Ġteam ed +è´§å¸ģ èµĦéĩij +çľĭå¾Ĺ åĩºæĿ¥ +åıĹ åĬĽ +ubb ing +ab it +ä¸ĭ å®ļ +æĺ¾ éľ² +ĠAir ways +å°± è¿ij +Ġdes ks +èģĶ çļĦ +END ING +_ controller +å¹¶ åĪĹ +å®ģ å¸Ĥ +c ritical +Ġhyper bolic +uc er +allow een +Rep orter +might y +æ¼Ķ æĪı +Ġwavelength s +ĠFut ures +åĨ² åĨ² +Ġm olding +Ġacad emia +t in +踪 迹 +æīĢ å¤ĦçļĦ +() ( +çŃĶ è¾© +ç»ĺ æľ¬ +-com ponent +ĠMe ans +ent on +æī¾ ä»ĸ +å¾ħ åľ¨ +æĶ¹ åĨĻ +å¸Ĥåľº ä¸ĬçļĦ +ĠM eth +_P AR +èµĦæľ¬ åĮĸ +ĠB om +ĠD in +Consider ing +AS F +ĠBas il +ĠP ulse +æĪĸ å°ij +ĠFly nn +Ġpret ending +Ġexpress ive +ĠSurre y +Ġads orption +Ġf x +æįŁå¤± çļĦ +æľ¬ç§ij çĶŁ +rupted Exception +Ġsp un +纸 æĿ¡ +g iveness +Ġnew Value +çĽĺ åŃIJ +ĠNeg ot +-P acific +è´ŁéĿ¢ å½±åĵį +Ġdeep en +ĠE OF +ç»§ ç͵åύ +ĠA mm +ys es +Ġmaxim izing +ï¼Į è°Ī +ER C +èĢģ çι +çĸı æĿ¾ +Ġof t +Ġfundra iser +ĠLegisl ative +ä¸į å¸ĮæľĽ +m ot +Ġpe ach +-m ap +iction aries +Change Listener +æķĻ ä¸» +辨 è¯Ĩ +.Att ribute +ï¼Į 游 +Ġe psilon +èµĦæºIJ åĴĮ +Ġfol iage +sl ug +-man agement +z ig +çļĦ ç§ĺå¯Ĩ +Ġgreat ness +g overnment +没 好 +Term inal +P enn +æµģ 产 +éĶĢ æ¯ģ +Ġs inking +Sh ot +åħ¨åĬĽ 以赴 +Ġneighbour ing +id an +迪 士 +ĠHy undai +äºĮ éĨĩ +/ ****** +Ġign ition +ingu ished +ĠSing les +度 为 +ĠØ £ +éĢļ è·¯ +ĠMe asures +Ġstr cmp +Ġb orne +å¼ķ åĬĽ +è¢ ± +Ġtem ps +Ñĥ ÑĤ +user Id +Ġpal ate +¸ Ãij +> true +Ġm ish +former ly +Ġ\ - +åħĥ å®Ŀ +_SE PARATOR +V EN +åħī 大 +Cover age +ĠUL ONG +Ġb ury +Ġinter acts +Ġup held +: < +ç»Ī端 设å¤ĩ +ï¼Įä½Ĩ æĪij们 +on so +ĠB un +ĠX en +Ġ å·´ +ê¸ ° +> .< +ī è· +æľīä»Ģä¹Ī äºĭ +Ġmanif olds +IST ORY +éĤ¯ éĥ¸ +[ len +Ġr p +ĠHom eland +J ar +ï¼Į ä¸ī个 +il us +<< << +) æĺ¯ +åĽ ¤ +æ§ ¿ +ï¼Į åİ¿ +èĩªå·± 对 +Ġse ptic +Ġmm ol +( not +ç»Ī çĶŁ +误导æĢ§ éĻĪè¿° +re pository +ĠFrag ment +èĻļåģĩ è®°è½½ +Ġsprink le +m apping +Ġb ri +.Dis pose +Ġloc i +OO OO +ĠDifferent ial +åħ±åIJĮ ä½ĵ +ĠSant iago +Ġover rides +ä¸Ģèά éĥ½æĺ¯ +Ġp encils +Ġd arn +ä¹ĭ ç͍ +Ġsub urb +èĥ½ å¾Ĺåΰ +é¸ ¢ +ç§° éĩį +Ġcytok ine +Ġor naments +åħ¨ æĻ¯ +Ġcontempl ated +ĠST D +Stud ies +åIJİ ç«¯ +ï¼Ī äºĶ +| - +ĠL IFE +Av g +å·¨ çŁ³ +ĠSy racuse +æ£ĭ åŃIJ +ä¸įç»ıæĦı éĹ´ +Ġt ighter +çłĶ åΤ +è¿ĻäºĽ äºĭæĥħ +åĨĻåŃĹ æ¥¼ +le ast +ãĢĤ è¦ģæ±Ĥ +æijĶ åĢĴ +W edding +åĪĨå¸ĥ äºİ +åĤ¬ çľł +. activity +class Name +ic io +æľī ä¸įåIJĮçļĦ +.get Data +éī´ èµı +æ²Ļ çī¹ +j ury +èIJ¨ å°Ķ +agn a +Ġfiref ighters +L ady +ĠPer f +å¹² æĹ± +æ½ ¢ +U ndefined +åĸĿ ä¸Ģ声 +:: __ +g rep +åįı åĬĽ +Ġdr ills +帮åĬ© æĪij们 +_enc oder +Ult imately +, æĮģç»Ń +ï¼Į M +é¦ ĭ +åĩł å¹´çļĦ +åįģåħŃ æĿ¡ +Ġsne akers +ĠT rophy +ĠK ard +roll able +æľĪå½± æŀ« +Ġd umps +Ġbro chure +ĠOUT PUT +ĠInd icates +çϽ çļĻ +é¹ Ń +åıijå¸ĥ ä¼ļä¸Ĭ +ä»İæĿ¥ ä¸į +Ġmant ra +ec o +çł ¥ +æľ¬æ¬¡ åıijè¡Į +Ġsqu at +Ġtransmit ting +çķĮ å®ļ +ass adors +ï¼ģ èĢĮ +ä¸Ģèά 为 +åĪļ æĢ§ +åģļ好 åĩĨå¤ĩ +æĨ © +Ġm igrant +ĠZ hao +ĠC OLOR +ç¼ ¨ +åĵ¥ä¼¦ æ¯Ķäºļ +åľ¨ æĹ¥æľ¬ +ĠH ert +Ġpoore r +G ro +Ġ èĮĥ +èĥŀ èĥİ +_d irect +åѦçĶŁ ä¼ļ +é£İ æ³¢ +ç¦ı éŁ³ +æĹ¶ èĩ³ +被 认为æĺ¯ +L abor +ä¸ĵ å®¶çļĦ +,ä¹Ł 没æľī +Ġperme ability +ä¸Ģ è§Ĵ +交 åıĭ +Ġparticip ates +æ£Ĵ çļĦ +_col lection +æľº ç®± +eg en +æ´¾ 对 +* )( +er ator +åIJį èĥľ +æĺ¯åIJ¦ ä¼ļ +ĠBench mark +ĠAm en +Ġaccommod ating +ĠF UNCTION +ĠE k +ĠIT S +ç¥ŀå¥ĩ çļĦ +åĴĮ ä¸ī +à · +ä¼ĺèī¯ çļĦ +çĶŁ éķ¿çļĦ +æł¼ åĬĽ +Ġplasm id +æĿ¥ æİ¥ +Ġresult ant +ĠW iley +Ń IJ +å°ı å¹³ +ĠV otes +åķĨæłĩ 注åĨĮ +éĿĴ èĽĻ +åıĮçľ¼ çļ® +ĠPione er +. include +Install ation +P ri +ĠErn est +es k +ĠC ement +å·¨ é¾Ļ +åij¨ ä¸ī +u en +-L icense +Ġmamm alian +N ik +Ch arge +Ġtransl ating +che mic +Ġfier c +src dir +ç¬Ķè®°æľ¬ ç͵èĦij +ĠM b +Ġch ats +_ usage +Ġcl k +Ġun in +æĽ´ æĸ°çļĦ +à¸ Ĺ +A ustin +æĪ¿ åŃIJçļĦ +ĠMur der +æĹ¥ çħ§ +. Anchor +空 空 +, å¢ŀåĬł +che on +Ġè¿Ļ å°±æĺ¯ +çľĭ ä¸Ģçľ¼ +Ġ åıĤæķ° +Ġpr isons +ĠIN DEX +_ uid +çľĭ æĪIJ +èĭį 穹 +Ind ependent +å®Ĺ éŨ +Ġsul ph +T al +EN GTH +Ġchrom atography +åѦ åłĤ +çļĦ大 éĩı +æĹ¶ æĹ¥ +äºĮ ä¸ĸ +-t ag +çļĦæ°Ķ åĬ¿ +æ·Ħ åįļ +Ġint estine +å®Ĺ 主 +æļ´ 涨 +og i +(b uilder +å¤ĩ æĪĺ +çIJĥ è¡£ +å·¥ç¨ĭ æĬĢæľ¯ +Ġout set +ĠChrys ler +nt z +é«ĺ ä»· +åı¯è¡Į æĢ§ +æī« åľ° +Ġ"$ ( +Ġwithdraw als +第åħŃ ç«ł +her ty +te ous +Ñģ п +å¦ĸ åħ½ +æĪij ä¹Łæĺ¯ +é£İ åĬĽ +äºĶ åĪĨéĴŁ +åĢĴ æķ° +æĪij æĿ¥è¯´ +Ġdebut ed +Ġirrad iation +Ç « +ä¸Ģ çĵ¶ +Ġik ke +âĢĿ è¿Ļä¸Ģ +Ġper malink +âĻ ¥ +Ġ 缮å½ķ +_s k +Ġreconc ile +m om +ĠC oo +cl ing +Ġpropag ate +ĠEd gar +_re nder +ç«Ń åĬĽ +-process ing +( readonly +ĠD ocs +å¾· èĤ² +, æĶ¾ +ãĢģ åζéĢł +人 å¿ĥçļĦ +å·¥ä½ľ åı° +Ġh ides +çĽĬ æĻº +Ġmal practice +Ġaut ore +çħ ½ +Res earchers +Ġen rol +_m edia +è·¨ çķĮ +x n +Ġin hal +éķ¿ å¾ģ +æ¶² ä½į +ä¸ĩ åIJį +Def endant +æįĤ çĿĢ +< dt +ib re +let ions +_E LEMENT +ï¼Į åijĪ +Ġb ots +Ġr uth +Ġt ying +éľ ¹ +"> ( +æĺ¯ä¸Ģ çĤ¹ +æĬķèµĦ ç»ĦåIJĪ +roke e +ï¼Įéļ¾ æĢª +èĦ± ç¡« +çŃī æ´»åĬ¨ +ĠBab ylon +Ġ éĵģ +Ġz ijn +Ġgrow ers +æīĵ çIJĨ +ãĢĤ æĹ© +ast on +Ġgl u +/ reference +C aps +åĬ³ å·¥ +Ne ill +ï¼Į åºĶç͍ +æĺİ çŁ¥ +åĪ« æīŃ +ĠQu iet +L ots +ĠMess iah +le in +ï¼Įä¸į 妨 +F ran +ĠSc ulpt +rodu ced +æľ¬ å®ŀæĸ½ä¾ĭä¸Ń +Stream ing +éĢı è§Ĩ +Ġcollabor ated +åħ¬åħ± åľºæīĢ +-g reen +atisf action +ä¸Ĭ è°ĥ +Ġp ued +çĤ¹ æĺ¯ +file Name +Ġpreced ence +Ġcomprom ising +ä»İ åĬ¨ +_n ow +Ġcounc ils +Ġm oss +åIJij 社ä¼ļ +-d ollar +i ya +ç² ½åŃIJ +羣çļĦ è¦ģ +Ġne ph +creens hot +, éϤ +ãĢģ 广 +_T ITLE +Ġdisturb ances +ĠE SG +Ġunus ually +Ġpod ium +_valid ation +Var ious +å·´ 马 +ä¸Ģ åŃ£åº¦ +éģ® éĺ³ +_CH ANGE +åĵŃç¬ij ä¸įå¾Ĺ +rav iolet +ĠKu wait +fin ished +éħįå¤ĩ äºĨ +(s k +ĠMer chant +; } +ï¼Ī åħĥ +æľµ æľµ +åľ¨ åIJĮä¸Ģ +æĥ º +ost asis +é¢ĺ 主 +äºĨ ä¹Ī +G PL +-ad just +ast ings +ä¹ĭ å¿§ +ĠHapp iness +åĮ¿ åIJį +Buffer Size +S erving +X F +缴 è¨Ģ +Ġins omnia +大 è·Į +å¼Ĥ常 çļĦ +ï¼Įç¥ŀ æĥħ +好 èݱåĿŀ +书 çĶŁ +ä¸į 顺 +人 éĢł +_p id +Sl ots +_ elem +åı¯ è°ĥ +åIJ¬ åIJİ +H s +Review ed +ãĢĤ æĹ¥æľ¬ +ä¼ļ计 æĶ¿çŃĸ +Hope fully +ä¸İ 大 +çı ŀ +çłĶåıij çļĦ +ï¼Į åįıåĬ© +ĠProf iles +Ġ 票 +æĪĺ åIJİ +msg id +ASH INGTON +ĠSp urs +Ïģ ÏĮ +çͰ éĩİ +ä¾§ æĿ¿ +ĠDrag ons +å¾Ī åĥı +, å¾Īå¤ļ人 +j ing +.G ame +ä¸Ģ ç«Ļå¼ı +"> &# +åħ¶å®ŀ å°±æĺ¯ +æIJ¬ åΰ +ä¸Ģ ç»ı +éĤ£ åĿĹ +Ø ² +åĵ¥ åĦ¿ +B less +çͲ éĨĩ +ï¼Į åĨ¯ +am oto +çłĶç©¶ 人åijĺ +ĠLo vely +è§ĦåĪĻ çļĦ +Ġmat te +Ġsent iments +embr ance +å¯Į æ±Ĺ +uper t +åı¯ 使ç͍ +.S plit +çŀ§ çĿĢ +ĠTer race +Ġinsign ificant +pl acing +Ġen quiries +Res erved +Des igned +: String +æĥ§ æĢķ +-s afe +ĠDet ect +tra ining +Ġmaster y +, åıĮæĸ¹ +][ $ +Ġanch ors +æķij æµİ +æľ¬æĸĩ æijĺè¦ģ +ãĢĬåħ¬åı¸ æ³ķ +ãĢģ 娱ä¹IJ +ĠU FO +æį » +被 æĬĵ +scan f +ï¼Į æĿ¾ +åĮħ 袱 +红楼 梦 +Ġsurround s +ï¼Į åIJķ +ä¸ĭ æ²ī +long rightarrow +Ġdemol ition +U m +å®ī 妮 +Ġ ä¹ĭåīį ++ C +èĩªå·± æīĢ +exper ienced +U h +iest a +Recogn izer +- ion +åİĤ çļĦ +Ġ ä¸Ģç§į +åĶĩ è§Ĵ +Ġfiduc iary +èµĮ åľº +ï¼Įåľ¨ 她 +éĺ³ æŀģ +æĢ» æĬķèµĦ +ĠSpec ification +çĶŁæ´» ä¹łæĥ¯ +æ½ ¼ +M oon +ï¼Ī ä¸įåIJ« +éĽ¾ æ°Ķ +³³³³³³³³ ³³³³³³³³ +ï¼Į å¤ļå°ij +æľ¬ 竳 +ĠL ips +ä¾Ľ éľĢ +å¸Į çī¹åĭĴ +и и +ĠS ne +åģļ 主 +ãĢĤä½ł åı¯ä»¥ +Ġgr pc +æ³¢ å½¢ +è°ģ çļĦ +ï¼Į æŃ£å¼ı +Ã¥ r +æīĭ æŀª +ä»· 款 +Ġbe i +ĠSant os +å°± çľĭ +æ¶ Ŀ +e pt +ĠH ess +å¸ĥ éĩĮ +Ġbl at +两 声 +ey es +个 ä¸įåģľ +æľ¬ æĬ¥ +ĠRa ise +ï¼Į 强è°ĥ +ï¼Ī %ï¼ī +æĺ¯ åįģåĪĨ +åįĩ åѦ +åįļ士 åIJİ +.D roid +æī¬ çļĦ +Ġnest ing +ï¼ļ æĿİ +_p in +t pl +ç»Ħç»ĩ åĴĮ +Ġdé cor +ä½ł éľĢè¦ģ +éĢĤ ä¸Ń +ĠStre ets +ç®Ń 头 +çĸı 忽 +çĶŁ å¹³ +建ç«ĭ çļĦ +ãĢģ èµĦéĩij +读 äºĨ +ï¼Įä½ł è§īå¾Ĺ +------------ - +åīª åĪĢ +æĽ´ åĸľæ¬¢ +Re uters +sc i +ĠUI View +ç¾½æ¯Ľ çIJĥ +æĹ¶ èĢĮ +ĠSuper intendent +ï¼Įä¸Ģ å¼ł +æĮ¯ èį¡ +as than +åŁº æĿIJ +Ġcycl ists +-d esign +ik an +ĠRav ens +- β +Ġre claim +ãĢĤ她 们 +ä¸ĭä¸Ģ 代 +ji ang +åij » +}$ ) +è§Ĵ è´¨ +èįĶ æŀĿ +[ X +_c ursor +& C +, åįł +æĪij ä¹Łä¸į +注 缮 +Ġet her +ĠJul iet +ĠObserv atory +Ġ æľŁæľ«ä½Ļé¢Ŀ +.pers istence +, Z +ĠI PA +æĢ» å̼ +CS R +ĠHy derabad +ĠSm oking +Ġab err +ï¼Į è´¾ +å®¶ 大 +çĽIJ éħ¸ +IN ED +ãĢģ 天津 +ĠOb j +ĠHE AD +Ġeas ing +约 æľī +Ġsupp er +Design er +åħļæĶ¯éĥ¨ 书记 +wo ff +s ers +-f ull +Ġre positories +æľį èᝠ+Ġref ining +, ä»ĸ们çļĦ +导 读 +Ġphot oc +our ning +éŨ ä¸ĭ +á l +Ġw c +get Instance +Ġcl azz +åı¯ 使 +ĠFel ix +Ġfil ament +æİ§åζ è£ħç½® +Ġcontamin ants +umber land +çīĽ å¸Ĥ +Ġpersu aded +让 åѦçĶŁ +Ġoutwe igh +夫 åIJĽ +åºĩ æĬ¤ +è me +al ers +ole cule +Ġcourt room +ĠForm ation +ï¼Įä¸ĭ 次 +/ gl +åħ¢ åħ¢ +æ² ½ +绿 åľ° +æł¹æľ¬ ä¸į +å£ģ 纸 +_l imits +Ġplug s +ÃŃ s +Ġd al +éķ ° +è¿Ľ é©» +ç»ķ è¿ĩ +ãĢĤ å¸Ĥ +ak k +· å¾· +éļ ĺ +åıĺ è´¨ +ĠSe asons +临 æ²Ĥ +鸣 ç±» +ï¼Į 太éĺ³ +Ġmis dem +è¿Ļéĥ¨ ç͵影 +Ġ\ ) +- connected +B razil +-m et +Ġearn est +çŃ¾è®¢ äºĨ +Ġconcent rating +, éĺ¿ +ĠMc Don +Y L +.p i +Ġdep icting +ç´§ ç»· +.W ait +tol ower +Ġy elled +Ġdissemin ation +Ġk ale +Ġvac ancy +æ³ķ è¯Ń +ĠAg encies +çļĦ 认è¯Ĩ +åįĩ å̼ +,ä¸į å°ij +èĢIJ çģ« +Ġv als +ĠSuz uki +ĠA PC +ãĢģ 产ä¸ļ +çĤ Ĭ +æİĮ å¿ĥ +稻 èįī +ä½ł åij¢ +ä¸Ĭå¹´ åIJĮæľŁ +Ġ åĥı +æĽ´ åIJį为 +, æľĢè¿ij +Ġf ences +软 管 +.T op +FT P +ç¥ŀ çģµ +Pr inc +ĠP TR +Ġcapac itor +Ġg in +Tag Name +- needed +çīĮ çħ§ +_output s +\\\\ \\\\ +Ġintermitt ent +ĠU tt +sp acing +ĠWorld s +åºĶ 注æĦı +Ġc raz +ä»Ĭ çĶŁ +(s um +ìĦ ľ +E c +Ġel usive +å¹» è§ī +Ġfant as +æĪĴ å¤ĩ +éĹªçĥģ çĿĢ +en ate +对 åŃ©åŃIJ +åĨľä¸ļ åĨľæĿij +_se lected +AP A +Ġpl unge +௠ģ +R U +æŀľ æłij +è·ij éģĵ +çĤ¹ åΰ +å±Ĥ 级 +Ġt l +ĠB ere +_d t +æļ Ħ +ĠLED s +Cong ress +Ġa che +Ġb un +ĠInteg rity +) ` +> ', +- rel +est ream +ä¸į æĮ¯ +ĠWatch ing +秸 ç§Ĩ +æĢ» èĤ¡æľ¬ +çģ¯ æ³¡ +æľº çIJĨ +绳 ç´¢ +\sub subsection +ĠB ark +Ġfront al +åıįåºĶ åύ +Ġdiff raction +LO PT +, éĿŀ +ĠS EL +èī² è°± +éĢĨ 天 +ĠM OT +.n c +Ġ& ' +太 å®Ĺ +Ex act +åĭ¾ èµ· +çIJ¥ çıĢ +Ġentang lement +çĮ ķ +_b ias +æ¥ Ĥ +grad es +fe el +ĠL TD +R ent +Ġde ception +.s ync +) å°Ĩ +d igital +ä¸Ģ个 å°ıæĹ¶ +ä¸ī æĿ¡ +代表 ä½ľ +-d ialog +è§£åĨ³ éĹ®é¢ĺçļĦ +( True +æľįåĬ¡ æľºæŀĦ +math op +Head ing +å·²ç»ı ä¸įæĺ¯ +ä¸¥æł¼ æī§è¡Į +è¿ĩ ä¸Ģ次 +-p re +Ġhang s +- unit +çIJĨ æĢ§çļĦ +Ġobs ess +Ġsl ated +avor able +Ġ åĨ¯ +am ong +ĠC trl +æ® ¡ +Ġland lords +, éĩĩç͍ +ĠOccup ational +M H +ĠOut reach +è¿Ľ éĺ¶ +Ġve il +åģļçļĦ å°±æĺ¯ +t ips +çı ı +Ġcorrespond ent +é£ŀ è·ĥ +.b it +Ġ äºĨ +Coord inates +R iver +æĮª å¨ģ +æĪij çľģ +enn el +ĠCh op +_p ublic +端 çĿĢ +ï¼Į æĹ©å·² +Ġd ucks +K ar +B ounding +Event Type +ï¼Į åĪĽæĸ° +æ»ij æĿ¿ +åΰ æĿ¥çļĦ +è¿ĩ éķ¿ +oh ist +ĠEl vis +g ames +ï¼Į T +p ip +ï¼Į çķĻä¸ĭ +- operative +è¿Ļ个 çĶ·äºº +Ġc apped +id ences +Ġest á +_k wargs +ä¸ĭä¸Ģ ç§Ĵ +ãĢĤ éĿŀ +ç»ı常 ä¼ļ +Ġwhis key +, è®¤çľŁ +èĢ ĺ +Ġcl ut +ĠCo operative +让 æĤ¨ +éĢģ è´§ +妩 åªļ +ma id +k W +åıª å°ı +}} {{ +èµĽ åīį +M ul +ĠâĢľ â̦â̦ +/m ol +.d ataset +ĠPower ful +ï¼Į 表æĥħ +座 ä¸Ĭ +éļ¾å¾Ĺ çļĦ +Name Link +ĠChron icles +ĠCha os +_f amily +ĠCl aus +eng ing +åľ¨ åħ¶ä»ĸ +RO SS +Ġcoun selling +Ġg cc +Ġge odes +ĠRot ary +åĩº æµ· +-t abs +Ġuint ptr +I ran +ä¸Ĭ åįĬ +éĹ´ è°į +ĠL ikes +ang i +åĽ½ åѦ +- values +*\ *\ +èĭ± åĭĩ +é¡¿ é¥Ń +ĠG IF +sp oken +ï¼Į åĨħå¿ĥ +-f acing +orb id +ãĢģ åĬŁèĥ½ +å´Ń æĸ°çļĦ +èļ Į +Ġchap el +Ġha il +éĩĩåıĸ äºĨ +ĠG IS +ä¿© 人 +ist em +Ġex claimed +ãĢģ æİĴ +éĢļ è´§ +ï¼Į ç©Ĩ +K P +Ġquestion naires +ĠAdjust able + ¯ +Ġm aze +æľī æŃ¤ +äºĨ åı£ +åĨ° ç³ĸ +Ġip v +å¼Ĥ æł· +æµħ æµħ +ĠCelebr ity +head ed +reet ings +åĽŀçŃĶ è¯´ +笨 èĽĭ +Ġget ter +èĬĤ 缮çļĦ +å¢ŀ æĮģ +per malink +ĠT iffany +åı¯ è¨Ģ +åĵ²åѦ å®¶ +éĽ ³ +ï¼Įä»ĸ åĴĮ +_pro gress +ï¼Į èĭ¦ +Ġ çݰ +å¼Ĭ 端 +D ates +» ÃIJ +Ġdep ressive +æijĦ åıĸ +Per form +âĢľ For +çĹ Ķ +c ake +ãĢĤ ä»»ä½ķ +å°± ç»Ļ +- Identifier +Ġ æĵįä½ľ +ĠWeb inar +Ġfind er +Ġhand book +æĬĹ è¡¡ +, self +Ġ è¿ĶåĽŀ +对 å°ı +åıĤä¸İ åΰ +çŃī è¿Ľè¡Į +æŃ¥ æŀª +士 åįĴ +滤 èĬ¯ +c atalog +æĺ¯ æŃ£ç¡®çļĦ +B eta +ä¼Ĭ æĭīåħĭ +L java +Ġspec ulate +Ġvolcan o +åIJİ åıĪ +Ġs ut +To List +æĢķ æĺ¯ +èµµ äºij +Ġbrain storm +ĠBal let +g ard +-m ass +# line +ient ists +Ġdraw back +Ġrec ursion +éĿŀ常 大çļĦ +d ry +_c ert +Al arm +Value Type +åĶ¿ åͤ +Ġunre liable +缸 éĢ¢ +åıĮ 缮 +Dis closure +H all +P rec +_S R +Ġec lectic +æµ ļ +ĠInd y +ãĢģ æĪIJéĥ½ +è¿Ļä¹Ī å¤ļçļĦ +ภ§ +ä¸Ģå®ļè¦ģ 注æĦı +Ġt unnels +lik es +ä¸į å®Įåħ¨ +为 å®ľ +ãĢĤè¦ģ çŁ¥éģĵ +Ġclean se +æ¯Ľ ç»Ĩ +Ġdimin ish +ï¼Įåħ¨ éĥ½ +ĠIntellig ent +ĠDor othy +ãĢģ 飩 +建 æŀĦ +fl are +ãĢģ 转 +Ġpoint less +æĹħ游 ä¸ļ +èĤ² åĦ¿ +ĠWor cester +pect ral +any e +åĵį 声 +èĬĤ度 使 +详ç»Ĩ 说æĺİ +ï¼Į å¼Ħ +åľ ĥ +åħĭ æŀĹ +Ġch illy +çĤ¹ çIJĥ +Ġperiod ont +Download s +Iter ation +\ log +- ar +U b +æ´» å¾Ĺ +å½¢ ä½ĵ +å¾® å¦Ļ +ï¼Į ç®Ģ +ac ons +åħij ä»ĺ +igs list +ï¼Įå°± æĬĬ +ĠLiter acy +ĠC FO +Ġbreak out +em onic +ign e +( vec +ĠB ucket +ĠCom bo +c uda +ĠEx ec +æĺĵ æĩĤ +çľģ éĴ± +.R ow +Ġ éĹ® +æĸĩ ç§ij +骨 è´¨ +Ġforward ing +L inda +in ous +id os +aw ks +ĠMart y +R ather +h ort +éļIJ ç§ĺ +_string s +BO ARD +_m ake +Stream s +,éĤ£ å°± +.Line ar +å±Ĥ éĿ¢çļĦ +主æ¼Ķ çļĦ +ä½Ļ ç¯ĩ +ĠWill is +èģĶ æİ¥ +æŃ¢ çĹĽ +å¹´ å°ij +uss ed +å·¥èīº åĵģ +å¼ķ æĿ¥ +G race +åĽ½å®¶ å®īåħ¨ +è´¸ å¸Ĥåľº +: function +ï¼Į 欧 +R ated +P AGE +åī¯ æĢ» +AND OM +q tt +Ġmac OS +H oly +ĠP ip +Ġf rog +ĠB ride +Ġk ö +Capt ain +CL C +ä¼ij åģĩ +èı² çī¹ +.f ire +Ġseason ing +认è¯Ĩ äºĨ +Ġplate au +Ġlan tern +ãĢĤ æĹ¶éĹ´ +ĠList ed +sp i +æµ· æ£ł +Ġcel ery +çļĦ åĩĨå¤ĩ +ç«Ļ ä½į +Ġcoast line +ãĢģ æĹ¶éĹ´ +ĠMost ly +ãĥ ij +äºĮæīĭ æĪ¿ +è§Ĥ æij© +ï¼ĮçĦ¶åIJİ ç͍ +. Argument +å¤ļ éĩį +ï¼Į人 çĶŁ +ĠIR Q +Ġper il +Ġgrass roots +ï¼Įè¿ĺ å¾Ĺ +ĠEN V +èĬ± é¦Ļ +O m +ĠEnd point +Ġcontin ual +CON NECT +loc ate +Ġtransc end +Ġdev ised +.col lection +æ¸ħæ¥ļ æ¥ļ +ÃĹ Â +Ġc pp +让 ä½łä»¬ +Ġes lint +p ast +ãĢģ 误导æĢ§éĻĪè¿° +/ int +/ utils +ï¼Įå½ĵ åīį +ĠHouse hold +ĠTable t +L anguages +åģļ çĿĢ +Ġadapt able +ĠP AN +ä¹ĭ åĽ½ +ä¸į åIJĪçIJĨ +ãĢģ èµĦæºIJ +Ġn z +ĠE OS +ES A +åºĹ å®¶ +æīĵéĩı çĿĢ +æģ¼ æĢĴ +è¿ĩ ä¸Ģ +人æīį çļĦ +ĠLE FT +åľ¨ åħ¬åı¸ +Ġdra ins +Ġgener ously +Cas ino +K F +ï¼Į è¾¾ +ä¸įçŁ¥éģĵ èĩªå·± +åıijéĢģ èĩ³ +ores cence +P urpose +Ġ 转 +W is +Ġ 车 +ï¼Į 称为 +art on +æĬ¥éģĵ ç§° +Ġp si +ä¹Łæ²¡æľī ä»Ģä¹Ī +ĠF IELD +Ġiron ic +ç¾İæľ¯ åѦéĻ¢ +ĠByte Array +_ obs +åĬĽ æ±Ĥ +ç¡ Ĵ +LE EP +, å®Įåħ¨ +ing leton +lib s +Per formed +éģŃ åΰäºĨ +Ġlip stick +ĠEvery day +gr ant +åĪ¶ä½ľ 人 +ĠH DR +G rowing +ï¼Į è§£ +ï¼Į åķĨ +ãĢģ æıIJä¾Ľ +åĽł èĢĮ +urd ue +.b oot +âĢ ¬ +èĭ¥å¹² 个 +Ġm ason +, ä»Ģä¹Ī +çİĭ 天 +åĪĹ ç¤º +æīĭæľº çļĦ +_ URI +ç½Ĺ æ±ī +Diff erence +éģ¿åħį äºĨ +ä¹ĭ é£İ +ĠV ault +Ġper for +opl astic +pp a +ç¦ģ æ¯Ĵ +ä¹³ åĮĸ +AG R +çĶĺ å¿ĥ +ol ated +ĠEx amin +举 个 +èİ« æµĭ +çļĦ å±ĢéĿ¢ +-p ublic +Ġdri p +( api +ĠE mit +(' [ +åij¨ åĽĽ +æľº çŃī +ĠPark way +âĪ ´ +ãĢĤè¿Ļ æĺ¯ä¸Ģ个 +éĽ¾ åĮĸ +\] ). +åı¸ 空 +è½» ç¬ij +课åłĤ ä¸Ĭ +- Le +åĴĮ ç»´æĬ¤ +身 亡 +软 å¼± +AR DS +åħ´ ä¸ļ +ï¼Į å½Ĵ +la unch +Ġtime frame +ass ing +æĪij们 æīĢ +Ġoutrage ous +äºĶ 彩 +å¤ĸåĽ½ è¯Ń +ç«ŀ éĢī +èĩª åıij +çľ¼ èī² +ĠExp ansion +Ġ #### +è¡Ģ æ¸ħ +na issance +Ġ] ] +ĠJ unction +^* $ +_M AG +çļĦ 被 +èµ°äºĨ è¿ĩåİ» +, 好åĥı +Ġt rop +.R ight +åĢºåĬ¡ èŀįèµĦ +åѦ åīį +åĨį æľī +ĠCard iff +Ġfragment ation +åı¯ä»¥ å¾Ĺåΰ +Ġminimal ist +Ġarchae ological +ä¼ļ æ¯Ķ +Or th +Ġmarked ly +èģĮä¸ļæĬĢæľ¯ åѦéĻ¢ +.No Error +l ance +å¾Ī éĩįè¦ģçļĦ +Ġmon uments +çľĭ æ¸ħæ¥ļ +头 é¢ħ +lock ing +åĵģçīĮ 形象 +For got +cut aneous +( attr +ãĢģ èĮ¶ +åıĭ 人 +Ġfresh water +( inst +() ] +EM BER +ENC ES += null +Ġin secure +转åıĺ 为 +ĠGl ory +Ġcro chet +Nob ody +ãĢģ æ·± +Ġwater front +æ²¹ 缸 +æĺ¨å¤© æĻļä¸Ĭ +åħļå§Ķ å§Ķåijĺ +ï¼ī 对 +Ġne urop +çĨ ¹ +åIJį å½ķ +ï¼Į æ´ª +.F ramework +éģĹ åĺ± +< csv +ĠV endor +空æ°Ķ è´¨éĩı +last ing +è¿ĩ éĩı +æĦĪ åĬł +ï¼Į åIJ¹ +åľ¨ 身ä¸Ĭ +çĶŁéķ¿ åıijèĤ² +al ach +ut an +çķĻ ä½ı +è´¢åĬ¡ çĬ¶åĨµ +ç»ķ ç»Ħ +Ġnic er +.S ession +S olutions +ĠDisc ord +Ġhe fty +ĠAng lo +, 认为 +ur ge +æĪij éĻ¢ +Sc enario +溶液 ä¸Ń +æ¼Ķ ä¹ł +åı² èĴĤ +sk ill +Ġ åĽ½éĻħ +ï¼Į è¿ĶåĽŀ +è¿Ļ å¹ħ +èį ¼ +ï¼Įè¿Ļ æīįæĺ¯ +åĽ¾ çĶ» +Ġst up +и д +Just in +ä»ĸ们 éĥ½ +ï¼Įåı¯ä»¥ å°Ĩ +ĠRoll s +Ġtodd lers +C ards +Ë Ī +主 æĿĥ +Ġ%> % +Ġen large +æİ§åζ 模åĿĹ +ä¹Ł æĮº +_C OPY +ä¾Ľ åħ» +æĬ¥åijĬ ä¸Ń += e +Ġdent ists +æ¯į ä¹³ +Ġhomeless ness +ĠK ot +(). __ +Ġsubt raction +没æľī ä¸Ŀ毫 +in ctions +ass ed +ä¹ĭ 乡 +Ġtext ing +åį¡ è¥¿ +_V ERT +ĠNeed ed +j on +äºİ å¿ĥ +ï¼Į两 èĢħ +/ search +h of +B UILD +æľĿ 天 +æģ© æĢ¨ +ä¸į æĶ¹ +ĠSav annah +ar ious +Ġprol ifer +ĠL icensing +å¤ļ å°Ķ +æ²» åĽ½ +å¦Ĥ æĿ¥ +es se +Ġpro claim +ak an +p arsed +å°± 好åĥı +åĬ¨ åIJij +Ġauthor ised +ä»ħ代表 ä½ľèĢħ +ä»İ 严 +G MT +Ġn iece +Ġcl ang +ode grad +(s b +ñ a +è¯ij èĢħ +â ŀ +Ġraz or +ĠHospit als +ĠNa Cl +Ġp its +ĠO ven +, $$ +马ä¸Ĭ å°±è¦ģ +大 éĥ½ +,æĪij æĺ¯ +.pro p +ĠInf luence +ãĢģ åŁ¹è®Ń +ç»Ħç»ĩ éĥ¨ +åģľè½¦ ä½į +躯 ä½ĵ +ĠM erg +çļĦç¾İ é£Ł +æ³¢ éķ¿ +伸 å±ķ +ĠDiff erences +, 第ä¸Ģ +h og +åľ£ æ¯į +æĬµ 触 +Ġ ä»Ģä¹Ī +é¡¶ ä¸Ĭ +åįķåħĥ æµĭè¯ķ +ĠStaff ord +éĺ² ä¼ª +åľ¨ åįĹ +Ġhem isphere +D ental +Ġcook book +纪念 é¦Ĩ +Lo vely +ä¸į åħ¬å¹³ +è¶ħ æłĩ +ld ap +Ġchrom osomes +Ġmultid isciplinary +ãĢģ æķ°åŃĹ +Ġloc ality +(Q t +çļĦ éħĴ +Ġanaly zer +ĠLOG GER +ï¼Į满 èĦ¸ +Ġk idd +ĠK urd +èĮī èİī +åįģ 天 +ا Ùħ +çĮķ çĮ´ +ï¼Į ä¾Ŀæį® +ic ia +ĠR W +, åIJĮ +Ed ited +M agento +ĠAustral ians +沦 为 +: g +L imited +pg f +åĩłå¹´ åīį +å§ĭ 建äºİ +X C +ï¼Į 缮æłĩ +Ġ çģ« +å±ħ å¤ļ +åı² æĸĻ +Christ opher +大 æīĭ +ĠMah arashtra +ĠBuild ings +è·¯çͱ åύ +ï¼Į 缸åıį +éĻĦ 带 +ç¦ħ å¸Ī +åħ³ 头 +åı¯ä»¥ åĪĨ为 +Ġshe dding +ID A +Ġdis cret +ï¼Į没 人 +- entry +æĪIJ 份 +åĮĸ èĤ¥ +Ġrecip rocal +Sh ares +ãĢģ ç§»åĬ¨ +éĩĮ åİ» +Ex ceptions +Ġscreens hots +è¿Ļç§į æĸ¹æ³ķ +Ġlog ically +ç° ª +ĠM OS +çĺ Ļ +Ġgen omes +æ²ī è¿· +æ·¡ æ°´ +.In valid +书 ä¿¡ +ĠW ick +_P CI +wood s +Ġcomb inator +ï¼Į ä½ĵéªĮ +ĠH ut +ç«¥ åŃIJ +Ġsyn onymous +ãģ§ ãģį +, æŀĹ +å¹³ æĹ¶çļĦ +ĠSch neider +è¿Ļä¸Ģ æŃ¥ +çļĦ çIJĨ论 +Ġconsc iously +ĠSub mission +Ġ ä¸ĸçķĮ +æĽ´ ä½İ +Ġquant ification +ï¼Į åıijçĶŁ +ĠC hes +å®ļ è¦ģ +U r +Ġche wing +.J SON +åħ° å¾· +çĮİ çī© +_TR AN +ãģĿ ãģ® +åĩº æ°Ķ +ãĢĤ å¤ı +ES P +ä¼ĺæĥł æĶ¿çŃĸ +女 åŃIJçļĦ +ĠAll ied +ĠCav al +, 她们 +M ASK +ãĢģ åĪĨæŀIJ +prot ection +Ġd ic +åĴĮ ä¸ĢäºĽ +- ready +Ġdiscretion ary +åĴĮ 第ä¸ī +IV ERS +ç²¾ç¥ŀ çĹħ +æĬ ł +è¡Į èĢħ +Ġg or +end as +Ġcogn ition +Ġcam el +å°±æĺ¯ è¿Ļä¹Ī +èħIJèļĢ æĢ§ +åĽ½ æĹĹ +ĠChe ers +Ġric hest +.not ify +Ġ åŃ£æŀ« +çļĦ è®Ńç»ĥ +ï¼Į è¿ĩäºĨ +ing ers +Ġemb ody +TR ANS +åľ° éĿ¢ä¸Ĭ +åŁºæľ¬ éĿ¢ +ç´§ éĹŃ +ĠCarn egie +çļĦ 计ç®Ĺ +St even +-trans ition +åĩº ä»Ģä¹Ī +Ġspirit ually +ĠNumer ous +, æĹłæ³ķ +ĠPRO DUCT +Ġat roc +B ang +_ self +åİĭ æĿ¿ +ćĈ ï¼Į +çľ¼ çķĮ +Ġdiss olve +Ġsan itation +Ġsett lers +.P er +I J +éĤ® å¯Ħ +ow e +ä¸īåĪĨ ä¹ĭä¸Ģ +ä¼ļ è°Ī +ï¼Ī ä¾ĭå¦Ĥ +ä½ı 建 +Manufact urer +ä¸įåIJĮ ç±»åŀĭçļĦ +Ġauthor itative +åıĹ äºº +ç§ģ ç«ĭ +ĠThom son +ĠC ITY +Ġ åıijè¡Į +ï¼Į é±¼ +Gl ad +çĿĢä½ľ æĿĥ +æ¤į 被 +C ivil +logen etic +第 åįģäºĮ +Ġfreed oms +Ġle ases +ãĢģ æ³¨æĦı +å¼ĢæĶ¾ çļĦ +Virgin ia +æĸ¹æ³ķ åĮħæĭ¬ +ãĢģ æł¹æį® +Ins ights +å¼ ¼ +çĪĨ çł´ +ĠPet roleum +赫 å°Ķ +F light +åĩº 产 +æĬĬ å°ı +ï¼Į çĹħ +ĠC itation +ir ror +ĠShir ley +side bar +ï¼Į åIJī +æķĻ çļĩ +æĺİç¡® äºĨ +Ġboil ers +, 西 +F ault +Y ears +æĥħ åķĨ +被 æĿĢ +ran o +Ġdel imiter +å®Ŀ åīij +b j +ãĢģ åįĬ +per f +æİ§åζ ä¿¡åı· +- loader +R anges +ç«ŀäºī ä¼ĺåĬ¿ +èĬ± èįī +br ane +ç»ĻäºĪ äºĨ +in fl +bol t +l ane +Ġà Ĥ +çīµ æĮĤ +论 è¯Ń +é©» åľ° +ãģĹ ãģ¾ãģĻ +ĠVM ware +å¿ĥ çĹĽ +Col umb +aid u +ï¼ĮæĪij è¿Ļ +Sub view +ä¸ĢåĪĩ çļĦ +ãĢĬåħ¬åı¸ 竳ç¨ĭ +Ġcon duction +Ġse ismic +ï¼Įä¸į åģľ +Ġtur moil +- ret +] ' +ãĢģ èĥ¡ +or st +æĸ° é£İ +ĠU ps +Ġcont emplate +ĠV AR +ĠI on +ãĢĤæĪij åľ¨ +Ġn uis +Ġparas ite +ä¹ĭ 举 +绿 è±Ĩ +è¿ĺæľī åħ¶ä»ĸ +ĠN ina +åį³ ä½į +M ale +ĠZ IP +ap oration +å³ ¦ +( loc +ï¼ĮäºĮ 人 +V i +Ġmon arch +Ġimpact ful +ãĢĤä¸ī æĺ¯ +-sign ature +-c ounter +/L ibrary +ĠPlatform s +( seq +N orthern +åIJĥ æİī +ĠPhot ographer +× ŀ +é¢ĺ å¹² +ĠInitial izes +Ep och +ãĢĤ åģļ +ĠSm ile +羣çļĦ æľī +ĠAct ing +{ if +Ġas ian +Ġexhaust ive +é¾Ļ 骨 +s it +ä¸īåįģ å¹´ +ï¼Į æĸ½å·¥ +ä¼ļ è¯Ŀ +人们 åľ¨ +æĹłçº¿ ç͵ +å®ĺ åĥļ +Ġstock ed +飵 åij³ +_ms gs +éĤ£ åı¥è¯Ŀ +Ġcarbohyd rate +Ġs oooo +ä¸Ĭ ä¸ĸ纪 +ĠDes criptor +It aly +I g +ĠVal ve +ĠC s +æĤ ´ +Res pond +ĠGu jarat +åݻ年 åIJĮæľŁ +Prob ably +ĠC CTV +è¾ĵ ç»Ļ +\ Delta +\ circ +S olver +. admin +Ġle pt +åĸ§ åļ£ +çļĦ èᝠ+çļĦä¸Ģ åľº +} )$, +ĠR oo +ĠO ber +åıĪ éģĵ +. account +ĠUn s +-v ol +_l r +ä½ĵåζ æĶ¹éĿ© +Ġprophe cy +ĠJ al +æľ¬ å°± +ï¼Ī è®°èĢħ +Ġfinal ized +ï¼Į éĶĢåĶ® +ĠKey words +åįģåĽĽ äºĶ +scrib ers +çļĦæĸ¹å¼ı æĿ¥ +Mar ia +ip o +çĽIJ æ°´ +åĵģ æł¼ +ĠQu int +Place ment +å°±æĺ¯ è¿Ļ个 +é¢Ħ ä¼° +ä¹Ŀ 天 +raft s +engu ins +To ast +è¨ Ń +ĠF iled +du plicate +_s uffix +ä»Ĭ天 æĺ¯ +æľº ä¸Ĭ +èϽ æĺ¯ +两 åĿĹ +åºķ æ°Ķ +Ġg on +çĸij èĻij +Ġun ravel +èݱ æĸ¯ +. Exception +^ d +éĩĮ 奥 +Ġpress es +;; ; +å¿ĥ èĤĮ +_AL IGN +ä¸Ģ个 女人 +.P age +ï¼Ľ ä»ĸ +Ġi ii +ĠEnt ries +Ġportray al +临æĹ¶ èĤ¡ä¸ľå¤§ä¼ļ +. ind +æ¯Ķ èµ·æĿ¥ +.C opy +æİ§åζ åįķåħĥ +Ġsteward ship +, ä¸Ģèµ· +声 èī² +Ġperpet ual +Ġmodal ities +ï¼Į æĺ¯ä¸Ģå®¶ +art ing +ä¸Ģ çĶŁçļĦ +\n ode +Ġbehav es +ĠBar ber +Ġantiv irus +- agent +âĢĿ 主é¢ĺ +åĩº åħµ +ĠAl ison +çķĻ é¦Ļ +.r oute +< B +ict ured +ĠE h +@ media +é¡¶ çĿĢ +ĠJud ges +ĠSt ru +ĠðŁ ij +ä»Ĩ 人 +ä¼ģä¸ļ åıijå±ķ +ynchron ized +åŁİéķĩ åĮĸ +å¸ĥ 鼷 +Y A +ï¼Į ç͵åŃIJ +_P HY +man ifest +对 è¿Ļ +å¼Ģ åħ· +\ hat +Ġnot or +Ġtrust ees +Ġwear able +ä¹ĭ äºī +åĩ¡ 人 +éŨ ä¸Ĭ +åĢį æķ° +ìĿ Ģ +åĢ ij +Ġreloc ate +Ġb ic +çľ¼ çĿģçĿģ +ä»ĭç»į çļĦ +Ġag ar +ACH INE +/ @ +nd ered +ĠLe ah +ĠT GF +ï¼Įä½ł ä¸į +EDIT OR +å¤Ħ 以 +ĠCl aud +ĠCamp ing +ĠSer um +æµģ éľ² +param ref +缴æİ¥ å½±åĵį +Ġhur ried +of s +åĽºå®ļ åĿĹ +è¿ĺ 被 +Ġemb eddings +ĠGe ographic +ï¼ļ 使ç͍ +Ġline back +Sub scriber +ĠLow e +èĩ´ åij½çļĦ +Ġcirc us +h ours +Ġ æľīäºĽ +羣 èıĮ +Initial izer +Ġun se +ĠIN IT +_ edges +åıª 为 +åŃĻ æĤŁç©º +{ }{ +ĠK M +å®ī 康 +-M M +ĠG EN +äºĭä¸ļ çļĦ +, çľĭçľĭ +æģ¯ æģ¯ +äºĶ æĺŁ +ä¹IJ çļĦ +-c ircle +-re aching +oton in +å·´åŁº æĸ¯åĿ¦ +Ġam y +ĠInt ro +ï¼ļ å¼ł +Ġtu ples += D +yn a +ĠTurn s +Ġunf olding +ĠEqu als +ç͍æĪ· åľ¨ +âĤ¬ Åĵ +h yp +ĠD ESCRIPTION +_con vert +é«ĺ 涨 +åįİ å°Ķ +Fl ush +Doc s +ĠB har +æľīæķĪ æĢ§ +ĠMet ric +Ġant agonist +ĠPat el +ãĢģ å¹¿ä¸ľ +管 ç½ij +俱 åħ¨ +O pp +ä¸Ńæĸĩ ç½ij +ãĢĤ èĥ¡ +Ġled ger +Ġsen ators +, åĪĨ +ãĢĤ æ±ī +çªģ åħĢ +_g o +ellig ence +çĺ¦ èº« += args +ãĢģ åĽĽå·Ŀ +ri angle +ĠR oc +Ġbra king +ĠOpen GL +ï¼Į èIJ½å®ŀ +ĠD IM +åľ° åIJį +åĢŁ ç͍ +ĠConsult ants +K at +å°± åıªæľī +çŁ¥è¯Ĩ åĪĨåŃIJ +éģ® æİ© +ãĢĤ æľīäºĨ +åŁºéĩijæīĺ管 人 +ï¼Į æĪIJ为äºĨ +Ġb ree +ĠU mb +( async +. ap +ä¸Ń 举 +ä¹Į 鸦 +æľĪä¸ĭ æĹ¬ +/ android +Ġsub d +è¿Ļç§į 人 +æĪIJåĬŁ åľ° +éģ¥ è¿ľçļĦ +Ġsho vel +çĤ¹ ä¸Ĭ +Ġan ne +Con current +ath lon +ĠChe vy +ĠE fficient +ä¼ļ æĽ´åĬł +好 èĩªå·±çļĦ +è¡Ģ èī² +黯 çĦ¶ +ĠW o +ĠLOC AL +" So +-n ormal +åĪºæ¿Ģ æĢ§ +Ġvan ish +ï¼Į çļĩå¸Ŀ +ĠB ast +Ġ å°±ç®Ĺ +Ġexhaust ing +, æīĢ +ĠG ret +éĻIJ åĶ® +è¿ij æĿ¥ +Ġrad ically +Ġdesc ended +åĨĽ æĸ¹ +çļĦä¸Ģ æĸ¹ +Exp anded +Ġsing leton ++ s +ets y +第äºĮ å±Ĭ +.as ync +[] > +abc def +ï¼Į æĮº +ĠL ung +Ġreloc ated +Ġlou der +_ OV +ĠUN ESCO +èĬĿ åĬł +ï¼Į å¼ĢåIJ¯ +Ġhom eland +ĠCont ributors +Ġapplic ability +ï¼Įæľª ç»ı +ĠKath leen +çļĦ æĪ¿åŃIJ +ĠFried man +ĠT one +ĠR oma +ï¼ĮéĤ£ ä½ł +ï¼Į åģı +che wan +Ġplate let +ï¼Įä¸İ åħ¶ +_config uration +lic ts +好 åľ¨ +ph yl +нÑĭ е +ãĢĤ åĬł +ĠC FR +b lo +è°ĭ æĿĢ +ä¿® ä»Ļ +ven cy +é¼» çĤİ +Ġcuc umber +other wise +vent h +èIJ¨ åħĭ +../../ ../ +&= & +\ psi +å°± åΰäºĨ +ĠJSON Object +æĶ¯æĮģ çļĦ +ĠBlog ging +Scal ing +Ġ 墨 +Ġ( / +å¾Ĺ è¦ģ +çļĦ大 èĦij +ï¼Į èĢĥ +part ition +, åĪĩ +ĠCor rection +IV ES +ĠL azy +ä¹Łä¸į çŁ¥ +ĠBuild ers +Q E +she ets +åĪĽæĸ° åĪĽä¸ļ +-r unning +ĠCarn ival +ãĢĤ å¾ħ +ĠBy ron +Ġrelent less +As ian +flu id +ĠGe orgetown +( Vector +ï¼Į æĬ¢ +å¼Ģ åIJİ +.D uration +å®ŀæĸ½æĸ¹æ¡Ī ä¸Ń +-n atural +Ġpron ounce +ï¼ī ä¸Ĭ +ribut ing +Ġlong ing +Ġextra ord +ä¸Ń央 空è°ĥ +al ignment +oh o +ĠBed ford +aly zed +l aws +ĠLe isure +_MODE L +ĠD aisy +Ġp aw +ï¼Įä¸įå¾Ĺ ä¸į +å ¶ +Ġab elian +C old +-g rand +ä¸įå¾Ĺ è¶ħè¿ĩ +.Get Value +ãĢĭçļĦ è§Ħå®ļ +Invest ment +Ġµ m +æĬķæłĩ 人 +ãĢģ åıijè¡Į人 +ä¼ļ èĩªåĬ¨ +erm aid +ä¹Łä¸į åĨį +å´ĩ å°ļ +ä¸įåĬ¨ 产 +ãĢģ éķĩ +ï¼Įå¤ļ 次 +æĽ´å¤ļ 人 +-m akers +. Conv +A rab +ĠM use +V IS +举 äºļ +Ġweb cam +Be haviour +Ġpal ms +_se ed +ĠC ycling +éģĵ æķĻ +å¤Ħ 女 +æ¬ł 缺 +ĠD aughter +Ġnational ity +Ġconced ed +åħĪè¿Ľ åįķä½į +urs ing +grad ed +ï¼Į åħ¼ +ĠThe sis +ä»ĸ ä¸Ģçľ¼ +Exper iment +æĺ¾èĢĮæĺĵ è§ģ +ĠRec ycling +è´¨ éĹ® +建ç«ĭ ä¸Ģ个 +ect ar +ĠV B +æīĵ åİĭ +oe lectric +IP A +mm as +Ġart is +ä¹Į é¾Ł +ĠW ORLD +èĢĥè¯ķ çļĦ +ĠComput ers +é¢Ĩ çķ¥ +_ ev +è¦ģ åĴĮ +é»Ħ å¸Ŀ +hed dar +.get Time +Att rs +-v olume +Ġdiscrim inatory +Ġstir red +æĪij åIJ§ +ï¼Į å¸Ī +ĠH ir +op ters +ĠWood en +ĠT at +ï¼Į 设å¤ĩ +c redit +( pt +IF S +Ġindu cing +ĠTit ans +çĥ¤ èĤī +èĬĿåĬł åĵ¥ +ure ment +ĠArgument NullException +L CD +æī Ī +åĤ» äºĨ +. verify +Ġ æĪĸèĢħ +Ġr ins +Ġ/ ^ +Ġsumm ers +ï¼Į " +lic ia +æıī äºĨ +ï¼Įèĩ´ 使 +- event +d j +èĥ½ ç͍ +ĠAS AP +ή ÏĤ +Ess ay +æĿ¥ æĿ¥ +æľ´ ç´ł +çļĦ èģĮä¸ļ +éĵ Ľ +íķ ´ +åħ± èģļ +Ġteam mate +å²Ń åįĹ +_un its +ter ra +Ġfuel ed +ĠProp Types +ä¸įä¸ĭ åİ»äºĨ +P AD +ä¸İ å°ı +(w x +éĤ£ éĩĮçļĦ +å·¥ä½ľ äºĨ +ал ÑĮ +å®ŀå®ŀåľ¨ åľ¨ +Ġtrou sers +-m edia +ï¼ĮåIJĮæĹ¶ ä¹Łæĺ¯ +æĸ° 西åħ° +çļĦ èĢģå¸Ī +ign ant +ĠO mar +æĥł å·ŀ +par ated +_T ASK +ĠChe ss +ans ing +Ġinterrupt s +æīĢ æıIJä¾ĽçļĦ +Ġdil ution +_ author +ĠV era +æįĤ ä½ı +ãĢĤ å¤ĸ +åĨĽ åľ¨ +het amine +_ web +ĠSerge ant +, ä½ķ +From String +,ä½Ĩ åľ¨ +:b log +Ġoff season +Te acher +çļĦ åķĨåĵģ +Ġsub type +Ġembry o +æĬ½ å¥ĸ +play ed +ĠCare y +èĥ¶åİŁ èĽĭçϽ +act in +ĠCarp enter +all i +Ġimp ending +è¿ĩ æľŁ +IM AL +Ġdistinct ly += no +', $ +æĥĭ æĥľ +Ġest a +ï¼Įå¹¶ 为 +俨 çĦ¶ +Ġobject ed +Ġscal ability +ht able +çIJ ¶ +, åIJĦç§į +ãĢģ éĩįåºĨ +ĠBox es +ãĢĤ ä¸įæĺ¯ +æľ¬è´¨ ä¸Ĭ +k p +ãĢĤ 两个 +unning ham +ut rients +MA IL +Ġperturb ations +al b +ä¸ŃåĽ½ ç»ıæµİ +ï¼Ł æīĢ以 +Ġmotiv ating +Ïħ ÏĦ +室 åıĭ +æ²ī éĹ· +çݰ å·² +_AL PHA +G y +ĠAl ger +Ġgr in +ãĢģ é±¼ +åĪ©çĽĬ çļĦ +èĥ½ ä»İ +åĩº å±Ģ +éĥ½æĺ¯ ä¸Ģ个 +æĤ¬ 念 +ä¸Ĭ ä¸Ģ次 +ĠTh irty +Ġtoler ated +, 强åĮĸ +Ġul cer +éĢĢ ç¼© +' }, +( inter +} a +ĠP ose +ć ãĢĤ +ĠCh o +表 å±Ĥ +Ġcal iber +ï¼Įä¸Ķ åľ¨ +DO I +iqu ette +Ġprob ate +ĠParent ing +Ġcaf es +æĻ ¤ +Ġj j +Ġblue print +Ġmotiv ational +ou ve +å±± 寨 +,åĨį åĬłä¸Ĭ +Ġknock out +est or +Ġqu ar +kit chen +ä¸Ģ ä¼Ĺ +Ġdisc ord +Ġpharmac ies +ot to +åħ± éĿĴ +渤 æµ· +ĠA j +oul os +ĠGL int +Ġoverd ose +ĠS PR +Ġpres ume +_ EL +ĠCheck ing +_ATTR IBUTE +èłķ åĬ¨ +温 å·® +Ġview port +æ¶µçĽĸ äºĨ +æ²ī浸 åľ¨ +avad oc +äºĨä¸Ģ çīĩ +ä¸İæīĢè¿° 第äºĮ +èĤĨ æĦı +NAS A +ĠSQL Exception +Ġcapt ive +Ġaug mentation +Ġfli pping +ï¼Į åľŁ +ĠVac uum +s ix +ä¸Ŀ çļĦ +Ġadvis ers +Ġ ÙĨ +äºİ ä¸Ģä½ĵ +该 æŃ» +ï¼Įä½ł åºĶ该 +Ġtot als +Ġmast ered +at os +ï¼Į ä»° +Ġf used +ĠCorn wall +amac are +åŁºéĩij份é¢Ŀ æĮģæľī人 +ĠN VIDIA +åΰ æľŁçļĦ +æĬ¥ æĸĩ +Ġassert ing +.w arning +å°ij è§ģ +Start Time +.re al +åĪĽéĢł åĩº +ĠWhe eler +ãĢģ åºĶç͍ +ç½Ĺ 伯çī¹ +æĩĤ äºĭ +ĠB ax +建çŃij çļĦ +Ġserial ization +B attery +ä¸į åħ·å¤ĩ +åIJ¸ æ°´ +ĠT ropical +act us +å¸Ĥåľº èIJ¥éĶĢ +æĺ¾å¾® éķľ +G iving +Ġunder m +Ġhard core +Ġall a +Ġper missible +. Connection +为 æł¸å¿ĥçļĦ +ç¾İ åĮĸ +红 çģ¯ +om ens +å·´ æĭī +ç¾İ å¦Ļ +ï¼Į ç´ł +· æĸ¯ +-in stall +ĠEd itors +飩 ç¡ķ +ä½ľåĵģ ä¸Ń +éħįç½® æĸĩä»¶ +Ġreject ing +c asters +ĠS ke +man age +åĮħ åİ¢ +[ num +Ġ 个人 +åıĪ æľīä»Ģä¹Ī +éĺ¶æ®µ æĢ§ +_ Name +Ġcyl inders +çĭ¡ çĮ¾ +ø r +åĮĸåѦ åıįåºĶ +å¼Ĺ æľĹ +/ cl +ä¸Ĭ å½ĵ +åħ¬åħģä»·å̼ åıĺåĬ¨ +Ġ ಠ+mg p +, 羣æĺ¯ +Link edin +_ imp +Ġby e +ĠFern ando +车 çªĹ +ĠCor b +ĠVer ification +- admin +Ġex cludes +ow ell +ĠO CT +ãĢĤ åı¯èĥ½ +ĠInst itutions +Ġmarvel ous +") [ +.e lements +é£ŀ æĿ¥ +ภ´ +横 æī« +em aker +è¿Ļ åĩłå¹´ +ĠAT TR +çļĦ ä»İ +Ġsou ven +Ġsc av +ï¼Įè¿Ļ 两个 +çŃī ä¼ĺçĤ¹ +d ependent +æľĢ å°ıçļĦ +-t ier +æľīéĻIJ åIJĪä¼Ļ +w omen +åľ¨çº¿ åĴ¨è¯¢ +ï¼Į è¾ĵåĩº +reat or +Ġattend ant +大 æĪIJ +å¹ķ å¢Ļ +ĠFair y +çĢ Ľ +ĠR AW +ï¼Įä½Ĩæĺ¯ çİ°åľ¨ +_W E +( rs +_ AX +Ġve gas +.g ui +ĠOut comes +森æŀĹ åħ¬åĽŃ +ĠLe igh +ä¸İ ä»ĸ们 +App ellant +ĠRab bi +èıł èIJĿ +Ġh yster +èĢģ ä¸ī +æľºæŀĦ åĮħæĭ¬ +ĠPref erred +ĠH its +.e u +礼 åĮħ +çļĦ 综åIJĪ +cal ed +对 她çļĦ +Ġrhe umat +ï¼Į 女æĢ§ +åıĸ äºĨ +,å°± ç®Ĺ +. alpha +at l +Ġn inety +Ġsh uff +éľĢæ±Ĥ åĴĮ +> @ +Ġfam ed +å±Ī æľį +inherit Doc +ï¼Į åıįåºĶ +-t rivial +C offee +P W +k as +ĠN il +æŁ¥ çIJĨ +çħ§ æĸĻ +çļĦå½±åĵį åĬĽ +Ġacceler ator +ĠM am +ä¸Ģ 楼 +add Class +åĵĪ å¸Į +èµ¶ å¾Ģ +ĠVi agra +åĨħ èĦı +com position +表达 æĸ¹å¼ı +Engine ering +ĠLANG UAGE +Ġcompetit iveness +Ġth umbs +ĠBe am +æŃ£ åIJij +å¾® å¼± +ãĢģ èģĮä¸ļ +ç»ı åĬŀ +ĠH erman +< body +re th +Color ado +ĠEl on +$ m +ç͍ å·¥ +class method +ĠDef initions +ï¼Į åı°æ¹¾ +åľ¨ äºĨä¸Ģèµ· +æĥł æ°ij +/l ibrary +çĥĺ çĦĻ +acc ording +h over +Ġun matched +ĠT ara +çªģåıij äºĭä»¶ +HE MA +ç͍ è¿ĩ +Ġcomm end +åįİå¾ĭç½ij å°ıç¼ĸ +d imensional +ãĢģ éĵ¶è¡Į +åį± æĢ¥ +ĠMalays ian +æŀģ éĢŁ +ground s +ï¼Įåīį éĿ¢ +G arden +un er +以 太 +_p ixel +lex er +é»ijè¡£ 人 +ĠNGO s +ĠS X +Ġconstitu ent +çļĦ é»Ħ +_f p +ig gered +æĺ¯ ä¸įåı¯ +è§īå¾Ĺ è¿Ļ +Ġp ci +ĠP une +ãĢģ æĶ¿çŃĸ +Rem ark +Perm alink +Ġh ires +Ġli bert +æķħ çŃĶæ¡Ī为 +èĩªå·± åĸľæ¬¢ +åĪ· çīĻ +M BA +Ġt ally +é¥®é£Ł ä¹łæĥ¯ +ç»Łè®¡ å±Ģ +åIJĮæĦı äºĨ +Ġpolicym akers +Ġ äºĭå®ŀä¸Ĭ +Ġfl akes +ĠWilliam son +Ġchim ney +ro pping +ĠAss urance +techn ology +åı¬å¼Ģ çļĦ +åħ¨ 社ä¼ļ +erm int +Ġdeb ated +_ ANY +Ġ åIJķ +ĠL ah +ara oke +åĩºçīĪ社 åĩºçīĪ +ï¼Į éŃĶ +ĠP ens +ĠSp ice +-in st +è¿Ŀæ³ķ çĬ¯ç½ª +æĸ° æĺ¥ +è´§ 款 +çļĦæ°´ æŀľ +éħįå¥Ĺ 设æĸ½ +oh a +ãĢĤ åĪ©ç͍ +Ġfam ously +ĠFrank furt +ĠIm mediately +è§Ĵ度 æĿ¥çľĭ +Ġover haul +Ġt bl +Ġver ifying +è§ĦèĮĥæĢ§ æĸĩä»¶ +err no +ç¡® ä¿¡ +Ġparent heses +synt ax +Ġv im +åħ¨ åĨĽ +\ : +aw an +{- # +li que +æīİ æł¹ +Ġtread mill +羣 åģĩ +Ġaut obi +èĥĮ 诵 +.' " +_sp in +âĢľ é»ij +ĠAl a +play ing +Ġincre ments +èĩª æĪIJ +ĠSen ators +å¹¿æ³Ľ åºĶç͍ +ĠPsych ological +Com parator +çĺ ª +âĢľ åıĤèĢĥåĨħ容 +å°Ĩ éĤ£ +assert Same +æ±Ł åİ¿ +Ġinstrument ation +Ġf idelity +ow ment +åĴĮ åĽ½å®¶ +.T oken +ace ous +ĠBelf ast +Sc ot +ĠFacebook Share +ĠX i +ĠAv engers +ĠY uan +ĠRock s +ĠKit ty +Ġbed time +ĠQuant ity +çĤ¹ 亮 +-T V +ãĢĤ 欢è¿İ +ä¸į éĻIJ +课 æĹ¶ +çĸ«èĭĹ æİ¥ç§į +Ġpl ank +æĻ´ 天 +Ġconst ructions +æľª 被 +京 æ´¥ +raft ed +åľ¨ ä½łçļĦ +åı¯ä»¥ åĪ©ç͍ +æĢ ¼ +以为 çĦ¶ +å°±ä¸į åĨį +Ġsock ets +åľ£è¯ŀ èĬĤ +wh atever +ãĢĤä¸Ģ åĪĩ +. change +K h +ĠT ribe +)= ( +Ġmem e +K ay +DM ETHOD +D ur +un ami +æ¶ İ +Ġliber ation +çĹ ŀ +}{ {\ +è¿Ļä¹Ī ä¸Ģ说 +ä½³ 人 +èĻļ 伪 +COD ER +Ġsc ooter +éĢī å®ļ +bb ox +ĠW and +Ġammon ia +or ange +çݰéĩij çŃīä»· +H arm +_p oly +ï¼ĮæĪij们 ä¹Ł +à§ ĩ +溢 åĩº +ĉĉĉĉĉĉĉĉ ĉĉĉĉ +r q +NS Number +b ike +Ġb red +ï¼ĮæĪij们 åºĶ该 +Ġgen ocide +è´´ çĿĢ +.pro vider +Ġun beat +æľŁ 为 +B ullet +O nt +ĠI PT +稳 稳 +Ġwr ath +Ġepoch s +Ġch ords +çļĦ èĥĮå½± +æĿİ çϽ +Ġcounter tops +åĩŃ çĿĢ +å¥ij 丹 +_ : +_se lection +éľ¹ éĽ³ +ĠL ets +æį¢ ä¸Ĭ +Ġdrop out +ĠHam as +R ick +åı¯ åIJ¦ +Ġè¿Ļ æĹ¶åĢĻ +æľĢç»Ī çļĦ +_ platform +Ġf rying +è¿Ī åħĭå°Ķ +ĠP J +ĠSnap chat +åľ¨ åįĬ +"> [ +f ade +èĢĮ ç«ĭ +é¢ł åĢĴ +Ġc aves +Ġv c +ĠRom antic +ĠAugust ine +Ġwe e +/ ****************************************************************************** +m nt +ï¼Į ç§»åĬ¨ +çİ°åľ¨ å°± +Ġther mostat +~ âĢĿ +éĢı å½» +Ġmanufact ures +Tim eline += utf +Ġgloss y +Ġdamp ing +åIJ» åIJĪ +z ema +Ġ 注åĨĮ +reach able +Tele phone +ä¿ Ł +h orse +èĭ± å°º +_CONT ENT +ãĢĤ é£İ +Ġha w +æīį å¼Ģå§ĭ +Ġд лÑı +Ġ æ±ī +Ġf g +ac ro +ĠRem odel +T em +åľ¨ 人 +å½ĵ éĿ¢ +.c at +=" $( +& =\ +å®ĺ çļĦ +æ¶Į åħ¥ +Ġintra venous +rat io +çļĦä½ľç͍ ä¸ĭ +OR A +i ants +äºĨ 大éĩı +_r untime +ä¸Ĭ å±± +åĩº æ±Ĺ +Ip v +çŃī å½¢å¼ı +åĩī çν +è´ŃæĪ¿ èĢħ +å¸ĥ çļĦ +ï¼Įåį´ ä¹Ł +äºĭ åıij +åĩł æĿ¡ +Ġdep ict +ï¼Įä¸Ģå®ļ ä¼ļ +åįģä¸ĥ æĿ¡ +- team +ï¼Įä¹Ł åľ¨ +ocl onal +éļ¾ åħ³ +Ġmount s +; ' +f ew +驾驶 人 +_back ground +æĿIJæĸĻ åĴĮ +æĪij们 å·²ç»ı +Cle arly +çļĦ主 åĬĽ +ç¿© ç¿© +èĢĮæĺĵ 举 +ĠH uge +强 硬 +< ( +缸 æ¯Ķè¾ĥ +an ey +ï¼Į åĪĽ +Âł and +æĹł åģ¿ +ä¿¡æģ¯ è¿Ľè¡Į +éĴ± äºĨ +ĠInf inite +ĠR ational +缸 交 +ĠCon clusions +Ġcher ish +poss ibly +Ġp onder +对æĪij æĿ¥è¯´ +ภª +Ġrot ations +èĬ¬ èĬ³ +责任 å¿ĥ +ĠApp et +Ġf action +Eng land +.google apis +è¯ķ 管 +è¸Ĭ è·ĥ +l ause +IG GER +R ab +ig or +Ġnumer ator +èIJ¨ æĭī +åѤ ç«ĭ +ĠDir ac +ï¼ģ èĢĮä¸Ķ +Ġhero ic +Ġalk aline +Ġprim a +å¿«éĢŁ å¢ŀéķ¿ +æľīæľº çī© +éĹ¯ åħ¥ +C W +ĠT ricks +ĠNow adays +æĿ¥åΰ è¿ĻéĩĮ +v ip +ï¼ĮæĪij 便 +ĠBack pack +æ£ £ +T ARGET +ĠH og +亲 åIJ» +ĠÂłĠÂł ĠÂłĠÂł +æ¯ħ çĦ¶ +Ġl atch +Ġ( âĪĴ +ĠHaw ks +ac in +ps um +éĥ½æĺ¯ çͱ +ĠHer b +v ik +Ġfin er +è¾½ 举 +, éĥ¨åĪĨ +: after +å¥ĩ æīį +ĠCo operation +å®ī举 å°¼ +æĶ¾åľ¨ å¿ĥä¸Ĭ +ĠIn quiry +. byte +æľĢä½³ çļĦ +ld b +_M AT +every thing +æ©ĺ åŃIJ +() }, +au ff +Ext ent +éĺ³ æ°Ķ +Ġprosper ous +审 å®ļ +çĹħ èıĮ +çĩķ çªĿ +ĠGram my +x m +羣 æľī +Ġant idepress +ï¼ĮèϽ 说 +B one +è¿ĩ ä½ł +æµģåĬ¨ èµĦéĩij +/ plugins +代表 äºĨ +EP ROM +/ io +ĠPot ato +çļĦ æľĢé«ĺ +Ġm ama +Ġdom inating +è¦ģ 害 +Ġlam inate +ĠD SP +è£ħ åᏠ+Ġpurch asers +ов ан +Ġa zure +éĻIJ é¢Ŀ +oh an +Ġerect ed +ï¼Į æĪIJäºĨ +urn iture +Document ation +ĠSteel ers +Ġregular ity +ä¸ĭåİ» çļĦ +. constant +ĠMath s +Ġd ew +éĹŃ çݯ +ĠW ax +Ġorgan ise +inn acle +ãĢĤ å¼Ģ +_B UF +Ġpers isted +â Ł +it ory +æĺ¨ å¤ľ +NAS DAQ +ãĢģ 人åijĺ +Ġall ied +注 è§£ +ĠARR AY +M it +ĠClick funnels +èĥ¡ ä¹± +"} ]( +å¦Ħ æĥ³ +Ġnarc iss +æĹł 踪 +çĺĻ çĹĴ +ãĢĤ æĺ¾çĦ¶ +Token izer +ĠL ords +å¯Ĩå°ģ åľĪ +D LL +åĩºä¸Ģ éģĵ +æŁĵèī² ä½ĵ +ĠDis patch +ï¼Į 失 +Ġrespond ers +\ eta +oun s +Ġ 管çIJĨ +ãĢģ èĤī +ç²Ĺ æļ´ +. am +äºĶ åIJį +åī¯ å¸Ĥéķ¿ +( static +j p +Ġfin itely +æĺ¯ 没 +lev ation +ç»´çĶŁç´ł C +âĢľ ä»Ģä¹Ī +èĩªå·±çļĦ æĥ³æ³ķ +-e ight +åıijçĶŁ æĹ¶ +ĠLev y +ĠSp ir +um pt +=" \ +èµĶ ä»ĺ +Ġanaly zes +è½° çĦ¶ +ĠA ircraft +æĬĬ å®ĥ们 +(c all +´ ÃIJ +çĤ ľ +Ġpanc akes +亿 ä¸ĩ +乡 亲 +Draw er +åĴĮ åij¨ +æŃ¤æĹ¶ çļĦ +Ġsn ork +åIJĬ è£ħ +èĩª 驾 +æĴĴ è°İ +çļĦ身 躯 +ĠEss entially +ak ov +-back ground +urs ors +è´¢æĶ¿ å±Ģ +ĠPers pectives +U IColor +acc um +éħĿ éħ¿ +Ġwe ary +ï¼Į以 èĩ´ +ãĢĤå¦Ĥ æľī +æĸ¹ä¾¿ çļĦ +åĭ¤ åĬ³ +èĥ½ è¾¾åΰ +Ġab uses +ĠF emin +åĬŀåħ¬å®¤ 主任 +åħ¨èµĦ åŃIJåħ¬åı¸ +åİĨ ä»» +pub lish +æīĢ ä½¿ç͍çļĦ +.add All +A cknowled +h oe +_h ook +Incre ment +Ġre combination +åIJį å°Ĩ +Ġbook let +Ġfur ious +Ġ{ č +ĠApprox imately +ï¼Į 次 +Ġsock addr +- par +F itness +éĥij å·ŀå¸Ĥ +p ots +åıijæĺİ ä¸ĵåĪ© +æĹ¥ è¶ĭ +ï¼Įè¿ĺ ä¸įå¦Ĥ +Spe ech +J a +Ġ éľį +Ġ à° +ç¥ IJ +京 åī§ +ï¼Į åĹ¯ +åĬł æĿĥ +_ void +Ġt urtles +ĠT ay +ĠPer kins +Ġä¸İ æŃ¤åIJĮæĹ¶ +-d el +ãĢĤ è¿ĩåİ» +æľī æĪIJ +Rec ording +ä¸į ä¿Ĺ +ĠW an +Âł the +åıij表 äºİ +åħ¬åı¸ ä¸İ +Ġmisunder stand +çīĩ åŃIJ +éĤ£ä¹Ī å¤ļçļĦ +æº ´ +Altern atively +ï¼Į èĮ¶ +.H ost +æĭį çļĦ +_S K +ĠF rozen +以 åĮĹ +è¯Ŀ äºĨ +f illed +éĿ¢ç§¯ 为 +èļĬ åŃIJ +åĪĨ åıij +ĠWork flow +Ġprerequ isite +ãĢģ éĩijå±ŀ +Se an +ĠSign ificant +IN O +(p art +@ c +æĺ¯ åĵª +è¿Ļ é¦ĸæŃĮ +ï¼Įå½ĵ ä»ĸ +鸡 汤 +AD IO +çĿ¡ å¾Ĺ +çĭĤ é£İ +Ġpl aster +å®¶ çļĦ人 +ml in +Ġlegit imacy +é²ľ ç¾İ +Ġpair wise +åı¯ è¡ĮçļĦ +ãĢģ ç͵åĬĽ +身ä¸Ĭ ä¸ĭ +å·´ åħĭ +è¡£ çĿĢ +ag us +Ġsh attered +æĭ¥ æĬ¤ +ĠRod gers +t oc +Ġd rap +-d omain +çļ± èµ· +è¿ĺæĺ¯ æĮº +åģľ ç͵ +æĤ² çĹĽ +å®¶ æľī +Ġde co +Ġdev oid +Ġcorrect ing +_fl ush +çľĭ çĤ¹ +Ġcle avage +å¼ł 大 +ä¸Ģ ç±³ +Ġprot ector +.n ative +å°±ç®Ĺ äºĨ +ãĢĤ ç¬¬åĽĽ +IC U +ĠLa unches +å¦Ĩ 容 +Ġa rous +æ¸ħ çļĦ +.P K +éĽª çļĦ +F IX +å¤ĸ å£ģ +ä¿¡ å¾Ĵ +asc ar +ĠDVD s +ç»Ļ å°ı +ï¼Įä¸Ģ çīĩ +èĥĨ å°ı +åIJĮä¸Ģ æİ§åζ +Ġrecip roc +è®® äºĭ +Ġaccret ion +Ġsc ipy +arc in +ä¸İ æľįåĬ¡ +Ġh ier +Ġlect urer +-f inal +èµĦ产 éĩįç»Ħ +Ġdivers ified +æĬĬ éĴ± +èĪª æµ· +âĢĿ ç§°åı· +Ġbus hes +ĠNAS CAR +ï¼Į æ¿Ģåıij +Ġp ouch +åij ¸ +åŁº åľ°çļĦ +ãĢģ åıį +åı¯èĥ½ä¼ļ 导èĩ´ +. å°Ĩ +Ġbab ys +- request +Ġgr ated +ä¸Ģ è§Ī +âĢĻ ) +è¯ģ çļĦ +çªģçł´ äºĨ +Prof iles +, å¹³æĹ¶ +d ash +ĠAthlet ics +[ { +ç¼ĸ æİĴ +çļĦæĥħ æĻ¯ +èĩª 强 +× ¢ +ĠST OP +ç¥ĸ åĽ½çļĦ +cal es +ãĢĤ该 æĿij +ç͍ çļĦæĺ¯ +Ġx p +èĥ½ æī¾åΰ +ĠD ess +per ate +å¼Ģ 端 +Ġcowork ers +_ ec +夸 å¥ĸ +, å½±åĵį +æĬķ å°Ħ +è´© åįĸ +Ġprophe ts +Ġ âĢĿï¼Į +ï¼Į çĬ¹ +æ¯ ¡ +é¸ ¯ +代çłģ çĶŁæĪIJ +åıijåĬ¨ æľºçļĦ +Div ision +ĠLis bon +-w ell +åŃķ æľŁ +ĠClean er +çļ ¿ +ĠE MS +ï¼Įä½Ĩ åħ¶ +Ġimprison ed +éĢļ 天 +æ´Ĺ å¹²åĩĢ +m pl +ä¸įæĸŃ æıIJåįĩ +ãĢĤ 常 +th ren +are na +åľ¨ è·¯ä¸Ĭ +reat ure +_W idget +(h w +Aut owired +.int eger +èħĶ åĨħ +ç¨Ģ 缺 +J en +ç ¸ +ĠT aj +.c or +_S OCK +.D o +Ġabrupt ly +ier re +AS Y +å¿ł å¿ĥ +ĠP W +è§ī æĤŁ +"} ), +^ b +Ġr aster +表åĨ³ ç»ĵæŀľ +g pu +çļĩ åĨł +Ġhyp not +Ġ é¦Ļ +ï¼ĮæīĢ以 说 +ĠCh ow +ĠâĤ ¹ +{ prop +ru pal +åIJij 西 +Âł çİĭ +ecess arily +T on +(f s +Ġforg iven +Ġpel vic +oph obia +æī¶ æīĭ +æįĨ ç»ij +B ird +_ In +ä¸Ģ åij³ +纸 ç®± +Ġpsy ched +åıĮ å±Ĥ +Ġauthent icate +ä»» çͱ +, re +Illust ration +et itions +Ġemb assy +Ġveterin arian +åķ ¶ +çľ¼ èĬ± +SE TT +E ight +羣 åĪĩ +书 ä¸Ĭ +设计 æĸ¹æ¡Ī +èĽĭ é»Ħ +Ġbe acon +ç§ij 举 +Ġbiom edical +Ġnostalg ia +大 æĢĴ +Ġpay outs +ĠMet als +åįĵ æĹŃ +çļĦ æĥħæĦŁ +Ġun secured +ĠAr th +éͦ 绣 +unct ive +ĠP redict +ä¹Įé²ģ æľ¨é½IJ +( ms +_M E +Ġwitness ing +Ġfront s +ĠB earing +æĺŁ ç³» +S orted +i ab +ĠP ension +\\ \ +Ġdraft s +å¿ ¿ +ç¡®å®ļ 为 +ĠPed iatric +(" ../ +æ±Ł å·Ŀ +um ina +ë ŀ +ï¼Į æŁĶ +.h idden +ãĢĤè¿Ļ å°± +ĠExt ensions +ig rations +Ġsc all +ĠK ub +é«ĺ æĺĤ +æĢ» æĪIJ +ãĢĤä¸Ģ æĺ¯ +çϾ ä½Ļ +( connection +h air +çĤ¹ æ»´ +ask ing +å¹¶ èģĶ +.t ensor +ä¸ĢæŃ¥ ä¸ĢæŃ¥ +Det ect +çĽij å±Ģ +æ¥ļ æĪĪ +åª ² +çĶµè·¯ çļĦ +å·¡ å¯Ł +åģľ æľº +ser de +éĻĨ å°ı +离å¼Ģ è¿ĻéĩĮ +æĸ Ľ +Config s +ĠM IDI +[ # +an ine +åĬ¨ ä¸įåĬ¨ +åİĭ åľ¨ +sql ite +pos als +ç¨Ģ æľī +éħ¿ éĢł +: end +AB B +.st ats +è¾ĵåħ¥ çļĦ +åĩĿ è§Ĩ +x ing +ct ed +å¨ ĵ +èģļ é¤IJ +å½¢æĪIJ ä¸Ģ个 +ĠT ate +Ġsuit ability +åģ¥èº« æĪ¿ +ĠAdm iral +{ The +ĠIs abel +ç¨İåĬ¡ æĢ»å±Ģ +integ ration +le ter +rep air +Non User +ĠC annon +- format +Ġprogress ing +ï¼Į åħĪçĶŁ +çݰ éĺ¶æ®µ +ered ith +{min ipage +pl ac +vis itor +Sur v +çŃĶ çĸij +ÙĬ Ø© ++-+- +-+- +Index ed +zz o +Ġre lic +Ġform ations +è®°å¿Ĩ åĬĽ +æ¯ħ åĬĽ +J ordan +flow ers +orph ic +æĺ¯ åIJ§ +_s oc +ï¼Įæľī å¾Īå¤ļ +Ġdop amine +å¦Ĥ æĦ¿ +Ġdownload able +ist o +ru gu +FT A +Ġt ul +_S ervice +och rom +Ġcyt os +Ġslog an +" s +K D +ç²¾ç¥ŀ åĬĽ +byter ian +ĠAn chor +åĹ¡ åĹ¡ +说 äºĨä¸Ģåı¥ +ï¼Įè¿ĺæľī ä¸Ģ个 +è̽ æIJģ +å°¾ 声 +Ġembod ied +M ovies +è¦ģ åΰ +éĤ º +up y +è½® åΰ +ï¼Į åIJĮåѦ们 +å°ı ä¹IJ +å¿ĥ èĻļ +Ġali ases +Ġshrink ing +Ġ åľ£ +ĠU DP +æŁIJ ä¸Ģ个 +Ġ áĥ +ĠC oding +èĨľ çĤİ +F ully +Ġsl ips +Ġexist ential +妻 åŃIJçļĦ +è· · +åĩº å¾ģ +Ġresent ment +Sc r +_ align +Ġmod ulo +ï¼Įä¸Ģ 声 +d ns +ĠS aturdays +ĠGive away +.t race +.trans late +Ġput ative +æĬ± èµ· +建 åĨĽ +åĥı æĪij +è§Ĩè§ī æķĪæŀľ +Ġoccup ations +D ial +al ready +Ġkn ob +T abs +ST S +ĠDar ren +å¤ļ åĬł +è¿Ľ 宫 +ä¹³ æ¶² +ĠPres ence +ãĢĤ å¾· +èĻļ å¹» +ĠCirc ular +ĠActiv ation +ĠBegin ners +ï¼Į è§Ĩ +Ġwe aving +æİ§èĤ¡ åŃIJåħ¬åı¸ +" H +m eter +ãĢģ æ°¸ +Ġarm ies +éŨåı£ çļĦ +Ġdownt urn +èĦ¸ 红 +( link +å½ĵåľ° æĹ¶éĹ´ +Ġ æīĭ +ä¸į ç§» +许 éģĵé¢ľ +夫 çļĦ +ç»ĵæŀĦ æĢ§ +åı¯ å°Ĩ +æĥĬ æĦķ +âĢĿ è¿Ľè¡Į +Ġorig inate +åºĶç͍ ä¸Ń +ĠAli en +ĠB rom +Ġdisp ens +表 å¾ģ +åιéĤ£ éĹ´ +湿 çĸ¹ +fin ish +Ġ ire +åįİ çļĦ +Sp ain +ĠColon ial +ĠB alk +人 åİ» +åĩº 游 +_H andle +辩 è§£ +:b logger +ãĢĤèĭ¥ æĺ¯ +# endregion +}) = +P iece +âĢľ So +Ġpet itions +ĠG ian +Ġunf inished +æī¿ éĩį +gres ql +æĺ¥ 天çļĦ +Ġillum inated +-A meric +Ġp uck +æ¶ ĵ +_p ayload +Ġch inese +Ġdiff ered +ars ity +. UN +æĿİ æµ© +Ġm ash +Ġcapital ize +ĠScot ia +ge ons +Ġcre ams +angu ard +Ġch iral +Ġpir ate +Ġ æ¢ħ +ãĢģ åı¶ +Ġdel ve +ĠMS M +ĠSouth ampton +ĠB are +l ut +start ing +.n il +_L AST +,å¦Ĥæŀľ ä½ł +Ġ éĴ± +ãĢģ ä½ł +Ġr ng +åĴĮ å¤ĦçIJĨ +Use ful +ĠEmploy ers +æ¼ ī +顺 é£İ +Ġheart y +å¾® è§Ĥ +Ġdiscipl ined +Ġsp it +å°ı åĵ¥ +Ġm Ã¥ +Ġfl ora +ç¼ĺ çͱ +n ar +Ġ å·²ç»ı +W ake +Ġe bay +ä¸Ģ æĹłæīĢ +ãĢģ åĶIJ +ï¼Ľ ä»İ +Ġfung us +Ñ ķ +çļĦ éĻIJåζ +Ġinnov ate +æīĵ æ³ķ +ioc re +çļĦ 空æ°Ķ +, å°½éĩı +/ ', +Ġo mission +and les +æĹł éĩı +tag Helper +Ġauthent icated +æıīäºĨ æıī +åħ¬ éģĵ +ï¼ļ æĶ¯æĮģ +ĠS ere +æľĹ 诵 +éģį äºĨ +è·Łä½ł 说 +п ÑĢ +ï¼Į åİŁåĽł +,ä¸į ç͍ +å̼ åĴĮ +æľī ä¸ī个 +åĮĸ åIJĪ +åĶ® åįĸ +ĠLink edin +âĿ ¤ +æĿ¥ åΤæĸŃ +ĠString s +charg ed +å¤į åİŁ +æĸĩæĺİ å»ºè®¾ +æĶ¾ 宽 +è¿ĺæľī çĤ¹ +Ġun st +åıĤåĬł ä¼ļè®® +Ġscientific ally +æ¯Ķäºļ 迪 +? \ +Ġtest Get +èİ« éĿŀ +å® ķ +ĠLy rics +è·ij 车 +ĠU W +ang ling +Fac ulty +ë ł +ĠH OT +å®Ī æ³ķ +缮æłĩ åĴĮ +æĨ Ķ +ĠNa ples +it ates +éĹ® åΰ +ĠLux embourg +_F IRST +se in +co ef +ĠMar ijuana +, éĤ£ä¸ª +两 ä¸ī +æĪij们 ä¹Ł +Ġmit igating +Ġsaf ari +红 èĮ¶ +Ġactiv ates +ĠQuarter ly +>{ @ +Ġn ur +Ġcol orectal +ĠM ai +.c allback +( rt +è´£ æĢª +å®ŀç͍ çļĦ +. one +T emporary +Ġ æķħ +çİĽ ç´¢ +O cean +çĶŁäº§ å·¥èīº +h aven +ï¼ĮéĿ¢ èī² +åį« åģ¥ +åħ¨ 线 +åĬłæ²¹ ç«Ļ +缸 éĢļ +le c +ç§Ĵ æĿĢ +ĠJ ensen +å¹³ æģ¯ +Ġpal p +ç§įæ¤į ä¸ļ +ĠK iller +ĠEx isting +èµŀ èªī +们 ä¹Ł +Ġsummar izes +re ly +ï¼Į æĭľ +ĠR im +lic es +Ġling ering +Ġv eto +b eg +Ġg pu +æµ´ 缸 +æĺ¯ æĢİæł·çļĦ +æĪij åı¯ +åĮħ çļĦ +çģµ çŁ³ +梨 èĬ± +æ·ĭæ¼ĵ å°½ +没æľī 说è¯Ŀ +æĸ° æľĪ +纸 å·¾ +ĠSTR ING +ãĢģ é¦Ļ港 +Rec overy +æĬ¥åijĬ 书 +åįĥ æĦģ +è¿Ł åΰ +Con versation +uch s +Ġiniti ating +ur us +æľĢ éĩįè¦ģçļĦæĺ¯ +æĸ¯ åħĭ +-c ourse +ãĢĤä»İ æŃ¤ +/ "> +ĠM oto +éĢģ åħ¥ +æ¸ħ æ¸ħæ¥ļæ¥ļ +_W ARNING +å¤ļ éķ¿æĹ¶éĹ´ +ç¥ŀ 殿 +çͰ éĹ´ +ï¼Į请 éĹ® +^ c +è° ¥ +-conf idence +/ img +为 åķ¥ +è·¯ ä¸ĬçļĦ +å¤ļ è¿ľ +ä l +çł´ éŨ +ĠJ ail +ï¼Į èĴĻ +æĪij åį´ +Ġwar p +ĠMar in +Class ifier +ãĢģ åĽ¾çīĩ +rem aining +Ġ æ´»åĬ¨ +.d ump +const ants +ï¼Įèĥ½ ä¸įèĥ½ +ĠMid night +-b etween +ä¸Ģ ç§Ĵ +æĬµ æİ¥ +Ð ľ +åĻ ¶ +éĽĨ ä¸ŃçļĦ +ο λ +äºļ å½ĵ +鸣 åĦ¿ +æµĭ 温 +Ġbat htub +碰 ä¸Ĭ +Ġstim ulates +åĨ¶ çĤ¼ +大 åIJ¼ +éĢĢ è´§ +( process +, åıį +M ental +ĠD ancing +ç½ij åºĹ +W ine +ĠMar cel +ĠOrd ered +Hard ware +F raction +ar ction +SP ACE +Ġmisunder standing +ab o +çĶŁ çģµ +Ġaudit ory +Ġmask ing +.cpp reference +Ġprofound ly +ĠW orship +ĠDis abled +æ²ī çĿĢ +ï¼Įç»Ļ 人 +ĠP FN +ä¸Ĭ èµĽåŃ£ +Ġfl ask +丢 å¼ĥ +Ġcloud y +/ dis +ĠJ PEG +ĠInter val +ĠDef ender +æłij å¹² +æĵ¦ äºĨ +Ġtight en +ä¹Ķ 丹 +å¤ļ 头 +Ġtime zone +夫 åŃIJ +å°ĺ åľŁ +Pop ulation +rocy tes +ï¼Į åĨµä¸Ķ +ãĢ ĸ +itt al +åħ¶ä»ĸ 综åIJοͶçĽĬ +稳 éĩį +Ġè¿Ļ个 æĹ¶åĢĻ +Ġsurre al +os al +çľ¼ å¸ĺ +ĠCor ollary +ĠMaj esty +Ġ å¸Ĥ +ï¼ Ĭ +Ġo zone +Ġper i +Ġmatch up +éĴ» è¿Ľ +ĠN ail +Âł å°ı +. ec +Ġcongrat ulations +D ocker +_F IX +Ġcontempl ating +ĠM SP +ç»ı 绾 +il ience +å®¶ åľ¨ +Lead er +å¢ĵ åľ° +S UP +æĻ¯ æ°Ķ +IM O +Ġä¸į éĢĤç͍ +æģ Ļ +ç»Ļ å®ĥ +æĿĤ èįī +èĥ½ åģļåΰ +Ġhom ology +ãĢģ è¡Į +æĹ¥ æŃ£å¼ı +ĠLy on +Ġn pm +æľ¨ è̳ +æĮ¡ ä½ıäºĨ +èĥ½ ä¸İ +ĠSav age +< Type +pp i +Ġcontrast s +è¿Ļ åı¥ +åħī 头 +Ġembarrass ment +交 åĵį +Ġrad iant +Ġhone ymoon +\ partial +çļĦ ç̧ +è¾ħ æĸĻ +ham mer +éģį åľ° +æ·»åĬł åΰ +. ones +ï¼Į æĻļ +Ġsimpl ifies +Ġcommut ative +.Back ground +A ustralian +vel yn +Ġbl k +emon str +ĠPut ting +ĠB orough +ield ing +女 è¶³ +ãĥĥ ãĥĪ +çĥŃ çģ« +W s +é ¤ +ï¼Į éļĶ +ĠI k +Ġst alls +ĠZ hou +æıIJä¾Ľ çļĦä¸Ģç§į +, å¤ĸ +éĴ» åŃĶ +åīį ä»» +å¾® åķĨ +åı¯ä»¥ åģļ +.s ummary +_C LOCK +çļĦ 设置 +ĠL DL +^{ * +col our +åįĬ çIJĥ +åIJij æĪij们 +Ġhead ings +ĠEnh anced +Y G +he ed +ï¼Į ç͵è¯Ŀ +Ġo sm +æŃ£ å̼ +ĠSe ah +z w +ãĢĭ è§Ħå®ļ +ophage al +Im plicit +竹 æŀĹ +ap os +Ġsumm aries +Ġpolar ity +Ġsal ty +çĦ ¯ +æ©¡ çļ® +Ġdip ole +.init ial +å®ī å®ī +éĢģ åĩº +ĠCoun c +æ¯į 女 +Ġc uff +æĹ¥ 为 +Ġsk irts +è¿· 宫 +å°± ä¸Ģ缴 +ä¹Į äºij +ï¼Ł èĢĮä¸Ķ +Ġcoh orts +Ġ第åħŃ ç«ł +Ġp udding +ãĢģ æ¶Īéĺ² +ä¸Ĭ 岸 +Ġend omet +è¿Ŀæ³ķ è¿Ŀè§Ħ +éĻĨ åľ° +奥 å°Ķ +AND ARD +cess ions +Ġwidth s +å¾Ĺ çĽĬäºİ +ĠQu art +vere tt +ce phal +åĩł å¹´æĿ¥ +ç»Łæ²» èĢħ +空 èĻļ +Ġrul ers +ï¼Į 表çݰ +çĵľ åŃIJ +C itation +l ayers +Ġcort ic +ĠCollabor ative +ĠLex ington +-s uccess +ĠR ough +å°Ĩ æĮģç»Ń +- ag +Ġdown hill +ï¼Į éĺ³åħī +ä¿ IJ +éķ Ĥ +建 æľī +æ´» è¡Ģ +è¾¹ å½¢ +Ġmed iator +urd en +åĮ»åĬ¡ 人åijĺ +ä¸ĭ æĸĩ +çļĦä¸Ģ åijĺ +/p erson +è½° 鸣 +çļĦ å¾®ç¬ij +èµ Ĥ +ä¸Ģ次 次 +åĩĮ äºij +Ġmund ane +çļĦäºĭæĥħ äºĨ +沪 æ·± +æĽ² å¼ł +éĢł åıį +Ġdepend ents +èĩªå·±çļĦ åŃ©åŃIJ +Ġdevast ated +TH ON +ĠD oyle +ä¸Ģ çŃī +ãĢĤ åħ·æľī +æĺ¯ åĴĮ +Blog s +çļĦ身 åIJİ +èĢģ å®¶ä¼Ļ +åIJ¬ ä»ĸ +éĤ® 票 +p ure +ĠHun ger +Ġsew age +åłķ èIJ½ +æľīä¸Ģ èĤ¡ +ros ine +ä¸ĭ åıij +Reg ional +天çĦ¶ çļĦ +éĽį æŃ£ +ĠJun gle +Ġz ombies +çĽĺ æĹĭ +.get X +part icularly +ĠT ulsa +æľ¬ çİĭ +ï¼Įä½ł åħĪ +Ġpot tery +t ick +çļĦ åĽ½éĻħ +åĪĨ æĭħ +ï¼Įè¿Ļ äºĭ +_SPE ED +C b +æĪij ä¸įæĥ³ +ĠNot ify +re k +Ġlow ers +ĠAndre as +. He += yes +ax on +èĤ¥ çļĤ +ACT OR +Ġh t +Ġst ag +.t ex +lean or +Ġbott led +Ġ æİ¥ä¸ĭæĿ¥ +Ġdo omed +åĬł åĪĨ +æ»ij è½® +ï¼Į åģĩ +ĠS ung +ĠTe eth +aggreg ate +ĠâĨ ĵ +ãĢĤ é¾Ļ +Ġn atives +ub ber +igh bour +é³ Į +ĠPerson ality +ISS ING +/ std +j oice +çļĦ åĩłä¸ª +.C lick +åį« æµ´ +ĠJ M +, æĹ¥æľ¬ +ï¼Į åᢠ+ĠFl int +çļĦç¬ij æĦı +(Int Ptr +. Identity +_ ctl +f ed +comm ission +.B oolean +AM ILY +ãĥ ¥ +il ian +å®Ī ä½ı +çĶ³è¯· 表 +Ġcasual ties +ãĢĤ å±± +ĠH os +è¿İ åIJĪ +Ġmitochond ria +Sm ooth +_f ast +é¹ ¦ +ĠAss ess +Ġre but +åIJİçļĦ 代çłģ +Ġtrans istor +åİī害 äºĨ +ĠAdvoc ate +æ¯ĭ 庸 +Ġcaptiv ating +ï¼Į æĻ® +è°ĥæķ´ 为 +è®¤çľŁ åľ° +(f ull +ï¼Ľ 第ä¸ī +ä»Ģä¹Ī éĥ½æ²¡æľī +ãĢģ åĦ¿ç«¥ +éĩij 丹 +Ġsacrific ed +ĠW iring +Ġins ulated +Ġadapt ations +ĠHon estly +ï¼Į 段 +ĠV IDEO +ĠQ A +æ´Ĺ æ¼± +Ġturb ines +åĽ Ķ +管 æĿIJ +Und o +Ġdist ressed +ä¸į åĪ©äºİ +Ġk ettle +Ġun att +亲 æľĭ +n al +ï¼Į大 声 +纯 æĶ¶åħ¥ +Ġhar bour +, è¾¾åΰ +å®Ī çĿĢ +Ġexpos es +Ġ å¼Ģå§ĭ +Ġas ymmetry +Ġsacrific ing +_ upload +人 éģĵ +æķijæĬ¤ 车 +à ½ +ĠâĿ ¤ +ĠC md +å¥ Ħ +ç¾İ æĦŁ +èĢģæĿ¿ å¨ĺ +Med line +Ġgym n +åºŁ æĹ§ +âĢĿ æĿ¥ +Ġtool kit +æĺ¥ å¤ı +V en +å¼¹ èᝠ+è¿Ŀ 竳 +(j ob +H ay +Ġdirection al +Ġgly c +. That +bra him +ï¼Įå¦Ĥæŀľ æĤ¨ +< F +g rowth +ç»Ļ åĬĽ +èĥ°å²Ľ ç´ł +ĠG arn +sp ath +让 åĪ«äºº +Class Loader +çĨŁ çŁ¥ +Ġstake holder +Z N +Ġ ä½łçļĦ +ra ised +how ever +Ġery th +ãĢĤ åį³ä¾¿ +_ selector +ĠT ou +ï¼Ł è¿Ļ个 +, è®©ä½ł +ĠB IO +å®ŀæĸ½ çļĦ +Ġaer ospace +Z n +ç¼ ® +èµĽ åĮº +ä¾į 女 +ĠOB JECT +opor osis +Ġbit ing +ä¸įåıĺ çļĦ +Ġtr ays +ãĢĤ æ¯Ķ +亦 æľī +ĠGib bs +( Un +åĽ½ è¶³ +)) **(- +Ġ ä¸ĭéĿ¢ +åİ» æĥ³ +ä¸İä¼Ĺ ä¸įåIJĮ +Ġgl ued +ASC II +Ġn ie +yl abel +Ġrespons ibly +åħĦ éķ¿ +Wonder ful +m peg +Ġpr udent +AR GE +Ġanonym ity +ĠMo ist +Ġcart oons +G rab +x ref +ï¼Į åŃ©åŃIJ们 +ä¼ģä¸ļ æīĢå¾Ĺç¨İ +ĠRem ed +Ġdec ays +å®ĩ èĪª +_t bl +Ġmanag erial +Ġ å¾Īå¤ļ +ãĢģ èĩªçĦ¶ +Ġtar iff +åĪĨ 娩 +Ġair flow +ĠIm plications +ï¼Į è¿ijå¹´æĿ¥ +ï¼Ī 约 +æī¾ å·¥ä½ľ +Ġconsolid ate +æĦķ çĦ¶ +ĠN AV +Ġ åıij +mm mm +Ġattack ers +Ġeth n +çĹ ¤ +çĶŁåij½ åij¨æľŁ +_per cent +G ov +cell s +ãĢģ åįĹ京 +Ġc arts +ï¼Į æĶ¹åıĺ +çļĦ身 æĿIJ +ï¼Į æĻ®éĢļ +ä½ľ å¼Ĭ +Ġbook store +ĠFront ier +/lic ense +S ampler +T ue +ä¸ĵä¸ļ å§Ķåijĺä¼ļ +ï¼ĮåħħåĪĨ åıijæĮ¥ +ĠCon nor +éĻĨ ç»Ŀ +å®Įåħ¨ ä¸įåIJĮ +Ġl akh +éĢīæĭ© ä¸Ģ个 +åĸĿ çĿĢ +Ġhorn s +Ġsumm ed +. Init +, åħħåĪĨ +ãĢģ ä¿ĿæĬ¤ +Ġion ic +, ä¸Ĭæµ· +åĨĽ æł¡ +ĠJos é +Ġw ie +没 åķ¥ +cr umb +W ITH +ĠBill board +- plan +ĠAud ience +ĠP SA +æļĸ åĴĮ +Execution Context +Ġhead quartered +æİĪ ä¿¡ +@ ", +Ġ Ø§Ø +ill or +顾 åıĬ +ï¼Įå½ĵ ä½ł +ภ¢ +Ġhyd rated +好 åIJ¬ +} > +ĠJ ade +éĤ£ 段 +ĠGree ks +åij½ä¸Ń çİĩ +E sp +Ġlocal Var +åİ¿ åħ¬å®īå±Ģ +Ġl ame +æķ ¸ +ric ht +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +磨 ç»ĥ +.. " +缸 èģļ +ç»Ń 约 +Ġcast s +Ġske ptic +ï¼Į åĪĨ享 +Ġth ieves +ĠFrid ays +æĬĸ åĬ¨ +Ġrel apse +, çζæ¯į +æī¾ 寻 +yl ie +åºı å¹ķ +f requency +éĶħ åĨħ +ãĢĤ éļ¾éģĵ +Wi Fi +ĠRen o +Ġearthqu akes +? s +æ°´ åŁŁ +ĠEx terior +ĠTim eline +åĭIJ çĥĪ +ï¼Įä»Ĭ æĻļ +ĠGuate mala +æ¿Ģ èµ· +åĸĿ çļĦ +Ġc ron +é¢ Ķ +çł´ 绽 +pl its +Text Color +çŁŃ è¯Ń +éħ¸ çļĦ +ĠExpl oration +ç¾ŀ è¾± +Program s +è°ĥ çļ® +éĩĩç͍ çļĦæĺ¯ +Ġbroad en +Ġcontrad ictory +Ġ_ ) += A +å¡ijæĸĻ è¢ĭ +h ra +ç¾İ åij³çļĦ +S in +Ġdiscour age +å¤ļ äºij +Qual ified +Ġwork around +(c ell +ĠOp ens +Serial izable +æķĻ å¾Ĵ +请 注æĺİ +=\ { +Ġaccomp anies +éĢĥ 亡 +Ġmanip ulating +osex uality +æĹ© èµ· +ĠProb ability +ĠN EXT +Ġvig orous +, æ·±åħ¥ +ĠN ets +æĹ¥ 线 +Ġ éħĴåºĹ +W AY +und e +çļĦçĶŁæ´» æĸ¹å¼ı +æĮ½ æķij +ĠHaz ard +ãĢĤ æĥ³è¦ģ +he p +Ġ? >" +Ġancest ry +XXXX XXXX +è¿ĺæĺ¯ éĿŀ常 +.Un marshal += $\ +åĩŃ ç©º +奢ä¾Ī åĵģ +ĠRe ceived +as us +: type +New ton +ï¼Į对 ä»ĸ +PL ACE +F UL +G ra +ĠM its +ãĢģ åİŁ +æĸij çĤ¹ +æİł 夺 +ï¼ĮæĪij å°±æĺ¯ +ĠCom position +_M odel +ï¼Į å·¦åı³ +åģ ĥ +Ġecho ed +Default Value +/t ools +v ier +ĠN amespace +被 åıijçݰ +ĠL IN +ON ENT +Ġåı¯ æĥľ +ĠHaz el +åĮĹ æĸĹ +ĠHy de +æľ¬ æ¡Ī +çŁŃ åıij +,: , +ï¼Į éĩĮ +çī¹ åħ° +AC P +é¡¶ çĤ¹ +OM A +usp ended +Ġimpe achment += https +at ore +ĠB ead +è¿Ļ åľºæ¯ĶèµĽ +Ġkn ight +ĠSH OW +ä¸įè¿ĩ æĿ¥ +ï¼Įä½Ĩæĺ¯ 她 +åľ¨ æĹģè¾¹ +. tt +触 åĬ¨ +Ġb ans +ï¼ī âĢĿ +cal culate +.g r +Qu otes +in ode +Ġinteg rations +éĺ» åĩ» +YN AM +ä¼ļ æł¹æį® +ä½ł æĺ¯ä¸įæĺ¯ +è¡£ é£Ł +èIJ§ èIJ§ +G h +\ (\ +红 å°ĺ +åĪĨ åŃIJçļĦ +æĽ´ éķ¿ +ï¼ģ ï¼Ī +Ġ ...... +âĶĢâĶĢâĶĢâĶĢ âĶĢâĶĢâĶĢâĶĢ +Action Bar +ĠCG Point +ï¼Į åħ´ +æĸ° éĻĪ代谢 +ĠRes olve +å¥Ĺ æİ¥ +ĠRet riev +åĪĿ æģĭ +mod ify +-ed uc +M ozilla +Ġvolunte ered +Car l +Ġmin ced +éĿĻ çļĦ +prot oc +ĠRoot s +ĠH ate +è¿ĺæĺ¯ 个 +çİ°åľº çļĦ +- under +ãĢģ ç½ijç«Ļ +b red +æĸĩåĮĸ æĹħ游 +èģĺ ä»» +Ñĥ Ñĩ +ä¸Ķåħ¶ åıĺåĬ¨ +带 åħ¥ +èıľ çļĦ +ĠA CA +ãĢģ è¡¥ +ĠB onds +综èīº èĬĤ缮 +ĠCont ributor +Aff iliate +ì ľ +_f unctions +é¸Ń åŃIJ +ç®Ĺ å¾Ĺä¸Ĭ +Ġsel ves +Compat ible +çŃī æĬĢæľ¯ +SS H +æĺŁçº§ éħĴåºĹ +. Output +]^ . +å°ı 溪 +}\ ,\ +ĠAtt ach +é¾Ļ头 ä¼ģä¸ļ +( ext +é¸ ½åŃIJ +游泳 æ±ł +P as +× © +Ġm ourn +ĠC lement +Ġcl aw +æĮĩ导 æĦıè§ģ +/ text +çľĭåΰ ä¸Ģ个 +ĠList ening +_V ENDOR +ï¼Į è¯Ŀ +ï¼ī ãĢĬ +èĩªå·± åĸľæ¬¢çļĦ +çľī头 ä¸Ģ +Foot ball +d uring +ĠC ros +Ġorn ament +Ġcre st +Call er +Ġre acts +ĠKa plan +Y O +ï¼Į éĽĨä¸Ń +_f ront +-b eh +Ġas hes +æĶ¯ æī¿ +Ġa ortic +.M ain +umb a +ĠĠ ³³³ +ĠF AST +åIJ« çĿĢ +è¿ĩ çĿĢ +æ³ķ 令 +çī¹ å·¥ +ĠBron x +b lob +ac ock +Ġbu oy +ç¬ij åĺ»åĺ» +ï¼Į æĽ° +Ġg utter +.S imple +< $ +OUT H +s orry +Ġlun ar +ä¸Ģ åīij +ä¸Ĭ ä»» +rec ipe +æŃ£å¸¸ è¿IJè¡Į +ï¼Į请 æł¹æį® +Ġretal iation +å°± å¤ŁäºĨ +ä¹ĭ è¾Ī +åIJİ å®« +Ġmalf unction +Ġdis sect +çħİ çĨ¬ +æ¸ħ åģ¿ +ãĥ¼ ãĥ« +W a +éĵ Ĩ +åĨ² åĩº +Ġsleep s +ãĢģ è§ĦèĮĥ +éĶ µ +车 éĢŁ +项 ç¾½ +aut ical +æĪIJåĬŁ çİĩ +çī©è´¨ æĸĩåĮĸéģĹ产 +{ def +- log +常 人 +ç»ĵ è¯Ĩ +绣 å¸ħ +æĸ°éĹ» åıijå¸ĥä¼ļ +ind i +olith ic +, æµ· +Ġ 缴æİ¥ +æĺ¯ æĪij们çļĦ +æĹ¶ éĻIJ +ĠV ital +ed ited +D rug +av o +Trans actions +l ite +Nut rition +_s izes +å¦Ĥæŀľ 说 +åij¨ äºĮ +ç«ŀäºī åĬĽçļĦ +ï¼Įä½Ĩ åıĪ +éĢĢ è¿ĺ +Seg ments +太æŀģ æĭ³ +çļĦ 第ä¸ī +çİĭ çīĮ +: absolute +çļĦ çļ®èĤ¤ +] $. +ï¼Į çĥ§ +è¿ĩ 人 +åı¶ æŀ« +Ġreal ism +(n n +ĠLand sc +åģļ å·¥ +çªģ åĽ´ +ï¼Į大 å¤ļ +y b +ĠNew ark +æ¯Ķè¾ĥ 大çļĦ +æĦŁåΰ å¾Ī +Enc rypt +[ offset +ï¼Į åıĺå¾Ĺ +um ulative +-t ax +Ġpe e +Ġsm ash +Ġent itlement +éĻ¢ éĩĮ +Ġsn aps +.se ed +ãĢģ ä¼ļ计 +Ġshot gun +Ġh olog +ĠP iet +åĺ Ī +Ġ èĸĽ +Ġs emic +ä¾§ éĩį +æºIJ æ³ī +Ġdeg eneration +Ġmass ively +ĠTo oth +/s ervices +ãĢĤ äºij +ĠA SD +/p ub +ĠTurn ing +æĤĦæĤĦ åľ° +v u +Bal ancer +In str +åĽĽ 个人 +æļ´ èºģ +Ġâĸ ª +ãĢģ éĢļè¿ĩ +Ġunreal istic +ĠD iaz +_f un +亲 çĶŁ +ãĢģ æ±Łèĭı +Ġcomp el +ï¼Įæĥ³ æĥ³ +çļĦ èµĦæĸĻ +ä¸ĭ åįĬ +对 ä¸Ĭ +! ", +. owner +Ġë ° +Ġv ested +åħ±äº§ åħļåijĺ +Ġf ittings +à® ¿ +åΰ ä¸Ģèµ· +ĠV L +æ´» åľ¨ +Sh a +æĺ¯ é«ĺ +åĪĢ çļĦ +âĢ ł +讲 课 +Ġchlor ine +ĠA ren +å»ī ä»· +ç͍ ä¸Ģ个 +-b lack +Ġsur rogate +IN DEX +(p attern +åĨľä¸ļ 大åѦ +éĹ² èģĬ +ec ake +ãĢģ ä¹Ŀ +åIJĥ çĤ¹ +è¿Ļ èĤ¡ +ä¸Ń éĥ½ +B at +Ġb orough +ĠVI EW +, å°ıç¼ĸ +ik ers +ĠSh an +B ell +ans w +ç¬Ķ 墨 +ĠComput ational +Ġpolar ized +å°Ĭ è´µ +t rip +el m +ĠMotor cycle +et us +缸 åħ¬ +éĽĨ è®Ń +}} < +å·² ä¹ħçļĦ +èĢĹ æĹ¶ +ï¼Į æĭ¿èµ· +çī¹åĪ« 好 +Ġneon atal +G em +ĠM MP +ĠPl ane +uit ively +ä»İ 没 +ภĦ +s aved +ĠLim its +çͲ çĥ· +ĠScre ens +ä¸Ń èİ·å¾Ĺ +æįį åį« +Ġk os +.p ar +- aff +ĠSl ice +Ġsp i +å¸Ī éķ¿ +æĿij éķĩ +帮 æīĭ +b ilt +è¿İ éĿ¢ +è¯ © +Ġst ale +Ġ(! _ +åijĬè¯ī 大家 +. Array +ĠL ob +Ġbright est +ĠRed s +Ġail ments +EN E +Ġkiss ing +_C AL +Ġspecial ised +Ass ociated +å¿ ĸ +Ġk inetics +æĬ¬èµ·å¤´ æĿ¥ +åij¨ åΰ +Ġbirth s +Ġuncon ventional +çļĦ ä¾§ +,å°± åı¯ä»¥ +Ġz ipper +çļĦ æľ¬è´¨ +奥çī¹ æĽ¼ +R J +Ġs alsa +ĠRep resentation +ĠComp iler +é¡¶ å±Ĥ +ls en +è¿ŀ ç»ĵ +Sw ift +Ġ ä¹ĭåIJİ +ĠL ime +å¢ŀ 设 +éģ¥ éģ¥ +/ add +_p cm +' { +èĤ¿ èĥĢ +Ġ åŃ¦ä¹ł +è¦ģ åħĪ +Ġspect ators +éŁ³ä¹IJ ä¼ļ +_EX EC +ä½ľ åĩºçļĦ +éĺ² åį« +丰 èĥ¸ +çα åIJĥ +ĠAd missions +Ġathlet ics +Ġcell ar +å¼Ĥ çī© +Script s +Ġpolymer ase +) this +ĠS oy +ï¼Įå°± å¿ħé¡» +Ġdis ob +ĠEmp ower +, åĵªæĢķ +ï¼Į 第ä¸Ģ个 +羣 æ°Ķ +.S chema +Ġnec rosis +ĠM ud +ä¹ĭ 说 +æijĨ 设 +ä¼ļæľī æīĢ +å£ģ åŀĴ +ç»ıéªĮ 丰å¯Į +Ġh ors +ĠK ah +éĹ² çĿĢ +-sm all +æĹł åĩł +Ġyou re +-d ose +ĠDead line +bit map +Ġrival ry +t abs +ĠT ao +ab er +è´¢åĬ¡ æĬ¥åijĬ +ä¸Ģ 天çļĦ +ĠHon ors +Activ ate +( any +[ + +_ assign +æĢ» æĺ¯åľ¨ +Ġevac uation +St orm +ĠC ors +ãĢĤè¿Ļ个 æĹ¶åĢĻ +èĢģ头 åŃIJ +ä¸į ä¹ı +人 å±ħ +ĠStruct ures +s oc +æĺ¯ 人类 +æĶ¶è´¹ æłĩåĩĨ +æĤ ĸ +_M OVE +.Hash Map +(" : +çĬĢ åĪ© +æ¿ ® +åĩ¹ åĩ¸ +åIJİ æİĴ +ĠAg u +æł Ģ +Ġret ract +èı² åĪ© +-T erm +IM G +ï¼Į 表æĺİ +âĢĶ is +æĴij çĿĢ +æ²¹ æ°´ +ãĢĤ æľª +ä¸ĭ ä¸Ģ次 +åĽ¢ èģļ +Ġscr atching +åĬł èµ·æĿ¥ +æŀľ åĽŃ +_f ace +ĠFe eling +ĠDi ary +çļĦ èµĦæºIJ +.m an +ãĢĤ 没 +v ette +y re +æİ¥ æīĭ +çĿ¡ è¡£ +æĸij æĸĵ +ï¼Į å¯Į +Ġinert ia +) âĢĶ +/ list +_l v +å¤ļ çĤ¹ +èģĶ æĥ³åΰ +ĠM TV +Ġsign ifies +_ operation +ï¼Į 丰å¯Į +æijĦæ°ı 度 +ï¼ĮèĩªçĦ¶ æĺ¯ +ph on +æħ µ +å®īåħ¨ 管çIJĨ +appe ar +yst ore +æīģ å¹³ +_ OT +ad ay +ãĢģ æĹ© +yst e +-h ole +æŃ£åľ¨ è¿Ľè¡Į +äºĨä¸Ģ æĿ¯ +è¶ħ é«ĺ +æĦĪæĿ¥ æĦĪ +âĢĿ ä¸Ģ声 +.st rict +. Zero +æĿ¥ éĢīæĭ© +}} ^{\ +Ġdefe ating +_count s +o iler +Ġteasp oons +R ou +i ota +Pr ince +æĿ¡ çļĦ +AS IC +ç¦ı çͰ +æ²Ļ æĭī +INST ALL +ĠN AD +失 åĪ© +Ġmouth s +\ mid +ï¼Įæľī åħ³ +{t ikz +(' : +UN G +ch rom +她 ä¼ļ +_f ixed +_C LEAR +éĥĬ åĮº +B V +L it +ĠW D +_M sk +< b +Main tenance +ĠÑĢаР· +æľºåύ 人çļĦ +ï¼ļ æĹł +ç¤ ´ +-h uman +ĠH IP +éĥ½ 对 +D omin +m Ah +ãĢĤ åĪļ +åıį åĵį +Fl a +j am +Com mission +ãĢģ éĩįçĤ¹ +Ġmat uration +æľī è¯Ŀ +çħ§ èĢĢ +ĠPay ne +èĥ½å¤Ł å°Ĩ +èĥ½å¤Ł 帮åĬ© +ĠGu er +rus ive +Ġtrou bling +Ġcohes ive +.b its +åIJĦ个 æĸ¹éĿ¢ +æ¯Ĺ éĤ» +ĠL iteral +éĥ½ 以 +éħ¸ 碱 +ĠGen etics +æĹ¶éĹ´ åİ» +Ġfact o +Ġsection al +çļĦ人 ä¹Ł +ero on +èĤ© è´Ł +pt une +ï¼Įæľī 个 +ĠSp ins +Just ice +ä¸Ĭ 楼 +æĺ¯åIJ¦ 符åIJĪ +ä¼ļ æ¯Ķè¾ĥ +â̦ . +ãĢĤåĽł èĢĮ +宽 广 +çıį èĹı +Ġcart ridges +éĺ³ çļĦ +Ġbad ges +ï¼Įå¸ĮæľĽ èĥ½ +åı¯æĢľ çļĦ +Ġr r +ĠKat rina +ï¼Įä¸į 代表 +天èĬ± æĿ¿ +Ġsilhou ette +代 åĬŀ +é¢Ĩ çĿĢ +G RE +s alt +çļĨ æľī +Ġspo iled +Ġd ns +缣 åıĭ +Ġ çľĭæĿ¥ +祥 åĴĮ +åħħ æ°Ķ +ĠMin istries +" When +_ cons +Ġmult im +Ġ çϾ +ĠC REATE +Ġget Value +åŁİ åįĹ +ĠOr t +(m atch +ï¼Į åıĺ +qu el +(s aved +ĠÏ ħ +Ġstack ing +æ¿ĢåĬ± 计åĪĴ +Ġ( £ +车 åºĵ +Ġglobal ization +å³° çļĦ +Ġan k +Ġprompt ing +Ġhurd les +Ġimp atient +Ġrem ix +ĠRep resents +Z en +é¦ Ģ +ãĥ ģ +( location +åı² å¯Ĩæĸ¯ +æķ¬ 佩 +Ġw aved +z x +带 åΰäºĨ +äºĨä¸Ģ å¹´ +Ġdel ine +tr an +ĠCon current +å¤ļ æĹ¶ +åĨį 好 +æİ§åζ æĸ¹æ³ķ +Ġpermut ations +.Debugger NonUser +æĢĿ ä¹ī +ĠAd option +ĠFull er +Old er +å°ı äºĨ +ĠReg ex +ĠN ile +k id +co ords +ãĢģ 广åijĬ +.n orm +æį§ çĿĢ +æĿĤ 交 +è¦ ĭ +( ct +æĸŃ è·¯ +ĠText View +Ġwithd rew +åĴĮ æīĢ述第äºĮ +ãĢģ ä¸ĥ +max t +ï¼Į åģıåģı +B loom +æŀĦ åĽ¾ +Ġwor sh +Ġsyn aptic +æĦŁæŁĵ çļĦ +é«ĺ 大çļĦ +妥 å½ĵ +缴 å¥Ķ +åı° ä¸Ń +åĽŀ èį¡ +-de vel +Ġ éľĢè¦ģ +Ġb x +çĽij管 éĥ¨éŨ +Ġconting ency +ç©¿ çĿĢä¸Ģ +s ales +è® · +åºĹ 主 +ï¼Į å¾ĹåΰäºĨ +ch u +ĠQ ing +.Se cond +è§ģ ä½ł +_ utf +åѦ 好 +å¼Ģå§ĭ åľ¨ +Ġtut ors +èIJ¥åħ» ä»·å̼ +________________________________ ________________________________ +å¹³æĹ¥ éĩĮ +l ots +åħ¬ æľī +æ³Į å°¿ +æĹ¥ æĬ¥éģĵ +ï¼Į P +ĠH ipp +pl asia +æĶ¿åºľ éĩĩè´Ń +âĪ Ĥ +ä¸Ń 年人 +p aid +æİ¥ åĬĽ +.d type +åºķ éĥ¨çļĦ +ç¨ĭåºı çļĦ +N AP +hat t +çĥŃ å¤ĦçIJĨ +æĸ¹å¼ı è¿Ľè¡Į +æ»ĭ çĶŁ +ĠGodd ess +B UFFER +ãĢģ èĤ¾ +èĩ³ é«ĺ +-re viewed +ä¼łæĦŁ åύçļĦ +çĨĦ çģŃ +Ġfare well +_ avg +é£İ æ°Ķ +Ġdel ves +ï¼Į è¡¥ +ä¾Ľ å¥ī +西 çº¢æŁ¿ +åŃĺ åıĸ +Ġ åį³ä½¿ +æĿ¡ä»¶ åĴĮ +转æį¢ åύ +_PARAM ETER +读 è¿ĩ +Y D +ĠLoc ale +çİĩ è¾¾ +ĠAnal og +ĠSoph ia +éĤ Ĥ +ĠGPL v +-a uth +ĠD ix +Ġcour teous +( abs +ï¼Į åĬ¨ä½ľ +.p ow +ï¼Į æĭħä»» +Ġb ile +éŁ³ æķĪ +线ä¸Ĭ 线ä¸ĭ +oth s +âĸ º +Ġlymph ocytes +? is +min or +ï¼Įè¿Ļ 个人 +æĶ¶ ç´§ +, äºĨè§£ +pp o +ĠPl asma +æĪĺæĸĹ ä¸Ń +æıIJåΰ è¿ĩ +k ick +.d iff +ï¼Įåľ¨ æīĢè¿° +/ modules +< x +Ġover he +Application Context +.l anguage +åİ¿ 人 +omed ical +èµ° åħ¥ +éĢĤ äºİ +Ġextrem es +èıģ èıģ +Ġin land +åıĪ åIJį +代表 æĢ§çļĦ +Ref und +æŃ£å¸¸ å·¥ä½ľ +ĠH alo +Ġ( ($ +ĠP unch +Tr ading +, æĻļä¸Ĭ +çģ¾ åĮº +æ¯į åŃIJ +éŀł 躬 +( axis +çļĦä¸Ĭ 端 +Ġdia per +èĶ ¼ +åıĤèĢĥ æĸĩçĮ® +ä¸ŃéĹ´ çļĦ +ï¼Įä¸Ģ åľº +æ¶Ī çĤİ +æľĢæĹ© çļĦ +ĠTr in +说 ä¸Ģä¸ĭ +CON CLUS +Ġdis closures +ĠS Q +cul us +de leted +è¯Ń è°ĥ +åĵįåºĶ äºİ += ', +ĠA jax +é£İ ç͵ +Ġimpe cc +Ġ< # +å®īè£ħ åŃĶ +Ġinf erences +, åĽ½åĨħ +ãĢĤ åŃ©åŃIJ +转 åĽŀ +ãĢģ 交æĺĵ +ax ial +ðŁ Į +Ġcens orship +F emale +о Ñĩ +ĠF ault +Ġj ac +çĹĽ åĵŃ +çļĦåĨħ å£ģ +Ġembry onic +ĠV ince +çŀª 大äºĨ +ĠSh am +_S INGLE +ĠScholar ships +Ġforesee able +å²ģ 以ä¸Ĭ +è½® æ¤ħ +æĹł ç͍ +Ġdi apers +,æĺ¯ åĽłä¸º +h f +Elements By +ãĢģ ä¼ļ +è·¯ äºĨ +çľ¼ åľĪ +åĮĹ å®ĭ +Ġmosquit oes +带 åŃ©åŃIJ +(x ml +åĪº çĹĽ +çļĦ éĩijé¢Ŀ +ĠV ERSION +ĠLam bert +æĹ¥ æ¶Īæģ¯ +_m ock +ç»ĵæĿŁ æĹ¶ +设ç«ĭ äºĨ +æĺ¯ä¸Ģ æľ¬ +åİĨ ç»ĥ +Ġsand als +æľ¬æľŁ åĢºåΏ +Ġlobby ing +Ġ é£ŀ +Ġj arg +æīĢ å¤Ħ +ĠConf idence +ĠBY TE +Ġcont empor +get ting +Ġwhis per +a head +ç²īä¸Ŀ 们 +Ġtet ra +ãĢģ åħ¨éĿ¢ +.Col lection +Ġvou chers +ap at +æľ¬ éĥ¨ +çĿ£ å¯Ł +ite ch +quer que +ilant ro +_PRI ORITY +, 举 +讲 æİĪ +ĠTime out +Ġimmun os +Ġprag matic +æ°ij çļĦ +Ġany ways +çͱ ä¸ŃåĽ½ +( Message +sw ire +Ġmicro bes +ç¥ĸ å¸Ī +Ġf ps +âĢľ åħ¨åĽ½ +ISH ED +_S END +çͲ éħ¸ +追 ä¸Ĭ +Ġcounter fe +ad ena +å·² è¾¾ +ï¼ĮæĽ´ 好 +_s n +Sing apore +, true +Ġmor ally +A ward +ed ium +_L ANG +个 åĽ½å®¶ +Ġbul ky +ç§ī æĮģ +ĠOri ental +l hs +ï¼Įåľ¨ ä¸ŃåĽ½ +Ġan emia +åIJIJ åĩº +Ġd uality +Ġcraftsm anship +ar ctic +OC I +craft ed +D iet +ĠV id +$ _{ +, éĴĪ对 +Ġpow dered +ç͵容 C +è¿Ħä»Ĭ 为æŃ¢ +Ġcomp artments +对 æĪij们çļĦ +ä¹Į é¾Ļ +Ġde em +Ġsuper star +Ġcard inal +w ash +uy a +oss ing +-g ood +ä¹ĭç±» çļĦè¯Ŀ +é£İ 声 +ä¸Ģ缴 åΰ +RUP T +Ġc asing +IR A +. UTF +è´¢ åĬĽ +æŁĵ æĸĻ +s chemas +çļĦ èģĶç³» +ç« º +æĬ¼ éĩij +Ġwholes ome +- ish +sub scription +ab by +ĠSp atial +Ġ å·¦ +Ġmag istrate +人 åķĬ +Ġcreat ively +è¡£ è¢ĸ +ic um +ĠV ox +é«ĺ é£İéĻ© +Ġalle les +çŤ çĸ® +åºĶ æĺ¯ +Ġmic rom +ĠS prite +(p re +NS Dictionary +нÑĭ й +åĩºä¸į ç©· +.S erial +æĪIJ为 ä¸ĢåIJį +Ġinvent or +Ġmat cher +æĿ° åĩºçļĦ +dim en +ãĢ ľ +ãĢģ åħ¬åħ± +è¿Ļ 帮 +Ġro l +æĶ¿åºľ éĥ¨éŨ +éĢĨ åıĺ +éķĩ ä¸Ĭ +ip a +*) & +u ers +è·ĥ åįĥæĦģ +pl astic +æľį å½¹ +å¼§ 度 +ĠS EE +ĠDod gers +è¡ ¢ +ĠD irty +åĨį ä¹Łä¸į +天 æĺİ +ï¼Į è¶ĬæĿ¥è¶Ĭ +Ġinter tw +å±Ģ åī¯å±Ģéķ¿ +") ] +å¾ģ åħĨ +Ġtel esc +ï¼Į N +çļĦåľ° çĤ¹ +ĠY A +Ġregular ization +ĠBro oke +ä¸Ģ åıij +ãĢģ åľŁ +ay be +äºĨ è¿ij +ĠP ork +B LOCK +Cont rollers +Ġaut os +.P arent +Ġtub ing +åįĥ çĵ¦ +åĬ¨çī© åĽŃ +ĠG rav +ĠAn ime +ĠAnt ib +od on +Ġde an +Ġfinal ize +ĠC ure +ĠL oyal +æīĺ 马æĸ¯ +æĢª æĪij +p ie +ï¼Į 康 +Ġfor ge +åĽ½ å¤ĸçļĦ +Ġshe ds +ä¸Ĭå¸Ĥ çļĦ +éͦ èµĽ +Sim ulation +æ¤Ń åľĨå½¢ +Is n +æĹł çĹĽ +Ġsucceed ing +æ°Ķ åĬ¨ +è®° ä½ıäºĨ +è§Ĥä¼Ĺ 们 +w ares +ĠP ike +æĶ¹åıĺ çļĦ +Le on +Ġoscill ation +çļĦæľī çĽĬ +I cons +积 éĽª +ä¸Ģ æľµ +ä¸į 以 +ä½ł 以为 +Ġtransition ing +æµ·åįĹ çľģ +Ġ" :" +Ġthread ing +å±ı é£İ +Arch itecture +ï¼Ľ è¦ģ +SP ORT +- param +Ġdifferent iable +Ġun conditional +ĠWal ton +ï¼ĮåĪ« 说 +Ġnu anced +ĠB illing +ĠF erry +èᝠç͍ +/ commit +ir ations +Ġsand box +åįģåħ« æĿ¡ +ä¹ĭ ä½į +oph yll +ĠMic rowave +ert ime +, opt +ãĢģ 软件 +Ġu d +éĺ² å°ĺ +ĠDis crete +Ġmission ary +æ´¥ æ´¥ +Ne uro +åij¨ æľŁçļĦ +æ°Ķ åľº +ĠRef und +/ is +Ġm arty +ï¼Įå°± å·²ç»ı +æ´Ĺæīĭ éĹ´ +- Th +ĠPhys icians +е ÑģÑĤ +/s ervice +éĿĴå²Ľ å¸Ĥ +( mp +ãĢĤ åħĥ +ठ® +/ php +ĠFound ed +ĠY i +çĭĤ æļ´ +ä¸įäºĨ äºĨ +. Project +ä»į æľª +(" \\ +Tim ing +åħ·ä½ĵ åľ° +ĠPar a +K ent +Ġbre ached +è¡Ģ æµģ +- te +åĵ Į +头 ä¸ĬçļĦ +æ½ º +Ġmaj estic +ä¸į è¯Ĩ +ĠAir bnb +Ġse ams +D egree +\ }$. +鼨 çļĦ +èĬ¬ åħ° +Ġk u +é« Ļ +éķ¿ åŃIJ +Ġgal van +áĥ Ķ +ï¼Į åĸĦ +çļĦä¸Ģ åĿĹ +ĠD LL +ä¸Ĭ å²Ĺ +天 æĢ§ +eb o +Ġcru ising +-sh ot +_TH RESH +ãĢģ åķĨåĬ¡ +ma res +ï¼ĮæĪij èĥ½ +éĥ½æľī äºĨ +Ġin patient +åĴĮ ä¿¡æģ¯åĮĸ +åĮ»çĸĹ åį«çĶŁ +å®ļä¹ī çļĦ +j as +Ġb ilingual +Ġv agu +_l anguage +(t otal +æĬķåħ¥ 使ç͍ +ï¼Į对 äºĨ +è¿ĺ åŃĺåľ¨ +çľĭ ä¸Ĭ +çĶ· åŃIJçļĦ +ĠSh oe +_r oute +ä½ľ çļĦ +âĢľ 没æľī +强 æľīåĬĽçļĦ +ä¹ī çļĦ +(s ample +ffic acy +ĠExper iences +çĺ« çĹª +g art +åı¤ èij£ +ĠIN VALID +伯 æł¼ +æĶ¾ éĩı +ul ia +_f ailed +è§£åĨ³ æĸ¹æ³ķ +ĠRef er +Ġpel let +åŃĿ 顺 +- plane +æĺ¯ ç¾İåĽ½ +为 åħĪ +ä¹Ł ä¸įåIJĮ +å¦Ĥ æ°´ +Ġste alth +q e +is ements +çĮľ åΰ +æĽ¿ ä½ł +Ġfert ile +ĠG BP +ï¼Įæľ¬ é¢ĨåŁŁ +_W rite +Ġmulti plic +ĠDev ils +ç»ĪæŃ¢ 确认 +æŃ£ åĽłä¸º +Ġmod ifiers +èĴĻ èĴĻ +é¢Ĩ 头 +( EX +Ġsh immer +è¾¹ éĻħ +æĬĢæľ¯ æľįåĬ¡ +åĵį äºĨèµ·æĿ¥ +M ilitary +èħ° æ¤İ +ï¼Į 人æ°ij +_j oin +ç»Ŀ对 ä¸įæĺ¯ +åIJĪå¹¶ è´¢åĬ¡æĬ¥è¡¨ +åİĭ å®ŀ +Jul ie +Ġsyll abus +ï¼Į çĽ¸å¯¹ +ac ia +è¡Ģ çĹĩ +è̳ 缮 +ĠCon vey +. ib +oo le +? ", +ĠL AT +ä¸ĭ æĦıè¯ĨçļĦ +éķ¿ çº¦ +Ġvisit ation +Ġn f +æĪij è·Ł +fl ip +omorph isms +æĪIJå°± æĦŁ += v += data +Ġout flow +é¢Ĩ导 åĴĮ +é į +ĠHe ck +ĠMar l +éĸ ĭ +çĽĸ 竳 +.f ront +Ġra ced +ç±» ä¸ĵä¸ļ +Att end +èµļ åıĸ +.w s +ru ly +Ġserv ings +åı° ä¸ĬçļĦ +èµĦ产 è¯Ħä¼° +ĠN olan +Ġun expl +ĠAt hen +ĠIN V +æĹ¶ æīĢ +è¿ľ å¾ģ +Ġbreak er +imb ing +Ġunw ind +Ġexch anging +$ c +âĢĿ å·¥ä½ľ +å¦ĩ 产 +Ġobtain able +Ġ\" % +ï¼Įä½Ĩ 对 +-p ressure +åģļäºĨ ä»Ģä¹Ī +ï¼Į åŃ£ +ign er +çĤ¼ åĮĸ +Ġvirt ues +çĭĦ åħĭ +ãĢĤ ä¸Ĭæµ· +Ġ` / +èĤ¯å®ļ ä¸įä¼ļ +Ġswe ating +åĴĮ é»Ħ +ä¸įèĥ½ 说 +ä¹ĭåIJİ åĨį +缮çļĦ åľ¨äºİ +çĨĬ çĨĬ +ãĥ¼ ãĤ¿ +ĠSt roke +åIJĮ åIJį +ãĢģ çϾ +å¸Ŀ éĥ½ +ãĢĤ ç¾İ +back slash +åİ¿ 令 +åĬŁèĥ½ æĢ§ +M b +æĸ¯ æīĺ +çĸı 导 +M appings +çļĦå¿ĥ èĦı +ï¼Į以 ä¸Ĭ +çļĦ ä»ĭç»į +ä»ĸ æĬĬ +ĠIN F +ĠBrid ges +Ġafford ability +ãĢģ åįıè°ĥ +Ġtext ured +ĠMor al +ĠS aul +ld er +Ġphosph orus +P b +è¿Ļ个 å®¶ä¼Ļ +n ite +åĢºåĬ¡ 人 +Object Type +Ġrun off +-l argest +ĠCov enant +ĠLauder dale +Ġl umbar +ĠS ight +ãĢģ å¾·åĽ½ +åĴĮ çłĶç©¶ +Ġun i +Pro be +_c oll +_DE L +G row +çĥŃ èº« +çģ« åħī +çĸ¾ æİ§ +è½° åĬ¨ +_mod ified +n esty +âĢĿ ãĢĤâĢľ +pc s +çѹ éĽĨ +j er +åºĹ åijĺ +ãĢĤ åıįæŃ£ +al u +ro ttle +Ġcl am +ot ides +p wd +è¿ĺ è¡Į +æĹł èĥ½ +é¦ ¥ +çļĦ å¸ĮæľĽ +Ġmor ale +ĠVari ant +ĠEL SE +prov ided +$ ac +å¿ĥ è¡Ģ +çĭĤ çĥŃ +. if +ï¼Ľ ä¸ī +respond ing +ĠConsider ations +çļĦ å͝ä¸Ģ +Ġfr anc +ĠTele com +Ġcatast rophe +å®ĺ åIJı +Ġdiscre et +/ os +th inking +å¿ĥ 仪 +fa ith +è§Ĩ éķľ +éħį è§Ĵ +éĩį éĩijå±ŀ +ĠBL ACK +注åĨĮ åķĨæłĩ +å¹²åĩĢ åĩĢ +åį°è±¡ æ·±åĪ» +çľ© æĻķ +æĢ» æľī +æĹ© æľŁçļĦ +èĥĮ è´Ł +st icks +é¾ Ī +H ierarchy +åĨį æĢİä¹Ī +urg a +ç§ijåѦ åİĨ +åĿIJ éªij +èľ · +Ġmotor cycles +R eward +Ġret ina +ï¼Į 麦 +ï¼ĮæĪij们 å¿ħé¡» +ĠST AR += T +s amples +ĠS app +è¿ĺ éľĢ +Ġve g +åIJ¸ 纳 +ठ¸ +Ġfarm house +ĠWinn ipeg +ĠPe ach +Ad obe +å®Ĺ å¸Ī +çļĦ 士åħµ +ow ler +ĠAl ignment +ĠDiv ide +ĠHum ans +Q I +Ġt aps +ãĢģ å®ĭ +å¹´ éĿĴ +ĠTE CH +-head ed +Ġl az +ĠD EM +é«ĺ è·Łéŀĭ +Class ification +-sp onsored +ĠAccept ed +寥 寥 +Ġtax ed +ĠAMA Z +- dd +- expression +æ²»çĸĹ æķĪæŀľ +Dec ision +ur ances +ĠP iper +åįķ æĽ² +转 å¢ŀ +B ee +× ij +éĹ´ æŃĩ +åĽŀ é¦Ī +Ġra ff +æģ° åΰ +éĺ» æĸŃ +RE AL +æĹĭ é£İ +Ġп од +G ear +ä»ĭ äºİ +Ġbisc uits +èĩĢ éĥ¨ +è¿Ľè¡Į æ¯Ķè¾ĥ +Imp lement +* : +Ġvan ishing +ãĢĤæľ¬ åıijæĺİ +approx imately +. Process +åĿIJ éķĩ +ĠEmm y +ä¸ī 项 +被 æµĭ +Ġtransf ected +( Action +iz en +ä¹ĭ åĬŁ +æµij çĦ¶ +rem oved +æ¤Ń åľĨ +åı¯ä»¥ æıIJä¾Ľ +ĠSi em +/ mm +Ġro gue +è§ģ æķĪ +çļĦ æııè¿° +Ġdes erialize +Http Client +L uck +ä¸Ģ è·ĥ +h oles +èĭ± éĩĮ +第ä¸ĥ 竳 +ç¬ ł +好 åĿı +( Item +Inter faces +é¢ĨåŁŁ ä¸Ń +被 èªī为 +Ne ither +çĿĢ æĪijçļĦ +ãĢģ åħ³äºİ +ĠGrand ma +Ġwaters hed +ï¼Į 带é¢Ĩ +Ġp ion +Exper imental +ä»·æł¼ 为 +)-- ( +.st at +åijĬè¯ī äºĨ +éļıæĹ¶ éļıåľ° +_not ify +ä»ħ 次äºİ +ç»Ļ èĩªå·±çļĦ +ï¼Įä¹Łåı¯ä»¥ æĺ¯ +ult z +æĸ° èĢģ +ç§ģ èĩª +ε ν +h ov +ãĢĤ ä»ĬæĹ¥ +å·² æĪIJ +ĠAn ch +- ce +åŀ Ľ +ĠV iolet +ĠFed er +ï¼Į æī©å¤§ +ä¸Ģ åħ±æľī +çļĦ 伤害 +ĠL und +B inder +ĠA FP +EL S +æĢ§èĥ½ åĴĮ +æĹł å¼Ĥ +ĠAm enities +ĠA PA +ĠI PS +Ġyouth s +Ass ociate +_qu ant +çļĦ éĥ½ +Ġcher ished +ä¸į ä»İ +ĠW OW +ä¹ĭ å¢ĥ +ï¼Ī ä¸ĩåħĥ +ï¼Į çĻ» +ĠC umm +Check s +. br +åħ³ åı£ +æĶ¿åºľ åĴĮ +ĠâĬ Ĥ +Ġw aving +éĩĮéĿ¢ æľī +Ġblo oms +å±ĢéĻIJ æĢ§ +åĩº 线 +æĿİ ä¸ĸæ°ij +ä¸įè¿ĩ äºĨ +( right +ï¼Į 身åIJİ +ä½ ° +å¹¶ ä¸İ +Ġduplic ation +Ġsol icit +åı¬ åĽŀ +/ ", +ĠH itch +æķ£çĥŃ åύ +EN OMEM +ĠT us +æł¼ åŃIJ +Ġpl ush +æīĵ éĩİ +ï¼ĮåĨį åΰ +ĠÐ Ŀ +%% % +Ġwind shield +Ġrem ake +part um +L as +çģ« çĤ® +çģµ åĬĽ +Every body +ĠBur lington +G ROUP +æ³Ľ 滥 +éļı æĦıçļĦ +è¦ģ æī¾ +å°± æ¯Ķè¾ĥ +Ġlas ers +ĠD IV +å®¶ 主 +ä¸įåĪ© å½±åĵį +v ron +ed ly +主åĬŀ çļĦ +令 çīĮ +_s d +åıį çľģ +( chan +н Ñı +ĠVol tage +Ġhe ctic +è¿Ľ å±ĭ +OM IC +éĤĤ éĢħ +Ġ åIJĦ +ĠK ro +_P AT +Ġrev ive +Ġl il +_ UI +is et +Elect ronic +\ N +ï¼Įä»ĸ å°Ĩ +çł´ ä»ij +S r +-b usiness +_pro gram +Ġring tone +ç«ĸ åIJij +ĠS le +ĠT LR +欧 å¼ı +semb led +contain ed +åĴĮ æĿ¨ +rew rite +ĠVal encia +Ġdismiss ing +over rightarrow +ঠ¿ +ĠGran ite +ä»»ä¸Ģ项 æīĢè¿°çļĦ +R outes +j Query +m otion +ĠMar ilyn +æĹı 群 +æİ¢ 寻 +ĠSpecial ists +å±Ĥ åĩºä¸įç©· +Ġur anium +Ġcar ving +åį³ ä¾¿æĺ¯ +App lied +ภķ +Ġgrac ious +ĠCart esian +工伤 ä¿ĿéĻ© +ï¼Ī éĽĨåĽ¢ +åı¦ä¸Ģ åįĬ +cer al +ĠCOP D +奥æŀĹåĮ¹ åħĭ +对 é½IJ +çŁ³ 榴 +(d p +ä¸įè¦ģ 太 +ï¼Įä»ĸ 没æľī +ACT IVE +We ights +-f ront +åįĥ åħĥ +ãĢģ å¼Ģåıij +ĠR ider +æŃ» è§Ĵ +at ian +ï¼Į é¢ĩ +ä½ĵ ä¸Ńæĸĩ +Ġset ter +ä¸Ģè¡Į 人 +Ġawaken ing +ï¼Į æİ¢ç´¢ +ä¼ļ å¢ŀåĬł +ual a +åįģäºĮ å¹´ +ãĢģ ä¸Ń央 +è¯į åħ¸ +ĠاÙĦ Ùħ +^ , +ï¼Į转 头 +ĠT ory +ARE NT +ĠSpec ify +ç͵åķĨ å¹³åı° +Ġpleasant ly +Ġc es +âĢľ åĪ« +Ġharm ed +Ġexpon ents +ĠGram mar +Ġlymph oma +âĢľ ä¸Ń +åIJĦ å¼Ĥ +.D ocument +西å®ī å¸Ĥ +Ġfest ivities +åı¯ ä¸İ +ç´¯ ç´¯ +lat able +è´¬ å̼ +Hot els +D ATE +Ġl imp +æĶ¯ä»ĺçļĦ çݰéĩij +çļĦ çIJĥåijĺ +ä»Ļ å¢ĥ +ç»Ħä»¶ åĮħæĭ¬ +Ġarrog ant +Ġpro w +Ġcr ane +gr and +ĠSM ART +_w riter +A y +æ¶² åĮĸ +Ġhon oring +at ars +ĠCh u +æŃ¢ è¡Ģ +ĠSur round +ï¼ĮåĽĽ åij¨ +åĴĮ èĭı +Ġ æijĦ +ok in +Ġbl and +ä¸ij éĻĭ +,æĺ¯ ä¸įæĺ¯ +( åĽ¾ +çIJĨ æŁ¥ +天 äºĨ +Ġsw ollen +Car bon +er ole +大 éªĤ +v ote +ï¼Ī B +åıĺ æķħ +éħĴ åIJİ +ĠSQL ite +Ġorth odont +ä¸Ĭ éĺµ +çİ© åĦ¿ +ĠBur k +让 æŃ¥ +åĸľ åºĨ +Ġpercent ile +ãĢģ éϤ +(m ain +Place holder +Z W +ĠH UD +Index Of +NS Object +_ Value +_trans action +åIJĥ èᝠ+丽 æ±Ł +.ex ceptions +ï¼ĮæĬĬ ä»ĸ +Ġ åºĶç͍ +好 åIJĥçļĦ +Ġph yt +èµĦ产 éĺ¶çº§ +æ§½ åĨħ +_l at +ĠAR C +èı² èı² +ĠM ash +çļĦä¸Ģ éģĵ +äºĨä¸Ģ å±Ĥ +åĩł 声 +ĠSabb ath +åīĤ åĴĮ +æŃī æĦı +.assert False +Ġfirst ly +ĠUn iv +ĠComp ound +ĠDec ode +éļ¶ å±ŀ +Ġ æ¯Ķä¾ĭ +({ }, +ï¼ĮåIJĦ èĩª +èĤ© 头 +ï¼Įå¾Ī æľī +ï¼Į æł¡ +æ© Ł +审议 éĢļè¿ĩäºĨ +âħ ¢ +ĠH ain +Ġut ens +鸳 鸯 +Ġ åĪĻ +çļĦå®īåħ¨ æĢ§ +c itation +å¸ĥ 满 +é¡¹çĽ® 管çIJĨ +åĩºä¸Ģ åī¯ +/j av +( add +/ server +åij¨ è¾¹çļĦ +.M anagement +z m +Ġspecial ties +åĬŀåħ¬å®¤ éĩĮ +no op +ä¿Ŀ å®ļ +u ces +è¿ŀ 线 +éĹ¯ åħ³ +Ġcat hedral +-al one +_ remote +Ġpro claimed +åIJij åĮĹ +Ġbin aries +æĪij æľĢ +çĶŁ çĮª +pe i +Ġartic ulated +Ġdes erving +, å±ŀäºİ +_d s +ĠDis p +æ°´ ä¸ĭ +å·²ç»ı æĬĬ +g ain +æ¹ĸ åĮº +Ġâī ¡ +åĪ© åύ +super vised +Di agnostic +Ġpredomin ant +ï¼Į å°½åı¯èĥ½ +空éĹ´ ä¸Ń +ĠPR INT +ç£ħ 礴 +ĠMust ang +å¹² åIJĹ +ĠHigh lands +æł¹æľ¬ 没 +P airs +o que +>< !-- +ä¹ĭ æºIJ +éŁ³ä¹IJ çļĦ +太 åĮ» +C OL +çıł æ±Ł +çŁ¿ æ³īæ°´ +èµĦæł¼ èĢĥè¯ķ +å°´å°¬ çļĦ +) }_{ +ç©· 人 +.com ponents +èIJ¥åķĨ çݯå¢ĥ +ä¸į 带 +æĸ¹æ³ķ æĿ¥ +λ η +h id +æĺ¯ åĪ©ç͍ +åĮĪ çīĻ +ĠF G +åIJĪæ³ķ æĢ§ +ĠC NS +äºĭä¸ļ éĥ¨ +ĠÑĩ ÑĤо +Ġcon verse +ç¨į æľī +Ġreject s +ï¼Į 广å·ŀ +çļĦæīĭ æ³ķ +åѦçĶŁçļĦ åŃ¦ä¹ł +ï¼Į éĿ¢ç§¯ +ĠK ant +æµ· éĩĮ +æĤĦæĤĦ çļĦ +éĩį åĪĽ +Ġm ango +иÑĩ е +Ġwatch dog +è¿ĩ 硬 +} )$. +æĪij 个人 +ove re +åĪĢ åŃIJ +ï¼Į天 天 +ä»İ ä¸Ģå¼Ģå§ĭ +res so +ĠH iro +æŀģ 强çļĦ +upp ly +/h igh +a ic +ï¼Į åѦä¼ļ +æļ´ è·Į +ĠPhil ly +Particip ant +l iving +æĬ¤ éĢģ +æŀĹ åľ° +è¿Ļ æĬĬ +B U +èĩªçĦ¶ æĿij +ĠCOM MENT += NULL +ö s +ĠH TTPS +H op +ĠL ori +æĹ¶éĹ´çļĦ æİ¨ç§» +Ġven ous +ãĢĢãĢĢãĢĢãĢĢ ãĢĢãĢĢãĢĢãĢĢ +æĶ¹ åζ +Ġstock ing +设 为 +çļĦ人 æł¼ +Ġre w +éĴ ´ +N r +åĽ¢ ä¼Ļ +Ġdom inates +Ġhab eas +Ġfasc ination +Ġesc apes +_A UDIO +ĠHelp ing +ĠMB EDTLS +ut or +第ä¸Ģ éĥ¨ +Ġscream ed +ĠD eg +æīĵ æĪIJ +èľ ¿ +以ä¸Ĭ 代çłģ +ĠMiche le +éĩį ä»» +èѦ è§ī +Ġåıª ä¸įè¿ĩ +ãĢģ èĭ±åĽ½ +Ġdo om +ä¾¿å®ľ çļĦ +æīĵ åľ¨ +æ¶Īè´¹ åĵģ +å®ī éĺ² +-c all +S dk +æĺ¯ éĴĪ对 +end ale +éĩij å¥ĸ +交 èŀį +æł¹ éĥ¨ +( Long +_m alloc +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +H igher +M CA +Ġd ma +F actors +èį¡ æ¼¾ +G aming +å¤ļ æľī +ä¿¡ çļĦ +Ann ounce +å¦ĩ èģĶ +Ñĥ Ñİ +åģı åĥ» +ĠHunting ton +ĠB is +ï¼Ł æľī +Off sets +Ġbull shit +ĠLithuan ia +(p arser +ild en +æķ° 次 +.d im +stack rel +ä¸Ģåıª æīĭ +< # +éĥ½ æ¯Ķ +åľ¨ é¦Ļ港 +ä¸ī ä¸ĩ +Block ing +èĦĸ é¢Ī +Ġhack er +s olid +åIJij åı³ +å¸ĥ æŀĹ +Ġcommun ist +D allas +c ash +Ġ è¦ģæĺ¯ +ĠMajor ity +Ġso aring +}$ { +çij Ļ +ãĢģ ä¿ĿéĻ© +OM G +çij Ľ +æ»ij 稽 +Ġb ary +Ġcomp rehens +, 大éĥ¨åĪĨ +l ain +Ġex fol +æľī å¤ļç§į +å̼ å®Ī +Ġpol ishing +æ²¹ çĤ¸ +缼 çļĦ +M ichigan +: active +_p adding +çĽĹ è´¼ +è¤ ¥ +Ġly ric +# , +Ġ} _{ +æĪIJ è´¥ +ç´« å¤ĸ +Ġban ning +Ġtens ors +ĠO man +å°ı ä¼ĻåŃIJ +ĠTwitter Share +è¸ı æĿ¿ +æĪij å¦Ī +çī¹ åĮº +Ġdec rypt +Ġretros pect +Ġth aw +Ġexplo its +D raft +Ġserv iced +çīĩ ä¸Ń +èĶ· èĸĩ +è¿Ļä¸Ģ å¹´ +.L ink +Ġdiplom acy +Podcast s +è§£åĨ³ åĬŀæ³ķ +ï¼Įèµ· çłģ +åıĤéĺħ åĽ¾ +ĠB W +æij© æł¹ +_DEP TH +stit ial +UFF IX +ĠBart on +ãĢģ åĨħ容 +çģµ èĬĿ +ĠO st +Ġv ind +comp atible +ĠOb st +ç¢İ çļĦ +ãĢĤ 使 +ĠP AL +è¿ĩ èĬĤ +Ġp aving +ĠD os +ĠC ursor +å°±æĺ¯ æĪij们 +Ġneg atives +*- *- +æĸĩçī© ä¿ĿæĬ¤ +Ġinv oking +æ±Ł åĮĹ +åħī éĺ´ +该 é¡¹çĽ® +abb ing +F ew +Press ure +S ony +is or +ib al +羣 æĮļ +çī¹åĪ« 注æĦı +为 鼶 +TH ING +âĢľ ï¼įâĢĿ +åħ» èĤ² +麾 ä¸ĭ +_ commit +ãģĦ ãģĨ +he v +ï¼Į对 æŃ¤ +å¹²éĥ¨ èģĮå·¥ +综åIJĪ ç´łè´¨ +Last Error +Ġre pt +UR AL +社 ç§ij +ä¸Ģ æĮ¥ +let ons +. ob +Ġ= ================ +Ġmen ing +ï¼Į é϶ +è°IJ æĮ¯ +( trans +Ġv b +æłĩåĩĨ åĴĮ +çļĦ æīĢè¿° +æĹł é¡» +伤 æ®ĭ +çĶ» é£İ +Ġconc at +ĠBath rooms +è¿Ļ è¾¹çļĦ +ĠCharacter istics +ãĢĤ å¿ĥ +Ġconfig urable +ĠNation als +纯粹 çļĦ +èĬ± åĦ¿ +ĠKard ash +P rel +ru gged +ï¼Ī åĮĹ京 +Ġstart Time +ĠAL T +ĠT ie +åĽ½èµĦ å§Ķ +åľ¨ å®ŀéĻħ +Ġcab ins +ç͵ 容åύ +ne ck +yn ch +jud gment +æĹ¶éĹ´ éķ¿ +Ġelect ive +Ġexport ing +) "> +åħī çݯ +ĠCourt ney +- rec +ip ay +ç¬Ķ å½ķ +ĠTw ilight +ĠTob acco +Ġcrystall ine +æĥ¦ è®° +Ġ æĭī +ĠD ud +åĪĨ离 åύ +ug gets +Ø ° +ãĢĤèĩª ä»İ +ãĢģ è¦ģ +ãĢģ ä¹Ļ +å¥Ķ èħ¾ +Ġhorse power +ä¸Ŀ绸 ä¹ĭè·¯ +( è®°èĢħ +Ġ} } +大 ä½ĵ +çϽ èĻİ +éĻIJ æľŁ +çݯ氧 æłijèĦĤ +ch rist +ç»Ŀ ä½³ +_const raint +强 çĽĹ +_HE LP +Ġtrans pose +Ġcond ol +ĠOr b +Ġdial ysis +ĠSach s +ĠIM AGE +EN G +Ġstere otype +åĴĮ åĪĽæĸ° +Output s +/ al +ĠB ram +æķĻ åĬ¡ +Ġnarrow ly +åĩĢåĮĸ åύ +B EGIN +ä»Ģä¹Ī éĹ®é¢ĺ +ä¹° 车 +æĢİæł· æīįèĥ½ +æĬĬ æİ§ +( ind +\ linewidth +ps is +ï¼Į请 æĤ¨ +Ġl est +ad minist +-s izing +奥 ç§ĺ +E at +p as +ä¼ļ éģĩåΰ +åħ¶ä»ĸ ä¸İ +\ set +æľī 以ä¸ĭ +éĿĻèĦī æĽ²å¼ł +Cho oser +å¦Ĥ ä¸Ĭ +ĠCarl son += http +Ġte as +ĠHe ads +_T est +æĢ» åĴĮ +ç¢İ çŁ³ +åıijæĮ¥ ä½ľç͍ +å¿« åľ° +ä¹Ł å·² +sub st +éĢı åħī +æ¡ĥ åĽŃ +ä¸ŃæľŁ 票æį® +æĺ¾çĦ¶ æĺ¯ +X A +Ġ{ ( +Ġ 注æĦı +èµ° ä¸Ĭåīį +è¿ŀ带 责任 +æľ± åħĥçĴĭ +ĠEm manuel +ĠCer amic +CH ANGE +Ġcan non +å¹¶ è¿Ľè¡Į +Ġturn out +sex ual +' ', +( order +ä¸ ķ +int ent +Dis p +ãĢģ ç͵è§Ĩ +è¿ĺæĺ¯ æľīäºĽ +åĢĴ éĹŃ +ĠL illy +åŁº çŁ³ +aff les +ĠPartners hips +Ġstrip ed +ï¼ģ ä½Ĩ +ĠShel by +P df +.W here +ãĢĤæīĢ以 说 +ĠTrib unal +_BY TES +Ġredd it +es igned +ones ia +å¢ŀ æķĪ +éħį åζ +ĠRe hab +å®īè£ħ çļĦ +ure ka +æĺİ æľĹ +Ġ__ (' +ĠSubject s +ĠNap oleon +Ġs x +ï¼Į èĴĭ +gg er +-en h +Ġse greg +è¿Ļ åī¯ +/ admin +< w +ĠP enguin +æĹł ä¸Ĭ +ï¼ī è´Łè´£ +ä½Ľ å±±å¸Ĥ +ĠSaskat chewan +ĠComb ining +Ġch or +度 éĩı +ä¸ĵ 访 +ĠPe oples +ĠFred die +Ú ¯ +Ġh oard +ãĢģ åı³ +_p k +äºĨ éĤ£ +-d et +-re ported +ĠKazakh stan +( cc +/ op +Table View +ä nd +ol v +ĠG omez +ãĢģ å¿«éĢŁ +Ġp izz +åĴĮ 产åĵģ +Ġst en +ç¾İ èªī +符 æĸĩ +ãĢĤ éķ¿æľŁ +ãĢģ èĩªæ²»åĮº +彩 票 +è¯Ĺ æĦı +ĠC inem +å·²ç»ı ä»İ +Ġwild card +ĠMood y +ï¼ļ ä¸Ģ个 +æĥħ人 èĬĤ +Ġdrop lets +Ġvan ished +_ hex +_f ix +.t x +èĪª è¿IJ +om id +od en +éģ ´ +çĵ¦ è§£ +Xml Element +Ġun published +_p kt +çļĦç¥ŀ ç§ĺ +} t +åįĥ ç§ĭ +å·¥ç¨ĭ ä¸ĵä¸ļ +ĠPharmaceutical s +å¨ģ é£İ +fl ake +an imate +ï¼Į 欧洲 +Ġg eek +ä¼łéĢĴ ç»Ļ +Ġdep ressing +åĪĽéĢł çļĦ +åijĬè¯ī èĩªå·± +: I +p un +.f eature +æ´Ĺ 车 +-inf ected +ask ed +ãĢģ æ£ĢæŁ¥ +åĴĮ åIJİ +Ġill icit +ä¸ĭ 马 +æĮ¯ 举 +ĠH CC +. uint +Own ed +med icine +ç¨Ģ å°ij +Ġsingular ity +Âł al +çļĦ å·¦ +âĢĻ T +Ġanatom ical +D riving +ä¸Ń åѦçĶŁ +. True +-f e +ĠCheck list +ĠShow case +Ġawa its +åįļ 主 +å°± åľ° +çĥŃ æ³µ +ĠRE LEASE +) (\ +@ article +ĠNot ebook +T ow +P ear +ĠJ asper +æĺ¯ä¸į ä¸Ģæł·çļĦ +n w +æĬĵ åΰ +, max +.get Y +åİĤ éķ¿ +ĠB ates +Ġem ulator +ĠQu artz +)+ ( +ĠMort on +å¼¹ åĬĽ +aza ar +ĠS ellers +è§£åĨ³ çļĦéĹ®é¢ĺ +墨 éķľ +B old +| Any +/f ont +æ·± å¤ĦçļĦ +-m atch +æĦŁæĥħ çļĦ +åĪ« åIJį +èij£ åįĵ +沫 沫 +èµĦæł¼ è¯ģ书 +Clos ure +(d es +it imate +od ied +.p repare +ĠCr ane +ãĢģ åķĨ +æ°¸è¿ľ æĺ¯ +ĠV W +Ġjealous y +Ġs ane +èĥ½å¤Ł éĢļè¿ĩ +- turn +Ġlit ers +[ J +ãĢģ æĿij +-n et +浩 çī¹ +ĠPerm it +Ġa ur +çĹħ æĤ£èĢħ +:: - +Ġdisadvant aged +Ġre used +ĠG ob +/d ocument +ce p +ãĢģ 微信 +_D OM +å¼Ħ æ¸ħæ¥ļ +feed back +çļĦ ä¿¡åı· +Ġsuff ices +æĪij åķĬ +ex ual +Ġback lash +ON Y +ä tt +Ġaer obic +ĠL OW +åľĪ çļĦ +ĠKrist en +et imes +è¿Ļ æĺ¯åľ¨ +_t raining +æ£Ģæµĭ ç»ĵæŀľ +ï¼Įä¼ļ ä¸įä¼ļ +éª ĭ +Ġinv aded +Ġbl aming +Ġmoder ator +é¡· åĪ» +ĠâĢľ ... +éĩij éϵ +ç£ IJ +-S ch +ĠC unningham +ĠCh loe +Ġref lux +åĪº è̳ +- mentioned +Ġant igens +ĠCr ushers +å¾Ī å·® +æĹłæķ° 次 +æ³ķ åύ +ÏĦ αι +å§ĭç»Ī åĿļæĮģ +çļĦ人 åĬĽ +æľī æĦıä¹ī +Ġk s +èĥ½å¤Ł å¾Ĺåΰ +oph ila +Version UID +od ial +.h ref +Ġnation als +æĢ» åĨłåĨĽ +Ạ¡ +. = +ut c +çľģ éķ¿ +åĨ° åĩī +, èµ° +ret te +æ¼ ķ +in ian +ï¼Į åĨħéĥ¨ +èļ Ŀ +éĢĤåºĶ æĢ§ +ĠâĦ ĵ +< User +.d umps +å¸ĥ 线 +.c ur +ĠVer ified +ĠCol ts +Ġtight ening +_PRO P +å·¥ä¸ļ åĽŃåĮº +ĠTreat ments +ju vant +Ġmerg ers +Ġduplic ated +缸 声 +_d ocument +cept s +æľī çIJĨ +ARS ER +ch ains +ANG ED +ST REAM +R TC +Ġd anced +rad es +ol one +AL TER +Ġdyn asty +æĿ¥ ä¿¡ +ä¸įåΰ ä½į +form in +Ġens l +Ġtub ular +_ (" +Ġpl ated +Ġchi ropractic +ĠO rientation +èĩª è´¸ +ç¥ŀ æĺİ +Ġc z +Ġl amin +è´¹ç͍ çļĦ +Ġsympt omatic +çīĪæĿĥ 声æĺİ +ĠâĹ ĭ +ĠGoth ic +-f it +ĠComp etitive +å°ı é¢ĺ +b il +, å¼ķ导 +ĠP tr +part icip +Ġtorn ado +n mgp +ï¼Įä¸į åĥı +ĠSME s +ï¼Į 诸å¦Ĥ +Ġp acing +ĠF requently +æľįåĬ¡ æľīéĻIJåħ¬åı¸ +ï¼Į åī¯ +å¹´ æľĪ +' un +ï¼Į å¢ŀåĬłäºĨ +Ġd ou +In cluded +ĠDoll ars +åİ» å¤Ħ +b w +ter a +Ġп еÑĢ +åıĮ 人 +am ble +æ°Ķ çIJĥ +Ġm ural +ãĢģ æ±ī +Ġcongen ital +éĢĢ åĽŀ +ï¼Į é£Ł +ĠCh al +ĠHel ena +ot in +åħ¨ èĥ½ +ç¿» å¼Ģ +ĠHigh light +ĠV oting +åŃ ¸ +ï¼Įå¹¶ åIJij +_p anel +å¤ļ ç±³ +åIJĦ åįķä½į +.R andom +å®Įåħ¨ çļĦ +Ġqual ifies +åĴ¬ äºĨ +ĠScript ures +ĠNi agara +Ġundis puted +ä¸į æĤ¦ +åĩŃåĢŁ çĿĢ +æģ© æĸ¯ +Ġglam orous +, æľª +. Convert +è¿ Ĥ +Ġb f +çļĦ 妻åŃIJ +ĠK afka +Ġimp urities +-t ouch +æĹ© çļĦ +Ġm alls +产 åĮº +çļĦ çŀ¬éĹ´ +Ġinvestig ates +ãĢģ é¤IJ饮 +æŃ¤ åIJİ +.p oint +ãĢĤåľ¨ ä»ĸ +ä¸ĥ ä¸ĥ +crum bs +çļĦ 年轻人 +att an +罪 è¡Į +æĬ¥éĶĻ å¦Ĥä¸ĭ +æĹłçĹĩçĬ¶ æĦŁæŁĵèĢħ +ĠP ending +åĨħ åIJij +éķ¿ æķĪ +_p c +æī¿ éĶĢ +Ġr l +é«ĺ è¶ħ +Ġsoc iology +ï¼Į ç§ij +th ick +ĠGe ography +DR AM +Ġma ize +å°± åħĪ +æļĤæĹ¶ æĢ§ +Ġpur ge +K y +æľī è¿Ļ个 +-c ultural +r ances +éĽĨ çļĦ +åİĨ æĹ¶ +çĨ ¨ +Ġspokes woman +å°ı 丫头 +è¿Ļç§į ä¸ľè¥¿ +çľ¼çĿĽ éĩĮ +èį ¤ +ä än +éĹª çĿĢ +st ores +èĢĮ ä¹ħä¹ĭ +Ġpr uning +ç§ijæĬĢ æĪIJæŀľ +å¤į è®® +ij ay +Ġb inge +pro be +ĠDaniel le +ul d +Ġcon ceive +Cong rats +åħħæĸ¥ çĿĢ +å¤į æŁ¥ +ï¼Įæĺ¯ 为äºĨ +onal do +ym al +ä¾Ľ è¿° +åĨ³ ç®Ĺ +ĠÑģ л +ãĢģ 主 +ĠKir by +Ġben ches +ĠNaz is +M OBILEPHONE +ä¸Ĭ æĿ¥çľĭ +èįĴ åĶIJ +ĠEx cess +Ġinf arction +ý ch +Ġ åŁºäºİ +åĩº æĸ° +åºľ éĩĮ +. attribute +åľ¨ ä¸ī +Ġev aporation +åĨ² åIJij +ï¼Į éĵ¶è¡Į +è½» èĢĮæĺĵ举 +Ġsoft en +ĠArmen ian +Ġ åıĹ +St rength +åĬł æ°´ +æķ° ä¸ĩ +ĠSo le +PRO JECT +åĭĭ 竳 +å°± åı« +Ġpen insula +ãĢĤå½ĵ åīį +, å¼Ģå±ķ +ĠJac ques +.j et +ä»ĺ æģ¯ +ĠGaz ette +ï¼Į ç¦ģæŃ¢ +èĢĮ å½Ĵ +Ġmis information +ĠD ies +Ġt ing +Ġscarc ity +ä¸į 强 +鹦 é¹ī +.A ccess +Des erializer +èĤº éĥ¨ +ĠIn ches +æŁ± åŃIJ +Ġphilos ophers +çĤ¹ æķ° +ĠMar ried +oly mer +ĠRand all +纸 å¸ģ +Brows able +Ġ æķĻèĤ² +Com fort +ĠðŁ Ĵ +å¼¹ å¹ķ +ure th +讲 åΰ +缩 åĩı +RESULT S +æİ¨ ç¿» +B X +ĠH ale +æĪij ä¸įèĥ½ +æī¾ æĿ¥ +^ s +ĠBah amas +ĠGreen wich +Ġ åŃĹæķ° +代 为 +Ġfl air +EX TERN +ä½³ èĬĤ +æĭŁ åIJĪ +è¿ŀæİ¥ éĥ¨ +ĠElect ron +çļĦåIJį ä¹ī +F ord +ĠC athy +åľ¨ ä¸Ĭè¿° +ĠDE P +Ġspont aneously +Du plicate +çĶŁ éĶĪ +Ġprot ons +Ġenvision ed +åĵŃ å£° +æIJľ æŁ¥ +ĠM SC +Ġ$ ? +fit ting +âĢ ŀ +. Enabled +S ending +ĠBre ath +人åijĺ è¿Ľè¡Į +形容 è¯į +r ne +è¯Ħ æµĭ +C OR +es on +åįĹ éĿŀ +FORM AT +èľ¿ èľĴ +åĩĨ åħ¥ +红 åįģåŃĹ +ä¸ŃåĽ½ åı¤ä»£ +rew s +ĠDep loyment +rabb it +Measure ment +Ġgo v +Î £ +Ġble ed +f ps +_S O +ĠPrem iere +Ġreact ing +M eter +ãĢĤ - +ĠL EV +_s ame +ĠC d +ss i +è½» 度 +ĠDef ines +ĠPl at +appe arance +ri et +æīĵ çIJĥ +ç²Ĵ å¾Ħ +S hel +Ġleft overs +èĤ¡ä»½ æĢ»æķ°çļĦ +Ġax i +MC U +-re port +åľ¨çº¿ éĺħ读 +chem ia +äºĮ æĪĺ +-c i +ä¸İ åħ¬åı¸ +å¤Ħ äºĭ +èİ Ĩ +ĠTest Case +Ġgram matical +讲 äºĨ +ï¼Į éĻį +ĠAfric ans +ãĢģ 建 +ĠH G +å¼Ģ åºŃ +Ġbl ush +(c rate +(file Name +ãĢĤ以ä¸ĭ æĺ¯ä¸ĢäºĽ +Ġs clerosis +å¾® ä¿¡åı· +ĠIn ject +èµĭ å̼ +æĸ°çĶŁ åĦ¿ +Ġmark ings +Ġ× IJ +æľī è¶³å¤ŁçļĦ +uct ive +ĠHom ework +Ġun checked +å±Ĥ åĴĮ +ĠDr inking +ĠVol vo +Ġar senal +, 没æĥ³åΰ +- response +让 ä½łçļĦ +å¥ĸ æĿ¯ +å±± æµ· +ãĢį çļĦ +ĠP ax +ĠKend all +ĠMillenn ium +a vers +m gr +ut ta +çī¹ éĩĮ +To Int +æ²Ļ é¾Ļ +æĭ¿ åİ» +äºĮåįģ ä¸ī +æĢ§è´¨ çļĦ +D ual +Ġp ÅĻ +æŃ£ æ°Ķ +uk es +ĠO vers +çłĶç©¶ æĬ¥åijĬ +earn ed +ĠL ef +ID C +æĬ¢ 夺 +å·®å¼Ĥ åĮĸ +ĠCe iling +Ġnewcom ers +éĺ ĸ +late x +åĴĸåķ¡ é¦Ĩ +ĠFranch ise +Ġ è¿Ľè¡Į +fig ures +åı¯ä»¥ ç͍æĿ¥ +æİĮ 管 +.ed itor +b os +ĠNeed less +. ACTION +on ial +ï¼Į æĬ±çĿĢ +enu ine +åİ» çļ® +èĤ¡ä»½ 转让 +Ġr n +污æŁĵ éĺ²æ²» +\ varphi +-t aking +Off line +Ġd re +Ġwith holding +Ġ æĿ¥æºIJ +Ġ Ñı +Ġmake over +éĩĮç¨ĭ ç¢ij +Ġcont ender +å¹² è´§ +æĪ´ åı£ç½© +ĠThous and +çļĦ èĦļæŃ¥ +ĠW itt +ib el +ç§ĭ é£İ +Ġcam per +è¢ľ åŃIJ +_b asic +ĠHarm ony +ãĢĤ ä¼ļ +any thing +æī« è¿ĩ +Ġatt ribution +_P C +Ġcompl ied +ä½ĵ æĵį +ĠJer seys +Ġpat hetic +èĹı 书 +è¶ĬæĿ¥è¶Ĭå¤ļ çļĦ人 +ĠC elsius +m h +ï¼Į æĸĩåĮĸ +ï¼Į åĩ¤ +ä¸Ń æĿ¥ +ĠK od +åĪ© 害 +åĿļ 强çļĦ +éĥ½ä¼ļ 被 +E ff +æľī ä¿¡å¿ĥ +ary ing +Ġro lex +ĠGu pta +-w arning +AI æĬĢæľ¯ +ĠJer ome +I oT +åľ¨ ä¸ĸçķĮ +Ġep oxy +躬 身 +- cloud +ĠT owers +Ġpromot ers +ĠP UT +æĪĸ å°Ĩ +ï¼Į åĨľæĿij +High lights +.c lean +Access Token +çݰå®ŀ çĶŁæ´»ä¸Ń +Ġhall uc +ï¼ģ ä½Ĩæĺ¯ +ĠOut s +ï¼Į äºī +Ġb ouncing +ĠWork force +äºĶ ä¸ĩ +楼 æĪ¿ +E I +AN CH +ĠReg Exp +é©» æīİ +æĪIJä¸Ģ åĽ¢ +åĽ´ç»ķ çĿĢ +Ġgut ters +åºĶç͍ åľºæĻ¯ +ä¿ĥè¿Ľ äºĨ +.in ject +大 头 +Ġnew line +Ġbirth days +æľī ä»·å̼ +ĠReg ression +è±Į è±Ĩ +ç½Ĺ åħ° +è¿Ļæł·çļĦ æĥħåĨµ +æĹ¶éĹ´ æĿ¥ +èĨ º +ĠCEO s +å¤Ħå¤Ħ éķ¿ +ä¹ĭ æľ¬ +æ°´ ä½ĵ +ãĢĤä¸į ä¹ħ +ĠOl iv +Ġst int +ĠE rie +èIJ¥ åĪ© +çIJĨ åıij +çŃī 产åĵģ +Comp ression +æķĻ å£« +Ġpred nis +æŁĶ软 çļĦ +ĠPill ow +X I +ĠRE F +åı¯ 羣æĺ¯ +_n ative +K ath +Ġè¦ģ çŁ¥éģĵ +åŃĶ çļĦ +çŁ¥ åºľ +So on +Ġbin omial +æļ´ é£İ +为 客æĪ·æıIJä¾Ľ +ĠSher lock +ï¼Į èĦ± +ĠM ild +大 好 +大 å¦Ī +ä¸īå¹´ 级 +t rial +Ġv ap +éĶ Ħ +Ġam mo +ï¼Į ç«Ļ +çα ä¸ĬäºĨ +åı¦ä¸Ģ ä½į +ag ogue +Ġnarrow ed +ient e +', [' +âĢ º +对 å³Ļ +Ġvill agers +éĩijåŃĹ å¡Ķ +f rey +æŀ¶ çļĦ +ĠLog ging +é̏ é£ŀ +Ġv iz +ĠStart s +Ġcorrel ates +ĠN SD +.F ull +A FE +get String +å·¥ è£ħ +ç¾ § +ç²® èįī +æĺİ æ²» +Ġdi vert +è°Ī èµ· +ç¼Ķ éĢł +: e +. axis +Ġstring With +åĪĩ åı£ +med ical +Ġ åķĨ +ĠAugust a +è§Ħ模 åĮĸ +Ġbrief s +Ġoverse es +Ġl ashes +æĸ¹ æĸ¹éĿ¢ +çļĦ çľ¼åħī +âĦĥ ãĢĤ +N FL +åıį è¿ĩæĿ¥ +å»¶ 误 +_PR IVATE +ĠW alls +ĠL ys +Ex planation +Ġev olves +åıĸ æł· +æĢĢ çī¹ +ç¥Ń åı¸ +Ġcort isol +re ceived +First ly +åįģå¹´ åīį +èī°éļ¾ çļĦ +Know ing +æīĭæľº ä¸Ĭ +া ঠ+Ġ åħ¨åĽ½ +ä¸į ä¸ĭæĿ¥ +é«ĺ æ°´å¹³ +æĢ» èĥ½ +离åIJĪ åύ +ä½ľ ç͍äºİ +az el +èİ« è¿ĩäºİ +ht a +è¿ij çϾ +IGN ORE +Ġanten nas +] ', +为 代表çļĦ +æķĻåѦ 楼 +æĭĮ åĮĢ +Ġbl urred +æĶ¾å°Ħ æĢ§ +Ć ą +, åΰäºĨ +re ve +çļĦ åIJĪåIJĮ +ï¼ļ æľ¬æĸĩ +Ġtoler ant +ï¼Įå°± è§ģ +\t ilde +Mon ster +Ġ ï¼į +åĨ· æ°Ķ +èĥľ åľ° +å¾Ī å¥ĩæĢª +Ġrespons iveness +Ġstra ined +_ex ample +ç®Ĭ æĥħåĨµ +Ġa ide +æĸ¹ åºĶ +çIJĥ å½¢ +ott ages +å®ļ çIJĨ +Ġsp elled +å¸ĥ è¢ĭ +Ġric hes +M odes +re cht +é¢Ħ è§ģ +Ġvacc inations +Ġtox in +T oy +ï¼Į æİ¨èįIJ +ĠW att +åĸĦ æĦı +. ini +æį¢ å±Ĭ + Ŀ +Ġ åħ± +ä¸į æıIJ +天 æķ° +åĪĽéĢłæĢ§ åĬ³åĬ¨ +å¤ Ļ +Ġtim ers +ï¼ĮæĮĩ çĿĢ +æĹ¶ éľĢè¦ģ +åŃ© åĦ¿ +anc ock +ï¼Įä»ĸ æĬĬ +å¹² å¹²åĩĢåĩĢ +æĬĵ æīĭ +ĠCarol yn +æĥ³è±¡ ä¸ŃçļĦ +Ġl ombok +èIJ¥ä¸ļ å¤ĸ +ĠJ ol +ï¼ĮæĪij ä¹Łä¸į +check ing +Ġre const +Ġwh ims +æĹ Į +åĴĮ åIJĦç§į +An imated +, å®ī +Ġadd Criterion +é» Ŀ +ĠMin isters +Ġ és +ä¸į 注æĦı +ç§»åĬ¨ çļĦ +Ġun avoid +ä¸ĢäºĽ å°ı +Ġcolumn ist +_AR M +) }) +ãĢĤ æ´»åĬ¨ +ç¡Ŀ éħ¸ +**** * +Ġdors al +ĠS utton +æĺ¯ æĸ° +res se +F uel +Ġtra vers +sh an +æĿĥ è¯ģ +ë © +ĠT ER +Ġtrans genic +åģľ æĶ¾ +Äģ n +常åĬ¡ å§Ķåijĺä¼ļ +.load s +v il +ä½ł éĤ£ +æĪij们 åºĶ该 +ï¼Įçľĭ æł·åŃIJ +å¤ĦçIJĨ 好 +ĠMaz da +Ġ' .$ +æĪĸ åħ¶å®ĥ +å®¶åºŃ æķĻèĤ² +éŁ³ä¹IJ åѦéĻ¢ +SK U +ä¸Ń ç«ĭ +éķ¿ éķ¿ +ï¼Įå¿ħ å®ļ +ç§ĺ å¢ĥ +.p rev +Ġsc oped +, æŃ¤æ¬¡ +A wait +ĠVis iting +ĠFind s +带 ä¸Ģè·¯ +\ setminus +urs es +ali ases +对 人 +åĨĽ æ°ij +Ġbar ley +åĬ¨ 人çļĦ +Ġre aff +. ^[@ +Ġfin ed +ï¼Įè¿Ļ ä¸ĢåĪĩ +ä¸į æ¯Ķ +Ġcav ities +ï¼Ľ ãĢĬ +ĠSettings Accept +åı¯ä»¥å¸®åĬ© ä½ł +åĭĺ æİ¢ +åºŁå¼ĥ çī© +Ġincarcer ation +ï¼Į å¸Ŀ +=' $ +Ġwarm ed +ĠSp iel +ä¸Ģæł· äºĨ +ĠBroadcast ing +çļĦ éŃħåĬĽ +责任 人 +ĠStri pe +ĠJ O +çĤ ķ +ç§Ł åĢŁ +Ġbroadcast s +ĠO mn +åĪĨæŀIJ äºĨ +Ġmis car +ĠCere mony +ä¸ĭå®ļ åĨ³å¿ĥ +ãĢĭ æĺ¯çͱ +åĴ« å°º +ĠS erg +æ´» åĬĽçļĦ +ĠAnt arctica +ul g +åħ¶ å®ĥçļĦ +å½ĵ æĻļ +亲åŃIJ éī´å®ļ +ãĢĤ åİŁæľ¬ +д а +ï¼Įåľ¨ ä»ĸçļĦ +å¦Ĥæŀľ æĪij们 +è´Ń 车 +ĠLEG O +å¼ ij +Non null +/ users +ï¼Į 带æĿ¥ +_comp are +Ġap ologies +ï¼Į èĶ¡ +åĬŁ èĩ£ +Ġvag inal +Ch rom +-l ib +Ġatt enuation +ĠDark ness +) f +. after +Ġge ological +V iet +au coma +ãĢģ è±Ĩ +鲤 é±¼ +æºIJ çļĦ +çĶĺ æ²¹ +- era +Ġb w +ï¼ĮæĪij ä¸įæĺ¯ +J udge +ir con +ĠNick el +R ights +up us +ĠMar ble +(s lot +z ek +ĠI ST +ĠHol t +engine ering +åįµ å·¢ +ä»Ģä¹Ī äºĨ +Ġwa ive +ä¹Ł éĢIJæ¸IJ +æĹ© äºĨ +iam eter +Ġinvent ive +éĿ¢çĽ¸ è§ij +ï¼Į å¹¿ä¸ľ +Ġ> :: +注æĦı åΰäºĨ +æ²ī æ²ī +ï¼Į æ³° +ãĢģ æĸ¹æ³ķ +绿 çģ¯ +为 åįķä½į +ãĤ § +ĠSh ops +Ġsens ations +ver ified +Ġper cussion +Ġdeg enerate +ä¹± ä¸ĸ +èĩªå·± äºĨ +Ġexempt ions +ä¸ĵåįĸ åºĹ +åĴĮ èµµ +Ġ ä¸Ńæĸĩ +ĠU d +Ġinadvert ently +( theta +è¶Ĭ éķ¿ +Ill uminate +ï¼Į åģ¥åº· +ert il +åĩ¶ çĭł +äºĮæīĭ 车 +crib es +ï¼Į çªģåĩº +ĠAl one +Ġshowc ased +$ } +ĠB ian +Ġpost ings +æľ¨ éŨ +åĥı ä¸Ģ个 +ĠRE PORT +. ctx +人åijĺ åĴĮ +æIJŀ æ¸ħæ¥ļ +ĠRoman ian +Ġupholst ery +çļĦ åķĨä¸ļ +Ġdel inqu +ç»ıæµİ æįŁå¤± +ym ers +ä¸įçŁ¥éģĵ 该 +L ew +ĠI U +åľ¨ åIJİéĿ¢ +为 æķ° +Ġsens ational +ï¼Į æ¯ĶèµĽ +_ Un +Author ity +ç½ķ è§ģçļĦ +en burg +Ġdi pped +ä¸ĥ 大 +Pattern s +ï¼Ł ä¸įè¿ĩ +çļĦ人 æ°Ķ +Ġflux es +ä¹Ł 该 +ãģ Ń +åij³ åĦ¿ +Ord inal +ĠP Y +, åħ¨åĬĽ +ä»İ ä¸Ĭ +æľĽ äºĨ +Ġsle w +æ·± æĦŁ +ad io +èĦij åIJİ +éģĹ çĹĩ +æ²¹ ç®± +ĠLind sey +ç»ļ 丽 +被 éªĹ +æµ· éĩı +d igit +Ġ æľī人 +ãĢĤ å¹³æĹ¶ +è¿ĺæĺ¯ ä¸į +ĠDev Ops +Phot ography +空 èħĶ +éĢĴ å½Ĵ +Ġan eur +plic ates +ĠLe aves +o C +éķ¿ åģĩ +Event ually +ï¼Į ä»Ģä¹ĪæĹ¶åĢĻ +åıĹ çļĦ +æĹł éĻħ +年代 çļĦ +Ġra ining +g io +Ġsm ashed +åħħ满 çĿĢ +åįĪ å¤ľ +ĠPres byterian +C rystal +Ġ\ ` +èĴ ¿ +Ġent ail +Ġun resolved +å¿ĥ åħ¨ +åĨľ æľº +ĠSent inel +åľ° åĬ¿ +Ġperson als +ç§° å¾Ĺä¸Ĭ +æ´ģ çϽ +-se lected +Ġ* >( +çŃī 诸å¤ļ +ĠLaure l +@@ @@ +åĨĽ æľº +ĠInj uries +éĶ ¢ +boot strap +Ġflee ing +( 以ä¸ĭç®Ģç§° +, è¿ĽèĢĮ +- change +æĪij们 æĿ¥ +èĩªçĦ¶ çķĮ +çļ± çľī头 +天 æĺŁ +ï¼Į人 åı£ +Ġster ling +Ġ æĽ² +Ġlip ids +ï¼Įåħ¶ä»ĸ 人 +Ġ{ - +Ġinvari ably +åı¯ 没æľī +Ġmult icultural +åĴĮ åĽ½éĻħ +ĠIllegal StateException +ĠCollect or +âĢľ åħŃ +res erved +(p ost +çͳ è¯ī +ãĢĤå¦Ĥ åĽ¾ +Ġad am +èģĮä¸ļ éģĵå¾· +æĿ° 伦 +åĬ¨åĬĽ åѦ +all ows +æ³ķå¾ĭ æĦıè§ģ书 +å¼Ģåħ³ 管 +ĠPal ette +med ian +ä¼ł è®° +Ġmon oclonal +Ġrev oked +Ġconsum es +Tor onto +ãĢģ æĮĩ导 +æĿ¡å½¢ çłģ +ĠJ ab +-cert ified +åĩº èĩªå·±çļĦ +éĥ½ å¼Ģå§ĭ +èĤĨ èĻIJ +空 äºĨ +dec imal +Ġpist on +ĠDest iny +, åIJĮæ¯Ķ += [" +第 åįģä¸ī +å®ŀçݰ ä¸Ĭè¿° +Ġpool ing +Ġincident al +ĠParticip ation +å°ı å®Ŀ +Ġtake over +Ġunrest ricted +ä¿Ŀåģ¥ åĵģ +Fr anc +pt ime +< head +Ġ èĤĸ +ab outs +çŃī级 çļĦ +im us +åģľ ä¸ĭäºĨ +ï¼ĮåĨį ç͍ +ĠP anc +_b ad +Ġrecept ive +åħļ é£İ +ï¼Įåı¯ ä»ĸ +æł¸å¿ĥ ç«ŀäºīåĬĽ +Ġpal let +ĠG rac +åı¯ä»¥ çIJĨè§£ +ĠRe vere +ï¼Įä¸Ķ æīĢè¿° +B ERS +âĢĶ as +è¯Ĺ è¯Ĺ +ï¼Į åıĸå¾ĹäºĨ +pp ermint +天 å°Ĭ +tern ess +ï¼Į æĦıåij³çĿĢ +人 ä¸Ń +list en +ĠPres ervation +Ġpiss ed +æ²»çĸĹ æĸ¹æ¡Ī +Ġcarbon ate +ï¼Įä¸į ä¹ħ +离 åĪ« +. record +E PT +è¿IJ è´¹ +ĠBent ley +ãĥķãĤ ¡ +éĢŁåº¦ åĴĮ +ĠH int +itone al +Ġb iz +Ġin organic +女 æĸ¹ +Ġobject ively +Ġunset t +-f ood +{ frame +ĠDis pose +Ġsw ell +æĺ¯åIJ¦ æĺ¯ +ĠPort rait +Ġsub title +Ġpean ut +ĠConfeder ate +g w +ï¼Į 设 +å¤ĸ åħ¬ +æĭī å¼ĢäºĨ +å·´ æĸ¯ +åĽ´ æłı +伤 çĹĽ +u aries +ï¼Įå°± éľĢè¦ģ +ĠRog ue +im ble +ç͵ ä½į +æ°´ åĬ¡ +æĸŃ å®ļ +plit ude +ur ricular +nd on +æĸ¹ åĿĹ +Ġfib res +s cheme +ï¼Į 绣ä¸Ģ +Ġv iv +å¤ı 天çļĦ +Ġmicro f +Ġcow boy +港 èĤ¡ +Ġrad ii +\ sim +âĢĿ æĹ¶ +ä½ł æĥ³è¦ģ +çłĤ ç³ĸ +å®ŀè´¨ æĢ§ +( items +ĠK olkata +大åѦ æ¯ķä¸ļ +Ġcatch y +å¹´ çĶŁ +åĨ³ æĸĹ +Ġimm utable +REG ISTER +Ġ éĺħ读 +Ġcle ars +è§īå¾Ĺ ä»ĸ +å᫠士 +nut rition +) ]( +f name +ï¼Į æĬķ +se ctor +ubb ard +. Extensions +CR A +Ġburst ing +å°± å¾Ģ +å£ ķ +ĠÐ ľ +Ġconve ction +åĮł å¿ĥ +Ġobl iv +( sw +åĬ¨ æĦŁ +缼 ä¼ļ +. av +Ġenvelop es +á Ł +ĠS hed +缼 è¡Į +ĠProt ected +ĠInv oke +èĮ¯ èĭĵ +Ġder ives +æīĢ æĢĿ +. unit +C oc +R uby +ĠE SC +exper ience +. IP +ï¼Į èĩªçͱ +Ġexpans ions +: ss +çļĦ è¿Ļä¸Ģ +Ġcommut ing +å±± èᝠ+ĠOb amacare +çĶľ åĵģ +Gen esis +ĠSide bar +æĪĸ åľ¨ +çļĦä¸Ģ å¼ł +Ġexc ursions +ï¼Į ä¼´éļıçĿĢ +[ row +RO UT +éĩijå±ŀ æĿIJæĸĻ +Att ention +, åIJ´ +Rob in +ï¼Į使 ä¹ĭ +( org +Ġdivers ion +çļĦ åį±å®³ +Ġpo ke +伤 人 +æĺ¯å¯¹ çļĦ +" How +. theme +ä½İ èIJ½ +Ġter restrial +ÈĻ i +ï¼Į æĤ¨çļĦ +æ³ ĵ +aaaaaaaa aaaaaaaa +ĠCau chy +Ġblock er +éļIJ 身 +è¾ĵéĢģ 带 +Ġpre tt +éĴŁ å±± +ĠG uns +Ġalk yl +- equiv +ĠEl f +Ġty res +Ġl m +æł ¾ +Ġturb o +/ (( +il oc +çİĭ éĽĦ +èıľ 鸣 +çļĦ æĶ¶åħ¥ +è¡Į åĨĽ +mas ters +Ġrev oke +èŀºçº¹ æĿĨ +Ġdep ended +ĠVar iety +Ġv l +Ġcl iffs +sc ode +åľŁ å·¥ +UI View +ï¼Įä½Ĩ 对äºİ +åijĺ å¤ĸ +Ġ! [ +ç¿» æĸ° +Ġancest ral +-n ull +Ġvig ilant +educ ation +ãĢģ éħĴ +çĸ¼ çα +ä¸į 妥 +åĽĽ åĪĨ +Ġpharmac ist +ĠPerson nel +ëı Ħ +ï¼Į åIJ¯åĬ¨ +To Array +ĠNumer ical +ï¼Įä½ł åİ» +Ġpeace fully +åľ¨ 身边 +Ġnon ce +Ġhom icide +åĨħ å¹ķ +ï¼Įè¿Ļ ä¸ĭ +ĠKel ley +ç§ij çļĦ +ding er +Ġresource Culture +çĮ® ç»Ļ +ĠèĢĮ åľ¨ +äºĭä¸ļ åıijå±ķ +ï¼ĮæĢ» éĥ¨ +纲 è¦ģ +ãĢģ ãĢĮ +Pro posal +ï¼Įä½Ĩ ä½ł +åħ¬å¼Ģ æĭĽèģĺ +.Set tings +é«ĺ å¤Ħ +æ¶² ä¸Ń +èĥľ è¿ĩ +çĽ¼ æľĽ +第ä¸Ģ 款 +è¿· éĽ¾ +t emplates +ĠE QU +clos est +M AR +et cher +ĠSt okes +ä¸ĥ æĺŁ +ĠBE FORE +ĠG iov +èĩªçĦ¶ç§ijåѦ åŁºéĩij +_ plan +Ġun question +Ġm olar +_gener ic +æĭī åĬĽ +èµ°äºĨ åĩºåİ» +èµļ åΰ +ï¼Į æĶ» +Ġmethod ological +]{ }\ +æľ¬ æľĪ +Ġmed ial +_ radius +ï¼Į éķĩ +éĿŀ éģĹ +äºĭå®ŀ è¯ģæĺİ +Ġstabil ized +Ġs ank +ï¼Į 梦 +èĢģ èĢģå®ŀ +Y TE +Ġp aced +éĩij æĸ¯ +æŀĹ æ¸ħ +Ġcorrect ive +ĠCalling Convention +ol ulu +ĠNg uyen +ĠS CC +=" + +ãĢģ æĪIJ +éĺħ åİĨ +Ġd ine +ĠW arn +IC ON +arth ritis +天 èµIJ +åĬ¨ 车 +åħ³èģĶ åħ³ç³» +ï¼Į ç¬¬åĽĽ +ç¯ĩ å¹ħ +西åĮ» ç»ĵåIJĪ +Ġl ava +太 ä¸Ĭ +éĿŀ çī©è´¨æĸĩåĮĸéģĹ产 +åĬ© åѦ +èĭ±åĽ½ çļĦ +åıijéĢģ ç»Ļ +æĬĢèĥ½ çļĦ +ĠJac qu +Ġsupermarket s +Ġr ation +交 æĥħ +Ġbicy cles +Ġmos que +Ġrain forest +ĠVan illa +à§į ঠ+ãĢģ èij± +ï¼Ł è°ģ +æķħ æĦıçļĦ +El astic +Ġbul ly +\ Vert +) is +ĠAl ign +ï¼Ľ åħ¶ +Wh ilst +irs ch += tf +Ġshow room +ãĢģ æ¹ĸåįĹ +ï¼ļ ç͍ +ĠEq s +> % +Rel oad +å¿ Ĵ +ĠWork out +夹 æĿ¿ +ri ot +ip so +Ġeight y +. Order +Ġe e +ï¼ĮèĢĮä¸Ķ è¿ĺæĺ¯ +Ġout bound +代 åħ¥ +åĻ İ +uth an +è¯Ĺ æĸĩ +ï¼Į没æľī ä»Ģä¹Ī +èĩª å®¶çļĦ +Exp ressions +ANG LE +ĠAzerbai jan +: name +龸 主 +åħ³éĶ® æĺ¯ +ï¼Į å·¥ä¸ļ +Ġsc rib +Id e +请 èģĶç³» +B rief +Ġpast oral +ĠT attoo +ãĢģ èĵĿ +åįģ æĿ¥ +ãĢĭ æĽ° +æĪij åı« +ä¸ĭ 头 +åĽł æĸ¯åĿ¦ +èī¾ ç±³ +大 çϽ +Ġcont iguous +_m issing +Any thing +ĠRam an +æķĸ æ²IJéĺ³ +_ verify +Y OU +ï¼Įè¿Ļ åľ¨ +Ġ> / +å±ħ äºİ +åĶł åı¨ +Ġbipart isan +Ġg ait +âĢĿ é¡¹çĽ® +Ġre think +ç±³ ç²ī +Ġoverwhelming ly +å¾Ĺ å½ĵ +æijĩ æĽ³ +ä¸Ģå¹´ åĨħ +çĽ¸å¯¹ çļĦ +端åįĪ èĬĤ +N u +å¾Ī æŃ£å¸¸ +è´¨ æ£Ģ +/dat abind +ĠL ey +_p atch +Ġsl ender +Ġq t +认åı¯ çļĦ +ï¼Įè¿Ļ æĦıåij³çĿĢ +èĩª ç«ĭ +_t ail +_d ead +ï¼Įæĺ¯ ä»ĸ +re ceive +Object Name +id ium +oun cy +寺 éĻ¢ +ĠC IO +æį® æŃ¤ +_f eed +ï¼Į该 åħ¬åı¸ +西 æ±ī +. Editor +Ġspat ially +ra ight +ĠApp Compat +Ġintr usion +ĠEston ia +Ġ åħ·ä½ĵ +Ġw rench +åŁº äºļ +Adv ance +W izard +er ity +ãĢģ åıĬæĹ¶ +ire z +Ġg m +Ġscreen ings +cuss ions +_res ources +Organ ic +室 åĨħçļĦ +aph rag +ç»ıèIJ¥èĮĥåĽ´ åĮħæĭ¬ +Ġ 饰æ¼Ķ +çĹ ¿ +Ġ第ä¸ĥ 竳 +æĺ¯ æĿ¥ +æŀľ èͬ +Ġemail ing +æľīä»Ģä¹Ī åħ³ç³» +Ġmin er +ä¸Ĭ æĿ¥è¯´ +N early +ich let +常 æľī +block quote +ĠA FC +象 æ£ĭ +Ạ¿ +Ġoverrid den +ĠS ink +ect l +Ġprot obuf +çĬ¶æĢģ æĹ¶ +, æĹ© +- player +le z +Ġen listed +å¿ĥ æĻº +åİ» åIJij +ç®Ĺ ä¸įä¸Ĭ +-t ailed +iver ing +α ν +ç͍ åħ· +}{ }{ +å¿ł äºİ +Ġunder grad +ç±» 产åĵģ +Ġcirc a +æİº æĿĤ +Ġirrit ating +Ġsail ors +ĠT oll +ĠSt em +ĠTw elve +æĩĬ æģ¼ +ä¸Ģ çѹ +_m onth +å¼ł çĭĤ +ä¿® 羣 +C ath +ãĢĤ é»ij +Ġinstitut ed +æŁIJç§į ç¨ĭ度ä¸Ĭ +ĠGeorg ian +ri que +.n umeric +Ġparticular s +Ġwin ters +ãĢĤ æĭ¥æľī +ĠM VC +æīĢ ç͍çļĦ +æķ£ åıijåĩº +æĿ¥æī¾ æĪij +Ġqu itting +ãĢĬ å°ı +å±± 人 +空æ°Ķ ä¸ŃçļĦ +Ġ æīĢè¿° +_pro vider +Ġaward ing +ä¸Ģ 颤 +ĠA min +åΰ è¿Ļ +ĠWe aver +expect s +Ġinst itutes +æĮģæľī人 ä¼ļè®® +ï¼Į 羣æŃ£çļĦ +çı © +åıĽ ä¹± +æµģ éľ²åĩº +_DE LETE +Ġ× Ķ +over nor +å±ħ å§Ķä¼ļ +Ġcontain ment +æĭ¼ å¤ļå¤ļ +常è§Ħ èµĽ +对å¤ĸ å¼ĢæĶ¾ +N b +ä¼ļ åıĹåΰ +ere f +ç»§ç»Ń 说 +è¿ ¥ +å·²ç»ı å°Ĩ +Ġrem anded +éĢļè¿ĩ æīĢè¿° +åĿĩ çͱ +èµ¢ å®¶ +ĠFac ial +åįĹ éĺ³ +åı£ ä¸ŃçļĦ +åĬŁèĥ½ åĴĮ +ãĥ¼ ãĥĪ +Ġh oop +大 çģ¯ +çļĦ å§¿æĢģ +ãĢģ åĮħè£ħ +ãĢĤ æ±Ł +ü ck +æĬĺ 弯 +iv irus +èĬĤ åζ +ï¼Į对 ä¸įèµ· +_back end +Ġem itting +å¥ĭ åĭĩ +ĠVolunte ers +Ġpl as +æĶ¾ æĺł +éĿĴ è¡£ +ĠFriend ship +ĠO V +Ġk Hz +text sc +.op ens +èĢĮ éĻį +Ġgener ality +羣 çļ® +airo bi +éĥ½æľī åı¯èĥ½ +å¦Ĥä¸ĭ åĽ¾ +_se g +.f c +S RC +Ġproc rast +ä¸į éĹ® +ãĢģ åIJij +Ste el +çľ¼ è¢ĭ +æľ¨ åħ° +_ phy +çŁ³å¢¨ çĥ¯ +ĠX V +="@ + +åºĶ 纳ç¨İ +.p ayload +. En +è¿Ļä¹Ī 个 +ĠCalcul us +U rban +Ġs dk +ĠC yt +c ulture +åĴĮ åĪ«äºº +ĠRespons ibilities +ï¼Į æ·±åľ³ +ult on +第 åįģä¸Ģ +" å°ı +U åŀĭ +in cluded +ï¼Į L +æĭį æĪı +å¾Īå¿« å°±ä¼ļ +ĠRen ov +ĠReg ions +-S emit +CAP TCHA +ä¸Ń åħ´ +ç¼ł 绵 +Sal ary +ĠM aver +ï¼Į 头åıij +Ġplant ation +( False +ĠE rd +éķ¿ é£İ +"] =" +Ġpast ors +ĠR ak +åΰ å°¾ +åĩº åĬĽ +éģĹæĨ¾ çļĦæĺ¯ +_S UP +ĠHam mond +F rag +ĠS UPPORT +ĠP on +è¡ ® +sp irit +-pack ages +qu ares +便 被 += # +Ġe urop +Ġann um +, 主 +åºĦ æĿij +Ġgamb lers +Ġ$$ ( +Ġcentr ally +Ġ 奥 +Ġm ai +ĠS UM +ä¹Ł å°±ä¸į +Victor ia +æľī åĩłåĪĨ +åļ· åļ· +ent iful +ĠF em +æĶ» åħ³ +Ġsubsid y +A aron +Ġble ach +Ġbull ish +Ġd osing +æĪij们 å®¶ +ĠChe rokee +å¤ľ 空 +ĠPOL ICY +åĴĮ å¸Ĥåľº +_c amera +Ġconvey ing +Ġm ating +ĠID S +, ä»¿ä½Ľ +ĠA ux +è¿ĺ ç͍ +Ġdam ned +é²ľ æ´» +Ġpric eless +å¹½ åĨ¥ +ï¼ĮäºĮ æĺ¯ +\ mathrm +ï¼Į èĢĥçĶŁ +á r +ĠBless ed +å°ıä¼Ļä¼´ 们 +ãĢĤ åįİ +ass ignment +Ġreason ed +éĩijé¢Ŀ 为 +å°Ĭæķ¬ çļĦ +[ g +ï¼Į 注åĨĮ +Ġm ute +Ġst ab +åįĸ æİī +ï¼Į æĢĿ +è¦ģ ç»Ļ +Ġdivers ification +Monitor ing +ä¸Ńåħ± ä¸Ń央 +(_ . +ĠRoad s +ä¸Ĭ æĿ¥çļĦ +ï¼Įä¹Ł ç®Ĺæĺ¯ +Ġwithdraw ing +Plan et +. ptr +Ġ æĥ³åΰ +Ġp ony +ãĢģ äºļ +ä¸Ģä»¶ äºĭæĥħ +ĠLe aving +ĠClass ics +æŃ£ çīĪ +ï¼Įåı¯ä»¥ æł¹æį® +Ġresemb ling +P ink +Ġpath ogenic +Calcul ator +< j +ĠT ues +Ġsp indle +Ġhome ostasis +Ident ify +æľ´ å®ŀ +Ġ æīĭæľº +Ġpl umber +åĪļ ä»İ +Ġair borne +level s +ä¹Ł æĽ´ +opt ic +-c ampus +ï¼Į她 æīį +æĦ£ æĦ£ +ï¼Ł æĺ¯ä¸įæĺ¯ +ig ibility +Y ep +en eg +ï¼Į å±ķçݰ +enc rypt +Ġex ile +ä¸ī äºĶ +Ġw oo +Ġcra ve +_OPT IONS +éĥ½ åħ·æľī +èĵĿ åŃĹ +Ġvoc ab +é¦ĸ è½® +æĪIJ æŃ£ +èĥ¶ æ°´ +èĿ Ĺ +Ġdict ators +ĠK ia +Pro d +é¼» æ¶ķ +Ġnom inees +comp at +Ġt rench +ĠF unk +com be +ä¸Ģå®ļ ç¨ĭ度 +_ rm +å¸ĮæľĽ çļĦ +说è¿ĩ è¿Ļæł· +Ġ éŨ +Ġin mate +_ rad +æĿľ é¹ĥ +FER ENCE +ĩ Ĵ +Ġe iner +ä¸į 平衡 +ãĢģ çī¹ +åĬłåħ¥ ä¸ŃåĽ½åħ±äº§åħļ +å¿Į æĥ® +Ġhalt ed +(in ode +åį¡ ç½Ĺ +åĶ¿åIJ¸ éģĵ +ãĢĭä¸Ģ 书 +ä¸Ģèµ·æĿ¥ çľĭçľĭ +ĠB unny +åĪĺ 举 +ĠSom erset +碳水 åĮĸåIJĪçī© +ĠLG PL +_ rep +ff s +æĻĵ æĻĵ +Ġplace ments +çģ« å½± +çī¹å¾ģ çļĦ +åģ Į +èĢĥè¯ķ æĪIJ绩 +Ġd yes +åĴĮ çĿ¦ +ĠAc res +C ID +Ġ ç±»åŀĭ +ĠThe ology +oc aly +ç®Ģ éĻĭ +缼 大 +-by te +ĠC ute +åĴĮ åľ¨ +æĹł çķı +Ġmom my +Ġow es +ĠT os +ĠD IG +æĶ¯ 票 +æĪ¿ è´· +ĠImport antly +ï¼Įä¹ĥ æĺ¯ +ĠP overty +èĩª çIJĨ +æıIJä¾Ľ äºĨä¸Ģ个 +ãĢĤ â̦â̦ +éĵģ éģĵ +缺 æ°§ +Ġfi ery +Ari zona +ĠH ou +éģ® çĽĸ +Emb ed +Ġv ibes +åĮĪçīĻ åĪ© +Ġsub conscious +èį¯ æ°´ +< s +Ġ åįĬ +_s mall +çļĦ æĢ§è´¨ +_h ome +Ġtroubles ome +/ off +Ġk itten +ï¼Ľ ä¸īæĺ¯ +ï¼Įä½ł ä¸įæĺ¯ +æİ¨ åIJij +TR AN +èĮ¶ åĩł +缸åħ³ æ³ķå¾ĭæ³ķè§Ħ +Ġsaved InstanceState +åįij éĦĻ +ï¼Ł è¿ĺæľī +åģı å¿ĥ +i ère +Ġv ines +Ġimpl ode +L icensed +æĺ Ļ +ĠY E +IM A +Ġdiv ider +åĩ¯ ä¹ĭ +å¥Ķ èµ´ +Ġwork places +è·³ åĩº +Ġ; ) +çĸ«æĥħ çļĦ +and as +Ïĥ ει +ĠKy oto +çľģ çļĦ +Ġdem os +.D omain +ç²ĺ èĨľ +-co ated +L arry +缸 éļĶ +ĠST UD +ï¼ĮåIJİ æľŁ +Ġgri ps +ĠKick starter +_ aux +Ġur llib +ï¼Įä¸Ģ 身 +Ġanal ges +å¾· ç½Ĺ +Ġwave form +ï¼ĮæľīäºĽ 人 +r ifying +åı¯ä»¥ æľī +ĠZ imm +Bind ings +, åĪĨåĪ« +ĠE u +Ġcl ing +çļĦ åIJ«ä¹ī +Ġlo oming +çīĪæĿĥå½Ĵ åİŁä½ľèĢħ +( if +_ nd +Mult iply +ï¼ī = +失 常 +Ġsu icidal +Ġreg rets +Sub mission +Ġp archment +å®ī åį± +Ġtra inees +Ġrad ios +: j +å¢ŀéķ¿ çļĦ +çķĻä¸ĭ æĿ¥çļĦ +-d ir +ï¼ĮæīĢ以 她 +æIJŃ ä¹ĺ +Ġsem if +Co ach +æµĵ度 为 +ĠI GF +ĠPart icularly +大æ¦Ĥ çİĩ +ĠSloven ia +é϶ éĨī +ĠP aste +åıĸ å̼ +plus plus +ï¼Į 群 +æľ¬ åĽ½ +稳 妥 +åIJĮ æĢ§ +çĶ» ä½ľ +ĠEd ison +æ°ijæĹı çļĦ +æľ¬ å¹´ +åij¼ åIJģ +Ġpsychiat rist +æľĢé«ĺ 人æ°ijæ³ķéĻ¢ +,è¦ģ ä¹Ī +Ġast ounding +æĶ¿ äºĭ +æĬ½ æŁ¥ +Ġtag ging +å®ŀç͍æĸ°åŀĭ åĨħ容 +ĠVan essa +c et +c ultural +i ography +æĥ¯ äºĨ +带头 人 +è¡Ģ æłĵ +ĠQual ified +cept ors +åIJ« çħ³ +åŁĶ 寨 +_M AIN +ĠSand wich +ator ium +æĿ¨ åĩĮ +è´ª 污 +ĠR J +å·® äºĨ +(p ayload +æĸ½å·¥ çİ°åľº +ï¼Įä¸įè¿ĩ æĺ¯ +ï¼Į以 æıIJé«ĺ +ilit ating +function al +_ comm +Ø Į +ï¼Į ä¸ļåĬ¡ +æľ¬ éĴ± +é«ĺ æ½® +æħ¢ äºĨ +School s +ĠLore ntz +åħ¼ åħ· +åĤ² 天 +.z ero +out side +Ġweb log +ĠDE LETE +READ ME +Ġslo ppy +ĠC obb +æĹ¶ 俱 +ĠTy r +åºĶæĢ¥ é¢Ħæ¡Ī +åĴ§ åĴ§ +Ġ 广å·ŀ +ort ing +Ġle ash +天 æĪIJ +Ġel ast +纽 带 +ĠKn ife +ag ulation +Ġfur ry +æ°® æ°Ķ +G ets +åĴĮ æķĻèĤ² +çīµ è¿ŀ +ĠK et +å®ŀä½ĵ åºĹ +æ£Ģå¯Ł å®ĺ +ĠRaj asthan +åĺĪ æĿĤ +ä¹ł æĢ§ +æ²³ çļĦ +å®ŀçݰ æĸ¹å¼ı +lo it +pack ed +Ġb rom +ĠTh urs +æ¿Ģ è¿Ľ +Ġcass ette +S z +ĠAn alyze +æĢİä¹Ī ä¹Ł +åij½è¿IJ çļĦ +èµ· å±ħ +- used +_ LL +èĩªå·± åģļ +æĻļ éĹ´ +Ġdom ination +ï¼ĮåİŁæĿ¥ æĺ¯ +ĠT K +Ġg ib +æĸ¹ æŃ£ +ï¼Įæľī çļĦ人 +å« ¦ +ä¸ĢèĦ¸ çļĦ +ĠSurve illance +ou fl +Ġis Equal +æľīä¸Ģ ä¸Ŀ +ĠAdv antages +Ġ ãĢİ +Ġen ch +Ch a +chron o +B ruce +ĠCo at +Ġaud iob +ĠCor por +ĠData Frame +é²ģ æĸ¯ +Ġit ching +Ġch ased +ï¼Įä½ł ä¸įè¦ģ +(l ayer +.Code Dom +Ġpl um +æ°Ķ ä½ĵçļĦ +Ġhyp oxia +il ver +ĠApplic ants +ï¼Į å§IJå§IJ +âĢĶ not +æĿĥ è¡¡ +ĠTree Node +ãĢĤ åįķ +åĬł åºĬ +åĬ¿ åĬĽçļĦ +ĠMaur ice +çĭ¬ä¸ĢæĹł äºĮçļĦ +L on +éľ ı +ç͵åŃIJ 书 +ugg ish +Ġcontag ious +åĴĮ å¤ļ +ĠY ah +ĠÐ ł +ãĢģ èIJ¥éĶĢ +Ġappro vals +大ä¼ļ ä¸Ĭ +); \ +.D B +Ġastr onomy +çľĭ ä¸įåĩºæĿ¥ +ĠK ad +éļ¾ åłª +Ġing en +gu ided +ãĢĤ çİ°åľ¨çļĦ +æĭ¬ åı· +Ass ume +ach ines +ĠNurs es +Element Type +Ġampl ify +Ġsl it +çļĦ éĺ³åħī +amb iguous +eng lish +çħ§ 亮 +DU C +col First +Ġthread ed += head +de ath +dep ending +est ep +å¼ł åı£ +æŀĹ ä¸Ń +AG G +Ġprop ane +ost at +Ġant ic +ĠR ee +éĿŀ常 ç®Ģåįķ +( th +ĠN ed +-b eta +D OC +os ine +/ The +L BL +ĠTh ur +ĠO ste +Ġre opening +ä¸įæĺ¯ ä»ĸ +çķĻ ä¸ĭä¸Ģ +gs l +Ġacknowled gement +ĠJere miah +Ġg ren +æĥ³ ä¸Ģæĥ³ +羨 äºĨ +Ġd g +ĠB AL +ĠL augh +æ´Ľ 夫 +Access ible +ï¼Į 客 +大 åħ´ +: ä½ł +éĢł èι +åĪ· åĪ· +P oss +Ġcharacter ised +è¯ģåΏ åħ¬åı¸ +å¹´é¾Ħ 段 +çĦ ¡ +wit z +rugu ay +ile en +ang an +TR ACT +æĹ¶ 被 +èĦļ ä¸ĭçļĦ +èģĮèĥ½ éĥ¨éŨ +est ate +no ise +Ġhomot opy +.v m +ri ever +Ġacid ity +åĢŁæ¬¾ 人 +V ue +Ġg uts +ac ulture +天 éĻħ +ĠAlex andra +ĠS J +ver te +èĦ¸ åºŀ +uzz i +çļĦ 第ä¸Ģ个 +ä¸ĭ åŀĤ +Ġweek day +St ride +æĬµ æ¶Ī +çļĦ æ°ĽåĽ´ +OR G +,æĪij ä¼ļ +ĠBoot strap +ĠT ray +车 ä¼ģ +Ġintern ships +æĿ¾ æĩĪ +æĭŁ è®¢ +Decl are +Ġscream s +ï¼Į æľŁéĹ´ +ãĢĤ ä¼Ĭ +_t ra +iol a +临åºĬ ä¸Ĭ +) e +S AP +Ġwait er +Ġe a +èĢĥ è¯Ħ +æľª è§ģ +稳 ä½ı +Ġcultiv ating +W at +ĠN yg +对 æĸ° +æĿİ å®¶ +ĠOver ride +ï¼Įè¿Ļæł· åı¯ä»¥ +Ġperen nial +èµĦ åİĨ +ä¸įäºĨ å¤ļä¹ħ +Ġpun ches +I AM +dd d +ĠRe ceiver +éĤ£ä¸ª 女人 +ĠFound ations +ĠI ch +丢 ä¸ĭ +é«ĺ 强度 +Ġquick est +å¿ĥ åĬĽ +_S SL +è¦ ĥ +åĩºäºĨ éĹ®é¢ĺ +Check box +ĠWorks hops +ĠMill ions +it in +è¿ĺæľī 个 +èĵ¦ çĦ¶ +åīį æ®µæĹ¶éĹ´ +红 è±Ĩ +ili ates +_e ffect +åĴļ åĴļ +c err +人 人éĥ½ +ä¸Ń åĩºçݰ +Ġro bbed +ĠMin imal +Ġ 便 +.init ialize +å¼ł æľĽ +æ±ĩ ç¼ĸ +-e ffects +- ended +Ġbureau c +Ġresh ape +ĠV k +YY YY +Ġpre season +ĠT oxic +ĠPhil ips +ãĢĤ ä¸įçŁ¥ +ãĢģ æľĪ +缼 åħ¸ +æŁ³ åı¶ +ĠRick y +in able +Ġar Xiv +Ġart illery +ï¼ĮåĪļ 好 +Ġ æľĢç»Ī +çŃī æķĪ +èᝠæĪ¿ +____ __ +Ġspray ing +P ok +çļĦ éĻĪ +Ġper oxide +ĠPRO GRAM +Ġpsych ologists +K id +ï¼Į æłij +ĠW ond +.nav bar +é¼ĵ èµ· +_ ONE +ĠH ogan +cl ave +æľ ĥ +æŁIJ çļĦ +污 åŀ¢ +Ġserial VersionUID +æĭĽåķĨ å¼ķèµĦ +Typ ically +æĦŁ æĢ§ +ĠMon etary +-old s +ĠDen ise +ï¼Į èĸĽ +çļĦ å°ijå¹´ +st alk +oc ene +女 éĥİ +åĤ¨ èĹı +ĠCommission ers +åħ¥ åºĵ +.D isplay +Ġbreath able +_AL T +åĬł åİĭ +arag ua +æĪĺ 马 +Ġcr ad +Ġcos ine +M es +m ixed +p ause +å§Ĭ 妹 +Ġart ific +é£ŀ åΰ +æĺ¯ ä¸ĸçķĮ +æ¶ £ +Ġsauce pan +Ġsa pp +ç»Ħ éĺŁ +- eye +Dr agon +éĴ Ĭ +ĠI PC +ob ar +æī¿æĭħ 责任 +ï¼Į天 æ°Ķ +ĠEmer ald +, æķĪæŀľ +/ output +Ġdev ise +åIJĪä¼Ļ ä¼ģä¸ļ +æĦŁ äºº +éľ² éĿ¢ +é¦Ļ çĶľ +ç²¾ æ²¹ +Ġguard ed +Ġmenstru al +st udio +ĠM amm +Ġrec ursively +isp ers +便åĪ© åºĹ +P or +n of +ï¼Į让 æĤ¨ +-p rom +ä¸į æľ½ +ĠJ ub +Ġ ï¼īãĢĤ +ed uct +ĠS AN +ĠA SE +ĠCOUR T +Ġad opts +ass oc +get Message +ä¹° åįķ +çīµ æīĭ +è¹² ä¸ĭ +éĥ½æĺ¯ 以 +!!!!!!!! !!!!!!!! +ĠC hern +åĨį ä¸į +è®Ńç»ĥ çļĦ +Ġc ray +int osh +ĠSt eele +éĢĶ ç»ı +ï¼Įä¹Ł 为 += u +K in +ãĢģ åħ¬æŃ£ +马 äºij +åĪij èѦ +åħħç͵ åύ +æĿŁ æīĭ +ĠI z +åĬł å°Ķ +åıĸæ¶Ī äºĨ +åħ¬åħ± 交éĢļ +åĩĿèģļ åĬĽ +B TC +æĵĤ åı° +æ²ī éĻį +v w +åĬł åĢį +Ġoptim isation +Ġ æ³ķå®ļ代表人 +Ġ ä¼Ĺ +ï¼Į å¡ŀ +ï¼Įä½Ĩ æĺ¯ä¸Ģ +端 ä¸İ +rot ic +Ġhand shake +Ġmus lim +.f ocus +æĬķèµĦ æĪIJæľ¬ +Fant astic +& $ +ç¾İ è²Į +l abs +ĠL ump +_m etrics +hem atically +Ġdazz ling +åѦ åĪĨ +ãĢĤè¿Ļ 款 +CS V +Ġnot ebooks +Ġgr ate +emp o +herit ance +Ġc ords +è¿Ļ éŨ +iv ate +Up dater +æ»ĭ è¡¥ +Ġbetray ed +è¿Ļä¹Ī 好çļĦ +lean ing +Ġspons oring +( keys +ĠS ect +令 èIJ¥ +B ow +rol ley +Ġclust ered +ä¸Ģ个å°ı å°ıçļĦ +ary a +产çĶŁ å½±åĵį +è· » +ĠSc opus +il og +-s hell +æIJľ çĭĹ +ĠT rap +天 åºľ +az ers +ĠRib bon +-b in +Ġfinal ists +èĩ´ çĻĮ +([ ^ +( search +å®ī å±ħ +æĬĬ ä½łçļĦ +æł¼ è°ĥ +ĠBrend a +u ators +è¦ģ èĢĥèĻij +å®Įåħ¨ ä¸į +аР± +Ġw att +ass igned +çĥĪ çĦ° +æŁ¬ åŁĶ寨 +Ġlower case +Ġroll ers +躲 å¼Ģ +ãĢĤ çŃīåΰ +Ïģ ί +C hen +éĶĭ åĪ© +isc opal +Ġsoft ened +âĶģâĶģ âĶģâĶģ +Ġbank ers +Ġv owed +Ġemp owers +è¿Ī è¿Ľ +be havior +å®īè£ħ 座 +以ä¸ĭåĩłä¸ª æĸ¹éĿ¢ +Ġaneur ys +over view +Ġparalle ls +leg ated +Ġpast ure +Ġs ailed +åŁº åºķ +play ers +ĠÎ ¶ +Ġt ummy +ï¼Į çĽĺ +Ġne arer +Ġqu aint +两 头 +åħĪ ç͍ +æŀĹ å³° +izz le +Second ly +ent imes +ãģ« ãģª +ï¼Į æŀĦæĪIJ +Ġy en +ĠThe ft +åĪĻ æľī +Ġhom ogen +Ġrevers ing +ĠAF TER +Ġ çŃīåΰ +Ġpupp et +Ġ:- ) +ile vel +Ġs words +士 é¡¿ +åIJİ åı¯ +ĠGe cko +ĠRed uced +Ġconstitu ency +ĠParam s +.S QL +åįĸ çĤ¹ +ĠPar agraph +ï¼Į æ²³ +äºĶ ç§į +( In +ãĢģ éĥij +ano i +Ġconst ipation +ï¼ĮæĪij ä¸įæĥ³ +๠Ħ +ãĢģ çİīç±³ +åijĨ æ»ŀ +book ing +ä¸įåΰ çļĦ +ç ¹ +æĪĺ 线 +ĠAutom ated +Ġunint ended +it Ãł +ãĢĤ ä½Ļ +ä¿® éķ¿ +æ¶Ī éĢĢ +s j +åľ¨ è¿ĩåİ» +E mit +éĻ¢ åĨħ +(m m +: length +ï¼Įä½ķ å¿ħ +æĥ³ ä½ł +Ġ ÅŁ +Ġs acks +åľĨ åij¨ +.l bl +åĵĢ æ±Ĥ +çĦ ± +_b ig +éĩįè¦ģ æĦıä¹ī +代 åı· +_st mt +- State +éģĵ éķ¿ +ä¹ĭ å¾Ĵ +Ġund ue +H eb +è¿ľè¿ľ çļĦ +Ġha ird +Open GL +ĠA DS +ĠTru ly +å·¥ä½ľ åİŁçIJĨ +éĻĨ å³° +-ass isted +- ground +W ang +æ°´ åľŁ +.sh ift +------------ -- +ç͵ éķĢ +ï¼ĮæĪij å°Ĩ +Begin ning +F est +æĺ¾ çĿĢçļĦ +ĠTex ans +if def +ĠL PC +对 ä¼ģä¸ļ +âĢĿçļĦ åİŁåĪĻ +Ġcritic ize +arx iv +ĠS rc +( thread +"> ' +ï¼Įåıª æĺ¯åľ¨ +åħį ç¨İ +Ġprep aid +Ġforg iving +OIN TER +æijĨäºĨ æijĨæīĭ +Ġtow ing +ĠNotImplemented Error +åŁº çļĦ +Ġw y +ĠI ris +Ġpay off +å¸ĪèĮĥ åѦéĻ¢ +Ġdiss ipation +> {{ +ĠD ESC +ĠW ifi +两 款 +work ed +rec ation +æıIJ æĹ© +èĪĮ å°ĸ +Ġcollabor ators +/ âĪĴ +Ġl ends +L azy +Ġto re +Ġsnap shots +Ġs urname +ĠIn jection +è¾¾ çļĦ +äºĶ åĪĨ +Ġes ter +Ñ ij +ĠT ee +_ $ +Ġit r +ĠH ed +_F S +.DebuggerNonUser CodeAttribute +åħ¨ éĥ½æĺ¯ +éĩį åIJĪ +æĪĺ äºĭ +dr agon +St encil +åħ´ 建 +ï¼Į她 说 +åĪĺ éĤ¦ +ĠMod ules +C ov +ï¼Į åıĮçľ¼ +Ġlo osen +æĿĤ ä¹± +Ġexcess ively +éĥ½ ä¸İ +éħįåIJĪ çļĦ +ä¸Ģ æ²ī +çŃī ä¸Ģä¸ĭ +头 äºĨ +Ġinf lated +ĠS IL +èĢĥ åīį +çĥĺ çĥ¤ +Ġd ag +çĽij å§Ķ +æĿ¡ è·¯ +æĿ¥æºIJäºİ ç½ij绾 +åľŁ 豪 +è¿ĻéĩĮ éĿ¢ +( ans +, å¾ħ +计åĪĴ åĴĮ +âĢľ é«ĺ +äºĨä¸Ģ 座 +Ġstand out +ĠRober to +çŀ§ è§ģ +ul ses +ĠY as +ĠPro posed +Ġfoot ing +çĹħ èϫ害 +欢 ç¬ij +Ġmes mer +å¾Ĺ 天 +ï¼Ľ å°Ĩ +Am anda +ĠBox ing +el ow +ÎŃ ÏĤ +ĠW ORD +ov olta +举 å±± +éĻ¢ èIJ½ +ï¼Įæĺ¯ çͱ +ĠAg reements +å°ī è¿Ł +ĠD OS +Ġimm ature +Ġcas ually +z hen +ä¸įæĸŃ å¢ŀåĬł +微微 çļĦ +( parse +sd n +A gg +çϽ é¢Ĩ +çĽ¾ çīĮ +oc cur +å®ļ åŀĭ +ãĢĤåľ¨ è¿Ļç§įæĥħåĨµä¸ĭ +亿 çļĦ +h ousing +æĪĸ 个人 +.A fter +Ġc uring +å¤ļ åıĺ +man ent +éĢıæĺİ åº¦ +ĠB ucks +ãĢĤ æŃ¦ +éľĢè¦ģ 说æĺİçļĦæĺ¯ +éĿĴ èī² +çł´ çĥĤ +森 çļĦ +åİĭåĬĽ åĴĮ +O LEGAL +} |\ +ãĢģ éŁ©åĽ½ +大 èĤ¡ä¸ľ +ĠAl ive +Ġquot ations +not iced +åĿIJ èIJ½äºİ +ï¼Į çݰ代 +è¶Ĭ å°ı +, Q +çĹĽ é£İ +Ġ æµĻæ±Ł +ï¼Į è§Ĥå¯Ł +ä¸ĵ åijĺ +ãĢĤ è¿Ľåħ¥ +åĨ· 空æ°Ķ +CC CC +é£ŀ å¥Ķ +Ġamount ed +={ " +Ġmell itus +_se cond +è½´ è·Ŀ +. import +. KEY +交 è´§ +Ġinf rast +å¾Ĺ æĪij +æĸĩåĮĸ 交æµģ +T ar +æĶ¾åľ¨ çľ¼éĩĮ +_ other +åĽ½åľŁ èµĦæºIJ +ï¼Į 好çļĦ +Ġbu ildup +urb ed +ĠMat te +æĪĸ çŃīäºİ +æĿİ ç»´ +(arg uments +ï¼ī âĢľ +é»ĺ çĦ¶ +æľīåħ³ äºĭ项 +ĠRenew able +ĠInter actions +Ġpear ls +iv ar +Ġpet ty +iz o +Ġfals ely +ĠÐ ŀ +èι åijĺ +Ġneg ativity +Ġanticip ating +Ġg igs +-b earing +-f ire +æĺ¯ èĢģ +åľ¨ æĢĢéĩĮ +ass ociated +Work ers +åijĬ çϽ +票 ä»· +çIJĨ论 çļĦ +ĠStory t +\ subseteq +Ġz ebra +S OL +g rey +身 æĹģçļĦ +_T EMPLATE +åħŃ ä¸ĥ +æĮij èµ· +ye ah +ac io +å¯Ĵ åĨ·çļĦ +ĠIr vine +. visible +红 线 +çķľçī§ ä¸ļ +ãĤ·ãĥ § +计åħ¥å½ĵæľŁæįŁçĽĬ çļĦ +end ra +ĠComp atible +IF A +Ġfluor ide +æıĴ 头 +åħ¨éĿ¢ åıijå±ķ +creat ive +æĬĬ æĪijçļĦ +ãĤ ĥ +ä¸¥æł¼ èIJ½å®ŀ +S AT +ĠB arg +å¯Ĩ 室 +ĠMessage Box +_g t +: P +åѦ çĿĢ +èı ¡ +带 她 +Ġgra ves +轻微 çļĦ +, ä¸įå¾Ĺ +ï¼Į çݰæľī +and es +ï¼ĮèĢĮ è¿ĻäºĽ +system s +_t wo +é¢Ĩ è¡Ķ +Ġbuff alo +.G ET +Ġepit he +ç²¾ èī¯ +//////////////// //////// +q c +Ġ æ·±åľ³ +Ġfly er +ov sky +(c b +è¡ĮåIJĦ ä¸ļ +, 令 +ï¼Į 沿çĿĢ +oplast y +en ance +Ġcoh omology +å®ī çIJª +æİ¢ æľĽ +Ġcon cession +ĠU A +_t ile +ĠEx ercises +ĠPen al +Ġoverd ue +Ġcond ensation +.er ase +Ġm ars +æµ Ĵ +ç»ı èĦī +è¿Ľ éĢĢ +.m essages +ĠButter fly +-b r +éģĵè·¯ 交éĢļå®īåħ¨ +.s f +ä½ł éĥ½ +æĽ¾ æ¯ħ +ä»İå°ı å°± +De ck +ãĢģ ä¹IJ +è¿Ľä¸ĢæŃ¥ æıIJåįĩ +ãĢĤ ç»ĵåIJĪ +ĠSt d +ract ory +å®Ī åľ¨ +èį· åı¶ +é£ĺ é̏ +_t im +åĨ· ç¬ijéģĵ +rad a +èĢIJ é«ĺ温 +Ġmild ly +_ ed +ĠC rop +ĠSlee ve +- cycle +Q B +Ġt aper +串 串 +Ġhelm ets +, æĺ¯åIJ¦ +Ġs ow +H ydro +f resh +çĬ¯ 人 +åĨ³çŃĸ éĥ¨ç½² +ï¼Į åİĨåı² +ur ator +ãĢģ åı£ +( ui +- print +æ¯Ķ åħ¶ä»ĸ +ill ard +éĤ£ å®¶ä¼Ļ +_const ant +ĠB low +(d escription +Support ing +ĠFlo ating +Ġ åŀĭ +ãĢģ 客æĪ· +å®¶ æĶ¿ +>: < +form ula +éĺ» æĬĹ +éĩĩåıĸ æİªæĸ½ +ãĢĤ å¦Īå¦Ī +ĠF PS +Ġref ill +æĿ¡ 缮 +Ġpel lets +Contin uous +. remote +ĠZ ar +$ sql +çļĦ åĽŀ +æĶ¹ 建 +æ°¸ ç»Ń +Ġsho pper +éĻį åİĭ +- arm +åIJij å·¦ +ĠAdv ices +ĠProdu ce +ãĢĤ åį´ +ãĢģ æī§è¡Į +æı ĸ +current ly +Ġscrut in +çļĦç½ij绾 å°ı说 +, 主è¦ģæĺ¯ +äºĮ è¿Ľåζ +缮 äºĨçĦ¶ +C row +ĠB aking +ä¸ĭ 人 +æīĢ åģļ +å¼ķ çĪĨ +Ġinitial izer +åĶ¿ åı« +åĪij ç½ļ +Ġl ondon +Book mark +æĺŁæľŁ åħŃ +Ġà ĸ +J ones +æŃ¦ åύçļĦ +æĬ¢ éĻ© +inal g +_n av +oad er +Ġb erry +ÏĦ ά +im at +ĠB enson +.Event Handler +ch ures +åī¯ ç§ĺ书éķ¿ +ĠDeb ian +ĠÑ ħ +åIJĮ éģĵ +_ bs +Ġsumm oned +ĠRF ID +ĠCarm en +/ ^ +ĠL AP +èĴĻ çī¹ +æħµ æĩĴ +éĥ¨ 级 +Ġproject ing +Ġretriev ing +n pc +åİ» å¹´çļĦ +Ġmyst ical +ĠSte ak +M ine +Ġcount able +Ġcer amics +温 æĥħ +.F unction +æľŁå¾ħ çļĦ +Ġtranqu il +_s uper +ä¸ĸ åĩ¯ +丰 åİļçļĦ +st udy +çα ç¾İ +b elt +天 åij½ +管çIJĨ ä¸İ +íĬ ¸ +éĩij é»Ħ +æĮģç»Ń åıijå±ķ +roph ies +el ope +åĤ» åĤ» +æĦ¤æĢĴ çļĦ +Ġrehears al +Ġ åĪ©ç͍ +ĠSur geon +Ġdisappe aring +è´Ńä¹° äºĨ +æķŀ å¼Ģ +Ġ 交æĺĵ +å®ĭ æľĿ +Ġstuff ing +她 åıĪ +Ġins ulating +Ġgar nered +Ġsimpl istic +------------ --- +regn ant +_w arning +ĠId ol +ulner ability +ï¼Įæĸ¹ æīį +: ä¸Ģ +All en +è¸ īè· +åį· åħ¥ +hh h +c ube +å¹³ 庸 +éϤ 湿 +çIJµ çIJ¶ +W X +ĠâĢ ķ +æİ¨ åΰ +åĸĬ 声 +è¸īè· Ħ +天 ä½ij +ĠFre el +Ġf iat +å°± åĪ« +åħ¨ ç½ij +åŁº åĽ¢ +ï¼Į åĩĿ +èĥ½ ç»Ļ +_DR IVER +Ġ é¢Ħ +çļĦæĹ¶åĢĻ äºĨ +sd k +éĵ ¿ +çĶ³è¯· çļĦ +U Integer +ï¼Į èģļ +Ġconst rain +éĩİ çĮª +åģļäºĨ 个 +ĠTreasure r +管 äºĭ +å°± æĺ¾å¾Ĺ +arch ing +èĬ± æ¤Ĵ +A KE +Ġ åĨĻ +ç¾İ 满 +女 æ¼Ķåijĺ +ä½ł çļĦ人 +Ġtherm odynamic +ĠF RE +ps z +Ġview points +é¢ĺ 为 +éĢīæĭ© æĢ§ +ĠGen ius +ãĢĭ ) +å®īåħ¨ 带 +Cond itional +è¿ĺ æ´»çĿĢ +éģĹ å¤± +Ġcl ergy +Ġassert False +ĠEm otion +ĠBlue host +Z Y +Ġs Ã¥ +åľĨ å¼§ +ĠHel m +Runtime Exception +ĠAlloc ate +Ġh og +Ġun fore +大家 对 +Ġall iances +ĠBe acon +使 æĪij们 +** . +è¦ģ è¿Ľè¡Į +å¹» å½± +( unit +g row +ĠCh urches +"> {{ +á» ĩ +Ġ第äºĶ èĬĤ +al en +计 çļĦ +åĨĽ èΰ +.d ep +æĽ² åŃIJ +L ONG +ä¸į æŃ£ç¡® +éļı ä»İ +sec ute +åıijè¡Į èĤ¡ä»½ +ä»ĸ çļĦ人 +Ġal b +æĸĩ åĩŃ +Ġ åĹ¯ +Ġgl m +çļĦçݯå¢ĥ ä¸Ń +_d est += < +ï¼Į å±ķ示 +Ġcou rier +riv ol +çĭĤ å¦Ħ +çŀª äºĨ +Ev idence +- ending +ĠAl pine +-c ells +éĥ½ä¸į æĥ³ +' l +Ġc k +Ġxy z +ĠF ountain +Ġfre aking +Ġa ure +_col ors +æĬ¥ 社 +ĠImpro ving +- users +ï¼Į èĢģæĿ¿ +Ġal loys +. Trim +St ars +空 æĹ· +/ >< +ĠT ek +ject ory +man i +ĠEst ates +Iss ues +ãĢģ åľŁåľ° +为 åĽ½ +äºij é¾Ļ +(s cope +Ġ éĵ¶è¡Į +ï¼Į ä¼łç»Ł +å°ı äºĮ +_F ile +Att ached +Ġadvers ary +Ġsh ingles +Ġnav igator +Ġsevent een +èĥ½ä¸º åĬĽ +Ġend emic +Ġterm inating +尤为 éĩįè¦ģ +itt s +红 è¡£ +ĠSee king +ĠP ieces +ĠConf idential +Ġtens ile +Ġst umble +çĶŁ åŃ©åŃIJ +Resp onder +_ ar +ãĢģ èµĦ产 +æĭįæijĦ çļĦ +ĠL oving +æł¸å¿ĥ ä»·å̼è§Ĥ +软 骨 +ĠBar cl +ï¼ĮåIJİ ç»Ń +羸 åħī +( vector +B US +to Have +缼 å¼Ģ +Ġadren aline +ĠS itting +åı¤ è£ħ +m ud +Ġrem ission +åİĮ å̦ +ĠEll iot +Ġfor c +åĶ® 票 +ä¸į 讲 +åħ³ ä¹İ +循 åºı +Ġperp lex +ĠEas ily +çħ® çĨŁ +ĠA very +åıĺ éĩıçļĦ +Ġe books +G rowth +S AM +çļĦ åŃ£èĬĤ +.test ing +ĠTow ards +O d +èĩªå·±çļĦ çĶŁæ´» +çģµ åĬ¨ +rug al +(d AtA +Ġassemb ling +ĠMe ghan +Cour tesy +_ chan +Ġp onds +_RE L +draw al +-prov oking +Ġto te +çļĦ 举åĬ¨ +ĠEst her +q n +st ellar +ERV ED +_ any +ĠProv incial +Ġcommand ing +ĠSuz anne +ĠAber deen +q v +zb ek +ç¬Ķ 缴 +Ġ è¿Ľåħ¥ +so f +TAIN ER +r z +ĠPL AY +-c ustom +ä¿ĿæĮģ äºĨ +ĠâĬ Ĺ +ï¼Į è¾ĵåħ¥ +Ġlob ster +èľķ åıĺ +è¡Į éķ¿ +Ġregist rations +ĠNad u +Ġarriv als +åķĨ çļĦ +åıĭ 好çļĦ +ä¹° ä¸ľè¥¿ +åħ½ 人 +Ġpromin ence +çŁ¥ ä¸įçŁ¥éģĵ +çļĦ好 å¥ĩ +/jav ase +Ġsub net +è¾ĥ ä½³ +éĩĮ çļĦ人 +. Unit +Ġpost age +å¤į åĩº +.de legate +èĥ¡æ¤Ĵ ç²ī +/ ui +åı ± +æŀģ å¤§åľ° +åı¯ åıĺ +èĤ©èĨĢ ä¸Ĭ +ol son +å¿ĥ åŃĺ +Ġref inance +çłĶç©¶ æĸ¹åIJij +.set Visibility +æ¼Ķ ä¹ī +-f ounded +/ bar +ot ropic +_cl s +è´ ° +itt on += {{ +éĥ½æĺ¯ ä»İ +æļĹ æ·¡ +aby rin +min utes +ä¸į 详 +Com position +ĠB AR +æķĻ åħ» +åıĤ åĨĽ +å²³ éĺ³ +ï¼Į æħ¢æħ¢çļĦ +ä¸Ģ个 好 +æľįåĬ¡ åύçļĦ +ĠIter able +ĠE BIT +红 åħī +uit ar +ï¼Įåį´ è§ģ +æŃ£å¸¸ 使ç͍ +ĠB ust +_m argin +æ²Ļ åŃIJ +_D ONE +Ge om +Ġorganis ational +åĮĸ å¤ĦçIJĨ +-reg ulation +Ġ>> = +.V er +Ġ 综åIJĪ +it ance +.s erialize +Ġcount down +çªģçĦ¶ éĹ´ +E CHO +ĠMc Connell +éĥ¨ä½į çļĦ +éĸ ¢ +ä½ł 羣çļĦ +ç¥ŀ åħ½ +ï¼Į人 åĿĩ +dr v +èĩª æķij +åıĸ åIJį +ç¥Ī æ±Ĥ +_ operator +ï¼Į 身边 +, String +ãĢĤ çŁ³ +æİ¥ çıŃ +ĠApp alach +èħĶ ä½ĵ +Ġformal ism +/ èĤ¡ +èĬĤèĥ½ çݯä¿Ŀ +Ġmuff ins +ä¿ ¸ +ĠBlack Berry +çĺŁ çĸ« +ist ication +Ġser otonin +å¢ŀ 产 +çĹħ äºĨ +ĠFis cal +Y NC +\ epsilon +Ġ( ). +-p riced +èµĽåŃ£ çļĦ +.v ideo +in formatics +æĪij åħ¬åı¸ +Ġ ä»»åĬ¡ +Ġw ipes +b ab +æĿľ çĶ« +ï¼Įæĥ³ èµ· +.d ownload +а Ñı +OLUM E +缸è¾ĥ äºİ +Ġst unt +ĠF AT +女åĦ¿ çļĦ +ä¸ĵ项 æķ´æ²» +Fre edom +çĩ İ +Ġapproxim ations +ĠG oose +Ġcar box +hydro gen +åºĶå½ĵ åľ¨ +ãĢģ éĥŃ +Ġv ents +Ġent angled +.c ard +Ġout file +_m gr +Ġbook marks +Tur key +Ġsub marine +é¡¶ æĿ¿ +åľ¨çº¿ è§Ĥçľĭ +ä¸Ģ æĭĽ +åĨ² è¿Ľ +æĺ¯ èĩªå·±çļĦ +åIJĵ 人 +çļĦ 念头 +ĠEmb edded +ி à® +ç¬Ķ ä¸ĭ +Ġacc using +æĿĥ åĬĽçļĦ +Append ix +- operation +ĠP AD +æĹł çĹķ +æĢİä¹ĪåĬŀ åij¢ +Ġ\ # +ush ort +è£ħ çĿĢ +å°ı èħ¿ +æijĨ æijĨæīĭ +èIJ§ è¾° +Ġcon cessions +.h andler +ĠSen iors +ä»Ķç»Ĩ çļĦ +鲨 é±¼ +Ġstrang ely +ic ative +被 çĽĹ +éĥİ ä¸Ń +еР¶ +åįłæľī çİĩ +äºĨ è¿Ļä¸Ģ +åįĹ å®ĭ +ĠSc outs +ï¼Į åħ¬åı¸çļĦ +, ä¸Ģç§į +踩 çĿĢ +Ġst amina +两 ä¸ĩ +_user name +/ he +没æľī å¿ħè¦ģ +åīij æ¡¥ +(r andom +ãĢģ åŁºæľ¬ +å¯Ĵ æ°Ķ +ĠPhilip pe +âĢĿ ï¼Ł +ï¼Įå¦Ĥæŀľ æĪij们 +RA IN +, åįķ +Ġco ached +ç¥ŀ é¾Ļ +人 寿 +ĠV ale +ĠExpl oring +Ġext inct +, è¿ij +P u +å°ı ä¸ī +åıį åħī +æĭ¿ èµ° +èĩªçĦ¶ çģ¾å®³ +_clean up +ï¼ĮæĪij æĿ¥ +Ġson o +ad m +App lying +å¦ĤæŃ¤ ä¹ĭ +Ġs led +ï¼Į ç½ij +ĠC argo +ä»ĸ们 ä¼ļ +.d river +åħĦå¼Ł å§IJ妹 +ï¼Į 汤 +) åĮħæĭ¬ +ĠBe aver +é¡» ç»ı +è¿Ķ 乡 +Ġbuff ered +没äºĭ åIJ§ +LO SED +åĢĴ åľ¨åľ°ä¸Ĭ +Ġserious ness +Ġremed iation +éĢļè´§ èĨ¨èĥĢ +ç¦ı æ°Ķ +-M obile +çļĦ å¿« +Ġd ick +ĠM atching +Exp ired +ĠSold ier +ĠGlor ia +ĠDi agnosis +Ġठ¹ +Spe ak +. lookup +ĠPr imitive +ĠV all +è¦ģæ±Ĥ åĴĮ +ãĢģ æĬĬ +Ġcl oning +ext ends +.Check ed +ag em +ĠL ace +软 æĸĩ +å°±åľ¨ è¿ĻæĹ¶ +éύ çŁ³ +' A +l ug +ãĢģ ä¸ģ +ç´§ éļı +M erg +ãĢĤ 太 +ĠY EAR +Ġmi RNAs +ï¼Į éĤĵ +Ġmet am +ãĢģ æľª +ri le +ï¼ĮæĪij æĢİä¹Ī +EN ABLE +管çIJĨ çŃī +.f ilename +orn o +Ġsat in +Ġè¯įæĿ¡ åĽ¾åĨĮ +ph osph +_B US +Ġmar ched +Ġintens ities +Ġs ided +åİħ éķ¿ +çĮ© çĮ© +ult ies +åĪĻ ä¼ļ +æĭī æĿĨ +èĩªå·± èĥ½ +Ġest eem +åĪ©æ¶¦ æĢ»é¢Ŀ +Ġadoles cence +äº ĺ +宣 èªĵ +ch io +ins pect +ĠGl uten +æ¸Ĭ æºIJ +Ġfet ched +ãĢģ åı° +äºĮ ä¸ī +çļ® çIJĥ +çĽĶ çͲ +åįģ ä½³ +(m ask +åĢĴ å¡Į +座 åŁİå¸Ĥ +æĬĵ æįķ +ĠOtt oman +æ°ijäºĭ è¯ī讼 +Ġ åĵģçīĮ +D emand +_{ -\ +è´µ éĩį +Ġ åĵĪ +æĬĹ çĻĮ +çĽijçĿ£ç®¡çIJĨ å§Ķåijĺä¼ļ +Ġ å¿« +Ġ åᢠ+ĠOper ators +æıIJåıĸ çī© +Ġware houses +Ġe k +Ġcan yon +/ resources +ĠL OV +转 äºĨ +ï¼Įä½Ĩæĺ¯ å¦Ĥæŀľ +View Holder +触 çĤ¹ +Sc i +F V +ĠNiel sen +ä¸į 代表 +ĠL obby +è¨Ģ éģĵ +ä¹Łè®¸ æĺ¯ +stad t +èĩ³ æīĢè¿° +ĠMod ify +Ġrupt ure +Ġimp oses +表çݰ åĩºæĿ¥ +çĶŁäº§ æĪIJæľ¬ +å¥ĸ åĵģ +æ´Ľ åĮĹ +声 åĬ¿ +UL ONG +å·¥åķĨ éĵ¶è¡Į +Ġlun ches +l aces +ãĢĤ æĿ¥ +èĢ» è¾± +ĠFor got +åĸľæ¬¢ ä¸Ĭ +è£ģ åīª +-support ed +ĠA im +Con cat +, åĮĹ +å¹³åĿĩ æ°Ķ温 +Ġsuit case +Âł A +Ġret ard +.Fore ign +so far +Ġbullet in +èĦ¸ çļ® +åĽº æľī +Ġexceed ingly +æķ´ æľº +çļĦ éĺ¿ +æķħ ä½ľ +ãĢģ ä½ķ +ĠG at +ĠI rene +éĿ¢ åĴĮ +ç»Ŀ ä¸įæĺ¯ +ï¼Įä½Ĩæĺ¯ 对äºİ +net t +ĠEll a +Ġtouch screen +ish ments +ĠGar lic +S erve +éĢģ 礼 +ï¼Įå·²ç»ı æĺ¯ +w end +é¡¶ å³° +ä¸ī个 åŃĹ +G uy +çľĭ åĩºäºĨ +Ġremn ants +ys c +ĠAll owed +(d ist +ë ³ +id ia +_l iteral +.set Property +ï¼Į çͲ +ĠD K +ĠPl ato +RET URN +_ act +åıĮ åŃIJ +éĹ² æļĩ +ĠQ CD +èĥ½ ä¸į +isk y +èĭı æł¼åħ° +vare z +说 äºĽä»Ģä¹Ī +.h ome +.k ind +Ġto fu +- create +l ucky +ï¼Į è®°å½ķ +ï¼Į çĽ¯çĿĢ +.B undle +å¢ŀåĬł åΰ +kl ore +æ¯Ĵ çļĦ +èĥ¸ èĦ¯ +æĿĥ å±ŀ +ĠDown s +座ä½į ä¸Ĭ +ren ches +ç»ıåİĨ çļĦ +Ġdark est +- ice +Ġfl orida +Ġens uing +DEV ICE +æ² ĵ +ï¼ļ 为 +èĩªå·± æĥ³ +å¿ħé¡» çļĦ +Ġ( âĢĺ +Re ject +ï¼Į è¿Ī +ä¿ ij +Ġpred ator +Ġroom mate +, æĶ¯æĮģ +, åĬłåħ¥ +{ cor +ä¸į åĩĨç¡® +åºŁ æĸĻ +Ġprop ensity +Ġas par +Ġk eras +èİ« éĹ® +- ord +ï¼ĮåĽłä¸º è¿Ļ +avour ite +/d es +ĠArch bishop +äºĨä¸Ģ æĶ¯ +, æķ´ä½ĵ +ä¹Ł å¹¶ä¸į +ï¼Į æĶ¶éĽĨ +Ex terior +é¾Ļ èϾ +身 ä»· +}[ \ +身å¿ĥ åģ¥åº· +ï¼Į è¿ijæľŁ +. ast +ï¼Į ä½ı +ï¼Į è¦ĨçĽĸ +ĠT EX +äºĮåįģ ä¹Ŀ +æ¶²åİĭ 缸 +. Stream +Ġmotiv ates +Ġsc out +åĨį åģļ +Ġflatten ed +/ [ +èϽ æľī +Ġs inc +åįģ åĢį +Ġwin ery +Ġseed lings +-pro ducing +Ġrev ocation +ĠV et +天 ä¹ĭ +ãĢĤ åıĮæĸ¹ +us ual +åıįæĺł åĩº +. AP +N J +Ġdifferent ially +Ġhouse keeping +ĠF uk +åĨį ç͍ +.d ebian +åIJĥ éĨĭ +æł¸ å®ļ +but tons +羸 ä¸Ń +_FL ASH +Ġf w +ĠD rops +uss en +åŁŁ ç½ij +èģĶèµĽ ä¸Ń +æķĻç§ij 书 +大 红 +, æ·± +æĽ´å¤ļ åľ° +ĠPFN GL +ĠP SD +V ED +äºĮ åįĥ +Ġmult it +ĠBe cker +rack ed +Ġaeros ol +ï¼Į éŁ©åĽ½ +\" \ +å¤ĸè§Ĥ 设计 +. asm +ategor ical +ä»° æľĽ +Ġsky rocket +S FR +oun cer +ĠNich ols +ĠC rab +ï¼Į好 åľ¨ +æķ¬ æĦı +Ġv odka +Ġhe ed +产åĵģ åľ¨ +éĥģ éĥģ +ĠLuc ia +/ code +éĤ£ éģĵ +ĠAM P +Ġ åıĬ +æħķ å°¼ +ĠCont ribution +å¯Ĵ åĨ¬ +ĠVal ent +åī©ä½Ļ çļĦ +ãĢģ çĶļèĩ³ +_EM PTY +Ġmisdem eanor +ĠS odium +_n r +File Info +ç¥ Ĥ +ĠHy g +-t emperature +/ cont +ms on +Ġc amb +åĴĮ æĹł +æł¹ ç³» +comp act +ĠSerial izable +滤波 åύ +, åĿļåĨ³ +ï¼Įè¿Ļ åľº +ĠJud ith +Fore x +ĠH ose +表 å§IJ +ä¸Ģèĩ´ çļĦ +ï¼Į è§£åĨ³äºĨ +Ġl icens +æĺ¯ å¤ļ +两 éĵ¶åŃIJ +éĥ½æĺ¯ éĿŀ常 +Ġantib acterial +åıijå±ķ ä¸Ń +Ġ è§Ĩé¢ij +() > +ä¸ĵ èijĹ +åĩĨå¤ĩ 好çļĦ +åĩ¡ äºĭ +Ġorgan ising +Ġt unn +åѦ 龸 +D IRECT +åħī å½± +è¾Ľèĭ¦ äºĨ +ĠMotor ola +ucc i +Ġm oot +ĠCompar ative +" date +ĠStep hens +P PT +è®® éĻ¢ +ift ed +Ġha unting +Ġclient ele +Ġpro phyl +åıĪ åı« +ï¼ĮåĨ· åĨ· +åħħ è£ķ +[ I +æĶ¶ åıij +å¿§ å¿ĥ +æĬĽ å¼Ģ +ĈĈ ï¼Į +ï¼Į大 éĩı +æľ¬ åĵģ +iss ued +社ä¼ļ ä¸Ń +(b ox +, è¿Ľåħ¥ +éĩį çĸ¾ +æľĪ åŃIJ +Ġasp ire +ĠE bola +Ġ` < +ĠSch r +ãģ« ãģ¯ +ct p +æľ¬ çļĦ +ach y +éĹ® ä¸ĸ +Ġ? : +}_{ {\ +.img ur +åĮħæĭ¬ äºĨ +Pl aces +æĺĨ å±± +ld on +Ġy uan +èĢĮ åĸ» +Ġwand ered +W y +ore a +.A t +Ġth ym +PL US +ĠØ ³ +ï¼Į æłijç«ĭ +Ġd ues +å°ı å·§ +ors et +Ġimag ining +p he +ĠCont ributions +Ġ 设计 +Ġn pc +å¯ĨåĪĩ 缸åħ³ +Ġende avour +ãĢĤ 个人 +ä¸Ń æŃ¢ +Ġdist inctions +f rag +Ġs plic +ĠP LEASE +å°± çŁ¥éģĵäºĨ +æ³¢ çļĦ +Rec v +Ġbud ding +Ġrum or +æĺ¯ åĽ½åĨħ +ĠSal vation +ĠAer ospace +n ome +ĠL al +Ġpred ecessors +(p air +ĠSome how +ĠæľĪ éĶĢåĶ® +ï¼Į 幸好 +Ġdoubt ful +ãĢģ æł¡ +ãĢĭ çͱ +æ¯į 线 +es ac +Ġto dos +ä¹ĭ åıĪ +EX PECT +Do ing +; ", +ĠT yson +. option +_ ready +Ġsc or +æĬĬ äºĭæĥħ +åįĬ æŃ¥ +st s +çĶŁäº§ æķĪçİĩ +Ġcurl s +_ List +_attr s +ï¼Į åĨ¬ +Ġoccup ying +ĠPrint ed +为 ä¸Ĭ +Ġfirst hand +空 æł¼ +åİĭ æľº +åĨ² 泡 +( Config +w ine +è¾½ éĺĶ +è¯ĿéŁ³ åĪļèIJ½ +Ġexper iential +çİĭ 大 +Ġlocal host +pop ulation +为 å¥ijæľº +èµĶåģ¿ è´£ä»» +Sc ientific +çľĭå¾Ĺ åĩº +ĠAs he +çļĦ å¿ħè¦ģ +è·¨ 度 +æĪ¿åľ°äº§ å¸Ĥåľº +Ġsie ge +ĠPlan ck +_ identifier +å°½éĩı éģ¿åħį +C andidates +ï¼Į åı£æĦŁ +w at +Ġ éĵ¶ +ĠF avorites +æ¨ ½ +Ġconf isc +æķ² åĩ» +ĠR ox +ĠAlex is +åı ¼ +ï¼Ī A +Ïĥη ÏĤ +ĠM oor +load s +>> ( +ĠLog ical +ocyt osis +ab la +Ġsuper intendent +ĠMead ows +. ai +é¦ĸ éķ¿ +ĠMom ents +C ars +Ġf erv +ä¸Ģ åłĤ +åIJ´ åĭī +ä¸Ń 西 +_c ancel +åīĶ éϤ +. ï¼Ī +æĻ® æĥł +ï¼Į æĭīçĿĢ +Ġd ing +æľª å°Ŀ +èѦ åĬ¡ +im plicit +ãĢģ åĽ½åĬ¡éĻ¢ +ĠN er +åıĸ ä¸ĭ +-int ensive +æij Ĵ +æ©Ļ èī² +æŃ¦ èīº +Ġdiscrep ancies +ï¼Į åĺ¿åĺ¿ +Ġsc opes +ĠFor ge +åĩºåıij çĤ¹ +app ropri +dir ty +åįģä¸ī äºĶ +ä¸į çķħ +Ġdis closes +è¨Ģ è¾ŀ +æŃ£ 缴 +ï¼Į è°ĵ +. ro +Ġcon duc +è¶ħè¶Ĭ äºĨ +beaut iful +Ġfis heries +Ġm uddy +ĠG es +Ġbo ating +ï¼Į ç«¥ +æ¯Ķè¾ĥ 容æĺĵ +, çĶ· +Ġhe uristic +çļĦ人 æĸĩ +, éķ¿æľŁ +. character +ol ysis +ĠG ala +åı¤ 迹 +è¡¥ ä¹ł +Ġmis placed +ĠAra bs +ĠMid lands +( ev +m ite +åijĬè¯ī ä»ĸ们 +gl omer +icip ated +ĠCon rad +ï¼Įä¸Ĭ ä¸ĭ +ĠScot ts +Ġhe ats +æĮĩ示 çģ¯ +è¦ģ é«ĺ +ĠX S +æĮģç»Ń çļĦ +æłħ æŀģ +è¿Ŀ约 éĩij +åĴĮ æĶ¹è¿Ľ +ãĢĤè¿Ļ ç±» +oph ysical +åĨĴ åħħ +åĩ¯ çī¹ +ç¨Ģ çĸı +éľį å°Ķ +对åºĶ äºİ +ĠKat z +Ġincons ist +Ġreg s +åĩł åıª +第åħ« 竳 +/ articles +ï¼ ¡ +ĠRe action +约 èĢĮåIJĮ +Ġgive aways +æĺ¯ä¸Ģ个 å¾Ī +ï¼Į åŃĶ +ĠF ence +Ġz h +Acc eler +çĽĨ åľ° +Ġrede emed +ĠMond ays +Ġart works +çĨĶ èŀį +缸 ä¾Ŀ +$ t +Ġtruth ful +-he ld +cl ips +ä½ĵéªĮ åΰ +ep rom +è¯Ŀ çŃĴ +ä¸ĵå®¶ ç»Ħ +æīįæĺ¯ æľĢ +ï¼Į åijĺå·¥ +( âĢľ +.Act ivity +æľĢ好 ä¸įè¦ģ +) ^\ +f id +ï¼Į çĶĺ +åIJİ æľŁçļĦ +Ġfragment ed +èĴ¸åıij åύ +V ault +éĥ½ ä¸įè¦ģ +å¨ ² +è¸ ± +ĠPrint s +ï¼Į æıIJéĨĴ +Ġdis b +-c r +er p +ï¼ļ 该 +ãĥ ĭ +æľįåĬ¡ çŃī +æİĢ å¼Ģ +éĢļ åIJij +m ale +ï¼Į åIJĵå¾Ĺ +Ġin p +UN ITY +.Un lock +-n etwork +ãĢģ 车è¾Ĩ +è° ¤ +å±± éĩĮ +ĠSh ake +äºij éĽ¾ +åĩłä¸ª å°ıæĹ¶ +æī§è¡Į å®ĺ +Occ up +ä¼ İ +å°± å·² +æ® ĥ +DT D +Ġhal ves +Ġscript ures +.strict Equal +åķ ¬ +çļĦ主 è§Ĵ +æŀĿ æĿ¡ +Ġb arr +âĢľ éĺ¿ +Ġch ol +ãĢĤâĢĿ ãĢĬ +ges ter +ï¼Įç͍ 以 +æĸĩ竳 åĨħ容 +Ġuns pecified +ä¸Ń æī¾åΰ +ous ands +åºĶ该 æľī +Ġg els +æĪIJ åįĥ +Ġult raviolet +Ġun equal +éļ¾ æ°ij +ï¼Į æĬĵä½ı +æĭ¿ çł´ä»ij +ï¼Į没 ä»Ģä¹Ī +b ble +ĠD EN +æį¢ 代 +大åѦ åĩºçīĪ社 +Ġhing es +ĠN ONE +ĠSh ak +æ»ij èIJ½ +L n +å®ģ åİ¿ +ANC EL +, å®¶éķ¿ +Ex plicit +è¿Ļä¹Ī æĥ³ +éĿĴæĺ¥ æľŁ +åį° ç¬¬ +Ġdown right +æIJŀ 好 +纵 çĦ¶ +ä¸į å̼å¾Ĺ +Ġwat ts +æ°¸è¿ľ çļĦ +ï¼Į 空éĹ´ +Ġar cs +ä¸ŃåĽ½ å®¶ +å°±ä¼ļ åĩºçݰ +èµĦæĸĻ çļĦ +åĨľæĿij ç»ıæµİ +Ġ ï½ŀ +éĥ¡ çİĭ +çĿģå¼Ģ çľ¼ +Ġper tains +人 æĿ¥è¯´ +Ñı ÑĤ +Ġmir rored +ï¼Įéļ¾ åħį +ãĢģ - +Ġtake away +ri ous +ĠBut t +éĢģ åΰäºĨ +èIJĮ èĬ½ +ç©¿ åŃĶ +d ad +Ġpre empt +æł¡ çļĦ +为 éĩįçĤ¹ +å¾Ĺ ä»ĸ +buff ers +Ġ éĩĩç͍ +Ġ ä½ľåĵģ +Int roducing +计ç®Ĺ åĩº +Ġpione ers +Ġdock ing +ĠJ edi +Ġsub string +åľ¨ 建 +å¸Ī 妹 +MS O +isc ard +éĴ¢ä¸Ŀ 绳 +Ġab norm +æīĢ æĥ³ +ĠK R +.c ategory +æ³³ æ±ł +溺 æ°´ +Ġcaul iflower +ä¸į åħī +ist en +è¡Ģ 红 +çĬ¯ éĶĻ +ĠRob otics +游 èīĩ +ĠP AY +- ID +ĠH icks +_ JSON +æīĵ äºĨä¸Ģ个 +ĠDes c +Ġclim ates +ï¼Į æĻ¯ +åĴ » +Ġch ir +åĨ· åĨ·çļĦ +俱ä¹IJ éĥ¨çļĦ +çļĦ åij½è¿IJ +Ġoper ands +ãĢĤæĪij 说 +ha el +ï¼Į æģ¶ +and als +æĤī å°¼ +æį· å¾Ħ +ozyg ous +Ġto asted +Ġsh ields +对 ä¸Ģ +on ics +ub ectl +Prov iding +/ TR +Ġpl entiful +çľĭèµ·æĿ¥ å¾Ī +ек ÑĤ +ãĥ £ +ï¼Į å½Ń +ãĢģ çݰ代 +ãĢģ è¿IJèIJ¥ +å¿ĥ æĢ¥ +Ġunder line +M ile +ĠB arker +è¿Ļä¹Ī ç®Ģåįķ +, åĨĻ +æĶ¶ éŁ³ +ĠBout ique +åĴĮ åħ¶å®ĥ +.p redict +' % +æµ· å¸Ĥ +åıªè¦ģ ä½ł +ç»ķ çĿĢ +å¿ĥ æĢĢ +Ġhon orable +äºĴèģĶç½ij éĩijèŀį +Ġ çĥŃ +Ġ çĶ·äºº +çŃī å¤Ħ +ĠAm end +å¾Ĺ å¿« +æĶ¿ åħļ +ĠEm erson +s pectrum +éĴŀ 票 +èĩªæĪij ä»ĭç»į +对ä»ĸ 说 +ĠBeck y +-m ost +Ġunn amed +p pe +Ġe b +Âł S +åİ» åĵª +ĠMir acle +Ġp interest +.config uration +Ġutter ance +éĿ¢ 带 +ĠOr n +Ġ ________ +ig ree +ãĢģ åIJĪä½ľ +Ġcon com +ï¼Įåı¯ä»¥ ç͍ +W ifi +o ys +ĠF AR +éĤ£ é¢Ĺ +Ġpok ies +t as +ãĥ Ĭ +Ġg ummy +ä¸ī ä¸ĸ +Ġcomm e +h rs +Ġh ut +Quant um +, è¾ĥ +丢 èĦ¸ +Ġsidew ays +ãĢĤå½ĵ å¹´ +ĠH of +STAT IC +V itamin +ï¼Į æľ¯è¯Ń +åĬł æĸ¯ +,è¿ĺ åı¯ä»¥ +ĠCharg es +ĠA the +åIJ¬ æĩĤ +(s pec +Group Id +Ġprem iered +åĽ°éļ¾ åĴĮ +. off +çļĦ è¡Įä¸ļ +Ġkeyboard s +C od +ä¸Ĭ æī¬ +åıĹ è®¿ +æĪ¿ åĨħ +é£Łçī© çļĦ +ic ent +åĽłä¸º ä½ł +åįij å¾® +ĠWrest ling +( al +ĠPre v +Ġsubtract ing +æĿĥ åĴĮ +ĠP b +让 å°ı +? # +D ating +çļĦ èĢģ人 +âĢĵ and +Ġhuman ities +(c s +ï¼Įæĥ³ ä¸įåΰ +_HAND LER +" ä¸ŃåĽ½ +ãĢģ 常 +å©ļ äºĭ +ot ically +Ġal go +os ocial +Ġα ν +ĠR apt +è´¨éĩı éĹ®é¢ĺ +çϽçĻľé£İ åĮ»éĻ¢ +Ġmon ks +åħ´ æĹº +Ġcommon place +å¦ĩ å¹¼ +Ġrel ativistic +è¿Ļ个 大 +ĠCA RE +ãĢģ éĢļä¿¡ +Ġad joining +ĠK ens +.F ilter +æĪ¿éĹ´ çļĦ +id ase +åı¯ æĥ³èĢĮçŁ¥ +IP åľ°åĿĢ +Ġarch ival +Ġsal iva +åħĭ èIJ¨æĸ¯ +ï¼Į æ£Ģæµĭ +Ġin experienced +Ġsau ces +S ibling +ï¼Įä¹Ł åıªæľī +-d iv +ä½ľèĢħ ç®Ģä»ĭ +åľ¨è¿Ļ æĸ¹éĿ¢ +Ġmigr ating +Ġst al +ï¼Į åĵªä¸ª +åľŁåľ° ä¸Ĭ +åħŃ ä¸ªæľĪ +æ°ijæ³ķ åħ¸ +Ġ è´Łè´£ +æĬĬ ä»ĸçļĦ +ãĢģ åĪ¶ä½ľ +Ġdispar ate +ĠKarn ataka +Ġstation ed +аР¶ +ĠSign ific +Break fast +ãĢĤ è´Łè´£ +åĢĴ æĺ¯ä¸į +è¿ĩ 失 +说 åĩºäºĨ +ach ts +Ġrein forcing +ĠNa omi +ĠRank ings +ĠC CD +äºİ 人 +éĩį ç£ħ +ĠZ bl +_h ist +_REG ION +çĭ¬ è§Ĵ +Ġcondemn ation +æĪij们 èĩªå·± +normal ize +Ġdinos aurs +ĠNyg ard +- ${ +att ention +综åIJĪ ä½ĵ +第ä¸Ģ å±Ĭ +ĠM oy +Ġtherm ometer +Ġpre clude +è§£ æķij +æĽ¾ç»ı 说è¿ĩ +Ġl obe +åľ¨ åīįéĿ¢ +ĠAggreg ate +T enant +ac ry +Ġall ot +Ġhom omorphism +Ġmagn ification +æ®Ĩ å°½ +Ġ æī§è¡Į +ï¼ĮæĪij åıª +Ġaud iting +Ġl ith +ĠCreat ivity +Full Name +Ġcompos ites +æĸŃ ç͵ +ĠC OS +qu ite +erv oir +ĠO ps +çīĻ èĨı +Ġvisual ized +è£ħ æ½¢ +çĪĨ 竹 +FFFF FF +ĠBer ks +è¦ģ ä¸İ +åı¯ä»¥ ä¸į +èĥĨ åĽĬ +Ġconf essed +ĠAdv ances +áĥĶ áĥ +åģ İ +Se attle +T U +b lower +ãĢģ èĦij +æĬ½ æł· +r ists +ĠF av +Type Info +Ġshoot ings +s uggest +ĠS HE +Âł æ²Ī +ĠTot ally +, æĺĵ +E K +Ġblind ness +æĺ¥èĬĤ æľŁéĹ´ +Interest ingly +ĠS olving +ĠG eek +åħ³ çħ§ +_UN USED +size i +é£İ 度 +缸 æİ¥ +/re act +Ġblock ade +ij e +-l a +" åŃĹ +åĮ® ä¹ı +% ï¼Ī +ĠR MS +讲 æķħäºĭ +çļĦä¸ĭ æĸ¹ +æľ¬ çͰ +un icode +éĿŀ常 åĸľæ¬¢ +ãĢĤè¿Ļ æĺ¯åĽłä¸º +,ä¹Ł ä¼ļ +Ġ æĪij们çļĦ +æľ¬ èIJ¥ +天 æ²³ +Let ters +ĠBra un +çĿĢ èī² +Ġminim izes +è¯ģæĺİ æĿIJæĸĻ +ĠO G + // +member NameLink +@ example +å¤ ī +ï¼Įåΰ çİ°åľ¨ +redit ary +ustain able +prov ide +Ġcraw ling +ï¼Ī è§ģ +b ugs +ĠMe V +为 åĽ½å®¶ +Âł åij¨ +å¦ĸ çİĭ +Pot ential +p ac +éĴŁ æĥħ +.G raphics +åĴĮ æĵįä½ľ +Ġimp osition +Def ense +Ġdepart ing +Ġfranch ises +çļĦ çIJĨ念 +èµ· æºIJäºİ +und i +è·³ èµ·æĿ¥ +ĠPRO JECT +éĩĬ ä¹ī +Ġw akes +Ġpres cribing +CON F +åIJį åĪ© +Ġcat ar +ĠMau i +ic ially +订 å©ļ +) **(- +ĠGL uint +Ġsub types +Ġcav al +â ŃIJ +ä¹Ŀ ä¹Ŀ +bring ing +ĠC ory +åĿ¦ è¯ļ +ï¼Į转 çľ¼ +B h +带 åİ» +Ġwork ings +ĠMem ories +LE M +åįİå°Ķ è¡Ĺ +ĠD ing +Ġsc raps +Ġurg ently +ãĢĤ è®°å¾Ĺ +åĪĨ åΰ +èĥĮ å¿ĥ +çļĦ åħ´è¶£ +Ġbe asts +ä¸ĵä¸ļ 人åijĺ +Ġransom ware +or an +Ġ ç«ĭ +ï¼Įçľ¼ éĩĮ +Ġsp aghetti +erv atives +æŃ£ åĩĨå¤ĩ +éĹ¹ éĴŁ +ent ence +表 妹 +Ġ å¹¶ä¸Ķ +up grade +ï¼ĮæĢİä¹Ī æł· +好 æĦı +ä»Ļ ä¾ł +éĩĩ çŁ¿ +ç´¢ åıĸ +Ġimm obil +ä¹Łæ²¡ æĥ³åΰ +ĠProm otions +æĢ§èĥ½ 好 +lig a +ir an +æ±Ł æ²³ +è¶ħ 人 +Ġh ive +对 社ä¼ļ +Ġmeth anol +读 çī© +ä¹Į æĭī +Ġsw ung +ĠAb road +Ġridic ulously +Ġbrace lets +åIJij ä»ĸ们 +.M ult +Ġsn ippets +ĠRel ay +Ġlimit less +semb les +Ġmoder ated +ãĢģ æĸĩæĺİ +ĠB AD +Ġsc ala +Ġà ª +Ġa kt +åķ Ħ +Ù ¾ +ä¹Ł 表示 +ĠCo ins +ĠAS N +ç©Ĩ æĸ¯ +é£Ļ åįĩ +第ä¸Ģ æĿ¡ +Ġjur or +ç½ij 讯 +. ï¼Į +ĠF asc +å§ Ĵ +æīĵ ä¸įè¿ĩ +ä¸ŃåĽ½ 人çļĦ +OLT IP +å¼Ģ æĴŃ +åĨħ容 çͱ +çĬ¹è±« äºĨä¸Ģä¸ĭ ++ N +ï¼Ł è¦ģ +æıIJä¾Ľ æľįåĬ¡ +人 èĥ½ +ĠLe one +ä¸Ģ缴 éĥ½åľ¨ +ĠMal ay +ĠInterest ed +åĬ¨çĶ» çīĩ +ï¼Įä¸Ĭ 次 +å¾Ģå¾Ģ ä¼ļ +ĠAn ita +Ġdrunk en +Ġconfig uring +ĠPub lish +æ°ı çļĦ +ĠB ose +åİĤ å®¶çļĦ +Ġels if +Ġ è¿Ļä¸Ģ次 +Ġw ed +Ch icken +-t alk +Ġquil ting +f ur +ĠG RE +ich ita +_s kip +_c at +è¸ µ +æĿĥçĽĬ æ³ķ +Ġprosecut ed +Ġanth ology +V m +ç»§æī¿ äºĨ +天 ä¸Ģ +æŃ£ ä¸Ń +çϾ 强 +ĠL ending +lo ff +ä¿¡ å°ģ +ĠPres ents +ç»ĵ èĬĤ +ï¼Įä¸į åΰ +åįıè®® çļĦ +ĠAng lic +æĬĬ åħ³ +ï¼Įä»ĸ们 ä¼ļ +ãĢģ é¼» +_p arts +PT O +Ġfe ud +æ°§åĮĸ 碳 +Ġconqu ered +æľį ä¾į +é£ŀ åĩº +迪 æĸ¯ +å®īæİĴ äºĨ +Ġ èĶ¡ +ï¼Į åħµ +Ġobserv es +Ġminim ise +çıŃ è½¦ +念 ä½Ľ +ĠGuarant eed +è· ¤ +åŁº è°ĥ +ç¨İ 款 +Ġtrain ings +F IT +ĠJ U +ĠSc rap +Ġpattern ed +æĥħ ä¸įèĩªç¦ģ +å¯Ĵ é£İ +p recision +ĠD und +Ġab lation +ĠAccess ed +ĠM outh +ĠApp l +Ġtw isting +en as +iss y +æīĺ è¿IJ +èĢĥ å®ĺ +åļ ı +Ġabort ions +ãĢĭæĺ¯ è¿ŀè½½äºİ +è¶ĬæĿ¥è¶Ĭ å°ij +Ġdegrad ed +d igest +ep isode +- editor +ãĢģ åŁºéĩij +Ġins ensitive +æĢĿ ä¹± +/d b +çļĦ èī²å½© +á g +Ġwit ty +å¾Ī 满æĦı +æĹłç¼Ŀ éĴ¢ç®¡ +Ġdi pping +产ä¸ļ ç»ĵæŀĦ +< i +èĩ § +èģĮå·¥ èĸªéħ¬ +ãĢĤæ¯Ķå¦Ĥ 说 +å¸ĮæľĽ ä½ł +interest ing +- employed +ĠG adget +è¿ģ å¾Ļ +éĤ£ çīĩ +su itable +æĪij åıª +AS N +Result Set +inf ection +D ON +çļĦ åı« +Ġm ourning +æ¶Ī失 ä¸įè§ģ +Ġcellul ose +Ġpess im +èµ ¡ +èĩª éĹŃ +-b al +Ġasp iration +ç±» 游æĪı +èĬĤ æ°´ +è¾ĥ çŁŃ +åĸ· åĩº +Talk ing +æĥ³ åIJĥ +Ġel it +å¹³éĿĻ çļĦ +Ġgrace ful +b abel +ĠFin ished +ãĢĤå¦Ĥæŀľ 没æľī +ĠT unnel +å¨ĺ 亲 +ĠB ail +æµģ éĢŁ +äºij å³° +Âĥ ÃIJ +ĠM PL +è¿ĩ ä½İ +çļĦå°ı 女åŃ© +ĠAcc ord +ĠSO CK +p ole +iv ism +åºĶ çŃĶ +ĠKat y +ĠS ey +ĠM iz +ĠIM O +M exico +W ASHINGTON +æŀģ æĺĵ +Ġliber ties +çݰéĩij åıĬ +çİ«çij° èĬ± +ä¸Ń æĹ¥ +Ġcontest ants +_INST ANCE +Ġunanim ous +ate au +å°ı è·¯ +em ann +Ġri pple +ĠL oud +ĠP is +ä¹Ł ç»Ļ +-M ail +Ġv ows +éĩij çīĽ +Ġjo ys +bra ins +bad os +Ġlever aged +al og +Ġprox ies +ĠWor st +ĠP urdue +æķ° 以 +ä½İ çĤ¹ +她 çļĦè¯Ŀ +Ġdilig ently +ï¼Į åIJ¸ +æľĢ 主è¦ģ +ĠCon way +çłĶç©¶ ä¸İ +mat ics +S ugar +åľ¨ ä»»ä½ķ +è´¢ æĬ¥ +ĠAdapt ive +p kt +nd ra +ĠF iji +son ian +æŃ» æ´» +.f s +.W ork +æ¯ĭ庸 ç½®çĸij +/ å¹´ +in ness +åIJį ä¸ĭ +Ġemp ir +èĤ¡ä»½ åħ¬åı¸ +丢 人 +ĠT ED +od os +äºĶ èĦı +ĠB MC +Ġhe irs +ãĢģ èĥĥ +åįķä½į åĴĮ +Ġelectric ally +ĠChi ropractic +ä¸ĵ 为 +éĩį çݰ +缸 åĬł +æīĵ æĭ¼ +第äºĮ ç§į +y ne +Ġd ared +Ġt ipping +ĠLaf ayette +ĠHuman ity +è§Ħå®ļ äºĨ +PROC ESS +_ Status +ä¹ĭ çģ« +çİ© ä¹IJ +Ġdub ious +( Log +Ġprior i +.config ure +Ġdehyd ration +ï¼Į å®¶åºŃ +f rm +Ġwas tes +æĹł å½± +Ġro aming +Ġwhat s +åīį è¨Ģ +str ide +çŀ© 缮 +_ ssl +Ġearth ly +sect s +èIJ½ éŃĦ +Ġax le +_ID X +ãĢģ åĽºå®ļ +-se ven +Ġmaxim ise +Âł åı¯æĺ¯ +Ġind ist +åıį éĹ® +ĠBrig ade +ãĢģ æ¸© +Ġit alic +ĠFellow s +( elem +Ġcrack ers +ĠJenn ings +ï¼Į çķ¥ +_ ident +éĺ² æ½® +è¿ĺæĺ¯ ä¸Ģ个 +.A c +åħĭæĸ¯ åĿ¦ +p ain +- self +er ase +大 åĬ¿ +åľ¨ åºĬä¸Ĭ +_AR B +ĠV PS +èĽ ° +ĠGl oucester +Ġz ucchini +^ r +ĠH IS +çļĦ人 士 +è¡Ģ 绣 +é½IJ é²ģ +Ġkidn apped +èµĦæł¼ çļĦ +v ie +ĠDE CL +éŃĶæ³ķ å¸Ī +Explore r +к о +å¹´ 产 +åľ° äºļ +Ġhab en +Ġdebug ger +ĠMut able +ĠCon verts +âĢ ¯ +ĠT ent +Ġpro verb +ĠB BB +_d ependency +鼨 ä¸Ń +Ġ åĪ¶ä½ľ +认 æ¸ħ +Ġsav ory +, æĪªèĩ³ +Ġh ues +管çIJĨ åѦéĻ¢ +[i i +ä¼łåĬ¨ è½´ +.tr igger +Ġthem atic +OP LE +Ġir is +ï¼Į æĶ¯æĴij +èįĴ éĩİ +çļĦ çĶŁéķ¿ +ä¸į æŃ£ +Ġdeterm inations +å°ı æĿ¿ +å¿Į 讳 +é³ŀ çīĩ +Lif ecycle +Ġ æĹłè®º +å® Ł +Ġclass ifications +ãĢģ大 åŀĭ +un likely +æĿ¥ å¤ĦçIJĨ +ä¹Ł æĪIJ为 +Ġindef inite +k V +åľ° è²Į +Ġkit ty +ï¼Į åı£ä¸Ń +èĢĮ 代ä¹ĭ +Ġind ifferent +é¢Ŀ 头ä¸Ĭ +Command Line +ĠPe el +æĹłå¿Į æĥ® +.c b +约翰 éĢĬ +çļĦ èĩªçͱ +è¶ħ 大 +ä¸Ģ æĸ¤ +çļĦ ç¨ĭåºı +ä¹ĭ çζ +åĹħ è§ī +æĹ¥å¸¸ å·¥ä½ľ +Ġkiss es +éģ¥æİ§ åύ +ãĢģ S +Ġquil ts +t ie +walk er +Ġim itation +ï¼Į æī¬ +èĻļ èᣠ+éģį åıĬ +大åѦ 士 +诸 ç¥ŀ +Ġasympt omatic +ï¼Į çŁŃ +Ġl ov +ĠZ oe +ĠSu icide +Ġp irates +BO SE +_PRO FILE +ĠAqu a +ro ach +å·¥ ä¿¡ +Ġ ä»ĬæĹ¥ +æīĵ èµı +t asks +h ore +ï¼ĮèĢĮ çİ°åľ¨ +Ġo mp +红 æŀ£ +为 好 +èĩª çŁ¥ +sec s +åıªèĥ½ 说 +Ġey ew +_ Int +Sh ar +ï¼ĮçĦ¶åIJİ æĬĬ +ĠNe ut +AMP LES +ä¸į ä¸ĭåİ» +oll s +æ°ij主 åħļ +Ġ( ^ +ç£ģ åĬĽ +ĠCL ICK +Ġmon k +èĥ½ èĢIJ +åħĥ ç¥ŀ +ç§ij 夫 +æĻ¶ çŁ³ +æĭĸ æ¬ł +çļĦ 车è¾Ĩ +( Date +ï¼Į åĮ»éĻ¢ +-t reatment +Ġdeploy ments +ice ps +ãĢģ åıĬ +arm or +è¿ľ åİ» +, èµµ +ä»İ ä»ĸçļĦ +ĠEle phant +( rect +å¹³ è£ħ +ĠF ate +ĠH astings +读 èĢħçļĦ +.m kdir +ĠLinked List +ĠSuff olk +M bps +.b ounds +Ġbank er +ç͵ æĢ§ +O US +Ġinst al +è£ħ åħ¥ +çIJ¼ æĸ¯ +Ġ æ´ª +没 æĶ¶ +Ġfluct uation +ä¸Ń åĮħåIJ« +举 缣 +ĠHig hest +å°± æĹłæ³ķ +åī Į +æľĢ çŁŃ +ĠRem oves +Ġprepared ness +ex act +Ġx l +缩 åĨĻ +ĠGrad ient +ĠR HS +çŃī éĩįçĤ¹ +] # +æħķ çϽ +è§Ĵ度 çľĭ +Ali ases +Ġfet us +ĠTher m +ç§į ç±»çļĦ +Ġwalk er +Ġsp ills +ES M +Ġell ipse +欧洲 æĿ¯ +Ġbrilliant ly +ott le +amb urger +éĺ» å°¼ +å½ĵ ä¸ĭçļĦ +举 ä¸ĢåĬ¨ +ĠGen ome +D ashboard +Ġd ictionaries +èĥ Ń +Ġbib liography +.c ast +-p aid +éĢĤç͍ èĮĥåĽ´ +äºĨ ä½łçļĦ +ident al +åIJ¬ æĪij +uc ent +C oder +Ġl bl +ĠL ibr +大 å¢ŀ +Ġinf antry +Tele gram +B anner +å°ij éĩıçļĦ +æİ¨ ç®Ĺ +-c urrent +Ġprincip ally +ol ing +lic he +éĽĨ å¸Ĥ +ä¼ĺéĽħ çļĦ +pect ing +书 åIJį +ï¼ĮæŃ¤ å¤Ħ +ĠCad illac +èµĽ ç¨ĭ +ĠC ogn +ĠK ru +ONE Y +PP P +lik elihood +æĴ ¸ +çĽĬ æ°Ķ +ðŁ Ķ +di ag +l aughter +ĠPh i +Ġav al +.H TTP +f ee +Ġant if +j h +_m odels +ï¼Į请 åľ¨ +ĠLeg o +ed ient +æ¯Ĵ èᝠ+Ġ Ç« +_m etric +Requ irement +ĠSPE C +Ġpolic ing +æ´» åĮĸ +Ġbos on +ĠV ibr +ï¼Į å±ĬæĹ¶ +æĺ¯ä»Ģä¹Ī æĹ¶åĢĻ +_PROC ESS +Âł M +个人 æīĢå¾Ĺç¨İ +å¯ĨåĪĩ åħ³æ³¨ +ï¼Į éĹ®é¢ĺ +Ġsp leen +_D e +Ġroad side +ĠDel icious +æĺ¯ 该 +ãĢģ å¤ı +ĠD re +ĠSc or +ä¸Ĭè¿° æĬĢæľ¯æĸ¹æ¡Ī +Ġin equ +Ġtruck ing +ĠSer ious +ER ATION +æĬĴ æĥħ +ĠAppell ants +Ġr ut +éĩij æ²Ļ +çļĦ æŀĹ +IN UE +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +大家 ä¸Ģèµ· +:m iddle +çļĦ æ¯Ķ +Ġl is +模åĿĹ åĮĸ +ĠShe lf +ä¹Łä¸į ç®Ĺ +åĸĺ çĿĢ +æĪij å°±ä¸į +ä¸ī 缸 +_N EXT +Ġmedium s +âĢĿ åIJİ +Ġ& _ +çļĦ å®ļä¹ī +Ġint olerance +éĩijèŀį å¸Ĥåľº +è·¯ ä¸İ +ï¼ĮæĪij ä¸įçŁ¥éģĵ +èĻļæĭŁ çݰå®ŀ +æľª å°½ +-m oving +èĭı è½¼ +Ġstri pping +Ġol ives +=-=- =-=- +_m on +Ġfac ade +el n +Ġup hill +åľŁ åĮª +Ġast rology +- address +Ġ èĴĭ +æŃ¥ åŃIJ +ä¸įèĥ½ åľ¨ +Ġgly cer +Ġpian ist +ĠT v +ãĢģ ä½ĵ +ĠLD AP +N an +åı¯ä»¥ èĢĥèĻij +_d irection +èī³ ä¸½ +/ abs +Y ahoo +ãĢģ æľĭåıĭ +éĢĥ åĩº +ï¼Įè¿ĺæľī ä¸ĢäºĽ +天ä¸ĭ 第ä¸Ģ +Comb at +æĿ¥ åĨ³å®ļ +sp ell +ï¼Įä½Ĩ éĤ£ +æ®ĭ ä½Ļ +念 åı¨ +L ay +ãĢĤ åĪĻ +å¥Ĺ çļĦ +Ġg rou +ĠM are +ĠN em +ä¿¡ éģĵ +out il +æĺ¨ 天çļĦ +å·¡ èĪª +ĠMeasure ments +èµı èµIJ +ï¼Įä¸ĢåĪĩ éĥ½ +Ġ ä¹IJ +ĠT rem +Ġcomp lements +. results +Ġwork book +ä»Ģä¹Ī éĥ½æ²¡ +åĽŃ èīº +ĠNewsp aper +Ġcl ipping +表 åįķ +Ġecho es +, åĿĩ +_t xt +_at om +Ġprest ige +& R +( of +en force +Bar bara +Ġphy logenetic +Ġbloss om +ĠDeuts ch +åĽ ± +app roved +碰 åΰäºĨ +( isset +åľ° æĥ³ +åħĪçĶŁ 说 +è¿ĻæĿ¡ è·¯ +( (" +Ġc ation +ä¸Ń åĮ»éĻ¢ +åģļ ä»»ä½ķ +èι çļĦ +ĠL ok +ĠCan berra +Ġweight ing +ãĢģ æĢ»ç»ıçIJĨ +ĠSub aru +æ¯Ķå¦Ĥ 说 +ãĢģ æ³ķåĽ½ +ä»ĭç»į 说 +ĠShel ter +Ġgriev ance +ĠNS F +åĴĮ ä¿¡æģ¯ +ĠAccount ability +æ¶Ł 漪 +人 å°Ĩ +å¤ļ æĿ¡ +ĠProm pt +re ro +Ġmach ining +æĥ¨ éĩį +ä¹ĭ ä¹ī +ENT R +å½Ĵ ç±» +èµĦæĸĻ æĺ¾ç¤º +ĠNation wide +ĠSt am +fter s +N g +æľ¬ èī² +éĢļ çķħ +PC M +Ġd ime +Mel issa +er ably +ï¼Įä½ł è¿ĺæĺ¯ +host s +å¯Ĵ æĦı +è¹ ¿ +P arsed +ä»ĸ çŁ¥éģĵ +ä½ķ å°Ŀ +Ġsubst itutions +æ´Ĵ èĦ± +Ġsh ading +æļĹ æĿĢ +ĠBen ef +ĠOffic ials +ĠBrief ly +ï¼Į åĢŁåĬ© +EN DS +éĢł ç¦ı +Ġ 亿 +Ġm ashed +Ġ æĻļä¸Ĭ +Ġf actions +н ого +éĶĭ èĬĴ +ĠMel anie +ip ulation +_or ig +ãĢĤ åı¦ +ĠP ec +Ġbar b +Ġalign ing +Ġhect ares +Ġ 软件 +ce mic +å·¡ æ£Ģ +_ am +ĠPract itioner +æĹ¥ éĩĮ +hel ps +, åĨħ +n ails +á ¸ +ot te +, ä»» +Ġelement al +åIJµ éĹ¹ +ï¼Į å¤Ħ +Ġst or +è§£éĩĬ äºĨ +ãĢĤ æ¯ıå¹´ +Ġgovern ors +Inst alled +ĠMark er +_ ld +ol ytic +ang ent +Ġwind y +ãĢģ çļ® +çļĦæ°Ķ åij³ +ĠTrust ed +Ġ$$ {\ +ĠBi otechnology +Ġvine yards +ĠB j +ĠD olphins +Q s +ac om +æĺ¯ä¸Ģ个 人 +åѦ å¾Ĵ +å¾Ĺ æľī +äºĨä¸Ģ å®ļ +黯 æ·¡ +ĠSof ia +å¹´ æĺ¯ +RA DE +cal er +è´Ń 票 +竹 åŃIJ +ï¼Į H +è¿ŀ åIJĮ +æĬ¥ äºĨ +Im mediate +éĻį åĻª +UN CH +c w +åıĹ è´¿ +." ) +æī« é»ij +}} =\ +çŀ© 缮çļĦ +Pro vision +çİĩ è¾¾åΰ +媲 ç¾İ +åĩºæĿ¥ åIJİ +. But +Ġconform ity +Ġexplan atory +Î ĵ +ĠTra uma +ãĢĤæĪij çŁ¥éģĵ +B ear +ãĢģ çİ»çĴĥ +è¿Ľ åΰ +é½IJ èģļ +ï¼Į ç´§ç´§ +æľĪ ä¸Ĭ +ï¼Į æŃ¦æ±ī +_ alt +text color +åį°ç¬¬ å®ī +Ident ification +, 估计 +J I +轻轻 ä¸Ģ +çĹĴ çĹĴ +Af rican +Clean up +çģ« çĤ¬ +ĠX iao +wh ose +,å°± è¦ģ +éģĩåΰ è¿ĩ +åĸ ĭ +Ġposition al +åī§ çļĦ +æ¯Ķ 以åīį +æ¡Ĩ åĽ¾ +ï¼Į èĬĤçľģ +âĢ ij +ĠS ultan +Âł èϽçĦ¶ +.j ob +åºĬ åįķ +ĠV ie +Ġapprox imated +, @ +A u +ĠSt alin +è¯ķ ä¸Ģè¯ķ +Track s +_w arn +i Pad +ĠFind ings +åħĥ èĢģ +ãĢģ 人æīį +-mod al +æľº åľ¨ +ĠCell ular +è¿Ļ 两天 +æıIJ 请 +ĠBlack jack +.N amespace +Ser vers +). \ +ï¼Įä¸Ģ æŃ¥ +(un ittest +se vere +ç¾ Ķ +æİī 头 +ä½Ľ éĻĢ +æĮº æĭĶ +Ġgeneral ize +t te +å¤įæĿĤ 度 +ely n +æŁ¥ åĩº +ï¼Įå®ĥ 们çļĦ +O LED +comp letion +Ġgrav y +, ä¸Ģå®ļ +\ l +æµ· æ·Ģ +Ġpan creas +Ġy s +Ġ èĭ± +ara oh +gu est +Ġinhab ited +åĨ·ç¬ij ä¸Ģ声 +ä¸Ń æİ§ +Ġout liers +ï¼Įåı¯ä»¥ 让 +æĹł éĿŀ +Ġresemb lance +ĠDo om +F u +Ġdim s +,åĽł èĢĮ +s ensor +ä¹ĭ éĥ½ +-s ol +Ġm ound +ĠC CC +äºİ ä¸ĸ +èĩªå·±çļĦ æĥħ绪 +Ġirrit ated +æŃ Ĩ +rop ractor +_ST ORE +R CC +Ġ æīĵå¼Ģ +.B itmap +ĠFl ame +W G +Ġins urg +ĠCh oir +èĤ¡ æ°ij +ä¾Ħ åŃIJ +大 èĴľ +ip ers +And re +Pointer Exception +大 æīĵ +èģļ éħ¯ +consc iously +Ġm oles +uk ary +ĠMent or +% èĩ³ +ç»Ļ ä»ĺ +åħī 临 +ĠData Type +ĠFund amental +大çIJĨ çŁ³ +ĠS ands +per l +ĠMix er +ä¸ĩ åĥıç´ł +çĿģ å¼ĢäºĨ +ï¼Ľ 对äºİ +帮 主 +ç¥Ŀ ä½ł +Ġalloc ations +éĵ¸ ä»¶ +,ä¸į ä½Ĩ +Ġmer ry +ĠH orm +å¹´ éĩij +ĠG unn +好 äºĽ +å¸Ī åıĶ +ĠArist otle +P X +st akes +ĠC andle +Ġmov able +Ġhairc ut +èģĶç³» çļĦ +* " +èµĦæł¼ å®¡æŁ¥ +( socket +å¹¶ 没 +Ġæľ¬ æĸĩ +Ġpit chers +ĠBren nan +ï¼Į æģ¨ä¸įå¾Ĺ +Ġb loc +ãĢģ æŃ¦æ±ī +æĪij åħĪ +çļĦ æŃĮ +zz arella +ĠO sw +_M ARK +æľĢ好 æĺ¯ +ĠP DE +Ġslow down +Attribute Value +ï¼Į 寻 +æĭĽ åij¼ +( account +æĢĿ æĢĿ +OG LE +ct omy +Ġcap illary +èĪªç©º èĪªå¤© +dim ension +ĠT eddy +ĠS olic +âĢĿ èĢĮ +ä½Ľ åĥı +ãĢģ æĶ¯æĮģ +éº ½ +åľĨ 润 +s am +Ġ çĩķ +.Aut omation +ym es +/ assets +ĠAm ar +añ ol +Sad ly +ä¸Ģ å±Ĭ +get Data +n ol +ãĢĤ çĶŁ +ĠM ao +ist ible +çļĦæľīçĽĬ æķĪæŀľ +çļĦ èĤ¡ç¥¨ +åģı ä½İ +Could n +answ ers +W arm +å°± æīĵ +AM I +Ġbit terness +年代 åĪĿ += F +ST AR +ĠSu itable +ĠD ummy +æľīä¸Ģ éĥ¨åĪĨ +eps i +Ġc ork +ĠPh p +å°ĸ 端 +-se q +: ãĢĮ +ä¼ļ计 å¤ĦçIJĨ +çļĦæĸ¹å¼ı è¿Ľè¡Į +re load +ĠMe h +_n umeric +part ner +. ss +ĠT issue +ä¸į èĩ³ +Ġwet lands +象å¾ģ çĿĢ +Ġs op +çī¹ å¤§ +æĿ¥ ä¹ĭ +(f ont +ĠNS Log +åħĭ åĪ© +人æ°ij æĹ¥æĬ¥ +åĪĽ ä½ľèĢħ +åłª æ¯Ķ +ĠNUM BER +äºĨä¸Ģ é¡¿ +ĠP apa +Ġun official +æĶ¶ åħ» +Ġstand by +å²ģ 以ä¸ĭ +_DE FIN +æŃ¤æĹ¶ æŃ¤åĪ» +ï¼Įè¿Ļæł· ä¸ĢæĿ¥ +ĠEL ISA +Ġ 容 +Ġa es +ä¹Ł åĽłæŃ¤ +ĠAn im +å¹´ èĸª +ĠV ish +\ Gamma +ĠWe apons +è¿ľ æ¯Ķ +æĹ© äºĽ +roid ism +ãĢģ çī© +Ġinstant iate +ãĢĤå°± è¿Ļæł· +çϽ ç³ĸ +çIJĥ èıĮ +Ġ æ¯ı个 +ãĢĤ æĿ¥èĩª +åŃIJ æĽ° +EN R +uss i +ĠModel Renderer +ä¸Ń 以 +ret ry +è¡Įä¸ļ çļĦåıijå±ķ +æīĩ éŨ +_SUPPORT ED +çĮķçĮ´ æ¡ĥ +ĠV ict +åıį åĢĴ +æ´Ľ æŀ« +Ġscript ing +ĠCoord inate +! $ +ons on +ĠCom paring +Me chan +æĬĬ 头 +çĵ ® +ä¸Ń 天 +ĠAnnounce ments +èĬ ª +éĴ ¯ +_c ut +.M enu +Ġnit rate +Ġsol vents +Ġword press +大 éĺµ +ä¸ī å°º +ìĭ ľ +Ġse psis +_D IP +umbers ome +O Auth +Ġd rowning +ĠF ury +ĠF TC +Ġcoll age +( auto +Ŀ ¼ +ere x +/ rest +ĠG ina +ĠMin n +æŁ¿ åŃIJ +, æīĭ +ull ing +sub str +H ugs +çļĦå°ı æīĭ +èĤ ® +ç§ģ å¯Ĩ +åĬ³åĬ¨ åħ³ç³» +c ars +ab leness +è° ij +ĠCount ies +å¹¶ä¸į æĦıåij³çĿĢ +al ms +Ġb ounced +ä¸Ń åŃĺåľ¨ +æ°´ è§£ +æī¿ éĶĢåķĨ +ãĢģ é£İéĻ© +UI Image +ack le +ĠK em +Ġcr c +Sh utdown +, 谢谢 +re ports +ĠC f +ãĢģ åı°æ¹¾ +). [ +ood les +ĠDep loy +Mod ifiers +ĠHead ers +ĠS iber +St ress +æµģ æ´¾ +ĠU h +声 æľĽ +Unity Engine +ĠL H +ĠShel ley +è¿ ¢ +Ġe inen +Ġco aster +Ġbefore Each +.d ialog +See ing +- termin +oo ch +æį º +Ġlo ot +å®ŀ è¯ģ +ruct or +è¯Ħ æ¯Ķ +ut m +ĠO xygen +. rect +åīį åį« +æĪĸ éĹ´æİ¥ +.P RO +å¤ļ å²ģçļĦ +G er +ig il +è§Ĵ èĨľ +è§£åĨ³ è¿Ļ个éĹ®é¢ĺ +ĠDec isions +ï¼Į çIJĥ +大 æŀĹ +æĥ³ åģļ +ĠAr rest +ï¼Įç͍ åĬĽ +ge al +æĶ¿ å§Ķ +irc uit +ong writer +Ġelectro static +åľ¨ 马 +ç»ĺ åĽ¾ +ï¼ĮåĬł éĢŁ +opens sl +ĠL ia +æķĻèĤ² åŁ¹è®Ń +æĻ® æĭī +éĿĻ è°§ +p rep +æĭį çĿĢ +ĠCommit ment +èĸĩ èĸĩ +ãĢģ æ¶Īè´¹ +ï¼ĮæĪij å°±ä¸į +As m +cro ft +Prov ided +ï¼Į åı° +é»Ħ å±± +.get Width +Call able +-p olicy +ĠBe ans +S ector +-Col a +说 好 +ĠNeuro science +为 æŃ£ +(p riv +at ical +å°Ĩ éĢļè¿ĩ +è¡° åĩı +ï¼Į 表达 +sequ ential +ä¸İ å¤ĸ +Ġfil enames +rat om +Bro ok +ä¼ģä¸ļ æıIJä¾Ľ +éĥ½æĺ¯ å¾Ī +åĵĪ éĩĮ +_ad apter +N ation +çªģ è¢Ń +( original +< object +Î ¦ +ï¼Į æĽ² +åIJĦ æĸ¹éĿ¢çļĦ +Ġplag ued +å¾· åĭĴ +.pro file +åĿļå®ļ ä¸įç§» +< H +çļĦ èĩªå·± +atic a +ï¼Į è¿ijæĹ¥ +ï¼Įä¸Ģ å¼Ģå§ĭ +it rogen +ãĢģ æľīæķĪ +çĥĪ æĹ¥ +çĽijæİ§ ç³»ç»Ł +éĺ²çģ« å¢Ļ +Ġa ches +âĢľ 第ä¸Ģ +èĥ½å¤Ł 对 +Ġsleep y +- acc +lo an +ï¼Įä¸Ģ åħ± +ET CH +Ġwhisk y +U nt +Ġst encil +B id +çļĦ ç»ĵåIJĪ +Ġj i +æ³¢ 段 +ï¼Į 丹 +æīĢ çŁ¥ +å°Ĩ çͱ +Ġcompos ers +æī¾ æŃ» +ä¸Ģ åijĺ +åĩº ä¸Ģç§į +ĠMagn et +Pro position +en iable +ï¼Į åħ· +çĶ ¥ +ä¸į å¼Ģå¿ĥ +çĿ ¨ +åĨĽ ç͍ +-f ed +èŀ ¨ +ίν αι +re cent +ĠI PL +ĠGo a +Ġcher ries +: YES +f ragment +ĠF inger +èĩª ä¿¡å¿ĥ +被 ä»ĸ们 +失 æİª +éĨĴ è¿ĩæĿ¥ +v ale +Ġtim etable +人 çŃī +Ġtra pping +Ġsimpl ifying +CRE T +ä¸ĵ åĮº +ĠInter vention +ï¼Į è®° +IS ON +: System +ï¼Į åŁĥ +Ġins anity +Ġn ailed +ext ended +ĠNet anyahu +Ġbif ur +. evaluate +ä¸ĵ åľº +èĪĴ å±ķ +ĠHass an +ĠR oe +oc can +Ġsequ entially +KE EP +Ġplead ings +ä¿ĿæĬ¤ 好 +æľī é£İéĻ© +为 第ä¸Ģ +ĠMom my +çļĦ å¦Īå¦Ī +ä½ľ åĿĬ +被 åĪ«äºº +å¤ĦçIJĨ åIJİ +æĽ¾ æĺ¯ +S ac +Ġ å¸Ĥåľº +od ings +ĠJ orge +èĮĥ æĸĩ +.rand int +Ġs ands +åľ¨ å¿ĥ +Ġpr é +èĻļ å®ŀ +Ġsab ot +Ġis nt +ĠC ritic +åŃIJ ç³»ç»Ł +é«ĺ 楼 +ä»İ è¿Ļ个 +ï¼ĮæīĢè¿° åĽºå®ļ +ĠReg ina +ï¼Įåΰ æĹ¶ +åħ±éĿĴ åĽ¢ +h int +æīĵ åĵį +ç³ķ çĤ¹ +(t p +Ġpregn ancies +Ġtort ured +æĺ¥ è¿IJ +Previous ly +IEL DS +æ±Ĥ ä½ł +_RES OURCE +æ±Ĥ æĺ¯ +_S ERIAL +E uro +Strict ly +ig ail +ä¹ĭ è°ľ +äºĮ éĥİ +the ad +çŃij çī¢ +orks pace +ä¹Łæĺ¯ è¿Ļæł· +ĠGa uss +r ification +Ġyoung ster +led ged +ç§» åΰ +ĠG SM +lic ensed +Ġæľ¬ å®ŀç͍æĸ°åŀĭ +究竣 æĺ¯ +Ġpetition ers +Under stand +Ġ 广 +åľ¨ çĶŁæ´»ä¸Ń +le w +æĪIJ åħ¨ +ä¸İ æĤ¨ +è¾ĥ å¼± +åĵĪ çĻ» +磨 åIJĪ +VE LO +ic illin +èĢĮ å¤į +人 åij½ +_PRO TOCOL +ĠC ush +Ġ) ( +å®ĺ åľº +Account ing +éļľç¢į çī© +æĸ° å¥ĩ +Ġgoal keeper +Ġge opol +ç«Ń è¯ļ +åĽ¾ 为 +Ġabandon ment +S parse +ent ered +ĠH iking +ng ine +Ġa e +ĠAn k +å®īè£ħ äºĨ +Ġ{} '. +Ġacc rued +ï¼ĮæĪij 对 +ave ment +ï¹ ij +Ġimplant ation +i atives +ĠA ck +Ġweb pack +å±ħä½ı åľ¨ +iff er +é£İ åIJij +.N on +滤 ç½ij +c alls +ĠQ ur +ä»·æł¼ ä¸Ĭ涨 +Ġconfront ing +_RE LEASE +ĠAm elia +. Std +G ran +ä¸Ģä¸ĭ å°± +éªĮè¯ģ çłģ +çļĦ æķ°åŃĹ +åı¯ ç¼ĸç¨ĭ +ä¹ĭ æĢ¥ +åĩºä¸Ģ ä¸Ŀ +_ Object +便 èĥ½ +å§Ķæīĺ 人 +, å¾Ĺ +çªģçĦ¶ åĩºçݰ +ĠLaw son +æµģæ°´ 线 +Ġ åį· +Ġpl ains +Ġem itter +ï¼Įä¸Ģ 头 +åį± åıĬ +ï¼Į æ·¡ +ĠSc enario +çĽĬ çĶŁ +Qu ota +ï¼Įç͍ æīĭ +_SHA RED +IP HER +çīĽ æİĴ +ĠTra ff +_T E +Âł ä½Ĩæĺ¯ +éļıå¤Ħ åı¯è§ģ +ĠG MO +Ġgood will +åĵ¥ çļĦ +ĠTR ACE +Ġcl own +åı¤ ç±į +cap acity +G uild +_ js +红 èĬ± +ï¼Įçľ¼ 泪 +å°Ĩ æł¹æį® +bi otic +Progress Bar +æģ¢å¤į åΰ +æĭ³ åĩ» +ĠYam aha +ï¼Į K +Ġb unny +UIL T +ĠS cores +/v ideo +.V ERSION +å½Ĵå±ŀäºİ æ¯įåħ¬åı¸ +ĠLic ence +å°¼ çİĽ +ï¼Į 伸 +åħ¶ 人 +éĿŀ å¾Ĺ +ä¼ļ åİ» +æĪij们 æľī +c rypt +çĶŁ æł¹ +åģļ é¢ĺ +顾 ä¸įå¾Ĺ +ub en +åĨľ 夫 +UR A +éĨĴ æĤŁ +Ġhor izons +Ġdinos aur +é³Ħ é±¼ +_ UT +ĠB AT +ï¼ī æĪĸ +å¿« äºĨ +çļĦ人 çļĦ +天 è¡Į +.Foreign Key +, ç»Ħç»ĩ +ãĢĤ è¿ĺæĺ¯ +åĴĮ çIJĨè§£ +åıĪ æ²¡æľī +ĠGall agher +ĠB icycle +å°ıç¼ĸ 为大家 +/ conf +ï¼Į åĦ¿åŃIJ +大 èĥľ +çĤ¹ å·¦åı³ +Transport ation +.is Array +ãĢĤåĨį åĬłä¸Ĭ +åĩº åŁİ +详ç»Ĩ ä¿¡æģ¯ +fore ground +空 头 +模å¼ı åĴĮ +Ġirre versible +ãĢģ åĽł +ä¸Ń 说 +Ġmed iate +.s ite +ĠW aves +ĠTru cks += function +Ġ åħ¬åijĬç¼ĸåı· +ĠH edge +ĠPost greSQL +Gu ess +诱 人 +ĠпÑĢ ÐµÐ´ +ĠDr ill +Coun cil +åħĭ åĬ³ +Ġroad way +ï¼ĮåĬĽ æ±Ĥ +Ġdict ates +Ġt ipped +æĹ¥ åİĨ +ĠBl ast +ĠCyber security +ĠConserv atives +ä¹Łæľī æīĢ +YNAM IC +/ projects +å®¶ éŨåı£ +ç»Ļ å®Ŀå®Ŀ +失 è¡¡ +g cc +k Hz +ï¼Į è´Ńä¹° +ĠMay er +/x html +-work er +Ġl g +un able +Pro tein +Ġlos er +Ġam ber +" D +ĠI CO +åı¯ 缴æİ¥ +F lo +Ġg ol +é£İ åĴĮ +ĠAv iv +Ġk W +.d uration +湿 çĥŃ +FR AME +ĠSleep ing +ç¾½ç»Ĵ æľį +i ad +Ġh ops +} < +ãĢģ æ°ijæĹı +æīį ä¸įä¼ļ +åĬŁ åºķ +Ġб Ñĭ +ĠIn cent +ãĢĤå¦Ĥæŀľ 说 +Ġgri pping +- var +G X +涨 è·Į +Ġsou ps +ĠG lu +Ġmonument al +M iami +Ġ åĪļåĪļ +ynchron ously +Ġrou ters +ĠI FS +è§ģ åΰçļĦ +çĥŃ ç͵ +åIJĥ è´§ +æĶĢ çĻ» +è¿Ķ æł¡ +ĠR oses +ãĥ Ł +åĪĨ éĺŁ +åºĦ å®¶ +> null +åħ¬å®ī éĥ¨ +P id +[ node +第ä¸ī å±Ĭ +åºĬ éĵº +Ġabol ished +Ġl ax +Ġ æŁ¥çľĭ +è¶ħ 强 +éĺ¿ æĸ¯ +Sp atial +ĠPR IMARY +åľ¨ æľ¬åıijæĺİ +ï¼Įä¸Ģ 缴åΰ +,, ,, +on ian +çģ¯ çļĦ +Ġsubst ituting +ãĢĤ åĽ½ +ĠJ ury +æ¼Ķ 说 +.ext ract +Ġpier cing +ãĢģ ä¸ĸçķĮ +Ġauthor itarian +æĹ© å¹´ +.w hat +ĠBever age +_inter rupt +ç»ĵ 转 +æķ´çIJĨ äºĨ +V intage +.b uf +åĵģè´¨ çļĦ +Ġfer mented +_t ables +Ġpain ters +Ġcrown ed +j m +w alls +ĠAn not +-R ay +Ġrepent ance +n en +Ġbenef iting +gt k +æłĩ è¯Ń +ï¼Įä¹Ł ä¸įè¦ģ +éŃ ĩ +Ġmaster ing +çİĦ åħ³ +.ch art +Ġn el +主 æİ§ +è°Ī åıĬ +çĶŁåij½ ä¸Ń +æĪij åij¢ +Equ ation +ĠAssoci ations +åIJIJ èķĥ +ograp hed +Tw enty +è® ¹ +Ïģ γ +æĵ¦äºĨ æĵ¦ +ç¬ij è¯Ń +å±ŀ å®ŀ +rt le +Ġconvers ational +çļĦæīĭ ä¸ĭ +ĠØ ± +oit te +ç¼Ŀ åIJĪ +Ġ 以åıĬ +çļĦ åħĥç´ł +ĠB LE +ĠF aces +ä¸Ĭ æŀ¶ +_sign ature +åĩĢæ°´ åύ +ĠRed irect +- context +Ġa rab +端 èµ· +ĠPass port +ĠGM AT +{ matrix +åĬŀ 好 +Ġä¸Ģ åĪĩ +w ed +Ġj ul +æ°ij å¿ĥ +æľįåĬ¡ è´¨éĩı +TE CH +Ġrest itution +ĠÑģ в +, åIJ¬ +ä¸ī æĸ¹ +è¯į çļĦ +art ner +èĭ±åĽ½ 人 +ï¼Į两 ä½į +Y o +å°± åΰ +Ġph antom +ern o +ĠFif ty +ĠT asks +å·¥ä½ľ æĹ¥ +. Number +åĨ¬ çĵľ +K ings +put ation +OP TION +Ġk arma +ï¼Ľ æĪĸ +æ´Ľ çī¹ +ä½ĵç³» åĴĮ +ĠSTAT ES +ï¼Į å¤ı天 +Ġch k +æĥĬ éĻ© +说ä¸į åĩºçļĦ +便æIJº å¼ı +æĺ¯ 让 +ĠN inth +R FC +T URE +缸 å¤ĦçļĦ +-f iles +wh it +Ġsw arm +Ġdistract ing +/ how +ock ed +åĽĽ åįĥ +Ġre joice +Ġj it +ä¿Ŀ åĪ© +åĪ« æıIJ +ãĢģ åĨ· +Ġv ase +ĠSepar ate +ä¹Łæľī çĿĢ +ä¹Łæľī ä¸ĢäºĽ +LET TER +çľĭ äºĨä¸Ģä¸ĭ +æľī 礼 +è¿Ľè¡Į ä¸Ģ次 +]( ../ +еР¿ +Ġ ****************************************************************************** +çļĦ èĭ±éĽĦ +_IN TEGER +Contain ers +Ġdict ated +un checked +ĠBig Integer +åºĶ 以 +d ependencies +ä¸Ĭ 身 +ex istent +ï¼ļ ä¸Ń +å¤ļ å¾Ĺ +æīĢ å¾ĭå¸Ī +ĠTrans cript +ï¼Į å§ĭ +Ġfunction ally +æĪĺ 车 +Ġhand writing +ser vers += get +b anks +ĠC FG +èĩª ä¹ł +Ġdel le +Ġmen opause +ï¼Įåįł æĢ»æĶ¶åħ¥çļĦ +ĠRefriger ator +Ġv andal +èİ·å¾Ĺ èĢħ +ĠSomal ia +Q M +ĠHe in +\ ^ +è¯ ½ +iv ist +iddle ware +éĥ½æ²¡æľī äºĨ +Ġdeck ing +ĠMock ito +åī¯ åħ¶å®ŀ +Message Box +in ances +Ġcamp ers +å͝ ç¾İ +sm ooth +L ily +c ir +.S ervices +Ġground ing +$ ' +Ġle vy +çŁŃ 裤 +Program ming +Near by +ĠEN GINE +Ġw rought +æĭ Ĺ +ĠY ug +æ°ij å±ħ +æĬĢæľ¯ æľīéĻIJåħ¬åı¸ +è¨Ģ çļĦ +åĢĴ ä¹Ł +ĠPant her +æĽ´ 强çļĦ +ees e +ĠMor ph +ç´łè´¨ æķĻèĤ² +/ install +Ġy um +å¾Ī æ·± +çݯ è·¯ +ç»´ å¤ļåĪ©äºļ +ï¼ļ ä»ĸ +.c m +Ġemb arked +æ²īé»ĺ äºĨ +ãĢģ ç«ĭ +.W rap +çīĻ é¾Ī +æĢ» æī¿åĮħ +Ġvision ary +Ġcow ard +éĹ®é¢ĺ æĹ¶ +æĺ¯ä¸į æĥ³ +coll apse +V a +ram ed +Ġpost season +è¿ľ è¿ij +ĠCam den +æ¡Ī åıij +ãĥ ¢ +æ³¢ åıĬ +Ġ æľŁåĪĿä½Ļé¢Ŀ +S b +j avax +æ°Ķ åĸĺ +è·Ł ä¸įä¸Ĭ +å²ģ æľĪçļĦ +çĥŁ çļĦ +ĠGard ening +éĩį éĺ³ +å¤ĩ å¿ĺ +.d one +åĩĦ åĩī +Ġc ape +ä¸į æĦ§æĺ¯ +Ġmass acre +Ġset ups +ĠZ ak +Test Method +. There +N ONE +æĹ¥ åĿĩ线 +ãĢĤ她 说 +èĢĮ 产çĶŁçļĦ +åĵį èµ·äºĨ +ĠD LC +æ°ij æĦı +bl ur +ú n +ĠTot tenham +orth and +K atie +å¾Ĺ å¾Ī好 +Compl iance +å°± åıªèĥ½ +é¢Ħ éĢī +typ ically +é ı +Spec ified +åĴ¸ éĺ³ +Ġinvert ible +Ġ è´¾ +ens it +éϤ æģ¶ +_T EMP +ĠBig gest +ĠÐ ¢ +< dl +et i +åĴķ åĻľ += l +end i +çļĦ åIJĦ +ä¸İ ä»ĸ人 +(f ind +R oy +æĽ´ åĥı +'] -> +: last +ĠM UX +ãĢģ éĵĿ +ect ure +ä¸ĵä¸ļ 课 +}. \ +_target s +F o +ic l +_F IFO +ĠSTE P +åıĪ æĥ³ +eter ia +è´Ł éĩį +Ġnight ly +.G raph +( require +ĠP IC +ï¼Įä¹Ł å¾Ī +lic hen +鼷 鸣 +_sh ould +è¦ģ æł¹æį® +ï¼Į åıĤ +ï¼Į 缺ä¹ı +ĠT urtle +Ġresp iration +Mult iplier +_ allowed +ç§ijåĪĽ æĿ¿ +Ġvul gar +ï¼Į çĹĽ +便 å°Ĩ +Ġprob ing +å¸Ń ä¸Ĭ +T rial +ãĢĤæĪij 认为 +èĸ ı +Spec ifications +Ġ ä¹Łæĺ¯ +åĩº éĶħ +Ġhyper link +ĠBan ana +ĠEn semble +Cor onavirus +Ex am +ï¼Įçľĭ åΰäºĨ +.In f +ĠD ense +åħ±äº§ 主ä¹ī +ĠLeon ardo +Ġ 举æĸ¹ +çļĦäºĭ äºĨ +ä¸įçĶĺ å¿ĥ +Ġc id +åİĨåı² ä¸ĬçļĦ +Ġhon oured +æĥ© æĪĴ +ĠNe utral +& ) +份 ä¸Ĭ +ï¼ļ çͱ +å°Ĭ èĢħ +ĠTol edo +çĶ» åĩº +秦 åĽ½ +åĩº å¢ĥ +ests eller +Ġkill ings +Ġinterrog ation +- peer +Ġsh rugged +ind e +Ġacc ol +dd ev +hes da +Ġmar in +ĠF I +aff in +Ġinvent ions +ãĢģ æłĩåĩĨ +ab h +ĠV est +igm oid +çݰ å¦Ĥä»Ĭ +Ġ. " +Ġg an +_s b +æŀª 声 +åŁºäºİ æīĢè¿° +Ġpol yp +客 æ°ĶçļĦ +Ġbi odegrad +Ġdir name +SUB SCRIBE +ãĢģ 广西 +çħ§ 缸 +Ġequival ents +è¿Ļ ä¸ĭ +稳 åİĭ += dict +( ap +(' @ +触 è§ī +per missions +ĠPast a +< ![ +Ġa iding +Ġon boarding +Ġem oji +b ond +Ġ å®ļä¹ī +AD ATA +ĠBel ly +ï¼Į éĿ¢åIJij +æľĢ åıĹ +ĠOver flow +çľī å¿ĥ +d well +(w riter +Ġp ope +IT IVE +-in vasive +ĠTra ils +.assert Is +ip ed +ï¼Įæĺ¯ ä½ł +Not Empty +主任 åĮ»å¸Ī +åĽ¾ 示 +顺åĪ© çļĦ +æ³ķå¾ĭ çļĦ +M as +] :: +ï¼Į æĮ¥ +ng x +çļĦ大 åѦçĶŁ +Ġmother hood +Ġmicro soft +( II +Ġpet als +ãĢģ åĪ© +æĿ¥ æİ§åζ +Ġmel anch +( rc +P WM +Ġpaper back +åĮĸåѦ çī©è´¨ +ass ic +建çŃij æĿIJæĸĻ +ar ra +ĠP anda +æį· åħĭ +ä¸Ģ 红 +举 çĿĢ +éĻIJä½į åĿĹ +$ n +æľī æĥħ +_level s +Ġde cedent +ç´ł é£Ł +" ãĢģ +ãĢģ æ¢ģ +å®ī é̏ +æĸŃ ç»Ń +ãĢĤæĪij æĺ¯ +oper ators +ĠâĻ ¥ +ãĢģ æĿŃå·ŀ +åĪļ ä¸Ģ +äºĨ好 å¤ļ +ï¼ĮæĹĭ åį³ +ãĢģ å®ŀéĻħæİ§åĪ¶äºº +Ġwater falls +ï¼Įä»ĸ们 æĺ¯ +Vis itors +åĽŀ æļĸ +ç»Ĩ å°ı +Ġgrand daughter +.time out +_Z ERO +* (( +AC ES +æĹł 以 +ä»Ĭ å¤ľ +C rop +.d iv +Ġcomplement ed +, æľ¬æĿ¥ +ĠT witch +é£İ 头 +ĠBow ie +åī§æĥħ ç®Ģä»ĭ +æ»Ķ æ»Ķ +ĠS ears +æĸĩ éĽĨ +Ap is +ĠUnder graduate +[ email +ate x +-c ritical +_B ase +cket t +大 æ¸ħ +ĠSub stance +Ġmut ed +ĠMad ness +ĠAltern atives +ĠHal ifax +å¾® å°ı +åıĤèĢĥ èµĦæĸĻ +ĠEnt rance +.trans pose +Ġlogarith m +rob at +Ġreass uring +ig ent +ãĢģ å¯Į +j peg +op rop +ĠTh ames +æķ° 个 +ä¸Ń央 ç͵è§Ĩåı° +Prot obuf +éĢĢå½¹ åĨĽäºº +ï¼Į ä¿¡æģ¯ +å¤įæĿĤ æĢ§ +Tool Tip +. rc +ãĢģ æ¸©åº¦ +Ġsc rape +product ive +}_{ - +ĠAlb u +_ soft +× ł +çĶŁ 计 +_tr igger +ĠAL WAYS +è»ĭ çĹħ +ĠB inance +ĠF oss +èIJ½ èĦļ +ĠVamp ire +. Combine +å¼Ģ åΰ +(m at +å¼± èĢħ +èij£äºĭä¼ļ ç§ĺ书 +- security +s orted +Ġf ait +ä¹ĭ 交 +å°¿ ç´ł +åĢĶ å¼º +Ġimpro v +å°ı è§ij +ĠF ahrenheit +Ġz eal +è·¯ åĨµ +,å°± èĥ½ +çļĦ çī©è´¨ +Ġh arp +åħ¶ ä¸į +å®Į é¢ľ +è½» åŀĭ +Ġsuper visory +è·¨å¢ĥ ç͵åķĨ +Âł éĤ£ +缴 è§Ĩ +ĠZ heng +ĠW EEK +Pro j +ï¼ĮåIJĮæĹ¶ è¿ĺ +Ġinvari ance +Ġneutr ality +ï¼Įä¸Ńåħ± åħļåijĺ +ư á» +çģ« é¾Ļ +> ; +åĸ Ĩ +常 ä½ı +bas ename +K enn +g x +op oulos +.t hen +Ġflavor ful +/ not +[ F +缼 å¤ı +Ġsegment ed +H oney +Ġpract ise +Ġscaff old +D ou +建 åħļ +段 åŃIJ +å°±åľ¨ è¿ĻéĩĮ +äº µ +ear able +Ġneed y +ä¸ĸ äºĭ +è¾¾ åħĭ +âĪ Ĩ +åı¦ä¸Ģ æĸ¹ +Ġse ren +emo ji +Ġunavoid able +le hem +ĠC yl +åľ¨ çİ°åľº +åĨĽ å¸Ī +in ject +Ġun interrupted +Ġassoci ative +å¾IJ å¾IJ +(v m +ĠC ous +ĠA UT +æĸ° 书 +ĠHand les +çļĦ 缮çļĦæĺ¯ +_fl at +. Store +ell ij +Ġorigin ates +客æ°Ķ äºĨ +Ġ åħ¶æ¬¡ +ĠY ield +æĭī èµ· +ãĢĤ第äºĮ 天 +âĢĿ å°±æĺ¯ +Ġreg exp +Volunte er +ĠAuss ie +ĠA be +Ġconf er +æį¢ æĿ¥ +ä¸į å¤ļçļĦ +ĠInd ie +æĹ© æ³Ħ +äºī åħĪ +éĩį大 èµĦ产éĩįç»Ħ +Ġnostalg ic +æĪIJ 大 +èµ° ç§ģ +éħ¸ çĹĽ +æĮĩæĮ¥ ä¸Ńå¿ĥ +_mem bers +ub ert +Ġk un +), ' +IM PORT +éĻį æ°´éĩı +.em place +åºĶ 声 +Ġblue berries +ä¸Ń 转 +åı¯ 说 +åıĪ å¤ļ +æĢ» å·¥ä¼ļ +Ġspray ed +Ġres ale +å°Ĩ è¿Ľä¸ĢæŃ¥ +è¿ŀæİ¥ åĿĹ +itiz ens +Ġply wood +ores is +CL I +ç͵è¯Ŀ åı·çłģ +æĹłå¥Ī åľ° +ĠCl othes +åħŃ çº§ +ĠDES IGN +/ year +缸 约 +å·¦ ä¼ł +comp leted +sk irts +ĠWild erness +Ġresidual s +HE ADER +_R C +Act s +Ġf anc +æµ £ +ï¼ĮçŃī çĿĢ +åŁĭ åľ¨ +à ģ +ï¼Į æķij +.s dk +ç½ijç«Ļ 建设 +æ³Ľ çĿĢ +åŃIJ å¤ľ +E UR +è¡Ģ éĩı +iam s +res c +æ¯Ľ 主å¸Ń +, åıij +, 主åĬ¨ +pl ist +æľ¬ èģĮ +ann ual +Ġsight seeing +ï¼Į ç²Ĺ +ĠL ol +èįĨ æ£ĺ +q b +ï¼Į çĶ³è¯· +羣çļĦ 好 +èĤĿ çĻĮ +Ġvamp ires +æ¡ĥ åŃIJ +ĠS aga +ãĢĤ çݰ代 +Ġr anc +Ġind ebted +aus ing +.F ree +Comp arer +ĠReal m +, 让ä»ĸ +. InputStream +f ab +Ġ åĪļæīį +åĮĹ åĮº +ç´¢ èµĶ +Ġslee per +[ P +ag ascar +å®ļ åζçļĦ +å¢ŀ èĩ³ +R aster +ĠM ish +-s w +IL LE +Ġextraord inarily +. bytes +çļĦ 强大 +Ġno ab +çļĦçĥŃ éĩı +v ivo +Ġ` . +åįĥ æĸ¤ +_ < +æĭ Ī +/ IP +å®īåħ¨ äºĭæķħ +Ġhairst yles +ï¼Ľ åħ¶æ¬¡ +士åħµ 们 +åİ» 寻æī¾ +æ¯ı å°ıæĹ¶ +ä¸ī个 æĸ¹éĿ¢ +, æĦŁè°¢ +Ġp ardon +.D evice +Rest art +Ġanomal ous +éģĹ çķĻ +ĠAc ute +æļĹ é»ij +oz o +好 æ¯Ķ +Ġhard ened +CL R +Ġhydro chlor +é¢ĩ åħ· +人 éĥ½æĺ¯ +sh own +èŀį 为ä¸Ģä½ĵ +ĠC aleb +Ġres urre +å¿ĥ å¢ĥ +app ers +è¶³ çļĦ +æ£Ĵ çIJĥ +Ġo tt +ng oing +伤 å¯Ĵ +çĶĺ æĥħæĦ¿ +Ġflav ored +W INDOW +ĠPam ela +e lection +Ġ 社ä¼ļ +éĥ½ åįģåĪĨ +Ġreplic ates +, æĽ´åĬł +ä¸Ĭ æĸĩ +Ġel icit +.c anvas +Rog er +æľ¬ åľºæ¯ĶèµĽ +åİ» æīĵ +Ġhot ter +åį¸ è½½ +ass en +In jection +ĠSo OLEGAL +端 åºĦ +ĠD unk +ĠDen is +.dis abled +ä¹Ł ä¸İ +Ġrest less +la very +_ch ildren +isc rim +çļĦ æĪĺçķ¥ +ĠAb by +omy cin +ĠK not +ne al +ĠCOMM AND +ï¼Į åĽĽå·Ŀ +raw ler +.b order +Ġsymmet ries +c plusplus +yp ical +ĠPass age +åīį çŀ» +,è¿Ļ æĹ¶ +ĠAuthor ities +. One +Į Ģ +Inter mediate +Ġneuro trans +æĬ¥ çŃĶ +-m on +odes k +Play list +Ġch icks +æł¡ åĨħ +Ġclean liness +, æĤ£èĢħ +Ġ 女人 +éķĩ éķ¿ +Ġdilig ent +Ġb ishops +é¦Ĩ çļĦ +Ġgl aze +èݱ çī¹ +èħĶ å®¤ +âĢľ è¿Ļ个 +触 æīĭ +Ġillust rative +Ġpromin ently +ĠThor nton +p ars +åĬł åĩı +è¿ij åľ¨ +Ġ@ _ +-per forming +åĬł è£ħ +çªĹ åīį +Ġesc orts +è§Ĥå¯Ł åΰ +Ġpun ched +ĠSer vers +ä¸Ń çĶŁ +åı£ 红 +å¦Ĥæŀľ ä¸įæĺ¯ +å°Ķ é¡¿ +-develop ed +ek yll +Trans parent +ĠGra ves +ing en +çŁ³ æĿ¿ +æĽ² 缮 +两 级 +éĥ½ 为 +at ology +ĠBos ch +ìŀ IJ +æĢ» åĪĨ +( The +S cheduled +PN G +çļĦ æĸĩåŃĹ +sw ana +å°±æĺ¯ æĥ³ +æķĻçłĶ 室 +é£ ĵ +åı¯ä»¥ åĴĮ +ï¼Įä½Ĩ ä»İ +ĠPro ven +abyrin th +æĢĿç»´ æĸ¹å¼ı +ĠHab itat +èĵĿ åĽ¾ +T weets +ï¼Į åĬŁèĥ½ +æĥĬè®¶ çļĦ +ãĢĤ èİ« +if ton +hen ce +An swers +æļĹ å½± +ĠAfter wards +ĠHE ALTH +å¿ĥ缮 ä¸ŃçļĦ +und ant +-h ours +run s +L iver +Ġ 没æĥ³åΰ +at ro +ä½İ 级 +ï¼Įä½Ĩæĺ¯ ä»ĸ们 +Short cut +ãģĤ ãĤĬ +. ops +_ Config +ä¸į éĩįè¦ģ +cl iffe +Ġradi otherapy +op ausal +ĠCUR LOPT +W ish +Ġ 汽车 +ï¼Į çĨŁæĤī +ãĢģ ç͍æĪ· +UNT IME +Ġkidn apping +Ġ æ¯ı天 +åIJİ åįĬ +-m aster +åĪĿ åѦèĢħ +Ġvac ate +_ch ars +I owa +t em +ĠP AS +ĠD ome +ĠThe rapist +欧 æĸĩ +C hel +a èĤ¡ +ãĢģ 交æµģ +åħ¨ æĹł +Ġord inal +enter prise +ï¼Į 宫 +èĩªçĦ¶ ä¸įä¼ļ +ÂŃ ing +绯 éĹ» +æĿĢ æĦı +P acific +Ġopport un +æ±ī ä¸Ń +åĬŀ å®ŀäºĭ +.R aw +iter ation +ĠTE AM +G ard +ĠT Y +umin ous +Ġatt ends +æīį ç®Ĺ +sp y +mic ron +è¾ĵéĢģ æľº +Ġcatal y +为 çİĭ +å¦Ĥ çģ« +æķĻ è¯² +éĻIJ æĹ¶ +ĠEl aine +Ġreact ivity +è´ » +file ID +Block chain +纱 å¸ĥ +åı ģ +èµ· çģ« +. æĪij +_ pe +Reg ards +ĠVel ocity +Ġg oof +ĠOd yssey +ãĢģ å·¥èīº +æĹł 为 +ĠPro ceed +å¼ł å°ı +é«ĺè´¨éĩı çļĦ +un ordered +To File +ĠL ara +Ġad hering +ĠH CV +ï¼Ī ç®Ģç§° +ĠP vt +se at +æĿ¥ æıIJé«ĺ +ĠWel ch +Ġ" ~ +ç¥ŀ åĮ» +éģµ ä¹ī +èĢķ èĢĺ +åĨħ 线 +秦 å§ĭçļĩ +Max Length +Ġ ä¸ŃçļĦ +é±¼ åĦ¿ +ris y +Ġ[ & +ãĢĭ æĬ¥éģĵ +åĪĿ 审 +,ä»ĸ 说 +ï¼Į åĽŀåİ» +ĠSl ides +Ġhe mod +天 çĽĸ +Ġinter connect +æĬĺ ä¸į +< Long +ãĢģ çŁ³æ²¹ +Ġhol omorphic +_ created +un ner +( me +å¾Ģ éĩĮ +Ġhem oglobin +å½ĵ æĪIJäºĨ +åıª ç͍ +ist y +ĠK G +åĮº éķ¿ +Qu eries +ç»Ŀ对 ä¸įèĥ½ +å°¼ 西äºļ +Ġ第ä¸ī çϾ +è¿Ļ é¢Ĺ +_dir s +çĪ±åĽ½ 主ä¹ī +ä¸ªå·¥ä½ľ æĹ¥ +ä¿Ŀ ä½ij +Ġres olves +åĽ¾ èħ¾ +Ġinf init +çĽĬ å¤Ħ +.n an +åζ å®ľ +å±ķ åĮº +èι éĺŁ +å¢Ļ å£ģä¸Ĭ +el ier +èµ° é«ĺ +aff er +ç§ijæĬĢ åħ¬åı¸ +.in cludes +Ġmultip lex +ãĢĭ æĺ¯ä¸Ģ款 +Ġtur meric +\ |\ +Ġexam iner +ä¸ĸ纪 æľ« +Ġkil ograms +pl at +åıĬ åºĶç͍ +_st ructure +ï¼Įåı¯ä»¥ éĢīæĭ© +- Object +ĠBuffered Reader +æľĿ ä»ĸ +éĴ ¼ +æł¹ æ²» +uk in +ç»ĵæĿŁ ä¹ĭåIJİ +æľĢ éļ¾ +ons ense +Ġlap ar +ot i +å°Ĩ è¾¾åΰ +Ġcock pit +è¿· æģĭ +å®ŀ å¹² +空 ä¸ŃçļĦ +å±ħ 士 +label ed +UST ER +l azy +æĽ ¸ +èĩªå·± çļĦ人 +eb p +åıĮ 羸 +Â Ī +Ġ$ " +re lu +Ġan them +Ġres isted +å¾Ī æ¼Ĥ亮 +å®Ī ä¿¡ +_ > +ä¸Ń ä¸į +åĩº æģ¯ +è¡ĮåĬ¨ çļĦ +Ġsh ave +建çŃij 设计 +驱åĬ¨ è£ħç½® +壮 æ±ī +ï¼Į èħ° +ãĢĭ æĺ¯ä¸Ģéĥ¨ +· 马 +ĠDo ppler +_E P +Ġc umbersome +åĴĮ çͰ +æī£ æĬ¼ +L ng +Ġ åĢºåΏ +çļĦ å¹³åĿĩ +åľ¨ æŁIJäºĽ +nc mp +çϽ éĩij +Suggest ed +ĠBer k +Ġcrunch y +Ġï¿¥ : +^ N +ic are +æłĩå¿Ĺ æĢ§ +éĿĴ æ¢ħ +Ġinject ive +ãĤĪ ãĤĬ +西 èĴĻ +åij¨åĽ´ çļĦ人 +^ . +ãĢģ åĮħ +çľĭ ç͵影 +ie ber +æ¯Ĵ èĽĩ +éĵ¾ 表 +IZ ER +ĠCelt ics +羣 è¦ģ +Ed itable +.sp ark +ĠDrop box +ä¹Ŀ 个 +ĠPoly gon +Elig ibility +Ġent icing +èĥľ çļĦ +Ġhom estead +_AL LOC +æ±Ĥ æķij +æŀģ 强 +è° Ĵ +Ġwork manship +éľĢè¦ģ èĢĥèĻij +ãĢĤä¸Ģ ä½į +Ġexh ilar +èĩ´ è¿ľ +èIJ¥ä¸ļ æĪIJæľ¬ +ä¸įåIJĮ ç¨ĭ度çļĦ +ä¸İ åĽ½éĻħ +ern a +Ġbit ch +ĠArm or +Ġacet yl +Ġval or +确认 çļĦ +μ ο +t ub +ĠD ian +Ġpop ulous +ä¹ĺ 以 +åį«çĶŁ éĥ¨ +-k now +-mount ed +ĠE verett +Ġne b +(` ${ +âĢĿ ç³»åĪĹ +ç¢İ è£Ĥ +Ġ"- " +åģļ å¤ļ +Ġmon st +ç¦ģ éĶ¢ +) 第 +ãĢĤ è¿Ļä¸ĢçĤ¹ +ern ed +Ġrevel ations +èĩªå·± æĥ³è¦ģ +open ed +çļĦå¤ĸ 表 +ï¼Į G +ĠF eld +Ġat rial +å°± 对 +ans i +yt ically +Ġstead fast +Ġ 人çĶŁ +_T rans +æļĸ å¿ĥ +Ġtrig on +s chedule +ĠCh arm +åĽĽ åIJį +åľ£ æĹ¨ +ĠFire place +Ġreck on +çļĦä¸Ģ ä¸ĭ +Ġmar rying += FALSE +ĠF LO +ĠJ E +èĹ ī +Ġcurs ed +Ġconf erred +Sc oped +Ġadren al +ï¼Į è¯ģæĺİ +éĥ ľ +éĩį äºĨ +诺 æĸ¯ +qu s +çĪ·çĪ· 奶奶 +par r +_SE SSION +çļĦ å¹´è½» +åĪĨ éĶĢ +æ± ŀ +Ġfibrobl asts +. Arrays +M t +ce le +çĥŁ åĽ± +éĢĴ å¢ŀ +, åѦ +if ecycle +Ġv y +æµģ åħī +ĠCont ain +, çİ°åľº +ä¹ĭ 缮çļĦ +è¿ŀ å¤ľ +å·® ä»· +åĬŀåħ¬ æ¡Į +Trust ed +B enchmark +è¢ģ éĩİ +ĠFre ight +ub in +( Event +Ġdis patcher +æ£Ģ 讨 +Ġpropos itions +åıĤåĬł è¿ĩ +pot ential +Ġd ow +建çŃij å¸Ī +è¯ģåΏ æĬ¥ +çĮ¥ çIJIJ +Service Client +æµ® èºģ +Ġ åħ¬ +(d one +da o +ï¼Į身 为 +Ġnew bie +åįģ å¹´çļĦ +åĨł å¿ĥçĹħ +Ġsuff erers +ĠObs erve +rac ial +伯 伯 +ü ss +Ġincarcer ated +æŁ¥ èİ· +.w rap +çļĦ æİªæĸ½ +ä¸İ ä¼ģä¸ļ +éĽĦ ä¼Ł +if ice +åIJİ éĻ¢ +ÙĪ ÙĨ +_P ASS +ç¬Ķ éĴ± +ĠAcc uracy +åıijéĢģ åΰ +Ġв ÐĤ +éĢĤéħį åύ +harm onic +Ġtre asury +ĠCS I +Ġcommission ers +追溯 åΰ +< size +åĴĮ æµ· +å¾Īæľī è¶£ +, åĩĨå¤ĩ +Ġap nea +çϽ åħī +Ġ è¿ijæĹ¥ +Ġstand ings +ĠAnt ique +ĠKardash ian +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +è̳ ä¸Ń +å®£ä¼ł çīĩ +麻 çĸ¹ +æĺĤ è´µçļĦ +ï¼Į éĩĮéĿ¢çļĦ +âĢľ 两个 +ĠG AME +_S h +m ob +éĩij åŃIJ +å·® ä¸ĢçĤ¹ +b ler +çŃī ä¸ļåĬ¡ +ind ependent +ä¸įä¼ļ åĩºçݰ +åIJĵ åͬ +å®¶ äºĨ +ä¸ī åħĥ +.S earch +Ġparan ormal +Ġd olphins +ĠO verse +ĠCan terbury +ĠP unk +Ġsp arks +Ġover turn +åŁº ä½ĵ +Ġrock ets +Ġfont Size +Ġprogram mable +Ġunt rans +_in ner +漫 ä¸įç»ı +æļĹ éģĵ +Servlet Response +åīij æ°Ķ +ï¼Įè¿Ļ æĺ¯ä¸Ģç§į +ä¸Ń æ·»åĬł +è½´ çļĦ +çĪĨ 款 +ĠCV S +ĠNear by +ĠC ame +Ġemb races +ard own +te a +åįĩ æľ¬ +Ġ ************************************************************************ +ï¼Į 车è¾Ĩ +man ual +ĠÐ ¶ +çĶŁäº§ è¿ĩç¨ĭä¸Ń +ĠTH ANK +, åĨ³å®ļ +ï¼Į ä¿Ħç½Ĺæĸ¯ +éĢł 诣 +å®ľ æĺĮ +羣æĺ¯ 个 +çľ¼åīį è¿Ļ个 +ï¼Įè°ģ çŁ¥éģĵ +Ġel ites +_c red +è̳ æĽ¼ +ï¼Į请 ä½ł +Ġc ilantro +ä¹Ł åĪ« +_LIB RARY +Ġper ch +am eth +im os +ä¼ĺ åĮĸçļĦ +åįĥ çϾ +ĠRes p +á m +script scriptstyle +Under lying +çļĦæĦıæĢĿ æĺ¯ +amp hetamine +(c p +ä¸įçŁ¥éģĵ æĢİä¹Ī +uit ary +ob ox +.n a +, æŃ£åľ¨ +ĠM oves +ĠAr cher +åıĤè§Ĥ äºĨ +tool tip +æĿĢ æĪij +åIJ«éĩı 为 +Camp us +_c alled +åIJĮåѦ çļĦ +沪 æĮĩ +大 ä¹± +èĩªå·± è¦ģ +æ°Ķ åľ° +Ġself ie +Ġpur pos +âĢľ æĪijçļĦ +ä»ħ æĺ¯ +Ġed itable +ç²ī çļĦ +ĠCelebr ate +Ġ å®īåħ¨ +Ġc og +, 大æ¦Ĥ +è¿ĩ æĹ¥åŃIJ +ĠV G +-l iter +ĠBr illiant +alloc ated +Ġqu bit +è¯ī 说 +-man ager +ĠGather ing +èĢĮ 产çĶŁ +Ġmission aries +è° Ļ +Ġdread ful +ĠDanger ous +ï¼Į å®Ľå¦Ĥ +ĠN ass +åĴĮ åѦçĶŁ +æľ¬ å®ŀæĸ½ä¾ĭ +ĠHttp Response +ä¸Ĭ æĿ¥äºĨ +Ġsl uggish +ĠComm od +设计 äºĨ +ne os +Ġend owed +æºIJ åľ° +ä»·å̼ åĴĮ +æľīçĤ¹ åĥı +ï¼Į 纪 +ĠL one +é£ŀ 天 +ĠRel iable +\ not +zz i +å°± éĤ£ä¹Ī +è¿ĩ ä¸Ĭ +Ġi Phones +â̦â̦ ãĢį +ĠG TA +Ġche ers +人åĿĩ 纯æĶ¶åħ¥ +æĸ° æĿij +_t asks +åį¡ çī¹ +ç¦ģ ä¸įä½ı +ï¼Į æIJħæĭĮ +set Value +éĥ½ä¸į ç͍ +B IN +å°ı 鸣 +}^ * +_reg ex +Ġaccompl ishing +Ref s +ÙĪ Ø± +Ġar sen +æķ°æį® ä¼łè¾ĵ +ä¸Ĭåįĩ åΰ +ĠEll ie +ï¼Į åĭIJåľ° +ĠH LA +éĤ£ åı¥ +ĠK emp +æıIJ çĿ£ +Ġcro pped +r ising +Ġ ä¾ĭå¦Ĥ +ĠC USTOM +æĶ¯ 座 +/c pp +åħ½ åĮ» +Ġcorner stone +Ġexp orter +éĻį 级 +Ġred esigned +м а +< style +ĠMed ieval +Ġarbit rator +çļĦåľ° ä¸ĭ +as in +Ġn M +ĠT ick +ãĢģ è°ĥ +Ġcomp lying +TH READ +å¾Īå¤ļ 人çļĦ +ä¸ī çļĦ +ç§ĭ æ°´ +çľĭ ä¸įæĩĤ +使 ä¹ĭ +è¡° å¼± +æĭĵ æīij +Ġra ped +From File +å¾· åĨĽ +" -- +åºĬ ä¸ĬçļĦ +ĠDesign ing +W V +ĠAn atomy +Ġdeb ating +ãĢģ å·´ +å®ļ åŃIJ +ĠAl ps +_S ER +è´¨éĩı 管çIJĨ +é²ģ èĥ½ +hd ad +-h ard +延伸 åΰ +ï¼Į æķ¬è¯· +ĠCh ampagne +ç´§ è·Ł +è¯ļ æĮļ +Ġkill ers +éĩįéĩı 份 +, æ¸ħ +C ovid +æĬĬ æīĢæľī +æľīä»Ģä¹Ī ç͍ +Ġn ib +_TO OLTIP +F aces +_ cloud +åĴĮ é»ij +ç«ĭåĪ» å°± +Ġgran ular +ï¼Į çݯ +åľ¨ åĵªåĦ¿ +Ġk ä +æĬ«éľ² çļĦ +çŀ ¿ +ĠOS HA +å¦Ĥ æķħ +æ¥ Ń +Ġnut shell +Im Gui +以åıĬ 对 +Ġinvol untary +ç¨İ é¢Ŀ +åĩº åħ¥åı£ +add ers +arc raft +OH N +ĠGreen land +ï¼Į åĢĺèĭ¥ +ĠH ancock +ĠL NG +_b p +Ġper l +Ġ第åħ« 竳 +é¦ į +Ind iana +yl a +çļĦæĬĢæľ¯ 人åijĺ +éĢĤ ç͍çļĦ +и ÑĨ +Ġri ots +çļĦ çIJĨæĥ³ +ig ations +ä»İ ä½ķ +Ġfull er +ĠMoh amed +ä¸į åĬł +两 é¢Ĺ +èµĦäº§è´ŁåĢºè¡¨ æĹ¥ +S OC +ĠAcc ommodation +_f sm +ĠS add +Ġj ed +-m eter +èϽçĦ¶ åľ¨ +ä½Ļ å®¶ +aud it +åıĤè°ĭ éķ¿ +绿 æ°´ +ãģĿ ãĤĮ +ĠScr atch +å¿ĥ缮 ä¸Ń +Ġelong ated +次 åºı +ĠBre ed +erm ons +_p m +æĭī èIJ¨ +.D ouble +èīºæľ¯ åѦéĻ¢ +P TR +åĽĽ 次 +æĦıè¯Ĩ åΰäºĨ +ï¼Įä¸İ æŃ¤åIJĮæĹ¶ +åζåĨ· åīĤ +ï¼Įåıª ä¼ļ +ç§ijåѦ åıijå±ķ +硬 è´¨ +ç͵è¯Ŀ éĩĮ +Ġtown ship +Ġin verter +ĠWat kins +Y e +ä¸Ģ èīĺ +Ġmembers hips +ĠOt to +Ġind ifference +å¾®åįļ ä¸Ĭ +ĠA ires +and ing +ort a +è¶³ èģĶ +æķ´çIJĨ çļĦ +k ish +è¯Ħ è®® +åĨľ çī§ +ĠVer de +çļĦ çĹħ +ãĢĤ åİ» +.G oogle +Ġbra very +-form ing +L N +h ound +åıĸ çļĦ +Rel ax +é« » +ï¼ī åħ¶ä»ĸ +æĴŃ æĬ¥ +鸣 人 +éª ħ +_sh a +åĴĮ è¡Į为 +交 èģĶ +ï¼Į èįī +ĠM SD +å·¥ ä½į +ĠIm ag +Ġpow ders +çĬ¯ç½ª çļĦ +-d anger +Ġcond ens +ĠPet ition +Spec s +Ġeru ption +ĠCh arts +åįļ 大 +Ġæľ¬ åŁºéĩij +Ġв Ñģ +Ġ 康 +ä¾Ŀ éĻĦ +åĨ· æĪĺ +ĠRel ation +ynchron ization +ĠInd icator +Ġnovel ist +çļĦä¸į èī¯ +å±ķè§Ī ä¼ļ +T ek +ĠCre ed +E Z +Ġback log +are z +ph il +CS A +ĠLight weight +ï¼Įä¹ĥ èĩ³ +ä¸į çľĭ +使ç͍ æĸ¹æ³ķ +è¿ŀæİ¥ äºİ +çī©ä¸ļ åħ¬åı¸ +Ġcommem orate +. Container +ention ally +Ġdam s +æĽ´ è¿Ľä¸ĢæŃ¥ +综åIJĪ èĢĥèĻij +ä¹ĺ æ³ķ +ec ode +太 éķ¿ +约 çijŁ +é©» è¶³ +èī²å½© çļĦ +é£İ èĮĥ +ma h +ĠDry er +Ġ ç§ij +èµ· èĪŀ +ï¼Į èĭ¹æŀľ +ãĢģ å¹¶ +Ġfl ushed +.j upiter +ĠBir ch +Ġruth less +-s ocial +客 æµģ +çļĦä¸ĭ 端 +ãĢģ åIJĪ +ä¿Ŀ æľī +è£ħä¿® åħ¬åı¸ +ĠM eter +åıĹ éĺ» +P am +ãĢĤä½Ĩ ä»ĸ +ĠCert ificates +ĠG MC +Ġcritic isms +Ġencompass ing +设å¤ĩ åıĬ +æĪIJæľ¬ åĴĮ +Ġcircul ated +æİ§åζ åĴĮ +~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~ +âĢ ħ +âĢĿ 建设 +代 人 +åį´ è¯´ +ĠEX IT +ĠInv olved +Ġth yme +ch ten +aton in +ãĢĤ ä¸ĩ +å¼Ģ åĮº +èİ ħ ++ q +ĠE arnings +æĽ´ è¦ģ +çİĭ 室 +åĩº 个 +ĠCol ony +Ġsw apped +° , +Ġimp oss +ï½ Ķ +Ġ ä¼ļè®® +ï¼Į æ´¾ +åį° åº¦çļĦ +ï¼Įå°Ĩ ä»ĸ +red dit +Ġ å¸ĮæľĽ +ä¸Ģ å¹ķ +.prevent Default +ĠP es +å±ĭ éĿ¢ +çϾåĪĨ çϾ +ï¼Į åζ +åıĺ æĽ´ä¸º +æĪ¿ åŃIJéĩĮ +ĠGem ini +lib c +å¹³æĿ¿ ç͵èĦij +âĢľ æĺ¯çļĦ +ĠMot ivation +Ġem inent +Ġer otic +lic ks +亦 åı¯ +Ġfort unately +ĠSlovak ia +< Node +k owski +ĠN U +uc ose +ik it +举个 ä¾ĭåŃIJ +Ġ è£ħ +Ġd uel +Ġsm ug +ï¼Į å¨ĩ +eth nic +âĢľ 她 +æł¼ é²ģ +ĠInvestig ations +" _ +( Image +- pe +çī¹å¾ģ æĺ¯ +ä¿Ĭ æĿ° +ĠBak ery +Girl s +ĠDO ES +( init +are as +åĥı ä½ł +ĠO LED +éĩį éĢ¢ +çīµ åζ +éĩį æŀĦ +IP C +åħ·å¤ĩ äºĨ +ï¼Į åħįè´¹ +ĠM ULT +å¾Ĺ æĿ¥ +ç¾ ļ +éĵ¶è¡Į éĹ´ +Ġslides how +çĥĺå¹² æľº +-b urn +ise ase +ÑĨи и +ĠHans on +ĠM iy +ä¸Ĭ çģ« +éĢł åģĩ +ĠBritt any +Ġsc ents +é«ĺ 声 +社ä¼ļ ç»Ħç»ĩ +graph s +ĠC rescent +ï¼Į å¼ķåıij +å§ £ +åģļ 客 +Ġbuilt in +Ġsoy bean +Ġove rest +è¿ľ è¶ħ +Ġcomment ators +Cert ified +ï¼Į åĤħ +ãĢģ æķĻå¸Ī +.set Enabled +ĠWal nut +E co +éĥ½ åŁİ +f arm +çļĦ éģĵçIJĨ +Ġup keep +èµ¶ è·¯ +å͝ çĭ¬ +æĿ¥ 帮åĬ© +Net flix +ç¼ ĩ +Ġconcent rates +Ġcrow ns +- CR +> &# +_ include +li ber +**************** **** +Ġmetast ases +il ate +å®ļ æĢ§ +IGHT S +æ¶Į åĬ¨ +( store +ï¼Į åĬ© +ĠG ives +æ¡Ī çļĦ +ĠX T +ï¼Įçľ¼ ä¸ĭ +-com mercial +Ġattain able +èĤ® èĦı +Ġrep ression +ãĢģ æĺ¯ +èĩªå·± 没æľī +ï¼Įä¸Ģ ä¸ĭ +åĪº 绣 +ĠPO INT +æģ¯æģ¯ 缸åħ³ +Ġres isting +erm o +.c uda +ï¼Į å·¦æīĭ +ĠR onaldo +ï¼Įä¸į æĢķ +ĠSof a +ĠCliff ord +x on +Ġf ou +ä¸Ĭ è¯ģ +Ġ马 åħŃ +åľ° ä¸Ńæµ· +å¥ĭ åıij +ï¼Įå¹¶ æľī +-lo ving +Ġ å±±ä¸ľ +æĪIJéķ¿ ä¸º +Ġacknowled gment +ĠK ok +åĢĴ éĢĢ +è´´ å¿ĥçļĦ +ï¼Į åĽŀæĿ¥ +ĠH b +缴 ç«ĭ +Ġdup lex +d ain +è§£ æĥij +æĽ¿ 她 +,åį³ ä¾¿ +Ġqu bits +Ġman a +æĽ´ æĸ¹ä¾¿ +Ġph ishing +ç´ł æıı +å¿ĺ åį´ +Ġanalys ing +ĠO val +åľº åĨħ +ç¨ĭ å¼ı +åĩ¯ å°Ķçī¹ +, { +Ġz um +-A ss +æ½ľåľ¨ çļĦ +] =" +ĠA BA +OR IZ +Res olved +Ġgl azed +[ h +åŃĺåĤ¨ åįķåħĥ +( ...) +ãĢģ æĮī +æĹ¥ èIJ½ +_DIS PLAY +ï¼Įå°ı æĺİ +ĠMemor andum +- load +\ underline +ĠW ig +-qu al +Ġ åĩ¤ +ĠCater ing +Ġ 段 +å¦Ĥ 鼨 +ï¼Įä»İèĢĮ å®ŀçݰ +Ġmic ron +ï¼Į å¤Ħäºİ +"> # +Ġspectrom etry +T odd +ĠS lam +è¿Ļ éĥ¨åĪĨ +CHO OL +W ere +j t +æī¿æĭħ çļĦ +Ġ ä½į +ï¼Į æĭĽ +ï¼Ł å½ĵçĦ¶ +å¹³ åľ° +æł¡ å¤ĸ +ï¼Įå°±æĺ¯ åĽłä¸º +ï¼ĮéĻįä½İ äºĨ +âĪ Ĺ +æŃ£ è§Ĩ +ãĢĤå®ĥ æĺ¯ +_P CM +è§īå¾Ĺ æľīäºĽ +åį´ æľī +CL ICK +ภ« +des erialize +Ġalloc ator +[ start +N OS +_p y +me et +(m em +Ġenc odes +std err +ĠAlbu querque +âĢĿ åΰ +èĨ³é£Ł 纤维 +ĠB orders +ĠAl gorithms +-C D +Ġmother board +-out s +åĬłå¤§ 对 +ãĢģ è¿Ľ +ĠL ies +ĠWater loo +C OME +J UST +Ġover p +ï¼Įæĺ¯ æĪij们 +Can onical +ĠFig s +, 带 +ðŁ İ +. When +Ġmid i +å¿ı æĤĶ +M ate +int ed +Ġreg rett +Ġsys call +, 以åīį +: } +Ġ ÙĬ +ï¼ļ æŃ¤ +Ġcan oe +ä»· å»ī +Ad j +ĠDep artments +Ġro asting +Ġinspect ors +Ġc udd +ĠM oms +ĠR eward +ĠJon as +Ġscram bled +/ id +an onymous +æĪij åıijçݰ +ä¸ŃåĽ½ å¸Ĥåľº +z ar +ï¼Į åģļåĩº +Ġsu fficiency +ath om +ix er +ï¼Įå¦Ĥæŀľ ä»ĸ +Ġinconven ient +_ accept +or c +çļĦ æĶ¹åıĺ +.t ile +M oh +ĠU AV +-t ools +Ġ 以åīį +ĠT ir +Ġsm oker +Ġhost ility +SE Q +ä¸įåIJĮ äºĨ +Re placement +ï¼Į æ±Łèĭı +ĠN X +ĠH OST +好 åı¤ +Ġout age +_N o +带çĿĢ ä¸Ģä¸Ŀ +沿 岸 +æĬĢèĥ½ åĴĮ +çĶŁæĪIJ ä¸Ģ个 +å¹¿æ³Ľ ç͍äºİ +ï¼Įåīį å¾Ģ +èĤĩ äºĭ +Ġwood land +/ ref +åĽ´ å·¾ +Ġher pes +Ġhairst yle +L imits +Ġun ch +éĩij åįİ +/s chema +Fun ny +: add +çϾ å®ĺ +éĢģ èĩ³ +ĠExper iments +Ġst ent +.c ap +åħ» çĮª +net te +ĠNe on +m ute +Ġact uator +ï¼Į åĵŃ +å®ģ åı¯ +大 便 +PR S +Ġdesert ed +ĠHe ater +ãĤ º +ï¼ĮåħĪ æĺ¯ +ï¼Įä»Ĭ åIJİ +p ard +ä¸Ń æıIJåıĸ +ãĢĤ 许 +ĠDes ire +ĠCost co +Ạ£ +ĠZ ucker +ï¼Įæľī ä¸Ģç§į +ĠSch ro +Ġê ² +F x +l uck +éĿ¢ éĿ¢çĽ¸è§ij +éĢļ æ°Ķ +Ġdef init +-M en +è§£éĩĬ 说 +_ nt +Ġover b +Ġequ ities +ĠRes pir +.n lm +/ product +_m ail +å¾® ä¸įè¶³ +ï¼Į没 äºĭ +Ġban quet +ĠEd win +Ġintrig ue +ĠMead ow +å¹´ å¹¼ +Ġche esy +Be am +ठ² +æĮģç»Ń æĹ¶éĹ´ +Ġp iled +oss a +缣 主 +æĪij çŃī +ä¿ ª +Ġpar cels +çŃĭ 骨 +F acts +åĺŁ åĽĶ +Ġfl ashed +æģ© æĿ¥ +\ Entity +交æĺĵ å¹³åı° +Ġ æĺŁ +ĠN GC +é² « +汤 åĮĻ +ä½łä»¬ 两个 +ad ge +ĠK um +身ä½ĵ ç´łè´¨ +æijĬ ä½į +" As +å°ı å±± +æľĢ 容æĺĵ +æķ¢ 说 +utter stock +O w +is man +ï¼Į æĥ¹ +å¤į 审 +(t ab +åĴĸåķ¡ åİħ +以å¾Ģ çļĦ +ĠP SP +马 èĻİ +ĠAD V +åĴĮ 她çļĦ +Ġë ĭ +, åĪ«äºº +IC ODE +er ic +åĨĻ æĪIJ +Ġindividual ity +èѦ 车 +ros ophila +ãĢģ 带 +åĩº èµ° +éļ¾ äºĭ +ï¼Į çĶļ +Ġbar code +ĠPass enger +ĠM é +pe re +e ated +ol ina +ĠA O +bb bb +SC O +ĠD ive +æĪij å¿ĥéĩĮ +Ġimpecc able +Ġass orted +Ġα ÏħÏĦ +-second ary +æĬĢæľ¯ éĹ®é¢ĺ +aj an +大éĻĨ çļĦ +Ġcontrad icts +ãĢģ éĻįä½İ +æĿ¥ çļĦæĹ¶åĢĻ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +æĺ¾ çľ¼ +V ox +Ġf rowned +åѦ åºľ +åİ» æĢĿèĢĥ +被 认为 +Ġins isting +éĤ» éĩĮ +Ġvo ic +Ġtors ion +纹 è·¯ +éħįç½® çļĦ +Ġfresh ness +C XX +S equ +éķ¿ ä¸īè§Ĵ +åĶ¿ åºĶ +ðŁ ĵ +ĠÏĥ ÏĦη +ud it +ĠL SU +éģ¿ éļ¾ +çĮ ĸ +_R AW +Ġbus iest +```` `` +pport unity +_r w +åĩĮ ä¹± +åĸ· æ³ī +åĨħå¿ĥ æ·±å¤Ħ +交 ç»ĻæĪij +éļĶ èĨľ +,ä¸Ģ æĸ¹éĿ¢ +Ġlink er +ĠMongo DB +C oding +åĪĨ éĥ¨ +imes ter +è´¸ çĦ¶ +ĠTable ts +Ġiv ory +E cho +ĠX D +æ¯Ķ 她 +éĢļè¿ĩ çļĦ +Art ificial +-Sh irt +ãĢĤ åĬłå¼º +oss ed +Ġmodel Builder +åıĺ å°ı +å¿§ æĦģ += float +IT ICAL +ĠObject ives +Real m +- ing +Ġartific ially +ï¼Į æĦ¿æĦı +Ġin accessible +_C B +åĬłå·¥ çļĦ +, æĪĸæĺ¯ +Ġun noticed +åĩºçĶŁ åľ° +igraph y +V ISION +ĠK ob +èIJ ¼ +åºŃ 审 +ĠE velyn +æĪĸå¤ļ æĪĸå°ij +Ġmod ality +åĩī äºĨ +Ġj ag +è·¯ åĨĽ +Ġorder ly +ĠPres erve +æĮģç»Ń æĢ§ +ä¼łè¯´ ä¸Ń +Ġpharmac ological +Grad uate +.define Property +åłĤ çļĦ +æľīä»Ģä¹Ī 好 +Ġbright en +ãĢģ èIJ¥åħ» +âĢľ 红 +ong a +иÑĩе Ñģк +å°ı æīĭ +Ġamb iance +åģ ķ +èī² æĸij +- et +yt ime +Ġson ic +ĠMo vers +æħĮ äºĨ +ĠTob y +ĠH ive +åı° éĿ¢ +Ġcent imeters +') ( +ä¼łéĢĴ æĽ´å¤ļä¿¡æģ¯ +co verage +ĠTrans parency +ç¾ŀ æĦ§ +ï¼ĮéϤ æŃ¤ä¹ĭå¤ĸ +nd e +èĥ¡ æĢĿä¹± +æĺ¯ ä¸įåIJĮçļĦ +éĥ½æľī åĵªäºĽ +ä¸įç͍ äºĨ +_initial izer +微信 群 +ĠPan els +C pp +ĠR CT +çͳ é¢Ĩ +big cup +Ġsan itary +æ°¢ æ°Ķ +åıĪ æĬĬ +å¿ĥ çľ¼ +æ±Ĥ åĩº +æĭĴ ä¸į +opens ource +res ume +åľĨ çĽĺ +ĠWall paper +Ġbust ling +âĺħâĺħ âĺħâĺħ +Ġ è¾ĵåħ¥ +ĠI J +çķĮ 线 +ĠComp ass +Ġsumm ons +侯 çĪ· +W OW +ep id +ãĤ¤ ãĥ« +-b oot +æŁIJ çͲ +ĠConstruct s +Ġnational ism +/ sec +A çļĦ +ke it +ï¼Į å±ķ +ĠON LINE +/ show +Ġ åıįæŃ£ +imp lemented +æīĺ ç¦ı +-c an +-c lose +çļĦå°ı å§ijå¨ĺ +ä¸į åıª +åħį éϤ +Ġsubt itles +Ġfle a +ï¼Į æī¿æĭħ +ĠQu ilt +éħ¸ çĶľ +ä¹Łæĺ¯ä¸Ģ æł· +y ms +æīĵ æĬĺ +_ ajax +g uns +ï¼Ī åİŁ +å¾· çͲ +CH R +ãĢĤ 女 +è¿ŀæİ¥ 管 +N am +ere otype +ĠPay day +åįıè®® 书 +ï¼Įæµ· æĭĶ +åĨħ容çļĦ 羣å®ŀæĢ§ +ï¼Į é²ľ +è¿ĩ åįĬ +_C heck +ĠGr anted +ä¸Ĭ æ¦ľ +ub i +app lic +ä¹Ł åĴĮ +åħ¬ æĬ¥ +at itis +æĪij们 çŁ¥éģĵ +Ġspark le +Lux ury +ç͵ çĥŃ +æİ¨ éŨ +äºij éĽĨ +ĠC YP +大 åŃĹ +缴 è§Ĵ +ï¼ĮæĪij 没 +ä¸Ģèά æĥħåĨµä¸ĭ +ĠI p +ends With +ĠTom ato +éĵ° éĵ¾ +ãĢģ å¿« +æķĻåѦ ä¸Ń +Ġwal nut +Ġreplic as +ãĢĤ ä¸ĥ +Ġla uncher +, æĺ¯ä¸Ģ个 +Blog This +ä¹Ł å¤ļ +ä¸İ æĿİ +两 éĺŁ +æķ£ å¼Ģ +ĠSun rise +âĢľä¸Ģ 带ä¸Ģè·¯ +evol ent +Be acon +( by +ĠS RC +æĺ¯ ä¸Ń +.c sdn +ĠReg iment +Ġchem ically +ĠE leanor +çİ ij +è¿ľ 举 +çķĻ æģĭ +C ann +ĠH ID +ert a +ĠRa ises +. Validate +æīĵ å®Į +åģı é«ĺ +ate urs +user content +å·¥ä¸ļ åĽŃ +Ġflash light +ĠAtt achment +, åĪļ +æį® çĤ¹ +Ġsign up +æŃ£å¸¸ æĥħåĨµä¸ĭ +_dec ay +ĠG ould +_b ounds +fin ally +-pro gram +Ġse rene +plic as +O t +常 说 +AN AN +Ġbal m +éĢĬ èī² +颤æĬĸ çĿĢ +度 è¿ĩäºĨ +.m aterial +ï¼Įä½ł è¦ģæĺ¯ +ĠShe ikh +l ue +oc able +_ resp +Ġg ag +Ġif rame +ĠCh r +ĠNo el +Ġk y +èĢĮ 论 +åľ°çľĭçĿĢ ä»ĸ +æį ĭ +ĠRound up +åĿIJæłĩ ç³» +ĠDialog ue +-m ar +éģ İ +ï¼ĮéĤ£ è¾¹ +æ³ ¯ +In novation +PH Y +gester one +æľĪ å¼Ģå§ĭ +åģľ äº§ +\ > +o L +çļĦ 迹象 +ĠC IS +å¹´ èĢģ +éŁ³ 符 +_RO W +w allet +ä¸ŃåĽ½ æĸĩåĮĸ +æŃ£å¼ı å¼Ģå§ĭ +_AL LOW +æĶ» åħĭ +v art +ï¼Įåħ¨ ä½ĵ +Ġ æ·»åĬł +Ġun ilateral +éĢīæĭ© é¢ĺ +erial ized +ĠTel escope +è¾ į +_b lob +ç«Ļ åı° +åİĨ æĿ¥ +Ġimpl anted +Ġsmooth ie +ĠBas el +ĠFL AG +æħķå°¼ é»ij +æijĨ çĿĢ +åĽ½ è¯Ń +Ġ é¦Ļ港 +Ġmon astery +there fore +ĠPoss ibly +t ear +åįĹ æŀģ +Ap ache +Ġcra ppy +ĠK anye +' all +Ġeffect ed +满 åľ° +å®ŀéĻħ æĵįä½ľ +Ġrod ents +U CTION +çļĦ å§¿åĬ¿ +Ġd oping +) ((( +ä¹ī ä¹Į +.set Color +æķ£ å¸ĥ +I W +æĥ Ĩ +æĹłæ³ķ åΤæĸŃ +ĠFort y +(null ptr +ï¼Į åĪĨåĪ«ä¸º +ied er +_s eries +ä¸ĵ åζ +åİĭ ä¸ĭ +纳 å°Ķ +ä¸Ĭå¸Ĥ åħ¬åı¸çļĦ +Ġdump sters +ï¼Įä¿Ŀè¯ģ äºĨ +æŁ Ĵ +两 æł· +_INTER VAL +ĠKos ovo +æĭ ´ +Ġrel atable +ĠAd oles +an ova +åıĮ èĥŀèĥİ +ĠYork er +çĽ¸å¯¹ åºĶ +èĪį 人 +åıĤæķ° çļĦ +æ»ŀ åIJİ +æĺ¯ ä¼ģä¸ļ +yst ers +ç»´æĮģ åľ¨ +PM I +ï¼Ľ åĽĽ +红 èĤ¿ +æģį çĦ¶ +Ser iously +ĠInf ection +éĿŀ ç»ı常æĢ§æįŁçĽĬ +åĪ» 度 +Ġmel odies +flat ten +z man +Ġ"" ; +Ġvill ains +ĠLat via +Ġuns ur +ĠDyn asty +Ġ ä¿¡ +çł ¾ +.t mp +åĵª 天 +æł¼ å¤ĸçļĦ +æĹ¢ èĥ½ +as ource +认 éĶĻ +_P M +没æľī éĤ£ä¹Ī +åįķ æµĭ +P ets +ad u +.c pu +ĠZ ambia +yy y +$ d +æĢ» è¦ģ +éªij 车 +æį¡ èµ· +.nav igation +Ġcyn ical +Ġ ä»Ģä¹Īæĺ¯ +ĠM argin +ĠEx act +çģĮ è£ħ +æŃ¦ æĺĮ +æĸ¹æ¡Ī çļĦ +.dis able +$ ^ +å°½ æĺ¯ +Ġsw amp +ä¸Ģ éĥİ +ff e +ik t +-m ort +Ġassert NotNull +G reek +å°Ĩ 缮åħī +Ġsa ver +åľ¨ 欧洲 +é»ij 马 +ĠRec ap +å¾Ī好 å¥ĩ +æ²¾ æŁĵ +é¢Ķ é¦ĸ +çĶŁ åĬ¨çļĦ +Ġpre natal +åħ³ ä¸Ń +Ġmod ulate +Ġrefund ed +ï¼Į æľĿå»· +Ġs per +ï¼Į çĶŁåij½ +éĿŀ æµģåĬ¨èµĦ产 +Ġsuggest ive +ĠPeg gy +ĠE ck +æĶ¶ 容 +(m ake +ĠSoci ology +$ ^{ +ex cluding +ĠCh unk +宦 å®ĺ +ï¼Į èĢĥèĻij +_f alse +ä¸ĸçķĮ 第ä¸Ģ +News letters +Ġresear ches +Ġto l +Ġcons pic +ç쵿´» çļĦ +Ġ å±ıå¹ķ +ĠÐ Ķ +LECT ION +ĠG ithub +å¹´ åĩºçĶŁ +è¿Ļ个 äºĭæĥħ +æĻ¯ çī© +ï¼Į èģĶåIJĪ +å®ī çŁ³ +æŁ¥ åΰ +D iversity +ï¼Į ç®Ģç§° +Ġm ime +Ġ å°±åĥı +_m any +ĠSil ence +ï¼Į è¶ĬæĿ¥è¶Ĭå¤ļçļĦ +D un +ess ay +ĠBy z +çĹ´ è¿· +i ander +äºĨä¸Ģ èĤ¡ +æĺ¯ä¸Ģ éŨ +ï¼ĮåĨį 说 +DE ST +, åĩºçݰ +ĠA ED +ĠæĪij åĽ½ +æľĢ åŁºæľ¬çļĦ +å¦Ĥä½ķ 使ç͍ +åį± æľºçļĦ +Ġcontrad ict +. Visible +ï¼Įä»ĸ们 éĥ½ +ï½ŀ âĢĿ +ĠFather s +( gen +çļĦ çļĦ +é£İ éģĵ +ä½Ļ çĶŁ +æİª æīĭ +滨 æ±Ł +ä¸Ĭ æĸ¹çļĦ +çŃī çݰ象 +ï¼Į äºĮåįģ +Ġble ak +æīĶ åΰ +ï ve +ç± ģ +æľīä»Ģä¹Ī åĮºåĪ« +plac ian +éĤ£ 群 +漫 漫 +ĠCam eroon +人æĢ§ åĮĸ +Ġpoore st +è¿Ļ åŃ©åŃIJ +' é +ä¸Ģ åĢį +Ġ( {\ +Ġdep iction +æīĢæľī çļĦ人 +ĠST DMETHOD +Play back +åŁİ乡 å±ħæ°ij +Ġ 纪 +åľ¨ 举 +大 èĤĨ +ĠOl son +ï¼ĮæĹ¥ åIJİ +交 åī² +çĶŁæ´» åĴĮ +ĠComp ile +æ°¸ ç£ģ +Inf inity +æ±¹ æ±¹ +m ovie +ä¹Ł åıª +hib it +, string +大 çīĮ +ek a +Ġcounter top +Õ ¡ +ĠSt o +大å°ı å°ıçļĦ +æ¸Ķ æ°ij +ĠEli jah +C re +设置 äºİæīĢè¿° +Ġconvolut ional +% / +æĢ§ éĹ®é¢ĺ +v ascular +Ġ ä¸ļ +表示 æĦŁè°¢ +ĠOs lo +Ġtrib unal +ï¼Į åįĹ京 +Sp aces +鸡 èħ¿ +ãĢģ åĭ¤ +ĠâĢ » +åºľ ä¸Ń +Mag azine +æŃ£ å®Ĺ +ï¼Įä½ł 以为 +ï¼Įå¹¶ çͱ +è°ĭ æ±Ĥ +èĭ±éĽĦ èģĶ缣 +, å¿« +åĨħ èħĶ +ä¸Ģèµ· åIJĥ +ï¼Įåħ¶ä»ĸ çļĦ +ocaly ptic +Ġ åĨħ容ç®Ģä»ĭ +_r gb +execut ion +æİ¥è§¦ çļĦ +sem ary +ĠParticip ant +.get Parent +RO I +ĠJo ined +Ġincompet ent +Ġ ç͵åŃIJ +å¾Ĺ éĿŀ常 +ĠFl ush +Ġword en +æĹĹ è¢į +in p +ĠH uss +çľĭåľ¨ çľ¼éĩĮ +em is +Ġtor us +çĦĬ ç¼Ŀ +/ media +e ce +j q +æ¿ ij +-pro duced +_v irtual +.s ymbol +ĠZ ERO +(d t +ĠFIG S +Ġselect ivity +. Values +âĢĿ åıĬ +èĩª 以为 +_t opic +ãĢĤ ä¹Łæĺ¯ +æľī å¾ħ +ä¿¡æģ¯ å®īåħ¨ +ĠCharg ing +ç͍ ä¸įçĿĢ +å®ŀ æĵį +.m ask +eb u +è¿ĺæľī 人 +ãĢģ å¦Ĥ +IC LES +Other wise +è´¹ çŃī +åıĺ æļĸ +ĠMoh ammad +Ġutens ils +Ġp ussy +ĠSpons ors +Ġco vert +太 è¿ľ +缸åħ³ èµĦæĸĻ +ed x +>( < +Ġscore r +ĠProm ote +Ġtur quoise +ĠBe coming +åıijå¸ĥ æĹ¶éĹ´ +对 åѦçĶŁ +æµģ è¨Ģ +åģľä¸ĭ èĦļæŃ¥ +.Acc ount +ĠB atter +ach inery +ĠX M +ï¼ĮåıĪ è¦ģ +ï¼Į 害 +Ġd ads +ap ur +西 å¤ı +çİ°åľ¨ å¼Ģå§ĭ +ĠOrd inary +Ġrall ies +ĠW ines +æĪĸ æľįåĬ¡ +åIJĦç§į åIJĦæł· +Ġfaith fully +_BO OT +ï¼Į æĮģ +ĠSt retch +ĠPo ison +ĠA ffect +åħ¶ è§ĤçĤ¹ +According ly +ĠTrack s +Ġco ales +ĠRun s +Ġtou red +ä¸ĺ éϵ +è¿ĩ 她 +Ġstar vation +ãģĽ ãĤĵ +_dec oder +ãĢĤ ä½įäºİ +Ġgen ital +çīĽ çļĦ +ãĢĤ ç͍æĪ· +Ġbapt ized +A rena +Ġhero ine +Ñ ĺ +ĠY ep +è¾ĵ æ¶² +éĿ¢å¯¹ çļĦ +L aser +g reens +èĦļ è¸Ŀ +Ġassault ed +b art +Ġd odge +pass ed +] [] +Ġro am +两个 æĸ¹éĿ¢ ++ H +< Q +ĠThis BlogThis +κ B +顾客 çļĦ +丽èİİ çϽ +/ init +own ership +ä¸įæĸŃ æī©å¤§ +æħĪ ç¦§ +Ñħ од +Ġadvers arial +Ġfatal ities +æĺ¯ä¸Ģ åī¯ +.f eatures +Ġnight time +ï¼Į天 åľ° +.Group Layout +ĠæĽ´å¤ļ åĽ¾åĨĮ +ï¼Į åĪĽå»º +ç»Ŀ éĿŀ +Ġcur ator +æĿ¯ éħĴ +Ġmur ine +å¿ » +ĠDist inguished +ç²¾ æ°Ķ +ĠGen re +Ġ'- ' +Ġwors ening +D igits +L AG +.l in +ĠCam eras +Ġjeopard y +ãĢĤ åŃIJ +å°ı说 åľ¨çº¿éĺħ读 +åĭĺ æŁ¥ +æĦı æ°Ķ +ĠRe levant +ĠACC ESS +ĠFe ather +è¡Ĺéģĵ ä¸Ĭ +çļ±äºĨ çļ±çľī +/ set +N AT +ĠD ug +ĠComp ression +Ġfort ress +ç§ijçłĶ æĪIJæŀľ +å¿ĥ çαçļĦ +ä¹° çĤ¹ +æįı çĿĢ +Ġo missions +çļĦ çĹķ迹 +è·ij è¿ĩæĿ¥ +åĨ¬ èĩ³ +ĠOb tain +Ġar b +ash ions +(s z +Iter able +é«ĺ éĽħ +æ¹ĸ çķĶ +éķ¿æ²Ļ å¸Ĥ +ĠDal ton +Ġcon duit +Ġ å¹² +åĿĩ æĺ¯ +(n ames +对 å®ĥ +æĥ³è±¡ ä¸Ń +ĠETF s +Ġoverrid ing +- yl +ef e +æĹħ游 æĻ¯åĮº +éķĩ å®Ī +_SE Q +ãĢĤ 人çĶŁ +ĠUn expected +åĨĻ åΰ +åĪºæ¿Ģ çļĦ +FILE S +ãĢĤ ä¹ĥ +Ġconve ys +us o +erm is +_dis abled +Ġspr outs +Ġdis place +åľ¨ ä¸Ģè¾¹ +. Protocol +(ch unk +SV G +Ġha iled +è¿ŀ 绵 +ĉĉĉĉĉĉĉĉ ĉĉĉĉĉĉĉĉ +åIJĦ å®¶ +Jam ie +_ String +b uds +大 å·´ +ib bon +骨 åŃIJéĩĮ +éģĵè·¯ 交éĢļ +ĠAl ter +Ġ åºĶæĶ¶ +åŁİ 建 +ï¼Į身 æĿIJ +ãĢĤåıª è§ģ +E gypt +ï¼Ľ ä½Ĩæĺ¯ +arg ed +ä¸ī éĥ¨ +-b rand +çĴ Ł +Ġz o +CON ST +ãĢģæ°´ æŀľ +ï¼Į好 ä¸į容æĺĵ +an imated +Ġan arch +ĠL arger +ĠP ia +Âł B +è¦ģ ä½ł +åı¹ ä¸Ģ声 +ï¼Į åįİ为 +GT K +( angle +- java +ĠBo ise +åįĥä¸ĩ ä¸įèĥ½ +Ġworld view +ĠSe en +ï¼Į æĪIJ绩 +ä¸į éĹ´æĸŃ +è¡Ģ ä¸Ŀ +çĽ¸ä¿¡ æĪij +æįķ é±¼ +ĠStev enson +ĠCoc oa +( 约 +ĠI brahim +ĠA GA +C ipher +ãĢģ åħ± +顺åĪ© è¿Ľè¡Į +éĤ£ ä¸Ģ天 +æĶ» çł´ +_comp lex +ĠP reference +å¤ļ åľ° +Ph rase +Ġstar ving +ãĢĤ å·²ç»ı +cyl inder +çŃī åIJĦç±» +ä¼ĺ åĬ£ +Ġsin ister +PRO DUCT +Ġillum inate +·· · +Ġ èij£ +Ġ ä¸įçŁ¥ +éĤ£ å°ı +ãĢģ R +Ġsp ared +çŁ³ åŃIJ +ĠCo ke +Ġ æłĩåĩĨ +ĠP att +ãĢģ åIJĪçIJĨ +b ru +l und +èĥ¤ ç¦ +Ġpriorit izing +Ġ 使 +å¹´è½» æĹ¶ +ĠJul ius +Ġqu ench +ival ence +, åıįæŃ£ +Ġis Valid +太 强 +Mutable Dictionary +Ġhover ing +Ġin et +Un ivers +å¾Ī好 çľĭ +è®°å¿Ĩ ä¸Ń +ĠBra ke +Ġadmitted ly +In verse +æľ¬èº« å°± +Ġg erman +èģĶ è½´ +éĽ¾ éľ¾ +Ġem blem +C HE +ä¹Ł åºĶ +---------------------------------------------------------------- ------ +.m ouse +Tom orrow +Ġu it +ä¸ĵä¸ļ ä»İäºĭ +ĠDon ovan +ĠNor ris +οÏħ ν +ĠHoo ver +doctor al +ãĢģ 绣ä¸Ģ +_co ord +hes ians +ĠH eg +ac id +sp ark +æĪ¿ ä¸Ń +_P WR +il ated +Ġconsequ ential +æĸĩæĺİ åŁİå¸Ĥ +ĠDick inson +Ġk ios +DECL ARE +嫦 娥 +s x +èᝠåѦ +sk ins +âĢĿ ï¼ģ +æĪIJ é¾Ļ +oc ent +Ġdel ights +Ġl int +Ġra pt +Ġion ization +ä¸į èĢģ +Ġhard ships +Equ ality +åĨ° åĨ» +åħįçĸ« ç³»ç»Ł +Ġ, \ +Des criptors +an ax +ore station +æĪij 为 +åĪĽæĸ° èĥ½åĬĽ +æ½ľ å¿ĥ +ĠS es +Ġpl ight +Ġoff ences +ACC ESS +Ġpatri ot +ï¼Į åĮĹ京å¸Ĥ +ĠL amar +è½»æĿ¾ åľ° +æĪĸ许 æĺ¯ +èĥŃ èĦĤ +ook ies +_ID LE +Cur r +çķľ çĶŁ +Ġ åĨħ容 +ĠB ravo +ĠV es +ĠCom cast +-d evice +大家 æĹı +åºĬ ä½į +à ĸ +å¹´ ä»» +åİĭ ä½İ +Ġs izable +ãĢģ èͬèıľ +åĨī åĨī +è°ģ çŁ¥éģĵ +/d etails +, 第äºĮ +ç»ĵæŀĦ ä½ıæĪ¿ +éļIJ å±ħ +.se lection +. actions +: F +ĠA AC +æµ® éĽķ +ĠLock smith +å°Ħ ç¨ĭ +ĠLeg islation +ĠSpeed way +ĠSt ur +æ²Ļ åĵij +æĥ¨ çϽ +Ġk ittens +æĦı 象 +.N ormal +ã ij +ĠT EM +Def s +æĻºèĥ½ åζéĢł +åľ° æııè¿° +Ġmilit ants +u et +Ġquant ization +ä¸įä»ħ èĥ½ +ĠRad ar +-v irus +ĠDomin ic +çĭ¬ è¡Į +ĠHD L +ĠMight y +ï¼Įä½Ĩ 没æľī +.f low +ĠPil gr +Ġhurd le +' < +å·¥ 人çļĦ +åħ¶ä»ĸ åĽ½å®¶ +ĠAN SW +Ġa ck +ä¸Ĭ 书 +ĠTr ick +æĬ¢ åįł +ä¸Ģ 棵 +使ç͍ çļĦæĺ¯ +æŃĩ å°Ķ +ĠSUP ER +çļĦ è¿IJè¡Į +ef ully +æĹł è¯Ŀ +ãĢģ æ²³åĮĹ +.R ev +Of Type +ureth ane +Ġ** ( +p rior +Ġ 计ç®Ĺ +ãĢĤ æĽ¾ç»ı +符åIJĪ é¢ĺæĦı +åİĮ çĥ¦ +å¾Īéķ¿ ä¸Ģ段æĹ¶éĹ´ +- angle +: true +r st +f light +.t imestamp +++ . +æĦŁåΰ éĿŀ常 +ĠHig gins +æ´Ĺ åıij +Be ck +åħ¨ä½ĵ æĪIJåijĺ +er obic +ĠF alk +ĠE rl +é¢ į +æ¿Ģ æĪĺ +ç§»åĬ¨ åΰ +λ α +ĠNik ki +P riv +ĠL AST +å¸Ī å¾· +,ä¸į å¦Ĥ +姨 å¦Ī +äºİ äºĭ +Ġdis may +ĠPil ates +Ġsurre ndered +ä¸Ģ å·´æİĮ +æ²³ åı£ +_G LOBAL +å¤ļå°ij 次 +ê s +Rec ipes +Ġblu etooth +Ġh umming +é¥ ¬ +ĠInd ies +ĠRep airs +ä¹İä¹İ çļĦ +} ~ +Ġmechan ically +æĻĵ æĺİ +åħļé£İ å»īæĶ¿ +ï¼Į åı¦ä¸Ģ端 +ï¼ĮçŃī æĪij +çĶĺ èĶĹ +èįĴ è°¬ +ãĢĤ æ³ķå®ļ代表人 +è½» çļĦ +Ġkind le +.on Create +d aily +ure en +ãĢĭ 以 +ĠByte Buffer +, åŁ¹åħ» +éģµ çħ§ +Bro ken +ä¼Łå¤§ å¤įåħ´ +ID GE +eterm inate +ĠS AY +æĶ¶ éĵ¶ +æľ¨ å±ĭ +( Required +Prot ected +Ġtrump et +Ġb ac +ãĢģ æĸ¹ +ĠDet ox +-re view +ĠX Y +åı¹ åı£æ°Ķ +ãĢģ 管 +Ġde ceptive +." . +.add Action +A ux +t ow +ĠShe ep +羣çļĦ åIJĹ +ãĢĤéĤ£ æĹ¶åĢĻ +ï¼ĮåIJĦ åľ° +è¿Ľç¨ĭ ä¸Ń +ĠL HC +ä¸ĭ å¿ĥæĿ¥ +ï¼Įä¸Ģ ä¼ļ +tr fs +ĠSh apes +çĽĨ æł½ +ax i +_H AVE +. ST +Ġs é +ãĢĤ 车 +ç»ı åıĹ +Jul ia +ĠOw l +ï¼Ī æľīéĻIJåIJĪä¼Ļ +å°ģ åłµ +_arg uments +ï¼Į éĽħ +ĠIm mediate +Ġrev ived +ĠD ante +Est imated +) // +, ä¹ĭåīį +J erry +çļĦ åĮ»çĸĹ +Ġ 忽çĦ¶ +Ġbr ute +é¢ł ç°¸ +ĠNeck lace +è¦ģ 大 +ĠPh ar +Ġbureauc racy +æĺ¯ åħ¨ +é£Łåĵģ èį¯åĵģ +ĠC ups +å°Ĩ ä½ł +(d ict +纳 ç²¹ +ĠGen es +ĠB av +èĢģ äºĮ +.d et +èµ·æĿ¥ åIJ§ +çĶŁäº§ èĥ½åĬĽ +çĶ³è¯· 书 +ĠEnd s +-op ening +et ra +æľī害 çī©è´¨ +éķ¿ åŃĻ +读 å®Į +åıijçĶŁ éĩį大 +æ·¡æ·¡ ä¸Ģç¬ij +ï¼Ľ å¦Ĥ +èµĽ åľºä¸Ĭ +è¿Ł éĴĿ +document ation +gra ve +oret ic +Ġacquaint ance +è¯Ŀ åī§ +Ġn ginx +å¹´ éĩĮ +ä¸Ģ éĹ® +åĴĮ åĨħ +æĢ» ç®Ĺæĺ¯ +ä¸įè¡Į äºĨ +ä¸ĵ项 è¡ĮåĬ¨ +ä»ĸ å®¶ +åĨį åĬł +Ġheart breaking +Ġbo ils +Ġund eniable +èµ· åIJį +ĠFor giveness +ĠTe ens +Ġacqu ires +Ġsnow y +Ġorient ations +ĠU IColor +åħ¨çIJĥ ç»ıæµİ +Ġmurd erer +.setOn ClickListener +ĠCol oring +-c overed +讲 åłĤ +ï¼Į å®īæİĴ +æłĩ 示 +åį¡ å¡Ķå°Ķ +App oint +Ke ith +计 çĶŁ +H ill +ĠOwn ership +ä¸Ģ缴 没 +Ġhom osexuality +ï¼Įåį´ åľ¨ +Ġprov ocative +Ġaut istic +æĸ°åĨł çĸ«æĥħ +ï¼Į çϽçĻľé£İ +ï¼Į åĵ¥åĵ¥ +air a +éĻIJ åħ¬åı¸ +.h ave +两个 åŃ©åŃIJ +çŁŃ çīĩ +Ġment orship +ĠØ ´ +èİ«åIJįåħ¶ å¦ĻçļĦ +, ä¿Ŀéļľ +{ pro +Ġev iction +Ġinc ision +ĠCU DA +oc ations +( pp +ä¸Ń éĶĭ +天 å±± +Ġex e +Ġmo ons +Ġtwe aks +ĠDeuts che +( tt +w aves +ĠC off +æĸŁ éħĮ +Ġporn ography +pl anned +/ All +åħ³ æĿij +人çļĦ æĦŁè§ī +ĠST A +pop up +æĹłæĦı éĹ´ +ãĢĤ çĪ¶äº² +ĠAr range +Ġvict orious +D ad +H at +ad ies +æĸŃ éĿ¢ +æ³¥ æµĨ +Ġunfore seen +åĽ½å®¶ éĩįçĤ¹ +æĴŀ åΰ +Ġisot ropic +çļĦ æĬĢå·§ +åıĹ ä½ĵ +Ġjud iciary +Ġsp anned +Ġent rusted +æ³° åĿ¦ +åĿIJåľ¨ éĤ£éĩĮ +ä¸İ æ°´ +ĠCharg er +Ġg d +å°Ĩ æŃ¤ +èĤł çĻĮ +夸 大 +@ n +à ľ +é»Ħ æ²¹ +idd y +æıIJ çݰ +çİĭ å°ı +· å·´ +åľ° åıijçݰ +å°Ĩ è¿Ļ个 +_ On +ãĢģ äºijåįĹ +éĢĢ ä¼į +åĿIJåľ¨ äºĨ +Ġneuro science +ĠRis ks +Ġutil ised +ĠApp ellee +Ġfemin ism +车 åŀĭçļĦ +æ¯ı å½ĵ +çα 丽ä¸Ŀ +ä¸ĥ çϾ +ç«ĭ å¿Ĺ +ï¼ĮéĤ£ 人 +ĠNe umann +Ġeth os +ĠIllust rated +ä¸į è§īå¾Ĺ +ĠW olves +op he +ull ed +Ġroll out +ĠAv atar +Cr ime +O c +Ġch oke +Ġ& , +å°±æĺ¯ 说 +_S PACE +oly gon +v ana +Ġs size +ï¼Į èι +oc yan +太 è¿ĩäºİ +.P h +æĭ³ éģĵ +:n th +( Entity +z c +Ġ å°¤åħ¶æĺ¯ +_OB J +ç»ıæµİæĬĢæľ¯ å¼ĢåıijåĮº +Ġf ug +mut ation +ĠCOMP ANY +峨 çľī +Ð ķ +ĠA ble +æ³ķ åĽ½çļĦ +åħ¶ä»ĸ åľ°æĸ¹ +_H DR +å¹´ ä¹ĭåIJİ +ï¼ģ è¿Ļæĺ¯ +迪 奥 +ĠT ec +没æľī ä¸ĢçĤ¹ +ĠCos metic +ĠCharg ers +ĠV and +åIJĦ æĹı +Ġfl ank +åĪĻ å¤© +н ой +ĠQuant itative +ener ic +-p article +ĠSar as +H ell +å¦Ĥæŀľ æĪij +Ġbl aze +ç¿» 天 +ing ale +èıľ è°± +Ġcolon ization +Ġseas ide +åĪĨ享 ä¸Ģä¸ĭ +ig ators +ãĢģ åĮ»éĻ¢ +ï¼Ł å¦Ĥä½ķ +.s core +Ġcompl ains +ï¼ĮåIJ¬ çĿĢ +Jere my +Ġrespect fully +æĻĴ 太éĺ³ +" mid +s olution +ĠK D +è´¥ åĿı +�� � +ãĢģ åį°åº¦ +æľī å¦Ĥ +åľ¨ åŃ¦ä¹ł +Ġsh aving +åģļ 强 +ĠCont rolled +/s ite +- Level +主è¦ģ åĨħ容 +æ´»åĬ¨ åĴĮ +ĠVo IP +çļĦ åĪĨç±» +åħĪ çŁ¥ +.app le +ĠN airobi +ï¼ĮæľĢ éĩįè¦ģçļĦæĺ¯ +è¿ŀ è´¯ +Ġport ability +Ġrecruit ers +. Options +R K +ç»ıæµİ å¼ĢåıijåĮº +äºķ çĽĸ +_ LED +/ < +æīĢ åIJ« +ï¼Įåħ¶ä¸Ń æīĢè¿° +Ġadapt ability +太 ä½İ +èĤ¡ä¸ľå¤§ä¼ļ 审议 +ï¼Į æĪIJç«ĭ +ï¼Į ä¿ĥ使 +Ġtrig lycer +( head +Ġh f +ĠS cho +为 åİŁæĸĻ +å¤ļ äºİ +ä¸ī æĪIJ +gan o +ĠFl our +ĠBra ve +Ġchees es +" She +äºĭ åħ³ +Ġdivers ify +Se en +ched ules +éĹŃ åħ³ +à³į ಠ+ç» ¾ +赤 裸 +æ£Ģå¯Ł æľºåħ³ +Ġ ******** +ä»ĸ们 两个 +ĠEn rollment +/ ******************************** +Ġ éĤĵ +Ġaccess ion +ĠAp k +-s uper +Z L +Ġ åĤħ +æĺ¯ä¸Ģ å¼ł +Ġaspir in +p illar +è¿ĩ å¤ļä¹ħ +æĺ¯ä»Ģä¹Ī åİŁåĽł +ä¼ļ è§ģ +Ġname of +ET ERS +Ġchocol ates +( html +-p refix +-st atus +éĺ¿ åį¡ +/b ootstrap +(g rid +代è¨Ģ 人 +è¡£ é¢Ĩ +为 ä¸Ģç§į +常 æķ° +èģĶ å¸Ń +Ġcongrat ulate +åģļ 空 +å¿ħé¡» æľī +ãĢĤåľ¨ æĪij +ĠCam el +ĠSt ro +uel ess +-d riving +çļĦ æĽ´ +大 éĽª +俯 çŀ° +ãĢĤ æĥŁ +ĠM isc +æľĪ 以æĿ¥ +har ma +两侧 çļĦ +å·¥ä½ľ æĹ¶éĹ´ +ĠThe odore +_T LS +Absolute Path +ag ate +èĩª èIJ¥ +Ġshe pherd +æµ· 滨 +Ġbi otechnology +hem ian +Ġvagu ely +p ixels +Ġè¿Ļ ä½į +åıijå¸ĥ åħ¬åijĬ +ï¼Į åİĭåĬĽ +in berg +使 åĩº +ĠBegin ner +Ġ ÈĻi +åĩºåİ» çİ© +ĠLim a +Ġantiv iral +æ§ ĥ +æĮij äºĨ +åĸĥåĸĥ èĩªè¯Ń +ä¸ĵç§ij åĮ»éĻ¢ +o arthritis +è§Ĥ å½± +ĠFr anz +Ġadjust s +Emb edded +umpt ech +h fill +æķĪ ç͍ +ĠVis ibility +Ġunders cores +Atl anta +Ġ ä¸Ĭè¿° +Ġ éĴĪ对 +æīĵ æĪij +éĥ½æľī çĤ¹ +ĠC ES +ĠW Y +.v ue +Ġcos y +转åĮĸ æĪIJ +ĠCitizens hip +ar oo +æŃĮ åī§ +(P y +Ro oms +çļĦ è¿Ļç§į +(& ( +ĠY acht +æĹ¥ æĪIJç«ĭ +ï¼Į èĻİ +.S ingle +_f it +è¿Ļæł· ä¸Ģç§į +å¿ĥ å®ī +çŀ¬ æģ¯ +æŃ»äº¡ çİĩ +åĬ ¾ +æ¹ĸ è¾¹ +西游 è®° +ith rom +ĠK irst +_C UR +rap ists +Ġair planes +é½IJ å¿ĥ +-s ensors +Acc um +åºŁ éϤ +å´ĩ é«ĺ +æ¤ ¿ +ĠPol o +Ġcapt ions +Ġsoft ball +Ġf ooth +责任 åζ +Ġs rv +é¼ĵ é£İæľº +n ard +Ġtra cer +åĿĩ å·² +ĠBrew ery +åŀĭ åĴĮ +ĠSt ake +ï¼ģ åĽłä¸º +led on +. Variable +k rit +éĩį 度 +åIJij 导 +çŁ³ åύ +Ġcamp site +ĠMart ial +å¿ĥ æĤ¦ +èij¬ 礼 +Ġoste oporosis +q xs +ï¼Į ç§ijæĬĢ +åľ° æļĸ +ãĢĬ è¯Ĺ +Ġμ l +çļĦ å¼Ģåıij +è¿Ļ款 游æĪı +opp el +Cra ig +大 ä¾ł +Ġnarrow er +ĠU rs +m ist +Ġi P +ĠSe afood +è´§ çī©çļĦ +éĺ¶ çº§çļĦ +Ġwrong ly +ï¼Į åĭIJçĦ¶ +ost ring +AC M +æĵħ éķ¿çļĦ +, éļ¾éģĵ +ay ed +åĩĢ æµģåħ¥ +ï¼Į æŃ¢ +åį ŀ +æĶ¶ å¤į +ä¼ł 人 +isc us +åĴĮ ä¿ĿæĬ¤ +ip ients +åĨį æĹł +èĢ¿ èĢ¿ +áĥĺ áĥ +S IGN +ãĢĤ æ²Ī +ĠK E +ĠDr inks +çݰéĩijåıĬ çݰéĩijçŃīä»· +ï¼Į çĿ¡ +Ġhelic opters +ï¼Įè¿ĺ 羣æĺ¯ +ĠCON F +.background Color +x v +ĠC out +Ġgl ac +å®ŀ æĻ¯ +Init ially +Ġon ward +ä¸İ 客æĪ· +æijĩ 篮 +Ġrend ition +ï¼Į å¥ĩ +çļĦ éĺŁä¼į +Ġcom orbid +çݯå¢ĥ åį«çĶŁ +åĮĸ éªĮ +ĠSch a +çİĭ ä¹ĭ +贯彻 æī§è¡Į +orde aux +ĠMar vin +å¹¶ä¸į 大 +Ġie ee +æķ° åĪĹ +Ġav ant +æ·± ä¿¡ +ï¼Į ç͵影 +Status Bar +Ġcru ises +æĸĩåѦ ä½ľåĵģ +Ġdisg race +ucceed ed +ãĢĤ é¢Ħ计 +æĺ¯ä¸ª 好 +Ġnight mares +å¥ĩæĢª çļĦæĺ¯ +ç§ij åijĺ +ï¼Įåıį åĢĴ +Ġå¦Ĥæŀľ ä½ł +åł´ åIJĪ +Per f +| ^{ +um ably +ĠG OV +æ¦Ĥ 论 +_R T +, æĸ¹ +p lectic +Ġdeduct ed +ap o +Ġfun k +(c urr +.sc ss +Ġt ac +æĹ¶ åı¯ä»¥ +éħį æ¯Ķ +ä½ł èĩªå·±çļĦ +Ġad ept +Ġmanif ests +Ġsin on +åľº ä¸Ń +æ¯ı ç§į +åĪ« å¿ĺäºĨ +å¹¶ä¸į ç®Ĺ +ĠSold iers +- interface +çļĦ æ¸ħ +ec ost +Ġgather s +为 客æĪ· +æĸĩ æĺĮ +amp oline +! Share +" ', +ĠC ancellationToken +th orne +éľĢè¦ģ æľī +Ġelectroly te +å®ļ æł¼ +æ´ĭ溢 çĿĢ +å·¥ä½ľ ç»Ħ +åĢį æĦŁ +OC US +Ġr aspberry +ä»Ķç»Ĩ è§Ĥå¯Ł +çļĦ èĤ¡ä»½ +ĠB lob +clus ively +åįķ æīĵ +鼶 çĤ¹ +æĹħ游 å±Ģ +åľ°éĵģ ç«Ļ +@b logger +âĢĻ all +ä¸Ĭ 大åѦ +åĭ¾ ç»ĵ +Ġpro actively +ä¾Ľ éĶĢ +çݯå¢ĥ å½±åĵį +inds ight +Mort gage +, ä¸įåı¯ +ĠS ick +常 温 +å¤ļå°ij 个 +Dec oration +ĠNurs ery +Ġdo ve +.p ublic +请 æĤ¨ +人çļĦ æĹ¶åĢĻ +ãĥ ĵ +vent ed +许 许å¤ļ +ä¹Ļ åŁº +åĬ² çļĦ +ous y +_c ross +Ġad hered +åIJĮ 为 +åĩĮ åħ° +ãĢĤæľ¬ å®ŀç͍æĸ°åŀĭ +çļĦ主 æµģ +ĠDeb ate +ĠVEG F +ï¼Į ç¨įå¾® +离 æķ£ +ĠSupplement al +G ravity +çļĦ æŃ£ç¡® +æĪIJ 亲 +éģĹ ä½ĵ +人工æĻºèĥ½ æĬĢæľ¯ +Reb ecca +.get ElementsBy +ä¸ŃåĽ½ ä¼łç»Ł +ĠColl ision +ç»Ħ åĽ¢ +N IC +n ah +ê me +Ġro be +ï¼Įä½ł èĩªå·± +-W est +Integ rated +ĠBulld ogs +. Stop +ĠF aster +rem ain +æĬ¢ æĸŃ +äºĮ çĪ· +交 ç»Ļä½ł +Ġvalid ating +ĠSa unders +ĠBab ies +- ring +åİ» åĵªåĦ¿ +ok ers +Acc uracy +åı¸ä»¤ éĥ¨ +" name +Ġ{ }) +以 对 +ä¿ĿæĬ¤ åĴĮ +å¤ļ å§¿ +PR I +æ¡Ĥ åĽŃ +( Text +Ġ 建ç«ĭ +楼 å®ĩ +纺ç»ĩ åĵģ +ãĢĤ åIJ¬ +æĭī æĭī +Ġre agent +Ġsm elled +ĠOn ion +ä½ıæĪ¿ åĴĮ +Sustain ability +çļĦ éĶĻ误 +å¿ĥ å¦Ĥ +Man chester +L K +v P +çĶŁ é²ľ +æĸ° æĺŁ +Ġac ronym +Ġlo oph +æī© 大äºĨ +åŃĺåĤ¨ 空éĹ´ +ĠSport ing +il and +ĠP redictions +çĿ ¾ +åįĬ åĬŁ +Ġluck ily +ĠTh orn +äºĴ åĪ© +ĠBlack s +itt ance +çļĦ éĿĴå¹´ +éĩį ç͍ +æ¯Ķè¾ĥ å°ij +Ġmillenn ials +Ġcommem or +ä¸Ģ è·¯ä¸Ĭ +ĠA licia +em erg +com plicated +空 åīį +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +äºĭ项 çļĦ +Ġ 以ä¸ĭ +ĠMC U +Th umbnail +\ overline +ĠS SC +ĠDirect ed +Vertex Attrib +çķľ ç¦½ +ĠÑĤ ак +ĠPrel iminary +çĤ¹ åŃIJ +AT M +/d L +Ġty rosine +ĠC arly +=" % +ç²¾ åħī +ä¸Ģå®ļ ä¸įä¼ļ +ĠComb ination +N om +çļĦ 顶端 +ãĢģ æ¯Ľ +åĪ°è¾¾ äºĨ +她 å·²ç»ı +mail to +cap ital +Ġ ........ +æłĩ æĺİ +e ering +Re peated +éģ´ éĢī +ĠC SA +Ġhydroph obic +ãĢĤä»ĸ 认为 +çĭIJ çĸij +è¿ĩæķı æĢ§ +_STAT S +j l +Ġl c +Ġg f +æŃ£ 绣 +èĢģ åħµ +访 客 +TA IL +ĠHydro gen +, æĺ¯ä¸Ģç§į +F t +ï½ Ĵ +-f ast +å¸Ĥåľº åĴĮ +æĹ¢çĦ¶ å¦ĤæŃ¤ +break er +ï¼Į æĽ´å¤ļçļĦ +åı¤ æľ´ +æ¯į åIJİ +æĬĹ åİĭ +æĶ¶èİ· äºĨ +ĠTrou ble +ï¼Į 个个 +è¢ Ħ +æīį ä¼ļæľī +Ġstart ling +bl as +Ġredist ribution +ĠTun isia +Ġw m +ï¼Į è¾Ľ +Ġtent ative +/ project +ĠN ach +å°ı åºĹ +ãģ ³ +书 é¦Ļ +强度 é«ĺ +, æľįåĬ¡ +ä¸Ĭ æł¡ +åķ ı +D oug +Ġvig orously +çļĦ åİŁçIJĨ +å¹¶ 举 +ç³»ç»Ł çŃī +ï¼Į åįķä½į +ĠC HA +.s uper +Ġprep ayment +v ide +ï¼Į 建çŃijéĿ¢ç§¯ +ig rated +第ä¸Ģ ç§į +æıIJé«ĺ åΰ +çĶŁ æ°ĶçļĦ +两 åı£ +ĠUS PS +æ®ĭéħ· çļĦ +éļ ½ +æŃ¦åύ è£ħå¤ĩ +éľī èıĮ +驳 åĽŀ +Ġalbum in +å°ı说 ç±»åŀĭ +Ġrecon cil +çĿ ¬ +å¹³ äºĨ +Ġpay pal +å±ħ çķĻ +èĵ Ł +ä¸Ģ æĥ³åΰ +以 举 +å·¥ä½ľ å²Ĺä½į +.group Box +ç´§ 缺 +èĦļ è·Ł +Ġvalid ates +æĭ¥æľī çĿĢ +Ġawa ited +ĠPar cel +Walk er +åύ çŃī +oph ile +寻 è§ħ +å¤ĸ æķĻ +Ġmon omer +UT R +Ġcomfort s +çļĦ 汽车 +æİ¥ åIJ¬ +eval uation +ãĢĤ åºĶ该 +Ġal ph +åIJij æĤ¨ +æ·± èĢķ +åħ´è¶£ çα好 +Wire less +` * +å¼Ģ æĮĸ +eb a +çłĶç©¶ 室 +ĠPr att +èµı è¯Ĩ +ï¼Į å¥ī +è¿ŀæİ¥ åľ¨ +ç½Ĺæĸ¯ ç¦ı +ä¹Ł 纳 +Ġso fas +çŃĴ ä½ĵ +Ġhybrid s +Ġaspar agus +è¿ĩ æĹ© +Ġcr umbs +æīįæĺ¯ 羣æŃ£çļĦ +ĠCS F +[ current +ä¸įçŁ¥éģĵ 为ä»Ģä¹Ī +(sub ject +ï¼Į å·¥ä½ľäººåijĺ +ĠV ed +æį¢ ä¹ĺ +Ġcorrid ors +Ġunderest imated +ãĢĤ éĥij +Ġu long +ĠF ang +Ġsym posium +æ»ij æĿĨ +çļ® ä¹¦ +ĠDesign ers +Ġj umper +AM B +ñ os +å¤ļ ä¸ĢçĤ¹ +.M vc +å̾ åĢĴ +赫 è¿ŀ +Ġlibr arian +} u +un ger +ä¿¡ ä»¶ +Ġbest s +ĠNor wich +Ġexplor atory +ad ores +-s uite +éĽª çϽ +.cl uster +¬ ģ +åĴĮ èĩªå·±çļĦ +åĩł 大 +P arsing +ï¼Įéĥ½ 没æľī +zz zz +ĠP arenthood +_t b +Ġven om +ĠHun ts +ĠDiscount s +- activated +C ow +ass andra +,ä½ł ä¼ļ +æĶ¶ è´§ +è®° äºĭ +: G +åħĥ é¦ĸ +Ġmicrobi ota +çķĻ æľī +Ġbog us +ãij ¹ +w hel +Ġcom for +æŁĶ å¼± +çļĦä¸Ń å¹´ +åįķçĭ¬ çļĦ +e am +æĹ¶åĪ» åĪ» +ĠY ours +Ġpo op +åIJ¯ 迪 +æīij éĿ¢ +æĢ» éĺŁ +ï¼Įä¹Ł æĹłæ³ķ +{sub figure +-s ymbol +ç¼Ń ç»ķ +h aha +ĠP ound +En velope +ãģ¨ ãģĦãģĨ +Ġun ix +æĹł åĬĽçļĦ +-h idden +éľĩ 天 +Ġch ond +Ġ é϶ +__ (( +.n s +ĠRES P +ARI ANT +æĹ¶ä¿± è¿Ľ +Ġc aches +ï¼Į ç½® +äºķ ä¸ĭ +æĭİ çĿĢ +ï¼Įåıª åī©ä¸ĭ +ĠTim ing +Ġclock wise +æīĶ æİī +Ġpuzz led +, åŁºæľ¬ä¸Ĭ +е Ñĩ +ç¢Ĺ éĩĮ +. over +æĬ½ çѾ +éĢĤåIJĪ äºİ +Ġmar bles +comp iled +ĠMich a +èĢĮå¾Ĺ åIJį +å© µ +ĠConf erences +å¿ħ ä¿® +Ġ ® +Ġpar ab +(c opy +(w orld +æĪij们 ä¸Ģèµ· +}) ^{ +æĺ¯ åħ³äºİ +Ġst abbed +åĴĮ æ°Ķ +, åıĮ +q ing +æĢĿ æĶ¿ +åIJĥäºĨä¸Ģ æĥĬ +æĹ¶ æĹł +çļĦç¬ij 声 +å®ļ åģļ +åIJį åī¯åħ¶å®ŀ +ierarch ical +ĠSp ike +_in line +ĠCl int +æĺ¯ä¸Ģ èά +Sur f +ĠKim berly +ĠLeb anese +Ġengra ved +Ġad mon +è¡Ģ çĹħ +Q å°ı说ç½ij +ç»ı åķĨ +aryn geal +ãĢģ èįī +ï¼Ī åĽ¾ +ãĢĭ èİ· +AG EMENT +/p df +ãĢģ å®īå¾½ +é«ĺ é¾Ħ +,ä¸į åĨį +Ġren ters +æIJĤ çĿĢ +ĠÐ ĺ +诺 夫 +åįģäºĮ äºĶ +æĢ§ çĶŁæ´» +Ġclos ets +Ġcas p +Ġt iers +æİĴåIJį 第ä¸Ģ +ĠCo aches +ï¼Įå¿ħé¡» è¦ģ +ĠO sc +Request Mapping +æŀª æīĭ +ĠVel vet +ĠB ien +ï¼Ī www +Ġallow able +æĦıè¯Ĩ åľ° +æľĢç»Ī è¿ĺæĺ¯ +é̼ 羣 +Ġapp lause +less sim +A i +å®ī æ£Ģ +Ġinf low +/\ / +ĠNag ar +Ġpre ached +åĨħ åĬĽ +ï¼Į让 åŃ©åŃIJ +Ġfool ed +âĸĪâĸĪ âĸĪâĸĪ +Ġbik ini +Ġuter us +o ire +èĩª æĭĶ +ĠIs abella +SHA RE +æľīäºĽ åıij +åIJ Ĩ +ï¼ĮæĪij们 éĥ½ +å°ļ æľī +ĠMal i +ĠSP SS +ï¼Į身 å½¢ +. Handler +Ġbut cher +ä¸Ģ个 好çļĦ +ux tap +æĪĪ å°Ķ +Ġant iqu +Ġarm our +IM UM +å°ĺ æ²Ļ +- { +ï¼Į èݱ +çļĦ å½±åŃIJ +LET ED +ĠEpid em +åįı åĴĮ +.res ources +V ectors +ĠNo ir +Jun ior +ĠTo String +-in line +åĪĨåŃIJ éĩı +æ³ķ æĭī +yt orch +åģı è¿ľ +Ġfort unes +çļĦ çľĭæ³ķ +æ£Ģæµĭ 仪 +p olar +åĴĮ æĶ¿æ²» +çĶŁäº§ åķĨ +Ġhot spot +çļĦé«ĺ 端 +ĠCh ill +Index Path +驱åĬ¨ æľºæŀĦ +or ama +ï¼Į åıijè¡Į +éŨ å¸Ĥ +çģ« èᝠ+çĿ¿ æĻº +åĨ² åİ» +, éľĢ +ĠB UILD +ĠWin chester += M +_N S +ĠM MC +(g ame +æĭĨ åĪĨ +// **************************************************************************** +èIJĮ èIJĮ +ç͍ æĪ¿ +Ox ford +Ġtire lessly +ĠH g +_r and +ĠNews letters +ĠCG I +Cook ing +åıĹ éªĹ +æ¯ı个人 éĥ½æľī +æłħ æłı +ĠR outine +åIJĮ è¡Įä¸ļ +æĬķ éĿł +è§ĦåĪĴ 设计 +åľ¨å®¶ ä¸Ń +Ġ çĶŁæ´» +ĠG low +éĺħ è§Ī +è·Į èIJ½ +踢 çIJĥ +z in +Ð ij +å¼ķ åĩº +-se parated +urope an +ĠProp he +ĠMald ives +ï¼Į æľĭåıĭ +ä¸į æ³ķ +ä¸įè¿ľ å¤ĦçļĦ +-f light +ĠReb el +ĠExpl ained +Clean ing +åĪĨæĶ¯ æľºæŀĦ +ä¼ļ éĿ¢ +Ġdesper ation +åĨĻ äºĨä¸Ģ +ç»ıæµİ çļĦåıijå±ķ +re ment +ä¸ī åı£ +çIJĥè¿· 们 +ch itz +ĠMor se +ĠSocial ist +Ġv aping +âĢĻ n +ĠW anted +è¯Ŀ çļĦ +çŁ³ åĿĹ +Ġmut ated +çļĦå·¥ä½ľ åİŁçIJĨ +H app +ä½ľ è¯į +Ġco ined +æ°ij åħµ +Ġ{ {{ +iz umab +ç»ĵ çĤ¹ +Ġclim bs +u pe +ï¼Į æıIJä¾ĽäºĨ +Ġ\ @ +ĠTo ilet +aut ore +( Abstract +ĠL ydia +ĠK ush +O LEAN +b ath +Ġinv ade +çļĦ è¾ĵåĩºç«¯ +pr on +æĶ¯ éĺŁä¼į +说è¯Ŀ çļĦæĹ¶åĢĻ +Web Socket +ĠA pex +orb ed +Ġbib li +- ROM +以 ä¸Ģç§į +åĦ¿ äºĨ +åºĦ 稼 +ic hen +pl ings +up dates +F ade +s ons +ï¼Į æħ¢ +.ch at +_ph ase +@ t +g il +sp ir +Set Name +ãĢģ çļ®èĤ¤ +å·¥ä½ľ ç«Ļ +æ£Ģæµĭ è£ħç½® +ä¸įæĥ³ åĨį +ï¼Į ä¸ľè¥¿ +ver bal +游 è¡Į +ãĢĤè¿Ļ æĦıåij³çĿĢ +ä¸Ģéĺµ åŃIJ +ĠHa irst +缴æİ¥ åľ¨ +Ġpo ignant +顾 ä¹ĭå¿§ +èĹı åĵģ +ठ¹ +éĩį å·¥ +-b all +ï¼Į è¸ı +ĠF iona +ä¸Ĭ 说 +éĥ½ä¸į ä¸Ģæł· +os ide +.Anchor Styles +Ġ åįłæ¯Ķ +ä¸ĭ 线 +çα ä»ĸ +Ġever lasting +SP A +çļĦ åIJĦ项 +çļĦ第ä¸Ģ æŃ¥ +_ activity +ãĢĤ åıĮ +ï¼Į å¡Ķ +Ġj oking +ï¼Įä¸įåIJĮ çļĦ +ĠOut line +ĠRob bins +ä»ĸ们 ä¹Ł +ï¼ĮæĪij å¿ĥéĩĮ +ĠæĪij æĺ¯ +åĽ¢éĺŁ åIJĪä½ľ +ĠAnt arctic +Ġmo et +Ġe ject +æĥĨ æĢħ +éĥ¨ 主任 +ĠApp reciation +ï¼Įçľĭ å¾Ĺ +çijŁ çIJ³ +ĠGov t +æĥħ è°Ĭ +æ·±åħ¥ çļĦ +Ġty re +æĪ· éĥ¨ +åŃĹ å½¢ +ĠSom ew +ĠMc Int +ĠSupp ress +æŀģ æĢ§ +æ²ī é¦Ļ +uts ch +ĠGuard ians +åĬĽ 强 +åĩł ä¸ĩ +rid den +å¦Ĥä½ķ å¤ĦçIJĨ +ĠSO UR +L W +ĠA UC +^ *( +Ġl cd +æ¯Ķè¾ĥ ä½İ +ĠPres idents +ï¼Ł ä½Ĩ +éŃĶ æĹı +v it +æĹł æĤĶ +Ġant ip +æŃ£å¼ı çļĦ +g ens +Ñĥ Ñģ +èĤ¡ä¸ľçļĦ åĩĢåĪ©æ¶¦ +ĠF ever +). $$ +çϾ ç±³ +Ġwater color +ï¼Į请 æ±Ĥ +èIJ¥ä¸ļ ç¨İ +ĠEnc ourage +Ġpolymorph ism +. Visual +C ourses +ĠâĢ ł +ĠShow ing +Ġchron ological +ĠJ elly +lis le +Ġfrag rant +ë Ŀ¼ +In come +亲æľĭ 好åıĭ +ĠA FL +ĠFollow ers +ï¼Įæķħ èĢĮ +çļĦé«ĺ ä½İ +ó s +[ root +Ġ åĨħåŃĺ +åľ°æĿ¿ ä¸Ĭ +å¤ĸ è²Į +_d ark +åĵªéĩĮ æľī +æľĿéĺ³ åĮº +ï¼Į åı¸ +ĠReview ed +åŃIJ åħ¬åı¸çļĦ +æ±Ĥ åѦ +å®ľ 宾 +ĠWood y +ï¼Į æĭ¿åĩº +,æĪij åľ¨ +ä¸įéĶĻ äºĨ +R oss +çݰ åŃĺ +b race +Ġ" << +Git Hub +k or +è¢ Ĥ +使 é¦Ĩ +çIJĨè§£ äºĨ +çĭ¬ç«ĭ æĢ§ +åŀ« çīĩ +åıĹ éĤĢ +· ç±³ +Direct ories +æĿijæ°ij 们 +( å¸Ĥ +çĿ ½ +ĠSt all +建设 å·¥ä½ľ +Ġupp ercase +) æľīéĻIJåħ¬åı¸ +Ġ å¹¿ä¸ľ +å±± å·Ŀ +çļ® çĤİ +ĠF FT +ok ane +å¾Ĺ æĿ¥çļĦ +ĠK raft +请 示 +Rec ursive +-up date +Ġlab ore +? Let +J E +h ua +an us +Ch all +ĠSh ine +æĺł åħ¥ +ĠR K +ĠSt able +а еÑĤ +Field Value +Ġtransl ators +Ġd vd +å²ģ å·¦åı³ +J T +k ern +ï¼Į åģľ +çļĦ 宽度 +ĠH in +Ġgl are +Ġunn ecessarily +天 å¸Ŀ +æĸŃ ç»Ŀ +ĠCont rast +çŁŃçŁŃ çļĦ +Ġpestic ide +Ġcytoplasm ic +ï¼Į 论 +ï¼Į æģIJ +ä»ĸ ä¸İ +å¦ ¤ +åIJij 大家 +Ġval ence +br ates +Exp ansion +ĠEV s +_for ce +Ġaure us +ï¼Į 起身 +Ġdress er +ce iving +ĠAss isted +åı¦ä¸Ģ ä¾§ +.qq qxs +start ed +èĤ¡ç¥¨ çļĦ +ak ar +é«ĺä¸Ń çĶŁ +] _ +E dd +_ usb +a N +_t ax +ĠE CC +é¦ĸ ä»ĺ +Ġfront end +ĠJak arta +ãĢĤ éĻĨ +un expected +ä»ĸ éĥ½ +.B atch +c rop += S +st em +ä»ĸ ä»İ +对 åı£ +转 转 +conf irmed +Ġε ίναι +ä½¼ ä½¼ +ï¼ĮæĪij èĩªå·± +è¿Ļ个 è¡Įä¸ļ +åĮ Ŀ +Ġcl ich +为 è¿Ľä¸ĢæŃ¥ +è£ħ åľ¨ +ĠF rem +âĢĶ for +aut ion +æī« è§Ĩ +çłĶåıij ä¸Ńå¿ĥ +忽è§Ĩ äºĨ +g ateway +_p d +ãĢģ æĸ°éĹ» +èĩª ä½ľ +ev o +æ®· åĭ¤ +ï¼Į åŃ£æŀ« +纯 æŃ£ +K ansas +ĠOper ational +éĢīæĭ© åIJĪéĢĤçļĦ +;;;;;;;; ;;;;;;;; +çĹħ 害 +Ġtable Name +ĠAssert ion +ļ è¯Ń +åıĬ æĹ© +åĿIJ èIJ½åľ¨ +py x +çŁ¿äº§ èµĦæºIJ +Ġp agination +èµ· è§ģ +åħ¥ èĤ¡ +el im +oc arcin +çĥ¹ è°ĥ +Ġfel on +æĹ¶ äºĭ +ĠY Y +amb ique +Ġstr cpy +Log ged +ĠM ey +æŃ» æŃ»çļĦ +å¾Ģ åĽŀ +ĠOrgan izational +带 è´§ +Ġà § +形象 çļĦ +ĠSuggest ions +/ path +åĵį 亮 +Ġps oriasis +æĪIJ å¥Ĺ +.D esign +- Class +çľģ ä¼ļ +ĠEnc ryption +Ġm V +Ġ{ ! +ĠHe ap +åĪĹ å®ģ +Ġviol ently +Ġsi RNA +ĠAccept ance +q d +Ġt ai +ï¼Į ç»ıèIJ¥ +ï¼Į åѦéĻ¢ +ĠB ones +user id +Ġinterven ing +åIJĮ è½´ +\[ \ +In form +åĮħ æīİ +Ġsoc i +.set ter +ठª +ĠGovern ments +为 人æ°ijå¸ģ +ĠпÑĢ Ð¾ += -\ +ï¼Į 人çļĦ +å°± çľĭåΰ +好 åĩłæ¬¡ +åĪ© èIJ½ +éĢīæĭ© åľ¨ +缴æİ¥ ä»İ +ï¼Į让 大家 +Ġjav afx +ĠCh ili +伸 éķ¿ +è§Ħå¾ĭ çļĦ +$ query +åıij èĦ¾æ°Ķ +Ġaut ophagy +ãĢĤä½Ĩæĺ¯ åľ¨ +Ġimmunos upp +< byte +() == +SS D +Ġax iom +cr ime +Open ed +Ġch ops +Ġun identified +è®Ń æĸ¥ +她 对 +å·² å°Ĩ +е ÑĪ +################################ ################ +Ġpizz as +ĠE SL +", $ +Ġcond os +ãĢĤ ç»Īäºİ +of lu +-h ot +Flex ible +ver m +èIJ½ åIJİçļĦ +ĠIV F +, åĮ»çĶŁ +éĺ³ åĮº +ĠSN R +z mann +. Control +ĠAl mighty +ĠACC EPT +ĠH ulu +å¤ĸ å¸ģ +ç¬ij äºĨä¸Ģä¸ĭ +âĻ ª +.h h +ĠMat hematic +FE ATURE +el ed +Ġprov oke +é£ŀ äºĨ +EF I +_P OINTER +Ġskeptic ism +åIJĮ å±ħ +å¼ł æģĴ +Ġcar ve +ĠREAD ME +) n +åĴĮ é£İ +Ġmess ing +Ġwre ath +被 èĩªå·± +å°ı çIJĥ +ount ains +æĸ¯ åį¡ +Ġbre thren +ĠCO RE +ï¼Į æİĴéϤ +åݦéŨ å¸Ĥ +(time out +oc occus +éĩij ä»· +Ġsw irl +- lock +ĠWolf e +_PARAM S +çĶŁäº§ 设å¤ĩ +æ²ī 声éģĵ +ĠSch ul +/qu estions +天 人 +Ãł n +Ġ æĢ»ä¹ĭ +ï¼Į 亲èĩª +ĠI OS +该 æĿij +çľģ å¿ĥ +ï¼Įæľ¬ æĸĩ +ĠMult imedia +çļĦåĨħ ä¾§ +P olar +å¼ł çħ§çīĩ +æ²»çĸĹ çϽçĻľé£İ +$ y +- variable +_ ES +è¿Ļ ä¼ļåĦ¿ +éĽĨ èµĦ +. Interface +æĪ· æĪ· +éľĢè¦ģ 使ç͍ +éĢģ æĸĻ +Ġcard inality +ĠPar al +麦 å½ĵ +Ġm ing +ãĢĤ æĻļä¸Ĭ +ï¼Į æĺ¾ +Service Provider +Ġsil ky +ĠD over +nt e +对 çĹĩ +åı¯ä»¥ çͱ +Ġsign ify +ĠOcc asionally +F el +åΰ ä»Ģä¹Ī +两 ä¸ĭ +两 åįĬ +SY STEM +è¾¾ æĭī +ĠBi omedical +Ġas cent +ĠF are +ä¹Ł å¾Īéļ¾ +H mm +Ġsub lime +æĬ¤ æ³ķ +åĴĮ ç¾İ +ä¸ī æĿ¿ +Ġprotest ing +F UNC +c oding +åIJĦ ä¸į缸åIJĮ +ED S +ãĢģ 磷 +ĠR ach +ä¸Ń å¾Ĺåΰ +æľ¬ ä½ĵçļĦ +Ġmon oton +äºĶ åĽĽ +å¯Ĵ åĨ° +çļĦåľ° éĿ¢ +éĥ½æĺ¯ æĪij +.Is True +ur ated +ãĢģ åıĺ +Ġvis ceral +ê ncia +Ġclim ax +Ġfru ity +* ]{}, +Certain ly +Ġn ä +马 å°¾ +_C USTOM +æľįåĬ¡ ä½ĵç³» +æĵ ¢ +Ġrefurb ished +, 表示 +Ġ ç¦ı +ãĢĤ æĪªæŃ¢ +è¡¥ èĤ¾ +顺åĪ© å®ĮæĪIJ +天æ°Ķ é¢ĦæĬ¥ +ĠTyp ed +强åζ æĢ§ +, éĩĮéĿ¢ +æķ´ä¸ª ä¸ĸçķĮ +,以 便 +æľŁéĻIJ åĨħ +æĦŁ æĥ³ +ital ic +æĢİä¹Ī è¿Ļä¹Ī +èİĨ çͰ +Ġf ury +åIJĮ åŁİ +ĠBe ard +Ġgar ner +ãĢģ ç¬¬åĽĽ +Ġgover ns +Phil adelphia +. attach +ä¸ī åŃ£åº¦ +æİ§åζ äºĨ +å¸IJ åı· +Ġec zema +ig ans +æµ· åĨħå¤ĸ +D SP +H ack +ten cent +æ°Ķ éģĵ +ç³Ĭ æ¶Ĥ +Ġaut or +åį« åĽ½ +_N V +ro tt +us cular +Ġag ony +"> " +设å¤ĩ æľīéĻIJåħ¬åı¸ +Field Type +åIJ¯ ç¨ĭ +Ġ è¯Ńè¨Ģ +é£ŀ æľºçļĦ +ĠString Buffer +ĠShould er +ent ary +çĭ¬ åĪĽ +td own +Ġabsor bs +/ auth +ï¼Į 交æĺĵ +Âł ä½Ĩ +ĠI W +åĶ ı +çļĦ缮çļĦ åľ¨äºİ +ãĥ Ģ +ĠSm ash +ĠTw ist +à ¹ģ +ro cess +Ġg b +ï¼ĮåĨį å°Ĩ +ĠRob bie +Ġи н +_h i +asc us +ĠCy rus +åĽĽéĿ¢ åħ«æĸ¹ +l w +éķ¿ éĿĴ +çĹħæ¯Ĵ çļĦ +æĮ¥äºĨ æĮ¥æīĭ +reg istration +éģĵ å®¶ +两 å¹´çļĦ +ä¸ĢäºĽ çļĦ +åľ¨ åĮĹ +ĠF ACT +缴æİ¥ è¿Ľè¡Į +åIJ«æľī 丰å¯ĮçļĦ +Ġsucc umb +Ġb m +ĠH Y +.m etrics +Ġpost graduate +åĸľ æĢĴ +Ġsales man +F ear +K eeper +åħī 顾 +(m atrix +èģĮä¸ļ åѦéĻ¢ +çά åΰ +ç¦ º +Tra il +W ays +éªĹ å±Ģ +Ġclo ak +ï¼Į åį°åº¦ +ãĢģ æŀľ +èĭ¦ å¿ĥ +çļĦå°ı åŀĭ +. le +被 éħį置为 +篮 åŃIJ +Ġimmun ization +_ST EP +N t +Û ģ +ĠH ors +.R el +Ġsucc inct +对 åķĬ +")) ; +ï¼ĮæĪij åį´ +Ġconfig s +Ġrot ates +Ġparan oid +æ©Ħæ¦Ħ æ²¹ +ãĢģ å¤ĦçIJĨ +est o +gram mar +åĶIJ è¯Ĺ +me as +Ġcomp ounded +ĠNeg ro +ĠT omb +åĴĮ 浩çī¹ +å¾Īå¤ļ äºĭæĥħ +Mut ation +e ax +ĠP AP +ĠFund amentals +ä¹Łä¸į è¡Į +ung sten +ãĢĤæĽ¾ ä»» += B +{ definition +åľ° åĽŀçŃĶ +ä¿¡ç͍ è¯Ħ级 +ĠPom pe +- responsive +ï¼Į 太åŃIJ +ĠC ary +Ġbi j +ĠJ ain +ĠG rape +Ġdis co +è·³ æ°´ +éĹ ° +éĿł èĩªå·± +T reat +ãĢģ åĽŀ +Ġcomplex ion +ãĢĤ åħ¬ +ĠInc orporated +éĽĦ å¿ĥ +_ep i +ĠLen ovo +Ġgel atin +åı¯ä»¥ éĩĩç͍ +æ³¢ 士顿 +ä½ł åĨį +( Source +ä¸İ ä¸Ń +ãĢĤ èĭ±åĽ½ +ĠD ag +æľ¬ éĻ¢ +头 åĴĮ +RE CT +çĥŃ éŨçļĦ +éĻĪ æµ©çĦ¶ +Pe ak +Ġ è¨Ģ +ĠÐ IJ +æİªæīĭ ä¸įåıĬ +åIJĮ 级 +ï¼Į ä»Ļ +Ġun equiv +产 äºİ +Ġdi aphrag +_\ - +Ġvegg ie +æĢ ¦ +Ġforb id +Ġfor s +ĠM p +ĠLars on +` t +_ rot +Ġ åħ¶å®ĥ +im ulated +æĭ¼ äºĨ +, NULL +èī ® +éĩįçĤ¹ é¡¹çĽ® +ednes days +pub lisher +ä¸Ģ æľ¬ä¹¦ +Ġquiet er +Ġon cology +åģļ äºĽ +Ġdet ract +课ç¨ĭ çļĦ +Ġtor so +Ġsuck ing +æĹł æİª +ç»ĵæŀĦ ç®Ģåįķ +Ġdetect ives +ĠB ands +Ġsp illed +åıª 管 +举 å®¶ +å¸Ī å¾Ĵ +ĠF owler +æī¾ äºĨ个 +ips is +è§īå¾Ĺ æĪij +.pro xy +ays cale +å®īè£ħ æ§½ +çĻ º +æīĵ åºķ +èĵĿ åħī +éĢĨ è¢Ń +èĻļæĭŁ æľº +( App +Ġchar ismatic +_or igin +ĠDent ist +\ c + ħ +Ġ æľīäºĨ +ãĢģ æĶ¾ +é¦ĸ å°Ķ +ape ake +è·³ 转 +Ġp unt +å®ŀ å¤Ħ +Ġserv ic +Ġref s +Ġlast ly +Ġfamil ial +Ġed ema +Ġcal am +ĠT PM +çĸ £ +let able +ä½ķ åľ¨ +ĠN LP +ï¼ĮèĢĮ 她 +ill ow +å¤ĸ åĬĽ +è¦ģ ä¿ĿæĮģ +Ġsymbol ism +Ġfro gs +Ġ è·Ŀ离 +梦 çļĦ +éļIJ åĮ¿ +Ġlos ers +ĠR TP +Ġcal ves +çĶŁäº§ æĢ»å̼ +ĠDeal ers +ate red +åıĬ çļĦ +æĪ¿ åŀĭ +bat is +Ġmod ulated +Ġshort ening +OK IE +æĶ¶è§Ĩ çİĩ +B rid +X amarin +ab an +ĠCrypt ocurrency +ĠP adding +åĬĽ 士 +ĠArc ade +{tikz picture +Ġinf ancy +æ¦ Ī +Prob ability +ĠS UCCESS +ï¼Įåľ¨ éĤ£éĩĮ +ĠUIT ableView +客æĪ· åľ¨ +_ he +æľĢ æ·± +åŁİ ä¸ĭ +ä¼Ĭ å§ĭ +ar Xiv +qu ets +ãĢģ å·¦ +强 å¼± +çķĻ å¿ĥ +ç»ĵæŀľ æĺ¯ +èĵ¬ èݱ +ä¸Ģ 女 +Ġgang s +ĠD IR +Ġcr us +ĠSl ave +ĠBru ins +Id eal +aut hentication +V N +ãĢģ å¡ijæĸĻ +ãĢģ åĨľæĿij +St ick +以 西 +Ġte aser +ä¿Ŀ è´¨ +åįĹ åĮº +ome gran +Ġre habilit +Adv antages +aken ing +ĠCr imes +l augh +N athan +Ġ åIJī +en ko +-- " +ï¼ļ éĻĪ +èĩª æŁ¥ +ä¸ĩåħĥ 以ä¸Ĭ +ĠTutorial s +, 竣çĦ¶ +Ġ æ¼Ķåijĺ +-aware ness +çIJĨ论 çŁ¥è¯Ĩ +' ^ +Ġc ada +è¦ģ åIJĥ +Hy brid +ĠY in +_POS ITION +âĸ ª +æĩĴ æĥ° +ĠP erc +ä¹ĭ æŃ» +-cl i +Ġ æīĢè°ĵ +äºĨ æĸ° +_n amespace +opt imal +æ¯į æł¡ +D ance +游 èµ° +å·¥ä¸ļ ä¼ģä¸ļ +ĠView er +åįķ çļĦ +al om +ĠOut come +Ġstream ed +éĵº 天çĽĸ +çĩĥæĸĻ çĶµæ±ł +. Reset +Ġdel uxe +Ñĥ н +è¿Ł ç¼ĵ +ĠProt ective +çħ§é¡¾ 好 +READ Y +ãĢģ ç»´ä¿® +å®¶ æĿij +ä¼ĺåħĪ èĤ¡ +å°Ĩ ç»ĵåIJĪ +åĢĴ 车 +Ġchem o +ĠStraw berry +ĠP riv +pro per +ANN OT +Ġundergo es +- common +æ¯Ľ æ¯Ľ +交æį¢ æľº +Ġ æĪ´ +T ai +ãĢĤ å·´ +ï¼Įè¿Ļæĺ¯ æĪij +Ġm f +åľ° ç«Ļåľ¨ +å¿ħçĦ¶ ä¼ļ +. upload +ãĢģ ãĢIJ +åīį æĸ¹çļĦ +· åĵĪ +æĻ®æ´± èĮ¶ +Ġapprentices hip +æĸ¹æĸ¹éĿ¢ éĿ¢ +Âł åĪĺ +å°ı 鬼 +æ¤įçī© æ²¹ +ĠDO UBLE +ing ular +大 æ²³ +abol ism +ãĢģ åĬ³åĬ¨ +è¿ĺ没 æĿ¥å¾ĹåıĬ +ĠKid ney +Ġcatalyst s +V F +Ġ 交éĢļ +ãĢģ çĮª +() / +_u pper +ï¼Į èİ·å¾ĹäºĨ +天 çĶŁçļĦ +读 æĩĤ +ï¼ī å°Ĩ +.se q +ĠA i +æķĮ æĦı +ï¼Į æģ¨ +Ġgo vt +éĩĮ 没æľī +Ġmod elled +track ing +( Op +-d eterm +ãĢģå¸Ĥ æĶ¿åºľ +é«ĺ é«ĺçļĦ +ä¸Ģ个 æĸ° +Ġbot anical +m oving +n ox +r ish +åħļ å·¥å§Ķ +æīij åħĭ +åĮĸåIJĪ çī©çļĦ +ï¼Į å¼Ģåı£ +.M ake +Ġdefe ats +æŃ¤ è¨Ģ +两 ä»¶ +æĬĢæľ¯ å¼Ģåıij +ĠUN IX +Ġeigen vectors +Ġnight life +注åĨĮ çļĦ +ï¼ĮæŃ¤ 人 +ãĢģ åİĭ +ri os +èµ° å¼Ģ +Exper ts +å¯ ¾ +çĿĢ çģ« +.m et +Ġsweet heart +ĠFed Ex +ãĢĤ éĥŃ +èIJ½ å¯ŀ +çĥŃéĹ¹ çļĦ +éĿĻ éŁ³ +Ġpharmaceutical s +M EDI +åĸ· åļı +Ġcarn ival +C ir +Ġ ä¸įèĥ½ +Ġadm irable +Ġub untu +ĠAd j +纪 åħĥ +ay o +ãĢģ åĬŀåħ¬ +Ġch amp +çIJĨ 说 +ç² ij +NS Integer +G rey +æŀľ 羣 +_INIT IAL +ãĢģ å°ij +Ġro semary +é¢Ħ è§Ī +åģ¥åº· çĬ¶åĨµ +ig ers +view port +积 èģļ +_ST D +大 åłĤ +ĠB ec +è´¢ç»ı 大åѦ +: url +O regon +t ell +åľ¨ 身 +A Q +w ashing +ĠN ora +_co eff +\ cup +scr atch +ĠH N +Ġhydro xy +æµ· å°Ķ +èĢĥ åħ¥ +ĠÑģ п +ĠGraph QL +Ġscrap ing +示 å¨ģ +De an +Ġì ĭ +ĠD SM +å¤ļ ä¸ĩåħĥ +ï¼Įåıª è§īå¾Ĺ +Ġimpro vis +ĠRE QUEST +Ġt acos +ï¼Įä»İèĢĮ 使å¾Ĺ +ĠstringWith Format +( Time +ä½ķ çŃī +çºł éĶĻ +ophag us +Ġbr ink +çļĦåĨħ æ¶µ +ä¸Ģ å°ģ +def endant +ĠA kt +ĠRes ervation +èī¾ å°Ķ +Y u +è´¢ ç¥ŀ +.set Layout +æ¼Ĩ é»ijçļĦ +Ġm olds +ĠG um +lic ting +ĠCh lor +Ġel bows +CE LL +.mock ito +天 çļĩ +Comp ared +ãĢģ æķ°åѦ +Ġbr illiance +ĠNav igator +ĠS ending +大 éĥ¨ +oy l +ï¼Įä»ĸ å°±æĺ¯ +ĠâĪ © +J NI +Ġtoken izer +åĿĩ ä¸İ +O USE +åĩº å®¶ +Ġout skirts +ãĢģ 空 +Exp iration +.grad le +m ie +å¤į ç͍ +_int eg +ĠDiss ertation +es la +æīĢ åįł +Ġp ont +让 åħ¶ +åı¯èĥ½ ä¼ļæľī +ĠSing leton +èĭ¯ ä¹Ļçĥ¯ +; t +ï¼ļ åĩºåľº +ï¼ĮèĢĮ ä¸į +(s chema +å®īåħ¨ éĹ®é¢ĺ +ĠAt ty +_re ceive +å°ı çĮ« +_d p +ä¸įè¦ģ åĩºçݰ +U IS +ï¼Į 毫ä¸į +âĢĻ Brien +ç±» åĴĮ +ç§»åĬ¨ ç͵è¯Ŀ +Ġcompar ator +» Ãij +ĠN apa +ĠE CB +æĹ¥ èĢ³æĽ¼ +IDD EN +Ġcont ractions +ï¼Įè¿Ļ 人 +è§ģ ä¸įåΰ +管çIJĨ 模å¼ı +ï¼Įåį³ å°Ĩ +END ER +ĠBerg er +çĽ¸ä¿¡ èĩªå·± +ĠFis heries +ï¼Į æĭħå¿ĥ +ä¸İ åIJĪä½ľ +è§ĦèĮĥ çļĦ +Ġcel estial +N EXT +Ġr aging +åºĶ éģĵ +_bl k +ĠMother s +ä¸Ĭ æĸĻ +çĤ¹ éĴ± +_p riority +ãĢĤä¸į 论 +ï¼Į åŀĤ +Ġout law +Ġconc ur +Ir ish +_SOCK ET +Ø ¶ +ï¼Į ç»´æĮģ +Ġforest ry +ен и +æ¸Ĺ æ¼ı +ï¼Į è¿IJè¡Į +_SE CTION +- owner +d ap +Ġc logged +åıijæĮ¥ åĩº +C BA +ma j +: v +m ess +Ġass ures +ĠOr chard +IR ON +ç¼ĸç¨ĭ è¯Ńè¨Ģ +第äºĮ æŃ¥ +rec iate +ĠT ough +èµ° ä¸ĭ +und les +PL IT +é İ +Did Load +DEF INED +奶èĮ¶ åºĹ +ĠC ERT +æĵį ä¹ĭ +Ġq q +ĠWest on +g ren +ï¼Į æĴĴ +ĠH DD +_ validate +ï¼Į æģ° +ĠP ew +ä¼ł ç»Ļ +Reg Exp +.s creen +Ġseem ing +èŀįåħ¥ åΰ +å½ĵäºĭ 人çļĦ +Ġinter ruptions +Ġ_ (' +_m onitor +ĠIMP ORT +es ley +ç¹ģ æĺŁ +æĺ¾å¾Ĺ å¾Ī +, æĬķèµĦ +éĩĮ äºĨ +æľĢ èĥ½ +âĢĶ you +åIJ¦ åĨ³ +p unk +ä½ı æ°ij +Ġgrad ers +ä»ħä»£è¡¨ä½ľèĢħ æľ¬äºº +èĢĮ åĬªåĬĽ +粪 æ±ł +ï¼Į å¼Ĥ +ãĢĤ åĪĨ +ãĢĤ åIJij +设计 ä¸Ĭ +RA INT +Ġfut ile +/ MS +ĠN ah +è¿ĺ å°ı +åħ¥ å¸Ĥ +_IN TR +ĠÏĢ Î± +Ġmicrobi ome +b ang +Ġ æ±Łèĭı +æķ° ä½į +éĩįçĤ¹ åħ³æ³¨ +. Kind +er ning +Ġk otlin +è¿Ļæĺ¯ 个 +Ġsidew alks +çļĦ 尺寸 +( evt +Ġwith hold +ç͍ è¯Ń +.s ide +.f ree +å²³ é£ŀ +Ġimperfect ions +, æĽ¾ç»ı +ï¼Į æĪIJæľ¬ +æľī åĽĽ +éĢģ æĪij +ĠT IFF +ç³ ł +å·¥ä½ľçļĦ éĢļçŁ¥ +Ġdun geon +Ġ åĩ¡ +ĠG lam +çļĦ è¿ĻäºĽ +ãĢģ æ¹ĸåĮĹ +人 åij¢ +æĢ§ æĪ¿åľ°äº§ +çľĭ ä¸Ń +.p m +ĠS AVE +land ers +Ġgeomet ries +èģĶ èIJ¥ä¼ģä¸ļ +Ġtyp o +Ġwood working +第ä¹Ŀ 竳 +? (: +éľ ģ +ç³»ç»Ł ä¸ŃçļĦ +大åŀĭ çļĦ +ĠS ECT +Ġpl umm +æīĭ æı¡ +æĮĩ 使 +agn osed +åĽºå®ļ äºİ +çļĦ æľĽçĿĢ +Ġn ests +è¿Ļ çķªè¯Ŀ +ä¸ī çľģ +Ġsimp lex +.b asename +Print f +æĵ Ģ +ä»ĺ 诸 +Ġ 赤 +Ġbooth s +id iol +Ġcat cher +Ġå°± è¿Ļæł· +- health +æľī 幸 +ih u +Ġ$ ^{ +Ġend ocrine +纬 度 +ï¼Į æľºæ¢° +ï¼Į æĢ§æł¼ +åºĶ äºĨä¸Ģ声 +Ġbored om +Ġag endas +åij¨æľŁ æĢ§ +Ġreopen ed +< any +ĠM FA +ä¸Ń æĺ¯ +EO C +ĠP ace +ind erella +lect or +(f iles +严 å¯Ĵ +饱 åıĹ +ãĢĤ . +缺 å°ijçļĦ +åĨ° å¯Ĵ +( KEY +ĠColumn s +V als +Ġcont ended +Ġdest abil +-per iod +.m k +Ġd urch +(d esc +èĮ¶ 饮 +ĠMad ame +Ġjog ging +ĠN umeric +Z I +y am +Ġcl ashes +ä¼ĺ 缺çĤ¹ +åĬŁèĥ½ éļľç¢į +çͰ åľ° +æĢĶ æĢĶ +ric o +ral tar +å¦ĸ åѽ +C t +Att orney +IV ED +ĠAppell ate +. ERROR +æľī 误 +Ġle gg +å¹³ çĶŁ +æĥĬ éªĩ +大大 æıIJé«ĺ +ĠRes ilience +ĠCirc us +Ġmuff in +ĠI so +class ified +çļĦæ°Ķ ä½ĵ +å°Ĩ èĩ³ +å°±æĺ¯ ä¸Ģç§į +Ġsuperv ise +é© ¸ +åıĸ è¯ģ +ç®Ģ 书 +IRE CTION +æ¸Ķ èι +P arm +ĠD oub +.s plice +ï¼Į æ²» +ï¼Į æķĻåѦ +ï¼Į æĸľ +Ġj al +Ġ èĤ¡ä¸ľ +ĠIt al +å½ĵ 她 +ç¥ŀ è¯Ĩ +Ġaut op +åį« åħµ +ç͍æĪ· åIJį +æ´Ĺ æµ´ +-off ice +çī©ä¸ļ æľįåĬ¡ +æİ Ĥ +ï¼ļ ãĢIJ +åīį ç¨ĭ +iss au +楼 éģĵ +Ġexcer pts +\ colon +ĠV IS +Ġcatalog s +代 ä¼ļ +ï¼Įåľ¨ ä¸Ģ个 +-r anked +è£Ĥ çĹķ +og on +å¹³ åİ¿ +åIJĮåѦ 们çļĦ +å¼¥éĻĢ ä½Ľ +ĠFOR MAT +Ġtrek king +åĵª ä¸Ģç§į +å͝ çī© +Ġ å®ŀéĻħä¸Ĭ +ĠPro ve +ï¼Įä¸Ģ åı£ +åѦ æ´¾ +å®Į èĽĭ +ä¸Ńå¿ĥ 主任 +Ġ~ /. +æģ³ æ±Ĥ +Ġhyg ien +in ence +Ġalloc ating +ree ce +=' " +ä¸Ĭ åºĬ +Ġper oxid +_log ic +Ġsub merged +ä¼ijæģ¯ ä¸Ģä¸ĭ +ï¼Į 室åĨħ +ãĢģ å®ĮåĸĦ +æĥħåĨµ åıĬ +款 车åŀĭ +å¹¶ä¸į 代表 +ĠInf antry +ä¹³èħº çĻĮ +< long +.D rop +è¿Ļ åıªæĺ¯ +æļĤ æĹ¶çļĦ +' >] `: +大 èIJ¥ +Ġimp art +Ġprote ase +ĠH atch +éĶĭ åĪ©çļĦ +两 å¸Ĥ +ä¸į è®°å¾Ĺ +女 çĶŁçļĦ +-ne utral +ï¼Ī M +dd dd +Ġchar ms +åĨĻ æ³ķ +温度 çļĦ +ĠOB J +å¡ŀ è¿Ľ +çĻ»è®° 表 +-c ross +ãĢĤæīĢ以 åľ¨ +ï¼Įåı¯æĺ¯ ä»ĸ +ĠLoad er +ĠSem inary +çļĦ åį°è±¡ +ĠG G +æ¸ħ äºĮ +ent ies +ãĢģ æĹ¶å°ļ +æĪij们 èĥ½ +.add r +é³ ĸ +ĠRos ie +Ġ æľĢ大 +Ġc auc +ĠE CG +åIJİ ä¾¿ +å°ģ 为 +è¿Ľè¡Į æ£Ģæµĭ +ĠEp stein +èĩ³å°ij ä¸Ģç§į +Ġcent red +(f ields +æ±ī åĨĽ +ï¼Į åĽŀå¤į +op hen +uc s +æĺ¾ åŃĺ +沿 éĿ© +ãĢĤæĪij们 åľ¨ +æĻºæħ§ åĴĮ +人 被 +//////////////////////////////////////////////////////////////////////// //// +_ Exception +rec ursive +Individual s +ĠCl aude +课 ä¸Ĭ +èµ¶ èµ° +Ġabstract s +θ ε +ĠH ubbard +ä»Ĭ天 æĻļä¸Ĭ +çļĦ大 äºĭ +ĠRut gers +æľī éģĵçIJĨ +æĥħ çIJĨ +(p rev +ä¸ĵä¸ļ æĬĢæľ¯äººåijĺ +Ġà ģ +å²³ çζ +ãĢĤ ä¹Ŀ +Ġst roller +λ ε +åݨæĪ¿ éĩĮ +éŃĶ ç¥ŀ +éĤ£ 座 +ĠTime Span +h ooks +ĠN EC +ä¸Ĭ è¿Ľ +åºķ éĿ¢ +Ġaccess es +l ion +ef er +port al +åĸľæ¬¢ ä»ĸ +ceed ed +ä¸Ģèĩ´ æĢ§ +blog s +Ġro tten +.B ig +页 éĿ¢çļĦ +éķ¿ åĩº +éĿŀ常 éĢĤåIJĪ +奥 巴马 +壮 å¿Ĺ +Ġθ α +ĠE ternal +æĶ¯ è·¯ +- Out +å¾® é£İ +èģª æħ§ +IPP ING +Ġepithe lium +, æĪIJåĬŁ +ĠI rr +èĦ± äºĨ +Ġreson ates +ĠGENER AL +Ġparal ysis +_P IXEL +顾 èĩª +Rece ipt +å¤ĩå¿ĺ å½ķ +/ XML +; - +æľī è¿Ļç§į +Ġman ure +Ġsk im +èIJ¥åħ» ç´ł +ie res +æĬĢæľ¯ ä¸Ĭ +åѦ å¹´ +çłĶ ä¿® +åĨ² åĪ· +j w +æĢ§ çĬ¶ +ä¸īå¹´ åīį +ĠEve rest +termin ate +. rel +P ractical +ä¹ĺ é£İ +ĠFlor al +Ġblind ly +cook ies +åĪĩæį¢ åΰ ++ | +ï¼Į 幸ç¦ı +å¥ĩ èīº +èıľ å¸Ĥåľº +Be ach +.class Name +ĠAstr onomy +Ġ ä¹Į +ãĢģ éĿ¢ +set Text +Ġhist ological +ĠMar cos +éĵº åŀ« +å¹² æ´Ĺ +大 象 +Ġfa una +-set ting +ï¼Į 代 +æ°´ éģĵ +åįĬ åĪĨ +Rec ipient +å¸ĥ åħ° +ls x +å¹³ çŃīçļĦ +-m m +åı¥ æĦı +.k ernel +Ġ éĹ»è¨Ģ +ĠS ard +Ill inois +_PACK ET +åĬł åĪ© +åĪ« å¤Ħ +éĺ¿ çİĽ +Ġhandic ap +ä¸ī é¤IJ +å¾· è¡Į +ĠClean up +Response Body +æľī äºĮ +è¶Ĭ æĥ³ +ĠRam irez +ĠJ ournals +çļĦçľĭçĿĢ ä»ĸ +Ġgriev ing +å¤ľ æĻ¯ +Ġc ó +ï¼Į éĻĽä¸ĭ +没 æĿ¥ +åĮĹ京 çļĦ +Hel en +泪 æµģ +V enue +(p acket +ç©¿ åĪº +æĺ¯åIJ¦ åı¯ä»¥ +弯 æĬĺ +big r +åłĨ æĶ¾ +çĹ ¢ +ï¼Į æĿ° +Ġtum ours +ο ν +.R est +ĠTravel ing +: =\ +ĠD ont +( åĽĽ +) t +ĠH AD +å®ļ éĩij +帮 æĪij们 +å¸ĮæľĽ éĢļè¿ĩ +л Ñİ +.L ong +ĠL AS +ĠK ier +url s +Ġcrit iques +å¤ĸ æĸĩåIJį +Ash ley +< option +index Of +为é¦ĸ çļĦ +Ġsub contract +-p ay +' Brien +ãĢģ å¢ŀ强 +Ġget All +ï¼Ī 第 +èµĦ ä¿¡ +å°±ä¼ļ åıijçݰ +ï¼ĮæĹ¶ èĢĮ +/ week +转 è¿ĩ +ĠOs borne +_SC ALE +ĠJur is +èľĹ çīĽ +Ġt uck +ï¼Į å±ħ +ï¼Į è¿IJåĬ¨ +anag an +Ġmus cul +éĿĵ 丽 +.nc bi +or io +Ġp he +çĿĢ è¿Ļ +-h over +éĢĢ ç¨İ +_r unning +ĠBulgar ian +_R CC +Ġhar ms +ĠDocument ary +å¢ŀæ·» äºĨ +西 ä¾§ +.b ukkit +æķij èµİ +ãĢĤ ä½ľåĵģ +ĠC p +æľīä¸Ģ é¢Ĺ +Inv ite +ĠBos nia +- ton +ĠT art +_A UT +yal gia +. Transaction +Ġplay wright +.A bs +罪 çļĦ +ĠHow e +èĥ¶ ç²ĺ +p rem +ab ytes +ĠD illon +æŀģ 好çļĦ +, +éĢĤ åºĶçļĦ +åħħåĪĨ èĤ¯å®ļ +ĠP roud +ç§ĺ ç±į +C riminal +Ġv ie +qu ake +ï¼Įä½Ĩ è¦ģ +åıĺ 缸 +ĠM ink +èįī çļĦ +ot ify +äºĨ 大éĩıçļĦ +ï¼ļ æĸ° +Ġ< ![ +-m emory +夸 èµŀ +æ¶ĪåĮĸ éģĵ +ĠTIM ER +/ th +ĠDon ate +M isc +æĤ » +èµĦ 管 +è¾¹ èµ° +椰 åŃIJ +, åı« +W el +Ġ 欧éĺ³ +åĴĮ å®¶éķ¿ +ĠPoll ution +b is +亮 åħī +èᣠåįİ +K o +åħ´ éļĨ +èĦļ æīĭ +Ġsleep ers +ĠProv ision +ãĢĤ 大å¤ļæķ° +ĠCon nie +æļ´ åĩ» +åľ¨ åľºçļĦ +å¹³ å¤į +éĺ² éĶĪ +溯 æºIJ +_ ge +ub ation +åIJĮ æ¡Į +ĠEric a +us i +Ġrum ours +åħ¬è¯ī æľºåħ³ +Ġerupt ed +åıį éĿ¢ +ãĢĤ æľķ +else y +ĠSe as +çİĦ å®Ĺ +缴æİ¥ æĪĸéĹ´æİ¥ +å¾ģ åľ° +obs erved +ĠIsrael is +ĠEst ablished +ä¸Ńæĸ° ç½ij +W ATCH +Ġaut og +åľ¨ åĮ»éĻ¢ +ĠW rites +åĪĨ 寸 +æ¥ļ æ¥ļ +Ġtax a +l ays +ol ed +åĨ² çł´ +foot notes +èŀįåIJĪ åıijå±ķ +Ġf oe +é«ĺ éĽĦ +é«ĺ åĤ² +-m ult +Ġinnov ators +ä¼ĺç§Ģ æķĻå¸Ī +ar um +转 èĢĮ +Ġ_ {\ +ï¼ĮéĤ£ä¹Ī å°± +çĸ² åĬĽ +æīĵ éĢłæĪIJ +åIJ¬ è¯ģ +京津 åĨĢ +J F +%çļĦ èĤ¡æĿĥ +ä¸į æħİ +åľ¨ 第 +æľª åĪĨéħįåĪ©æ¶¦ +å¯Į 人 +åıij表 çļĦ +Ġcolour ing +ä¸Ģ éĺŁ +åĩº 没 +Ġche ated +çľģ åĬĽ +ãĢģ ç¦ı建 +Ġk en +GS M +Ġsub units +ĠMed ian +å¡Ķ çļĦ +æĶ¾å¿ĥ äºĨ +辨 è¯ģ +as her +ĠM AL +ĠW end +æĢ¨ æ°Ķ +- parameter +社 å·¥ +è½» èĶij +" æĪij +ï¼ĮéĤ£ ä½į +: æīĢè¿° +g ravity +r ath +Ġc aster +ont ology +æİ¥è§¦ è¿ĩ +ĠHon olulu +éĵĥ èĸ¯ +ĠS gt +ĠM org +çİĭ åIJİ +Ġnumber ing +绿 åı¶ +P urch +ï¼Įä½Ĩ åħ¶å®ŀ +- âĢĿ +Ġpsy che +, ä¸ĸçķĮ +ä¸į åĨ³ +å¸Ĩ èι +Ġdisrupt ing +- price +Z O +Ġa usp +Ġint angible +Inter preter +ed eration +çļĦ 次æķ° +ãĢĤ æĿľ +.is Valid +ä½ł ä¸įçŁ¥éģĵ +åł ĩ +ĠLe ap +ãĢĤä¸į çĦ¶ +å©ī åĦ¿ +(t okens +ĠEn code +æĥĬ æĤļ +ãĢĤæľī ä¸Ģ次 +åIJĪèĤ¥ å¸Ĥ +( Json +è¡Į 踪 +讲 讲 +åĪĽå»º çļĦ +Respons es +åįĬåĬŁ åĢį +_ ag +å¦Ĥ ä¸Ģ +_LO OP +ï¼Į åįĩ +ens in +la id +ra e +ãĢģ çŃī +æľī ä¿Ŀéļľ +天 åºŃ +alk er +Four th +ï¼Įä½Ĩ ä»į +æīĭæľ¯ åIJİ +ĠOrig ins +ä¸į é½IJ +ĠL au +çİĭ è´¤ +interest ed +Ġ å±ŀæĢ§ +ãĢģ éĽª +ord en +.h istory +çĤ¼ 丹 +ä¸Ń åIJ« +顾 ä¸įä¸Ĭ +ĠTr is +ĠJagu ar +Ġiod ine +L ag +-p rivate +ãĢģ èĥ½æºIJ +ä¹ĭ 女 +-c ou +ĠGl acier +Ġminim ization +Ġ' ? +Ġmult is +Ġun answered +.B ind +纵 è§Ĥ +ĠEp iscopal +Ġsurf act +I reland +ï¼Į åĩıè½» +Ġpress ured +ĠWar fare +ï¼Į æģ© +ĠBl oss +éķĩ éĿĻ +åĽºå®ļ 座 +Ġboy cott +ä¸Ļ åŁº +Ġnan os +ëĤ ĺ +çļĦ ç¾İåĽ½ +æŃ¤ ç§į +æµģ éĩıçļĦ +know ledge +um ont +Ġsc rum +çϽ çŁ³ +ĠSh arks +ĠCO LL +åľ°ä¸ĭ æ°´ +çŁŃæľŁ åĢŁæ¬¾ +Qu aternion +, this +D iamond +Pro per +Ġcoll apsing +Ġbow ed +) ä¹ĭéĹ´ +ay as +Ġprerequ isites +Ġir responsible +æijĺ ä¸ĭ +vd ots +(Q String +âĢĿ æľŁéĹ´ +âĢĶ they +yl ase +æ¢ģ æĺĬ天 +颤 åĬ¨ +åľ¨ æīĭéĩĮ +éĿ¢ å̼ +å¦Ĥ èĬ± +ä¿Ŀ ç¨İ +åįİ è¯Ń +ï¼Įå°±æĺ¯ 为äºĨ +çļĦ èµĦ产 +æľī ç¼ĺ +âĢľ Well +Prof iler +-car bon +åŃĿ æķ¬ +JSON Object +Ġenumer ated +大å¤ļ æĺ¯ +Ġ æ·± +ãĢģ åħ±åIJĮ +ç¼ ° +æ¸ħ ç§Ģ +_D ES +End points +Found er +è¿Ľè¡Į åħ¨éĿ¢ +> "; +Ġr sp +å·² æľīçļĦ +çĶ· ç¥ŀ +Te ams +ä¸ĭ è§Ĵ +ĠBow ling +çł¥ çłº +è§Ĩç½ij èĨľ +æľī å¾Ī好çļĦ +æĸĩåĮĸ 产ä¸ļ +Ġwip ing +约 åįł +.D ef +åį° åζ +Ġfall out +çļĦ æķĪçİĩ +cons istent +æ½® æ°´ +æĪĴ çĥŁ +ell as +çĪĨ è£Ĥ +Ġla ure +èĦ± ä¸ĭ +-M ay +Ġann uity +çļĨ çŁ¥ +ï¼Į æĪIJå°± +ĠJ asmine +_C AM +产åĵģ åĴĮæľįåĬ¡ +Ġcombinator ial +éĢĢ åIJİ +esc ence +S AN +Ġo asis +ac ad +åĺ ¤ +( selected +ä¸į å¹² +-b ooks +Ġrev olving +dep loy +[ R +ãĢģ 主åĬ¨ +åİ» æİ¥ +Ġsn printf +ĠLenn on +/ æľĪ +äºĮ å±Ĥ +被 è¿Ļ +_W ARN +ï¼Įå°±æĺ¯ åľ¨ +äºĭ åīį +-f ill +ï¼ĮæŃ¤ åīį +å¤ĸ交 éĥ¨ +Ġsens ed +çģĮ 注 +est i +prom pt +at ism +åĽŃ çļĦ +Ġunlock ing +ang ement +Ġcl js +α ÏĤ +_ex amples +ĠSt ereo +缴 éĿ¢ +åħ¬å¼Ģ èµĽ +| string +声 éĹ®éģĵ +D AV +åĬ Ī +ĠTh reshold +头 è¡Ķ +èĩªå·±çļĦ èĥ½åĬĽ +å½¢çĬ¶ çļĦ +Ġmetic ulously +_C F +weight ed +è´¢åĬ¡ æĮĩæłĩ +éĢĨ åIJij +Ġt iled +ym our +ĠS MTP +Ġps z +Ġк ак +ç»ı éĶĢ +ines cence +çݯ çĬ¶ +è¡ĮæĿİ ç®± +ĠN arc +Sh ield +æĭ¿ è¿ĩ +D yn +Ġrect angles +acchar ide +è¿Ļ äºĭåĦ¿ +ä»İ 她 +Ġem ph +åİŁ æī¿å¤© +åĩłåįģ 个 +Ġg ps +Ġ' '). +ï¼Į以 åħ¶ +ĠCal iforn +s uffix +We apons +Ġdispos ing +_P B +åīĶ éĢı +éªģ é¾Ļ +ãĢģ è·¯ +éĽĦ åİļçļĦ +Te en +E ase +Ġjack pots +a at +æĺ¯ ä¹Ł +å° į +âĢľ ä¸ĸçķĮ +åIJĮäºĭ 们 +(" ( +Ġmult il +ĠF raction +ĠE W +_P S +ãĤĤ ãģ® +pe aker +èĥ Ħ +åĭĴ ç´¢ +ä¾µ åįł +é«ĺ ä¸ŃçļĦ +åħ« éģĵ +CH APTER +Ġfac ulties +_A ES +åIJĿ åķ¬ +大 ä½ľ +_un stable +ï¼ĮæĹ¢ æľī +Ġanisot ropy +_ atomic +ĠS chn +Ġimpair ments +ï¼Į çħ® +ä¹Łæ²¡ åĬŀæ³ķ +èIJ¥ä¸ļ é¢Ŀ +èĢIJ çĥŃ +M d +ĠÐ ķ +æĻļ å®´ +建ç«ĭ åģ¥åħ¨ +ĠMod ular +Ġknock down +ĠPercent age +ĠBax ter +西 å±± +好 è¿ĩ +å¦Ĥ 梦 +çĶ» è´¨ +Le o +Exp ires +ĠRecommend ation +ä¾ĭ è¡Į +ç²Ĵ 度 +ï¼Į é»Ħéĩij +ï¼Įä»ĸ们 ä¹Ł +æ°¸ ä¹IJ +Ġbe ige +ãĢģ ä¼ĺåĮĸ +ĠSt eward +Wh itespace +åģľ éĿł +Min us +ĠMo ines +ĠCross Ref +Ġ---- -- +_ span +ï¼Į æijĩ +ãĢģ æľįè£ħ +å¿į å¿ĥ +f k +{ conf +Ġs con +çζ çİĭ +å¨ľ å¨ľ +Ident ifiers +, æĢķ +Ġ\ ,\ +ER G +ĠAbd ullah +J OIN +æıĴ æĽ² +.u pper +Ġw art +æĺ¯ ä¸ī +ĠF rog +Ġcan als +ç¬ijçĿĢ éģĵ +( return +çļĦ åIJĦ个 +Ġst alled +ar ab +æĭĸ ç´¯ +Ġt ame +.set State +ĠTrad ition +Bro ther +å¸Ĥ çĽĪ +Ġhasht ags +- One +ï¼Į 表 +ãĢģ é¢Ħéĺ² +ops ies +å¾Īæľī æĦıæĢĿ +B ab +交 åĩº +Ġred ness +交æĺĵ ä¸Ńå¿ĥ +g ov +Ġfantas ies +ĠL ighthouse +ĠAd a +åĨ· éĵ¾ +omet rics +_dat etime +_ peer +ï¼Įè¿Ļ å°Ĩ +æİ§åζ éĺĢ +Qu ite +æ¸ħ æĸ°çļĦ +Mat hemat +佼佼 èĢħ +ĠPOST S +ç͍ å®ĥ +ï¼ĮæĹł 人 +.un iform +. constructor +礼 çĽĴ +ĠChart ered +ĠSh ay +Ġcross ref +磨 éļ¾ +é«ĺçŃī éĻ¢æł¡ +ĠR ao +çº ¨ +arch itecture +ç¨İåĬ¡ æľºåħ³ +Rew rite +. Encode +c oder +Ġvolt ages +( option +( Player +ĠH ort +Ġex ogenous +èĥĮ åħī +æĸĹ å£« +c wd +.sub mit +ãĢĤ è¿Ļä¸Ģ次 +以 身 +ãĤ ĩ +ï¼Įåħ¶ ä¸ŃçļĦ +.M ove +Ġplastic ity +Ġdizz iness +ĠFL AGS +Ġstyl ist +H ur +åĵģ è¡Į +Ġri pen +} y +Ġ 欧 +ï¼Į å·®ä¸įå¤ļ +ac ulate +å®Ī æľĽ +举 åĮº +(B undle +屡 屡 +å¿ħ ç»ı +ĠMcC oy +_ contact +add en +è¿ľ åľ¨ +uilt in +oter ic +ĠEBIT DA +% D +è¶ħ åĩ¡ +Invest ing +Ġne aring +åħ¨ æĺİæĺŁ +_M P +Des k +. identity +T an +.d esc +ĠShe ila +.ch annels +Âł èµµ +Ġrad iative +Ġscreen play +æĿijæ°ij å°ıç»Ħ +. ctrl +管çIJĨ æľºæŀĦ +éĿĴ èĬ± +åºŁ äºĨ +Ġwid est +_ OC +â ¾ +und ance +ĠExper ienced +ä¼ļ æĽ´å¥½ +ĠJ oker +Ġbackground Color +Ġadminist rations +æĹłæĦı ä¸Ń +æĸ° èµĽåŃ£ +_p ose +( sock +çļĦ ç§ijåѦ +åľ° æłĩ +ĠUn lock +sc aled +Ġsent imental +, æ¯ıä¸Ģ +Pre paring +åħ¼ å¹¶ +B ias +d ensity +马 åĮ¹ +åĪ¶åº¦ åĴĮ +Ġul cers +ï¼Įç®Ģ缴 å°±æĺ¯ +j es +ï¼Į éĩįåºĨ +ãĢĤ å¹´ +ãĢĤ åĬłä¸Ĭ +客 å®¶ +ä»»åĬ¡ æĺ¯ +åıĤèĢĥ åĽ¾ +æķ² æīĵ +ĠI CD +erm ost +FF T +å®Ŀ 座 +_h int +è¶ĬæĿ¥è¶Ĭ è¿ij +" äºĨ +ç²¾ çĤ¼ +è¯ķ æł· +顺 å¾· +-h aired +Ġutil ise +æĹĭ éĴ® +Ġn erd +ĠT ide +åľ¨ åIJĦ +Network ing +Develop ing +, 个人 +z v +Ġ$\ {\ +R even +id in +ĠT EMP +ĠL AB +æĥħ æ·± +æ°´ æ§½ +设å¤ĩ çŃī +çľĭ æľĽ +宽 çļĦ +p hen +çĽ ħ +_f w +æłij ç§į +Ġillust rator +ĠNic aragua +ot ential +åİļ éĩįçļĦ +normal ized +çļĦèĦ¸ é¢Ĭ +åıij 麻 +Ġsurv ives +_se m +èĻIJ å¾ħ +, æ°¸è¿ľ +é£İ å¯Ĵ +åħħç͵ æ¡© +æĿij å¹²éĥ¨ +ä¼Ĭ åĪ© +top ics +Bi ography +çĶŁ åľ¨ +çͱ è¡· +æŀģ 好 +Ph ill +, éĻįä½İ +Ġs is +è¿Ļæł· äºĨ +Ġmut ate +çĿĢä¸Ģ æĿ¡ +d ust +d type +ï¼ĮéĤ£ ä»ĸ +éģµ ä»İ +æĮĸæİĺ æľº +на Ñĩ +ï¼Įåīį åIJİ +RESS ION +f ight +以 ä¸Ģ +å¨ģ æħij +æķĻ室 éĩĮ +-read able +L ie +ä¹ĭ æľī +Ġmy sq +-s core +Check out +-ch air +bound ary +! : +èı² äºļ +ro ker +op f +éϤ æİī +å¿ħéľĢ çļĦ +ĠX K +å¯Ĵ åħī +ĠCou ples +èį¡èį¡ çļĦ +H ug +å°½ æķ° +Ġreact ors +Ġmiscon ceptions +P ump +å½Ĵ æł¹ +æķij æĪij +é¡¶ éĿ¢ +ä¸Ģèµ·æĿ¥ çľĭçľĭåIJ§ +Ġenlight enment +, *) +H dr +举 æ±ī +ï¼ĮæĪij åĨį +ï¼Įéĥ½ å±ŀäºİ +ulk an +Ġskew ed +æģ £ +Ġfl ute +ï¼Įå°± 让 +Ġtable View +ĠSin clair +Ġindent ation +Ġhind i +å®Ī éŨ +ĠCant on +n ested +æıIJ éĢŁ +ï¼ĮæĪij ç»Ļä½ł +红 æľ¨ +ä¸įè¦ģ èĦ¸ +çļĦä¸į 满 +ĠC oh +æĪĸ å¤ļç§į +çĩķ 麦 +Dep osit +èĬĤèĥ½ åĩıæİĴ +èķ¾ ä¸Ŀ +Ġlong standing +Ġfer ment +, 女 +[ count +å¾Ī è¿ij +Ġair y +Ġopp ressed +Ġat l +âĢľ è¿Ļæĺ¯ +ç«ĭ æĹ¶ +çİī 佩 +Ġdis belief +ï¼Įä½Ĩ åĽłä¸º +-d im +éĢĢ åĮĸ +ĠBel lev +å¹½ å·ŀ +Ġsac ram +ï¼Į æµĭè¯ķ +Ġorigin ality +_READ Y +ĠScar let +èĥ½å¤Ł å®ŀçݰ +ãĤ·ãĥ§ ãĥ³ +åľ¨ä¸Ģèµ· äºĨ +Ġast roph +Ġ 人æ°ijå¸ģ +ĠEntreprene urs +ĠHond uras +åı¯ è´µ +_def inition +.u uid +Ġparam et +ĠTime Unit +Employ ees +W oman +ãĢĤ èĩ³å°ij +Autom ation +ĠT U +ãĢģ æľ¬æ¬¡ +Ġ æĸ¯ +ï¼Į å¤Ħå¤Ħ +Ġout field +åħ¨ èģĮ +_B IND +çĥŁ å°ĺ +Ġr idden +å°± å¦ĤåIJĮ +am ines +ä¸į ä¸į +ä¸Ĭ èħº +è¦ģ 为 +Ġqual ifier +ä»İ éĤ£ +ï¼ĮæĪij ä¸įèĥ½ +Ġc aste +Ġv ä +éŃĶ å¥³ +ĠUp coming +ĠSi oux +Ġt n +Dis connect +Ġl apse +ä¹ĭ æŃĮ +ç§» å¼Ģ +çĹĽ æ¥ļ +Ġoat meal +ĠD egrees +设 äºİæīĢè¿° +æ·±åħ¥ äºĨè§£ +ĠPed iatrics +ĠOE CD +Ġ æīĢå±ŀ +ï¼Į èĦijè¢ĭ +çļĦ çIJĥéĺŁ +ä¸ĭ è¿° +åŃ¦æł¡ éĩĮ +ä¸Ģ ç´§ +ĠU i +è¯Ĺ è¯Ń +éĿłè°± çļĦ +åľ¨ å½ĵæĹ¶ +çļ® åį¡ +ĠPh ones +ï¼Įå®ĥ åı¯ä»¥ +A qu +以 èĩ´ +ĠNe ptune +æĭī æĭ¢ +Ġshut ters +Ġs vc +ï¼Į è§ĦåĪĴ +è̳ é¼» +éĿĴå¹´ æķĻå¸Ī +???? ???? +Âł K +Ġdec ipher +ÃŃ m +Ġì Īĺ +.b g +Confirm ation +Ġtrans ports +.t oggle +ä»ģ æħĪ +- vector +ç¨Ģ ç½ķ +ĠD ane +ä¹Łä¸į å°ij +âĢĺ I +ĠT bsp +ï¼Įä¸Ģ 人 +Hand les +Ġinterview er +Ġcyt ometry +, ç§° +-ind ust +åıijçĶŁäºĨ ä»Ģä¹Īäºĭ +è¶³ é¢Ŀ +ĠÑģ е +iv as +Lo an +Ġtransl ucent +ĠMont erey +çļĦä¸Ģ åı¥ +è·ij çļĦ +cover ing +ĠS napshot +ä»ĩ 人 +Ġpy ram +. Player +Ġ 建çŃij +ĠKnox ville +ä¸į åģĩ +åı¯ åĮħæĭ¬ +Ġso othe +In coming +åĶIJ æģ© +æī«é»ij éϤæģ¶ +Ġra ke +co eff +Ġcommun ion +ĠInd o +éĶĻ æĦķ +Ġfac ie +严 å®ŀ +oph ilic +å®ŀæĸ½ ç»ĨåĪĻ +å±ħä½ı çļĦ +é£İ å°ļ +çĶŁæ´» è´¨éĩı +ãĤ ½ +åĪĿå§ĭ 确认 +çĶŁ æĢķ +ä¸İ æŃ¤ +åıĹ è®© +éļı身 æIJºå¸¦ +ĠLump ur +en ants +æľĢ å¼Ģå§ĭ +èĦļ å°ĸ +vey ard +Ġconce ivable +身 æĺ¯ +çͲ 级 +æĻ´ æľĹ +鸿 竳 +æ®´ æīĵ +r ants +åı Ł +è¨ » +ĠMad onna +ä¸įåı¯éģ¿åħį çļĦ +Ġn ombre +ä»ĸ æīį +ĠRock ies +mond s +Ġl w +Ġtall est +ĠRose mary +ĠActive Record +Ġ// !< +.M IN +ellig ent +p redict +ï¼Į é¢ľ +Ġam alg +å¢ŀåĬł çļĦ +ĠEconom ist +çĿģ çľ¼ +S ara +ä¹Ł å¿« +ins n +log ue +èı ı +(b uild +r asing +ĠM k +ãĢģ çīĪæĿĥ +per se +æĺŁ æ²³ +.b asic +ĠL och +è·Į åĢĴ +- Re +Ġ é¢ľ +_D OC +ìĿ ¸ +ĠT k +.f ast +é¡¹çĽ® åĴĮ +Ġ? , +浸 润 +ĠS overe +ĠL id +åĬ© åīĤ +-f ound +æĿĢ èĻ« +å¹² åķ¥ +Text ures +Ġbi ologically +Ġpain fully +ĠBlue print +.ab spath +H ung +ĠM ansion +Ġcon co +Ġro ar +ax e +Ġtax onomy +å¢ĵ ç¢ij +_ext ensions +(std out +ï¼ĮæĪij们 æĺ¯ +ãĢģ çͱ +èĨĿ åħ³èĬĤ +L ic +ãĢģ çĽijçĿ£ +æĬĹ äºī +AND S +Ġglam our +ĠJ B +该 æł¡ +Sub tract +_PL AYER +ï¼Į æ¡ij +æīį æĻº +è¯Ń å½ķ +Rec over +ĠRO CK +ĠCh im +åħ± ç͍ +çļĦé«ĺ 温 +åĪĽ ä¸ĭ +-f in +(l abels +ĠLO CK +ä¸įä»ħ æľī +çIJ³ çIJħ +没æľī åľ¨ +_s i +.R ange +æijĴ å¼ĥ +ind uced +.j sp +å±ĭ æªIJ +ĠSmart phone +UIT ableView +Check sum +èį ĥ +æİ¨ æĭī +æµĩ 注 +çĿĢ è¿· +æĶ¾ çľ¼ +_re v +åĭº åŃIJ +. geometry +人 æĢ§çļĦ +æŃ£ æŀģ +èĦij çļĦ +Ġord ained +ç«ĭ éĿ¢ +q w +Ġ å®Ŀ +ĠL evin +åį¡ åĿĹ +_default s +Ġpatri otic +Ġbios ynthesis +_b order +æ£ķ æ¦Ī +f ault +, 两个 +çļĦ åİļ度 +è¿Ļ个 æĹ¶ä»£ +-h it +Ġmistaken ly +åħµ æ³ķ +Ġ åŁİå¸Ĥ +åĨĽ éĺĢ +Reg s +èĩªçͱ è´¸æĺĵ +åĩº ç¥ŀ +_d i +è res +ĠSiem ens +ï¼Į å®ļä½į +ĠJ VM +åį¡ æī£ +祷 åijĬ +ï¼Į åħħ满äºĨ +åĬ¨ äºİ +æ¯ı ç§Ĵ +èµ¶ èµ´ +æĺı æĺı +. he +æĺ¥ 鼨 +/ ms +ä¸į æĢ¥ +è° Ł +温度 ä¼łæĦŁåύ +number Of +/ compare +Ġapprent ice +er ph +è¿ħ åĭIJ +Ġshoot ers +Luck ily +print ln +ĠTrans former +æķĻèĤ² èµĦæºIJ +ĠWH Y +g ies +å¦ ² +Ġ éĩĮ +Ġ åħ° +ĠU ID +æĺİç¡® è§Ħå®ļ +Ġoverr uled +Ġw char +here inafter +IS PR +ĠGood reads +ç° Į +å¤ļ å¤Ħ +ĠGreen ville +Ġadorn ed +Ġmor als +op ies +è´¹ åĴĮ +Ġrandom ness +all ah +Ġorbit als +V ice +æĪij ä¸Ģ个人 +çİ© å¼Ħ +ĠDH CP +ãĢĤ æĺ¨å¤© +ĠCh ances +å¸Ĥåľº çĽijçĿ£ç®¡çIJĨå±Ģ +ï¼Į竣 æĺ¯ +PERT IES +ĠISS N +Ġ å½ĵåīį +æĹł èĥ½ä¸ºåĬĽ +Is Valid +è¿Ļ座 åŁİå¸Ĥ +comput ed +z f +ä¿¡æģ¯ æľįåĬ¡ +Ġset Value +Th om +_b and +Ġont ology +ä¸į æħ¢ +ä¸Ń åįĹ +é² ² +Ġmel ts +ä½ł æĺ¯åIJ¦ +èµ° ä¸ĬäºĨ +çIJĨå·¥ åѦéĻ¢ +ï¼Į ä¾ĿéĿł +ä¸Ģ æ°Ķ +p ipeline +ï¼Į ä¾Ŀæīĺ +èĤ¾ çĹħ +Ġ é»İ +ort e +ï¼Įä¸Ģ 群 +æŀĹ åŃIJ +èĤ² èĭĹ +çŃij åŁº +FA ILED +T v +åľ¨ 为 +Âł J +AB I +Ġge ographically +äºĮåįģ ä¸ĩ +èµļ äºĨ +ï¼ĮæĢİä¹Ī èĥ½ +Camb ridge +ĠMaced onia +will Return +Ġ ä½İ +èµĦæĸĻ æĿ¥æºIJ +, å§ĭç»Ī +r na +Ġ} č +av ir +æĺĵ 失 +æĭ¼ åij½çļĦ +çļĦæĸ° é²ľ +Order ing +-date picker +) c +ĠI cons +æĪij ä¹Łä¸įçŁ¥éģĵ +ï¼Ī åħ¶ä¸Ń +æķĻ æĪij +粤 港澳 +Ġirres istible +à± į +_ archive +Ġ æĥ³è¦ģ +èIJ¥ æķij +ĠParam ount +ï¼ĮéĻĪ åĪĿ +olog ue +( initial +L iquid +Ġbe ware +éļ¾ ä¸įæĪIJ +碧 æ¡ĤåĽŃ +amer ican +èĬŃ èķ¾ +æĮī è¦ģæ±Ĥ +æĸĩ竳 çļĦ +ĠMand arin +ĠOFF SET +Ġhemorrh age +ĠW ants +ï¼Į她 å·²ç»ı +ãĢĤæĪij å¸ĮæľĽ +éĴ± å¸ģ +讨 ä¼IJ +ï¼ĮæĢ» ç»ĵ +-gu ided +T int +{ and +Ġ åŃĹ +ĠDe legate +çľĭåΰ æĪij +ï¼ĮæľĢ 大çļĦ +Foreign Key +ĠD HS +åĨħ æĸ¯ +空 åľ° +Ġworld ly +Ġfinal ist +leg round +åıĽ åĨĽ +ĠCHAR ACTER +ä¸Ĭ è¿ĩ +æĹ¶ ä¹Ł +Ġj ot +Ġcare less +ĠCou ple +Ġequip ments +æĺĵ çĩĥ +( height +Res erve +Ġapolog ized +éĦĻ å¤· +ĠR azor +Ġded uced +ï¼Įä»İèĢĮ 导èĩ´ +ĠPros per +è´¨ æľ´ +Ġ æİ§åζ +Ġd ab +ä¸Ń åı¯ä»¥ +-d em +åİ¿ åŁŁ +å·¨ èŁ¹ +zz y +ç§»åĬ¨ ç»Ī端 +详ç»Ĩ æııè¿° +ãĢģ åĴĮè°IJ +éĺµ éĽ¨ +çĿ¡ çļĦ +Scroll View +è¿ŀ äºij +ĠBund es +ï¼Į åѤ +ĠE cosystem +Ġli ar +éĿĴ å¹´çļĦ +Ġoverw ritten ++ A +èĢĮ éĢĢ +Ġfor ks +åĪĴ å®ļ +ĠAppli ances +st ab +æīĵ æĿ¥ +ç¥ŀ åºĻ +.M ouse +High ly +è¿ľ 大 +/lib s +Ġattenu ated +. vector +红 润 +çĪĨ åĩº +çļĦæīĭ éĩĮ +ĠM SE +ä¼ļæľī ä»Ģä¹Ī +Ġunfold ed +)) ). +åĪĹ ä¼ł +ä¸ļåĬ¡ æĶ¶åħ¥ +CG Float +e ffective +ãĢĤ 书 +ãĢģ åĨ° +å®¶ æķĻ +æĹł æ±Ĥ +ĠLex us +ter ies +åIJĥ èĤī +Ġsequ enced +详 å°½ +Read able +, åݻ年 +ãĢĤæĪij çĽ¸ä¿¡ +ç͵åŃIJ çĥŁ +央 ä¼ģ +æĿľ åĩ¡ +Ġrheumat oid +ĠB UY +她 è¿ĺ +ç¬ij éĿŀ +ĠAss ad +Ġcovari ates +ch airs +åľ¨ ä¸ĸ +ĠV ita +åĦ¿ 媳 +æĹ¶åĢĻ çļĦ +h ya +ord ial +头 缮 +åįĹ åİ¿ +éŀ ij +å¾Ĺ 主 +Ġsub ordinate +ĠBel ize +Ġout burst +ç»´ ä¹Łçº³ +ï¼Įæĺ¯ 为 +ch ol +没 å®Į +éĴī åŃIJ +CLUS IVE +æ¿Ģ æĺĤ +æľīåħ³ æ³ķå¾ĭ +, 缮æłĩ +F ULL +è¦ģ 好好 +è¿Ļ个 è¯Ŀé¢ĺ +Imp orter +åĩ»è´¥ äºĨ +Ġ 鼨 +_S S +Ġsymmet rical +Ġincent iv +- utils +ĠE H +Ġall otted +LO VE +ä¸į 缺 +Ġthere on +便 å¼Ģå§ĭ +æ±Ł æ°´ +æĺ¯ä»Ģä¹Ī æł· +åĸ· æ¼Ĩ +ĠChem icals +Ġtransl ational +ç½ij è´· +arr ays +light ing +ï¼Į åĩı +ä¸į ç®Ģåįķ +é£ŀ äºĨåĩºåİ» +人们 çļĦçĶŁæ´» +-n ine +ald i +个 åŃĹ +ä¼ļ 带æĿ¥ +Ġexp orters +ĠHel d +åĩ¯ æĹĭ +èī° å·¨ +ÑĨ иÑı +ĠOver night +ĠAud rey +res erve +éĩį å¡ij +æĤ¬ æŀ¶ +ĠZ ombie +Book ing +ĠQuick ly +-pres ident +Y W +rom yalgia +åIJİ åıijçݰ +olog ne +Ut ah +ï¼Įä»ĸ ä»İ +ĠRe ject +ĠHy att +æ¸Ĺ åħ¥ +ä¸į èĭŁ +åĴĮ èĥ½åĬĽ +ï¼Ľ åı¦å¤ĸ +ĠCont rary +Hon estly +Ġpatri arch +B arn +Ġk lass +Ġ: ( +åıĹ伤 äºĨ +h omes +ĠT LC +(p oints +Ġdeg rade +ĠSign als +Ġclim atic +P ermanent +å¾Ĺ çĿĢ +class ification +æĹ¶ æīį +åıijå±ķ åīįæĻ¯ +ĠPo ems +åıij çĤİ +è¯ģåΏ æ³ķ +大éĥ¨åĪĨ çļĦ +éĢļè¡Į è¯ģ +ĠDET AIL +ï¼Į èĭį +Ġre agents +åĴĮ 缮æłĩ +æ·± éĢł +.st atic +Ġbrut ality +{ }\ +hes ive +Ġp ups +ĠM ILL +Ġacc ru +ç²¾åĩĨ çļĦ +ĠAnglic an +Ġ åĨ° +Ġto ppings +æĽ´ ä½³ +ĠNo on +ĠRE P +Ġpra ises +Ġves icles +Ġnotor iously +Ġh oo +åįķ æľº +ç¼ĵç¼ĵ åľ° +ĠAG N +ĠS ind +天 大çļĦ +ĠPS I +ĠV ul +çŃī 她 +广 大çļĦ +çĶ· æĸ¹ +(f lags +åĽĬ æĭ¬ +Ġuniform ity +åºĶ åıĬæĹ¶ +çŀ¬éĹ´ å°± +躲 è¿ĩ +Ġreservoir s +Ġabbrev iated +/w rite +ĠTrou bles +çĤ¹ åIJį +Ġret in +ĠS VM +ĠY osh +ĠCal dwell +ãĢĤï¼Ī ãĢĬ +Ġmisunderstand ings +ãĢģ 许 +åĴĮ 家人 +Ġhand crafted +ç¿ ± +ĠEn emy +ä ll +Dat um +èµŀåIJĮ åħ¶è§ĤçĤ¹ +ÂĢÂ Ļ +, é¼ĵåĬ± +è½ ¶ +ĠY og +Ġx range +Ġmed itate +TM LElement +.Null able +Ġthin ning +æĸŃè·¯ åύ +key board +File Sync +Ac ross +åģ¶ éģĩ +åıĺé¢ij åύ +Ġa ft +Ġp und +Ġsh util +Ġdr ifting +ï¼ĮæīĢ以 ä»ĸ们 +Ġrad ians +( Array +æ°´ 溶液 +Pro x +ï¼Įä½Ĩæĺ¯ æĪij们 +身ä½ĵ çĬ¶åĨµ +ĠLad en +ä¸Ģ带 ä¸Ģè·¯ +ë ° +âĢľ With +ä¸ĭ æĸĻ +带 ä½łåİ» +Ġhappen ings +cast s +-F riendly +S essions +å®¶ ä¸ŃçļĦ +ï¼Į èµĦéĩij +ĠT aco +æĹ¶ åľ¨ +èįī åľ°ä¸Ĭ +åŁ¹è®Ń åŃ¦æł¡ +op code +å¤ĸ åĬł +td c +ï¼Įé«ĺ 级 +ĠTah oe +ĠMon k +opl an +олÑĮ з +çĶ ¬ +Ġsettings ACCEPT +Ġalert ed +æľ« å°¾ +Ġsom atic +åĪĿ ä¸ī +ï¼Į被 èªī为 +ĠPal o +èĦĬ æŁ± +ä¸į ä¸İ +Ġv engeance +Ġrest ricts +ç´« äºij +program s +è¿ĩ çĺ¾ +Ġsm elling +ĠAr r +éļı åIJİçļĦ +S Z +ä¸įä¼ļ 对 +ĠWould n +Ġcath olic +åģļ äºĽä»Ģä¹Ī +稽 æŁ¥ +ï¼Į åĭIJ +çļĦ ç»ıèIJ¥ +as ions +Ġse cluded +èĩª åĺ² +åłµ ä½ı +ç»´ æĭī +Ġred o +åijµ æĸ¥ +Ġ 欧洲 +å°ij å°Ĩ +ç»Ŀ åľ° +OUR N +两年 åīį +éĿĴ å·ŀ +um as +// ---------------------------------------------------------------- +æĹł æļĩ +HA HA +' = +Un used +å¢ŀåĬł å̼ +Ch ocolate +Ġser a +Ġgly cos +åħ¬ çĦ¶ +hern et +æĢĴ éģĵ +åŁºéĩijèµĦ产 åĩĢå̼ +Ġfl ips +Ġtheat res +ãĢģ éĢīæĭ© +Ġunn atural +çŁ Ĺ +è¾¾ æĪIJäºĨ +H ousing +it ius +ĠY ong +è¶ħ çŁŃæľŁèŀįèµĦåΏ +é¥Ń åIJĥ +Hash Set +ilden afil +她 没æľī +Ġbehav ed +åIJ¬è§ģ äºĨ +ĠN ex +ο ι +ç쵿ķı 度 +Ġs ling +Ġst ren +ï¼Į æī¶ +åľ¨ ä¸Ģ次 +Ġbr as +åºĹ éķ¿ +ĠSou ls +讥 讽 +at ters +ï¼Į å·¥ç¨ĭ +æĹħ è¡ĮçļĦ +Red ucer +ig mat +ä¸į æĺİæĺ¾ +åĴĮ ç½Ĺ +inst ant +ĠBel ief +ï¼Įæ°Ķ åĬ¿ +ä¿ĿæĬ¤ èĮĥåĽ´ +ĠMidd leton +âĢľ ç¥ŀ +为 代表 +财产 å®īåħ¨ +ĠI MD +ç´§ 身 +ĠRE QUIRE +ol vers +æľī æĪij +éĩij é»Ħèī² +eng ed +çļĨ 为 +åIJ¹ é£İæľº +ĠMist akes +èĬĬ èĬĬ +. Stat +ï¼Į 鸡 +缮 ä¸į +ãĢĤè¿Ļ ä¹Ł +åIJIJ è¡Ģ +-trans fer +; n +ĠB MP +ĠThe oretical +Ġgl omer +ch s +èĢĥ çĶŁçļĦ +Ġshel ving +. section +ĠB alls +.m onth +Ġenact ment +æµ· æ¹¾ +AC ç±³åħ° +P Q +b ones +å¹¶ åŃĺ +éĻĨ ç¾½ +Ġroot ing +æŃ¤æ¬¡ æ´»åĬ¨ +è¿ĩ çĥŃ +ï¼ģ âĢĻ +æ¶Ī çĺ¦ +Ġtax ing +åģ· æĩĴ +Min nesota +ĠDeterm ines +ĠHus sein +ä¸İ éĿŀ +ï¼Į以 éģ¿åħį +å¢ŀåĬł é¢Ŀ +æ´ŀ 天 +el ike +缸åħ³ æĢ§ +Ph y +ĠInvest igator +wait ing +_END IAN +Ġdens ely +ME A +ï¼Į å¢ŀ +Ġcl ipped +RE A +ï¼Įä¸Ģ çľ¼ +ä¸ĢåĬ¨ ä¸įåĬ¨ +>? [< +ĠSear ches +gr unt +INT RODUCTION +.b i +åĩºåħ¥ å¢ĥ +é¢ģå¥ĸ åħ¸ç¤¼ +as eline +åIJĽ çļĦ +ĠBuck ingham +å¹´ 年度æĬ¥åijĬ +å±ŀ åľ° +ä¹ĭ åij½ +ric ula +æľ« æľŁ +v acc +it ä +æĻº åºĵ +Ġfoot note +.get Parameter +èµı æŀIJ +ĠCong rats +ä¼łéĢģ 带 +Incre ased +ĠHarm on +yst ic +åī§ éĽĨ +åIJ¯åĬ¨ äºĨ +ĠMass ive +our d +ĠN ay +And rea +Ġsh ard +Ġsc ot +è¾¾ æĸ¯ +åľ° çľĭäºĨ +cc s +ï¼Įåľ¨ éĤ£ +ï¼Įæīį èĥ½å¤Ł +èĤĸ æĪĺ +_ clip +Ġb tw +ãĢģ å®Ŀ +éħĴ é¦Ĩ +æ°´ å¤ĦçIJĨ +Ġet a +æĿij éĩĮçļĦ +åĩºä¸Ģ èĤ¡ +çªĿ éĩĮ +ep am +Ġfl ax +HE ME +ĠBoy le +æĮĤäºĨ ç͵è¯Ŀ +Pix map +, but +åIJij éĺ³ +M ISSION +ĠB U +- vis +ä¸Ģ个 æĺŁæľŁ +åŀ ł +.l abels +ĠBeth lehem +d bl +æľī åij³ +`` , +Ġunf olds +ĠJo anna +åĺ¿åĺ¿ ä¸Ģç¬ij +ĠKath ryn +/ CD +ĠC CS +æĪIJ 群 +Ġunder cover +.S canner +Ġpolit ely +_ins n +鸦 çīĩ +M j +ä¹ĭ éķ¿ +á rio +ĠWar wick +Ġhint ed +Ġrh in +Ġ---- --- +o ine +Ġw b +æłª æ´² +Contin uing +, sizeof +Ġe j +ĠConnect ing +Market s +n oreply +Ġ iced +说 ä¸Ģåı¥ +Ġvis ibly +ĠG TX +æ¿Ģ èį¡ +Ġthin ly +Ġ å´Ķ +å°Ķ åħĭ +综 è¿° +Good s +ï¼Įè¿Ļ éĥ½æĺ¯ +建 æ¡£ +ier o +Ġgl itch +Ġharmon ious +åIJĪ ä¹İ +Ġrec ol +æĺ¯ä¸į éĶĻ +说äºĨ ä»Ģä¹Ī +Ġ ile +åIJ¬ ä¸įåΰ +èĩªå·±çļĦ åĬĽéĩı +_H TTP +Ġcompl ies +_DOM AIN +com mercial +Ġac cl +ÙĬ ÙĨ +ĠTur ks +Ġ åĵªæĢķ +Ph p +BT W +r iment +Comp ressed +æĿ¯ ä¸Ń +Ġperipher y +ĠO pc +ĠSim one +ç¥Ī ç¦ı +à¥įठ° +. figure +ä¸ĭ èĤ¢ +K ick +è¶ħ é¢Ŀ +ĠSub mitted +ï¼ħ ï¼Ľ +æ±IJ èİŀ +Ġend lessly +Ġgl acier +å¹´çļĦ åİĨåı² +ĠK aj +éĩij çŁ³ +sub mitted +æľ¬å®ŀç͍æĸ°åŀĭ æ¶īåıĬ +Ġprohib iting +-s ale +Ġdri pping +å»¶ å±ķ +-M ar +ä¼łæĿ¥ ä¸Ģéĺµ +Ġit ch +ĠH ospice +Ġwor sen +ï¼Ł åı¯æĺ¯ +ĠZimm erman +Ġint rins +.m emory +Ġallow ances +çģ« èħ¿ +éĴ¢ åİĤ +åĶIJ å±± +æĭ¿ ä¸ĭäºĨ +ĠMin erals +ACH ED +ï¼Ľ æĪĸèĢħ +.n on +诺 åŁºäºļ +_MAG IC +æĿ¥ åĪĨæŀIJ +.d w +, çļ®èĤ¤ +B ible +åΰ ä»ĸçļĦ +ç¹ģ æĿĤ +Ġsecret ed +ĠRe iki +ĠRe eves +æľīä¸Ģ çķª +Ġcar avan +åĪĽä½ľ çļĦç½ij绾å°ı说 +çĽİ çĦ¶ +. Bytes +. rule +è®°å½ķ çļĦ +对æīĭ çļĦ +P ASS +ĠT ight +_F AST +åľ¨ æŁIJ +çŃī éĥ½ +ĠH ak +å¤ļ ç͍ +大 å¨ĺ +B illy +ï¼Ī ä¸Ĭæµ· +,å¹¶ ä¸įæĺ¯ +ĠTr udeau +åĵĪ å¼Ĺ +pl s +éĩį ç½® +çα ä¸İ +çļ® æ¯Ľ +ĠVal erie +Ġrib bons +all ax +pl l +T orch +Ġcough ing +ãĢģ åζ +çŃ µ +ä¹ĭ èĭ¦ +第 åįģåĽĽ +PACK AGE +.get Column +æĹ¢çĦ¶ æĺ¯ +æĻºæħ§ çļĦ +ĠFlo res +ä¸į éĢĢ +ãĢģ éĩį大 +æľī 礼è²Į +âĢľ To +... ( +Ar senal +象 çīĻ +н ик +on ance +Ġz ig +.App ly +ï¼Į ä¾Ŀçħ§ +âĢľ åħ¬åı¸ +Ġle aps +缸 çīĩ +ĠTr ash +æĴѿ; åύ +ĠDiam onds +ĠRoy als +H UD +æĹł æŃ¢ +Ġtrans porter +IS D +Byte Buffer +è·¯æĺĵ æĸ¯ +åĨ¬å¥¥ ä¼ļ +. xyz +Ġd rowned +ãģ ¹ +æİ¨ åĬĽ +Private Key +/ module +ĠAr ithmetic +åĨ³ æĸŃ +è¿Ļä¸Ģ éĹ®é¢ĺ +Ġhor rors +ĠCru ises +asm us +ĠE in +ï¼Ł èĢĮ +Ġwork station +[' _ +Ġ æĽ¾ç»ı +Ġcaus ation +浪漫 çļĦ +缴 è§ĤçļĦ +ä»ĵ ä¿ĥ +ï¼Įåıį 对 +Ġnarrow ing +Ġshield ing +Ġpe eling +ç¬ij åijµåijµ +orph ous +_red irect +ì ĥ +ox ins +Execut able +ĠLoren zo +wit ness +ĠRef lections +ĠDeep Copy +å¹¶ éĢļè¿ĩ +åĪĨæŀIJ ä¸İ +çĤ® åħµ +Ġiter able +) .. +Ġmoistur izer +çļĦ éħįåIJĪ +åĪĨ æijĬ +宣 æ³Ħ +ä¸įå¾Ĺä¸į æī¿è®¤ +| > +太 æ¹ĸ +Rep air +fin ancial +æľĢæĸ° 竳èĬĤ +ãĢĤ å¾Ĺ +ĠC CR +岩 æµĨ +,åı¯ä»¥ 说 +Ġpunch ing +Ġg imm +ah s +è¿ĻäºĽ äºĭ +缸åħ³ èģĶ +èĶ º +/// < +ĠM ention +æľį äºĨ +Ġobject ForKey +ãĢĤ åįģ +Âł èIJ§ +ĠK nee +ï¼Įä»ĸ éĥ½ +.Att ributes +ï¼Į çī© +Ġat ypical +æľ¬ 宫 +没æľī åħ³ç³» +管 åŃIJ +ä¼ĺè´¨ çļĦæľįåĬ¡ +sp here +çĭł æĬĵ +ç²® æ²¹ +_ip v +æĪij 以为 +马 è¹Ħ +Ġrest orative +çļ± èµ·äºĨ +ï¼Įè°ģ çŁ¥ +Ġrecall ing +Ġtrans cribed +ç®Ĺ çĽĺ +ĠT ata +éĥ¨åĪĨ åľ°åĮº +éª ¥ +Te a +å¿ĥçIJĨ åѦ家 +Ġ çͲ +å½Ĵ 宿 +ĠInstall ing +ï¼Į åºĦ +åĴĮ æıIJé«ĺ +aps ible +Ġprejud icial +Ġloc ator +Ġescal ation +ç¥Ń åĿĽ +ĠKurd ish +Ġab orted +æĸ° æĶ¿ +.f oo +ĠFl av +æ¿ĢåĬ± 对象 +åīį ä¸Ģ天 +æĻ®éĢļ åIJĪä¼Ļ +ĠCrit ics +ol st +Cons ent +Ġµ g +ï¼Įä¸į论 æĺ¯ +ãĢĤ èIJ§ +Ġpersu asion +çľĭ è¿Ļ +AD V +Ġslic ing +âĢĿ - +-n ote +æŀ¢ å¯Ĩ +å¨ģå°Ķ 士 +æĬĵç´§ æĹ¶éĹ´ +N BC +âĢľ å½ĵçĦ¶ +Che f +: string +Ġl inem +ĠTown s +r isk +ï¼Ī åľ¨ +ĠSe vere +_T C +ĠTest imonials +Dir s +Ġast rolog +Ġf intech +ĠSt im +æľ¬ é¢ĺèĢĥæŁ¥ +ath ione +Ġcontent ious +ĠCrim son +Ġexert ed +Ġcl aws +ĠY AML +br ate +c apture +举 ä¾§ +, å¾Ī容æĺĵ +ĠB uh +ident ly +åĮĹ å¹³ +æľįåĬ¡ 端 +.j boss +æĭĽ äºĨ +Ġconc ave +åĽŀå¿Ĩ èµ· +俯 è§Ĩ +ĠShut tle +ï¼Į æĪIJéĥ½ +mer c +Ġ_ ( +篮 ç½ij +弯 è·¯ +çº £ +ï¼Įåľ¨ ä»ĸ们 +èħ ± +Ġmag ically +åĩº åIJįçļĦ +é«ĺ ç´łè´¨ +Ġemerg ent +æ·ij 女 +ĠL yme +红 é¢ľ +found land +al us +éĥ¨åĪĨ æĺ¯ +fe at +ä¸Ĭä¸ĭ 游 +Ġantit rust +· ÃIJ +礼 åłĤ +ا د ++ v +Ġv oxel +-c ig +æĸĩèīº å¤įåħ´ +çļĦ å®ŀçݰ +Ġ! !! +Ps alm +< & +ï¼Į è´º +Ġin ks +Ġd j +Ġhe reditary +ĠZ ap +å¿«éĢŁ åľ° +æİ¨åĬ¨ äºĨ +ãĢĤ ç͍äºİ +Ġdorm ant +S cores +® , +/ edit +为 ä¸Ń +ä»į å°Ĩ +μ g +ä¹ī å·¥ +乡 åľŁ +稻 çͰ +å¹³ ç§» +æķ Ŀ +Ġeurope an +Ġnont rivial +db g +ĠTh ou +èIJ¥ä¸ļ éĥ¨ +é¢Ħ示 çĿĢ +ç¥ŀ åĬĽ +ãĢĤ åį¡ +论 çĤ¹ +æĤ¨ åı¯ä»¥ +åĩı çģ¾ +-re li +Ġartis ans +Ġin quired +ĠE MT +å°½ æľī +ä¸Ĭæµ· è¯ģåĪ¸äº¤æĺĵæīĢ +ç¼´ åŃĺ +ä¸įåı¯èĥ½ çļĦ +èĢĮ åĿIJ +æ¯Ķè¾ĥ å°ı +åѦçĶŁ 对 +çīĽ æ´¥ +ĠAM L +ĠTrin idad +缸 è·Ŀ +æİ¥ äºĨ +CA DE +John ny +en ia +ä¸Ģ æ¡Ī +Ġattain ment +ĠH anoi +Ġhas hes +ee z +ĠPand ora +ãĢĤ åĪļæīį +躲 éĹª +/r hs +Ġserv o +. They +åħ¥ 宫 +表 象 +rest art +ĠSem antic +% @ +åħΠ驱 +Ġexp elled +åĴĮ èµĦæºIJ +Ġch atter +) åıĬ +ï¼Į éĩijå±ŀ +åΰ æĪij们 +Ġenforce able +ĠDEV ICE +æ¼Ķ çļĦ +éĵ¶è¡Į åŃĺæ¬¾ +gl ut +ĠMal awi +Ġlin ers +. loop +N ich +ï¼Į æ²³åįĹ +æ¯Ķ è¯ķ +æĶ¾ 纵 +æij ģ +_M ASTER +ï¼Įå¾Īå¤ļ 人éĥ½ +èµ°äºĨ è¿Ľåİ» +åıijçĶŁäºĨ åıĺåĮĸ +ĠLy ons +Ġpilgr image +æııè¿°çļĦ å®ŀæĸ½ä¾ĭ +ãĢģ èĭ± +ï¹ IJ +Ġch al +a ise +ĠPl ays +Ġbi ometric +_num bers +ĠItem Stack +Ġsel enium +åѦ è¿ĩ +ix ing +ĠTut or +ĠP yth +(c ursor +Uk raine +èĢIJ ä¹ħ +ï¼Į éļIJéļIJ +个 èĭ¹æŀľ +å°ı éĥİ +Ġcar c +åıijçݰ éĹ®é¢ĺ +æ°§åĮĸ éĵĿ +.Field Descriptor +Ġ æ±Ĥ +author ization +оÑĤ оÑĢ +å®ģæ³¢ å¸Ĥ +æĪij åĨĽ +æīĢä½ľ æīĢ为 +åĨ· äºĨ +åºĶ该 å°±æĺ¯ +ĠTen ant +Ġc airo +ï¼ļ âĢĿ +ä¸İ 伦 +ãĢģ P +ĠK uala +ĠPhot ograph +th in +Ġex position +led ger +åı· åĴĮ +Mill iseconds +Ġaster oid +åĪĨ ç»Ļ +ä¹ĭ æĽ° +ï¼Įä¹Ł ä¸įçŁ¥ +失 æģĭ +åı¯çα çļĦå°ı +ĠPhill ies +C arp +x or +æĬ¬ çľ¼ +(B uild +èݹ èݹ +ãĢĤ åĸľæ¬¢ +å°ij 主 +åIJ¸ çĽĺ +Ġlod ged +Ġinsult ing +éĩį æ¸© +èĩ´ çĹħ +Ġsepar able +H ang +Ñĥ м +reat er +ï¼Įä¸Ĭ å¸Ĥ +åij¼åIJ¸ éģĵ +_att ach +" M +: ä¸ŃåĽ½ +éĩį æķ´ +-in clusive +Ġtilt ed +ĠP ty +è´Ł æľī +Ġd avid +Ġ' :' +ï¼ĮæīĢ以 å°± +ĠR out +èĩªå·± æľī +åıĹåΰ çļĦ +ĠRub in +Ġadip ose +Ġle th +éģĵ éģĵ +Up dating +Elect rical +缸 è§Ĩ +ãĢĤæŃ¤ åĪ» +ï¼Į éħĴåºĹ +Ġbe gged +Ġair ing +Ġgarn ish +ol ite +çĭ¬ æľī +ĠHay den +Ġ ä¸Ģ缴 +éĺ³ çĹ¿ +Ġaud ible +ĠPROC ESS +Ġepidem iological +ç»ĵæŀľ 为 +F allback +h igher +éľĢæ±Ĥ éĩı +æ°ı æĹı +Ġerr ands +åİĭåĬĽ 大 +ĠBerks hire +ä¹ī 项 +'] ). +. restore +al ist +åijĬ ç»Ī +-in stance +Ġoc clusion +ï¼Įè¿Ļ æĿ¡ +æİ§åζ ä½ı +æĻ® æ³ķ +âĢľ , +éĩij æĺŁ +ĠMerr ill +Ġsten osis +B UTTON +Creat es +åľ° åĪ¶å®ľ +Ġover turned +è¿Ļ个 æķħäºĭ +Ġgl aucoma +è·³ è¿ĩ +ç¹ģ è¡į +ter dam +Ġacc use +æıIJ éĺ² +æĬĬ 缮åħī +Ġì Ħ +ĠDress es +ãĢģ æ£Ģæµĭ +ä¸ĭ 课 +oot s +æŃĮ è¿· +èģĶ ç»ĵ +ĠAdd ition +_IN V +Ġgrass es +Ġspawn ed +çϽ æĺĵ +rr rr +Ġ æĪĺ +å¼ı ä¸Ń +å¼ķ 诱 +åıĬåħ¶ å®ĥ +\ Schema +ï¼Į \" +ĠS ik +åħ¥ ä¼į +ï¼Įä¸Ģ é¢Ĺ +ï¼Į以 满足 +MA IN +UI Application +éķ¿ èħ¿ +å¤ĩ æŁ¥ +Ġflo ated +æĪIJ为 ä¸ŃåĽ½ +ĠRuntime Error +ï¼Į åĩĨç¡® +val ence +Ġchang er +æı¡ ç´§ +ãĢģ 空æ°Ķ +Ġweek days +积 æ·Ģ +éĥ½ çͱ +ĠV od +åıΠ好 +ãģ ¸ +æ¸ħ çϽ +ĠX II +å·¥ç¨ĭ 设计 +Ġton er +Ġdiss imilar +æ¹ĺ æ½Ń +: l +ï¼Į æĦŁåΰ +ĠB ess +Ġf us +Ġchild birth +æľīä¸Ģ å¥Ĺ +-ex ecut +n ecessary +at hed +.h and +ĠEver ton +# > +ĠH ubble +Ġnumber With +æ²³ çķĶ +ï¼Į被 称为 +Help ing +Ġcardi omy +Ġ æĻºèĥ½ +, æĶ¾åħ¥ +人 æĪĸ +墨 æ°´ +é£ŀè¡Į åύ +ĠThe ss +ç½ Ķ +éŨ åħ³ +åıĪ æĿ¥äºĨ +ĠTr out +åѦçĶŁ åŃ¦ä¹ł +ãģ¾ ãģĹãģŁ +ä¸į æĶ¾å¿ĥ +ĠM ice +IO C +éªĹ åıĸ +ãģĹ ãģĦ +  +id ious +ITT LE +ĠT ess +Ġ= " +çŁŃ æĹ¶éĹ´ +ĠEth nic +_not ification +% B +Ġmat hematically +ott ie +f itted +åıij æĦģ +eb x +纷 åijĪ +Ġmis fort +ãĢĤ å̼å¾Ĺä¸ĢæıIJçļĦæĺ¯ +Ġse u +ĠOut doors +( Model +ĠH orses +Incre asing +Ġ ................................ +Ġm ö +ĠLong er +ĠWorks heet +.int ellij +ï¼Į è¯Ń +âĢľ âĢĺ +æľª æĪIJå¹´ +ä»ħ æľīçļĦ +Ġoverwhel m +ï¼ļ é«ĺ +åĵ Ķ +浪费 äºĨ +ãĢĤ çĶŁæ´» +çļĦ人 å·¥ +湿 äºĨ +ç¬¬åĽĽ å±Ĭ +ĠInterest s +CRE EN +ãĢģ èĩªæĪij +ĠA lo +ï¼Ľ ç»Ħç»ĩ +æĿ¨ å®¶ +Ġconstruct ors +ĠMaster Card +Ġ å¾Ĺ +ĠD SS +ä¸ī èĢħ +éĵģ çļ® +ipt ic +advant ages +æ²ĥå°Ķ æ²ĥ +a qu +c us +Ġr idd +.Status Code +人 åı¯ä»¥ +æ¡¥ ä¸Ĭ +Ġn aughty +ĠGl ue +SH OP +Ġre claimed +Ġcl asp +æīĢ éĢī +æĦŁ åħī +æīį å¹² +é¾Ļ å±± +è¢ģ ä¸ĸåĩ¯ +Ġét é +_ constructor +Ġdata frame +.p k +_S ub +åŁºåĽł ç»Ħ +çļĦæĥħ æĬ¥ +, in +ï¼Ī H +æľª å®Į +é¦ĸ 款 +ä¿Ŀ温 æĿIJæĸĻ +åĩłåįģ ä¸ĩ +Ġdec ad +ĠPers istent +Ġspraw ling +( scale +ï¼Į èµ°è¿Ľ +港 åĮº +Ġpre operative +oth ic +å®ŀæĸ½ äºĨ +æĭ¥æľī ä¸Ģ个 +åĩ¶ åĭIJ +ï¼Įæĸ° å¢ŀ +ĠFres no +us band +åı£ éŁ³ +ĠImprove ments +ĠS CR +å°ı åı¯ +æµ· 伦 +æķ´ 容 +-d isplay +: æŃ¥è¡Į +åĴĮ åįİ +åı¯èĥ½ä¼ļ åĩºçݰ += h +HE L +-r anging +æĪij ç»Ļä½ł +äºĶ 天 +çģ« æŁ´ +ĠCoin base +ï¼Į è¯Ńè¨Ģ +é«ĺ æ°Ķ +æĹ¶éĹ´ çĤ¹ +}) } +Ġg es +ä¸Ģ æł¼ +ĠCom Visible +ĠPl uto +åıĹ å½±åĵį +æľ« ä¸ĸ +ĠEuro s +ĠEx odus +~ ( +Ġhal ftime +æ· ħ +ĠZ ag +.normal ize +al as +åıįåºĶ çļĦ +ï¼ĮçľĭäºĨ çľĭ +Ġ æĺ¨å¤© +, åĨῬ¡ +? < +次 åħĥ +è¨ ĺ +çĽĺ éĿ¢ +çªĹ å¤ĸçļĦ +Ġaffirm ation +pp les +Ġflow ed +åħ¨æĸ¹ä½į çļĦ +.s im +ï¼Įä»ĸ们 å°± +åħ³æ³¨ 度 +uster ity +Nic ole +æŃ£ äºĭ +renew command +æĿ¥ 表示 +é£İ åįİ +âĦĥ ä¸ĭ +éĻĦå±ŀ åĮ»éĻ¢ +åΰ æĻļ +.t m +éħĴ åºĦ +Ġneutr inos +ä¹ĭ åīij +请 注æĦı +åĪĿ è§ģ +T erry +g aming +ï¼Į æĺİçϽ +ï¼Į æĹ¶åĪ» +Ã Ļ +èĩ³å°ij 两个 +- reference +/ tr +ï¼Į æİ¢ +_b ook +åij¨ 身 +å°ij åħĪ +. animation +å·¥ä½ľ é¢Ĩ导å°ıç»Ħ +ä¿® æĸ¯ +å´© å¡Į +Ġf ray +æİĴ çīĪ +çľĭåΰ ä½ł +æĺ¾ç¤º äºĨ +æĺ¯ä¸į æķ¢ +ĠJew el +çŀ§ ä¸įèµ· +çİ»çĴĥ 纤维 +ĠAdvert isement +红 æĺŁ +ĠFre ed +Initial ization +ä¸Ĭ æľĪ +St uff +Ġ æį¢ +åĽĽ å°Ħ +.De ep +- rock +Ġmet ropolis +åİŁåĽł çļĦ +ü ller +ĠM ines +ĠN odes +ï¼Įéģ¿åħį äºĨ +Ġde re +Ġgenes is +å¼ł åĺ´ +éĻĪ å®¶ +ãĢĤä»ĸ è¿ĺ +: æīĵ车 +社ä¼ļ åıijå±ķ +ä¸Ģ次 åıĪä¸Ģ次 +éĨĴ 缮 +Ġgro oves +Ġfract ured +Pred iction +Ġuntrans lated += j +Ad mission +IR Q +ĠC JK +Ġv r +ä¸Ń ä¸įè¦ģåĩºçݰ +西 æľį +åĵĪ æ¬ł +T OB +Ġap ache +Ġfull ness +Ġneg ate +¿ Ãij +appro val +æĭĽæłĩ æĸĩä»¶ +ä¸įèĥ½ ä¸į +ä¸Ģ大 åłĨ +çļĦ 带é¢Ĩä¸ĭ +ĠI st +c rate +ãĢĤ å·¥ä½ľ +ĠY N +æīĵ åŃĹ +äºĭæĥħ èĬĤ +ĠCH ANGE +SH OW +ĠSlo an +ãĢģ 西å®ī +æºIJ 代çłģ +åıįåºĶ éĩľ +ĠAMAZ ING +å¿ĥ çĶĺæĥħæĦ¿ +Ġpurpose ful +ĠJ W +æııè¿° ä¸Ń +. forward +Ġkn obs +Ġ å§ĵåIJį +ol ks +ER GY +æĶ¾ ä»» +ä¹° 个 +Ġs ms +æŀģ ä½İ +Al igned +åħ³æ³¨ åĴĮ +æ³° åĭĴ +ĠEthiop ian +Ġ è´¦éĿ¢ä½Ļé¢Ŀ +-S ah +ãĢģ 竹 +ĠGr inder +ĠJud ah +Ġune asy +两 åľº +Ġreg imens +è´´ åIJ§ +T AGS +Ġprow ess +In nov +ĠWorks pace +ï¼Į åζéĢł +ht e +è¦ģ é¢Ĩ +大 å±ķ +éĻĪ å°ij +éĺµ åŃIJ +æµĵ 度çļĦ +Ġunt uk +æĸ°éĹ» æĬ¥éģĵ +ï¼Įä¸į 许 +éķĩ æ±Ł +éľ² èIJ¥ +æIJĢ æī¶ +ä¸į çIJĨè§£ +åĢĴ 计æĹ¶ +å§IJ åĦ¿ +滤 éķľ +Ġhand set +éĿŀ常 æĦŁè°¢ +ĠRand olph +ere e +ĠZ o +_rec ords +ĠAsp en +-d rive +Ġbeh aving +èѦ åijĺ +åįł åΰ +Ġtrav eller +Ġleaf y +Ġastronom ical +/ shared +Ġun ethical +çĶ· åĦ¿ +ĠLO OK +ĠM ou +ĠW arrant +-> {' +_F ONT +è½® æį¢ +Ġpyl int +Ġ 客æĪ· +éϤ å¤ķ +Ġdram as +ĠF ulton +çŃī æİªæĸ½ +åIJ« æ°´ +麻 éĽĢ +Dead line +B ah +-Americ ans +A AP +æĺ¯ éĤ£ä¹Ī +Ġdo able +天 ä¹IJ +_T CP +é¾Ļ æ³ī +åºĶ该 ä¸įä¼ļ +_p oll +ĠKey Error +Ġrout ed +æĿIJè´¨ çļĦ +or bit +ä»Ģä¹Ī æł·åŃIJ +çľĭçĿĢ èĩªå·± +mat htt +,å¦Ĥ æľī +Ġgl aring +设å¤ĩ è¿Ľè¡Į +æĪIJ为 ä¸Ģç§į +Ang ela +Ġt ann +èī² ç³» +Ġconc ussion +ĠBatt alion +R aj +æĸľ åĿ¡ +çļĦ å¼Ģåı£ +æŀĹ æŀľ +红 çģ« +åĭ¾ å¼ķ +ĠPas adena +Ġo cular +许å¤ļ çļĦ +ĠW omens +ĠL oy +Ġhears ay +( lib +; $ +Ġr as +(p aste +èĪį åĪ© +. old +ãĢĤ æĪIJ +éĢ ² +èĢģ æľĭåıĭ +Ġf ishes +Ġout ings +åĩĮ 空 +ç¼ĵåĨ² åĮº +ãĢĤ ç®Ģ +ãĢģ å®ŀçݰ +æĹł èµĸ +å¤ľ å¹ķ +ĠPan asonic +ĠL ank +ĠG AP +ĠNSD ictionary +ãĢģ ç½ij +ä¸į è¿Ľ +åIJİ è§Ĩéķľ +-s u +ĠTR AN +ĠCommit tees +Ġsyn opsis +æŀ¯ èIJİ +ìļ Ķ +Ġç͍æĪ· éĹ®é¢ĺ += P +ï¼Į è§Ĥä¼Ĺ +æİĴ çļĦ +æĽ´ å¿«çļĦ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ +Ġorth opedic +~ O +Ġover arching +ç¼ ¥ +äºij éľĦ +Ġpar abolic +æİ¥çĿĢ è¯´ +. @ +Ġ å½Ń +æľĢ 常è§ģçļĦ +Ġemb odies +La uren +| < +åIJĦ è·¯ +ç¿» äºĨ个 +Ex porter +ä¼ļ 为 +Ġi kea +.N um +èĥĨ æĢ¯ +Ġreput ed +ĠEl le +ĠHeaven ly +æŀ · +é£Ł çļĦ +æ·±åĪ»çļĦ åį°è±¡ +åΰ å°ı +èĢģ å¨ĺ +Ġmin ed +_m ag +ï¼Į åĽº +im ely +ç² ¼ +ĠI KE +Ġmon opol +Rel igion +ãĢģ 代 +Ġco y +ring es +ãĢĤåľ¨ ä¸Ģ个 +Ġfre es +æ¶Į åĩº +æŃ» åİ»çļĦ +Ġbott leneck +Ġrig idity +ï¼Įä¸į æĹ¶ +Ġtender ness +éħĭ éķ¿ +æ³ ł +Ġwrong doing +å®ŀä¸ļ æľīéĻIJåħ¬åı¸ +Ġc umin +ĠE MP +èĢIJ å¿ĥçļĦ +term ine +Ġexacerb ated +é± ¿ +Ġerad icate +.s k +æĿİ éĺ³ +éķ¿æľŁ 以æĿ¥ +ĠPet ro +ĠOp rah +Ġë ³ +B UF +Ġpick er +.p oints +Ant on +ä¸ŃèᝠæĿIJ +循åºı æ¸IJè¿Ľ +ãĢĤ åŃ¦ä¹ł +pl anted +sm arty +в ан +.I ter +主åĬŀ æĸ¹ +ĠJ ah +ĠPL A +æī¿ å¾· +åħľ éĩĮ +Ġenzym atic +H its +ä¾Ľ æ±Ĥ +çļĦæĹ¶åĢĻ æĪij +è·Į åģľ +H ear +Q i +Ġ èĭ±åĽ½ +ĠP OD +åĨħ 设æľī +åĮĹ æ¬§ +åĨ· åĨ°åĨ° +Ġelect orate +Decl ared +Ġä¸Ĭ æľŁ +]] > +éªĮ èµĦ +unk er +dom ains +ĠAm id +ĠMac Donald +å¾Ĵ åĬ³ +Ġ' ^ +ãĢģ æ±Łè¥¿ +çα 她 +Ġquest s +åĶ® 楼 +å·¥ åѦ +ol ocation +Ġfin s +èĽ Ģ +å®ı 大 +cc ión +Custom ize +Ġs cept +ĠAf ro +Inst itute +Ġdiss atisfied +褪 èī² +Ġad apters +_t ools +è¶ħ ä¹İ +ä¼ij çľł +çļĦ åħ¬åijĬ +eed s +æ¤į åıij +ç²ĺåIJĪ åīĤ +Ð Ĺ +ĠT avern +èĥ½ å¹² +对 æµģ +reg ation +_w rap +*~ * +Ġbe ck +ĠWh ites +Return Type +.ext ra +ä¸į æİ¥åıĹ +um etric +Ġdist rust +Ġcare rs +ä¸ģ åŁº +åħ¬è®¤ çļĦ +_ aff +Ġleg ality +Ġrecogn ising +ภ° +å¹¿æ³Ľ çļĦåºĶç͍ +åĽĬ èĤ¿ +j r +Ġ ä»· +æĶ¯æĮģ è¯ģåΏ +ĠPRO P +p itch +Ġf ores +Ġm ower +] ? +Ġ åĦ¿ç«¥ +, è´¨éĩı +åIJĦ åİ¿ +M J +is bury +ĠS ão +æĸ° ä¸ĸ纪 +ï¼Įè¿Ļ ä¸į +åı° å±± +ãĢĤ æĢİä¹Ī +çļĦåİŁåĽł æĺ¯ +ãĢģ åıĤä¸İ +Ġinf estation +éĴ¦ 佩 +/ DC +ç͵ åĽ¾ +ç»ĵæŀĦ åĮĸ +è¤IJ æĸij +" ä¸Ń +Ġg ated +л ен +ĠYan kee +ĠV E +ï¼ĮæĪij åıijçݰ +CT IONS +é¡¶ éĥ¨çļĦ +åĪĨå¸ĥ çļĦ +èĩ³ åĽ¾ +Ġphen otypic +ĠTu ition +Ġ` \" +Mod ification +> Must +æĺ¯ åħ¨çIJĥ +缩 æĶ¾ +è¸ı æŃ¥ +Ġspot ting +ĠPir ate +.m em +Un ary +_R SA +ï¼Įå°ı åĮº +è¿·çħ³ çħ³ +Ġconst itut +Ġbas ename +(st ep +ï¼Į èĥĮåIJİ +åIJİ éģĹçĹĩ +_s id +Ġpost pone +Re asons +ĠProb ate +_up dated +Ġ ä¸Ķ +æľ¬ æĥ³ +ĠInc redible +IST ANCE +ĠBl izzard +æķĮ 对 +æī« äºĨä¸Ģçľ¼ +" S +ĠN ODE +èĢĥèĻij ä¸Ģä¸ĭ +Install ing +ĠDick ens +ĠErn st +) << +çļĦ èĥ³èĨĬ +æ° Ĺ +em outh +身 ä¸ĸ +ï¼Ľ çĦ¶åIJİ +emb edding +ĠMuseum s +Ġgolf ers +åį«åģ¥ å§Ķ +æĽ´ éļ¾ +_d ynamic +ä½İ 端 +éĺ´ åĩī +rob es +et ine +äºİ ä»ĸ +.C iv +ä¹° ä¸ĭ +èĦī æIJı +Delay ed +J ax +ä¹Łæ²¡ ç͍ +contin ued +Ġenorm ously +, 人çĶŁ +ĠB K +Ġha unt +æĹł è·¯ +List ening +Ġtem pered +ĠBar rel +script size +è¨Ģä¸į åıij +åı¯ 没 +çī² çķľ +^^^^ ^^^^ +åı¯ä»¥ åĩıå°ij +åªĽ åªĽ +on en +ï¼Į æĭĴç»Ŀ +Ġh b +ĠB ain +åį´ æĺ¯ä¸Ģ +ve olar +Ġenerg ized +Ġcapac itance +F olders +Ġa lex +ï¼Į 女åĦ¿ +ĠF oley +Ġrep ub +_H andler +Ġè¿Ļ æĺ¯ä¸Ģ个 +ĠEN TER +Ġincons istency +Ġparl ament +女 æĺŁ +缴æİ¥ 被 +^* \ +ers en +åıij çģ« +ĠCl an +_D IM +Ġsingular ities +Ġdat atype +æīĵ èµ· +è¨ Ī +Ġfacilit ator +, éĩĩåıĸ +Ĉ ãĢģ +Ġj uxtap +ne z +ĠMult ip +IMP LE +Ġswallow ing +Ġre inst +ãĢģ æĪIJæľ¬ +å°Ĩ ä¼ļåľ¨ +ï¼Į è§Ĥ +Ġv f +åľº å¤ĸ +æĿ¨ æ£ł +Ġsat ire +EXTERN ALS +ord ion +ç»Ļ 对æĸ¹ +æłĩ çļĦåħ¬åı¸ +Re plication +å½±è§Ĩ åī§ +ĠPupp y +ä¸į åĽŀ +ãĢĬ ä¸ī +éĩij ä¸Ŀ +éĵĥ æľ¨ +绿èī² çݯä¿Ŀ +çļĦæĪĺ 绩 +i ak +Ġext rac +æĽ¾ 说 +å¿ĺ æİī +èħ¾ 空 +_COMM ON +âĢľ ä¸Ĭ +ç«Ļ èµ· +Ġinject ing +Ġsh rine +å¤ļ 好 +æķ°æį® ä¸Ń +综åIJĪ æ²»çIJĨ +ĠSHO ULD +> false +Q D +æĺ¯ éĶĻ误çļĦ +åĸľ äºĭ +,ä½ł åı¯ä»¥ +- added +åľ¨ èĦ¸ä¸Ĭ +reat he +ç»Ĩ å°ıçļĦ +ĠGreen wood +åĨľ æŀĹ +UR Y +æĿ¾ ä¸ĭ +ç«ŀäºī ä¸Ń +ĠPH R +.se parator +Ġallerg ens +Ġ çłĶç©¶ +ï¼Į 尽快 +å¾Ī èĪĴæľį +Ġnon fiction +/g pl +ĠBring ing +IN V +éĹŃ å¹ķ +çļĦåīį 端 +i ert +ä¸ĵ åįĩæľ¬ +ĠC ouch +ym p +ä¸Ģå®ļ æľī +å¦ĸ æĹı +{ AD +Ġclass ifiers +ç´« èĸĩ +ĠM ango +ãĢģ 秦 +ĠB isc +ĠU ran +-m ean +ãĢģ H +é»Ħ è±Ĩ +Ġround up +æĭĨ è£ħ +intern et +çIJĨæŁ¥ å¾· += {\ +äºĨä¸Ģ 项 +éħĴ çĵ¶ +å¸ĮæľĽ èĥ½å¤Ł +çľ¯ èµ· +ĠVine yard +Ġem its +è¿ľ è·Ŀ离 +ä¸ĩåħĥ 人æ°ijå¸ģ +åĨľä¸ļ 人åı£ +Ġ è´¢åĬ¡ +as co +ãĢĤ æ¯ıä¸Ģ +ĠI ve +ðŁ ¤ +豪 æĿ° +Ġcommission ing +Ġt outed +ĠG astro +good s +åĩıéĢŁ æľº +ç»ļ çĥĤ +ĠM CC +ç¼ Ī +ĠSh adows +è¶Ĭ å¿« +æī¿ åİĭ +é¼» åŃĶ +( Constants +ãĢģ æĶ¹åĸĦ +J U +ĠP au +åŃIJ æĺ¯ +æĻĥ æĻĥ +æıŃ ç§ĺ +Ġtreat ies +æ°¸ çĶŁ +Ġmid way +Ġing estion +äºij 天 +è¿Ī åIJij +å±Ĥ éĿ¢ä¸Ĭ +w arming +or ations +ãĢĤ ä¸ĸçķĮ +Ġcrypt ography +- option +çļĦ åijĺå·¥ +为 åĽ¾ +ä¸Ĭ 没æľī +-f aced +.P OST +grad ing +p owers +äºĨ å°± +Ġfetch ing +ãĢģ é£Ł +Ġ 论 +ãĢĭ âĢľ +Top ology +ĠWin ery +èϹ æ¡¥ +Ġcupc ake +ï¼Į çijŀ +Ġr nd +(s cript +Ġarrog ance +, å¼ķèµ· +âĢľ å¦Ĥæŀľ +ĠAd ri +ĠBrid g +Ġdoctr ines +Ġd usk +,ä¹Ł è¦ģ +Ġlumin ous +( es +ĠH et +çζ 女 +èī¯ å¤ļ +,æĪij è¦ģ +ĠDom ino +æģ¶æĢ§ èĤ¿çĺ¤ +ĠL over +}} + +irc ular +Ġ第ä¹Ŀ 竳 +Ġis a +å§Ķ å©ī +-P resident +èĤºçĤİ çĸ«æĥħ +ĠPE OPLE +-ren owned +[ ** +ä¸Ń æĸ¹ +ĠG ast +Ġad verts +ie k +æĸĩåĮĸ ä¼łæĴŃ +Ġdeb ilitating +Ġdat um +Ġclar ifying +cons ult +Ġ åĽºå®ļèµĦ产 +ç»Ŀ 伦 +ro k +ĠB DS +çϾ 人 +Ġdata Type +ï¼Įå°Ĩ 她 +æĥ ĺ +示 å¼± +æıIJ交 çļĦ +Bag Constraints +[ out +å½ĵ 头 +温 çĥŃ +ä¼ĺåĬ¿ çļĦ +Ġcaut iously +S ERV +æµģéĩı 计 +) \\ +大 éĹ®é¢ĺ +. Compare +ĠF n +ĠO CD +æĴ ħ +éĿł å±± +ãĢģ 强åĮĸ +ĠHundred s +Ġdi agon +åĽŀæĿ¥ åIJİ +æľº çģµ +æĢ¥ èºģ +Ġsquir rel +L AGS +P AT +çŁ³ éŨ +Ġbreath s +积åĪĨ æ¦ľ +ungal ow +< Item +Ġw ards +èIJ½ æ°´ +\ vec +ĠC aul +åıĬ åij¨è¾¹ +æĢķ ä½ł +éĤ£ åľº +被 åħ³ +ĠAcc reditation +v at +ä¸Ń 表示 +å§Ķ 书记 +é¡¶ çļĦ +å»Ĭ åĿĬ +w ort +积 æĶĴ +Ġ< $ +ec ret +ãĢģ 鼷 +ĠF ay +ĠAr rang +$ ", +Ġcon quest +ĠTax i +W inner +orn a +æĻļ è¾Ī +c rit +Ġin clus +åħ·æľī ä¸Ģå®ļ +çļĦéĤ£ ä½į +å̼å¾Ĺ ä¿¡èµĸ +.input s +缸åħ³ æ³ķå¾ĭ +éĥ¨éĺŁ çļĦ +âĢľ çα +ä¾Ŀ ç¨Ģ +让 对æĸ¹ +èĢĥ çļĦ +_ED GE +ĠM og +å§IJ å¼Ł +part icle +END IF +Ġstrat ified +Ġmotor ist +ĠHon orable +Altern ate +æ¶ħ æ§ĥ +B luetooth +ĠC SP +çī¹ çº³ +åħ« æĪĴ +ĠMor an +.y ear +Ġh ob +Ġgu inea +åıĸ èĪį +åĨ¬ 天çļĦ +æľ± éĽĢ +). : ][< +ĠSwe at +ig ua +Ġhand written +åĿĩ 设æľī +è¾ħ ä½IJ +Ġfuck ed +ĠR OW +Ġj ihad +è¨Ģæĥħ å°ı说 +an se +大 ç±» +equ ivalent +charg ing +ï¼Į以ä¸ĭ æĺ¯ä¸ĢäºĽ +Ġh ither +å̼ éĴ± +ĠAN N +产åĵģ æľī +交 äºĨ +ï¼Į她 è¿ĺ +ĠIv ory +A UD +\ wedge +ut ely +èº ĩ +æĴ ® +æģ¼ çģ« +Ġ éĿ¢ +Ġ éĢļ +ä»Ģä¹Ī åİŁåĽł +åİĨåı² æĤłä¹ħ +Ġescal ating +æĺµ ç§° +ĠFib onacci +ĠR oles +åįķ æį® +ĠIn verse +次 åĬ©æĶ» +è®Ńç»ĥ èIJ¥ +å¼Ģåıij åĴĮ +çĶ³è¯· æĿIJæĸĻ +ï¼ĮæĢķ æĺ¯ +ic ul +P RESS +Ġse ab +ï¼Įèĭ¥ ä¸įæĺ¯ +ĠGL float +ï¼ļ ä¸į +å¾ģ ç¨İ +ĠAr b +Mar ie +\| _ +certain ty +Ġjarg on +èį ŀ +éĢļè¿ĩ ç½ij绾 +umer able +çĻĮ ç»Ĩèĥŀ +_B INARY +otyp ical +Ġmon ol +.T ree +Ġnit ric +Ġreloc ating +ä¹ĭ 书 +ï¼ĮæĪij ä¸Ģ缴 +.d ouble +åĨľ åķĨ +arc her +æıĴ åľ¨ +t itles +ãĢģ èĥ¸ +éĵģ éĿĴ +ĠBy rne +çļĦæ°´ åĪĨ +ä¹ĭ éŁ³ +Ġque ens +å¬ī æĪı +Ġ ³³ +çŃī åĽ½ +ĠL ester +ac us +ç»Ĩ çļĦ +Ġsupernat ant +> Q +Ġpar ishes +Ġmur m +ĠEst imates +adjust ed +欢 声 +设å¤ĩ ä¸Ĭ +Ġneuro deg +Ġ å·¥ç¨ĭ +çŃī åįķä½į +.D escription +Ġuncont rolled +åŃĻ æĿĥ +d egree +Ġatt est +åIJ« èĵĦ +æ·¡ æ¼ł +ĠColomb ian +Ult ra +F riendly +achel ors +Ġimmer se +/ create +Ġ 楼 +ĠF irms +读 åΰ +æĬ¬ é«ĺ +Ġrob ber +Ġ(* ( +Sustain able +ĠANSW ER +ï¼Į è¡£æľį +Ġp j +ĠB aba +ud ev +æĭį æīĵ +: left +ä¸į æĥĬ +ï¼Įä»ĸ 认为 +çłĶç©¶ å·¥ä½ľ +ï¼Į åħĦå¼Ł +del im +Ġplung ed +J ake +å¹ħ çĶ» +_str ategy +ĠE EPROM +", & +åĬŁ åĭĭ +_w hen +l apping +ĠS plash +ç¾ŀ èĢ» +ult ures +丹 çͰ +ĠE GL +ä¸İä¼Ĺ ä¸įåIJĮçļĦ +,ä½Ĩ æĪij +åĭŁ æĬķ +转åĮĸ çİĩ +å¼Ģå§ĭ æĹ¶ +人æ°ij ç½ij +亮 丽 +第äºĶ çϾ +Ġfertil izers +éϤå°ĺ åύ +ĠA SA +ä¼ļ ç»§ç»Ń +计 è°ĭ +åĪļ éľĢ +ĠUser name +. obs +Ġl ash +åĪĽ æĬķ +reason ably +åºĶ éĤĢ +und able +èĤī è´¨ +çļĦ ç¾İ丽 +å· ½ +ĠK obe +羣 è¯Ŀ +ead y +ï¼Įä½Ĩ ä»ĸçļĦ +Ġlo fty +âĢľ çİ°åľ¨ +ĠR AD +éĹ· éĹ· +( .* +s erv +en arios +西 æĸ¹çļĦ +è¿ĺ ä¸įåΰ +设计 çIJĨ念 +ĠARTICLE SMORE +Ġrhyth mic +ãĢĤ æĦ¿ +ä¹ĭ é«ĺ +åĪĩ ç£ĭ +ĠLa place +å¦ĸ éŃĶ +Ġch ant +Ġ% { +Ġinc arnation +æķij åĩº +ĠAv a +ä½ĵèĤ² è¿IJåĬ¨ +ĠCock tail +Y a +å¿ĥ çŁ¥ +... ]( +交 åĬŀ +åIJĥ ä¸ĢäºĽ +ãĥ Ļ +_buff ers +. operator +ĠB enny +Ġen sembles +ĠSearch ing +comb ined +er ne +ä¹Ł åŃĺåľ¨ +Ġappro ves +è¤ Ĥ +ĠOrt iz +cond itionally +ET IME +]{} ]{} +IC ollection +帮 æĤ¨ +_s wap +åį« åĨĽ +æ¶Ĥ å¸ĥ +é¼İ é¼İ +( rule +ï¼Į æıIJåĩºäºĨ +è¡ Ĩ +æĤ¦ è̳ +ĠExpert ise +è´® èĹı +Ġgriev ances +æľªå©ļ 妻 +ĠS cheduled +é¢ ļ +ph ans +æĿĢ æľº +éĴ» äºķ +Ach ieve +( rec +× ĵ +æľī åĪ« +ĠD FS +æĶ» 读 +å¸Ĥå§Ķ 书记 +Ġheavy weight +Ton ight +åħī æ´ģ +æĢĢ æĹ§ +ĠRequ ire +ä¸īåįģ äºĶ +abcdef gh +çļĦ æŃ¥ä¼IJ +Ġam used +欣 å®ī +åį³ä½¿ æĺ¯ +ï¼ĮçϽ 天 +h ands +Ġf uzz +Ġsuccess ors +汤 æ±ģ +Ġ èĤ¡ç¥¨ +说 æ¸ħæ¥ļ +B lo +ä¹Ł ç¡®å®ŀ +Ġbl ister +ĠLogger Factory +Ġf ools +å¸ķ çī¹ +ĠS MC +åĪĨ éĻ¢ +æŁIJç§į æĦıä¹īä¸Ĭ +ĠFried rich +åĽ½ èĹ© +å®Ī åĢĻ +ä¸įè¦ģ ç´§ +缸åIJĮ æĪĸ +Ġanthrop ology +B estseller +ĠG ael +身 åıĹ +_g ain +Norm ally +ĠSew ing +ĠO ro +èά èĭ¥ +ĠM LA +Ġ[ . +.P rim +ĠF ired +è¿Ļ éĹ´ +ĠCh ains +åĪĨ享 äºĨ +ä¸į åĢĴ +Ġset back +èµ° è¿ĽæĿ¥ +/ all +è±ģ çĦ¶ +Ġflee ce +t ics +ãĢĤ æĤ£èĢħ +K al +ãĢģ çī¹èī² +og any +åıijå±ķ æĶ¹éĿ© +éĥ½ä¼ļ åľ¨ +第äºĶ å±Ĭ +Hist ogram +re peated +çļĦä¸Ģ å¤Ħ +å¯ĦçĶŁ èĻ« +^ ) +Ĭ åŃIJ +Ġcol legiate +requ isite +æļ´ åıij +æľŁå¾ħ çĿĢ +Ġembro idered +ĠW ah +ĠSp am +Ġsw agger +æ¹ĸ å·ŀ +è¿Ļéĥ¨ åī§ +èĥ° èħº +e ight +å®ŀ å½ķ +ĠAL IGN +强度 åĴĮ +List ed +_AD MIN +ï¼ī 人 +ĠInterpret ation +éĺĢ ä½ĵ +oc in +éľĢè¦ģ ä½ł +term ilk +EXTERNALS YM +( empty +æĺİ çĽ® +ãĢĤåľ¨ è¿Ļç§į +Ġcash ier +ch al +Ġund e +许 诺 +Ġpoly ethylene +æĺŁæľŁ ä¸Ģ +contin ental +çĥ§ 伤 +æķıæĦŁ æĢ§ +_ EDIT +以 åĨħçļĦ +Ġup regulated +éĢī 为 +ĠLan tern +, æĺİç¡® +. # +ï¼ļ å¦Ĥ +åıĮ åįģä¸Ģ +Ġsyn ch +ï¼Į èIJ¨ +èŁ Ĩ +ĠSpec s +ï¼Į çĿĢ +Host s +_ identity +Ġ åı° +is Valid +âĢĿ äºĮåŃĹ +åIJĪ èIJ¥ +å±ķ é¦Ĩ +ï¼Į èĢĥè¯ķ +çļĦ éĩı +ĠArg entine +ith a +ï¼Įè¿ĺ ä¸į +è¦ģ ä¸įæĺ¯ +建议 大家 +(k ind +Ġdet achment +å¨ģ 夷 +港 å¸ģ +æł¹æį® åľ° +å¾Īå¿« çļĦ +麻辣 çĥ« +大 åı¯ +çĶŁäº§ ä¸Ń +æĢ»ç»ĵ äºĨ +B read +pp en +Ġperf ected +Wil son +çļĦ æĦŁåıĹ +åħ¥ è´¦ +Ġhere after +ï¼Į æĿIJæĸĻ +li oma +Ġ è§ģåΰ +ãĢģ å¢ŀåĬł +声 åIJį +å°± å¦Ĥ +ä¸ī 竳 +Ġ` ( +å¤ļå°ij å°ij +å®¶ç͍ ç͵åύ +, å®ĮæĪIJ +H ire +ĠR amb +æĪij å°Ĩ +åħ¶ä»ĸ 人çļĦ +åľ°çIJĥ çļĦ +èµIJ äºĪ +ĠHold en +åħ» é¢ľ +æĻº åĪ© +Ġtestimon ial +. ali +m age +äºĨ æĥ³ +Ġcat ers +çĭ¬èĩª ä¸Ģ人 +ĠMethod ology +Ġintertw ined +$ str +Ġl ign +èĥ¡ é¡» +çļĦ主è¦ģ åĨħ容 +Ġr arity +æ°´ æ»´ +leq slant +çŃĽ åĪĨ +ĠWas her +éĶ¦è¡£ åį« +em ically +åħ¬åı¸ 对 +ï¼Įåıª åIJ¬ +ä¸ĭåĪĹ æĥħå½¢ +å®ŀè´¨ ä¸Ĭ +æ½ľ åĬĽçļĦ +: ä¸Ģæĺ¯ +e j +åΰ èĩªå·±çļĦ +åºĶ éħ¬ +( Is +é«ĺ 精度 +游 è®° +æİ¨ æĭ¿ +çļĦæĹ¶åĢĻ ä¼ļ +_EX CEPTION +æ³ķåħ° åħĭ +Ġretire es +ĠM PH +ĠH au +æ´Ĺ éĿ¢ +Ġcapital ization +Cent re +ï¼Į 缮çļĦæĺ¯ +ï¼ĮæīĢæľī 人 +-round ed +å®ļ äºİ +åŃ¦ä¹ł ä¸Ń +ç¨İ åIJİ +Did n +ĠFarm ing +Ġå¼Ģ æľ¬ +åIJį åĮ» +ĠBar th +çIJIJ äºĭ +Ġget Type +转 è§Ĵ +ĠDec ide +Ġ æĿŃå·ŀ +ãĢĤ å¸Ĥåľº +ĠDu chess +åIJĮä¸Ģæİ§åζ ä¸ĭ +s ong +Ġt q +_t ri +å±ķ ä½į +ĠDe af +Ġhapp iest +çļĦå¤ĸ å£ģ +Ġfo i +IRT UAL +P aid +\ fs +n orth +ï¼Į è´µ +æĵį çĽĺ +_ editor +鼶 åħ« +çļĦéĹ®é¢ĺ æĺ¯ +.read Line +Ġscram ble +çļĦ 广åijĬ +ãĢĤ èĥ½å¤Ł +çļĦä¸Ģ å®ļ +ĠOff shore +å£ģ æĮĤ +ĠPath s +Ġun imag +æº ¥ +åĮĸ ç²ªæ±ł +Ġpain less +åħ¥ åĽŃ +çݰéĩij æµģåħ¥ +Ġ 空 +an j +ï¼Į æ·»åĬł +Ġnew found +ï¼Įä¸įæĺ¯ åIJĹ +ĠKar ma +Ġent ice +çļĩ ä¸ĬçļĦ +_MEM BER +ĠS CH +fil tered +ï¼Į å´Ķ +ï¼Ī åħ¬åħĥ +_g a +ĠSub sequent +交æµģ åĴĮ +çŀ¬ æĹ¶ +ĠDar ling +缮 ä¸Ń +è¯ļ å¿ĥ +ĠBow en +ĠKind ergarten +Ġretreat s +on ation +Ġinter ception +Ġjurisdict ional +ĠSt ub +Ġcover ings +ï¼ģ 好 +Ġlik eness +Ġsuit ably +ĠTown send +çļĦ åIJij +大 çĤ® +æ°´ åİ¿ +ĠHe ard +ç¥ŀ åĨľ +()) -> +ä¼¼ æĺ¯ +âĢľ How +ĠG ott +ĠHead lines +Tex Coord +Ġaz imuth +- im +ä¼´ çĿĢ +ï¼Į建ç«ĭ äºĨ +_ operand +ãĢĤ æ¯į亲 +äºī 缸 +åĪĨæŀIJ 仪 +ç»Ļ大家 带æĿ¥ +ç£ķ 头 +çļĦ éĢłåŀĭ +field set +è¡Į åIJĹ +ĠÙħ ÙĨ +çĥĻ åį° +ĠL ub +é«ĺ 丽 +大åѦ æķĻæİĪ +亮 çľ¼ +éĵ¶è¡Į 贷款 +/t mp +ï¼Į 汪 +ä»ĸ å°Ĩ +åĪ« æľī +éĩĮ 尼奥 +å¹³ å®ļ +çİĦ æľº +ä¸į çģŃ +end um +Integ ral +æľĿ æ°Ķ +åŁ¹åħ» åŁº +æĴ¤ åĽŀ +Ġsquee zing +lyss a +le ur +Ġw l +åı¯ éĢīæĭ© +Ġun ambiguous +Ġadj oint +Process ed +åıĹ çģ¾ +ĠRed emption +ãĢģ åĬŀçIJĨ +ç͵ çŃĴ +Ġprocess ion +æĢ¥ æĢ¥ +亿 åIJ¨ +l ush +ä¸į åΰäºĨ +ĠG room +ï¼Įå°± 说 +Pref s ++ D +ĠP raise +éĢļ常 ä¼ļ +Christ ine +ĠJenn a +çĨı é϶ +ç¦Ģ æĬ¥ +x fe +åı¯ ä¸įèĥ½ +ĠEp isodes +SETT ING +est imate +âĢľ ä¸ĥ +ul ose +und ra +æ´ŀ éĩĮ +ĠInf ant +Ġ åĪłéϤ +ï¼ļ åĪĺ +æıIJ æĮ¯ +ä½ľ çŃĶ +å¤ĸ å±Ĥ +ĠAr d +Ġdiagn osing +Ġfrust rations +( alpha +Ġ éĹ®é¢ĺ +ĠN SC +Cred its +Ġunders core +æĥ³ å¾Ĺ +çī¹ ä»· +(h andles +urga on +åħ¬åı¸ æ³ķ +å±Ģ åŁŁç½ij +=" ./ +Ġmon oxide +Edit Text +Ġpenet rating +ãĢĤ åħĪåIJİ +âĢľ æĢİä¹Ī +G MP +æĿ¥ 表达 +Ġsh ri +Specific ally +Ġfren zy +大 å®ĭ +Ġadd Object +/d ocker +ĠTitan ium +ess es +umm ed +æľĪ åŃ£ +æīĵ è¶£ +èĦij éŨ +Ġmiscon ception +Ġb or +ï¼Įè¿Ļ åı¥è¯Ŀ +æĽ¾ 被 +å¢ŀéķ¿ äºĨ +åĮª æµħ +Ġips um +E PA +_un icode +æŃ¤ 举 +SE A +躺 ä¸ĭ +Ġphysic ist +Ġam el +æ»ļ çıł +/ Object +G ENER +åĴĮ éĤ£ +æŃ¤ æĸĩ +æŃ¦ åѦ +ĠCons umption +æĪ¿éĹ´ åĨħ +ï¼Į æĦŁæĥħ +Ġv ort +Ġget Current +Ġrep etitions +åŃ¦ä¹ł æĸ¹æ³ķ +ĠDi agnostics +ï¼Į åı«åģļ +人 ä¸Ģæł· +åŃIJ ä¹Ł +æ²ī éĨī +ĠPay roll +åĽļ ç¦ģ +çļĦ éĩijå±ŀ +ĠV or +ĠCh apters +端 æľ¨ +< Map +个 æĢ§çļĦ +Ġupt o +æ´»å¡ŀ æĿĨ +ĠRenew al +âĢľ ä¹Ŀ +Ġvis cous +CT P +Ġgre asy +ç͍ æīĭæĮĩ +å°ģéĹŃ å¼ı +. pp +ĠM DA +ï¼Ł âĢĻ +éĩĬ 迦 +å¿ĺ ä¸įäºĨ +. original +Ġc heddar +Ġel m +论 çļĦ +仪å¼ı ä¸Ĭ +Ġf iddle +ä¸ī çͲ +ĠX YZ +ï¼Įåΰ è¾¾ +Ġapr on +Ġsyst olic +Ġsec s +- We +ãĢģ åĢºåΏ +è¡Ģ ç¼ĺ +å¨ģ æľĽ +æĥ¹ 人 +% çļĦ人 +缸 æľĽ +urg ence +Ġcrow dfunding +çϾåĪĨä¹ĭ çϾ +" time +B ubble +Ġ% , +_PRO DUCT +_err no +ï¼Įä»» çͱ +\ mapsto +{{ / +ï¼Į èᣠ+Ġn ag +æŁ³ éļıäºij +è¾ŀ éĢĢ +Ġfry er +ĠR az +ĠQuestion naire +ĠRon nie +ĠMull er +\ mbox +ãĢģ åľ°çĤ¹ +.P re +ï¼Įä¸įçĦ¶ çļĦè¯Ŀ +_SW ITCH +ï¼ĮæĪij æł¡ +ä¸įä¼ļ åĽłä¸º +? > ( +Ġsight ings +Ġrum ored +åįļçī© éĻ¢ +Ġfollic les +ĠT SA +ĠM oodle +åĪĿ ä¸Ģ +åºĶ该 注æĦı +Ġarom as +F acing +åIJİ æīįèĥ½ +ï¼Į对 åħ¶ +_RE PORT +G all +Ġ æ½ĺ +Col on +igs aw +åīĸ éĿ¢ +ĠS IR +ï¼Įè¿Ļ åĽŀ +å·¥ä½ľ éĩı +Ġdraw able +ĠUnsupported OperationException +D h +ĠP epsi +ä¹Ł æľī人 +天 åĽ½ +Ġdisc erning +ĠP ASS +èĥ½ 被 +ä½łä»¬ äºĨ +éĢı æĶ¯ +Port able +_ age +h ospital +Ġ è´¹ +de ck +ĠPr imer +_ST YLE +å¼± å°ı +å¾Īä¹ħ äºĨ +çļĦ åĨĽéĺŁ +if ix +ĠG ABA +ĠJ ian +æľīä¸Ģ åıª +ĠC LEAR +ç͍ æĦı +åı¯ä»¥ èĤ¯å®ļ +ĠHel ic +Ġcomplain ant +S pect +ä¹ĭ å®Ŀ +Ġdrop let +容积 çİĩ +ĠAuthent ic +åĮĸ çī© +ï¼Įä½ł è¿Ļ个 +æĹ§ éĩijå±± +ĠCL K +. rec +âĢľ These +éĹ® çļĦ +ï¼ĮæĪij çŃī +åĬ£ è´¨ +z ac +ĠC ARD +ĠP ence +ĠL ig +Ġreli ant +èĥİ è®° +ï¼Įå¹¶ å°Ĩåħ¶ +Ġweak est +çĶ© å¼Ģ +ä¹ĭ éĢī +çķĻ å¿µ +Inter section ++ w +_ plane +ĠM inds +-t oken +åĩĨå¤ĩ éĩij +Ġprost itution +èī¯ çŁ¥ +Ġpred ic +α Ïĥ +ĠActiv ate +que ued +çĶŁçī© çļĦ +å¤ĸæĺŁ äºº +ä¸į å·® +.c ols +Ġri pping +æ¶ĪåĮĸ ä¸įèī¯ +ĠContin ued +% ï½ŀ +- animation +c riteria +ĠA rial +ĠL oves +ä¹ħ è¿Ŀ +ĠEgypt ians +Ġ åºĶæĶ¶è´¦æ¬¾ +he he +ãĢģ éŃı +声 åĵįèµ· +èĬ± åľ¨ +AD O +æŀª æĶ¯ +åĽ¾ä¹¦ 缮å½ķ +ï¼Į严 ç¦ģ +Ĉ ćć +大 èĤł +Ġhand gun +ra re +æīĢ å¯¹åºĶçļĦ +çŁ³ ç¢ij +çѹ 建 +æ°Ķ象 åı° +Ġsuperconduct ing +D ining +ĠT anner +ä¸į éĹ» +å¼Ģ çªĹ +(s ymbol +Ġanecd otes +.L earn +B ride +æķ°æį® ç±»åŀĭ +åľ°ä½į çļĦ +oc ode +ç͍äºİ 对 +æĽ´å¥½åľ° äºĨè§£ +dist ributed +ï¼Į æŃ£ç¡® +æĥħæĦŁ çļĦ +ĠMagn us +ãĢĭ è¯Ĺ +_b oard +èŤ èĶĵ +Ġcytot oxic +å¤ļ ä¸ĢäºĽ +åıijçĶŁ çļĦäºĭ +.sub scribe +-g irl +">< !-- +.bl ue +ä¸Ģ èµ° +æıIJ è´¨ +Ġchief ly +å°Ĩ è¿Ļ段 +S ew +Ġunders erved +L iz +Ġpower ing +ï¼Įåı¯ä»¥ çľĭåΰ +.parent Node +" ï¼ģ +æİĴ ç»ĥ +榴 å¼¹ +Y B +ãĢģ å°±ä¸ļ +Ġreg enerative +ĠSquad ron +ï¼Į çĤĴ +ãĢĤ æĹ©åľ¨ +å¼ł æµ· +æŃ¦ å½ĵ +UM MY +itiz en +ĠÑģ о +- abs +r ud +Ġ 约 +ĠS hat +Can on +ĠJa ipur +å¦Ĥ çĶ» +ä¿Ŀ åįķ +éĤ£ä¹Ī ä¹ħ +_ST ORAGE +st amp +ĠEl igible +Ġdent ures +[ ind +èµ· åĽł +Gu ests +Ġliquid ation +å¹³åĩ¡ çļĦ +Ġor deal +Ġlibr arians +çľī头ä¸Ģ çļ± +ï¼Į å¯Ĩå°ģ +åı¯ å®ŀçݰ +( parameter +Ġconc ord +åľ¨ä»ĸ 身ä¸Ĭ +Ġd art +ãĢģ åĩıå°ij +管 åĴĮ +ĠAdvance ment +st ations +âĢľ 为ä»Ģä¹Ī +ĠJe ans +è¯ķéªĮ åĮº +Ġhunt ed +Ġ åĩºçīĪ社 +ign ored +ĠTe V +èģĬ çĿĢ +Ġsp ong +ãĢģ åĽ½åĨħ +é¢Ĩ 带 +æĻ® ç½Ĺ +åΰåºķ æĺ¯æĢİä¹Ī +Coll apse +White Space +åı¯ ä¸įæĥ³ +Ġher ald +é£Ł 客 +' _{ +Ġke V +çĽĺ åı¤ +Ġoptim ally +âĬ Ļ +ĠS PA +æľī æ°´ +çª ¿ +ία ÏĤ +_RE AL +Ġsy nergy +ĠAri el +çļĦ åĬŁå¤« +Ġ 鬼 +ĠC aring +å¿Ļ èĦļ +Ġbroad ening +ĠIT EM +åłĨ åıł +FORM ANCE +an ely +Ġb lem +Ġdem eanor +Ġsol ace +Ġappla ud +/ pr +å°ı é¢Ŀ +Ġlegal ization +飦 å¾· +æłĩè¯Ĩ 符 +! $ +çī¹ éĤĢ +æĭī éķ¿ +-w all +éĢļ éĢļ +_t cp +ion age +qu oted +Ġanc illary +Ġwall papers +æľīä»Ģä¹Ī äºĭæĥħ +ĠFac ilit +ï¼Įä¹Ł éĥ½ +æĪı è°ij +CL IENT +_back up +im eline +Ġfor d +æĺ¯ 第ä¸Ģ +ari ance +è¡· å¿ĥ +Ġeste emed +M eg +S oul +åľ¨ å¿ħ +(' { +ĠApp ropriate +åĪij éĥ¨ +ç²ĺ 稳 +åŁĭ èij¬ +ĠB ias +ĠReg ents +/ us +æłĩ çīĮ +è¿ĺæĺ¯ æľīçĤ¹ +yl in +ĠPre paring +bel ieve +ï¼Įå¤ĸ è§Ĥ +éģŃéģĩ äºĨ +ĠSh iv +ä»Ĭå¹´ 以æĿ¥ +. white +Ġneed less +头 ä¹Łä¸į +çľ¼ çıł +_S CRIPT +ĠMcL aren +å®ĩå®Ļ çļĦ +_ vertices +Ġw afer +èĦļ è¶¾ +èİİ å£« +ï¼Įä½ľä¸º ä¸Ģ个 +Ġ åĿıè´¦åĩĨå¤ĩ +ï¼Į ä¾Ŀ次 +岩 æ£ī +-a verage +ĠCG Size +ï¼Į 计ç®Ĺæľº +çİĭ éģĵ +S MS +åIJİ è¢« +/d etail +g v +ãĢĤ ç»Ļ +æľĿ å¤ķ +_IN CLUDE +ĠD ai +Rem oving +RT OS +æķ² äºĨ +æ¸ħæ´Ĺ å¹²åĩĢ +(ex ception +ĠZe it +Ġ éħįç½® +禽 åħ½ +æĶ¹ åIJį +An a +Ġstruct uring +Ġbox er +Ġhabit ual +åIJ¸å°ĺ åύ +åĴĮ ç»Ħç»ĩ +åIJĮ æĹ¥ +Ch arg +ä¹Ķ æ±IJèİŀ +PF N +( (- +Z hang +没æľī çľĭåΰ +è¨Ģ åıĪ +ĠBrid al +å¼Ĺåħ° åħĭ +Ġt rophies +ĠS OS +éģ® èͽ +Ġforfe iture +ĠR outing +æĹł 礼 +Ġpe a +å¼Ĥ çķĮ +伸 åħ¥ +ï¼ĮæŃ¤ äºĭ +ĠDO E +Ġelectro chemical +俯 身 +ãĢĤ C +GL IBC +sem antic +åĬłå¿« äºĨ +大 ä¹ī +åı¯ä»¥ èĩªçͱ +ï¼Įä¸Ģ è·¯ä¸Ĭ +çļĦä¸Ģ 对 +. LOG +Ç IJ +ĠN Ps +apt cha +ãĢĤè¿Ļ åı¥è¯Ŀ +ĠOut fit +Ġo ok +Ġr iff +ĠSt rain +åı¤ å¸ĮèħĬ +_part ition +Ham ilton +ãĢĤ åĽ½åĨħ +_b oolean +Ġsed entary +Ġsc anners +çļĦä¸Ģ åıª +Ġtight ened +è¡° èIJ½ +_z ip +zbek istan +M akes +ï¼Į 软件 +ef eller +dep ends +A ust +M iller +åĸĤ é£Ł +. clip +ä½ł 说ä»Ģä¹Ī +è¯ģ è¨Ģ +èµł ä¸İ +uther land +typ ical +w anted +ĠB ally +çIJĥ éŨ +ĠCart oon +è¿Ľ 京 +Ġty ph +_pos itions +Ġbreat hed +" Not +Ġ@ { +Pro ceedings +åıį 常 +åijĪ çİ°åľ¨ +Ġfreel ancers +coord inate +åIJij èĩªå·± +æļ´éľ² åľ¨ +çļĦé¦ĸ è¦ģ +m atter +æĿ¥ 西äºļ +_d om +ĠZ ig +å¯Ĩ å¸ĥ +-sc enes +éĥ½æĺ¯ä¸Ģ æł·çļĦ +/d ec +connect ions +ĠSt akes +第ä¸Ģ åŃ£åº¦ +_message Info +ï¼Įèİ« éĿŀ +度åģĩ æĿij +æİ ³ +av ior +Ġcontrast ed +Ġcontrovers ies +or rent +\ hspace +ĠG ale +IP H +- Con +- Line +Ġ çİ°åľ¨çļĦ +让 人们 +带 åħµ +, ä»į +_D P +_PACK AGE +â IJ +ĠW AR +Ġun h +çī¹ æĢ§çļĦ +³³³³ ³³ +_ team +âĢľ All +åĴĮ åĨħ容 +çĦ¶ éģĵ +满 天 +ç±³ äºļ +æıĴ çĶ» +ï¼Į人 人 +Ġmood s +U x +Ġatt aining +è¿ŀ è´¥ +åĨĽéĺŁ çļĦ +ç»Ĵ æ¯Ľ +Ġj unctions +Ġne urom +Ġuns atisf +Ġr asp +Ġ# ' +E lim +le on +ĠIn vent +åĦ¿ 媳å¦ĩ +Ġtop ography +åĴĮ æĪijçļĦ +被 人们 +åĪ« åĨį +}, $$ +Ġcool ant +CP tr +ĠAtt acks +寿åij½ éķ¿ +ĠD AV +ĠN ell +é»Ħ æ³ī +åħ¬åı¸ å°Ĩ +Ġrel ish +åŃ¦ä¹ł æĪIJ绩 +å¤ľ å¸Ĥ +ĠVan ity +Ġbro chures +Ġphotos ynthesis +æ£į åŃIJ +ĠF rames +.F ill +åĩºå¸Ń äºĨ +æŃĩ æģ¯ +Ġintens ified +åħĪ ç¥ĸ +ĠF ACE +sh r +ï¼Įä¹Ł åıªèĥ½ +æľī æĽ´å¤ļçļĦ +对 ä¸į对 +_US ART +主èIJ¥ä¸ļåĬ¡ æĶ¶åħ¥ +éĢļ è¾¾ +ï¼Įåıª 为 +æİĮ ä¸Ĭ +ä¼ĺè´¨ æľįåĬ¡ +æĹıèĩªæ²» åİ¿ +å®Ī åĨĽ +æĭĨ å¼Ģ +Ġaest hetically +ï¼Į åĶ¿ +ï¼Į å®Ŀå®Ŀ +éĹ ¾ +åıĮ çľ¼çĿĽ +ç´« çłĤ +âĢľ è°ģ +åħ¬åı¸ ç»ıèIJ¥ +Ġprot ested +ĠChe es +comp ression +æĹ¥æĻļ éĹ´ +Ġ 建 +Ġc Äĥ +Ġst umbling +ib il +åı¤ æĸ¯ +ĠInter ruptedException +ymmet rical +åIJı éĥ¨ +at uration +_SL OT +ÏĦ ή +ĠPlug ins +æľī线 ç͵è§Ĩ +Ġfl ushing +çļĦçĥŃ çα +å°ģ åı£ +æ»ŀ çķĻ +æĸ°æµª ç½ij +åĬ¨äºİ è¡· +D ennis +x ed +Ġg zip +ĠB rack +åĬł æ³ķ +Ġund ec +Ġpol o +Ġrelie ving +Ġpl acent +被 åĩ» +sw ift +_set s +.or ig +åIJ ® +ç¿» éĺħ +column width +ĠSN AP +æĶ¾ åΰäºĨ +ah aha +Ġdiam eters +Ġrefriger ation +ĠTrib al +ï¼Į èĸĦ +ĠD ia +ĠK idd +-b g +åľ¨è¿Ļ æĹ¶ +Ġbast ard +> a +Ġsp aring +ĠInt roducing +Ġj ams +积æŀģ åĵįåºĶ +çĶĺ éľ² +ãĢģ 宽 +ĠO TC +游 èį¡ +_id le +ï¼Į大 åĵ¥ +C Q +G orgeous +Ġp wd +Ġn th +ĠW imbledon +Ġpart ed +Ġdi as +çĻ» åŁº +.as array +Ġfed eration +E ating +æĮł 头 +Sem i +åĴĮ åģ¥åº· +æĶ¹ äºĨ +IV ING +åħĪçĶŁ åľ¨ +Ġbelie vable +-d escription +bul k +ä¼ « +å°± 以 +åħ¬çĽĬ æ´»åĬ¨ +i R +ï¼Į ç§į +Ġpar ap +ï¼ĮæĢİä¹Ī åĬŀ +ĠMess i +ç«ĭ å¼ı +Ġeth yl +第äºĶ èĬĤ +Dom ains +. et +ĠPh o +ä¹Łæĺ¯ 为äºĨ +ĠBh ag +ĠRemed ies +æĬ¨ åĩ» +_ der +ĠPhys iology +ĠBeg ins +åı«ä»Ģä¹Ī åIJįåŃĹ +_ energy +ĠB SA +Ġwal nuts +abil ia +.p ool +Ġl ui +ph oria +缸åħ³ ä¸ĵä¸ļ +微波 çĤī +è¿Ľè¡Į åĪĨç±» +ĠSun der +g pio +ĠB ordeaux +èĩ ¼ +èģĶ ç¤¾ +.P ublic +ĠAst roph +Ġê tre +æıIJåįĩ åΰ +ĠDir ichlet +ĠDOWN LOAD +. ep +ä¹ĭ æ°´ +.d i +Off ers +è¡£æľį çļĦ +ï¼Į å¹´è½» +å°ı ä¼Ļ +åı· çīĮ +亲 çĥŃ +sec urities +港 å¸Ĥ +æİ¥ ä¸ĭ +åĪ© å¾Ĺ +_M M +Read ers +ĠCour age +ç®± çļĦ +, éģĩåΰ +åĴĮ ä¸Ĭ +ä¸Ģèµ· çİ© +è·³ åΰ +(file Path +æĶ¶éٳ æľº +a ith +{ (\ +缸 å¹² +人æ°ij åĩºçīĪ社 +inst ancetype +Ġalleg iance +Ġlay ering +Ġd urations +ä½ĵ å¼ı +ĠMe asuring +æĹł æ°´ +aw l +太 å·® +Ġpost card +ï¼Įä½ł è¿Ļæĺ¯ +Ġcrypt ographic +ĠÏĮ ÏĦι +Ġproject ile +priv ile +çĥŃè¡· äºİ +_ override +Ġt amb +Ġb fd +ĠMETHOD S +ag han +大 çĹħ +éļ¾ éĢĥ +Ġvisual izations +æľ¬æĿ¥ æĺ¯ +st ri +åĵĢ ä¼¤ +Ġextravag ant +im etric +Ġbe z +ĠP X +ï¼ļ åĮħæĭ¬ +ä¸İ ä¼łç»Ł +éľĢè¦ģ ç͍ +ï¼ĮæĿ¥ åΰäºĨ +@ param +Ġre define +ä¹° èıľ +_ad just +. install +åĴĮ æĬķèµĦ +(p ackage +Ġequival ently +ä¸ĵéŨ 为 +Circ uit +ĠD DS +é£İ æľºçļĦ +æ¥ļ åĽ½ +ìļ © +T rou +ï¼Į以 éĺ²æŃ¢ +arth a +èıı æ³½ +C isco +ãĢģ åİĭåĬĽ +ĠMac au +ãĢĤ对 äºĨ +ĠBT W +Ġremn ant +- ent +æĪij æĦŁè§ī +æĩµ æĩĤ +åĨ² é«ĺ +æŀ« åı¶ +\_ [ +is cher +ĠE ph +æĹ¥ æĿ¥ +管 æķĻ +ning ton +æĮģç»Ń ç»ıèIJ¥ +Ġaccus ation ++ l +ĠV ega +åIJį åı· +Ut c +Ġupl ift +. ag +æĻ¨ åħ® +èŃ¦å¯Ł å±Ģ +imp act +éĺ³åħī çļĦ +Ġparas itic +r oring +èIJ½ 泪 +ĠSir i +( edge +ĠIn line +æ¶Ĥ è¦Ĩ +ï¼Į 裴 +ä¸Ģ åĩ¡ +ãĢģ çłĶåıij +erm ont +è¶ħ æĹ¶ +c ine +Ġ æ°¸ +Ġt ion +ï¼Į åĩºçݰäºĨ +ĠA in +ä¿¡ äºĨ +.st ub +_ Start +ãĢģ éĢļ讯 +åįļ æł¼ +Ġsu cker +æ°´ 车 +ĠFor rest +æĬ± ä½ıäºĨ +-gener al +ĠAppe arance +m akes +ĠK yr +æĹ¥ æĺ¯ +éĽĨåĽ¢ åĨĽ +ĠApost le +Ġsens ual +çļĦåĨħ åľ¨ +_com ments +uther ford +" net +åı¯ä»¥ éļıæĹ¶ +èĬĤ èĬĤ +week ly +交èѦ 大éĺŁ +obacter ia +C ry +ac am +ĠGu ill +Relations hips +ac onda +æĬĢæľ¯ çłĶåıij +Ġoptim izations +isc overed +APP ER +Di agnostics +ĠBios c +éļıå¿ĥ æīĢæ¬² +Ġc ures +管 ç͍ +çī¹ æľī +æµģ è¿ĩ +å¾½ 竳 +Ġcaf eteria +çļĦ ä¹IJè¶£ +M oved +大 åħ¸ +ĠCabin ets +, æĦ¿ += name +Ph D +Ġ åĮħæĭ¬ +Ġcent roid +Reg ression +æ´Ľ æŀĹ +ä¸Ĭè¿° çļĦ +æĮ½ çķĻ +âĢ Ł +å¹´ æĹ¶ +天 å·¦åı³ +æıIJ äºĨ +unknown Fields +F abric +äºĮ ä¸Ń +å¸ĮæľĽ 大家 +len ame +说äºĨ åı¥ +ĠO asis +Ġmilit ant +ï¼Į æĢ§ +åľ¨ éĤ£ä¸ª +æĪij å¿ĥ +æŃ£ åĪĻ +说äºĨ ç®Ĺ +ĠFort ran +Ġimp over +Pl ate +Ġbom ber +Ġ åĬŀåħ¬ +çļĦ èĬĤå¥ı +ver n +éĢļ ç͍çļĦ +Ġed ged +A ES +ãĢĤ åĮ»çĶŁ +ĠI CON +被 åIJĵ +æµ· è¿IJ +æ·® å®ī +ĠS ut +-t rial +.C L +鼨 ä¼ŀ +æij© 天 +çν æľĹ +ä¼ijæģ¯ äºĨ +N ine +大 åĪĢ +éĩį大 äºĭ项 +Ġov ens +ĠT itles +( web +B uzz +ĠDel phi +ĠAv on +ĠMess aging +.Compiler Services +ĠSchr ö +ä¼ļ 社 +ather ing +å¤ĦçIJĨåύ æī§è¡Į +ĠT ribute +Ġam et +æĪij åģļ +èĢģ å°ij +éĿĴ åŁİ +ÃŃ as +ĠNic ola +ç´§å¯Ĩ ç»ĵåIJĪ +B le +ï¼Į èĪĴ +ãĢĤ æŀľçĦ¶ +æĬ ¡ +æ¯Ķ æ¯Ķ +Ġwater ways +ĠSam my +å±Ī åİŁ +Ġt gt +ï¼Į æł¼ +ï¼Į éĻª +åĴĴ è¯Ń +éĽĩ åijĺ +ãĢģ åijĺå·¥ +bb b +Ġtransf ection +ĠBeng als +对 讲 +è¿ĺ 为 +ĠMaster card +ï¼Įè¿Ļ åı¯ +ç§» éĢģ +çIJĨè§£ çļĦæĺ¯ +éϵ åĽŃ +ìł ķ +. TR +èĦ¸èī² ä¸Ģåıĺ +construct ed +ï¼Įä¹Ł åı¯èĥ½ +åı¯ä»¥å¸®åĬ© æĤ¨ +ĠJehov ah +C URRENT +H AVE +ac enter +éĢļ ç¼ī +ãĢĤ çζæ¯į +ĠU rb +Al bert +.P os +ĠPaper back +dog s +Z H +} d +ï¼Į åĸĦäºİ +âĢĻ âĢĻ +ĠApp arel +é¦Ĩ éķ¿ +ä½³ ä½ľ +ï¼Į åIJĮæĦı +ĠH are +åģľ å·¥ +Ġadvert iser +Ġcancell ations +O lymp +id opsis +ĠM CA +Ġ× ľ +/app s +M ULT +çļĦ ç²īä¸Ŀ +Ġre writing +ï¼Ī âĢľ +Ġinstall ers +ĠEvent Handler +çļĦ çĶŁçī© +ĠM PU +å¤ĸ è¾¹ +约 车 +Ġdri zzle +Ġnames paces +æĬ¢ è´Ń +ĠArm our +R ename +ä¸Ģ æĹ¶çļĦ +Ġcont r +Al cohol +æķij çĶŁ +å°± èµ°äºĨ +管 åĨħ +Invalid ArgumentException +ĠDIS C +ç³»ç»Ł æĢ§ +æł¹æľ¬ å°±æĺ¯ +Ġtum ble +Ġdisp ensing +Ġmillenn ia +th orn +å¿Ĺ æĪIJ +AV EL +ĠInnov ations +ou k +åĪ« æĹł +èIJ½ ä¸ĭæĿ¥ +ĠPr ism +ĠOper and +ĠPath ology +_work er +. asset +h ay +ĠD ucks +éĩįè¦ģ çļĦäºĭæĥħ +Ġgre ener +Ġpremature ly +Ġdet riment +Ġtro op +æĪĺ æĹ¶ +Ġdisp enser +Ġmes hes +/pro file +æĢł æħ¢ +t il +åĩº å¥ĩ +çĿĢ è£ħ +产 éĶĢ +æĸĩåѦ å¥ĸ +-th inking +Ġmel odic +ĠW ednesdays +åΰ è´¦ +æ·±åħ¥ 人å¿ĥ +h ape +ĠE ase +为 æĮĩ导 +itt a +æ±Ł å¤ı +æ¦ Ķ +Ġred ox +é¢Ħ设 çļĦ +Ġhere to +Ġ================================================================= ======== +Ġun loading +头 çŃī +ĠIntern ship +,èĢĮ åľ¨ +Ġpolic eman +æĸ° ä»» +æĭĨ è§£ +åĩł çľ¼ +çļĦ è¯Ĺ +Ġtr imester +_c urve +/ New +æĿ µ +ãĢģ çݯ +大 æ±Ĺ +ĠV anguard +Ġsc uba +/k ubernetes +- import +. allow +G ST +c akes +çļĦ çľ¼ä¸Ń +åĬ¨ åľ° +è¿ĺ åī© +Ġdown fall +ä½ķ 人 +æĭį åΰ +_PL AY +à¯ģ à® +ad r +ä¹ĭ è§Ħå®ļ +ãĢĤ è¡Į +Ġbl azing +.b ool +ãĢģ äºĴèģĶç½ij +ex cel +ibr ate +Ġord inances +ĠBlock ly +ï¼Į ( +Com paring +unc ated +Ġorgan ically +ĠPa ige +å°ijå¹´ åĦ¿ç«¥ +ĠCle aring +Ġde ceive +Ġtow ering +Es pecially +Ġelucid ate +ĠM ST +被 害 +éĥ½ä¸į éĶĻ +( queue +ç»ĵ 缣 +å±ħ æĺĵ +æĸľ éĿ¢ +/ red +ãĢĤ ç¥ŀ +éģĵ åħī +åŃĹ çľ¼ +çģ« ä¸Ĭ +Ġbreak point +ĠCount s +æĸ½ ç͍ +Ġste amed +g raphics +(file path +_DIRECT ORY +re ject +ĠM ODULE +ĠH aj +Ex clude +è¦ĨçĽĸ çİĩ +åįĩ åΰ +æĿĢ æŃ»äºĨ +Ġä¸Ģ 声 +Ġse o +ĠChe ney +_fl ash +Ġquad rant +. IM +re levant +ĠM our +ID GET +PE LL +临åºĬ 表çݰ +. bs +çļĦ æĿ¥ +人 æĿĥ +æīį åŃIJ +åĿĩ å̼ +ĠBra ves +广éĺĶ çļĦ +. placeholder +: + +ï¼ļ çͱäºİ +æĻ ģ +ï¼Į为 æĤ¨ +åħļçļĦåįģä¹Ŀ 大 +Ġst itched +az ioni +å°Ķ éĽħ +anag ed +ì Ĥ¬ +ï¼ ĩ +æĹ¥ æĻļä¸Ĭ +åħį åıĹ +åıijæĮ¥ çĿĢ +çĽĨ æĻ¯ +OC O +Ġintimid ation +åıĹ å®³äºº +ĠSc am +èİ·åıĸ çļĦ +Ġintermed iary +èİİ士 æ¯Ķäºļ +H ip +æľ¬ åįķä½į +, ä¾ĿçĦ¶ +æĸ° åĨľæĿij +Ġdifferent iating +Bar ry +æ·¡æ·¡ éģĵ +Est imate +_ ob +èĩª èĭ¥ +Ġstore front +ĠL ark +èĥ½ 帮åĬ© +οÏħ με +c old +âĢľ äºij +èĩªå·± ä¸į +ä»ĸçļĦ 身ä½ĵ +.un pack +Ġbin ocular +Ġunfair ly +çĶŁäº§ èĢħ +æī§è¡Į åĬĽ +ĠCl oth +ĠFl utter +ä»ĸ ç͍ +ĠEx ams +ĠSp art +é©° éªĭ +ĠH orton +ç´ł æľī +åĢ ¤ +ĠY O +èĬ± 鸣 +èİ« 大çļĦ +çļĦ æĪIJåĪĨ +ĠS AME +åĩł ç§ĴéĴŁ +管çIJĨ è§Ħå®ļ +åĩ¶ éĻ© +ĠV ocal +ï¼Į以 å®ŀçݰ +éķľ éĿ¢ +çļĦçݯå¢ĥ ä¸ĭ +Ġj ailed +èĢĮ åĩºçļĦ +é«ĺ 强 +éĺµ åŀĭ +çݰ代 åĨľä¸ļ +ï¼Įåħ¨ çľģ +åĩº è¿ĩ +Ġeffect or +· 奥 +Ġf url +åľ © +if ers +éģĩ éļ¾ +-th read +ãĢĤ æĭī +ĠL DA +æĿİ åŃIJ +ãĤ ± +è´¨éĩı 管çIJĨä½ĵç³» +å¨ģ æµ· +ĠBO X +åįĬ个 æĹ¶è¾° +ë© ´ +k B +ï¼Į è̳ +ãĢģ æĿľ +Property Value +ĠWer ner +/ linux +h ui +ĠI IS +ï¼Ł ä¸įæĺ¯ +主è¦ģ ä»İäºĭ +æ¼Ĥ æ³Ĭ +Ġ` * +åºĶ该 ä¼ļ +çİ» å°¿éħ¸ +ĠMad agascar +~ * +Ġ 宫 +Alloc ate +, ç»ıæµİ +? org +ãĢģ éĵģè·¯ +ï¼ģ ãĢij +Ġcol loqu +ĠIs les +ç»ĵæŀĦ ä¸İ +/m aterial +对大家 æľīæīĢ帮åĬ© +主 讲 +羣 åħĥ +åĩºçīĪ çī© +.a udio +D egrees +\ index +~ - +她 èĥ½ +ĠAng ry +çĥŃ æĴŃ +.p id +çīĮ åĿĬ +åIJĦç§į ä¸įåIJĮçļĦ +Ġfear less +æĢľ æĥľ +âĢľ äºĴèģĶç½ij +åĽĽ 溢 +æ¯ģ åĿı +B uck +ĠSt acey +æĹł è¶£ +åľ¨ ä¸Ģå®ļç¨ĭ度ä¸Ĭ +Ġstr ata +ung a +è½°çĤ¸ æľº +ĠHuff ington +好 å¤ļäºĨ +(' ../../ +ĠUS SR +çļĩå®¶ 马德éĩĮ +Ġunle ash +ĠM OVE +æĹ¶ åºı +Ġun read +Ġ@ ( +_B IN +Ġì ĺ +ï¼Įæ¯ı æľĪ +åį³å°Ĩ åΰæĿ¥çļĦ +Ġfreel ancer +Ġ è½° +Ġo prot +ar ro +ĠB d +ç±į è´¯ +çĶµæ±ł çļĦ +{AD IE +ä¸į æķ£ +å°± åıĪ +-ch ief +è£ħç½® åĴĮ +Ġqual itatively +è·ŁçĿĢ ä»ĸ +Ġwhen ce +çݯ 顾 +åŁİå¸Ĥ ä¸Ń +驱éĢIJ èΰ +, æ¯į亲 +çĭ¬ åįł +ORIZ ONTAL +ĠG REEN +Ġsur jective +oci ations +res olution +Ġro aring +ä¿® è¾ŀ +éĺ³ çº¿ +il ts +ï¼Įä»İ ä¸Ń +Ġvirtual ization +ç¥ŀ æĢģ +L ights +Ġt ides +æķ° åįģå¹´ +Ġmet formin +æī§è¡Į èij£äºĭ +æĥ¨ è´¥ +ç¡ħ è°· +( math +ï¼Į è·¨ +ep loyment +å®ī åIJī +ä¸ĢäºĽ éĹ®é¢ĺ +Ġbo asting +Ġnour ishing +N arr +åĬ¨ èµ·æĿ¥ +Ġrest room +Ġf oes +åĴĮ åįĹ +ï¼Įä»ĸ èĥ½ +ç§ĭ 天çļĦ +横 æĿĨ +ĠCr ush +åİŁæĿ¥ å¦ĤæŃ¤ +, æĸ¹ä¾¿ +ä¿ĿæĮģ èī¯å¥½çļĦ +zy k +ĠSUV s +ãĢģ 山西 +声 ä¹IJ +, åıĸ +å¹´ åıĤåĬł +é¡¹çĽ® éĥ¨ +ĠEn ables +æľĢå¿«çļĦ éĢŁåº¦ +Q W +ol it +Normal ized +åIJİç»Ń çļĦ +积 æľ¨ +ĠOb esity +_ ports +ĠY ay +ON US +ಠ¿ +æĶ¿åĬ¡ æľįåĬ¡ +Again st +/ ip +set Name +ãĥ³ ãĤ° +ĠS amp +æľ¬ åħ¬å¼ĢçļĦ +åĨħ 裤 +uch a +IC I +ĠCD T +丼 ä¸Ń +mir ror +- character +ĠB ikes +人 è¡Į +.r ules +( en +ï¼Į ä¸Ĭæµ·å¸Ĥ +åı¯ 被 +ĠK W +Ġgr unt +wh itespace +éĤ¦ å¾· +ĠBonus es +- edit +ĠC ascade +ï¼Ł å°±æĺ¯ +ï¼Įä½ł å¿ħé¡» +çľĭåΰ è¿Ļ个 +åľ£ è´¤ +代çłģ çīĩ段 +Ġquart et +èĦļæīĭ æŀ¶ +R at +æľ¬ æł¡ +空 èħ¹ +è¾ĥ æĹ© +RO UGH +Ġwin eries +å®ģ å¾· +踩 åľ¨ +Ġw iser +ĠH ugs +_M IC +åĩĢ å¢ŀåĬłé¢Ŀ +Invest or +con version +ĠInteg ral +ann ounce +-d om +Ġ 梦 +pc m +. An +C rew +å½ĵ ä¹ĭ +åĩº äºĭäºĨ +对 ä»· +ush ima +ds a +ä¹Ŀ 竳 +ĠCar la +Pub Key +Ġeyeb row +à į +ï¼Į ç©¿è¿ĩ +ĠZ ones +ĠMoz art +ãĢģ éķ¿æľŁ +Ġinaug uration +ĠP DP +ï¼Į æĵħéķ¿ +åĴĮ æĹ¥æľ¬ +_F N +Ġf idd +ä¸į éľĢ +ib ase +rac ies +Thread Pool +å¹´ ä¸ĭåįĬå¹´ +ĠK ag +èĩªå·±çļĦ å°ı +èĹı çļĦ +åįıä¼ļ çļĦ +Ġfertil ization +. Expression +an h +Ġcomm encing +ä¿ĿæĬ¤ çļĦèĮĥåĽ´ +Ġrig orously +âī Ī +âĤ ģ +ric orn +Def erred +_RE QUIRED +âĢĺ The +çĿ£ åĬŀ +汤 åľĨ +, æľīçĤ¹ +ãĢģ çŁ¥è¯Ĩ +çϽ 头 +ita ire +ä¸Ģ çıŃ +ĠExt end +Ġinstant iated +ĠKar achi +ä½ł 个 +ç¥ŀ çζ +ä¹Łæ²¡æľī æĥ³åΰ +诵 读 +hen y +ĠPr as +ç͍æĪ· 对 +å·¾ 帼 +æ°Ķ æĢ¥ +åĮħ è¦Ĩ +æĸ¹æ³ķ åıĬ +æŀª çļĦ +det ect +Pur ple +æĿĢ伤 åĬĽ +M AG +ï¼Į èĤ¡ç¥¨ +ĠSt anton +级 以ä¸Ĭ +马 çͲ +å¸ĥ 满äºĨ +åĵį å½» +åģľ ä½ı +typ ing +draw able +Ġcro oked +èµ·çĤ¹ ä¸Ńæĸĩç½ij +ĠCann es +å¾Ĺ天 çĭ¬ +Ġf rac +å¾Ĺ è¿Ļä¹Ī +Ġstart led +å¿« åİ» +çĶľ çļĦ +éĻĢ èŀº +Âł çϽ +å¾Ī ç´¯ +ÙĦ Ùī +ĠM AD +Ġem bol +Ġgene alogy += X +åĴĮ çα +ä¸ĭ åºĬ +Ġaffect ive +æīĢåѦ çŁ¥è¯Ĩ +æĹ¶ 为 +çīĪ åĿĹ +æ´ŀ åºŃ +çijŀ æĭī +ĠNO AA +å¬ Ľ +Ġrecharge able +-adjust ed +Ġmelanch oly +m pp +èĥľ äºİ +het to +ĠPy ramid +ä¸Ģç³»åĪĹ çļĦ +ent es +æ¸ħ åĨĽ +Ġalk al +ä¸ĭæĦıè¯Ĩ åľ° +Ġa cl +è½½ 人 +ãģ§ ãĤĤ +.Test s +ä¸įçŁ¥ä¸įè§ī ä¸Ń +p ink +ï¼Į ç´¯ +åΰ ä½İ +åµ ĺ +Ġsplic ing +ë ² +æĪij 羣 +æķıæĦŁ çļĦ +:` ~ +ĠLect ures +ï¼Į åĽŀå®¶ +ĠS ark +ĠC URRENT +ä¸į åīį +uh n +onom ics +ĠGall eries +Ġph ag +ĠDet ector +éĹŃä¸ĬäºĨ çľ¼çĿĽ +C ab +ä¼ł ä¸Ń +带 è·¯ +Columb ia +- export +M p +çĻ ¿ +æ±ī å§Ĩ +Ġarr h +agg io +Ġfauc ets +Enh anced +ä¸Ģ åľ° +ag ree +iv os +Ġro y +åĩĨ äºĨ +Ġà ľ +Ġnewcom er +P ont +åĮ¹éħį çļĦ +Ġf ashions +æĸ¹å¼ı æĺ¯ +ä½³ 绩 +Mar ine +æĹłäºº 驾驶 +/r uby +Ġpir acy +( Input +åŃ¦æľ¯ 交æµģ +_ACT IVITY +. uri +; T +ï¼Į ç¥ĸ +ur ple +ĠAcc ent +æĶĢ çά +ocarcin oma +Pre heat +"/ > (), +笨 æĭĻ +Ġdrift ed +åľ¨ 京 +_P WM +è£ħä¿® é£İæł¼ +è¡¥åħħ éģĵ +çļĦä¸ĢåĪĩ éĥ½ +ç¾½ 翼 +ĠTravel ers +å®īå¾· çĥĪ +( Arrays +éĥ¨ æĹı +Ġac claim +èľ ĵ + namespace +_ext ract +ï¼ĮæĬĬ å®ĥ +Ġfluct uate +Ch ance +åı¯èĥ½ åŃĺåľ¨ +宽 大 +Collect ors +é« ĭ +AL A +_h alf +/m o +Ġapprec iating +ĠWal ters +( images +æİ £ +Ġcons olation +åİħ éĩĮ +Ġcere bell +Ġip a +Ġphilosoph ies +ĠM acy +Ch ron +ä½Ļ ä¸ĩåħĥ +ĠNS MutableArray +Ġ\ {\ +ĠAn alyzer +° ï¼Į +ç«Ļåľ¨ äºĨ +å¸ĮæľĽ èĩªå·± +Pay ments +ĠBad ge +, 社ä¼ļ +, 大å¤ļæķ° +ï¼Į æĥł +Ġ å®ŀéªĮ +Ġve z +.l ight +_sub ject +Ġ éħĴ +æİ¥ åºĶ +åIJĦ åĽ½çļĦ +ï¼Įä¸Ģ 举 +éĴ¢ ç¬Ķ +or ator +ä¸Ģ åºĶ +Ġx t +æ®ĭ æļ´ +æĹĹ é¼ĵ +åĬĿ 导 +Ġhate ful +ne k +ä¸ĵä¸ļ æĬĢèĥ½ +èĬĤ缮 ç»Ħ +åī¥ åīĬ +飧 带 +ï¼Į æĶ¶åħ¥ +round ed +æ³¢ æ¶Ľ +ç»ĥ åĬŁ +交æĺĵ ä¸Ń +W IDTH +Ġst rom +ãĢģ 麦 +=" ..\..\ +è¶Ĭ ä½İ +ĠSy ll +ç¼ĸçłģ åύ +ä¸į å°ıäºİ +å¿ĥ èħ¹ +çŃī äºĭ项 +è¾Ľ 亥 +Ġconver ters +. Extension +im etry +}\ | +èĢĢ çľ¼çļĦ +_ keep +åıij çĸ¯ +oint ed +计ç®Ĺ åħ¬å¼ı +pat ches +ä¸ĭäºĨ 车 +Ġ**** * +åĬ¨ 身 +_C AST +åIJ¬ åύ +æ¶Ĥ ä¸Ĭ +ĠTom as +ĠCE LL +çŃī çĸ¾çĹħ +ĠDr one +Ġpri zed +ake up +: ^( +L t +æī¯ çĿĢ +Ġnan ot +ĠKens ington +ä¸Ń å±Ĥ +éĿĴæĺ¥ çļĦ +Ġ对 æŃ¤ +ĠP ARK +ãĢģ N +-w riting +åıĸå¾Ĺ æĪIJåĬŁ +ĠFern andez +èĤ¥ èĤī +oz ora +-d at +å»¶ç»Ń äºĨ +ï¼Į å¹³åı° +æĹ¥ èijµ +ien a +ĠMem oir +Sen ator +Ġthromb osis +pec ies +å®īæİĴ éĥ¨ç½² +fill ment +(se ed +å°ı çľĭ +eter a +ĠAS M +,çĦ¶åIJİ åĨį +, æĦŁåıĹ +P el +ĠD FT +æĪij 身边 +é½IJ äºĨ +篡 æĶ¹ +ï¼Į åĭ¿ +ĠT olkien +æľī çļĦæĺ¯ +ä¹Ł ç§° +Ġph arma +æľīæľº 溶åīĤ +@ test +× Ĺ +ä»ĸ è¿Ļ个 +Ġequ ate +rav a +Ġferm ions +ĠM AV +t emperature +éĽª åľ° +ä½³ èĤ´ +ãĢĤå½ĵ ä»ĸ +æ¶Īéĺ² æķijæı´ +ench ymal +ĠK ann +æĪĺ ä¹± +èIJ½ å·® +Ġlingu istics +M OV +Â Ķ +Ġ eller +ĠC oco +çĤ Ķ +Ġproperty Name +,æīĢ以 åľ¨ +Ġsp anish +åĸĦ å¾ħ +Of Week +ÏĢ Î± +ï¼Įä»ĸ 被 +Ġrest ores +ĠSp okane +è°ģ ä¼ļ +æĻĵ 彤 +ĠSpr inkle +Ġalphabet ical +p ictured +ï¼Į çģ° +ä¸Ĭ 人 +æĢ§ åıĬ +éĺ² æĴŀ +åĤ¨ ç½IJ +Ed ition +åħ¨çIJĥ çļĦ +ï¼Į两 åıª +æĴ Ĥ +Ġsubt ly +ä½ıæĪ¿åĴĮ åŁİ乡建设 +, 对æĸ¹ +åħ¬ é¦Ĩ +æīĭ æĿ¥ +.f ragment +Ġhist opath +èľ ĥ +Ġobsc ene +/ ac +ĠL act +广 为 +_n umpy +Ġs ipping +ust a +èĥ½ åIJĥ +èĦij éĥ¨ +ĠWilk inson +M z +å°ı 便 +Ġgr inned +ĠHow ell +å¾ħ åĶ® +Ġtyr anny +Ġ æ¯Ľ +ï¼Į çĭĹ +ï¼ļ If +ï¼Į æİ¨åĩº +大 é¹ı +Ġi Cloud +ãĢĤæĪij ä¼ļ +æĥ¨ äºĨ +ä¹ĸä¹ĸ çļĦ +æģ°å½ĵ çļĦ +ĠîĹ¥îĹ¥ âĢľ +min ute +Ġtre asured +æĹ§ åĿĢ +éĺ´ æ£® +ĠProject ion +ĠWater front +in crement +æĥħ æľī +èľ » +ä»Ļ åīij +åıĹåΰ 伤害 +好å¥ĩ çļĦ +K u +Ġu rea +ĠM VT +èĢĮ éĹ»åIJį +ãĢģ å·Ŀ +ph olst +èļ ĵ +èľ ´ +å·¥ä¸ļ åĮº +æ®ĭ 渣 +azz i +ĠD oo +æłij 人 +Ġstaff ed +Ġamb ience +accept ed +# L ++ ] +ra i +_d type +éĢł çļĦ +ãģ¦ ãģĦãĤĭ +èij± èĬ± +æĺĵ失 æĢ§ +, ), +åľ¨ è¿Ļæł·çļĦ +请 ä»ĸ +ĠLow ell +Âł The +è¯ģ çĽij +æ²³ åĨħ +åŁİå¸Ĥ éĩĮ +纱 线 +æŀĦéĢł åĩ½æķ° +ãĢĤæĪªèĩ³ 缮åīį +c en +ï¼Į çĭłçĭł +ãĢĤ ä¸įå°ij +Ġmicro array +Ġang led +ĠTom atoes +åħ¨èº« çļĦ +( activity +Ġa usterity +ãĢģ æŁ³ +æ°´ çģ« +") : +fl ate +ĠBar bie +Ġdehyd rated +l ery +ĠRev ival +夫妻 ä¿© +H orse +ĠDomin ion +为äºĨ éģ¿åħį +举 人 +ĠSeason al +.m ulti +Message Type +Ġaccum ulator +ĠAutom atically +P LE +Ġ æŃ¦æ±ī +Ġr tl +æģĴ å®ļ +çļĦç¥ŀ å¥ĩ +ĠChev ron +天 éŨ +ĠTam my +ãĢģ çͰ +çº ¾ +ä½ľ çĶ» +票 éĿ¢ +ä¸Ģ缴 被 +ĠExecut or +aphy loc +ï¼Į ä»·å̼ +ĠW ired +è¶Ĭ åıijçļĦ +car bons +el ius +Ġbe gs +ç»ĻæĪij ä¸Ģ个 +æĭľ è§ģ +ĠCL IENT +D utch +K s +ĠN ucle +Ġk or +ĠCard iovascular +æĪ¿äº§ è¯ģ +H AM +H ooks +og raf +ï¼Įå¦Ĥæŀľ æĪij +Ġepigen etic +ï¼Į æķ°åŃĹ +Ġt aped +Ġinv ading +ä¹İ åħ¶ +çι å¨ĺ +_ ce +ud u +缴 éĢļ +Whit ney +Ġ æ¡ij +ĠF olding +lo ch +Ġun born +ï¼ĮèĢĮ è¿Ļ个 +Order By +ĠXia omi +çļĦ åĩłçİĩ +祸 é¦ĸ +, æĹ¢çĦ¶ +åŃĺ æĶ¾åľ¨ +ĠPat reon +ĠCly de +all on +åĶIJ åĥ§ +ĠRest art +Ġabsent ee +as n +å¾Ĺ å¿ĥ +Ġam ps +å¸Ī å°Ĭ +éĶĤ 离åŃIJ +L X +[ Illustration +åĴĮ åīį +离 äºĨ +è¿ĺæĺ¯ 没 +æĹ© æķĻ +ï¼Įä½Ĩæĺ¯ ä½ł +éĽĨä½ĵ ç»ıæµİ +ĠMah ar +Ġ" .. +åĸĿ 彩 +ï¼Į åģļäºĨ +çļĦ å±ŀæĢ§ +Ġwe arer +ĠFree ze +è´ŁéĿ¢ æĥħ绪 +帮åĬ© ä»ĸ们 +ĠCra igslist +åį´ åıijçݰ +æ²ī éĿĻ +ä¼¼ä¹İ ä¹Ł +ä¸į åħ·æľī +æĹł èıĮ +äºĮ 年级 +æ·± åĬłå·¥ +Ġreve rence +ĠShr imp +ç»Ŀ äºĨ +伦 çī¹ +,è¿Ļ个 æĹ¶åĢĻ +Ġ åĩĨå¤ĩ +第ä¸Ģ çľ¼ +æĸŃ è¨Ģ +ĠCos metics +> # +up arrow +泸 å·ŀ +D ependent +ï¼Į ç½ijç«Ļ +ãĢĤ èĢĥèĻijåΰ +ãĢģ åĮĸ +åıĪ æĺ¯ä¸Ģ个 +ä¸Ģ å¸Ĩ +ãĢģ E +ä»ĸçļĦ åIJįåŃĹ +ï¼Įå½ĵ æĪij们 +ä¾į ä»İ +ĠAdjust ment +çݰæľīæĬĢæľ¯ ä¸Ń +J AVA +ud ential +ï¼ĮæĪij åı« +æ¸ħ æ°Ķ +ĠPay ing +Help ful +F amilies +C ARD +ct ools +Ġaut opsy +, èĩ³ä»Ĭ +- fig +e ys +Ġb lower +ell ants +éķ¿ åº¦çļĦ +ï¼ī + +ä¸ŃçļĦ æīĢæľī +ĠAtt ractions +walk ing += >>> >>>> +ï¼Į éĢĥ +åıij çIJĥ +Ġoff end +CC I +ĠAnal ytical +Ġhydro carbon +寿 åı¸ +Ret ention +ï¼Į åŁ¹èĤ² +Ġo ysters +åĽº ä»¶ +ant z +ï¼Įåľ¨ åħ¶ +模æĭŁ åύ +Ġin herits +. identifier +è¦ģ åĿļæĮģ +ä½Ļ çĥŃ +Ġna ïve +Ġ'@ / +: R +} O +ĠS CE +ĠThe o +éļ¾ åº¦çļĦ +Ġob edient +SP AN +çļĦæīĭ æİĮ +Mat chers +ĠSam pling +åľ¨æĥ³ ä»Ģä¹Ī +ãĢĤ åħ¨åĽ½ +æĸ¹ åŃIJ +_C ENTER +ĠPh osph +ĠQuick Fix +ĠRoy ale +éĩĩ访 ä¸Ń +-test ing +Ġmason ry +-L ife +æ¸ħæ´ģ èĥ½æºIJ +å®ŀæĸ½ä¾ĭ æıIJä¾ĽçļĦ +Ġsan itize +.new Instance +Ġ ä¿ĿåŃĺ +ï¼Į éĩįè¦ģçļĦæĺ¯ +ãĢĤ åĮ»éĻ¢ +- pos +çŃī æĸ¹æ³ķ +ĠQ Q +az o +ĠAs ians +osp els +åĪ©ç͍ äºĨ +ç²Ĺ 壮 +ĠTw ain +ï¼Į æıĴ +ĠR DF +-> __ +][ : +Ġexhib itors +å¹¿æ³Ľ åħ³æ³¨ +Optim ization +C BC +Ġ åζ +å¤Ħ ä¸ĸ +Im mediately +Ñĭ й +Marc us +Ġb im +ĠSe ymour +-d iff +ï¼ĮæĬĬ æı¡ +ï¼Įä¹Łè®¸ æĺ¯ +, åıijå±ķ +ve al +AL LOW +åĩłä¹İ æīĢæľī +ige on +_emb edding +çĽijæĬ¤ 人 +èľ· 缩 +ĠF ayette +ĠN ab +ï¼Ł 欢è¿İ +常 说çļĦ +满 çļĦ +ĠPl um +åĨĻ å®Į +西 åĮº +ï¼Įåıªè¦ģ æľī +ĠWild cats +ĠRece ipt +abcdefgh ij +çŃī å¤ļ项 +ç§° è°ĵ +ĠAb rams +欣 欣 +æĹ¨ æĦı +some one +ä¿ı èĦ¸ +Ġexting u +å°± åıĺæĪIJäºĨ +red ential +èĥĥ çĤİ +ulner able +ઠ¾ +ĠIn visible +æİ¨ è¾ŀ +约 约 +Ġver d +æĥ¨ çĥĪ +å¾Ĺ éĢŀ +åIJij åħ¶ +ä¿® èĢħ +æ¦ Ń +Ġintellect ually +M ID +Ġcompanions hip +ĠNotImplemented Exception +ĠZucker berg +çļĦäºĭ åĬ¡ +ĠDermat ologist +as pect +éĩį è´Ł +ç»Ļä½ł ä¸Ģ个 +Ġchief s +Ġ$ @ +ä¹ĭ çģ¾ +ĠV inci +碳 æİĴæĶ¾ +ĠCR YPT +Ġprospect us +ç¯Ŀ çģ« +ä»ĸ 没 +Run s +ag ency +ens ibly +miss ibility +è³ ĩ +, å¹³åĿĩ +an imal +Ġsh aky +æµ· çĶŁ +æł¸ éĶĢ +Ġmicro phones +Ġmalign ancy +eque ue +ord inal +ĠSp artan +Ġcmd let +大 é»Ħ +è·µ è¸ı +Ġaccol ades +Ġab duct +绣 èĢĥ +å·´ åĭĴ +åĸĦ æģ¶ +ĠM arm +æĪij å½ĵæĹ¶ +ĠGu inness +å¹¶ èĮĤ +Ġdict ator +Ġcha ired +ï¼Į ä½ĵçݰäºĨ +åīį èĮħ +被 æ·ĺæ±° +Acc ommodation +| [ +sh ipping +jug ated +ĠD CA +,åľ¨ è¿Ļ个 +Ġconv ict +O OK +ãĢģ 人工æĻºèĥ½ +Ġsyn onym +SH IFT +ĠRub io +Ġwill s +çĤ¹ åľ¨ +Ġra is +Ġcor iander +æĸĩä»¶ åIJį +Ġcategor ize +C it +Cl aire +ï¼Įæľ¬ 书 +Fant asy +ĠParl ament +{ remark +å°ı å¿ĥçļĦ +Ġper ish +pc i +gener ally +Ġsynerg istic +F iber +_ ER +Ġex clusions +Ġprov oked +Ġresp ite +å±ħ ä¸Ń +Ġcas o +ĠOm ni +ĠC ologne +ĠF lux +为 ç͍æĪ· +缸åºĶ åľ° +ic olor +ç½ij绾 游æĪı +| " +Ġan glers +ut tered +æŀĹ å®¶ +inter rupt +æŃ¦ ç¥ŀ +æ¶ī å¤ĸ +çĸ¼ çļĦ +_F ILENAME +ï¼Į 躲 +çıŃ ç»Ħ +Ġrefresh ments +/ packages +Ġm pg +,éĤ£ æĺ¯ +Ġip ad +Ġdisgu ised +J L +Ġsp ar +æ¿Ģ æĢĴ +ir ut +çłĶç©¶ äºĨ +- loading +H RESULT +çļĦ æŃ£å¸¸ +ĠR t +ä¸Ģ è¯į +ĠTh rift +eg ra +Ġreg ained +ĠBut tons +r ÃŃ +ĠM ord +Ġpro gesterone +åĽŀ 访 +ruct ose +QU ENCE +/ AP +ĠP ROM +çŃī ä¼Ĺå¤ļ +åľ¨ èĭ±åĽ½ +ĠG ourmet +æĿij 级 +ĠC umberland +Ġpass ports +æĶ¶åħ¥ åĴĮ +ro de +èĭ± çī¹å°Ķ +念 çĿĢ +, èĩ³äºİ +y ar +Ġ è´Ŀ +å¤ĸ ç±į +åĬŁ åIJį +ä¸¥æł¼ è¦ģæ±Ĥ +target s +èģĶ缣 çļĦ +,t p +ĠRot terdam +çļĦ帮åĬ© ä¸ĭ +æ¸ħ æ²³ +éĿŀ æµģåĬ¨è´ŁåĢº +ë ¬ +ens ical +Ġid ols +享 æľīçļĦ +OS C +Ġsu ing +åij¨ éģŃ +åĪĿ å¤ı +ãĢĤ 综åIJĪ +ãĢĤ èĻ½è¯´ +æį¢ åIJij +æĻ® 京 +å¦Ĥä½ķ åİ» +奢 æľĽ +æīĵ个 ç͵è¯Ŀ +T iny +ĠP ines +Ġal c +ï¼Įåı¯ ç͍ +æĪIJ绩 åįķ +Ġjournal ing +ä¸įå¿ĺ åĪĿå¿ĥ +æľī ç¥ŀ +Ġ' (' +å¼Ģ å¼ł +AC ING +ĠBuild s +çļĦåľ° åĽ¾ +çľĭå¾Ĺ è§ģ +, æīįä¼ļ +od ie +ìľ ¼ +l ave +ãĢĤ é½IJ +åĴĮ 交æµģ +-t rip +欢 å¿« +åģ¥ ç¾İ +æ½ ¦ +.w riter +pal ette +åİ¿å§Ķ 书记 +ä¸Ģ èIJ½ +大 ç¢į +å¿ĥ éħ¸ +çŃī è¯Ń +ĠAs king +Ġun suitable +é©» æĿij +ĠDu plicate +F ight +UN TRY +ठµ +ĠSub division +ĠT oni +ĠG iles +-d ays +çļĩ æĹı +Ġmis interpret +éĿ¢è¯ķ å®ĺ +[ H +co herent +å¯ĨéĽĨ çļĦ +Cou pon +Q ty +_ so +ĠInter im +.a ozora +人 åįķä½į +ĠH ector +éĢģ è¿Ľ +Ġprejud iced +S pr +ac lass +说å¾Ĺ 对 +ä¸Ģ æĪIJ +ä¼Ĭ 丽èİİçϽ +. rad +Ġt esters +èĩ´ åĬĽ +ĠMem o +Dom estic +Ġl angu +ï¼Ł åıĪ +满 æľĪ +, ~ +å°ı éĥ¨åĪĨ +æĿĤ ç²® +ĠRock ets +Ġguard ing +$ i +, ä¸ĩ +ãĢģ è¿ĺæľī +èµĦ产 æĢ»é¢Ŀ +Ġdecay ing +Ġ æł¸å¿ĥ +Ġg enders +èµ° 人 +è¡Įä¸ļ æłĩåĩĨ +çİī åħ° +ä½ľèĢħ çļĦ +Ġ ä¼ļ计 +å°¼ åħĭæĸ¯ +æĬ½ åĬ¨ +,ä¸Ģ ä½į +Ġ× ŀ +åįķä¸Ģ çļĦ +ĠMob il +ro ok +± оÑĤ +Î Ľ +å¾Ī éĩį +çİĭ æ°ı +åĵij å·´ +Ġm og +æĹł éĹ» +太 å²ģ +-label ed +Ġbrut ally +ĠMadd en +T cp +ĠAny where +,ä¸į管 æĺ¯ +< label +ĠT ears +ãĢģ çͲ +å®ł 溺 +ĠAppli ance +ëĵ ľ +å¤ļ ç³ĸ +西 è¾¹ +.b lack +å¥ĸ çīĮ +C ENT +F luid +s pect +åħ¶ çĦ¶ +åı° åīį +De als +ĠView Group +Marg aret +trad itional +ĠDud ley +ï¼ļ ä¸İ +æľ¬ è½® +_C OLUMN +çĽĺ ä¸Ĭ +é¼» å°ĸ +çŁĽçĽ¾ çļĦ +, out +åħ¬ èĭ± +åĩĦ åİī +ãĢģ åIJĥ +Fig s +å·· åŃIJ +' en +St opped +æį® ä»ĭç»į +termin ation +T ING +l ou +Ġ åĨῬ¡ +å°± 容æĺĵ +åĸĿ äºĨä¸Ģåı£ +å̾ å¿ĥ +çĤĴ èıľ +对ä»ĸ æĿ¥è¯´ +ĠNiger ians +çĿ¡è§ī äºĨ +ĠFly ers +ĠComfort able +è¿Ľè¡Į ä¸Ń +Ġsimpl ification +SEL F +弥漫 çĿĢ +> ) ): +Ġh h +çĬ¯ç½ª äºĭå®ŀ +Ġ{{ / +/ em +ç¾İ å¦Ĩ +PI PE +æīij é¼» +æĹł èĻij +Type Error +Ġamb assadors +Ġ 她们 +åıij 红 +åIJĮ çIJĨ +Bounding Box +s burg +ject ives +个ä½ĵ å·¥åķĨæĪ· +.Sh ared +f lo +o jo +Ġ æľŁ +ĠSch l +.net ty +ï¼Į éģĵè·¯ +St y +æķĪ ä»¿ +æĿİ æĺİ +ĠEm il +ĠFrank ie +B ET +ï¼Į åĪ· +Ty ler +p romise +w arts +Ġ éĢī +è§£ ä½ĵ +ĠReve als +ĠHIP AA +ĠAnch orage +H ab +ï¼Įåľ¨ ä¸ĢäºĽ +Ġdep rive +å¯Ĵ æļĦ +ç»ĵæĿŁ çļĦ +Ġhyp o +Ġcoerc ion +æĪij çΏ +ream ble +ĠDirector ate +< d +ï¼Į åĵ¦ +ï¼Į æĪªæŃ¢ +代 åIJįè¯į +åŃĺ æľī +ĠRes idency +æĦıåij³çĿĢ ä»Ģä¹Ī +åįĵè¶Ĭ çļĦ +çļ ij +ç»Ħç»ĩ æľºæŀĦ +Ġ(( * +\ plain +åľ¨ ä¸Ģç§į +åįĥ 亿 +ä¸ĢåĿĹ åĦ¿ +.Column s +( ad +ä¸į æĺİçļĦ +Ġey ed +_ commands +ä¸įåı¯ åIJ¦è®¤ +罪 éŃģ +æľªæĿ¥ åıijå±ķ +Ġwholes alers +n ature +ãĢģ 鸡èĽĭ +ĠB ai +âĢľ åĸĤ +éĹ² è¯Ŀ +Ġapprec iative +OU CH +Ġm ingle +TE E +羨 çľ¼çĿĽ +Ġ'* ' +Ġ èµ· +_h d +çļĦ åıĮæīĭ +ï¼Į没 éĶĻ +åĿĩ 设置æľī +mb re +Ġfootprint s +æĹł æģ¯ +éĻIJ 度çļĦ +Josh ua +igar h +为 è¿ĩ +Ġcommand ments +åİŁæľ¬ çļĦ +, æħ¢æħ¢ +l ld +ä¸Ń ä¸İ +å¾Ī æĸ¹ä¾¿ +install er +Ġan ew +çļĦ èĦļ +Ġn ook +ĠLab rador +ADD ING +ĠBour bon +满 è½½ +å¼Ģå±ķ ç»ıèIJ¥æ´»åĬ¨ +Ġblue berry +äºķ çĦ¶ +on ant +ï¼Į 饶 +EN N +ĠVill as +ï¼Į å®ŀæĹ¶ +ĠB aj +Ġam orphous +ĠWh itt +æĺ¯åIJ¦ åľ¨ +ï¼Įä¸įè¿ĩ è¿Ļ +/ Sh +Y ork +ãĢģ 空éĹ´ +å¤ļ åıij +oss ier +èIJ¦ ç»ķ +* sizeof +ĠAd idas +éªij èĩªè¡Į车 +ãĢĤ æľīä¸Ģ +ĠC LE +ãĢģ è¿IJè¡Į +nd i +临 æŃ» +ĠReg isters +éĻ Ĥ +æĮīçħ§ è§Ħå®ļ +漫 å¨ģ +ĠAT V +ĠCow boy +на Ñı +ĠP ry +ä¼ł çĥŃ +Ġhard working +Ġmis cellaneous +ä¸ĭ è¾ĸ +åѦ ç³» +Ġ第 åįģ竳 +Ġsusp ensions +ĠHav ana +Ġs ieve +ĠT RE +ĠPro ducers +ts on +Ġfl aming +å¤ĦçIJĨ è£ħç½® +åģĩ è´§ +éĢłæĪIJ å½±åĵį +ï¼ĮèĢģ çĪ· +H w +_S AMPLE +RO T +äºļ è¿IJä¼ļ +ĠQt Gui +ck i +åĽłä¸º 她 +æļ´ é£İ鼨 +è°ĥæŁ¥ æĺ¾ç¤º +Br andon +ï¼Į 足足 +对äºİ æĪij们 +bl a +Ġany how +åºĶ è¿IJ +- Ar +ï¼Į åĭī强 +ĠT OR +åĩº ä¸ĢäºĽ +ç«ŀäºī çļĦ +Ġmetall icity +ust ic +éĺ´ èĻļ +Ġquant itatively +ĠAtt ached +_S ORT +Ġinform ant +ä¸Ń è¯ģ +åĨį ç»§ç»Ń +_C M +(p c +æ£Ģæµĭ åύ +éĻª 她 +idel berg +Ġatroc ities +t rait +ĠSp ine +ï¼Į èĦī +am ax +}} }_ +_F UN +建设 åįķä½į +è´ª åĽ¾ +æ°ijæĶ¿ å±Ģ +çµ® åĩĿ +Ġglac iers +ï¼Į åij¨è¾¹ +The mes +å±Ĥ ä¸Ń +ç½ļ çIJĥ +ĠPH OTO +per ial +è¿Ļ个 é¡¹çĽ® +èģĶç³» åľ¨ä¸Ģèµ· +Ġcooper ating +. Optional +Î ł +âĢĿ è§ĦåĪĴ +åı£ 令 +ç͵è§Ĩ èĬĤ缮 +EE DED +ĠMet all +ĠBot swana +od der +èĢģå¸Ī 说 +.L ook +Ġunmist ak +ĠT orn +以 äººä¸ºæľ¬ +ĠCent res +åIJĬ éĶĢ +çģĮ è¾ĵ +Ġgy ms +ĠP AM +çα åĽłæĸ¯åĿ¦ +éĥ½ä¸į 太 +Ve get +; | +æķ° çϾä¸ĩ +éķ¿å¤§ åIJİ +ï¼Į èī²å½© +åŁºæľ¬ éĥ½æĺ¯ +/h our +P ie +ĠSh ame +æĻ¯ èĩ´ +.Get HashCode +æķħ äºĭæĥħèĬĤ +éĵģ çļĦ +ï¼Į 幸 +äºļ çī¹åħ° +Format ting +Ġb py +st y +· ç§ij +æ¦Ĥ è¦ģ +Met ro +Ġendorse ments +Den ied +.dis pose +强 æ±Ĥ +ĠBarn ett +/ update +ï¼Į è¯Ĺ +åı¯ æī§è¡Į +注 æµĨ +åħ³æ³¨ çļĦæĺ¯ +Instance Id +è¾ŀ åİ» +åĬ¨äºĨ åĬ¨ +åĬł 湿 +Ġappet izer +ĠLud wig +çľ¼ éĩĮçļĦ +å¾· æ¯Ķ +Ġsuper class +æĮĤ æĸŃ +æijĨèĦ± äºĨ +Ġdiplom at +çļĦ å®ļä½į +y ah +ï¼Į 女åŃ© +am n +æĹĭ转 è½´ +éĤĵ å°ıå¹³ +diff erence +ï¼Į éĴ¢ +Ġp lex +ĠN im +满 å¿ĥ +-p ocket +G ING +R m +泡 èĮ¶ +Ġ åĪ© +el ite +Ġg fx +å¹´ èĩ³ä»Ĭ +缸åħ³ èµĦ产 +çĻ»è®° æľºåħ³ +ä¸Ģä½ĵ æľº +ĠUr du +åIJĮ æµİ +ä¼Ĺ çѹ +Ġinvent ories +il ess +ol iber +æĹł 罪 +.re nderer +çά è¡Į +æ´» ä¸ĭæĿ¥ +å¼Ģåıij 人åijĺ +éĵ¾ è½® +Layout Panel +_DISABLE D +ï¼Į åķĨä¸ļ +ĠI ber +ĠW IFI +大 ä¸ļ +åŁİå¸Ĥ è§ĦåĪĴ +ĠData Source +æij© æĸ¯ +ĠMcG ill +_ connected +èħ ĵ +åģ¥åº· çłģ +ĠA uf +æ³ķ åѦéĻ¢ +纪念 ç¢ij +Autom otive +ĠPrec ious +ĠR ae +æıIJä¾Ľ æĽ´ +ucl id +污水å¤ĦçIJĨ åİĤ +Ġdeclar atory +SE G +æĭī äºĨ +ï¼Į åįıè°ĥ +åľ¨ ä¸įåIJĮçļĦ +管 å±Ģ +ç±» åĪ«çļĦ +ãĢģ éĻĨ +ç͍ ä¸Ģç§į +hold s +ĠLa os +ä¸ĵåĪ© æĿĥ +æĴĩ äºĨ +ï¼Į çŀ§ +Ġ* __ +pro blems +ĠStep han +ĠQt Widgets +N est +br ick +Õ¡ Õ +n printf +ç͵èĦij ä¸Ĭ +ĠOwn ed +, åį³åı¯ +b eyond +éģĵ æĿ¥ +æī¬ æī¬ +Ġextrem ist +Character istic +YC LE +ent ing +ĠC TA +Ġpart ake +ĠCom parator +Ġaff lict +ä¼ļæľī ä¸Ģ个 +ĠC uts +èĩª æĭį +Ġun married +åħ¥ çļĦ +èĬĤ ä¿Ń +åı¸æ³ķ éī´å®ļ +ĠDiff icult +Ġcrad le +åĥı æĺ¯åľ¨ +çģ« è¾£ +ĠZ L +çĨĶ æĸŃ +y out +åĨį 说äºĨ +IS SN +Ġcontrad ictions +.Auto Size +C NT +ens ch +å®ļ ä¼ļ +è´Łè´£ çļĦ +åĩĨç¡® çİĩ +åº ¾ +æĺİ æĸĩ +vent ures +è¿Ļæł· ä¸ĢæĿ¥ +éĢĢ çģ« +ĠRed skins +.std in +æĮ¥èĪŀ çĿĢ +ĠAnthrop ology +ï¼Į åIJ¸æĶ¶ +est het +å¼ł ä¸ī +å¸ĤçĽĪ çİĩ +æľĢ çαçļĦ +ä»ĸçļĦ èĦ¸ +(b oost +ĠGro cery +_ ACK +est ra +ï¼Ľ æľīçļĦ +Ġrich ly +çĶµæľº çļĦ +Ġdw ind +ĠLanc ashire +åľ¨ ä¸įæĸŃ +åıĺ æ³ķ +éľĢ è°¨æħİ +Ġhand bag +è·³ çļĦ +å¹³æĸ¹ åįĥç±³ +åı· è§Ĵ +æĿ¨ é£ŀ +å±¥è¡Į èģĮè´£ +æ²§ å·ŀ +ĠClos et +ãĢģ å¾Ī +ĠW ilde +-b en +Ġlemon ade +以æŃ¤ 为 +åĩł åĿĹ +Ġrest raints +ï¼Įæ¯ı å½ĵ +Ġä¸Ģ è¾¹ +èIJ¥åħ» ä¸įèī¯ +-le arn +_P ID +ï¼ĮæĹł éĿŀ +.trans port +æİ¥ç§į çĸ«èĭĹ +Ġrefin ancing +ï¼Į å¹¿æ³Ľ +ä¸ī 两 +ĠCar lisle +ze it +Ġc ep +è·Į å®ķ +_var iant +T olerance +Ġ å¾·åĽ½ +大 èĽĩ +åħ¨ çıŃ +æ°´ æµĴ +.to List +æĤ¬ æ®Ĭ +Ġpend ulum +ï¼Į è½½ +å¢ŀ æı´ +ern ary +Ġrest arted +壮 éĺĶ +ĠH och +ï¼Ī æ¯Ķå¦Ĥ +ĠNew est +æĭ© ä¼ĺ +omen cl +ï¼Įæĸ° 车 +Ëĭ Ëĭ +H J +ï¼Į å¾Ī好 +ä¹Łä¸į ä¸Ģæł· +Ġgrape fruit +ĠC PC +åľ¨ å±± +æīĵ æīĵ +sp awn +Ġtool ing +ĠS ST +å½¢æĪIJ æľī +åĴĴ éªĤ +Ġreluct antly +- events +æ¯Ķ æĸ¹ +Ġthanks giving +åľ¨ å½ĵåľ° +ist ar +Ġun heard +Ġunder lined +æ¸ħ æ¸ħ +èĬ± å²Ĺ +_F P +èººåľ¨ åľ°ä¸Ĭ +H TTPS +ãĢģ è¿ŀæİ¥ +th or +ĠH odge +ĠIn struct +abet ics +Ġ ][ +ï¼Į åIJĮæł·çļĦ +ĠD ias +tern oons +iss or +åįģ å²ģ +离 å¥ĩ +ç¨ĭåºı 设计 +Ġupload s +Ġdeter rent +åij ² +çĩĥçĥ§ çļĦ +è¯ģæĺİ èĩªå·± +ĠÑģ ÑĬ +ĠOrder ing +æĸĩçī©ä¿ĿæĬ¤ åįķä½į +åĬł 大äºĨ +(" \" +-L ength +"} ; +/ arch +et to +.w av +ĠPER F +ĠASE AN +' une +- = +P aste +Ġ åĮĹ京å¸Ĥ +ï¼Į åĬ³åĬ¨åĬĽ +åĴĮ èͼ +ä¹ĭ èĩ³ +_m et +Ġ æİ¥ +Ġand rogen +大 æĶ¾ +èĬ± æŀľ +Ġmar ina +çļĦæīĭ èħķ +ĠB ayer +åĴĮ ç¬¬åĽĽ +ï¼Įä½ł å°±æĺ¯ +Ġbit ters +Ġ 社 +çļĦ èį¯çī© +le i +å¹´ æĹ¶éĹ´ +ĠY MCA +é«ĺ å¼Ģ +åºĦ éĩį +is ke +çļĦ æľīåħ³ +ĠC TO +Ġnot ations +ä¹Ł 说ä¸į +Ġpat ched +], " +å®ĺ 宣 +åΤ åĪ« +P AL +åĶ¿ åĸĬ +(! ( +è¯ŀçĶŁ äºĨ +ï¼Į çĶ»éĿ¢ +Ġg db +ç»Ħ ç»Ħéķ¿ +.l aunch +ãĢĤ å¹³ +ĠD ice +鼨 æŀĹ +, 约 +@ Component +ãĢģ æĽ¹ +æľ¬ åľ°çļĦ +å¼Ĥ æŀĦ +plan et +Pray er +ä¸İ åĪĨæŀIJ +Ġevery time +æİ§åζ ä¸Ńå¿ĥ +ĠAg nes +åį«çĶŁ ç»Ħç»ĩ +Ġdecom posed +ä»İä¸ļ èĢħ +/ es +_ org +ä¸Ģ ç¼ķ +ãĢģ æħ¢æĢ§ +Ġsh one +åĸĿ ä¸ĢæĿ¯ +ï¼Įå·² æľī +ĠCos mos +ï¼Įæĺ¾çĦ¶ æĺ¯ +ä¸ī éĩį +èIJ§ æĿ¡ +, æ°ijèѦ +åħ³éĶ® çĤ¹ +inv oice +ĠL oose +éĩį äºİ +pr ised +æł¡ å°ī +Ġweb pages +ĠHar b +ĠB rem +ä¸ŃçļĦ ä½ľç͍ +- ordered +æ£ĢæŁ¥ åĴĮ +_SE G +ĠDecor ating +f av +ĠA ero +å°ı éģĵ +Ġpr une +è´¹ åĬ² +ï¼ĮæĪij们 å·²ç»ı +èĢķ åľ°éĿ¢ç§¯ +ä»Ĺ çĿĢ +ĠG OLD +ç»ĥ åħµ +_ ir +Ġbest owed +å¼Ģå±ķ å·¥ä½ľ +osoph ical +ag os +ĠD é +EX IT +第ä¸ī 代 +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠ +ĠMenu Item +æĺĨæĺİ å¸Ĥ +Ġa ides +iff in +ç¼ ľ +æ¡ ¢ +æµ· è±ļ +表çݰ åĩºæĿ¥çļĦ +äºĨåĩł æŃ¥ +ADI US +ï¼Į 广西 +ãĢĤ æĽ¹ +ãĢģ è°ĥæķ´ +âĢĿ æĮīéĴ® +ĠE SR +å¹´ å°± +Ġcomm ens +Ġamel ior +r ino +éª ° +_p ython +å¹³åı° åĴĮ +sl ave +ç«Ń å°½åħ¨åĬĽ +<< ( +mem item +Bel ieve +æĺ¯ ä¸ĸçķĮä¸Ĭ +ä¸į è¿Ń +ĠL ila +çķĻ åľ¨äºĨ +èľ¥ èľ´ +x in +ãĢģ 建ç«ĭ +ĠEx xon +ĠVisual ization +ãĢģ åįķä½į +dis cuss +_ex ecute +Ġ çĻ¾åº¦çϾç§ij +Ġg ens +Ġme adow +ns ics +åį°è±¡ ä¸Ń +techn ic +èĽ¤ èŁĨ +éĮ ² +ĠF ires +ä¸Ģ个 åŃ©åŃIJ +oid es +æ·± çα +ĠCon ce +ĠAb igail +Ġ åĬ¨ +æľĢ 主è¦ģçļĦ +que ues +stream s +Ġsalt ed +ĠGar ner +.key Set +ĠH CI +Ġmorph isms +ï¼Į åıĸåĩº +## _ +Ġrec overs +Ġtele port +Prov ince +_ To +天 主æķĻ +Ġet ched +Ġcheck points +Ġâĸ ³ +åı« äºĨ +Ġwhole hearted +else if +éĩįè¦ģ讲è¯Ŀ ç²¾ç¥ŀ +åıį å·® +ï¼Įä½ł 好 +Ġair s +éķĤ 空 +ew ays +çļĦ大 çľ¼çĿĽ +}) =\ +èµŀ 许 +ä½ĵèĤ² å±Ģ +è¦ģ éĢīæĭ© +æĺ¯ä¸Ģ 份 +Ġtax is +rehens ible +Ġfort ified +am ura +ĠS out +ãĢģ M +ãĢģ èĦĤèĤª +人 ä¸ĸ +æģ¶ æ¯Ĵ +omew here +ç©¶ åħ¶ +idd ers +ç»ĵæŀĦ 设计 +Ġbrainstorm ing +P ap +or gh +ãĢģ K +ĠE sk +Cont rast +Ġâ Ł +Ġ æł¹æį®æĿĥåĪ©è¦ģæ±Ĥ +éĥ½ åĴĮ +è§ī çĿĢ +{} ", +F illed +éĢĢ ä¸ĭ +æĴŀ ä¸Ĭ +éĤĢ çº¦ +å¤ĸ åķĨ +-st ick +ä»ģ çα +ĠW orse +åĨħ éĻĨ +æĺİ æĻ° +åĨ· æļĸ +æ¥ļ äºijé£ŀ +ĠArt istic +ĠI AS +ĠS ID +cl ients +è¾ŀ åħ¸ +, æīĢæľīçļĦ +/ ns +_b h +ĠChe er +æĪĺ士 们 +Ġc et +ãĢĤ 鼷 +ĠF aul +ä¹Ł å¾ĹåΰäºĨ +Ġ[ â̦ +Ġmultif aceted +> (& +Ġab er +çľĭåΰ è¿ĩ +Ġfear ing +{ [ +ene ath +j ie +ï¼Į çĸ«æĥħ +游æĪı ä¸ŃçļĦ +Ġcircum vent +éĶIJ åĪ© +ï¼Įä¼¼ä¹İ åľ¨ +å½Ĵå±ŀäºİ ä¸Ĭå¸Ĥåħ¬åı¸ +Ġshar per +/ex amples +- validation +Ġp ak +Ġth a +ĠS ALE +ç¨İ éĩij +ç½¢ ä¼ij +old t +Ġbust ed +Ġmim ics +åIJīæĢĿ æ±Ĺ +å¾· åĪ© +Ġden oting +Ġsuc rose +ins k +éł ħ +; font +E z +ä»ĸ 认为 +å§» ç¼ĺ +(code c +D ogs +Ġun complicated +èĩªå·±çļĦ å·¥ä½ľ +Ġest r +Ded icated +Ġl itt +å®¶ å¢ĥ +群 ç»Ħ +æĬĹ åĬĽ +è¾ħ 以 +ä¸ŃåĽ½ è¯ģåΏ +æĭī å°Ķ +-n utrients +è¾ĵåħ¥ æ³ķ +ĠPick up +ãĢģ å±Ģéķ¿ +ï¼ģ åı¯æĺ¯ +ĠNew foundland +_R AM +_log its +çļĩåIJİ å¨ĺå¨ĺ +B ITS +çļĦ ä¼ĺç§Ģ +ĠT MC +è¿Ľè¡Į éĢīæĭ© +éķĢ éĵ¬ +. dd +å·± æĸ¹ +-m aker +å®ŀæĸ½æĸ¹å¼ı çļĦ +ĠFlo ors +åı¯ä»¥ åıĤèĢĥ +rad er +-pro p +B Q +qu estions +Ġun conditionally +å¾ħ 人 +æ»ij åĿ¡ += max +L emon +def initions +åħįçĸ« åĬŁèĥ½ +, æķĻå¸Ī +Ġ æĸĩåĮĸ +ener al +Character istics +人 æľº +è¿ĩ æĹ¶ +ĠSh iva +ĠFl ames +ĠPot atoes +åľ°åĽ¾ ä¸Ĭ +Simple Name +ĠSapp hire +T ank +ãĢģ éĽĨ +ç§ij åįı +å°ıå§IJ çļĦ +.Rec ord +pp ard +Ġconsent ing +è´§å¸ģ æĢ§ +å¸Ĩ å¸ĥ +Ạ¥ +Ġre legated +Ġif ace +Ġher ds +å¾IJ æ¶Ľ +Ġmature d +Ġmonot onic +D anny +ï¼Į æħķ +ĠG au +ç͵ 车 +ï¼Įä»ĸ çĶļèĩ³ +ç²¾çĽĬ æ±Ĥç²¾ +ãĢģ ç»Ĩ +åıij éĹ® +横 å¹ħ +ubb les +_POL ICY +åĴĮ å®¶åºŃ +çīĩ éĿ¢ +ĠSmall er +ï¼Į çİ»çĴĥ +æİĴ 便 +ä½Ļ 个 +Access ories +ãĢģ æĬ¤ +ĠShe pard +éĶĻ å¤± +ä»»ä½ķ äºĭæĥħ +å¿įä¸įä½ı äºĨ +olog na +æł¼ æĭīæĸ¯ +- γ +Ġfor aging +ĠR ULE +Ġ好 åľ¨ +_ du +SC ALL +Ġt body +æľ¬ å°±æĺ¯ +Int Ptr +Ġpriorit ized +Ġ åĸľæ¬¢ +esc aped +ĠTor rent +Ġ ä¿¡æģ¯ +åľ¨ åį³ +ï¼ĮæĪij å®¶ +éĿŀ ä½Ĩ +QU ERY +è· Ĩ +Ġx hr +dist ribution +çŀ¥ äºĨä¸Ģçľ¼ +Ġ é²ģ +为 该 +Ġdon uts +IL A +ĠLO AD +æ³ķåħ° 西 +éļ¾å¿ĺ çļĦ +ĠM ater +çĥŃ å·´ +è´§ åĵģ +.t ake +å°½éĩı ä¸įè¦ģ +ĠConven ient +- contact +ï¼Į è§Ĩ线 +åŀĤ ä¸ĭ +ped o +ãĢģ æ¤įçī© +con ftest +๠Į +Ġ åIJ¬äºĨ +ï¼ģ ä»Ĭ天 +åĮħæĭ¬ åľ¨ +Se ems +ï¼ĮæĬĬ èĩªå·± +éªĹ æĪij +ĠT OM +天 马 +éķ¿ çº¿ +ä¹IJ 祸 +Ġâ ģ +Ġsubt ree +as see +第äºĮ æī¹ +Ġdi verted +ĠMix ing +c ru +Ġ 代 +Ġsc ares +åį´ å·²ç»ı +å½ĵçĦ¶ çŁ¥éģĵ +å§ijå¨ĺ 们 +toHave BeenCalled +Th r +Th reat +举 éĺ³ +ï¼Į没 åĬŀæ³ķ +Ġrom an +Compat ibility +- Service +æł¡ æľį +ä¹Łä¸į æĦ¿æĦı +说çļĦ éĤ£æł· +Ġencaps ulated +( ä¸ŃåĽ½ +erv al +.m akedirs +æĥĬ 诧 +ãĢı ï¼Į +Ġlev itra +/ ne +ãĢĭ ä¹ĭ +ĠClass ified +æ¡¥ éķĩ +女æĢ§ æľĭåıĭ +æµ®çݰ åĩº +.N ONE +è¾ĵ åįµ +][ / +åͤ èµ· +åIJŀ åĴ½ +-s plit +æľįåĬ¡ ç«Ļ +à³ ģ +åİĭåĬĽ ä¼łæĦŁåύ +к Ñĥ +Ġle mons +ç͍ èĦļ +_p ol +æĪ´ ç»´ +çαæĥħ æķħäºĭ +åľ°è´¨ çģ¾å®³ +ng a +ĠAss umption +-w ife +çīµ æ¶ī +ĠC air +ãĢģ ç³ĸå°¿çĹħ +Ġox ides +ĠEnhance ment +çļĦ åĪĽæĸ° +鼨 éĽª +]( ./ +files ystem +Ġassim ilation +w ik +ä»ĸ们 èĩªå·± +带 æĪijåİ» +æĺ¥ æĹ¥ +æĬ¢ èµ° +, ç͍äºİ +为 群ä¼Ĺ +Ġtemper ate +çĸı è¿ľ +Ġdef raud +éĽĦ æĢ§ +æĺİçϽ çļĦ +Ġdef erence +, å¹² +ä½ł ç»ĻæĪij +ĠCh andra +éĻį å¹ħ +Trans cript +Ġcontra ception +ãĢģ è¯ļä¿¡ +æĢ» åħµ +Ġfacilit ation +ĠSher ry +Ġsaut é +b ibr +æŀģ å°ijæķ° +sc apes +.C H +re name +ï¼Į çĿĢå®ŀ +æĺ¯ æĺ¯ +Ġsh aved +ï¼Į æ²īé»ĺ +il or +æĵ¦ å¹² +Ġ 举é£İ +ãĢģ 空è°ĥ +ĠW ink +ĠCall able +izz o +çļĦ åľ£ +ãĢģ åĨĻ +ĠSm ok +. cons +æĪĸ 被 +enu ous +) v +ï¼Į åĨ·åį´ +ĠF its +é«ĺ éĢļ +åı¯ä»¥ åIJij +. å¦Ĥæŀľ +ĠN CC +å°± 绪 +Ġq emu +è§Ħ模 åĴĮ +( Index +å½ĵ åħĪ +ĠCl ifton +ä¹ĭéĹ´ éĢļè¿ĩ +.r x +ä¸ĵç§ij åŃ¦æł¡ +èĽĽ ä¸Ŀ +ä½ľ 对 +éķ¿ å¤Ħ +交 æľĭåıĭ +ĠDec o +G ED +I UM +令 ä¸ĭ +Ġgoal ie +.re ject +社ä¼ļ主ä¹ī çݰ代åĮĸ +ĠMoz ambique +æ·± åĪĩ +æĢ»ä½ĵ æĿ¥è¯´ +ĠC FP +ĠK es +éĺ´ åĨ· +arant eed +, 满足 +. low +ãĢģ ç²¾åĩĨ +Ġunderstand ings +åŃIJ宫 åĨħ +Ġvide ot +Gar age +ĠD rosophila +rou se +ach o +Ġfavor ably +ä¸Ģ ç¯ĩæĸĩ竳 +åΰ èĢģ +é£İ è¶£ +.p ackage +åĽłç´ł çļĦ +Ġconstitution ally +const expr +ĠPok ies +ä¸Ĭ åĵģ +å·² è¿Ľåħ¥ +æķĻèĤ² æľºæŀĦ +çł´ 浪 +举 ä¸ĸ +Ġclub house +ĠCR P +åľ¨ æīĭä¸Ń +ĠThe ological +ĠK au +ä¼ł ä¸ĸ +Account Id +* N +ĠB aked +Ġco op +åĨį éĢł +Ġfl otation +éĨ º +Ġsequ est +ĠRen ee +ĠSere na +太 éĩį +ç®Ĺ è´¦ +yn man +æĬ½ è°ĥ +ĠRad ius +Ġdecomp ose +av ings +å¦Ĥ åĪĿ +ï¼ģ åĪ« +äºĨä¸Ģ é¢Ĺ +ĠAm ish +èĤ¡æĿĥ æ¿ĢåĬ± +Ġhol iness +Enumer ation +tagHelper ExecutionContext +? ä¸ĭéĿ¢ +Ġw enn +Rou ge +æĮ İ +æİ¨ äºĨ +ä¼ij æķ´ +d raft +ĠM bps +ĠR oku +å´ĩ é«ĺçļĦ +="# " +å¸ĪèµĦ åĬĽéĩı +d q +ion ate +èį ļ +ask an +ï¼Į西 çıŃçīĻ +id le +Ġsub lim +_S AVE +æĿij åŃIJéĩĮ +å¯Ł çľĭ +bl ast +Gram mar +èŁij èŀĤ +ï¼Į X +ĠH olds +Ġ\ } +/m ysql +à± ģ +Ġ 羣æĺ¯ +ru v +åı¯ä»¥ åħĪ +éħ IJ +. force +ä¸į 满足 +um sy +Ġse af +Ġmillion aire +Ġton ed +E FF +r ime +.get Bytes +å¦Ĥ èį¼ +ãĥ ı +èĥľ çİĩ +çĻ» ä¸ĬäºĨ +é¼» èħĶ +Ġg ist +å¾Ī æĹ© +н е +Ġcalcul ators +ERR IDE +ä¸įåľ¨ çĦī +åĴĮ åIJ´ +å½ĵ 个 +è£ħ 满 +ç»ĵæŀĦ ä¸Ń +. ignore +æĺ¯ä¸Ģ åĪĩ +ä»ħ éľĢ +Ġblock ers +Ġver ifiable +ï¼Į æĿĥ +Ġp q +æĬļ æħ° +.per form +Ġinert ial +RE SET +åĨĴ åĩºæĿ¥ +缺çĤ¹ æĺ¯ +Ġskate board +ĠByz antine +CH AN +,æľī äºĨ +Ġm ellow +// === +åĴĮ æĶ¿çŃĸ +ign ation +ĠSe ab +ĠMy rtle +常è§Ħ çļĦ +$ db +S erves +Ġt witch +Ġs ous +çϽ æĹ¥ +ç½® ä¸ļæľīéĻIJåħ¬åı¸ +ĠDevelop ments +å°¾ çĽĺ +èĢĮ æľª +æĦı åľ° +Ġfr aternity +(c anvas +Ġä¸Ģ æĹ¶éĹ´ +Ġdo od +第 åįģ竳 +åĩ¯ æģ© +Ġtape red +Drop down +pers ons +ä½ł 羣 +åĪļ æĥ³ +Ġfav oured +îĢ Ħ +åħĭéĩĮæĸ¯ èĴĤ +\ varepsilon +æ² ± +ĠOlymp ia +æĹ¥ åĩºçĶŁäºİ +æĪ· 人家 +Ġbreed ers +ä½ĵ éĿ¢ +Cl ay +ãĢĤ 奥 +est ar +Ġcapt ivity +åı¯èĥ½ä¼ļ 被 +ä¸īåĪĨ çIJĥ +Ġgreet ings +Ġnort heastern +Ġ åĵ¦ +åĽ´ ä½ı +ĠSpe ars +Ġunle ashed +ĠAtmosp heric +ĠJ L +Ġgl ide +Ġt riv +åĺ¶ åIJ¼ +Ġ____ __ +榴 èݲ +s weet +çļĦ ä¸ŃéĹ´ +.pub lish +. agent +k 线 +ĠA cer +ĠL itt +-C al +ï¼Į åĮº +ï¼Į 注åĨĮèµĦæľ¬ +çĿĢ è¯´ +IG INAL +ĠRec yclerView +åĪĨéħį ç»Ļ +äºĨ å¾Ĺ +èĪ · +ili ency +ï¼Įå¼Ģ æĭĵ +m ime +in ib +ãĢĤ çİ°åľº +é¾Ļ åĩ¤ +åĨ¤ å®¶ +Administ ration +ĠM asc +ä¼ļ è¯Ĭ +è®® ç¨ĭ +Ġhon ours +æĶ¯æĴij æŁ± +è¿Ļ 两ä½į +èĩªå·±çļĦ åĬªåĬĽ +åı« äºĨä¸Ģ声 +æĬĬæı¡ 好 +ĠA stra +âĢĻ l +th on +åĿĩ éĩĩç͍ +ä¸ľè¥¿ çļĦ +èįĴ èĬľ +Ġget User +管çIJĨ æ°´å¹³ +ĠComp assion +çĶŁæĹ¥ å¿«ä¹IJ +or ning +ĠD res +Ġsm b +.f inish +oll ip +éĹŃ çĿĢçľ¼çĿĽ +èĤ¯å®ļ è¦ģ +å°½åı¯èĥ½ åľ° +x FE +Ġl upus +æľĢ ç®Ģåįķ +Ġmust er +Ġdream y +pat ients +åĮºåĪ« äºİ +ĠLah ore +Ġ 说æĺİ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠ +ĠÎ ¹ +Ġcode cs +ä¼Ĭ å°Ķ +-P ack +ï¼Į è®Ńç»ĥ +pe as +ĠJ avier +å°Ĩ å®ĥ们 +æīĢè¿° 第ä¸ī +ï¼Įå°± å¦ĤåIJĮ +æijĬ å¼Ģ +å¤Ħç½ļ éĩij +åĩº æłı +å°±æĺ¯ 对 +Ġparticip atory +çľĭäºĨ ä»ĸä¸Ģçľ¼ +à¥įठ¯ +çļĦ åĨĽ +çĭ¬ åΰ +ä¸ļåĬ¡ åıijå±ķ +ĠP eng +ĠR iders +åĩº 人 +Ġrem uneration +è¿Ī æŃ¥ +ĠHyg iene +ĠU IS +æĶ¿ å±Ģ +Ġphilanth ropic +ï¼Į æĢĢ +容 ç½® +丰 缼 +表çݰ å½¢å¼ı +Ġrev olt +Ġcritic izing +- settings +\ V +çļĦ åĪĺ +æİ¨ 车 +ĠVeget ables +Ġchees ecake +vart heta +ï¼Į éĢĤå®ľ +_s ound +( ep +åIJį è´µ +çī¹ èĴĻå¾· +AL I +ĠDiam eter +Ġleisure ly +, ] +Ġ æĿ° +ï¼Į åĸ· +Ġn ectar +ä¹ĭ çģµ +æŃ¦ çİĭ +ĠMcC artney +âľ ħ +: Is +_ until +æľī åĪ©çļĦ +Ġch ancellor +æĽ´ æĦ¿æĦı +ĠIs Set +Ġphysic ists +. ready +b ron +ä¼ij åħ» +ĠTow ard +ĠJ ord +ĠK ale +æıIJä¾Ľ ä¸ĢäºĽ +Ġden omination +Ġinitial s +ĠC OD +od end +è¿Ļ çķª +Pro fit +è¯ķ è¿ĩ +åĪĿ åĪĽ +-int ensity +ï¼Įåĩıå°ij äºĨ +F PS +e V +çļĦåĨħ åŃĺ +: E +q li +ãĢĤ å¿« +Ġdis ordered +conf erence +æĢ»ä½ĵ è§ĦåĪĴ +press ure +ĠTerror ism +ãĢĤ åĽ½éĻħ +ï¼Įè¿Ļ 使å¾Ĺ +UL ATION +ï¼ĮéĤ£ä¹Ī ä½ł +ï¼Įè¿Ļæł· çļĦè¯Ŀ +èĩªéĹŃ çĹĩ +ï¼Į æŃ»äº¡ +-c ourt +ĠSA FE +Ġn anny +第äºĮ æľŁ +Ġdebt ors +ï¼Įä¸Ģç§į æĺ¯ +Ġchandel ier +, ç«ĭåį³ +ĠK T +ï¼Įè¿Ļ 座 +rug ated +, 女人 +ãĢĤ æľīäºĽäºº +ä¸į äºĮ +ï¼ĮéĤ£ 天 +Ġuser Name +Ġmbed tls +Z F +ãĢģ 该 +cor p +.inner HTML +ĠB AM +ä¾ Ĺ +In g +å®ĺ æĸ¹çļĦ +å¤ĦçIJĨ åĴĮ +y rs +ĠR ath +ä¸ĩ å·¦åı³ +äºĨä¸Ģ 身 +绾 ç»İ +(i ii +Ġsup ersed +_cl i +DOWN LOAD +PI LE +Rec yclerView +(int ent +ï¼Į åĴ¬ +Ġkn ack +æĭī éĩĮ +ä¹° æĿ¥ +åı¤ è¯Ĺ +çļĦåīį æĻ¯ +ï¼Į èµ¶å¿« +ĠC CL +Ġ" ? +æĥ³ 好 +äºĨä¸Ģ 款 +绿 æ´² +Line Width +åıijèĩª ç®Ģ书 +ĠB ett +çķ ¿ +iss en +认 åĩºäºĨ +çļĦåİŁåĽł ä¹ĭä¸Ģ +éļı便 便 +èł¢ èł¢ +Ġcon glomer +ï¼Įè¿Ļ å°ıåŃIJ +Ġerror Message +{{ # +Anim als +ãĢĤ æķ´ä½ĵ +æľī åı¯èĥ½æĺ¯ +ĠR ory +tr ast +Ġhead board +ĠBe ats +Ġkinem atics +m allow +Ġ 尺寸 +çĶŁ æºIJ +ãĢĭ ä½ľèĢħ +Ax es ++ T +Â İ +ĠJ T +_t f +be hind +ä¼ģä¸ļ ç»ıèIJ¥ +èİ· çĽĬ +å¹³åĿĩ æ°´å¹³ +åįģåĽĽ å¹´ +ĠRo ast +Ġ è´¨éĩı +Ġl umen +âĢľ å¿« +åŀĭ éĴ¢ +æİ¢ 访 +åı¸æ³ķ æľºåħ³ +ĠDish washer +k im +Ġ å¹´çļĦ +Ġ[ ]) +çŁ³ è¶Ĭ +ãĢĤå¦Ĥæŀľ æľī +Ġmicro gl +Ġdestruct or +è¨Ń å®ļ +z ia +ãĢģ è£ħ饰 +Ġro i +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠ +éģ£ ä½¿ +; margin +Ġ 个æľĪ +çļĦ 课ç¨ĭ +éĺŁ åĴĮ +.g roups +对å¤ĸ æĭħä¿Ŀ +Ġ æŀľ +sg i +çĬ¶åĨµ ä¸ĭ +- structured +ĠWe yl +åĥı ä»ĸ +çı Ī +è¡ĮæĶ¿ 许åı¯ +ĠNeed le +Spons or +N ano +ol ist +ä¹Ł æŃ£æĺ¯ +ĠCh ong +çĶ· æ¼Ķåijĺ +, åŃĻ +ĠP ett +em er +ĠAbb as +_VERT EX +ĠY ad +ĠPer ipheral +Ġrev olve +h x +ĠN ico +au ce +âĪ ¼ +ï¼Į主è¦ģ ç͍äºİ +Ġunw avering +ĠFO UND +×ķ× ª +Ġd rib +ĠG ing +ä¹Ķ æľ¨ +ĠLiving ston +åĽļ çĬ¯ +èĵ¦ åľ° +åıĬ æľįåĬ¡ +-p y +çĭ¼ 人 +ï¼Ī G +æ»ĭ éĺ´ +åĵĢ åļİ +.equals IgnoreCase +åĬ¨åĬĽ çĶµæ±ł +MO ESM +骨干 æķĻå¸Ī +ãĢģ å°¿ +使 èĩªå·± +Att ributed +ĠEar rings +åħ¨ èĥľ +ï¼Įå¦Ĥ æĤ¨ +Ġign ite +便 è¦ģ +ï¼Įåľ¨ è¿Ļç§į +Ġinfrast ructures +ĠM ID +ï¼Įåĩłä¹İ æĺ¯ +Ġneurop athy +. room +åIJĪ ä½ĵ +Ġfulf ills +C ute +{ in +Ġj asmine +Ġcomp ilers +æĥħ åĬ¿ +ç²¾ è¿Ľ +å°ı éĿĴ +é¦Ļ èįī +ĠT ires +缴æİ¥ å°± +çľī çľ¼ +ĠN ur +Ġco ke +Ġins cription +åĵĪåĵĪ ä¸Ģç¬ij +Ġde odor +èĩª 大 +ĠPro st +Ġview Model +ĠIm pl +ä¸ĢçĤ¹ ä¸ĢçĤ¹ +空æ°Ķ çļĦ +_AL G +lo ans +åı¶ é£ŀ +Ins pect +ĠCharl ott +d pi +å¿ĥ èĤº +Ġext rad +æıı æ·¡ +ĠCarl ton +ĠGib raltar +, çϾ +ç²¾ å·§ += } +Ġ ä¿®æĶ¹ +ĠMid land +ĠC ic +çIJĨ çĸĹ +ï¼Įä¸Ģ æł· +ï¼Įæľī ä¸ĢäºĽ +_F IN +ĠTor ch +ï¼Į让 å®ĥ +. uid +çļĦ éļ¾åº¦ +åı° è´¦ +inter faces +çļĦ人 å½± +ES OME +w ish +æµ· éĿ¢ +Ġprob iotic +åŁºæľ¬ åĮ»çĸĹä¿ĿéĻ© +褶 çļ± +- force +_c alls +å°ģ ç¥ŀ +裸 éľ² +Ġarsen ic +é ¦ģ +ï¼ī âĢĶâĢĶ +æµĵ çĥŁ +f rog +ĠP OV +Ġde ceived +Ġad ored +Ġpr ick +主é¢ĺ æĽ² +ĠNic ol +Ġpion eered +ĠF atal +å¤ļ éĥ¨ +ĠV ide +of i +éŀĭ åºķ +ç¼Ŀ 纫 +hed ra +ãĢĤä½Ĩ æĪij +æĸij 驳 +èIJ¥éĶĢ çŃĸçķ¥ +ĠSelect ing +ĠGam ble +ï¼Į éĶģ +_c art +è¶ħ åīį +Ġaff licted +åī¯ å¤Ħéķ¿ +离 åľº +è¿Ļä¸Ģ æĭĽ +soft max +.sub ject +é¢ĵ åºŁ +est ablish +Ġsp rang +åĪĨ享 çļĦ +å¯Ĩå°ģ ä»¶ +è¯ŀ çĶŁçļĦ +å±ħé«ĺ 临 +è¡Į æĢ§ +éŨ æĿ¿ +By Key +_dir ty +Ġs out +ç»ı 审计 +Ġdef lection +以为 æĪij +åĨħèĴĻåı¤ èĩªæ²»åĮº +ãĢģ èĶ¡ +大 åĿĹ +_V ARIABLE +ĠPres cott +Ġfol ly +- Commerce +è¦ģ æĺ¯ä¸į +_c ar +val ued +Ġec static +ï¼Įåı¯æĺ¯ 她 +ĠLuc a +ĠExpress ions +大大 éĻįä½İ +âĸ¡ âĸ¡ +D al +R are +ĠS asha +Âł of +AP R +é¤IJ åݨ +Ġcos mos +æķ´å½¢ ç¾İ容 +ãģĿ ãģĨ +Ġkinem atic +ot os +Ġpres ets +ä½İ 声éģĵ +çİī åύ +Ġ[ ]( +çĥ½ çģ« +ĠM eng +ä¸ĵ éķ¿ +ï¼ĮæŃ¤ åIJİ +om aterials +ãĢģ è§£ +ĠAl as +临 ç»Ī +ĠAdd ison +Ġfire wood +åĿ¡ 度 +ĠWu han +(" * +åı² åѦ +alloc ator +Recogn ition +ĠVaugh an +æľĢ大éĻIJ度 åľ° +, åı¦ä¸Ģæĸ¹éĿ¢ +ãĢģ 麻 +ous ine +被 é̼ +ĠRe el +ĠTravel er +Ñ ļ +Ø « +Host name +Ġpig ments +å¼ł æ°ı +Ġmol ten +éĹ® èĩªå·± +åħħ è¡Ģ +éĩĩ访æĹ¶ 表示 +Ġtrans duction +TE CTION +Ub untu +- κB +I k +ç͍ ä¸Ĭ +æķ¬ äºŃ +ç»Łè®¡ åѦ +éľĵ èϹ +* A +Oper ators +Ġsweat y +ï¼Į æĬ¤ +åѦ åΰäºĨ +ï¼ī 以 +åħį äºİ +Ġsn ail +åħ³éĶ® æĬĢæľ¯ +çģ¾ ä¹IJ祸 +ä¹ı åij³ +Ġdeep ening +ĠBuck ley +ï¼Į æĶ¶èİ· +ĠM CS +ĠP CS +æľ¬ åľº +æĽ´ éĩįè¦ģçļĦæĺ¯ +_c orrect +ÙĪ ÙĦ +Ġly rical +渺 å°ı +ãĥĹ ãĥŃ +ĠS cheduling +Ġq r +ĠâĹ İ +Ġhydrox ide +way ne +.t imer ++ X +ï¼Į çĮ« +ĠG aut +èĢħ ä¸į +ĠT od +æľī å¿Ĺ +_BO X +æĺ¯ æĮīçħ§ +_D ESCRIPTION +ä¼ijæģ¯ åIJ§ +ä¸ĵåĪ© çĶ³è¯· +g cd +rib es +æĬķ æİ· +请 大家 +伤 åijĺ +ĠMcK enzie +Ġunders ide +ãĢģ b +Ġsc outs +线 ä¸İ +ภ¸ +ĠBrig gs +I v +Ġh oses +Ġu g +å¾Ĺ çĽĬ +_in stances +ĠPC M +Ġgear box +Ġaston ished +çİ°åľ¨ è¿ĺ +夺 åĽŀ +çľĭè§ģ ä»ĸ +ĠAlbum s +, å±± +大 åºĨ +_c i +å¼Ħ åΰ +社åĮº å±ħæ°ij +ĠT ender +ãĢģ èĥ¡èIJĿåįľ +æİ§åζ åı° +Med ian +�� �� +Ġinduct ed +çļĦ æ¶Īè´¹ +Ġre position +๠ĩ +################################################################ ######## +Ġ çģµ +Ġsc orn +ĠClo ver +ĠE IN +åĬŁ ç»© +ãĢģåī¯ å±Ģéķ¿ +é£İ éĩı +èĬ± æµ· +, is +à ĩ +æĺ¯ 她çļĦ +ĠB ly +ub ar +éŨ æ¡Ĩ +(p id +ĠTH ERE +ĠAngel o +ç½IJ ä½ĵ +Gal axy +åĴĮ ä½łçļĦ +ä¹Łä¸į å¤ļ +èµĦæľ¬ å®¶ +ĠMeaning ful +æ¦Ĩ æŀĹ +ä¸Ģ æŀª +åĴĮ åħ¬åı¸ +èĢģ äºĶ +æµ® äºij +åIJ¾ å°Ķ +Ġun structured +åºĶ 符åIJĪ +ç²¾ ç®Ģ +èĭĹ æĹı +Ġbran ched +N aturally +u let +Ġb uns +ä¸Ģ æłĭ +ug en +åıį æĤĶ +çĦ¦ çĤŃ +åıijèĩªç®Ģ书 app +ãĢĤ ä¹Łå°±æĺ¯ +ib b +å¦Ĥ 鼷 +ï¼Įåı¯ æł¹æį® +arc gis +åIJ¬åΰ çļĦ +ĠC AB +Ġexc ite +å°¾ çļĦ +Vis a +污æŁĵ çļĦ +, åĽŀ +Ġf ades +ĠY um +ï¼Įæ¯ı 人 +_dead line +ĠR é +åıª çľĭ +ĠSh ampoo +æľĿ 代 +Ġboard ed +ĠRoss i +Ġfost ers +Ġexhilar ating +Ġactiv ator +æĪIJåijĺ çļĦ +re leases +âĢĻ est +å¼Ģ åİ» +åģļ éĶĻ +éĽĨåĽ¢ åľ¨ +ÑĢаР¼ +Ġim balances +åłĤ çļĩ +åĽĽ æĿ¡ +z burg +æľī çĹħ +âĢľ åħ« +ĠV F +.t a +ĠRel iability +ĠView ing +, ç͍æĪ· +W ikipedia +c ipher +_TR ACK +Ġw agers +ĠH IF +éģ ½ +ĠDeterm ination +广æĴŃ ç͵åı° +opa edic +( valid +r sp +å¼ķ 以为 +-m ot +Ġapproach able +认è¯ģ çļĦ +Ġtx n +C er +害 èĻ« +Ġspl ice +èĥ½ æķĪ +ĠAss am +.E vents +çļĦä¸Ĭ 表éĿ¢ +Ġker atin +Cath olic +ï¼Į ä¼ı +index Path +æĬ¥åijĬ çļĦ +çĦķ åıij +Ġg st +åΰ 访 +ä½įç½® åĴĮ +çŀª çľ¼ +_or iginal +è¾īçħĮ çļĦ +every one +ĠRetriev es +Ġ 麦 +没æľī åĽŀçŃĶ +ï¼Įåı¯ éĢļè¿ĩ +çĽ¸ä¿¡ ä½ł +åĩ¶ æ®ĭ +æĩĪ æĢł +ï¼Į ä½ľåĵģ +Con ven +æĸ¹æ¡Ī åĴĮ +å¿ĥä¸Ń ä¸Ģ +< Point +å£°éŁ³ çļĦ +_E FFECT +åĸĥåĸĥ éģĵ +' ex +çĨŁæĤī äºĨ +, åħ³æ³¨ +a es +ä¿Ŀ åŃĺåľ¨ +åĩł 款 +è¿ĺæĺ¯ 第ä¸Ģ次 +Ġtan ning +ĠPartial Eq +( owner +ï¼Į åĭ¤ +Ġdes ktops +ï¼Įä¸į éĶĻ +æģ¯ èĤī +/d l +åĵŃ éĹ¹ +èĩª 认为 +åįķ èĸĦ +ï¼ĮæĪij ä¸Ģå®ļ +Ġdon key +追 æįķ +oflu orescence +ä¸Ń é£İ +li an +éĩijé¢Ŀ çļĦ +Ġæį® äºĨè§£ +ĠRespir atory +ĠMicha els +, éĢĤåIJĪ +P ictures +ï¼ģ èϽçĦ¶ +Ġform ative +But ter +Ġconc ierge +ĠMore no +çļĦä¸ī 大 +Ø§Ø ¨ +ä¸ī åĵ¥ +_t ex +Ġfe ats +å̼ æĹ¶ +çłĶ åѦ +ĠÃIJ ºÃIJ +åĨ¥ åĨ¥ +åĽŀæĬ¥ çİĩ +Ġgymn astics +æĪĺ çͲ +)} (\ +ãģķãĤĮ ãģŁ +ä¸ĩ èĭ±éķij +çĺ ł +_ch anges +Ġtoilet ries +ROLL ER +_p ref +ç´§ èĩ´ +é¦Ļ èıľ +çļĦè¯Ŀ 说 +æīĺ å°Ķ +Ġmuc osal +. DEBUG +ï¼Į åĪ«çļĦ +Ġcy to +ĠST ORE +ĠOrgan ized +opo ietic +è·º èĦļ +N FT +Ġn inja +ĠW ills +Ġpol ype +Ġ_ $ +æĪ¿å±ĭ çļĦ +ãĢģæĸ° åĬłåĿ¡ +åĽŀ头 çľĭ +ĠConsolid ated +Ġunexpl ained +Ġ 人们 +ĠWh ale +ĠCan ary +è·ij è¿ĩåİ» +ĠDec oration +pol itical +ï¼Įä¸į åĪ©äºİ +Ġant iques +åī§ çĽ® +ä¼ĺç§Ģ å¥ĸ +ĠWik imedia +c oc +c ible +Ġgener als +arm acy +å¿Ĺ 强 +Ġmountain ous +.high light +P PC +ï¼Į æ¯į +è¿Ľè¡Į è¯Ħä¼° +olve ment +ä¸ĢåĪĨ éĴ± + ¨ +ï¼Į çαæĥħ +ï¼Į 麻çĥ¦ +éĢģ 她 +Ġhe par +大 åħ¬ +ere t +ä»Ĭ åĦ¿ +Ġcentrifug ed +ä¸įè¨Ģ èĢĮåĸ» +/ by +is ex +ï¼Į å¼Ħå¾Ĺ +Ġf ave +ĠH obby +ç͍ æīĭæľº +åIJĪ çħ§ +Out look +Ġcomfor ter +Ġ 严 +ĠT su +Ġne ces +æĦıè§ģ çļĦ +åģļåĩº è´¡çĮ® +ĠKen yan +.s cope +ç͵影 ä¸Ń +Bar rier +-b oy +åĩ¯ æĴĴ +.J ob +Ġnic hes +åĨ³èµĽ ä¸Ń +æ¯ı æĻļ +åį« åĨķ +Ġcharacter izing +.R ows +è¡¥ ä¸ģ +Ġstre pt +åīĤ çŃī +w ali +æĸĻ æĸĹ +çϾ åĢį +çĦķ çĦ¶ +æĪij è¿ĻéĩĮ +æĸ¯ æĸĩ +Ġreal tor +失 ç¬ij +ãĢĤä½Ĩ çͱäºİ +Foot note +H art +åīį ä¸įä¹ħ +Ġwid ened +N SS +h ower +.F eature +ĠDam n +Ġchrom ium +å°ıå¿ĥ翼翼 çļĦ +ï¼Į 巨大çļĦ +大 éĢī +åı¯ä»¥ åģļåΰ +ĠC TC +æ°Ķ åĬĽ +Ġmel atonin +R t +d iss +_F REQ +,大 åĬĽ +est r +éĥ½ åĮº +é«ĺ è¿ľ +çĥŃ éĶĢ +æľīä¸Ģ 座 +ä¾Ľç»Ļ ä¾§ +æĮª åĬ¨ +, ä¸ĬéĿ¢ +ä½ł æľī没æľī +客 çļĦ +åŃĺåĤ¨ æľī +-se eking +ĠEmer itus +æĺ¯ åĵªä¸ª +Ġnarr ated +èĬĿ 士 +C USTOM +ï¼Į çĶ·åŃIJ +åľ° åĿIJåľ¨ +容 许 +Ġcor ollary +umm us +çĽĸ çļĦ +}. $ +Ġhes itated +ä½ Ĺ +ĠB J ++ } +Ġ ç»ıèIJ¥æ´»åĬ¨ +Ġcour thouse +å®ŀéªĮ åŃ¦æł¡ +Ġstag gered +ĠPay load +Br ick +Ġ åįģäºĮ +æľĪ 楼 +åįģ çĤ¹ +ç¾İ å¼ı +Ġstip ulation +ĠA STM +ind o +ĠK ell +çİĭ åĿļ +awa ited +Ġк оÑĤоÑĢ +ä»ĸ 身ä¸Ĭ +str ate +第äºĮ 大 +çĵ Ĵ +ï¼Į第ä¸Ģ æĹ¶éĹ´ +Ġwra ppers +èĥ½ æĪIJ为 +æĸ° å©ļ +Ġraff le +t icket +åįģ åIJį +çµ IJ +ãĢĤçͱæŃ¤ åı¯è§ģ +, å¾IJ +ĠW ester +ĠS OP +(m d +å¥ĩ çī¹çļĦ +ĠRic ardo +Ġe jection +ä¹Ł 纷纷 +æĮĩ 头 +ÑĢ Ð¾ +ĠMcG regor +Ġsubdu ed +z p +ĠB oca +äºĮ åħĥ +ï¼Įä¸Ģ çĶŁ +çŁŃ ç¯ĩå°ı说 +è®°å½ķ ä¸ĭæĿ¥ +Mar riage +å¾Ī æĺ¾çĦ¶ +ES I +/ USD +Ġf ide +Ġun o +_m y +ï¼ĮèĢģ 夫 +, åĬ©åĬĽ +B asis +Ġs ire +ĠSL OT +çĥ« 伤 +ĠS ocks +ĠA SL +Ġal ia +ä½łçļĦ æĦıæĢĿ +æµĩ çģĮ +ĠClear ance +ï¼Į çŁŃçŁŃ +å¹¶ æİĴ +Ġquest o +åIJ¸ æ¯Ĵ +çķħ 游 +Ġstric ter +ag ically +ĠP he +æĹ¶ å·² +æĢ» éĩıçļĦ +ĠDis pute +tool bar +æľī å¼Ĥ +èĩªå·± çļĦ人çĶŁ +(n amespace +/ github +æĹ¥ åIJij +ä¼¼ä¹İ åľ¨ +缸åıį çļĦ +- essential +String Utils +(d irectory +Fe eling +K el +in ventory +Ġd unes +ãĢģ ä¿ĿæĮģ +Ġoff s +^{ (\ +Ġ<< " +ĠJo anne +\ cdots +ĠC RS +æĪij们 没æľī +ĠLiber ia +Ġtelesc opes +ĠF ou +- variant +ãĢĤ æĬķèµĦ +ãĢģ æ¬§æ´² +ĠBomb ay +Ġs older +ï¼Į æĢªä¸įå¾Ĺ +Ġre pos +Ġz ap +Cl usters +ç´§ç´§ åĽ´ç»ķ +ĠRiv iera +/ map +ĠM ESSAGE +åħŃ åįĥ +æĥĬ å¼Ĥ +以为 ä»ĸ +é¼ĵ é¼ĵ +Ġentr ants +æļĤæĹ¶æĢ§ å·®å¼Ĥ +ï¼Į éĩİ +ä½ł ä¸įèĥ½ +æĸĩ è¨Ģ +Ġsm ack +Ġenrich ing +creat or +æĪ· æķ° +ãĢģ ä¿Ħç½Ĺæĸ¯ +èµ¶ åΰäºĨ +表éĿ¢ æ´»æĢ§ +Port land +ĠBR CA +棱 è§Ĵ +Ġ è¶Ĭ +Ġ å¢ŀåĬł +ï¼Į åĨľä¸ļ +çİī çļĦ +Ġerrone ously +F lu +Ġ ä¼łçľŁ +æĸ° ä¸ĸçķĮ +æģ » +Ġing enuity +ĠExt remely +.* ]{} +åħ¨ä½ĵ èĤ¡ä¸ľ +å¼Ģå·¥ 建设 +_ Item +ore al +ãĢĤ 谢谢 +ĠF c +æŃ» æİī +éĽ¾ æ°´ +ĠTrad ers +éĴ¢çŃĭ æ··åĩĿåľŁ +åĸ§ åĵĹ +_b uttons +ãĢĤ以ä¸ĭ æĺ¯ +åIJ¬åΰ è¿Ļè¯Ŀ +imm el +ĠT ASK +ĠF RI +åı£ å¸Ĥ +ĠÏĢ Î¿Î» +èĪĨ æĥħ +ĠYuk on +AL YS +è½´ ä¸Ĭ +åIJįåŃĹ åı« +ĠRock efeller +ĠCommun icate +j ans +Ġstart Index +Format Exception +ĠD ems +Ġconst ituting +Ġprot otyping +éĢĥ é̏ +Ġarrest ing +Ġob t +Ġdig ested +Ġtwe aking +b ok +-r ank +, éĥ½æľī +Ġwhere abouts +çīĽ ç¾Ĭ +å·į å·į +E h +åΰ 缮åīį为æŃ¢ +ĠHome page +æĬ¢ äºĨ +æĪIJåĪĨ çļĦ +D ent +åIJĥ æ³ķ +红 å¤ĸ线 +å§Ķ åĨħ +Ġisol ating +æľī æĽ´å¤ļ +éŨ ç¦ģ +hav iors +ï¼ļ人æ°ijå¸ģ åħĥ +ĠS li +太 åı² +ä¸ĸ å¤ĸ +ä¸ĵä¸ļ æĢ§ +æī¿åıĹ çļĦ +æıIJèµ· è¯ī讼 +Ġhug ged +è§ģè¯ģ äºĨ +h il +ãĢĤ è¿Ļä¹Ī +ãĢģ è¯Ħä¼° +Th ousands +sh ifts +æ¯ı æ¯ı +}} $$ +CT C +æĸ¹éĿ¢ çļĦéĹ®é¢ĺ +è¯ĬæĸŃ ä¸º +ic iation +ãĢģ åĬłæĭ¿å¤§ +çīĽ å¤´ +ĠP ony +æĿ¥ 对 +St ores +ç£ĭ åķĨ +ide on +Ġ\ "" +Ġbet tors +Ġter ra +æīĢå¾Ĺ é¢Ŀ +é«ĺ å®Ĺ +block ing +æĢİä¹Īæł· åij¢ +ĠTai pei +æľĪä¸Ĭ æĹ¬ +Ġâ ķ +/g atsby +çļ±èµ·äºĨ çľī头 +ĠI CA +è¡Į çľģ +ï¼ģ è¿ĺæľī +åįķ项 éĩijé¢Ŀ +éĴĪ对 æĢ§åľ° +ĠD PS +ç©¿ åĩº +æĮ¡ ä¸įä½ı +å°Ĩ ä¸Ģ个 +ĠAl uminium +Ġaggrav ating +ç¡®ç«ĭ äºĨ +ĠS SR +IN ATION +éĢĢ æĪ¿ +å͝ä¸Ģ ä¸Ģ个 +éĥ¨ä»¶ çļĦ +ĠMans field +ï¼Į èģĤ +per ia +Ġinter ceptor +æĶ¾ æħ¢ +建çŃij çī©çļĦ +_al ert +_DEF INE +, æľĢé«ĺ +Ġu ber +åĴĮ ä½łä»¬ +Ġj peg +_c alc +Ġder ail +å®Ĺ 室 +dec ision +adal afil +ĠCec il +T ro +çĶŁ 俱 +ä½Ĩ åľ¨ +åĪĽå»º äºİ +Ġfrag rances +ĠRah ul +Ġ åīij +ãĢģ åıĪ +Ġagree able +/r untime +Ġ[ ^ +Ġfl ares +Ġcreat inine +ç«¥ è£ħ +ĠAP PLICATION +æĢĿç»´ èĥ½åĬĽ +Ġretro fit +ĠC ig +âĢľ C +åĮĹ ä¾§ +æĻ® é¡¿ +emp re +诱 åĽł +ãĢģ åĵĪ +Ġdown wards +Ġrun down +çŁŃ è£Ļ +/ pre +æĽ´ å°ı +_per m +ä¼ĺçĤ¹ æĺ¯ +intern ational +ãĢģ A +æĶ¹ çīĪ +ĠRec order +ä¹īæĹł åıį顾 +åIJĥ åIJ§ +çĶ· æĢ§çļĦ +éĻĪ ä¸ĢåĪĢ +第ä¸ī åŃ£åº¦ +Le ast +.To Array +ä½ĵ è£ģ +ä¸İ æĸĩåĮĸ +åı¤ çİ© +ĠDE A +æĢĿèĢĥ åĴĮ +Ġwash able +- ob +@ SuppressWarnings +æľ¬ 年度 +Sh ut +Method Name +.z oom +FIN ITY +ur ist +ä¼ģä¸ļ ä¸Ń +ĠIT V +Ġech ocard +D eg +[ new +ä¹ĭ ä¹IJ +err in +sign ificant +Ġdec imals +çĮ ¬ +, å¹³ +ą Ć +åİ» éĿ¢å¯¹ +Ġpost cards +Ġstandard ization +Ġhyp oth +ä¸ĭäºĨ 头 +, åĽ½éĻħ +: image +ĠE ly +åĩº éĴ± +ĠPro x +èģĶ å§» +ĠInd icators +gs ql +代çłģ ä¸Ń +mult ip +.deep Equal +Ġin clusions +ĠCh am +å·¥èīº ç¾İæľ¯ +UPPORT ED +Ġ 缴 +Ġ éĩįè¦ģ +å¾Ĺ 人 +Ġin hom +Ġg azing +æ¹ į +Pre vent +Co al +çļ Ī +çĸĹ ä¼¤ +åı« 好 +ĠAcceler ator +B IO +d ress +Ġch ained +St raight +çİĩ åĨĽ +Ġsyn agogue +othe rapist +çIJIJ ç¢İ +ĠG OT +ä»» éĢī +太 è¡Į +jo ined +Ġexperiment ed +æ³µ çļĦ +bl ah +ï¼ĮæľĢ åĪĿ +èĭ±è¯Ń åŃ¦ä¹ł +b asis +h ara +ãĢģ åķĨåĵģ +Ġas ynchronously +æīĵ åĢĴ +ERR Y +Ġsh oved +è¿ĩ ä¸įåİ» +odd y +s old +Ġfl op +(\ " +ĠPM I +åĩ¸ åı° +ĠéĻĪ åĪĿ +F er +ï¼Į è¿ľç¦» +ĠS ai +ĠC IT +éŁ³ è´¨ +æĿĢ äººçļĦ +豪 æĥħ +-sh are +ĠBu cc +require ments +agu ay +F LOAT +op i +Ġsh in +çľĭ æł·åŃIJ +æĿ¿ ä¸İ +ä¹ĭåīį åľ¨ +ĠMag ical +åĩºçĶŁ åľ¨ +B EST +.m esh +_T REE +ĠKe eps +.col ors +Ra ise +Mary land +Ġ é¦ĸ +ï¼Į 俺 +ur vey +{g athered +ĠCli ppers +æĥĬ å¿ĥåĬ¨éŃĦ +ä¼ij åħĭ +ĠL ayers +Ġsub mits +Ġliber ated +åħ¨ å¿ĥåħ¨ +/w idget +Ġsumm ertime +ĠHan over +ä¸į è½» +æľª åıijçĶŁ +ç¦ı å°¼äºļ +Thank fully +æĸĩåŃĹ çļĦ +è´¡çĮ® åĬĽéĩı +coord inates +acchar ides +åİ» åΰ +æĹł åīį +æķĻ æ¡Ī +)) ( +æľ« å¹´ +Ġaffirm ing +_TH ROW +Ġcongru ent +ãĢģ ç͵影 +åĴĮ çĥŃ +ĠSh red +èᝠæĸ¹ +ĠAg o +æ²ĥ çī¹ +æī³ æīĭ +æ¯Ľç»Ĩ è¡Ģ管 +ãĢģ éĩĩè´Ń +å°± æĦıåij³çĿĢ +å¾Ģ åIJİéĢĢ +梦 å¯IJ +,\ " +æ¶Ĥ 鸦 +ï¼ĮèĢĮä¸įæĺ¯ åħ¨éĥ¨çļĦ +.l oss +æĤ£ å¤Ħ +Ġw k +çļĦ æĮijæĪĺ +ion g +ãĢĤ ç±³ +Ġat m +èĩª ä¿Ŀ +($ ( +" All +_ rr +am mer +ĠH ISTORY +ä¹ĭ éģ¥ +å¾Ĺ 她 +REC ISION +_sc roll +( ar +Ġ å¦Īå¦Ī +ay ne +ä¸ĭ éĻIJ +两 è·¯ +, æľĪ +N eb +Âł is +å°ı æķ° +åĿļ å®ŀçļĦ +æĬ¹ å¸ĥ +æĵİ å¤© +ĠRu iz +T ED +Ġt rolley +ĠS cheduler +æıIJä¾Ľ åħįè´¹ +åľºæĻ¯ ä¸Ń +, åģ¶å°Ķ +P REFIX +æĪij 说çļĦ +èµ· è·ij +ãĤĵ ãģł +Ġin cess +ĠP ounds +åĪĨ享 åΰ +Ġ'../../ ../ +sp arse +ĠR upert +ν η +relations hips +file Path +div ide +éĿł æĭ¢ +æī¹åĩĨ çļĦé¡¹çĽ® +Ġana erobic +Ġinhal ation +ì Ĩ +Ġn ieces +form atter +æĹł å¼Ĥè®® +çϽ èĮ¶ +å¢ŀ åıij +_s napshot +第äºĮ åŃ£ +plic ial +å±ħæ°ij 身份è¯ģ +(st at +/re leases +( Token +ãĢģ æ¢ħ +Ġk ur +ogn ito +_RE GS +积æŀģ ä½ľç͍ +ãĢģ çĶĺ +ĠD ONE +éĥ½ åıªæĺ¯ +红 æĸij +Ġinform ations +å¿ĥçIJĨ åĩĨå¤ĩ +èįĴ æ¼ł +- No +< vector +鼶åĶ® åķĨ +ĠEz ra +ĠE MC +ä¹Łå¾Ī éĩįè¦ģ +ï¼Į éĢĤ +大 è´¥ +æĶ¯ 线 +Ġeight eenth +Ne ighborhood +exper t +çļĦ æ¯Ķè¾ĥ +ãĢģ åħ¬å¹³ +çϽ 纸 +Ġbusiness men +R uth +æĥ³ çľĭ +举 éģĵ +-b o +( logger +ĠF ir +zb ollah +ÑĤ ÑĮ +å°ļ åı¯ +Ġprop hetic +Ġ å¤ĦçIJĨ +Ġpre text +RE V +Ġcath ode +IM M +.F lags +Russ ell +\ Tests +åĪ« åħ· +è¿Ļç§į çݰ象 +æ£Ĵ æ£Ĵ +mith y +- const +A IR +æĺ¯ éĿł +Ġres usc +ï¼Įä»ĸ ä¸į +,ä½Ĩ ä»ĸ +Ġå°± è¿ŀ +åIJ©åĴIJ éģĵ +pl en +æľ¬ åij½ +åIJĥ 鸡 +it ability +ĠW yn +get t +Ġafter market +ĠGl ossary +ï¼Įä¼ļ 导èĩ´ +Ag ency +ĠGrad uation +ä¿Ŀ温 管 +ãĢĤ å¤į +ĠI IT +åĴĮ å®ī +羣çļĦ 没æľī +Ġrenew ables +çļĦçĬ¶æĢģ ä¸ĭ +åľ¨ åĽ¾ +.get Resource +è§īå¾Ĺ 她 +Ġpred icated +Ġи м +@ string +C m +Ġs ooo +ä¸į å®īåħ¨ +åIJĪ ä¸Ĭ +å¾Ī 严éĩį +交æĺĵ å¸Ĥåľº +å¿ħè¦ģ æĢ§ +æµ· 浪 +Ġthink er +社åĮº åį«çĶŁ +,, , +D or +ï¼Įä¸Ģ æĿ¥ +ĠSaras ota +Ġ oust +Ġint ram +ĠDe Fi +纺 å¸ĥ +太éĺ³èĥ½ çĶµæ±ł +ĠOliv ier +ld rich +Ġsh alt +ç͍ 书 +åįł åįľ +Ins ight +èĤĭ 骨 +ĠConsc iousness +ï¼Į é¢Ĩ导 +erv a +åĽŀ æĶ¾ +æ¶Ī 泡 +åĽºå®ļ å®īè£ħåľ¨ +åıĤåĬł çļĦ +Ġn autical +im iento +æľī çļĦæĹ¶åĢĻ +-b odied +ĠSk ate +è´¯ 注 +Ġb az +Ġin versely +ĠDart mouth +, no +. Option +Ġ éŁ³ä¹IJ +人 èĦī +ĠBe ethoven +é¡» è¦ģ +岸 ä¸Ĭ +çĨł çĨł +Ġu art +åĴĮ ç»ıèIJ¥ +å¹» å¢ĥ +è¿ĺ没 说å®Į +ĠLion el +ï¼Į èīºæľ¯ +大 é¾Ļ +æĹ¥ æĹ¥ +äºij æµ· +E lection +Ġ åΤæĸŃ +ĠT ITLE +æĶ¾ æ°´ +ï¼Į éħįç½® +åĨħ æķĽ +èĩªçĦ¶ ä¹Ł +cast ing +Ġfr antic +åĩĿ ç¥ŀ +ï¼Įçİ°åľ¨ æĺ¯ +,ä¸Ģ 天 +Eth ics +Ġn oses +ĠM CP +ĠR oz +æĥħ绪 çļĦ +è§Ĵèī² æī®æ¼Ķ +_sp i +æĹł æĿĥ +åĨ³å®ļ 书 +为主 线 +鹿 æĻĹ +ĠSans krit +" Don +f ib +ãĢģ å½±åĵį +åħĭ 鼷 +Ġk ol +举 è¯ģ +æľīä»Ģä¹Ī éĹ®é¢ĺ +ï¼įï¼įï¼įï¼į ï¼įï¼įï¼įï¼į +Ġpresent ers +Ġten or +æİ¥çıŃ äºº +y k +ï¼Į åĪĹ +ĠK ak +Ġent renched +éĺ» æĮł +èĥĨ éĩı +_per mission +çĽ¸ä¼¼ 度 +D avis +Ġphot ovoltaic +å·¥ä½ľäººåijĺ çļĦ +ĠS ensitivity +å¤ļ æĥħ +æĹłçº¿ éĢļä¿¡ +人èĦ¸ è¯ĨåĪ« +åĴĮ ä¼ĺåĮĸ +( Set +åıį ä¹ĭ +èΰ å¨ĺ +^ e +ç®Ĭ æĢ§ +éĻĦåĬł å̼ +ĠR outes +å°ij åį¿ +ç©¿ è¡Į +Ġsen ate +Ïĥ ε +èIJ½åΰ å®ŀå¤Ħ +Ġbl asts +礼 è®° +_m ount +Ġorgan izes +_D DR +Ġfresh men +adec imal +G K +ĠP OT +ãĢģ æĥħæĦŁ +ĠIm possible +ĠMon a +çĩĥ çħ¤ +G overnor +ĠC ancellation +ãĢģ èħ° +éĩįçĤ¹ æĺ¯ +_ ie +ä¸Ģ个 æľĪçļĦ +Ġmass ages +彩 ç»ĺ +ç§ĭ 鼨 +Ġpunct ure +is oft +Ġ[ / +æĹ¥ æľŁéĹ´ +ãĢĤéϤ éĿŀ +ï¼Į é¡¿ +se mi +ãĢģ éĥ¨éŨ +åľ¨ åİŁåľ° +æŃ¤ çĶŁ +åŁºç¡Ģ æķĻèĤ² +Ġec x +Den ver +\ bib +åŁŁ çļĦ +,ä¸Ģ æĺ¯ +åĪĨéħį åΰ +Ġentr ances +a uthors +ĠC SC +Ġtechn ologically +.h ibernate +mb uds +åĶIJ 书 +è·ij è·¯ +ï¼Į æķ´åIJĪ +æľĢ ä¼Łå¤§çļĦ +æ» ģ +åĥı 以åīį +请 åıĤéĺħåĽ¾ +Ġd agger +ç´¢ è¦ģ +R p +ist ler +up a +交 ä¼ļ +åĽ¾ è°± +ä¸ŃåĽ½ ä¼ģä¸ļ +å¼Ģåıij åĪ©ç͍ +å·¥èīº æµģç¨ĭ +Ġdimension ality +IFICATION S +ra ch +Ġwait For +Ġexecut ions +-r ise +é«ĺåħ´ äºĨ +Ġα ÏĢο +æ²ĥå°Ķ çİĽ +f am +Ġtimestamp s +Ġsegreg ated +_ led +ï¼Į æķħäºĭ +ric ot +æ²¹ æĢ§ +ĠChe shire +Ġmut tered +ï¼Į åľ°ä¸Ĭ +PC S +ĠStr anger +Ġtroubles hoot +Ġstalk ing +ĠAuditor ium +ä¸Ĭ 讲 +ER ATOR +主è¦ģ éĽĨä¸Ńåľ¨ +读 éŁ³ +亿 人 +Ġpropag ating +ĠPresent ed +á ¿ +ï¼Į ä¸ĸçķĮä¸Ĭ +两 æĬĬ +æįķ æįŀ +èµĦäº§è´ŁåĢº çİĩ +, åĢĴ +- New +åľ¨ å¾Īå¤ļ +åħ¨ éĺŁ +âĢĿçļĦ çIJĨ念 +åͱ çļĦ +ract able +ĠEng ines +Back Color +ĠPale o +ĠC CA +æł¼ åĭĴ +-t uning +-c rafted +Re plica +åºĶæĢ¥ æķijæı´ +Ġspir ited +Ġgirlfriend s +Ġ ï¼» +ĠN uts +好 çİ©çļĦ +çļĦ人 éĥ½çŁ¥éģĵ +æŁ¥ åħĭæĭī +:\ /\/ +ï¼Į çĥŁ +EN UM +Activ ated +-drop down +S ydney +Ġ åĿIJåľ¨ +it et +å¸Ĥåľº 主ä½ĵ +ĠDav en +(w in +l ady +iew icz +CC R +ĠL X +oc ortic +_P USH +Sub net +Ġmal ice +çļĦæľĢ å°ı +-imp act +* % +æīĵ 游æĪı +ä¼ĺ éħ· +æľ¨ 马 +Ġstock holders +Ġcommand ers +Ġcytot oxicity +ĠStr ick +ĠComplex ity +ning en +æĬĬæı¡ ä½ı +ä»İå°ı åΰ大 +_c pp +ĠSadd am +, åijµåijµ +: value +éĺ²æĬ¤ 罩 +åľ¨ éŨåı£ +åħ¶ åIJį +-t ail +èĩªå·±çļĦ å®ŀåĬĽ +-g rowth +(w idget +V IN +大 çľ¼ +.A uthor +Ġtra inee +ĠW INDOW +æĹ¶éĹ´ çŁŃ +.get Content +_D S +ĠBay ern +Ġ Ùĥ +Ġw f +ãĢĤ åIJĦç§į +ç͍ è¿Ļç§į +å¤ĸ 头 +ä¸Ĭåįĩ è¶ĭåĬ¿ +ĠCul inary +Viet nam +ãĢģ å®ŀæĸ½ +æĬ¥ çļĦ +just ify +è¿İ çĿĢ +çѾ äºĨ +å¦Ļ æĭĽ +_SE LF +å±ħä½ı åľ° +$ A +ï¼Į æµħ +Ġ$ -\ +Ġrec oil +cre ening +çīĩ ä¸Ĭ +ĠBl uff +Ġstatus es +]{ }. +, çİ°åľ¨çļĦ +ï¼Į åĦ¿ç«¥ +Ġquery ing +/ plugin +Ġ ä¸ĢäºĽ +Ġl f +ĠL STM +éĤ® å±Ģ +ï¼Įçݰ å·² +ĠInstall er +ï¼Į èµ¢å¾ĹäºĨ +é«ĺ éĩĩ +æī§ æİĮ +.Ex it +æĸ¯ 大æŀĹ +æ¹ Ħ +ĠLoad s +ãĢģ éĻį +Ġha ze +åĨ· ä¸į +Dist ributed +- cylinder +ĠRe ign +çļĦæķ°æį® æĺ¾ç¤º +Ġgol fer +ĠB EL +åĪĨ åĩº +ä½İ æĶ¶åħ¥ +ĠPRO PERTY +ï¼Įæ°Ķ æ°Ľ +æ»Ķ 天 +id ue +ä¸Ńå¿ĥ åĴĮ +å§ļ æĺİ +åŃ£èĬĤ æĢ§ +ä»ĸ ä¿© +åĽ½ èĦļ +åĢŁ çͱ +åIJĪåIJĮ 约å®ļ +ĠHe ading +å¾· æĦıå¿Ĺ +Ġet ching +Re action +Ġmis represent +, 缴 +h ora +rac ula +ä¸ĭæ°´ éģĵ +ĠP seud +åľ¨ åįİ +th umbnail +ĠSur geons +Ġpure e +' am +ĠF ries +ĠF CA +Ġsh orthand +ç»Ļ æ°´ +chen ko +omin ator +Ġcraft y +Ġun balanced +ï¼Įä¸Ģ ç»ı +èĮ¶ æłij +Ġsand ing +} c +Ġ æĿ¥åΰ +or relation +ĠCh ak +çİĭ 宫 +åĨ² ä¸Ĭåİ» +(n o +Ag reement +W arranty +ãĢĤ è¿ĩäºĨ +ãĢģ æĪ¿åľ°äº§ +Le od +ãĢĤæĽ´ ä½ķåĨµ +Ġenlight ening +Ġquer ied +èİ·åıĸ åΰ +Ġhe lix +ĠG rip +ä¸ĭ æĭī +åIJİ ç»§ +ĠAs per +çļĦåıijå±ķ åĴĮ +ĠPL AN +ç»´çĶŁç´ł c +ãĢĤèĩ³ æŃ¤ +olog ia +åĨľ è´¸å¸Ĥåľº +ä¸Ńæĸĩ çīĪ +ĠAshe ville +g os +t aken +ĠL imb +å°ij æľī +ï¼Įåı¯ å°Ĩ +åªĴä½ĵ è®°èĢħ +æĩĴ èħ° +REFER RED +c ao +çļĦä¸Ģ项 æĺ¯ +ĠHutch inson +- formed +åı¯ è§ĤçļĦ +ãĢĭ 以åıĬ +Mon key +Ġce ases +- Ad +ãĢģ ä¸Ļ +为 天 +ĠBas eline +ĠCOUNT Y +Ġtelev ised +Ġstagn ant +æľĢ æĢķ +_B IG +ï¼Įå½ĵ æĹ¶çļĦ +EL COME +ĠStr and +ĠFund raising +åķĬåķĬ åķĬåķĬ +Expl oring +åįĹ æ´ĭ +è¶³ åĿĽ +ĠBO ARD +l z +ĠC inderella +ä¸Ĭ åıij表 +-in variant +Ġalcohol ism +çļ±äºĨ çļ±çľī头 +ï¼Į æĭ¨ +_F ield +æģ¶ 人 +-x l +Ġsmok y +- CH +Ġo id +Ġright ful +设计 é£İæł¼ +____ _ +请 æĿ¥ +å®ŀéªĮ å°ıåѦ +ç²Ĺ ç»Ĩ +Ġalign ments +é¢Ħ åΤ +è·ij åĩºæĿ¥ +Ġaffili ations +Ġculmin ating +# u +çļĦ åĨ²åĬ¨ +请 è¾ĵåħ¥ +å°Ħ ç®Ń +ä¸į å±Ī +ãĢģ 人æ°ij +ood oo +ï¼Įä½Ĩæĺ¯ çͱäºİ +è¦ģ 约 +åı¯ çĩĥ +iel le +èĢģ 乡 +æ¯ı ä¸Ģç§į +-m otion +究竣 æĺ¯ä»Ģä¹Ī +ĠN ES +ĠK U +ï¼Įä¹Ł ä¸įæķ¢ +Out standing +/ testing +ä¸Ń 带çĿĢ +èį ª +ãĥķãĤ¡ ãĤ¤ãĥ« +ï¼Į å·¨ +æľī æ°§ +åĽ½ ç¨İ +éª ¡ +æĬĢ å·¥ +æĶ¾ ä¸įä¸ĭ +éļı è¡Į +æ¼Ķ è¿Ľ +Ġflu ency +-develop ment +Ġa ve +å¥ĩ å¦ĻçļĦ +强大çļĦ åĬĽéĩı +calcul ated +, 第ä¸Ģ次 +_p i +èĭı å·ŀå¸Ĥ +Ġgg plot +ãĢģ æĪ¿å±ĭ +Ġdies e +Ġsc our +èĵĿ çѹ +Ġairt ight +çļĦ çľĭåIJij +ãĢģ èī²å½© +å¹´ å¹´åºķ +æľĢ éľĢè¦ģ +æ´» 人 +åĮħè£ħ è¢ĭ +Ġg if +ĠS PL +ä¸į éĨĴ +å½± ä¸ļ +ç®Ģ æĺİ +å°½ åľ¨ +åħ° çļĦ +$ M +ä¼ļ éļıçĿĢ +èĮ¶ åĮĻ +Ġmorph ine +âĢľ . +åħµ 士 +Ġwill ful +ĠCumm ings +éĢļè¿ĩ åIJİ +æ··åIJĪ åĿĩåĮĢ +O EM +Ġ å¸Ī +ï¼Į 主人 +âĢľ ä»İ +æŃ¥ éģĵ +Ġsw irling +åİĮ æ°§ +æĹ¶æĹł åĪ» +çļĦ å®ŀæĸ½ +ĠC DS +ï¼ĮæĪij åı¯æĺ¯ +Ġsk ysc +ä¸ŃçļĦ æķ°æį® +ĠWhat sapp +åı« ä¸Ģ个 +磨 çłº +Ġbail out +æº Ł +ç»Ħ æĪIJäºĨ +ek o +Ar my +åĨ³å®ļ æĢ§ +Make file +Ġrect ify +ãĢģä¸į éĶĪéĴ¢ +æľ¬æĬ¥ 讯 +Ġmonst rous +F mt +Q V +ãĢĤ åѦéĻ¢ +CC D +计ç®Ĺ æĸ¹æ³ķ +çıŃåŃIJ æĪIJåijĺ +MMMM MMMM +éϤ èįī +_D RAW +Ġelev ations +缮å½ķ ä¸ĭ +ï¼Į æĹħ游 +_p ix +,å¹¶ 没æľī +erent ially +â̦â̦âĢĿ âĢľ +âĢľ åĵ¼ +ç͵ ä¿¡åı· +File Size +ubs cription +åŀĤ缴 äºİ +ï¼Į两个 æīĢè¿° +ç»Ļ åѦçĶŁ +ĠÐ ij +Ġhard y +è§ģéĿ¢ äºĨ +, è§£åĨ³ +ãĢģ æĻºèĥ½åĮĸ +ge ometric +Ġcounter act +è§ģåΰ ä»ĸ +/ aut +ĠT ad +å°± éĿŀ常 +åIJĮ 声 +æīĵ ä¸ĭäºĨ +éĵº åŃIJ +Ġ____ _ +( CH +对 æīĢæľī +车 头 +æ¸ħ åĨ· +åĸľæ¬¢ 她 +å¼Ģåıij äºĨ +èħIJ æľ½ +æ´ª èįĴ +yll is +ĠW izards +Ġin eligible +åģĩ 象 +Rest riction +Ġ è´ŁåĢº +ãĢģ æµĭè¯ķ +ï¼Įä½Ĩ åıªè¦ģ +é£ŀ è¿ĩ +ï¼Įåı¯ä»¥ æĺ¯ +mac d +ol and +ur ic +ï¼Ī åīį +CT A +åĬ³ ä½ľ +Ġcoll apses +åĪĩåħ¥ çĤ¹ +ĠM IME +ï¼Įåľ¨ 使ç͍ +è¿ľ æĻ¯ +ĠRel oad +è§Ħæł¼ çļĦ +ĠHistor ically +Ġescal ate +> s +ĠFor ced +马 åĪº +_b t +-s erving +ĠList ener +çļĦ第äºĮ 端 +-compl iant +ï¼Į ä½Ľ +ãĢģ åĮºåŁŁ +æĬ¥ åºĶ +_st ar +çIJĥ ä½ĵ +UM B +ĠCould n +_F ORE +Ġsuper st +汽车 ç«Ļ +upp et +ĠRow e +Ġverte bra +ent re +è¾¹ è§Ĵ +çİ°åľ¨ è¿Ļ个 +Ġgra pple +ĠSk ull +_CON NECTION +ĠSal man +Localized String +Ġlinger ie +Ġg ulp +ĠC uisine +è¿Ļ 两人 +çľĭ åIJ§ +Ġrest rain +å®Ŀ ç®± +.Add Range +ADD RESS +C UR +ĠE mber +åħĥ 人æ°ijå¸ģ +æľ¬åıijæĺİ æ¶īåıĬ +non ce +Way ne +R ATE +Ġg id +ĠS SE +y lic +Ġbi opsies +Ġbreakthrough s +Respons ible +- End +ä¸Ģèά éĥ½ +Ġswe eter +(' $ +便 å½ĵ +æŃ» ä½ł +ä¸Ģ缴 å¤Ħäºİ +以ä¸Ĭ åĨħ容 +ĠDel oitte +å¨ľ çļĦ +is ive +ä¹łæĥ¯ çļĦ +Ġbull pen +Ġb ellow +ĠN AC +_m ass +æĸĹ ç½Ĺ +æī« éϤ +åı°æ¹¾ çļĦ +_ pts +åIJİ æľī +ï¼ī è¿Ľè¡Į +ä¸Ģå¹´ å¤ļ +ä¼ĺå¼Ĥ æĪIJ绩 +ä¹ĭ åĪĹ +äºĮ 个 +æĽ¿ 身 +ĠSunder land +P IC +å¾Ī å°ıçļĦ +-c oded +çĨ µ +çŃī éĩįè¦ģ +ä»į å¤Ħäºİ +ov als +让 æĿİ +_s ources +Ġelabor ated +ĠL umber +头 åı· +ĠSW IG +stat istics +ĠпÑĢ Ð¸ +ĠB anc +pp t +临 åħ¶ +è¾ħ 缸 +ĠBu ick +ĠIt alia +ï¼Ī è¯ķè¡Į +èģĶ åIJį +çIJĥ 磨 +åħį ä¸įäºĨ +ĠFound ing +Ä ° +è¿Ļæł·çļĦ éĹ®é¢ĺ +èĢģæĿ¿ çļĦ +t og +-s ervices +èĴ² åħ¬èĭ± +ĠAthlet es +P AN +ĠG ee +Ġrec ollection +éĢī æĿIJ +++ + +åĽ½éĻħ åľ¨çº¿ +mem brane +L AST +ĠY ates +Ġra cer +-m embers +ĠCall er +å®ī é¡¿ +å¾· è¯Ń +èµĽ å°Ķ +_TR IGGER +Ġinstruct ive +ĠMaid en +ĠArchae ology +Ġde activate +ax el +è¡ĮæĶ¿ åĮºåŁŁ +Ġmot ility +é¤IJ æ¡Įä¸Ĭ +Scot land +Ġ å¿ĥä¸Ń +Ġj query +Ġdisc olor +iol i +æľºåύåŃ¦ä¹ł ç®Ĺæ³ķ +Ġw d +è¿Ľè¡Į æ¸ħæ¥ļ +Ġsal inity +L ING +ï¼Į èµ°åIJij +Ġb aud +ĠS CHOOL +åĸĿ çĤ¹ +Do S +ĠAtl antis +éĢĴå»¶æīĢå¾Ĺç¨İ è´ŁåĢº +Z D +åıĶ çζ +Ġsusp icions +çİ°åľ¨ è¿Ļæł· +å¼Ĺ æ´Ľä¼Ĭ +éĻĦåĽ¾ ä¸Ń +Buff ered +å®ŀçݰä¸Ĭè¿° 缮çļĦ +- command +_P AY +åİ¿ 人æ°ijæĶ¿åºľ +US C +n B +Ġn row +è§Ĩ ä½ľ +_b b +ï¼Įå½ĵ åľº +å½Ĵ ä¸Ģ +èĻİ çļĦ +Ġ ../../ +ãĢģ åIJ¬ +åĴĮ èĢģå¸Ī +å¤ĸ éĥ¨çļĦ +åı° å¼ı +ĠGener ates +丰 ç¡ķ +/P rivate +åıĸ代 çļĦ +ãĢģ éģĵ +åĨľ èĢķ +uit o +èĥ¡è¯´ åħ«éģĵ +t ur +Ġpres ervatives +Ġfore arm +Ġadopt ive +Ġsid el +è°¦ éĢĬ +ï¼Į å¼¹ +è¿ĺ 带çĿĢ +ç³»ç»Ł åľ¨ +æĬĵ äºĨ +èĬ¦ èįŁ +.And roid +ĠRem aining +Ġdef orestation +ĠAm os +ĠWild er +çŃī éĥ½æĺ¯ +ï¼Įä»ĸ ä¹Łæĺ¯ +-st orage +æŃ£ç¡® åľ° +Ġwid en +Anal og +q f +ĠA OL +æ´» çĿĢçļĦ +ãĢĤ çİī +ĠW TO +第ä¸ī 人 +è¹ ĭ +Subject s +$ r +' ? +on k +Ġu z +èĩ³ å®Ŀ +æĶ¾ åĽŀ +Ġinf ographic +设å¤ĩ ä¸Ń +å®īæİĴ 好 +ĠFP GA +ãĢģ 审计 +主 æĹ¨ +Ġfree zes +è°ĥæķ´ åIJİ +: å¦Ĥæŀľ +Ġemb argo +åºŁ åĵģ +ĠPH YS +Ġapt itude +_ Button +... [ +ï¼Įä¸į å®ľ +æ¸ħ 羣 +Ġuns olicited +æĺ¯ æĿİ +ä¼ļ åIJĪ +她 è¦ģ +å¾® è°ĥ +ĠCR T +åIJĮå¿Ĺ 们 +æĺŁ äºij +è´Ń 建 +å§ĭç»Ī 没æľī +ĠPic asso +: new +ãĢģ èĢĥè¯ķ +åĩı 产 +Ġenc ore +æľī人 æĿ¥ +æıŃ çīĮ +\ Api +Ġw icket +Israel i +\ C +Ġ 谢谢 +强 横 +Ġpolymorph isms +Ġ äºĭ +ĠR ipple +ĠN ose +é«ĺ è̏ +æĶ¾ 声 +åħ·æľī çļĦ +K er +ĠF ritz +åĬł ç´§ +_p ipeline +æ·± èī² +Ġcustom ised +ĠLe a +(m etadata +udd in +Conf idence +她 æĥ³ +(f older +ï¼Įæľī åı¯èĥ½ +æ¢ħ å°Ķ +Ġcomplic ate +Ġspo iler +.jet brains +ĠN ess +é¼İ 缼 +ï¼Į åįļ士 +ĠCh ard +丽 丽 +ä»Ļ çķĮ +æŃ£å¼ı åIJ¯åĬ¨ +othe lioma +ç¼ĸè¯ij åύ +å½· 徨 +. rt +it ät +ï¼Į 微信 +im ar +çĭ¬ ç§Ģ +æľ¨ åģ¶ +åºĶç͍ é¢ĨåŁŁ +å¹´çļĦ åıijå±ķ +-E uropean +b ah +çļĦ æĻ¯è±¡ +ec ure +-b uy +================ ==== +身ä½ĵ éĩĮ +ĠAle c +R i +ĠF MC +å¾Ī å¿Ļ +转 æľº +åĮħ 头 +ï¼Įæľī ç§į +ĠEd g +ĠIslam ist +糸 äºĨ +åľĨæŁ± å½¢ +N AM +Ġsub cutaneous +åĮĹ ç«Ļ +Ġe rection +åĨ² äºĨè¿ĩåİ» +ï¼Ľ 为 +Ġ` -- +æĽĿ æ°Ķ +J oh +ĠL ymph +çıł ä¸īè§Ĵ +APP Y +Ġ× ij +Ġstrat ification +s phinx +ãĢģ æľº +天 åķĬ +Ġar du +åįķ æīĭ +转 æĴŃ +åĮ»çĸĹ ä¿Ŀéļľ +çݰå®ŀ ä¸ĸçķĮ +容åύ ä¸Ń +Enh ance +Ġempt ied +ï¼Įä½ł åıĪ +çīĩ åĴĮ +ug get +èĤ¯ å¾· +.ch oice +ĠDam ien +ĠAJ AX +Ġfl uff +ĠMan uscript +(M ain +åĩºæ°´ éĿ¢ +ä¸Ģ åį· +ĠB ANK +管 äºĨ +产åĵģ ä¸Ń +Ġvol ts +顺 æĹ¶éĴĪ +æļ´ æĢĴ +è½°è½° çĥĪ +æį¢ ç®Ĺ +ä¸įè¿ĩ åİ» +ç͵è§Ĩ ä¸Ĭ +å¹³éĿĻ ä¸ĭæĿ¥ +ä¸Ģ æİĮ +og yn +ĠPol ly +ìĿ ¼ +ä¸į 为人 +éģĵ è°¢ +Ġbody building +_dist ribution +ĠMSN BC +为 è¾ħ +æŃ¥ è¿Ľ +éĵģ å¡Ķ +User ID +,让 ä»ĸ们 +ĠHem isphere +N ursing +ĠM ailing +(n etwork +èĥĮæĻ¯ å¢Ļ +Ġincub ator +ĠB ieber +ĠL ep +æıIJ æĪIJ +ĠSh ri +_b w +Node Type +link ing +èľĤ æĭ¥ +Ġmemor ize +oe lect +NY C +-C an +ï¼ĮæĽ´ èĥ½ +ãĢģå®Įæķ´ åľ°æııè¿° +åĪ« 离 +ĠChrist church +éĽĦ 鹿 +çļĦä¸Ń éĥ¨ +ãĢĤ å¼Ģå§ĭ +åħ¨ ä¸ĸçķĮçļĦ +.M ode +ĠBart lett +ä¸ī åĪĨéĴŁ +è´¢åĬ¡ ä¼ļ计 +åı¯ä»¥ ç¡®å®ļ +åı£ æīį +-con v +Ġnewborn s +å; æ¶² +] =' +b low +Ġprov oking +ĠAcc om +ä¸į æ¼ı +ans ki +ä¸İ 被 +Ver se +Isa iah +B oo +Ġrins ed +ĠH oy +åįĬ 空ä¸Ń +è°ĭ åıĸ +æĤ¬ èµı +ä»Ķç»Ĩ çľĭ +H ANDLE +ï¼Į å®£ä¼ł +ĠS OME +å¥ĸ çļĦ +s è +Ġpolit ic +Ġten ancy +ĠZe us +Ġcongreg ations +. ^ +ãĢĤ ç«ĭåį³ +ĠC Z +ãĢĬ ä¸īåĽ½ +åį³ åħ´ +ĠFire wall +çī§ ç¾Ĭ +ĠBurg ess +çͲ 骨 +omer ic +Ġcl ueless +åħ¥ åij³ +åįĬ æķ° +å±¥ 带 +娴 çĨŁ +t is +æĹłæķ° 个 +. peek +çļĦ å¢ĥçķĮ +Ġme lee +AD VERTISE +Ġcur ricula +ï¼Į æĬķåħ¥ +ä¸ĩ åİĨ +æĸ°éĹ» åĩºçīĪ +- DC +é£İ éĢŁ +uk h +Ġfre eway +èݱ å¾· +åıĺæĽ´ çĻ»è®° +ĠâĬ Ĩ +ĠCrow d +Ġfilmm aking +ĠD rives +Ġ? ?? +请æ±Ĥ çļĦ +ĠReve al +å² ĸ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠ +ĠVer se +ãĢĬ 天 +_d l +Ġappropri ation +VO KE +ี à¹Ī +( OH +ĠR adeon +ĠPM C +omin ations +Ġcro pping +(cl uster +ä»Ģä¹Ī è¯Ŀ +åĽłä¸º è¿Ļ个 +Ġcirc adian +,åľ¨ è¿ĻéĩĮ +Ġnut meg +ĠSP ACE +çݰéĩijæµģéĩı 表 +Ġv æ +被 ä¸Ģ个 +ĠNe u +ÃŃt ica +ä¸Ģ åĪĻ +ãĢģ å¤į +ĠCyp ress +, çŁ¥éģĵ +, éĩįæĸ° +ag in +ĠRE PLY +Ġgar ages +Ġ åѦçĶŁ +Ġor chard +ä¸ī éĢļ +梦æĥ³ çļĦ +wp db +Ġgr ating +Cl ark +èĭ± æĿ° +Ġchalleng er +è¡ĮæĶ¿ å¤įè®® +Ġgrat is +\ E +äº ³ +ĠT REE +AM PL +uk o +_qu ote +ex am +-r andom +éģĩåΰ çļĦéĹ®é¢ĺ +Ġbrew ed +ï¼ Ń +Ġl ousy +ĠSign ing +ä¸Ģå¼Ģå§ĭ å°± +ĠRespons ive +" x +两 æĶ¯ +æķ°æį®åºĵ ä¸Ń +- ath +Ġ åŃĺè´§ +AT G +举 éŨ +-b ind +Ġsize able +æĨĭ å±Ī +B uddy +ĠA ura +ĠW rit +ä¸İ æİ§åζ +ï¼Ī R +æŃ£ 大 +pr inc +æŃ¢ æ°´ +åħ¨éĥ¨ éĥ½æĺ¯ +-M in +âĢĻ an +åŁº çĤ¹ +é£İ çĶŁ +çĶŁæ´» è´¹ +ä¹ĭéĹ´ æľī +æİ¥æĶ¶ åύ +Bath room +Ġbour bon +æŀ ³ +ĠBlack burn +åħ»èĢģ éĻ¢ +ĠRemodel ing +, ä¾Ŀæ³ķ +L ind +Ġ æĻ®éĢļ +Ġk ube +åı« æĿ¥ +Ġmeas les +说çĿĢ è¯Ŀ +çĮİ æĿĢ +w elling +ov ski +Ġunt rue +ä¼Ł ä¸ļ +Ġ è¯į +é«ĺåħ´ åľ° +çĥŁèĬ± çĪĨ竹 +\ # +Ex tras +äºij æ·¡ +-car b +ĠThess alon +, å®ĮåĸĦ +é¾Ļ åŁİ +ï¼Įå°Ĩ æīĢè¿° +åįĸ æĸ¹ +主åĬ¨ æĿĥ +çļĦ éĺ¶æ®µ +èĦ¸ éĿ¢ +çī¹åĪ« å¤ļ +æĮ¥ éľį +为ä»Ģä¹Ī åij¢ +PC lient +èĪŀ å¼Ĭ +é«ĺæł¡ æ¯ķä¸ļçĶŁ +_ primary +Ġt renches +ï¼Ľ æľĢåIJİ +Ġattract iveness +æł¡åĽŃ éĩĮ +- letter +ï¼Į 失åİ» +ç²ī 红 +å¹¶éĿŀ æĺ¯ +ĠTarget s +ut ures +co ast +Ġfl ange +èĥ½å¤Ł çľĭåΰ +çķħ å¿« +ï¼Į两 人çļĦ +ï¼Į为ä»Ģä¹Ī è¦ģ +ĠCoo ke +ãĢĤ è¿ijæľŁ +身 ä¸ĭ +æĽ¾ ä»» +ãĢģ ç»ĵ +åIJİ è¾¹ +æľĪ åĪĬ +èĤ¡ç¥¨ éħįèµĦ +W alter +ĠT umor +大 伯 +ĠJ OB +æijĦ æĶ¿ +çĭĹ ç²® +åIJĮ 人 +Ġte k +æīĭæľº 游æĪı +设æĸ½ çļĦ +Mar vel +un ame +çĹħ æŃ» +Service Impl +ĠRo asted +èĢģå¹´ 人çļĦ +ä½ł è¿Ļæł· +æį İ +éķ¿ æĮī +Ġpel vis +Ġins istence +æĸĩåĮĸ ä¸İ +åľĨ åľĪ +Ġthe res +'] ), +çĥ§ çĥŃ +Ġsh roud +iot ensin +F UN +t ro +æĺ¯ åħ¬åı¸ +iv ating +Ġgener ative +ig matic +(p rivate +Pack ets +主é¢ĺ æ´»åĬ¨ +K am +Ġint est +éľĢè¦ģ å°Ĩ +ĠDisc ipline +çªį éŨ +stead y +Ġcentrifug ation +W u +çϽ ç¾Ĭ +ï¼Į对 æĪij +_IN C +Ang les +Ġtransf usion +Jew ish +çļĦ åIJĪæĪIJ +ãĢģ åĮ»åѦ +åıĺ ç͵ç«Ļ +éģĩ è§ģäºĨ +å¸Ń ä¹ĭåľ° +è¸ı ä¸ĬäºĨ +ĠFer din +Ġr ink +ĠG raz +éĶ Ĩ +ä¸ŃåĽ½ çĶ» +åł ± +ĠMar ino +\n onumber +Ġquad ru +ĠF iat +åŃIJ éĥ½ +_m u +èĥ½å¤Ł 满足 +ĠPe ck +ĠNat asha +re ef +ĠM Sc +ĠS ass +ä¹ĭ çŃĸ +Ġcommut er +Ġinsol vency +iconduct ors +ï¼Į æĪĺæĸĹ +ĠR IP +ie vers +æ¯ķä¸ļ çļĦ +Ġtab oo +-tr ad +_ unknown +.T otal +å§Ķåijĺä¼ļ 主任 +andon ed +ä¸į对 ç§° +Ġpleas urable +ber ta +ä¸įæĺ¯ 个 +.t asks +Ġceremon ial +Ġsynth ase +( collection +çļĦ åıijçݰ +åľ¨ åIJĦ个 +åı¯ä»¥ å¢ŀåĬł +交 åΰ +äºļ 麻 +yl us +ç¡ħ èĹ» +ä¸ĩ åIJij +ï¼ĮèĢĮ ä½ł +åĮ»çĸĹ è´¹ç͍ +ĠDi aries +Ġdivis ors +C ape +C MP +v pn +Ġm A +Ġd iner +ĠM osaic +_p recision +大 æĿĥ +åĽ½ åIJĽ +ä¹ĭ å·ħ +该 åĽ½ +请 äºİ +Ġdir s +M m +T one +ut to +éĥ¨ 份 +å¼Ģå§ĭ åīį +å²ģçļĦ åŃ©åŃIJ +é«ĺ éĺ¶ +离 ä¸ĸ +_reg istry +(f lag +羣æŃ£ æĦıä¹īä¸ĬçļĦ +Ġaqu a +Ġapt ly +" ä¸İ +Ġ èģĶ系人 +ï¼Į è§Ħ模 +ä¸į æŀĦæĪIJ +ĠD warf +and ers +Ġconc urrency +Ġsong writing +* [ +D ense +ĠE uchar +å¾Īå¤ļ æľĭåıĭ +éĿĴæµ· çľģ +éľĢ åľ¨ +æµ· äºĭ +roll back +欺 人 +( email +, æľ± +ĠThe rapeutic +ä¹ĭ 礼 +ä½įç½® ä¿¡æģ¯ +ulture Info +ãĢģ 羣 +å°ı å°Ĩ +举 åįİ +ĠCatal yst +è°ĥåij³ åĵģ +( adapter +æĥ ´ +çĶŁ è¾° +éķ¿ æĸ¹å½¢ +Ġunder statement +ä¸ŃçļĦ å®ŀæĸ½ä¾ĭ +Ġhom ologous +ĠCast ing +_check point +éķ° åĪĢ +et es +ĠI OP +åľ¨ æīĢæľī +Ġjust ices +Ġauthor izing +è¿Ļæł·çļĦ äºĭ +Ġa ri +om ach +Ġabs cess +-p ointer +å¯Ĵ çļĦ +Co ast +ĠChi ang +ï¼Įä½łä¼ļ åıijçݰ +it ively +ĠS SP +åĨ° éľľ +åħ¨ä½ĵ åħļåijĺ +çį ł +, æİ¥çĿĢ +ï¼Į æĮij +Ġk im +ary ana +çϾ èά +Ġsuper imp +_B ANK +çĶŁåij½ å®īåħ¨ +-man aged +ĠCHE M +PLIC IT +ĠO SS +RO AD +U ps +æĬĬ è¯Ŀ +羣çļĦ 太 +, æŃ¢æįŁ +-out line +ih anna +Ġsig m +çĭ¬ä¸ĢæĹł äºĮ +( iv +) ]) +. primary +he avy +ĠO LD +æĸ¹ èĥ½ +两 è½® +ev olution +Ġtechn o +çĥ§ æ¯ģ +Ġrust y +: false +f ashion +ĠI BD +con ies +çľĭ éĶĻ +é¥ ¨ +缸åħ³ æĶ¿çŃĸ +ĠAss assin +Comp rehensive +å°¾ çģ¯ +O ral +ĠC MP +ç»Ŀ æĿĢ +计åĪĴ åľ¨ +ĠMain taining +Ġmetabol ite +磾 æĮģ +ï¼Įä¹Ł 被 +æł¡ ä¼ģ +çļĦ好 åıĭ +ĠMON TH +F ILTER +Ġpre con +åįĬ æĪª +Ġsource Tree +_g enerate +åĶIJ éķ¿çĶŁ +çĵľ æŀľ +Ġinject or +Ġf umes +è¾ ĺ +éħĴ ä¸ļ +Ġprop elled +主æĮģ ä¼ļè®® +Ġinh aled +Ġparadig ms +é£Ł 管 +_h al +å¸ķ åħĭ +t os +ï¼Į æ±ŁåįĹ +马 é¾Ļ +b uck +ĠT FT +Int ensity +ĠSal isbury +ĠMand ela +j ew +Ġt arn +é¾Ļ èĪŁ +.n z +_L IN +æ¶Ĥ åĪ· +QU ARE +, < +ä¸į åĪ©çļĦ +ãĢģ è¿ŀ +Com poser +åį¡ åIJĪ +ĠMc Mahon +Ġlegal ized +.H tml +ĠInitial ization +Ġkö nnen +s now +ç½® ä¹ĭ +_EXT ENSION +Ġvene er +çļĦ éĢ»è¾ij +说 ä¸Ģ声 +åİ¿ å¸Ĥ +_D M +ĠØ Ń +Ġchunk y +ĠFab ulous +ï¼Į 转åĬ¨ +Ġaut of +Ġcoe ff +ï¼Įåįł åľ° +Dam n +( Stream +Ġcomm ons +ĠRad i +ĠInput s +ĠPred icate +_ph ys +( round +Ġ æŃ¥éª¤ +Ġ\ \\ +_b inding +Ġsl ang +çĽĹ çīĪ +(ch ip +ĠAl am +çģ« çº¿ +_M EDIA +èµ¢ åĪ© +年代 æľ« +R oche +ãĢģ äºĨè§£ +ãĢģ è§ĦåĪĴ +ĠH IM +_f ifo +ï¼ĮåĽłä¸º ä½ł +èģĶèµĽ çļĦ +ãĢĤ çݰæľī +ç§į 群 +Ġinf ra +ĠFR AME +è°ĥåij³ æĸĻ +T J +Ġal d +ib ur +çĽĹ å¢ĵ +Ġredirect s +Ġ 产 +èµ° çļĦæĹ¶åĢĻ +Ġlay offs +optim ization +ĠKl aus +, é¢ľèī² +æ°Ķ 缸 +Ġprim ed +prot ective +Ġmetaph ors +Different iate +èĮģ 壮 +M erry +Ĉ ãĢĤ +st aking +Ġfor all +sc ala +ç²ī 红èī² +ä»·æł¼ åľ¨ +Ġassess es +ĠLow est +æĻĥäºĨ æĻĥ +ĠD SC +Ġwh istles +Ġass hole +.d elta +çĭ¬ çĶŁ +ï¼ĮæĹł ä¸į +ĠHun ters +Ġbart ender +l us +ĠJ ules +Ġvoc ation +ï¼Į 顺åĪ© +ĠG urgaon +以 ä¸Ģ个 +éĢī ä¿® +æĽ¾ æľī +ĠPer forms +æıŃ示 äºĨ +ãĢģ éħ¸ +åı¯ ä»İ +Ġimpro b +ĠH AND +ere g +L v +ä¸Ń 线 +åĨį åĪ©ç͍ +åıĸ æĿIJ +lex ia +utt gart +åħ¨ ç¾İ +ik el +éĥ½æĺ¯ è¿Ļæł· +ç»Ļ大家 ä»ĭç»į +Ġj ab +éĿŀ 线æĢ§ +ren o +prop ylene +market ing +éĤ¢ åı° +B art +ç® ķ +Ġbooks helf +, size +æĬĺä¸į æī£ +人 åĵģ +çŃī åľ°çļĦ +Ġvac u +Ġg ala +Ġpe at +æĭ¼ åĽ¾ +ulum i +ĠStruct ured +ç¡Ŀ çĥŁ +ĠFest ivals +& W +åİ» éĹ® +,è¿Ļ 款 +æ³¥ é³ħ +Birth day +ä½ ļ +为 åIJį +ĠEng el +ĠAg ree +çıį åĵģ +Ġlatt ices +is ual +ĠB CS +ĠD eng +å½ Ĺ +çĶŁ è¾ī +èĢģ æ±ī +Ġgr p +_M B +æĢķ æĪij +çĤ¹ å¼Ģ +ä»ĸ们 æīĢ +å·¥ä½ľ 计åĪĴ +IT ING +å¤±æľĽ äºĨ +, æĶ¶ +æĹł ä»»ä½ķ +çĶļ å¤ļ +Ġice berg +说å¾Ĺ 好 +_ ft +ãĢģ å®¶éķ¿ +ĠF UNC +ub by +Ġev ils +Ġore gano +ĠJoh ann +/XML Schema +Ġt ous +çĹĽ ç»ı +éĹŃ çĽ® +Ġmid day +ãĢĤ ç¬ĶèĢħ +Ġap ical +é»Ħ åŁĶ +.P ort +èĻļ å½± +TE GR +á» ĥ +èϾ ä»ģ +.entry Set +Ġ å°ij +ĠE MI +ï¼ģ ï¼ģâĢĿ +å°Ķ èĴĻ +åįĩ èģĮ +Ġpret rial +è¿Ļæł·çļĦ ä¸Ģ个 +éĺ´ å¤© +ãĢĤ çī¹ +st asy +ĠE nerg +Cons umers +èĤ¾ çĤİ +D DR +ãĢĤ æľīåħ³ +ä¼ļ å¦Ĥä½ķ +第ä¸Ģ åŃ£ +Web Kit +ï¼Įä¸ŃåĽ½ çļĦ +amer on +ĠAd mit +Ġregist rar +ä¹Ļ äºĮéĨĩ +ï¼Ľ èĬ± +é¦ Ħ +Ġsign aled +åĩºæĿ¥ ä¹ĭåIJİ +鼨 åŃ£ +æı´ åĨĽ +.run ner +åĪº çľ¼ +-W orld +Ġ([ # +ĠS AC +Ġwork able +aw ns +ï¼Įä¸į 让 +En s +ĠAc ne +ĠEnc oder +Ġpoison ed +ĠPBX FileReference +c ra +ĠP arr +Ġseed ing +ï¼Į纵 çĦ¶ +O OM +ĠS PORT +IT TER +_c ategories +æĹ¢ è¦ģ +奶 çīĽ +âĹ ĩ +ç¥Ľ éϤ +ï¼Įå¹¶ä¸į 代表 +æĪªçĦ¶ ä¸įåIJĮçļĦ +åħ¬ åĭŁ +Ġprim aries +åĽºå®ļèµĦ产 æĬķèµĦ +ĠPl ates +_re verse +Since rely +_emb ed +-pr one +Harm ony +. lo +M yth +çļĦ åIJįç§° +ãĢĤ åĵĪ +ĠD iving +ä¼ļ å¾Ĺåΰ +ï¼Ł è¿ĺ +ï¼ģ ï¼ī +çľ¼ 线 +å®Ŀ çıł +( Resource +m oon +ĠTh ats +ĠFl ask +çļĦ çŃĸçķ¥ +con i +第 åįģäºĶ +æĸ¯ å·´ +ĠRef erral +ĠSpace X +num s +-disc iplinary +L ar +为 çĶŁ +éĤ ¬ +å¼ķ 线 +Ġnetwork ed +åĽ½åĨħ å¸Ĥåľº +Ġbureaucr atic +ï¼Į æľ« +åĽĽ æ°Ł +ï¼Įåį´ ä¸į +æ³ķåĽ½ 人 +.move To +ãĢģ åıĹ +轻轻 æĿ¾æĿ¾ +éĺ²æİ§ æİªæĸ½ +LED çģ¯ +Ġcate red +ll ll +è¿Ľè¡Į è¿ĩ +åĶ® è´§ +ĠRE SET +ãĢĤè¦ģ æĥ³ +ĠÅ ¼ +COD ING +on ucle +Ġre ordered +Ġdef ends +ĠAl ma +.is file +Ġrev ising +Ġroll back +åĦĴ åѦ +s ie +Ġimp etus +åĪ« çļĦåľ°æĸ¹ +Ġblot ting +ĠC AC +红 ç³ĸ +缸å½ĵ 大çļĦ +éĽĨä¸Ń äºİ +éĽĢ è·ĥ +M olecular +_l arge +Ġå¦Ĥæŀľ 说 +Ġf ountains +âĢľ æµ· +å¾Ĺ æĺ¯ +ãĢĤâĢĿ ï¼Ī +_F T +åįĥ å®¶ +éĥ¨åĪĨ åĨħ容 +Ġletter ing +D æīĵåį° +sc p +è¿İ æĺ¥ +å°ıé¾Ļ èϾ +ï¼Į 奴婢 +æ¯Ľ åĿ¯ +,è¿Ļ æĹ¶åĢĻ +太éĺ³ ç©´ +åıij çİ°åľ¨ +)) -> +ç§ij ç§ijéķ¿ +ĠCl ash +Ġrecess ed +ï¼Į æĦıæĢĿ +æĪĺ åħ¢åħ¢ +åĪ©æ¶¦ 表 +_CO UNTER +èĢĥ åĭ¤ +_h it +åħ¬éĩĮ å¤Ħ +Ġdictators hip +Ġh ci +_M UT +Sec rets +âĦĥ å·¦åı³ +Ge V +Where as +ï¼Į è¾¾åΰäºĨ +ãĢģ å¹´é¾Ħ +åĴĮ èīºæľ¯ +ä¹ĭ èĢħ +æĸĩ 稿 +å·²ç»ı è¾¾åΰäºĨ +.t imes +Ġaf loat +Ġknock s +aus age +ï¼Į éľ²åĩºäºĨ +âĢľ -âĢĿ +åĩł 天çļĦ +Ġident ically +çŃĶ åį· +ç»ĻäºĨ 她 +Ġc usp +çļĦ åĨ³å¿ĥ +ch os +ä½ł è¦ģæĺ¯ +() " +é«ĺ æ·± +Ġeas ement +人类 社ä¼ļ +åĤ» çľ¼äºĨ +-ref undable +ï¼ļ ç¾İåĽ½ +æĮ¡ é£İ +á» ij +Ġw atered +ĠG ow +ud ges +ç͵ è´¹ +ç´ł é¢ľ +çºł èijĽ +ĠRealt ors +åľ¨ ä»Ĭ天 +çīĪ åŀĭ +Set t +åµĮ å¥Ĺ +ĠæĿ¨ å¿Ĺè¿ľ +å°ı åħµ +头 åĦ¿ +è¿ij ä¸īå¹´ +CD F +~ ) +Ġt ainted +ĠO scill +ä¸ī éĥİ +ys er +çİ°åľ¨ åľ¨ +Ġsouth western +è¿ĺä¸į ç®Ĺ +H DR +ï¼ļ AI +Ġext rinsic +ä¹Łä¼ļ 被 +ic ile +ï¼Įä¸į æĸĻ +dam age +( pl +P ract +s umm +çļĦ åĩº +ass ociation +Ġvar n +hand lers +j our +è¿ © +Ġman power +åĨ· æ¸ħ +ILE S +C J +Ġo xy +ĠO U +ĠK ont +åĽł çĹħ +Ġchild ish +_M OV +æĶ¾åľ¨ ä¸Ģèµ· +Bad ge +ĠDest inations +çľĭ çĥŃéĹ¹ +.p resent +-f inals +P redict +_r q +é¢ľ åħŃ +ä½ĵèĤ² éĶ»çĤ¼ +åij¼ åı« +åıijè¾¾ çļĦ +ĠJen ner +åĨĢ å·ŀ += E +Ġth orn +osp heric +ãĢģæ°´ æ³¥ +æĮ¨ çĿĢ +applic able +Ġl ute +ĠC es +æľĪ å¤ľ +缴 èIJ¥ +-f ixed +AD MIN +ĠRot ate +åĪĨ è¿° +requ irement +Ġsw ine +ĠSC ARPA +Ġgrasp ing +ivari able +c ord +al chemy +å¿ĥ æľº +cl imate +ĠRN As +Ġhym n +o E +tt ps +èϽçĦ¶ æľī +åºĵ å°Ķ +深度 èŀįåIJĪ +WE LL +j abi +ä¸Ń 带 +å®ļ æĬķ +åħ¬åı¸ äºİ +éŨ éĿ¢ +.in v +转è¿ĩ身 æĿ¥ +ï¼ģ ä¸į +è·ĭ æ¶ī +çļĦ è¿Ľè¡Į +ĠAm ended +ĠEst imation +Ġl td +ä¹Łæĺ¯ æľĢ +ä¸ĵä¸ļ çĶŁäº§ +Ġlicense e +Column Name +好好 åŃ¦ä¹ł +ĠINT ENT +s nd +çļĦ æĸ°éĹ» +èĢģ åĵ¥ +IL ITIES +ĠFlor a +æįī æij¸ +èľ» èľĵ +A mp +åĬł ä»ĵ +èħ¹ åľ° +call er +oqu ine +( fig +( attrs +C atherine +_ define +Ġt ribut +çݰ å½¹ +天 宫 +çϽ è¡ĢçĹħ +ä¸ĸçķĮ ç»ıæµİ +温度 åĴĮ +Ġfill ings +Short ly +ĠHB V +Ġâľ ĵ +F isher +Ġdis dain +ï¼Įä¹Ł ç®Ĺ +æĬĢæľ¯ æ°´å¹³ +A sp +{ class +_d emo +åĪĩ 身 +_gener al +ï¼Į éĿŀ常çļĦ +Ġin securities +å¿ĥ æ³ķ +äºĶ æĮĩ +_S CREEN +鼷 ç¥ŀ +æīĢ ç§° +ĠIn box +èIJ½ èIJ½ +ï¼Įå°± è·Ł +ET C +ĠNon linear +åĽĽ åĪĨä¹ĭä¸Ģ +马 èµĽ +-t imes +éļĶ å¼Ģ +ĠSau vignon +L iv +çļĦ åĭĩæ°Ķ +iet ta +çīĽ è§Ĵ +åĺī å¹´åįİ +Side bar +Ġ åIJĮæł· +ï¼Į é¥®é£Ł +Ġshow down +ĠSh ores +abel le +Ġprevent able +é»ĺ 认为 +Ġpoly urethane +询 ä»· +è¾Ī åŃIJçļĦ +_res ume +Py Object +on ium +ï¼Į æ³ķéĻ¢ +ï¼Į è®°ä½ı +ä¸Ģ è¯Ń +ç±» çŃī +亲 çļĦ +åIJ« æ°´éĩı +ĠCON S +æ¯ķä¸ļ 论æĸĩ +æ·ĭ æ·ĭ +, åı¤ +ĠP OW +NotFound Error +ï¼Į å¾ĹçŁ¥ +ĠD olly +æ°´ åį° +ä¹IJ äºĨ +åįĬ 空 +T ruck +ï¼Į å¿«ä¹IJ +è¯ Ļ +pport unities +-c oding +伦 å¤ļ +çݰéĩij æµģåĩº +ĠTerrit ories +Ġreproduc ible +ĠR iot +ĠCo il +Ġcarp enter +Ġ èİ·å¾Ĺ +ĠE FFECT +ç²ī åºķ +没äºĭ çļĦ +, æ¯ıæĹ¥ +ãĢĤ éģĵ +ĠH Cl +ĠE aton +Âł åı¯ +)) + +Ġoste oarthritis +Da emon +æľ¬ 级 +equ ipment +èᝠæĢ§ +.ex pr +代çIJĨ æľºæŀĦ +( up +âĢľ ä¸Ģ个 +text width +'] = +欧 äºļ +H annah +× § +æĺ¯ä¸Ģ æĶ¯ +ĠS oda +ãĢģ èĭ¹æŀľ +Ġhum iliation +è̳ çݯ +Ġd ll +ãĢĤ çݩ家 +åıij çϽ +lin eno +ĠMont essori +appe ared +t et +ĠS outheastern +æľī è°ģ +ĠPan ic +. Op +f riendly +ĠS erved +_p df +Ch ronic +åį´ æĺ¯ä¸į +åŁºéĩij 财产 +æĬ± æĬ± +ĠER ISA +, æīįæĺ¯ +ve get +VER SE +Y K +ĠS SI +DIT ION +ά ν +, èIJ½å®ŀ +大 æĬĬ +æĹ¶ åıijçݰ +Ġmon archy +çĶŁæ´» äºĨ +çĭIJ èĩŃ +è¾± éªĤ +[ V +çīĩåĪ» ä¹ĭåIJİ +ĠMillenn ials +ä¸Ģ çĽĺ +åĢĻ è½¦ +åºĵ ä¸Ń +å¿ł åijĬ +åĪĨéħį çļĦ +幸è¿IJ çļĦ +ä¸Ģ æĬĸ +å°Ĩ è¿İæĿ¥ +éĢĢ å¸Ĥ +EC s +纵 æ·± +: table +åΰ å¦Ĥä»Ĭ +Ġent hal +åij³ è§ī +ĠÑ Ī +ï¼ĮèĢĮ ä¸įèĥ½ +NUM BER +ãĢĤ 羣æĺ¯ +åģļ åĩºæĿ¥çļĦ +Line No +ĠMP a +ãĢĤ ä¸ĸ +èĢ Ļ +æĪij èĩªå·±çļĦ +Ġch atted +BC D +Ġexplore rs +åľ¨æĪij éĿ¢åīį +Ġ åĪĨæŀIJ +Ġt ä +ä¸į 大äºİ +, å¾Ĺåΰ +åĴĮ ç»ıéªĮ +ä¸ŃåĽ½ ç§ijåѦéĻ¢ +åĪĽ æĦıçļĦ +æ¥ ¹ +è¶³ è½»éĩį +âĦĥ ãĢģ +. '' +ĠN ested +å°ı å¾®ä¼ģä¸ļ +å¤ĸ æİ¥ +æīĵ åĪĨ +An ime +æŃĮ é¢Ĥ +bf d +ĠSem in +æ±Ł åŁİ +Ġguess es +åºĶå±Ĭ æ¯ķä¸ļçĶŁ +ൠį +_ asset +p urchase +èᝠæķĪ +éĻĦ æľī +Reg ist +Ġreass ure +Ġ æħķ容 +âĢĿ ä¸ŃçļĦ +ĠN un +Ġfeed ers +Ġ( -- +æ³ ŀ +åIJİ åı¯ä»¥ +å¿ħ èĥľ +Ġphen yl +ä¸įåĬ¨ äºĨ +åħ»æ®ĸ æĪ· +exper imental +ĠIn clusive +æłĩ å®ļ +Ġexc itations +é¼ĵ åĬ¨ +åĩłä¹İ æīĢæľīçļĦ +Ġhippoc ampal +å¿Ĺ æĺİ +ĠApplic ant +工信 éĥ¨ +_ ETH +Ġsur ged +ĠMod al +èµı èĬ± +ãĢģæ°´ åĪ© +creat ing +S J +ï¼Į èµ°åĩº +缸 å¾ħ +è£ħ ä¸Ĭ +å·¥ä½ľ çݯå¢ĥ +è¿ĺæľī çĿĢ +By ID +ç§ĭ åįĥ +Author ized +ÅĽ ci +éĢłå°± äºĨ +.Global ization +Ġe clips +æĺ¯ éĩĩç͍ +pt uous +æĥħåĨµ åIJİ +éļĨ èµ· +Ġabund antly +æīĽ çĿĢ +ãĢģ èī² +æµij 身ä¸Ĭä¸ĭ +ĠBrew ers +ĠScre w +ĠK ne +éĿĴå¹´ 人 +æľīåĵªäºĽ åij¢ +ï¼Į æ²IJ +ï¼Į æłĩå¿ĹçĿĢ +æīĭ å¿ĥ +åħĪ åıij +Ġhair y +åѦåijĺ 们 +, 符åIJĪ +u gh +ãĢĤ æŁIJ +.C o +Ġant ics +IL I +Mass achusetts +F rozen +H omes +Ġ ä½ĵ +us ages +Ġpre term +åħĪ åīįçļĦ +Ġins anely +ä¸ģ åł¡ +ï¼Į åľ°çIJĥ +Ġbl inking +_T ime +(s ig +Read s +åįģåĪĨ éĩįè¦ģ +nes ia +m inton +ï¼Į åģľæŃ¢ +iv ores +Cont aining +ĠTr uman +cycl ing +å°± æĽ´åĬł +è·ij åĩº +un ce +ĠH ANDLE +çİĭ åħ¬ +struct ural +Be ans +Ġtreasure r +Ġunve il +èĪ Ģ +æĶ¯ æķĻ +Ġep is +å¡« 空 +çĭł å¿ĥ +Ġdepartment al +ch imp +âĢľ åĽ½å®¶ +.... " +åī¯ åİ¿éķ¿ +æĿ¥è¯´ 说 +çļĦæīĭ ä¸Ĭ +ĠNare ndra +æĽ¼ è°· +_ major +ï¼Į 稳å®ļ +ãĢģ æľīæľº +ĠD VR +åĴĮ 设计 +Ġup rising +ÃŃ c +d ynamics +Ġsp ying +ç»ıæµİ æŀĹæŀľ +-ne ck +罪éŃģ 祸é¦ĸ +- / +U a +ï¼Ł ä»İ +Ġover came +åĽŀ åĵį +Time Stamp +娶 äºĨ +Ġcontempl ation +Ġdistort ions +Ġ é¢Ħ计 +ch mod +old ed +w inter +âĢĿ éĹ®é¢ĺ +æİ¥ 踵 +ï¼Įä½Ĩ ä¸įèĥ½ +Ġrep lying +èµĦæºIJ 丰å¯Į +纲 é¢Ĩ +Ñģк ий +. endsWith +ĠC ME +ä¸į éĢĤåºĶ +un lock +ĠW TF +åīį æľŁçļĦ +äºĨä¸Ģ è¾Ĩ +寿 éĻ© +æīĢåľ¨ åŁİå¸Ĥ +Ġarchae ology +æĹł éĺ» +å¼ı åĴĮ +鼨 éľ² +ĠSecret ariat +Ġbust le +] n +ç³»ç»Ł åĮħæĭ¬ +åĨľ åºĦ +Ġacceler ates +çļĦç²¾ç¥ŀ åĴĮ +éĺ Ĥ +åĿ ¨ +Ġpopul ace +g ings +ill ions +No vel +Ġtrack ers +é¢Ĩ导 åĬĽ +_log o +f ell +ä¸ĸçķĮ 级 +æį¢ æ°Ķ +æ¾ ¹ +åı® å½ĵ +Ġmacroph age +ĠN SError +æĹħ éĢĶä¸Ń +-sc roll +L s +P roud +ĠC url +ost e +è¿Ļ个 æĸ¹æ³ķ +sub string +ä¸įä»ħ åľ¨ +æĺł 衬 +åĵģç§į çļĦ +飦 å°Ķ +_CONST ANT +< t +èĸĦ èĸĦçļĦ +ĠN SS +åĽ½ å®Ŀ +åĪĨ ä¸įæ¸ħ +å¹³ åºķ +(p arts +Ġactress es +, 羣çļĦæĺ¯ +ĠS ES +em m +å¡Ķ åħĭ +izz ie +ç½ij çĬ¶ +åij¨ æĹĭ +ï¼Įä¹Ł èĥ½å¤Ł +ĠRes ervations +ä¹° ä¹° +éĺ¿ å¼¥éĻĢä½Ľ +ĠCA ST +\ Contracts +ĠG ert +Ġj eg +è¶ħ 强çļĦ +æIJŃ ä¸Ĭ +ãĢį ãĢģãĢĮ +ä»Ķç»Ĩ åľ° +åı¸æ³ķ å±Ģ +åĩ¯å°Ķçī¹ äºº +æľī ä»·å̼çļĦ +å¦Ĥ é£İ +Ġstren uous +S v +ĠS utherland +å½ĵ è¿ĩ +bit rary +under stand +, èİ« +Ġd unk +-e lectric +éĵ² éϤ +åIJ ł +åĪ» 骨 +Al abama +æĻ® å°Ķ +çĭ¬ å¤Ħ +å¹³æĸ¹ç±³ çļĦ +- HT +at iva +ãĢģ ï¼Ī +ç«ĭ ä¸ļ +èŀ³ èŀĤ +, æĭ¿ +bro ker +Ġoutper forms +_b box +æĹłåħ³ ç´§è¦ģ +Jeff rey +æµ¦ä¸ľ æĸ°åĮº +ï¼Į ä¹ī +ä¸į æĹł +æĽ´ è¿ľ +åįģ ä¸īå¹´ +è¾Ľèĭ¦ èĭ¦ +d ims +Ġr ussian +åĽŀ æĹĭ +ĠCent ennial +å²ģ 以ä¸ĭçļĦ +ham pton +A ce +K athy +w olves +Ġper ched +ĠEx ceptions +Ġhot spots +æĵ¦ éϤ +ĠUI Kit +à® ¾ +, åıijæĮ¥ +Ġ åĩºçīĪ +æ¡ § +æĸ¯ åĴĮ +è¡£ åĨł +ï¼ĮçĦ¶åIJİ éĢļè¿ĩ +æ¶² 缸 +, æĪIJ +Ġ å®ŀä¾ĭ +ãĢģ æ³° +ä½ł åı¯èĥ½ +SC AN +ĠIsland ers +re i +è¾ĵ ç͵ +ç»Ļä½ł 带æĿ¥ +Ġtele metry +. Product +L iu +æĮī çĿĢ +伤 èĢħ +åı³ éĶ® +Ġbatch ing +ĠAtkins on +Ġel k +ï¼Įä¹Ł éľĢè¦ģ +Ġdry ness +ä¹łæĥ¯ äºİ +V oc +Ġc map +æľī èĩ´ +ĠL iga +Ġsc andals +Ġ. âĢĿ +Ġfl a +ĠPM ID +æ£Ĵ äºĨ +.âĢĻ âĢĿ +B anners +if olds +ĠF DR +.p oll +éĿĴ åħī +.g lyph +-se cret +æĺ¯æľĢ éĩįè¦ģçļĦ +ĠNull able +, 第 +B UT +Ö · +Ġ çIJĨ +è¦ģ å°ıå¿ĥ +éĿĻ é»ĺ +Ġclos eness +çģ¿ çģ¿ +or ov +ä¸Ģ 线çļĦ +æ°´ çĵ¶ +æĽ´ éľĢè¦ģ +é¥ ķ +_D LL +.R oot +èµ£ å·ŀ +_ User +ï¼Į çĪ·çĪ· +è¿ĺæľī 许å¤ļ +å§¥ çĪ· +ï¼Į æŃ£å¸¸ +Ġv k +ĠLib ra +导 è´Ń +è¿ĺæĺ¯ éľĢè¦ģ +ĠSp here +ç®Ģ çŁŃçļĦ +åºĶ该 çŁ¥éģĵ +èĹı 身 +Ïģ η +Ġåħ¶ä»ĸ åºĶæĶ¶æ¬¾ +ãĢģ é£ŀ +· éľį +å±ł é¾Ļ +æĤļ çĦ¶ +, åħįè´¹ +æľī åķ¥ +大 é¢Ŀ +å¸Ĥå§Ķ 常å§Ķ +è´§çī© è¿IJè¾ĵ +Ġfur the +ALYS IS +ĠR uff +ial ect +æµģ çĿĢ +Ġelect rom +Ġeth ylene +-ex clusive +èį¨ éº»çĸ¹ +is ks +ĠA ries +åĽŀ 京 +Ġtre ason +ĠBlack berry +- awaited +en ade +éϤ æ³ķ +Trans mission +Ġham per +ï¼Į éĽĨåĽ¢ +Ġun riv +ç§Ł æĪ· +å¿ł ä¹ī +Ġpart ing +å®£ä¼ł å·¥ä½ľ +ĠHon est +éļIJèĹı çļĦ +Ġg ee +Ġped igree +Ġgrass y +(pro file +_cm ds +Ġf eline +ä¸Ĭ çŃī +没 æĹ¶éĹ´ +Ġstud s +çħ§ ä¾ĭ +ĠO yster +_add ed +ĠTud or += config +åħ¶ 对 +ĠGu o +ĠGround s +计æıIJåĿıè´¦åĩĨå¤ĩ çļĦ +åıΠ以 +_n il +è£ħéħį å¼ı +Ġmuc us +æľįåĬ¡ åĮº +&& ( +comb ine +Ġpenn ies +CONCLUS ION +; height +[ scale +ãĢģ éĴ¢ +æĽ´ å°ij +æķ£ èIJ½ +æŁı æĭī +art i +Ġcomp ressive +éĢī åŀĭ +é£ŀ åĩºåİ» +ĠCo ch +Ġproof reading +Ġmanifest o +åij¨ çijľ +OM O +ç»ĵæŀĦ è°ĥæķ´ +ãĢģ åIJĪåIJĮ +åĨį èµ· +çĽij管 æľºæŀĦ +, éĥ½è¦ģ +Ġu mp +ç¼ĸ èijĹ +åħ¨åĽ½ æĢ§ +Âł ä¹Ķ +çŁ¥ è¶³ +å¼Ģå§ĭ å°± +æĬķèµĦ æ´»åĬ¨ +Config urations +Ġbi otech +ĠWell being +ï¼Įåıªæľī åľ¨ +æĥ¨ éģŃ +ĠNik ol +åĸĦ æĽ° +ĠWood ward +; åľ¨ +èIJ½ æĹ¥ +ç¯ ĵ +ĠDur ant +ĠM ek +(s ystem +çİī åĦ¿ +æ´Ĺ äºĨ +ĠAcc um +èįĴ åĩī +ï¼Įä¸įä»ħ æĺ¯ +Ġlin ens +ãĢĤ å¸Ŀ +å½ĵ åĽŀäºĭ +å¯Į äºĮ代 +çĨŁç»ĥ æİĮæı¡ +@ f +å®īåħ¨ ä¿Ŀéļľ +(\ \ +ï¼Įä¸Ķ 使 +ĠContract ing +, éϤéĿŀ +.S H +群 éĽĦ +Ġbrown ed +ĠColl ar +æ°¯ ä¹Ļçĥ¯ +åĽŀçŃĶéĹ®é¢ĺ æĹ¶ +T Z +Ġpl edges +åľ° é»Ħ +F IRST +Âł G +åı¯ä»¥ éģ¿åħį +å·²ç»ı è¿ĩåİ» +ĠHum or +åĪĨæ³Į çī© +ä¸į èĢĥèĻij +çľĭ æĩĤ +åı£ å¤Ħ +_p ci +çİ°åľ¨ æĪij +.f eed +ãĢĤå½ĵ ä¸ĭ +èĭį èĢģ +æľ¬ç§ij ä¸ĵä¸ļ +nas ium +.getElementsBy TagName +[ col +id ay +人士 çļĦ +Ġinterpol ate +赡 åħ» +_m ouse +Ġrefriger ators +A ura +ors ch +m aterials +ï¼Į èģļçĦ¦ +ãĢĤ éĴ± +igh am +Ġbl urry +ĠSc enes +ĠPOS IX +Ġredd ish +ĠW eld +ĠSuccess fully +R PG +æµģ ç»ı +ä¸į 饶 +ĠK ear +åĽŃ åĨħ +object ive +T ITLE +)) = +ĠAc rylic +æİĪæĿĥ çļĦ +çļ±èµ· çľī头 +he i +ä»ĸ 身边 +åį´ èĥ½ +è¶Ĭ èµ° +-p review +æĬķèµĦ 管çIJĨ +MS M +ï¼Į 计 +ĠW ATER +ĠScal ing +Ġdealership s +, åħī +- liked +/ type +ë ¶ +Ġ é±¼ +ãĢģ 身份è¯ģ +ĠK DE +Ġover power +åĬŁ äºİ +åħŃ è§Ĵ +ãĢĤåľ¨ ä¸ŃåĽ½ +åħ« è§Ĵ +å¥Ĺ åĪ© +Ġvir ulence +Ġ æ¯ĶèµĽ +ĠD imit +æĺ¯ä¸Ģ 段 +éĢĢ åİ» +æĻĵ çϽ +æį£ ä¹± +åľ¨ 身åIJİ +è¿Ļ ä¼ļ +ĠDe S +åħĭæľį äºĨ +ĠR ican +ä»ĸ们 æĿ¥è¯´ +sv n +( State +ï¼Į 竹 +æĽ´ å®īåħ¨ +Ġ åĮº +éĺµ ä¸Ń +éĿ¢ç§¯ 约 +çĹħæ¯Ĵ æĦŁæŁĵ +H ollywood +R ST +ç»Ŀ å¢ĥ +ç§ijåѦ家 们 +åĽ½åºĨ èĬĤ +ĠN OV +åѦ åIJį +æŃ¥è¡Į è¡Ĺ +åIJ¬åıĸ äºĨ +ĠK ri +æ°´ 壶 +åıĤ æĪĺ +-l ast +Ġground work +å¿ĥéĩĮ éĿ¢ +Ġgran ules +ĠF ink +IST RY +Âł C +Ġcommun ism +(p assword +åīij çļĦ +æ´ģ çϽçļĦ +ä¹Łä¸įæĺ¯ ä»Ģä¹Ī +Sam uel +ï¼Įä¸į å°±æĺ¯ +m j +鸡 ç¿ħ +çĮ® çŃĸ +Ġrandom ised +.pre vious +ert ia +ä»İ åħ¶ +bb en +ç½Ĺ马 å°¼äºļ +ĠDol by +æijĩæĻĥ æĻĥ +it izer +ĠD odd +ï¼ļ ä¸Ĭæµ· +ä¿¡æģ¯ åıijå¸ĥ +ç°ĩ æĭ¥ +- åĪĨ +çļĦ åŃIJ +ÑĢ Ñĭ +æĬ¹ åİ» +åĽ½éĺ² éĥ¨ +-auth ored +Ġin se +ï¼Ł åĪ« +æĹł åĬ¨äºİè¡· +éĩį ä¿® +éĺ² æ´ª +çĽij åζ +ç»ıèIJ¥ 许åı¯è¯ģ +åľ°çľĭçĿĢ å¥¹ +am t +ï¼Ł ä»Ģä¹Ī +ar ize +Ġcru iser +为ä½ķ è¦ģ +_RG BA +Ġw ilt +ous and +è¿Ļ个 åŃ©åŃIJ +ĠMc Call +ĠFlu or +ãĢģ åĵģè´¨ +ï¼Į èģĬ +åħ¨ åŁİ +ï¼ĮæĪij 羣 +_D AY +ĠSic ily +åķĨ å®¶çļĦ +Ġalarm ed +ĠUtil izing +stud ents +è¿Ļ ä¸į +çĤ® çģ« +\| ^ +\ !\ +Ġcommun icative +IS R +èĹı æĹı +ĠTool box +Ġdepos iting +åѤçĭ¬ çļĦ +ï¼Į å̾ +ĠR utherford +ĠL enders +ĠO bit +æĽ´ ä½ķåĨµ +Ġpass er +ĠTo e +Ġfaith fulness +çļĦ天 æīį +ä¸Ģ大 æī¹ +æĭŃ çĽ® +Fin ite +ĠWhit man +å¦ĩ产 ç§ij +- webkit +en k +çĶŁæĢģ æĸĩæĺİ +Ġcm ds +宫 主 +使åij½ æĦŁ +Ġupset ting +çļĦåıĮ éĩį +v ous +ï¼Į æŁIJäºĽ +è´ ² +æ¸ħ éĿĻ +鼷 鼨 +é¢ij 段 +Ġpsychiat ry +educt ible +äºij 轩 +Ġret ries +Ġä¸ī 人 +Ġbird ing +H arris +å¼Ģ èĥĥ +.p attern +å·¥åħ· çļĦ +ĠS IN +ï¼Įä¸į 说 +æī¶ èµ· +缸æ¯Ķ ä¹ĭä¸ĭ +ä¸Ńä»ĭ æľºæŀĦ +è¾ĵåįµ ç®¡ +ĠF OUR +ĠH OL +.M ulti +ĠS ailing +èĮħåı° éħĴ +T REE +ï¼ī åıĤä¸İ +çα æħķ +çĽĪ è¢ĸ +ç²® æ¶² +éĢĨ æµģ +第åħŃ å±Ĭ +T enn +Ġ ç´§æİ¥çĿĢ +Ġb ends +Ġpre clinical +Ġhyp ogly +ĠD aly +æĪij åİ¿ +éļ ¼ +çīĪ åĽ¾ +çĶŁäº§ è¿ĩç¨ĭ +ï¼Į缴æİ¥ å°Ĩ +éŃħ æĹı +çļĦç¾İ åij³ +clean up +Ġmans laughter +èµ° 强 +èģĶ éĺŁ +Ġ, " +Ġcharg ers +伯 åĪ©äºļ +è¯Ŀ说 åĽŀæĿ¥ +缸åħ³éĥ¨éŨ æī¹åĩĨ +Ġpued e += sub +ĠL up +ĠJ as +rove ment +IT C +èĵĿ æµ· +Ġ æŁ¥è¯¢ +al ah +ir u +é¢ ī +马 è¶ħ +.st roke +Ġbul ge +_load ed +ç«ŀæĬĢ åľº +_symbol s +ĠDaven port +ï¼Į å¯Ĩ +æŃ£è§Ħ åĮ»éĻ¢ +ĠBot ox +Ġlever ages +.Dec ode +ĠRead ings +ĠDun geon +æĸ¹åºĶ çī© +. reference +ĠA UDIO +_s upp +带 ä»ĸ +临åºĬ åĮ»åѦ +è¿Ľåı£ çļĦ +Ġunderm ined +å·¥åķĨè¡ĮæĶ¿ 管çIJĨå±Ģ +b st +Ġ èĪĴ +Ġ çīĪæľ¬ +æĮī æıŃ +èĭ¥ çݰ +Ġredu cer +è´¢ åĽ¢ +æĿ¾ å¼ĢäºĨ +Ġintellig ently +Y R +Y ay +e lected +r outes +Ġ 度 +ãĢģ å¼Ĥ +Ġ' ~ +ĠAl mond +çİ°åľ¨ æĪij们 +ĠMar i +_ Input +ĠP encil +Ġåľ¨ è¿Ļ个 +为主 导 +å®´ 请 +/ group +\ exp +Ã Ģ +追 æŁ¥ +人æ°ijæ£Ģå¯ŁéĻ¢ æĮĩæİ§ +ĠÙģ ÙĬ +^ / +ĠI ke +Ġall uring +å¾Ĺ åĬĽ +æľĪ èī² +èĦ± æ¯Ľ +殿 ä¸Ń +S eb +ĠInv ite +ĠVir go +åĵĪä½Ľ 大åѦ +æľ¨ å·¥ +æģ¶ ä½ľ +Layout Manager +Ġforc ibly +im in +ãĢģ ä¿¡ +å®īåħ¨ éĺ²æĬ¤ +å¸ĥç½® çļĦ +Ġconspic uous +, çĿĢåĬĽ +y brid +ï¼Į 羣å®ŀ +ï¼Įè¿Ļ è¾¹ +é£ŀ èµ· +Ġdisplay Name +ĠPL AYER +åIJ± åIJ± +} n +ĠP ools +ud ging +itt sburgh +-in cludes +çİī é¾Ļ +æ»ij ç§» +ny a +ĠâĨ IJ +. book +代 æķ° +ç»´ åIJ¾å°Ķ +ãĢĤ æĶ¯æĮģ +pe ating +Ġdev iate +_DE CODER +/g it +çģ¼ çĥŃ +åĪĨ æĭ£ +Ġra cc +éĽª çϽçļĦ +ĠVal le +Ġcasual ty +æīİå®ŀ æİ¨è¿Ľ +å·² è¾¾åΰ +亦 ä¹IJ +æīĵå¼Ģ éŨ +æ¶ĪåĮĸ åIJ¸æĶ¶ +. tencent +T itles +主è¦ģ è´Łè´£äºº +Ġhum bled +pl in +æĪijçļĦ æľĭåıĭ +Jo el +æ³ķ å¼ı +Ġemb arking +Ġsoft ness +L Q +GR P +Bring ing +ur istics +举 ç«Ļ +Ġru ining +为 åѦçĶŁ +该 æľīçļĦ +å¿Ļ æ´» +. thread +ab cd +âĢľ åѦ +éķ¿ æ²³ +æįŁ æ¯ģ +æģŃ ç»´ +Bed room +, 累计 +æĿ¥ åıĤåĬł +ï¼Ľ ä¸į +åįģ ä¸Ģå¹´ +è§ģ 鬼 +With Error +ï¼Į对 她 +é£İéĻ© è¯Ħä¼° +çĵ¶ ä¸Ń +éĢĨ è¡Į +ĠD are +ĠF ringe +ĠL isp +å¿« æ´» +Ab d +为 åŃ©åŃIJ +ï¼ļâĢľ â̦â̦ +ï¼ĮæīĢ以 ä½ł +Trans ient +NS MutableArray +ĠWord press +çĽĨ èħĶ +ĠEXP ER +Ġunquestion ably +m ort +带 åĽŀå®¶ +CT R +char acters +è¿Ľä¸ĢæŃ¥ å®ĮåĸĦ +éĥ½æľī æīĢ +夺 缮 +ĠPR ICE +Ġlymph atic +ä¸į è¡° +ĠP IP +Ind oor +åĪĨ æī¹ +建 åĬŁ +-T ech +ç͵ç£ģ æ³¢ +; p +éĶĻ è¿ĩçļĦ +å²ģ æķ° +麻çĥ¦ çļĦ +Ġpedag ogical +Ġ éĽħ +å¹´ å¤ļ +_count ry +Ġh anger +ãĢģ é½IJ +Ġun ivariate +åºĶ ä¸İ +èIJ½ èĬ± +éĽª èĮĦ +Ġretriev es +: Number +ãĢģ å®ĹæķĻ +ĠN ish +èĩª é¦ĸ +_D C +W ash +æīĢ å¤§åѦ +Ġfl irting +èIJ½ å¾Ĺ +é»ij æĿ¿ +乡 éĩĮ +Div ider +- that +ĠSE ARCH +æķĻ åijĺ +ï¼ĮèĢĮ æĪij们 +èĥ¶ ä½ĵ +ï¼ĮèϽçĦ¶ 没æľī +Ġoxid ized +åĭĩæķ¢ çļĦ +ĠK illed +-b orne +è®°èĢħ ä»İ +å§Ķåijĺä¼ļ çļĦ +èħ» åŃIJ +Mean ing +, ãĢĮ +ist ribution +è´¢ ä¼ļ +çľĭçĿĢ éĤ£ +æ¯Ľ éĴ± +urb ation +ï¼Į æļĤ +IN TEGER +å·¦ ä¸Ĭ +è¡į çĶŁçī© +( ne +F tdc +)) ), +Ġet iology +Ġe greg +åĭIJ åħ½ +ï¼Į 缸å½ĵ +ch allenge +ant t +æĹ¥ ä¸ŃåįĪ +ĠAT L +Ġkin ases +ĠJ our +éĴ £ +ç§ij 大 +_S UR +ĠSome body +Ġ åĩł +ä½ł ä¸Ģ个 +å¤ļ æĸ¹éĿ¢ +éķ¿ ä¹ħçļĦ +-c opy +Ġdiscrim inator +ĠSchrö dinger +ï¼Į她 æĥ³ +Ġste aming +å§ĭç»Ī ä¿ĿæĮģ +ĠV oters +å§Ķ æ´¾ +沿 ç͍ +åĵªéĩĮ æĿ¥çļĦ +åIJĮä¸Ģ æĹ¶éĹ´ +ï¼ĮåĢĴ åħ¥ +Ġtr unks +æĬĬ æīĢæľīçļĦ +ç²¾ åħµ +e ine +on et +ï¼Į è¯ı +å¸Ĥ ä¸Ń +å«ģ æİ¥ +Ġfro ze +个 èµĽåŃ£ +Ġlib s +Ġlif etimes +-pro fits +ĠProt ector +/ Data +ä¸Ĭ åĩł +è·Ł åĪ«äºº +åķĨä¸ļ ç§ĺå¯Ĩ +è®°å½ķ äºĨ +个 æĿijæ°ijå°ıç»Ħ +ä»İ éĩĮéĿ¢ +æīĵ æĿ¥çļĦ +çϽ åĨħéļľ +åĩºä¸Ģ åı£ +ĠDeb ra +ĠHind us +ĠC MB +ä¿¡ ä¸Ń +_S LEEP +åŃ¦ä¹ł èĥ½åĬĽ +See king +f j +Ġ éĩįéĩı +ãĢĤ æīĢæľīçļĦ +车 åĴĮ +(t xt +å¤ı å¨ģ夷 +Ġmel tdown +Ġreprodu cing +ĠST S +. adapter +ä½ł å°ıåŃIJ +å¹³ ç¼ĵ +Ġlog its +Ġq p +åĽŀæĿ¥ çļĦæĹ¶åĢĻ +Typ ical +Ġtq dm +ï¼Į æĭĸ +ĠS ITE +åŃĺåľ¨ äºĨ +ĠArch ie +Ġfract al +-f lag +Ġemp ath +å¥ĩ è§Ĥ +ĠIncre ases +Ġvene ers +ï¼Į æĶ¿æ²» +æīĢ åĬ¨ +ä»ĸ们 没æľī +ĠNull PointerException +ĠF iling +æİ¨èįIJ éĺħ读 +it cher +Ġnorm als +èįīåİŁ ä¸Ĭ +ĠStra uss +Liver pool +ãĢĤ ãĢı +ist ream +头 é¢Ĩ +å·¥ä½ľ æĥħåĨµ +åºľ ä¸Ĭ +Ġlockdown s +R c +Ġt iring +Long itude +Ġbread s +ĠMo j +ĠDifferent iate +Ġharass ed +mbuds man +ĠCart ier +N v +对 ä»ĸ们çļĦ +天 å®Ŀ +éĵģ çŁ¿çŁ³ +(n ormal +西åĮĹ éĥ¨ +< X +ãĢĤ çĥŃ +ach able +åĨĽ å§Ķ +ĠHttp Client +Ġunb earable +ĠM IP +Ġun lucky +}$ ï¼Į +left arrow +溪 æµģ +hand les +ĠLock s +ic ure +md b +ç¾İ好 çĶŁæ´» +Unexpected EOF +Ġ æŃ¤æ¬¡ +ãĢĤ æīĵ +çŃī ä¸įåIJĮ +使 ä½ł +è§ģ éĹ» +åħĭ æĺŁ +æ±Ł å®ģ +éº Ŀ +å¨ģ åİĭ +API ENTRY +-gener ator +Ġvivid ly +s queeze +Ġ ä¿ĿæĮģ +ï¼Į 宣å¸ĥ +ãĢģ èµ· +lo in +ere m +ĠÎ ļ +è½® èι +åľ¨ä¸Ģ çīĩ +å¨ĩ å¨ĩ +ent anyl +è¿Ľè¡Į å®£ä¼ł +èĤ¡ä¸ľ 大 +contin ent +_ ENTER +d eps + ª +Ġde letions +æľ¯ çļĦ +Object Id +åı¹æģ¯ ä¸Ģ声 +Ġen closing +Ġup he +éķ¿ çĿĢ +çĽĪ äºı +æĺ ĩ +æĢ»é¢Ŀ çļĦ +èIJ¤ çģ« +L ens +Ġal imony +âĢľ æĿ¥æºIJ +ï¼ļ éĩĩç͍ +æ¡Į åīį +åIJĵ åĿıäºĨ +} ") +Ġ èµ° +Ġgerm any +ĠLug gage +$ ]{} +Ġo lf +æĺ¯ 两 +Ġcom et +没 è§ģ +By Type +ï¼Įè¿ĺæľī å¾Īå¤ļ +æĭľ çĻ» +ãĢģ æ¾³å¤§åĪ©äºļ +un istd +ĠComm iss +path y +Ġcit rate +Ġneglect ing +ĠENABLE D +ĠK ahn +æ¯Ķ åĪĴ +âĢĶ he +ï¼Įæĺ¯ çļĦ +.l at +ĠAst ro +a çļĦ +ï¼Į å²³ +Ġch akra +åıijå±ķ éĺ¶æ®µ +.read er +Ġk ans +class ic +ĠSun ni +ï¼ĮåĨį 度 +ä¼ijæģ¯ 室 +Ġ 代çłģ +ãĢģ æĸĩåѦ +满 缮 +Ġscal ars +r ils +Ġj uggling +.get Boolean +Ġexempl ified +à ĵ +.m ail +Ġpalp able +Ġ åįģä¸Ģ +_T RI +(m esh +çĪĨ æ£ļ +Ġcandid acy +ICE F +( use +as ms +èĢģ åĽĽ +çα æĦı +éĢĴ åĩı +ĠCond itioner +ç»° åı· +æľº ä¸Ń +æŃ» åľ° +Ġlam inated +sp aces +æķĪ åĬ³ +åĨĻ ä½ľä¸ļ +æĬķèµĦ åħ¬åı¸ +éŃĶ å¤´ +Ġcaut ioned +U ber +大 åĴĸ +Ġnot ifying +åħĭ æ´Ľ +So ap +ĠLik ely +æķ°éĩı åĴĮ +- region +Ġ å°ijå¹´ +ĠT CR +_c urr +ä¹ĭä¸Ģ æĺ¯ +"=> " +> public +èĬ± æĿ¿ +æķĻèĤ² åŁºåľ° +è´¢åĬ¡ æķ°æį® +æħİ éĩįçļĦ +.In variant +Ġtrunc ation +I b +re ceiver +ĠC IF +Ġ( -> +Ġres urgence +ĠÎ ij +Organ izations +ĠNewton soft +cccc cccc +. team +çĬ¹è±« ä¸įåĨ³ +ĠImm une +Ġcatar act +大 æľ¬èIJ¥ +Ġdis ple +comp ared +U å½¢ +ĠK eeper +åı¯ä»¥ 满足 +è¦Ĩ çģŃ +çİĽ çijĻ +ï¼ĮæĽ¾ ä»» +, å±ħçĦ¶ +ĠR ename +.d irection +can onical +Ġmel od +.back end +Ġf iance +Ġl ads +IV AL +fr anch +c our +ï¼Į æĹĭ转 +åįķ äºİ +Mark up +ĠSIGN AL +. INSTANCE +ĠS ensors +æľĢ åħĪè¿ĽçļĦ +DE T +-l ab +Mar shall +ä¾Ŀæ³ķ é¡»ç»ı +CHED ULE +æ¸ ¥ +åIJij æīĢè¿° +è¿Ļ个 游æĪı +åį° æŁĵ +èµ¶ åĽŀ +ĠBeck ham +alam us +ï¼Į èµ¢å¾Ĺ +å¹´ 满 +Ġlact ose +Ġpreponder ance +_ restore +ery l +ĠLe opard +ĠHis pan +ü l +Ge org +约çij٠夫 +/ trans +æľī å¾Īå¤ļ人 +è¿Ľ æĿij +ĠCook er +ĠObs ervations +à±į à° +T ennessee +èıľ åĪĢ +ĠMag istrate +ĠBrown ian +Non ce +æ°® åĮĸ +æ¥Ķ å½¢ +çĸ ¸ +To Many +ĠMy ths +缮çļĦ çļĦ +ä¸ģ é¦Ļ +ĠRob ust +× ¤ +ĠG ior +åĨ¥ çİĭ +ï¼ĮåıįèĢĮ æĺ¯ +, 严 +Ġ ith +æ°´ é¾Ļ头 +une i +åħ·æľī 以ä¸ĭ +Ġadj acency +Miss ouri +, çΏçΏ +: ? +L atch +S ter +Ġtrans mits +示èĮĥ åŁºåľ° +磮 人 +ĠStev ie +Ġst ink +ĠM OST +以 è½» +ĠZ odiac +Data Size +ĠFort nite +Ġ 没éĶĻ +çħ ħ +ĠEn ch +åĵĩ åĵĩ +E lev +ï¼Įå°± èĥ½å¤Ł +. recv +çĿĢ èħ° +ĠAb ortion +specific ally +( IP +. Change +{ id +qu i +ĠL TC +_w p +代表 éĺŁ +çν çļĦ +-cent ral +imon ial +ĠD olphin +Ġsp ies +åºķ çīĮ +ä¸ī è·¯ +çī¹ åĬ¡ +(m ember +çķª ç¦º +Ġsmart est +_ref resh +榻 ä¸Ĭ +girl s ++ "/ +[ G +çĶŁ æĿ¥ +éĥ ´ +æŀĹ èĤ¯ +itch ie +åĥµ å±Ģ +ĠPoly ester +Ġret ic +_re peat +ĠBi har +åľ¨æľ¬ å®ŀæĸ½ä¾ĭä¸Ń +æ°´ æ·± +è¿ľ å±± +ãĢģé«ĺ éĢŁ +Sm oke +ä¸İ çłĶç©¶ +å®ī åºĨ +ãĢĤ 大éĥ¨åĪĨ +ev ed +.S eries +_V IS +ĠAD P +女åŃ© çļĦ +对 èģĶ +init is +ĠCar a +å®¶åįıä¼ļ ä¼ļåijĺ +, åIJİéĿ¢ +ï¼Į èѦæĸ¹ +ä½ ĥ +ä¼ĺç§Ģ 人æīį +Re ality +æķĻåѦ æĸ¹æ³ķ +Ġaccommod ated +-point s +( JS +R IS +ä¸Ń ä»»ä¸Ģ项æīĢè¿°çļĦ +ĠRe union +éĵ¶ éĴĪ +ĠAc robat +ĠHar rington +é IJ +iz u +æĶ¶ å°¾ +ä¸įä¼ļ çļĦ +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠ +Success fully +Ġ é»ĺ认 +çľĭåΰ èĩªå·± +_V M +ĠMechan ism +ed ish +ic in +ãĢĤ æ¥ļ +ĠS MA +Ġsp ruce +-g raph +ĠReg ist +åĸĬ äºĨä¸Ģ声 +Ġdermat itis +ä¸Ń çļĦ人 +con j +å¿ĥ æľī +é¡¶ å¤ļ +ĠTHE M +ä¹Łè®¸ ä¼ļ +ĠShel ton +æķĻå¸ĪèµĦæł¼ è¯ģ +L yn +\ User +äºĮ åıĶ +éĶĻ ç»¼ +ï¼Į她 è¿ĺæĺ¯ +L ikes +P f +ãĢĤ æĺĵ +æīĢ åIJ¸å¼ķ +天 æľº +ä¸Ģ个 ä¸Ģ个 +èĶļ èĵĿ +åħĭç½Ĺ åľ°äºļ +ĠW OM +ĠRes urrection +å¢ĥ éģĩ +B ALL +åľ° å°± +çͱ å¾Ĺ +_s hell +.m m +åĸĺ ä¸įè¿ĩæ°Ķ +ĠK lo +yn aptic +Fire fox +ĠNewsp apers +ä½ı ä»ĸçļĦ +ĠÎ ¨ +Ġsquare ly +讨论 äºĨ +ï¼ĮåıĹ åΰäºĨ +C ities +æĪij 好 +ç´¯ çļĦ +èļ ¯ +åīį æİĴ +_s leep +ï¼Įä¸Ģ åŃĹ +á c +ãĢģ åªĴä½ĵ +æĪij ä¹ĭåīį +ass ment +ç»§ç»Ń éģĵ +Ġspect ator +[ Test +Ġ å¼Ģåıij +ç͍ æĹ¶ +,åħ¶ ä½Ļ +ĠJacob ian +Ġcyst s +F ellow +h q +ï¼Į 认è¯Ĩ +åºĶ该 çļĦ +.add Widget +Fac et +大 ä¸ī +表 çİĩ +æĵįä½ľ æĢ§ +.B ottom +A thlet +\ footnote +ar ized +ĠO MG +å¾Ī åı¯èĥ½ä¼ļ +Ġshrink age +-b efore +Mem o +ãĢĤåħ¨ 书 +ä¸ŃåĮ»èᝠ大åѦ +ĠZel da +ĠiP ads +Ġtrans itive +_P K +士 大夫 +æĭį æīĭ +ĠPre heat +çļĦåıijå±ķ è¶ĭåĬ¿ +ï¼Į æĦıæĢĿæĺ¯ +ĠAn and +'] ] +Ġcharacter izes +ï¼Į ç»ĥ +ä¸Ģ 毫 +(n ums +éĹª åĬ¨ +. & +" testing +B ull +ï¼Į çͳ +ess aging +ĠD ressing +ä¸İ å®ŀè·µ +å¹² ç»ĥ +管çIJĨ å¹³åı° +ä»ħ åľ¨ +æ³¢ åĬ¨çļĦ +çĤ¼ éĩij +b road +re asing +ãĢģ è¡Į为 +æĽ´ æ·±åħ¥ +æł¹ æ·± +åĬ© æķĻ +C ultural +Type Enum +.C hat +ä¸įæĥ³ 让 +æĥ¨ åı«å£° +åĭ¾ å½ĵ +çļĦçĥŃ éŨ +ï¼Į 温æŁĶ +è¿IJ åΰ +å¤į çĽĺ +OD S +ç¨İ åīį +Ġbackpack s +Le ague +éĢļéģĵ çļĦ +ä»ħä»ħ åıªæĺ¯ +ç»· ç´§ +Ġtroll s +( section +Ġpre amble +åIJĮæ¯Ķ ä¸ĭéĻį +ï¼Įä¸įæĸŃ çļĦ +篮çIJĥ åľº +Ġ çݯå¢ĥ +åij¨ åIJij +éĢĢ è·¯ +лÑİ Ñĩ +ï¼Į éĢĤå½ĵ +çĶľ ç¾İçļĦ +ĠMicro biology +Mad ison +f ried +Authent icated +æīĭ 头 +_com pute +Ġ 临 +å¥ĸ 竳 +ä¾Ľ 大家 +åįĩ èħ¾ +ä¹ħ èĢĮä¹ħä¹ĭ +âľ ĵ +æķ´ä¸ªäºº éĥ½ +omencl ature +ãĢģ æĢ§ +ãĢģ æ²Ī +-m etal +Arg entina +case cmp +管éģĵ çļĦ +\ Support +é£İ è¡£ +å¡« 满 +Ġreson ances +Ġdischarg es +å¾®ä¸įè¶³ éģĵ +以 èĩ³ +è¿Ľè¡Į è°ĥæŁ¥ +ĠRev is +ä¸įèĥľ æķ° +eni ably +" os +( DB +. Uri +ï¼Į E +ãĢĭ è¦ģæ±Ĥ +åįİ ç¤¾ +stra ctions +åĸ³ åĸ³ +éķ IJ +项 å·¥ä½ľ +é£ŀ é©° +ï¼ĮæĢ» è§īå¾Ĺ +ĠInv itational +建éĢł çļĦ +ĠL ESS +Ġpe asant +èĢĥ ç©¶ +æĤĶ æģ¨ +ĠRo oney +Ġpanc ake +ç¯Ĩ åĪ» +ĠDix ie +éĺ² çģ¾ +缸åħ³ éĹ®é¢ĺ +(c ategory +Thought s +he er +æģ© æł¼æĸ¯ +Ġaf ternoons +åĨĴ çĬ¯ +çļĦä¸ĭ åľº +Ġ 两个人 +ĠF ILTER +ä¸ĭ è¿Ľè¡Į +Ch orus +Ġgrand e +Ġwave let +ï¼Įè½» 声 +, æ²»çĸĹ +ï¼Ł éĤ£ä¹Ī +ï¼Įä»ĸ çªģçĦ¶ +Al gebra +é¦Ļ æ§Ł +æ²¥ å¹² +od in +ï¼Įåħ¶å®ŀ æĺ¯ +s port +types cript +Ġa ussi +ï¼Į 询éĹ® +int el +ush a +POP ULAR +PFN GL +å¦Ĥ å½Ĵ +缴 缴 +Ġtrans planted +SE TS +åĽ´ åī¿ +çªŁ 窿 +åĪ« èĩ´ +ç´§ æī£ +ä¸Ģ缴 èĩ´åĬĽäºİ +Ġpun ishing +è¾¾æĪIJ ä¸Ģèĩ´ +é«ĺ é¢Ŀ +ĠMult iply +, æī¾åΰ +ãĢģ 对äºİ +èĢĮ éĢłæĪIJ +çIJĨ ä»ĸ +èĬ ¡ +å¿« æīĭ +åij½ åIJįçļĦ +func s +æĪ·å¤ĸ æ´»åĬ¨ +Ġber th +C p +Ġde ze +ach al +çª Ī +é¢ij 次 +ĠCampaign s +Ġelong ation +ĠF ruits +第äºĮ éĺ¶æ®µ +äºĴèģĶç½ij çļĦ +ĠScor pio +ï¼Įè¿Ļ åĩłå¤© +åΤ å®ĺ +ĠCR ISPR +æł½ æ¤į ++ ---------------- +åľ¨ å¸Ĥåľºä¸Ĭ +åīį äºĶ +ĠS EEK +å°Ĩ ä¹ĭ +Ġsol vers +éĥ¨éŨ åĴĮ +çĶĺ æĦ¿ +ĠTrust s +éĴī éĴī +' Connor +ĠP c +ãĢģ 京 +ï¼Ī ç®ĬæĻ®éĢļåIJĪä¼Ļ +è¿Ļ个 åĽ½å®¶ +ather s +Web inars +Ġtweet ing +Ġrepublic an +ãĢĤ ä¹ĭæīĢ以 +ï¼Įå¹¶ æĬĬ +Ġphot ometric +Ġpast ime +åĿIJ å§¿ +读书 人 +æķ°åŃĹåĮĸ 转åŀĭ +Lat ency +_un register +ĠHand ic +Ġdehydrogen ase +ĠJ FK +_head s +éĿ´ åŃIJ +ĠDEF INE +lod ash +ll is +ĠK ING +é»ij åIJįåįķ +Ġlocal Storage +ĠLe ib +WH Y +èħ¥ åij³ +åĬł ç´¢ +ãĢĭ æľī +åį´ è¦ģ +éĺ³ åı°ä¸Ĭ +ä¸ĥ æĹ¥ +-C V +ä¼¼ä¹İ æľīäºĽ +" use +( ast +C and +r ude +ĠH HS +ans son +ç¥ŀ éĩĩ +.Err UnexpectedEOF +æºIJæºIJ ä¸įæĸŃçļĦ +N ev +c q +i eth +çĻ ¼ +ä¸ĸçķĮ åIJĦåĽ½ +-S A +âĢĿä¸Ģ è¯į +Ġv ets +Âĥ Ãij +ĠBatter ies +. ce +é«ĺ å±Ĥ次 +çĤ¹ çĿĽ +åĽŀ 款 +æĥĬ åĬ¨ +ĠMc Gr +å¼Ģ设 äºĨ +ĠLind en +åħ´èĩ´ åĭĥåĭĥ +) è¿Ľè¡Į +put er +åħļ 课 +常è§ģ éĹ®é¢ĺ +symbol s +æ¸Ń åįĹ +åĮĹ æĸ¹çļĦ +âĢĵ the +lor o +åŁ¹è®Ń ä¸Ńå¿ĥ +æĺİæĺİ æĺ¯ +Ġintrins ically +åħ¶ çī¹å¾ģåľ¨äºİ +åħĭ é²ģ +ĠIM G +Ġouts ourced +çªĺ è¿« +D up +el ift +æ¯Ķ å̼ +å·²ç»ı å®ĮæĪIJ +ï¼Įæī¾ åĩº +S ri +ãĢĤ 建 +ay ama +Ġon Change +ĠM ee +红 çĿĢèĦ¸ +Not Supported +è¿ĺ没 åΰ +ãĢĤ åħ¥ +Ġindex Path +æĩ ī +ä¸Ĭæµ· çļĦ +èĤĿ èĥĨ +Sen ate +âĤ ¹ +åħ¬ åŃIJçļĦ +Ġmag ician +åĬłéĢŁ åύ +Ġscar ring +Anim ations +Sn ippet +_REM OVE +ä¸į æ¶īåıĬ +å·²ç»ı éĿŀ常 +Ġgr ills +壮 丽 +çī¢åĽº æłijç«ĭ +ä¿Ĺ è¯Ŀ +Ġ åĩłä¸ª +ĠP IO +ĠB urt +æĿ¡ çIJĨ +ES PN +CT S +unders et +ĠMind fulness +ãģł ãģij +ĠF ung +ç͵ åħī +åĮĹ çº¦ +cul pt +,ä¹Ł ä¸įæĺ¯ +èļ £ +. astype +æŁ³ èĭ¥ +ï¼ĮåĴĮ ä»ĸ +ï¼ĮåIJİ æŀľ +åζå¤ĩ çļĦ +ĠItal ians +ãĢģ æıIJ +ä¼ļ éĢļè¿ĩ +Ġint val +æħĪ ç¥¥ +f q +ĠV IN +Ġend oscopic +ï¼ĮæĪij æĦŁè§ī +ik ov +ï¼Į她 çİ°åľ¨ +Le aving +Ġkick er +Ġboo ze +对æĤ¨ æľīæīĢ帮åĬ© +- earned +ĠD HA +May or +@ hotmail +m td +_config ure +ãĢģèĬ± çĶŁ +. space +> } +ï¼Į æ¼Ķåijĺ +ï¼Į æģ°å¥½ +æĥ ĩ +assert False +Net works +大å¹ħ æıIJåįĩ +ĠWhis key +j ad +ä¸Ģ æķ° +å°± å¤ļ +.f inal +Ġinc ense +Ġgross ly +Ġrais ins +ï¼Įä¸į 顾 +ï¼ĮåĩĮ ä»Ļ +f emale +Ġo phthalm +æīĵ åĩºäºĨ +Ġautom orphism +åIJĥé¥Ń äºĨ +梳 å¦Ĩ +å¦Ĥä½ķ æīįèĥ½ +Ġaud ited +ç͵åŃIJ çīĪ +èΰ èīĩ +èĭį çϽçļĦ +camp aign +Ġseren ity +\ paragraph +Ġfor ging +æĶ¶ åľº +éĻ¢ ä¸Ń +æĸŃ æĸŃç»Ńç»Ń +å²Ľ ä¸ĬçļĦ +èĩ³å°ij è¦ģ +Ġjew ish +Ġз ап +f inger +ãĢĤ ç»ı常 +iel s +Ġsl ain +appe al +Ġ ________________ +ãĢģ 请 +ä¹Ł æľªå¿ħ +èĤ© éĥ¨ +Assign able +Ġ ÙĤ +æµĵ çĥĪ +Ġ{{ # +Ġ 裴 +ï¼Į 仿 +ĠI BS +äºļ èĥº +Ġsanit izer +ä¸į ä¸Ń +Ġget Item +ange a +æĶ¶ çľĭ +åį´ ä¸įèĥ½ +夹 å±Ĥ +åĴĮ éľĢæ±Ĥ +ast atin +Ġprot agonists +ï¼Į åĶĩ +ĠF TX +Ġdec als +åĽ½å®¶ åħ¬åĽŃ +ĠLeaf s +èĮ ´ +æĢĿ æ½® +ĠCon cerning +çϾ年 åīį +pattern s +人ä½ĵ åĨħ +ä¸į åħ¶çĦ¶ +åĪ© ç´¢ +vent us +ãĥ İ +(b uff +Vis iting +Ġpier ced +ĠP umps +Ġwh ipping +$$ $$ +Ġheal er +ĠM elt +æľĢ åŁºæľ¬ +å¿Ĺ åIJĮéģĵ +- mer +d ont +ï¼Į èŀį +ĠP URE +两个 æīĢè¿° +æķĮ æīĭ +Min imal +Ġnour ishment +ĠM HC +_PRO TO +widget s +çļĦ æĹ¶åħī +ĠEd ith +ĠCalcul ation +! ... +left rightarrow +à¸ Ī +æķ°åŃĹ ç»ıæµİ +åĩ¯ çijŁçIJ³ +Ġfurn ishing +ĠBack end +åĵĴ åĵĴ +ãĢĤ ä¼łç»Ł +åĴĮ æĮijæĪĺ +æĮ¥ æ´Ĵ +ĠGro ove +.b ias +exper iment +D inner +M ast +V u +ì Īĺ +ik in +ĠNC ERT +ĠLINK S +Ġmysq li +, åŃ©åŃIJ们 +.s quare +åĮĹ æ´ĭ +å£ģ åİļ +åķĨä¸ļ åĮĸ +å¡Į éĻ· +æijĦåħ¥ éĩı +ĠB IM +ä»İ åı¥ +_c ov +åĬŁ åĪ© +Ġrun away +é»ij éģĵ +综åIJĪ å®ŀåĬĽ +ä½ĵ åĮĸ +Ġ ä¹ī +Ġ ä½įäºİ +æħĮ ä¸į +Ġrefriger ated +æ¡ĵ åħ¬ +. amount +F leet +} z +ĠP up +è¿ĺ åī©ä¸ĭ +åĬªåĬĽ åŃ¦ä¹ł +-z one +æĶ»åĿļ æĪĺ +Ġactual ity +,æĪij们 è¦ģ +,æ¯Ķå¦Ĥ 说 +Ġn ova +é£İ è½» +ç½ij 课 +ĠAd ler +Log out +ĠMush room +Islam ic +/ events +ĠS LE +-st ack +Ġscan f +áĥ Ŀ +( Field +v ary +ãĢģ åľ¨çº¿ +Ġj p +Ġimp ede +Ġsay ings +çł´ çļĦ +æĸ¥ è´£ +ial e +ie gel +æĪij们 å¿ħé¡» +æĪ· æĻĵ +æĸĩåĮĸ æ´»åĬ¨ +è·ij å¾Ĺ +æ·· è¡Ģ +ãĢģå¸Ĥ æĶ¿ +é¢Ĺç²Ĵ çī© +ç§»åĬ¨ éĢļä¿¡ +éħįç½® æĪIJ +D rupal +O OT +ï¼Įå°± å¼Ģå§ĭ +ä¸ĩä½Ļ åħĥ +k ies +ãĢģ G +ï¼ĮæĬĬ æĪij +ĠUn ions +梦 çij¶ +ãĢģ åıijè¡Į +头 åıijçļĦ +.d elay +.B inary +ç²Ĺ çķ¥ +, æĸĩ +, æĬķèµĦèĢħ +Ġ èIJ¥ä¸ļæĶ¶åħ¥ +çļĦ 表æ¼Ķ +Ġg eese +èĩª å¹¼ +av s +å°½ åħ¶ +ï¼Įä¸Ģ缴 åľ¨ +æĻ¯å¾· éķĩ +失 å¿Ĩ +Ġcontinu ance +Ġì § +æľī çĶŁ +-t opic +æľ¬æ¬¡ èĤ¡ä¸ľå¤§ä¼ļ +æĢ¨ è¨Ģ +Ġ-------- --- +éĻ¡ å³Ń +Ġbrig ade +æĺ¯ æĿ¥èĩª +æ¡Ĥ æŀĿ +, åĽ´ç»ķ +Ġun sub +}$ \ +ĠEd itions +_th resh +ucc o +m ach +ãĢģ èĬĤèĥ½ +ax ed +éĩij èĬ± +æŃ» è·¯ +Ġshut s +èĵ¬ æĿ¾ +Ġcomed ic +Cont emporary +è± ī +Ġattend ants +Coll ins +" strings +Ġto gg +LO OK +æģ¶ èĩŃ +\ ud +ĠH AR +ĠDE VELO +æ¸Ĺ åĩº +Ġche ered +ï¼Įä½Ĩ è¿ĻäºĽ +.s el +Ġtele health +_COMP LETE +Ġspectrom eter +Ġc rou +List Box +ĠJan ice +çĤ« éħ· +ãĢĤ è´¾ +ä¸į 使ç͍ +ãĢģ é¢ľèī² +缴 æ°Ķ +ĠJack pot +ï¼Įä¸Ń åįĪ +id l +æĢİä¹Ī å°± +ä¹Į åħ° +误ä¼ļ äºĨ +è¢ħ è¢ħ +le ms +Ġtra versal +ĠØ ¥ +èĩªå·± æĿ¥ +Ġcut est +SY NC +-tool bar +uchs ia +ĠC ipher +é© ® +åŁº å°¼ +æĴ µ +atal ina +Ġå¦Ĥæŀľ æĺ¯ +åķª åķ¦ +Ġs ash +çĬ Ĭ +åĵĪ çī¹ +æļĹ å¤ľ +çļĦ天 èµĭ +, èĥ¡ +| ( +ãĢģ åij³ç²¾ +åľ° æľĿ +_f ramework +.get Block +ĠBro chure +驱åĬ¨ åĬĽ +æ¯ı次 éĥ½ +) y +Ġo o +ä¹ĭ æķħ +ĠEx haust +ãĢģ éĶĮ +åŁİ 西 +play list +Ġill usions +åĭĩ èĢħ +çŃ¾è®¢ åIJĪåIJĮ +ÏĮ ÏĤ +ĠHack er +享åıĹ çĿĢ +St reng +å¼ł 仲åĨĽ +è¾ĥ æħ¢ +åĴ¨è¯¢ å¸Ī +åķ° åŦ +ç»Ĩç»Ĩ çļĦ += UTF +ï¼Į 夫人 +ct urnal +_d c +Ġspecial ise +çľĭåΰ è¿Ļ +è¿ŀæİ¥ æīĢè¿° +ĠFile System +,ä»İ æĿ¥ +³³³³³³³³ ³³³³³ +l ng +åĴĮ è°ĥæķ´ +ĠU CS +Ġbl asp +åİŁä»¶åıĬ å¤įåį°ä»¶ +ãĢģ æīĢ +ĠW EST +ĠV ive +ĠCor ridor +Ġnons ensical +ĠB au +ck en +åľĪ åŃIJéĩĮ +ï¼Įèĥ½ åľ¨ +Ġhun ts +` ; +yl lic +Ġsocial ize +æĺ¯ éĤ£ +Ġst alks +æĥ³ è§ģ +iff ies +Button Item +ĠGood win +Ġiniti ates +ot onic +ãĢģ æĬĵ +ĠTer rain +ï¼Į åĬĿ +ï¼Įè¿Ļ è¯Ŀ +ĠReve aled +人 åΰ +ble y +åħ¶ä»ĸ æĸ¹å¼ı +å²Ĺ äºŃ +æľ¬çĶ³è¯· çļĦ +c umin +ĠF au +åİ» å¾Ģ +åħ¨ ç§° +Ġcivil ized +) âĢĵ +åĽŀ 身 +oid a +Ġflash y +C razy +ãĢĤ æľīä¸Ģ天 +Ġ| -- +æĬļ æij¸çĿĢ +ĠRealt or +: UI +Ġ è¡¥ +ou m +ä¸Ģ çĽı +åīį åľº +ä»Ģä¹Ī ä¹Łæ²¡ +é£ŀ åįĩ +. related +Ġmethod Name +åı¶ çļĦ +æĸ¹åIJij åĴĮ +çļĦé«ĺ å±Ĥ +-sh op +ipp les +ĠPain ter +åij ¤ +-f ollow +.b rowser +Ġrig s +á» į +( transform +\ chi +che at +att rib +ĠGe ological +ï¼Įé«ĺ 度 +ï¼Įäºİæĺ¯ ä»ĸ +ĠCab ernet +- about +大 å±ı +åıijçĶŁäºĨ ä»Ģä¹Īäºĭæĥħ +æľī è¶³å¤Ł +èĢĮ 没æľī +ç§įæ¤į çīĻ +z r +ä¹Ł æľª +æĻ® æŀĹ +æłij çļ® +Ġopp oses +Law rence +L ef +_ character +Ġide ologies +Ġmeth amphetamine +ï¼ĮåºĶ åľ¨ +çĭ¬è§Ĵ åħ½ +ĠJ Label +ä»ĸ们 å°± +ĠMer lin +ATT LE +Ġ`` , +æĺ¯ å¾Īæľī +éĤ Ī +éĺµ é£İ +ãĢĤä»ĸ 对 +亦 çĦ¶ +æĸĩåѦ çļĦ +ï¼Įå¾Īå¤ļ æĹ¶åĢĻ +.ext ensions +ĠParl amento +V acc +Ġ åĮ»éĻ¢ +ĠS arg +Ġwh ining +äºĭ ä¾ĭ +ï¼Į她 çŁ¥éģĵ +å·¥ç¨ĭ ç³» +çļĦå°ı åĮº +Ñĭ е +ãĥ¼ãĥ ł +or ated +ï¼Į å¸Ĥæ°ij +Ġf abs +il ogue +ĠI OC +åħ¨ æĿĥ +çĥŃ æºIJ +åŃĹ æł· +DIT IONAL +Ġ åĮħè£ħ +it ized +ĠB GC +æł¼ 丽 +åĮħ éĤ® +è¯ģæį® 表æĺİ +ç³ĸå°¿çĹħ æĤ£èĢħ +èł¢èł¢ 欲 +ï¼Į çͷ女 +Ġfact ored +é¦Ļ èĤł +ĠBi ochemistry +/ Core +D awn +ãĢģ åħ³ +æĹł ä¸İ伦 +çİ© è¿ĩ +è¡£ è¥Ł +ĠUI ViewController +< Int +M ISS +)) *- +缮æłĩ ä»»åĬ¡ +Interpol ation +æīį åĪļ +å·ŀ åºľ +rap ies +ãĢĤ ä½ķåĨµ +Pro g +AB STRACT +jud ge +ĠDM V +èĩªæľī èµĦéĩij +K an +Ġ 级 +ï¼Į åĪĿæŃ¥ +çļĦ æĬĹ +åΰ ä¸Ģè¾¹ +鼶 ä¸ĭ +åĢį 以ä¸Ĭ +Ġphosph olip +-cut ting +ĠM anny +åĴĮ éĤ£ä¸ª +ĠPhot ographs +溪 æ°´ +çĺ¦ å¼± +è½ ² +好 çĶŁ +.C ache +çļ® èĦĤ +ç»§ èĢĮ +亿 欧åħĥ +æ¸ħéĨĴ è¿ĩæĿ¥ +æīĢä½ľ çļĦ +ï¼Į çĤ¹äºĨçĤ¹å¤´ +ãĢĤ éī´äºİ +ï¼Įå°ı å§IJ +ä¹Łè¦ģ 注æĦı +\ lib +é«ĺ äºĮ +åĪĨæŀIJ æĸ¹æ³ķ +ĠCount ing +æĮ¥ æĮ¥æīĭ +ï¼Įéļ¾ ä¸įæĪIJ +âĻ ¦ +ĠGonz ales +çļĦ æĿ¡ä»¶ä¸ĭ +ne au +çļĦ åľºæīĢ +Ġm ids +Ġd ao +ĠDis qus +ĠMod ification +. ant +çļĦ èĥľåĪ© +ĠA VR +ĠG est +ĠCor vette +Scr atch +- Christian +L eb +Ġon der +Ġread ership +Ġver a +横 æĪªéĿ¢ +ĠLaure nce +E yes +J PEG +ãĢģ åΰ +ER K +SE P +/( (- +ĠCit rus +$ labels +ï¼ļ 人工æĻºèĥ½ +ĠSt ochastic +Ġunder mining +/s vg +æIJľ æķij +Ġchrom at +ãĢģ åijķåIJIJ +èĬ± åijĹ +å¹¶ä¸į åĥı +_se p +ul ge +ĠCont ra +MC s +pir acy +hyper link +Sever ity +V H +è·¯ æ¡¥ +åĺī å®ļ +b anner +ĠE HR +çŃī 设æĸ½ +æŀĿ 头 +* The +m ium +çĤ¹ 个 +Ġcr amped +Ġunderstand ably +BO OT +ĠCur ious +.list dir +è¯ ĺ +å½Ĵ æ¡£ +Ġwa ivers +ĠKath mandu +ĠRus so +í Ļ +ĠQ M +æģ© 人 +åľ¨ ä¸ŃåĽ½çļĦ +æĪij们 ä»İ +æĿĥ è´µ +建设 éĵ¶è¡Į +_alloc ator +æĹ¶ èµ· +è¿ĺ æīĭ +Ġsub graph +触 ç͵ +æī§è¡Į ä»»åĬ¡ +鸿 èĴĻ +太åŃIJ å¦ĥ +论åĿĽ ä¸Ĭ +- location +S AR +PO OL +Ġlib el +( ed +ãĢģ æ¸ħæ´ģ +âĢľ æĤ¨ +ç»ı å¼ĢåĮº +è½» å·§ +åħŃ äºº +éĵ¸ å°± +B ED +en en +ï¼Į æĭĵå±ķ +ĠO y +éĹ® 询 +Ġextrem ists +æĺ¯ä¸įæĺ¯ 羣çļĦ +Ġpl ating +Ġrep aid +å¨ģ æĸ¯ +è·ij çĿĢ +çīĻ ç§ij +红åįģåŃĹ ä¼ļ +l ates +èįī èįī +åĹ Ŀ +Ġinstruct ing +åΤåĨ³ 书 +ï¼Į æİĴåIJį +ãĢĤ åİŁåĽł +â̦â̦ âĢľ +è¿Ķ ç¨ĭ +æĻ¨ åħī +_bl ank +-s urface +ole v +è¿Ķ åĪ© +Ñĥ п +che e +çα åĴĮ +æĺ¾ç¤º è£ħç½® +å¹¶ä¸į éļ¾ +Ġstation ery +S ymptoms +没 å¾Ĺ +Ġconst ru +è´Ń åħ¥ +å¥ĩ çijŀ +-in vest +Ġder og +ภ¹ +æĬ½ äºĨ +Rel ay +èĢ Ĩ +好 ä¹ĭåIJİ +ä¸ī åıª +åĹ ª +è°IJ æ³¢ +BM W +Ġathe ists +- ounce +_ ignore +ï¼Į é»ijèī² +Ġright fully +äºĨä¸Ģ çϾ +Ġbr im +ä s +æŀª 械 +Ġbio film +åĴĮ è§Ĩé¢ij +å°±æĺ¯ ä»İ +Ġesc orted +- III +ĠF U +Ġwild fires +T win +ĠO BS +_f ocus +社ä¿Ŀ åį¡ +Ġb ordered +val uation +Ġtri ples +è¾ĵ æİī +ĠBack yard +Ġlegit imately +æ¿Ģåħī åύ +M ismatch +ĠB IA +度 æķ° +å°±æĺ¯ å¦ĤæŃ¤ +Ġlist a +ĠYork ers +Ġtim id +宽 大çļĦ +, ç½Ĺ +nd s +æľª 央 +Ġtri um +rest rict +çľĭä½ľ æĺ¯ +Ġf les +ĠC ENTER +ä¸İ åİŁ +RE ET +_d ispatch +é¢ĦæľŁ ä¿¡ç͍ +hard ware +re ich +ĠA β +é¾Ļ äºķ +Ġsand stone +^ (- +ä¸ĩ ä¼Ĺ +å±Ĥ åıł +éĺ´ çº¿ +èļ ¤ +ï¼Į è£ħä¿® +ï¼Į çµģ +ĠH ats +å¹´ åħ¬åı¸ +çł´ æĹ§ +Ġsn ag +Det roit +éĺĢ èĬ¯ +ĠSing ing +Ġpin ning +ill ust +Ġk ms +.s witch +ĠSch we +ĠHost ed +转载 请注æĺİ +(pro to +P g +S izer +éĥ½ éļ¾ +ĠUn employment +vis align +éͤ çĤ¼ +X t +ï¼Į ç¬ij容 +ï¼Į åģ·åģ· +Ġ( ++ +åı¯ æĤ² +åģļ çļĦæĺ¯ +æĺ¯ä¸Ģ æĬĬ +æĻķ äºĨ +Ġfle ets +奶奶 çļĦ +羣è¯ļ çļĦ +ç͍æĪ· éľĢæ±Ĥ +Ġpref s +Ġ æĸ½ +ãĢģ åĪ¶åº¦ +转 æİ¥ +.S uccess +Ġter pen +ä¿Ħ è¯Ń +ĠåįĹ å®« +Ġinfinit es +Ġd av +æĻ¾ æĻĴ ++ |\ +ĠC BT +ke red +ï¼Įä»ĸ å¿ĥéĩĮ +è·³ ä¸ĭ +ĠSan ford +Ġinfl amed +Ġ æĥħ +Ġp arm +form ats +Ġass es +.j av +\\ / +Ġsun day +.make Text +ãĢģ ç͵æ°Ķ +th reat +ĠL DS +没 ç͍çļĦ +Ġmathematic ians +F ingerprint +} X +Ġed s +é¾Ļ æ¹ĸ +éĹ® äºĨä¸Ģåı¥ +åĨħ容 è¾ĥå¤ļ +ĠHam let +ĠValid ator +ãĢĤ åıĤåĬł +ĠP enguins +Ġbo on +ä¸Ģ段æĹ¶éĹ´ åIJİ +ikh ail +A AC +C ole +is ión +-s um +ä¸īè½® 车 +.lin space +_m aps +éĶĻ èIJ½ +Ġbeaut ies +-ij erph +R b +Ġextrem ity +è¿IJèIJ¥ çļĦ +缸æıIJå¹¶ 论 +Ġin activation +èĢĮ æĪĺ +åĽĽ 竳 +ï¼Įä»ĸ ä¸İ +æłij èĭĹ +åŃĶ éļĻ +rich ment +è°ĥçłĶ åijĺ +Ġundef eated +, åħ³éĶ® +, 人家 +: center +Ġcommun icator +è¿Ļç§į çĸ¾çĹħ +ãĢģ ä¹³ +Ġpl aza +æĢİä¹Ī çŁ¥éģĵ +-m outh +-cl uster +. Standard +ç¦ı æĻĭ +.Cl uster +欢声 ç¬ijè¯Ń +æľī 天 +Ġsche mas +æIJŀ ä»Ģä¹Ī +.t w +ï¼Įå½ĵ 天 +åľ¨åľ° ä¸ĬçļĦ +did n +è±ģ è¾¾ +Ġb ays +oc ry +ä½ł 为ä»Ģä¹Ī +åζ èĥľ +æºIJ æĢ§ +_res olution +é¦Ħ 饨 +Ġhom er +, ä¸ĭåįĪ +ĠG TP +åĴĮ æĮĩ导 +转 åŀĭçļĦ +IT IONS +åĨ·åį´ æ°´ +åĴĮè°IJ çļĦ +Suggest ions +ï¼Į åĺ´ +ä»· è¿ĺ +- contract +ãĢģ æ´Ĺ +ä½ł åΰåºķ +_d ummy +å¼ł åĩ¡ +åħ¬åħ± èµĦæºIJ +Ø§Ø ³ +. ax +p ig +ĠA ly +irect or +Ġsw ore +æĸ¹åIJij ä¸ĬçļĦ +NO LOGY +ĠHost s +å¦Ĥ çĥŁ +Ġblock age +Ġmonot one +G raham +å°± å¾Īéļ¾ +ä¸ĵä¸ļ 人æīį +ç®Ģåįķ æĺĵ +ĠTrans fers +åijĨ çĿĢ +æĭŃ缮 以å¾ħ +ess o +_c ells +äºĨä¸Ģ æĬ¹ +ä½İ å¼Ģ +-g ray +-Ch ief +大ä¼Ļ åĦ¿ +ï¼ģ æĪijçļĦ +Business es +) C +ĠY ii +å¸Ŀ åIJĽ +- land +个 交æĺĵæĹ¥ +rid ing +楼 é¡¶ +Ġtim ings +Fe aturing +Ġdoubt ed +åĽĬ ä¸Ń +éħį 饰 +Ġsport y +æ¹ĺ 西 +ĠW IRE +Ġso ared +Ġmon soon +Ġmur als +ĠEss ence +Ġexch anger +Ġfec al +ĠUIL abel +( load +D AG +S ans +ï¼Į æīİ +å±ķ åı° +ï¼ĮæīĢè¿° è¿ŀæİ¥ +触 缮 +ĠAf ternoon +Ġconven ed +Art ists +n th +ĠB AB +æĪij们 è¿ĻäºĽ +å°±æĺ¯ 被 +ĠBy rd +exp ires +Th or +竣çĦ¶ ä¼ļ +æĿĥåĪ© 人 +FL D +IRON MENT +W itness +ĠF acing +è¿ĺæľī ä¸Ģç§į +åĿIJ èµ·æĿ¥ +lp Vtbl +Ġ'_ ' +f urther +ãĢģ ä¸ĵå®¶ +å¦Ĥ äºij +声 åѦ +ï¼Įåľ¨ äºİ +游 åİĨ +-g rained +_ IGNORE +ä¸Ģ çϾä¸ĩ +ĠF ell +_INS ERT +ĠVict ims +ãĢģ æĽ² +ĠV GA +Pro ve +ĠStaff ing +Ġham pered +è¿IJæ°Ķ 好 +è¶Ĭ 强 +æł¹æľ¬ ä¸įåı¯èĥ½ +åIJ¯åĬ¨ 仪å¼ı +Ġappet izers +èĥ½ æľīæķĪ +åĪĨ æĹ¶ +OM ET +ï¼Įåıį åĢĴæĺ¯ +RT L +å¢ĥå¤ĸ è¾ĵåħ¥ +, éħįåIJĪ +.s ingle +åĮĹ è¾° +çľģ åŁİ +Ġhum ankind +Ġmis chief +æīĭä¸Ģ æĮ¥ +Bright ness +) }$, +- æĢ» +åİ» æĭ¿ +Ġunder stated +缴æİ¥ æİ¥è§¦ +Ġplain text +ĠS our +åľ¨ éĿ¢å¯¹ +Ġad o +第ä¸Ģ éĺ¶æ®µ +-p ull +ĠMar iners +)) **( +Ġhyp nosis +çļĨ åı¯ +åŀĥåľ¾ å¤ĦçIJĨ +Ġ"_ " +Ġbisc uit +In Progress +Ġdes erts +ï¼ĮæĽ´ åĪ«è¯´ +è°± åĨĻ +å®Įç¾İ ç»ĵåIJĪ +çĭŃ éļĺ +æĹ¶ 说 +ĠInc or +èĢIJ åıĹ +éĥ½ä¸į è¡Į +ĠH U +Ġhe als +ä¹Ł ä¸Ģ缴 +çϾ åı¶ +页 岩 +滤 æ¶² +ĠRob ots +å¤ļäºĨ åĩłåĪĨ +åı³ä¸Ĭ è§Ĵ +P etition +Ġsh aker +å°ı ä¸ĥ +å®ī 详 +åIJĥ åIJĥ +ä¹° è¿ĩ +Ġtw ilight +S olving +ro ductive +å°± åĸľæ¬¢ +åĽł 人èĢĮ +å¹¶ä¸įæĺ¯ å¾Ī +com parable +åĻ » +ä¸ĵ ç¨ĭ +è´¢åĬ¡ 顾éĹ® +Ġa pl +ãĢĤ çľĭçľĭ +æ´ º +éĴ» æĪĴ +ĠØ ¬ +/ 人 +对 æ¯Ķä¾ĭ +æĪĸ æļĹ示 +èĢĥ äºĨ +æĬķèµĦ åĴĮ +ãĢĤæį® ç»Łè®¡ +ĠÅŁ i +Ġmuscul oskeletal +le aders +.d est +å¥ĩ å¼ĤçļĦ +ä¸ĵä¸ļ åIJĪä½ľç¤¾ +Ġå½ĵ åĪĿ +åıĺæĪIJäºĨ ä¸Ģ个 +åѦ åĽŃ +åıĪ éĩįæĸ° +æķĻåѦ 模å¼ı +ogen es +_ ram +Ġb raz +ĠP MA +é» į +ma ids +rel igious +éĩİ çļĦ +çĵ ¯ +åŁºæľ¬ åħ»èĢģä¿ĿéĻ© +ï¼Į为 人 +è¯ ĭ +æĪij éĤ£ +两 段 +çł´ æ¡Ī +çĶļèĩ³ è¿ŀ +Ġcoun sell +(_ ) +In cluding +Ġcomm as +ym in +çŁŃ æĸĩ +Ġrep ur +riend s +åĵĹ åĵĹ +ĠCatal an +å¤ĸ åªĴ +ym ax +çģ«ç®Ń éĺŁ +ï¼Į谢谢 ä½ł +ĠRa ised +çĿĢçľ¼ äºİ +, èĭı +_ we +Ġev asion +Ġunder rated +çĶŁäº§ åζéĢł +ðŁ ļ +夹 åħĭ +éĬ ® +K U +m aven +ãĤ Ģ +ĠH umb +个 ä½ĵçļĦ +Ġ[ ? +reg ions +Vol tage +æĻķ åĢĴ +ì ² +(c ore +ĠMathematic a +ï¼Į 伯 +not ag +éĥ½æĺ¯ åı¯ä»¥ +ĠHol istic +Ġferm ion +à ļ +ree ks +æīĢæľī åĨħ容 +åĨ² è¿ĩåİ» +ÑĤ оÑĢ +ĠHimal ayan +ï¼Į 宣 +æľĪ èĩ³ä»Ĭ +Ġ/ . +太 åĤħ +.load ing +Ġgrat ification +严èĤĥ çļĦ +F IND +ĠR ookie +Ãł o +M aur +ï¼Į æģĴ +Ġgl azing +å±ĭ å¤ĸ +çļĦéĤ£ 天 +å¨ľ å¡Ķ +ĠCK D +Ġ ç³»åĪĹ +ï¼Į åħħ +对 çĦ¦ +è¿Ļæł· åķĬ +ĠAss igned +çŀ ł +åĢĴ ä¸įæĺ¯ +æīģ æ¡ĥ +亲 亲 +Pass ed +Ġlibert arian +B rew +sc opes +j os +社ä¼ļ åѦ +空æ°Ķ 污æŁĵ +C ant +X s +ill is +æĪIJ 羣 +Ġ... " +ç͵åŃIJ 设å¤ĩçļĦ +å°ı æŀĹ +-p recision +_lock ed +ï¼Į ä¼ĺéĢī +ãĢģ è´¢æĶ¿ +ĠR AF +.D ock +她çļĦ èĦ¸ +èĢĥè¯ķ ä¸Ń +. available +Ġto aster +ĠS ED +.s ingleton +表çݰ äºĨ +ĠCH ILD +æ··åIJĪ åĬ¨åĬĽ +Ġin ad +ãĢģ 赤 +ĠR ode +circ um +ĠCop ies +ĠI CS +æĢ» ç«Ļ +çĸij å¿ĥ +ç§Ģ ç§Ģ +çīĻ åij¨ +åĹľ è¡Ģ +_ Request +ro pe +ä¸į åIJĮæĹ¶ +å°± åı¯èĥ½ +ç´§ ä¸įæħ¢ +(c m +Ġter races +æ£Ģå¯Ł éķ¿ +åįģåŃĹ è·¯åı£ +ä¿Ŀ æĹ¶æį· +强 强 +.g wt +Re actions +ï¼ĮéĤ£ä¹Ī ä»ĸ +çĶŁåŃĺ çļĦ +๠ĥ +Ġchrom osomal +ĠJa ime +Ġtant al +j ian +éĩĮ å¤ĸ +æĹł éĹ´ +ener able +èģļ åĬĽ +SH IP +_le af +éĩįéĩį åľ° +( NS +. pe +ĠL om +_P OP +B UR +\ S +t æģ¤ +æĿ¿ æłĹ +éĢĢ åĩºäºĨ +Ġpen is +åĢºåΏ å¸Ĥåľº +翻天 è¦Ĩ +ï¼Į ä¸ĵå®¶ +US R +æĿ¾ æķ£ +ä¹Ł å¿ħé¡» +ï¼ļ - +Ġwat cher +Ġglut athione +( bb +B RA +_ room +r á +.p ower +æī§è¡Į æĥħåĨµ +_G roup +æľīä¸Ģ åįĬ +exp anded +Ġbenchmark ing +M ol +ï¼Į ä¼ģåĽ¾ +绵 éĺ³ +éĢ µ +第ä¸Ģ è½® +æĢģ çļĦ +æķ¬ éĩį +Ġd ut +Ġh ikers +å¾ħ äºĨ +ĠCons ensus +æ³ķå¾ĭ æľįåĬ¡ +Ġ è§£ +å¤ĩ éĢī +Ġauthor izes +-r anking +ĠL l +çĻ» æľº +Connect ivity +ãģ¨ ãģĹãģ¦ +.Q t +Ġperturb ed +acam ole +Ġ éĹ» +' er +G ordon +Ġf ission +ãĢģ è£ħç½® +å¾ħ ç»Ń +Ġsec p +æ³¢ éŁ³ +ĠPost ing +ç»§ç»Ń åľ¨ +Sw eden +TX T +Ġcra ps +ï¼Į æ¶Īè´¹ +Ġe arm +ĠM PC +ï¼Įä¹Ł åıªæĺ¯ +bl ade +_r d +è¿ĽæŃ¥ çļĦ +Ġvars ity +( expression +int ro +头 åŃIJ +åŃĶ åĨħ +åij¨åĽ´ çݯå¢ĥ +Ġabsorb ance +港澳 åı° +) dx +çļĦ é±¼ +åı¯ è¾¾åΰ +å°ij女 çļĦ +ä¿¡æģ¯æĬ«éľ² ä¹īåĬ¡ +od il +ab al +ĠW arming +Ġx f +æ¶Ī éģ£ +_T S +è¾ĵ ç»ĻäºĨ +æł¼å¼ı åĮĸ +F c +Ġsc ented +åIJ¹ éĽª +- vers +_p ic +ĠZ ah +éĵģ éªij +Ass igned +Ġsuperv ising +æµ·æ·Ģ åĮº +éĿ¢ æĺ¯ +ĠPa olo +æ·±åħ¥ çłĶç©¶ +Ø º +ĠSpirit uality +lat itude +Ġplacent a +, æ¯ı个人 +æµ Ķ +åĪĨ å·¦åı³ +ĠSh u +åħŃ éģĵ +以ä¸Ĭ æīĢè¿° +夺 èµ° +ĠPop up +Ġbg color +( TM +/ ubuntu +ä¸į æĬĬ +ĠâĪ ª +inn ie +_EX TRA +åĩ¸ åĿĹ +Ġiso forms +ä¸į äºī +åľ° å¹³ +åĮħæĭ¬ ä½Ĩä¸įéĻIJäºİ +å»¶ å¹´ +ĠBurn ett +. enc +V ir +Ġo me +è¿ľ æ´ĭ +亲 åı£ +LL VM +ï¼Įåı¯ ç͍äºİ +-block ing +C c +ool ed +ste am +-des cribed +Ġ æľĢä½³ +å°±æĺ¯ æĪijçļĦ +马 å±ģ +åľ¨ä»ĸ éĿ¢åīį +Upload ed +Ġobliv ious +ï¼Į ä¸Ńåįİ +ĠC ART +æľī äºĨä¸Ģ个 +æľī èµĦæł¼ +ï¼Įä»ĸ åı¯ä»¥ +Sign s +λ ά +ï¼Į éĩįå¤į +éĿ¢ 纱 +ĠAn ast +åĿIJ åľ¨ä¸Ģèµ· +äºĴ åĬ¨çļĦ +ï¼Įè¿ĺ èĥ½å¤Ł +ĠKe pler +ĠDel ight +ĠElev ator +Mis cellaneous +ĠVaugh n +ĠS od +ĠE ner +ä¸İ ä¸Ĭ +å·¥ä½ľ éľĢè¦ģ +ĠBrow ne +ä¸įè¦ģ åİ» +æĺ¯ä¸ª å¾Ī +èĪŁ å±± +Land scape +奥æĸ¯ æĽ¼ +å·§å¦Ļ åľ° +æĹ¶ å¿ħé¡» +_m asks +.R ptr +ĠCou pe +æµĵ çľī +å®ŀåľ¨ çļĦ +室åĨħ 设计 +åı¯æĢķ äºĨ +Ġsabot age +天 é»ij +## ' +Ġprogram matic +æĻ® éĻĢ +åĬĽéĩı åĴĮ +èĽŁ é¾Ļ +æł· æł· +.s chedule +Ġwater mark +åħŃ åIJĪ +ĠDI FF +åĹĵ éŨ +Ġlact ate +ç»Ŀ æĭĽ +åįĥ å±± +.P anel +åĢŁ æľº +触 çĬ¯ +Ġhydro carbons +çī©çIJĨ åѦ家 +Sem antic +CD SA +Ġing est +èĿ ¼ +å¥ĭæĸŠ缮æłĩ +.Rem ote +人å±ħ çݯå¢ĥ +ĠD BS +irm ing +èµ¶ çĿĢ +$- $ +Ġ[" ", +.Ref erence +. Intent +ĠB ites +对 大 +åĪĨ åĮħ +éĴ¢ çļĦ +.r pc +å¹¼ èĻ« +ï¼Į 丢 +Ġh c +ose c +æıIJ è¦ģ +ms elves +以ä¸Ĭ æĺ¯ +don ald +_OPER ATION +Ġantagon ists +ãĢĤ 便 +ĠAl onso +å¾® å°ıçļĦ +Ġvent ral +Ġchore ography +ĠQuin cy +. INFO +(" + +ï¼Įè¿Ļ åIJį +å°ij æľīçļĦ +.T emplate +è¶£åij³ æĢ§ +Ġw inger +ãĢģ éĴĻ +QU IT +ï¼Į大家 åı¯ä»¥ +ĠSqu ares +æļĤè¡Į åĬŀæ³ķ +Z M +n est +Ġ è¿ĩåİ» +头 ä¸Ģ次 +常 åľ¨ +Ġtrans ducer +.get State +åĹ· åĹ· +N igeria +çļĦ è¿ĽæĶ» +ro th +oth o +| } +Ġlast Known +çĶŁæ´» çݯå¢ĥ +èĥĥ èĤłéģĵ +åŃ¦æľ¯ çķĮ +ĠLips chitz +: r +R ome +ï¼Ī L +.S cript +èİī ä¸Ŀ +" æł¹æį® +, æĭī +ãĢģ çĭ¬ç«ĭ +ä¿® æķ´ +幸 çģ¾ä¹IJ祸 +_comp letion +Ġm over +Ġdist illation +åı¤ æłij +å°ı康 社ä¼ļ +\ ln +çĥŃ æ³ª +ä»ĸçļĦ å£°éŁ³ +Be er +纵 容 +çijŁçijŁ åıijæĬĸ +ï¼ĮéĤ£ä¹Ī æĪij们 +ld a +Âł åĽłä¸º +ï¼Ľ å¹¶ +ĠPlay ground +éĵŃ æĸĩ +大 åĬŁ +St able +æ·± æĦı +de alloc +.F rame +ï¼ĮçĦ¶åIJİ æīį +ä¸Ĭä¸ĭ çıŃ +ï¼ĮéĤ£ä¸ª æĹ¶åĢĻ +arc a +DF LAGS +APP ING +Ġcomorbid ities +. help +åģļ çĤ¹ +è¿Ļ个 æĦıæĢĿ +_c am +åĪĿ è¯ķ +æĹłç©· çļĦ +çĶŁ æĬ½ +åŁº åĿij +éĤ£ä¸ª åľ°æĸ¹ +è¿ĺ没 çŃī +欺 åĩĮ +ï¼Į以便 äºİ +å¤ļ çľĭ +é» ł +è¿ŀ éķ¿ +ï¼Įçİ°åľ¨ å·²ç»ı +Ġbirth place +Blue print +åĿļå®ŀ åŁºç¡Ģ +, è¶ħ +U g +f ighter + ij +è¿ĩ éģĵ +ĠK iev +ä¹Łä¸į æĢķ +ï¼Įåľ° å¤Ħ +C ats +ï¼Į åĵ¥ +ç͵ å¼§ +æĿĢäºĨ ä½ł +Dat as +æ·±åĮĸ æĶ¹éĿ© +âĢ § +äºĭ ä¸Ń +Ġob nox +_UNS IGNED +ি ঠ+/ about +说 æĪIJ +å¿ĥ ä¸ĭ +åij¢ åĸĥ +Pat ent +S oup +Ġt g +ãĢĤ åĨħ容 +èĢĥ åıĸ +Ġpub erty +æī¾åΰ çļĦ +Ġt aut +ãĢĤ å½±çīĩ +ĠG EO +第ä¸Ģ åľº +ĠEM PTY +æĽ¾ å¤ļ次 +æ¯Ľ 骨 +Ġunknown s +Ġt rot +äºļ çļĦ +çªģåĩº éĹ®é¢ĺ +å°Ĩ æīĭ +Ġdiff e +ç¥ŀ åħµ +认 罪 +Ch ap +éĵ¶è¡Į è´¦æĪ· +οÏħ ÏĤ +ĠTrad itionally +ç»ĵ èĪĮ +çļĦ缸åħ³ è§Ħå®ļ +our ism +ä»İ å¤ĸéĿ¢ +æĸĩä»¶ åĴĮ +ha ft +Ġgau ges +ï¼Ł æĪijçļĦ +_f ragment +_c redentials +-m obile +ä¸ĩåħĥ åĴĮ +æ¯ķä¸ļ è¯ģ书 +æİĴæĶ¾ æłĩåĩĨ +Ġobsc ured +ï¼Į W +ï¼Į æĢ§ä»·æ¯Ķ +ï¼Įä»İ æľª +ĠMod erate +± Ãij +Ġ ä¹Łå°±æĺ¯è¯´ +ç® ĵ +-l ibrary +Ġheart break +纪å§Ķ çĽijå§Ķ +w ag +Ġag n +eg ovina +å¨ £ +.d f +_D raw +èħ¹ ä¸Ń +åΰ æĪijçļĦ +ĠIn gram +Char Array +æIJŃè½½ äºĨ +P un +_ terms +åľ¨ åİ¿ +çIJĨ åºĶ +iet f +çļ® å°Ķ +------------------------------------------------------------------------ --- +游åĩ» éĺŁ +N ash +ĠG ains +Ġso b +AC EOF +è¿ŀæİ¥ èĩ³ +éģĩ ä¸ĬäºĨ +åĪĽéĢł ä»·å̼ +åĮĸåѦ æĪIJåĪĨ +ç§įæ¤į éĿ¢ç§¯ +ä½łçŁ¥éģĵ åIJĹ +ä¸ī 人çļĦ +åıijå±ķ ä¸ŃåĽ½å®¶ +Pl ural +ĠQual ification +è¡įçĶŁ åĵģ +, å®ŀåľ¨ +B ush +ĠCl imbing +ĠAct a +Ġmid term +Ġpul ver +T odo +p owered +ĠP ins +Ġsp iked +èĩªå·± æľĢ +io ch +åĨľä¸ļ éĥ¨ +. reply +get Current +. ssl +对 岸 +no vel +-ad minist +æľīæĺİæĺ¾ åĮºåĪ« +b ush +åIJĦ èī² +ĠOpen ings +Ġc wd +Ġsh outs +ä¹Ł 缸å½ĵ +Ġunbeat en +" To +ãĢģ 让 +ĠB REAK +å¹³ ä»ĵ +], \ +Count ries +ĠMer idian +çļĦ å®īæİĴ +Ġd angling +éĢļ åĭ¤ +ãĤ ¬ +ĠAc oustic +âĪ ij +S sl +_ answer +l id +p gen +ä½ĵ éĩı +åģļ ä¸įäºĨ +åŃĺåľ¨ éĹ®é¢ĺ +ç¼ĸè¾ij éĥ¨ +ĠStir ling +j al +Ġp ode +Ġcar ic +游æĪı ä½ĵéªĮ +èģĶèµĽ åĨłåĨĽ +Ġsensit ivities +R atings +st ub +ĠP DA +çİĭ ä½į +第ä¸Ģ 大 +.Index Of +ĠH mm +åIJij ä¸ŃåĽ½ +æīijéĿ¢ èĢĮæĿ¥ +ik on +è¯ļ çĦ¶ +Pal m +iph any +å´İ å²ĸ +: NO += item +æīĵ 人 +.id x +ä¼ı åĩ» +rivile ged +çIJĨ论ä¸İ å®ŀè·µ +çŁ ¾ +Ġhyper links +Print able +ĠVari ation +iop athic +ï¼Į åĬłå·¥ +ĠS EN +Ġhor rified +èļ¯ èļĵ +ĠR ever +), $$ +Ġfl oss +Ġ** ) +åIJ¹ çīĽ +Ġconcert ed +åĺİ åĺİ +ĠJacqu eline +Ġh aste +Ġdef lect +_b lack +符åIJĪ åĽ½å®¶ +ï¼Įåı¯æĺ¯ çİ°åľ¨ +Ġreset ting +ĠJam mu +å§Ĺ å§Ĺ +ul le +Ġsa ute +.com tag +-l im +_r anges +ĠCass idy +Aud ience +çķĻå®Ī åĦ¿ç«¥ +æĺİçϽ è¿ĩæĿ¥ +Ġcere als +西æĸ¹ åĽ½å®¶ +è¿ŀéĶģ åºĹ +vell ous +R ide +ãĢĤ èĩªçĦ¶ +个 å±ģ +ç¥ İ +å¼ł ä¸ĵè¾ij +è¿ij çļĦ +.RE LEASE +ĠCreature TPL +æıIJ åĩºæĿ¥ +ä½Ļ 项 +éĴ٠声 +ĠSub scriptions +_EN C +imm ers +pur ple +èĤĽ éŨ +( (' +Ind onesia +æĬ½ æ£Ģ +Ġpy game +ä¸Ńå°ı åŀĭ +详æĥħ 请 +Anc ient +S uddenly +女 çļĩ +ĠUn c +ĠDec oder +åĴ¸ 丰 +.Ver ify +ge b +eg ment +社ä¼ļ åĮĸ +ĠPI PE +æIJģ ç½® +Ġcomprehens ively +ä¸ĭ é£İ +åĨĻ å®ŀ +* pi +~ $\ +ï¼Įä¸Ģ åIJij +ä¿¡æģ¯ ç½ij +秦 æ·® +-n ational +Ret rieve +D ivid +Ġkn ights +Ġimmun otherapy +è´© åŃIJ +, æīĵå¼Ģ +âĢľ åħĪ +大 è·¯ +车 æŀ¶ +Ġcre ed +满 头 +Ġwalk way +Ġpsych ologically +_int o +ĠW earing +两 è¾¹çļĦ +ï¼ĮæĪij è·Ł +åįĹ éŨ +.S kip +-l iving +æĶ»åĩ» çļĦ +çŃīçĿĢ ä½ł +Ġvoic email +í ĺ +æ°´ åĨĽ +but erol +ĠB ub +ä¸Ńå¿ĥ å°ıåѦ +åºĬ åīį +ĠFound ers +/sw agger +liter ally +Ġ æ³ķåĽ½ +ĠV ance +ature d +ĠComput ation +åıĤèµĽ éĢīæīĭ +( work +Ġaneurys m +Ġbid irectional +Ġdef iant +Ġshe af +_M ACHINE +managed Type +çļĦæĹ¶åĢĻ è¦ģ +èĹ ĵ +ifer ous +woo commerce +" ä¹ĭç±»çļĦè¯Ŀ +ĠL ansing +åįģ æĹ¥ +Ġmon ocytes +ĠCol o +åľŁ çĿĢ +Ġtimes cale +W ear +Ġb um +çIJĨ çŁ³ +_C ODES +åĨ· çľ¼ +ĠMarx ist +Ġreconsider ation +æĺ¯ èĥ½å¤Ł +.s peed +Ġ% @", +S pectrum +Ġf ad +éĢł 车 +ĠVer dict +Ġirregular ities +. Children +ĠR ptr +Ġmed iating +é£ŀ 鸣 +ĠVol leyball +çļĦ èĤ¡ä¸ľ +ï¼ļ é»Ħ +ä½ı æīĭ +_l ists +罪 è¿ĩ +.Argument Parser +Ġensl aved +! } +{ ex +ï¼Į æľªæĿ¥çļĦ +Ġte ased +æŁĶ æŁĶ +Ġrenew ing +ĠFol ks +ä»ĸ们 äºĨ +ä¹Ŀ çĤ¹ +æĥĬ å¿ĥ +éļIJ èĭ¥çݰ +/p ool +æĥ³åΰäºĨ ä»Ģä¹Ī +H aha +M OST +ï¼Į éĢĴ +åľ¨ æľ¬å®ŀç͍æĸ°åŀĭ +请 å®ī +èĤł çĤİ +åľ°çĤ¹ çĤ¹å¤´ +_the ta +Ġomin ous +* ), +Ġd lg +缴 éļ¶ +âĢī h +ĠSta ples +æĺ¯ ç͍äºİ +ĠR ift +项 è§Ħå®ļ +èĤ¡ æģ¯ +ĠOrgan izing +ĠM illing +-d eal +令 她 +æ·ĺ æ°Ķ +éĤ£ä¹Īå¤ļ 人 +ãĢģ æĶ¶ +Ġph ilippines +ç»ı常 åĩºçݰ +Ġing ested +Fire wall +ĠRosen berg +Ġ é¢Ŀ +Ġinitial izing +special chars +ĠEff orts +P ivot +_s plits +çļĩ åIJİçļĦ +áº Ń +å·´é»İ åľ£ +æĭįåįĸ ä¼ļ +ĠBh utan +Ġunsett ling +e ast +n ak +ing way +ãĢģ èij£äºĭéķ¿ +æĪij å¾Ĺ +ä½ĵ ä¸Ń +Ġback side +Http Response +ç½IJ åŃIJ +ï¼Įæķ´ 天 +é« Ķ +ET O +Ġcondition ers +æĬ± æĭ³ +_SE CRET +Ġconvey ance +ãĢĤ æľ¨ +_G ame +Syn opsis +Ġcuc umbers +Ġ( ?) +Ġ. * +éĿŀ åħ¬å¼Ģåıijè¡Į +.set Visible +.class es +ĠAuthor ized +ĠNY U +ä¸Ĭåīį åİ» +ĠConstant in +c um +Ġ å¸ģç§į +çļĦ èĤī +ht i +Ġå¼ł è¡į +èİİ æĭī +åĢŁæ¬¾ è´¹ç͍ +Ġscar ves +) b +, æľ¬æ¬¡ +åĽ½ åºĵ +常 éĩı +ä¼ļæľī å¾Īå¤ļ +Ġsm uggling +è¿ĻäºĽ 天 +PD U +æ·ĭå·´ ç»ĵ +sth rough +ĠF BS +åħ¬å®ī åİħ +æĺĶ æĹ¥çļĦ +ĠConcent ration +ìĬµ ëĭĪëĭ¤ +ĠS ore +ĠB odies +å¸Ī åĽ¢ +伸 åĩºäºĨ +ĠSwan sea +Dou glas +> I +ï¼Į ç»ķ +çļĦ é»Ħéĩij +æĺ¯ åħ¨åĽ½ +åĩł å²ģ +Ġà ¸ +ï¼ĮåĨį ä¹Ł +Drop Down +ĠAut odesk +å¥ī ä¸Ĭ +Ġ åĬłåħ¥ +Ġs ä +Ġm use +åľ° ç¬ij +åı¯ä»¥ è®©ä½ł +Ġlog out +Mark down +p data +on ormal +ĠB etsy +ĠK ylie +AT O +dom inal +, 离 +p ak +Ġse vered +åĪ© 空 +Sh ows +ï¼Įè·Ł æĪij +) V +Ġs amsung +ï¼Į æĹ¥åŃIJ +ber man +_C lass +Ġdeg enerative +Ġgerm ination +_ ot +ãĢĤ åĽŀ +Ġout spoken +Set Value +âĢľ 鼶 +Ġdo cks +ĠDe V +好çļĦ è¯Ŀ +Ġcabin etry +ĠMAT ERIAL +he rapy +Ġin und +ĠG areth +å¿« å¿« +,è¿ĺ ä¼ļ +M egan +æĬĬ ä¸Ģ个 +ĠSp ur +åı³ èĩĤ +æĭħå¿ĥ äºĨ +ç²ĺ éĻĦ +\ }_{ +ĠF arn +å½ĵ 天çļĦ +ä»ĸ们 ä¿© +Con duct +å¼Ĥ åħ½ +Ġcirrh osis +åľ¨ æ¯ı个 +ãĤ¹ ãĤ¿ +Ġtelev isions +w el +ĠP PT +-c ancer +и б +Ġë Ħ +ĠPul itzer +. radius +åľ° äºĨè§£ +æĹ©å°± å·²ç»ı +ĠSon ia +åĩºèµĦ é¢Ŀ +ä¸Ń åĮħæĭ¬ +æĪĺ éĺŁçļĦ +Ġpap rika +çĮĿ ä¸įåıĬéĺ² +Ġaval anche +ĠCh un +享 èªī +æī¬ å°ĺ +ĠØ ® +Ġreass urance +è·Ĩ æĭ³éģĵ +F amous +çļĦ æĸĩ +éķ¿ çŁĽ +ĠX III +äºī 端 +UN KNOWN +Ga ussian +ĠEstablish ment +Ġ" {{ +å°ı ä¼ģä¸ļ +é£İ éĽª +æĬķèµĦ 建议 +åĽŀçŃĶ ä¸İ +ãĢĤéĤ£ 天 +_ analysis +æŃ¤ çķª +ĠBl ink +Ġtable top +_DECL ARE +ï¼Į å°¹ +pl ans +å®ŀäºĭ æ±Ĥæĺ¯ +L ack +å̼å¾Ĺ çļĦ +åıijå±ķæĶ¹éĿ© å§Ķ +/ an +w rapped +Ġsp urred +With Name +ĠIns pect +æĽ´æĸ° æĹ¶éĹ´ +Ġdis qualified +èµ° ä¸ĢæŃ¥ +Ġbro om +Q String +â ł +é»ij è¢į +arrow ing +éļĭ åĶIJ +è¿ĽæĸĻ åı£ +æĻĤ éĸĵ +gh i +^{ {\ +La TeX +( Command +ãĢĤ âĢĺ +ĠD uffy +åĪĨ éĴ± +DR AW +Ġantidepress ants +ase ous +å¼ł åĽ½ +ĠGu cci +Ġpred atory +ĠEnt ities +Ġå½ĵ ä¸ĭ +æ¿ĢåĬ¨ åľ° +âĢĿä¹ĭ ç§° +S MB +ach ieve +Ġcreat ives +ï¼Į大 人 +æ§ Į +çļĦåºķ 端 +ç¬ijéĿŀ ç¬ij +âĢĻ - +ĠR ies +æ¶² ä½ĵçļĦ +ãĢģ æĢ§èĥ½ +å®ĩå®Ļ ä¸Ń +Ġlect urers +ï¼Į è·¯ä¸Ĭ +åĬł æ°¢ +æİĴ çĥŁ +Ġes ophageal +ĠAdvis er +j is +Ġch oking +åħ¶ 身 +æĥ³ çľĭçľĭ +_C BC +å¹´è½» çļĦæĹ¶åĢĻ +m otor +Ġsp urious +æĢ» æĪIJ绩 +åĽ½éĻħ åIJĪä½ľ +oph on +çѾ åıij +bour g +$ P +ï¼Į 女åŃIJ +il en +ĠS FR +_C ATEGORY +èİ·å¾Ĺ æĦŁ +è´¥ äºĨ +é£İéĻ© æİ§åζ +out line +Ġsumm ing +ï¼ĮçŃī ä½ł +. entities +ï¼Įå°± åºĶ该 +onn ay +-b rown +rap id +Ġfire places +åı¦å¤ĸ çļĦ +ãĢĤä»İ èĢĮ +ĠEnlight enment +- constant += R +éĩij çIJĥ +Host ing +var iants +åĵª åĴ¤ +ĠLe ak +åħµ ç§į +éļIJ æĢ§ +è¡ĮæĶ¿ è¯ī讼 +P ilot +ĠM AS +æĹ¶ 使ç͍ +天 ä»Ļ +ĠTel ugu +ÂĴ s +åºĶ å°Ĩ +æĿ¨ æ´Ľ +/ network +T ill +Ġ åĮĸ +ĠD ST +èĩªå·± å·²ç»ı +ĠBent on +ĠF IND +ç»Ļ æĪij们çļĦ +èĢĥ é¢ĺ +éĽĨ éķĩ +Ġâ IJ +des pite +C OS +Ġf on +pp p +éĢł çī© +ĠGu adal +address es +éľĦ äºij +ä»İ头 åΰ尾 +í Ħ +ä¸į èĻļ +ãĢģ åı¯ä»¥ +Cl azz +ĠHer bs +æī« èį¡ +èĤ¡æĿĥ ç»ĵæŀĦ +æģª å®Ī +( js +ï¼Į ä»ĺ +Ġl uk +åĴĮ åŃĻ +ĠK K +_s ervices +èĥĮ æĿ¿ +æĮģç»Ń äºĨ +è·Ŀ离 çļĦ +ĠCa es +/k ernel +_AX IS +( ä¸ĭ ++ F +Ġm ême +ãĢĤ åĨħ容ç®Ģä»ĭ +åĴĮ ä¸ļåĬ¡ +ĠDon ations +é¢ĦéĢī èµĽ +$ th +j id +Ġ è¾¾ +ent ional +ä¸į è§ĦèĮĥ +are e +ï¼Įä»ĸ åıª +ä¼ļè®® åı¬å¼Ģ +End Time +.To Lower +_ et +éľĢè¦ģ æł¹æį® +Ġaccompan iment +åľ¨ ä¸Ģå®ļ +å¾Ĺ ä¸ĭ +In active +åı£ åı£ +欢 欢 +çīĪ éĿ¢ +è´´ çݰ +Ġparameter ized +Administ rative +attan ooga +P LEASE +rest ricted +åIJ¸æĶ¶ äºĨ +ï¼Į çĵ¦ +ãĢģ æĸ¹ä¾¿ +åıij 车 +и г +èݱ æĺĤ +Ġnucle otides +ãĢģ çŁ¥ +ĠD ementia +pl a +,: ,: +为己 ä»» +M ENU +Ġj ä +å½ĵ åħ¶ +Ġass uring +ç½Ĺ çļĦ +Ġund ist +å´ ½åŃIJ +è¦ĨçĽĸ äºĨ +[ ad +ï¼Į æ³ķå¾ĭ +ä¸İ å®ŀéĻħ +å½ĵ ä¸Ģ个 +Ġx r +åĮħ éĹ´ +åĨĽ åĮ» +ç¦ģ åĨĽ +éĶħ çĽĸ +ä¸įçŁ¥ æĥħ +ãĢĤ åĩº +楼 éĺģ +èĥĨ æĪĺ +è¡Ģæ¶² ä¸Ń +åĪijäºĭ æ¡Īä»¶ +æ·ĺæ±° èµĽ +Ġdin ers +Ġ 管 +ï¼ģ æľī +quir rel +æĪĪ å£ģ +Ġle vers +ĠK av +æŃ¤ è¡Į +ï¼Įä¸į 太 +éĵģ è¡Ģ +详ç»Ĩ äºĨè§£ +转让 ç»Ļ +èĶļ æĿ¥ +. vertex +C x +T ower +ft ed +è¿ij 身 +Ġlaw fully +è·ij åΰäºĨ +èĩªçͱ éĢīæĭ© +v irus +ï¼Į æĽ¿ +æį¢ æĪIJäºĨ +' http +S HELL +ĠClin ics +è¯ Ł +qu ires +åħ± è¿Ľ +ç§ĺ é²ģ +è¹ ´ +ĠH ARD +ĠDIS ABLE +ä¿Ŀè´¨ æľŁ +? ... +m oor +US ART +è¿İ 宾 +æ¦Ĥ念 çļĦ +T c +ĠR itz +ĠPS U +. ke +ĠC yan +é£İ æİ§ +*, * +ĠAst rology +: å°Ĩ +EM U +Ġoptim ised +æµģåĬ¨ çļĦ +追æ±Ĥ çļĦ +念念 ä¸įå¿ĺ +èµ° ä½İ +åįĹ ä¾§ +æ·· æĪĺ +åŁ¹åħ» åѦçĶŁ +ĠEsc herichia +c is +Ġal f +Ġr tc +IN I +åħī åIJĪ +.B order +建çŃij æĸ½å·¥ +Ġarth ro +Ġartic ulation +Ñ Ķ +Ġst if +è¿Ľè¡Į 交æµģ +åĽ¾ è§£ +Ġz eta +æĮī æįº +æķ¬ ä»° +为大家 ä»ĭç»į +_t ick +åĪĿ ä¸ĥ +ç»Ŀ ä¸įèĥ½ +ä¼łéĢĴ åΰ +.gener ic +Al ter +éĥ¨åĪĨ æł¹æį® +é²ľ å«© +(user Id +J y +Ġdis ables +ä¸İ åģ¥åº· +ĠCom parable +.b efore +Ġbur geoning +âĢľ Why +å·® åĪĨ +P regnancy +ĠP ods +éķ Į +å¿« æĦŁ +ä½ľåĵģ å±ķ +×Ļ× Ŀ +ä¸Ģ ä¸įå°ıå¿ĥ +缸 容 +.s ome +éļ¾ åIJ¬ +Be zier +MC I +Ġlip oprotein +Ġ èᣠ+ĠSt oke +çķ ² +Us b +表达 èĩªå·±çļĦ +ĠHard ing +ĠSnap dragon +uss el +å¾ģ æĸĩ +éĹŃ çľ¼ +Ġhind ered +" ï¼Ł +et ected +è¦ģ éĹ® +èĢģ é¹° +AT ORS +æ£Ģæµĭ 设å¤ĩ +Ġm Context +è¿ĩ ä¸ĸ +æ·± æľī +,åľ¨ æŃ¤ +ob ility +Ġinj ure +Ġharmon ics +å¾Ī éķ¿çļĦ +ï¼ĮåįĬ æĻĮ +ĠS ulf +ãĢģ èĪŀè¹Ī +建 åζ +çŁŃ è¢ĸ +çļĦå°ı ä¼ĻåŃIJ +Ġwholehearted ly +è¿Ľè¡Į æ²ŁéĢļ +ãĢĤ 临 +éŁ³ èī² +Ġbol st +Ġconjug ation +at ians +-g lobal +èķ ¨ +ĠPlay list +åIJĦ个 çݯèĬĤ +ĠPART Y +ad visor +os uction +ip zig +ï¼Įå¹¶ ç»ĵåIJĪ +è¿ĻäºĽ ä¿¡æģ¯ +а Ñĩ +(c x +åĽ½éĻħ å¸Ĥåľº +Ġsubsequ ence +åĸ» æĪ·æĻĵ +为æĤ¨ æľįåĬ¡ +æĸ§ 头 +Mur ray +ĠCPP UNIT +è¯Ļ è°IJ +ï¼Į åIJĵ +ï¼Ł \" +а ÑĪ +_g ap +Ġens ued +/ settings +S AVE +_C A +åij¨ åħ¬ +ĠMer ck +çĿ¡çľł è´¨éĩı +åīĸ è§ĨåĽ¾ +å°±æĺ¯ éĤ£ä¸ª +ï¼Į åĬ¿ +ï¼Į åĩĿèģļ +æĪ ¬ +以为 ä½ł +ĠLand mark +éĢĨåıĺ åύ +D AR +ĠSouth western +âĢĻ Connor +é¢Ħ çŁ¥ +个人 éĺ²æĬ¤ +Ġclaim ants +èīºæľ¯ èĬĤ +sl aught +ĠHom estead +çªĥ åıĸ +ĠLag oon +N ope +-se lection +该 æĢİä¹Īåģļ +ret rained +ç¦ı ç¥ī +Ġintox ication +æĸ° 京 +头 çIJĥ +çϾ 亿 +è¡Ģ æµĨ +æĮģç»Ń å¢ŀéķ¿ +Ġrid ges +Ġbass ist +] & +åį« è¡£ +æĹħ åºĹ +Administ rator +ãĢģ 讲 +æĪij æĥ³è¦ģ +_C ID +Ġhom olog +åľ¨è¿Ļ åľº +Ġdiscrim inant +( 第 += list +ãĢĤ ä¼Ĺ +ä¹± 象 +ĠPe acock +æģĭ çαçļĦ +ĠMont enegro +é©° åIJį +强 æķĮ +çľ¯ çĿĢçľ¼çĿĽ +ĠDSL R +D x +Ġ çİ°åľº +ç§Ģ åıij +åıijæĺİ äºĨ +ç²ĺ åľŁ +.~ (\ +F etcher +ãĢĤ 女人 +éĥ½ åĥı +身 ä¾§ +åıĺ æķ° +.get Selected +纯 æ°´ +ĠSub scriber +竹 马 +åĤ² å¨ĩ +_CH ANGED +Ġmic rop +ĠAk ron +Kent ucky +ĠH PLC +ep oint +ï¼Ł èϽçĦ¶ +For ums +no DB +éĢĥ çªľ +åĿIJåľ¨ æ²Ļåıijä¸Ĭ +å°±åĥı ä¸Ģ个 +ĠM ENU +å°± æľīçĤ¹ +å·¥ä½ľ ä¸Ĭ +Ġbi ochemistry +ĠC um +ç»ĵ ä¼´ +转 åĩº +ĠOp code +æľī é«ĺ +å°Ĩ å°± +ç¾İ ç¾İ +åĩł ç§Ĵ +,è¿Ļ ä¹Ł +ç½ijä¸Ĭ æĬ¥åIJį +Ġheter osexual +ĠJar vis +æīĢèİ·å¾Ĺ çļĦæīĢæľī +f iddle +Ġ å·¥ä¸ļ +ent ions +ï¼ļ ãĢİ +Ass oc +/g raph +å¦Ħ åĬ¨ +çĨĦ çģ« +ĠDETAIL S +ï¼Į å¿ĥçIJĨ +Ġp innacle +èIJ½ æĪIJ +Ġbas eman +Ġsweet est +Ġdeterior ated +æı£ æij© +å¤ľ åıī +æĸĩåĮĸ ä¼łåªĴ +-product s +X Z +pe a +ĠF unnel +å°ı 鸡 +Ġimp ulsive +表示 为 +éģĹ çī© +Ġfamiliar ize +Ġwet land +z ag +ãĢĤ åIJ¾ +_p ayment +B REAK +ï¼Į è·Į +Ġag ro +.get Size +ĠHapp en +åĽŀè¿ĩ头 æĿ¥ +å¨ģ士 å¿Į +d le +{ Name +ç½Ĺ èĮ¨ +OM UX +è½® çķª +ï½ Į +éľĩæĥĬ äºĨ +è¯·ä½ł æł¹æį® +ï¼Į æĿŃå·ŀ +ow an +ced ural +转æĬĺ çĤ¹ +j x +ï¼ļ åĮĹ京å¸Ĥ +å°±ä¸ļ æľºä¼ļ +Gesture Recognizer +Z ONE +ï¼Į 年纪 +col lege +顺 æ°´ +æĶ¿æ²» å±Ģ +说 åij¢ +ĠLi ang +ÏĨ ο +大 é¤IJ +éĩĮ æľĢ +主 å¦ĩ +è¿Ľè¡Į æİ§åζ +IC Ag +.Get Object +æľĢæĸ° æ¶Īæģ¯ +Ġaffection ate +å§ĶåĨħ çijŀæĭī +Ġ æıIJé«ĺ +ab ler +ĠH ens +Ġpr és +æĸ½ åİĭ +åħ´ åĽ½ +è¿Ļä¸Ģ å¥Ĺ +第ä¸ī æŃ¥ +ĠMac ron +åĩºå£° æĿ¥ +Ġspr ung +orp ion +ï¼Į 飦 +è¿IJèIJ¥ 管çIJĨ +ĠHOLD ER +-oper ated +è¦ģ ä»ĸ +åĪĽ ä¸ĸ +ĠZ ac +Ġspac er +, column +Ġso res +第äºĮ ä½į +oper ands +积æŀģ 主åĬ¨ +Ther mo +d ex +è§£ èᝠ+RE VIEW +Ġed x +åĿı å¤Ħ +ĠLegend ary +as one +ä¸Ń ä¸ĸ纪 +çĮ® ä¸Ĭ +ç§Łèµģ åIJĪåIJĮ +( DateTime +ĠB SP +åħ¶ ä¸Ĭ +Ġcol itis +ï¼Įä½ł å°±ä¼ļ +/s pec +Ġapost le +Ġfiref ighter +H earing +ch anging +ĠIn formed +å¹¶ä¸į é«ĺ +ãĢģæĸ° çĸĨ +ä¸į ç¾ģ +âĢľ åı¯ +ĠD IST +Ġover looks +è°ĭ çķ¥ +ï¼Įåħ³éĶ® æĺ¯ +- rem +/ icon +Ġg orge +ĠF AB +Ġpa ul +æľīä¸Ģ 份 +æĸ¹ä¾¿ äºĨ +åĪĨ åºĹ +羣 è°Ľ +ĠBar ney +ĠTw ice +Ġadd ictions +ä¿Ŀ èĤ² +æĥħåĨµ 说æĺİ +(B ig +ãĢĤå¤ļ å¹´æĿ¥ +ãĢĤ 羣æŃ£ +浦 åĮº +æĴķ å¼Ģ +elect ronics +Ġshaft s +ï¼Į éĻĦ +ĠM GM +ĠB inder +åıĪ æ²¡ +ĠApp ropri +èĦ± æİī +ĠIr win +Ret irement +&= &\ +v otes +ï¼Į éĩĬæĶ¾ +Ġso bri +ph ysics +ï¼Įå¹¶ åı¯ +_ex ist +xi om +_EM AIL +æĿ¥ä¹ĭ ä¸įæĺĵ +tear ray +ĠSt abil +Ġkn ead +ĠIsland er +ãĢģæľī éĢ»è¾ij +ĠI EC +ĠPro verbs +åı¯ä»¥æł¹æį® èĩªå·±çļĦ +Calcul ation +ï¼Į 平常 +è¿Ļ个 è¿ĩç¨ĭ +åŃ¦æł¡ åĴĮ +æ²Ļ çĽĺ +Pack aging +Ġcran berry +对 æķ´ä¸ª +äºĶ 个人 +-qu arters +.ch ain +åı°åĮĹ å¸Ĥ +èĩªçĦ¶èĢĮ çĦ¶ +- expand +Ġc log +ĠT riton +ag og +åĴĮ ä½İ +ang ana +, åħħåĪĨåıijæĮ¥ +ĠG ynec +è° Ħ +éĢļ 宵 +ï¼Įä½ł åĨį +Inter cept +è¶£ äºĭ +ç¢į äºİ +ãĢĤä»ĸ们 åľ¨ +[ cur +Ġ æ¯ı次 +ãĢĤ åıijè¡Į人 +åıĬ æł¼ +ï¼Įè¿Ļ ä¸İ +çļĦ人 éĥ½æĺ¯ +_B AR +è½½ åħ¥ +_m c +æľ¨ çļĦ +mod ifier +Ġnod al +氢氧åĮĸ éĴł +åIJ«éĩij éĩı +C aret +ĠD ire +éĽ ¹ +Ġ------------ -- +ï¼Į å¨ĺ +ĠS CM +app lied +å¿« åΰ +ĠAs us +èĦļ ä¸Ĭ +Ġh m +ä¸ĭ 身 +me asured +.l ines +mon o +Ġdb g +quire r +æĮª ç͍ +Ġc uz +Ġm é +ãĢĤ å·¦ +Ġper col +éĩį çͳ +Th ailand +ä½ı çļĦåľ°æĸ¹ +管çIJĨ 软件 +_CON N +(pro gram +çħİ é¥¼ +" Yeah +Ġg cd +du ces +ĠX er +é»ij çľ¼åľĪ +ĠCro chet +âĢľ ãĢĬ +ĠPaul ine +ä¸īåįģ ä¸ĩ +oj is +Ġdeterior ate +s ense +Ġcontent ment +èĨ Ī +Ġenthusi astically +Ġshame ful +强 éĺŁ +.d p +Ġk ad +Ġcl umsy +æĿĨ çļĦ +Ġmasc ot +å½ĵä¹ĭ æĹłæĦ§ +ĠG ri +æĬķ æ¡£ +ï¼Įå°Ĩ åĨĽ +Select ing +ĠNeuro logy +Ġs ermons +çļĦ 客人 +ä»ĺåĩº 代价 +æķĻ åĮĸ +é¢Ĩ åħµ +åĪĴ çĹķ +åĪĽä¸ļ çļĦ +æ¶µ åħ» +L android +ï Ĥ +alk ing +èĵ ģ +Ġled ge +ï¼ģ ( +å¼Ĥ äºİ +ï¼ĮçĶļèĩ³ åľ¨ +éĢļ常 åľ¨ +ï¼Į èµĽ +è§ Ĭ +ï¼ļ è¿Ļæĺ¯ +å¿ĥ åı£ +Ġz z +æŃª æŃª +_lib s +w onder +ä¸į ä¹± +_L abel +ĠHome owners +ĠTax ation +Ġbother s +upro fen +( Application +ãĢģ éĩįè¦ģ +è¿ĩ å°ı +å¿ĥ èĤł +æĥħ æĵį +æľºæŀĦ æĬķèµĦèĢħ +çĸ¼ äºĨ +éģĵè·¯ 为 +æķıéĶIJ çļĦ +V eg +we e +... ] +åģļ éĶĻäºĨ +reg exp +éĺ³ æĺ¥ +-m achine +ç»Ĩ å¿ĥçļĦ +Ġwater y +\\ [ +ĠRev enge +éĶģ éĵ¾ +, æıIJåĩº +ï¼Į èĤ¡ä»· +ad ult +aur ant +ĠTra its +ĠSub way +Box es +Phone Number +ä¸įèµ· çľ¼ +Rotation Point +ip ad +æľĪ çīĻ +Ġdef y +ĠStat ute +, å̼å¾Ĺ +N eal +çļĦ 顺åºı +âĢľ 绿èī² +AM C +çĦ¶èĢĮ æŃ¢ +æŃ£ç¡® çŃĶæ¡Ī +ç§ijåѦä¸İ æĬĢæľ¯ +, num +ĠN FS +.S leep +amed a +ĠC DF +ĠAm ir +_re ceived +ä¸ij éĹ» +äºĨ两 次 +, è¿ijæľŁ +Ġcler ks +ĠQué bec +l ung +çĿĢ ç§° +-m icro +å¿ĺ æĢĢ +( select +Ġ åIJ¦åĪĻ +ĠT MS +.p adding +è¿Ļæł· çļĦ大 +æŃĮ çļĦ +ä¹Łåı¯ä»¥ éĢļè¿ĩ +ç¥ŀç»ı çĹħ +ï¼ĮäºĮ æĿ¥ +çłį ä¸ĭ +ô ng +ĠP CC +è´¨éĩı å®īåħ¨ +ĠæĪij åľ¨ +ITH ER +æĪIJ ä¸Ģçīĩ +欢 å¿«çļĦ +åŁºç¡ ħ +æĶ¹éĢł é¡¹çĽ® +ä¼ĺåħĪ èĢĥèĻij +ĠP EN +飩 åĽ½çļĦ +ĠDar cy +Ġreign ing +ï¼Į å°Ĭéĩį +å®¶ åºĹ +å°ı ä½Ļ +Ġcar ousel +ï¼Įæľī å¿ħè¦ģ +ä¹Łä¸į ä¸Ģå®ļ +Secret ary +ãĢĤ ä¹Łæľī +ãĢģ åŁºç¡Ģ +Ġstabil izer +, çŃīå¾ħ +g arden +çļĦ æĿĥåĬĽ +è¦ģ è·Ł +ä¹ĭ èĥ½ +get ter +éĩį 天 +éĢģ èµ° +ï¼Įè¿ĺæĺ¯ åľ¨ +é£ĺ æī¬ +(st ats +ĠSax on +- June +Ġj ames +æ´» æ´» +ĠBall room +еÑĤ ÑģÑı +u il +ç®Ģ çķ¥ +æĦ¤ æģ¨ +Ġ è´Ńä¹° +ï¼Į æ¶µçĽĸ +èĩª è¾¾ +ä½ĵ å¾ģ +主 æī¿éĶĢåķĨ +æĪijæīĢ çŁ¥ +Ġscoot ers +} P +âĢľ 好äºĨ +_H S +éĹ² äºĭ +Ġvot re +游ä¹IJ åľº +Ġvow el +ĠEpidem iology +B ake +èĩªå·± 人 +_c ached +æĸ¯ æ´Ľ +ï¼ĮèĢĮæĺ¯ åĽłä¸º +ãĢģ åĨ¶éĩij +ï¼Į缴 å¾Ħ +ãĢģ人 æĸĩ +èľĪ èļ£ +åį°èĬ± ç¨İ +oc entric +Ġmet av +[i NdEx +计æıIJ æ¯Ķä¾ĭ +M ight +ĠT ories +åı¯ä»¥ ä¿Ŀè¯ģ +-m atrix +伤 åΰ +ĠAN IM +Plaintiff s +S audi +ä¹ĭ æķ° +表 éĿ¢ç§¯ +Ġins ufficiency +, ä»ĬæĹ¥ +ä¸Ń ç»§ +âĢĶ an +èĥ½å¤Ł èİ·å¾Ĺ +ä¸įäºĨ å¤ļå°ij +-sh ort +ĠGa ia +ĠÏĥÏĦη ν +- visual +h oun +al con +ä¸į éĩĬ +ä¸įæĺ¯ 没æľī +客è¿IJ ç«Ļ +Ġpredic ament +çļĦ è¿ĺæľī +ĠD ao +ec s +äºĴ 为 +yout u +Ġb ordering +åĴĮ åĬŁèĥ½ +çł § +æį¢ æĮ¡ +ĠDis posal +æ´ª æŃ¦ +Inf rastructure +èĬ± åºı +é£ŀ åIJij +ãĥ ¯ +Ont ario +Ġardu ous +ä¸į å¤ĸ +æĦ « +Ġad herent +Ġsp illing +æĹł å°ĺ +è½® åŃIJ +Ġpurpose fully +è·ĥ è·ĥ +ĠBall ard +ĠSomew here +. EMPTY +ĠR NG +std in +å¿ĥæĥħ ä¸į好 +ĠSalmon ella +ãĢģ éĩİ +书 å±Ģ +.f ilters +çĶ» ä¸Ń +åĴĮ å¦Īå¦Ī +ĠContin ues +ä¸įä¼ļ å½±åĵį +ä¹ĺ æľº +微信 å°ıç¨ĭåºı +ãĢĤ ç¨ĭ +æłĩ ä»· +åĩºçīĪ äºĨ +_ex e +/ ext +j ak +ãĢĤ åĶī +erm ission +è´¨ åŃIJ +åĨ² åħ¥ +åħ¨éĥ¨ 被 +_MAN AGER +S åºĹ +çļĦ åIJ¸æĶ¶ +ä¸Ģ æĦı +Ġr ue +æĿ¥ ä¿ĿæĬ¤ +å°± 羣çļĦ +çľ¼ çĨŁ +Ġund one +BB B +éĥ½ å¸ĮæľĽ +L adies +Ġp st +ĠCh amp +æĿ¡ 第 +æĶ¯ æµģ +æ£Ģ è§Ĩ +_sh utdown +Ġuns ustainable +ĠâĪ ĩ +涨 äºĨ +ĠBarcl ays +< ID +åĴĮ 被 +å·² å©ļ +çļĦä¸Ģ 段æĹ¶éĹ´ +Ġnood le +ĠW nt +åĮ į +æľ¬ æĦı +åĩ» æºĥ +éĴŁ è¡¨ +Ġrecogn ises +ç¿» èħ¾ +éĥģ éĩij +S creenshot +Ġbe gg +ĠJ V +_P ULL +读 åĩº +- account +- oxid +/ apis +\ Console +Ġs int +ĠD umps +è¿Ļ 两年 +og rad +ç͵ ä»· +ĠGar bage +Prem ier +Ġplasm ids +æĶ¹åĨĻ åIJİçļĦ +_ plugins +ï¼Į æīŃ头 +ãĢĤ ç¥Ŀ +AL Y +add ock +Del imiter +ãĢĤ æ¢ħ +per iment +对 åŃ©åŃIJçļĦ +Ġquot as +翱 ç¿Ķ +åľ° æĿ¿çļĦ +Ġ: ] +.d rag +åħŃ çĤ¹ +App Data +çī©åĵģ çļĦ +梦å¯IJ 以æ±Ĥ +âĢĿ 以åıĬ +åΰ ä»Ĭ天 +å·²ç»ı è¶ħè¿ĩ +Ġswe eps +ä¸īè§Ĵ æ´² +çļĦ ç͵åİĭ +id or +宣 åΤ +éĵľ éĴ± +ä¸įå¼Ģ çļĦ +Appe ar +èĦļè¸ı å®ŀåľ° +" B +ï¼Ł "" +äºĨä¸Ģ å°ı +UM AN +æ´ģ éĿ¢ +Host ed +æľºåĬ¨è½¦ 驾驶è¯ģ +社 çļĦ +åįĬ æĪIJåĵģ +ä½łçļĦ çĶŁæ´» +ĠHand made +çŃīåIJĮ æĽ¿æį¢ +.mult iply +Ġ ç»´ +Ġcon ical +Ġwe ep +ss ss +æ¨ ¾ +Line Number +åį§ åºĬ +, ä¿ĿæĬ¤ +T esla +pl atin +eg l +åĴĸ åĸ± +re au +ĠB uf +Ġob fusc +Pres ence +é¢ĨåŁŁçļĦ åºĶç͍ +qu eries +åĴĮ åĶIJ +ĠOr well +AB L +/d t +ĠAp ocalypse +çĬ · +äºĮåįģ å¤ļ +$ b +- IV +ä¿¡ æľį +æīĭæľº åı·çłģ +Ġrat ified +åĽ¾åĥı å¤ĦçIJĨ +J W +he aring +f iled +Ġst aking +æĿ¥ èİ·å¾Ĺ +au gment +Ġbre eder +ĠEX EC +Ġuns us +.V ISIBLE +Ġf ists +est anding +ãĢij , +ĠLoc ate +ĠAnt hem +ï¼Įèĥ½ 让 +ï¼Į åıĸæ¶Ī +ĠB X +ä¸įå¾Ĺ èĢĮçŁ¥ +ĠDor is +G ifts +ï¼Į 绿èī² +æľĢ æľĢ +)) ^ +Ġwh ispers +Ġbl uff +ĠC PL +å¼ł çĦ¶ +IG IN +éĹ» ä¹ĭ +豪 è¿Ī +chell es +Hex String +Ġmin ima +åıijçĶŁ ä»Ģä¹Ī +ï¼Įä¸įè¿ĩ åľ¨ +ĠHer cules +ï¼Įåıį ä¹ĭ +ä¸ŃåĽ½äººæ°ij éĵ¶è¡Į +ĠC ortex +è·¯ èĻİ +file path +è´« å¯Į +/man ual +çİĭåħ« èĽĭ +æ°Ķåĸĺ åIJģåIJģ +Ġ èĭ±è¯Ń +Ġr ye +åĪ« åħĭ +åħ¬äº¤ 线路 +è¦ģ éĿł +Ġjust ifies +Ġserv let +ï¼Į对 åºĶ +åĪĿå§ĭ æĬķèµĦæĪIJæľ¬ +ĠEsp resso +- html +Ġa pril +ç©Ĩ éĩĮ尼奥 +J G +ãĢĤ æĵħéķ¿ +两 æĹ¥ +/c ard +åľ° 说çĿĢ +åIJİ ç͍ +èĦ ² +ĠR AS +au k +æĹ© çŁ¥éģĵ +Ġcaus ality +交æĺĵ æĢ§ +Ġtransfer able +_list ener +ç¡®å®ŀ æľī +Ġsuppress es +Interpol ator +è²Ĥ èĿī +Ġcondens ate +L ever +æľī人 ä¼ļ +_COMP ONENT +Ġphosphat ase +ĠP antry +åIJİ ä¸įä¹ħ +Ġ` - +- ness +Ġu reth +Ġag itated +ĠCal ories +åIJįåŃĹ çļĦ +Ġneut rons +ç»´çĶŁç´ł B +æī©å±ķ åΰ +Americ ans +Ġ æĺ¯ä¸Ģ个 +Ġh osp +æĮģ ä¹ĭ以æģĴ +æ»ij éģĵ +å°Ĭ è´µçļĦ +ess ler +av vy +ĠDeb it +ĠFerdin and +ï¼Į éĺħ读 +没æľī æĹ¶éĹ´ +_c aps +ag reement +.c rypto +Ġcrim son +Ġelev ators +ĠGlass es +Ġ åģ¥åº· +ï¼Į å¹½ +ĠO rr +éĿĴ çļĦ +Ġsea weed +Bank ing +Ġextr usion +; k +Ġme hr +太 åı¤ +AD R +对äºİ ä¸Ģ个 +Ġsym phony +ĠChall enger +ï¼Į æĢª +Ġp oking +Ġrem over +ï¼Įåľ¨ ä½ł +rang ler +A head +Ġ åıijå±ķ +Ġg arant +è¢ ¤ +çľ¼ çıłåŃIJ +å¼Ĥ 彩 +æ´¾ é©» +æĦıå¿Ĺ åĬĽ +ãĢĤ åIJĥ +Ġv v +åģļ èıľ +æīĵ åŃĶ +Ġed gy +éĹ¹ äºĭ +è¿ľè¿ľ ä¸įå¤Ł +éªļ åĬ¨ +An on +æĿİ ä½³ +æ¿Ģ å¢ŀ +æĶ¿åºľ 对 +é¥Ń é¦Ĩ +f ld +éĩı åĬĽ +å¥Ĺ ä»¶ +ĠFore nsic +ĠRich ie +_CL R +Ġbuff ering +羨 å·´ +isen berg +Ġè¿Ļä¸Ģ åĪ» +P AC +ãĢģ å¼ĢæĶ¾ +对 åIJ§ +æĹł åŀł +che f +Load Balancer +ĠCard iac +Ġenv oy +_ OD +s rv +er b +æĺ¯ æīĢæľī +ib et +次 éĥİ +强 åģ¥ +Trans parency +.comp iler +ĠSovere ign +ade v +ç²¾ æ·± +ĠInd icate +PS A +诸 天 +åĩĮ 天 +_AC EOF +fu els +Ø ¥ +æŀģ æľīåı¯èĥ½ +( IM +c box +h ana +Ġan ode +ä¸į ä¹° +Time Zone +ii ii +éĥ½ä¸į å¦Ĥ +ï¼ĮåįĹ å®« +th r +ĠBy e +æľŁéĹ´ åĨħ +èµı å¿ĥæĤ¦ +æķ² è¯Ī +Ġ× © +_ass oc +- appointed +Ġt inct +çĽ Ĥ +è·¯ ç«Ļ +å§Ķ ä»» +大ä¼Ĺ çļĦ +# set +ĠS OD +Ġpro clamation +est ors +为 ä¸ī +æ°´ çĶŁ +被 åΤ +ĠEN ERGY +as ley +çĥŃ é£İ +ä¹Łä¸į æĸŃ +aur i +mark down +åĽŀçŃĶ äºĨ +Ġportray ing +ĠJagu ars +å¹´ æĪIJç«ĭ +å°ij æł¡ +æģ¨ æģ¨ +çł´ç¢İ æľº +çļĦ 西 +è¿IJåĬ¨ éŀĭ +ç»ı常 被 +Ġmal aysia +Adjust ment +ĠM unicipality +æĻļ æ¸ħ +_R ST +æľīä¸Ģ éģĵ +ĠTerm ination +@ h +çļĦæ²»çĸĹ æĸ¹æ³ķ +ам и +çªĹ åŃIJ +æĭĽèģĺ å²Ĺä½į +Ġmeta verse +.Sp ring +ĠP ang +ãĢģ åĴ¨è¯¢ +Ġal log +æĿ¡ æĿ¡ +é¾Ļ åįİ +åĬª å°Ķ +诺 æĽ¼ +Suggest ion +Ġ 请æ±Ĥ +è¿ĩ åĩłå¤© +ĠY ing +åĬĽ æīĢèĥ½ +èĢIJ åĬ³ +Ġdeterior ating +ĠT id +Âł å¤ı +åľ° å¾Ģ +èݲ èĹķ +åħ¬å®ī åĪĨå±Ģ +æĺŁæľŁ ä¸ī +_me asure +çĶ Ń +ĠL ash +å¼ķ è¿ĽäºĨ +/p rivacy +ĠMet allic +Ġ çαæĥħ +ro i +ãĢĤ å¿ħé¡» +ãĢĤ æ¯ıä¸Ģ个 +ve ction +ĠS rin +ĠH arness +æĭī ä½ıäºĨ +ä¿Ŀåģ¥ é£Łåĵģ +Ġdisreg arded +æķ°æį® ç»ĵæŀĦ +ä¹Łæĺ¯ åįģåĪĨ +Ġ 说åΰè¿ĻéĩĮ +Ġpre cluded +ĠPass over +ç§ģå®¶ 车 +' id +* out +ï¼Į çĿ£ä¿ĥ +女 娲 +ĠMc Lean +ĠSoc ieties +ĠCH F +æ¶Īè´¹èĢħ 对 +_emb eddings +Ġm oll +ic rous +rodu ces +æľºä¼ļ äºĨ +Ġge othermal +ä¸įåľ¨ å®¶ +è´ŁåĢº çļĦ +, åѦä¼ļ +- Path +ãĢĤ 带çĿĢ +ä¸Ģ çݯ +ĠM afia +åľ¨ åIJĮ +天 èĿİ +ä»Ķç»Ĩ éĺħ读 +ĠFed ora +Ġ 设å¤ĩ +æŃ£ èī² +å°±æĺ¯ è¿Ļæł·çļĦ +äºĮåįģ ä¸ĸ纪 +Ġhyd rate +B ryan +Ġ\ |\ +åķĨ çķĮ +Ġpar alyzed +Ġmicro tub +B ry +Ġn ods +åij¨ æĿ°ä¼¦ +Jul ian +åľ¨ ç»ıæµİ +çī¹ æĸ¯ +_C HA +und en +æĢ¥ å¾Ĺ +æĢĿæĥ³ ä¸Ĭ +åį±éĻ© åĮĸåѦåĵģ +Ġcust odian +Neg ot +om od +ä¸į æīĵç®Ĺ +Ġch ipped +te ga +å¹³ ä»· +ĠAnd hra +ser ious +ãĢĤå½ĵ åľ° +壳 ä½ĵçļĦ +广åijĬ çļĦ +ĠJean ne +ĠFD IC +H ighest +b ios +ï¼Į å±ķå¼Ģ +ï¼Į 赫çĦ¶ +Ġn col +ĠSp ots +Ġcut ters +å¥ĸ èµı +å°Ŀè¯ķ çĿĢ +æķ´é½IJ çļĦ +ĠPurs uant +. images +V ern +t weet +ĠTr ilogy +æĭį åĩº +esh oe +bo a +-sh ift +R an +Ġpre historic +aj u +ç§° 龸 +Ġcod on +Ġk B +ĠGe ometric +Ġfast ened +æIJŃ åľ¨ +ĠAff iliates +STR ICT +M and +ä¸į çĶŁ +ç͍ åħµ +åIJİ å¸Ĥ +åħ¶ä»ĸ å®ŀæĸ½ä¾ĭ +[ http +ĠE LECT +.st age +ow icz +Ġdem oc +çķĻ äºĨ +ç§ijåѦ çłĶç©¶éĻ¢ +ï¼Įå·² çĦ¶ +ï¼ĮæĽ´å¤ļ çļĦæĺ¯ +Ġproverb ial +Ġmisfort une +> N +v ian +yp ress +çIJĥ éĺĢ +åŃ£ é£İ +ó l +çĽ¸å¯¹ è¾ĥä½İ +.mod al +, åζå®ļ +Ġam assed +ä¸ĥ åĪĨ +employ ees +ï¼Į轻轻 çļĦ +Ġ第åħŃ èĬĤ +D ic +åĴ Ĥ +ä¹ĭ æīį +ä»İ 大 +è·¯ é£ŀ +Cor relation +Iter ations +åĴĮ æľªæĿ¥ +åİĭ ç͵ +æµĭè¯ķ ç»ĵæŀľ +ï¼ĮåIJĦ ç±» +ãģĭ ãģ£ãģŁ +Ġdenomin ations +çļĦ èĦĸåŃIJ +为 é«ĺ +èĥ½ èİ·å¾Ĺ +Ġsa usages +ï¼Įåľ¨ 没æľī +å§Ķåijĺä¼ļ åī¯ä¸»ä»» +æıIJéĨĴ ä½ł +ĠP MS +æķ°æį® ç»Łè®¡ +èĽ İ +ï¼Į使 ä»ĸ +{l st +s ites +Ġdet ections +åĨ² 浪 +Ġsitu ational +FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF +Ġad iab +é£İ å°ĺ +èĥľ åĩº +ĠEm ails +Ġshr unk +éĺ¿éĩĮ äºij +ĠTob ias +ä¸Ģ æĸij +å¾ ĩ +åIJ¸ åĬĽ +ĠChamber lain +å¼ĵç®Ń æīĭ +Franc is +/ non +ï¼Į åĺ´å·´ +ac illus +ï¼ĮæĪij æĢķ +é¦ĸ æĹ¥ +çIJĨ论 åŁºç¡Ģ +ĠJama ican +lo res +社ä¼ļ ç»ıæµİ +ä¸ĭéĻį åΰ +æī¯ äºĨ +⣠© +( rows +ĠC app +String Ref +ĠÐ £ +Ġshort listed +oph il +èĩ£ æľį +é£ŀæľº ä¸Ĭ +H uge +R AP +_ Query +Ġf andom +ĠT uscany +get User +ï¼Ī F +çī© æĿĥ +åĿļ å®ļäºĨ +Ġè¿Ļ 让 +ĠForm ats +_ ht +um ptions +ie ver +å¸Ĥ éĩĮ +æ¸ħ 鼶 +ç»Ħç»ĩ äºĨ +表示 äºĨ +Ġang st +Ñĥ б +R aid +个 ç³ĸæŀľ +å¿ĥ 满æĦı +ne b +è§ģ ä¹ł +é»ij åıij +两大 ç±» +. ubuntu +j av +举 举 +åİĭåĬĽ ä¸ĭ +ĠAssess ments +ĠD ose +åѦ åΰçļĦ +宫 åĨħ +_re ward +ĠWil helm +( Client +ï¼Į 绣çѹ +å¼Ģ çģ« +å·¥ä½ľ çĬ¶æĢģ +Ġequ ator +pkg dir +çļĦ å¨ģèĥģ +ĠM ilit +è¿ĩ å¢ĥ +ĠV y +eth anol +èĮ¶ é¦Ĩ +ĠGrand pa +äºĨ她 ä¸Ģçľ¼ +ĠI MS +浸 æ¸į +m ilk +Ġl or +os its +çľĭ ä¸įä¸Ĭ +ï¼Į éĩĩ +ĠW ishes +没 åľ¨ +Ġcr anes +é½IJ çİĭ +åıĺå¾Ĺ å¾Ī +- reading +Ġsing let +Ġmock s +( SD +Ġdis mal +åıĪ åĽŀåΰäºĨ +-comp lete +交 æĪ¿ +é¦Ļ港 çļĦ +# . +ä¸Ĭ ä¹ĺ +Ġref ute +Ġ) -> +ä¸įèĥ½ 被 +Pr incess +,ä¸į æĥ³ +ĠJo ining +Cost s +Hu gh +Ġsouven ir +Ġup ro +åĩł çϾä¸ĩ +åĽĽ 驱 +ĠCol legiate +ĠAll ies +ĠDef ining +_att ention +Ġha uled +æĿ¡ æııè¿° +ä¾ĿçĦ¶ åľ¨ +åįģåħ« å²ģ +Ġcord less +éĹªåħī çģ¯ +ç»ĵæŀĦè¿Ľè¡Į æııè¿° +p is +at ron +ĠE ileen +磨 è¹Ń +åĽĽ èµ· +æ¸IJ åıĺ +éĺ´ æ°Ķ +å¿ĥä¸Ń æľī +å®īéĿĻ åľ° +åµ´ æŁ± +O SE +am is +State Changed +æĮģæľī å¾ħåĶ® +Ġ" âĻª +ï¼Įä½Ĩ 表达æĸ¹å¼ı +导 åĽ¾ +èĥĮ 对çĿĢ +-l imited +æľīæīĢ ä¸ĭéĻį +溢 æµģ +åŁºå±Ĥ åħļç»Ħç»ĩ +å½Ŀ æĹı +_ Key +d rug +大 åĸĿ +ä¸İ 设计 +_t ot +ĠWood land +Scal ed +I x +Q H +ab as +æĿĢ çģŃ +第ä¸ī 天 +,ä¸Ģ è·¯ +Ġprefer ring +ï¼ĮåĪĻ çĽ´æİ¥è¿Ľè¡Į +éĢĤå½ĵ æĶ¹ +èĢķ ç§į +åĩºä¹İ æĦıæĸĻ +Ġend anger +D rivers +ä¹ĭ ä¼Ĺ +å¦Ĥ åIJĮä¸Ģ +Ġaf ar +SQL ite +Ġbacks plash +åĺ¶ åĵij +ĠP helps +(c r +ï¼ĮåĨ² çĿĢ +ä¿ĥéĶĢ æ´»åĬ¨ +å·¥ çļĦ +Ġburn ers +åľ¨æĪij 身边 +ï¼ĮäºĮ èĢħ +ä¸Ģ线 åŁİå¸Ĥ +åįµ å½¢ +ãģķ ãģĦ +B EN +Ġth rives +ï¼Ľ ä¸İ +Th rown +å¤ĦçIJĨ åIJİçļĦ +ĠBr agg +Weight ed +. region +es que +iz io +éķ¿ ä¹IJ +ĠQ in +Ġä¸Ģ ä½į +Ġnorm ality +çµ ¶ +Ġmig raines +ãĢģ缴 è¾ĸå¸Ĥ +Ġoft entimes +ĠP orn +è¿ĺ 设æľī +è§Ĩ èĢĮä¸įè§ģ +et in +ĠC riterion +群 ä¸Ń +ãĢĤæĪij çİ°åľ¨ +Ġeyes ight +bi otics +Med icare +æĴĴ ä¸Ĭ +èĩªä¸» åĪĽæĸ° +Ġoverhe ating +éĵģ èĬ¯ +æĥ¨ æ·¡ +!!!! ! +ĠH eter +uck les +è¡Į å¾Ħ +éĺ² é£İ +Ġmodern ity +æ½® å·ŀ +ï¼Įåīį æľŁ +ĠInsp ire +ĠM CI +æĸ¹ å·® +Ġser pent +Ġfan atic +ĠMa ureen +举 åIJ´ +æĤ¨ æĺ¯ +课 çļĦ +ĠSim ult +Ġresemb led +Ġengra ving +ï¼Į æ»ļ +åİ» äºĨè§£ +_s r +使ç͍ 该 +èĹ ľ +æĶ¿æ²» ç«Ļä½į +ĠCap abilities +. tech +< k +£ ¼ +ãĢģ åĽŀçŃĶéĹ®é¢ĺæĹ¶ +Ġdis integ +ĠAl k +.R ole +Ġrepro gram +åĭī åĬ± +ef orm +åıĸ åħ¶ +-d eductible +ï¼Įéĥ½ éľĢè¦ģ +ĠSte iner +Ġking doms +.z end +.X ML +Ġlad en +ĠRespond ents +Ġm ites +ch all +ĠK ry +Ġl Ãł +ch uk +ĠD ri +å¾Ī éĢĤåIJĪ +çļĦæīĭ ç»Ń +bro ther +ï¼ļå¦Ĥæŀľ æł¹æį® +Ġ äºĨè§£ +ï¼Į åIJĪåIJĮ +am aged +âĢĿ åĽŀçŃĶéĹ®é¢ĺ +èĢģ è¿ľ +ãĢĬ åı²è®° +æĶ¶ åIJ¬ +ĠIs olation +ä¸Ŀ çĵľ +w inds +ä¸Ģ åħĥ +æĿĢ æķĮ +CE P +Ġfib rous +Ġassass in +Ġsuper position +ï¼Įåħ¨ æĺ¯ +ĠBreak s +_ ", +ï½ Ī +åįķåħĥ æł¼ +åIJİæĤĶ äºĨ +.S ample +War ren +ï¼Įå°½éĩı 丰å¯Į +ro z +âĢĿ çļĦ人 +æľª 满 +Ġpay er +ĠID irect +-M uslim +å¯Ħ äºĪ +ï¼ ¿ +åį´ è¿ĺæĺ¯ +ĠAcc urate +Ñĥ ж +anal og +åŃº åŃIJ +Ġo auth +ãĢĤ ä»Ģä¹Ī +导 è¯Ń +Ġes ports +OL A +èħ¿ çļĦ +åĽłç´ł å½±åĵį +re ys +ï¼Į èĦļä¸ĭ +Ġwe eping +ï¼Ľ 第ä¸Ģ +ĠEx amine +èι èα +ï¼Įæīĭ ä¸Ĭ +ĠChrom ium +åĪĨ段 æııè¿° +ãĢĭ 对 +åĽłä¸º æĺ¯ +ä½Ļ ç§į +åĿIJ çļĦ +.T race +èIJ¥ä¸ļ åĪ©æ¶¦ +å¾Ĺ åİī害 +Ġsc ree +IF ont +èĭ±éĽĦ çļĦ +ï¼ĮèĤ¯å®ļ ä¼ļ +åıĤèĢĥåĨħ容 å¦Ĥä¸ĭ +ĠAthen a +K ES +ent ious +âĢĿ æĹłæ³ķåΤæĸŃ +Ġsing apore +Ġbar ber +,åı¯ è§ģ +æ°Ķ象 å±Ģ +é£ŀéĢŁ åıijå±ķ +Ġcol lo +-b rowser +ĠNot ch +åľŁåľ° çļĦ +é¤IJ饮 ä¸ļ +è¯Ńä¹ī ç»ĵæŀĦè¿Ľè¡Į +Ġt ink +åľ¨ ä¸ŃéĹ´ +ãĢĭ æĹ¶ +æĦıæĢĿ ä¿ĿæĮģä¸Ģèĩ´ +åºĶä»ĺ 账款 +è¯Ģ çªį +" åıĤèĢĥåĨħ容 +âĢĿ ç»ĵæŀĦè¿Ľè¡Įæııè¿° +åĪĨ 许 +æĿĢ ä»ĸ +(M andatory +表述 æľī礼è²Į +ãĢģå¦Ĥæŀľ åĨħ容è¾ĥå¤ļ +ï¼Įä¸Ķåľ¨ åĪĨè¿° +âĢĿè¿Ľè¡Į éĢĤå½ĵæĶ¹ +æĪĸåĪĨ æĿ¡æııè¿° +ï¼Įä¸Ķ使 æĶ¹åĨĻåIJİçļĦ +"æł¹æį® åıĤèĢĥåĨħ容 +% + +ï¼Į åĨľ +ãĢģ ä»» +em akers +èĢĮ åıijçĶŁ +ĠAl ta +éļ¾ äºİ +Ġpret rained +_per missions +Ġenumer able +Ġmemor abilia +ĠLimit ations +el age +ä¸į ä½İ +ĠD ER +çľ¼ éľľ +åIJĥ 个 +润 èĤº +æİ¥åıĹ æ²»çĸĹ +Me chanical +è±¹ åŃIJ +Ġfor age +她 è¿ĺæĺ¯ +å®ŀéĻħ éĹ®é¢ĺ +æİ¢ éĴĪ +ros ive +^* _ +))/ (( +( obs +Ġst opp +ĠO ll +è§£ äºĨ +Ġtext area +æ·· åĬ¨ +Ġunve iling +æĺ¯ åħ·æľī +ä¸į æĢª +:: : +åĨľæĪ· æķ° +Ġ 许å¤ļ +Ġ( ... +но е +, åı¯èĥ½æĺ¯ +Ġhas hing +没æľī éĶĻ +Ġcustom izing +Log Level +åīij 客 +绣 èĬ± +ãĢĤ 康 +ĠM EG +åıij èµ·äºĨ +ĠK ettle +ä»İ ä¹ĭ +éĴ¢ åĮĸ +åīª è£ģ +ï¼Į åĺ´åĶĩ +æĸĩ åįİ +å·§ å¦ĻçļĦ +Ġdimension less +_IO CTL +# " +G am +G len +R ocket +ĠL HS +ĠG X +æ²¹ åĴĮ +Un available +Ġ大 æ¦Ĥ +K ir +uss ing +ï¼ĮèĢĮä¸Ķ ä»ĸ +Aut umn +Does n +Di abetes +ĠART ICLES +Ġdiplom ats +å°ı åŃ¦æł¡ +Ĉ ćĈ +Âł å°±åľ¨ +Ġli ens +.c ar +ĠPh y +çªģçĦ¶ åıijçݰ +, è®°å¾Ĺ +O z +æİ¥ ç¼Ŀ +ä¿Ŀ 级 +Ġback ers +红 æĻķ +åıĸ代 äºĨ +Ġr k +åĴĮ ä»·å̼ +å¸Ī çĪ· +ĠPer uvian +-A ldrich +çļĦ主 æĮģ +D ress +.f unctions +è¡Ģ æ°Ķ +Ġsol l +ĠPat ton +Ġover board +éĺ² éĿĻç͵ +è¯Ĺ çļĦ +åį· å¸ĺ +ad ish +Ġ" =" +äºĶ çĤ¹ +æķ°æį® æºIJ +.set Title +éĵģ æĿ¿ +Cr unch +B ench +Ġ 满 +Ġkn itted +åĩı æ³ķ +å¾Ĺåΰ ä¸Ģ个 +èª į +åĩī äºŃ +ï¼Įè¿Ļæĺ¯ ä»ĸ +Server Error +ãĢģæĸ° èĥ½æºIJ +ç¾İ容 éĻ¢ +ĠProdu ced +ĠB oz +Res idents +çľģ éģĵ +æ½ĩ æ½ĩ +Ġorthodont ic +-burn ing +Ġ ____________ +ä½ł è¿Ļæĺ¯ +å¹¶ æıIJä¾Ľ +ä¿¡æģ¯ ä¸İ +Ġenc ro +.set Image +æĸĩåĮĸ çĶŁæ´» +Ñģ ли +å®ħ åŁºåľ° +Ġswim mer +& s +: key +l vert +ĠE TS +åŁİ æĬķ +åĮ» åĺ± +-d estruct +å¾· æĽ¼ +Ġsqu amous +ï¼ĮæĽ´ 为 +Ġbubb ling +Strateg ies +S pl +âĢľ çİĭ +.m aster +Ġsl ur +ä¸ĬäºĨ 车 +åĴĮæĪij ä¸Ģæł· +ç͍ éĴ± +ï¼Įä¸Ģ åıªæīĭ +åŃĹ è¿¹ +ä¸ĥ åįģäºĮ +ä»Ģä¹Īæł· çļĦ人 +ä¸Ģ ç¬ijéģĵ +- ST +def ining +çłĶ ä¹ł +Ġanecd ote +/ logo +al ics +Ġnew bies +ï¼ģ è¦ģ +éĢł 访 +ä¼Ļ åĦ¿ +å¹´ æĺ¥ +æĪIJ æ´» +éĥ½ æĬĬ +溪 åİ¿ +ĠW arcraft +Sc ar +Ġextrem ism +Ġintest ines +- enter +c ow +Ġ ãģ® +å¤ĸ éĵ¾ +ç«ĭ ä¸ĭ +Ch arts +å±ħä½ı è¯ģ +èħĬ æľĪ +ath ons +è´¢æĶ¿ æĶ¶åħ¥ +èĤ¾ èĻļ +.text ure +R ap +_EX TERNAL +Ñĸ д +ï¼Ľ åħ¬åı¸ +ĠK H +åķ ī +æĢ» ç½² +yn ski +鸡 æ¯Ľ +âĤ¬ âĢľ +ĠBuff et +B UY +ĠS aves +La ure +ĠBa um +å½±è§Ĩ ä½ľåĵģ +Ġ èĥ½å¤Ł +ï¼Į éĩijèŀį +çļĦ åıĮçľ¼ +Ġg nc +ĠW ARN +对 ç¾İåĽ½ +ĠTest ed +AX B +ä¹Łå°± ç®ĹäºĨ +æ¶Į ä¸Ĭ +Ġ å²ģ +_g p +Ġpiece wise +is empty +ภ· +Ġε ν +好 åѦ +å¸Ĥ åİ¿ +èᝠ䏏 +æ¹Ľ æ±Ł +è¯ģå®ŀ äºĨ +) }^{ +Ġman or +缴 çϽ +çĨŁ çĿ¡ +ê n +Ġcolonial ism +z ap +ï¼Į çϽèī² +æŃ£ 轨 +仪åύ 仪表 +è´± 人 +çĭĻåĩ» æīĭ +-incre asing ++ ^ +l anguages +var rho +éĩį大 é¡¹çĽ® +æij§ æ®ĭ +å°ijæŀĹ å¯º +b ir +Ġ ç½ij +Ġ å±Ĥ +_d ocs +ï¼Įå®ĥ ä¼ļ +Ġcam ar +ĠCompl aints +åIJİ çĽ¾ +IN CT +åĮ»åѦ è§Ĥå¯Ł +Ġtip o +_PI PE +æľīäºĽ å¥ĩæĢª +硬 çĶŁçĶŁ +fe as +ĠPear ce +å¾Ĺä¸į åģ¿ +ï¼Į å½°æĺ¾ +ĠC MA +bl ind +Ġrespond er +obacter ium +Numer ous +\ M +Ġqu its +eb el +yl im +åĪĢ éĶĭ +çıį 妮 +åı²ä¸Ĭ æľĢ +为 人æ°ij +æĭĽ èĢĥ +á¹ £ +Ġhast ily +-Semit ism +ãĢģ åºĶ +ãĢģ åĴ³åĹ½ +çļĦæĹ¶åĢĻ ä¸Ģå®ļè¦ģ +_sh adow +åĴĮæĪij ä¸Ģèµ· +æĶ¹ç¼ĸ èĩª +' ` +, æIJŃéħį +ä½ł åĪļæīį +ï¼Į对 åIJ§ +ford shire +æĤ¬ 空 +Ġtort illa +Ġcl inging +Ġun protected +Ġcoll ars +á v +Ġorth odox +ĠRan cho +ĠG ad +)) : +éĢģ ä»ĸ +Ġlinked in +ĠBus ch +âĢľ 请 +.Try GetValue +op rene +ĠX Path +') \ +ï¼Į常 å¹´ +Ġlent ils +Ġhe res +ain ment +Ġev okes +ĠCAP ITAL +n ement +.g son +ĠAng ola +Ġnic est +ï¼Įæĺİ æĹ¥ +æĢ» æ¯Ķ +è¾¹ 沿 +Ġap ocalypse +Ġpilgr ims +at ypes +åįģ ä¸ĢçĤ¹ +å¤Ħ æŃ» +åįĬ è·¯ +ä¸ļåĬ¡ åijĺ +Obs ervation +ĠCred entials +Ġ åī¯ +ĠB az +ass ie +Ch r +ï¼Įåıª æĥ³ +çĶļ è¿ľ +åįķä½į åĴĮ个人 +.put Extra +n oc +åİ» åŃ¦ä¹ł +认为 è¿Ļæĺ¯ +â Į +ost atic +ber os +ãĢĤå¦Ĥæŀľ åľ¨ +.Des erialize +-trad itional +** ãĢĤ +åıij éľī +æijĬ ä½Ļ +æ¯ĶæĭŁ çļĦ +ĠEvangel ical +_ enter +}} }{\ +Celebr ity +ĠP ell +对 åħ¶ä»ĸ +Ġ\ \[ +æ¶ ª +ĠMir iam +Ġgrat uit +ï¼Įå¹¶ 使 +ç³ĸ åĪĨ +å¦Ĥä¸ĭ æŃ¥éª¤ +» , +社 åijĺ +äºij å¹³åı° +ãĢĤæĪij ä¸įçŁ¥éģĵ +åĵĢ ä¹IJ +lene cks +ä¸Ńåħ¨ä¼ļ ç²¾ç¥ŀ +Ġco ef +åįİ ç¾İ +ĠER K +亦ä¹IJ ä¹İ +ĠS phinx +Ġsh ove +çĿĢ è¿Ļ个 +éĻĨç»Ń ç»Ń +æĪij们 åħĪ +表 éľ² +æĵį ç»ĥ +ãĢĤä»ĸ 表示 +ä¸įåĬ¨ 声èī² +æĸĩåĮĸåĴĮ æĹħ游 +ĠB ourn +åŃ£ æĬ¥ +è¡¡ éĺ³ +ĠLo vel +ĠNav igate +ä¸į æĶ¶ +èµ· åħµ +Ġplan ter +è°Ī ç¬ij +驱åĬ¨ ä»¶ +^+ $ +St rike +Ġdef amation +Con sequently +é¦Ĩ èĹı +èĤĮ çĺ¤ +( Element +av ens +ä¸İ èĩªçĦ¶ +åIJij è®°èĢħ +Ġhot line +ä¸įå¾Ĺ 转载 +æĸ¹æ¡Ī ä¸Ń +éŁ³ä¹IJ èĬĤ +ï¼Į éļ¾å¾Ĺ +çļĦ æĿ¥è¯´ +ãĢģ ç»Ļ +çĺ ´ +Mer chant +ĠC ah +trans pose +èĪŀ ä¼ļ +Ġpsych osis +B att +Ã İ +çļĦ 说æĺİ +Ġre CAPTCHA +ub arb +æĬ± åĽ¢ +ĠShould n +éĤ£ è¾Ĩ +Ġget Class +Ġback story +ï¼ĮåIJĮæĹ¶ åıĪ +竣工 éªĮæĶ¶ +Ġb mp +Ġl da +Ġover run +ĠInd uction +Ġconsider ate +注æĦı çļĦ +æ¤įçī© åĽŃ +对å¤ĸ æĬķèµĦ +大 æķĻåłĤ +Ġab iding +Ġgra ppling +Ġo sg +çļĦ çĽ¸å¯¹ +ĠG rap +æĭī å§Ĩ +çĶŁäº§ æĬĢæľ¯ +ä»ķ éĢĶ +P eg +ä¸ī åľ° +Ġextension Registry +Ġµ M +Ġimpover ished +ä»İ严治 åħļ +j sp +ï¼Į æĢģ度 +ãĢĤ 忽çĦ¶ +Ġunder represented +ï¼Įå°± å°Ĩ +Ġpar anoia +ĠSl ater +Ġrein vest +Ġindemn ify +Ġcanc elling +v ich +se i +end ium +è¿Ľè¡Į æµĭè¯ķ +ä¸ĵ æŁľ +ï¼ĮåIJĦ 大 +Ġski pper +ĠDynam o +Ġrept iles +ĠLibr arian +ï¼Į åĮħè£ħ +æīĢ æĸĻ +没æľī ä¸Ģä¸Ŀ +ç»ĵ è¯Ń +é» ľ +éĩĬ çĦ¶ +ĠDE FIN +ï¼Įå¤ļ åįĬ +Ġdisp ense +Ġmaxim izes +å®ļæĹ¶ åύ +Ġse ep +ost i +çľĭ åģļ +Ġmon op +.W in +年被 è¯Ħ为 +éĻªåIJĮ ä¸ĭ +å¼ķ人 æ³¨çĽ® +Âł to +con cil +æĥħ ç»ĵ +ĠAs st +亩 产 +纽 æī£ +çĽ¯çĿĢ ä»ĸ +Histor ic +-s ales +éŁ³ åĥı +é»ij 帮 +Be coming +询 éĹ®éģĵ +çľ· æģĭ +æĻĵ 举 +æ³¥ æ³ŀ +ĠStat ue +æľī æĸ° +Ġem erald +âĢĶ one +æķĻåѦ çļĦ +è§Ĵ度 æĿ¥è¯´ +æ¹ĸåįĹ åį«è§Ĩ +ĠlastKnown FileType +c oded +PE X +磨 çģŃ +润æ»ij åīĤ +çļĦ é»ijèī² +-d eg +å®Įåħ¨ 被 +Val ley +èĥĸ èĥĸ +oct et +è¿ijåľ¨ åĴ«å°º +ï¼Į å±ħæ°ij +æ´ µ +ï¼Ľ æŃ¤å¤ĸ +ĠED TA +, 转 +- env +Ġform ulating +_in formation +Ġcur bs +åľ°åĮº åĴĮ +èݱ åħĭ +ĠHaw thorne +ĠAnalyst s +ĠAttend ance +ï¼Į è¡¥åħħ +ãĢĤ éŨ +ass el +Ġdis content +头 绪 +Ġlight est +Ġpick les +å®ŀæĸ½ä¾ĭ æĪĸ +ï¼Į主è¦ģ åĮħæĭ¬ +P d +f ishing +Ġl umps +-> {$ +æĭ¼ æŃ» +Ġfra ught +Ġproc ured +ï¼Į èµ¶å¿Ļ +Ġem ulsion +èĢģ 大çļĦ +产åĵģ å¼Ģåıij +_n b +æł¹æį® èĩªèº« +Ġquarter backs +ĠEU RO +Jan et +Ġâĭ ħ +ĠHe zbollah +游æĪı éĩĮ +èīĺ èι +Ġchi ropractor +- radio +ĠP ause +ĠR itual +ĠG AM +Ġsp oof +ĠCon an +Ġhit ters +-ch arge +åij¼ åͤ +Ġreproduc ibility +Ġc w +ĠN DP +èĻ ± +Ġtrans national +ä¼ģ åĪĴ +field Name +寻 æĢĿ +ï¼ĮåħĪ åīį +ä¸įåĩº æĪ· +Ġdiscrim inated +.al ibaba +ĠG AL +ĠG PI +æĹ¥ åIJİçļĦ +åİŁ åij³ +-n one +_dis claimer +Ġpedag ogy +L oved +ãĢģ èĭıå·ŀ +è¿Ļ 头 +æİ¨ 论 +ç o +Prel ude +C arm +ĠH aha +主è¦ģ åĪĨ为 +æ¯į è¯Ń +SO LE +) çļĦä¸Ģ端 +_ IV +æĭ Ħ +æľ¬ æ³ķ +åı¤ 建çŃij +Ġasync io +/st orage +ĠWhit ening +ĠB TS +æīĵ æ°´ +Ġcra bs +W et +r dev +çļĦ åį¡ +Ġv antage +ä¹Ł æ¸IJæ¸IJ +åħ¶ éģĵ +Ġdeb unk +Method Impl +æĢĿç»´ çļĦ +â te +æĭĺ æĿŁ +ĠLon ely +M ars +Ġi y +Ġprim ordial +ĠEver green +Ġconjug ated +Ġholog raphic +/ arm +Ġl ak +æĸ¹ çĻ¾è®¡ +æĢ§ åĮĸ +ç¾İ çͲ +WO OD +( åħ¶ä¸Ń +s ensors +åĨħ åĬŁ +ä¼ł è°ķ +ï¼Įåľ¨ åħ¨åĽ½ +代çłģ å¦Ĥä¸ĭ +ï¼ĮçĶļèĩ³ è¿ĺæľī +çīĪæĿĥ æīĢæľī +ic ata +ry ker +管çIJĨ åѦ +åħ« éŨ +ï¼Į请 åıĬæĹ¶ +ĠSuper visors +unn ies +ĠStream s +· å¸ĥ +comm itted +(l oss +mar shall +åĬłæĿĥ å¹³åĿĩ +- coming + į +Ġ 建议 +Ġp cs +æ³ ± +è¿Ľè¡Į çİ°åľº +ï¼Į便 åı¯ +çĶŁçī© æĬĢæľ¯ +Mar co +Ġprox imate +V ILLE +pr udence +å¹²åĩĢ æķ´æ´ģ +å¿ħçĦ¶ çļĦ +. required +n ip +ä¸į æµİ +çļĦå£°éŁ³ åĵįèµ· +Ġg ynec +ac ross +åĩº èĩªå·± +æ´ª æµģ +ãĢĤä½ľä¸º ä¸Ģ个 +$ ~ +L TE +ĠH uck +代 è´Ń +)/ \ +_END POINT +ĠâĬ ķ +"> č +æľīä¸Ģ åIJį +æı´ å¼ķ +äºİ ä¸Ģ身 +wit cher +-li quid +èĬį èᝠ+ä¸ŃçļĦ éĩįè¦ģ +Ġcapt ains +ï¼Įåĩº éŨ +æĪIJ åĽł +空éĹ´ åĴĮ +èĩ£ 妾 +è¿Ī åħĭ +_ad j +_AC COUNT +ain ter +sh ade +æ¯Ķè¾ĥ å¤įæĿĤ +ä½łä»¬ éĥ½ +ĠCOR POR +( äºĶ +Ġ ä¸ĬåįĪ +ï¼Įåı¯ æĢľ +Ġsprink ler +at chers +Ġc love +ï¼Į å¿ħè¦ģæĹ¶ +ĠT ract +åĽŀ èĢģå®¶ +æĢ» éĥ¨çļĦ +éĢIJ 个 +ãĢĤæĪij们 è¦ģ +æijĬ è´¹ç͍ +x fc +åĬ¨ 产 +天 æ¡¥ +éĥ¨ ç»ıçIJĨ +å·² è¶ħè¿ĩ +Ġtra b +Ġmen ace +ĠCal m +Ġfre estyle +æĿı èĬ± +Ġle ur +ĠTechn ological +æĮ¯ å¹ħ +\ fi +Ġsu g +主 éĺŁ +æŃ¤ è¯Ŀ +åĩºçݰ æķħéļľ +. Entities +è° Ĩ +åħ¬åı¸ æ²»çIJĨ +é¾Ļ çıł +èµĦ产 ç»Ħ +Ġax ios +人群 çļĦ +Ġtint ed +Ġ åķĨåĵģ +Ġo int +-p ayment +åĭĩ å¾Ģ +æ¶Ī失 çļĦ +ĠAdminist rators +M ATH +Ġbe arer +ere l +ä¸İ çĶŁæ´» +ï¼Įåīį èĢħ +æģ¼ ç¾ŀ +å°ĸéĶIJ çļĦ +åģľ ä¸ļ +Ref Count +)= - +Ġcurs es +ï¼Į çĻ¾åº¦ +ï¼Į æĽ¼èģĶ +çļĦ èĮĥåĽ´åĨħ +ãĢģ èij£äºĭä¼ļ +ï¼Įåı¯ çİ°åľ¨ +ĠRE IT +CON S +ĠMack enzie +RE W +æĭī éĿ¢ +è£ħ饰 æĿIJæĸĻ +ĠInitial ized +happ iness +B erg +èĢģ å¹²éĥ¨ +ä¼ł éģį +Big g +ï¼Įçݰ å°Ĩ +Ġsnork eling +, åıĹåΰ +对 åIJĦ +æ¶Ī失 åľ¨äºĨ +ÂĢ Ãij +æľī ä¸īç§į +· èİ« +sv c +è´¸æĺĵ æľīéĻIJåħ¬åı¸ +éħįå¥Ĺ çļĦ +磮 å°ı +æķ°åįģ ä¸ĩ +.Byte String +ĠCorpor ations +ĠS ensitive +Ġes l +ĠE id +ĠV ag +ç§ij 级 +_p review +Ġerr atic +j g +ess er +æĪij 被 +Ġtra umat +æĪı 份 +Ent repreneur +track s +en emy +ĠW n +åıij æĿ¥çļĦ +éĩį åĨĻ +ä½İ è¯Ń +.R eturn +ï¼ĮæľĢ æĸ° +ĠS op +åģľ ä½ıäºĨ +æī¿è½½ çĿĢ +ISTR ATION +-bal anced +Ġ éļıåį³ +Ġlic ences +Ġundis closed +c ision +Ġn oc +ĠE bay +ï¼Įä»ĸ ç͍ +åħ·æľī éĩįè¦ģæĦıä¹ī +main ly +nav List +.send Message +ä¹°åįĸ åIJĪåIJĮ +ãĢĤæ¯ı å½ĵ +å´©æºĥ äºĨ +泪æµģ 满éĿ¢ +. []{ +ud ad +éķ¿ åľ¨ +æĬĬ éŨ +èĩªæĪij ä¿ĿæĬ¤ +_ ast +ĠP arm +ĠL OS +ä½ł å¾Ī +IL ON +Red uced +ãĤĵ ãģª +, éĿł +ãĢĤ ä¸ĭä¸ĢæŃ¥ +-s cript +缮åīį æŃ£åľ¨ +é¥Ń çļĦ +Gr anted +Ġvibr ational +ĠSie gel +.S DK +ĠDent on +ĠC iti +ĠM andy +ĠG om +èĥ½ è®©ä½ł +Entity Type +_u art +Ġstew ards +ãĢģ éĿĴå²Ľ +Ġsp ree +éĿĴ 天 +oph osph +æ±Ĺ çıł +(err ors +W STR +Ġass urances +åħ¬åı¸ 注åĨĮ +åİŁ çĤ¹ +ï¼ĮæĪij åĸľæ¬¢ +Of Class +ĠSem ester +ĠGoth am +_OPER ATOR +æľ¬ ä¼ļ +åĽłä¸º åľ¨ +è°ģ ä¹Ł +_R W +ĠBank er +Tra iling +åĸĦèī¯ çļĦ +Ġscaff olding += L +Ġ åķĨä¸ļ +åĪĿ æľŁçļĦ +Ġpret ended +ĠWeb inars +, ç©¿ +ve cs +ä¸Ģ è¿ŀ串 +Ġinter ceptions +Ġref inery +çļĦå°ı äºĭ +代çIJĨ è®°è´¦ +æĭĽåķĨ éĵ¶è¡Į +Ġsarc astic +ï¼Į æĪIJç«ĭäºİ +Ġimp urity +ĠAr rival +æľĢåIJİ è¿ĺæĺ¯ +å¿ħé¡» å¾Ĺ +æĿ¯ æ°´ +κ ε +ĠElastic search +\ Lambda +ĠN acional +ain en +ĠO culus +è¿ĩ æ²³ +åķ ¾ +acet yl +ĠG uth +ãĢĤæĪij è¦ģ +.Invariant Culture +, value +â ļ +ï¼Į 念 +æİ¥ ä½ı +ĠSh abb +æĵ ŀ +综åIJĪ çĹĩ +(B oolean +ĠI ps +Ġreimb ursed +èĤ¯å¾· åŁº +ĠCl ouds +ĠMart ins +åĭ¾ åĭ¾ +ĠBUT TON +ï¼Įç»Ŀ对 æĺ¯ +, ä¸įåIJĮ +åĽ½ å¸Ī +.M ODE +Check point +ĠGal ois +( editor +K w +ĠV apor +å¯Ĩ ä¸įåı¯ +æĹłç¼ĺ æĹłæķħ +( Layout +ï¼Į å®ĺæĸ¹ +Ġg char +æ°´ å¸Ī +ä¿Ŀ çĽijä¼ļ +ĠU zbekistan +ENT AL +带æĿ¥ æĽ´å¤ļçļĦ +ĠBL UE +,âĢĻ âĢĿ +Ġperpet rator +ĠεÏĢ Î¹ +Ġdomest ically +C ycl +ä¹ĭ è¯į +; : +ç»ı 纬 +ï¼Įè¿Ļ 段æĹ¶éĹ´ +U d +ãģ ² +ron omy +å®ģ å¹³ +æł¹æľ¬ ä¸įçŁ¥éģĵ +ç¾İ丽 乡æĿij +_min us +ä¸į 饱åĴĮ +ç³» 主任 +æĭ¥æľī ç§»åĬ¨ç͵è¯Ŀ +Del iver +X box +Ġ åıĤåĬł +Ġan aph +é£İ èµ· +å© º +Ġmetaph ysical +å¿ĥçIJĨåĴ¨è¯¢ å¸Ī +ĠBloss om +åĪ© åīij +æ¥ļ 天 +] ` +Ġ è½» +_log s +T itan +çļĦ æķĮ人 +ĠB ingham +ĠF elt +ä¸ĭ åįĬåľº +æ²¹ æĿ¡ +Item Type +_R ING +ĠDynam ical +- Share +_P D +ĠPar an +Ġsubs cript +éĥ½ä¼ļ éĢīæĭ© +ĠMark us +èĢ½è¯¯ äºĨ +c airo +j y +Ġ æŃ» +Ġcr ates +Cost a +, ä¸ŃéĹ´ +ï¼Į æ²³åĮĹ +ï¼ĮåıĪ åľ¨ +æĹ¥ ä¹ĭåīį +åħ¬åı¸ æĺ¯ +" Then +R ational +éĺ´ èĮİ +Ġconver ged +M ari +æ¯Ķ ä¹ĭåīį +两个 å°ı +鸡 çļ® +渡 æ²³ +ãĢģ åºĶæĢ¥ +ĠR acial +æ¶Ī 亡 +ï¼Įåıª æĺ¯ä¸Ģ +æ¶Īè´¹ çļĦ +ä½ł 身边 +_SC HEMA +çļĦ æįŁå¤± +ĠH DF +å¹´ æ£Ģ +ĠTrans itional +åıªè¦ģ æľī +没äºĭ åĦ¿ +Ġvow els +Ġh opped +ãĢĤ æķ´ +Ġinc arn +åĨ· é£İ +ä¿ĿæĬ¤ å±Ĥ +Vari ation +é£ŀå¿« åľ° +G PT +l bl +Ġs acked +åŃĺ 亡 +æĹłæ³ķ æİ¥åıĹ +å°¼ æĹ¥ +ĠHay ward +ï¼Į åķĨåĵģ +好 åĩłå¤© +_S ize +å¦ĥ åŃIJ +C ub +J ill +åİŁ ä½į +ars on +æijĬ åŃIJ +ï¼Į æłĩåĩĨ +ĠC PD +Ġcr umb +é¾Ļ å²Ĺ +ĠIm agination +èĪŀ åĬ¨ +表éĿ¢ å¤ĦçIJĨ +ĠIKE A +\ ne +Ġp ears +å°±æĺ¯ ä½łçļĦ +ibr ated +pre viously +, å½ĵåīį +ĠC URL +our ke +æķĻ ä¹ī +ĠPart icular +åĪº çĮ¬ +ĠMaur itius +å¸ĥèݱ æģ© +æİĴ éĩı +乡 å¸Ĥ +ĠGr atitude +çĨŁ çŁ¥çļĦ +ĠIm am +çĶļèĩ³ è¿ĺ +èĥĨ æ±ģ +ĠCrow ley +Ġ ç®Ģåįķ +æ°´ åĮº +ï¼Įä¸į æĦ¿ +_ place +To Add +- span +it ans +æĹ » +Ġdes ir +绾ç»İ ä¸įç»Ŀ +( one +F lying +} v +ï¼Į ç»ĦæĪIJ +Ġn ifty +Ġaden ocarcinoma +Ïģι Ïĥ +rocy te +\ Data +è£ ± +tt ed +ï¼Įä¹Ł åı¯ä»¥éĢļè¿ĩ +ĠSystem atic +æİ¨å¹¿ åºĶç͍ +绵 ç¾Ĭ +, åĬłå¤§ +Ġ çijŀ +å°± æĭ¿ +å¹² åĬ² +æĵįä½ľ æĹ¶ +æĺĤ é¦ĸ +Ġnod ules +B ert +åĬ« æĮģ +åĨĽæľº 大èĩ£ +ãĢĤ å®ŀ +çĶŁçĹħ äºĨ +ĠW icked +æĽ´ åĥıæĺ¯ +é£ŀ åĪĢ +çļĦåīį éĿ¢ +. Args +ĠS ushi +åĨĽ è£ħ +å¹¶ä¸į 好 +æĬĴ åıij +è̏äºĨ è̏èĤ© +F ork +ĠG ED +ard t +Ġres ized +ï¼Įä¸į åľ¨ +è°ĥ åħ¥ +å¾® åĩī +Ad ams +é©¶ åħ¥ +夹 çĿĢ +Ġmsg id +æıIJéĨĴ éģĵ +anim als += z +ĠR TX +åľ° 使ç͍ +Ġstock ings +Cert ificates +Ġwart ime +t ys +ï¼Į 说çļĦ +ãĢģ 身ä½ĵ +å¤ļ 说äºĨ +Ġmay o +害 çļĦ +Thanks giving +D OS +O liver +Ġ 读 +Ġ ä¸ī个 +An nie +ĠOutput s +åĵĪå°Ķ滨 å¸Ĥ +ï¼Įç»Ļ人 ä¸Ģç§į +, çĶ·äºº +ä½ĵ éŃĦ +.N O +Facebook Twitter +ĠHelp ers +飵 å¾ĭ +å¸ĺ åŃIJ +(pro perties +ç»Ļ人 以 +D av +ãĢĤ ä¸ĭåįĪ +ĠC LOCK +ĠW IDTH +没 æĢİä¹Ī +Ġcard stock +ĠD yson +ï¼Įæľī 许å¤ļ +ĠMiss ions +Well ness +åľ¨ä¸Ģ å®¶ +è£ħ饰 åĵģ +ä¸ĵ æĪ· +çļ® æįŁ +æķij ä¸ĸ +.Append Line +_ Id +åΰ æīĢè¿° +ï¼ĮæĪij ä¹Łä¼ļ +cr atch +å°Ŀè¯ķ ä¸Ģä¸ĭ +H TT +宣 读 +à¤ Ĺ +Opt imize +é«ĺ æķĪçİĩ +æŃ¤ 书 +ES G +第ä¸ī åIJį +çļĦä¸į è¡Į +é¢Ħ ä¹ł +Se at +çĮ« çļĦ +ader ie +E rin +é»Ħ çŁ³ +ãĥ į +Ġstaff ers +ç§ģ èIJ¥ +DC s +èĢIJå¿ĥ çŃīå¾ħ +ĠIn formatics +ä¸İ åIJĦ +让 她们 +åij¨ åĨħ +ĠRec ession +å¡« åŁĭ +Red uction +ãĢģ ä¿Ŀéļľ +åĮ IJ +Ġfact ually +_{ [ +客 å¥Ĺ +ä½İ éŁ³ +åį« ä¸ľ +ä¿ĿéĻ© åIJĪåIJĮ +ph thal +Ġ<< < +èĤ¤ è´¨ +ï¼Įå®ŀ åĪĻ +Ö ¸ +è¿Ľè¡Į 管çIJĨ +the rapy +.d st +å®Ŀ 鸡 +-st at +æ¼Ĥ ç§» +é«ĺ级 ä¸ŃåѦ +ï¼Į æĺ¨æĻļ +个 ä¸Ń +åİĭ ä½ı +çĶŁäº§ åĬłå·¥ +ĠBal loon +ĠTrace y +â ĥ +Ġ( ); +åĴĮ å®ŀè·µ +âĢĶ are +Ġback stage +.h l +rect angle +æľīäºĽ çĸijæĥij +ï¼Į å°ļæľª +ä¹Ł å¾Īå¤ļ +èĤ¡ä»½ åζ +å±Ī æĮĩ +C ER +ãĢģ èij£äºĭ +_s f +Ġble aching +åı¯ è¦ģ +ä¹Ł ç͍ +äºķ æ°´ +ĠMold ova +ãĢģ çĶ³è¯· +åĪĨ å¿ĥ +ãĢĬ ä¸ĸçķĮ +æŁIJ ä¸Ģ天 +å±¥ è¡ĮçļĦ +ĠIMD b +ĠK are +Ġco z +è±Ĩ åŃIJ +ä¸Ģéĥ¨åĪĨ å®ŀæĸ½ä¾ĭ +ä¸į å®ŀ +è¦ ı +å͝ä¸Ģ èĥ½ +ĠNev ille +ï¼Į å¥Īä½ķ +ĠB RA +åĴĮ éĤ£äºĽ +alf a +Ġtick er +Ġpartition ed +Mal aysia +Ġ æĶ¾ +åıĹ åij½ +_{ { +inter op +=' # +ä¾Ŀèµĸ æĢ§ +.Un known +U çĽĺ +ä¸Ģ æĸ¹çļĦ +åΰ çİ°åľº +Ġem ulation +ĠAm herst +, åİ¿ +ï¼Į æİ§åζåύ +å¦Ĥæŀľ è¦ģ +Ġleft ist +æīĢæľī åζ +(p i +Ġbroad casters +å®īå¾· é²ģ +- operator +t reatment +in itive +æľ¬ æĿ¡ä¾ĭ +ï¼Ľ èĢĮä¸Ķ +Ġpr ides +Ġrearr ange +e urs +j ia +åľ¨ æĹ¥å¸¸ +Ġad obe +æĽ´ åºĶ该 +ç¾İ é¢ľ +æ¯į çĮª +åŃĺåĤ¨ 设å¤ĩ +Ġneck line +ĠYose mite +K on +ãĢĤ åĢĺèĭ¥ +() "> +.w in +ï¼ĮåıĪ éģĵ +èĩ£ åŃIJ +åİŁæľ¬ æĺ¯ +ĠMAG IC +G lob +re ast +at el +大 éĺŁéķ¿ +è¿ľ 端 +Dis position +ls l +C mp +Ġt é +çļĦ æĪĺäºī +åΰ 大家 +äºĴèģĶ äºĴéĢļ +\ dot +ãĢģ ä¼łæĴŃ +æĹ¥ å¼ı +åħ³ ä¸ĬäºĨ +.U int +Ġnot ary +Ġsome place +-d uration +(* ( +ĠM odes +ĠP lex +Ġ& . +åıĺ åŀĭ +OO LEAN +ĠTher mo +é½IJå¿ĥ åįıåĬĽ +çļĦ åĽ¾ +ĠSh ang +IDD LE +h un +m ethyl +Ġ å®ļä»· +ĠF illing +æµ· åķ¸ +èµ° è¿ľ +inc ar +comp an +Ġlit ig +ĠMur doch +ï¼ĮåĽĽ å¤Ħ +ãĢģ ä¸Ķ +éĵ¶ 两 +Restaur ants +çĿ ¢ +åĬ³ æĸ¯ +å²Ĺä½į èģĮè´£ +ãĢģ 鼶 +ru id +æ¡ ģ +Ġgu ise +å·²ç»ı ä¸įåĨį +Ġsn iper +- encoded +Ġn ipple +ĠH ib +æĹ¥ åıijå¸ĥ +Qual ifier +_ adv +åĽĽ åIJĪ +主è¦ģ æĺ¯åĽłä¸º +ï¼Įæľ¬ æľŁ +Ġstra pped +.mark down +产åѦ çłĶ +s imp +ãĢģ åĽ¢ç»ĵ +pl aintiff +ä¸ī æĽ´ +ĠEl sa +ä¸į ä¹IJ +Ġav ian +è¡Ģ å°ıæĿ¿ +ĠApp les +å«ģ å¦Ĩ +Ġδ εν +. cy +ĠB azaar +ĠMy c +asc a +,以 æŃ¤ +ĠMagn olia +ï¼Į çĭ¼ +ĠPet ty +ĠAL PHA +Est ablish +çīĩ çĬ¶ +ĠAttribute Error +ab br +ä¸ĭ æľī +åĨį è¿Ľè¡Į +å¿« èµ° +Ġsec ures +Ġä»ĸ 说 +Ġcom un +ĠE ste +Th irty +åĨį æ²¡æľī +ï¼ĮåĨį ä¸Ģ次 +讨 ä»·è¿ĺ +è£ħä¿® 设计 +ç¡ķ æŀľ +é£İ 顺 +ç¡® åĩ¿ +èĥ½å¤Ł è¾¾åΰ +(c v +± ÃIJ +Ġsuppress or +Ġunp repared +.B ox +- Ind +ãĢģ åľ°çIJĨ +çĸ¾ é©° +ï¼Įéĺ¿ å°Ķ +åĪĨæīĭ äºĨ +åºĶ纳ç¨İ æīĢå¾Ĺé¢Ŀ +ï¼Į èŃ¦å¯Ł +id ata +åľ¨ 两 +æīĢ çļĦ +åįĬ çĶŁ +/ max +D f +ĠF uck +ob ot +ĠCon ner +èĥ½å¤Ł ä»İ +ĠF ilename +ï¼Įä¸Ģ å¿ĥ +Ġpower fully +ĠGu am +æĢª å¼ĤçļĦ +, åįģåĪĨ +大 çŁ³ +Ġ' ] +Ġcomm utes +,ä¸į éľĢè¦ģ +R outine +å®Ŀ åħ¸ +顾 åIJįæĢĿä¹ī +åѤ å¯Ĥ +hash Code +èĢIJå¿ĥ åľ° +ĠWE LL +Agric ulture +æģ¶ä½ľ åī§ +ĠBeth any +.Logger Factory +ï¼ ¯ +ãĢĤ å®¶éķ¿ +ĠCh alk +li pped +åĮ»éĻ¢ ä¸ĵå®¶ +Par ad +æ¹ĸ人 éĺŁ +/ example +El apsed +çĭŃ å°ı +Ġe erie +ä¸Ģ 绣 +Ġex cretion +ï¼Įä¸Ģ 座 +è´´ çīĩ +ä¸ĭ æ£ĭ +æľ¬ ä¸ĵä¸ļ +ĠPat ron +æ´ŀ åºľ +ĠFeed s +, åĿIJ +ï¼Į 顾客 +ãĢĤ ç»Ħç»ĩ +ol ition +Ġon s +ä¼ł 令 +åı° å¸ģ +æľīä¸Ģ å¼ł +g ps +çļĦ è¾ĵåħ¥ +ä½ ¶ +ĠD uties +Ġr RNA +Ġsl ag +Ġ ¿ +æĭ¿ æįı +ï¼Įçľ¼ åīįçļĦ +p z +ãĢĤ ä¸įåIJĮçļĦ +ig l +ĠR ama +ĠJ ia +åıij æĿ¥ +æ¯Ķ ä»ĸ们 +ï¼Į çIJĨè§£ +ĠOr bit +æĿĢ ä¹ĭ +Ġarm ored +è®°å¿Ĩ çļĦ +ĠProsecut or +ĠCorb yn +k bd +ĠS ponge +渴 æ±Ĥ +Ġt igers +ä¸ ¶ +Ġan che +çļĦ åĽºå®ļ +ĠS weeney +çļĦæĹ¶åĢĻ åı¯ä»¥ +ĠDE ST +ĠDC HECK +Ġcrack down +ĠPyth ag +om mu +ãĢģ å®ŀéªĮ +ĠG w +ĠO c +-s ongwriter +-f ledged +Ġbal conies +åĪ¶ä½ľ å·¥èīº +ĠGL FW +ĠGeorg es +G auge +ãĢĤ 缸åħ³ +ãĢĤ 建ç«ĭ +id irectional +ĠG rief +æĪij们 ä¸įèĥ½ +ç²¾ç¥ŀ çĬ¶æĢģ +ĠEm phasis +Ġchip set +åºķ åŃIJ +ç²Ĺ æ°Ķ +Ġda ÃŁ +pay day +Viol ation +M os +æĪĺ åĬŁ +_R ULE +奥 åĪ© +}}( {\ +; x +S andy +æĪij åı¸ +ä¸Ģ个 éĿŀ常 +ĠU pt +å¤ļ æĭī +ä¸ŃåĽ½ åĽ½éĻħ +æ²Ļ æ²Ļ +OV ERY +èİ« è¨Ģ +ç¡ķ 大çļĦ +emp lo +å®¶éĩĮ æľī +graph ic +第ä¸ĥ å±Ĭ +.Visual Studio +å°ı èι +ĠSt ing +ĠUS P +ï¼Įè¦ģ åľ¨ +åĩºæ°´ åı£ +è´¨éĩı æİ§åζ +_G UID +æĬµ éĶĢ +æĬ« é£İ +Ġlunch time +ĠKom mission +. visual +æĪĺ å±Ģ +çł´ åı£ +缴æİ¥ ç͍ +IF ORM +, è¿ĩåİ» +Ġ ç»§ç»Ń +ĠI EL +ĠR ho +Ġcomm uters +Let t +èĦ± ä¿Ĺ +æģ¢å¤į çļĦ +å¼Ģåı£ éĹ®éģĵ +ĠAT A +ĠP TA +é£ĺ é¦Ļ +ï¼Į çİĩ +大 礼 +ex clusive +ap r +楼 æĪIJ +è¿Ļ款 车 +, åΰåºķ +Ġe aves +æ±Ł éĺ´ +P ts +k ubuntu +pp elin +举 å³» +.m ember +èĬ± çĽĨ +Ġsk yl +,å¦Ĥæŀľ æĺ¯ +Ġthe ses +ap ar +_M T +èĭį çĶŁ +ĠPo et +ï¼Įä½ł åΰåºķ +æĿĢ ä½ł +Ġsuper flu +ä¹Ŀ äºĶ +MP P +'' ( +ĠRh ino +建 ä»ĵ +åĦ¿ æĹ¶ +åį± éļ¾ +ï¼Į轻轻 åľ° +ĠKel vin +al leg +å°± åĽłä¸º +ï¼ļ åĪ©ç͍ +End Of +å¹¶éĿŀ å¦ĤæŃ¤ +ĠRh ythm +\ Form +æł¡ éŨ +ä½ľåĵģ æľī +Ġchem ok +Ġsoft ening +çĥ¤ é¸Ń +Ġrig ged +N ike +ï¼Į åĩĢ +åĪĨæŀIJ ä¸Ģä¸ĭ +åı¯ ç͍çļĦ +å°ı å²Ľ +å̼ æĺ¯ +许 æĦ¿ +èĤī é£Ł +ç®Ģåįķ äºĨ +æĻºæħ§ åŁİå¸Ĥ +cr ash +âĢĿï¼Ī ãĢĬ +ĠAl c +éģ¿ å¼ĢäºĨ +æĺĤ æī¬ +))) ** +- el +æµģ äºij +æĮģ ä¹ħçļĦ +Ġaw fully +æĮ¯ ä½ľ +å·ŀ åŁİ +Ġaf rican +è´ŀ è§Ĥ +ĠMos que +id on +Ġun for +Ġsm e +,ä¸Ģ å¹´ +èIJ½å®ŀ åΰ +ï¼Į æ¹ĸ +ä¸Ģ ç¿» +åĴĮ åĸĦ +æİ¥ æĽ¿ +åģļ æĪIJçļĦ +ï¼Įä½ł ä¸įä¼ļ +erc a +å¾ģ åħµ +èµĦæºIJ åħ±äº« +rien ne +åij¨è½¬ çİĩ +æĥħ æŃĮ +Ġyear ning +Ġautom ating +æ¡Į éĿ¢ä¸Ĭ +ĠGold stein +ad one +æĿ¥ åķ¦ +Ġun ic +éĩij 森 +æŃ¤ èµ·å½¼ä¼ı +An alyze +èϽçĦ¶ ä¸įæĺ¯ +ठ¦ +宽 é«ĺ +ĠImage View +åºĻ å®ĩ +èĿİ åŃIJ +Aggreg ation +ãĢĤéĤ£ æĺ¯ +åľºä¸Ĭ ä½įç½® +æĩĬ æĤĶ +ï¼ļ çĶ· +OT OS +Ġåľ¨ è¿ĻéĩĮ +ĠBal m +è¿Ļä¸ĢçĤ¹ ä¸Ĭ +Ġrepay ments +çļĦ æī¿è¯º +åĴĮ åķĨä¸ļ +ï¼Įä¹Ł æĺ¯ä¸Ģ个 +åı² ä¸ĬçļĦ +iner ary +éĩijåĪļ çŁ³ +交çķĮ å¤Ħ +è¿ĺ å¤Ħäºİ +çļĦ人 å·¥æĻºèĥ½ +ĠST L +Sim ulator +ĠStock ton +(sc ene +R ising +Ġg reek +ãĢģ å¢ŀ +_C ARD +æī§ 念 +æ²ī 沦 +Dr ink +ROW N +, æķĻèĤ² +[ q +Ġf oyer +ãĢĤ éĥ½ +ĠT OS +è£ Ĩ +ãĢĤè¿Ļ éĥ¨ +ĠWho ever +(s d +çļĦåIJį 声 +er ous +ĠY ok +é«ĺ å®ĺ +ç² ³ +Ġbreak age +çļĦçľĭçĿĢ å¥¹ +A mber +å¿ĥ 声 +çIJĨ æĪIJ竳 +éļ į +Ġx c +long itude +ĠInf rared +æķ°æİ§ æľºåºĬ +s us +å¾Ī æĹ©å°± +客 åķĨ +åĵĪ æĭī +_g uid +ĠMal ibu +Ġadm iring +_ Open +x ious +ĠD ort +带 ç͵ +ä¸ĩ æĸ¹ +æ¸ħ 空 +çļĦä½įç½® ä¸Ĭ +èĭ¯ äºĮ +çļĦ ä¸ī个 +åĬªåĬĽ åľ° +Ġal veolar +çĶŁæ´» æ°´å¹³ +ĠIslam abad +_COM MENT +········ ········ +( MAX +cent ed +æ¯į 鸡 +Ġhor rifying +_process or +ĠM SA +ĠL SD +ĠG ems +æĿİ å°ı +Ġsw ag +å©ļ åºĨ +ĠBig ger +çķª å¤ĸ +ç»ĵå©ļ è¯ģ +ĠKauf man +ä¸Ń 大 +åIJĪçIJĨ å®īæİĴ +/g ems +b ud +ä¸Ń éĵģ +çĶŁ åĦ¿ +æĸ¹æ³ķ è¿ĺåĮħæĭ¬ +(b it +宿 è¿ģ +Ġp oo +ĠS ao +Ġrec ited +åľŁ çļĦ +, åı¶ +ï¼Įè¿Ļ åıª +çĽĺ æķ´ +PRO GRAM +伪 åĬ£ +åᏠæĸĻ +onitor ing +AUTH OR +s imply +ä½ł å¾Ĺ +_ex pect +re ported +çļĦ çģ¯åħī +âĢĻ a +å¢ĥ åĨµ +è½® èŀįèµĦ +ĠLa uncher +ĠShen zhen +F ruit +Ġde ems +ä¸İ åĪĽæĸ° +èΰ éķ¿ +èĬ³ åįİ +ç»ŀ çĹĽ +èIJİ éĿ¡ +, 建设 +G RA +天 å¿ĥ +Ġ# $ +ï¼Į为 客æĪ·æıIJä¾Ľ +çĽIJ åŁİ +å°±ä¸į ä¸Ģæł·äºĨ +Ġip rot +Ġd udes +ĠP ik +ï¼Įä½İ 声éģĵ +æĻ¾ å¹² +Ġ èµĦ +ĠH ahn +è¡Į äºij +çľĭ éĢı +ĠK rak +ï¼Ł ä½Ĩæĺ¯ +-d ouble +æŃ¤ åħ¬åijĬ +ĠCom pos +åıĪ ä¸įèĥ½ +å·¥ä½ľ æĸ¹æ¡Ī +æŀ¶ 设 +P oker +h ipping +l uster +ï¼Į 举åĮĹ +ig u +Ġr st +æĹ¶ ä»» +ä¹Ł 以 +ç±³ æĭī +èµĮ 注 +å©ī 转 +çĸ¯çĭĤ åľ° +严åİī æīĵåĩ» +ĠæĽ´æĸ° æĹ¶éĹ´ +, åĴ±ä»¬ +çļĦ ä¾Ŀæį® +åı¯ åĪ« +ov ar +ä½ķ åħ¶ +ä»ħ åī© +éĻį æģ¯ +ĠU ng +CT G +ĠSnow den +( .. +\ lim +in ative +对 åħ¬åı¸çļĦ +åı£ èĪĮ +ï¼Įåľ¨ 线 +æŃ¦ åĪĻ天 +ĠAdd r +é£İæł¼ åĴĮ +Ġdoubt less +Ġwave guide +Ġwashing ton +ĠNort heastern +pkg ver +ĠEdd y +ï¼Ł å®ĥ +-m atched +Ġid yllic +_IN FORMATION +æµ® èĤ¿ +. Offset +Ġ ä½ĵéĩį +Ġvol umetric +åħ±åIJĮ çĤ¹ +ront al +ï¼Į车 åŃIJ +mill an +ĠNathan iel +åºĶæľī å°½æľī +å¦Ĥçģ« å¦Ĥèį¼ +ா à® +. ãĢIJ +.get Source +ĠThat cher +åģľ åľ¨äºĨ +ur de +éģĵ åľº +è·¯ åŁº +çŁ³ åĪ» +Ġing ress +ĠJur assic +Ġwast eful +S quared +ï¼Į æĸĹ +om ac +the ory +æĿij æĿij +нÑĭ м +( Activity +ĠAl ph +ĠNew ly +ĠEz ek +Ġwhirl wind +è¡ ĵ +Service Helper +ĠDraw er +Ġpatriot ism +ä¸ī å®Ŀ +å®ī 迪 +亲 åħµ +ä¿ĿæĮģ ä¸įåıĺ +äºĭæķħ åıijçĶŁ +_PL UGIN +P ED +ĠF K +ĠEnd e +çļĦ å¿«ä¹IJ +ĠR uf +é«ĺ éŁ³ +Impl Options +.Cl oud +ĠPACK AGE +L icensing +ï¼Į ç½ijåıĭ +ãĢĤ 社ä¼ļ +åįģåħŃ å¹´ +Ġcontest ant +çļĦ çİ»çĴĥ +im id +æĪij åĪļæīį +æĤ² æĦ¤ +æİ¥è¿ij äºİ +åī§ æ¯Ĵ +æĮģç»Ń åΰ +èª ª +Ġdivis ive +ĠG Ps +èħ ¼ +å°Ķ æľ¬ +åĶIJ 人 +-ind ent +åıij æĢĴ +æĪijçļĦ åIJįåŃĹ +é¢ij è°± +f leet +us ky +ne ur +丰 åı° +ä»įçĦ¶ åľ¨ +ĠSant o +Ġe agles +æľº çİĩ +_c mos +è½» åĬŁ +Ġvolcan oes +, id +ĠS orted +Ġst abbing +** âĢľ +å¾Ĺ æ°´ +å¤Ħ 级 +ä½ı çĿĢ +ern al +éĢīæĭ© æĿĥ +ãĢĤåľ¨ è¿ĻäºĽ +Equ ivalent +ï¼Įéļı æĦı +O SS +çļĦ åĬ¨çī© +æķ° åĢį +æłĪ éģĵ +丨丨 丨 +å° ĩ +ä¸į çŃīäºİ +æĹł å¥ĩ +æĸ°éĹ» åıijå¸ĥä¼ļä¸Ĭ +Ġsouven irs +ç͍ ä¹ĭ +ä¹Ł æĿ¥äºĨ +åŁ¹ æł¹ +Ġear buds +.st ereotype +æīĩ å½¢ +( Result +in variant +ĠM ister +æĿ ³ +ãĢģ éĤĵ +AD T +ä¹Łä¸į å¾Ĺä¸į +Ġhor rend +,åı¯ æĥľ +缸ç»ĵåIJĪ çļĦ +Ġin activity +ĠT f +è° ª +ï¼Ľ C +åĪ« æł·çļĦ +cent re +èİ« åıĬ +ĠMod ifier +ĠCare g +æľīä»Ģä¹Ī ä¸ľè¥¿ +Ġì ĥ +æĭīå¼Ģ 帷å¹ķ +åĩºåĽ½ çķĻåѦ +Ġse per +çŀħ çĿĢ +çļĦ æ¯ĶèµĽä¸Ń +ĠR ai +åıij åΰ +çĤİ é»Ħ +Ġsplit ter +åįģåħ« å¹´ +, èµ· +Ġz w +_M ISC +ĠCo pp +Ġserge ant +- Sp += test +Ġg ulf +_m id +Ġhealth iest +ï¼Įä»į æĹ§ +ãĢģ åľĨ +æīĵ æ»ļ +ç»Ī æĹ¥ +ET TE +Ġliter als +Ġretro grade +Ġd olphin +è¦ģ éĴ± +ĠSt ellar +Ġder by +æĭ¨ ä»ĺ +æī³ æľº +K ER +ï¼Į æīĶ +å°±æĺ¯ ç͍ +èĥģ è¿« +Ġdwell ings +æľ¬é¢ĨåŁŁ æĬĢæľ¯äººåijĺ +, åħ¨éĥ¨ +好 æĹ¥åŃIJ +ä¸İ çݰæľīæĬĢæľ¯çĽ¸æ¯Ķ +æłij ä¸Ģ +Ġpsych opath +ĠLoad ed +ĠKoh l +ĠMoment um +è§£ åĽ´ +Ġpneum atic +ï¼Į åĵİ +æĬķ å¥Ķ +ern ames +æµĭè¯ķ 仪 +. tele +ï¼Į 鼶 +æĥ³ ç͍ +æ¸ħ 宫 +Ġmed i +æ»ij è¡Į +çĿ¡ åIJ§ +æŁ± å¡ŀ +诽 è°¤ +ï¼Į 导æ¼Ķ +ĠC TR +ĠG ong +Ġob lique +ĠSk inner +åıijèµ· 人 +Ġp name +ä¸Ń å°± +è´Ł 离åŃIJ +endo za +Ġdissemin ate +ãĢĭ ç¬¬åĽĽ +Name In +æ½ ŀ +Ġdeep copy +Ġsem is +æĢĿæĥ³ å®¶ +çĦ¦ è·Ŀ +Rest ricted +, 女æĢ§ +ĠAss oc +ĠTrend ing +ï¼Į è¯Ħä¼° +ç«Ļ ä¸Ĭ +åıªè¦ģ æĺ¯ +çľŁç©º æ³µ +Ġintersect ing +( product +ãĢģ 书 +Ġlot teries +ç²¾ç¥ŀ ä¸ĬçļĦ +ĠSt rom +åı¯ä»¥ æľīæķĪ +ĠBe irut +顺 çľ¼ +æ»´ åĬł +ĠE I +Ġby stand +ï¼Įå°± ä¸į +stra ight +ĠG IT +Ġch ills +App roved +uten berg +.comp lete +ĠFO LLOW +Ġt rom +ãĢĤ 第äºĶ +ĠR OT +缸 çļĦ +西 奥 +è¿Ļ个 ä¸ĸçķĮçļĦ +åįİ æ¶¦ +ç½Ĺ 宾 +åıĤåĬł æ´»åĬ¨ +åĭIJ èĻİ +s outh +Ġ 帧 +ãĢģ ç£ģ +åľ¨ è§Ħå®ļ +满 èħĶ +aron i +Ġapolog ise +T ak +ãĢĤ æ¯ı个人 +ç® ´ +çľĭ ä½łçļĦ +omet ime +Ġ è®°å¾Ĺ +ï¼ī æľī +Ġfl utter +ESS AGES +æĹł çŃĸ +Ġsk id +ĠTri umph +åİĭ缩 空æ°Ķ +R ATION +or os +ãĢĤ ä»į +ãĢģ é²ľ +大 å¸ħ +åı¥ åı¥ +éľ² åı° +秦 æ±ī +ĠMon et +fe res +D 项 +Ġ å·¥ +ous s +ĠCan aan +ä¹Ŀ çϾ +Ġbare foot +çļĦåıij èĤ² +pl and +Âł æŁ³ +ĠV endors +ï¼Įä»ĸ ç»Īäºİ +广 çļĦ +me asures +æ¯į çα +æ·±åħ¥ æİ¨è¿Ľ +ÑģÑĤв о +as sembled +è¿ĺ åıªæĺ¯ +Ġapp rais +åĽŀæĶ¶ åĪ©ç͍ +Ġsore ness +åĮ» ç¾İ +Ġsil enced +hum id +( plot +èģĶ æ¬¢ +ï¼Į è§īå¾Ĺèĩªå·± +ãĢģ é¤IJåİħ +ĠR age +ep ro +ĠK odi +ĠIncre ment +èļĮ åŁł +ank o +ĠOne Plus +agg ie +-lo ved +æĹıèĩªæ²» å·ŀ +Ġhither to +åĨĽ 人çļĦ +离 åİ»çļĦ +Sh apes +-per fect +ç»ĵ åºķ +æ±Ł è¾¹ +åħ´ çļĦ +èĥ¡ éĢĤ +åı¦è¡Į éĢļçŁ¥ +ï¼Įå¹¶ 被 +èĭ¦ çļĦ +æľīçĤ¹ å°ı +åĪļåĪļ 好 +管 ä»ĸ +Ġread out +Ġbl itz +-p olar +Ġо д +æijĶ è·¤ +ï¼Į以æŃ¤ æĿ¥ +Ġtranqu ility +ãĢģ æķ´çIJĨ +æĬĬ æĮģ +è£ħ é̼ +_pro j +çļĦå¿ĥ è·³ +éϵ å¢ĵ +没æľīä»»ä½ķ çļĦ +Ġpes ky +Ġim aged +æį¢ è¡£æľį +Ġpast ures +欲 è¯ķ +ï¼Į请 èģĶç³» +ĠBlog gers +ĠSqu ee +a ussian +Ġ ç´¢ +ä¸į å®ģ +Ġi outil +Res istance +-def inition +Ġrenormal ization +s impl +ï¼Į 积 +(' " +ï¼ĮæĽ´ è¦ģ +Ġdepart ures +çĶŁèĤ² ä¿ĿéĻ© +Linear Layout +ãĢģåī¯ æĢ»ç»ıçIJĨ +ĠTob ago +_src dir +ĠVT SS +, é¡¹çĽ® +Ġt innitus +re li +_C IPHER +ane ers +ĠRed dy +ä¸Ģä½ĵ åĮĸçļĦ +Ġunint entionally +ï¼Į åģ· +Ġb ah +ĠH irsch +ĠN inet +æĸ¹éĿ¢ æľī +éľ² 头 +åIJ¸å¼ķ 人çļĦ +èĩª éĩį +è¾¾ å·ŀ +è¿ľ æĸ¹çļĦ +æĶ¿åºľ åľ¨ +ĠAg ar +æĪIJæľ¬ é«ĺ +V ent +es gue +ĠM EDI +æ°Ķ è¿IJ +éĹ® åı· +о е +åħļ åĨħ +åĶ¿ 声 +f ection +ĠA CH +ä½ľ è¯ģ +å·² åΰ +èį ł +ä¸įåı¯ æĬĹåĬĽ +ãĢģ æĮģç»Ń +å¼ ģ +è§īå¾Ĺ èĩªå·±çļĦ +Ġrub ble +Ġnu ance +_IM PL +å¹´ åIJĮæľŁ +ç½ij 约车 +è´µ éĺ³å¸Ĥ +ãĢĤå¦Ĥæŀľ ä¸įæĺ¯ +èĩªåĬ¨ æİ§åζ +Ġmic row +ĠRow an +d av +} r +åĩº è¨Ģ +Ġreb ates +.con sole +Jes se +幸 çļĦæĺ¯ +ĠOff ensive +éĶĢåĶ® æ¸łéģĵ +indust ry +åĸ ı +åĮĹ å¸Ĥ +çļĦä¸Ģ ç±» +_g u +ãĢĤä»ĸ æĬĬ +Ġrev olutions +æĶ¯éĥ¨ 书记 +Haw aii +- cy +为 æķĮ +æĸĩ çİĭ +_d isp +åłĨ éĩĮ +è§Ĩè§ī ä¸Ĭ +_COMP AT +çģŃçģ« åύ +ĠR ansom +Comp etition +çĵ¶ è£ħ +èł ¡ +ĠLor raine +m apper +ï¼Į å°ij女 +Ġb anging +Ġm ichael +ĠPM P +ï¼ĮæĹł ä¸Ģ +h urt +å°ı çİĭ +åύ ä»¶çļĦ +åĽ¢ æĪIJåijĺ +产ä¸ļ çļĦåıijå±ķ +åĽŀå®¶ åIJİ +Ġhood ie +ä¸į çĨŁæĤī +ĠDe aling +Ġconf defs +ï¼ĮæĹ¶ ä¸įæĹ¶ +[ K +æĺ¯ æľ¬ +æĽ´ æĹ© +åĪ© å¼Ĭ +_N EG +ĠBhar at +/ dd +ate e +ĠL J +åĨħ çī¹ +-t oo +Ġelev ating +Ġaggreg ator +_ Log +k f +Ġgr out +éŁ³ è§Ĩé¢ij +éĤ® ç¼ĸ +èĢĮ å°½ +ï¼Į许å¤ļ 人 +period ic +Ġa version +Ġbe ets +å¤ļ 级 +åĪĨ 以ä¸Ĭ +Ġsynt actic +åħ»èĢģ æľįåĬ¡ +åīĸ èħ¹ +Ġy olk +å¦Ĥ 常 +Or Update +çĸ¾ é£İ +çĶŁéķ¿ åľ¨ +第ä¸ĢçϾ ä¸Ģ +ĠLandsc aping +ãĢģ ç§ĭ +æīĭ åĨĻ +ĠNo Such +ĠInst alled +Hel vetica +ãĥĥ ãĥĹ +Ġga ussian +ï¼Į å¼ĺæī¬ +Ġex uber +æİ¥ ä¸Ģ个 +ĠMake file +Ġer as +Ġfra il +Ġcere bro +Ġclever ly +ĠEmpower ment +æĪĸ éĿŀ +æĬ¤ 身 +Ġautog enerated +èĢĥèĻij è¿ĩ +æĸ°åĨł çĸ«èĭĹ +ĠBuh ari +Ġr amb +ï¼Į 读èĢħ +Ġto pper +ĠT anya +表达 çļĦ +Ġfict itious +_ ix +av link +æ¯ķ çĶŁ +è§£åĨ³ æİī +Mark ers +Ġmerg es +Ġunimag inable +Ġ æ³¢ +Ġ æĿ¾ +.p ass +软 äºĨ +_PRO GRESS +sear ched +ï¼Į èĦij +æ± © +ob le +åįĥ å¹´çļĦ +æĸĩåĮĸ èĬĤ +look ed +Ġrail ways +ä¸Ĭ 表 +åIJĮ æĦıçļĦ +转 念 +Ġline ages +è¾ĵ çIJĥ +Ġpar able +çĨŁ èĻij +ï¼ĮæĢ» åħ± +ï¼Įæĸ¹ é̏ +/ __ +ĠT rey +âĢľ 谢谢 +天 æĹ¶ +çĭ¬ç«ĭ æĦıè§ģ +Coun sel +Celebr ating +/ nginx +n pos +Ġcl a +ï¼Ī åħįè´¹ +å±± èħ° +ï¼Įä½ł åĴĮ +ç½Ĺ 纳 +èĥ¸ èħĶ +ĠSolar is +Ġdowns ides +åŃľ åŃľ +Ġè¯ģåΏ 代çłģ +ë ª +Ġup holding +çĤ¸ å¼Ģ +Works hop +Z ach +s ess +ãĢģ ç¾İæľ¯ +å¾® åĪĨ +(w rite +Ġbill board +ĠText Appearance +Ġtrigon ometric +ĠL n +æĿ¥è¯´ æĺİ +Ġ 缸 +ĠK iwi +缮 åħ± +ym b +å°ģ åı· +Ġleak y +ãĢģ æ¯Ķ +è¡Į ä¸įè¡Į +éĿŀ常 ä¸įéĶĻ +DR A +å·¥åħ· åĴĮ +null ptr +ĠDev in +Configure Await +éĴ£ éĩij +为 ä¾Ŀæīĺ +æĢĢ éĩĮçļĦ +ç»ĵåIJĪ çļĦ +æĬ½ 空 +(dir name +w ah +Ġal oe +Com pose +åĩı ç¨İ +ç§ģ è¯Ń +è·Į èĩ³ +source LineNo +ï¼Įåı¯ä»¥ ä»İ +Basic Block +, çļĨ +. other +d ana +es o +Ġp armesan +St ake +åħ³ æĸŃ +]) [ +ĠBrit ann +å®ĺæĸ¹ å¾®åįļ +(err no +OND ON +Ġ 京 +lect able +èĦ¸ åŀĭ +Ġfont size +ĠEffect iveness +ĠVenet ian +T rav +Ġun loaded +åĨĻ å¥½ +æĻĴ å¹² +议论 纷纷 +ãĢĤ æĺ¥ +äºĨ 该 +ï¼Ł è¿ĻäºĽ +Ġte h +Ġam enable +å·¥ä½ľ æĺ¯ +äºĶ æĹ¥ +éľĢè¦ģ æĽ´å¤ļçļĦ +表 å¼Ł +_RE CE +æĬĺ çݰ +ภĤ +Gr ass +ĠHard wood +ĠGro ovy +Comb ination +ãĢģ人 äºĭ +å¯Łè§ī åΰäºĨ +(f oo +å¹¶ä¸į 容æĺĵ +Ġprosecut ing +æĦŁåºĶ åύ +Ġ åı³ +ĠN atur +Ġemp athetic +å¹¶ä¸įæĺ¯ ä¸Ģ个 +ĠN ails +åĴĮ å®ŀæĸ½ +-f amous +åħļ 代ä¼ļ +èµµ åĽ½ +Ġrev amped +ĠN ost +åĮĸ å¸Ĥ +.Set up +èĮĤ 缼 +Ġman ne +亲 æĺµ +è¿Ī åħ¥ +ĠG ron +å±Ĥ 楼 +åĿļ 硬çļĦ +çļĦ大 å¤ļæķ° +bad ge +ose conds +az es +è¶ħ è½½ +Ġair ways +Ġ é¢ĺ +ĠTrans parent +æĮĤ ä¸Ĭ +ãģª ãģı +_form ats +å´Ń æĸ° +( Collectors +æŃ£ æĥ³ +åŃĺ æ¡£ +.C ross +.assert In +ĠAu ctions +Ġm exico +ST ACK +н ов +没ä»Ģä¹Ī 好 +è¶Ĭéĩİ è½¦ +ãĢģ åIJ¸ +æ°´ 乡 +ï¼ĮæĪij ä»İ +çİĭ ä¸Ģ +Ġblack out +.B asic +åĩºåı° äºĨ +Ġconcaten ate +B race +b roadcast +Âł åıªæĺ¯ +ä¸ĩ æ¡¶ +èµĦæºIJ éħįç½® +Block ed +碰 碰 +buy er +åŃIJ æħķ +Ġco agulation +Ġincl ine +Ġ çݰ任 +ĠP emb +Ġdev otional +_pro bs +åħįè´¹ æıIJä¾Ľ +ï¼Įå¿ĥ 头 +ëĵ ¤ +èĥ½ åĬ¨ +彩 å¦Ĩ +è¿Ļ两个 åŃĹ +N FC +ould ers +没 å°ij +å®ĺ èĥ½ +(& $ +èį· å°ĶèĴĻ +æĸ¯èĴĤ èĬ¬ +é¡·åĪ» éĹ´ +_ ), +ï¼ī åıijè¡Į人 +æŀĹ éĹ´ +Ġdi aries +åıijçĶŁ äºİ +oper atively +ï¼ĮåıĪ ä¸įæĺ¯ +|| || +åĬŁçİĩ 为 +å°ı æĿİ +å¿ĥ èĦijè¡Ģ管 +Ġapp rehension +追 梦 +- Net +Ġ æ²IJ +ãĢģ å®¶åħ· +ãĢĬ éĩij +è¡Ĺ åĿĬ +ä¹Ļ éħ° +Ġdissemin ated +æİ§åζ åύçļĦ +ä¸İ 大家 +没æľī çļĦ +Ch ad +chan ics +Ġprec arious +çĭł æīĭ +ä»° åį§ +Ġvandal ism +ãĢģ èĪªç©º +åıĮ é±¼ +wit ched +è§ĦåĪĴ 建设 +éĶIJ æĦı +, æľĭåıĭ +ï¼Į éͦ +ess enger +Ġbi jection +Ġ æĺ¾åį¡ +æī¾ æī¾ +ĠMah m +D as +ï¼Ī åħ± +å±ķ æ¼Ķ +CT OR +å¢Ļ çļĦ +.read Int +Ġverb atim +Ġspat ula +ĠCauc asian +Ġm uy +æīĭ ç»ĺ +Ġam in +Ġ\" $ +ãĢģ çľģ级 +æī ¦ +Ġk cal +Ġout raged +åī¯ å°Ĩ +æĭĽ æŀ¶ +Ġcapac itors +à« ĩ +( Unit +. vertical +åĽłä¸º æľī +ĠMu ir +ĠLear ners +å·¥ä¸ļ éĿ©åij½ +.sh adow +ez vous +ï¼ĮéĿŀ常 éĢĤåIJĪ +ĠAw akening +ĠFlu ent +- util +ï¼Į åķĨå®¶ +ãĢĤ æ£ĢæŁ¥ +ĠA TC +ĠR if +å·¥ä½ľ è¿Ľè¡Į +è¿ŀ ç´¯ +-p atient +éĺ¿ åħĭ +æ®ĭ 骸 +Min ister +I z +u ire +ĠWe instein +.P ackage +Ġrect al +.Generated CodeAttribute +Ġin continence +ä¸Ń æĹ¶ +éĹ® åıĬ +Hand led +Ġп оÑģ +âħ £ +W U +ä¸į 误 +ãĢģ é϶ +ĠF reak +å¸Ĥ éĽĨ +å·² è¿ĩ +éľĢè¦ģ 帮åĬ© +mon ster +ĠRed eem +")) ) +S witzerland +s age +Ġ èĩ³å°ij +Ġw reak +å¾Ĺ åIJį +ï¼Ľ 第 +è§£ çļĦ +西 欧 +å·¥ä½ľ æµģç¨ĭ +éĢł åŀĭçļĦ +ï¼Įåħ¶ åĮħæĭ¬ +ä¹ĭéĹ´ å½¢æĪIJ +, çłĶç©¶ +, æ¯ıä¸Ģ个 +ĠD ior +ĠDe cker +ales e +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠ +ENS IONS +æµģéĢļ èĤ¡ +w et +im me +ĠC ebu +_p arty +Ġbond age +Ġfunn iest +Ġsapp hire +ç»Ļ 她çļĦ +éŃĶ çķĮ +åĨľå®¶ ä¹IJ +Ġchuck le +åįĹå®ģ å¸Ĥ +ĠC utter +ä¸ī éŨ +ï¼Įå®ĥ å°Ĩ +çļĦ æĻºèĥ½ +ç¾İ äºĨ +.s cal +ç¼ĸ å§Ķ +Key Name +è½½ æ³¢ +Ġbar ring +.Set Value +çĨĶ çĤ¼ +quant um +Ġdiast olic +Âł years +ens ky +- img +; * +åIJĪ æĪIJçļĦ +è§ģ ä¸įå¾Ĺ +æ±ĩ åħij +é£İæĻ¯ 线 +_SK IP +Ġ 带çĿĢ +æĭĽ æı½ +.F LAG +è¿« äºİ +微微 ä¸ĢæĦ£ +ä¸Ĭå¸Ŀ çļĦ +ĠS aud +ĠP ledge +ĠH SP +roph ot +åIJĬ 车 +ãĢĤ æĺ¯ä»¥ +èĩª æŃ¤ +Ġra ined +(t ok +çĿ£ æĬļ +ĠConvey or +C able +Ġtr ich +ĠAl le +æĽ¾ 说è¿ĩ +Ġå¹´ åĪĿ +åĩºæīĭ äºĨ +Ġremodel ed +Ġbrit ish +: ä»İ +ĠM ais +ä»ĸ éĿ¢åīį +ï¼Ł æĤ¨ +æĮĩ æ´¾ +Ġpred icates +=\ "" +æ¦Ĥ念 èĤ¡ +Ġpriest hood +ĠFor bidden +ĠFrank enstein +Ø ¸ +ĠH RT +æĥ³ ä¸įéĢļ +çīĪ çĶ» +ï¼ĮæľĢ ä½İ +SO CK +ĠHomes chool +缸éĤ» çļĦ +h ler +Ġm owing +ãĢģ çŁŃ +ãĢģ ä»ĵåĤ¨ +ä¼ļ åıĺ +没 çľĭè§ģ +ĠCh ore +Su itable +ï¼ ® +Ġl adders +ç¿ Ĵ +è¯ij 为 +ä¸įæ¸ħ çļĦ +âĺĨ âĺĨ +, éģĵ +m apped +t old +èĩª å°ı +Ġad jectives +ĠK and +èĢģ éģĵ +AG O +ï¼Į为 ä½ł +rote ins +ÈĽ i +ĠProte ins +çĿ¾ 丸 +/ error +Ġ åıijçݰ +ol r +ä¼ł éŁ³ +ĠRh ine +DIS CLAIM +ĠBlank et +Ġs og +, èĭ±åĽ½ +c itations +æĸ¹ åľ¨ +æīį 被 +ä½ı åĿĢ +_l ambda +ï¼Łï¼Ł ï¼Ł +Ġmoistur izing +at oms +ãĢģ åIJį +ãĢģ åħ±äº« +our y +å¹¶ ç»Ħç»ĩå®ŀæĸ½ +åħį åİ» +è¡£ 人 +ĠÏĦ ιÏĤ +Ġlag oon +Ġ{ [ +é¡ ŀ +åħ¨ çĽĺ +.s ignal +(p ub +çĭĤ åĸľ +host ing +_grad ient +, 讲 +缴 éĢļ车 +ï¼Įä»ĸ 竣çĦ¶ +ĠRes earcher +.reg ex +ir ate +çľĭ æĬ¤ +UT ER +Ġinj unctive +ĠLa placian +,åı¯ è°ĵ +æĬ¥çº¸ ä¸Ĭ +.inter faces +èĶij è§Ĩ +Ġreplen ish +ĠIMPORT ANT +ell ion +Data Frame +çͳ æĺİ +Ġlin ewidth +Ġprob ed +ĠCG AL +, æīĢè°ĵ +天 åı° +.S ort +stand s +Reg exp +els en +Ġpract ising +ĠMod elling +èĩªä¿¡ çļĦ +ĠNorm andy +åħ¬ 车 +ĠK ras +Ġx max +LE V +With Context +ï¼Į 广åijĬ +Ġg fc +åľ¨ åIJĦç§į +åĨ· èIJ½ +ĠRest ricted +ÙĬ ر +æĸ¹ä½į æĪĸ +æłĢ åŃIJ +åĩº æľī +iff el +Ġrestart ing +zs che +ĠO MX +çŃī çݯèĬĤ +-d en +éĶĢåĶ® éĩı +enz o +Ġvas cul +ĠC us +æľ¬æ¬¡ ä¼ļè®® +Media Type +B racket +D iane +V irt +Z ERO +ĠB ets +åİ» çİ© +åľ¨è¿Ļ çīĩ +ĠMil ford +_al ignment +Ġindemn ity +ï¼Į æĹ¥å¸¸ +ãĢģ ç͵åĬ¨ +Ġme ch +æIJŃ è®ª +ĠHam m +Pay Pal +ĠSt unning +Ġflo ppy +åģı æĮ¯ +çļĦèĢģ å©Ĩ +ï¼Į éļIJ +ra co +åĩ» éĢĢ +ĠRec ipient +ĠChar itable +W endy +Ġmay onnaise +ï¼Įè¿Ļ åħ¶ä¸Ń +åŃĹ çĶ» +åºĵ åħĭ +çŃīä½ł æĿ¥ +åĴĮ æī§è¡Į +ARR Y +Ġ åıĸå¾Ĺ +ï¼Į 羣çļĦå¾Ī +od ate +âĢľ ä¸ī个 +ep hy +è¿ĺ ä¸İ +æĥħ 书 +ä¸ŃçļĦ åľ°ä½į +ĠCol lier +æĹ© åīį +å·¥ä¸ļ åĴĮä¿¡æģ¯åĮĸ +串 è¡Į +åĩĽ çĦ¶ +. sequence +o cean +ï¼Į å¹¿ä¸ľçľģ +ĠP ops +ç³»ç»Ł åıĬ +Ġjo ystick +æĶ¹éĿ© åıijå±ķ +Ġpra wn +å¤ļ ç»´ +ï¼Įä½ł ä¸įèĥ½ +åħ³å¿ĥ çļĦéĹ®é¢ĺ +èĢķ ä½ľ +it ro +Ġor phans +åı¯ 转åĢº +ä¼ļ è¶ĬæĿ¥è¶Ĭ +å±Ĥ 为 +åįĩ åİĭ +Ġsubs paces +ĠOpen API +èĤĿ èĤ¾ +ĠF ond +Over lap +LOG O +ĠP endant +ãĢģ åĿļæĮģ +èĥ½å¤Ł 为 +Ġ<< = +Ġpen icillin +ï¼Įè¿Ļæł· å°± +Ġru pees +ĠMcCorm ick +Ġcamoufl age +d na +im aging +_t ls +å¸ĥ è¡£ +J azz +Ġt ambién +_M IX +uf req +æĬĢæľ¯çļĦ åºĶç͍ +å§IJ妹 们 +Ġsign er +æ¶Ī äºij +ÑĤ е +ä¸īåįģ ä¸ĥ +æ³ķ 西æĸ¯ +离 çļĦ +_S Z +çļĦ第ä¸Ģ 天 +ç»ĵå©ļ çļĦ ++ xml +get Num +Ent ropy +ï¼ĮåĽłä¸º å®ĥ们 +åĹ ij +Ġfif o +Ġobjection able +J os +b oo +on is +å°ı é¼ł +è¿Ļ个 æĥ³æ³ķ +è¡¥ åħ¨ +Ġem bar +Brook lyn +h oo +ĠR AP +Ġach ing +å·´å·´ çļĦ +Ġtreacher ous +Th ai +强 äºĨ +è¶Ĭ å°ij +ĠCol leen +_MAT RIX +èĥ½ 对 +ä½ĵ ä¾ĭ +çī© ç¾İ +æł¸ éªĮ +ä¿ĿæĮģ 稳å®ļ +ĠEnd owment +Ġmeat balls +Ġinfring ing +d if +u ve +çļĦ é¢ijçİĩ +ãĢģ çĥŁ +ãĢģ 人çĶŁ +èĢħ ä¸İ +Ġpopular ly +è¿ŀç»Ń æĢ§ +phan umeric +Built in +å°Ķå¤ļ æĸ¯ +. art +qu arter +.t opic +omy ces +-p assword +æĹłæ³ķ çIJĨè§£ +ĠSub s +ĠGood bye +éĥĬ å¤ĸ +Ġr ims +ä¼ļ é¦Ĩ +åIJĮ è´¨ +æĬĬ æĪı +æĶ¶ åĽŀäºĨ +Ġcre pt +æĮ¥ åıijæĢ§ +åķĨä¸ļ è¡Ĺ +- even +ï¼Į åĿļå®ļ +ĠS ON +Ġon Error +ä½ł è·Ł +Ġun ification +æĹł ç¥ŀ +让 ä»ĸçļĦ +Ġent hr +ä¼ĺ å¾ħ +ä¸ĢäºĽ äºĭæĥħ +Bo ys +ä¸į èĩªåľ¨ +æľī åı¯èĥ½ä¼ļ +åľ° çłĸ +ï¼Ł é¦ĸåħĪ +æĽ´ æĺ¯ä¸į +åıΠ大 +åı° å·ŀ +cont rollers +ĠPack s +éĽķ çIJ¢ +ç쵿´» éħįç½® +å¿łè¯ļ 度 +Ġinaccur acies +@ the +ï¼Į åIJĪä½ľ +æīĭ çݯ +å¹¶ 对 +ĠCon or +Ġcr umble +-c amera +/s cripts +åᢠåį¡ +_WR AP +/ UIKit +ĠT itus +ĠA IS +ĠP regnant +主è¦ģ çļĦæĺ¯ +äºļ åįļ +- AD +G adget +ĠC RL +ĠH ail +éħį 以 +Ġinteresting ly +å©´ åĦ¿çļĦ +åħ¬åĬ¡åijĺ èĢĥè¯ķ +Ġdischarg ing +ë§ Į +( Query +For ge +rad o +大åѦ åĴĮ +çĭ®åŃIJ 座 +ãĢģ åħ¬è·¯ +Ġdis perse +举 åİ¿ +_n l +ĠDep recated +ĠEl iza +åĪ¶ä½ľ æĸ¹æ³ķ +ĠCap ability +ï¼ĮåĽł åħ¶ +,æĪĸèĢħ æĺ¯ +Ġcovari ant +严åİī çļĦ +, è½» +D uke +好 æĪı +_P AN +Ext reme +j f +w oven +on uclear +Ġ( ? +Ġequ iv +éļĶ éĺĤ +author ised +西çıŃçīĻ äºº +å¤§åľ° éľĩ +à ı +Ġc ay +Ġcre ase +Ġbrown ies +ä¹Ł æŃ£åľ¨ +åĵ Ŀ +å¤ļ åĩº +缸 åIJij +éģĹ ä½Ļ +FL ASH +-Z a +. span +B çļĦ +D ynam +硬 æľĹ +л ед +Ġê ¸ +Ġfec es +Ġ å®¶åºŃ +ĠM PS +空 åİĭæľº +ĠFl avor +ĠEli ot +T iger +} =( +re se +çļĦ èĮ¶ +ĠT NT +Ġtra pez +åŁĥ å¾· +æĺŁæľŁ 天 +F iction +ç͍ å°½ +-c aps +沸 çĤ¹ +ĠM IX +ĠM anga +Ġdel im +æĬ¤ çĽ¾ +éľ² éľ² +Font s +Ġrac ially +ĠEld ers +Ġtraged ies +ĠIceland ic +çĶľçĶľ çļĦ +ï¼Į 讨论 +ĠP osit +Ġde ported +è£ ¨ +Ġel ves +åĽºå®ļ ä»¶ +è°· åºķ +åİŁåĪĽ æĸĩ竳 +Ġunbelie vably +C PI +T f +çļĦ 年代 +Ġr és +顺åĪ© éĢļè¿ĩ +.Text Box +- SC +ĠA EM +ĠP DO +è®° èµ· +ĠFour teenth +çŃī æľīåħ³ +Th under +iel en +_D RV +Ġkil n +ĠWolf gang +è½¬çľ¼ éĹ´ +åľ¨ åĽ½å®¶ +Ġi pt +åĽ´ æĮ¡ +ï¼Įè¿ĺ æĥ³ +饱 åIJ« +Ġevapor ated +S s +at oga +ĠP RC +éĩįçĤ¹ å®ŀéªĮ室 +Ġmill igrams +i eren +ãĢģ 乡 +å±± ä¹ĭ +Ġsl iders +CA RE +Ġphotos hop +åIJIJ äºĨ +Ġsur charge +Ġlot us +åħ¬ å¢ĵ +毫 ç§Ĵ +è¿Ľæ°Ķ åı£ +Ġbeet les +çī Ĵ +éĿ¢ 罩 +èĩ´ åĬ¨ +åĨħ容 为 +éĻĦ ä¸Ń +ĠEN G +Ġ 头 +ĠP IX +ĠPro ps +è§ģ åºķ +çļĦå¿ĥ æĦı +åį«çĶŁ æīĢ +Ġtrace back +åı¤ å¢ĵ +åᏠä¸ĭ +ĠS ikh +ĠE EOC +ific ent +æīĵ ä¸Ĭ +cd r +ĠOver lay +Ġadapt or +â t +è̶ 夫 +ĠCome y +æľīè¯Ŀ è¦ģ说 +ãĢģ çĽijäºĭä¼ļ +å¾Īä¹ħ 以åīį +In Bytes +åºĹ éĩĮçļĦ +çł´ 空 +_w r +Ġbi ographies +ĠDi ablo +Ġreal ising +åħ´ é«ĺéĩĩ +临 å®ī +ï¼Į åıĤèĢĥ +Ġm ongo +ãĢģ åĪĽä¸ļ +ãĢģ æĸĻéħĴ +两 åĪĨéĴŁ +Ġpersecut ed +Ġgalvan ized +- rule +æľī å¤ļ个 +æĶ¿ åıĺ +S ant +Ġe jected +åĪĹ é¢ł +åĨ· è½§ +Ġmamm ary +Ġinaug urated +ĠSequ ential +_C ANCEL +é»ij åŃIJ +ARG IN +Ġkom mer +åħ¼å®¹ æĢ§ += models +Ġb ilinear +æīĭ å¿ĻèĦļ +缴 ç³» +举 è¾¹ +è¾Ľ è¾Ľèĭ¦èĭ¦ +æķĻæİĪ çļĦ +åIJĪå¹¶ æĬ¥è¡¨ +éĨĩ åİļ +ĠRo vers +çħ½ åĬ¨ +ç´§éļı åħ¶åIJİ +O tt +Ġn op +ï¼Įä½Ĩ åIJĮæĹ¶ +ĠCustom ize +Ġdos ages +ĠNET WORK +éĤ£ 以åIJİ +车 åºĬ +æĺŁæľŁ åĽĽ +Ġinterle ukin +ï¼Į åĩºçİ°åľ¨ +ĠF UT +Âł åIJ¬åΰ +å¾ħ çĿĢ +gen ces +Ġg out +ag et +IN Y +.m aven +ĠCol t +ãĤĮ ãģ° +L ift +Ġc us +ï¼Į çİĩåħĪ +å®ļ 论 +å½ĵçĦ¶ åı¯ä»¥ +.de cl +åĪ® 缮 +ĠCob ra +Ġ ################ +End ed +ĠBlock ing +ä¾į èĢħ +ĠÏĥÏħ ν +Ġ æľĽçĿĢ +ï¼Į åı¦æľī +åĪ© åĪĥ +éĺ¿ èĥ¶ +æī§ äºĭ +ĠCheck er +Ġslog ans +" }} +\ Microsoft +ç´§ éĶģ +æĥĬ éŃĤ +ï¼ĮåĨį æĿ¥ +æīĵéĢł åĩº +S wing +ĠCh attanooga +ï¼Įä¹Ł å°Ĩ +æ²³ éķĩ +Ġcart e +Ġbru ises +è´¢ æºIJ +åı¯æĮģç»Ń åıijå±ķçļĦ +Ù Ĵ +.. ' +æĹ¥ ç͍ +çĺ¦ äºĨ +Ġantidepress ant +P ent +at ten +å·¥ äºĭ +ĠCY REG +èĩªå·±çļĦ åĦ¿åŃIJ +çĶ· çε +èī¾ çģ¸ +Ġbacter ium +精彩 åĨħ容 +ĠC ER +äºĶ åij³ +Ġteam ing +'] [] +ç´§ éĤ» +\ m +马 å°ıä¹IJ +å©ļ æģĭ +Ġmoment a +Ġdiet ing +ãĢģ å®ŀè·µ +çŃī æĿIJæĸĻ +ä¸įçŁ¥ ä½ķæĹ¶ +ä¸įæķ¢ åĨį +å·®ä¸į é½IJ +L m +ç» ¶ +Ġlo om +å¥ĩ éģĩ +æĿ¯ èĮ¶ +æłª å¼ı +Ġchuck led +ol ive +å°± éĹ® +Âł å½ĵ +äºĮ èĥİ +ĠChrist y +æ³¢ æĬĺ +æĺ¥ çļĦ +å½ĵçĦ¶ ä¸įæĺ¯ +æĬ¢ çĿĢ +Ġsnow fall +othy roidism +çİ°åľ¨ å¾Īå¤ļ +Ġtemp file +ĠAstr onom +ĠEVERY THING +et ur +âĢľ ä¸įè¦ģ +èĢĮ æĹłæ³ķ +Ġstatic ally +ï¼Įä¸Ĭ åīį +侯 åºľ +åIJĬ 带 +$ user +D BC +æĪij çľĭåΰ +ĠG MP +æıIJ è¿ĩ +Ġcr umbling +çªĹ è¾¹ +çģ° åº¦ +Ġsymbol izes +åºĶ对 æİªæĸ½ +l ı +at te +ï¼Į æĪ¿ +ä¸ĵ æľī +Cl Compile +ij d +æĻ¶èݹ åīĶéĢı +D w +\ Bundle +ĠSt ages +第 åįģä¸Ģ竳 +ull er +amp ers +ï¼Įå¹¶ åıĬæĹ¶ +-c ategory +Che st +Ġbank roll +弯 éģĵ +ĠRad iology +æīĢ说 çļĦè¯Ŀ +_ret ry +D emonstr +å¾Ģ æĺĶ +в ÑĢ +)** ( +Ġ æĶ¯ä»ĺ +ãĢģ åıĸ +è¾ĥ éĩį +æľĽ äºĨä¸Ģçľ¼ +éĹª 身 +at here +ï¼Į ä¼ij +ĠT uck +æľīéĴ± 人 +èļĿ æ²¹ +G ross +ä¸Ģ æķ´å¤© +Ġpe ppermint +æŀģ ç®Ģ +_de leted +Ġfisher y +' i +, åħ¥ +Ð ¤ +be ats +è¡Į为 åĴĮ +,å¦Ĥæŀľ 没æľī +Ġ å®ĮæĪIJ +ï¼Į 俱 +ĠG ao +çľĭ ç©¿ +Ġfavor ing +Dis pose +ï¼Įè¿Ļ个 ä¸ĸçķĮ +- ft +ï¼Į å±±ä¸ľçľģ +Ġplan ks +ĠBar row +,å½ĵ ä½ł +ä¸į论 æĺ¯ +ĠS is +ĠCom o +ä»»æĦı çIJĥ +Ġmultipl iers +( center +Ġ éĤµ +att ached +è°ĥæķ´ çļĦ +ï¼Įæĸ¹ åı¯ +äºīè®® çļĦ +ĠCatalog ue +ĠP eb +ï¼Įåį³ä½¿ åľ¨ +) ä¸ŃçļĦ +_ evt +ĠE PO +åĬ¨ åIJ¬ +æīĵ çĤ¹ +Ġdev out +ĠAm es +( region +, éĢIJæ¸IJ +ä¸Ģ èĩ³ +-t racking +æķħ 人 +Tr iggers +çIJĨ念 åĴĮ +ĠâĦ ĥ +Ġun enforce +åĨ° å°ģ +è§Ĩé¢ij ä¸Ń +ĠM ature +å¼Ģ è·¯ +éķ¿ å¹´ +Ġpet ite +Ġsports books +ï¼Įç»Ŀ 大å¤ļæķ° +g ons +å¹³ åĪĨ +ĠCon sequences +æ£Ģæµĭ æĸ¹æ³ķ +ĠPhil anth +card ia +å®Ļ æĸ¯ +.param etrize +Ġ ä»¿ä½Ľ +ï¼Į åĬ¡ +ï¼Į èĪĮ +ãĢģ åľ°æĸ¹ +建 ä¸ļ +ï¼Įä¸į 对 +.get Sub +ç´ł æĿ¥ +-com ponents +寰 å®ĩ +Ġn ad +ĠB ishops +éħį ä¹IJ +Ġhear th +Ġfluct uating +FO X +æīĵéĢł ä¸Ģ个 +èĬ±åĽŃ éĩĮ +ĠYE ARS +Y F +ãĢĤ 积æŀģ +ĠR ang +ä¼ļ æľī人 +Ġpain staking +ï¼Įåΰ æľĢåIJİ +ĠMcG raw +.Integer Field +( By +ou le +ï¼Į çİĽ +å°ĸ çļĦ +Mill an +Mouse Event +Ġisot opes +urn ed +ĠV erg +èģĶ ç¿© +æģ¼ç¾ŀ æĪIJ +åIJį åĨĮ +åħĪ åΰ +.L en +ĠFix es +顽 强çļĦ +al em +Ġm uzzle +ĠSwitch ing +Ġ 以åIJİ +ĠH SV +车 åIJİ +ĠTHE IR +Ġä¸Ģ éģĵ +not in +åī§ åIJį +è¿IJç͍ åΰ +ĠColl apse +æŁ´ èĥ¡ +éĤ®æĶ¿ ç¼ĸçłģ +, nonatomic +请 ä¸įè¦ģ +_P ARENT +æĺ¾ç¤º éĿ¢æĿ¿ +imer ick +äºĭä¸ļ ä¸Ĭ +æīĢå¾Ĺ çļĦ +Tool Bar +N ord +_ En +ãĢģ ä¼ĺç§Ģ +å¤ļ åľ¨ +åħ± å¤Ħ +Ġfat ig +ĠIron ically +ro o +ï¼Įä¸į ä¼ļæľī +æµĭ è·Ŀ +æį¢ ä¸Ģ个 +ML B +Ġ................................................................ ................................ +ãĢģ æĻº +éķ¿ æĸ¹ +li us +ä¼ģä¸ļ ä¸İ +ï¼Į大 èĩ´ +ĠSpecial ized +ĠSt air +track er +ĠTes co +( active +re views +ou in +ï¼Į çĶŁæĦı +æĺ¯ ä»¶ +ink a +åĶIJ ä¸ī +URL Connection +_un iform +ä¹Ł æĿ¥ +æīĢ åĪĹ +ï¼Ľ åĴĮ +èĢģ ä¸Ģè¾Ī +Ġ/* ! +è°ģ 说 +Ġq i +æĮ¥ åĬ¨ +p ox +线 段 +_C RC +çŁ³ éĽķ +ä¹Łä¸į èĩ³äºİ +Sw ipe +è̳鼻 åĸī +ĠE CS +-s ession +éĵĿ æĿ¿ +Ġmanip ulations +ĠBengal uru +Ġ 羣çļĦ +ore f +æĢ» 产å̼ +èĵĦ åĬ¿ +Ġrefriger ant +P agination +Ġt iling +ï¼Į å·Ŀ +Less ons +ĠCauc us +p agination +æŃ¥ å±¥ +端 çĽĸ +ç«¥ å¹´çļĦ +_length s +乡æĿij 人åı£ +ï¼ĮåIJİ éĿ¢çļĦ +_TO OL +磫 æĥħ +Ġwrest ler +å¸ĥé²ģ æĸ¯ +ç²¾æ¹Ľ çļĦ +ãĢĤ çͰ +è¦ģ çľĭçľĭ +ĠAl s +èµĽ 马 +åį· çĥŁ +ĠNass au +ï¼Į åºŁ +ãĢģ ä¹± +ï¼Įä½ł å°Ĩ +亲 æ°ij +å±ħ çļĦ +bb les +, çī¹ +/ St +大 大å°ıå°ıçļĦ +åĩĨ å¦Īå¦Ī +åĩłå¤© åIJİ +ï¼Įèĥ½å¤Ł åľ¨ +ĠArab idopsis +ĠDat abases +z et +Ġbut termilk +ç¥ŀ çİĭ +ä½ķ ä¹Ķ +ä¹IJ 竳 +.* , +æ¶Īè´¹èĢħ æıIJä¾Ľ +Go als +ĠReform ation +Ġan gr +Ġst bi +ä¿¡ ç®± +å·² å¼Ģå§ĭ +Ġexp ended +满 身 +ãĢĤè¿Ļ å°Ĩ +Ġcov enants +Ġpron oun +. escape +L ATEST +ï¼Į ä¸īå¹´ +ĠT AP +ãĢĤä½ł çľĭ +Ġbifur cation +ï¼Į å°Ķ +ï¼Į åĬŀçIJĨ +æľ¬ ä½ľ +ä½İ åIJ¸ +rid ged +ĠSp are +ĠèĢĮ æĺ¯ +ãĢĤ ç«Ļåľ¨ +ãĢģ åĪ©æ¶¦ +ç»Ļ ç͍æĪ· +Data Member +è·ij éħ· +åħ¬ä¸» çļĦ +åľ¨æĪij 身ä¸Ĭ +ĠTransform ers +Ġdetox ification +ant ra +åıª åģļ +ä¸ĩ åħ¬éĩĮ +ĠPh uket +.b ig +V egan +ãĢģ æĬĢèĥ½ +inc ible +ö k +æįı äºĨ +" Now +- Ab +/ string +æ¯Ķ è¿Ļ +æĪĸ æľª +åĸľæ¬¢ çľĭ +C leveland +Ġm idd +Ġ\ ;\ +é»Ħ è¤IJæĸij +åĵª æĿ¥çļĦ +æĿ¥è¯´ å°±æĺ¯ +ãĢĤ她 åľ¨ +æī¿æĭħ äºĨ +Pat ricia +ĠSQL ITE +P rest +ĠL UA +çݰ æĪIJçļĦ +åįķ æĮij +_N ot +ä¿¡ç͍ çŃī级 +Conf irmed +-head ing +Mess enger +w reck +ï¼Į åĬĽéĩı +ĠS ender +ĠG artner +ç¨ĭåºı ç¿»è¯ijæĪIJ +_sh apes +Christ ina +he en +ï¼Į çļĦ +Ġstr ife +åŁºæľ¬ä¸Ĭ éĥ½æĺ¯ +Ġsobri ety +G EM +_ Action +ĠPlay ed +渡 åı£ +.Des criptor +Ġw igs +ï¼Į è¿ĩæĿ¥ +ä¸į 约èĢĮåIJĮ +éĩı èĥ½ +pr incipal +åįĥ çݺ +åĩłä¹İ éĥ½ +-res ource +re pl +åħ¬åı¸ 为 +ç³»ç»Ł éĽĨæĪIJ +Co pper +Ġreinst ated +, è·Ŀ离 +, åħ¨å¸Ĥ +é¢ĺ çļĦ +西 å®ģ +çĹħ çĹĽ +-In ch +Ġ å²³ +Ġst s +ä¸Ĭ åįĬåľº +ä¸įåIJĮ ç±»åŀĭ +ole um +Ġpenal ized +Ġç®Ģ ä½ĵä¸Ńæĸĩ +ĠKyr gyz +ï¼Į 亲çαçļĦ +ĠR ope +Ġsh abby +-s ac +Res ervation +-E ast +aze era +å·¥ åĨľ +æĭĽ èĩ´ +éĺµ åĬ¿ +_v ocab +迪 åħĭ +交æµģ ä¼ļ +ĠEm ory +Sem aphore +åı¯ä¸į åı¯ä»¥ +. Async +N OV +ãĢĤ æķħäºĭ +ãĢģ 缮æłĩ +Ġsp oons +B igr +Ġampl ifiers +èĩªå°Ĭ å¿ĥ +_ vel +ä»ĸ们 åİ» +èĥ½å¤Ł åģļåΰ +Ġvirt uous +åIJŁ åIJŁ +ĠPey ton +, éļıæĹ¶ +w ara +ĠT rac +ä¹Ł å¾Īæľī +get Bytes +Ġsp rites +ä¹IJ åĿĽ +åĪ· åŃIJ +ç½ijåıĭ çļĦ +δ ο +j v +k its +ide as +ĠU CHAR +ï¼ī éĢļè¿ĩ +_s orted +该 åī§ +Ġcapital ized +æľīäºĨ æĸ°çļĦ +éªĤ æĪij +ĠGram marly +ï¼Į ä¿Ħ +ä¹Ł ç»Īäºİ +li as +åĽĽ åįģäºĶ +é¢Ħ æĶ¶ +æı¡ ä½ıäºĨ +Air port +åħ¬ 鸡 +èĩªå·± åĬ¨æīĭ +BS ITE +Ġkick off +Ġsadd ened +äºĨ ç»ĵ +ĠP ays +Ġres urf +_t l +æĽ´ åħ·æľī +åıijå±ķ 空éĹ´ +occ urrence +ï¼Į åIJ¸å¼ķäºĨ +Ġm RNAs +. contract +åı¯ 对 +ĠHe al +Ġconf luence +ĠAN T +pack ing +L orem +L ynn +Ġl ily +è¿ĩ çĶŁæĹ¥ +失 ç¥ŀ +Obj C +è£Ļ æijĨ +jud ice +ĠSab ha +æľ¬èģĮ å·¥ä½ľ +p ill +ï¼Į åĩī +Ġp omp +åľ¨ ä¸ĬçļĦ +èĥ½ éĢļè¿ĩ +.f m +ï¼ĮæīĢ以 è¦ģ +ï¼Į大 éĩıçļĦ +å¹» çģ¯ +æģ¨ æĦı +æĿ · +ĠR abb +éĺ³ ç¦»åŃIJ +ĠFe ynman +ó d +æĶ¯æĴij ä»¶ +æıIJåĩºçļĦ éĹ®é¢ĺ +_off sets +incre ase +å¼Ĺæ´Ľä¼Ĭ å¾· +-d ocument +åı¥ åı· +å¢Ļ 纸 +ĠText ile +elect ron +Ġun important +æ°Ķ åŃĶ +_ex c +Ġphosphory lated +Asc ii +K orean +ter o +Ġbudget ary +_p kg +åıį åıĽ +uc ene +me at +ĠDr illing +table Name +Ġpsych otic +殿 åĨħ +Ġmarty r +ĠL Z +au i +Ġbl inding +Col in +æĺ¯åIJ¦ æŃ£å¸¸ +op atra +å°ı 楼 +客 éĺŁ +Or lando +åİĨåı² åĴĮ +ĠMet ropolis +缮åħ± çĿ¹ +Ġit ertools +-b ye +Ġrad iology +Ġtail oring +( an +ĠX OR +ĠDis posable +Ġinn umerable +詹 å§Ĩ +Offic ials +å¼łå®¶ çķĮ +, äºīåıĸ +ä¸į æĥħæĦ¿ +ç¥ ļ +æĶ¹ è§Ĥ +éĢģ æŃ» +éĺ¿ å¸ĥ +Ġpret reatment +Ġarch iving +-em erg +iel lo +rt p +,å°± åľ¨ +å½Ĵå±ŀ æĦŁ +å¼Ĥ åĬ¨ +åŁ¹è®Ń 课ç¨ĭ +åΤæĸŃ åĩº +R ough +æľī ç®Ĭ +è° © +导 å¼ķ +AL ES +è¾ī æĺł +çģ«éĶħ åºĹ +Liter ature +ĠStrick land +ï¼Į æĮĩåĩº +ï¼Į åĭ¾ +ĠG ed +åijĬ ä¸Ģ段 +第äºĮ æĿ¡ +ï¼Įå°± æĥ³ +ĠTaiwan ese +ĠJD BC +Ġpals y +E aster +ĠÐ ĵ +ç§»åĬ¨ 端 +ĠMcK ay +Ġpanor ama +æĺ¯ è¿Ļ +ĠF ertil +çľģ äºĭ +ĠLe asing +é£Łåĵģ çļĦ +Ġunatt ended +, éĢIJæŃ¥ +. ud +èĢĮ ä¸įåı¯ +ie ux +èĬ © +æľĿ ä¸Ĭ +Toy ota +ĠE O +缴 æĮĩ +_b n +Ġ第 åįģä¸Ģ竳 +d ough +çļĦ ç͵åŃIJ +ĠA ven +Âł åĶIJ +min a +éĿŀ常 éĩįè§Ĩ +åİŁåĽł å°±æĺ¯ +ä¸Ń央 éĵ¶è¡Į +éĹ¹ äºĨ +Ġcheap ly +åıįå¤į åıijä½ľ +ĠHur ricanes +ãĥĨ ãĤ£ +. Keys +è¿Ļæł· æīįèĥ½ +åĸĿ åĴĸåķ¡ +ä¸ĢåºĶ 俱åħ¨ +Ġt ect +ä½įç½® å¤Ħ +âĢľ H +æĹł éĤª +è§£ åĨ» +æīĵ çĮİ +åıĹ访 èĢħ +å¦Ĥ ä¹Ł +以ä¸ĭ æľīæľŁå¾ĴåĪij +æĭ¼ è£ħ +cor r +楷 模 +Ġdetain ees +Ġ éĺ® +æĿ¾ æīĭ +Tree View +Ġpractical ity +. Headers +Ġ å¯Į +ï¼Į æİĮ +åı¯ éĥ½æĺ¯ +åħī æĻ¯ +ï¼Įåħ¶ éĹ´ +ç½Ĺ ä¼Ĭ +溶 èĥ¶ +ä¿Ĺ è¯Ń +cor responding +ĠP DB +pp c +åİŁ å½¢ +Cor respond +ĠSE Q +ä¸Ļçĥ¯éħ¸ éħ¯ +ä¸Ģ éķ¿ +å¼Ģå§ĭ çļĦæĹ¶åĢĻ +,æĪij们 åľ¨ +èįĴ è¯ŀ +indust rial +è¹Ĭ è·· +ĠIth aca +ï¼Į åĽ¢ç»ĵ +ĠA GE +é«ĺ å³¥ +主 æµģçļĦ +éĩij åıī +-b lood +Ġpick led +æ³ķå¾ĭ 顾éĹ® +èĦ¸ä¸ĬçļĦ 表æĥħ +ï¼Į éĢłåŀĭ +Ġun imp +èĩªå·±çļĦ äºĭæĥħ +认è¯Ĩ åĴĮ +ĠMS U +ï¼Į åĽ¢éĺŁ +ãĢĤ 人çī© +ãĢģ èij£ +åĴĮ 好 +è¿ij 两年 +Ġsk is +(p y +- organized +ĠC NT +ri osis +èĥ½ çIJĨè§£ +arg as +.b ad +_VER IFY +ĠEff ort +åĴĮ 秦 +æĹł 妨 +Ġplay book +æĹ¢ åı¯ä»¥ +Ġhug ging +Ġ ç¥Ŀ +ï¼Į æĸĩ竳 +æķĻåѦ åĨħ容 +Ġash ore +Ġp db +åIJī æĸ¯ +asp ers +draw ing +ANC ED +Ġgrac iously +ĠHert z +, éĴ± +- actin +çļĦ人 åIJĹ +ĠQu ora +ā Ă +ï¼Į åĵģ +ĠT read +ĠC CP +od oxy +ãĢģ ç¨İåĬ¡ +æĹ¥ ä¸Ĭ +è§Ĥ çľĭäºĨ +ĠCl ive +ç±»åŀĭ 为 +Rem oval +管çIJĨ æľįåĬ¡ +æĺŁ åŁŁ +-re act +åĨ·åį´ å¡Ķ +ĠHil ary ++ g +çļĦ æĸ¹æ¡Ī +ĠA man +nd t +åį³ æĪIJ +Ġsper mat +( inner +PS P +å®´ å¸Ń +dist inct +.Active Cfg +or ca +ï¼Į æĭ¿åΰ +ĠB OTH +åѦ èĢħçļĦ +Ġreturn Value +æľĢ æĥ³ +ä¿Ŀ éĩį +åŁĥ éĩĮåħĭ +æĭ¿åĩº æīĭæľº +羣å®ŀæĢ§ è´Łè´£ +ãĢĤ å¤ľ +æĬĢæľ¯ åıĬ +Ġsales person +çε ä½į +è¿ij æľŁçļĦ +åħ¶å®ŀ æĪij +ç¿» çľĭ +Ġhospital izations +Ġ ~~ +ol ini +Ġch icago +Ġsw am +a quin +âĢĿ 被 +get Text +ï¼ģ æĪijæĺ¯ +ĠSub section +-qual ified +. Out +Ġan esthetic +åij ĭ +ä¹ĭ åĬĽçļĦ +转 è½® +ï¼ĮæĢİä¹Ī äºĨ +ĠSOL UTION +çī¹ å¼Ĥ +ĠTop ology +çĵ¶ çĽĸ +ĠAff air +æĸ°åįİ ç½ij +Ġcraw led +p el +ï¼Į æ¹ĸåĮĹ +ue jin +ç»Ĩ çľĭ +N ST +× ĺ +è¿Ļæł· æĥ³ +Ġgate ways +åĪĥ æľīä½Ļ +éĺİ çİĭ +ï¼Įä¸Ģ åIJĮ +çħ§ æĹ§ +社ä¼ļ å·¥ä½ľ +"] ; +åľ¨æŃ¤ ä¹ĭåīį +è´«åĽ° åľ°åĮº +ĠS addle +对 çϽ +å°ij 说 +å¼¹ çIJ´ +Ġmigr atory +âĢĿ æĪĺçķ¥ +å½ĵ çļĦ +å¼ı 设计 +ï¼Įä¸į 好æĦıæĢĿ +åĭIJ çĥĪçļĦ +{ max +ï¼Įæĺ¯ 缮åīį +ĠPoly technic +æĭī æīĭ +åİĨåı² åѦ家 +Ġmis represented +èĤ¥ 大 +ĠStr as +å©¢ 女 +_PO OL +op ot +é¢Ĩ èĪª +æķħ éĩĮ +ç¼ĵ æŃ¥ +æŁ³åı¶ æ¢ħ +ä¸Ģ åħ« +ĠCon se +UPD ATED +Ġwrest le +ĠMAN AGEMENT +ï¼Į 姬 +get Class +LL ING +ä¾ĿçĦ¶ 没æľī +ĠHyper t +/ gen +/ security +åĬ¡ ä¹ĭæĢ¥ +ĠX code +ä¸Ŀ è·¯ +èĦļ 踢 +åĸĩ åĺĽ +Ġbeet le +ĠT ester +-S eries +ç²Ĺ çļĦ +- rep +- English +ï¼ģ â̦ +Ġinf os +ĠHum ane +Ġfet ish +æľīå¿ĥ 人 +_ dup +tern ut +ä½ı 她çļĦ +é¢Ħ åŁĭ +-J ones +æĥ¶ æĥ¶ +- acting +ine x +bold math +å¯Ĩå¯Ĩ麻麻 çļĦ +Ġbri bery +ĠLingu istics +/ å¹³æĸ¹ç±³ +he on +åľ¨ æĿİ +ä¸ĭ éĽª +士 å¤ļ +Ġunbeat able +éĩįçĸ¾ éĻ© +ï¼Į æĪ¿éĹ´ +梦 éŃĩ +Comp iled +ом Ñĥ +think able +ĠDew ey +< Self +Ġb outs +人çļĦ 身份 +ï¼Įåıª åı¯æĥľ +<< _ +Ġfo resh +kn ife +æīĵè´¥ äºĨ +äºĶèĬ± èĤī +} ï¼Ī +Ġ åĨħç½® +ï¼Į 好äºĨ +if ndef +request ed +带åĬ¨ ä¸ĭ +ãĢĤ ç½ij绾 +ĠF idel +all en +Ġme adows +cy c +çļĦåľ° çĽĺ +T une +W riters +Ġb tc +ãĢģ 鼨 +ant ib +Ġget Instance +ï¼ģ ä¸įè¦ģ +Ġcond enser +éĹ¹ çļĦ +åĬŀåħ¬å®¤ çļĦ +.I con +L åŀĭ +Ġthe rapeutics +eg lasses +.t ail +Ġa ra +ãĢĤ ç͵影 +ĠAddress es +æ½ĩ æ¹ĺ +Ġlac rosse +< % +Ġre printed +ä½İ é¢ij +"] : +æµ® æĥ³ +Ġm á +ĠAr s +.s n +æŁ¥ å®ŀ +ĠAd ele +è¡ĮåĬ¨ ä¸Ń +. ion +缸 è¾ħ缸 +è¯ģ çħ§ +ĠUS ING +å¿Ļ äºĨ +æĻ®éĢļ é«ĺä¸Ń +Ne ighbor +k ai +ĠB eware +ä¼ļ è¿Ļä¹Ī +éĢļ ç͵è¯Ŀ +è½» æııæ·¡ +ç«ŀäºī èĢħ +,ä½ł å°± +ï¼Įå·² æĪIJ为 +ãĢģæĹł å½¢èµĦ产 +ĠStam ford +e us +Ġpro ff +ht ar +ï¼Įä½ł ç»ĻæĪij +åĬ¨åĬĽ æĸ¹éĿ¢ +ĠTor o +森æŀĹ éĩĮ +ä¼¶ ä¿IJ +ä¸Ģ èĬĤ +æĹ¶ 对 +IN VALID +Ġtest Case +Adapt ive +ĠHitch cock +Ġreason ableness +ores cent +éľĩ 颤 +ĠS GD +and re +个 éĹ®é¢ĺ +å¿ Ħ +Ġapp alling +äºĶ è°· +To Be +å¼Ĥ åŁŁ +å¨ģ åĬ¿ +ï¼Įè¦ģ æĬĬ +-A z +ĠBloom ington +大 åłĨ +ä¹Ł æŃ£ +æľĪ èĸª +çŀ Į +åıªæĺ¯ åĽłä¸º +,ä¹Ł å°± +æ²Ł æ§½ +碰 å·§ +è·¨ è¿ĩ +èĥİ çĽĺ +ĠInv itation +æľīäºĽ å°´å°¬ +ĠImp lements +BI OS +ĠEc ological +Sure ly +ãĢĤ æĥ³æĥ³ +è¾ ¼ +åĽ½ ç͍ +å·² çŁ¥çļĦ +ï¼Įä¸Ģ ä»¶ +ĠRe active +éĿŀ常 å¿« +- Party +éĻª ä»ĸ +Ag ree +ãĢĤ æľŁéĹ´ +éĥ½ éħįæľī +Sp a +record ed +åIJį éŨ +Ġred ress +ĠSEC URITY +ï¼Į åıijå¸ĥ +æĺ¯ éĤ£ä¸ª +æ°ı å®¶æĹı +ĠTour ing +_ velocity +ï¼Įä½ł ä¹Łåı¯ä»¥ +ĠId le +Inv oker +ococ cal +) }$. +[ Int +b ite +ĠM CL +大 åħ³ +.p ad +æ°ı éĽĨåĽ¢ +Ġrevis ited +-vol tage +粤港澳 大湾åĮº +ãĢĤ æ³ķ +çĿĢ èĦļ +ä¹Łæ²¡æľī åĬŀæ³ķ +ĠRefuge e +D ell +S keleton +ï¼Į ä¸ĭä¸Ģ +åľ° çľĭåIJij +ï¼ĮæĪij们 è¿ĺæĺ¯ +è°ģ æķ¢ +Ġsu ede +ä¸Ĭ 表éĿ¢ +羣 èĥ½ +ï¼Įä¸Ģ åĿĹ +åŁºæľ¬ åİŁåĪĻ +å¹¶ä¸į éľĢè¦ģ +Ġincident ally +Ġrebell ious +ag li +è¿Ļ æīįæĺ¯ +æĸ¹ 管 +çŃī åIJĦ +.p b +æľª èIJ½ +æĢİä¹Ī ä¸į +.C ancel +ĠStart ups +ĠSyll abus +å®¶ åŃIJ +ï¼Ľ ä½ł +ĠBo ats +Ġ-------- - +################################################################ ################ +ãģĵãģ¨ ãģĮ +çļĦ 转åĬ¨ +to a +ï¼Įå¹¶ ä»İ +åĽ½éĻħ æłĩåĩĨ +Ġintellectual s +( acc +Ġc affe +ĠM im +çļ®èĤ¤ ä¸Ĭ +ç²Ĺ é²ģ +ï¼Įæīĭ æĮģ +Ġcomm ended +Test Data +ï¼Įè¦ģ æľī +( role +ãĢģ åįĥ +åıĬ æĬĢæľ¯ +æĿĢ åħ¥ +ä¹Łæľī ä¸įå°ij +_bound ary +åºĶè¿IJ èĢĮçĶŁ +çº Ń +æ°ij æŃĮ +ĠPass es +Celebr ate +è·ĥè·ĥ 欲è¯ķ +ust ing +str ncmp +çĻ» é¡¶ +æ·¡ éĽħ +西åįĹ éĥ¨ +, åı¯èĥ½ä¼ļ +Ð Ľ +Ġc uffs +ĠA eron +ä¸Ń åį« +yn os +è¨Ģ 诺 +ĠJournal ists +Stat istic +ĠLag range +Ġleng then +å°¼ çļĦ +Ġemb ossed +åĺī åºĨ +ĠSE AL +æ¸ħæĻ° 度 +èµł åĵģ +说æľį åĬĽ +, æ¿Ģåıij +ãĢģ èĽĭ +çģ« æµ· +åIJĮæĹ¶ è¿Ľè¡Į +Hand shake +Ġje ep +ĠE ats +å½± è¿· +表示 èĩªå·± +çĸ¾çĹħ é¢Ħéĺ² +Ġneuro log +Ùĩ ا +ĠBlo ody +Ġdevote es +, ç»´æĬ¤ +âĢĿ 模å¼ı +ĠAn at +-p ackage +åŃĺåľ¨ æĦŁ +æķ°åŃĹ è´§å¸ģ +ï¼Įè¿ŀ è¿ŀ +Ġfuel ing +ï¼Įæµ· åįĹ +ĠBL M +Ġç¬¬åĽĽ çϾ +ĠRece iving +k art +_s uite +Ġè¿Ļ ä¹Łæĺ¯ +May a +ï¼Įæĥ³ äºĨæĥ³ +çłĶç©¶çĶŁ åѦåİĨ +ĠAG M +Ter rain +ĠUn ve +åij¨ 天 +SS A +稳 产 +ĠMc P +allow ay +ĠLat itude +ä¸Ń æ±Ĥ +æİ¥ ç»Ń +Her itage +ĠP RESS +Ġend Time +åŁİ éĤ¦ +åı² çļĦ +Print ing +ĠT AC +." \ +Ġdel i +_B lock +IB Action +Ġalt ru +ç»· 带 +éŃĶæľ¯ å¸Ī +.Full Name +ãĢĤ 好çļĦ +Ġk z +,ä»ĸ å°± +Attribute Name +.y ang +_ch oice +jor ie +quis itions +T urbo +天 å¹³ +é» ŀ +и ли +åĮħè£ħ çĽĴ +ĠPupp et +æ³ķåħ°åħĭ ç¦ı +ï¼Į çĶŁçī© +ess on +æĪIJ ä½Ľ +get text +Ġbra ided +_RO LE +; èĢĮ +om n +ï¼Įä¸į èĤ¯ +绣 ç§° +Ġcra ze +ĠAdvoc ates +Serialized Name +ä¸į 以为çĦ¶ +å°ı çĮª +_R ANDOM +åį· èµ· +åĮ»çĸĹ è®¾å¤ĩ +ä»Ģä¹Īäºĭ äºĨ +(/ ^\ +D IG +ä¸į æ±Ĥ +Ġ! _ +éĽĨ æķ£ +.c od +ãģ£ ãģ¨ +_SM ALL +éģĵ èıľ +Ġ\ : +åĽŀ 乡 +ï¼Įä¸įå¾Ĺ ä¸į说 +西éĥ¨ åľ°åĮº +æī¿ç§Ł 人 +n P +åĩł è¿ij +åĬŁèĥ½ åĮº +_W ORLD +ï¼ĮæĽ´ æĸ° +æĬ¥èѦ åύ +åħ¢åħ¢ ä¸ļ +ab en +åħĪ è¾Ī +é rie +念 书 +åĸľæ¬¢ åľ¨ +,åĽłä¸º æĪij +åIJĦ个 é¢ĨåŁŁ +_cl usters +Ġmascul inity +ĠD WI +Ġlif eless +m z +p rivacy +ãĢģ æĬ¥åIJį +Ġres ets +Ġself ies +æľª åΰ +-m ark +ĠChrist ensen +Ġæľī æĹ¶åĢĻ +Ġadvers aries +å¹´ æĶ¶åħ¥ +ĠV ad +çİĭ åĽ½çļĦ +åįİ è£Ķ +åģı æī§ +éĽĦ å®ī +Port rait +OWN ER +æĺŁæľŁ æĹ¥ +ĠBrow ning += q +Ê » +Ġconf ocal +æģ© å¸Ī +ä¸įåºĶ æ±Ĥ +.tt f +m ts +ãĢģ 产 +em aking +hen ko +Ġsw iss +æĺł çħ§ +Ġneuro psych +Ġexped ite +Ġinterpol ated +ĠAppCompat Theme +in ities +am u +_m r +çł´ å¼Ģ +lam ide +ç¨į åIJİ +ĠTreat s +ãĤ¯ ãĥĪ +åıijå±ķåĴĮ æĶ¹éĿ© +ï¼Į 佩 +get Resource +éĩij é±¼ +ä¸ĸ åįļ +Ġlim o +çͳ åĬŀ +-effect iveness +: w +å¹¶ 讲è¯Ŀ +éļı éļı便便 +çIJĨ论 åŃ¦ä¹ł +Ġbour geois +) # ++ L +人 åIJĹ +Ġ+ ( +ĠY en +ĠSu k +.W orld +æļĸ æĦı +,ä¸Ģ个 æĺ¯ +ĠTh orough +æŀľ èĤī +åĩł é¢Ĺ +ESS ION +" io +T rap +ä¸į éĻIJäºİ +ä¸įæĺ¯ éĤ£ä¹Ī +ç§ijæĬĢ ä¼ģä¸ļ +ç§ĭ çļĦ +Sign er +å¤±æľĽ çļĦ +åľ¨ 设计 +ĠJ ed +åİŁ ä½ľ +Ġbas ins +ĠSil icone +ï¼ħ 以ä¸Ĭ +äºļæ´² æĿ¯ +ĠScript s +Ġglycer ol +ä¸İ ä¸ĭ +ĠExt ensive +èİī å¨ħ +Ġfle as +åĴĮ 飩 +对 éĶĻ +Ġlocal ities +.b oost +ä¹Łä¸į éľĢè¦ģ +Dub ai +V IOUS +} ï¼ī +Ġ èĻ½è¯´ +ï¼Į 礼 +Ġb v +ĠF EMA +为 å®ĺ +æľĢ éķ¿çļĦ +å¼ķ åħ¥äºĨ +ĠAtt raction +y enne +ĠM off +æŃ£ åĿIJåľ¨ +æł¸ èĭ· +ç»Ļ èᝠ+广 æ±½ +大家 åı¯ä»¥ +æĤ£ äºĨ +è°· åŃIJ +å¼Ħ æŃ» +Ġcommercial ization +寻æ±Ĥ 帮åĬ© +Ġinfl ater +a er +æľ¬ 说æĺİ书 +Ex e +}} . +ä¸Ģèµ· åľ¨ +åįļ åѦ +æ´Ĺ è¡£æľį +çĿĢä¸Ģ ä¸Ŀ +ĠSE A +å¿ħçĦ¶ æĺ¯ +ĠBeat rice +ĠIter ate +, 设计 +ç͍æĪ· çķĮéĿ¢ +(l p +å§IJå§IJ çļĦ +Ġfibr illation +Rol ling +Ġ åı£ +or ity +ĠBl itz +_D ESCRIPTOR +,æĪij 说 +æĩĤ å¾ĹäºĨ +ĠHttp Request +OURN AL +- AP +åŃIJ æĸĩ +Ġen igmatic +Ġ< % +-t one +åĩĮ é£İ +ä¼ı ç¾² +ï¼ĮåįĹ åĮĹ +ĠScan ning +æłĩ 段 +è¿ĩäºĨ å¤ļä¹ħ +Ãł i +_cl one +åĪĽç«ĭ äºİ +b ak +ãĢĤ æŁ¥ +åıijå±ķ ä¸İ +.t gz +åłĤ 课 +F p +P AY +Ġle ans +å°ı å¦ĸ +_p ixels +èĩªçĦ¶ å°± +Sk etch +Ġreform ed +_pack ages +F BI +ï¼Įæīį çŁ¥éģĵ +å¤ĩæŁ¥ æĸĩä»¶ +ust ered +åı¯èĥ½ åıijçĶŁ +param etric +åĪĴ çł´ +Des criptions +汽车 è¡Įä¸ļ +ĠKend rick +Ġv end +è½´ å¿ĥ +æĦŁæŁĵ äºĨ +ĠHerm es +, 竣 +es co +ï¼Į åĬ¿å¿ħ +SE MB +çľŁäºº ç§Ģ +æ²Ļ滩 ä¸Ĭ +y um +ãĢĤ åĪļåĪļ +Ġon stage +ï¼ĮéĤ£ æĺ¯åĽłä¸º +Ġdecad ent +j unction +ä»ĸ 羣çļĦ +åīį 两天 +çļĦç¾İ æĻ¯ +è·Įä»· åĩĨå¤ĩ +, ç®Ģåįķ +Ġ å±ķ +çļĦ éĽª +Ġcross roads +Ġqual ifiers +驱 èµ¶ +SA FE +æĬij æĪĸ +Ġconj unct +ĠD IN +容 åύçļĦ +éĢĤ é¾Ħ +Ġant iquity +-l ang +_h our +ä½łä»¬ è¿ĻäºĽ +è§ İ +Ġfr an +æij¸ æİĴ +ĠNS Number +Ġdermat ologist +ĠR ye +ä½ĵ æł¼ +Ġrec ite +ç»ĵ è´¦ +åĦ¿ èĩ£ +ĠRIGHT S +è¿Ļ åı¯æĺ¯ +åĴĮ æ´»åĬ¨ +é£İ 浪 +äºĶ èī² +社ä¼ļ å®ŀè·µ +_con verter +æĻ®éģį 认为 +ãģ¾ ãģ§ +ç²¾åĩĨ æī¶è´« +Ġsubcontract ors +/ azure +ãĢģ æĶ¹ +ĠO at +_t w +èĩªå·±çļĦ æīĭ +ç»Ħç»ĩ ç»ĵæŀĦ +åĿł åħ¥ +-tr ade +/ per +ï¼Į éģµå¾ª +ä¸Ģ æŀĿ +æľĢ åıĹæ¬¢è¿İ +li qu +éĵĿ åįķæĿ¿ +Ġundergrad uates +f acts +Ġ æĿ¡ +ĠRes istant +ĠSpecial s +æĺ¾å¾Ĺ æĽ´åĬł +_bl ue +Ġhepar in +/ fl +ĠP é +ä»ĸ æĿ¥è¯´ +ap ort +Ġfl atter +ĠQ LD +éĢı éľ²åĩº +è¿Ŀ èĢħ +æľºæ¢° å·¥ä¸ļ +éĽĩ ä½£åħµ +Ġcinem as +Ġunm anned +ä½įç½® æĹ¶ +.Se lection +\ input +ãĢĤ çϾ +æīĢ å½¢æĪIJçļĦ +第ä¸Ģ åį· +ĠCool er +åѦ æľŁçļĦ +ï¼Įå¹¶ æĹł +а Ñħ +(); // +Ġsyn apses +Ġmamm al +R Q +Ġsn oring +è¿ľè¿ľ åľ° +说ä¸įåĩº è¯ĿæĿ¥ +Ġg eb +æīĢ é«ĺæł¡ +Ġher nia +ah ua +份 çļĦ +Ġadapt s +éĽĨä¸Ń éļĶ离 +ãĢģ å¿«ä¹IJ +Ġbro ok +讲 ä¹ī +æķ´ä¸ª è¿ĩç¨ĭ +éĥ½ä¸į å¤Ł +ï¼Įå¤ļ è°¢ +. bean +ãĢĤ çͲ +ãĢĤ 大æ¦Ĥ +Ġe er +æľī æĽ´ +çĮª è¹Ħ +ाठ° +ï¼Į 设ç«ĭ +Ġp ours +ĠA loe +== ( +Ġsp awning +oh m +æľ¨ çĵľ +çĤĴ é¥Ń +car ry +çļĦä¸ĭ èIJ½ +ĠOutput Stream +Sil ent +, éĵ¶è¡Į +D ont +åľ¨ 两个 +éĥ½ å°ī +Ġup regulation +åħ¥ åĨħ +ç¨Ģ éĩĮ +ä¼łæŁĵ æĢ§ +Ġbout iques +P ope +_ Val +t rap +ãĢĤ æ²»çĸĹ +ĠR MB +æ³ķ éĺµ +温åĴĮ çļĦ +Ġlev ied +Ġbos ons +ï¼Į éĩįè§Ĩ +åĽŀ æĹı +åħΠ容 +åĬ© åIJ¬åύ +Ġblog ged +å°½åı¯èĥ½ çļĦ +ï¼Į åĮĨåĮĨ +Ġn ir +æ¿ ł +é¢ijç¹ģ çļĦ +ãĢģ ä¼Ĭ +ĠL ough +è§ī çļĦ +èĥĨ çļĦ +Term inate +_DIP SETTING += : +L ICENSE +Ġrec reated +声 åĴĮ +ä½łçļĦ åIJįåŃĹ +æ±ī æŃ¦å¸Ŀ +ILL S +in strument +Ġexc els +Ġhills ide +Ġhandic apped +s amp +ãĢĤ åIJ¬è¯´ +ĠA PO +ess ors +ä¸įæĸŃ åĪĽæĸ° +èī¾ æĸ¯ +ĠAth lete +çŃī 大 +éĢĢ è®© +çļĦé«ĺ åİĭ +Ġmerc iful +âĢĿ æĪĸèĢħ +ĠJ UD +æŁIJ ä½į +æī« ä¸Ģæī« +.re q +主é¢ĺ çļĦ +ĠRO OT +.el astic +. \[[@ +el on +Ġ# ( +çĥŃ çĨĶ +ä¸įä¼ļ 让 +ï¼Į æĵ¦ +ï¼Į æĤĦæĤĦ +ä¹Ł éļ¾ +Ġpl umbers +è¿ľ æľŁ +-g al +ĠRE CE +Local ization +ï¼Ī åĮº +Ġinst ill +åİŁ çīĪ +Ġï ģ +.ib m +} C +ĠC ray +ä¹Ł å¾Īå¿« +_RE V +Ġcoff ees +ĠUl ster +ĠVers us +_SL AVE +ä¸Ģ ä¼Ļ +åĴĮ åį¡ +Ġar re +ov ascular +.b ot +ĠCal ed +ï¼Įåı¯ä»¥ 使 +/test s +èļķ ä¸Ŀ +Ġesp ionage +\ if +ï¼Į åħ³éĹŃ +ï¼Į æĩĤå¾Ĺ +人çĶŁ ä¸Ń +Main e +ï¼ĮéϤ åİ» +p ter +Ġ åĵģ +ä¹ĭéĹ´ è¿Ľè¡Į +è°ģ åķĬ +æĹħ游 åĮº +å¾Ī大çļĦ å½±åĵį +ĠBellev ue +Ġ$ [\ +ä¹ĭ 象 +ï¼Įæĺ¯ 她 +OL F +ĠPublic Key +æģ° å·§ +Ġend owment +ï¼Įä»ĸ å¾Ī +å¹² ç³» +ĠMar quis +_s cheduler +å®ŀæĸ½ åĬŀæ³ķ +ĠDist ricts +å¦Īå¦Ī 说 +display Name +_ prime +çļĦ èµĦæł¼ +ãĢĤ åŃŁ +西 éĩĮ +çľ¼ åĬĽ +ĠBe aches +æĪIJåĬ٠䏾åĬŀ +à° ¾ +âĢľ çϾ +ĠE tc +ĠSt amps +Ġgr ime +(d ep +under brace +-government al +Ġ$ ${ +注 å®ļäºĨ +ç¼ĸ 导 +èĭ¥ ä¸į +ĠHait ian +äºĮ çĥ¯ +ç¾İ åıij +é»Ħ é¾Ļ +æĬĹ æĹ± +H olly +al ien +åıĹ åζ +åħ± æĢ§ +ED GE +ç©¿ 好 +Ġcash back +ä¸īåįģ åħ« +æĸ¹ä½įæĪĸ ä½įç½®åħ³ç³» +ä¸Ģ æĶ¹ +ĠB istro +Ġi w +· è´Ŀ +å¾Īéļ¾ åıĹ +ĠVenezuel an +çľĭåΰ è¿Ļä¸Ģå¹ķ +CO UR +Ġdelinqu ent +ç» Ķ +Ġdes de +_s dk +æ¸ĹéĢı åΰ +æĢİä¹Ī åİ» +è£Ĥ åıĺ +å°±åľ¨ è¿Ļ +é³ Ĺ +缴纳 çļĦ +ãĢģ ç»Łè®¡ +Ġdo xy +ED A +(r and +ä»İæĿ¥ éĥ½æ²¡æľī +为ä¸Ńå¿ĥ çļĦ +Ġdisrespect ful +;| & +ï¼Į çĶµæ±ł +两 åı° +fo res +端 åΰ +ĠHel vetica +Ġmotor ized +Ġk J +æĹł çĽĬ +_G AIN +Ġstraight en +åŃĺåĤ¨ çļĦ +åĩºä¸Ģ å¼ł +Ġsp ed +çłĶ åζçļĦ +Alex a +Ġ å°ı说 +ä¸ľè¥¿ éĥ½ +èĮ¶ 壶 +,ä½ł è¦ģ +åįĩ级 为 +ä¼ijéĹ² 娱ä¹IJ +need le +åĸĢ ä»Ģ +Ġdis location +Ġinter feres +è¿ŀ 个 +gs m +æĶ» åįł +ĠCapital ism +åįĹåĮĹ æľĿ +æ±¶ å·Ŀ +Ġ æ²IJæĢĿæĺİ +èµ· 头 +-f act +éĢīæĭ© åĴĮ +æijĨ å¼Ħ +(T IM +GR AP +jug ate +- ir +f ighters +ãĢģ è¾£æ¤Ĵ +_p g +Ġtrust y +éªĹ äºĨ +_MIN OR +elastic search +, æıIJåīį +ě [ +ï¼Į çł´åĿı +çļĦ 稳å®ļ +ov ial +ĠInter iors +æijĨ æĶ¾åľ¨ +Ġdark ened +åıĤèĢĥ çŃĶæ¡Ī +.un wrap +ç͍ å°ı +Ġun ifying +ĠRead Only +éĩİ èıľ +å¡« åħ¥ +å±ħä½ı çݯå¢ĥ +Ġnan ost +uis ines +beaut y +ĠF arr +éĹ ľ +ä¼ļ 缴æİ¥ +itt arius +_c a +æļĹ å¤Ħ +è§£éĩĬ çļĦ +æĬĸ æĵŀ +æĹłçĹĽ 人æµģ +' b +, åıĬ +çļĦ 缴å¾Ħ +Ġde ft +amm able +/ opt +Ġ ä½Ľ +æīį æĢª +å·® äºĭ +对她 说 +é¦ħ 饼 +rom o +åı¯ 好 +鬼 èĦ¸ +ĠCro hn +* B +u ir +ĠW ille +Ġen closures +the mes +å¾® å¼±çļĦ +ĠS ERVER +ä¹Ł æĪIJäºĨ +è¾ħ é£Ł +失ä¸ļ çİĩ +ç»° ç»° +-gu ide +ï¼Į åĽŀçŃĶ +ĠP atti +ios ync +赤 å£ģ +æī¿è¯º 书 +æīĭæĮĩ 头 +çĽ² 人 +Ġrelic s +¢ çĹķ +ĠD enny +ans ky +FER ENCES +l ä +as al +âĢľ èĩª +æķĻèĤ² åѦ +ä½ľç͍ åĬĽ +ä¸Ģçľ¼ å°± +ĠTi O +] )/ +ãĢĤ ä¸Ģ缴 +ĠT OTAL +们 对 +æĵįä½ľ ç®Ģåįķ +ãĢģ 奥 +âĢľ B +ĠMar se +æµĵ çĥĪçļĦ +PH I +ä¸ŃéĹ´ ä½ĵ +Sl ug +ãĢģ 课ç¨ĭ +Ġtr u +eb ner +Ġund eniably +ĠStud ying +éĽĮ æ¿Ģç´ł +( common +åĬł éķ¿ +æį¢ è´§ +ä¹ĭéĹ´ 设æľī +Ġbad ass +ih il +Ġreception ist +Ġanx ieties +大声 çļĦ +Spirit ual +ou la +çļĦ åĺ´ +et na +ass ociate +Ġcons erving +æīĵ 转 +Ġes ophagus +.M an +IZ EOF +ç¾Ĭ çļ® +ĠUl tr += w +Ġsa ff +åģľ ç͍ +æīĺ æŀ¶ +Truth y +: K +æĸ¹æ³ķ è¿Ľè¡Į +(d c +ä¸īåįģ å²ģ +, 缴èĩ³ +w string +æīĵ ä¸Ń +rab ly +cs r +_CON TAINER +ĠText s +çļĦæĸ¹æ³ķ æĿ¥ +ï¼Įåĩº äºİ +ï¼Į èIJ½åľ¨ +ï¼Į æīĢè°ĵçļĦ +ä¸Ń åħ·æľī +æ°´ ä¹ĭ +使 她 +äºĨä¸Ģ åłĨ +é¦ĸ æĴŃ +Ġsubsid ized +éĽı å½¢ +ä¸Ģ个 åı« +æĥ³ ä¹° +ĠHe idelberg +ĠBut cher +ä¼łç»Ł æĸĩåĮĸçļĦ +anda fter +, åĮ»éĻ¢ +Ġ çŁ¥éģĵ +Ġe bx +人 å·²ç»ı +æĿ¥ èĢħ +ma i +Ġfl ung +Ġoffset of +æ¡Īä¾ĭ åĪĨæŀIJ +ĠNight mare +温馨 çļĦ +C zech +Ġc ringe +Ġre inc +åľ£ æ´ģ +æĭĽçĶŁ 计åĪĴ +; padding +f ic +ï¼Ľ B +Ġgl Get +Ġtyp ography +æİ§åζ çĿĢ +iter als +驱åĬ¨ çĶµè·¯ +ĠReport ed +rog ens +æĬµæĬ¼ 贷款 +Attempt s +H erm +J IT +ãĢģ 交 +Ġdown grade +èĤ¯å®ļ æľī +å·¥ä¸ļ çĶŁäº§ +oxic illin +âĢľ T +èݱ æģ© +ç¼´ èİ· +Ġstadium s +ĠAval on +J i +ï¼ģ ï¼Ł +æĹł åŃĺ +-d ebug +ohyd rate +å¨ĵ å¨ĵ +æľĢ èµ·çłģ +羣 伪 +ĠAir line +åĪĽå»º æĹ¶éĹ´ +Ġlat te +ĠPsy cho +> Returns +i ership +ãĢģ 骨 +ĠG ros +File Dialog +lim itations +ï¼Įä¸įæĸŃ åľ° +. encoding +ĠP ug +Ġde pt +ä¸Ĭ å°± +åķĨ çĶ¨è½¦ +å¦ĥ å¨ĺå¨ĺ +_CNT L +x mm +un iversal +Ġv ox +æľĿ ä¸ĭ +è°ģ åij¢ +Ġpref ixed +Ġtend ons +: V +ï¼Į æŀª +Ġsh l +ĠU gly +çłĶç©¶ æľºæŀĦ +å·¥ç¨ĭ éĻ¢ +ä½ĵåζ æľºåζ +æĶ¿æ³ķ 大åѦ +N aming +ï¼Į å°Ħ +æ£Ģ å®ļ +(p arsed +åģĩ ä½ĵ +èᣠåħī +Ġutil ising +ĠMor i +èį· åĮħ +Long rightarrow +Ġkidd os +: block +Z r +_ UTF +ï¼Į åľ°æĸ¹ +ĠP orch +大 åĶ¿ +Ġint s +Ġet hernet +ç¿» çĻ½çľ¼ +欲 è¨ĢåıοѢ +bow l +ú mer += num +c ds +å¤ Ķ +ãĢģ éĢī +åıij é»Ħ +ook er +ich a +äºĮ è¯Ŀä¸į说 +æłĩ çĤ¹ +Ġ åľŁåľ° +ãĢģ éģĵå¾· +nt l +æĹ¶ ä¸Ģå®ļè¦ģ +æŀ ĩ +æİ§ çIJĥ +鼶åĶ® ä¸ļ +ĠRav i +s and + Ĩ +âĢľ People +çݰ æĹ¶ +å¤Ħ æīĢ +Names paces +c ivil +ä¸ī æĢĿ +.s wt +ï¼ĮèĢĮ éĤ£ +ä¹IJ 天 +ina ire +æĿĥçĽĬæ³ķ æł¸ç®Ĺ +_ uc +Ġ æĪIJæľ¬ +ãĢĤ ç§ĭ +åı¯ 转æį¢ +.s ym +ä»ħ ç͍äºİ +me eting +æ°ijæĹı æĸĩåĮĸ +ĠPlant ation +Ġhe eft +éĢļ åħ¥ +è·¯ è¾¹çļĦ +Ġplan ters +Ġmor atorium +Ġanim ator +äºĮåįģ å²ģ +ĠUnder wood +æįŁå¤± 以 +æĺĮ 缼 +æĦŁåĬ¨ äºĨ +Ġost ensibly +ä¼ļ ä¸İ +äºĮ åĪĨ +ĠSH OP +é³ Ŀ +ãĢģ åIJĦç±» +ĠE MR +é¦ĸ èĦij +Ïģ Ïİ +ÏĢ ÎµÎ¹ +COM MENT +op in +ï¼Įä½ł 羣çļĦ +Cmd let +çĥĽ åħī +W AR +ãĢģ æĥħ绪 +reat ive +_m ux +_c apture +ina e +çłĶç©¶ å¼Ģåıij +ĠSk yl +æijĨ åĩº +//////////////////////////////// //////////////////////// +···· ·· +Ġintros pection +ĠI da +äºĮ 线 +åij³ èķ¾ +Author ities +Ġm unch +ä¹IJ è§Ĩ +-l imit +Ġstre aks +( or +- IN +f ir +å®¶ é£İ +(" ${ +产åĵģ 线 +éĢļçŁ¥ å¦Ĥä¸ĭ +/- / +å°¼åħĭ æĿ¾ +ĠThr iller +ãĢĭ åIJİ +Ġph age +.get Color +èģĶ èĢĥ +Ġpul umi +ĠHay nes +åĴĦ åĴĦ +Ïĥει ÏĤ +(v ideo +ĠProtocol s +ĠAle jandro +- raising +Ġ èģĤ +ĠT BI +说 è¿Ļè¯Ŀ +çѹ æİª +æķ· 设 +ĠGlo ver +; q +Ġt tl +ãĢģ æĽ¾ +vers ations +ĠEs per +ĠD oha +ĠV oucher +èĭ¦ 头 +æ¯ı天 éĥ½è¦ģ +åį«çĶŁ å±Ģ +天ä¸ĭ ä¹ĭ +('/ ', +et Address +åĴĮ æĶ¿åºľ +å·¥ä½ľ åİĭåĬĽ +ç¼ĸ éĢł +) dealloc +ĠT CL +没æľī ç͍ +att ie +åħĥä»¶ çļĦ +.Response Writer +Ġenrol ment +æĺłåħ¥ çľ¼å¸ĺ +为 ä¾Ŀæį® +(t race +è¡£ 橱 +ĠGUID E +/ inf +Ġre duct +ĠM Äģ +çIJĨ 缴æ°Ķ +-t une +ĠAuto CAD +ï¼Į好åĥı æĺ¯ +Ġis lam +Ġch auff +éķ¿ ç©º +ï¼ĮæĪij们 è¿ĺè¦ģ +壮 士 +åħ±åĴĮ åħļ +ĠSco op +S aw +æĪij å·² +客 ä½ĵ +(r oute +Ġrelent lessly +éļĨéĩį 举è¡Į +Ġm aven +ĠR udd +ress ors +åĪĻ æĺ¯åľ¨ +ĠCross Fit +Ġw av +ĠM MO +æµİ äºİäºĭ +åľĪ åľĪ +诸 å°Ĩ +( selector +Ġdrink ers +å°¸ 骨 +Fore ver +éļıæľº æķ° +æĸ°åįİ ä¹¦åºĹ +Ġlou is +issau ga +as el +ãĢĤ æĬķèµĦèĢħ +è¿Ļ éĥ½æĺ¯ +æĥ³ äºĨè§£ +_p itch +ï¼Į她 åĴĮ +èµ¢ çIJĥ +Ġpuzz ling +E FAULT +S ally +lic ht +çŃī é«ĺ +ï¼Įç͍ å¿ĥ +ĠBrief ing +å¸ĤåľºçĽij管 å±Ģ +( IT +ï¼Į éĿ¢ä¸Ĭ +ĠM DR +Ġra cers +Ġcollabor ator +Ġcup boards +ĠSon ny +æ¸ħ æ³ī +ĠString Comparison +æĿ¡ä»¶ æĺ¯ +.cal culate +." ). +çħ§ åºĶ +æĬķèµĦ åĨ³çŃĸ +Ġpa uses +ĠDis hes +én é +( mean +æĶ¹ åIJį为 +è¿ĺåľ¨ ç»§ç»Ń +ï¼Įæīĵ çł´ +Ġho ax +T ol +ï¼Į å®Įç¾İ +om acy +åı¯ è°ĥèĬĤ +Ġun planned +_R AT +.I gnore +Ġescal ated +Ġp ager +Ġst oves +Ġ" ); +ç¬ij é¢ľ +Ġå½ĵ å¹´ +Ġи ли +ĠWel ding +ĠCant or +ä¹łè¿ijå¹³æĢ»ä¹¦è®° åľ¨ +âĤ¬TM t +, å®ŀéĻħ +_ Enable +p ayer +Ġs istema +æĥ³ ä¸Ģä¸ĭ +西 çļĦ +çϽ ç²ī +ĠTr istan +Ġselfish ness +Ġpatron age +he ated +pl otype +åľ° ç¬ijäºĨç¬ij +Ġun ify +ä¸įç͍ åĨį +Gr pc +ĠFam iliar +碳éħ¸ éĴĻ +ĠHumph rey +äºĨä¸Ģ åı¥è¯Ŀ +.c ross +Ġdom ino +æ¡ĥ æĿİ +ãĢĤ ä¾Ŀæį® +em ple +_d eps +AM M +ç§» å±ħ +èµĦéĩij æĿ¥æºIJ +ä¼ļ åIJİ +bers pace +è·Ł ä»ĸ说 +ä»»ä½ķ éĹ®é¢ĺ +åģı ç½® +rup ulous +Ġumb rellas +pref erred +- {\ +ä¸Ń 庸 +ĠU G +ĠV ictim +Info List +ĠRed wood +Ġwar ped +ĠSH ORT +Ġmacro economic +èĢĮ 亡 +è§ģ ä¹ĭ +æµģ ä¸ĭ +ĠAl vin +请 计ç®Ĺ +å¾ħ æľº +Ġsever ance +亲èĩª åİ» +ĠPsych iatric +ĠSqu ash +ĠT oul +ãĢģ æµ·æ´ĭ +æľĢé«ĺ æ°Ķ温 +ĠW rote +Ġde leter +iv ic +åįĥ å¤ľ +=' ', +ĠAnn ounced +ĠGra vel +Ġgloss ary +A DE +è¦ģ å¦Ĥä½ķ +åIJĥ å®ĮäºĨ +èµĦ产 æĶ¯æĮģè¯ģåΏ +ï¼ĮæĹł æīĢ +Ġauthors hip +æŃ¹ å¾Ĵ +Ġpolyp hen +åĮį åĮIJ +? t +C FLAGS +ï¼Į ç͵èĦij +ĠC ached +Ġst on +çĻ» éŨ +/d ebug +è¯Ńè¨Ģ æĸĩåѦ +æĺ¾èĢĮæĺĵ è§ģçļĦ +ĠForgot ten +ï¼Į èģĶç³» +以 éĺ² +_N ATIVE +ĠOri oles +Ġdesp ise +Ġcauc us +Ġ åIJĪåIJĮ +å®Ŀ åºĵ +壮æĹı èĩªæ²»åĮº +åĨħ ç»ı +," % +è±Ĩ èĬ½ +ore xia +åıį è¶ħ +-s olid +åħħ çĽĪ +åĨ² äºĨè¿ĩæĿ¥ +ï¼Įåı¯ä»¥ èĢĥèĻij +Root s +åĬłåĪ© ç¦ıå°¼äºļ +Ġvalu ables +çļĦ 请æ±Ĥ +ĠéĤ£ æĺ¯ +æļĸæļĸ çļĦ +ĠPhen omen +åľ° åºķ +ä¸ī åĨĽ +-s n +ï¼Įåħ¶ 主è¦ģ +ï¼ĮæıIJåįĩ äºĨ +-Q aeda +ĠPRODUCT S +âĢľ å¤ļ +åĩº ä»· +åľ° 头 +æīĵ æįŀ +Ġextrac urricular +en ol +con crete +åĬł åĪ©äºļ +é¢Ĩ äºĨ +.e ql +state ments +ĠMey ers += top +åį³ æľŁ +Ġprop hes +ĠTim my +hot el +ĠAhmed abad +åĹĸ åĹĸ +ç͍ åĬĽçļĦ +AT TER +_R S +{ th +éĤ£ 帮 +ï¼Įä¸Ģ éĥ¨åĪĨ +èĵĿ èİĵ +è¾Ľ åĬ³ +Ġaer odynamic +E thereum +F ried +âĢľ M +Ġall ure +ring ing +Ġgraft s +çļĦ è®°å½ķ +ãĢģ 康å¤į +ĠJ DK +Ġmax ima +Block Size +éķ¿ è¢ĸ +æ²³ å¸Ĥ +Ġdigit ized +Ġele venth +Ġpund its +< Data +l ur +p nt +æ±Ĥ æĥħ +Car oline +Âł å®ī +没 说è¯Ŀ +çŁ³ çªŁ +æĺŁ é©° +æ¼Ĩ çļĦ +éħ± æ±ģ +Ġpeas ants +丰å¯Įå¤ļ彩 çļĦ +éľİ æĹ¶ +O Z +st retch +ĠC ite +ĠA Q +-e lected +åİĦ è¿IJ +å¸ĥé²ģ åħĭ +-che cbox +U ARY +ĠJ em +og ia +ĠK elsey +å¹´é¾Ħ çļĦå¢ŀéķ¿ +ï¼Į马 åħĭ +åħ¬ éĴ¥ +_A UD +ãĢĤä¸į管 æĺ¯ +èħ¾èħ¾ çļĦ +. ); +åľ¨ ä½į +æľº 壳 +Ġgen omics +ĠS ensing +gh al +é«ĺ è°ĥ +åĮĹ éĿ¢ +èĩªå·±çļĦ çĶŁåij½ +äºij å±Ĥ +ç͵æºIJ 线 +rah ydro +åĽĽåij¨ çļĦ +Ġ(+ ) +b attle +Ġt ights +ï¼Įä¸į 好 +yd on +éĤ£ä¸ª å®¶ä¼Ļ +Ġsharp ness +_ owned +管 æīĢ +åıĸ èĩª +失 çģµ +-m eg +个人 è§ĤçĤ¹ +ĠRec ycl +ĠLib re +ĠDivid end +- Atlantic +Ġcol ossal +æĮģ åį¡ +积æŀģ åľ° +èµĸ 以 +éŃĦ åĬĽ +.Entity Data +ãĢģ æ¡Ĥ +ĠF us +ex plain +æİĴ æĮ¤ +ĠPr at +Ġgrat ifying +h ive +ãĢģ 幸ç¦ı +ĠG orge +æĶ¾ å¼ĢäºĨ +管çIJĨ èĥ½åĬĽ +.P arser +-B ar +è¢ĭ éĩĮ +( types +F IFA +ï¼Į åIJĥäºĨ +æĸ° 鼶åĶ® +Post ing +prov ides +r agon +åĩł æł¹ +æŃ¦ 好åı¤ +/std c +Ġ 好åIJ§ +Ġdise ased +Ġetern ally +è·ĭ æīĪ +ICollection View +d ia +ä½ľ å®¶çļĦ +缸 仿 +ï¼Įæ¯Ķ ä¸Ĭå¹´ +Ġè¯ģåΏ ç®Ģç§° +Ġlapar oscopic +ĠContain ers +ĠErl ang +g ado +æĺ¯ æķ´ä¸ª +ĠE pson +Ġpre process +oph ysics +æīĢå±ŀ çļĦ +ĠT odo +èĥ « +Ġreal isation +满 è´¯ +cent ric +é¼ĵ åIJ¹ +éĩijå±ŀ çļĦ +Week end +Ġprophyl axis +çļĦ çĹħ人 +æĸŃ å±Ĥ +æľīäºĽ äºĭæĥħ +rep end +Ġbunk er +ãĢģ ä¼ĺè´¨ +oc ally +æĸ¹ 士 +å®ī åĽ½ +ï¼Įåıª ä¸įè¿ĩæĺ¯ +æĪª äºĨ +ï¼Į 游客 +Ġm ike +ï¼Įæ¯ı åij¨ +çľ¼èĬ±ç¼Ń ä¹± +Ġ| > +æĿİ æĸĩ +æļĹ åύ +ãĢģ æ¯ı个 +è¦ģ ä»¶ +Ġwhe y +æĶ¯ çĤ¹ +æŃ¦ æĬĢ +м ен +Ġtwe aked +Ġcamar aderie +åĿ ³ +ç¥ŀ åħī +é¦ĸ éĥ¨ +-e fficacy +梯 åŃIJ +Own ership +Ġquint essential +ãĢģ 西çıŃçīĻ +åĴĮ åĩıå°ij +ç»Ħ åĴĮ +ĠQu ot +Reg isters +æī¿æĭħ 个åĪ« +ĠAlloc ator +Ġgoof y +{lst listing +çīĩ çīĩ +Ġpar rot +.b inary +PM G +Ġtort illas +缮çļĦæĺ¯ 为äºĨ +ĠÄ ° +äºŁ å¾ħ +è¶Ĭæĥ³ è¶Ĭ +/ ajax +U IC +ĠG K +å¾Ī æ·±çļĦ +_NOT IFY +æİĴæ°´ 管 +Ġ éĺ³ +èĬĤçľģ äºĨ +æĶ¿åĬ¡ åħ¬å¼Ģ +大æīĵ æĬĺæī£ +ï¼Į æ»ij +ï¼Įå°± ä¸įèĥ½ +æĶ¶ ä¹° +åħī é²ľ +çļĦ人 æĿ¥ +以ä¸ĭ åĩłç§į +ä¸ºåŁºç¡Ģ çļĦ +J uan +ä¸Ģ æľĽ +_s quare +æĢİä¹Ī åı¯ä»¥ +æĶ» åħ¥ +èµĦ产 åĴĮ +æľīçĽĬ çļĦ +.im show +æłªå¼ı ä¼ļ社 +j im +ãĢģ åIJī +âĢľ å¿ĥ +âĢľ åįĹ +æĮĩ æİĮ +å·²ç»ı çŁ¥éģĵ +弯 ä¸ĭ +Ġye a +ánd ez +( AP +Ġ æĻ® +ĠO sm +æķ¬ éħĴ +# Translate +d un +ĠM ISSING +ab on +ĠR TS +å¹³ æĺĵè¿ij +ĠSub missions +_al gorithm +ĠMand al +, The +Ġ æ¹ĸåįĹ +om ethyl +æĹ ĸ +Ġcon forms +åºĶ æ¿Ģ +éª ľ +Ġsub mar +Ġcount erex +_L ICENSE +åIJ¯ è¶ħ +atal yst +æ£Ģæµĭ çļĦ +æıĴ åĺ´ +(h Object +çļĦéĤ£ ä¸Ģ +Ġconver ging +sock opt +, å±ŀ +æĪij 以åīį +èĩª éĹ® +Ġac utely +del ivery +V II +âĢľ çĸ« +op old +ä¸ī çĪ· +ĠCon vergence +åħ° åį¡ +Enter ing +& L +Ġ( ± +åħ¬åı¸ åĨħéĥ¨ +æĥħåĨµ æĿ¥çľĭ +æĸ¹æ³ķ åı¯ä»¥ +ros cope +Ġsem aphore +ĠNOT HING +åºĶå½ĵ æĮīçħ§ +ĠRout ledge +_ rotation +Ġnd array +Ġdisob edience +ĠÏħ ÏĢ +Ġt ween +Ġth resh +ĠInd igo +ĠDes mond +Ġrol lover +ĠRapt ors +D ESC +å¹´ éķ¿ +çĸ² 软 +ĠChin atown +æ´ĹéĿ¢ 奶 +D ynamics +Ġf fi +åĪĩ ç¢İ +åĨħ容 æĺ¯ +in str +ï¼Į æ®ĭ +çļĦ è°ĥæķ´ +ä¸Ĭ çļ® +å¸Ī çĶŁçļĦ +èĭ± æĺİ +âĢĵ I +zz led +Ġsal ons +, table +W IFI +Ġ ðĿ +ol vable +Ġk araoke +åħ¥ çĭ± +OT ION +_init ialize +_OP TS +ATEG ORIES +Ġeyew itness +ant as +Ġdis illusion +_f uture +çľģ å¤ĸ +åĨĻ ä¸Ģç¯ĩ +å¹ķ åºľ +éĽĨä¸Ń 度 +, åİŁæľ¬ +\ par +ĠMag dal +Ïģ Ïĩ +éĤ® æĬ¥ +æĹº è¾¾ +åĭŁæĬķ é¡¹çĽ® +èļ© å°¤ +, ç¡®å®ļ +ĠL é +ä¸ī çķĮ +åĽŀ ä¸į +Ġpath name +ĠEn thus +ĠMat cher +è¯Ńè¨Ģ åѦ +ï¼ĮæĢ» æĬķèµĦ +çŁ¥åIJį ä¼ģä¸ļ +ĠAyurved a +å¤ĦçIJĨ 模åĿĹ +ĠHor izons +. enter +ï¼Į å¨ģåĬĽ +çļĦ æľĢç»Ī +ãĢĤ åħ± +od ds +ãĢģ éĩĩç͍ +éĩį çī© +车 ä½ĵ +Ġmin is +ĠSn acks +( ids +转 çĿĽ +.get Status +åĨ³å®ļ æĺ¯åIJ¦ +âĹĭ âĹĭ +Ġcentr ality +å¹ Ķ +æ²¹ æ³µ +ĠCO X +Ġtest ifying +æĿĢ äºĨæĪij +票 æķ° +Ġspy ware +ä¸Ģè¾Ī åŃIJçļĦ +ãĢĤ æĸ¯ +è¾¹ ä¸ĬçļĦ +Ġsculpt or +ĠD ora +ï¼Įä»ĸ åıijçݰ +Con verters +Ġart istry +N ova +ï¼Į ç»ıåİĨ +ãĢĤ åİ¿ +ip i +ĠK udos +ĠGr und +ä¿ĥè¿Ľ ä½ľç͍ +nam ely +橱 çªĹ +rompt u +% ' +ï¼Į 产 +æĹ¶ 表示 +Ġgener ational +ĠLa unched +ï ¾ +ct xt +æľįåĬ¡ åħ¬åı¸ +âij § +eless ly +Ġtele gram +ĠCrime a +< File +p urpose +Ġv ile +大 æ³ķ +è¿ĺ æľ¬ +ç±» 缮 +äºĴèģĶç½ij ä¸Ĭ +Ġbear ish +( br +anc ipation +æŃ¦ ç£Ĭ +.M aterial +ä»ģ æĿ° +è½»æĺĵ åľ° +Ġcongr ats +B or +r Ã¥ +ĠS MP +ä¸į è°ĥ +ting ly +æł¹ çļĦ +Ġpast ed +è¿IJåĬ¨ ä¸Ń +ĠNov ak +PRO P +ä¸īåĪĨ ä¹ĭäºĮ +-inst alled +Ġlist Of +Ġlevel ed +Ġchron ically +ãĢģ æķĻ +ãĢģ éĴ± +air n +Ġmet avar +Ġinvent ors +qu ila +ew e +ä¹ĭ åѦ +æĹł ä¸Ģ人 +竳 é±¼ +ĠZ ara +åĮ»çĸĹ éĺŁ +ĠMel ody +ĠOpt ics +) A +amb ient +æħ¢ æĤłæĤł +fl akes +ä¼ij æŃ¢ +Ġmicro environment +åĽºåĮĸ åīĤ +æĿŁæīĭ æĹłçŃĸ +. age +ĠC LEAN +ob ble +Ġnon existent +åıijå°Ħ åύ +B orrow +[ z + Ħ +æĶ¿æ²» ä¸Ĭ +èģĶåIJĪ ä½ĵ +èģļéĽĨ åľ¨ +âĸij âĸij +ï¼ĮèĢĮ 对äºİ +Ġpoly meric +Ġpor que +ĠConsult ancy +Ġrational ity +Ġhypert rophy +æı£ æµĭ +ìł ľ +Ġg aseous +æľĢ 常è§ģ +Ġx si +åĨ° åŁİ +空æ°Ķ åĩĢåĮĸåύ +kt or +dep artment +åı¤æĢª çļĦ +\ Request +åĴĮ æĪij说 +_s cheme +_pro d +æľīæīĢ äºĨè§£ +çIJ³ è¾¾ +ĠCatholic ism +å¼ŁåħĦ 们 +( av +ĠR TE +çļĦå¿ĥ æĦ¿ +ï¼Įè¿ĺæĺ¯ è¦ģ +éĵĥ éĵĽ +稻 è°· +æĪIJæŃ£ æ¯Ķ +Ġ æ°Ķ +Ġ æ²³åįĹ +èīº èĢĥ +ĠChile an +ä»»åij½ 为 +_FIX ED +F lower +al uronic +ĠW ad +AT I +çĿĢä¸Ģ æĬĬ +-med ium +G LOBAL +V W +il ical +å¼Ģ å¾Ģ +ms dn +Ġseek er +ãĢĤåΰ æĹ¶åĢĻ +ĠHairst yles +- ONT +Ġas ia +Th ost +Ġass ail +æ¸ħ çĤ¹ +Com ma +å½Ĵ åĬŁäºİ +Web inar +è¸ı è¿Ľ +Ġpor osity +ĠGar field +ĠVick i +è¶ħ çĦ¶ +_F rom +身ä½ĵ ä¸Ĭ +æij¸ ä¸į +éĻIJä½į æĿĨ +æĮł äºĨ += (\ +H OT +ï¼Į åĨ¬å¤© +Ġm oose +ig os +ID L +便 æľī +New swire +Ġbi ologists +Ġwood y +ä¼ļ å½±åĵįåΰ +Rem ain +Ġpanel ists +åĩ¸ åĩº +Republic an +вÐĤTM s +Ġolf actory +" T +æ·¡ åŃ£ +,æĪij们 åı¯ä»¥ +ĠClo jure +ĠVod afone +S andra +ĠF iesta +æĢ§ çŃī +离 åŃIJçļĦ +æĺ¯ä¸Ģ èĦ¸ +Ġcig ars +R ub +S usp +ä¸į 认 +éĴ Ĵ +Re vel +ĠCal ibration +ĠBo ilers +ĠSer ie +')) ; +ĠProtect ing +éĺ²æĻĴ éľľ +æľī å½±åĵį +åħ¥ 室 +è§Ħ模 æľĢ大çļĦ +临åºĬ ç»ıéªĮ +BL ACK +-sol uble +Ġso v +_p ay +sc aling +ĠLe hman +çİĦ å¾· +ï¼ĮåĬł æ²¹ +Ġmanip ulative +ie ee +æĬķ è¡Į +ä¸įä¼ļ åIJ§ +诱 饵 +ĠDund ee +\ operatorname +çļĦ æµģç¨ĭ +ĠR PA +çī© è¯Ń +ense mble +Ġinitial izes +Ġfacilit ators +Supplement al +s ad +ãĢģ 室åĨħ +Ġк о +ï¼Į 带æľī +ãĢĤ åı¦ä¸Ģ +è¿Ļ 丫头 +ĠN ing +æŀ ł +两 çīĩ +ä»ĸ们 è¦ģ +ä½łä»¬ åľ¨ +ï¼Įåį´ è¿ĺæĺ¯ +æıĴ ä¸Ĭ +ĠпÑĢ Ð°Ð² +) ') +< Double +am atory +Ġwh ist +Ġjust ifying +åģĩ éĿ¢ +Ġdiv est +è¯ĨåĪ« åĴĮ +ĠKy iv +< Value +al id +ç§ij æķĻ +é¦ĸ åºľ +_L CD +Ber lin +ï¼Į ãĢIJ +Ġp iling +Ġl ysis +ĠL ola +ï¼Įä»ĸ å°±ä¼ļ +çIJĥ åľºä¸Ĭ +ï¼Įå¹¶ æĮīçħ§ +requ encies +å¤ı é¾Ļ +èĤ¡ç¥¨ ä¸Ĭå¸Ĥ +é¢Ħéĺ² æİªæĸ½ +{ tr +ï¼Į åıij表 +ĠL ax +使 å¾Ĵ +Ġfl urry +é¾ Ľ +æ°ı æĽ° +Ġinterfer on +- SP +W ARN +åĽĽ 天 +ä¹Łæĺ¯ è¦ģ +([ - +(Un managedType +: æĪij们 +ãĢģ 丹 +ä»Ĭ天 è¦ģ +ï¼Įæĸ° çĸĨ +è´ª å¿ĥ +ï¼Į æĿijæ°ij +âĢĿ ... +ç͍ çĿĢ +è®° åı· +æļ´éľ² äºĨ +Iss uer +id r +举 åįĩ +é¾Ļ åį· +ĠFocus ing +ãĢģæ³ķè§Ħ åĴĮ +l amp +t rying +ãĢĤ åĩŃåĢŁ +ãĢģ èĩªåĬ¨åĮĸ +ter r +大 å±ıå¹ķ +åı¯ åģļ +æĶ¯ åĩºçļĦ +text up +çĻ» åı° +ï¼Į æīŃ +她 åį´ +ï¼Ī K +AL D +Ġcor r +ï¼ĮæīĢ以 æīįä¼ļ +_OT G +Ġmis ogyn +Ġscript ed +åĨľä¸ļ éĵ¶è¡Į +è¯įæĿ¡ åĨħ容 +E g +æ°´ çħ® +æ´» 该 +æĸ¯ åºķ +çģ¯ ç®± +ä»ģ å®Ĺ +åĪĨ享 ç»Ļ +vin yl +urop a +æ·±è¿ľ çļĦå½±åĵį +ĠTact ics +Thost Ftdc +Ġa woke +Ġper tain +è¯ģåΏ å¸Ĥåľº +ãĢģ å®Ī +éĢģ ç»Ļä½ł +åįģä¸Ģ äºĶ +Ġincompet ence +åĭĩå¾Ģ 缴 +ï¼Į èĩªèº« +ĠCh orus +ç±» èį¯çī© +è½» 伤 +è¿ľè¿ľ è¶ħè¿ĩ +-sp in +N SError +Ġa orta +imp lement +åĨĻ çĶŁ +-l isted +Ġ çŁ¥ +ä¸Ń èİ·åıĸ +åıijå±ķ æĪIJ +ç³»ç»Ł åľ° +åĽŃ éķ¿ +éĢĨ æĹ¶éĴĪ +_reg ular +Ġtar ot +ĠW orry +ild ed +Ġpr agma +ç¾İ å°ij女 +ms m +åıĭ çα +ï¼Įå¹¶ ç¡®ä¿Ŀ +/f ull +åij½ä»¤ è¡Į +oret te +æŀĹä¸ļ å±Ģ +åľ¨ 广å·ŀ +_S UFFIX +LL LL +çļĦ女 æľĭåıĭ +Ag ents +åłµ 车 +Ġrein vent +ĠPsych ologist +ĠRaj a +Ġis ometric +ï¼Įä½Ĩ ä¸įæĺ¯ +使ç͍ è¿ĩç¨ĭä¸Ń +abin et +纵 éĺŁ +è¯ĬæĸŃ åĴĮæ²»çĸĹ +ĠWith drawal +çľĭåΰ çļĦæĺ¯ +Ġten ets +åĩºåıij äºĨ +åŁºæľ¬ä¸Ĭ æĺ¯ +ĠSimple DateFormat +le ck +æĸ¹ æĹŃ +Context s +ç»ıèIJ¥ æĿĥ +æĴĩäºĨ æĴĩåĺ´ +ï¼Į åı¸é©¬ +ch te +ãĢģ çĶľ +âĢĿ [ +ç»ķ è¡Į +ç¬¬åĽĽ 个 +_sp arse +.check ed +ĠC ider +." ); +"> , C +d ip +g ay +Ġ æĪIJåĬŁ +æĢ§ åħ³èĬĤçĤİ +To Remove +æī¾ åĩĨ +ç»ĵ 对 +PR T +ï¼Įä¸įæĸŃ æıIJåįĩ +à¸Ń à¸ĩ +åIJŀåIJIJ éĩı +Ex cerpt +åıĹ å®ł +To Point +Al erts +Ġgy ro +ç»Ļ 客æĪ· +åŃ£ 度çļĦ +éĦĤ å°Ķå¤ļæĸ¯ +ï¼Įå¦Ĥæľī ä¾µæĿĥ +Ġh amburger +è¡Į éĶĢ +åĽŀ åºľ +éŨ ç±» +Ġcap itals +追究 åĪijäºĭ责任 +ä¹ĭ è°ĵ +è̳ çķĶ +æ´ŀ ä¸Ń +ĠImp acts +ç§ijæĬĢ åıijå±ķ +Ġparty ing +Ġglimp ses +Ġyarn s +对 人çļĦ +æ¯Ķ ä¸ĺ +æĿİ å¢¨çϽ +(t m +ç§įæ¤į çļĦ +ä¸Ģ 顾 +Ġk ap +èĩª æİ§ +åıĬ 以ä¸ĭ +-s pecial +åİŁåĽł ä¹ĭä¸Ģ +Ġsex ist +ĠMart ian +ĠSam son +Ess entially +åİ¿å§Ķ 常å§Ķ +ĠPs alms +Ġaudiob ook +B OR +Ġaut ocomplete +ä¿ĿéĻ© ç®± +Ġc actus +好 æĪIJ绩 +å·¥ä½ľ è¦ģæ±Ĥ +è®° çĿĢ +[@ " +_ FF +ï¼Į å̡坼 +ãĢĤ åľ° +Com parable +OS X +ĠMont y +çļĦ 软件 +erv ous +åıĤ å·®ä¸įé½IJ +-d ried +Ġlocal ize +ç§ijæĬĢ åĽŃ +ï¼Į西 å®ī +ï¼Įç»§ç»Ń 说éģĵ +Ġrefere es +åħ¥ éĻ¢ +æŃ£å¼ı æĪIJç«ĭ +è´¢æĶ¿ åİħ +_SET UP +ĠEisen hower +b ek +k ci +ĠT Result +å°± æĪIJ为 +Ġcl adding +åıijçĶŁ åĨ²çªģ +ĠTravel s +å©ļå§» çļĦ +Ġ æ²» +åĵ ¡ +èµ· èī² +å·¥ä½ľ å¼Ģå±ķ +éŁ³ 讯 +æĻĭæ±Ł æĸĩåѦ +ĠD ying +.d ylib +è¿Ł äºĨ +aph ne +ï¼Įä»İæĿ¥ 没æľī +mer chant +_g amma +ĠKr ish +/ ro +ï¼Ī N +两 å¥Ĺ +orb idity +ĠTow ing +åIJįåĪĹ åīįèĮħ +ä»ĸ ä¹Łæĺ¯ +ng en +éĤª æ°Ķ +k ap +å°± å½ĵ +Ġï Ĥ +ĠRend erer +ĠGor illa +s child +Ġ çĶŁæĪIJ +ä¹ĭ æľĢ +(s orted +容æĺĵ 导èĩ´ +妮 åŃIJ +èħ¼ èħĨ +b illing +âĢĶ if +Ġz er +åŀĤ æ¶İ +.un defined +Ġdeng ue +å¤ļ éĹ® +ç¢İ å±ij +âĦĥ æĹ¶ +å¼ķ导 åѦçĶŁ +缸è¿ŀ çļĦ +) _{\ +Ġ 好åĥı +ä¸į çIJĨæĥ³ +ãĢģ 群ä¼Ĺ +è¿ĩ éĩį +so v +Ġdef ensively +è̳ éĹ» +Ġnurt ured +ï¼Į ç½Ĺ马 +ĠÃ Ń +ĠMe i +æĻ¶ åľĨ +ĠBring s +ĠHaus dorff +, éĥŃ +ä½IJ èŤ +as il +ĠY uri +ule le +éĩĬ æĢĢ +Do ctors +Ġneurodeg enerative +ĠD ROP +èĬĤ æĭį +Ġsuper l +NS Data +丰å¯ĮçļĦ ç»ıéªĮ +F IFO +ĠM MM +å¿ĥ æħĮ +å·¥ éĥ¨ +com parison +ç»ĵæŀĦ ä½ĵ +Ġss id +Ġgamb ler +, ä¸Ń央 +ä¸ĭåİ» åIJ§ +ç»Ļ大家 åĪĨ享 +ĠRoll ins +åİ»ä¸ĸ åIJİ +åĴĮ æĻ®éĢļ +Ġcour ting +çĶļ èĢħ +ï¼ĮåıĪ è¢« +ĠMate o +[ size +ãĢģ æķ°éĩı +ï¼Ľ æĪij们 +表 éĩĮ +è¾ĥ è½» +); č +æĥħå½¢ ä¸ĭ +Protocol s +ï¼Į è¶ħ级 +å®ī æĶ¾ +æĸ¹ä¾¿ éĿ¢ +ĠI bn +ä¸Ģ é»ij +ĠP ru +Ġhist ograms +Inter ruptedException +Ġ åĪĨéĴŁ +çļĦ æĪIJæŀľ +cl r +ä¸Ģ个 å¤ļæľĪ +ç»Ŀ é¡¶ +word press +æ¯Ľ åĪ· +æ²Ļ åľº +ĠCast illo +Ġmultip art +\ ]( +p ayers +ãĢĤ éĽª +ĠF use +ĠN PS +å°½ æĶ¶ +鼷 åħĭ +ÏĢ Î¹ +memItem Left +ed u +Ġst rolling +éħį çļĦ +ik awa +失 礼 +éħ· æļij +渣 çĶ· +_sl ug +Ġcl ots +å¾Ī çĶŁæ°Ķ +æķ° ä¸Ģæķ° +Re play +Ġste pper +ĠRet ry +详ç»Ĩ åľ° +_log ging +ĠInvalid OperationException +æģ°æģ° 缸åıį +( and +ä¸Ĭ æ·» +ï¼ĮæľĢ éĩįè¦ģçļĦ +ä¾į å¥ī +_PRO XY +_par allel +Ġhamm ered +, 以为 +w q +ï¼Į éħįå¤ĩ +çļĦ åľºéĿ¢ +ãĢĤ åģĩ设 +ç® IJ +åĪ© çī¹ +.d irect +for ums +é¾ ĭ +Ġret reated +ĠElse vier +( ab +Č ĠĠĠĠĠĠ +çĤ¹ 对 +å¿« èι +è·Ŀ ä»Ĭ +-sm oking +ĠSu pper +çłĶç©¶ é¢ĨåŁŁ +社ä¼ļ ä¿¡ç͍ +Ġfasc ist +F lux +ĠM ermaid +ĠB ells +ä¸İ ä»ĸçļĦ +士 åĿ¦ +.N OT +ãĢģæľī åºı +éħįå¥Ĺ èµĦéĩij +缸è¿ŀ éĢļ +Ġld ap +Ġabras ion +L abs +ĠSt u +çα çݲ +åįİ åĽ½ +ĠSp iral +æľĹ æľĹ +Pub lishing +Ġdisag rees +-educ ated +Ġpaj amas +èIJ¥ çļĦ +_st a +Ġcasc ading +ĠG ER +å°ı èĻİ +ï¼Įä½Ĩ éļıçĿĢ +_S QL +ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠĠĠĠĠĠĠĠĠĠĠĠĠ +ĠP az +ãĢģ åݦéŨ +Ġdies er +ĠGadget s +éķ¿ åĪĢ +Ġam put +èݱ èĮµ +Ġliv estream +( rel +p ytest +çļĦ åıĤæķ° +SC P +é»ĺé»ĺ æĹłéĹ» +, å®¶åºŃ +j ani +ĠS CO +æĸ° èᝠ+æĹģè§Ĥ èĢħ +Ġor nate +å¿ĥ çİĩ +帮åĬ© æĤ¨ +ĠConst raints +. oo +Ġ ä¸Ģ个人 +Ġt ic +å°ı èıľ +主 ç¥ŀ +ĠCont rovers +ĠMal ware +Ġfortn ight +ĠD uel +ĠSt ove +éĤ£ éĹ´ +.n pm +. anim +Ġon slaught +ï¼ļ éĩij +ï¼Įè¿Ļ åıªæĺ¯ +æĺ¯ä¸Ģ èĩ´çļĦ +æľīäºĽ æĥĬè®¶ +Ġerad ication +g rove +ï¼Į èħ¾è®¯ +çļĦ ä¿¡å¿ĥ +Ġmed all +çģ« çĥŃçļĦ +åĮºåĪ« åľ¨äºİ +éĻĮ 离 +èĥ¤ç¦ Ľ +ãĢģ æ³ķ人 +ĠBra h +ï¼ĮæĪij åıªèĥ½ +ĠX VI +è°¢ éĤĢ +å¨ģ ä¿¡ +uz u +ç§įç±» ç¹ģå¤ļ +obb led +èµĶåģ¿ éĩij +á¹ ĩ +_ af +e ep +ï¼Į b +大 åĿĿ +Ġch ow +Ġmod ulating +AT C +Ġdon ut +åĪĻ éľĢè¦ģ +ĠPr ag +pre ting +,以 èĩ³äºİ +Inf inite +ĠE manuel +use ppe +.sh utdown +_PRO T +ï¼Į èѬå¦Ĥ +Ġl abyrinth +ä»Ĭ æľĿ +-c lear +å¹´ åĮĹ京 +é£ ķ +(" // +stand alone +è½´æī¿ 座 +æĺ¯ä¸Ģå®¶ éĽĨ +Ġphilanth rop +O ri +_g r +ĠRE V +Dep uty +Ġcoinc ided +ĠR ats +Ġdex ter +whel ming +T rivia +V illa +tt l +_c ipher +è¾¾ æĪIJçļĦ +é¢Ħ èµĽ +éĢĥ åij½ +éĥİ åIJĽ +å¾Ī大 ä¸Ģéĥ¨åĪĨ +æ¶Į èµ· +Ġadul tery +s af +Ġ ä¹° +ä¸į åĬĽ +ĠO O +ens a +æĬĽ çī© +z ones +Ġp edd +Ġconf ection +UR ST +_g rp +Ġaren as +åį§ åºķ +ãĢģ åŃIJ +ãĢģ æķĻæİĪ +æĹ¶éĹ´ ä¸İ +è¡¥ 课 +第ä¸ĢçϾ 鼶 +ĠPic nic +ãĤĪãģĨ ãģ« +ãĢģ è°ĥèĬĤ +åĽŃ 寺 +.d esign +,æĪij åĴĮ +æļ´ éĽª +Te levision +$ L +-> $ +åĬł å¾· +å±± ä½ĵ +Ġequ ates +AG C +ä½łçļĦ æīĭ +- strong +es us +æĬĢ å¸Ī +TT T +çļĦé«ĺ æł¡ +人åĿĩ èĢķåľ° +æŀ· éĶģ +J H +P urs +d rops +f on +æĹ¥ æĻĴ +che st +ĠDon or +Ġmut agen +第ä¸Ģ次 è§ģåΰ +( origin +cert ificate +/font s +çļĦ åĽ½ +å¤ĸ å¾Ħ +è¿IJ ç͍äºİ +ÑĢ ÐµÐ¼ +Rew ards +\ cell +× Ľ +Ġhe bben +æĢ» åľ¨ +Ġä»ĸ åľ¨ +. printf +Ġ åħ¨çIJĥ +ãĢģ çĶĺèĤĥ +ĠCl oser +Ġlo oms +Ġerror Code +PM ENT +碳 éĴ¢ +ant ec +èĩª 认 +( ãĢĬ +Ġ éŁ³é¢ij +ï¼Į æİ¥æĶ¶ +å¾ħ æijĬè´¹ç͍ +å¨ģ èĥ½ +容æĺĵ éĢłæĪIJ +è°ľ åĽ¢ +æĿ¥ çļĦ人 +è£ħç½® ä¸Ń +,ä¹Ł ä¸įä¼ļ +Tok yo +u F +åŁ ļ +åħ¨ 产ä¸ļéĵ¾ +å¾Ī æħ¢ +ç«ĭ çĿĢ +Ġobject AtIndex +å§ĭç»Ī æĺ¯ +.trans ition +Ġlands lide +Ġper ce +åĿļ æĮº +纯 天çĦ¶ +åĩłä¹İ éĥ½æĺ¯ +æĵ¦èĤ© èĢĮè¿ĩ +é«ĺ èĸª +å¤©åľ° éĹ´ +彪 æĤį +, åĦ¿åŃIJ +ï¼Į åįĥä¸ĩåĪ« +主 æĶ» +举 åŁİ +å¾· 森 +ĠPost ers +Me ans +Rad ar +ĠHa as +Ġà ¾ +åıijæĺİ çļĦ +污æŁĵ æºIJ +èµĦ讯 ç½ij +Ġs inner +ãĢģ æİ¥åıĹ +In vent +æĬĹ çĹħ +åľ£ 殿 +Ġnick named +西 ç«Ļ +Ġleaf let +Ġê° Ģ +s ports +Ġw ij +bl adder +ãģª ãĤī +Ġ\ _ +身份 ä¿¡æģ¯ +author ity +Ap artment +ĠINST ALL +Ġman ned +å±ģ é¢ł +å©´åĦ¿ åºĬ +/ art +被 æĴŀ +ç§ij æĸ¯ +ogen etic +Sign ificant +ãĢģ åı¸æ³ķ +us ional +åĩº è¡ĮçļĦ +Ġhere under +ï¼Į èĥľ +al beit +çļĦ æĿ¥æºIJ +åĭ Ļ +é²ģ èݽ +ĠHop f +ĠBernard ino +Ġ ç¾İåħĥ +em ing +ĠAd Words +Ġhost ess +亦 èı² +Ġdry ers +access ibility +è¿ŀè½½ ä¸Ń +ĠAdjust ed +him self +Ġ æľīçļĦ +ï¼ ¥ +ĠP addy +Ġv oir +ï¼ī åĨħ +(" x +r ased +Ġ ç»Ħç»ĩ +åIJİ è®° +åĬĽ è¡Į +.c gi +è°ĥæŁ¥ ä¸Ń +. READ +Ġ 缮æłĩ +ĠN IR +ject ure +ä½İ ä½İ +äºĴ æĦŁ +缩 éĩı +)} = +ĠReb els +-pub lished +-enh anced +Ġball park +_c ircle +SS ID +æİ¨åĬ¨ ä¸ĭ +Connect icut +Ġeyel ashes +Wh olesale +,è¿Ļ æĺ¯ä¸Ģ个 +çĽ¸å¯¹ æ¯Ķè¾ĥ +Tow ards +ist ently +Ġro ost +åĪĽæĸ° é«ĺ +çģĮ æµĨ +Ġcushion ing +Q N +ĠP g +ĠB ER +der a +æµ· æ¶Ľ +Ġorth onormal +大 éĢļ +ï¼Įä¸į æŃ¢ +Ġfund ers +ãĢģé«ĺ è¡Ģåİĭ +, len +H p +w C +yst y +ĠLog istic +ĠGC SE +Ġastronom ers +Ġe gy +Ġ$ -$ +_T AB +Ġpract icable +æŃ¦ 夷 +æľĿ ä¸ĢæĹ¥ +åIJĪå¹¶ èĮĥåĽ´ +lix ir +ĠHost el +- ear +> .< +ä¸Ģ éĴ± +è® « +è¡ ¿ +(s ym +æŁIJ 个人 +åIJ¸å¼ķ çĿĢ +ï¼Įåĵª æľī +ĠRud olph +Ġman oeuv +èĪ « +èİ« æĦģ +Ġconsolid ating +ĠWid ow +æĹ¥ 以 +å½±åĵį åĽłç´ł +orb is +ĠOS X +æĮ¨ æīĵ +. Controller +S vc +åľ¨ ä»Ģä¹Īåľ°æĸ¹ +ĠF itting +éĶģ æŃ¢ +è®Ńç»ĥ åĴĮ +Execut ing +大è¡Ĺ ä¸Ĭ +, åıĤåĬł +int e +ä¹ĭ çľ¼ +éªĤ 人 +oglob ulin +ï¼İï¼İ ï¼İï¼İ +/ rs +äºĨ åı¥ +åıį æīĭ +}} / +Ġmyel oid +她 åİ» +è§ģ çĿĢ +åįĬ å¤ı +åī§ çħ§ +大éĥ¨åĪĨ 人 +éĻĦåĽ¾ æłĩè®° +ãĢģ æĸĩåŃĹ +ress ible +èĥ½å¤Ł ä¸İ +éͦ ç¨ĭ +Ret ro +bm c +A str +ĠT old +ãĢģ çĶµæľº +Ġextrem ities +å®ħ åŃIJ +éĺ²èħIJ åīĤ +ĠFrem ont +v scale +ï¼Į çĭłçĭłçļĦ +èĩ ¾ +æĭ ® +Ġcont ending +æĺ¯ä¸Ģ é¢Ĺ +ĠSc enic +ä¾Ŀ æģĭ +è¾ĵ èµ¢ +ĠBY U +çıĬ çıĬ +; ++ +get Parent +Ġqu el +ãĢĭ ï¼īï¼Į +éĢļè¿ĩ åIJĦç§į +çİ© åģ¶ +ĠMed i +ä»»ä½ķ ä¸Ģç§į +/M icrosoft +ï¼Į éĿłè¿ij +Ġm pi +è°ĥ æį¢ +åIJ¸ äºĨä¸Ģåı£æ°Ķ +æ»´ è¡Ģ +Ġä¸Ĭ å®ĺ +ĠLat ina +ĠA erial +(p ublic +iny in +ï¼Į åĨ¬åŃ£ +è¿Ļ 两个人 +çī© åĬĽ +_s ched +以åıĬ åľ¨ +ï¼Įä»ħ ä¾ĽåıĤèĢĥ +æīĢå¾Ĺç¨İ è´¹ç͍ +v io +æľī æ°Ķ +Ġas n +ä½ł åģļ +åıij ä¸Ŀ +Ġ+ - +In herited +åIJĪ äººæ°ijå¸ģ +çŃĸ 马 +ï¼Įè¿ĺ 以为 +sub s +ĠNe ighbor +Ġcorrespond ed +æĹ©å°± çŁ¥éģĵ +-store y +Ġdist ressing +å¿« éŨ +ï¼Įåħ¨ å¹´ +ĠDermat ology +Ġinter loc +/ products +ãĢĤ åĽŀåΰ +å¸ħ çļĦ +ĠFrances co +ï¼Į çĭ¬èĩª +ãĢĤ ä¼¼ä¹İ +ãĢĤ çĤ¹åĩ» +Ġfall acy +endor f +Ġneutroph il +- My +è¾ĥ éķ¿çļĦ +ä¹Ł åĸľæ¬¢ +转 磩 +åįģä¸ĥ å¹´ +Ġmobil ize +Ġunst oppable +Z m +Ġ æĭ¥æľī +ãĢģ åĸĦ +ĠW rapped +ä¹Ł éļ¾ä»¥ +Ġres ins +iff on +没æľī åħ¶ä»ĸ +è§Ħ模 æľĢ大 +强åζ æī§è¡Į +ĠVoy ager +Ġconscient ious +Ġlud icrous +R andy +Ġ åľŁ +ĠG ideon +ä¹Ł å¸ĮæľĽ +ä¸İ æĶ¯æĮģ +-b udget +ä¹Łæĺ¯ éĿŀ常çļĦ +-ind ucing +ugg led +d ependence +çļĦ人 身 +ĠLib by +è¿ĩ è½½ +å·² å®ļ +èĥ¶ çīĩ +è´Ŀ è´Ŀ +coll ision +èĥ½ 详 +_f name +æºIJ æŀģ +æĴŀ æĴŀ +Ġiron ing +åĩĢåĪ©æ¶¦ 为 +Ġuncover ing +Imm igration +Ġsuperhero es +åħĥ宵 èĬĤ +ãĢĤ å¿ĥéĩĮ +è°Ī è¿ĩ +V GA +ï¼Į è¯ļ +ĠA irt +ĠM ott +(" __ +ram ing +Ġimprob able +Ġt ec +Ġc ello +ï¼Į åĩºæĿ¥ +âĢľ æīĵ +å¿ĥ æĢ§ +åIJĮ ä¸Ĭ +å¤ĸ ç͍ +ï¼Įè¿Ļ 让ä»ĸ +_P IX +çĶ· ä¸Ģ女 +ä¸ĢåĪĩ éĥ½æĺ¯ +(st mt +èī² å·® +ann ies +æĭĽ å½ķ +ĠAM I +AV I +jud icial +Ġsharpen ing +Ġhydrox yl +ĠMoist ur +.Iter ator +Ġcon forming +ĠH ym +Ġpr ong +æĮij æĭ¨ +çIJĨ论 çłĶç©¶ +ä¸Ńæĸĩ ç³» +ĠPeriod ic +Ġparaph rase +- images +h ak +çļĦ å¤ļ个 +åĴ¸ é±¼ += right +å°ģ é¡¶ +Def endants +ĠChar ities +.N il +ä¸ī个 å°ıæĹ¶ +æĶ¯ä»ĺ æĸ¹å¼ı +笼 åŃIJ +ĠBreak down +-en vironment +ĠEas ier +ĠRac ism +嬴 æĶ¿ +$ g +) è¿ŀæİ¥ +. ma +it re +ãĢģ éĺ²æ°´ +èĢĮ æĶ¹åıĺ +æ¶ ¿ +èİ« å±ŀ +湿 æ¼ī +ä¿Ĭ ç¾İ +ĠCur tain +P ac +ï¼Ī éĿŀ +ĠBe ckett +æĿIJæĸĻ ä¸Ń +èĥĥ éħ¸ +tra ffic +Ġclim bers +çļĦä¸ĢçĤ¹ æĺ¯ +, åij³éģĵ +Ġprot racted +.N ative +fe et +设置æľī 第ä¸Ģ +ERV E +Autom ated +Ġabbrev iations +Ġinter stellar +éªı 马 +Pen alty +M int +ï¼Į éĢīç͍ +åĴĮ åĽĽ +çľ¼ å½± +å¼ķ å¾Ĺ +ç§Ģ çļĦ +Ġep ist +Ġiter ating +ĠBiosc iences +ĠP eek +Sh annon +è¶£ çļĦ +Ġpron ouns +Ġchron icles +N Ps +è¿Ļ è¾Ĩ +iv ore +æīĢ æ¶īåıĬçļĦ +è¿ĺæĺ¯ å¾Ĺ +åĨ² è¿ĩæĿ¥ +ĠRC W +ĠTodd ler +ĠB ite +åŃIJ 模åĿĹ +ï¼ĮæĪij ä¹Łä¸įä¼ļ +æĬĢæľ¯ çŃī +ç»ıæµİ 建设 +Ġæľ¬æľŁ åıijçĶŁé¢Ŀ +对 éĤ£äºĽ +ä½ľ åĪĻ +ĠWe ir +pro tein +åĩ» çł´ +è¿İ é£İ +ĠMcG ee +- odd +ĠA CP +ind icated +çĿĢ åľ° +Part itions +ãģª ãģ© +bed o +_qu estion +ĠC ull +found ation +ï¼Į å¸ķ +诺 ç»´å¥ĩ +ä¹ĭéĹ´çļĦ èģĶç³» +æĹłå¥Ī ä¹ĭä¸ĭ +E igen +ï¼Į æī¾åΰäºĨ +IV ERY +åį§ å¼ı +å´© åĿı +Ġml x +Ġflaw lessly +ĠSHA RE +æ´¾ äºĨ +åĵŃ å¾Ĺ +ĠTur f +éŃħ æĥij +Ġsed uctive +ĠSes ame +大 秦 +æĹ¥ 飩 +æĺİ è¯´ +å°±æĺ¯ æĮĩ +Ġposs ib +Ġwar ms +æķ¬ 礼 +沿 æ±Ł +.U UID +ï¼Į è¶³å¤Ł +ĠS ND +Ġout p +(" & +è¡£ èįī +æĿĥåĪ© çļĦ +} T +ĠT CG +ate k +Ġpe ep +æĿİ åħĪçĶŁ +ĠMin im +çļĦ æİ¥è§¦ +使ç͍ ä¸Ń +è¿ľ é«ĺäºİ +è¿Ļä¸Ģ åľº +.T imestamp +ï¼Įæľ¬ å®ŀæĸ½ä¾ĭ +Med iator +Ġfibr in +ĠLuk as +åĬł èĸª +Ġtype Name +åijĬ çĬ¶ +éĿĴ çŁ³ +讲 éģĵçIJĨ +=' \ +ĠCustom ized +Ġbackpack ing +ĠRend ering +Appro val +et ah +ĠS BS +Ġne oc +ï¼Ľ å¹¶ä¸Ķ +.s mart +ï¼ĮèϽçĦ¶ æĺ¯ +马 ç«ŀ +åįı åĬŀ +, ç¥ŀ +ï¼Į éĿĻéĿĻ +ä¸į éĿłè°± +ĠWh irl +é¹ Ī +ï¼Įæľ¬ çİĭ +}^{ * +_a verage +K irk +æĶ¯ åIJ¾ +å±Ģ åľ° +Ġcool s +ĠAst hma +é¼ĵèµ· åĭĩæ°Ķ +å¯ĨåĪĩæİ¥è§¦ èĢħ +Ġ çĶŁæĹ¥ +æĢĢ æľī +ï¼Įèĩª æĪij +Ġg z +ĠS ank +ĠC ough +ĠK abul +éĩį éĩij +_S B +éĿĴ æ¶© +ĠSR AM +/ facebook +: normal +s db +ĠS ides +-s heet +æł¸ åıij +ĠBr at +ĠMid i +. Provider +_ standard +Ġhe lical +ord a +Ġheav iest +.assert That +ï¼Įåħ¨ æĸ¹ä½į +ç»ĵå©ļ åIJİ +ал и +ĠWake field +S aver +or ro +çļĦ æľĢ好 +ãĢģ åħħ满 +ç½ij绾 ä¸Ń +æĹ¢ ä¸į +害æĢķ äºĨ +ĠFred dy +_pop up +ï¼Į ä¸ĵ注äºİ +ä¸Ģ ç«Ļ +vers es +ï¼Ī éϤ +Ġperson able +绿 æ¤į +Ġ[[ [ +派人 åİ» +// \ +对 ä¸Ĭè¿° +éĢļ æĺİ +åı¯ä»¥ åIJĥ +_M PEG +Ġexc used +çļĦ主 导 +Ġchart ered +é¢Īæ¤İ çĹħ +im achinery +ort ical +æľŁ ä¸Ń +ï¼Įèĭ¥ æľī +æ£ĢéªĮ æ£Ģçĸ« +ĠFIN AL +ĠConserv ancy +g db +Ġ åĩłä¹İ +å¾Ī åı¯èĥ½æĺ¯ +"> )> +æĺ¯ åģĩçļĦ +ç¥ŀ 贯注 +æł¼ 纳 +Ġdec ryption +gg plot +_D ST +çŀª å¤§çľ¼çĿĽ +/ et +l ating +ak ens +åħ¬ 害 +æĬĬ æŁĦ +.M e +å°¼ æ³Ĭå°Ķ +Ġzero es +ĠFly er +æĶ¯æ°Ķ管 çĤİ +, é¡» +以 ä»»ä½ķ +åIJİ èħ¿ +ĠIn equality +没æľī åĩºçݰ +åıĪ åİ» +ĠX HTML +ï¼Įé«ĺ éĢŁ +.Is Valid +å·į 峨 +( orig +ï¼Į è´¹ç͍ +çļĦ èĭı +ä¸Ģ èģĬ +æıIJé«ĺ èĩªå·±çļĦ +çĭ¬ç«ĭ äºİ +ĠDest ruction +. Plugin +_ Channel +å°ı æıIJçIJ´ +å½ĵ åħµ +ĠGuang zhou +å½ĵ ä»ĸ们 +许 æĺĮ +ä¸Ŀ 线 +åĽ½éĻħ éĩijèŀį +ĠAcc redited +Ġdark net +ĠIP V +çļĦçĶŁæ´» ä¸Ń +Ġblo ated +ĠDh aka +D uck +in verse +ãĢģ æ²ŁéĢļ +åľ¨ æīĢ +âĢĻ ãĢĤâĢĿ +èģĶåIJĪ èµ·æĿ¥ +è¯įæĿ¡ ç¼ĸè¾ij +Ġquir ks +ಿ ಠ+æĺ¯ æĮī +ne o +ä¸ļåĬ¡ èĮĥåĽ´ +vest on +çĩĥ æĶ¾ +åħ±åIJĮ ç¼ĸè¾ij +ï¼Įäºİæĺ¯ å°± +ĠGentle man +Ġegreg ious +ĠD ab +å¼¹ éģĵ +æıIJåįĩ èĩ³ +èīºæľ¯ 设计 +æĹĹ åı· +ĠFort ress +(: ,:, +ï¼ ´ +çļĦ åĽ¾çīĩ +ä¸į ä¹łæĥ¯ +Ġ" {} +èĩªå·± ä¸Ģ个人 +allow ing +.max imum +红äºĨ èĦ¸ +ĠAx el +cou pon +ê ·¸ +èĭ¥ ä¸įæĺ¯ +enn ett +-l aden +顺åĪ© åľ° +ï¹ £ +å¿Ĺ åĪļ +Net herlands +ur faces +Ġk ang +å§Ĩ å·´ +Ġbrief ed +åŁİéķĩ å±ħæ°ij +æĺ¯ åĪĨ +ĠB PM +åľ° 级 +Data Table +ĠIm plant +Ġenh ancer +ç®Ĺæ³ķ çļĦ +æĭIJ çĤ¹ +Ġrenov ate +OFF SET +uter onomy +çļĦ çĶŁ +ãĢĤ éļı +ĠS lavery +ä¸į åİĮ +ä¸Ń åı¶ +ï¼Ľ åĽłä¸º +ç®Ĺ äºĨåIJ§ +ah assee +Ġopt ically +Ġaccommod ates +R alph +ï¼ĮæĪij è®°å¾Ĺ +åĽĽ 项 +é»Ħ å·¾ +森 çī¹ +ĠRel iance +çĤ® çģ° +âĢľ 好åIJ§ +Ġsh rew +æį¢ ä½į +\ ref +ä¹ĭ åĬ© +两 å¤Ħ +ãĢĤèĢĮ è¿Ļ +ĠFOR CE +.res erve +ãĢģ å¿«æį· +åĨħ è¿Ľè¡Į +ï¼Įä¸į è¡Į +ĠCam ino +- os +Sh anghai +ĠSub sid +åĸĬ è¯Ŀ +äºĶå¹´ 级 +ĠLif ecycle +G ithub +çļĦ åĪĢ +ac ola +.d irectory +è¿Ļä¹Ī éķ¿æĹ¶éĹ´ +æĢª 人 +è¯Ĺ 人çļĦ +,éĤ£ ç§į +T bl +æľº ä½ĵçļĦ +æ· ŀ +th i +ĠG aw +éķ¿ æ²» +Ġsur ging +ç®Ģ ç®Ģåįķ +Ġ æĢ§åĪ« +ãĢģ æĬ¤çIJĨ +ä¼ļ éĢIJæ¸IJ +åıĬ åIJĦç§į +éĢī æīĭçļĦ +Ġdec id +è¿IJåĬ¨ æĹ¶ +pred icate +Ġascertain ed +W x +_c atalog +å·ŀ ç«ĭ +æĸĩåĮĸ åºķèķ´ +ĠAng er +äºĭä»¶ ä¸Ń +å¼¥ åĭĴ +Dist inct +èģĬ天 è®°å½ķ +Ġrasp berries +åIJ¬ 她 +çĹħ éĢĿ +æł¹æį® ç»Ļå®ļçļĦ +æĦģ çľī +ethe red +-bl own +ä¼Ĭæĸ¯åħ° æķĻ +ig ram +.v olume +Liber ty +_ ## +æ±Ĥ åĴĮ +èµµ 丽é¢ĸ +åĨῬ¡ 被 +éĺħ读 åİŁæĸĩ +çļĦçĥŃ çĤ¹ +éĻĪ æĹ§ +ĠMAP K +Ġadam ant +D n +L ion +飩 å¼ı +ç»Īäºİ åı¯ä»¥ +Ġer st +é©» 马 +ç¼ł çĿĢ +pers istent +Ġbru ised +ĠVu itton +R ental +ad oes +ĠO TT +è¦ģ äºĨ +ib uf +aut ilus +_F ree +åŃ¦ä¹ł èĢħ +Ġhex agonal +é¡¶å°ĸ çļĦ +spe ech +æŀĩ æĿ· +ï¼Į éĢŁ +port ing +_ST A +ä¹ĭéĹ´çļĦ å·®é¢Ŀ +Ġgru esome +é¢ģå¸ĥ çļĦ +.Res olve +(Method ImplOptions +M ist +v ig +Ġ( ...) +æĺ¯ æ°´ +å°±æĺ¯ å°Ĩ diff --git a/vocab/ling_vocab.mllm b/vocab/ling_vocab.mllm new file mode 100644 index 0000000000000000000000000000000000000000..c12f8df7da410f19933f21e506b5cfafcf5ad81e GIT binary patch literal 2772094 zcmb6CcbpVO_dSkZaz@Nq$D9#!*50Yp=754ZFvA8|S=e<0h;aaO#GJJWn*d=6l0&-; z=72ftn6qNe`aQS0YWDrSexHASKJDY4Q@5(CE8MzuE6h&kirnyRC((cO|F`phDA-;k zcT{H=vIGAcba7xu{vC96U?++N-5l6iBnrAau!~3>^l)HTkwVbZf!+Aul3ot%E;68` zw*z~Kq)PfYu&2nNlD-b?#g~@!b6}vz;FA6h>@AWhSD_P%xeMPP- z*}#GQL?)MP=)nFW_m*trzybV(l8qfWP^6_~69*0wX)D>(frCXBmu%+1A^g&k%^f&Y z=!2&7S+JPfQz9`wofuls$m2B%kAo6=j%7GI8H?5VV z^^+Fqnr0{4!Onw4b1u_9ZgSxFWg zCz48QC24BMi|m+YC0THS$gXKtk_9J;AD~g)2t*5P7ygc%}TOh zu*l(QR+0s$vQE>iBnwVs#?!1M3xUtR+0s0hzw1$k}Nn= z%G%Lvhc7Ty-R+0thiBzRoNfw;XhLmO{S#W_! zeVUbI!7!1F)2t*5G9s6y0|&BfZ|M>ThKo#0vy!Y>smN7nR+0r}BG;r@Nfwl|S*BS@ z7F4i5rddfAj1ajg%}TOhq{uC4R+0skY`tk#k_8uv+@5A7SujfE&NM5@f+~@_)2t*5 zMzfKpSxFX*5xGCjO0u9@%oCe2E+V64cDG%Lx1aU!$QtRxFA7MY!9C0Q_@JuA&hvfvVtd1+RX1(%8} zNVAeGxJ+bWnw4b15NCy*j3Z4rzC7T zrPHja1T~7})2yikHHkctW>qDqnY}vAx=K)s$TMkHR)ShZo=dZ~5;Q~Pg*2-xK{KfU z(yXrp%@TPz%?eA`*ftg!^m5qUk$Doaosbw!$WmY}&JZ>L#l37RMJZkn~0p!p*2 zr&(K;60}6*t28SwK}$ux zNwfA6v`pl?G^;N`%c-o=tiJ@U5cx693QW*Sk)PA7!33=m`8CZdv}kpXdM(X5Owa_8 zKhvzl1WgqAJAI``lSKYaQ#=W~ihmf2C+KQczoB@7uHk!>Xa z#S?VBNH;_A1l=Ig-B3J1H;VKy6i?7iRIG;L3A$ONm!WuqZV~BiD4w8OMfwWMf0|1l=#PiJ^Fc9uV2oP&`2oau6^SPtZdmn;VKJ=wXp948;@lh{%?P z;t7g4UKoleXo|?zhT;jDDzc5Cc!JpDwlx$_5PMw8P&`5GaoZV+C#Z==hoN|anniXn z6i*O)+>VCg31W}i$xu8&>~T9AiYJIYZWlxG1hL2MYABwdM@4os6i*QQ-|mLu31a`- z!%#dy?0`;Mu+#`0V64UMxJ5<`N_J|$I zn7l{qP%vveVuuRN6CSZc9c`ZUh#l$}^OQ&IP{*35Jz|GC&OGB0JJj*!S&!JEPB71T z#13_$dEO&-sFTbK9`>>M_dQ~Vy1;zk5j)f{Q}Bo#Dq}wMh#e|xKJthiYPk8>BX+1#^NC07P-W&* zkJzEg&1W95Lsgj1Jz|F%VZQK)9crZc(j#`LO7oRR>`)h)uRUUi8fCumh#jiReCrWA z)M)daN9<5z%=aF#Lsgq~9)c1hq}o8=n*?qt@+6#cBne@vq$Vu_2w6k*r6KC zuO6{OjWxe{#11vi{O%Du)WzlxkJzEcn?F5bhq}c4!=sG1QcnI1$v-COLNa+6F?CsAHY6V~){D9hJgWqK27u2xTPXZc-i z`Vc3%s*~K+rY~W)B$N8?YfL{EySi3#*O>l3_MCQ>;a@U#xL`hnuw2;mE zK9DJ2XErDXjuW}wZ0G_jnXBu~MjqACnl>9dRNWxC8_XsSW%<1~noWtiYyO#o{A|hH zXg2fVRW!cM=0r&zDkOK4*`f$*L~b@)I#@Yogye2ETNOjAX{(#9i*UH)ZZX>sY7Lc_ ziQHn$?!Zo>1}2QA7fg6s^o4nI}#@u z9nIN**~!65R%`Bdv$L0;-p;0chuMW#^HRkoaEIB|h2|q|J$IVjinzX7a(9~DopdGZ z;V!cWQSzoT$=zl4EDBdwaJFIgB2KD2JB9*xn}IHNmX&dj+1rV)o~rr2#|(0zwJfrG z%|1l>o!a#Bk>u_*`?~P*dXf9geniQ;M@sHKvp-?dC+bIXK4T7W!li5l_nQNqaQPU< zeZU+f#mY*)U2h71PIvX#$^n>OQ7rl~BQ%_HV0hbpTi_lOCIk}qP>N2Y`@`6BI|kx3VW`Iafh zxZu?-?W-g=#lYjn_UW9QnXriS&61mHjxI)L@0(_hA+$<@6*J8o>xG;0Y!uVYaV~T$ z-#pzM?@*SRZZszlCD}Yqa*gK1A{@$@pE;=r*$LWIobLh~ z_(ikL1w{6Xrnhs{m}7ESPdGW52d(2c3+RtF~Xy?$p(2On$P?Ih+V+i%t`A9Ri$W#~ca2DDk zQ{(XJ<~+yU#pWW98{69?x7gGY>-)y)z_P^D5!%K{O}oU@JK=o9-Y82=gA>k2M@Vj| z8S8@C5ty}QW}J)Mz)rQyT1&ZH>9fY%d zULsGLTZvqISxM>KlV-Ay-MD5FohRltFVUD^+1?_#r_AkSk~UbXZRlxphl|1v&A#=t zxzi^xT`h!X%v~NgY9%~l?k3g@l~Y?hYwq!(Ez~W!XU)AXG&`LB8FQZt<)BJs@tnDz zIC*)Ejy}(u2b_2V$IR!=gAUbJ(w$=-B1&p7Ex8xW!!EFNl*o(b5f?a;6_R_=L@uy_ znObY6I8?*3Uu&ikC7mWq9rco#=AxGCp!1TMPG}2}4Nr&amrbLKu)2}jCHJyvauM>; zSdmvuvyZ^>G`~!8ub7tq%g_LQ)wH@O<#qh-SIrCutEs-^H8azP)-v=pGmFr+oyK-X ze%(AutR;LA`~2%>whwL1a|ZB+nd3rhY9#lDY4f3t8v3T0>q6BKc+<=y(ju(X9{rY? z?_fTHi0df+#$6g-Zv|V-1je+-1}x_G3uEjADC5ywt}?0IR<}V zVi$cBGgdH<6D5r*t0Q>9w7dAV<@~S@&1%9VdFqwihbHfWtEsT%BeTW@Q>U^iePo_+ z!TIPkk&n%jK6Z-^EFYVvy!iF`>*?AvPdjmIdVOM^Axtt;snd~~ejJ~J;kSj|t7&&`X3T5PnZa-W;EE^a%#yg`)oz7r+)wRw|J3vskH z?Y=Q@Ih>EmSmxiDw~1{f(M)2ekZ;X9WNhMW^H@WXkfmoBWj%-Fb><@{Og+QQ|6o4$kz3lQNbU#o ziO0=Uvht((lvoq1VY&TiJ|ohcl(W;wPv&zk+|vG-UW{%pP^a_VAnJI$w` z%~w7;ZD9GueC@;s4wT$4<{O9h-kY9S^Q{xjM<+|}SMwdAelzPcEApH9-UZjP>EwPh z>m1CgHT}E!!NGiVspNh)KNcaI@gL?VLZ2_{{@fqt=b`|M>`(KH6UayPBh_^K)BH+C zOQDLY_%HLD6VGx+lKad2PH5|+DbMcxxB0^b=c7<^f15u$f>~Yvn7=%3X{Qu@UQvTM`+^sFaMeUJZ{V{klcSpbC$e+%|zxAortxPvbFUR2s*o9 z8Y|S2f-c1V^V!;CL02b1Td0j5Yjh*#Bb8$%=!EV*v{B9aPUum@oRh|#(39Awry1;w zUS6V^laZh^dJ}7gD%E)Jj6OcNk*|w8qpuHECDaA|Trl%n&P84HCrH|a>;73&uxjN@1ubj1c!@$+Qi+lm5<-d8kZi}x)}cy33^}~!cA;)9aFcCza-ZK+qwwZ5#f8@oB#d_?0u=#AYSUfq;$lw5D@L98`gYG)B~Z|qqVXrISr z3+zR#<(cJx8T7$G2lLU6lIw%L3GLT5<(ITCl(-KDkx80Nsd`fSVjm}>>Vu6i=!<<_ z8Vx!S_Qifh0nRsSCGLy;9kaSIKZ8>O>4yWzB>jvy=!XM|`ABuO zfD?%IWwrD@#T(#6LOzl$@oX*awheI#p{tbn5^spX9yhCn zx)Dw#<|FJF!A3ZZf7;|Y>r*3tBMk9OOJ0jQ-UvgYEp za8~Wrjd7-rPpeY3>BczAMaT~4_sJ$Wo45xPP^VIU85PndILC>w^Kj0z3C<Hz`;tjTsOrq2WvS|jyFZdMdsv_EoU=iiTx+9nIOSt z815w|u9+yg%~0xaKB9RWZ-z2r%}pik71QKA|DoJQ!`RGCkw!npiu0EGAH@Ph^ij1wmW-5|+3siaBlz)^#i3C%T;eTJQ^b`OTnNNP#F~lf+R+khg<78g4JMtpY=t_<=q#1h z9&d$u7p1b4g|Iamd=z!XvK?-Xu}+|&iUY#d80TPCHTu@L*ui{sJXaer-bd#=Nfq!m zxP**rw=|u$!KEIzaAp&4gUgBua1ysIF89Gr?61MLxPq9EWND9Xiz|I-V|$at+al*M zO->ptDNHD0?ZPQcB<3U8QIbnx693fFX{a3|aSB&Cn2#>!@+Yn)OfpK}Zm=D$Ax>&| zoX!Ha!?jLcrxfvaxQ>vIRMv306xZ|5q;|FLw#N+~H|F`-+v7%J*B(}|HOAZHCNfEb zIh`x4xS24;7rx*-UX4vG;e7S?}{nJ`URELSHZ5B>Vj9dwsRV{E2a^< zDq5-r+pd^iOn}Cb?1n}kqq%*i1iPV$SQFH_Q*JjjJ6KKWcsI0oSk0EbJ6Z`{d!l%- zJ7$p3BB!;$O57bY9j3CRe%&3j9A+KUakvK_CARtF42ITKum@(7(f4Q7)xHPjbO_90 z=Zp718=0Q=6;>(Jm9Qt~x=8tG7YX*nJVMv(X|e5z`7SuCWw<965ZaegYvreM`5lir zfl9S;_QFC!K2lmLxxKK6e`;#=>V%2+!eWQ>5i4B=VhOS4SRGBlKrAKXBfD^j8Hi>4 zQ{Tk`sb6J`!gp)PeCJYAFLs?Wj38UEZ7H6xZrFp zr=I)ZNgto?a!w55eee_+K2l!6tp|9zBYX+ug2njSWAYFR1W7J2fV~TZ9$G;P3(`C z2{i}VF{NzF`{Nbjq)@`tiJw0yhE70emMPO@qu{P$Dpf8Tf#wjuPCA} zwBR7TPr|;mS^bU&;RA>B(GVta5DLV6Bukgw!T6AW+Tx?fC^#4&IpNh!)Ze*-@v#%$ zbvKC*#wRY6lLY4f5PV8(^H292r&_@w_{=k{*1XCcg3pU_hK`i@5PU(bFD$>9_QIj~ z(np}Pn-*GdD86zLIJufGxkK?aF(0X=xpOGK@uAK7`G?_KVoh!Y*W`l3@SO{;wX2|q z;d^42!#1v*#fM>CF#%n>JRCn1CD=8Xfy41*hXgZlIDYaHx`e`ha5#P@qc5#i|KJh$ z#S3t5)IL>$Bk-$FqEU^WBk&tBA7RIckHGIPlm-|FrX%r(3oUDq;7I)GLb*CaU&oR7 z%Z0MY<0J963$54DTaLm%4zt1*OK=qaCAJ^T^&efsItu@JhO>PRd+|}wysL~|#o-qO z=tM?8sFJNZ2+)~-GnR~?yE8x+hmJTx;s9NVk`m1~vyDgzx{RZz2MJ8#mYOkiz+euJas;@7XMjt0Z#l%jSMqgq+?4?{D zGwA1FKH7u3fzY2Y=`>@?=~FdWkA!_eOZy_Oe_#NyeqLpk-V>}(WHZF2R5ehIrf_i?M1V>|w4$PtXXlzN$haw@ST^euuotoBLEQ)^V4w@78-o7k6R@|# zm8G1Z$0uMAu`LQN)afewiP*<8TJ0+&I1&4jNeW}!NFDieCt^QRnybphn{guc_p#KY zNB_`CIDiZv_K1-ZoP-1Uw`RNC4l*aV@1VNwyQc5{Paocx95G{NG*fWv$tU8JWXBz8qROZ(WVIGPL} zR^8c>I~B*c2()==FrA8HU9ep$I1R@+IF|bxg41xkgSF*s2B+Z!Lf3{{)kk?6P9&ox zOq-S_^AMawYMrW+kBt8S@kx5=sMz6Me13C*?GWv15^B)P$!f@iGPh^Ly4U#(xrKI>s zHJxwqSt#?6icii)Ibo79^}PjWqk@F}KF)A-DfMiOAY%)#Nk{FoF|rsX%hf$O2bCoF zNcA{=$vL=?e{1=TqUCxHMiFW3d{jPG;&V_{#C42(E=D`d=E+`tF2;D=q;EeL)x?@w zmL|u!s3A(euiD!4avm;n0yXT<=b@H}4<}S~(42=l2i2~Q&qF<-{gg&JJmh>d5WA0^ zr}LNdF_uhU#^(Y*_h{(<>qPK;jPsJsoZ8Kl_-37q~xWqH` zeREXEU4Tn{oL1`h_ySz!C7P-6X+jUfwqd6IsQ>@|uLKpipOSp&l4d1U-~peMD!LYlEAU{Ep@Bbx1|c3I zV?Vf=Eif2?hl#cB8;0woFgF5^kkGzU!NxKIkqhP$azzFA-eL*~Ep>X{bP5%W#8k&{ zSYAx+m>Y>{E{WX+N<0$N9pX$^D$z)!@27pw##)IchZ&o$)k-vb+`_e~xDqYIu9lbR zO3#I8?O+<)=Sy%QW{}Y=m-7QI#7rVSQmM|_3o(m-Cyl#Cr+lOEC<)C$KH|z{FbcE1 z{1|%IMqv)2Cbrw25|2U~QQ~>1El*7LD$Fe=!2LNv73LA!EOIqS^-mS%lSwp=DjcfN zDlG6qx)+13bu=FHj82X@D2&EJ$FOWi>I8Z;7Ll=EHbUajSlkg~s-`gpOFYw zn$Fs4#6Dc7u+%>_c$|!FQ;pP6K@HlS1iz!2ogi0()lMQG9mi%>gS?N?q8jKTtZ^~a z-k_U0xCl>phFXf&cF4$u2IjrrMJj0@`Uf@ip3wPvE^>hK~NK3rcOCvhFt@^38w z&J3sx>+w=Y1Rei^dc5ozwE#F$*W(q>&<~&^bv<6~VA^z_SOZ=oqXmD&_7XJUbt0{- z)m#VAeZor$xH1e}3A!G5Dlb|kVcO8qjeT?RI&W^|8onj0&Ogfv! z;$0_^t!iM08He|rgq=W)mS7y-??{7Q*KzoOIO$^*v^V2%D0qQZ-K}>qKJ>VmS}3>} zA34lg;2iT}d`xWH9QSiDMtm_o@iFXlWIR4~5>!OG#V;6-&x#T{M<0*ReHu+`Ch9zK zJiZ{qM=DiyU4k$9w;iUr2e*9=hiP3*4lco0eQwCZNwOYyynkdKC!vmeKoVx5anuG@kx!w(Ktb8BgE8Gdx~ zZ2hgOKrX{iWHiOfT3w#F3_p7bZdss?mCNyqOQMv%zTk5F>IKy9ltpoq5CE`0sV?`##Bo*0sV=!Z4F~J zPQZFZEDLGigtjmN16*|NSi0^#5$ij~o*-BusfpOYGu(x!UfPM+&@<>pKe*OB5t|a&USQWN$ZG2-OvGkRj{88Fl}Xs#;VPXH zrY2zv;-rwrlyhw*n1n4I!=AK)%{DU$TanR>Y`>@ECSmJhjB&a%HkyQOd<^=*sh#3U z*tW>fN4;1IlaM0Ahn<%8h+Kv32(-3q?DRZ!6}B%%p_XR@xe7aYM#qX7lDP^ylHtRT z*2&dX*onYa!!U`i!p<&qOqqK3ufi_GT4Lkb*$P)-S3;`+xaP$cDOY1R&v1R7uS{Ky z-O1QeREPY0t4la7z8ZUw*B8+e&s>c?iTLPh6ixA~v6sX7i1YC1Y7BJJyKXP>)!3UT zY1a+ZD}}2u$cb|$s*&eiun)23vz8^3x(53aCN;uYHudr~*smkPBFS8X{hfqWEOU8C z1_u=53{}fLx&{Y&8EywqFaI?-$TQTC)OUqzaIj}+SgY6dS{y=#kA7LLq^`xG4)aYk zL$1YP#G2Jg?ncR6i^F|zi!O0pizA3_5jU@yzygh~#gSx^kJn}L_*xuALQ66{O$yf{ zCN=#!=qt0FT?E&`cmdrHvQRSD0c14A9d_WEAB0573(L5i z5nYF)i-cYDxemt^i85AS;W`{kf{)O8n$L4WIIbvANq<%9dK~WrIB#WrT#plq0wZZC zWUj}FBy6s!mvnRZ^*G5hY8cFx=z5%7Or(PL$@MseShJnISPIu;a541Ea-K)RsXjgz znmKZ&Zop||v>ZxxdF}=bAyhSQSI(BzOXda)b!o8kPvt2lobF=OQXfY*;0zZ`olmWG z1I{FNMZJQ0uW$p-auVfZSo?A#&h`>IfX$cGjW~ylW};5r`ZwZS!lbZAXU9wCMx5tk zG;xV*I*&@>{Gy1)iEhLNB=|_R?o5bp#4r~{4;Jw#QQ<~p9K-L>jYM)2vShTZ##Kw| zCJZlza}=N@cN0oI!!15^?PYF485zx}uC?ZFLb(&*_6ObT72SjiA4ON4=^VNVBV3eP z?kX?bgpm$1Up&TzNPn6Vf`z-Y*-hu`fznp6r(JdJ3#B1ojzXjvGIE_w@`Gs3>v1jN| z)`|437*B?e_Lb$5x)ql=T%ighxD}TYCoQ6sMo{KfT;>QWVRoL}t+>1>FL51CJ2$kxE_BE8Ky|MX;;mtcp7^ z#Yu3R6}#n~nCdW>pqPO>F^yQWTS-GKb0?-dSUskUhZfQ3rFCSE?nINrv@aG*d?%WT zHG_J3i5{}TooI0hsXkE&K?s|0srele13Nl6HQXMEBweLOzT$oX+Qa@uUl`@v~)c%6i8YU+%cWhY|nD)-|JA64hy3#D*B-Xz0EM@+ht z9>7~(f-@E-o_YXpJ4RhJG^BzD@Q#;h$~RGuW*)%1WRk+Eug&s6F5V+yGhjcQic8ni zqX+Old94CfTMys^pO9JvOQi4s3S^RoP+FyJUmnDVq>{92s%hvwh>u7ll|E2{2l25_ zL~Tu)6%XPQCs1Bn%j3WJ)Cq8*GpjSy2k{x1B+1%xX5>M9P9kY+HRV<-79PYGPKbrd zaaLGmP8Pyc@c|C-$$!OkmJ8R}4eB)p~+JOg+@hxHUb#zUtGJ6Q$ zbtExO9cvHadoo%?hwm+ghp^6vtJ2_7`NQ~ujJ|?ibV)soAH9Hj4Cw)U7(aPNqs)@b z!}ysDAJt#WB=<0W@e;aNyG){o@vE0;Wf8^?<2Pb0p~@;f3R8F(zmsq!lz6M<5&YqV zbgw~~q#nVaBy5+OnxD!N3Le2<|A*n|mw5z#li{O-8+Gd=_=iA0r?i|c_YwT-gIm=v z_Xz%Tmrqsbmc=uX16Ty;$>w_2JLvj{!N+ZWS&s}r*bJw2m-4rXNvdXdq@InYd( z)D-k~n1`@9&P_odhpQ^p^qYdd#F}-^({fYLkI243_dw9(nS%ag_(+YlvEnIMk0_~y z$}!gQT9|?Xp5w_e{U1+{V|{X(kxD&Qm70nTh_zIzSx>=KY)F{ADLOW$TM8T z)16OKv9XI{y$4gVi5K88UEO;;6`PVtN|FnCg{j!Ah}p?x8aDSaxWR(WE;S8XI0-H+ z(-AohTN3kOUDR{VkeP<9io_V6xXew%)-DDWI9tawY(uOWx86`X_oiW6$54N%O;?zP zRFPrh=A|Liv7Jvvdu3`mwkOuos4S%&IvqQ>;3N2tWTsPfU zKAMi5iL~M>xsEj*ySNCexnYSqvoIaIy6}b(JaUiSis9{Z=@LmbVs|pOK6II?5qmf| znzlry5qlEaX4J|~lxxIZF243NofkD?pp&T8aWHPg-bIPpa&BuVG-41L`v!G-Henya zq~X+!v<}Bq6ZUnHID?x`$3oDA{ahrSQD>U4KcVKMp^EOtToVo;=EKs@)-xMTIMB;$ zE}C!cM1FKNc% zUZ7cvqZvmKYvJ#*r$o&-(jjh;jhk^45g#>ZxO!e_MnGhnI@cKWd`t^U97Bg?H6x{3 zkS;QHy0Ir{fhoq~!l&$mNJp#{eh z_p;wsKhljWtvJpJ)i$WJuNB9;WN4=8F0h~#Cy?R8BB|ghx=brhED}b~^tIw75?Ur) z(2rViGLcq(wswTXtvH1+={4i@%wM4ugNyMi$8eL&44g_rGinPUH3O#+7q#GQj(B?d zGMIrOPL7+z%Oo=cLy7ghr-i(<0jCq$!dCNQnnW{j1{prg`B>eXG6QEi5naMmN9+uo zMaK3fK-_&UF&m`cnG0X5u`D^U>~m^KuBB?=Vj* z)k!oH7x)xt4CNaoo{3>jf@9D!Da=I1N$3ICDjJ8gkaZF~(ZEr57KZyYxX+s!Gnj=^ zGJN=DwVX0%W}%EIY5nDPlUi;T%1PStjOl1EYLCF<4j_$V&)Y3P)5fdr3Y6q)43T)C`emw6ObE)usvmh;vNj3(y8%<5s( z=uwPu0^FBChu@>9Ce})5;O7<|MNLtDupX$Njf-4(89hj;*{CJ7AELH1_Y2HMooCbv zqfccv>Wd5~zVms#1{yrWvzatZqS+WrMqgV+Cqq0N;|P;YcU;O!4!9L&<6^RWnEA8y zdW$(2UnFX2il^q_5)xkV*po+da49KGd8D?}Ik=3_mAtx!a&vGw8Ev^khDtOCSNL#U zSDi2M99&ss=q;pDpM#uZR59t+ur^HSV04Wp)rN^=T#a+HQyV4`^O5Q*U9HTt;VMUP zv69=@b8Wbqgl5z_Lfdc+q0ML$7frbs*M@7!Xp*cu_LnwX=OSp$$y{9D5n(0URBA46 z@C^60sGDOhZX~1MS~65Jb8(YPppuj2++5u3piX3?xwys0)@3MKK67y^8C6=kr#88} zq%aqgy_h;vxq>qfw~^6&vH&@)orl|rlN#VAqj|W)MbK48&TKOCa3`7K9AU9@CeeI6Oq?iiokH8~1@rNU z6Us-YkCDQBM8x_gJtL+{Z2_i`(XyzfJ&{^~sf6~+d4Ed#Tw05IElaQf)5!DTd|P*{ zXBJ>Ok<0T^`loUW&`8E&7NuElEE}7EI>;Kqn%M6Ln|3R z`l%Hal6nj?ya+dk>tyCJ%p{}bx7%)#c?`3Bxc1(uyjKQ~y72H~i5|mjB0j>CaOyLD z40C)0UF@1Kg~!lFMvFm9TNYxj7tjq9Y`P0E&of-i@$UhSWHGgY&0jBi?DEOi3I zXf7|pG9qmR)!cO>nMGJm?E0wPakmI7oCI6aXo(hKrHjuUbMYdqa`GGmb@y^%5#o*% zR`SbbF&=j@sxOw*Vzm2kZWQ8H{a`UxdxkDFuJU9SBTq&Pvz&A3++wWp0zAvf4j3)Q z6J#{o*?OKmix=ZbFQKYsr4$z9DbH}mLBmy+;OQd67q>`i37+X-^k{Cd1kaM;!(Bw` z$jvOlb3{o2)+R^3m*9CHi)J}}(9sgSKt{8x+jiq6c#)6~o8LGNDTO6i>tgsx%u>8W zCP}ugUN?ZHmf~eni5bhWT@MomOYw@2sKyZ$%Tl~bh7Z#&qT_p|M!cx5HpoYpayyal6j(*GVHla43U3ZaS8QyV$rMzAyvkdPN z{vXRpwJ7Jg%kUogL@Cfb7$ea#yiZ1R#ij*nbKds=%rJ|?v3PGjHCEXOAfkIUB5a9xg1eRvaRdeL%x=J1&8XjaW~eC{wE z`2(e}9A6M?*;rFx1->M-t)HjkwTZ02S7fxJ?BJm1wO8P4FQog0Xb!BvH!hW|?t))| zZwYNC8#(oeR^U5gEz@#lVFkYT(bciiB!v}N=j5{^XrahT{6L&2VtQAz>KRV0#E->j z^rZ4g%}V^_87eh?ZDu8Yc8r?;+H+Ro7c#bGsybbXUkNoQC8tTe62EmMpi`K_O8icS z56^?D&s0|74fOPjM3A_;2^^l8+jbP z$Y?IP(VSPmq#j3a5_&Yx?bv{fEpRH8c5LXw z>F#K6luSD|B9pwPjOI(O9UGHygE$W!(0tKzdQm$zDGH9}WG!yTrX)1wGLAj%*o=se z&Iy{e*j8h6LanMQYaOh{7G8oUM5!5q)!5QW(0@m7&1!5#oa99hg5_3YYad0Y@~slB z#x_NUI}4~@R%2V22#3L}6jmeU5^1o>wePRe>g z>0QiY$BuaR@M9i3k3HT4Acb+C$|!4uezkPjVx-1fFyGEZQC zLXFSEC$vtUzyU=Gxr^aKv{4EG-DzQHGOkY{wTXqCbfIM}5^9|5PMPvQ__&Agox zKZ!#LlaWz(g3*cfBn~5GOU>@G&pe64N&L?^WVfb0i6fk#>OT&KPvS@td~|JTS-wf) zCvlXIYESO4qV=e7;YkGKwOUU(jd#GIgvfOW&SX+gAx(mhw(J#pG~g*1LM@Edt-4I` z6hN$>k*#9cJcZCl(7n6!C3*@+lhHTOHyb~NV_Z0=<+_w!cnZh51UNb79dkIYC_t~) zI7vN?;~k?O3##kjX`J90exByyX`DzVDZLSPTYm0ooJ2}9nvduLjGo5H#F|kSro>O< z6c?kRF0pwEPh&7C&8eQ1dIqNw@lnU`EUJstGdRsNjT`_u+js^;Jfk|A>lDvmsAK5O zw3o&`gVVi?ZldQn@C?rI438+%?u(znnPif@j-aRS8Jy)M8r$d6{Fi5Owv(W`;8^f1 z&T$e|<@TDb;8~pO7&?^npk(G*oL5YRxohT?dpO@SJebL%jGn~>WNdY|usy`jVi>WO zQaM*53eO_rBXGf3@A57kWmm zD!Ox?$0(P?SUvENc^*{`kFaZ<&to)k@+q3n=y{CsNl@kLF30Cl?HTPhT=IM#HJ;&i zU$w7az(r&<=jtMo)C;I}m?k01;|0|D7_HoJutYL1pq@;kgX`Sxj2F;AF3HSDu8Kr2 zU@Qr3jia*?zkqQr5p`#=+zT(@;$nm{U5kDZ9Tt-IAwMI9{zlh5Tla8bvV}wL6;tEpwedFxj+ZS=A!_`%s&=y`qj+l>X>J^;Z z%UVou5^StACf8yjv3?5ost0Q^$;+#s%sdmhH?h_KZo|6Wv>v~V zdt6K%@^rJv%ea?}zB_XV%ufuc}td4*(N!Gk3D z@TikLtC4#J4-x7Y4y%#q6+G<1*}xX+4ux0nh+}juj%V2luORX=+&Zee@L$Cg&*x_&r1aa+}EXeCVA$#C^MzJ?ht3U7g+Iq({065HgdQeVR?B3lFY zs;$-TOxbIAlsq4u_qEY9i(bQQ$FRUFd6h!^8s>NzE-C41<7;Rmlf1mHVK}ez#M~lL z!ndbh$2=d0n?yL*30}v1&uCq92gU1HKqhI&>XLmOk2wh%&pP{yUdKWoho>#`jS|0( zMJ^5p3pyZQ$Ks*{hqgxE9f~DRf^CmEc>_zG1hu+e5gNRKWlmzCo_Wo@f#t-uY&2(c z*d){gmU{y$$lDU6Y4QeEx^(oiIu5Jx8(8HT-u$CG2HrqSCTW{=hpA6h-o)eN^eaot zc@tymO|&~q%cN0)H?i8|W_6{!i9E5swYq}0n_>-7A0o}Y_3>$seiKiS9zZ%dtkd!T z62FNj8OBG)|HZnb@Ft$}jJBR8-ja%^J)_467D(zXJVQpanU6~7B7FCuVa!V6A>dTJG&?(tiAu^4H%niPe%u-40H2WsPutayox zpE}oDMV)#ZFBcx$qjctKeOH?7~%Hu}I#ag6VQFusrT@e7vOCk-1rr|hp)*buiyQsr|!*?zvoi=k~62FJ<$s~0(yj%zG!h2ZfBQ||@uN$FjeG`YuEG2GshGwHyBj(4K7Mv-@aSqCFWtp2K9ag6n+k#j}AK)(+ zizX(Wfgj*+;-sB&Pl4V$mHPnycp3GkL?7T^V*OBix5NkdkI*$jZf#}`)q*d404*;D z=>%skhfXP=lV@}dc!s13=uF0DhWp?P=t86kXL+n6Q$W|EIH!wryA;rkjMnGLR{Ivv z-AkxmTqtn?JzNr{BiVrp=;g4F=3)^bd53k2%C^_xvY}- zBW&vA^U-!v_z0U3^5J*!G6~Kn~gA}x75ej!ZW%Jjb}tY#+GD~*U(^;%*WV@ zgsq}6rM!n3Tl*M1-A)T6`WV}|80EJ0#2;f@683}b`3Y(=y?&_hF;e8U821`3@(H$c zsGNR-Pp~~v@-aiW<@6KmK+K1^ud!R~GoN5bV%NIns88+_>_jF})Z8p#cTGp1U}uua z2aHzB@)PVrLX#e<_e&H$!LCk#Tj<#Wb2|0~jwZI{ zqgVA#k@yQ7<5Oy-K~?wy#}X&aiAQpIyEl$=MAq*7OMQvsT@1V06MTsi9Oeca`jWrI ziNvmj%+;liFL4r?q#o-UlC5jempGZE)*L5D5`T$P930834+~#nuup`8wK_4r!l|C& zDzKVMU*WVOvu2V`+P}h(B9o^|mdsZeN=6HcThZxa`UsxhKRP+_jAWXV0&sxlK z!)5#x&g@8NE)9;tS2)W>%vO!!wdFY5321+%U6uM8=a8{g(yW`=zQ(ye2{rhr;J(Ir zPJ+AK8+g|_&L`Hq=z>@DH7@WG=x^sI$6sTZXL!kiF3^3AjAv*d>t42RkoAljz$+#7 z4Th7k8EInM2);onaZ;mWdB`mD4aywh7U#Y}xl6}-V@UFYecc|}(VDG8=4h>}Zu!B}4`>4OeSmLC;==EQ2Y>U6cI3HQp zz&H*04i|fd7gy?}=zEO!j23Di>ad2yHKCUKab*&%!!<;<_p?3nyW@4ZmW*bos#+J@ z*Wo(iBt2ckl^<}ukD>=Un>0#)TYJt_Q* z780&5W^rVfU(o8J&_{oyq<+DS4hj85h2R&=BvZ7P%5*nn<`>K&X{(0|t-s*WVj?9} ze7|6}PlP)I*G!W57tA4}l~c>QDExvpC&1+r-EShlVy;Vq`|mks|B87&i6+hyczwpN zm`}!*@o>rfiUl3vi`B{TD<1Og_&2O7rof?>`tCQxp5bXd9k74Lz?oK! z{DG&7QFLcv>JL0aLaSsiE|&d)XMF^2FW}&o`2)|9aTUOgN9;uOg7e2N@O+1)PSK-3 z@IsMkpUP#C_z%2DMzh1cL(I+}SX-3fH6S_uMh0FY<35R3bfo^o%U*=1ZgkZC6R$Xi zz6re=CG#g<^)hO^t>O=B;59P(5d&E)f8uo_eJ$ivbcJfoLda;*FdZenHo(~EB z#>d3kXmwdV^EW;rObWGBmlOZSrzD)p&?#p0H$HQWE(K6c#((4UB2#atOMl}FAB#?2 zF3ZV3_|h|tJRLDhQvcv9GFsGBzY8Sz2VXnPafCzDKlsMS;I&eWk^2YVlF__oSvS!? z_>NG^mp4_$|KNKf%{eV-Z885~os*_jz+W}N4}?h{=Gk|32&ewVkL2vfaSH%Pzu;f| zbP6880sTDwam zmarcg+u*pIyH>*f4)U0p6eL`aP+wx#Ok|ye14w9#=8;z}V0Q}FC+0%|j>vjf_<&B~ z1|J)BNOhfN$<8Jk!Q@AlX&DNp3?rU(Ta1%mT zOL}xM(<$7POp>!>xq@HQDcsD(u-l_Mg_{?{bqY7RQ@Di>=h9TvDcq7!KZKL2I%(?^ zZdH`8(Vr&i6mCtzzEV}oQd!$6+@>g!)dIgSR2{UYW^5dxEqnJ5jFCbQXA>2$>h%A?&Mvu@?JuTI){6Z zvB}c1ZR;HFNoey?M;vz!_v(l+hb?Mt=WrmIq;2X?59&>nh0fvLB<=e+fb-I(>+(JHCw5+3Xrx;kqcI3#ol4uf0M5+3H0(b)()SC{Z`GMW{hCm+tAObU;1iEv=!ykTvZ@W>*; z{qR!g5*|e&Q7Lux`jZ&zx`Y9#>8lFO|ZIP=)vaV}5*adU+<7n3{Je62qSz=^BxA3%LWWzqyEgVAZ z%5fqs-a*~Mp-z7LBl%lX;pr~iE;UjUcMH!Tqm@y4Npe^r(=9xcl;()5A&pYgEj-Ib zVpGx+2DxtG*<|>zadD>0bDUJ76D8^vp4$;`Hb=v@ZsB=k^xN{$B@%ZF&v&qa zT6Jx=@B%`8FXuE=!`;GR#7R53hzD)zWnH&0Ln^6Bb&N^(Fzb`3sE`5O!{LOk2QB0G zr@DuwWHiy*YQAJp_pr=Ms4+`hvU^zWB=XVFS{d9utZu`ExqERMy4=?ml>7vpzs@=m;j-m3bt*(%^?qQXe(Hp>< z`IBAYXfj&GmtQVxyN6?ll27JjPYT_`Y9E2y#5i`Y>mJs4h9;O^Ro^4Lh>U)9scu&p z&?BrR)+G0$dEX9sw=D@gER92TG+=_vFFuXI9{_JWUfJ;EFb&0AG9 zoo_wE35520t-Wmhn9F5A&u}7n+gdo8r=SOR+GKLi@CGuP-SXNI z67>vkEDE$wr`Ble8Q$a>y%~VUXwUFwGFnu+X0O}4*7giw1Qh$!IG$e;`M%@HQe_f&A&a0lmW8y||8(bd~lB?;xYifk!6lN6MgH;hkPYH{vMFnjy$YI=t)_6g@Y%nD$s^aP zN!a$JindROrDN}q6*6R{ft*Yycw;-vizwLhQGH+h>|V^$njRsU!p~zTAeW7poqKi>EO4jua*ZOeXurQTd&BB))qZ*r~IiO$o zGMS{_>PG7+gjB!q6(5a$Vd|zq{lZtt@ZqPjxAM9d{t9CFnwR2lzR+tjxL^1>8Li75 z_>W}zg>MiiNwZ?uTWk7-Z<6A}gzCzf6qQWB@GTdOopY&7?iapIoYW_ahuf9Ehu4qW80`?H9gJUSF>lPikK)^b0>AWji06FegX- z!U735jV-U$9eDh`#_&Uu`WQ2F)`KXM7_wgVk4Q~kq_NofwYKU4LXp>=MZ+3GV2g|&&9m9f zv)RqP+0E~FtLkg^rSs0iIi7R>T~%Mzt$b6(1YMnML#OM{NdmJaW*a(Pe~Ad}vnX)6 z)Ad&n`>K!XoIhQEgAU^T^@)tEaJpWumQK(ISY1S|6KWW z{S&}Xw}uezrE~3vMIeL z0yylEBA3!@V}|v-GMi87b&xjLIuRO{#%x!TQ5W1xF1_0B;amOV% z3D;7D+OgH;l-|g%VNy19nEOVtg)iN)0nKN`Yr2qWUllPie z<{3IC$#9%QS?&y-3vFB{285Yho}u%SEEWa<;ldf}6A`M29{7el6F$US|%B3?kERxN5 z5|_`^@JOC4k8qVUH3HI@f@dg4{q8e062SMG#YDW%^_;0uAXaa}ruLqx(J=!z3`}dP zXDS0=>_N`Z!V9muG}1FHFi7ewT?TE{u@DsLvvfJ6FCRHH7pcry8j~O5+kx@8Hu={WKS(*e8I=tRwWIbnTGKe2^(Vh(H&ZDmPEKP|; zafyH2RnJlu+E_Pr5l`1@DpY8NZ&;^GovmqLo*fq09KVmVH9h88KE!3t)(j}C+;tY? zD0{XP)7yog+U3sHOpwqX2A|8Hty!^vEi5Z%Yj(`Qz%*tS&(@s(DWZ`%bhfSr@y)>m z$(x+`NV8|_8gMHbe>CJGm9sS$z_*7J?%A3b3-S`O+g#7tnx7Qp#eV+I$2s?GEl5(@ zq5BzEJzKem_(N6`@AB$e5G#8XYs)!W2xYu_o-kb}pX88{K1YjUiu$!KbB-268E4R* zp?Wz-OJWX_vUt~>+&Nkb<{M_dN{?~0x5vQq=jb|c&vl+w;Ko!qN6TVqEFg%T&e8SI zfvW|sI;C@TL(Jk|fnwa8qva9l2r`_?Ia&eYhdQIA`y8!=v=+^f>p4d^Mhg94?>Sl( zlX7!+)pL}G^c7-On+5c_st2(OVAk8o(f?dE0Q}FG3(t9_&sAfRm0-O{eKY5(2_$U0 zK3IT_lkB-_2DQprT%_E&S{=y_A|vL{)taOff=IA!7S2@*i1D}GyJVlM)+B|wOW)y2 z=V~oT7|-}%*x)Lkt94-fF}pbA`A}4qbG1InYBCy3&(75b5G%aRbT~cdsx8tsDP8Zm zYEN?D6v5_FJy(U80uK;wM(1f`OhL%MW>iV3^V9+22j@JOK2M!7Jw^_jT;@D&s-@?y zz(Mysb=6WJxz3%Z&Cp??TI2HPX-oXM-W(|k=V>c+Xf5GpEe1pJJZ%FDn{E)Vl+M$3 zpg6QDXyVG}X-9$(DhpG&%6Zxu5nDqky!$-u01c z-RgNN#{5h$QB(Z1GeY6+EN*u*;u8;O5MKC9jhh+O`e=GuT zY|ihwK01&jF_krn@IE>ilZ3d3g+4lzBr&c1oxDA*!yvvBI$f!c-WsU^LtVL#-j<}c zC-rW3l|FiVf*@lzMRgy&1H{j2&xbyGXOhBvl2~K==v^RTX4-q!)jldkfTqJc*H`Zb z@FN`!L8`Cb0~tDLgAe_X?yL946lV09>8tlahD8|H2x92>)%z2~6p;_PTwi?v#46_f zj`Mx>LFh0X>eqY4PNA=ENpfMFPGyUI^&t?eN;{LT)K?#l2{<6y&86H|9|8HFS?zSGb%@?vU%p1%5clEx%#SUmLACqV3Tvl#Q$zA8gno#|5MOh4TU zZJjfcBY!{L7PI45WA6>5`|0+Gc)N9kll^oDh!xn%`k(EmBangjoS|H4gG@JzX%?v4o-E^w88x+fN3 zYqtsE`sv>I``o#%r=RYNzgw&>%$R%o>3$H;QU5|I`Ah*-?WYQOV8-eW-XYfmF((JT zhqxrA&ewyr6rHf+d_5FXu!L;oo$bu|dKkpmVed|6&(|YK5f;|`PM14hk0yu(g}^uR zd_5Mkm?diAe4VHz;C@%+t#dsN5?pzL{fZ?@~RrxHBCoGV?R&n1Yd;LsUfpwGuF>rs1EF3=YsjY;(KBRul1FG7b& zNssxhq8 z^(}DEBQw(Acz>Z@Je9Q_E?uZ^CrL~k{G=;gsP80&nf&NB4r6w8DqpDYCMiuybktQY z)b~K*Q1hWVZN2QiP~Qjk!)CSXxllid#raXsni|4+T&N$OD(*=HG1Uvz3liGd#$x6! z(vMChxtmFsx=24hg*=RkG<}hN0%9MVv)W}Y(of^>CV;{qCwq~8mi)fRTS2^{6+c&m}j1k;A#g%T35J8FU6d@2D#!z`XyAToW*W0U8G+DgvN(J5!U$fMfx?c zXSo?Jz@>}yn_5D90V*7uyD!pjYjFMMMCjLZk$wkkgLn>6qI)mW?;)*ub%R{>B2}Tn znD<&Ecd`Be!XHa=J@+#+`b=G{KZ1n1dSUm)`csn6v=w){%*FaMNLVNfKEzY@V*Le( zKY!FBQZLI!?qdBFB#hlfxF%ezzt!l54p+EXFGGiNaEET>LVdCR4rDE0iFT!n^$*BU zndz7pmM_*n0jv>TNXQN8V*RU@WGWj+_r>}*fbS9?0NS<>mZ+YK^`Dp!(<)Z~-i!5L z06$@mG1aOU%g(7llx^|qh-BzoTCV^Mb!_ig!&xnr)+-}q)=0Kf(t4{MA#YlzCCN?i&n+OW*MkIJ z)Y~9R>kR;L*Dn<8LA-KWZv+d~MT2jWm$cplui*P&-!s=v+zid92_mF};z0Q@)D@!)=@ zzs?5ny<$tnqZ}5!r$&FB18%kJFxh;rzs^l^@~#mo<9vUe7gKPxV$}3kpGcda#ufXk zFSOO(d^}72)i3@`EKr2r{dGQc=+#2BtE=?a1%Sruk&Ujqzb=IGbqhD>puFwruZzG# zE7+vCJNDPbAfch_xvEtAD-GaT*Vu}nR{fKbF!K4-Zf@Qd$u~7X0}|Xn?!XRVAp_C_ zG!Wc)Y3}|ulrjS}2*?i{ACWaXK$k>-S&E7~H$Z~{k`|fCDhts74T&XLd@#?b0jdM? z)i+CnL?p{)kYD07vs4p0UpFmMr}Lfk-I3Sd1kYK=<`)Mb&XU+vNZ zbvcw(g9n(mxy(R~i8OjvhX{tJ{_k=FH8z%{87@CiS3=omH~Tji3IjDR z7R7dVhbs=$RnSRIkz2u z3>n&K?}+sd)D!?~=c;+GI#Ah|+eaUEgESR7VJJR<#?WV6YLKSIT++M@fUNB^XS$w2 znh)jM8kC-P5_;P84$^|8D2tziqF|765kaqG+k?AA*MeAuEHa==U8051_OXFc@Rq(r zi-4@(*ce^r5-pBp*oLtI*~}$cQbW8kU+xkujR;HgG3I6d5?u#kHD0pV6)w>-sPNVP zlU(rGBS`H96*=XKRl}oguhHNmy^X^NuvWEB&Dm|Cz zMv(BCMUAfa60M3U7^C-dgQ;GkJV@XzI@S6$1PfC=kZ&$`pwwVB)KavCkST-J2*e*e z!%I568=e`gCZMp0Y-tWc=8yu|mS^~CGw(h|yB*;;s@!ZWFKpShwbA`4z%CxD;fR5de1 zn;^q{ni?b**&*tx<>7$haznHkzYd}Nm8dn{nB7m=p`Cr}6iBP*i>|=zQ+Urtv+7q)N^x*-6be;AlSxjBe zv9C`1ViI(!CdI4M{s_?B1$0VvIsjk|ym5!i*XbZss6Ve5n%!)nPKUsZ=jMxBtkYr0 zFj3ZUP;#X@y%ogjg;;^9RHwJa3`9wBl{&p0(lgr|><~bHuU*9J^p2RV)z0NTb$Tas zXfW=i_qpCWy(>X@&6*CX)~N(ywVl46F44P_--&UJgef&t?*Xy8VrAsgL-pQBT43(X zP`xjvXJN6x+}WXeKS=Da`VAH=I5$)u01NeHMwy=M4s%Evst^z^yLSV0Ym4@oW;IVo4q5v%q)ki>#Z#*Nv-c^R`qe)J4jK3$UqPmCb zW3`-I%{cuH)yF~NqT)064%H`s!qD8ngG<$+Dg#*QUYqBJ>DHtao1%}q)G*x!5*qJ! zFJ3|!rrVQLcG^4UGQ)HSh!t#aF|Zg9(-8pU521hUWuPFr%nj4gh#SYalm>ljewdCW zMejUG`glggVY(B*x)oc#(lFfx63vKxSoPC zR;*!Gbr09mkwgvcdWP#6NbAiIN~(9bo&|^n2Isu$aCL+Ep=yRk4|8qMCqY76QI>Jf zOO4QTK=vJzQKU!c`BQnGWq4&q=wwX58P#P+=uN;9<<;9XV3phQvgW_Wl3)&y_~%J4r!U(UeE(yO6Q>?_#;BjMVo)l0nBF$^~qs zz7J;XWJWZ(o{{N?^ zLT|6Jcm~B$`en?(84Cxd(kT5ZCL!9zqZ~iVqx5SK-?!$p{bcl*tBlfbz^&$uJfhV- zO20jo4EGVnik&8UM(KCpHfii~XYLcdqxAbEsmXWm^Jnr$U3HYI;DLJu^EMc*KLCXG z<1@%=Jz9T^Nn!x+(fSjBaeze&J@{z-8QRzOs6}3(Y`aKgN9!-(#t1ETxzYM7lrPxS za0m@Y>u(8Sl0TeyM(gFIB-@A*pNQgU{T$BS7i zqxG+(EFWT#y}^8}x<~8ZF*Druo7!moCqalmM?HE+>%Xx$voA5}QgyUU1ZRw5rDXoO zj9vlYN6~5y(;2-IG7Qy53w(*RHKSL7g_*w?(}|2;9kZa(ciD_yQ_JF6+vai^y|$KR zQJ2eS^g3wITe~xvSBfcu3mKgTZoHj3!xb}nJye_n&1+mKqc;GAQAfZR&PEx%F(M46 zhfNHh(VJ?SnmFTjXY}S8u!V3HJsG_v$z#mpV3g76AinD@3_~@eRFZ-i^Nc-rsm_Qg zS}ibo>QbEv9U9;_XY;$lU;k2_1s)f6@9dkoRA(niy}&1~H`z;d4tN-nD81R-F4ega z@s9v7=`PiIN#1DK;9tisT&g}vUY-->@Kd~0eL;+K!-u=lrRtabevHHJF;~7+=YvFE zwy$xOOLajl2~lhAaov~d!UQ2!Cz|V?OLb91Fe&RY!Pup`I7wqR9Yt5YRA~?!FlL(W zE>nL%QPCK*3uL7vbnuiFH;6Q+*W*iGj0v; za$TAvPBuAP;Zm3DvZPo92?)Q_m+NwnFrK)}B2vy=t}#G?cMbSLWG~khNiG8aF$Z#& zYb;2t%;P8TrP>doQ_f$mE0dJ=$V0^yF4s7az>4RIQ**hlf)3x~_KK%t>2i$+vJO63 z&b#vEnh?uCIBb>>mCH3TCTQhM(S5llL0bI~rI{e;a!m&CwXygIETqppgk??d<(iTt z^jl2za%Gc*-fPUxy)?&-(bSmmWZ51rNR81n02?iKu7D}&F`5qIM74W<&d`+vy#Z^ieoeuxsdjajt-WR?lGDNZTupdknwAb=Enpl z%Yz5I-Z5GL9U9ZgJ5t+Rb&PT`38v1h+E?gWXj`Ve*_a)9Q&(tVk_J_-OJAWy&|%!z zMKW`R7RLn7o8L$F3N3*S-(g^J3dvoerL{bb9Q5;7=sE!7Je9T26t2*+T9O71k;N-? zeN4iV{0wTq(iOS^Bn+}?$fK{&@+1W|#8}r=hNBRz#%s`R;z0$0)R%G1{+;|tk%Rb35>{! zG*&IpetF}uT~71Gv1$bgz0pQ*l*Vdp%+iiYohy&kx+II~B=2#Rv04ve%i5@^u6wLD z#PqE!46bLa+9JK)BDVF8ReSP#Q**nkj#UBLH_HOlK5nKetN`vxZA@?F; z>HxPY;}2k`k@S`71PN8{gtwV1wJFJZ>{GZaBRVvbknEM}swFgYs@#>@3}Btm>Yo6+ zQd^)sJIuZUf0!$^wUz}ZdsnEtm4Hsvd|BO)ei<7iU3QaeF> zZ<`Zy_m$cO?He6VUjCHmdal$>;Bi%M41sleuhh-4I9uisiji z#))>`wL}OzPJ5E9>~IXv^f>K}Nj7`Iab}$M0fbMoY9Rn+=^m&3fbn=mI9oa{H%n^Y`MZX9fC3z;xg2XPOdmkhm(Bf82T8q?-90;(m1^pJapS! zMp}8C-UeVy@=wK8#_8>mW_g8aoJ{z*QV_d&lWr31VtmMFe_L5x`(2d>h4K>{1%jXrag-UnvQ-L=AHuhRRW ztj;IP3m8#X=>wz3El2(k-?0^KpZ|N*{{pZBu6J`Nhk@dHSAdau$aKq41xuQL;X2VC_k zmBFnwt7bYkUbjMpF0q(Ssqwn4RuBiyTU~m*Zm%V=lX_;n?ubBet;vqp5rD8av6}Gg6@j8Ag!F_mv6vyk%8iF+XPFEVQyFkJ~<%z2hLU6q9 z2DFcvQ7*AbU1hxP0Sb*+YfjJOb#F{#wuTlOuV=jO1M&>AcV$r@j@SJOV)rRj9OG31 z30+&LcW#0nh$*;8a^-NT33@Q5@E*nK33@2fxSV4=H$e|Wd#0P+5BDn{i6uKhkHnIg z&=$2fH$jgk2rCG8qWlCs2IBXbCKxn9Cu#{8#ps+T=I57Pu6}acQISj7;b+E^to3f9J_%;5ulFW)sfl_n0$d&0xYHB$e61YZ67F-Ei8>jRV5&p^Whd%W z0M_y@++1@L^=Zh^4bQ*R@~9y1^AD>V=5F;QLu0ixc%(5Ni#V<)w-G9F(sW znkv{bQJ=3B;cfLR6ZHiU`v~q}NYf_ji_lhw_1y1zChAKu1N=G;AA2Y2%P~P~N29Aw zR1ahr^PB8CicgBZlH|e4ft4sVNnZu=yf>%yXQ=IcHl-%%YcZuov_OWInWV3SgrROO zGPccSC+QnWb{}iZZw8OL+$4Q7!7VcXGx08ypQLZq3b8YWokt6k^dexG9E6c^#Yy^h zlG|oN5Mv*ArAhh@xUq1_LRX%o??wudN@bG12W8ypAf8C~Bz+$;tdcS2Ue6@`0L)J? zo*1@s(Iov4#8}*JforRi)Ef(#L&e-={V4uS^hgZeC+o-1q0o+IuZ2rb)=y%Vt_^5e zC+nw>o}X+*9D;3R9(UQv`Wbjw{kWDs=yH?wa}fJBnr>8Oll6;JDemV+S(vPsKmuPd zt#HN3`XxY|yTt4@ZnH_0ChJ$RsFUSs+|efM*U)~na^S5@)^8x=x1UBI&^=kdjTz8L za(A7q-z6!Iu?C-Ty_5BO5bJF_qy^Pgb+W2}Rw0HHM{74lf2if-Ui^?tP0=4g{GeTL z&u353pP;SFMzJnW(Vt@h7V4qhWvA#bF}V+El$)ZzMtZf`)#az?Z?z2bFl8@H(aQkV zw06!C#VPuGOy7tq!j-1zAJCEgyk`K1%zvglMgIg3T~Fx8`&?y;{sm$c6BY_n^zY<% zR3_Y`dZy?O`e<8zUB4Q2K`|1?ghpdDJi=E5r6;PqG3Mkc5S-ld#*VIg0 zvU(My6~JS^!E__5R|6%doQ+)={<~~euK~1D=gf1ttX>PnpS|aB;<-Eg|L=17tX>Bg z+jI9xqEBRXT0{s+VD1*htX>adUBPt4H7%<*L>h56D^6B#jC6;YoJ`bvB^Yfa896VP&e$0kX2Zz4ug|3+acQ zEmrxdIuF|O=O{kUSlCTfACNG2QJ}gLj?vlo8PCaPE{Jns$ajM0nv;4 z*HUcqfxT1HG$2W_hIuqi10k)dc>S3MXqpBA_-Y^(q#DyS3^IP}X}e8K)9{$Uf(lipX#`|o zWP2kL`e_;o5RQPR{q+Hed!}hrQjYnNI5lLxEdbSZSu~ zQUL23XJXa)KB;9&o+WH3ft}VxrqXrYwurQ=P7C zObKhft;-BeP4XVY3+7IjnxSb4Vpif0x%3Q82l2CJ{w$Z7p&5~EC9-*Th6EYLDK5ik z)^am6vsMKAIPVP3&@7P9Gk8n8!VJxhNxC|`468Upb0Wf_vI~(e z15>dqM;t9(n;;ft>8MLd3lqe2`>Z_DqKI%iHeq>2S_~3Cw7wPNUTH~^3G+A;K}$<( znOGax!=>v$d}W%Mqy=diw6$~bj;9-3NxC7H;jgX_xw5nzgg;ZQU|7JE zILei_BCPy}o=j26QISyGR5V?+>3+)vAUrByLYD+_*A$|niTV(|{_t5lyL zgf+r2A~jPD31ZB`Q+TEtLHM&NitLD5SrCEDOf>;oeQcy;XR0}7^wE8}cFxr5i1=OW zh|AB^nwX`Pc~+RI7D(e3&y{iPo2k}X5lnJ|k*2>pUhGxv{hl%440XuO-TXvcnI-RXQ?Y9W?RN_B{xf( zK|+zM322j_r7f`t;&K#bX)BZ;PM$%tv<*5;(DmM$wKPlHW0H2WKQ7PG4rutO>dwyAevsr;&AT7SQfKQx zOvPA!kfkd>TL(ex<5Q=(!fYLa;?J5%$aX(@kQC0=VZgYAA?ZOBHd}86@+~`t740Lg zJX>!Av5{L(=*P-zy*(yi?r*{yuY0!MQ9~LmZhy~gy%Qv~EriF|;Cg54T`?KAria-U ztFu)Cv65G_7P&ckcdZ=D9uQ+%mwyW?JxA|N$~Z#p*std3eITI;!F)eENACx+ zw$EnJ%+Uv+tS(+!7J^gG(FXzT%dMU3Tw#uGf%H=gwW2G|(T5_vihr&&M<0d`z0kx` z@5*!Z5fJ{2qo!qy180st3K*)x8-RErchAwsfb3g!Lr1xuIr=!HeG8Lh^vrYg3FuIE zp@lxL&QUq0Xf%bOyIQwG^JgzKvAFR?Q@NzB)@?B-OU<)LK+;$1_Lvh(8baq>tvjGY zZ9>?n?A1C_gNW#1Qo*ZrG%3eKN_V*Y)j9@Ze6QrUQqiMkwvL=&(*pw7Ssy+ zdau^~kYT(}Z}DdA)vHyhm1JrQ?!}nSU!w;={m?ZtJd6^r(Sx$C{=*XS{5{w(6glP7sEJt(}c(FwrN zlgLe3qOZ~85%GtbyItuTJpmHfQtu!9EnlN2fs6s>5LK17fY?BoF@! zbM*p%jgw}?F2%X}Y$S(ppDWGP=OB$g$>Fm+SDy#sFFAypq~Ix6nX4}(xS9POWpY@Q z$L_iMBDghXwJA(`=ITq(f#n_E@UM5Sz6_M~6t}DDT=jtX1%b8O&C^$60y^$#&YG!t z`YK4^+j`uWY!;;F>1%-Ysgq^y#hH2fdd!BIR67O%*?IZ~Na$Q14RyJB`eqH7hXNx% zPu~LIj{}U4Qe|g-Zm9G0BA|CXOBA_w;KHrGEd(F@$-~}NcTK_AJV47A}p=u=?AssoUu7k&(jY<_&ZfSi(6Zr zr{0*7FhsoMz>`7x5r}=734yF^zJ46()<&*H>G}Ezbm#{HXEV++^Yv38`}j7bhV%8a zq=4htGUev$=g_|HW{}5war5_Rp2(>sK*F z9hZ&y`gJUU`}!kxP@J#d#NQXpbKUdx+vInAGdLCY%-8Qg;)GcrBssnF^?N|;R{54x z=c}6JGkNe+NICQe5UWc#y{^X)Z-M?;ONF)0eJ;H~e*y_i>GU%_vp|0aGNvr#ma#y8 ziCHZ44u#|v=&wm3X7q8d%P-L1K&(qGfNWubUWN=4)ton3Ws3{+_au{99G!5b1^New zeWtG9$_w<*yIG)rN5E9vs3;cbKM_Fjftsjyf&L2+8q>bo zUg@eXkiCuQ`w-~_IsonguK@AG#2)ZT<@8GEkg2}GIyIfstAPBN#0Ds*S3`wu!*ufX z9gTRWw%K0x=!W=`?U-*HjB$mDB4XeHBfS zcf^%)dP9O($VkGh=k!L9Fpb5`ujKS50ITBiR@a@=n_~v^$)M1loZbQwTD7U&UXbd| z>GW6zSA5onYEG$`i~ajaq-^e5osl3WSmuIpt@!ee3SYjswV1Sb(XDs!#Q2Jy`_ zZSE5s4<17OlD$^vfLj%jndGk3xk)~AbAQ(5uhn@V))DCNS(vX?ALuY_n#>t&gDYOE zzOjt@R#&=K{h$ID?ESp*wK~5Bbk<|hdaW)1FxFmUi_5jT5YkwS2+&r{o@;ecL|C!z zwFTx{T?~?N%3=dmuT{DR;Z$a_<%Q}G6b8Yjc2aq7%7q#LYM(RLt@J_-gbafXyB=;` z3pEJD+IX@&dYH>D)FsfKS6+w6B4BTKH`A!pVoi&Q>{QLVm|m>u zAjZ0S(==rkYeuATi-SpvC1`6nLisL)K8rOIz_>PQt;;XgEGW+gyF?RjX0c``h)H(u zb;ZS+0}^H$8;V61FD=&9V4e}C=X=yz!TqMZSl1-D$;Iwvsel!(vRHGIQY`}fZr8n7 z^CE&;*$4evtocb^|7I+w!e>~`dKYT}xYal(S6!@JQj*CqjxY>$ZIaKTcbJVAQEXjm zi57zU>BglXy+n&311F|hNXjKzoaCbY>AlU`tC}ik7M& zCh}t~y;O~-ig^&pP-dx`Vv3XHd0ga|syWh}myWvJQmsyMAXA`^^Gme`B(7E%v9dN< z*t^0~wInIotSP&=RIRbBnHFZRv{Y-86nOjLkyKu)brC@aVLp?UrCOh)F@-gTzDu$_aR#q-B7-%MSnj+g@8 za!PgS>(p68xUsT8U#CqqglUT{)OG3t@ylI1r=9Dx88Xb3&h|z#&CXw^EnuE6b{sy! z_O zI_-iCUq=9Dk9PE2r<=h1*S+Y~u6CHg_Fku(!9)32tMR02^*R-S;JS1Bor>{2fEtW|wI{xP7xV#!AdB(*d9` z37Y7}{4yO(@`ekB88Y1G3d?i|+)s|9NH>eibQs#Y8x2ZnncfQJYh}R)32wAZZvzR9 zu~$I6Ia+0z-d;B@o$zBX@O~ zO8=Yk5lT2=N9ybK?wFDTr|H5|*Xun=UfeA#rrPy-FNiT0*Dsg3UhjhpowC|nzh$r2 z`;$C&eJ7O5_4+_W@O#DV!R4>l2a_~M5NE=z>vaoAnDqXj&Oj_)uMYv*$J#Ag?)CaG zq_LhLr2JmKULOH47B9BAfR*d@(U`z2s}O!%uaCt7x;il0xLzNRWNTZy>%Cr|fb=`d z3|GBgWhg7`WO+urb2sQ#=+M#gn31U)bQ?eztj%qv0dVOXbbHLiZpjVx2HgQ|&Cu2) zvUTzG$^icgN{ca1obW6pgWU1Y}pnD_6FS* z5p)gy0C0ouu9dRdPD3~79soaBf~cK`{F#AlV`aIX1h5k8+t%SXw_H!f$ke>ci(kt{lR9x3^CF7(~;WUt0p_AaDE70n) z17=s~Q$S%UFc*9OwsCHSJ`Eas<7tjQ`4##Mh@T&w1y@+17a*;PNYOD6TcOWF$Cbj~ zTMYYKX@x!)v(=lq>I!`x(wA$pk!M|Hg}#s!bd1fddxgFjQ?&DpO`*m0tk9Q|JocO= z9x5yJWf0H)@vgc;J+TC?l(1)|z5;DEZN>VbGXcsc$BTy+!$;%dgb8Kf4aU zCjZo6X{Ejc9X?vZikIG7Y4=D2JNhV+SN_{^;?&Ju7x^$&}0Ad_K z@YcIhKZLS6bg)@gSE@JuxM2eh#`;mD>Q=bajruWE7;dKGWi+R6)K9>|5WpTUJSm>J zQ9lI@(_%UXD>v$A&{i!|H|iHLnGYk-;0ibDrCLD+j4W@| zFJlV2!XD@@-KbxI@COeGuwc*gdf9&YM*TWw^&+^+jrvWbITRzuxKY1_Ha668QNK~Y zi@zc=CtBl;`aQJodE|_rDl!Y~UB&8+s>XE007odlN`HX%4Cms)ewtdPKZ01fOXj=u zD*Y*@XRJTvGOP6Gm_GV~W>@JiAc3nyoUy2zxmEfrSm0bagf)Kd)rvEA#$9&CB< zS*8EPLfC6@g?GKH^j{Eb-{gs|x=QXXNsJ{1kYA8F+vN2M;4lCtPIRffUI`tBD(^pY zOibtXDj?%9-koiyoOJVgHF)4h1A)b{9mwYO8ZgggEPpv0&;0nGc&l|_2l&ykpGd^n%MX_gU6h2dhsmS{5_oNtdqISs=#!QL9|0US~svS+tS4XErX`dYzMGLbhou zPrc3s32os-+Ofvv>vdi%XAa)X_39H7jPg=Sp7pC&Um(vx(`oVCf)6!Xs#ibo&=owH zj?ZPi&QDVM0HusblU!HobwQGn2RS~q*LBzHLXc1o#5rbQ^70ufvqG@ync&Siye(7=dTkenutJPjHIf;k%F&BUQy zm^{I)23=B1xS9YPF4v&JHH2IFHkWVE5Rhav`NhDt#6pAW68wMrx!9ngu>`Ip&vIlf zHE39pGF+vPc}-opLBqjAYsXJ=l?IK7bccms>~7G=Nc)%XdKxqeI&?VVLmx`Dw?U%; zef3NU@SvTO*;lI#%7EKgSv4Q2kuHTYPPf`s*`*qF8GwB|c&Rk%a_BVl$p4RjF4L$n zr1hVq3oM+Snc28(qpnDB7EI=y`7WJsxkilz_g!W>xnnNhs4GEi0#9v1>e#4pkYQ*v zc#Gp=qpkw7`gIb4!<8B}9y$ya6X};5H31-0f-Abk`ZaI8N~0!%+s8QD*+bdgjhX}! zN+*zMD=wOinha#6FE*8XZ=URP<-+yps_+W1-5-K2RSo^MQ5 zyr1n}g^Hs|^T9(!>RZ_ao3sGH?*(?%Z&EHP$)pKKSjKcMNbEKAz3W`6SqqayM;HM| zUAkF|K&<^Mn1;<-3>7}o-oPQUSxb@(#3I8QHrK4BAhEYFfX6biS=Rv>PfwO7j%NMU zvLutOtw&t3S=ZMxHMKW)GGLl@1CUjJ)Tq&}+^pr0wy_LMl!}#RtpKyygyo>SSt|jo zvJDNcr&%{fYS#$Y+pJZQnm*fAo0W&M(l;P#b*oh$$yM}WYPA|5t-{y|V2QX|jnKYd zj-UX+Jae_0Vum)%VzR5%3>o->9L42UYc)XNLX&@`DZg54l0uGRcZu6wmM0LRlFo^B?# zU#+%SmOrC&YhSH)5aZW2B=)OSfQo{Sc0|yo+IMTTG3LUX(~#5}b;MkCTU~mMI-%kT zXoG)(JhMidz(R-5MBKVYT`|Wzd=Hqv|Mq5DQm^R6XkN)inYqS+SuywlK z)z@fSlJE#(mM2Jv0lzD)(ROhAU@K zT+bTa1Q6Qc9}gjp^BUb8Gx>)vs%un)wqm=&<<+%lcSO8%8yeFV?THBD0ke=xw`ebj z^%%xiF4LlYk+iC2TeKfC@(&#=C%asW4uDy6u-!yz-=c$&?lLW2p+$!xy%@_`S8UN? zXzRyK$W>eP)<`Xw>&h*98&nvH&Ad;@J)=c$2lDJTJ1;xo++`t)Tl5a_q$K5?O zvldpl*s2c!_{tsUy|UX~sZ}2a3E#rKoc*cXs*eEm<6Hml!8}~0RUai);83v7blt7` z7#OE&awZ}*6I}PS>f^PqY%=|;>uuF1fC4wsfAN41k*8W!28_(J=U?1f-3k&ui$^HoVL~YsjgKeNnznL z9wZ))9;lVWqh`pLU22^k1oL$_vx8^jOZ4e=dML?l@_9D+b$U2S$xh0HB&IDs;Fg*6Bo27?FGshL|NjV%c?iyjB>oPB>Gp z(-XDARtLkl@;W^UX2WuQvt5I^wXD-qK*rX3E?!)G*Xe11-8K|m?pl1((CnnL@*CAgX_$C zodgMA=g~R;=vj8XJ_Q(N6QTFn4|D7FX&@_kRLobw6L*}?%FF?hCaF_WQuGeQl z;!H+E$WrtU>w(pzp;b95S~0 z$K5vQ`#@nJ`x_krPzA{s?64;xU zSWV2UlhvqQe>;`w3Bn{4+VwI>=xPiYtX0K!{T(b+sKLuJO6~dwkX7hpc~+Mzx9gwK z|04+rF56yF=PK>`7r(~&`V3E_dfzG6-L8Lw+mLBBMM%5;lOzkqZ)WL)15CUA3m(2t zAUB3nwO#J?@O`ud2nh;$1$0P4OrBNsbJ26Kq=#BAbcDhGgrJy%KhXK-rQC)XIZwByH$1jxob5B8U0kLke*D~#&>n-SX zFe}yK?^g>-LE1;L&0xlD)EUseaxvC`MQL!UjXLxHjN6fzS6VmfEO6sSU4zSP)Y(vB z93Xcv`C)dW&H)QdMjwKCQ*NWq1qxO79-13<9zfu_m)#XMs!uH!A{~q~iyPH9LKYy; zmgUk$^{W-cy}^|?>U;oe&O&>0y|PgkKwE2v&^O&1bzv+5{~5~I?0PopqL|}k8T;+t zjk>s&1Z@(VVRfU@K*>6a3I;zj*P;G^wO%yC2YXB{)u92k{3e*>Ue}?4KvpSC3r@I9 zhXz51Rjm`_Hy`vR+o4N915@Usj>>gtFhFF={p{xX4h;eE-}H)7&Y~4A!-WpjfroVs z4@st<>As5{8k!VvC;lZk)puwZNSvowLbT(F*P-EH)`JUBvUO+#RQ!b9k?h`ouj}s6 zNN{6hJBqNL4vm5gor?1TU+eAAXrNGk-n4Yp4rOANR>JJMPF)J=n`5rW7_4>bvIH?Z z96Vw=b$QIPWbRy->C~7cfko!x1(r@-0b;DgAD5BTsj<*jj{=coZL`XE>dKge9T(Z+K6V+@DNPK}55ZAL`J@xQ&|w>`pV_pr!*BR^h+w^YG!4v} z+GL(Cw~ zij^*{0P%gjp$jLgF0F*NI`X;&U+?MCjkQ9M>7tYC(khTR12Mp4o$68^s5W;k;sCb{ zoLN*49wrS@2veKY0Bxn$doRrNW;FuXN1tFT!u05gSPK!o~vxudZ@74 z`q*E#aBtQIz|bRHzEG{Wp3Q0l3m@Oc{iJuZ+5zH%`3UNT>Sh%Z1XE__o!g>~AfD5v z;Y)2%M=YdkjhXDEx2O{!IdT$;0E+^b*`iHJLH26OLoT~TT`?mEV5HNzE!vzUu~;+@ zx%?Jw0kL)wBfqdkTcM1}9HL!ui?&75Ud=3R(RRqtN0`Hww`fPCpMN)QHkB>f2_0rM z4j8+6NWB&-oIY&Fog~2eL-6^kOWtRR^Hsvew`w-}$XN z2o@T0@_ts8!d4vuv0;0%>?6noueah>9gaAm6f9PSDJ~vzrLB4^xG{1hm*MhOy$#Za zff*umncb?l0|Zt+j|^_B-T`gZ-oUwftKJC}T5tC)6D#y?)w=*gr>`cS2XP~qPg_+2 z^?M#pm2R8f4QVyEqh1?w>}`4vh<(Xi%Uyb#-V5y~pcz78gy%JinQeL>c;JJ*&C5*5 zZqxf?X-w0npS$1Xw&?>2Vul2dx%@VL@Dy@{6F^~`ZUM0`nu(YzZqtWi3R74WcspyG zJ{(hEX~BtTn?911VWM-KVYca`Ab|rIDTc^G+w`%R4c#ARBir=xn2mz%nfKmp`b1LD zQSY`{-KH`~ZN0gT=9=o^)?Ya%fcanF4NN?Be036U^W=$vD(#qv+ zyYAo@>#iZ=U3R;UKn1Z^bK5Dmyxevj<%d2b3o4ypp3T5;6+jT$K*_8MHBms2Q?W)AmX~pf#BDX^iB&FNb z#CeJTUa94RCeg8h$Ldo9eNtXDl>A6>)D}aYB>xA#WJz@;mhzaNjtSZgbGwsTX2Sj1}??T#V=h(Xum0kK?{JFWK-F5HM_aS|kSmW<@J-hUS1hL3g zx4Yh5`e7^r2O=&hyVM)$Mw61eoAjfYgUN2f$ka{xG06W-NWm~b%$>eTKZ)s02z&BA zm$^wl1+flU#c;YwKZEjv&?497Zqm=8jZ!F$X)1K=Oh<;0>*FlX8k2WEUXB|?KkVMAoiU_`0d}Uzd^-XK1m3(pdKjP zte0adp580otiQ)nOsHnklbiLABp=okTpNPHVEJbK6WkBoBhIxQ(r^VZAD(nkuK@|W3N}F&8@R5h z*VeL{S+YO07WFznYby55EpA*Ap)SCf(3wZ~nrKq>W94vZ|F?b3^oemNzjoDH&b75;y zDX=)@yF!4UVo_(rth_(kyrt6}D(XxS`xqeysb{IEvua5iiEis|De7zxUvra7guU8Sh=z>H0;n@Dq_s6No4TD*LMaD!;@MfC;rooc>x z$J`4=^#d_(PUV7D)cH`MV9H&MK<>q&E{G`x4RXCjT?l2(K=!nz-Mv)QMF76icA$Ee zd1*oWszqHKv(0aJFBg@D3I!L?{+L(5ZuJL?jBDk66C~-U?bZOmQ2r*2dQ-bK5Wtsj zGv1=o+dBk(c54v0wU@cF#ie)a5@_o?Y<^tbZViSEJML8f`VNZA%x(<tFW#_v^aw!>9+ z>q>yoIKoR1Y~#dkjROkh^R{mn$B^#bx~i6p_7XhbD-X}2arTOasfUff}JYf40{=t8r5dAG6=VL;r? zz0U2?RFF_{IF79Kv^|;@6WKcqY}cthnqDgisaBKgvqv*PY}^cChNSmMv6K=1r1Oxg z+oPGM@|bKavq!Tc!r|fxJf_C&(QFWFYP(6jvwJiL+PZqx7B_p3u1?aMEB{?Cw@24R z#3T%uDK6WixiQD6nJ&La^O77EEBiLrvPbhzAy1pSVviPpSl8LJXq|5B9_0Wcf5TJv zCpc~u_vqS~(ALN%cW93m0)*=b2A(Fl@~4E-9xdVrYX+tYo$i)BTAY-Kp@K=RPU3aq z%6qf~Jd6n2sgYY8-=n2qf&Yarb6KwJ(RH!7oaxt3?9no4zx>$I1_P}qVd&$4U1v`06BgoS`n zu--?ssP54!&`?=IN-|hp-lIH_4TOgFtR7rsw^!>xB0qT2DT+{+?bUj4tK}$O8+G};+5jDTo+~_W zdQq!z1jvCI^EXo4)?-dZI6(*;9@`M*{dC~ ztT|q5{o-Ej1n@0B#-_=FwO6}p2&@@eJ8Hldgas}8^iF`lSnr&~a*@GV=mxbA)W5TrF#{`rU( z_UXd_Ry|^|BX8QLkHiFK(9qys+^3Jm0_uihSGi9ggY@k_rRjLay|hmskL8>!&qT$$ zPoIe85G|8k>g9bZN5I}|!u52&ZjAtKu!GZn-3H*9%#@+wsr|Yg#DC0o9XmN;GVS{8 z*B#(tPz>NXqy0J(=?-%muiLMqNl8bsZ%5U)U&m?)hv_HWxcxc~63V7jtm07FJm|9f zb!URx#7&|{&)%=QPT@~uf97xTF1KHIgNM3|oa~nE*FDhI3VXP%ksJ4Z-5U{95f8Ik zwCvY?5#ecCTaya=b$^n^2GUb*>wZ;0Lb-D|MD5oD(AIM~3???XL;Lk$Ex}Y?!`ZKg zk|NC3>3(<1emx8lRzw2XSonqVemw#fCN+X6&H~5x>(L}5Zv`Q*tL)cfAU1`X+TDr$ zIuR+>rSAQDJV}jJE7GnP_Uj1{s~Ou6t5nZ^Jqch{_gAME_v6kGrZ!hiFGXTarQ;wmbuI|^fNmiRJ$2qN7B+!@ls~g;!W{)gzGhjd+&?mvH)(d91 z(+=o4D63WL8hdCrbwJMpSmD#dy`awlodmIZ(oYDc4(L;nZp94G)g92Mp@TYiBWK27 z`<6MN&j8z$>cq2a+yT7+87~1Snl08?_JBSM7+8;%#O~a)59o7X_PN%r%!u3peIDA^ zkfIyivIF`;1c+*n<~DyoUj*=sJC0w+V;rz87(mMbeF;49sm0DEg#-FBh?UJY*X*_) zP!F`#u>-T=;sJdnW}t}USW_H2ps&`7U_cQ8|A4+$LwGBL6Zipr9mGVt|4$-P!(91* zzCoI}!}>QGJKgaE`erPO{(2nSuF3&@3na9}-XXA^6w8Pc2lQfsBZuIX0+T9WEOmd{1qmPK=H(;uzIZ_2i`o1e6}<=a{Yc|8)#P3}pdTc~ za3n%9RXv~|f>FI_&af8Ikum6P(KE+QML{L-Gll`{F&vF zOKhKm`YC{Q4NZR4RT39SBB(!_CfusmJS{9UY9$lUxS1Z*vLl9b!OQ?{RYgqy1IkP z<`3$(k){fFxt4?a9kj0)CqTR2umaxU3J3N3n2wiD7+nWdg%0D71-IT659$vf;cFJA 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

bHKdm&Nld#5Ba0!u3?$3|&Ki1& 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%0D*7!Y8)`IESh!a7H0Ah%o3OC4vknei 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

Ft^pO_ z?ruyq58P;C$mH>EUaI+Jv9NlA-|_rZ3rgHHZf3}4I_3qbZYuGa-h~63C2VGIO0^K& zhMYA7=Yx!DVXB+KI)R0NC+_A{x2*b__&4kTH=v5XCDo$hYZynnd@gp2QY{9n^`9Fp zd$ma&uj6X8IMuD>cA{>G9r>5LHPsT3ux0jvZA7bx@olQ5pne!Uf9Ox#*=}j7W#EBC z`k>l2nQp4vz&cSU9^H)-8r*HEmX}{!@HE?=dAZ#!Pqm`NO=^o*E^WBctw?n{xZiUy zXuCbt9Yu1$z+>DUsqQS2!w92rXDTM%Hv!=}rU0y|yHec^X0v$c&@m0}?o{jwVYbkb zu1s|gNk1lD*XP%+nYS*+I^>>I_mbO*kGYqao#VZ!?gO#v%+$!;m+If71B23iocH)} z|4wy(QRrX`8h(GO2T1!No5dxUx2+lSneKs9{{asJj70{+YvB-5JqQ~1Rg|{8VL|Y8 zw$TSuJycdRZ6%?gjec?Eekj$$;6}M!&D734oazw(TO}6QqKVM?kED7OC>))4%|V0d zuc|>HL2qwoOMEode~WsE-el&rsU8C;rg{Ol=wRCMSgOat{h)>8C@^z&1kH1gr+T9H z6_abqQmg)nR8N8jW8;y$Q;Sp^eI5sodotBiWObs!m@%|8jCD_?dK$#$y?xvS_jIaf zNEXD^%&h`5+f>hj6%z27kTQ~PcA8t=v#FjV$0n(dms~b?k7Z4)4uWZFH(I89#(9_1RR_2V{>1o`l_g4<&?e__{M#e>g!s;{`P*b>A1d5^$n;s zvKzq-ze)9NQ3!dQF~%l;`!>~gpf)L{1#NQQrTQMgkD`gJxtE(&D@}sebKj@>f!x3h zpe;g5XiMscR6o{W+YN2|ZgoGV`U$ubm0QU4rY84Os-FwQo@L`!^K&XUBb4dhG})dj zaGBNs2^#@)bu;s8fnV0hv?h4?ZA3f`NJF_tt(j@9qWH=wymCi?QZJHUD^rJ}Vv~)d zJ?oIEV}YO+HDk(-nL2@V_6z=6}OX z8agB!(9F!jyGnKmiQO<#F4LMMx}wajgjX;W~cpTPr%4d~@I&9oUn z=o0s@NtoMjmTB|a#|+E$EH|@<+&t43;MP@;>p-^1v}IY+;u)Z)z#@K{+cMKuCC<>X z&4+Dlt4v#iTQkwu9_O~sw9Tq=;k_eMCTx>wTX6d&ye~{Wwr!^E3S>0KE^OS}W!k=| ztJ~udF}O8vcu!s}9_r#u2}oyAzRZ-9o8NHb;R zuC`AG3sd$<&hBs-39)LjOgSZsQNIam{yb9^B#h!=hq-E|ok)k~b1gA>6cMuBPMLNF zH&%YI+|HSHDNEUNzvixFLDzQ4)V0KoKQxJn$*a0%>INPt16IEg>*j8mb_EM-+5%x< z1jmWDYo^_Ri=l6t*vNx;##(q2fZa0fPNwZ^LwL?;_e^_`^o=czt!Hrl?U89uaNkV} zaxus4nQ5;AA*!gEPVbdzZxBDEw$0gUL3~mW*WQ`-DQhtHd4=02)4sJDPPO2K`)1k? z#D;DN)=_T1O#71#>yJS*b-tNu?VsrY@NoDIX&&Vc$aG+>svhkvquqg-4gv|>oyBjo z^?6XHg8@5J|8Q=nc5EG->5$?}3zyJ$q&pwu~|E&`gJs4wT|`tsxwkF@j6o zVVSy@xyJq5tJVb6r=b>^w|k}@A#v z{h)^J)A-3n?ublB7GEO~Cf4bZnflefHfJas!hV_h16t#I!*un}G=QWH)_{RSd%FRd z29oYfn!q9!Cf5zjG^l`@TPL9TZ*YS$9R*a(>k5e4^so!uQJDsVTL*^YY=g0DrXc{f zMzUSqkW52K6>HWUXG@zWyguE~OvA`6Rs`2RHripCjt1+@_qOnjmpwYuF=Zuz;j!R} zwybXE(sE3uW6AX`3$Zn3Vt90eJ2umC;GPNhyfXY^c<9E$@4<{9`#3Js@s#Q8`+khQ z1?G;=bOKOVkv>q%2rkd=giI#_`(N=Y`(llpnCYYv50MuM0*%1oq)aE5xR)!iSy}k2 zlQRvkRgZoOA+HhG@Jy!w8)Xn=#Vm49$y8TXz(v5gNP9EL)nyt1UNGWeG)-Z=*p0|k zU(`X_TPRzfX(ULXWi0s3d(4f@)BtGY&~;R!YsfT;r0*CuXfVhob)VrzWf~3cXD$q! zpNyj0qce>uzcMA6-Gt3!eN3iCa8Kbpz==s*W2RHfl7%!4QPB!_YNoN^cJUg+tJRIq)C6R7SBJ8v#WiJW2C!cqf`v6>+MH=Z zQN(PS2zHR^GytRgx{(}sr)6p>KHPweViGqsWOLr^rG8-cyyVK=X~ zOzq@a3wU{ut7Lnoi2%jUfo+P#p_!QJbU^#fl~ei+b*E>VM7mf<3(Y(d&U>nxlxZ?} z?YE|)Q|3*1|96F(oav16D^q^(&?M*SGSy9ZcLlFNQaa5+)U?@TTqO7 z>RG6h8{K)C&M$GZ=Q67o(_hP<43c6~0#0>* z&Ga|$Fkx(gO=mQ?zh(M+S=L{LxMkbq{yoz_O1w0zF}dVFGW`?WW}|OwOC4v^KQsLc zB&>w`CikyQmy`A@n6PY3?($4mlvRb>t#|rxS7f@f#Dk2_CUCC1GSgMH3Sm92%5-&E zZq{8>(UAmty*kr1;9*BM)_*hto(6YKrYU9du)2LHTsI}twI$Bd@P=9o2z7mJrt3=F z)crRXmVVb|nhL%FJw@W%*jhJXLNlsiuZo?T>3Z@4t2W79pJ`fI1(9_Tn+J|$TBhmX zwZ(4_q?ml$+>6e4(=*K=*T`j6G{6~|W|mbMd%UdZ?95EFz>8Hd1Hs~~OgDgZF4|`= z4cw4vc2Ot~(%RXX=79J^VHncbOmj(wB~A=gKB{ zmG!NemVgG@;2q4iX3KI*GA%6%5673o8^X4^rJ0t2cJ|%Ew0CTSTbAiIpl}-7D>!Ht zIm=+-Z_Bit93%JKJOGzxT2cF$6P`_QMW)+<{9M7Ib4$HF(;X#ZZ{)0ScVxN~By^@f z9^)gM(J9=Si6gpbHg|dS6lUgoSEjpx!@_0CZe2OU-JOZQ<$*IB#Q|#zvDwN@_msHl z5=}yGT*N(@?gbB1Z0{x5TZi{%y00wkH9btUy~uQ5rhkKb!VSVE%SGbqWoiG;bU(Q^ z1l{n|boXa^psa-@>=l>xe$xY){sSH+0bMxugT}Z1C)0z#p(U80wls{G>>kYY5MbEM zyoQ<=-K_LOnI0y?e(dgx8MuctJwm#+C)!J?cEaJ30(1CCrbo#&IvaR&clT(f|B|$U z>(wx-jyFG%$7XsAtTPxIdR$wY++&#@2MR6X^-Fm3R`+90p&LMvc*j8f-WA}Wf7s$1a<164^$n;`a zcy-o#2KHi0+>4oBBDWBkw~TH_8;>|P)61Y?x`NjhjGKEo(<{K%WQ4p}D7sfNy$WJe z!jfokuV#9!NUxl-xdS zmv3fz3p_N1_<}7=0BilNOmD9$J{J|JKi=HincgXJFTSCg+u0)D$@DIGAY)El^Oy~; zVRj>YH`9CMTE_?uZP6s&%k+L(o}&Yv*<=kCThV+t-p}+w`75(HD7;)4GXEgchv1$4 z01e|}*XlmZ^bwHF|1PXQ9~cHxf@SWbOdpqZ7^@dzna*?{XZi%(X4~RLwz^L;eOdr@ z-a+-#OrHVxzSxw95N;Ojz?h!TGJQ_&DBp(vmj*6n-R|>DU+{}zPvUXM7L?0hWcm`! zPrPZKV5zyXEpT6E`U>1r{WRWFzuA42>1&Wcfqjktv-$lx(>I`=CkjWm-GI!D$8MP1 zR!~cPlj&Q^7@>DV1ov&G??~Ff5gQ)hyG-8$6r?i=!Kq)i-)H&(I8ZTRX4~8knSKQ6 z%$Hrc*PC(okC}cd3UO&Mb@@-3el8H!zsY`o&g5p+_8%YY*V_!3fAwOfCfHL6oFg4_bp-R3nUWQm z3w+CB*D+V85;vnC&%3g$JLT#O9=0)T#l5jy=UiO?%Z=5C7&7A<*Cp55WO#xyv73>i z`K1SfT07S|tFxz+{mLOY91vB9mI>lX!f_a*F07c=F*$h97rpYoYz z2Itnx^-GXI9FTs=+59rs`Xz20sBPu^b?fKapv3JeYBwq~cHJP?h9y1&Ho->4h-|}L z8-W|M(7VNLlxt&BHo)D7_C30{+c?)I09^pkk=$^oWb<5Gko0qhH(|ZoBG;Ax*4N?Tm8LCoZB-!1WSiiUx5~9ONFdAp zjpI(QYaff-#@4yE0S@<|U>gPx>v_y=a&1diSR(e6z25@2&9xn<{dn%5lix1a_5cON zanECqLtW^$&$UB|b7M!-;s3fFa_tCi{Y!j&{n>8ET$KVUJs~T(A|Ov3;gVFIvKBcx z$`zAaoD>a&Xsb8AC(e}s7sgBrVAPG4>=}#@8FeusLjvobIq+bP%1KsI_rxNRQkcFwg6K-d-r6WGt~lB;V`8&oovd-Qb1bAjucs~fmY2kK<_ z<5uHNy5-sx)L$(pxLtGYM#>WkGJ@T5?M|{w_$1gO@1ARq0)q@~b3me-YfrE+h2FVg z2C{$!ZqHnM)ymdkBna{Cm1}RX&?!8DU{v-4E(-GR9d zB4uMbyq@*q4$5^fKxj|j?(X1Rhtz7pUmqsW80kZD9SYoq?+Dn>aKc<2n(MIQQ%t+A zb%*8ZPTG%5AV9l_EO6a(^(e{>8Om!*J#zIV9j0+2LHJzHT)jYgQv1p&2mk;5=X&Mp zT{a|e26jG8b-i;PUf@PhEp6?iG1ekXLN0;(arJH=jOcu?Trz2za`hqCMu>O_lU<)& zeMuMNj7uOc%8W+eTt^g@7g8e|gZb`=Tt|W%4ZvNPtCKr2S3jUa`opDzMQ1ExcuNI- z0Uc+*T>Xpc%xxK0ZIfh;bp3M;05_^VvT?i{kZT~xE`H>CwBzQF;5gSHFl#V@iOzF_ zaveoF94ah1E<(J9f;jo8T!YCdCTt0IL4kJ~oNEZU5y|1E-*iKA4Fw1!Ik=$^{#g9T zp}B??RS;nVZ|yPTy=H1yuA{-NnT?R$(YcNxX-(>1H?qMUlj~U0_6vgs_8lX8 zq8^i~`QS%pqH|oX<4c^-J0=)qfzNZt=Q;sAw5T4d`kE=;3As)r$Htpr5cqo&5I5IJ zK!L{l4RI&sI+?WndY$*xJUQ2J0Ha9LKaVB=Zmv^6ibZHAZlUOMr{t<5#}ArGzzGe` zEqbA=%QXVrdfe1d=SJkJFREnz+KKX7pKByY7Ya1i6E?erWi^twcfktEv&SjS2;S^^ z5lXs-T%*XfpRz}sP0#J`WTSG82DkPfU`h@*I@g$@AQccpk_xcxb7OKff`^VD)7LfT zI<=NoA9rf5vE_FrH@X!PBwDT;n`>NAuG;|4)N#4SlkVahqQY8#jgM>4%S9`IsH|LrF8u*-Jpb(R@O~`c`piNQ_%)HD{;Iv#VMSTclOyts%s}&^B ztvS`gcY3#<)?95xQHzQL$+zWd2k|pXypI;wo@-)J1a0+r0{>0Sbvj5mBnvA?6Ve6i zyVG+`A~&>hGTUDJhz2()*W{wsgYX#{=O*VmqgLv0do6&UIwRMaWyLUlUgBlDM>sss z%ykyIo?PtFJuZT4`+6iQ)xw-yU!|m)q-f$BlyT9f7J9rlx2zw#d4xqp1`bVuSjERN(FuwU8 zx&8?rn2@93l3UzAbN#DU6#Fr|G;;vCf91Ly+(^w^F<+kR3ev?c>qE2IMGK0#BG;AV zbfIK7I4onA+?Bbm0t?#}N+Z^~zq?$O>*@mMcNTFu3@VAMb6o=-c96r(Hs+dKQ$WIg zHE_I}lIz-{M9;y!yQ3$)HrI8vZ`cwiyX$gI1@RPPd)Q4T24MMxo6*!<*OOb@$8qAJ z4f8NJxIWi3a>B5vaTM41X}P8Yd3xd`G&3~|_T#4Kno;6Zi$RT_Wj7<&OmJItgb^Xu z+{|3FYIP17V{a|b%5?)!7heXsKUN_zo?TT$Cb{_&$R%=77%t0Zb7b_ zNcx}fF1m~j8fAA=u7xFT=ZURii%h&Q*Ucpkcf;*3jPlL7ZUGNtIkI5{H~U+1EdsKs zy!#>!>_xd2llIeOCX1^gXPHD~ajsj*wRUwI*4N#dYYEAsT{FCv*@Qq#axDc9TVFqm zf6B45G}p4SX5*dAhF}IqU})O1T(^-Mc07yV0`tN?b6c+E^gTxt~*O)mRTyfJ9BZQmvx%g zlUMnzP9vXNwCp^Lo#CCV*VqA(Lg-Fo0uFQ2$S%U@V zcWus%Q5h?$KQT1tG!i`_Tg?->o&+kk4R&k4Ed&pSrS8dGPmx<3SM~<8@yk!;db+4)R0G@? z%kJr1&j1BVf#+HQKVe$WXL3DTtALln!zK6GT+e}q{`KvJnQpG<%g<5evE!H%-0kl9 zTrU&_p;wGSUdZ(#Ko~ww$|m<>u9rZH1%(!n?cr9FuXqERmvX&aRy>_>-?oC6!B4-O z>y;9>`-vA!!o9wd>s4?YA(Qc&eDBp9X?bG-u=rfX<3 zwsP*BT<-$;-rAg+;Dm6dUgSH=y_@SjasxRad?^l|_j0`tT)2|5w3%hw8|<%n%)OuM z1M+P;Ch>aRWcNX?4*`M}5oNTQI`J+#rz=w8Tpy9=XWB%%=C5u{`bW7w2JhlKFcJq1 z==kGYpMd$+7F>*%2!^2dpXBb6@59nlfQwh8R~E z=;rzcFi@~}((q_HY=UQV-{$(REXskv@s@fXF z+A?HZ1CLp5UDY;45zM&I8MJ62UG@Se4|ry24}RZ&@<;GuT+#8h>$i>ivj z!|nz5)E?e8imOV1ZM@nDchWY-B~_(m1-3q}rvi)jl~$F3how4*mqy09tg3wVqCteX z!sS&}OWe#Z{Z@#grdrib;5LXWrySWl#_d$q&H$bx>p9NtT-7cl1G&HyV7EVdyxXO! zuApoCuX=^RXRd2i-2goW2iB^1sS=~)#jaabyB41i9k5U(?ON4tfME~f3g^Qw!^iAa z)$S$kBiC?>A@+2;SG7m^6JdW1F&OOnx4`XD)t=}tvsClo>lDyWVG0==lGFs zud4Pg(t`&w?R!_X59!eTK9fhfeX82GsKdfKTcELhtJ)8!SVd!a!nwiiSJnPtq2a7G z^M*8jcK@mlDC*;p4%qtxsyYxLj342?y?)9aSk*!0=Q9au9^5EzcL!B(X~U<*C8s>8s-_FKH)Zjj$DX;ReUO#ezAes$*AG7Vg~B(Fjg;$5wS5Ii5`ji!)G^sTr0*yeL84aaA2p z8Q*0SSxuuk$T{8dRh>}&<_vC2#t@pgD+rBGsOrS>D{Ht>sl7vWVpS)BhuzH!vMs!% zJE^LZf&FL^1KFKi)$rnTyG#2AHtj?jUezh!fyg1m`IzsXQdJ#TI7xcqz~t(x8c~#L zWQ14>cPSf+Z%^0#QFwTU)9Lk$GzI&`bJjO0OH3o>?Skrxd2B3V`3M%hN?!9 zYYkmFrB^REs;bdNdYDPBM^`n5^xEXt722;>H>Rq_0z@~4QMg$zH&%5jV4&ks7P-Wo zTGdz}KOMLd!@dW;3Ra#)8yK;%RgI&JZ3ep>>&8_zp44iMwZS&#-)u$3SJg!B+P<;v zc0Wc|(^OS6U|7$XH<;RpJGE=BY65r|#$iKx4|Wr(I;|`j+~HLd&nn?;Vxez~DGK2E%ZuLc>$6KZhq-}LsHYmG^Ui)w3Fi{l63vGV8D!^{a9*Vt z11a%6CpzZ563#E`F3fV~QPk|8b?29G0dw6d@mkL$E&0H|po9wx+zTV+dStO(Si(gG zKAA6HswdN%!2Nbn2^SOh<0M7TM!UF#ODaXV$|Yu?cXYd?giDFL>qAbE?9vi0D+)SA zIG!Qo{@P_FTu$7d?JbR5BDz;DFX0NJTEA2q7t`d560WS2>%<6&jB(U#SC()UQ8%Xk ztn^Pox#hppt}5Yb=K9l)+(}t9$X4y@60RYxeu%jsn*Ev*t|g>#ZhIuR%e5t3$Fv$S zxQhPzYVEobt|y`?rATxZyr1$SnEQFJQ!H9u3`)iMxuJv`nd>ho1TZ#&Of23DJb}wIVr$Y_); zVIpyLNx=m*rxQz88I9J46b@!JrkI))~mW??o*^HNTEh=F#QMdLy1tZ#DKKB*A zXK@Kjn5*5>zlSX;;Q^-HP;lUR6FgADgGBrZI+)H{hu6xH;DaSRMA#q2RPd$AnLSj( z((rL()k)RdnoCPqM#L{I>Phx^2~RNX+g4jYtbtA;o+#l-VqyD^ zC*zu1kK6aj5}qQinc-YH&7`MFc)BPmUbalBsa9!Em+%bnHCU9p!Us;VXG(asDD2#i zkO*2x((l<4o~sn5xfDG$kFe)Tc%Goz-7=)go-g5r;#=(!s)o_)!W?^{gcl23ipetO zS3u7fOL(ckb#%$0t`w19D&b|~>H{Mq_wC%XgS}kBD@9S~XU`oBGwqcUUL~%jL*0u1 zWUuyW39l6&I88*YZIV2%mGC-oHMu?cRIiutMo~;BleE@mQx)}%65b^4)(x4P58Y>P zmhcu4x9VI#Mb`$bPw@Y}3xZl6de~RQNVRNyD$&|IfQ^LDN z&BY<%-{rc6-Ywxh=IW@Z=B5~I@0IX=0G5sE(?T|F2_F>Sd*-ILu~-9(*n$sA_%Iab zbx6&N4@>xnfLl3SGm6B?Gj@`FRKmx^{l@6y6eko2_~Q~jA*{tnQmxuPDdAJ5i<_8a zg}fboTEb^U!?m}7*WPUVtc1^rX{eiqRoUkye8J=zO!5^|HQGrAzbN5Lg8oNCICY)~ zUzYGy__WRTiG5YV*G#JR(PV>AUx3`$621wT-g$J8UuWNx@GUVdoHp)o9B<#2@Lhn! zeXFOjz;`8lAHK|6xS6VI=_a9sABg!&xDQ+KLkT|;@P~|JH&ZE&k7-Ya{aC_J%+>NB zS6ke)pGx?dh=wUn!S+iDzY_7gxG(Q<%E*2#;WuJxFr5R`*OJBa zTM54tQcFhj6s)t~OZbC8ICJQmkUb+4%Kj+fPvT)gQlRNqxJY{%5B*ufUzM8q9;zB< zf0ghzA-|@V&EdxUyM%v;tl@s%pM}l#PYM4L^ix8Yg2NgdyYk->Y-({xQ(V(HTG0r3 z##@9HnBh+%ilY=7g~3{Eg$OGWcS~QFF&`ZdpUJ&XF(diWv;n7Fb;SrPv5bC;X2p$- z{vx-PBCJf<4^ zl{uWN>f{!(2setbF;Ty=$bFTG!aaNxZ5&|};_5WLWwgjqmu(VZQ({`Fq>SW#z&4Gr zS%By+Z_pqZef1w@ZXJ;Zw${6TMTkQ!JpPAKcQTHU1ca6_L%GwF2q_WQ0+DfrXU#N17D_T;J6E`65pp7a zeN(Tmo(^^L2<75yDx*>4s`uf&R*tZ1rECv{32L-mBkV>@V@P3f-(I#`gxxEJ$n|3M zNZUQa9z}&*?9z55`(eE85n)f_TFLz7D%&%{UX^dFn`-NMy6hEUZ(?rc6!ErbSHQg> zcIMs@_F---*3cvu<;g zk%;8CX#WTY5Le@tUdiL^fCvXNt(k9;ofog010x(%d@50()~8h44~lSb_>_nIXgfH< zAtBwSZ(GScTL;U}44U>KLI@QI({a(rV-@iEDH*pQ@cAfVr*MOA+j3 zqRRFF5jqpqSTI!DVCx*A3)314`XO=`d6x)>5^_Hm`ov>xf*l&6Yk}*aljng&l=F0r z&@EKCY|Nk$)-6K!O1hR>t`T~K^Z>fju^th6GOf+CgS74jTF(f*h-jSp@RlMOLf5wu z4kPAT!C&Ljm3i!4c36bo#NCMd2Xk=ILF#>;^^VZzzpvzl2}GflqNao99~e zjnI#{x<7!C*Xcvc`b9XLkQx(4q}C3P(4Uz5QE$|x3Dy9JGVCAWh@x_-eBQ@-5WRLp zgd+=lGP&VXiSw@=8R4j+Hh+ZrsLvBqi1>FM=clQGTog&tt0Gi0qZLPsI>U`*Qr1($p*lhh(Xe9WF_Wv7J+FySOI&9R z9SGCJtu{hkQBXTTr-7V3)I}Ib+;^m^y0*#LW7@z7gDS;2vGN?iFbXy(!eHWB)jV8> z+u#WGO#kl~ivPx|XCB)kzhw0hPGA|$^MH;$+P3S~v4fouVF)q5{f3FF%bRdWga(4k z?Qspc7$1vCYd1s~%3Rmg$=nsZl3YlLp%EI17l(|TbvH(6DvE|GxQb?2Q-om!&XbIy zcs-#e*susEhAJp3aC`H_2*U~aLz?T=hDT^7;2Kx(0rgxH-)n(2M;O6ecPuw^Tt-A_ zVcPeP%!7eVw8UtMa1ud3+an~AIVr-(N-?SflONY$BO{C==zd932(CHt)&dzlD#B>y z>Y(O*VxuFR%%mF?2_>A{Z+7YA2&WKt7pI;!W9^g(r-lznHQK2WPGeFnrlQn9J1xTL zOoyH4Lo#qn^SAi|x6>n>!Cc>;wu(>5r|cOK&Lrq(#0lb@7i&8+!dXRCm5rrE;aG=f zML3(e{@pLt0EQmr{EI(zc7$`7m^a$xe?B*6zSH&5M&X~C*T?( zJ#4vjkk;M#5iTI^g+>ensAs)rGG7qkLgx6(q7MVZbLm|e;i94zt{A6DKb~xhiy~Z1 zycI{OU!$x5oE6Z;5iSWRA4rTQA@w-BB*LXcms`HvVvfTrk8qbpxQw}BqU7Gn9kzB^ zgv%>+QPGYZ*_t}LJi--3eH*opc>G@x;Ywnf`QddZ+m#WnV$%Jb*W-1r=fc5tRfMaH zT&ey@OhsNtpaHIqa1C=?u_|_;j+*u|SGgv_wM6|{z&L&!F)7Jh8{xW2Rg#qPbfvEa zSJeW$F2eQ9Rlj7KL=SfKg+sRQ^$~6$Ug)9oH@pFa-4NkMX1JrNn!e2J#t1hNsOZa* z9%=C``kNx$%p8qE6gf+-8Fq7oTZs8aIuAeY=rt)W)xi|{deYlPbfxRc4rzr!x_ zdsmOE8FpKQ+gZl1>Kdwe$jQv@5$+&ZnMPViQ3fv?11Z4X5n&8-{lw5bP(C8ZM7Xn3 zO?w%Naxm|VFqWWSy433(W@96aBjQ%TL_X`J)UI1?T!it&{myga>$Jc5gL8S3kB=~+ z_{tLlUOF=&!bIZQzmx6{aD-DGo*Uu*P;Nk{w%z)4wEH8>tCVA;jH(fX$>f+9VSWYe zKbY@GMW~%0VF6LsDw10~4S34Z>S#fPh5zAqlCkWWCkrDiBCZJ?!Jq@w)0#Fj*Opn^N)6<_585gsJo%5{sXYM!8YFv3Gbb;xw)96S_Z zDU*IymR`>4mPX*J^ey*Pux4?VEsOAQf%_Mu*t`qu;Rufq_Zy~)u5c+8d?do76^!b# z6i?Wr5gseP*R3oyEWH39i|}}XGZL(0gUB50@d!^4*RyZ`+@6T=WTi&(k?DNZo{aER z@ui+VdcDXo&r=beCa#^s=UA;h9pRax++;EhqzgZbWcV`?o+a)#PoEJoxqCLkbA&Vv zhl*Wq&qa8ifO;q2EN;_1AK?XJe$0l6=lep07m4`oKs8=+zZ&et2rm)z3)88a=s9th zy%gc)%IDO{tF@OSyh6ksWundHD0jLiJt*yQuY7wY!mBLfk6S5Fk!|U`M7|o~HD-ie zM1{c1hr%iq~gt65#FwpVd(W11#x^k!aGHUa_1~BQ1|l1_)dg(!?y<(gl`G^twnPjVc$mhu7Y)I8P&qK{dW<*C#K)vUC$Y| z?<4#W5WXawNeanUJ^C-TZG?<`FUmxD9+dK5&j_LeosqUZ@xP@ zUw=gSleimQ&w7{KR@@m$DgTV{7js*=W>?h@ce=jzSA@TbYLMxJqt5=0@DJ0zb9JKz z+dmQh4F#5-$Cy$7MzCpqk~)%~Y%x|~Qcd>Z*x9}nVysBaw~sbjlemMp25iL`D-rh- z*nxs3TPeoM0dc~d1-5dGRfuQ}G!1I9Rbs3fk_R1gfUO#1H73Jl=?En{u8pxeK|i;o z#1!6m^%!dqb3@^mw6j&>K#8NVMvPYBi>`H}tD7jKvsN+IB(|m-9)^gZhL0A>nlV}v z4r4vb1uv4;PU{$J5%*^WSMOBbs$RoMA(GaLu{LuxX)QX#IFD<`Sci~ry4Tk_+SZA& zZl!h}8`6Xu&$r{cG1eolE-{RXSIS;5#`?sxRE}X}vKSkL)S*3XgBTkY^@uA;6BXKw z&bJL?Y*gTSmFhU8e8@J6u`zMY`e~;fcZzKsV-u!>6_byNq`PXGZ4zTs<}5dm-Wj2I z4Kr-h7@LK9c!E~hW-&HrTJ2tXCBw8_N%qI)F}5J)7qG1Inr(|1TM`Njgnl_Wc+yqa zGR9VwqP?pccp7dMV{1Zdvc~o#ZAfQ3WtpvGY*W*??e3uw) zh-(A#oyWVmO^i|iC`awt%Sth#;!Cn$#6YDs7yZ`8hzp$8H{`>FwHRd&k&^DL1qv@0^i>l-Kr&vG0HQJm*|V!D07}vEP3< z*@v78`m3=0V(d@cA1poj!rOzA#zSJXCEynVPfNXZB!FuhqaE>Z)=@V>nojLvv@Z(# zC%jh8ENdU5LxFpq70GmRGCIWQNL;_(X9Ppsc8t-9X*WM($abG)onoN)l6%1^pU+cz6xC_MadPfJyTmw@csPJtXkt@qhsNkyl-2U~?B^NQHAc4r zmp6JTB+>(>b&JuRxI1UOilVlp>_!y>w|k5p;TK$NMm@xO#OO)P-&F1CS)yl*UIhF> z(|#~r%~`J)hXu$fv$0`^#pq4Q&rqMf3>wutMxRPWy{c-gPmI07M~tQl?nV;n(H>!$l*c0`OLi%+FpBD34Y z6pbAj<0#_3aW!(ZdsK|0iG*IZ?QTcMIHvg2bD6m>d^wSZ0WRPjujK(TjwkL`C^gaT_!w18yA!C9TIg04qndyQwysLr!Od13 zqlS>1t|0WFL`%_MmXHNj6QeeKKr+#psn*7*BeW*#pj=68EN8D(7h@pdaPeHu38%Xt z{+nk5V+>+WWz=au$AP-v2E`ame7OtBX{K^1O58FyMm=*~Q^~5)I;oFwLV(D?8A9o& zoe*P4QMXs*l4A0B8xo_T!1;iZ|C41?c@Q+j7)splVXAcujnPvMI(e!fF)t0T@DvPHJPESk$0Xx{&;z7-Kl`4Olec2`m-0u;d)~b$EF-8ZRl48EJ2Q^U|JK9FaIGMP=Gv(a6mKMYf zwX)tnImRhPRWd`D^nur}of6|z;u@h;v=@t>8soJ8iY_WV*xG3^PA9(n%HyuPlf7F& z!shfCXE4{DZ<6&+u`^|Smk9RvW##y0m#YUmIBY6>My*~E*H|z@GbYd0#1wYTWIIRIG4D7xuvE-nlR_aIFE?mgDs827?*{gS~jLr z3nPxjxI6$PNExZ?@)%bXUwXHY;{M%fSH!roz*XZ|K8NO#9dc!itBCuD3900xW2&sVxCMD zge7);j2nn+xXH7!8)DqZbX8?H#<+>OZZ%DIt_W|6aWfI^H3s#owVPwy z5~}Oip^M!T<5nj9l#|yj!vEG7w-NIv_$~+Jc3X_wLmf-cBd6f@7rpAQ z=`rpqzISB0JCJ7CT`^`5_X~`rC)$h{Gl}?4^slQMA|I_YW6UDBT)(A*s2FnmYqMg^ zX0AWI+EeX%m}H7{MbvDwW87V-zkmIZdb>NuJw$v@oYdbl4DX3?FLB=!s>tYpd2fvS zi1|g`M=n?Gz8G@|`6oGT+gqx|-kTF+E>SI*0dl-)b7S03!2OC-0pJ$p#wm8O;fOD=Xm*iouO|c}#1H}Cq=9DINnaZP}^!*=*@nBJ#t|U=_ zi^(T_Fvdf~HD(#zn>m5|Lot>HjD!Sv@MH@ujlo8`a(be>UtAXBVPbxswrG?WQ?bn^2@Kkms{u)TCu&PEzD2KSj^P zcsAe~B}(zhxuJ^EvoW44aFJ|sA3y~HdoITF1wO^e+Ue1V%$et7yg*!Sl)mbCzV%*+ z@ggC=6#G(-icFptW4uI63x|HnI@wDxUJjp$IAhcxdpX7{g#6N!H)6T?u~%ZeN>qa) zd%U6cYK+$^U)Bw+=Ip-~<8?y*2isLKFmj{49^(ySZYtEj={#hljqpZ{H!Ed1J(GBa zzZv7L3Py`%ouO~Vc$=6X+Mz822in^)-XWqc4CvXbue}rF-H`4^*15eK<2|N}tK2=3 z8Ka2fI*kG<$Gf)oV!R(})f!}b-jDGC5l!g+ZR~>>A2Q`pHIF}@3hNIi48QX}}g7~c~M8%tM)zb?Oz@dI(cW}2(0 zS1C#L4>5ius%CYP1LA4jJ~@KcPRiTXXLH)Gx5 z^^E=ZON?I$`tyaiy<)^IqGt?$_Wl~5p^XWBn81}P#`2(n|p$M}Oe zYOgnSqD5wd{So6&qON!1oa$Iqtj#}T{6$==f#Hv7&p*iiit%@VC_)_0F5BNR{vqU7 z|6oS`q{iMqG5#%Tl&Z@(noTSq>Gf|6n_lUM9Pnsw=y^Ghx>A;41?KwI*G|5`Y=s0X z5>nTwxlg~b304Ye`WzW%D1{#Ko>onRfN zeUs=(l|5P~!MdRcPuDtIH^F*LyXE5KMjQ`Hk9geNO|72w60FbM*6P2gV+I!FQLxa~ zPq0CO^H!9a1DD!(+aSS)#QiemsJpNv8z$I@pgU~}c5}rlng=mGiP%O7HZCgkFFPlV zwT%;OLR>v)qnK`tnzTuRO$n_@i1$X5G&4zr*ro|KBkV8c8YYe;nlA;|F?8q`K7{`^}F~Lqnt$N@nJjr~j zMD3JdXW|;=RFV%W9_^f9mjEgJww_bFBxpm(FM7IPl3iw-1f@_+M&D97DJ6&q>0I4^ z`-3b>5Hs0YJ@GT^B3D|RAR+E+qZP6EIZ1+)m|y=R$)F&e&}?afjHnx_@bvaiG+K+$ zr9p!He{+|&$IBCxnd|BMnkGs?15s2?uq!kCav^upc1^Gwf!1m#dHXKZiyXM^mSFb+ z=Tavr>{sUQ3HBhaF(Wl5g&x}@!JhvWm9sNB;ag&RCfJL(>+1PI{ba8MdlU2PtQW%< z*xm{DDZZAr?LtQeOtyUz>|5X*Kwi@mxn5`5z6tg#aPI)a^T_v0us?A%tYv6*BMCO! zKfwWn^kV}Q;I+vPNN`~BvDamE8e(=}f`f=_@=mB4YzHMcIMhXwiJ>^owu2KKQhcdX zOE&;3y{5 ztfuN}(KJUTIGRYY=e+Y=QT#_IIEEQ+Iz3Os3)9@iZpS1zmbqHD3`IrT zug{^w?6?F22x+VaxWJMF5*$xJ-Dw$0MaJV3R52aSRk=yhTUnmAq}NlGp!&ZWU6irv z1T}=zfqp#Z7)!4vL2ac_AF}A^r655aq1G%!HLf$Aq;o!XKri35L24B z&eS=e`Z(?D2PGI>eCm`X*dRIO9Gsv&;EL!)!$LAmIM4M7P9W~5P0uc1x^yZi4fet6oz2Jd6M4+Ib1iFTU_6rl?D5o$&7zJ3qk%;R_yV-Z<)l z1Q!z1n%}RjU6|maP(tLY3x{-3f{Oz-pijSEy?XZUYZoWDgqUlY@4Uz^iJ<9@(k@AG zDRZ@C+ftTTLr2y;YA#K18BvY2_f|wkYl6!O`Q6dS#qgC!mdg`dL0Cf=0+3&k;7TH4 zB>X$b6R^5Fu1s(hbG1atXK1#o5?sx+CkLu%xN>!ZYeI#LT_nqvYZ6>bq%}X`po-jb zSBqVn;5y=J5k-M@4Nb#b+pkM-Jz>8IeOzBYcCSxx15v-u7%-k8i0y_1H&!sJ`YCkA zjR|fdrpe9dx75e{xGBNS1Y4^G5`*%oPS(*(yE(xv#QjgT*CS5)r?(`ym8e@)6X~L3 zf!&(mHX?q-(31`Cm0G(k!R-Y7X-&VSZb+r`d3%C8n4!U6Hm16zmZ#ty3C0l8C}rgS z4Yx4~?yP)F!jUz4joUjDjAce^HC1$~Vg)avuxM<8al}<=Z*Co#j*Uw&o{;wJpt>d- zpI}1eOS0S)RDiAnZ9;;H0q0x0g$^Hlti*{4CJ}e@T#)nOok*U=qy&?TTv4A=UzYsd z9~YAoOku8CGqlA&w5KGPT72NyA?~ye2jbKO)0pd5AEg%3Cne!GEy48SBfqxEXLl66 zcHQ&@cQMzmt$|!gcO{rXKpUt7{S+ja$&~spLFCK?vzTnnBq!N>SsY8=->d|)!$~eDPggzH$59$^e}Z`h&Lh=%GLXD? zUV{0=)w_DGp!o?FFsWv>oP095Z3_}CEWQh8qFd7o6D%rl|03nYaY7d*SWMhax9Emx zI?^fdaILq+36_NFtL0zYmLzz9fG2La3$JjpmL{5c(*jcG9s&N0@YNl#84>ydA{{^Ox!) z2_9vxhM-Mf{qUm+9wX3NwN8GBH;uYP<&eh`JWkv%Hqt{>Arlq#c!DPgyW0JT(e(?} z4dlAw9(y9elg#ydoHSd5uBRsxJVmgzej%Lk%V=3|PbGMoxTf})f%bHQXP8odMKX|* zdnUoNMAWagJ=)r{37!iDoWaXNdoIEAL|Uuj31kO(7v*#9`2;Tz*Ty0RL*3QU_CkUe z1H`MGXT?x^F~LiOd#K+b?W;pI^2o5oQzRwWv?W7 zm1WfY9=xb}4!2hmyhcPL&6|llg4YtfPN21#TkKN>nRq?H8^ryfHP8c~&d)azyjc_u zS|iJ5Qe^aIg10I-Z7k&}Y#iA!ZzXt}c%X7*UOdU(PVf#fH&^Zo{-4$QPJ(xt>wmT{ zCs%ady9wSSsPkCvJ^tfNyqDm8W~es zIjuE_l!a1(QErUYH!$A3BD$-9=DadHv2lkHw64K*MXbTzDe*ck>WUTY#g2b;(6X@ z-zNBux%%y8V~*%%-zE5-X@60YIpt4+?-Tq$)K5bPIye|a7TpgCek7=$N=bp&HQ0{{ zej?(2%3m~6FIOCUIWqbw!OzUqFl)s-0nN_|ej(PH7?1K9A;`~N_Dh0ai<&sYB+|6u zB?+ES{g7W1{Ki~0dSFw-5c@5`??o*tcNa@9Ag}HB1b+~BBopIe(M~|zmp>BxNi@9X z*uiF*kT>!0`ZK{_%&By9hy~s`b zH-X(1y7%AZF_r^{6^N@OPf6KYuaIIzB7O}H)vIWYRM+%;lZAQi_$C z>l;9)r&U92#o9#ts8YRyw~qYWtes*V!urwP3R2Zf!gHMz>k@M<7HM)eXLkt+;&oH3 zN8AmMi_j;Ek9V@aL)J^NK6BM^+Ov>SUO&YK1k}c=p-s)UL5dBTR+~uE$&7i!6dMr< z`%XUbY@-w#6Y|X@Ur5%cB>Xl`u?b;6Tk^F=Dsht(n^wN2T!OvXG{t6w^b-m~KoRg} zDK-xXJ!}!7ALMEAmZB!qINKt{mc-TE-gULLwq=T~nASxzkm@a4rP!KD z--1q@8y-7br`V>bN+g+-HeB$o6x$ZK1esD)rIQ2OHpOWkdZHw~oGvq<%wQtV7z zb3soGq&ap@u}dh(!(lEr>_jI#-z7yG;_8*2_2es%f1091Oux~qb6YE=h(ZxQI=s{= zN)Z$D`?gBP)|~G+MMBWereil-k|HIf`QXVfgM>6i7HVSvEomp+V_Axvn46K}CLK>= zBTrE-aBp_wP1egPb`7{Z$M9t#=St1CYl_{7`=gYC%)yMsIMjAavHNnhIOPQy-|U`Z zj{>JJ7YcLqccJZ(V$Vt~9re(WbS>^yu#_Nm51>(+dstt zp(Zk-WF&P!iUWy+%_z%7y^d$A6FjR9OmR?AkGl%F0_CyupcDsJzH&-to=wZ+n`Fen zDGp(-A3(DG7V+O~J0wM0qP|P0rUbx6^Xh?erv)z&dZr%FDRKNef36d>YG5E8e|h7_F%xY1BZZ7Ge>U4(T`(Ipfd z(1jF=bxCn30X4jtN_ONs)bZJJXo{{x{k`LK$-J3nvvp0;jXA!(J~W+mOVOQ}8&K(w zc||^QydBllJw*@Z`abt%j2!Ecq9+k;lct&m>zSh0f1fiFy(dB3&YxnvQXCdOXN6=p z*-B zrP+>4F@V5Y1eT5I$pGC9z~%_f0V$3T83{L+t{|~D=G*Zps+gf^=uju)8mmfCO~fr4 za*FG$Iz4v)M``IG41AC*F0aC6oQR&KXkv*Nz>bLX&X`uT`q$z&)u3@WJ6OlGQ-ca zG_h!icMie+Qu56Bsq(}6&WlZd+^oJg`_ zuAP)(BoTj~(90J!okyk^MM!hlS@QEyDMmBxH-d;Jk`-ick4|wiVK)xms8B|u3I7}|w&lj2|Zr>8iB zxVsm;C{aUBl>n*#y2+hoXQVi@_|`?1=RDF=y`7ojEaK{5%W&S(RSkAlin9qVzbGH_ zft$oiK0C!ZMMX}VlDETb-VW!aIJdy{^Hlidvv7i)o8r6zr*f@$Oyu6ovGY=#Ph3AN zpIF^FlIN$mfRNiA@}GP`iVG{BhWF289=#W)xQKXIN>b2Kl@b(_3bcz-TwHvm4J*gq zQVP5{#U%yq^);m$xx_9>acO~1BtLKw*OUBVT$!EYTnW&gn#L$=ZX|p64x1&QJi;WimRA(?H6BLUefO86V21GSEabRsD#?_ z95A_jo^MyDxQ4jjBK;XGS;y@)DXt~xw)pUx!K3Zk6xS7B`|;0!^)XA52U! ziGbUX%gI^YJuEwTPPt7=F_~rjP*>A$J%@U7iYdfg`<;OXmxMGIrlgo!;9@7yTc&f( zGBw3C;{P+YQ{71{me;ft)0wMg(NlHDPBuNoT?E3rrfFC>_3lbBgRoy%ovDwj(VdZE zCP7W+(zAK>ImWHcOfie78YsUOa*s^qlUkdVVs^mUw1r&DT)Dh~W~aEjz%`sYs}(Zu z?iBYB_e~qj$HF}+?j_(!o8jWk-J9Y*B5S#yBA1Uuz#ukwxZRgx4l^_%$Mb(SC&gT* zRae$SU(QW&KLNiE``1;|R|CiP{uJ|whE2D~IsDRJzvKX2)YR*3gzx(S&D}X+%rFQzD=-)Q#?}OE{2keq_n^uN%1IgO;J0F zD0po>n&L4c{!CGTum*c9#p9KaIo08ox5raFL0r9;zL!0b;>l1M5ATJf@SjZaRQPh) z7;Yk3M^eLYv^|yLY2sn;YLGq4$Pe|?DV_=SEE{vU_TDooo+aYmmA;pW#^_!H&XwsijY}^-9 zyhL1GTs9^@&|XUMa#2fh@J(VZ@(elFUQY1}bNw1QtcB+>PrFxAyh_mT0-FC<+p8&F zBNC_u(x!Ez?6nlH2TaT@ZdW=KNbyGa(uKNZ5U&((649MAl6UKyDc)kz4@)1(xa_SI zZ-;Lj*LShKo#GuL{?|x8=wbX$ig$^*!SEsZZE+K>N+Z5js*NoJS;31o~!`<(>jQ%A1KE)43 zO_PF__gFqXen{~nalhc?^;)O=k12j4=uWfZ*z>|bM?ZQFZi=5-#;Chl{CwKPw@wFT}xeh{uiVD zj}(6r4hxT@CzlrO@cCEfw|}Pii@AQORy9=D@oo24iogH+VlH>44C6WLq~6Bb-zolK zt_FQ6eZg`_{z>sKkxGMRdf|uto5E%UT(5BPp=GUQ8CD?fr>&Rtm{!QJA`u_1UIYz) zYd-06cQ}doD0nosVuqDi(w{-K^>kLM5Kt>+Sed9cDb2rZAGAT8FCKd_u48M zR;^S~O(%$sT3Pb%yk`}K#3aN;&O%D zZEIv`Rp13vl}>%FRfaV~-N&3{Yi4N8lp4ETo9(T2hP9Xs^E2D+E{%X+hHGV5o4J0h zoW}xB%*8m3>$=WT0^t44Ki%V zbV11|qX@zvh6Z#AHL-;OyN6w`wTmTA~G)NZ98Pxk$@k`8v2;8rw5TL+cCpVgx#=l zF;h=LxVB4%HpKj)(Z8>?$xtfl)AP#9a;IA< zLqz=lt$2C`L6vWP|ORVK*k1Yo}foj<>-|cFV9k zbA7A2*Ece}1*3aq*n^-JBl$;MdgE-540{st?*g*@osizy?a(xwcf)MbaC>Ihi)H-C z)1Q{Sa?o3o?Ui9~;+ot6^deMcduP}u04aTWH`+cK_9fuj=+x{62V6N{}51OY+{rP|l2Zma_{&ce)nBgEo zo|f+|<=6}dS3Vp_7Pz$c4$g20L5=4KIw(FQL)-9CQ>|FZZ8NkZpsD5=x{&l#yA17# zxPd5+vU^B5wa?IjxH>{Yap*8^@(vj~7Db&OO|GA5)Y9shp%Zbxxar}AF*~Ia-zftK zt1WdWjWA^BTzox_{O-G`3oxD>jm{am5Z4-}OtiteWH>Z@Hh>2Ihi2%?q;D~g(Z$v^ zLpLJJ-KNqS(Nfn^@h_-u8M?EKo5uE?+xE8Z8F~=#ZLDezvPSEXp(kPeI0@4s)-yvd zrq$~qbh#s`eXk6M5po0MX$GekV~1tv9g0##y{?fmn%)`u5c1pBDUuDbJ{kHF`=8|^ z_l^=D&9c53`W3m{DHT~Pm6pgB>zCnh=BgJNV;PRH!!z_J;CCwD9w%A<3`Y?07v6}b zJ~R;HiF8DUBZ-D>IECD0U6qUN$P7mnINcU&)yqc5j>>R!fs218jlFwFsvVu-7~*ai zTck>pl&QL?#k3rpNipFa))DqD`>)E%j)n=$GK6F;k zK~PecVPJuKg9Uj~zTXCB7({$+elFDz#{U=^G~Nbf7|a|ucj98n-50%6a_8uEJvc)> zbJgNHa-*p_o8bfkp~Yhz_k|pIJ0Zgm;<{-@*4U5?4NR%~HPkNQnL;|n8Zrze>VC>; z_;Utk@!jkeg$>Qn$XqQf+VawxlUunlLlZH-K|4_1*}1V#Lo?I<@L@0;nl}%!<_seUhV4v;m&2U6U_^!%!hUhn7p$oCmJBBm z(-2UJm?Y{+8AcNDjnY9d+D2v=MaYecKVbO2;i!ztFq*jk845IO=mU*aj?Qp$rG^e% z%|q}`?g zXJt5>i27e$H)5pT9A{@ZhmdCAfcADyhI5&64f3HeHNz4>>6$z@!+Fg0KjR`WiQYOd z!}+07I##7-RI{C*;Q~T_;N=MAf(#cDaHH&bVV*C1VTOx{Ye0@Y=Geq8%5X8$YE9pI zyEwxo#aD`b;J5Q+yClP<#NDAwt~&YYmu9#u)KlMhVvAjt;qv0kifR#cx-QRf#ecYb zZ+ZFC6&bE1t_Jh+r_$n;8LlFrpHOgysz$pi!_`E>f{-$=Q~19+!!@BGoqtL->Y5DK zR*?RT7iZUIxQ>WlcAbVZ6p~$+;d(-TC5#wm*Jrqa=`cXFdmyRBLAM(++*sg~ISG2b zN@wH73^!H2Upmun%5XE&ei3q0(7f4h&Tvcdt%PmG$#6@CTZwCslP-2^hTDo#k}%4O zjgGqPwhXryxF;m!uyLH-p5YGS8X59`s`)#2WEc|=dUusBVH7}gS%!xT?83lacsRo&MU|eT<~>TwSLvMRJ!!t~408R)R>(69(mXIG$%0+mT(4VkIRrUhUW_T`qP|}S=%JI1j z&lB=HUF^xGQT4U_uRWjP1!m~SmW?@Pe|sUri%k1FzGt<5u-RVB@Djl=-ZF32sW;zV z%J6c5i!muKwoEi%&hQHHa4|_8S*k{_WO$XRKX#?XTx+jpc&(^Fhn->&OP={!hS!Pv z(e1`>U(fJHQP5vlT7~oNjSO!RmncflTyOP7K{?NWH#5A&EH{j`RYUEq3~w{-9s(lC zeDDS`A<2H1d4$ZI-p=q2%lIaCZK2w}y_4ZxLYkj;(pnsB?`C+9h`yX$O5D#_H_E=Gbn$71&j_yVrj=(&2sFqc|187j%u$1+QbBfV zhA#-XdV|fc1grK%hA)Zxtz6aE$QQUG+JBkhE5d%kbUDnv%J6ll&kNqZ&hSl9pG?>3 zQbB+1n+)F)cjM&wXocsw*|byoHp6%So2!LO?-@=7@4F1&7j;T?Tz>r+72Uqi@B?w* zcZQ8{8VWyT_>rKWMA|&@X#Fw6Petv^M;Gw)@=qClX0AUY4kd4k9`=9E@JsPUL5EhD zm-b7BUzw{#p?4`c^1o*IjfjS&it!-rw+z2C?OQgIk*LK1|2@MW1j7`H4dAQ=?2in8 z64#1K2esIr8U8AYc^wy>MKkQL41W{Xul8$fP=vC-GyFqDlgalMJNi$Ce=DEzU{Jh> z@jMy-&0sUb;CrhHZ{5dSp5m5cg(7#7Q%m%L>pa6}g&Zp~*R@&#Pzi8l-LPVgm5BRs z?yf+*wo;Cji=qrD>6B)c@IY8O$0`NxDMvlL@3&QQtV-Oi2|vnWbI853PJvZ(tX6y_ zPM2iEdP=R9V|C&huI{{>R?o2plWt>Aq4~M=P8Ye5)6V6yv<+;H9Ic8U(koB&y3}C& zCT*2tP3F4kR5-8kwq}mj0il?-YGk9e&aoB|HwwJGr~%*?&ssUwChjM?ZUi};O%1ko zj&%sSe(6Rd{Xuqv1d?={Y3t-zm$_PRRFFK$soSobV?AQ73F0g-vh{MTPed!Klhn%A z&#^%$(Z@&W-5|$?p~O;l+cwOxQ7Ex&3{6S~+eSGyt{^oOx!T4#HVFuaU@~o_H_5Rn z5!W#(wBOA`d=7<^o95VzxSt!gUg7`bC)^L&W;r%zu0P_**R17PIm9;4u|@HXCzm9G zy~hpJEZZW-mdtglwT03S+cL*i1pHaoyN)lV8Xt*rs~lT1L!&{8PR5m6=h%iwScGF8 z>t-%R4%_6|_CH*VGRLW~ZF6i_;CkCAwvBufZI@$v;u?FIzi~`P+x9tjAQm`)_wagi zYB;{9VJ+^EV@H-z+sWT$_ouN`*2zl%jRaM96J-#mN?isxmsX5=h%hN{~UW% z-qTX%l)r|pNdi3dQX^xD5ek~h8?de9#a^yt(dhj|Iy4o$z zQLf-l@yEv$DCgKUROz(kZPy&T6$J~DN!|x{%dtCgf1xneG<6#lOl|iZdl1$-&&Z~= zJ#y^HbfDO%kWLNpJ#*|8s+2t)^-cKF*pGmE&d|El4YmDp>`%n6>E^moo*}z`jsu8>_EgbuztIlJabWnC%F5?( zPal}$AR>OpQ;CcIncYi=w;12K2jw`JxoQt188}Z>2j@71ke|FkRTA0JgKUnr1j9_v z6`@6^3=^zvj&{U-8=7f|!f|VtqkW|Ur<}*fZu=Y^2>RQ3@G$F;qhsYmDnyCm?3kky zG1pYjq7)&a@LqD@*eM5?>$hH>=LZ;abSB~&CFz-h%}7hFbB->={fJU>W?ga|N?;xK z(s>g0A`r*bJ~T(yq7FS7rO%~Mab0tCBd&pIN3V+VtI#b+cS3GGFs`L_&(R|kaVnqW z#PrC~laT-AetkPx&m6r7_`#$DOR8oMw_Z683l(w8jg!$tAMlE=& z$x%xz>_{i)uFX+bDb}uzSgqCN7)VTwqgKU;;X`d;jzL89lk%WLpYRRNh-6TX!IcW> z@SdhwgLBk}kGcEiQr1wPQ6M*rS6G)E(Gb@#w(Ys}Halt!5$sTG8VCqz?@VFdkQ*S290HE~7^9%{pK zoJiPjWZn?+Nqb_B;lwmFOy6_uL%k5%)c9s2@nO zf!pZ39On}a=R?H{Yaox#&v8Lf*F@^CdS9GN?1CH@5*O)uBz@gonByWQePcUx>|+<@ zxH#l9VxV1|;}Rw{HHys4cf+8AY?57;vP;d+^>!m>hQ&r9FWvj>c5GGsjrseuK8}*0xU{8=GTX zrGgr%35g{)F2{JHS_cPE%0n7?e2xi4mAuUPywvGD&L-rTSm4gEiVY(p(I)1Y6l##h zJ*BCWa!d{-seRnSv%p)OPR=ofc$kX8?zEkfV=6Hn5%r8EYEyGeW7_YtYDI{Z+PzK7 zF+F@*r%138MorIg7csZKJS#v32Mg@395aZkONUddf+WR^95aiOftKW6onnY$}u~nyYy|}*=Fasn`uAhjx=WUZo50jJw!E;O+%XOo*efwsb00IZfc?|z0vN? zaUU_aLbN=^TAWGe6?*I~wEJ?*VeUHog6=lGSshP%ITxFgV=l9_0tXBpK@q~-9QPB@ zcBmO;_ve_$R9Jbk0+NrHxnbqa%Q2t1n)Dt`jj{;0`8gI4(il;YQCF+zaH2F8Hc#xPo92v)tT-XP5aEtpX^Qt*|rOva5axATUJ&YVBzB-rYSXPwfGw0zm+1Ckt zX)eq0a8awSsU`Msjz@@8cyiLVnMA6Wzd*qU)s?BA@kowGE59Jw!tf@0G{`hf46C5m)K)D9DdV_zFzmnrs!dem18lXt-)f}%8@#|&; z&0e_)Ud!=1G1p@6-&kb+Bzrx_8^k?1(zdbD``F}z`HdWJGGlF4%ZHSh*fIm4W`@0) z<1OZBklM=kCcE=ij<*T#yAIpPLyTu z=6LTvoc`~*+~n2#y&Ufo_jAyn&lYkc?EM@c5LCbAP?zC^KgjVR5kLCft4_8Lb9_X= zH>)oXO-BiRl;dNf?$`CMkiMdfsy@!~NvN=6mmY`Hy!(?JpB5!$)G6Iay^TK2@fmTA z0Bto1f?Sf{_1p=eb*b|02hiMExvMKY^z8^1l0Jj;{#o*ldy3 z>Q_0wX4-d|n%XWF~ zT;4yqM77`N_#xn2WcQL6BbNzd?S~vc5)UU2pC_E-A9MUvlogkwh%4|@j-QFEQ4JD; z)Y#8CeyMy-4y)e8zvTFpnC}lG>^k+9UvvCc0sAn_jM&(}<@lYTpGCeY?Drgh5b(Vo zrXYrYMtUf;lr1 z`zOc0#aD7HMa9o$Gn`Wa332|-VY7<%bf@8}Ss5!33GI=WVkwZ0w-w4*k+{0T_eaeT zTd|Cl2)O1HzJ31NSSyvWGIO;C+Q^`5_>TcwOund^SkbM%yZ zkF8q9Y6Z?Yt=Md=R>tbY)tKfHwe?N5dKqgF@Ke&cY1j}NPTLw~v?93N5u{U`Oj!=Y zRBKhnn#}bJe;{XZw5?f2>k8C^W&sV>x{S4oI>b|!Nm<2HtF2YW+RSzB78U2}rY7Io zWvo-+EbsV*3X-!<8S4`FYY_|sMG|e@GS(xeWuEntU4I`@KDJ&N>lan{qo2HFR=s{1 z8xZ%+ZdW&)&EBAl4GD#<#1N^rVHq1$kg8fPyp77(IDAH?1VvZ1ws9Go5b}+Y2}Et3 zZBoXj#KP>4b9OCbd9-d?#%9DdofKWv*=A*IUX-J^BVN9Ye8P)*^D?#|zTDesxzm;d zueZ|{Wo%jbmejS}hfd|IY|ApXD)3^Wq_e+O8Cw^)yn9K!KbP#Pt;^V^!2Jy~i6gYY zwkc!V0+)&{8TyVZxosKS6}ZSPIrh7o@f5ZzV|(I$_-KGyW80UpL!~57$*Gh>(~{SA zC}T(BZb3O8PkKYpE2$^!cPwM4;w#ApXg*Ex5fx|4*qOK%Yf8$3-Vn;zg@6XLeb4T_ zY?m_HFfAJH*aNIh8KqF1#~@8ZN@YX@eEZrp(GE2#BPQZkJ2^wnL^>`bA*iV%3!|!m z`XE(u449OW64!zmNewAd^_G^A5mJi=G>>kqv8;?de9K195aW!~Nfp^L%HiAnq+mq- z>v9>p5>jj0XweL{UCY=l)JEEoXXb8Y>>i46h(+`4UdA2)p|D=hm_5qalZaX+BeSEb z8*I-q_97HE(_-iIW+tidy~@~|xLP}!im1)DcNzPHZ|TKgFcqzApEC9(q_x~e8sTD& z>|4fu#QdElPeT3W0(8GJ_9yCpg_M9Su4j^Yx_=o56u3xo*?f{1vIELEkhmI}HOM{t za67P!g9y1r?jDz10OFTBl7gQ}>*Sy^4lb%=+<0F9D!IfCF5{2__a~qjmGp8@MqA=~ zG|+V3+LqCdNk7As2s7^HXlqwS`|z#vN<i52{JeTv(GP)A?Ga>DKh61Rwu4Qy1s(G#F3a+zmWppn-pF;H$ zsXdVaVBO2;5el~HBx0;b89fPT4RU9SOWd=JUZDuzAY3E8$~cU`|D65Ku*Dhj9#%$g z=7y!_J<3Vdrgs^Ah*ua|3}fcsLw(BVTgj-ar?(wF$a%x}Eu&xYJDOn;mW!w}uS<#N3*CJvu>`Eqy}{h8}p!PkV-bD~_*`j>G8aSbbX@)34K8AleiNN~#c3&pMU z3*=bHN0xC^C_TE73;d`uj%Hdbss4m|JGzWxm~?xc_F+|aOc}=#&}8(kBg3P`aT1R$ z<2a(eEj-l7h$ewN*N!V=0C9i#^lRI@uMH^U_<-=xrUYRTs8AB>nbfO_Z zvkfVup#mM&Pc3dJV<;i_xF_deXc>)6x|PViM0s^%8BLXM+EHRR+M3E3M(F?8dJ8bC zs`q>RwY#vp6@&4fytWd<0;Oa?40If31{fJ;Z~_>yySo#SmX?q-!0ztuj*p%Hwe~*e z!uR+5^>H5e+WYLg$Uv6ni(U-=Txlwx znYq3rY-;ZDsJVcamH1?mo-~2)wUz=}b3DIH$z5V=0V8u<=N1*PX^uR>MiwxNxW%gv z=MeBDS-~U7&MDyB64I%DWR0C$z%zV6+5)a)+Fuwu(GZ2)!0QUQzJy88!}sI$1>BH*$Ka*qc0&O-GVRFQ zopxM_&h*l$h1^)cP0Uq0nq*VhY&R8fGZB$h1^L7`7jO%co?v(zlY0r-Dcn-Pt;GFk z)5?&iKF8?R0&XL!P7IW@n%fGvooV;uel_^RS{IyIc6$MLFgJU_dP88&#vKLRN!T+C zs0v(5BOAt&t)`cP0`6jtCq7!ZG}~PT+)czak4i5*R9(Jp#WO|*V*sMh^qQUQ}Q zob8$|cTZ%YEwjl5Ov!7@6|eQs(uHW6O(|e1bNv|edM#CGK0l@wa35i<>oTgm)!2On zOv`Iu)jR040;XpLX=B@Gq)jhi1_8e|DmXQ?oUs`N%q*4aM*HcR1MHsQ*5oWG-~pnpozhp- ziluIeJy5{H9QO~N$%_AK3kz73;}QnYPToDV78S6VxFac@=8Q})H6=Dw*4nPowzz;L zETgqniN3a^fTej=`8t_NDaq0TmJ!z;);^2wx~zZ)3HiH{Q^lq{TubD^0v=+9R^R}7 zMze|K=|bY~mVW{(uGoX{$3Rg|sWnCxL&UI15pK7G@@ zpIdf+MFEel#Aj2EB)Xe#j~4J)_5&-%O8}5?Gx_&ivlNaviLO0U zz_Y~N_;G7yuyA{}faeIQEeyIKCG6)4c%F#67f^4u-kvYug}gSYOUWsp6g^%j;KdB* z1Biw`q*<}RUM%3Hyu9`n=O~)2j+Y8}ImdMb$fSZMi1u;;uMk(O>jk_)+`Tpi`=GD(Mgec;Wyu9_W1(;v zZx-+taSi!EMnie4fVY|S4-Ga>VP~99W~S;ZN3w4h@J?QpJH4{2(K`jaOFU!jQnX9D zc7N^N0^Vbeo9QXU=h=G&yidgM8ctTn5q`gb5Aup9u9)tWvKXktJ}BVBQsLg*Vsx~8 zSinbFom34H@=*aF6Y(daQ@N?Jj|=#Om~RuAopfnJsft$nCk1@U9KYJ-)P#oI)VM9+ zGotzV;S^tHkgPu|;B(>{`xRsR_U>t)7w`oEKU)<;>jt;j7X^G-`t}iCT{tcbJ!D@N z@D*{9B{!7Q?W+R5E|p`DRvsBNgI{J}7w}Dv%fd@;OcbsAn*zQi?!(GzI&=;xFt&fV zd|SYG%vMV}$U`O{+us%NeO?paK2C#A>R8_w@I#J^-69P+9acXS@FQ`5E%6Uw&kFpp zfS;J*_5gBkcuV!BXTD)S74Sdixq1^i4v^Gu7!M&3StF5s7}<`rX|_PdiV zHrp=+{K^bB(7J}mp8)^0Ukmsx!zBar{==$k?Y9DcC+-N->tcEqq+5d-0sdaVA1vcq zt5aKC{weMzuIJ<*1^mfezw>o*;s|L1{#n3Z`A44C-F{8FU&syauLAyNuJ2L#vAkFR zUBEv?JmuC`ji8s>X8Wgre@n#}>Yic43iywR>z_X!^mnTLSAfm-6}ESgb_yJLf+pt2(TgXY!1jaCeHcdaLRMTh5zT|MT4);u*f_68e82_dAxN=x z;{coFxE_Y&`ZF1&ewEtsplwp&-*BEXhR`So5=(Z#k5uoVG6Qf@QUo<7mG3b1vK z%V>F?)5e)>TL;)C$H(!sxR;M;{yQz#dw@NNWV9vILF$ZfN$n9}PvZWUx_XC*dj{Bxn0`qLM8j>b0DEU2^SVGQ z4_Y^om1cVfXiwY^Urp^GVsug)U>|~h_W2az^>v>B`)1$sVLg+VW9@^BY~KL;5%)A8 z%NgR@P{k*jY5N7(KmUsBU(9XtycXI10XpQk41L6`mL7G70A<9rOc;EIdb9x!U|QW6 zOl62>J0L(IE3o_;>Z}w31S>1@fo$YpAqWr>&yG&N1B)xLz`_7gRwdOB%KKRqASR#@ z=pg|`=PF77;s8lrublbn8P5(|5+KbAOR2hkuw=|>fFeOZ0o(|6%Pj^tFt31IKBvec zJ(vRn97NoWmz0X>SvFIIcfJe)9L!vI^w250yfPjf;1EI@g7(fL{g42MW@Q@1?);+*c1pEXrV0zW? zHajZ7(Ztk77o_Uw06p@`BukbO{xt5)Jp%M3?rEKB^7L@oGeECWb$lJuQ>*m~&^s%3 zfNX(yDd-)bPX--Z-nT-|`1=GnCWFc-Mz7}l9TT80A-})!By-E#`Ua>VsyX5rMeih5 z5uhIt4KkmLyw&sz(4T-ipyk+7ddxiX_*V+)QXQLU{R14!GHQJJ2zqL%skLJR3?QVr zrqu-<3z7nKEDs299C0_)IyrS!St;r}F2M0wMU`HHX2%COfso%Bs_8yN2KOffIFX=l z_fd`9YEKL>kcgu#anj|`U6VI3z)3kSS%bJsGB!9Vz{$k@o?GK1jgmA@4p5mF&vilM z+_EyjDa1wE6>WA(fGVckm`JBax-N2H>GvFYBb{kg0S2+mDm#+ih4S@$53dV@0#q|M zdy_V`QLayMWOaZVqMm@rH?F2vrZGjo<%!ogW-v2+Oz; zk%EuxWR~y*9ui*;-U__~g+R?m3`q()m0-ToDp!bDdWV3koofe>pxM+FB*shGM(iEUMFPH~+ z;jmeAfEMDu!Goy0UPHg~))JtVsAhu#MQNV3S!;li#Qbc?o?WI=BLj>gsFwOx*{A@c ziHKZkPPfqk+L+45gW5IDUsGFv(}}wI@msK$pq?IJO!n<53tmM& zxGbxNR@1|p?6Lrt6YvAd^IcB=}OX8xP~dUjxO=o2|Aq(a4jKE-ad*rm51ouAi#AQF7oEf z+iy(Q1-PDgX(JSaF$?iXRef8`qs4E$Bfy=dDn~LBWQ*My;4VUbS@x!6 z=B@yD6Y#gBYI@(HvvYs@ygR^H=D0zkMvY{m?y}-__s0gfhq=BL9UJP%exxIW0OJUH zVxpp413e~<3ve$nKhxFJDWje#`*v@D@q``0Or*ZfcutLOZQ}z>Anun<1-+Blga8wX z_*IAsn;2jc(|%Msd;9(xn-pL&QFV+KDO^>P15C*PTJbfu+LQoO3AjCN$_lFW+SCB| z5piu`FbFEK_!rfE0j3f6eH%nY0|ok=7GOF-Hyln;+o?wAsy~xP^wR^($g7e!L|Q^W zazD4h83ASz_l@mCp^wuIm>FOeQ9ld4s;GAxV0QkwBrW1bPylMP1I!`rS&&@Vw0@vk z91r0+0q$ppsHH4BtnUvnm(c$qYJa+Go1GhA9&=sq#c^L?^8(B#;(G}S8HdoJ!u$XW z2)ZGm;SBAsCCON13j#bq+|TR?Dt~ce9tg0I*s4_Rc(df?l1t^4*%t;_l-Dd}Wg^&g>#Xd^|EGuQmO3Zh!}wkR~l-RHpo50#2n)kw`v?>Bm(4e&5CT#tR+M74jeJsg1T%;?tX z^SZ#Xj|5mwSk%}!iYi#k1FT@$)2majToK?=BI?>eN)fB<(EyJT@C%7T1!^nnA(8Eb zj|F%zCTkwSdFJ`s#jX9K(h8F|8L?qv?=su3e(@OzfCg?Xi>KgDN z{&Ij<2>FS2;ScNU-I4W5fLEEJPSnvl)SU>g26&B_j-%S@8hb6k>rDDd=*11uUJvjF z5x;3PkF+-eyjdzSyo!z{-VE>-5#KHftr26(6RS#>Q{``-!h zE)lhyi_xv-cLTgfNE2SxiMJAaFTnc*JO%cp3jYu>5Z@2*0nuy&S>V)Z7_cfkl0FFV zVV>(=C8U3fJ~*t5{$w8p_=vgcU}ZC1dbQX`0X`<84tC{sZyyKvglRvbTn^kLJ_+zC zA-`s+c&CftrvW}IVMEAaz~{trf+G{u$7A|Dz!${TFRHKbIQ=5Pm!*$8GAd2u zX!|n2SH%4G&dZB@RPeXI3h*^yHMqmzx+Y3Pz7FsWkf8`Huu9*$NUjhDRt|xKMR;z4%{|@jE!EC~+Wu_?B z{XYTzCG0knv1HSZvws8pSNfVh!JIDVe*tVxHj6s8EW?@ShAHRA4b@rD-LY9Ur9 z;#Xj=9=3XjHL?<uf%A7TRne!K>7 zd26fMAjF0Q9o>5Iy4)=!yq{C+ zW|I(`67_?{Q*N4V8e+5TV@V2m1LFy|S%`K7^~>dwr^@nx>&x1O*qpe2nI_pawt0vx zm~O|kwu?up^yc^j?z(1MgxHd~eis?1w=m?3Z4+W!f_|rwZBmtO8)Ccsdp`g9+?ArvRNF4Z_Qcz%W%6i7 zYaNcA*bY*;-9E$)%=N>a`CYReLhMM;*WNfn`_qmgb}H4f3V)GTB-XN1h@F}1+U~f{ zTv$>U-#NrC#Qo5Btad8>bR!#LSE4#NhLicUYlz*L)KK=43((y{?9OyMHP~%DTuGB< zRq6N{yNB2#`?&0+_O?feJ(=|MQ(0MQdxqGHfQDKQMV&}(uMm3^^PS{HQl5Zp?-1ni&&w#q1kmztVSfP}^+#h1j2n+AzqmllKqN zAuA$Bhy18Rh%zE>fW*?%-Et8LxGcm0#PyS99m!S=QOG`IC^30ODTD|z#CdmGWI>3K zNIQPQQNEA!>D*6e{E09`#9Y7P(PmMIm}&RJ;?yu~BAGx7Ee??o*A(x=YNRopgh=zE zlgKvCT`;8~ilr*)*1Z_wK&EwA^slo6Lmb4EA4Wbc>g=Ep2NO}B+V9=L4i0e$lkL=A z@9s##D{{`cZ^@HuO5Qh`-M5%jbgB>2?2tw^t zwKo&>dR25F$@BV%5JzTJ?C$=tBSUl~qKT>;(7j(b>lmUF0gYCVa{5Z`6rwZJB|>T8 zCEGfO=#mxc*sr|8x`ZfaT1|HDPxVrBT-6X=iHlzPv^wY6PG;FP1hV4l8-@Ko<{d(G zBd%fWJJh;`=$@D2K1>S$_t(0IIEr{Xmh#@c__e&R_?zBQA&$QHV(?Lc-;NH^ zBgeI0GFUJlc5|&qh@Qm#KE!FCP4_T8L-Zo%H^N7z@DS}4qBjw(S}OH&1Exr()_RBN zlh-L3qI|39?$9U1FIqq&e#3_QYlS5SIIJGgIuArjqRfaf) zcsq4YBPCZbC3nttN{A}v`fYU-wO>Yv{;EO@BI@_6ZVFmlO%qic6r!4N*2w-eD6I}r zLqvlv8;xeG2~nHXN3(1`)`m%=ur|ct>_ZacEIup-hZsVnom!Q%P!yO;x8wyjB*akW zy1q}KZza9t#bz2BqK>#GuLG~YJXLF~F2t$C{6g!YCk6Q@r-m3tFn@iJv8NcDB)wrF z>Y1Ts%4ogAtvj@_!n=B%`Vk>cW3JZazA1bs%3_B~t*-W=%T3U&``{?GOP?HRvW@m>u zhq)TTp6(9cWaor9myla&gXxM*i;44pZiw>;i!Ld}uN`9Ng*cypr*raDt7_yA?)(rJ z5Y^91@@E%>xR7bLfvKYt?ZOZjWe8<2(ptDE#KlC^2pSg28;)HZ;u1oBGP2{nvB@q8 zaVcR9>WZ<9@<{otTteBUAuc2CALy&>@6C2uh|8Iy_E4JE(Jl{h1=D`PL4NSA2ytbp zPD!okyhbbb$`Ds&U()7pxLpg-Dr<~**Qt3zBv#BY4M=W(@O6XIH8JM;I-{1Zf! zyF!83rc!OyDbH}bn9ZljwIQx!QAZ)}#NeFJ*`-|<;`$u-UwKcE*N3>Fgi}r|vwyi< zyCKAl#2uZ;T0&|My5p`&+&6}}iDi7ZM=BKNO(Aa1Yg2nDC3;lRAZ`wE3vto=m@#AQ zmJqixsqrHRv%zi+aU0X^n9g(^?Rl=dLa_7l<2LD$`^ZhaJ;WW%)p(UN zoC!B}a$rN;Nz4rb_1AR)=5WoiJ44)6!fETJP(lnzYj=gXJI5!Iy)S>c5@_8WVk~iY zui0mejSX=RlYVFD$0ts`-4kM5{w3?8m|Yj1xi&7uy~H&%BWVgjg`#^yj3**e?^o5# z5MSd%Odz0!%im6&&cX>HCKA)Ykdt0x6GKd5I-AYK&Zvk_T$>bPa*k*F01us6HaWx; z;(kWzsTFQhLQEynjy0;YnTN5Z*;N%%+8Byd(uoyV25Xim_uAMp?F1eLfp@!-zF3xd#K3h{t$DCYKVK1;WgUkhL}e{ z8+*+Vn-^j}Q))09HkVw^`5_h%$&Vj#dRyJwXF-Sun4zDmsyWpj2(ge!RV-d|y)6u} zh=5vN-N>+zd|WIFv6xV{a}8~zCrhsP#UYju^{d$}o@KTq#8P5v2fdi}>EF+mhFF#% zRo*Z8vJeku2&Zivg&7Zqc!)?lewClZq)|F_<(56w9t!a=bN%m}+Ddiz8hbbdkHloNkzHuj#CY}uO6p?o7j+YT-+QaUR@KlJW znX3V(1{B$pPltGhfF@)ghU$GL#Isp`SuKx7dp5*#1U6;U%s`4BJUUpw2q7ec&9z#k0ci?;CCCq2Cw;w8e_cu_XaJ$4Sq>!lDc=eXYd za<~{q^t07(^klh;OJ4j*SWEJR*m-+wpT8P*4 zAMg?q?MI93^$>3m_cTVW?m9+Ttg$yjyh+qA#BOq)@n(p(GK9KXlX)b+72@r@Mjg^* z+EE}d&fX634skWF%t?UX3GprgKgAq`+E#lv#CwF=u?)YO#|>cBZQ#8S?`IzjWlRe_ zpWYAg0U_U@E)>|>2O&NzRl#HK|9WHmFvLg9^~dRu2Ky+)$4qCtp57haW!uLgJ}K4P znf8A6Nr+GLlDgMX49>+e(LN3FSyrR;aO|@XpEK=eM#j*Tt$rTji>x+wi^jP2MTjqn z__^xT*l1sd_=b!4RhU*Q8U=S3GpqH z>e{|1jXBf44e=e*u4_~(;p1G-w8i#ai0^Y;k75aIrDgbih#!diCh02hLx>*`h4`6>zjzO#pB(K=KZp2*pliour^rETdAk?VdFs8OvgtdwK zo{r?x$JUOp4v}p5XY!sjnGB41woZg~vpS`|IdaLwYE`&jk9{lq4ihQT2k7^5jH8| zWMj)MzC?PPMA$UL^`@X)O|fle*rpLS%W=7){`0AF2d$S zHP=-xHumNbw#Wc7!bo{rMA))apS0n45Yl+jwv4b9akl~{>o#FqMcA5%pUe>?LjwoGca7=)U-9Sm%{ZG`Qzny4(JK5rLc`>a&?Xr4S`RuxpH0Y7-6TpuzY*b2LWXs3vH(eI}>-L<%!mz6AZ0R}l8+i;e?tBOCS58j%+jrD zjqM+y12aUjBL`WB2xUz91=Lvz6=e|)AmYZ;Ux4-4(QYc2vj;>dFxS7_-1fw$xAUe_ zh!Eu8Na(L4=UGA`)674R)#V?0-M!a93df=y_IBn zsyCEmG`!_qu>s;@%CdZ_0}On<({H@grkUR zdx2tBiORXrbmJtOpD+OLl8Vno&r zZnItydJ}bo;3GD9$)Z^O zq~qlEjZi_vk6CBMRibpbB0@icB6#wbs)r5YDcdhX|Ljxlii$YXKf&_Mi@v$%_DoL%DJ=}7~v#hYE0RwRZVtMgp*5OkzF*xPL5DXM6IBT0|jlmnp8$O zg`lVN9^^E$v93=N1r2eW1gR+7h7(i3+g+URj38|%BJNBq3x9SKr1bja= zkea}n2(?)$HkO{sY9kCL;OX4?26Id@8ysOs_H`ffHt9lxZ|5NqhGt(^^1(CIhDN9( z;ON1}mX{DEU)OaJPGzoddq1hf$e-@15rz@f*mU5#)P_Z8}$5b%BK(MX;!Y3GaxXA<-aqp!C}cFHto zMmUQZ*+h&Z16@3|rFK??vx$3>AJNEb%h?gmDb+ius%Z!v-`Y75&L!yE)Wu8Jo9)~P z=Ve8?ZA)}PR_S>W&L`+bCqLlG`r_|N;CFt63re-~1;y~gO?E+q3kmum8`an}jQZv@ zCAcucMT9j$m0h}5bnMil+%Af6F)_c2sp^VDsQJkme{5ZQL!llG@f)Cu+ zE{$**Q@*1WRrMq7vIv(G$uILxjKi2Hy!n(IBHHBqt{tjKWfJJn z9W@`!i|pD6*RhO9pm{_u4$yTGt}oS3bs3sLJKd7&Biuk-ty_L8A7D2`xG^uMyNU#| z(y_ZS!cAF)46DS6xGBQTSwY{_b5E!z;p_S+bIE_d6rp#iajr zvf8vG-WB0)VxD9ujN*G*o9x{Y#uE0`(?P!UP3V~*!aYPCg-m*c9=X_<2RNYjL>QOj z9CR&Vp7E1yT!edx`}yHE#;y9^2;&L44QnF3JDhLhBTOKoK^`t^*9j3OW+mvVqI(xA ztVWnbMDtZC|8PpRSp)i6?5gn7gqdD9qAzb@*U}hY0u%OCOly z_)vt0iDjFHb8JF3?!ytdH2vbeg>?2vgyl?o;&sYrp8LH#!iuaMML=z~BEq9g`>kI} z1XO`?@6bmhJeF7Bl=C^U3uyuNScJ!kud+}*-^Z)LJ|5u-=4J#>F`YdT;YlJ|q|_3% zCnG$?q;Gv!D%(1_;!_cxChA+k#}sXjy#d105uVAuE^BD8XCgeCl~YuL8Dv0A;(;{D zo{jKasam?gsB&EF=OR2$RP@g`W(%c}lnFi`;RS+zOsfVBVh{&=A;OEq+-Oa48clMe zHQ8Q_@Dg!PvvNXCUDOCKmmo3ohSZnF|J1yLdJoB@^p7HZOiX(vm7dz{;|QNH?Ru_@*JKJ2?%_G-7uY8eK4q>WJt+Z9 zuumg=mLV&~9&q@f2iRv3KF?|_quUPqJi-@D`^jM-92#jf*%uMMB8l_*IB(v$lo!mn9T zy&6T#zef12^fj-YB%$9T{7%R>MBG3Q>+cc%Ag1~0Du+x%?T-k567kefPR|g!I*@bU zWPe8Zi#dK?7#XaEk`4PS!rxh?+#+hI*xzh_NBD=B8z+AOnkbuHj)#=;|B3J~bJYpw zAkaJNt+9V2{8z%W%c^?vUj&<*&kSAKF{}g`=N4l%qHZYY%b2zER>t+PT8!0+YhKIB zo0@F(7;7-?51uZxw6Qf}tVu)z-GlcG`UZ%x76FY*CHp`P-dbBL#@fWPF32AZZ`h=2 z&si9HfO)sH4P$J?3`afE{LM$JrvrmQ4E{yt9l0ZOa&25mJj5S2~RLUz^*H>QCcZjhg%c!B1TnIetZO0fp5z3}{AuoD#LBtu@DaOvk z)nbatB-7qG#x6uOCuM`^mD6^Ku`2-)+OdrB;xs#Vjj>x^oo47>RwsMr-D2!c+%H2h z%XQ0iO3=H<*dwc!Zn(R{_K2}30Z)xxB@p2obU z$7r7+b+k1g^P_!?eKLg6G_=U}iLoycZJCw(+P*RNW6IAO9r2L8vtNw;vrl-`&7ooZ z{xLcb(Wsw1ro%w%5TlG~zfPT9u^vFvtSrU>Svf{WskZ}S6tbG62FPbYAx1z%E2Fu( zscwYc>&+I#2(#~K=-6ywjEHFsa^Kn^6w^mB;tZ&)X&pYo;ur}5*8*LG=aRVfHcw)t z#NFKLxaSU;#wcdr9&l+e3w5XS6r`}SzON?@2ZfyOD=r_pn7+te(SB!0IvaT_Z zeY^Y?Hu+XA55(w}VJpTCs^cxE#=6Dmp4BHuIZbq6#f8&m-D4a@+>x&&A>-|+7)NI% zIsCj>@O0s;&yJ4KgSguWsUTNvJ!14Epq`g?9ArIX^vb`Jl7NPfHCnG2y@~tFZbj}T zo*c*CG5RpWoeurF_bl&C6^lMGj>#+Wd=Uv?rr9wu`sTQQ{>hQmLhBo&g1DMbPb4Gx zhNy_qkBHm4GFwCXI+7ugBI@>w(Lb-p*YB?q{bL-P<8o+yE-7OgS#Zb37_btjq<|zo zj?aPtF^0=1l*a}#C zVvKA+k{*zi|e?^hQt_3-1ohQVh8X}GBieA_GzCM ztBY|eQ?A$4kC3r3uVr!xavv${)EL9^inWmCj)QME8y2HJ|4Nf^uM-nzf2}^o@a!uI zQYm`YwTFtTF&gsP{JBnTb-EvJh|x&gcd!pH&76(K7$fqs(hpEDk-6NcM#MNR$3>tD znY@$?#M5Fl5!d{5tfz|$GUS?KG-uW7ZlwF2HOFYlFmBaNRc##0mKd$X{KbTq2X2b; zl{3>?V~ot|r1~bU?MKB%#q_wazYxabfl`k9)ob8|=au z7ZGv;s5lAYfys>Kq8Jww7tIf+6RV43T*9Qb#3!o z3!lK;m#>O(b&mTtn^U*9t7BY4+^fe|w{cAA4}eb?zAUeaaV@h%52~8Yx;DmjMARb& zb+5MTVqDL(za&-jX+=M8yecuY^z|`rV2xxkCZt1z$8+!Qc5{qd2&n%QZ8>u^yCuf0#QerUV}0j!{ni+_5p-KY?pl#b zho0{2wivfF*AE$c*+PDNv)vx!4x+AM5^(ZJ;ze|h-4WwX;@Y21Z?-#Q+{KjoPVJCx zc2|tMnRdVAHv-YNSO{_}d3TJl%+=WSlxNf-Ha5mRMEtKv^Nib*?2Ye7+?C9%x~!mvsX4g#suOSv!9OZX>mbD-h>zv32X5AN@4l&HZjH| zLaVe^6sVh%nAekHOlGb>AIs~>gq$2>3K7>@@eOFh&YgdfO^Gp;c($UaIwMN?4D~CT zf2nyjHO74`V(u0&pw_0vn7*?5dl}t9UTtRE^cXWrpN_1f9c+Wm zh%qxS>*7baADd<~W6UBhA_3WgwKglpYyzIlhs$oEyOX%=ft?5nBOWn z)1`p4_s5va4A*BK5Kfz30lwzOn3v;ve@TsXD({2yV$3J**EjdT`7stStp@1;po`WR z59A-ppp&WuWI8Uk2VyMD3hJ)iWD8>~%4%9ZR+jxS7Uv(z%Ew0xo@t9?EGgmATVYES zAaqHLrNsS+ccRrCX=Z7RWqDbDHKax`TfHpCgT(y|Iwt}C{z~fQJUaQHJs9I5mhtPF zjh;AV?098lMh6JkHlC`#0{k?=8|%6!sRhmWF>h<%cx;R zj7KwsTKPS>%Rd_9vHV-72G5fB@)Gn|jK_)l#Y;kOp;mCSJs#r;qMCF*y`1jL6EU77 zqeXquzi}5@`*K2VH#Uq?Yp5OB^ULdZYP>8J>dm+Y)1k^%u+?wsh z7%wsHR!7T7dnv}tc|BTKOG)vHa{h9RSBU$)nxf{$Y6{jVA>%Fil^Cxw%MZ?}nN5bh z8sjyhniwvy>5O3ZT8!88s@+p4+W}sW@kWO8x=mp=SF$#uo%NC=999zudlv@g;$5!*QA~6M1X6*S?JLRaV`KvE2sPS24cMzAU5Y zw#L4W@eKjZUu%7{Gz-3o@huTIAKt}B#*F28FxS3~@m*Gd^dIW&yBOaS(8j>KT4TLz zx4w_@12NxdvLPigvL9mnNKgZCK=TOuF~(0!x+OG?GTNVF{Eun%sg6we5%#|rKND~R z@4^C$)Op?fImR!<{WGp-9a+a!d`Z;NuWF26nUSp`ib8dt_%+6Fc`f;!a4GFuev9!t zaX;Cu!zqoRNYZ|f@kd^o+Ewn|FOK#fG5#d(DMl}2iH(}=&lrCZR-5JGwb}lP@pt~c z-|gH!V1LK>hj_lR)OqEye`5SgR1Gd8XM+z9Hu&Ed|K(Nq+m+6(#r9teo0o6E3~C^~ zDNC>#F-@Lmn3K0!g4Kz*LCf!EOQ-?0dV)1dUpqG`gKdojYnCuB(y82h*G#Y$F+cf| zK5$=H%3+Wm$Yfh9!PEM`faNJRoBt<`YQW{U*B>9eVx0+x>;vyh27g}t? z1RF8!Pbeu{72Ibo2XKo7Tb8O^ zF^jKzDL+iJEfZ`-Ji8+E5$K*bPJLyo1Y747dIFZGx;*yA)(N&LRmh){h0+pse47N@ z=3hCrHa38czBtQbV{MyYyZkG8$dFg3g%o0KmtgxG_cwT6aLM@GKEVzv@dbQV$P4%k z+abY@#Ql(0jNlEa$#zVz6EQz6z53ct33g`M4TvNKiWQ*ivXiUW&IxwOYt~ZXaPjYW z+a`Ud;9Dvrq1WXRic%6V*iT)~nI>PSBo7x3;|PmQLUq);_^L z#C@Aa(a##2uup=0iFul*gJ}ByY_ok6>_^aV7oEt~-7mrZ89?4MTe*LN4g^F?9gngO z3Cfrfm3H?Y3Ca>2kmc`wupN+~z?9#W80xQO=qM@a6%qu5T~|f)GVPWo*kn3&m}x#WPV35Yq(3JeT(^lD#uRXPIR@qlyU*%yM}#XlkQn7avZNlE_T_zyt>|*VEI{ z6?Ra9gPB(Q$p?4W?Sm5>LP+DpDiuoYkOYSk@l(=;oY$rnJ2b&zSw$U2(0Acs2@Yr4 z_1bv{BZ-YCNA2(gM`Y!wQ$NU#NN{9cPKMb&NcSQ;GC@b;nqu!9Q~p^xCg?;^Kio)r z8#!>aP6;{_Q}Ze*5a8>+bAm2J)Cb;I<&N|3Ba_P zOD~5dg#kl?Zp58didP8sLL>2_CuzN}V2A~ZFQ!?y1l_Y5IFX!6y>j@N>Ym^z;-2`O z{goV=AC=(fyfmd;tjmk$k515oxNm#MK`d`Q67(eG>2xHuU9D$=UPQ9qv<$Oe33?OA zmY;-Lv|{3;!;6r6C+NdmjT#;Cjn{wHC&4jU6!AV&ioY+xhb+y?^2~H;FhAY1W$W&a1^!;{ng37!mXEWgz_)M!za0+paL>XuB zlmt~ws>igdr_7(qstE=WQjeSJ2Dc8eK?$n!s=S?-Y-JZ)b%L7g+cDmOw$&u4&5M#D z>CP^BkEu;CcqLA&QVlp?n1d4xA?`?NXO;A@V%YeIsIMQ_q zP9>(cc5cdG^#sZTIG|BCKd$&e5yZHf&~&_LX8 zp55icLbjaNkf1TIEE{=oHyjuK9&1c6g1K6h<#euUBNCjJSI!%U-t&&Te_Dbj;-3D? zInGT9nhE${lan`p+i6bFl9em(+pD~XwIpaIuu5P2+H>xDtTn+%=4wdu=t?#+!KnNT zt$Z;(<$K<*tWgO@GuQtvFzf;PgQMxBYCx4mggaC%;u=Q#1Gc8Yd9wC(f+ zW0>o2DYVM3aVkqrVmT(k8O+L;3i-G#c1D6T^B?g~2p5vh&P;Gtj_XFlcwuq~W@jZh zo4DU2xU@4SS;mVwJHa`nTxZYia{@*1DE+yjMXB-7yV)el^yEMUN*$+^rL7@u`yCo&NEWzc(9ScQT zJ<=6bs48bT%D>Bar@uVG71_7mXrDN}o!J!$t|aan=ltA|g|kFwvHR-E1Xtx>`P+d` zihJ#<1XmOHrvP0KlQGRx=jsI4A79n zbqTJ|zRq0fQV(E6n_Zva2I78s@Fin6B)E}4)@1oy)s=;sv@Y<$jR|gIt|oWjNo96Z zf}69iTb<$Y%?WNHpxKsXfZdYdR;IP_mB|+duQ<0RxQ&onC$TM^mo(dL32rBr{V0`e z*f++k=4es((QZ$02XjRdG;3Jtg5r(@cM|t)2Oq$9Cb+8vP_@eLN^p1fB~9Hj*E-~n z-<@DAaX-S{s+ww?sCjIHdx)xYox63kdlHOeQUiM|`P{S<7?xhB;p#gqj%eh%;ML8wG)Y7j|C`9!@lF4|Rn&3X-YCA=Wd{x!jeF>&z z5E<`{GUA_>U^*c;5p0{&K4-8eks8m(=?P{qS1oPTMQBEXnM}K-k)MtFCf{Q8&CCR| zSVn`|i$a8131;U%kc}4)QmrQX?X=km=H$6DaF?Z=SoD4eos-~x=4wI|fQ`d)e}cJ0 z-01t;taqw1H^DsOq73SjQ;;<;!Tjt~dT^+vxNd%e1w{O_fCJ(jBrZtsKwe)iP>|Kq z0|^$EaI#V5YGVo6`3n;)BA)HF(t2#RMF|!Y({{$_QHv8SVag4tA0mFqJ;d#pwj{w) z=6X78rV~+Fq}b8~%kppB0nSm#ywh-RUY6iN=K9~H@8Mx2tp^i4M9gdak>F7#T^DqqQQ6ux z$17Jnn&2_!YEn2&dRae~;Bg{;S+*zV@9_jr5Ku$tX|%zfNbn@nz6bOXL>7)cnc%6c zjC3>XsRU0m?PgYtg4{pR(+Qr*@rf?Pt{YE#Cc(4BJu8X^fQ&lmZN8sP@EkMLnZtM6 z-=0hGJd@doi={0cy5|$Tkk`stlBi!@v=tB0)w)qG#P zl;CCJ>RBuKs?>~bu$L3OLTnWZm_&h-obbz=vAl ztpslq_eaPHa?0>_f_L(gJZ)V-99dGlli*$Ae)u|5U1T_QN$lMO?-BK9s=Qh#GO+ml z?Z!6!u3em?pYa^aH%pAvC{E;a_GuTHY!HSIo4@ELR6_TVJYpC$O5 zfJU}%WMhkcp5P0n-9YJHG>u#AVm@%bNbn_bKTyN!Y8vdz1YhMP^+U1{k*mh95`0}M z*-a|aUnls6h<;;uT}_L9li*vX)d<=&^I-fo!FL2)oBfS%0#&$pNp|wd?-G2^TtD)| zTP0}Y2Kaq~ABeh!PIfL-DdUqGY=R#%e8t$oWT-ZdatiuCCip4;4GCH#r1HnDTo(M4 z;D32-eskulg71g_CHOhV`CckrX@5@eOJ1AGXGXjvVS2Q*UlRP9f8~iuM5%rFu+ydM_XK}rkS3IJ0sAAtpM=~-Ll2;25B!OTqo&2!~i;~p(dZt;Ez{+r;x(vS4**V+C{ zVDocvnKn&c6rC=aS&G$|*Van0Hp_T=q~=7kt({^WB7S{UFk%AT zWvr88U1Fjx7hw3yHGjZoa27Dy_=4mQ|v#BV6uS`-ogYnYJbF1u zu{(kPKf*2@e7mREBdew_FK1l-d!*Qth-7C>}g9~i06nkfN zkj&?i(Xe-l_8CH*TlvXspJE>(o0U>6=QpJ?_~R@=s-a9%ZLgt8f1qQWrW<)BO}$yQXG)iB~1$jRHEgI9gw215+^H` z!>J`vND<`tL@s%`mYh#EZjd4*?ti;y1uRSvtt=>~HWX)2*&|936ZiW;-^Sq$wQUxs zNb<6NImrNVp(QEO9QR>#l)Kc@6vYxw#mQM2MHN#VnBlZ7po?*uvPklEV2Xo?>o=EQ z&8}QUE9HYy98Ann&Ho8J>-hEur#K}41^uR+4Dp6+hom@^xF%vuy&an3Fs8Ih_ul7V zJ1oWF`A1^6a1Y{>VW}OS;t1k?PP@|F$i-ebBE^wJJ^O{~Q#1@xTaQf9k+24`gNqc_ zF-51m)(IBx4SiK`;dD#UosdQY$6EIk zN97+%({UMD9*Wg=REnc>-1#l$Y&}Rd&ZATGAnxx|68(uG-Xld%f}T9u8i!Cz%6g{g zMa*x*gR1C|%zCBhO-P+DNJQP>=|%Sw6qz#KyA4cnQvO>y3aBSSOHL`@OyVW!q!cGJ z*G~Wg6)<9$ot&aFtGlvmkB+FY$`q$$b?a-&5j-dTloVB2Nv;^`99dP0L8X!;OKvc{ zE8TB{QdASyRPfHyz*mo+h}9`-veI%G;Y<-F>8VLko7dts>Am(|ZHmD;E^1rCUdZ}? zaEc+swTdV?r}x7lDTWg8#3q|c{o2qJb)~PlJ1Od!+zi#FI5o%hN|1|JhOD+zQw$^S zC$6Efjw=4cQq&XD64gle~B*9+hHr2CNv{ zvqy!EPSHldEgW&-XL2^=3QvvNppWpW-f!A?&xhGn#up2TPIm=tH^ zRr!&ibs-!C&D7Oo2E}uGQrZ|gb{9N-2LpSRUc2qt({bVn)2G2=xE|Y%f$ON!+Q=FH5!sCSRuqHb%#rcH%nsTp2AIj$Z6c=PT`?iog zT)lah*##*s%yFlK#_68P)91nz7ZDesRPjP(7p1s3FQ?I_(_IP+?zf9mTteJ$SjUn< zPlM1}yClV>d1-g==C3JK*QF^g%W)Ep_m#s7>18P{&v8GPljz8mT;dd05EmuLYPO-4 zYARQxxH2#6cNwQUXji7Vint%0W2u;SRf?ixbbm-a?*Ae%f<0v>!zII)T>xpKk(@Iy!ew({K#SM9`Cs7}+&>Obhkm5$> z>bLm-6HD>N6gLscNK(O+9O>CjDQ+gN2_WOJ*=|m8OJ2^g>^M=2sIPcSid%DBYtcnN z@v@^`JJ5t=qT(V-KGg8cC(haoJTj2OSz?a6% z6tgm%$`CD{#Ch(_N-;aDkU}8Epqrgy4iPoy;3I8Liu<$t4h%gsw8idEF_(xxSk4$| zb5qP?+K*L5y}Z55OEI62-}P##hSo^o*8CI;2(Chs+EW zVb=>0xZLr{NyTF+9xoNwVKd4Jo*qx}ME)E3S*mx09{%I)i4;#V*AHBe-W3)0WQwPV zXoeXorpca4@pS&ZZh>MLKA<}_O}@t2(fP4-NRXNma5PUCQCQ8B=?J)7b= z;+jIKjy#v*c_u|Tof{j6>2CFWiWdm!mn%E=>S8aXcrhzd$v6hGjC?W0OIZ;rV9c_Y zQoPKxr!`tYGj3;%y`16|g8HQ{biwsXidR=D)67Rtlf9baHG*zx#qN`nRoy^!_nc|3 zrFfmWtK4(_J;C2|b-X-aucvr}WkjP2;7gaaDc&TIEk4F9ciYJ%do#sbIj#z%sJM)m zk+)L3P23NCKVFsX?G*3iCFP_=@uzeRd?&@b#5Gp#EDv-ral9})9wt~&|gqZA)!09`4P zT0c(l2?5tZf2=43$b#5IOGwYjBzmEvn6+Q4c$ z+1Dw)DSby~jGhPMX>9XNif@Vg-GP%%mVkYm;yYql3#RburJSaflP({+Qw?0)9D=qb%wCy`2B4PVA#cwNdMG0{#CiYv3---Ke zq(W2aJo^2f;t#@FZF~vMw?9(+$+SP7Xa+`0V2Ty~Oz{^{Hz>M;Gq4tSsQY!rqGrHf zDgI`z>l{rzIb^~Y*xxDsA+EvVQ*#2Jn*XHumq>P|I`4!3ruZ-a*k3gjn0|)+m%uO?8cLYcguB) zSdWMwJ~DSElDYGstyjeQME&ePa*wm6SxSb|`bBJzTw)5gTUpO5>Q1=M9V4 zh)6a8PPL!gmE!8i?c_#9Y@FA_&;fiRd3@s{Hpy|VBl%`y;1%1Xh)s!W(iw7Oux(nz zW=yLe6m-jaXtN^PWk{tHv0J+$HYegYhH{?Hn-{SKfvi*G#o!?y_*5pjf$=<^o7C$Y_}qIC#)Wv$$xD3BK9bKNf!>h1ng17 zo`l>AlNYQRwr3H0mFl8ZMpG57#)jBlMeI%3H+@ju=?q0wYkL>bKKt5iJmRuZaDL`TA-5=$O0v7tw*BBiif% zLLF^+UYSRt?NCG+b9Fw~Hq=>J5eH<+eL8fo1Bxgx>8Qxx%Ka^#adxRq=OsjiA_A82 z6v(NUk@Paw925}}_vAc`Ojiqwi1L#D-M|+BpL|gfaj7Ji!f=a=NQh_wmyv9GG&)1d zq=+>CUVLL8>2aE+MHGo^yviz^;gc1MI500di7X(+t)>@gJFtj@vWm%_p#O})b)4ga zia404UsV;n;vQVYAq3R+N_tvq9btzQacK6T(=ILVNvWL!7tnrFL`?J&3qA zdNI3phuPMnh@Qm#0vp9k@d)Q`u4fUwvf^?{KExfZTr9nc=uJE$W+z#1vED`WA?SwJ zx#}gc>1N`0+CD`b!(0t-du~9K6WTFF^d;nv0$%v3waE$ZTSNs>w_;`gIL|7I=$BWl zvz0tUg|*>@L;3*yis)aerFOKOzOa`5MI1|1b5%*PLX90;!~g=W=hyJgc`d~X*OKZ6 z6mcB!Rj#mV9K(z{Ij$F99#_Qi`L}u)OIeldFgw186NrmGDtlMh2}PWk7js&W61-E? za$*q!iMt-1|HwSveg+nC5)rkIUh>HGIH`z}vm#XX;^t;27g3piG})ox1|~U|Izl=fmI#b_xP^6yL(Fo>b*zP1_%pUtOTjk$c3bYB#i*6 zySsZSP^>N5;*<(?cXxMp`>r)}&V~2+{r!9IHLtT~&fJkbGkf-IDWEzpsjE7bjr2xu z)dke#_@t%d89|s*3CiDU3aBN%+%`0sQlFXGeq38Xk-2`d<$R5ix~y2hFoJ&WxD86@ zqRxgDFg*VO&6G65^%OC@fI8wL=yti}t1F;BE5~O`&O3u2xAIC{U%&~(^;13+o!IFU z3K+4h(uI^DPGs9B+lT@hh`Z%DTy1J7U}RoUk_*}R%zS9BjVz$Cg!36d&$!ZiY%HK@ z8BPm3ooqaNn+j+q?uLWH9@Zn-sQeUhBCNT96Pc^NP_dxiPAs4$OLwB`v9%P?%CwqA zcX>1;Xf2?PfT*MoUE8-6(9UGG1lbk->JqYZ?FEb??tazZKeaSz8je-z7(!AUmir1#}P=;dNnbE4HPhfRjoEM;2)+N5f-!xGmsh z!hVWr6Rt2Qc5(ry5Y&p@UB4z_ZULtf^0Pjys$Q1Et#)bwrxA7ARTTqnoL0c;OlKQ` zJgn1ZK{6=Gj_mXT&d76pKizJ?yZlsg%4ZaCCUdjZPj17`EZ{66C9;?IglUwto>jov z#MQhCdRwDoe>=N?bMm5kxsjbYL(JPb1)NLVcW+dYQFhqpa|<{xFPy(nNUP$!0?yBH z=@5);CMTqbIOi8|0rBPLhx6dBDSBzRpnwaR>)Nf8e4brcz(sj^iNeM6&v#zNq!)Hk z0T*Y#;%3r?W+r}d0heU;P)${eNS73FX>?=#~B>CZZ>*>k7C&1A4mQ zy}p1O2#AO%VuRgKz>Q4%Gq1dXah_`J#sY34CQ_i&T>3s>XmSzYO$FRcTm#aDR3>M~ zHy3bAsXCfp-BQ4ZciP^6#9Xp&`uuUvr5)ln!XGS5iNd-)1I%n#KWla6# z0;Ukok6y_H$m&liU@B3+)b#9;o!wIlxQn1??z_k1aoH4DVuZ1?Pfa&=U_%Y7*1nGs?^a5ru*9(s+la(!&yL8Sd zU}jdGVtABv)Mgeii@2zsk>EKBvkI7<7391v;p};pxY-5VOWa9uYwg|w?#oL_b|+N{ zxq7^>fH}mo{Y>w;Uf{tt@)VgG%U0S3*eFIJ1c^dS(lam-R+SA9?d=`U%*q3G_E&` zM+DdzeSuB5Qpo+{w!ydG`ia@Z*2*ryA4hPXz4aFOQB8o3!=KncSO1-!^yKVuDb^od)*OQnjt z$-wKS0$wJf#z>-KFBkC2vJw>Z+A9UTnpNVxfxcS6YXr2eovFTe!uMJMuV)oe6Qsso zFW?QP-P~s@*-6IVDB#WPYdv$cdKXr27Vs8PKev1#p!iT4&uVz0^VWT z4{~b<1#|Bd@GcQ`v75~7?cD<2BarPQa-pSP*9AFYu*C5IiudNWQv0HSFPWREpZV8z&!2u-z*o%i^v`9!h$_GZe4Rmh z&(YHRx`1y8Wt+CRTc`AE-xTmIad!eKNYhOFwt(-5WJ=af_1(GRv+oM{KC6N(4{zyY z3*{2w`vQK*tCk+Gm{Hyu?1ut=B(Af$yqf0iRIjri3;2nch?UC7ZT3?EKQryAhHR8f z7Rey|T);1cMH6(QRZB+?1^i0Dcan~8IVHaq@Eak2^bcW6c-8)`fZwz4meTtmJ>eGc zNA?}HA@wj~e-!X1AvIy?*rk`+p9TEIv<`Bz5B669e>3S>fYx@#{2&$oUBEvC-6-8j zVZ;pkr+|NnsD+d+^QQf80soc0;|0?-`@aHgo-Z}DCH*eZu11TN_eEPHz?w{F z9hgPYsT5!)+nNE^%5h2lB&M7E$XT{lfVK15wYKCILGh{lb${&u>*TrOGikT1)tTk4 z6JTBD`WdEC4?VZrx&hY9f5#s@lw{GCZM^{N6W^Te%mcG=v+~-a`YR=!^#g3cG8(&{ zRjsrtXdl^V8wA*pV7A-L}`c})|^g7d|I=J&Y_d6NK}GFJn+H{ICTrU5o%T8*h{7|xq*Tir<8EWqXjMOC!= zqBwW+09z37^EiNx@mwq*UU#<$uq89p2&wc^C0pSY7@jP^R>U2pG7JJKb*lhd6LB4M zk_L{hLZW*PcSa3x*qMOe z>RK5lr>MAcd~C3t1MI>aE!9febLL$dQzrw0mvW0J{;-f0+9p2W+qJqWt3tEP<>v~*j!M}R$v>Bm79dd~oR<@I@HRLtUh z+bck4;_4vJyP6TL);U0zyd>kAx*#L;_hnrI>`h!9AIhEQMB6*SK6ybYXUY*cAD(QV z0Q(a6{h)1^NmGS zbxS?LFhE4mZ{Pg}bm#kO6d)#~U*T5W-cW6EfP{#fPH(m?J=KMl1V~FIc|Z)eG(Z^< z|GS(=z1NooIC$CDaviP{cZwYx;1J@D{QW$6&vPPwdUOa-o_{3{k8i{-@>F?%uEhPi zYb=hY`o4S%wOZEz-I$?Cqh2?8zit7#=QT)Tcm*G9`Ty2EKn3xvjZ`g@# zEmh5})*}G&Z?&{^8qDQg2?2T%&$eU*p>{`owk`Gy&@2B+N;*2qrQ6*rz@a(ruO42! ze`tWih>N}MIoJ*h&^s?hOK;a>zHD0W0DW@YkCPm*kF!1j`Vtq}^U2Tp2I!X;bJ{Tc zaawj*zX1J-Ylgd&dyTLD0S?cLO3siA`wtH=fVf7XwOAZs0|HcLpAN0;H)ue&3abn- zF#lBN1!Zg0M!nw#1{jp#)V!&wX(!op+p|Fd1{3$h)Yx=ll?@IsB(K3;pg4FWcN-Gm z2;%Bazn0;4M1UhpA9B66*^vQ`BBIt+(6^r*72xP)70ElExY4`q=m5tMSBE>vxiXL8 zV*(soDyr84?U#Hd%jkL=8sK=Q{IX&23wP5#K0s9o zl!GNoGOQ{Gs| z{$b@dEWmK4Ji#}&c2H(X4MwU)3=dGp46kp~tzX~e%;D++)R$`QU)3Ou)A|4>5X<*u zcVVPF%1#I{g194TNi6m3L67K}ZqA4R4W+M~FEe_u<<8d-U?g$hDz3kg^$ZOv*U=*b zH0ITL+ZfFXEoUh97;lXMn)2#oWFn;*>4-E1XeO?Ks%A|itvSGn1T+SHDWeV0!jvB+ z-b}SbTLQG^RmsDzmv!A|tpVDI`&pp6_-tzn&`!klP^Tr?U`lSp(NIoi?EywHS3k{2 zV6{y)D!^z0{>LcyP~3*m0mcv$5m1G9SUuI`>9`?42SK+z^J&dG0-VIOr=~h;e!EaS zCj~f}sOsmlSkIH}Usm3Df7Gnia%C!Iq5W#0TrgwySe0B17SGX-+b)-+shC(aCT)^Z<_@1VrcF9auwiy(fU7d3Qw>%5TkWaqt~^%+O7?7U6ur?=DGmam+Eo;zqM6eAK(U}BCeV`MzgRR0^FDZ zRCH*k%r(GG1k~zE^2yW_xGBKRr6Pxsj&BZd3jyD4G9J1i$nAqBb%xy%;MS~yrDMCx z$m7-kw-M2>jVd-Upjd$0nf3(6xe+T|(_yy<7)#jqv9gZbMy-tva0fBJ3GqSO@$}@- z?+7rCxF4m8F_hR#-+f$w@ykkk-Se3|D#izxKzuoRr?)6wU`W7|Y(juLnd=u^Z-!gC zGr+{WxMT_A*fVcODPy6D0Vd@?;*CbQVbLUdQh>=huID#-<&-zq$pNMi*E9|4HPEI6 zn3@%nAvmYk-REp-fV;9{Lx;87T>{&W?v$DMO6e^Z+w*T>Vj`t*O*fn-O3pam^0BO!l&w0cJ7nj|qhWuB8Qj zo735v6<~H&bZGaA{x&)H4ytD!4x*kgcJdjnu_O(~r0|6c+;1@+R zWtL5C9W(`dFu+5EH&?y>cyxj%jgVdxI3Dxtp#TrFj9-tOQ-v}d$FbCl&Ln#{0H?$+ zA&F3ByGv(Bwlu&a#QnVY8E%gRc$8^%X%NY>!yXOr7y)g^^pPg5Bzr8t<5?NX{OLI6 z@c>T{aO+cU<<-d<{Lv=@JV{);h#YcLIqJy(Ph|+{zCZOsp9=6a5iN{iZO!&{fM=NW z%b$^eBoTckz_Y}%<-eFrxm=UXvu6W5N8I(;yX+PJBy&DREq*S*^UPhJ74zLnH|mmZ zu{|H)h5XBjva0r1C#_Yof-eMkk-2I%_pS;$3V1QVOGGp(Y*711dnv%n1YDE!k<@;9 z3$>R6yh7aH;w1j0nxLnlR|34s9KTo5nIMDI^JIKAz-vT3$<VM%q`ev7EuxxRnxs&68{q9ysUEz@ zF<5Io(!iku;6A z_XB)D&=28|rltn_Ai#(D=b9!7jwbP0^TPliWw?7=aCZ&f?>`FgF>&8``gQ#{z$aO{ z6T`{dCjmZX+OHH^N6G&K`IAore3n(`W>X5KlpEP+0Y1-h@p06N;+eJ3J`eB(am_66 z+GNMR2=FC=r*4VEBek0&^2De!j?Y98G6Vgyf6_i8qdw@TP`2D5-F#99GpG>PW z^~F*4XMn%5I_Nx$q~C0R1^Am#<_%GAuFIdk&h?S@G@e<12l$62^=tf+3e@&bfPabj zJ&*%Gl_hCu<2vd^Te*tWMHdX$4PFf#J%tEYC!g*KaRi47X`L;rc z6^W}q^k-0OD~4DpFUKvwon6x@zE~;5$~m4hn%uc<XGftA<#Oh-c&JFqo&&Y9Ur9lyzg!z@GgE*yziZ zRM%6tY|RjB5pfhMD`dTd&0x3J3bA&MPkclkJJjtZwswehN;Oa(&}!?1Shs}qrej50 zH^h4Rw>hoN_7t7z%i9T}5w;}DzV6;aZ{OQ?TZ+$6-N#5IgOK-#&gHx02_>C;+j4{jD>a{`-d zq`5=zDMzQJq^Ry$&|NAv53xn|Q6H)3*%l$TB#@EUVs|B!S&AR!EkkU@Tt6=@?F@`W z2MZy#CgyhnZab9iP-wouwhplkaZM{_1Jng;wQWLdOGv}i$(avs8)CasedR5@Dc9O| zA+|4JJO-(;W!s0?ftWv8823Z6=MLK;#EwMWFFQ9GY$d}i+KwT1BJTR&XNg_rB6EAP z?G$3?{41SnG%BUk=w917#4gKlDY`57F54xH0rLDzw4Y6B>(m6iQo;Io8 z>=vREQ9r$dsZ<+c_bmPJSzKDXhuDK@*E0XxE@+P1ekR)Phm^3Y(RGT|cu0tHVi`T&?Y4FKc`Fam zmAG4oc?U{9Q#g+DFVr=~jLala4urqN!l^$Kw)AsuCn zRrPjgh{KrF@b<2f7MC3sqIXu8E_t=Iess=`dxz*lTr}5E#m%@+h`w2x<)~*HqF?qM zsniF7(dp1HM1SILsPqsZjTCRlGT&|Ba_rnc#NpYu-0EAJn(29%UOw&c5CclTQ9j59 zgs5cN_eVBPqpUK-z`S}r-bpt^L2o7dkTYnxj~^If5X)riy}fOClMeYoAqHoa(Mdp! zl&A-X7(z(X%~v3A5v{A#kPt^K`w_+8lFFX6`(%EkcfI@Vh!97XeuORu#Ob95XUj?)}*sd z>9FHM49$x4?ANElhK4vkE3%_sJa&ADDng!ANc=S8Coa_J4hu1S*~dI8iZ(n% z9U-@vydALLrt3n~6L(wa^8S3hh@(El3C#5kZfR1qrdm58#E7hRIi(&slFkxBG~~5w zUKEd1yJ$m*k)`kH7L4!q!);`UMuHldq25zxt2KsbTD}6=m63j|DMWLQYljzKOxN|+ z9O6Xc{$ya--xEW$7K z6RkbOsO2i-+V{uxs1T!x>*__1qx7Lj>koI^A01*${(%Jkb4gz0kZeqd4&vHXhEfvJ zY8@d?BH-tm4`Z|d=5^qt5GUuK^SO_5jJI<` zoJZUZx`ayi*?A$(FMZnHIMU7!aRC9}56WV7X}KW8g?V*e-Hbaf$>G8f7ZLYu993V% zpB6`RQHYE4;@+@b?i6O&#UU;s?weV~XabjnxRijO7iXIzLcKJ^WhGSi9Vg7XEX3u@ zP!0t>{IuESA+8{r4XC`K`1oj7gt(Hp-+@WGQ@DFkHGsUj+?P(`$+Ez%3~?39WW?OZ zt_pE=R+p?PDEstec6EqrvT`(;Jj|{Macx%4`J81$2VMmk`7FeB#FslDrFWrs2nFzV zms7hg#PuxW*1atG71&!k0iN=%4{-x?-Sp_;xV2Pc_bOVeP~scnHezmRwhXh|Lfl>| zB7rZj>$is(OUzTK(-*R_A@0b&sv6N`cZ3+nWKMH#GnztIqvxe9V82Fe257- z?r-jHBeV%2?#yv#oXvAh7ri?}OeF3HM{i3uF~p?2Bz>9i9xjG)x=ji(nYbrQzNPWy zT1wcHLrfv;$!`c{A5%h1CE(W*ozlD4!Koqc$}8om&3ocR?yNKIt`K)G!^zOIS+bqD zJH$Q2)vR(K-sGMT(}?&v)9sM7F)hS&Vt)AgRLLRg^bj)$Ia2Vi5#A)#Z+bIA%w(=_ zo6a%qF*8HVBB;5PD>IuFVs@!k`k?&3I()Am4!2U$iBkbBnIgCQPb z%5MeThuA|Q9%fogse6$t$-j6!9AYU^%}FnE_KY`3{l29k9?3ohO|a~d5RYc*9^63e z(GZU@?MA|BMv|VSH}zPE$BAnqx>F09jDCkb9^#2oS@N`UJThP6*$__>_rpWZi~ba8 zB+D03CyRJ8#8b@G0Pt~DQGlKb@iY-p8$+qP0PjzScqXqxT2qS2A~&=$)|g|@gm^a3 z)k!LyPbr1Tu9)K65YI6;n@ssy<*7xH$8#Z`&+%+!Q)_XmJs;u);%-LBm{Zf`g%B?i z(a4e0b&7U1_F{;a2x`}9q5qqgLcGkRsH#afCwn=>D+Jun>ab)a969~6S3DWOeyA~e;@`Df`68DW{v?rNUeHh{+V!m1A z=DlxcR{BwhkF&x<$a^{8svn2=gqYt>I04*ED47lMDM7WLPe}tRdf2BSJ}VU)-qciE z-BGm9LVQk8jg$t3eIDWqrad{3-}Iq*jrARYQk;9pan3e!jgL zqS5NlA%4k=N<(V~o3@ZA&MzT;CGL+FnjPD(A$}_rq@E_1ppe>2DLe3{!U z9#Z@fzMyiMEavX`cZh#jW@io(>5^Aw*2>lHcxU|r--B3w*(L9v5dX5ghMk86)sOAp z5dRVJ6RoQ&w?gjYt@d9CTi{2mq1Yi$VP+9lAmm!)bqOe~%yl2wA~D=6L|Bn!JmbQL zKWf?Wg0^CWm5BNw;j^YQC0Z%M$^}RtGn-klB?V&(}O0@i^r6c2^H;=FdGyN1(MY~2Sy|zV!Es3fNo!jee%LrRB z>3^!+$;&Hks|Z^YR7VC4@TTKiN7#mtYpOqY1?efxm ztzpMJZEP1|d*XiR`!_If%=Qs>AmYbN!I_G-Lxdgkj~Us6dyy>err3@Vb|Nl1qzwXn zYVH(aX9E7Whsn%W`}xihb|LD=iT0c|%^kK&gk6dGUn#HVTbAt_VK+h|s-a%^4s1Q?&7ca#z7h5#?g^OwIT_eN+uME-_9yJ8n~kU)#)qN(BOFiyn~Qw=;V>Q$ z;lRA&O!UZ2Z?PR1;UMA~w=S(MHFi*hLSBwr8b{1q`xPPt#QikTPDnadL4=T)KTSyK zQ!I=S5%KGTbIqq>3PW-=@+d;gTt98}`$|_gafF1BAD_%dOTi?P2r2RG{!y&rlczMq z(+FjRy=<1-CIeFBH|DYk2Q$n4^zyC`{L(x)!XeD{O?8~tArZ=Rgwdg>1XmuRD-qWg znb1k{Dwl*^BXrAamMxZSt};ic)ed9XY%15h`+A@00TKH-n*mD+fx84~=jbaW^nJv*|ZDQ%I8z&tVaI=efFP$@F|0Z`|bjXyDa5LLcU4Gu9xD z*FF*Y5)#3*)Q_mLz7hH{?MbkY7d2SF2>l7VBTF?==YX`N`(DXMto4s@ILmliVL!A4 z6f?+A*x?ZdFxO88xqW$rpH8{(fC!buHIbDS0|rwWyE4MSyrh0hhp{5G4va7;D@nt) zVzJo4J1V#q^A!{b(SWQ3!L zc}}IWs?Lsza5RC8aOU%3pgYGDJ37KK#QlcGL%DV|*+Dxd!m-Or^IFAG(dGQu2*>5P zL`@P&lj*hNA`H!OsaVe>n;{p!Ln9oY<4#~rdb#)#8gh-! zysSDx4RJplHBGX_u8B}vf`-udW}VeWDCS@5rJj>WAKUY+7-3kBdtFQ~mK_#hc#eA? zd458NN2nvNX6a>@o^B)56VT6(%(%7s2qzG7Y(%$ic0z;^Ogakj_A;JP)AeeKjfl{| zTsP`Ymd;UM%&TrggptHOK{9H9b8$5?LStT-j@`J1y#t!Y2u)dGayL#PyVjZ_G!xXk zm6MGe-soO3nj@S@)HSZWubmj7g-P{iWEEowSWARf0`4teo4NSXdAzu&`_eqq>xJ7m ztTjR#OZw$bH3u$t$r;)rv}ZMT=_banJ;JCAkoHBRjfyauKxsh4k4imEx|$Pgbc8X? z%{W&E;dM;7_)+~kRX`{p9uuL1Wjsli*VH(h9P5a15>YplylrvQ_l(O)5l$|Z9@(B5 zlbjsk6r%3PXsH@)r$jh4|5|4j&o~My=GmzcPAh%gql&(2#mAi%;dG)J#=ZG8aC(F@ zm~=vfMmr`1&otcz^ofYA1=K2ZeEK*mY(aw%= z4#BKTlbxHaITWCt6XDz(7r}ZzfAj3z2Zv#5dQ!cim! zy-=MW;eur~O>^@t?VAfCTu59UY@oi_g%K_)72~#`BT*;)MG-E}E7z-&?m_dpY5RB$ z7e}~+xoQrrYufoRNjC`*E+wV~<6NXJiR{t{ml5*UnBmm>s+H=mZ0#;fk!na)x4+Bkn6ATuI1tbkw77v@0WARYLkUal5-J!qr4H|5VpL z!mf^R4by(Z=}#-gYa(1rz!Oln*$}u8VLz5jRK9|3bDtu8(j7 zagAUtr5ZOxxH0>%OB;;=8|=miHxW?_`m}QwzbV4ac|~3cks@}!|KA+p7UF(~Lqk(_ z(Qb)wD~84k&0Tiw_6TE{qXs(_OG>ZkTW+|G zjc`YXb9TLrkyzY2B8(%R5fG1C<}SMxj*Bq9R9ma~U3p_2VdEoAAgtFNjkk+(lry<>&N<*qH@89D81zbQRK${j}I&t-LxO_8Ak1!)I=O6U6F6P*b2s1OhORWoA+U$0PnGt3Y_jK1* z(`>UM%qHO4sk2aq=+m5DDi@Z`j&Lt?^KHVt2id(5?jyJ}+d$%zs)SdH@v2m0CwRq^ z?Sa@5Zs~SkggGqlN42HM0IqW)%q8M!0#q68SABx)Sms8UM?B~0xQ40N-eL11%qOf) zI|0S~2n(3jwRSI#%VN5jqa>fo8Ve#UWQOmIi_9%s1#yvgbN5&nVG(oH4lOU99*ZI@ z&MK}_1d+uN?q}N5emVWrwb}g3?0{O*k7`PMFwtJnpr4b$>?z-WO;B^n92zerz z{e|{Ogh%t-{Dsh&!qBO~VtX{gW6agr(EU(*EW+bV`3`Yiw2!gJBRoOKQI?#-$xcLL z_e6vzmsKk{nKrz;_*W{gPeynu|0>sT=B(RO5uPTlsiAP8)}D^=4AX84&96+_q5XYL zO!O3cCc?9MUHT2V4ph*gXCpk9<9ble!id{*5uPXRr$8cz=Oet37gY14PAr!rFGP5e zxF;XF{G?^4cA6I>yhPX&@c_Ca8eP?4FGYBn;BxD8IV~@HIl?Q<^~>bslaH}iBD|Ux z_Z04p86?e~YOh9kjk%(UrDIRv)v?%NuSIyBm>Xw*N@-!uv)3cMK|I?(YRN%r9lsIb zO`={>Lq+slfydsA@D?+C;~B|sv@WJ^MR=Q_pVlt=kG&n?9YUH2`XR2ccOtyYbVfrm zbX-O&fk}Zm|{Gwev0sO2_?tE3pK^4KS%h5sHbB7 z9<5;Qmk7U>Dy3(a;o3HTjqn>mH^7Rg!|M&7L1)=-5q>XKOR1!M6|~y#5&j^mZI|)s z&*nqk9})f}l5?!|F7EXI{*3TfUac3DQ(VaVIP(Cab?e7Tx5YjNB{~-G( z!oN)FCweJ(V2k}5;lI2ty}zAJzE_g!|03AJ|Cv**U`e6na>in;z+AU`k!E|^>Go!)SYoTk zSc9NHW%>HtWNXA&Gp|-2UU|hPuQSEgjImaZ>jV%NJ%hBlR*bcY`%Q0DQ-`e`W1SLk zC~qz6#8{VrW@2dHL4CSXlCW-!^$4l=3^Uef>%~}~X%TG~XMxt62cWGVV}tC&rSzW0 z_g~u}#)gFaueDGFw_%Kp2>4Uo$%Dv>=rX@ijE$M0$>!b5Hjc3glWw$f)<}x0o5a{O z$Ni*w|74rS*eu5w6`&;PMd8WV+&%-oeDmLxjzKAh_NMe z)sU9q)wX4ft(f$5N!EyL@K!OlCgf*Q3tpr{PGIX8+YtAi-E;5GwoQy}31r)|Q*-0- zorhH0HpX_#a;0M@5|WY$FUPiBjP050dF?)QCdii%D!_2?w~w&{bKKAC#_nAUPq!Un z>_}WgyXkGKQuNJXaRYoNTukomj^8SBJIKsbyQ|FIAml?4H*-h3*s=+3qp+ z$jkf5)Ttwvb6P}u#MqO$uAiRkb)n*H&lr0V_cPMFYGCmQ+bc$ALhf*Aq4GuN7+vy; zd3-z~JqwyxWEFRbv3FjvKWHY>QQdgkJH|f$7r&c>vrmkDiMy_g7N@Z`_mHIrY_8&Q z6kG2bV?UPB7!PtTX!nb;e_ok4Wb=2E{bL+J-0$}T7}CzYpdS$9K%#!JJE0GE-~(eE zL{PmN+PzP?9TcO$w4Xu0Nt$i&GVXPUtt`gD#C5w>&Eli;NSa_D5~G}$I`{BY4q$nVu1u@?Dym@D6s>EFZl!8^(`dh2jP501 z6z#~m$EYCSDWO6-=2j7-2O-y64LI$aN*)BxB%#ux%zDP? zMLc8M_{dz;`so$p&l>pVK~Mg!CtT{ZDd`uZKXG-MvT&K@TK^b_ zXApH_dBIc^jjr#Tdw>XA${S(_HV39XXN%V+>+e z#+dL`#mV{x#TcB|%cGJHn3CTuvB5Eh5O+)8Gep_|WVgAHo7s>UM=)1y9$I;1pRWCS z+YvF2B$N%`vH+#pguO=SR68=pQ7j|6p_v+exbWrns2E3QRnb{Qi`?lP9pe~6ZaZUC z5DEZ}iE%8E|JmVXBk7O8V`Ci0TsN{pq}D9+@8e<&CGI(vzD+HoDKX=IJ2b}egf(QN z=s@lG7*$OA$&$LSbd0KER1hBnu4H*hvf(l6a$FKKk)@ns*2SnN z?$;m<)}^LgAL9gKT7!F$k+TzGj9^;i8trN$Vl?D6<=f{B^7RcdMiTeKbV55FU^&Vd z8KaS~rD4me`0K9xITerv+f3ZQc*1O(J{ubjNeQg2T6N9$~wlx=pde*>w4^VcU}@ZZ#dQw z<0R&aUb;|@ds2*(^B}v?+TDqBW{k6l z`iW_8bpe^qig7kEzi|)XJHy#A&LQ9iKqn)h$)+c`1LCGNKkIU?h3=BR+Kbz_{z zEcG7U``dXj&Sz3HRFt|Hr}6w47ZB1kQoWfPM0P=p3p0cp@qN5JTo~gbBEEIqWyo4* z7sa@km|9oO_?vBZag0j{=%*?Ml-ngSE@jfsmU~Wf`oVT-jLV3-W3;Ze#V(6+In&wf zaSggnYNGo)#V(I=1#>+~^+wl$huak~uFNXnI5*jqF|Nuh@H>BIcH(q7uZnRsbNwLp zAj^AojB5yF?c%#B`>5DR*TlG%cs>qfdasRf9TClHx?`6vd;9;{buq3d>}PdYJI$|a zigtaB8?vu?f1#^GyCKGnM10G^2Q_N*#<(dfB-Q*LwLa5SVx5l_Ft8}R3vPHWs#_dG>Y*EfGJ)YZRj3uUF=+?Wu zveL%JxPyS2r^wcdA9_cOafGs8n8iz!zg>@uF`l?@WS{mrJ#yFD_!twi3fxXuTeJx= z?j+>f?KGI#nmc1m%xWcD(q7}V6iH!syJ?(6Z93-=lSkUz81r)6yUr6gFwy44m`^-gfX=u`M;G@N zML(GzV*zv3*0TM6>v|jxx*fc@i22WOci730rlY+OPLl0@Uff+)6y7^5OCw>Zz+7g=7*2Ocr>q8 z5$YtA$flHs&!aIOTlUpdcAk3>>Fu!?j}zAz_3BY!kH>g|NxvosQ(vDe?>qJz5ka*S8B*J8Y$f2kRfnzKaOug7?U_;S7Q)@&NQY4%2pH<>FksO)uAg}oW$ zt^Y0Ulxev2%^<11731yy&Gk&8v-7aGW4yy$QD`Ub0<&n6_)d&>31vj2uv6j#C)m3& z-XpI0r?(R)`nC6ByiY7Ms+X~f({1~oeZ%{GdOyYo%W9oYnwIg{eET5Ahs3iDx2l8M zl(qI@jE@NVbyH7c*;@N3#>e^hUJC0d$v%$pNsfDgnP_XSeG=nS;u<76k7%|}V|tzI_(sbK;KA=J%Aee;(rtBA$rp+k-Myd8GUz#+O+I3=Bq}FWywuzKroz zUV+%-d+e(iUuPw~e1HQhf#laQzA07Q-bkyq2EB`Z6XRRL;*n1tWZ%a4jwzi~+^aGv zt$i2c`@BkBo)_}OCyQX;$M}J`NUXkDW*R@l_>q8bd@bE4cx$>JWBinVKaomDdLtp1 zX+OpInYbT)9lfIGpJV(&&{1FM0H7$8pYWyVml(h1Re4bjX_mM7Ut|212%-ziSaLS&8eJ+Gl1s5G5*VI(0(hW=^1n<^f+V`3|s%(V>D>CVuOa{tUOt2CGRXYWewsL}1 zvahKA&NFV61gmC1v%65QnqV~o+1t0S_YyHm$9%N}t24(RSR*M8C;6?OU=3pW(V^Y? zb+71VYb02ch@U&E3Gz+3*49k07C|>uQrS?Iyo}gd3DzdAPIx2YwG*t97ZmS8w@Cc$ zdA3f1bxXAl@ans^Zi4j)>c`1hG>jT)>m^t}|C}4RoclZ3^ZE%kAnvELhwK3BY=ZMhP}1?mMIxQr*5bPOu34L|d#}T`@|eZJuBY;%caGCI@ee1Y721y#R|( zr(DomCfJI&+Ax%yXoGE)U~2-R>E0c-b%Je}at-jOtKWb9)6F&sw#`27(L-(owoR~I zUYv)t3p^?@k669=wq1hlnd{o?MTwJm_TO*YC)k0wi1IM%-0YBG$Gj3>OpobKcJjzs zwqt^wm@9g$9N25%pn(;(Q-YoIdc_m--H8{kX|{8MU5L9K+zFl84sU5g=TH21mgV$F zV|teayRxK4jK=u%*u?w(t_gM{=GVqRDv<1!pc4U63KeIhQqU>E?nJzNUOTUjM;*qy zC)k4-eygG=np=NMbDiyxV9yNh%so~XE{dbEXM(-*ilvHqkL{J9bB2%*NG#SlK^G$V zT+_VL1;n#13HBzQuaqKhh^@AFf_(^zD*3?OYWpPEmuY`RkWniyGIYt1U_YYjAddnX zAMTf6e**dqvU+l=r^sS0wts>Hh^yoEaxc|r2P8O& zc07@vz!FPF-4!+*DI%L4uHg>!8S6wv>y>4TT9J;+_J@rpik_-Dt4; zck|$m62$pe`D?CT7vcm7aktINlU|Y_Wm+R3D$m>mrwPjPuXP&ucaSrzEWyFV-G~Ccpeu2a=O}8uNXptZLAUH%Ixj3AXx$QY z&%e#y%z2NWYTXl55Z{R3?xkM3OUg1mtBM3Y^3OaY@1==75`eh+dQ3CpEFnQprqy~K z8=UE$33?Gx>nq!elqdH}a3}#csM;ab`q?fM-b2T#fy|G@^Q&&4;_)< zNM`x5qF#$st%lo?363JFHY^>>fKuE&j!JMeAx9#U;uj2DXhRbmPu!1H4Rwtbo%r|! zRe53Urdo#D_^J|A=Xk!?(ni#(6V&9m&OmN#kDNu>bWMU<;_5CBKsi5=Npfw1B2m}) zycVxt!DlTiCK$%tZ1UQx$;MD3n_xIWO-YyX=6V~RppIz`Pv?<(QLjr-p8;JsrX#FA z!3hMin-;D3+(saI)HJHZ`iIRE5{zJ(Y+|Q5CG~q57;i*^2I9U6?ahpQ&EvNr!N}|v zhK}S@g^f(mn13yfVIp_)yZH*-n4pQcpX07A?G%afUfqaB`%7g)VD_W_|^n%c~QwfsZL7<@h)pi&`#V9 zgq{FtPD_D?R|?FZ1KSgfVj1lL^h3}@E!0s7M(4FrLxBgN{QpsGn_vuaKQvwW9?09a zjY-f!(D#@wIi&ntYaIzrBI>ESmTHdl+>qd8LYg*)&z{_BCnq?CfEyJjtLH4yK?$2E zkD;d|IF-4Y^}e+gW9-xfr!np3%juAihG&xzKP|!O#9bG)5mEEkDA)=4 zZIKIbonQCZ1qm)>u3AAMAi3ZR6I?{VPlODZX|rV)CAc`R!}DLxn<*Q@n~7bV;F7G4 zT~BPM=k7}qTuLCL|3!R9@pt}96I_-RY-b3ITDvU4<)wn+WjMgH(7imt6~r}uOUITs z*3vl4u1IhtF?SmF7*O7)!mdnk6%mbSXYvwuRf4OTR>v7j)~-%)4U<_bGKa3*nXXB2 zZH{M;fUX1NQ~$`#T2x&+q~_r&$c*==@xf*S~E%j|NR-H_l$raU^c9?h-g<^;D8@QcHVIc`aCD-qvqzPai&yEVaWrBW4C zju7>PI5}n0|rLhU_$cs9bkhqis??^Ci87^%IF|7C5 zxCG;KT*u%2q!OJx;}cBC@$97HX0q5OB)F4!MqBdQC#n+9G>2ldI}=P~uJ7QG`i2oU zF~Ov~9`6Cwy9u9^U~;Ks|6)tKO-?X{h&t1S=I~UWw&9PPB+Y^NccM*CFoXEUY~Rwc8i@bHIL$~fllhw6rj`-(!b3`#nP3(% zPbu_(;#{iFN-&$C=(?HPyviG`)tro7mNsmw-Irhvajk}9 z8ryA7g1Joky_BqcQ6>yFH^IE@W0JsPjsx4x%j~=a^K+c`7&3Ws(cR}KSU}v}Wpr*x zZ0vPL7D@|-av`U4Oc~FD1PfWxPyV5b`@S&2A|jqqs%c^nQTM2|D8XXFYG<*w$rdNL zKl^TgIGm#0pI`|Qw+s8T%KOFOyg6TFawD-M!2>Mg=EUbZ?#&)Z@L>L}5IIm#du6qt zql%sl?7;*Nv5cRC{tO@>*6E=H4-@p1&C8G+Am|F|*TcgJ_+i!+I@_mrVwou{P4Ea| zKNVc$bhg$kE#yZMJW5<$?Ao=PJ(}RLyl%f_)nd>)!A*2*m@OXkJ zi21=BCRcAyBzQ8fLvQyylw=aa_9?)~lL?+;Ziz%?eWlnCPbGMoc-B=uBk4}}bb@E{ z!jn0s(q@u&_%jKfCGH#2PFrcl%6m4!bHuV6CF3vB&VWqda|xc$tC0B)^?vo&o=@-s zas3|MY%z4V-l$$k@M2zA+~r(y{WHmXyqMr6;_4)uJD1znO9@^sm895KZw7P7%DtT6 zl^oXqYFfm-yprHm;-1Evn`*sS@zn&c5!L=puXt5s?6m~16L18TD}ri~dxl>NcdEUf z;0>1XYmOX>MCmgfgC{koHxj(bTuo@VrgnQX!COqKoBey|QN-R#@OEB9zI`||AEzkw zc7k`ZPv|+WwY6PD_fCR$32Nat)pWGky9wT7I-5rC;Y6`g-b?U)R?hh}em}tnOlzk2 zS~QRUEVK_2e3*ah)n#~9<=*yTf{%#1j!ouh%C?`UoNit`ct1+;F>}2r!K*+xS+;$g z;1g!JGw)RUB*CY7Uz^$>$?Qs6Ia`vO+ll5pWp`~nr@0Gs8=nk zt{)QoNKhovrMkg>Oz=}yhMX_$_|?Im68uci%_jxBPM?{+NbTnYzYxzTU;3`UB>0tx zC}HW?zU}sFg5R?A!)Ni;?6(BJm+}V;u-_B>!L(?67$qik_D6z0O9e)@*q;ghV%m*~ zr+J?E+||VH&bGf2{LNf7e)qkOvA+}i!=&FPchn3|6D(&9{{}IW$ z<3w6ce*IqpTby%5HFfPZBX|?X3WVIx=VZmF6HbYqnpQ}$B6Gc*wzZu%5Bf8vq`ARX zOtBJkJel-wZ;=3gr4%a@^FPb5pSf%Ol~b%j+%samTC1vRY?TzNmOkg*p-7FiRa2}+ zO#K+@Wj?E=Se;0=snK6IBYAMsT|LDbghlc_dfFN()?`X!(pd*JV+_(6Z;G`D`mLo{ zQ)6qTSew9d!|e1KvVN|eVx3a)ih(_BofPX5P?P(UjC9>vH^q8{d}GM>W-eIQOR+v- z5yYYG^o6s2iVc|dQ$%4Ha>DYj)sc5~$G03#$e*tRLQBbxPV0Uunv6ZY*=Y@g#2_whuc zG-|qSpJE5%qJSY?ZHE*)GPT^c!m~>}BcCG2*^Vi8Vs5sfF~nj`o$ZujXJVQ(##`uN zJEz!%>Fhqa?A_leqTV(Fe~yDfVSrzt(9tJ?`wA zVm|`euT3SFEKY8g?U!PI;(mh}sOVz*r#K+1YU$Vt*a0aHWLiC@N5qCEK3X1_;-C!T zy+PrU?VuEe>?^LG8Y`p-m{tQQ>1IHbAVo+ZYk+s5Je@~om?Fw?x@YEzAtz3=ElLp+ zcN6a=9n0&1#VHcz`Z4b>Z#7jkDoawNd0ld$CiCU-6l$g^%JRCFckJLNzbwVU%=JS+ zJ=UTfoZ=87e(ox|+94^*nfAZdhss&b7h-veu0%BF z?gU*Yv=dOW$tzrb#CA_n!CXhFwe%=kk)lUlI_J5?1j!};Bq0xR_l|ZFL6!v;3jEL^i9!^fFHh2k@ZW_pXqEWogZ+i17vHj ze~QDI>-$AB8=4u)75L#P1`u}JQbnZ=NKwh8pMvhrgtNM6l_>@iRp)#4?J=NNUwGd% z15*sjJ|5bAfDKA9m`T5H^S(+yAauE#VhBOMcl558b)^kSaRf0>3awPHv?Ed+nIRn% z@$!myWQwDRXqfh-mTiiovs%FSe0Q20o#Gf`{^yEge4xBzQXEUrZ9@}zFUb7Hksu@q za3T>qHpOu)#|EO^RB=no6pcau#Y+6bU#Im0+ZpVpv{Z z&e7=FGAzaLQhj{hk{dK`g2PkP<;6uZv{7?z#OqSj6Za!jF-A^Ai&mfF1cJ+TEH{c! z*sBv#j3`z0ki=V(h~8}@QZx|v)7Y)5QR?muDMscs`Gw>~OJ1FDWQxYTCJK3Fs>X1o zOROuC481OrD)D^9p3UIO?PtEoZ`g%SKLm*olBbBUb=E(ikAE<2|K)$ zW}LO8XeI7v6m-eZXss#Q2x-)5*hK#xZ7JIGZ`~DvzbN&r_7tN^1*>R}HY&wv0)AC! z7bO4OYNJz(A?hc$r^F5}eCU`I9eJ(Uvpk=k=2%CHlZgA}nF$lT+d(?2v6E7qyexMn zh1?S7=Js1Br#OYVzBk2&YMPXslH%0-XQcKc8IbtRQ&XHqT%^=VJ|9j?ae9`1Skc)} zPjLp*8imf)a*}dJiZcmh+lF(8_|R0UX-lYlpPiZFEaqyh@H7>pe^!dKi8xyKv+iT# zo}J>H9M?EXuq1KRIVsL1?un4WWQOUUd~S;KN}&88sOIxhoS)a=DS+Wk_;`JOiVKMQ z_1cHp3wA+@3yElR*kz1enBt-=pUd+uYWiK2;^Mp}`JB_T6$5f{ic7MRGTDQ?VjH4KZn zSp7pV&5P{D6gM$f-IVeYeW*}>iPEc^Qrt{j-Jw=EN3_juPH_t%%}n>fc1wy|vkyt0 zUROgucWa8xc3Xni;Ycj2h&<}(x7tT z2FL*1kzyQS&C}2!qsnWfUf^whiUmYnry1Ux*0o-oxgf>D z9QVS+DU<*%w1p`aW%aUQycOG`6pM+tQ<*O~t+qJD{aKOB;mG|dmgJRbrAz&E9EEvH zQanK1bzwO%qv(kH*8?dY%<7>OTSm_hrg(^mMx_gFDeHI`J(S{MLfJa@CTFeoa0>1P zd9Nn=_c<=0r70dE?uU9HJ@q$G5}V>tV#|%A4$v%Mojsc3u{>9TEAqQKc6pdi;R=5& z#pC(!OyT;c`@N-8sp0o{iYJJ>hBh{l{co@*Qanj$ISHd@wmE4Oko$f1$rMlJ)#+6B zXZdV}M!);(d?d)lxi5NK1Mk6`!9?@m&6;`~j1u`6V@W zQ#?=H4_i6ivO9s*^C?~+no%PCg;S5^g%mFm6WP_$)4RQx;w7flwHn5Y<1S$@rFfZ; zXpQO=G8cL|#VbVo`szQRUyoh`EA5pOuV!D;Spi@FTkX{puMzS~P8TaKxmmn+y_Vv2 z;+{ufd>FToJM8roZ{)@OgRAF(-bnE#akcUAcHRKrOz{@ezIQeB%0<Xm6!>o2YLT z^+u#@WN)Wrdkq<4(Z`yk)-Y1}O9?>+y z-cRuXlgo)&bP{IN(BxxY?`b;kKTPovbNzztBO&}pDLy9R+bg9k zfgh*%gkZKA({C~lh=t@|K1uOuj{Eg0Daw8JX^PK?YiKw%wf0$x&$Du}yQ4pWHm4W) zd5SNHt3OSnI_!%SUoxrR9_mD#>hqT=z9Q&{l`_TQe6VV^uTp$X)Dunj@;>FLu&+~m zL(I>gJNXzMr@_8S@hxFBrgL#jvwfT5yDZ(vxJmY1itm|LBj^{yzEAN3lN$6cRE(fN zHN}qv{7>;AT6@BeDSjg6C#%@bGuD1e@iU?220GgromYpSQ~bhQ{m9VD{`O0XUzzly zT)`NBEqnv}HN|fP-6-opo7Q&^@$|RfQv6Ollh$} z>*v7zlj2`u8U#ipP~1WLH^qO1{1nuyUrrM8UkbZFCo{VCFPfEM1tP93UXfn10Oui% ztltV{SdqDSc$l3VJJgMl7^%duu>UTCR$B&>Dd3j|7$CkVHN(GdJRhW zyDI^}Lu=PRO@8MtAixtdZd^;EvnjNVsd1 zVNK$0jFwkv@s?C;mSHXCYUw)R`9fQ(3~LkdG|-c-F6m=t?J}%GOe|jANw!WI)@4c* zk@7lf>y}|Xrn8-pFFIl-c>P(g4C@p3CyxQ45W_N!#F zw=Ba}M0O_PcSE*as#DH|0+IjgUvR53Y@OFEajlfBr1ida8MYy=#t)^)&9*7SwoLoM zqlg+Un*s%;d5%{^E1nBghop}9Q5T^JwRtqh%rJF1(+C$L4um7ed)=Dxjq< zTvM$}8TQU`z8^WWDH%NPU50(KYH7?fh8F1zy;g>Ovud5i7Nr6EmSI0ao@z*hwqF_c z&+DTVxK{urOR#?#4j`UO24!q5UYQhrKp76qzwq~8QOs03unY$g_lwYZQK+(m%1|KY z=1MnpIz^`n2vy+R@-LJjV6JaWC9T_oGK8fn`fDAxSy+aMm>*?DjO(zd3^5@$Hr@w` z<8m!7LsBX_psJZNyrc|iUR2km++ZUuLm6>xP>Lj1R)&L_6p6?h#j|Gzm*J2MY;UHi zu5u_A9uOcGHc+Dc|o_hVDe&K=AVB1ltRp z3B4}--OEr>`i5?Z>EVi}Rz(?lWHt91SkcFNlmU4iP9M=NTe?p8e`LJ{n3qNO|34~r zceg$!_;eU|FKNd17zHDQN(kUe<*-1UpJcU76)OT3dc?s0oZ>R-bV9-12ET#o1dkp_T= zJ|f$KF?RzZ4J@(ToSNI?@W4p>fRz(a+GFti6zqNWiL`I^i;h+^ARXuSjkF(F(De?5ZsnW-nVyecVMK0$~4c&*Smuv z9ZWimX2ywdaHK;3N@_J?n7y01Ln0jt=!p-yn%pQ3jWnpN$3nllL6Ht4U9w7xAGR<- z^oEzjYs;7)Kn;y29>U4di!9Zd7%J<2^k%oYUj<rc+v(@9NW%dF0j4Uvde~>$-0(f^-#8iTiBlwLp5~yrMJynm4)C^K? z2s~CY0?m^(NNMQSgxGQJ8vc_Vdz`DGGB=4M87o$H7+8r&~WzkB?R_vZ3Y8y#s3x%P1! zKMZkWB8??&JxhaL!`MjUs^5otgThOYwvLN*6uF__13CteL_7YdNJm${;GXUMMB1|P z|8_@5I;P5nKZW>*3sxZ9$3!}o+>)7TZX{l7GgS20NXJz_3bceD`6php_dG7r@l~#g z_DmJ{CVLe3XTkB2P9V41KU@L0t3gCgh;$;jEv>!-dtfJbVx*I*f_7;)50)nSKPl45 z;NigPXf}Zhag2<|IyurQ)i0{YmIYLON~BY3I7gUS(x5)=PK|V0h1(s&Osr=^VNZ*6 z`eNL^OddY=PLFg3xSzY=b~enQT|?)(Ga{Wyu8qBU-bK!dhHs>^z``CUJnoPV)9{US z_TuWN@zfVy;?9orUvQi320Idw21hyvB+xSN`l)==L$*8FofGNYsvb`xp>a1No;f$t zd5du`n?Q<&*WO6ygWCvqZE7Cc;?9qB0YJG++8bI3>UKe-3&Ctt_Crb8ZkHEE`X7+B zD`QL3uKz{42*l4}&=Rs|C91~)>UL5HXFy99+0xK67x~*u>T@vZiD%ZcS zkQ=xMJ1#GcbXoPC;C$P7qnq4ikuC?fqj%v+ya{=2GIx2TD;Af&9^Aikx+@}G2_7b) zyMOW`G+U&r00SlKfsgmAB3%t&z4TA=Gu_pZt|^P`+jBr&;jW2vEkGbx18_y&=B|x2 z9;oD=!q!1l#WEcq={j-(doT*&4X?)y?z%|VmsNOP(gYxD$si8TRyQHi4P}`z zje~s*lN%yU1hN6Q`;&LvYSm4QGzmP+Ak&X(qni|IGMEvpv|pW@9O*`q)~_9RJmlzO zcXl^MngU`(h7gT|-IPdE%MvW~1xRM6M!E^a&#ze=nZDjMZhJRHx*6P>8pJm@N4ljd z7zn|{&O2CYw?w+Ns&WeAvB~b%NYg;V*tPRi(B`H^nhq2w?U1oXjC317xt4;`ubB!2%5qzz+sU<#_skD)w@12zWEh(fIAVb3za!Etu+R#0 z&QS5573oeO`zpZ`*q(PrnhoGT5*U^xANXcRnp5T4qW6K<{R8XusKd>PG?!fK5(*`4 zZf>NzNSDOUq{yCHySpOY4Q?Op*}W%A>+VSN0K#fPpw!AXL*g50K4{t8A=ve}`H>dX z3Stu7Vv3$_L8N;?eVci5GJA0I&{Gb~J(2Du*SDg2#+!=X@V${>^U4t_>RXu=cVDE1 zU|~TcAw)xgmYCw{!bqLugl&Wu%;qD|RO^hiXmQo1M~J)`Q|?8P?ypttg^$;{`y)L7 z78D*?R(^xt4dr|w(t}kc6LI|*d`;fy9*p!5csbpk)$-?nzYe*FB0XIFs$6^6cg}YY zM|uRj9JI#veMY%QB0X9aorL*@nS$O0y?Qj#W8h)MjjA8%9*guifGwe2cRkKM9_a~^ zHl1C$Ww<9IJz3Rb?{XGmj78v{jPz862M-@~4@&%0q^H5dkhOJ~%aS(tbfjkh?Hg_8 zgE!K%Bu$ll38yxTz1ut+>A9-zaNtkEB<3dfT%_m0ZC`he-?N3sspliT01|q0*kOmc z7b3j~5Ej)ydttOa@M5HwYQ;K6jdCwVdKtiaIlP5M`*NgLNQVI=j6HI@S0cSytEq0R znS4WiUXAn`sGlEGWth$6-{uuW(A0OYMS7jwKt%kF%lp6dj`R+Yjp-mRzwbnPx2kFaBE-qW z;+eoB%e#@@0}t#>+T7BNl`dD~_aeOy?5Ejmq27=50qKgWBB#8~eGutGFl$9OM31B0 zhmk(26=EZrqq&bFeGC>_h7VTu)5noM0kXO~#~-|n`y|q*q)XCDSR=0zJKud8>9Yzq z&1;LIWezVsi}ZPg`v|)*3&e_XpGW!v+@`-06Q|F&a}k2KhG9cc5Xx?TbaG`!3S= zCE~+x4tL*2`T@lE4(Ab2NB`IT5a~y7`#}GGx%)BFPgSw7buGH!UGAqyKUcU93IgT0 z4O^L?BmGjtgBA@-X^#6P(y!p5p#v~o@yqhpNWX#l8xpS>oDX)1E+Y)HV{gOF+;5S7 zr%V`v?mWi+9_bH&lIl-7iD^P2-dQTv(qLhI znLbSLG`w`IWq<=2048onn_DJU7eGH$VGM$-txK$BD?A8{*)}|VEgNe&@G$(nEf(!^ zv6cr3EvO%C)^Be4SSx^q71*m~7>!yX){2WO`fBWMw(Mx9< z+{Ups0rlUk7$@_1U|*i@Hi@-qRlmK7n^SP}BDra-%_=;YE#jLKne%3`HV3z{7&M@+ zm-%JbJk}OKVVFl_I)d%)IJZTtEkVl#T8d1Nz{c7N*p|Y8BTSOIRjjQ6YKzmH^5LV= zZ5?YHa2vV4#Q|=cSlg1cl`sHpE@pk(SbqZX{qhRG|L0lvPqDTmH*5sN9q1@Exb0$X z4`{Q~AMXfm`&c`Wwr?ZMY#B+EHZR!OA=Zvn)t=#F9h>46ErUMq7;7hTttoj^D@M?6 zr&v3Kghgpy4Olcg$Ldi!k$-=s z(4Pkz3#2s_Li_Jn|DlXcxaqav1vl2N0M^lNSev_DW9>%Tw=3)h)5fjr;C73(JGs_r zUiL<`jN|OvJ=Pv&mG(4;``cJiRYiz=5XAQ^Xs#Ghthg+W$_)=9ajXQu)<#pXKjvo)@td|GIXfx z8Eem~mPzn!Rg|<~iM?m6y=vtVpKfU#z_;X=~xA;h0?Q z9jia-uy!#5Sx^eA`o|hje#0D95>tLatbtX@Dd?k^5g7qN-N0D;fZHq}WShtTGu%G0 z_5};HV1Pv);X1u~@8z9ojLI+`(CaHym&!w89SRGeG94VR)>j#Z^o&zLD0?bWO1i2e(1%+F+J3hsQdi1X{dS z-x0A!RKGM$9$W6lZjFdF5qN?gX7+AsXmBUSI;pBH=mVHZ^GtVAtdqe*FO64fg{Ykz z>l8rWr*LwIfelgEPKkADt@1Y0A3rtLX&^Q+=%Y8e(_)=o{k~+D!eIo_n(a=Hbq2ZN zlg$J$s2?%Roe}HIvWmJ^==+(m&LVBYf%!1zOlQS98z8I`-(}QsWBnJ*cGCcyu-jJn zZ>)2G{P31sI&0z%cTTKx!EHp~{igC-eQvDtK>Rp*DW#t>Z}{v(zL-4oyjbT`#?!&` zk%*s<9@zP@E&%&KOWu4Th1t#><|BH1IfQ=az zp7rjcSQjt;A*_by0;af&V_gCs`ptV1P88fFu`VsKu3pQ9eROH8%fNyh2sM}1CZz1% zk@aPeaEXAswa{tyk}A@|sxJmOnNgv3Y1ytKa?C#u^VEs7hPADI&6- z#>cv@EKMut6QvM4JRZ2Oi*-Ht5*I~ca{G|>3;ZF+yRExE)&$Cg&+pkdbZ9FoClg}b zu((2VSHNL~*z<;16KjRd3D_{+v?j)y1ZX2ZsEr${JyK4JH5n|tiQ$T?eK?G+k*~?I zZX_enr2akKjj^VX4m)pv#ciGvYify%Kw}OfGBwssASDS1A;%%u?xt8bgWF)hgEseX zlO3 z)^tGMh+u4Gku&DG>9J;j+n(AUg>38mj94>kzwg~R5)W2wZf3080K>W*jR8EjmD^(7 zUc=gsXtM9z9_tP;Tlj-|)pZ}}?ua!DAdC>AsTMaY)}0`BOmyuUxjSRcCK-nG*xlUh zSaZtk?YG<3&51R)Og4_}aC2kbMbh`f$J6k~=M;BWth>SezyvXz9jj)gWj0MgVdCys z^C%Pg&>o^x&5Jc3%nx_?-IC@l^J6U_H>?9rrNJCcJ`B);Soc&v3nbGV>fH%(HxEAd z#JackGcUC!-juy(-Wvv2QCjrkg`a75@V%{I?fvV2QIBqxP0vHhYK&%IAb@s+g zj_I|h><42#1a1?B8HIZ&*25&j$}~Uf^cLQi&1$ss;aHE5YxCSIyh1$^>(LV7L(>qy zKN{;XkaF_oo2@(wJOo>d^>~RxE)b(z*g!mqae1Ny+b%%i=ZRQPmNoB!o(}ig zCu2QTl`QuK3bk|GQ?Z_|@Nf>AcEfD=3U&Q(n%w`r22LEVZ#`+4N+%Og_n~1%h8kvOnt5{!?YwdvpB)%p}sb~YcuVZ}! z9!6~-7d#YuV|@!0C^~`n+RS|7+gRU~zo*{$CjRqkLEpvt9z1XcoaJ16>rK|x=Dv^h z135OeJ^S@@Kg9ZxWEguw;+S}rNNBNs0uA5l7;F}p?e3>oKLdsd8Djya0+;i)h(51Y4E_^K&414@HN#U?qE$&+qwsV$ z&aIkgHPTBoqr8PJ!at*1Ez#=a`mqV)9UPCWo@kA-7F-ZExHS^3NjkJ6wV-8dCRz(5 zj9$kmrq#RZSS!)mRfQ&=GGhhvaI$uyb--<*_AKi94CJ9=okZ&bc_L~g-%ehe>o8b> zh_0JxJ<8bDQLmn=>yy{H^%AWQ7QQ^Pei-I7<{NqaL>mD6u1w-R&w|6BV5^V?` z)+k=a;BngAhKV);v{CBbw||}6DAC5GZ8|J^D{;>fZ31BJ9nDfVbLLGFZCaKYMC8H| zZqr1Y0r(CW4L3^81(_K(mpkEf-z?GQl<~tK&Xn+&YZtp2Zu3N2kXsx6n|RwYKiyj- z+7jH47Cp2(!Ip`(s*3V53O%KC3U>RePR1VJCJM5 z4gwlzb%rRmx(g%!O*05mdKCyMX(NfJrcQSdJ&7pqSuM#=_3*lIYKr@h!IDK*CV;YZ~T?M0EgR zxi!Ev*Soqz-GQu!V<^!*kw{wmI>&Ffy;GtdqY}Ee_+(PWEOb#+&y{ zv}gHy?sWBT&qRBX_B}9dICE)_hwdCE6RnI>5W|I0)6=iTZ#LD#eDzYx=gkLlPYdZ2cZZxL0>* zqCuqn)Y_V#>;@$|tSkZJ-{=lYR8P8Wqisp^U1&}S%;$G~qQO;e#jcwq#3a|#+~7n* z%DS@p!QAlJ*q2Hkw{fm8+3WEMl)C6SY=lJQ0Lep@GhPSim7O4!GO3 zCTgQh*hY;bd1f5KvTRG#4r;r6#~pWe?TI=_+Q$cDZ|6D^jV`nI$$PlbiN=uhD+4<~ zw2H$5;M^SUj!$#~ zY2V^0h|}h|6B3RQ?7&u+^QE=w#C6mf``2MRIbYQ^0JT`ZtborzAR+ zWLPukOc|$w=&V#EIW^H~;5p+%db9SQt0)?$@@l1wdr-vKdMCSm9 z0|*rXGrmOD)aK4fbS@cTkC|1URdQ~k^8iD~eG6x}^Aep8=38DmV6xN5ouB9e@QRiY zfy38(L81$RZ8~vP%~Q;UiT+pp-kzk5&QInv{$HYtz->Uy2lz#aE+!d1Js?=VT%70< zuy801HEz>glIYUK#k|&lyEM^dVAjIEt;3L^92FEKE=zQIiIO|Mn%5iR(nn#1XCegK^ z*1wj+o7}aD#*?)E)uOkKPjnqv_yF&%tu0LrW8HO$t_Srah+6qLcYUG>0DcAnq43(y zZbG6PD%=NeX2x#4?*?~6qKV+vk6lohb`uj#A|0lhP>??S%cMk;0mHPySWJTG-32+F zoajbyPi>6b^X4bU;Vtpna$}+?)o*dFh?o}z7zC?R5={jU^9A$VHquQ^bQ6$`!k~0t zcT=L9Nru52VNYc@C%Oe>H41c&=ZZ~WF&-k!L)$HhZY9UYp&JS#t?t%D(*VL+Mva_f z9r6kZnU-ie8NM&P2SG9HQGS-2o@fSmn9v@%n~`W{RW3*=?J;M%o0;e~aNlQ(W8`h_ zVKyftBqR7QDlD_yZHaEDjLqM|@Kn3N-Ja+UFh5gAwcz>TjzqHn?1SEc(yT;xlD6It z$osoH6U`>++i8ctIiW(i#m!DMr^3SoTkGb!If>?iTm7Bm1!X^S2Q+k_P z@`QIKx|>`Z+(Gb2BO2V@iRP6^=lEV79If*b%?I&KFt)-@QL~<#pJ+jadp?YsXTj4g zNOTW)*p`&F!{(ku_kxA>gvbm1vIci=qWb{t;|p(Q46k?hC0Yn#pMnUEg7{#~$!sl5 z)Cpd8!d_s)9l{&Nxz0q3$h9@ptA&`hRJ|zC{Xn52Z(TnGSNjd_{zMOe+b2zy2v_|; zq6f>8ygp5Up@%ExE$_iZ4^_DDmmjyu?x92vgZrI=x|Mr4(IZtk8-+PE&78VElIT%z z8-<#>=%a}q1GCBLI*QQvBbZ;Su#AC=qa#3 zMf*XXdBI0;@>HUyfvv92@pv|RI?*$vt*Zm-hg#^xXA(UNQcg_pBlT>e=fM2r+73Xg z#l*$#xkS&GzaA18#OD*e0OIGs)*6pYom1e@mklCv;7R+>|RXt61d+d zVb1LJ)dtD#fL`w4UP|;bWo*eKd2}x)dZnt0VqA*D_4buSuY#9*86LTkr@xx$H8N~* z5yo%iC~uDRTB6qhtFs0ZWbYH<^+ay~`~I4niWy8R(pmRLqBp^9^f(Ddx;GQOMcUf5 z{SL>vw-UWwW)qU4zk55;JEQ{%@?2Zv*znr$PNH|o2`j9(#bS6j(R(F=&t)?;crVfW zAhuvT$M+rCIIP~ipXdXiK-Y1?g%u84?}J1ig8J6l8<4GgbF%YcqK_)v3^UAd&ZyT% zi9W7y_-eL!;154e^a;41yTFjz_@ljuC!qQ6lSH4AYv0Cd!iW9fY3b8MpH+2nr{ERO zZWgz?&k}tOZX+|Isl|Ps=nIlIaJ+6byDt)bN!r%ZCnU4;(kr^8%h5I*lH&2w?w~#_^SOhQW1QO z`#sSgWl5wnW?uJ4B6n}Kc88dSidQUisg?q^FLDtZ?UqWlbeTpauih=4YMI*41`w*o z9*1x|o2m3Q*Y^AFs+=g07NkRd7GqVc}L*Tjqw?mi`R4YO2*JW5Y7So;+4dwK{2=2=yD_ zR!_A?Sv6NI3k%%t-`>|qwdUfgYhHb+bg|djHB+rs{+1PVlmDaz4qYqN+TdZ6x0ve6 z+Nst73Ek~z#xoVFaNZrWTPM}JWclsYZtsY&+9Tb%sn!Dx#29z^rt`dBs`bIbD6pX| zcBO@KSU=SU;C}o13$eY$Rbn=`L8=XFHI2mf6PGa?rrHS18VFZmyyZrzHU_aNIwa_8 zx{Xt90^~nesYg$T9&D0o)AGkm9ky9+(^Q+)ki5Qil-n%T=4Ew*V5{&4={8TbMOg?F zZjLIqMXD{!LY?FD5lA21mZ`P^3d?6CR|r&0+*YZ!1`G{>hp;nv9tt^Ir`iU5Y1*83 zxNTBxTdNJnINV6KP4y?BCFoi>nV@baMNPF`RV~*Ddp3iPAw^BKJ$RVCf+rfceX1Qm zjA+4wVtKnmsvT=ZFc)oeJEqzRBs6?XBf$e1)SXi83}_9(CHapwBTdG|^Z2|9a?9m6iT~hs-wC`28y&HA6#egu+{W;ZNs=AGN zH=|FaDef<+{tE61&UhT-UGM&y>Te*{s{!pO;kdu0`g>UfJN9~f==?p^Kg!Cy@(1hF z>;3;D)jw+`+XuIea{o;Aud<|d$qo-x-)FdgrTTYS5+h!7Ui$A;{{ivMH`de?56y|d zjc`|!-G5T;T9#)^!O*&0Q|(sOY|GGW3idOTsmM^G06=`H4xkueK)it$GCy1_5rYc(ZGcHv? zG@9F`(VuDVz*GlSIL8_MT=2quP^yE$ZK?<`$fWRT$jia04ylS;uc!EG?sA8uIuzXc z*g4*MbZDwUCD64y2Rs*N9R?7(g3d$(ks%LDRSy=H6dHN;em~Wx8Vu^m20DvKdxe;j5$Y?$?m2aq&;Fm2{1%hJu7o5YBDn7y^N~p{a&}+SX!x zCb?m$hLbL-_TrN_h*XBBY9iNv-rl|#aTt@ETvMvU!NceK*A?#YR7U{V>9AjScSNcY zwd{dSgWZT!BWv|wvSzybrj;`?RWo=PniiyjaDC0GTEKjZyzmT?#WOJ-H*s!Ds!>%< zrl4r{{x@^i9+m3I>Q@zWas$Gu;9KO#RISyo%vZg+ak+`r(weFbJoIDi*s-oHReM#? zb2Kz`7Gjn5R2>zL9;s0}$juDbk!mz}AOh`}l-W`looY-~*w!flKiL$s+?Z5jOWfWB zhZ3CAGgWL#~5L3IWE;vd;Dhs-C6hZY)$!oA{`{J3bjPPU0mL`WR=sI0 zaRa1*laPL%km^KojdTyPLjjrYiK$L1tDxvzSmU0Q>SPdO0oz+fx|36#LNY8%i|7Kg z)#gq~b!z!Dbj&Se ?S0|`^pfQ`y&sZKA8czM+w?(|e=fP~ePTR`_VcSfo+!TgFf zBRezkHUfNRs?aoSdc3BSX6(1_X-}=u^^F&H#=T~_3QfzLf&rfv$xNlP<;+_jqU09W~!8V_2 zCvmJ_nCgGvewaBKC7E>Cp@NRSAa zHin5pOj3PCsw>MXn76sm5VTS6yUtyi>Z%H#3`I6?6f7-wRjRAO!_eZo!8H2a)v2xl zw5e{vmY1`0l)EO?wIxQd<=(wh0=8b8YCMITx*#qEc+wseegH>8?aBAo;^W-(7pH3=lFz>IO_rD0O4 z$zb+9|9H?c5*q>>yi87YV~MkULLex!J-ad06!4PX&Ev6evOmFtJFqFKrjl!|7y{FU zyCL}w(d%zdbq8P=7?#Wu1lWH!wpKDwIFpG0j-31a> z;TSY|&E?NssqO|0w2L*42YqZ)?@l!jG^{xo70$4EspbRu@0eV~#I#e9dCX6>pu){z zHUYVr>)YLeRQG`UHBfS)<|>X~&ETeTPpW&#U7K#~><_du7B{12+LiaFx{vIz^LUy> z*D!F__oZ4`eJv1g`#ak$Ox0Q8kOwa}v}x%~wFo?PuMH=5*mAVFMXBzuN^>Rfx=9w< zJP=0X_NKeXQ#}D5 zT8jn<4|sgu7M=~^6RDnD;#bBC(!@FL$y85)mt>yPnn`z0rFt4LEJ(t_K#<(ish+7S zunQtj5dMUGCe^bQ9z>kp-;9X>qFJfG?Xa2t<> zC&MbrTN%rBpA22Qt0Q_FHZ3UQYE&S+aAy8M656 zbGv&b)vMrk?iJXXyqfAYl3~RAj<5~(TB_H9{0N3u4o@A}(q{Mgda5_b4PP44F=~i= zBh{N_jYI%-Z>D;SWN33gXy;q0-Y$UxRkV@r?NsjogiV8nG+r8w@pJE_dbh$W&3^N- z^KPp5D%{)v`&|Ja^j@m>!HpLko4NN>eLyPQyll@BM;sNo4^n*y945fz3><6i?!#0c zRaM$W#^Tt`=J@<5)yK8cXq*o9Z?+$&`UKSa%sQINt>u$cpMqE?(J&c4&V8EdGXQJL zk!|j?RG*Ww9wPo~VD#IYOt<9oR9}EEvHeYN&P<*bEIPq`k?KowLk}7nx%7E%W8wVDaDvhroVaqkm^V9utSF8{+%a1_hYJ`0K*Pp2yb91{*>xx zuqFB!jx83^q7&WEseU0hoF{033@17}j3M3nCDpIh?<&UL^r!+s{WaBZ#PFJe zZmCR5g9lPun?Q)<(wUYaqwMkI`z9_r!7Y=iOI3-zyqP4;G^Dy@TDHQ2qmb~?Wiu@Y z?nlTjsx}!jc?1g249jI&o?M&mL2XBlaLZ>}fpqv{|Hd{BOSeL%6~V%^p@urdt(a*g z5I@0m!CU>A2bYyHtz0X)U(?V=w{oUcs*-{B;C6|4kE>)_6+C>$jFfo_SvAvYHLPU_ z+Z{=7rq#i0wGHyN1r2WXOly=7JoYHF$6h1Tnm}Q`(zZ4n)cR$#W~Q~kZH*UrHyzP3 z%EN1AS{t~eDy=A3tet6{8ghWW8myCPT@XKPrj%h8VMyl~JOn3h-AwCMxn4p<4l`?FHP0G_i~$L+LTnNuN4)3w`r!$%HKg!ZsFSNpN`yS znKlOx+YCz&G(iyZX4<0sc{eB<^lOVuTUI|0XSFe0ce^b!ZB^nZnc>PDHIkv|gKw2- z>#95gJg$;vDmle%ooSm2H}CZ)VOwUwW46h(EqGY}c?&8k*nnDm*=;lZiHvgnBVJo^8S^c(Uy>ZC_Pg3EZY5O5Hxw4&dR$DNOm^?T~3lAnSBD(|u_{+1~A# zX(vD%vxT>EM$U9QW!kx_kqeUvgt#_Mb~|V4TGmKY&E>S~nyDL*(a1VeQFYxi?E(-w zgtr;iW8j^3$@FJ3jDWNw`TBFFzmT-AV&-FkBmR=tN`v_tj4^!3KQsLcJS>#9arkxr zSEhf17&+L(lq~<9=|7~)1wsf2<0t-;X;(lSQ(MTqrMO))?FQs0rF}R{VR#ES&)qWZ z4qCDE==n`$pYXQkcF(j&Sw(Lgl$h=49+@H_Ys`Rw{rAZSx+qf&;*Y&%9ui!fDFIl5 z*!w$I$^IvqQgTCEM~*{Hz+}9cGQjebgUv_C%Ftz*a^OI~Xcuu7OfkUanTiVcvLyP4 zx|J(3)z#|m(RaVPee3$Wx=h^xZ5+@)7;GnD_e=uX42V{RD~L%Sy`CYA$7EwWo-011`|l8+3l67 z7f2Y69v#iY%!s>Jrr!Vmsw~dk;<)j>GxecNAf~8sG;uX!-d&$eeZj+48Uydv=K5yp z2NYH%dc}5;?3Zcp5^Lt!+ux%0&eR_)v<1^d?<%~1rU8I{HiJ7>Xp1+rHYW`OG7Tix zR^kyBKyYBDeMpBHgA&_)-`4Oxnf5KqwRQ}~J#D7_YPFhd&lA}yGU0xi_9r(ihkQ6@ zy0Bc0ZvRXN0Edl`nj-oEnGUQKJiMb}m>nE#?!Zh30oxd`$dRj~Rh#KxpwJEf!EnCX zu`t6Ooaqp9ZNm@j*UKG}=}?k35cTacg%ob}49heeJdCs* zBSGFhJX2E%8}a2j?GLb~Oos#eePhmnyk;(Hj>a;WR)QHkb0gqReR!rLC}{(l_NjA6 zWExTXA%*QswM%0q5VPpI;p#Xd)5!9NJMFZy8=0w@?U9gSE)((?GUH zXBt!CrUG{><>zrR9g}HniSrcGC$9{K#%3A^UJ~poh}0ZRU&m!SiX7XHyTC@fqcR;$ zIuHXi#*t1Oo#_}LBL?;~?oY;JG93%H1nIIHjd{MqH#dW4x8!3p9Y+~Iqx%hT$7MRc zOm2^Q)bW{4An6C*emj$OVB*AJ-g82x6UnvV z&H}e{mSDi;0q@SrbT(*MDZ@KB_Rh}q-x48Oj>)$Eo9P@7n;qM87*3CK=VUq;tU4Uc zUyIp$o}1}B;LswrE`bM{-FcbL2egss#p~1gnJyq{>%rs~?t)AgR_T`Zc6VW>|B(*L z5<}2^z+k^r!2MsQi^`%{SRCap%5*VlBUD{^M`(8!XSxKy?>>8Mo8m6XbSa3nXgJUE zXcZ4{cb8_mtSn~lX?S+JEYsy6Sqpiixdv|B1+2t>J zuWxj-GtD8rG$jrl=;maaORC09&og18e*m1D=`M1@IJS*!ad&098z3}`!M02M-I?Zr zmFpW`ztvt9=4F~+L-R%-UVNOJpJ@T8AK^gGf;(w{w7LbE?x}K3l*S7SelpEG#`G5N z$#gHd<-x!k{}6X?ru%@beS_L9l;3@s76SMUjv)wwnuVDjhj$Efi!$9$(&nbMiKn;wGd)1skMsE`r=pdQiO3!9flLpAhr#e6hVlZlt97q9qyjU^dx|_lQ+qhQCI}}E6J0Yo&w*-YR9`LXSF>d zm>Pl&gb78xC8L+Mn3JfdGCfWCFrnCpHDkm&%srjy8BjlUc3j$XFWUcp7teLiWO|m| zFc$vq+w7jr^c>g{M|4fWitmQUv*$8BPZ>Y9#)femvE!$@=QF)feJv~$6KI(d7Af~a zrWeVz5v(6)PAJ@qnO-W9k!UO+W_c;o%T>*2guyd~@KP^ldIj7c(LpS1n>?`bfyXoB zQ>2;hl}xWv()W0xC!+QgZ;##Phw9Z#ua#dU_@%vbzn1Cs55W;ixdhBm5k2H~c8m$7MPEpg`?D&h$y`hx>HT z-6xqo1@J>*LF4S+NW3ujX{OJ>ji#cSf-`@M6Y^Q6&jAA=fVDs~@bgSx0EMm^W8r%W z&HN(Mmt=$%p`UE48AjyGOkV-}1r&VPeU<5Jkg(|6uu8-*I+PB)&${^aGeR+LV-ULh|xMrXPXI zL)yZlA-nS&cI7PcR`+A3pQ=w-plNdfN4RPCQ>LFQJjn5E3U75kXZof53|?pb#{DJJ zuT@br3+x8u1>C=8`VHKAgQZiw`z_P&q{9~GGp4rld!|3YY=(!x{x!NkGP#B2z_lVa z9l`mfr9iBjt_5yRmddp>=`i9)cC^@?gRQW1u4RC&CdBiNBiu5%x&V}`AE)h%3RJ~) z$+axFr;a#$W~VKiYq_dq&<6A}PPbgH<-r3*LRe%w(>pU~bZ>CW=USoq)g&`}v0Oxj zE96?S!V#WuyxZQJ;8x7F(qeojG|?|aw^FW^!L8xu@4w!yoNE;T>o7{r{oN|LRwZ3B zwe_Rg5IVV4bFBvG+qOistg?@*toku&vLGwYYh-T8iC#!ZMxO1k!#Hg_tChF zcJMl}X0Els!*Xp#vO5CnO1D<7wX4$M88`4%Yv)=A+@{utL$sM(C)c`Q)&}^rdP1wO zn`^xiVfxJv^m@70FMroLzB}(YY@PLUZ2)Eq*(?psyTS&!HUtVIFtmO&)_@Ie!(1By z+At03U)SAjlxyQ!Av_QIDDWHS+61sRg}iSvk+zRuXWS;aHZ6ZLkU+xSn;H@QZJKMd z>L(^_Fv*1(h1lPzZnIpQlWSi^<)Lt!=h}kwGNj>z+!ndEBpE2yel0C-%UoLl1X==< z!o%-YxwZ!KZ3_0#$j^A&4nw(hu5HK-eI0-Z-sGj*k_K1D+Nk0?0pe{R=QOsJ&&Z z=}P=7*T2D*;Zr+ox3l|quK$p<4tL`cM_jX9y8>8K3VbsYID6MzyMg$o1XjQ{%?!`d zOm(~E+Py4q6qCm7o@j&;*Ct~ZVh6OkUb%Xg0K0?xSnphY z0K$ysXfLrI`{e3d7Bcrt!(HE8{QyF{@OKOmX>k2=?OpzoaJ}KQ**jN%FyGc7o&0&~1T{o9;oM~2`j-#=p?maD$1vYKteRJ!_HgTccT@S==9K&u;^Ye-et zu5xJoE<&d4hU97h54-?A7h6%DWL_I`H3Hi{!8uEdYs@v2bYO&_|CPFs@hO$_m7%$Y zQ6>=TUI^ocyJ5M8S3e6&&H`1K4$4f3q<_G1!*exJ#xI0Pyib}!u!(O1F>lIsIJsdw z{f_V!=kD-aM^v~G2G24nyxdy2NA*n4sku(8N*j5%Bif8}PRn&V zc-SqxwBcIM==tfn&Zvqb2!o~~GFx=AJ0sVb;Gv&svsvq%nd>Z|u%?i?j)pv*mFw(U zF(N0>+_Q827s!vRDQ@^%9oLT_HUDp}bI7$bZ9u&{C)c^8Y(5E;J=&d{>paq-OJ;cH zWx(gXl4EZ0RK zp)-C!Z*v#rx){vPHZMu_q7i$3yg1h-WQ1lh7$&Z7beH71w5+sq{9yAhcxkT7YUNC= z0GCnC?y_8$gZk#%JBG<4S!(X`Tvt>$%#@#3V@$8eb!CMcahw-ItGg?6T?KCY486J(T-R1*?d=;9hHAz{cWtim;9*(h!H9+z zyz#lNtBRW{goV$Z#UXZGuIo#jL(>G2{x0mU&ou$u+Sap=deylJxo!Zk^)r%E7V7+l zTobE0OQx5H<>_u>u1OUhBo9FyX;QAq6^?X;>E$5gb}~8Fjo^NPg~Ou?Fl3kd8*@z| zH*}si{T5EdDY>TBuzDC7DCE>!H-QDJwLjeZO}TCcC|8+DwSy?;=3KYbe(d!F+uSX= zZUqYq0*P->&bl?%w5kRy-@KIuDobu!uIY>M+5Xg-$H_fC*9`EmPN55TxEZ--f`nZ+ z2DNTn=H|Ms`mu=^&Ep79Kkl|%x0gRAdFnCbFz`Ndo>0W4zxFAKu6Mv~7(2%|jBxMd zdbcW9vFZfcbnoVRufhY#G$pM$?!8>^gD=DHd-fmb-p};`$*@EQ;#2U0Tpt1$Nf|VR zeh)K&>xa2MDoc6)b?&2F9|PEA_!m=X(Z{(yDa&*l*$9*LNv=-;tgjrFBXBzPX|B&e ztnQpWV&)u;?z3E<1BS(K*O{gv?(W( zo|M>)%RGfK%8a1-di1xd@Z#gX%JnrR!$*n`g!SuO-++Y$$o$WA-{krh#1jbn>|ACo zJS>`}L}2m1&Gj8+eA7%f4c33rN$lb8a(xe8k~NDTISEZAR9L+yO_Q*gPjL$<{e7+< z%I_jl>R@C4kn2YfqbXdNC-N-8wb}ic>!(_|{dm)LKjr$lEY}q+6+4KL1pS=r7tnIs z%m|8BuolME-spbG^=qw`{*5@r_%+vWRr%^B7R)*6tNSh2@3r!ELx#7w-*f!|64+F) z?CS5t9H@Wfa-G#G=io3uE9Mf=6Xs_BG)SPD`=P$sWOBZx3oTPChl*mm zTc%JKkg_ipBL&_R4mCLW=~8G}asvsdLq)FHEn8?gAV2Kkh?Eg;uS~dw=R>)vFd-4Lqz>d}JHxU#-yUU^b$d zq}chedZ9Hyx`0Id=hi5+Ch0K3ga+aP57NA5p|xr#PucBWbAGKtYl8*~XL}X<9t4AH z7g`56^oan92uIf`v@VdJk0mUk{5;Qf>lRv%+%V4>av`@~q4hz!(5h}JM1K838<1Xx zv^tvI28A}P{a~mW9Bf!s~rq^zq~#}Kzk zp-o9HG2D}oG0$+D7TT=*UFZ0t5Xo*>}y+2boFkH!rjW8J++j8d!9)+oI5x zAlBS8AKq8bwuSx#R&w8H`C|G)(LWX1t}JR=4hbAZC_{yfRgsi_YZa! zzj}v4JA#LKAQaY6w_~B5K>WPbZe)mY!i{XFLOYWi+R)ZG7Tb1Hve~&%SKuJ%>(_U{ zfSy^;UOfjMz&nh()iMxKn+}U-@46M*g$&=IaQK)u*`02eLVpJLpI`Eg)=LT9p9}qk z-0=B^akwY+5~9Bp`YUi)e%z1g@Lvo4tp*|I;JEl(p}&_96N3D+(fz&9KY;w#JdviG zrhet$M%_OO{gYhZ#_&#UVhB`<3;he+4kNTm+Ih!g3;e6lzsuS?$9o$L_wPdg0SYH% zFMJ67r_iotg{Dhx5x2c`Vb?;tf!pHg%S-)kg?1-d8m;k3TuC5pujKx_7utjDE|ezB zYvJ}N6p;?Qejs}NNED(%F<80#xV_m8j*}=n)5e7oazn!g3_%cFCV56T7Q>AyvP!@GGWWb2qX@73%SSe`UUpIVd@_Z*@Hi^(5B@aUArgXQ4gI zN;=1zdEAH=t~rfv&q8}umD?$dmuI|3UFY^H)T^r8E3dE!EKsOtBwepUy~*uDev~TRB8CYl^a>E^O zh=rYg$^TUiG^ky@k#Jj zw=X)$9agBG+%7b#bNr6oTz#Rzr2RhZHP8(%G^EV#Ti_IbNTCMOfv6)qHM=le_7-Xc ztx<{FjdA0`-dJcTco^vZEe$wa?Pxs84J|YbIM6CK+K40EutLLuY&&+~*SN_IFVqB3 ziuZWhWJ}|_5<=Tl=q56p%G;dS z)LJ6=kT)ah)#{l9X>jd@I?6)$se$q1eXgU>=&}$O7Q`E) z3yrB2svm+&s5UpI&{(iADI+my_6O3~LgQ*^yZ1{4V=%7JQMKQTC=(3TQH72Mv-t?# za8h@4p<{qb;%Tmi12Z28#W97BCD)HyAQW~^O>xH-Iu1M#)&BeRamN)pzA9L8brX?d zA7AJM@UZlU<7^*h=7d5gmSwRK9E)yr2#j=Mp_9OEe7m=_?nR)flM0;-5>_J&kkg{1g-#N9=X#l?csInU?0PUUNPAhaec-UEOBT9*H zp)&x(B5rLQ(P76Os=I~GTwI5-?_Sy7omuFt3TMBv(Si$!vkILJ9u~c6w<7s1^k1No zIC0>Z1DO97I;U1{z>yvG4ep#m=T=pk+Br8hdrNlb7CH~y_G-VLg*&g%`6RoL#K}>! zJHOBcq^;X%0W{$uqR@o^)@>FO3}opd>cT?*0}oBxhZBy#X@xEV3T&TEy)6LqO?6SB zi)(e%x3M|eaZoVCU0mprvJPIY%v#G`Qs`2kB?u1{EjpRWvMc(fg)SpEuw4t!h5lbw z=<*Vw%zWs_<%O=OYA~HIZxI12XeZ@7cSWHq$?ZaST3gUWy0Xw!q}Ql!3`D#FL>3rzqC!x`Si!ud3z&<$kN=+6zTmOBt^ z-cV>FxJ_-rQ^LeTlgeaoe2q^kG?`=;9&SiC7McQRt!Tu( z6djmSXevn92YrygPc3v4fS(~aP*^0yB>WAojBYA)Gr87=sPi0mbD>*Eh9Ma_4xw;^ zyQR>rU}0~hts_}d=49^HLer{x167^OeA=0eHmjRfXnK`vxL5L@>S3jM`^X zE>i5Z8HHwo`2jUMjTvrcq1!+zVFRlwkmO3_V0JUN6}p`=er)X((jur>r0&}b-2rZr zwS6;pN1<7y%K0B|p%v-DtU`B|zwI24)}=kV+uPEeg=T|WOVFbkP&d%cE;I+kR>eM} z8sH<^+?+ylf&8#m4E!97Rap4kXy+EXi`=m5F&gB1gGK z^9s!e2xEX=z&tm<&;pRqKbT_^T$+2O1%>Vb??Q{lm>=MK3f)UOOdO81O&{pqLid4L zZJag3@iTZ|p@ksUkCc~ub4{_ZP$!Tzsw?kT4X(4$qOuHL=UUL9aEl7v4`hoZ?VY;& z3q3&6cilAMj5G&(Ydb0*DD)t?){=!Mv5)QH^1(t6f%#sPk^+Wlo_na!!xfGc-$X^7 zJaxK<3q1mEAKc@h?c5`U9wlkbM)3uw(#`JCLXVXt>W2+?j}>~HWEV(*^&_jsWv zNQYtTG=E9<(zw7qQRqo<8Au-cQ_n}5nqtszeYVhZ)o;Bf2r~8SdB=XP(DUG7 zW%O=2$~|A`1pqG??(beG^dc!6j>Dn3FBW=p%2I_ z*TZz)U%j@w`=HQ=;J#V-{DZ$RH|uyi=XyNDeOTxta>J$?*rTp*{{!4dg+2!B!dD1_ z-snCq^a<&5+RY@O>^2(%qQ@bI$KFDpQpQ@}E$cv;0C&BGJ_E8IHsO~V7286e1B5+R zxX%lHL9z?^Bg{YR7lpng9R`3O;CT7VLSK~-ye}rJjqa;LUjx~UhR|W=IP2>|-vIhP z+9k~Fr^3a@e4~C-=v#8Fk1ae^V^~l8vqImM)z~vfTf3zW(f4~2dt9R>{_VLaEn9}E3dV%wW8s_{TS75W*>*Jo!vf=u2x?sh*H`UN~3 zH@sD%3uQ~~mqNdm#XHA0As#hzRGRf`q2Fr7xw;SK`oZ=0w?e-IccE3|_|N@b=#TQ} zp8Yj@3q;oLk3w!yD7UA*ow+(KMLLYLMb~L`OVw#H-w{-rp<`@!VUdWx;G>i-CRJvUOUHT4Ofp~ zl;r=qwd=GFx%S=t?96U=>(psokYzzS$E$lkw{D%*11LLavFA;@V2)d_PV0l)><;pV z{K#MHv;mN98Rp+Epv=Jrb=nZn<`K6EBYCVxyS7dnfh`NB7F&@U)oJ6h5XbAl{yi~s z-?&bj)G!?X*a@>qoi+tqa_Y=hmr*r$$eY$_GjcussQ3sNUpqW_ZTEgE+-7y!oHAii z;v1e8ZeFJ?fNU~g^E0BpVW!a|g{}J}q0e%%%ANN#<0Hp$Lfwq*QL6YEZk$b;aVk8?Jmd)-aS+dz( zRwB4tad$%8i4Y);1b26LcW=x4IWzbElIMN@c+;obXTCGPxua*!oH?Q`N%{ttmteD@ zFbUX9w`HWQ$PH^8HzW2!wN<38!PcSzyA`y#ts`{o3Lh{V(rqJcM{YQlOv#C-Ot)R6?E#A!C2j#CK2w6+K2rA*_oe{0l(|)O zkJJM^j7PtLgZo09)Uzz<<5qhevT3eoq#eMmsol9y?GR~4lGZ)qN(KGS9V6{jRE7+H z6n@@zinMd3G8D$<`jvZ|+d0xM;9>J}xvfF&i8qHxyH-kLSi-#0_=RrQNV|atQioG9 zGxMvhce_Q}9oP?#an@#;>W?f~l8J8jNPCdG77biAA?Kp7N2EOgilHHx0kxZt);%Nb z1s+z-2ozQ8++LCPE{mE~gHb_aSND#z4|o`@Esn>j@jj9E1qmG)ZjQd}eAzeBewA{V zK()I4BJE!(XI=w_H^6!BAL#&4Tb(sc$JMw4BK0Een`l#Q=E6pZdPVA8!MS?ctF6#-*9ZIM0TX7_T zhoRxA1hr{JN`S(K8d>L(NNFW~a37aO%F3$za~X1n#h6NDk#g|RBrcJ-=EbpeSCRRLOC`*1^GWmZKRTB#{-w8zh( zkq!c~X4P~IcLzl}nB-a{>syUMJUG%J0DdmLx+26JD|vTFq(i~|Oawv}7@=STc4(x- z%3p=sLU@ZhEYjiSuY#?Y5rooU_V7qYkQ+K$OK{XScSNKkfx>u?sK^jhRXLI=nVi&P5`wr5}b zwgy>MZKOKj&;m4v5sgNw2PxQK6Lur=W|s#xi31vI_3$E5A8B~yw;WyVZg`{-AbvOl zu{Gb*bKHnXBf;0AHU05x)9OY>Y5?%#Tbj5}Vke=rz%kMg=@@dYQT0tYy%^z+i8Kl% z&}l@g$lu(kNR41&ANspXI2RiujV^wDd@bU8f|*5X0`bREA=G2XmSK^D)oW9vX3B&C z+-h^z9I561{>JZe_To~%Be@>CmPp4^Cd{bmGPb#6Beeqgj)loL$(Jbrn<8#&q_#4* z7@r_!;0#^v+9I`+Yu&D{Y2@j_wMXhG5Of5l@Z!-CX$(l%3UyG~5m2Zxk;Vdsc8u>B zJ$k$w8)+O+c-%9;ca0WFg>5q~()gmvRTGBV=!}na9Efjn7@g_C1sEFQ3*B*%jwiPm zRxAjI1X)3jC2xMpu#5VYBvv1 zCq+6L)H==VujFoba->s0Y|qxVx4Kgzol4R-z&^Clv%JgPsgX`Aeppj?3~DLvv`D9e zgbyHAM^g>`xYHw@0U8Epc*k+ajdy26Iupp|`Y8UnGb5cv+P;Xm-<=idY?6U^F>{ms z1CD7DogL{Ma*Fl60v<20A?HLo7u>!)*zB>)Vbxf7Zlv=-!(0t%x5tMzcV47_1BMOP z-!$a@9qD|K&_E3w*msCKKhgz2*1!?wujqnE7n1hh4FWG)TeIDTkuCzSEbLqS*!-Wr z?xIK+SE`5o9?{`0j&uo-pB-GidNtuoB3%j=I!(NU+EH-_eg#mwx-`;dH^T}f`}B|gu1S-mpSRb|B&BY3$O z$;Kr-3SJfI>JqmHt@+R%bBuU(q-)9#purV{t6n@i8D|#PM7oyTFxta-QnA&3ZKUe} z1J%RkrM{IXGl>8#m3eyW=q zX_NHf6v21S&Kf7}_7W`fv)z!Ma%EKN}pmExI^W`Wy+ z*le3^dbnAUW*5Iihrk3mvm?zZ5P}bxoMTR;xgcTDcylh(Iz;ynO^c~+ZlqhtEx*Ji z46?zr-V$kEQBPZY9gd*fyh!saH4hmJ?>j%z0+2BEX2I3$&6^fPS_o_t(2ZbVW^B1I z(yc&#f#VYr&rD{GtxcHn_p_!D4rNq&vWU zw@lg4yy@8cut^yfx;r8*CO0&#dHC=)+;Y&X#gUc(uf_Lz)zu)*ToP$1Kp1+g?dQ0q zk(QOn6#QM^?3P7Z4&uL5Qg0uTfbUIn%OkBIH!L^w)d~KxBGO7A-`nB`^cEp(q&v%s zyk2ye1Fyw!v%53WUFEL=%VT%kx$dq=cZ07*n|V`b*zb;X4?q|tWL5}G+&z(2f!V^S z?%%7ATNUYE(xLx||LuI@7`r#peZaO6QVasa{o%ey_XDnFAi6GX?*2#*0E7?p=kcSq z#yt?}L9pW9i9Ewta#V#OJq*36s?2f^MtX=cfj$h!3s4P%@ld3PE0qnZ_g<7Aj`Rqa zwHB?EI`>GVM@d&UnO*QuKH#r;J9sqGW8@kecKCSrSfs~E*^J=@hv$3uc%&!FU)${S zYk#1GJHQi>o+P*EG7>&>=J{l#rvSsG#SM+Hg-=C#8Ypxc_pO++yQd>P1Lh~vzY{>0 zEhNY@k)ADZR4C9D7)Ho)c-?0sJy({u)o6YJZbgppT%_m0t-tqN&Gvpi(hFs|5Yq!e z5iIBnkzNG1W^w)E0l3Y*80n<~>eg5@dRSeJdnwY(K(=Yd^U;?hy+YCk1W6atGWSZP zS3!#5T;rjZm(QEstC3zK*Uu!VZ{26H$$Q~ zBE4CGtiAQ_%}8%mpth#^no;hpNN)qJMe};p)e|%M?MUwc_(3(A>3w{0iF+r~yWqtN zTaMIcwX1|+|F_J&8|gjD1a*1S(twyZHhOjW_aePdmfy*y7Bs`XAL)a#!oWX4KT!KM zJ?&}5nfXDa4=EEE8uMPrV@;F$Fw#e$1-S}ZCktRMKZ^8miI>6`Q$qeY(kI|HIA+O8 zEJF85q)#gqceJogjiLTD(r0A_fig^8wE#1K&mw&ezLuZE!2^f5&m(;S5LRO?lnU>= zUqt${{IPikG50^vJ@;j#ufVt9$9_ASnUHPG&|6!v7Sh6e_+ZEbh5IVf*Oa&Q(;t(~ zuOod!(iUeoi#GaAq;Jd5c*er7k16ikNZ)~5CwU1njRN;wr0;=3E6rq!z5IQoAIhJb z8XtG@yC-q+{UOqi;5I+q4ytKncl{XYCy>BE6P}h3>EV^~r$|3ns!ba3liuonj`Sa} zu>OXO!X(c9C(?h58WE`CaM}Gg(*HmL)vKv9T{aVt{4dfkzO_ipSip(&+gNLX*r<2oEpM$@ok)gydpER?Cj3CBSe?OqI}u3G&Z(RLD_!SU zUBHXJ!{Q>}jnx&%zIMa`u4}BdNv%bSkY4?IyR~Dj15g}}1lF*V1_i!A64!~fZl%7# zsgf$UZmiz{g}JD0Xf+cQ&jq-QgEWZXVhcXB$> zC8#=&RIYoh9w2@KSzSC~Sh)I?#JN#V@G$5RVLa?Du4k+r0By1K;&Qt~tQ|>)ElI4# zdKm5D*c@#ub0v&arj@_jJ_U3hxqYSJHkh7@@u$;%rtA zX3Aq{F0Vpv*I2tzCd}KwsK47S*6u|mt0wGwlG{Dj9;B^J#+vhd(dhPwwP#szd9EQe zf{i?dyP%1Wrn^03?L`?sf2;KnZO55hbgx)@lk2xD#eY^c*9RTLPR2Y$X2IGKO zy-M5;8GFgM7nfeKdY8BnX)`b~clo_z^#Sih-K`i5!{qdd)we8Zt8XGDO*Y*(Rs>#I zxs#|FM>+g89oi^XT>c8#@x7~B_unMTs2`ln#?YVm4bxDF$iU9 zs6`qp1M{Eq8^DIkZ-&J%d0DKS+@P*(edJbe=AwbEae1tMWOw2dh?rV=+3OdpKS)WD zERmO@CQOuq&Iba9G8VKS^9L)N_Sc6E0<%r4~=e~cp85HZl5~qjoJySUPrn>`U z4FtdO!iZztnusf>@HW)I^u)Q)9Qm_9Sj~AEsKuem&d`e4ymB&fU0Ql;Gu)uA+Zhx4I7@PQcUl?WV_8B z8tX7}?1R-lf(~wZV;v4;qc$kGa%E-?k97oKCqS0P3WOs^#5xkhchfWjO$}oaQxXLK zN5(pe+^`|MCam8~?xNfi z47igOv$0+5hQ+Ea5qn~t;c8>mfrJ5TB}hT*C{z%}ySiBQ1@1@NWI|>LTOVt9iQ9o< zcO}$z-SAi=zv!`dX?nlOI01wN$53B{^yoOlEtggw7 zD#NpGcxyQ()+lnroVVb^uEmXt)d&KQwIu?4Q^bl@nFRw^Vg|0ZldF39Y=21-y@*qX3u+Etm7-y41#3x zK7D+w6Tp07Vd;tCxRQr#R?gY>cm(l0fc3T*#um*J)fNv>*TT={@w7d5bKlz zXc*A|RXHWrsQ|vA|6dN})L5sH+sRK`KYOq}E!OEEHpAN^D&#g{s}8z+daN_Zu+`93 z?;T~kGh&?yWP{ZVOYa@LpBd|{qSzqzzHOniVx0|SGrr9>+q$!3okKDV4wh?N?nb(E zVx0>Zj#T8N=f*mZwDtFhruwnvQ~P%#Jv_C7Zg;>=%nVXTY5{rLDJv)F=x>$@n{#pH(N&<}+RrsCpQmw;JQ zt7}nSza-YBWzBv`L5G&Z)Lt6vva)7-T)fRYCJ295xXWT)PHvdc0rZfA2BLa-tSgGj zS4}v4FLy<(D~rm}xwB}sD4BD;yfW5R;A^m-Yl>Ba0>M?WuBJ>N#0Z2O@LvM1-*|@`leVD$S8=0v7w#`bQ5CTT;iq} zXa3$7LhEmiHL<{<+QW`1@0Al{O)ATCIkpQlXTuyfDb{3gYmG5kJgc{ibdzIEDGM9R zW>)d@;ZUZ;nhIWQ9m0OX)+45)Nyb@CjWwcLYt#3oNHzU@}vUW}k_?BRp!KsU1hMBQum9-l(nXekxG%MEZ68H4f5A#YlJJuX< zqjlRK()vQ{RbZ8ZjH4FARO>834|{;f7Y-Gi(=hI zPA3{vGi+GR2%@mXx*fz7s9m#F(_E>j-TeEt4+lf13EiMZdjEphFZgH$7;GHN4 zU08JYRJSD7(y}D-7Y-p4=1g)+V=XK3P=m=e7r14ymV<{~iGiW%({WBNkF^5WuY`gR z=On%jQo)tat%$Xd361+giHl^yTyjdfq~6D&?3 z8u!JzAD}qg>;Y%EyFb~pA36SRVrUwucxeW}7vOm29d$AIAEK+|UG6MNAU%QLK-_{FoIK z1TpJk_i?OGO56nccKtCARG-B9boCcZm)E!l8=XlANj{DB8M#J$N7lN}Vtr1^)_w0G zeck7=z9@fcTg!Z$;*QC-6I}ThvA!g?n7nDWF1XVzc3;N&s>G*z4FYqAc&qy=*4NxbgEh>n;U!nU@-M*a}%M{qyHVZh3#e0X2?W2~QwUoj-+&)O?Oxu0VF4Bm-P_>-{K z{T%B*Wj%o=BDLWnJss!b6WxDe{kN#cUny(r5r;!5{u}FmMLiIK*5*3*zgWM3gh@3o zhH0JqC6>Ft#EQVFPWlyCCt6@Mhtc_!^lOk}p@&ct6%Y9C*V1pu4dez|Qz{exM*3}~ z?vaoS?rp!7)&jGEZ{sqDq*v-xRvkKLn|vWe#QgVmk~))XmRdK589l-QqVWnsO+tEBy|@FDE;wCb7)S zY3T2y^}uZyh@e48cDJ7N`vU1*&*Ksi*Q7sy_<=E&!#q08Mwk#5&mW{embv9ClBxZ8 zK6mR&8x0S6#F)i{tWJUNzP(ZD)p`d z*HjVuv-B6r*a%i*is$|!{greeB=9h(#=%_vRoW2LmPWz!-tIP(HmZ~)K!ACd9q%@h zHU_m(fj1|Nhuc{C8;H%xKKpfZf0O=B(q_2lFmsmucj+GhVR`f-2xC(_qLnuH4{4JE z_t$?yun@xY4!4Q)&!PgNU{odUpVFpfLDP4%LB^WdZ7Tf>+z4L~tfUfNZ>Jk2q2r&;{CZKQ20 zwb_ovZjznc=C+l#BO}P^n`)Yx;lt7Pve;nTN!ydvnbC&SV-PvYZ7+2PvKdC$&^)4v z2e&%cUFrcEhND+;!uF7Q0){2X!CwZC=_&0{;w&}unZ?Ff>UNNJEO9R}WFam^(!8Uz z6L=VhwvJ&~Xtj43!@85SbNK^YEP1&E;!L-*v`Yo&J;_Ap<}_s&Y1h^GJYE>Wd9V>6n)0`s|>v^#hh=ONKxx4X1Q0qj>r6k)fAv?qX{*{PgP^WC1(ULbzi*gePm zOqs8yaC_ZL+MC?}Lk-N?`QFk#B|d}K4fBe?YnaR*dQ5qV|JTu{G9SFVXLH z#8m4;8QXdT5Ru{^w=c=Sy_h=&XfbO9#|Y8tnv8Dydl9D&mu?1_)#y;+jVTkl5$r@9 zLSGfNH#8l?si1_UADMz>hv8c35-A0@lYF0ph;OZol=Zzw74#yLa?+tqENbF+*u#A; z^#krqvFc%sI7n)9{iOatVKMrUOy*m2qU$dWC~-7`{Cv&jMPYz6u*7Xp0s}bH4U`6f z+l-^yf|`IEBpnFihq63~d5~ccEjR)5&io!I4W>+3!glF0OJ5w7xWUp8G75reT0}Ns zL!>Iuu$>4{+cuKbUL_4JikhZ@*(p-NQ0X90Kl|R;^&shB0BfKv=B8$MuyjZTLG(4= z9U>hHQVd3rmCa|y50wrp@#)-dP5Irt&>SWm4&IqMk0=x&4wsGqvhU)(kF9WobR>Wu zh7gI(9^Q!T8eX6L%fpec^rJ{qG&o)YICpJwZBjc>L6_-qO&tpr8EU)KK}OLJ)FbJ~TozNfLUl-E$PH~C3F9+H z8Vk^ws<(##%|z{JtTYZNY=FM4ND!H=ankt84+o&$GG00kz<;Nd83aFP%W>OtoOFDp zxXF8tmrei(?Hz+{DzXnu*2cRNq!Wvh-IDfpba|zd0K(^6khIxhc#?E7V3@I%4!YXr zPL@sqE5_9#E}O`Ii91C)6+Da|R0Vxr>9k6fgPSo^qD7}krrQ#uPg^r(Xegkk3RWf(fX(%Iz?khA%F(F`{7+0r@S zVR=A=I{YQWog2GqABKCXBFmd*#X zVZn7oX{tpqH0c8H%EI90m?i+qw&-i;BAO{60QB|6C+p3}{2! zf*V=<3|uT-0^%pZ7%n@-<}wMFNSA`!gdI3E8d8-G9N;dME?ZsJyi=Q9@Dg{KbUAou z-{My9(D-ucisI+1CiKJZ9f8;t(v@Jv!f1tkKDNVMDP2`5h;rpbL>X5}SA%t?K2uV$ zP`Ou2*8th14(+ALT_asvq?dZ!+w%)@ zd$Tl=GB(*AoFo&aNhJM9+wpcY8=IghZjv+^+*%Z)j7A$LOH)8X3m5^5BR)l%TKw8v zO|{_e+?&@Fp3y>+E6l83!bW8Co zAA}i&OLP5k%ut0oMqNAOV30afSjkQRgcW^goEqtP2OW$}r3Pjic(R=FYr~~0SZzolP)ZmR)E{=#Wik)w33vq z?nWe#Zl!c*S)1on;Whb>yHmOg+*UYOTeL;)lI|`G8Y4P~g6KB7yNUDwUT}>goAJD6 zS`GK$;tRMlzc*!0YxpW`&&nE%oiW`J^BQ|E8VlgX;LNkTv55zZU2`9tExBP{TTEht zTM2i+^Z;nswtdV#>H+D&O1T6}2u`^+_n`C;XrM8@O}CS??;+`7z~Y0q;8fF$;_Y49 zUOpa{9wFCyKG?LW+#}MX0Ji<$)J=)F(LE|X1{QkF^$sN@tNAhMap2Cr*EMxUz8{yK z04ldR{j$+p;hvD5EOA6;Uai4g4?Zb9RpL{Tgpc3#rT`zAU{0?7v(x`{wD{t_Vau zlU^m)Rw~{|`nXr6*GO0BFz@;9HR*LQ+kR=kzV3DD4U)dGMvlUjX{CEZdb2DxpqG17 zdW&ReBMSA#Yq__iw*iYqG0n80?!L`Sw`@_oExki-Sa0Tm%)KMM3u4=N40yZyK>83Yv`Y<*n6tIJ52cSP zAc3*`W%?uOV?aMPLk6YpW9bvp{wu{C`hc3BNS}gtwlTy~JL=WneJXthRD7hc==n_g zy!?HzMl_9#rS5a-3vlaX^>*$H=}S_6h{ALJG)}Bi7wb#uD{_l1frz^v4|#R&E9q-s z+fK-c@P7EU^vxROh!joHI`@tAZCQD+TMAFU#)RDJzLmZsHw@QcjyovQchdKjn)~$| zunIEN}Ksx)@#1<9Y{UrSi6spdf%@3;kS^5u{tt%`c z+<&D1k_>&Q;(g%1(*G*IsjA0>tJVEa`la~IiCc7czew(Z@=FM3dCK7a{VO1=rn-Jy zeXaXdqF)2}(*wr>zfSZUl3|ezu7R8XO`_j|gb_FDVBJOEpq*=`#l40 z4D(uvI)Qs;!~`HKJqba00?{=`$ozGk5_P6b;CB5j%V-;1S?5Gu$goD3sR@*|OQNm? z!cE)sI=UuW8^k(d?gg9N+KJWy2t*p$rRmAmxpfk)TNFdFZb%=uZld1-gv|h30K>>u zU*vw5XuYCfKQE78FVXMIfVg4;m$>OaK&G0~q$ zb|JZH0v*P$jr&ug^(z?WU1%t|^%HFX=G$Xt4klk(fbX#l68*WvOSzNbe@^rl@X$@6 zL+w3u{3X#}E2Vj%VvBn_^uH$B5Zp$oyTyNS8z$Napfdo9(zQ5Ka2qAs7|1rVhNgYp z#);_hz4Y*CBZOb}r*%PGi?wfhj-8Rv7 z;5KW=*N0$dRI**7?Ln;(i0(P5N4xD4bqBJR*LA?NxbBI1lr;v8`k;i?BT-Lq8`0=M z*E7)$q`Hve`KA$Lq(-+xq8-a$2A62Y+|P15CfW%+te`_p*QLI3xZ5ew&Y(e!z`|_> z_ifa(bD~|y2_zxH;k?@=(XN#mQm!z*@4F`24YZ4I!;tY@#>ctc67633EuOVUyWJD* z0rG#yiID`a&+GO`v?sY?Sb1~8A&41(?3rjU;Lx~^rkYxNw(`z}_DZyOSzReISnBO0 z2tVTXPP7lXK@^UWWjzAE1}-lw+I>m{?fcj6itp2#lUL}owx6YU?3`YaRNUYrV0OI{KhF!0^(a| zDg;Ja@MY_gL@9U|syA=WHH|25rHL}I(0#a()>fA#%7MZ<@s2l*z04E!1GUw_!QBLj z?U$%Oh$r=7i~fK9y8ejbB886to+qQoUs>jYrT+j^sq#Sg9qZ1AUGZZbv-=M5rFp1 zeZ1qzBN816U<25~!=*W4Ix^8wWrbm5n1pbaJ1S8%xUGB4TjZ(}9ZlMLm5ykF2KB)Q zfjc@;4XAHyL0B4qm70bZ;io|j-Km`?`RvAZ0F9j!85MEX>`w(WBj{M2!GNqs%^*4nw{h z6O9J->&3G%qSN3`sX0+giKDH+ zYMyTDC9WmWvEX4t*o2IC$0lk8TB8X;mRzb6uYO=}P1Ht7>lLxdvCC~s)LwqY9{~*A zbfiq}i8{bTTTxHLN(m~{k!Va=I@oCj3Bi~|W5L4?<7tM)V$TF)6O9A*^Aetj))WDb zOEjL`E`HSUlx9BB#wR)sER6cdhGX1uiH-;Gqh5G5fzKpNTA~wH<7OIbl8I^VghVHT zud$Q7KNF7YX;8Nl6P-kE7yn7(QrIRvDbdMb)>AA@c_?Lv)VY%rol@3gd(>vd#AY_1 zbKEJ3P9@hCP@jQ_=1)y@8fn{!J&5gKhaS4TiB1RfO}E!3^BQ$4T+-=@&HxW*CO3sP zcSfQ!K|-&4@l1PWqO$|zRPBXruZ;PQt=Oy|#csNgc;hzZ2V#b8S{@;ntCnubk16v6v z*Kl0%?s0yi3&`ri0NDBHA9pTDbRn3h1dZGl>fMEjE&{Qk?q2!lE=qJUXy|=^>QqE=hE01?*ct+#4KTn&>jXuonj46{N;pmgsVzuoU|t+`^QbE7IkO zuBgC-YGLyY?-=2(NOUD|7g|(kE39-^Cb|mD=8ZwcYRvl{Yjam6x*FU*=1n5fI(K!V zYbr(82p)A!qHBwyee2sswc|46+CWijodR?OHOMDuu#NHBdxaqD>bVE@^ zwYl4XQrwW}Mj$_{fzsHU`4rF2n~!>nb9rN;n<&$TMtTov_UM08q6uI&o)B0Q1n~|s zA<@l%VHGA8cl72&6N{e?=J|^k|8_Sq(IhZih}HNTc9RlKCT%=UkM7;wbZ2Ad)9nQm&LY2d}~oLP#Vt?dlOv_#X(UwQA8g@w)ZL^Db}^xLb* zxfzLOf_I@YUd6$7^UOrEz{2$N?&x)l$GcgHW&_(A8#o|NkS?J~@ znhS2jVzDA%+vg^_rBagng^2}kg+ktvXkJlew<`9Xo0n)lfQ`)|yw1%}w4nT*9Y;1# zy!f~Ui57y}kZ!&2ep|bRiEbrrUu=c}g>c-OXiZ%fGHjiM={NE0 zl0-`Zy8y15(AYp2^H#Ss(K0Y=G9+atgRv~p@)9xSf+cQwq7@)vYxb?TM~@YWRsvO4 zi#cRib-IhCyq>B_yFlaix84qWgfuxmPo`hF1$# z)qRQX2Mw!*YwrTjU`%rNCwc(f=92f~7WY7+2T89nPvMg6m8sl=i5@C*O})_!?|G>6 z>uIigDAB{@7MCoG$7uH(`})I)9x1+Z&sE6XA4&8mY2TW#8aP~Gl^;#?7+?w`o#Y-*^aM#iOy!f#T>oAelm^YS?h}cgq)eE%x_aoJdos~eKw;j{o<;qi zC+sQisYFkg)%m!u-r1fhPuPo&=@cw*PbYe&Ql0q{8sVNv^ej*pzoObk<08DyJ)7t` zu+a43=G)`BM9+hSLtt!8>+l*F*XI+x0BHRgz(Mgsq8CZ}hOxHI`kJTG1@6T}FM)?i zL=ue)T|BwIl<4KMG|T{69^qm29Xl^cJ}P{#3*p zw2Ncf1{uo<_g12}i<-(ftM2VY@02x}L5R$LB`xCi9RLQMzEVX`)28Wn&>m2us=~i z!m!5>sRy7^PfcjtrRwQu*MMlH_`t9i~YeA z`!}QiCHe(4^lwPRh|x9fmqhNt@F_Hr(H=K}3yN940t}xb+%xJr4BS%pt5m-R4_zDH z+Tnhk>Nfyu@GBdsm=ty;Q#^*FId02a87c z`&54@0DLsnj&grU^+$j%lqin2@$QeQ{siVnG(3-3$eG*RpHi(4?!V=^MdKOoJsm1% z531{@+JIaer5?E1+91`Ri{xhMaQEj_e<5i@0{hwK{*vmiWnEzd+N|LK9gn~B++R~| zNUm=Il1;v0mw{Ps!&DoUzbbU9P2GYP%!EhXDAmTrH;7Z;Yu+%bTiGtHIwDZF| z?$)Wg6~8cDhf&1JaNSaE17?ET))8)-RNImYN6&Dg+PQ60ZC61C+Q4j=YI~5b{9@Gv znB6*4G~7N_cfc^_-j(ne3*OT`RS#g_C(QV~%Gp#Xevec=D|MLbgH}$K40DM@ zqy|aO4ykqovz=F6)oZY#Dz{^*ohrX=fx4LY(w$Q647kR?a|!n*c7!2xJEz)(Tw9qv z;cne7sdg=DZT6SSTDNPe-3rJy3D4qgw^X|W1+r|Bee7Om+|ll-_9)86tRowgJyPun zKAitwHHTFrhFG)XMVTFX7^S-I} z1Mlj`98GDQ^fbHuQtb~ICacceLGGXGfC>_)aW8j3s$L+0EcL6Yb-hyc1_y|{I|fvE|C08o)+LAjs)gfeb_1)!N(g)!=B-NpSetKX= z*ELAO7xHpCirC)BYHdS3&^)&3KOhdx_l6zsFt4mc+ zZda;qY$)&J^{Ivf7K3GRpUpkWbT>TJ2=FjX@Io`)h*TpB1Pc~p*+!;nD1U1Ku<@zs zANCqj9RnU#I!!R$onums0<(cb0~FFUDpezZ=ShO}#N-omC_aN3vqKi;+f<_|V~wC$ z=CXTqswNN{9>Uj-b4{t5i)#1c?pW`dQ?&qerN9{8knH)X&9$UDw)hncN4+~XRV(RY zquN7T5@b$}JCnZSCkBh{Gl*MV6K z#&Kg(jVrP2^Drr9;fz`L=Hp88o>NN1K)Xv(h8Q*NOh0{`<4j4wsgg%V_ z>8Z{D3w|t{# zV-sgWi^;sBT#)L*GS_UhEG_}Ag9_&1!c-TLYc1?!@AMa?y0}QERlWMTi&I@fx-0pu z@IrR~Y;%{Sy0idI`;S;14AP~kE(7$f2#k)=S<_lvz!m?pRF{)$`=^VPL6k}$3<~AzEgc+&5KGhB6+BA-C9^-CEbt6d| zBrE|&xf@g6MA|PXBYwBD|18$XO{pfV#-R#@+;Kvxo58I;)o?pQ+|8*bmIaFdOIV=J za1&EaDhi@f*@2ie)ntIK{>$bSl&#_>rIh2!H6 z;pU~9Un$MMx9pZEM!3(C?+yaQi|_UeLE3&8_m$WF=ZKT5h`Jr!jx23whf<@fsIm2&HbqARLTEYJN$C0U6B2RR8 zq*_d_O+7jxV{6>vR7(H?b>`vM^ykbm-I7#G!97`<$ca7EElsryWR1r-^Jg*D(|Y@r z#a;@&_m`zwPDxv?&2W&*Q>`egGPA0MZbhnj_07jqJwa|DAct?^o=Ej1X;1th zsdzJgGSyRMy=LBMO1d-A7<($!(?v<5F`HS()2W^*>bhqZUw$UlvqcG3@?0qXv#Fjd zN)X1Y%{`audD6bk=09a|SVHdkR4tMOS5v)Kb^?Q>>j=dVuhrg{&|$f4PCw7_k@m+Jir zgn1Cwgzu;N0LVApeA+B>AEf#aBrL2kn5VUHvZCOc>LXwqgKqfn|0vbRB>k)~YOEwv zE1TjzPW1`6wFJ-a6M0RX=RQgGX<61a!BJUr%EEP4xO%s?WjgQw<}C zEtcwwvY7Ya3EjAjY5F47m*8Pp_K)3{slF=9u@vBAjR;S5U#0rGz}agU!a@0r+xa@x zH{fB8+EHF&Uw)J7+p-Qb06z_t3ya9|ZL06UJ->{?v2m;BIe`sg|3Ba1-2N`r_vLTx z%RW*lPe9+N`T^WeT`(#Si_MdD_d}{5$qm=HZmmq6z^#AH#LBQZO`S4zE{igB+;PGR>71zx z_!`7AXjJ%zB-bTV*Ya0Wc;PUc^og9qT{Eo>ZjJNd)e(MXTBm}vb<{Pxbuz6BVv7pv z{?TsTOusAYVy~kzixX2j>wlMNy`o%296-W2Qfm4%^LhNQi%1-Jde84{YOFH@wZQpJ@Yv* z{4p>t|H!lnxOH?4j$k**^iPsS`@MY^kCy>7PZm&eW~^c@a^bYFD^!nYID<9kSzSmfI%Nwv`IGJeZ7j z+f3Vm1u75>e5SyM&2igh+MbLx9uESIuuHqyLD}QM_L;huW$cNSXrj3EH9PDO;Bq1C zLibEPDj#iVVimW$9+`TA`KFl!;TG33(+(hO(=UrqQ8??_A=8eaffAui;C9Tk6F@P? zW=n0)j+ak{cG?hyi2BCE5C#vH03n&UbSnc-N0=bn({I3 z7!arJmTC90FxPl*h=uUY?Vf25@Gv99qCq#s?U89uFu%%!zL&j91bQ*g?U`vWa;*o| zL-G6R_R6$3fbY7A74L9+XW9qE)*Qc0ho zgI(WDQ3a^&sC7}MxcJek2?wGC-Q?m78>(V2#=X*hW-6^r37GGtQFi2+nNkqH-Tkuy zyTYZJGC-S7^ze&Q`<{zkmMI6f=^R!M50Yo12ID~OWWID2}q`X#IfX^c{9R+S5MC-yw zns7&Dss^(ugLNI|sxuv3{??deuOrM+cyy+k61Nu}Q{XkxK~1J%;9&&Ya49=1Q!PN) z!cf09SDUF0#6EGjF@|-S>Ph>?mlv1SrmXduh8Mr*I%H3@!!wO25W2YpMs7r=ks#I) z_{AljXB?TS0nB$~blV8mkm(rG#Y}RsYi@-_XdCU0$uz30ZVG(iLN_W?WAW2!wB}r6 zrqQH}iL})cuH~aMHG$h_t4k&4rcBLXVO{hN7Ba3mQwyNYRS~InQtUb6ci%%2*?Co>bFlA?(^Sbrdz> z*34d#Ix>wZ5RN}=ZrzwnV?l}~v($t&=zLfd0keY}n`vB`TfWX>v}|_*+qXZsIibBL zW;&@XXLq(G?xaj7gZN26Rl$4mGo#v*Go1n+`rpP8!3ljzrc=SfB=p1V&jb~xW;zYf z+S0@PIlI#`onF>x&de+d(n^@u(=(j`9#-tJ9Ym!%Bh#56;Tv&t>o5-7Gc%o4RM&l2 zGirZlWjed~S$FEMt#@Z<2C%1an~HL< z&&%}hqTU{+LV>4%Oy`3bnb~KMJ3rF}Wvv9{Ll=a7ihAq?nJxsk{&K$6j&v7hx~TZs zen-2DGF?n6^odYXIJ8kZuJ(uOF3EH$xnW!gqc+lAn(49vp~-f#UY6-{ zkf7R%yIYh;xO{qd8kc9ff-K*Aqe7+$Y)kEmOjm;Yj~b2UQQV8GLhhBBt|B)~W#0z# zbvoKzmFeoTs?bjFsN7wh>6)^t0!NBqiV{oUW3S0{Ex9%z)jWI>2`tlfWi{pi%-DPs zn%s4nuCL&n?TfkFm~Wr!Gu;3l+Jc`Docqz~qCuF*rGJag9ubKnDYl?r%+|8LLf`v>zWO)0$(g2*HXbAB|FyX(nWh5SoSC98obS|3(?INV_?ivM$A(YKG`+y-u9-=5 zRMP3`nP!x@J*U`c8pAas(@gNSeLeQt3WHqhW@efNYTx7c^U;Ad zApf~iG`A9Ko)wu^7Def^*K}Q(=}sWu0uxDCwD?<%IfBue?C#8T7rEAt>Onjh-<9cZ z(qZ6eCDK55ccyzPST9ugIRx&>vm+w?ru)D{ z$NHGABVxb%GTjdty07FocYme_0M@28N3_?EYY&&>2Qobf8pJHcOYZX0x~L#H4`zC( zsH%F9ITd**)58GaJT`Z-_>pAb9?tX#aOmH`^-#zr_eiEk!F*rr9%YeIED*(`nI0?Z zv^S|*_gJRK0sK&|siPXG+T)p?AlJSaLRXH&gHD@!BGZ$=_C+|#aFu>C(^FtZQTEwq zGxt=cr%Cz-T+B&vF@n5Hn4G6GJp=B)2VZRBG<#^^@6B*!&t!VG{8bS8hgZ#KGd)-0 zw!(vL-Aeadrsu)K6bz}a#W7Qxdp^?(fVPR^|JOhFLZ%nVE4pi1m*#S($E|66du#0GQFK2oMBuqk`xvlZBqF>4MDsVC2v;AAsN=%hr&GZ_$wQvZY zsff4$xqU6u>y^d4Zb#L!bf z!v@y(y-e=|hgCfoR`dN#9{|`2Kn#ndh!%a2=|ix1+s)2*u7n!~+iZrwhtAW~ondvJKzcK>(DPR0d z^6*urugML2jB{WXZfL&F^bMFb&Ag#wp*qI1m)~Uiw!k?V?7`m)L*2KTzAJH?0+Rxp zanW~~zAy0*pAdfo$VI=;^aHrjvBAx}h5nG~N7BAqX1{lb`!Ul`MTs6UuX{gb`ngDt zXl=p$Yo`B@_I>gjnlGA};S>xLR=WRW`Y*X_`}X7Jatvg+&iyyj|0<{t%wtUH|1$jo zYRkAAeudGcWwHE{$vqqzv}yt&S8E;4`F;gr| z@o%?SU%9%JczL`mhOh6Et1GxQxi@CLBVE^AYnKIs)Yb-Vp<6rGI^e#^l^Z=IJ5b7X za;;0QO^(ILU?A7c^*a#ThG|um`(3W}NQM>E68Qi1a{V5xSls5E(Uh(T_?7Dq;Qmvb zI40mPbayNg^B;2kv8c(*ylwCOG1s5K{CVO}L4Lsvh`!q^L~uOzr(EloUqesaaPMer z{ahP>uR}wezKXPqC(vPvt`#gV;&2yXN`e%t7 z4`HrU(SdOP%(W@F5v%?U!NK09x&8%Y{px}Kwfk4D&B~vKrDQDRLbqA2%}YGU8cf-C zlG{Aj79~Cdt80rDJ{xu4EplxMZcVT5mk!9?mbtb9un+a*w(7RZwRQPJ0!(xF4e>X& z&eaXvuMd-nn=P*KVPPqD%e77UD-(qTIy2jClWW@&$6bmYqVUPLxNUQ7SK>j!Zf{q! z+;+LPFYyrQ+%$+6x$Sdx2M=q_w62&+Gnh0z61*?td2^}jo~uXs+i9!jbIgZb*dtfZ z3hvur@29u9p1F1ax1s1((>h{|+acGEWkIAJ2%or*pn9=muARWcHmdS*CEZTBb_O%X z_J9_*bFN(~C3<6A!1mZB*REh|?A>WN*`H0LY(wpuYd3QJJoHYhhPd5w?G8{-t)NX| z+A+K5+M_6FcZ52(N3J~qY{JaNliM@bUZg|o`t%w)BOp5!HT#Ac}JM}{c`P3t`Q;h zaQY^F-Tt`_C_YnNGa8-kc6UIoUO?7n2zit1m8&=D$_BwQj-|HT_0H7?yg2e;uwjM! zW`Tv*>_wCFI)P z?F%!VT5A zM-^}0L;}k-pg_=LsNrB4kZT}Fm>lZi5-~8>AfS?b``g!`TnB=!rd<|o!yTAwFld+} zv^gy>0*3E__PN2ihLF3CpQ1xeO^f%~dN(9jRi!F#{%LyMRk?rj$@FwIK@+n+EV3*4c(4g)Wi z)FM+Sh9mcS?rh}4avi?N3OiWmptG>jiqu^y8q>xIx`dq`o{m7Jb zekT00$*oRv!*h)wH!Ko(Pwqt{a*YHEiv*LTCKN44=4t@5N$K5duxrS53`su=MmCY5 zF$;6tF}X&8SN4&emA9FJ8@$H~H!4>nxwedXPO0Zpjk!jH*a*Wd*Nk$bb2Sx3q5(t9 z9cELmW)S}=PJ1Y{P1I!9oT~+VjZfLTphZ}p&jUqEu4Boy_6~-}J2qD<$#wj9+G>XL zW?>QITXVGmuR*JP-Tn)99+-J=TdsD>tnnQ$mF3i#h^|C?t`2g;SaB~#{^2@ujREs5 z#x(*;K}a3&<2)wU*b+BuX*}H88-p90Yg~z&EQsKGSiwzn<8qBJ>gI`bB;t5H4dgnm zQkJ1zL>;pbY95#Cc<^<62m3T5Dd9d-=Z?>H0 zbrP`erp*>{d2RLZ*QACg2?=5GuK(guW$y>J(`}4#1!r zxz4MU$}pj9bLZvyH&D?xo5AVW5fe!)*ZJVSRn}WOeE45h&|)^l`MEBrR76AoNa6*# zE-Zgg?8)GL!?P?G=DLX7z?yiWRA7v-@!^th^2%G>MY%36YcQi&^Vwxyq)h2{nY%dG zCFI(&>{foSsI>tP@5F3WW}fbU#!a3hXd>MqZ9MTxULV1k0? z_Z7LWEb*|+r?X;~yDM{D1s+DXH!*VXL6Ga}3S_z!P44Pk*Ob4un~BNa@sZ`O$#pGw zI1>6d)QyFccGu>*4lwMp2#t!C8h2f;>%rEcJKbUD@s;dp<@LF40JfFNn>jHBYfXlK zL#`V^!^E-d%#2_O$LNi@ZUPU3(5r5=yD8TMfN=Y789kG3KDi1 zS8*>4aZ__mtNeaQM=jpt+lFIRH7(b4@OAi(sk&GgOyd=%=bEv)_|V=s6|Ndu6}cI? zW`c(?95R}?!Xw?xT(gR@ejl0Es`0V2a?J*}F7T8x%FWI-r}EnY+$VShos(-WSkc%H z#3bgEW^S%q${Nw-fm&NA=auf3T=T%gzGX=-=6iElN}j8B^K#86*9I4k6z~6Tey#;Y zJ?vyu?Z$EsXV4bpT3FWa?VwpUE8r*>=DHO;@EG*MG(Q8YeQT~oke{4&~JABs#cuEnLapnd>fa+nAd%MD~7sSFXE(!ul6%-`%pWh1rL-D*4Q4?OqC!U8~5hAk6ddTXW$|fWADp# zKZt$M44uci`*S@|R%{wZ=3QYn2igO<9xMtXl|l3I!CVgkc%nFs?Ph#{S>Tuq%1;23 z_)xBg%QAt4*q&Cg;peL+q$uu~qE(xFGS^eU)^A?uFuHy!*V6#S z%yaH>2tA$a88BaSXnrti4VqWaCfhR4j{PnN9ZsdXEomGi&;%Rm+N^l zjgSptZ?^QuN1wToa?j^_fecRy!{|)0qsP6F>qYQDwucz6;9ku263{xnFU_r7A-s_I zrCcuq`_r^{U-xpZS4jF+`^Ty<66`CBto=%^SIPCCGv>xb_-4uTYOdGHUlk{yH{f9Q zxuLz5>veLiF=Y&x*K@s5{$Lt2Y35ocNDX4(H*&pMekMpCz3#DlGuK<->-a8sZpS-S zcq`Z2mEy>BY}uL#+S|F_0k^Il(K6b-lj~iQ){N$H_}ODz-_7-2`AgLE3bDi-_g=2| z!EISp_rhoO`?)?S%au#fR7pO_^&xnecg&B?1>c9cJ_0L-z80B~`zY7PKz_Az?c!=_ zx`4(>u6E`7ajs7&;|IPFNfm0WixC!olIzo=QhDpx@$S=Hp8bA44Q&xSP525^t=t6X1$hd$+4 z?TmL{=lTYy*f<2^_WV&9qxYL!-&TGAmqgv)=K2mO@B#`(*zUVr-vbt`=y>c)+DDFe z-{<-PG<2>-+=Q@S< znSS%nx&9yC{xV9dV{5~OD{jPyyC*~-?g|auAuNZ4IBA6rO?RgSiMzY|CWZuu1cFD1 zyKQ%O_Z>OctXk`V@BR1vIEReUBXw7;dP--_nlK)~d-YvI_%< zn}Xr`3OI}^d%-Sp;1b5BS~t>qwHoosiM14r%6gI32kk?5JteeYa%ShUexwb+ z!^ts}nD=gjNE?<&`2x3Lq>ZX??VvR29FiorQKXH*eJg`Se(>ZOc>RqdZBpf$u19ql z58>-JiL_~z8-y+12cNa=)#u%&kv6Mx?Rslk{zm76VN<)$%h3gY(bD%!f zJ^%g&N#GN=d894YR1{(cnHTtQG;I-SOLD_3U5rar?lW6P+6pWT$Y6^HuvMh3LG0(w zYQ_Zsg|?2=w}gyWF^NUrNZSC};_HuHpW7zVwxk0SNz`Rr5b_32!EGaLM@AoOst*!L zub#!r{&tbJ2M@g(gto*uw|%4?fcya4AUy*kHPfph5q;h55NStp!wrEYX-n0Fm*&I9 zq)-+(WyeT6QO0`HSl`vaEqJF$JA?EAF%h{p`83CcJ4f23#93yTEAv|~(X3q}?ONeB zMU}$;u90>F56#6io4vhTq}_o6{}s-m7H?1Lc8|0NIf2C(SqyZ0MB1|k4CLqcjIX9td_%*Vl1_ldMGXdsoe(l(3*p|n>=ZWUfS zv~Q&SDAUIV-X0dn^=4T6McTjm)<67Xt#h?k9rSU57>mVj|40YazV*zFSvNoJ4v5qb zyd*@NjQ;-7FVcZ!Y18Mg1s6Ur(m~*MvJB>EJt)$_B>iy_rK8-zkq#--2v+OeA(8r% z4kKXRB|}WZ{*eX%+hF$drY-{_9SRVZ?3w24_|Qm)f%LJiTIWr{uF2or z$&pSWCoJpwF@(Q$r$jmxDEzhwCs=gez1pdfP9vj_jRKU}Yo+rV;ZBP*5Zr60j6nTR zgQ`--Yt8T@Hp2~yR0kf81H44xQnSm|MH&nkl({bM#pRueLcExLaHJt*+1NI5IT{ja zD9Lcx9e9Ep8WCKfq(595og$r1+7Ccr3<9GUE<~qC8dg>|@T`G&_}3XEZArnYHjZ^? zL>dmz2LQc7yhKdoI%GoVNKuKiq*eu{8_8=FDF(OJ5SOmr#gP)yp>v#S{wXYpl$K!s z29*4~SUZiBRW({zU{i!QX;T&{UxPpI<5-*1)jU!GZo_cusi(Rk(g>2in}Nlul)mP% zJx4?uSyci_^KMMcJI%;QXM$UQ(J+SLKQq!<0Ab~iK=k9?kDnE36sYy;HB%QF73pl! zp32y0ntJgn-oU2QZd?iZcAp*T9LiLi_F^mtE&AFyky8^54=X= zE%@LIkZ09pUL@I-w>H}W_;V|E{aqSW}{$+|2?igQUgHPG;68ygq}4-Y9u$18ShfPF;WvqAM2EH z{qtzH?c=6M%~d_6TQ!w6$;mT(&w6KO2? z|FKOq#=!hY+T)Oz(Yd_V#nTWLGS3QNLSb3 zQocbGu8wpKaOhpv*k-61Dw5Yky0%u>YnB3%#Ghdu=H z40B|j8?KLZ1GpbllYLlZI#WOjlC2ve-B^9ayR#R;+PlGxk#4H+>C}S-m(9DoDbmg0 zc0!!Izq>ioEu?HHT1?V;OQc&#+hQ70#O~Hex0RKwiATk--WKWh^0T36w7c6Q-9b7G zGqwd@K5$2*I{|&W%|6@|ZZSmgXV6l2XQaEzsyR2Y?=&G6gML?}yTQXjoWZ$PQU!N+ zq`pAy|v9f z9O)6#VXC{DO}OtKiS%d4_4;eU%+&?ukfG0@*IY7a+zqPe%GitxOj-KX|l_GzF*+Wtap!sCx>w*iDJ_RQc`b zu|{Q{iu5!vYdVdX{7#t1QSnO-wk$Jsasc@X*~6BMHJd z!aWyhDp(*CoxNNyrbe1peeFrStqM-ZX_2N^IBT7Edmnh-O^-CAhC}F4{_u(nGa@}- z;lcl;t@T;%`A9Rt16@1dfCJskNVBSf_~F}to^0!f47?x zX)ai~1KE@OdU%|&i_Y9g^T-V=mbHxG6#2$5%!@RioIZYx%y5a3vXggyqy=m6dF)y5 zsl_dbw6MZWu52sW2<^g1FM!+lv3jSPYI39(L2OZsHUkg54!#&^5m4xIJCe3VkrtPL z>E^e&#gSeD=;ND1L(F?G@22jhNK3$N#rE49|HMloEhQapcQnHY&I0Z-wq{IAX$AVk zOCv3#j5VpQYjP(lLdzm82k8T1l1FDVk+N>^lnx2 z46YGA`VBXgcO$)5;o(Kp%X!^0Or3tNX9rN3`lpt1KOeNcTBo&q@(5Y2oL=|k|a zEjcrr*wG(G`lyESP-%YkKZ^7*Sb3YBiQp$lm+h)miPb-j^vRmvnB!f-^4EP5=~M79 z*ypy6Z>VpW*z7)y^jTHf^8wU|*8}%iq|ev<(kwVBZfIVxkHpG;l^Q>f^i9gx#56X- z9k_2s`W8UwMr3!0n`qd);>;eV3H&81rpw#@gSF z^gSTEU75Ey(-QL675BYJ->+&!!wV;`_z7b_e?QU>z)SYFjpLjrp&vy0A)qZn8$$QP zNIxR&M=*$&0@H0AqJ>y6_qacb^kd3|Uk-{bezM$;BmIO7>oCj_H2Wu!ep&*D^1|5W zej4d#0M-xQAsLfy_p?Yp2kHZ4E6x)~<92@@=@%7laur)yriS~ANWTQPf!Xh5_sdAX zs+IB*RKJ4VuOj`rhT|>PLIYace;w&J;GP@CBMTNtw*Fr7xhC3Mb07Ilq~B69++Mlr zw)J9_VpqA}M*1BYwUZf*17wWGlUh`e-$nX8x#gZkj}klaZuk30e*m?Su{gfpl z$9@urTpbPWuaW)+;M7B-7{L}8MNMD2d5eT7jjI%QJ-BoCed>zTXAGQJ>5_{NpTBl5}o{|oB>%>}@v^5bu zXA1?oZmjjn5)I9bHUKOeW5%NX(amiTYs0cIXE#f$vmQUU zu{Np-!&1ugeEWTO(T4e7(o5b3b3~T6s9t8B= zZqrzs)rtm3b0+zI%54^_4;i-o(H1=0^@+7PY2R3TmaT~9=CQT_50inN3p*Em`7L5? z32Hx7#=F`w)>dVGgE8}QTgBR%v`yClA31lH+d5X?vWSKyLtNij+mN>XJgmcQ6Kh*i zz5(I1Veg}MxoxcNz&G~|wdfS)Vb1PI+r`?R3~NINR#J3!`&c`G_*s6AqsmMuOxML9 zd~SzWJCYlEf>kZ@V&3w1jI|S}r%TN(Y@@Mmr&v1!g?aNVzTKyvb34b{1>7dtyOeHe zWs-M^wQKqP>M0Y^=4*1h#@Y?YhW53ad4b+7*6vk(-b@tAvl2qTd#pXma`hyR(}xN2WKF?WrD)d(XoypH|%ciZD#R%Osr$UtnW}Ym{)gftm8n!-ZTXS zPrqlo<6<5Ef9p24thq<14m!xhQ`F!4c`wmUw5cLc`>qL zon95YqMtiG)-aMbKd7s;HgvgRvCaUoMY8t^m+kG&h&7yaSP|TNmh+Tzra~ViGF_4=bneab8>+D+4n^ zFmkxdV&$aDjbJ_{*Jg(ESOvM(cOlIxVvVR(SKmFk4ZnsXVvPi|j+Q6d$XI8VrMPnj zi|I3CodxE*ZHlt(<1c`kGHu^Pb3TeG>iH}2b*{)SkM zORt}9kIsX+D59OAlT^^msT zA20@~lIw}p3t+!6xTCT3C)FEkLJ8u~f?E#4R5u~kL_oj30u}aG4L32?Bybz1F0?`@ zIVslU5}{G^Xw>9bmx9=eYU_X)aRs?F)@4A}GN{{PcUi2vVNWtfv5M%bzsRJr(O|Qsugv>-FSTF{@9< zdZxndv6VZ8f3SNd*0W`GtEUX+1bsHva{!(bu4tFB8ur>|T(s$zKNo9iRT&RiaMx({ z!H7(aH4S_%I&8i-{I}c_rp20GePza+<|iHpJ8pWc8Q|6XM&WQCqfNi%34WH*@ z%_JF)D$aDSu9#n&TfLdFW>qz!b_&O3aUf^9S+Qn=hqW`Xx2JbJ3d^zPfZ5oO=Ix79 zZBDGYB{Be}9R;YlvF3sJv2Wl8G%wbC(qUzG_w+V+-!t=LEdaIV4NL0Wf>;YluGQ)A z@EJ6g7RGvk+_3L(9x&Ct5bH&d&>iF;__G=lnDiH8Eg~n7B8y!)$t{YtxcnSCNz_=k zIMz#Lp#eke{)R$wtR+At@wC{(;caS3tfk<-Wp>!vKI9TqQlh1?mQ`Pc!Na%>wV!3N zmV<}(;eBmLQJk5LG+UhIu~t-H*jtx*B}50!t%$V}+=i{oo}*UAT17hSbKE}JK4(X- ziuLlE&%MNveYV`a9P5?xb39(RyH{epO4`P^Ur&pBHP&k+eJ_kxH;ayjsbeQ@klQT5A*JHf_=9jb?Dw(KrCC|%2MaZ-Rmbo`#y-68cggw0&g}66k zy#?TZ)^@K+oYxo_y%p>2@@F_lI=PE>xwm7zQ~iuLmbc-ixt=JN)a0F5?^4G4HZrYq z@5Xws`jO|5;aEfg;%AjJ^j@s@$@TLZY+X&1@Vt9J)(7CWb|1z1xGXuMx22_ZlKVK;CsoPmlr%-Mm0X8EiS;SCA2HkV!TQ#; zt^K{so+I3+u|A`WAE4l?#@-jrP|*0!&tiQ}u5F#yu6_MlKjPEf=dr#CYAqi++9G z-B{lPv4uG(9WlavFV^=-`vEnU*WLik#^w95egGc!d3_T?ITOtMAl45-Z7CJ#XQ%Dv z^di=esv5i<4BcJ9rRPVnehlvCwJvi%j`b6g)`9am&A9jfB-T&M4_V|U{xL7)P41_$ zepXe;?bEx4;332PEY{D#YaKSB+gwPdf92!p7r>wX#QSJhV)1Nn?+xJ*glSFwIweHA=gnhD=r_v=`{0S|mj#*F+X)^7ny z+BmkOs|O1(_uE*%12qzc49X5z_q$lX2eP3-_1*nG)*ncQxy21$kNZQcKZ5vK@%JM- zU|O?(jP)n*&H3;UTfvp6+x;olpQ{hdFDjA>^MB(09P2OO<(4%c5uWcTSL9z}{gvE6 z8Q5p$efqDl{#L^>j62xIe~b0^s&=~qqGN8M0o~tY{R2F7*vmLj26O+2^-oai&TD3y z`;7Z%tbbMC+x^@;UE9m-zheEnhO>j_*wUe!|Bm&a3a`k9JsJHc)_=im#PP`k_xj&h z|0{uh=C0iRFV+{;mqr9L#c`4(UvAzPUk+bTlz-0b&-B+=`CfDX@ zNH)TKO&IMDLIpv7z(RG2)&UFKJs8-a_hT0Aw%ylBv@W?;!QK~~=hjWM9!Wo?Ci@9j zu@~KXiPoi^Om1N0aA1T)k(g_VHUSLF8rKkRlSG>W*x02|qn0*ed~BL% zGccQDEb)2Ecbg^Z15z7JQ(Z%Ei&cuRJl7}D=4E-#DrlzLJkb^);Y7^XD=o;MJKPqD zwgfKe(F)VN^}3~7CfW*o3x3cPlDPk)eCY2@TP50>9HVIcno#80I#FNJo0lay0ZU;| z-$dJx;j5m?c-d)3@Cdg}qHW6x&<^i#+a}tMv<*PNh7RsS+a=l_U@gKk6$iwnUr^|+ zS#@lmXa~ypMUN1U`QIVYjvzL5bsdjxkD2j24wRzI!Y6{!x9}1V7-C$WwE-$6CD9!D|+?Kt8a8iBs#K86W*-J9hvAT z(!PH|YbM05J1Wu9748LBb|`XC9i8YH@W4dZai4E?$0Rxy$W{<>)LOl!)v<|=1G9#3 z9@`0hT%zMaY@*Je)a;H=bOOne-o41;2^Zi%?@mZ`BDua*5MFQ4NNikpVxp7EN?ONV z>P|{@GD-VoLNK*?)zXs_ol<>jIyM&hY!;WNQxct8;TCim(?o8~&$&|*od#|LL?Es) z?zBV$Ne5a|@X(0eAnyeO6Ah|9pITnJP4RnBqPp^P9&U%bxSj5eVMpQ+^RoD3KS#Ct4k>IxO>n5Ao$jC%z*1jE#I{#RAW}>rd5JaAb zptBN<0QwcK8o;evtT6Ko(U7RI{Is)mQgfSYOw8(Rh+!J$IuDk23c7MD1WkF%KE)+7oq@brAHUxfyp;9f>-De9tRxaLp@RXQE5U zwaGQcpxcbD%^3WWL|x#v?^-QXL|3BjGTqU{J7jmFp7J}k195NRe=TZ7PoiG%aBMcv z4~u!wn`lA}3>u)_ZbG7ofZ+h}EQu*4PE0fj)Vgz4hntjWGO2RwJ;$*b%sD3~x)eMt zA`ZQlW_M|#%YXtA!#=4gyb@iO=<-?(%&EP3n_=eViLLO|L&TXJm8?Itbcjry8I z*8+!OK#wcLTDUgRb=6N8zhG6(ff2ke(e<^`I9VWgGb``8O9&co zO?2CuqL>fdmgsf>+l3QayE`!Ax;@byAYr{?hCdMtpgR)X2^NNdWpAD$kvQF%=&tf( z7H-Fw4tH0gyFtPnH};y-=DQQ!Qx<|kTa@a165U%NT$Z?Q-kaz?5I+fldzrySHuz+o z@9s-A@%n!EU0bz-)6Of9UGMi*mDjD$&zrK?1;nAtHV{(KBFv-`N@_Vvn~jcqY-a;N_gO zAq;cRCVCFYRus|d77@-Z(bVeOAP);fdTOF+6%J!%N6-EMlK z8DKU6=J3PKNc4PJ2Ja1U!3@mviDp*y8PjZfIT$FonTcjqcom%;uaa(7qS+O0T7~HJ zavONY%}z9@hGThUJ}c&Plb@4lF1Ss_`RKawurfE%ys9Kq;MoLNS~oAz{IVpi>%iz@ zexe0yN-n2uek9z2L<_-f{0{BxZQv!{Ell(R&{_wRU2n~w1CQVCg+wpbsy-bNn|m?Q zqOxieaj|`{D}`__O0>AdSxW>Fg<_aH^u>u@0=J(ul{egvxR(+w0SeoaGin@5d`Y6E zU?uJHZoFT=#>;R_gKue~WwpvVn@w~%o2QIriI!Ji`G*sJ+5#V00~WgFiB?o!A#H(i z!aW8}T9IgFg_{cmGv#B<-O5C(O5B1Y;+`l3HCUDCW$>`-&cG{ak9#@MD>Z0*y@^*} zN%Sg^r|8e&PSCUu{okNnZu8|{P4pUN0`ZBkCpC{6lih2HRs;Lan>x0)Z-Ji)`jM*> zy-u#*40b%2KXG%j^m?KM2)T z=H5^AL0OLJSm~WcEk-x|gG3*K+ppk&fPmxf!$codCGD&UVP%%Oj}m=c;bEGBx%J11 zJ^>G{!uZ9!J$;hsQ!t|fF~%Z|?$bn{mB7FZiNE_S(dPi6)6J8D)3#>!d7^Iu2XO-z zIF6SdY|NV6HxqrUte}IN-x&9;MBfG|ry)dZTh5$*JJEN*twV@c%>DOw5`DKs*pCEf zaNkYzJrKV(sw-{qZE22y9%Lcn@n01o-L82c5+KJlO z*y?_m=tm^&=OIATVFP}Y=*J*77A7p~c0W$^6M(R{%KZ^69*i&eNur;Y6|flb59EHD z=w~2dsJtR1wnv13OZ4-qnsT#w$0_#gHpBfq(J#mid<3f1c!FRkev#;xptdSTpFVJe z`(>hERdtvs(H?N@uIB4=ze@CLa{Uko-S?nx^y@^w0k=MO5sZLS^EZipTa}#3Ws~!j z8^BZUw~2lSZi6_w7&78a!e#s}(eJCGp;B*V=YF5)58%Pu$b{ZD3peEVqn(z2Nc2ZC z{g8zT3ojog&3)eeG0~r@DtSzR0Sjh#e@gV{>MMV^KmwjIJ#;P=i`}0S{e|4H)L3W8 z%mbJGmqdRpt6M!q_GA$JlKeH%-@wC=Ud({DHxuXMZ;Ad6>ZOOql$Ba#45Zn2V18&^ zDwmM??(d2ILCGx`jMY;h=xc%o{3Fpn$q8&&U44uDXQF=r*rGZE^7gMp|0Wq$z}Q~w zdC?tjcK=TFpBg+Kdum3E_41!Y|1Cd0p9B5BiT+2@&*D_L3eytjcy#|u^aXg>w=gSo z$bFIMOR$n?^43YypXE_ttp|GdWumVrV{_WS8;e}_;#Y~j1_}%(f<(k)KC}*x$6q6p z`7o?FR^fPro?3^rwZ<&Y{9UQ3cf4CC)w_7(9WrL0rJhUV2`HjV!jD^K!zQ@hQ|&?8kAzi% zS~)#l;`T_jC%FIV>ZmYN20YSX)U;=+y~quR1jgQws=ZR}T~&nrqQ9e>lIGs2_Ngig zLu&H!;PPUT+b7k&)mJ70$N!Z@Zgcyl+7H~?Z6PU}+gTQTukgvB8J{E@Kpi~C~ z`jM?RrI&`R5!kzfQyoH?uzItBwCIpj{XxQPc^7Er2yGEWnf|)|sRod1Y|_C8x&f&U zC1p#g_2PPWXsW|V+IS8vy+Iw8>TsYffC%;++~tKAr^8bnK~8XPj}iusudt^Kc}Ju= zlDyEWu6hD19+~PW5Z`fF;qt9-syiyx(cm?XgDX$)v~hH*W5@_=wwWh~wvJABOsZo6 zZ9dFL#0Yn6s^b8BXYCqePl6U^&$|S0$E7;HEWUcmaOl(VsZJ;>9l)&|n%mgyPDphk zU|2;omPgDJQ=J4(j>F7i zfm5o}!2{XjTciJ{ry2(4M?bjb@;rJ;D2JswqpZpMO2H<@zZ#v9YB+e9+3x1nOKq(W zPZa@rDu$v5(d<&i<=5VH*`m$a16Q0X0WX&~(O@~s33Us-xCTw_Bvo2|g}T!kPu6Lw z3_Q@Ax=}7ml~=V?(?j$q&w0&rd8&fkz-o-gr=$6ic15ZYpf>q~>&K&Y=SHL&xuzEL za_OfL>SR8(My5KGT)&8ryn2;r{<WJnCsv zsSu-3H!9WHRaGY0d)g1iJa=}gbHJ@h=$2a?^K(+23t~+Vmfha^)KsYs^+RP`~!LGPl6b^=2R`#|Tt}+TvJRSPCbWzgG^;b!B{kf0W41}>yGv4afroYHYYU6lvsuISzFvQ(D?+G4>J2@-dCsw)7jl>>OR;#{~Q)s?kcy{>$4K4K#>%Uzl3Dsp{W z0+}-oVz#>~)z#oOlNl!oE}Zd?oa!2|&;oD%N0+ZjbuD0689vY__G!e-OLblOeLq}o zn3&jIm+E>j8=Zk8M;7k-R5y?==iJQ1OKF*x*4>cm#ws_AlC{{oPC-s|W2&3TU2BJ# zHpmKhQ>vS*uk5wJI5vC=`q!7m?&egtkZUdAw-&lvQr%kB611=VUw3P&+bY}~lAA1l z0iw{`Qr%vD-*4{$hq~KS-BFdZ!x^U~=IYGdk?KzHun$^H?%eF|Om!ES%}fXCVx5!S zU8(M_mFld=|5}f`JJmgFYFtTw1806us(ZoxSOtn=+jbdigA>->o9aGtZJqHPgu+F) zNhj`0bw8-TKQeZ&Uq>%iz{PoPiF(a=G$_U1pXvchhO>5T?|7J+2U0y)R>}5gCf-Xc z*RcmvJp}59-E@pguk-GqR1bsOIy6hsF86S%N2-D*q%wEv_VD^hsz)n4>||60UY+Y6 zP4!rbfH9{XtbY^vwLtYJQGCBOGvs;NNb4zssN)2j2Y@pv&K)$`zi_&@>O^QmS6 z*ntY^aWhlRB55nWxo4uq^_`V!Hi$J5=a=4$cXp~dB{Uk(ndZ!JPO7;;fu!JVAox*r zb5qR&wq^}5ADi=1%_nWuk7pJT-p^09psdT2bd+lrq*@5%`xsm-ntXhTTbSyF3ZH83 zJlGrNR``WfFP4?Ao`Qg}*}a%*QHgjy7l+HK7FXYzZ&TC|@Tfo6El%|kc-ZyAxhFI5 zQmQ3jVYT2N5$(ezsg_os+or$`9dGp0-O^Ocz^y-wgYC9usg{F;3k2@o@V!8^3W5(T zPql&!8)$SF-HKEzN&0EFAOeVmUWc!RA26%?m8n*dTTb%=I6?oU;8vx289W?LXIW$m zdm?{1)hku$;Mr_CDugrLE2&2+aHRtEpZC4;`$lht#>(QmqEEj;x+C3g@S8 zb*k4vLIb@XbS0lN^@i6|y+Lkh2$4&Jg3cSM-UPMjW+?03o2lNamFjF|_1F--mFjI! z8}oj=I+)W!_jamx$}hS5x4Cyxy-V5;fN6aPJNPB;-Bj;YczGQ#jZF7ms`tTdUH5Nk zLzDgeR3B6YO@W&u8QIkf?t@exf?G# zJ^=|m?&ej*i(NlS^(m<5T0(omD|$Hhyym$3G}UL634LLDXO`!~XQ@61w-qrs8R0%p z^-YptR)%%eUxNRORNty<4??#fL9}zLG6wxts&7-qdOo@yYg6~_RNnz8*N$E0OpW0w z_nlPVE$biJI?19^x$ma>UR9J9Tl7Yl)#u#zQhgsh&>-&`4SjH1g#MKOeySf-xn7cH zoSi?lm%*(5Ak`1cpFz_J9oMn$hpB!9WKC>95wX$zDAkVvtmgyHJI(z#)lW!<8R%$7 z&eJ%~{Up^-0Ru(p?(H-mzJ?|2)+%YPAk* zho70)?S7H!m*wXan~iAvm#KaQVjH%pv`K?ihV}VXs$Y{~^I_b8k?>!q`VCN^77-^l zmz3Y6`Yl*k7lU|&^ImX&o9cI<*3A0x93$QCcd334;+q-9dK%gRE8Xu?{Q=yMwY{dA zu$-qDT4xfQKcxEOny;3d?lJgW_s3L!0uQ5OQZ-a|*+zd#_2;U%O{F=lGM7SsPW2b? zFv2Kt!QYH=e@XRMz_8%X!ee*0`)jJd0r|#EWq63C!VSb&ce8u?TdKd;YN>BTuE-7V z@2UO)7zkcBaWr|{H;U)}k?Nmh*bw;3<2?7zRR03;LlD?TQ#_mR{*~(A;GrRn=ynsg zFV%m5Y=tCQo%>I!|B?(pg4Yf&C^miQ|EBsM8TKR4{tm)R{V&xQwaR!cf}Q>%)t6(fwoyhdzaIAy-e#@xnBDe+&>|D{~GIO+JM|} zRu@Aew?U>20c=oCIq6ilVWy2p+N2VdsbLsiekQq%GHncKV`)Tq~#+f!LA^eAV zMafMvZ39DcXE+-8~jfQRwoRe?jz^~tn(Rfn-e zII8AhcahsX(-yTl%G-s#ByN#uOK?9F73p4#NOl@8+DqJ)nYJR=6H?>EhzMgr(E_u~ zU}6pCw#u}1^@}FlyG+}c-}3u2y?%&k0&bsahYAlukZ>sC{-)@T$aEyQwUztE0(2^l%yblpO*zM;sSpyVFVoRg-9Z!0WV?*Nxk7bE zXF7&lJDp%&vXJw8#uhyE_NqmI+1i3+6nMc?!-(dl@)m=!Bj&Qz=58W>16P*pa~BN18KL2 zlQW$HY?BCy;YNE(rc-O>DwC~lcWS27%5r$&K~e3rOalSJFT-VycLOsG0;v(?`Ru(H zF-jYhsSeyvgk394R0P!`7t-tMG7Tm-oRh=RU>Xnc8=PqfU|3qG*H6G^MMJB)r(u|A z?g>pLb!aBlz8-9b!JPZbbUL6ltsiF!y*xeBuo9t{7UE@CrZYfHuGTrhosnrcDc{7f z8jNgUQ2}9_>V{{E$Sp}XmOHFGyQN2&V(|YT`I$L!^AbwBhj&F6XG+T7NhfizDkT*< z+tl2QZ-zIuqP4pS#)GXJ$I9Di;n2fAe)`Wg1oCfs7i7n&(DkI=jNl zI4~$XEOlpRItScF^Slx6oJ{AE3S>5GZEkFK=Vm$&$PaM%Asg?cw3~S9x(FmJpE|T>FUnL8P#Y(n zKHwEza`l-SDm+vi7G*=GM)0s?{R>Wr(J>YEg}JUVQ&agBUbl#gWXvkkyrxXe;C^(k z~~YdR>YRbkG@XKJr% zF&FP9#xkLKd!`QX(DH$3wz7yjGIfG^I)cqho9oPUN%gV0k+p_T<2HCnrY>+lv|cP1 zI1Lsqmb9)bQ+Mqvp1EwFFJhv)GxdPmz`)sFjjX*VQ!hx^O6K#`-l=;tO(=`Og7n}6 zVM3;fAmOgi1Q*+GE(IrMngm)~59YfUWeYbc)8tyEM*PgN&E!m%0*38~v<OvRmI~%4An$x)RtZ`)D3xuFP~5$uRW| zZRmnrmFa4bFw99ha#-CEcXg&~z-s%*!e*@Tj(tt0Yss~4nQn)vZ}9}w<*vp zLpluiaH90MdotZyBCvI~rti&kA4vE??%~tDsA#UcFVp?tzT*|uKpEVh7R%lJnI5RV z;)cP(_kZ03nI5cgd$lpM95aG_Fw;ZeVVb!sje}QsDAU6=tP|fBZ~_l!dIT)A*z6eG zBbgp8k^U0_y4<6g9s>!hy{7}4bu0H+rpIe&>zH=j9x~jIXLY9zPe{JJquK8gc&%S$B1V$JqK=sf_`^UDR?f^)DpwZW3b?!nrRxCt*S$fNp{mR zO$V^1wvMrgLT-Ad86dSSW3d}Cb2PF)Pz-lGe@^nu&y`+s)222h0W#T>_KVx;dHV0@)HBHQde3G>?>TQFsqA zp2OZ?mOjr2!XkgzNKzSrln;yUW8`?5|frL&9n^Mn$+L?a4;gvGA*wv3i3PC(epYg zJmN3Uw1QmES=rbS@`YyqxfPjKmOtikQ`yJB)~(F6s=`gzBE(l(zUpF^3!Epusz_LU!*rOy$NnZ+#jc+ZSKuXZ&d}S zq4RwmN1*AYzLn|i8je<@kz1@;+}oMnDe=`)cpbwH4y2&ly_4x(aO>}Ad=Eq6-p%x0 zRf9R>Gy-ZN9p20IKDg0FLT|Ra_cMJ!IvlOT&~vZ}`ykVY)yMW&Xs)wOvi)JEk18C^ zQ?6frh}=h+J_fhJ9e_lmYhaK2IMXLUVZ6LGmN^tP+V)ANPss`EY~YB@eVXYr0Bh0! zyKsG$>2uPy1>)xMguU|euFo@l6V$fV`JL{YnZ8x4q?;H#-^%oDfO7UMlteHiwBcXk zzMbhig<6;uMA7=UyxQ)x`rVeZln%$2w{kSS>Lue0U^H>@`&h!&- z-+t5AH$@)%>t6)jPcr>VBW;4;AiZ zmL}_BvHl^`AHn^g7*W7*5XRRC)=Svy{4vv?$PI^SM;DGZ+uffs{Ta*_SJctLR{V3O zzW{`N4}C@o`2KhH^ui6I$HHUR-!lCj)P{0&H!hs;y4>vk zp6MU8S{pEKZFB#~^v|l+aK!q*?w^_d1s;}GG!PBle`WeNh;c2fciwH-7nh=7oasNn z)}7a`g~Kp4tp8;CFId4Rq!tD)lyA|^6O0Q{ z*qla~zv6XrtqUF|i|IB#djZcQ!D@5eTr8kL9b8QA>V_nzU)#x_M)rYiS&-McNoa>Wo^YSAYYgEOX z-R8Nr0P>>{`Vh2a;*Vs4LHl%%H>>Qfow#l_Ei2vnjJa(Fld`*byZF6l`)oX7Y3=oU{1-D(U z?ZLy6fK6*11G}+(t{tk%%~|_PZiieuf|Nu%8}4?@wNq6DZ||7>?v!h15bIm-m|nMY zu3bomibuj6nNy`*a_tJZ_UPEbXe$fZ;jX!MBiHvm7`@n~e}>yF*Y4n9G2@QAtCjdM zZueY!RHbbLn~J0N1d(gcTIqp3W6gsnD+7B#FdSEj4$+a&?AR*=ez1!`ZYd;|04{Lki`z=s`$@lilwLiImFtr3dsQq&t z02YR$uD;Vh5FU`LA7Ht?v0dwz>p%cM0%o|)9wYp<-9anv8OrxDb%eea8cNINOl$z?fn+0Vf&j4F&Zea_Y88eCOw z6J)x`3y{PQ&NZaMjR!Ry`ejJUhvXUx9ySG$Gkbd6&|CrvB2q+PJhgHFn0?TT-ao-A zenz=Yr;N={sXTsqu3;dd^?M(Bs2i5+3;L6|xuV)vW+-j(emG^KTrqfPCq}Z*cDXoL0%Tip6oN5}Qqb*^Tq$71-*f9QyIYGp zljh3E3CphzKl7ZKS*{$+FX}Ls=<@P}mgg$KeH+8X+CmC19CKZfYee;xO(3rw+`Oi{ z5xGW!mt%?HLAM*3>r9~Vql}pjY_gD=We59%rMR9?*&yZT%WAhu?B2H?ujkgKt*tl3!%GC_A z)~uPQvFBZLu9gb7wQq(w7XGCr*O;=_)l*JKzJfQtF}cRBDT^m6zX_jrV{^5ZW&5Lb z(}aeWYt3~rm>=$vFybT3LVVaw?BZPG$Svmx>7i-EcDr%8+JJ4a2GF(ECX?#4ru$v^j2oY;y~0hU`9(ijvt4_xjtaNE0(s|_vBY)c>IC=v$I#Su=DLKW-3U%- zb(iGoA{A(7TtB(qb>-?Vt3j8xnX4w!Pz<2DbM@3pj%en^zb9934MCL?Rp49`K*E97 z(b9tX7k(#lO$00#V9;GP0vvd|iMb|Kxuy?aI&bzz(+W2!*JN_7?dRiR2#Opx}qwM4wH%NIZKwXxh# z3+6{7h|Pm+Cyd6mxvnEOa4aqL9319a2j=6tT-R5h1(BpzS@l$6j=MhB4YeP_W4uXw zZ^(5cn036);_SE^bKO)H8e)PQ3$AxluA9Na^p8iN=5Ee)3rNLlw<4OvL#ewZ*R5s2 zCRF`9#<*K^-3H=EY8vK8HVO-P9K9{q?ciYzV6fstYTusg4!|%H4Xvz|$?lF^cUBcl z#U28+1tc&F-JQAas#Va50gr9$yK>zPXwB+xYPiTf&79%xT=xKbGQkAGp5K$}-rCn^ zG;>R1?cST~K0u>mSu5@$?#p#Q=|FsuKcdBSf3640A_U)(dmz_?r2Vn}G-u8tl<#`n zgSj38^~(TFN&lWQms7*IYYR1D@k}1d^)O{@;QRX!zYphn1i*f6G>+bl=sl9_Q6Os& zH#$Ps<$8>?AIxfcSMdD%Sgyw_+|F!Ml6(qc_;{`-%J2K5SMHw3^(1Ng32r?2xJ9O$ z>l;AjwhK=5j3|VK_KjRqs$9G1tqI6x!i6cho+_*JT+YNc_f)Q@fvi`nryzKCPv?3D zAn=rdkK~QO{0MVTXDI9e^_g7HQf94gVY$JJ@w2&}t8f!g&Sdv3<_7y*uBjDX5zhs1 zX;X7e0}p4!VC-v?b^DH;A# zpU*Y3s)RQ*7%wmC;00A&|YKe|D}p;Qkow#sY_3 zI49R!ps?`qhlM8-H#gV3vKX=yRHEzMyj=5vd{_KSm7Nz%N?@Dk=UPB+*lHYxb}ya{ z*SsLt!U{KChTuJPo?Dpf1@J&M>)i{vUaTtrKUyh_`HQ(0ksFvGe~rL&$SdYA%C)$v z-mJcTcmZ@^7w39ut@>>3cq8nvvR=xyr248F9DIDaCApS@+g3%OV!of3=2}+O6HGkp z1<}GASR~kGxt6b~X9Y}asDF8`6}7LtcV4?@6HJ7SvBa&&wX(`JJpx{<7%+1HYU_Gs zu2of?2r$rK4FkL?*UR969^j&_vBSNb>y@gaU;q^uqfpT+xn8X*GBZ|xo8^3eHP>t4 zVY)HRH9fZ1a;*llokIXG1dpq8y$($%<_!-lATCof`6?u}e;f|N7= z0^Q_^6^850TyKG|we;aCaV`-2dc2kEZE^z%?jDN*C6&LO>m5K((9E5$+0@N(@8o(H z)EYM+>1Dybo9jIQ|BEJ0SyT?ud%51P@IZ;|f&WGKey$I|t<9s0VLE-J`ykhcAYlwz zJI9)&<-=Sbff>ESOLw#TDA&iNZNMiqk8L&oY9HtN1jzrex1Xnl_=Izx$9q)H#A}W;r`lvmg{qH`w`CCCii)+Z;}p284Qc*t09a2X0C5lpO*%@^mDrV zR<3V@hf(9wWE?0%T*M`fL;8Ft|u&g%S8t{;Pj z0Up?dCt_S))WG<@!00 z4c(v)ObC9S>ldW``YH)Aj1Dg4?63Ppu3wg=`xEEg{W90DNE^L5D@)w3a{Zd5^$kuI z!;oL+`c0YN377brT)!phE4Nh$%f}A3JBMi`{x;X|$hDqy)}teZns2V(mk64O=7{(A zx&8nW$np>riad|>hg^RIwH35_N*zxUydjz&k3Z)6Q~A9aGr(H^Dc7H?8twd9=>DAR zFCbw-cKKocORm3`)zLuW7?niiuettKt8REZPXGRv>+j{q_=tpjjCFs{^^X!75Cxm2 zf8_dSRiE9e&42$YIF^6r`WJYZdESESo2c?%x&B>#k2;or`TTdT{{Z=6^Ztyz3b2v3 zMZ7ZqC)a=1)H1e%j-$$(>wkbYmaU!MbJ_oLeF5TknbAJ3GIq6aU*!4{+~$mz1Fnr< z=K87xh)~u($$gdUYk;t7aE{T~wuOU8E;0AW~h@}r_j3K z))+|q5~h0HLhDr}jgdAVffo6Fy+Z3(xZQ1+d15uqtzT$^vW5oU+_0+LpwNaOVH**v z&}~>~BY^U}MbZla-l)*VVAgW#vBAwPu1}%Of%;mn%#%dv^Om02^?LI{TafFwLibpx#}bs^UGrD6wO}tvCvLsO(!(EoeJ$t$|l-IX;_onxzH{kVOB6;z%!lOrO>WrHN=KQ zX{E*OT4*<*a^-~g%Tu>}3wLi>PP!@ZqFkK3ovz96CDFb3Q>-M)qP zD=|)qv2_YbL zjxKZzP}oJ|+4jd2I=1@OJRqBgSW|yIw$O3lVFJ;gUFD7|bbPJ05wNwm1uk?#4H`@o z(|UJ8p%bh6j1xu865TX>0T((6Ja7<0yTVK0WOq`bldIy!L72BWvzj}(&?#$b_JK4` zDRe4OSZMZ)f$s~HZ3~?SYBMpR6_tR~3Jt6(3~%gHSI_35W?-Q~<<|pINtau{L_3mazmkU~SjZ7h-BGRH#;3BZ>4 z0E{R{Hc#qtDs*~Th@HgS`RRp*0oYGA)VI1}h0Y-9=RNpN#yuVFJ)_X@3b$*_Dz+Pn z&~A942)sP6@w3v=33n3}ib4Ifwl~27#)Xpdb1W`9dRx2A<9M@63Z>xo>l{TcEtHWo zx^>`5E-RFmANhw9dxA6Io&zj|mLL)%>@*V5N>{HEwO(lpLQD|gUk6q_| zNL}upBMY4g9@b-9s|6!Gv(Q;JsDT5&$(>bbRP{9%1swTVIOLUXRH3uM1FxTX4}?K- zadx3|st@pm&ofMrJfBnO+zR&un5KGBY@zeOtvmg2eUJF+-p)ugLe|S;oc4G>SC2b2NL#j2lP-~eS&{FSO3tddouLLM3 z+}_27#({)`#@<=j@1_(su25SI=N-es%wVhK+6s*a4+LZFiv_GHj|wU|ZbddJ6RdSl7%Y3w~U~dh0DT0lXwc-JJ;b znCS_HCW6}LM~MK*_CW`^iG?PCh0bEb)_iF%!Q$PdLX&~5ot&0NN+uV&6vVopjvVMN zEp!=4Kd8ZBOArEGR_O8)_cra`X$fTP@+ZtQJ}&9edRa90$%l3e>age2I( zyDJM_1rmDD)!Yyi6|X9EHE78_cR}cA+0})v0qkp42QDjIWy5Sb?Q_d=w6*B82>!ov-T$Ptjh8w%YBZi6zSuG`&M z=q8e(d5n6yIqq%`2>uE*V6=oX+b==CiSW*o>ixmya|TGm!KVwk(N&}}4b zP&lwnDt}v{+iO+f%&Vc>-CpPpps=`MF3k>Q1?2CJLU&fUy(FO_iFVUGcW0ryz)P8? zcUVQV6Cc_sJyhu7HTBK((oR!TdAQIc;3ZFC>SgYcLXTEO%|VxWx}MG`JzD6oTG1vZp~XE` z=y9OFwwi*R5nEUeePbx+xyK7VQRM~|jBp|b8@wk9JxQ*g3=7O;0Y1QGK&-3i{OrdAX4{<-w{g`lZg`TU5@@#8wRj_GG+;fGdf`>`q z;yuSrEi|n}>c_Kg$GB;QrdQvZ1q5*~?M2c}FEj(Z@0uYC`X@npHlxtO zESeXO=L^jw*LL9$)D^vz#LPmoz`_LD9T_JIg=PblJzT^k(Zuho-0VVgYDF=4Vsp(Y zG#AMBqpsdB-U1!j)1%(y@*#M_Q+`>XH zkm_rd*o!W*H&dnK?{xG-Unuk{-anElpEg_cw`*#*z8W$2!`C54uP2Wn_M2+IPIYN2IS>5?k3E2q0a|Vwgv!ZB(#a?Q-uHdXIEC6$aN&Hj&bMh296V(TAyrrhAvb z?-%+2v|N(2(MPq5^t0}RLLY)#f6+q5lZUBAeOTzDHHBw-^=>269~Jr-+`2iSc|5nD zj|+VQ;F+Bc2KbXgpOUtLYUQbq9sFsb&p`TuunC^_`W>c)7YNj6g+3=Yj7axnl!r}C zf{O$eP5%#VZyBXmkwpz3+}+(F0n)f@C+X}2V)S(ggtl~=w1k!j?(Xiyg@gzRaY4es z3=Hn>?(TehSKa$0^S%Gxwcc5z*VL}M^^}~dI(6#EOO<#z|B|D{GlgDj82EtEEi_&) zSK<}s=9`q5T7N=of8eP?apq!sr4p|$FGJP-yo^p5@8))fy;_OaSjLSDc>>2AOWW|Z zO1w_o(*Z-jGe}aqyNZOXZJq6?2SsiNhDX(&}*$MR~Pc``(`EH$}8ws&6`w5 z8~gNDCEh0Jw@uy_>6?bWSL@|E^6g5z!z`^Y9s1R@9DAn{?-KGqS6r;%T%k?zOBS}gz_%a zvXNaAQ~X^ez9;UNW*g%dw=~J5>ibIkkk`N<6m_(dupcV%BO$GhN5}A?{>MuE#I$~u znm?19?59fnOu$bk`EE)fv#4@Uw^49ieCH^8Jn(xF5g7;7P zS0(-?s9zY^t$$>HSK=S0H)h(+wOkds@ZQu3deHuhauYuoBDY zhwHpE*p&jTOe7x%zWuOHI_b2P1FVvl>knZ)ThblIi*ZHYn8|khic60&GacQwGDl(Pt(}b;AG~5!D>=Rbr@Z6kubf z)%VleZQ}r&Fy(&S%jo!6PkvVPL2thSHf65*n#bMRG{9y=TwnDPNvRll%JH^YfX(w- zPwH!%2iT%0#RaD;J1K37Z4qG0yuN`oE+*5K0k+CZQlL!mcFT?yAS6gc-sKm5fxRCSKvja(Y6b)Jt1u_W#q`V z53oaCg5pD2CfW`Gb|mC}NZLL0yv18Z!B^}UU?=9fLGb*cU0d^&bC z_F{Q|ZjsHA?YbZTy#nmb9Boq0EuifkpbG&v5`IaOaQL3wB|sT*KN1oZ@_U{XWdZgf z?00_BjSN+$k%MrXCn@PXzIE>tU|*KWPfdSt`$vg=1MFA)n3K^imUOE+Ai#mdT`LORLFYM~Mv;6FcS_6$1~`aiJpF-8s=K}%6yRW@ zjx6#WjHkNX^vHF?!2u3ou0}_pkm~G^0EZSoB(a)a&ZK``h>FM++o1st%Ri#p6xZuv z0S+fnA}&eC6eQ#D07noPIq;Zjv?Br>$+T;W23^8jDcblsJTkyh%oP>zI@{4W)Q$>p zG!eCqYKPPmI6A;Fr6TTi`rBfUYIn zs{m63HQl-f=$7M@pEzr5F77t#7N9%v{P>qH{Qv1ywtIjImMM)Y6el9@82DdgeIS*JKV2iG!leo&kCh*U;3^RDySvUIC6H;wQUn zgTk$FmpCrK@kITR$`>RGBklMAy^A_I(3CdF>VqB^0`$r2hEMf(Kkn}6NS8H!R) z(>FlBQjMen2Jf?e0s0fuw6u?u=%jyu69~9@l{T{cWKc_hKO~*x69QBgxlVzf)y#7` zCK9$*1_+p|jcs86UKRuhi^BejFE5+YII2FRG}iIDR5cFO{sSVHzV+y%uvV4ugkMsZGbu=n-JMs>qgdcc~}j-x7Gz1 zlz%|EljKx`0@M@9$zYII3vfMI8Evw^Bl@%KLT)^ZW3dzz+Rh4ac2SWNHFIjEId*n{bBMc*k@qg?I>}XwHeoI-&*PjE z;N0R{|6Zd<+8K6kfb)pwr>2ijw)D|!xhI?#;C$w2z`D{U$l!K6Kfnb2sTDq_oD z65vwix^C(^%xfXp5m`ge<@HY%cvJ1t0GAatXwQIb^$VRe-BmM!V>7 z^m=o3fNPi(xkie6C>!@{0$fYX58-f%U>L8NT4;0%9N;=;xL+K_H=8APU4ZL}cp8)M z3rZ{O`T#c&bPXm?;GWDW2DBRj+(_Kha$8B}a$|s-2>TVowl1MW^riqe7gbOi=!B87 zG`%^%EyUg6>s6cXA94m(!oXVs+{#=n(DuO{ZFXyb+lpE|TOw{_lHC^I_PiV&%GKNL z0q!VjRpiqN6r;Gvr%upzM}Rw->qgZRg4-cT*FFT8geG?exQk^pGA%>tRgsP!0^FS= zi5o(@JHS0e+^}fE<@9VOY51N1_Y!w~@+JbxrMbJCuX_WGDsmMBglad^#LTzKQ2|C5 zxwHr4-bU6&HdwCZqXUd#t`;w~O(;eiX=4J6&7tNFnoRRyZft;Ygfwb=cc-u30OOhV z)5JS|9fhD|-Npx)kQd`Sa37lxU?S6^Q=0tp?3ox~5&=JtgFEW$NHLQFOfG%YG0Y|h zxQ}U1%QO|Fb5GqV?Y;n03S3;V6f@``(53{KN?bqEAjg32##o7iIk{zV{PVS2OSA;!M^E5PH# zeam_@wv4Q`#{)c36!ljN7skY%2=H&>enWH5#d6vk;6Hg`svuFdvtcML8Yz?x@Fa1q zoL-XAJQ?7rQl*?^IY`%??5P0%C7$nEdY15KpOc!}e*-+t+`JoHG*1V3hJZ$m52~`A ze3-Im{;kMmy%6BV zB6qo1ghS@;H!lWwiMgWcvuf<6053D;wg|-$emTG^Oy_qBN*1dXnCq1QuM$ZvP?RO-} z80%X^(r*QLn{a8m^`^=3&x0(?x=PhC5eZgd~}IKU@Gow|F`Uk)z@OYM^YpO$cUmh#Z!S^8;!&xm`Xk@Dnc z0X{DQeJgv|=K;PT;F$ql8l38kvnE~sPVhy5FN@l99*6I(GwjO%UlG@WAzQ_TJJ`Mo z@O4qt%OT{bd76D4;2Yw8*GC7L#47tHz_&$NK7F`#peL(u1AJG)X&E5XRyhUvF2MJt zI(l=nCFy)0;0Iy_fsdfgP^0}2;K!l@ufOLF#C{C$6LG)5oQjBY^Y{w(Q-GhDs~KE2 zs;sPRZ~HmGFGSS8$~v7ZZT3rmUkQoCmyPOlj{O?oH>NefgQ>LGX1@jaoq!tT9rIGw zWxogbgPwW zpuCW2^$=?i_Y~T_JhL@ItVzI)iF6BTn?^?4zYtHdHAAe$T;6}Yxt1vF)ZG+Qsk`oulqme*5} zzuwjlu>mo^(FD}xkVbQxZ4hEZ!v6elK0Iv05F6#S${>@6n}568D8$CZH(@vSCYvCy zR{*SQ(pz*qoT3AuSjY6PfSL zLu^4@L&i8Lwnd07OP`i23Uh;P8Dguv2wh6pRw1@7YMMapNC`{F^6=d{#5Tm;)D(hp z_iirc+O`R?ZSj>(2X#q`VB3b+j<_F|CW@bHY`YNKmmnYiZ~G8C5K=2EMpF13Vn-&` z<1!~C-!a5a1l(`ui-fxsFFD*^9)X~x}nfQT9&(o*qym<$CQYGqECrSNiXB5L9S_>W4njggJslb zNb*H4V2==;2x(5s=vm!5h3L$*j?O)rt#gPynNs%|tJ3xiu@{rBKi<-mR7z^xE5zQ! z{k&8DBwOmeLv$ggiu+MJ)4GHxV_N%IA1Vv*r^`a@Q~Ii>bHHxO*ia?#?N{Utw3UP3etET9^L?R+*x@8B4IE1-w(DjvMf$~R00hN2I zmfwd%LLAC6YR99uFPmwHhB%CAKUnotv*02*EX3i&T*pex4n-=5hd82CmZsw^+{%v# zab!_emGFrd-dyU-9uCm5;0UYHc1`0B1Dh;OFoa$?n82&9w9(bKSS9q-!`S_N9Q95 z(KG*?oW>H$qI!ntMZ|Zq+u*ukG?k?4Vy_U# zj{5Ip4f=;Tp{PJRhAzW0Ksq5rC2>y{!yC@f994!0in94D1xa?U1tG!$_c97cd=`d? zN_8-f8u?L+Ld3*0)cmC-lmW#d5+a`9>Dxz_^6Bh|Hv9)H36YlSsMme6&C(DVG2glN zst(ISoJb&-2`-bzeDz|gofzUIW;nv2)WqvyvBf8a7*OC`K(s6M=h%P{Cl|O71?F2q zHH?!(oU$C(f|J$G7&|4zz~#6TLGvy=&jyA#mAHCId#TojL3V10Dk83z6q2)rej5D+ zu_{D$UcQ{#M>Ta;9ioPaXLkovM~tRkZB`SamZ)eqqOqT164i#N%Rdbo7~OKD)rA;D z#C4imF$Yv~AnFu{s3-2HltL(Z+NuvRI4|pz87bUzq&_%A199!Uah)}UIE^U{ctzi! zU!|QEVn`0qMO1s04GGamz;#dWgtF41FMje|^v7?FA)1)$e|ac z@sOf_9cvEJLfm(}zk3d(CR9s^p+)^VqGSjxcX)oU85-hr=4!R@0l39Z57AoG?JX~; zm(9bsHAEY6O$%*?JgWVDz9iV-13645x6DGFFeb)Ah2aR#w`9LBi=^g&*{&IoZP zaZR;+WphaF%n)Z4MR{`b^+fnQJ1fN51@6yp1@xI`XNNe4xPGq7&<@I#*x_?RoJ&mm z>d5A1J2%96Olm|ZYSX-&7vg*(n)$tZ+W8?aV9JezuUbo6mW+CmydcDd%vBp1hpA5N z-Gw18BINdQx|+9(LR?%_u!13czI|OB;u7YHu(~jk)KI%5#HBf~Y*deK-R#m3ml4qL z@Nq_*rPB+y%R*dE-2XJg5!H^g%R^j2$hFn;#QHnOIk2B&SA@8-$kjQ;7b`xi=-o<8 z&Xpmq%74bup}g_YA+lW+;%efaK2C@#0(V|q9pW0I`tct0_pYkbo@qDH?s(GC&DXW-L)?&8M!SdRT3U|X5aPz7sO)secJO^~n%x-U zro5dYt_pmB?Y}9 zZex}wNdD{uPWC+RfwzUYy}%_2&}BoM-t8goAnunwbupb!P6{3U0d+@+JDHo`Jv=9< z{e7w38R9PHxRw`8j7ZDLOdPj3-|h-=H_M1VIK{L;xI4r>1oG8Fw`8ty)HV)rFLBq1 zVi>5r$I7OX=eak;sQfEN>!44%hCw4G^cWRlH1YfzS}PW%&PInALolDo>nP?Q6Jl)s zx#rCET<_LnLyRNtTGz@Ohm8v{J_n?1*ly!POd#MlJ~}Jo?cXMZm{`;%w#{8g`ciXZMAe!lc-Y?sW{$@%^GebPUT(=_+WlV+#Ld;^?KZCT5WH=piPiL@4vqH=+s+YDtpK0~i zW`}sNz{OL@HN!%3Ru6`lQ{bXY$=K+9$mWEYOWf}V-8qkKHaEn)yy&t~9nB5$a;Zaf zUWoa`UCX_%I9-qAT0kal^Fu6PuBI%cZ#k#Uu^`04ye5`f;#~O9TevL@v8ccc4;;J( z*rE`NbDaAkB|gKsOK@-(hgd>fqZ0P)71)vxON;OQwcLvVmWFtUxMro?MHYT2#KQzc zlVUsRSM%WzkK{#`jY31KJrd$k0-ojM>rtJLB=Km7WrTfaUCipjC|6>TWg#A8t{=53 za)qt-ScrcS5{Z=!ud{!Jc$`T`OWre?eAtY!$3r|pyjUeX+@1*W@1kVk9a5*$zeD_o zcXTyFDA?IRd^PbPv^H&xLrN zh`%(@#Uo$x+U@xeFA&U!!D%Wk<6En}5aPuG*JDU-2Wl^dc&SuvP**p^UJCJYUXpTH z#z|~xb*5-9hj^u^LC1o;&&xOED(1km z{(guLh-<338Mh3!4?=uMK&y|y2>UR^M@;)$gTEp>vo-rD#K(C-dSb1!k3)RIv~Nz^ za4)I&B*dqAp}`}`hkqL4Gp02fBvTjUEyU+UTz|dbM0e>2?eh>{5Z9ukM!$PD{367c zg!}_h-r)Ft%C-?4Cof(CjyQZ=wFoQ!%rc8CgOT85vmqEUy$tQ5Wf(2t?(SBj#O#qc)`j9 z+E4xx;@7;kGQJW}FZ$OIzY$sSw4tIF^=BWM!ma1G5Wh25t!^NrYrlv1gK14z7kdAv zDImx3j}U+6g%ncK{tWRK)4qY?WH?NUJo8tGzlr-jv5(Vs`a8rwC8&RcT(tZ{y~~&K zf#ONZ`xsVY+STSA^3c5j<%%msSedwIARX&b%`4i<5mq7UhHJbFL%&LdRf+gHEhmpl z&F@tstVYZae$8M$4YfB_wb^PBRwt|mmQ}mhfwp>tH3+$1pFoQYx&2v8;m#Tn*3662 zF-XG*4#S!e)>>XvLCLkDFSWHItWDgF@WjV1kZ!UYVSg&F9bp~js(D=~I~XS3VVwx; z7GF5MuabyQ9#YqhupV=@7u3-!+X%Y0S4B zBkV+6Js;T7U^_+Fd3m*p!Q|w^IS0RUgk6~HwuG>vzwHuX*HWcCs&rLa$n9m<2)hyY zyCmIkQ@&JdyG7W&DD0FA*s=#G^w~Ya9>g_jWzGf89uYbf1q+usWu-#Ah}AVUTUmsCh`HNvh3ykzU#9#T(Sr!@WsLsB;aWiP`o0nNV{X0(XVDXq zR2$~mei8OB@Zt`w^7}_PfVc*>u9;7v2ShlKY2V2D))w;Pc3^~qif?(iQ3m1u+CdQx zChj*W2KQ^JvV$WWLdcJQJsTq z=}(^@+&OutIXuDUZy!`W8DT!m&)}+Z?UW_{-cGj*U=G*bTO}7X@A8D~1MuJ6m~#u0^h1 zai#HfUr7b)?Fn{bgp+clgSOE;PELw2fQWC} zo}D|{fCwiO$ajdk##-uAoE+g4V%jD-$977DflP`{c|f-?G^i7m4vcUrVb>VHyw!!- zWT?h)|2j276?5}VfdVOxnbcUSB2*JsBL{~4j<4uz)e&lls7YO@0#a)=5o(Kywa?5Y z>66>x*hmq$HbNb9)wn(O*u&}~3@QryXCo;p-p|6aHX9V7p1GRIfi-QztUkhErajHd zL7EMY&_E<_=M=Wn>wh#vIE}bt*Lc{-cACtbB1K8O;$=LiMHs>|U0J)+37}fQ|NZ}L zNQ6e#rg5N&*`Ri7jL<~D?+@K+bw%?kvYbs3nhESvcHXta7O->=ZDIB*%=Ye%(14HT83O?1J8_b7BP`YSPnZY!r6H} z{xmo{!Z`%;4mc}sy;Ex+A!B_`gmanese-zJ75Ya?7oz_nAtRC)0fUvyoB>xpZ+dhrHueS{lIRnhSa1?)FO zxRH?P_o$I}V}zTEdYu0Q&ym~$U`OoIk5@=k1&Ex)7xM>fOoXv4<9iV} zw~{;%$3_@ORMg4<1Px7eEfHZn5p`nOs3fVd@ew8v@MAovv1&Ni;DiVhOO^56xQ2#( zwKg%rq!LX?e zEz0>5z-c1d)Cl(z_f13tWxf%n5fF`4oz`O0B1|v7^AbK8bWgSE5oYAy$$p~VW<;1t zz%@;3`g3e%ga?RtN@t`PGOQ0om{rs!>9*`p_}6Adm`z*+S=LMO8)aTOJHmqm)rG!U zP+<>7m{WYLRWUn1Eaya+OWY4?SF%0~Wi>a#y!_jqiZ(tk!hEJ3A&aY^tsogtx!jhpL6Iv>aaq5~3de0twjjbn=BjaBTyS=+mW2@(5p?4&UlCN$;ALZuEsC(1xF-!> zFAk`%jqng*_1l^MJrv>LJl)Y$Rc#MPc!X)S zr<<;V?x=Yr!lMN9ErV*l>>wQ|+M^Mc5ifS3HooJLz-(EB#|Ue-=vkEu${vgGuTsJO zblYfY#+c*1;@=VeL)g&*m7XXG z{ZE7^iMZzJJ|ra{F}P1gc#6227fE`gAjF6Y?l@RvPeu4IbNxG1iw}#T@svb2!qdzW z-PSnw?oUT}CI=|;=IhEc5uPQWMwFEe;D7dPgy)F()^{In&qa8iY1b%vz|kW!7yLMT zKEewHE~oC|Y7~g`g$OSa7eVt;m(eyDw=Kd;%ZqZ`sNW#u$#RZ;Vl9h3VKbdv$rC=&9u7K+QO5H2in^a z-XWy+(mSM#so#n4E|Gj|lnWql^rDT_zsyaucO$&VGHy(r)&wVX3@_gAMR=dMr$gQy zDIAd(koO~eKsbK@^v`D#XgNOGK8WxkbJS!Vur2msgpUaLf${1wPA=!U%#R{`%v`mW zERfuce;nZxB7Ufvs_2iL(b8m|^htzIncFQLkEv+V+VhU@GCJ51>dIV53Ws~#(s_P8&OY>vS|1% z!tVq;c_=JcvvZODdxSp-=TkMG54wJ~|A_D>aeuT79yye{fPY5#E3dNbI4Z5%UlIP! z%be`}R@vVX{vqUvq^FD|{)u2O7f2xIWENv3BEBVU4YWb1l2@FSVysM9{b20+!X$s? z7^~zcx%KO)b8#J|x~s%km8j(POh3qfi}`P!{=cmnW3|#3J?dKPJ0wO~Eyn6ZeSf-B zh*D>($5?}qrvaw{=x=sw#8{KK??cxHN`}^qu~t#iKYGfnZn~`%W9?FuD(B;?ts7%KrZqjZcqQ|-UX1k#_?6G2mr@TZl1X)N2IoXt z!Ef_wlw-jE$M{P2z>Fj?uN* zgpFftk{8-*h;0&MQ>NTtkhvf`CX<>)wrPybimG6n#n?PAMKOccm%oE=9%BpQ>JHx{ z_=vwnj4ktm)bx=`v7!;S+Lkf4D&aK$=Bq5vdU}zFu{Cjja5N3Gtz&G%w5F>c_144> zY!hSK{8P3~S3SR}Y#U>{0{4pM6je};ym)qBlH;S+497&{lZ%FFs$z9)B%u?ulcQU~L5`SIB$#;yc& zr#*~E#(8DvN^X3)Iz8DXzwUO8v0G8Cp1R2*aUSN|ZZUTMUtA&6rrGW>_E?V3rPi?A zZ7i@oVst8SJ}0>M`{}${QW(Zto6N=78)hH!L@V~FJB zt?Qc9Eoky-$HX|6IsPE!UPYFa>VC(@D9>x)6g|KxDv!~XNNKZ_Zvq;2TGtre@{-F& zoko_{y2a>Tlq@tYWy#b%Mn!?UZ&|}k;uSG^5O)(+$nTt052yS=>k$Ka{geYwp%Nit z^!)#o=Ot9S^o;UsJ!AA@u7<7`qX74caU7HW800nAj*D?T0WHr~dVTS?F=xxP~#B))7V)QM2OInqfT>g>z#^{&-5S=Es(9;A@p?)#?6BMEM z>&pvQ{}?AQt=0}0QEMl}sASR&h1cKIyFR6>k6p-ncV&!#xtdl^9z%6l5F;ewC&fL< zyU?i?#)wwHsbxn&IytE*MqJ?J1S!jOe=UxY5cecVc^55dk{Br=*A%y~IKDFd@VikO zBg;P^-^bV7I?H05Sk&#-n#PcdK_|vIsleS^CfhE*#V5rWK-?2v8;=KWI(0T6#>qtU zpOsVd6;`;N9OD$`YPh1_-R+bZ1DW*AW-A&SY+#I232BUC&$gc$qpGOUJ&9;9ac_1q zy{L*&UE~(TM<-wGreYvg$Eabh_As#)k6zFHy(UI2F*oMi7r2b+dV(8kZHzkNek!Z2 zF2&~#|7%fcu zdC0|G46cNMh{M#LCN#NTP@N{kX88WlROcw~$-nB@9LbDD$a$GD*QYBHDdXo<=AKyyKi3yJ#`K%?g7 zA$DPmiwNlld((}kT@>SDrbU;{d{enN#wA5f{uUy&?^$+9j7y38ev&PdJh9C#jd58C z<&Bc^aZdMTF)kRoybauXrLwJTy=$y`56jSbbUc4dsK zh`539FRRk-o@7_WxSF_|;-I23uBf!DV_ZW>UFgN+H8HNuzm(3r=9immt6dx8I^u4B z)FU3HxiPNK>smI7#-BAq?D`lt5OU4TAFasEh-;e7MSMey8}ll77h^CkyD`R1MWqwC z#ZI!DV%$u`HC*CP-TUNJ>gE`?6g5+C!CiVK=<)+_ON?8Yt3C{-wCvUxw=wAn(J7I% z+ifv!Czf9wcmdL3Oot9J?jY=EhT868q}%L{74*-8NVReYac7LXN~LL}>=h{Q zig7nl-)qv39_$#4l6$%~!MkJJQ`A*NqEfJfdt%&6+&AbnMY^LvVWiy~V-#U^B?!CQ zs2HP})McaB2{t;$n7l3yIWNqu9YfpsS~Moc*c|7GOyC0mg@lx%j*T&{z`2piijVp@ zvu#|A@x(<2+}HIWYU5)}AmnK%QP|80F(&4S0@z5X8)Fg??Ie`;kd2!ZV{%>(^qvd~ z$CyTJg#}Eic5F9&BipnX)0yjsGIX~>smM-`F@vyQNjsO7?Zf|UMvR#R)phr@w78Sa zjPU>=*FgWQGG3AedmzRv;-y7Lof)oXJ>Tkya#oDlMXujdboZg-G}=W!XtQHH$Xv}^ z*-rLgj5$m>R!8Fa{F&2nReUq0d}F%Ji7~gR&tHX{20F_~&^R~7Jm&hnh>@_#h|Y^K zpO9y}!jx_wvQQn9i@Wc$B{7yVV};pJC?p9txHN5PjE9)(+eJ20&-3#rLVGC2 z!v*fVC2AnaR6ZQz5#svMy{hby7>_cg#ww<}JsM*f)1EGS$$D&AjK_%hB`Yhn;Z==8 z?6DaCBC1}O52Fas{uSeK0)AC$pZ6o_$J`!|@dR@{ZPd3aPDQOf5#!$k_1m=1Y_fmH z_z%;5(7TUprWc(5#CVdBmS;#t?#UQWG3kC}5^t#PY0)X2$RpoVG5(tuu3&JZ|HgQl zN&lOt)wR%BWvx9O;~9eLUs*Sa=k1vo&l2(D$C0B`ZoWs%v}a>HSKxeyrA*a_i+e7{ z^Tbz}4ZqFE1JGQ1KE?~oU4hFMnM(9QBIaMY?0zA}i!760V7%9)xsP5;T6!_YOU&`4 zGjzDU6ys&4H6jChmiO(>NI5UZc!iMfl~@i%uY4uOs{~z}ig?Ac=M*t7wpU}kme)cb z4HXhwy%ytjLYh9RjZ*OTdW<&+XcU||;xMZBXv2OZ#+$^|qN6)?F0(gdyv4Nt`3kC| zsnA<7-X`d6tNm!K=w|Hg81FD!y`Xn+YTQsMH^#e!+@Ke$nIT5(-5Bo?cO4O@?oBet z!itNr_hP)CS48Kl6vNQvLyQjyi9pJ$tL=jrA2M06OU;Fe56|=uV|>Ic^@I!{)S_&mlJMLBoxATiL_m3w+j0@#y5EdoqBb*Z(@AQq+h_)VjOPY#`uniUsjb; zW3%sKd{4+x=?ZUG9Oef^|7_R{`##1GEaP|is*ZZm8VBQt7(Wtr{q>5P5?I`4KgRfp zxF7jm^xjFKOYRc!rx-soOFPby-R8Jn#z|aJ_N6lVAZ0aUc|j)Px^I8uv(5U8%6#* zSD3cd60A-YLl(a^IH4EH7X7b6BBA_)BtVP@pGF6d$ zAjY*4tWDJGkXO}+F)h3d+1d%#DQfac6EY~9YwILfm$)doA`EQZ1nU*WNLM^B^}w^x z)=RK{33n=SvZowx>nGTtz!{2L4-xun8zk6}c)lX?w{;#bo)z6N!A8Ybg$9RC#f=hd zOxzQ_Y$IE3;{=-!@>^FzVJ*E!*(M1#C8$L&fgdew5<|sT~y@h zK;$&jwob4O@qEjb4>Ru9+a%bw1om$kLQSS-+cv>=1pShwgQ9lUTs73TORzoRg0Y|* zH*P0#>$!b`9hl*o$X|4P678h(q1_?Dj?C4HVH4$}Y{vvU73IB{Qe-dfv^fk0zEgso znd^s~0+7=?Z07{K5b{mucG@A``CSt1O3*C~ACT0^Zf(~DyAk)TucSZKR;T>4TY}vQ z`wgw9PVC(i>_J3R;6mBk9tk=T&|XXR)gjg?L1(7@&(_i>6n!#V=LCBa)ZY2%1$>O8 z0}0zR!Cu5%Q>3I)bbYS`dl$I&C^=%5Z{NKWbRq61pE2F6OM)Cm(dqLDB&U4rH#DT<5dTwgVF!#H4feE!x9``R7%5j$``3CMA_Kk363b?wA5CZZz{Ih z5ebeY?(Y|E?IXqc9hu-LVt&)(?6r_L}mewo5am4*#v8@X^TgN3ho|tQe=1;d{if;K=ZnKY1(3`pW zs&m);-U<2;@(Zai4bvzAp)9*kg1&@x3=bJ*eG~L!%C8X$9cnr_FZ~kqC+Mk=TC+Ne zrt$LJKfwva{d~#8xO?P0AweZk*Dz_=Q0st`qo6Ld2eQfpK~Wbka%7CO!bV$=ASA9q zFRzwbdYB+0;G4^kadkB#H&SKv-j^BpArFn%*l2

CJf>Vj8nO*q%`smaIRe5C` zu_bhW1Wm;C zv%UHS)|8;RD8}A8(!Y=DWX%a$i08{hZxmy#CBe|5tQUIfG=9K_CODnASec-Mdo8&? zN^x~>X|vN4v@*|AFcqL=0POt1@b*2?S`)P8H7Y7>TMga#iv?~=&`w+w+}ct_-m*PG z2La7@-zq-C)LBP@VMH|F1Lz7tp^1hi7*5FF`W!<=S&JL%;R#0Mg=wI~6Jn%|NHCI+ z8y_dvV#DsE2KdMXXDr8aM~a;0GZLIhJnzUjO|a9c_R@?q6P#6iB?&aurg*4LwzCqP zP2BGt3boK?XD2wPC`t~CY^CS3&Pi}CanD1n=-lr=ODBPU|#B{-juR$K)i zP+MHgfb$bvP*kkgZ?cFYuWJ`1xRAJOxmS1g>(RIT!UPu;xqSJhA(`l;Q24qi!Nttg zj@GZyE>3U>Qz8n^lh^yYB*CS`G*$ahpPh|jzZ=l)2`|J=c3FbU3AzQQMX2ZR zNz@u}hb%X>>C33xo8StTaqaZGz5LVjJaRJaD-vAET+z4N@vls971R3N6FPJRT$SKz z0&YSl^Obf!50M9X1YMor8sZ|I+B#?Zc};?AiD(H_mM3;?g6o*{yJLQ@;#qlJg6j$U z6+kYphIDy-f*bO>7`|FTK5j^GBN4yM+&x9n4#wJz32w?u@??;`*i8v;US3l1P8@@0 zHz&A-c)oj*+}o+&aZ7?*i^AH9?fF-_&yefk zLBeL=p5Tt6Hoq5mTE8Q~odxcUgf-Tz=gtIo5%*1MqUMG)g6>LiH$jndXKjyU!0%3Q zPw9Kd-FhDr_awNNxQ3iOTO9>Y_a+!cB%gl?YSb$^1zhftaa4lQETd^D?;qIc1Y?-g zgp=%RY)pc&Oy@EkEf5+sxbtpof^p38Ki8GZ+r}jrPsDGWa*69=6OK4sq=c13KB91atFJ{K4rGbC7vm zU~?19Bd$iD-a%sG(9KIQzbLARck=EskwW452^JK%3r5d1qHENG1Ph649B7`^ZVMAE z%B!qo5M&w*+oA-EbBOUd>FTW67AIIjNc}y0x3WD?KG~KeSW3jtZnr`8aUI3PQt)4z z;2~z@>q^Gf5-Lg{DJK&TC3u**8m2O*4E1n=M+j)@%jhs_n7oBOlHgHd`ZaE7GRJr{ z!7?I#FcmM#x$Ib$;4z{i^Uj@jwZ{_ti^=>PTB^4?67^F1SAxfhYi#%4(;iRo1XF%R zwoxLZQ}T%f|0d{nD0(f>$o@OQe~786GF7CU~03g8gV>Y&X*6(+Qp->Xef-J4GyQQL#JS6+4LZHpiYx@NDrj zRKX%!?@zjC6Ff&;?QZO-YghC?doIEAMOld@6;_a;NbLCpFAx{;>`jgC3n{L6A;F79 zQ6K-qSNmdumkM0{p&A2)LgVeF1TPc!!_-d>y{Y?~;1yzi%Lp1MZhs}gt9hw?PNUAc z^ezW;GI0(QA>@&cM`nIwA(*)L6WpvMqger#=la$ zo8Uc`@vGiHNmFfTmc5tYed4~W%^f6(_Y-_T#J7nTP+Dx0C_YH=VX0hi#^SaQ6MRI( zEeg#pB|_S7Ig4z8eU#v1=H|ag4Pmy1s%rLef=`OC#OulX)N-xePZE5Z|H`A2A3OiC z3+>YcpAiwob|^@heU{*J0-o0Cqn4Xcn|+?(3xfHtDddinXvf(X3BDxm7cPHoocpyI zyfKTv{4&8;c~xD+Bz8!&_*H_hi>lN#3V?Z?nr>ew_=b3XMoo1dLVY+Tvia<^;un0A z;M?WjicDpLF~z=3@Evj23~%7%>;^eadXD%m!S~Gdtey8^RZ^^)7nH_1 zT{WawjetJ~q^8iAYhJFFV)f-U$f>bsF;-8p2JvDkaNhM8CA-R{e2G{i#hS%ex-7~M zA(y7DnPRO1_s1D+d$~l`O0o8Ge35%lR6T2_SckahM4J>D)2aEdlVV-Mey|m6w$av2 zu^u7cf&SdlsK4&+yz8Y{pBZ^W7m{(*i$fvHT|dPJ%=LRgSNiz14N`1KL|cBZ%5Jt{ zijA053kH&Xq|%Mk&fF-)#)SRo(`)w-?syxg*o2th!)lvslN6gW?FQeA%O}vVc8qPB zVl(2t_40v8uf8cZC!`-e<;=Zo^AuY!=_zbbt9Q`1MT#v6`leE6WUy_SVypbChUymE zD#g}$GA75ob&75B@-)g+(4%cqY)iyb14VjzFV!ixZHn!Pi)DfT9wGv?ZHiU*p#Q*>cYv1*8~_~_mxMHzGbkTFOH7om@-RF+~N zW@zf!Z5jgEJ}LGk;_0uZh2B|fZQm685p#`hsU|bOUyA(+_?e+)gyaz1IrdL+0Abhc zLK%V_ryY>uzyg-|1+xIK`9Pqc~7VTE${8% z6o(Wwdld?=5OGL~Ly5cL@E2dt>G+NL&=iLiU&&OAQ!e*Nc36tTiL0M<2Uy<64o`6e z0Z#+nN7@l7jx0V@v|Z0ZPO~FZ97WtOylx#dQn#a098E|=&Ua#+TBTEk$=?8ZE}3QCNiTDJqDle*V@T06FXTOK zku&X?q8G6(S(97pigLUBuH^{RdZjpyWgIo+=1|Vh(Qzq`C+<&P?r@SZ)!OkXdJ|RK z`tw0LwB9ND5K!|Oh*QQMeNyx#;zzE3M|B^5);C2zV(v!@7L8GctzU}%InH1jRqcE> zX{UCZ^-pmEaqWj35<4M9C6j)}dsm%dl_>%OekR+fS=DMmija`sGwV5FGH(x4LlhoJVnk6=N2|hq(}#eKNHLPQ#;o%xe0&<2;*6r4^8k^P^BF15%**kOw9(E?aaK`| zTIwWNiB4zPSt-sY?#Z71ba~*DH*osUH^q4@>3d!-Ct`M9it`C+duX7@{`?ddFsUKzsC5sx7o@l_FHlocV;82lh)F-i z%g6Mh6c-crTilQaMPZi1h7^|&^?C>jV@4~af*Zah#ih)1LtZ?v&*x5ZX^P8;yGfit zq2~mbFTNWOftJ#CB?0!`q*3PvC5IbttoCJz9s9+{igZ132y=9^p=xNCao?B}V@pNIFSpy+6yr)rvm}h;Qj90!Xrr)0lIqm>6ch5w#3PKb z2`MHL@I9jHxqNR-OfiXAzKOI}oxz}NDJB#0&7xgrqfJh6ACVQPOe<6JX>A$zrI^Cp zoGoZ=8Qf6KNuH8oDp7TX_WzvDsVVL!Q2aW>2Q=FKDW(x~O_z%Xc`x8!o0eiaarc8x zF3aho?`mi2KG~+Hn8936Eh4`*+EL6%F_WNL%~{Y7&P?$D5&whjd|}|u{y>UZc`2H> zGw`0xN->*=`zZyLW7ruAhUj=nRAaMKJjh&sR?$erG0Zxv9!xQ(_{?7_JiFjHV4IU- zE^}SKJU=~=c5_Q?Zi;!OucVvLesLA%SB!Zn<`=ncqtj{PBv?B7=cib}T%8d;8LutH zLZTpgLjMJW~&5w%v)ti%?lSi-a>O3_&8WmA*8B*jvq{&YQ_ z%1BF7JVd}XUQ!YH3zUHQp%f1j_gg08GcvHXTxva>;*p}b9@C^@#?8VWN%3f@-fBL9 zKbm4$QP5klIloJ`EX8BQ)y#p_)V6pm#lM*L^G5EB%53(p6ps`0zwJ$2^g#J|iYM}- zUEI+^ounsH{F|64n$l3Z%2;gwPVpZ?#rC48w{7;H6i*UVH?=&5dFe)*J(=RE6~3nj zHhU_?e+hXCuc3t6u`B;g@ibAjo3fThdpgB4Oy`s|&v~j+99{VapJdOZc$T?tRGo~L zlPe#C&!%{;z{NFEo=%=}f<2ewdE)*zV@45oywme3ULfi=2tIZ<+Y2dPB;e+l<6ti9Ql9AudaAvd;;p>TPfaV+Ru2mkwaVA;rN0+Gcw<#d}Qpp2kHiLwhg9 z`}ub~U}Zh|eu@u>_}S;#O{dwd_Cbmd3F;^LfJHkNu7nR$e3WC{k7=60N&P6r$HX)m zz50|_X7+K4PYC#VsT)yO(;;5$lN6s4^}kWsAP0HP_GyaG2s*;n!_j9cJ}(uL{+#^X zeV*bAg6gL;;A*!oQhZ57KS@@PMZQe&6#>5+^0?xwsI|hr_9o%cl5#IX=ND zKTtj0zEAN3admFls6Fzoht;sHax>mg6=li>hB!{8r$8gQPfuD)+yo_`Se&aUlJXUzlaTr}(2( zd(B{~;Oe#Kj}(6vrJZYczs=g8DgGj!4>RAiIKaz|*8fWJH*?irUZ$to-zoknYLUMc zIp-No{lkA!*lWdF5O2Zlkm01wGOR@0)td&ziI@|cxYaDrc+|Bg2}6U4!*gi~TW>pH*vSSc|#t{83!&MYdLkwTWmeiH7oG z%8_0>!#afWdAwh$S>ziQ*g6^3C9YGoFV!I`M%2jXIh(j{hV_aMq>Usy-Sa5hS}(); z#5Fu&YX@cP>u1=YD9AdU#BdzXi48JrNZgZlJ0C8!#5T;Z5kZmOK#Ikwa;t0TMj1BF z(Pg6;3!R4o_kfKvY(mtJdtFU&sBDs9Q^MMN`Y^`KrWrP4(v6MhqUBUV>O&kS+bqN8 z%yr$CR*>9!ONV|kO)V@6vjYSM3!VarlUZkh6w&gT@{GQ(EOaXtS_0qg)7Kj zd%j{oZJ%KWf__&n=lHZ%*$x?YEUM8tGM2x`XPTTScFeF-sT%UbRKsbroiglP0*BDk zG_AXA=M1})>Td0**R6Y(47(B&RfyAS^zMkcZ|<65H)go;^wL1b7ujwZb|>zZ0O#9xpQG-t}UY#@SS^AihCLh4^pR{L&y$amF z1G8$LZF^B0}%dkIFs*>U!s%6;z84e)gr-tK9zcqG1h69PI)`2nv zZmG2cGaQsd%SH_s-(m-4IG9krB<1o|dO%C<;0%Wl*KaHv70Z8tE?X|Z z$S@z8;V|NU;}6cT!!jJ6r|D^;(GJgW1k>&&UR7sDWH^#ZM|k3ReAqWS{&YsHM`k#R zxvn|#f=iWRcf&j?!_mb3KDUfsIUJ$>ud?CM8ICDxb`Rm)UA)$eZ0C;2aBNZYWRk%` za+34O(I10Y0DWjKymo~D~yT6l)E*>M?;C#b37b#J5{pP@I? zu8GoaqO%a{%*)iqzn;h=_ixq!DhRVDm9#Vr_tTIDDz)wOAZ__PJ4AG{0T#zAT zj+YDZTvr5A-RM0B;04s$`xaQ3A!135SPySE6J>~r_z5I=%JFENAu0V5Ct#5?{#inP zA<2;D-@DouTACpv;#*FieC%A7;l#X3vW;H+dSZr?h-p|To8yslQicIJ!1$l!BL`$S znSdMC;%=v>ai^;T$6BC0BCQU^^$nxdhzM zc{k+xJI&6`a9)A?=Rs)(O|Okmi+hFi zQgC60i;55BkXm7PW{~r|D8t3XR~XKM5acWM;tZEC*Dv9qsoQ!=v>OARIATZS6Ik2)47)zV4b0VC4`m#p8#3Hj6n3$uI0H+aRf}Y#H)gnr zx$15w?xN(4Zpv^o5siq~wz)aOEd>0oe_Rz=(HiRGX1JB0>x($0`<--lirt#wHsX2H z)F^jgy45<>Zp&~xbJf!_hKaG;Gu*+nAN~H_=$0YFoyF&rD~V&F7aXZY%L~Sx8SctI z@2U`EcV)OcPq$Kc$L`K>57YSo&(=c%9ZAp;Lxy{ad#V`PLal7OH^V4Gek*ZS^=u-w zLu^!r(adli@S+>NOv_dLRPqR;GmK%b#xQQ3AWd3;ChqPwnMpDP2o@{`0TM_8ad&rjcl+&KRrkTH@86HL=(TEB-Fl^`P93W| zOSp@`a?RFs>4^$G*LGJ4cQaR=%*T!xZg-b3muU@OdvbD;w$CkL9wATi^!kYx*3T>9 zo}ymQ@fSp1QSR<3VScEmniBsOnq$o`VF984Cv@VKq{a(MSjap-KCL59Bx7R>OSm^w zp%|MIWZqlCeS|cVOXkoH=XSfVghfQ$;3(`1wPAF~n`nzlSWH~!+Tnw2aS8W_RJ+6N z{t_NwN<*ah#!dD>2@e*P=&98cz z441<9EG^+7;%*>$9;o#XmGE#;)VUqIjWfp{F5wa4{@|ihE8{D&`;V0HC{fK!x2ofs z?a>k*E524UWXCUC!^cW^oVb3ddQ@GFZt{DsMF z@2>W039k|HWK5e^#-&uMc+tXZCA`kua0$|i*XvPg?&~GI!5q&v4x*2`Y^Ehad833k znNjQ??n!R;W_z=Qw+L(Av_51C`Bn*U6B3PVm+oe7m+%ggZf%Qy*9#$hN5bAI;oa~h zxKiZ8^ll075po-Y;y7MG-Yen#;$wwdqUR_7-fr)g@BwiVQ%7Q*UBm|^d{`8gzoLKc zZN7b2!bcUH2PL)4l!xD8AC>SiaW_Wd*rbD22z82gs3rWkgin~Oy;n8PJ}Kc-rabj- z9W{gkq!#mGE_e`*r066ZUlp-xRoC$Bs?2Z%X*Kz&(j`AtCJB z622>N@1!q|Vzzx(!uP~Au}jB`z_i%+CHz20O|H>{KR=Z4Bh!9^4xsH0kK`Xq_=%Xt ziRyHUJ9KaSsf3>iy1oTla0#95=MsJ?aPJK6gKqp%!mpu{#zCzi3dFA^{6^3(z+OIT zUQ?U>R>JS04n8k8lwynep^8cLdkKG3iqjxemuH6e`lEzD32TWlzMZaKf0pnU5zTXX zH~XuEznM}WWeZ||m+%kMZjJc!L9Et9ksT6;e@d{|i+#k$7g`6=1*%#4A&amAb9`&N zI?aJ(o-0IHk+2^!DSx;OSB$U{F*iCz%p)1Ut`uSA0_U8&dy#1J$`Mwn)X~&1iV=@( zl?ba6bItUt$DitwjLouDBdo?;(XdX9BY7CF7Gd?GxODw;h;gon6j02x)g!DCiZ2~M zoZ&3jh_Ge=2KFO&ZfizZi-1P4eQldYajghz6Y*30;A9;jyrs{!wIi%Uyx_B3*jX2= zV4Vo-GDB2?@+(_6!g`@b?#_8M6Id_8`b4wfeShQ&d?H;y_uoZEQu(z7Bts-nq#CNF^6$e9Q3bS>DZ9+L7Sc-|TO@wWi)kuS5 z5)3(|ZX01c;;xgEX=Nt;+D_7QeqQtO6p9iv-phY0Nm z_;W*wil&BIsl=MCU4$LOm%}*HJ4V=vNjEQnnn~?!7I{96K<= zLBuu8v~Q=v_n-&|6YzvfM6=%MzYmUZNT{)&yz%SokO+qsHA=1~mPWo|hekLo)VOqf z=YC!7un3121$Bl?Qa_*D;qVAYgn~7-(svyZ;Yb304hJzHoz9LUBOFE0&*6}!x|8gv z2uBmCkYqh5!uMP$Os2E09UY;Hxo$`lwN)mWiaT5tp;LiN*iWAQT_bcO;>V2^xpJXk^SebrQ4N1i+D%?0 zgFMp^p*wTc*eZp;s;T8yTq4~g^dPQT5mz;m@0Z~i0)FH5mm{TI`eoU0OoU@Y6?|4e z){AtPC1ZAMgr3B8kX5&i7-2ml^a@q>uj<68UcDmpCg6tAi#0^6#36DMTJH#bLbZ!JZFM75hkVw=HJpa%3c4n10oz>`1l9|nd@mY$r7WT42*CB zp+N22i$LT$6`OR5i*>A*oll5RVi~to_*M#R4@EYKgi|NVMw0!4c|+YrS-kimWce5T<>9J5fb6Btm`hp_k-&Yr6UfLx~51K~bW! zQnsNH8VIYk-MDKN3w?N-HAFZu)Jlt7Hvhy3!w9%hCzm1))9(ntqHJ2k>-#fOrU%RHB1?CrD&rxW+#Y(A2kx*7BV0sW4d~vrs*7C|;o^{P&k#6vafC~l)(>~>SIwX-mqfU< zQW1xOHrul9u}dRdM%*n5v69YflUHTk5a!!u5iVbrdoOJW#kwh$imvRJN4SEy{wyLx z)@)ZqxRQwHPaN;tY*$9OikO>zUSYW4$jh+qt0G)o)a@m%Vj*-!>)C{>BV1GD`t2zb z02xe5(tJ&XYniKGK87-sQA6$82-g+AqP9!tbr(mpoFTm#j95MxYVAK_n2YwdKD zbC^7Co9tf^Zm4|CYl-6bP*iOaE2 z2)7XMn~fo%+44HOCBg)PZgi*7f4{KuoDg9maj(Q}qC+}$>w}!FgH4PuiCG#FUS@jO zqzJbbRrt%BI)A6#8ewvQi+$2bOu@KKjxZ(Qa)M>J1zu-KVy8ryO56`twOE9y5vCFG z!$NmL=gUJ`afIoWf;}7fQswjrw}mR5kVc#p39;Q4VFq!HK}Uu-r+IILnFMsgA3D}% zMwrEvTfF|h<92gkq-I5!&0LLXH3K1uq|J^nhmfC;&Nc3}`8g48C+0>_9i+#yNT%H$ z;SS=y@pOLWG>NL;5#dh4;mUS5i@S5vFBr$M+-i45xQk`HP_PHZSj)Y*a#w`Andiw= zm%66fHoH5*TtcA*dee|Qk&5`a5#|xsxn0A681o|B!=&bIltRzk6JdVwnJx(uN$Lcj zA7Md(7bn|vYFrjXSQx&~2iJ|Vg%R#$+KpZzVGt+pH}|~}?qjZR=RhvVHoGsvB0^e# zj8LwCKD>V|im(f)*vCsZhK>!UIKl&ro^Ji1Wu&?tuso zGS`i6(RLr)b(!P(gAtanjBgnQER_5$iLjKAmc&8%1Zcj#dikMp3nUW^nO`eMIG!efzoUBB; zy9M@iglCAWlQpzk<)dy9o+S_%Px)Iy`g2c}Xh4)f~ zmx-$<9lc?|%Mo57;`!4dHMKH_b@q6#M0mBRVlpk(6vtvA55-p_yhdEDrPxA`Ma{F< zBD@}|Fhh-e^MY8$ys--z&LC_;{$t~K^%gtv%Fqla-X-qY4?U^NXSeI^-3adyRWmv$q>H^5;e7&bKBmwL zPQ8*^(wqOwg<_GtAK?R*@k3Hevs4ARA*HboB79i+4fkG@e&fRkABEq@<r-JeAGl$a*B6WQiSTWKdnz%FF(Ibfw-LUp z)WTt`YgNpg?;?CpbSHLMzoynvG9k{75(}<`TX-v$nc@^8976j(!VfIJ+`~<`y}&HS3dFUAmX7aESE3bStVlpd zu%12*eyFx$jFku%7hS#BLA@JkNr~^#;T!!8}!?4 z)flT0@f2}L4LN)Ysbj28%q;*feG~5~Q%%`;`ypLA7caJIyOB)Znh0#Y)Hs;w9rA% z5(6ZOg>4vPBj)-&$zzn7C!SCn#n`y0UQ*}V!}{Mi#wG>M>Ey6z-OjU3Vr)v>P5(@V zmbXn~Y(~U0R(zwA0yl}CHjA-2VU1k%s5aX?#uiL^!P7EJUC#0rF}7rmpE3%bYTBA@ z%NSb`6Iok2eq5bx6=Q3rJ&!=TN@(jC+YkywO;%;{QJrqv#MqX&Z%$9Xa6(xUY2dao zwkwM3&Lv8*h;~!k#n_&>8#A$s3OrwNZMW@X?7&<s89b&X2>WSg7&)2wo{CqnGP+ch{z4;6x%t*E(PwbB%JQRc8ReoamO4F zv0Y=d54BMvKf~I`*o|qwyL!~ac8jrl0Gywe?H*$f0>1Hm8%EKuhZ2T8V(dxO54VC3 z@Ic)&Mu&ir_3)>7hZr4+xzWtAAq0NhE5_cHoVpQVAM2po zJH|fD2_%@i?0*J%pBVcx*DWc^UP(Fjjj%Pg?VuP36ZB)kK*$t}+QBgn zDQYfQ*JUwF4~cOobJb>9qEb(IXpF-`#T{H|XLbCr7>9>qBsY3b>hKsx5Yh5X7zLK+ z;xI|cj)-w2VeOXm@V)HF7)LSbC$|%Q2abwyGyyjverrqiJkySjQ56c(%1ma-F**_O zUGD52N$M1%bEUGnQ8Y%5(S?AG&G1o1u(i#v2u4bSJJBRQ2zQKK)A8Jw^{g>Q2L8*%|bRaSQ>!G-<)) zLz*5F$biGU|5sx{=f|_m44vfNQ+i73cZSL%~JWv;i@WFRBbjzb;X1 zF}c66qK}U;kY%*)YKD_%9BBh%oIoV(6~4&Ky>c7p?SvR5;+_sR({Iy<(<#M>mKB$r z*!yWlG2%+`TH2I}C26)eMnYILsC#5djI{Vz>=UDKJ3&Np^^U{)Vv zC~?1=7?GJaX+vW)5YnXbjdD8dHN-fvQe}NBZ<&tHo)}{oVYfgE9lG9GSdOo0hPm2)498|;VvJ={qroSl zIGuWsm<+<$7;OP(vvhiRT~1q!am2NLx_9l_)5gU(xl&G^(`2*elI1-)#wo;o7rhCS zB7|t4kb<5P<5cDb+CQp6UM#1^IIV&WZlqpmu$>m;bYhzKjtUB9r^h&>Qm9L76J_;w zMvOCwX&RQ?Ms{S8of+e-fH1y@l)-1kIGc!@bk2e9FYe}jc8qfhoQuI-`{<5j=fpUd zxTB{dYR2hUIXA|6g#0Qd`E04@8PaU$#WTX$GC!+KdY+-(Ycnp{)!k^ z67*a0MEcvd*_AP_BIHJWB3)L`u&ZKRO~jLi!A&*w3Z`#Y$GC>5@2zB?;RtkMS=;TEYW)O#ds!4NPhV zs`*NX-4Ns7O#8(}XDE5!{X52gi22E@;w`>KhDr9H7&j7j^g@iNVn4~D*6)9J#kLz` z+{7}XWjpL@H^sP_Dg7AjGbh{4G5*W6>z<3@$c43tRw@6DF}}bjbBbi6%Lfl_e2iPd z_e;n3>ua~fn838#C*ESky}Zm?q#c+LV`7o(#YWWNxL7f~HrvD)lbGx2Pv@G}K{hGI ztwbsZq^`x3g7Pn48s>>7m(E*bOfKpyPCTb+cS~Y&j48}@{h9XQMEQ+S_H~<0i7~bK zN``jgOy{_8)-oHI8e4Ngc^*bD*Vi#Zlq3?PY}GGOV7L#{aqeDQ5Mv>6 z*B!^Yla}~scY2*?VT^l=uk>4z=*{IqxHraq#I^Z4(Esti7>kNxYUJG%?J{VAEsC+Y zz!i^f9xGQ6g~c)MC$4$nJ1e?P+#llsBHG~9w7J%9eIUkzgftYqNV3d>F_sjyNuZ;5 zCgcFIB*s$We*bdz=Y}pw^rL4tCem|vX^e+h#&t93633j%I(4cSI(2> z;TVq))6etSAF>~h#CVi|R|GK@AC<<=P=jRf(HM_0ORc9Vgga{K(i1VmwdK?Xj>>D2bV3&&PP7Qn+UDXe!B??S&XG z2C$1{3zPu1*^4n=s+1fWB(^Wbc$uJ^snNPqy&U5e0vgY%kqwLrN6(~JV!TQ$EHs&o zFI#RC?9~{rG1s+Bl4}Y5Xk=rr#dw{#=m(!Sq+Oj>{$k2GUytzyGc>+rSX%6j7;iGI zHgJP=?r(3#c#DAMM7FPb>FBK(ZwIJ<-Po2+jbrWY81E4Bze~MEv@o}YKHQkUtj`0Zr)!k8-$4_E>%CzRWgM`*}RT*xd#`uh& zKj-=~AQ~Sn`Yguh#N6eoUzL3x;|nI;^bD23-WM^xB%q2rFqnjW8RILaeYg5IQVR4{ zjIW9KVIe(`L|0a6U&r_+RK;lgqej>_F}|%73=x48i09iF-xav-%d%aW%8(G>#rU4M zU#nERI=|QNWBgDQ_VyHRY1j`jekAUejN^{n#-6~xGH?Dd#!t*u&pY%dC)QeDV?V|C zIbgE1aQcLwWBgLou1CWp%bm}r{1W3=;u@BYB#*zv_??&^8ajVB z*zYm^AmV#4ih(f{5%rH4e^x-f3a#hm{*3V#LBEEmT4EEaH~1^Y-$dQe(ukfq8hIr% zKt+sy3S8#1F4{KPvwvdPo4y4K;zR#JORxeF|FR%`T1N5`K%J@=9<7jIMP@o;=$VD$ zJ=@@GNwU0Rf|XcCUC6mPogl(iO0Y6PzbqAzSwdoxft3@iLR^bw1h1yHN`h5GIq?<%H|2SAnsSFT;|8rwAmI3wj`(#Vf=9^thP+B zRpoO|q1U0zu&okoP26?Y2WHnSIXyI&>DCFh36=A7;vB^GhLoyZ zf*lEjw#g?(bScCrupJZZ6lz#Ho*w0`gKeh-I}_4!;(BhgofGWBw3}nE8qzFIv0W1E zN?gtHfiP^>1nmRDJ27JkSo;LK1%!tX!zS5o33d-i4?UyYY`Z7egUE79B)3Y)sptWQ z$>b4>K-zmG*pnq)R|+X71FO5^ZGr8XpaXNYs=AJ({{;6U&(IDDIuaFO-*vaxIwshQ zNj17BJtMdz_DZmK_>6`L@)lQQki8S^6UuR1r0(1&!M>rQ>drlE-vs+H>DuDu;JkUb z;L?)i?w4SH=4uw&_m=I*{s|5s;096pLPaFd9rb_&2Nt*lP&C}70nr_HV1k1}1sy3` zXt9G5985s7!pNLM?BE246d#KHlnEvO+93%J4IhrsBkOi(g2M=S9*IWO!->*4{ICRv z6JBmCJ&WsYOAk+QM5vutjkD8SifU&g?3e_{GUbo4k&SgO`i~u(peIrN^pRvb>a1si zUIfBVJ6RDKwOg%Mg5JcnNb7w3+};WL5K(73%0?>$D(RD;ZzxCuRCy%yO>i6$|I0(` zhBL+t{dtZ{(2uBVyQW#MDeI)S-fGu`an8AXqXhA?x+YNJqka`Kk~l%aT-PIKZQ*p7Q!Po5 zR&WZc#V{gfl!3pXL+*^G3tyq^}NP&ANRd2yF zBtboKjrobSR-a%fQ*La1B!cAy@k0|dFjxD7hAa#C{~l{daALp|>X+d&_7!mhYX z5*9QkXdxa}Po0!YEeTpfQO3G!9C;!ysqV?R1fz*BCl-_hOUI&Dc`G2AANtV=#;~M* zo`N>@eoTU~MEn5t>e1Q8CTI&k!nHJ$mmz;vwrL&iWPPIw|qIeL0hB7SOu(~7Ssd~@TWC^n}hIGwm((fueJ zs3jkIdV(_uYLG_BeuLESj09&^$_=6``v_j!&rEO@K|k!BXyIUIB{-Xi`ps({>CD*) z&I!QM@dFvH;hY5L643mUYj3l26P(9%SSPv;Nz-$iotNNz;%Y;O##+sZouA+WLfUAG z@O(jn3z_t5gk9n$C5fHJIg#Pog$XXI)XM>1zyYWGs$G=e;sU>wr-gHaC4O;&ONe_( z2ajCIs&41Qe4YS#&&x{^T*@-)9rdZahFqH9G6JCqcR7>XTgdHse*3ZnmorzpDW}5= zhmq3X1XmDq-PKI%sxC(OiUd~@*HCu!!KJQDa8*%qGMBwK&AQ#LN^o@rCv|3EI2ZZv z>IBz>8aU^aRM|BNt|j7HR|q22F|QlDHo3em7tU`QUre%pC-@I>Pw@EATuqx74kx&g zu!b{fcWBbiZcK1f<$HQxIKy{xNjD|9xxnec=p+fcGT)rwzXdLFyq=ig%MAA41mlS> z*Kr;o&csMVJwCxL#aI5Sq?i8~y&}N`;+{ERO*Bxl2?-_=3#&p_Yo2JzY0#}G4)eqW zlR|xro+mpWojeR_k>J+icjR8Km8}Tmw7-Qe?kaN<+)i9a zP5T|~_5^o?QsTUwv6;dV-I3tVqCPn}%(Xic+*OqHBTE{~qyDZ0cN5o0jjE})yA#YU zin)mnduMKfdBpul^{Kac3GQLqFSpLLDHK~lQ{)8m32OlIE)0KV^Aju};K`S~Qfxtj zg+x48G)z$%q+wZ@;9jEs%wYU`#!|UA!F{2wrQ>_H^6|I?iwL--PZfe2%zH>y7A06r zT))wwW{iv*7bmzs)W(47F09x62_7J{+TF4ZrG#7~yj-195Hey*6Ffv*ji6#ijoo=EUys6-ETQ*32VCU}aF+jO38k#%qu$dM3fM#b=)J;g)mO2#VnHY=Y;Q>$gb1zOd&KJWoI? zt8Z1m{`P!=7npXP;D_W%bwRnsUP$mFaldY;BcrT=4Bd+fULvaPFkqOyl;CBiJOu@v z4yC$&Il(IgH8V60kxcrP1h0l-9jQiZuA@<*y_(=Pg6a>~^9aTd30BFkC3ro2pZD#f zCr4gS@CFghU^fb3-$?K#lWv?8?niz_lN>)QQR15k-ePW;lzEPT(vsHRO7J#uPYNkX zp~bJgo#35HSz3Zf!^_7K?41Pf64wv5kK5V13Em6I-S$ZAy#((w>DE8(vKoij`w2cE z;_L1+yn)fC?Slj#5-Sdf(G7aEq}e`9@DX7RKi?}HY#$}~nCWFSk8wDiarVavK4FF* z|1PZ~M(Hgq`y|1qM3>uEQhVuOSKmKP@ELPGY3CVSJVxj*>0Y(*S%S}5#?Lp|0gj&g z_VWZ^5chpxBuGB7W?v-ua=EfRZlru#WM3xuinuz_N@C&}?5P z_$E{!sR$+4RN8Xjze(^daSb7vTRtFV-zNAjlyn7K`z67zM6^KaYU}LR1iuv(hGsAf!)*I4!SBQa>F~4QdG_BE{J|VQyUi3l zlmBGw;sk#Z)$TfJl>M3DFQ)vc_UPTMPrqJO{q@lIUkUzZh8vSxsjmu75j;9*H)Ve( z_=mY+L(h@9G361r+CK^GtqSfpx<=SitU%l^)CL9(Y;r=96;iB7Se@ozGXk=$m|`U& zn)UW{3bK__tjzTP&@}Exm8LLAf&Hi2$|+W18Q+IyDTQbZGm<>=Dk)ZFhF@--8r{pC ztEO0um~V*;-Wc1Q7qQh+tWG#|i1xUyqf>456l)Z?7;Hrrk`{7}6l)R}$?NT23R*M8 zS^?<7xQI=*R*JQYFM~`#E*rLXigk#)9{D@9Q>pX!mRXvvlVaWCThU8Bh&7GFxNeH| zh-*n4nk2SfiuFTs_uUV*^;2xXr0*^RV#+LPgA^Nvni$B0`-rbIGGLT#m|~+!+2J&X zWZ8{UY)s6r7y1-1+QFbN&kUc+78_Vlx8%nD5`GOI67> zOR+hju>WU}vlqQzY@4UpqQL#xq?J6~wn(uhanX2?iyzfn(wi+)Y*iGNz+AG*`Q$CP zO0hL@HK-%0x^10e8>aov8PduYZIfc#%9p_clx{$_ZHny*TzgeyDR!xR%(!7AZI=|g67iEaP!Z2sY}XX+iTQT)8bqJAmZ5FdKE-ZC-Ouawvd$5de^peXt^n0Y(lZZxhSY6vF+cQOn zP=en~rHrvdijG7ozo)A-ctDB+ znbi0l8vfaVDGnm$TF&vH{f2m_JM5qo2NTyQRE3DdDGni`QCM;=b@PX$IFxBOmg2*7 zXv+^^`LR4S#bHJ5WVfhBaJn-)EXCo(LvMBX`EPx14^MGK_@$-ehYhtOQXI*&$noJ_ z?Z^~I6?HljDe{6GD?2L1(ZoH~qO4^wmkh_?=oD3i{i5OW;M2iYm7)_djb4WksI*gx z&V<~K8Nlmz=M-I-b}jVmsVpQE{CyTV&MqmsGFPL+6?7)8%e$uNM#QhfG2HZgn6lZr zr9cI3u4@=a;SUXdQ*_zuQC_Ds>Mz;!z4q@W*<^-9s3xH{EH z-eFLk^-j^JC^?Ojs|Z~)$@KS0(U-U%YQ{&VeX86H`=&UqDDDp*30EiDaVh!{7wPI% zJf>#-QdBQj*hwoEaw}D*=ucb|K@+lO>z`skNbg7iy$wilJkuJfPI|`8j!!W#087X3 zwbxEIFvST3mfuP=ypo>+9}cz?Qk0k*7Ceb1m(RVFG?!9Dp_;BDA{M2HmsKPCGWA9~ zat>vUaf+mY#b5&31MP?KiYF1|;1qSl)KCW3>(Retbt#5~&xQqCNoCF4#hSilGGD zmRArL=^m+Saw9ACDg%Sq&=d_Us3L$h032`I^~@DTWa#EOMv{_pgBP$Q_nq zII}#PLM51-_UPHvY{OHGV1}o6uA4R@#YjT>A-Zw*wvj0snf5!7!7v!*v#!P(Q;Z_& zxBnPMGUO>WD#b~}+!FAH3$iV`(@sj!L|jdE;^=y7O3_Tj|E!qtA=aFtg^)i&oM?l$ z9%(b2KcE{AYe~_{GWt;pjA?Jg-PoF9G%>d-^#YB|`}_+?V*W;_7{gpq>e_~JHYUZ` z<$pxGe1bGu%YM+trf6dsQN=zbYfCYXDSri|#)Wo#gKb=jlL`9HgEE}Kb#`)!Q;4Zc zc@0CDQLS`Jic>4axE&a?#7<3d8Zp)0)?lZlIGriicuz{42`;-Zn>@qmDb8T7#*HVp z_??V=PH6LM1@430^YX$iuckSw35p0bNmT*5NyPrt6c?2;6h zhFYk@<*piRm!`NZlu&f7%TiokRH|cCcE7i{+p?4Nklf#4m#4UbWdhA&OfmlCeT<}X zMT#p!ReKE@VOOTOib=nIkMBx9lB-f&T|s)u$mr@6*Mv`wr`GJ66xTB8H&LhFc5RC5 z!Uw%MNL)kLrMR9*xI4)ctaz#Q`V{{PWw{V0QF8LH6gLp@>#Z|w{S|3A#lMNUrQ=1S z)GkxiF`14_x7fc^{D--&XF4*ZJ-df2*MCyn7;qO{u&!B7G|hHnikphs3QdGmCSDV9 zQ;M6JtHD>Gpqo?tmr0FBtG~khH^unM=gzWSL`(ZhqL%R~ZVBa=j_=%OKtH=B#RMX1 zo|8s4GQ^VxWkQOHMLjNF2M54g0Wh49O-wO~xoQS!txZaCYewy7zm6(uLDe0!#oD{dSj3=olwbBmDZclLs zA>V&Grr#cpk~>n|8H(mUY_Q##;x0n2U(2h^|GH&r5Mnz;z?68BMz%361VaF`u}Gh>ZO72k*A|DHc>}aO;{PL0-TX zq*zGY^K(`G`q{!1_Y!ao4=>qKuQZpNeGz2>_ole7$X)(Om2_o>-Irn!bM>o$K#B*62X@sv^)%aq zDV9{K?NckNYD-cqC8nOxn}-^_r70dNs`O`pHtuwLD8<9X_51DFBnIdmRA&#TcqG)= znGK?Bkrufr9wp{!PTJ8PP4O7heynKyXOE?LJbXlZ3|cF3k362@31V6{?HQQ5nVjGg zDV`*xZI*ZHXHTYhib>xkN->8y`-Z1dJWW(%Cwj&}sZXbPCLl}4D|os+lj2z-zCnFk z?Aa90G3`f}!Y4Ag_FRhRiTOtMWN6OkQ@lVxKS!ffU0N0K<%JY45_Qw;uHqc;IW)F& z`@mjI@e*^xA>HWwTkNG2FB8;BduVDer+9@awPnfmB>k_Xc$I12D+&|p7;dKCUQO{D zQ8%rH8H23aUQ6+MrSy`^$T3{TMf!S*H;DS3U0p+eoi|dvS^1uXSWmtvXvLc;-U{FQ zn_B;&G&y@K#oI*H?7kG{E1Js?dppHDMHSv4(qEt7N%3xhi?~XnFXiaFDc&n^3Kn>M z(Z%IHdoRWNp>mn|3{f0%dq2eo1T_jYOKY$XQhdm?pAqM!-ew=B_=uRMzg?f9_ECzD znRI(owv)5%;}oBSN*ZaZZJ(t0l<6>NdPs_$rabM_6rWYTq*>V_`z*!hL;{uZ4*CqX z5oYo86kmjT82@JkE#VnyoowY7DZV7GCEBe0$9?)`imwQ%jrC;xze@2nlYxKMfgyT4 zgIDf~Z-9NB;v1H6zdglW^CU`;9iNQ4zDeCD_k5L62(a8Ok;&0}< zzIpYGG35yZtayatX$w?k9}O#3AS>ERfvZh#xlk5RO(phE#{6}7p!=2^xlAGTVC)rotWGg|L}(;##83~Lbd)U3Xy)z-+c zW~h%u@e1+?Yi3xBh_+xtmq}YI!`h()`*kOG^x7HLA)-MT$XmoZ8P;Xe?@>NuF3x7% z4C@hdU7tpyLWvsad~EAwSih)D#ACLtpJ4+cn%=zAfd2g{Uf&?YhQ-HIAM}p863}g! zVI$&x>3PQwnPY8~VdJ8>d(V!;EG5#$88#vAsb9Secs9wfDG}d$xkqf8VYA{>&$swX z{$?3A4+T5w5lY)U!xjX59~q{_ndoNNl9=kJ1)+MqWrnRnsT#h(=z?8um0@dQVQVS$ ziC4vMonaf|Zt2K3Yatm6KEKRy(zS4#4BIj{5DXECLayTMglLL$i*1`>yP{?%KhsvH zpkuoX+Y{IHwDDzz?KAAaq(4X~9-|6?E+0E&Xh+n|@*uLz?K13GR7R00`9{ay+Kw4^ zBJNjF10VOKLeX~0urt9hb94{glZ|$~0ks#m z*uEL|3mG&Oqs&0>T#qB++b_fZ%_M5GLD|K>*WjMU@Ww_z#q2d|~>B+ff;gX0Bh@{TubX3%S&zGgKAdXbtemJ0Furw?3=N z(22RO*$vIZtW$>0Osm;Ej2SE4I%nuY#IM`t8ro}EmkeDAsl~kRNUTFs-VEJ{g>jKi zj5bbWhP!1zf%{vp6CWEgbPshXd}31zqx^Kw(1VztV1<6^k>Qx)W667^8e&j2J0`=i z#C@B3H|klAV>9$5q>k`?*xjsWhF(mojZ54{V*Jrw8G2W$<2K=Sm+NJc_0G_Tc;#jv zdch$lTRLqEc9*97Yf?qM1D-r=+v zi^+-h%TQfZ%;Vng8YjsnGi22n`ZHIZp(E8O>z`o&(}89#=E3P6Ubg`mjxTEQ+%I<> zm$GMKj?XZVxf-Q0b+z)1wt*Q=s8qxQXc9O2Z1Q<0WGEH5mrD3(Riz9OaV>|FInxxI zL>XctBBsqPBP`C4FzKhPUB`BoWJrse+#}>#M$}}c8L|TRCWN%ABZX6JGps(t&;s{so6}7$ zacG7H;(>4BBgkx~3lFuNa;+i5iN&`%Sx8RFoh`HzGYl(m-6P~KtT(}jWf)%IQ+Y+< z8z%1Q*5MgO6u;%}9mE&w1rc6midQd3WEjaZnlru+Wg{~*GU+L=#5GjLk@DVSjTuHU z!)<;lJIS7m%5V}9-*cLL(lpNz{gW~@1zctnjQYti4kYSL8JdZU1SM3rdLL73&d@^C zk1?NIr}(NRLn|Rq^m^C1m)%=4jII>xTsN4<+vp5q2)W-cuGq8a@Hr;KSmJ(qX{|xy zZn^W1&Co{JAI{w=&EcN3whZHnIy_6^IqPv5PA2Y~P)jK}kC>A)oI=bkGaaNdsFs(G zr&*_DIF-3!e0W6KsTodNR=0ZsmX25V*l8I~C$0_LtzVyBc6x?0igM2OlPf~9)iW}j zNj&`CeY~TD6O4qKLgEZ(g<2Yh^1^;rhO?R0=yqmnz5A}6o#7m!>W2$t%XlqzPKI-d zxpC8sQM*iO$5cBv!+FHD5=PaHv-2{XUlfzT=NA6Fg7BT6;R52t3UTa~r22M2h6{@i zWaz<|Up)O5+JzY|BCahX>3WM@l;L6m6~d{@N5$2_F3xaCr5Xx(bwQ!}%`VAsX@ScS zUki9HspX{^E+g(X)bifXisH|R0M7ILvJ98AjGxY~&E(At&&<7cTZS3LUE?G;(%pTw4qz=5n~`B= z@s$EKEn-s^@_3(_VHWXX=};QzsMo9vvk80ZHHx>>mf<69c7{2j4*G@DRhA62*2$a< zw-fin!mT3b4RI#^=)XO~9n94LQ~pRH)g2k`4AroSRGEEzZxdps37KJiR5q$QEQ+NIY<2a$XC;Yi(hMdy6j=^g!3fNj&=R&2S%azn*C$ zO&-GT%dn^@E7KjZytCNZMHvsp(0lj`$CQGL)kx+;bG>6 z6?U8BF=ZV8aE3?1uTT|3+G>wvc$A3Wom>w*CLhi47$J2`k8{&RIK$%vT+73`$vvnR)f5(QkUf#%NoHv{kEvsXD?NPpWQM1R`5)}c=fj)qsSHmOQr|~- zsms$Do*@$2PuU^ohmWP%GZ~%@CBZGN$PO8vD@w{3iGkJl8q68?T!!a~``PI=sJA_z z;ROOZta|ZXx)(CM81i|8WJND#c!|Jrw^Kc#7T%Z-8{wr4FSAS-EQaA~vX?WwLP!gi zM%i>dZ*vx8uVi?YuwU^M_71gIGrUH`bxFRq3TP}j%4->3C+?SAPa6M|KE9se4Pt6* zUlOf1GQ7!T-~jdHw&Yq`vlFFT5tD9jW_YVoJ#VH(ptiR%yd7}zR*Zlv;U;;jw==v$ zT;oGSaFY0UGQ3N`(=rws*-WX6;_JPe;XP((xAh=LZSQ4xKcp$A9c%Ar_<(8GG4Vor zlZ290`yj)I1@5$uY%e#ueVE~+@coHWuzZx^<7MS!=`6#IDfV%OPl$U0)=yp$yqJBG z;ZuVCq+l#Qn%2_^^3x2T5%pA~y3M%{PnhkDS5(h>VC-Z zW2j7g5Y2~lW1nF^X84J?CaUvr9>hOo_<315FNcvH_2&$~6u8)XY0DHO?UxL{64&T- zpy9W3;QBSgZvh)fCtDh@jIrM`{9b%d1+f#JN_O*mhChfeM<%=kN0-0b?2in87GE(y zty7s%jBI~q_=~vKdi8+g?XL`fGwJtje+G8{JHtN&{QeloBbH0@pA7a+h2(JC$;F-* zX3mP`SblmYmHsyK;_I zijq2$Wv-+k;j83WmAGGya?}_?iHoh8W3>t@(;})eT5Po(s}uDbjNYyzT0@YE)pM*- zDejJB9Ug1sSd*w<{(N(}Rn8h~=2(lM8)Dt_6!Tp%ubph&*2=MV)@815)DTLS8=8kw>dlQHp#JRrApn6bpkEqNxW%}&6uGj)Q$0%Hp{U&lVQ4DSUB<` zciQGTwy0DqpB(9Tn{A66TM`cYSobpuEh$1#-DldCIksYM!9!3NP19W$S#GNwTQkS6 z)MnasZJlEq0%3f-AI)972yc^PTjG9F zgUPhDZ;2u%8ohqVs01|KC!@1}FjqrCO@a7QF$xYwxpI!4MU7mI&RTH>O;LL0 z=vClS+|6`n*G%h`qc?GNfzSNV5TbXEJ_I!54Z~WkPmaD!s?9l14h~G;9LI$M?Rkkf zE=NBm{TvN&F*T$v>6fFLu-^lc!I79qQ&F9xKXFgfy3~!a{y7E^aO*?Cgr?en9LER5 zMdN6;<8urwD)XV+#jMY>fjLefE*9vNo$Q1hC8m7U-GjJ-ha{EJx0ypG58_26xC&t{`2bJP(Gw1fwo z&JOCg>v9Ys?mJsusX#Li%P@}@o`&@~h7wovN4M75&>Rg+hBe4%1FRv(iA2Kr zqnn0GXsp_gq}|T29K)FotJOJ0P)aw^hUXYTT;p{_XB&}YBvbmq?i2!! z%+VNKowB%?F1v}~CKWoh~x+v%rEP+KEons7fzhzy3ZC!s026;@5 zvBg(@J87HFv9USYh^xyTcC)q|<3cK{v2i(0F20%Slomb+@X0w&De%cW;Au!qq4#t< zCC916{SKmONL>vjN%eMWj?)PHMKp#xuh~w^aXKLlZ41rsPS0^hQQ;I9w!jOS&d6~l zaV@TngBzNhIn|jt&ML~X3lE*Gvxn^2Svk%QxQm=Jazt94a0{W(9!1tEKcUM{*I$AwG>PL@Fro$~3z92XIF z!|$iX(FxAKB6D1n<6`FeRbItFDi`Otqykiv3%n%9r3CzX?k69>OLJUSK?YQJsj|y* zTuvnHp;_(@w3tGp%X3^oT$9-DD7zxZl}x#oco~Ftfh@q(k}Gpu#az!xG3X;79xWVA zugY~%S=XNG!NEkEKqyFSOih-iL}XxHvY`&W(|m{wnQ-^p&s@o%QwzTxT4 z*WYsdClv3%_lNC2Ic{XyPX>8Z`V^A1-9PCn|OSVTZ*q3*VbKa^dQYGIVKc%7;tC!G9kxA;%Y@o z+0euslbG}~+`nODn@!4bYw;mp*WpGA!qps;iF>P7K2|i4Ght0`xJJUKP z{PnXBosMqLaR))a!X3jq^}*>R{&(cKlepSjOxlbIc8&*EZJL+#K_mbS#lmba34DGB2NL;ko3;bzY8pSjH1GI=z$WqMF(6$uXa> z7G&S%wn0N}evSnM!jh2{gmijNze^TiL5_vY4QG;czH*S%+kOjk+{+vdSP#DIV)y2_ z?|1J z-TgTpC@OL)XdRK1h&+(v!GKd#Mfpj%aX*-2Nm1TOsQJSb1KW}uONsj(-b^_X1$TN( z!j|TEh#BfvFaEQKay-nmU!N3j=yEHYIKQPH&hbc5y=jAf*Yz+*WcC+tVLwyCjZ@F04F>Fjwt#}mx)tOzfR&h!3>98Xqi86%$* zvflOfWR9mQWse=HHzb?wsT@xeTyA=omkB(b;~D0&4`5Z40(v}nhM6u8dIbI~<&yebddV4X)O9Vpa z>gX`X2EUZ!WrD6rnp!&PDL|FIoa2=WE~OvWyzFsa$?+<2(VE`W<~nniS982ZEHsD8 zt-;lRc}r{x@>G8S11hpEr_uGsjy+Sr_t}YzrSj zwYPG-UBUU@%3?0CyLg_zo#P$i{s+4?G&Re>^_?8=64baVs;|N#alMfBcsIv;%b@{5{&Kx`1g=ZN9O@ET(Q=%Hn28HF5J@%(LJ|hmLIFaY&(!BRz96P~W<+L2fcqlHmz6^O_@ogpTwmt+ikNQzb*{}+4^Z}+ z<7=X>xe6R2(<{B0^>vPKi2K289@#*zs}}nv$G1gcwMj2s&7_d(+Z^8!4=YbGlfTRH zJ(1-$0WCpY03%uBe4pb7=4$NsBpsgj;9~nB$B%^k0ao48rndc<<0oRSZGlL+_tbyN z@iTG1tVgvCx1V$TQWOmKV|4Pm&3?)8D{-9xgN8NQuQ`5W(r+c20V$F#?FoO&@jKyO zEVb9}{~!O^?>YWp#lBDdt{2 z8I_gQJ*sVmGFBuaHY#he70XzODeZ;cJ$l1dDr04)efbj=%53E_Rw3eN$7^q$nae6= ztQtyc)v)BMWvoUd5cE6bj78Q(1{;gG^;aunb>?c6I3oT?SiOuji1``r$4J&|l(A+2 zD2wLdw`Lh@g|EmhFlH)ww6)4uo0wm-J$Z+e`O4a5tV7WKxZDIK*VJE;-8r^S8S56g zI!*M5?XqX^)-7W_=Bm?r+?qsfy)xD(qCx83XzQ1;0aI$aXGnUr*#>27NK6yVhB2JW zAltBvjR^VPR9APmjmp@VfEzj=%ZyLqP;|I)8JmQHd7s`rOSVZFn-b6hZl&V{-zoB95jrlUqRFs?E#Tg1GN=FpHV%p5fp#*|tR)TZXTej;GHh7om$@ zuw@xr5!akA9e?Z?+p3JMnfA0(CWd+_fr@9_x{Pg@;a6;5N?)AnWScU!C8}C9dTo8jGIlCTPGt~Wd2#3g)t$=NxxmHZ$?Z}1nw`torN9~4amkfSC-MI* z+ogjYj7+qUzw=#BT$}fVx zeFk>zXS`B}crDnZ8=alk$meHXo?gC8*_NPM`9SfXCr{l7n z;I)jsi0c>gs?Pm;9N*RUDr4^ed3`R!^Oms>A_B%#`YCV3iZyEa$ z^xKu3mp@+%-P?X;?9W`c=C7bh&lTK7`D)z z98};E8qejT((4-sm2q%^%lL~7F@+*`*uiBSLfkJlnYh%-Jo1n-4khXtxV|+!F37!+ z!=Ti)jKi3tnb_#4+*qeF zIv2Qa1y}6S#n!ouF2vQ`rQ-*TY_Kk6bS2;~9;{MEhThad7T``UV_nPWR{4n0=d4>9 zAfRa`TRzTEM)!~&SVe(Z_cD5fG{bXJ!dk{LMVdR;jw$2VknUGEh?3PZdNS>LCsl_m zhVP}tK+iII5%-h8eOv^4SY*A*=*=9h>JH2PS?@CXgo>7qr>IAc1`?U}DWflO4d(C@ zt#28}F{LHum_ZTh>f;D_ zgMykeY71QV6-5tSKsj@58G{O3BkW#6Az2<&#$e)}Y*jO)5cePX`@v<@5%yC@`HuLT zx-y0k^LvLO9@}h48TCZm!DWnTdosBG`k=Xwb4GE;3^2Zv>7!|&t!bN^%!);UqstgWTw?%lX)>mau|&d{FJ^ZcC|-1rr|cvfTSi+^kM^+-i$2@h${0u7FTuWw zRVx1m@?Yc1IGGuKqWg8N9?-MDom|E##Pp+%GTm*blyNE%*JYX2$rD8ZqfRa3v;r@L zOtND*t&G!&i~RLzZRs<_PA}sO0_twZ)=_pw8D}yXhS1pxa;?s=Gs`%OxF0G#y{+rR zS!JAE0SDC#motlC-7t7ISyDU3RN_f=x1CeQxy;oP>))eSS39?i^O)ApckbKQ z&MV`5Cf(2L*&zj*5^*}ej0=eCv!&zXo$Z1$E@XPSA8}9qae>L>`@%9VVyg?9Xj>aT%8coX?=p^IW4(?c^n8Tw0X(jH_q#FD>IT;#zku>Njod zE-T~mqNpmBLzW^jTwcZ%p(u$l6~aU8iZZSw!2x}H=qUd9~*CkeaI^%adLH}FXG zQDd@k_RiM$iY5Su`H!1hTkQGv2^CE&YYOp_!U%_&CRQ|w+=4nxEHS&E`EF80lfgqf zInLHMomG$h6H1-Q6-}wt$Np$cg$JS;QL|E-Qqfd$jjsFlI>}9~Xd21T(0)x-Z(!Ks zrd2e(D23^bn_kfjl3~y}sBxt@qoSEW#q6RSVi&c*@G~pAp;jUGT)ej1z~*y9MYDkY za0Q|*$qVhYn^n<`Wo6-!k*TO6mbn`%nhkE#)6LX(4Q_TtbIN+k`wFvTG+W-qZcasW z%X-+nAyCt=&Tw-png{N;c3TI2vP`e&AMavdAmVuy-Bf;C)(p#XH&t{qcrj<}K4!dk zb49lR+9(e1*4^Dw(XAwn)`+#pnfca=<^%ZAu`pKNd7A^t{E8NUhv6nl9Q&l5_!m^P z5IB(ekOrJS7gn^WK)55Zh`fs`S`6Yxuxwul@ntXCEUst?x&8;Oho&<(MH*`m2PQ8%gXPkvZ&3pguiZCMa#hhe;eG>EwAYI;!|$U8lsjF z?)HlA01AB?Hv+RJGb(g4N>=gz1*D@tsrS#Y;C}-r_HUXs2yZe5M;d&9tHMf zA!Y3T(6v`|7x}(Rc0plLrupmcs_1U;u#Rz+XH$1~S9A}UZC3kG>;}8-^5${(RCF&H zwoHaK5>5%j>@4-~i`-k$edJh!7y#Qf?yKm25dVY0w!=96B6oj94}b^iC%_Za^FT!p z0tJ?Xaj)rwTik;cJp}5fD9Gwl+p*tfW!SyKLlr$-`-TgyYGx|Ghbwvn)CRbPxp0qE z^k`A4Z{t|wj<)AMTG3;mMbqpS)rfY1d#s|z!Hw{Eq!~r#;}tyt5GDg}e^Vthy-!s1 zByb>u9*}`O;r?VrPXXFMTIedTDtxMuRmSUGl2FhT^sFfmS-w@7QiFO**uyrG?oHupkBFP1p2 zA2^!WUt;xE^b&X&{GOQ)u+ZXOs_5nNH*8}!Uo8t)8rbN|6}?i{Wj2ZSfPy)Qyi(Dt z;DMM-aEDjDTG4A|S<|gy*T@$$+-nuR4(=%?L+ey^uUGU&S<>Ie@oNiFp}tYko8Z2` zwhrwE#(vXQ=0x{qMQ;`Lu(7iTy0iwDd&*$VPfxA^d7iTlU=U5_bPgyv}b(Y-GL?qi&ZmpHWT?J?){2BpiI$N^TqJK zI>o?!P|=6v2Fhdj%`|cnjry>nkH7;(rFMPK$bD4N#|4P&$;%^lJNR)$p8#6(>-yNE z#%Pl(`V`1lYML6mQZ+&1(~3R=w-IiRa2RcIpH=iZh<)5XzI(rcJ&t#uSM&vt{qk@# zvhx;pUsUuZpsn-v@p$y`NOLyU2jc#+qOZuY8Z3yg>BGOO=xZQjO?^?deO=KvB<)vO zL_C?|zNzTj8iI~#vir88??6I3A`D3*_gzKb7lryZ@J7%W_kBe_fEX8IV*UMcSiV10 z^dlKz5D{C^E!h2=`>~>*z-_e-9M_1$5K2=P=1&#z_=+He7Pn@k zwQA^!OIV(l(89GMtqp2JkL9*4skI}m1LA)q7~zHmyiTNFfrq{fiGrN}t4QmvEW8ZY zICM66M6MfYJ@7DF>{6_R^&+hgWZkYCgpBCckF)`RHM1@dtMze%NE;Skc4@(IJsagV zjI>etr9}#I8%5d}z#84fKcMM0jbCAoflW+1WRxWZoo@kZLJsK-qInj73! zk+uf0Da@Oi#t_|%2)vQD0kctH`{ts3n@HQ1)s<4kVos6UM%u2#aoAwPF*bwIZKUnN zjlrNm9^tl+v_o0Wj8VOp0*99!BJBtshJaBcxHqeL$4EPYdUj;zq9Qzjk+COQbi!_@ zNIRD`dal5nn%->ZNV}AH;l;(}@?y73q+P+SMVYa+EbIh4#qANPbD3Klv2by;x2#Qx-Z|2qwO>FwLmR(mq`iQ` zxb_^@*XO!uOw>bo~uyJR+lc2it zlX7xQ@5_ASY*-hmE4h9!L#`dxOBtg99$^fk-oBCc1M?JQ0`PJg zg2l7jFVg-c&bH^Bn~W*%AL#&a>l;gno*WSAKmZ$YF3B6*fsqa(9p-vO>!|R;*g=sF zuA!rwMtd_>cW|UbKy9TAL9#d`(xD`6nAmkD(yK!w9R?ECKYD{nY@L(1Xgn;^;l+pb z$=UAkNJo(L^A|dAwqUaM(R%w7@TeQd*{BOOzeC)jT`rpX->=~xioBNVL1M(Rc~3`S$CnM|Q(?G~wf zS*dsLVh&dtHgu2FgIpV7G?vpM*CSF-0Hfi3Y-@za_l(pF$QtV77d5+Hk$QvJ+;(Y3 zvW+;;_KqYlKP<(CKFzi>qX`m<)Thi1gJ$BHY3J<$q&|`Qk{cEdQN)^?T;E8?0r|u(5W(lU<02go9=Jf`S?>5q{mP2{6EbwqjE93=QNKw2%iJOeuvz+(Yu-5hBMn&j z8*FoSZ^991P6IJMfy~aOjV;L2BApJn%21iU)`Do6xvEKdv)t*CeodJmAbHHJw2a~Y zI?`{*@ofx)7+wMTO{C%AftFV4z!?UMIx{>{rTogK#EZC4Q6*ATeighBJazGviO^A` znA|XIX2L*7WKG*Sj)6GR|;B#JCj4p4B4LZ;29%Q#6=Ga>e515@1 zX=LpKhH?T^xEvkY$Vd&~e$Z_Pv4>nO;)8EQLE8I+L_@6@6Xdp2vQAW~63tBbn3D;_>tZ99bT!HMK?>TU6UVKCefW@5V+NSA%*+ zDXRQ&k`3R3_OmwQ&Kc}7{N=EB zPNd(0+nC@cfF)crovA3y^q znwd6xmASi(v3{74s+x#qcTs=#@O zVkVc&br(eXBe}K~>$-UlP_8`w80kX5&?2r#7xLc%cVVQ9Ky6fpG!nS#qDU8$_RTQ? z!?e(5x_5D;KY`mQbi=!ic)yYUToxpJI@D(cZ*+f-^cV0jk#+^+{u1f0Ac26p;lXJ) zMs|AtYox!C;ky{tw`ruz;hAfF_qRxYC)ZlmKE6*M_xDJb6cy9i88~oU66qfxVKhzC z$lGm^{#pB|=K%N5NdF@3yHnbB@v?^dSEPS~hdJyCB&8|gYA`>i474eYLqbUi@Pb%ICp-Sv^igV``ycnEX|!NqBOqzMJi^v?E{1-EcI znhx@V-#Nq=al5yE&2O79~259@FgRMw&-Dbbly@m2GZbq?>^J7@EjwVbs`~ zAoe-v`fiGJbD0aD@aF=&n4qZ1FsYj(-9oNE>7IU?yCu@CMRGJA+qXuVPty3o@r_O6 zPJdB^-NHzVitpOT_dt=*ga_H8NQ-M=FEnvYY#fUt zEddN2=FmFEEs1nnQC;V1LsN{3{I*C-fs7HD@W?TMzL{a)(n!n52=sx7Va8y~A}t47 zg*lY(q}$tK%Ol-RuAf6=9W#BDu37H(NOzRDDU0wIK-3^kZ=^fH12Z}P6nAH&6{KxM z+Q)ZmJgYuKyRjltJ7DMpNj2PpM*m^9qAb`-}zO;mfNXtk$Wc6 zv*g{y8d7K$2}M6`C7Y*xQow6dI8K2qjwgz9SZLALZlZ<+~~(1 zzr%9My%^~w@IYyVkr?S-iu7_>vb0d2iMrzDNUwkwJ+@n62-=KYh`(~adnMAVMLjF* z{mNPH)kv=uNEf@p#DX}|>$RF8E|k^SL{4(AM|uN1EP-BlW?SJmBE1P{1bpOh_hzKG zipp@xHYM0wk=`y4Hs#jp2={iRcR)hdO{Weenos>Zk=_Ll#K7#e5X1i6NbiC9&Tt6y z7q8}^Zssgl5l4EztjQ3I<2nbwp!Xwv0B)o*yhp#jyt3gwi1Zn#$yjboaGyl_lro;P z=8f*tNS_tS!*@N$eHQ6+l7WojkL(YhNBRP&#+vN@aWS_nUqt#6+?Hk?H$%;BL;R%= zH{!>7N`nvAIVeWV}2y*Sb`l2FJ$MEViHdeybiHU1dsr&^8p zM}@GBKSlbvtTC9w`>PH2bEIEtr3vEPoSEJGFOl5q#blV_xNUH3zzj4jj}wPhBR8yx zgqOM8YOz)av1Xuuh5=OF>ajW$P*;1o4h=?!SZfsD9iC&+i4}0Hjvxh@nbR#}<<(kt ztnV1B6S;nVI2ge?r}E;=MAs?Sn&39kc~10(SZkHV!f_E_bL`93inTVlHM6&Qi!{5n zW32-c7E({7q2{JGw@$2I0S5Bt%}mpQ{3_PE#iz{kB6Ozf##*mdYAB`Hh1QF;K3G^# z!3~B}>~gn$tPQ|zj*(=BxD8@$NZRJOYmS_qHJ?Rz+6`lERFvvAY-k_1QLK$g`>|j< z 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

bfsgz~78Zy+|7c}yz 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

aSIB0*f3jESQ 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%0AEzjdZFK)sl{ppvll(MU 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

rE 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 q5bPpo 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�f{Onmz^LAa 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 Date: Tue, 15 Jul 2025 22:33:15 +0800 Subject: [PATCH 14/22] feat: batch infer qwen --- examples/CMakeLists.txt | 1 + examples/demo_bailing_moe_mbp.cpp | 5 +- examples/demo_qwen.cpp | 10 +- examples/demo_qwen_batch.cpp | 76 +++ include/Types.hpp | 1 + src/Module.cpp | 74 +++ src/Module.hpp | 4 +- src/Tensor.cpp | 22 + src/backends/cpu/CPUBackend.cpp | 7 +- src/backends/cpu/compute/Matmul.cpp | 3 +- src/backends/cpu/op/CPUClipFunc.hpp | 2 +- .../cpu/op/CPUFlashAttention2Func.hpp | 87 +-- src/backends/cpu/op/CPUKVCache.cpp | 4 +- src/backends/cpu/op/CPULinear.cpp | 48 +- src/backends/opencl/OpenCLBackend.cpp | 272 +++++---- src/backends/qnn/QNNBackend.cpp | 4 +- src/backends/xnnpack/XnnpackBackend.cpp | 4 +- .../ling/mbp/modeling_bailing_moe_mbmpip.hpp | 561 ++++++++++++++++++ .../ling/mbp/settings_bailing_moe_mbp.hpp | 53 +- src/models/qwen/configuration_qwen.hpp | 2 +- src/models/qwen/tokenization_qwen.hpp | 49 ++ tools/quantizer/QuantWriter.cpp | 273 +++++---- tools/quantizer/QuantWriter.hpp | 1 + 23 files changed, 1219 insertions(+), 344 deletions(-) create mode 100644 examples/demo_qwen_batch.cpp create mode 100644 src/models/ling/mbp/modeling_bailing_moe_mbmpip.hpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index db060177b..23a4b9ec4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -108,6 +108,7 @@ func_llm_add_executable(demo_minicpm_moe_mbp) func_llm_add_executable(demo_bailing_moe) func_llm_add_executable(demo_bailing_moe_mbp) func_llm_add_executable(test) +func_llm_add_executable(demo_qwen_batch) func_vlm_add_executable(demo_llava) func_vlm_add_executable(demo_fuyu) diff --git a/examples/demo_bailing_moe_mbp.cpp b/examples/demo_bailing_moe_mbp.cpp index 9a6b383db..dc84e2c1f 100644 --- a/examples/demo_bailing_moe_mbp.cpp +++ b/examples/demo_bailing_moe_mbp.cpp @@ -8,7 +8,8 @@ #include "Module.hpp" #include "cmdline.h" #include "models/ling/configuration_bailing_moe.hpp" -#include "models/ling/mbp/modeling_bailing_moe.hpp" +// #include "models/ling/mbp/modeling_bailing_moe.hpp" +#include "models/ling/mbp/modeling_bailing_moe_mbmpip.hpp" #include "models/ling/tokenizer_bailing.hpp" #include @@ -22,7 +23,7 @@ int main(int argc, char **argv) { cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/ling_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/ling_merges.txt"); #ifdef ARM - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-kai_q4_0.mllm"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-kai_q4_0_e2.mllm"); #else cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-q4_0.mllm"); #endif diff --git a/examples/demo_qwen.cpp b/examples/demo_qwen.cpp index a1e61ab49..2f82d246a 100644 --- a/examples/demo_qwen.cpp +++ b/examples/demo_qwen.cpp @@ -21,12 +21,12 @@ int main(int argc, char **argv) { cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2.5_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2.5_merges.txt"); #ifdef ARM - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-kai_q4_0.mllm"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-kai_q4_0_lm.mllm"); #else cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"); #endif - cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B | 3B |]", false, "1.5B"); - cmdParser.add("limits", 'l', "max KV cache size", false, 400); + cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B | 3B |]", false, "1.5b-lm"); + cmdParser.add("limits", 'l', "max KV cache size", false, 550); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); @@ -44,7 +44,9 @@ int main(int argc, char **argv) { model.load(model_path); vector in_strs = { - " Give me a short introduction to large language model.", + "Give me a short introduction to large language model.", + "介绍一下你自己。", + "项羽已杀卿子冠军,威震楚国,名闻诸侯。乃遣当阳君、蒲将军将卒二万渡河,救巨鹿。战少利,陈馀复请兵。项羽乃悉引兵渡河,皆沉船,破釜甑,烧庐舍,持三日粮,以示士卒必死,无一还心。于是至则围王离,与秦军遇,九战,绝其甬道,大破之,杀苏角,虏王离。涉间不降楚,自烧杀。当是时,楚兵冠诸侯。诸侯军救巨鹿下者十余壁,莫敢纵兵。及楚击秦,诸将皆从壁上观。楚战士无不一以当十,楚兵呼声动天,诸侯军无不人人惴恐。于是已破秦军,项羽召见诸侯将,入辕门,无不膝行而前,莫敢仰视。项羽由是始为诸侯上将军,诸侯皆属焉。 问题:结合项羽在巨鹿之战中的战术决策与心理威慑手段,分析其如何实现『楚战士无不一以当十』的战斗效应,并论述这种军事心理学实践对诸侯将领『膝行而前,莫敢仰视』行为模式的生成机制。", }; for (int i = 0; i < in_strs.size(); ++i) { auto input_str = tokenizer.apply_chat_template(in_strs[i]); diff --git a/examples/demo_qwen_batch.cpp b/examples/demo_qwen_batch.cpp new file mode 100644 index 000000000..4c25f3de9 --- /dev/null +++ b/examples/demo_qwen_batch.cpp @@ -0,0 +1,76 @@ +/** + * @file demo_qwen.cpp + * @author Chenghua Wang (chenghua.wang.edu@gmail.com) + * @version 0.1 + * @date 2024-05-01 + * + * @copyright Copyright (c) 2024 + * + */ +#include "cmdline.h" +#include "models/qwen/configuration_qwen.hpp" +#include "models/qwen/modeling_qwen.hpp" +#include "models/qwen/tokenization_qwen.hpp" +#include +#include + +using namespace mllm; + +int main(int argc, char **argv) { + std::iostream::sync_with_stdio(false); + + cmdline::parser cmdParser; + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2.5_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2.5_merges.txt"); +#ifdef ARM + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-kai_q4_0_lm.mllm"); +#else + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"); +#endif + cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B | 3B |]", false, "1.5b-lm"); + cmdParser.add("limits", 'l', "max KV cache size", false, 400); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + string model_billion = cmdParser.get("billion"); + int tokens_limit = cmdParser.get("limits"); + CPUBackend::cpu_threads = cmdParser.get("thread"); + + auto tokenizer = QWenTokenizer(vocab_path, merge_path); + QWenConfig config(tokens_limit, model_billion, RoPEType::HFHUBROPE); + // config.attn_implementation = "sage_attention"; // 使用Sage Attention实现 + auto model = QWenForCausalLM(config); + model.load(model_path); + + vector in_strs = { + "Give me a short introduction to large language model.", + "介绍一下你自己。", + "什么是北京市的旧称?", + }; + vector input_strs; + for (int i = 0; i < in_strs.size(); ++i) { + std::cout << "[Q" << i << "] " << in_strs[i] << std::endl; + auto input_str = tokenizer.apply_chat_template(in_strs[i]); + input_strs.push_back(input_str); + } + auto input_tensor = tokenizer.tokenize(input_strs); + + LlmTextGeneratorOpts opt{ + .max_new_tokens = 200, + .do_sample = false, + .temperature = 0.3F, + .top_k = 50, + .top_p = 0.F, + }; + auto output_tokens = model.generate(input_tensor, opt, tokenizer.eos_id_); + for (int i = 0; i < output_tokens.size(); ++i) { + auto out_token = output_tokens[i]; + auto out_string = tokenizer.detokenize(out_token); + std::cout << "[A" << i << "] " << out_string << std::endl; + } + model.clear_kvcache(); + model.profiling(); +} diff --git a/include/Types.hpp b/include/Types.hpp index 879400f84..c579cad38 100644 --- a/include/Types.hpp +++ b/include/Types.hpp @@ -26,6 +26,7 @@ typedef map OpParam; #define LLAMAFILE_SGEMM inline int KVCache_TYPE = 16; inline int KVCacheSageDtypeBit = 8; // 8 or 16 +inline int KVCache_batch = 1; typedef enum { MLLM_CPU, MLLM_OPENCL, diff --git a/src/Module.cpp b/src/Module.cpp index 7e9f84fc1..501c74d2f 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -4,7 +4,10 @@ #include "Module.hpp" #include "Types.hpp" +#include #include +#include +#include namespace mllm { @@ -96,6 +99,8 @@ void Module::generate( chatPostProcessing(out_token, input_ids, {}); } } + +/* vector Module::generate(Tensor &input_ids, const LlmTextGeneratorOpts &opt, int end_token) { auto chatPostProcessing = [](unsigned token_idx, Tensor &tokens_tensor, const vector &clean_tensors) { tokens_tensor.reshape(1, 1, 1, 1); @@ -131,4 +136,73 @@ vector Module::generate(Tensor &input_ids, const LlmTextGeneratorOpts } return result; } +*/ +/** + * @brief 使用模型生成文本序列,支持批处理输入。 + * @param input_ids 输入的 token ID 张量,形状应为 [batch_size, 1, seq_len, 1]。 + * @param opt 生成选项,如最大新 token 数。 + * @param end_token 序列生成的结束符 ID。 + * @return 一个包含多个生成序列的向量,每个子向量是一个完整的 token ID 序列。 + */ +vector> Module::generate(Tensor &input_ids, const LlmTextGeneratorOpts &opt, int end_token) { + auto chatPostProcessing = [](vector token_idxs, Tensor &tokens_tensor, const vector &clean_tensors) { + tokens_tensor.reshape(token_idxs.size(), 1, 1, 1); + tokens_tensor.alloc(); + for (size_t idx = 0; idx < token_idxs.size(); ++idx) { + unsigned int token_idx = token_idxs[idx]; + tokens_tensor.setDataAt(idx, 0, 0, 0, token_idx); + } + for (auto tensor : clean_tensors) { + tensor->reshape(0, 0, 0, 0); + tensor->alloc(); + } + }; + + if (!opt.do_sample) { + // fail to greedy search + if (!text_generator_ || text_generator_->type() != LLmTextGeneratorType::kGreedySearch) + text_generator_ = std::make_shared(LLmTextGeneratorType::kGreedySearch, opt); + } else if (opt.do_sample && !opt.top_k && opt.top_p != 0.F) { + // fail to top p sampling + if (!text_generator_ || text_generator_->type() != LLmTextGeneratorType::kToppSampling) + text_generator_ = std::make_shared(LLmTextGeneratorType::kToppSampling, opt); + } else if (opt.do_sample && opt.top_k) { + // fail to top k sampling + if (!text_generator_ || text_generator_->type() != LLmTextGeneratorType::kTopkSampling) + text_generator_ = std::make_shared(LLmTextGeneratorType::kTopkSampling, opt); + } + auto batch_size = input_ids.batch(); + vector> results(batch_size); + vector is_end(batch_size, false); + for (int step = 0; step < opt.max_new_tokens; ++step) { + auto _out = (*this)({input_ids}); + // _out[0].saveData(); + // exit(1); + vector out_tokens; + for (int batch_ = 0; batch_ < batch_size; ++batch_) { + Tensor _outt(1, 1, _out[0].sequence(), _out[0].dimension(), MLLM_CPU, true); + memcpy(_outt.hostPtr(), _out[0].ptrAt(batch_, 0, 0, 0), _outt.cntSize()); + auto out_token = text_generator_->generate(_outt); + if (end_token != -1 && out_token == end_token) { + // std::cout << "End batch_: " << batch_ << std::endl; + is_end[batch_] = true; // 标记该 batch 已经结束 + // out_tokens.push_back(0); + // continue; + } + if (!is_end[batch_]) { + out_tokens.push_back(out_token); + results[batch_].push_back(out_token); + } else { + out_tokens.push_back(0); // 如果该 batch 已经结束,则填充 + } + } + chatPostProcessing(out_tokens, input_ids, {}); + if (std::all_of(is_end.begin(), is_end.end(), [](bool v) { return v; })) { + // std::cout << "All batches ended." << std::endl; + break; // 如果所有 batch 都结束,则退出循环 + } + } + return results; +} + } // namespace mllm \ No newline at end of file diff --git a/src/Module.hpp b/src/Module.hpp index 7baf9e7d5..c564297db 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -296,7 +296,9 @@ class Module { virtual void generate( Tensor &input_ids, const LlmTextGeneratorOpts &opt, const std::function &call_back = [](unsigned int) -> bool { return true; }); - vector generate(Tensor &input_ids, const LlmTextGeneratorOpts &opt, int end_token = -1); + // vector generate(Tensor &input_ids, const LlmTextGeneratorOpts &opt, int end_token = -1); + + vector> generate(Tensor &input_ids, const LlmTextGeneratorOpts &opt, int end_token = -1); }; class CPUModuleWrapper : public Module { diff --git a/src/Tensor.cpp b/src/Tensor.cpp index c296accc4..e9bbdb3b1 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -216,6 +216,28 @@ void Tensor::_allocate_final_tensor( Backend *backend) { if (is_kvcached_tensor(template_tensor)) { if (auto master_tensor_sp = template_tensor->masterTensor()) { + if (master_tensor_sp->name().find(".Cache") != std::string::npos && (master_tensor_sp->batch() != batch())) { + KVCache_batch = batch(); + master_tensor_sp->reshape(KVCache_batch, master_tensor_sp->head(), + master_tensor_sp->sequence(), master_tensor_sp->dimension()); + master_tensor_sp->setName(name() + ".Cache"); + master_tensor_sp->alloc(); + + switch (master_tensor_sp->dtype()) { + case MLLM_TYPE_F32: + memset(master_tensor_sp->hostPtr(), 0, master_tensor_sp->count() * sizeof(float)); + break; + case MLLM_TYPE_F16: + memset(master_tensor_sp->hostPtr(), 0, master_tensor_sp->count() * sizeof(mllm_fp16_t)); + break; + case MLLM_TYPE_Q8_0: + memset((char *)master_tensor_sp->rawHostPtr(), 0, + master_tensor_sp->count() * sizeof(block_q8_0) / QK8_0); + break; + default: + break; + }; + } auto cache_seq_len_ = template_tensor->shapeOffset()[2]; if (name().find("cache") == std::string::npos) { diff --git a/src/backends/cpu/CPUBackend.cpp b/src/backends/cpu/CPUBackend.cpp index cb397ff75..1d448a957 100644 --- a/src/backends/cpu/CPUBackend.cpp +++ b/src/backends/cpu/CPUBackend.cpp @@ -371,7 +371,8 @@ std::vector CPUBackend::runOp(Op *op, std::vector inputs, std::v for (const auto &out_tensor : out_tensors) { results.push_back(*out_tensor); #ifdef DEBUGSAVETENSOR - out_tensor->saveData(); + if (out_tensor->dtype() == MLLM_TYPE_F32) + out_tensor->saveData(); #endif } return results; @@ -404,9 +405,9 @@ std::vector CPUBackend::runForward(Module *module, std::vector i } mllm::Module::llm_model_ptr = module; if (module->prefilling_token_size_ == 0) { // first time init - module->prefilling_token_size_ = inputs[0].sequence(); + module->prefilling_token_size_ = inputs[0].sequence() * inputs[0].batch(); } else if (module->decoding_token_size_ == 0) { - module->decoding_token_size_ = inputs[0].sequence(); + module->decoding_token_size_ = inputs[0].sequence() * inputs[0].batch(); } time_start = mllm_time_us(); } diff --git a/src/backends/cpu/compute/Matmul.cpp b/src/backends/cpu/compute/Matmul.cpp index 4e3ac4d03..5ac470efd 100644 --- a/src/backends/cpu/compute/Matmul.cpp +++ b/src/backends/cpu/compute/Matmul.cpp @@ -194,6 +194,7 @@ ErrorCode mat_mul(Tensor *src0, Tensor *src1, Tensor *dst, bool support_bias, Te dst->dtype(), ld_src1 / src1_blck_size, ld_src0 / src0_blck_size, ld_dst / blck_size(dst->dtype())) && dst->dtypeAt(0, 0, 0, 0) == MLLM_TYPE_F32 && dst->ctype() == BSHD && dst->aggregatedTensors().empty()) { + int is_0 = (src1->batch() == 1 && src1->head() == 1 && src1->batch() != src0->batch()) ? 0 : 1; #pragma omp parallel for collapse(3) num_threads(thread_count) for (int64_t b = 0; b < dst->batch(); b++) { for (int64_t h = 0; h < dst->head(); h++) { @@ -201,7 +202,7 @@ ErrorCode mat_mul(Tensor *src0, Tensor *src1, Tensor *dst, bool support_bias, Te llamafile_sgemm( N, M, K / blck_size(src1->dtype()), (char *)src1->rawHostPtr() - + src1->offset(b, h, 0, 0) * src1_type_size / src1_blck_size, + + src1->offset(b * is_0, h, 0, 0) * src1_type_size / src1_blck_size, ld_src1 / src1_blck_size, (char *)src0->rawHostPtr() + src0->offset(b, h, 0, 0) * src0_type_size / src0_blck_size, diff --git a/src/backends/cpu/op/CPUClipFunc.hpp b/src/backends/cpu/op/CPUClipFunc.hpp index 72c6a0a81..c6b623933 100644 --- a/src/backends/cpu/op/CPUClipFunc.hpp +++ b/src/backends/cpu/op/CPUClipFunc.hpp @@ -312,8 +312,8 @@ class CPUcliptensorFunction : public Op { outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), new_seq, inputs[0]->dimension()); outputs[0]->alloc(); } -#pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) for (int b = 0; b < inputs[0]->batch(); ++b) { +#pragma omp parallel for num_threads(CPUBackend::cpu_threads) for (int s = 0; s < inputs[1]->dimension(); ++s) { auto selected_idx = (int)inputs[1]->dataAt(0, 0, 0, s); memcpy(outputs[0]->ptrAt(b, 0, s, 0), diff --git a/src/backends/cpu/op/CPUFlashAttention2Func.hpp b/src/backends/cpu/op/CPUFlashAttention2Func.hpp index 6ed62aebe..5c5ed6120 100644 --- a/src/backends/cpu/op/CPUFlashAttention2Func.hpp +++ b/src/backends/cpu/op/CPUFlashAttention2Func.hpp @@ -6,6 +6,7 @@ #define CPUFA2FUNC_HPP #include "CPUBackend.hpp" +#include "DataType.hpp" #include "Tensor.hpp" #include "Types.hpp" #include "../compute/FlashAttention2.hpp" @@ -70,45 +71,55 @@ class CPUFlashAttention2Func : public Op { int32_t br = q_sequence >= 4 ? 4 : 1; int32_t bc = q_sequence >= 4 ? 4 : 1; constexpr bool high_precision_exp = true; - - // for BSHD attention start - if (inputs[0]->ctype() == BHSD && inputs[1]->ctype() == BHSD && inputs[2]->ctype() == BHSD) { - int km = k_sequence; - int vm = v_sequence; - if (k_tensor->masterTensor() != nullptr && v_tensor->masterTensor() != nullptr) { - km = k_tensor->masterTensor()->sequence(); - vm = v_tensor->masterTensor()->sequence(); + for (int bch = 0; bch < batch_size; ++bch) { + void *o_ptr = o_tensor->ptrAt(bch, 0, 0, 0); + void *q_ptr = q_tensor->ptrAt(bch, 0, 0, 0); + void *k_ptr; + void *v_ptr; + if (kv_use_fp32) { + k_ptr = k_tensor->ptrAt(bch, 0, 0, 0); + v_ptr = v_tensor->ptrAt(bch, 0, 0, 0); + } else { + k_ptr = k_tensor->ptrAt(bch, 0, 0, 0); + v_ptr = v_tensor->ptrAt(bch, 0, 0, 0); + } + // for BSHD attention start + if (inputs[0]->ctype() == BHSD && inputs[1]->ctype() == BHSD && inputs[2]->ctype() == BHSD) { + int km = k_sequence; + int vm = v_sequence; + if (k_tensor->masterTensor() != nullptr && v_tensor->masterTensor() != nullptr) { + km = k_tensor->masterTensor()->sequence(); + vm = v_tensor->masterTensor()->sequence(); + } + flash_attention_2_forward_h( + q_ptr, k_ptr, v_ptr, o_ptr, // 输入输出张量 + 1, q_head, q_sequence, k_sequence, dimension, // 基本维度 + causal_mask_, // 使用因果掩码 + kv_use_fp32, // 使用FP32(x86必须) + threads, // 线程数 + br, // 查询分块大小 + bc, // 键值分块大小 + q_head, // 查询头数 + k_head, // 键值头数 + high_precision_exp, // 使用快速指数近似 + q_sequence * dimension, + km * dimension, + vm * dimension); + // for BSHD attention end + } else { + flash_attention_2_forward( + q_ptr, k_ptr, v_ptr, o_ptr, // 输入输出张量 + 1, q_head, q_sequence, k_sequence, dimension, // 基本维度 + causal_mask_, // 使用因果掩码 + kv_use_fp32, // 使用FP32(x86必须) + threads, // 线程数 + br, // 查询分块大小 + bc, // 键值分块大小 + q_head, // 查询头数 + k_head, // 键值头数 + high_precision_exp // 使用快速指数近似 + ); } - flash_attention_2_forward_h( - q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), - o_tensor->hostPtr(), // 输入输出张量 - batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 - causal_mask_, // 使用因果掩码 - kv_use_fp32, // 使用FP32(x86必须) - threads, // 线程数 - br, // 查询分块大小 - bc, // 键值分块大小 - q_head, // 查询头数 - k_head, // 键值头数 - high_precision_exp, // 使用快速指数近似 - q_sequence * dimension, - km * dimension, - vm * dimension); - // for BSHD attention end - } else { - flash_attention_2_forward( - q_tensor->hostPtr(), k_tensor->hostPtr(), v_tensor->hostPtr(), - o_tensor->hostPtr(), // 输入输出张量 - batch_size, q_head, q_sequence, k_sequence, dimension, // 基本维度 - causal_mask_, // 使用因果掩码 - kv_use_fp32, // 使用FP32(x86必须) - threads, // 线程数 - br, // 查询分块大小 - bc, // 键值分块大小 - q_head, // 查询头数 - k_head, // 键值头数 - high_precision_exp // 使用快速指数近似 - ); } return ErrorCode::MLLM_NO_ERROR; } diff --git a/src/backends/cpu/op/CPUKVCache.cpp b/src/backends/cpu/op/CPUKVCache.cpp index 20318e4bb..8d469b555 100644 --- a/src/backends/cpu/op/CPUKVCache.cpp +++ b/src/backends/cpu/op/CPUKVCache.cpp @@ -45,7 +45,7 @@ CPUKVCache::CPUKVCache(Backend *bn, string opName, int hidden, int head, int n_r if (head > 0) { if (for_xnn_) cache_->setDtype(MLLM_TYPE_F32); - cache_->reshape(1, head * n_rep_, cache_limit_, hidden); + cache_->reshape(KVCache_batch, head * n_rep_, cache_limit_, hidden); cache_->setName(name() + ".Cache"); cache_->alloc(); @@ -71,7 +71,7 @@ ErrorCode CPUKVCache::reshape(vector> inputs, vector> outputs) { assert(inputs.size() == 1); assert(outputs.size() == 1); - if (cache_seq_len_ < 0) { + if (cache_seq_len_ < 0) { //|| inputs[0]->batch() != cache_->batch() if (for_xnn_) cache_->setDtype(MLLM_TYPE_F32); cache_->reshape(inputs[0]->batch(), inputs[0]->head() * n_rep_, cache_limit_, diff --git a/src/backends/cpu/op/CPULinear.cpp b/src/backends/cpu/op/CPULinear.cpp index b3c1b2547..356fd2356 100644 --- a/src/backends/cpu/op/CPULinear.cpp +++ b/src/backends/cpu/op/CPULinear.cpp @@ -120,17 +120,19 @@ ErrorCode CPULinear::execute(vector> inputs, vectorsequence(); - auto N = outputs[0]->dimension(); - auto K = inputs[0]->dimension(); - if (outputs[0]->dtype() == MLLM_TYPE_F16) { - mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(0, 0, 0, 0), - inputs[0]->ptrAt(0, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); - } else { - mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(0, 0, 0, 0), - inputs[0]->ptrAt(0, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); + for (int b = 0; b < inputs[0]->batch(); b++) { + auto M = inputs[0]->sequence(); + auto N = outputs[0]->dimension(); + auto K = inputs[0]->dimension(); + if (outputs[0]->dtype() == MLLM_TYPE_F16) { + mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(b, 0, 0, 0), + inputs[0]->ptrAt(b, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } else { + mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(b, 0, 0, 0), + inputs[0]->ptrAt(b, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } } return MLLM_NO_ERROR; #else @@ -169,17 +171,19 @@ ErrorCode CPULinear::execute(vector> inputs, vectorsequence(); - auto N = outputs[0]->dimension(); // out_features_ - auto K = inputs[0]->dimension(); // in_features_ - if (outputs[0]->dtype() == MLLM_TYPE_F16) { - mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(0, 0, 0, 0), - inputs[0]->ptrAt(0, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); - } else { - mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(0, 0, 0, 0), - inputs[0]->ptrAt(0, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); + for (int b = 0; b < inputs[0]->batch(); b++) { + auto M = inputs[0]->sequence(); + auto N = outputs[0]->dimension(); // out_features_ + auto K = inputs[0]->dimension(); // in_features_ + if (outputs[0]->dtype() == MLLM_TYPE_F16) { + mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(b, 0, 0, 0), + inputs[0]->ptrAt(b, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } else { + mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(b, 0, 0, 0), + inputs[0]->ptrAt(b, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } } return MLLM_NO_ERROR; #else diff --git a/src/backends/opencl/OpenCLBackend.cpp b/src/backends/opencl/OpenCLBackend.cpp index 1cdf86213..b3fed31c3 100644 --- a/src/backends/opencl/OpenCLBackend.cpp +++ b/src/backends/opencl/OpenCLBackend.cpp @@ -8,16 +8,16 @@ #include "utils/OpenCLTools.hpp" // 错误检查函数 -void check_cl_error(cl_int err, const std::string& operation) { +void check_cl_error(cl_int err, const std::string &operation) { if (err != CL_SUCCESS) { std::cerr << "OpenCL Error during " << operation << " (" << err << ")" << std::endl; - //应该调度到cpu + // 应该调度到cpu throw std::runtime_error("OpenCL Error: " + operation); } } // 从文件加载内核源码的辅助函数 -std::string load_file_contents(const char* filename) { +std::string load_file_contents(const char *filename) { std::ifstream in(filename, std::ios::in | std::ios::binary); if (in) { return std::string((std::istreambuf_iterator(in)), std::istreambuf_iterator()); @@ -25,15 +25,14 @@ std::string load_file_contents(const char* filename) { throw std::runtime_error(std::string("Could not open file: ") + filename); } - namespace mllm { // 静态辅助函数,用于在构造函数初始化列表中创建 MemoryManager // 这样可以确保在调用基类构造函数之前,context 和 device 已经被正确初始化 -std::shared_ptr OpenCLBackend::createMemoryManager(cl_context& context, cl_device_id& device) { +std::shared_ptr OpenCLBackend::createMemoryManager(cl_context &context, cl_device_id &device) { cl_int err; cl_platform_id platform; - + // 1. 获取平台 err = clGetPlatformIDs(1, &platform, nullptr); check_cl_error(err, "clGetPlatformIDs"); @@ -53,13 +52,13 @@ std::shared_ptr OpenCLBackend::createMemoryManager(cl_conte return std::make_shared(context); } // namespace mllm -OpenCLBackend::OpenCLBackend(const BackendConfig &config) : Backend() { +OpenCLBackend::OpenCLBackend(const BackendConfig &config) : + Backend() { mem_manager_ = createMemoryManager(context_, device_); cl_int err; queue_ = clCreateCommandQueue(context_, device_, 0, &err); check_cl_error(err, "clCreateCommandQueue"); - // ======================================================================= // ========== 检查扩展支持和获取对齐值 ========== // ======================================================================= @@ -78,12 +77,12 @@ OpenCLBackend::OpenCLBackend(const BackendConfig &config) : Backend() { // 检查是否包含我们需要的扩展 if (extensions.find("cl_khr_image2d_from_buffer") != std::string::npos) { this->image_from_buffer_supported_ = true; - + // 如果支持,则进一步查询行间距对齐要求(单位:字节) // CL_DEVICE_IMAGE_PITCH_ALIGNMENT 返回的是像素单位,需要转换,不如此处直接查询字节对齐可靠。 // CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 是一个更通用的字节对齐保证。 clGetDeviceInfo(device_, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT, sizeof(cl_uint), &this->image_pitch_alignment_bytes_, nullptr); - + // 根据规范,如果返回0,则表示没有特殊的对齐要求,我们可以认为是1字节对齐。 if (this->image_pitch_alignment_bytes_ == 0) { this->image_pitch_alignment_bytes_ = 1; @@ -96,12 +95,12 @@ OpenCLBackend::OpenCLBackend(const BackendConfig &config) : Backend() { // ======================================================================= const std::string convert_kernel_path = get_kernel_path(__FILE__, "./kernel/convert_fp.cl"); std::string build_options = ""; - + // 如果硬件支持FP16,我们通过宏定义告诉编译器去编译高性能版本的内核 if (this->has_fp16_support_) { build_options += " -DSUPPORTS_FP16"; } - + cl_program convert_program = getProgram(convert_kernel_path, build_options); // --- 根据硬件能力,创建并加载相应版本的内核 --- @@ -126,10 +125,10 @@ OpenCLBackend::OpenCLBackend(const BackendConfig &config) : Backend() { check_cl_error(err, "CreateKernel: convert_fp16_to_fp32_buffer_compat"); // 在不原生支持FP16的设备上,Image转换通常也不可行或无意义,所以不加载Image内核 } - + sampler_ = clCreateSampler(context_, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); check_cl_error(err, "clCreateSampler in Backend"); - + this->type_ = MLLM_OPENCL; registerOps(); } @@ -143,7 +142,7 @@ OpenCLBackend::~OpenCLBackend() { if (sampler_) clReleaseSampler(sampler_); // (保留原有释放 program 和 queue 的代码) - for (auto const& [key, program] : program_cache_) { + for (auto const &[key, program] : program_cache_) { if (program) { clReleaseProgram(program); } @@ -154,12 +153,12 @@ OpenCLBackend::~OpenCLBackend() { } void OpenCLBackend::finishQueue() { - if(queue_) { + if (queue_) { clFinish(queue_); } } -cl_program OpenCLBackend::getProgram(const std::string& program_name, const std::string& build_options) { +cl_program OpenCLBackend::getProgram(const std::string &program_name, const std::string &build_options) { // 检查缓存 auto it = program_cache_.find(program_name); if (it != program_cache_.end()) { @@ -168,7 +167,7 @@ cl_program OpenCLBackend::getProgram(const std::string& program_name, const std: // 加载和编译 std::string kernel_source = load_file_contents(program_name.c_str()); - const char* source_ptr = kernel_source.c_str(); + const char *source_ptr = kernel_source.c_str(); size_t source_len = kernel_source.length(); cl_int err; @@ -184,7 +183,7 @@ cl_program OpenCLBackend::getProgram(const std::string& program_name, const std: std::string error_msg = "Kernel build error for " + program_name + ":\n" + log.data(); throw std::runtime_error(error_msg); } - + // 存入缓存并返回 program_cache_[program_name] = program; return program; @@ -193,62 +192,62 @@ void OpenCLBackend::alloc_device(DeviceMemory &mem, DataType dtype) { if (context_ == nullptr) throw std::runtime_error("OpenCL context is not initialized."); cl_int err; switch (mem.type) { - case MEM_TYPE_BUFFER: { - // **新增逻辑**:检查是否是创建 Image 兼容 Buffer 的特殊请求 - if (mem.image_width > 0 && mem.image_height > 0 && image_from_buffer_supported_) { - // === 创建 Image 兼容的、带行间距对齐的 Buffer === - - // 1. 计算满足硬件对齐要求的行间距(字节单位) - const size_t pixel_width = mem.image_width; // 此时 image_width 是像素数 - const cl_uint pitch_alignment = image_pitch_alignment_bytes_; - - size_t row_pitch = pixel_width * 4 * sizeof(float); // 理论行间距 - if (pitch_alignment > 0 && row_pitch % pitch_alignment != 0) { - row_pitch = (row_pitch + pitch_alignment - 1) / pitch_alignment * pitch_alignment; - } - - // 2. 计算带填充的总 buffer 大小 - const size_t padded_buffer_size = mem.image_height * row_pitch; - - // 3. 更新 DeviceMemory 结构体,保存关键信息 - mem.size_in_bytes = padded_buffer_size; // 使用计算出的、更大的尺寸 - mem.image_row_pitch_in_bytes = row_pitch; // **保存行间距,为零拷贝做准备** - - // 4. 使用新的总大小创建 Buffer - mem.handle = clCreateBuffer(context_, CL_MEM_READ_WRITE, padded_buffer_size, nullptr, &err); - check_cl_error(err, "clCreateBuffer for Image-Compatible Buffer"); - - } else { - // === 创建一个标准的、紧密排列的 Buffer === - mem.handle = clCreateBuffer(context_, CL_MEM_READ_WRITE, mem.size_in_bytes, nullptr, &err); - check_cl_error(err, "clCreateBuffer for Standard Buffer"); + case MEM_TYPE_BUFFER: { + // **新增逻辑**:检查是否是创建 Image 兼容 Buffer 的特殊请求 + if (mem.image_width > 0 && mem.image_height > 0 && image_from_buffer_supported_) { + // === 创建 Image 兼容的、带行间距对齐的 Buffer === + + // 1. 计算满足硬件对齐要求的行间距(字节单位) + const size_t pixel_width = mem.image_width; // 此时 image_width 是像素数 + const cl_uint pitch_alignment = image_pitch_alignment_bytes_; + + size_t row_pitch = pixel_width * 4 * sizeof(float); // 理论行间距 + if (pitch_alignment > 0 && row_pitch % pitch_alignment != 0) { + row_pitch = (row_pitch + pitch_alignment - 1) / pitch_alignment * pitch_alignment; } - break; + + // 2. 计算带填充的总 buffer 大小 + const size_t padded_buffer_size = mem.image_height * row_pitch; + + // 3. 更新 DeviceMemory 结构体,保存关键信息 + mem.size_in_bytes = padded_buffer_size; // 使用计算出的、更大的尺寸 + mem.image_row_pitch_in_bytes = row_pitch; // **保存行间距,为零拷贝做准备** + + // 4. 使用新的总大小创建 Buffer + mem.handle = clCreateBuffer(context_, CL_MEM_READ_WRITE, padded_buffer_size, nullptr, &err); + check_cl_error(err, "clCreateBuffer for Image-Compatible Buffer"); + + } else { + // === 创建一个标准的、紧密排列的 Buffer === + mem.handle = clCreateBuffer(context_, CL_MEM_READ_WRITE, mem.size_in_bytes, nullptr, &err); + check_cl_error(err, "clCreateBuffer for Standard Buffer"); } - case MEM_TYPE_IMAGE_2D: { - // cl_image_format format = {CL_RGBA, CL_FLOAT}; - cl_image_format format = {CL_RGBA}; // 通道顺序不变 - - // **核心修改:根据dtype设置通道数据类型** - switch (dtype) { - case MLLM_TYPE_F32: - format.image_channel_data_type = CL_FLOAT; - break; - case MLLM_TYPE_F16: - format.image_channel_data_type = CL_HALF_FLOAT; - break; - default: - throw std::runtime_error("Unsupported data type for Image2D creation."); - } - cl_image_desc desc = {}; - desc.image_type = CL_MEM_OBJECT_IMAGE2D; - desc.image_width = mem.image_width; - desc.image_height = mem.image_height; - mem.handle = clCreateImage(context_, CL_MEM_READ_WRITE, &format, &desc, nullptr, &err); - check_cl_error(err, "clCreateImage"); + break; + } + case MEM_TYPE_IMAGE_2D: { + // cl_image_format format = {CL_RGBA, CL_FLOAT}; + cl_image_format format = {CL_RGBA}; // 通道顺序不变 + + // **核心修改:根据dtype设置通道数据类型** + switch (dtype) { + case MLLM_TYPE_F32: + format.image_channel_data_type = CL_FLOAT; + break; + case MLLM_TYPE_F16: + format.image_channel_data_type = CL_HALF_FLOAT; break; + default: + throw std::runtime_error("Unsupported data type for Image2D creation."); } - default: throw std::runtime_error("Unsupported device memory type for OpenCL."); + cl_image_desc desc = {}; + desc.image_type = CL_MEM_OBJECT_IMAGE2D; + desc.image_width = mem.image_width; + desc.image_height = mem.image_height; + mem.handle = clCreateImage(context_, CL_MEM_READ_WRITE, &format, &desc, nullptr, &err); + check_cl_error(err, "clCreateImage"); + break; + } + default: throw std::runtime_error("Unsupported device memory type for OpenCL."); } } @@ -263,46 +262,46 @@ void OpenCLBackend::copy_from_host(const DeviceMemory &dest, const void *src) { if (dest.handle == nullptr || src == nullptr) return; cl_mem dest_handle = static_cast(dest.handle); switch (dest.type) { - case MEM_TYPE_BUFFER:{ - // 检查这个Buffer是否是Image兼容的 - if (dest.image_row_pitch_in_bytes > 0 && dest.image_height > 0) { - // **使用 clEnqueueWriteBufferRect 来处理行间距** - const size_t buffer_origin[3] = {0, 0, 0}; - const size_t host_origin[3] = {0, 0, 0}; - - // region_in_bytes: {width, height, depth} - const size_t region_in_bytes[3] = { - dest.image_width * 4 * sizeof(float), // 拷贝区域的宽度(字节) - dest.image_height, // 拷贝区域的高度(行数) - 1 // 深度为1 - }; - - clEnqueueWriteBufferRect( - queue_, - dest_handle, - CL_TRUE, // 阻塞调用 - buffer_origin, - host_origin, - region_in_bytes, - dest.image_row_pitch_in_bytes, // Buffer中的行间距 - 0, // Buffer中的切片间距 - dest.image_width * 4 * sizeof(float), // Host内存中的行间距(假设紧密排列) - 0, // Host内存中的切片间距 - src, - 0, nullptr, nullptr); - } else { - // 标准的Buffer拷贝 - clEnqueueWriteBuffer(queue_, dest_handle, CL_TRUE, 0, dest.size_in_bytes, src, 0, nullptr, nullptr); - } - break; - } - case MEM_TYPE_IMAGE_2D: { - const size_t origin[3] = {0, 0, 0}; - const size_t region[3] = {dest.image_width, dest.image_height, 1}; - clEnqueueWriteImage(queue_, dest_handle, CL_TRUE, origin, region, 0, 0, src, 0, nullptr, nullptr); - break; + case MEM_TYPE_BUFFER: { + // 检查这个Buffer是否是Image兼容的 + if (dest.image_row_pitch_in_bytes > 0 && dest.image_height > 0) { + // **使用 clEnqueueWriteBufferRect 来处理行间距** + const size_t buffer_origin[3] = {0, 0, 0}; + const size_t host_origin[3] = {0, 0, 0}; + + // region_in_bytes: {width, height, depth} + const size_t region_in_bytes[3] = { + dest.image_width * 4 * sizeof(float), // 拷贝区域的宽度(字节) + dest.image_height, // 拷贝区域的高度(行数) + 1 // 深度为1 + }; + + clEnqueueWriteBufferRect( + queue_, + dest_handle, + CL_TRUE, // 阻塞调用 + buffer_origin, + host_origin, + region_in_bytes, + dest.image_row_pitch_in_bytes, // Buffer中的行间距 + 0, // Buffer中的切片间距 + dest.image_width * 4 * sizeof(float), // Host内存中的行间距(假设紧密排列) + 0, // Host内存中的切片间距 + src, + 0, nullptr, nullptr); + } else { + // 标准的Buffer拷贝 + clEnqueueWriteBuffer(queue_, dest_handle, CL_TRUE, 0, dest.size_in_bytes, src, 0, nullptr, nullptr); } - default: throw std::runtime_error("Unsupported copy for this memory type."); + break; + } + case MEM_TYPE_IMAGE_2D: { + const size_t origin[3] = {0, 0, 0}; + const size_t region[3] = {dest.image_width, dest.image_height, 1}; + clEnqueueWriteImage(queue_, dest_handle, CL_TRUE, origin, region, 0, 0, src, 0, nullptr, nullptr); + break; + } + default: throw std::runtime_error("Unsupported copy for this memory type."); } } @@ -310,27 +309,26 @@ void OpenCLBackend::copy_to_host(void *dest, const DeviceMemory &src) { if (dest == nullptr || src.handle == nullptr) return; cl_mem src_handle = static_cast(src.handle); switch (src.type) { - case MEM_TYPE_BUFFER: - clEnqueueReadBuffer(queue_, src_handle, CL_TRUE, 0, src.size_in_bytes, dest, 0, nullptr, nullptr); - break; - case MEM_TYPE_IMAGE_2D: { - const size_t origin[3] = {0, 0, 0}; - const size_t region[3] = {src.image_width, src.image_height, 1}; - clEnqueueReadImage(queue_, src_handle, CL_TRUE, origin, region, 0, 0, dest, 0, nullptr, nullptr); - break; - } - default: throw std::runtime_error("Unsupported copy for this memory type."); + case MEM_TYPE_BUFFER: + clEnqueueReadBuffer(queue_, src_handle, CL_TRUE, 0, src.size_in_bytes, dest, 0, nullptr, nullptr); + break; + case MEM_TYPE_IMAGE_2D: { + const size_t origin[3] = {0, 0, 0}; + const size_t region[3] = {src.image_width, src.image_height, 1}; + clEnqueueReadImage(queue_, src_handle, CL_TRUE, origin, region, 0, 0, dest, 0, nullptr, nullptr); + break; + } + default: throw std::runtime_error("Unsupported copy for this memory type."); } } cl_mem OpenCLBackend::get_cl_mem(const Tensor &tensor) const { if (tensor.backend() != this) throw std::runtime_error("Tensor is not on this backend."); - const auto& mem = tensor.device_memory(); + const auto &mem = tensor.device_memory(); if (mem.handle == nullptr) throw std::runtime_error("Tensor CL handle is null."); return static_cast(mem.handle); } - Op *OpenCLBackend::opCreate(const OpParam &op_param, std::string name, int threadCount) { OpType type = (OpType)op_param.find("type")->second; auto it = op_creator_map_.find(type); @@ -355,16 +353,15 @@ void OpenCLBackend::registerFuncs() { std::cout << "OpenCLBackend funcs is abanded." << std::endl; } - // 用以下最终完整版替换您的 convert_fp_data 函数 void OpenCLBackend::convert_fp_data(Tensor *src, Tensor *dest) { if (src->device() != MLLM_OPENCL || dest->device() != MLLM_OPENCL) { throw std::runtime_error("Type conversion on GPU requires both tensors to be on OpenCL backend."); } - + // 获取源和目标的内存描述符 - auto& src_mem = src->device_memory(); - auto& dest_mem = dest->device_memory(); + auto &src_mem = src->device_memory(); + auto &dest_mem = dest->device_memory(); // =================================================== // ============ 第一层决策:根据内存类型 ============ @@ -380,41 +377,40 @@ void OpenCLBackend::convert_fp_data(Tensor *src, Tensor *dest) { } else if (src->dtype() == MLLM_TYPE_F16 && dest->dtype() == MLLM_TYPE_F32) { kernel_to_use = kernel_fp16_to_fp32_buffer_; } else { - if(src->dtype() == dest->dtype()) return; + if (src->dtype() == dest->dtype()) return; throw std::runtime_error("Unsupported Buffer conversion types."); } cl_mem src_buf = get_cl_mem(*src); cl_mem dest_buf = get_cl_mem(*dest); int count = src->count(); - + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &src_buf); clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &dest_buf); clSetKernelArg(kernel_to_use, 2, sizeof(int), &count); - const size_t global_work_size[1] = { (size_t)count }; + const size_t global_work_size[1] = {(size_t)count}; clEnqueueNDRangeKernel(queue_, kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); } else if (src_mem.type == MEM_TYPE_IMAGE_2D) { - - if (dest_mem.type != MEM_TYPE_IMAGE_2D) throw std::runtime_error("Destination must be an Image for Image conversion."); + if (dest_mem.type != MEM_TYPE_IMAGE_2D) throw std::runtime_error("Destination must be an Image for Image conversion."); cl_kernel kernel_to_use = nullptr; - + if (src->dtype() == MLLM_TYPE_F32 && dest->dtype() == MLLM_TYPE_F16) { kernel_to_use = kernel_fp32_to_fp16_image_; } else if (src->dtype() == MLLM_TYPE_F16 && dest->dtype() == MLLM_TYPE_F32) { kernel_to_use = kernel_fp16_to_fp32_image_; } else { - if(src->dtype() == dest->dtype()) return; + if (src->dtype() == dest->dtype()) return; throw std::runtime_error("Unsupported Image conversion types."); } - + // **新增**: 健壮性检查,如果内核未创建(例如硬件不支持FP16),则报错 if (!kernel_to_use) { throw std::runtime_error("Image conversion kernel is not available. This may be due to lack of FP16 hardware support."); } - + cl_mem src_img = get_cl_mem(*src); cl_mem dest_img = get_cl_mem(*dest); const int width = src_mem.image_width; @@ -427,7 +423,7 @@ void OpenCLBackend::convert_fp_data(Tensor *src, Tensor *dest) { clSetKernelArg(kernel_to_use, 3, sizeof(int), &width); clSetKernelArg(kernel_to_use, 4, sizeof(int), &height); - const size_t global_work_size[2] = { (size_t)width, (size_t)height }; + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; clEnqueueNDRangeKernel(queue_, kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); } } @@ -436,7 +432,6 @@ void registerOpenCLBackendCreator() { InsertBackendCreatorMap(MLLM_OPENCL, std::make_shared()); } - std::vector OpenCLBackend::runLayer(Layer *layer, std::vector inputs, int N) { throw std::runtime_error("runLayer not implemented for OpenCLBackend"); return {}; @@ -507,7 +502,7 @@ std::vector OpenCLBackend::runOp(Op *op, std::vector inputs, std #ifdef DEBUGOPTIME uint64_t time_end = mllm_time_us(); double inference_time_ = (time_end - time_start) / 1000.0F; // ms - std::cout << layer->op_->name() << " | time: " << inference_time_ << "ms" << std::endl; + std::cout << op->name() << " | time: " << inference_time_ << "ms" << std::endl; #endif vector results; @@ -520,5 +515,4 @@ std::vector OpenCLBackend::runForward(Module *module, std::vector QNNBackend::runForward(Module *module, std::vector i // Module setUp & execute if (inputs[0].ttype() == TensorType::INPUT_TENSOR) { if (module->prefilling_token_size_ == 0) { // first time init - module->prefilling_token_size_ = inputs[0].sequence(); + module->prefilling_token_size_ = inputs[0].sequence() * inputs[0].batch(); } else if (module->decoding_token_size_ == 0) { - module->decoding_token_size_ = inputs[0].sequence(); + module->decoding_token_size_ = inputs[0].sequence() * inputs[0].batch(); } for (int i = 0; i < inputs.size(); i++) { auto &input = inputs[i]; diff --git a/src/backends/xnnpack/XnnpackBackend.cpp b/src/backends/xnnpack/XnnpackBackend.cpp index ff0825d93..5f87accfb 100644 --- a/src/backends/xnnpack/XnnpackBackend.cpp +++ b/src/backends/xnnpack/XnnpackBackend.cpp @@ -1213,9 +1213,9 @@ std::vector XnnpackBackend::runForward(Module *module, std::vectorprefilling_token_size_ == 0) { // first time init - module->prefilling_token_size_ = inputs[0].sequence(); + module->prefilling_token_size_ = inputs[0].sequence() * inputs[0].batch(); } else if (module->decoding_token_size_ == 0) { - module->decoding_token_size_ = inputs[0].sequence(); + module->decoding_token_size_ = inputs[0].sequence() * inputs[0].batch(); } for (int i = 0; i < inputs.size(); i++) { auto &input = inputs[i]; diff --git a/src/models/ling/mbp/modeling_bailing_moe_mbmpip.hpp b/src/models/ling/mbp/modeling_bailing_moe_mbmpip.hpp new file mode 100644 index 000000000..3577a364e --- /dev/null +++ b/src/models/ling/mbp/modeling_bailing_moe_mbmpip.hpp @@ -0,0 +1,561 @@ +#pragma once +#include "Layer.hpp" +#include "Module.hpp" +#include "Tensor.hpp" +#include "Trace.hpp" +#include "Types.hpp" +#include "../configuration_bailing_moe.hpp" +#include "settings_bailing_moe_mbp.hpp" +#include "models/transformer/modeling_transformer.hpp" +#include +#include +#include +#include +#include + +#define MBP_THREAD + +using namespace mllm; + +class BailingMoeMLP final : public Module { +public: + BailingMoeMLP() = default; + BailingMoeMLP(int hidden_size, int intermediate_size, const BailingMoeNameConfig &names, const std::string &base_name) { + gate_proj = Linear(hidden_size, intermediate_size, false, base_name + names._gate_proj_name); + silu = SiLU(base_name + "act"); + up_proj = Linear(hidden_size, intermediate_size, false, base_name + names._up_proj_name); + down_proj = Linear(intermediate_size, hidden_size, false, base_name + names._down_proj_name); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto x = gate_proj(inputs[0]); + x = silu(x); + auto y = up_proj(inputs[0]); // ERROR + x = x * y; + x = down_proj(x); + return {x}; + } + + void load() { + gate_proj.load(); + up_proj.load(); + down_proj.load(); + } + bool loaded() { + return gate_proj.loaded() && up_proj.loaded() && down_proj.loaded(); + } + void free() { + gate_proj.free(); + up_proj.free(); + down_proj.free(); + } + +private: + Layer gate_proj; + Layer up_proj; + Layer down_proj; + Layer silu; +}; + +class BailingMoeGate final : public Module { +public: + BailingMoeGate() = default; + BailingMoeGate(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const std::string &base_name) { + gate = Linear(config.hidden_size, config.num_experts, false, base_name + "gate"); + softmax = Softmax(DIMENSION, false, base_name + "softmax"); + num_experts_per_tok = config.num_experts_per_tok; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto scores = softmax(gate(inputs[0])); + auto experts_w_i = Tensor::topk(scores, num_experts_per_tok, DIMENSION); + auto topk_weight = experts_w_i[0]; // 1, batch*seq, 1, k + auto topk_idx = experts_w_i[1]; // 1, batch*seq, 1, k + topk_idx = topk_idx.view(-1, 1, 1, -1); // 1, 1, 1, k* batch*seq + topk_weight = topk_weight / topk_weight.sum(DIMENSION); // 1, batch*seq, 1, k + return {scores, topk_weight, topk_idx}; + } + +private: + Layer gate; + Softmax softmax; + int num_experts_per_tok{}; +}; + +class BailingMoeSparseMoeBlock final : public Module { +public: + BailingMoeSparseMoeBlock() = default; + BailingMoeSparseMoeBlock(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + experts = List(config.num_experts, config.hidden_size, config.moe_intermediate_size, names, base_name + "experts."); + gate = BailingMoeGate(config, names, base_name); + num_experts_per_tok = config.num_experts_per_tok; + num_shared_experts = config.num_shared_experts; + if (num_shared_experts > 0) { + shared_experts = BailingMoeMLP(config.hidden_size, + config.moe_intermediate_size * config.num_shared_experts, + names, base_name + "shared_experts."); + } + num_hidden_layers = config.num_hidden_layers; + } + // receive embeds + std::vector Forward(std::vector inputs, std::vector args) override { + int layer_idx = std::any_cast(args[0]); + auto hidden_states = inputs[0]; + auto identity = hidden_states; + if (hidden_states.batch() > 1) { + hidden_states = hidden_states.view(1, -1, ANYDIM, -1); // 1, batch*seq, 1, hidden + } + auto gates_t = gate({hidden_states}); // 1, batch*seq, 1, num_experts + auto scores = gates_t[0]; // 1, batch*seq, 1, num_experts + auto topk_weight = gates_t[1]; // 1, batch*seq, + auto topk_idx = gates_t[2]; // 1, batch*seq, 1, k + hidden_states = moe_infer(hidden_states, topk_weight, topk_idx, layer_idx); // 1, batch*seq, 1, hidden + if (num_shared_experts) { + hidden_states = hidden_states + shared_experts({identity})[0]; // add shared experts + } + if (hidden_states.batch() > 1) { + // expert_cache.view(ANYDIM, seq, -1, -1);//TODO + } + return {hidden_states}; + } + Tensor moe_infer(Tensor hidden_states, + Tensor &topk_weight, + Tensor &topk_idx, + int layer_idx) { + auto idxs = topk_idx.argsort(); + auto tokens_per_expert = topk_idx.bincount(); + auto token_idxs = idxs / num_experts_per_tok; + int start_idx = 0; + int end_idx = start_idx; + auto expert_cache = Tensor::zero_like(hidden_states); + map exp_token_idx_list, exp_idx_list; + std::vector sorted_keys; + for (int i = 0; i < experts.size(); ++i) { + if (i >= tokens_per_expert.dimension()) break; + int this_token_num = tokens_per_expert.dimension() ? tokens_per_expert.d(0, 0, 0, i) : 0; + if (!this_token_num) continue; + end_idx = start_idx + this_token_num; + auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); + auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); + topk_weight = topk_weight.view(-1, -1, 1, 1); + exp_token_idx_list[i] = exp_token_idx; + sorted_keys.push_back(i); + exp_idx_list[i] = exp_idx; + start_idx = end_idx; + } + if (!sorted_keys.empty()) { + int mv_i = 0; + if (std::find(sorted_keys.begin(), sorted_keys.end(), mv_i) != sorted_keys.end()) { + sorted_keys.erase(std::remove(sorted_keys.begin(), sorted_keys.end(), mv_i), sorted_keys.end()); + sorted_keys.insert(sorted_keys.begin(), mv_i); + } + } + + if (sorted_keys.empty() || Module::doLoad) { + return expert_cache; + } + +#ifdef MBP_THREAD + // 步骤 1: 启动流水线 - 预先为第一个专家派发任务 + { + int first_expert_id = sorted_keys[0]; + // 派发加载任务 + if (!experts[first_expert_id].loaded()) { + LoadRequest req{layer_idx, first_expert_id}; + lock_guard lk(queue_mutex); + load_requests.push(req); + queue_cv.notify_one(); + } + // 派发裁剪任务 + ClipRequest req{ + layer_idx, first_expert_id, hidden_states, + exp_token_idx_list[first_expert_id], topk_weight, exp_idx_list[first_expert_id]}; + lock_guard lk(clip_queue_mutex); + clip_requests.push(req); + clip_queue_cv.notify_one(); + } +#endif + + // 步骤 2: 循环处理 + for (int ii = 0; ii < sorted_keys.size(); ii++) { + int expert_id = sorted_keys[ii]; + string expert_name = std::to_string(layer_idx) + "_" + std::to_string(expert_id); + +#ifdef MBP_THREAD + // A. [预取] 为下一个专家 (ii+1) 派发任务 + bool is_last_expert_in_layer = (ii == sorted_keys.size() - 1); + if (!is_last_expert_in_layer || (is_last_expert_in_layer && layer_idx < num_hidden_layers - 1)) { + int q_layer_idx, q_expert_id; + bool should_dispatch_clip = false; + + if (is_last_expert_in_layer) { // 如果是本层最后一个,预取下一层的 expert 0 + q_layer_idx = layer_idx + 1; + q_expert_id = 0; + // 对于下一层的专家,我们无法知道它是否有token,因此不派发裁剪任务 + should_dispatch_clip = false; + } else { // 否则,预取本层的下一个专家 + q_layer_idx = layer_idx; + q_expert_id = sorted_keys[ii + 1]; + // 仅当该专家确实需要处理时,才派发裁剪任务 + should_dispatch_clip = exp_token_idx_list.count(q_expert_id) > 0; + } + + // 派发加载任务 + LoadRequest load_req{q_layer_idx, q_expert_id}; + lock_guard load_lk(queue_mutex); + load_requests.push(load_req); + queue_cv.notify_one(); + + // 根据判断条件派发裁剪任务 + if (should_dispatch_clip) { + ClipRequest clip_req{ + q_layer_idx, q_expert_id, hidden_states, + exp_token_idx_list[q_expert_id], topk_weight, exp_idx_list[q_expert_id]}; + lock_guard clip_lk(clip_queue_mutex); + clip_requests.push(clip_req); + clip_queue_cv.notify_one(); + } + } + + // B. [等待] 等待当前专家 (ii) 的任务完成 + // 等待加载 + double time_start_w = (mllm_time_us() - start_time) / 1000.0F; + if (!experts[expert_id].loaded()) { + unique_lock lock(*mtxs[layer_idx][expert_id]); + cvs[layer_idx][expert_id]->wait(lock, [&] { return dones[layer_idx][expert_id].load(memory_order_acquire); }); + } + double time_end_w = (mllm_time_us() - start_time) / 1000.0F; + expert_wait_times[expert_name] = {time_start_w, time_end_w}; + + // 等待裁剪并获取结果 + Tensor expert_tokens, topk_weight_clip; + { + unique_lock lock(*clip_mtxs[layer_idx][expert_id]); + clip_cvs[layer_idx][expert_id]->wait(lock, [&] { return clip_dones[layer_idx][expert_id].load(memory_order_acquire); }); + + std::lock_guard result_lk(clip_results_mutex); + auto &clipped_pair = clipped_data.at(expert_name); + expert_tokens = clipped_pair.first; + topk_weight_clip = clipped_pair.second; + } +#else + // 非多线程模式,直接加载和裁剪 + if (!experts[expert_id].loaded()) experts[expert_id].load(); + auto expert_tokens = hidden_states.clip(exp_token_idx_list[expert_id], SEQUENCE); + auto topk_weight_clip = topk_weight.clip(exp_idx_list[expert_id], SEQUENCE); +#endif + + // C. [计算] 使用准备好的数据进行计算 + double time_start_cal = (mllm_time_us() - start_time) / 1000.0F; + auto expert_out = experts[expert_id]({expert_tokens})[0]; + expert_out = expert_out * topk_weight_clip; + expert_cache.scatter_add(expert_out, exp_token_idx_list[expert_id]); + double time_end_cal = (mllm_time_us() - start_time) / 1000.0F; + expert_cal_times[expert_name] = {time_start_cal, time_end_cal}; + + // D. [清理] 清理当前专家的资源 + experts[expert_id].free(); +#ifdef MBP_THREAD + { + std::lock_guard result_lk(clip_results_mutex); + clipped_data.erase(expert_name); + } + // std::cout << clipped_data.size() << std::endl; + clip_dones[layer_idx][expert_id] = false; + dones[layer_idx][expert_id] = false; +#endif + } + return expert_cache; + } + + void load_experts(int expert_idx) { + int result; + experts[expert_idx].load(); + } + +private: + BailingMoeMLP shared_experts; + std::vector experts; + BailingMoeGate gate; + int num_shared_experts{}; + int num_experts_per_tok{}; + int num_hidden_layers{}; +}; + +class BailingMoeDecoder final : public Module { +public: + BailingMoeDecoder() = default; + BailingMoeDecoder(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, + config.hidden_size / config.num_attention_heads, + SPLIT_HD, PostQkv_NONE, false, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, + config.cache_limit, config.use_cache, config.use_qkv_bias, config.use_bias, + config.attn_implementation, names, base_name + names._attn_base_name); + moe = BailingMoeSparseMoeBlock(config, names, base_name + names._ffn_base_name); + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); + num_hidden_layers = config.num_hidden_layers; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = input_layernorm(inputs[0]); + int layer_idx = std::any_cast(args[0]); + hidden_states = self_atten({hidden_states, hidden_states, hidden_states})[0]; + auto tmp = hidden_states + inputs[0]; + hidden_states = post_attention_layernorm(tmp); + hidden_states = moe({hidden_states}, layer_idx)[0]; + hidden_states = hidden_states + tmp; + return {hidden_states}; + } + + void load_experts(int expert_idx) { + moe.load_experts(expert_idx); + } + + MultiHeadAttention &get_attention() { + return self_atten; + } + +private: + MultiHeadAttention self_atten; + BailingMoeSparseMoeBlock moe; + Layer input_layernorm; + Layer post_attention_layernorm; + int num_hidden_layers; +}; + +class BailingMoeModel final : public Module { +public: + BailingMoeModel() = default; + BailingMoeModel(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + blocks = List(config.num_hidden_layers, config, names, base_name); + norm = RMSNorm(config.hidden_size, config.rms_norm_eps, names.post_norm_name); + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + int layer_idx = 0; + for (auto &block : blocks) { + hidden_states = block({hidden_states}, layer_idx)[0]; + layer_idx++; + } + hidden_states = norm(hidden_states); + return {hidden_states}; + } + + void load_experts(int layer_idx, int expert_idx) { + blocks[layer_idx].load_experts(expert_idx); + } + void clear_kvcache() override { + for (auto &block : blocks) { + auto kvcache = block.get_attention().get_cache(); + for (auto &cache : kvcache) { cache->clearCache(); } + auto ropes = block.get_attention().get_rope(); + for (auto &rope : ropes) { rope->clearCache(); } + } + } + +private: + std::vector blocks; + Layer norm; +}; + +class BailingMoeForCausalLM final : public Module { +public: + BailingMoeForCausalLM(BailingMoeConfig &config) { + auto names = config.names_config; + hidden_size = config.hidden_size; + embedding = Embedding(config.vocab_size, config.hidden_size, names.token_embd_name); + model = BailingMoeModel(config, names, names.blk_name); + lm_head = Linear(config.hidden_size, config.vocab_size, false, names.lm_head_name); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + std::vector outputs; + clearMBPtimes(); +#ifdef MBP_THREAD + start_time = mllm_time_us(); + mbp_finish.store(false, std::memory_order_relaxed); + if (inputs[0].dimension() == 1) { + omp_set_max_active_levels(2); // Enable OpenMP nesting +#pragma omp parallel num_threads(3) + if (omp_get_thread_num() == 0) { // 根据线程ID决定执行哪个函数 +#if defined(__ARM_NEON) && !defined(__APPLE__) + { + struct sched_param param; + param.sched_priority = 21; // 范围 1–99,根据设备可酌情调整 + pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + } + // ─── 2. 绑定到大核(big cluster)以减少与小核的资源争用 ────────────── + { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(2, &cpuset); + sched_setaffinity(pthread_self(), sizeof(cpuset), &cpuset); + } +#endif + mbp_load(); + } else if (omp_get_thread_num() == 1) { // 线程1: 裁剪 (新增) + +#if defined(__ARM_NEON) && !defined(__APPLE__) + { + struct sched_param param; + param.sched_priority = 20; // 范围 1–99,根据设备可酌情调整 + pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + } + // ─── 2. 绑定到大核(big cluster)以减少与小核的资源争用 ────────────── + { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(3, &cpuset); + sched_setaffinity(pthread_self(), sizeof(cpuset), &cpuset); + } +#endif + mbp_clip(); + } else { + // #if defined(__ARM_NEON) && !defined(__APPLE__) + // { + // struct sched_param param; + // param.sched_priority = 22; // 范围 1–99,根据设备可酌情调整 + // pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + // } + // // ─── 2. 绑定到大核(big cluster)以减少与小核的资源争用 ────────────── + // { + // cpu_set_t cpuset; + // CPU_ZERO(&cpuset); + // CPU_SET(7, &cpuset); + // sched_setaffinity(pthread_self(), sizeof(cpuset), &cpuset); + // } + // #endif + outputs = do_Forward(inputs, args); + } + } else { +#endif + outputs = do_Forward(inputs, args); +#ifdef MBP_THREAD + } +#endif + return outputs; + } + void clear_kvcache() override { + model.clear_kvcache(); + } + + std::vector do_Forward(std::vector inputs, std::vector args) { + auto x = embedding(inputs[0]); + auto outputs = model({x})[0]; + if (outputs.sequence() > 1) { + outputs = outputs.clip({}, {}, {-1}, {}); + } + outputs = lm_head(outputs); + +#ifdef MBP_THREAD + // 设置 mbp_finish 为 true,结束 mbp_load 线程 + // 1. 设置内存序保证可见性 + mbp_finish.store(true, std::memory_order_release); // 改为 release 内存序 + // 2. 主动唤醒所有等待线程 + { + std::lock_guard lk(queue_mutex); + queue_cv.notify_all(); // 必须加锁后通知 + } + { + std::lock_guard lk(clip_queue_mutex); + clip_queue_cv.notify_all(); // [新增] 唤醒 clip 线程 + } + // 3. 添加二次状态检查 + std::atomic_thread_fence(std::memory_order_seq_cst); + // std::cout << "do_Forward finish " << load_requests.size() << std::endl; +#endif + return {outputs}; + } + void load_experts(int layer_idx, int expert_idx) { + model.load_experts(layer_idx, expert_idx); + } + void mbp_load() { + while (!mbp_finish.load(std::memory_order_acquire)) { + std::unique_lock lk(queue_mutex); + queue_cv.wait(lk, [this] { + return !load_requests.empty() || mbp_finish.load(std::memory_order_acquire); + }); + + if (mbp_finish.load(std::memory_order_acquire)) { + break; + } + + while (!load_requests.empty()) { + auto req = load_requests.front(); + load_requests.pop(); + lk.unlock(); // 释放锁以便其他线程入队 + { // 执行加载 + std::unique_lock expert_lk(*mtxs[req.layer][req.expert]); + if (!dones[req.layer][req.expert].load(std::memory_order_acquire)) { + double time_start = (mllm_time_us() - start_time) / 1000.0F; // ms + + // std::cout << "load_requests.load_: " << req.layer << " " << req.expert << std::endl; + load_experts(req.layer, req.expert); + // std::cout << "load_requests.load_d: " << req.layer << " " << req.expert << std::endl; + dones[req.layer][req.expert].store(true, std::memory_order_release); + + string expert_name = std::to_string(req.layer) + "_" + std::to_string(req.expert); + double time_end = (mllm_time_us() - start_time) / 1000.0F; // ms + load_times[expert_name] = {time_start, time_end}; + } + } + cvs[req.layer][req.expert]->notify_all(); + lk.lock(); // 重新获取锁处理下一个请求 + } + } + // std::cout << "mbp_load finish" << std::endl; + } + void mbp_clip() { + while (!mbp_finish.load(std::memory_order_acquire)) { + std::unique_lock lk(clip_queue_mutex); + clip_queue_cv.wait(lk, [this] { + return !clip_requests.empty() || mbp_finish.load(std::memory_order_acquire); + }); + + if (mbp_finish.load(std::memory_order_acquire)) { + break; + } + + while (!clip_requests.empty()) { + auto req = clip_requests.front(); + clip_requests.pop(); + lk.unlock(); + + string expert_name = std::to_string(req.layer) + "_" + std::to_string(req.expert); + + // --- 执行裁剪 --- + double time_start_ = (mllm_time_us() - start_time) / 1000.0F; + auto expert_tokens = req.hidden_states.clip(req.exp_token_idx, SEQUENCE); + auto topk_weight_clip = req.topk_weight.clip(req.exp_idx, SEQUENCE); + double time_end_ = (mllm_time_us() - start_time) / 1000.0F; + expert_clip_times[expert_name] = {time_start_, time_end_}; + + // --- 存储结果 --- + { + std::lock_guard result_lk(clip_results_mutex); + clipped_data[expert_name] = {expert_tokens, topk_weight_clip}; + } + + // --- 发送完成信号 --- + { + std::unique_lock done_lk(*clip_mtxs[req.layer][req.expert]); + clip_dones[req.layer][req.expert].store(true, std::memory_order_release); + } + clip_cvs[req.layer][req.expert]->notify_all(); + + lk.lock(); + } + } + // std::cout << "mbp_clip finish" << std::endl; + } + +private: + int hidden_size; + bool tie_embedding_words; + Layer embedding; + Layer lm_head; + BailingMoeModel model; +}; diff --git a/src/models/ling/mbp/settings_bailing_moe_mbp.hpp b/src/models/ling/mbp/settings_bailing_moe_mbp.hpp index 4f9f7f86c..a0ceedda9 100644 --- a/src/models/ling/mbp/settings_bailing_moe_mbp.hpp +++ b/src/models/ling/mbp/settings_bailing_moe_mbp.hpp @@ -13,8 +13,10 @@ #include #include #include +#include "Tensor.hpp" using namespace std; +using namespace mllm; int mbp_load_layer_idx; int mbp_load_expert_idx; @@ -23,16 +25,41 @@ struct LoadRequest { int layer; int expert; }; - queue load_requests; // 替换原do_mbp_load相关变量 mutex queue_mutex; // 队列互斥锁 condition_variable queue_cv; // 队列条件变量 -atomic mbp_finish{false}; // 改为原子布尔 + +// ========= Clip Thread Globals (NEW) ========= +// 1. 新增 ClipRequest 结构体 +struct ClipRequest { + int layer; + int expert; + Tensor hidden_states; + Tensor exp_token_idx; + Tensor topk_weight; + Tensor exp_idx; +}; +// 2. 新增 clip 线程的任务队列、锁和条件变量 +queue clip_requests; +mutex clip_queue_mutex; +condition_variable clip_queue_cv; +// 3. 新增用于存储 clip 结果的 map 和其互斥锁 +map> clipped_data; +mutex clip_results_mutex; +//============ End Clip Thread Globals ============ + +atomic mbp_finish{false}; // 改为原子布尔 vector>> mtxs; // 每个层和专家一个互斥锁 vector>> cvs; // 每个层和专家一个条件变量 vector>> dones; // 原子布尔保证可见性 +// --- Clipping Primitives (NEW) --- +// 4. 新增 clip 线程的同步对象 +vector>> clip_mtxs; +vector>> clip_cvs; +vector>> clip_dones; + // 修改 MAP_MINICPMMOE_MBP_HPP 中的相关部分 inline void reset_syntax_mbm(int layer_idx, int expert_idx) { @@ -41,19 +68,32 @@ inline void reset_syntax_mbm(int layer_idx, int expert_idx) { } inline void minicpmmoe_mbp_init(int num_layers, int num_experts) { + // 初始化 loading 相关的变量 mtxs.resize(num_layers); cvs.resize(num_layers); dones.resize(num_layers); - for (int i = 0; i < num_layers; ++i) { mtxs[i].resize(num_experts); cvs[i].resize(num_experts); - dones[i] = std::vector>(num_experts); // Step 2: 显式构造 - + dones[i] = std::vector>(num_experts); for (int j = 0; j < num_experts; ++j) { mtxs[i][j] = make_unique(); cvs[i][j] = make_unique(); - dones[i][j].store(false, std::memory_order_relaxed); // 显式原子初始化 + dones[i][j].store(false, std::memory_order_relaxed); + } + } + // 初始化 clipping 相关的变量 + clip_mtxs.resize(num_layers); + clip_cvs.resize(num_layers); + clip_dones.resize(num_layers); + for (int i = 0; i < num_layers; ++i) { + clip_mtxs[i].resize(num_experts); + clip_cvs[i].resize(num_experts); + clip_dones[i] = std::vector>(num_experts); + for (int j = 0; j < num_experts; ++j) { + clip_mtxs[i][j] = make_unique(); + clip_cvs[i][j] = make_unique(); + clip_dones[i][j].store(false, std::memory_order_relaxed); } } } @@ -68,6 +108,7 @@ void clearMBPtimes() { expert_cal_times.clear(); expert_clip_times.clear(); expert_wait_times.clear(); + clipped_data.clear(); // [请确认已添加] 清理裁剪结果,防止内存泄漏 start_time = 0; } void prinMBPtimes() { diff --git a/src/models/qwen/configuration_qwen.hpp b/src/models/qwen/configuration_qwen.hpp index 5a5a8eba6..6304253fa 100644 --- a/src/models/qwen/configuration_qwen.hpp +++ b/src/models/qwen/configuration_qwen.hpp @@ -131,7 +131,7 @@ struct QWenConfig : public TransformerConfig { sliding_window = 32768; vocab_size = 151936; tie_embedding_words = true; - } else if (billionsType == "1.5b-rotated") { + } else if ((billionsType == "1.5b-rotated") || (billionsType == "1.5b-lm")) { attention_dropout = 0.0; std::string hidden_act = "silu"; hidden_size = 1536; diff --git a/src/models/qwen/tokenization_qwen.hpp b/src/models/qwen/tokenization_qwen.hpp index 4a803a0cf..5976d6f2b 100644 --- a/src/models/qwen/tokenization_qwen.hpp +++ b/src/models/qwen/tokenization_qwen.hpp @@ -15,6 +15,7 @@ #include "tokenizers/Unicode.hpp" #include #include +#include using namespace mllm; @@ -177,6 +178,54 @@ class QWenTokenizer final : public BPETokenizer { return Tokenizer::tokens2Input(ret); } + Tensor tokenize(vector texts, string name = "input", BackendType type = MLLM_CPU) { + std::vector> rets; + for (auto &text : texts) { + std::vector ret; + if (split_special_tokens_) { + const auto word_collection = unicode_regex_split(text, FIXED_PAT_STRS); + for (auto &piece : word_collection) { + std::vector tmp; + BPETokenizer::tokenize(piece, tmp, false, true, ""); + ret.insert(ret.end(), tmp.begin(), tmp.end() - 1); + } + } else { + auto parts = _splitWithDelimiters(text, special_tokens); + for (auto &p : parts) { + if (std::find(special_tokens.begin(), special_tokens.end(), p) != special_tokens.end()) { + std::string token; + for (auto b : UTF8(p)) token += byte_encoder_[b]; + + std::vector tmp; + BPETokenizer::tokenize(token, tmp, false, special_tokens, true); + ret.insert(ret.end(), tmp.begin(), tmp.end() - 1); + } else { + const auto word_collection = unicode_regex_split(p, FIXED_PAT_STRS); + for (auto &piece : word_collection) { + std::vector tmp; + BPETokenizer::tokenize(piece, tmp, false, true, ""); + assert(!tmp.empty()); + ret.insert(ret.end(), tmp.begin(), tmp.end() - 1); + } + } + } + } + rets.push_back(ret); + } + size_t max_len = 0; + for (const auto &vec : rets) { + if (vec.size() > max_len) { + max_len = vec.size(); + } + } + for (auto &vec : rets) { + if (vec.size() < max_len) { + vec.insert(vec.begin(), max_len - vec.size(), bos_id_); + } + } + return Tokenizer::tokens2Input(rets); + } + std::pair tokenizeWithPadding(std::string &text, int seqLength, int vocab_size) { std::vector ret; diff --git a/tools/quantizer/QuantWriter.cpp b/tools/quantizer/QuantWriter.cpp index f4b63beef..97d5cc983 100644 --- a/tools/quantizer/QuantWriter.cpp +++ b/tools/quantizer/QuantWriter.cpp @@ -79,7 +79,26 @@ QuantWriter::~QuantWriter() { }; int QuantWriter::readParams() { - param_names_ = param_loader_->getParamNames(); + original_param_names_ = param_loader_->getParamNames(); // 保存原始参数名 + param_names_ = original_param_names_; // 复制一份用于可能的操作 + + // 检查 lm_head.weight 是否存在,如果不存在且 model.embed_tokens.weight 存在,则添加它 + bool lm_head_exists = false; + bool embed_tokens_exists = false; + for (const auto &name : original_param_names_) { + if (name == "lm_head.weight") { + lm_head_exists = true; + } + if (name == "model.embed_tokens.weight") { + embed_tokens_exists = true; + } + } + + if (!lm_head_exists && embed_tokens_exists) { + std::cout << "INFO: lm_head.weight not found, will be created by copying model.embed_tokens.weight" << std::endl; + param_names_.push_back("lm_head.weight"); + } + paddingIndex(param_names_); return param_names_.size(); } @@ -138,173 +157,187 @@ void QuantWriter::quantize(DataType target_quant_type, const std::string &other_ int tmp_hidden_dim = -1; int vit_tmp_hidden_dim = -1; - for (const auto &name : param_names_) { - ParamMetadata meta = param_loader_->getParamMetadata(name); - const uint64_t num_floats = meta.size / sizeof(float); - - for (const auto &name : param_names_) { - if (tmp_hidden_dim != -1 && vit_tmp_hidden_dim != -1) { - break; // 如果都找到了,就提前退出预扫描 - } - /* - if (tmp_hidden_dim == -1 && find_in_layers(name, {"model.layers.0.input_layernorm"})) { - ParamMetadata meta = param_loader_->getParamMetadata(name); - tmp_hidden_dim = meta.size / sizeof(float); - } - if (vit_tmp_hidden_dim == -1 && find_in_layers(name, {"visual.patch_embed.norm"})) { - ParamMetadata meta = param_loader_->getParamMetadata(name); - vit_tmp_hidden_dim = meta.size / sizeof(float); - } - */ - if (tmp_hidden_dim == -1 && (name.find("model") != std::string::npos && name.find("norm") != std::string::npos)) { - ParamMetadata meta = param_loader_->getParamMetadata(name); - tmp_hidden_dim = meta.size / sizeof(float); - std::cout << " - Found hidden dimension (tmp_hidden_dim): " << tmp_hidden_dim << " from layer '" << name << "'" << std::endl; - } - if (vit_tmp_hidden_dim == -1 && (name.find("visual") != std::string::npos && name.find("norm") != std::string::npos)) { - ParamMetadata meta = param_loader_->getParamMetadata(name); - vit_tmp_hidden_dim = meta.size / sizeof(float); - std::cout << " - Found ViT hidden dimension (vit_tmp_hidden_dim): " << vit_tmp_hidden_dim << " from layer '" << name << "'" << std::endl; - } + // 预扫描以找到隐藏维度 + std::cout << "Pre-scanning to find hidden dimensions..." << std::endl; + for (const auto &name : original_param_names_) { + if (tmp_hidden_dim == -1 && (name.find("model") != std::string::npos && name.find("norm") != std::string::npos)) { + ParamMetadata meta = param_loader_->getParamMetadata(name); + tmp_hidden_dim = meta.size / sizeof(float); + std::cout << " - Found hidden dimension (tmp_hidden_dim): " << tmp_hidden_dim << " from layer '" << name << "'" << std::endl; + } + if (vit_tmp_hidden_dim == -1 && (name.find("visual") != std::string::npos && name.find("norm") != std::string::npos)) { + ParamMetadata meta = param_loader_->getParamMetadata(name); + vit_tmp_hidden_dim = meta.size / sizeof(float); + std::cout << " - Found ViT hidden dimension (vit_tmp_hidden_dim): " << vit_tmp_hidden_dim << " from layer '" << name << "'" << std::endl; + } + if (tmp_hidden_dim != -1 && vit_tmp_hidden_dim != -1) { + break; } + } + for (const auto &name : param_names_) { + bool is_copied_lm_head = (name == "lm_head.weight" && std::find(original_param_names_.begin(), original_param_names_.end(), name) == original_param_names_.end()); DataType final_quant_type = getQuantizationTypeFor(name, target_quant_type, other_flag); std::cout << "Processing param " << name << " -> " << DataTypeName(final_quant_type) << " ... "; + if (is_copied_lm_head) { + std::cout << "(copied from model.embed_tokens.weight) "; + } fflush(stdout); beginWriteParam(name, final_quant_type); - fseek(fp_in, meta.offset, SEEK_SET); - if (final_quant_type == MLLM_TYPE_F32) { - std::vector f32_buffer(meta.size); - fread(f32_buffer.data(), 1, meta.size, fp_in); - writeChunk(f32_buffer.data(), meta.size); - } -#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) - else if (final_quant_type == MLLM_TYPE_KLEIDIAI_Q4_0) { - int H = find_in_layers(name, {"visual"}) ? vit_tmp_hidden_dim : tmp_hidden_dim; - if (H <= 0) { - std::cout << "FAIL! Hidden dimension not found for " << name << std::endl; + std::vector full_param_data; + uint64_t num_floats; + + if (is_copied_lm_head) { + full_param_data = load_full_fp32_param("model.embed_tokens.weight"); + if (full_param_data.empty()) { + std::cerr << "FAIL! Failed to load model.embed_tokens.weight for copying." << std::endl; __exit(-1); } - - int N, K; - if (find_in_layers(name, {"w2", "down_proj", "fc2"})) { - N = H; - K = num_floats / N; - } else { - K = H; - N = num_floats / K; + num_floats = full_param_data.size(); + } else { + ParamMetadata meta = param_loader_->getParamMetadata(name); + num_floats = meta.size / sizeof(float); + fseek(fp_in, meta.offset, SEEK_SET); + if (final_quant_type == MLLM_TYPE_KLEIDIAI_Q4_0 || final_quant_type == MLLM_TYPE_Q4_0_4_4) { + full_param_data.resize(num_floats); + fread(full_param_data.data(), sizeof(float), num_floats, fp_in); } + } - // 1. 加载完整的 bias (因为它很小) - std::string bias_name = name; - bias_name.replace(bias_name.find("weight"), 6, "bias"); - std::vector bias_data = load_full_fp32_param(bias_name); - - // 2. 分配转置矩阵的内存 - std::vector transposed_weight_data(num_floats); + if (!full_param_data.empty()) { + void *quant_ptr = nullptr; + uint64_t quant_size = 0; - // 3. 流式读取并转置 - std::vector row_buffer(K); - for (int n = 0; n < N; ++n) { - fread(row_buffer.data(), sizeof(float), K, fp_in); - for (int k = 0; k < K; ++k) { - transposed_weight_data[k * N + n] = row_buffer[k]; + if (final_quant_type == MLLM_TYPE_KLEIDIAI_Q4_0) { +#if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) + int H = find_in_layers(name, {"visual"}) ? vit_tmp_hidden_dim : tmp_hidden_dim; + if (H <= 0) { + std::cout << "FAIL! Hidden dimension not found for " << name << std::endl; + __exit(-1); } - } - - // 4. 分配量化空间并执行量化 - auto block_t = alloc_kleidiai_quant_block(final_quant_type, N, K); - void *quant_ptr = block_t.first; + // ==================【代码修正】================== + // 恢复您指出的、用于判断 N 和 K 的关键逻辑 + int N, K; + if (find_in_layers(name, {"w2", "down_proj", "fc2"})) { + N = H; + if (num_floats % N != 0) { + std::cerr << "FAIL! num_floats not divisible by N for " << name << std::endl; + __exit(-1); + } + K = num_floats / N; + } else { + K = H; + if (num_floats % K != 0) { + std::cerr << "FAIL! num_floats not divisible by K for " << name << std::endl; + __exit(-1); + } + N = num_floats / K; + } + // =============================================== + + std::string bias_name = name; + bias_name.replace(bias_name.find("weight"), 6, "bias"); + std::vector bias_data = load_full_fp32_param(bias_name); + std::vector transposed_weight_data(num_floats); + for (int n = 0; n < N; ++n) + for (int k = 0; k < K; ++k) transposed_weight_data[k * N + n] = full_param_data[n * K + k]; + auto block_t = alloc_kleidiai_quant_block(final_quant_type, N, K); + quant_ptr = block_t.first; + quant_size = block_t.second; #ifndef KAI_FP16_CAL - mllm_kleidai_pack_b_and_bias_qsi4( - (uint8_t *)quant_ptr, - transposed_weight_data.data(), - bias_data.empty() ? nullptr : bias_data.data(), - N, K); + mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), bias_data.empty() ? nullptr : bias_data.data(), N, K); #else - mllm_kleidai_pack_b_and_bias_qsi4_to_fp16( - (uint8_t *)quant_ptr, - transposed_weight_data.data(), - bias_data.empty() ? nullptr : bias_data.data(), - N, K); -#endif - - // 5. 写入量化数据块 - writeChunk(quant_ptr, block_t.second); - delete[] (char *)quant_ptr; - - } + mllm_kleidai_pack_b_and_bias_qsi4_to_fp16((uint8_t *)quant_ptr, transposed_weight_data.data(), bias_data.empty() ? nullptr : bias_data.data(), N, K); #endif - else if (final_quant_type == MLLM_TYPE_Q4_0_4_4) { - // 1. 为 Q4_0_4_4 加载完整的 FP32 数据 - std::vector param_data(num_floats); - fread(param_data.data(), sizeof(float), num_floats, fp_in); - - // 2. 确定维度信息 (借鉴旧代码逻辑) - // 'vl' 标志和 'visual' 层名的判断 - bool is_visual = find_in_layers(name, {"visual"}); - int H = is_visual ? vit_tmp_hidden_dim : tmp_hidden_dim; - if (H <= 0) { - std::cout << "FAIL! Hidden dimension not found for " << name << std::endl; +#else + std::cerr << "KLEIDIAI_Q4_0 is only supported on ARM architecture." << std::endl; __exit(-1); +#endif + } else if (final_quant_type == MLLM_TYPE_Q4_0_4_4) { + bool is_visual = find_in_layers(name, {"visual"}); + int H = is_visual ? vit_tmp_hidden_dim : tmp_hidden_dim; + if (H <= 0) { + std::cout << "FAIL! Hidden dimension not found for " << name << std::endl; + __exit(-1); + } + int K = H; + if ((is_visual && find_in_layers(name, {"fc2", "down_proj"})) || (!is_visual && find_in_layers(name, {"w2", "down_proj"}))) { + if (num_floats % H != 0) { + std::cerr << "FAIL! num_floats not divisible by H for " << name << std::endl; + __exit(-1); + } + K = num_floats / H; + } + auto block_t = alloc_quant_block(num_floats, final_quant_type); + quant_ptr = block_t.first; + quant_size = block_t.second; + quantize_row_q4_0_4x4(full_param_data.data(), quant_ptr, num_floats, K); + } else { + auto block_t = alloc_quant_block(num_floats, final_quant_type); + quant_ptr = block_t.first; + quant_size = block_t.second; + switch (final_quant_type) { + case MLLM_TYPE_F32: break; + case MLLM_TYPE_Q4_0: quantize_row_q4_0(full_param_data.data(), quant_ptr, num_floats); break; + case MLLM_TYPE_Q8_0: quantize_row_q8_0(full_param_data.data(), quant_ptr, num_floats); break; + case MLLM_TYPE_Q2_K: quantize_row_q2_K(full_param_data.data(), quant_ptr, num_floats); break; + case MLLM_TYPE_Q3_K: quantize_row_q3_K(full_param_data.data(), quant_ptr, num_floats); break; + case MLLM_TYPE_Q4_K: quantize_row_q4_K(full_param_data.data(), quant_ptr, num_floats); break; + case MLLM_TYPE_Q6_K: quantize_row_q6_K(full_param_data.data(), quant_ptr, num_floats); break; + case MLLM_TYPE_Q8_K: quantize_row_q8_K(full_param_data.data(), quant_ptr, num_floats); break; + default: + std::cerr << "Unsupported quantization type for full-tensor processing: " << DataTypeName(final_quant_type) << std::endl; + delete[] (char *)quant_ptr; + __exit(-1); + } } - // 根据层名决定 K 的值 - int K = H; - if ((is_visual && find_in_layers(name, {"fc2", "down_proj"})) || (!is_visual && find_in_layers(name, {"w2", "down_proj"}))) { - K = num_floats / H; + if (final_quant_type == MLLM_TYPE_F32) { + writeChunk(full_param_data.data(), num_floats * sizeof(float)); + if (quant_ptr) delete[] (char *)quant_ptr; + } else { + writeChunk(quant_ptr, quant_size); + delete[] (char *)quant_ptr; } - - // 3. 分配量化空间并执行量化 - auto block_t = alloc_quant_block(num_floats, final_quant_type); - void *quant_ptr = block_t.first; - - // 调用与旧版本中类似的函数 - quantize_row_q4_0_4x4(param_data.data(), quant_ptr, num_floats, K); - - // 4. 写入量化数据块 - writeChunk(quant_ptr, block_t.second); - delete[] (char *)quant_ptr; } else { uint64_t floats_processed = 0; while (floats_processed < num_floats) { uint64_t floats_to_read = std::min((uint64_t)CHUNK_SIZE_FLOATS, num_floats - floats_processed); if (floats_to_read == 0) break; - fread(read_buffer.data(), sizeof(float), floats_to_read, fp_in); - auto block_t = alloc_quant_block(floats_to_read, final_quant_type); void *quant_ptr = block_t.first; - switch (final_quant_type) { + case MLLM_TYPE_F32: + writeChunk(read_buffer.data(), floats_to_read * sizeof(float)); + delete[] (char *)quant_ptr; + quant_ptr = nullptr; + break; case MLLM_TYPE_Q4_0: quantize_row_q4_0(read_buffer.data(), quant_ptr, floats_to_read); break; case MLLM_TYPE_Q8_0: quantize_row_q8_0(read_buffer.data(), quant_ptr, floats_to_read); break; case MLLM_TYPE_Q2_K: quantize_row_q2_K(read_buffer.data(), quant_ptr, floats_to_read); break; - case MLLM_TYPE_Q2_0: quantize_row_q2_0(read_buffer.data(), quant_ptr, floats_to_read); break; case MLLM_TYPE_Q3_K: quantize_row_q3_K(read_buffer.data(), quant_ptr, floats_to_read); break; case MLLM_TYPE_Q4_K: quantize_row_q4_K(read_buffer.data(), quant_ptr, floats_to_read); break; case MLLM_TYPE_Q6_K: quantize_row_q6_K(read_buffer.data(), quant_ptr, floats_to_read); break; case MLLM_TYPE_Q8_K: quantize_row_q8_K(read_buffer.data(), quant_ptr, floats_to_read); break; default: std::cerr << "Unsupported quantization type in streaming loop: " << DataTypeName(final_quant_type) << std::endl; - delete[] (char *)quant_ptr; // 避免内存泄漏 + delete[] (char *)quant_ptr; __exit(-1); } - - writeChunk(quant_ptr, block_t.second); - delete[] (char *)quant_ptr; - + if (quant_ptr) { + writeChunk(quant_ptr, block_t.second); + delete[] (char *)quant_ptr; + } floats_processed += floats_to_read; } } - endWriteParam(); std::cout << "Done." << std::endl; } - writeIndex(); } } // namespace mllm \ No newline at end of file diff --git a/tools/quantizer/QuantWriter.hpp b/tools/quantizer/QuantWriter.hpp index 86ab5037e..3ed0ad77e 100644 --- a/tools/quantizer/QuantWriter.hpp +++ b/tools/quantizer/QuantWriter.hpp @@ -72,6 +72,7 @@ class QuantWriter : public ParamWriter { std::string output_path_; ParamLoader *param_loader_; std::vector param_names_; + std::vector original_param_names_; DataType getQuantizationTypeFor(const std::string &name, DataType target_type, const std::string &other_flag); From aa5b8ca6efdd3c84a6e0557cbb164f3df3084b39 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Sun, 27 Jul 2025 18:57:16 +0800 Subject: [PATCH 15/22] feat: add opencl qwen2.5-1.5b-q4_0 --- .gitignore | 2 + CMakeLists.txt | 29 +- examples/CMakeLists.txt | 27 +- examples/demo_bailing_moe.cpp | 25 +- examples/demo_bailing_moe_mbp.cpp | 29 +- examples/demo_qwen.cpp | 30 +- include/OpDefined.hpp | 4 + include/Types.hpp | 7 +- scripts/run_ling.sh | 1 + src/Backend.hpp | 11 + src/Generate.hpp | 109 +- src/Layer.hpp | 141 +- src/Module.cpp | 4 + src/Module.hpp | 167 +- src/Op.hpp | 8 +- src/ParamLoader.cpp | 14 +- src/Tensor.cpp | 96 +- src/Tensor.hpp | 153 +- src/TensorImpl.hpp | 12 +- src/backends/cpu/CPUBackend.cpp | 25 +- src/backends/cpu/compute/GemmFp.hpp | 283 ++ src/backends/cpu/compute/GemmKleidiai.cpp | 119 +- src/backends/cpu/compute/GemmKleidiai.hpp | 4 + src/backends/cpu/compute/Matmul.cpp | 67 - src/backends/cpu/compute/Sigmoid.hpp | 69 + src/backends/cpu/compute/Transpose2D.hpp | 24 +- src/backends/cpu/compute/Transpose3D.hpp | 154 +- src/backends/cpu/op/CPUArgSortFunc.hpp | 7 +- src/backends/cpu/op/CPUBinaryFunc.hpp | 53 +- src/backends/cpu/op/CPUExpandFunc.hpp | 23 +- src/backends/cpu/op/CPUGather.cpp | 45 +- src/backends/cpu/op/CPUGather.hpp | 2 +- src/backends/cpu/op/CPUKVCache.cpp | 36 +- src/backends/cpu/op/CPUMaskedFill.hpp | 70 + src/backends/cpu/op/CPUMatmulFunc.hpp | 74 +- src/backends/cpu/op/CPUParameter.cpp | 2 - src/backends/cpu/op/CPUScatter.hpp | 85 + src/backends/cpu/op/CPUScatterAddFunc.hpp | 40 +- src/backends/cpu/op/CPUSigmoid.cpp | 46 + src/backends/cpu/op/CPUSigmoid.hpp | 28 + src/backends/cpu/op/CPUTilde.hpp | 65 + src/backends/cpu/op/CPUTopkFunc.hpp | 23 + src/backends/cpu/op/CPUTransposeFunc.hpp | 85 +- src/backends/cpu/op/CPUViewFunc.hpp | 20 +- src/backends/opencl/CMakeLists.txt | 41 +- src/backends/opencl/OpenCLBackend.cpp | 1114 ++++- src/backends/opencl/OpenCLBackend.hpp | 100 +- src/backends/opencl/OpenCLMemoryManager.cpp | 51 +- src/backends/opencl/OpenCLMemoryManager.hpp | 14 +- src/backends/opencl/kernel/add.cl | 96 +- src/backends/opencl/kernel/argsort.cl | 256 + src/backends/opencl/kernel/bincount.cl | 107 + src/backends/opencl/kernel/cliptensor.cl | 102 + src/backends/opencl/kernel/convert_fp.cl | 141 +- src/backends/opencl/kernel/div.cl | 362 ++ src/backends/opencl/kernel/div_int.cl | 181 + src/backends/opencl/kernel/embedding.cl | 125 + src/backends/opencl/kernel/flash_attention.cl | 884 ++++ src/backends/opencl/kernel/kvcache.cl | 129 + src/backends/opencl/kernel/like.cl | 21 + src/backends/opencl/kernel/matmul.cl | 334 ++ src/backends/opencl/kernel/matmul_transb.cl | 436 ++ .../opencl/kernel/matmul_transb_bias.cl | 1972 ++++++++ src/backends/opencl/kernel/mul.cl | 135 + src/backends/opencl/kernel/rmsnorm.cl | 162 + src/backends/opencl/kernel/rope.cl | 136 + src/backends/opencl/kernel/scatter_add.cl | 211 + src/backends/opencl/kernel/silu.cl | 71 + src/backends/opencl/kernel/softmax.cl | 159 + src/backends/opencl/kernel/split.cl | 47 + src/backends/opencl/kernel/sub.cl | 76 + src/backends/opencl/kernel/sum.cl | 81 + src/backends/opencl/kernel/topk.cl | 164 + src/backends/opencl/kernel/transpose.cl | 271 + src/backends/opencl/op/OpenCLAddFuncOp.cpp | 174 - src/backends/opencl/op/OpenCLAddOp.cpp | 198 + src/backends/opencl/op/OpenCLAddOp.hpp | 42 + src/backends/opencl/op/OpenCLAddTwoOp.cpp | 162 + ...OpenCLAddFuncOp.hpp => OpenCLAddTwoOp.hpp} | 17 +- src/backends/opencl/op/OpenCLArgSortOp.cpp | 133 + src/backends/opencl/op/OpenCLArgSortOp.hpp | 41 + src/backends/opencl/op/OpenCLBinCountOp.cpp | 129 + src/backends/opencl/op/OpenCLBinCountOp.hpp | 35 + src/backends/opencl/op/OpenCLClipOp.cpp | 184 + src/backends/opencl/op/OpenCLClipOp.hpp | 55 + src/backends/opencl/op/OpenCLClipTensorOp.cpp | 128 + src/backends/opencl/op/OpenCLClipTensorOp.hpp | 37 + src/backends/opencl/op/OpenCLDivIntOp.cpp | 127 + src/backends/opencl/op/OpenCLDivIntOp.hpp | 41 + src/backends/opencl/op/OpenCLDivOp.cpp | 116 + src/backends/opencl/op/OpenCLDivOp.hpp | 40 + src/backends/opencl/op/OpenCLDivTwoOp.cpp | 131 + src/backends/opencl/op/OpenCLDivTwoOp.hpp | 38 + src/backends/opencl/op/OpenCLEmbeddingOp.cpp | 119 + src/backends/opencl/op/OpenCLEmbeddingOp.hpp | 43 + .../opencl/op/OpenCLFlashAttentionOp.cpp | 279 ++ .../opencl/op/OpenCLFlashAttentionOp.hpp | 43 + src/backends/opencl/op/OpenCLKVCacheOp.cpp | 170 + src/backends/opencl/op/OpenCLKVCacheOp.hpp | 60 + src/backends/opencl/op/OpenCLLikeOp.cpp | 60 + src/backends/opencl/op/OpenCLLikeOp.hpp | 35 + src/backends/opencl/op/OpenCLLinearOp.cpp | 302 ++ src/backends/opencl/op/OpenCLLinearOp.hpp | 56 + src/backends/opencl/op/OpenCLMatmulOp.cpp | 202 + src/backends/opencl/op/OpenCLMatmulOp.hpp | 41 + src/backends/opencl/op/OpenCLMulOp.cpp | 108 + src/backends/opencl/op/OpenCLMulOp.hpp | 40 + src/backends/opencl/op/OpenCLMulTwoOp.cpp | 111 + src/backends/opencl/op/OpenCLMulTwoOp.hpp | 37 + src/backends/opencl/op/OpenCLRMSNormOp.cpp | 117 + src/backends/opencl/op/OpenCLRMSNormOp.hpp | 43 + src/backends/opencl/op/OpenCLRoPEOp.cpp | 357 ++ src/backends/opencl/op/OpenCLRoPEOp.hpp | 80 + src/backends/opencl/op/OpenCLScatterAddOp.cpp | 96 + src/backends/opencl/op/OpenCLScatterAddOp.hpp | 37 + src/backends/opencl/op/OpenCLSiLUOp.cpp | 91 + src/backends/opencl/op/OpenCLSiLUOp.hpp | 37 + src/backends/opencl/op/OpenCLSoftMaxOp.cpp | 113 + src/backends/opencl/op/OpenCLSoftMaxOp.hpp | 40 + src/backends/opencl/op/OpenCLSplitOp.cpp | 126 + src/backends/opencl/op/OpenCLSplitOp.hpp | 46 + src/backends/opencl/op/OpenCLSubOp.cpp | 128 + src/backends/opencl/op/OpenCLSubOp.hpp | 42 + src/backends/opencl/op/OpenCLSubTwoOp.cpp | 124 + src/backends/opencl/op/OpenCLSubTwoOp.hpp | 40 + src/backends/opencl/op/OpenCLSumOp.cpp | 118 + src/backends/opencl/op/OpenCLSumOp.hpp | 35 + src/backends/opencl/op/OpenCLTopkOp.cpp | 92 + src/backends/opencl/op/OpenCLTopkOp.hpp | 38 + src/backends/opencl/op/OpenCLTransposeOp.cpp | 176 + src/backends/opencl/op/OpenCLTransposeOp.hpp | 49 + src/backends/opencl/op/OpenCLViewOp.cpp | 105 + src/backends/opencl/op/OpenCLViewOp.hpp | 37 + .../opencl/third_party/OpenCL-Headers/CL/cl.h | 1920 +++++++ .../third_party/OpenCL-Headers/CL/cl_d3d10.h | 268 + .../third_party/OpenCL-Headers/CL/cl_d3d11.h | 270 + .../OpenCL-Headers/CL/cl_dx9_media_sharing.h | 386 ++ .../CL/cl_dx9_media_sharing_intel.h | 18 + .../third_party/OpenCL-Headers/CL/cl_egl.h | 185 + .../third_party/OpenCL-Headers/CL/cl_ext.h | 4435 +++++++++++++++++ .../OpenCL-Headers/CL/cl_ext_intel.h | 19 + .../OpenCL-Headers/CL/cl_function_types.h | 1184 +++++ .../third_party/OpenCL-Headers/CL/cl_gl.h | 421 ++ .../third_party/OpenCL-Headers/CL/cl_gl_ext.h | 18 + .../third_party/OpenCL-Headers/CL/cl_half.h | 440 ++ .../third_party/OpenCL-Headers/CL/cl_icd.h | 342 ++ .../third_party/OpenCL-Headers/CL/cl_layer.h | 125 + .../OpenCL-Headers/CL/cl_platform.h | 1407 ++++++ .../CL/cl_va_api_media_sharing_intel.h | 220 + .../OpenCL-Headers/CL/cl_version.h | 81 + .../third_party/OpenCL-Headers/CL/opencl.h | 32 + src/backends/opencl/utils/OpenCLTools.hpp | 140 +- src/models/ling/configuration_bailing_moe.hpp | 30 +- ...g_moe.hpp => modeling_bailing_moe_mbp.hpp} | 14 +- ...ip.hpp => modeling_bailing_moe_mbppip.hpp} | 13 +- src/models/ling/modeling_bailing_moe.hpp | 33 +- src/models/minicpm/modeling_minicpm.hpp | 6 +- .../mbm/modeling_minicpm_moe_mbm.hpp | 2 +- .../mbp/modeling_minicpm_moe_mbp.hpp | 3 +- .../minicpm_moe/modeling_minicpm_moe.hpp | 3 +- src/models/qwen/modeling_qwen.hpp | 12 +- .../transformer/configuration_transformer.hpp | 1 + .../transformer/modeling_transformer.hpp | 38 +- tools/quantizer/QuantWriter.cpp | 7 +- 164 files changed, 27043 insertions(+), 1028 deletions(-) create mode 100644 src/backends/cpu/compute/GemmFp.hpp create mode 100644 src/backends/cpu/compute/Sigmoid.hpp create mode 100644 src/backends/cpu/op/CPUMaskedFill.hpp create mode 100644 src/backends/cpu/op/CPUScatter.hpp create mode 100644 src/backends/cpu/op/CPUSigmoid.cpp create mode 100644 src/backends/cpu/op/CPUSigmoid.hpp create mode 100644 src/backends/cpu/op/CPUTilde.hpp create mode 100644 src/backends/opencl/kernel/argsort.cl create mode 100644 src/backends/opencl/kernel/bincount.cl create mode 100644 src/backends/opencl/kernel/cliptensor.cl create mode 100644 src/backends/opencl/kernel/div.cl create mode 100644 src/backends/opencl/kernel/div_int.cl create mode 100644 src/backends/opencl/kernel/embedding.cl create mode 100644 src/backends/opencl/kernel/flash_attention.cl create mode 100644 src/backends/opencl/kernel/kvcache.cl create mode 100644 src/backends/opencl/kernel/like.cl create mode 100644 src/backends/opencl/kernel/matmul.cl create mode 100644 src/backends/opencl/kernel/matmul_transb.cl create mode 100644 src/backends/opencl/kernel/matmul_transb_bias.cl create mode 100644 src/backends/opencl/kernel/mul.cl create mode 100644 src/backends/opencl/kernel/rmsnorm.cl create mode 100644 src/backends/opencl/kernel/rope.cl create mode 100644 src/backends/opencl/kernel/scatter_add.cl create mode 100644 src/backends/opencl/kernel/silu.cl create mode 100644 src/backends/opencl/kernel/softmax.cl create mode 100644 src/backends/opencl/kernel/split.cl create mode 100644 src/backends/opencl/kernel/sub.cl create mode 100644 src/backends/opencl/kernel/sum.cl create mode 100644 src/backends/opencl/kernel/topk.cl create mode 100644 src/backends/opencl/kernel/transpose.cl delete mode 100644 src/backends/opencl/op/OpenCLAddFuncOp.cpp create mode 100644 src/backends/opencl/op/OpenCLAddOp.cpp create mode 100644 src/backends/opencl/op/OpenCLAddOp.hpp create mode 100644 src/backends/opencl/op/OpenCLAddTwoOp.cpp rename src/backends/opencl/op/{OpenCLAddFuncOp.hpp => OpenCLAddTwoOp.hpp} (70%) create mode 100644 src/backends/opencl/op/OpenCLArgSortOp.cpp create mode 100644 src/backends/opencl/op/OpenCLArgSortOp.hpp create mode 100644 src/backends/opencl/op/OpenCLBinCountOp.cpp create mode 100644 src/backends/opencl/op/OpenCLBinCountOp.hpp create mode 100644 src/backends/opencl/op/OpenCLClipOp.cpp create mode 100644 src/backends/opencl/op/OpenCLClipOp.hpp create mode 100644 src/backends/opencl/op/OpenCLClipTensorOp.cpp create mode 100644 src/backends/opencl/op/OpenCLClipTensorOp.hpp create mode 100644 src/backends/opencl/op/OpenCLDivIntOp.cpp create mode 100644 src/backends/opencl/op/OpenCLDivIntOp.hpp create mode 100644 src/backends/opencl/op/OpenCLDivOp.cpp create mode 100644 src/backends/opencl/op/OpenCLDivOp.hpp create mode 100644 src/backends/opencl/op/OpenCLDivTwoOp.cpp create mode 100644 src/backends/opencl/op/OpenCLDivTwoOp.hpp create mode 100644 src/backends/opencl/op/OpenCLEmbeddingOp.cpp create mode 100644 src/backends/opencl/op/OpenCLEmbeddingOp.hpp create mode 100644 src/backends/opencl/op/OpenCLFlashAttentionOp.cpp create mode 100644 src/backends/opencl/op/OpenCLFlashAttentionOp.hpp create mode 100644 src/backends/opencl/op/OpenCLKVCacheOp.cpp create mode 100644 src/backends/opencl/op/OpenCLKVCacheOp.hpp create mode 100644 src/backends/opencl/op/OpenCLLikeOp.cpp create mode 100644 src/backends/opencl/op/OpenCLLikeOp.hpp create mode 100644 src/backends/opencl/op/OpenCLLinearOp.cpp create mode 100644 src/backends/opencl/op/OpenCLLinearOp.hpp create mode 100644 src/backends/opencl/op/OpenCLMatmulOp.cpp create mode 100644 src/backends/opencl/op/OpenCLMatmulOp.hpp create mode 100644 src/backends/opencl/op/OpenCLMulOp.cpp create mode 100644 src/backends/opencl/op/OpenCLMulOp.hpp create mode 100644 src/backends/opencl/op/OpenCLMulTwoOp.cpp create mode 100644 src/backends/opencl/op/OpenCLMulTwoOp.hpp create mode 100644 src/backends/opencl/op/OpenCLRMSNormOp.cpp create mode 100644 src/backends/opencl/op/OpenCLRMSNormOp.hpp create mode 100644 src/backends/opencl/op/OpenCLRoPEOp.cpp create mode 100644 src/backends/opencl/op/OpenCLRoPEOp.hpp create mode 100644 src/backends/opencl/op/OpenCLScatterAddOp.cpp create mode 100644 src/backends/opencl/op/OpenCLScatterAddOp.hpp create mode 100644 src/backends/opencl/op/OpenCLSiLUOp.cpp create mode 100644 src/backends/opencl/op/OpenCLSiLUOp.hpp create mode 100644 src/backends/opencl/op/OpenCLSoftMaxOp.cpp create mode 100644 src/backends/opencl/op/OpenCLSoftMaxOp.hpp create mode 100644 src/backends/opencl/op/OpenCLSplitOp.cpp create mode 100644 src/backends/opencl/op/OpenCLSplitOp.hpp create mode 100644 src/backends/opencl/op/OpenCLSubOp.cpp create mode 100644 src/backends/opencl/op/OpenCLSubOp.hpp create mode 100644 src/backends/opencl/op/OpenCLSubTwoOp.cpp create mode 100644 src/backends/opencl/op/OpenCLSubTwoOp.hpp create mode 100644 src/backends/opencl/op/OpenCLSumOp.cpp create mode 100644 src/backends/opencl/op/OpenCLSumOp.hpp create mode 100644 src/backends/opencl/op/OpenCLTopkOp.cpp create mode 100644 src/backends/opencl/op/OpenCLTopkOp.hpp create mode 100644 src/backends/opencl/op/OpenCLTransposeOp.cpp create mode 100644 src/backends/opencl/op/OpenCLTransposeOp.hpp create mode 100644 src/backends/opencl/op/OpenCLViewOp.cpp create mode 100644 src/backends/opencl/op/OpenCLViewOp.hpp create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_d3d10.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_d3d11.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_dx9_media_sharing.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_dx9_media_sharing_intel.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_egl.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_ext.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_ext_intel.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_function_types.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_gl.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_gl_ext.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_half.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_icd.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_layer.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_platform.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_va_api_media_sharing_intel.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/cl_version.h create mode 100644 src/backends/opencl/third_party/OpenCL-Headers/CL/opencl.h rename src/models/ling/mbp/{modeling_bailing_moe.hpp => modeling_bailing_moe_mbp.hpp} (97%) rename src/models/ling/mbp/{modeling_bailing_moe_mbmpip.hpp => modeling_bailing_moe_mbppip.hpp} (97%) diff --git a/.gitignore b/.gitignore index ddf80d2f0..e71fb0951 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ src/backends/qnn/sdk/* .DS_Store examples/test.cpp +examples/demo_bailing_moe2* +src/models/ling2 diff --git a/CMakeLists.txt b/CMakeLists.txt index af1ec0c68..e449c9fd3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,7 +54,7 @@ add_compile_options(-Wno-gnu-string-literal-operator-template) if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64") message(STATUS "ARM detected") set(ARM ON) - set(ANDROID_PLATFORM android-28) + # set(ANDROID_PLATFORM android-28) endif () if (ARM) @@ -120,16 +120,27 @@ endif () option(OPENCL "Enable OpenCL Backend" ON) if(OPENCL) - find_package(OpenCL) - if(NOT OpenCL_FOUND) - message(STATUS "OpenCl backend not found。") - set(OPENCL OFF CACHE BOOL "Enable OpenCL Backend" FORCE) + if(ANDROID) + # 对于现代 NDK (r23+),我们不再需要 find_library 或 find_package。 + # NDK 工具链会在链接时自动找到像 OpenCL 这样的系统库。 + # 我们只需确保启用了相关宏定义,并在链接目标时指明即可。 + message(STATUS "OpenCL backend for Android enabled. Linking will be handled by the NDK toolchain.") + add_definitions(-DUSE_OPENCL) + add_definitions(-DMLLM_TARGET_ANDROID) + include_directories(${CMAKE_SOURCE_DIR}/src/backends/opencl/third_party/OpenCL-Headers) + + else() + # 对于非 Android 平台,保持原有的查找逻辑 + find_package(OpenCL) + if(NOT OpenCL_FOUND) + message(STATUS "OpenCl backend not found.") + set(OPENCL OFF CACHE BOOL "Enable OpenCL Backend" FORCE) + else() + message(STATUS "OpenCL backend enabled.") + add_definitions(-DUSE_OPENCL) + endif() endif() endif() -if(OPENCL) - message(STATUS "OpenCL backend enabled.") - add_definitions(-DUSE_OPENCL) -endif() diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 23a4b9ec4..45714a205 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -27,6 +27,28 @@ macro(func_set_compile_opts_defs target) endif() endmacro() +# macro(func_link_libs target) +# target_link_libraries(${target} PUBLIC mllm_cpu fmt) +# if (MLLM_OPENMP) +# if (ARM AND NOT (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING)) +# # 非Mac的ARM,静态链接OpenMP +# target_link_libraries(${target} PUBLIC -fopenmp -static-openmp) +# else() +# # 其它平台(含Mac),动态链接OpenMP +# target_link_libraries(${target} PUBLIC -fopenmp) +# endif() +# endif() +# if(OPENCL) +# target_link_libraries(${target} PRIVATE mllm_opencl ${CMAKE_DL_LIBS}) +# endif() +# if (QNN) +# target_link_libraries(${target} PUBLIC mllm_qnn ${CMAKE_DL_LIBS}) +# endif() +# if (MLLM_BUILD_XNNPACK_BACKEND) +# target_link_libraries(${target} PRIVATE mllm_xnnpack) +# endif() +# endmacro() + macro(func_link_libs target) target_link_libraries(${target} PUBLIC mllm_cpu fmt) if (MLLM_OPENMP) @@ -39,7 +61,8 @@ macro(func_link_libs target) endif() endif() if(OPENCL) - target_link_libraries(${target} PRIVATE mllm_opencl ${CMAKE_DL_LIBS}) + # 【关键修正】将 PRIVATE 修改为 PUBLIC,确保 OpenCL 的系统库依赖能最终链接到可执行文件上。 + target_link_libraries(${target} PUBLIC mllm_opencl ${CMAKE_DL_LIBS}) endif() if (QNN) target_link_libraries(${target} PUBLIC mllm_qnn ${CMAKE_DL_LIBS}) @@ -106,7 +129,9 @@ func_llm_add_executable(demo_minicpm_moe_mbm) func_llm_add_executable(demo_qwen_sd) func_llm_add_executable(demo_minicpm_moe_mbp) func_llm_add_executable(demo_bailing_moe) +func_llm_add_executable(demo_bailing_moe2) func_llm_add_executable(demo_bailing_moe_mbp) +func_llm_add_executable(demo_bailing_moe2_mbp) func_llm_add_executable(test) func_llm_add_executable(demo_qwen_batch) diff --git a/examples/demo_bailing_moe.cpp b/examples/demo_bailing_moe.cpp index 9fd1bee02..d30d4f69e 100644 --- a/examples/demo_bailing_moe.cpp +++ b/examples/demo_bailing_moe.cpp @@ -5,6 +5,7 @@ * @date 2025-07-01 * */ +#include "Types.hpp" #include "cmdline.h" #include "models/ling/configuration_bailing_moe.hpp" #include "models/ling/modeling_bailing_moe.hpp" @@ -16,27 +17,41 @@ int main(int argc, char **argv) { std::iostream::sync_with_stdio(false); cmdline::parser cmdParser; + cmdParser.add("device", 'd', "mllm backend [0:`cpu` | 1:`opencl`]", false, 0); cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/ling_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/ling_merges.txt"); -#ifdef ARM - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-kai_q4_0.mllm"); -#else - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-q4_0.mllm"); + string default_model_path = "../models/ling-lite-1.5-q4_0.mllm"; +#if defined(ARM) + default_model_path = "../models/ling-lite-1.5-kai_q4_0.mllm"; #endif + cmdParser.add("model", 'm', "specify mllm model path", false, default_model_path); cmdParser.add("limits", 'l', "max KV cache size", false, 500); cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.add("gen", 'g', "max new tokens", false, -1); cmdParser.parse_check(argc, argv); string vocab_path = cmdParser.get("vocab"); string merge_path = cmdParser.get("merge"); string model_path = cmdParser.get("model"); int tokens_limit = cmdParser.get("limits"); + int max_new_tokens = cmdParser.get("gen"); CPUBackend::cpu_threads = cmdParser.get("thread"); + BackendType device = (BackendType)cmdParser.get("device"); + assert((device == MLLM_CPU || device == MLLM_OPENCL) && "device not supports!"); auto tokenizer = BaiLingTokenizer(vocab_path, merge_path); BailingMoeConfig config(tokens_limit); +#ifdef USE_OPENCL + if (device == MLLM_OPENCL) { + config.dtype = MLLM_TYPE_F16; + config.attn_implementation = "eager"; + } +#endif // config.attn_implementation = "sage_attention"; auto model = BailingMoeForCausalLM(config); +#ifdef USE_OPENCL + model = model.to(device); +#endif model.load(model_path); vector in_strs = { @@ -58,7 +73,7 @@ int main(int argc, char **argv) { std::cout << "[A] " << std::flush; LlmTextGeneratorOpts opt{ - .max_new_tokens = static_cast(tokens_limit - input_tensor.sequence()), + .max_new_tokens = max_new_tokens > 0 ? max_new_tokens : static_cast(tokens_limit - input_tensor.sequence()), .do_sample = false, .temperature = 0.3F, .top_k = 50, diff --git a/examples/demo_bailing_moe_mbp.cpp b/examples/demo_bailing_moe_mbp.cpp index dc84e2c1f..e9088d762 100644 --- a/examples/demo_bailing_moe_mbp.cpp +++ b/examples/demo_bailing_moe_mbp.cpp @@ -8,8 +8,8 @@ #include "Module.hpp" #include "cmdline.h" #include "models/ling/configuration_bailing_moe.hpp" -// #include "models/ling/mbp/modeling_bailing_moe.hpp" -#include "models/ling/mbp/modeling_bailing_moe_mbmpip.hpp" +#include "models/ling/mbp/modeling_bailing_moe_mbp.hpp" +// #include "models/ling/mbp/modeling_bailing_moe_mbppip.hpp" #include "models/ling/tokenizer_bailing.hpp" #include @@ -20,26 +20,41 @@ int main(int argc, char **argv) { Module::alloc_mmap = false; cmdline::parser cmdParser; + cmdParser.add("device", 'd', "mllm backend [0:`cpu` | 1:`opencl`]", false, 0); cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/ling_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/ling_merges.txt"); -#ifdef ARM - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-kai_q4_0_e2.mllm"); -#else - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/ling-lite-1.5-q4_0.mllm"); + string default_model_path = "../models/ling-lite-1.5-q4_0.mllm"; +#if defined(ARM) + default_model_path = "../models/ling-lite-1.5-kai_q4_0.mllm"; #endif + cmdParser.add("model", 'm', "specify mllm model path", false, default_model_path); cmdParser.add("limits", 'l', "max KV cache size", false, 500); cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.add("gen", 'g', "max new tokens", false, -1); cmdParser.parse_check(argc, argv); string vocab_path = cmdParser.get("vocab"); string merge_path = cmdParser.get("merge"); string model_path = cmdParser.get("model"); int tokens_limit = cmdParser.get("limits"); + int max_new_tokens = cmdParser.get("gen"); CPUBackend::cpu_threads = cmdParser.get("thread"); + BackendType device = (BackendType)cmdParser.get("device"); + assert((device == MLLM_CPU || device == MLLM_OPENCL) && "device not supports!"); auto tokenizer = BaiLingTokenizer(vocab_path, merge_path); BailingMoeConfig config(tokens_limit); +#ifdef USE_OPENCL + if (device == MLLM_OPENCL) { + config.dtype = MLLM_TYPE_F16; + config.attn_implementation = "eager"; + } +#endif + // config.attn_implementation = "sage_attention"; auto model = BailingMoeForCausalLM(config); +#ifdef USE_OPENCL + model = model.to(device); +#endif model.load(model_path); vector in_strs = { @@ -61,7 +76,7 @@ int main(int argc, char **argv) { std::cout << "[A] " << std::flush; LlmTextGeneratorOpts opt{ - .max_new_tokens = static_cast(tokens_limit - input_tensor.sequence()), + .max_new_tokens = max_new_tokens > 0 ? max_new_tokens : static_cast(tokens_limit - input_tensor.sequence()), .do_sample = false, .temperature = 0.3F, .top_k = 50, diff --git a/examples/demo_qwen.cpp b/examples/demo_qwen.cpp index 2f82d246a..282705bdd 100644 --- a/examples/demo_qwen.cpp +++ b/examples/demo_qwen.cpp @@ -7,6 +7,7 @@ * @copyright Copyright (c) 2024 * */ +#include "DataType.hpp" #include "cmdline.h" #include "models/qwen/configuration_qwen.hpp" #include "models/qwen/modeling_qwen.hpp" @@ -18,14 +19,17 @@ int main(int argc, char **argv) { std::iostream::sync_with_stdio(false); cmdline::parser cmdParser; + cmdParser.add("device", 'd', "mllm backend [0:`cpu` | 1:`opencl`]", false, 0); cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2.5_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2.5_merges.txt"); -#ifdef ARM - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-kai_q4_0_lm.mllm"); -#else - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"); + string default_model_path = "../models/qwen-2.5-1.5b-instruct-q4_0_4_4.mllm"; + string default_model_billion = "1.5b"; +#if defined(ARM) + default_model_path = "../models/qwen-2.5-1.5b-instruct-kai_q4_0_lm.mllm"; + default_model_billion = "1.5b-lm"; #endif - cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B | 3B |]", false, "1.5b-lm"); + cmdParser.add("model", 'm', "specify mllm model path", false, default_model_path); + cmdParser.add("billion", 'b', "[0.5B | 1.8B | 1.5B | 3B |]", false, default_model_billion); cmdParser.add("limits", 'l', "max KV cache size", false, 550); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); @@ -36,16 +40,28 @@ int main(int argc, char **argv) { string model_billion = cmdParser.get("billion"); int tokens_limit = cmdParser.get("limits"); CPUBackend::cpu_threads = cmdParser.get("thread"); + BackendType device = (BackendType)cmdParser.get("device"); + assert((device == MLLM_CPU || device == MLLM_OPENCL) && "device not supports!"); auto tokenizer = QWenTokenizer(vocab_path, merge_path); - QWenConfig config(tokens_limit, model_billion, RoPEType::HFHUBROPE); - // config.attn_implementation = "sage_attention"; // 使用Sage Attention实现 + QWenConfig config(tokens_limit, model_billion); +#ifdef USE_OPENCL + if (device == MLLM_OPENCL) { + config.dtype = MLLM_TYPE_F16; + // config.attn_implementation = "eager"; + } +#endif + // config.attn_implementation = "sage_attention"; auto model = QWenForCausalLM(config); +#ifdef USE_OPENCL + model = model.to(device); +#endif model.load(model_path); vector in_strs = { "Give me a short introduction to large language model.", "介绍一下你自己。", + "清晨的阳光透过薄纱窗帘,懒洋洋地洒在木地板上,空气中飘散着咖啡豆研磨后特有的醇厚香气。窗外传来几声清脆的鸟鸣,伴随着远处隐约的车流声,构成这座都市尚未完全苏醒的独特交响。书桌上摊开着昨夜未读完的书,书页边缘已微微卷起。厨房里,水壶正发出细密的声响,预示着一天的热饮即将就绪。昨日的计划表贴在冰箱门上,几个重要的待办事项用红笔醒目地圈出。公园里晨练的人们身影绰绰,有节奏的脚步声和太极音乐交织。一只橘猫敏捷地跃上围墙,在晨光中伸展着腰肢,神态悠闲得仿佛它是这片领地的主人。街角的面包店刚拉开铁门,新鲜出炉的面包香气迫不及待地涌向街头。公交站台上,等待的乘客低头刷着手机屏幕,神情各异。云朵缓慢地在湛蓝的天空中移动,时间似乎被拉长了片刻。生活就在这些微小的、平凡的细节里徐徐展开,既不惊天动地,却也充满细碎的温暖和实在的步履。新的一天开始了。\n​​请在以上文本中找出描述“气味”的句子(复制出来),然后判断叙述者对“橘猫”的态度是正面还是负面,最后请用三个成语概括文中描绘的早晨氛围。", "项羽已杀卿子冠军,威震楚国,名闻诸侯。乃遣当阳君、蒲将军将卒二万渡河,救巨鹿。战少利,陈馀复请兵。项羽乃悉引兵渡河,皆沉船,破釜甑,烧庐舍,持三日粮,以示士卒必死,无一还心。于是至则围王离,与秦军遇,九战,绝其甬道,大破之,杀苏角,虏王离。涉间不降楚,自烧杀。当是时,楚兵冠诸侯。诸侯军救巨鹿下者十余壁,莫敢纵兵。及楚击秦,诸将皆从壁上观。楚战士无不一以当十,楚兵呼声动天,诸侯军无不人人惴恐。于是已破秦军,项羽召见诸侯将,入辕门,无不膝行而前,莫敢仰视。项羽由是始为诸侯上将军,诸侯皆属焉。 问题:结合项羽在巨鹿之战中的战术决策与心理威慑手段,分析其如何实现『楚战士无不一以当十』的战斗效应,并论述这种军事心理学实践对诸侯将领『膝行而前,莫敢仰视』行为模式的生成机制。", }; for (int i = 0; i < in_strs.size(); ++i) { diff --git a/include/OpDefined.hpp b/include/OpDefined.hpp index 85d235938..e1470dc60 100644 --- a/include/OpDefined.hpp +++ b/include/OpDefined.hpp @@ -65,6 +65,10 @@ enum OpType { IROPE, OP_NUM, NTKROPE, + SCATTER, + TILDE, + MASKEDFILL, + SIGMOID, // add in xnnpack DIRECT, diff --git a/include/Types.hpp b/include/Types.hpp index c579cad38..3086c1090 100644 --- a/include/Types.hpp +++ b/include/Types.hpp @@ -23,8 +23,13 @@ typedef map OpParam; // #define DEBUGSAVETENSOR // #define DEBUGOPTIME -#define LLAMAFILE_SGEMM +// #define LLAMAFILE_SGEMM inline int KVCache_TYPE = 16; +#if !defined(ARM) +inline int KVCache_Type_eager = KVCache_TYPE; +#else +inline int KVCache_Type_eager = 32; +#endif inline int KVCacheSageDtypeBit = 8; // 8 or 16 inline int KVCache_batch = 1; typedef enum { diff --git a/scripts/run_ling.sh b/scripts/run_ling.sh index 15cc60670..ba34d7f80 100755 --- a/scripts/run_ling.sh +++ b/scripts/run_ling.sh @@ -17,5 +17,6 @@ if [ $? -ne 0 ]; then fi adb shell "cd /data/local/tmp/mllm/bin && ./demo_bailing_moe -m ../models/ling-lite-1.5-kai_q4_0.mllm" adb shell "cd /data/local/tmp/mllm/bin && ./demo_bailing_moe_mbp -m ../models/ling-lite-1.5-kai_q4_0.mllm" +# adb shell "cd /data/local/tmp/mllm/bin && ./demo_bailing_moe -d 1 -m ../models/ling-lite-1.5-q4_0.mllm" # adb shell "cd /data/local/tmp/mllm/bin && ./demo_bailing_moe -m ../models/ling-lite-1.5-kai_q4_0_e2.mllm" # adb shell "cd /data/local/tmp/mllm/bin && ./demo_bailing_moe_mbp -m ../models/ling-lite-1.5-kai_q4_0_e2.mllm" \ No newline at end of file diff --git a/src/Backend.hpp b/src/Backend.hpp index e16b141db..04c40204e 100644 --- a/src/Backend.hpp +++ b/src/Backend.hpp @@ -18,6 +18,7 @@ class Backend; class Module; class Layer; struct DeviceMemory; +class ParamLoader; // KVCache map for QNN-CPU KVCache sharing static std::unordered_map kv_cache_map; @@ -106,6 +107,16 @@ class Backend { virtual void registerOps() = 0; virtual void registerFuncs() = 0; + /** + * @brief (可选) 从文件中直接加载张量数据到设备,为后端提供优化路径。 + * @param tensor 目标张量,其设备内存应已分配。 + * @param loader 参数加载器,用于获取文件句柄和元数据。 + * @return 如果后端处理了加载则返回 true,否则返回 false,让 ParamLoader 使用默认方法。 + */ + virtual bool load_from_file(Tensor *tensor, ParamLoader *loader) { + return false; + } + BackendType type() const { return type_; } diff --git a/src/Generate.hpp b/src/Generate.hpp index 63f79b5cb..6c58eb280 100644 --- a/src/Generate.hpp +++ b/src/Generate.hpp @@ -9,6 +9,8 @@ * */ #pragma once +#include "Types.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" #ifndef MLLM_GENERATE_HPP #define MLLM_GENERATE_HPP #include @@ -79,7 +81,14 @@ class _LlmTextGenerateMethod { } } for (int i = 0; i < _dims; ++i) { - auto value = t.dataAt(0, 0, _seq, i); + float value; + if (t.dtype() == MLLM_TYPE_F16) { + value = MLLM_FP16_TO_FP32(t.dataAt(0, 0, _seq, i)); + } else if (t.dtype() == MLLM_TYPE_F32) { + value = t.dataAt(0, 0, _seq, i); + } else { + throw std::runtime_error("Unsupported dtype for text generation."); + } scores.push_back(value); } } @@ -152,39 +161,39 @@ class _LlmTextGenerateGreedySearchMethod : public _LlmTextGenerateMethod { }; class _LlmTextGenerateGreedySearchMethodForSD : public _LlmTextGenerateMethod { - public: - _LlmTextGenerateGreedySearchMethodForSD() = default; - ~_LlmTextGenerateGreedySearchMethodForSD() = default; - inline void _tensor_to_vec_of_multiIndices(Tensor &t, std::vector> &scores, std::vector indices) { - assert(t.batch() == 1 && "Batch size of result is not 1. Which is not supported for now."); - assert(t.head() == 1 && "The 3rd dim of result should be one. e.g.:[1, 1, seq, hidden]"); - int _dims = t.dimension(); - // TODO: 考虑QNN进行padding - // padding prefill for QNN - // if (is_padding) { - // if (chunk_size > 0) { - // _seq = (seq_before_padding - 1) % chunk_size; - // } else { - // _seq = seq_before_padding - 1; - // } - // } - for (int idx = 0; idx < indices.size(); ++idx) { - std::vector values(t.dimension()); - int _seq = indices[idx]; - for (int i = 0; i < _dims; ++i) { - auto value = t.dataAt(0, 0, _seq, i); - values[i] = value; - } - scores.push_back(values); +public: + _LlmTextGenerateGreedySearchMethodForSD() = default; + ~_LlmTextGenerateGreedySearchMethodForSD() = default; + inline void _tensor_to_vec_of_multiIndices(Tensor &t, std::vector> &scores, std::vector indices) { + assert(t.batch() == 1 && "Batch size of result is not 1. Which is not supported for now."); + assert(t.head() == 1 && "The 3rd dim of result should be one. e.g.:[1, 1, seq, hidden]"); + int _dims = t.dimension(); + // TODO: 考虑QNN进行padding + // padding prefill for QNN + // if (is_padding) { + // if (chunk_size > 0) { + // _seq = (seq_before_padding - 1) % chunk_size; + // } else { + // _seq = seq_before_padding - 1; + // } + // } + for (int idx = 0; idx < indices.size(); ++idx) { + std::vector values(t.dimension()); + int _seq = indices[idx]; + for (int i = 0; i < _dims; ++i) { + auto value = t.dataAt(0, 0, _seq, i); + values[i] = value; } + scores.push_back(values); } - unsigned int generate(Tensor &t) override { - std::cerr << "Should use generate_SD" << std::endl; - assert(false); - return -1; - }; - unsigned int generate_SD(Tensor &t, TracePool &tp); + } + unsigned int generate(Tensor &t) override { + std::cerr << "Should use generate_SD" << std::endl; + assert(false); + return -1; }; + unsigned int generate_SD(Tensor &t, TracePool &tp); +}; class _LlmTextGenerateTopkSamplingMethod : public _LlmTextGenerateMethod { public: @@ -216,7 +225,9 @@ class _LlmTextGenerateToppSamplingMethod : public _LlmTextGenerateMethod { class _LlmTextGenerateNucleusSamplingMethodForSD : public _LlmTextGenerateMethod { public: - _LlmTextGenerateNucleusSamplingMethodForSD(int k, float p, float temp) : samplingConfig(SamplingConfig(temp, p, k)) {} + _LlmTextGenerateNucleusSamplingMethodForSD(int k, float p, float temp) : + samplingConfig(SamplingConfig(temp, p, k)) { + } ~_LlmTextGenerateNucleusSamplingMethodForSD() = default; unsigned int generate(Tensor &t) override { @@ -226,6 +237,7 @@ class _LlmTextGenerateNucleusSamplingMethodForSD : public _LlmTextGenerateMethod }; unsigned int generate_SD(Tensor &t, TracePool &tp); std::vector evalPosterior(const std::vector> &logit_scores, const std::vector &sampled_token_ids, TracePool &tp); + private: float temperature = 1.0; float top_p = 1.0; @@ -234,17 +246,19 @@ class _LlmTextGenerateNucleusSamplingMethodForSD : public _LlmTextGenerateMethod float temperature = 1.0; float top_p = 1.0; int top_k = -1; - SamplingConfig(float _temperature, float _top_p, float _top_k): temperature(_temperature), top_p(_top_p), top_k(_top_k) {} + SamplingConfig(float _temperature, float _top_p, float _top_k) : + temperature(_temperature), top_p(_top_p), top_k(_top_k) { + } } samplingConfig; - void apply_logits_processor(std::vector>& logits_with_indices, const SamplingConfig& config) { + void apply_logits_processor(std::vector> &logits_with_indices, const SamplingConfig &config) { const size_t vocab_size = logits_with_indices.size(); if (vocab_size == 0) return; // 温度调整 if (config.temperature > 0 && config.temperature != 1.0f) { const float inv_temp = 1.0f / config.temperature; - for (auto& v : logits_with_indices) v.first *= inv_temp; + for (auto &v : logits_with_indices) v.first *= inv_temp; } // Top-k处理 @@ -253,17 +267,16 @@ class _LlmTextGenerateNucleusSamplingMethodForSD : public _LlmTextGenerateMethod std::partial_sort( logits_with_indices.begin(), logits_with_indices.begin() + config.top_k, - logits_with_indices.end() - ); + logits_with_indices.end()); // 构建屏蔽掩码 std::vector mask(vocab_size, false); - for (int i=0; i probs(vocab_size); std::pair max_logit_with_index = *std::max_element(logits_with_indices.begin(), logits_with_indices.end(), - [](std::pair a, std::pair b) { return a.first > b.first; }); + [](std::pair a, std::pair b) { return a.first > b.first; }); float max_logit = max_logit_with_index.first; float sum_exp = 0.0f; - for (size_t i=0; i> sorted_probs(vocab_size); - for (size_t i=0; i a, std::pair b) { return a.first > b.first; }); @@ -295,16 +308,16 @@ class _LlmTextGenerateNucleusSamplingMethodForSD : public _LlmTextGenerateMethod cumulative += sorted_probs[cutoff].first; if (cumulative > config.top_p) break; } - cutoff = std::min(cutoff+1, vocab_size-1); + cutoff = std::min(cutoff + 1, vocab_size - 1); // 构建有效集合 std::vector valid(vocab_size, false); - for (size_t i=0; i(m_method_class)->generate_SD(t, tp); + return dynamic_cast<_LlmTextGenerateGreedySearchMethodForSD *>(m_method_class)->generate_SD(t, tp); }; inline unsigned int generate(Tensor &t, const LlmTextGeneratorOpts &opt) { diff --git a/src/Layer.hpp b/src/Layer.hpp index 1cc5228b6..509bb59de 100644 --- a/src/Layer.hpp +++ b/src/Layer.hpp @@ -36,6 +36,7 @@ class Layer { } void init(std::string name, OpType type) { name_ = std::move(name); + type_ = type; param_["type"] = type; Module::initBackend(MLLM_CPU); backend_ = Backend::global_backends[MLLM_CPU].get(); @@ -45,53 +46,36 @@ class Layer { bool ready() { return init_; } - static map layername_2_tensorname; - static bool use_layername_2_tensorname; + /**** for forward ****/ Tensor operator()(Tensor input) { auto ts = run({input}, 1); return ts[0]; } - Tensor operator()(Tensor input0, Tensor input1) { auto ts = run({input0, input1}, 1); return ts[0]; } - Tensor operator()(Tensor input0, Tensor input1, Tensor input2) { auto ts = run({input0, input1, input2}, 1); return ts[0]; } - Tensor operator()(Tensor input0, Tensor input1, Tensor input2, Tensor input3) { auto ts = run({input0, input1, input2, input3}, 1); return ts[0]; } - void initOp() { + /**** for dynamic load ****/ + void load(std::shared_ptr loader = nullptr) { if (op_ == nullptr) { - if ((param_["type"] == KVCACHE || param_["type"] == KVCACHENPU) - && (Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end())) { - if (kv_cache_map.find(name_) == kv_cache_map.end()) { - // for the prefill part, we need to create a new op - param_["type"] = KVCACHENPU; - op_ = backend_->opCreate(param_, name_); - kv_cache_map[name_] = op_; - } else { - // for the decoding part, we need to get created op from global container - op_ = kv_cache_map[name_]; - } - } else { - op_ = backend_->opCreate(param_, name_); - } + initOp(); } - } - - void load() { - initOp(); if (inited_loaded && loaded_param) return; - op_->load(*Module::llm_model_ptr->loader); + if (!loader) { + loader = Module::llm_model_ptr->loader; + } + op_->load(*loader); loaded_param = true; inited_loaded = true; } @@ -104,38 +88,89 @@ class Layer { inited_loaded = false; } + /**** for change backend ****/ + void to(BackendType type) { + if (type == backend_->type()) { + return; + } + Module::initBackend(type); + backend_ = Backend::global_backends[type].get(); + if (!init_) { + init(name_, type_); + } + } + void cpu() { + to(MLLM_CPU); + } + void cl() { +#ifdef USE_OPENCL + to(MLLM_OPENCL); +#else + throw std::runtime_error("OpenCL backend is not available. Please compile with USE_OPENCL=ON."); +#endif + } + protected: + // 统一入口 vector run(vector inputs, int N = 1) { - initOp(); + // auto start_time = mllm_time_us(); + + // ==================== [开始] 前向计算 ====================// Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); - if (module->doLoad || !inited_loaded) { // load + /*** part.1 change backend(if) ***/ + if (module && module->doChangeBn) { + if (check_op_support(Backend::global_backends[module->device()].get())) { + to(module->device()); + } else { + std::cout << "Backend " << module->device() << " does not support the operation, falling back to CPU." << std::endl; + to(MLLM_CPU); + } + } + /*** part.2 init op(if) ***/ + if (op_ == nullptr || op_->backend()->type() != backend_->type()) { + auto created = initOp(); + assert(op_ != nullptr && "Op creation failed, please check the backend and parameters."); + } + /*** part.3 load params(if) ***/ + if (module && (module->doLoad || !inited_loaded) && !module->doChangeBn) { // load if (module->doLoad) { op_->load(*module->loader); inited_loaded = true; } else if (loaded_param) { inited_loaded = loaded_param; } else if (!inited_loaded) { - // auto empty_loader = new ParamLoader(""); ParamLoader empty_loader(""); op_->load(empty_loader); inited_loaded = true; } } - auto backend = inputs.empty() ? Backend::global_backends[MLLM_CPU].get() : inputs[0].backend(); + /*** part.4 forward ***/ + auto backend = backend_; if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { backend = Backend::global_backends[MLLM_QNN].get(); } + for (auto &input : inputs) { + if (input.backend() != backend) { + input.to(backend->type()); + } + } vector out_names; int count = (N > 1) ? N : 1; for (int i = 0; i < count; ++i) { std::string tensor_name = (N > 1) ? "out-" + op_->name() + "-" + std::to_string(i) : "out-" + op_->name(); out_names.push_back(tensor_name); } + // ==================== [结束] 前向计算 ====================// + // if (inputs[0].dimension() > 0) { + // auto time_end = mllm_time_us(); + // std::cout << name_ << " dispatch Layer in " << (time_end - start_time) / 1000.0F << " ms" << std::endl; + // } return backend->runOp(op_, inputs, out_names, false); } public: std::string name_; + OpType type_; Op *op_ = nullptr; Backend *backend_{}; OpParam param_; @@ -144,6 +179,43 @@ class Layer { bool inited_loaded = false; bool loaded_param = false; + + static map layername_2_tensorname; + static bool use_layername_2_tensorname; + +private: + bool initOp(Backend *bn = nullptr) { // 返回bn是否能成功创建op + assert(op_ == nullptr); + if (bn == nullptr) { + bn = backend_; + } + if ((param_["type"] == KVCACHE || param_["type"] == KVCACHENPU) + && (Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end())) { // 针对qnn专门处理 + if (kv_cache_map.find(name_) == kv_cache_map.end()) { + // for the prefill part, we need to create a new op + param_["type"] = KVCACHENPU; + assert(bn->type() == MLLM_CPU && "QNN backend is required for cpu's KVCACHENPU."); + op_ = bn->opCreate(param_, name_); + kv_cache_map[name_] = op_; + } else { + // for the decoding part, we need to get created op from global container + op_ = kv_cache_map[name_]; + } + op_->type() = (OpType)param_["type"]; + return true; + } + if (!(op_ = bn->opCreate(param_, name_))) { + // std::cout << "Backend" << op_->type() << " does not support the operation, falling back to CPU." << std::endl; // ttt + op_ = backend_->opCreate(param_, name_); // cpu fallback + op_->type() = (OpType)param_["type"]; + return false; + } + op_->type() = (OpType)param_["type"]; + return true; + } + bool check_op_support(Backend *bn) { + return bn->opCreate(param_, name_); + } }; class Linear final : public Layer { @@ -337,6 +409,17 @@ class Softmax final : public Layer { return ts[0]; } }; +class Sigmoid final : public Layer { +public: + Sigmoid() = default; + explicit Sigmoid(std::string name) { + init(std::move(name), OpType::SIGMOID); + } + Tensor operator()(Tensor input) { + auto ts = run({input}, 1); + return ts[0]; + } +}; class Embedding final : public Layer { public: diff --git a/src/Module.cpp b/src/Module.cpp index 501c74d2f..11cd78583 100644 --- a/src/Module.cpp +++ b/src/Module.cpp @@ -68,6 +68,7 @@ vector Module::profiling(string name) { void Module::generate( Tensor &input_ids, const LlmTextGeneratorOpts &opt, const std::function &call_back) { auto chatPostProcessing = [](unsigned token_idx, Tensor &tokens_tensor, const vector &clean_tensors) { + tokens_tensor.cpu(); tokens_tensor.reshape(1, 1, 1, 1); tokens_tensor.alloc(); tokens_tensor.setDataAt(0, 0, 0, 0, token_idx); @@ -94,6 +95,9 @@ void Module::generate( for (int step = 0; step < opt.max_new_tokens; ++step) { auto _out = (*this)({input_ids}); + if (_out[0].backend()->type() != MLLM_CPU) { + _out[0].cpu(); + } auto out_token = text_generator_->generate(_out[0]); if (!call_back(out_token)) break; chatPostProcessing(out_token, input_ids, {}); diff --git a/src/Module.hpp b/src/Module.hpp index c564297db..a40162654 100644 --- a/src/Module.hpp +++ b/src/Module.hpp @@ -13,6 +13,7 @@ #include "Trace.hpp" #include "Types.hpp" #include "backends/cpu/CPUBackend.hpp" +#include #ifdef USE_OPENCL #include "backends/opencl/OpenCLBackend.hpp" #endif @@ -59,7 +60,9 @@ class Module { map activation_tensors_num; std::shared_ptr loader; bool doLoad = false; + bool doChangeBn = false; bool doTrace = false; + bool tracedFlag = false; bool op_transposed_flag = false; static Module *llm_model_ptr; @@ -97,6 +100,45 @@ class Module { } int idx; + double forwardNoInput() { + mllm_time_init(); + vector tmps; + int max_in_size = 5; + for (int i = 0; i < max_in_size; ++i) { + Tensor t(Backend::global_backends[MLLM_CPU].get()); + t.setName("input" + std::to_string(i)); + t.reshape(1, 1, 1, 10); + t.alloc(); + t.setModule(this); + tmps.push_back(t); + } + llm_model_ptr = this; + vector alternate_args = { + {}, + vector{0, 0}, + std::vector>(32, std::vector(2))}; + uint64_t time_start = 0; + for (auto args : alternate_args) { + time_start = mllm_time_us(); + try { + operator()(tmps, args); + break; + } catch (const std::exception &e) { +#if not defined(__ARM_NEON) + if (std::string("bad any_cast") != e.what()) { + MLLM_LOG_ERROR_STREAM << e.what() << std::endl; + exit(0); + } +#endif + } catch (...) { + MLLM_LOG_ERROR_STREAM << "load error" << std::endl; + exit(0); + } + } + uint64_t time_end = mllm_time_us(); + return (time_end - time_start) / 1000.0F; // ms + } + public: Module() { idx = Module::graphIdx; @@ -104,12 +146,17 @@ class Module { } virtual ~Module() = default; - BackendType device() const { + BackendType &device() { return device_; } static void initBackend(BackendType type = BackendType::MLLM_CPU) { if (Backend::global_backends.find(type) == Backend::global_backends.end() || Backend::global_backends[type] == nullptr) { + // std::cout << "Initializing OpenswwssCL Backend..." << std::endl; + // #ifdef USE_OPENCL + // std::cout << "Initializiwwng OpenswwssCL Backend..." << std::endl; + // #endif + switch (type) { case BackendType::MLLM_CPU: { shared_ptr mm = nullptr; @@ -120,6 +167,7 @@ class Module { } #ifdef USE_OPENCL case BackendType::MLLM_OPENCL: { + // std::cout << "Initializing OpensssCL Backend..." << std::endl; BackendConfig config; Backend::global_backends[MLLM_OPENCL] = std::make_unique(config); break; @@ -144,98 +192,47 @@ class Module { } // TODO: Deprecated, the module is not backend specific, the backend should be set in the SubGraphStart and SubGraphFinalize - void to(BackendType type) { + Module &to(BackendType type) { initBackend(type); device_ = type; + doChangeBn = true; + doTrace = true; + forwardNoInput(); + doChangeBn = false; + doTrace = false; + tracedFlag = true; + return *this; + } + Module &cpu() { + return to(MLLM_CPU); + } + Module &cl() { +#ifdef USE_OPENCL + return to(MLLM_OPENCL); +#else + throw std::runtime_error("OpenCL backend is not available. Please compile with USE_OPENCL=ON."); +#endif } void load(string path) { // create global loader and save to llm_model_ptr.loader as QNNBackend needs to load weights in runtime loader = std::make_unique(std::move(path), alloc_mmap); // todo Tensor::tensor_status = TENSOR_STATIC_INIT; - mllm_time_init(); doLoad = true; doTrace = true; - vector tmps; - int max_in_size = 5; - for (int i = 0; i < max_in_size; ++i) { - Tensor t(Backend::global_backends[MLLM_CPU].get()); - t.setName("input" + std::to_string(i)); - t.reshape(1, 1, 1, 10); - t.alloc(); - t.setModule(this); - tmps.push_back(t); - } - llm_model_ptr = this; - vector alternate_args = { - {}, - vector{0, 0}, - std::vector>(32, std::vector(2))}; - uint64_t time_start = 0; - for (auto args : alternate_args) { - time_start = mllm_time_us(); - try { - operator()(tmps, args); - break; - } catch (const std::exception &e) { -#if not defined(__ARM_NEON) - if (std::string("bad any_cast") != e.what()) { - MLLM_LOG_ERROR_STREAM << e.what() << std::endl; - exit(0); - } -#endif - } catch (...) { - MLLM_LOG_ERROR_STREAM << "load error" << std::endl; - exit(0); - } - } - uint64_t time_end = mllm_time_us(); - load_time_ = (time_end - time_start) / 1000.0F; // ms + load_time_ = forwardNoInput(); // ms doLoad = false; + tracedFlag = true; doTrace = false; } void load_multifile(const std::initializer_list path) { loader = std::make_unique(std::move(path)); Tensor::tensor_status = TENSOR_STATIC_INIT; - mllm_time_init(); doLoad = true; doTrace = true; - vector tmps; - int max_in_size = 5; - for (int i = 0; i < max_in_size; ++i) { - Tensor t(Backend::global_backends[MLLM_CPU].get()); - t.setName("input" + std::to_string(i)); - t.reshape(1, 1, 1, 10); - t.alloc(); - t.setModule(this); - tmps.push_back(t); - } - llm_model_ptr = this; - vector alternate_args = { - {}, - vector{0, 0}, - std::vector>(32, std::vector(2))}; - uint64_t time_start = 0; - for (auto args : alternate_args) { - time_start = mllm_time_us(); - try { - operator()(tmps, args); - break; - } catch (const std::exception &e) { -#if not defined(__ARM_NEON) - if (std::string("bad any_cast") != e.what()) { - MLLM_LOG_ERROR_STREAM << e.what() << std::endl; - exit(0); - } -#endif - } catch (...) { - MLLM_LOG_ERROR_STREAM << "load error" << std::endl; - exit(0); - } - } - uint64_t time_end = mllm_time_us(); - load_time_ = (time_end - time_start) / 1000.0F; // ms + load_time_ = forwardNoInput(); // ms doLoad = false; + tracedFlag = true; doTrace = false; } @@ -252,7 +249,13 @@ class Module { template vector operator()(vector inputs, Args... args) { vector anyArgs = convertArgsToAnyVector(args...); - auto backend = inputs.empty() ? Backend::global_backends[MLLM_CPU].get() : inputs[0].backend(); + device_ = Module::llm_model_ptr->device(); + auto backend = Backend::global_backends[device_].get(); + if (inputs.empty()) { + for (auto input : inputs) { + assert(input.backend() == backend && "All inputs must have the same backend as the module."); + } + } if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { backend = Backend::global_backends[MLLM_QNN].get(); } @@ -361,6 +364,20 @@ class QNNModuleWrapper : public Module { } }; +#define CHAINABLE_MODULE_METHODS(ClassName) \ + ClassName &to(BackendType type) { \ + Module::to(type); \ + return *this; \ + } \ + ClassName &cpu() { \ + to(MLLM_CPU); \ + return *this; \ + } \ + ClassName &cl() { \ + to(MLLM_OPENCL); \ + return *this; \ + } + } // namespace mllm #endif // MODULE_HPP diff --git a/src/Op.hpp b/src/Op.hpp index ddfa99bf1..f765d41c8 100644 --- a/src/Op.hpp +++ b/src/Op.hpp @@ -61,6 +61,7 @@ class Op { virtual ErrorCode setUp(vector> inputs, vector> outputs) { for (auto &output : outputs) { output->setDtype(activation_dtype_); + output->setCtype(inputs[0]->ctype()); output->alloc(); } return MLLM_NO_ERROR; @@ -110,7 +111,7 @@ class Op { DataType activation_dtype() const { return activation_dtype_; } - OpType type() const { + OpType &type() { return type_; } void setOpType(OpType type) { @@ -131,6 +132,10 @@ class Op { return no_load_weights_dtype_; } + bool &traced() { + return traced_; + } + protected: Backend *backend_; vector inputs_; @@ -139,6 +144,7 @@ class Op { DataType activation_dtype_ = MLLM_TYPE_F32; OpType type_; static DataType no_load_weights_dtype_; + bool traced_ = false; }; class Callable { diff --git a/src/ParamLoader.cpp b/src/ParamLoader.cpp index 90c9cdbcd..bb59dadc2 100644 --- a/src/ParamLoader.cpp +++ b/src/ParamLoader.cpp @@ -86,6 +86,10 @@ bool ParamLoader::load(mllm::Tensor *tensor) { */ // 在 ParamLoader.cpp 中 bool ParamLoader::load(mllm::Tensor *tensor) { + if (tensor->backend() && tensor->backend()->load_from_file(tensor, this)) { + return true; + } + string name = tensor->name(); if (!use_mmap_) { std::lock_guard lock(mtx); @@ -307,11 +311,11 @@ DataType ParamLoader::getDataType(string name) { exit(0); } - // if (use_mmap_) { - // MLLM_LOG_WARNING_STREAM << "Mmap mode: Tensor '" << name << "' not found in model metadata." << std::endl; - // } else { - // MLLM_LOG_WARNING_STREAM << "File IO mode: Tensor '" << name << "' not found in model metadata." << std::endl; - // } + if (use_mmap_) { + MLLM_LOG_WARNING_STREAM << "Mmap mode: Tensor '" << name << "' not found in model metadata." << std::endl; + } else { + MLLM_LOG_WARNING_STREAM << "File IO mode: Tensor '" << name << "' not found in model metadata." << std::endl; + } return DataType::MLLM_TYPE_COUNT; } diff --git a/src/Tensor.cpp b/src/Tensor.cpp index e9bbdb3b1..d164fe1dd 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -11,6 +11,7 @@ // #include "Timing.hpp" #include "Types.hpp" #include +#include #include // #include #include @@ -54,11 +55,12 @@ Tensor::Tensor(const std::vector &shape) : Tensor::Tensor(int value, Backend *bn) : impl_(std::make_shared()) { impl_->dtype_ = MLLM_TYPE_F32; - impl_->backend_ = bn; + impl_->backend_ = Backend::global_backends[MLLM_CPU].get(); reshape(1, 1, 1, 1); alloc(); impl_->should_in_graphs_ = false; setDataAt(0, 0, 0, 0, static_cast(value)); + to(bn->type()); } Tensor::Tensor(int value, BackendType bn_type) : @@ -152,7 +154,9 @@ Tensor &Tensor::to(BackendType backend_type) { // if so, return the origin tensor // if not, return the new tensor // TODO: if need copy, should implement copyDataCrossBn and do copy when Tensor::TENSOR_STATIC_READY - + // if (Module::llm_model_ptr->doChangeBn) { + // Module::llm_model_ptr->device() = backend_type; + // } /** * Currently, there are following cases: * CPU -> QNN, QNN -> CPU @@ -190,8 +194,8 @@ Tensor &Tensor::to(BackendType backend_type) { target_backend = Backend::global_backends[backend_type].get(); assert(target_backend != nullptr && "Target backend is not initialized."); } - // if (backend_type = MLLM_OPENCL){ - // impl_->location_ = TensorImpl::ON_DEVICE; // OpenCL backend should always be on device + // { + // std::cout << name() << ", changing backend from " << device() << " to " << backend_type << std::endl; // debug log // } impl_->to(target_backend); return *this; @@ -252,9 +256,13 @@ void Tensor::_allocate_final_tensor( setDtype(master_tensor_sp->dtype()); shallowCopyFrom(master_tensor_sp, false, {0, 0, (int)cache_seq_len_, 0}); } else { + setDtype(template_tensor->dtype()); alloc(); } } else { + if (template_tensor != nullptr) { + setDtype(template_tensor->dtype()); + } alloc(); } } @@ -348,18 +356,53 @@ std::vector Tensor::runFunc(std::vector out_names, OpParam param, std::vector input_tensors, bool in_place) { + // auto start_time = mllm_time_us(); + + // ==================== [开始] Op 缓存修改 ==================== + if (!input_tensors.empty()) { + for (auto &input : input_tensors) { + assert(input.backend() == input_tensors[0].backend() && "All inputs must have the same backend."); + } + } auto backend = input_tensors.empty() ? Backend::global_backends[MLLM_CPU].get() : input_tensors[0].backend(); - if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { + if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { // 针对QNN的特殊处理 backend = Backend::global_backends[MLLM_QNN].get(); } + + // 1. 在函数内部创建一个静态缓存池,它只初始化一次,并在多次调用中保持存在。 + static std::unordered_map> op_cache; param["type"] = type; - // Op *op_ = backend->opCreate(param, ""); - std::unique_ptr op_(backend->opCreate(param, "")); - if (!op_) { - // 如果 opCreate 失败,可以提前返回或抛出异常 - return {}; + std::shared_ptr op_to_run; + // 2. 生成唯一的缓存键 (Cache Key) + std::stringstream key_stream; + key_stream << static_cast(type); // 加入 OpType + for (const auto &pair : param) { + key_stream << ';' << pair.first << ':' << pair.second; // 加入所有参数 + } + const auto key = key_stream.str(); + // 3. 查找缓存 + auto it = op_cache.find(key); + if (it != op_cache.end()) { + op_to_run = it->second; + if (op_to_run->backend() != backend) { + backend = op_to_run->backend(); + } + } else { + std::unique_ptr op_new(backend->opCreate(param, "")); + if (!op_new) { + backend = Backend::global_backends[MLLM_CPU].get(); + op_new.reset(backend->opCreate(param, "")); + } + op_to_run = std::move(op_new); + op_cache[key] = op_to_run; } - return backend->runOp(op_.get(), input_tensors, out_names, in_place); + // ==================== [结束] Op 缓存修改 ==================== + // if (input_tensors[0].dimension() > 0) { + // auto time_end = mllm_time_us(); + // std::cout << out_names[0] << " dispatch Func: " << type << " in " << (time_end - start_time) / 1000.0F << " ms" << std::endl; + // } + // 4. 使用缓存的或新创建的 Op 执行计算 + return backend->runOp(op_to_run.get(), input_tensors, out_names, in_place); } Tensor Tensor::operator+(float data) { @@ -423,6 +466,9 @@ Tensor Tensor::operator/(Tensor other) { return runFunc({name() + "-TTdiv"}, F_TTDIV, {}, {*this, other})[0]; } +Tensor Tensor::operator~() { + return runFunc({name() + "~"}, TILDE, {}, {*this})[0]; +} Tensor Tensor::mean(Chl axis) { OpParam param; @@ -431,14 +477,14 @@ Tensor Tensor::mean(Chl axis) { {*this})[0]; } -Tensor Tensor::view(int b, int h, int s, int d) { +Tensor Tensor::view(int b, int h, int s, int d, bool in_place) { OpParam param; param["b"] = (float)b; param["h"] = (float)h; param["s"] = (float)s; param["d"] = (float)d; return runFunc({name() + "-view"}, F_VIEW, param, - {*this}, true)[0]; + {*this}, in_place)[0]; } Tensor Tensor::flatten(Chl axis_start, Chl axis_end) { @@ -460,7 +506,7 @@ Tensor Tensor::transpose(vector> axiss) { } bool in_place = (master_tensor_.expired() || (master_tensor_.lock()->name().find("Cache") == std::string::npos && master_tensor_.lock()->name().find("weight") != std::string::npos)); // for BSHD attention start - if (axiss.size() == 1 && axiss[0].first == HEAD && axiss[0].second == SEQUENCE) { + if (Module::llm_model_ptr == nullptr || backend()->type() != MLLM_CPU || (axiss.size() == 1 && axiss[0].first == HEAD && axiss[0].second == SEQUENCE)) { in_place = false; // in-place transpose } // for BSHD attention end @@ -553,12 +599,18 @@ Tensor Tensor::index_put(Tensor value, Tensor indices, bool accumulate) { {*this, value, indices}, !accumulate)[0]; } -void Tensor::scatter_add(Tensor value, Tensor indices) { +void Tensor::scatter_add(Tensor value, Tensor indices, Chl dim) { OpParam param; - runFunc({name()}, F_SCATTERRADD, param, + runFunc({}, F_SCATTERRADD, param, {*this, value, indices})[0]; } - +void Tensor::scatter_(Chl dim, Tensor index, float src) { + OpParam param; + param["dim"] = (float)dim; + param["value"] = src; + runFunc({}, SCATTER, param, + {*this, index})[0]; +} Tensor Tensor::cat(vector input_tensors, Chl axis) { OpParam param; param["axis"] = (float)axis; @@ -634,6 +686,16 @@ Tensor Tensor::repeat(Chl dim, int dim_size) { return runFunc({name() + "repeat"}, F_REPEAT, param, {*this})[0]; } +Tensor Tensor::masked_fill(Tensor mask_index, float value) { + OpParam param; + param["value"] = value; + return runFunc({name() + "-masked_fill"}, MASKEDFILL, param, {*this, mask_index})[0]; +} +Tensor Tensor::gather(Tensor input, Tensor index, Chl dim) { + OpParam param; + param["dim"] = dim; + return runFunc({input.name() + "-gather"}, GATHER, param, {input, index})[0]; +} Tensor Tensor::zero_like(Tensor input) { Module *module = input.module(); OpParam param; diff --git a/src/Tensor.hpp b/src/Tensor.hpp index 2a92ebefa..3b08bcd41 100644 --- a/src/Tensor.hpp +++ b/src/Tensor.hpp @@ -1,6 +1,8 @@ #ifndef MLLM_TENSOR_H #define MLLM_TENSOR_H // #include +#include "DataType.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" #include #include #include @@ -59,8 +61,9 @@ class Module; * */ class Tensor : public std::enable_shared_from_this { +protected: std::shared_ptr impl_; // 核心:使用shared_ptr管理实现 - +private: // used for ChildTensor vector shape_offset_; vector shape_master_; @@ -319,6 +322,8 @@ class Tensor : public std::enable_shared_from_this { auto shape = grandmaster->impl_->shape_; if (grandmaster->impl_->ctype_ == BSHD) { return shape[3] * shape[2]; + } else if (grandmaster->impl_->ctype_ == BHSD) { + return shape[3]; } else if (grandmaster->impl_->ctype_ == BHDS) { return shape[3]; } else if (grandmaster->impl_->ctype_ == BDHS) { @@ -331,6 +336,8 @@ class Tensor : public std::enable_shared_from_this { auto shape = master->impl_->shape_; if (master->impl_->ctype_ == BSHD) { return shape[3] * shape[2]; + } else if (master->impl_->ctype_ == BHSD) { + return shape[3]; } else if (master->impl_->ctype_ == BHDS) { return shape[3]; } else if (master->impl_->ctype_ == BDHS) { @@ -343,6 +350,8 @@ class Tensor : public std::enable_shared_from_this { } else { if (impl_->ctype_ == BSHD) { return impl_->shape_[3] * impl_->shape_[2]; + } else if (impl_->ctype_ == BHSD) { + return impl_->shape_[3]; } else if (impl_->ctype_ == BHDS) { return impl_->shape_[3]; } else if (impl_->ctype_ == BDHS) { @@ -573,6 +582,28 @@ class Tensor : public std::enable_shared_from_this { }); return shape_int; } + int shape(Chl axis) const { + switch (axis) { + case Chl::BATCH: + return impl_->shape_[impl_->chls_[BATCH]]; + case Chl::HEAD: + return impl_->shape_[impl_->chls_[HEAD]]; + case Chl::SEQUENCE: + return impl_->shape_[impl_->chls_[SEQUENCE]]; + case Chl::DIMENSION: + return impl_->shape_[impl_->chls_[DIMENSION]]; + // case TIME: + // return impl_->shape_[impl_->chls_[TIME]]; + // case HEIGHT: + return impl_->shape_[impl_->chls_[HEIGHT]]; + case Chl::WIDTH: + return impl_->shape_[impl_->chls_[WIDTH]]; + // case CHANNLE: + // return impl_->shape_[impl_->chls_[CHANNLE]]; + default: + throw std::invalid_argument("Invalid axis for shape retrieval"); + } + } ChlType ctype() const { return impl_->ctype_; @@ -808,8 +839,8 @@ class Tensor : public std::enable_shared_from_this { Tensor operator*(float data); Tensor operator/(float data); Tensor operator/(double data); - Tensor operator/(int data); + Tensor operator~(); /** * \brief Overload the operators. @@ -823,7 +854,7 @@ class Tensor : public std::enable_shared_from_this { Tensor mean(Chl axis); - Tensor view(int b, int h, int s, int d); + Tensor view(int b, int h, int s, int d, bool in_place = true); Tensor flatten(Chl axis_start, Chl axis_end); Tensor transpose(Chl axis0, Chl axis1) { return transpose({{axis0, axis1}}); @@ -844,12 +875,18 @@ class Tensor : public std::enable_shared_from_this { return split(*this, each_dims, split_dim, same_dim_size); } Tensor index_put(Tensor value, Tensor indices, bool accumulate); - void scatter_add(Tensor value, Tensor indices); + void scatter_add(Tensor value, Tensor indices, Chl dim = SEQUENCE); + void scatter_(Chl dim, Tensor index, float src); static vector topk(Tensor input, int k, Chl dim); + vector topk(int k, Chl dim) { + return topk(*this, k, dim); + } Tensor sum(Chl dim); Tensor argsort(); Tensor bincount(); Tensor repeat(Chl dim, int dim_size); + Tensor masked_fill(Tensor mask, float value); + static Tensor gather(Tensor input, Tensor index, Chl dim); static Tensor zero_like(Tensor input); static Tensor flash_attention2_forward(Tensor q, Tensor k, Tensor v, bool is_causal = true); static Tensor sage_attention_forward(Tensor q, Tensor k, Tensor v, bool causal_mask = false); @@ -905,7 +942,10 @@ class Tensor : public std::enable_shared_from_this { // 步骤 2: 核心浅拷贝操作 - 共享数据指针和元数据 impl_->host_ptr_ = source->hostPtr(); + impl_->memory_handle_ = source->impl_->memory_handle_; impl_->owns_host_ptr_ = false; + impl_->device_memory_ = source->impl_->device_memory_; + impl_->owns_device_memory_ = false; impl_->capacity_ = source->impl_->capacity_; impl_->count_ = source->impl_->count_; impl_->allocated_ = source->impl_->allocated_; @@ -1067,6 +1107,15 @@ class Tensor : public std::enable_shared_from_this { } Tensor &to(BackendType backend_type); + Tensor to(DataType dtype) { + if (dtype == MLLM_TYPE_F16) { + return half(); + } else if (dtype == MLLM_TYPE_F32) { + return fp32(); + } else { + throw std::runtime_error("Unsupported dtype conversion."); + } + } Tensor &cpu() { return to(MLLM_CPU); @@ -1085,8 +1134,15 @@ class Tensor : public std::enable_shared_from_this { assert(dtype() == MLLM_TYPE_F32 && "Tensor::half() can only be called on an FP32 tensor."); assert(master_tensor_.expired() && "Conversion not supported for child tensors."); if (allocted()) { - Tensor half_tensor(batch(), head(), sequence(), dimension(), backend(), false); + Tensor half_tensor(backend()); + auto batch = this->batch(); + auto head = this->head(); + auto sequence = this->sequence(); + auto dimension = this->dimension(); half_tensor.setDtype(MLLM_TYPE_F16); + half_tensor.setName(impl_->name_); + half_tensor.setCtype(impl_->ctype_); + half_tensor.reshape(batch, head, sequence, dimension); half_tensor.alloc(); backend()->convert_fp_data(this, &half_tensor); return half_tensor; @@ -1105,8 +1161,15 @@ class Tensor : public std::enable_shared_from_this { assert(dtype() == MLLM_TYPE_F16 && "Tensor::fp32() can only be called on an FP16 tensor."); assert(master_tensor_.expired() && "Conversion not supported for child tensors."); if (allocted()) { - Tensor fp32_tensor(batch(), head(), sequence(), dimension(), backend(), false); + Tensor fp32_tensor(backend()); + auto batch = this->batch(); + auto head = this->head(); + auto sequence = this->sequence(); + auto dimension = this->dimension(); fp32_tensor.setDtype(MLLM_TYPE_F32); + fp32_tensor.setName(impl_->name_); + fp32_tensor.setCtype(impl_->ctype_); + fp32_tensor.reshape(batch, head, sequence, dimension); fp32_tensor.alloc(); backend()->convert_fp_data(this, &fp32_tensor); return fp32_tensor; @@ -1659,6 +1722,7 @@ class Tensor : public std::enable_shared_from_this { template void printData() { + assert(backend()->type() == MLLM_CPU && "printData only support CPU backend."); if (ctype() == BTHWC || ctype() == BCTHW) { printData(); return; @@ -1737,12 +1801,29 @@ class Tensor : public std::enable_shared_from_this { int C = head(); int H = sequence(); int W = dimension(); + + if (impl_->ctype_ == BHSD) { + for (int n = 0; n < batch(); ++n) { + for (int c = 0; c < head(); ++c) { + for (int h = 0; h < sequence(); ++h) { + for (int w = 0; w < dimension(); ++w) { + outFile << std::fixed << std::setprecision(6) << dataAt(n, c, h, w) << " "; + } + outFile << std::endl; + } + outFile << std::endl; + } + outFile << std::endl; + } + outFile.close(); + return; + } if (impl_->ctype_ == BSHD) { for (int n = 0; n < batch(); ++n) { for (int h = 0; h < sequence(); ++h) { for (int c = 0; c < head(); ++c) { for (int w = 0; w < dimension(); ++w) { - outFile << std::fixed << std::setprecision(6) << dataAt(n, c, h, w) << " "; + outFile << std::fixed << std::setprecision(6) << static_cast(dataAt(n, c, h, w)) << " "; } outFile << std::endl; } @@ -1786,6 +1867,64 @@ class Tensor : public std::enable_shared_from_this { outFile.close(); } + void saveQ4Data_d(string ex = "", string directory = "save_out") { + if (batch() == 0) { + return; + } + struct stat info; +#ifdef _WIN32 + _mkdir(directory.c_str()); +#else + if (stat(directory.c_str(), &info) != 0) { + if (stat(directory.c_str(), &info) != 0) { + mkdir(directory.c_str(), 0777); // notice that 0777 is different than usual + } else if (!(info.st_mode & S_IFDIR)) { + // if the path exists but it is not a directory, also create it + mkdir(directory.c_str(), 0777); // notice that 0777 is different than usual + } + } +#endif + std::ofstream outFile(directory + "/" + name() + ex + ".log"); + outFile << "----------------------------------------" << std::endl; + if (impl_->ctype_ == BSHD) { + outFile << name() << ": [BSHD]shape:[" << batch() << " " << sequence() << " " << head() << " " << dimension() << "] " << DataTypeName(dtype()) << " " << ctype() << std::endl; + } else { + outFile << name() << ": shape:[" << batch() << " " << head() << " " << sequence() << " " << dimension() << "] " << DataTypeName(dtype()) << " " << ctype() << std::endl; + } + + if (impl_->dtype_ != MLLM_TYPE_Q4_0) { + outFile << "Error: Tensor is not of type MLLM_TYPE_Q4_0." << std::endl; + outFile.close(); + return; + } + + block_q4_0 *data_ptr = hostPtr(); + if (data_ptr == nullptr) { + outFile << "Error: Host pointer is null." << std::endl; + outFile.close(); + return; + } + + const int W_blocks = dimension() / QK4_0; + + // 保持原始的循环结构。注意变量名: h 代表 sequence, c 代表 head。 + for (int n = 0; n < batch(); ++n) { + for (int h = 0; h < sequence(); ++h) { + for (int c = 0; c < head(); ++c) { + for (int w = 0; w < W_blocks; ++w) { + uint64_t block_offset = offset(n, c, h, w) / QK4_0; + block_q4_0 &data_block = data_ptr[block_offset]; + float da = MLLM_FP16_TO_FP32(data_block.d); + outFile << std::fixed << std::setprecision(6) << da << " "; + } + outFile << std::endl; + } + outFile << std::endl; + } + outFile << std::endl; + } + outFile.close(); + } template void saveIntData(string ex = "") { if (Tensor::tensor_status != TENSOR_STATIC_READY) return; diff --git a/src/TensorImpl.hpp b/src/TensorImpl.hpp index 82eefbd63..942312260 100644 --- a/src/TensorImpl.hpp +++ b/src/TensorImpl.hpp @@ -1,6 +1,7 @@ #ifndef MLLM_TENSORIMPL_H #define MLLM_TENSORIMPL_H #include +#include #include #include // #include @@ -47,6 +48,7 @@ class TensorImpl { public: void *host_ptr_ = nullptr; bool owns_host_ptr_ = true; + bool owns_device_memory_ = true; std::shared_ptr memory_handle_ = nullptr; //=====GPU====== @@ -101,6 +103,9 @@ class TensorImpl { return DataTypeSize(dtype_, count_); } void alloc() { + if (backend_->type() == MLLM_OPENCL) { + location_ = ON_DEVICE; + } if (location_ == ON_DEVICE) { if (device_memory_.handle != nullptr) return; if (host_ptr_ != nullptr && owns_host_ptr_) { @@ -110,6 +115,8 @@ class TensorImpl { } device_memory_.size_in_bytes = cntSize(); backend_->alloc_device(device_memory_, dtype_); + // owns_device_memory_ = true; + allocated_ = count_; return; } if (allocated_ != count_) { @@ -127,9 +134,10 @@ class TensorImpl { void free_memory() { if (location_ == ON_HOST && host_ptr_ != nullptr && owns_host_ptr_) { if (backend_) backend_->free(host_ptr_); - } else if (location_ == ON_DEVICE && device_memory_.handle != nullptr) { + } else if (location_ == ON_DEVICE && device_memory_.handle != nullptr && owns_device_memory_) { // if (backend_) backend_->free_device(device_memory_); device_memory_.handle = nullptr; // 清理句柄 + // owns_device_memory_ = false; } host_ptr_ = nullptr; allocated_ = 0; @@ -189,7 +197,7 @@ class TensorImpl { } host_ptr_ = nullptr; location_ = ON_DEVICE; - allocated_ = 0; + // allocated_ = 0;// todo1418 } } else { std::cout << "Device -> Device migration via Host" << std::endl; diff --git a/src/backends/cpu/CPUBackend.cpp b/src/backends/cpu/CPUBackend.cpp index 1d448a957..6e3ae45c2 100644 --- a/src/backends/cpu/CPUBackend.cpp +++ b/src/backends/cpu/CPUBackend.cpp @@ -96,6 +96,10 @@ #include "op/CPUVisionRoPEFunc.hpp" #include "op/CPUFlashAttention2Func.hpp" #include "op/CPUSageAttentionFunc.hpp" +#include "op/CPUScatter.hpp" +#include "op/CPUTilde.hpp" +#include "op/CPUMaskedFill.hpp" +#include "op/CPUSigmoid.hpp" #include "op/CPUFuyuGatherEmbdFunc.hpp" #include "op/CPUPhi3VhdmergeFunc.hpp" @@ -165,7 +169,6 @@ void CPUBackend::registerOps() { addCreator(VISIONROPE, (CPUBackend::Creator *)(new CPUVisionRoPECreator())); addCreator(MULTIMODALROPEPIP, (CPUBackend::Creator *)(new CPUMultimodalRoPEPipelineCreator())); addCreator(MULTIMODALROPE, (CPUBackend::Creator *)(new CPUMultimodalRoPECreator())); - // addCreator(CAT, (CPUBackend::Creator *)(new CPUCatCreator())); addCreator(TRANSPOSE, (CPUBackend::Creator *)(new CPUTransposeCreator())); addCreator(SUBDIM, (CPUBackend::Creator *)(new CPUSubDimCreator())); addCreator(DIVISION, (CPUBackend::Creator *)(new CPUDivisionCreator())); @@ -189,6 +192,7 @@ void CPUBackend::registerOps() { addCreator(NTKROPE, (CPUBackend::Creator *)(new CPUNTKRoPECreator())); addCreator(HEADLINEAR, (CPUBackend::Creator *)(new CPUHeadLinearCreator())); addCreator(KVCACHESAGE, (CPUBackend::Creator *)(new CPUKVCacheSageCreator())); + addCreator(SIGMOID, (CPUBackend::Creator *)(new CPUSigmoidCreator())); // funsction addCreator(F_ADD, (CPUBackend::Creator *)(new CPUaddFunctionCreator())); @@ -225,6 +229,9 @@ void CPUBackend::registerOps() { addCreator(F_APPLY_VISIOROPE, (CPUBackend::Creator *)(new CPUVisionRoPEFuncFunctionCreator())); addCreator(F_FA2, (CPUBackend::Creator *)(new CPUFlashAttention2FuncCreator())); addCreator(F_SAGEATTN, (CPUBackend::Creator *)(new CPUSageAttentionFuncCreator())); + addCreator(SCATTER, (CPUBackend::Creator *)(new CPUScatterCreator())); + addCreator(TILDE, (CPUBackend::Creator *)(new CPUTildeCreator())); + addCreator(MASKEDFILL, (CPUBackend::Creator *)(new CPUMaskedFillCreator())); // models use only addCreator(F_FUYU_GATHER_EMBD, (CPUBackend::Creator *)(new CPUFuyuGatherEmbdFuncCreator())); addCreator(F_PHI3V_HD_MERGE, (CPUBackend::Creator *)(new CPUPhi3VhdmergeFunctionCreator())); @@ -303,6 +310,18 @@ std::vector CPUBackend::runOp(Op *op, std::vector inputs, std::v static map> empty_activation_tensors; map> &activation_tensors = module ? module->activation_tensors : empty_activation_tensors; if (module && module->doTrace) { // trace + if (module->tracedFlag) { + vector results = {}; + for (auto &name : out_names) results.push_back(*activation_tensors[name]); + return results; + } + for (auto &input : inputs) { + if (input.shouldInGraphs() && activation_tensors.find(input.name()) == activation_tensors.end()) { + activation_tensors[input.name()] = std::make_shared(op->backend()); + activation_tensors[input.name()]->setName(input.name()); + activation_tensors[input.name()]->setModule(module); + } + } for (const auto &out_name : out_names) { if (activation_tensors.find(out_name) == activation_tensors.end()) { activation_tensors[out_name] = std::make_shared(op->backend()); @@ -373,6 +392,8 @@ std::vector CPUBackend::runOp(Op *op, std::vector inputs, std::v #ifdef DEBUGSAVETENSOR if (out_tensor->dtype() == MLLM_TYPE_F32) out_tensor->saveData(); + if (out_tensor->dtype() == MLLM_TYPE_F16) + out_tensor->saveData(); #endif } return results; @@ -391,7 +412,7 @@ std::vector CPUBackend::runLayer(Layer *layer, std::vector input } std::vector CPUBackend::runForward(Module *module, std::vector inputs, std::vector args) { - if (mllm::Module::llm_model_ptr && mllm::Module::llm_model_ptr->doLoad) { + if (mllm::Module::llm_model_ptr && (mllm::Module::llm_model_ptr->doLoad || Module::llm_model_ptr->doChangeBn)) { auto outputs = module->Forward(inputs, args); return outputs; } diff --git a/src/backends/cpu/compute/GemmFp.hpp b/src/backends/cpu/compute/GemmFp.hpp new file mode 100644 index 000000000..977f11c85 --- /dev/null +++ b/src/backends/cpu/compute/GemmFp.hpp @@ -0,0 +1,283 @@ +#include +#include +#include +#include + +#include "DataType.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" + +// --- 平台检测和微内核尺寸定义 --- +#if defined(__aarch64__) +#include +#define TARGET_ARCH "aarch64 (NEON)" +#define MR_micro 4 // NEON 使用 4x4 微内核 +#define NR_micro 4 + +#elif defined(__x86_64__) || defined(_M_X64) +#include // for AVX, FMA +#define TARGET_ARCH "x86_64 (AVX)" +#define MR_micro 8 // AVX 使用 8x8 微内核 +#define NR_micro 8 + +#else +#define TARGET_ARCH "Generic C" +#define MR_micro 4 +#define NR_micro 4 +#endif + +#define KC_BLOCK 256 + +static inline int min(int a, int b) { + return a < b ? a : b; +} + +// --- 平台特定的打包和微内核函数 --- + +#if defined(__aarch64__) +// NEON: 打包B矩阵的一个 4xkc 的 Panel +static void pack_b_for_neon_4x4(float *packed_b, const float *b_ptr, int N, int k_start, int k_end, int n_start) { + int kc = k_end - k_start; + const int nc = NR_micro; + + for (int k_local = 0; k_local < kc; ++k_local) { + const float *b_src_ptr = b_ptr + (k_start + k_local) * N + n_start; + float *b_dest_ptr = packed_b + k_local * nc; + memcpy(b_dest_ptr, b_src_ptr, nc * sizeof(float)); + } +} + +// NEON: 4x4 微内核 +static void gemm_micro_kernel_neon_4x4(float *c_ptr, const float *a_ptr, const float *packed_b_ptr, int kc, int lda, int ldc) { + float32x4_t c_reg0, c_reg1, c_reg2, c_reg3; + c_reg0 = vld1q_f32(c_ptr + 0 * ldc); + c_reg1 = vld1q_f32(c_ptr + 1 * ldc); + c_reg2 = vld1q_f32(c_ptr + 2 * ldc); + c_reg3 = vld1q_f32(c_ptr + 3 * ldc); + for (int k = 0; k < kc; ++k) { + float32x4_t b_reg = vld1q_f32(packed_b_ptr + k * NR_micro); + c_reg0 = vfmaq_f32(c_reg0, vld1q_dup_f32(a_ptr + 0 * lda + k), b_reg); + c_reg1 = vfmaq_f32(c_reg1, vld1q_dup_f32(a_ptr + 1 * lda + k), b_reg); + c_reg2 = vfmaq_f32(c_reg2, vld1q_dup_f32(a_ptr + 2 * lda + k), b_reg); + c_reg3 = vfmaq_f32(c_reg3, vld1q_dup_f32(a_ptr + 3 * lda + k), b_reg); + } + vst1q_f32(c_ptr + 0 * ldc, c_reg0); + vst1q_f32(c_ptr + 1 * ldc, c_reg1); + vst1q_f32(c_ptr + 2 * ldc, c_reg2); + vst1q_f32(c_ptr + 3 * ldc, c_reg3); +} + +#elif defined(__x86_64__) || defined(_M_X64) +// AVX: 打包B矩阵的一个 8xkc 的 Panel +static void pack_b_for_avx_8x8(float *packed_b, const float *b_ptr, int N, int k_start, int k_end, int n_start) { + int kc = k_end - k_start; + const int nc = NR_micro; + + for (int k_local = 0; k_local < kc; ++k_local) { + const float *b_src_ptr = b_ptr + (k_start + k_local) * N + n_start; + float *b_dest_ptr = packed_b + k_local * nc; + memcpy(b_dest_ptr, b_src_ptr, nc * sizeof(float)); + } +} + +// AVX: 8x8 微内核 +static void gemm_micro_kernel_avx_8x8(float *c_ptr, const float *a_ptr, const float *packed_b_ptr, int kc, int lda, int ldc) { + __m256 c_reg[MR_micro]; + for (int i = 0; i < MR_micro; ++i) { + c_reg[i] = _mm256_loadu_ps(c_ptr + i * ldc); + } + + for (int k = 0; k < kc; ++k) { + __m256 b_reg = _mm256_load_ps(packed_b_ptr + k * NR_micro); + for (int i = 0; i < MR_micro; ++i) { + __m256 a_broadcast = _mm256_set1_ps(a_ptr[i * lda + k]); + c_reg[i] = _mm256_fmadd_ps(a_broadcast, b_reg, c_reg[i]); + } + } + + for (int i = 0; i < MR_micro; ++i) { + _mm256_storeu_ps(c_ptr + i * ldc, c_reg[i]); + } +} +#endif + +// 主 GEMM 函数 +void gemm_fp32(float *c_ptr, const float *a_ptr, const float *b_ptr, int M, int N, int K) { +#if defined(__aarch64__) || defined(__x86_64__) || defined(_M_X64) + // 仅在NEON或AVX路径下,我们才为打包分配内存 + float *packed_b = (float *)malloc(KC_BLOCK * NR_micro * sizeof(float)); + if (!packed_b) return; +#endif + + for (int k_col = 0; k_col < K; k_col += KC_BLOCK) { + int kc = min(KC_BLOCK, K - k_col); + + for (int i_row = 0; i_row < M; i_row += MR_micro) { + int mc = min(MR_micro, M - i_row); + + for (int j_col = 0; j_col < N; j_col += NR_micro) { + int nc = min(NR_micro, N - j_col); + +#if defined(__aarch64__) + if (mc == MR_micro && nc == NR_micro) { + pack_b_for_neon_4x4(packed_b, b_ptr, N, k_col, k_col + kc, j_col); + gemm_micro_kernel_neon_4x4(c_ptr + i_row * N + j_col, a_ptr + i_row * K + k_col, packed_b, kc, K, N); + continue; + } +#elif defined(__x86_64__) || defined(_M_X64) + if (mc == MR_micro && nc == NR_micro) { + pack_b_for_avx_8x8(packed_b, b_ptr, N, k_col, k_col + kc, j_col); + gemm_micro_kernel_avx_8x8(c_ptr + i_row * N + j_col, a_ptr + i_row * K + k_col, packed_b, kc, K, N); + continue; + } +#endif + + // --- 通用C语言路径 (也用于NEON/AVX的边缘情况) --- + // 直接使用原始A, B矩阵进行计算,确保正确性 + for (int i = 0; i < mc; ++i) { + for (int j = 0; j < nc; ++j) { + float sum = 0.0f; + for (int k = 0; k < kc; ++k) { + sum += a_ptr[(i_row + i) * K + (k_col + k)] * b_ptr[(k_col + k) * N + (j_col + j)]; + } + c_ptr[(i_row + i) * N + (j_col + j)] += sum; + } + } + } + } + } + +#if defined(__aarch64__) || defined(__x86_64__) || defined(_M_X64) + free(packed_b); +#endif +} + +#if defined(__aarch64__) +// NEON: 打包B矩阵(fp16)的一个 4xkc 的 Panel +static void pack_b_fp16_for_neon_4x4(mllm_fp16_t *packed_b, const mllm_fp16_t *b_ptr, int N, int k_start, int k_end, int n_start) { + int kc = k_end - k_start; + const int nc = NR_micro; + + for (int k_local = 0; k_local < kc; ++k_local) { + const mllm_fp16_t *b_src_ptr = b_ptr + (k_start + k_local) * N + n_start; + mllm_fp16_t *b_dest_ptr = packed_b + k_local * nc; + memcpy(b_dest_ptr, b_src_ptr, nc * sizeof(mllm_fp16_t)); + } +} + +// NEON: 4x4 微内核 (fp32 * fp16) +static void gemm_micro_kernel_fp32_fp16_neon_4x4(float *c_ptr, const float *a_ptr, const mllm_fp16_t *packed_b_ptr, int kc, int lda, int ldc) { + float32x4_t c_reg0, c_reg1, c_reg2, c_reg3; + c_reg0 = vld1q_f32(c_ptr + 0 * ldc); + c_reg1 = vld1q_f32(c_ptr + 1 * ldc); + c_reg2 = vld1q_f32(c_ptr + 2 * ldc); + c_reg3 = vld1q_f32(c_ptr + 3 * ldc); + + for (int k = 0; k < kc; ++k) { + // 1. 从打包好的B中加载一行fp16 + float16x4_t b_reg_f16 = vld1_f16(packed_b_ptr + k * NR_micro); + // 2. 将fp16向量转换为fp32向量 + float32x4_t b_reg_f32 = vcvt_f32_f16(b_reg_f16); + + // 3. 执行乘加操作 (与之前相同) + c_reg0 = vfmaq_f32(c_reg0, vld1q_dup_f32(a_ptr + 0 * lda + k), b_reg_f32); + c_reg1 = vfmaq_f32(c_reg1, vld1q_dup_f32(a_ptr + 1 * lda + k), b_reg_f32); + c_reg2 = vfmaq_f32(c_reg2, vld1q_dup_f32(a_ptr + 2 * lda + k), b_reg_f32); + c_reg3 = vfmaq_f32(c_reg3, vld1q_dup_f32(a_ptr + 3 * lda + k), b_reg_f32); + } + vst1q_f32(c_ptr + 0 * ldc, c_reg0); + vst1q_f32(c_ptr + 1 * ldc, c_reg1); + vst1q_f32(c_ptr + 2 * ldc, c_reg2); + vst1q_f32(c_ptr + 3 * ldc, c_reg3); +} + +#elif defined(__x86_64__) || defined(_M_X64) +// AVX: 打包B矩阵(fp16)的一个 8xkc 的 Panel +static void pack_b_fp16_for_avx_8x8(mllm_fp16_t *packed_b, const mllm_fp16_t *b_ptr, int N, int k_start, int k_end, int n_start) { + int kc = k_end - k_start; + const int nc = NR_micro; + + for (int k_local = 0; k_local < kc; ++k_local) { + const mllm_fp16_t *b_src_ptr = b_ptr + (k_start + k_local) * N + n_start; + mllm_fp16_t *b_dest_ptr = packed_b + k_local * nc; + memcpy(b_dest_ptr, b_src_ptr, nc * sizeof(mllm_fp16_t)); + } +} + +// AVX: 8x8 微内核 (fp32 * fp16) +static void gemm_micro_kernel_fp32_fp16_avx_8x8(float *c_ptr, const float *a_ptr, const mllm_fp16_t *packed_b_ptr, int kc, int lda, int ldc) { + __m256 c_reg[MR_micro]; + for (int i = 0; i < MR_micro; ++i) { + c_reg[i] = _mm256_loadu_ps(c_ptr + i * ldc); + } + + for (int k = 0; k < kc; ++k) { + // 1. 从打包好的B中加载一行fp16 (8个uint16_t) 到一个128位的XMM寄存器 + __m128i b_reg_f16 = _mm_loadu_si128((__m128i const *)(packed_b_ptr + k * NR_micro)); + // 2. 将128位的fp16向量转换为256位的fp32向量 + __m256 b_reg_f32 = _mm256_cvtph_ps(b_reg_f16); + + // 3. 执行乘加操作 (与之前相同) + for (int i = 0; i < MR_micro; ++i) { + __m256 a_broadcast = _mm256_set1_ps(a_ptr[i * lda + k]); + c_reg[i] = _mm256_fmadd_ps(a_broadcast, b_reg_f32, c_reg[i]); + } + } + + for (int i = 0; i < MR_micro; ++i) { + _mm256_storeu_ps(c_ptr + i * ldc, c_reg[i]); + } +} +#endif + +// 新增的 GEMM 函数 +void gemm_fp32_fp16(float *c_ptr, const float *a_ptr, const mllm_fp16_t *b_ptr, int M, int N, int K) { +#if defined(__aarch64__) || defined(__x86_64__) || defined(_M_X64) + // 仅在NEON或AVX路径下,我们才为打包分配内存 + mllm_fp16_t *packed_b = (mllm_fp16_t *)malloc(KC_BLOCK * NR_micro * sizeof(mllm_fp16_t)); + if (!packed_b) return; +#endif + + for (int k_col = 0; k_col < K; k_col += KC_BLOCK) { + int kc = min(KC_BLOCK, K - k_col); + + for (int i_row = 0; i_row < M; i_row += MR_micro) { + int mc = min(MR_micro, M - i_row); + + for (int j_col = 0; j_col < N; j_col += NR_micro) { + int nc = min(NR_micro, N - j_col); + +#if defined(__aarch64__) + if (mc == MR_micro && nc == NR_micro) { + pack_b_fp16_for_neon_4x4(packed_b, b_ptr, N, k_col, k_col + kc, j_col); + gemm_micro_kernel_fp32_fp16_neon_4x4(c_ptr + i_row * N + j_col, a_ptr + i_row * K + k_col, packed_b, kc, K, N); + continue; + } +#elif defined(__x86_64__) || defined(_M_X64) + if (mc == MR_micro && nc == NR_micro) { + pack_b_fp16_for_avx_8x8(packed_b, b_ptr, N, k_col, k_col + kc, j_col); + gemm_micro_kernel_fp32_fp16_avx_8x8(c_ptr + i_row * N + j_col, a_ptr + i_row * K + k_col, packed_b, kc, K, N); + continue; + } +#endif + + // ---- 通用C语言路径 (也用于NEON/AVX的边缘情况) ---- + // 直接使用原始A(fp32)和B(fp16)矩阵进行计算 + for (int i = 0; i < mc; ++i) { + for (int j = 0; j < nc; ++j) { + float sum = 0.0f; + for (int k = 0; k < kc; ++k) { + // C[i_row+i][j_col+j] += A[i_row+i][k_col+k] * B[k_col+k][j_col+j] + // 关键:使用宏将B的fp16值转换为fp32 + sum += a_ptr[(i_row + i) * K + (k_col + k)] * MLLM_FP16_TO_FP32(b_ptr[(k_col + k) * N + (j_col + j)]); + } + c_ptr[(i_row + i) * N + (j_col + j)] += sum; + } + } + } + } + } + +#if defined(__aarch64__) || defined(__x86_64__) || defined(_M_X64) + free(packed_b); +#endif +} diff --git a/src/backends/cpu/compute/GemmKleidiai.cpp b/src/backends/cpu/compute/GemmKleidiai.cpp index d7a0e4ee5..9b0d2ec8a 100644 --- a/src/backends/cpu/compute/GemmKleidiai.cpp +++ b/src/backends/cpu/compute/GemmKleidiai.cpp @@ -698,7 +698,7 @@ void mllm_kleidai_pack_b_and_bias_fp16_transpose(mllm_fp16_t *packed_b_ptr, cons mllm_kleidai_pack_b_and_bias_fp16(packed_b_ptr, b_temp_kxn.data(), bias_ptr, N, K); } - +/*** no use ****/ void mllm_kleidai_gemm_fp32_transpose(float *c_ptr, const float *a_ptr, const float *b_ptr_nxk, const float *bias_ptr, int M, int N, int K) { size_t packed_b_size = mllm_kleidai_get_packed_b_fp32_size(N, K); std::vector packed_b_data(packed_b_size); @@ -713,4 +713,121 @@ void mllm_kleidai_gemm_fp16_transpose(float *c_ptr, const float *a_ptr, const ml mllm_kleidai_gemm_fp16(c_ptr, a_ptr, packed_b_data.data(), M, N, K); } +void mllm_kleidai_gemm_fp32_bshd(float *c_ptr, const float *a_ptr, const float *packed_b_ptr, int B, int H, int S_M, int S_N, int D_K) { + const int M = S_M; + const int K = D_K; // 在GEMM上下文中,K是BSHD布局中的D(dimension) + + // 为 BSHD (B,S,H,D/N) 布局计算跨距 + const long long stride_a_b = (long long)S_M * H * K; + const long long stride_a_s = (long long)H * K; + + const long long stride_c_b = (long long)S_M * H * S_N; + const long long stride_c_s = (long long)H * S_N; + + const int m_step = fp32_ukernel.get_m_step(); + const int n_step = fp32_ukernel.get_n_step(); + + // 并行处理 batch 和 head 维度 +#pragma omp parallel for collapse(2) num_threads(kai_thread_count) + for (int b = 0; b < B; ++b) { + for (int h = 0; h < H; ++h) { + for (int m_start = 0; m_start < M; m_start += m_step) { + for (int n_start = 0; n_start < S_N; n_start += n_step) { + const int current_m = std::min(M - m_start, m_step); + const int current_n = std::min(S_N - n_start, n_step); + + // 计算当前块在BSHD布局中的A矩阵偏移 + // 指向 A[b, m_start, h, 0] + const float *a_offset = a_ptr + b * stride_a_b + m_start * stride_a_s + h * K; + + // B矩阵是预打包的,其偏移仅与N维度相关 + const float *b_offset = packed_b_ptr + (n_start * (K + 1)); + + // 计算当前块在BSHD布局中的C矩阵偏移 + // 指向 C[b, m_start, h, n_start] + float *c_offset = c_ptr + b * stride_c_b + m_start * stride_c_s + h * S_N + n_start; + + // 调用微内核,传入正确的行跨距 + fp32_ukernel.run_matmul( + current_m, current_n, K, + a_offset, stride_a_s * sizeof(float), // A矩阵的行跨距 + b_offset, + c_offset, stride_c_s * sizeof(float), // C矩阵的行跨距 + sizeof(float), + -FLT_MAX, FLT_MAX); + } + } + } + } +} + +void mllm_kleidai_gemm_fp16_bshd(float *c_ptr, const float *a_ptr, const mllm_fp16_t *packed_b_ptr, int B, int H, int S_M, int S_N, int D_K) { + const int M = S_M; + const int K = D_K; // 在GEMM上下文中,K是BSHD布局中的D(dimension) + + // 为 BSHD (B,S,H,D/N) 布局计算跨距 + const long long stride_a_b = (long long)S_M * H * K; + const long long stride_a_s = (long long)H * K; + + const long long stride_c_b = (long long)S_M * H * S_N; + const long long stride_c_s = (long long)H * S_N; + + const int m_step = fp16_ukernel.get_m_step(); + const int n_step = fp16_ukernel.get_n_step(); + + // 并行处理 batch 和 head 维度 +#pragma omp parallel for collapse(2) num_threads(kai_thread_count) + for (int b = 0; b < B; ++b) { + for (int h = 0; h < H; ++h) { + // 从工作区管理器获取线程本地缓冲区 + auto &a_fp16 = WorkspaceManager::get_instance().get_fp16_a_buffer(); + if (a_fp16.size() < M * K) { + a_fp16.resize(M * K); + } + + auto &c_fp16 = WorkspaceManager::get_instance().get_fp16_c_buffer(); + if (c_fp16.size() < M * S_N) { + c_fp16.resize(M * S_N); + } + + // 1. 收集(Gather)和转换: 将非连续的 BSHD float A矩阵切片复制到连续的 fp16 缓冲区 + const float *a_bh_ptr = a_ptr + b * stride_a_b; // 指向批次 b 的起始位置 + for (int s = 0; s < S_M; ++s) { + for (int d = 0; d < D_K; ++d) { + // 从 A[b,s,h,d] 读取 + a_fp16[s * D_K + d] = static_cast(a_bh_ptr[s * stride_a_s + h * D_K + d]); + } + } + + // 2. 计算: 在连续的缓冲区上执行GEMM + for (int m_start = 0; m_start < M; m_start += m_step) { + for (int n_start = 0; n_start < S_N; n_start += n_step) { + const int current_m = std::min(M - m_start, m_step); + const int current_n = std::min(S_N - n_start, n_step); + + const mllm_fp16_t *a_offset = a_fp16.data() + m_start * K; + const mllm_fp16_t *b_offset = packed_b_ptr + (n_start * (K + 1)); + mllm_fp16_t *c_offset = c_fp16.data() + m_start * S_N + n_start; + + // 由于 a_fp16 和 c_fp16 是连续的,使用标准的行跨距 + fp16_ukernel.run_matmul( + current_m, current_n, K, + a_offset, K * sizeof(mllm_fp16_t), + b_offset, + c_offset, S_N * sizeof(mllm_fp16_t), sizeof(mllm_fp16_t), + -FLT_MAX, FLT_MAX); + } + } + + // 3. 分散(Scatter)和转换: 将连续的 fp16 结果缓冲区复制回非连续的 BSHD float C矩阵 + float *c_bh_ptr = c_ptr + b * stride_c_b; // 指向批次 b 的起始位置 + for (int s = 0; s < S_M; ++s) { + for (int n = 0; n < S_N; ++n) { + // 写入 C[b,s,h,n] + c_bh_ptr[s * stride_c_s + h * S_N + n] = static_cast(c_fp16[s * S_N + n]); + } + } + } + } +} #endif \ No newline at end of file diff --git a/src/backends/cpu/compute/GemmKleidiai.hpp b/src/backends/cpu/compute/GemmKleidiai.hpp index 208545117..dbdf18962 100644 --- a/src/backends/cpu/compute/GemmKleidiai.hpp +++ b/src/backends/cpu/compute/GemmKleidiai.hpp @@ -34,4 +34,8 @@ void mllm_kleidai_gemm_fp32(float *c_ptr, const float *a_ptr, const float *packe void mllm_kleidai_gemm_fp32_transpose(float *c_ptr, const float *a_ptr, const float *b_ptr_nxk, const float *bias_ptr, int M, int N, int K); void mllm_kleidai_gemm_fp16_transpose(float *c_ptr, const float *a_ptr, const mllm_fp16_t *b_ptr_nxk, const float *bias_ptr, int M, int N, int K); +// --- APIs for BSHD layout GEMM --- +void mllm_kleidai_gemm_fp32_bshd(float *c_ptr, const float *a_ptr, const float *packed_b_ptr, int B, int H, int S_M, int S_N, int D_K); +void mllm_kleidai_gemm_fp16_bshd(float *c_ptr, const float *a_ptr, const mllm_fp16_t *packed_b_ptr, int B, int H, int S_M, int S_N, int D_K); + #endif \ No newline at end of file diff --git a/src/backends/cpu/compute/Matmul.cpp b/src/backends/cpu/compute/Matmul.cpp index 5ac470efd..a2f500a10 100644 --- a/src/backends/cpu/compute/Matmul.cpp +++ b/src/backends/cpu/compute/Matmul.cpp @@ -28,73 +28,6 @@ ErrorCode mat_mul(Tensor *src0, Tensor *src1, Tensor *dst, bool support_bias, Te auto src1_dtype = src1->dtype(); auto dst_dtype = dst->dtype(); - // ----------- BEGIN SME Path Check ----------- - /* - #if defined(__ARM_FEATURE_SME) - if (src0->batch() == 1 && src0->head() == 1 && src1->batch() == 1 && src1->head() == 1 && dst->batch() == 1 && dst->head() == 1 && // Ensure dst also expects B=1, H=1 - src1->ctype() == BSHD && dst->ctype() == BSHD && dst_dtype == MLLM_TYPE_F32) { - // Calculate base pointers for b=0, h=0 - // Assuming blck_size is 1 for F32/F16, so division by blck_size is not strictly needed here - // but kept for consistency if it could be > 1 for some packed types. - const void *p_src0_base = (const char *)src0->rawHostPtr() + src0->offset(0, 0, 0, 0) * type_size(src0_dtype) / blck_size(src0_dtype); - const void *p_src1_base = (const char *)src1->rawHostPtr() + src1->offset(0, 0, 0, 0) * type_size(src1_dtype) / blck_size(src1_dtype); - float *p_dst_base = (float *)((char *)dst->rawHostPtr() + dst->offset(0, 0, 0, 0) * type_size(dst_dtype) / blck_size(dst_dtype)); - - // Leading dimensions (number of columns for row-major) - // For A (src0) M x K: lda = K - // For B (src1, which is W) K x N: ldb = N (cols of W) - // For C (dst) M x N: ldc = N - int lda = K; - int ldb = N; // src1 (W) has N columns - int ldc = N; - - bool sme_path_taken = false; - - if (src0_dtype == MLLM_TYPE_F32 && src1_dtype == MLLM_TYPE_F32) { - // Call SME F32 x F32^T -> F32 - sme_gemm_f32f32_f32( - static_cast(p_src0_base), - static_cast(p_src1_base), - p_dst_base, - M, K, N, lda, ldb, ldc); - sme_path_taken = true; - } else if (src0_dtype == MLLM_TYPE_F16 && src1_dtype == MLLM_TYPE_F16) { - #if MLLM_FP16_SUPPORTED // Ensure mllm_fp16_t is usable - // Call SME F16 x F16^T -> F32 - sme_gemm_f16f16_f32( - static_cast(p_src0_base), - static_cast(p_src1_base), - p_dst_base, - M, K, N, lda, ldb, ldc); - sme_path_taken = true; - #else - // std::cerr << "Warning: MLLM_TYPE_F16 SME path requested but mllm_fp16_t support is limited/dummy." << std::endl; - #endif - } - - if (sme_path_taken) { - if (support_bias && bias != nullptr) { - // Bias addition: Iterating through the single batch/head/sequence - // Assuming bias is [1,1,1,N] or compatible and needs to be added to each M row of C. - // The existing bias logic seems to add bias[0,0,0,n] to C[b,h,s,n]. - // For B=1,H=1, this means C[0,0,s,n] += bias[0,0,0,n]. - // This effectively adds the bias vector to each row of the computed C matrix. - // This can be parallelized if M is large. - #pragma omp parallel for num_threads(thread_count) - for (int m_idx = 0; m_idx < M; ++m_idx) { - mllm_add_fp32(dst->ptrAt(0, 0, m_idx, 0), - bias->ptrAt(0, 0, 0, 0), // Assuming bias is [1,1,1,N] - dst->ptrAt(0, 0, m_idx, 0), - N); // N is dst->dimension() in this context if dst is M seq, N dim - } - } - return MLLM_NO_ERROR; - } - } - #endif // __ARM_FEATURE_SME - */ - // ----------- END SME Path Check ----------- - auto vec_dot_type = type_traits[src1_dtype].vec_dot_type; auto vec_dot = type_traits[src1_dtype].vec_dot; auto x_to_vec_dot_type = type_traits[vec_dot_type].from_float; diff --git a/src/backends/cpu/compute/Sigmoid.hpp b/src/backends/cpu/compute/Sigmoid.hpp new file mode 100644 index 000000000..d7a8b7958 --- /dev/null +++ b/src/backends/cpu/compute/Sigmoid.hpp @@ -0,0 +1,69 @@ +#if defined(__ARM_NEON) && defined(__aarch64__) +#include // 包含 NEON 指令集的头文件 +#endif +#if defined(__AVX2__) && defined(__FMA__) +#include // 包含 AVX, SSE 等指令集的头文件 +#endif +#include + +#if defined(__AVX2__) && defined(__FMA__) +// AVX2 版本的快速 exp (示意) +static inline __m256 fast_exp_ps_avx2(__m256 x) { + float temp_in[8], temp_out[8]; + _mm256_storeu_ps(temp_in, x); + for (int i = 0; i < 8; ++i) temp_out[i] = expf(temp_in[i]); + return _mm256_loadu_ps(temp_out); +} +#endif + +#if defined(__ARM_NEON) && defined(__aarch64__) +static inline float32x4_t fast_exp_f32_neon(float32x4_t x) { + float temp_in[4], temp_out[4]; + vst1q_f32(temp_in, x); + for (int i = 0; i < 4; ++i) temp_out[i] = expf(temp_in[i]); + return vld1q_f32(temp_out); +} +#endif + +/** + * @brief 对一个 float 数组进行 Sigmoid 计算 (支持 AVX 和 NEON 的高性能版本) + * @param n 数组中元素的数量 + * @param y 指向输出数组的指针 + * @param x 指向输入数组的指针 + */ +void vec_sigmoid_f32(const int n, float *y, const float *x) { + int i = 0; + +// 1. 优先使用 AVX2 和 FMA 指令集 (x86 架构, 一次处理8个float) +#if defined(__AVX2__) && defined(__FMA__) + const __m256 ones_avx = _mm256_set1_ps(1.0f); + const __m256 zeros_avx = _mm256_setzero_ps(); + + for (; i + 7 < n; i += 8) { + __m256 val = _mm256_loadu_ps(x + i); // 加载数据 + val = _mm256_sub_ps(zeros_avx, val); // 计算 -x + val = fast_exp_ps_avx2(val); // 计算 exp(-x) + val = _mm256_add_ps(ones_avx, val); // 计算 1 + exp(-x) + val = _mm256_div_ps(ones_avx, val); // 计算 1 / (...) + _mm256_storeu_ps(y + i, val); // 存储结果 + } + +// 2. 其次,如果平台是 ARMv8-A (aarch64),则使用 NEON (一次处理4个float) +#elif defined(__ARM_NEON) && defined(__aarch64__) + const float32x4_t ones_neon = vdupq_n_f32(1.0f); + + for (; i + 3 < n; i += 4) { + float32x4_t val = vld1q_f32(x + i); // 加载数据 + val = vnegq_f32(val); // 计算 -x + val = fast_exp_f32_neon(val); // 计算 exp(-x) + val = vaddq_f32(ones_neon, val); // 计算 1 + exp(-x) + val = vdivq_f32(ones_neon, val); // 计算 1 / (...) (vdivq_f32 在 aarch64 中可用) + vst1q_f32(y + i, val); // 存储结果 + } +#endif + + // 3. "收尾"循环:处理剩余的不足一个SIMD块的元素,或在不支持SIMD的平台上运行 + for (; i < n; ++i) { + y[i] = 1.0f / (1.0f + expf(-x[i])); + } +} \ No newline at end of file diff --git a/src/backends/cpu/compute/Transpose2D.hpp b/src/backends/cpu/compute/Transpose2D.hpp index 055066032..eabde519e 100644 --- a/src/backends/cpu/compute/Transpose2D.hpp +++ b/src/backends/cpu/compute/Transpose2D.hpp @@ -17,7 +17,7 @@ * @param dst_stride 目标矩阵的行步长 (即转置前的行数) */ #if defined(__AVX__) || defined(__AVX2__) -static inline void transpose_block_8x8_avx(const float* src, float* dst, const int src_stride, const int dst_stride) { +static inline void transpose_block_8x8_avx(const float *src, float *dst, const int src_stride, const int dst_stride) { // 1. 从源矩阵加载8行数据到8个AVX寄存器 __m256 row0 = _mm256_loadu_ps(src + 0 * src_stride); __m256 row1 = _mm256_loadu_ps(src + 1 * src_stride); @@ -78,7 +78,7 @@ static inline void transpose_block_8x8_avx(const float* src, float* dst, const i * @param dst_stride 目标矩阵的行步长 (即转置前的行数) */ #if defined(__aarch64__) -static inline void transpose_block_4x4_neon(const float* src, float* dst, const int src_stride, const int dst_stride) { +static inline void transpose_block_4x4_neon(const float *src, float *dst, const int src_stride, const int dst_stride) { // 1. 从源矩阵加载4行数据,每行4个float float32x4_t row0 = vld1q_f32(src + 0 * src_stride); float32x4_t row1 = vld1q_f32(src + 1 * src_stride); @@ -117,7 +117,7 @@ static inline void transpose_block_4x4_neon(const float* src, float* dst, const * @param N 源矩阵的行数 * @param M 源矩阵的列数 */ -void transpose_matrix_efficient(const float* src, float* dst, const int N, const int M) { +inline void transpose_matrix_efficient(const float *src, float *dst, const int N, const int M) { #if defined(__AVX__) || defined(__AVX2__) const int BLOCK_DIM = 8; // 使用8x8分块处理大部分矩阵 @@ -143,7 +143,7 @@ void transpose_matrix_efficient(const float* src, float* dst, const int N, const // 使用4x4分块处理大部分矩阵 for (int i = 0; i < N / BLOCK_DIM * BLOCK_DIM; i += BLOCK_DIM) { for (int j = 0; j < M / BLOCK_DIM * BLOCK_DIM; j += BLOCK_DIM) { - transpose_block_4x4_neon(src + i * M + j, dst + j * N + i, M, N); + transpose_block_4x4_neon(src + i * M + j, dst + j * N + i, M, N); } } // 处理剩余部分 @@ -159,11 +159,9 @@ void transpose_matrix_efficient(const float* src, float* dst, const int N, const } #else - // 通用C++回退方案 (无SIMD,但有缓存分块优化) const int BLOCK_DIM = 16; for (int i = 0; i < N; i += BLOCK_DIM) { for (int j = 0; j < M; j += BLOCK_DIM) { - // 转置当前块 for (int bi = i; bi < i + BLOCK_DIM && bi < N; ++bi) { for (int bj = j; bj < j + BLOCK_DIM && bj < M; ++bj) { dst[bj * N + bi] = src[bi * M + bj]; @@ -174,7 +172,6 @@ void transpose_matrix_efficient(const float* src, float* dst, const int N, const #endif } - // --- BEGIN: High-Performance FP16 Transpose Function for ARM NEON --- #if defined(__aarch64__) @@ -187,7 +184,7 @@ void transpose_matrix_efficient(const float* src, float* dst, const int N, const * @param src_stride 源矩阵的行步长 (即列数) * @param dst_stride 目标矩阵的行步长 (即转置前的行数) */ -static inline void transpose_block_8x8_neon_fp16(const __fp16* src, __fp16* dst, const int src_stride, const int dst_stride) { +static inline void transpose_block_8x8_neon_fp16(const __fp16 *src, __fp16 *dst, const int src_stride, const int dst_stride) { // 1. Load 8 rows from source matrix into 8 NEON registers float16x8_t r0 = vld1q_f16(src + 0 * src_stride); float16x8_t r1 = vld1q_f16(src + 1 * src_stride); @@ -230,20 +227,19 @@ static inline void transpose_block_8x8_neon_fp16(const __fp16* src, __fp16* dst, * @param N 源矩阵的行数 * @param M 源矩阵的列数 */ -void transpose_matrix_efficient_fp16(const mllm_fp16_t* src, mllm_fp16_t* dst, const int N, const int M) { +inline void transpose_matrix_efficient_fp16(const mllm_fp16_t *src, mllm_fp16_t *dst, const int N, const int M) { const int BLOCK_DIM = 8; // Use an 8x8 block loop to process the majority of the matrix for (int i = 0; i < N / BLOCK_DIM * BLOCK_DIM; i += BLOCK_DIM) { for (int j = 0; j < M / BLOCK_DIM * BLOCK_DIM; j += BLOCK_DIM) { // On ARM, mllm_fp16_t is __fp16, so we can call the NEON helper directly transpose_block_8x8_neon_fp16( - (const __fp16*)(src + i * M + j), - (__fp16*)(dst + j * N + i), - M, N - ); + (const __fp16 *)(src + i * M + j), + (__fp16 *)(dst + j * N + i), + M, N); } } - + // Process the remaining rows and columns on the edges using standard C++ for (int i = 0; i < N; ++i) { for (int j = M / BLOCK_DIM * BLOCK_DIM; j < M; ++j) { diff --git a/src/backends/cpu/compute/Transpose3D.hpp b/src/backends/cpu/compute/Transpose3D.hpp index 229ba4edd..208dfd051 100644 --- a/src/backends/cpu/compute/Transpose3D.hpp +++ b/src/backends/cpu/compute/Transpose3D.hpp @@ -5,7 +5,7 @@ #include #include #include // 用于 memcpy - +#include "DataType.hpp" // 为不同平台引入对应的 SIMD 指令集头文件 #if defined(__AVX__) || defined(__AVX2__) #include // Intel/AMD AVX & AVX2 指令集 @@ -16,14 +16,6 @@ // 引入 OpenMP 头文件以支持多线程并行 #include -/** - * @brief 定义一个命名空间来组织张量操作相关函数 - */ -// namespace TensorOps { - -// --- BEGIN: 高性能 2D 转置核心 (从 Transpose2D.hpp 集成) --- -// 这部分代码与上一版完全相同,此处为了完整性而保留。 -// SIMD指令集优化代码... #if defined(__AVX__) || defined(__AVX2__) static inline void transpose_block_8x8_avx(const float *src, float *dst, const int src_stride, const int dst_stride) { __m256 row0 = _mm256_loadu_ps(src + 0 * src_stride); @@ -129,10 +121,8 @@ static inline void transpose_matrix_2d_efficient(const float *src, float *dst, c #endif } -// --- END: 高性能 2D 转置核心 --- - /** - * @brief 对一个三维浮点数张量进行高效转置 (终极版: SIMD + OpenMP)。 + * @brief 对一个三维浮点数张量进行高效转置 * 该函数根据指定的维度置换 (permutation) 来重新排列数据。 * * @param src 指向源张量数据的指针。数据布局为 (D1, D2, D3) 的稠密行主序。 @@ -165,8 +155,6 @@ void transpose3d_efficient(const float *src, float *dst, int d1, int d2, int d3, } // --- 3. 性能最优路径:只交换最后两个维度 (e.g., NHW -> NWH) --- - // 【OpenMP + SIMD 加速】 - // OpenMP 将d1个二维切片的转置任务分配给多个线程,每个线程内部使用SIMD指令高速完成自己的任务。 if (perm[0] == 0 && perm[1] == 2 && perm[2] == 1) { const int N = d2; const int M = d3; @@ -180,9 +168,6 @@ void transpose3d_efficient(const float *src, float *dst, int d1, int d2, int d3, } // --- 4. 通用路径:处理所有其他维度置换 --- - // 【OpenMP 加速】 - // OpenMP 将最外层循环并行化,每个线程负责处理目标张量的一个或多个“块板”(slab of blocks)。 - // 内部依然使用缓存分块来优化每个线程的执行效率。 const int dst_dims[3] = {src_dims[perm[0]], src_dims[perm[1]], src_dims[perm[2]]}; const int BLOCK_DIM = 16; @@ -217,4 +202,137 @@ void transpose3d_efficient(const float *src, float *dst, int d1, int d2, int d3, } } -// } // namespace TensorOps \ No newline at end of file +#if defined(__aarch64__) +// NEON 平台使用 8x8 的 __fp16 块转置 +static inline void transpose_block_8x8_neon_fp16(const mllm_fp16_t *src, mllm_fp16_t *dst, const int src_stride, const int dst_stride) { + // 在 aarch64 上, mllm_fp16_t 就是 __fp16 + float16x8_t r0 = vld1q_f16(src + 0 * src_stride); + float16x8_t r1 = vld1q_f16(src + 1 * src_stride); + float16x8_t r2 = vld1q_f16(src + 2 * src_stride); + float16x8_t r3 = vld1q_f16(src + 3 * src_stride); + float16x8_t r4 = vld1q_f16(src + 4 * src_stride); + float16x8_t r5 = vld1q_f16(src + 5 * src_stride); + float16x8_t r6 = vld1q_f16(src + 6 * src_stride); + float16x8_t r7 = vld1q_f16(src + 7 * src_stride); + float16x8x2_t t01 = vtrnq_f16(r0, r1); + float16x8x2_t t23 = vtrnq_f16(r2, r3); + float16x8x2_t t45 = vtrnq_f16(r4, r5); + float16x8x2_t t67 = vtrnq_f16(r6, r7); + float32x4x2_t z02 = vzipq_f32(vreinterpretq_f32_f16(t01.val[0]), vreinterpretq_f32_f16(t23.val[0])); + float32x4x2_t z13 = vzipq_f32(vreinterpretq_f32_f16(t01.val[1]), vreinterpretq_f32_f16(t23.val[1])); + float32x4x2_t z46 = vzipq_f32(vreinterpretq_f32_f16(t45.val[0]), vreinterpretq_f32_f16(t67.val[0])); + float32x4x2_t z57 = vzipq_f32(vreinterpretq_f32_f16(t45.val[1]), vreinterpretq_f32_f16(t67.val[1])); + vst1q_f16(dst + 0 * dst_stride, vreinterpretq_f16_f32(z02.val[0])); + vst1q_f16(dst + 1 * dst_stride, vreinterpretq_f16_f32(z13.val[0])); + vst1q_f16(dst + 2 * dst_stride, vreinterpretq_f16_f32(z02.val[1])); + vst1q_f16(dst + 3 * dst_stride, vreinterpretq_f16_f32(z13.val[1])); + vst1q_f16(dst + 4 * dst_stride, vreinterpretq_f16_f32(z46.val[0])); + vst1q_f16(dst + 5 * dst_stride, vreinterpretq_f16_f32(z57.val[0])); + vst1q_f16(dst + 6 * dst_stride, vreinterpretq_f16_f32(z46.val[1])); + vst1q_f16(dst + 7 * dst_stride, vreinterpretq_f16_f32(z57.val[1])); +} +#endif + +// 高效的2D FP16矩阵转置 +static inline void transpose_matrix_2d_efficient_fp16(const mllm_fp16_t *src, mllm_fp16_t *dst, const int N, const int M) { +#if defined(__aarch64__) + const int BLOCK_DIM = 8; + for (int i = 0; i < N - (N % BLOCK_DIM); i += BLOCK_DIM) { + for (int j = 0; j < M - (M % BLOCK_DIM); j += BLOCK_DIM) { + transpose_block_8x8_neon_fp16(src + i * M + j, dst + j * N + i, M, N); + } + } + // 处理边缘情况 + for (int i = 0; i < N; ++i) { + for (int j = M - (M % BLOCK_DIM); j < M; ++j) { dst[j * N + i] = src[i * M + j]; } + } + for (int i = N - (N % BLOCK_DIM); i < N; ++i) { + for (int j = 0; j < M - (M % BLOCK_DIM); ++j) { dst[j * N + i] = src[i * M + j]; } + } +#else + // 在非NEON平台 (如AVX),使用通用的缓存分块方法 + const int BLOCK_DIM = 16; + for (int i = 0; i < N; i += BLOCK_DIM) { + for (int j = 0; j < M; j += BLOCK_DIM) { + for (int bi = i; bi < i + BLOCK_DIM && bi < N; ++bi) { + for (int bj = j; bj < j + BLOCK_DIM && bj < M; ++bj) { + dst[bj * N + bi] = src[bi * M + bj]; + } + } + } + } +#endif +} + +/** + * @brief 对一个三维 mllm_fp16_t 张量进行高效转置。 + * @param src 指向源张量数据的指针。 + * @param dst 指向目标张量数据的指针。 + * @param d1, d2, d3 源张量的维度。 + * @param perm 维度置换向量, e.g., {0, 2, 1}。 + */ +void transpose3d_efficient_fp16(const mllm_fp16_t *src, mllm_fp16_t *dst, int d1, int d2, int d3, const std::vector &perm) { + // --- 1. 输入验证 --- + if (perm.size() != 3) { throw std::invalid_argument("Permutation vector must contain 3 elements."); } + std::vector sorted_perm = perm; + std::sort(sorted_perm.begin(), sorted_perm.end()); + if (sorted_perm[0] != 0 || sorted_perm[1] != 1 || sorted_perm[2] != 2) { + throw std::invalid_argument("Permutation vector must be a permutation of {0, 1, 2}."); + } + + const int src_dims[3] = {d1, d2, d3}; + + // --- 2. 处理特殊情况:无需转置 --- + if (perm[0] == 0 && perm[1] == 1 && perm[2] == 2) { + const size_t total_elements = static_cast(d1) * d2 * d3; + if (src != dst) { + memcpy(dst, src, total_elements * sizeof(mllm_fp16_t)); + } + return; + } + + // --- 3. 性能最优路径:只交换最后两个维度 (e.g., HSD -> HDS) --- + if (perm[0] == 0 && perm[1] == 2 && perm[2] == 1) { + const int N = d2; + const int M = d3; +#pragma omp parallel for schedule(static) + for (int i = 0; i < d1; ++i) { + const mllm_fp16_t *src_slice = src + i * (N * M); + mllm_fp16_t *dst_slice = dst + i * (M * N); + transpose_matrix_2d_efficient_fp16(src_slice, dst_slice, N, M); + } + return; + } + + // --- 4. 通用路径:处理所有其他维度置换 --- + const int dst_dims[3] = {src_dims[perm[0]], src_dims[perm[1]], src_dims[perm[2]]}; + const int BLOCK_DIM = 16; + long src_strides[3] = {(long)d2 * d3, d3, 1}; + long dst_strides[3] = {(long)dst_dims[1] * dst_dims[2], dst_dims[2], 1}; + int p_inv[3]; + p_inv[perm[0]] = 0; + p_inv[perm[1]] = 1; + p_inv[perm[2]] = 2; + +#pragma omp parallel for schedule(static) + for (int i0 = 0; i0 < dst_dims[0]; i0 += BLOCK_DIM) { + for (int j0 = 0; j0 < dst_dims[1]; j0 += BLOCK_DIM) { + for (int k0 = 0; k0 < dst_dims[2]; k0 += BLOCK_DIM) { + for (int i = i0; i < i0 + BLOCK_DIM && i < dst_dims[0]; ++i) { + for (int j = j0; j < j0 + BLOCK_DIM && j < dst_dims[1]; ++j) { + for (int k = k0; k < k0 + BLOCK_DIM && k < dst_dims[2]; ++k) { + long dst_idx = (long)i * dst_strides[0] + (long)j * dst_strides[1] + k; + int dst_coords[3] = {i, j, k}; + int src_coords[3]; + src_coords[p_inv[0]] = dst_coords[0]; + src_coords[p_inv[1]] = dst_coords[1]; + src_coords[p_inv[2]] = dst_coords[2]; + long src_idx = (long)src_coords[0] * src_strides[0] + (long)src_coords[1] * src_strides[1] + src_coords[2]; + dst[dst_idx] = src[src_idx]; + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/backends/cpu/op/CPUArgSortFunc.hpp b/src/backends/cpu/op/CPUArgSortFunc.hpp index 6ac6e74c2..fbe858ca1 100644 --- a/src/backends/cpu/op/CPUArgSortFunc.hpp +++ b/src/backends/cpu/op/CPUArgSortFunc.hpp @@ -19,7 +19,7 @@ class Tensor; class CPUargsortFunction : public Op { private: int thread_count = 4; - + // 自定义比较函数,用于对索引进行排序 bool compareIndices(const std::pair &a, const std::pair &b) { return a.second < b.second; @@ -39,8 +39,9 @@ class CPUargsortFunction : public Op { } public: - CPUargsortFunction(Backend *bn, string name, int threadCount) - : thread_count(threadCount), Op(bn, name) {} + CPUargsortFunction(Backend *bn, string name, int threadCount) : + thread_count(threadCount), Op(bn, name) { + } ErrorCode reshape(vector> inputs, vector> outputs) override { assert(inputs[0]->sequence() == 1); diff --git a/src/backends/cpu/op/CPUBinaryFunc.hpp b/src/backends/cpu/op/CPUBinaryFunc.hpp index 3c7ec52a7..484a32e72 100644 --- a/src/backends/cpu/op/CPUBinaryFunc.hpp +++ b/src/backends/cpu/op/CPUBinaryFunc.hpp @@ -12,14 +12,13 @@ namespace mllm { class Tensor; - class CPUaddFunction : public Op { private: int thread_count = 4; float data = 0.0f; // The data to be added public: - CPUaddFunction(Backend *bn, string name, float data, int threadCount) - : thread_count(threadCount), Op(bn, name) { + CPUaddFunction(Backend *bn, string name, float data, int threadCount) : + thread_count(threadCount), Op(bn, name) { this->data = data; } ErrorCode reshape(vector> inputs, vector> outputs) override { @@ -55,9 +54,10 @@ class CPUsubFunction : public Op { private: int thread_count = 4; float data = 0.0f; + public: - CPUsubFunction(Backend *bn, string name, float data, int threadCount) - : thread_count(threadCount), Op(bn, name) { + CPUsubFunction(Backend *bn, string name, float data, int threadCount) : + thread_count(threadCount), Op(bn, name) { this->data = data; } ErrorCode reshape(vector> inputs, vector> outputs) override { @@ -93,9 +93,10 @@ class CPUmulFunction : public Op { private: int thread_count = 4; float data = 0.0f; + public: - CPUmulFunction(Backend *bn, string name, float data, int threadCount) - : thread_count(threadCount), Op(bn, name) { + CPUmulFunction(Backend *bn, string name, float data, int threadCount) : + thread_count(threadCount), Op(bn, name) { this->data = data; } ErrorCode reshape(vector> inputs, vector> outputs) override { @@ -131,14 +132,16 @@ class CPUdivFunction : public Op { private: int thread_count = 4; float data = 0.0f; + public: - CPUdivFunction(Backend *bn, string name, float data, int threadCount) - : thread_count(threadCount), Op(bn, name) { + CPUdivFunction(Backend *bn, string name, float data, int threadCount) : + thread_count(threadCount), Op(bn, name) { this->data = data; } ErrorCode reshape(vector> inputs, vector> outputs) override { auto input = inputs[0]; auto output = outputs[0]; + output->setCtype(input->ctype()); output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); output->setDtype(input->dtype()); return ErrorCode::MLLM_NO_ERROR; @@ -169,9 +172,10 @@ class CPUdivintFunction : public Op { private: int thread_count = 4; float data = 0.0f; + public: - CPUdivintFunction(Backend *bn, string name, float data, int threadCount) - : thread_count(threadCount), Op(bn, name) { + CPUdivintFunction(Backend *bn, string name, float data, int threadCount) : + thread_count(threadCount), Op(bn, name) { this->data = data; } ErrorCode reshape(vector> inputs, vector> outputs) override { @@ -208,9 +212,11 @@ class CPUdivintFunctionCreator : public CPUBackend::Creator { class CPUaddTwoFunction : public Op { private: int thread_count = 4; + public: - CPUaddTwoFunction(Backend *bn, string name, int threadCount) - : thread_count(threadCount), Op(bn, name) {} + CPUaddTwoFunction(Backend *bn, string name, int threadCount) : + thread_count(threadCount), Op(bn, name) { + } ErrorCode reshape(vector> inputs, vector> outputs) override { outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); @@ -227,8 +233,9 @@ class CPUaddTwoFunction : public Op { #pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) for (int c = 0; c < input0->head(); ++c) { for (int h = 0; h < input0->sequence(); ++h) { + auto s_1 = std::min(h, input1->sequence() - 1); mllm_add_fp32(input0->ptrAt(n_0, c, h, 0), - input1->ptrAt(n_1, c, h, 0), + input1->ptrAt(n_1, c, s_1, 0), outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); } } @@ -246,9 +253,11 @@ class CPUaddTwoFunctionCreator : public CPUBackend::Creator { class CPUsubTwoFunction : public Op { private: int thread_count = 4; + public: - CPUsubTwoFunction(Backend *bn, string name, int threadCount) - : thread_count(threadCount), Op(bn, name) {} + CPUsubTwoFunction(Backend *bn, string name, int threadCount) : + thread_count(threadCount), Op(bn, name) { + } ErrorCode reshape(vector> inputs, vector> outputs) override { outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); @@ -284,9 +293,11 @@ class CPUsubTwoFunctionCreator : public CPUBackend::Creator { class CPUmulTwoFunction : public Op { private: int thread_count = 4; + public: - CPUmulTwoFunction(Backend *bn, string name, int threadCount) - : thread_count(threadCount), Op(bn, name) {} + CPUmulTwoFunction(Backend *bn, string name, int threadCount) : + thread_count(threadCount), Op(bn, name) { + } ErrorCode reshape(vector> inputs, vector> outputs) override { outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); @@ -334,9 +345,11 @@ class CPUmulTwoFunctionCreator : public CPUBackend::Creator { class CPUdivTwoFunction : public Op { private: int thread_count = 4; + public: - CPUdivTwoFunction(Backend *bn, string name, int threadCount) - : thread_count(threadCount), Op(bn, name) {} + CPUdivTwoFunction(Backend *bn, string name, int threadCount) : + thread_count(threadCount), Op(bn, name) { + } ErrorCode reshape(vector> inputs, vector> outputs) override { outputs[0]->reshape(std::max(inputs[0]->batch(), inputs[1]->batch()), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); diff --git a/src/backends/cpu/op/CPUExpandFunc.hpp b/src/backends/cpu/op/CPUExpandFunc.hpp index a4221b024..7877e12f6 100644 --- a/src/backends/cpu/op/CPUExpandFunc.hpp +++ b/src/backends/cpu/op/CPUExpandFunc.hpp @@ -8,6 +8,7 @@ #include "Tensor.hpp" #include "Types.hpp" #include "CPUBackend.hpp" +#include #include namespace mllm { @@ -19,8 +20,9 @@ class CPUexpandFunction : public Op { int b_, h_, s_, d_; public: - CPUexpandFunction(Backend *bn, string name, int threadCount, int b, int h, int s, int d) - : Op(bn, name), thread_count(threadCount), b_(b), h_(h), s_(s), d_(d) {} + CPUexpandFunction(Backend *bn, string name, int threadCount, int b, int h, int s, int d) : + Op(bn, name), thread_count(threadCount), b_(b), h_(h), s_(s), d_(d) { + } ErrorCode reshape(vector> inputs, vector> outputs) override { // The original assert seems to imply only one dimension can be expanded at a time. @@ -81,7 +83,14 @@ class CPUexpandFunction : public Op { } } } else if (d_ != -1) { - std::cerr << "expand for DIMENSION not support" << std::endl; + for (int b = 0; b < dim_b; ++b) { + for (int s = 0; s < dim_s; ++s) { + for (int h = 0; h < dim_h; ++h) { + float data = inputs[0]->dataAt(b, h, s, 0); + std::fill_n(outputs[0]->ptrAt(b, h, s, 0), outputs[0]->dimension(), data); + } + } + } } return ErrorCode::MLLM_NO_ERROR; } @@ -91,10 +100,10 @@ class CPUexpandFunctionCreator : public CPUBackend::Creator { public: virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { // Assumes OpParam contains keys "b", "h", "s", "d" - int b = static_cast(op_param.at("b")) ; - int h = static_cast(op_param.at("h")) ; - int s = static_cast(op_param.at("s")) ; - int d = static_cast(op_param.at("d")) ; + int b = static_cast(op_param.at("b")); + int h = static_cast(op_param.at("h")); + int s = static_cast(op_param.at("s")); + int d = static_cast(op_param.at("d")); return new CPUexpandFunction(bn, name, threadCount, b, h, s, d); } }; diff --git a/src/backends/cpu/op/CPUGather.cpp b/src/backends/cpu/op/CPUGather.cpp index c00a5933f..eebbe2e3d 100644 --- a/src/backends/cpu/op/CPUGather.cpp +++ b/src/backends/cpu/op/CPUGather.cpp @@ -9,18 +9,18 @@ CPUGather::CPUGather(Backend *bn, string opName, int threadCount) : } ErrorCode CPUGather::reshape(vector> inputs, vector> outputs) { - assert(inputs.size() == 3); + // assert(inputs.size() == 3); assert(outputs.size() == 1); - if (inputs[1]->batch() == 0) { - outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), inputs[0]->dimension()); - return Op::reshape(inputs, outputs); - } + // if (inputs[1]->batch() == 0) { + // outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), inputs[0]->dimension()); + // return Op::reshape(inputs, outputs); + // } assert(inputs[0]->batch() == inputs[1]->batch()); assert(inputs[0]->head() == inputs[1]->head()); assert(inputs[0]->head() == 1); - assert(inputs[0]->dimension() == inputs[1]->dimension()); - assert(inputs[2]->dimension() == 1); - outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), inputs[0]->dimension()); + // assert(inputs[0]->dimension() == inputs[1]->dimension()); + // assert(inputs[1]->dimension() == 1); + outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), inputs[1]->dimension()); return Op::reshape(inputs, outputs); } @@ -32,27 +32,28 @@ ErrorCode CPUGather::execute(vector> inputs, vectorctype() == BSHD); assert(inputs[1]->ctype() == BSHD); assert(outputs[0]->ctype() == BSHD); - auto input_indices = inputs[2]; + auto input_indices = inputs[1]; int hiddenSize = inputs[0]->dimension(); +#pragma omp parallel for collapse(3) num_threads(CPUBackend::cpu_threads) for (int batch = 0; batch < inputs[0]->batch(); ++batch) { for (int seq = 0; seq < inputs[0]->sequence(); ++seq) { - if (input_indices->dataAt(batch, 0, seq, 0) >= 0) { - memcpy(outputs[0]->hostPtr() + outputs[0]->offset(batch, 0, seq, 0), - inputs[1]->hostPtr() + (int)inputs[1]->offset(batch, 0, input_indices->dataAt(batch, 0, seq, 0), 0), - inputs[1]->dtypeSize() * hiddenSize); + for (int indices = 0; indices < input_indices->dimension(); ++indices) { + int dim_index = input_indices->dataAt(batch, 0, seq, indices); + float value = inputs[0]->dataAt(batch, 0, seq, dim_index); + outputs[0]->setDataAt(batch, 0, seq, indices, value); } } } return Op::execute(inputs, outputs); } -ErrorCode CPUGather::setUp(vector> inputs, vector> outputs) { - if (inputs[0]->masterTensor() == nullptr) { - inputs[0]->free(); - } - outputs[0]->setDtype(activation_dtype()); - outputs[0]->alloc(); - inputs[0]->shallowCopyFrom(outputs[0], false); - return MLLM_NO_ERROR; -} +// ErrorCode CPUGather::setUp(vector> inputs, vector> outputs) { +// if (inputs[0]->masterTensor() == nullptr) { +// inputs[0]->free(); +// } +// outputs[0]->setDtype(activation_dtype()); +// outputs[0]->alloc(); +// inputs[0]->shallowCopyFrom(outputs[0], false); +// return MLLM_NO_ERROR; +// } } // namespace mllm diff --git a/src/backends/cpu/op/CPUGather.hpp b/src/backends/cpu/op/CPUGather.hpp index cee464f68..d902203ee 100644 --- a/src/backends/cpu/op/CPUGather.hpp +++ b/src/backends/cpu/op/CPUGather.hpp @@ -13,7 +13,7 @@ class CPUGather final : public Op { virtual ~CPUGather() = default; virtual ErrorCode reshape(vector> inputs, vector> outputs) override; virtual ErrorCode execute(vector> inputs, vector> outputs) override; - virtual ErrorCode setUp(vector> inputs, vector> outputs) override; + // virtual ErrorCode setUp(vector> inputs, vector> outputs) override; private: int thread_count = 4; diff --git a/src/backends/cpu/op/CPUKVCache.cpp b/src/backends/cpu/op/CPUKVCache.cpp index 8d469b555..fb0d1a1f1 100644 --- a/src/backends/cpu/op/CPUKVCache.cpp +++ b/src/backends/cpu/op/CPUKVCache.cpp @@ -10,7 +10,11 @@ CPUKVCache::CPUKVCache(Backend *bn, string opName, int hidden, int head, int n_r thread_count(threadCount), Op(bn, opName) { cache_ = std::make_shared(1, head * n_rep, cache_max, hidden, bn, false); fa2_ = fa2; - switch (KVCache_TYPE) { + auto KVdtype = KVCache_TYPE; + if (!fa2) { + KVdtype = KVCache_Type_eager; + } + switch (KVdtype) { case 16: { cache_->setDtype(MLLM_TYPE_F16); break; @@ -204,6 +208,36 @@ ErrorCode CPUKVCache::execute(vector> inputs, } } } + } else if (cache_->ctype() == BHSD) { + for (int b = 0; b < cache_->batch(); ++b) { + for (int h = inputs[0]->head() - 1; h >= 0; --h) { +#pragma omp parallel for collapse(2) num_threads(thread_count) + for (int seq = cache_seq_len_old; seq < cache_seq_len_; ++seq) { + for (int i_rep = 0; i_rep < n_rep_; ++i_rep) { + auto cache_head = h * n_rep_ + i_rep; + if (cache_->dtype() == MLLM_TYPE_F32) { + auto src_ptr = + inputs[0]->ptrAt(b, h, seq - cache_seq_len_old, 0); + auto dest_ptr = cache_->ptrAt(b, cache_head, seq, 0); + int copy_size = cache_->dimension(); + memcpy(dest_ptr, src_ptr, copy_size * sizeof(float)); + } else if (cache_->dtype() == MLLM_TYPE_F16) { + auto src_ptr = + inputs[0]->ptrAt(b, h, seq - cache_seq_len_old, 0); + auto dest_ptr = cache_->ptrAt(b, cache_head, seq, 0); + int copy_size = cache_->dimension(); + memcpy(dest_ptr, src_ptr, copy_size * sizeof(mllm_fp16_t)); + } else if (cache_->dtype() == MLLM_TYPE_Q8_0) { + auto src_ptr = + (char *)inputs[0]->rawHostPtr() + inputs[0]->offset(b, h, seq - cache_seq_len_old, 0) * sizeof(block_q8_0) / QK8_0; + auto dest_ptr = (char *)cache_->rawHostPtr() + cache_->offset(b, cache_head, seq, 0) * sizeof(block_q8_0) / QK8_0; + int copy_size = cache_->dimension(); + memcpy(dest_ptr, src_ptr, copy_size * sizeof(block_q8_0) / QK8_0); + } + } + } + } + } } else { std::cout << "ERROR Ctype in KVCcache;" << std::endl; } diff --git a/src/backends/cpu/op/CPUMaskedFill.hpp b/src/backends/cpu/op/CPUMaskedFill.hpp new file mode 100644 index 000000000..febd27406 --- /dev/null +++ b/src/backends/cpu/op/CPUMaskedFill.hpp @@ -0,0 +1,70 @@ +// +// Created by Rongjie Yi on 24-12-16. +// + +#ifndef CPUMaskedFill_HPP +#define CPUMaskedFill_HPP + +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include +// #include +// #include +#include + +namespace mllm { +class Tensor; + +class CPUMaskedFill : public Op { +private: + int thread_count = 4; + float value_; + +public: + CPUMaskedFill(Backend *bn, float value, string name, int threadCount) : + Op(bn, name), value_(value), thread_count(threadCount) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + // assert(outputs.size() == 2); // topk returns values and indices + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); // topk_values + + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + // std::cout << inputs[0]->name() << " " << inputs[1]->name() << std::endl; + memcpy(outputs[0]->hostPtr(), inputs[0]->hostPtr(), inputs[0]->cntSize()); +#pragma omp parallel for collapse(4) num_threads(CPUBackend::cpu_threads) + for (int n = 0; n < inputs[0]->batch(); n++) { + for (int h = 0; h < inputs[0]->head(); h++) { + for (int s = 0; s < inputs[0]->sequence(); s++) { + for (int d = 0; d < inputs[0]->dimension(); ++d) { + float mask_flag = inputs[1]->dataAt(n, h, s, d); + if ((int)mask_flag == 1) { + outputs[0]->setDataAt(n, h, s, d, value_); // MaskedFill operation: negation + } + } + } + } + } + // NOTE: Add cases for other dimensions if needed. + return MLLM_NO_ERROR; + } +}; + +class CPUMaskedFillCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + float value = op_param["value"]; + return new CPUMaskedFill(bn, value, name, threadCount); + } +}; + +} // namespace mllm +#endif // CPUMaskedFill_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUMatmulFunc.hpp b/src/backends/cpu/op/CPUMatmulFunc.hpp index 09b4ddd45..6f00cf0b3 100644 --- a/src/backends/cpu/op/CPUMatmulFunc.hpp +++ b/src/backends/cpu/op/CPUMatmulFunc.hpp @@ -6,6 +6,7 @@ #define CPUMATMULFUNC_HPP #include "CPUBackend.hpp" +#include "DataType.hpp" #include "Tensor.hpp" #include "Types.hpp" #include "../compute/Matmul.hpp" @@ -13,6 +14,8 @@ #include #include #include // For std::equal +#include "../compute/GemmKleidiai.hpp" +#include "../compute/GemmFp.hpp" namespace mllm { class Tensor; @@ -40,9 +43,13 @@ class CPUmmFunction : public Op { // [FIX] Correctly handle the master tensor and its children if (auto master = input.masterTensor()) { // master is now a shared_ptr + auto batch = master->batch(); + auto head = master->head(); + auto dimension = master->dimension(); + auto sequence = master->sequence(); master->chls() = input.chls(); master->changeCtype(); - master->reshape(master->batch(), master->head(), master->sequence(), master->dimension()); + master->reshape(batch, head, sequence, dimension); // Loop through the master's children for (auto &child_wp : master->childTensors()) { @@ -82,7 +89,10 @@ class CPUmmFunction : public Op { } ErrorCode setUp(vector> inputs, vector> outputs) override { - if (inputs[1]->chls()[SEQUENCE] != 3) { + if (inputs[0]->ctype() == BHSD) { + assert(inputs[0]->ctype() == inputs[1]->ctype()); + outputs[0]->setCtype(BHSD); + } else if (inputs[1]->chls()[SEQUENCE] != 3) { tranTensorChl(*inputs[1]); } if (!inputs[1]->shape().empty() && !inputs[0]->shape().empty()) { @@ -93,10 +103,14 @@ class CPUmmFunction : public Op { } ErrorCode reshape(vector> inputs, vector> outputs) override { - if (inputs[1]->chls()[SEQUENCE] != 3) { + if (inputs[0]->ctype() != BHSD && inputs[1]->chls()[SEQUENCE] != 3) { tranTensorChl(*inputs[1]); assert(inputs[1]->chls()[SEQUENCE] == 3); } + if (inputs[0]->ctype() == BHSD) { + assert(inputs[0]->ctype() == inputs[1]->ctype()); + outputs[0]->setCtype(BHSD); + } assert(inputs[0]->dimension() == inputs[1]->sequence()); outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[1]->dimension()); outputs[0]->setDtype(inputs[0]->dtype()); @@ -106,6 +120,60 @@ class CPUmmFunction : public Op { } ErrorCode execute(vector> inputs, vector> outputs) override { + if (inputs[0]->ctype() == BHSD) { +#ifdef ARM + auto M = inputs[0]->sequence(); + auto N = inputs[1]->dimension(); + auto K = inputs[0]->dimension(); + size_t packed_b_size = mllm_kleidai_get_packed_b_fp32_size(N, K); + for (int b = 0; b < inputs[0]->batch(); b++) { + for (int h = 0; h < inputs[0]->head(); h++) { + if (inputs[1]->dtype() == MLLM_TYPE_F32) { + std::vector packed_b_data(packed_b_size); + mllm_kleidai_pack_b_and_bias_fp32(packed_b_data.data(), + inputs[1]->ptrAt(b, h, 0, 0), + nullptr, N, K); // Pass nullptr for bias + mllm_kleidai_gemm_fp32(outputs[0]->ptrAt(b, h, 0, 0), + inputs[0]->ptrAt(b, h, 0, 0), + packed_b_data.data(), + M, N, K); + } else { // inputs[1]->dtype() == MLLM_TYPE_F16 + std::vector packed_b_data(packed_b_size); + mllm_kleidai_pack_b_and_bias_fp16(packed_b_data.data(), + inputs[1]->ptrAt(b, h, 0, 0), + nullptr, N, K); // Pass nullptr for bias + mllm_kleidai_gemm_fp16(outputs[0]->ptrAt(b, h, 0, 0), + inputs[0]->ptrAt(b, h, 0, 0), + packed_b_data.data(), + M, N, K); + } + } + } + return MLLM_NO_ERROR; +#else + auto M = inputs[0]->sequence(); + auto N = inputs[1]->dimension(); + auto K = inputs[0]->dimension(); + memset(outputs[0]->hostPtr(), 0, outputs[0]->cntSize()); + for (int b = 0; b < inputs[0]->batch(); b++) { + for (int h = 0; h < inputs[0]->head(); h++) { + if (inputs[1]->dtype() == MLLM_TYPE_F32) { + gemm_fp32(outputs[0]->ptrAt(b, h, 0, 0), + inputs[0]->ptrAt(b, h, 0, 0), + inputs[1]->ptrAt(b, h, 0, 0), + M, N, K); + + } else { // inputs[1]->dtype() == MLLM_TYPE_F16 + gemm_fp32_fp16(outputs[0]->ptrAt(b, h, 0, 0), + inputs[0]->ptrAt(b, h, 0, 0), + inputs[1]->ptrAt(b, h, 0, 0), + M, N, K); + } + } + } + return MLLM_NO_ERROR; +#endif + } bool isSame = std::equal(inputs[0]->chls().begin(), inputs[0]->chls().end(), inputs[1]->chls().begin()); assert(inputs[0]->dtype() == MLLM_TYPE_F32); mat_mul(inputs[0].get(), inputs[1].get(), outputs[0].get(), false, nullptr, false, isSame, thread_count); diff --git a/src/backends/cpu/op/CPUParameter.cpp b/src/backends/cpu/op/CPUParameter.cpp index debd5a2fb..5ec2b4c9e 100644 --- a/src/backends/cpu/op/CPUParameter.cpp +++ b/src/backends/cpu/op/CPUParameter.cpp @@ -40,8 +40,6 @@ ErrorCode CPUParameter::load(AbstructLoader &loader) { } ErrorCode CPUParameter::execute(vector> inputs, vector> outputs) { - // outputs[0] = std::make_shared(weight_); - if (outputs[0]->masterTensor()->name() != weight_->name()) { if (outputs[0]->masterTensor() == nullptr) { // outputs[0]->copyFrom(weight_); diff --git a/src/backends/cpu/op/CPUScatter.hpp b/src/backends/cpu/op/CPUScatter.hpp new file mode 100644 index 000000000..c95d2f18f --- /dev/null +++ b/src/backends/cpu/op/CPUScatter.hpp @@ -0,0 +1,85 @@ +// +// Created by Rongjie Yi on 24-12-26. +// + +#ifndef CPUSCATTE_HPP +#define CPUSCATTE_HPP + +#include "Tensor.hpp" +#include "Types.hpp" +#include "CPUBackend.hpp" +#include +#include +#include + +namespace mllm { +class Tensor; + +class CPUScatter : public Op { +private: + int thread_count = 4; + Chl dim_; // default dimension is SEQUENCE + float value_ = 0.0f; // default value is 0.0f + +public: + CPUScatter(Backend *bn, string name, Chl dim, float value, int threadCount) : + Op(bn, name), dim_(dim), value_(value), thread_count(threadCount) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { + if (inputs[1]->batch() == 0) { + return MLLM_NO_ERROR; + } + assert(inputs.size() == 2); + assert(inputs[0]->batch() == 1); + auto dest_input = inputs[0]; + auto replace_idx = inputs[1]; + if (dim_ == SEQUENCE) { + assert(inputs[0]->head() == 1); + assert(replace_idx->batch() == 1); + assert(replace_idx->sequence() == 1); + assert(replace_idx->head() == 1); + assert(dest_input->head() == 1); + // Todo check + // #pragma omp parallel for num_threads(CPUBackend::cpu_threads) + for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { + auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); + auto dst_ptr = dest_input->ptrAt(0, 0, replace_seq, 0); + memset(dst_ptr, value_, sizeof(float) * dest_input->dimension()); + } + } else if (dim_ == HEAD) { + assert(replace_idx->sequence() == dest_input->sequence()); + for (int tok = 0; tok < replace_idx->sequence(); tok++) { + for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { + auto replace_seq = (int)replace_idx->dataAt(0, 0, tok, r_idx); + auto dst_ptr = dest_input->ptrAt(0, replace_seq, tok, 0); + dest_input->setDataAt(0, replace_seq, tok, 0, value_); + } + }; + } else { + std::cerr << "Error: CPUScatter only supports SEQUENCE dimension currently." << std::endl; + return NOT_SUPPORT; + } + return MLLM_NO_ERROR; + } +}; + +class CPUScatterCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + Chl dim = SEQUENCE; + auto it = op_param.find("dim"); + if (it != op_param.end()) { + dim = static_cast(it->second); + } + float value = static_cast(op_param["value"]); + return new CPUScatter(bn, name, dim, value, threadCount); + } +}; + +} // namespace mllm +#endif // CPUSCATTE_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUScatterAddFunc.hpp b/src/backends/cpu/op/CPUScatterAddFunc.hpp index 8cf188b76..4dd7e3c7b 100644 --- a/src/backends/cpu/op/CPUScatterAddFunc.hpp +++ b/src/backends/cpu/op/CPUScatterAddFunc.hpp @@ -9,6 +9,7 @@ #include "Types.hpp" #include "CPUBackend.hpp" #include "../compute/Arithmetic.hpp" +#include #include namespace mllm { @@ -17,10 +18,11 @@ class Tensor; class CPUScatterAddFunction : public Op { private: int thread_count = 4; + Chl dim_ = SEQUENCE; // default dimension is SEQUENCE public: - CPUScatterAddFunction(Backend *bn, string name, int threadCount) : - Op(bn, name), thread_count(threadCount) { + CPUScatterAddFunction(Backend *bn, string name, Chl dim, int threadCount) : + Op(bn, name), dim_(dim), thread_count(threadCount) { } ErrorCode reshape(vector> inputs, vector> outputs) override { @@ -40,17 +42,22 @@ class CPUScatterAddFunction : public Op { assert(replace_idx->batch() == 1); assert(replace_idx->sequence() == 1); assert(replace_idx->head() == 1); - // #pragma omp parallel for num_threads(CPUBackend::cpu_threads) - for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { - auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); - auto dst_ptr = dest_input->ptrAt(0, 0, replace_seq, 0); - auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); - // memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); - float tmp[src_input->dimension()]; - memcpy(tmp, dst_ptr, sizeof(float) * dest_input->dimension()); - mllm_add_fp32(tmp, - src_ptr, - dst_ptr, dest_input->dimension()); + if (dim_ == SEQUENCE) { + // #pragma omp parallel for num_threads(CPUBackend::cpu_threads) + for (int r_idx = 0; r_idx < replace_idx->dimension(); r_idx++) { + auto replace_seq = (int)replace_idx->dataAt(0, 0, 0, r_idx); + auto dst_ptr = dest_input->ptrAt(0, 0, replace_seq, 0); + auto src_ptr = src_input->ptrAt(0, 0, r_idx, 0); + // memcpy(dst_ptr, src_ptr, sizeof(float) * src_input->dimension()); + float tmp[src_input->dimension()]; + memcpy(tmp, dst_ptr, sizeof(float) * dest_input->dimension()); + mllm_add_fp32(tmp, + src_ptr, + dst_ptr, dest_input->dimension()); + } + } else { + std::cerr << "Error: CPUScatterAddFunction only supports SEQUENCE dimension currently." << std::endl; + return NOT_SUPPORT; } return MLLM_NO_ERROR; } @@ -59,7 +66,12 @@ class CPUScatterAddFunction : public Op { class CPUScatterAddFunctionCreator : public CPUBackend::Creator { public: virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { - return new CPUScatterAddFunction(bn, name, threadCount); + Chl dim = SEQUENCE; + auto it = op_param.find("dim"); + if (it != op_param.end()) { + dim = static_cast(it->second); + } + return new CPUScatterAddFunction(bn, name, dim, threadCount); } }; diff --git a/src/backends/cpu/op/CPUSigmoid.cpp b/src/backends/cpu/op/CPUSigmoid.cpp new file mode 100644 index 000000000..4bab0908e --- /dev/null +++ b/src/backends/cpu/op/CPUSigmoid.cpp @@ -0,0 +1,46 @@ +#include "CPUSigmoid.hpp" +// #include +#include "Tensor.hpp" +#include "../compute/Sigmoid.hpp" + +namespace mllm { + +// static void vec_sigmoid_f32(const int n, float *y, const float *x) { +// for (int i = 0; i < n; ++i) { +// y[i] = 1.0f / (1.0f + expf(-x[i])); +// } +// } + +CPUSigmoid::CPUSigmoid(Backend *bn, string opName, int threadCount) : + thread_count(threadCount), + Op(bn, opName) { + // 构造函数中没有特殊操作 +} + +ErrorCode CPUSigmoid::reshape(vector> inputs, vector> outputs) { + // Sigmoid 是按元素操作的,所以输出张量的形状与输入张量完全相同 + assert(inputs.size() == 1); + assert(outputs.size() == 1); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + return Op::reshape(inputs, outputs); +} + +ErrorCode CPUSigmoid::execute(vector> inputs, vector> outputs) { + auto &input = inputs[0]; + auto &output = outputs[0]; + +#pragma omp parallel for collapse(3) num_threads(thread_count) + for (int n = 0; n < input->batch(); ++n) { + for (int h = 0; h < input->head(); ++h) { + for (int s = 0; s < input->sequence(); ++s) { + const float *in_ptr = input->ptrAt(n, h, s, 0); + float *out_ptr = output->ptrAt(n, h, s, 0); + vec_sigmoid_f32(input->dimension(), out_ptr, in_ptr); + } + } + } + + return Op::execute(inputs, outputs); +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/cpu/op/CPUSigmoid.hpp b/src/backends/cpu/op/CPUSigmoid.hpp new file mode 100644 index 000000000..d12211bcd --- /dev/null +++ b/src/backends/cpu/op/CPUSigmoid.hpp @@ -0,0 +1,28 @@ +#ifndef MLLM_CPUSIGMOID_H +#define MLLM_CPUSIGMOID_H + +#include "Op.hpp" +#include "../CPUBackend.hpp" + +namespace mllm { + +class CPUSigmoid final : public Op { +public: + CPUSigmoid(Backend *bn, string opName, int threadCount); + virtual ~CPUSigmoid() = default; + virtual ErrorCode reshape(vector> inputs, vector> outputs) override; + virtual ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + int thread_count = 4; +}; + +class CPUSigmoidCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const { + return new CPUSigmoid(bn, name, threadCount); + } +}; +} // namespace mllm + +#endif // MLLM_CPUSIGMOID_H \ No newline at end of file diff --git a/src/backends/cpu/op/CPUTilde.hpp b/src/backends/cpu/op/CPUTilde.hpp new file mode 100644 index 000000000..edb934ece --- /dev/null +++ b/src/backends/cpu/op/CPUTilde.hpp @@ -0,0 +1,65 @@ +// +// Created by Rongjie Yi on 24-12-16. +// + +#ifndef CPUTILDE_HPP +#define CPUTILDE_HPP + +#include "CPUBackend.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include +// #include +// #include +#include + +namespace mllm { +class Tensor; + +class CPUTilde : public Op { +private: + int thread_count = 4; + +public: + CPUTilde(Backend *bn, string name, int threadCount) : + Op(bn, name), thread_count(threadCount) { + } + + ErrorCode reshape(vector> inputs, vector> outputs) override { + // assert(outputs.size() == 2); // topk returns values and indices + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); // topk_values + + // 遵从原始 reshape 逻辑,在这里 alloc + // outputs[0]->alloc(); + + return MLLM_NO_ERROR; + } + + ErrorCode execute(vector> inputs, vector> outputs) override { +#pragma omp parallel for collapse(4) num_threads(CPUBackend::cpu_threads) + for (int n = 0; n < inputs[0]->batch(); n++) { + for (int h = 0; h < inputs[0]->head(); h++) { + for (int s = 0; s < inputs[0]->sequence(); s++) { + for (int d = 0; d < inputs[0]->dimension(); ++d) { + float value = inputs[0]->dataAt(n, h, s, d); + assert(((int)value == 1 || (int)value == 0) && "Tilde operation expects input to be 1.0"); + float set_data = ((int)value == 1) ? 0.0F : 1.0F; // Tilde operation: negation + outputs[0]->setDataAt(n, h, s, d, set_data); // Tilde operation: negation + } + } + } + } + return MLLM_NO_ERROR; + } +}; + +class CPUTildeCreator : public CPUBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new CPUTilde(bn, name, threadCount); + } +}; + +} // namespace mllm +#endif // CPUTILDE_HPP \ No newline at end of file diff --git a/src/backends/cpu/op/CPUTopkFunc.hpp b/src/backends/cpu/op/CPUTopkFunc.hpp index f3193e4f3..2c028bd2a 100644 --- a/src/backends/cpu/op/CPUTopkFunc.hpp +++ b/src/backends/cpu/op/CPUTopkFunc.hpp @@ -32,6 +32,10 @@ class CPUtopkFunction : public Op { if (dim_ == DIMENSION) { outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), k_); outputs[1]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), k_); + } else if (dim_ == HEAD) { + assert(inputs[0]->dimension() == 1 && "Only support topk on last dimension currently."); + outputs[0]->reshape(inputs[0]->batch(), k_, inputs[0]->sequence(), 1); // topk values + outputs[1]->reshape(inputs[0]->batch(), k_, inputs[0]->sequence(), 1); // topk values } // NOTE: Add cases for other dimensions if needed. @@ -68,6 +72,25 @@ class CPUtopkFunction : public Op { } } } + } else if (dim_ == HEAD) { + for (int n = 0; n < inputs[0]->batch(); n++) { + for (int s = 0; s < inputs[0]->sequence(); s++) { + std::priority_queue, std::vector>, std::greater<>> topk_value_indices; + for (int h = 0; h < inputs[0]->head(); h++) { + float value = inputs[0]->dataAt(n, h, s, 0); + topk_value_indices.push({value, h}); + if (topk_value_indices.size() > k_) { + topk_value_indices.pop(); + } + } + for (int h = k_ - 1; h >= 0; --h) { + auto top = topk_value_indices.top(); + topk_value_indices.pop(); + outputs[0]->setDataAt(n, h, s, 0, top.first); + outputs[1]->setDataAt(n, h, s, 0, top.second); + } + } + } } // NOTE: Add cases for other dimensions if needed. return MLLM_NO_ERROR; diff --git a/src/backends/cpu/op/CPUTransposeFunc.hpp b/src/backends/cpu/op/CPUTransposeFunc.hpp index aad13458a..1031cfd5e 100644 --- a/src/backends/cpu/op/CPUTransposeFunc.hpp +++ b/src/backends/cpu/op/CPUTransposeFunc.hpp @@ -9,6 +9,7 @@ #include "Types.hpp" // #include "Module.hpp" #include "CPUBackend.hpp" +#include "compute/Transpose2D.hpp" #include "backends/cpu/third_party/ggml/Quantize.hpp" #include // #include @@ -35,12 +36,17 @@ class CPUtransposeFunction : public Op { if (axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { if (inputs[0]->ctype() == BSHD) { outputs[0]->chls() = {{BATCH, 0}, {HEAD, 1}, {SEQUENCE, 2}, {DIMENSION, 3}}; - } else { + } else { // inputs[0]->ctype() == BHSD outputs[0]->chls() = {{BATCH, 0}, {SEQUENCE, 1}, {HEAD, 2}, {DIMENSION, 3}}; } outputs[0]->changeCtype(4); outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); return MLLM_NO_ERROR; + } else if (axiss_.size() == 1 && axiss_[0].first == SEQUENCE && axiss_[0].second == DIMENSION && inputs[0]->ctype() == BHSD) { + outputs[0]->setCtype(BHSD); + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->dimension(), inputs[0]->sequence()); + return MLLM_NO_ERROR; } // for BSHD attention end @@ -87,6 +93,12 @@ class CPUtransposeFunction : public Op { outputs[0]->chls() = inputs[0]->chls(); std::swap(outputs[0]->chls()[HEAD], outputs[0]->chls()[SEQUENCE]); outputs[0]->changeCtype(inputs[0]->shape().size()); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + return MLLM_NO_ERROR; + } else if (axiss_.size() == 1 && axiss_[0].first == SEQUENCE && axiss_[0].second == DIMENSION && inputs[0]->ctype() == BHSD) { + outputs[0]->setCtype(BHSD); + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->dimension(), inputs[0]->sequence()); return MLLM_NO_ERROR; } // for BSHD attention end @@ -123,37 +135,60 @@ class CPUtransposeFunction : public Op { outputs[0]->alloc(); } // BSHD -> BHSD (transpose S and H) - if (true) { // 真转置 - assert(inputs[0]->batch() == 1); - assert(outputs[0]->batch() == 1); - // After reshape, H and S dimensions are swapped in the output tensor's shape - assert(inputs[0]->head() == outputs[0]->sequence()); - assert(inputs[0]->sequence() == outputs[0]->head()); - - if (inputs[0]->dtype() == outputs[0]->dtype()) { + // 真转置 + assert(inputs[0]->batch() == 1); + assert(outputs[0]->batch() == 1); + assert(inputs[0]->head() == outputs[0]->head()); + assert(inputs[0]->sequence() == outputs[0]->sequence()); + if (inputs[0]->dtype() == outputs[0]->dtype()) { #pragma omp parallel for num_threads(thread_count) - for (int h = 0; h < inputs[0]->head(); ++h) { - for (int s = 0; s < inputs[0]->sequence(); ++s) { - auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); - // Swap h and s for output access - auto output_ptr = outputs[0]->ptrAt(0, s, h, 0); - memcpy(output_ptr, input_ptr, inputs[0]->dimension() * inputs[0]->dtypeSize()); - } + for (int h = 0; h < inputs[0]->head(); ++h) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); + auto output_ptr = outputs[0]->ptrAt(0, h, s, 0); + memcpy(output_ptr, input_ptr, inputs[0]->dimension() * sizeof(float)); } - } else { // With quantization + } + } else { // With quantization #pragma omp parallel for num_threads(thread_count) - for (int h = 0; h < inputs[0]->head(); ++h) { - for (int s = 0; s < inputs[0]->sequence(); ++s) { - auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); - // Swap h and s for output access - auto output_ptr = outputs[0]->ptrAt(0, s, h, 0); - for (int d = 0; d < inputs[0]->dimension(); ++d) { - output_ptr[d] = MLLM_FP32_TO_FP16(input_ptr[d]); - } + for (int h = 0; h < inputs[0]->head(); ++h) { + for (int s = 0; s < inputs[0]->sequence(); ++s) { + // auto input_ptr = inputs[0]->ptrAt(0, h, s, 0); + // auto output_ptr = outputs[0]->ptrAt(0, h, s, 0); + for (int d = 0; d < inputs[0]->dimension(); ++d) { + // output_ptr[d] = MLLM_FP32_TO_FP16(input_ptr[d]); + auto value = inputs[0]->dataAt(0, h, s, d); + outputs[0]->setDataAt(0, h, s, d, MLLM_FP32_TO_FP16(value)); } } } } + + } else if (axiss_.size() == 1 && axiss_[0].first == SEQUENCE && axiss_[0].second == DIMENSION && inputs[0]->ctype() == BHSD) { + assert(outputs[0]->ctype() == BHSD); + // 真转置 + assert(inputs[0]->batch() == 1); + assert(outputs[0]->batch() == 1); + assert(inputs[0]->sequence() == outputs[0]->dimension()); + assert(outputs[0]->sequence() == inputs[0]->dimension()); + // BHSD->BHDS + const int N = inputs[0]->sequence(); + const int M = inputs[0]->dimension(); + if (inputs[0]->dtype() == MLLM_TYPE_F32) { +#pragma omp parallel for num_threads(thread_count) + for (int h = 0; h < inputs[0]->head(); ++h) { + const float *src_ptr = inputs[0]->ptrAt(0, h, 0, 0); + float *dst_ptr = outputs[0]->ptrAt(0, h, 0, 0); + transpose_matrix_efficient(src_ptr, dst_ptr, N, M); + } + } else { +#pragma omp parallel for num_threads(thread_count) + for (int h = 0; h < inputs[0]->head(); ++h) { + const mllm_fp16_t *src_ptr = inputs[0]->ptrAt(0, h, 0, 0); + mllm_fp16_t *dst_ptr = outputs[0]->ptrAt(0, h, 0, 0); + transpose_matrix_efficient_fp16(src_ptr, dst_ptr, N, M); + } + } } // for BSHD attention end // Note: The general transpose case is handled by metadata changes in reshape/setUp diff --git a/src/backends/cpu/op/CPUViewFunc.hpp b/src/backends/cpu/op/CPUViewFunc.hpp index 254e77698..7414b4e75 100644 --- a/src/backends/cpu/op/CPUViewFunc.hpp +++ b/src/backends/cpu/op/CPUViewFunc.hpp @@ -8,6 +8,8 @@ #include "Tensor.hpp" #include "Types.hpp" #include "CPUBackend.hpp" +#include +#include #include #include #include @@ -41,7 +43,8 @@ class CPUviewFunction : public Op { outputs[0]->alloc(); inputs[0]->shallowCopyFrom(outputs[0], false); } else { - std::cout << "[TODO]Tensor.View alloc not support!!!!" << std::endl; + std::cout << "[TODO]Tensor.View [" << b << ", " << s << ", " << h << ", " << d << "] alloc not support!!!!" << std::endl; + exit(-2); } return MLLM_NO_ERROR; } @@ -81,7 +84,8 @@ class CPUviewFunction : public Op { dim_h = inputs[0]->dimension() * inputs[0]->head() / d; dim_d = d; } else { - std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + std::cout << "[TODO]Tensor.View [" << b << ", " << s << ", " << h << ", " << d << "] alloc not support!!!!" << std::endl; + exit(-2); } } else if (b == -1 && h != -1 && s != -1 && d == -1) { // head & sequence if (h != ANYDIM && s != ANYDIM) { @@ -95,7 +99,8 @@ class CPUviewFunction : public Op { dim_h = inputs[0]->sequence() * inputs[0]->head() / s; dim_s = s; } else { - std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + std::cout << "[TODO]Tensor.View [" << b << ", " << s << ", " << h << ", " << d << "] not support!!!!" << std::endl; + exit(-2); } } else if (b != -1 && h == -1 && s != -1 && d == -1) { // batch & sequence if (b != ANYDIM && s != ANYDIM) { @@ -109,10 +114,12 @@ class CPUviewFunction : public Op { dim_b = inputs[0]->sequence() * inputs[0]->batch() / s; dim_s = s; } else { - std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + std::cout << "[TODO]Tensor.View [" << b << ", " << s << ", " << h << ", " << d << "] not support!!!!" << std::endl; + exit(-2); } } else { - std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + std::cout << "[TODO]Tensor.View [" << b << ", " << s << ", " << h << ", " << d << "] not support!!!!" << std::endl; + exit(-2); } if (inputs[0]->ctype() == BCTHW && inputs[0]->name() == outputs[0]->name()) { outputs[0]->setCtype(BSHD); @@ -127,6 +134,9 @@ class CPUviewFunction : public Op { ErrorCode execute(vector> inputs, vector> outputs) override { // View is a metadata-only operation, no data movement is needed in execute. + if (inputs[0]->hostPtr() != outputs[0]->hostPtr()) { + memcpy(outputs[0]->hostPtr(), inputs[0]->hostPtr(), inputs[0]->cntSize()); + } return MLLM_NO_ERROR; } }; diff --git a/src/backends/opencl/CMakeLists.txt b/src/backends/opencl/CMakeLists.txt index 94f668bf2..759e51331 100644 --- a/src/backends/opencl/CMakeLists.txt +++ b/src/backends/opencl/CMakeLists.txt @@ -1,14 +1,6 @@ -# 查找 OpenCL 库 -find_package(OpenCL REQUIRED) -if(OpenCL_FOUND) - message(STATUS "Found OpenCL library: ${OpenCL_LIBRARIES}") - message(STATUS "Found OpenCL include directory: ${OpenCL_INCLUDE_DIRS}") -else() - message(FATAL_ERROR "OpenCL library not found.") -endif() - -# 包含 OpenCL 头文件目录 -include_directories(${OpenCL_INCLUDE_DIRS}) +# ====================================================================== +# 最终修正版 - 匹配您当前的目录结构 +# ====================================================================== # 收集所有 OpenCL 源文件 file(GLOB OPENCL_SRC @@ -16,16 +8,27 @@ file(GLOB OPENCL_SRC ${CMAKE_CURRENT_LIST_DIR}/op/*.cpp ) -# 定义 OpenCL 后端库 -add_library(mllm_opencl STATIC - ${OPENCL_SRC} -) +# 定义 OpenCL 后端静态库 +add_library(mllm_opencl STATIC ${OPENCL_SRC}) -# 链接 OpenCL 库 -target_link_libraries(mllm_opencl PRIVATE OpenCL::OpenCL) -# 将 mllm_opencl 库的头文件目录设为 public -# 这样其他目标链接到 mllm_opencl 时就能自动找到头文件 +if(ANDROID) + # --- 安卓平台的逻辑 --- + # 在安卓上,我们在 C++ 代码中通过 dlopen 动态加载 libOpenCL.so。 + # 因此,在编译时不应该链接 -lOpenCL。 + # 我们唯一需要的链接依赖是 dl 库,用于 dlopen/dlsym。 + # 这个依赖已经在 examples/CMakeLists.txt 中的 ${CMAKE_DL_LIBS} 变量里处理了。 + # 所以,这里什么都不用做。 + message(STATUS "OpenCL backend for Android: dynamic loading enabled, skipping link-time dependency on OpenCL.") + +else() + # --- 非安卓平台的逻辑 (macOS, Linux) --- + find_package(OpenCL REQUIRED) + target_include_directories(mllm_opencl PUBLIC ${OpenCL_INCLUDE_DIRS}) + target_link_libraries(mllm_opencl PUBLIC OpenCL::OpenCL) +endif() + +# 将 mllm_opencl 库自身的头文件目录设为 public target_include_directories(mllm_opencl PUBLIC ${CMAKE_CURRENT_LIST_DIR} ) \ No newline at end of file diff --git a/src/backends/opencl/OpenCLBackend.cpp b/src/backends/opencl/OpenCLBackend.cpp index b3fed31c3..a39831142 100644 --- a/src/backends/opencl/OpenCLBackend.cpp +++ b/src/backends/opencl/OpenCLBackend.cpp @@ -2,16 +2,54 @@ #include #include #include -#include "Tensor.hpp" +#include +#if defined(MLLM_TARGET_ANDROID) +#include +#include // for dirname +#endif +#include // C++17, for directory creation +#include // for std::error_code -#include "./op/OpenCLAddFuncOp.hpp" +#include "Tensor.hpp" +#include "Backend.hpp" +#include "OpDefined.hpp" +#include "Types.hpp" +#include "Module.hpp" #include "utils/OpenCLTools.hpp" +#include "op/OpenCLAddOp.hpp" +#include "op/OpenCLAddTwoOp.hpp" +#include "op/OpenCLSubOp.hpp" +#include "op/OpenCLSubTwoOp.hpp" +#include "op/OpenCLMulOp.hpp" +#include "op/OpenCLMulTwoOp.hpp" +#include "op/OpenCLDivOp.hpp" +#include "op/OpenCLDivIntOp.hpp" +#include "op/OpenCLDivTwoOp.hpp" +#include "op/OpenCLMatmulOp.hpp" +#include "op/OpenCLLinearOp.hpp" +#include "op/OpenCLTransposeOp.hpp" +#include "op/OpenCLSoftMaxOp.hpp" +#include "op/OpenCLRMSNormOp.hpp" +#include "op/OpenCLEmbeddingOp.hpp" +#include "op/OpenCLSiLUOp.hpp" +#include "op/OpenCLViewOp.hpp" +#include "op/OpenCLKVCacheOp.hpp" +#include "op/OpenCLRoPEOp.hpp" +#include "op/OpenCLClipOp.hpp" +#include "op/OpenCLFlashAttentionOp.hpp" +#include "op/OpenCLSplitOp.hpp" +#include "op/OpenCLTopkOp.hpp" +#include "op/OpenCLSumOp.hpp" +#include "op/OpenCLLikeOp.hpp" +#include "op/OpenCLClipTensorOp.hpp" +#include "op/OpenCLScatterAddOp.hpp" +#include "op/OpenCLArgSortOp.hpp" +#include "op/OpenCLBinCountOp.hpp" // 错误检查函数 void check_cl_error(cl_int err, const std::string &operation) { if (err != CL_SUCCESS) { std::cerr << "OpenCL Error during " << operation << " (" << err << ")" << std::endl; - // 应该调度到cpu throw std::runtime_error("OpenCL Error: " + operation); } } @@ -25,123 +63,486 @@ std::string load_file_contents(const char *filename) { throw std::runtime_error(std::string("Could not open file: ") + filename); } +#if defined(MLLM_TARGET_ANDROID) +std::string get_executable_dir() { + char path_buf[1024] = {0}; + // 读取 /proc/self/exe 符号链接,获取可执行文件的完整路径 + ssize_t len = readlink("/proc/self/exe", path_buf, sizeof(path_buf) - 1); + if (len != -1) { + path_buf[len] = '\0'; + // 使用 dirname 获取路径的目录部分 + return std::string(dirname(path_buf)); + } + // 如果失败,返回一个默认的相对路径作为后备 + return "."; +} +#endif + namespace mllm { -// 静态辅助函数,用于在构造函数初始化列表中创建 MemoryManager -// 这样可以确保在调用基类构造函数之前,context 和 device 已经被正确初始化 +#if defined(MLLM_TARGET_ANDROID) +// 【关键修正】将 OpenCLSymbols 的完整定义放回到 .cpp 文件中 +struct OpenCLSymbols { + typedef cl_int (*clGetPlatformIDs_f_t)(cl_uint, cl_platform_id *, cl_uint *); + typedef cl_int (*clGetDeviceIDs_f_t)(cl_platform_id, cl_device_type, cl_uint, cl_device_id *, cl_uint *); + typedef cl_int (*clGetDeviceInfo_f_t)(cl_device_id, cl_device_info, size_t, void *, size_t *); + typedef cl_context (*clCreateContext_f_t)(const cl_context_properties *, cl_uint, const cl_device_id *, void(CL_CALLBACK *)(const char *, const void *, size_t, void *), void *, cl_int *); + typedef cl_command_queue (*clCreateCommandQueue_f_t)(cl_context, cl_device_id, cl_command_queue_properties, cl_int *); + typedef cl_int (*clReleaseCommandQueue_f_t)(cl_command_queue); + typedef cl_int (*clReleaseContext_f_t)(cl_context); + typedef cl_program (*clCreateProgramWithSource_f_t)(cl_context, cl_uint, const char **, const size_t *, cl_int *); + typedef cl_int (*clBuildProgram_f_t)(cl_program, cl_uint, const cl_device_id *, const char *, void(CL_CALLBACK *)(cl_program, void *), void *); + typedef cl_int (*clGetProgramBuildInfo_f_t)(cl_program, cl_device_id, cl_program_build_info, size_t, void *, size_t *); + typedef cl_program (*clCreateProgramWithBinary_f_t)(cl_context, cl_uint, const cl_device_id *, const size_t *, const unsigned char **, cl_int *, cl_int *); + typedef cl_int (*clGetProgramInfo_f_t)(cl_program, cl_program_info, size_t, void *, size_t *); + typedef cl_int (*clReleaseProgram_f_t)(cl_program); + typedef cl_kernel (*clCreateKernel_f_t)(cl_program, const char *, cl_int *); + typedef cl_int (*clReleaseKernel_f_t)(cl_kernel); + typedef cl_int (*clSetKernelArg_f_t)(cl_kernel, cl_uint, size_t, const void *); + typedef cl_int (*clEnqueueNDRangeKernel_f_t)(cl_command_queue, cl_kernel, cl_uint, const size_t *, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *); + typedef cl_mem (*clCreateBuffer_f_t)(cl_context, cl_mem_flags, size_t, void *, cl_int *); + typedef cl_int (*clReleaseMemObject_f_t)(cl_mem); + typedef cl_int (*clEnqueueWriteBuffer_f_t)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clEnqueueReadBuffer_f_t)(cl_command_queue, cl_mem, cl_bool, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clFinish_f_t)(cl_command_queue); + typedef cl_sampler (*clCreateSampler_f_t)(cl_context, cl_bool, cl_addressing_mode, cl_filter_mode, cl_int *); + typedef cl_int (*clReleaseSampler_f_t)(cl_sampler); + typedef cl_mem (*clCreateImage_f_t)(cl_context, cl_mem_flags, const cl_image_format *, const cl_image_desc *, void *, cl_int *); + typedef cl_int (*clEnqueueWriteImage_f_t)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clEnqueueReadImage_f_t)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clEnqueueWriteBufferRect_f_t)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, const size_t *, size_t, size_t, size_t, size_t, const void *, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clEnqueueReadBufferRect_f_t)(cl_command_queue, cl_mem, cl_bool, const size_t *, const size_t *, const size_t *, size_t, size_t, size_t, size_t, void *, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clReleaseDevice_f_t)(cl_device_id); + typedef cl_int (*clRetainDevice_f_t)(cl_device_id); + typedef cl_command_queue (*clCreateCommandQueueWithProperties_f_t)(cl_context, cl_device_id, const cl_queue_properties *, cl_int *); + typedef cl_int (*clRetainCommandQueue_f_t)(cl_command_queue); + typedef void *(*clSVMAlloc_f_t)(cl_context, cl_svm_mem_flags, size_t, cl_uint); + typedef void (*clSVMFree_f_t)(cl_context, void *); + typedef cl_int (*clEnqueueSVMMap_f_t)(cl_command_queue, cl_bool, cl_map_flags, void *, size_t, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clEnqueueSVMUnmap_f_t)(cl_command_queue, void *, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clSetKernelArgSVMPointer_f_t)(cl_kernel, cl_uint, const void *); + typedef cl_mem (*clCreateSubBuffer_f_t)(cl_mem, cl_mem_flags, cl_buffer_create_type, const void *, cl_int *); + typedef cl_int (*clEnqueueCopyBuffer_f_t)(cl_command_queue, cl_mem, cl_mem, size_t, size_t, size_t, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clEnqueueCopyBufferToImage_f_t)(cl_command_queue, cl_mem, cl_mem, size_t, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clEnqueueCopyBufferRect_f_t)(cl_command_queue, cl_mem, cl_mem, const size_t *, const size_t *, const size_t *, size_t, size_t, size_t, size_t, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clWaitForEvents_f_t)(cl_uint, const cl_event *); + typedef cl_int (*clGetEventProfilingInfo_f_t)(cl_event, cl_profiling_info, size_t, void *, size_t *); + typedef cl_int (*clReleaseEvent_f_t)(cl_event); + typedef cl_int (*clEnqueueCopyImageToBuffer_f_t)(cl_command_queue, cl_mem, cl_mem, const size_t *, const size_t *, size_t, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clEnqueueCopyImage_f_t)(cl_command_queue, cl_mem, cl_mem, const size_t *, const size_t *, const size_t *, cl_uint, const cl_event *, cl_event *); + typedef cl_int (*clGetMemObjectInfo_f_t)(cl_mem, cl_mem_info, size_t, void *, size_t *); + typedef cl_int (*clEnqueueFillBuffer_f_t)(cl_command_queue, cl_mem, const void *, size_t, size_t, size_t, cl_uint, const cl_event *, cl_event *); + typedef void *(*clEnqueueMapBuffer_f_t)(cl_command_queue, cl_mem, cl_bool, cl_map_flags, size_t, size_t, cl_uint, const cl_event *, cl_event *, cl_int *); + typedef cl_int (*clEnqueueUnmapMemObject_f_t)(cl_command_queue, cl_mem, void *, cl_uint, const cl_event *, cl_event *); + + clGetPlatformIDs_f_t clGetPlatformIDs = nullptr; + clGetDeviceIDs_f_t clGetDeviceIDs = nullptr; + clGetDeviceInfo_f_t clGetDeviceInfo = nullptr; + clCreateContext_f_t clCreateContext = nullptr; + clCreateCommandQueue_f_t clCreateCommandQueue = nullptr; + clReleaseCommandQueue_f_t clReleaseCommandQueue = nullptr; + clReleaseContext_f_t clReleaseContext = nullptr; + clCreateProgramWithSource_f_t clCreateProgramWithSource = nullptr; + clBuildProgram_f_t clBuildProgram = nullptr; + clGetProgramBuildInfo_f_t clGetProgramBuildInfo = nullptr; + clCreateProgramWithBinary_f_t clCreateProgramWithBinary = nullptr; + clGetProgramInfo_f_t clGetProgramInfo = nullptr; + clReleaseProgram_f_t clReleaseProgram = nullptr; + clCreateKernel_f_t clCreateKernel = nullptr; + clReleaseKernel_f_t clReleaseKernel = nullptr; + clSetKernelArg_f_t clSetKernelArg = nullptr; + clEnqueueNDRangeKernel_f_t clEnqueueNDRangeKernel = nullptr; + clCreateBuffer_f_t clCreateBuffer = nullptr; + clReleaseMemObject_f_t clReleaseMemObject = nullptr; + clEnqueueWriteBuffer_f_t clEnqueueWriteBuffer = nullptr; + clEnqueueReadBuffer_f_t clEnqueueReadBuffer = nullptr; + clFinish_f_t clFinish = nullptr; + clCreateSampler_f_t clCreateSampler = nullptr; + clReleaseSampler_f_t clReleaseSampler = nullptr; + clCreateImage_f_t clCreateImage = nullptr; + clEnqueueWriteImage_f_t clEnqueueWriteImage = nullptr; + clEnqueueReadImage_f_t clEnqueueReadImage = nullptr; + clEnqueueWriteBufferRect_f_t clEnqueueWriteBufferRect = nullptr; + clEnqueueReadBufferRect_f_t clEnqueueReadBufferRect = nullptr; + clReleaseDevice_f_t clReleaseDevice = nullptr; + clRetainDevice_f_t clRetainDevice = nullptr; + clCreateCommandQueueWithProperties_f_t clCreateCommandQueueWithProperties = nullptr; + clRetainCommandQueue_f_t clRetainCommandQueue = nullptr; + clSVMAlloc_f_t clSVMAlloc = nullptr; + clSVMFree_f_t clSVMFree = nullptr; + clEnqueueSVMMap_f_t clEnqueueSVMMap = nullptr; + clEnqueueSVMUnmap_f_t clEnqueueSVMUnmap = nullptr; + clSetKernelArgSVMPointer_f_t clSetKernelArgSVMPointer = nullptr; + clCreateSubBuffer_f_t clCreateSubBuffer = nullptr; + clEnqueueCopyBuffer_f_t clEnqueueCopyBuffer = nullptr; + clEnqueueCopyBufferToImage_f_t clEnqueueCopyBufferToImage = nullptr; + clEnqueueCopyBufferRect_f_t clEnqueueCopyBufferRect = nullptr; + clWaitForEvents_f_t clWaitForEvents = nullptr; + clGetEventProfilingInfo_f_t clGetEventProfilingInfo = nullptr; + clReleaseEvent_f_t clReleaseEvent = nullptr; + clEnqueueCopyImageToBuffer_f_t clEnqueueCopyImageToBuffer = nullptr; + clEnqueueCopyImage_f_t clEnqueueCopyImage = nullptr; + clGetMemObjectInfo_f_t clGetMemObjectInfo = nullptr; + clEnqueueFillBuffer_f_t clEnqueueFillBuffer = nullptr; + clEnqueueMapBuffer_f_t clEnqueueMapBuffer = nullptr; + clEnqueueUnmapMemObject_f_t clEnqueueUnmapMemObject = nullptr; + + void *handle = nullptr; +}; + +OpenCLSymbols OpenCLBackend::symbols_; +static std::once_flag opencl_symbols_load_flag; + +// 实现 getSymbols 辅助函数 +OpenCLSymbols *OpenCLBackend::getSymbols() { + return &symbols_; +} + +// extern "C" 包装函数 +extern "C" { +cl_int CL_API_CALL clGetPlatformIDs(cl_uint num_entries, cl_platform_id *platforms, cl_uint *num_platforms) { + auto func = mllm::OpenCLBackend::getSymbols()->clGetPlatformIDs; + return func(num_entries, platforms, num_platforms); +} +cl_int CL_API_CALL clGetDeviceIDs(cl_platform_id platform, cl_device_type device_type, cl_uint num_entries, cl_device_id *devices, cl_uint *num_devices) { + auto func = mllm::OpenCLBackend::getSymbols()->clGetDeviceIDs; + return func(platform, device_type, num_entries, devices, num_devices); +} +cl_int CL_API_CALL clGetDeviceInfo(cl_device_id device, cl_device_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clGetDeviceInfo; + return func(device, param_name, param_value_size, param_value, param_value_size_ret); +} +cl_context CL_API_CALL clCreateContext(const cl_context_properties *properties, cl_uint num_devices, const cl_device_id *devices, void(CL_CALLBACK *pfn_notify)(const char *, const void *, size_t, void *), void *user_data, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateContext; + return func(properties, num_devices, devices, pfn_notify, user_data, errcode_ret); +} +cl_command_queue CL_API_CALL clCreateCommandQueue(cl_context context, cl_device_id device, cl_command_queue_properties properties, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateCommandQueue; + return func(context, device, properties, errcode_ret); +} +cl_int CL_API_CALL clReleaseCommandQueue(cl_command_queue command_queue) { + auto func = mllm::OpenCLBackend::getSymbols()->clReleaseCommandQueue; + return func(command_queue); +} +cl_int CL_API_CALL clReleaseContext(cl_context context) { + auto func = mllm::OpenCLBackend::getSymbols()->clReleaseContext; + return func(context); +} +cl_program CL_API_CALL clCreateProgramWithSource(cl_context context, cl_uint count, const char **strings, const size_t *lengths, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateProgramWithSource; + return func(context, count, strings, lengths, errcode_ret); +} +cl_int CL_API_CALL clBuildProgram(cl_program program, cl_uint num_devices, const cl_device_id *device_list, const char *options, void(CL_CALLBACK *pfn_notify)(cl_program, void *), void *user_data) { + auto func = mllm::OpenCLBackend::getSymbols()->clBuildProgram; + return func(program, num_devices, device_list, options, pfn_notify, user_data); +} +cl_int CL_API_CALL clGetProgramBuildInfo(cl_program program, cl_device_id device, cl_program_build_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clGetProgramBuildInfo; + return func(program, device, param_name, param_value_size, param_value, param_value_size_ret); +} +cl_int CL_API_CALL clReleaseProgram(cl_program program) { + auto func = mllm::OpenCLBackend::getSymbols()->clReleaseProgram; + return func(program); +} +cl_kernel CL_API_CALL clCreateKernel(cl_program program, const char *kernel_name, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateKernel; + return func(program, kernel_name, errcode_ret); +} +cl_int CL_API_CALL clReleaseKernel(cl_kernel kernel) { + auto func = mllm::OpenCLBackend::getSymbols()->clReleaseKernel; + return func(kernel); +} +cl_int CL_API_CALL clSetKernelArg(cl_kernel kernel, cl_uint arg_index, size_t arg_size, const void *arg_value) { + auto func = mllm::OpenCLBackend::getSymbols()->clSetKernelArg; + return func(kernel, arg_index, arg_size, arg_value); +} +cl_int CL_API_CALL clEnqueueNDRangeKernel(cl_command_queue command_queue, cl_kernel kernel, cl_uint work_dim, const size_t *global_work_offset, const size_t *global_work_size, const size_t *local_work_size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueNDRangeKernel; + return func(command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, event_wait_list, event); +} +cl_mem CL_API_CALL clCreateBuffer(cl_context context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateBuffer; + return func(context, flags, size, host_ptr, errcode_ret); +} +cl_int CL_API_CALL clReleaseMemObject(cl_mem memobj) { + auto func = mllm::OpenCLBackend::getSymbols()->clReleaseMemObject; + return func(memobj); +} +cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, size_t offset, size_t size, const void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueWriteBuffer; + return func(command_queue, buffer, blocking_write, offset, size, ptr, num_events_in_wait_list, event_wait_list, event); +} +cl_int CL_API_CALL clEnqueueReadBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, size_t offset, size_t size, void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueReadBuffer; + return func(command_queue, buffer, blocking_read, offset, size, ptr, num_events_in_wait_list, event_wait_list, event); +} +cl_int CL_API_CALL clFinish(cl_command_queue command_queue) { + auto func = mllm::OpenCLBackend::getSymbols()->clFinish; + return func(command_queue); +} +cl_sampler CL_API_CALL clCreateSampler(cl_context context, cl_bool normalized_coords, cl_addressing_mode addressing_mode, cl_filter_mode filter_mode, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateSampler; + return func(context, normalized_coords, addressing_mode, filter_mode, errcode_ret); +} +cl_int CL_API_CALL clReleaseSampler(cl_sampler sampler) { + auto func = mllm::OpenCLBackend::getSymbols()->clReleaseSampler; + return func(sampler); +} +cl_mem CL_API_CALL clCreateImage(cl_context context, cl_mem_flags flags, const cl_image_format *image_format, const cl_image_desc *image_desc, void *host_ptr, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateImage; + return func(context, flags, image_format, image_desc, host_ptr, errcode_ret); +} +cl_int CL_API_CALL clEnqueueWriteImage(cl_command_queue command_queue, cl_mem image, cl_bool blocking_write, const size_t *origin, const size_t *region, size_t input_row_pitch, size_t input_slice_pitch, const void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueWriteImage; + return func(command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event); +} +cl_int CL_API_CALL clEnqueueReadImage(cl_command_queue command_queue, cl_mem image, cl_bool blocking_read, const size_t *origin, const size_t *region, size_t row_pitch, size_t slice_pitch, void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueReadImage; + return func(command_queue, image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event); +} +cl_int CL_API_CALL clEnqueueWriteBufferRect(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, const size_t *buffer_origin, const size_t *host_origin, const size_t *region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, const void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueWriteBufferRect; + return func(command_queue, buffer, blocking_write, buffer_origin, host_origin, region, buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event); +} +cl_int CL_API_CALL clEnqueueReadBufferRect(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, const size_t *buffer_origin, const size_t *host_origin, const size_t *region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueReadBufferRect; + return func(command_queue, buffer, blocking_read, buffer_origin, host_origin, region, buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event); +} +cl_int CL_API_CALL clReleaseDevice(cl_device_id device) { + auto func = mllm::OpenCLBackend::getSymbols()->clReleaseDevice; + return func(device); +} +cl_int CL_API_CALL clRetainDevice(cl_device_id device) { + auto func = mllm::OpenCLBackend::getSymbols()->clRetainDevice; + return func(device); +} +cl_command_queue CL_API_CALL clCreateCommandQueueWithProperties(cl_context context, cl_device_id device, const cl_queue_properties *properties, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateCommandQueueWithProperties; + return func(context, device, properties, errcode_ret); +} +cl_int CL_API_CALL clRetainCommandQueue(cl_command_queue command_queue) { + auto func = mllm::OpenCLBackend::getSymbols()->clRetainCommandQueue; + return func(command_queue); +} +void *CL_API_CALL clSVMAlloc(cl_context context, cl_svm_mem_flags flags, size_t size, cl_uint alignment) { + auto func = mllm::OpenCLBackend::getSymbols()->clSVMAlloc; + return func(context, flags, size, alignment); +} +void CL_API_CALL clSVMFree(cl_context context, void *svm_pointer) { + auto func = mllm::OpenCLBackend::getSymbols()->clSVMFree; + func(context, svm_pointer); +} +cl_int CL_API_CALL clEnqueueSVMMap(cl_command_queue command_queue, cl_bool blocking_map, cl_map_flags map_flags, void *svm_ptr, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueSVMMap; + return func(command_queue, blocking_map, map_flags, svm_ptr, size, num_events_in_wait_list, event_wait_list, event); +} +cl_int CL_API_CALL clEnqueueSVMUnmap(cl_command_queue command_queue, void *svm_ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueSVMUnmap; + return func(command_queue, svm_ptr, num_events_in_wait_list, event_wait_list, event); +} +cl_int CL_API_CALL clSetKernelArgSVMPointer(cl_kernel kernel, cl_uint arg_index, const void *arg_value) { + auto func = mllm::OpenCLBackend::getSymbols()->clSetKernelArgSVMPointer; + return func(kernel, arg_index, arg_value); +} +cl_mem CL_API_CALL clCreateSubBuffer(cl_mem mem, cl_mem_flags flags, cl_buffer_create_type type, const void *b_info, cl_int *err) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateSubBuffer; + return func(mem, flags, type, b_info, err); +} +cl_int CL_API_CALL clEnqueueCopyBuffer(cl_command_queue q, cl_mem s, cl_mem d, size_t s_o, size_t d_o, size_t si, cl_uint e_l, const cl_event *e, cl_event *ev) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueCopyBuffer; + return func(q, s, d, s_o, d_o, si, e_l, e, ev); +} +cl_int CL_API_CALL clEnqueueCopyBufferToImage(cl_command_queue q, cl_mem s, cl_mem d, size_t s_o, const size_t *d_o, const size_t *r, cl_uint el, const cl_event *e, cl_event *ev) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueCopyBufferToImage; + return func(q, s, d, s_o, d_o, r, el, e, ev); +} +cl_int CL_API_CALL clEnqueueCopyBufferRect(cl_command_queue q, cl_mem s_b, cl_mem d_b, const size_t *s_o, const size_t *d_o, const size_t *r, size_t s_r_p, size_t s_s_p, size_t d_r_p, size_t d_s_p, cl_uint el, const cl_event *e, cl_event *ev) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueCopyBufferRect; + return func(q, s_b, d_b, s_o, d_o, r, s_r_p, s_s_p, d_r_p, d_s_p, el, e, ev); +} +cl_int CL_API_CALL clWaitForEvents(cl_uint num_events, const cl_event *event_list) { + auto func = mllm::OpenCLBackend::getSymbols()->clWaitForEvents; + return func(num_events, event_list); +} + +cl_int CL_API_CALL clGetEventProfilingInfo(cl_event event, cl_profiling_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clGetEventProfilingInfo; + return func(event, param_name, param_value_size, param_value, param_value_size_ret); +} + +cl_int CL_API_CALL clReleaseEvent(cl_event event) { + auto func = mllm::OpenCLBackend::getSymbols()->clReleaseEvent; + return func(event); +} + +// 添加下面的两个新函数 +cl_int CL_API_CALL clEnqueueCopyImageToBuffer(cl_command_queue q, cl_mem s_img, cl_mem d_buf, const size_t *s_o, const size_t *r, size_t d_o, cl_uint el, const cl_event *e, cl_event *ev) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueCopyImageToBuffer; + if (func) { + return func(q, s_img, d_buf, s_o, r, d_o, el, e, ev); + } + return CL_INVALID_OPERATION; // Or another appropriate error +} + +cl_int CL_API_CALL clEnqueueCopyImage(cl_command_queue q, cl_mem s_img, cl_mem d_img, const size_t *s_o, const size_t *d_o, const size_t *r, cl_uint el, const cl_event *e, cl_event *ev) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueCopyImage; + if (func) { + return func(q, s_img, d_img, s_o, d_o, r, el, e, ev); + } + return CL_INVALID_OPERATION; // Or another appropriate error +} +cl_int CL_API_CALL clGetMemObjectInfo(cl_mem memobj, cl_mem_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clGetMemObjectInfo; + if (func) { + return func(memobj, param_name, param_value_size, param_value, param_value_size_ret); + } + return CL_INVALID_OPERATION; // 或者返回其他合适的错误码 +} +cl_program CL_API_CALL clCreateProgramWithBinary(cl_context context, cl_uint num_devices, const cl_device_id *device_list, const size_t *lengths, const unsigned char **binaries, cl_int *binary_status, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clCreateProgramWithBinary; + return func(context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret); +} + +cl_int CL_API_CALL clGetProgramInfo(cl_program program, cl_program_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clGetProgramInfo; + return func(program, param_name, param_value_size, param_value, param_value_size_ret); +} +cl_int CL_API_CALL clEnqueueFillBuffer(cl_command_queue command_queue, + cl_mem buffer, + const void *pattern, + size_t pattern_size, + size_t offset, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event *event_wait_list, + cl_event *event) { + // 从 symbols_ 结构体中获取函数指针 + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueFillBuffer; + if (func) { + // 如果成功加载,则调用真实的 OpenCL 函数 + return func(command_queue, buffer, pattern, pattern_size, offset, size, num_events_in_wait_list, event_wait_list, event); + } + // 如果函数指针为空(例如在某些非常老的设备上不支持),返回一个错误码 + return CL_INVALID_OPERATION; +} +void *CL_API_CALL clEnqueueMapBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_map, cl_map_flags map_flags, size_t offset, size_t size, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event, cl_int *errcode_ret) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueMapBuffer; + if (func) { + return func(command_queue, buffer, blocking_map, map_flags, offset, size, num_events_in_wait_list, event_wait_list, event, errcode_ret); + } + if (errcode_ret) { + *errcode_ret = CL_INVALID_OPERATION; + } + return nullptr; +} + +cl_int CL_API_CALL clEnqueueUnmapMemObject(cl_command_queue command_queue, cl_mem memobj, void *mapped_ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { + auto func = mllm::OpenCLBackend::getSymbols()->clEnqueueUnmapMemObject; + if (func) { + return func(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event); + } + return CL_INVALID_OPERATION; +} + +} // extern "C" +#endif // MLLM_TARGET_ANDROID + std::shared_ptr OpenCLBackend::createMemoryManager(cl_context &context, cl_device_id &device) { +#if defined(MLLM_TARGET_ANDROID) + std::call_once(opencl_symbols_load_flag, [&]() { + loadOpenCLSymbols(); + }); +#endif cl_int err; cl_platform_id platform; - - // 1. 获取平台 err = clGetPlatformIDs(1, &platform, nullptr); check_cl_error(err, "clGetPlatformIDs"); - - // 2. 获取设备 (优先GPU) err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, nullptr); if (err != CL_SUCCESS) { + std::cout << "No GPU found, trying CPU..." << std::endl; err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &device, nullptr); } check_cl_error(err, "clGetDeviceIDs"); - - // 3. 创建上下文 context = clCreateContext(nullptr, 1, &device, nullptr, nullptr, &err); check_cl_error(err, "clCreateContext"); - - // 4. 创建并返回 OpenCLMemoryManager return std::make_shared(context); -} // namespace mllm +} OpenCLBackend::OpenCLBackend(const BackendConfig &config) : Backend() { mem_manager_ = createMemoryManager(context_, device_); cl_int err; - queue_ = clCreateCommandQueue(context_, device_, 0, &err); + // queue_ = clCreateCommandQueue(context_, device_, 0, &err); + cl_command_queue_properties properties = CL_QUEUE_PROFILING_ENABLE; + queue_ = clCreateCommandQueue(context_, device_, properties, &err); check_cl_error(err, "clCreateCommandQueue"); - - // ======================================================================= - // ========== 检查扩展支持和获取对齐值 ========== - // ======================================================================= + err = clGetDeviceInfo(device_, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &this->max_image2d_width_, nullptr); + check_cl_error(err, "clGetDeviceInfo for CL_DEVICE_IMAGE2D_MAX_WIDTH"); + // 如果查询失败或返回0,可以设置一个保守的默认值 + if (this->max_image2d_width_ == 0) { + this->max_image2d_width_ = 8192; // 一个非常保守的值 + } size_t extensions_size; - // 获取扩展字符串的长度 clGetDeviceInfo(device_, CL_DEVICE_EXTENSIONS, 0, nullptr, &extensions_size); std::string extensions(extensions_size, ' '); - // 获取完整的扩展字符串 clGetDeviceInfo(device_, CL_DEVICE_EXTENSIONS, extensions_size, &extensions[0], nullptr); - if (extensions.find("cl_khr_fp16") != std::string::npos) { this->has_fp16_support_ = true; } else { this->has_fp16_support_ = false; } - // 检查是否包含我们需要的扩展 if (extensions.find("cl_khr_image2d_from_buffer") != std::string::npos) { this->image_from_buffer_supported_ = true; - - // 如果支持,则进一步查询行间距对齐要求(单位:字节) - // CL_DEVICE_IMAGE_PITCH_ALIGNMENT 返回的是像素单位,需要转换,不如此处直接查询字节对齐可靠。 - // CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 是一个更通用的字节对齐保证。 clGetDeviceInfo(device_, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT, sizeof(cl_uint), &this->image_pitch_alignment_bytes_, nullptr); - - // 根据规范,如果返回0,则表示没有特殊的对齐要求,我们可以认为是1字节对齐。 if (this->image_pitch_alignment_bytes_ == 0) { this->image_pitch_alignment_bytes_ = 1; } } else { - // 如果不支持,明确设置为false this->image_from_buffer_supported_ = false; this->image_pitch_alignment_bytes_ = 0; } - // ======================================================================= - const std::string convert_kernel_path = get_kernel_path(__FILE__, "./kernel/convert_fp.cl"); +#if defined(MLLM_TARGET_ANDROID) + kernel_root_path_ = get_executable_dir(); +#else + kernel_root_path_ = get_kernel_path(__FILE__, "."); +#endif + const std::string convert_kernel_path = kernel_root_path_ + "/kernel/convert_fp.cl"; std::string build_options = ""; - - // 如果硬件支持FP16,我们通过宏定义告诉编译器去编译高性能版本的内核 if (this->has_fp16_support_) { build_options += " -DSUPPORTS_FP16"; + // std::cout << "OpenCL supports cl_khr_fp16." << std::endl; } - cl_program convert_program = getProgram(convert_kernel_path, build_options); - - // --- 根据硬件能力,创建并加载相应版本的内核 --- if (this->has_fp16_support_) { - // **高性能路径**: 加载使用原生 `half` 的内核 kernel_fp32_to_fp16_buffer_ = clCreateKernel(convert_program, "convert_fp32_to_fp16_buffer_ext", &err); check_cl_error(err, "CreateKernel: convert_fp32_to_fp16_buffer_ext"); kernel_fp16_to_fp32_buffer_ = clCreateKernel(convert_program, "convert_fp16_to_fp32_buffer_ext", &err); check_cl_error(err, "CreateKernel: convert_fp16_to_fp32_buffer_ext"); - - // Image内核只有在支持FP16时才有意义 kernel_fp32_to_fp16_image_ = clCreateKernel(convert_program, "convert_fp32_to_fp16_image2d", &err); check_cl_error(err, "CreateKernel: convert_fp32_to_fp16_image2d"); kernel_fp16_to_fp32_image_ = clCreateKernel(convert_program, "convert_fp16_to_fp32_image2d", &err); check_cl_error(err, "CreateKernel: convert_fp16_to_fp32_image2d"); - } else { - // **兼容性路径**: 加载使用 `ushort` 模拟的内核 kernel_fp32_to_fp16_buffer_ = clCreateKernel(convert_program, "convert_fp32_to_fp16_buffer_compat", &err); check_cl_error(err, "CreateKernel: convert_fp32_to_fp16_buffer_compat"); kernel_fp16_to_fp32_buffer_ = clCreateKernel(convert_program, "convert_fp16_to_fp32_buffer_compat", &err); check_cl_error(err, "CreateKernel: convert_fp16_to_fp32_buffer_compat"); - // 在不原生支持FP16的设备上,Image转换通常也不可行或无意义,所以不加载Image内核 } - sampler_ = clCreateSampler(context_, CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); check_cl_error(err, "clCreateSampler in Backend"); - this->type_ = MLLM_OPENCL; registerOps(); } OpenCLBackend::~OpenCLBackend() { - // 释放所有缓存的 cl_program + if (mem_manager_) { + mem_manager_.reset(); + } if (kernel_fp32_to_fp16_buffer_) clReleaseKernel(kernel_fp32_to_fp16_buffer_); if (kernel_fp16_to_fp32_buffer_) clReleaseKernel(kernel_fp16_to_fp32_buffer_); if (kernel_fp32_to_fp16_image_) clReleaseKernel(kernel_fp32_to_fp16_image_); if (kernel_fp16_to_fp32_image_) clReleaseKernel(kernel_fp16_to_fp32_image_); if (sampler_) clReleaseSampler(sampler_); - - // (保留原有释放 program 和 queue 的代码) for (auto const &[key, program] : program_cache_) { if (program) { clReleaseProgram(program); @@ -149,7 +550,12 @@ OpenCLBackend::~OpenCLBackend() { } if (queue_) clReleaseCommandQueue(queue_); if (context_) clReleaseContext(context_); - // std::cout << "OpenCLBackend cleaned up." << std::endl; +#if defined(MLLM_TARGET_ANDROID) + if (symbols_.handle) { + dlclose(symbols_.handle); + symbols_.handle = nullptr; + } +#endif } void OpenCLBackend::finishQueue() { @@ -157,35 +563,108 @@ void OpenCLBackend::finishQueue() { clFinish(queue_); } } - cl_program OpenCLBackend::getProgram(const std::string &program_name, const std::string &build_options) { - // 检查缓存 - auto it = program_cache_.find(program_name); + // 使用 program_name 和 build_options 创建唯一的键,用于在内存中缓存 program 对象 + std::string cache_key = program_name + build_options; + auto it = program_cache_.find(cache_key); if (it != program_cache_.end()) { return it->second; } - // 加载和编译 - std::string kernel_source = load_file_contents(program_name.c_str()); - const char *source_ptr = kernel_source.c_str(); - size_t source_len = kernel_source.length(); + // 1. 构建源文件和缓存文件的完整路径 + std::filesystem::path source_path(kernel_root_path_); + source_path /= program_name; + + // a. 创建缓存目录 (例如: opencl/kernel/cache) + std::filesystem::path cache_dir = source_path.parent_path() / "cache"; + std::error_code ec; + if (!std::filesystem::exists(cache_dir, ec)) { + std::filesystem::create_directories(cache_dir, ec); + } + + // b. 生成一个稳定且唯一的缓存文件名 (例如: kernel_add_cl_xxxxx.bin) + // 将路径中的 '/' 和 '.' 替换为 '_',并附上编译选项的哈希值 + std::string bin_file_name = program_name; + std::replace(bin_file_name.begin(), bin_file_name.end(), '/', '_'); + std::replace(bin_file_name.begin(), bin_file_name.end(), '.', '_'); + std::hash hasher; + std::string options_hash = std::to_string(hasher(build_options)); + std::filesystem::path bin_path = cache_dir / (bin_file_name + "_" + options_hash + ".bin"); + + cl_program program = nullptr; cl_int err; - cl_program program = clCreateProgramWithSource(context_, 1, &source_ptr, &source_len, &err); - check_cl_error(err, "clCreateProgramWithSource"); + // 2. 尝试从二进制缓存文件加载程序 + std::ifstream bin_file(bin_path, std::ios::binary); + if (bin_file.is_open()) { + bin_file.seekg(0, std::ios::end); + size_t bin_size = bin_file.tellg(); + bin_file.seekg(0, std::ios::beg); + std::vector bin_data(bin_size); + bin_file.read(reinterpret_cast(bin_data.data()), bin_size); + bin_file.close(); + + const unsigned char *bin_ptr = bin_data.data(); + cl_int binary_status; + program = clCreateProgramWithBinary(context_, 1, &device_, &bin_size, &bin_ptr, &binary_status, &err); + + if (err == CL_SUCCESS && binary_status == CL_SUCCESS) { + // ===== [ 核心修正点 ] ===== + // 即使从二进制加载,也需要Build来使其对设备可执行 + err = clBuildProgram(program, 1, &device_, build_options.c_str(), nullptr, nullptr); + if (err != CL_SUCCESS) { + // 如果Build失败,说明缓存可能已损坏或不兼容,需要回退到从源码编译 + if (program) clReleaseProgram(program); // 释放无效的 program 对象 + program = nullptr; // 将 program 置空,以便后续逻辑能从源码重新编译 + } + // ===== [ 修正结束 ] ===== + } else { + // 如果加载失败,清空 program 对象 + if (program) clReleaseProgram(program); + program = nullptr; + } + } - err = clBuildProgram(program, 1, &device_, build_options.c_str(), nullptr, nullptr); - if (err != CL_SUCCESS) { - size_t log_size; - clGetProgramBuildInfo(program, device_, CL_PROGRAM_BUILD_LOG, 0, nullptr, &log_size); - std::vector log(log_size); - clGetProgramBuildInfo(program, device_, CL_PROGRAM_BUILD_LOG, log_size, log.data(), nullptr); - std::string error_msg = "Kernel build error for " + program_name + ":\n" + log.data(); - throw std::runtime_error(error_msg); + // 3. 如果从缓存加载失败 (program == nullptr),则从源码编译 + if (program == nullptr) { + std::string kernel_source = load_file_contents(source_path.c_str()); + const char *source_ptr = kernel_source.c_str(); + size_t source_len = kernel_source.length(); + program = clCreateProgramWithSource(context_, 1, &source_ptr, &source_len, &err); + check_cl_error(err, "clCreateProgramWithSource for " + program_name); + + err = clBuildProgram(program, 1, &device_, build_options.c_str(), nullptr, nullptr); + if (err != CL_SUCCESS) { + size_t log_size; + clGetProgramBuildInfo(program, device_, CL_PROGRAM_BUILD_LOG, 0, nullptr, &log_size); + std::vector log(log_size); + clGetProgramBuildInfo(program, device_, CL_PROGRAM_BUILD_LOG, log_size, log.data(), nullptr); + std::string error_msg = "Kernel build error for " + program_name + ":\n" + log.data(); + if (program) clReleaseProgram(program); + throw std::runtime_error(error_msg); + } + + // 4. 编译成功后,获取二进制码并保存到缓存文件 + size_t binary_size; + clGetProgramInfo(program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binary_size, nullptr); + if (binary_size > 0) { + std::vector binary_data(binary_size); + unsigned char *bin_ptr = binary_data.data(); + // 注意:clGetProgramInfo的第三个参数应该是`sizeof(unsigned char*)` + clGetProgramInfo(program, CL_PROGRAM_BINARIES, sizeof(unsigned char *), &bin_ptr, nullptr); + + std::ofstream out_bin_file(bin_path, std::ios::binary); + if (out_bin_file.is_open()) { + out_bin_file.write(reinterpret_cast(binary_data.data()), binary_size); + out_bin_file.close(); + } else { + std::cerr << "Warning: Could not write to kernel cache file: " << bin_path << std::endl; + } + } } - // 存入缓存并返回 - program_cache_[program_name] = program; + // 将最终获取的 program 对象存入内存缓存 + program_cache_[cache_key] = program; return program; } void OpenCLBackend::alloc_device(DeviceMemory &mem, DataType dtype) { @@ -193,42 +672,30 @@ void OpenCLBackend::alloc_device(DeviceMemory &mem, DataType dtype) { cl_int err; switch (mem.type) { case MEM_TYPE_BUFFER: { - // **新增逻辑**:检查是否是创建 Image 兼容 Buffer 的特殊请求 if (mem.image_width > 0 && mem.image_height > 0 && image_from_buffer_supported_) { - // === 创建 Image 兼容的、带行间距对齐的 Buffer === - - // 1. 计算满足硬件对齐要求的行间距(字节单位) - const size_t pixel_width = mem.image_width; // 此时 image_width 是像素数 + const size_t pixel_width = mem.image_width; const cl_uint pitch_alignment = image_pitch_alignment_bytes_; - - size_t row_pitch = pixel_width * 4 * sizeof(float); // 理论行间距 + size_t row_pitch = pixel_width * 4 * sizeof(float); if (pitch_alignment > 0 && row_pitch % pitch_alignment != 0) { row_pitch = (row_pitch + pitch_alignment - 1) / pitch_alignment * pitch_alignment; } - - // 2. 计算带填充的总 buffer 大小 const size_t padded_buffer_size = mem.image_height * row_pitch; - - // 3. 更新 DeviceMemory 结构体,保存关键信息 - mem.size_in_bytes = padded_buffer_size; // 使用计算出的、更大的尺寸 - mem.image_row_pitch_in_bytes = row_pitch; // **保存行间距,为零拷贝做准备** - - // 4. 使用新的总大小创建 Buffer - mem.handle = clCreateBuffer(context_, CL_MEM_READ_WRITE, padded_buffer_size, nullptr, &err); - check_cl_error(err, "clCreateBuffer for Image-Compatible Buffer"); - - } else { - // === 创建一个标准的、紧密排列的 Buffer === - mem.handle = clCreateBuffer(context_, CL_MEM_READ_WRITE, mem.size_in_bytes, nullptr, &err); - check_cl_error(err, "clCreateBuffer for Standard Buffer"); + mem.size_in_bytes = padded_buffer_size; + mem.image_row_pitch_in_bytes = row_pitch; + mem_manager_->alloc(&mem.handle, mem.size_in_bytes, 0); + if (mem.handle == nullptr) { + throw std::runtime_error("OpenCLMemoryManager failed to allocate buffer."); + } + } else if (mem.size_in_bytes > 0) { + mem_manager_->alloc(&mem.handle, mem.size_in_bytes, 0); + if (mem.handle == nullptr) { + throw std::runtime_error("OpenCLMemoryManager failed to allocate buffer."); + } } break; } case MEM_TYPE_IMAGE_2D: { - // cl_image_format format = {CL_RGBA, CL_FLOAT}; - cl_image_format format = {CL_RGBA}; // 通道顺序不变 - - // **核心修改:根据dtype设置通道数据类型** + cl_image_format format = {CL_RGBA}; switch (dtype) { case MLLM_TYPE_F32: format.image_channel_data_type = CL_FLOAT; @@ -243,8 +710,10 @@ void OpenCLBackend::alloc_device(DeviceMemory &mem, DataType dtype) { desc.image_type = CL_MEM_OBJECT_IMAGE2D; desc.image_width = mem.image_width; desc.image_height = mem.image_height; - mem.handle = clCreateImage(context_, CL_MEM_READ_WRITE, &format, &desc, nullptr, &err); - check_cl_error(err, "clCreateImage"); + if (desc.image_width > 0) { + mem.handle = clCreateImage(context_, CL_MEM_READ_WRITE, &format, &desc, nullptr, &err); + check_cl_error(err, "clCreateImage"); + } break; } default: throw std::runtime_error("Unsupported device memory type for OpenCL."); @@ -253,7 +722,18 @@ void OpenCLBackend::alloc_device(DeviceMemory &mem, DataType dtype) { void OpenCLBackend::free_device(DeviceMemory &mem) { if (mem.handle != nullptr) { - clReleaseMemObject(static_cast(mem.handle)); + switch (mem.type) { + case MEM_TYPE_BUFFER: + mem_manager_->free(mem.handle); + break; + case MEM_TYPE_IMAGE_2D: + clReleaseMemObject(static_cast(mem.handle)); + break; + default: + // 对于其他类型,也许也应该直接释放 + clReleaseMemObject(static_cast(mem.handle)); + break; + } mem.handle = nullptr; } } @@ -263,34 +743,18 @@ void OpenCLBackend::copy_from_host(const DeviceMemory &dest, const void *src) { cl_mem dest_handle = static_cast(dest.handle); switch (dest.type) { case MEM_TYPE_BUFFER: { - // 检查这个Buffer是否是Image兼容的 if (dest.image_row_pitch_in_bytes > 0 && dest.image_height > 0) { - // **使用 clEnqueueWriteBufferRect 来处理行间距** const size_t buffer_origin[3] = {0, 0, 0}; const size_t host_origin[3] = {0, 0, 0}; - - // region_in_bytes: {width, height, depth} const size_t region_in_bytes[3] = { - dest.image_width * 4 * sizeof(float), // 拷贝区域的宽度(字节) - dest.image_height, // 拷贝区域的高度(行数) - 1 // 深度为1 - }; - + dest.image_width * 4 * sizeof(float), + dest.image_height, + 1}; clEnqueueWriteBufferRect( - queue_, - dest_handle, - CL_TRUE, // 阻塞调用 - buffer_origin, - host_origin, - region_in_bytes, - dest.image_row_pitch_in_bytes, // Buffer中的行间距 - 0, // Buffer中的切片间距 - dest.image_width * 4 * sizeof(float), // Host内存中的行间距(假设紧密排列) - 0, // Host内存中的切片间距 - src, - 0, nullptr, nullptr); + queue_, dest_handle, CL_TRUE, buffer_origin, host_origin, + region_in_bytes, dest.image_row_pitch_in_bytes, 0, + dest.image_width * 4 * sizeof(float), 0, src, 0, nullptr, nullptr); } else { - // 标准的Buffer拷贝 clEnqueueWriteBuffer(queue_, dest_handle, CL_TRUE, 0, dest.size_in_bytes, src, 0, nullptr, nullptr); } break; @@ -333,45 +797,65 @@ Op *OpenCLBackend::opCreate(const OpParam &op_param, std::string name, int threa OpType type = (OpType)op_param.find("type")->second; auto it = op_creator_map_.find(type); if (it == op_creator_map_.end()) { - throw std::runtime_error("Op type " + std::to_string(type) + " not supported by OpenCLBackend"); + return nullptr; } return it->second->create(op_param, this, name, threadCount); } TensorFunction *OpenCLBackend::funcCreate(TensorFuncType type) { throw std::runtime_error("funcCreate not implemented for OpenCLBackend"); - return nullptr; } void OpenCLBackend::registerOps() { - // 在这里注册该后端支持的所有 Op - op_creator_map_[F_TTADD] = std::make_shared(); - // std::cout << "OpenCLBackend ops registered." << std::endl; + op_creator_map_[F_ADD] = std::make_shared(); + op_creator_map_[F_TTADD] = std::make_shared(); + op_creator_map_[F_SUB] = std::make_shared(); + op_creator_map_[F_TTSUB] = std::make_shared(); + op_creator_map_[F_MUL] = std::make_shared(); + op_creator_map_[F_TTMUL] = std::make_shared(); + op_creator_map_[F_DIV] = std::make_shared(); + op_creator_map_[F_DIVINT] = std::make_shared(); + op_creator_map_[F_TTDIV] = std::make_shared(); + op_creator_map_[F_MM] = std::make_shared(); + op_creator_map_[LINEAR] = std::make_shared(); + op_creator_map_[F_TRANPOSE] = std::make_shared(); + op_creator_map_[SOFTMAX] = std::make_shared(); + op_creator_map_[RMSNORM] = std::make_shared(); + op_creator_map_[EMBEDDING] = std::make_shared(); + op_creator_map_[SILU] = std::make_shared(); + op_creator_map_[F_VIEW] = std::make_shared(); + op_creator_map_[KVCACHE] = std::make_shared(); + op_creator_map_[ROPE] = std::make_shared(); + op_creator_map_[F_CLIP] = std::make_shared(); + op_creator_map_[F_FA2] = std::make_shared(); + op_creator_map_[F_SPLIT] = std::make_shared(); + op_creator_map_[F_TOPK] = std::make_shared(); + op_creator_map_[F_SUM] = std::make_shared(); + op_creator_map_[F_LIKE] = std::make_shared(); + op_creator_map_[F_CLIPTENSOR] = std::make_shared(); + op_creator_map_[F_SCATTERRADD] = std::make_shared(); + op_creator_map_[F_ARGSORT] = std::make_shared(); + op_creator_map_[F_BINCOUNT] = std::make_shared(); } void OpenCLBackend::registerFuncs() { std::cout << "OpenCLBackend funcs is abanded." << std::endl; } -// 用以下最终完整版替换您的 convert_fp_data 函数 void OpenCLBackend::convert_fp_data(Tensor *src, Tensor *dest) { if (src->device() != MLLM_OPENCL || dest->device() != MLLM_OPENCL) { throw std::runtime_error("Type conversion on GPU requires both tensors to be on OpenCL backend."); } - - // 获取源和目标的内存描述符 auto &src_mem = src->device_memory(); auto &dest_mem = dest->device_memory(); - // =================================================== - // ============ 第一层决策:根据内存类型 ============ - // =================================================== - if (src_mem.type == MEM_TYPE_BUFFER) { - // ========== Buffer-to-Buffer 转换路径 ========== - if (dest_mem.type != MEM_TYPE_BUFFER) throw std::runtime_error("Destination must be a Buffer for Buffer conversion."); - + if (dest_mem.type != MEM_TYPE_BUFFER) { + throw std::runtime_error("Destination must be a Buffer for Buffer conversion."); + } cl_kernel kernel_to_use = nullptr; + + // 根据转换类型选择内核 if (src->dtype() == MLLM_TYPE_F32 && dest->dtype() == MLLM_TYPE_F16) { kernel_to_use = kernel_fp32_to_fp16_buffer_; } else if (src->dtype() == MLLM_TYPE_F16 && dest->dtype() == MLLM_TYPE_F32) { @@ -383,20 +867,32 @@ void OpenCLBackend::convert_fp_data(Tensor *src, Tensor *dest) { cl_mem src_buf = get_cl_mem(*src); cl_mem dest_buf = get_cl_mem(*dest); - int count = src->count(); + const int count = src->count(); - clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &src_buf); - clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &dest_buf); - clSetKernelArg(kernel_to_use, 2, sizeof(int), &count); + // ✨ **关键修正: 明确控制工作组大小** + if (count > 0) { + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &src_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &dest_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(int), &count); - const size_t global_work_size[1] = {(size_t)count}; - clEnqueueNDRangeKernel(queue_, kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + // 1. 定义一个标准的工作组大小 + const size_t local_work_size = 256; - } else if (src_mem.type == MEM_TYPE_IMAGE_2D) { - if (dest_mem.type != MEM_TYPE_IMAGE_2D) throw std::runtime_error("Destination must be an Image for Image conversion."); + // 2. 手动计算向上补齐的全局工作大小 + const size_t global_work_size = ((count + local_work_size - 1) / local_work_size) * local_work_size; - cl_kernel kernel_to_use = nullptr; + // 3. 使用明确的 local 和 global size 启动内核 + cl_event event; + cl_int err = clEnqueueNDRangeKernel(queue_, kernel_to_use, 1, nullptr, &global_work_size, &local_work_size, 0, nullptr, &event); + this->addProfilingEvent("convert_fp_data", event); + check_cl_error(err, "clEnqueueNDRangeKernel for type conversion"); + } + } else if (src_mem.type == MEM_TYPE_IMAGE_2D) { + if (dest_mem.type != MEM_TYPE_IMAGE_2D) { + throw std::runtime_error("Destination must be an Image for Image conversion."); + } + cl_kernel kernel_to_use = nullptr; if (src->dtype() == MLLM_TYPE_F32 && dest->dtype() == MLLM_TYPE_F16) { kernel_to_use = kernel_fp32_to_fp16_image_; } else if (src->dtype() == MLLM_TYPE_F16 && dest->dtype() == MLLM_TYPE_F32) { @@ -405,8 +901,6 @@ void OpenCLBackend::convert_fp_data(Tensor *src, Tensor *dest) { if (src->dtype() == dest->dtype()) return; throw std::runtime_error("Unsupported Image conversion types."); } - - // **新增**: 健壮性检查,如果内核未创建(例如硬件不支持FP16),则报错 if (!kernel_to_use) { throw std::runtime_error("Image conversion kernel is not available. This may be due to lack of FP16 hardware support."); } @@ -416,16 +910,73 @@ void OpenCLBackend::convert_fp_data(Tensor *src, Tensor *dest) { const int width = src_mem.image_width; const int height = src_mem.image_height; - // **修改**: 取消注释并使用成员变量 sampler_ clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &src_img); clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &dest_img); clSetKernelArg(kernel_to_use, 3, sizeof(int), &width); clSetKernelArg(kernel_to_use, 4, sizeof(int), &height); - const size_t global_work_size[2] = {(size_t)width, (size_t)height}; - clEnqueueNDRangeKernel(queue_, kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + // 对于2D图像,通常让驱动选择最佳工作组大小是安全的,但也可以明确指定 + const size_t local_ws[2] = {16, 16}; + const size_t global_ws[2] = { + ((size_t)width + local_ws[0] - 1) / local_ws[0] * local_ws[0], + ((size_t)height + local_ws[1] - 1) / local_ws[1] * local_ws[1]}; + + clEnqueueNDRangeKernel(queue_, kernel_to_use, 2, nullptr, global_ws, local_ws, 0, nullptr, nullptr); + } +} +bool OpenCLBackend::load_from_file(Tensor *tensor, ParamLoader *loader) { + // 1. 从加载器获取张量的元数据和文件句柄 + ParamMetadata metadata = loader->getParamMetadata(tensor->name()); + FILE *fp = loader->getInputStream(); + if (metadata.size == 0) { + return true; // 无需加载 + } + + // 2. 检查张量设备内存是否已就绪 + if (tensor->device_memory().handle == nullptr) { + // 如果内存未分配,此快速路径无法工作。 + // 这通常意味着调用顺序有问题,load() 之前应先 alloc()。 + return false; + } + + // 3. 获取OpenCL对象 + cl_command_queue queue = this->getQueue(); + cl_mem buffer = this->get_cl_mem(*tensor); + + // 4. 将GPU缓冲区映射到主机地址空间 (阻塞式,写入模式) + cl_int err; + void *mapped_ptr = clEnqueueMapBuffer(queue, buffer, CL_TRUE, CL_MAP_WRITE, 0, metadata.size, 0, nullptr, nullptr, &err); + check_cl_error(err, "OpenCLBackend::load_from_file clEnqueueMapBuffer"); + if (mapped_ptr == nullptr) { + fprintf(stderr, "Error: Failed to map OpenCL buffer for tensor '%s'.\n", tensor->name().c_str()); + return false; + } + + // 5. 将文件指针移动到权重数据的起始位置,并直接读入映射后的内存 + fseek(fp, metadata.offset, SEEK_SET); + size_t read_size = fread(mapped_ptr, 1, metadata.size, fp); + if (read_size != metadata.size) { + fprintf(stderr, "Error: File read failed for tensor '%s'. Expected %llu, got %zu.\n", tensor->name().c_str(), metadata.size, read_size); + // 出错也要确保解映射 + clEnqueueUnmapMemObject(queue, buffer, mapped_ptr, 0, nullptr, nullptr); + clFinish(queue); // 等待命令完成 + return false; } + + // 6. 解除内存映射,并将控制权交还GPU + cl_event unmap_event; + err = clEnqueueUnmapMemObject(queue, buffer, mapped_ptr, 0, nullptr, &unmap_event); + check_cl_error(err, "OpenCLBackend::load_from_file clEnqueueUnmapMemObject"); + + // 7. 阻塞等待解映射操作完成,确保数据对GPU可见 + clWaitForEvents(1, &unmap_event); + clReleaseEvent(unmap_event); + + // 8. 数据已在设备上,主机指针应失效,防止误用 + tensor->forceResetHostPointer(nullptr); + + return true; // 表示加载已由本函数成功处理 } void registerOpenCLBackendCreator() { @@ -434,85 +985,228 @@ void registerOpenCLBackendCreator() { std::vector OpenCLBackend::runLayer(Layer *layer, std::vector inputs, int N) { throw std::runtime_error("runLayer not implemented for OpenCLBackend"); - return {}; } std::vector OpenCLBackend::runOp(Op *op, std::vector inputs, std::vector out_names, bool in_place) { - Module *module = inputs[0].module(); - // map> &actime] = std::make_shared(op->backend()); - // activation_tensors[out_name]->setName(out_name); - // activation_tensors[out_name]->setModule(module); - // }vation_tensors = module->activation_tensors; - // if (module->doTrace) { // trace - // for (const auto &out_name : out_names) { - // if (activation_tensors.find(out_name) == activation_tensors.end()) { - // activation_tensors[out_na - // } - // vector> inPtrs; - // for (auto &input : inputs) { - // inPtrs.push_back(input.shouldInGraphs() ? activation_tensors[input.name()] : - // std::shared_ptr(&input, [](Tensor *) {})); - // } - // vector> outPtrs = {}; - // for (auto &name : out_names) outPtrs.push_back(activation_tensors[name]); - // op->setUp(inPtrs, outPtrs); - // vector results = {}; - // for (auto &name : out_names) results.push_back(*activation_tensors[name]); - // return results; - // } - -#ifdef DEBUGOPTIME - uint64_t time_start = mllm_time_us(); -#endif + Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); + static map> empty_activation_tensors; + map> &activation_tensors = module ? module->activation_tensors : empty_activation_tensors; + if (module && module->doTrace) { + if (module->tracedFlag) { + vector results = {}; + for (auto &name : out_names) results.push_back(*activation_tensors[name]); + return results; + } + for (auto &input : inputs) { + if (input.shouldInGraphs() && activation_tensors.find(input.name()) == activation_tensors.end()) { + activation_tensors[input.name()] = std::make_shared(op->backend()); + activation_tensors[input.name()]->setName(input.name()); + activation_tensors[input.name()]->setModule(module); + } + } + for (const auto &out_name : out_names) { + if (activation_tensors.find(out_name) == activation_tensors.end()) { + activation_tensors[out_name] = std::make_shared(op->backend()); + activation_tensors[out_name]->setName(out_name); + activation_tensors[out_name]->setModule(module); + } + } + vector> inPtrs; + for (auto &input : inputs) { + inPtrs.push_back(input.shouldInGraphs() ? activation_tensors[input.name()] : + std::shared_ptr(&input, [](Tensor *) {})); + } + vector> outPtrs = {}; + for (auto &name : out_names) outPtrs.push_back(activation_tensors[name]); + op->setUp(inPtrs, outPtrs); + vector results = {}; + for (auto &name : out_names) results.push_back(*activation_tensors[name]); + return results; + } vector> input_tensors; for (auto &input : inputs) { input_tensors.push_back(std::shared_ptr(&input, [](Tensor *) {})); } vector> out_tensors; - // Part 1: Create tensor shells - for (const auto &out_name : out_names) { - auto out_tensor = std::make_shared(op->backend()); - out_tensor->setName(out_name); - // out_tensor->setModule(module); - out_tensors.push_back(out_tensor); - } - // if (!in_place) { - // _create_output_tensors(out_tensors, input_tensors, out_names, module, activation_tensors, op->backend()); - // } else { - // // If in-place, we already have out_tensors filled with input tensors. - // for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { - // input_tensors[i]->setName(out_names[i]); - // out_tensors.push_back(input_tensors[i]); - // } - // } - // Part 2: Reshape the tensors + if (!in_place) { + for (const auto &out_name : out_names) { + auto out_tensor = std::make_shared(op->backend()); + out_tensor->setName(out_name); + out_tensors.push_back(out_tensor); + } + } else { + for (size_t i = 0; i < input_tensors.size() && i < out_names.size(); ++i) { + input_tensors[i]->setName(out_names[i]); + out_tensors.push_back(input_tensors[i]); + } + } op->reshape(input_tensors, out_tensors); - // Part 3: Allocate memory op->setUp(input_tensors, out_tensors); - // if (!in_place) { - // for (auto &out_tensor : out_tensors) { - // auto act_it = activation_tensors.find(out_tensor->name()); - // auto template_it = act_it != activation_tensors.end() ? act_it->second : nullptr; - // out_tensor->allocFromTemplate(template_it); - // } - // } - // Part 4: Execute the operation op->execute(input_tensors, out_tensors); + vector results; + for (const auto &out_tensor : out_tensors) { + results.push_back(*out_tensor); +#ifdef DEBUGSAVETENSOR + out_tensor->cpu(); + if (out_tensor->dtype() == MLLM_TYPE_F32) { + out_tensor->saveData(); + } + if (out_tensor->dtype() == MLLM_TYPE_F16) { + out_tensor->saveData(); + } + out_tensor->cl(); +#endif + } + return results; +} +std::vector OpenCLBackend::runForward(Module *module, std::vector inputs, std::vector args) { + if (Module::llm_model_ptr && (Module::llm_model_ptr->doLoad || Module::llm_model_ptr->doChangeBn)) { + auto outputs = module->Forward(inputs, args); + return outputs; + } + uint64_t time_start, time_end; + bool ouilter_flag = (inputs[0].ttype() == TensorType::INPUT_TENSOR); + if (ouilter_flag) { + for (int i = 0; i < inputs.size(); i++) { + auto &input = inputs[i]; + input.setModule(module); + input.setTtype(TensorType::NORMAL_TENSOR); + } + Module::llm_model_ptr = module; + if (module->prefilling_token_size_ == 0) { + module->prefilling_token_size_ = inputs[0].sequence() * inputs[0].batch(); + } else if (module->decoding_token_size_ == 0) { + module->decoding_token_size_ = inputs[0].sequence() * inputs[0].batch(); + } + time_start = mllm_time_us(); + // exe_times.clear(); + } + auto output = module->Forward(inputs, args); + if (ouilter_flag) { + this->finishQueue(); + time_end = mllm_time_us(); + double inference_time_ = (time_end - time_start) / 1000.0F; #ifdef DEBUGOPTIME - uint64_t time_end = mllm_time_us(); - double inference_time_ = (time_end - time_start) / 1000.0F; // ms - std::cout << op->name() << " | time: " << inference_time_ << "ms" << std::endl; + this->reportProfilingResult(); + std::cout << "One token total inference time: " << inference_time_ << " ms" << std::endl; #endif + module->inference_times_.push_back(inference_time_); + } + return output; +} - vector results; - for (const auto &out_tensor : out_tensors) { results.push_back(*out_tensor); } - return results; +#if defined(MLLM_TARGET_ANDROID) +void OpenCLBackend::loadOpenCLSymbols() { + static const std::vector android_paths = { + "libOpenCL.so", + "libGLES_mali.so", + "libmali.so", + "libOpenCL-pixel.so", + "/system/vendor/lib64/libOpenCL.so", + "/system/lib64/libOpenCL.so", + "/system/vendor/lib64/egl/libGLES_mali.so", + "/system/lib64/egl/libGLES_mali.so"}; + + for (const auto &path : android_paths) { + symbols_.handle = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL); + if (symbols_.handle) break; + } + + if (!symbols_.handle) { + throw std::runtime_error("Failed to load OpenCL library on Android"); + } + +#define LOAD_FUNC(name) \ + symbols_.name = reinterpret_cast(dlsym(symbols_.handle, #name)); \ + if (!symbols_.name) { \ + std::cerr << "Failed to load: " << #name << std::endl; \ + } + + LOAD_FUNC(clGetPlatformIDs); + LOAD_FUNC(clGetDeviceIDs); + LOAD_FUNC(clGetDeviceInfo); + LOAD_FUNC(clCreateContext); + LOAD_FUNC(clCreateCommandQueue); + LOAD_FUNC(clReleaseCommandQueue); + LOAD_FUNC(clReleaseContext); + LOAD_FUNC(clCreateProgramWithSource); + LOAD_FUNC(clBuildProgram); + LOAD_FUNC(clGetProgramBuildInfo); + LOAD_FUNC(clCreateProgramWithBinary); + LOAD_FUNC(clGetProgramInfo); + LOAD_FUNC(clReleaseProgram); + LOAD_FUNC(clCreateKernel); + LOAD_FUNC(clReleaseKernel); + LOAD_FUNC(clSetKernelArg); + LOAD_FUNC(clEnqueueNDRangeKernel); + LOAD_FUNC(clCreateBuffer); + LOAD_FUNC(clReleaseMemObject); + LOAD_FUNC(clEnqueueWriteBuffer); + LOAD_FUNC(clEnqueueReadBuffer); + LOAD_FUNC(clFinish); + LOAD_FUNC(clCreateSampler); + LOAD_FUNC(clReleaseSampler); + LOAD_FUNC(clCreateImage); + LOAD_FUNC(clEnqueueWriteImage); + LOAD_FUNC(clEnqueueReadImage); + LOAD_FUNC(clEnqueueWriteBufferRect); + LOAD_FUNC(clEnqueueReadBufferRect); + LOAD_FUNC(clReleaseDevice); + LOAD_FUNC(clRetainDevice); + LOAD_FUNC(clCreateCommandQueueWithProperties); + LOAD_FUNC(clRetainCommandQueue); + LOAD_FUNC(clSVMAlloc); + LOAD_FUNC(clSVMFree); + LOAD_FUNC(clEnqueueSVMMap); + LOAD_FUNC(clEnqueueSVMUnmap); + LOAD_FUNC(clSetKernelArgSVMPointer); + LOAD_FUNC(clCreateSubBuffer); + LOAD_FUNC(clEnqueueCopyBuffer); + LOAD_FUNC(clEnqueueCopyBufferToImage); + LOAD_FUNC(clEnqueueCopyBufferRect); + LOAD_FUNC(clWaitForEvents); + LOAD_FUNC(clGetEventProfilingInfo); + LOAD_FUNC(clReleaseEvent); + LOAD_FUNC(clEnqueueCopyImageToBuffer); + LOAD_FUNC(clEnqueueCopyImage); + LOAD_FUNC(clEnqueueCopyBufferRect); + LOAD_FUNC(clGetMemObjectInfo); + LOAD_FUNC(clEnqueueMapBuffer); + LOAD_FUNC(clEnqueueUnmapMemObject); + +#undef LOAD_FUNC } +#endif -std::vector OpenCLBackend::runForward(Module *module, std::vector inputs, std::vector args) { - throw std::runtime_error("runForward not implemented for OpenCLBackend"); - return {}; +void OpenCLBackend::addProfilingEvent(const std::string &op_name, cl_event event) { + profiling_events_.push_back(event); + event_op_names_[event] = op_name; } +void OpenCLBackend::reportProfilingResult() { + if (profiling_events_.empty()) { + return; + } + + clWaitForEvents(profiling_events_.size(), profiling_events_.data()); + + std::cout << "--- OpenCL Kernel Profiling Report ---" << std::endl; + double total_duration_ms = 0.0; + for (cl_event event : profiling_events_) { + cl_ulong start_time, end_time; + clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &start_time, NULL); + clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &end_time, NULL); + + double duration_ms = (end_time - start_time) / 1000000.0; + std::cout << "OpenCL Operator [" << event_op_names_[event] << "] took " << duration_ms << " ms" << std::endl; + total_duration_ms += duration_ms; + clReleaseEvent(event); + } + std::cout << "---- Total Duration: " << total_duration_ms << " ms ---" << std::endl; + + // 清空 + profiling_events_.clear(); + event_op_names_.clear(); +} } // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/OpenCLBackend.hpp b/src/backends/opencl/OpenCLBackend.hpp index 985e30209..e33c4a277 100644 --- a/src/backends/opencl/OpenCLBackend.hpp +++ b/src/backends/opencl/OpenCLBackend.hpp @@ -7,106 +7,115 @@ #include #include #include - +#include #ifdef __APPLE__ #include #else #include #endif -// 外部函数声明,用于错误检查 -// void check_cl_error(cl_int err, const std::string& operation); - namespace mllm { struct DeviceMemory; -class Tensor; +class Layer; + +// 【关键修正 1】: 在类定义之前,提供 OpenCLSymbols 的前向声明 +#if defined(MLLM_TARGET_ANDROID) +struct OpenCLSymbols; +#endif class OpenCLBackend : public Backend { public: - - // 为工厂模式定义的 Creator 基类 class Creator { public: virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const = 0; virtual ~Creator() = default; }; - OpenCLBackend(const BackendConfig &config); ~OpenCLBackend() override; - // --- OpenCL 特有方法 --- - cl_context getContext() const { return context_; } - cl_device_id getDevice() const { return device_; } - cl_command_queue getQueue() const { return queue_; } + cl_context getContext() const { + return context_; + } + cl_device_id getDevice() const { + return device_; + } + cl_command_queue getQueue() const { + return queue_; + } void finishQueue(); - // 获取或编译并缓存 Kernel Program - cl_program getProgram(const std::string& program_name, const std::string& build_options = ""); + cl_program getProgram(const std::string &program_name, const std::string &build_options = ""); - // --- 实现基类的纯虚函数 --- Op *opCreate(const OpParam &op_param, std::string name = "", int threadCount = 4) override; TensorFunction *funcCreate(TensorFuncType type) override; - void alloc_device(DeviceMemory &mem, DataType dtype) override; void free_device(DeviceMemory &mem) override; void copy_from_host(const DeviceMemory &dest, const void *src) override; void copy_to_host(void *dest, const DeviceMemory &src) override; - - // 注意:下面几个函数的具体实现依赖于你的框架逻辑,这里暂时提供桩实现 (stub) std::vector runLayer(Layer *layer, std::vector inputs, int N) override; std::vector runOp(Op *op, std::vector input, std::vector out_names, bool in_place) override; std::vector runForward(Module *module, std::vector inputs, std::vector args) override; - void registerOps() override; void registerFuncs() override; void convert_fp_data(Tensor *src, Tensor *dest) override; + bool load_from_file(Tensor *tensor, ParamLoader *loader) override; cl_mem get_cl_mem(const Tensor &tensor) const; - /** - * @brief 检查当前设备是否支持从Buffer创建Image的零拷贝扩展。 - */ - bool is_image_from_buffer_supported() const { return image_from_buffer_supported_; } + bool is_image_from_buffer_supported() const { + return image_from_buffer_supported_; + } + cl_uint get_image_pitch_alignment_in_bytes() const { + return image_pitch_alignment_bytes_; + } + // bool &has_fp16_support() { + // return has_fp16_support_; + // } + bool has_fp16_support() const { // 1. 移除引用'&' 2. 增加const关键字 + return has_fp16_support_; + } + void addProfilingEvent(const std::string &op_name, cl_event event); + void reportProfilingResult(); // 新增分析结果的函数 - /** - * @brief 获取设备要求的Image行间距对齐字节数。 - */ - cl_uint get_image_pitch_alignment_in_bytes() const { return image_pitch_alignment_bytes_; } + size_t getMaxImage2dWidth() const { + return max_image2d_width_; + } +#if defined(MLLM_TARGET_ANDROID) +public: + // 【关键修正 2】: getSymbols 的声明保持 public,返回一个指向前向声明类型的指针 + static OpenCLSymbols *getSymbols(); +private: + static void loadOpenCLSymbols(); + static OpenCLSymbols symbols_; +#endif private: - // 构造函数辅助函数,用于解决基类和子类成员的初始化顺序问题 - static std::shared_ptr createMemoryManager(cl_context& context, cl_device_id& device); - + static std::shared_ptr createMemoryManager(cl_context &context, cl_device_id &device); + cl_context context_ = nullptr; cl_device_id device_ = nullptr; cl_command_queue queue_ = nullptr; - // 内核程序缓存 std::map program_cache_; std::map> op_creator_map_; - /** - * @brief 标记设备是否支持 cl_khr_image2d_from_buffer 扩展。 - */ bool image_from_buffer_supported_ = false; - - /** - * @brief 存储硬件要求的Image行间距对齐字节数。 - */ cl_uint image_pitch_alignment_bytes_ = 0; - /** - * @brief 标记设备是否支持 cl_khr_fp16 扩展。 - */ bool has_fp16_support_ = false; -private: + + size_t max_image2d_width_ = 0; + std::string kernel_root_path_; + cl_kernel kernel_fp32_to_fp16_buffer_ = nullptr; cl_kernel kernel_fp16_to_fp32_buffer_ = nullptr; - cl_kernel kernel_fp32_to_fp16_image_ = nullptr; // 新增 - cl_kernel kernel_fp16_to_fp32_image_ = nullptr; // 新增 + cl_kernel kernel_fp32_to_fp16_image_ = nullptr; + cl_kernel kernel_fp16_to_fp32_image_ = nullptr; cl_sampler sampler_ = nullptr; -}; + std::vector profiling_events_; + std::map event_op_names_; +}; class OpenCLBackendCreator : public BackendCreator { public: @@ -115,7 +124,6 @@ class OpenCLBackendCreator : public BackendCreator { } }; - } // namespace mllm #endif // OPENCL_BACKEND_H \ No newline at end of file diff --git a/src/backends/opencl/OpenCLMemoryManager.cpp b/src/backends/opencl/OpenCLMemoryManager.cpp index 0db3dd32c..d94e0e0d0 100644 --- a/src/backends/opencl/OpenCLMemoryManager.cpp +++ b/src/backends/opencl/OpenCLMemoryManager.cpp @@ -1,27 +1,64 @@ + + #include "OpenCLMemoryManager.hpp" #include +#include // 用于调试输出 namespace mllm { -OpenCLMemoryManager::OpenCLMemoryManager(cl_context context) : context_(context) { +OpenCLMemoryManager::OpenCLMemoryManager(cl_context context) : + context_(context) { assert(context_ != nullptr); } +OpenCLMemoryManager::~OpenCLMemoryManager() { + std::lock_guard lock(pool_mutex_); + for (auto const &[size, buffer] : memory_pool_) { + if (buffer) { + clReleaseMemObject(buffer); + } + } + memory_pool_.clear(); +} + void OpenCLMemoryManager::alloc(void **ptr, size_t size, size_t alignment) { assert(ptr != nullptr); assert(size > 0); - cl_int err; - // 分配一个可供GPU内核读写的设备缓冲区 - cl_mem buffer = clCreateBuffer(context_, CL_MEM_READ_WRITE, size, nullptr, &err); - check_cl_error(err, "OpenCLMemoryManager::clCreateBuffer"); - *ptr = buffer; + std::lock_guard lock(pool_mutex_); + auto it = memory_pool_.lower_bound(size); + + if (it != memory_pool_.end()) { + // 找到了合适的内存块 + cl_mem buffer = it->second; // 获取内存句柄 + memory_pool_.erase(it); // 从池中移除 + *ptr = buffer; // 将句柄赋给指针 + // std::cout << "[OpenCL Memory Pool] Reused buffer of size " << it->first << " for request of " << size << std::endl; + } else { + // 如果池中没有合适的内存块,则分配新的内存 + cl_int err; + cl_mem buffer = clCreateBuffer(context_, CL_MEM_READ_WRITE, size, nullptr, &err); + check_cl_error(err, "OpenCLMemoryManager::clCreateBuffer (new allocation)"); + *ptr = buffer; + // std::cout << "[OpenCL Memory Pool] Allocated new buffer of size " << size << std::endl; + } } void OpenCLMemoryManager::free(void *ptr) { if (ptr != nullptr) { + std::lock_guard lock(pool_mutex_); cl_mem buffer = static_cast(ptr); - clReleaseMemObject(buffer); + + size_t buffer_size = 0; + cl_int err = clGetMemObjectInfo(buffer, CL_MEM_SIZE, sizeof(size_t), &buffer_size, nullptr); + check_cl_error(err, "OpenCLMemoryManager::clGetMemObjectInfo (on free)"); + + if (buffer_size > 0) { + memory_pool_.insert({buffer_size, buffer}); + // std::cout << "[OpenCL Memory Pool] Returned buffer of size " << buffer_size << " to pool." << std::endl; + } else { + clReleaseMemObject(buffer); + } } } diff --git a/src/backends/opencl/OpenCLMemoryManager.hpp b/src/backends/opencl/OpenCLMemoryManager.hpp index 77571a6bd..b63587afb 100644 --- a/src/backends/opencl/OpenCLMemoryManager.hpp +++ b/src/backends/opencl/OpenCLMemoryManager.hpp @@ -2,7 +2,9 @@ #define OPENCL_MEMORY_MANAGER_H #include "MemoryManager.hpp" -#include // For std::string in check_cl_error +#include +#include // 引入map用于内存池 +#include // 引入mutex用于线程安全 #ifdef __APPLE__ #include @@ -10,21 +12,25 @@ #include #endif -// 前向声明,实现在 backend.cpp 中 -void check_cl_error(cl_int err, const std::string& operation); +void check_cl_error(cl_int err, const std::string &operation); namespace mllm { class OpenCLMemoryManager : public MemoryManager { public: explicit OpenCLMemoryManager(cl_context context); - ~OpenCLMemoryManager() override = default; + + ~OpenCLMemoryManager() override; void alloc(void **ptr, size_t size, size_t alignment) override; void free(void *ptr) override; private: cl_context context_; // 需要OpenCL上下文来创建缓冲区 + + std::multimap memory_pool_; + + std::mutex pool_mutex_; }; } // namespace mllm diff --git a/src/backends/opencl/kernel/add.cl b/src/backends/opencl/kernel/add.cl index 06529f25b..1f46ea6c3 100644 --- a/src/backends/opencl/kernel/add.cl +++ b/src/backends/opencl/kernel/add.cl @@ -1,12 +1,11 @@ __kernel void add_float( - __global const float* A, - __global const float* B, - __global float* C) { + __global const float *A, + __global const float *B, + __global float *C) { size_t index = get_global_id(0); C[index] = A[index] + B[index]; } - /* * 定义一个全局的采样器(sampler)。采样器是用于配置如何从图像对象中读取数据的。 * CLK_NORMALIZED_COORDS_FALSE: 使用非归一化的整数坐标(像素坐标),而不是[0.0, 1.0]的浮点坐标。 @@ -24,13 +23,12 @@ __kernel void add_float( * @param height 图像的逻辑高度(单位:像素)。 */ __kernel void add_float_image2d( - sampler_t sampler, // 采样器现在是第一个参数 + sampler_t sampler, // 采样器现在是第一个参数 __read_only image2d_t inputA, __read_only image2d_t inputB, __write_only image2d_t output, const int width, - const int height) -{ + const int height) { const int2 pos = (int2)(get_global_id(0), get_global_id(1)); if (pos.x >= width || pos.y >= height) { @@ -43,10 +41,6 @@ __kernel void add_float_image2d( write_imagef(output, pos, result); } - - - - #pragma OPENCL EXTENSION cl_khr_fp16 : enable /** @@ -57,10 +51,9 @@ __kernel void add_float_image2d( * @param C 输出张量 C (__global half*) */ __kernel void add_fp16_vector( - __global const half* A, - __global const half* B, - __global half* C) -{ + __global const half *A, + __global const half *B, + __global half *C) { const int i = get_global_id(0); // 高效地加载 4 个 half (共64位) 数据 @@ -90,8 +83,7 @@ __kernel void add_fp16_image2d( __read_only image2d_t inputB, __write_only image2d_t output, const int width, - const int height) -{ + const int height) { const int2 pos = (int2)(get_global_id(0), get_global_id(1)); if (pos.x >= width || pos.y >= height) { @@ -107,3 +99,73 @@ __kernel void add_fp16_image2d( // 使用 write_imageh 写回 half4 向量 write_imageh(output, pos, result); } + +// ================================================================== +// 4. Tensor + Scalar 内核 +// ================================================================== + +/** + * @brief [FP32 Buffer版] 将一个标量 `B` 加到张量 `A` 的每个元素上。 + */ +__kernel void add_scalar_float( + __global const float *A, + const float B, + __global float *C) { + size_t index = get_global_id(0); + C[index] = A[index] + B; +} + +/** + * @brief [FP16 Buffer版] 使用向量指令将一个标量 `B` 加到张量 `A` 的每个元素上。 + */ +__kernel void add_scalar_fp16_vector( + __global const half *A, + const half B, + __global half *C) { + const int i = get_global_id(0); + half4 a_vec = vload4(i, A); + // 将标量 B 广播成一个 half4 向量 + half4 b_vec = (half4)(B); + half4 c_vec = a_vec + b_vec; + vstore4(c_vec, i, C); +} + +/** + * @brief [FP32 Image版] 将一个标量 `B` 加到张量 `A` 的每个像素上。 + */ +__kernel void add_scalar_float_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const float B, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + + float4 inA = read_imagef(inputA, sampler, pos); + // 将标量 B 广播成一个 float4 向量 + float4 inB = (float4)(B); + float4 result = inA + inB; + write_imagef(output, pos, result); +} + +/** + * @brief [FP16 Image版] 将一个标量 `B` 加到张量 `A` 的每个像素上。 + */ +__kernel void add_scalar_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const half B, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + + half4 inA = read_imageh(inputA, sampler, pos); + // 将标量 B 广播成一个 half4 向量 + half4 inB = (half4)(B); + half4 result = inA + inB; + write_imageh(output, pos, result); +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/argsort.cl b/src/backends/opencl/kernel/argsort.cl new file mode 100644 index 000000000..ca0451afc --- /dev/null +++ b/src/backends/opencl/kernel/argsort.cl @@ -0,0 +1,256 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// ============================================================================ +// 通用内核 (FP32 和 索引初始化) +// ============================================================================ + +/** + * @brief 初始化索引数组,值为 0, 1, 2, ..., N-1。 + */ +__kernel void init_indices( + __global int *indices, + const int N) { + const int gid = get_global_id(0); + const int local_idx = gid % N; + indices[gid] = local_idx; +} + +/** + * @brief Bitonic Sort 的一个步骤 (FP32 版本)。 + */ +__kernel void bitonic_argsort_step_fp32( + __global float *values, + __global int *indices, + const int N, + const int stage, + const int pass, + const int descending) { + const int i = get_global_id(0); + const int row = get_global_id(1); + int k = 1 << pass; + int j = i & (k - 1); + int ix = (i << 1) - j; + int iy = ix + k; + int sort_increasing = ((ix >> (stage + 1)) & 1) == 0; + if (descending) { + sort_increasing = !sort_increasing; + } + + if (ix < N) { // 仅当比较对的第一个元素在界内时才处理 + const int row_offset = row * N; + const int global_ix = row_offset + ix; + const int global_iy = row_offset + iy; + + float val1 = values[global_ix]; + // 如果 iy 越界, 根据排序方向,将其值视作 INFINITY (无穷大) 或 -INFINITY (负无穷大) + float val2 = (iy < N) ? values[global_iy] : (descending ? -INFINITY : INFINITY); + + if ((val1 > val2) == sort_increasing) { + // 当需要交换时,只对真实存在的元素进行写操作 + int index_from_ix = indices[global_ix]; + int index_from_iy = (iy < N) ? indices[global_iy] : -1; // 用-1作为无效索引哨兵 + + values[global_ix] = val2; + indices[global_ix] = index_from_iy; + + // 只有当 iy 也在界内时,才把 val1 的值和原始索引写入 iy 位置 + if (iy < N) { + values[global_iy] = val1; + indices[global_iy] = index_from_ix; + } + } + } +} + +/** + * @brief 将排序后的 int 类型索引转换为 float 类型并写入输出。 + */ +__kernel void cast_indices_to_fp32( + __global const int *sorted_indices, + __global float *output) { + const int gid = get_global_id(0); + output[gid] = (float)sorted_indices[gid]; +} + +// ============================================================================ +// FP16 内核 (根据硬件支持情况进行条件编译) +// ============================================================================ + +#if defined(SUPPORTS_FP16) + +// =================== 方案A: 设备支持原生 FP16 ===================== + +/** + * @brief Bitonic Sort 的一个步骤 (原生FP16版本)。 + */ +__kernel void bitonic_argsort_step_fp16( + __global half *values, + __global int *indices, + const int N, + const int stage, + const int pass, + const int descending) { + const int i = get_global_id(0); + const int row = get_global_id(1); + int k = 1 << pass; + int j = i & (k - 1); + int ix = (i << 1) - j; + int iy = ix + k; + int sort_increasing = ((ix >> (stage + 1)) & 1) == 0; + if (descending) { + sort_increasing = !sort_increasing; + } + + if (ix < N) { + const int row_offset = row * N; + const int global_ix = row_offset + ix; + const int global_iy = row_offset + iy; + + half val1 = values[global_ix]; + + // ====================== ✨✨✨ 核心修正区域 as_half ✨✨✨ ====================== + // 修正: 显式地将整型字面量转换为 ushort (16-bit) 来解决 as_half 的歧义 + half infinity_h = as_half((ushort)0x7C00); + half neg_infinity_h = as_half((ushort)0xFC00); + // ========================================================================== + + half val2 = (iy < N) ? values[global_iy] : (descending ? neg_infinity_h : infinity_h); + + if ((val1 > val2) == sort_increasing) { + int index_from_ix = indices[global_ix]; + int index_from_iy = (iy < N) ? indices[global_iy] : -1; + + values[global_ix] = val2; + indices[global_ix] = index_from_iy; + + if (iy < N) { + values[global_iy] = val1; + indices[global_iy] = index_from_ix; + } + } + } +} + +/** + * @brief 将排序后的 int 类型索引转换为 half 类型并写入输出。 + */ +__kernel void cast_indices_to_fp16( + __global const int *sorted_indices, + __global half *output) { + const int gid = get_global_id(0); + output[gid] = (half)sorted_indices[gid]; +} + +#else + +// =================== 方案B: 软件模拟 FP16 (兼容版) ===================== +// ✨✨✨ 核心修正区域:严格仿照您的榜样代码 ✨✨✨ + +// 辅助函数: 将 ushort (存储着 half 的二进制位) 转换为 float +// (该函数仿照您项目中的 kernel/convert_fp.cl 和 scatter_add.cl) +static float ushort_to_float(ushort u) { + uint sign = (u >> 15) & 1; + uint exponent = (u >> 10) & 0x1F; + uint mantissa = u & 0x3FF; + uint result_uint; + if (exponent == 0) { + if (mantissa == 0) { + result_uint = sign << 31; + } else { + exponent = 1; + while ((mantissa & 0x400) == 0) { + mantissa <<= 1; + exponent++; + } + mantissa &= 0x3FF; + exponent = 127 - 15 - exponent + 1; + result_uint = (sign << 31) | (exponent << 23) | (mantissa << 13); + } + } else if (exponent == 0x1F) { + result_uint = (sign << 31) | (0xFF << 23) | (mantissa << 13); + } else { + exponent = exponent - 15 + 127; + result_uint = (sign << 31) | (exponent << 23) | (mantissa << 13); + } + return as_float(result_uint); +} + +// 辅助函数: 将 float 转换为 ushort +static ushort float_to_ushort(float f) { + uint u = as_uint(f); + uint sign = (u >> 16) & 0x8000; + int exponent = ((u >> 23) & 0xFF) - 127; + uint mantissa = u & 0x7FFFFF; + if (exponent > 15) { + return sign | 0x7C00; + } // Infinity + if (exponent < -14) { + mantissa = (mantissa | 0x800000) >> (1 - exponent); + return sign | (mantissa >> 13); + } + return sign | ((exponent + 15) << 10) | (mantissa >> 13); +} + +/** + * @brief Bitonic Sort 的一个步骤 (兼容版FP16)。 + * 使用与原生版相同的名称,但输入输出为 ushort*。 + */ +__kernel void bitonic_argsort_step_fp16( + __global ushort *values, // 数据以 ushort 形式存储 + __global int *indices, + const int N, + const int stage, + const int pass, + const int descending) { + const int i = get_global_id(0); + const int row = get_global_id(1); + int k = 1 << pass; + int j = i & (k - 1); + int ix = (i << 1) - j; + int iy = ix + k; + int sort_increasing = ((ix >> (stage + 1)) & 1) == 0; + if (descending) { + sort_increasing = !sort_increasing; + } + + if (ix < N) { + const int row_offset = row * N; + const int global_ix = row_offset + ix; + const int global_iy = row_offset + iy; + + // 核心: 读出 ushort, 转换为 float 进行比较 + float val1 = ushort_to_float(values[global_ix]); + float val2 = (iy < N) ? ushort_to_float(values[global_iy]) : (descending ? -INFINITY : INFINITY); + + if ((val1 > val2) == sort_increasing) { + // 交换时,直接交换原始的 ushort 值 + ushort val_from_ix = values[global_ix]; + // 如果 iy 越界,需要一个代表无穷大的 ushort 值 + ushort val_from_iy = (iy < N) ? values[global_iy] : float_to_ushort(val2); + values[global_ix] = val_from_iy; + + // 交换索引 + int temp_idx_from_ix = indices[global_ix]; + int temp_idx_from_iy = (iy < N) ? indices[global_iy] : -1; + indices[global_ix] = temp_idx_from_iy; + + if (iy < N) { + values[global_iy] = val_from_ix; + indices[global_iy] = temp_idx_from_ix; + } + } + } +} + +/** + * @brief 将排序后的 int 类型索引转换为 ushort 类型并写入输出 (兼容版)。 + */ +__kernel void cast_indices_to_fp16( + __global const int *sorted_indices, + __global ushort *output) { // 输出是 ushort* + const int gid = get_global_id(0); + // 先将 int 转为 float, 再将 float 的二进制位表示转为 ushort + output[gid] = float_to_ushort((float)sorted_indices[gid]); +} + +#endif // SUPPORTS_FP16 \ No newline at end of file diff --git a/src/backends/opencl/kernel/bincount.cl b/src/backends/opencl/kernel/bincount.cl new file mode 100644 index 000000000..8aa74430b --- /dev/null +++ b/src/backends/opencl/kernel/bincount.cl @@ -0,0 +1,107 @@ +// opencl/kernel/bincount.cl + +#if defined(SUPPORTS_FP16) +#pragma OPENCL EXTENSION cl_khr_fp16 : enable +#endif + +// ===================== FP16 (ushort) <-> FP32 (float) 转换辅助函数 ===================== +// 只有在不支持原生 FP16 时才需要 +#if !defined(SUPPORTS_FP16) +static float ushort_to_float(ushort u) { + uint sign = (u >> 15) & 1; + uint exponent = (u >> 10) & 0x1F; + uint mantissa = u & 0x3FF; + if (exponent == 0x1F) { return as_float((sign << 31) | (0xFF << 23) | (mantissa << 13)); } + if (exponent == 0) { + if (mantissa == 0) { return as_float(sign << 31); } + exponent = 1; + while ((mantissa & 0x400) == 0) { + mantissa <<= 1; + exponent++; + } + mantissa &= 0x3FF; + exponent = 127 - 15 - exponent + 1; + return as_float((sign << 31) | (exponent << 23) | (mantissa << 13)); + } + return as_float((sign << 31) | ((exponent - 15 + 127) << 23) | (mantissa << 13)); +} + +static ushort float_to_ushort(float f) { + uint u = as_uint(f); + uint sign = (u >> 16) & 0x8000; + int exponent = ((u >> 23) & 0xFF) - 127; + uint mantissa = u & 0x7FFFFF; + if (exponent > 15) { return sign | 0x7C00; } + if (exponent < -14) { + mantissa = (mantissa | 0x800000) >> (1 - exponent); + return sign | (mantissa >> 13); + } + return sign | ((exponent + 15) << 10) | (mantissa >> 13); +} +#endif + +// ========================== 内核 1: 执行 Bincount 到整数缓冲区 ========================== +__kernel void bincount_count( +#if defined(SUPPORTS_FP16) + __global const half *input, +#else + __global const ushort *input, +#endif + __global int *out_counts, + const int size, + const int max_val) { + + for (int i = get_global_id(0); i < size; i += get_global_size(0)) { + float val; +#if defined(SUPPORTS_FP16) + val = input[i]; +#else + val = ushort_to_float(input[i]); +#endif + int index = (int)val; + if (index >= 0 && index <= max_val) { + atomic_add(&out_counts[index], 1); + } + } +} + +// Float32 版本的 bincount 内核 +__kernel void bincount_count_fp32( + __global const float *input, + __global int *out_counts, + const int size, + const int max_val) { + for (int i = get_global_id(0); i < size; i += get_global_size(0)) { + int index = (int)input[i]; + if (index >= 0 && index <= max_val) { + atomic_add(&out_counts[index], 1); + } + } +} + +// ========================== 内核 2: 将整数计数转换为 FP32/FP16 ========================== +__kernel void cast_int_to_float( + __global const int *int_buffer, + __global float *float_buffer, + const int count) { + for (int i = get_global_id(0); i < count; i += get_global_size(0)) { + float_buffer[i] = (float)int_buffer[i]; + } +} + +__kernel void cast_int_to_half( + __global const int *int_buffer, +#if defined(SUPPORTS_FP16) + __global half *half_buffer, +#else + __global ushort *half_buffer, +#endif + const int count) { + for (int i = get_global_id(0); i < count; i += get_global_size(0)) { +#if defined(SUPPORTS_FP16) + half_buffer[i] = (half)int_buffer[i]; +#else + half_buffer[i] = float_to_ushort((float)int_buffer[i]); +#endif + } +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/cliptensor.cl b/src/backends/opencl/kernel/cliptensor.cl new file mode 100644 index 000000000..7a83fced0 --- /dev/null +++ b/src/backends/opencl/kernel/cliptensor.cl @@ -0,0 +1,102 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// Kernel for clipping along the SEQUENCE dimension +__kernel void clip_sequence_fp32( + __global const float *src_data, + __global const float *indices, + __global float *dst_data, + const int B, const int H, const int S_in, const int D, const int S_out) { + // Each work-item handles one element in the H*D plane of the output + const int d = get_global_id(0); + const int h = get_global_id(1); + const int bs = get_global_id(2); // Combined batch and output sequence index + + const int b = bs / S_out; + const int s_out = bs % S_out; + + if (d >= D || h >= H || b >= B) { + return; + } + + // Get the source sequence index from the indices tensor + const int s_in = (int)indices[s_out]; + + // Assuming BSHD layout for both input and output + // src_offset for [b, s_in, h, d] + size_t src_offset = ((size_t)b * S_in + s_in) * H * D + (size_t)h * D + d; + // dst_offset for [b, s_out, h, d] + size_t dst_offset = ((size_t)b * S_out + s_out) * H * D + (size_t)h * D + d; + + dst_data[dst_offset] = src_data[src_offset]; +} + +// Kernel for clipping along the DIMENSION dimension +__kernel void clip_dimension_fp32( + __global const float *src_data, + __global const float *indices, + __global float *dst_data, + const int B, const int H, const int S, const int D_in, const int D_out) { + // Each work-item handles one element in the output tensor + const int d_out = get_global_id(0); + const int s = get_global_id(1); + const int bh = get_global_id(2); + const int b = bh / H; + const int h = bh % H; + + if (d_out >= D_out || s >= S || b >= B) { + return; + } + + // Get the source dimension index from the indices tensor + const int d_in = (int)indices[d_out]; + + // Assuming BSHD layout for both input and output + // src_offset for [b, s, h, d_in] + size_t src_offset = ((size_t)b * S + s) * H * D_in + (size_t)h * D_in + d_in; + // dst_offset for [b, s, h, d_out] + size_t dst_offset = ((size_t)b * S + s) * H * D_out + (size_t)h * D_out + d_out; + + dst_data[dst_offset] = src_data[src_offset]; +} + +// ========================== FP16 Versions ============================== + +__kernel void clip_sequence_fp16( + __global const half *src_data, + __global const half *indices, + __global half *dst_data, + const int B, const int H, const int S_in, const int D, const int S_out) { + const int d = get_global_id(0); + const int h = get_global_id(1); + const int bs = get_global_id(2); + const int b = bs / S_out; + const int s_out = bs % S_out; + + if (d >= D || h >= H || b >= B) { + return; + } + const int s_in = (int)indices[s_out]; + size_t src_offset = ((size_t)b * S_in + s_in) * H * D + (size_t)h * D + d; + size_t dst_offset = ((size_t)b * S_out + s_out) * H * D + (size_t)h * D + d; + dst_data[dst_offset] = src_data[src_offset]; +} + +__kernel void clip_dimension_fp16( + __global const half *src_data, + __global const half *indices, + __global half *dst_data, + const int B, const int H, const int S, const int D_in, const int D_out) { + const int d_out = get_global_id(0); + const int s = get_global_id(1); + const int bh = get_global_id(2); + const int b = bh / H; + const int h = bh % H; + + if (d_out >= D_out || s >= S || b >= B) { + return; + } + const int d_in = (int)indices[d_out]; + size_t src_offset = ((size_t)b * S + s) * H * D_in + (size_t)h * D_in + d_in; + size_t dst_offset = ((size_t)b * S + s) * H * D_out + (size_t)h * D_out + d_out; + dst_data[dst_offset] = src_data[src_offset]; +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/convert_fp.cl b/src/backends/opencl/kernel/convert_fp.cl index d1e3a3314..ed3d7db09 100644 --- a/src/backends/opencl/kernel/convert_fp.cl +++ b/src/backends/opencl/kernel/convert_fp.cl @@ -1,96 +1,142 @@ +// =================================================================== +// **部分一:兼容模式内核(适用于无原生FP16支持的硬件)** +// =================================================================== -// 将一个32位float转换为16位ushort (模拟FP16) +// 将一个32位float稳健地转换为16位ushort (模拟FP16) ushort float_to_half_bits(const float f) { + // 将 float 的位模式存储在 uint 中 const uint u = as_uint(f); - const uint sign = (u >> 16) & 0x8000; - uint exponent = ((u >> 23) & 0xff) - 127; - uint mantissa = u & 0x7fffff; - - if (exponent > 15) return sign | 0x7c00; + // 1. 正确提取各部分 + // 提取符号位 (bit 31) + const uint sign_bit = u & 0x80000000; + // 提取指数位 (bits 30-23) + int exponent = (int)((u >> 23) & 0xff) - 127; // FP32 bias is 127 + // 提取尾数位 (bits 22-0) + uint mantissa = u & 0x007fffff; + // 将32位符号位移动到16位的位置 + const ushort half_sign = (ushort)(sign_bit >> 16); + // 2. 处理特殊值:NaN 和 Infinity + if (exponent == 128) { // FP32 exponent is all 1s + if (mantissa == 0) { + // FP32 is Infinity, convert to FP16 Infinity + return half_sign | 0x7c00; + } else { + // FP32 is NaN, convert to FP16 NaN + // 保留尾数最高位以标识为NaN + return half_sign | 0x7c00 | (ushort)(mantissa >> 13); + } + } + // 3. 处理上溢到 Infinity + if (exponent > 15) { // Exponent too large for FP16 normal + return half_sign | 0x7c00; // Overflow -> Infinity + } + // 4. 处理正规数 (Normal Numbers) if (exponent >= -14) { - exponent = (exponent + 15) << 10; - mantissa >>= 13; - return sign | exponent | mantissa; + // 将FP32指数转换为FP16指数 (FP16 bias is 15) + ushort half_exponent = (ushort)(exponent + 15); + // 添加被截断部分的最高位,以实现简单的“四舍五入” + mantissa = mantissa + (1 << 12); + // 如果舍入导致尾数上溢,需要调整指数 + if (mantissa & 0x00800000) { + mantissa = 0; + half_exponent++; + if (half_exponent == 31) { // 溢出到 Infinity + return half_sign | 0x7c00; + } + } + ushort half_mantissa = (ushort)(mantissa >> 13); + return half_sign | (half_exponent << 10) | half_mantissa; } + // 5. 处理非正规数 (Denormalized Numbers) if (exponent >= -24) { - mantissa = (mantissa | 0x800000) >> (14 - (-exponent)); - return sign | mantissa; + // 加上隐藏位,然后根据指数进行移位 + mantissa = (mantissa | 0x00800000) >> (14 - exponent); + // 同样可以增加舍入逻辑 + mantissa += 1; + return half_sign | (ushort)(mantissa >> 1); } - return sign; + // 6. 处理下溢到 0 + return half_sign; // Underflow -> Zero } -// 将一个16位ushort (模拟FP16) 转换回32位float +// [已优化] 将一个16位ushort (模拟FP16) 转换回32位float float half_bits_to_float(const ushort h) { - const uint sign = (h >> 15) & 1; - uint exponent = (h >> 10) & 0x1f; - uint mantissa = h & 0x3ff; + const uint sign = (uint)(h & 0x8000) << 16; + uint exponent = (h & 0x7c00) >> 10; + uint mantissa = h & 0x03ff; - if (exponent == 0x1f) return as_float((sign << 31) | 0x7f800000 | (mantissa << 13)); - if (exponent == 0) { - if (mantissa == 0) return as_float(sign << 31); - mantissa <<= 1; - while ((mantissa & 0x400) == 0) { mantissa <<= 1; exponent--; } - mantissa &= 0x3ff; exponent += 1; + if (exponent == 0x1f) { // Infinity or NaN + // 直接构造对应的FP32 Infinity/NaN + return as_float(sign | 0x7f800000 | (mantissa << 13)); } + + if (exponent == 0) { // Zero or Denormal + if (mantissa == 0) { // Zero + return as_float(sign); + } + // Denormalized: 找到隐藏的 '1' + while ((mantissa & 0x0400) == 0) { + mantissa <<= 1; + exponent--; + } + exponent++; // 补偿循环多减的一次 + mantissa &= 0x03ff; // 移除隐藏的 '1' + } + + // 转换为FP32的指数和尾数 exponent = exponent + (127 - 15); - mantissa <<= 13; - return as_float((sign << 31) | (exponent << 23) | mantissa); + mantissa = mantissa << 13; + + return as_float(sign | (exponent << 23) | mantissa); } __kernel void convert_fp32_to_fp16_buffer_compat( // 兼容版内核 - __global const float* input, - __global ushort* output, - const int count) -{ + __global const float *input, + __global ushort *output, + const int count) { int i = get_global_id(0); if (i < count) output[i] = float_to_half_bits(input[i]); } __kernel void convert_fp16_to_fp32_buffer_compat( // 兼容版内核 - __global const ushort* input, - __global float* output, - const int count) -{ + __global const ushort *input, + __global float *output, + const int count) { int i = get_global_id(0); if (i < count) output[i] = half_bits_to_float(input[i]); } // =================================================================== // **部分二:高性能内核(需要硬件原生支持FP16)** -// 只有在C++端定义了 "SUPPORTS_FP16" 宏时,这部分代码才会被编译。 // =================================================================== #ifdef SUPPORTS_FP16 #pragma OPENCL EXTENSION cl_khr_fp16 : enable // --- Buffer Kernels (高性能版) --- -__kernel void convert_fp32_to_fp16_buffer_ext( // 高性能版内核 - __global const float* input, - __global half* output, - const int count) -{ +__kernel void convert_fp32_to_fp16_buffer_ext( + __global const float *input, + __global half *output, + const int count) { int i = get_global_id(0); if (i < count) output[i] = convert_half(input[i]); } -__kernel void convert_fp16_to_fp32_buffer_ext( // 高性能版内核 - __global const half* input, - __global float* output, - const int count) -{ +__kernel void convert_fp16_to_fp32_buffer_ext( + __global const half *input, + __global float *output, + const int count) { int i = get_global_id(0); if (i < count) output[i] = vload_half(i, input); } // --- Image Kernels (高性能版) --- -// Image的FP16转换本身就依赖硬件支持,所以它只在高性能路径下才有意义。 __kernel void convert_fp32_to_fp16_image2d( sampler_t sampler, __read_only image2d_t input_fp32, __write_only image2d_t output_fp16, const int width, - const int height) -{ + const int height) { const int2 pos = (int2)(get_global_id(0), get_global_id(1)); if (pos.x >= width || pos.y >= height) return; float4 data_fp32 = read_imagef(input_fp32, sampler, pos); @@ -103,8 +149,7 @@ __kernel void convert_fp16_to_fp32_image2d( __read_only image2d_t input_fp16, __write_only image2d_t output_fp32, const int width, - const int height) -{ + const int height) { const int2 pos = (int2)(get_global_id(0), get_global_id(1)); if (pos.x >= width || pos.y >= height) return; half4 data_fp16 = read_imageh(input_fp16, sampler, pos); diff --git a/src/backends/opencl/kernel/div.cl b/src/backends/opencl/kernel/div.cl new file mode 100644 index 000000000..708bae408 --- /dev/null +++ b/src/backends/opencl/kernel/div.cl @@ -0,0 +1,362 @@ +// 文件名: kernel/div.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable +// ================================================================== +// 1. Tensor / Tensor Division Kernels (FP32) +// ================================================================== + +__kernel void div_float( + __global const float *A, + __global const float *B, + __global float *C, + const int b_dim, + const int a_dim) { + size_t index = get_global_id(0); + float b_val; + + // If b_dim is 1 and a_dim is greater than 1, apply broadcasting + if (b_dim == 1 && a_dim > 1) { + // Correct Broadcasting Logic: + // 1. Get the current d coordinate from the global index of A + int d_coord = index % a_dim; + // 2. Get the BSH part of the index for A + size_t a_bsh_index = index / a_dim; + // 3. Since B's dimension is 1, its BSH index is the same as its global index + size_t b_index = a_bsh_index; + // This is the correct index for B + b_val = B[b_index]; + } else { + // Original element-wise division + b_val = B[index]; + } + + // 添加保护防止除以零 + C[index] = b_val == 0.0f ? 0.0f : A[index] / b_val; +} + +__kernel void div_float_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + __read_only image2d_t inputB, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + float4 inA = read_imagef(inputA, sampler, pos); + float4 inB = read_imagef(inputB, sampler, pos); + // 添加保护防止除以零 + float4 result = (inB.x == 0.0f && inB.y == 0.0f && inB.z == 0.0f && inB.w == 0.0f) ? + (float4)(0.0f) : + inA / inB; + write_imagef(output, pos, result); +} + +// ================================================================== +// 2. Tensor / Scalar Division Kernels (FP32) +// ================================================================== + +__kernel void div_scalar_float( + __global const float *A, + const float B, + __global float *C) { + size_t index = get_global_id(0); + C[index] = B == 0.0f ? 0.0f : A[index] / B; +} + +__kernel void div_scalar_float_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const float B, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + float4 inA = read_imagef(inputA, sampler, pos); + float4 inB = (float4)(B); + float4 result = (B == 0.0f) ? (float4)(0.0f) : inA / inB; + write_imagef(output, pos, result); +} + +// ================================================================== +// FP16 Kernels Implementations with Preprocessor Guards +// ================================================================== + +#ifdef SUPPORTS_FP16 + +__kernel void div_fp16_vector( + __global const half *A, + __global const half *B, + __global half *C, + const int b_dim, + const int a_dim) { + const int i = get_global_id(0); + // If b_dim is 1 and a_dim is greater than 1, apply broadcasting + if (b_dim == 1 && a_dim > 1) { + // Broadcasting case with correct indexing + const int start_idx_A = i * 4; + for (int j = 0; j < 4; ++j) { + int current_idx_A = start_idx_A + j; + // Correct Broadcasting Logic: + size_t a_bsh_index = current_idx_A / a_dim; + size_t b_index = a_bsh_index; // This is the correct index for B + + half b_val = B[b_index]; + half a_val = A[current_idx_A]; + C[current_idx_A] = (b_val == (half)0.0h) ? (half)0.0h : a_val / b_val; + } + } else { + // Original element-wise vectorized division + half4 a_vec = vload4(i, A); + half4 b_vec = vload4(i, B); + // 添加保护防止除以零 (转换为 float 进行比较) + half4 c_vec = (all(convert_float4(b_vec) == 0.0f)) ? + (half4)(0.0h) : + a_vec / b_vec; + vstore4(c_vec, i, C); + } +} + +// 新增的标量内核,用于处理任意尺寸的张量 +__kernel void div_fp16_scalar( + __global const half *A, + __global const half *B, + __global half *C, + const int b_dim, + const int a_dim) { + size_t index = get_global_id(0); + half b_val; + if (b_dim == 1 && a_dim > 1) { + size_t a_bsh_index = index / a_dim; + size_t b_index = a_bsh_index; + b_val = B[b_index]; + } else { + b_val = B[index]; + } + C[index] = (b_val == (half)0.0h) ? (half)0.0h : A[index] / b_val; +} + +__kernel void div_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + __read_only image2d_t inputB, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + half4 inA = read_imageh(inputA, sampler, pos); + half4 inB = read_imageh(inputB, sampler, pos); + half4 result = (all(convert_float4(inB) == 0.0f)) ? (half4)(0.0h) : inA / inB; + write_imageh(output, pos, result); +} + +__kernel void div_scalar_fp16_vector( + __global const half *A, + const float B, + __global half *C) { + const int i = get_global_id(0); + float4 a_vec_f = convert_float4(vload4(i, A)); + + // B 已经是 float,无需转换 + float4 c_vec_f = a_vec_f / B; + vstore4(convert_half4_rte(c_vec_f), i, C); +} + +__kernel void div_scalar_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const float B, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { + return; + } + + // 1. 读取 half4 数据并立即提升到 float4 + float4 inA_f = convert_float4(read_imageh(inputA, sampler, pos)); + // 2. 在 float 精度下进行计算 + float4 result_f = inA_f / B; + // 3. 将结果转换回 half4 并写入 + write_imageh(output, pos, convert_half4_rte(result_f)); +} + +#else // !SUPPORTS_FP16 + +// ===================== B. FP16实现 (软件回退) ===================== +// 当硬件不支持时, 不使用'half'类型. +// 我们用'ushort'来存储16位数据, 并手动转换到'float'进行计算. +inline float half_to_float(ushort h) { + const uint s = (h >> 15) & 0x0001; + const uint e = (h >> 10) & 0x001f; + const uint f = h & 0x03ff; + uint float_val; + if (e == 0) { + if (f == 0) { // +0 or -0 + float_val = s << 31; + } else { // Denormalized number to normalized float + uint f_shifted = f; + uint e_shifted = e; + while ((f_shifted & 0x0400) == 0) { + f_shifted <<= 1; + e_shifted--; + } + e_shifted++; + f_shifted &= ~0x0400; + float_val = (s << 31) | ((e_shifted + 112) << 23) | (f_shifted << 13); + } + } else if (e == 31) { // Inf or NaN + if (f == 0) { // +/- Infinity + float_val = (s << 31) | 0x7f800000; + } else { // NaN + float_val = (s << 31) | 0x7f800000 | (f << 13); + } + } else { // Normalized number + float_val = (s << 31) | ((e + 112) << 23) | (f << 13); + } + + return as_float(float_val); +} + +// 帮助函数: 将 float 转换为 ushort (存储为half) +inline ushort float_to_half(float f) { + uint u = as_uint(f); + uint s = (u >> 16) & 0x8000; + int e = ((u >> 23) & 0xFF) - 127; + uint f_mant = u & 0x7FFFFF; + + if (e > 15) return (ushort)(s | 0x7C00); + if (e < -14) { + f_mant |= 0x800000; + return (ushort)(s | (f_mant >> (-e - 14))); + } + return (ushort)(s | ((e + 15) << 10) | (f_mant >> 13)); +} + +__kernel void div_fp16_vector( + __global const ushort *A, + __global const ushort *B, + __global ushort *C, + const int b_dim, + const int a_dim) { + const int i = get_global_id(0); + // If b_dim is 1 and a_dim is greater than 1, apply broadcasting + if (b_dim == 1 && a_dim > 1) { + const int start_idx_A = i * 4; + for (int j = 0; j < 4; ++j) { + int current_idx_A = start_idx_A + j; + // Correct Broadcasting Logic: + size_t a_bsh_index = current_idx_A / a_dim; + size_t b_index = a_bsh_index; + + float a_val = half_to_float(A[current_idx_A]); + float b_val = half_to_float(B[b_index]); + + float result = b_val == 0.0f ? + 0.0f : + a_val / b_val; + C[current_idx_A] = float_to_half(result); + } + } else { + // Original element-wise division for software fallback + const int start_idx = i * 4; + float4 a_vec = (float4)(half_to_float(A[start_idx]), half_to_float(A[start_idx + 1]), half_to_float(A[start_idx + 2]), half_to_float(A[start_idx + 3])); + float4 b_vec = (float4)(half_to_float(B[start_idx]), half_to_float(B[start_idx + 1]), half_to_float(B[start_idx + 2]), half_to_float(B[start_idx + 3])); + + float4 c_vec; + c_vec.x = b_vec.x == 0.0f ? 0.0f : a_vec.x / b_vec.x; + c_vec.y = b_vec.y == 0.0f ? + 0.0f : + a_vec.y / b_vec.y; + c_vec.z = b_vec.z == 0.0f ? 0.0f : a_vec.z / b_vec.z; + c_vec.w = b_vec.w == 0.0f ? 0.0f : a_vec.w / b_vec.w; + + C[start_idx] = float_to_half(c_vec.x); + C[start_idx + 1] = float_to_half(c_vec.y); + C[start_idx + 2] = float_to_half(c_vec.z); + C[start_idx + 3] = float_to_half(c_vec.w); + } +} + +// 新增的标量内核的软件回退实现 +__kernel void div_fp16_scalar( + __global const ushort *A, + __global const ushort *B, + __global ushort *C, + const int b_dim, + const int a_dim) { + size_t index = get_global_id(0); + float b_val; + + if (b_dim == 1 && a_dim > 1) { + size_t a_bsh_index = index / a_dim; + size_t b_index = a_bsh_index; + b_val = half_to_float(B[b_index]); + } else { + b_val = half_to_float(B[index]); + } + + float a_val = half_to_float(A[index]); + float result = b_val == 0.0f ? 0.0f : a_val / b_val; + C[index] = float_to_half(result); +} + +__kernel void div_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + __read_only image2d_t inputB, + __write_only image2d_t output, + const int width, + const int height) { + // 这是一个存根(stub)实现, 因为不支持cl_khr_fp16的平台 + // 通常也不支持CL_HALF_FLOAT图像格式. + // 主机代码中该路径已通过&& false禁用. + // 仅用于保证内核能被创建. + return; +} + +__kernel void div_scalar_fp16_vector( + __global const ushort *A, + const float B, + __global ushort *C) { + // 每个工作项依然负责4个元素,但我们将逐个处理它们 + const int i = get_global_id(0) * 4; + // 临时存储4个float类型的结果 + float results[4]; + + // 核心安全检查 + if (B == 0.0f) { + results[0] = 0.0f; + results[1] = 0.0f; + results[2] = 0.0f; + results[3] = 0.0f; + } else { + // 【关键改动】像 flash_attention.cl 一样,逐个加载、转换、计算 + results[0] = half_to_float(A[i + 0]) / B; + results[1] = half_to_float(A[i + 1]) / B; + results[2] = half_to_float(A[i + 2]) / B; + results[3] = half_to_float(A[i + 3]) / B; + } + + // 逐个转换回 half 并存储 + C[i + 0] = float_to_half(results[0]); + C[i + 1] = float_to_half(results[1]); + C[i + 2] = float_to_half(results[2]); + C[i + 3] = float_to_half(results[3]); +} + +__kernel void div_scalar_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const ushort B, + __write_only image2d_t output, + const int width, + const int height) { + // 存根(stub)实现. + return; +} + +#endif // SUPPORTS_FP16 \ No newline at end of file diff --git a/src/backends/opencl/kernel/div_int.cl b/src/backends/opencl/kernel/div_int.cl new file mode 100644 index 000000000..3956d7a05 --- /dev/null +++ b/src/backends/opencl/kernel/div_int.cl @@ -0,0 +1,181 @@ +// 文件名: kernel/div_int.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// ================================================================== +// 1. Tensor / Scalar Division with Integer Truncation (FP32) +// ================================================================== + +__kernel void div_int_scalar_float( + __global const float *A, + const float B, + __global float *C) { + size_t index = get_global_id(0); + int val_a = convert_int_rtz(A[index]); + int val_b = convert_int_rtz(B); + int result = (val_b == 0) ? 0 : (val_a / val_b); + C[index] = (float)result; +} + +__kernel void div_int_scalar_float_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const float B, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + int4 val_a = convert_int4_rtz(read_imagef(inputA, sampler, pos)); + int val_b = convert_int_rtz(B); + int4 result = (val_b == 0) ? (int4)(0) : (val_a / val_b); + write_imagef(output, pos, convert_float4(result)); +} + +// ================================================================== +// 2. FP16 Kernels (Hardware vs. Software Fallback) +// ================================================================== + +#ifdef SUPPORTS_FP16 + +// A. FP16实现 (硬件原生支持) +__kernel void div_int_scalar_fp16_vector( + __global const half *A, + const float B, + __global half *C) { + const int i = get_global_id(0); + float4 val_a_f = convert_float4(vload4(i, A)); + int4 val_a = convert_int4_rtz(val_a_f); + int val_b = convert_int_rtz(B); + int4 result = (val_b == 0) ? (int4)(0) : (val_a / val_b); + vstore4(convert_half4_rte(result), i, C); +} + +__kernel void div_int_scalar_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const float B, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + float4 val_a_f = convert_float4(read_imageh(inputA, sampler, pos)); + int4 val_a = convert_int4_rtz(val_a_f); + int val_b = convert_int_rtz(B); + int4 result = (val_b == 0) ? (int4)(0) : (val_a / val_b); + write_imageh(output, pos, convert_half4_rte(result)); +} + +// ADDED: Scalar Kernel (for any data count) +__kernel void div_int_scalar_fp16( + __global const half *A, + const float B, + __global half *C) { + size_t index = get_global_id(0); + float val_a_f = convert_float(A[index]); + int val_a = convert_int_rtz(val_a_f); + int val_b = convert_int_rtz(B); + int result = (val_b == 0) ? 0 : (val_a / val_b); + C[index] = convert_half_rte((float)result); +} + +#else // !SUPPORTS_FP16 + +// B. FP16实现 (软件回退) +inline float half_to_float(ushort h) { + const uint s = (h >> 15) & 0x0001; + const uint e = (h >> 10) & 0x001f; + const uint f = h & 0x03ff; + uint float_val; + if (e == 0) { + if (f == 0) { + float_val = s << 31; + } else { + uint f_shifted = f; + uint e_shifted = e; + while ((f_shifted & 0x0400) == 0) { + f_shifted <<= 1; + e_shifted--; + } + e_shifted++; + f_shifted &= ~0x0400; + float_val = (s << 31) | ((e_shifted + 112) << 23) | (f_shifted << 13); + } + } else if (e == 31) { + if (f == 0) { + float_val = (s << 31) | 0x7f800000; + } else { + float_val = (s << 31) | 0x7f800000 | (f << 13); + } + } else { + float_val = (s << 31) | ((e + 112) << 23) | (f << 13); + } + return as_float(float_val); +} + +inline ushort float_to_half(float f) { + uint u = as_uint(f); + uint s = (u >> 16) & 0x8000; + int e = ((u >> 23) & 0xFF) - 127; + uint f_mant = u & 0x7FFFFF; + + if (e > 15) return (ushort)(s | 0x7C00); + if (e < -14) { + f_mant |= 0x800000; + return (ushort)(s | (f_mant >> (-e - 14))); + } + return (ushort)(s | ((e + 15) << 10) | (f_mant >> 13)); +} + +__kernel void div_int_scalar_fp16_vector( + __global const ushort *A, + const float B, + __global ushort *C) { + const int i = get_global_id(0) * 4; + int val_b = convert_int_rtz(B); + if (val_b == 0) { + C[i + 0] = float_to_half(0.0f); + C[i + 1] = float_to_half(0.0f); + C[i + 2] = float_to_half(0.0f); + C[i + 3] = float_to_half(0.0f); + return; + } + int val_a0 = convert_int_rtz(half_to_float(A[i + 0])); + int val_a1 = convert_int_rtz(half_to_float(A[i + 1])); + int val_a2 = convert_int_rtz(half_to_float(A[i + 2])); + int val_a3 = convert_int_rtz(half_to_float(A[i + 3])); + int res0 = val_a0 / val_b; + int res1 = val_a1 / val_b; + int res2 = val_a2 / val_b; + int res3 = val_a3 / val_b; + C[i + 0] = float_to_half((float)res0); + C[i + 1] = float_to_half((float)res1); + C[i + 2] = float_to_half((float)res2); + C[i + 3] = float_to_half((float)res3); +} + +__kernel void div_int_scalar_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const float B, + __write_only image2d_t output, + const int width, + const int height) { + // Stub implementation as this path is not used for non-aligned data + return; +} + +// ADDED: Scalar Kernel Fallback (for any data count) +__kernel void div_int_scalar_fp16( + __global const ushort *A, + const float B, + __global ushort *C) { + size_t index = get_global_id(0); + int val_a = convert_int_rtz(half_to_float(A[index])); + int val_b = convert_int_rtz(B); + int result = (val_b == 0) ? 0 : (val_a / val_b); + C[index] = float_to_half((float)result); +} + +#endif // SUPPORTS_FP16 \ No newline at end of file diff --git a/src/backends/opencl/kernel/embedding.cl b/src/backends/opencl/kernel/embedding.cl new file mode 100644 index 000000000..e06a3e9f6 --- /dev/null +++ b/src/backends/opencl/kernel/embedding.cl @@ -0,0 +1,125 @@ +// 文件名: kernel/embedding.cl +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// 与 C++ DataType.hpp 中定义匹配的 Q4_0 量化块结构 +typedef struct { + half d; + unsigned char qs[16]; +} block_q4_0; + +// ============================================================================ +// ========================== FP32 Embedding Kernel =========================== +// ============================================================================ +__kernel void embedding_fp32( + __global const float *input_ids_float, + __global const float *weights, + __global float *output, + const int vocab_size, + const int hidden_size, + const int sequence_len) { + const int d_idx = get_global_id(0); + const int token_idx = get_global_id(1); + + if (d_idx >= hidden_size || token_idx >= sequence_len) { + return; + } + + const int token_id = (int)input_ids_float[token_idx]; + if (token_id < 0 || token_id >= vocab_size) { + output[token_idx * hidden_size + d_idx] = 0.0f; + return; + } + + const size_t src_idx = (size_t)token_id * hidden_size + d_idx; + const size_t dst_idx = (size_t)token_idx * hidden_size + d_idx; + + output[dst_idx] = weights[src_idx]; +} + +// ============================================================================ +// ========================== Q4_0 Embedding Kernel =========================== +// ============================================================================ +__kernel void embedding_q4_0( + __global const float *input_ids_float, + __global const block_q4_0 *weights, + __global float *output, + const int vocab_size, + const int hidden_size, + const int sequence_len) { + const int d_idx = get_global_id(0); + const int token_idx = get_global_id(1); + + if (d_idx >= hidden_size || token_idx >= sequence_len) { + return; + } + + const int token_id = (int)input_ids_float[token_idx]; + if (token_id < 0 || token_id >= vocab_size) { + output[token_idx * hidden_size + d_idx] = 0.0f; + return; + } + + const size_t weight_idx = (size_t)token_id * hidden_size + d_idx; + const int block_idx = weight_idx / 32; + const int quant_idx_in_block = weight_idx % 32; + const __global block_q4_0 *b = &weights[block_idx]; + + // 正确的解量化逻辑 + const int qs_index = quant_idx_in_block % 16; + // [修正] 将 uchar 替换为 unsigned char 提高兼容性 + const unsigned char quant_pair = b->qs[qs_index]; + int nibble; + + if (quant_idx_in_block < 16) { + // 元素在块的前半部分 (0-15), 取低4位 + nibble = (quant_pair & 0x0F); + } else { + // 元素在块的后半部分 (16-31), 取高4位 + nibble = (quant_pair >> 4); + } + + const float dequantized_value = (float)b->d * (float)(nibble - 8); + const size_t dst_idx = (size_t)token_idx * hidden_size + d_idx; + output[dst_idx] = dequantized_value; +} +// ============================================================================ +// ================= Q4_0 Embedding Kernel (Output: FP16) ============ +// ============================================================================ +__kernel void embedding_q4_0_fp16( + __global const half *input_ids_half, // ✨ **核心修正点**: 输入类型改为 half + __global const block_q4_0 *weights, + __global half *output, + const int vocab_size, + const int hidden_size, + const int sequence_len) { + const int d_idx = get_global_id(0); + const int token_idx = get_global_id(1); + + if (d_idx >= hidden_size || token_idx >= sequence_len) { + return; + } + + // ✨ **核心修正点**: 从 half 类型的输入中读取 token ID + const int token_id = (int)input_ids_half[token_idx]; + const size_t dst_idx = (size_t)token_idx * hidden_size + d_idx; + + if (token_id < 0 || token_id >= vocab_size) { + output[dst_idx] = (half)0.0f; + return; + } + + // 解量化逻辑与 embedding_q4_0 完全相同 + const size_t weight_idx = (size_t)token_id * hidden_size + d_idx; + const int block_idx = weight_idx / 32; + const int quant_idx_in_block = weight_idx % 32; + const __global block_q4_0 *b = &weights[block_idx]; + const int qs_index = quant_idx_in_block % 16; + const unsigned char quant_pair = b->qs[qs_index]; + int nibble = (quant_idx_in_block < 16) ? (quant_pair & 0x0F) : (quant_pair >> 4); + + // 计算结果为 float + const float dequantized_value = (float)b->d * (float)(nibble - 8); + + // 将 float 结果转换为 half 并存储 + output[dst_idx] = (half)dequantized_value; +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/flash_attention.cl b/src/backends/opencl/kernel/flash_attention.cl new file mode 100644 index 000000000..3797b5a4e --- /dev/null +++ b/src/backends/opencl/kernel/flash_attention.cl @@ -0,0 +1,884 @@ +// 文件: opencl/kernel/flash_attention.cl +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +#define F32_MAX 3.402823466e+38f +// 根据您的硬件能力和模型维度进行调整 +#define DIM_MAX 128 +// K/V瓦片的序列长度,32或64是常见选择 +#define TILE_S 32 +// 工作组大小,128或256是常见选择 +#define WGS 128 + +__kernel void flash_attention_2_prefill_fp32( + __global const float *Q, + __global const float *K, + __global const float *V, + __global float *O, + const int q_head_size, + const int kv_head_size, + const int seq_size_q, + const int seq_size_k, + const int dim_size, + const int causal_mask_flag) { + __local float k_tile[TILE_S][DIM_MAX]; + __local float v_tile[TILE_S][DIM_MAX]; + + // 1. 并行模型与索引:一个工作组计算一个输出行 O[b, s_q, h, :] + // 全局ID的每一行代表一个输出向量 + const int row_idx = get_group_id(0); + const int local_id = get_local_id(0); // 线程在工作组内的ID (0 to WGS-1) + + const int b = row_idx / (seq_size_q * q_head_size); + const int s_q_h_idx = row_idx % (seq_size_q * q_head_size); + const int s_q = s_q_h_idx / q_head_size; + const int h = s_q_h_idx % q_head_size; + + // 处理GQA/MQA: 多个Q头可能对应同一个KV头 + const int kv_h_idx = h / (q_head_size / kv_head_size); + + // 2. 初始化线程私有累加器 (在寄存器中,速度最快) + float my_max_score = -F32_MAX; + float my_sum_exp = 0.0f; + float my_acc_o[DIM_MAX]; + for (int d = 0; d < dim_size; ++d) { + my_acc_o[d] = 0.0f; + } + + // 将当前查询向量Q加载到私有内存(寄存器)中,以便在循环中反复使用 + float my_q[DIM_MAX]; + const long q_base_addr = (long)b * seq_size_q * q_head_size * dim_size + (long)s_q * q_head_size * dim_size + (long)h * dim_size; + for (int d = 0; d < dim_size; ++d) { + my_q[d] = Q[q_base_addr + d]; + } + // 注意:此处需要一个屏障,因为每个线程只加载了Q的一部分,但下面计算需要完整的Q + // 但由于并行模型是冗余计算,每个线程最终都会有完整的my_q,所以也可以不加。 + // 为了逻辑严谨和未来可能的优化,我们这里假设每个线程都拿到了完整的Q。 + // 在实践中,更优化的方式是让一个warp加载Q然后广播,但为简单起见,这里每个线程都读。 + + const float scale = rsqrt((float)dim_size); + const int max_s_k = (causal_mask_flag && seq_size_q > 1) ? (s_q + 1) : seq_size_k; + + // 3. 沿K/V序列长度的分块循环 + for (int s_k_start = 0; s_k_start < max_s_k; s_k_start += TILE_S) { + // a. 工作组协作加载K, V块到高速的__local内存 + for (int i = local_id; i < TILE_S * dim_size; i += WGS) { + int s_local = i / dim_size; + int d_local = i % dim_size; + int s_k_global = s_k_start + s_local; + + if (s_k_global < seq_size_k) { + long kv_offset = (long)b * seq_size_k * kv_head_size * dim_size + (long)s_k_global * kv_head_size * dim_size + (long)kv_h_idx * dim_size + d_local; + k_tile[s_local][d_local] = K[kv_offset]; + v_tile[s_local][d_local] = V[kv_offset]; + } else { + // 超出范围的数据用0填充 + k_tile[s_local][d_local] = 0.0f; + v_tile[s_local][d_local] = 0.0f; + } + } + // 同步点:确保所有线程都完成了加载,K/V tile现在对所有线程可见 + barrier(CLK_LOCAL_MEM_FENCE); + + // b. 每个线程独立处理已加载的K/V瓦片,执行在线Softmax + for (int s_local = 0; s_local < TILE_S; ++s_local) { + int s_k_global = s_k_start + s_local; + if (s_k_global < max_s_k) { + // 计算分数 (Q * K^T) + float score = 0.0f; + for (int d = 0; d < dim_size; ++d) { + score += my_q[d] * k_tile[s_local][d]; + } + score *= scale; + + float old_max = my_max_score; + my_max_score = fmax(old_max, score); + + float scale_factor = exp(old_max - my_max_score); + my_sum_exp *= scale_factor; + + for (int d = 0; d < dim_size; ++d) { + my_acc_o[d] *= scale_factor; + } + + float p = exp(score - my_max_score); + my_sum_exp += p; + + for (int d = 0; d < dim_size; ++d) { + my_acc_o[d] += p * v_tile[s_local][d]; + } + } + } + // 同步点:确保所有线程都处理完当前块,才能进入下一轮循环加载新块 + barrier(CLK_LOCAL_MEM_FENCE); + } + + // 4. 最终写回 + // 只需要一个线程来执行最后的归一化和写回操作,避免写入冲突 + if (local_id == 0) { + float inv_sum_exp = 1.0f / (my_sum_exp + 1e-6f); + long o_offset = (long)b * seq_size_q * q_head_size * dim_size + (long)s_q * q_head_size * dim_size + (long)h * dim_size; + for (int d = 0; d < dim_size; ++d) { + O[o_offset + d] = my_acc_o[d] * inv_sum_exp; + } + } +} + +__kernel void flash_attention_2_decode_fp32( + __global const float *Q, + __global const float *K, + __global const float *V, + __global float *O, + const int q_head_size, + const int kv_head_size, + const int seq_size_k, + const int dim_size) { + __local float q_vec[DIM_MAX]; + __local float l_max_score; + __local float l_sum_exp; + __local float partial_sums[WGS]; + __local float p, scale_factor; + + // 1. 并行模型与索引 + const int row_idx = get_group_id(0); + const int local_id = get_local_id(0); + + const int b = row_idx / q_head_size; + const int h = row_idx % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + + // 2. 协作加载Q向量 + const long q_addr = (long)b * q_head_size * dim_size + (long)h * dim_size; + for (int d = local_id; d < dim_size; d += WGS) { + q_vec[d] = Q[q_addr + d]; + } + + // 3. 初始化 + if (local_id == 0) { + l_max_score = -F32_MAX; + l_sum_exp = 0.0f; + } + + const int dims_per_thread = (dim_size + WGS - 1) / WGS; + float my_acc_o[DIM_MAX / WGS + 1]; + for (int i = 0; i < dims_per_thread; ++i) my_acc_o[i] = 0.0f; + + const float scale = rsqrt((float)dim_size); + barrier(CLK_LOCAL_MEM_FENCE); + + // 4. 遍历所有Key向量 + for (int s_k = 0; s_k < seq_size_k; ++s_k) { + // ... 并行计算点积与规约 (这部分逻辑不变) ... + float partial_sum = 0.0f; + long k_addr = (long)b * seq_size_k * kv_head_size * dim_size + (long)s_k * kv_head_size * dim_size + (long)kv_h_idx * dim_size; + for (int i = 0; i < dims_per_thread; ++i) { + int d = local_id + i * WGS; + if (d < dim_size) { + partial_sum += q_vec[d] * K[k_addr + d]; + } + } + partial_sums[local_id] = partial_sum; + barrier(CLK_LOCAL_MEM_FENCE); + + for (int offset = WGS / 2; offset > 0; offset /= 2) { + if (local_id < offset) { + partial_sums[local_id] += partial_sums[local_id + offset]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + // c. 由线程0计算并更新共享的统计量 + // __local float p, scale_factor; // <--- 从这里移除 + if (local_id == 0) { + float score = partial_sums[0] * scale; + float old_max = l_max_score; + l_max_score = fmax(old_max, score); + scale_factor = exp(old_max - l_max_score); + p = exp(score - l_max_score); + l_sum_exp = l_sum_exp * scale_factor + p; + } + barrier(CLK_LOCAL_MEM_FENCE); + + // d. 所有线程并行累加V向量 + long v_addr = (long)b * seq_size_k * kv_head_size * dim_size + (long)s_k * kv_head_size * dim_size + (long)kv_h_idx * dim_size; + for (int i = 0; i < dims_per_thread; ++i) { + int d = local_id + i * WGS; + if (d < dim_size) { + my_acc_o[i] = my_acc_o[i] * scale_factor + p * V[v_addr + d]; + } + } + } + + // 5. 最终写回 + barrier(CLK_LOCAL_MEM_FENCE); + float inv_sum_exp = 1.0f / (l_sum_exp + 1e-6f); + long o_addr = (long)b * q_head_size * dim_size + (long)h * dim_size; + + for (int i = 0; i < dims_per_thread; ++i) { + int d = local_id + i * WGS; + if (d < dim_size) { + O[o_addr + d] = my_acc_o[i] * inv_sum_exp; + } + } +} + +// ================================================================================================= +// +// FP16 KERNELS START HERE +// +// ================================================================================================= +#if !defined(SUPPORTS_FP16) +// ------------------------------------------------------------------------------------------------- +// [回退版] FP16 Prefill (Tiled) Kernel +// ------------------------------------------------------------------------------------------------- +__kernel void flash_attention_2_prefill_fp16( + __global const half *Q, + __global const half *K, + __global const half *V, + __global half *O, + const int q_head_size, + const int kv_head_size, + const int seq_size_q, + const int seq_size_k, + const int dim_size, + const int causal_mask_flag) { + __local half k_tile[TILE_S][DIM_MAX]; + __local half v_tile[TILE_S][DIM_MAX]; + + const int row_idx = get_group_id(0); + const int local_id = get_local_id(0); + const int b = row_idx / (seq_size_q * q_head_size); + const int s_q_h_idx = row_idx % (seq_size_q * q_head_size); + const int s_q = s_q_h_idx / q_head_size; + const int h = s_q_h_idx % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + + float my_max_score = -F32_MAX; + float my_sum_exp = 0.0f; + float my_acc_o[DIM_MAX]; + for (int d = 0; d < dim_size; ++d) { + my_acc_o[d] = 0.0f; + } + + half my_q[DIM_MAX]; + const long q_base_addr = (long)b * seq_size_q * q_head_size * dim_size + (long)s_q * q_head_size * dim_size + (long)h * dim_size; + for (int d = 0; d < dim_size; ++d) { + my_q[d] = Q[q_base_addr + d]; + } + + const float scale = rsqrt((float)dim_size); + const int max_s_k = (causal_mask_flag && seq_size_q > 1) ? (s_q + 1) : seq_size_k; + + for (int s_k_start = 0; s_k_start < max_s_k; s_k_start += TILE_S) { + for (int i = local_id; i < TILE_S * dim_size; i += WGS) { + int s_local = i / dim_size; + int d_local = i % dim_size; + int s_k_global = s_k_start + s_local; + if (s_k_global < seq_size_k) { + long kv_offset = (long)b * seq_size_k * kv_head_size * dim_size + (long)s_k_global * kv_head_size * dim_size + (long)kv_h_idx * dim_size + d_local; + k_tile[s_local][d_local] = K[kv_offset]; + v_tile[s_local][d_local] = V[kv_offset]; + } else { + k_tile[s_local][d_local] = 0.0h; + v_tile[s_local][d_local] = 0.0h; + } + } + barrier(CLK_LOCAL_MEM_FENCE); + + for (int s_local = 0; s_local < TILE_S; ++s_local) { + int s_k_global = s_k_start + s_local; + if (s_k_global < max_s_k) { + float score = 0.0f; + for (int d = 0; d < dim_size; ++d) { + score += (float)my_q[d] * (float)k_tile[s_local][d]; + } + score *= scale; + + float old_max = my_max_score; + my_max_score = fmax(old_max, score); + + float scale_factor = exp(old_max - my_max_score); + my_sum_exp *= scale_factor; + for (int d = 0; d < dim_size; ++d) { + my_acc_o[d] *= scale_factor; + } + + float p = exp(score - my_max_score); + my_sum_exp += p; + + for (int d = 0; d < dim_size; ++d) { + my_acc_o[d] += p * (float)v_tile[s_local][d]; + } + } + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + if (local_id == 0) { + float inv_sum_exp = 1.0f / (my_sum_exp + 1e-6f); + long o_offset = (long)b * seq_size_q * q_head_size * dim_size + (long)s_q * q_head_size * dim_size + (long)h * dim_size; + for (int d = 0; d < dim_size; ++d) { + O[o_offset + d] = (half)(my_acc_o[d] * inv_sum_exp); + } + } +} + +#else +// ------------------------------------------------------------------------------------------------- +// [高性能版] FP16 Prefill (Tiled) Kernel +// ------------------------------------------------------------------------------------------------- + +#define VEC_SIZE 8 +__kernel void flash_attention_2_prefill_fp16( + __global const half *Q, + __global const half *K, + __global const half *V, + __global half *O, + const int q_head_size, + const int kv_head_size, + const int seq_size_q, + const int seq_size_k, + const int dim_size, + const int causal_mask_flag) { + __local half k_tile[TILE_S * DIM_MAX]; + __local half v_tile[TILE_S * DIM_MAX]; + __local half q_local[DIM_MAX]; + + const int row_idx = get_group_id(0); + const int local_id = get_local_id(0); + + const int b = row_idx / (seq_size_q * q_head_size); + const int s_q_h_idx = row_idx % (seq_size_q * q_head_size); + const int s_q = s_q_h_idx / q_head_size; + const int h = s_q_h_idx % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + + float my_max_score = -F32_MAX; + float my_sum_exp = 0.0f; + float8 my_acc_o_vec[DIM_MAX / VEC_SIZE]; + for (int i = 0; i < dim_size / VEC_SIZE; ++i) { + my_acc_o_vec[i] = (float8)(0.0f); + } + + const long q_base_addr = (long)b * seq_size_q * q_head_size * dim_size + (long)s_q * q_head_size * dim_size + (long)h * dim_size; + for (int d = local_id; d < dim_size; d += WGS) { + q_local[d] = Q[q_base_addr + d]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + const float scale = rsqrt((float)dim_size); + const int max_s_k = (causal_mask_flag && seq_size_q > 1) ? (s_q + 1) : seq_size_k; + const int dim_vec = dim_size / VEC_SIZE; + + for (int s_k_start = 0; s_k_start < max_s_k; s_k_start += TILE_S) { + for (int i = local_id; i < TILE_S * dim_vec; i += WGS) { + int s_local = i / dim_vec; + int d_vec_idx = i % dim_vec; + int s_k_global = s_k_start + s_local; + + if (s_k_global < seq_size_k) { + long kv_offset = (long)b * seq_size_k * kv_head_size * dim_size + (long)s_k_global * kv_head_size * dim_size + (long)kv_h_idx * dim_size + (long)d_vec_idx * VEC_SIZE; + *((__local half8 *)k_tile + i) = *((__global const half8 *)(K + kv_offset)); + *((__local half8 *)v_tile + i) = *((__global const half8 *)(V + kv_offset)); + } else { + *((__local half8 *)k_tile + i) = (half8)(0.0h); + *((__local half8 *)v_tile + i) = (half8)(0.0h); + } + } + barrier(CLK_LOCAL_MEM_FENCE); + + for (int s_local = 0; s_local < TILE_S; ++s_local) { + int s_k_global = s_k_start + s_local; + if (s_k_global < max_s_k) { + float score = 0.0f; + for (int d_vec = 0; d_vec < dim_vec; ++d_vec) { + float8 q_f_vec = vload_half8(d_vec, q_local); + float8 k_f_vec = vload_half8(s_local * dim_vec + d_vec, k_tile); + float8 mul_res = q_f_vec * k_f_vec; + score += mul_res.s0 + mul_res.s1 + mul_res.s2 + mul_res.s3 + mul_res.s4 + mul_res.s5 + mul_res.s6 + mul_res.s7; + } + score *= scale; + float old_max = my_max_score; + my_max_score = fmax(old_max, score); + float scale_factor = exp(old_max - my_max_score); + my_sum_exp *= scale_factor; + float p = exp(score - my_max_score); + my_sum_exp += p; + for (int d_vec = 0; d_vec < dim_vec; ++d_vec) { + float8 v_f_vec = vload_half8(s_local * dim_vec + d_vec, v_tile); + my_acc_o_vec[d_vec] = mad((float8)(p), v_f_vec, my_acc_o_vec[d_vec] * scale_factor); + } + } + } + barrier(CLK_LOCAL_MEM_FENCE); + } + if (local_id == 0) { + float inv_sum_exp = 1.0f / (my_sum_exp + 1e-6f); + long o_offset = (long)b * seq_size_q * q_head_size * dim_size + (long)s_q * q_head_size * dim_size + (long)h * dim_size; + for (int d_vec = 0; d_vec < dim_vec; ++d_vec) { + float8 out_f_vec = my_acc_o_vec[d_vec] * inv_sum_exp; + vstore_half8(out_f_vec, 0, (__global half *)(O + o_offset + d_vec * VEC_SIZE)); + } + } +} + +#endif // SUPPORTS_FP16 +// ------------------------------------------------------------------------------------------------- +// FP16 Decode Kernel +// ------------------------------------------------------------------------------------------------- +__kernel void flash_attention_2_decode_fp16( + __global const half *Q, + __global const half *K, + __global const half *V, + __global half *O, + const int q_head_size, + const int kv_head_size, + const int seq_size_k, + const int dim_size) { + __local half q_vec[DIM_MAX]; + __local float l_max_score; + __local float l_sum_exp; + __local float partial_sums[WGS]; + __local float p, scale_factor; + + const int row_idx = get_group_id(0); + const int local_id = get_local_id(0); + + const int b = row_idx / q_head_size; + const int h = row_idx % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + + const long q_addr = (long)b * q_head_size * dim_size + (long)h * dim_size; + for (int d = local_id; d < dim_size; d += WGS) { + q_vec[d] = Q[q_addr + d]; + } + + if (local_id == 0) { + l_max_score = -F32_MAX; + l_sum_exp = 0.0f; + } + + const int dims_per_thread = (dim_size + WGS - 1) / WGS; + float my_acc_o[DIM_MAX / WGS + 1]; + for (int i = 0; i < dims_per_thread; ++i) my_acc_o[i] = 0.0f; + + const float scale = rsqrt((float)dim_size); + barrier(CLK_LOCAL_MEM_FENCE); + + for (int s_k = 0; s_k < seq_size_k; ++s_k) { + float partial_sum = 0.0f; + long k_addr = (long)b * seq_size_k * kv_head_size * dim_size + (long)s_k * kv_head_size * dim_size + (long)kv_h_idx * dim_size; + for (int i = 0; i < dims_per_thread; ++i) { + int d = local_id + i * WGS; + if (d < dim_size) { + partial_sum += (float)q_vec[d] * (float)K[k_addr + d]; + } + } + partial_sums[local_id] = partial_sum; + barrier(CLK_LOCAL_MEM_FENCE); + + for (int offset = WGS / 2; offset > 0; offset /= 2) { + if (local_id < offset) { + partial_sums[local_id] += partial_sums[local_id + offset]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + if (local_id == 0) { + float score = partial_sums[0] * scale; + float old_max = l_max_score; + l_max_score = fmax(old_max, score); + scale_factor = exp(old_max - l_max_score); + p = exp(score - l_max_score); + l_sum_exp = l_sum_exp * scale_factor + p; + } + barrier(CLK_LOCAL_MEM_FENCE); + + long v_addr = (long)b * seq_size_k * kv_head_size * dim_size + (long)s_k * kv_head_size * dim_size + (long)kv_h_idx * dim_size; + for (int i = 0; i < dims_per_thread; ++i) { + int d = local_id + i * WGS; + if (d < dim_size) { + my_acc_o[i] = my_acc_o[i] * scale_factor + p * (float)V[v_addr + d]; + } + } + } + + barrier(CLK_LOCAL_MEM_FENCE); + float inv_sum_exp = 1.0f / (l_sum_exp + 1e-6f); + long o_addr = (long)b * q_head_size * dim_size + (long)h * dim_size; + for (int i = 0; i < dims_per_thread; ++i) { + int d = local_id + i * WGS; + if (d < dim_size) { + O[o_addr + d] = (half)(my_acc_o[i] * inv_sum_exp); + } + } +} + +// ---------- [Image 版] FP32 Prefill Kernel ---------- +__kernel void flash_attention_2_prefill_fp32_image( + sampler_t sampler, + __read_only image2d_t Q, __read_only image2d_t K, __read_only image2d_t V, + __write_only image2d_t O, + const int q_head_size, const int kv_head_size, + const int seq_size_q, const int seq_size_k, + const int dim_size, const int causal_mask_flag) { + const int row_idx = get_group_id(0); + const int local_id = get_local_id(0); + const int b = row_idx / (seq_size_q * q_head_size); + const int s_h_idx = row_idx % (seq_size_q * q_head_size); + const int s_q = s_h_idx / q_head_size; + const int h = s_h_idx % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + float my_max_score = -F32_MAX; + float my_sum_exp = 0.0f; + float my_acc_o[128]; + for (int d = 0; d < dim_size; ++d) my_acc_o[d] = 0.0f; + float my_q[128]; + const int q_y_coord = (b * seq_size_q * q_head_size) + (s_q * q_head_size) + h; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + float4 q_pix = read_imagef(Q, sampler, (int2)(d_pixel, q_y_coord)); + my_q[d_pixel * 4 + 0] = q_pix.x; + my_q[d_pixel * 4 + 1] = q_pix.y; + my_q[d_pixel * 4 + 2] = q_pix.z; + my_q[d_pixel * 4 + 3] = q_pix.w; + } + const float scale = rsqrt((float)dim_size); + const int max_s_k = (causal_mask_flag && seq_size_q > 1) ? (s_q + 1) : seq_size_k; + for (int s_k_start = 0; s_k_start < max_s_k; s_k_start += TILE_S) { + for (int s_local = 0; s_local < TILE_S; ++s_local) { + int s_k_global = s_k_start + s_local; + if (s_k_global < max_s_k) { + float score = 0.0f; + const int k_y_coord = (b * seq_size_k * kv_head_size) + (s_k_global * kv_head_size) + kv_h_idx; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + float4 k_pix = read_imagef(K, sampler, (int2)(d_pixel, k_y_coord)); + score += my_q[d_pixel * 4 + 0] * k_pix.x; + score += my_q[d_pixel * 4 + 1] * k_pix.y; + score += my_q[d_pixel * 4 + 2] * k_pix.z; + score += my_q[d_pixel * 4 + 3] * k_pix.w; + } + score *= scale; + float old_max = my_max_score; + my_max_score = fmax(old_max, score); + float scale_factor = exp(old_max - my_max_score); + my_sum_exp *= scale_factor; + float p = exp(score - my_max_score); + const int v_y_coord = k_y_coord; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + float4 v_pix = read_imagef(V, sampler, (int2)(d_pixel, v_y_coord)); + my_acc_o[d_pixel * 4 + 0] = my_acc_o[d_pixel * 4 + 0] * scale_factor + p * v_pix.x; + my_acc_o[d_pixel * 4 + 1] = my_acc_o[d_pixel * 4 + 1] * scale_factor + p * v_pix.y; + my_acc_o[d_pixel * 4 + 2] = my_acc_o[d_pixel * 4 + 2] * scale_factor + p * v_pix.z; + my_acc_o[d_pixel * 4 + 3] = my_acc_o[d_pixel * 4 + 3] * scale_factor + p * v_pix.w; + } + my_sum_exp += p; + } + } + } + if (local_id == 0) { + float inv_sum_exp = 1.0f / (my_sum_exp + 1e-6f); + const int o_y_coord = (b * seq_size_q * q_head_size) + (s_q * q_head_size) + h; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + float4 out_pixel; + out_pixel.x = my_acc_o[d_pixel * 4 + 0] * inv_sum_exp; + out_pixel.y = my_acc_o[d_pixel * 4 + 1] * inv_sum_exp; + out_pixel.z = my_acc_o[d_pixel * 4 + 2] * inv_sum_exp; + out_pixel.w = my_acc_o[d_pixel * 4 + 3] * inv_sum_exp; + write_imagef(O, (int2)(d_pixel, o_y_coord), out_pixel); + } + } +} + +// ---------- [Image 版] FP32 Decode Kernel [最终修正] ---------- +__kernel void flash_attention_2_decode_fp32_image( + sampler_t sampler, + __read_only image2d_t Q, __read_only image2d_t K, __read_only image2d_t V, + __write_only image2d_t O, + const int q_head_size, const int kv_head_size, + const int seq_size_k, const int dim_size) { + const int gx = get_global_id(0); + const int gy = get_global_id(1); + if (gx >= (dim_size / 4)) return; + const int b = gy / q_head_size; + const int h = gy % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + float max_score = -F32_MAX; + float sum_exp = 0.0f; + float4 acc_o = (float4)(0.0f); + const float scale = rsqrt((float)dim_size); + const int q_y_coord = gy; + for (int s_k = 0; s_k < seq_size_k; ++s_k) { + float score = 0.0f; + const int k_y_coord = (b * seq_size_k * kv_head_size) + (s_k * kv_head_size) + kv_h_idx; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + float4 q_pix = read_imagef(Q, sampler, (int2)(d_pixel, q_y_coord)); + float4 k_pix = read_imagef(K, sampler, (int2)(d_pixel, k_y_coord)); + score += dot(q_pix, k_pix); + } + score *= scale; + float old_max = max_score; + max_score = fmax(old_max, score); + float scale_factor = exp(old_max - max_score); + sum_exp *= scale_factor; + acc_o *= scale_factor; + float p = exp(score - max_score); + sum_exp += p; + const int v_y_coord = k_y_coord; + float4 v_pix = read_imagef(V, sampler, (int2)(gx, v_y_coord)); + acc_o = mad(p, v_pix, acc_o); + } + float inv_sum_exp = 1.0f / (sum_exp + 1e-6f); + acc_o *= inv_sum_exp; + write_imagef(O, (int2)(gx, gy), acc_o); +} + +// ================================================================================================= +// 3. FP16 全 Image 版本的内核 +// ================================================================================================= +#if defined(SUPPORTS_FP16) +// ================================================================================================= +// FP16 Prefill Kernel (Image) +// ================================================================================================= +__kernel void flash_attention_2_prefill_fp16_image( + sampler_t sampler, + __read_only image2d_t Q, __read_only image2d_t K, __read_only image2d_t V, + __write_only image2d_t O, + const int q_head_size, const int kv_head_size, + const int seq_size_q, const int seq_size_k, + const int dim_size, const int causal_mask_flag) { + const int row_idx = get_group_id(0); + const int local_id = get_local_id(0); + const int b = row_idx / (seq_size_q * q_head_size); + const int s_h_idx = row_idx % (seq_size_q * q_head_size); + const int s_q = s_h_idx / q_head_size; + const int h = s_h_idx % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + float my_max_score = -F32_MAX; + float my_sum_exp = 0.0f; + float4 my_acc_o[32]; + float4 my_q[32]; +#pragma unroll + for (int i = 0; i < 32; ++i) { + my_acc_o[i] = (float4)(0.0f); + } + const int q_y_coord = (b * seq_size_q * q_head_size) + (s_q * q_head_size) + h; + const int dim_vec_size = dim_size / 4; +#pragma unroll + for (int d_vec = 0; d_vec < dim_vec_size; ++d_vec) { + my_q[d_vec] = convert_float4(read_imageh(Q, sampler, (int2)(d_vec, q_y_coord))); + } + const float scale = rsqrt((float)dim_size); + const int max_s_k = (causal_mask_flag && seq_size_q > 1) ? (s_q + 1) : seq_size_k; + for (int s_k_global = 0; s_k_global < max_s_k; ++s_k_global) { + float score = 0.0f; + const int k_y_coord = (b * seq_size_k * kv_head_size) + (s_k_global * kv_head_size) + kv_h_idx; +#pragma unroll + for (int d_vec = 0; d_vec < dim_vec_size; ++d_vec) { + float4 k_pix = convert_float4(read_imageh(K, sampler, (int2)(d_vec, k_y_coord))); + score += dot(my_q[d_vec], k_pix); + } + score *= scale; + float old_max = my_max_score; + my_max_score = fmax(old_max, score); + float scale_factor = exp(old_max - my_max_score); + my_sum_exp *= scale_factor; + float p = exp(score - my_max_score); + const int v_y_coord = k_y_coord; +#pragma unroll + for (int d_vec = 0; d_vec < dim_vec_size; ++d_vec) { + float4 v_pix = convert_float4(read_imageh(V, sampler, (int2)(d_vec, v_y_coord))); + my_acc_o[d_vec] = my_acc_o[d_vec] * scale_factor + p * v_pix; + } + my_sum_exp += p; + } + if (local_id == 0) { + float inv_sum_exp = 1.0f / (my_sum_exp + 1e-6f); + const int o_y_coord = (b * seq_size_q * q_head_size) + (s_q * q_head_size) + h; +#pragma unroll + for (int d_vec = 0; d_vec < dim_vec_size; ++d_vec) { + float4 out_pixel_f = my_acc_o[d_vec] * inv_sum_exp; + write_imageh(O, (int2)(d_vec, o_y_coord), convert_half4_rte(out_pixel_f)); + } + } +} + +// ================================================================================================= +// FP16 Decode Kernel (Image) +// ================================================================================================= +__kernel void flash_attention_2_decode_fp16_image( + sampler_t sampler, + __read_only image2d_t Q, __read_only image2d_t K, __read_only image2d_t V, + __write_only image2d_t O, + const int q_head_size, const int kv_head_size, + const int seq_size_k, const int dim_size) { + const int gx = get_global_id(0); // Corresponds to dimension vector index + const int gy = get_global_id(1); // Corresponds to batch/head/sequence index + if (gx >= (dim_size / 4)) return; + const int b = gy / q_head_size; + const int h = gy % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + float max_score = -F32_MAX; + float sum_exp = 0.0f; + float4 acc_o = (float4)(0.0f); + const float scale = rsqrt((float)dim_size); + const int q_y_coord = gy; + const int dim_vec_size = dim_size / 4; + for (int s_k = 0; s_k < seq_size_k; ++s_k) { + float score = 0.0f; + const int k_y_coord = (b * seq_size_k * kv_head_size) + (s_k * kv_head_size) + kv_h_idx; +#pragma unroll + for (int d_vec = 0; d_vec < dim_vec_size; ++d_vec) { + float4 q_pix = convert_float4(read_imageh(Q, sampler, (int2)(d_vec, q_y_coord))); + float4 k_pix = convert_float4(read_imageh(K, sampler, (int2)(d_vec, k_y_coord))); + score += dot(q_pix, k_pix); + } + score *= scale; + float old_max = max_score; + max_score = fmax(old_max, score); + float scale_factor = exp(old_max - max_score); + sum_exp *= scale_factor; + acc_o *= scale_factor; + float p = exp(score - max_score); + sum_exp += p; + const int v_y_coord = k_y_coord; + float4 v_pix = convert_float4(read_imageh(V, sampler, (int2)(gx, v_y_coord))); + acc_o = mad(p, v_pix, acc_o); + } + float inv_sum_exp = 1.0f / (sum_exp + 1e-6f); + acc_o *= inv_sum_exp; + write_imageh(O, (int2)(gx, gy), convert_half4_rte(acc_o)); +} + +#else + +// ---------- [Image 版] FP16 Prefill Kernel [兼容回退版] ---------- +__kernel void flash_attention_2_prefill_fp16_image( + sampler_t sampler, + __read_only image2d_t Q, __read_only image2d_t K, __read_only image2d_t V, + __write_only image2d_t O, + const int q_head_size, const int kv_head_size, + const int seq_size_q, const int seq_size_k, + const int dim_size, const int causal_mask_flag) { + const int row_idx = get_group_id(0); + const int local_id = get_local_id(0); + const int b = row_idx / (seq_size_q * q_head_size); + const int s_h_idx = row_idx % (seq_size_q * q_head_size); + const int s_q = s_h_idx / q_head_size; + const int h = s_h_idx % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + + float my_max_score = -F32_MAX; + float my_sum_exp = 0.0f; + float my_acc_o[128]; // 假设 DIM_MAX <= 128 + for (int d = 0; d < dim_size; ++d) my_acc_o[d] = 0.0f; + + float my_q[128]; + const int q_y_coord = (b * seq_size_q * q_head_size) + (s_q * q_head_size) + h; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + // 直接读取CL_FLOAT图像 + float4 q_pix = read_imagef(Q, sampler, (int2)(d_pixel, q_y_coord)); + my_q[d_pixel * 4 + 0] = q_pix.x; + my_q[d_pixel * 4 + 1] = q_pix.y; + my_q[d_pixel * 4 + 2] = q_pix.z; + my_q[d_pixel * 4 + 3] = q_pix.w; + } + + const float scale = rsqrt((float)dim_size); + const int max_s_k = (causal_mask_flag && seq_size_q > 1) ? (s_q + 1) : seq_size_k; + + for (int s_k_global = 0; s_k_global < max_s_k; ++s_k_global) { + float score = 0.0f; + const int k_y_coord = (b * seq_size_k * kv_head_size) + (s_k_global * kv_head_size) + kv_h_idx; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + float4 k_pix = read_imagef(K, sampler, (int2)(d_pixel, k_y_coord)); + score += my_q[d_pixel * 4 + 0] * k_pix.x; + score += my_q[d_pixel * 4 + 1] * k_pix.y; + score += my_q[d_pixel * 4 + 2] * k_pix.z; + score += my_q[d_pixel * 4 + 3] * k_pix.w; + } + score *= scale; + + float old_max = my_max_score; + my_max_score = fmax(old_max, score); + float scale_factor = exp(old_max - my_max_score); + my_sum_exp *= scale_factor; + float p = exp(score - my_max_score); + + const int v_y_coord = k_y_coord; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + float4 v_pix = read_imagef(V, sampler, (int2)(d_pixel, v_y_coord)); + my_acc_o[d_pixel * 4 + 0] = my_acc_o[d_pixel * 4 + 0] * scale_factor + p * v_pix.x; + my_acc_o[d_pixel * 4 + 1] = my_acc_o[d_pixel * 4 + 1] * scale_factor + p * v_pix.y; + my_acc_o[d_pixel * 4 + 2] = my_acc_o[d_pixel * 4 + 2] * scale_factor + p * v_pix.z; + my_acc_o[d_pixel * 4 + 3] = my_acc_o[d_pixel * 4 + 3] * scale_factor + p * v_pix.w; + } + my_sum_exp += p; + } + + if (local_id == 0) { + float inv_sum_exp = 1.0f / (my_sum_exp + 1e-6f); + const int o_y_coord = (b * seq_size_q * q_head_size) + (s_q * q_head_size) + h; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + float4 out_pixel; + out_pixel.x = my_acc_o[d_pixel * 4 + 0] * inv_sum_exp; + out_pixel.y = my_acc_o[d_pixel * 4 + 1] * inv_sum_exp; + out_pixel.z = my_acc_o[d_pixel * 4 + 2] * inv_sum_exp; + out_pixel.w = my_acc_o[d_pixel * 4 + 3] * inv_sum_exp; + // 直接写入CL_FLOAT图像 + write_imagef(O, (int2)(d_pixel, o_y_coord), out_pixel); + } + } +} + +// ---------- [Image 版] FP16 Decode Kernel [兼容回退版] ---------- +__kernel void flash_attention_2_decode_fp16_image( + sampler_t sampler, + __read_only image2d_t Q, __read_only image2d_t K, __read_only image2d_t V, + __write_only image2d_t O, + const int q_head_size, const int kv_head_size, + const int seq_size_k, const int dim_size) { + const int gx = get_global_id(0); + const int gy = get_global_id(1); + + if (gx >= (dim_size / 4)) return; + + const int b = gy / q_head_size; + const int h = gy % q_head_size; + const int kv_h_idx = h / (q_head_size / kv_head_size); + + float max_score = -F32_MAX; + float sum_exp = 0.0f; + float4 acc_o = (float4)(0.0f); + + const float scale = rsqrt((float)dim_size); + const int q_y_coord = gy; + + for (int s_k = 0; s_k < seq_size_k; ++s_k) { + float score = 0.0f; + const int k_y_coord = (b * seq_size_k * kv_head_size) + (s_k * kv_head_size) + kv_h_idx; + for (int d_pixel = 0; d_pixel < dim_size / 4; ++d_pixel) { + float4 q_pix = read_imagef(Q, sampler, (int2)(d_pixel, q_y_coord)); + float4 k_pix = read_imagef(K, sampler, (int2)(d_pixel, k_y_coord)); + score += dot(q_pix, k_pix); + } + score *= scale; + + float old_max = max_score; + max_score = fmax(old_max, score); + float scale_factor = exp(old_max - max_score); + sum_exp *= scale_factor; + acc_o *= scale_factor; + float p = exp(score - max_score); + sum_exp += p; + + const int v_y_coord = k_y_coord; + float4 v_pix = read_imagef(V, sampler, (int2)(gx, v_y_coord)); + acc_o = mad(p, v_pix, acc_o); + } + + float inv_sum_exp = 1.0f / (sum_exp + 1e-6f); + acc_o *= inv_sum_exp; + + // 直接写入CL_FLOAT图像 + write_imagef(O, (int2)(gx, gy), acc_o); +} +#endif // SUPPORTS_FP16 diff --git a/src/backends/opencl/kernel/kvcache.cl b/src/backends/opencl/kernel/kvcache.cl new file mode 100644 index 000000000..0e9125135 --- /dev/null +++ b/src/backends/opencl/kernel/kvcache.cl @@ -0,0 +1,129 @@ +// 文件名: kernel/kvcache.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// ================================================================== +// Kernels for BSHD (Batch, Sequence, Head, Dim) Layout +// ================================================================== +__kernel void update_kv_cache_fp32_bshd( + __global const float *src, + __global float *cache, + const int H_in, + const int S_in, + const int D, + const int H_cache, + const int S_cache, + const int n_rep, + const int cache_offset) { + const int d_vec_idx = get_global_id(0); + const int s_idx = get_global_id(1); + const int h_idx_dst = get_global_id(2); + + const int D_vec = D / 4; + if (d_vec_idx >= D_vec || s_idx >= S_in || h_idx_dst >= H_cache) { + return; + } + + const int h_idx_src = h_idx_dst / n_rep; + const int s_idx_dst = cache_offset + s_idx; + + // BSHD [Batch, Sequence, Head, Dim] layout indexing + size_t src_offset = (size_t)s_idx * H_in * D + (size_t)h_idx_src * D + (size_t)d_vec_idx * 4; + size_t dst_offset = (size_t)s_idx_dst * H_cache * D + (size_t)h_idx_dst * D + (size_t)d_vec_idx * 4; + + float4 data_vec = vload4(0, src + src_offset); + vstore4(data_vec, 0, cache + dst_offset); +} + +__kernel void update_kv_cache_fp16_bshd( + __global const half *src, + __global half *cache, + const int H_in, + const int S_in, + const int D, + const int H_cache, + const int S_cache, + const int n_rep, + const int cache_offset) { + const int d_vec_idx = get_global_id(0); + const int s_idx = get_global_id(1); + const int h_idx_dst = get_global_id(2); + + const int D_vec = D / 4; + if (d_vec_idx >= D_vec || s_idx >= S_in || h_idx_dst >= H_cache) { + return; + } + + const int h_idx_src = h_idx_dst / n_rep; + const int s_idx_dst = cache_offset + s_idx; + + // BSHD [Batch, Sequence, Head, Dim] layout indexing + size_t src_offset = (size_t)s_idx * H_in * D + (size_t)h_idx_src * D + (size_t)d_vec_idx * 4; + size_t dst_offset = (size_t)s_idx_dst * H_cache * D + (size_t)h_idx_dst * D + (size_t)d_vec_idx * 4; + + half4 data_vec = vload4(0, src + src_offset); + vstore4(data_vec, 0, cache + dst_offset); +} + +// ================================================================== +// Kernels for BHSD (Batch, Head, Sequence, Dim) Layout (New) +// ================================================================== +__kernel void update_kv_cache_fp32_bhsd( + __global const float *src, + __global float *cache, + const int H_in, + const int S_in, + const int D, + const int H_cache, + const int S_cache, + const int n_rep, + const int cache_offset) { + const int d_vec_idx = get_global_id(0); + const int s_idx = get_global_id(1); + const int h_idx_dst = get_global_id(2); + + const int D_vec = D / 4; + if (d_vec_idx >= D_vec || s_idx >= S_in || h_idx_dst >= H_cache) { + return; + } + + const int h_idx_src = h_idx_dst / n_rep; + const int s_idx_dst = cache_offset + s_idx; + + // BHSD [Batch, Head, Sequence, Dim] layout indexing + size_t src_offset = (size_t)h_idx_src * S_in * D + (size_t)s_idx * D + (size_t)d_vec_idx * 4; + size_t dst_offset = (size_t)h_idx_dst * S_cache * D + (size_t)s_idx_dst * D + (size_t)d_vec_idx * 4; + + float4 data_vec = vload4(0, src + src_offset); + vstore4(data_vec, 0, cache + dst_offset); +} + +__kernel void update_kv_cache_fp16_bhsd( + __global const half *src, + __global half *cache, + const int H_in, + const int S_in, + const int D, + const int H_cache, + const int S_cache, + const int n_rep, + const int cache_offset) { + const int d_vec_idx = get_global_id(0); + const int s_idx = get_global_id(1); + const int h_idx_dst = get_global_id(2); + + const int D_vec = D / 4; + if (d_vec_idx >= D_vec || s_idx >= S_in || h_idx_dst >= H_cache) { + return; + } + + const int h_idx_src = h_idx_dst / n_rep; + const int s_idx_dst = cache_offset + s_idx; + + // BHSD [Batch, Head, Sequence, Dim] layout indexing + size_t src_offset = (size_t)h_idx_src * S_in * D + (size_t)s_idx * D + (size_t)d_vec_idx * 4; + size_t dst_offset = (size_t)h_idx_dst * S_cache * D + (size_t)s_idx_dst * D + (size_t)d_vec_idx * 4; + + half4 data_vec = vload4(0, src + src_offset); + vstore4(data_vec, 0, cache + dst_offset); +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/like.cl b/src/backends/opencl/kernel/like.cl new file mode 100644 index 000000000..28f2b7c55 --- /dev/null +++ b/src/backends/opencl/kernel/like.cl @@ -0,0 +1,21 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +__kernel void like( + __global void *output, + const float like_value, + const int count, + const int dtype_size) { // sizeof(float) or sizeof(half) + + const int gid = get_global_id(0); + if (gid >= count) { + return; + } + + if (dtype_size == 4) { // float + __global float *out_fp32 = (__global float *)output; + out_fp32[gid] = like_value; + } else if (dtype_size == 2) { // half + __global half *out_fp16 = (__global half *)output; + out_fp16[gid] = (half)like_value; + } +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/matmul.cl b/src/backends/opencl/kernel/matmul.cl new file mode 100644 index 000000000..bcddf1e50 --- /dev/null +++ b/src/backends/opencl/kernel/matmul.cl @@ -0,0 +1,334 @@ +// opencl/kernel/matmul.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// ================================================================== +// 1. 宏定义和数据结构 +// ================================================================== + +#define TILE_SIZE 16 +#define QK4_0 32 +#define QK8_0 32 + +typedef struct { + half d; + uchar qs[QK4_0 / 2]; +} block_q4_0; + +// ================================================================== +// 2. FP32 BSHD GEMM 内核 +// ================================================================== + +/** + * @brief 高性能浮点矩阵乘法 (FP32 * FP32),支持 BSHD 布局 + */ +__kernel void gemm_fp32( + __global const float *A, + __global const float *B, + __global float *C, + const int M, const int K, const int N, + const int H, const int K_b) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + __local float a_tile[TILE_SIZE][TILE_SIZE]; + __local float b_tile[TILE_SIZE][TILE_SIZE]; + + float acc = 0.0f; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + const int a_k_idx = k_start + local_col; + const int b_k_idx = k_start + local_row; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0f; + } + if (n < N && b_k_idx < K_b) { + b_tile[local_row][local_col] = B[(long)b * K_b * H * N + (long)b_k_idx * H * N + (long)h * N + n]; + } else { + b_tile[local_row][local_col] = 0.0f; + } + barrier(CLK_LOCAL_MEM_FENCE); + + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += a_tile[local_row][k_tile] * b_tile[k_tile][local_col]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + if (s < M && n < N) { + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = acc; + } +} + +// ================================================================== +// 3. FP32 BHSD GEMM 内核 (New) +// ================================================================== +/** + * @brief 高性能浮点矩阵乘法 (FP32 * FP32),支持 BHSD 布局 + */ +__kernel void gemm_fp32_bhsd( + __global const float *A, + __global const float *B, + __global float *C, + const int M, const int K, const int N, + const int H, const int K_b) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + __local float a_tile[TILE_SIZE][TILE_SIZE]; + __local float b_tile[TILE_SIZE][TILE_SIZE]; + + float acc = 0.0f; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + const int a_k_idx = k_start + local_col; + const int b_k_idx = k_start + local_row; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * H * M * K + (long)h * M * K + (long)s * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0f; + } + if (n < N && b_k_idx < K_b) { + b_tile[local_row][local_col] = B[(long)b * H * K_b * N + (long)h * K_b * N + (long)b_k_idx * N + n]; + } else { + b_tile[local_row][local_col] = 0.0f; + } + barrier(CLK_LOCAL_MEM_FENCE); + + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += a_tile[local_row][k_tile] * b_tile[k_tile][local_col]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + if (s < M && n < N) { + C[(long)b * H * M * N + (long)h * M * N + (long)s * N + n] = acc; + } +} + +#if !defined(SUPPORTS_FP16) +// ================================================================== +// 4. FP16 GEMM 内核 (Fallback) +// ================================================================== + +// ---------- [FP16 BSHD 回退版] ---------- +__kernel void gemm_fp16( + __global const half *A, __global const half *B, __global half *C, + const int M, const int K, const int N, const int H, const int K_b) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + if (s >= M || n >= N) return; + + float acc = 0.0f; + for (int k = 0; k < K; ++k) { + long a_idx = (long)b * M * H * K + (long)s * H * K + (long)h * K + k; + long b_idx = (long)b * K_b * H * N + (long)k * H * N + (long)h * N + n; + acc += (float)A[a_idx] * (float)B[b_idx]; + } + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = (half)acc; +} + +// ---------- [FP16 BHSD 回退版] (New) ---------- +__kernel void gemm_fp16_bhsd( + __global const half *A, __global const half *B, __global half *C, + const int M, const int K, const int N, const int H, const int K_b) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + if (s >= M || n >= N) return; + + float acc = 0.0f; + for (int k = 0; k < K; ++k) { + long a_idx = (long)b * H * M * K + (long)h * M * K + (long)s * K + k; + long b_idx = (long)b * H * K_b * N + (long)h * K_b * N + (long)k * N + n; + acc += (float)A[a_idx] * (float)B[b_idx]; + } + C[(long)b * H * M * N + (long)h * M * N + (long)s * N + n] = (half)acc; +} + +#else +// ================================================================== +// 5. FP16 GEMM 内核 (High-Performance) +// ================================================================== + +// ---------- [FP16 BSHD 高性能版] ---------- +__kernel void gemm_fp16( + __global const half *A, __global const half *B, __global half *C, + const int M, const int K, const int N, const int H, const int K_b) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + __local half a_tile[TILE_SIZE][TILE_SIZE]; + __local half b_tile[TILE_SIZE][TILE_SIZE]; + + half acc = 0.0h; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + const int a_k_idx = k_start + local_col; + const int b_k_idx = k_start + local_row; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0h; + } + if (n < N && b_k_idx < K_b) { + b_tile[local_row][local_col] = B[(long)b * K_b * H * N + (long)b_k_idx * H * N + (long)h * N + n]; + } else { + b_tile[local_row][local_col] = 0.0h; + } + barrier(CLK_LOCAL_MEM_FENCE); + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += a_tile[local_row][k_tile] * b_tile[k_tile][local_col]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + if (s < M && n < N) { + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = acc; + } +} + +// ---------- [FP16 BHSD 高性能版] ---------- + +__kernel void gemm_fp16_bhsd( + __global const half *A, __global const half *B, __global half *C, + const int M, const int K, const int N, const int H, const int K_b) { + const int s_out = get_global_id(1); + const int n_out = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + __local half a_tile[TILE_SIZE][TILE_SIZE]; + __local half b_tile[TILE_SIZE][TILE_SIZE]; + half acc = 0.0f; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + const int a_s_idx = get_group_id(1) * TILE_SIZE + local_row; + const int a_k_idx = k_start + local_col; + if (a_s_idx < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * H * M * K + (long)h * M * K + (long)a_s_idx * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0h; + } + const int b_n_idx = get_group_id(0) * TILE_SIZE + local_col; + const int b_k_idx = k_start + local_row; + if (b_n_idx < N && b_k_idx < K_b) { + b_tile[local_col][local_row] = B[(long)b * H * K_b * N + (long)h * K_b * N + (long)b_k_idx * N + b_n_idx]; + } else { + b_tile[local_col][local_row] = 0.0h; + } + barrier(CLK_LOCAL_MEM_FENCE); + +#pragma unroll + for (int k_tile_vec = 0; k_tile_vec < TILE_SIZE; k_tile_vec += 4) { + half4 a_vec = vload4(0, &a_tile[local_row][k_tile_vec]); + half4 b_vec = vload4(0, &b_tile[local_col][k_tile_vec]); + acc += dot(a_vec, b_vec); + } + barrier(CLK_LOCAL_MEM_FENCE); + } + if (s_out < M && n_out < N) { + C[(long)b * H * M * N + (long)h * M * N + (long)s_out * N + n_out] = acc; + } +} + +// #define TILE_M 8 +// #define TILE_N 4 +// #define K_STEP 4 + +// __kernel void gemm_fp16_bhsd( +// __global const half *A, +// __global const half *B, +// __global half *C, +// const int M, +// const int K, +// const int N, +// const int H, +// const int K_b) { +// const int gx = get_global_id(0); +// const int gy = get_global_id(1); +// const int bh_idx = get_global_id(2); +// const int m_base = gy * TILE_M; +// const int n_base = gx * TILE_N; +// if (m_base >= M || n_base >= N) { +// return; +// } +// const int b = bh_idx / H; +// const int h = bh_idx % H; +// __global const half *a_ptr = A + ((long)b * H + h) * M * K; +// __global const half *b_ptr = B + ((long)b * H + h) * K_b * N; +// half4 a_reg; +// half4 b_tile_reg[K_STEP]; +// half c_acc[TILE_M][TILE_N] = {{0.0h}}; +// for (int k_outer = 0; k_outer < K; k_outer += K_STEP) { +// #pragma unroll +// for (int i = 0; i < K_STEP; ++i) { +// if (k_outer + i < K) { +// b_tile_reg[i] = vload4(0, b_ptr + (k_outer + i) * N + n_base); +// } else { +// b_tile_reg[i] = (half4)(0.0h); +// } +// } +// #pragma unroll +// for (int m_local = 0; m_local < TILE_M; ++m_local) { +// if (m_base + m_local < M) { +// a_reg = vload4(0, a_ptr + (m_base + m_local) * K + k_outer); +// // 计算 C[m_local][0] +// half4 b_col0 = (half4)(b_tile_reg[0].s0, b_tile_reg[1].s0, b_tile_reg[2].s0, b_tile_reg[3].s0); +// c_acc[m_local][0] += dot(a_reg, b_col0); +// // 计算 C[m_local][1] +// half4 b_col1 = (half4)(b_tile_reg[0].s1, b_tile_reg[1].s1, b_tile_reg[2].s1, b_tile_reg[3].s1); +// c_acc[m_local][1] += dot(a_reg, b_col1); +// // 计算 C[m_local][2] +// half4 b_col2 = (half4)(b_tile_reg[0].s2, b_tile_reg[1].s2, b_tile_reg[2].s2, b_tile_reg[3].s2); +// c_acc[m_local][2] += dot(a_reg, b_col2); +// // 计算 C[m_local][3] +// half4 b_col3 = (half4)(b_tile_reg[0].s3, b_tile_reg[1].s3, b_tile_reg[2].s3, b_tile_reg[3].s3); +// c_acc[m_local][3] += dot(a_reg, b_col3); +// } +// } +// } +// __global half *c_ptr = C + ((long)b * H + h) * M * N; +// #pragma unroll +// for (int i = 0; i < TILE_M; ++i) { +// if (m_base + i < M) { +// #pragma unroll +// for (int j = 0; j < TILE_N; ++j) { +// if (n_base + j < N) { +// c_ptr[(long)(m_base + i) * N + (n_base + j)] = c_acc[i][j]; +// } +// } +// } +// } +// } + +#endif // SUPPORTS_FP16 diff --git a/src/backends/opencl/kernel/matmul_transb.cl b/src/backends/opencl/kernel/matmul_transb.cl new file mode 100644 index 000000000..a58a2f5aa --- /dev/null +++ b/src/backends/opencl/kernel/matmul_transb.cl @@ -0,0 +1,436 @@ +// opencl/kernel/matmul.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// ================================================================== +// 1. 宏定义和数据结构 +// ================================================================== + +#define TILE_SIZE 16 +#define QK4_0 32 +#define QK8_0 32 + +typedef struct { + half d; + uchar qs[QK4_0 / 2]; +} block_q4_0; + +// ================================================================== +// 2. FP32 GEMM 内核 +// ================================================================== +/** + * @brief 高性能 FP32 GEMM,计算 C = A * B^T + * @param A 矩阵 A,布局为 (B, M, H, K) + * @param B 矩阵 B,布局为 (B, N, H, K) + * @param C 矩阵 C,布局为 (B, M, H, N) + */ +__kernel void gemm_fp32_transb( + __global const float *A, + __global const float *B, + __global float *C, + const int M, const int K, const int N, + const int H) { + // --- 1. 索引计算 --- + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + // --- 2. 初始化和局部内存 --- + __local float a_tile[TILE_SIZE][TILE_SIZE]; + __local float b_tile[TILE_SIZE][TILE_SIZE]; + + float acc = 0.0f; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + + // --- 3. 沿 K 维度进行分块计算 --- + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + + // --- 3a. 协作加载 A 和 B 的 tile --- + // 加载 A 的 tile: A[s, k] + const int a_k_idx = k_start + local_col; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0f; + } + + // 加载 B 的 tile: B[n, k] + // 整个工作组协作加载 B 的一个 TILE_SIZE * TILE_SIZE 区域 + const int b_n_idx = get_group_id(0) * TILE_SIZE + local_row; + const int b_k_idx = k_start + local_col; + if (b_n_idx < N && b_k_idx < K) { + // B 布局为 (B, N, H, K) + b_tile[local_row][local_col] = B[(long)b * N * H * K + (long)b_n_idx * H * K + (long)h * K + b_k_idx]; + } else { + b_tile[local_row][local_col] = 0.0f; + } + + barrier(CLK_LOCAL_MEM_FENCE); + + // --- 3b. 在局部内存中计算点积 --- + // C[s, n] = sum_k A[s, k] * B[n, k] + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + // A[s, k] 从 a_tile[local_row][k_tile] 获取 + // B[n, k] 从 b_tile[local_col][k_tile] 获取 + acc += a_tile[local_row][k_tile] * b_tile[local_col][k_tile]; + } + + barrier(CLK_LOCAL_MEM_FENCE); + } + + // --- 4. 将结果写回全局内存 --- + if (s < M && n < N) { + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = acc; + } +} + +__kernel void gemm_fp32_q4_0_transb( + __global const float *A, + __global const uchar *B_q, + __global float *C, + const int M, const int K, const int N, + const int H, const int K_b) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + __global const block_q4_0 *B = (__global const block_q4_0 *)B_q; + __local float a_tile[TILE_SIZE][TILE_SIZE]; + __local float b_dequant_tile[TILE_SIZE][TILE_SIZE]; + float acc = 0.0f; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + + const int a_k_idx = k_start + local_col; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0f; + } + + const int n_for_load = get_group_id(0) * TILE_SIZE + local_row; + const int k_for_load = k_start + local_col; + + if (n_for_load < N && k_for_load < K) { + const int k_block_idx = k_for_load / QK4_0; + const int k_in_block = k_for_load % QK4_0; + + const long b_block_mem_idx = (long)b * N * H * (K / QK4_0) + (long)n_for_load * H * (K / QK4_0) + (long)h * (K / QK4_0) + k_block_idx; + const __global block_q4_0 *b_block_ptr = &B[b_block_mem_idx]; + + const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); + + const int qs_idx = k_in_block % (QK4_0 / 2); + const uchar q_packed = b_block_ptr->qs[qs_idx]; + + char q_nibble; + if (k_in_block >= (QK4_0 / 2)) { + q_nibble = (q_packed >> 4); + } else { + q_nibble = (q_packed & 0x0F); + } + b_dequant_tile[local_row][local_col] = (float)(q_nibble - 8) * d_b; + } else { + b_dequant_tile[local_row][local_col] = 0.0f; + } + barrier(CLK_LOCAL_MEM_FENCE); + + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += a_tile[local_row][k_tile] * b_dequant_tile[local_col][k_tile]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + if (s < M && n < N) { + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = acc; + } +} + +/**************************************************************************************************/ +/* 新增算子: gemm_fp32_fp16_transb */ +/* 功能: 高性能混合精度矩阵乘法 C(fp32) = A(fp32) * B(fp16)^T */ +/* 架构: 采用与gemm_fp32_transb相同的Tiling架构,确保高性能和边界安全。 */ +/**************************************************************************************************/ +__kernel void gemm_fp32_fp16_transb( + __global const float *A, + __global const half *B, + __global float *C, + const int M, const int K, const int N, + const int H) { + // --- 1. 索引计算 --- + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + // --- 2. 初始化和局部内存 --- + __local float a_tile[TILE_SIZE][TILE_SIZE]; + __local float b_tile[TILE_SIZE][TILE_SIZE]; // B Tile也使用float以保持精度 + + float acc = 0.0f; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + + // --- 3. 沿 K 维度进行分块计算 --- + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + + // --- 3a. 协作加载 A (FP32) tile --- + const int a_k_idx = k_start + local_col; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0f; + } + + // --- 3b. 协作加载 B (FP16) tile 并立即转换为 FP32 --- + const int b_n_idx = get_group_id(0) * TILE_SIZE + local_row; + const int b_k_idx = k_start + local_col; + if (b_n_idx < N && b_k_idx < K) { + // 从全局内存读取half,转换为float,存入局部内存 + b_tile[local_row][local_col] = (float)B[(long)b * N * H * K + (long)b_n_idx * H * K + (long)h * K + b_k_idx]; + } else { + b_tile[local_row][local_col] = 0.0f; + } + + barrier(CLK_LOCAL_MEM_FENCE); + + // --- 3c. 在局部内存中计算点积 (全部为FP32) --- + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += a_tile[local_row][k_tile] * b_tile[local_col][k_tile]; + } + + barrier(CLK_LOCAL_MEM_FENCE); + } + + // --- 4. 将结果写回全局内存 --- + if (s < M && n < N) { + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = acc; + } +} + +// ================================================================== +// 3. FP16 GEMM 内核 +// ================================================================== + +/** + * @brief 高性能 FP16 GEMM,计算 C = A * B^T + */ +#if !defined(SUPPORTS_FP16) +// ---------- [FP16_transb 回退版] ---------- +__kernel void gemm_fp16_transb( + __global const half *A, + __global const half *B, + __global half *C, + const int M, const int K, const int N, + const int H) { + // 1. 索引计算:每个工作项负责计算输出 C 的一个元素 + const int s = get_global_id(1); // C 的行索引 (M 维度) + const int n = get_global_id(0); // C 的列索引 (N 维度) + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + // 边界检查 + if (s >= M || n >= N) return; + + // 2. 计算:C[s,n] = sum_k(A[s,k] * B[n,k]) + // 使用 float 累加器以保证精度,与原始回退版保持一致 + float acc = 0.0f; + for (int k = 0; k < K; ++k) { + // A[s,k] 的索引,布局 (B, M, H, K) + long a_idx = (long)b * M * H * K + (long)s * H * K + (long)h * K + k; + // B[n,k] 的索引,布局 (B, N, H, K) + long b_idx = (long)b * N * H * K + (long)n * H * K + (long)h * K + k; + + acc += (float)A[a_idx] * (float)B[b_idx]; + } + + // 3. 写回结果 + long c_idx = (long)b * M * H * N + (long)s * H * N + (long)h * N + n; + C[c_idx] = (half)acc; +} +#else +// ---------- [FP16_transb 高性能版] ---------- +__kernel void gemm_fp16_transb( + __global const half *A, + __global const half *B, + __global half *C, + const int M, const int K, const int N, + const int H) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + __local half a_tile[TILE_SIZE][TILE_SIZE]; + __local half b_tile[TILE_SIZE][TILE_SIZE]; + + half acc = 0.0h; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + + const int a_k_idx = k_start + local_col; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0h; + } + + const int b_n_idx = get_group_id(0) * TILE_SIZE + local_row; + const int b_k_idx = k_start + local_col; + if (b_n_idx < N && b_k_idx < K) { + b_tile[local_row][local_col] = B[(long)b * N * H * K + (long)b_n_idx * H * K + (long)h * K + b_k_idx]; + } else { + b_tile[local_row][local_col] = 0.0h; + } + + barrier(CLK_LOCAL_MEM_FENCE); + + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += a_tile[local_row][k_tile] * b_tile[local_col][k_tile]; + } + + barrier(CLK_LOCAL_MEM_FENCE); + } + + if (s < M && n < N) { + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = acc; + } +} +#endif // SUPPORTS_FP16 +#if !defined(SUPPORTS_FP16) +// ---------- [FP16_Q4_0 回退版 - 已修正] ---------- +__kernel void gemm_fp16_q4_0_transb( + __global const half *A, + __global const block_q4_0 *B, + __global half *C, + const int M, const int K, const int N, + const int H, const int K_b) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + if (s >= M || n >= N) { + return; + } + + float acc = 0.0f; + + const long a_row_offset = (long)b * M * H * K + (long)s * H * K + (long)h * K; + const long b_row_offset = (long)b * N * H * (K / QK4_0) + (long)n * H * (K / QK4_0) + (long)h * (K / QK4_0); + + for (int k_block_idx = 0; k_block_idx < K / QK4_0; ++k_block_idx) { + const __global block_q4_0 *b_block_ptr = &B[b_row_offset + k_block_idx]; + const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); + + const __global half *a_ptr = A + a_row_offset + k_block_idx * QK4_0; + + for (int j = 0; j < QK4_0 / 2; ++j) { + const uchar q_packed = b_block_ptr->qs[j]; + + const float b_val_0 = (float)((q_packed & 0x0F) - 8) * d_b; + const float b_val_1 = (float)((q_packed >> 4) - 8) * d_b; + + acc += (float)a_ptr[j] * b_val_0; + acc += (float)a_ptr[j + QK4_0 / 2] * b_val_1; + } + } + + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = (half)acc; +} +#else +// ---------- [FP16_Q4_0 高性能版 - 已修正] ---------- +__kernel void gemm_fp16_q4_0_transb( + __global const half *A, + __global const block_q4_0 *B, + __global half *C, + const int M, const int K, const int N, + const int H, const int K_b) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + __local half a_tile[TILE_SIZE][TILE_SIZE]; + __local float b_dequant_tile[TILE_SIZE][TILE_SIZE]; + float acc = 0.0f; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + + const int a_k_idx = k_start + local_col; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0h; + } + + const int n_for_load = get_group_id(0) * TILE_SIZE + local_row; + const int k_for_load = k_start + local_col; + + if (n_for_load < N && k_for_load < K) { + const int k_block_idx = k_for_load / QK4_0; + const int k_in_block = k_for_load % QK4_0; + + const long b_block_mem_idx = (long)b * N * H * (K / QK4_0) + (long)n_for_load * H * (K / QK4_0) + (long)h * (K / QK4_0) + k_block_idx; + const __global block_q4_0 *b_block_ptr = &B[b_block_mem_idx]; + + const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); + + const int qs_idx = k_in_block % (QK4_0 / 2); + const uchar q_packed = b_block_ptr->qs[qs_idx]; + + char q_nibble; + if (k_in_block >= (QK4_0 / 2)) { + q_nibble = (q_packed >> 4); + } else { + q_nibble = (q_packed & 0x0F); + } + b_dequant_tile[local_row][local_col] = (float)(q_nibble - 8) * d_b; + } else { + b_dequant_tile[local_row][local_col] = 0.0f; + } + + barrier(CLK_LOCAL_MEM_FENCE); + + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += (float)a_tile[local_row][k_tile] * b_dequant_tile[local_col][k_tile]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + if (s < M && n < N) { + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = (half)acc; + } +} + +#endif // SUPPORTS_FP16 \ No newline at end of file diff --git a/src/backends/opencl/kernel/matmul_transb_bias.cl b/src/backends/opencl/kernel/matmul_transb_bias.cl new file mode 100644 index 000000000..beb0a3ad1 --- /dev/null +++ b/src/backends/opencl/kernel/matmul_transb_bias.cl @@ -0,0 +1,1972 @@ +// kernel/matmul_transb_bias.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable +#define TILE_SIZE 16 +#define QK4_0 32 +#define QK8_0 32 + +typedef struct { + half d; + uchar qs[QK4_0 / 2]; +} block_q4_0; + +// ================================================================== +// 1. FP32 Fused GEMM + Bias Kernel +// ================================================================== +__kernel void gemm_fp32_transb_bias( + __global const float *A, + __global const float *B, + __global const float *bias, + __global float *C, + const int M, const int K, const int N, + const int H, const int K_b, + const int has_bias) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + __local float a_tile[TILE_SIZE][TILE_SIZE]; + __local float b_tile[TILE_SIZE][TILE_SIZE]; + + float acc = 0.0f; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + + const int a_k_idx = k_start + local_col; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0f; + } + + const int b_n_idx = get_group_id(0) * TILE_SIZE + local_row; + const int b_k_idx = k_start + local_col; + if (b_n_idx < N && b_k_idx < K) { + b_tile[local_row][local_col] = B[(long)b * N * H * K + (long)b_n_idx * H * K + (long)h * K + b_k_idx]; + } else { + b_tile[local_row][local_col] = 0.0f; + } + barrier(CLK_LOCAL_MEM_FENCE); + + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += a_tile[local_row][k_tile] * b_tile[local_col][k_tile]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + if (s < M && n < N) { + if (has_bias != 0) { + acc += bias[n]; + } + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = acc; + } +} + +__kernel void gemm_fp32_fp16_transb_bias( + __global const float *A, + __global const half *B, + __global const float *bias, + __global float *C, + const int M, const int K, const int N, + const int H, + const int has_bias) { + // --- 1. 索引计算 --- + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + // --- 2. 初始化和局部内存 --- + __local float a_tile[TILE_SIZE][TILE_SIZE]; + __local float b_tile[TILE_SIZE][TILE_SIZE]; + + float acc = 0.0f; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + + // --- 3. 沿 K 维度进行分块计算 --- + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + + // --- 3a. 协作加载 A (FP32) tile --- + const int a_k_idx = k_start + local_col; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0f; + } + + // --- 3b. 协作加载 B (FP16) tile 并立即转换为 FP32 --- + const int b_n_idx = get_group_id(0) * TILE_SIZE + local_row; + const int b_k_idx = k_start + local_col; + if (b_n_idx < N && b_k_idx < K) { + b_tile[local_row][local_col] = (float)B[(long)b * N * H * K + (long)b_n_idx * H * K + (long)h * K + b_k_idx]; + } else { + b_tile[local_row][local_col] = 0.0f; + } + + barrier(CLK_LOCAL_MEM_FENCE); + + // --- 3c. 在局部内存中计算点积 (全部为FP32) --- + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += a_tile[local_row][k_tile] * b_tile[local_col][k_tile]; + } + + barrier(CLK_LOCAL_MEM_FENCE); + } + + // --- 4. 添加偏置(可选)并将结果写回全局内存 --- + if (s < M && n < N) { + if (has_bias != 0) { + acc += bias[n]; + } + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = acc; + } +} + +// ================================================================== +// 2. FP16 Fused GEMM + Bias Kernel +// ================================================================== +#if defined(SUPPORTS_FP16) +// ---------- [FP16_transb_bias 高性能版] ---------- +__kernel void gemm_fp16_transb_bias( + __global const half *A, + __global const half *B, + __global const float *bias, + __global half *C, + const int M, const int K, const int N, + const int H, const int K_b, + const int has_bias) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + const int local_row = get_local_id(1); + const int local_col = get_local_id(0); + + __local half a_tile[TILE_SIZE][TILE_SIZE]; + __local half b_tile[TILE_SIZE][TILE_SIZE]; + + half acc = 0.0h; + const int num_tiles = (K + TILE_SIZE - 1) / TILE_SIZE; + + for (int t = 0; t < num_tiles; ++t) { + const int k_start = t * TILE_SIZE; + const int a_k_idx = k_start + local_col; + if (s < M && a_k_idx < K) { + a_tile[local_row][local_col] = A[(long)b * M * H * K + (long)s * H * K + (long)h * K + a_k_idx]; + } else { + a_tile[local_row][local_col] = 0.0h; + } + + const int b_n_idx = get_group_id(0) * TILE_SIZE + local_row; + const int b_k_idx = k_start + local_col; + if (b_n_idx < N && b_k_idx < K) { + b_tile[local_row][local_col] = B[(long)b * N * H * K + (long)b_n_idx * H * K + (long)h * K + b_k_idx]; + } else { + b_tile[local_row][local_col] = 0.0h; + } + barrier(CLK_LOCAL_MEM_FENCE); + + for (int k_tile = 0; k_tile < TILE_SIZE; ++k_tile) { + acc += a_tile[local_row][k_tile] * b_tile[local_col][k_tile]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + if (s < M && n < N) { + if (has_bias != 0) { + acc += bias[n]; + } + C[(long)b * M * H * N + (long)s * H * N + (long)h * N + n] = acc; + } +} +#else +// ---------- [FP16_transb_bias 回退版] ---------- +__kernel void gemm_fp16_transb_bias( + __global const half *A, + __global const half *B, + __global const float *bias, + __global half *C, + const int M, const int K, const int N, + const int H, const int K_b, + const int has_bias) { + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + if (s >= M || n >= N) return; + + float acc = 0.0f; + for (int k = 0; k < K; ++k) { + long a_idx = (long)b * M * H * K + (long)s * H * K + (long)h * K + k; + long b_idx = (long)b * N * H * K + (long)n * H * K + (long)h * K + k; + acc += (float)A[a_idx] * (float)B[b_idx]; + } + + if (has_bias != 0) { + acc += bias[n]; + } + long c_idx = (long)b * M * H * N + (long)s * H * N + (long)h * N + n; + C[c_idx] = (half)acc; +} +#endif // SUPPORTS_FP16 + +// ================================================================== +// 3. FP32 * Q4_0 Fused GEMV + Bias Kernels (for M = 1, Decoding) +// ================================================================== +__kernel void gemv_fp32_q4_0_transb_bias( + __global const float *A, + __global const block_q4_0 *B, + __global const float *bias, + __global float *C, + const int K, const int N, + const int H, + const int has_bias) { + // [修正] 从 group ID 而非 global ID 获取索引,确保工作组内索引统一 + const int n = get_group_id(0); + const int bh_idx = get_group_id(1); + const int b = bh_idx / H; + const int h = bh_idx % H; + + // 边界检查 + if (n >= N) return; + + const int local_id = get_local_id(0); + const int wg_size = get_local_size(0); + __local float partial_sums[256]; + + float private_acc = 0.0f; + const long a_base_idx = (long)b * H * K + (long)h * K; + const long b_row_offset_blocks = (long)b * N * H * (K / QK4_0) + (long)n * H * (K / QK4_0) + (long)h * (K / QK4_0); + + // 并行计算,每个线程计算一部分 + for (int k = local_id; k < K; k += wg_size) { + const int k_block_idx = k / QK4_0; + const int k_in_block = k % QK4_0; + + const __global block_q4_0 *b_block_ptr = &B[b_row_offset_blocks + k_block_idx]; +#if defined(SUPPORTS_FP16) + const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); +#else + const float d_b = (float)(b_block_ptr->d); // TODO Change here [gemini] +#endif + // 反量化逻辑 (这部分与 gemm 内核一致,是正确的) + const uchar q_packed = b_block_ptr->qs[k_in_block % 16]; + char q_nibble = (k_in_block < 16) ? (q_packed & 0x0F) : (q_packed >> 4); + const float b_val = (float)(q_nibble - 8) * d_b; + + private_acc += A[a_base_idx + k] * b_val; + } + + // 将各自的部分和存入局部内存 + partial_sums[local_id] = private_acc; + barrier(CLK_LOCAL_MEM_FENCE); + + // 在工作组内进行规约求和 + for (int offset = wg_size / 2; offset > 0; offset >>= 1) { + if (local_id < offset) { + partial_sums[local_id] += partial_sums[local_id + offset]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + // 由工作组的第一个线程写入最终结果 + if (local_id == 0) { + float final_val = partial_sums[0]; + if (has_bias != 0) { + final_val += bias[n]; + } + const long c_idx = (long)b * H * N + (long)h * N + n; + C[c_idx] = final_val; + } +} +// ================================================================== +// 4. FP32 * Q4_0 Fused GEMM + Bias Kernels (for M > 1, Training) +// ================================================================== + +__kernel void gemm_fp32_q4_0_transb_bias( + __global const float *A, + __global const block_q4_0 *B, + __global const float *bias, + __global float *C, + const int M, const int K, const int N, + const int H, const int K_b, + const int has_bias) { + // --- 1. 索引计算 (与原版保持一致) --- + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + // --- 2. 边界检查 --- + if (s >= M || n >= N) { + return; + } + + // --- 3. 基于寄存器的优化计算 --- + + float acc = 0.0f; + + const long a_row_offset = (long)b * M * H * K + (long)s * H * K + (long)h * K; + const long b_row_offset_blocks = (long)b * N * H * (K / QK4_0) + (long)n * H * (K / QK4_0) + (long)h * (K / QK4_0); + + // 主循环:沿K维度进行,每次处理一个大小为 QK4_0 (32) 的块 + for (int k_block_idx = 0; k_block_idx < K / QK4_0; ++k_block_idx) { + const __global block_q4_0 *b_block_ptr = &B[b_row_offset_blocks + k_block_idx]; + // const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); + +#if defined(SUPPORTS_FP16) + const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); +#else + const float d_b = (float)(b_block_ptr->d); // TODO Change here [gemini] +#endif + const __global float *a_ptr = A + a_row_offset + k_block_idx * QK4_0; + + // ** 向量化核心 ** + // 循环展开,每次处理块内16个 'uchar' 中的4个,对应8个浮点数 + for (int j = 0; j < QK4_0 / 2; j += 4) { // QK4_0/2 = 16 + + // ** 修正点:安全地加载和解包B矩阵的值 ** + // 之前使用*((__global uint*))是不安全的,现改为逐字节加载 + const uchar q_packed0 = b_block_ptr->qs[j + 0]; + const uchar q_packed1 = b_block_ptr->qs[j + 1]; + const uchar q_packed2 = b_block_ptr->qs[j + 2]; + const uchar q_packed3 = b_block_ptr->qs[j + 3]; + + // A矩阵的向量化加载是安全的 + const float4 a_vals_lo = vload4(0, a_ptr + j); + const float4 a_vals_hi = vload4(0, a_ptr + j + (QK4_0 / 2)); // (QK4_0 / 2) = 16 + + // 将4个uchar解包成两个float4向量 + float4 b_dequant_lo; + b_dequant_lo.x = (float)((q_packed0 & 0x0F) - 8) * d_b; // qs[j] 的低4位 + b_dequant_lo.y = (float)((q_packed1 & 0x0F) - 8) * d_b; // qs[j+1] 的低4位 + b_dequant_lo.z = (float)((q_packed2 & 0x0F) - 8) * d_b; // qs[j+2] 的低4位 + b_dequant_lo.w = (float)((q_packed3 & 0x0F) - 8) * d_b; // qs[j+3] 的低4位 + + float4 b_dequant_hi; + b_dequant_hi.x = (float)((q_packed0 >> 4) - 8) * d_b; // qs[j] 的高4位 + b_dequant_hi.y = (float)((q_packed1 >> 4) - 8) * d_b; // qs[j+1] 的高4位 + b_dequant_hi.z = (float)((q_packed2 >> 4) - 8) * d_b; // qs[j+2] 的高4位 + b_dequant_hi.w = (float)((q_packed3 >> 4) - 8) * d_b; // qs[j+3] 的高4位 + + // ** 核心计算 ** + acc += dot(a_vals_lo, b_dequant_lo); + acc += dot(a_vals_hi, b_dequant_hi); + } + } + + if (has_bias != 0) { + acc += bias[n]; + } + + const long c_idx = (long)b * M * H * N + (long)s * H * N + (long)h * N + n; + C[c_idx] = acc; +} + +// ================================================================== +// 5. FP16 * Q4_0 Fused GEMV + Bias Kernel (for M=1, Decoding) +// ================================================================== +#if defined(SUPPORTS_FP16) + +// ---------- [高性能版 - 向量化 + 并行规约] ---------- + +__kernel void gemv_fp16_q4_0_transb_bias( + __global const half *A, + __global const block_q4_0 *B, + __global const float *bias, + __global half *C, + const int K, + const int N, + const int H, + const int has_bias) { + const int n = get_group_id(0); + const int bh_idx = get_group_id(1); + const int b = bh_idx / H; + const int h = bh_idx % H; + if (n >= N) return; + const int local_id = get_local_id(0); + const int wg_size = get_local_size(0); + __local float partial_sums[256]; + float private_acc = 0.0f; + const long a_base_idx = (long)b * H * K + (long)h * K; + const long b_row_offset_blocks = (long)b * N * H * (K / QK4_0) + (long)n * H * (K / QK4_0) + (long)h * (K / QK4_0); + const int num_k_blocks = K / QK4_0; + + for (int k_block_idx = local_id; k_block_idx < num_k_blocks; k_block_idx += wg_size) { + const __global block_q4_0 *b_block_ptr = &B[b_row_offset_blocks + k_block_idx]; + const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); + const __global half *a_ptr = A + a_base_idx + k_block_idx * QK4_0; + +#pragma unroll + for (int j = 0; j < QK4_0 / 2; j += 4) { // j = 0, 4, 8, 12 + const uchar q_packed0 = b_block_ptr->qs[j + 0]; + const uchar q_packed1 = b_block_ptr->qs[j + 1]; + const uchar q_packed2 = b_block_ptr->qs[j + 2]; + const uchar q_packed3 = b_block_ptr->qs[j + 3]; + const int vec_offset_lo = j / 4; + const int vec_offset_hi = j / 4 + 4; + const float4 a_vals_lo = convert_float4(vload4(vec_offset_lo, a_ptr)); + const float4 a_vals_hi = convert_float4(vload4(vec_offset_hi, a_ptr)); + float4 b_dequant_lo, b_dequant_hi; + b_dequant_lo.x = (float)((q_packed0 & 0x0F) - 8) * d_b; + b_dequant_lo.y = (float)((q_packed1 & 0x0F) - 8) * d_b; + b_dequant_lo.z = (float)((q_packed2 & 0x0F) - 8) * d_b; + b_dequant_lo.w = (float)((q_packed3 & 0x0F) - 8) * d_b; + b_dequant_hi.x = (float)((q_packed0 >> 4) - 8) * d_b; + b_dequant_hi.y = (float)((q_packed1 >> 4) - 8) * d_b; + b_dequant_hi.z = (float)((q_packed2 >> 4) - 8) * d_b; + b_dequant_hi.w = (float)((q_packed3 >> 4) - 8) * d_b; + private_acc += dot(a_vals_lo, b_dequant_lo); + private_acc += dot(a_vals_hi, b_dequant_hi); + } + } + partial_sums[local_id] = private_acc; + barrier(CLK_LOCAL_MEM_FENCE); + for (int offset = wg_size / 2; offset > 0; offset >>= 1) { + if (local_id < offset) { + partial_sums[local_id] += partial_sums[local_id + offset]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + if (local_id == 0) { + float final_val = partial_sums[0]; + if (has_bias != 0) { + final_val += bias[n]; + } + const long c_idx = (long)b * H * N + (long)h * N + n; + vstore_half_rte(final_val, 0, &C[c_idx]); + } +} + +// #pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// 定义一个 half16 向量的横向求和辅助函数 +inline float hsum_half16(half16 v) { + half8 r1 = v.lo + v.hi; + half4 r2 = r1.lo + r1.hi; + half2 r3 = r2.lo + r2.hi; + return (float)(r3.x + r3.y); +} + +__kernel void gemv_fp16_q4_0_transb_bias_half16( + __global const half *A, + __global const block_q4_0 *B, + __global const float *bias, + __global half *C, + const int K, + const int N, + const int H, + const int has_bias) { + const int n = get_group_id(0); + const int bh_idx = get_group_id(1); + const int b = bh_idx / H; + const int h = bh_idx % H; + if (n >= N) return; + + const int local_id = get_local_id(0); + const int wg_size = get_local_size(0); + + // 使用 float 累加器保证精度(推荐) + float private_acc = 0.0f; + // 若要追求极致速度(有精度风险),可替换为下一行 + // half private_acc = 0.0h; + + // 使用 float 局部内存保证精度(推荐) + __local float partial_sums[256]; + // 若要追求极致速度,可替换为下一行 + // __local half partial_sums[256]; + + const long a_base_idx = (long)b * H * K + (long)h * K; + const long b_row_offset_blocks = (long)b * N * H * (K / QK4_0) + (long)n * H * (K / QK4_0) + (long)h * (K / QK4_0); + + // K维度被切分为大小为 QK4_0 (32) 的块 + const int num_k_blocks = K / QK4_0; + + for (int k_block_idx = local_id; k_block_idx < num_k_blocks; k_block_idx += wg_size) { + const __global block_q4_0 *b_block_ptr = &B[b_row_offset_blocks + k_block_idx]; + const half d_b = b_block_ptr->d; + + // QK4_0 = 32, a_ptr 指向一个32个half的块 + const __global half *a_ptr = A + a_base_idx + k_block_idx * QK4_0; + + // ** 优化核心:一次处理16个元素 ** + // 处理块的前半部分 (0-15) + const half16 a_vals_lo = vload16(0, a_ptr); + const uchar8 q_packed_lo = vload8(0, b_block_ptr->qs); // 加载8个uchar (包含16个4-bit值) + + // 高效解量化 + char16 b_s_lo; + b_s_lo.s0 = (q_packed_lo.s0 & 0x0F) - 8; + b_s_lo.s1 = (q_packed_lo.s0 >> 4) - 8; + b_s_lo.s2 = (q_packed_lo.s1 & 0x0F) - 8; + b_s_lo.s3 = (q_packed_lo.s1 >> 4) - 8; + b_s_lo.s4 = (q_packed_lo.s2 & 0x0F) - 8; + b_s_lo.s5 = (q_packed_lo.s2 >> 4) - 8; + b_s_lo.s6 = (q_packed_lo.s3 & 0x0F) - 8; + b_s_lo.s7 = (q_packed_lo.s3 >> 4) - 8; + b_s_lo.s8 = (q_packed_lo.s4 & 0x0F) - 8; + b_s_lo.s9 = (q_packed_lo.s4 >> 4) - 8; + b_s_lo.sa = (q_packed_lo.s5 & 0x0F) - 8; + b_s_lo.sb = (q_packed_lo.s5 >> 4) - 8; + b_s_lo.sc = (q_packed_lo.s6 & 0x0F) - 8; + b_s_lo.sd = (q_packed_lo.s6 >> 4) - 8; + b_s_lo.se = (q_packed_lo.s7 & 0x0F) - 8; + b_s_lo.sf = (q_packed_lo.s7 >> 4) - 8; + + const half16 b_vals_dequant_lo = convert_half16(b_s_lo) * d_b; + private_acc += hsum_half16(a_vals_lo * b_vals_dequant_lo); + + // 处理块的后半部分 (16-31) + const half16 a_vals_hi = vload16(0, a_ptr + 16); + const uchar8 q_packed_hi = vload8(0, b_block_ptr->qs + 8); // 加载后8个uchar + + char16 b_s_hi; + b_s_hi.s0 = (q_packed_hi.s0 & 0x0F) - 8; + b_s_hi.s1 = (q_packed_hi.s0 >> 4) - 8; + b_s_hi.s2 = (q_packed_hi.s1 & 0x0F) - 8; + b_s_hi.s3 = (q_packed_hi.s1 >> 4) - 8; + b_s_hi.s4 = (q_packed_hi.s2 & 0x0F) - 8; + b_s_hi.s5 = (q_packed_hi.s2 >> 4) - 8; + b_s_hi.s6 = (q_packed_hi.s3 & 0x0F) - 8; + b_s_hi.s7 = (q_packed_hi.s3 >> 4) - 8; + b_s_hi.s8 = (q_packed_hi.s4 & 0x0F) - 8; + b_s_hi.s9 = (q_packed_hi.s4 >> 4) - 8; + b_s_hi.sa = (q_packed_hi.s5 & 0x0F) - 8; + b_s_hi.sb = (q_packed_hi.s5 >> 4) - 8; + b_s_hi.sc = (q_packed_hi.s6 & 0x0F) - 8; + b_s_hi.sd = (q_packed_hi.s6 >> 4) - 8; + b_s_hi.se = (q_packed_hi.s7 & 0x0F) - 8; + b_s_hi.sf = (q_packed_hi.s7 >> 4) - 8; + + const half16 b_vals_dequant_hi = convert_half16(b_s_hi) * d_b; + private_acc += hsum_half16(a_vals_hi * b_vals_dequant_hi); + } + + partial_sums[local_id] = private_acc; + barrier(CLK_LOCAL_MEM_FENCE); + + // 并行规约 + for (int offset = wg_size / 2; offset > 0; offset >>= 1) { + if (local_id < offset) { + partial_sums[local_id] += partial_sums[local_id + offset]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + // 第一个线程写入最终结果 + if (local_id == 0) { + float final_val = partial_sums[0]; + if (has_bias != 0) { + final_val += bias[n]; + } + const long c_idx = (long)b * H * N + (long)h * N + n; + vstore_half_rte(final_val, 0, &C[c_idx]); + } +} + +#else +// ---------- [兼容版 - 纯标量 + 并行规约] ---------- +__kernel void gemv_fp16_q4_0_transb_bias( + __global const half *A, + __global const block_q4_0 *B, + __global const float *bias, + __global half *C, + const int K, + const int N, + const int H, + const int has_bias) { + // --- 1. 索引计算 (与原版一致) --- + const int n = get_group_id(0); + const int bh_idx = get_group_id(1); + const int b = bh_idx / H; + const int h = bh_idx % H; + if (n >= N) return; + const int local_id = get_local_id(0); + const int wg_size = get_local_size(0); + __local float partial_sums[256]; + float private_acc = 0.0f; + const long a_base_idx = (long)b * H * K + (long)h * K; + const long b_row_offset_blocks = (long)b * N * H * (K / QK4_0) + (long)n * H * (K / QK4_0) + (long)h * (K / QK4_0); + const int num_k_blocks = K / QK4_0; + for (int k_block_idx = local_id; k_block_idx < num_k_blocks; k_block_idx += wg_size) { + const __global block_q4_0 *b_block_ptr = &B[b_row_offset_blocks + k_block_idx]; + const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); + const __global half *a_ptr = A + a_base_idx + k_block_idx * QK4_0; +#pragma unroll + for (int j = 0; j < QK4_0 / 2; j += 4) { + const uchar q_packed0 = b_block_ptr->qs[j + 0]; + const uchar q_packed1 = b_block_ptr->qs[j + 1]; + const uchar q_packed2 = b_block_ptr->qs[j + 2]; + const uchar q_packed3 = b_block_ptr->qs[j + 3]; + // 将vload4替换为手动的标量加载,以避免内存对齐问题。 + float4 a_vals_lo, a_vals_hi; + a_vals_lo.x = (float)a_ptr[j + 0]; + a_vals_lo.y = (float)a_ptr[j + 1]; + a_vals_lo.z = (float)a_ptr[j + 2]; + a_vals_lo.w = (float)a_ptr[j + 3]; + a_vals_hi.x = (float)a_ptr[j + 16 + 0]; + a_vals_hi.y = (float)a_ptr[j + 16 + 1]; + a_vals_hi.z = (float)a_ptr[j + 16 + 2]; + a_vals_hi.w = (float)a_ptr[j + 16 + 3]; + float4 b_dequant_lo, b_dequant_hi; + b_dequant_lo.x = (float)((q_packed0 & 0x0F) - 8) * d_b; + b_dequant_lo.y = (float)((q_packed1 & 0x0F) - 8) * d_b; + b_dequant_lo.z = (float)((q_packed2 & 0x0F) - 8) * d_b; + b_dequant_lo.w = (float)((q_packed3 & 0x0F) - 8) * d_b; + b_dequant_hi.x = (float)((q_packed0 >> 4) - 8) * d_b; + b_dequant_hi.y = (float)((q_packed1 >> 4) - 8) * d_b; + b_dequant_hi.z = (float)((q_packed2 >> 4) - 8) * d_b; + b_dequant_hi.w = (float)((q_packed3 >> 4) - 8) * d_b; + private_acc += dot(a_vals_lo, b_dequant_lo); + private_acc += dot(a_vals_hi, b_dequant_hi); + } + } + partial_sums[local_id] = private_acc; + barrier(CLK_LOCAL_MEM_FENCE); + for (int offset = wg_size / 2; offset > 0; offset >>= 1) { + if (local_id < offset) { + partial_sums[local_id] += partial_sums[local_id + offset]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + if (local_id == 0) { + float final_val = partial_sums[0]; + if (has_bias != 0) { + final_val += bias[n]; + } + const long c_idx = (long)b * H * N + (long)h * N + n; + vstore_half_rte(final_val, 0, &C[c_idx]); + } +} + +#endif // SUPPORTS_FP16 + +// ================================================================== +// 6. FP16 * Q4_0 Fused GEMM + Bias Kernel (for M>1, Prefill) +// ================================================================== +#if defined(SUPPORTS_FP16) +// ---------- [高性能版 - Tiling + 寄存器] ---------- + +#define TILE_M 64 +#define TILE_N 64 +#define TILE_K 16 +#define WPT_M 8 +#define WPT_N 8 +#define THREADS_X (TILE_N / WPT_N) // 8 +#define THREADS_Y (TILE_M / WPT_M) // 8 + +__kernel void gemm_fp16_q4_0_transb_bias( + __global const half *A, + __global const block_q4_0 *B, + __global const float *bias, + __global half *C, + const int M, const int K, const int N, + const int H, const int K_b, + const int has_bias) { + const int group_m_idx = get_group_id(1); + const int group_n_idx = get_group_id(0); + const int local_m_idx = get_local_id(1); + const int local_n_idx = get_local_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + __local half a_tile[TILE_M][TILE_K + 1]; + __local half b_tile[TILE_K][TILE_N + 1]; + float acc[WPT_M][WPT_N]; +#pragma unroll + for (int i = 0; i < WPT_M; ++i) { +#pragma unroll + for (int j = 0; j < WPT_N; ++j) { + acc[i][j] = 0.0f; + } + } + + const long base_a_offset = (long)b * M * H * K + (long)h * K; + const long base_b_offset_blocks = (long)b * N * H * (K / QK4_0) + (long)h * (K / QK4_0); + const int num_k_tiles = (K + TILE_K - 1) / TILE_K; + for (int t = 0; t < num_k_tiles; ++t) { + const int k_start = t * TILE_K; +#pragma unroll + for (int i = 0; i < WPT_M; ++i) { + const int m_local = local_m_idx * WPT_M + i; + const int k_local = local_n_idx; + const int m_global = group_m_idx * TILE_M + m_local; + if (m_global < M) { + for (int k_load_step = 0; k_load_step < TILE_K / THREADS_X; ++k_load_step) { + int k_global = k_start + k_local + k_load_step * THREADS_X; + if (k_global < K) { + a_tile[m_local][k_local + k_load_step * THREADS_X] = A[base_a_offset + m_global * K + k_global]; + } else { + a_tile[m_local][k_local + k_load_step * THREADS_X] = 0.0h; + } + } + } else { + for (int k_load_step = 0; k_load_step < TILE_K / THREADS_X; ++k_load_step) { + a_tile[m_local][k_local + k_load_step * THREADS_X] = 0.0h; + } + } + } + +#pragma unroll + for (int i = 0; i < WPT_N; ++i) { + const int n_local = local_n_idx * WPT_N + i; + const int k_local = local_m_idx; + const int n_global = group_n_idx * TILE_N + n_local; + if (n_global < N) { + for (int k_load_step = 0; k_load_step < TILE_K / THREADS_Y; ++k_load_step) { + int k_global = k_start + k_local + k_load_step * THREADS_Y; + if (k_global < K) { + const int k_block_idx = k_global / QK4_0; + const int k_in_block = k_global % QK4_0; + const __global block_q4_0 *b_block_ptr = &B[base_b_offset_blocks + n_global * (K / QK4_0) + k_block_idx]; + + const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); + + // --- **修正核心** --- + // 1. 根据 k_in_block (0-31) 计算在 qs 数组 (0-15) 中的索引 + const uchar qs_sub_idx = k_in_block % 16; + // 2. 从 qs 数组中取出打包好的两个 4-bit 值 + const uchar q_packed = b_block_ptr->qs[qs_sub_idx]; + // 3. 判断 k_in_block 是在块的前半部分还是后半部分,来决定是取高4位还是低4位 + const bool is_low_nibble = (k_in_block < 16); + char q_nibble = is_low_nibble ? ((q_packed & 0x0F) - 8) : ((q_packed >> 4) - 8); + + // 4. 解量化并存入 b_tile + b_tile[k_local + k_load_step * THREADS_Y][n_local] = (half)((float)q_nibble * d_b); + + } else { + b_tile[k_local + k_load_step * THREADS_Y][n_local] = 0.0h; + } + } + } else { + for (int k_load_step = 0; k_load_step < TILE_K / THREADS_Y; ++k_load_step) { + b_tile[k_local + k_load_step * THREADS_Y][n_local] = 0.0h; + } + } + } + + barrier(CLK_LOCAL_MEM_FENCE); +#pragma unroll + for (int k_tile = 0; k_tile < TILE_K; ++k_tile) { +#pragma unroll + for (int m = 0; m < WPT_M; ++m) { + half a_val = a_tile[local_m_idx * WPT_M + m][k_tile]; +#pragma unroll + for (int n = 0; n < WPT_N; ++n) { + half b_val = b_tile[k_tile][local_n_idx * WPT_N + n]; + acc[m][n] = mad((float)a_val, (float)b_val, acc[m][n]); + } + } + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + long c_offset = (long)b * M * H * N + (long)h * N; +#pragma unroll + for (int m = 0; m < WPT_M; ++m) { + int m_global = group_m_idx * TILE_M + local_m_idx * WPT_M + m; + if (m_global < M) { +#pragma unroll + for (int n = 0; n < WPT_N; ++n) { + int n_global = group_n_idx * TILE_N + local_n_idx * WPT_N + n; + if (n_global < N) { + float result = acc[m][n]; + if (has_bias) { + result += bias[n_global]; + } + C[c_offset + m_global * N + n_global] = (half)result; + } + } + } + } +} + +#else +// ---------- [兼容版] ---------- +__kernel void gemm_fp16_q4_0_transb_bias( + __global const half *A, + __global const block_q4_0 *B, + __global const float *bias, + __global half *C, + const int M, const int K, const int N, + const int H, const int K_b, + const int has_bias) { + // --- 1. 索引计算 --- + const int s = get_global_id(1); + const int n = get_global_id(0); + const int bh_idx = get_global_id(2); + const int b = bh_idx / H; + const int h = bh_idx % H; + + // --- 2. 边界检查 --- + if (s >= M || n >= N) { + return; + } + + // --- 3. 核心计算 --- + float acc = 0.0f; + const long a_row_offset = (long)b * M * H * K + (long)s * H * K + (long)h * K; + const long b_row_offset_blocks = (long)b * N * H * (K / QK4_0) + (long)n * H * (K / QK4_0) + (long)h * (K / QK4_0); + + for (int k_block_idx = 0; k_block_idx < K / QK4_0; ++k_block_idx) { + const __global block_q4_0 *b_block_ptr = &B[b_row_offset_blocks + k_block_idx]; + // 使用 vload_half 确保从 half* 安全加载到 float + const float d_b = vload_half(0, (__global half *)(&(b_block_ptr->d))); + const __global half *a_ptr = A + a_row_offset + k_block_idx * QK4_0; + + for (int j = 0; j < QK4_0 / 2; ++j) { + const uchar q_packed = b_block_ptr->qs[j]; + const char q_lo = (q_packed & 0x0F) - 8; + const char q_hi = (q_packed >> 4) - 8; + + acc += vload_half(j, a_ptr) * (float)q_lo * d_b; + acc += vload_half(j + QK4_0 / 2, a_ptr) * (float)q_hi * d_b; + } + } + + // --- 4. 偏置和写回 --- + if (has_bias != 0) { + acc += bias[n]; + } + const long c_idx = (long)b * M * H * N + (long)s * H * N + (long)h * N + n; + + // 使用 vstore_half_rte 进行精确舍入并存储 + // vstore_half_rte 将 float 类型的 acc 舍入为最接近的 half 值,并将结果存入 C 的 c_idx 位置 + vstore_half_rte(acc, 0, &C[c_idx]); +} +#endif // SUPPORTS_FP16 + +// ================================================================== +// 7. FP32 * Q4_0 Fused GEMM + Bias Kernel (Image Pipe) +// [最终修正版 - 动态解量化 & 修复索引] +// ================================================================== +__kernel void gemm_fp32_q4_0_transb_bias_image_pipe( + sampler_t sampler, + __read_only image2d_t A, + __global const block_q4_0 *B, + __global const float *bias, + __write_only image2d_t C, + const int M, const int K, const int N, + const int H, const int K_b, + const int has_bias) { + // 1. 索引计算 + const int gx = get_global_id(0); + const int gy = get_global_id(1); + const int n_start = gx * 4; + if (n_start >= N) { return; } + + float4 acc = (float4)(0.0f, 0.0f, 0.0f, 0.0f); + const int K_blocks = K / 32; + const long base_offset = 0; // B=1, H=1 + const long n_stride = K_blocks; + + // 3. 沿 K 维度循环计算 + for (int k = 0; k < K; ++k) { + // ** [核心修正] ** + // a. 正确地从 Image A 中读取 FP32 值 + int pixel_x = k / 4; + int component = k % 4; + float4 a_pixel = read_imagef(A, sampler, (int2)(pixel_x, gy)); + float a_val; + if (component == 0) + a_val = a_pixel.x; + else if (component == 1) + a_val = a_pixel.y; + else if (component == 2) + a_val = a_pixel.z; + else + a_val = a_pixel.w; + + // b. 实时解量化 4 个 B 值 (这部分逻辑是正确的) + const int k_block_idx = k / 32; + const int k_in_block = k % 32; + const long b_block_mem_idx0 = base_offset + (long)(n_start + 0) * n_stride + k_block_idx; + const long b_block_mem_idx1 = base_offset + (long)(n_start + 1) * n_stride + k_block_idx; + const long b_block_mem_idx2 = base_offset + (long)(n_start + 2) * n_stride + k_block_idx; + const long b_block_mem_idx3 = base_offset + (long)(n_start + 3) * n_stride + k_block_idx; + + const float d_b0 = vload_half(0, (__global half *)(&(B[b_block_mem_idx0].d))); + const float d_b1 = vload_half(0, (__global half *)(&(B[b_block_mem_idx1].d))); + const float d_b2 = vload_half(0, (__global half *)(&(B[b_block_mem_idx2].d))); + const float d_b3 = vload_half(0, (__global half *)(&(B[b_block_mem_idx3].d))); + + const uchar q_packed0 = B[b_block_mem_idx0].qs[k_in_block % 16]; + const uchar q_packed1 = B[b_block_mem_idx1].qs[k_in_block % 16]; + const uchar q_packed2 = B[b_block_mem_idx2].qs[k_in_block % 16]; + const uchar q_packed3 = B[b_block_mem_idx3].qs[k_in_block % 16]; + + const char q_nibble0 = (k_in_block < 16) ? ((q_packed0 & 0x0F) - 8) : ((q_packed0 >> 4) - 8); + const char q_nibble1 = (k_in_block < 16) ? ((q_packed1 & 0x0F) - 8) : ((q_packed1 >> 4) - 8); + const char q_nibble2 = (k_in_block < 16) ? ((q_packed2 & 0x0F) - 8) : ((q_packed2 >> 4) - 8); + const char q_nibble3 = (k_in_block < 16) ? ((q_packed3 & 0x0F) - 8) : ((q_packed3 >> 4) - 8); + + float4 b_vals = (float4)((float)q_nibble0 * d_b0, (float)q_nibble1 * d_b1, (float)q_nibble2 * d_b2, (float)q_nibble3 * d_b3); + + acc = mad(a_val, b_vals, acc); + } + + if (has_bias != 0) { + float4 bias_vals = vload4(0, bias + n_start); + acc += bias_vals; + } + + write_imagef(C, (int2)(gx, gy), acc); +} + +// ================================================================== +// 8. FP16 * Q4_0 Fused GEMM + Bias Kernel (Image Pipe) +// ================================================================== +#if defined(SUPPORTS_FP16) +/* +__kernel void gemm_fp16_q4_0_transb_bias_image_pipe( + sampler_t sampler, + __read_only image2d_t A, + __global const block_q4_0 *B, + __global const float *bias, + __write_only image2d_t C, + const int K, const int N, + const int H, + const int has_bias) { + // 1. 并行策略: 每个工作项计算一个输出像素 (float4) + const int gx = get_global_id(0); + const int n_start = gx * 4; + if (n_start >= N) { return; } + + // 2. 寄存器累加器 + float4 acc = (float4)(0.0f); + const int K_blocks = K / 32; + const long n_stride = K_blocks; + const int K_vec_size = K / 4; + + // 3. 核心计算循环:沿K维度4倍展开, 深度优化指令级并行 + for (int k_vec = 0; k_vec < K_vec_size; ++k_vec) { + const int k = k_vec * 4; + + // a. 向量化读取A + half4 a_pixel_h = read_imageh(A, sampler, (int2)(k_vec, 0)); + float4 a_vals = convert_float4(a_pixel_h); + + // b. 为 a_vals 的每个分量并行准备权重向量,打破依赖 + // --- 解量化与 a_vals.x (k+0) 相乘的 b_vals_k0 --- + const int k0_block_idx = (k + 0) / 32; + const int k0_in_block = (k + 0) % 32; + const long b_idx0_k0 = (long)(n_start + 0) * n_stride + k0_block_idx; + const long b_idx1_k0 = (long)(n_start + 1) * n_stride + k0_block_idx; + const long b_idx2_k0 = (long)(n_start + 2) * n_stride + k0_block_idx; + const long b_idx3_k0 = (long)(n_start + 3) * n_stride + k0_block_idx; + const float d0_k0 = vload_half(0, (__global half *)(&(B[b_idx0_k0].d))); + const float d1_k0 = vload_half(0, (__global half *)(&(B[b_idx1_k0].d))); + const float d2_k0 = vload_half(0, (__global half *)(&(B[b_idx2_k0].d))); + const float d3_k0 = vload_half(0, (__global half *)(&(B[b_idx3_k0].d))); + const uchar qp0_k0 = B[b_idx0_k0].qs[k0_in_block % 16]; + const uchar qp1_k0 = B[b_idx1_k0].qs[k0_in_block % 16]; + const uchar qp2_k0 = B[b_idx2_k0].qs[k0_in_block % 16]; + const uchar qp3_k0 = B[b_idx3_k0].qs[k0_in_block % 16]; + const char qn0_k0 = (k0_in_block < 16) ? ((qp0_k0 & 0x0F) - 8) : ((qp0_k0 >> 4) - 8); + const char qn1_k0 = (k0_in_block < 16) ? ((qp1_k0 & 0x0F) - 8) : ((qp1_k0 >> 4) - 8); + const char qn2_k0 = (k0_in_block < 16) ? ((qp2_k0 & 0x0F) - 8) : ((qp2_k0 >> 4) - 8); + const char qn3_k0 = (k0_in_block < 16) ? ((qp3_k0 & 0x0F) - 8) : ((qp3_k0 >> 4) - 8); + float4 b_vals_k0 = (float4)((float)qn0_k0 * d0_k0, (float)qn1_k0 * d1_k0, (float)qn2_k0 * d2_k0, (float)qn3_k0 * d3_k0); + + // --- 解量化与 a_vals.y (k+1) 相乘的 b_vals_k1 --- + const int k1_block_idx = (k + 1) / 32; + const int k1_in_block = (k + 1) % 32; + const long b_idx0_k1 = (long)(n_start + 0) * n_stride + k1_block_idx; + const long b_idx1_k1 = (long)(n_start + 1) * n_stride + k1_block_idx; + const long b_idx2_k1 = (long)(n_start + 2) * n_stride + k1_block_idx; + const long b_idx3_k1 = (long)(n_start + 3) * n_stride + k1_block_idx; + const float d0_k1 = vload_half(0, (__global half *)(&(B[b_idx0_k1].d))); + const float d1_k1 = vload_half(0, (__global half *)(&(B[b_idx1_k1].d))); + const float d2_k1 = vload_half(0, (__global half *)(&(B[b_idx2_k1].d))); + const float d3_k1 = vload_half(0, (__global half *)(&(B[b_idx3_k1].d))); + const uchar qp0_k1 = B[b_idx0_k1].qs[k1_in_block % 16]; + const uchar qp1_k1 = B[b_idx1_k1].qs[k1_in_block % 16]; + const uchar qp2_k1 = B[b_idx2_k1].qs[k1_in_block % 16]; + const uchar qp3_k1 = B[b_idx3_k1].qs[k1_in_block % 16]; + const char qn0_k1 = (k1_in_block < 16) ? ((qp0_k1 & 0x0F) - 8) : ((qp0_k1 >> 4) - 8); + const char qn1_k1 = (k1_in_block < 16) ? ((qp1_k1 & 0x0F) - 8) : ((qp1_k1 >> 4) - 8); + const char qn2_k1 = (k1_in_block < 16) ? ((qp2_k1 & 0x0F) - 8) : ((qp2_k1 >> 4) - 8); + const char qn3_k1 = (k1_in_block < 16) ? ((qp3_k1 & 0x0F) - 8) : ((qp3_k1 >> 4) - 8); + float4 b_vals_k1 = (float4)((float)qn0_k1 * d0_k1, (float)qn1_k1 * d1_k1, (float)qn2_k1 * d2_k1, (float)qn3_k1 * d3_k1); + + // --- 解量化与 a_vals.z (k+2) 相乘的 b_vals_k2 --- + const int k2_block_idx = (k + 2) / 32; + const int k2_in_block = (k + 2) % 32; + const long b_idx0_k2 = (long)(n_start + 0) * n_stride + k2_block_idx; + const long b_idx1_k2 = (long)(n_start + 1) * n_stride + k2_block_idx; + const long b_idx2_k2 = (long)(n_start + 2) * n_stride + k2_block_idx; + const long b_idx3_k2 = (long)(n_start + 3) * n_stride + k2_block_idx; + const float d0_k2 = vload_half(0, (__global half *)(&(B[b_idx0_k2].d))); + const float d1_k2 = vload_half(0, (__global half *)(&(B[b_idx1_k2].d))); + const float d2_k2 = vload_half(0, (__global half *)(&(B[b_idx2_k2].d))); + const float d3_k2 = vload_half(0, (__global half *)(&(B[b_idx3_k2].d))); + const uchar qp0_k2 = B[b_idx0_k2].qs[k2_in_block % 16]; + const uchar qp1_k2 = B[b_idx1_k2].qs[k2_in_block % 16]; + const uchar qp2_k2 = B[b_idx2_k2].qs[k2_in_block % 16]; + const uchar qp3_k2 = B[b_idx3_k2].qs[k2_in_block % 16]; + const char qn0_k2 = (k2_in_block < 16) ? ((qp0_k2 & 0x0F) - 8) : ((qp0_k2 >> 4) - 8); + const char qn1_k2 = (k2_in_block < 16) ? ((qp1_k2 & 0x0F) - 8) : ((qp1_k2 >> 4) - 8); + const char qn2_k2 = (k2_in_block < 16) ? ((qp2_k2 & 0x0F) - 8) : ((qp2_k2 >> 4) - 8); + const char qn3_k2 = (k2_in_block < 16) ? ((qp3_k2 & 0x0F) - 8) : ((qp3_k2 >> 4) - 8); + float4 b_vals_k2 = (float4)((float)qn0_k2 * d0_k2, (float)qn1_k2 * d1_k2, (float)qn2_k2 * d2_k2, (float)qn3_k2 * d3_k2); + + // --- 解量化与 a_vals.w (k+3) 相乘的 b_vals_k3 --- + const int k3_block_idx = (k + 3) / 32; + const int k3_in_block = (k + 3) % 32; + const long b_idx0_k3 = (long)(n_start + 0) * n_stride + k3_block_idx; + const long b_idx1_k3 = (long)(n_start + 1) * n_stride + k3_block_idx; + const long b_idx2_k3 = (long)(n_start + 2) * n_stride + k3_block_idx; + const long b_idx3_k3 = (long)(n_start + 3) * n_stride + k3_block_idx; + const float d0_k3 = vload_half(0, (__global half *)(&(B[b_idx0_k3].d))); + const float d1_k3 = vload_half(0, (__global half *)(&(B[b_idx1_k3].d))); + const float d2_k3 = vload_half(0, (__global half *)(&(B[b_idx2_k3].d))); + const float d3_k3 = vload_half(0, (__global half *)(&(B[b_idx3_k3].d))); + const uchar qp0_k3 = B[b_idx0_k3].qs[k3_in_block % 16]; + const uchar qp1_k3 = B[b_idx1_k3].qs[k3_in_block % 16]; + const uchar qp2_k3 = B[b_idx2_k3].qs[k3_in_block % 16]; + const uchar qp3_k3 = B[b_idx3_k3].qs[k3_in_block % 16]; + const char qn0_k3 = (k3_in_block < 16) ? ((qp0_k3 & 0x0F) - 8) : ((qp0_k3 >> 4) - 8); + const char qn1_k3 = (k3_in_block < 16) ? ((qp1_k3 & 0x0F) - 8) : ((qp1_k3 >> 4) - 8); + const char qn2_k3 = (k3_in_block < 16) ? ((qp2_k3 & 0x0F) - 8) : ((qp2_k3 >> 4) - 8); + const char qn3_k3 = (k3_in_block < 16) ? ((qp3_k3 & 0x0F) - 8) : ((qp3_k3 >> 4) - 8); + float4 b_vals_k3 = (float4)((float)qn0_k3 * d0_k3, (float)qn1_k3 * d1_k3, (float)qn2_k3 * d2_k3, (float)qn3_k3 * d3_k3); + + // c. 并行执行 4次独立的MAD指令 + acc = mad(a_vals.x, b_vals_k0, acc); + acc = mad(a_vals.y, b_vals_k1, acc); + acc = mad(a_vals.z, b_vals_k2, acc); + acc = mad(a_vals.w, b_vals_k3, acc); + } + + // 4. 扫尾处理: K不是4的倍数时 + for (int k = K_vec_size * 4; k < K; ++k) { + int pixel_x = k / 4; + int component = k % 4; + half4 a_pixel = read_imageh(A, sampler, (int2)(pixel_x, 0)); + float a_val; + if (component == 0) + a_val = (float)a_pixel.x; + else if (component == 1) + a_val = (float)a_pixel.y; + else if (component == 2) + a_val = (float)a_pixel.z; + else + a_val = (float)a_pixel.w; + + const int k_block_idx = k / 32; + const int k_in_block = k % 32; + const long b_idx0 = (long)(n_start + 0) * n_stride + k_block_idx; + const long b_idx1 = (long)(n_start + 1) * n_stride + k_block_idx; + const long b_idx2 = (long)(n_start + 2) * n_stride + k_block_idx; + const long b_idx3 = (long)(n_start + 3) * n_stride + k_block_idx; + const float d0 = vload_half(0, (__global half *)(&(B[b_idx0].d))); + const float d1 = vload_half(0, (__global half *)(&(B[b_idx1].d))); + const float d2 = vload_half(0, (__global half *)(&(B[b_idx2].d))); + const float d3 = vload_half(0, (__global half *)(&(B[b_idx3].d))); + const uchar qp0 = B[b_idx0].qs[k_in_block % 16]; + const uchar qp1 = B[b_idx1].qs[k_in_block % 16]; + const uchar qp2 = B[b_idx2].qs[k_in_block % 16]; + const uchar qp3 = B[b_idx3].qs[k_in_block % 16]; + const char qn0 = (k_in_block < 16) ? ((qp0 & 0x0F) - 8) : ((qp0 >> 4) - 8); + const char qn1 = (k_in_block < 16) ? ((qp1 & 0x0F) - 8) : ((qp1 >> 4) - 8); + const char qn2 = (k_in_block < 16) ? ((qp2 & 0x0F) - 8) : ((qp2 >> 4) - 8); + const char qn3 = (k_in_block < 16) ? ((qp3 & 0x0F) - 8) : ((qp3 >> 4) - 8); + float4 b_vals = (float4)((float)qn0 * d0, (float)qn1 * d1, (float)qn2 * d2, (float)qn3 * d3); + acc = mad(a_val, b_vals, acc); + } + + // 5. 添加偏置 + if (has_bias != 0) { + acc += vload4(0, bias + n_start); + } + + // 6. 将结果像素写入输出 Image C + write_imageh(C, (int2)(gx, 0), convert_half4_rte(acc)); +} +*/ +__kernel void gemm_fp16_q4_0_transb_bias_image_pipe( + sampler_t sampler, + __read_only image2d_t A, + __global const block_q4_0 *B, + __global const float *bias, + __write_only image2d_t C, + const int M, const int K, const int N, + const int H, const int K_b, + const int has_bias) { + const int gx = get_global_id(0); + const int gy = get_global_id(1); // gy 对应 M 维度 + const int n_start = gx * 4; + + if (n_start >= N || gy >= M) { return; } + + half4 acc = (half4)(0.0h); + + const int K_blocks = K / 32; + const long n_stride = K_blocks; + const int K_vec_size_x8 = K / 8; + + for (int k_vec = 0; k_vec < K_vec_size_x8; ++k_vec) { + const int k = k_vec * 8; + + // **核心区别**: 读取A时,y坐标使用 gy + half4 a_vals_lo = read_imageh(A, sampler, (int2)(k / 4, gy)); + half4 a_vals_hi = read_imageh(A, sampler, (int2)(k / 4 + 1, gy)); + + // --- 8倍展开的解量化与计算(代码同GEMV版,此处为简洁省略)--- + // --- k+0 --- + const int k0_block_idx = (k + 0) / 32; + const int k0_in_block = (k + 0) % 32; + const long b_idx0_k0 = (long)(n_start + 0) * n_stride + k0_block_idx; + const long b_idx1_k0 = (long)(n_start + 1) * n_stride + k0_block_idx; + const long b_idx2_k0 = (long)(n_start + 2) * n_stride + k0_block_idx; + const long b_idx3_k0 = (long)(n_start + 3) * n_stride + k0_block_idx; + const half d0_k0 = vload_half(0, (__global half *)(&(B[b_idx0_k0].d))); + const half d1_k0 = vload_half(0, (__global half *)(&(B[b_idx1_k0].d))); + const half d2_k0 = vload_half(0, (__global half *)(&(B[b_idx2_k0].d))); + const half d3_k0 = vload_half(0, (__global half *)(&(B[b_idx3_k0].d))); + const uchar qp0_k0 = B[b_idx0_k0].qs[k0_in_block % 16]; + const uchar qp1_k0 = B[b_idx1_k0].qs[k0_in_block % 16]; + const uchar qp2_k0 = B[b_idx2_k0].qs[k0_in_block % 16]; + const uchar qp3_k0 = B[b_idx3_k0].qs[k0_in_block % 16]; + const half qn0_k0 = (half)((k0_in_block < 16) ? ((qp0_k0 & 0x0F) - 8) : ((qp0_k0 >> 4) - 8)); + const half qn1_k0 = (half)((k0_in_block < 16) ? ((qp1_k0 & 0x0F) - 8) : ((qp1_k0 >> 4) - 8)); + const half qn2_k0 = (half)((k0_in_block < 16) ? ((qp2_k0 & 0x0F) - 8) : ((qp2_k0 >> 4) - 8)); + const half qn3_k0 = (half)((k0_in_block < 16) ? ((qp3_k0 & 0x0F) - 8) : ((qp3_k0 >> 4) - 8)); + half4 b_vals_k0 = (half4)(qn0_k0 * d0_k0, qn1_k0 * d1_k0, qn2_k0 * d2_k0, qn3_k0 * d3_k0); + // ... k+1 到 k+7 的代码 ... + const int k1_block_idx = (k + 1) / 32; + const int k1_in_block = (k + 1) % 32; + const long b_idx0_k1 = (long)(n_start + 0) * n_stride + k1_block_idx; + const long b_idx1_k1 = (long)(n_start + 1) * n_stride + k1_block_idx; + const long b_idx2_k1 = (long)(n_start + 2) * n_stride + k1_block_idx; + const long b_idx3_k1 = (long)(n_start + 3) * n_stride + k1_block_idx; + const half d0_k1 = vload_half(0, (__global half *)(&(B[b_idx0_k1].d))); + const half d1_k1 = vload_half(0, (__global half *)(&(B[b_idx1_k1].d))); + const half d2_k1 = vload_half(0, (__global half *)(&(B[b_idx2_k1].d))); + const half d3_k1 = vload_half(0, (__global half *)(&(B[b_idx3_k1].d))); + const uchar qp0_k1 = B[b_idx0_k1].qs[k1_in_block % 16]; + const uchar qp1_k1 = B[b_idx1_k1].qs[k1_in_block % 16]; + const uchar qp2_k1 = B[b_idx2_k1].qs[k1_in_block % 16]; + const uchar qp3_k1 = B[b_idx3_k1].qs[k1_in_block % 16]; + const half qn0_k1 = (half)((k1_in_block < 16) ? ((qp0_k1 & 0x0F) - 8) : ((qp0_k1 >> 4) - 8)); + const half qn1_k1 = (half)((k1_in_block < 16) ? ((qp1_k1 & 0x0F) - 8) : ((qp1_k1 >> 4) - 8)); + const half qn2_k1 = (half)((k1_in_block < 16) ? ((qp2_k1 & 0x0F) - 8) : ((qp2_k1 >> 4) - 8)); + const half qn3_k1 = (half)((k1_in_block < 16) ? ((qp3_k1 & 0x0F) - 8) : ((qp3_k1 >> 4) - 8)); + half4 b_vals_k1 = (half4)(qn0_k1 * d0_k1, qn1_k1 * d1_k1, qn2_k1 * d2_k1, qn3_k1 * d3_k1); + const int k2_block_idx = (k + 2) / 32; + const int k2_in_block = (k + 2) % 32; + const long b_idx0_k2 = (long)(n_start + 0) * n_stride + k2_block_idx; + const long b_idx1_k2 = (long)(n_start + 1) * n_stride + k2_block_idx; + const long b_idx2_k2 = (long)(n_start + 2) * n_stride + k2_block_idx; + const long b_idx3_k2 = (long)(n_start + 3) * n_stride + k2_block_idx; + const half d0_k2 = vload_half(0, (__global half *)(&(B[b_idx0_k2].d))); + const half d1_k2 = vload_half(0, (__global half *)(&(B[b_idx1_k2].d))); + const half d2_k2 = vload_half(0, (__global half *)(&(B[b_idx2_k2].d))); + const half d3_k2 = vload_half(0, (__global half *)(&(B[b_idx3_k2].d))); + const uchar qp0_k2 = B[b_idx0_k2].qs[k2_in_block % 16]; + const uchar qp1_k2 = B[b_idx1_k2].qs[k2_in_block % 16]; + const uchar qp2_k2 = B[b_idx2_k2].qs[k2_in_block % 16]; + const uchar qp3_k2 = B[b_idx3_k2].qs[k2_in_block % 16]; + const half qn0_k2 = (half)((k2_in_block < 16) ? ((qp0_k2 & 0x0F) - 8) : ((qp0_k2 >> 4) - 8)); + const half qn1_k2 = (half)((k2_in_block < 16) ? ((qp1_k2 & 0x0F) - 8) : ((qp1_k2 >> 4) - 8)); + const half qn2_k2 = (half)((k2_in_block < 16) ? ((qp2_k2 & 0x0F) - 8) : ((qp2_k2 >> 4) - 8)); + const half qn3_k2 = (half)((k2_in_block < 16) ? ((qp3_k2 & 0x0F) - 8) : ((qp3_k2 >> 4) - 8)); + half4 b_vals_k2 = (half4)(qn0_k2 * d0_k2, qn1_k2 * d1_k2, qn2_k2 * d2_k2, qn3_k2 * d3_k2); + const int k3_block_idx = (k + 3) / 32; + const int k3_in_block = (k + 3) % 32; + const long b_idx0_k3 = (long)(n_start + 0) * n_stride + k3_block_idx; + const long b_idx1_k3 = (long)(n_start + 1) * n_stride + k3_block_idx; + const long b_idx2_k3 = (long)(n_start + 2) * n_stride + k3_block_idx; + const long b_idx3_k3 = (long)(n_start + 3) * n_stride + k3_block_idx; + const half d0_k3 = vload_half(0, (__global half *)(&(B[b_idx0_k3].d))); + const half d1_k3 = vload_half(0, (__global half *)(&(B[b_idx1_k3].d))); + const half d2_k3 = vload_half(0, (__global half *)(&(B[b_idx2_k3].d))); + const half d3_k3 = vload_half(0, (__global half *)(&(B[b_idx3_k3].d))); + const uchar qp0_k3 = B[b_idx0_k3].qs[k3_in_block % 16]; + const uchar qp1_k3 = B[b_idx1_k3].qs[k3_in_block % 16]; + const uchar qp2_k3 = B[b_idx2_k3].qs[k3_in_block % 16]; + const uchar qp3_k3 = B[b_idx3_k3].qs[k3_in_block % 16]; + const half qn0_k3 = (half)((k3_in_block < 16) ? ((qp0_k3 & 0x0F) - 8) : ((qp0_k3 >> 4) - 8)); + const half qn1_k3 = (half)((k3_in_block < 16) ? ((qp1_k3 & 0x0F) - 8) : ((qp1_k3 >> 4) - 8)); + const half qn2_k3 = (half)((k3_in_block < 16) ? ((qp2_k3 & 0x0F) - 8) : ((qp2_k3 >> 4) - 8)); + const half qn3_k3 = (half)((k3_in_block < 16) ? ((qp3_k3 & 0x0F) - 8) : ((qp3_k3 >> 4) - 8)); + half4 b_vals_k3 = (half4)(qn0_k3 * d0_k3, qn1_k3 * d1_k3, qn2_k3 * d2_k3, qn3_k3 * d3_k3); + const int k4_block_idx = (k + 4) / 32; + const int k4_in_block = (k + 4) % 32; + const long b_idx0_k4 = (long)(n_start + 0) * n_stride + k4_block_idx; + const long b_idx1_k4 = (long)(n_start + 1) * n_stride + k4_block_idx; + const long b_idx2_k4 = (long)(n_start + 2) * n_stride + k4_block_idx; + const long b_idx3_k4 = (long)(n_start + 3) * n_stride + k4_block_idx; + const half d0_k4 = vload_half(0, (__global half *)(&(B[b_idx0_k4].d))); + const half d1_k4 = vload_half(0, (__global half *)(&(B[b_idx1_k4].d))); + const half d2_k4 = vload_half(0, (__global half *)(&(B[b_idx2_k4].d))); + const half d3_k4 = vload_half(0, (__global half *)(&(B[b_idx3_k4].d))); + const uchar qp0_k4 = B[b_idx0_k4].qs[k4_in_block % 16]; + const uchar qp1_k4 = B[b_idx1_k4].qs[k4_in_block % 16]; + const uchar qp2_k4 = B[b_idx2_k4].qs[k4_in_block % 16]; + const uchar qp3_k4 = B[b_idx3_k4].qs[k4_in_block % 16]; + const half qn0_k4 = (half)((k4_in_block < 16) ? ((qp0_k4 & 0x0F) - 8) : ((qp0_k4 >> 4) - 8)); + const half qn1_k4 = (half)((k4_in_block < 16) ? ((qp1_k4 & 0x0F) - 8) : ((qp1_k4 >> 4) - 8)); + const half qn2_k4 = (half)((k4_in_block < 16) ? ((qp2_k4 & 0x0F) - 8) : ((qp2_k4 >> 4) - 8)); + const half qn3_k4 = (half)((k4_in_block < 16) ? ((qp3_k4 & 0x0F) - 8) : ((qp3_k4 >> 4) - 8)); + half4 b_vals_k4 = (half4)(qn0_k4 * d0_k4, qn1_k4 * d1_k4, qn2_k4 * d2_k4, qn3_k4 * d3_k4); + const int k5_block_idx = (k + 5) / 32; + const int k5_in_block = (k + 5) % 32; + const long b_idx0_k5 = (long)(n_start + 0) * n_stride + k5_block_idx; + const long b_idx1_k5 = (long)(n_start + 1) * n_stride + k5_block_idx; + const long b_idx2_k5 = (long)(n_start + 2) * n_stride + k5_block_idx; + const long b_idx3_k5 = (long)(n_start + 3) * n_stride + k5_block_idx; + const half d0_k5 = vload_half(0, (__global half *)(&(B[b_idx0_k5].d))); + const half d1_k5 = vload_half(0, (__global half *)(&(B[b_idx1_k5].d))); + const half d2_k5 = vload_half(0, (__global half *)(&(B[b_idx2_k5].d))); + const half d3_k5 = vload_half(0, (__global half *)(&(B[b_idx3_k5].d))); + const uchar qp0_k5 = B[b_idx0_k5].qs[k5_in_block % 16]; + const uchar qp1_k5 = B[b_idx1_k5].qs[k5_in_block % 16]; + const uchar qp2_k5 = B[b_idx2_k5].qs[k5_in_block % 16]; + const uchar qp3_k5 = B[b_idx3_k5].qs[k5_in_block % 16]; + const half qn0_k5 = (half)((k5_in_block < 16) ? ((qp0_k5 & 0x0F) - 8) : ((qp0_k5 >> 4) - 8)); + const half qn1_k5 = (half)((k5_in_block < 16) ? ((qp1_k5 & 0x0F) - 8) : ((qp1_k5 >> 4) - 8)); + const half qn2_k5 = (half)((k5_in_block < 16) ? ((qp2_k5 & 0x0F) - 8) : ((qp2_k5 >> 4) - 8)); + const half qn3_k5 = (half)((k5_in_block < 16) ? ((qp3_k5 & 0x0F) - 8) : ((qp3_k5 >> 4) - 8)); + half4 b_vals_k5 = (half4)(qn0_k5 * d0_k5, qn1_k5 * d1_k5, qn2_k5 * d2_k5, qn3_k5 * d3_k5); + const int k6_block_idx = (k + 6) / 32; + const int k6_in_block = (k + 6) % 32; + const long b_idx0_k6 = (long)(n_start + 0) * n_stride + k6_block_idx; + const long b_idx1_k6 = (long)(n_start + 1) * n_stride + k6_block_idx; + const long b_idx2_k6 = (long)(n_start + 2) * n_stride + k6_block_idx; + const long b_idx3_k6 = (long)(n_start + 3) * n_stride + k6_block_idx; + const half d0_k6 = vload_half(0, (__global half *)(&(B[b_idx0_k6].d))); + const half d1_k6 = vload_half(0, (__global half *)(&(B[b_idx1_k6].d))); + const half d2_k6 = vload_half(0, (__global half *)(&(B[b_idx2_k6].d))); + const half d3_k6 = vload_half(0, (__global half *)(&(B[b_idx3_k6].d))); + const uchar qp0_k6 = B[b_idx0_k6].qs[k6_in_block % 16]; + const uchar qp1_k6 = B[b_idx1_k6].qs[k6_in_block % 16]; + const uchar qp2_k6 = B[b_idx2_k6].qs[k6_in_block % 16]; + const uchar qp3_k6 = B[b_idx3_k6].qs[k6_in_block % 16]; + const half qn0_k6 = (half)((k6_in_block < 16) ? ((qp0_k6 & 0x0F) - 8) : ((qp0_k6 >> 4) - 8)); + const half qn1_k6 = (half)((k6_in_block < 16) ? ((qp1_k6 & 0x0F) - 8) : ((qp1_k6 >> 4) - 8)); + const half qn2_k6 = (half)((k6_in_block < 16) ? ((qp2_k6 & 0x0F) - 8) : ((qp2_k6 >> 4) - 8)); + const half qn3_k6 = (half)((k6_in_block < 16) ? ((qp3_k6 & 0x0F) - 8) : ((qp3_k6 >> 4) - 8)); + half4 b_vals_k6 = (half4)(qn0_k6 * d0_k6, qn1_k6 * d1_k6, qn2_k6 * d2_k6, qn3_k6 * d3_k6); + const int k7_block_idx = (k + 7) / 32; + const int k7_in_block = (k + 7) % 32; + const long b_idx0_k7 = (long)(n_start + 0) * n_stride + k7_block_idx; + const long b_idx1_k7 = (long)(n_start + 1) * n_stride + k7_block_idx; + const long b_idx2_k7 = (long)(n_start + 2) * n_stride + k7_block_idx; + const long b_idx3_k7 = (long)(n_start + 3) * n_stride + k7_block_idx; + const half d0_k7 = vload_half(0, (__global half *)(&(B[b_idx0_k7].d))); + const half d1_k7 = vload_half(0, (__global half *)(&(B[b_idx1_k7].d))); + const half d2_k7 = vload_half(0, (__global half *)(&(B[b_idx2_k7].d))); + const half d3_k7 = vload_half(0, (__global half *)(&(B[b_idx3_k7].d))); + const uchar qp0_k7 = B[b_idx0_k7].qs[k7_in_block % 16]; + const uchar qp1_k7 = B[b_idx1_k7].qs[k7_in_block % 16]; + const uchar qp2_k7 = B[b_idx2_k7].qs[k7_in_block % 16]; + const uchar qp3_k7 = B[b_idx3_k7].qs[k7_in_block % 16]; + const half qn0_k7 = (half)((k7_in_block < 16) ? ((qp0_k7 & 0x0F) - 8) : ((qp0_k7 >> 4) - 8)); + const half qn1_k7 = (half)((k7_in_block < 16) ? ((qp1_k7 & 0x0F) - 8) : ((qp1_k7 >> 4) - 8)); + const half qn2_k7 = (half)((k7_in_block < 16) ? ((qp2_k7 & 0x0F) - 8) : ((qp2_k7 >> 4) - 8)); + const half qn3_k7 = (half)((k7_in_block < 16) ? ((qp3_k7 & 0x0F) - 8) : ((qp3_k7 >> 4) - 8)); + half4 b_vals_k7 = (half4)(qn0_k7 * d0_k7, qn1_k7 * d1_k7, qn2_k7 * d2_k7, qn3_k7 * d3_k7); + + acc = mad(a_vals_lo.x, b_vals_k0, acc); + acc = mad(a_vals_lo.y, b_vals_k1, acc); + acc = mad(a_vals_lo.z, b_vals_k2, acc); + acc = mad(a_vals_lo.w, b_vals_k3, acc); + acc = mad(a_vals_hi.x, b_vals_k4, acc); + acc = mad(a_vals_hi.y, b_vals_k5, acc); + acc = mad(a_vals_hi.z, b_vals_k6, acc); + acc = mad(a_vals_hi.w, b_vals_k7, acc); + } + + // 扫尾和偏置 + for (int k = K_vec_size_x8 * 8; k < K; ++k) { + int pixel_x = k / 4; + int component = k % 4; + half4 a_pixel = read_imageh(A, sampler, (int2)(pixel_x, gy)); + half a_val; + if (component == 0) + a_val = a_pixel.x; + else if (component == 1) + a_val = a_pixel.y; + else if (component == 2) + a_val = a_pixel.z; + else + a_val = a_pixel.w; + const int k_block_idx = k / 32; + const int k_in_block = k % 32; + const long b_idx0 = (long)(n_start + 0) * n_stride + k_block_idx; + const long b_idx1 = (long)(n_start + 1) * n_stride + k_block_idx; + const long b_idx2 = (long)(n_start + 2) * n_stride + k_block_idx; + const long b_idx3 = (long)(n_start + 3) * n_stride + k_block_idx; + const half d0 = vload_half(0, (__global half *)(&(B[b_idx0].d))); + const half d1 = vload_half(0, (__global half *)(&(B[b_idx1].d))); + const half d2 = vload_half(0, (__global half *)(&(B[b_idx2].d))); + const half d3 = vload_half(0, (__global half *)(&(B[b_idx3].d))); + const uchar qp0 = B[b_idx0].qs[k_in_block % 16]; + const uchar qp1 = B[b_idx1].qs[k_in_block % 16]; + const uchar qp2 = B[b_idx2].qs[k_in_block % 16]; + const uchar qp3 = B[b_idx3].qs[k_in_block % 16]; + const half qn0 = (half)((k_in_block < 16) ? ((qp0 & 0x0F) - 8) : ((qp0 >> 4) - 8)); + const half qn1 = (half)((k_in_block < 16) ? ((qp1 & 0x0F) - 8) : ((qp1 >> 4) - 8)); + const half qn2 = (half)((k_in_block < 16) ? ((qp2 & 0x0F) - 8) : ((qp2 >> 4) - 8)); + const half qn3 = (half)((k_in_block < 16) ? ((qp3 & 0x0F) - 8) : ((qp3 >> 4) - 8)); + half4 b_vals = (half4)(qn0 * d0, qn1 * d1, qn2 * d2, qn3 * d3); + acc = mad(a_val, b_vals, acc); + } + + if (has_bias != 0) { + half4 bias_h = convert_half4_rte(vload4(0, bias + n_start)); + if (n_start < N) acc.x += bias_h.x; + if (n_start + 1 < N) acc.y += bias_h.y; + if (n_start + 2 < N) acc.z += bias_h.z; + if (n_start + 3 < N) acc.w += bias_h.w; + } + + write_imageh(C, (int2)(gx, gy), acc); +} +#else +// ---------- [兼容回退版 - Fallback Version] ---------- +__kernel void gemm_fp16_q4_0_transb_bias_image_pipe( + sampler_t sampler, + __read_only image2d_t A, + __global const block_q4_0 *B, + __global const float *bias, + __write_only image2d_t C, + const int M, const int K, const int N, + const int H, const int K_b, + const int has_bias) { + // 逻辑与FP32版本完全相同,因为Host端会准备好FP32的Image + const int gx = get_global_id(0); + const int gy = get_global_id(1); + const int n_start = gx * 4; + if (n_start >= N) { return; } + + float4 acc = (float4)(0.0f, 0.0f, 0.0f, 0.0f); + const int K_blocks = K / 32; + const long base_offset = 0; + const long n_stride = K_blocks; + + for (int k = 0; k < K; ++k) { + int pixel_x = k / 4; + int component = k % 4; + // 使用 read_imagef 读取,因为Image是CL_FLOAT格式 + float4 a_pixel = read_imagef(A, sampler, (int2)(pixel_x, gy)); + float a_val; + if (component == 0) + a_val = a_pixel.x; + else if (component == 1) + a_val = a_pixel.y; + else if (component == 2) + a_val = a_pixel.z; + else + a_val = a_pixel.w; + + const int k_block_idx = k / 32; + const int k_in_block = k % 32; + const long b_block_mem_idx0 = base_offset + (long)(n_start + 0) * n_stride + k_block_idx; + const long b_block_mem_idx1 = base_offset + (long)(n_start + 1) * n_stride + k_block_idx; + const long b_block_mem_idx2 = base_offset + (long)(n_start + 2) * n_stride + k_block_idx; + const long b_block_mem_idx3 = base_offset + (long)(n_start + 3) * n_stride + k_block_idx; + + const float d_b0 = vload_half(0, (__global half *)(&(B[b_block_mem_idx0].d))); + const float d_b1 = vload_half(0, (__global half *)(&(B[b_block_mem_idx1].d))); + const float d_b2 = vload_half(0, (__global half *)(&(B[b_block_mem_idx2].d))); + const float d_b3 = vload_half(0, (__global half *)(&(B[b_block_mem_idx3].d))); + + const uchar q_packed0 = B[b_block_mem_idx0].qs[k_in_block % 16]; + const uchar q_packed1 = B[b_block_mem_idx1].qs[k_in_block % 16]; + const uchar q_packed2 = B[b_block_mem_idx2].qs[k_in_block % 16]; + const uchar q_packed3 = B[b_block_mem_idx3].qs[k_in_block % 16]; + + const char q_nibble0 = (k_in_block < 16) ? ((q_packed0 & 0x0F) - 8) : ((q_packed0 >> 4) - 8); + const char q_nibble1 = (k_in_block < 16) ? ((q_packed1 & 0x0F) - 8) : ((q_packed1 >> 4) - 8); + const char q_nibble2 = (k_in_block < 16) ? ((q_packed2 & 0x0F) - 8) : ((q_packed2 >> 4) - 8); + const char q_nibble3 = (k_in_block < 16) ? ((q_packed3 & 0x0F) - 8) : ((q_packed3 >> 4) - 8); + + float4 b_vals = (float4)((float)q_nibble0 * d_b0, (float)q_nibble1 * d_b1, (float)q_nibble2 * d_b2, (float)q_nibble3 * d_b3); + + acc = mad(a_val, b_vals, acc); + } + + if (has_bias != 0) { + float4 bias_vals = vload4(0, bias + n_start); + acc += bias_vals; + } + + // 使用 write_imagef 写入,因为输出Image也是CL_FLOAT格式 + write_imagef(C, (int2)(gx, gy), acc); +} +#endif // SUPPORTS_FP16 + +// ================================================================== +// 9. FP32 * Q4_0 Fused GEMV + Bias Kernel (All Image Pipe) [最终修正版] +// C = A(Image) * B(Q4_0 Buffer)^T + Bias +// ================================================================== +__kernel void gemv_fp32_q4_0_transb_bias_image_pipe( + sampler_t sampler, + __read_only image2d_t A, + __global const block_q4_0 *B, + __global const float *bias, + __write_only image2d_t C, // 【修改】C 也是 Image + const int K, const int N, + const int H, + const int has_bias) { + // 1. 并行策略: 每个工作项计算一个输出像素 (float4) + const int gx = get_global_id(0); // 对应 C 的 x 坐标, 范围 [0, N/4 - 1] + const int n_start = gx * 4; + if (n_start >= N) { return; } + + // 2. 初始化累加器 + float4 acc = (float4)(0.0f, 0.0f, 0.0f, 0.0f); + + const int K_blocks = K / 32; + const long n_stride = K_blocks; + + // 3. 沿 K 维度循环计算 + for (int k = 0; k < K; ++k) { + // a. 正确地从 Image A 中读取 FP32 值 (y坐标永远是0) + int pixel_x = k / 4; + int component = k % 4; + float4 a_pixel = read_imagef(A, sampler, (int2)(pixel_x, 0)); + float a_val; + if (component == 0) + a_val = a_pixel.x; + else if (component == 1) + a_val = a_pixel.y; + else if (component == 2) + a_val = a_pixel.z; + else + a_val = a_pixel.w; + + // b. 解量化 B 的4个值 + const int k_block_idx = k / 32; + const int k_in_block = k % 32; + const long b_block_mem_idx0 = (long)(n_start + 0) * n_stride + k_block_idx; + const long b_block_mem_idx1 = (long)(n_start + 1) * n_stride + k_block_idx; + const long b_block_mem_idx2 = (long)(n_start + 2) * n_stride + k_block_idx; + const long b_block_mem_idx3 = (long)(n_start + 3) * n_stride + k_block_idx; + + const float d_b0 = vload_half(0, (__global half *)(&(B[b_block_mem_idx0].d))); + const float d_b1 = vload_half(0, (__global half *)(&(B[b_block_mem_idx1].d))); + const float d_b2 = vload_half(0, (__global half *)(&(B[b_block_mem_idx2].d))); + const float d_b3 = vload_half(0, (__global half *)(&(B[b_block_mem_idx3].d))); + + const uchar q_packed0 = B[b_block_mem_idx0].qs[k_in_block % 16]; + const char q_nibble0 = (k_in_block < 16) ? ((q_packed0 & 0x0F) - 8) : ((q_packed0 >> 4) - 8); + const uchar q_packed1 = B[b_block_mem_idx1].qs[k_in_block % 16]; + const char q_nibble1 = (k_in_block < 16) ? ((q_packed1 & 0x0F) - 8) : ((q_packed1 >> 4) - 8); + const uchar q_packed2 = B[b_block_mem_idx2].qs[k_in_block % 16]; + const char q_nibble2 = (k_in_block < 16) ? ((q_packed2 & 0x0F) - 8) : ((q_packed2 >> 4) - 8); + const uchar q_packed3 = B[b_block_mem_idx3].qs[k_in_block % 16]; + const char q_nibble3 = (k_in_block < 16) ? ((q_packed3 & 0x0F) - 8) : ((q_packed3 >> 4) - 8); + + float4 b_vals = (float4)((float)q_nibble0 * d_b0, (float)q_nibble1 * d_b1, (float)q_nibble2 * d_b2, (float)q_nibble3 * d_b3); + + acc = mad(a_val, b_vals, acc); + } + + if (has_bias != 0) { + float4 bias_vals = vload4(0, bias + n_start); + acc += bias_vals; + } + + // 4. 将结果像素写入输出 Image C (y坐标永远是0) + write_imagef(C, (int2)(gx, 0), acc); +} + +// ================================================================== +// 10. FP16 * Q4_0 Fused GEMV + Bias Kernel (All Image Pipe) [最终修正版] +// ================================================================== +#if defined(SUPPORTS_FP16) +// ---------- [高性能版] ---------- +/* +__kernel void gemv_fp16_q4_0_transb_bias_image_pipe( + sampler_t sampler, + __read_only image2d_t A, // 输入向量 A, 形状 [1, K], 映射为 [K/4, 1] 的 half4 Image + __global const block_q4_0 *B, // 权重矩阵 B, 形状 [N, K] + __global const float *bias, // 偏置向量, 形状 [N] + __write_only image2d_t C, // 输出向量 C, 形状 [1, N], 映射为 [N/4, 1] 的 half4 Image + const int K, const int N, + const int H, // H=1, 为了兼容性保留 + const int has_bias) { + // 1. 并行策略: 每个工作项计算一个输出像素 (float4) + const int gx = get_global_id(0); // C 的 x 坐标, 范围 [0, N/4 - 1] + const int n_start = gx * 4; + if (n_start >= N) { return; } + + // 2. 寄存器累加器:使用float4在寄存器中进行高精度累加 + float4 acc = (float4)(0.0f); + const int K_blocks = K / 32; + const long n_stride = K_blocks; + const int K_vec_size = K / 4; + + // 3. 核心计算循环:沿K维度4倍展开, 深度优化指令级并行 + // 每次循环处理K维度的4个元素 + for (int k_vec = 0; k_vec < K_vec_size; ++k_vec) { + const int k = k_vec * 4; + + // a. 向量化读取A: 一次读取4个half, 组成一个half4 + half4 a_pixel_h = read_imageh(A, sampler, (int2)(k_vec, 0)); + float4 a_vals = convert_float4(a_pixel_h); + + // b. 为 a_vals 的每个分量(x,y,z,w) 分别解量化B的值 + // 这部分代码虽然冗长,但将所有计算和访存操作完全展开, + // 能让编译器和硬件最大程度地并行调度,隐藏延迟。 + + // --- 解量化与 a_vals.x (k+0) 相乘的 b_vals_k0 --- + const int k0_block_idx = (k + 0) / 32; + const int k0_in_block = (k + 0) % 32; + const long b_idx0_k0 = (long)(n_start + 0) * n_stride + k0_block_idx; + const long b_idx1_k0 = (long)(n_start + 1) * n_stride + k0_block_idx; + const long b_idx2_k0 = (long)(n_start + 2) * n_stride + k0_block_idx; + const long b_idx3_k0 = (long)(n_start + 3) * n_stride + k0_block_idx; + const float d0_k0 = vload_half(0, (__global half *)(&(B[b_idx0_k0].d))); + const float d1_k0 = vload_half(0, (__global half *)(&(B[b_idx1_k0].d))); + const float d2_k0 = vload_half(0, (__global half *)(&(B[b_idx2_k0].d))); + const float d3_k0 = vload_half(0, (__global half *)(&(B[b_idx3_k0].d))); + const uchar qp0_k0 = B[b_idx0_k0].qs[k0_in_block % 16]; + const uchar qp1_k0 = B[b_idx1_k0].qs[k0_in_block % 16]; + const uchar qp2_k0 = B[b_idx2_k0].qs[k0_in_block % 16]; + const uchar qp3_k0 = B[b_idx3_k0].qs[k0_in_block % 16]; + const char qn0_k0 = (k0_in_block < 16) ? ((qp0_k0 & 0x0F) - 8) : ((qp0_k0 >> 4) - 8); + const char qn1_k0 = (k0_in_block < 16) ? ((qp1_k0 & 0x0F) - 8) : ((qp1_k0 >> 4) - 8); + const char qn2_k0 = (k0_in_block < 16) ? ((qp2_k0 & 0x0F) - 8) : ((qp2_k0 >> 4) - 8); + const char qn3_k0 = (k0_in_block < 16) ? ((qp3_k0 & 0x0F) - 8) : ((qp3_k0 >> 4) - 8); + float4 b_vals_k0 = (float4)((float)qn0_k0 * d0_k0, (float)qn1_k0 * d1_k0, (float)qn2_k0 * d2_k0, (float)qn3_k0 * d3_k0); + + // --- 解量化与 a_vals.y (k+1) 相乘的 b_vals_k1 --- + const int k1_block_idx = (k + 1) / 32; + const int k1_in_block = (k + 1) % 32; + const long b_idx0_k1 = (long)(n_start + 0) * n_stride + k1_block_idx; + const long b_idx1_k1 = (long)(n_start + 1) * n_stride + k1_block_idx; + const long b_idx2_k1 = (long)(n_start + 2) * n_stride + k1_block_idx; + const long b_idx3_k1 = (long)(n_start + 3) * n_stride + k1_block_idx; + const float d0_k1 = vload_half(0, (__global half *)(&(B[b_idx0_k1].d))); + const float d1_k1 = vload_half(0, (__global half *)(&(B[b_idx1_k1].d))); + const float d2_k1 = vload_half(0, (__global half *)(&(B[b_idx2_k1].d))); + const float d3_k1 = vload_half(0, (__global half *)(&(B[b_idx3_k1].d))); + const uchar qp0_k1 = B[b_idx0_k1].qs[k1_in_block % 16]; + const uchar qp1_k1 = B[b_idx1_k1].qs[k1_in_block % 16]; + const uchar qp2_k1 = B[b_idx2_k1].qs[k1_in_block % 16]; + const uchar qp3_k1 = B[b_idx3_k1].qs[k1_in_block % 16]; + const char qn0_k1 = (k1_in_block < 16) ? ((qp0_k1 & 0x0F) - 8) : ((qp0_k1 >> 4) - 8); + const char qn1_k1 = (k1_in_block < 16) ? ((qp1_k1 & 0x0F) - 8) : ((qp1_k1 >> 4) - 8); + const char qn2_k1 = (k1_in_block < 16) ? ((qp2_k1 & 0x0F) - 8) : ((qp2_k1 >> 4) - 8); + const char qn3_k1 = (k1_in_block < 16) ? ((qp3_k1 & 0x0F) - 8) : ((qp3_k1 >> 4) - 8); + float4 b_vals_k1 = (float4)((float)qn0_k1 * d0_k1, (float)qn1_k1 * d1_k1, (float)qn2_k1 * d2_k1, (float)qn3_k1 * d3_k1); + + // --- 解量化与 a_vals.z (k+2) 相乘的 b_vals_k2 --- + const int k2_block_idx = (k + 2) / 32; + const int k2_in_block = (k + 2) % 32; + const long b_idx0_k2 = (long)(n_start + 0) * n_stride + k2_block_idx; + const long b_idx1_k2 = (long)(n_start + 1) * n_stride + k2_block_idx; + const long b_idx2_k2 = (long)(n_start + 2) * n_stride + k2_block_idx; + const long b_idx3_k2 = (long)(n_start + 3) * n_stride + k2_block_idx; + const float d0_k2 = vload_half(0, (__global half *)(&(B[b_idx0_k2].d))); + const float d1_k2 = vload_half(0, (__global half *)(&(B[b_idx1_k2].d))); + const float d2_k2 = vload_half(0, (__global half *)(&(B[b_idx2_k2].d))); + const float d3_k2 = vload_half(0, (__global half *)(&(B[b_idx3_k2].d))); + const uchar qp0_k2 = B[b_idx0_k2].qs[k2_in_block % 16]; + const uchar qp1_k2 = B[b_idx1_k2].qs[k2_in_block % 16]; + const uchar qp2_k2 = B[b_idx2_k2].qs[k2_in_block % 16]; + const uchar qp3_k2 = B[b_idx3_k2].qs[k2_in_block % 16]; + const char qn0_k2 = (k2_in_block < 16) ? ((qp0_k2 & 0x0F) - 8) : ((qp0_k2 >> 4) - 8); + const char qn1_k2 = (k2_in_block < 16) ? ((qp1_k2 & 0x0F) - 8) : ((qp1_k2 >> 4) - 8); + const char qn2_k2 = (k2_in_block < 16) ? ((qp2_k2 & 0x0F) - 8) : ((qp2_k2 >> 4) - 8); + const char qn3_k2 = (k2_in_block < 16) ? ((qp3_k2 & 0x0F) - 8) : ((qp3_k2 >> 4) - 8); + float4 b_vals_k2 = (float4)((float)qn0_k2 * d0_k2, (float)qn1_k2 * d1_k2, (float)qn2_k2 * d2_k2, (float)qn3_k2 * d3_k2); + + // --- 解量化与 a_vals.w (k+3) 相乘的 b_vals_k3 --- + const int k3_block_idx = (k + 3) / 32; + const int k3_in_block = (k + 3) % 32; + const long b_idx0_k3 = (long)(n_start + 0) * n_stride + k3_block_idx; + const long b_idx1_k3 = (long)(n_start + 1) * n_stride + k3_block_idx; + const long b_idx2_k3 = (long)(n_start + 2) * n_stride + k3_block_idx; + const long b_idx3_k3 = (long)(n_start + 3) * n_stride + k3_block_idx; + const float d0_k3 = vload_half(0, (__global half *)(&(B[b_idx0_k3].d))); + const float d1_k3 = vload_half(0, (__global half *)(&(B[b_idx1_k3].d))); + const float d2_k3 = vload_half(0, (__global half *)(&(B[b_idx2_k3].d))); + const float d3_k3 = vload_half(0, (__global half *)(&(B[b_idx3_k3].d))); + const uchar qp0_k3 = B[b_idx0_k3].qs[k3_in_block % 16]; + const uchar qp1_k3 = B[b_idx1_k3].qs[k3_in_block % 16]; + const uchar qp2_k3 = B[b_idx2_k3].qs[k3_in_block % 16]; + const uchar qp3_k3 = B[b_idx3_k3].qs[k3_in_block % 16]; + const char qn0_k3 = (k3_in_block < 16) ? ((qp0_k3 & 0x0F) - 8) : ((qp0_k3 >> 4) - 8); + const char qn1_k3 = (k3_in_block < 16) ? ((qp1_k3 & 0x0F) - 8) : ((qp1_k3 >> 4) - 8); + const char qn2_k3 = (k3_in_block < 16) ? ((qp2_k3 & 0x0F) - 8) : ((qp2_k3 >> 4) - 8); + const char qn3_k3 = (k3_in_block < 16) ? ((qp3_k3 & 0x0F) - 8) : ((qp3_k3 >> 4) - 8); + float4 b_vals_k3 = (float4)((float)qn0_k3 * d0_k3, (float)qn1_k3 * d1_k3, (float)qn2_k3 * d2_k3, (float)qn3_k3 * d3_k3); + + // c. 累加: 4次独立的MAD指令,可以被硬件并行执行 + acc = mad(a_vals.x, b_vals_k0, acc); + acc = mad(a_vals.y, b_vals_k1, acc); + acc = mad(a_vals.z, b_vals_k2, acc); + acc = mad(a_vals.w, b_vals_k3, acc); + } + + // 4. 扫尾处理: K不是4的倍数时,处理余下的1-3个元素 (保持不变) + for (int k = K_vec_size * 4; k < K; ++k) { + int pixel_x = k / 4; + int component = k % 4; + half4 a_pixel = read_imageh(A, sampler, (int2)(pixel_x, 0)); + float a_val; + if (component == 0) + a_val = (float)a_pixel.x; + else if (component == 1) + a_val = (float)a_pixel.y; + else if (component == 2) + a_val = (float)a_pixel.z; + else + a_val = (float)a_pixel.w; + + const int k_block_idx = k / 32; + const int k_in_block = k % 32; + const long b_idx0 = (long)(n_start + 0) * n_stride + k_block_idx; + const long b_idx1 = (long)(n_start + 1) * n_stride + k_block_idx; + const long b_idx2 = (long)(n_start + 2) * n_stride + k_block_idx; + const long b_idx3 = (long)(n_start + 3) * n_stride + k_block_idx; + const float d0 = vload_half(0, (__global half *)(&(B[b_idx0].d))); + const float d1 = vload_half(0, (__global half *)(&(B[b_idx1].d))); + const float d2 = vload_half(0, (__global half *)(&(B[b_idx2].d))); + const float d3 = vload_half(0, (__global half *)(&(B[b_idx3].d))); + const uchar qp0 = B[b_idx0].qs[k_in_block % 16]; + const uchar qp1 = B[b_idx1].qs[k_in_block % 16]; + const uchar qp2 = B[b_idx2].qs[k_in_block % 16]; + const uchar qp3 = B[b_idx3].qs[k_in_block % 16]; + const char qn0 = (k_in_block < 16) ? ((qp0 & 0x0F) - 8) : ((qp0 >> 4) - 8); + const char qn1 = (k_in_block < 16) ? ((qp1 & 0x0F) - 8) : ((qp1 >> 4) - 8); + const char qn2 = (k_in_block < 16) ? ((qp2 & 0x0F) - 8) : ((qp2 >> 4) - 8); + const char qn3 = (k_in_block < 16) ? ((qp3 & 0x0F) - 8) : ((qp3 >> 4) - 8); + float4 b_vals = (float4)((float)qn0 * d0, (float)qn1 * d1, (float)qn2 * d2, (float)qn3 * d3); + + acc = mad(a_val, b_vals, acc); + } + + // 5. 添加偏置 (优化为单次vload4,因为N通常是4的倍数) + if (has_bias != 0) { + float4 bias_vals = vload4(0, bias + n_start); + acc += bias_vals; + } + + // 6. 将结果像素写入输出 Image C + write_imageh(C, (int2)(gx, 0), convert_half4_rte(acc)); +} +*/ +__kernel void gemv_fp16_q4_0_transb_bias_image_pipe( + sampler_t sampler, + __read_only image2d_t A, + __global const block_q4_0 *B, + __global const float *bias, + __write_only image2d_t C, + const int K, const int N, + const int H, + const int has_bias) { + const int gx = get_global_id(0); + const int n_start = gx * 4; + if (n_start >= N) { return; } + + half4 acc = (half4)(0.0h); + + const int K_blocks = K / 32; + const long n_stride = K_blocks; + const int K_vec_size_x8 = K / 8; + + for (int k_vec = 0; k_vec < K_vec_size_x8; ++k_vec) { + const int k = k_vec * 8; + + // 读取A时,y坐标固定为0,因为是GEMV + half4 a_vals_lo = read_imageh(A, sampler, (int2)(k / 4, 0)); + half4 a_vals_hi = read_imageh(A, sampler, (int2)(k / 4 + 1, 0)); + + // --- 8倍展开的解量化与计算(代码同上一版,此处为简洁省略)--- + // --- k+0 --- + const int k0_block_idx = (k + 0) / 32; + const int k0_in_block = (k + 0) % 32; + const long b_idx0_k0 = (long)(n_start + 0) * n_stride + k0_block_idx; + const long b_idx1_k0 = (long)(n_start + 1) * n_stride + k0_block_idx; + const long b_idx2_k0 = (long)(n_start + 2) * n_stride + k0_block_idx; + const long b_idx3_k0 = (long)(n_start + 3) * n_stride + k0_block_idx; + const half d0_k0 = vload_half(0, (__global half *)(&(B[b_idx0_k0].d))); + const half d1_k0 = vload_half(0, (__global half *)(&(B[b_idx1_k0].d))); + const half d2_k0 = vload_half(0, (__global half *)(&(B[b_idx2_k0].d))); + const half d3_k0 = vload_half(0, (__global half *)(&(B[b_idx3_k0].d))); + const uchar qp0_k0 = B[b_idx0_k0].qs[k0_in_block % 16]; + const uchar qp1_k0 = B[b_idx1_k0].qs[k0_in_block % 16]; + const uchar qp2_k0 = B[b_idx2_k0].qs[k0_in_block % 16]; + const uchar qp3_k0 = B[b_idx3_k0].qs[k0_in_block % 16]; + const half qn0_k0 = (half)((k0_in_block < 16) ? ((qp0_k0 & 0x0F) - 8) : ((qp0_k0 >> 4) - 8)); + const half qn1_k0 = (half)((k0_in_block < 16) ? ((qp1_k0 & 0x0F) - 8) : ((qp1_k0 >> 4) - 8)); + const half qn2_k0 = (half)((k0_in_block < 16) ? ((qp2_k0 & 0x0F) - 8) : ((qp2_k0 >> 4) - 8)); + const half qn3_k0 = (half)((k0_in_block < 16) ? ((qp3_k0 & 0x0F) - 8) : ((qp3_k0 >> 4) - 8)); + half4 b_vals_k0 = (half4)(qn0_k0 * d0_k0, qn1_k0 * d1_k0, qn2_k0 * d2_k0, qn3_k0 * d3_k0); + // ... k+1 到 k+7 的代码 ... + const int k1_block_idx = (k + 1) / 32; + const int k1_in_block = (k + 1) % 32; + const long b_idx0_k1 = (long)(n_start + 0) * n_stride + k1_block_idx; + const long b_idx1_k1 = (long)(n_start + 1) * n_stride + k1_block_idx; + const long b_idx2_k1 = (long)(n_start + 2) * n_stride + k1_block_idx; + const long b_idx3_k1 = (long)(n_start + 3) * n_stride + k1_block_idx; + const half d0_k1 = vload_half(0, (__global half *)(&(B[b_idx0_k1].d))); + const half d1_k1 = vload_half(0, (__global half *)(&(B[b_idx1_k1].d))); + const half d2_k1 = vload_half(0, (__global half *)(&(B[b_idx2_k1].d))); + const half d3_k1 = vload_half(0, (__global half *)(&(B[b_idx3_k1].d))); + const uchar qp0_k1 = B[b_idx0_k1].qs[k1_in_block % 16]; + const uchar qp1_k1 = B[b_idx1_k1].qs[k1_in_block % 16]; + const uchar qp2_k1 = B[b_idx2_k1].qs[k1_in_block % 16]; + const uchar qp3_k1 = B[b_idx3_k1].qs[k1_in_block % 16]; + const half qn0_k1 = (half)((k1_in_block < 16) ? ((qp0_k1 & 0x0F) - 8) : ((qp0_k1 >> 4) - 8)); + const half qn1_k1 = (half)((k1_in_block < 16) ? ((qp1_k1 & 0x0F) - 8) : ((qp1_k1 >> 4) - 8)); + const half qn2_k1 = (half)((k1_in_block < 16) ? ((qp2_k1 & 0x0F) - 8) : ((qp2_k1 >> 4) - 8)); + const half qn3_k1 = (half)((k1_in_block < 16) ? ((qp3_k1 & 0x0F) - 8) : ((qp3_k1 >> 4) - 8)); + half4 b_vals_k1 = (half4)(qn0_k1 * d0_k1, qn1_k1 * d1_k1, qn2_k1 * d2_k1, qn3_k1 * d3_k1); + const int k2_block_idx = (k + 2) / 32; + const int k2_in_block = (k + 2) % 32; + const long b_idx0_k2 = (long)(n_start + 0) * n_stride + k2_block_idx; + const long b_idx1_k2 = (long)(n_start + 1) * n_stride + k2_block_idx; + const long b_idx2_k2 = (long)(n_start + 2) * n_stride + k2_block_idx; + const long b_idx3_k2 = (long)(n_start + 3) * n_stride + k2_block_idx; + const half d0_k2 = vload_half(0, (__global half *)(&(B[b_idx0_k2].d))); + const half d1_k2 = vload_half(0, (__global half *)(&(B[b_idx1_k2].d))); + const half d2_k2 = vload_half(0, (__global half *)(&(B[b_idx2_k2].d))); + const half d3_k2 = vload_half(0, (__global half *)(&(B[b_idx3_k2].d))); + const uchar qp0_k2 = B[b_idx0_k2].qs[k2_in_block % 16]; + const uchar qp1_k2 = B[b_idx1_k2].qs[k2_in_block % 16]; + const uchar qp2_k2 = B[b_idx2_k2].qs[k2_in_block % 16]; + const uchar qp3_k2 = B[b_idx3_k2].qs[k2_in_block % 16]; + const half qn0_k2 = (half)((k2_in_block < 16) ? ((qp0_k2 & 0x0F) - 8) : ((qp0_k2 >> 4) - 8)); + const half qn1_k2 = (half)((k2_in_block < 16) ? ((qp1_k2 & 0x0F) - 8) : ((qp1_k2 >> 4) - 8)); + const half qn2_k2 = (half)((k2_in_block < 16) ? ((qp2_k2 & 0x0F) - 8) : ((qp2_k2 >> 4) - 8)); + const half qn3_k2 = (half)((k2_in_block < 16) ? ((qp3_k2 & 0x0F) - 8) : ((qp3_k2 >> 4) - 8)); + half4 b_vals_k2 = (half4)(qn0_k2 * d0_k2, qn1_k2 * d1_k2, qn2_k2 * d2_k2, qn3_k2 * d3_k2); + const int k3_block_idx = (k + 3) / 32; + const int k3_in_block = (k + 3) % 32; + const long b_idx0_k3 = (long)(n_start + 0) * n_stride + k3_block_idx; + const long b_idx1_k3 = (long)(n_start + 1) * n_stride + k3_block_idx; + const long b_idx2_k3 = (long)(n_start + 2) * n_stride + k3_block_idx; + const long b_idx3_k3 = (long)(n_start + 3) * n_stride + k3_block_idx; + const half d0_k3 = vload_half(0, (__global half *)(&(B[b_idx0_k3].d))); + const half d1_k3 = vload_half(0, (__global half *)(&(B[b_idx1_k3].d))); + const half d2_k3 = vload_half(0, (__global half *)(&(B[b_idx2_k3].d))); + const half d3_k3 = vload_half(0, (__global half *)(&(B[b_idx3_k3].d))); + const uchar qp0_k3 = B[b_idx0_k3].qs[k3_in_block % 16]; + const uchar qp1_k3 = B[b_idx1_k3].qs[k3_in_block % 16]; + const uchar qp2_k3 = B[b_idx2_k3].qs[k3_in_block % 16]; + const uchar qp3_k3 = B[b_idx3_k3].qs[k3_in_block % 16]; + const half qn0_k3 = (half)((k3_in_block < 16) ? ((qp0_k3 & 0x0F) - 8) : ((qp0_k3 >> 4) - 8)); + const half qn1_k3 = (half)((k3_in_block < 16) ? ((qp1_k3 & 0x0F) - 8) : ((qp1_k3 >> 4) - 8)); + const half qn2_k3 = (half)((k3_in_block < 16) ? ((qp2_k3 & 0x0F) - 8) : ((qp2_k3 >> 4) - 8)); + const half qn3_k3 = (half)((k3_in_block < 16) ? ((qp3_k3 & 0x0F) - 8) : ((qp3_k3 >> 4) - 8)); + half4 b_vals_k3 = (half4)(qn0_k3 * d0_k3, qn1_k3 * d1_k3, qn2_k3 * d2_k3, qn3_k3 * d3_k3); + const int k4_block_idx = (k + 4) / 32; + const int k4_in_block = (k + 4) % 32; + const long b_idx0_k4 = (long)(n_start + 0) * n_stride + k4_block_idx; + const long b_idx1_k4 = (long)(n_start + 1) * n_stride + k4_block_idx; + const long b_idx2_k4 = (long)(n_start + 2) * n_stride + k4_block_idx; + const long b_idx3_k4 = (long)(n_start + 3) * n_stride + k4_block_idx; + const half d0_k4 = vload_half(0, (__global half *)(&(B[b_idx0_k4].d))); + const half d1_k4 = vload_half(0, (__global half *)(&(B[b_idx1_k4].d))); + const half d2_k4 = vload_half(0, (__global half *)(&(B[b_idx2_k4].d))); + const half d3_k4 = vload_half(0, (__global half *)(&(B[b_idx3_k4].d))); + const uchar qp0_k4 = B[b_idx0_k4].qs[k4_in_block % 16]; + const uchar qp1_k4 = B[b_idx1_k4].qs[k4_in_block % 16]; + const uchar qp2_k4 = B[b_idx2_k4].qs[k4_in_block % 16]; + const uchar qp3_k4 = B[b_idx3_k4].qs[k4_in_block % 16]; + const half qn0_k4 = (half)((k4_in_block < 16) ? ((qp0_k4 & 0x0F) - 8) : ((qp0_k4 >> 4) - 8)); + const half qn1_k4 = (half)((k4_in_block < 16) ? ((qp1_k4 & 0x0F) - 8) : ((qp1_k4 >> 4) - 8)); + const half qn2_k4 = (half)((k4_in_block < 16) ? ((qp2_k4 & 0x0F) - 8) : ((qp2_k4 >> 4) - 8)); + const half qn3_k4 = (half)((k4_in_block < 16) ? ((qp3_k4 & 0x0F) - 8) : ((qp3_k4 >> 4) - 8)); + half4 b_vals_k4 = (half4)(qn0_k4 * d0_k4, qn1_k4 * d1_k4, qn2_k4 * d2_k4, qn3_k4 * d3_k4); + const int k5_block_idx = (k + 5) / 32; + const int k5_in_block = (k + 5) % 32; + const long b_idx0_k5 = (long)(n_start + 0) * n_stride + k5_block_idx; + const long b_idx1_k5 = (long)(n_start + 1) * n_stride + k5_block_idx; + const long b_idx2_k5 = (long)(n_start + 2) * n_stride + k5_block_idx; + const long b_idx3_k5 = (long)(n_start + 3) * n_stride + k5_block_idx; + const half d0_k5 = vload_half(0, (__global half *)(&(B[b_idx0_k5].d))); + const half d1_k5 = vload_half(0, (__global half *)(&(B[b_idx1_k5].d))); + const half d2_k5 = vload_half(0, (__global half *)(&(B[b_idx2_k5].d))); + const half d3_k5 = vload_half(0, (__global half *)(&(B[b_idx3_k5].d))); + const uchar qp0_k5 = B[b_idx0_k5].qs[k5_in_block % 16]; + const uchar qp1_k5 = B[b_idx1_k5].qs[k5_in_block % 16]; + const uchar qp2_k5 = B[b_idx2_k5].qs[k5_in_block % 16]; + const uchar qp3_k5 = B[b_idx3_k5].qs[k5_in_block % 16]; + const half qn0_k5 = (half)((k5_in_block < 16) ? ((qp0_k5 & 0x0F) - 8) : ((qp0_k5 >> 4) - 8)); + const half qn1_k5 = (half)((k5_in_block < 16) ? ((qp1_k5 & 0x0F) - 8) : ((qp1_k5 >> 4) - 8)); + const half qn2_k5 = (half)((k5_in_block < 16) ? ((qp2_k5 & 0x0F) - 8) : ((qp2_k5 >> 4) - 8)); + const half qn3_k5 = (half)((k5_in_block < 16) ? ((qp3_k5 & 0x0F) - 8) : ((qp3_k5 >> 4) - 8)); + half4 b_vals_k5 = (half4)(qn0_k5 * d0_k5, qn1_k5 * d1_k5, qn2_k5 * d2_k5, qn3_k5 * d3_k5); + const int k6_block_idx = (k + 6) / 32; + const int k6_in_block = (k + 6) % 32; + const long b_idx0_k6 = (long)(n_start + 0) * n_stride + k6_block_idx; + const long b_idx1_k6 = (long)(n_start + 1) * n_stride + k6_block_idx; + const long b_idx2_k6 = (long)(n_start + 2) * n_stride + k6_block_idx; + const long b_idx3_k6 = (long)(n_start + 3) * n_stride + k6_block_idx; + const half d0_k6 = vload_half(0, (__global half *)(&(B[b_idx0_k6].d))); + const half d1_k6 = vload_half(0, (__global half *)(&(B[b_idx1_k6].d))); + const half d2_k6 = vload_half(0, (__global half *)(&(B[b_idx2_k6].d))); + const half d3_k6 = vload_half(0, (__global half *)(&(B[b_idx3_k6].d))); + const uchar qp0_k6 = B[b_idx0_k6].qs[k6_in_block % 16]; + const uchar qp1_k6 = B[b_idx1_k6].qs[k6_in_block % 16]; + const uchar qp2_k6 = B[b_idx2_k6].qs[k6_in_block % 16]; + const uchar qp3_k6 = B[b_idx3_k6].qs[k6_in_block % 16]; + const half qn0_k6 = (half)((k6_in_block < 16) ? ((qp0_k6 & 0x0F) - 8) : ((qp0_k6 >> 4) - 8)); + const half qn1_k6 = (half)((k6_in_block < 16) ? ((qp1_k6 & 0x0F) - 8) : ((qp1_k6 >> 4) - 8)); + const half qn2_k6 = (half)((k6_in_block < 16) ? ((qp2_k6 & 0x0F) - 8) : ((qp2_k6 >> 4) - 8)); + const half qn3_k6 = (half)((k6_in_block < 16) ? ((qp3_k6 & 0x0F) - 8) : ((qp3_k6 >> 4) - 8)); + half4 b_vals_k6 = (half4)(qn0_k6 * d0_k6, qn1_k6 * d1_k6, qn2_k6 * d2_k6, qn3_k6 * d3_k6); + const int k7_block_idx = (k + 7) / 32; + const int k7_in_block = (k + 7) % 32; + const long b_idx0_k7 = (long)(n_start + 0) * n_stride + k7_block_idx; + const long b_idx1_k7 = (long)(n_start + 1) * n_stride + k7_block_idx; + const long b_idx2_k7 = (long)(n_start + 2) * n_stride + k7_block_idx; + const long b_idx3_k7 = (long)(n_start + 3) * n_stride + k7_block_idx; + const half d0_k7 = vload_half(0, (__global half *)(&(B[b_idx0_k7].d))); + const half d1_k7 = vload_half(0, (__global half *)(&(B[b_idx1_k7].d))); + const half d2_k7 = vload_half(0, (__global half *)(&(B[b_idx2_k7].d))); + const half d3_k7 = vload_half(0, (__global half *)(&(B[b_idx3_k7].d))); + const uchar qp0_k7 = B[b_idx0_k7].qs[k7_in_block % 16]; + const uchar qp1_k7 = B[b_idx1_k7].qs[k7_in_block % 16]; + const uchar qp2_k7 = B[b_idx2_k7].qs[k7_in_block % 16]; + const uchar qp3_k7 = B[b_idx3_k7].qs[k7_in_block % 16]; + const half qn0_k7 = (half)((k7_in_block < 16) ? ((qp0_k7 & 0x0F) - 8) : ((qp0_k7 >> 4) - 8)); + const half qn1_k7 = (half)((k7_in_block < 16) ? ((qp1_k7 & 0x0F) - 8) : ((qp1_k7 >> 4) - 8)); + const half qn2_k7 = (half)((k7_in_block < 16) ? ((qp2_k7 & 0x0F) - 8) : ((qp2_k7 >> 4) - 8)); + const half qn3_k7 = (half)((k7_in_block < 16) ? ((qp3_k7 & 0x0F) - 8) : ((qp3_k7 >> 4) - 8)); + half4 b_vals_k7 = (half4)(qn0_k7 * d0_k7, qn1_k7 * d1_k7, qn2_k7 * d2_k7, qn3_k7 * d3_k7); + + acc = mad(a_vals_lo.x, b_vals_k0, acc); + acc = mad(a_vals_lo.y, b_vals_k1, acc); + acc = mad(a_vals_lo.z, b_vals_k2, acc); + acc = mad(a_vals_lo.w, b_vals_k3, acc); + acc = mad(a_vals_hi.x, b_vals_k4, acc); + acc = mad(a_vals_hi.y, b_vals_k5, acc); + acc = mad(a_vals_hi.z, b_vals_k6, acc); + acc = mad(a_vals_hi.w, b_vals_k7, acc); + } + + for (int k = K_vec_size_x8 * 8; k < K; ++k) { + int pixel_x = k / 4; + int component = k % 4; + half4 a_pixel = read_imageh(A, sampler, (int2)(pixel_x, 0)); + half a_val; + if (component == 0) + a_val = a_pixel.x; + else if (component == 1) + a_val = a_pixel.y; + else if (component == 2) + a_val = a_pixel.z; + else + a_val = a_pixel.w; + const int k_block_idx = k / 32; + const int k_in_block = k % 32; + const long b_idx0 = (long)(n_start + 0) * n_stride + k_block_idx; + const long b_idx1 = (long)(n_start + 1) * n_stride + k_block_idx; + const long b_idx2 = (long)(n_start + 2) * n_stride + k_block_idx; + const long b_idx3 = (long)(n_start + 3) * n_stride + k_block_idx; + const half d0 = vload_half(0, (__global half *)(&(B[b_idx0].d))); + const half d1 = vload_half(0, (__global half *)(&(B[b_idx1].d))); + const half d2 = vload_half(0, (__global half *)(&(B[b_idx2].d))); + const half d3 = vload_half(0, (__global half *)(&(B[b_idx3].d))); + const uchar qp0 = B[b_idx0].qs[k_in_block % 16]; + const uchar qp1 = B[b_idx1].qs[k_in_block % 16]; + const uchar qp2 = B[b_idx2].qs[k_in_block % 16]; + const uchar qp3 = B[b_idx3].qs[k_in_block % 16]; + const half qn0 = (half)((k_in_block < 16) ? ((qp0 & 0x0F) - 8) : ((qp0 >> 4) - 8)); + const half qn1 = (half)((k_in_block < 16) ? ((qp1 & 0x0F) - 8) : ((qp1 >> 4) - 8)); + const half qn2 = (half)((k_in_block < 16) ? ((qp2 & 0x0F) - 8) : ((qp2 >> 4) - 8)); + const half qn3 = (half)((k_in_block < 16) ? ((qp3 & 0x0F) - 8) : ((qp3 >> 4) - 8)); + half4 b_vals = (half4)(qn0 * d0, qn1 * d1, qn2 * d2, qn3 * d3); + acc = mad(a_val, b_vals, acc); + } + + if (has_bias != 0) { + acc += convert_half4_rte(vload4(0, bias + n_start)); + } + write_imageh(C, (int2)(gx, 0), acc); +} +#else +// ---------- [兼容回退版] ---------- +__kernel void gemv_fp16_q4_0_transb_bias_image_pipe( + sampler_t sampler, + __read_only image2d_t A, + __global const block_q4_0 *B, + __global const float *bias, + __write_only image2d_t C, + const int K, const int N, + const int H, + const int has_bias) { + // 兼容版逻辑与FP32版本完全相同 + const int gx = get_global_id(0); + const int n_start = gx * 4; + if (n_start >= N) { return; } + + float4 acc = (float4)(0.0f, 0.0f, 0.0f, 0.0f); + const int K_blocks = K / 32; + const long n_stride = K_blocks; + + for (int k = 0; k < K; ++k) { + int pixel_x = k / 4; + int component = k % 4; + float4 a_pixel = read_imagef(A, sampler, (int2)(pixel_x, 0)); + float a_val; + if (component == 0) + a_val = a_pixel.x; + else if (component == 1) + a_val = a_pixel.y; + else if (component == 2) + a_val = a_pixel.z; + else + a_val = a_pixel.w; + + const int k_block_idx = k / 32; + const int k_in_block = k % 32; + const long b_block_mem_idx0 = (long)(n_start + 0) * n_stride + k_block_idx; + const long b_block_mem_idx1 = (long)(n_start + 1) * n_stride + k_block_idx; + const long b_block_mem_idx2 = (long)(n_start + 2) * n_stride + k_block_idx; + const long b_block_mem_idx3 = (long)(n_start + 3) * n_stride + k_block_idx; + + const float d_b0 = vload_half(0, (__global half *)(&(B[b_block_mem_idx0].d))); + const float d_b1 = vload_half(0, (__global half *)(&(B[b_block_mem_idx1].d))); + const float d_b2 = vload_half(0, (__global half *)(&(B[b_block_mem_idx2].d))); + const float d_b3 = vload_half(0, (__global half *)(&(B[b_block_mem_idx3].d))); + + const uchar q_packed0 = B[b_block_mem_idx0].qs[k_in_block % 16]; + const char q_nibble0 = (k_in_block < 16) ? ((q_packed0 & 0x0F) - 8) : ((q_packed0 >> 4) - 8); + const uchar q_packed1 = B[b_block_mem_idx1].qs[k_in_block % 16]; + const char q_nibble1 = (k_in_block < 16) ? ((q_packed1 & 0x0F) - 8) : ((q_packed1 >> 4) - 8); + const uchar q_packed2 = B[b_block_mem_idx2].qs[k_in_block % 16]; + const char q_nibble2 = (k_in_block < 16) ? ((q_packed2 & 0x0F) - 8) : ((q_packed2 >> 4) - 8); + const uchar q_packed3 = B[b_block_mem_idx3].qs[k_in_block % 16]; + const char q_nibble3 = (k_in_block < 16) ? ((q_packed3 & 0x0F) - 8) : ((q_packed3 >> 4) - 8); + + float4 b_vals = (float4)((float)q_nibble0 * d_b0, (float)q_nibble1 * d_b1, (float)q_nibble2 * d_b2, (float)q_nibble3 * d_b3); + + acc = mad(a_val, b_vals, acc); + } + + if (has_bias != 0) { + float4 bias_vals = vload4(0, bias + n_start); + acc += bias_vals; + } + + // 兼容版输出的Image也是FP32格式 + write_imagef(C, (int2)(gx, 0), acc); +} +#endif // SUPPORTS_FP16 \ No newline at end of file diff --git a/src/backends/opencl/kernel/mul.cl b/src/backends/opencl/kernel/mul.cl new file mode 100644 index 000000000..a52668a56 --- /dev/null +++ b/src/backends/opencl/kernel/mul.cl @@ -0,0 +1,135 @@ +// 文件名: kernel/mul.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// ================================================================== +// 1. Tensor * Tensor Multiplication Kernels +// ================================================================== + +__kernel void mul_float( + __global const float *A, + __global const float *B, + __global float *C, + const int b_dim, + const int a_dim) { + size_t index = get_global_id(0); + + // If b_dim is 1 and a_dim is greater than 1, apply broadcasting + if (b_dim == 1 && a_dim > 1) { + size_t a_bsh_index = index / a_dim; + size_t b_index = a_bsh_index; + C[index] = A[index] * B[b_index]; + } else { + // Original element-wise multiplication + C[index] = A[index] * B[index]; + } +} + +__kernel void mul_float_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + __read_only image2d_t inputB, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + float4 inA = read_imagef(inputA, sampler, pos); + float4 inB = read_imagef(inputB, sampler, pos); + float4 result = inA * inB; + write_imagef(output, pos, result); +} + +__kernel void mul_fp16_vector( + __global const half *A, + __global const half *B, + __global half *C, + const int b_dim, + const int a_dim) { + const int i = get_global_id(0); + + // If b_dim is 1 and a_dim is greater than 1, apply broadcasting + if (b_dim == 1 && a_dim > 1) { + const int start_idx_A = i * 4; + for (int j = 0; j < 4; ++j) { + int current_idx_A = start_idx_A + j; + size_t a_bsh_index = current_idx_A / a_dim; + size_t b_index = a_bsh_index; + C[current_idx_A] = A[current_idx_A] * B[b_index]; + } + } else { + // Original element-wise vectorized multiplication + half4 a_vec = vload4(i, A); + half4 b_vec = vload4(i, B); + half4 c_vec = a_vec * b_vec; + vstore4(c_vec, i, C); + } +} + +__kernel void mul_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + __read_only image2d_t inputB, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + half4 inA = read_imageh(inputA, sampler, pos); + half4 inB = read_imageh(inputB, sampler, pos); + half4 result = inA * inB; + write_imageh(output, pos, result); +} + +// ================================================================== +// 2. Tensor * Scalar Multiplication Kernels +// ================================================================== + +__kernel void mul_scalar_float( + __global const float *A, + const float B, + __global float *C) { + size_t index = get_global_id(0); + C[index] = A[index] * B; +} + +__kernel void mul_scalar_fp16_vector( + __global const half *A, + const half B, + __global half *C) { + const int i = get_global_id(0); + half4 a_vec = vload4(i, A); + half4 b_vec = (half4)(B); + half4 c_vec = a_vec * b_vec; + vstore4(c_vec, i, C); +} + +__kernel void mul_scalar_float_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const float B, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + float4 inA = read_imagef(inputA, sampler, pos); + float4 inB = (float4)(B); + float4 result = inA * inB; + write_imagef(output, pos, result); +} + +__kernel void mul_scalar_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + const half B, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + if (pos.x >= width || pos.y >= height) { return; } + half4 inA = read_imageh(inputA, sampler, pos); + half4 inB = (half4)(B); + half4 result = inA * inB; + write_imageh(output, pos, result); +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/rmsnorm.cl b/src/backends/opencl/kernel/rmsnorm.cl new file mode 100644 index 000000000..c9d9cda9f --- /dev/null +++ b/src/backends/opencl/kernel/rmsnorm.cl @@ -0,0 +1,162 @@ +// 文件名: rmsnorm.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// 定义工作组内用于并行归约的线程数(必须是2的幂) +#define RMSNORM_WG_SIZE 256 + +// 与 C++ DataType.hpp 中定义匹配的量化块结构 +typedef struct { + half d; + uchar qs[16]; // QK4_0 / 2 = 16 +} block_q4_0; + +// 内核辅助函数:实时从 Q4_0 块中解量化一个元素 +inline float dequantize_q4_0(const __global block_q4_0 *blocks, int index) { + const int block_idx = index / 32; // QK4_0 is 32 + const int quant_idx_in_block = index % 32; + + // 定位到对应的 Q4_0 块 + const __global block_q4_0 *b = &blocks[block_idx]; + + // 从 uchar 中提取 4-bit 的量化值 + const uchar quant_pair = b->qs[quant_idx_in_block / 2]; + const int nibble = (quant_idx_in_block % 2 == 0) ? (quant_pair & 0x0F) : (quant_pair >> 4); + + // 应用反量化公式 + return (float)b->d * (float)(nibble - 8); +} + +__kernel void rmsnorm_f32_q4( + __global const float *src, // 输入张量 (fp32) + __global float *dst, // 输出张量 (fp32) + __global const void *weights, // 权重张量 (可以是 fp32 或 q4_0) + const int weight_is_q4, // 标志位:0 表示权重是 fp32, 1 表示是 q4_0 + const int D, // Dimension, 即每行的长度 + const float epsilon, // epsilon 值,防止除以零 + const int add_unit_offset // 标志位:是否对权重执行 +1 操作 +) { + // 1. 获取ID + const int row_id = get_group_id(0); // 每个工作组处理一行,行ID由工作组ID决定 + const int local_id = get_local_id(0); // 工作组内的线程ID + + // 2. 在本地内存中声明共享数组 + __local float local_sum_sq[RMSNORM_WG_SIZE]; + + // 3. 并行计算平方和 + float thread_sum_sq = 0.0f; // 每个线程计算一部分元素的平方和 + for (int i = local_id; i < D; i += RMSNORM_WG_SIZE) { + float val = src[row_id * D + i]; + thread_sum_sq += val * val; + } + local_sum_sq[local_id] = thread_sum_sq; + + // 4. 工作组内归约(Reduction),计算整个行的总平方和 + barrier(CLK_LOCAL_MEM_FENCE); + for (int s = RMSNORM_WG_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { + local_sum_sq[local_id] += local_sum_sq[local_id + s]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + // 此时,local_sum_sq[0] 中存放了整个行的平方和 + + // 5. 计算 RMS 缩放因子并安全地广播 + float rms_val; + // 只有工作组的第一个线程进行这个标量计算 + if (local_id == 0) { + float variance = local_sum_sq[0] / D; + rms_val = rsqrt(variance + epsilon); + local_sum_sq[0] = rms_val; // 线程0计算结果并存入共享内存 + } + + // 同步点:确保所有线程都等待线程0将rms_val写入共享内存 + barrier(CLK_LOCAL_MEM_FENCE); + + // 所有线程(包括线程0)从共享内存中读取广播的值 + rms_val = local_sum_sq[0]; + + // 6. 并行执行归一化和应用权重 + for (int i = local_id; i < D; i += RMSNORM_WG_SIZE) { + // a. 获取权重值 + float weight_val; + if (weight_is_q4) { + weight_val = dequantize_q4_0((const __global block_q4_0 *)weights, i); + } else { + weight_val = ((const __global float *)weights)[i]; + } + + // b. 根据标志位决定是否加1 + if (add_unit_offset) { + weight_val += 1.0f; + } + + // c. 计算最终结果并写回全局内存 + size_t index = row_id * D + i; + dst[index] = src[index] * rms_val * weight_val; + } +} + +// ================================================================== +// 2. FP16 Input Kernel (rmsnorm_f16_q4) +// ================================================================== +__kernel void rmsnorm_f16_q4( + __global const half *src, // 输入张量 (fp16) + __global half *dst, // 输出张量 (fp16) + __global const void *weights, // 权重张量 (可以是 fp32 或 q4_0) + const int weight_is_q4, // 标志位 + const int D, // Dimension + const float epsilon, // Epsilon (仍然是 float) + const int add_unit_offset // 标志位 +) { + const int row_id = get_group_id(0); + const int local_id = get_local_id(0); + + __local float local_sum_sq[RMSNORM_WG_SIZE]; + + // 使用 float 累加器以保证精度 + float thread_sum_sq = 0.0f; + for (int i = local_id; i < D; i += RMSNORM_WG_SIZE) { + // 从 half 转换为 float 进行计算 + float val = (float)src[row_id * D + i]; + thread_sum_sq += val * val; + } + local_sum_sq[local_id] = thread_sum_sq; + + // 工作组内归约 (与fp32版本完全相同) + barrier(CLK_LOCAL_MEM_FENCE); + for (int s = RMSNORM_WG_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { + local_sum_sq[local_id] += local_sum_sq[local_id + s]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + // 计算 RMS 缩放因子 (与fp32版本完全相同) + float rms_val; + if (local_id == 0) { + float variance = local_sum_sq[0] / D; + rms_val = rsqrt(variance + epsilon); + local_sum_sq[0] = rms_val; + } + barrier(CLK_LOCAL_MEM_FENCE); + rms_val = local_sum_sq[0]; + + // 归一化和应用权重 + for (int i = local_id; i < D; i += RMSNORM_WG_SIZE) { + float weight_val; + if (weight_is_q4) { + weight_val = dequantize_q4_0((const __global block_q4_0 *)weights, i); + } else { + weight_val = ((const __global float *)weights)[i]; + } + if (add_unit_offset) { + weight_val += 1.0f; + } + + size_t index = row_id * D + i; + // 计算结果为 float,最后转换回 half 存入 dst + float src_val = (float)src[index]; + dst[index] = (half)(src_val * rms_val * weight_val); + } +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/rope.cl b/src/backends/opencl/kernel/rope.cl new file mode 100644 index 000000000..476c385a9 --- /dev/null +++ b/src/backends/opencl/kernel/rope.cl @@ -0,0 +1,136 @@ +// 文件名: kernel/rope.cl +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// LLaMA-style RoPE 内核 (FP32) +__kernel void rope_llama_fp32( + __global float *data, + __global const float *sin_table, + __global const float *cos_table, + const int partial_dim, + const int head_dim, + const int seq_len, + const int pos_offset) { + const int d = get_global_id(0); // Dimension index within a pair (0 to partial_dim/2 - 1) + const int s = get_global_id(1); // Sequence index + const int h = get_global_id(2); // Head index + + if (d >= (partial_dim / 2) || s >= seq_len || h >= head_dim) { + return; + } + + const int pos = s + pos_offset; + const int idx_d = d * 2; + + // BSHD 布局: index = s * (H * D) + h * D + d + size_t base_idx = (size_t)s * head_dim * partial_dim + (size_t)h * partial_dim + idx_d; + + float in0 = data[base_idx]; + float in1 = data[base_idx + 1]; + + float sin_val = sin_table[pos * (partial_dim / 2) + d]; + float cos_val = cos_table[pos * (partial_dim / 2) + d]; + + data[base_idx] = in0 * cos_val - in1 * sin_val; + data[base_idx + 1] = in0 * sin_val + in1 * cos_val; +} + +// HuggingFace-style RoPE 内核 (FP32) +__kernel void rope_hf_fp32( + __global float *data, + __global const float *sin_table, + __global const float *cos_table, + const int partial_dim, + const int head_dim, + const int seq_len, + const int pos_offset) { + const int d = get_global_id(0); // Half dimension index + const int s = get_global_id(1); // Sequence index + const int h = get_global_id(2); // Head index + + const int half_dim = partial_dim / 2; + if (d >= half_dim || s >= seq_len || h >= head_dim) { + return; + } + + const int pos = s + pos_offset; + + // BSHD 布局 + size_t base_idx0 = (size_t)s * head_dim * partial_dim + (size_t)h * partial_dim + d; + size_t base_idx1 = base_idx0 + half_dim; + + float in0 = data[base_idx0]; + float in1 = data[base_idx1]; + + float sin_val = sin_table[pos * half_dim + d]; + float cos_val = cos_table[pos * half_dim + d]; + + data[base_idx0] = in0 * cos_val - in1 * sin_val; + data[base_idx1] = in0 * sin_val + in1 * cos_val; +} + +// ================================================================== +// =================== 新增: FP16 Kernels ===================== +// ================================================================== + +// LLaMA-style RoPE 内核 (FP16) +__kernel void rope_llama_fp16( + __global half *data, + __global const half *sin_table, + __global const half *cos_table, + const int partial_dim, + const int head_dim, + const int seq_len, + const int pos_offset) { + const int d = get_global_id(0); + const int s = get_global_id(1); + const int h = get_global_id(2); + + if (d >= (partial_dim / 2) || s >= seq_len || h >= head_dim) { + return; + } + + const int pos = s + pos_offset; + const int idx_d = d * 2; + size_t base_idx = (size_t)s * head_dim * partial_dim + (size_t)h * partial_dim + idx_d; + + half in0 = data[base_idx]; + half in1 = data[base_idx + 1]; + + half sin_val = sin_table[pos * partial_dim + idx_d]; + half cos_val = cos_table[pos * partial_dim + idx_d]; + + data[base_idx] = in0 * cos_val - in1 * sin_val; + data[base_idx + 1] = in0 * sin_val + in1 * cos_val; +} + +// HuggingFace-style RoPE 内核 (FP16) +__kernel void rope_hf_fp16( + __global half *data, + __global const half *sin_table, + __global const half *cos_table, + const int partial_dim, + const int head_dim, + const int seq_len, + const int pos_offset) { + const int d = get_global_id(0); + const int s = get_global_id(1); + const int h = get_global_id(2); + + const int half_dim = partial_dim / 2; + if (d >= half_dim || s >= seq_len || h >= head_dim) { + return; + } + + const int pos = s + pos_offset; + size_t base_idx0 = (size_t)s * head_dim * partial_dim + (size_t)h * partial_dim + d; + size_t base_idx1 = base_idx0 + half_dim; + + half in0 = data[base_idx0]; + half in1 = data[base_idx1]; + + half sin_val = sin_table[pos * half_dim + d]; + half cos_val = cos_table[pos * half_dim + d]; + + data[base_idx0] = in0 * cos_val - in1 * sin_val; + data[base_idx1] = in0 * sin_val + in1 * cos_val; +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/scatter_add.cl b/src/backends/opencl/kernel/scatter_add.cl new file mode 100644 index 000000000..e4ab06810 --- /dev/null +++ b/src/backends/opencl/kernel/scatter_add.cl @@ -0,0 +1,211 @@ +// 请用此完整代码替换您的 kernel/scatter_add.cl 文件 + +#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable + +// ======================================================================== +// 通用部分:fp32 内核 和 fp32 原子加法 +// 这部分代码已经是正确的,保持不变。 +// ======================================================================== + +void atomic_add_float(__global float *addr, float val) { + union { + unsigned int u32; + float f32; + } next, expected, current; + current.f32 = *addr; + do { + expected.f32 = current.f32; + next.f32 = expected.f32 + val; + current.u32 = atomic_cmpxchg((volatile __global unsigned int *)addr, expected.u32, next.u32); + } while (current.u32 != expected.u32); +} + +__kernel void scatter_add_fp32( + __global float *self_data, + __global const float *value_data, + __global const float *index_data, + const int B, const int H, const int D, + const int S_self, const int S_value) { + const int d = get_global_id(0); + const int h = get_global_id(1); + const int bs_val = get_global_id(2); + const int b = bs_val / S_value; + const int s_val = bs_val % S_value; + + if (d >= D || h >= H || b >= B) { + return; + } + size_t value_offset = (size_t)b * S_value * H * D + (size_t)s_val * H * D + (size_t)h * D + d; + float value_to_add = value_data[value_offset]; + int target_seq_index = (int)index_data[s_val]; + size_t self_offset = (size_t)b * S_self * H * D + (size_t)target_seq_index * H * D + (size_t)h * D + d; + atomic_add_float(&self_data[self_offset], value_to_add); +} + +// ======================================================================== +// FP16 实现部分:根据 SUPPORTS_FP16 宏进行条件编译 +// ======================================================================== + +#ifdef SUPPORTS_FP16 + +// A. 如果设备支持 FP16,我们编译这部分代码 + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +/* + * [最终修正] atomic_add_half: + * 1. 使用 uintptr_t 和位运算代替取模,提高可移植性,解决编译失败问题。 + * 2. 使用 float 进行中间加法计算,保证精度和兼容性。 + */ +void atomic_add_half(__global half *addr, half val) { + // uintptr_t 是专门为存储指针而设计的整数类型,转换更安全。 + uintptr_t ptr_val = (uintptr_t)addr; + // 使用位运算判断地址是在一个32位字的前半部分(0)还是后半部分(1)。 + // (ptr_val >> 1) & 1 等价于 ((ptr_val % 4) / 2) + int half_idx_in_uint = (ptr_val >> 1) & 1; + + // 找到包含当前 half 的那个4字节对齐的地址 + volatile __global uint *addr_as_uint = (volatile __global uint *)(ptr_val - (half_idx_in_uint * 2)); + + union { + uint u32; + half2 f16x2; + } next, expected, current; + + do { + current.u32 = *addr_as_uint; + expected.u32 = current.u32; + + if (half_idx_in_uint == 0) { // 更新前半部分 (s0) + float sum = (float)expected.f16x2.s0 + (float)val; + next.f16x2.s0 = (half)sum; + next.f16x2.s1 = expected.f16x2.s1; + } else { // 更新后半部分 (s1) + float sum = (float)expected.f16x2.s1 + (float)val; + next.f16x2.s0 = expected.f16x2.s0; + next.f16x2.s1 = (half)sum; + } + } while (atomic_cmpxchg(addr_as_uint, expected.u32, next.u32) != expected.u32); +} + +__kernel void scatter_add_fp16( + __global half *self_data, + __global const half *value_data, + __global const half *index_data, + const int B, const int H, const int D, + const int S_self, const int S_value) { + const int d = get_global_id(0); + const int h = get_global_id(1); + const int bs_val = get_global_id(2); + const int b = bs_val / S_value; + const int s_val = bs_val % S_value; + if (d >= D || h >= H || b >= B) { + return; + } + size_t value_offset = (size_t)b * S_value * H * D + (size_t)s_val * H * D + (size_t)h * D + d; + half value_to_add = value_data[value_offset]; + int target_seq_index = (int)convert_float(index_data[s_val]); + size_t self_offset = (size_t)b * S_self * H * D + (size_t)target_seq_index * H * D + (size_t)h * D + d; + atomic_add_half(&self_data[self_offset], value_to_add); +} +#else +// 辅助函数: 将 ushort (存储着 half 的二进制位) 转换为 float +// 注意: 这个函数内部不创建 half 变量,只进行位运算和类型双关转换 +static float ushort_to_float(ushort u) { + uint sign = (u >> 15) & 1; + uint exponent = (u >> 10) & 0x1F; + uint mantissa = u & 0x3FF; + uint result_uint; + if (exponent == 0) { + if (mantissa == 0) { + result_uint = sign << 31; + } else { + exponent = 1; + while ((mantissa & 0x400) == 0) { + mantissa <<= 1; + exponent++; + } + mantissa &= 0x3FF; + exponent = 127 - 15 - exponent + 1; + result_uint = (sign << 31) | (exponent << 23) | (mantissa << 13); + } + } else if (exponent == 0x1F) { + result_uint = (sign << 31) | (0xFF << 23) | (mantissa << 13); + } else { + exponent = exponent - 15 + 127; + result_uint = (sign << 31) | (exponent << 23) | (mantissa << 13); + } + return as_float(result_uint); +} + +// 辅助函数: 将 float 转换为 ushort +static ushort float_to_ushort(float f) { + uint u = as_uint(f); + uint sign = (u >> 16) & 0x8000; + int exponent = ((u >> 23) & 0xFF) - 127; + uint mantissa = u & 0x7FFFFF; + if (exponent > 15) { return sign | 0x7C00; } // Infinity + if (exponent < -14) { + mantissa = (mantissa | 0x800000) >> (1 - exponent); + return sign | (mantissa >> 13); + } + return sign | ((exponent + 15) << 10) | (mantissa >> 13); +} + +// 辅助函数: 在一个 ushort 地址上,原子地加上一个 float 值 +void atomic_add_float_to_ushort_location(__global ushort *addr, float val_to_add) { + uintptr_t ptr_val = (uintptr_t)addr; + int ushort_idx_in_uint = (ptr_val >> 1) & 1; + volatile __global uint *addr_as_uint = (volatile __global uint *)(ptr_val - (ushort_idx_in_uint * 2)); + + union { + uint u32; + ushort us16[2]; + } next, expected, current; + + do { + current.u32 = *addr_as_uint; + expected.u32 = current.u32; + + // 核心逻辑:解包 -> 转float -> 计算 -> 转ushort -> 打包 + ushort old_val_ushort = expected.us16[ushort_idx_in_uint]; + float old_val_float = ushort_to_float(old_val_ushort); + float new_val_float = old_val_float + val_to_add; + ushort new_val_ushort = float_to_ushort(new_val_float); + + next.u32 = expected.u32; // 先复制 + next.us16[ushort_idx_in_uint] = new_val_ushort; // 再修改目标部分 + + } while (atomic_cmpxchg(addr_as_uint, expected.u32, next.u32) != expected.u32); +} + +__kernel void scatter_add_fp16( + __global ushort *self_data, + __global const ushort *value_data, + __global const ushort *index_data, + const int B, const int H, const int D, + const int S_self, const int S_value) { + const int d = get_global_id(0); + const int h = get_global_id(1); + const int bs_val = get_global_id(2); + const int b = bs_val / S_value; + const int s_val = bs_val % S_value; + if (d >= D || h >= H || b >= B) { return; } + + // 1. 读取源数据和索引,并立即转换为 float + size_t value_offset = (size_t)b * S_value * H * D + (size_t)s_val * H * D + (size_t)h * D + d; + // 使用 vload_half 读取并转换,遵从编译器建议 + float value_to_add = vload_half(value_offset, (__global half *)value_data); + + // 读取索引也同样处理 + float index_as_float = vload_half(s_val, (__global half *)index_data); + int target_seq_index = (int)index_as_float; + + // 2. 计算目标地址 + size_t self_offset = (size_t)b * S_self * H * D + (size_t)target_seq_index * H * D + (size_t)h * D + d; + + // 3. 执行软件模拟的原子加法 + // 因为 vload/vstore 不支持原子操作,所以必须使用手动实现的原子函数 + atomic_add_float_to_ushort_location(&self_data[self_offset], value_to_add); +} +#endif // SUPPORTS_FP16 \ No newline at end of file diff --git a/src/backends/opencl/kernel/silu.cl b/src/backends/opencl/kernel/silu.cl new file mode 100644 index 000000000..1bbd8ff48 --- /dev/null +++ b/src/backends/opencl/kernel/silu.cl @@ -0,0 +1,71 @@ +// 文件名: kernel/silu.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// ============================================================================ +// ========================== FP32 (float) Kernel ============================= +// ============================================================================ +/** + * @brief 对 float 张量执行 SiLU (Swish) 激活函数。 + * out = x * (1 / (1 + exp(-x))) + */ +__kernel void silu_fp32( + __global const float *input, + __global float *output) { + const int i = get_global_id(0); + const float x = input[i]; + + // 计算 SiLU + output[i] = x / (1.0f + exp(-x)); +} + +// ============================================================================ +// ========================== FP16 (half) Kernel ============================== +// ============================================================================ +/** + * @brief 对 half 张量使用向量指令执行 SiLU (Swish) 激活函数。 + * 一次处理4个 half 元素。 + */ +// __kernel void silu_fp16_vector( +// __global const half *input, +// __global half *output) { +// const int i = get_global_id(0); + +// // 高效地加载 4 个 half 数据 +// half4 x = vload4(i, input); + +// // 计算 SiLU +// // 注意: OpenCL C 中,exp() 等数学函数可以直接作用于向量类型 +// half4 result = x / ((half4)(1.0h) + exp(-x)); + +// // 高效地写回 4 个 half 数据 +// vstore4(result, i, output); +// } + +__kernel void silu_fp16( + __global const half *input, + __global half *output, + const int count) { + // --- 向量化部分 --- + const int vec_idx = get_global_id(0); + const int vec_limit = count / 4; + + if (vec_idx < vec_limit) { + const int i = vec_idx * 4; + half4 x = vload4(0, input + i); + half4 result = x / ((half4)(1.0h) + exp(-x)); + vstore4(result, 0, output + i); + } + + // --- 标量处理部分 (处理余数) --- + // ✨ **核心修正点** ✨: 'local_id' 替换为 'get_local_id(0)' + // 让第一个工作组中ID合适的线程来处理余下的部分 + const int remainder_start = vec_limit * 4; + if (get_local_id(0) < (count - remainder_start) && get_group_id(0) == 0) { + const int i = remainder_start + get_local_id(0); + if (i < count) { // 再次检查边界,确保安全 + const half x = input[i]; + output[i] = x / (1.0h + exp(-x)); + } + } +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/softmax.cl b/src/backends/opencl/kernel/softmax.cl new file mode 100644 index 000000000..021442a08 --- /dev/null +++ b/src/backends/opencl/kernel/softmax.cl @@ -0,0 +1,159 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +#define SOFTMAX_BLOCK_SIZE 256 + +#define HALF_MAX 65504.0h +#ifdef SUPPORTS_FP16 +// ============================================================================ +// ========================== FP16 (half) 高性能版 ============================= +// ============================================================================ +__kernel void softmax_fp16_along_d( + const __global half *src, + __global half *dst, + const int B, const int H, const int S, const int D, + const int do_causal_mask) { + const int row_id = get_group_id(0); + if (row_id >= B * H * S) return; + const int local_id = get_local_id(0); + int effective_D = D; + if (do_causal_mask) { + const int current_s = row_id % S; + effective_D = current_s + 1; + } + __local half local_max[SOFTMAX_BLOCK_SIZE]; + __local float local_sum[SOFTMAX_BLOCK_SIZE]; + half thread_max = -HALF_MAX; + for (int i = local_id; i < effective_D; i += SOFTMAX_BLOCK_SIZE) { + thread_max = max(thread_max, src[row_id * D + i]); + } + local_max[local_id] = thread_max; + barrier(CLK_LOCAL_MEM_FENCE); + for (int s = SOFTMAX_BLOCK_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { local_max[local_id] = max(local_max[local_id], local_max[local_id + s]); } + barrier(CLK_LOCAL_MEM_FENCE); + } + const half row_max = local_max[0]; + barrier(CLK_LOCAL_MEM_FENCE); + + float thread_sum = 0.0f; + for (int i = local_id; i < effective_D; i += SOFTMAX_BLOCK_SIZE) { + half val = exp(src[row_id * D + i] - row_max); + thread_sum += (float)val; + dst[row_id * D + i] = val; + } + local_sum[local_id] = thread_sum; + barrier(CLK_LOCAL_MEM_FENCE); + for (int s = SOFTMAX_BLOCK_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { local_sum[local_id] += local_sum[local_id + s]; } + barrier(CLK_LOCAL_MEM_FENCE); + } + const float row_sum = local_sum[0]; + barrier(CLK_LOCAL_MEM_FENCE); + for (int i = local_id; i < effective_D; i += SOFTMAX_BLOCK_SIZE) { + dst[row_id * D + i] /= (half)row_sum; + } + if (do_causal_mask) { + for (int i = local_id + effective_D; i < D; i += SOFTMAX_BLOCK_SIZE) { + dst[row_id * D + i] = (half)0.0f; + } + } +} +#else +// ============================================================================ +// ========================== FP16 (half) 兼容版 ============================== +// ============================================================================ +__kernel void softmax_fp16_along_d( + const __global half *src, + __global half *dst, + const int B, const int H, const int S, const int D, + const int do_causal_mask) { + const int row_id = get_global_id(0); + if (row_id >= B * H * S) return; + + int effective_D = D; + if (do_causal_mask) { + effective_D = (row_id % S) + 1; + } + const __global half *p_src = src + row_id * D; + __global half *p_dst = dst + row_id * D; + + float max_val = -INFINITY; + for (int i = 0; i < effective_D; ++i) { + max_val = max(max_val, (float)p_src[i]); + } + float sum = 0.0f; + for (int i = 0; i < effective_D; ++i) { + float val_f32 = exp((float)p_src[i] - max_val); + p_dst[i] = (half)val_f32; + sum += val_f32; + } + for (int i = 0; i < effective_D; ++i) { + p_dst[i] = (half)((float)p_dst[i] / sum); + } + if (do_causal_mask) { + for (int i = effective_D; i < D; ++i) { + p_dst[i] = (half)0.0f; + } + } +} +#endif // SUPPORTS_FP16 + +// ============================================================================ +// ========================== FP32 (float) Kernel ============================= +// ============================================================================ +__kernel void softmax_f32_along_d( + const __global float *src, + __global float *dst, + const int B, const int H, const int S, const int D, + const int do_causal_mask) { + const int row_id = get_group_id(0); + if (row_id >= B * H * S) return; + + const int local_id = get_local_id(0); + int effective_D = D; + if (do_causal_mask) { + effective_D = (row_id % S) + 1; + } + + __local float local_max[SOFTMAX_BLOCK_SIZE]; + __local float local_sum[SOFTMAX_BLOCK_SIZE]; + + float thread_max = -INFINITY; + for (int i = local_id; i < effective_D; i += SOFTMAX_BLOCK_SIZE) { + thread_max = max(thread_max, src[row_id * D + i]); + } + local_max[local_id] = thread_max; + barrier(CLK_LOCAL_MEM_FENCE); + + for (int s = SOFTMAX_BLOCK_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { local_max[local_id] = max(local_max[local_id], local_max[local_id + s]); } + barrier(CLK_LOCAL_MEM_FENCE); + } + const float row_max = local_max[0]; + barrier(CLK_LOCAL_MEM_FENCE); + + float thread_sum = 0.0f; + for (int i = local_id; i < effective_D; i += SOFTMAX_BLOCK_SIZE) { + float val = exp(src[row_id * D + i] - row_max); + thread_sum += val; + dst[row_id * D + i] = val; + } + local_sum[local_id] = thread_sum; + barrier(CLK_LOCAL_MEM_FENCE); + + for (int s = SOFTMAX_BLOCK_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { local_sum[local_id] += local_sum[local_id + s]; } + barrier(CLK_LOCAL_MEM_FENCE); + } + const float row_sum = local_sum[0]; + barrier(CLK_LOCAL_MEM_FENCE); + + for (int i = local_id; i < effective_D; i += SOFTMAX_BLOCK_SIZE) { + dst[row_id * D + i] /= row_sum; + } + if (do_causal_mask) { + for (int i = local_id + effective_D; i < D; i += SOFTMAX_BLOCK_SIZE) { + dst[row_id * D + i] = 0.0f; + } + } +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/split.cl b/src/backends/opencl/kernel/split.cl new file mode 100644 index 000000000..0d3a04d81 --- /dev/null +++ b/src/backends/opencl/kernel/split.cl @@ -0,0 +1,47 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +__kernel void split_fp32( + __global const float *input, + __global float *output, + const int outer_size, + const int split_dim_size, + const int inner_size, + const int offset, + const int total_split_dim_size) { + const int inner_idx = get_global_id(0); + const int split_idx = get_global_id(1); + const int outer_idx = get_global_id(2); + + if (inner_idx >= inner_size || split_idx >= split_dim_size || outer_idx >= outer_size) { + return; + } + + size_t src_offset = (size_t)outer_idx * total_split_dim_size * inner_size + (size_t)(split_idx + offset) * inner_size + inner_idx; + + size_t dst_offset = (size_t)outer_idx * split_dim_size * inner_size + (size_t)split_idx * inner_size + inner_idx; + + output[dst_offset] = input[src_offset]; +} + +__kernel void split_fp16( + __global const half *input, + __global half *output, + const int outer_size, + const int split_dim_size, + const int inner_size, + const int offset, + const int total_split_dim_size) { + const int inner_idx = get_global_id(0); + const int split_idx = get_global_id(1); + const int outer_idx = get_global_id(2); + + if (inner_idx >= inner_size || split_idx >= split_dim_size || outer_idx >= outer_size) { + return; + } + + size_t src_offset = (size_t)outer_idx * total_split_dim_size * inner_size + (size_t)(split_idx + offset) * inner_size + inner_idx; + + size_t dst_offset = (size_t)outer_idx * split_dim_size * inner_size + (size_t)split_idx * inner_size + inner_idx; + + output[dst_offset] = input[src_offset]; +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/sub.cl b/src/backends/opencl/kernel/sub.cl new file mode 100644 index 000000000..13e3ff17f --- /dev/null +++ b/src/backends/opencl/kernel/sub.cl @@ -0,0 +1,76 @@ +// 文件名: kernel/sub.cl + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// ================================================================== +// 1. Tensor - Tensor Subtraction Kernels +// ================================================================== + +/** + * @brief [FP32 Buffer版] 两个 float 张量的元素级减法 C = A - B + */ +__kernel void sub_float( + __global const float *A, + __global const float *B, + __global float *C) { + size_t index = get_global_id(0); + C[index] = A[index] - B[index]; +} + +/** + * @brief [FP32 Image版] 两个 float 图像的元素级减法 + */ +__kernel void sub_float_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + __read_only image2d_t inputB, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + + if (pos.x >= width || pos.y >= height) { + return; + } + + float4 inA = read_imagef(inputA, sampler, pos); + float4 inB = read_imagef(inputB, sampler, pos); + float4 result = inA - inB; + write_imagef(output, pos, result); +} + +/** + * @brief [FP16 Buffer版] 两个 half 张量的向量化元素级减法 + */ +__kernel void sub_fp16_vector( + __global const half *A, + __global const half *B, + __global half *C) { + const int i = get_global_id(0); + half4 a_vec = vload4(i, A); + half4 b_vec = vload4(i, B); + half4 c_vec = a_vec - b_vec; + vstore4(c_vec, i, C); +} + +/** + * @brief [FP16 Image版] 两个 half 图像的元素级减法 + */ +__kernel void sub_fp16_image2d( + sampler_t sampler, + __read_only image2d_t inputA, + __read_only image2d_t inputB, + __write_only image2d_t output, + const int width, + const int height) { + const int2 pos = (int2)(get_global_id(0), get_global_id(1)); + + if (pos.x >= width || pos.y >= height) { + return; + } + + half4 inA = read_imageh(inputA, sampler, pos); + half4 inB = read_imageh(inputB, sampler, pos); + half4 result = inA - inB; + write_imageh(output, pos, result); +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/sum.cl b/src/backends/opencl/kernel/sum.cl new file mode 100644 index 000000000..f0de879aa --- /dev/null +++ b/src/backends/opencl/kernel/sum.cl @@ -0,0 +1,81 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +#define SUM_WG_SIZE 256 // 工作组大小, 必须是2的幂 + +// ========================== FP32 (float) Kernel ============================= +__kernel void sum_fp32( + __global const float *input, + __global float *output, + const int outer_size, + const int inner_size, + const int reduce_size) { + // 1. 获取全局和局部ID + const int inner_idx = get_group_id(0); + const int outer_idx = get_group_id(1); + const int local_id = get_local_id(0); + + // 2. 在本地内存中声明共享数组,用于存储部分和 + __local float partial_sums[SUM_WG_SIZE]; + + // 3. 并行计算部分和 + float thread_sum = 0.0f; + // 每个线程负责累加 `reduce_size` 维度上的一部分数据 + for (int i = local_id; i < reduce_size; i += SUM_WG_SIZE) { + size_t offset = (size_t)outer_idx * reduce_size * inner_size + (size_t)i * inner_size + inner_idx; + thread_sum += input[offset]; + } + partial_sums[local_id] = thread_sum; + + // 4. 工作组内同步,确保所有线程都已算完自己的部分和 + barrier(CLK_LOCAL_MEM_FENCE); + + // 5. 在本地内存中进行并行规约 + for (int s = SUM_WG_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { + partial_sums[local_id] += partial_sums[local_id + s]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + // 6. 由工作组的第一个线程将最终结果写回全局内存 + if (local_id == 0) { + size_t out_offset = (size_t)outer_idx * inner_size + inner_idx; + output[out_offset] = partial_sums[0]; + } +} + +// ========================== FP16 (half) Kernel ============================== +__kernel void sum_fp16( + __global const half *input, + __global half *output, + const int outer_size, + const int inner_size, + const int reduce_size) { + const int inner_idx = get_group_id(0); + const int outer_idx = get_group_id(1); + const int local_id = get_local_id(0); + + // 使用 float 累加器以保证精度 + __local float partial_sums[SUM_WG_SIZE]; + float thread_sum = 0.0f; + + for (int i = local_id; i < reduce_size; i += SUM_WG_SIZE) { + size_t offset = (size_t)outer_idx * reduce_size * inner_size + (size_t)i * inner_size + inner_idx; + thread_sum += (float)input[offset]; + } + partial_sums[local_id] = thread_sum; + + barrier(CLK_LOCAL_MEM_FENCE); + + for (int s = SUM_WG_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { + partial_sums[local_id] += partial_sums[local_id + s]; + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + if (local_id == 0) { + size_t out_offset = (size_t)outer_idx * inner_size + inner_idx; + output[out_offset] = (half)partial_sums[0]; + } +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/topk.cl b/src/backends/opencl/kernel/topk.cl new file mode 100644 index 000000000..1554b54a7 --- /dev/null +++ b/src/backends/opencl/kernel/topk.cl @@ -0,0 +1,164 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +#define WG_SIZE 256 // 工作组大小,必须是2的幂 + +// 交换两个 pair +void swap_pairs(volatile __local float *values, volatile __local int *indices, int i, int j) { + float temp_val = values[i]; + values[i] = values[j]; + values[j] = temp_val; + + int temp_idx = indices[i]; + indices[i] = indices[j]; + indices[j] = temp_idx; +} + +// ========================== FP32 (float) Kernel ============================= +__kernel void topk_fp32( + __global const float *input, + __global float *topk_values, + __global float *topk_indices, + const int D, // dimension to sort along + const int k) { + // ** FIX: All __local memory declarations moved to the top-level scope ** + __local float local_values[WG_SIZE]; + __local int local_indices[WG_SIZE]; + __local float wg_max_vals[WG_SIZE]; + __local int wg_max_indices[WG_SIZE]; + + const int row_id = get_group_id(0); + const int local_id = get_local_id(0); + + // 1. 并行加载一行数据到本地内存 + for (int i = local_id; i < D; i += WG_SIZE) { + local_values[i] = input[row_id * D + i]; + local_indices[i] = i; + } + // 处理 D < WG_SIZE 的情况,将多余的本地内存元素初始化为最小值 + if (local_id >= D && local_id < WG_SIZE) { + local_values[local_id] = -FLT_MAX; + local_indices[local_id] = -1; + } + + barrier(CLK_LOCAL_MEM_FENCE); + + // 2. 在本地内存中进行部分排序 (选择排序的变体) + for (int i = 0; i < k; ++i) { + // 在工作组内并行查找 [i, D) 区间内的最大值 + float thread_max_val = -FLT_MAX; + int thread_max_idx = -1; + for (int j = i + local_id; j < D; j += WG_SIZE) { + if (local_values[j] > thread_max_val) { + thread_max_val = local_values[j]; + thread_max_idx = j; + } + } + + // 使用本地内存进行归约,找到整个工作组的最大值 + wg_max_vals[local_id] = thread_max_val; + wg_max_indices[local_id] = thread_max_idx; + barrier(CLK_LOCAL_MEM_FENCE); + + for (int s = WG_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { + if (wg_max_vals[local_id + s] > wg_max_vals[local_id]) { + wg_max_vals[local_id] = wg_max_vals[local_id + s]; + wg_max_indices[local_id] = wg_max_indices[local_id + s]; + } + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + int max_idx = -1; + if (local_id == 0) { + max_idx = wg_max_indices[0]; + } + barrier(CLK_LOCAL_MEM_FENCE); // 确保所有线程都看到了max_idx + + // 将找到的最大值与第 i 个元素交换 + if (max_idx != -1 && max_idx != i) { + if (local_id == 0) { + swap_pairs(local_values, local_indices, i, max_idx); + } + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + // 3. 由前 k 个线程将结果写回全局内存 + if (local_id < k) { + topk_values[row_id * k + local_id] = local_values[local_id]; + // 将索引转换为 float 类型写入 + topk_indices[row_id * k + local_id] = (float)local_indices[local_id]; + } +} + +// ========================== FP16 (half) Kernel ============================== +__kernel void topk_fp16( + __global const half *input, + __global half *topk_values, + __global half *topk_indices, + const int D, + const int k) { + // ** FIX: All __local memory declarations moved to the top-level scope ** + __local float local_values[WG_SIZE]; + __local int local_indices[WG_SIZE]; + __local float wg_max_vals[WG_SIZE]; + __local int wg_max_indices[WG_SIZE]; + + const int row_id = get_group_id(0); + const int local_id = get_local_id(0); + + for (int i = local_id; i < D; i += WG_SIZE) { + local_values[i] = (float)input[row_id * D + i]; + local_indices[i] = i; + } + if (local_id >= D && local_id < WG_SIZE) { + local_values[local_id] = -FLT_MAX; + local_indices[local_id] = -1; + } + + barrier(CLK_LOCAL_MEM_FENCE); + + for (int i = 0; i < k; ++i) { + float thread_max_val = -FLT_MAX; + int thread_max_idx = -1; + for (int j = i + local_id; j < D; j += WG_SIZE) { + if (local_values[j] > thread_max_val) { + thread_max_val = local_values[j]; + thread_max_idx = j; + } + } + + wg_max_vals[local_id] = thread_max_val; + wg_max_indices[local_id] = thread_max_idx; + barrier(CLK_LOCAL_MEM_FENCE); + + for (int s = WG_SIZE / 2; s > 0; s >>= 1) { + if (local_id < s) { + if (wg_max_vals[local_id + s] > wg_max_vals[local_id]) { + wg_max_vals[local_id] = wg_max_vals[local_id + s]; + wg_max_indices[local_id] = wg_max_indices[local_id + s]; + } + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + int max_idx = -1; + if (local_id == 0) { + max_idx = wg_max_indices[0]; + } + barrier(CLK_LOCAL_MEM_FENCE); + + if (max_idx != -1 && max_idx != i) { + if (local_id == 0) { + swap_pairs(local_values, local_indices, i, max_idx); + } + } + barrier(CLK_LOCAL_MEM_FENCE); + } + + if (local_id < k) { + topk_values[row_id * k + local_id] = (half)local_values[local_id]; + topk_indices[row_id * k + local_id] = (half)local_indices[local_id]; + } +} \ No newline at end of file diff --git a/src/backends/opencl/kernel/transpose.cl b/src/backends/opencl/kernel/transpose.cl new file mode 100644 index 000000000..90c4fe60a --- /dev/null +++ b/src/backends/opencl/kernel/transpose.cl @@ -0,0 +1,271 @@ +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// 定义在本地内存中转置的块大小 +#define BLOCK_DIM 16 + +// // ============================================================================ +// // ========================== FP32 (float) Kernel ============================= +// // ============================================================================ +// __kernel void transpose_float_2d( +// const __global float *src, // 源矩阵指针 (指向一个 S x D 块) +// __global float *dst, // 目标矩阵指针 (指向一个 D x S 块) +// const int S, // 源矩阵的行数 +// const int D // 源矩阵的列数 +// ) { +// // 1. 定义一个本地内存块 +// __local float tile[BLOCK_DIM][BLOCK_DIM + 1]; // +1 用于避免 bank conflict + +// // 2. 计算全局ID (在 S x D 矩阵内的坐标) +// int d = get_global_id(0); +// int s = get_global_id(1); + +// // 3. 从全局内存加载数据到本地内存 +// if (d < D && s < S) { +// tile[get_local_id(1)][get_local_id(0)] = src[s * D + d]; +// } + +// // 4. 同步工作组,确保所有数据都已加载 +// barrier(CLK_LOCAL_MEM_FENCE); + +// // 5. 计算转置后的新坐标 +// int new_d = get_group_id(1) * BLOCK_DIM + get_local_id(0); +// int new_s = get_group_id(0) * BLOCK_DIM + get_local_id(1); + +// // 6. 从本地内存读取转置后的元素并写回全局内存 +// if (new_d < S && new_s < D) { +// // 读取时索引交换,实现转置 +// dst[new_s * S + new_d] = tile[get_local_id(0)][get_local_id(1)]; +// } +// } + +// // ============================================================================ +// // ========================== FP16 (half) Kernel ============================== +// // ============================================================================ +// __kernel void transpose_fp16_2d( +// const __global half *src, +// __global half *dst, +// const int S, +// const int D) { +// __local half tile[BLOCK_DIM][BLOCK_DIM + 1]; + +// int d = get_global_id(0); +// int s = get_global_id(1); + +// if (d < D && s < S) { +// tile[get_local_id(1)][get_local_id(0)] = src[s * D + d]; +// } + +// barrier(CLK_LOCAL_MEM_FENCE); + +// int new_d = get_group_id(1) * BLOCK_DIM + get_local_id(0); +// int new_s = get_group_id(0) * BLOCK_DIM + get_local_id(1); + +// if (new_d < S && new_s < D) { +// dst[new_s * S + new_d] = tile[get_local_id(0)][get_local_id(1)]; +// } +// } + +#pragma OPENCL EXTENSION cl_khr_fp16 : enable + +// 定义在本地内存中转置的块大小 +#define BLOCK_DIM 16 + +// ============================================================================ +// ========================== FP32 (float) Kernel ============================= +// ============================================================================ +__kernel void transpose_float_2d( + const __global float *src, // 源矩阵的基地址指针 + __global float *dst, // 目标矩阵的基地址指针 + const int S, // 子矩阵的行数 + const int D, // 子矩阵的列数 + const int src_offset_elements, // 【新增】源数据在基地址上的偏移量 (以元素为单位) + const int dst_offset_elements // 【新增】目标数据在基地址上的偏移量 (以元素为单位) +) { + // 1. 定义一个本地内存块 + __local float tile[BLOCK_DIM][BLOCK_DIM + 1]; // +1 用于避免 bank conflict + + // 【修改】根据偏移量获取子矩阵的实际指针 + const __global float *src_ptr = src + src_offset_elements; + __global float *dst_ptr = dst + dst_offset_elements; + + // 2. 计算全局ID (在 S x D 子矩阵内的坐标) + int d = get_global_id(0); + int s = get_global_id(1); + + // 3. 从全局内存加载数据到本地内存 + if (d < D && s < S) { + tile[get_local_id(1)][get_local_id(0)] = src_ptr[s * D + d]; + } + + // 4. 同步工作组,确保所有数据都已加载 + barrier(CLK_LOCAL_MEM_FENCE); + + // 5. 计算转置后的新坐标 + int new_d = get_group_id(1) * BLOCK_DIM + get_local_id(0); + int new_s = get_group_id(0) * BLOCK_DIM + get_local_id(1); + + // 6. 从本地内存读取转置后的元素并写回全局内存 + if (new_d < S && new_s < D) { + // 读取时索引交换,实现转置 + dst_ptr[new_s * S + new_d] = tile[get_local_id(0)][get_local_id(1)]; + } +} + +// ============================================================================ +// ========================== FP16 (half) Kernel ============================== +// ============================================================================ +__kernel void transpose_fp16_2d( + const __global half *src, + __global half *dst, + const int S, + const int D, + const int src_offset_elements, // 【新增】源数据在基地址上的偏移量 + const int dst_offset_elements // 【新增】目标数据在基地址上的偏移量 +) { + __local half tile[BLOCK_DIM][BLOCK_DIM + 1]; + + // 【修改】根据偏移量获取子矩阵的实际指针 + const __global half *src_ptr = src + src_offset_elements; + __global half *dst_ptr = dst + dst_offset_elements; + + int d = get_global_id(0); + int s = get_global_id(1); + + if (d < D && s < S) { + tile[get_local_id(1)][get_local_id(0)] = src_ptr[s * D + d]; + } + + barrier(CLK_LOCAL_MEM_FENCE); + + int new_d = get_group_id(1) * BLOCK_DIM + get_local_id(0); + int new_s = get_group_id(0) * BLOCK_DIM + get_local_id(1); + + if (new_d < S && new_s < D) { + dst_ptr[new_s * S + new_d] = tile[get_local_id(0)][get_local_id(1)]; + } +} + +// ============================================================================ +// ============ BSHD -> BHSD FP32 (float) Kernel ============================== +// ============================================================================ +__kernel void transpose_bshd2bhsd_fp32( + const __global float *src, // 源张量指针 (BSHD 布局) + __global float *dst, // 目标张量指针 (BHSD 布局) + const int B, // Batch size + const int H, // Head count + const int S, // Sequence length + const int D // Dimension +) { + // 使用3D工作项ID来唯一标识目标张量中的每一个元素 + const int d = get_global_id(0); + const int s = get_global_id(1); + const int hb = get_global_id(2); // h 和 b 的组合索引 + + // 检查边界 + if (d >= D || s >= S || hb >= H * B) { + return; + } + + // 从组合索引中分解出 h 和 b + const int h = hb % H; + const int b = hb / H; + + // 根据 BSHD 布局计算源索引 + // src[b][s][h][d] + size_t src_idx = (size_t)b * S * H * D + (size_t)s * H * D + (size_t)h * D + d; + + // 根据 BHSD 布局计算目标索引 + // dst[b][h][s][d] + size_t dst_idx = (size_t)b * H * S * D + (size_t)h * S * D + (size_t)s * D + d; + + // 执行数据拷贝 + dst[dst_idx] = src[src_idx]; +} + +// ============================================================================ +// ============ BSHD -> BHSD FP16 (half) Kernel =============================== +// ============================================================================ +__kernel void transpose_bshd2bhsd_fp16( + const __global half *src, + __global half *dst, + const int B, + const int H, + const int S, + const int D) { + const int d = get_global_id(0); + const int s = get_global_id(1); + const int hb = get_global_id(2); + + if (d >= D || s >= S || hb >= H * B) { + return; + } + + const int h = hb % H; + const int b = hb / H; + + size_t src_idx = (size_t)b * S * H * D + (size_t)s * H * D + (size_t)h * D + d; + size_t dst_idx = (size_t)b * H * S * D + (size_t)h * S * D + (size_t)s * D + d; + + dst[dst_idx] = src[src_idx]; +} + +// ============================================================================ +// ============ BHSD -> BSHD FP32 (float) Kernel (新增) ======================== +// ============================================================================ +__kernel void transpose_bhsd2bshd_fp32( + const __global float *src, // 源张量指针 (BHSD 布局) + __global float *dst, // 目标张量指针 (BSHD 布局) + const int B, + const int H, + const int S, + const int D) { + const int d = get_global_id(0); + const int s = get_global_id(1); + const int hb = get_global_id(2); + + if (d >= D || s >= S || hb >= H * B) { + return; + } + + const int h = hb % H; + const int b = hb / H; + + // 根据 BHSD 布局计算源索引 + // src[b][h][s][d] + size_t src_idx = (size_t)b * H * S * D + (size_t)h * S * D + (size_t)s * D + d; + + // 根据 BSHD 布局计算目标索引 + // dst[b][s][h][d] + size_t dst_idx = (size_t)b * S * H * D + (size_t)s * H * D + (size_t)h * D + d; + + dst[dst_idx] = src[src_idx]; +} + +// ============================================================================ +// ============ BHSD -> BSHD FP16 (half) Kernel (新增) ======================== +// ============================================================================ +__kernel void transpose_bhsd2bshd_fp16( + const __global half *src, + __global half *dst, + const int B, + const int H, + const int S, + const int D) { + const int d = get_global_id(0); + const int s = get_global_id(1); + const int hb = get_global_id(2); + + if (d >= D || s >= S || hb >= H * B) { + return; + } + + const int h = hb % H; + const int b = hb / H; + + // 根据 BHSD 布局计算源索引 + size_t src_idx = (size_t)b * H * S * D + (size_t)h * S * D + (size_t)s * D + d; + // 根据 BSHD 布局计算目标索引 + size_t dst_idx = (size_t)b * S * H * D + (size_t)s * H * D + (size_t)h * D + d; + + dst[dst_idx] = src[src_idx]; +} \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLAddFuncOp.cpp b/src/backends/opencl/op/OpenCLAddFuncOp.cpp deleted file mode 100644 index fa579af30..000000000 --- a/src/backends/opencl/op/OpenCLAddFuncOp.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include "OpenCLAddFuncOp.hpp" -#include "Types.hpp" -#include "utils/OpenCLTools.hpp" - -namespace mllm { - - -OpenCLAddFuncOp::OpenCLAddFuncOp(Backend *bn, std::string name) : Op(bn, std::move(name)) { - ocl_backend_ = dynamic_cast(backend_); - if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); - - // 只获取一次 Program - const std::string kernel_path_str = get_kernel_path(__FILE__, "../kernel/add.cl"); - cl_program program = ocl_backend_->getProgram(kernel_path_str); - - cl_int err; - // --- 创建全部四个内核 --- - kernel_fp32_buffer_ = clCreateKernel(program, "add_float", &err); - check_cl_error(err, "clCreateKernel for add_float"); - - kernel_fp32_image_ = clCreateKernel(program, "add_float_image2d", &err); - check_cl_error(err, "clCreateKernel for add_float_image2d"); - - kernel_fp16_buffer_ = clCreateKernel(program, "add_fp16_vector", &err); - check_cl_error(err, "clCreateKernel for add_fp16_vector"); - - kernel_fp16_image_ = clCreateKernel(program, "add_fp16_image2d", &err); - check_cl_error(err, "clCreateKernel for add_fp16_image2d"); - - // --- 创建 Sampler --- - sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); - check_cl_error(err, "clCreateSampler"); -} - -// 替换您的析构函数 -OpenCLAddFuncOp::~OpenCLAddFuncOp() { - if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); - if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); - if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); - if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); - if (sampler_) clReleaseSampler(sampler_); -} - -ErrorCode OpenCLAddFuncOp::reshape(vector> inputs, vector> outputs) { - // 加法操作要求输入和输出的形状一致 - auto input0_shape = inputs[0]->shape(); - outputs[0]->reshape(input0_shape[0], input0_shape[1], input0_shape[2], input0_shape[3]); - outputs[0]->setDtype(inputs[0]->dtype()); - return MLLM_NO_ERROR; -} - -ErrorCode OpenCLAddFuncOp::setUp(vector> inputs, vector> outputs) { - // 确保输入在设备上 - for(auto& input : inputs) { - input->to(MLLM_OPENCL); - } - auto output = outputs[0]; - - // 根据输入设置输出的数据类型 - output->setDtype(inputs[0]->dtype()); - - auto& out_mem = output->device_memory(); - - // **核心修改:直接决策为 Image 或 Buffer** - if (output->dimension() % 4 == 0) { - // 条件满足,直接为输出张量申请 Image2D 类型的内存 - out_mem.type = MEM_TYPE_IMAGE_2D; // **直接设为 Image2D** - out_mem.image_width = output->dimension() / 4; - out_mem.image_height = output->batch() * output->head() * output->sequence(); - } else { - // 条件不满足,回退到普通 Buffer - out_mem.type = MEM_TYPE_BUFFER; - } - - // alloc() 现在会根据 out_mem.type 直接创建出 Image 或 Buffer - output->alloc(); - return MLLM_NO_ERROR; -} - -// in OpenCLAddFuncOp.cpp - -ErrorCode OpenCLAddFuncOp::execute(vector> inputs, vector> outputs) { - // 1. 获取输入数据类型和输出张量 - auto input_dtype = inputs[0]->dtype(); - auto output = outputs[0]; - - // 2. 根据输出张量的内存类型,决定执行“Image优化路径”还是“普通Buffer路径” - // 这个类型是在 setUp 函数中根据维度是否为4的倍数决定的。 - if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { - // =================================================== - // ================ Image 优化路径 =================== - // =================================================== - - // a. 选择内核:根据数据类型选择FP32或FP16的Image内核 - cl_kernel kernel_to_use = nullptr; - if (input_dtype == MLLM_TYPE_F32) { - kernel_to_use = kernel_fp32_image_; - } else if (input_dtype == MLLM_TYPE_F16) { - kernel_to_use = kernel_fp16_image_; - } else { - throw std::runtime_error("Unsupported data type for OpenCLAddFuncOp Image Path"); - } - - // b. 准备内核参数 - // - 输入张量(inputs): 它们是由默认的 .cl() 方法创建的Buffer,所以必须通过工具函数进行拷贝转换。 - // - 输出张量(output): 它在setUp中已经被直接创建为Image,所以可以直接获取其句柄。 - - // 创建一个临时存储vector,用于管理为“输入”转换而来的临时Image的生命周期 - std::vector temp_tensor_storage; - - cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); - cl_mem inB_mem = get_image_from_tensor(inputs[1], ocl_backend_, temp_tensor_storage); - - // 输出张量已经是Image,直接获取句柄,无需转换! - cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); - - // c. 设置内核参数 - clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); - clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); - clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &inB_mem); - clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); - - const int width = static_cast(output->device_memory().image_width); - const int height = static_cast(output->device_memory().image_height); - - clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); - clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); - - // d. 设置工作维度并执行内核 - const size_t global_work_size[2] = { (size_t)width, (size_t)height }; - clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); - - } else { - // =================================================== - // ============= 普通 Buffer 回退路径 ================ - // =================================================== - - // a. 选择内核:根据数据类型选择FP32或FP16的Buffer内核 - cl_kernel kernel_to_use = nullptr; - if (input_dtype == MLLM_TYPE_F32) { - kernel_to_use = kernel_fp32_buffer_; - } else if (input_dtype == MLLM_TYPE_F16) { - kernel_to_use = kernel_fp16_buffer_; - } else { - throw std::runtime_error("Unsupported data type for OpenCLAddFuncOp Buffer Path"); - } - - // b. 准备内核参数 (所有张量都是Buffer,直接获取句柄) - cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); - cl_mem in1_buf = ocl_backend_->get_cl_mem(*inputs[1]); - cl_mem out_buf = ocl_backend_->get_cl_mem(*output); - - clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); - clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &in1_buf); - clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); - - // c. 计算工作项数量 - size_t count = inputs[0]->count(); - // FP16的Buffer内核是向量化的,工作项数量是总元素数除以4 - if (input_dtype == MLLM_TYPE_F16) { - if (count % 4 != 0) { - throw std::runtime_error("For FP16 vector kernel, tensor count must be a multiple of 4."); - } - count /= 4; - } - - // d. 设置工作维度并执行内核 - const size_t global_work_size[1] = {count}; - clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); - } - - return MLLM_NO_ERROR; -} -} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLAddOp.cpp b/src/backends/opencl/op/OpenCLAddOp.cpp new file mode 100644 index 000000000..694c30849 --- /dev/null +++ b/src/backends/opencl/op/OpenCLAddOp.cpp @@ -0,0 +1,198 @@ +#include "OpenCLAddOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" + +namespace mllm { + +OpenCLAddOp::OpenCLAddOp(Backend *bn, std::string name, float data) : + Op(bn, std::move(name)), data_(data) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/add.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + kernel_fp32_buffer_ = clCreateKernel(program, "add_scalar_float", &err); + check_cl_error(err, "clCreateKernel for add_scalar_float"); + + kernel_fp32_image_ = clCreateKernel(program, "add_scalar_float_image2d", &err); + check_cl_error(err, "clCreateKernel for add_scalar_float_image2d"); + + kernel_fp16_buffer_ = clCreateKernel(program, "add_scalar_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for add_scalar_fp16_vector"); + + kernel_fp16_image_ = clCreateKernel(program, "add_scalar_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for add_scalar_fp16_image2d"); + + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +OpenCLAddOp::~OpenCLAddOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLAddOp::reshape(vector> inputs, vector> outputs) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLAddOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + auto output = outputs[0]; + output->setDtype(inputs[0]->dtype()); + + auto &out_mem = output->device_memory(); + if (output->dimension() % 4 == 0 && false) { + out_mem.type = MEM_TYPE_IMAGE_2D; + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + out_mem.type = MEM_TYPE_BUFFER; + } + output->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLAddOp::execute(vector> inputs, vector> outputs) { + /* + auto input_dtype = inputs[0]->dtype(); + auto output = outputs[0]; + if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { + // --- Image 优化路径 --- + cl_kernel kernel_to_use = nullptr; + if (input_dtype == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_image_; + } else { // MLLM_TYPE_F16 + kernel_to_use = kernel_fp16_image_; + } + + std::vector temp_tensor_storage; + cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); + cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); + if (input_dtype == MLLM_TYPE_F32) { + clSetKernelArg(kernel_to_use, 2, sizeof(float), &data_); + } else { // MLLM_TYPE_F16 + mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(data_); + clSetKernelArg(kernel_to_use, 2, sizeof(mllm_fp16_t), &data_fp16); + } + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); + + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + + } else { + // --- 普通 Buffer 回退路径 --- + cl_kernel kernel_to_use = nullptr; + if (input_dtype == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_buffer_; + } else { // MLLM_TYPE_F16 + kernel_to_use = kernel_fp16_buffer_; + } + + cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + if (input_dtype == MLLM_TYPE_F32) { + clSetKernelArg(kernel_to_use, 1, sizeof(float), &data_); + } else { // MLLM_TYPE_F16 + mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(data_); + clSetKernelArg(kernel_to_use, 1, sizeof(mllm_fp16_t), &data_fp16); + } + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + + size_t count = inputs[0]->count(); + if (input_dtype == MLLM_TYPE_F16) { count /= 4; } + + const size_t global_work_size[1] = {count}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } + */ + auto input = inputs[0]; + auto output = outputs[0]; + // 假设我们决定在这个算子中使用Image路径以获得最佳性能 + bool use_image_path = (output->dimension() % 4 == 0); + if (use_image_path) { + // =================================================== + // ================ Image 优化路径 =================== + // =================================================== + // 1. 将输入和输出Tensor原地转换为Image2D类型 + tensorGlobal2Image(*input); + tensorGlobal2Image(*output); // 注意:这里假设output在setUp中是以Buffer类型分配的 + // 2. 选择内核 + cl_kernel kernel_to_use = nullptr; + if (input->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_image_; + } else { // MLLM_TYPE_F16 + kernel_to_use = kernel_fp16_image_; + } + // 3. 获取Image句柄并设置参数 + cl_mem in_img = ocl_backend_->get_cl_mem(*input); + cl_mem out_img = ocl_backend_->get_cl_mem(*output); + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &in_img); + if (input->dtype() == MLLM_TYPE_F32) { + clSetKernelArg(kernel_to_use, 2, sizeof(float), &data_); + } else { // MLLM_TYPE_F16 + mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(data_); + clSetKernelArg(kernel_to_use, 2, sizeof(mllm_fp16_t), &data_fp16); + } + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_img); + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + // 4. 执行内核 + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + // 5. [重要] 如果后续的算子需要Buffer类型,则将Tensor转换回去 + tensorImage2Global(*input); + tensorImage2Global(*output); + } else { + // =================================================== + // ============= 普通 Buffer 回退路径 ================ + // =================================================== + // 确保输入输出都是Buffer(如果之前被转换过) + tensorImage2Global(*input); + tensorImage2Global(*output); + cl_kernel kernel_to_use = nullptr; + if (input->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_buffer_; + } else { // MLLM_TYPE_F16 + kernel_to_use = kernel_fp16_buffer_; + } + cl_mem in0_buf = ocl_backend_->get_cl_mem(*input); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + if (input->dtype() == MLLM_TYPE_F32) { + clSetKernelArg(kernel_to_use, 1, sizeof(float), &data_); + } else { // MLLM_TYPE_F16 + mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(data_); + clSetKernelArg(kernel_to_use, 1, sizeof(mllm_fp16_t), &data_fp16); + } + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + size_t count = input->count(); + if (input->dtype() == MLLM_TYPE_F16) { count /= 4; } + const size_t global_work_size[1] = {count}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLAddOp.hpp b/src/backends/opencl/op/OpenCLAddOp.hpp new file mode 100644 index 000000000..63b9729e1 --- /dev/null +++ b/src/backends/opencl/op/OpenCLAddOp.hpp @@ -0,0 +1,42 @@ +#ifndef OPENCL_ADD_OP_HPP +#define OPENCL_ADD_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLAddOp : public Op { +public: + OpenCLAddOp(Backend *bn, std::string name, float data); + ~OpenCLAddOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + float data_; // 用于存储要加的标量 + + cl_kernel kernel_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp16_buffer_ = nullptr; + cl_kernel kernel_fp16_image_ = nullptr; + + cl_sampler sampler_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +// OpenCLAddOp 的创建器 +class OpenCLAddOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // 从 op_param 中解析出要加的标量数据 + float data = op_param["data"]; + return new OpenCLAddOp(bn, name, data); + } +}; + +} // namespace mllm + +#endif // OPENCL_ADD_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLAddTwoOp.cpp b/src/backends/opencl/op/OpenCLAddTwoOp.cpp new file mode 100644 index 000000000..93bdca9f0 --- /dev/null +++ b/src/backends/opencl/op/OpenCLAddTwoOp.cpp @@ -0,0 +1,162 @@ +#include "OpenCLAddTwoOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLAddTwoOp::OpenCLAddTwoOp(Backend *bn, std::string name) : + Op(bn, std::move(name)) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + // 只获取一次 Program + const std::string kernel_path = "kernel/add.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + // --- 创建全部四个内核 --- + kernel_fp32_buffer_ = clCreateKernel(program, "add_float", &err); + check_cl_error(err, "clCreateKernel for add_float"); + + kernel_fp32_image_ = clCreateKernel(program, "add_float_image2d", &err); + check_cl_error(err, "clCreateKernel for add_float_image2d"); + + kernel_fp16_buffer_ = clCreateKernel(program, "add_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for add_fp16_vector"); + + kernel_fp16_image_ = clCreateKernel(program, "add_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for add_fp16_image2d"); + + // --- 创建 Sampler --- + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +// 替换您的析构函数 +OpenCLAddTwoOp::~OpenCLAddTwoOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLAddTwoOp::reshape(vector> inputs, vector> outputs) { + // 加法操作要求输入和输出的形状一致 + auto input0_shape = inputs[0]->shape(); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLAddTwoOp::setUp(vector> inputs, vector> outputs) { + // 确保输入在设备上 + for (auto &input : inputs) { + input->to(MLLM_OPENCL); + } + auto output = outputs[0]; + output->to(MLLM_OPENCL); + // 根据输入设置输出的数据类型 + output->setDtype(inputs[0]->dtype()); + + auto &out_mem = output->device_memory(); + + // **核心修改:直接决策为 Image 或 Buffer** + if (output->dimension() % 4 == 0 && false) { + // 条件满足,直接为输出张量申请 Image2D 类型的内存 + out_mem.type = MEM_TYPE_IMAGE_2D; // **直接设为 Image2D** + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + // 条件不满足,回退到普通 Buffer + out_mem.type = MEM_TYPE_BUFFER; + } + + // alloc() 现在会根据 out_mem.type 直接创建出 Image 或 Buffer + output->alloc(); + return MLLM_NO_ERROR; +} +ErrorCode OpenCLAddTwoOp::execute(vector> inputs, vector> outputs) { + auto input1 = inputs[0]; + auto input2 = inputs[1]; + auto output = outputs[0]; + + // 决定是否走Image优化路径 + bool use_image_path = (output->dimension() % 4 == 0) && false; + + if (use_image_path) { + // =================================================== + // ================ Image 优化路径 =================== + // =================================================== + + // 1. 将两个输入和输出Tensor原地转换为Image2D类型 + tensorGlobal2Image(*input1); + tensorGlobal2Image(*input2); + tensorGlobal2Image(*output); + + // 2. 选择内核 + cl_kernel kernel_to_use = (input1->dtype() == MLLM_TYPE_F32) ? kernel_fp32_image_ : kernel_fp16_image_; + + // 3. 获取Image句柄并设置参数 + cl_mem inA_img = ocl_backend_->get_cl_mem(*input1); + cl_mem inB_img = ocl_backend_->get_cl_mem(*input2); + cl_mem out_img = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_img); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &inB_img); + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_img); + + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + + // 4. 执行内核 + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + cl_event event; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "add2", event); + + // 5. [重要] 将所有Tensor转换回Buffer格式,以供后续算子使用 + tensorImage2Global(*input1); + tensorImage2Global(*input2); + tensorImage2Global(*output); + + } else { + // =================================================== + // ============= 普通 Buffer 回退路径 ================ + // =================================================== + + // 确保所有Tensor都是Buffer格式 + tensorImage2Global(*input1); + tensorImage2Global(*input2); + tensorImage2Global(*output); + + cl_kernel kernel_to_use = (input1->dtype() == MLLM_TYPE_F32) ? kernel_fp32_buffer_ : kernel_fp16_buffer_; + + cl_mem in0_buf = ocl_backend_->get_cl_mem(*input1); + cl_mem in1_buf = ocl_backend_->get_cl_mem(*input2); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &in1_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + + size_t count = input1->count(); + if (input1->dtype() == MLLM_TYPE_F16) { + if (count % 4 != 0) { + throw std::runtime_error("[addTwo]For FP16 vector kernel, tensor count must be a multiple of 4."); + } + count /= 4; + } + + const size_t global_work_size[1] = {count}; + cl_event event; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "add2", event); + } + + return MLLM_NO_ERROR; +} +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLAddFuncOp.hpp b/src/backends/opencl/op/OpenCLAddTwoOp.hpp similarity index 70% rename from src/backends/opencl/op/OpenCLAddFuncOp.hpp rename to src/backends/opencl/op/OpenCLAddTwoOp.hpp index 1173528ff..98365bc22 100644 --- a/src/backends/opencl/op/OpenCLAddFuncOp.hpp +++ b/src/backends/opencl/op/OpenCLAddTwoOp.hpp @@ -6,34 +6,31 @@ namespace mllm { -class OpenCLAddFuncOp : public Op { +class OpenCLAddTwoOp : public Op { public: - OpenCLAddFuncOp(Backend *bn, std::string name); - ~OpenCLAddFuncOp() override; + OpenCLAddTwoOp(Backend *bn, std::string name); + ~OpenCLAddTwoOp() override; ErrorCode reshape(vector> inputs, vector> outputs) override; ErrorCode setUp(vector> inputs, vector> outputs) override; ErrorCode execute(vector> inputs, vector> outputs) override; private: - // cl_kernel buffer_kernel_ = nullptr; - // cl_kernel image_kernel_ = nullptr; // 新的 Image2D kernel - cl_kernel kernel_fp32_buffer_ = nullptr; cl_kernel kernel_fp32_image_ = nullptr; cl_kernel kernel_fp16_buffer_ = nullptr; cl_kernel kernel_fp16_image_ = nullptr; - + cl_sampler sampler_ = nullptr; OpenCLBackend *ocl_backend_ = nullptr; }; -// OpenCLAddFuncOp 的创建器,用于工厂模式 -class OpenCLAddFuncOpCreator : public OpenCLBackend::Creator { +// OpenCLAddTwoOp 的创建器,用于工厂模式 +class OpenCLAddTwoOpCreator : public OpenCLBackend::Creator { public: Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { // 对于简单的加法,我们可能不需要 op_param 和 threadCount - return new OpenCLAddFuncOp(bn, name); + return new OpenCLAddTwoOp(bn, name); } }; diff --git a/src/backends/opencl/op/OpenCLArgSortOp.cpp b/src/backends/opencl/op/OpenCLArgSortOp.cpp new file mode 100644 index 000000000..fd7d7cef8 --- /dev/null +++ b/src/backends/opencl/op/OpenCLArgSortOp.cpp @@ -0,0 +1,133 @@ +#include "OpenCLArgSortOp.hpp" +#include "Types.hpp" +// #include "utils/OpenCLTools.hpp" +#include +#include // For error message formatting + +namespace mllm { + +// 构造函数、析构函数、reshape 和 setUp 保持不变... +OpenCLArgSortOp::OpenCLArgSortOp(Backend *bn, std::string name) : + Op(bn, std::move(name)) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + support_fp16_ = ocl_backend_->has_fp16_support(); + const std::string kernel_path = "kernel/argsort.cl"; + + std::string build_options; + if (support_fp16_) { + build_options += " -DSUPPORTS_FP16"; + } + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + + cl_int err; + kernel_init_indices_ = clCreateKernel(program, "init_indices", &err); + check_cl_error(err, "clCreateKernel init_indices"); + kernel_argsort_fp32_ = clCreateKernel(program, "bitonic_argsort_step_fp32", &err); + check_cl_error(err, "clCreateKernel bitonic_argsort_step_fp32"); + kernel_cast_indices_fp32_ = clCreateKernel(program, "cast_indices_to_fp32", &err); + check_cl_error(err, "clCreateKernel cast_indices_to_fp32"); + + kernel_argsort_fp16_ = clCreateKernel(program, "bitonic_argsort_step_fp16", &err); + check_cl_error(err, "clCreateKernel bitonic_argsort_step_fp16"); + kernel_cast_indices_fp16_ = clCreateKernel(program, "cast_indices_to_fp16", &err); + check_cl_error(err, "clCreateKernel cast_indices_to_fp16"); +} + +OpenCLArgSortOp::~OpenCLArgSortOp() { + if (kernel_init_indices_) clReleaseKernel(kernel_init_indices_); + if (kernel_argsort_fp32_) clReleaseKernel(kernel_argsort_fp32_); + if (kernel_cast_indices_fp32_) clReleaseKernel(kernel_cast_indices_fp32_); + if (kernel_argsort_fp16_) clReleaseKernel(kernel_argsort_fp16_); + if (kernel_cast_indices_fp16_) clReleaseKernel(kernel_cast_indices_fp16_); +} + +ErrorCode OpenCLArgSortOp::reshape(vector> inputs, vector> outputs) { + assert(inputs.size() == 1 && outputs.size() == 1); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLArgSortOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLArgSortOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + + const int batch_size = input->batch() * input->head() * input->sequence(); + const int N = input->dimension(); + cl_int err; + + const size_t input_bytes = (size_t)input->count() * input->dtypeSize(); + cl_mem input_buf = ocl_backend_->get_cl_mem(*input); + cl_mem output_buf = ocl_backend_->get_cl_mem(*output); + + // 1. 创建临时 buffer + cl_mem temp_values_buf = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_WRITE, input_bytes, nullptr, &err); + check_cl_error(err, "clCreateBuffer for temp_values"); + cl_mem indices_buf = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_WRITE, (size_t)batch_size * N * sizeof(int), nullptr, &err); + check_cl_error(err, "clCreateBuffer for indices"); + + // 2. 在设备上复制数据到临时 buffer + err = clEnqueueCopyBuffer(ocl_backend_->getQueue(), input_buf, temp_values_buf, 0, 0, input_bytes, 0, nullptr, nullptr); + check_cl_error(err, "clEnqueueCopyBuffer to temp_values_buf"); + + // 3. 初始化索引 buffer + size_t global_work_size_init = (size_t)batch_size * N; + clSetKernelArg(kernel_init_indices_, 0, sizeof(cl_mem), &indices_buf); + clSetKernelArg(kernel_init_indices_, 1, sizeof(int), &N); + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_init_indices_, 1, nullptr, &global_work_size_init, nullptr, 0, nullptr, nullptr); + check_cl_error(err, "clEnqueueNDRangeKernel init_indices"); + + // 4. 执行 Bitonic Sort + cl_kernel kernel_sort = (input->dtype() == MLLM_TYPE_F32) ? kernel_argsort_fp32_ : kernel_argsort_fp16_; + int descending = 0; // 0 for ascending + + int power_of_2_N = 1; + while (power_of_2_N < N) { + power_of_2_N <<= 1; + } + int num_stages = (N > 1) ? std::log2(power_of_2_N) : 0; + + for (int stage = 0; stage < num_stages; ++stage) { + for (int pass = stage; pass >= 0; --pass) { + size_t global_work_size_sort[2] = {(size_t)power_of_2_N / 2, (size_t)batch_size}; + + clSetKernelArg(kernel_sort, 0, sizeof(cl_mem), &temp_values_buf); + clSetKernelArg(kernel_sort, 1, sizeof(cl_mem), &indices_buf); + clSetKernelArg(kernel_sort, 2, sizeof(int), &N); + clSetKernelArg(kernel_sort, 3, sizeof(int), &stage); + clSetKernelArg(kernel_sort, 4, sizeof(int), &pass); + clSetKernelArg(kernel_sort, 5, sizeof(int), &descending); + + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_sort, 2, nullptr, global_work_size_sort, nullptr, 0, nullptr, nullptr); + if (err != CL_SUCCESS) { + std::string error_msg = "clEnqueueNDRangeKernel bitonic_sort failed with code " + std::to_string(err) + + " at stage " + std::to_string(stage) + ", pass " + std::to_string(pass); + throw std::runtime_error(error_msg); + } + } + } + + // 5. 转换索引类型并写入输出 + cl_kernel kernel_cast = (output->dtype() == MLLM_TYPE_F32) ? kernel_cast_indices_fp32_ : kernel_cast_indices_fp16_; + size_t global_work_size_cast = (size_t)batch_size * N; + clSetKernelArg(kernel_cast, 0, sizeof(cl_mem), &indices_buf); + clSetKernelArg(kernel_cast, 1, sizeof(cl_mem), &output_buf); + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_cast, 1, nullptr, &global_work_size_cast, nullptr, 0, nullptr, nullptr); + check_cl_error(err, "clEnqueueNDRangeKernel cast_indices"); + + // 6. 释放临时 buffer + clReleaseMemObject(temp_values_buf); + clReleaseMemObject(indices_buf); + + return MLLM_NO_ERROR; +} + +} // namespace mllm diff --git a/src/backends/opencl/op/OpenCLArgSortOp.hpp b/src/backends/opencl/op/OpenCLArgSortOp.hpp new file mode 100644 index 000000000..908cf7cba --- /dev/null +++ b/src/backends/opencl/op/OpenCLArgSortOp.hpp @@ -0,0 +1,41 @@ +#ifndef OPENCL_ARGSORT_OP_HPP +#define OPENCL_ARGSORT_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLArgSortOp : public Op { +public: + // 构造函数与CPU版本类似,但不需要threadCount + OpenCLArgSortOp(Backend *bn, std::string name); + ~OpenCLArgSortOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + // 内核对象 + cl_kernel kernel_init_indices_ = nullptr; + cl_kernel kernel_argsort_fp32_ = nullptr; + cl_kernel kernel_argsort_fp16_ = nullptr; + cl_kernel kernel_cast_indices_fp32_ = nullptr; + cl_kernel kernel_cast_indices_fp16_ = nullptr; + + OpenCLBackend *ocl_backend_ = nullptr; + bool support_fp16_ = false; +}; + +class OpenCLArgSortOpCreator : public OpenCLBackend::Creator { +public: + // create 方法与CPU版本类似 + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new OpenCLArgSortOp(bn, name); + } +}; + +} // namespace mllm + +#endif // OPENCL_ARGSORT_OP_HPP diff --git a/src/backends/opencl/op/OpenCLBinCountOp.cpp b/src/backends/opencl/op/OpenCLBinCountOp.cpp new file mode 100644 index 000000000..ddbcb911c --- /dev/null +++ b/src/backends/opencl/op/OpenCLBinCountOp.cpp @@ -0,0 +1,129 @@ +// opencl/op/OpenCLBinCountOp.cpp + +#include "OpenCLBinCountOp.hpp" +#include "Types.hpp" +#include +#include +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" +// opencl/op/OpenCLBinCountOp.cpp +namespace mllm { + +// 构造函数、reshape、setUp函数与上一版相同,这里省略... +OpenCLBinCountOp::OpenCLBinCountOp(Backend *bn, std::string name) : + Op(bn, std::move(name)) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/bincount.cl"; + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + + auto program = ocl_backend_->getProgram(kernel_path, build_options); + cl_int err; + + kernel_map_["bincount_count_fp32"] = clCreateKernel(program, "bincount_count_fp32", &err); + check_cl_error(err, "clCreateKernel bincount_count_fp32"); + kernel_map_["bincount_count_fp16"] = clCreateKernel(program, "bincount_count", &err); + check_cl_error(err, "clCreateKernel bincount_count_fp16"); + kernel_map_["cast_int_to_float"] = clCreateKernel(program, "cast_int_to_float", &err); + check_cl_error(err, "clCreateKernel cast_int_to_float"); + kernel_map_["cast_int_to_half"] = clCreateKernel(program, "cast_int_to_half", &err); + check_cl_error(err, "clCreateKernel cast_int_to_half"); +} + +OpenCLBinCountOp::~OpenCLBinCountOp() { + for (auto &pair : kernel_map_) { + if (pair.second) { + clReleaseKernel(pair.second); + } + } +} + +ErrorCode OpenCLBinCountOp::reshape(vector> inputs, vector> outputs) { + assert(inputs[0]->batch() == 1 && inputs[0]->sequence() == 1 && inputs[0]->head() == 1); + outputs[0]->reshape(1, 1, 1, 0); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLBinCountOp::setUp(vector> inputs, vector> outputs) { + if (inputs[0]->dtype() != MLLM_TYPE_F32 && inputs[0]->dtype() != MLLM_TYPE_F16) { + return NOT_SUPPORT; + } + inputs[0]->to(MLLM_OPENCL); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLBinCountOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + // ocl_backend_->finishQueue(); // todo 同步问题 + + input->cpu(); + int size = input->dimension(); + int max_val = 0; + if (size > 0) { + if (input->dtype() == MLLM_TYPE_F32) { + float *data_ptr = input->hostPtr(); + max_val = static_cast(*std::max_element(data_ptr, data_ptr + size)); + } else { // MLLM_TYPE_F16 + std::vector float_vec(size); + for (int i = 0; i < size; ++i) { + float_vec[i] = MLLM_FP16_TO_FP32(input->dataAt(0, 0, 0, i)); + } + max_val = static_cast(*std::max_element(float_vec.begin(), float_vec.end())); + } + } + int output_size = max_val + 1; + output->reshape(1, 1, 1, output_size); + output->alloc(); + cl_int err; + cl_mem tmp_count_buffer = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_WRITE, output_size * sizeof(int), nullptr, &err); + check_cl_error(err, "clCreateBuffer for tmp_count_buffer"); + + int zero = 0; + cl_event fill_event; + err = clEnqueueFillBuffer(ocl_backend_->getQueue(), tmp_count_buffer, &zero, sizeof(int), 0, output_size * sizeof(int), 0, nullptr, &fill_event); + check_cl_error(err, "clEnqueueFillBuffer for tmp_count_buffer"); + ocl_backend_->addProfilingEvent("bincount_fill_zero", fill_event); + + input->cl(); + + cl_kernel count_kernel = (input->dtype() == MLLM_TYPE_F32) ? kernel_map_["bincount_count_fp32"] : kernel_map_["bincount_count_fp16"]; + cl_mem in_buf = ocl_backend_->get_cl_mem(*input); + clSetKernelArg(count_kernel, 0, sizeof(cl_mem), &in_buf); + clSetKernelArg(count_kernel, 1, sizeof(cl_mem), &tmp_count_buffer); + clSetKernelArg(count_kernel, 2, sizeof(int), &size); + clSetKernelArg(count_kernel, 3, sizeof(int), &max_val); + + const size_t local_work_size = 256; + const size_t global_work_size = ((size > 0 ? size : 1) + local_work_size - 1) / local_work_size * local_work_size; + + cl_event count_event; + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), count_kernel, 1, nullptr, &global_work_size, &local_work_size, 1, &fill_event, &count_event); + check_cl_error(err, "clEnqueueNDRangeKernel for bincount_count"); + ocl_backend_->addProfilingEvent("bincount_count", count_event); + + cl_kernel cast_kernel = (output->dtype() == MLLM_TYPE_F32) ? kernel_map_["cast_int_to_float"] : kernel_map_["cast_int_to_half"]; + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + clSetKernelArg(cast_kernel, 0, sizeof(cl_mem), &tmp_count_buffer); + clSetKernelArg(cast_kernel, 1, sizeof(cl_mem), &out_buf); + clSetKernelArg(cast_kernel, 2, sizeof(int), &output_size); + + const size_t cast_global_work_size = ((output_size > 0 ? output_size : 1) + local_work_size - 1) / local_work_size * local_work_size; + cl_event cast_event; + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), cast_kernel, 1, nullptr, &cast_global_work_size, &local_work_size, 1, &count_event, &cast_event); + check_cl_error(err, "clEnqueueNDRangeKernel for cast"); + ocl_backend_->addProfilingEvent("bincount_cast", cast_event); + clReleaseMemObject(tmp_count_buffer); + clWaitForEvents(1, &cast_event); + clReleaseEvent(fill_event); + clReleaseEvent(count_event); + clReleaseEvent(cast_event); + + return MLLM_NO_ERROR; +} +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLBinCountOp.hpp b/src/backends/opencl/op/OpenCLBinCountOp.hpp new file mode 100644 index 000000000..b481efd4f --- /dev/null +++ b/src/backends/opencl/op/OpenCLBinCountOp.hpp @@ -0,0 +1,35 @@ +// opencl/op/OpenCLBinCountOp.hpp + +#ifndef OPENCL_BINCOUNT_OP_HPP +#define OPENCL_BINCOUNT_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLBinCountOp : public Op { +public: + OpenCLBinCountOp(Backend *bn, std::string name); + ~OpenCLBinCountOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + +private: + std::map kernel_map_; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLBinCountOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // bincount 通常没有额外参数 + return new OpenCLBinCountOp(bn, name); + } +}; + +} // namespace mllm + +#endif // OPENCL_BINCOUNT_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLClipOp.cpp b/src/backends/opencl/op/OpenCLClipOp.cpp new file mode 100644 index 000000000..bae62eafe --- /dev/null +++ b/src/backends/opencl/op/OpenCLClipOp.cpp @@ -0,0 +1,184 @@ +// 文件名: ops/OpenCLClipOp.cpp + +#include "OpenCLClipOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" // 包含 check_cl_error +#include + +namespace mllm { + +// 构造函数 +OpenCLClipOp::OpenCLClipOp(Backend *bn, std::string name, const std::vector &b, const std::vector &h, const std::vector &s, const std::vector &d) : + Op(bn, std::move(name)), b_(b), h_(h), s_(s), d_(d) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) { + throw std::runtime_error("Backend is not OpenCLBackend for OpenCLClipOp"); + } +} + +// reshape方法,逻辑与CPU版本完全一致 +ErrorCode OpenCLClipOp::reshape(vector> inputs, vector> outputs) { + int dim_b = inputs[0]->batch(); + int dim_h = inputs[0]->head(); + int dim_s = inputs[0]->sequence(); + int dim_d = inputs[0]->dimension(); + + std::vector *, int *>> data = {{&b_, &dim_b}, {&h_, &dim_h}, {&s_, &dim_s}, {&d_, &dim_d}}; + for (auto &pair : data) { + if (pair.first->size() == 2) { // [start, end) + *pair.second = (*pair.first)[1] - (*pair.first)[0]; + } else if (pair.first->size() == 1) { // [index] + *pair.second = 1; + } + } + + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +// setUp方法,准备输入输出张量 +ErrorCode OpenCLClipOp::setUp(vector> inputs, vector> outputs) { + // 确保输入张量在OpenCL设备上 + inputs[0]->to(MLLM_OPENCL); + + // 根据裁剪参数计算输出形状 + reshape(inputs, outputs); + + // 为输出张量分配设备内存 + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +// execute方法,执行实际的裁剪操作 +ErrorCode OpenCLClipOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + size_t element_size = input->dtypeSize(); + + cl_mem in_buf = ocl_backend_->get_cl_mem(*input); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + cl_command_queue queue = ocl_backend_->getQueue(); + cl_int err; + + // 根据不同的裁剪参数执行相应的拷贝操作 + if (!b_.empty()) { + // 裁剪 'batch' 维度。这部分数据是连续的,可一次性拷贝。 + int b_start = b_[0]; + if (b_start < 0) b_start += input->batch(); + int b_end = (b_.size() == 2) ? b_[1] : b_start + 1; + if (b_.size() == 2 && b_end < 0) b_end += input->batch(); + + if (b_start < 0 || b_end > input->batch() || b_start >= b_end) { + return NOT_SUPPORT; + } + int count_b = b_end - b_start; + + size_t src_offset_bytes = (size_t)b_start * input->head() * input->sequence() * input->dimension() * element_size; + size_t copy_size_bytes = (size_t)count_b * input->head() * input->sequence() * input->dimension() * element_size; + + err = clEnqueueCopyBuffer(queue, in_buf, out_buf, src_offset_bytes, 0, copy_size_bytes, 0, nullptr, nullptr); + check_cl_error(err, "clEnqueueCopyBuffer for batch clipping"); + + } else if (!s_.empty()) { + // ============================ 已修正的逻辑 ============================ + // 裁剪 'sequence' 维度。 + int s_start = s_[0]; + if (s_start < 0) { + s_start += input->sequence(); + } + + int s_end; + if (s_.size() == 2) { + s_end = s_[1]; + if (s_end < 0) { + s_end += input->sequence(); + } + } else { // s_.size() == 1 + s_end = s_start + 1; + } + + // 增加健壮性检查 + if (s_start < 0 || s_end > input->sequence() || s_start >= s_end) { + std::cerr << "Error: Invalid sequence clip range. Input sequence is " << input->sequence() + << ", but calculated range is [" << s_start << ", " << s_end << ")." << std::endl; + return NOT_SUPPORT; + } + + int count_s = s_end - s_start; + // ============================ 修正结束 ============================ + + size_t copy_size_per_batch = (size_t)input->head() * count_s * input->dimension() * element_size; + for (int b = 0; b < input->batch(); ++b) { + size_t src_offset_bytes = input->offset(b, 0, s_start, 0) * element_size; + size_t dst_offset_bytes = output->offset(b, 0, 0, 0) * element_size; + cl_event event; + err = clEnqueueCopyBuffer(queue, in_buf, out_buf, src_offset_bytes, dst_offset_bytes, copy_size_per_batch, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "clip", event); + check_cl_error(err, "clEnqueueCopyBuffer for sequence clipping"); + } + + } else if (!d_.empty()) { + // 裁剪 'dimension' 维度。这是典型的非连续内存拷贝,使用clEnqueueCopyBufferRect效率最高。 + int d_start = d_[0]; + if (d_start < 0) d_start += input->dimension(); + + int d_end; + if (d_.size() == 2) { + d_end = d_[1]; + if (d_end < 0) d_end += input->dimension(); + } else { // d_.size() == 1 + d_end = d_start + 1; + } + + if (d_start < 0 || d_end > input->dimension() || d_start >= d_end) { + return NOT_SUPPORT; + } + int count_d = d_end - d_start; + + // 定义源、目标和区域的3D参数 + size_t src_origin[3] = {(size_t)d_start * element_size, 0, 0}; // X, Y, Z in bytes + size_t dst_origin[3] = {0, 0, 0}; + size_t region[3] = {(size_t)count_d * element_size, (size_t)input->sequence(), (size_t)(input->batch() * input->head())}; + + // 定义内存布局的行间距和切片间距 + size_t src_row_pitch = input->dimension() * element_size; + size_t src_slice_pitch = input->sequence() * src_row_pitch; + size_t dst_row_pitch = output->dimension() * element_size; + size_t dst_slice_pitch = output->sequence() * dst_row_pitch; + + cl_event event; + err = clEnqueueCopyBufferRect(queue, in_buf, out_buf, src_origin, dst_origin, region, + src_row_pitch, src_slice_pitch, dst_row_pitch, dst_slice_pitch, + 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "clEnqueueCopyBufferRect for dimension clipping"); + + } else { + std::cerr << "[TODO] OpenCLClipOp does not support this clipping parameter configuration!" << std::endl; + return NOT_SUPPORT; + } + + return MLLM_NO_ERROR; +} + +// 创建器实现 +Op *OpenCLClipOpCreator::create(OpParam op_param, Backend *bn, string name, int threadCount) const { + // 从op_param中解析出向量参数 + + // Example structure: {"b_size": 1, "b_0": 5, "h_size": 0, ...} + int b_size = op_param.at("b_size"); + int h_size = op_param.at("h_size"); + int s_size = op_param.at("s_size"); + int d_size = op_param.at("d_size"); + + std::vector b, h, s, d; + for (int i = 0; i < b_size; ++i) b.push_back(op_param.at("b_" + std::to_string(i))); + for (int i = 0; i < h_size; ++i) h.push_back(op_param.at("h_" + std::to_string(i))); + for (int i = 0; i < s_size; ++i) s.push_back(op_param.at("s_" + std::to_string(i))); + for (int i = 0; i < d_size; ++i) d.push_back(op_param.at("d_" + std::to_string(i))); + + return new OpenCLClipOp(bn, name, b, h, s, d); +} + +} // namespace mllm diff --git a/src/backends/opencl/op/OpenCLClipOp.hpp b/src/backends/opencl/op/OpenCLClipOp.hpp new file mode 100644 index 000000000..2c275c26e --- /dev/null +++ b/src/backends/opencl/op/OpenCLClipOp.hpp @@ -0,0 +1,55 @@ +// 文件名: ops/OpenCLClipOp.hpp + +#ifndef OPENCL_CLIP_OP_HPP +#define OPENCL_CLIP_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" +#include + +namespace mllm { + +/** + * @brief OpenCL实现的Clip操作,用于裁剪张量的部分区域。 + */ +class OpenCLClipOp : public Op { +public: + /** + * @brief 构造函数 + * @param bn 后端指针 + * @param name 操作名 + * @param b 裁剪batch维度的参数 + * @param h 裁剪head维度的参数 + * @param s 裁剪sequence维度的参数 + * @param d 裁剪dimension维度的参数 + */ + OpenCLClipOp(Backend *bn, std::string name, const std::vector &b, const std::vector &h, const std::vector &s, const std::vector &d); + + // 默认析构函数即可 + ~OpenCLClipOp() override = default; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + // 存储各个维度的裁剪参数 + std::vector b_; + std::vector h_; + std::vector s_; + std::vector d_; + + OpenCLBackend *ocl_backend_ = nullptr; +}; + +/** + * @brief OpenCLClipOp的创建器类,用于工厂模式创建实例。 + */ +class OpenCLClipOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override; +}; + +} // namespace mllm + +#endif // OPENCL_CLIP_OP_HPP diff --git a/src/backends/opencl/op/OpenCLClipTensorOp.cpp b/src/backends/opencl/op/OpenCLClipTensorOp.cpp new file mode 100644 index 000000000..0ebebc8fa --- /dev/null +++ b/src/backends/opencl/op/OpenCLClipTensorOp.cpp @@ -0,0 +1,128 @@ +#include "OpenCLClipTensorOp.hpp" +#include "Types.hpp" +// #include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLClipTensorOp::OpenCLClipTensorOp(Backend *bn, std::string name, Chl dim) : + Op(bn, std::move(name)), dim_(dim) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/cliptensor.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + kernel_seq_fp32_ = clCreateKernel(program, "clip_sequence_fp32", &err); + check_cl_error(err, "clCreateKernel for clip_sequence_fp32"); + kernel_seq_fp16_ = clCreateKernel(program, "clip_sequence_fp16", &err); + check_cl_error(err, "clCreateKernel for clip_sequence_fp16"); + + kernel_dim_fp32_ = clCreateKernel(program, "clip_dimension_fp32", &err); + check_cl_error(err, "clCreateKernel for clip_dimension_fp32"); + kernel_dim_fp16_ = clCreateKernel(program, "clip_dimension_fp16", &err); + check_cl_error(err, "clCreateKernel for clip_dimension_fp16"); +} + +OpenCLClipTensorOp::~OpenCLClipTensorOp() { + if (kernel_seq_fp32_) clReleaseKernel(kernel_seq_fp32_); + if (kernel_seq_fp16_) clReleaseKernel(kernel_seq_fp16_); + if (kernel_dim_fp32_) clReleaseKernel(kernel_dim_fp32_); + if (kernel_dim_fp16_) clReleaseKernel(kernel_dim_fp16_); +} + +ErrorCode OpenCLClipTensorOp::reshape(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto indices = inputs[1]; + auto output = outputs[0]; + + if (dim_ == SEQUENCE) { + int new_seq = indices->dimension(); // Indices are 1D, stored in the dimension field + output->reshape(input->batch(), input->head(), new_seq, input->dimension()); + } else if (dim_ == DIMENSION) { + int new_dim = indices->dimension(); + output->reshape(input->batch(), input->head(), input->sequence(), new_dim); + } else { + return NOT_SUPPORT; + } + output->setDtype(input->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLClipTensorOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + inputs[1]->to(MLLM_OPENCL); // Indices tensor also needs to be on the device + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLClipTensorOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto indices = inputs[1]; + auto output = outputs[0]; + + if (input->ctype() != BSHD || output->ctype() != BSHD) { + return NOT_SUPPORT; + } + + cl_kernel kernel_to_use = nullptr; + cl_event event; + cl_int err; + + cl_mem in_buf = ocl_backend_->get_cl_mem(*input); + cl_mem indices_buf = ocl_backend_->get_cl_mem(*indices); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + if (dim_ == SEQUENCE) { + kernel_to_use = (input->dtype() == MLLM_TYPE_F32) ? kernel_seq_fp32_ : kernel_seq_fp16_; + + const int B = input->batch(); + const int H = input->head(); + const int S_in = input->sequence(); + const int D = input->dimension(); + const int S_out = output->sequence(); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &indices_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &B); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &H); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &S_in); + clSetKernelArg(kernel_to_use, 6, sizeof(int), &D); + clSetKernelArg(kernel_to_use, 7, sizeof(int), &S_out); + + const size_t global_work_size[3] = {(size_t)D, (size_t)H, (size_t)B * S_out}; + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, global_work_size, nullptr, 0, nullptr, &event); + check_cl_error(err, "clEnqueueNDRangeKernel for Clip Sequence"); + + } else if (dim_ == DIMENSION) { + kernel_to_use = (input->dtype() == MLLM_TYPE_F32) ? kernel_dim_fp32_ : kernel_dim_fp16_; + + const int B = input->batch(); + const int H = input->head(); + const int S = input->sequence(); + const int D_in = input->dimension(); + const int D_out = output->dimension(); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &indices_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &B); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &H); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &S); + clSetKernelArg(kernel_to_use, 6, sizeof(int), &D_in); + clSetKernelArg(kernel_to_use, 7, sizeof(int), &D_out); + + const size_t global_work_size[3] = {(size_t)D_out, (size_t)S, (size_t)B * H}; + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, global_work_size, nullptr, 0, nullptr, &event); + check_cl_error(err, "clEnqueueNDRangeKernel for Clip Dimension"); + + } else { + return NOT_SUPPORT; + } + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLClipTensorOp.hpp b/src/backends/opencl/op/OpenCLClipTensorOp.hpp new file mode 100644 index 000000000..cf8ef773a --- /dev/null +++ b/src/backends/opencl/op/OpenCLClipTensorOp.hpp @@ -0,0 +1,37 @@ +#ifndef OPENCL_CLIP_TENSOR_OP_HPP +#define OPENCL_CLIP_TENSOR_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLClipTensorOp : public Op { +public: + OpenCLClipTensorOp(Backend *bn, std::string name, Chl dim); + ~OpenCLClipTensorOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + Chl dim_; + cl_kernel kernel_seq_fp32_ = nullptr; + cl_kernel kernel_seq_fp16_ = nullptr; + cl_kernel kernel_dim_fp32_ = nullptr; + cl_kernel kernel_dim_fp16_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLClipTensorOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + Chl dim = (Chl)op_param.at("dim"); + return new OpenCLClipTensorOp(bn, name, dim); + } +}; + +} // namespace mllm + +#endif // OPENCL_CLIP_TENSOR_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLDivIntOp.cpp b/src/backends/opencl/op/OpenCLDivIntOp.cpp new file mode 100644 index 000000000..dea5fd68a --- /dev/null +++ b/src/backends/opencl/op/OpenCLDivIntOp.cpp @@ -0,0 +1,127 @@ +#include "OpenCLDivIntOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +// #include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" + +namespace mllm { + +OpenCLDivIntOp::OpenCLDivIntOp(Backend *bn, std::string name, float data) : + Op(bn, std::move(name)), data_(data) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/div_int.cl"; + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + + cl_int err; + kernel_fp32_buffer_ = clCreateKernel(program, "div_int_scalar_float", &err); + check_cl_error(err, "clCreateKernel for div_int_scalar_float"); + kernel_fp32_image_ = clCreateKernel(program, "div_int_scalar_float_image2d", &err); + check_cl_error(err, "clCreateKernel for div_int_scalar_float_image2d"); + + // Load vectorized kernel + kernel_fp16_buffer_ = clCreateKernel(program, "div_int_scalar_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for div_int_scalar_fp16_vector"); + + // Load image kernel + kernel_fp16_image_ = clCreateKernel(program, "div_int_scalar_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for div_int_scalar_fp16_image2d"); + + // ADDED: Load the new scalar kernel + kernel_fp16_buffer_scalar_ = clCreateKernel(program, "div_int_scalar_fp16", &err); + check_cl_error(err, "clCreateKernel for div_int_scalar_fp16"); + + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +OpenCLDivIntOp::~OpenCLDivIntOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (kernel_fp16_buffer_scalar_) clReleaseKernel(kernel_fp16_buffer_scalar_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLDivIntOp::reshape(vector> inputs, vector> outputs) { + outputs[0]->setCtype(inputs[0]->ctype()); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLDivIntOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + auto output = outputs[0]; + output->setDtype(inputs[0]->dtype()); + auto &out_mem = output->device_memory(); + if (output->dimension() % 4 == 0 && false) { + out_mem.type = MEM_TYPE_IMAGE_2D; + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + out_mem.type = MEM_TYPE_BUFFER; + } + output->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLDivIntOp::execute(vector> inputs, vector> outputs) { + auto input_dtype = inputs[0]->dtype(); + auto output = outputs[0]; + + if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_image_ : kernel_fp16_image_; + std::vector temp_tensor_storage; + cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); + cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); + clSetKernelArg(kernel_to_use, 2, sizeof(float), &data_); + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } else { // Buffer Path + cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + size_t count = inputs[0]->count(); + + cl_kernel kernel_to_use; + size_t global_work_size[1]; + + if (input_dtype == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_buffer_; + global_work_size[0] = count; + } else { // MLLM_TYPE_F16 + if (count % 4 == 0) { + // Use the fast, vectorized kernel for aligned data + kernel_to_use = kernel_fp16_buffer_; + global_work_size[0] = count / 4; + } else { + // Use the robust, scalar kernel for non-aligned data + kernel_to_use = kernel_fp16_buffer_scalar_; + global_work_size[0] = count; + } + } + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(float), &data_); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLDivIntOp.hpp b/src/backends/opencl/op/OpenCLDivIntOp.hpp new file mode 100644 index 000000000..ce2065c3d --- /dev/null +++ b/src/backends/opencl/op/OpenCLDivIntOp.hpp @@ -0,0 +1,41 @@ +#ifndef OPENCL_DIV_INT_OP_HPP +#define OPENCL_DIV_INT_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLDivIntOp : public Op { +public: + OpenCLDivIntOp(Backend *bn, std::string name, float data); + ~OpenCLDivIntOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + float data_; // 用于存储要除的标量 + + cl_kernel kernel_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp16_buffer_ = nullptr; // Vectorized version + cl_kernel kernel_fp16_image_ = nullptr; + cl_kernel kernel_fp16_buffer_scalar_ = nullptr; // ADDED: Scalar (element-wise) version + + cl_sampler sampler_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLDivIntOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + float data = op_param["data"]; + return new OpenCLDivIntOp(bn, name, data); + } +}; + +} // namespace mllm + +#endif // OPENCL_DIV_INT_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLDivOp.cpp b/src/backends/opencl/op/OpenCLDivOp.cpp new file mode 100644 index 000000000..d26b81d41 --- /dev/null +++ b/src/backends/opencl/op/OpenCLDivOp.cpp @@ -0,0 +1,116 @@ +#include "OpenCLDivOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" + +namespace mllm { + +OpenCLDivOp::OpenCLDivOp(Backend *bn, std::string name, float data) : + Op(bn, std::move(name)), data_(data) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/div.cl"; + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + + cl_int err; + kernel_fp32_buffer_ = clCreateKernel(program, "div_scalar_float", &err); + check_cl_error(err, "clCreateKernel for div_scalar_float"); + kernel_fp32_image_ = clCreateKernel(program, "div_scalar_float_image2d", &err); + check_cl_error(err, "clCreateKernel for div_scalar_float_image2d"); + kernel_fp16_buffer_ = clCreateKernel(program, "div_scalar_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for div_scalar_fp16_vector"); + kernel_fp16_image_ = clCreateKernel(program, "div_scalar_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for div_scalar_fp16_image2d"); + + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +OpenCLDivOp::~OpenCLDivOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLDivOp::reshape(vector> inputs, vector> outputs) { + outputs[0]->setCtype(inputs[0]->ctype()); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLDivOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + auto output = outputs[0]; + output->setDtype(inputs[0]->dtype()); + auto &out_mem = output->device_memory(); + if (output->dimension() % 4 == 0 && false) { + out_mem.type = MEM_TYPE_IMAGE_2D; + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + out_mem.type = MEM_TYPE_BUFFER; + } + output->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLDivOp::execute(vector> inputs, vector> outputs) { + auto input_dtype = inputs[0]->dtype(); + auto output = outputs[0]; + + if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_image_ : kernel_fp16_image_; + std::vector temp_tensor_storage; + cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); + cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); + clSetKernelArg(kernel_to_use, 2, sizeof(float), &data_); + // if (input_dtype == MLLM_TYPE_F32) { + // clSetKernelArg(kernel_to_use, 2, sizeof(float), &data_); + // } else { + // mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(data_); + // clSetKernelArg(kernel_to_use, 2, sizeof(mllm_fp16_t), &data_fp16); + // } + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } else { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_buffer_ : kernel_fp16_buffer_; + cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(float), &data_); + // if (input_dtype == MLLM_TYPE_F32) { + // clSetKernelArg(kernel_to_use, 1, sizeof(float), &data_); + // } else { + // mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(data_); + // clSetKernelArg(kernel_to_use, 1, sizeof(mllm_fp16_t), &data_fp16); + // } + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + + size_t count = inputs[0]->count(); + if (input_dtype == MLLM_TYPE_F16) { count /= 4; } + + const size_t global_work_size[1] = {count}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLDivOp.hpp b/src/backends/opencl/op/OpenCLDivOp.hpp new file mode 100644 index 000000000..0b59a8be7 --- /dev/null +++ b/src/backends/opencl/op/OpenCLDivOp.hpp @@ -0,0 +1,40 @@ +#ifndef OPENCL_DIV_OP_HPP +#define OPENCL_DIV_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLDivOp : public Op { +public: + OpenCLDivOp(Backend *bn, std::string name, float data); + ~OpenCLDivOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + float data_; // 用于存储要除的标量 + + cl_kernel kernel_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp16_buffer_ = nullptr; + cl_kernel kernel_fp16_image_ = nullptr; + + cl_sampler sampler_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLDivOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + float data = op_param["data"]; + return new OpenCLDivOp(bn, name, data); + } +}; + +} // namespace mllm + +#endif // OPENCL_DIV_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLDivTwoOp.cpp b/src/backends/opencl/op/OpenCLDivTwoOp.cpp new file mode 100644 index 000000000..a967dc168 --- /dev/null +++ b/src/backends/opencl/op/OpenCLDivTwoOp.cpp @@ -0,0 +1,131 @@ +#include "OpenCLDivTwoOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLDivTwoOp::OpenCLDivTwoOp(Backend *bn, std::string name) : + Op(bn, std::move(name)) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/div.cl"; + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + + cl_int err; + kernel_fp32_buffer_ = clCreateKernel(program, "div_float", &err); + check_cl_error(err, "clCreateKernel for div_float"); + kernel_fp32_image_ = clCreateKernel(program, "div_float_image2d", &err); + check_cl_error(err, "clCreateKernel for div_float_image2d"); + + // Kernel for vectorized FP16 (count must be multiple of 4) + kernel_fp16_buffer_ = clCreateKernel(program, "div_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for div_fp16_vector"); + + // Kernel for scalar FP16 (handles any count) + kernel_fp16_scalar_ = clCreateKernel(program, "div_fp16_scalar", &err); + check_cl_error(err, "clCreateKernel for div_fp16_scalar"); + + kernel_fp16_image_ = clCreateKernel(program, "div_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for div_fp16_image2d"); + + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +OpenCLDivTwoOp::~OpenCLDivTwoOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_scalar_) clReleaseKernel(kernel_fp16_scalar_); // Release new kernel + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLDivTwoOp::reshape(vector> inputs, vector> outputs) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLDivTwoOp::setUp(vector> inputs, vector> outputs) { + for (auto &input : inputs) { + input->to(MLLM_OPENCL); + } + auto output = outputs[0]; + output->setDtype(inputs[0]->dtype()); + auto &out_mem = output->device_memory(); + if (output->dimension() % 4 == 0 && false) { + out_mem.type = MEM_TYPE_IMAGE_2D; + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + out_mem.type = MEM_TYPE_BUFFER; + } + output->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLDivTwoOp::execute(vector> inputs, vector> outputs) { + auto input_dtype = inputs[0]->dtype(); + auto output = outputs[0]; + + if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_image_ : kernel_fp16_image_; + std::vector temp_tensor_storage; + cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); + cl_mem inB_mem = get_image_from_tensor(inputs[1], ocl_backend_, temp_tensor_storage); + cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &inB_mem); + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } else { + // === MODIFIED LOGIC FOR BUFFER-BASED EXECUTION === + cl_kernel kernel_to_use; + size_t count = inputs[0]->count(); + size_t global_work_size[1]; + + if (input_dtype == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_buffer_; + global_work_size[0] = count; + } else { // MLLM_TYPE_F16 + if (count % 4 == 0) { + // Use the fast vectorized kernel if count is a multiple of 4 + kernel_to_use = kernel_fp16_buffer_; + global_work_size[0] = count / 4; + } else { + // Use the robust scalar kernel for other cases + kernel_to_use = kernel_fp16_scalar_; + global_work_size[0] = count; + } + } + + cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); + cl_mem in1_buf = ocl_backend_->get_cl_mem(*inputs[1]); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &in1_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + const int b_dim = inputs[1]->dimension(); + const int a_dim = inputs[0]->dimension(); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &b_dim); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &a_dim); + + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLDivTwoOp.hpp b/src/backends/opencl/op/OpenCLDivTwoOp.hpp new file mode 100644 index 000000000..7695a5607 --- /dev/null +++ b/src/backends/opencl/op/OpenCLDivTwoOp.hpp @@ -0,0 +1,38 @@ +#ifndef OPENCL_DIV_TWO_OP_HPP +#define OPENCL_DIV_TWO_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLDivTwoOp : public Op { +public: + OpenCLDivTwoOp(Backend *bn, std::string name); + ~OpenCLDivTwoOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + cl_kernel kernel_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp16_buffer_ = nullptr; // Note: this kernel is "div_fp16_vector" + cl_kernel kernel_fp16_scalar_ = nullptr; // Added for non-multiple-of-4 cases + cl_kernel kernel_fp16_image_ = nullptr; + + cl_sampler sampler_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLDivTwoOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new OpenCLDivTwoOp(bn, name); + } +}; + +} // namespace mllm + +#endif // OPENCL_DIV_TWO_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLEmbeddingOp.cpp b/src/backends/opencl/op/OpenCLEmbeddingOp.cpp new file mode 100644 index 000000000..9d0c48fc6 --- /dev/null +++ b/src/backends/opencl/op/OpenCLEmbeddingOp.cpp @@ -0,0 +1,119 @@ +#include "OpenCLEmbeddingOp.hpp" +#include "Types.hpp" +// #include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLEmbeddingOp::OpenCLEmbeddingOp(Backend *bn, std::string name, int vocab_size, int hidden_size) : + Op(bn, std::move(name)), vocab_size_(vocab_size), hidden_size_(hidden_size) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/embedding.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + kernel_fp32_ = clCreateKernel(program, "embedding_fp32", &err); + check_cl_error(err, "clCreateKernel for embedding_fp32"); + + kernel_q4_0_ = clCreateKernel(program, "embedding_q4_0", &err); + check_cl_error(err, "clCreateKernel for embedding_q4_0"); + + kernel_q4_0_fp16_ = clCreateKernel(program, "embedding_q4_0_fp16", &err); + check_cl_error(err, "clCreateKernel for embedding_q4_0_fp16"); +} + +OpenCLEmbeddingOp::~OpenCLEmbeddingOp() { + if (kernel_fp32_) clReleaseKernel(kernel_fp32_); + if (kernel_q4_0_) clReleaseKernel(kernel_q4_0_); + if (kernel_q4_0_fp16_) clReleaseKernel(kernel_q4_0_fp16_); +} + +ErrorCode OpenCLEmbeddingOp::reshape(vector> inputs, vector> outputs) { + // 输出张量的形状是 [B, H, S, D],其中 D 是 hidden_size + // 注意:Embedding通常不关心H,这里假设H=1 + outputs[0]->reshape(inputs[0]->batch(), 1, inputs[0]->sequence(), hidden_size_); + // Embedding的输出总是FP32 + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLEmbeddingOp::load(AbstructLoader &loader) { + weight_.setBackend(Backend::global_backends[MLLM_CPU].get()); + // 从模型文件中加载权重 + weight_.setName(name() + ".weight"); + // 权重的形状是 [vocab_size, hidden_size],我们用 BHSD 来模拟 [1, 1, vocab_size, hidden_size] + weight_.reshape(1, 1, vocab_size_, hidden_size_); + + if (loader.getDataType(weight_.name()) != MLLM_TYPE_COUNT) { + weight_.setDtype(loader.getDataType(weight_.name())); + weight_.alloc(); + loader.load(&weight_); + } else { + // 如果模型文件中没有,可能需要一个默认的空权重 + weight_.setDtype(MLLM_TYPE_F32); + weight_.alloc(); + } + weight_.to(MLLM_OPENCL); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLEmbeddingOp::free(vector> inputs, vector> outputs) { + weight_.free(); + return Op::free(inputs, outputs); +} + +ErrorCode OpenCLEmbeddingOp::setUp(vector> inputs, vector> outputs) { + // 确保所有张量都在OpenCL设备上 + inputs[0]->to(MLLM_OPENCL); // input_ids + // 输出总是 FP32 + outputs[0]->to(MLLM_OPENCL); + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLEmbeddingOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; // (B, 1, S, 1) or (B, S) - + auto output = outputs[0]; // (B, 1, S, D) + + cl_kernel kernel_to_use = nullptr; + if (weight_.dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_; + } else if (weight_.dtype() == MLLM_TYPE_Q4_0) { + if (output->dtype() == MLLM_TYPE_F16) { + kernel_to_use = kernel_q4_0_fp16_; // 调用新的FP16输出内核 + } else { + kernel_to_use = kernel_q4_0_; // 保留对FP32输出的兼容 + } + } else { + return NOT_SUPPORT; + } + + cl_mem in_id_buf = ocl_backend_->get_cl_mem(*input); + cl_mem weight_buf = ocl_backend_->get_cl_mem(weight_); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + // input tensor (token_ids) is usually flat, e.g. (B*S) + const int sequence_len = input->batch() * input->sequence(); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in_id_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &weight_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &vocab_size_); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &hidden_size_); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &sequence_len); + + // 启动2D内核: + // - 维度0 (X): 对应 hidden_size,每个工作项负责拷贝一个维度 + // - 维度1 (Y): 对应 token 数量 (B*S),每个工作项负责处理一个 token + const size_t global_work_size[2] = {(size_t)hidden_size_, (size_t)sequence_len}; + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "clEnqueueNDRangeKernel for Embedding"); + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLEmbeddingOp.hpp b/src/backends/opencl/op/OpenCLEmbeddingOp.hpp new file mode 100644 index 000000000..16f4854d1 --- /dev/null +++ b/src/backends/opencl/op/OpenCLEmbeddingOp.hpp @@ -0,0 +1,43 @@ +#ifndef OPENCL_EMBEDDING_OP_HPP +#define OPENCL_EMBEDDING_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLEmbeddingOp : public Op { +public: + OpenCLEmbeddingOp(Backend *bn, std::string name, int vocab_size, int hidden_size); + ~OpenCLEmbeddingOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode load(AbstructLoader &loader) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + ErrorCode free(vector> inputs, vector> outputs) override; + +private: + int vocab_size_; + int hidden_size_; + Tensor weight_; + + cl_kernel kernel_fp32_ = nullptr; + cl_kernel kernel_q4_0_ = nullptr; + cl_kernel kernel_q4_0_fp16_ = nullptr; + + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLEmbeddingOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + int vocab_size = op_param["vocab_size"]; + int hidden_size = op_param["hidden_size"]; + return new OpenCLEmbeddingOp(bn, name, vocab_size, hidden_size); + } +}; + +} // namespace mllm + +#endif // OPENCL_EMBEDDING_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLFlashAttentionOp.cpp b/src/backends/opencl/op/OpenCLFlashAttentionOp.cpp new file mode 100644 index 000000000..b36fffe32 --- /dev/null +++ b/src/backends/opencl/op/OpenCLFlashAttentionOp.cpp @@ -0,0 +1,279 @@ +#include "OpenCLFlashAttentionOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" + +// 宏定义现在只控制Tile的行列数和工作组大小 +#define Br 8 +#define Bc 8 +#define WGS_S 8 +#define WGS_D 8 +// 定义一个与内核中 LOCAL_MEM_SIZE 计算逻辑相关的维度上限 +#define DIM_MAX 128 +// 定义工作组大小,必须与内核中的WGS一致 +#define WGS 128 + +namespace mllm { + +OpenCLFlashAttentionOp::OpenCLFlashAttentionOp(Backend *bn, std::string name, bool causal_mask) : + Op(bn, std::move(name)), causal_mask_(causal_mask) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/flash_attention.cl"; + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + + cl_int err; + kernel_fp32_ = clCreateKernel(program, "flash_attention_2_prefill_fp32", &err); + check_cl_error(err, "clCreateKernel for flash_attention_2_prefill_fp32"); + + kernel_fp32_decode_ = clCreateKernel(program, "flash_attention_2_decode_fp32", &err); + check_cl_error(err, "clCreateKernel for flash_attention_2_decode_fp32"); + + kernel_fp16_ = clCreateKernel(program, "flash_attention_2_prefill_fp16", &err); + check_cl_error(err, "clCreateKernel for flash_attention_2_prefill_fp16"); + + kernel_fp16_decode_ = clCreateKernel(program, "flash_attention_2_decode_fp16", &err); + check_cl_error(err, "clCreateKernel for flash_attention_2_decode_fp16"); + + kernel_fp32_image_ = clCreateKernel(program, "flash_attention_2_prefill_fp32_image", &err); + check_cl_error(err, "clCreateKernel for flash_attention_2_prefill_fp32_image"); + kernel_fp32_decode_image_ = clCreateKernel(program, "flash_attention_2_decode_fp32_image", &err); + check_cl_error(err, "clCreateKernel for flash_attention_2_decode_fp32_image"); + kernel_fp16_image_ = clCreateKernel(program, "flash_attention_2_prefill_fp16_image", &err); + check_cl_error(err, "clCreateKernel for flash_attention_2_prefill_fp16_image"); + kernel_fp16_decode_image_ = clCreateKernel(program, "flash_attention_2_decode_fp16_image", &err); + check_cl_error(err, "clCreateKernel for flash_attention_2_decode_fp16_image"); + + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler for FlashAttention"); +} + +OpenCLFlashAttentionOp::~OpenCLFlashAttentionOp() { + if (kernel_fp32_) clReleaseKernel(kernel_fp32_); + if (kernel_fp32_decode_) clReleaseKernel(kernel_fp32_decode_); + if (kernel_fp16_) clReleaseKernel(kernel_fp16_); + if (kernel_fp16_decode_) clReleaseKernel(kernel_fp16_decode_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp32_decode_image_) clReleaseKernel(kernel_fp32_decode_image_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (kernel_fp16_decode_image_) clReleaseKernel(kernel_fp16_decode_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLFlashAttentionOp::reshape(vector> inputs, vector> outputs) { + auto q_tensor = inputs[0]; + auto o_tensor = outputs[0]; + o_tensor->reshape(q_tensor->batch(), q_tensor->head(), q_tensor->sequence(), q_tensor->dimension()); + o_tensor->setDtype(q_tensor->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLFlashAttentionOp::setUp(vector> inputs, vector> outputs) { + for (auto &input : inputs) { + input->to(MLLM_OPENCL); + } + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->to(MLLM_OPENCL); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLFlashAttentionOp::execute(vector> inputs, vector> outputs) { + auto q_tensor = inputs[0]; + auto k_tensor = inputs[1]; + auto v_tensor = inputs[2]; + auto o_tensor = outputs[0]; + + const auto data_type = q_tensor->dtype(); + + const int dim_size = q_tensor->dimension(); + + if (dim_size > DIM_MAX) { + throw std::runtime_error("FlashAttention Error: Tensor dimension size (" + std::to_string(dim_size) + ") exceeds kernel's compiled limit (DIM_MAX=" + std::to_string(DIM_MAX) + ")."); + } + + cl_mem q_buf = ocl_backend_->get_cl_mem(*q_tensor); + cl_mem k_buf = ocl_backend_->get_cl_mem(*k_tensor); + cl_mem v_buf = ocl_backend_->get_cl_mem(*v_tensor); + cl_mem o_buf = ocl_backend_->get_cl_mem(*o_tensor); + + const int batch_size = q_tensor->batch(); + const int q_head_size = q_tensor->head(); + const int kv_head_size = k_tensor->head(); + const int seq_size_q = q_tensor->sequence(); + const int seq_size_k = k_tensor->sequence(); + + int causal_mask_int = causal_mask_ ? 1 : 0; + if (seq_size_q == 1) { + causal_mask_int = 0; + } + // 2. 决策:是否使用全 Image 优化路径 + +#if !defined(__APPLE__) || !defined(__aarch64__) + bool use_image_path = (seq_size_q > 1) && (q_tensor->dimension() % 4 == 0) && (k_tensor->dimension() % 4 == 0) && (v_tensor->dimension() % 4 == 0) && (o_tensor->dimension() % 4 == 0); +#else + bool use_image_path = false; +#endif + + // bool use_image_path = false; + if (use_image_path) { + // a. 将所有相关张量原地转换为 Image + tensorGlobal2Image(*q_tensor); + tensorGlobal2Image(*k_tensor); + tensorGlobal2Image(*v_tensor); + tensorGlobal2Image(*o_tensor); + cl_mem q_img = ocl_backend_->get_cl_mem(*q_tensor); + cl_mem k_img = ocl_backend_->get_cl_mem(*k_tensor); + cl_mem v_img = ocl_backend_->get_cl_mem(*v_tensor); + cl_mem o_img = ocl_backend_->get_cl_mem(*o_tensor); + cl_kernel kernel_to_use = nullptr; + cl_event event; + cl_int err; + if (seq_size_q == 1) { // Decode 阶段 (GEMV-like) + if (data_type == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_decode_image_; + } else { // MLLM_TYPE_F16 + kernel_to_use = kernel_fp16_decode_image_; + } + int arg_idx = 0; + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &q_img); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &k_img); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &v_img); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &o_img); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &q_head_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &kv_head_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &seq_size_k); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &dim_size); + const size_t global_work_size[2] = { + o_tensor->device_memory().image_width, // N / 4 + o_tensor->device_memory().image_height // B * H + }; + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "flash_attention2_decode_image", event); + check_cl_error(err, "clEnqueueNDRangeKernel for FlashAttention Decode Image"); + } else { // Prefill 阶段 (GEMM-like) + if (data_type == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_image_; + } else { // MLLM_TYPE_F16 + kernel_to_use = kernel_fp16_image_; + } + int arg_idx = 0; + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &q_img); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &k_img); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &v_img); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &o_img); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &q_head_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &kv_head_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &seq_size_q); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &seq_size_k); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &dim_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &causal_mask_int); + const size_t local_work_size[1] = {WGS}; + const size_t num_output_rows = batch_size * q_head_size * seq_size_q; + const size_t global_work_size[1] = {num_output_rows * WGS}; + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "flash_attention2_prefill_image", event); + check_cl_error(err, "clEnqueueNDRangeKernel for FlashAttention Prefill Image"); + } + + // d. 将所有张量转换回 Buffer 以便后续操作 + tensorImage2Global(*q_tensor); + tensorImage2Global(*k_tensor); + tensorImage2Global(*v_tensor); + tensorImage2Global(*o_tensor); + } else { + if (data_type == MLLM_TYPE_F32 && seq_size_q == 1) { // Decode 阶段 - FP32 + cl_kernel kernel = kernel_fp32_decode_; + clSetKernelArg(kernel, 0, sizeof(cl_mem), &q_buf); + clSetKernelArg(kernel, 1, sizeof(cl_mem), &k_buf); + clSetKernelArg(kernel, 2, sizeof(cl_mem), &v_buf); + clSetKernelArg(kernel, 3, sizeof(cl_mem), &o_buf); + clSetKernelArg(kernel, 4, sizeof(int), &q_head_size); + clSetKernelArg(kernel, 5, sizeof(int), &kv_head_size); + clSetKernelArg(kernel, 6, sizeof(int), &seq_size_k); + clSetKernelArg(kernel, 7, sizeof(int), &dim_size); + const size_t local_work_size[3] = {WGS, 1, 1}; + const size_t num_output_rows = batch_size * q_head_size; + size_t global_work_size[3] = {num_output_rows * WGS, 1, 1}; + cl_event event; + cl_int err = clEnqueueNDRangeKernel( + ocl_backend_->getQueue(), kernel, 1, nullptr, + global_work_size, local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "flash_attention2", event); + check_cl_error(err, "clEnqueueNDRangeKernel for FlashAttention Decode"); + } else if (data_type == MLLM_TYPE_F32) { // Prefill 阶段 - FP32 + cl_kernel kernel = kernel_fp32_; + clSetKernelArg(kernel, 0, sizeof(cl_mem), &q_buf); + clSetKernelArg(kernel, 1, sizeof(cl_mem), &k_buf); + clSetKernelArg(kernel, 2, sizeof(cl_mem), &v_buf); + clSetKernelArg(kernel, 3, sizeof(cl_mem), &o_buf); + clSetKernelArg(kernel, 4, sizeof(int), &q_head_size); + clSetKernelArg(kernel, 5, sizeof(int), &kv_head_size); + clSetKernelArg(kernel, 6, sizeof(int), &seq_size_q); + clSetKernelArg(kernel, 7, sizeof(int), &seq_size_k); + clSetKernelArg(kernel, 8, sizeof(int), &dim_size); + clSetKernelArg(kernel, 9, sizeof(int), &causal_mask_int); + const size_t local_work_size[3] = {WGS, 1, 1}; + const size_t num_output_rows = batch_size * q_head_size * seq_size_q; + size_t global_work_size[3] = {num_output_rows * WGS, 1, 1}; + cl_event event; + cl_int err = clEnqueueNDRangeKernel( + ocl_backend_->getQueue(), kernel, 1, nullptr, + global_work_size, local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "flash_attention2", event); + check_cl_error(err, "clEnqueueNDRangeKernel for FlashAttention V2"); + } else if (data_type == MLLM_TYPE_F16 && seq_size_q == 1) { // Decode 阶段 - FP16 + cl_kernel kernel = kernel_fp16_decode_; + clSetKernelArg(kernel, 0, sizeof(cl_mem), &q_buf); + clSetKernelArg(kernel, 1, sizeof(cl_mem), &k_buf); + clSetKernelArg(kernel, 2, sizeof(cl_mem), &v_buf); + clSetKernelArg(kernel, 3, sizeof(cl_mem), &o_buf); + clSetKernelArg(kernel, 4, sizeof(int), &q_head_size); + clSetKernelArg(kernel, 5, sizeof(int), &kv_head_size); + clSetKernelArg(kernel, 6, sizeof(int), &seq_size_k); + clSetKernelArg(kernel, 7, sizeof(int), &dim_size); + const size_t local_work_size[3] = {WGS, 1, 1}; + const size_t num_output_rows = batch_size * q_head_size; + size_t global_work_size[3] = {num_output_rows * WGS, 1, 1}; + cl_event event; + cl_int err = clEnqueueNDRangeKernel( + ocl_backend_->getQueue(), kernel, 1, nullptr, + global_work_size, local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "flash_attention2_fp16_decode", event); + check_cl_error(err, "clEnqueueNDRangeKernel for FlashAttention Decode FP16"); + } else if (data_type == MLLM_TYPE_F16) { // Prefill 阶段 - FP16 + cl_kernel kernel = kernel_fp16_; + clSetKernelArg(kernel, 0, sizeof(cl_mem), &q_buf); + clSetKernelArg(kernel, 1, sizeof(cl_mem), &k_buf); + clSetKernelArg(kernel, 2, sizeof(cl_mem), &v_buf); + clSetKernelArg(kernel, 3, sizeof(cl_mem), &o_buf); + clSetKernelArg(kernel, 4, sizeof(int), &q_head_size); + clSetKernelArg(kernel, 5, sizeof(int), &kv_head_size); + clSetKernelArg(kernel, 6, sizeof(int), &seq_size_q); + clSetKernelArg(kernel, 7, sizeof(int), &seq_size_k); + clSetKernelArg(kernel, 8, sizeof(int), &dim_size); + clSetKernelArg(kernel, 9, sizeof(int), &causal_mask_int); + const size_t local_work_size[3] = {WGS, 1, 1}; + const size_t num_output_rows = batch_size * q_head_size * seq_size_q; + size_t global_work_size[3] = {num_output_rows * WGS, 1, 1}; + cl_event event; + cl_int err = clEnqueueNDRangeKernel( + ocl_backend_->getQueue(), kernel, 1, nullptr, + global_work_size, local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "flash_attention2_fp16", event); + check_cl_error(err, "clEnqueueNDRangeKernel for FlashAttention V2 FP16"); + + } else { + return NOT_SUPPORT; + } + } + + return MLLM_NO_ERROR; +} +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLFlashAttentionOp.hpp b/src/backends/opencl/op/OpenCLFlashAttentionOp.hpp new file mode 100644 index 000000000..185258506 --- /dev/null +++ b/src/backends/opencl/op/OpenCLFlashAttentionOp.hpp @@ -0,0 +1,43 @@ +#ifndef OPENCL_FLASHATTENTION_OP_HPP +#define OPENCL_FLASHATTENTION_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLFlashAttentionOp : public Op { +public: + OpenCLFlashAttentionOp(Backend *bn, std::string name, bool causal_mask); + ~OpenCLFlashAttentionOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + bool causal_mask_; + cl_kernel kernel_fp32_ = nullptr; + cl_kernel kernel_fp32_decode_ = nullptr; + cl_kernel kernel_fp16_ = nullptr; + cl_kernel kernel_fp16_decode_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; + + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp32_decode_image_ = nullptr; + cl_kernel kernel_fp16_image_ = nullptr; + cl_kernel kernel_fp16_decode_image_ = nullptr; + cl_sampler sampler_ = nullptr; +}; + +class OpenCLFlashAttentionOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + bool causal_mask = (bool)op_param.at("causal_mask"); + return new OpenCLFlashAttentionOp(bn, name, causal_mask); + } +}; + +} // namespace mllm + +#endif // OPENCL_FLASHATTENTION_OP_HPP diff --git a/src/backends/opencl/op/OpenCLKVCacheOp.cpp b/src/backends/opencl/op/OpenCLKVCacheOp.cpp new file mode 100644 index 000000000..4acc1a476 --- /dev/null +++ b/src/backends/opencl/op/OpenCLKVCacheOp.cpp @@ -0,0 +1,170 @@ +// 文件: OpenCLKVCacheOp.cpp + +#include "OpenCLKVCacheOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLKVCacheOp::OpenCLKVCacheOp(Backend *bn, std::string name, int hidden, int head, int n_rep, bool fa2, int cache_max) : + Op(bn, std::move(name)), hidden_(hidden), head_(head), n_rep_(n_rep), cache_limit_(cache_max), fa2_(fa2) { + if (fa2_) { + n_rep_ = 1; // Flash Attention 2 does not use n_rep + } + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + cache_ = std::make_shared(bn); + cache_->setName(name + ".Cache"); + const int KVCache_batch = 1; + cache_->reshape(KVCache_batch, head_ * n_rep_, cache_limit_, hidden_); + cache_->setDtype(MLLM_TYPE_F32); + cache_->alloc(); + cache_->cl(); + + const std::string kernel_path = "kernel/kvcache.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + // Load BSHD kernels + kernel_fp32_bshd_ = clCreateKernel(program, "update_kv_cache_fp32_bshd", &err); + check_cl_error(err, "clCreateKernel for update_kv_cache_fp32_bshd"); + kernel_fp16_bshd_ = clCreateKernel(program, "update_kv_cache_fp16_bshd", &err); + check_cl_error(err, "clCreateKernel for update_kv_cache_fp16_bshd"); + + // Load BHSD kernels + kernel_fp32_bhsd_ = clCreateKernel(program, "update_kv_cache_fp32_bhsd", &err); + check_cl_error(err, "clCreateKernel for update_kv_cache_fp32_bhsd"); + kernel_fp16_bhsd_ = clCreateKernel(program, "update_kv_cache_fp16_bhsd", &err); + check_cl_error(err, "clCreateKernel for update_kv_cache_fp16_bhsd"); +} + +OpenCLKVCacheOp::~OpenCLKVCacheOp() { + if (kernel_fp32_bshd_) clReleaseKernel(kernel_fp32_bshd_); + if (kernel_fp16_bshd_) clReleaseKernel(kernel_fp16_bshd_); + if (kernel_fp32_bhsd_) clReleaseKernel(kernel_fp32_bhsd_); + if (kernel_fp16_bhsd_) clReleaseKernel(kernel_fp16_bhsd_); +} + +ErrorCode OpenCLKVCacheOp::reshape(vector> inputs, vector> outputs) { + outputs[0]->setCtype(inputs[0]->ctype()); + const int new_sequence_length = cache_seq_len_ + inputs[0]->sequence(); + outputs[0]->reshape(cache_->batch(), cache_->head(), new_sequence_length, cache_->dimension()); + outputs[0]->setDtype(cache_->dtype()); + if (inputs[0]->ctype() == BHSD && cache_->ctype() != inputs[0]->ctype()) { + // cache_->cpu(); + cache_->setCtype(BHSD); + cache_->reshape(cache_->batch(), head_ * n_rep_, cache_limit_, hidden_); + // cache_->alloc(); + // cache_->cl(); + } + if (cache_->dtype() != inputs[0]->dtype()) { + cache_->setDtype(inputs[0]->dtype()); + cache_->alloc(); + } + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLKVCacheOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + outputs[0]->setDtype(cache_->dtype()); + outputs[0]->alloc(); + + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLKVCacheOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + + if (cache_seq_len_ + input->sequence() > cache_limit_) { + std::cerr << "KVCache is full, cannot update." << std::endl; + return MLLM_NO_ERROR; // Cache is full + } + + cl_kernel kernel_to_use = nullptr; + auto ctype = input->ctype(); + + if (input->dtype() == MLLM_TYPE_F32) { + if (cache_->dtype() != MLLM_TYPE_F32) { /* Realloc logic for cache_ */ + } + if (ctype == BSHD) { + kernel_to_use = kernel_fp32_bshd_; + } else if (ctype == BHSD) { + kernel_to_use = kernel_fp32_bhsd_; + } + } else if (input->dtype() == MLLM_TYPE_F16) { + if (cache_->dtype() != MLLM_TYPE_F16) { /* Realloc logic for cache_ */ + } + if (ctype == BSHD) { + kernel_to_use = kernel_fp16_bshd_; + } else if (ctype == BHSD) { + kernel_to_use = kernel_fp16_bhsd_; + } + } + + cl_mem src_buf = ocl_backend_->get_cl_mem(*input); + cl_mem cache_buf = ocl_backend_->get_cl_mem(*cache_); + + const int h_in = input->head(); + const int s_in = input->sequence(); + const int d_in = input->dimension(); + const int h_cache = cache_->head(); + const int s_cache = cache_->sequence(); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &src_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &cache_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(int), &h_in); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &s_in); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &d_in); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &h_cache); + clSetKernelArg(kernel_to_use, 6, sizeof(int), &s_cache); + clSetKernelArg(kernel_to_use, 7, sizeof(int), &n_rep_); + clSetKernelArg(kernel_to_use, 8, sizeof(int), &cache_seq_len_); + + const size_t global_work_size[3] = {(size_t)d_in, (size_t)s_in, (size_t)h_in * n_rep_}; + + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + check_cl_error(err, "clEnqueueNDRangeKernel for KVCache Update"); + + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + if (ctype == BHSD) { + const size_t batch_size = output->batch(); + const size_t head_size = output->head(); + const size_t seq_len_out = output->sequence(); + const size_t dim_size = output->dimension(); + const size_t seq_len_cache = cache_->sequence(); // cache_limit + const size_t dtype_size = output->dtypeSize(); + for (size_t b = 0; b < batch_size; ++b) { + for (size_t h = 0; h < head_size; ++h) { + size_t src_offset_bytes = (b * head_size * seq_len_cache + h * seq_len_cache) * dim_size * dtype_size; + size_t dst_offset_bytes = (b * head_size * seq_len_out + h * seq_len_out) * dim_size * dtype_size; + size_t bytes_per_head = seq_len_out * dim_size * dtype_size; + cl_event event; + err = clEnqueueCopyBuffer( + ocl_backend_->getQueue(), + cache_buf, + out_buf, + src_offset_bytes, + dst_offset_bytes, + bytes_per_head, + 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "clEnqueueCopyBuffer for BHSD head"); + } + } + } else { + // 对于 BSHD 布局,可以直接进行线性复制 + size_t bytes_to_copy = output->count() * output->dtypeSize(); + cl_event event; + err = clEnqueueCopyBuffer(ocl_backend_->getQueue(), cache_buf, out_buf, 0, 0, bytes_to_copy, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "clEnqueueCopyBuffer from cache to output"); + } + + cache_seq_len_ += s_in; + + return MLLM_NO_ERROR; +} + +} // namespace mllm diff --git a/src/backends/opencl/op/OpenCLKVCacheOp.hpp b/src/backends/opencl/op/OpenCLKVCacheOp.hpp new file mode 100644 index 000000000..1267a82c8 --- /dev/null +++ b/src/backends/opencl/op/OpenCLKVCacheOp.hpp @@ -0,0 +1,60 @@ +#ifndef OPENCL_KVCACHE_OP_HPP +#define OPENCL_KVCACHE_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLKVCacheOp : public Op { +public: + OpenCLKVCacheOp(Backend *bn, std::string name, int hidden, int head, int n_rep, bool fa2, int cache_max); + ~OpenCLKVCacheOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + int getCacheSeqLen() override { + return cache_seq_len_; + } + void clearCache() override { + cache_seq_len_ = 0; + cache_->cache_seq_len_ = cache_seq_len_; + } + +private: + shared_ptr cache_; + int n_rep_; + int cache_limit_; + int cache_seq_len_ = 0; + int hidden_; + int head_; + bool fa2_; + + // Kernels for BSHD layout + cl_kernel kernel_fp32_bshd_ = nullptr; + cl_kernel kernel_fp16_bshd_ = nullptr; + + // Kernels for BHSD layout (New) + cl_kernel kernel_fp32_bhsd_ = nullptr; + cl_kernel kernel_fp16_bhsd_ = nullptr; + + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLKVCacheOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + int n_rep = (int)op_param["n_rep"]; + int cache_max = (int)op_param["cache_max"]; + bool for_xnn = (bool)op_param["for_xnn"]; + int hidden = (int)op_param["hidden"]; + int head = (int)op_param["head"]; + bool fa2 = (bool)op_param["fa2"]; + return new OpenCLKVCacheOp(bn, name, hidden, head, n_rep, fa2, cache_max); + } +}; + +} // namespace mllm + +#endif // OPENCL_KVCACHE_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLLikeOp.cpp b/src/backends/opencl/op/OpenCLLikeOp.cpp new file mode 100644 index 000000000..9da8ba797 --- /dev/null +++ b/src/backends/opencl/op/OpenCLLikeOp.cpp @@ -0,0 +1,60 @@ +#include "OpenCLLikeOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLLikeOp::OpenCLLikeOp(Backend *bn, std::string name, float like_value) : + Op(bn, std::move(name)), like_value_(like_value) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/like.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + // 内核将处理所有数据类型,但在内核内部进行转换 + kernel_ = clCreateKernel(program, "like", &err); + check_cl_error(err, "clCreateKernel for like"); +} + +OpenCLLikeOp::~OpenCLLikeOp() { + if (kernel_) clReleaseKernel(kernel_); +} + +ErrorCode OpenCLLikeOp::reshape(vector> inputs, vector> outputs) { + // 输出的形状和数据类型与输入完全一致 + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->to(MLLM_OPENCL); // 确保输出张量在OpenCL上 + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLLikeOp::setUp(vector> inputs, vector> outputs) { + // Like 操作不需要输入张量的数据,所以 inputs[0] 无需 to(MLLM_OPENCL) + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLLikeOp::execute(vector> inputs, vector> outputs) { + auto output = outputs[0]; + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + const int count = output->count(); + const int dtype_size = output->dtypeSize(); + + clSetKernelArg(kernel_, 0, sizeof(cl_mem), &out_buf); + clSetKernelArg(kernel_, 1, sizeof(float), &like_value_); + clSetKernelArg(kernel_, 2, sizeof(int), &count); + clSetKernelArg(kernel_, 3, sizeof(int), &dtype_size); + + const size_t global_work_size = (size_t)count; + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_, 1, nullptr, + &global_work_size, nullptr, 0, nullptr, &event); + check_cl_error(err, "clEnqueueNDRangeKernel for Like"); + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLLikeOp.hpp b/src/backends/opencl/op/OpenCLLikeOp.hpp new file mode 100644 index 000000000..66d8a727c --- /dev/null +++ b/src/backends/opencl/op/OpenCLLikeOp.hpp @@ -0,0 +1,35 @@ +#ifndef OPENCL_LIKE_OP_HPP +#define OPENCL_LIKE_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLLikeOp : public Op { +public: + OpenCLLikeOp(Backend *bn, std::string name, float like_value); + ~OpenCLLikeOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + float like_value_; + cl_kernel kernel_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLLikeOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // 从 op_param 中获取 "like_value" + float like_value = op_param.at("like_value"); + return new OpenCLLikeOp(bn, name, like_value); + } +}; + +} // namespace mllm + +#endif // OPENCL_LIKE_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLLinearOp.cpp b/src/backends/opencl/op/OpenCLLinearOp.cpp new file mode 100644 index 000000000..5d5eeae87 --- /dev/null +++ b/src/backends/opencl/op/OpenCLLinearOp.cpp @@ -0,0 +1,302 @@ +#include "OpenCLLinearOp.hpp" +#include "Backend.hpp" +#include "DataType.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +#include +// #include +#include +#include + +namespace mllm { + +OpenCLLinearOp::OpenCLLinearOp(Backend *bn, string opName, int in_features, int out_features, bool bias) : + Op(bn, opName), in_features_(in_features), out_features_(out_features), support_bias_(bias) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) { + throw std::runtime_error("Backend for OpenCLLinearOp is not OpenCLBackend"); + } + + const std::string kernel_path = "kernel/matmul_transb_bias.cl"; + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + cl_int err; + kernel_fp32_transb_bias_ = clCreateKernel(program, "gemm_fp32_transb_bias", &err); + check_cl_error(err, "CreateKernel gemm_fp32_transb_bias"); + kernel_fp16_transb_bias_ = clCreateKernel(program, "gemm_fp16_transb_bias", &err); + check_cl_error(err, "CreateKernel gemm_fp16_transb_bias"); + kernel_fp16_q4_0_transb_bias_ = clCreateKernel(program, "gemm_fp16_q4_0_transb_bias", &err); + check_cl_error(err, "CreateKernel gemm_fp16_q4_0_transb_bias"); + kernel_fp32_q4_0_transb_bias_ = clCreateKernel(program, "gemm_fp32_q4_0_transb_bias", &err); + check_cl_error(err, "CreateKernel gemm_fp32_q4_0_transb_bias"); + kernel_gemv_fp32_q4_0_transb_bias_ = clCreateKernel(program, "gemv_fp32_q4_0_transb_bias", &err); + check_cl_error(err, "CreateKernel gemv_fp32_q4_0_transb_bias"); + kernel_gemv_fp16_q4_0_transb_bias_ = clCreateKernel(program, "gemv_fp16_q4_0_transb_bias", &err); + check_cl_error(err, "CreateKernel gemv_fp16_q4_0_transb_bias"); + if (ocl_backend_->has_fp16_support()) { + kernel_gemv_fp16_q4_0_transb_bias_half16_ = clCreateKernel(program, "gemv_fp16_q4_0_transb_bias_half16", &err); + check_cl_error(err, "CreateKernel gemv_fp16_q4_0_transb_bias_half16"); + } + + kernel_fp32_q4_0_transb_bias_image2d_ = clCreateKernel(program, "gemm_fp32_q4_0_transb_bias_image_pipe", &err); + check_cl_error(err, "CreateKernel gemm_fp32_q4_0_transb_bias_image_pipe"); + kernel_fp16_q4_0_transb_bias_image2d_ = clCreateKernel(program, "gemm_fp16_q4_0_transb_bias_image_pipe", &err); + check_cl_error(err, "CreateKernel gemm_fp16_q4_0_transb_bias_image_pipe"); + kernel_gemv_fp32_q4_0_transb_bias_image2d_ = clCreateKernel(program, "gemv_fp32_q4_0_transb_bias_image_pipe", &err); + check_cl_error(err, "CreateKernel gemv_fp32_q4_0_transb_bias_image_pipe"); + kernel_gemv_fp16_q4_0_transb_bias_image2d_ = clCreateKernel(program, "gemv_fp16_q4_0_transb_bias_image_pipe", &err); + check_cl_error(err, "CreateKernel gemv_fp16_q4_0_transb_bias_image_pipe"); +} + +OpenCLLinearOp::~OpenCLLinearOp() { + if (kernel_fp32_transb_bias_) clReleaseKernel(kernel_fp32_transb_bias_); + if (kernel_fp16_transb_bias_) clReleaseKernel(kernel_fp16_transb_bias_); + if (kernel_fp32_q4_0_transb_bias_) clReleaseKernel(kernel_fp32_q4_0_transb_bias_); + if (kernel_fp16_q4_0_transb_bias_) clReleaseKernel(kernel_fp16_q4_0_transb_bias_); + if (kernel_gemv_fp32_q4_0_transb_bias_) clReleaseKernel(kernel_gemv_fp32_q4_0_transb_bias_); + if (kernel_gemv_fp16_q4_0_transb_bias_) clReleaseKernel(kernel_gemv_fp16_q4_0_transb_bias_); + if (kernel_gemv_fp16_q4_0_transb_bias_half16_) clReleaseKernel(kernel_gemv_fp16_q4_0_transb_bias_half16_); + if (kernel_fp32_q4_0_transb_bias_image2d_) clReleaseKernel(kernel_fp32_q4_0_transb_bias_image2d_); + if (kernel_fp16_q4_0_transb_bias_image2d_) clReleaseKernel(kernel_fp16_q4_0_transb_bias_image2d_); + if (kernel_gemv_fp32_q4_0_transb_bias_image2d_) clReleaseKernel(kernel_gemv_fp32_q4_0_transb_bias_image2d_); + if (kernel_gemv_fp16_q4_0_transb_bias_image2d_) clReleaseKernel(kernel_gemv_fp16_q4_0_transb_bias_image2d_); +} + +ErrorCode OpenCLLinearOp::reshape(vector> inputs, vector> outputs) { + assert(inputs.size() == 1); + assert(outputs.size() == 1); + + // Input: [batch, 1, seq_len, in_features] + // Output: [batch, 1, seq_len, out_features] + assert(inputs[0]->head() == 1); + assert(in_features_ == inputs[0]->dimension()); + + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), out_features_); + outputs[0]->setDtype(inputs[0]->dtype()); + // #if !defined(__APPLE__) || !defined(__aarch64__) + // const size_t max_image_width = ocl_backend_->getMaxImage2dWidth(); + // if (out_features_ % 4 == 0 && (out_features_ / 4) <= max_image_width) { // inputs[0]->sequence() == 1 && + // auto &out_mem = outputs[0]->device_memory(); + // out_mem.type = MEM_TYPE_IMAGE_2D; + // out_mem.image_width = out_features_ / 4; + // out_mem.image_height = inputs[0]->batch() * inputs[0]->head() * inputs[0]->sequence(); + // } + // #endif + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLLinearOp::load(AbstructLoader &loader) { + weight_.setName(name() + ".weight"); + weight_.setBackend(ocl_backend_); + weight_.reshape(1, 1, out_features_, in_features_); + weight_.setDtype(loader.getDataType(weight_.name())); + weight_.alloc(); + loader.load(&weight_); + // weight_.saveQ4Data_d(); + + if (support_bias_) { + bias_.setName(name() + ".bias"); + bias_.setBackend(ocl_backend_); + bias_.reshape(1, 1, 1, out_features_); + bias_.setDtype(loader.getDataType(bias_.name())); + bias_.alloc(); + loader.load(&bias_); + } + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLLinearOp::setUp(vector> inputs, vector> outputs) { + // Move all tensors to OpenCL device + inputs[0]->to(MLLM_OPENCL); + outputs[0]->to(MLLM_OPENCL); + // Allocate output memory + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} +ErrorCode OpenCLLinearOp::free(vector> inputs, vector> outputs) { + weight_.unload(); + if (support_bias_) { + bias_.unload(); + } + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLLinearOp::execute(vector> inputs, vector> outputs) { + auto &A = inputs[0]; + auto &W = weight_; + auto &C = outputs[0]; + + // 1. 选择 Matmul+Bias 内核 + cl_kernel kernel_to_use = nullptr; + // 2. 设置参数并执行 + const int M = C->sequence(); + const int K = A->dimension(); + const int N = C->dimension(); + const int B_size = A->batch(); + const int H_size = A->head(); + const int K_b = W.dimension(); + + cl_mem a_mem = ocl_backend_->get_cl_mem(*A); + cl_mem w_mem = ocl_backend_->get_cl_mem(W); + cl_mem c_mem = ocl_backend_->get_cl_mem(*C); + + cl_mem bias_mem_arg = support_bias_ ? ocl_backend_->get_cl_mem(bias_) : a_mem; // 使用 a_mem 作为哑参数 + const int has_bias_flag = support_bias_ ? 1 : 0; + cl_event event; + cl_int err; + + if (M == 1 && (A->dtype() == MLLM_TYPE_F32 || A->dtype() == MLLM_TYPE_F16) && W.dtype() == MLLM_TYPE_Q4_0) { + bool use_image_path_for_gemv = (A->dimension() % 4 == 0 && C->dimension() % 4 == 0) && (C->device_memory().type == MEM_TYPE_IMAGE_2D); + if (use_image_path_for_gemv) { + // --- GEMV All Image 路径 --- + tensorGlobal2Image(*A); + tensorGlobal2Image(*C); + cl_kernel kernel_to_use = nullptr; + if (A->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_gemv_fp32_q4_0_transb_bias_image2d_; + } else { // MLLM_TYPE_F16 + kernel_to_use = kernel_gemv_fp16_q4_0_transb_bias_image2d_; + } + cl_mem a_img_mem = ocl_backend_->get_cl_mem(*A); + cl_mem c_img_mem = ocl_backend_->get_cl_mem(*C); + cl_sampler sampler = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler for GEMV Image"); + int arg_idx = 0; + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_sampler), &sampler); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &a_img_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &w_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &bias_mem_arg); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &c_img_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &K); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &N); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &H_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &has_bias_flag); + const size_t global_work_size[2] = {(size_t)N / 4, 1}; // Width: N/4, Height: 1 + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "_gemv_image", event); + check_cl_error(err, "EnqueueNDRangeKernel GEMV Image"); + clReleaseSampler(sampler); + tensorImage2Global(*A); + tensorImage2Global(*C); + } else { + cl_kernel kernel_to_use = nullptr; + if (A->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_gemv_fp32_q4_0_transb_bias_; + } else { // MLLM_TYPE_F16 + kernel_to_use = kernel_gemv_fp16_q4_0_transb_bias_; + } + int arg_idx = 0; + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &a_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &w_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &bias_mem_arg); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &c_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &K); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &N); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &H_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &has_bias_flag); + if (ocl_backend_->has_fp16_support() && A->dtype() == MLLM_TYPE_F16) { + const size_t local_work_size[2] = {128, 1}; // 建议从128开始 + const size_t global_work_size[2] = {(size_t)N * local_work_size[0], (size_t)(B_size * H_size)}; + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, local_work_size, 0, nullptr, &event); + } else { + const size_t local_work_size[2] = {256, 1}; + const size_t global_work_size[2] = {(size_t)N * local_work_size[0], (size_t)(B_size * H_size)}; + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, local_work_size, 0, nullptr, &event); + } + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "EnqueueNDRangeKernel GEMV"); + } + } else if (C->device_memory().type == MEM_TYPE_IMAGE_2D) { + tensorGlobal2Image(*inputs[0]); + tensorGlobal2Image(*C); + cl_kernel kernel_to_use = nullptr; + if (A->dtype() == MLLM_TYPE_F32 && W.dtype() == MLLM_TYPE_Q4_0) { + kernel_to_use = kernel_fp32_q4_0_transb_bias_image2d_; + } else if (A->dtype() == MLLM_TYPE_F16 && W.dtype() == MLLM_TYPE_Q4_0) { + kernel_to_use = kernel_fp16_q4_0_transb_bias_image2d_; + } else { + throw std::runtime_error("Unsupported data types for OpenCLLinearOp Image Path."); + } + cl_mem a_img_mem = ocl_backend_->get_cl_mem(*A); + cl_mem c_img_mem = ocl_backend_->get_cl_mem(*C); + cl_sampler sampler = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler for LinearOp Image"); + int arg_idx = 0; + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_sampler), &sampler); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &a_img_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &w_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &bias_mem_arg); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &c_img_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &M); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &K); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &N); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &H_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &K_b); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &has_bias_flag); + const size_t global_work_size[2] = {(size_t)N / 4, (size_t)(B_size * H_size * M)}; + err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "_image", event); + check_cl_error(err, "EnqueueNDRangeKernel Image GEMM"); + clReleaseSampler(sampler); + tensorImage2Global(*C); + tensorImage2Global(*A); + } else { + if (A->dtype() == MLLM_TYPE_F32 && W.dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_transb_bias_; + } else if (A->dtype() == MLLM_TYPE_F16 && W.dtype() == MLLM_TYPE_F16) { + kernel_to_use = kernel_fp16_transb_bias_; + } else if (A->dtype() == MLLM_TYPE_F32 && W.dtype() == MLLM_TYPE_Q4_0) { + kernel_to_use = kernel_fp32_q4_0_transb_bias_; + } else if (A->dtype() == MLLM_TYPE_F16 && W.dtype() == MLLM_TYPE_Q4_0) { + kernel_to_use = kernel_fp16_q4_0_transb_bias_; + } else { + throw std::runtime_error("Unsupported data types for OpenCLLinearOp."); + } + int arg_idx = 0; + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &a_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &w_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &bias_mem_arg); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &c_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &M); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &K); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &N); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &H_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &K_b); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &has_bias_flag); + if (kernel_to_use == kernel_fp16_q4_0_transb_bias_ && ocl_backend_->has_fp16_support()) { + const size_t TILE_M = 64; + const size_t TILE_N = 64; + const size_t THREADS_X = 8; + const size_t THREADS_Y = 8; + const size_t global_work_size[3] = { + (size_t)ceil((float)N / TILE_N) * THREADS_X, + (size_t)ceil((float)M / TILE_M) * THREADS_Y, + (size_t)(B_size * H_size)}; + const size_t local_work_size[3] = {THREADS_X, THREADS_Y, 1}; + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, global_work_size, local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "_tiled_q4", event); + check_cl_error(err, "EnqueueNDRangeKernel tiled gemm_fp16_q4_0_transb_bias"); + + } else { + const size_t TILE_SIZE = 16; + const size_t global_work_size[3] = { + (size_t)(((N + TILE_SIZE - 1) / TILE_SIZE) * TILE_SIZE), + (size_t)(((M + TILE_SIZE - 1) / TILE_SIZE) * TILE_SIZE), + (size_t)(B_size * H_size)}; + const size_t local_work_size[3] = {TILE_SIZE, TILE_SIZE, 1}; + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, global_work_size, local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "EnqueueNDRangeKernel fused matmul_bias"); + } + } + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLLinearOp.hpp b/src/backends/opencl/op/OpenCLLinearOp.hpp new file mode 100644 index 000000000..616d4631d --- /dev/null +++ b/src/backends/opencl/op/OpenCLLinearOp.hpp @@ -0,0 +1,56 @@ +#ifndef MLLM_OPENCLLINEAROP_H +#define MLLM_OPENCLLINEAROP_H + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLLinearOp final : public Op { +public: + OpenCLLinearOp(Backend *bn, string opName, int in_features, int out_features, bool bias); + virtual ~OpenCLLinearOp() override; + virtual ErrorCode reshape(vector> inputs, vector> outputs) override; + virtual ErrorCode load(AbstructLoader &loader) override; + virtual ErrorCode execute(vector> inputs, vector> outputs) override; + virtual ErrorCode free(vector> inputs, vector> outputs) override; + virtual ErrorCode setUp(vector> inputs, vector> outputs) override; + +private: + int in_features_; + int out_features_; + bool support_bias_; + + Tensor weight_; + Tensor bias_; + + // 使用新的带有 bias 后缀的内核 + cl_kernel kernel_fp32_transb_bias_ = nullptr; + cl_kernel kernel_fp16_transb_bias_ = nullptr; + cl_kernel kernel_fp16_q4_0_transb_bias_ = nullptr; + cl_kernel kernel_fp32_q4_0_transb_bias_ = nullptr; + cl_kernel kernel_gemv_fp32_q4_0_transb_bias_ = nullptr; // GEMV + cl_kernel kernel_gemv_fp16_q4_0_transb_bias_ = nullptr; // GEMV + cl_kernel kernel_gemv_fp16_q4_0_transb_bias_half16_ = nullptr; // GEMV for K%16==0 + + cl_kernel kernel_fp32_q4_0_transb_bias_image2d_ = nullptr; + cl_kernel kernel_fp16_q4_0_transb_bias_image2d_ = nullptr; + + cl_kernel kernel_gemv_fp32_q4_0_transb_bias_image2d_ = nullptr; + cl_kernel kernel_gemv_fp16_q4_0_transb_bias_image2d_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLLinearOpCreator : public OpenCLBackend::Creator { +public: + virtual Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + int in_features = op_param["in_features"]; + int out_features = op_param["out_features"]; + bool bias = op_param["bias"]; + return new OpenCLLinearOp(bn, name, in_features, out_features, bias); + } +}; + +} // namespace mllm + +#endif // MLLM_OPENCLLINEAROP_H \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLMatmulOp.cpp b/src/backends/opencl/op/OpenCLMatmulOp.cpp new file mode 100644 index 000000000..4916e4860 --- /dev/null +++ b/src/backends/opencl/op/OpenCLMatmulOp.cpp @@ -0,0 +1,202 @@ + +#include "OpenCLMatmulOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +#include +#include + +namespace mllm { + +// Constructor remains the same +OpenCLMatmulOp::OpenCLMatmulOp(Backend *bn, std::string name) : + Op(bn, std::move(name)) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) { + throw std::runtime_error("Backend for MatmulOp is not OpenCLBackend"); + } + const std::string kernel_path = "kernel/matmul.cl"; + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += "-DSUPPORTS_FP16"; + } + + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + cl_int err; + kernel_fp32_ = clCreateKernel(program, "gemm_fp32", &err); + check_cl_error(err, "CreateKernel gemm_fp32"); + kernel_fp16_ = clCreateKernel(program, "gemm_fp16", &err); + check_cl_error(err, "CreateKernel gemm_fp16"); + kernel_fp32_bhsd_ = clCreateKernel(program, "gemm_fp32_bhsd", &err); + check_cl_error(err, "CreateKernel gemm_fp32_bhsd"); + kernel_fp16_bhsd_ = clCreateKernel(program, "gemm_fp16_bhsd", &err); + check_cl_error(err, "CreateKernel gemm_fp16_bhsd"); + + const std::string kernel_transb_path = "kernel/matmul_transb.cl"; + cl_program program_tansb = ocl_backend_->getProgram(kernel_transb_path, build_options); + kernel_fp32_transb_ = clCreateKernel(program_tansb, "gemm_fp32_transb", &err); + check_cl_error(err, "CreateKernel gemm_fp32_transb"); + kernel_fp16_transb_ = clCreateKernel(program_tansb, "gemm_fp16_transb", &err); + check_cl_error(err, "CreateKernel gemm_fp16_transb"); + kernel_fp32_q4_0_transb = clCreateKernel(program_tansb, "gemm_fp32_q4_0_transb", &err); + check_cl_error(err, "CreateKernel gemm_fp32_q4_0_transb"); + kernel_fp16_q4_0_transb = clCreateKernel(program_tansb, "gemm_fp16_q4_0_transb", &err); + check_cl_error(err, "CreateKernel gemm_fp16_q4_0_transb"); +} + +// Destructor remains the same +OpenCLMatmulOp::~OpenCLMatmulOp() { + if (kernel_fp32_) clReleaseKernel(kernel_fp32_); + if (kernel_fp16_) clReleaseKernel(kernel_fp16_); + if (kernel_fp32_bhsd_) clReleaseKernel(kernel_fp32_bhsd_); + if (kernel_fp16_bhsd_) clReleaseKernel(kernel_fp16_bhsd_); + if (kernel_fp32_transb_) clReleaseKernel(kernel_fp32_transb_); + if (kernel_fp16_transb_) clReleaseKernel(kernel_fp16_transb_); + if (kernel_fp32_q4_0_transb) clReleaseKernel(kernel_fp32_q4_0_transb); + if (kernel_fp16_q4_0_transb) clReleaseKernel(kernel_fp16_q4_0_transb); +} + +ErrorCode OpenCLMatmulOp::reshape(vector> inputs, vector> outputs) { + auto &A = inputs[0]; + auto &B = inputs[1]; + auto &C = outputs[0]; + + int M = A->sequence(); + int K = A->dimension(); + int N; + + // 智能判断是标准乘法还是转置乘法,并设置标志 + // 标准: A(M,K) * B(K,N) => A.dimension() == B.sequence() + // 转置: A(M,K) * B_T(N,K) => A.dimension() == B.dimension() + if (A->dimension() == B->sequence()) { + // 标准乘法 + use_transb_ = false; // <--- 设置标志 + N = B->dimension(); + } else if (A->dimension() == B->dimension()) { + // 转置乘法 + use_transb_ = true; // <--- 设置标志 + N = B->sequence(); + } else { + // 不支持的矩阵乘法形状 + return NOT_SUPPORT; + } + assert(inputs[0]->ctype() == inputs[1]->ctype() && "Input tensors must have the same ctype"); + C->setCtype(inputs[0]->ctype()); + // 重塑输出张量 C + C->reshape(A->batch(), A->head(), M, N); + C->setDtype(A->dtype()); + return MLLM_NO_ERROR; +} + +// setUp 函数保持不变,reshape 已确保输出张量维度正确,alloc 将分配正确的空间 +ErrorCode OpenCLMatmulOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + inputs[1]->to(MLLM_OPENCL); + outputs[0]->to(MLLM_OPENCL); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLMatmulOp::execute(vector> inputs, vector> outputs) { + auto &A = inputs[0]; + auto &B = inputs[1]; + auto &C = outputs[0]; + + cl_kernel kernel_to_use = nullptr; + DataType in_type = A->dtype(); + DataType weight_type = B->dtype(); + + // === 修改后的内核选择逻辑 === + if (use_transb_) { + // 选择转置内核 + if (in_type == MLLM_TYPE_F32 && weight_type == MLLM_TYPE_F32) + kernel_to_use = kernel_fp32_transb_; + else if (in_type == MLLM_TYPE_F16 && weight_type == MLLM_TYPE_F16) + kernel_to_use = kernel_fp16_transb_; + else if (in_type == MLLM_TYPE_F32 && weight_type == MLLM_TYPE_Q4_0) { + // assert(inputs[0]->head() == 1 && "fp32_q40 only support head==1"); + kernel_to_use = kernel_fp32_q4_0_transb; + } else if (in_type == MLLM_TYPE_F16 && weight_type == MLLM_TYPE_Q4_0) { + // assert(inputs[0]->head() == 1 && "fp16_q40 only support head==1"); + kernel_to_use = kernel_fp16_q4_0_transb; + } else + throw std::runtime_error("Unsupported data types for OpenCL Matmul operation."); + } else { + if (A->ctype() == BHSD) { + if (in_type == MLLM_TYPE_F32 && weight_type == MLLM_TYPE_F32) + kernel_to_use = kernel_fp32_bhsd_; + else if (in_type == MLLM_TYPE_F16 && weight_type == MLLM_TYPE_F16) + kernel_to_use = kernel_fp16_bhsd_; + else + throw std::runtime_error("Unsupported data types for OpenCL Matmul BHSD operation."); + } else { // Default to BSHD + if (in_type == MLLM_TYPE_F32 && weight_type == MLLM_TYPE_F32) + kernel_to_use = kernel_fp32_; + else if (in_type == MLLM_TYPE_F16 && weight_type == MLLM_TYPE_F16) + kernel_to_use = kernel_fp16_; + else + throw std::runtime_error("Unsupported data types for OpenCL Matmul BSHD operation."); + } + } + + if (kernel_to_use == nullptr) { + throw std::runtime_error("No suitable OpenCL Matmul kernel found for the given data types and shape."); + } + + const int M = C->sequence(); + const int K = A->dimension(); + const int N = C->dimension(); + const int B_size = A->batch(); + const int H_size = A->head(); + const int K_b = (A->dimension() == B->sequence()) ? B->sequence() : B->dimension(); // K for B + + cl_mem a_mem = ocl_backend_->get_cl_mem(*A); + cl_mem b_mem = ocl_backend_->get_cl_mem(*B); + cl_mem c_mem = ocl_backend_->get_cl_mem(*C); + + int arg_idx = 0; + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &a_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &b_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(cl_mem), &c_mem); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &M); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &K); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &N); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &H_size); + clSetKernelArg(kernel_to_use, arg_idx++, sizeof(int), &K_b); + cl_event event; + + // if (ocl_backend_->has_fp16_support() && !use_transb_ && A->ctype() == BHSD && in_type == MLLM_TYPE_F16 && weight_type == MLLM_TYPE_F16) { + // const int TILE_M = 8; + // const int TILE_N = 4; + // const size_t global_work_size[3] = { + // (size_t)((N + TILE_N - 1) / TILE_N), + // (size_t)((M + TILE_M - 1) / TILE_M), + // (size_t)(B_size * H_size)}; + // const size_t *local_work_size = nullptr; + // cl_int err = clEnqueueNDRangeKernel( + // ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, + // global_work_size, + // local_work_size, + // 0, nullptr, &event); + // check_cl_error(err, "EnqueueNDRangeKernel Tiled Matmul 3D"); + // } else { + const int TILE_SIZE = 16; + const size_t global_work_size[3] = { + (size_t)(((N + TILE_SIZE - 1) / TILE_SIZE) * TILE_SIZE), + (size_t)(((M + TILE_SIZE - 1) / TILE_SIZE) * TILE_SIZE), + (size_t)(B_size * H_size)}; + const size_t local_work_size[3] = {TILE_SIZE, TILE_SIZE, 1}; + + cl_int err = clEnqueueNDRangeKernel( + ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, + global_work_size, + local_work_size, + 0, nullptr, &event); + + check_cl_error(err, "EnqueueNDRangeKernel Tiled Matmul 3D"); + // } + + ocl_backend_->addProfilingEvent(this->name() + "mat_mul", event); + + return MLLM_NO_ERROR; +} +} // namespace mllm diff --git a/src/backends/opencl/op/OpenCLMatmulOp.hpp b/src/backends/opencl/op/OpenCLMatmulOp.hpp new file mode 100644 index 000000000..404c56911 --- /dev/null +++ b/src/backends/opencl/op/OpenCLMatmulOp.hpp @@ -0,0 +1,41 @@ +#ifndef OPENCL_MATMUL_OP_HPP +#define OPENCL_MATMUL_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLMatmulOp : public Op { +public: + OpenCLMatmulOp(Backend *bn, std::string name); + ~OpenCLMatmulOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + cl_kernel kernel_fp32_ = nullptr; + cl_kernel kernel_fp16_ = nullptr; + cl_kernel kernel_fp32_bhsd_ = nullptr; + cl_kernel kernel_fp16_bhsd_ = nullptr; + cl_kernel kernel_fp32_transb_ = nullptr; + cl_kernel kernel_fp16_transb_ = nullptr; + cl_kernel kernel_fp32_q4_0_transb = nullptr; + cl_kernel kernel_fp16_q4_0_transb = nullptr; + + OpenCLBackend *ocl_backend_ = nullptr; + bool use_transb_ = false; +}; + +class OpenCLMatmulOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new OpenCLMatmulOp(bn, name); + } +}; + +} // namespace mllm + +#endif // OPENCL_MATMUL_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLMulOp.cpp b/src/backends/opencl/op/OpenCLMulOp.cpp new file mode 100644 index 000000000..ad51a47b4 --- /dev/null +++ b/src/backends/opencl/op/OpenCLMulOp.cpp @@ -0,0 +1,108 @@ +#include "OpenCLMulOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" + +namespace mllm { + +OpenCLMulOp::OpenCLMulOp(Backend *bn, std::string name, float data) : + Op(bn, std::move(name)), data_(data) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/mul.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + kernel_fp32_buffer_ = clCreateKernel(program, "mul_scalar_float", &err); + check_cl_error(err, "clCreateKernel for mul_scalar_float"); + kernel_fp32_image_ = clCreateKernel(program, "mul_scalar_float_image2d", &err); + check_cl_error(err, "clCreateKernel for mul_scalar_float_image2d"); + kernel_fp16_buffer_ = clCreateKernel(program, "mul_scalar_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for mul_scalar_fp16_vector"); + kernel_fp16_image_ = clCreateKernel(program, "mul_scalar_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for mul_scalar_fp16_image2d"); + + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +OpenCLMulOp::~OpenCLMulOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLMulOp::reshape(vector> inputs, vector> outputs) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLMulOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + auto output = outputs[0]; + output->setDtype(inputs[0]->dtype()); + auto &out_mem = output->device_memory(); + if (output->dimension() % 4 == 0 && false) { + out_mem.type = MEM_TYPE_IMAGE_2D; + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + out_mem.type = MEM_TYPE_BUFFER; + } + output->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLMulOp::execute(vector> inputs, vector> outputs) { + auto input_dtype = inputs[0]->dtype(); + auto output = outputs[0]; + + if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_image_ : kernel_fp16_image_; + std::vector temp_tensor_storage; + cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); + cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); + if (input_dtype == MLLM_TYPE_F32) { + clSetKernelArg(kernel_to_use, 2, sizeof(float), &data_); + } else { + mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(data_); + clSetKernelArg(kernel_to_use, 2, sizeof(mllm_fp16_t), &data_fp16); + } + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } else { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_buffer_ : kernel_fp16_buffer_; + cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + if (input_dtype == MLLM_TYPE_F32) { + clSetKernelArg(kernel_to_use, 1, sizeof(float), &data_); + } else { + mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(data_); + clSetKernelArg(kernel_to_use, 1, sizeof(mllm_fp16_t), &data_fp16); + } + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + + size_t count = inputs[0]->count(); + if (input_dtype == MLLM_TYPE_F16) { count /= 4; } + + const size_t global_work_size[1] = {count}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLMulOp.hpp b/src/backends/opencl/op/OpenCLMulOp.hpp new file mode 100644 index 000000000..1efbd1355 --- /dev/null +++ b/src/backends/opencl/op/OpenCLMulOp.hpp @@ -0,0 +1,40 @@ +#ifndef OPENCL_MUL_OP_HPP +#define OPENCL_MUL_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLMulOp : public Op { +public: + OpenCLMulOp(Backend *bn, std::string name, float data); + ~OpenCLMulOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + float data_; // 用于存储要乘的标量 + + cl_kernel kernel_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp16_buffer_ = nullptr; + cl_kernel kernel_fp16_image_ = nullptr; + + cl_sampler sampler_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLMulOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + float data = op_param["data"]; + return new OpenCLMulOp(bn, name, data); + } +}; + +} // namespace mllm + +#endif // OPENCL_MUL_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLMulTwoOp.cpp b/src/backends/opencl/op/OpenCLMulTwoOp.cpp new file mode 100644 index 000000000..ef411d819 --- /dev/null +++ b/src/backends/opencl/op/OpenCLMulTwoOp.cpp @@ -0,0 +1,111 @@ +#include "OpenCLMulTwoOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLMulTwoOp::OpenCLMulTwoOp(Backend *bn, std::string name) : + Op(bn, std::move(name)) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/mul.cl"; + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + + cl_int err; + kernel_fp32_buffer_ = clCreateKernel(program, "mul_float", &err); + check_cl_error(err, "clCreateKernel for mul_float"); + kernel_fp32_image_ = clCreateKernel(program, "mul_float_image2d", &err); + check_cl_error(err, "clCreateKernel for mul_float_image2d"); + kernel_fp16_buffer_ = clCreateKernel(program, "mul_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for mul_fp16_vector"); + kernel_fp16_image_ = clCreateKernel(program, "mul_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for mul_fp16_image2d"); + + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +OpenCLMulTwoOp::~OpenCLMulTwoOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLMulTwoOp::reshape(vector> inputs, vector> outputs) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLMulTwoOp::setUp(vector> inputs, vector> outputs) { + for (auto &input : inputs) { + input->to(MLLM_OPENCL); + } + auto output = outputs[0]; + output->setDtype(inputs[0]->dtype()); + auto &out_mem = output->device_memory(); + if (output->dimension() % 4 == 0 && false) { + out_mem.type = MEM_TYPE_IMAGE_2D; + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + out_mem.type = MEM_TYPE_BUFFER; + } + output->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLMulTwoOp::execute(vector> inputs, vector> outputs) { + auto input_dtype = inputs[0]->dtype(); + auto output = outputs[0]; + + if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_image_ : kernel_fp16_image_; + std::vector temp_tensor_storage; + cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); + cl_mem inB_mem = get_image_from_tensor(inputs[1], ocl_backend_, temp_tensor_storage); + cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &inB_mem); + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } else { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_buffer_ : kernel_fp16_buffer_; + cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); + cl_mem in1_buf = ocl_backend_->get_cl_mem(*inputs[1]); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &in1_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + const int b_dim = inputs[1]->dimension(); + const int a_dim = inputs[0]->dimension(); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &b_dim); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &a_dim); + size_t count = inputs[0]->count(); + if (input_dtype == MLLM_TYPE_F16) { + if (count % 4 != 0) { + throw std::runtime_error("[mulTwo]For FP16 vector kernel, tensor count must be a multiple of 4."); + } + count /= 4; + } + const size_t global_work_size[1] = {count}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLMulTwoOp.hpp b/src/backends/opencl/op/OpenCLMulTwoOp.hpp new file mode 100644 index 000000000..2f1b991a2 --- /dev/null +++ b/src/backends/opencl/op/OpenCLMulTwoOp.hpp @@ -0,0 +1,37 @@ +#ifndef OPENCL_MUL_TWO_OP_HPP +#define OPENCL_MUL_TWO_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLMulTwoOp : public Op { +public: + OpenCLMulTwoOp(Backend *bn, std::string name); + ~OpenCLMulTwoOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + cl_kernel kernel_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp16_buffer_ = nullptr; + cl_kernel kernel_fp16_image_ = nullptr; + + cl_sampler sampler_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLMulTwoOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new OpenCLMulTwoOp(bn, name); + } +}; + +} // namespace mllm + +#endif // OPENCL_MUL_TWO_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLRMSNormOp.cpp b/src/backends/opencl/op/OpenCLRMSNormOp.cpp new file mode 100644 index 000000000..7a7f8009a --- /dev/null +++ b/src/backends/opencl/op/OpenCLRMSNormOp.cpp @@ -0,0 +1,117 @@ +// OpenCLRMSNormOp.cpp + +#include "OpenCLRMSNormOp.hpp" +#include "Types.hpp" +// #include "utils/OpenCLTools.hpp" + +namespace mllm { + +// 构造函数 +OpenCLRMSNormOp::OpenCLRMSNormOp(Backend *bn, std::string name, int normSize, float epsilon, bool add_unit_offset) : + Op(bn, std::move(name)), normSize_(normSize), epsilon_(epsilon), add_unit_offset_(add_unit_offset) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/rmsnorm.cl"; + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + + cl_int err; + // ✨ 修改: 创建两个内核 + kernel_fp32_ = clCreateKernel(program, "rmsnorm_f32_q4", &err); + check_cl_error(err, "clCreateKernel for rmsnorm_f32_q4"); + + kernel_fp16_ = clCreateKernel(program, "rmsnorm_f16_q4", &err); + check_cl_error(err, "clCreateKernel for rmsnorm_f16_q4"); +} + +// ✨ 新增: 自定义析构函数 +OpenCLRMSNormOp::~OpenCLRMSNormOp() { + if (kernel_fp32_) clReleaseKernel(kernel_fp32_); + if (kernel_fp16_) clReleaseKernel(kernel_fp16_); +} + +// reshape, load, free, setUp 函数保持不变 +ErrorCode OpenCLRMSNormOp::reshape(vector> inputs, vector> outputs) { + assert(normSize_ == inputs[0]->dimension()); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + // ✨ 新增: 确保输出类型与输入一致 + outputs[0]->setDtype(inputs[0]->dtype()); + return Op::reshape(inputs, outputs); +} +ErrorCode OpenCLRMSNormOp::load(AbstructLoader &loader) { + weight_.setBackend(Backend::global_backends[MLLM_CPU].get()); + weight_.setName(name() + ".weight"); + weight_.reshape(1, 1, 1, normSize_); + if (loader.getDataType(weight_.name()) != MLLM_TYPE_COUNT) { + weight_.setDtype(loader.getDataType(weight_.name())); + weight_.alloc(); + loader.load(&weight_); + weight_.to(MLLM_OPENCL); + } else { + weight_.setDtype(MLLM_TYPE_F32); + weight_.alloc(); + weight_.to(MLLM_OPENCL); + } + return Op::load(loader); +} +ErrorCode OpenCLRMSNormOp::free(vector> inputs, vector> outputs) { + weight_.free(); + return Op::free(inputs, outputs); +} +ErrorCode OpenCLRMSNormOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + outputs[0]->to(MLLM_OPENCL); + return MLLM_NO_ERROR; +} + +// execute 函数 +ErrorCode OpenCLRMSNormOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + + // ✨ 修改: 根据输入类型选择内核 + cl_kernel kernel_to_use = nullptr; + if (input->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_; + } else if (input->dtype() == MLLM_TYPE_F16) { + kernel_to_use = kernel_fp16_; + } else { + return NOT_SUPPORT; + } + + const int D = input->dimension(); + const int weight_is_q4 = (weight_.dtype() == MLLM_TYPE_Q4_0) ? 1 : 0; + const int add_unit_offset_int = add_unit_offset_ ? 1 : 0; + + cl_mem src_buf = ocl_backend_->get_cl_mem(*input); + cl_mem dst_buf = ocl_backend_->get_cl_mem(*output); + cl_mem w_buf = ocl_backend_->get_cl_mem(weight_); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &src_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &dst_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &w_buf); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &weight_is_q4); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &D); + clSetKernelArg(kernel_to_use, 5, sizeof(float), &epsilon_); + clSetKernelArg(kernel_to_use, 6, sizeof(int), &add_unit_offset_int); + + const size_t total_rows = (size_t)input->batch() * input->head() * input->sequence(); + const size_t local_work_size = 256; + const size_t global_work_size = total_rows * local_work_size; + + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, &global_work_size, &local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "clEnqueueNDRangeKernel for RMSNorm"); + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLRMSNormOp.hpp b/src/backends/opencl/op/OpenCLRMSNormOp.hpp new file mode 100644 index 000000000..31943528b --- /dev/null +++ b/src/backends/opencl/op/OpenCLRMSNormOp.hpp @@ -0,0 +1,43 @@ +#ifndef OPENCL_RMSNORM_OP_HPP +#define OPENCL_RMSNORM_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLRMSNormOp : public Op { +public: + OpenCLRMSNormOp(Backend *bn, std::string name, int normSize, float epsilon = 1e-6, bool add_unit_offset_ = false); + ~OpenCLRMSNormOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode load(AbstructLoader &loader) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + ErrorCode free(vector> inputs, vector> outputs) override; + +private: + float epsilon_; + Tensor weight_; + int normSize_; + bool add_unit_offset_; + + cl_kernel kernel_fp32_ = nullptr; + cl_kernel kernel_fp16_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLRMSNormOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + int normSize = (int)op_param["norm_size"]; + float epsilon = op_param.count("epsilon") ? (float)op_param["epsilon"] : 1e-6f; + bool add_unit_offset = op_param.count("add_unit_offset") ? (bool)op_param["add_unit_offset"] : false; + return new OpenCLRMSNormOp(bn, name, normSize, epsilon, add_unit_offset); + } +}; + +} // namespace mllm + +#endif // OPENCL_RMSNORM_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLRoPEOp.cpp b/src/backends/opencl/op/OpenCLRoPEOp.cpp new file mode 100644 index 000000000..af0d65d16 --- /dev/null +++ b/src/backends/opencl/op/OpenCLRoPEOp.cpp @@ -0,0 +1,357 @@ +#include "OpenCLRoPEOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" // For MLLM_FP32_TO_FP16 +#include + +namespace mllm { + +cl_mem OpenCLRoPEOp::sin_buffer_fp32_ = nullptr; +cl_mem OpenCLRoPEOp::cos_buffer_fp32_ = nullptr; +cl_mem OpenCLRoPEOp::sin_buffer_fp16_ = nullptr; +cl_mem OpenCLRoPEOp::cos_buffer_fp16_ = nullptr; +size_t OpenCLRoPEOp::buffer_size_fp32_ = 0; +size_t OpenCLRoPEOp::buffer_size_fp16_ = 0; +vector> OpenCLRoPEOp::sin_table_cpu_fp32_; +vector> OpenCLRoPEOp::cos_table_cpu_fp32_; +int OpenCLRoPEOp::partial_dim_cached_ = -1; + +// === 本地辅助函数 (sinusoidal_position_embedding_*) 保持不变 === +namespace { +void sinusoidal_position_embedding_llama(int seq_len, int output_dim, float rope_theta, + vector> &sin_table, vector> &cos_table) { + sin_table.resize(seq_len, vector(output_dim)); + cos_table.resize(seq_len, vector(output_dim)); + vector theta(output_dim / 2); + for (int i = 0; i < output_dim / 2; ++i) { + theta[i] = 1.0f / powf(rope_theta, (float)(2 * i) / output_dim); + } + for (int s = 0; s < seq_len; ++s) { + for (int d = 0; d < output_dim; d += 2) { + float t = (float)s * theta[d / 2]; + float sin_val = sinf(t); + float cos_val = cosf(t); + sin_table[s][d] = sin_val; + cos_table[s][d] = cos_val; + sin_table[s][d + 1] = sin_val; + cos_table[s][d + 1] = cos_val; + } + } +} + +void sinusoidal_position_embedding_huggingface(int seq_len, int output_dim, float rope_theta, + vector> &sin_table, vector> &cos_table) { + sin_table.resize(seq_len, vector(output_dim / 2)); + cos_table.resize(seq_len, vector(output_dim / 2)); + vector theta(output_dim / 2); + for (int i = 0; i < output_dim / 2; ++i) { + theta[i] = 1.0f / powf(rope_theta, (float)(2 * i) / output_dim); + } + for (int s = 0; s < seq_len; ++s) { + for (int d = 0; d < output_dim / 2; ++d) { + float t = (float)s * theta[d]; + sin_table[s][d] = sinf(t); + cos_table[s][d] = cosf(t); + } + } +} +} // namespace + +// === 构造函数实现 (保持不变) === +OpenCLRoPEOp::OpenCLRoPEOp(Backend *bn, string opName, OpParam &config, int threadCount) : + Op(bn, opName), config_(config) { + _init(threadCount); +} +OpenCLRoPEOp::OpenCLRoPEOp(Backend *bn, string opName, int pose_type, int threadCount) : + Op(bn, opName) { + config_["pose_type"] = pose_type; + _init(threadCount); +} +OpenCLRoPEOp::OpenCLRoPEOp(Backend *bn, string opName, int pose_type, float rope_theta, int max_position_embeddings, int threadCount) : + Op(bn, opName) { + config_["pose_type"] = pose_type; + config_["rope_theta"] = rope_theta; + config_["max_position_embeddings"] = max_position_embeddings; + _init(threadCount); +} +OpenCLRoPEOp::OpenCLRoPEOp(Backend *bn, string opName, int pose_type, float rope_theta, float partial_rotary_factor, int max_position_embeddings, int threadCount) : + Op(bn, opName) { + config_["pose_type"] = pose_type; + config_["rope_theta"] = rope_theta; + config_["partial_rotary_factor"] = partial_rotary_factor; + config_["max_position_embeddings"] = max_position_embeddings; + _init(threadCount); +} + +// ✨ 修改: _init 函数,创建所有内核 +void OpenCLRoPEOp::_init(int threadCount) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + pose_type_ = (RoPEType)config_.at("pose_type"); + if (config_.find("rope_theta") != config_.end()) rope_theta_ = config_.at("rope_theta"); + if (config_.find("partial_rotary_factor") != config_.end()) partial_rotary_factor_ = config_.at("partial_rotary_factor"); + if (config_.find("max_position_embeddings") != config_.end()) pos_max_ = config_.at("max_position_embeddings"); + + const std::string kernel_path = "kernel/rope.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + cl_int err; + + kernel_llama_fp32_ = clCreateKernel(program, "rope_llama_fp32", &err); + check_cl_error(err, "clCreateKernel rope_llama_fp32"); + kernel_hf_fp32_ = clCreateKernel(program, "rope_hf_fp32", &err); + check_cl_error(err, "clCreateKernel rope_hf_fp32"); + + kernel_llama_fp16_ = clCreateKernel(program, "rope_llama_fp16", &err); + check_cl_error(err, "clCreateKernel rope_llama_fp16"); + kernel_hf_fp16_ = clCreateKernel(program, "rope_hf_fp16", &err); + check_cl_error(err, "clCreateKernel rope_hf_fp16"); +} + +// ✨ 修改: 析构函数,释放所有资源 +OpenCLRoPEOp::~OpenCLRoPEOp() { + if (kernel_llama_fp32_) clReleaseKernel(kernel_llama_fp32_); + if (kernel_hf_fp32_) clReleaseKernel(kernel_hf_fp32_); + // if (sin_buffer_fp32_) clReleaseMemObject(sin_buffer_fp32_); + // if (cos_buffer_fp32_) clReleaseMemObject(cos_buffer_fp32_); + + if (kernel_llama_fp16_) clReleaseKernel(kernel_llama_fp16_); + if (kernel_hf_fp16_) clReleaseKernel(kernel_hf_fp16_); + // if (sin_buffer_fp16_) clReleaseMemObject(sin_buffer_fp16_); + // if (cos_buffer_fp16_) clReleaseMemObject(cos_buffer_fp16_); +} + +/* +void OpenCLRoPEOp::_computeSinCosTable(int partial_dim) { + if (!sin_table_cpu_fp32_.empty() && partial_dim_cached_ == partial_dim) { + return; + } + partial_dim_cached_ = partial_dim; + + if (pose_type_ == LLAMAROPE) { + sinusoidal_position_embedding_llama(pos_max_, partial_dim, rope_theta_, sin_table_cpu_fp32_, cos_table_cpu_fp32_); + } else if (pose_type_ == HFHUBROPE || pose_type_ == MLAROPE) { + sinusoidal_position_embedding_huggingface(pos_max_, partial_dim, rope_theta_, sin_table_cpu_fp32_, cos_table_cpu_fp32_); + } else { + throw std::runtime_error("Unsupported RoPE type for OpenCL"); + } + + int seq_len = sin_table_cpu_fp32_.size(); + int table_dim = sin_table_cpu_fp32_[0].size(); + + // --- 1. 处理 FP32 Buffer --- + size_t new_buffer_size_fp32 = (size_t)seq_len * table_dim * sizeof(float); + if (buffer_size_fp32_ != new_buffer_size_fp32) { + if (sin_buffer_fp32_) clReleaseMemObject(sin_buffer_fp32_); + if (cos_buffer_fp32_) clReleaseMemObject(cos_buffer_fp32_); + cl_int err; + sin_buffer_fp32_ = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_ONLY, new_buffer_size_fp32, nullptr, &err); + check_cl_error(err, "clCreateBuffer for sin_buffer_fp32_"); + cos_buffer_fp32_ = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_ONLY, new_buffer_size_fp32, nullptr, &err); + check_cl_error(err, "clCreateBuffer for cos_buffer_fp32_"); + buffer_size_fp32_ = new_buffer_size_fp32; + } + + vector sin_flat_fp32, cos_flat_fp32; + sin_flat_fp32.reserve(seq_len * table_dim); + cos_flat_fp32.reserve(seq_len * table_dim); + for (int i = 0; i < seq_len; ++i) { + sin_flat_fp32.insert(sin_flat_fp32.end(), sin_table_cpu_fp32_[i].begin(), sin_table_cpu_fp32_[i].end()); + cos_flat_fp32.insert(cos_flat_fp32.end(), cos_table_cpu_fp32_[i].begin(), cos_table_cpu_fp32_[i].end()); + } + clEnqueueWriteBuffer(ocl_backend_->getQueue(), sin_buffer_fp32_, CL_TRUE, 0, buffer_size_fp32_, sin_flat_fp32.data(), 0, nullptr, nullptr); + clEnqueueWriteBuffer(ocl_backend_->getQueue(), cos_buffer_fp32_, CL_TRUE, 0, buffer_size_fp32_, cos_flat_fp32.data(), 0, nullptr, nullptr); + + // --- 2. 处理 FP16 Buffer --- + size_t new_buffer_size_fp16 = (size_t)seq_len * table_dim * sizeof(mllm_fp16_t); + if (buffer_size_fp16_ != new_buffer_size_fp16) { + if (sin_buffer_fp16_) clReleaseMemObject(sin_buffer_fp16_); + if (cos_buffer_fp16_) clReleaseMemObject(cos_buffer_fp16_); + cl_int err; + sin_buffer_fp16_ = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_ONLY, new_buffer_size_fp16, nullptr, &err); + check_cl_error(err, "clCreateBuffer for sin_buffer_fp16_"); + cos_buffer_fp16_ = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_ONLY, new_buffer_size_fp16, nullptr, &err); + check_cl_error(err, "clCreateBuffer for cos_buffer_fp16_"); + buffer_size_fp16_ = new_buffer_size_fp16; + } + + vector sin_flat_fp16, cos_flat_fp16; + sin_flat_fp16.reserve(seq_len * table_dim); + cos_flat_fp16.reserve(seq_len * table_dim); + for (int i = 0; i < seq_len; ++i) { + for (int j = 0; j < table_dim; ++j) { + sin_flat_fp16.push_back(MLLM_FP32_TO_FP16(sin_table_cpu_fp32_[i][j])); + cos_flat_fp16.push_back(MLLM_FP32_TO_FP16(cos_table_cpu_fp32_[i][j])); + } + } + clEnqueueWriteBuffer(ocl_backend_->getQueue(), sin_buffer_fp16_, CL_TRUE, 0, buffer_size_fp16_, sin_flat_fp16.data(), 0, nullptr, nullptr); + clEnqueueWriteBuffer(ocl_backend_->getQueue(), cos_buffer_fp16_, CL_TRUE, 0, buffer_size_fp16_, cos_flat_fp16.data(), 0, nullptr, nullptr); +} +*/ +void OpenCLRoPEOp::_computeSinCosTable(int partial_dim) { + if (!sin_table_cpu_fp32_.empty() && partial_dim_cached_ == partial_dim) { + return; + } + partial_dim_cached_ = partial_dim; + + if (pose_type_ == LLAMAROPE) { + sinusoidal_position_embedding_llama(pos_max_, partial_dim, rope_theta_, sin_table_cpu_fp32_, cos_table_cpu_fp32_); + } else if (pose_type_ == HFHUBROPE || pose_type_ == MLAROPE) { + sinusoidal_position_embedding_huggingface(pos_max_, partial_dim, rope_theta_, sin_table_cpu_fp32_, cos_table_cpu_fp32_); + } else { + throw std::runtime_error("Unsupported RoPE type for OpenCL"); + } + + int seq_len = sin_table_cpu_fp32_.size(); + int table_dim = sin_table_cpu_fp32_[0].size(); + + // FP32 + size_t new_buffer_size_fp32 = (size_t)seq_len * table_dim * sizeof(float); + if (buffer_size_fp32_ != new_buffer_size_fp32) { + if (sin_buffer_fp32_) clReleaseMemObject(sin_buffer_fp32_); + if (cos_buffer_fp32_) clReleaseMemObject(cos_buffer_fp32_); + cl_int err; + sin_buffer_fp32_ = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_ONLY, new_buffer_size_fp32, nullptr, &err); + check_cl_error(err, "clCreateBuffer sin_buffer_fp32_"); + cos_buffer_fp32_ = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_ONLY, new_buffer_size_fp32, nullptr, &err); + check_cl_error(err, "clCreateBuffer cos_buffer_fp32_"); + buffer_size_fp32_ = new_buffer_size_fp32; + } + + vector sin_flat_fp32, cos_flat_fp32; + sin_flat_fp32.reserve(seq_len * table_dim); + cos_flat_fp32.reserve(seq_len * table_dim); + for (int i = 0; i < seq_len; ++i) { + sin_flat_fp32.insert(sin_flat_fp32.end(), sin_table_cpu_fp32_[i].begin(), sin_table_cpu_fp32_[i].end()); + cos_flat_fp32.insert(cos_flat_fp32.end(), cos_table_cpu_fp32_[i].begin(), cos_table_cpu_fp32_[i].end()); + } + clEnqueueWriteBuffer(ocl_backend_->getQueue(), sin_buffer_fp32_, CL_TRUE, 0, buffer_size_fp32_, sin_flat_fp32.data(), 0, nullptr, nullptr); + clEnqueueWriteBuffer(ocl_backend_->getQueue(), cos_buffer_fp32_, CL_TRUE, 0, buffer_size_fp32_, cos_flat_fp32.data(), 0, nullptr, nullptr); + + // FP16 + size_t new_buffer_size_fp16 = (size_t)seq_len * table_dim * sizeof(mllm_fp16_t); + if (buffer_size_fp16_ != new_buffer_size_fp16) { + if (sin_buffer_fp16_) clReleaseMemObject(sin_buffer_fp16_); + if (cos_buffer_fp16_) clReleaseMemObject(cos_buffer_fp16_); + cl_int err; + sin_buffer_fp16_ = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_ONLY, new_buffer_size_fp16, nullptr, &err); + check_cl_error(err, "clCreateBuffer sin_buffer_fp16_"); + cos_buffer_fp16_ = clCreateBuffer(ocl_backend_->getContext(), CL_MEM_READ_ONLY, new_buffer_size_fp16, nullptr, &err); + check_cl_error(err, "clCreateBuffer cos_buffer_fp16_"); + buffer_size_fp16_ = new_buffer_size_fp16; + } + + vector sin_flat_fp16, cos_flat_fp16; + sin_flat_fp16.reserve(seq_len * table_dim); + cos_flat_fp16.reserve(seq_len * table_dim); + for (int i = 0; i < seq_len; ++i) { + for (int j = 0; j < table_dim; ++j) { + sin_flat_fp16.push_back(MLLM_FP32_TO_FP16(sin_table_cpu_fp32_[i][j])); + cos_flat_fp16.push_back(MLLM_FP32_TO_FP16(cos_table_cpu_fp32_[i][j])); + } + } + clEnqueueWriteBuffer(ocl_backend_->getQueue(), sin_buffer_fp16_, CL_TRUE, 0, buffer_size_fp16_, sin_flat_fp16.data(), 0, nullptr, nullptr); + clEnqueueWriteBuffer(ocl_backend_->getQueue(), cos_buffer_fp16_, CL_TRUE, 0, buffer_size_fp16_, cos_flat_fp16.data(), 0, nullptr, nullptr); +} + +ErrorCode OpenCLRoPEOp::reshape(vector> inputs, vector> outputs) { + int partial_dim = inputs[0]->dimension() * partial_rotary_factor_; + _computeSinCosTable(partial_dim); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); // 确保输出类型与输入一致 + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLRoPEOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +// ✨ 修改: execute 函数,根据数据类型选择内核 +ErrorCode OpenCLRoPEOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + + // RoPE是in-place操作,先将输入数据拷贝到输出 + clEnqueueCopyBuffer(ocl_backend_->getQueue(), ocl_backend_->get_cl_mem(*input), ocl_backend_->get_cl_mem(*output), 0, 0, input->size(), 0, nullptr, nullptr); + + cl_kernel kernel_to_use = nullptr; + cl_mem sin_buf_to_use = nullptr; + cl_mem cos_buf_to_use = nullptr; + int partial_dim = output->dimension() * partial_rotary_factor_; + size_t d_work_size = 0; + + if (output->dtype() == MLLM_TYPE_F32) { + sin_buf_to_use = sin_buffer_fp32_; + cos_buf_to_use = cos_buffer_fp32_; + if (pose_type_ == LLAMAROPE) { + kernel_to_use = kernel_llama_fp32_; + d_work_size = partial_dim / 2; + } else { // HFHUBROPE, MLAROPE + kernel_to_use = kernel_hf_fp32_; + d_work_size = partial_dim / 2; + } + } else if (output->dtype() == MLLM_TYPE_F16) { + sin_buf_to_use = sin_buffer_fp16_; + cos_buf_to_use = cos_buffer_fp16_; + if (pose_type_ == LLAMAROPE) { + kernel_to_use = kernel_llama_fp16_; + d_work_size = partial_dim / 2; + } else { // HFHUBROPE, MLAROPE + kernel_to_use = kernel_hf_fp16_; + d_work_size = partial_dim / 2; + } + } else { + std::runtime_error("Unsupported RoPE data type for OpenCL: " + std::to_string(output->dtype())); + return NOT_SUPPORT; + } + + if (kernel_to_use == nullptr || sin_buf_to_use == nullptr || cos_buf_to_use == nullptr) { + std::runtime_error("RoPE kernel or buffers not initialized properly."); + return NOT_SUPPORT; // 安全检查 + } + + cl_mem data_buf = ocl_backend_->get_cl_mem(*output); + int head_dim = output->head() * output->batch(); // 将 batch 和 head 合并 + int seq_len = output->sequence(); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &data_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &sin_buf_to_use); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &cos_buf_to_use); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &partial_dim); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &head_dim); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &seq_len); + clSetKernelArg(kernel_to_use, 6, sizeof(int), &pos_offset_); + + size_t global_work_size[3] = {d_work_size, (size_t)seq_len, (size_t)head_dim}; + + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "clEnqueueNDRangeKernel for RoPE"); + + pos_offset_ += output->sequence(); + return MLLM_NO_ERROR; +} + +// Creator 的实现保持不变 +Op *OpenCLRoPEOpCreator::create(OpParam op_param, Backend *bn, string name, int threadCount) const { + auto it = op_param.find("rope_type"); + if (it != op_param.end()) { + return new OpenCLRoPEOp(bn, name, op_param, threadCount); + } + int pose_type = op_param["pose_type"]; + if (op_param.find("rope_theta") == op_param.end()) { + return new OpenCLRoPEOp(bn, name, pose_type, threadCount); + } + float rope_theta = op_param["rope_theta"]; + int max_position_embeddings = op_param["max_position_embeddings"]; + if (op_param.find("partial_rotary_factor") == op_param.end()) { + return new OpenCLRoPEOp(bn, name, pose_type, rope_theta, max_position_embeddings, threadCount); + } + float partial_rotary_factor = op_param["partial_rotary_factor"]; + return new OpenCLRoPEOp(bn, name, pose_type, rope_theta, partial_rotary_factor, max_position_embeddings, threadCount); +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLRoPEOp.hpp b/src/backends/opencl/op/OpenCLRoPEOp.hpp new file mode 100644 index 000000000..ad2baa42a --- /dev/null +++ b/src/backends/opencl/op/OpenCLRoPEOp.hpp @@ -0,0 +1,80 @@ +#ifndef OPENCL_ROPE_OP_HPP +#define OPENCL_ROPE_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" +#include "Types.hpp" + +namespace mllm { + +class OpenCLRoPEOp : public Op { +public: + OpenCLRoPEOp(Backend *bn, string opName, OpParam &config, int threadCount); + OpenCLRoPEOp(Backend *bn, string opName, int pose_type, int threadCount); + OpenCLRoPEOp(Backend *bn, string opName, int pose_type, float rope_theta, int max_position_embeddings, int threadCount); + OpenCLRoPEOp(Backend *bn, string opName, int pose_type, float rope_theta, float partial_rotary_factor, int max_position_embeddings, int threadCount); + + ~OpenCLRoPEOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + + void clearCache() override { + pos_offset_ = 0; + } + +private: + // 原来的成员变量改为 static(全局共享) + static cl_mem sin_buffer_fp32_; + static cl_mem cos_buffer_fp32_; + static cl_mem sin_buffer_fp16_; + static cl_mem cos_buffer_fp16_; + static size_t buffer_size_fp32_; + static size_t buffer_size_fp16_; + static vector> sin_table_cpu_fp32_; + static vector> cos_table_cpu_fp32_; + static int partial_dim_cached_; + + void _init(int threadCount); + void _computeSinCosTable(int partial_dim); + + // FP32 buffers + // cl_mem sin_buffer_fp32_ = nullptr; + // cl_mem cos_buffer_fp32_ = nullptr; + // size_t buffer_size_fp32_ = 0; + // vector> sin_table_cpu_fp32_; + // vector> cos_table_cpu_fp32_; + + // FP16 buffers + // cl_mem sin_buffer_fp16_ = nullptr; + // cl_mem cos_buffer_fp16_ = nullptr; + // size_t buffer_size_fp16_ = 0; + + // FP32 kernels + cl_kernel kernel_llama_fp32_ = nullptr; + cl_kernel kernel_hf_fp32_ = nullptr; + + // FP16 kernels + cl_kernel kernel_llama_fp16_ = nullptr; + cl_kernel kernel_hf_fp16_ = nullptr; + + OpParam config_; + RoPEType pose_type_; + int pos_max_ = 4096; + float rope_theta_ = 10000.0f; + float partial_rotary_factor_ = 1.0f; + // int partial_dim_cached_ = 0; + int pos_offset_ = 0; + + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLRoPEOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override; +}; + +} // namespace mllm + +#endif // OPENCL_ROPE_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLScatterAddOp.cpp b/src/backends/opencl/op/OpenCLScatterAddOp.cpp new file mode 100644 index 000000000..81b9faa20 --- /dev/null +++ b/src/backends/opencl/op/OpenCLScatterAddOp.cpp @@ -0,0 +1,96 @@ +#include "OpenCLScatterAddOp.hpp" +#include "Types.hpp" +// #include "utils/OpenCLTools.hpp" + +namespace mllm { + +// 构造函数、析构函数、reshape、setUp 保持不变... +OpenCLScatterAddOp::OpenCLScatterAddOp(Backend *bn, std::string name, Chl dim) : + Op(bn, std::move(name)), dim_(dim) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/scatter_add.cl"; + // cl_program program = ocl_backend_->getProgram(kernel_path, "-cl-std=CL1.2"); + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + + cl_program program = ocl_backend_->getProgram(kernel_path, build_options + " -cl-std=CL1.2"); + + cl_int err; + kernel_fp32_ = clCreateKernel(program, "scatter_add_fp32", &err); + check_cl_error(err, "clCreateKernel for scatter_add_fp32"); + kernel_fp16_ = clCreateKernel(program, "scatter_add_fp16", &err); + check_cl_error(err, "clCreateKernel for scatter_add_fp16"); +} + +OpenCLScatterAddOp::~OpenCLScatterAddOp() { + if (kernel_fp32_) clReleaseKernel(kernel_fp32_); + if (kernel_fp16_) clReleaseKernel(kernel_fp16_); +} + +ErrorCode OpenCLScatterAddOp::reshape(vector> inputs, vector> outputs) { + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLScatterAddOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + inputs[1]->to(MLLM_OPENCL); + inputs[2]->to(MLLM_OPENCL); + return MLLM_NO_ERROR; +} + +// **execute 函数已修正** +ErrorCode OpenCLScatterAddOp::execute(vector> inputs, vector> outputs) { + auto self = inputs[0]; + auto value = inputs[1]; + auto indices = inputs[2]; + + if (dim_ != SEQUENCE) { + std::cerr << "This version of OpenCLScatterAddOp only supports SEQUENCE dimension." << std::endl; + return NOT_SUPPORT; + } + if (self->ctype() != BSHD || value->ctype() != BSHD) { + return NOT_SUPPORT; + } + + cl_kernel kernel_to_use; + if (self->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_; + } else if (self->dtype() == MLLM_TYPE_F16) { + kernel_to_use = kernel_fp16_; + } else { + return NOT_SUPPORT; + } + + cl_mem self_buf = ocl_backend_->get_cl_mem(*self); + cl_mem value_buf = ocl_backend_->get_cl_mem(*value); + cl_mem indices_buf = ocl_backend_->get_cl_mem(*indices); + + const int B = self->batch(); + const int H = self->head(); + const int D = self->dimension(); + const int S_self = self->sequence(); + const int S_value = value->sequence(); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &self_buf); // 参数 0: self + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &value_buf); // 参数 1: value + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &indices_buf); // 参数 2: indices + + clSetKernelArg(kernel_to_use, 3, sizeof(int), &B); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &H); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &D); + clSetKernelArg(kernel_to_use, 6, sizeof(int), &S_self); + clSetKernelArg(kernel_to_use, 7, sizeof(int), &S_value); + const size_t global_work_size[3] = {(size_t)D, (size_t)H, (size_t)B * S_value}; + + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, global_work_size, nullptr, 0, nullptr, &event); + check_cl_error(err, "clEnqueueNDRangeKernel for ScatterAdd (in-place, sequence)"); + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLScatterAddOp.hpp b/src/backends/opencl/op/OpenCLScatterAddOp.hpp new file mode 100644 index 000000000..8f3ebee99 --- /dev/null +++ b/src/backends/opencl/op/OpenCLScatterAddOp.hpp @@ -0,0 +1,37 @@ +#ifndef OPENCL_SCATTER_ADD_OP_HPP +#define OPENCL_SCATTER_ADD_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" +#include "Types.hpp" + +namespace mllm { + +class OpenCLScatterAddOp : public Op { +public: + OpenCLScatterAddOp(Backend *bn, std::string name, Chl dim); + ~OpenCLScatterAddOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + Chl dim_; // The axis of `self` that `indices` refers to. + cl_kernel kernel_fp32_ = nullptr; + cl_kernel kernel_fp16_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLScatterAddOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // CPU版本的命名是"dim",我们保持一致 + // Chl dim = (Chl)op_param.at("dim"); + return new OpenCLScatterAddOp(bn, name, SEQUENCE); + } +}; + +} // namespace mllm + +#endif // OPENCL_SCATTER_ADD_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSiLUOp.cpp b/src/backends/opencl/op/OpenCLSiLUOp.cpp new file mode 100644 index 000000000..9ef4e4ff4 --- /dev/null +++ b/src/backends/opencl/op/OpenCLSiLUOp.cpp @@ -0,0 +1,91 @@ +// 文件名: ops/OpenCLSiLUOp.cpp + +#include "OpenCLSiLUOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +#include + +namespace mllm { + +OpenCLSiLUOp::OpenCLSiLUOp(Backend *bn, std::string name) : + Op(bn, std::move(name)) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/silu.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + kernel_fp32_ = clCreateKernel(program, "silu_fp32", &err); + check_cl_error(err, "clCreateKernel for silu_fp32"); + + kernel_fp16_ = clCreateKernel(program, "silu_fp16", &err); + check_cl_error(err, "clCreateKernel for silu_fp16"); +} + +OpenCLSiLUOp::~OpenCLSiLUOp() { + if (kernel_fp32_) clReleaseKernel(kernel_fp32_); + if (kernel_fp16_) clReleaseKernel(kernel_fp16_); +} + +ErrorCode OpenCLSiLUOp::reshape(vector> inputs, vector> outputs) { + // SiLU 是元素级操作,输出形状与输入形状完全相同 + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSiLUOp::setUp(vector> inputs, vector> outputs) { + // 确保输入在设备上,并为输出分配内存 + inputs[0]->to(MLLM_OPENCL); + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSiLUOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + const int count = input->count(); + + cl_kernel kernel_to_use = nullptr; + size_t global_work_size[1]; + const size_t *local_work_size_ptr = nullptr; + const size_t local_work_size[1] = {256}; // 典型的工作组大小 + + if (input->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_; + global_work_size[0] = count; + } else if (input->dtype() == MLLM_TYPE_F16) { + kernel_to_use = kernel_fp16_; + + // ✨ **核心修正**: 简化并修正启动配置 + // 我们只需要启动足够的线程来处理向量部分 + size_t vec_count = count / 4; + // 向上取整到工作组大小的倍数 + global_work_size[0] = ((vec_count + local_work_size[0] - 1) / local_work_size[0]) * local_work_size[0]; + // 如果元素总数少于一个工作组的大小,确保至少启动一个工作组 + if (global_work_size[0] == 0 && count > 0) { + global_work_size[0] = local_work_size[0]; + } + local_work_size_ptr = local_work_size; + + } else { + return NOT_SUPPORT; + } + + cl_mem in_buf = ocl_backend_->get_cl_mem(*input); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &out_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(int), &count); + + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, local_work_size_ptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "clEnqueueNDRangeKernel for SiLU"); + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSiLUOp.hpp b/src/backends/opencl/op/OpenCLSiLUOp.hpp new file mode 100644 index 000000000..cbd7c6679 --- /dev/null +++ b/src/backends/opencl/op/OpenCLSiLUOp.hpp @@ -0,0 +1,37 @@ +// 文件名: ops/OpenCLSiLUOp.hpp + +#ifndef OPENCL_SILU_OP_HPP +#define OPENCL_SILU_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLSiLUOp : public Op { +public: + OpenCLSiLUOp(Backend *bn, std::string name); + ~OpenCLSiLUOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + cl_kernel kernel_fp32_ = nullptr; + cl_kernel kernel_fp16_ = nullptr; + + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLSiLUOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // SiLU通常没有额外参数,但保留 op_param 以备将来扩展 + return new OpenCLSiLUOp(bn, name); + } +}; + +} // namespace mllm + +#endif // OPENCL_SILU_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSoftMaxOp.cpp b/src/backends/opencl/op/OpenCLSoftMaxOp.cpp new file mode 100644 index 000000000..5b2f55900 --- /dev/null +++ b/src/backends/opencl/op/OpenCLSoftMaxOp.cpp @@ -0,0 +1,113 @@ +#include "OpenCLSoftMaxOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLSoftMaxOp::OpenCLSoftMaxOp(Backend *bn, std::string name, int axis, bool do_causal_mask) : + Op(bn, std::move(name)), axis_(axis), do_causal_mask_(do_causal_mask) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + if (axis_ == DIMENSION) { + const std::string kernel_path = "kernel/softmax.cl"; + + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + + cl_int err; + + kernel_fp32_d_ = clCreateKernel(program, "softmax_f32_along_d", &err); + check_cl_error(err, "clCreateKernel for softmax_f32_along_d"); + + // 仅当硬件支持FP16时,才创建FP16内核 + // if (ocl_backend_->has_fp16_support()) { + kernel_fp16_d_ = clCreateKernel(program, "softmax_fp16_along_d", &err); + check_cl_error(err, "clCreateKernel for softmax_fp16_along_d"); + // } + } +} + +OpenCLSoftMaxOp::~OpenCLSoftMaxOp() { + if (kernel_fp32_d_) clReleaseKernel(kernel_fp32_d_); + if (kernel_fp16_d_) clReleaseKernel(kernel_fp16_d_); +} + +ErrorCode OpenCLSoftMaxOp::reshape(vector> inputs, vector> outputs) { + outputs[0]->setCtype(inputs[0]->ctype()); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSoftMaxOp::setUp(vector> inputs, vector> outputs) { + // 确保输入在设备上,并为输出分配内存 + for (auto &input : inputs) { + input->to(MLLM_OPENCL); + } + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSoftMaxOp::execute(vector> inputs, vector> outputs) { + if (axis_ != DIMENSION) { + throw std::runtime_error("OpenCLSoftMaxOp currently only supports axis=DIMENSION"); + } + + auto input = inputs[0]; + auto output = outputs[0]; + + cl_kernel kernel_to_use = nullptr; + if (input->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_d_; + } else if (input->dtype() == MLLM_TYPE_F16) { + // 如果fp16内核未创建成功(因为硬件不支持),这里会是nullptr + if (kernel_fp16_d_ == nullptr) { + throw std::runtime_error("FP16 Softmax kernel is not available on this device."); + } + kernel_to_use = kernel_fp16_d_; + } else { + return NOT_SUPPORT; + } + + const int B = input->batch(); + const int H = input->head(); + const int S = input->sequence(); + const int D = input->dimension(); + int do_causal_mask_int = do_causal_mask_ ? 1 : 0; + if (input->sequence() == 1) { + do_causal_mask_int = 0; + } + + cl_mem src_buf = ocl_backend_->get_cl_mem(*input); + cl_mem dst_buf = ocl_backend_->get_cl_mem(*output); + + // 设置所有内核参数 + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &src_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &dst_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(int), &B); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &H); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &S); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &D); + clSetKernelArg(kernel_to_use, 6, sizeof(int), &do_causal_mask_int); + + // --- 核心修正:修改内核启动配置 --- + const size_t total_rows = (size_t)B * H * S; + const size_t local_work_size = 256; // 每个工作组的线程数,必须与 .cl 文件中的 SOFTMAX_BLOCK_SIZE 一致 + + // 全局工作大小 = 总行数 * 每个工作组的线程数 + // 这会启动 total_rows 个工作组,每个组有 local_work_size 个线程 + const size_t global_work_size = total_rows * local_work_size; + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, &global_work_size, &local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name(), event); + check_cl_error(err, "clEnqueueNDRangeKernel for SoftMax"); + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSoftMaxOp.hpp b/src/backends/opencl/op/OpenCLSoftMaxOp.hpp new file mode 100644 index 000000000..834d30152 --- /dev/null +++ b/src/backends/opencl/op/OpenCLSoftMaxOp.hpp @@ -0,0 +1,40 @@ +#ifndef OPENCL_SOFTMAX_OP_HPP +#define OPENCL_SOFTMAX_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLSoftMaxOp : public Op { +public: + OpenCLSoftMaxOp(Backend *bn, std::string name, int axis, bool do_causal_mask); + ~OpenCLSoftMaxOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + int axis_ = 0; + bool do_causal_mask_ = false; + + cl_kernel kernel_fp32_d_ = nullptr; + cl_kernel kernel_fp16_d_ = nullptr; + + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLSoftMaxOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + int axis = op_param["axis"]; + bool do_causal_mask = op_param["do_causal_mask"]; + // threadCount is not used for OpenCL ops + return new OpenCLSoftMaxOp(bn, name, axis, do_causal_mask); + } +}; + +} // namespace mllm + +#endif // OPENCL_SOFTMAX_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSplitOp.cpp b/src/backends/opencl/op/OpenCLSplitOp.cpp new file mode 100644 index 000000000..8920e79be --- /dev/null +++ b/src/backends/opencl/op/OpenCLSplitOp.cpp @@ -0,0 +1,126 @@ +#include "OpenCLSplitOp.hpp" +#include "Types.hpp" +// #include "utils/OpenCLTools.hpp" +// #include + +namespace mllm { + +OpenCLSplitOp::OpenCLSplitOp(Backend *bn, std::string name, int num_splits, const std::vector &each_dims, Chl split_dim, int head_size) : + Op(bn, std::move(name)), num_splits_(num_splits), each_dims_(each_dims), split_dim_(split_dim), head_size_(head_size) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/split.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + kernel_fp32_ = clCreateKernel(program, "split_fp32", &err); + check_cl_error(err, "clCreateKernel for split_fp32"); + + kernel_fp16_ = clCreateKernel(program, "split_fp16", &err); + check_cl_error(err, "clCreateKernel for split_fp16"); +} + +OpenCLSplitOp::~OpenCLSplitOp() { + if (kernel_fp32_) clReleaseKernel(kernel_fp32_); + if (kernel_fp16_) clReleaseKernel(kernel_fp16_); +} + +ErrorCode OpenCLSplitOp::reshape(vector> inputs, vector> outputs) { + auto input = inputs[0]; + int split_dim_size = 0; + for (const auto &dim : each_dims_) { + split_dim_size += dim; + } + + for (int i = 0; i < num_splits_; ++i) { + switch (split_dim_) { + case Chl::HEAD: + outputs[i]->reshape(input->batch(), each_dims_[i], input->sequence(), input->dimension()); + break; + case Chl::SEQUENCE: + outputs[i]->reshape(input->batch(), input->head(), each_dims_[i], input->dimension()); + break; + case Chl::DIMENSION: + outputs[i]->reshape(input->batch(), input->head(), input->sequence(), each_dims_[i]); + break; + default: + return NOT_SUPPORT; + } + outputs[i]->setDtype(input->dtype()); + } + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSplitOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + for (auto &output : outputs) { + output->setDtype(inputs[0]->dtype()); + output->to(MLLM_OPENCL); + output->alloc(); + } + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSplitOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + + cl_kernel kernel_to_use = (input->dtype() == MLLM_TYPE_F32) ? kernel_fp32_ : kernel_fp16_; + + cl_mem in_buf = ocl_backend_->get_cl_mem(*input); + + std::vector offsets(num_splits_, 0); + for (int i = 1; i < num_splits_; ++i) { + offsets[i] = offsets[i - 1] + each_dims_[i - 1]; + } + + int outer_size = 1; + int inner_size = 1; + + switch (split_dim_) { + case Chl::HEAD: + outer_size = input->batch(); + inner_size = input->sequence() * input->dimension(); + break; + case Chl::SEQUENCE: + outer_size = input->batch() * input->head(); + inner_size = input->dimension(); + break; + case Chl::DIMENSION: + outer_size = input->batch() * input->head() * input->sequence(); + inner_size = 1; + break; + default: + return NOT_SUPPORT; + } + int dims = input->shape(split_dim_); + + for (int i = 0; i < num_splits_; ++i) { + cl_mem out_buf = ocl_backend_->get_cl_mem(*outputs[i]); + int split_dim_size = each_dims_[i]; + int offset = offsets[i]; + if (inner_size == 0 || split_dim_size == 0 || outer_size == 0) { + continue; + } + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &out_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(int), &outer_size); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &split_dim_size); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &inner_size); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &offset); + clSetKernelArg(kernel_to_use, 6, sizeof(int), &dims); + + const size_t global_work_size[3] = {(size_t)inner_size, (size_t)split_dim_size, (size_t)outer_size}; + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "split", event); + if (err != CL_SUCCESS) { + std::cout << "clEnqueueNDRangeKernel error: split" << inner_size << " " << split_dim_size << " " << outer_size << std::endl; + } + check_cl_error(err, "clEnqueueNDRangeKernel for Split"); + } + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSplitOp.hpp b/src/backends/opencl/op/OpenCLSplitOp.hpp new file mode 100644 index 000000000..fe8f31968 --- /dev/null +++ b/src/backends/opencl/op/OpenCLSplitOp.hpp @@ -0,0 +1,46 @@ +#ifndef OPENCL_SPLIT_OP_HPP +#define OPENCL_SPLIT_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" +#include + +namespace mllm { + +class OpenCLSplitOp : public Op { +public: + OpenCLSplitOp(Backend *bn, std::string name, int num_splits, const std::vector &each_dims, Chl split_dim, int head_size = 1); + ~OpenCLSplitOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + int num_splits_; + std::vector each_dims_; + int head_size_ = 1; + Chl split_dim_; + + cl_kernel kernel_fp32_ = nullptr; + cl_kernel kernel_fp16_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLSplitOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + int num_splits = static_cast(op_param.at("num_splits")); + std::vector each_dims; + for (int i = 0; i < num_splits; ++i) { + each_dims.push_back(static_cast(op_param.at("dim_" + std::to_string(i)))); + } + Chl split_dim = (Chl)op_param.at("split_dim"); + int head_size = static_cast(op_param.at("head_size")); + return new OpenCLSplitOp(bn, name, num_splits, each_dims, split_dim, head_size); + } +}; + +} // namespace mllm + +#endif // OPENCL_SPLIT_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSubOp.cpp b/src/backends/opencl/op/OpenCLSubOp.cpp new file mode 100644 index 000000000..ff436550e --- /dev/null +++ b/src/backends/opencl/op/OpenCLSubOp.cpp @@ -0,0 +1,128 @@ +#include "OpenCLSubOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +#include "backends/cpu/third_party/ggml/QuantizeFP16.hpp" + +namespace mllm { + +// 构造函数:与AddOp类似,但内核名称是硬编码的,所以我们仍然指向 "add.cl" +OpenCLSubOp::OpenCLSubOp(Backend *bn, std::string name, float data) : + Op(bn, std::move(name)), data_(data) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + // 复用 add.cl 内核文件 + const std::string kernel_path = "kernel/add.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + // 注意:我们创建的是 add_scalar_* 内核,因为我们将在内核中通过数学技巧实现减法 + kernel_fp32_buffer_ = clCreateKernel(program, "add_scalar_float", &err); + check_cl_error(err, "clCreateKernel for add_scalar_float (used by Sub)"); + + kernel_fp32_image_ = clCreateKernel(program, "add_scalar_float_image2d", &err); + check_cl_error(err, "clCreateKernel for add_scalar_float_image2d (used by Sub)"); + + kernel_fp16_buffer_ = clCreateKernel(program, "add_scalar_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for add_scalar_fp16_vector (used by Sub)"); + + kernel_fp16_image_ = clCreateKernel(program, "add_scalar_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for add_scalar_fp16_image2d (used by Sub)"); + + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +OpenCLSubOp::~OpenCLSubOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLSubOp::reshape(vector> inputs, vector> outputs) { + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSubOp::setUp(vector> inputs, vector> outputs) { + // 与 AddOp 逻辑相同 + inputs[0]->to(MLLM_OPENCL); + auto output = outputs[0]; + output->setDtype(inputs[0]->dtype()); + + auto &out_mem = output->device_memory(); + if (output->dimension() % 4 == 0 && false) { + out_mem.type = MEM_TYPE_IMAGE_2D; + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + out_mem.type = MEM_TYPE_BUFFER; + } + output->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSubOp::execute(vector> inputs, vector> outputs) { + auto input_dtype = inputs[0]->dtype(); + auto output = outputs[0]; + + // ✨ 核心技巧:A - B 等价于 A + (-B) + // 我们将要减去的标量取反,然后调用加法内核 + float neg_data = -data_; + + if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { + // Image 路径 + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_image_ : kernel_fp16_image_; + std::vector temp_tensor_storage; + cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); + cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); + if (input_dtype == MLLM_TYPE_F32) { + clSetKernelArg(kernel_to_use, 2, sizeof(float), &neg_data); + } else { + mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(neg_data); + clSetKernelArg(kernel_to_use, 2, sizeof(mllm_fp16_t), &data_fp16); + } + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); + + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + + } else { + // Buffer 路径 + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_buffer_ : kernel_fp16_buffer_; + cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + if (input_dtype == MLLM_TYPE_F32) { + clSetKernelArg(kernel_to_use, 1, sizeof(float), &neg_data); + } else { + mllm_fp16_t data_fp16 = MLLM_FP32_TO_FP16(neg_data); + clSetKernelArg(kernel_to_use, 1, sizeof(mllm_fp16_t), &data_fp16); + } + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + + size_t count = inputs[0]->count(); + if (input_dtype == MLLM_TYPE_F16) { count /= 4; } + + const size_t global_work_size[1] = {count}; + cl_event event; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "sub", event); + } + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSubOp.hpp b/src/backends/opencl/op/OpenCLSubOp.hpp new file mode 100644 index 000000000..8574f468d --- /dev/null +++ b/src/backends/opencl/op/OpenCLSubOp.hpp @@ -0,0 +1,42 @@ +#ifndef OPENCL_SUBTRACTION_OP_HPP +#define OPENCL_SUBTRACTION_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLSubOp : public Op { +public: + OpenCLSubOp(Backend *bn, std::string name, float data); + ~OpenCLSubOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + float data_; // 用于存储要减去的标量 + + cl_kernel kernel_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp16_buffer_ = nullptr; + cl_kernel kernel_fp16_image_ = nullptr; + + cl_sampler sampler_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +// OpenCLSubOp 的创建器 +class OpenCLSubOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // 从 op_param 中解析出要减去的标量数据 + float data = op_param["data"]; + return new OpenCLSubOp(bn, name, data); + } +}; + +} // namespace mllm + +#endif // OPENCL_SUBTRACTION_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSubTwoOp.cpp b/src/backends/opencl/op/OpenCLSubTwoOp.cpp new file mode 100644 index 000000000..66cc5d988 --- /dev/null +++ b/src/backends/opencl/op/OpenCLSubTwoOp.cpp @@ -0,0 +1,124 @@ +// 文件名: ops/OpenCLSubTwoOp.cpp + +#include "OpenCLSubTwoOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLSubTwoOp::OpenCLSubTwoOp(Backend *bn, std::string name) : + Op(bn, std::move(name)) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + // 关键:加载新的 sub.cl 内核文件 + const std::string kernel_path = "kernel/sub.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + // 关键:创建减法内核 + kernel_fp32_buffer_ = clCreateKernel(program, "sub_float", &err); + check_cl_error(err, "clCreateKernel for sub_float"); + + kernel_fp32_image_ = clCreateKernel(program, "sub_float_image2d", &err); + check_cl_error(err, "clCreateKernel for sub_float_image2d"); + + kernel_fp16_buffer_ = clCreateKernel(program, "sub_fp16_vector", &err); + check_cl_error(err, "clCreateKernel for sub_fp16_vector"); + + kernel_fp16_image_ = clCreateKernel(program, "sub_fp16_image2d", &err); + check_cl_error(err, "clCreateKernel for sub_fp16_image2d"); + + sampler_ = clCreateSampler(ocl_backend_->getContext(), CL_FALSE, CL_ADDRESS_CLAMP_TO_EDGE, CL_FILTER_NEAREST, &err); + check_cl_error(err, "clCreateSampler"); +} + +OpenCLSubTwoOp::~OpenCLSubTwoOp() { + if (kernel_fp32_buffer_) clReleaseKernel(kernel_fp32_buffer_); + if (kernel_fp32_image_) clReleaseKernel(kernel_fp32_image_); + if (kernel_fp16_buffer_) clReleaseKernel(kernel_fp16_buffer_); + if (kernel_fp16_image_) clReleaseKernel(kernel_fp16_image_); + if (sampler_) clReleaseSampler(sampler_); +} + +ErrorCode OpenCLSubTwoOp::reshape(vector> inputs, vector> outputs) { + // 形状逻辑与AddTwoOp相同 + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->sequence(), inputs[0]->dimension()); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSubTwoOp::setUp(vector> inputs, vector> outputs) { + // setUp逻辑与AddTwoOp相同 + for (auto &input : inputs) { + input->to(MLLM_OPENCL); + } + auto output = outputs[0]; + output->setDtype(inputs[0]->dtype()); + + auto &out_mem = output->device_memory(); + if (output->dimension() % 4 == 0 && false) { + out_mem.type = MEM_TYPE_IMAGE_2D; + out_mem.image_width = output->dimension() / 4; + out_mem.image_height = output->batch() * output->head() * output->sequence(); + } else { + out_mem.type = MEM_TYPE_BUFFER; + } + output->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSubTwoOp::execute(vector> inputs, vector> outputs) { + // 这里的逻辑与 AddTwoOp 完全相同,只是 kernel_to_use 指向的是减法内核 + auto input_dtype = inputs[0]->dtype(); + auto output = outputs[0]; + + if (output->device_memory().type == MEM_TYPE_IMAGE_2D) { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_image_ : kernel_fp16_image_; + + std::vector temp_tensor_storage; + cl_mem inA_mem = get_image_from_tensor(inputs[0], ocl_backend_, temp_tensor_storage); + cl_mem inB_mem = get_image_from_tensor(inputs[1], ocl_backend_, temp_tensor_storage); + cl_mem out_mem_handle = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_sampler), &sampler_); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &inA_mem); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &inB_mem); + clSetKernelArg(kernel_to_use, 3, sizeof(cl_mem), &out_mem_handle); + + const int width = static_cast(output->device_memory().image_width); + const int height = static_cast(output->device_memory().image_height); + + clSetKernelArg(kernel_to_use, 4, sizeof(int), &width); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &height); + + const size_t global_work_size[2] = {(size_t)width, (size_t)height}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + + } else { + cl_kernel kernel_to_use = (input_dtype == MLLM_TYPE_F32) ? kernel_fp32_buffer_ : kernel_fp16_buffer_; + + cl_mem in0_buf = ocl_backend_->get_cl_mem(*inputs[0]); + cl_mem in1_buf = ocl_backend_->get_cl_mem(*inputs[1]); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in0_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &in1_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &out_buf); + + size_t count = inputs[0]->count(); + if (input_dtype == MLLM_TYPE_F16) { + if (count % 4 != 0) { + throw std::runtime_error("[subTwo]For FP16 vector kernel, tensor count must be a multiple of 4."); + } + count /= 4; + } + + const size_t global_work_size[1] = {count}; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, global_work_size, nullptr, 0, nullptr, nullptr); + } + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSubTwoOp.hpp b/src/backends/opencl/op/OpenCLSubTwoOp.hpp new file mode 100644 index 000000000..0ecbd28b7 --- /dev/null +++ b/src/backends/opencl/op/OpenCLSubTwoOp.hpp @@ -0,0 +1,40 @@ +// 文件名: ops/OpenCLSubTwoOp.hpp + +#ifndef OPENCL_SUBTRACTION_TWO_OP_HPP +#define OPENCL_SUBTRACTION_TWO_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLSubTwoOp : public Op { +public: + OpenCLSubTwoOp(Backend *bn, std::string name); + ~OpenCLSubTwoOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + cl_kernel kernel_fp32_buffer_ = nullptr; + cl_kernel kernel_fp32_image_ = nullptr; + cl_kernel kernel_fp16_buffer_ = nullptr; + cl_kernel kernel_fp16_image_ = nullptr; + + cl_sampler sampler_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +// OpenCLSubTwoOp 的创建器 +class OpenCLSubTwoOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + return new OpenCLSubTwoOp(bn, name); + } +}; + +} // namespace mllm + +#endif // OPENCL_SUBTRACTION_TWO_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSumOp.cpp b/src/backends/opencl/op/OpenCLSumOp.cpp new file mode 100644 index 000000000..7592fdc44 --- /dev/null +++ b/src/backends/opencl/op/OpenCLSumOp.cpp @@ -0,0 +1,118 @@ +#include "OpenCLSumOp.hpp" +#include "Types.hpp" +// #include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLSumOp::OpenCLSumOp(Backend *bn, std::string name, Chl axis) : + Op(bn, std::move(name)), axis_(axis) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/sum.cl"; + + std::string build_options; + if (ocl_backend_->has_fp16_support()) { + build_options += " -DSUPPORTS_FP16"; + } + + cl_program program = ocl_backend_->getProgram(kernel_path, build_options); + + cl_int err; + kernel_fp32_ = clCreateKernel(program, "sum_fp32", &err); + check_cl_error(err, "clCreateKernel for sum_fp32"); + + kernel_fp16_ = clCreateKernel(program, "sum_fp16", &err); + check_cl_error(err, "clCreateKernel for sum_fp16"); +} + +OpenCLSumOp::~OpenCLSumOp() { + if (kernel_fp32_) clReleaseKernel(kernel_fp32_); + if (kernel_fp16_) clReleaseKernel(kernel_fp16_); +} + +ErrorCode OpenCLSumOp::reshape(vector> inputs, vector> outputs) { + int batch = inputs[0]->batch(); + int head = inputs[0]->head(); + int sequence = inputs[0]->sequence(); + int dimension = inputs[0]->dimension(); + + switch (axis_) { + case BATCH: batch = 1; break; + case HEAD: head = 1; break; + case SEQUENCE: sequence = 1; break; + case DIMENSION: dimension = 1; break; + default: break; + } + + outputs[0]->reshape(batch, head, sequence, dimension); + outputs[0]->setDtype(inputs[0]->dtype()); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSumOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLSumOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + + cl_kernel kernel_to_use = (input->dtype() == MLLM_TYPE_F32) ? kernel_fp32_ : kernel_fp16_; + + int outer_size = 1; + int inner_size = 1; + int reduce_size = 1; + + // 1. Get the actual memory index for the reduction axis + const int axis_mem_idx = input->chls().at(axis_); + + // 2. Get the total number of axes from the shape vector's size + const int num_axes = input->shape().size(); + + // 3. Calculate outer_size (product of dimensions before the reduction axis) + for (int i = 0; i < axis_mem_idx; ++i) { + outer_size *= input->legacyShape(i); + } + + // 4. Get the size of the reduction dimension + reduce_size = input->legacyShape(axis_mem_idx); + + // 5. Calculate inner_size (product of dimensions after the reduction axis) + for (int i = axis_mem_idx + 1; i < num_axes; ++i) { + inner_size *= input->legacyShape(i); + } + + cl_mem in_buf = ocl_backend_->get_cl_mem(*input); + cl_mem out_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &out_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(int), &outer_size); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &inner_size); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &reduce_size); + + // 1. 将 local_work_size 定义为二维数组 + const size_t local_work_size[2] = {256, 1}; // 第一个维度是规约并行度,第二个是1 + + // 2. 确保 global_work_size 的每个维度都是 local_work_size 对应维度的整数倍 + const size_t global_work_size[2] = { + (size_t)inner_size * local_work_size[0], + (size_t)outer_size * local_work_size[1] // outer_size * 1 + }; + // ============================================================== + + cl_event event; + // 3. 将二维的 local_work_size 数组传递给内核 + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, + global_work_size, local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "sum", event); + check_cl_error(err, "clEnqueueNDRangeKernel for Sum"); + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLSumOp.hpp b/src/backends/opencl/op/OpenCLSumOp.hpp new file mode 100644 index 000000000..d5c5b4bc9 --- /dev/null +++ b/src/backends/opencl/op/OpenCLSumOp.hpp @@ -0,0 +1,35 @@ +#ifndef OPENCL_SUM_OP_HPP +#define OPENCL_SUM_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLSumOp : public Op { +public: + OpenCLSumOp(Backend *bn, std::string name, Chl axis); + ~OpenCLSumOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + Chl axis_; + cl_kernel kernel_fp32_ = nullptr; + cl_kernel kernel_fp16_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLSumOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + Chl axis = (Chl)op_param.at("dim"); + return new OpenCLSumOp(bn, name, axis); + } +}; + +} // namespace mllm + +#endif // OPENCL_SUM_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLTopkOp.cpp b/src/backends/opencl/op/OpenCLTopkOp.cpp new file mode 100644 index 000000000..1ec406a3e --- /dev/null +++ b/src/backends/opencl/op/OpenCLTopkOp.cpp @@ -0,0 +1,92 @@ +#include "OpenCLTopkOp.hpp" +#include "Types.hpp" +// #include "utils/OpenCLTools.hpp" + +namespace mllm { + +OpenCLTopkOp::OpenCLTopkOp(Backend *bn, std::string name, int k, Chl dim) : + Op(bn, std::move(name)), k_(k), dim_(dim) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/topk.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + kernel_fp32_ = clCreateKernel(program, "topk_fp32", &err); + check_cl_error(err, "clCreateKernel for topk_fp32"); + + kernel_fp16_ = clCreateKernel(program, "topk_fp16", &err); + check_cl_error(err, "clCreateKernel for topk_fp16"); +} + +OpenCLTopkOp::~OpenCLTopkOp() { + if (kernel_fp32_) clReleaseKernel(kernel_fp32_); + if (kernel_fp16_) clReleaseKernel(kernel_fp16_); +} + +ErrorCode OpenCLTopkOp::reshape(vector> inputs, vector> outputs) { + if (dim_ != DIMENSION) { + return NOT_SUPPORT; + } + assert(outputs.size() == 2); // topk returns values and indices + + auto input = inputs[0]; + auto values_out = outputs[0]; + auto indices_out = outputs[1]; + + values_out->reshape(input->batch(), input->head(), input->sequence(), k_); + indices_out->reshape(input->batch(), input->head(), input->sequence(), k_); + + values_out->setDtype(input->dtype()); + // 虽然索引通常是整数,但为了简化和保持一致性,这里也使用与输入相同的数据类型 + indices_out->setDtype(input->dtype()); + + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLTopkOp::setUp(vector> inputs, vector> outputs) { + inputs[0]->to(MLLM_OPENCL); + for (auto &output : outputs) { + output->setDtype(inputs[0]->dtype()); + output->alloc(); + } + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLTopkOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto values_out = outputs[0]; + auto indices_out = outputs[1]; + + cl_kernel kernel_to_use = (input->dtype() == MLLM_TYPE_F32) ? kernel_fp32_ : kernel_fp16_; + + cl_mem in_buf = ocl_backend_->get_cl_mem(*input); + cl_mem values_buf = ocl_backend_->get_cl_mem(*values_out); + cl_mem indices_buf = ocl_backend_->get_cl_mem(*indices_out); + + const int B = input->batch(); + const int H = input->head(); + const int S = input->sequence(); + const int D = input->dimension(); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &in_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &values_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(cl_mem), &indices_buf); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &D); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &k_); + + // 启动一个工作组来处理每一行 + const size_t total_rows = (size_t)B * H * S; + const size_t local_work_size = 256; // 必须是2的幂,与内核中的 WG_SIZE 保持一致 + const size_t global_work_size = total_rows * local_work_size; + cl_event event; + cl_int err = clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 1, nullptr, + &global_work_size, &local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "topk", event); + check_cl_error(err, "clEnqueueNDRangeKernel for TopK"); + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLTopkOp.hpp b/src/backends/opencl/op/OpenCLTopkOp.hpp new file mode 100644 index 000000000..e1a222905 --- /dev/null +++ b/src/backends/opencl/op/OpenCLTopkOp.hpp @@ -0,0 +1,38 @@ +#ifndef OPENCL_TOPK_OP_HPP +#define OPENCL_TOPK_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLTopkOp : public Op { +public: + OpenCLTopkOp(Backend *bn, std::string name, int k, Chl dim); + ~OpenCLTopkOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + int k_; + Chl dim_; + + cl_kernel kernel_fp32_ = nullptr; + cl_kernel kernel_fp16_ = nullptr; + OpenCLBackend *ocl_backend_ = nullptr; +}; + +class OpenCLTopkOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + int k = static_cast(op_param.at("k")); + Chl dim = (Chl)op_param.at("dim"); + return new OpenCLTopkOp(bn, name, k, dim); + } +}; + +} // namespace mllm + +#endif // OPENCL_TOPK_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLTransposeOp.cpp b/src/backends/opencl/op/OpenCLTransposeOp.cpp new file mode 100644 index 000000000..654e01191 --- /dev/null +++ b/src/backends/opencl/op/OpenCLTransposeOp.cpp @@ -0,0 +1,176 @@ +#include "OpenCLTransposeOp.hpp" +#include "Types.hpp" +#include "utils/OpenCLTools.hpp" +#include + +namespace mllm { + +OpenCLTransposeOp::OpenCLTransposeOp(Backend *bn, std::string name, const vector> &axiss) : + Op(bn, std::move(name)), axiss_(axiss) { + ocl_backend_ = dynamic_cast(backend_); + if (ocl_backend_ == nullptr) throw std::runtime_error("Backend is not OpenCLBackend"); + + const std::string kernel_path = "kernel/transpose.cl"; + cl_program program = ocl_backend_->getProgram(kernel_path); + + cl_int err; + kernel_fp32_2d_ = clCreateKernel(program, "transpose_float_2d", &err); + check_cl_error(err, "clCreateKernel for transpose_float_2d"); + + kernel_fp16_2d_ = clCreateKernel(program, "transpose_fp16_2d", &err); + check_cl_error(err, "clCreateKernel for transpose_fp16_2d"); + + kernel_fp32_bshd_ = clCreateKernel(program, "transpose_bshd2bhsd_fp32", &err); + check_cl_error(err, "clCreateKernel for transpose_bshd2bhsd_fp32"); + kernel_fp16_bshd_ = clCreateKernel(program, "transpose_bshd2bhsd_fp16", &err); + check_cl_error(err, "clCreateKernel for transpose_bshd2bhsd_fp16"); + + kernel_fp32_bhsd_ = clCreateKernel(program, "transpose_bhsd2bshd_fp32", &err); + check_cl_error(err, "clCreateKernel for transpose_bhsd2bshd_fp32"); + kernel_fp16_bhsd_ = clCreateKernel(program, "transpose_bhsd2bshd_fp16", &err); + check_cl_error(err, "clCreateKernel for transpose_bhsd2bshd_fp16"); +} + +OpenCLTransposeOp::~OpenCLTransposeOp() { + if (kernel_fp32_2d_) clReleaseKernel(kernel_fp32_2d_); + if (kernel_fp16_2d_) clReleaseKernel(kernel_fp16_2d_); + if (kernel_fp32_bshd_) clReleaseKernel(kernel_fp32_bshd_); + if (kernel_fp16_bshd_) clReleaseKernel(kernel_fp16_bshd_); +} + +ErrorCode OpenCLTransposeOp::reshape(vector> inputs, vector> outputs) { + // Transpose on BHSD -> BHDS (swapping Sequence and Dimension) + if (axiss_.size() == 1 && axiss_[0].first == SEQUENCE && axiss_[0].second == DIMENSION && inputs[0]->ctype() == BHSD) { + outputs[0]->setCtype(BHSD); + outputs[0]->setDtype(inputs[0]->dtype()); + outputs[0]->reshape(inputs[0]->batch(), inputs[0]->head(), inputs[0]->dimension(), inputs[0]->sequence()); + } else if (axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { + // H,S 转置 (BSHD -> BHSD) + auto input = inputs[0]; + auto output = outputs[0]; + // 这一步是元数据变换,定义逻辑形状 + output->transCopyShape(input->shape()); + output->chls() = input->chls(); + std::swap(output->chls()[HEAD], output->chls()[SEQUENCE]); + output->changeCtype(input->shape().size()); + // 物理形状与输入保持一致,因为将在execute中进行物理拷贝 + output->reshape(input->batch(), input->head(), input->sequence(), input->dimension()); + } else { + std::cerr << "error reshape" << std::endl; + } + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLTransposeOp::setUp(vector> inputs, vector> outputs) { + // 确保输入和输出的数据类型一致 + outputs[0]->setDtype(inputs[0]->dtype()); + + // 将输入张量的数据转移到OpenCL设备 + for (auto &input : inputs) { + input->to(MLLM_OPENCL); + } + + // 为输出张量分配内存,您的框架会根据分页策略进行管理 + outputs[0]->alloc(); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLTransposeOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + + cl_mem parent_src_buffer = ocl_backend_->get_cl_mem(*input); + cl_mem parent_dst_buffer = ocl_backend_->get_cl_mem(*output); + cl_int err; + + // === 新增: 处理 H,S 轴转置的逻辑分支 === + if (axiss_.size() == 1 && axiss_[0].first == HEAD && axiss_[0].second == SEQUENCE) { + cl_kernel kernel_to_use = nullptr; + if (input->ctype() == BSHD) { // BSHD -> BHSD + if (input->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_bshd_; + } else { + kernel_to_use = kernel_fp16_bshd_; + } + } else if (input->ctype() == BHSD) { // BHSD -> BSHD + if (input->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_bhsd_; + } else { + kernel_to_use = kernel_fp16_bhsd_; + } + } else { + return NOT_SUPPORT; + } + const int B = input->batch(); + const int H = input->head(); + const int S = input->sequence(); + const int D = input->dimension(); + + cl_mem src_buf = ocl_backend_->get_cl_mem(*input); + cl_mem dst_buf = ocl_backend_->get_cl_mem(*output); + + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &src_buf); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &dst_buf); + clSetKernelArg(kernel_to_use, 2, sizeof(int), &B); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &H); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &S); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &D); + + const size_t global_work_size[3] = {(size_t)D, (size_t)S, (size_t)H * B}; + cl_event event; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 3, nullptr, global_work_size, nullptr, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "transpose", event); + } + // === 处理 S,D 轴转置的逻辑保持不变 === + else if (axiss_.size() == 1 && axiss_[0].first == SEQUENCE && axiss_[0].second == DIMENSION && inputs[0]->ctype() == BHSD) { + cl_kernel kernel_to_use = nullptr; + size_t element_size = 0; + if (input->dtype() == MLLM_TYPE_F32) { + kernel_to_use = kernel_fp32_2d_; + element_size = sizeof(float); + } else if (input->dtype() == MLLM_TYPE_F16) { + kernel_to_use = kernel_fp16_2d_; + element_size = sizeof(mllm_fp16_t); + } else { + return NOT_SUPPORT; + } + for (int b = 0; b < input->batch(); ++b) { + for (int h = 0; h < input->head(); ++h) { + const int S = input->sequence(); + const int D = input->dimension(); + + // 计算偏移量(以元素数量为单位) + int src_offset_elements = (b * input->head() + h) * S * D; + int dst_offset_elements = (b * output->head() + h) * D * S; + + // 不再创建 SubBuffer + // clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &src_sub_buffer); + // clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &dst_sub_buffer); + + // 传递父缓冲区和偏移量 + clSetKernelArg(kernel_to_use, 0, sizeof(cl_mem), &parent_src_buffer); + clSetKernelArg(kernel_to_use, 1, sizeof(cl_mem), &parent_dst_buffer); + clSetKernelArg(kernel_to_use, 2, sizeof(int), &S); + clSetKernelArg(kernel_to_use, 3, sizeof(int), &D); + clSetKernelArg(kernel_to_use, 4, sizeof(int), &src_offset_elements); + clSetKernelArg(kernel_to_use, 5, sizeof(int), &dst_offset_elements); + + const size_t block_dim = 16; + const size_t global_work_size[2] = { + (size_t)D + ((block_dim - (size_t)D % block_dim) % block_dim), + (size_t)S + ((block_dim - (size_t)S % block_dim) % block_dim)}; + const size_t local_work_size[2] = {block_dim, block_dim}; + cl_event event; + clEnqueueNDRangeKernel(ocl_backend_->getQueue(), kernel_to_use, 2, nullptr, global_work_size, local_work_size, 0, nullptr, &event); + ocl_backend_->addProfilingEvent(this->name() + "transpose", event); + } + } + } else { + std::cerr << "OpenCLTransposeOp execute error: unsupported transpose axis or ctype" << std::endl; + return NOT_SUPPORT; + } + + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLTransposeOp.hpp b/src/backends/opencl/op/OpenCLTransposeOp.hpp new file mode 100644 index 000000000..47213b5c7 --- /dev/null +++ b/src/backends/opencl/op/OpenCLTransposeOp.hpp @@ -0,0 +1,49 @@ +#ifndef OPENCL_TRANSPOSE_FUNC_OP_HPP +#define OPENCL_TRANSPOSE_FUNC_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLTransposeOp : public Op { +public: + OpenCLTransposeOp(Backend *bn, std::string name, const vector> &axiss); + ~OpenCLTransposeOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + cl_kernel kernel_fp32_2d_ = nullptr; + cl_kernel kernel_fp16_2d_ = nullptr; + + cl_kernel kernel_fp32_bshd_ = nullptr; + cl_kernel kernel_fp16_bshd_ = nullptr; + + cl_kernel kernel_fp32_bhsd_ = nullptr; + cl_kernel kernel_fp16_bhsd_ = nullptr; + + OpenCLBackend *ocl_backend_ = nullptr; + vector> axiss_; +}; + +class OpenCLTransposeOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // Example: {"num_pairs": 1, "axis1_0": 2, "axis2_0": 1} (HEAD, SEQUENCE) + int num_pairs = static_cast(op_param.at("num_pairs")); + vector> axiss; + for (int i = 0; i < num_pairs; ++i) { + Chl axis1 = (Chl)op_param.at("axis1_" + std::to_string(i)); + Chl axis2 = (Chl)op_param.at("axis2_" + std::to_string(i)); + axiss.push_back({axis1, axis2}); + } + return new OpenCLTransposeOp(bn, name, axiss); + } +}; + +} // namespace mllm + +#endif // OPENCL_TRANSPOSE_FUNC_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLViewOp.cpp b/src/backends/opencl/op/OpenCLViewOp.cpp new file mode 100644 index 000000000..5b358fc56 --- /dev/null +++ b/src/backends/opencl/op/OpenCLViewOp.cpp @@ -0,0 +1,105 @@ +#include "OpenCLViewOp.hpp" +#include "Types.hpp" +// #include "utils/OpenCLTools.hpp" +#include +#include + +namespace mllm { + +OpenCLViewOp::OpenCLViewOp(Backend *bn, std::string name, int b, int h, int s, int d) : + Op(bn, std::move(name)), b(b), h(h), s(s), d(d) { +} + +OpenCLViewOp::~OpenCLViewOp() { +} + +ErrorCode OpenCLViewOp::reshape(vector> inputs, vector> outputs) { + int dim_b = inputs[0]->batch(); + int dim_h = inputs[0]->head(); + int dim_s = inputs[0]->sequence(); + int dim_d = inputs[0]->dimension(); + if (b == -1 && h == 1 && s == 1 && d == -1) { // sequence & head & dimension -> dimension + dim_s = 1; + dim_h = 1; + dim_d = inputs[0]->sequence() * inputs[0]->head() * inputs[0]->dimension(); + } else if (b == -1 && h == -1 && s == 1 && d == 1) { // sequence & head & dimension -> sequence + dim_s = inputs[0]->sequence() * inputs[0]->head() * inputs[0]->dimension(); + dim_h = 1; + dim_d = 1; + } else if (b == 1 && h == 1 && s == -1 && d != -1 && inputs[0]->ctype() == BCTHW) { // batch & head & sequence -> sequence + dim_b = 1; + dim_s = inputs[0]->channel() * inputs[0]->time() * inputs[0]->batch() * inputs[0]->height() * inputs[0]->width() / d; + dim_h = 1; + dim_d = d; + } else if (b == 1 && h == 1 && s == -1 && d != -1) { // batch & head & sequence -> sequence + dim_b = 1; + dim_s = inputs[0]->sequence() * inputs[0]->batch() * inputs[0]->head() * inputs[0]->dimension() / d; + dim_h = 1; + dim_d = d; + } else if (b == -1 && h != -1 && s == -1 && d != -1) { // head & dimension + if (h != ANYDIM && d != ANYDIM) { + assert(inputs[0]->dimension() * inputs[0]->head() == h * d); + dim_h = h; + dim_d = d; + } else if (h != ANYDIM) { + dim_h = h; + dim_d = inputs[0]->dimension() * inputs[0]->head() / h; + } else if (d != ANYDIM) { + dim_h = inputs[0]->dimension() * inputs[0]->head() / d; + dim_d = d; + } else { + std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + } + } else if (b == -1 && h != -1 && s != -1 && d == -1) { // head & sequence + if (h != ANYDIM && s != ANYDIM) { + assert(inputs[0]->sequence() * inputs[0]->head() == h * s); + dim_h = h; + dim_s = s; + } else if (h != ANYDIM) { + dim_h = h; + dim_s = inputs[0]->sequence() * inputs[0]->head() / h; + } else if (s != ANYDIM) { + dim_h = inputs[0]->sequence() * inputs[0]->head() / s; + dim_s = s; + } else { + std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + } + } else if (b != -1 && h == -1 && s != -1 && d == -1) { // batch & sequence + if (b != ANYDIM && s != ANYDIM) { + assert(inputs[0]->sequence() * inputs[0]->batch() == b * s); + dim_b = b; + dim_s = s; + } else if (b != ANYDIM) { + dim_b = b; + dim_s = inputs[0]->sequence() * inputs[0]->batch() / b; + } else if (s != ANYDIM) { + dim_b = inputs[0]->sequence() * inputs[0]->batch() / s; + dim_s = s; + } else { + std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + } + } else { + std::cout << "[TODO]Tensor.View not support!!!!" << std::endl; + } + if (inputs[0]->ctype() == BCTHW && inputs[0]->name() == outputs[0]->name()) { + outputs[0]->setCtype(BSHD); + } + outputs[0]->reshape(dim_b, dim_h, dim_s, dim_d); + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLViewOp::setUp(vector> inputs, vector> outputs) { + assert(inputs[0]->backend()->type() == MLLM_OPENCL); + if (inputs[0]->sequence() > 0) { + assert(inputs[0] == outputs[0]); + } + return MLLM_NO_ERROR; +} + +ErrorCode OpenCLViewOp::execute(vector> inputs, vector> outputs) { + auto input = inputs[0]; + auto output = outputs[0]; + return MLLM_NO_ERROR; +} + +} // namespace mllm \ No newline at end of file diff --git a/src/backends/opencl/op/OpenCLViewOp.hpp b/src/backends/opencl/op/OpenCLViewOp.hpp new file mode 100644 index 000000000..0ea575698 --- /dev/null +++ b/src/backends/opencl/op/OpenCLViewOp.hpp @@ -0,0 +1,37 @@ +#ifndef OPENCL_VIEW_OP_HPP +#define OPENCL_VIEW_OP_HPP + +#include "Op.hpp" +#include "../OpenCLBackend.hpp" + +namespace mllm { + +class OpenCLViewOp : public Op { +public: + OpenCLViewOp(Backend *bn, std::string name, int b, int h, int s, int d); + ~OpenCLViewOp() override; + + ErrorCode reshape(vector> inputs, vector> outputs) override; + ErrorCode setUp(vector> inputs, vector> outputs) override; + ErrorCode execute(vector> inputs, vector> outputs) override; + +private: + int b, h, s, d; +}; + +// OpenCLViewOp 的创建器 +class OpenCLViewOpCreator : public OpenCLBackend::Creator { +public: + Op *create(OpParam op_param, Backend *bn, string name, int threadCount) const override { + // 从 op_param 中解析出要减去的标量数据 + int b = static_cast(op_param.at("b")); + int h = static_cast(op_param.at("h")); + int s = static_cast(op_param.at("s")); + int d = static_cast(op_param.at("d")); + return new OpenCLViewOp(bn, name, b, h, s, d); + } +}; + +} // namespace mllm + +#endif // OPENCL_VIEW_OP_HPP \ No newline at end of file diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl.h new file mode 100644 index 000000000..d55772019 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl.h @@ -0,0 +1,1920 @@ +/******************************************************************************* + * Copyright (c) 2008-2020 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef __OPENCL_CL_H +#define __OPENCL_CL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) && defined(_MSC_VER) && __CL_HAS_ANON_STRUCT__ + /* Disable warning C4201: nonstandard extension used : nameless struct/union */ + #pragma warning( push ) + #pragma warning( disable : 4201 ) +#endif + +/******************************************************************************/ + +typedef struct _cl_platform_id * cl_platform_id; +typedef struct _cl_device_id * cl_device_id; +typedef struct _cl_context * cl_context; +typedef struct _cl_command_queue * cl_command_queue; +typedef struct _cl_mem * cl_mem; +typedef struct _cl_program * cl_program; +typedef struct _cl_kernel * cl_kernel; +typedef struct _cl_event * cl_event; +typedef struct _cl_sampler * cl_sampler; + +typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */ +typedef cl_ulong cl_bitfield; +typedef cl_ulong cl_properties; +typedef cl_bitfield cl_device_type; +typedef cl_uint cl_platform_info; +typedef cl_uint cl_device_info; +typedef cl_bitfield cl_device_fp_config; +typedef cl_uint cl_device_mem_cache_type; +typedef cl_uint cl_device_local_mem_type; +typedef cl_bitfield cl_device_exec_capabilities; +#ifdef CL_VERSION_2_0 +typedef cl_bitfield cl_device_svm_capabilities; +#endif +typedef cl_bitfield cl_command_queue_properties; +#ifdef CL_VERSION_1_2 +typedef intptr_t cl_device_partition_property; +typedef cl_bitfield cl_device_affinity_domain; +#endif + +typedef intptr_t cl_context_properties; +typedef cl_uint cl_context_info; +#ifdef CL_VERSION_2_0 +typedef cl_properties cl_queue_properties; +#endif +typedef cl_uint cl_command_queue_info; +typedef cl_uint cl_channel_order; +typedef cl_uint cl_channel_type; +typedef cl_bitfield cl_mem_flags; +#ifdef CL_VERSION_2_0 +typedef cl_bitfield cl_svm_mem_flags; +#endif +typedef cl_uint cl_mem_object_type; +typedef cl_uint cl_mem_info; +#ifdef CL_VERSION_1_2 +typedef cl_bitfield cl_mem_migration_flags; +#endif +typedef cl_uint cl_image_info; +#ifdef CL_VERSION_1_1 +typedef cl_uint cl_buffer_create_type; +#endif +typedef cl_uint cl_addressing_mode; +typedef cl_uint cl_filter_mode; +typedef cl_uint cl_sampler_info; +typedef cl_bitfield cl_map_flags; +#ifdef CL_VERSION_2_0 +typedef intptr_t cl_pipe_properties; +typedef cl_uint cl_pipe_info; +#endif +typedef cl_uint cl_program_info; +typedef cl_uint cl_program_build_info; +#ifdef CL_VERSION_1_2 +typedef cl_uint cl_program_binary_type; +#endif +typedef cl_int cl_build_status; +typedef cl_uint cl_kernel_info; +#ifdef CL_VERSION_1_2 +typedef cl_uint cl_kernel_arg_info; +typedef cl_uint cl_kernel_arg_address_qualifier; +typedef cl_uint cl_kernel_arg_access_qualifier; +typedef cl_bitfield cl_kernel_arg_type_qualifier; +#endif +typedef cl_uint cl_kernel_work_group_info; +#ifdef CL_VERSION_2_1 +typedef cl_uint cl_kernel_sub_group_info; +#endif +typedef cl_uint cl_event_info; +typedef cl_uint cl_command_type; +typedef cl_uint cl_profiling_info; +#ifdef CL_VERSION_2_0 +typedef cl_properties cl_sampler_properties; +typedef cl_uint cl_kernel_exec_info; +#endif +#ifdef CL_VERSION_3_0 +typedef cl_bitfield cl_device_atomic_capabilities; +typedef cl_bitfield cl_device_device_enqueue_capabilities; +typedef cl_uint cl_khronos_vendor_id; +typedef cl_properties cl_mem_properties; +#endif +typedef cl_uint cl_version; + +typedef struct _cl_image_format { + cl_channel_order image_channel_order; + cl_channel_type image_channel_data_type; +} cl_image_format; + +#ifdef CL_VERSION_1_2 + +typedef struct _cl_image_desc { + cl_mem_object_type image_type; + size_t image_width; + size_t image_height; + size_t image_depth; + size_t image_array_size; + size_t image_row_pitch; + size_t image_slice_pitch; + cl_uint num_mip_levels; + cl_uint num_samples; +#if defined(CL_VERSION_2_0) && __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ union { +#endif + cl_mem buffer; +#if defined(CL_VERSION_2_0) && __CL_HAS_ANON_STRUCT__ + cl_mem mem_object; + }; +#endif +} cl_image_desc; + +#endif + +#ifdef CL_VERSION_1_1 + +typedef struct _cl_buffer_region { + size_t origin; + size_t size; +} cl_buffer_region; + +#endif + +#ifdef CL_VERSION_3_0 + +#define CL_NAME_VERSION_MAX_NAME_SIZE 64 + +typedef struct _cl_name_version { + cl_version version; + char name[CL_NAME_VERSION_MAX_NAME_SIZE]; +} cl_name_version; + +#endif + +/******************************************************************************/ + +/* Error Codes */ +#define CL_SUCCESS 0 +#define CL_DEVICE_NOT_FOUND -1 +#define CL_DEVICE_NOT_AVAILABLE -2 +#define CL_COMPILER_NOT_AVAILABLE -3 +#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4 +#define CL_OUT_OF_RESOURCES -5 +#define CL_OUT_OF_HOST_MEMORY -6 +#define CL_PROFILING_INFO_NOT_AVAILABLE -7 +#define CL_MEM_COPY_OVERLAP -8 +#define CL_IMAGE_FORMAT_MISMATCH -9 +#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10 +#define CL_BUILD_PROGRAM_FAILURE -11 +#define CL_MAP_FAILURE -12 +#ifdef CL_VERSION_1_1 +#define CL_MISALIGNED_SUB_BUFFER_OFFSET -13 +#define CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST -14 +#endif +#ifdef CL_VERSION_1_2 +#define CL_COMPILE_PROGRAM_FAILURE -15 +#define CL_LINKER_NOT_AVAILABLE -16 +#define CL_LINK_PROGRAM_FAILURE -17 +#define CL_DEVICE_PARTITION_FAILED -18 +#define CL_KERNEL_ARG_INFO_NOT_AVAILABLE -19 +#endif + +#define CL_INVALID_VALUE -30 +#define CL_INVALID_DEVICE_TYPE -31 +#define CL_INVALID_PLATFORM -32 +#define CL_INVALID_DEVICE -33 +#define CL_INVALID_CONTEXT -34 +#define CL_INVALID_QUEUE_PROPERTIES -35 +#define CL_INVALID_COMMAND_QUEUE -36 +#define CL_INVALID_HOST_PTR -37 +#define CL_INVALID_MEM_OBJECT -38 +#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39 +#define CL_INVALID_IMAGE_SIZE -40 +#define CL_INVALID_SAMPLER -41 +#define CL_INVALID_BINARY -42 +#define CL_INVALID_BUILD_OPTIONS -43 +#define CL_INVALID_PROGRAM -44 +#define CL_INVALID_PROGRAM_EXECUTABLE -45 +#define CL_INVALID_KERNEL_NAME -46 +#define CL_INVALID_KERNEL_DEFINITION -47 +#define CL_INVALID_KERNEL -48 +#define CL_INVALID_ARG_INDEX -49 +#define CL_INVALID_ARG_VALUE -50 +#define CL_INVALID_ARG_SIZE -51 +#define CL_INVALID_KERNEL_ARGS -52 +#define CL_INVALID_WORK_DIMENSION -53 +#define CL_INVALID_WORK_GROUP_SIZE -54 +#define CL_INVALID_WORK_ITEM_SIZE -55 +#define CL_INVALID_GLOBAL_OFFSET -56 +#define CL_INVALID_EVENT_WAIT_LIST -57 +#define CL_INVALID_EVENT -58 +#define CL_INVALID_OPERATION -59 +#define CL_INVALID_GL_OBJECT -60 +#define CL_INVALID_BUFFER_SIZE -61 +#define CL_INVALID_MIP_LEVEL -62 +#define CL_INVALID_GLOBAL_WORK_SIZE -63 +#ifdef CL_VERSION_1_1 +#define CL_INVALID_PROPERTY -64 +#endif +#ifdef CL_VERSION_1_2 +#define CL_INVALID_IMAGE_DESCRIPTOR -65 +#define CL_INVALID_COMPILER_OPTIONS -66 +#define CL_INVALID_LINKER_OPTIONS -67 +#define CL_INVALID_DEVICE_PARTITION_COUNT -68 +#endif +#ifdef CL_VERSION_2_0 +#define CL_INVALID_PIPE_SIZE -69 +#define CL_INVALID_DEVICE_QUEUE -70 +#endif +#ifdef CL_VERSION_2_2 +#define CL_INVALID_SPEC_ID -71 +#define CL_MAX_SIZE_RESTRICTION_EXCEEDED -72 +#endif + + +/* cl_bool */ +#define CL_FALSE 0 +#define CL_TRUE 1 +#ifdef CL_VERSION_1_2 +#define CL_BLOCKING CL_TRUE +#define CL_NON_BLOCKING CL_FALSE +#endif + +/* cl_platform_info */ +#define CL_PLATFORM_PROFILE 0x0900 +#define CL_PLATFORM_VERSION 0x0901 +#define CL_PLATFORM_NAME 0x0902 +#define CL_PLATFORM_VENDOR 0x0903 +#define CL_PLATFORM_EXTENSIONS 0x0904 +#ifdef CL_VERSION_2_1 +#define CL_PLATFORM_HOST_TIMER_RESOLUTION 0x0905 +#endif +#ifdef CL_VERSION_3_0 +#define CL_PLATFORM_NUMERIC_VERSION 0x0906 +#define CL_PLATFORM_EXTENSIONS_WITH_VERSION 0x0907 +#endif + +/* cl_device_type - bitfield */ +#define CL_DEVICE_TYPE_DEFAULT (1 << 0) +#define CL_DEVICE_TYPE_CPU (1 << 1) +#define CL_DEVICE_TYPE_GPU (1 << 2) +#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3) +#ifdef CL_VERSION_1_2 +#define CL_DEVICE_TYPE_CUSTOM (1 << 4) +#endif +#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF + +/* cl_device_info */ +#define CL_DEVICE_TYPE 0x1000 +#define CL_DEVICE_VENDOR_ID 0x1001 +#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002 +#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003 +#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004 +#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B +#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C +#define CL_DEVICE_ADDRESS_BITS 0x100D +#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E +#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F +#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010 +#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011 +#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012 +#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013 +#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014 +#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015 +#define CL_DEVICE_IMAGE_SUPPORT 0x1016 +#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017 +#define CL_DEVICE_MAX_SAMPLERS 0x1018 +#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019 +#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A +#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B +#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C +#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D +#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E +#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F +#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020 +#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021 +#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022 +#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023 +#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024 +#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025 +#define CL_DEVICE_ENDIAN_LITTLE 0x1026 +#define CL_DEVICE_AVAILABLE 0x1027 +#define CL_DEVICE_COMPILER_AVAILABLE 0x1028 +#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029 +#define CL_DEVICE_QUEUE_PROPERTIES 0x102A /* deprecated */ +#ifdef CL_VERSION_2_0 +#define CL_DEVICE_QUEUE_ON_HOST_PROPERTIES 0x102A +#endif +#define CL_DEVICE_NAME 0x102B +#define CL_DEVICE_VENDOR 0x102C +#define CL_DRIVER_VERSION 0x102D +#define CL_DEVICE_PROFILE 0x102E +#define CL_DEVICE_VERSION 0x102F +#define CL_DEVICE_EXTENSIONS 0x1030 +#define CL_DEVICE_PLATFORM 0x1031 +#ifdef CL_VERSION_1_2 +#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032 +#endif +/* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG which is already defined in "cl_ext.h" */ +#ifdef CL_VERSION_1_1 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034 +#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035 /* deprecated */ +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C +#define CL_DEVICE_OPENCL_C_VERSION 0x103D +#endif +#ifdef CL_VERSION_1_2 +#define CL_DEVICE_LINKER_AVAILABLE 0x103E +#define CL_DEVICE_BUILT_IN_KERNELS 0x103F +#define CL_DEVICE_IMAGE_MAX_BUFFER_SIZE 0x1040 +#define CL_DEVICE_IMAGE_MAX_ARRAY_SIZE 0x1041 +#define CL_DEVICE_PARENT_DEVICE 0x1042 +#define CL_DEVICE_PARTITION_MAX_SUB_DEVICES 0x1043 +#define CL_DEVICE_PARTITION_PROPERTIES 0x1044 +#define CL_DEVICE_PARTITION_AFFINITY_DOMAIN 0x1045 +#define CL_DEVICE_PARTITION_TYPE 0x1046 +#define CL_DEVICE_REFERENCE_COUNT 0x1047 +#define CL_DEVICE_PREFERRED_INTEROP_USER_SYNC 0x1048 +#define CL_DEVICE_PRINTF_BUFFER_SIZE 0x1049 +#endif +#ifdef CL_VERSION_2_0 +#define CL_DEVICE_IMAGE_PITCH_ALIGNMENT 0x104A +#define CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT 0x104B +#define CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS 0x104C +#define CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE 0x104D +#define CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES 0x104E +#define CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE 0x104F +#define CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE 0x1050 +#define CL_DEVICE_MAX_ON_DEVICE_QUEUES 0x1051 +#define CL_DEVICE_MAX_ON_DEVICE_EVENTS 0x1052 +#define CL_DEVICE_SVM_CAPABILITIES 0x1053 +#define CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE 0x1054 +#define CL_DEVICE_MAX_PIPE_ARGS 0x1055 +#define CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS 0x1056 +#define CL_DEVICE_PIPE_MAX_PACKET_SIZE 0x1057 +#define CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT 0x1058 +#define CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT 0x1059 +#define CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT 0x105A +#endif +#ifdef CL_VERSION_2_1 +#define CL_DEVICE_IL_VERSION 0x105B +#define CL_DEVICE_MAX_NUM_SUB_GROUPS 0x105C +#define CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS 0x105D +#endif +#ifdef CL_VERSION_3_0 +#define CL_DEVICE_NUMERIC_VERSION 0x105E +#define CL_DEVICE_EXTENSIONS_WITH_VERSION 0x1060 +#define CL_DEVICE_ILS_WITH_VERSION 0x1061 +#define CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION 0x1062 +#define CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES 0x1063 +#define CL_DEVICE_ATOMIC_FENCE_CAPABILITIES 0x1064 +#define CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT 0x1065 +#define CL_DEVICE_OPENCL_C_ALL_VERSIONS 0x1066 +#define CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x1067 +#define CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT 0x1068 +#define CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT 0x1069 +/* 0x106A to 0x106E - Reserved for upcoming KHR extension */ +#define CL_DEVICE_OPENCL_C_FEATURES 0x106F +#define CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES 0x1070 +#define CL_DEVICE_PIPE_SUPPORT 0x1071 +#define CL_DEVICE_LATEST_CONFORMANCE_VERSION_PASSED 0x1072 +#endif + +/* cl_device_fp_config - bitfield */ +#define CL_FP_DENORM (1 << 0) +#define CL_FP_INF_NAN (1 << 1) +#define CL_FP_ROUND_TO_NEAREST (1 << 2) +#define CL_FP_ROUND_TO_ZERO (1 << 3) +#define CL_FP_ROUND_TO_INF (1 << 4) +#define CL_FP_FMA (1 << 5) +#ifdef CL_VERSION_1_1 +#define CL_FP_SOFT_FLOAT (1 << 6) +#endif +#ifdef CL_VERSION_1_2 +#define CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT (1 << 7) +#endif + +/* cl_device_mem_cache_type */ +#define CL_NONE 0x0 +#define CL_READ_ONLY_CACHE 0x1 +#define CL_READ_WRITE_CACHE 0x2 + +/* cl_device_local_mem_type */ +#define CL_LOCAL 0x1 +#define CL_GLOBAL 0x2 + +/* cl_device_exec_capabilities - bitfield */ +#define CL_EXEC_KERNEL (1 << 0) +#define CL_EXEC_NATIVE_KERNEL (1 << 1) + +/* cl_command_queue_properties - bitfield */ +#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0) +#define CL_QUEUE_PROFILING_ENABLE (1 << 1) +#ifdef CL_VERSION_2_0 +#define CL_QUEUE_ON_DEVICE (1 << 2) +#define CL_QUEUE_ON_DEVICE_DEFAULT (1 << 3) +#endif + +/* cl_context_info */ +#define CL_CONTEXT_REFERENCE_COUNT 0x1080 +#define CL_CONTEXT_DEVICES 0x1081 +#define CL_CONTEXT_PROPERTIES 0x1082 +#ifdef CL_VERSION_1_1 +#define CL_CONTEXT_NUM_DEVICES 0x1083 +#endif + +/* cl_context_properties */ +#define CL_CONTEXT_PLATFORM 0x1084 +#ifdef CL_VERSION_1_2 +#define CL_CONTEXT_INTEROP_USER_SYNC 0x1085 +#endif + +#ifdef CL_VERSION_1_2 + +/* cl_device_partition_property */ +#define CL_DEVICE_PARTITION_EQUALLY 0x1086 +#define CL_DEVICE_PARTITION_BY_COUNTS 0x1087 +#define CL_DEVICE_PARTITION_BY_COUNTS_LIST_END 0x0 +#define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN 0x1088 + +#endif + +#ifdef CL_VERSION_1_2 + +/* cl_device_affinity_domain */ +#define CL_DEVICE_AFFINITY_DOMAIN_NUMA (1 << 0) +#define CL_DEVICE_AFFINITY_DOMAIN_L4_CACHE (1 << 1) +#define CL_DEVICE_AFFINITY_DOMAIN_L3_CACHE (1 << 2) +#define CL_DEVICE_AFFINITY_DOMAIN_L2_CACHE (1 << 3) +#define CL_DEVICE_AFFINITY_DOMAIN_L1_CACHE (1 << 4) +#define CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE (1 << 5) + +#endif + +#ifdef CL_VERSION_2_0 + +/* cl_device_svm_capabilities */ +#define CL_DEVICE_SVM_COARSE_GRAIN_BUFFER (1 << 0) +#define CL_DEVICE_SVM_FINE_GRAIN_BUFFER (1 << 1) +#define CL_DEVICE_SVM_FINE_GRAIN_SYSTEM (1 << 2) +#define CL_DEVICE_SVM_ATOMICS (1 << 3) + +#endif + +/* cl_command_queue_info */ +#define CL_QUEUE_CONTEXT 0x1090 +#define CL_QUEUE_DEVICE 0x1091 +#define CL_QUEUE_REFERENCE_COUNT 0x1092 +#define CL_QUEUE_PROPERTIES 0x1093 +#ifdef CL_VERSION_2_0 +#define CL_QUEUE_SIZE 0x1094 +#endif +#ifdef CL_VERSION_2_1 +#define CL_QUEUE_DEVICE_DEFAULT 0x1095 +#endif +#ifdef CL_VERSION_3_0 +#define CL_QUEUE_PROPERTIES_ARRAY 0x1098 +#endif + +/* cl_mem_flags and cl_svm_mem_flags - bitfield */ +#define CL_MEM_READ_WRITE (1 << 0) +#define CL_MEM_WRITE_ONLY (1 << 1) +#define CL_MEM_READ_ONLY (1 << 2) +#define CL_MEM_USE_HOST_PTR (1 << 3) +#define CL_MEM_ALLOC_HOST_PTR (1 << 4) +#define CL_MEM_COPY_HOST_PTR (1 << 5) +/* reserved (1 << 6) */ +#ifdef CL_VERSION_1_2 +#define CL_MEM_HOST_WRITE_ONLY (1 << 7) +#define CL_MEM_HOST_READ_ONLY (1 << 8) +#define CL_MEM_HOST_NO_ACCESS (1 << 9) +#endif +#ifdef CL_VERSION_2_0 +#define CL_MEM_SVM_FINE_GRAIN_BUFFER (1 << 10) /* used by cl_svm_mem_flags only */ +#define CL_MEM_SVM_ATOMICS (1 << 11) /* used by cl_svm_mem_flags only */ +#define CL_MEM_KERNEL_READ_AND_WRITE (1 << 12) +#endif + +#ifdef CL_VERSION_1_2 + +/* cl_mem_migration_flags - bitfield */ +#define CL_MIGRATE_MEM_OBJECT_HOST (1 << 0) +#define CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED (1 << 1) + +#endif + +/* cl_channel_order */ +#define CL_R 0x10B0 +#define CL_A 0x10B1 +#define CL_RG 0x10B2 +#define CL_RA 0x10B3 +#define CL_RGB 0x10B4 +#define CL_RGBA 0x10B5 +#define CL_BGRA 0x10B6 +#define CL_ARGB 0x10B7 +#define CL_INTENSITY 0x10B8 +#define CL_LUMINANCE 0x10B9 +#ifdef CL_VERSION_1_1 +#define CL_Rx 0x10BA +#define CL_RGx 0x10BB +#define CL_RGBx 0x10BC +#endif +#ifdef CL_VERSION_2_0 +#define CL_DEPTH 0x10BD +#define CL_sRGB 0x10BF +#define CL_sRGBx 0x10C0 +#define CL_sRGBA 0x10C1 +#define CL_sBGRA 0x10C2 +#define CL_ABGR 0x10C3 +#endif + +/* cl_channel_type */ +#define CL_SNORM_INT8 0x10D0 +#define CL_SNORM_INT16 0x10D1 +#define CL_UNORM_INT8 0x10D2 +#define CL_UNORM_INT16 0x10D3 +#define CL_UNORM_SHORT_565 0x10D4 +#define CL_UNORM_SHORT_555 0x10D5 +#define CL_UNORM_INT_101010 0x10D6 +#define CL_SIGNED_INT8 0x10D7 +#define CL_SIGNED_INT16 0x10D8 +#define CL_SIGNED_INT32 0x10D9 +#define CL_UNSIGNED_INT8 0x10DA +#define CL_UNSIGNED_INT16 0x10DB +#define CL_UNSIGNED_INT32 0x10DC +#define CL_HALF_FLOAT 0x10DD +#define CL_FLOAT 0x10DE +#ifdef CL_VERSION_2_1 +#define CL_UNORM_INT_101010_2 0x10E0 +#endif + +/* cl_mem_object_type */ +#define CL_MEM_OBJECT_BUFFER 0x10F0 +#define CL_MEM_OBJECT_IMAGE2D 0x10F1 +#define CL_MEM_OBJECT_IMAGE3D 0x10F2 +#ifdef CL_VERSION_1_2 +#define CL_MEM_OBJECT_IMAGE2D_ARRAY 0x10F3 +#define CL_MEM_OBJECT_IMAGE1D 0x10F4 +#define CL_MEM_OBJECT_IMAGE1D_ARRAY 0x10F5 +#define CL_MEM_OBJECT_IMAGE1D_BUFFER 0x10F6 +#endif +#ifdef CL_VERSION_2_0 +#define CL_MEM_OBJECT_PIPE 0x10F7 +#endif + +/* cl_mem_info */ +#define CL_MEM_TYPE 0x1100 +#define CL_MEM_FLAGS 0x1101 +#define CL_MEM_SIZE 0x1102 +#define CL_MEM_HOST_PTR 0x1103 +#define CL_MEM_MAP_COUNT 0x1104 +#define CL_MEM_REFERENCE_COUNT 0x1105 +#define CL_MEM_CONTEXT 0x1106 +#ifdef CL_VERSION_1_1 +#define CL_MEM_ASSOCIATED_MEMOBJECT 0x1107 +#define CL_MEM_OFFSET 0x1108 +#endif +#ifdef CL_VERSION_2_0 +#define CL_MEM_USES_SVM_POINTER 0x1109 +#endif +#ifdef CL_VERSION_3_0 +#define CL_MEM_PROPERTIES 0x110A +#endif + +/* cl_image_info */ +#define CL_IMAGE_FORMAT 0x1110 +#define CL_IMAGE_ELEMENT_SIZE 0x1111 +#define CL_IMAGE_ROW_PITCH 0x1112 +#define CL_IMAGE_SLICE_PITCH 0x1113 +#define CL_IMAGE_WIDTH 0x1114 +#define CL_IMAGE_HEIGHT 0x1115 +#define CL_IMAGE_DEPTH 0x1116 +#ifdef CL_VERSION_1_2 +#define CL_IMAGE_ARRAY_SIZE 0x1117 +#define CL_IMAGE_BUFFER 0x1118 +#define CL_IMAGE_NUM_MIP_LEVELS 0x1119 +#define CL_IMAGE_NUM_SAMPLES 0x111A +#endif + + +/* cl_pipe_info */ +#ifdef CL_VERSION_2_0 +#define CL_PIPE_PACKET_SIZE 0x1120 +#define CL_PIPE_MAX_PACKETS 0x1121 +#endif +#ifdef CL_VERSION_3_0 +#define CL_PIPE_PROPERTIES 0x1122 +#endif + +/* cl_addressing_mode */ +#define CL_ADDRESS_NONE 0x1130 +#define CL_ADDRESS_CLAMP_TO_EDGE 0x1131 +#define CL_ADDRESS_CLAMP 0x1132 +#define CL_ADDRESS_REPEAT 0x1133 +#ifdef CL_VERSION_1_1 +#define CL_ADDRESS_MIRRORED_REPEAT 0x1134 +#endif + +/* cl_filter_mode */ +#define CL_FILTER_NEAREST 0x1140 +#define CL_FILTER_LINEAR 0x1141 + +/* cl_sampler_info */ +#define CL_SAMPLER_REFERENCE_COUNT 0x1150 +#define CL_SAMPLER_CONTEXT 0x1151 +#define CL_SAMPLER_NORMALIZED_COORDS 0x1152 +#define CL_SAMPLER_ADDRESSING_MODE 0x1153 +#define CL_SAMPLER_FILTER_MODE 0x1154 +#ifdef CL_VERSION_2_0 +/* These enumerants are for the cl_khr_mipmap_image extension. + They have since been added to cl_ext.h with an appropriate + KHR suffix, but are left here for backwards compatibility. */ +#define CL_SAMPLER_MIP_FILTER_MODE 0x1155 +#define CL_SAMPLER_LOD_MIN 0x1156 +#define CL_SAMPLER_LOD_MAX 0x1157 +#endif +#ifdef CL_VERSION_3_0 +#define CL_SAMPLER_PROPERTIES 0x1158 +#endif + +/* cl_map_flags - bitfield */ +#define CL_MAP_READ (1 << 0) +#define CL_MAP_WRITE (1 << 1) +#ifdef CL_VERSION_1_2 +#define CL_MAP_WRITE_INVALIDATE_REGION (1 << 2) +#endif + +/* cl_program_info */ +#define CL_PROGRAM_REFERENCE_COUNT 0x1160 +#define CL_PROGRAM_CONTEXT 0x1161 +#define CL_PROGRAM_NUM_DEVICES 0x1162 +#define CL_PROGRAM_DEVICES 0x1163 +#define CL_PROGRAM_SOURCE 0x1164 +#define CL_PROGRAM_BINARY_SIZES 0x1165 +#define CL_PROGRAM_BINARIES 0x1166 +#ifdef CL_VERSION_1_2 +#define CL_PROGRAM_NUM_KERNELS 0x1167 +#define CL_PROGRAM_KERNEL_NAMES 0x1168 +#endif +#ifdef CL_VERSION_2_1 +#define CL_PROGRAM_IL 0x1169 +#endif +#ifdef CL_VERSION_2_2 +#define CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT 0x116A +#define CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT 0x116B +#endif + +/* cl_program_build_info */ +#define CL_PROGRAM_BUILD_STATUS 0x1181 +#define CL_PROGRAM_BUILD_OPTIONS 0x1182 +#define CL_PROGRAM_BUILD_LOG 0x1183 +#ifdef CL_VERSION_1_2 +#define CL_PROGRAM_BINARY_TYPE 0x1184 +#endif +#ifdef CL_VERSION_2_0 +#define CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE 0x1185 +#endif + +#ifdef CL_VERSION_1_2 + +/* cl_program_binary_type */ +#define CL_PROGRAM_BINARY_TYPE_NONE 0x0 +#define CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT 0x1 +#define CL_PROGRAM_BINARY_TYPE_LIBRARY 0x2 +#define CL_PROGRAM_BINARY_TYPE_EXECUTABLE 0x4 + +#endif + +/* cl_build_status */ +#define CL_BUILD_SUCCESS 0 +#define CL_BUILD_NONE -1 +#define CL_BUILD_ERROR -2 +#define CL_BUILD_IN_PROGRESS -3 + +/* cl_kernel_info */ +#define CL_KERNEL_FUNCTION_NAME 0x1190 +#define CL_KERNEL_NUM_ARGS 0x1191 +#define CL_KERNEL_REFERENCE_COUNT 0x1192 +#define CL_KERNEL_CONTEXT 0x1193 +#define CL_KERNEL_PROGRAM 0x1194 +#ifdef CL_VERSION_1_2 +#define CL_KERNEL_ATTRIBUTES 0x1195 +#endif + +#ifdef CL_VERSION_1_2 + +/* cl_kernel_arg_info */ +#define CL_KERNEL_ARG_ADDRESS_QUALIFIER 0x1196 +#define CL_KERNEL_ARG_ACCESS_QUALIFIER 0x1197 +#define CL_KERNEL_ARG_TYPE_NAME 0x1198 +#define CL_KERNEL_ARG_TYPE_QUALIFIER 0x1199 +#define CL_KERNEL_ARG_NAME 0x119A + +#endif + +#ifdef CL_VERSION_1_2 + +/* cl_kernel_arg_address_qualifier */ +#define CL_KERNEL_ARG_ADDRESS_GLOBAL 0x119B +#define CL_KERNEL_ARG_ADDRESS_LOCAL 0x119C +#define CL_KERNEL_ARG_ADDRESS_CONSTANT 0x119D +#define CL_KERNEL_ARG_ADDRESS_PRIVATE 0x119E + +#endif + +#ifdef CL_VERSION_1_2 + +/* cl_kernel_arg_access_qualifier */ +#define CL_KERNEL_ARG_ACCESS_READ_ONLY 0x11A0 +#define CL_KERNEL_ARG_ACCESS_WRITE_ONLY 0x11A1 +#define CL_KERNEL_ARG_ACCESS_READ_WRITE 0x11A2 +#define CL_KERNEL_ARG_ACCESS_NONE 0x11A3 + +#endif + +#ifdef CL_VERSION_1_2 + +/* cl_kernel_arg_type_qualifier */ +#define CL_KERNEL_ARG_TYPE_NONE 0 +#define CL_KERNEL_ARG_TYPE_CONST (1 << 0) +#define CL_KERNEL_ARG_TYPE_RESTRICT (1 << 1) +#define CL_KERNEL_ARG_TYPE_VOLATILE (1 << 2) +#ifdef CL_VERSION_2_0 +#define CL_KERNEL_ARG_TYPE_PIPE (1 << 3) +#endif + +#endif + +/* cl_kernel_work_group_info */ +#define CL_KERNEL_WORK_GROUP_SIZE 0x11B0 +#define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1 +#define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2 +#define CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x11B3 +#define CL_KERNEL_PRIVATE_MEM_SIZE 0x11B4 +#ifdef CL_VERSION_1_2 +#define CL_KERNEL_GLOBAL_WORK_SIZE 0x11B5 +#endif + +#ifdef CL_VERSION_2_1 + +/* cl_kernel_sub_group_info */ +#define CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE 0x2033 +#define CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE 0x2034 +#define CL_KERNEL_LOCAL_SIZE_FOR_SUB_GROUP_COUNT 0x11B8 +#define CL_KERNEL_MAX_NUM_SUB_GROUPS 0x11B9 +#define CL_KERNEL_COMPILE_NUM_SUB_GROUPS 0x11BA + +#endif + +#ifdef CL_VERSION_2_0 + +/* cl_kernel_exec_info */ +#define CL_KERNEL_EXEC_INFO_SVM_PTRS 0x11B6 +#define CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM 0x11B7 + +#endif + +/* cl_event_info */ +#define CL_EVENT_COMMAND_QUEUE 0x11D0 +#define CL_EVENT_COMMAND_TYPE 0x11D1 +#define CL_EVENT_REFERENCE_COUNT 0x11D2 +#define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3 +#ifdef CL_VERSION_1_1 +#define CL_EVENT_CONTEXT 0x11D4 +#endif + +/* cl_command_type */ +#define CL_COMMAND_NDRANGE_KERNEL 0x11F0 +#define CL_COMMAND_TASK 0x11F1 +#define CL_COMMAND_NATIVE_KERNEL 0x11F2 +#define CL_COMMAND_READ_BUFFER 0x11F3 +#define CL_COMMAND_WRITE_BUFFER 0x11F4 +#define CL_COMMAND_COPY_BUFFER 0x11F5 +#define CL_COMMAND_READ_IMAGE 0x11F6 +#define CL_COMMAND_WRITE_IMAGE 0x11F7 +#define CL_COMMAND_COPY_IMAGE 0x11F8 +#define CL_COMMAND_COPY_IMAGE_TO_BUFFER 0x11F9 +#define CL_COMMAND_COPY_BUFFER_TO_IMAGE 0x11FA +#define CL_COMMAND_MAP_BUFFER 0x11FB +#define CL_COMMAND_MAP_IMAGE 0x11FC +#define CL_COMMAND_UNMAP_MEM_OBJECT 0x11FD +#define CL_COMMAND_MARKER 0x11FE +#define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF +#define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200 +#ifdef CL_VERSION_1_1 +#define CL_COMMAND_READ_BUFFER_RECT 0x1201 +#define CL_COMMAND_WRITE_BUFFER_RECT 0x1202 +#define CL_COMMAND_COPY_BUFFER_RECT 0x1203 +#define CL_COMMAND_USER 0x1204 +#endif +#ifdef CL_VERSION_1_2 +#define CL_COMMAND_BARRIER 0x1205 +#define CL_COMMAND_MIGRATE_MEM_OBJECTS 0x1206 +#define CL_COMMAND_FILL_BUFFER 0x1207 +#define CL_COMMAND_FILL_IMAGE 0x1208 +#endif +#ifdef CL_VERSION_2_0 +#define CL_COMMAND_SVM_FREE 0x1209 +#define CL_COMMAND_SVM_MEMCPY 0x120A +#define CL_COMMAND_SVM_MEMFILL 0x120B +#define CL_COMMAND_SVM_MAP 0x120C +#define CL_COMMAND_SVM_UNMAP 0x120D +#endif +#ifdef CL_VERSION_3_0 +#define CL_COMMAND_SVM_MIGRATE_MEM 0x120E +#endif + +/* command execution status */ +#define CL_COMPLETE 0x0 +#define CL_RUNNING 0x1 +#define CL_SUBMITTED 0x2 +#define CL_QUEUED 0x3 + +/* cl_buffer_create_type */ +#ifdef CL_VERSION_1_1 +#define CL_BUFFER_CREATE_TYPE_REGION 0x1220 +#endif + +/* cl_profiling_info */ +#define CL_PROFILING_COMMAND_QUEUED 0x1280 +#define CL_PROFILING_COMMAND_SUBMIT 0x1281 +#define CL_PROFILING_COMMAND_START 0x1282 +#define CL_PROFILING_COMMAND_END 0x1283 +#ifdef CL_VERSION_2_0 +#define CL_PROFILING_COMMAND_COMPLETE 0x1284 +#endif + +/* cl_device_atomic_capabilities - bitfield */ +#ifdef CL_VERSION_3_0 +#define CL_DEVICE_ATOMIC_ORDER_RELAXED (1 << 0) +#define CL_DEVICE_ATOMIC_ORDER_ACQ_REL (1 << 1) +#define CL_DEVICE_ATOMIC_ORDER_SEQ_CST (1 << 2) +#define CL_DEVICE_ATOMIC_SCOPE_WORK_ITEM (1 << 3) +#define CL_DEVICE_ATOMIC_SCOPE_WORK_GROUP (1 << 4) +#define CL_DEVICE_ATOMIC_SCOPE_DEVICE (1 << 5) +#define CL_DEVICE_ATOMIC_SCOPE_ALL_DEVICES (1 << 6) +#endif + +/* cl_device_device_enqueue_capabilities - bitfield */ +#ifdef CL_VERSION_3_0 +#define CL_DEVICE_QUEUE_SUPPORTED (1 << 0) +#define CL_DEVICE_QUEUE_REPLACEABLE_DEFAULT (1 << 1) +#endif + +/* cl_khronos_vendor_id */ +#define CL_KHRONOS_VENDOR_ID_CODEPLAY 0x10004 + +/* cl_version */ +#define CL_VERSION_MAJOR_BITS (10) +#define CL_VERSION_MINOR_BITS (10) +#define CL_VERSION_PATCH_BITS (12) + +#define CL_VERSION_MAJOR_MASK ((1 << CL_VERSION_MAJOR_BITS) - 1) +#define CL_VERSION_MINOR_MASK ((1 << CL_VERSION_MINOR_BITS) - 1) +#define CL_VERSION_PATCH_MASK ((1 << CL_VERSION_PATCH_BITS) - 1) + +#define CL_VERSION_MAJOR(version) \ + ((version) >> (CL_VERSION_MINOR_BITS + CL_VERSION_PATCH_BITS)) + +#define CL_VERSION_MINOR(version) \ + (((version) >> CL_VERSION_PATCH_BITS) & CL_VERSION_MINOR_MASK) + +#define CL_VERSION_PATCH(version) ((version) & CL_VERSION_PATCH_MASK) + +#define CL_MAKE_VERSION(major, minor, patch) \ + ((((major) & CL_VERSION_MAJOR_MASK) \ + << (CL_VERSION_MINOR_BITS + CL_VERSION_PATCH_BITS)) | \ + (((minor) & CL_VERSION_MINOR_MASK) << CL_VERSION_PATCH_BITS) | \ + ((patch) & CL_VERSION_PATCH_MASK)) + +/********************************************************************************************************/ + +/* CL_NO_PROTOTYPES implies CL_NO_CORE_PROTOTYPES: */ +#if defined(CL_NO_PROTOTYPES) && !defined(CL_NO_CORE_PROTOTYPES) +#define CL_NO_CORE_PROTOTYPES +#endif + +#if !defined(CL_NO_CORE_PROTOTYPES) + +/* Platform API */ +extern CL_API_ENTRY cl_int CL_API_CALL +clGetPlatformIDs(cl_uint num_entries, + cl_platform_id * platforms, + cl_uint * num_platforms) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetPlatformInfo(cl_platform_id platform, + cl_platform_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +/* Device APIs */ +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceIDs(cl_platform_id platform, + cl_device_type device_type, + cl_uint num_entries, + cl_device_id * devices, + cl_uint * num_devices) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceInfo(cl_device_id device, + cl_device_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_int CL_API_CALL +clCreateSubDevices(cl_device_id in_device, + const cl_device_partition_property * properties, + cl_uint num_devices, + cl_device_id * out_devices, + cl_uint * num_devices_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainDevice(cl_device_id device) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseDevice(cl_device_id device) CL_API_SUFFIX__VERSION_1_2; + +#endif + +#ifdef CL_VERSION_2_1 + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetDefaultDeviceCommandQueue(cl_context context, + cl_device_id device, + cl_command_queue command_queue) CL_API_SUFFIX__VERSION_2_1; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceAndHostTimer(cl_device_id device, + cl_ulong* device_timestamp, + cl_ulong* host_timestamp) CL_API_SUFFIX__VERSION_2_1; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetHostTimer(cl_device_id device, + cl_ulong * host_timestamp) CL_API_SUFFIX__VERSION_2_1; + +#endif + +/* Context APIs */ +extern CL_API_ENTRY cl_context CL_API_CALL +clCreateContext(const cl_context_properties * properties, + cl_uint num_devices, + const cl_device_id * devices, + void (CL_CALLBACK * pfn_notify)(const char * errinfo, + const void * private_info, + size_t cb, + void * user_data), + void * user_data, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_context CL_API_CALL +clCreateContextFromType(const cl_context_properties * properties, + cl_device_type device_type, + void (CL_CALLBACK * pfn_notify)(const char * errinfo, + const void * private_info, + size_t cb, + void * user_data), + void * user_data, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainContext(cl_context context) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseContext(cl_context context) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetContextInfo(cl_context context, + cl_context_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_3_0 + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetContextDestructorCallback(cl_context context, + void (CL_CALLBACK* pfn_notify)(cl_context context, + void* user_data), + void* user_data) CL_API_SUFFIX__VERSION_3_0; + +#endif + +/* Command Queue APIs */ + +#ifdef CL_VERSION_2_0 + +extern CL_API_ENTRY cl_command_queue CL_API_CALL +clCreateCommandQueueWithProperties(cl_context context, + cl_device_id device, + const cl_queue_properties * properties, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_2_0; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainCommandQueue(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseCommandQueue(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetCommandQueueInfo(cl_command_queue command_queue, + cl_command_queue_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +/* Memory Object APIs */ +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateBuffer(cl_context context, + cl_mem_flags flags, + size_t size, + void * host_ptr, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_1 + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateSubBuffer(cl_mem buffer, + cl_mem_flags flags, + cl_buffer_create_type buffer_create_type, + const void * buffer_create_info, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_1; + +#endif + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateImage(cl_context context, + cl_mem_flags flags, + const cl_image_format * image_format, + const cl_image_desc * image_desc, + void * host_ptr, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +#endif + +#ifdef CL_VERSION_2_0 + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreatePipe(cl_context context, + cl_mem_flags flags, + cl_uint pipe_packet_size, + cl_uint pipe_max_packets, + const cl_pipe_properties * properties, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_2_0; + +#endif + +#ifdef CL_VERSION_3_0 + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateBufferWithProperties(cl_context context, + const cl_mem_properties * properties, + cl_mem_flags flags, + size_t size, + void * host_ptr, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_3_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateImageWithProperties(cl_context context, + const cl_mem_properties * properties, + cl_mem_flags flags, + const cl_image_format * image_format, + const cl_image_desc * image_desc, + void * host_ptr, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_3_0; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainMemObject(cl_mem memobj) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseMemObject(cl_mem memobj) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSupportedImageFormats(cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint num_entries, + cl_image_format * image_formats, + cl_uint * num_image_formats) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetMemObjectInfo(cl_mem memobj, + cl_mem_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetImageInfo(cl_mem image, + cl_image_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_2_0 + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetPipeInfo(cl_mem pipe, + cl_pipe_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_2_0; + +#endif + +#ifdef CL_VERSION_1_1 + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetMemObjectDestructorCallback(cl_mem memobj, + void (CL_CALLBACK * pfn_notify)(cl_mem memobj, + void * user_data), + void * user_data) CL_API_SUFFIX__VERSION_1_1; + +#endif + +/* SVM Allocation APIs */ + +#ifdef CL_VERSION_2_0 + +extern CL_API_ENTRY void * CL_API_CALL +clSVMAlloc(cl_context context, + cl_svm_mem_flags flags, + size_t size, + cl_uint alignment) CL_API_SUFFIX__VERSION_2_0; + +extern CL_API_ENTRY void CL_API_CALL +clSVMFree(cl_context context, + void * svm_pointer) CL_API_SUFFIX__VERSION_2_0; + +#endif + +/* Sampler APIs */ + +#ifdef CL_VERSION_2_0 + +extern CL_API_ENTRY cl_sampler CL_API_CALL +clCreateSamplerWithProperties(cl_context context, + const cl_sampler_properties * sampler_properties, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_2_0; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainSampler(cl_sampler sampler) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseSampler(cl_sampler sampler) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSamplerInfo(cl_sampler sampler, + cl_sampler_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +/* Program Object APIs */ +extern CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithSource(cl_context context, + cl_uint count, + const char ** strings, + const size_t * lengths, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithBinary(cl_context context, + cl_uint num_devices, + const cl_device_id * device_list, + const size_t * lengths, + const unsigned char ** binaries, + cl_int * binary_status, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithBuiltInKernels(cl_context context, + cl_uint num_devices, + const cl_device_id * device_list, + const char * kernel_names, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +#endif + +#ifdef CL_VERSION_2_1 + +extern CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithIL(cl_context context, + const void* il, + size_t length, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_2_1; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainProgram(cl_program program) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseProgram(cl_program program) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clBuildProgram(cl_program program, + cl_uint num_devices, + const cl_device_id * device_list, + const char * options, + void (CL_CALLBACK * pfn_notify)(cl_program program, + void * user_data), + void * user_data) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_int CL_API_CALL +clCompileProgram(cl_program program, + cl_uint num_devices, + const cl_device_id * device_list, + const char * options, + cl_uint num_input_headers, + const cl_program * input_headers, + const char ** header_include_names, + void (CL_CALLBACK * pfn_notify)(cl_program program, + void * user_data), + void * user_data) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_program CL_API_CALL +clLinkProgram(cl_context context, + cl_uint num_devices, + const cl_device_id * device_list, + const char * options, + cl_uint num_input_programs, + const cl_program * input_programs, + void (CL_CALLBACK * pfn_notify)(cl_program program, + void * user_data), + void * user_data, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +#endif + +#ifdef CL_VERSION_2_2 + +extern CL_API_ENTRY CL_API_PREFIX__VERSION_2_2_DEPRECATED cl_int CL_API_CALL +clSetProgramReleaseCallback(cl_program program, + void (CL_CALLBACK * pfn_notify)(cl_program program, + void * user_data), + void * user_data) CL_API_SUFFIX__VERSION_2_2_DEPRECATED; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetProgramSpecializationConstant(cl_program program, + cl_uint spec_id, + size_t spec_size, + const void* spec_value) CL_API_SUFFIX__VERSION_2_2; + +#endif + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_int CL_API_CALL +clUnloadPlatformCompiler(cl_platform_id platform) CL_API_SUFFIX__VERSION_1_2; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetProgramInfo(cl_program program, + cl_program_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetProgramBuildInfo(cl_program program, + cl_device_id device, + cl_program_build_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +/* Kernel Object APIs */ +extern CL_API_ENTRY cl_kernel CL_API_CALL +clCreateKernel(cl_program program, + const char * kernel_name, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCreateKernelsInProgram(cl_program program, + cl_uint num_kernels, + cl_kernel * kernels, + cl_uint * num_kernels_ret) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_2_1 + +extern CL_API_ENTRY cl_kernel CL_API_CALL +clCloneKernel(cl_kernel source_kernel, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_2_1; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainKernel(cl_kernel kernel) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseKernel(cl_kernel kernel) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetKernelArg(cl_kernel kernel, + cl_uint arg_index, + size_t arg_size, + const void * arg_value) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_2_0 + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetKernelArgSVMPointer(cl_kernel kernel, + cl_uint arg_index, + const void * arg_value) CL_API_SUFFIX__VERSION_2_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetKernelExecInfo(cl_kernel kernel, + cl_kernel_exec_info param_name, + size_t param_value_size, + const void * param_value) CL_API_SUFFIX__VERSION_2_0; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelInfo(cl_kernel kernel, + cl_kernel_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelArgInfo(cl_kernel kernel, + cl_uint arg_indx, + cl_kernel_arg_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_2; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelWorkGroupInfo(cl_kernel kernel, + cl_device_id device, + cl_kernel_work_group_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_2_1 + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelSubGroupInfo(cl_kernel kernel, + cl_device_id device, + cl_kernel_sub_group_info param_name, + size_t input_value_size, + const void* input_value, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) CL_API_SUFFIX__VERSION_2_1; + +#endif + +/* Event Object APIs */ +extern CL_API_ENTRY cl_int CL_API_CALL +clWaitForEvents(cl_uint num_events, + const cl_event * event_list) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetEventInfo(cl_event event, + cl_event_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_1 + +extern CL_API_ENTRY cl_event CL_API_CALL +clCreateUserEvent(cl_context context, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_1; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainEvent(cl_event event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseEvent(cl_event event) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_1 + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetUserEventStatus(cl_event event, + cl_int execution_status) CL_API_SUFFIX__VERSION_1_1; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetEventCallback(cl_event event, + cl_int command_exec_callback_type, + void (CL_CALLBACK * pfn_notify)(cl_event event, + cl_int event_command_status, + void * user_data), + void * user_data) CL_API_SUFFIX__VERSION_1_1; + +#endif + +/* Profiling APIs */ +extern CL_API_ENTRY cl_int CL_API_CALL +clGetEventProfilingInfo(cl_event event, + cl_profiling_info param_name, + size_t param_value_size, + void * param_value, + size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +/* Flush and Finish APIs */ +extern CL_API_ENTRY cl_int CL_API_CALL +clFlush(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clFinish(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_0; + +/* Enqueued Commands APIs */ +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReadBuffer(cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_read, + size_t offset, + size_t size, + void * ptr, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_1 + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReadBufferRect(cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_read, + const size_t * buffer_origin, + const size_t * host_origin, + const size_t * region, + size_t buffer_row_pitch, + size_t buffer_slice_pitch, + size_t host_row_pitch, + size_t host_slice_pitch, + void * ptr, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_1; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueWriteBuffer(cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_write, + size_t offset, + size_t size, + const void * ptr, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_1 + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueWriteBufferRect(cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_write, + const size_t * buffer_origin, + const size_t * host_origin, + const size_t * region, + size_t buffer_row_pitch, + size_t buffer_slice_pitch, + size_t host_row_pitch, + size_t host_slice_pitch, + const void * ptr, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_1; + +#endif + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueFillBuffer(cl_command_queue command_queue, + cl_mem buffer, + const void * pattern, + size_t pattern_size, + size_t offset, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyBuffer(cl_command_queue command_queue, + cl_mem src_buffer, + cl_mem dst_buffer, + size_t src_offset, + size_t dst_offset, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_1 + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyBufferRect(cl_command_queue command_queue, + cl_mem src_buffer, + cl_mem dst_buffer, + const size_t * src_origin, + const size_t * dst_origin, + const size_t * region, + size_t src_row_pitch, + size_t src_slice_pitch, + size_t dst_row_pitch, + size_t dst_slice_pitch, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_1; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReadImage(cl_command_queue command_queue, + cl_mem image, + cl_bool blocking_read, + const size_t * origin, + const size_t * region, + size_t row_pitch, + size_t slice_pitch, + void * ptr, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueWriteImage(cl_command_queue command_queue, + cl_mem image, + cl_bool blocking_write, + const size_t * origin, + const size_t * region, + size_t input_row_pitch, + size_t input_slice_pitch, + const void * ptr, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueFillImage(cl_command_queue command_queue, + cl_mem image, + const void * fill_color, + const size_t * origin, + const size_t * region, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyImage(cl_command_queue command_queue, + cl_mem src_image, + cl_mem dst_image, + const size_t * src_origin, + const size_t * dst_origin, + const size_t * region, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyImageToBuffer(cl_command_queue command_queue, + cl_mem src_image, + cl_mem dst_buffer, + const size_t * src_origin, + const size_t * region, + size_t dst_offset, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCopyBufferToImage(cl_command_queue command_queue, + cl_mem src_buffer, + cl_mem dst_image, + size_t src_offset, + const size_t * dst_origin, + const size_t * region, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY void * CL_API_CALL +clEnqueueMapBuffer(cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_map, + cl_map_flags map_flags, + size_t offset, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY void * CL_API_CALL +clEnqueueMapImage(cl_command_queue command_queue, + cl_mem image, + cl_bool blocking_map, + cl_map_flags map_flags, + const size_t * origin, + const size_t * region, + size_t * image_row_pitch, + size_t * image_slice_pitch, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueUnmapMemObject(cl_command_queue command_queue, + cl_mem memobj, + void * mapped_ptr, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMigrateMemObjects(cl_command_queue command_queue, + cl_uint num_mem_objects, + const cl_mem * mem_objects, + cl_mem_migration_flags flags, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2; + +#endif + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueNDRangeKernel(cl_command_queue command_queue, + cl_kernel kernel, + cl_uint work_dim, + const size_t * global_work_offset, + const size_t * global_work_size, + const size_t * local_work_size, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueNativeKernel(cl_command_queue command_queue, + void (CL_CALLBACK * user_func)(void *), + void * args, + size_t cb_args, + cl_uint num_mem_objects, + const cl_mem * mem_list, + const void ** args_mem_loc, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_0; + +#ifdef CL_VERSION_1_2 + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMarkerWithWaitList(cl_command_queue command_queue, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueBarrierWithWaitList(cl_command_queue command_queue, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2; + +#endif + +#ifdef CL_VERSION_2_0 + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMFree(cl_command_queue command_queue, + cl_uint num_svm_pointers, + void * svm_pointers[], + void (CL_CALLBACK * pfn_free_func)(cl_command_queue queue, + cl_uint num_svm_pointers, + void * svm_pointers[], + void * user_data), + void * user_data, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_2_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMMemcpy(cl_command_queue command_queue, + cl_bool blocking_copy, + void * dst_ptr, + const void * src_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_2_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMMemFill(cl_command_queue command_queue, + void * svm_ptr, + const void * pattern, + size_t pattern_size, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_2_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMMap(cl_command_queue command_queue, + cl_bool blocking_map, + cl_map_flags flags, + void * svm_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_2_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMUnmap(cl_command_queue command_queue, + void * svm_ptr, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_2_0; + +#endif + +#ifdef CL_VERSION_2_1 + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMMigrateMem(cl_command_queue command_queue, + cl_uint num_svm_pointers, + const void ** svm_pointers, + const size_t * sizes, + cl_mem_migration_flags flags, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_2_1; + +#endif + +#ifdef CL_VERSION_1_2 + +/* Extension function access + * + * Returns the extension function address for the given function name, + * or NULL if a valid function can not be found. The client must + * check to make sure the address is not NULL, before using or + * calling the returned function address. + */ +extern CL_API_ENTRY void * CL_API_CALL +clGetExtensionFunctionAddressForPlatform(cl_platform_id platform, + const char * func_name) CL_API_SUFFIX__VERSION_1_2; + +#endif + +#ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS + /* + * WARNING: + * This API introduces mutable state into the OpenCL implementation. It has been REMOVED + * to better facilitate thread safety. The 1.0 API is not thread safe. It is not tested by the + * OpenCL 1.1 conformance test, and consequently may not work or may not work dependably. + * It is likely to be non-performant. Use of this API is not advised. Use at your own risk. + * + * Software developers previously relying on this API are instructed to set the command queue + * properties when creating the queue, instead. + */ + extern CL_API_ENTRY cl_int CL_API_CALL + clSetCommandQueueProperty(cl_command_queue command_queue, + cl_command_queue_properties properties, + cl_bool enable, + cl_command_queue_properties * old_properties) CL_API_SUFFIX__VERSION_1_0_DEPRECATED; +#endif /* CL_USE_DEPRECATED_OPENCL_1_0_APIS */ + +/* Deprecated OpenCL 1.1 APIs */ +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL +clCreateImage2D(cl_context context, + cl_mem_flags flags, + const cl_image_format * image_format, + size_t image_width, + size_t image_height, + size_t image_row_pitch, + void * host_ptr, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_mem CL_API_CALL +clCreateImage3D(cl_context context, + cl_mem_flags flags, + const cl_image_format * image_format, + size_t image_width, + size_t image_height, + size_t image_depth, + size_t image_row_pitch, + size_t image_slice_pitch, + void * host_ptr, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL +clEnqueueMarker(cl_command_queue command_queue, + cl_event * event) CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL +clEnqueueWaitForEvents(cl_command_queue command_queue, + cl_uint num_events, + const cl_event * event_list) CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL +clEnqueueBarrier(cl_command_queue command_queue) CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED cl_int CL_API_CALL +clUnloadCompiler(void) CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_1_DEPRECATED void * CL_API_CALL +clGetExtensionFunctionAddress(const char * func_name) CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +/* Deprecated OpenCL 2.0 APIs */ +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_2_DEPRECATED cl_command_queue CL_API_CALL +clCreateCommandQueue(cl_context context, + cl_device_id device, + cl_command_queue_properties properties, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2_DEPRECATED; + +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_2_DEPRECATED cl_sampler CL_API_CALL +clCreateSampler(cl_context context, + cl_bool normalized_coords, + cl_addressing_mode addressing_mode, + cl_filter_mode filter_mode, + cl_int * errcode_ret) CL_API_SUFFIX__VERSION_1_2_DEPRECATED; + +extern CL_API_ENTRY CL_API_PREFIX__VERSION_1_2_DEPRECATED cl_int CL_API_CALL +clEnqueueTask(cl_command_queue command_queue, + cl_kernel kernel, + cl_uint num_events_in_wait_list, + const cl_event * event_wait_list, + cl_event * event) CL_API_SUFFIX__VERSION_1_2_DEPRECATED; + +#endif /* !defined(CL_NO_CORE_PROTOTYPES) */ + +#ifdef __cplusplus +} +#endif + +#if defined(_WIN32) && defined(_MSC_VER) && __CL_HAS_ANON_STRUCT__ + #pragma warning( pop ) +#endif + +#endif /* __OPENCL_CL_H */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_d3d10.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_d3d10.h new file mode 100644 index 000000000..6b56c775b --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_d3d10.h @@ -0,0 +1,268 @@ +/******************************************************************************* + * Copyright (c) 2008-2023 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef OPENCL_CL_D3D10_H_ +#define OPENCL_CL_D3D10_H_ + +/* +** This header is generated from the Khronos OpenCL XML API Registry. +*/ + +#if defined(_MSC_VER) +#if _MSC_VER >=1500 +#pragma warning( push ) +#pragma warning( disable : 4201 ) +#pragma warning( disable : 5105 ) +#endif +#endif +#include +#if defined(_MSC_VER) +#if _MSC_VER >=1500 +#pragma warning( pop ) +#endif +#endif + +#include + +/* CL_NO_PROTOTYPES implies CL_NO_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_PROTOTYPES) && !defined(CL_NO_EXTENSION_PROTOTYPES) +#define CL_NO_EXTENSION_PROTOTYPES +#endif + +/* CL_NO_EXTENSION_PROTOTYPES implies + CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES and + CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************** +* cl_khr_d3d10_sharing +***************************************************************/ +#define cl_khr_d3d10_sharing 1 +#define CL_KHR_D3D10_SHARING_EXTENSION_NAME \ + "cl_khr_d3d10_sharing" + + +#define CL_KHR_D3D10_SHARING_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_uint cl_d3d10_device_source_khr; +typedef cl_uint cl_d3d10_device_set_khr; + +/* Error codes */ +#define CL_INVALID_D3D10_DEVICE_KHR -1002 +#define CL_INVALID_D3D10_RESOURCE_KHR -1003 +#define CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR -1004 +#define CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR -1005 + +/* cl_d3d10_device_source_khr */ +#define CL_D3D10_DEVICE_KHR 0x4010 +#define CL_D3D10_DXGI_ADAPTER_KHR 0x4011 + +/* cl_d3d10_device_set_khr */ +#define CL_PREFERRED_DEVICES_FOR_D3D10_KHR 0x4012 +#define CL_ALL_DEVICES_FOR_D3D10_KHR 0x4013 + +/* cl_context_info */ +#define CL_CONTEXT_D3D10_DEVICE_KHR 0x4014 +#define CL_CONTEXT_D3D10_PREFER_SHARED_RESOURCES_KHR 0x402C + +/* cl_mem_info */ +#define CL_MEM_D3D10_RESOURCE_KHR 0x4015 + +/* cl_image_info */ +#define CL_IMAGE_D3D10_SUBRESOURCE_KHR 0x4016 + +/* cl_command_type */ +#define CL_COMMAND_ACQUIRE_D3D10_OBJECTS_KHR 0x4017 +#define CL_COMMAND_RELEASE_D3D10_OBJECTS_KHR 0x4018 + + +typedef cl_int CL_API_CALL +clGetDeviceIDsFromD3D10KHR_t( + cl_platform_id platform, + cl_d3d10_device_source_khr d3d_device_source, + void* d3d_object, + cl_d3d10_device_set_khr d3d_device_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices); + +typedef clGetDeviceIDsFromD3D10KHR_t * +clGetDeviceIDsFromD3D10KHR_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_mem CL_API_CALL +clCreateFromD3D10BufferKHR_t( + cl_context context, + cl_mem_flags flags, + ID3D10Buffer* resource, + cl_int* errcode_ret); + +typedef clCreateFromD3D10BufferKHR_t * +clCreateFromD3D10BufferKHR_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_mem CL_API_CALL +clCreateFromD3D10Texture2DKHR_t( + cl_context context, + cl_mem_flags flags, + ID3D10Texture2D* resource, + UINT subresource, + cl_int* errcode_ret); + +typedef clCreateFromD3D10Texture2DKHR_t * +clCreateFromD3D10Texture2DKHR_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_mem CL_API_CALL +clCreateFromD3D10Texture3DKHR_t( + cl_context context, + cl_mem_flags flags, + ID3D10Texture3D* resource, + UINT subresource, + cl_int* errcode_ret); + +typedef clCreateFromD3D10Texture3DKHR_t * +clCreateFromD3D10Texture3DKHR_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL +clEnqueueAcquireD3D10ObjectsKHR_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueAcquireD3D10ObjectsKHR_t * +clEnqueueAcquireD3D10ObjectsKHR_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL +clEnqueueReleaseD3D10ObjectsKHR_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReleaseD3D10ObjectsKHR_t * +clEnqueueReleaseD3D10ObjectsKHR_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceIDsFromD3D10KHR( + cl_platform_id platform, + cl_d3d10_device_source_khr d3d_device_source, + void* d3d_object, + cl_d3d10_device_set_khr d3d_device_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromD3D10BufferKHR( + cl_context context, + cl_mem_flags flags, + ID3D10Buffer* resource, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromD3D10Texture2DKHR( + cl_context context, + cl_mem_flags flags, + ID3D10Texture2D* resource, + UINT subresource, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromD3D10Texture3DKHR( + cl_context context, + cl_mem_flags flags, + ID3D10Texture3D* resource, + UINT subresource, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireD3D10ObjectsKHR( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseD3D10ObjectsKHR( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_intel_sharing_format_query_d3d10 +***************************************************************/ +#define cl_intel_sharing_format_query_d3d10 1 +#define CL_INTEL_SHARING_FORMAT_QUERY_D3D10_EXTENSION_NAME \ + "cl_intel_sharing_format_query_d3d10" + + +#define CL_INTEL_SHARING_FORMAT_QUERY_D3D10_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* when cl_khr_d3d10_sharing is supported */ + +typedef cl_int CL_API_CALL +clGetSupportedD3D10TextureFormatsINTEL_t( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint num_entries, + DXGI_FORMAT* d3d10_formats, + cl_uint* num_texture_formats); + +typedef clGetSupportedD3D10TextureFormatsINTEL_t * +clGetSupportedD3D10TextureFormatsINTEL_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSupportedD3D10TextureFormatsINTEL( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint num_entries, + DXGI_FORMAT* d3d10_formats, + cl_uint* num_texture_formats) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#ifdef __cplusplus +} +#endif + +#endif /* OPENCL_CL_D3D10_H_ */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_d3d11.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_d3d11.h new file mode 100644 index 000000000..384c8f428 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_d3d11.h @@ -0,0 +1,270 @@ +/******************************************************************************* + * Copyright (c) 2008-2023 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef OPENCL_CL_D3D11_H_ +#define OPENCL_CL_D3D11_H_ + +/* +** This header is generated from the Khronos OpenCL XML API Registry. +*/ + +#if defined(_MSC_VER) +#if _MSC_VER >=1500 +#pragma warning( push ) +#pragma warning( disable : 4201 ) +#pragma warning( disable : 5105 ) +#endif +#endif +#include +#if defined(_MSC_VER) +#if _MSC_VER >=1500 +#pragma warning( pop ) +#endif +#endif + +#include + +/* CL_NO_PROTOTYPES implies CL_NO_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_PROTOTYPES) && !defined(CL_NO_EXTENSION_PROTOTYPES) +#define CL_NO_EXTENSION_PROTOTYPES +#endif + +/* CL_NO_EXTENSION_PROTOTYPES implies + CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES and + CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************** +* cl_khr_d3d11_sharing +***************************************************************/ +#define cl_khr_d3d11_sharing 1 +#define CL_KHR_D3D11_SHARING_EXTENSION_NAME \ + "cl_khr_d3d11_sharing" + + +#define CL_KHR_D3D11_SHARING_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_uint cl_d3d11_device_source_khr; +typedef cl_uint cl_d3d11_device_set_khr; + +/* Error codes */ +#define CL_INVALID_D3D11_DEVICE_KHR -1006 +#define CL_INVALID_D3D11_RESOURCE_KHR -1007 +#define CL_D3D11_RESOURCE_ALREADY_ACQUIRED_KHR -1008 +#define CL_D3D11_RESOURCE_NOT_ACQUIRED_KHR -1009 + +/* cl_d3d11_device_source_khr */ +#define CL_D3D11_DEVICE_KHR 0x4019 +#define CL_D3D11_DXGI_ADAPTER_KHR 0x401A + +/* cl_d3d11_device_set_khr */ +#define CL_PREFERRED_DEVICES_FOR_D3D11_KHR 0x401B +#define CL_ALL_DEVICES_FOR_D3D11_KHR 0x401C + +/* cl_context_info */ +#define CL_CONTEXT_D3D11_DEVICE_KHR 0x401D +#define CL_CONTEXT_D3D11_PREFER_SHARED_RESOURCES_KHR 0x402D + +/* cl_mem_info */ +#define CL_MEM_D3D11_RESOURCE_KHR 0x401E + +/* cl_image_info */ +#define CL_IMAGE_D3D11_SUBRESOURCE_KHR 0x401F + +/* cl_command_type */ +#define CL_COMMAND_ACQUIRE_D3D11_OBJECTS_KHR 0x4020 +#define CL_COMMAND_RELEASE_D3D11_OBJECTS_KHR 0x4021 + + +typedef cl_int CL_API_CALL +clGetDeviceIDsFromD3D11KHR_t( + cl_platform_id platform, + cl_d3d11_device_source_khr d3d_device_source, + void* d3d_object, + cl_d3d11_device_set_khr d3d_device_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices); + +typedef clGetDeviceIDsFromD3D11KHR_t * +clGetDeviceIDsFromD3D11KHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_mem CL_API_CALL +clCreateFromD3D11BufferKHR_t( + cl_context context, + cl_mem_flags flags, + ID3D11Buffer* resource, + cl_int* errcode_ret); + +typedef clCreateFromD3D11BufferKHR_t * +clCreateFromD3D11BufferKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_mem CL_API_CALL +clCreateFromD3D11Texture2DKHR_t( + cl_context context, + cl_mem_flags flags, + ID3D11Texture2D* resource, + UINT subresource, + cl_int* errcode_ret); + +typedef clCreateFromD3D11Texture2DKHR_t * +clCreateFromD3D11Texture2DKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_mem CL_API_CALL +clCreateFromD3D11Texture3DKHR_t( + cl_context context, + cl_mem_flags flags, + ID3D11Texture3D* resource, + UINT subresource, + cl_int* errcode_ret); + +typedef clCreateFromD3D11Texture3DKHR_t * +clCreateFromD3D11Texture3DKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueAcquireD3D11ObjectsKHR_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueAcquireD3D11ObjectsKHR_t * +clEnqueueAcquireD3D11ObjectsKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueReleaseD3D11ObjectsKHR_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReleaseD3D11ObjectsKHR_t * +clEnqueueReleaseD3D11ObjectsKHR_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceIDsFromD3D11KHR( + cl_platform_id platform, + cl_d3d11_device_source_khr d3d_device_source, + void* d3d_object, + cl_d3d11_device_set_khr d3d_device_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromD3D11BufferKHR( + cl_context context, + cl_mem_flags flags, + ID3D11Buffer* resource, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromD3D11Texture2DKHR( + cl_context context, + cl_mem_flags flags, + ID3D11Texture2D* resource, + UINT subresource, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromD3D11Texture3DKHR( + cl_context context, + cl_mem_flags flags, + ID3D11Texture3D* resource, + UINT subresource, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireD3D11ObjectsKHR( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseD3D11ObjectsKHR( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_intel_sharing_format_query_d3d11 +***************************************************************/ +#define cl_intel_sharing_format_query_d3d11 1 +#define CL_INTEL_SHARING_FORMAT_QUERY_D3D11_EXTENSION_NAME \ + "cl_intel_sharing_format_query_d3d11" + + +#define CL_INTEL_SHARING_FORMAT_QUERY_D3D11_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* when cl_khr_d3d11_sharing is supported */ + +typedef cl_int CL_API_CALL +clGetSupportedD3D11TextureFormatsINTEL_t( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint plane, + cl_uint num_entries, + DXGI_FORMAT* d3d11_formats, + cl_uint* num_texture_formats); + +typedef clGetSupportedD3D11TextureFormatsINTEL_t * +clGetSupportedD3D11TextureFormatsINTEL_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSupportedD3D11TextureFormatsINTEL( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint plane, + cl_uint num_entries, + DXGI_FORMAT* d3d11_formats, + cl_uint* num_texture_formats) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#ifdef __cplusplus +} +#endif + +#endif /* OPENCL_CL_D3D11_H_ */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_dx9_media_sharing.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_dx9_media_sharing.h new file mode 100644 index 000000000..b079379d0 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_dx9_media_sharing.h @@ -0,0 +1,386 @@ +/******************************************************************************* + * Copyright (c) 2008-2023 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef OPENCL_CL_DX9_MEDIA_SHARING_H_ +#define OPENCL_CL_DX9_MEDIA_SHARING_H_ + +/* +** This header is generated from the Khronos OpenCL XML API Registry. +*/ + +#if defined(_WIN32) +#if defined(_MSC_VER) +#if _MSC_VER >=1500 +#pragma warning( push ) +#pragma warning( disable : 4201 ) +#pragma warning( disable : 5105 ) +#endif +#endif +#include +#if defined(_MSC_VER) +#if _MSC_VER >=1500 +#pragma warning( pop ) +#endif +#endif +#endif + +#include + +/* CL_NO_PROTOTYPES implies CL_NO_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_PROTOTYPES) && !defined(CL_NO_EXTENSION_PROTOTYPES) +#define CL_NO_EXTENSION_PROTOTYPES +#endif + +/* CL_NO_EXTENSION_PROTOTYPES implies + CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES and + CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************** +* cl_khr_dx9_media_sharing +***************************************************************/ +#define cl_khr_dx9_media_sharing 1 +#define CL_KHR_DX9_MEDIA_SHARING_EXTENSION_NAME \ + "cl_khr_dx9_media_sharing" + + +#define CL_KHR_DX9_MEDIA_SHARING_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_uint cl_dx9_media_adapter_type_khr; +typedef cl_uint cl_dx9_media_adapter_set_khr; + +#if defined(_WIN32) +typedef struct _cl_dx9_surface_info_khr { + IDirect3DSurface9* resource; + HANDLE shared_handle; +} cl_dx9_surface_info_khr; + +#endif /* defined(_WIN32) */ + +/* Error codes */ +#define CL_INVALID_DX9_MEDIA_ADAPTER_KHR -1010 +#define CL_INVALID_DX9_MEDIA_SURFACE_KHR -1011 +#define CL_DX9_MEDIA_SURFACE_ALREADY_ACQUIRED_KHR -1012 +#define CL_DX9_MEDIA_SURFACE_NOT_ACQUIRED_KHR -1013 + +/* cl_media_adapter_type_khr */ +#define CL_ADAPTER_D3D9_KHR 0x2020 +#define CL_ADAPTER_D3D9EX_KHR 0x2021 +#define CL_ADAPTER_DXVA_KHR 0x2022 + +/* cl_media_adapter_set_khr */ +#define CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 0x2023 +#define CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR 0x2024 + +/* cl_context_info */ +#define CL_CONTEXT_ADAPTER_D3D9_KHR 0x2025 +#define CL_CONTEXT_ADAPTER_D3D9EX_KHR 0x2026 +#define CL_CONTEXT_ADAPTER_DXVA_KHR 0x2027 + +/* cl_mem_info */ +#define CL_MEM_DX9_MEDIA_ADAPTER_TYPE_KHR 0x2028 +#define CL_MEM_DX9_MEDIA_SURFACE_INFO_KHR 0x2029 + +/* cl_image_info */ +#define CL_IMAGE_DX9_MEDIA_PLANE_KHR 0x202A + +/* cl_command_type */ +#define CL_COMMAND_ACQUIRE_DX9_MEDIA_SURFACES_KHR 0x202B +#define CL_COMMAND_RELEASE_DX9_MEDIA_SURFACES_KHR 0x202C + + +typedef cl_int CL_API_CALL +clGetDeviceIDsFromDX9MediaAdapterKHR_t( + cl_platform_id platform, + cl_uint num_media_adapters, + cl_dx9_media_adapter_type_khr* media_adapter_type, + void* media_adapters, + cl_dx9_media_adapter_set_khr media_adapter_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices); + +typedef clGetDeviceIDsFromDX9MediaAdapterKHR_t * +clGetDeviceIDsFromDX9MediaAdapterKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_mem CL_API_CALL +clCreateFromDX9MediaSurfaceKHR_t( + cl_context context, + cl_mem_flags flags, + cl_dx9_media_adapter_type_khr adapter_type, + void* surface_info, + cl_uint plane, + cl_int* errcode_ret); + +typedef clCreateFromDX9MediaSurfaceKHR_t * +clCreateFromDX9MediaSurfaceKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueAcquireDX9MediaSurfacesKHR_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueAcquireDX9MediaSurfacesKHR_t * +clEnqueueAcquireDX9MediaSurfacesKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueReleaseDX9MediaSurfacesKHR_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReleaseDX9MediaSurfacesKHR_t * +clEnqueueReleaseDX9MediaSurfacesKHR_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceIDsFromDX9MediaAdapterKHR( + cl_platform_id platform, + cl_uint num_media_adapters, + cl_dx9_media_adapter_type_khr* media_adapter_type, + void* media_adapters, + cl_dx9_media_adapter_set_khr media_adapter_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromDX9MediaSurfaceKHR( + cl_context context, + cl_mem_flags flags, + cl_dx9_media_adapter_type_khr adapter_type, + void* surface_info, + cl_uint plane, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireDX9MediaSurfacesKHR( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseDX9MediaSurfacesKHR( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_intel_dx9_media_sharing +***************************************************************/ +#define cl_intel_dx9_media_sharing 1 +#define CL_INTEL_DX9_MEDIA_SHARING_EXTENSION_NAME \ + "cl_intel_dx9_media_sharing" + + +#define CL_INTEL_DX9_MEDIA_SHARING_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef cl_uint cl_dx9_device_source_intel; +typedef cl_uint cl_dx9_device_set_intel; + +/* Error codes */ +#define CL_INVALID_DX9_DEVICE_INTEL -1010 +#define CL_INVALID_DX9_RESOURCE_INTEL -1011 +#define CL_DX9_RESOURCE_ALREADY_ACQUIRED_INTEL -1012 +#define CL_DX9_RESOURCE_NOT_ACQUIRED_INTEL -1013 + +/* cl_dx9_device_source_intel */ +#define CL_D3D9_DEVICE_INTEL 0x4022 +#define CL_D3D9EX_DEVICE_INTEL 0x4070 +#define CL_DXVA_DEVICE_INTEL 0x4071 + +/* cl_dx9_device_set_intel */ +#define CL_PREFERRED_DEVICES_FOR_DX9_INTEL 0x4024 +#define CL_ALL_DEVICES_FOR_DX9_INTEL 0x4025 + +/* cl_context_info */ +#define CL_CONTEXT_D3D9_DEVICE_INTEL 0x4026 +#define CL_CONTEXT_D3D9EX_DEVICE_INTEL 0x4072 +#define CL_CONTEXT_DXVA_DEVICE_INTEL 0x4073 + +/* cl_mem_info */ +#define CL_MEM_DX9_RESOURCE_INTEL 0x4027 +#define CL_MEM_DX9_SHARED_HANDLE_INTEL 0x4074 + +/* cl_image_info */ +#define CL_IMAGE_DX9_PLANE_INTEL 0x4075 + +/* cl_command_type */ +#define CL_COMMAND_ACQUIRE_DX9_OBJECTS_INTEL 0x402A +#define CL_COMMAND_RELEASE_DX9_OBJECTS_INTEL 0x402B + + +typedef cl_int CL_API_CALL +clGetDeviceIDsFromDX9INTEL_t( + cl_platform_id platform, + cl_dx9_device_source_intel dx9_device_source, + void* dx9_object, + cl_dx9_device_set_intel dx9_device_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices); + +typedef clGetDeviceIDsFromDX9INTEL_t * +clGetDeviceIDsFromDX9INTEL_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_mem CL_API_CALL +clCreateFromDX9MediaSurfaceINTEL_t( + cl_context context, + cl_mem_flags flags, + IDirect3DSurface9* resource, + HANDLE sharedHandle, + UINT plane, + cl_int* errcode_ret); + +typedef clCreateFromDX9MediaSurfaceINTEL_t * +clCreateFromDX9MediaSurfaceINTEL_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL +clEnqueueAcquireDX9ObjectsINTEL_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueAcquireDX9ObjectsINTEL_t * +clEnqueueAcquireDX9ObjectsINTEL_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL +clEnqueueReleaseDX9ObjectsINTEL_t( + cl_command_queue command_queue, + cl_uint num_objects, + cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReleaseDX9ObjectsINTEL_t * +clEnqueueReleaseDX9ObjectsINTEL_fn CL_API_SUFFIX__VERSION_1_1; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceIDsFromDX9INTEL( + cl_platform_id platform, + cl_dx9_device_source_intel dx9_device_source, + void* dx9_object, + cl_dx9_device_set_intel dx9_device_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices) CL_API_SUFFIX__VERSION_1_1; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromDX9MediaSurfaceINTEL( + cl_context context, + cl_mem_flags flags, + IDirect3DSurface9* resource, + HANDLE sharedHandle, + UINT plane, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_1; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireDX9ObjectsINTEL( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_1; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseDX9ObjectsINTEL( + cl_command_queue command_queue, + cl_uint num_objects, + cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_1; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_intel_sharing_format_query_dx9 +***************************************************************/ +#define cl_intel_sharing_format_query_dx9 1 +#define CL_INTEL_SHARING_FORMAT_QUERY_DX9_EXTENSION_NAME \ + "cl_intel_sharing_format_query_dx9" + + +#define CL_INTEL_SHARING_FORMAT_QUERY_DX9_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* when cl_khr_dx9_media_sharing or cl_intel_dx9_media_sharing is supported */ + +typedef cl_int CL_API_CALL +clGetSupportedDX9MediaSurfaceFormatsINTEL_t( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint plane, + cl_uint num_entries, + D3DFORMAT* dx9_formats, + cl_uint* num_surface_formats); + +typedef clGetSupportedDX9MediaSurfaceFormatsINTEL_t * +clGetSupportedDX9MediaSurfaceFormatsINTEL_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSupportedDX9MediaSurfaceFormatsINTEL( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint plane, + cl_uint num_entries, + D3DFORMAT* dx9_formats, + cl_uint* num_surface_formats) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#ifdef __cplusplus +} +#endif + +#endif /* OPENCL_CL_DX9_MEDIA_SHARING_H_ */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_dx9_media_sharing_intel.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_dx9_media_sharing_intel.h new file mode 100644 index 000000000..f6518d7f6 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_dx9_media_sharing_intel.h @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2008-2020 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#include +#pragma message("The Intel DX9 media sharing extensions have been moved into cl_dx9_media_sharing.h. Please include cl_dx9_media_sharing.h directly.") diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_egl.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_egl.h new file mode 100644 index 000000000..68aefec76 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_egl.h @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2008-2023 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef OPENCL_CL_EGL_H_ +#define OPENCL_CL_EGL_H_ + +/* +** This header is generated from the Khronos OpenCL XML API Registry. +*/ + +#include + +/* CL_NO_PROTOTYPES implies CL_NO_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_PROTOTYPES) && !defined(CL_NO_EXTENSION_PROTOTYPES) +#define CL_NO_EXTENSION_PROTOTYPES +#endif + +/* CL_NO_EXTENSION_PROTOTYPES implies + CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES and + CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************** +* cl_khr_egl_image +***************************************************************/ +#define cl_khr_egl_image 1 +#define CL_KHR_EGL_IMAGE_EXTENSION_NAME \ + "cl_khr_egl_image" + + +#define CL_KHR_EGL_IMAGE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* Command type for events created with clEnqueueAcquireEGLObjectsKHR */ +#define CL_COMMAND_EGL_FENCE_SYNC_OBJECT_KHR 0x202F +#define CL_COMMAND_ACQUIRE_EGL_OBJECTS_KHR 0x202D +#define CL_COMMAND_RELEASE_EGL_OBJECTS_KHR 0x202E + +/* Error type for clCreateFromEGLImageKHR */ +#define CL_INVALID_EGL_OBJECT_KHR -1093 +#define CL_EGL_RESOURCE_NOT_ACQUIRED_KHR -1092 + +/* CLeglImageKHR is an opaque handle to an EGLImage */ +typedef void* CLeglImageKHR; + +/* CLeglDisplayKHR is an opaque handle to an EGLDisplay */ +typedef void* CLeglDisplayKHR; + +/* properties passed to clCreateFromEGLImageKHR */ +typedef intptr_t cl_egl_image_properties_khr; + + +typedef cl_mem CL_API_CALL +clCreateFromEGLImageKHR_t( + cl_context context, + CLeglDisplayKHR egldisplay, + CLeglImageKHR eglimage, + cl_mem_flags flags, + const cl_egl_image_properties_khr* properties, + cl_int* errcode_ret); + +typedef clCreateFromEGLImageKHR_t * +clCreateFromEGLImageKHR_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL +clEnqueueAcquireEGLObjectsKHR_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueAcquireEGLObjectsKHR_t * +clEnqueueAcquireEGLObjectsKHR_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL +clEnqueueReleaseEGLObjectsKHR_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReleaseEGLObjectsKHR_t * +clEnqueueReleaseEGLObjectsKHR_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromEGLImageKHR( + cl_context context, + CLeglDisplayKHR egldisplay, + CLeglImageKHR eglimage, + cl_mem_flags flags, + const cl_egl_image_properties_khr* properties, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireEGLObjectsKHR( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseEGLObjectsKHR( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_egl_event +***************************************************************/ +#define cl_khr_egl_event 1 +#define CL_KHR_EGL_EVENT_EXTENSION_NAME \ + "cl_khr_egl_event" + + +#define CL_KHR_EGL_EVENT_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* CLeglDisplayKHR is an opaque handle to an EGLDisplay */ +/* type CLeglDisplayKHR */ + +/* CLeglSyncKHR is an opaque handle to an EGLSync object */ +typedef void* CLeglSyncKHR; + + +typedef cl_event CL_API_CALL +clCreateEventFromEGLSyncKHR_t( + cl_context context, + CLeglSyncKHR sync, + CLeglDisplayKHR display, + cl_int* errcode_ret); + +typedef clCreateEventFromEGLSyncKHR_t * +clCreateEventFromEGLSyncKHR_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_event CL_API_CALL +clCreateEventFromEGLSyncKHR( + cl_context context, + CLeglSyncKHR sync, + CLeglDisplayKHR display, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#ifdef __cplusplus +} +#endif + +#endif /* OPENCL_CL_EGL_H_ */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_ext.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_ext.h new file mode 100644 index 000000000..688e24316 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_ext.h @@ -0,0 +1,4435 @@ +/******************************************************************************* + * Copyright (c) 2008-2023 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef OPENCL_CL_EXT_H_ +#define OPENCL_CL_EXT_H_ + +/* +** This header is generated from the Khronos OpenCL XML API Registry. +*/ + +#include + +/* CL_NO_PROTOTYPES implies CL_NO_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_PROTOTYPES) && !defined(CL_NO_EXTENSION_PROTOTYPES) +#define CL_NO_EXTENSION_PROTOTYPES +#endif + +/* CL_NO_EXTENSION_PROTOTYPES implies + CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES and + CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************** +* cl_khr_command_buffer (beta) +***************************************************************/ +#if defined(CL_ENABLE_BETA_EXTENSIONS) + +#define cl_khr_command_buffer 1 +#define CL_KHR_COMMAND_BUFFER_EXTENSION_NAME \ + "cl_khr_command_buffer" + + +#define CL_KHR_COMMAND_BUFFER_EXTENSION_VERSION CL_MAKE_VERSION(0, 9, 7) + +typedef cl_bitfield cl_device_command_buffer_capabilities_khr; +typedef struct _cl_command_buffer_khr* cl_command_buffer_khr; +typedef cl_uint cl_sync_point_khr; +typedef cl_uint cl_command_buffer_info_khr; +typedef cl_uint cl_command_buffer_state_khr; +typedef cl_properties cl_command_buffer_properties_khr; +typedef cl_bitfield cl_command_buffer_flags_khr; +typedef cl_properties cl_command_properties_khr; +typedef struct _cl_mutable_command_khr* cl_mutable_command_khr; + +/* cl_device_info */ +#define CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR 0x12A9 +#define CL_DEVICE_COMMAND_BUFFER_SUPPORTED_QUEUE_PROPERTIES_KHR 0x129A +#define CL_DEVICE_COMMAND_BUFFER_REQUIRED_QUEUE_PROPERTIES_KHR 0x12AA + +/* cl_device_command_buffer_capabilities_khr - bitfield */ +#define CL_COMMAND_BUFFER_CAPABILITY_KERNEL_PRINTF_KHR (1 << 0) +#define CL_COMMAND_BUFFER_CAPABILITY_DEVICE_SIDE_ENQUEUE_KHR (1 << 1) +#define CL_COMMAND_BUFFER_CAPABILITY_SIMULTANEOUS_USE_KHR (1 << 2) + +/* cl_command_buffer_properties_khr */ +#define CL_COMMAND_BUFFER_FLAGS_KHR 0x1293 + +/* cl_command_buffer_flags_khr - bitfield */ +#define CL_COMMAND_BUFFER_SIMULTANEOUS_USE_KHR (1 << 0) + +/* Error codes */ +#define CL_INVALID_COMMAND_BUFFER_KHR -1138 +#define CL_INVALID_SYNC_POINT_WAIT_LIST_KHR -1139 +#define CL_INCOMPATIBLE_COMMAND_QUEUE_KHR -1140 + +/* cl_command_buffer_info_khr */ +#define CL_COMMAND_BUFFER_QUEUES_KHR 0x1294 +#define CL_COMMAND_BUFFER_NUM_QUEUES_KHR 0x1295 +#define CL_COMMAND_BUFFER_REFERENCE_COUNT_KHR 0x1296 +#define CL_COMMAND_BUFFER_STATE_KHR 0x1297 +#define CL_COMMAND_BUFFER_PROPERTIES_ARRAY_KHR 0x1298 +#define CL_COMMAND_BUFFER_CONTEXT_KHR 0x1299 + +/* cl_command_buffer_state_khr */ +#define CL_COMMAND_BUFFER_STATE_RECORDING_KHR 0 +#define CL_COMMAND_BUFFER_STATE_EXECUTABLE_KHR 1 +#define CL_COMMAND_BUFFER_STATE_PENDING_KHR 2 + +/* cl_command_type */ +#define CL_COMMAND_COMMAND_BUFFER_KHR 0x12A8 + + +typedef cl_command_buffer_khr CL_API_CALL +clCreateCommandBufferKHR_t( + cl_uint num_queues, + const cl_command_queue* queues, + const cl_command_buffer_properties_khr* properties, + cl_int* errcode_ret); + +typedef clCreateCommandBufferKHR_t * +clCreateCommandBufferKHR_fn ; + +typedef cl_int CL_API_CALL +clFinalizeCommandBufferKHR_t( + cl_command_buffer_khr command_buffer); + +typedef clFinalizeCommandBufferKHR_t * +clFinalizeCommandBufferKHR_fn ; + +typedef cl_int CL_API_CALL +clRetainCommandBufferKHR_t( + cl_command_buffer_khr command_buffer); + +typedef clRetainCommandBufferKHR_t * +clRetainCommandBufferKHR_fn ; + +typedef cl_int CL_API_CALL +clReleaseCommandBufferKHR_t( + cl_command_buffer_khr command_buffer); + +typedef clReleaseCommandBufferKHR_t * +clReleaseCommandBufferKHR_fn ; + +typedef cl_int CL_API_CALL +clEnqueueCommandBufferKHR_t( + cl_uint num_queues, + cl_command_queue* queues, + cl_command_buffer_khr command_buffer, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueCommandBufferKHR_t * +clEnqueueCommandBufferKHR_fn ; + +typedef cl_int CL_API_CALL +clCommandBarrierWithWaitListKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandBarrierWithWaitListKHR_t * +clCommandBarrierWithWaitListKHR_fn ; + +typedef cl_int CL_API_CALL +clCommandCopyBufferKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_buffer, + cl_mem dst_buffer, + size_t src_offset, + size_t dst_offset, + size_t size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandCopyBufferKHR_t * +clCommandCopyBufferKHR_fn ; + +typedef cl_int CL_API_CALL +clCommandCopyBufferRectKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_buffer, + cl_mem dst_buffer, + const size_t* src_origin, + const size_t* dst_origin, + const size_t* region, + size_t src_row_pitch, + size_t src_slice_pitch, + size_t dst_row_pitch, + size_t dst_slice_pitch, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandCopyBufferRectKHR_t * +clCommandCopyBufferRectKHR_fn ; + +typedef cl_int CL_API_CALL +clCommandCopyBufferToImageKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_buffer, + cl_mem dst_image, + size_t src_offset, + const size_t* dst_origin, + const size_t* region, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandCopyBufferToImageKHR_t * +clCommandCopyBufferToImageKHR_fn ; + +typedef cl_int CL_API_CALL +clCommandCopyImageKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_image, + cl_mem dst_image, + const size_t* src_origin, + const size_t* dst_origin, + const size_t* region, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandCopyImageKHR_t * +clCommandCopyImageKHR_fn ; + +typedef cl_int CL_API_CALL +clCommandCopyImageToBufferKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_image, + cl_mem dst_buffer, + const size_t* src_origin, + const size_t* region, + size_t dst_offset, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandCopyImageToBufferKHR_t * +clCommandCopyImageToBufferKHR_fn ; + +typedef cl_int CL_API_CALL +clCommandFillBufferKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem buffer, + const void* pattern, + size_t pattern_size, + size_t offset, + size_t size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandFillBufferKHR_t * +clCommandFillBufferKHR_fn ; + +typedef cl_int CL_API_CALL +clCommandFillImageKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem image, + const void* fill_color, + const size_t* origin, + const size_t* region, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandFillImageKHR_t * +clCommandFillImageKHR_fn ; + +typedef cl_int CL_API_CALL +clCommandNDRangeKernelKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_kernel kernel, + cl_uint work_dim, + const size_t* global_work_offset, + const size_t* global_work_size, + const size_t* local_work_size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandNDRangeKernelKHR_t * +clCommandNDRangeKernelKHR_fn ; + +typedef cl_int CL_API_CALL +clGetCommandBufferInfoKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_buffer_info_khr param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetCommandBufferInfoKHR_t * +clGetCommandBufferInfoKHR_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_command_buffer_khr CL_API_CALL +clCreateCommandBufferKHR( + cl_uint num_queues, + const cl_command_queue* queues, + const cl_command_buffer_properties_khr* properties, + cl_int* errcode_ret) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clFinalizeCommandBufferKHR( + cl_command_buffer_khr command_buffer) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainCommandBufferKHR( + cl_command_buffer_khr command_buffer) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseCommandBufferKHR( + cl_command_buffer_khr command_buffer) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueCommandBufferKHR( + cl_uint num_queues, + cl_command_queue* queues, + cl_command_buffer_khr command_buffer, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandBarrierWithWaitListKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandCopyBufferKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_buffer, + cl_mem dst_buffer, + size_t src_offset, + size_t dst_offset, + size_t size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandCopyBufferRectKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_buffer, + cl_mem dst_buffer, + const size_t* src_origin, + const size_t* dst_origin, + const size_t* region, + size_t src_row_pitch, + size_t src_slice_pitch, + size_t dst_row_pitch, + size_t dst_slice_pitch, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandCopyBufferToImageKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_buffer, + cl_mem dst_image, + size_t src_offset, + const size_t* dst_origin, + const size_t* region, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandCopyImageKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_image, + cl_mem dst_image, + const size_t* src_origin, + const size_t* dst_origin, + const size_t* region, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandCopyImageToBufferKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem src_image, + cl_mem dst_buffer, + const size_t* src_origin, + const size_t* region, + size_t dst_offset, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandFillBufferKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem buffer, + const void* pattern, + size_t pattern_size, + size_t offset, + size_t size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandFillImageKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_mem image, + const void* fill_color, + const size_t* origin, + const size_t* region, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandNDRangeKernelKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + cl_kernel kernel, + cl_uint work_dim, + const size_t* global_work_offset, + const size_t* global_work_size, + const size_t* local_work_size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetCommandBufferInfoKHR( + cl_command_buffer_khr command_buffer, + cl_command_buffer_info_khr param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/* From version 0.9.4 of the extension */ + +typedef cl_int CL_API_CALL +clCommandSVMMemcpyKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + void* dst_ptr, + const void* src_ptr, + size_t size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandSVMMemcpyKHR_t * +clCommandSVMMemcpyKHR_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_int CL_API_CALL +clCommandSVMMemFillKHR_t( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + void* svm_ptr, + const void* pattern, + size_t pattern_size, + size_t size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle); + +typedef clCommandSVMMemFillKHR_t * +clCommandSVMMemFillKHR_fn CL_API_SUFFIX__VERSION_2_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandSVMMemcpyKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + void* dst_ptr, + const void* src_ptr, + size_t size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) CL_API_SUFFIX__VERSION_2_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCommandSVMMemFillKHR( + cl_command_buffer_khr command_buffer, + cl_command_queue command_queue, + const cl_command_properties_khr* properties, + void* svm_ptr, + const void* pattern, + size_t pattern_size, + size_t size, + cl_uint num_sync_points_in_wait_list, + const cl_sync_point_khr* sync_point_wait_list, + cl_sync_point_khr* sync_point, + cl_mutable_command_khr* mutable_handle) CL_API_SUFFIX__VERSION_2_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#endif /* defined(CL_ENABLE_BETA_EXTENSIONS) */ + +/*************************************************************** +* cl_khr_command_buffer_multi_device (beta) +***************************************************************/ +#if defined(CL_ENABLE_BETA_EXTENSIONS) + +#define cl_khr_command_buffer_multi_device 1 +#define CL_KHR_COMMAND_BUFFER_MULTI_DEVICE_EXTENSION_NAME \ + "cl_khr_command_buffer_multi_device" + + +#define CL_KHR_COMMAND_BUFFER_MULTI_DEVICE_EXTENSION_VERSION CL_MAKE_VERSION(0, 9, 2) + +typedef cl_bitfield cl_platform_command_buffer_capabilities_khr; + +/* cl_platform_info */ +#define CL_PLATFORM_COMMAND_BUFFER_CAPABILITIES_KHR 0x0908 + +/* cl_platform_command_buffer_capabilities_khr - bitfield */ +#define CL_COMMAND_BUFFER_PLATFORM_UNIVERSAL_SYNC_KHR (1 << 0) +#define CL_COMMAND_BUFFER_PLATFORM_REMAP_QUEUES_KHR (1 << 1) +#define CL_COMMAND_BUFFER_PLATFORM_AUTOMATIC_REMAP_KHR (1 << 2) + +/* cl_device_info */ +#define CL_DEVICE_COMMAND_BUFFER_NUM_SYNC_DEVICES_KHR 0x12AB +#define CL_DEVICE_COMMAND_BUFFER_SYNC_DEVICES_KHR 0x12AC + +/* cl_device_command_buffer_capabilities_khr - bitfield */ +#define CL_COMMAND_BUFFER_CAPABILITY_MULTIPLE_QUEUE_KHR (1 << 4) + +/* cl_command_buffer_flags_khr - bitfield */ +#define CL_COMMAND_BUFFER_DEVICE_SIDE_SYNC_KHR (1 << 2) + + +typedef cl_command_buffer_khr CL_API_CALL +clRemapCommandBufferKHR_t( + cl_command_buffer_khr command_buffer, + cl_bool automatic, + cl_uint num_queues, + const cl_command_queue* queues, + cl_uint num_handles, + const cl_mutable_command_khr* handles, + cl_mutable_command_khr* handles_ret, + cl_int* errcode_ret); + +typedef clRemapCommandBufferKHR_t * +clRemapCommandBufferKHR_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_command_buffer_khr CL_API_CALL +clRemapCommandBufferKHR( + cl_command_buffer_khr command_buffer, + cl_bool automatic, + cl_uint num_queues, + const cl_command_queue* queues, + cl_uint num_handles, + const cl_mutable_command_khr* handles, + cl_mutable_command_khr* handles_ret, + cl_int* errcode_ret) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#endif /* defined(CL_ENABLE_BETA_EXTENSIONS) */ + +/*************************************************************** +* cl_khr_command_buffer_mutable_dispatch (beta) +***************************************************************/ +#if defined(CL_ENABLE_BETA_EXTENSIONS) + +#define cl_khr_command_buffer_mutable_dispatch 1 +#define CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_NAME \ + "cl_khr_command_buffer_mutable_dispatch" + + +#define CL_KHR_COMMAND_BUFFER_MUTABLE_DISPATCH_EXTENSION_VERSION CL_MAKE_VERSION(0, 9, 3) + +typedef cl_uint cl_command_buffer_update_type_khr; +typedef cl_bitfield cl_mutable_dispatch_fields_khr; +typedef cl_uint cl_mutable_command_info_khr; +typedef struct _cl_mutable_dispatch_arg_khr { + cl_uint arg_index; + size_t arg_size; + const void* arg_value; +} cl_mutable_dispatch_arg_khr; +typedef struct _cl_mutable_dispatch_exec_info_khr { + cl_uint param_name; + size_t param_value_size; + const void* param_value; +} cl_mutable_dispatch_exec_info_khr; +typedef struct _cl_mutable_dispatch_config_khr { + cl_mutable_command_khr command; + cl_uint num_args; + cl_uint num_svm_args; + cl_uint num_exec_infos; + cl_uint work_dim; + const cl_mutable_dispatch_arg_khr* arg_list; + const cl_mutable_dispatch_arg_khr* arg_svm_list; + const cl_mutable_dispatch_exec_info_khr* exec_info_list; + const size_t* global_work_offset; + const size_t* global_work_size; + const size_t* local_work_size; +} cl_mutable_dispatch_config_khr; +typedef cl_bitfield cl_mutable_dispatch_asserts_khr; + +/* cl_command_buffer_flags_khr - bitfield */ +#define CL_COMMAND_BUFFER_MUTABLE_KHR (1 << 1) + +/* Error codes */ +#define CL_INVALID_MUTABLE_COMMAND_KHR -1141 + +/* cl_device_info */ +#define CL_DEVICE_MUTABLE_DISPATCH_CAPABILITIES_KHR 0x12B0 + +/* cl_command_properties_khr */ +#define CL_MUTABLE_DISPATCH_UPDATABLE_FIELDS_KHR 0x12B1 + +/* cl_mutable_dispatch_fields_khr - bitfield */ +#define CL_MUTABLE_DISPATCH_GLOBAL_OFFSET_KHR (1 << 0) +#define CL_MUTABLE_DISPATCH_GLOBAL_SIZE_KHR (1 << 1) +#define CL_MUTABLE_DISPATCH_LOCAL_SIZE_KHR (1 << 2) +#define CL_MUTABLE_DISPATCH_ARGUMENTS_KHR (1 << 3) +#define CL_MUTABLE_DISPATCH_EXEC_INFO_KHR (1 << 4) + +/* cl_mutable_command_info_khr */ +#define CL_MUTABLE_COMMAND_COMMAND_QUEUE_KHR 0x12A0 +#define CL_MUTABLE_COMMAND_COMMAND_BUFFER_KHR 0x12A1 +#define CL_MUTABLE_COMMAND_COMMAND_TYPE_KHR 0x12AD +#define CL_MUTABLE_COMMAND_PROPERTIES_ARRAY_KHR 0x12A2 +#define CL_MUTABLE_DISPATCH_KERNEL_KHR 0x12A3 +#define CL_MUTABLE_DISPATCH_DIMENSIONS_KHR 0x12A4 +#define CL_MUTABLE_DISPATCH_GLOBAL_WORK_OFFSET_KHR 0x12A5 +#define CL_MUTABLE_DISPATCH_GLOBAL_WORK_SIZE_KHR 0x12A6 +#define CL_MUTABLE_DISPATCH_LOCAL_WORK_SIZE_KHR 0x12A7 + +/* cl_command_buffer_update_type_khr */ +#define CL_STRUCTURE_TYPE_MUTABLE_DISPATCH_CONFIG_KHR 0 + +/* cl_command_buffer_properties_khr */ +#define CL_COMMAND_BUFFER_MUTABLE_DISPATCH_ASSERTS_KHR 0x12B7 + +/* cl_command_properties_khr */ +#define CL_MUTABLE_DISPATCH_ASSERTS_KHR 0x12B8 + +/* cl_mutable_dispatch_asserts_khr - bitfield */ +#define CL_MUTABLE_DISPATCH_ASSERT_NO_ADDITIONAL_WORK_GROUPS_KHR (1 << 0) + + +typedef cl_int CL_API_CALL +clUpdateMutableCommandsKHR_t( + cl_command_buffer_khr command_buffer, + cl_uint num_configs, + const cl_command_buffer_update_type_khr* config_types, + const void** configs); + +typedef clUpdateMutableCommandsKHR_t * +clUpdateMutableCommandsKHR_fn ; + +typedef cl_int CL_API_CALL +clGetMutableCommandInfoKHR_t( + cl_mutable_command_khr command, + cl_mutable_command_info_khr param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetMutableCommandInfoKHR_t * +clGetMutableCommandInfoKHR_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clUpdateMutableCommandsKHR( + cl_command_buffer_khr command_buffer, + cl_uint num_configs, + const cl_command_buffer_update_type_khr* config_types, + const void** configs) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetMutableCommandInfoKHR( + cl_mutable_command_khr command, + cl_mutable_command_info_khr param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#endif /* defined(CL_ENABLE_BETA_EXTENSIONS) */ + +/*************************************************************** +* cl_khr_fp64 +***************************************************************/ +#define cl_khr_fp64 1 +#define CL_KHR_FP64_EXTENSION_NAME \ + "cl_khr_fp64" + + +#define CL_KHR_FP64_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +#if !defined(CL_VERSION_1_2) +/* cl_device_info - defined in CL.h for OpenCL 1.2 and newer */ +#define CL_DEVICE_DOUBLE_FP_CONFIG 0x1032 + +#endif /* !defined(CL_VERSION_1_2) */ + +/*************************************************************** +* cl_khr_fp16 +***************************************************************/ +#define cl_khr_fp16 1 +#define CL_KHR_FP16_EXTENSION_NAME \ + "cl_khr_fp16" + + +#define CL_KHR_FP16_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_HALF_FP_CONFIG 0x1033 + +/*************************************************************** +* cl_APPLE_SetMemObjectDestructor +***************************************************************/ +#define cl_APPLE_SetMemObjectDestructor 1 +#define CL_APPLE_SETMEMOBJECTDESTRUCTOR_EXTENSION_NAME \ + "cl_APPLE_SetMemObjectDestructor" + + +#define CL_APPLE_SETMEMOBJECTDESTRUCTOR_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + + +typedef cl_int CL_API_CALL +clSetMemObjectDestructorAPPLE_t( + cl_mem memobj, + void (CL_CALLBACK* pfn_notify)(cl_mem memobj, void* user_data), + void* user_data); + +typedef clSetMemObjectDestructorAPPLE_t * +clSetMemObjectDestructorAPPLE_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetMemObjectDestructorAPPLE( + cl_mem memobj, + void (CL_CALLBACK* pfn_notify)(cl_mem memobj, void* user_data), + void* user_data) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_APPLE_ContextLoggingFunctions +***************************************************************/ +#define cl_APPLE_ContextLoggingFunctions 1 +#define CL_APPLE_CONTEXTLOGGINGFUNCTIONS_EXTENSION_NAME \ + "cl_APPLE_ContextLoggingFunctions" + + +#define CL_APPLE_CONTEXTLOGGINGFUNCTIONS_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + + +typedef void CL_API_CALL +clLogMessagesToSystemLogAPPLE_t( + const char* errstr, + const void* private_info, + size_t cb, + void* user_data); + +typedef clLogMessagesToSystemLogAPPLE_t * +clLogMessagesToSystemLogAPPLE_fn CL_API_SUFFIX__VERSION_1_0; + +typedef void CL_API_CALL +clLogMessagesToStdoutAPPLE_t( + const char* errstr, + const void* private_info, + size_t cb, + void* user_data); + +typedef clLogMessagesToStdoutAPPLE_t * +clLogMessagesToStdoutAPPLE_fn CL_API_SUFFIX__VERSION_1_0; + +typedef void CL_API_CALL +clLogMessagesToStderrAPPLE_t( + const char* errstr, + const void* private_info, + size_t cb, + void* user_data); + +typedef clLogMessagesToStderrAPPLE_t * +clLogMessagesToStderrAPPLE_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY void CL_API_CALL +clLogMessagesToSystemLogAPPLE( + const char* errstr, + const void* private_info, + size_t cb, + void* user_data) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY void CL_API_CALL +clLogMessagesToStdoutAPPLE( + const char* errstr, + const void* private_info, + size_t cb, + void* user_data) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY void CL_API_CALL +clLogMessagesToStderrAPPLE( + const char* errstr, + const void* private_info, + size_t cb, + void* user_data) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_icd +***************************************************************/ +#define cl_khr_icd 1 +#define CL_KHR_ICD_EXTENSION_NAME \ + "cl_khr_icd" + + +#define CL_KHR_ICD_EXTENSION_VERSION CL_MAKE_VERSION(2, 0, 0) + +/* cl_platform_info */ +#define CL_PLATFORM_ICD_SUFFIX_KHR 0x0920 + +/* Error codes */ +#define CL_PLATFORM_NOT_FOUND_KHR -1001 + +/* ICD 2 tag value */ +#if INTPTR_MAX == INT32_MAX +#define CL_ICD2_TAG_KHR ((intptr_t)0x434C3331) +#else +#define CL_ICD2_TAG_KHR ((intptr_t)0x4F50454E434C3331) +#endif + + +typedef cl_int CL_API_CALL +clIcdGetPlatformIDsKHR_t( + cl_uint num_entries, + cl_platform_id* platforms, + cl_uint* num_platforms); + +typedef clIcdGetPlatformIDsKHR_t * +clIcdGetPlatformIDsKHR_fn ; + +typedef void* CL_API_CALL +clIcdGetFunctionAddressForPlatformKHR_t( + cl_platform_id platform, + const char* func_name); + +typedef clIcdGetFunctionAddressForPlatformKHR_t * +clIcdGetFunctionAddressForPlatformKHR_fn ; + +typedef cl_int CL_API_CALL +clIcdSetPlatformDispatchDataKHR_t( + cl_platform_id platform, + void* dispatch_data); + +typedef clIcdSetPlatformDispatchDataKHR_t * +clIcdSetPlatformDispatchDataKHR_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clIcdGetPlatformIDsKHR( + cl_uint num_entries, + cl_platform_id* platforms, + cl_uint* num_platforms) ; + +extern CL_API_ENTRY void* CL_API_CALL +clIcdGetFunctionAddressForPlatformKHR( + cl_platform_id platform, + const char* func_name) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clIcdSetPlatformDispatchDataKHR( + cl_platform_id platform, + void* dispatch_data) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_il_program +***************************************************************/ +#define cl_khr_il_program 1 +#define CL_KHR_IL_PROGRAM_EXTENSION_NAME \ + "cl_khr_il_program" + + +#define CL_KHR_IL_PROGRAM_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_IL_VERSION_KHR 0x105B + +/* cl_program_info */ +#define CL_PROGRAM_IL_KHR 0x1169 + + +typedef cl_program CL_API_CALL +clCreateProgramWithILKHR_t( + cl_context context, + const void* il, + size_t length, + cl_int* errcode_ret); + +typedef clCreateProgramWithILKHR_t * +clCreateProgramWithILKHR_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_program CL_API_CALL +clCreateProgramWithILKHR( + cl_context context, + const void* il, + size_t length, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_image2d_from_buffer +***************************************************************/ +#define cl_khr_image2d_from_buffer 1 +#define CL_KHR_IMAGE2D_FROM_BUFFER_EXTENSION_NAME \ + "cl_khr_image2d_from_buffer" + + +#define CL_KHR_IMAGE2D_FROM_BUFFER_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_IMAGE_PITCH_ALIGNMENT_KHR 0x104A +#define CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT_KHR 0x104B + +/*************************************************************** +* cl_khr_initialize_memory +***************************************************************/ +#define cl_khr_initialize_memory 1 +#define CL_KHR_INITIALIZE_MEMORY_EXTENSION_NAME \ + "cl_khr_initialize_memory" + + +#define CL_KHR_INITIALIZE_MEMORY_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_bitfield cl_context_memory_initialize_khr; + +/* cl_context_properties */ +#define CL_CONTEXT_MEMORY_INITIALIZE_KHR 0x2030 + +/* cl_context_memory_initialize_khr */ +#define CL_CONTEXT_MEMORY_INITIALIZE_LOCAL_KHR (1 << 0) +#define CL_CONTEXT_MEMORY_INITIALIZE_PRIVATE_KHR (1 << 1) + +/*************************************************************** +* cl_khr_terminate_context +***************************************************************/ +#define cl_khr_terminate_context 1 +#define CL_KHR_TERMINATE_CONTEXT_EXTENSION_NAME \ + "cl_khr_terminate_context" + + +#define CL_KHR_TERMINATE_CONTEXT_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_bitfield cl_device_terminate_capability_khr; + +/* cl_device_info */ +#define CL_DEVICE_TERMINATE_CAPABILITY_KHR 0x2031 + +/* cl_context_properties */ +#define CL_CONTEXT_TERMINATE_KHR 0x2032 + +/* cl_device_terminate_capability_khr */ +#define CL_DEVICE_TERMINATE_CAPABILITY_CONTEXT_KHR (1 << 0) + +/* Error codes */ +#define CL_CONTEXT_TERMINATED_KHR -1121 + + +typedef cl_int CL_API_CALL +clTerminateContextKHR_t( + cl_context context); + +typedef clTerminateContextKHR_t * +clTerminateContextKHR_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clTerminateContextKHR( + cl_context context) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_spir +***************************************************************/ +#define cl_khr_spir 1 +#define CL_KHR_SPIR_EXTENSION_NAME \ + "cl_khr_spir" + + +#define CL_KHR_SPIR_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_SPIR_VERSIONS 0x40E0 + +/* cl_program_binary_type */ +#define CL_PROGRAM_BINARY_TYPE_INTERMEDIATE 0x40E1 + +/*************************************************************** +* cl_khr_create_command_queue +***************************************************************/ +#define cl_khr_create_command_queue 1 +#define CL_KHR_CREATE_COMMAND_QUEUE_EXTENSION_NAME \ + "cl_khr_create_command_queue" + + +#define CL_KHR_CREATE_COMMAND_QUEUE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_properties cl_queue_properties_khr; + + +typedef cl_command_queue CL_API_CALL +clCreateCommandQueueWithPropertiesKHR_t( + cl_context context, + cl_device_id device, + const cl_queue_properties_khr* properties, + cl_int* errcode_ret); + +typedef clCreateCommandQueueWithPropertiesKHR_t * +clCreateCommandQueueWithPropertiesKHR_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_command_queue CL_API_CALL +clCreateCommandQueueWithPropertiesKHR( + cl_context context, + cl_device_id device, + const cl_queue_properties_khr* properties, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_nv_device_attribute_query +***************************************************************/ +#define cl_nv_device_attribute_query 1 +#define CL_NV_DEVICE_ATTRIBUTE_QUERY_EXTENSION_NAME \ + "cl_nv_device_attribute_query" + + +#define CL_NV_DEVICE_ATTRIBUTE_QUERY_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000 +#define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001 +#define CL_DEVICE_REGISTERS_PER_BLOCK_NV 0x4002 +#define CL_DEVICE_WARP_SIZE_NV 0x4003 +#define CL_DEVICE_GPU_OVERLAP_NV 0x4004 +#define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005 +#define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006 + +/*************************************************************** +* cl_amd_device_attribute_query +***************************************************************/ +#define cl_amd_device_attribute_query 1 +#define CL_AMD_DEVICE_ATTRIBUTE_QUERY_EXTENSION_NAME \ + "cl_amd_device_attribute_query" + + +#define CL_AMD_DEVICE_ATTRIBUTE_QUERY_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_PROFILING_TIMER_OFFSET_AMD 0x4036 +#define CL_DEVICE_TOPOLOGY_AMD 0x4037 +#define CL_DEVICE_BOARD_NAME_AMD 0x4038 +#define CL_DEVICE_GLOBAL_FREE_MEMORY_AMD 0x4039 +#define CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD 0x4040 +#define CL_DEVICE_SIMD_WIDTH_AMD 0x4041 +#define CL_DEVICE_SIMD_INSTRUCTION_WIDTH_AMD 0x4042 +#define CL_DEVICE_WAVEFRONT_WIDTH_AMD 0x4043 +#define CL_DEVICE_GLOBAL_MEM_CHANNELS_AMD 0x4044 +#define CL_DEVICE_GLOBAL_MEM_CHANNEL_BANKS_AMD 0x4045 +#define CL_DEVICE_GLOBAL_MEM_CHANNEL_BANK_WIDTH_AMD 0x4046 +#define CL_DEVICE_LOCAL_MEM_SIZE_PER_COMPUTE_UNIT_AMD 0x4047 +#define CL_DEVICE_LOCAL_MEM_BANKS_AMD 0x4048 +#define CL_DEVICE_THREAD_TRACE_SUPPORTED_AMD 0x4049 +#define CL_DEVICE_GFXIP_MAJOR_AMD 0x404A +#define CL_DEVICE_GFXIP_MINOR_AMD 0x404B +#define CL_DEVICE_AVAILABLE_ASYNC_QUEUES_AMD 0x404C +#define CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_AMD 0x4030 +#define CL_DEVICE_MAX_WORK_GROUP_SIZE_AMD 0x4031 +#define CL_DEVICE_PREFERRED_CONSTANT_BUFFER_SIZE_AMD 0x4033 +#define CL_DEVICE_PCIE_ID_AMD 0x4034 + +/*************************************************************** +* cl_arm_printf +***************************************************************/ +#define cl_arm_printf 1 +#define CL_ARM_PRINTF_EXTENSION_NAME \ + "cl_arm_printf" + + +#define CL_ARM_PRINTF_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_context_properties */ +#define CL_PRINTF_CALLBACK_ARM 0x40B0 +#define CL_PRINTF_BUFFERSIZE_ARM 0x40B1 + +/*************************************************************** +* cl_ext_device_fission +***************************************************************/ +#define cl_ext_device_fission 1 +#define CL_EXT_DEVICE_FISSION_EXTENSION_NAME \ + "cl_ext_device_fission" + + +#define CL_EXT_DEVICE_FISSION_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_ulong cl_device_partition_property_ext; + +/* Error codes */ +#define CL_DEVICE_PARTITION_FAILED_EXT -1057 +#define CL_INVALID_PARTITION_COUNT_EXT -1058 +#define CL_INVALID_PARTITION_NAME_EXT -1059 + +/* cl_device_info */ +#define CL_DEVICE_PARENT_DEVICE_EXT 0x4054 +#define CL_DEVICE_PARTITION_TYPES_EXT 0x4055 +#define CL_DEVICE_AFFINITY_DOMAINS_EXT 0x4056 +#define CL_DEVICE_REFERENCE_COUNT_EXT 0x4057 +#define CL_DEVICE_PARTITION_STYLE_EXT 0x4058 + +/* cl_device_partition_property_ext */ +#define CL_DEVICE_PARTITION_EQUALLY_EXT 0x4050 +#define CL_DEVICE_PARTITION_BY_COUNTS_EXT 0x4051 +#define CL_DEVICE_PARTITION_BY_NAMES_EXT 0x4052 +#define CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT 0x4053 + +/* cl_device_partition_property_ext - affinity domains */ +#define CL_AFFINITY_DOMAIN_L1_CACHE_EXT 0x1 +#define CL_AFFINITY_DOMAIN_L2_CACHE_EXT 0x2 +#define CL_AFFINITY_DOMAIN_L3_CACHE_EXT 0x3 +#define CL_AFFINITY_DOMAIN_L4_CACHE_EXT 0x4 +#define CL_AFFINITY_DOMAIN_NUMA_EXT 0x10 +#define CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT 0x100 + +/* cl_device_partition_property_ext - list terminators */ +#define CL_PROPERTIES_LIST_END_EXT ((cl_device_partition_property_ext)0) +#define CL_PARTITION_BY_COUNTS_LIST_END_EXT ((cl_device_partition_property_ext)0) +#define CL_PARTITION_BY_NAMES_LIST_END_EXT ((cl_device_partition_property_ext)0 - 1) + + +typedef cl_int CL_API_CALL +clReleaseDeviceEXT_t( + cl_device_id device); + +typedef clReleaseDeviceEXT_t * +clReleaseDeviceEXT_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL +clRetainDeviceEXT_t( + cl_device_id device); + +typedef clRetainDeviceEXT_t * +clRetainDeviceEXT_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL +clCreateSubDevicesEXT_t( + cl_device_id in_device, + const cl_device_partition_property_ext* properties, + cl_uint num_entries, + cl_device_id* out_devices, + cl_uint* num_devices); + +typedef clCreateSubDevicesEXT_t * +clCreateSubDevicesEXT_fn CL_API_SUFFIX__VERSION_1_1; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseDeviceEXT( + cl_device_id device) CL_API_SUFFIX__VERSION_1_1; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainDeviceEXT( + cl_device_id device) CL_API_SUFFIX__VERSION_1_1; + +extern CL_API_ENTRY cl_int CL_API_CALL +clCreateSubDevicesEXT( + cl_device_id in_device, + const cl_device_partition_property_ext* properties, + cl_uint num_entries, + cl_device_id* out_devices, + cl_uint* num_devices) CL_API_SUFFIX__VERSION_1_1; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_ext_migrate_memobject +***************************************************************/ +#define cl_ext_migrate_memobject 1 +#define CL_EXT_MIGRATE_MEMOBJECT_EXTENSION_NAME \ + "cl_ext_migrate_memobject" + + +#define CL_EXT_MIGRATE_MEMOBJECT_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_bitfield cl_mem_migration_flags_ext; + +/* cl_mem_migration_flags_ext */ +#define CL_MIGRATE_MEM_OBJECT_HOST_EXT (1 << 0) + +/* cl_command_type */ +#define CL_COMMAND_MIGRATE_MEM_OBJECT_EXT 0x4040 + + +typedef cl_int CL_API_CALL +clEnqueueMigrateMemObjectEXT_t( + cl_command_queue command_queue, + cl_uint num_mem_objects, + const cl_mem* mem_objects, + cl_mem_migration_flags_ext flags, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueMigrateMemObjectEXT_t * +clEnqueueMigrateMemObjectEXT_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMigrateMemObjectEXT( + cl_command_queue command_queue, + cl_uint num_mem_objects, + const cl_mem* mem_objects, + cl_mem_migration_flags_ext flags, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_ext_cxx_for_opencl +***************************************************************/ +#define cl_ext_cxx_for_opencl 1 +#define CL_EXT_CXX_FOR_OPENCL_EXTENSION_NAME \ + "cl_ext_cxx_for_opencl" + + +#define CL_EXT_CXX_FOR_OPENCL_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_CXX_FOR_OPENCL_NUMERIC_VERSION_EXT 0x4230 + +/*************************************************************** +* cl_qcom_ext_host_ptr +***************************************************************/ +#define cl_qcom_ext_host_ptr 1 +#define CL_QCOM_EXT_HOST_PTR_EXTENSION_NAME \ + "cl_qcom_ext_host_ptr" + + +#define CL_QCOM_EXT_HOST_PTR_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef cl_uint cl_image_pitch_info_qcom; +typedef struct _cl_mem_ext_host_ptr { + cl_uint allocation_type; + cl_uint host_cache_policy; +} cl_mem_ext_host_ptr; + +/* cl_mem_flags */ +#define CL_MEM_EXT_HOST_PTR_QCOM (1 << 29) + +/* cl_device_info */ +#define CL_DEVICE_EXT_MEM_PADDING_IN_BYTES_QCOM 0x40A0 +#define CL_DEVICE_PAGE_SIZE_QCOM 0x40A1 + +/* cl_image_pitch_info_qcom */ +#define CL_IMAGE_ROW_ALIGNMENT_QCOM 0x40A2 +#define CL_IMAGE_SLICE_ALIGNMENT_QCOM 0x40A3 + +/* cl_uint host_cache_policy */ +#define CL_MEM_HOST_UNCACHED_QCOM 0x40A4 +#define CL_MEM_HOST_WRITEBACK_QCOM 0x40A5 +#define CL_MEM_HOST_WRITETHROUGH_QCOM 0x40A6 +#define CL_MEM_HOST_WRITE_COMBINING_QCOM 0x40A7 + + +typedef cl_int CL_API_CALL +clGetDeviceImageInfoQCOM_t( + cl_device_id device, + size_t image_width, + size_t image_height, + const cl_image_format* image_format, + cl_image_pitch_info_qcom param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetDeviceImageInfoQCOM_t * +clGetDeviceImageInfoQCOM_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceImageInfoQCOM( + cl_device_id device, + size_t image_width, + size_t image_height, + const cl_image_format* image_format, + cl_image_pitch_info_qcom param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_qcom_ext_host_ptr_iocoherent +***************************************************************/ +#define cl_qcom_ext_host_ptr_iocoherent 1 +#define CL_QCOM_EXT_HOST_PTR_IOCOHERENT_EXTENSION_NAME \ + "cl_qcom_ext_host_ptr_iocoherent" + + +#define CL_QCOM_EXT_HOST_PTR_IOCOHERENT_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_uint host_cache_policy */ +#define CL_MEM_HOST_IOCOHERENT_QCOM 0x40A9 + +/*************************************************************** +* cl_qcom_ion_host_ptr +***************************************************************/ +#define cl_qcom_ion_host_ptr 1 +#define CL_QCOM_ION_HOST_PTR_EXTENSION_NAME \ + "cl_qcom_ion_host_ptr" + + +#define CL_QCOM_ION_HOST_PTR_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* type cl_mem_ext_host_ptr */ +typedef struct _cl_mem_ion_host_ptr { + cl_mem_ext_host_ptr ext_host_ptr; + int ion_filedesc; + void* ion_hostptr; +} cl_mem_ion_host_ptr; + +/* cl_uint allocation_type */ +#define CL_MEM_ION_HOST_PTR_QCOM 0x40A8 + +/*************************************************************** +* cl_qcom_android_native_buffer_host_ptr +***************************************************************/ +#define cl_qcom_android_native_buffer_host_ptr 1 +#define CL_QCOM_ANDROID_NATIVE_BUFFER_HOST_PTR_EXTENSION_NAME \ + "cl_qcom_android_native_buffer_host_ptr" + + +#define CL_QCOM_ANDROID_NATIVE_BUFFER_HOST_PTR_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* type cl_mem_ext_host_ptr */ +typedef struct _cl_mem_android_native_buffer_host_ptr { + cl_mem_ext_host_ptr ext_host_ptr; + void* anb_ptr; +} cl_mem_android_native_buffer_host_ptr; + +/* cl_uint allocation_type */ +#define CL_MEM_ANDROID_NATIVE_BUFFER_HOST_PTR_QCOM 0x40C6 + +/*************************************************************** +* cl_img_yuv_image +***************************************************************/ +#define cl_img_yuv_image 1 +#define CL_IMG_YUV_IMAGE_EXTENSION_NAME \ + "cl_img_yuv_image" + + +#define CL_IMG_YUV_IMAGE_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_channel_order */ +#define CL_NV21_IMG 0x40D0 +#define CL_YV12_IMG 0x40D1 + +/*************************************************************** +* cl_img_cached_allocations +***************************************************************/ +#define cl_img_cached_allocations 1 +#define CL_IMG_CACHED_ALLOCATIONS_EXTENSION_NAME \ + "cl_img_cached_allocations" + + +#define CL_IMG_CACHED_ALLOCATIONS_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_mem_flags */ +#define CL_MEM_USE_UNCACHED_CPU_MEMORY_IMG (1 << 26) +#define CL_MEM_USE_CACHED_CPU_MEMORY_IMG (1 << 27) + +/*************************************************************** +* cl_img_use_gralloc_ptr +***************************************************************/ +#define cl_img_use_gralloc_ptr 1 +#define CL_IMG_USE_GRALLOC_PTR_EXTENSION_NAME \ + "cl_img_use_gralloc_ptr" + + +#define CL_IMG_USE_GRALLOC_PTR_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* Error codes */ +#define CL_GRALLOC_RESOURCE_NOT_ACQUIRED_IMG 0x40D4 +#define CL_INVALID_GRALLOC_OBJECT_IMG 0x40D5 + +/* cl_mem_flags */ +#define CL_MEM_USE_GRALLOC_PTR_IMG (1 << 28) + +/* cl_command_type */ +#define CL_COMMAND_ACQUIRE_GRALLOC_OBJECTS_IMG 0x40D2 +#define CL_COMMAND_RELEASE_GRALLOC_OBJECTS_IMG 0x40D3 + + +typedef cl_int CL_API_CALL +clEnqueueAcquireGrallocObjectsIMG_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueAcquireGrallocObjectsIMG_t * +clEnqueueAcquireGrallocObjectsIMG_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueReleaseGrallocObjectsIMG_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReleaseGrallocObjectsIMG_t * +clEnqueueReleaseGrallocObjectsIMG_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireGrallocObjectsIMG( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseGrallocObjectsIMG( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_img_generate_mipmap +***************************************************************/ +#define cl_img_generate_mipmap 1 +#define CL_IMG_GENERATE_MIPMAP_EXTENSION_NAME \ + "cl_img_generate_mipmap" + + +#define CL_IMG_GENERATE_MIPMAP_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef cl_uint cl_mipmap_filter_mode_img; + +/* cl_mipmap_filter_mode_img */ +#define CL_MIPMAP_FILTER_ANY_IMG 0x0 +#define CL_MIPMAP_FILTER_BOX_IMG 0x1 + +/* cl_command_type */ +#define CL_COMMAND_GENERATE_MIPMAP_IMG 0x40D6 + + +typedef cl_int CL_API_CALL +clEnqueueGenerateMipmapIMG_t( + cl_command_queue command_queue, + cl_mem src_image, + cl_mem dst_image, + cl_mipmap_filter_mode_img mipmap_filter_mode, + const size_t* array_region, + const size_t* mip_region, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueGenerateMipmapIMG_t * +clEnqueueGenerateMipmapIMG_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueGenerateMipmapIMG( + cl_command_queue command_queue, + cl_mem src_image, + cl_mem dst_image, + cl_mipmap_filter_mode_img mipmap_filter_mode, + const size_t* array_region, + const size_t* mip_region, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_img_mem_properties +***************************************************************/ +#define cl_img_mem_properties 1 +#define CL_IMG_MEM_PROPERTIES_EXTENSION_NAME \ + "cl_img_mem_properties" + + +#define CL_IMG_MEM_PROPERTIES_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_mem_properties */ +#define CL_MEM_ALLOC_FLAGS_IMG 0x40D7 + +/* cl_mem_alloc_flags_img */ +#define CL_MEM_ALLOC_RELAX_REQUIREMENTS_IMG (1 << 0) +#define CL_MEM_ALLOC_GPU_WRITE_COMBINE_IMG (1 << 1) +#define CL_MEM_ALLOC_GPU_CACHED_IMG (1 << 2) +#define CL_MEM_ALLOC_CPU_LOCAL_IMG (1 << 3) +#define CL_MEM_ALLOC_GPU_LOCAL_IMG (1 << 4) +#define CL_MEM_ALLOC_GPU_PRIVATE_IMG (1 << 5) + +/* cl_device_info */ +#define CL_DEVICE_MEMORY_CAPABILITIES_IMG 0x40D8 + +/*************************************************************** +* cl_khr_subgroups +***************************************************************/ +#define cl_khr_subgroups 1 +#define CL_KHR_SUBGROUPS_EXTENSION_NAME \ + "cl_khr_subgroups" + + +#define CL_KHR_SUBGROUPS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +#if !defined(CL_VERSION_2_1) +/* defined in CL.h for OpenCL 2.1 and newer */ +typedef cl_uint cl_kernel_sub_group_info; + +#endif /* !defined(CL_VERSION_2_1) */ + +/* cl_kernel_sub_group_info */ +#define CL_KERNEL_MAX_SUB_GROUP_SIZE_FOR_NDRANGE_KHR 0x2033 +#define CL_KERNEL_SUB_GROUP_COUNT_FOR_NDRANGE_KHR 0x2034 + + +typedef cl_int CL_API_CALL +clGetKernelSubGroupInfoKHR_t( + cl_kernel in_kernel, + cl_device_id in_device, + cl_kernel_sub_group_info param_name, + size_t input_value_size, + const void* input_value, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetKernelSubGroupInfoKHR_t * +clGetKernelSubGroupInfoKHR_fn CL_API_SUFFIX__VERSION_2_0_DEPRECATED; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelSubGroupInfoKHR( + cl_kernel in_kernel, + cl_device_id in_device, + cl_kernel_sub_group_info param_name, + size_t input_value_size, + const void* input_value, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) CL_API_SUFFIX__VERSION_2_0_DEPRECATED; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_mipmap_image +***************************************************************/ +#define cl_khr_mipmap_image 1 +#define CL_KHR_MIPMAP_IMAGE_EXTENSION_NAME \ + "cl_khr_mipmap_image" + + +#define CL_KHR_MIPMAP_IMAGE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_sampler_properties */ +#define CL_SAMPLER_MIP_FILTER_MODE_KHR 0x1155 +#define CL_SAMPLER_LOD_MIN_KHR 0x1156 +#define CL_SAMPLER_LOD_MAX_KHR 0x1157 + +/*************************************************************** +* cl_khr_priority_hints +***************************************************************/ +#define cl_khr_priority_hints 1 +#define CL_KHR_PRIORITY_HINTS_EXTENSION_NAME \ + "cl_khr_priority_hints" + + +#define CL_KHR_PRIORITY_HINTS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* To be used by clGetEventInfo */ +typedef cl_uint cl_queue_priority_khr; + +/* cl_queue_properties */ +#define CL_QUEUE_PRIORITY_KHR 0x1096 + +/* cl_queue_priority_khr */ +#define CL_QUEUE_PRIORITY_HIGH_KHR (1 << 0) +#define CL_QUEUE_PRIORITY_MED_KHR (1 << 1) +#define CL_QUEUE_PRIORITY_LOW_KHR (1 << 2) + +/*************************************************************** +* cl_khr_throttle_hints +***************************************************************/ +#define cl_khr_throttle_hints 1 +#define CL_KHR_THROTTLE_HINTS_EXTENSION_NAME \ + "cl_khr_throttle_hints" + + +#define CL_KHR_THROTTLE_HINTS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* To be used by clGetEventInfo */ +typedef cl_uint cl_queue_throttle_khr; + +/* cl_queue_properties */ +#define CL_QUEUE_THROTTLE_KHR 0x1097 + +/* cl_queue_throttle_khr */ +#define CL_QUEUE_THROTTLE_HIGH_KHR (1 << 0) +#define CL_QUEUE_THROTTLE_MED_KHR (1 << 1) +#define CL_QUEUE_THROTTLE_LOW_KHR (1 << 2) + +/*************************************************************** +* cl_khr_subgroup_named_barrier +***************************************************************/ +#define cl_khr_subgroup_named_barrier 1 +#define CL_KHR_SUBGROUP_NAMED_BARRIER_EXTENSION_NAME \ + "cl_khr_subgroup_named_barrier" + + +#define CL_KHR_SUBGROUP_NAMED_BARRIER_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_MAX_NAMED_BARRIER_COUNT_KHR 0x2035 + +/*************************************************************** +* cl_khr_extended_versioning +***************************************************************/ +#define cl_khr_extended_versioning 1 +#define CL_KHR_EXTENDED_VERSIONING_EXTENSION_NAME \ + "cl_khr_extended_versioning" + + +#define CL_KHR_EXTENDED_VERSIONING_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +#define CL_VERSION_MAJOR_BITS_KHR 10 +#define CL_VERSION_MINOR_BITS_KHR 10 +#define CL_VERSION_PATCH_BITS_KHR 12 + +#define CL_VERSION_MAJOR_MASK_KHR ((1 << CL_VERSION_MAJOR_BITS_KHR) - 1) +#define CL_VERSION_MINOR_MASK_KHR ((1 << CL_VERSION_MINOR_BITS_KHR) - 1) +#define CL_VERSION_PATCH_MASK_KHR ((1 << CL_VERSION_PATCH_BITS_KHR) - 1) + +#define CL_VERSION_MAJOR_KHR(version) ((version) >> (CL_VERSION_MINOR_BITS_KHR + CL_VERSION_PATCH_BITS_KHR)) +#define CL_VERSION_MINOR_KHR(version) (((version) >> CL_VERSION_PATCH_BITS_KHR) & CL_VERSION_MINOR_MASK_KHR) +#define CL_VERSION_PATCH_KHR(version) ((version) & CL_VERSION_PATCH_MASK_KHR) + +#define CL_MAKE_VERSION_KHR(major, minor, patch) \ + ((((major) & CL_VERSION_MAJOR_MASK_KHR) << (CL_VERSION_MINOR_BITS_KHR + CL_VERSION_PATCH_BITS_KHR)) | \ + (((minor) & CL_VERSION_MINOR_MASK_KHR) << CL_VERSION_PATCH_BITS_KHR) | \ + ((patch) & CL_VERSION_PATCH_MASK_KHR)) + +#define CL_NAME_VERSION_MAX_NAME_SIZE_KHR 64 + +typedef cl_uint cl_version_khr; +typedef struct _cl_name_version_khr { + cl_version_khr version; + char name[CL_NAME_VERSION_MAX_NAME_SIZE_KHR]; +} cl_name_version_khr; + +/* cl_platform_info */ +#define CL_PLATFORM_NUMERIC_VERSION_KHR 0x0906 +#define CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR 0x0907 + +/* cl_device_info */ +#define CL_DEVICE_NUMERIC_VERSION_KHR 0x105E +#define CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR 0x105F +#define CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR 0x1060 +#define CL_DEVICE_ILS_WITH_VERSION_KHR 0x1061 +#define CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR 0x1062 + +/*************************************************************** +* cl_khr_device_uuid +***************************************************************/ +#define cl_khr_device_uuid 1 +#define CL_KHR_DEVICE_UUID_EXTENSION_NAME \ + "cl_khr_device_uuid" + + +#define CL_KHR_DEVICE_UUID_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* Size Constants */ +#define CL_UUID_SIZE_KHR 16 +#define CL_LUID_SIZE_KHR 8 + +/* cl_device_info */ +#define CL_DEVICE_UUID_KHR 0x106A +#define CL_DRIVER_UUID_KHR 0x106B +#define CL_DEVICE_LUID_VALID_KHR 0x106C +#define CL_DEVICE_LUID_KHR 0x106D +#define CL_DEVICE_NODE_MASK_KHR 0x106E + +/*************************************************************** +* cl_khr_pci_bus_info +***************************************************************/ +#define cl_khr_pci_bus_info 1 +#define CL_KHR_PCI_BUS_INFO_EXTENSION_NAME \ + "cl_khr_pci_bus_info" + + +#define CL_KHR_PCI_BUS_INFO_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef struct _cl_device_pci_bus_info_khr { + cl_uint pci_domain; + cl_uint pci_bus; + cl_uint pci_device; + cl_uint pci_function; +} cl_device_pci_bus_info_khr; + +/* cl_device_info */ +#define CL_DEVICE_PCI_BUS_INFO_KHR 0x410F + +/*************************************************************** +* cl_khr_suggested_local_work_size +***************************************************************/ +#define cl_khr_suggested_local_work_size 1 +#define CL_KHR_SUGGESTED_LOCAL_WORK_SIZE_EXTENSION_NAME \ + "cl_khr_suggested_local_work_size" + + +#define CL_KHR_SUGGESTED_LOCAL_WORK_SIZE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + + +typedef cl_int CL_API_CALL +clGetKernelSuggestedLocalWorkSizeKHR_t( + cl_command_queue command_queue, + cl_kernel kernel, + cl_uint work_dim, + const size_t* global_work_offset, + const size_t* global_work_size, + size_t* suggested_local_work_size); + +typedef clGetKernelSuggestedLocalWorkSizeKHR_t * +clGetKernelSuggestedLocalWorkSizeKHR_fn CL_API_SUFFIX__VERSION_3_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetKernelSuggestedLocalWorkSizeKHR( + cl_command_queue command_queue, + cl_kernel kernel, + cl_uint work_dim, + const size_t* global_work_offset, + const size_t* global_work_size, + size_t* suggested_local_work_size) CL_API_SUFFIX__VERSION_3_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_integer_dot_product +***************************************************************/ +#define cl_khr_integer_dot_product 1 +#define CL_KHR_INTEGER_DOT_PRODUCT_EXTENSION_NAME \ + "cl_khr_integer_dot_product" + + +#define CL_KHR_INTEGER_DOT_PRODUCT_EXTENSION_VERSION CL_MAKE_VERSION(2, 0, 0) + +typedef cl_bitfield cl_device_integer_dot_product_capabilities_khr; +typedef struct _cl_device_integer_dot_product_acceleration_properties_khr { + cl_bool signed_accelerated; + cl_bool unsigned_accelerated; + cl_bool mixed_signedness_accelerated; + cl_bool accumulating_saturating_signed_accelerated; + cl_bool accumulating_saturating_unsigned_accelerated; + cl_bool accumulating_saturating_mixed_signedness_accelerated; +} cl_device_integer_dot_product_acceleration_properties_khr; + +/* cl_device_integer_dot_product_capabilities_khr */ +#define CL_DEVICE_INTEGER_DOT_PRODUCT_INPUT_4x8BIT_PACKED_KHR (1 << 0) +#define CL_DEVICE_INTEGER_DOT_PRODUCT_INPUT_4x8BIT_KHR (1 << 1) + +/* cl_device_info */ +#define CL_DEVICE_INTEGER_DOT_PRODUCT_CAPABILITIES_KHR 0x1073 +#define CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_8BIT_KHR 0x1074 +#define CL_DEVICE_INTEGER_DOT_PRODUCT_ACCELERATION_PROPERTIES_4x8BIT_PACKED_KHR 0x1075 + +/*************************************************************** +* cl_khr_external_memory +***************************************************************/ +#define cl_khr_external_memory 1 +#define CL_KHR_EXTERNAL_MEMORY_EXTENSION_NAME \ + "cl_khr_external_memory" + + +#define CL_KHR_EXTERNAL_MEMORY_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 1) + +typedef cl_uint cl_external_memory_handle_type_khr; + +/* cl_platform_info */ +#define CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR 0x2044 + +/* cl_device_info */ +#define CL_DEVICE_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR 0x204F +#define CL_DEVICE_EXTERNAL_MEMORY_IMPORT_ASSUME_LINEAR_IMAGES_HANDLE_TYPES_KHR 0x2052 + +/* cl_mem_properties */ +#define CL_MEM_DEVICE_HANDLE_LIST_KHR 0x2051 +#define CL_MEM_DEVICE_HANDLE_LIST_END_KHR 0 + +/* cl_command_type */ +#define CL_COMMAND_ACQUIRE_EXTERNAL_MEM_OBJECTS_KHR 0x2047 +#define CL_COMMAND_RELEASE_EXTERNAL_MEM_OBJECTS_KHR 0x2048 + + +typedef cl_int CL_API_CALL +clEnqueueAcquireExternalMemObjectsKHR_t( + cl_command_queue command_queue, + cl_uint num_mem_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueAcquireExternalMemObjectsKHR_t * +clEnqueueAcquireExternalMemObjectsKHR_fn CL_API_SUFFIX__VERSION_3_0; + +typedef cl_int CL_API_CALL +clEnqueueReleaseExternalMemObjectsKHR_t( + cl_command_queue command_queue, + cl_uint num_mem_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReleaseExternalMemObjectsKHR_t * +clEnqueueReleaseExternalMemObjectsKHR_fn CL_API_SUFFIX__VERSION_3_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireExternalMemObjectsKHR( + cl_command_queue command_queue, + cl_uint num_mem_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_3_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseExternalMemObjectsKHR( + cl_command_queue command_queue, + cl_uint num_mem_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_3_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_external_memory_dma_buf +***************************************************************/ +#define cl_khr_external_memory_dma_buf 1 +#define CL_KHR_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME \ + "cl_khr_external_memory_dma_buf" + + +#define CL_KHR_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_external_memory_handle_type_khr */ +#define CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR 0x2067 + +/*************************************************************** +* cl_khr_external_memory_opaque_fd +***************************************************************/ +#define cl_khr_external_memory_opaque_fd 1 +#define CL_KHR_EXTERNAL_MEMORY_OPAQUE_FD_EXTENSION_NAME \ + "cl_khr_external_memory_opaque_fd" + + +#define CL_KHR_EXTERNAL_MEMORY_OPAQUE_FD_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_external_memory_handle_type_khr */ +#define CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_FD_KHR 0x2060 + +/*************************************************************** +* cl_khr_external_memory_win32 +***************************************************************/ +#define cl_khr_external_memory_win32 1 +#define CL_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME \ + "cl_khr_external_memory_win32" + + +#define CL_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_VERSION CL_MAKE_VERSION(1, 1, 0) + +/* cl_external_memory_handle_type_khr */ +#define CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR 0x2061 +#define CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KMT_KHR 0x2062 +#define CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_NAME_KHR 0x2069 + +/*************************************************************** +* cl_khr_external_semaphore +***************************************************************/ +#define cl_khr_external_semaphore 1 +#define CL_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME \ + "cl_khr_external_semaphore" + + +#define CL_KHR_EXTERNAL_SEMAPHORE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 1) + +typedef struct _cl_semaphore_khr * cl_semaphore_khr; +typedef cl_uint cl_external_semaphore_handle_type_khr; + +/* cl_platform_info */ +#define CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR 0x2037 +#define CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR 0x2038 + +/* cl_device_info */ +#define CL_DEVICE_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR 0x204D +#define CL_DEVICE_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR 0x204E + +/* cl_semaphore_properties_khr */ +#define CL_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR 0x203F +#define CL_SEMAPHORE_EXPORT_HANDLE_TYPES_LIST_END_KHR 0 + +/* cl_semaphore_info_khr */ +#define CL_SEMAPHORE_EXPORTABLE_KHR 0x2054 + + +typedef cl_int CL_API_CALL +clGetSemaphoreHandleForTypeKHR_t( + cl_semaphore_khr sema_object, + cl_device_id device, + cl_external_semaphore_handle_type_khr handle_type, + size_t handle_size, + void* handle_ptr, + size_t* handle_size_ret); + +typedef clGetSemaphoreHandleForTypeKHR_t * +clGetSemaphoreHandleForTypeKHR_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSemaphoreHandleForTypeKHR( + cl_semaphore_khr sema_object, + cl_device_id device, + cl_external_semaphore_handle_type_khr handle_type, + size_t handle_size, + void* handle_ptr, + size_t* handle_size_ret) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_external_semaphore_dx_fence (beta) +***************************************************************/ +#if defined(CL_ENABLE_BETA_EXTENSIONS) + +#define cl_khr_external_semaphore_dx_fence 1 +#define CL_KHR_EXTERNAL_SEMAPHORE_DX_FENCE_EXTENSION_NAME \ + "cl_khr_external_semaphore_dx_fence" + + +#define CL_KHR_EXTERNAL_SEMAPHORE_DX_FENCE_EXTENSION_VERSION CL_MAKE_VERSION(0, 9, 0) + +/* cl_external_semaphore_handle_type_khr */ +#define CL_SEMAPHORE_HANDLE_D3D12_FENCE_KHR 0x2059 + +#endif /* defined(CL_ENABLE_BETA_EXTENSIONS) */ + +/*************************************************************** +* cl_khr_external_semaphore_opaque_fd +***************************************************************/ +#define cl_khr_external_semaphore_opaque_fd 1 +#define CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXTENSION_NAME \ + "cl_khr_external_semaphore_opaque_fd" + + +#define CL_KHR_EXTERNAL_SEMAPHORE_OPAQUE_FD_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_external_semaphore_handle_type_khr */ +#define CL_SEMAPHORE_HANDLE_OPAQUE_FD_KHR 0x2055 + +/*************************************************************** +* cl_khr_external_semaphore_sync_fd +***************************************************************/ +#define cl_khr_external_semaphore_sync_fd 1 +#define CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXTENSION_NAME \ + "cl_khr_external_semaphore_sync_fd" + + +#define CL_KHR_EXTERNAL_SEMAPHORE_SYNC_FD_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_properties cl_semaphore_reimport_properties_khr; + +/* cl_external_semaphore_handle_type_khr */ +#define CL_SEMAPHORE_HANDLE_SYNC_FD_KHR 0x2058 + + +typedef cl_int CL_API_CALL +clReImportSemaphoreSyncFdKHR_t( + cl_semaphore_khr sema_object, + cl_semaphore_reimport_properties_khr* reimport_props, + int fd); + +typedef clReImportSemaphoreSyncFdKHR_t * +clReImportSemaphoreSyncFdKHR_fn CL_API_SUFFIX__VERSION_3_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clReImportSemaphoreSyncFdKHR( + cl_semaphore_khr sema_object, + cl_semaphore_reimport_properties_khr* reimport_props, + int fd) CL_API_SUFFIX__VERSION_3_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_external_semaphore_win32 (beta) +***************************************************************/ +#if defined(CL_ENABLE_BETA_EXTENSIONS) + +#define cl_khr_external_semaphore_win32 1 +#define CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME \ + "cl_khr_external_semaphore_win32" + + +#define CL_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_VERSION CL_MAKE_VERSION(0, 9, 1) + +/* cl_external_semaphore_handle_type_khr */ +#define CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KHR 0x2056 +#define CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_KMT_KHR 0x2057 +#define CL_SEMAPHORE_HANDLE_OPAQUE_WIN32_NAME_KHR 0x2068 + +#endif /* defined(CL_ENABLE_BETA_EXTENSIONS) */ + +/*************************************************************** +* cl_khr_semaphore +***************************************************************/ +#define cl_khr_semaphore 1 +#define CL_KHR_SEMAPHORE_EXTENSION_NAME \ + "cl_khr_semaphore" + + +#define CL_KHR_SEMAPHORE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* type cl_semaphore_khr */ +typedef cl_properties cl_semaphore_properties_khr; +typedef cl_uint cl_semaphore_info_khr; +typedef cl_uint cl_semaphore_type_khr; +typedef cl_ulong cl_semaphore_payload_khr; + +/* cl_semaphore_type */ +#define CL_SEMAPHORE_TYPE_BINARY_KHR 1 + +/* cl_platform_info */ +#define CL_PLATFORM_SEMAPHORE_TYPES_KHR 0x2036 + +/* cl_device_info */ +#define CL_DEVICE_SEMAPHORE_TYPES_KHR 0x204C + +/* cl_semaphore_info_khr */ +#define CL_SEMAPHORE_CONTEXT_KHR 0x2039 +#define CL_SEMAPHORE_REFERENCE_COUNT_KHR 0x203A +#define CL_SEMAPHORE_PROPERTIES_KHR 0x203B +#define CL_SEMAPHORE_PAYLOAD_KHR 0x203C + +/* cl_semaphore_info_khr or cl_semaphore_properties_khr */ +#define CL_SEMAPHORE_TYPE_KHR 0x203D +#define CL_SEMAPHORE_DEVICE_HANDLE_LIST_KHR 0x2053 +#define CL_SEMAPHORE_DEVICE_HANDLE_LIST_END_KHR 0 + +/* cl_command_type */ +#define CL_COMMAND_SEMAPHORE_WAIT_KHR 0x2042 +#define CL_COMMAND_SEMAPHORE_SIGNAL_KHR 0x2043 + +/* Error codes */ +#define CL_INVALID_SEMAPHORE_KHR -1142 + + +typedef cl_semaphore_khr CL_API_CALL +clCreateSemaphoreWithPropertiesKHR_t( + cl_context context, + const cl_semaphore_properties_khr* sema_props, + cl_int* errcode_ret); + +typedef clCreateSemaphoreWithPropertiesKHR_t * +clCreateSemaphoreWithPropertiesKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueWaitSemaphoresKHR_t( + cl_command_queue command_queue, + cl_uint num_sema_objects, + const cl_semaphore_khr* sema_objects, + const cl_semaphore_payload_khr* sema_payload_list, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueWaitSemaphoresKHR_t * +clEnqueueWaitSemaphoresKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueSignalSemaphoresKHR_t( + cl_command_queue command_queue, + cl_uint num_sema_objects, + const cl_semaphore_khr* sema_objects, + const cl_semaphore_payload_khr* sema_payload_list, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSignalSemaphoresKHR_t * +clEnqueueSignalSemaphoresKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clGetSemaphoreInfoKHR_t( + cl_semaphore_khr sema_object, + cl_semaphore_info_khr param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetSemaphoreInfoKHR_t * +clGetSemaphoreInfoKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clReleaseSemaphoreKHR_t( + cl_semaphore_khr sema_object); + +typedef clReleaseSemaphoreKHR_t * +clReleaseSemaphoreKHR_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clRetainSemaphoreKHR_t( + cl_semaphore_khr sema_object); + +typedef clRetainSemaphoreKHR_t * +clRetainSemaphoreKHR_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_semaphore_khr CL_API_CALL +clCreateSemaphoreWithPropertiesKHR( + cl_context context, + const cl_semaphore_properties_khr* sema_props, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueWaitSemaphoresKHR( + cl_command_queue command_queue, + cl_uint num_sema_objects, + const cl_semaphore_khr* sema_objects, + const cl_semaphore_payload_khr* sema_payload_list, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSignalSemaphoresKHR( + cl_command_queue command_queue, + cl_uint num_sema_objects, + const cl_semaphore_khr* sema_objects, + const cl_semaphore_payload_khr* sema_payload_list, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSemaphoreInfoKHR( + cl_semaphore_khr sema_object, + cl_semaphore_info_khr param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseSemaphoreKHR( + cl_semaphore_khr sema_object) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainSemaphoreKHR( + cl_semaphore_khr sema_object) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_arm_import_memory +***************************************************************/ +#define cl_arm_import_memory 1 +#define CL_ARM_IMPORT_MEMORY_EXTENSION_NAME \ + "cl_arm_import_memory" + + +#define CL_ARM_IMPORT_MEMORY_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef intptr_t cl_import_properties_arm; + +/* cl_import_properties_arm */ +#define CL_IMPORT_TYPE_ARM 0x40B2 +#define CL_IMPORT_TYPE_HOST_ARM 0x40B3 +#define CL_IMPORT_TYPE_DMA_BUF_ARM 0x40B4 +#define CL_IMPORT_TYPE_PROTECTED_ARM 0x40B5 +#define CL_IMPORT_TYPE_ANDROID_HARDWARE_BUFFER_ARM 0x41E2 +#define CL_IMPORT_DMA_BUF_DATA_CONSISTENCY_WITH_HOST_ARM 0x41E3 +#define CL_IMPORT_MEMORY_WHOLE_ALLOCATION_ARM SIZE_MAX +#define CL_IMPORT_ANDROID_HARDWARE_BUFFER_PLANE_INDEX_ARM 0x41EF +#define CL_IMPORT_ANDROID_HARDWARE_BUFFER_LAYER_INDEX_ARM 0x41F0 + + +typedef cl_mem CL_API_CALL +clImportMemoryARM_t( + cl_context context, + cl_mem_flags flags, + const cl_import_properties_arm* properties, + void* memory, + size_t size, + cl_int* errcode_ret); + +typedef clImportMemoryARM_t * +clImportMemoryARM_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_mem CL_API_CALL +clImportMemoryARM( + cl_context context, + cl_mem_flags flags, + const cl_import_properties_arm* properties, + void* memory, + size_t size, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_arm_shared_virtual_memory +***************************************************************/ +#define cl_arm_shared_virtual_memory 1 +#define CL_ARM_SHARED_VIRTUAL_MEMORY_EXTENSION_NAME \ + "cl_arm_shared_virtual_memory" + + +#define CL_ARM_SHARED_VIRTUAL_MEMORY_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef cl_bitfield cl_svm_mem_flags_arm; +typedef cl_uint cl_kernel_exec_info_arm; +typedef cl_bitfield cl_device_svm_capabilities_arm; + +/* cl_device_info */ +#define CL_DEVICE_SVM_CAPABILITIES_ARM 0x40B6 + +/* cl_mem_info */ +#define CL_MEM_USES_SVM_POINTER_ARM 0x40B7 + +/* cl_kernel_exec_info_arm */ +#define CL_KERNEL_EXEC_INFO_SVM_PTRS_ARM 0x40B8 +#define CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM_ARM 0x40B9 + +/* cl_command_type */ +#define CL_COMMAND_SVM_FREE_ARM 0x40BA +#define CL_COMMAND_SVM_MEMCPY_ARM 0x40BB +#define CL_COMMAND_SVM_MEMFILL_ARM 0x40BC +#define CL_COMMAND_SVM_MAP_ARM 0x40BD +#define CL_COMMAND_SVM_UNMAP_ARM 0x40BE + +/* cl_device_svm_capabilities_arm */ +#define CL_DEVICE_SVM_COARSE_GRAIN_BUFFER_ARM (1 << 0) +#define CL_DEVICE_SVM_FINE_GRAIN_BUFFER_ARM (1 << 1) +#define CL_DEVICE_SVM_FINE_GRAIN_SYSTEM_ARM (1 << 2) +#define CL_DEVICE_SVM_ATOMICS_ARM (1 << 3) + +/* cl_svm_mem_flags_arm */ +#define CL_MEM_SVM_FINE_GRAIN_BUFFER_ARM (1 << 10) +#define CL_MEM_SVM_ATOMICS_ARM (1 << 11) + + +typedef void* CL_API_CALL +clSVMAllocARM_t( + cl_context context, + cl_svm_mem_flags_arm flags, + size_t size, + cl_uint alignment); + +typedef clSVMAllocARM_t * +clSVMAllocARM_fn CL_API_SUFFIX__VERSION_1_2; + +typedef void CL_API_CALL +clSVMFreeARM_t( + cl_context context, + void* svm_pointer); + +typedef clSVMFreeARM_t * +clSVMFreeARM_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueSVMFreeARM_t( + cl_command_queue command_queue, + cl_uint num_svm_pointers, + void* svm_pointers[], + void (CL_CALLBACK* pfn_free_func)(cl_command_queue queue, cl_uint num_svm_pointers, void * svm_pointers[], void *user_data), + void* user_data, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMFreeARM_t * +clEnqueueSVMFreeARM_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueSVMMemcpyARM_t( + cl_command_queue command_queue, + cl_bool blocking_copy, + void* dst_ptr, + const void* src_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMMemcpyARM_t * +clEnqueueSVMMemcpyARM_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueSVMMemFillARM_t( + cl_command_queue command_queue, + void* svm_ptr, + const void* pattern, + size_t pattern_size, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMMemFillARM_t * +clEnqueueSVMMemFillARM_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueSVMMapARM_t( + cl_command_queue command_queue, + cl_bool blocking_map, + cl_map_flags flags, + void* svm_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMMapARM_t * +clEnqueueSVMMapARM_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueSVMUnmapARM_t( + cl_command_queue command_queue, + void* svm_ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMUnmapARM_t * +clEnqueueSVMUnmapARM_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clSetKernelArgSVMPointerARM_t( + cl_kernel kernel, + cl_uint arg_index, + const void* arg_value); + +typedef clSetKernelArgSVMPointerARM_t * +clSetKernelArgSVMPointerARM_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clSetKernelExecInfoARM_t( + cl_kernel kernel, + cl_kernel_exec_info_arm param_name, + size_t param_value_size, + const void* param_value); + +typedef clSetKernelExecInfoARM_t * +clSetKernelExecInfoARM_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY void* CL_API_CALL +clSVMAllocARM( + cl_context context, + cl_svm_mem_flags_arm flags, + size_t size, + cl_uint alignment) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY void CL_API_CALL +clSVMFreeARM( + cl_context context, + void* svm_pointer) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMFreeARM( + cl_command_queue command_queue, + cl_uint num_svm_pointers, + void* svm_pointers[], + void (CL_CALLBACK* pfn_free_func)(cl_command_queue queue, cl_uint num_svm_pointers, void * svm_pointers[], void *user_data), + void* user_data, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMMemcpyARM( + cl_command_queue command_queue, + cl_bool blocking_copy, + void* dst_ptr, + const void* src_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMMemFillARM( + cl_command_queue command_queue, + void* svm_ptr, + const void* pattern, + size_t pattern_size, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMMapARM( + cl_command_queue command_queue, + cl_bool blocking_map, + cl_map_flags flags, + void* svm_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueSVMUnmapARM( + cl_command_queue command_queue, + void* svm_ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetKernelArgSVMPointerARM( + cl_kernel kernel, + cl_uint arg_index, + const void* arg_value) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetKernelExecInfoARM( + cl_kernel kernel, + cl_kernel_exec_info_arm param_name, + size_t param_value_size, + const void* param_value) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_arm_get_core_id +***************************************************************/ +#if defined(CL_VERSION_1_2) + +#define cl_arm_get_core_id 1 +#define CL_ARM_GET_CORE_ID_EXTENSION_NAME \ + "cl_arm_get_core_id" + + +#define CL_ARM_GET_CORE_ID_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_COMPUTE_UNITS_BITFIELD_ARM 0x40BF + +#endif /* defined(CL_VERSION_1_2) */ + +/*************************************************************** +* cl_arm_job_slot_selection +***************************************************************/ +#define cl_arm_job_slot_selection 1 +#define CL_ARM_JOB_SLOT_SELECTION_EXTENSION_NAME \ + "cl_arm_job_slot_selection" + + +#define CL_ARM_JOB_SLOT_SELECTION_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_JOB_SLOTS_ARM 0x41E0 + +/* cl_queue_properties */ +#define CL_QUEUE_JOB_SLOT_ARM 0x41E1 + +/*************************************************************** +* cl_arm_scheduling_controls +***************************************************************/ +#define cl_arm_scheduling_controls 1 +#define CL_ARM_SCHEDULING_CONTROLS_EXTENSION_NAME \ + "cl_arm_scheduling_controls" + + +#define CL_ARM_SCHEDULING_CONTROLS_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* Types */ +typedef cl_bitfield cl_device_scheduling_controls_capabilities_arm; + +/* cl_device_scheduling_controls_capabilities_arm */ +#define CL_DEVICE_SCHEDULING_KERNEL_BATCHING_ARM (1 << 0) +#define CL_DEVICE_SCHEDULING_WORKGROUP_BATCH_SIZE_ARM (1 << 1) +#define CL_DEVICE_SCHEDULING_WORKGROUP_BATCH_SIZE_MODIFIER_ARM (1 << 2) +#define CL_DEVICE_SCHEDULING_DEFERRED_FLUSH_ARM (1 << 3) +#define CL_DEVICE_SCHEDULING_REGISTER_ALLOCATION_ARM (1 << 4) +#define CL_DEVICE_SCHEDULING_WARP_THROTTLING_ARM (1 << 5) +#define CL_DEVICE_SCHEDULING_COMPUTE_UNIT_BATCH_QUEUE_SIZE_ARM (1 << 6) +#define CL_DEVICE_SCHEDULING_COMPUTE_UNIT_LIMIT_ARM (1 << 7) + +/* cl_device_info */ +#define CL_DEVICE_SCHEDULING_CONTROLS_CAPABILITIES_ARM 0x41E4 +#define CL_DEVICE_SUPPORTED_REGISTER_ALLOCATIONS_ARM 0x41EB +#define CL_DEVICE_MAX_WARP_COUNT_ARM 0x41EA + +/* cl_kernel_exec_info */ +#define CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_ARM 0x41E5 +#define CL_KERNEL_EXEC_INFO_WORKGROUP_BATCH_SIZE_MODIFIER_ARM 0x41E6 +#define CL_KERNEL_EXEC_INFO_WARP_COUNT_LIMIT_ARM 0x41E8 +#define CL_KERNEL_EXEC_INFO_COMPUTE_UNIT_MAX_QUEUED_BATCHES_ARM 0x41F1 + +/* cl_kernel_info */ +#define CL_KERNEL_MAX_WARP_COUNT_ARM 0x41E9 + +/* cl_queue_properties */ +#define CL_QUEUE_KERNEL_BATCHING_ARM 0x41E7 +#define CL_QUEUE_DEFERRED_FLUSH_ARM 0x41EC +#define CL_QUEUE_COMPUTE_UNIT_LIMIT_ARM 0x41F3 + +/*************************************************************** +* cl_arm_controlled_kernel_termination +***************************************************************/ +#define cl_arm_controlled_kernel_termination 1 +#define CL_ARM_CONTROLLED_KERNEL_TERMINATION_EXTENSION_NAME \ + "cl_arm_controlled_kernel_termination" + + +#define CL_ARM_CONTROLLED_KERNEL_TERMINATION_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* Types */ +typedef cl_bitfield cl_device_controlled_termination_capabilities_arm; + +/* Error codes */ +#define CL_COMMAND_TERMINATED_ITSELF_WITH_FAILURE_ARM -1108 + +/* cl_device_controlled_termination_capabilities_arm */ +#define CL_DEVICE_CONTROLLED_TERMINATION_SUCCESS_ARM (1 << 0) +#define CL_DEVICE_CONTROLLED_TERMINATION_FAILURE_ARM (1 << 1) +#define CL_DEVICE_CONTROLLED_TERMINATION_QUERY_ARM (1 << 2) + +/* cl_device_info */ +#define CL_DEVICE_CONTROLLED_TERMINATION_CAPABILITIES_ARM 0x41EE + +/* cl_event_info */ +#define CL_EVENT_COMMAND_TERMINATION_REASON_ARM 0x41ED + +/* cl_command_termination_reason_arm */ +#define CL_COMMAND_TERMINATION_COMPLETION_ARM 0 +#define CL_COMMAND_TERMINATION_CONTROLLED_SUCCESS_ARM 1 +#define CL_COMMAND_TERMINATION_CONTROLLED_FAILURE_ARM 2 +#define CL_COMMAND_TERMINATION_ERROR_ARM 3 + +/*************************************************************** +* cl_arm_protected_memory_allocation +***************************************************************/ +#define cl_arm_protected_memory_allocation 1 +#define CL_ARM_PROTECTED_MEMORY_ALLOCATION_EXTENSION_NAME \ + "cl_arm_protected_memory_allocation" + + +#define CL_ARM_PROTECTED_MEMORY_ALLOCATION_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +#define CL_MEM_PROTECTED_ALLOC_ARM ((cl_bitfield)1 << 36) + +/*************************************************************** +* cl_intel_exec_by_local_thread +***************************************************************/ +#define cl_intel_exec_by_local_thread 1 +#define CL_INTEL_EXEC_BY_LOCAL_THREAD_EXTENSION_NAME \ + "cl_intel_exec_by_local_thread" + + +#define CL_INTEL_EXEC_BY_LOCAL_THREAD_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_command_queue_properties - bitfield */ +#define CL_QUEUE_THREAD_LOCAL_EXEC_ENABLE_INTEL ((cl_bitfield)1 << 31) + +/*************************************************************** +* cl_intel_device_attribute_query +***************************************************************/ +#define cl_intel_device_attribute_query 1 +#define CL_INTEL_DEVICE_ATTRIBUTE_QUERY_EXTENSION_NAME \ + "cl_intel_device_attribute_query" + + +#define CL_INTEL_DEVICE_ATTRIBUTE_QUERY_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef cl_bitfield cl_device_feature_capabilities_intel; + +/* cl_device_feature_capabilities_intel */ +#define CL_DEVICE_FEATURE_FLAG_DP4A_INTEL (1 << 0) +#define CL_DEVICE_FEATURE_FLAG_DPAS_INTEL (1 << 1) + +/* cl_device_info */ +#define CL_DEVICE_IP_VERSION_INTEL 0x4250 +#define CL_DEVICE_ID_INTEL 0x4251 +#define CL_DEVICE_NUM_SLICES_INTEL 0x4252 +#define CL_DEVICE_NUM_SUB_SLICES_PER_SLICE_INTEL 0x4253 +#define CL_DEVICE_NUM_EUS_PER_SUB_SLICE_INTEL 0x4254 +#define CL_DEVICE_NUM_THREADS_PER_EU_INTEL 0x4255 +#define CL_DEVICE_FEATURE_CAPABILITIES_INTEL 0x4256 + +/*************************************************************** +* cl_intel_device_partition_by_names +***************************************************************/ +#define cl_intel_device_partition_by_names 1 +#define CL_INTEL_DEVICE_PARTITION_BY_NAMES_EXTENSION_NAME \ + "cl_intel_device_partition_by_names" + + +#define CL_INTEL_DEVICE_PARTITION_BY_NAMES_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +#define CL_DEVICE_PARTITION_BY_NAMES_INTEL 0x4052 +#define CL_PARTITION_BY_NAMES_LIST_END_INTEL -1 + +/*************************************************************** +* cl_intel_accelerator +***************************************************************/ +#define cl_intel_accelerator 1 +#define CL_INTEL_ACCELERATOR_EXTENSION_NAME \ + "cl_intel_accelerator" + + +#define CL_INTEL_ACCELERATOR_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef struct _cl_accelerator_intel* cl_accelerator_intel; +typedef cl_uint cl_accelerator_type_intel; +typedef cl_uint cl_accelerator_info_intel; + +/* cl_accelerator_info_intel */ +#define CL_ACCELERATOR_DESCRIPTOR_INTEL 0x4090 +#define CL_ACCELERATOR_REFERENCE_COUNT_INTEL 0x4091 +#define CL_ACCELERATOR_CONTEXT_INTEL 0x4092 +#define CL_ACCELERATOR_TYPE_INTEL 0x4093 + +/* Error codes */ +#define CL_INVALID_ACCELERATOR_INTEL -1094 +#define CL_INVALID_ACCELERATOR_TYPE_INTEL -1095 +#define CL_INVALID_ACCELERATOR_DESCRIPTOR_INTEL -1096 +#define CL_ACCELERATOR_TYPE_NOT_SUPPORTED_INTEL -1097 + + +typedef cl_accelerator_intel CL_API_CALL +clCreateAcceleratorINTEL_t( + cl_context context, + cl_accelerator_type_intel accelerator_type, + size_t descriptor_size, + const void* descriptor, + cl_int* errcode_ret); + +typedef clCreateAcceleratorINTEL_t * +clCreateAcceleratorINTEL_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clGetAcceleratorInfoINTEL_t( + cl_accelerator_intel accelerator, + cl_accelerator_info_intel param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetAcceleratorInfoINTEL_t * +clGetAcceleratorInfoINTEL_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clRetainAcceleratorINTEL_t( + cl_accelerator_intel accelerator); + +typedef clRetainAcceleratorINTEL_t * +clRetainAcceleratorINTEL_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clReleaseAcceleratorINTEL_t( + cl_accelerator_intel accelerator); + +typedef clReleaseAcceleratorINTEL_t * +clReleaseAcceleratorINTEL_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_accelerator_intel CL_API_CALL +clCreateAcceleratorINTEL( + cl_context context, + cl_accelerator_type_intel accelerator_type, + size_t descriptor_size, + const void* descriptor, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetAcceleratorInfoINTEL( + cl_accelerator_intel accelerator, + cl_accelerator_info_intel param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clRetainAcceleratorINTEL( + cl_accelerator_intel accelerator) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clReleaseAcceleratorINTEL( + cl_accelerator_intel accelerator) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_intel_motion_estimation +***************************************************************/ +#define cl_intel_motion_estimation 1 +#define CL_INTEL_MOTION_ESTIMATION_EXTENSION_NAME \ + "cl_intel_motion_estimation" + + +#define CL_INTEL_MOTION_ESTIMATION_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef struct _cl_motion_estimation_desc_intel { + cl_uint mb_block_type; + cl_uint subpixel_mode; + cl_uint sad_adjust_mode; + cl_uint search_path_type; +} cl_motion_estimation_desc_intel; + +/* cl_accelerator_type_intel */ +#define CL_ACCELERATOR_TYPE_MOTION_ESTIMATION_INTEL 0x0 + +/* cl_uint mb_block_type */ +#define CL_ME_MB_TYPE_16x16_INTEL 0x0 +#define CL_ME_MB_TYPE_8x8_INTEL 0x1 +#define CL_ME_MB_TYPE_4x4_INTEL 0x2 + +/* cl_uint subpixel_mode */ +#define CL_ME_SUBPIXEL_MODE_INTEGER_INTEL 0x0 +#define CL_ME_SUBPIXEL_MODE_HPEL_INTEL 0x1 +#define CL_ME_SUBPIXEL_MODE_QPEL_INTEL 0x2 + +/* cl_uint sad_adjust_mode */ +#define CL_ME_SAD_ADJUST_MODE_NONE_INTEL 0x0 +#define CL_ME_SAD_ADJUST_MODE_HAAR_INTEL 0x1 + +/* cl_uint search_path_type */ +#define CL_ME_SEARCH_PATH_RADIUS_2_2_INTEL 0x0 +#define CL_ME_SEARCH_PATH_RADIUS_4_4_INTEL 0x1 +#define CL_ME_SEARCH_PATH_RADIUS_16_12_INTEL 0x5 + +/*************************************************************** +* cl_intel_advanced_motion_estimation +***************************************************************/ +#define cl_intel_advanced_motion_estimation 1 +#define CL_INTEL_ADVANCED_MOTION_ESTIMATION_EXTENSION_NAME \ + "cl_intel_advanced_motion_estimation" + + +#define CL_INTEL_ADVANCED_MOTION_ESTIMATION_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_ME_VERSION_INTEL 0x407E + +#define CL_ME_VERSION_LEGACY_INTEL 0x0 +#define CL_ME_VERSION_ADVANCED_VER_1_INTEL 0x1 +#define CL_ME_VERSION_ADVANCED_VER_2_INTEL 0x2 + +#define CL_ME_CHROMA_INTRA_PREDICT_ENABLED_INTEL 0x1 +#define CL_ME_LUMA_INTRA_PREDICT_ENABLED_INTEL 0x2 + +#define CL_ME_SKIP_BLOCK_TYPE_16x16_INTEL 0x0 +#define CL_ME_SKIP_BLOCK_TYPE_8x8_INTEL 0x4 + +#define CL_ME_COST_PENALTY_NONE_INTEL 0x0 +#define CL_ME_COST_PENALTY_LOW_INTEL 0x1 +#define CL_ME_COST_PENALTY_NORMAL_INTEL 0x2 +#define CL_ME_COST_PENALTY_HIGH_INTEL 0x3 + +#define CL_ME_COST_PRECISION_QPEL_INTEL 0x0 +#define CL_ME_COST_PRECISION_HPEL_INTEL 0x1 +#define CL_ME_COST_PRECISION_PEL_INTEL 0x2 +#define CL_ME_COST_PRECISION_DPEL_INTEL 0x3 + +#define CL_ME_LUMA_PREDICTOR_MODE_VERTICAL_INTEL 0x0 +#define CL_ME_LUMA_PREDICTOR_MODE_HORIZONTAL_INTEL 0x1 +#define CL_ME_LUMA_PREDICTOR_MODE_DC_INTEL 0x2 +#define CL_ME_LUMA_PREDICTOR_MODE_DIAGONAL_DOWN_LEFT_INTEL 0x3 +#define CL_ME_LUMA_PREDICTOR_MODE_DIAGONAL_DOWN_RIGHT_INTEL 0x4 +#define CL_ME_LUMA_PREDICTOR_MODE_PLANE_INTEL 0x4 +#define CL_ME_LUMA_PREDICTOR_MODE_VERTICAL_RIGHT_INTEL 0x5 +#define CL_ME_LUMA_PREDICTOR_MODE_HORIZONTAL_DOWN_INTEL 0x6 +#define CL_ME_LUMA_PREDICTOR_MODE_VERTICAL_LEFT_INTEL 0x7 +#define CL_ME_LUMA_PREDICTOR_MODE_HORIZONTAL_UP_INTEL 0x8 + +#define CL_ME_CHROMA_PREDICTOR_MODE_DC_INTEL 0x0 +#define CL_ME_CHROMA_PREDICTOR_MODE_HORIZONTAL_INTEL 0x1 +#define CL_ME_CHROMA_PREDICTOR_MODE_VERTICAL_INTEL 0x2 +#define CL_ME_CHROMA_PREDICTOR_MODE_PLANE_INTEL 0x3 + +#define CL_ME_FORWARD_INPUT_MODE_INTEL 0x1 +#define CL_ME_BACKWARD_INPUT_MODE_INTEL 0x2 +#define CL_ME_BIDIRECTION_INPUT_MODE_INTEL 0x3 + +#define CL_ME_BIDIR_WEIGHT_QUARTER_INTEL 16 +#define CL_ME_BIDIR_WEIGHT_THIRD_INTEL 21 +#define CL_ME_BIDIR_WEIGHT_HALF_INTEL 32 +#define CL_ME_BIDIR_WEIGHT_TWO_THIRD_INTEL 43 +#define CL_ME_BIDIR_WEIGHT_THREE_QUARTER_INTEL 48 + +/*************************************************************** +* cl_intel_simultaneous_sharing +***************************************************************/ +#define cl_intel_simultaneous_sharing 1 +#define CL_INTEL_SIMULTANEOUS_SHARING_EXTENSION_NAME \ + "cl_intel_simultaneous_sharing" + + +#define CL_INTEL_SIMULTANEOUS_SHARING_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_SIMULTANEOUS_INTEROPS_INTEL 0x4104 +#define CL_DEVICE_NUM_SIMULTANEOUS_INTEROPS_INTEL 0x4105 + +/*************************************************************** +* cl_intel_egl_image_yuv +***************************************************************/ +#define cl_intel_egl_image_yuv 1 +#define CL_INTEL_EGL_IMAGE_YUV_EXTENSION_NAME \ + "cl_intel_egl_image_yuv" + + +#define CL_INTEL_EGL_IMAGE_YUV_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_egl_image_properties_khr */ +#define CL_EGL_YUV_PLANE_INTEL 0x4107 + +/*************************************************************** +* cl_intel_packed_yuv +***************************************************************/ +#define cl_intel_packed_yuv 1 +#define CL_INTEL_PACKED_YUV_EXTENSION_NAME \ + "cl_intel_packed_yuv" + + +#define CL_INTEL_PACKED_YUV_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_channel_order */ +#define CL_YUYV_INTEL 0x4076 +#define CL_UYVY_INTEL 0x4077 +#define CL_YVYU_INTEL 0x4078 +#define CL_VYUY_INTEL 0x4079 + +/*************************************************************** +* cl_intel_required_subgroup_size +***************************************************************/ +#define cl_intel_required_subgroup_size 1 +#define CL_INTEL_REQUIRED_SUBGROUP_SIZE_EXTENSION_NAME \ + "cl_intel_required_subgroup_size" + + +#define CL_INTEL_REQUIRED_SUBGROUP_SIZE_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_SUB_GROUP_SIZES_INTEL 0x4108 + +/* cl_kernel_work_group_info */ +#define CL_KERNEL_SPILL_MEM_SIZE_INTEL 0x4109 + +/* cl_kernel_sub_group_info */ +#define CL_KERNEL_COMPILE_SUB_GROUP_SIZE_INTEL 0x410A + +/*************************************************************** +* cl_intel_driver_diagnostics +***************************************************************/ +#define cl_intel_driver_diagnostics 1 +#define CL_INTEL_DRIVER_DIAGNOSTICS_EXTENSION_NAME \ + "cl_intel_driver_diagnostics" + + +#define CL_INTEL_DRIVER_DIAGNOSTICS_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef cl_bitfield cl_diagnostic_verbose_level_intel; + +/* cl_context_properties */ +#define CL_CONTEXT_SHOW_DIAGNOSTICS_INTEL 0x4106 + +/* cl_diagnostic_verbose_level_intel */ +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_ALL_INTEL 0xff +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_GOOD_INTEL (1 << 0) +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_BAD_INTEL (1 << 1) +#define CL_CONTEXT_DIAGNOSTICS_LEVEL_NEUTRAL_INTEL (1 << 2) + +/*************************************************************** +* cl_intel_planar_yuv +***************************************************************/ +#define cl_intel_planar_yuv 1 +#define CL_INTEL_PLANAR_YUV_EXTENSION_NAME \ + "cl_intel_planar_yuv" + + +#define CL_INTEL_PLANAR_YUV_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_channel_order */ +#define CL_NV12_INTEL 0x410E + +/* cl_mem_flags */ +#define CL_MEM_NO_ACCESS_INTEL (1 << 24) +#define CL_MEM_ACCESS_FLAGS_UNRESTRICTED_INTEL (1 << 25) + +/* cl_device_info */ +#define CL_DEVICE_PLANAR_YUV_MAX_WIDTH_INTEL 0x417E +#define CL_DEVICE_PLANAR_YUV_MAX_HEIGHT_INTEL 0x417F + +/*************************************************************** +* cl_intel_device_side_avc_motion_estimation +***************************************************************/ +#define cl_intel_device_side_avc_motion_estimation 1 +#define CL_INTEL_DEVICE_SIDE_AVC_MOTION_ESTIMATION_EXTENSION_NAME \ + "cl_intel_device_side_avc_motion_estimation" + + +#define CL_INTEL_DEVICE_SIDE_AVC_MOTION_ESTIMATION_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_AVC_ME_VERSION_INTEL 0x410B +#define CL_DEVICE_AVC_ME_SUPPORTS_TEXTURE_SAMPLER_USE_INTEL 0x410C +#define CL_DEVICE_AVC_ME_SUPPORTS_PREEMPTION_INTEL 0x410D + +/* returned by CL_DEVICE_AVC_ME_VERSION_INTEL */ +#define CL_AVC_ME_VERSION_0_INTEL 0x0 +#define CL_AVC_ME_VERSION_1_INTEL 0x1 + +/* Inter macro-block major shape values */ +#define CL_AVC_ME_MAJOR_16x16_INTEL 0x0 +#define CL_AVC_ME_MAJOR_16x8_INTEL 0x1 +#define CL_AVC_ME_MAJOR_8x16_INTEL 0x2 +#define CL_AVC_ME_MAJOR_8x8_INTEL 0x3 + +/* Inter macro-block minor shape values */ +#define CL_AVC_ME_MINOR_8x8_INTEL 0x0 +#define CL_AVC_ME_MINOR_8x4_INTEL 0x1 +#define CL_AVC_ME_MINOR_4x8_INTEL 0x2 +#define CL_AVC_ME_MINOR_4x4_INTEL 0x3 + +/* Inter macro-block major direction values */ +#define CL_AVC_ME_MAJOR_FORWARD_INTEL 0x0 +#define CL_AVC_ME_MAJOR_BACKWARD_INTEL 0x1 +#define CL_AVC_ME_MAJOR_BIDIRECTIONAL_INTEL 0x2 + +/* Inter (IME) partition mask values */ +#define CL_AVC_ME_PARTITION_MASK_ALL_INTEL 0x0 +#define CL_AVC_ME_PARTITION_MASK_16x16_INTEL 0x7E +#define CL_AVC_ME_PARTITION_MASK_16x8_INTEL 0x7D +#define CL_AVC_ME_PARTITION_MASK_8x16_INTEL 0x7B +#define CL_AVC_ME_PARTITION_MASK_8x8_INTEL 0x77 +#define CL_AVC_ME_PARTITION_MASK_8x4_INTEL 0x6F +#define CL_AVC_ME_PARTITION_MASK_4x8_INTEL 0x5F +#define CL_AVC_ME_PARTITION_MASK_4x4_INTEL 0x3F + +/* Search window configuration */ +#define CL_AVC_ME_SEARCH_WINDOW_EXHAUSTIVE_INTEL 0x0 +#define CL_AVC_ME_SEARCH_WINDOW_SMALL_INTEL 0x1 +#define CL_AVC_ME_SEARCH_WINDOW_TINY_INTEL 0x2 +#define CL_AVC_ME_SEARCH_WINDOW_EXTRA_TINY_INTEL 0x3 +#define CL_AVC_ME_SEARCH_WINDOW_DIAMOND_INTEL 0x4 +#define CL_AVC_ME_SEARCH_WINDOW_LARGE_DIAMOND_INTEL 0x5 +#define CL_AVC_ME_SEARCH_WINDOW_RESERVED0_INTEL 0x6 +#define CL_AVC_ME_SEARCH_WINDOW_RESERVED1_INTEL 0x7 +#define CL_AVC_ME_SEARCH_WINDOW_CUSTOM_INTEL 0x8 +#define CL_AVC_ME_SEARCH_WINDOW_16x12_RADIUS_INTEL 0x9 +#define CL_AVC_ME_SEARCH_WINDOW_4x4_RADIUS_INTEL 0x2 +#define CL_AVC_ME_SEARCH_WINDOW_2x2_RADIUS_INTEL 0xa + +/* SAD adjustment mode */ +#define CL_AVC_ME_SAD_ADJUST_MODE_NONE_INTEL 0x0 +#define CL_AVC_ME_SAD_ADJUST_MODE_HAAR_INTEL 0x2 + +/* Pixel resolution */ +#define CL_AVC_ME_SUBPIXEL_MODE_INTEGER_INTEL 0x0 +#define CL_AVC_ME_SUBPIXEL_MODE_HPEL_INTEL 0x1 +#define CL_AVC_ME_SUBPIXEL_MODE_QPEL_INTEL 0x3 + +/* Cost precision values */ +#define CL_AVC_ME_COST_PRECISION_QPEL_INTEL 0x0 +#define CL_AVC_ME_COST_PRECISION_HPEL_INTEL 0x1 +#define CL_AVC_ME_COST_PRECISION_PEL_INTEL 0x2 +#define CL_AVC_ME_COST_PRECISION_DPEL_INTEL 0x3 + +/* Inter bidirectional weights */ +#define CL_AVC_ME_BIDIR_WEIGHT_QUARTER_INTEL 0x10 +#define CL_AVC_ME_BIDIR_WEIGHT_THIRD_INTEL 0x15 +#define CL_AVC_ME_BIDIR_WEIGHT_HALF_INTEL 0x20 +#define CL_AVC_ME_BIDIR_WEIGHT_TWO_THIRD_INTEL 0x2B +#define CL_AVC_ME_BIDIR_WEIGHT_THREE_QUARTER_INTEL 0x30 + +/* Inter border reached values */ +#define CL_AVC_ME_BORDER_REACHED_LEFT_INTEL 0x0 +#define CL_AVC_ME_BORDER_REACHED_RIGHT_INTEL 0x2 +#define CL_AVC_ME_BORDER_REACHED_TOP_INTEL 0x4 +#define CL_AVC_ME_BORDER_REACHED_BOTTOM_INTEL 0x8 + +/* Inter skip block partition type */ +#define CL_AVC_ME_SKIP_BLOCK_PARTITION_16x16_INTEL 0x0 +#define CL_AVC_ME_SKIP_BLOCK_PARTITION_8x8_INTEL 0x4000 + +/* Inter skip motion vector mask */ +#define CL_AVC_ME_SKIP_BLOCK_16x16_FORWARD_ENABLE_INTEL (0x1 << 24) +#define CL_AVC_ME_SKIP_BLOCK_16x16_BACKWARD_ENABLE_INTEL (0x2 << 24) +#define CL_AVC_ME_SKIP_BLOCK_16x16_DUAL_ENABLE_INTEL (0x3 << 24) +#define CL_AVC_ME_SKIP_BLOCK_8x8_FORWARD_ENABLE_INTEL (0x55 << 24) +#define CL_AVC_ME_SKIP_BLOCK_8x8_BACKWARD_ENABLE_INTEL (0xAA << 24) +#define CL_AVC_ME_SKIP_BLOCK_8x8_DUAL_ENABLE_INTEL (0xFF << 24) +#define CL_AVC_ME_SKIP_BLOCK_8x8_0_FORWARD_ENABLE_INTEL (0x1 << 24) +#define CL_AVC_ME_SKIP_BLOCK_8x8_0_BACKWARD_ENABLE_INTEL (0x2 << 24) +#define CL_AVC_ME_SKIP_BLOCK_8x8_1_FORWARD_ENABLE_INTEL (0x1 << 26) +#define CL_AVC_ME_SKIP_BLOCK_8x8_1_BACKWARD_ENABLE_INTEL (0x2 << 26) +#define CL_AVC_ME_SKIP_BLOCK_8x8_2_FORWARD_ENABLE_INTEL (0x1 << 28) +#define CL_AVC_ME_SKIP_BLOCK_8x8_2_BACKWARD_ENABLE_INTEL (0x2 << 28) +#define CL_AVC_ME_SKIP_BLOCK_8x8_3_FORWARD_ENABLE_INTEL (0x1 << 30) +#define CL_AVC_ME_SKIP_BLOCK_8x8_3_BACKWARD_ENABLE_INTEL (0x2 << 30) + +/* Block based skip type values */ +#define CL_AVC_ME_BLOCK_BASED_SKIP_4x4_INTEL 0x00 +#define CL_AVC_ME_BLOCK_BASED_SKIP_8x8_INTEL 0x80 + +/* cl_intel_device_side_avc_motion_estimation.?? */ +#define CL_AVC_ME_INTRA_16x16_INTEL 0x0 +#define CL_AVC_ME_INTRA_8x8_INTEL 0x1 +#define CL_AVC_ME_INTRA_4x4_INTEL 0x2 + +/* Luma intra partition mask values */ +#define CL_AVC_ME_INTRA_LUMA_PARTITION_MASK_16x16_INTEL 0x6 +#define CL_AVC_ME_INTRA_LUMA_PARTITION_MASK_8x8_INTEL 0x5 +#define CL_AVC_ME_INTRA_LUMA_PARTITION_MASK_4x4_INTEL 0x3 + +/* Intra neighbor availability mask values */ +#define CL_AVC_ME_INTRA_NEIGHBOR_LEFT_MASK_ENABLE_INTEL 0x60 +#define CL_AVC_ME_INTRA_NEIGHBOR_UPPER_MASK_ENABLE_INTEL 0x10 +#define CL_AVC_ME_INTRA_NEIGHBOR_UPPER_RIGHT_MASK_ENABLE_INTEL 0x8 +#define CL_AVC_ME_INTRA_NEIGHBOR_UPPER_LEFT_MASK_ENABLE_INTEL 0x4 + +/* Luma intra modes */ +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_VERTICAL_INTEL 0x0 +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_HORIZONTAL_INTEL 0x1 +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_DC_INTEL 0x2 +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_DIAGONAL_DOWN_LEFT_INTEL 0x3 +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_DIAGONAL_DOWN_RIGHT_INTEL 0x4 +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_PLANE_INTEL 0x4 +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_VERTICAL_RIGHT_INTEL 0x5 +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_HORIZONTAL_DOWN_INTEL 0x6 +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_VERTICAL_LEFT_INTEL 0x7 +#define CL_AVC_ME_LUMA_PREDICTOR_MODE_HORIZONTAL_UP_INTEL 0x8 + +/* Chroma intra modes */ +#define CL_AVC_ME_CHROMA_PREDICTOR_MODE_DC_INTEL 0x0 +#define CL_AVC_ME_CHROMA_PREDICTOR_MODE_HORIZONTAL_INTEL 0x1 +#define CL_AVC_ME_CHROMA_PREDICTOR_MODE_VERTICAL_INTEL 0x2 +#define CL_AVC_ME_CHROMA_PREDICTOR_MODE_PLANE_INTEL 0x3 + +/* Reference image select values */ +#define CL_AVC_ME_FRAME_FORWARD_INTEL 0x1 +#define CL_AVC_ME_FRAME_BACKWARD_INTEL 0x2 +#define CL_AVC_ME_FRAME_DUAL_INTEL 0x3 + +/* Slice type values */ +#define CL_AVC_ME_SLICE_TYPE_PRED_INTEL 0x0 +#define CL_AVC_ME_SLICE_TYPE_BPRED_INTEL 0x1 +#define CL_AVC_ME_SLICE_TYPE_INTRA_INTEL 0x2 + +/* Interlaced image field polarity values */ +#define CL_AVC_ME_INTERLACED_SCAN_TOP_FIELD_INTEL 0x0 +#define CL_AVC_ME_INTERLACED_SCAN_BOTTOM_FIELD_INTEL 0x1 + +/*************************************************************** +* cl_intel_unified_shared_memory +***************************************************************/ +#define cl_intel_unified_shared_memory 1 +#define CL_INTEL_UNIFIED_SHARED_MEMORY_EXTENSION_NAME \ + "cl_intel_unified_shared_memory" + + +#define CL_INTEL_UNIFIED_SHARED_MEMORY_EXTENSION_VERSION CL_MAKE_VERSION(1, 1, 0) + +typedef cl_bitfield cl_device_unified_shared_memory_capabilities_intel; +typedef cl_properties cl_mem_properties_intel; +typedef cl_bitfield cl_mem_alloc_flags_intel; +typedef cl_uint cl_mem_info_intel; +typedef cl_uint cl_unified_shared_memory_type_intel; +typedef cl_uint cl_mem_advice_intel; + +/* cl_device_info */ +#define CL_DEVICE_HOST_MEM_CAPABILITIES_INTEL 0x4190 +#define CL_DEVICE_DEVICE_MEM_CAPABILITIES_INTEL 0x4191 +#define CL_DEVICE_SINGLE_DEVICE_SHARED_MEM_CAPABILITIES_INTEL 0x4192 +#define CL_DEVICE_CROSS_DEVICE_SHARED_MEM_CAPABILITIES_INTEL 0x4193 +#define CL_DEVICE_SHARED_SYSTEM_MEM_CAPABILITIES_INTEL 0x4194 + +/* cl_unified_shared_memory_capabilities_intel - bitfield */ +#define CL_UNIFIED_SHARED_MEMORY_ACCESS_INTEL (1 << 0) +#define CL_UNIFIED_SHARED_MEMORY_ATOMIC_ACCESS_INTEL (1 << 1) +#define CL_UNIFIED_SHARED_MEMORY_CONCURRENT_ACCESS_INTEL (1 << 2) +#define CL_UNIFIED_SHARED_MEMORY_CONCURRENT_ATOMIC_ACCESS_INTEL (1 << 3) + +/* cl_mem_properties_intel */ +#define CL_MEM_ALLOC_FLAGS_INTEL 0x4195 + +/* cl_mem_alloc_flags_intel - bitfield */ +#define CL_MEM_ALLOC_WRITE_COMBINED_INTEL (1 << 0) +#define CL_MEM_ALLOC_INITIAL_PLACEMENT_DEVICE_INTEL (1 << 1) +#define CL_MEM_ALLOC_INITIAL_PLACEMENT_HOST_INTEL (1 << 2) + +/* cl_mem_alloc_info_intel */ +#define CL_MEM_ALLOC_TYPE_INTEL 0x419A +#define CL_MEM_ALLOC_BASE_PTR_INTEL 0x419B +#define CL_MEM_ALLOC_SIZE_INTEL 0x419C +#define CL_MEM_ALLOC_DEVICE_INTEL 0x419D + +/* cl_unified_shared_memory_type_intel */ +#define CL_MEM_TYPE_UNKNOWN_INTEL 0x4196 +#define CL_MEM_TYPE_HOST_INTEL 0x4197 +#define CL_MEM_TYPE_DEVICE_INTEL 0x4198 +#define CL_MEM_TYPE_SHARED_INTEL 0x4199 + +/* cl_kernel_exec_info */ +#define CL_KERNEL_EXEC_INFO_INDIRECT_HOST_ACCESS_INTEL 0x4200 +#define CL_KERNEL_EXEC_INFO_INDIRECT_DEVICE_ACCESS_INTEL 0x4201 +#define CL_KERNEL_EXEC_INFO_INDIRECT_SHARED_ACCESS_INTEL 0x4202 +#define CL_KERNEL_EXEC_INFO_USM_PTRS_INTEL 0x4203 + +/* cl_command_type */ +#define CL_COMMAND_MEMFILL_INTEL 0x4204 +#define CL_COMMAND_MEMCPY_INTEL 0x4205 +#define CL_COMMAND_MIGRATEMEM_INTEL 0x4206 +#define CL_COMMAND_MEMADVISE_INTEL 0x4207 + + +typedef void* CL_API_CALL +clHostMemAllocINTEL_t( + cl_context context, + const cl_mem_properties_intel* properties, + size_t size, + cl_uint alignment, + cl_int* errcode_ret); + +typedef clHostMemAllocINTEL_t * +clHostMemAllocINTEL_fn ; + +typedef void* CL_API_CALL +clDeviceMemAllocINTEL_t( + cl_context context, + cl_device_id device, + const cl_mem_properties_intel* properties, + size_t size, + cl_uint alignment, + cl_int* errcode_ret); + +typedef clDeviceMemAllocINTEL_t * +clDeviceMemAllocINTEL_fn ; + +typedef void* CL_API_CALL +clSharedMemAllocINTEL_t( + cl_context context, + cl_device_id device, + const cl_mem_properties_intel* properties, + size_t size, + cl_uint alignment, + cl_int* errcode_ret); + +typedef clSharedMemAllocINTEL_t * +clSharedMemAllocINTEL_fn ; + +typedef cl_int CL_API_CALL +clMemFreeINTEL_t( + cl_context context, + void* ptr); + +typedef clMemFreeINTEL_t * +clMemFreeINTEL_fn ; + +typedef cl_int CL_API_CALL +clMemBlockingFreeINTEL_t( + cl_context context, + void* ptr); + +typedef clMemBlockingFreeINTEL_t * +clMemBlockingFreeINTEL_fn ; + +typedef cl_int CL_API_CALL +clGetMemAllocInfoINTEL_t( + cl_context context, + const void* ptr, + cl_mem_info_intel param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetMemAllocInfoINTEL_t * +clGetMemAllocInfoINTEL_fn ; + +typedef cl_int CL_API_CALL +clSetKernelArgMemPointerINTEL_t( + cl_kernel kernel, + cl_uint arg_index, + const void* arg_value); + +typedef clSetKernelArgMemPointerINTEL_t * +clSetKernelArgMemPointerINTEL_fn ; + +typedef cl_int CL_API_CALL +clEnqueueMemFillINTEL_t( + cl_command_queue command_queue, + void* dst_ptr, + const void* pattern, + size_t pattern_size, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueMemFillINTEL_t * +clEnqueueMemFillINTEL_fn ; + +typedef cl_int CL_API_CALL +clEnqueueMemcpyINTEL_t( + cl_command_queue command_queue, + cl_bool blocking, + void* dst_ptr, + const void* src_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueMemcpyINTEL_t * +clEnqueueMemcpyINTEL_fn ; + +typedef cl_int CL_API_CALL +clEnqueueMemAdviseINTEL_t( + cl_command_queue command_queue, + const void* ptr, + size_t size, + cl_mem_advice_intel advice, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueMemAdviseINTEL_t * +clEnqueueMemAdviseINTEL_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY void* CL_API_CALL +clHostMemAllocINTEL( + cl_context context, + const cl_mem_properties_intel* properties, + size_t size, + cl_uint alignment, + cl_int* errcode_ret) ; + +extern CL_API_ENTRY void* CL_API_CALL +clDeviceMemAllocINTEL( + cl_context context, + cl_device_id device, + const cl_mem_properties_intel* properties, + size_t size, + cl_uint alignment, + cl_int* errcode_ret) ; + +extern CL_API_ENTRY void* CL_API_CALL +clSharedMemAllocINTEL( + cl_context context, + cl_device_id device, + const cl_mem_properties_intel* properties, + size_t size, + cl_uint alignment, + cl_int* errcode_ret) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clMemFreeINTEL( + cl_context context, + void* ptr) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clMemBlockingFreeINTEL( + cl_context context, + void* ptr) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetMemAllocInfoINTEL( + cl_context context, + const void* ptr, + cl_mem_info_intel param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetKernelArgMemPointerINTEL( + cl_kernel kernel, + cl_uint arg_index, + const void* arg_value) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMemFillINTEL( + cl_command_queue command_queue, + void* dst_ptr, + const void* pattern, + size_t pattern_size, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMemcpyINTEL( + cl_command_queue command_queue, + cl_bool blocking, + void* dst_ptr, + const void* src_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMemAdviseINTEL( + cl_command_queue command_queue, + const void* ptr, + size_t size, + cl_mem_advice_intel advice, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#if defined(CL_VERSION_1_2) +/* Requires OpenCL 1.2 for cl_mem_migration_flags: */ + +typedef cl_int CL_API_CALL +clEnqueueMigrateMemINTEL_t( + cl_command_queue command_queue, + const void* ptr, + size_t size, + cl_mem_migration_flags flags, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueMigrateMemINTEL_t * +clEnqueueMigrateMemINTEL_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMigrateMemINTEL( + cl_command_queue command_queue, + const void* ptr, + size_t size, + cl_mem_migration_flags flags, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#endif /* defined(CL_VERSION_1_2) */ + +/* deprecated, use clEnqueueMemFillINTEL instead */ + +typedef cl_int CL_API_CALL +clEnqueueMemsetINTEL_t( + cl_command_queue command_queue, + void* dst_ptr, + cl_int value, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueMemsetINTEL_t * +clEnqueueMemsetINTEL_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueMemsetINTEL( + cl_command_queue command_queue, + void* dst_ptr, + cl_int value, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_intel_mem_alloc_buffer_location +***************************************************************/ +#define cl_intel_mem_alloc_buffer_location 1 +#define CL_INTEL_MEM_ALLOC_BUFFER_LOCATION_EXTENSION_NAME \ + "cl_intel_mem_alloc_buffer_location" + + +#define CL_INTEL_MEM_ALLOC_BUFFER_LOCATION_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_mem_properties_intel */ +#define CL_MEM_ALLOC_BUFFER_LOCATION_INTEL 0x419E + +/* cl_mem_alloc_info_intel */ +/* enum CL_MEM_ALLOC_BUFFER_LOCATION_INTEL */ + +/*************************************************************** +* cl_intel_create_buffer_with_properties +***************************************************************/ +#define cl_intel_create_buffer_with_properties 1 +#define CL_INTEL_CREATE_BUFFER_WITH_PROPERTIES_EXTENSION_NAME \ + "cl_intel_create_buffer_with_properties" + + +#define CL_INTEL_CREATE_BUFFER_WITH_PROPERTIES_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* type cl_mem_properties_intel */ + + +typedef cl_mem CL_API_CALL +clCreateBufferWithPropertiesINTEL_t( + cl_context context, + const cl_mem_properties_intel* properties, + cl_mem_flags flags, + size_t size, + void* host_ptr, + cl_int* errcode_ret); + +typedef clCreateBufferWithPropertiesINTEL_t * +clCreateBufferWithPropertiesINTEL_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateBufferWithPropertiesINTEL( + cl_context context, + const cl_mem_properties_intel* properties, + cl_mem_flags flags, + size_t size, + void* host_ptr, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_intel_program_scope_host_pipe +***************************************************************/ +#define cl_intel_program_scope_host_pipe 1 +#define CL_INTEL_PROGRAM_SCOPE_HOST_PIPE_EXTENSION_NAME \ + "cl_intel_program_scope_host_pipe" + + +#define CL_INTEL_PROGRAM_SCOPE_HOST_PIPE_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* clGetEventInfo response when param_name is CL_EVENT_COMMAND_TYPE */ +#define CL_COMMAND_READ_HOST_PIPE_INTEL 0x4214 +#define CL_COMMAND_WRITE_HOST_PIPE_INTEL 0x4215 + +/* clGetProgramInfo param_name */ +#define CL_PROGRAM_NUM_HOST_PIPES_INTEL 0x4216 +#define CL_PROGRAM_HOST_PIPE_NAMES_INTEL 0x4217 + + +typedef cl_int CL_API_CALL +clEnqueueReadHostPipeINTEL_t( + cl_command_queue command_queue, + cl_program program, + const char* pipe_symbol, + cl_bool blocking_read, + void* ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReadHostPipeINTEL_t * +clEnqueueReadHostPipeINTEL_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL +clEnqueueWriteHostPipeINTEL_t( + cl_command_queue command_queue, + cl_program program, + const char* pipe_symbol, + cl_bool blocking_write, + const void* ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueWriteHostPipeINTEL_t * +clEnqueueWriteHostPipeINTEL_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReadHostPipeINTEL( + cl_command_queue command_queue, + cl_program program, + const char* pipe_symbol, + cl_bool blocking_read, + void* ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueWriteHostPipeINTEL( + cl_command_queue command_queue, + cl_program program, + const char* pipe_symbol, + cl_bool blocking_write, + const void* ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_intel_mem_channel_property +***************************************************************/ +#define cl_intel_mem_channel_property 1 +#define CL_INTEL_MEM_CHANNEL_PROPERTY_EXTENSION_NAME \ + "cl_intel_mem_channel_property" + + +#define CL_INTEL_MEM_CHANNEL_PROPERTY_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_mem_properties_intel */ +#define CL_MEM_CHANNEL_INTEL 0x4213 + +/*************************************************************** +* cl_intel_mem_force_host_memory +***************************************************************/ +#define cl_intel_mem_force_host_memory 1 +#define CL_INTEL_MEM_FORCE_HOST_MEMORY_EXTENSION_NAME \ + "cl_intel_mem_force_host_memory" + + +#define CL_INTEL_MEM_FORCE_HOST_MEMORY_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_mem_flags */ +#define CL_MEM_FORCE_HOST_MEMORY_INTEL (1 << 20) + +/*************************************************************** +* cl_intel_command_queue_families +***************************************************************/ +#define cl_intel_command_queue_families 1 +#define CL_INTEL_COMMAND_QUEUE_FAMILIES_EXTENSION_NAME \ + "cl_intel_command_queue_families" + + +#define CL_INTEL_COMMAND_QUEUE_FAMILIES_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef cl_bitfield cl_command_queue_capabilities_intel; + +#define CL_QUEUE_FAMILY_MAX_NAME_SIZE_INTEL 64 + +typedef struct _cl_queue_family_properties_intel { + cl_command_queue_properties properties; + cl_command_queue_capabilities_intel capabilities; + cl_uint count; + char name[CL_QUEUE_FAMILY_MAX_NAME_SIZE_INTEL]; +} cl_queue_family_properties_intel; + +/* cl_device_info */ +#define CL_DEVICE_QUEUE_FAMILY_PROPERTIES_INTEL 0x418B + +/* cl_queue_properties */ +#define CL_QUEUE_FAMILY_INTEL 0x418C +#define CL_QUEUE_INDEX_INTEL 0x418D + +/* cl_command_queue_capabilities_intel */ +#define CL_QUEUE_DEFAULT_CAPABILITIES_INTEL 0 +#define CL_QUEUE_CAPABILITY_CREATE_SINGLE_QUEUE_EVENTS_INTEL (1 << 0) +#define CL_QUEUE_CAPABILITY_CREATE_CROSS_QUEUE_EVENTS_INTEL (1 << 1) +#define CL_QUEUE_CAPABILITY_SINGLE_QUEUE_EVENT_WAIT_LIST_INTEL (1 << 2) +#define CL_QUEUE_CAPABILITY_CROSS_QUEUE_EVENT_WAIT_LIST_INTEL (1 << 3) +#define CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_INTEL (1 << 8) +#define CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_RECT_INTEL (1 << 9) +#define CL_QUEUE_CAPABILITY_MAP_BUFFER_INTEL (1 << 10) +#define CL_QUEUE_CAPABILITY_FILL_BUFFER_INTEL (1 << 11) +#define CL_QUEUE_CAPABILITY_TRANSFER_IMAGE_INTEL (1 << 12) +#define CL_QUEUE_CAPABILITY_MAP_IMAGE_INTEL (1 << 13) +#define CL_QUEUE_CAPABILITY_FILL_IMAGE_INTEL (1 << 14) +#define CL_QUEUE_CAPABILITY_TRANSFER_BUFFER_IMAGE_INTEL (1 << 15) +#define CL_QUEUE_CAPABILITY_TRANSFER_IMAGE_BUFFER_INTEL (1 << 16) +#define CL_QUEUE_CAPABILITY_MARKER_INTEL (1 << 24) +#define CL_QUEUE_CAPABILITY_BARRIER_INTEL (1 << 25) +#define CL_QUEUE_CAPABILITY_KERNEL_INTEL (1 << 26) + +/*************************************************************** +* cl_intel_queue_no_sync_operations +***************************************************************/ +#define cl_intel_queue_no_sync_operations 1 +#define CL_INTEL_QUEUE_NO_SYNC_OPERATIONS_EXTENSION_NAME \ + "cl_intel_queue_no_sync_operations" + + +#define CL_INTEL_QUEUE_NO_SYNC_OPERATIONS_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_command_queue_properties */ +#define CL_QUEUE_NO_SYNC_OPERATIONS_INTEL (1 << 29) + +/*************************************************************** +* cl_intel_sharing_format_query +***************************************************************/ +#define cl_intel_sharing_format_query 1 +#define CL_INTEL_SHARING_FORMAT_QUERY_EXTENSION_NAME \ + "cl_intel_sharing_format_query" + + +#define CL_INTEL_SHARING_FORMAT_QUERY_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/*************************************************************** +* cl_ext_image_requirements_info +***************************************************************/ +#if defined(CL_VERSION_3_0) + +#define cl_ext_image_requirements_info 1 +#define CL_EXT_IMAGE_REQUIREMENTS_INFO_EXTENSION_NAME \ + "cl_ext_image_requirements_info" + + +#define CL_EXT_IMAGE_REQUIREMENTS_INFO_EXTENSION_VERSION CL_MAKE_VERSION(0, 5, 0) + +/* Types */ +typedef cl_uint cl_image_requirements_info_ext; + +/* cl_image_requirements_info_ext */ +#define CL_IMAGE_REQUIREMENTS_BASE_ADDRESS_ALIGNMENT_EXT 0x1292 +#define CL_IMAGE_REQUIREMENTS_ROW_PITCH_ALIGNMENT_EXT 0x1290 +#define CL_IMAGE_REQUIREMENTS_SIZE_EXT 0x12B2 +#define CL_IMAGE_REQUIREMENTS_MAX_WIDTH_EXT 0x12B3 +#define CL_IMAGE_REQUIREMENTS_MAX_HEIGHT_EXT 0x12B4 +#define CL_IMAGE_REQUIREMENTS_MAX_DEPTH_EXT 0x12B5 +#define CL_IMAGE_REQUIREMENTS_MAX_ARRAY_SIZE_EXT 0x12B6 + +/* Enqueued Commands APIs */ + +typedef cl_int CL_API_CALL +clGetImageRequirementsInfoEXT_t( + cl_context context, + const cl_mem_properties* properties, + cl_mem_flags flags, + const cl_image_format* image_format, + const cl_image_desc* image_desc, + cl_image_requirements_info_ext param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetImageRequirementsInfoEXT_t * +clGetImageRequirementsInfoEXT_fn CL_API_SUFFIX__VERSION_3_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetImageRequirementsInfoEXT( + cl_context context, + const cl_mem_properties* properties, + cl_mem_flags flags, + const cl_image_format* image_format, + const cl_image_desc* image_desc, + cl_image_requirements_info_ext param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) CL_API_SUFFIX__VERSION_3_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#endif /* defined(CL_VERSION_3_0) */ + +/*************************************************************** +* cl_ext_image_from_buffer +***************************************************************/ +#if defined(CL_VERSION_3_0) + +#define cl_ext_image_from_buffer 1 +#define CL_EXT_IMAGE_FROM_BUFFER_EXTENSION_NAME \ + "cl_ext_image_from_buffer" + + +#define CL_EXT_IMAGE_FROM_BUFFER_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_image_requirements_info_ext */ +#define CL_IMAGE_REQUIREMENTS_SLICE_PITCH_ALIGNMENT_EXT 0x1291 + +#endif /* defined(CL_VERSION_3_0) */ + +/*************************************************************** +* cl_loader_info +***************************************************************/ +#define cl_loader_info 1 +#define CL_LOADER_INFO_EXTENSION_NAME \ + "cl_loader_info" + + +#define CL_LOADER_INFO_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_uint cl_icdl_info; + +/* cl_icdl_info */ +#define CL_ICDL_OCL_VERSION 1 +#define CL_ICDL_VERSION 2 +#define CL_ICDL_NAME 3 +#define CL_ICDL_VENDOR 4 + + +typedef cl_int CL_API_CALL +clGetICDLoaderInfoOCLICD_t( + cl_icdl_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetICDLoaderInfoOCLICD_t * +clGetICDLoaderInfoOCLICD_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetICDLoaderInfoOCLICD( + cl_icdl_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_depth_images +***************************************************************/ +#define cl_khr_depth_images 1 +#define CL_KHR_DEPTH_IMAGES_EXTENSION_NAME \ + "cl_khr_depth_images" + + +#define CL_KHR_DEPTH_IMAGES_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +#if !defined(CL_VERSION_2_0) +/* cl_channel_order - defined in CL.h for OpenCL 2.0 and newer */ +#define CL_DEPTH 0x10BD + +#endif /* !defined(CL_VERSION_2_0) */ + +/*************************************************************** +* cl_ext_float_atomics +***************************************************************/ +#define cl_ext_float_atomics 1 +#define CL_EXT_FLOAT_ATOMICS_EXTENSION_NAME \ + "cl_ext_float_atomics" + + +#define CL_EXT_FLOAT_ATOMICS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_bitfield cl_device_fp_atomic_capabilities_ext; + +/* cl_device_fp_atomic_capabilities_ext */ +#define CL_DEVICE_GLOBAL_FP_ATOMIC_LOAD_STORE_EXT (1 << 0) +#define CL_DEVICE_GLOBAL_FP_ATOMIC_ADD_EXT (1 << 1) +#define CL_DEVICE_GLOBAL_FP_ATOMIC_MIN_MAX_EXT (1 << 2) +#define CL_DEVICE_LOCAL_FP_ATOMIC_LOAD_STORE_EXT (1 << 16) +#define CL_DEVICE_LOCAL_FP_ATOMIC_ADD_EXT (1 << 17) +#define CL_DEVICE_LOCAL_FP_ATOMIC_MIN_MAX_EXT (1 << 18) + +/* cl_device_info */ +#define CL_DEVICE_SINGLE_FP_ATOMIC_CAPABILITIES_EXT 0x4231 +#define CL_DEVICE_DOUBLE_FP_ATOMIC_CAPABILITIES_EXT 0x4232 +#define CL_DEVICE_HALF_FP_ATOMIC_CAPABILITIES_EXT 0x4233 + +/*************************************************************** +* cl_intel_create_mem_object_properties +***************************************************************/ +#define cl_intel_create_mem_object_properties 1 +#define CL_INTEL_CREATE_MEM_OBJECT_PROPERTIES_EXTENSION_NAME \ + "cl_intel_create_mem_object_properties" + + +#define CL_INTEL_CREATE_MEM_OBJECT_PROPERTIES_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* cl_mem_properties */ +#define CL_MEM_LOCALLY_UNCACHED_RESOURCE_INTEL 0x4218 +#define CL_MEM_DEVICE_ID_INTEL 0x4219 + +/*************************************************************** +* cl_pocl_content_size +***************************************************************/ +#define cl_pocl_content_size 1 +#define CL_POCL_CONTENT_SIZE_EXTENSION_NAME \ + "cl_pocl_content_size" + + +#define CL_POCL_CONTENT_SIZE_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + + +typedef cl_int CL_API_CALL +clSetContentSizeBufferPoCL_t( + cl_mem buffer, + cl_mem content_size_buffer); + +typedef clSetContentSizeBufferPoCL_t * +clSetContentSizeBufferPoCL_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetContentSizeBufferPoCL( + cl_mem buffer, + cl_mem content_size_buffer) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_ext_image_raw10_raw12 +***************************************************************/ +#define cl_ext_image_raw10_raw12 1 +#define CL_EXT_IMAGE_RAW10_RAW12_EXTENSION_NAME \ + "cl_ext_image_raw10_raw12" + + +#define CL_EXT_IMAGE_RAW10_RAW12_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_channel_type */ +#define CL_UNSIGNED_INT_RAW10_EXT 0x10E3 +#define CL_UNSIGNED_INT_RAW12_EXT 0x10E4 + +/*************************************************************** +* cl_khr_3d_image_writes +***************************************************************/ +#define cl_khr_3d_image_writes 1 +#define CL_KHR_3D_IMAGE_WRITES_EXTENSION_NAME \ + "cl_khr_3d_image_writes" + + +#define CL_KHR_3D_IMAGE_WRITES_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_async_work_group_copy_fence +***************************************************************/ +#define cl_khr_async_work_group_copy_fence 1 +#define CL_KHR_ASYNC_WORK_GROUP_COPY_FENCE_EXTENSION_NAME \ + "cl_khr_async_work_group_copy_fence" + + +#define CL_KHR_ASYNC_WORK_GROUP_COPY_FENCE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_byte_addressable_store +***************************************************************/ +#define cl_khr_byte_addressable_store 1 +#define CL_KHR_BYTE_ADDRESSABLE_STORE_EXTENSION_NAME \ + "cl_khr_byte_addressable_store" + + +#define CL_KHR_BYTE_ADDRESSABLE_STORE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_device_enqueue_local_arg_types +***************************************************************/ +#define cl_khr_device_enqueue_local_arg_types 1 +#define CL_KHR_DEVICE_ENQUEUE_LOCAL_ARG_TYPES_EXTENSION_NAME \ + "cl_khr_device_enqueue_local_arg_types" + + +#define CL_KHR_DEVICE_ENQUEUE_LOCAL_ARG_TYPES_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_expect_assume +***************************************************************/ +#define cl_khr_expect_assume 1 +#define CL_KHR_EXPECT_ASSUME_EXTENSION_NAME \ + "cl_khr_expect_assume" + + +#define CL_KHR_EXPECT_ASSUME_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_extended_async_copies +***************************************************************/ +#define cl_khr_extended_async_copies 1 +#define CL_KHR_EXTENDED_ASYNC_COPIES_EXTENSION_NAME \ + "cl_khr_extended_async_copies" + + +#define CL_KHR_EXTENDED_ASYNC_COPIES_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_extended_bit_ops +***************************************************************/ +#define cl_khr_extended_bit_ops 1 +#define CL_KHR_EXTENDED_BIT_OPS_EXTENSION_NAME \ + "cl_khr_extended_bit_ops" + + +#define CL_KHR_EXTENDED_BIT_OPS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_external_memory_android_hardware_buffer (beta) +***************************************************************/ +#if defined(CL_ENABLE_BETA_EXTENSIONS) + +#define cl_khr_external_memory_android_hardware_buffer 1 +#define CL_KHR_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME \ + "cl_khr_external_memory_android_hardware_buffer" + + +#define CL_KHR_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_VERSION CL_MAKE_VERSION(0, 9, 2) + +/* cl_external_memory_handle_type_khr */ +#define CL_EXTERNAL_MEMORY_HANDLE_ANDROID_HARDWARE_BUFFER_KHR 0x2070 + +#endif /* defined(CL_ENABLE_BETA_EXTENSIONS) */ + +/*************************************************************** +* cl_khr_global_int32_base_atomics +***************************************************************/ +#define cl_khr_global_int32_base_atomics 1 +#define CL_KHR_GLOBAL_INT32_BASE_ATOMICS_EXTENSION_NAME \ + "cl_khr_global_int32_base_atomics" + + +#define CL_KHR_GLOBAL_INT32_BASE_ATOMICS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_global_int32_extended_atomics +***************************************************************/ +#define cl_khr_global_int32_extended_atomics 1 +#define CL_KHR_GLOBAL_INT32_EXTENDED_ATOMICS_EXTENSION_NAME \ + "cl_khr_global_int32_extended_atomics" + + +#define CL_KHR_GLOBAL_INT32_EXTENDED_ATOMICS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_int64_base_atomics +***************************************************************/ +#define cl_khr_int64_base_atomics 1 +#define CL_KHR_INT64_BASE_ATOMICS_EXTENSION_NAME \ + "cl_khr_int64_base_atomics" + + +#define CL_KHR_INT64_BASE_ATOMICS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_int64_extended_atomics +***************************************************************/ +#define cl_khr_int64_extended_atomics 1 +#define CL_KHR_INT64_EXTENDED_ATOMICS_EXTENSION_NAME \ + "cl_khr_int64_extended_atomics" + + +#define CL_KHR_INT64_EXTENDED_ATOMICS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_kernel_clock +***************************************************************/ +#define cl_khr_kernel_clock 1 +#define CL_KHR_KERNEL_CLOCK_EXTENSION_NAME \ + "cl_khr_kernel_clock" + + +#define CL_KHR_KERNEL_CLOCK_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_KERNEL_CLOCK_CAPABILITIES_KHR 0x1076 + +typedef cl_bitfield cl_device_kernel_clock_capabilities_khr; + +/* cl_device_kernel_clock_capabilities_khr */ +#define CL_DEVICE_KERNEL_CLOCK_SCOPE_DEVICE_KHR (1 << 0) +#define CL_DEVICE_KERNEL_CLOCK_SCOPE_WORK_GROUP_KHR (1 << 1) +#define CL_DEVICE_KERNEL_CLOCK_SCOPE_SUB_GROUP_KHR (1 << 2) + +/*************************************************************** +* cl_khr_local_int32_base_atomics +***************************************************************/ +#define cl_khr_local_int32_base_atomics 1 +#define CL_KHR_LOCAL_INT32_BASE_ATOMICS_EXTENSION_NAME \ + "cl_khr_local_int32_base_atomics" + + +#define CL_KHR_LOCAL_INT32_BASE_ATOMICS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_local_int32_extended_atomics +***************************************************************/ +#define cl_khr_local_int32_extended_atomics 1 +#define CL_KHR_LOCAL_INT32_EXTENDED_ATOMICS_EXTENSION_NAME \ + "cl_khr_local_int32_extended_atomics" + + +#define CL_KHR_LOCAL_INT32_EXTENDED_ATOMICS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_mipmap_image_writes +***************************************************************/ +#define cl_khr_mipmap_image_writes 1 +#define CL_KHR_MIPMAP_IMAGE_WRITES_EXTENSION_NAME \ + "cl_khr_mipmap_image_writes" + + +#define CL_KHR_MIPMAP_IMAGE_WRITES_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_select_fprounding_mode +***************************************************************/ +#define cl_khr_select_fprounding_mode 1 +#define CL_KHR_SELECT_FPROUNDING_MODE_EXTENSION_NAME \ + "cl_khr_select_fprounding_mode" + + +#define CL_KHR_SELECT_FPROUNDING_MODE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_spirv_extended_debug_info +***************************************************************/ +#define cl_khr_spirv_extended_debug_info 1 +#define CL_KHR_SPIRV_EXTENDED_DEBUG_INFO_EXTENSION_NAME \ + "cl_khr_spirv_extended_debug_info" + + +#define CL_KHR_SPIRV_EXTENDED_DEBUG_INFO_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_spirv_linkonce_odr +***************************************************************/ +#define cl_khr_spirv_linkonce_odr 1 +#define CL_KHR_SPIRV_LINKONCE_ODR_EXTENSION_NAME \ + "cl_khr_spirv_linkonce_odr" + + +#define CL_KHR_SPIRV_LINKONCE_ODR_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_spirv_no_integer_wrap_decoration +***************************************************************/ +#define cl_khr_spirv_no_integer_wrap_decoration 1 +#define CL_KHR_SPIRV_NO_INTEGER_WRAP_DECORATION_EXTENSION_NAME \ + "cl_khr_spirv_no_integer_wrap_decoration" + + +#define CL_KHR_SPIRV_NO_INTEGER_WRAP_DECORATION_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_spirv_queries +***************************************************************/ +#define cl_khr_spirv_queries 1 +#define CL_KHR_SPIRV_QUERIES_EXTENSION_NAME \ + "cl_khr_spirv_queries" + + +#define CL_KHR_SPIRV_QUERIES_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_device_info */ +#define CL_DEVICE_SPIRV_EXTENDED_INSTRUCTION_SETS_KHR 0x12B9 +#define CL_DEVICE_SPIRV_EXTENSIONS_KHR 0x12BA +#define CL_DEVICE_SPIRV_CAPABILITIES_KHR 0x12BB + +/*************************************************************** +* cl_khr_srgb_image_writes +***************************************************************/ +#define cl_khr_srgb_image_writes 1 +#define CL_KHR_SRGB_IMAGE_WRITES_EXTENSION_NAME \ + "cl_khr_srgb_image_writes" + + +#define CL_KHR_SRGB_IMAGE_WRITES_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_subgroup_ballot +***************************************************************/ +#define cl_khr_subgroup_ballot 1 +#define CL_KHR_SUBGROUP_BALLOT_EXTENSION_NAME \ + "cl_khr_subgroup_ballot" + + +#define CL_KHR_SUBGROUP_BALLOT_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_subgroup_clustered_reduce +***************************************************************/ +#define cl_khr_subgroup_clustered_reduce 1 +#define CL_KHR_SUBGROUP_CLUSTERED_REDUCE_EXTENSION_NAME \ + "cl_khr_subgroup_clustered_reduce" + + +#define CL_KHR_SUBGROUP_CLUSTERED_REDUCE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_subgroup_extended_types +***************************************************************/ +#define cl_khr_subgroup_extended_types 1 +#define CL_KHR_SUBGROUP_EXTENDED_TYPES_EXTENSION_NAME \ + "cl_khr_subgroup_extended_types" + + +#define CL_KHR_SUBGROUP_EXTENDED_TYPES_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_subgroup_non_uniform_arithmetic +***************************************************************/ +#define cl_khr_subgroup_non_uniform_arithmetic 1 +#define CL_KHR_SUBGROUP_NON_UNIFORM_ARITHMETIC_EXTENSION_NAME \ + "cl_khr_subgroup_non_uniform_arithmetic" + + +#define CL_KHR_SUBGROUP_NON_UNIFORM_ARITHMETIC_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_subgroup_non_uniform_vote +***************************************************************/ +#define cl_khr_subgroup_non_uniform_vote 1 +#define CL_KHR_SUBGROUP_NON_UNIFORM_VOTE_EXTENSION_NAME \ + "cl_khr_subgroup_non_uniform_vote" + + +#define CL_KHR_SUBGROUP_NON_UNIFORM_VOTE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_subgroup_rotate +***************************************************************/ +#define cl_khr_subgroup_rotate 1 +#define CL_KHR_SUBGROUP_ROTATE_EXTENSION_NAME \ + "cl_khr_subgroup_rotate" + + +#define CL_KHR_SUBGROUP_ROTATE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_subgroup_shuffle +***************************************************************/ +#define cl_khr_subgroup_shuffle 1 +#define CL_KHR_SUBGROUP_SHUFFLE_EXTENSION_NAME \ + "cl_khr_subgroup_shuffle" + + +#define CL_KHR_SUBGROUP_SHUFFLE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_subgroup_shuffle_relative +***************************************************************/ +#define cl_khr_subgroup_shuffle_relative 1 +#define CL_KHR_SUBGROUP_SHUFFLE_RELATIVE_EXTENSION_NAME \ + "cl_khr_subgroup_shuffle_relative" + + +#define CL_KHR_SUBGROUP_SHUFFLE_RELATIVE_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_khr_work_group_uniform_arithmetic +***************************************************************/ +#define cl_khr_work_group_uniform_arithmetic 1 +#define CL_KHR_WORK_GROUP_UNIFORM_ARITHMETIC_EXTENSION_NAME \ + "cl_khr_work_group_uniform_arithmetic" + + +#define CL_KHR_WORK_GROUP_UNIFORM_ARITHMETIC_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/*************************************************************** +* cl_ext_buffer_device_address +***************************************************************/ +#define cl_ext_buffer_device_address 1 +#define CL_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME \ + "cl_ext_buffer_device_address" + + +#define CL_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 2) + +typedef cl_ulong cl_mem_device_address_ext; + + +typedef cl_int CL_API_CALL +clSetKernelArgDevicePointerEXT_t( + cl_kernel kernel, + cl_uint arg_index, + cl_mem_device_address_ext arg_value); + +typedef clSetKernelArgDevicePointerEXT_t * +clSetKernelArgDevicePointerEXT_fn CL_API_SUFFIX__VERSION_3_0; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetKernelArgDevicePointerEXT( + cl_kernel kernel, + cl_uint arg_index, + cl_mem_device_address_ext arg_value) CL_API_SUFFIX__VERSION_3_0; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/* cl_mem_properties */ +#define CL_MEM_DEVICE_PRIVATE_ADDRESS_EXT 0x5000 + +/* cl_mem_info */ +#define CL_MEM_DEVICE_ADDRESS_EXT 0x5001 + +/* cl_kernel_exec_info */ +#define CL_KERNEL_EXEC_INFO_DEVICE_PTRS_EXT 0x5002 + +/*************************************************************** +* cl_ext_image_unorm_int_2_101010 +***************************************************************/ +#define cl_ext_image_unorm_int_2_101010 1 +#define CL_EXT_IMAGE_UNORM_INT_2_101010_EXTENSION_NAME \ + "cl_ext_image_unorm_int_2_101010" + + +#define CL_EXT_IMAGE_UNORM_INT_2_101010_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_channel_type */ +#define CL_UNORM_INT_2_101010_EXT 0x10E5 + +/*************************************************************** +* cl_ext_image_unsigned_10x6_12x4_14x2 +***************************************************************/ +#define cl_ext_image_unsigned_10x6_12x4_14x2 1 +#define CL_EXT_IMAGE_UNSIGNED_10X6_12X4_14X2_EXTENSION_NAME \ + "cl_ext_image_unsigned_10x6_12x4_14x2" + + +#define CL_EXT_IMAGE_UNSIGNED_10X6_12X4_14X2_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_channel_type */ +#define CL_UNSIGNED_INT10X6_EXT 0x10E6 +#define CL_UNSIGNED_INT12X4_EXT 0x10E7 +#define CL_UNSIGNED_INT14X2_EXT 0x10E8 +#define CL_UNORM_INT10X6_EXT 0x10E1 +#define CL_UNORM_INT12X4_EXT 0x10E9 +#define CL_UNORM_INT14X2_EXT 0x10EA + +/*************************************************************** +* cl_ext_immutable_memory_objects +***************************************************************/ +#define cl_ext_immutable_memory_objects 1 +#define CL_EXT_IMMUTABLE_MEMORY_OBJECTS_EXTENSION_NAME \ + "cl_ext_immutable_memory_objects" + + +#define CL_EXT_IMMUTABLE_MEMORY_OBJECTS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_mem_flags */ +#define CL_MEM_IMMUTABLE_EXT (1 << 6) + +/*************************************************************** +* cl_img_cancel_command +***************************************************************/ +#define cl_img_cancel_command 1 +#define CL_IMG_CANCEL_COMMAND_EXTENSION_NAME \ + "cl_img_cancel_command" + + +#define CL_IMG_CANCEL_COMMAND_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* Error codes */ +#define CL_CANCELLED_IMG -1126 + + +typedef cl_int CL_API_CALL +clCancelCommandsIMG_t( + const cl_event* event_list, + size_t num_events_in_list); + +typedef clCancelCommandsIMG_t * +clCancelCommandsIMG_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clCancelCommandsIMG( + const cl_event* event_list, + size_t num_events_in_list) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_qcom_perf_hint +***************************************************************/ +#define cl_qcom_perf_hint 1 +#define CL_QCOM_PERF_HINT_EXTENSION_NAME \ + "cl_qcom_perf_hint" + + +#define CL_QCOM_PERF_HINT_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 5) + +typedef cl_uint cl_perf_hint_qcom; + +/* cl_perf_hint_qcom */ +#define CL_PERF_HINT_HIGH_QCOM 0x40C3 +#define CL_PERF_HINT_NORMAL_QCOM 0x40C4 +#define CL_PERF_HINT_LOW_QCOM 0x40C5 + +/* cl_context_info */ +#define CL_CONTEXT_PERF_HINT_QCOM 0x40C2 + + +typedef cl_int CL_API_CALL +clSetPerfHintQCOM_t( + cl_context context, + cl_perf_hint_qcom perf_hint); + +typedef clSetPerfHintQCOM_t * +clSetPerfHintQCOM_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clSetPerfHintQCOM( + cl_context context, + cl_perf_hint_qcom perf_hint) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#ifdef __cplusplus +} +#endif + +#endif /* OPENCL_CL_EXT_H_ */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_ext_intel.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_ext_intel.h new file mode 100644 index 000000000..a7ae87a34 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_ext_intel.h @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2008-2020 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include +#pragma message("The Intel extensions have been moved into cl_ext.h. Please include cl_ext.h directly.") diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_function_types.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_function_types.h new file mode 100644 index 000000000..124f53ba7 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_function_types.h @@ -0,0 +1,1184 @@ +/* + * Copyright (c) 2023 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * OpenCL is a trademark of Apple Inc. used under license by Khronos. + */ + +#ifndef OPENCL_CL_FUNCTION_TYPES_H_ +#define OPENCL_CL_FUNCTION_TYPES_H_ + +#include + +typedef cl_int CL_API_CALL clGetPlatformIDs_t( + cl_uint num_entries, + cl_platform_id* platforms, + cl_uint* num_platforms); + +typedef clGetPlatformIDs_t * +clGetPlatformIDs_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetPlatformInfo_t( + cl_platform_id platform, + cl_platform_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetPlatformInfo_t * +clGetPlatformInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetDeviceIDs_t( + cl_platform_id platform, + cl_device_type device_type, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices); + +typedef clGetDeviceIDs_t * +clGetDeviceIDs_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetDeviceInfo_t( + cl_device_id device, + cl_device_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetDeviceInfo_t * +clGetDeviceInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_context CL_API_CALL clCreateContext_t( + const cl_context_properties* properties, + cl_uint num_devices, + const cl_device_id* devices, + void (CL_CALLBACK* pfn_notify)(const char* errinfo, const void* private_info, size_t cb, void* user_data), + void* user_data, + cl_int* errcode_ret); + +typedef clCreateContext_t * +clCreateContext_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_context CL_API_CALL clCreateContextFromType_t( + const cl_context_properties* properties, + cl_device_type device_type, + void (CL_CALLBACK* pfn_notify)(const char* errinfo, const void* private_info, size_t cb, void* user_data), + void* user_data, + cl_int* errcode_ret); + +typedef clCreateContextFromType_t * +clCreateContextFromType_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clRetainContext_t( + cl_context context); + +typedef clRetainContext_t * +clRetainContext_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clReleaseContext_t( + cl_context context); + +typedef clReleaseContext_t * +clReleaseContext_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetContextInfo_t( + cl_context context, + cl_context_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetContextInfo_t * +clGetContextInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clRetainCommandQueue_t( + cl_command_queue command_queue); + +typedef clRetainCommandQueue_t * +clRetainCommandQueue_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clReleaseCommandQueue_t( + cl_command_queue command_queue); + +typedef clReleaseCommandQueue_t * +clReleaseCommandQueue_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetCommandQueueInfo_t( + cl_command_queue command_queue, + cl_command_queue_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetCommandQueueInfo_t * +clGetCommandQueueInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_mem CL_API_CALL clCreateBuffer_t( + cl_context context, + cl_mem_flags flags, + size_t size, + void* host_ptr, + cl_int* errcode_ret); + +typedef clCreateBuffer_t * +clCreateBuffer_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clRetainMemObject_t( + cl_mem memobj); + +typedef clRetainMemObject_t * +clRetainMemObject_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clReleaseMemObject_t( + cl_mem memobj); + +typedef clReleaseMemObject_t * +clReleaseMemObject_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetSupportedImageFormats_t( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint num_entries, + cl_image_format* image_formats, + cl_uint* num_image_formats); + +typedef clGetSupportedImageFormats_t * +clGetSupportedImageFormats_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetMemObjectInfo_t( + cl_mem memobj, + cl_mem_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetMemObjectInfo_t * +clGetMemObjectInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetImageInfo_t( + cl_mem image, + cl_image_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetImageInfo_t * +clGetImageInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clRetainSampler_t( + cl_sampler sampler); + +typedef clRetainSampler_t * +clRetainSampler_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clReleaseSampler_t( + cl_sampler sampler); + +typedef clReleaseSampler_t * +clReleaseSampler_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetSamplerInfo_t( + cl_sampler sampler, + cl_sampler_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetSamplerInfo_t * +clGetSamplerInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_program CL_API_CALL clCreateProgramWithSource_t( + cl_context context, + cl_uint count, + const char** strings, + const size_t* lengths, + cl_int* errcode_ret); + +typedef clCreateProgramWithSource_t * +clCreateProgramWithSource_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_program CL_API_CALL clCreateProgramWithBinary_t( + cl_context context, + cl_uint num_devices, + const cl_device_id* device_list, + const size_t* lengths, + const unsigned char** binaries, + cl_int* binary_status, + cl_int* errcode_ret); + +typedef clCreateProgramWithBinary_t * +clCreateProgramWithBinary_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clRetainProgram_t( + cl_program program); + +typedef clRetainProgram_t * +clRetainProgram_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clReleaseProgram_t( + cl_program program); + +typedef clReleaseProgram_t * +clReleaseProgram_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clBuildProgram_t( + cl_program program, + cl_uint num_devices, + const cl_device_id* device_list, + const char* options, + void (CL_CALLBACK* pfn_notify)(cl_program program, void* user_data), + void* user_data); + +typedef clBuildProgram_t * +clBuildProgram_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetProgramInfo_t( + cl_program program, + cl_program_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetProgramInfo_t * +clGetProgramInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetProgramBuildInfo_t( + cl_program program, + cl_device_id device, + cl_program_build_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetProgramBuildInfo_t * +clGetProgramBuildInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_kernel CL_API_CALL clCreateKernel_t( + cl_program program, + const char* kernel_name, + cl_int* errcode_ret); + +typedef clCreateKernel_t * +clCreateKernel_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clCreateKernelsInProgram_t( + cl_program program, + cl_uint num_kernels, + cl_kernel* kernels, + cl_uint* num_kernels_ret); + +typedef clCreateKernelsInProgram_t * +clCreateKernelsInProgram_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clRetainKernel_t( + cl_kernel kernel); + +typedef clRetainKernel_t * +clRetainKernel_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clReleaseKernel_t( + cl_kernel kernel); + +typedef clReleaseKernel_t * +clReleaseKernel_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clSetKernelArg_t( + cl_kernel kernel, + cl_uint arg_index, + size_t arg_size, + const void* arg_value); + +typedef clSetKernelArg_t * +clSetKernelArg_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetKernelInfo_t( + cl_kernel kernel, + cl_kernel_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetKernelInfo_t * +clGetKernelInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetKernelWorkGroupInfo_t( + cl_kernel kernel, + cl_device_id device, + cl_kernel_work_group_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetKernelWorkGroupInfo_t * +clGetKernelWorkGroupInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clWaitForEvents_t( + cl_uint num_events, + const cl_event* event_list); + +typedef clWaitForEvents_t * +clWaitForEvents_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetEventInfo_t( + cl_event event, + cl_event_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetEventInfo_t * +clGetEventInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clRetainEvent_t( + cl_event event); + +typedef clRetainEvent_t * +clRetainEvent_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clReleaseEvent_t( + cl_event event); + +typedef clReleaseEvent_t * +clReleaseEvent_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clGetEventProfilingInfo_t( + cl_event event, + cl_profiling_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetEventProfilingInfo_t * +clGetEventProfilingInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clFlush_t( + cl_command_queue command_queue); + +typedef clFlush_t * +clFlush_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clFinish_t( + cl_command_queue command_queue); + +typedef clFinish_t * +clFinish_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueReadBuffer_t( + cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_read, + size_t offset, + size_t size, + void* ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReadBuffer_t * +clEnqueueReadBuffer_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueWriteBuffer_t( + cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_write, + size_t offset, + size_t size, + const void* ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueWriteBuffer_t * +clEnqueueWriteBuffer_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueCopyBuffer_t( + cl_command_queue command_queue, + cl_mem src_buffer, + cl_mem dst_buffer, + size_t src_offset, + size_t dst_offset, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueCopyBuffer_t * +clEnqueueCopyBuffer_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueReadImage_t( + cl_command_queue command_queue, + cl_mem image, + cl_bool blocking_read, + const size_t* origin, + const size_t* region, + size_t row_pitch, + size_t slice_pitch, + void* ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReadImage_t * +clEnqueueReadImage_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueWriteImage_t( + cl_command_queue command_queue, + cl_mem image, + cl_bool blocking_write, + const size_t* origin, + const size_t* region, + size_t input_row_pitch, + size_t input_slice_pitch, + const void* ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueWriteImage_t * +clEnqueueWriteImage_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueCopyImage_t( + cl_command_queue command_queue, + cl_mem src_image, + cl_mem dst_image, + const size_t* src_origin, + const size_t* dst_origin, + const size_t* region, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueCopyImage_t * +clEnqueueCopyImage_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueCopyImageToBuffer_t( + cl_command_queue command_queue, + cl_mem src_image, + cl_mem dst_buffer, + const size_t* src_origin, + const size_t* region, + size_t dst_offset, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueCopyImageToBuffer_t * +clEnqueueCopyImageToBuffer_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueCopyBufferToImage_t( + cl_command_queue command_queue, + cl_mem src_buffer, + cl_mem dst_image, + size_t src_offset, + const size_t* dst_origin, + const size_t* region, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueCopyBufferToImage_t * +clEnqueueCopyBufferToImage_fn CL_API_SUFFIX__VERSION_1_0; + +typedef void* CL_API_CALL clEnqueueMapBuffer_t( + cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_map, + cl_map_flags map_flags, + size_t offset, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event, + cl_int* errcode_ret); + +typedef clEnqueueMapBuffer_t * +clEnqueueMapBuffer_fn CL_API_SUFFIX__VERSION_1_0; + +typedef void* CL_API_CALL clEnqueueMapImage_t( + cl_command_queue command_queue, + cl_mem image, + cl_bool blocking_map, + cl_map_flags map_flags, + const size_t* origin, + const size_t* region, + size_t* image_row_pitch, + size_t* image_slice_pitch, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event, + cl_int* errcode_ret); + +typedef clEnqueueMapImage_t * +clEnqueueMapImage_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueUnmapMemObject_t( + cl_command_queue command_queue, + cl_mem memobj, + void* mapped_ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueUnmapMemObject_t * +clEnqueueUnmapMemObject_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueNDRangeKernel_t( + cl_command_queue command_queue, + cl_kernel kernel, + cl_uint work_dim, + const size_t* global_work_offset, + const size_t* global_work_size, + const size_t* local_work_size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueNDRangeKernel_t * +clEnqueueNDRangeKernel_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clEnqueueNativeKernel_t( + cl_command_queue command_queue, + void (CL_CALLBACK* user_func)(void*), + void* args, + size_t cb_args, + cl_uint num_mem_objects, + const cl_mem* mem_list, + const void** args_mem_loc, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueNativeKernel_t * +clEnqueueNativeKernel_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL clSetCommandQueueProperty_t( + cl_command_queue command_queue, + cl_command_queue_properties properties, + cl_bool enable, + cl_command_queue_properties* old_properties); + +typedef clSetCommandQueueProperty_t * +clSetCommandQueueProperty_fn CL_API_SUFFIX__VERSION_1_0_DEPRECATED; + +typedef cl_mem CL_API_CALL clCreateImage2D_t( + cl_context context, + cl_mem_flags flags, + const cl_image_format* image_format, + size_t image_width, + size_t image_height, + size_t image_row_pitch, + void* host_ptr, + cl_int* errcode_ret); + +typedef clCreateImage2D_t * +clCreateImage2D_fn CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +typedef cl_mem CL_API_CALL clCreateImage3D_t( + cl_context context, + cl_mem_flags flags, + const cl_image_format* image_format, + size_t image_width, + size_t image_height, + size_t image_depth, + size_t image_row_pitch, + size_t image_slice_pitch, + void* host_ptr, + cl_int* errcode_ret); + +typedef clCreateImage3D_t * +clCreateImage3D_fn CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +typedef cl_int CL_API_CALL clEnqueueMarker_t( + cl_command_queue command_queue, + cl_event* event); + +typedef clEnqueueMarker_t * +clEnqueueMarker_fn CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +typedef cl_int CL_API_CALL clEnqueueWaitForEvents_t( + cl_command_queue command_queue, + cl_uint num_events, + const cl_event* event_list); + +typedef clEnqueueWaitForEvents_t * +clEnqueueWaitForEvents_fn CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +typedef cl_int CL_API_CALL clEnqueueBarrier_t( + cl_command_queue command_queue); + +typedef clEnqueueBarrier_t * +clEnqueueBarrier_fn CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +typedef cl_int CL_API_CALL clUnloadCompiler_t( + void ); + +typedef clUnloadCompiler_t * +clUnloadCompiler_fn CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +typedef void* CL_API_CALL clGetExtensionFunctionAddress_t( + const char* func_name); + +typedef clGetExtensionFunctionAddress_t * +clGetExtensionFunctionAddress_fn CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +typedef cl_command_queue CL_API_CALL clCreateCommandQueue_t( + cl_context context, + cl_device_id device, + cl_command_queue_properties properties, + cl_int* errcode_ret); + +typedef clCreateCommandQueue_t * +clCreateCommandQueue_fn CL_API_SUFFIX__VERSION_1_2_DEPRECATED; + +typedef cl_sampler CL_API_CALL clCreateSampler_t( + cl_context context, + cl_bool normalized_coords, + cl_addressing_mode addressing_mode, + cl_filter_mode filter_mode, + cl_int* errcode_ret); + +typedef clCreateSampler_t * +clCreateSampler_fn CL_API_SUFFIX__VERSION_1_2_DEPRECATED; + +typedef cl_int CL_API_CALL clEnqueueTask_t( + cl_command_queue command_queue, + cl_kernel kernel, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueTask_t * +clEnqueueTask_fn CL_API_SUFFIX__VERSION_1_2_DEPRECATED; + +#ifdef CL_VERSION_1_1 + +typedef cl_mem CL_API_CALL clCreateSubBuffer_t( + cl_mem buffer, + cl_mem_flags flags, + cl_buffer_create_type buffer_create_type, + const void* buffer_create_info, + cl_int* errcode_ret); + +typedef clCreateSubBuffer_t * +clCreateSubBuffer_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL clSetMemObjectDestructorCallback_t( + cl_mem memobj, + void (CL_CALLBACK* pfn_notify)(cl_mem memobj, void* user_data), + void* user_data); + +typedef clSetMemObjectDestructorCallback_t * +clSetMemObjectDestructorCallback_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_event CL_API_CALL clCreateUserEvent_t( + cl_context context, + cl_int* errcode_ret); + +typedef clCreateUserEvent_t * +clCreateUserEvent_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL clSetUserEventStatus_t( + cl_event event, + cl_int execution_status); + +typedef clSetUserEventStatus_t * +clSetUserEventStatus_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL clSetEventCallback_t( + cl_event event, + cl_int command_exec_callback_type, + void (CL_CALLBACK* pfn_notify)(cl_event event, cl_int event_command_status, void *user_data), + void* user_data); + +typedef clSetEventCallback_t * +clSetEventCallback_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL clEnqueueReadBufferRect_t( + cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_read, + const size_t* buffer_origin, + const size_t* host_origin, + const size_t* region, + size_t buffer_row_pitch, + size_t buffer_slice_pitch, + size_t host_row_pitch, + size_t host_slice_pitch, + void* ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReadBufferRect_t * +clEnqueueReadBufferRect_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL clEnqueueWriteBufferRect_t( + cl_command_queue command_queue, + cl_mem buffer, + cl_bool blocking_write, + const size_t* buffer_origin, + const size_t* host_origin, + const size_t* region, + size_t buffer_row_pitch, + size_t buffer_slice_pitch, + size_t host_row_pitch, + size_t host_slice_pitch, + const void* ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueWriteBufferRect_t * +clEnqueueWriteBufferRect_fn CL_API_SUFFIX__VERSION_1_1; + +typedef cl_int CL_API_CALL clEnqueueCopyBufferRect_t( + cl_command_queue command_queue, + cl_mem src_buffer, + cl_mem dst_buffer, + const size_t* src_origin, + const size_t* dst_origin, + const size_t* region, + size_t src_row_pitch, + size_t src_slice_pitch, + size_t dst_row_pitch, + size_t dst_slice_pitch, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueCopyBufferRect_t * +clEnqueueCopyBufferRect_fn CL_API_SUFFIX__VERSION_1_1; + +#endif /* CL_VERSION_1_1 */ + +#ifdef CL_VERSION_1_2 + +typedef cl_int CL_API_CALL clCreateSubDevices_t( + cl_device_id in_device, + const cl_device_partition_property* properties, + cl_uint num_devices, + cl_device_id* out_devices, + cl_uint* num_devices_ret); + +typedef clCreateSubDevices_t * +clCreateSubDevices_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clRetainDevice_t( + cl_device_id device); + +typedef clRetainDevice_t * +clRetainDevice_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clReleaseDevice_t( + cl_device_id device); + +typedef clReleaseDevice_t * +clReleaseDevice_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_mem CL_API_CALL clCreateImage_t( + cl_context context, + cl_mem_flags flags, + const cl_image_format* image_format, + const cl_image_desc* image_desc, + void* host_ptr, + cl_int* errcode_ret); + +typedef clCreateImage_t * +clCreateImage_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_program CL_API_CALL clCreateProgramWithBuiltInKernels_t( + cl_context context, + cl_uint num_devices, + const cl_device_id* device_list, + const char* kernel_names, + cl_int* errcode_ret); + +typedef clCreateProgramWithBuiltInKernels_t * +clCreateProgramWithBuiltInKernels_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clCompileProgram_t( + cl_program program, + cl_uint num_devices, + const cl_device_id* device_list, + const char* options, + cl_uint num_input_headers, + const cl_program* input_headers, + const char** header_include_names, + void (CL_CALLBACK* pfn_notify)(cl_program program, void* user_data), + void* user_data); + +typedef clCompileProgram_t * +clCompileProgram_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_program CL_API_CALL clLinkProgram_t( + cl_context context, + cl_uint num_devices, + const cl_device_id* device_list, + const char* options, + cl_uint num_input_programs, + const cl_program* input_programs, + void (CL_CALLBACK* pfn_notify)(cl_program program, void* user_data), + void* user_data, + cl_int* errcode_ret); + +typedef clLinkProgram_t * +clLinkProgram_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clUnloadPlatformCompiler_t( + cl_platform_id platform); + +typedef clUnloadPlatformCompiler_t * +clUnloadPlatformCompiler_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clGetKernelArgInfo_t( + cl_kernel kernel, + cl_uint arg_index, + cl_kernel_arg_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetKernelArgInfo_t * +clGetKernelArgInfo_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clEnqueueFillBuffer_t( + cl_command_queue command_queue, + cl_mem buffer, + const void* pattern, + size_t pattern_size, + size_t offset, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueFillBuffer_t * +clEnqueueFillBuffer_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clEnqueueFillImage_t( + cl_command_queue command_queue, + cl_mem image, + const void* fill_color, + const size_t* origin, + const size_t* region, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueFillImage_t * +clEnqueueFillImage_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clEnqueueMigrateMemObjects_t( + cl_command_queue command_queue, + cl_uint num_mem_objects, + const cl_mem* mem_objects, + cl_mem_migration_flags flags, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueMigrateMemObjects_t * +clEnqueueMigrateMemObjects_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clEnqueueMarkerWithWaitList_t( + cl_command_queue command_queue, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueMarkerWithWaitList_t * +clEnqueueMarkerWithWaitList_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL clEnqueueBarrierWithWaitList_t( + cl_command_queue command_queue, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueBarrierWithWaitList_t * +clEnqueueBarrierWithWaitList_fn CL_API_SUFFIX__VERSION_1_2; + +typedef void* CL_API_CALL clGetExtensionFunctionAddressForPlatform_t( + cl_platform_id platform, + const char* func_name); + +typedef clGetExtensionFunctionAddressForPlatform_t * +clGetExtensionFunctionAddressForPlatform_fn CL_API_SUFFIX__VERSION_1_2; + +#endif /* CL_VERSION_1_2 */ + +#ifdef CL_VERSION_2_0 + +typedef cl_command_queue CL_API_CALL clCreateCommandQueueWithProperties_t( + cl_context context, + cl_device_id device, + const cl_queue_properties* properties, + cl_int* errcode_ret); + +typedef clCreateCommandQueueWithProperties_t * +clCreateCommandQueueWithProperties_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_mem CL_API_CALL clCreatePipe_t( + cl_context context, + cl_mem_flags flags, + cl_uint pipe_packet_size, + cl_uint pipe_max_packets, + const cl_pipe_properties* properties, + cl_int* errcode_ret); + +typedef clCreatePipe_t * +clCreatePipe_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_int CL_API_CALL clGetPipeInfo_t( + cl_mem pipe, + cl_pipe_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetPipeInfo_t * +clGetPipeInfo_fn CL_API_SUFFIX__VERSION_2_0; + +typedef void* CL_API_CALL clSVMAlloc_t( + cl_context context, + cl_svm_mem_flags flags, + size_t size, + cl_uint alignment); + +typedef clSVMAlloc_t * +clSVMAlloc_fn CL_API_SUFFIX__VERSION_2_0; + +typedef void CL_API_CALL clSVMFree_t( + cl_context context, + void* svm_pointer); + +typedef clSVMFree_t * +clSVMFree_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_sampler CL_API_CALL clCreateSamplerWithProperties_t( + cl_context context, + const cl_sampler_properties* sampler_properties, + cl_int* errcode_ret); + +typedef clCreateSamplerWithProperties_t * +clCreateSamplerWithProperties_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_int CL_API_CALL clSetKernelArgSVMPointer_t( + cl_kernel kernel, + cl_uint arg_index, + const void* arg_value); + +typedef clSetKernelArgSVMPointer_t * +clSetKernelArgSVMPointer_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_int CL_API_CALL clSetKernelExecInfo_t( + cl_kernel kernel, + cl_kernel_exec_info param_name, + size_t param_value_size, + const void* param_value); + +typedef clSetKernelExecInfo_t * +clSetKernelExecInfo_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_int CL_API_CALL clEnqueueSVMFree_t( + cl_command_queue command_queue, + cl_uint num_svm_pointers, + void* svm_pointers[], + void (CL_CALLBACK* pfn_free_func)(cl_command_queue queue, cl_uint num_svm_pointers, void* svm_pointers[], void* user_data), + void* user_data, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMFree_t * +clEnqueueSVMFree_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_int CL_API_CALL clEnqueueSVMMemcpy_t( + cl_command_queue command_queue, + cl_bool blocking_copy, + void* dst_ptr, + const void* src_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMMemcpy_t * +clEnqueueSVMMemcpy_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_int CL_API_CALL clEnqueueSVMMemFill_t( + cl_command_queue command_queue, + void* svm_ptr, + const void* pattern, + size_t pattern_size, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMMemFill_t * +clEnqueueSVMMemFill_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_int CL_API_CALL clEnqueueSVMMap_t( + cl_command_queue command_queue, + cl_bool blocking_map, + cl_map_flags flags, + void* svm_ptr, + size_t size, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMMap_t * +clEnqueueSVMMap_fn CL_API_SUFFIX__VERSION_2_0; + +typedef cl_int CL_API_CALL clEnqueueSVMUnmap_t( + cl_command_queue command_queue, + void* svm_ptr, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMUnmap_t * +clEnqueueSVMUnmap_fn CL_API_SUFFIX__VERSION_2_0; + +#endif /* CL_VERSION_2_0 */ + +#ifdef CL_VERSION_2_1 + +typedef cl_int CL_API_CALL clSetDefaultDeviceCommandQueue_t( + cl_context context, + cl_device_id device, + cl_command_queue command_queue); + +typedef clSetDefaultDeviceCommandQueue_t * +clSetDefaultDeviceCommandQueue_fn CL_API_SUFFIX__VERSION_2_1; + +typedef cl_int CL_API_CALL clGetDeviceAndHostTimer_t( + cl_device_id device, + cl_ulong* device_timestamp, + cl_ulong* host_timestamp); + +typedef clGetDeviceAndHostTimer_t * +clGetDeviceAndHostTimer_fn CL_API_SUFFIX__VERSION_2_1; + +typedef cl_int CL_API_CALL clGetHostTimer_t( + cl_device_id device, + cl_ulong* host_timestamp); + +typedef clGetHostTimer_t * +clGetHostTimer_fn CL_API_SUFFIX__VERSION_2_1; + +typedef cl_program CL_API_CALL clCreateProgramWithIL_t( + cl_context context, + const void* il, + size_t length, + cl_int* errcode_ret); + +typedef clCreateProgramWithIL_t * +clCreateProgramWithIL_fn CL_API_SUFFIX__VERSION_2_1; + +typedef cl_kernel CL_API_CALL clCloneKernel_t( + cl_kernel source_kernel, + cl_int* errcode_ret); + +typedef clCloneKernel_t * +clCloneKernel_fn CL_API_SUFFIX__VERSION_2_1; + +typedef cl_int CL_API_CALL clGetKernelSubGroupInfo_t( + cl_kernel kernel, + cl_device_id device, + cl_kernel_sub_group_info param_name, + size_t input_value_size, + const void* input_value, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetKernelSubGroupInfo_t * +clGetKernelSubGroupInfo_fn CL_API_SUFFIX__VERSION_2_1; + +typedef cl_int CL_API_CALL clEnqueueSVMMigrateMem_t( + cl_command_queue command_queue, + cl_uint num_svm_pointers, + const void** svm_pointers, + const size_t* sizes, + cl_mem_migration_flags flags, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueSVMMigrateMem_t * +clEnqueueSVMMigrateMem_fn CL_API_SUFFIX__VERSION_2_1; + +#endif /* CL_VERSION_2_1 */ + +#ifdef CL_VERSION_2_2 + +typedef cl_int CL_API_CALL clSetProgramSpecializationConstant_t( + cl_program program, + cl_uint spec_id, + size_t spec_size, + const void* spec_value); + +typedef clSetProgramSpecializationConstant_t * +clSetProgramSpecializationConstant_fn CL_API_SUFFIX__VERSION_2_2; + +typedef cl_int CL_API_CALL clSetProgramReleaseCallback_t( + cl_program program, + void (CL_CALLBACK* pfn_notify)(cl_program program, void* user_data), + void* user_data); + +typedef clSetProgramReleaseCallback_t * +clSetProgramReleaseCallback_fn CL_API_SUFFIX__VERSION_2_2_DEPRECATED; + +#endif /* CL_VERSION_2_2 */ + +#ifdef CL_VERSION_3_0 + +typedef cl_int CL_API_CALL clSetContextDestructorCallback_t( + cl_context context, + void (CL_CALLBACK* pfn_notify)(cl_context context, void* user_data), + void* user_data); + +typedef clSetContextDestructorCallback_t * +clSetContextDestructorCallback_fn CL_API_SUFFIX__VERSION_3_0; + +typedef cl_mem CL_API_CALL clCreateBufferWithProperties_t( + cl_context context, + const cl_mem_properties* properties, + cl_mem_flags flags, + size_t size, + void* host_ptr, + cl_int* errcode_ret); + +typedef clCreateBufferWithProperties_t * +clCreateBufferWithProperties_fn CL_API_SUFFIX__VERSION_3_0; + +typedef cl_mem CL_API_CALL clCreateImageWithProperties_t( + cl_context context, + const cl_mem_properties* properties, + cl_mem_flags flags, + const cl_image_format* image_format, + const cl_image_desc* image_desc, + void* host_ptr, + cl_int* errcode_ret); + +typedef clCreateImageWithProperties_t * +clCreateImageWithProperties_fn CL_API_SUFFIX__VERSION_3_0; + +#endif /* CL_VERSION_3_0 */ + +#endif /* OPENCL_CL_FUNCTION_TYPES_H_ */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_gl.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_gl.h new file mode 100644 index 000000000..552560f71 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_gl.h @@ -0,0 +1,421 @@ +/******************************************************************************* + * Copyright (c) 2008-2023 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef OPENCL_CL_GL_H_ +#define OPENCL_CL_GL_H_ + +/* +** This header is generated from the Khronos OpenCL XML API Registry. +*/ + +#include + +/* CL_NO_PROTOTYPES implies CL_NO_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_PROTOTYPES) && !defined(CL_NO_EXTENSION_PROTOTYPES) +#define CL_NO_EXTENSION_PROTOTYPES +#endif + +/* CL_NO_EXTENSION_PROTOTYPES implies + CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES and + CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************** +* cl_khr_gl_sharing +***************************************************************/ +#define cl_khr_gl_sharing 1 +#define CL_KHR_GL_SHARING_EXTENSION_NAME \ + "cl_khr_gl_sharing" + + +#define CL_KHR_GL_SHARING_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef int cl_GLint; +typedef unsigned int cl_GLenum; +typedef unsigned int cl_GLuint; + +typedef cl_uint cl_gl_context_info; + +/* Error codes */ +#define CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR -1000 + +/* cl_gl_context_info */ +#define CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006 +#define CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007 + +/* Additional cl_context_properties */ +#define CL_GL_CONTEXT_KHR 0x2008 +#define CL_EGL_DISPLAY_KHR 0x2009 +#define CL_GLX_DISPLAY_KHR 0x200A +#define CL_WGL_HDC_KHR 0x200B +#define CL_CGL_SHAREGROUP_KHR 0x200C + +typedef cl_uint cl_gl_object_type; +typedef cl_uint cl_gl_texture_info; +typedef cl_uint cl_gl_platform_info; + +/* cl_gl_object_type */ +#define CL_GL_OBJECT_BUFFER 0x2000 +#define CL_GL_OBJECT_TEXTURE2D 0x2001 +#define CL_GL_OBJECT_TEXTURE3D 0x2002 +#define CL_GL_OBJECT_RENDERBUFFER 0x2003 + +#if defined(CL_VERSION_1_2) +/* cl_gl_object_type */ +#define CL_GL_OBJECT_TEXTURE2D_ARRAY 0x200E +#define CL_GL_OBJECT_TEXTURE1D 0x200F +#define CL_GL_OBJECT_TEXTURE1D_ARRAY 0x2010 +#define CL_GL_OBJECT_TEXTURE_BUFFER 0x2011 + +#endif /* defined(CL_VERSION_1_2) */ + +/* cl_gl_texture_info */ +#define CL_GL_TEXTURE_TARGET 0x2004 +#define CL_GL_MIPMAP_LEVEL 0x2005 + + +typedef cl_int CL_API_CALL +clGetGLContextInfoKHR_t( + const cl_context_properties* properties, + cl_gl_context_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetGLContextInfoKHR_t * +clGetGLContextInfoKHR_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_mem CL_API_CALL +clCreateFromGLBuffer_t( + cl_context context, + cl_mem_flags flags, + cl_GLuint bufobj, + cl_int* errcode_ret); + +typedef clCreateFromGLBuffer_t * +clCreateFromGLBuffer_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetGLContextInfoKHR( + const cl_context_properties* properties, + cl_gl_context_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromGLBuffer( + cl_context context, + cl_mem_flags flags, + cl_GLuint bufobj, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#if defined(CL_VERSION_1_2) + +typedef cl_mem CL_API_CALL +clCreateFromGLTexture_t( + cl_context context, + cl_mem_flags flags, + cl_GLenum target, + cl_GLint miplevel, + cl_GLuint texture, + cl_int* errcode_ret); + +typedef clCreateFromGLTexture_t * +clCreateFromGLTexture_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromGLTexture( + cl_context context, + cl_mem_flags flags, + cl_GLenum target, + cl_GLint miplevel, + cl_GLuint texture, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#endif /* defined(CL_VERSION_1_2) */ + + +typedef cl_mem CL_API_CALL +clCreateFromGLRenderbuffer_t( + cl_context context, + cl_mem_flags flags, + cl_GLuint renderbuffer, + cl_int* errcode_ret); + +typedef clCreateFromGLRenderbuffer_t * +clCreateFromGLRenderbuffer_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL +clGetGLObjectInfo_t( + cl_mem memobj, + cl_gl_object_type* gl_object_type, + cl_GLuint* gl_object_name); + +typedef clGetGLObjectInfo_t * +clGetGLObjectInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL +clGetGLTextureInfo_t( + cl_mem memobj, + cl_gl_texture_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetGLTextureInfo_t * +clGetGLTextureInfo_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL +clEnqueueAcquireGLObjects_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueAcquireGLObjects_t * +clEnqueueAcquireGLObjects_fn CL_API_SUFFIX__VERSION_1_0; + +typedef cl_int CL_API_CALL +clEnqueueReleaseGLObjects_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReleaseGLObjects_t * +clEnqueueReleaseGLObjects_fn CL_API_SUFFIX__VERSION_1_0; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromGLRenderbuffer( + cl_context context, + cl_mem_flags flags, + cl_GLuint renderbuffer, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetGLObjectInfo( + cl_mem memobj, + cl_gl_object_type* gl_object_type, + cl_GLuint* gl_object_name) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetGLTextureInfo( + cl_mem memobj, + cl_gl_texture_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireGLObjects( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_0; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseGLObjects( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_0; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/* OpenCL 1.0 APIs that were deprecated in OpenCL 1.2 */ + +typedef cl_mem CL_API_CALL +clCreateFromGLTexture2D_t( + cl_context context, + cl_mem_flags flags, + cl_GLenum target, + cl_GLint miplevel, + cl_GLuint texture, + cl_int* errcode_ret); + +typedef clCreateFromGLTexture2D_t * +clCreateFromGLTexture2D_fn CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +typedef cl_mem CL_API_CALL +clCreateFromGLTexture3D_t( + cl_context context, + cl_mem_flags flags, + cl_GLenum target, + cl_GLint miplevel, + cl_GLuint texture, + cl_int* errcode_ret); + +typedef clCreateFromGLTexture3D_t * +clCreateFromGLTexture3D_fn CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromGLTexture2D( + cl_context context, + cl_mem_flags flags, + cl_GLenum target, + cl_GLint miplevel, + cl_GLuint texture, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromGLTexture3D( + cl_context context, + cl_mem_flags flags, + cl_GLenum target, + cl_GLint miplevel, + cl_GLuint texture, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_1_DEPRECATED; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_gl_event +***************************************************************/ +#define cl_khr_gl_event 1 +#define CL_KHR_GL_EVENT_EXTENSION_NAME \ + "cl_khr_gl_event" + + +#define CL_KHR_GL_EVENT_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef struct __GLsync * cl_GLsync; + +/* cl_command_type */ +#define CL_COMMAND_GL_FENCE_SYNC_OBJECT_KHR 0x200D + + +typedef cl_event CL_API_CALL +clCreateEventFromGLsyncKHR_t( + cl_context context, + cl_GLsync sync, + cl_int* errcode_ret); + +typedef clCreateEventFromGLsyncKHR_t * +clCreateEventFromGLsyncKHR_fn CL_API_SUFFIX__VERSION_1_1; + +#if !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_event CL_API_CALL +clCreateEventFromGLsyncKHR( + cl_context context, + cl_GLsync sync, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_1; + +#endif /* !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_khr_gl_depth_images +***************************************************************/ +#define cl_khr_gl_depth_images 1 +#define CL_KHR_GL_DEPTH_IMAGES_EXTENSION_NAME \ + "cl_khr_gl_depth_images" + + +#define CL_KHR_GL_DEPTH_IMAGES_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_channel_order */ +#define CL_DEPTH_STENCIL 0x10BE + +/* cl_channel_type */ +#define CL_UNORM_INT24 0x10DF + +/*************************************************************** +* cl_khr_gl_msaa_sharing +***************************************************************/ +#define cl_khr_gl_msaa_sharing 1 +#define CL_KHR_GL_MSAA_SHARING_EXTENSION_NAME \ + "cl_khr_gl_msaa_sharing" + + +#define CL_KHR_GL_MSAA_SHARING_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +/* cl_gl_texture_info */ +#define CL_GL_NUM_SAMPLES 0x2012 + +/*************************************************************** +* cl_intel_sharing_format_query_gl +***************************************************************/ +#define cl_intel_sharing_format_query_gl 1 +#define CL_INTEL_SHARING_FORMAT_QUERY_GL_EXTENSION_NAME \ + "cl_intel_sharing_format_query_gl" + + +#define CL_INTEL_SHARING_FORMAT_QUERY_GL_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* when cl_khr_gl_sharing is supported */ + +typedef cl_int CL_API_CALL +clGetSupportedGLTextureFormatsINTEL_t( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint num_entries, + cl_GLenum* gl_formats, + cl_uint* num_texture_formats); + +typedef clGetSupportedGLTextureFormatsINTEL_t * +clGetSupportedGLTextureFormatsINTEL_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSupportedGLTextureFormatsINTEL( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint num_entries, + cl_GLenum* gl_formats, + cl_uint* num_texture_formats) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#ifdef __cplusplus +} +#endif + +#endif /* OPENCL_CL_GL_H_ */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_gl_ext.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_gl_ext.h new file mode 100644 index 000000000..b5da13eb6 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_gl_ext.h @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2008-2021 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#include +#pragma message("The extensions in cl_gl_ext.h have been moved into cl_gl.h. Please include cl_gl.h directly.") diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_half.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_half.h new file mode 100644 index 000000000..ecc422332 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_half.h @@ -0,0 +1,440 @@ +/******************************************************************************* + * Copyright (c) 2019-2020 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +/** + * This is a header-only utility library that provides OpenCL host code with + * routines for converting to/from cl_half values. + * + * Example usage: + * + * #include + * ... + * cl_half h = cl_half_from_float(0.5f, CL_HALF_RTE); + * cl_float f = cl_half_to_float(h); + */ + +#ifndef OPENCL_CL_HALF_H +#define OPENCL_CL_HALF_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Rounding mode used when converting to cl_half. + */ +typedef enum +{ + CL_HALF_RTE, // round to nearest even + CL_HALF_RTZ, // round towards zero + CL_HALF_RTP, // round towards positive infinity + CL_HALF_RTN, // round towards negative infinity +} cl_half_rounding_mode; + + +/* Private utility macros. */ +#define CL_HALF_EXP_MASK 0x7C00 +#define CL_HALF_MAX_FINITE_MAG 0x7BFF + + +/* + * Utility to deal with values that overflow when converting to half precision. + */ +static inline cl_half cl_half_handle_overflow(cl_half_rounding_mode rounding_mode, + uint16_t sign) +{ + if (rounding_mode == CL_HALF_RTZ) + { + // Round overflow towards zero -> largest finite number (preserving sign) + return (sign << 15) | CL_HALF_MAX_FINITE_MAG; + } + else if (rounding_mode == CL_HALF_RTP && sign) + { + // Round negative overflow towards positive infinity -> most negative finite number + return (1 << 15) | CL_HALF_MAX_FINITE_MAG; + } + else if (rounding_mode == CL_HALF_RTN && !sign) + { + // Round positive overflow towards negative infinity -> largest finite number + return CL_HALF_MAX_FINITE_MAG; + } + + // Overflow to infinity + return (sign << 15) | CL_HALF_EXP_MASK; +} + +/* + * Utility to deal with values that underflow when converting to half precision. + */ +static inline cl_half cl_half_handle_underflow(cl_half_rounding_mode rounding_mode, + uint16_t sign) +{ + if (rounding_mode == CL_HALF_RTP && !sign) + { + // Round underflow towards positive infinity -> smallest positive value + return (sign << 15) | 1; + } + else if (rounding_mode == CL_HALF_RTN && sign) + { + // Round underflow towards negative infinity -> largest negative value + return (sign << 15) | 1; + } + + // Flush to zero + return (sign << 15); +} + + +/** + * Convert a cl_float to a cl_half. + */ +static inline cl_half cl_half_from_float(cl_float f, cl_half_rounding_mode rounding_mode) +{ + // Type-punning to get direct access to underlying bits + union + { + cl_float f; + uint32_t i; + } f32; + f32.f = f; + + // Extract sign bit + uint16_t sign = f32.i >> 31; + + // Extract FP32 exponent and mantissa + uint32_t f_exp = (f32.i >> (CL_FLT_MANT_DIG - 1)) & 0xFF; + uint32_t f_mant = f32.i & ((1 << (CL_FLT_MANT_DIG - 1)) - 1); + + // Remove FP32 exponent bias + int32_t exp = f_exp - CL_FLT_MAX_EXP + 1; + + // Add FP16 exponent bias + uint16_t h_exp = (uint16_t)(exp + CL_HALF_MAX_EXP - 1); + + // Position of the bit that will become the FP16 mantissa LSB + uint32_t lsb_pos = CL_FLT_MANT_DIG - CL_HALF_MANT_DIG; + + // Check for NaN / infinity + if (f_exp == 0xFF) + { + if (f_mant) + { + // NaN -> propagate mantissa and silence it + uint16_t h_mant = (uint16_t)(f_mant >> lsb_pos); + h_mant |= 0x200; + return (sign << 15) | CL_HALF_EXP_MASK | h_mant; + } + else + { + // Infinity -> zero mantissa + return (sign << 15) | CL_HALF_EXP_MASK; + } + } + + // Check for zero + if (!f_exp && !f_mant) + { + return (sign << 15); + } + + // Check for overflow + if (exp >= CL_HALF_MAX_EXP) + { + return cl_half_handle_overflow(rounding_mode, sign); + } + + // Check for underflow + if (exp < (CL_HALF_MIN_EXP - CL_HALF_MANT_DIG - 1)) + { + return cl_half_handle_underflow(rounding_mode, sign); + } + + // Check for value that will become denormal + if (exp < -14) + { + // Denormal -> include the implicit 1 from the FP32 mantissa + h_exp = 0; + f_mant |= 1 << (CL_FLT_MANT_DIG - 1); + + // Mantissa shift amount depends on exponent + lsb_pos = -exp + (CL_FLT_MANT_DIG - 25); + } + + // Generate FP16 mantissa by shifting FP32 mantissa + uint16_t h_mant = (uint16_t)(f_mant >> lsb_pos); + + // Check whether we need to round + uint32_t halfway = 1 << (lsb_pos - 1); + uint32_t mask = (halfway << 1) - 1; + switch (rounding_mode) + { + case CL_HALF_RTE: + if ((f_mant & mask) > halfway) + { + // More than halfway -> round up + h_mant += 1; + } + else if ((f_mant & mask) == halfway) + { + // Exactly halfway -> round to nearest even + if (h_mant & 0x1) + h_mant += 1; + } + break; + case CL_HALF_RTZ: + // Mantissa has already been truncated -> do nothing + break; + case CL_HALF_RTP: + if ((f_mant & mask) && !sign) + { + // Round positive numbers up + h_mant += 1; + } + break; + case CL_HALF_RTN: + if ((f_mant & mask) && sign) + { + // Round negative numbers down + h_mant += 1; + } + break; + } + + // Check for mantissa overflow + if (h_mant & 0x400) + { + h_exp += 1; + h_mant = 0; + } + + return (sign << 15) | (h_exp << 10) | h_mant; +} + + +/** + * Convert a cl_double to a cl_half. + */ +static inline cl_half cl_half_from_double(cl_double d, cl_half_rounding_mode rounding_mode) +{ + // Type-punning to get direct access to underlying bits + union + { + cl_double d; + uint64_t i; + } f64; + f64.d = d; + + // Extract sign bit + uint16_t sign = f64.i >> 63; + + // Extract FP64 exponent and mantissa + uint64_t d_exp = (f64.i >> (CL_DBL_MANT_DIG - 1)) & 0x7FF; + uint64_t d_mant = f64.i & (((uint64_t)1 << (CL_DBL_MANT_DIG - 1)) - 1); + + // Remove FP64 exponent bias + int64_t exp = d_exp - CL_DBL_MAX_EXP + 1; + + // Add FP16 exponent bias + uint16_t h_exp = (uint16_t)(exp + CL_HALF_MAX_EXP - 1); + + // Position of the bit that will become the FP16 mantissa LSB + uint32_t lsb_pos = CL_DBL_MANT_DIG - CL_HALF_MANT_DIG; + + // Check for NaN / infinity + if (d_exp == 0x7FF) + { + if (d_mant) + { + // NaN -> propagate mantissa and silence it + uint16_t h_mant = (uint16_t)(d_mant >> lsb_pos); + h_mant |= 0x200; + return (sign << 15) | CL_HALF_EXP_MASK | h_mant; + } + else + { + // Infinity -> zero mantissa + return (sign << 15) | CL_HALF_EXP_MASK; + } + } + + // Check for zero + if (!d_exp && !d_mant) + { + return (sign << 15); + } + + // Check for overflow + if (exp >= CL_HALF_MAX_EXP) + { + return cl_half_handle_overflow(rounding_mode, sign); + } + + // Check for underflow + if (exp < (CL_HALF_MIN_EXP - CL_HALF_MANT_DIG - 1)) + { + return cl_half_handle_underflow(rounding_mode, sign); + } + + // Check for value that will become denormal + if (exp < -14) + { + // Include the implicit 1 from the FP64 mantissa + h_exp = 0; + d_mant |= (uint64_t)1 << (CL_DBL_MANT_DIG - 1); + + // Mantissa shift amount depends on exponent + lsb_pos = (uint32_t)(-exp + (CL_DBL_MANT_DIG - 25)); + } + + // Generate FP16 mantissa by shifting FP64 mantissa + uint16_t h_mant = (uint16_t)(d_mant >> lsb_pos); + + // Check whether we need to round + uint64_t halfway = (uint64_t)1 << (lsb_pos - 1); + uint64_t mask = (halfway << 1) - 1; + switch (rounding_mode) + { + case CL_HALF_RTE: + if ((d_mant & mask) > halfway) + { + // More than halfway -> round up + h_mant += 1; + } + else if ((d_mant & mask) == halfway) + { + // Exactly halfway -> round to nearest even + if (h_mant & 0x1) + h_mant += 1; + } + break; + case CL_HALF_RTZ: + // Mantissa has already been truncated -> do nothing + break; + case CL_HALF_RTP: + if ((d_mant & mask) && !sign) + { + // Round positive numbers up + h_mant += 1; + } + break; + case CL_HALF_RTN: + if ((d_mant & mask) && sign) + { + // Round negative numbers down + h_mant += 1; + } + break; + } + + // Check for mantissa overflow + if (h_mant & 0x400) + { + h_exp += 1; + h_mant = 0; + } + + return (sign << 15) | (h_exp << 10) | h_mant; +} + + +/** + * Convert a cl_half to a cl_float. + */ +static inline cl_float cl_half_to_float(cl_half h) +{ + // Type-punning to get direct access to underlying bits + union + { + cl_float f; + uint32_t i; + } f32; + + // Extract sign bit + uint16_t sign = h >> 15; + + // Extract FP16 exponent and mantissa + uint16_t h_exp = (h >> (CL_HALF_MANT_DIG - 1)) & 0x1F; + uint16_t h_mant = h & 0x3FF; + + // Remove FP16 exponent bias + int32_t exp = h_exp - CL_HALF_MAX_EXP + 1; + + // Add FP32 exponent bias + uint32_t f_exp = exp + CL_FLT_MAX_EXP - 1; + + // Check for NaN / infinity + if (h_exp == 0x1F) + { + if (h_mant) + { + // NaN -> propagate mantissa and silence it + uint32_t f_mant = h_mant << (CL_FLT_MANT_DIG - CL_HALF_MANT_DIG); + f_mant |= 0x400000; + f32.i = (sign << 31) | 0x7F800000 | f_mant; + return f32.f; + } + else + { + // Infinity -> zero mantissa + f32.i = (sign << 31) | 0x7F800000; + return f32.f; + } + } + + // Check for zero / denormal + if (h_exp == 0) + { + if (h_mant == 0) + { + // Zero -> zero exponent + f_exp = 0; + } + else + { + // Denormal -> normalize it + // - Shift mantissa to make most-significant 1 implicit + // - Adjust exponent accordingly + uint32_t shift = 0; + while ((h_mant & 0x400) == 0) + { + h_mant <<= 1; + shift++; + } + h_mant &= 0x3FF; + f_exp -= shift - 1; + } + } + + f32.i = (sign << 31) | (f_exp << 23) | (h_mant << 13); + return f32.f; +} + + +#undef CL_HALF_EXP_MASK +#undef CL_HALF_MAX_FINITE_MAG + + +#ifdef __cplusplus +} +#endif + + +#endif /* OPENCL_CL_HALF_H */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_icd.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_icd.h new file mode 100644 index 000000000..bce60ea25 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_icd.h @@ -0,0 +1,342 @@ +/******************************************************************************* + * Copyright (c) 2019-2020 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef OPENCL_CL_ICD_H +#define OPENCL_CL_ICD_H + +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +#include +#include +#include +#endif + +#if defined(_WIN32) && defined(_MSC_VER) && __CL_HAS_ANON_STRUCT__ + /* Disable warning C4201: nonstandard extension used : nameless struct/union */ + #pragma warning( push ) + #pragma warning( disable : 4201 ) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Vendor dispatch table structure */ + +typedef struct _cl_icd_dispatch { + /* OpenCL 1.0 */ +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ union { +#endif + clGetPlatformIDs_t *clGetPlatformIDs; +#if __CL_HAS_ANON_STRUCT__ + /* Set to CL_ICD2_TAG_KHR for cl_khr_icd 2.0.0 */ + intptr_t clGetPlatformIDs_icd2_tag; + }; +#endif + clGetPlatformInfo_t *clGetPlatformInfo; + clGetDeviceIDs_t *clGetDeviceIDs; + clGetDeviceInfo_t *clGetDeviceInfo; + clCreateContext_t *clCreateContext; + clCreateContextFromType_t *clCreateContextFromType; + clRetainContext_t *clRetainContext; + clReleaseContext_t *clReleaseContext; + clGetContextInfo_t *clGetContextInfo; + clCreateCommandQueue_t *clCreateCommandQueue; + clRetainCommandQueue_t *clRetainCommandQueue; + clReleaseCommandQueue_t *clReleaseCommandQueue; + clGetCommandQueueInfo_t *clGetCommandQueueInfo; + clSetCommandQueueProperty_t *clSetCommandQueueProperty; + clCreateBuffer_t *clCreateBuffer; + clCreateImage2D_t *clCreateImage2D; + clCreateImage3D_t *clCreateImage3D; + clRetainMemObject_t *clRetainMemObject; + clReleaseMemObject_t *clReleaseMemObject; + clGetSupportedImageFormats_t *clGetSupportedImageFormats; + clGetMemObjectInfo_t *clGetMemObjectInfo; + clGetImageInfo_t *clGetImageInfo; + clCreateSampler_t *clCreateSampler; + clRetainSampler_t *clRetainSampler; + clReleaseSampler_t *clReleaseSampler; + clGetSamplerInfo_t *clGetSamplerInfo; + clCreateProgramWithSource_t *clCreateProgramWithSource; + clCreateProgramWithBinary_t *clCreateProgramWithBinary; + clRetainProgram_t *clRetainProgram; + clReleaseProgram_t *clReleaseProgram; + clBuildProgram_t *clBuildProgram; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ union { +#endif + clUnloadCompiler_t *clUnloadCompiler; +#if __CL_HAS_ANON_STRUCT__ + /* Set to CL_ICD2_TAG_KHR for cl_khr_icd 2.0.0 */ + intptr_t clUnloadCompiler_icd2_tag; + }; +#endif + clGetProgramInfo_t *clGetProgramInfo; + clGetProgramBuildInfo_t *clGetProgramBuildInfo; + clCreateKernel_t *clCreateKernel; + clCreateKernelsInProgram_t *clCreateKernelsInProgram; + clRetainKernel_t *clRetainKernel; + clReleaseKernel_t *clReleaseKernel; + clSetKernelArg_t *clSetKernelArg; + clGetKernelInfo_t *clGetKernelInfo; + clGetKernelWorkGroupInfo_t *clGetKernelWorkGroupInfo; + clWaitForEvents_t *clWaitForEvents; + clGetEventInfo_t *clGetEventInfo; + clRetainEvent_t *clRetainEvent; + clReleaseEvent_t *clReleaseEvent; + clGetEventProfilingInfo_t *clGetEventProfilingInfo; + clFlush_t *clFlush; + clFinish_t *clFinish; + clEnqueueReadBuffer_t *clEnqueueReadBuffer; + clEnqueueWriteBuffer_t *clEnqueueWriteBuffer; + clEnqueueCopyBuffer_t *clEnqueueCopyBuffer; + clEnqueueReadImage_t *clEnqueueReadImage; + clEnqueueWriteImage_t *clEnqueueWriteImage; + clEnqueueCopyImage_t *clEnqueueCopyImage; + clEnqueueCopyImageToBuffer_t *clEnqueueCopyImageToBuffer; + clEnqueueCopyBufferToImage_t *clEnqueueCopyBufferToImage; + clEnqueueMapBuffer_t *clEnqueueMapBuffer; + clEnqueueMapImage_t *clEnqueueMapImage; + clEnqueueUnmapMemObject_t *clEnqueueUnmapMemObject; + clEnqueueNDRangeKernel_t *clEnqueueNDRangeKernel; + clEnqueueTask_t *clEnqueueTask; + clEnqueueNativeKernel_t *clEnqueueNativeKernel; + clEnqueueMarker_t *clEnqueueMarker; + clEnqueueWaitForEvents_t *clEnqueueWaitForEvents; + clEnqueueBarrier_t *clEnqueueBarrier; + clGetExtensionFunctionAddress_t *clGetExtensionFunctionAddress; + clCreateFromGLBuffer_t *clCreateFromGLBuffer; + clCreateFromGLTexture2D_t *clCreateFromGLTexture2D; + clCreateFromGLTexture3D_t *clCreateFromGLTexture3D; + clCreateFromGLRenderbuffer_t *clCreateFromGLRenderbuffer; + clGetGLObjectInfo_t *clGetGLObjectInfo; + clGetGLTextureInfo_t *clGetGLTextureInfo; + clEnqueueAcquireGLObjects_t *clEnqueueAcquireGLObjects; + clEnqueueReleaseGLObjects_t *clEnqueueReleaseGLObjects; + clGetGLContextInfoKHR_t *clGetGLContextInfoKHR; + + /* cl_khr_d3d10_sharing */ +#ifdef _WIN32 + clGetDeviceIDsFromD3D10KHR_t *clGetDeviceIDsFromD3D10KHR; + clCreateFromD3D10BufferKHR_t *clCreateFromD3D10BufferKHR; + clCreateFromD3D10Texture2DKHR_t *clCreateFromD3D10Texture2DKHR; + clCreateFromD3D10Texture3DKHR_t *clCreateFromD3D10Texture3DKHR; + clEnqueueAcquireD3D10ObjectsKHR_t *clEnqueueAcquireD3D10ObjectsKHR; + clEnqueueReleaseD3D10ObjectsKHR_t *clEnqueueReleaseD3D10ObjectsKHR; +#else + void *clGetDeviceIDsFromD3D10KHR; + void *clCreateFromD3D10BufferKHR; + void *clCreateFromD3D10Texture2DKHR; + void *clCreateFromD3D10Texture3DKHR; + void *clEnqueueAcquireD3D10ObjectsKHR; + void *clEnqueueReleaseD3D10ObjectsKHR; +#endif + + /* OpenCL 1.1 */ +#ifdef CL_VERSION_1_1 + clSetEventCallback_t *clSetEventCallback; + clCreateSubBuffer_t *clCreateSubBuffer; + clSetMemObjectDestructorCallback_t *clSetMemObjectDestructorCallback; + clCreateUserEvent_t *clCreateUserEvent; + clSetUserEventStatus_t *clSetUserEventStatus; + clEnqueueReadBufferRect_t *clEnqueueReadBufferRect; + clEnqueueWriteBufferRect_t *clEnqueueWriteBufferRect; + clEnqueueCopyBufferRect_t *clEnqueueCopyBufferRect; +#else + void *clSetEventCallback; + void *clCreateSubBuffer; + void *clSetMemObjectDestructorCallback; + void *clCreateUserEvent; + void *clSetUserEventStatus; + void *clEnqueueReadBufferRect; + void *clEnqueueWriteBufferRect; + void *clEnqueueCopyBufferRect; +#endif + + /* cl_ext_device_fission */ + clCreateSubDevicesEXT_t *clCreateSubDevicesEXT; + clRetainDeviceEXT_t *clRetainDeviceEXT; + clReleaseDeviceEXT_t *clReleaseDeviceEXT; + + /* cl_khr_gl_event */ + clCreateEventFromGLsyncKHR_t *clCreateEventFromGLsyncKHR; + + /* OpenCL 1.2 */ +#ifdef CL_VERSION_1_2 + clCreateSubDevices_t *clCreateSubDevices; + clRetainDevice_t *clRetainDevice; + clReleaseDevice_t *clReleaseDevice; + clCreateImage_t *clCreateImage; + clCreateProgramWithBuiltInKernels_t *clCreateProgramWithBuiltInKernels; + clCompileProgram_t *clCompileProgram; + clLinkProgram_t *clLinkProgram; + clUnloadPlatformCompiler_t *clUnloadPlatformCompiler; + clGetKernelArgInfo_t *clGetKernelArgInfo; + clEnqueueFillBuffer_t *clEnqueueFillBuffer; + clEnqueueFillImage_t *clEnqueueFillImage; + clEnqueueMigrateMemObjects_t *clEnqueueMigrateMemObjects; + clEnqueueMarkerWithWaitList_t *clEnqueueMarkerWithWaitList; + clEnqueueBarrierWithWaitList_t *clEnqueueBarrierWithWaitList; + clGetExtensionFunctionAddressForPlatform_t * + clGetExtensionFunctionAddressForPlatform; + clCreateFromGLTexture_t *clCreateFromGLTexture; +#else + void *clCreateSubDevices; + void *clRetainDevice; + void *clReleaseDevice; + void *clCreateImage; + void *clCreateProgramWithBuiltInKernels; + void *clCompileProgram; + void *clLinkProgram; + void *clUnloadPlatformCompiler; + void *clGetKernelArgInfo; + void *clEnqueueFillBuffer; + void *clEnqueueFillImage; + void *clEnqueueMigrateMemObjects; + void *clEnqueueMarkerWithWaitList; + void *clEnqueueBarrierWithWaitList; + void *clGetExtensionFunctionAddressForPlatform; + void *clCreateFromGLTexture; +#endif + + /* cl_khr_d3d11_sharing and cl_khr_dx9_media_sharing */ +#ifdef _WIN32 + clGetDeviceIDsFromD3D11KHR_t *clGetDeviceIDsFromD3D11KHR; + clCreateFromD3D11BufferKHR_t *clCreateFromD3D11BufferKHR; + clCreateFromD3D11Texture2DKHR_t *clCreateFromD3D11Texture2DKHR; + clCreateFromD3D11Texture3DKHR_t *clCreateFromD3D11Texture3DKHR; + clCreateFromDX9MediaSurfaceKHR_t *clCreateFromDX9MediaSurfaceKHR; + clEnqueueAcquireD3D11ObjectsKHR_t *clEnqueueAcquireD3D11ObjectsKHR; + clEnqueueReleaseD3D11ObjectsKHR_t *clEnqueueReleaseD3D11ObjectsKHR; + clGetDeviceIDsFromDX9MediaAdapterKHR_t * + clGetDeviceIDsFromDX9MediaAdapterKHR; + clEnqueueAcquireDX9MediaSurfacesKHR_t * + clEnqueueAcquireDX9MediaSurfacesKHR; + clEnqueueReleaseDX9MediaSurfacesKHR_t * + clEnqueueReleaseDX9MediaSurfacesKHR; +#else + void *clGetDeviceIDsFromD3D11KHR; + void *clCreateFromD3D11BufferKHR; + void *clCreateFromD3D11Texture2DKHR; + void *clCreateFromD3D11Texture3DKHR; + void *clCreateFromDX9MediaSurfaceKHR; + void *clEnqueueAcquireD3D11ObjectsKHR; + void *clEnqueueReleaseD3D11ObjectsKHR; + void *clGetDeviceIDsFromDX9MediaAdapterKHR; + void *clEnqueueAcquireDX9MediaSurfacesKHR; + void *clEnqueueReleaseDX9MediaSurfacesKHR; +#endif + + /* cl_khr_egl_image */ + clCreateFromEGLImageKHR_t *clCreateFromEGLImageKHR; + clEnqueueAcquireEGLObjectsKHR_t *clEnqueueAcquireEGLObjectsKHR; + clEnqueueReleaseEGLObjectsKHR_t *clEnqueueReleaseEGLObjectsKHR; + + /* cl_khr_egl_event */ + clCreateEventFromEGLSyncKHR_t *clCreateEventFromEGLSyncKHR; + + /* OpenCL 2.0 */ +#ifdef CL_VERSION_2_0 + clCreateCommandQueueWithProperties_t *clCreateCommandQueueWithProperties; + clCreatePipe_t *clCreatePipe; + clGetPipeInfo_t *clGetPipeInfo; + clSVMAlloc_t *clSVMAlloc; + clSVMFree_t *clSVMFree; + clEnqueueSVMFree_t *clEnqueueSVMFree; + clEnqueueSVMMemcpy_t *clEnqueueSVMMemcpy; + clEnqueueSVMMemFill_t *clEnqueueSVMMemFill; + clEnqueueSVMMap_t *clEnqueueSVMMap; + clEnqueueSVMUnmap_t *clEnqueueSVMUnmap; + clCreateSamplerWithProperties_t *clCreateSamplerWithProperties; + clSetKernelArgSVMPointer_t *clSetKernelArgSVMPointer; + clSetKernelExecInfo_t *clSetKernelExecInfo; +#else + void *clCreateCommandQueueWithProperties; + void *clCreatePipe; + void *clGetPipeInfo; + void *clSVMAlloc; + void *clSVMFree; + void *clEnqueueSVMFree; + void *clEnqueueSVMMemcpy; + void *clEnqueueSVMMemFill; + void *clEnqueueSVMMap; + void *clEnqueueSVMUnmap; + void *clCreateSamplerWithProperties; + void *clSetKernelArgSVMPointer; + void *clSetKernelExecInfo; +#endif + + /* cl_khr_sub_groups */ + clGetKernelSubGroupInfoKHR_t *clGetKernelSubGroupInfoKHR; + + /* OpenCL 2.1 */ +#ifdef CL_VERSION_2_1 + clCloneKernel_t *clCloneKernel; + clCreateProgramWithIL_t *clCreateProgramWithIL; + clEnqueueSVMMigrateMem_t *clEnqueueSVMMigrateMem; + clGetDeviceAndHostTimer_t *clGetDeviceAndHostTimer; + clGetHostTimer_t *clGetHostTimer; + clGetKernelSubGroupInfo_t *clGetKernelSubGroupInfo; + clSetDefaultDeviceCommandQueue_t *clSetDefaultDeviceCommandQueue; +#else + void *clCloneKernel; + void *clCreateProgramWithIL; + void *clEnqueueSVMMigrateMem; + void *clGetDeviceAndHostTimer; + void *clGetHostTimer; + void *clGetKernelSubGroupInfo; + void *clSetDefaultDeviceCommandQueue; +#endif + + /* OpenCL 2.2 */ +#ifdef CL_VERSION_2_2 + clSetProgramReleaseCallback_t *clSetProgramReleaseCallback; + clSetProgramSpecializationConstant_t *clSetProgramSpecializationConstant; +#else + void *clSetProgramReleaseCallback; + void *clSetProgramSpecializationConstant; +#endif + + /* OpenCL 3.0 */ +#ifdef CL_VERSION_3_0 + clCreateBufferWithProperties_t *clCreateBufferWithProperties; + clCreateImageWithProperties_t *clCreateImageWithProperties; + clSetContextDestructorCallback_t *clSetContextDestructorCallback; +#else + void *clCreateBufferWithProperties; + void *clCreateImageWithProperties; + void *clSetContextDestructorCallback; +#endif + +} cl_icd_dispatch; + +#ifdef __cplusplus +} +#endif + +#if defined(_WIN32) && defined(_MSC_VER) && __CL_HAS_ANON_STRUCT__ + #pragma warning( pop ) +#endif + +#endif /* #ifndef OPENCL_CL_ICD_H */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_layer.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_layer.h new file mode 100644 index 000000000..245f7b532 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_layer.h @@ -0,0 +1,125 @@ +/******************************************************************************* + * Copyright (c) 2008-2023 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef OPENCL_CL_LAYER_H_ +#define OPENCL_CL_LAYER_H_ + +/* +** This header is generated from the Khronos OpenCL XML API Registry. +*/ + +#include + +#include + +/* CL_NO_PROTOTYPES implies CL_NO_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_PROTOTYPES) && !defined(CL_NO_EXTENSION_PROTOTYPES) +#define CL_NO_EXTENSION_PROTOTYPES +#endif + +/* CL_NO_EXTENSION_PROTOTYPES implies + CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES and + CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************** +* cl_loader_layers +***************************************************************/ +#define cl_loader_layers 1 +#define CL_LOADER_LAYERS_EXTENSION_NAME \ + "cl_loader_layers" + + +#define CL_LOADER_LAYERS_EXTENSION_VERSION CL_MAKE_VERSION(1, 0, 0) + +typedef cl_uint cl_layer_info; +typedef cl_uint cl_layer_api_version; + +/* cl_layer_info */ +#define CL_LAYER_API_VERSION 0x4240 +#define CL_LAYER_NAME 0x4241 + +/* Misc API enums */ +#define CL_LAYER_API_VERSION_100 100 + + +typedef cl_int CL_API_CALL +clGetLayerInfo_t( + cl_layer_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret); + +typedef clGetLayerInfo_t * +clGetLayerInfo_fn ; + +typedef cl_int CL_API_CALL +clInitLayer_t( + cl_uint num_entries, + const cl_icd_dispatch* target_dispatch, + cl_uint* num_entries_ret, + const cl_icd_dispatch** layer_dispatch_ret); + +typedef clInitLayer_t * +clInitLayer_fn ; + +/* +** The function pointer typedefs prefixed with "pfn_" are provided for +** compatibility with earlier versions of the headers. New code is +** encouraged to use the function pointer typedefs that are suffixed with +** "_fn" instead, for consistency. +*/ + +typedef clGetLayerInfo_t * +pfn_clGetLayerInfo ; + +typedef clInitLayer_t * +pfn_clInitLayer ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetLayerInfo( + cl_layer_info param_name, + size_t param_value_size, + void* param_value, + size_t* param_value_size_ret) ; + +extern CL_API_ENTRY cl_int CL_API_CALL +clInitLayer( + cl_uint num_entries, + const cl_icd_dispatch* target_dispatch, + cl_uint* num_entries_ret, + const cl_icd_dispatch** layer_dispatch_ret) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#ifdef __cplusplus +} +#endif + +#endif /* OPENCL_CL_LAYER_H_ */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_platform.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_platform.h new file mode 100644 index 000000000..5f92d6faa --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_platform.h @@ -0,0 +1,1407 @@ +/******************************************************************************* + * Copyright (c) 2008-2020 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef __CL_PLATFORM_H +#define __CL_PLATFORM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(_WIN32) + #if !defined(CL_API_ENTRY) + #define CL_API_ENTRY + #endif + #if !defined(CL_API_CALL) + #define CL_API_CALL __stdcall + #endif + #if !defined(CL_CALLBACK) + #define CL_CALLBACK __stdcall + #endif +#else + #if !defined(CL_API_ENTRY) + #define CL_API_ENTRY + #endif + #if !defined(CL_API_CALL) + #define CL_API_CALL + #endif + #if !defined(CL_CALLBACK) + #define CL_CALLBACK + #endif +#endif + +/* + * Deprecation flags refer to the last version of the header in which the + * feature was not deprecated. + * + * E.g. VERSION_1_1_DEPRECATED means the feature is present in 1.1 without + * deprecation but is deprecated in versions later than 1.1. + */ + +#ifndef CL_API_SUFFIX_USER +#define CL_API_SUFFIX_USER +#endif + +#ifndef CL_API_PREFIX_USER +#define CL_API_PREFIX_USER +#endif + +#define CL_API_SUFFIX_COMMON CL_API_SUFFIX_USER +#define CL_API_PREFIX_COMMON CL_API_PREFIX_USER + +#define CL_API_SUFFIX__VERSION_1_0 CL_API_SUFFIX_COMMON +#define CL_API_SUFFIX__VERSION_1_1 CL_API_SUFFIX_COMMON +#define CL_API_SUFFIX__VERSION_1_2 CL_API_SUFFIX_COMMON +#define CL_API_SUFFIX__VERSION_2_0 CL_API_SUFFIX_COMMON +#define CL_API_SUFFIX__VERSION_2_1 CL_API_SUFFIX_COMMON +#define CL_API_SUFFIX__VERSION_2_2 CL_API_SUFFIX_COMMON +#define CL_API_SUFFIX__VERSION_3_0 CL_API_SUFFIX_COMMON +#define CL_API_SUFFIX__EXPERIMENTAL CL_API_SUFFIX_COMMON + + +#ifdef __GNUC__ + #define CL_API_SUFFIX_DEPRECATED __attribute__((deprecated)) + #define CL_API_PREFIX_DEPRECATED +#elif defined(_MSC_VER) && !defined(__clang__) + #define CL_API_SUFFIX_DEPRECATED + #define CL_API_PREFIX_DEPRECATED __declspec(deprecated) +#else + #define CL_API_SUFFIX_DEPRECATED + #define CL_API_PREFIX_DEPRECATED +#endif + +#ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS + #define CL_API_SUFFIX__VERSION_1_0_DEPRECATED CL_API_SUFFIX_COMMON + #define CL_API_PREFIX__VERSION_1_0_DEPRECATED CL_API_PREFIX_COMMON +#else + #define CL_API_SUFFIX__VERSION_1_0_DEPRECATED CL_API_SUFFIX_COMMON CL_API_SUFFIX_DEPRECATED + #define CL_API_PREFIX__VERSION_1_0_DEPRECATED CL_API_PREFIX_COMMON CL_API_PREFIX_DEPRECATED +#endif + +#ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS + #define CL_API_SUFFIX__VERSION_1_1_DEPRECATED CL_API_SUFFIX_COMMON + #define CL_API_PREFIX__VERSION_1_1_DEPRECATED CL_API_PREFIX_COMMON +#else + #define CL_API_SUFFIX__VERSION_1_1_DEPRECATED CL_API_SUFFIX_COMMON CL_API_SUFFIX_DEPRECATED + #define CL_API_PREFIX__VERSION_1_1_DEPRECATED CL_API_PREFIX_COMMON CL_API_PREFIX_DEPRECATED +#endif + +#ifdef CL_USE_DEPRECATED_OPENCL_1_2_APIS + #define CL_API_SUFFIX__VERSION_1_2_DEPRECATED CL_API_SUFFIX_COMMON + #define CL_API_PREFIX__VERSION_1_2_DEPRECATED CL_API_PREFIX_COMMON +#else + #define CL_API_SUFFIX__VERSION_1_2_DEPRECATED CL_API_SUFFIX_COMMON CL_API_SUFFIX_DEPRECATED + #define CL_API_PREFIX__VERSION_1_2_DEPRECATED CL_API_PREFIX_COMMON CL_API_PREFIX_DEPRECATED + #endif + +#ifdef CL_USE_DEPRECATED_OPENCL_2_0_APIS + #define CL_API_SUFFIX__VERSION_2_0_DEPRECATED CL_API_SUFFIX_COMMON + #define CL_API_PREFIX__VERSION_2_0_DEPRECATED CL_API_PREFIX_COMMON +#else + #define CL_API_SUFFIX__VERSION_2_0_DEPRECATED CL_API_SUFFIX_COMMON CL_API_SUFFIX_DEPRECATED + #define CL_API_PREFIX__VERSION_2_0_DEPRECATED CL_API_PREFIX_COMMON CL_API_PREFIX_DEPRECATED +#endif + +#ifdef CL_USE_DEPRECATED_OPENCL_2_1_APIS + #define CL_API_SUFFIX__VERSION_2_1_DEPRECATED CL_API_SUFFIX_COMMON + #define CL_API_PREFIX__VERSION_2_1_DEPRECATED CL_API_PREFIX_COMMON +#else + #define CL_API_SUFFIX__VERSION_2_1_DEPRECATED CL_API_SUFFIX_COMMON CL_API_SUFFIX_DEPRECATED + #define CL_API_PREFIX__VERSION_2_1_DEPRECATED CL_API_PREFIX_COMMON CL_API_PREFIX_DEPRECATED +#endif + +#ifdef CL_USE_DEPRECATED_OPENCL_2_2_APIS + #define CL_API_SUFFIX__VERSION_2_2_DEPRECATED CL_API_SUFFIX_COMMON + #define CL_API_PREFIX__VERSION_2_2_DEPRECATED CL_API_PREFIX_COMMON +#else + #define CL_API_SUFFIX__VERSION_2_2_DEPRECATED CL_API_SUFFIX_COMMON CL_API_SUFFIX_DEPRECATED + #define CL_API_PREFIX__VERSION_2_2_DEPRECATED CL_API_PREFIX_COMMON CL_API_PREFIX_DEPRECATED +#endif + +#if (defined (_WIN32) && defined(_MSC_VER)) + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wlanguage-extension-token" +#endif + +/* intptr_t is used in cl.h and provided by stddef.h in Visual C++, but not in clang */ +/* stdint.h was missing before Visual Studio 2010, include it for later versions and for clang */ +#if defined(__clang__) || _MSC_VER >= 1600 + #include +#endif + +/* scalar types */ +typedef signed __int8 cl_char; +typedef unsigned __int8 cl_uchar; +typedef signed __int16 cl_short; +typedef unsigned __int16 cl_ushort; +typedef signed __int32 cl_int; +typedef unsigned __int32 cl_uint; +typedef signed __int64 cl_long; +typedef unsigned __int64 cl_ulong; + +typedef unsigned __int16 cl_half; +typedef float cl_float; +typedef double cl_double; + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +/* Macro names and corresponding values defined by OpenCL */ +#define CL_CHAR_BIT 8 +#define CL_SCHAR_MAX 127 +#define CL_SCHAR_MIN (-127-1) +#define CL_CHAR_MAX CL_SCHAR_MAX +#define CL_CHAR_MIN CL_SCHAR_MIN +#define CL_UCHAR_MAX 255 +#define CL_SHRT_MAX 32767 +#define CL_SHRT_MIN (-32767-1) +#define CL_USHRT_MAX 65535 +#define CL_INT_MAX 2147483647 +#define CL_INT_MIN (-2147483647-1) +#define CL_UINT_MAX 0xffffffffU +#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL) +#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL) +#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL) + +#define CL_FLT_DIG 6 +#define CL_FLT_MANT_DIG 24 +#define CL_FLT_MAX_10_EXP +38 +#define CL_FLT_MAX_EXP +128 +#define CL_FLT_MIN_10_EXP -37 +#define CL_FLT_MIN_EXP -125 +#define CL_FLT_RADIX 2 +#define CL_FLT_MAX 340282346638528859811704183484516925440.0f +#define CL_FLT_MIN 1.175494350822287507969e-38f +#define CL_FLT_EPSILON 1.1920928955078125e-7f + +#define CL_HALF_DIG 3 +#define CL_HALF_MANT_DIG 11 +#define CL_HALF_MAX_10_EXP +4 +#define CL_HALF_MAX_EXP +16 +#define CL_HALF_MIN_10_EXP -4 +#define CL_HALF_MIN_EXP -13 +#define CL_HALF_RADIX 2 +#define CL_HALF_MAX 65504.0f +#define CL_HALF_MIN 6.103515625e-05f +#define CL_HALF_EPSILON 9.765625e-04f + +#define CL_DBL_DIG 15 +#define CL_DBL_MANT_DIG 53 +#define CL_DBL_MAX_10_EXP +308 +#define CL_DBL_MAX_EXP +1024 +#define CL_DBL_MIN_10_EXP -307 +#define CL_DBL_MIN_EXP -1021 +#define CL_DBL_RADIX 2 +#define CL_DBL_MAX 1.7976931348623158e+308 +#define CL_DBL_MIN 2.225073858507201383090e-308 +#define CL_DBL_EPSILON 2.220446049250313080847e-16 + +#define CL_M_E 2.7182818284590452354 +#define CL_M_LOG2E 1.4426950408889634074 +#define CL_M_LOG10E 0.43429448190325182765 +#define CL_M_LN2 0.69314718055994530942 +#define CL_M_LN10 2.30258509299404568402 +#define CL_M_PI 3.14159265358979323846 +#define CL_M_PI_2 1.57079632679489661923 +#define CL_M_PI_4 0.78539816339744830962 +#define CL_M_1_PI 0.31830988618379067154 +#define CL_M_2_PI 0.63661977236758134308 +#define CL_M_2_SQRTPI 1.12837916709551257390 +#define CL_M_SQRT2 1.41421356237309504880 +#define CL_M_SQRT1_2 0.70710678118654752440 + +#define CL_M_E_F 2.718281828f +#define CL_M_LOG2E_F 1.442695041f +#define CL_M_LOG10E_F 0.434294482f +#define CL_M_LN2_F 0.693147181f +#define CL_M_LN10_F 2.302585093f +#define CL_M_PI_F 3.141592654f +#define CL_M_PI_2_F 1.570796327f +#define CL_M_PI_4_F 0.785398163f +#define CL_M_1_PI_F 0.318309886f +#define CL_M_2_PI_F 0.636619772f +#define CL_M_2_SQRTPI_F 1.128379167f +#define CL_M_SQRT2_F 1.414213562f +#define CL_M_SQRT1_2_F 0.707106781f + +#define CL_NAN (CL_INFINITY - CL_INFINITY) +#define CL_HUGE_VALF ((cl_float) 1e50) +#define CL_HUGE_VAL ((cl_double) 1e500) +#define CL_MAXFLOAT CL_FLT_MAX +#define CL_INFINITY CL_HUGE_VALF + +#else + +#include + +/* scalar types */ +typedef int8_t cl_char; +typedef uint8_t cl_uchar; +typedef int16_t cl_short; +typedef uint16_t cl_ushort; +typedef int32_t cl_int; +typedef uint32_t cl_uint; +typedef int64_t cl_long; +typedef uint64_t cl_ulong; + +typedef uint16_t cl_half; +typedef float cl_float; +typedef double cl_double; + +/* Macro names and corresponding values defined by OpenCL */ +#define CL_CHAR_BIT 8 +#define CL_SCHAR_MAX 127 +#define CL_SCHAR_MIN (-127-1) +#define CL_CHAR_MAX CL_SCHAR_MAX +#define CL_CHAR_MIN CL_SCHAR_MIN +#define CL_UCHAR_MAX 255 +#define CL_SHRT_MAX 32767 +#define CL_SHRT_MIN (-32767-1) +#define CL_USHRT_MAX 65535 +#define CL_INT_MAX 2147483647 +#define CL_INT_MIN (-2147483647-1) +#define CL_UINT_MAX 0xffffffffU +#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL) +#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL) +#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL) + +#define CL_FLT_DIG 6 +#define CL_FLT_MANT_DIG 24 +#define CL_FLT_MAX_10_EXP +38 +#define CL_FLT_MAX_EXP +128 +#define CL_FLT_MIN_10_EXP -37 +#define CL_FLT_MIN_EXP -125 +#define CL_FLT_RADIX 2 +#define CL_FLT_MAX 340282346638528859811704183484516925440.0f +#define CL_FLT_MIN 1.175494350822287507969e-38f +#define CL_FLT_EPSILON 1.1920928955078125e-7f + +#define CL_HALF_DIG 3 +#define CL_HALF_MANT_DIG 11 +#define CL_HALF_MAX_10_EXP +4 +#define CL_HALF_MAX_EXP +16 +#define CL_HALF_MIN_10_EXP -4 +#define CL_HALF_MIN_EXP -13 +#define CL_HALF_RADIX 2 +#define CL_HALF_MAX 65504.0f +#define CL_HALF_MIN 6.103515625e-05f +#define CL_HALF_EPSILON 9.765625e-04f + +#define CL_DBL_DIG 15 +#define CL_DBL_MANT_DIG 53 +#define CL_DBL_MAX_10_EXP +308 +#define CL_DBL_MAX_EXP +1024 +#define CL_DBL_MIN_10_EXP -307 +#define CL_DBL_MIN_EXP -1021 +#define CL_DBL_RADIX 2 +#define CL_DBL_MAX 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0 +#define CL_DBL_MIN 2.225073858507201383090e-308 +#define CL_DBL_EPSILON 2.220446049250313080847e-16 + +#define CL_M_E 2.7182818284590452354 +#define CL_M_LOG2E 1.4426950408889634074 +#define CL_M_LOG10E 0.43429448190325182765 +#define CL_M_LN2 0.69314718055994530942 +#define CL_M_LN10 2.30258509299404568402 +#define CL_M_PI 3.14159265358979323846 +#define CL_M_PI_2 1.57079632679489661923 +#define CL_M_PI_4 0.78539816339744830962 +#define CL_M_1_PI 0.31830988618379067154 +#define CL_M_2_PI 0.63661977236758134308 +#define CL_M_2_SQRTPI 1.12837916709551257390 +#define CL_M_SQRT2 1.41421356237309504880 +#define CL_M_SQRT1_2 0.70710678118654752440 + +#define CL_M_E_F 2.718281828f +#define CL_M_LOG2E_F 1.442695041f +#define CL_M_LOG10E_F 0.434294482f +#define CL_M_LN2_F 0.693147181f +#define CL_M_LN10_F 2.302585093f +#define CL_M_PI_F 3.141592654f +#define CL_M_PI_2_F 1.570796327f +#define CL_M_PI_4_F 0.785398163f +#define CL_M_1_PI_F 0.318309886f +#define CL_M_2_PI_F 0.636619772f +#define CL_M_2_SQRTPI_F 1.128379167f +#define CL_M_SQRT2_F 1.414213562f +#define CL_M_SQRT1_2_F 0.707106781f + +#if defined( __GNUC__ ) + #define CL_HUGE_VALF __builtin_huge_valf() + #define CL_HUGE_VAL __builtin_huge_val() + #define CL_NAN __builtin_nanf( "" ) +#else + #define CL_HUGE_VALF ((cl_float) 1e50) + #define CL_HUGE_VAL ((cl_double) 1e500) + float nanf( const char * ); + #define CL_NAN nanf( "" ) +#endif +#define CL_MAXFLOAT CL_FLT_MAX +#define CL_INFINITY CL_HUGE_VALF + +#endif + +#include + +/* + * Vector types + * + * Note: OpenCL requires that all types be naturally aligned. + * This means that vector types must be naturally aligned. + * For example, a vector of four floats must be aligned to + * a 16 byte boundary (calculated as 4 * the natural 4-byte + * alignment of the float). The alignment qualifiers here + * will only function properly if your compiler supports them + * and if you don't actively work to defeat them. For example, + * in order for a cl_float4 to be 16 byte aligned in a struct, + * the start of the struct must itself be 16-byte aligned. + * + * Maintaining proper alignment is the user's responsibility. + */ + +/* Define basic vector types */ +#if defined( __VEC__ ) + #if !defined(__clang__) + #include /* may be omitted depending on compiler. AltiVec spec provides no way to detect whether the header is required. */ + #endif + typedef __vector unsigned char __cl_uchar16; + typedef __vector signed char __cl_char16; + typedef __vector unsigned short __cl_ushort8; + typedef __vector signed short __cl_short8; + typedef __vector unsigned int __cl_uint4; + typedef __vector signed int __cl_int4; + typedef __vector float __cl_float4; + #define __CL_UCHAR16__ 1 + #define __CL_CHAR16__ 1 + #define __CL_USHORT8__ 1 + #define __CL_SHORT8__ 1 + #define __CL_UINT4__ 1 + #define __CL_INT4__ 1 + #define __CL_FLOAT4__ 1 +#endif + +#if defined( __SSE__ ) + #if defined( __MINGW64__ ) + #include + #else + #include + #endif + #if defined( __GNUC__ ) + typedef float __cl_float4 __attribute__((vector_size(16))); + #else + typedef __m128 __cl_float4; + #endif + #define __CL_FLOAT4__ 1 +#endif + +#if defined( __SSE2__ ) + #if defined( __MINGW64__ ) + #include + #else + #include + #endif + #if defined( __GNUC__ ) + typedef cl_uchar __cl_uchar16 __attribute__((vector_size(16))); + typedef cl_char __cl_char16 __attribute__((vector_size(16))); + typedef cl_ushort __cl_ushort8 __attribute__((vector_size(16))); + typedef cl_short __cl_short8 __attribute__((vector_size(16))); + typedef cl_uint __cl_uint4 __attribute__((vector_size(16))); + typedef cl_int __cl_int4 __attribute__((vector_size(16))); + typedef cl_ulong __cl_ulong2 __attribute__((vector_size(16))); + typedef cl_long __cl_long2 __attribute__((vector_size(16))); + typedef cl_double __cl_double2 __attribute__((vector_size(16))); + #else + typedef __m128i __cl_uchar16; + typedef __m128i __cl_char16; + typedef __m128i __cl_ushort8; + typedef __m128i __cl_short8; + typedef __m128i __cl_uint4; + typedef __m128i __cl_int4; + typedef __m128i __cl_ulong2; + typedef __m128i __cl_long2; + typedef __m128d __cl_double2; + #endif + #define __CL_UCHAR16__ 1 + #define __CL_CHAR16__ 1 + #define __CL_USHORT8__ 1 + #define __CL_SHORT8__ 1 + #define __CL_INT4__ 1 + #define __CL_UINT4__ 1 + #define __CL_ULONG2__ 1 + #define __CL_LONG2__ 1 + #define __CL_DOUBLE2__ 1 +#endif + +#if defined( __MMX__ ) + #include + #if defined( __GNUC__ ) + typedef cl_uchar __cl_uchar8 __attribute__((vector_size(8))); + typedef cl_char __cl_char8 __attribute__((vector_size(8))); + typedef cl_ushort __cl_ushort4 __attribute__((vector_size(8))); + typedef cl_short __cl_short4 __attribute__((vector_size(8))); + typedef cl_uint __cl_uint2 __attribute__((vector_size(8))); + typedef cl_int __cl_int2 __attribute__((vector_size(8))); + typedef cl_ulong __cl_ulong1 __attribute__((vector_size(8))); + typedef cl_long __cl_long1 __attribute__((vector_size(8))); + typedef cl_float __cl_float2 __attribute__((vector_size(8))); + #else + typedef __m64 __cl_uchar8; + typedef __m64 __cl_char8; + typedef __m64 __cl_ushort4; + typedef __m64 __cl_short4; + typedef __m64 __cl_uint2; + typedef __m64 __cl_int2; + typedef __m64 __cl_ulong1; + typedef __m64 __cl_long1; + typedef __m64 __cl_float2; + #endif + #define __CL_UCHAR8__ 1 + #define __CL_CHAR8__ 1 + #define __CL_USHORT4__ 1 + #define __CL_SHORT4__ 1 + #define __CL_INT2__ 1 + #define __CL_UINT2__ 1 + #define __CL_ULONG1__ 1 + #define __CL_LONG1__ 1 + #define __CL_FLOAT2__ 1 +#endif + +#if defined( __AVX__ ) + #if defined( __MINGW64__ ) + #include + #else + #include + #endif + #if defined( __GNUC__ ) + typedef cl_float __cl_float8 __attribute__((vector_size(32))); + typedef cl_double __cl_double4 __attribute__((vector_size(32))); + #else + typedef __m256 __cl_float8; + typedef __m256d __cl_double4; + #endif + #define __CL_FLOAT8__ 1 + #define __CL_DOUBLE4__ 1 +#endif + +/* Define capabilities for anonymous struct members. */ +#if !defined(__cplusplus) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define __CL_HAS_ANON_STRUCT__ 1 +#define __CL_ANON_STRUCT__ +#elif defined(_WIN32) && defined(_MSC_VER) && !defined(__STDC__) +#define __CL_HAS_ANON_STRUCT__ 1 +#define __CL_ANON_STRUCT__ +#elif defined(__GNUC__) && ! defined(__STRICT_ANSI__) +#define __CL_HAS_ANON_STRUCT__ 1 +#define __CL_ANON_STRUCT__ __extension__ +#elif defined(__clang__) +#define __CL_HAS_ANON_STRUCT__ 1 +#define __CL_ANON_STRUCT__ __extension__ +#else +#define __CL_HAS_ANON_STRUCT__ 0 +#define __CL_ANON_STRUCT__ +#endif + +#if defined(_WIN32) && defined(_MSC_VER) && __CL_HAS_ANON_STRUCT__ + /* Disable warning C4201: nonstandard extension used : nameless struct/union */ + #pragma warning( push ) + #pragma warning( disable : 4201 ) +#endif + +/* Define alignment keys */ +#if defined( __GNUC__ ) || defined(__INTEGRITY) + #define CL_ALIGNED(_x) __attribute__ ((aligned(_x))) +#elif defined( _WIN32) && (_MSC_VER) + /* Alignment keys neutered on windows because MSVC can't swallow function arguments with alignment requirements */ + /* http://msdn.microsoft.com/en-us/library/373ak2y1%28VS.71%29.aspx */ + /* #include */ + /* #define CL_ALIGNED(_x) _CRT_ALIGN(_x) */ + #define CL_ALIGNED(_x) +#else + #warning Need to implement some method to align data here + #define CL_ALIGNED(_x) +#endif + +/* Indicate whether .xyzw, .s0123 and .hi.lo are supported */ +#if __CL_HAS_ANON_STRUCT__ + /* .xyzw and .s0123...{f|F} are supported */ + #define CL_HAS_NAMED_VECTOR_FIELDS 1 + /* .hi and .lo are supported */ + #define CL_HAS_HI_LO_VECTOR_FIELDS 1 +#endif + +/* Define cl_vector types */ + +/* ---- cl_charn ---- */ +typedef union +{ + cl_char CL_ALIGNED(2) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_char x, y; }; + __CL_ANON_STRUCT__ struct{ cl_char s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_char lo, hi; }; +#endif +#if defined( __CL_CHAR2__) + __cl_char2 v2; +#endif +}cl_char2; + +typedef union +{ + cl_char CL_ALIGNED(4) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_char x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_char s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_char2 lo, hi; }; +#endif +#if defined( __CL_CHAR2__) + __cl_char2 v2[2]; +#endif +#if defined( __CL_CHAR4__) + __cl_char4 v4; +#endif +}cl_char4; + +/* cl_char3 is identical in size, alignment and behavior to cl_char4. See section 6.1.5. */ +typedef cl_char4 cl_char3; + +typedef union +{ + cl_char CL_ALIGNED(8) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_char x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_char4 lo, hi; }; +#endif +#if defined( __CL_CHAR2__) + __cl_char2 v2[4]; +#endif +#if defined( __CL_CHAR4__) + __cl_char4 v4[2]; +#endif +#if defined( __CL_CHAR8__ ) + __cl_char8 v8; +#endif +}cl_char8; + +typedef union +{ + cl_char CL_ALIGNED(16) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_char x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_char8 lo, hi; }; +#endif +#if defined( __CL_CHAR2__) + __cl_char2 v2[8]; +#endif +#if defined( __CL_CHAR4__) + __cl_char4 v4[4]; +#endif +#if defined( __CL_CHAR8__ ) + __cl_char8 v8[2]; +#endif +#if defined( __CL_CHAR16__ ) + __cl_char16 v16; +#endif +}cl_char16; + + +/* ---- cl_ucharn ---- */ +typedef union +{ + cl_uchar CL_ALIGNED(2) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_uchar x, y; }; + __CL_ANON_STRUCT__ struct{ cl_uchar s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_uchar lo, hi; }; +#endif +#if defined( __cl_uchar2__) + __cl_uchar2 v2; +#endif +}cl_uchar2; + +typedef union +{ + cl_uchar CL_ALIGNED(4) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_uchar x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_uchar s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_uchar2 lo, hi; }; +#endif +#if defined( __CL_UCHAR2__) + __cl_uchar2 v2[2]; +#endif +#if defined( __CL_UCHAR4__) + __cl_uchar4 v4; +#endif +}cl_uchar4; + +/* cl_uchar3 is identical in size, alignment and behavior to cl_uchar4. See section 6.1.5. */ +typedef cl_uchar4 cl_uchar3; + +typedef union +{ + cl_uchar CL_ALIGNED(8) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_uchar x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_uchar4 lo, hi; }; +#endif +#if defined( __CL_UCHAR2__) + __cl_uchar2 v2[4]; +#endif +#if defined( __CL_UCHAR4__) + __cl_uchar4 v4[2]; +#endif +#if defined( __CL_UCHAR8__ ) + __cl_uchar8 v8; +#endif +}cl_uchar8; + +typedef union +{ + cl_uchar CL_ALIGNED(16) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_uchar x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_uchar8 lo, hi; }; +#endif +#if defined( __CL_UCHAR2__) + __cl_uchar2 v2[8]; +#endif +#if defined( __CL_UCHAR4__) + __cl_uchar4 v4[4]; +#endif +#if defined( __CL_UCHAR8__ ) + __cl_uchar8 v8[2]; +#endif +#if defined( __CL_UCHAR16__ ) + __cl_uchar16 v16; +#endif +}cl_uchar16; + + +/* ---- cl_shortn ---- */ +typedef union +{ + cl_short CL_ALIGNED(4) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_short x, y; }; + __CL_ANON_STRUCT__ struct{ cl_short s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_short lo, hi; }; +#endif +#if defined( __CL_SHORT2__) + __cl_short2 v2; +#endif +}cl_short2; + +typedef union +{ + cl_short CL_ALIGNED(8) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_short x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_short s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_short2 lo, hi; }; +#endif +#if defined( __CL_SHORT2__) + __cl_short2 v2[2]; +#endif +#if defined( __CL_SHORT4__) + __cl_short4 v4; +#endif +}cl_short4; + +/* cl_short3 is identical in size, alignment and behavior to cl_short4. See section 6.1.5. */ +typedef cl_short4 cl_short3; + +typedef union +{ + cl_short CL_ALIGNED(16) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_short x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_short4 lo, hi; }; +#endif +#if defined( __CL_SHORT2__) + __cl_short2 v2[4]; +#endif +#if defined( __CL_SHORT4__) + __cl_short4 v4[2]; +#endif +#if defined( __CL_SHORT8__ ) + __cl_short8 v8; +#endif +}cl_short8; + +typedef union +{ + cl_short CL_ALIGNED(32) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_short x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_short8 lo, hi; }; +#endif +#if defined( __CL_SHORT2__) + __cl_short2 v2[8]; +#endif +#if defined( __CL_SHORT4__) + __cl_short4 v4[4]; +#endif +#if defined( __CL_SHORT8__ ) + __cl_short8 v8[2]; +#endif +#if defined( __CL_SHORT16__ ) + __cl_short16 v16; +#endif +}cl_short16; + + +/* ---- cl_ushortn ---- */ +typedef union +{ + cl_ushort CL_ALIGNED(4) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_ushort x, y; }; + __CL_ANON_STRUCT__ struct{ cl_ushort s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_ushort lo, hi; }; +#endif +#if defined( __CL_USHORT2__) + __cl_ushort2 v2; +#endif +}cl_ushort2; + +typedef union +{ + cl_ushort CL_ALIGNED(8) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_ushort x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_ushort s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_ushort2 lo, hi; }; +#endif +#if defined( __CL_USHORT2__) + __cl_ushort2 v2[2]; +#endif +#if defined( __CL_USHORT4__) + __cl_ushort4 v4; +#endif +}cl_ushort4; + +/* cl_ushort3 is identical in size, alignment and behavior to cl_ushort4. See section 6.1.5. */ +typedef cl_ushort4 cl_ushort3; + +typedef union +{ + cl_ushort CL_ALIGNED(16) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_ushort x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_ushort4 lo, hi; }; +#endif +#if defined( __CL_USHORT2__) + __cl_ushort2 v2[4]; +#endif +#if defined( __CL_USHORT4__) + __cl_ushort4 v4[2]; +#endif +#if defined( __CL_USHORT8__ ) + __cl_ushort8 v8; +#endif +}cl_ushort8; + +typedef union +{ + cl_ushort CL_ALIGNED(32) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_ushort x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_ushort8 lo, hi; }; +#endif +#if defined( __CL_USHORT2__) + __cl_ushort2 v2[8]; +#endif +#if defined( __CL_USHORT4__) + __cl_ushort4 v4[4]; +#endif +#if defined( __CL_USHORT8__ ) + __cl_ushort8 v8[2]; +#endif +#if defined( __CL_USHORT16__ ) + __cl_ushort16 v16; +#endif +}cl_ushort16; + + +/* ---- cl_halfn ---- */ +typedef union +{ + cl_half CL_ALIGNED(4) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_half x, y; }; + __CL_ANON_STRUCT__ struct{ cl_half s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_half lo, hi; }; +#endif +#if defined( __CL_HALF2__) + __cl_half2 v2; +#endif +}cl_half2; + +typedef union +{ + cl_half CL_ALIGNED(8) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_half x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_half s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_half2 lo, hi; }; +#endif +#if defined( __CL_HALF2__) + __cl_half2 v2[2]; +#endif +#if defined( __CL_HALF4__) + __cl_half4 v4; +#endif +}cl_half4; + +/* cl_half3 is identical in size, alignment and behavior to cl_half4. See section 6.1.5. */ +typedef cl_half4 cl_half3; + +typedef union +{ + cl_half CL_ALIGNED(16) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_half x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_half s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_half4 lo, hi; }; +#endif +#if defined( __CL_HALF2__) + __cl_half2 v2[4]; +#endif +#if defined( __CL_HALF4__) + __cl_half4 v4[2]; +#endif +#if defined( __CL_HALF8__ ) + __cl_half8 v8; +#endif +}cl_half8; + +typedef union +{ + cl_half CL_ALIGNED(32) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_half x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_half s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_half8 lo, hi; }; +#endif +#if defined( __CL_HALF2__) + __cl_half2 v2[8]; +#endif +#if defined( __CL_HALF4__) + __cl_half4 v4[4]; +#endif +#if defined( __CL_HALF8__ ) + __cl_half8 v8[2]; +#endif +#if defined( __CL_HALF16__ ) + __cl_half16 v16; +#endif +}cl_half16; + +/* ---- cl_intn ---- */ +typedef union +{ + cl_int CL_ALIGNED(8) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_int x, y; }; + __CL_ANON_STRUCT__ struct{ cl_int s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_int lo, hi; }; +#endif +#if defined( __CL_INT2__) + __cl_int2 v2; +#endif +}cl_int2; + +typedef union +{ + cl_int CL_ALIGNED(16) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_int x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_int s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_int2 lo, hi; }; +#endif +#if defined( __CL_INT2__) + __cl_int2 v2[2]; +#endif +#if defined( __CL_INT4__) + __cl_int4 v4; +#endif +}cl_int4; + +/* cl_int3 is identical in size, alignment and behavior to cl_int4. See section 6.1.5. */ +typedef cl_int4 cl_int3; + +typedef union +{ + cl_int CL_ALIGNED(32) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_int x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_int4 lo, hi; }; +#endif +#if defined( __CL_INT2__) + __cl_int2 v2[4]; +#endif +#if defined( __CL_INT4__) + __cl_int4 v4[2]; +#endif +#if defined( __CL_INT8__ ) + __cl_int8 v8; +#endif +}cl_int8; + +typedef union +{ + cl_int CL_ALIGNED(64) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_int x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_int8 lo, hi; }; +#endif +#if defined( __CL_INT2__) + __cl_int2 v2[8]; +#endif +#if defined( __CL_INT4__) + __cl_int4 v4[4]; +#endif +#if defined( __CL_INT8__ ) + __cl_int8 v8[2]; +#endif +#if defined( __CL_INT16__ ) + __cl_int16 v16; +#endif +}cl_int16; + + +/* ---- cl_uintn ---- */ +typedef union +{ + cl_uint CL_ALIGNED(8) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_uint x, y; }; + __CL_ANON_STRUCT__ struct{ cl_uint s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_uint lo, hi; }; +#endif +#if defined( __CL_UINT2__) + __cl_uint2 v2; +#endif +}cl_uint2; + +typedef union +{ + cl_uint CL_ALIGNED(16) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_uint x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_uint s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_uint2 lo, hi; }; +#endif +#if defined( __CL_UINT2__) + __cl_uint2 v2[2]; +#endif +#if defined( __CL_UINT4__) + __cl_uint4 v4; +#endif +}cl_uint4; + +/* cl_uint3 is identical in size, alignment and behavior to cl_uint4. See section 6.1.5. */ +typedef cl_uint4 cl_uint3; + +typedef union +{ + cl_uint CL_ALIGNED(32) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_uint x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_uint4 lo, hi; }; +#endif +#if defined( __CL_UINT2__) + __cl_uint2 v2[4]; +#endif +#if defined( __CL_UINT4__) + __cl_uint4 v4[2]; +#endif +#if defined( __CL_UINT8__ ) + __cl_uint8 v8; +#endif +}cl_uint8; + +typedef union +{ + cl_uint CL_ALIGNED(64) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_uint x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_uint8 lo, hi; }; +#endif +#if defined( __CL_UINT2__) + __cl_uint2 v2[8]; +#endif +#if defined( __CL_UINT4__) + __cl_uint4 v4[4]; +#endif +#if defined( __CL_UINT8__ ) + __cl_uint8 v8[2]; +#endif +#if defined( __CL_UINT16__ ) + __cl_uint16 v16; +#endif +}cl_uint16; + +/* ---- cl_longn ---- */ +typedef union +{ + cl_long CL_ALIGNED(16) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_long x, y; }; + __CL_ANON_STRUCT__ struct{ cl_long s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_long lo, hi; }; +#endif +#if defined( __CL_LONG2__) + __cl_long2 v2; +#endif +}cl_long2; + +typedef union +{ + cl_long CL_ALIGNED(32) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_long x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_long s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_long2 lo, hi; }; +#endif +#if defined( __CL_LONG2__) + __cl_long2 v2[2]; +#endif +#if defined( __CL_LONG4__) + __cl_long4 v4; +#endif +}cl_long4; + +/* cl_long3 is identical in size, alignment and behavior to cl_long4. See section 6.1.5. */ +typedef cl_long4 cl_long3; + +typedef union +{ + cl_long CL_ALIGNED(64) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_long x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_long4 lo, hi; }; +#endif +#if defined( __CL_LONG2__) + __cl_long2 v2[4]; +#endif +#if defined( __CL_LONG4__) + __cl_long4 v4[2]; +#endif +#if defined( __CL_LONG8__ ) + __cl_long8 v8; +#endif +}cl_long8; + +typedef union +{ + cl_long CL_ALIGNED(128) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_long x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_long8 lo, hi; }; +#endif +#if defined( __CL_LONG2__) + __cl_long2 v2[8]; +#endif +#if defined( __CL_LONG4__) + __cl_long4 v4[4]; +#endif +#if defined( __CL_LONG8__ ) + __cl_long8 v8[2]; +#endif +#if defined( __CL_LONG16__ ) + __cl_long16 v16; +#endif +}cl_long16; + + +/* ---- cl_ulongn ---- */ +typedef union +{ + cl_ulong CL_ALIGNED(16) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_ulong x, y; }; + __CL_ANON_STRUCT__ struct{ cl_ulong s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_ulong lo, hi; }; +#endif +#if defined( __CL_ULONG2__) + __cl_ulong2 v2; +#endif +}cl_ulong2; + +typedef union +{ + cl_ulong CL_ALIGNED(32) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_ulong x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_ulong s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_ulong2 lo, hi; }; +#endif +#if defined( __CL_ULONG2__) + __cl_ulong2 v2[2]; +#endif +#if defined( __CL_ULONG4__) + __cl_ulong4 v4; +#endif +}cl_ulong4; + +/* cl_ulong3 is identical in size, alignment and behavior to cl_ulong4. See section 6.1.5. */ +typedef cl_ulong4 cl_ulong3; + +typedef union +{ + cl_ulong CL_ALIGNED(64) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_ulong x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_ulong4 lo, hi; }; +#endif +#if defined( __CL_ULONG2__) + __cl_ulong2 v2[4]; +#endif +#if defined( __CL_ULONG4__) + __cl_ulong4 v4[2]; +#endif +#if defined( __CL_ULONG8__ ) + __cl_ulong8 v8; +#endif +}cl_ulong8; + +typedef union +{ + cl_ulong CL_ALIGNED(128) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_ulong x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_ulong8 lo, hi; }; +#endif +#if defined( __CL_ULONG2__) + __cl_ulong2 v2[8]; +#endif +#if defined( __CL_ULONG4__) + __cl_ulong4 v4[4]; +#endif +#if defined( __CL_ULONG8__ ) + __cl_ulong8 v8[2]; +#endif +#if defined( __CL_ULONG16__ ) + __cl_ulong16 v16; +#endif +}cl_ulong16; + + +/* --- cl_floatn ---- */ + +typedef union +{ + cl_float CL_ALIGNED(8) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_float x, y; }; + __CL_ANON_STRUCT__ struct{ cl_float s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_float lo, hi; }; +#endif +#if defined( __CL_FLOAT2__) + __cl_float2 v2; +#endif +}cl_float2; + +typedef union +{ + cl_float CL_ALIGNED(16) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_float x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_float s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_float2 lo, hi; }; +#endif +#if defined( __CL_FLOAT2__) + __cl_float2 v2[2]; +#endif +#if defined( __CL_FLOAT4__) + __cl_float4 v4; +#endif +}cl_float4; + +/* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */ +typedef cl_float4 cl_float3; + +typedef union +{ + cl_float CL_ALIGNED(32) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_float x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_float4 lo, hi; }; +#endif +#if defined( __CL_FLOAT2__) + __cl_float2 v2[4]; +#endif +#if defined( __CL_FLOAT4__) + __cl_float4 v4[2]; +#endif +#if defined( __CL_FLOAT8__ ) + __cl_float8 v8; +#endif +}cl_float8; + +typedef union +{ + cl_float CL_ALIGNED(64) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_float x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_float8 lo, hi; }; +#endif +#if defined( __CL_FLOAT2__) + __cl_float2 v2[8]; +#endif +#if defined( __CL_FLOAT4__) + __cl_float4 v4[4]; +#endif +#if defined( __CL_FLOAT8__ ) + __cl_float8 v8[2]; +#endif +#if defined( __CL_FLOAT16__ ) + __cl_float16 v16; +#endif +}cl_float16; + +/* --- cl_doublen ---- */ + +typedef union +{ + cl_double CL_ALIGNED(16) s[2]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_double x, y; }; + __CL_ANON_STRUCT__ struct{ cl_double s0, s1; }; + __CL_ANON_STRUCT__ struct{ cl_double lo, hi; }; +#endif +#if defined( __CL_DOUBLE2__) + __cl_double2 v2; +#endif +}cl_double2; + +typedef union +{ + cl_double CL_ALIGNED(32) s[4]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_double x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_double s0, s1, s2, s3; }; + __CL_ANON_STRUCT__ struct{ cl_double2 lo, hi; }; +#endif +#if defined( __CL_DOUBLE2__) + __cl_double2 v2[2]; +#endif +#if defined( __CL_DOUBLE4__) + __cl_double4 v4; +#endif +}cl_double4; + +/* cl_double3 is identical in size, alignment and behavior to cl_double4. See section 6.1.5. */ +typedef cl_double4 cl_double3; + +typedef union +{ + cl_double CL_ALIGNED(64) s[8]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_double x, y, z, w; }; + __CL_ANON_STRUCT__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7; }; + __CL_ANON_STRUCT__ struct{ cl_double4 lo, hi; }; +#endif +#if defined( __CL_DOUBLE2__) + __cl_double2 v2[4]; +#endif +#if defined( __CL_DOUBLE4__) + __cl_double4 v4[2]; +#endif +#if defined( __CL_DOUBLE8__ ) + __cl_double8 v8; +#endif +}cl_double8; + +typedef union +{ + cl_double CL_ALIGNED(128) s[16]; +#if __CL_HAS_ANON_STRUCT__ + __CL_ANON_STRUCT__ struct{ cl_double x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; + __CL_ANON_STRUCT__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; + __CL_ANON_STRUCT__ struct{ cl_double8 lo, hi; }; +#endif +#if defined( __CL_DOUBLE2__) + __cl_double2 v2[8]; +#endif +#if defined( __CL_DOUBLE4__) + __cl_double4 v4[4]; +#endif +#if defined( __CL_DOUBLE8__ ) + __cl_double8 v8[2]; +#endif +#if defined( __CL_DOUBLE16__ ) + __cl_double16 v16; +#endif +}cl_double16; + +/* Macro to facilitate debugging + * Usage: + * Place CL_PROGRAM_STRING_DEBUG_INFO on the line before the first line of your source. + * The first line ends with: CL_PROGRAM_STRING_DEBUG_INFO \" + * Each line thereafter of OpenCL C source must end with: \n\ + * The last line ends in "; + * + * Example: + * + * const char *my_program = CL_PROGRAM_STRING_DEBUG_INFO "\ + * kernel void foo( int a, float * b ) \n\ + * { \n\ + * // my comment \n\ + * *b[ get_global_id(0)] = a; \n\ + * } \n\ + * "; + * + * This should correctly set up the line, (column) and file information for your source + * string so you can do source level debugging. + */ +#define __CL_STRINGIFY( _x ) # _x +#define _CL_STRINGIFY( _x ) __CL_STRINGIFY( _x ) +#define CL_PROGRAM_STRING_DEBUG_INFO "#line " _CL_STRINGIFY(__LINE__) " \"" __FILE__ "\" \n\n" + +#ifdef __cplusplus +} +#endif + +#if defined(_WIN32) && defined(_MSC_VER) && __CL_HAS_ANON_STRUCT__ + #pragma warning( pop ) +#endif + +#endif /* __CL_PLATFORM_H */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_va_api_media_sharing_intel.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_va_api_media_sharing_intel.h new file mode 100644 index 000000000..9fb8863f2 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_va_api_media_sharing_intel.h @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2008-2023 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H_ +#define OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H_ + +/* +** This header is generated from the Khronos OpenCL XML API Registry. +*/ + +#include + +#include + +/* CL_NO_PROTOTYPES implies CL_NO_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_PROTOTYPES) && !defined(CL_NO_EXTENSION_PROTOTYPES) +#define CL_NO_EXTENSION_PROTOTYPES +#endif + +/* CL_NO_EXTENSION_PROTOTYPES implies + CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES and + CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES: */ +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif +#if defined(CL_NO_EXTENSION_PROTOTYPES) && \ + !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) +#define CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*************************************************************** +* cl_intel_sharing_format_query_va_api +***************************************************************/ +#define cl_intel_sharing_format_query_va_api 1 +#define CL_INTEL_SHARING_FORMAT_QUERY_VA_API_EXTENSION_NAME \ + "cl_intel_sharing_format_query_va_api" + + +#define CL_INTEL_SHARING_FORMAT_QUERY_VA_API_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +/* when cl_intel_va_api_media_sharing is supported */ + +typedef cl_int CL_API_CALL +clGetSupportedVA_APIMediaSurfaceFormatsINTEL_t( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint plane, + cl_uint num_entries, + VAImageFormat* va_api_formats, + cl_uint* num_surface_formats); + +typedef clGetSupportedVA_APIMediaSurfaceFormatsINTEL_t * +clGetSupportedVA_APIMediaSurfaceFormatsINTEL_fn ; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetSupportedVA_APIMediaSurfaceFormatsINTEL( + cl_context context, + cl_mem_flags flags, + cl_mem_object_type image_type, + cl_uint plane, + cl_uint num_entries, + VAImageFormat* va_api_formats, + cl_uint* num_surface_formats) ; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +/*************************************************************** +* cl_intel_va_api_media_sharing +***************************************************************/ +#define cl_intel_va_api_media_sharing 1 +#define CL_INTEL_VA_API_MEDIA_SHARING_EXTENSION_NAME \ + "cl_intel_va_api_media_sharing" + + +#define CL_INTEL_VA_API_MEDIA_SHARING_EXTENSION_VERSION CL_MAKE_VERSION(0, 0, 0) + +typedef cl_uint cl_va_api_device_source_intel; +typedef cl_uint cl_va_api_device_set_intel; + +/* Error codes */ +#define CL_INVALID_VA_API_MEDIA_ADAPTER_INTEL -1098 +#define CL_INVALID_VA_API_MEDIA_SURFACE_INTEL -1099 +#define CL_VA_API_MEDIA_SURFACE_ALREADY_ACQUIRED_INTEL -1100 +#define CL_VA_API_MEDIA_SURFACE_NOT_ACQUIRED_INTEL -1101 + +/* cl_va_api_device_source_intel */ +#define CL_VA_API_DISPLAY_INTEL 0x4094 + +/* cl_va_api_device_set_intel */ +#define CL_PREFERRED_DEVICES_FOR_VA_API_INTEL 0x4095 +#define CL_ALL_DEVICES_FOR_VA_API_INTEL 0x4096 + +/* cl_context_info */ +#define CL_CONTEXT_VA_API_DISPLAY_INTEL 0x4097 + +/* cl_mem_info */ +#define CL_MEM_VA_API_MEDIA_SURFACE_INTEL 0x4098 + +/* cl_image_info */ +#define CL_IMAGE_VA_API_PLANE_INTEL 0x4099 + +/* cl_command_type */ +#define CL_COMMAND_ACQUIRE_VA_API_MEDIA_SURFACES_INTEL 0x409A +#define CL_COMMAND_RELEASE_VA_API_MEDIA_SURFACES_INTEL 0x409B + + +typedef cl_int CL_API_CALL +clGetDeviceIDsFromVA_APIMediaAdapterINTEL_t( + cl_platform_id platform, + cl_va_api_device_source_intel media_adapter_type, + void* media_adapter, + cl_va_api_device_set_intel media_adapter_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices); + +typedef clGetDeviceIDsFromVA_APIMediaAdapterINTEL_t * +clGetDeviceIDsFromVA_APIMediaAdapterINTEL_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_mem CL_API_CALL +clCreateFromVA_APIMediaSurfaceINTEL_t( + cl_context context, + cl_mem_flags flags, + VASurfaceID* surface, + cl_uint plane, + cl_int* errcode_ret); + +typedef clCreateFromVA_APIMediaSurfaceINTEL_t * +clCreateFromVA_APIMediaSurfaceINTEL_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueAcquireVA_APIMediaSurfacesINTEL_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueAcquireVA_APIMediaSurfacesINTEL_t * +clEnqueueAcquireVA_APIMediaSurfacesINTEL_fn CL_API_SUFFIX__VERSION_1_2; + +typedef cl_int CL_API_CALL +clEnqueueReleaseVA_APIMediaSurfacesINTEL_t( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event); + +typedef clEnqueueReleaseVA_APIMediaSurfacesINTEL_t * +clEnqueueReleaseVA_APIMediaSurfacesINTEL_fn CL_API_SUFFIX__VERSION_1_2; + +#if !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) + +extern CL_API_ENTRY cl_int CL_API_CALL +clGetDeviceIDsFromVA_APIMediaAdapterINTEL( + cl_platform_id platform, + cl_va_api_device_source_intel media_adapter_type, + void* media_adapter, + cl_va_api_device_set_intel media_adapter_set, + cl_uint num_entries, + cl_device_id* devices, + cl_uint* num_devices) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_mem CL_API_CALL +clCreateFromVA_APIMediaSurfaceINTEL( + cl_context context, + cl_mem_flags flags, + VASurfaceID* surface, + cl_uint plane, + cl_int* errcode_ret) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueAcquireVA_APIMediaSurfacesINTEL( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +extern CL_API_ENTRY cl_int CL_API_CALL +clEnqueueReleaseVA_APIMediaSurfacesINTEL( + cl_command_queue command_queue, + cl_uint num_objects, + const cl_mem* mem_objects, + cl_uint num_events_in_wait_list, + const cl_event* event_wait_list, + cl_event* event) CL_API_SUFFIX__VERSION_1_2; + +#endif /* !defined(CL_NO_NON_ICD_DISPATCH_EXTENSION_PROTOTYPES) */ + +#ifdef __cplusplus +} +#endif + +#endif /* OPENCL_CL_VA_API_MEDIA_SHARING_INTEL_H_ */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_version.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_version.h new file mode 100644 index 000000000..3844938d5 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/cl_version.h @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2018-2020 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef __CL_VERSION_H +#define __CL_VERSION_H + +/* Detect which version to target */ +#if !defined(CL_TARGET_OPENCL_VERSION) +#pragma message("cl_version.h: CL_TARGET_OPENCL_VERSION is not defined. Defaulting to 300 (OpenCL 3.0)") +#define CL_TARGET_OPENCL_VERSION 300 +#endif +#if CL_TARGET_OPENCL_VERSION != 100 && \ + CL_TARGET_OPENCL_VERSION != 110 && \ + CL_TARGET_OPENCL_VERSION != 120 && \ + CL_TARGET_OPENCL_VERSION != 200 && \ + CL_TARGET_OPENCL_VERSION != 210 && \ + CL_TARGET_OPENCL_VERSION != 220 && \ + CL_TARGET_OPENCL_VERSION != 300 +#pragma message("cl_version: CL_TARGET_OPENCL_VERSION is not a valid value (100, 110, 120, 200, 210, 220, 300). Defaulting to 300 (OpenCL 3.0)") +#undef CL_TARGET_OPENCL_VERSION +#define CL_TARGET_OPENCL_VERSION 300 +#endif + + +/* OpenCL Version */ +#if CL_TARGET_OPENCL_VERSION >= 300 && !defined(CL_VERSION_3_0) +#define CL_VERSION_3_0 1 +#endif +#if CL_TARGET_OPENCL_VERSION >= 220 && !defined(CL_VERSION_2_2) +#define CL_VERSION_2_2 1 +#endif +#if CL_TARGET_OPENCL_VERSION >= 210 && !defined(CL_VERSION_2_1) +#define CL_VERSION_2_1 1 +#endif +#if CL_TARGET_OPENCL_VERSION >= 200 && !defined(CL_VERSION_2_0) +#define CL_VERSION_2_0 1 +#endif +#if CL_TARGET_OPENCL_VERSION >= 120 && !defined(CL_VERSION_1_2) +#define CL_VERSION_1_2 1 +#endif +#if CL_TARGET_OPENCL_VERSION >= 110 && !defined(CL_VERSION_1_1) +#define CL_VERSION_1_1 1 +#endif +#if CL_TARGET_OPENCL_VERSION >= 100 && !defined(CL_VERSION_1_0) +#define CL_VERSION_1_0 1 +#endif + +/* Allow deprecated APIs for older OpenCL versions. */ +#if CL_TARGET_OPENCL_VERSION <= 220 && !defined(CL_USE_DEPRECATED_OPENCL_2_2_APIS) +#define CL_USE_DEPRECATED_OPENCL_2_2_APIS +#endif +#if CL_TARGET_OPENCL_VERSION <= 210 && !defined(CL_USE_DEPRECATED_OPENCL_2_1_APIS) +#define CL_USE_DEPRECATED_OPENCL_2_1_APIS +#endif +#if CL_TARGET_OPENCL_VERSION <= 200 && !defined(CL_USE_DEPRECATED_OPENCL_2_0_APIS) +#define CL_USE_DEPRECATED_OPENCL_2_0_APIS +#endif +#if CL_TARGET_OPENCL_VERSION <= 120 && !defined(CL_USE_DEPRECATED_OPENCL_1_2_APIS) +#define CL_USE_DEPRECATED_OPENCL_1_2_APIS +#endif +#if CL_TARGET_OPENCL_VERSION <= 110 && !defined(CL_USE_DEPRECATED_OPENCL_1_1_APIS) +#define CL_USE_DEPRECATED_OPENCL_1_1_APIS +#endif +#if CL_TARGET_OPENCL_VERSION <= 100 && !defined(CL_USE_DEPRECATED_OPENCL_1_0_APIS) +#define CL_USE_DEPRECATED_OPENCL_1_0_APIS +#endif + +#endif /* __CL_VERSION_H */ diff --git a/src/backends/opencl/third_party/OpenCL-Headers/CL/opencl.h b/src/backends/opencl/third_party/OpenCL-Headers/CL/opencl.h new file mode 100644 index 000000000..ef8dd1e03 --- /dev/null +++ b/src/backends/opencl/third_party/OpenCL-Headers/CL/opencl.h @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2008-2021 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#ifndef __OPENCL_H +#define __OPENCL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#ifdef __cplusplus +} +#endif + +#endif /* __OPENCL_H */ diff --git a/src/backends/opencl/utils/OpenCLTools.hpp b/src/backends/opencl/utils/OpenCLTools.hpp index cc04941b3..45c031260 100644 --- a/src/backends/opencl/utils/OpenCLTools.hpp +++ b/src/backends/opencl/utils/OpenCLTools.hpp @@ -7,9 +7,7 @@ namespace mllm { - - -std::string inline get_kernel_path(const std::string& current_file, const std::string& relative_kernel_path) { +std::string inline get_kernel_path(const std::string ¤t_file, const std::string &relative_kernel_path) { // 将源文件路径转换为 filesystem::path 对象 std::filesystem::path source_path(current_file); // 获取源文件所在的目录 @@ -20,7 +18,6 @@ std::string inline get_kernel_path(const std::string& current_file, const std::s return kernel_path.string(); } - /** * @brief 从一个已在设备上的Tensor获取一个可用于内核计算的Image2D句柄。 * 该函数是算子内部使用的核心工具。 @@ -38,11 +35,10 @@ std::string inline get_kernel_path(const std::string& current_file, const std::s * @return 一个可用于 clSetKernelArg 的 cl_mem 句柄(指向一个Image2D对象)。 */ static inline cl_mem get_image_from_tensor( - const std::shared_ptr& input_tensor, - OpenCLBackend* ocl_backend, - std::vector& temp_storage) -{ - auto& dev_mem = input_tensor->device_memory(); + const std::shared_ptr &input_tensor, + OpenCLBackend *ocl_backend, + std::vector &temp_storage) { + auto &dev_mem = input_tensor->device_memory(); if (dev_mem.type == MEM_TYPE_IMAGE_2D) { return ocl_backend->get_cl_mem(*input_tensor); @@ -70,7 +66,7 @@ static inline cl_mem get_image_from_tensor( wrapper_tensor.device_memory().handle = image_view; wrapper_tensor.device_memory().type = MEM_TYPE_IMAGE_2D; temp_storage.push_back(std::move(wrapper_tensor)); - + return image_view; } @@ -81,7 +77,7 @@ static inline cl_mem get_image_from_tensor( // ==================================================================================== { Tensor temp_image(input_tensor->batch(), input_tensor->head(), input_tensor->sequence(), input_tensor->dimension(), ocl_backend, false); - auto& img_mem = temp_image.device_memory(); + auto &img_mem = temp_image.device_memory(); img_mem.type = MEM_TYPE_IMAGE_2D; img_mem.image_width = input_tensor->dimension() / 4; img_mem.image_height = input_tensor->batch() * input_tensor->head() * input_tensor->sequence(); @@ -89,15 +85,14 @@ static inline cl_mem get_image_from_tensor( cl_mem src_buffer = ocl_backend->get_cl_mem(*input_tensor); cl_mem dst_image = ocl_backend->get_cl_mem(temp_image); - + const size_t origin[3] = {0, 0, 0}; const size_t region[3] = {img_mem.image_width, img_mem.image_height, 1}; cl_int err = clEnqueueCopyBufferToImage( ocl_backend->getQueue(), src_buffer, dst_image, 0, origin, region, - 0, nullptr, nullptr - ); + 0, nullptr, nullptr); check_cl_error(err, "clEnqueueCopyBufferToImage (Fallback Copy)"); temp_storage.push_back(std::move(temp_image)); @@ -105,7 +100,124 @@ static inline cl_mem get_image_from_tensor( } } +/** + * @brief 将一个Tensor的设备内存从Buffer类型原地转换为Image2D类型。 + * + * 该函数直接修改传入Tensor的内部状态。它会分配一个新的Image2D内存, + * 将原始Buffer的数据拷贝过去,然后释放原始的Buffer,最后更新Tensor的内存类型信息。 + * 如果已经是Image2D,则不执行任何操作。 + * + * @param tensor 要转换的Tensor的引用。Tensor必须在OpenCL设备上。 + */ +static inline void tensorGlobal2Image(Tensor &tensor) { + auto ocl_backend = dynamic_cast(tensor.backend()); + if (!ocl_backend) { + throw std::runtime_error("Tensor backend is not OpenCLBackend for tensorGlobal2Image."); + } + + auto &dev_mem = tensor.device_memory(); + + // 如果已经是Image2D,则无需转换 + if (dev_mem.type == MEM_TYPE_IMAGE_2D) { + return; + } + + if (dev_mem.type != MEM_TYPE_BUFFER || dev_mem.handle == nullptr) { + throw std::runtime_error("tensorGlobal2Image requires a valid Buffer on the device."); + } + + if (tensor.dimension() % 4 != 0) { + throw std::runtime_error("Image2D conversion requires the dimension to be a multiple of 4."); + } + + // 1. 创建一个新的Image2D内存对象 + cl_image_format format = {CL_RGBA}; + format.image_channel_data_type = (tensor.dtype() == MLLM_TYPE_F32) ? CL_FLOAT : CL_HALF_FLOAT; + + cl_image_desc desc = {}; + desc.image_type = CL_MEM_OBJECT_IMAGE2D; + desc.image_width = tensor.dimension() / 4; + desc.image_height = tensor.batch() * tensor.head() * tensor.sequence(); + + cl_int err; + cl_mem new_image_handle = clCreateImage(ocl_backend->getContext(), CL_MEM_READ_WRITE, &format, &desc, nullptr, &err); + check_cl_error(err, "clCreateImage in tensorGlobal2Image"); + + // 2. 将数据从旧的Buffer拷贝到新的Image + cl_mem src_buffer_handle = static_cast(dev_mem.handle); + const size_t origin[3] = {0, 0, 0}; + const size_t region[3] = {desc.image_width, desc.image_height, 1}; + err = clEnqueueCopyBufferToImage( + ocl_backend->getQueue(), + src_buffer_handle, new_image_handle, + 0, origin, region, + 0, nullptr, nullptr); + check_cl_error(err, "clEnqueueCopyBufferToImage in tensorGlobal2Image"); + + // 3. 释放旧的Buffer内存 + clReleaseMemObject(src_buffer_handle); + + // 4. 更新Tensor的内部状态 + dev_mem.handle = new_image_handle; + dev_mem.type = MEM_TYPE_IMAGE_2D; + dev_mem.image_width = desc.image_width; + dev_mem.image_height = desc.image_height; +} + +/** + * @brief 将一个Tensor的设备内存从Image2D类型原地转换为Buffer类型。 + * + * 该函数直接修改传入Tensor的内部状态。它会分配一个新的Buffer内存, + * 将原始Image2D的数据拷贝过去,然后释放原始的Image,最后更新Tensor的内存类型信息。 + * 如果已经是Buffer,则不执行任何操作。 + * + * @param tensor 要转换的Tensor的引用。Tensor必须在OpenCL设备上。 + */ +static inline void tensorImage2Global(Tensor &tensor) { + auto ocl_backend = dynamic_cast(tensor.backend()); + if (!ocl_backend) { + throw std::runtime_error("Tensor backend is not OpenCLBackend for tensorImage2Global."); + } + + auto &dev_mem = tensor.device_memory(); + + // 如果已经是Buffer,则无需转换 + if (dev_mem.type == MEM_TYPE_BUFFER) { + return; + } + + if (dev_mem.type != MEM_TYPE_IMAGE_2D || dev_mem.handle == nullptr) { + throw std::runtime_error("tensorImage2Global requires a valid Image2D on the device."); + } + // 1. 创建一个新的Buffer内存对象 + size_t buffer_size = tensor.count() * tensor.dtypeSize(); + cl_int err; + cl_mem new_buffer_handle = clCreateBuffer(ocl_backend->getContext(), CL_MEM_READ_WRITE, buffer_size, nullptr, &err); + check_cl_error(err, "clCreateBuffer in tensorImage2Global"); + + // 2. 将数据从旧的Image拷贝到新的Buffer + cl_mem src_image_handle = static_cast(dev_mem.handle); + const size_t origin[3] = {0, 0, 0}; + const size_t region[3] = {dev_mem.image_width, dev_mem.image_height, 1}; + err = clEnqueueCopyImageToBuffer( + ocl_backend->getQueue(), + src_image_handle, new_buffer_handle, + origin, region, 0, + 0, nullptr, nullptr); + check_cl_error(err, "clEnqueueCopyImageToBuffer in tensorImage2Global"); + + // 3. 释放旧的Image内存 + clReleaseMemObject(src_image_handle); + + // 4. 更新Tensor的内部状态 + dev_mem.handle = new_buffer_handle; + dev_mem.type = MEM_TYPE_BUFFER; + // 清理Image相关的元数据 + dev_mem.image_width = 0; + dev_mem.image_height = 0; + dev_mem.image_row_pitch_in_bytes = 0; +} } // namespace mllm diff --git a/src/models/ling/configuration_bailing_moe.hpp b/src/models/ling/configuration_bailing_moe.hpp index ecfb077a4..63dbf8903 100644 --- a/src/models/ling/configuration_bailing_moe.hpp +++ b/src/models/ling/configuration_bailing_moe.hpp @@ -29,13 +29,13 @@ class BailingMoeNameConfig : public TransformerNameConfig { }; struct BailingMoeConfig : public TransformerConfig { - explicit BailingMoeConfig(int token_limit) : + explicit BailingMoeConfig(int token_limit, string type = "A2.75B") : //"A1.3B" cache_limit(token_limit) { names_config.init(); } int num_experts = 64; // 64 - int num_experts_per_tok = 6; // 6` + int num_experts_per_tok = 6; // 6 int num_shared_experts = 2; // 2 bool norm_topk_prob = true; // true bool use_cache = true; // true @@ -47,19 +47,19 @@ struct BailingMoeConfig : public TransformerConfig { int bos_token_id = 1; int eos_token_id = 126081; // 126081 std::string hidden_act = "silu"; - int hidden_size = 2048; // 2048 - float initializer_range = 0.006; // 0.006 - int intermediate_size = 1408; // 1408 - int moe_intermediate_size = 1408; // 1408 - int max_position_embeddings = 32768; // 32768 - std::string model_type = "ling_moe"; // "ling_moe" - int num_attention_heads = 16; // 16 - int num_hidden_layers = 28; // 28 - int num_key_value_heads = 4; // 4 - double rms_norm_eps = 1e-06; // 1e-06 - float rope_theta = 600000.0; // 600000 - int vocab_size = 126464; // 126464 - int head_dim = hidden_size / num_attention_heads; //2048/16= 128 + int hidden_size = 2048; // 2048 + float initializer_range = 0.006; // 0.006 + int intermediate_size = 1408; // 1408 + int moe_intermediate_size = 1408; // 1408 + int max_position_embeddings = 32768; // 32768 + std::string model_type = "ling_moe"; // "ling_moe" + int num_attention_heads = 16; // 16 + int num_hidden_layers = 28; // 28 + int num_key_value_heads = 4; // 4 + double rms_norm_eps = 1e-06; // 1e-06 + float rope_theta = 600000.0; // 600000 + int vocab_size = 126464; // 126464 + int head_dim = hidden_size / num_attention_heads; // 2048/16= 128 int cache_limit; RoPEType RoPE_type = RoPEType::HFHUBROPE; diff --git a/src/models/ling/mbp/modeling_bailing_moe.hpp b/src/models/ling/mbp/modeling_bailing_moe_mbp.hpp similarity index 97% rename from src/models/ling/mbp/modeling_bailing_moe.hpp rename to src/models/ling/mbp/modeling_bailing_moe_mbp.hpp index 74cae4fa3..414dc3d56 100644 --- a/src/models/ling/mbp/modeling_bailing_moe.hpp +++ b/src/models/ling/mbp/modeling_bailing_moe_mbp.hpp @@ -30,7 +30,7 @@ class BailingMoeMLP final : public Module { std::vector Forward(std::vector inputs, std::vector args) override { auto x = gate_proj(inputs[0]); x = silu(x); - auto y = up_proj(inputs[0]); // ERROR + auto y = up_proj(inputs[0]); x = x * y; x = down_proj(x); return {x}; @@ -122,8 +122,12 @@ class BailingMoeSparseMoeBlock final : public Module { Tensor &topk_weight, Tensor &topk_idx, int layer_idx) { + auto dtype = topk_idx.dtype(); + auto device = topk_idx.device(); + topk_idx = topk_idx.fp32().cpu(); auto idxs = topk_idx.argsort(); // 1, 1, 1, k* batch*seq auto tokens_per_expert = topk_idx.bincount(); // (1, 1, 1, 0) 1, 1, 1, k + idxs = idxs.to(device).to(dtype); auto token_idxs = idxs / num_experts_per_tok; // 1, 1, 1, k* batch*seq int start_idx = 0; int end_idx = start_idx; @@ -136,10 +140,9 @@ class BailingMoeSparseMoeBlock final : public Module { if (!this_token_num) continue; end_idx = start_idx + this_token_num; // - auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s - auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s - topk_weight = topk_weight.view(-1, -1, 1, 1); - + auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + if (topk_weight.dimension() != 1) { topk_weight = topk_weight.view(-1, -1, 1, 1); } // 1, k* batch*seq, 1, 1 exp_token_idx_list[i] = exp_token_idx; sorted_keys.push_back(i); exp_idx_list[i] = exp_idx; @@ -366,6 +369,7 @@ class BailingMoeModel final : public Module { class BailingMoeForCausalLM final : public Module { public: + CHAINABLE_MODULE_METHODS(BailingMoeForCausalLM) BailingMoeForCausalLM(BailingMoeConfig &config) { auto names = config.names_config; hidden_size = config.hidden_size; diff --git a/src/models/ling/mbp/modeling_bailing_moe_mbmpip.hpp b/src/models/ling/mbp/modeling_bailing_moe_mbppip.hpp similarity index 97% rename from src/models/ling/mbp/modeling_bailing_moe_mbmpip.hpp rename to src/models/ling/mbp/modeling_bailing_moe_mbppip.hpp index 3577a364e..13b1e2d83 100644 --- a/src/models/ling/mbp/modeling_bailing_moe_mbmpip.hpp +++ b/src/models/ling/mbp/modeling_bailing_moe_mbppip.hpp @@ -30,7 +30,7 @@ class BailingMoeMLP final : public Module { std::vector Forward(std::vector inputs, std::vector args) override { auto x = gate_proj(inputs[0]); x = silu(x); - auto y = up_proj(inputs[0]); // ERROR + auto y = up_proj(inputs[0]); x = x * y; x = down_proj(x); return {x}; @@ -122,8 +122,12 @@ class BailingMoeSparseMoeBlock final : public Module { Tensor &topk_weight, Tensor &topk_idx, int layer_idx) { - auto idxs = topk_idx.argsort(); - auto tokens_per_expert = topk_idx.bincount(); + auto dtype = topk_idx.dtype(); + auto device = topk_idx.device(); + topk_idx = topk_idx.fp32().cpu(); + auto idxs = topk_idx.argsort(); // 1, 1, 1, k* batch*seq + auto tokens_per_expert = topk_idx.bincount(); // (1, 1, 1, 0) 1, 1, 1, k + idxs = idxs.to(device).to(dtype); auto token_idxs = idxs / num_experts_per_tok; int start_idx = 0; int end_idx = start_idx; @@ -137,7 +141,7 @@ class BailingMoeSparseMoeBlock final : public Module { end_idx = start_idx + this_token_num; auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); - topk_weight = topk_weight.view(-1, -1, 1, 1); + if (topk_weight.dimension() != 1) { topk_weight = topk_weight.view(-1, -1, 1, 1); } // 1, k* batch*seq, 1, 1 exp_token_idx_list[i] = exp_token_idx; sorted_keys.push_back(i); exp_idx_list[i] = exp_idx; @@ -363,6 +367,7 @@ class BailingMoeModel final : public Module { class BailingMoeForCausalLM final : public Module { public: + CHAINABLE_MODULE_METHODS(BailingMoeForCausalLM) BailingMoeForCausalLM(BailingMoeConfig &config) { auto names = config.names_config; hidden_size = config.hidden_size; diff --git a/src/models/ling/modeling_bailing_moe.hpp b/src/models/ling/modeling_bailing_moe.hpp index e4bdfce7b..3b52bac16 100644 --- a/src/models/ling/modeling_bailing_moe.hpp +++ b/src/models/ling/modeling_bailing_moe.hpp @@ -1,4 +1,5 @@ #pragma once +#include "DataType.hpp" #include "Layer.hpp" #include "Module.hpp" #include "Tensor.hpp" @@ -9,6 +10,8 @@ #include #include #include +#include +#include using namespace mllm; @@ -25,7 +28,7 @@ class BailingMoeMLP final : public Module { std::vector Forward(std::vector inputs, std::vector args) override { auto x = gate_proj(inputs[0]); x = silu(x); - auto y = up_proj(inputs[0]); // ERROR + auto y = up_proj(inputs[0]); x = x * y; x = down_proj(x); return {x}; @@ -100,8 +103,12 @@ class BailingMoeSparseMoeBlock final : public Module { Tensor moe_infer(Tensor hidden_states, Tensor &topk_weight, Tensor &topk_idx) { + auto dtype = topk_idx.dtype(); + auto device = topk_idx.device(); + topk_idx = topk_idx.fp32().cpu(); auto idxs = topk_idx.argsort(); // 1, 1, 1, k* batch*seq auto tokens_per_expert = topk_idx.bincount(); // (1, 1, 1, 0) 1, 1, 1, k + idxs = idxs.to(device).to(dtype); auto token_idxs = idxs / num_experts_per_tok; // 1, 1, 1, k* batch*seq int start_idx = 0; int end_idx = start_idx; @@ -116,14 +123,14 @@ class BailingMoeSparseMoeBlock final : public Module { continue; end_idx = start_idx + this_token_num; // - auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s - auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s - auto expert_tokens = hidden_states.clip(exp_token_idx, SEQUENCE); //(1, 0, 1, hidden) 1, e-s, 1, hidden - auto expert_out = experts[i]({expert_tokens})[0]; //(1, 0, 1, hidden) 1, e-s, 1, - topk_weight = topk_weight.view(-1, -1, 1, 1); // 1, k* batch*seq, 1, 1 - auto expert_weights_clip = topk_weight.clip(exp_idx, SEQUENCE); //(1, 0, 1, 1) 1, e-s, 1, 1 - expert_out = expert_out * expert_weights_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden - expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden + auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto expert_tokens = hidden_states.clip(exp_token_idx, SEQUENCE); //(1, 0, 1, hidden) 1, e-s, 1, hidden + auto expert_out = experts[i]({expert_tokens})[0]; //(1, 0, 1, hidden) 1, e-s, 1, + if (topk_weight.dimension() != 1) { topk_weight = topk_weight.view(-1, -1, 1, 1); } // 1, k* batch*seq, 1, 1 + auto expert_weights_clip = topk_weight.clip(exp_idx, SEQUENCE); //(1, 0, 1, 1) 1, e-s, 1, 1 + expert_out = expert_out * expert_weights_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden + expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden // start_idx = end_idx; } @@ -146,7 +153,8 @@ class BailingMoeDecoder final : public Module { config.num_key_value_heads, config.hidden_size / config.num_attention_heads, SPLIT_HD, PostQkv_NONE, false, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, + config.RoPE_type, config.rope_theta, + config.max_position_embeddings, config.cache_limit, config.use_cache, config.use_qkv_bias, config.use_bias, config.attn_implementation, names, base_name + names._attn_base_name); moe = BailingMoeSparseMoeBlock(config, names, base_name + names._ffn_base_name); @@ -209,7 +217,9 @@ class BailingMoeModel final : public Module { class BailingMoeForCausalLM final : public Module { public: + CHAINABLE_MODULE_METHODS(BailingMoeForCausalLM) BailingMoeForCausalLM(BailingMoeConfig &config) { + dtype = config.dtype; auto names = config.names_config; hidden_size = config.hidden_size; embedding = Embedding(config.vocab_size, config.hidden_size, names.token_embd_name); @@ -218,7 +228,7 @@ class BailingMoeForCausalLM final : public Module { } std::vector Forward(std::vector inputs, std::vector args) override { - auto x = embedding(inputs[0]); + auto x = embedding(inputs[0]).to(dtype); auto outputs = model({x})[0]; if (outputs.sequence() > 1) { outputs = outputs.clip({}, {}, {-1}, {}); @@ -236,4 +246,5 @@ class BailingMoeForCausalLM final : public Module { Layer embedding; Layer lm_head; BailingMoeModel model; + DataType dtype; }; diff --git a/src/models/minicpm/modeling_minicpm.hpp b/src/models/minicpm/modeling_minicpm.hpp index 383a62121..3b3d977d4 100644 --- a/src/models/minicpm/modeling_minicpm.hpp +++ b/src/models/minicpm/modeling_minicpm.hpp @@ -23,7 +23,7 @@ class MiniCPMMLP final : public Module { std::vector Forward(std::vector inputs, std::vector args) override { auto x = gate_proj(inputs[0]); x = silu(x); - auto y = up_proj(inputs[0]); // ERROR + auto y = up_proj(inputs[0]); x = x * y; x = down_proj(x); return {x}; @@ -43,10 +43,10 @@ class MiniCPMDecoder final : public Module { MiniCPMDecoder(const MiniCPMConfig &config, const MiniCPMNameConfig &names, const string &base_name) { self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, config.num_key_value_heads, - config.hidden_size / config.num_attention_heads, + config.hidden_size / config.num_attention_heads, SPLIT_NONE, PostQkv_NONE, false, config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, - true, false,false, + true, false, false, config.attn_implementation, names, base_name + names._attn_base_name); mlp = MiniCPMMLP(config.hidden_size, config.intermediate_size, names, base_name + names._ffn_base_name); diff --git a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp index 217b90bef..64b022dad 100644 --- a/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp +++ b/src/models/minicpm_moe/mbm/modeling_minicpm_moe_mbm.hpp @@ -42,7 +42,7 @@ class MiniCPMMLP final : public Module { std::vector Forward(std::vector inputs, std::vector args) override { auto x = gate_proj(inputs[0]); x = silu(x); - auto y = up_proj(inputs[0]); // ERROR + auto y = up_proj(inputs[0]); x = x * y; x = down_proj(x); return {x}; diff --git a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp index 65ad96e4f..ae3a6fb3b 100644 --- a/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp +++ b/src/models/minicpm_moe/mbp/modeling_minicpm_moe_mbp.hpp @@ -39,7 +39,7 @@ class MiniCPMMLP final : public Module { std::vector Forward(std::vector inputs, std::vector args) override { auto x = gate_proj(inputs[0]); x = silu(x); - auto y = up_proj(inputs[0]); // ERROR + auto y = up_proj(inputs[0]); x = x * y; x = down_proj(x); return {x}; @@ -377,7 +377,6 @@ class MiniCPMForCausalLM final : public Module { MiniCPMForCausalLM(MiniCPMConfig &config) { num_hidden_layers = config.num_hidden_layers; num_experts = config.num_experts; - // KVCache_TYPE = 32; auto names = config.names_config; scale_emb = config.scale_emb; dim_model_base = config.dim_model_base; diff --git a/src/models/minicpm_moe/modeling_minicpm_moe.hpp b/src/models/minicpm_moe/modeling_minicpm_moe.hpp index bf47c4390..7212ffb28 100644 --- a/src/models/minicpm_moe/modeling_minicpm_moe.hpp +++ b/src/models/minicpm_moe/modeling_minicpm_moe.hpp @@ -25,7 +25,7 @@ class MiniCPMMLP final : public Module { std::vector Forward(std::vector inputs, std::vector args) override { auto x = gate_proj(inputs[0]); x = silu(x); - auto y = up_proj(inputs[0]); // ERROR + auto y = up_proj(inputs[0]); x = x * y; x = down_proj(x); return {x}; @@ -177,7 +177,6 @@ class MiniCPMModel final : public Module { class MiniCPMForCausalLM final : public Module { public: MiniCPMForCausalLM(MiniCPMConfig &config) { - // KVCache_TYPE = 32; auto names = config.names_config; scale_emb = config.scale_emb; dim_model_base = config.dim_model_base; diff --git a/src/models/qwen/modeling_qwen.hpp b/src/models/qwen/modeling_qwen.hpp index 689eb4312..73985b6c0 100644 --- a/src/models/qwen/modeling_qwen.hpp +++ b/src/models/qwen/modeling_qwen.hpp @@ -13,9 +13,11 @@ #define MODELING_QWEN_HPP #include "Backend.hpp" +#include "DataType.hpp" #include "Layer.hpp" #include "Module.hpp" #include "Tensor.hpp" +#include "Types.hpp" #include "configuration_qwen.hpp" #include "models/transformer/modeling_transformer.hpp" #include @@ -105,7 +107,9 @@ class QWenModel final : public Module { std::vector Forward(std::vector inputs, std::vector args) override { auto x = inputs[0]; - for (auto &block : blocks) { x = block({x})[0]; } + for (auto &block : blocks) { + x = block({x})[0]; + } x = norm(x); return {x}; } @@ -126,7 +130,9 @@ class QWenModel final : public Module { class QWenForCausalLM final : public Module { public: + CHAINABLE_MODULE_METHODS(QWenForCausalLM) QWenForCausalLM(QWenConfig &config) { + dtype = config.dtype; auto names = config.names_config; hidden_size = config.hidden_size; tie_embedding_words = config.tie_embedding_words; @@ -145,8 +151,7 @@ class QWenForCausalLM final : public Module { } std::vector Forward(std::vector inputs, std::vector args) override { - auto x = embedding(inputs[0]); - + auto x = embedding(inputs[0]).to(dtype); // go through model auto outputs = model({x})[0]; if (outputs.sequence() > 1) { @@ -170,6 +175,7 @@ class QWenForCausalLM final : public Module { Parameter lm_head; Layer lm_head_layer; QWenModel model; + DataType dtype; }; #endif //! MODELING_QWEN_HPP \ No newline at end of file diff --git a/src/models/transformer/configuration_transformer.hpp b/src/models/transformer/configuration_transformer.hpp index c425bb768..3a3dfc711 100644 --- a/src/models/transformer/configuration_transformer.hpp +++ b/src/models/transformer/configuration_transformer.hpp @@ -38,5 +38,6 @@ class TransformerConfig { TransformerConfig() { } string attn_implementation = "flash_attention_2"; // Options: "flash_attention_2", "eager" + DataType dtype = MLLM_TYPE_F32; }; #endif // CONFIGURATION_TRANSFORMER_HPP diff --git a/src/models/transformer/modeling_transformer.hpp b/src/models/transformer/modeling_transformer.hpp index ce186908f..34b38e2fa 100644 --- a/src/models/transformer/modeling_transformer.hpp +++ b/src/models/transformer/modeling_transformer.hpp @@ -5,6 +5,7 @@ #ifndef MODELING_TRANSFORMER_HPP #define MODELING_TRANSFORMER_HPP +#include "DataType.hpp" #include "Layer.hpp" #include "Types.hpp" #include "configuration_transformer.hpp" @@ -23,6 +24,7 @@ struct MultiHeadAttentionConfig { RoPEType RoPE_type = RoPEType::NONE; // Options: NONE, ALIBI, ROPE, PERSIMMONROPE float rope_theta; int max_position_embeddings; + float partial_rotary_factor = 1.0f; // Used for PERSIMMONROPE int cache_limit; bool is_causal; bool qkv_bias; @@ -56,19 +58,33 @@ class MultiHeadAttention final : public Module { public: MultiHeadAttention() = default; MultiHeadAttention(MultiHeadAttentionConfig config, - const TransformerNameConfig &names, const string &base_name) { + const TransformerNameConfig &names, const string &base_name) : MultiHeadAttention(config.hidden_dim, config.num_heads, config.num_key_value_heads, config.head_dim, config.do_qkv_proj, config.post_qkv_norm, config.bias_kv_cat, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, - config.cache_limit, config.is_causal, config.qkv_bias, config.o_bias, - config.attn_implementation, names, base_name); + config.RoPE_type, config.rope_theta, config.partial_rotary_factor, + config.max_position_embeddings, + config.cache_limit, config.is_causal, + config.qkv_bias, config.o_bias, + config.attn_implementation, names, base_name) { } MultiHeadAttention(int hidden_dim, int num_heads, int num_key_value_heads, int head_dim, AttnQKVSplitType do_qkv_proj, AttnPostQkvNormType post_qkv_norm, bool bias_kv_cat, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, bool is_causal, bool qkv_bias, bool o_bias, string attn_implementation, + const TransformerNameConfig &names, const string &base_name) : + MultiHeadAttention(hidden_dim, num_heads, num_key_value_heads, head_dim, + do_qkv_proj, post_qkv_norm, bias_kv_cat, + RoPE_type, rope_theta, 1.0f, max_position_embeddings, + cache_limit, is_causal, qkv_bias, o_bias, + attn_implementation, names, base_name) { + } + MultiHeadAttention(int hidden_dim, int num_heads, int num_key_value_heads, int head_dim, + AttnQKVSplitType do_qkv_proj, AttnPostQkvNormType post_qkv_norm, bool bias_kv_cat, + RoPEType RoPE_type, float rope_theta, float partial_rotary_factor, int max_position_embeddings, + int cache_limit, bool is_causal, bool qkv_bias, bool o_bias, + string attn_implementation, const TransformerNameConfig &names, const string &base_name) { head_dim_ = head_dim; num_heads_ = num_heads; @@ -95,8 +111,8 @@ class MultiHeadAttention final : public Module { k_norm = RMSNorm(head_dim, 1e-6, base_name + names._k_norm_name); } if (RoPE_type > 0) { - q_rope = RoPE(RoPE_type, rope_theta, max_position_embeddings, base_name + "q_rope"); - k_rope = RoPE(RoPE_type, rope_theta, max_position_embeddings, base_name + "k_rope"); + q_rope = RoPE(RoPE_type, rope_theta, partial_rotary_factor, max_position_embeddings, base_name + "q_rope"); + k_rope = RoPE(RoPE_type, rope_theta, partial_rotary_factor, max_position_embeddings, base_name + "k_rope"); } if (cache_limit > 0) { k_cache = KVCache(num_key_value_heads, head_dim, @@ -154,7 +170,7 @@ class MultiHeadAttention final : public Module { q = q_rope(q); k = k_rope(k); } - if (head_first_attn) { + if (attn_implementation_ == "eager") { q = q.transpose(HEAD, SEQUENCE); k = k.transpose(HEAD, SEQUENCE); v = v.transpose(HEAD, SEQUENCE); @@ -168,18 +184,16 @@ class MultiHeadAttention final : public Module { o = Tensor::flash_attention2_forward(q, k, v, causal_mask); } else if (attn_implementation_ == "sage_attention") { o = Tensor::sage_attention_forward(q, k, v, causal_mask); - } else { // eager implementation + } else if (attn_implementation_ == "eager") { // eager implementation + q = q / std::sqrt(head_dim_); k = k.transpose(SEQUENCE, DIMENSION); auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(head_dim_); - if (k_cache.ready() && v_cache.ready()) { + if (k_cache.ready() && v_cache.ready() && k_cache.getCacheSeqLen() != qk.sequence() && qk.sequence() > 1) { qk = softmax(qk, k_cache.getCacheSeqLen()); } else { qk = softmax(qk); } o = Tensor::mm(qk, v); - } - if (head_first_attn) { o = o.transpose(HEAD, SEQUENCE); } o = o.view(-1, 1, -1, head_dim_ * num_heads_); diff --git a/tools/quantizer/QuantWriter.cpp b/tools/quantizer/QuantWriter.cpp index 97d5cc983..273d8e3fc 100644 --- a/tools/quantizer/QuantWriter.cpp +++ b/tools/quantizer/QuantWriter.cpp @@ -25,7 +25,9 @@ const std::vector fp32_layers = { "ln_q", "patch_embed.proj", // "mlp.gate.", - // "lm_head.weight", + // "lm_head.weight", // T + // "query_key_value", // T + // "word_embeddings", // T }; const std::vector q40_layers = { "embed_tokens", @@ -160,7 +162,7 @@ void QuantWriter::quantize(DataType target_quant_type, const std::string &other_ // 预扫描以找到隐藏维度 std::cout << "Pre-scanning to find hidden dimensions..." << std::endl; for (const auto &name : original_param_names_) { - if (tmp_hidden_dim == -1 && (name.find("model") != std::string::npos && name.find("norm") != std::string::npos)) { + if (tmp_hidden_dim == -1 && (name.find("model") != std::string::npos && name.find("norm") != std::string::npos && name.find("k") == std::string::npos && name.find("q") == std::string::npos)) { ParamMetadata meta = param_loader_->getParamMetadata(name); tmp_hidden_dim = meta.size / sizeof(float); std::cout << " - Found hidden dimension (tmp_hidden_dim): " << tmp_hidden_dim << " from layer '" << name << "'" << std::endl; @@ -248,6 +250,7 @@ void QuantWriter::quantize(DataType target_quant_type, const std::string &other_ auto block_t = alloc_kleidiai_quant_block(final_quant_type, N, K); quant_ptr = block_t.first; quant_size = block_t.second; + // std::cout << "N: " << N << ", K: " << K << ", quant_size: " << quant_size << " "; #ifndef KAI_FP16_CAL mllm_kleidai_pack_b_and_bias_qsi4((uint8_t *)quant_ptr, transposed_weight_data.data(), bias_data.empty() ? nullptr : bias_data.data(), N, K); #else From e92b9969e90b3f740f632d8848cfffdf41e87879 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Wed, 6 Aug 2025 14:45:21 +0800 Subject: [PATCH 16/22] feat: add smallthinker --- .gitignore | 1 + examples/CMakeLists.txt | 31 +- examples/demo_bailing_moe.cpp | 2 +- examples/demo_bailing_moe_mbp.cpp | 5 +- examples/demo_smallthinker.cpp | 99 + examples/demo_smallthinker_mbp.cpp | 102 + src/Layer.hpp | 11 +- src/Tensor.cpp | 45 +- src/backends/cpu/CPUBackend.cpp | 63 +- src/backends/cpu/CPUBackend.hpp | 3 + .../ling/mbp/modeling_bailing_moe_mbp_e.hpp | 555 + src/models/ling/mbp/projection_loader.cpp | 104 + .../ling/mbp/settings_bailing_moe_mbp.hpp | 2 +- .../ling/mbp/settings_bailing_moe_mbp_e.hpp | 178 + ...r_bailing.hpp => tokenization_bailing.hpp} | 0 src/models/qwen/configuration_qwen.hpp | 19 + src/models/qwen3/configuration_qwen3.hpp | 20 + .../configuration_smallthinker.hpp | 71 + .../mbp/modeling_smallthinker_mbp.hpp | 433 + .../mbp/settings_smallthinker_mbp.hpp | 145 + .../smallthinker/modeling_smallthinker.hpp | 218 + src/tokenizers/BPE/Bpe.cpp | 79 +- src/tokenizers/BPE/Bpe.hpp | 1 + tools/quantizer/QuantWriter.cpp | 8 +- vocab/smallthinker_merges.txt | 151387 +++++++++++++++ vocab/smallthinker_vocab.mllm | Bin 0 -> 3189859 bytes 26 files changed, 153492 insertions(+), 90 deletions(-) create mode 100644 examples/demo_smallthinker.cpp create mode 100644 examples/demo_smallthinker_mbp.cpp create mode 100644 src/models/ling/mbp/modeling_bailing_moe_mbp_e.hpp create mode 100644 src/models/ling/mbp/projection_loader.cpp create mode 100644 src/models/ling/mbp/settings_bailing_moe_mbp_e.hpp rename src/models/ling/{tokenizer_bailing.hpp => tokenization_bailing.hpp} (100%) create mode 100644 src/models/smallthinker/configuration_smallthinker.hpp create mode 100644 src/models/smallthinker/mbp/modeling_smallthinker_mbp.hpp create mode 100644 src/models/smallthinker/mbp/settings_smallthinker_mbp.hpp create mode 100644 src/models/smallthinker/modeling_smallthinker.hpp create mode 100644 vocab/smallthinker_merges.txt create mode 100644 vocab/smallthinker_vocab.mllm diff --git a/.gitignore b/.gitignore index e71fb0951..a915cc77c 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ src/backends/qnn/sdk/* examples/test.cpp examples/demo_bailing_moe2* src/models/ling2 +scripts/tmp.sh diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 45714a205..6a65b0d15 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -27,28 +27,6 @@ macro(func_set_compile_opts_defs target) endif() endmacro() -# macro(func_link_libs target) -# target_link_libraries(${target} PUBLIC mllm_cpu fmt) -# if (MLLM_OPENMP) -# if (ARM AND NOT (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING)) -# # 非Mac的ARM,静态链接OpenMP -# target_link_libraries(${target} PUBLIC -fopenmp -static-openmp) -# else() -# # 其它平台(含Mac),动态链接OpenMP -# target_link_libraries(${target} PUBLIC -fopenmp) -# endif() -# endif() -# if(OPENCL) -# target_link_libraries(${target} PRIVATE mllm_opencl ${CMAKE_DL_LIBS}) -# endif() -# if (QNN) -# target_link_libraries(${target} PUBLIC mllm_qnn ${CMAKE_DL_LIBS}) -# endif() -# if (MLLM_BUILD_XNNPACK_BACKEND) -# target_link_libraries(${target} PRIVATE mllm_xnnpack) -# endif() -# endmacro() - macro(func_link_libs target) target_link_libraries(${target} PUBLIC mllm_cpu fmt) if (MLLM_OPENMP) @@ -61,7 +39,6 @@ macro(func_link_libs target) endif() endif() if(OPENCL) - # 【关键修正】将 PRIVATE 修改为 PUBLIC,确保 OpenCL 的系统库依赖能最终链接到可执行文件上。 target_link_libraries(${target} PUBLIC mllm_opencl ${CMAKE_DL_LIBS}) endif() if (QNN) @@ -101,6 +78,7 @@ macro(func_vlm_add_executable target) endif() endmacro() +func_llm_add_executable(test) func_llm_add_executable(mllm_benchmark) func_llm_add_executable(demo_llama) func_llm_add_executable(demo_tinyllama) @@ -127,13 +105,14 @@ func_llm_add_executable(demo_phonelm) func_llm_add_executable(demo_llama3) func_llm_add_executable(demo_minicpm_moe_mbm) func_llm_add_executable(demo_qwen_sd) +func_llm_add_executable(demo_qwen_batch) func_llm_add_executable(demo_minicpm_moe_mbp) func_llm_add_executable(demo_bailing_moe) func_llm_add_executable(demo_bailing_moe2) func_llm_add_executable(demo_bailing_moe_mbp) func_llm_add_executable(demo_bailing_moe2_mbp) -func_llm_add_executable(test) -func_llm_add_executable(demo_qwen_batch) +func_llm_add_executable(demo_smallthinker) +func_llm_add_executable(demo_smallthinker_mbp) func_vlm_add_executable(demo_llava) func_vlm_add_executable(demo_fuyu) @@ -151,7 +130,7 @@ if(QNN) func_llm_add_executable(demo_qwen_npu) func_llm_add_executable(demo_phonelm_npu) func_llm_add_executable(demo_qwen2.5_npu) - # func_vlm_add_executable(demo_qwen2_vl_npu) + func_vlm_add_executable(demo_qwen2_vl_npu) func_vlm_add_executable(demo_showui_npu) endif() diff --git a/examples/demo_bailing_moe.cpp b/examples/demo_bailing_moe.cpp index d30d4f69e..75fb23120 100644 --- a/examples/demo_bailing_moe.cpp +++ b/examples/demo_bailing_moe.cpp @@ -9,7 +9,7 @@ #include "cmdline.h" #include "models/ling/configuration_bailing_moe.hpp" #include "models/ling/modeling_bailing_moe.hpp" -#include "models/ling/tokenizer_bailing.hpp" +#include "models/ling/tokenization_bailing.hpp" using namespace mllm; diff --git a/examples/demo_bailing_moe_mbp.cpp b/examples/demo_bailing_moe_mbp.cpp index e9088d762..c0071b45a 100644 --- a/examples/demo_bailing_moe_mbp.cpp +++ b/examples/demo_bailing_moe_mbp.cpp @@ -9,8 +9,9 @@ #include "cmdline.h" #include "models/ling/configuration_bailing_moe.hpp" #include "models/ling/mbp/modeling_bailing_moe_mbp.hpp" +// #include "models/ling/mbp/modeling_bailing_moe_mbp_e.hpp" // #include "models/ling/mbp/modeling_bailing_moe_mbppip.hpp" -#include "models/ling/tokenizer_bailing.hpp" +#include "models/ling/tokenization_bailing.hpp" #include using namespace mllm; @@ -68,7 +69,7 @@ int main(int argc, char **argv) { "项羽已杀卿子冠军,威震楚国,名闻诸侯。乃遣当阳君、蒲将军将卒二万渡河,救巨鹿。战少利,陈馀复请兵。项羽乃悉引兵渡河,皆沉船,破釜甑,烧庐舍,持三日粮,以示士卒必死,无一还心。于是至则围王离,与秦军遇,九战,绝其甬道,大破之,杀苏角,虏王离。涉间不降楚,自烧杀。当是时,楚兵冠诸侯。诸侯军救巨鹿下者十余壁,莫敢纵兵。及楚击秦,诸将皆从壁上观。楚战士无不一以当十,楚兵呼声动天,诸侯军无不人人惴恐。于是已破秦军,项羽召见诸侯将,入辕门,无不膝行而前,莫敢仰视。项羽由是始为诸侯上将军,诸侯皆属焉。 问题:结合项羽在巨鹿之战中的战术决策与心理威慑手段,分析其如何实现『楚战士无不一以当十』的战斗效应,并论述这种军事心理学实践对诸侯将领『膝行而前,莫敢仰视』行为模式的生成机制。", }; - minicpmmoe_mbp_init(config.num_hidden_layers, config.num_experts); + ling_mbp_init(config.num_hidden_layers, config.num_experts); for (int i = 0; i < in_strs.size(); ++i) { auto input_str = tokenizer.apply_chat_template(in_strs[i]); auto input_tensor = tokenizer.tokenize(input_str); diff --git a/examples/demo_smallthinker.cpp b/examples/demo_smallthinker.cpp new file mode 100644 index 000000000..9412e6e7c --- /dev/null +++ b/examples/demo_smallthinker.cpp @@ -0,0 +1,99 @@ +/** + * @file demo_smallthinker.cpp + * @brief A demo for using smallthinker model. + * @author Rongjie Yi + * @date 2025-08-06 + * + */ +#include "Types.hpp" +#include "cmdline.h" +#include "models/smallthinker/configuration_smallthinker.hpp" +#include "models/smallthinker/modeling_smallthinker.hpp" +#include "models/qwen/tokenization_qwen.hpp" + +using namespace mllm; + +int main(int argc, char **argv) { + std::iostream::sync_with_stdio(false); + + cmdline::parser cmdParser; + cmdParser.add("device", 'd', "mllm backend [0:`cpu` | 1:`opencl`]", false, 0); + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/smallthinker_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/smallthinker_merges.txt"); + string default_model_path = "../models/smallthinker-4ba0.6b-instruct-q4_0.mllm"; +#if defined(ARM) + default_model_path = "../models/smallthinker-4ba0.6b-instruct-kai_q4_0.mllm"; +#endif + cmdParser.add("model", 'm', "specify mllm model path", false, default_model_path); + cmdParser.add("limits", 'l', "max KV cache size", false, 500); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + int tokens_limit = cmdParser.get("limits"); + CPUBackend::cpu_threads = cmdParser.get("thread"); + BackendType device = (BackendType)cmdParser.get("device"); + assert((device == MLLM_CPU || device == MLLM_OPENCL) && "device not supports!"); + + auto tokenizer = QWenTokenizer(vocab_path, merge_path); + string chat_template_pre = "<|im_start|>system\nYou are SmallThinker. You are a helpful assistant.<|im_end|>\n<|im_start|>user\n"; + string chat_template_end = "<|im_end|>\n<|im_start|>assistant\n"; + tokenizer.set_chat_template(chat_template_pre, chat_template_end); + SmallThinkerConfig config(tokens_limit, "4ba0.6b-lm"); +#ifdef USE_OPENCL + if (device == MLLM_OPENCL) { + config.dtype = MLLM_TYPE_F16; + config.attn_implementation = "eager"; + model_path = default_model_path; + } +#endif + // config.attn_implementation = "eager"; + // config.attn_implementation = "sage_attention"; + auto model = SmallThinkerForCausalLM(config); +#ifdef USE_OPENCL + model = model.to(device); +#endif + model.load(model_path); + + vector in_strs = { + "Give me a short introduction to large language model.", + "怎样计算1+2+...+100的和?", + "Who are you?", + "背诵天下第一骈文", + "你写一首七言绝句。", + "背诵一下水调歌头。", + "清晨的阳光透过薄纱窗帘,懒洋洋地洒在木地板上,空气中飘散着咖啡豆研磨后特有的醇厚香气。窗外传来几声清脆的鸟鸣,伴随着远处隐约的车流声,构成这座都市尚未完全苏醒的独特交响。书桌上摊开着昨夜未读完的书,书页边缘已微微卷起。厨房里,水壶正发出细密的声响,预示着一天的热饮即将就绪。昨日的计划表贴在冰箱门上,几个重要的待办事项用红笔醒目地圈出。公园里晨练的人们身影绰绰,有节奏的脚步声和太极音乐交织。一只橘猫敏捷地跃上围墙,在晨光中伸展着腰肢,神态悠闲得仿佛它是这片领地的主人。街角的面包店刚拉开铁门,新鲜出炉的面包香气迫不及待地涌向街头。公交站台上,等待的乘客低头刷着手机屏幕,神情各异。云朵缓慢地在湛蓝的天空中移动,时间似乎被拉长了片刻。生活就在这些微小的、平凡的细节里徐徐展开,既不惊天动地,却也充满细碎的温暖和实在的步履。新的一天开始了。\n​​请在以上文本中找出描述“气味”的句子(复制出来),然后判断叙述者对“橘猫”的态度是正面还是负面,最后请用三个成语概括文中描绘的早晨氛围。", + "项羽已杀卿子冠军,威震楚国,名闻诸侯。乃遣当阳君、蒲将军将卒二万渡河,救巨鹿。战少利,陈馀复请兵。项羽乃悉引兵渡河,皆沉船,破釜甑,烧庐舍,持三日粮,以示士卒必死,无一还心。于是至则围王离,与秦军遇,九战,绝其甬道,大破之,杀苏角,虏王离。涉间不降楚,自烧杀。当是时,楚兵冠诸侯。诸侯军救巨鹿下者十余壁,莫敢纵兵。及楚击秦,诸将皆从壁上观。楚战士无不一以当十,楚兵呼声动天,诸侯军无不人人惴恐。于是已破秦军,项羽召见诸侯将,入辕门,无不膝行而前,莫敢仰视。项羽由是始为诸侯上将军,诸侯皆属焉。 问题:结合项羽在巨鹿之战中的战术决策与心理威慑手段,分析其如何实现『楚战士无不一以当十』的战斗效应,并论述这种军事心理学实践对诸侯将领『膝行而前,莫敢仰视』行为模式的生成机制。", + }; + for (int i = 0; i < in_strs.size(); ++i) { + // auto input_str = in_strs[i]; + auto input_str = tokenizer.apply_chat_template(in_strs[i]); + auto input_tensor = tokenizer.tokenize(input_str); + std::cout << "[Q] " << in_strs[i] << std::endl; + std::cout << "[A] " << std::flush; + + LlmTextGeneratorOpts opt{ + .max_new_tokens = static_cast(tokens_limit - input_tensor.sequence()), + .do_sample = false, + .temperature = 0.3F, + .top_k = 50, + .top_p = 0.F, + }; + model.generate(input_tensor, opt, [&](unsigned int out_token) -> bool { + auto out_string = tokenizer.detokenize({out_token}); + auto [not_end, output_string] = tokenizer.postprocess(out_string); + if (!not_end) { return false; } + std::cout << output_string << std::flush; + return true; + }); + /* + auto output_tokens = model.generate(input_tensor, opt, tokenizer.eos_id_)[0]; + auto out_string = tokenizer.detokenize(output_tokens); + std::cout << out_string << std::endl; + */ + std::cout << "\n"; + model.clear_kvcache(); + model.profiling(); + } +} diff --git a/examples/demo_smallthinker_mbp.cpp b/examples/demo_smallthinker_mbp.cpp new file mode 100644 index 000000000..df6fc17cd --- /dev/null +++ b/examples/demo_smallthinker_mbp.cpp @@ -0,0 +1,102 @@ +/** + * @file demo_smallthinker.cpp + * @brief A demo for using smallthinker model. + * @author Rongjie Yi + * @date 2025-08-06 + * + */ +#include "Types.hpp" +#include "cmdline.h" +#include "models/smallthinker/configuration_smallthinker.hpp" +// #include "models/smallthinker/modeling_smallthinker.hpp" +#include "models/smallthinker/mbp/modeling_smallthinker_mbp.hpp" +#include "models/qwen/tokenization_qwen.hpp" + +using namespace mllm; + +int main(int argc, char **argv) { + std::iostream::sync_with_stdio(false); + Module::alloc_mmap = false; + + cmdline::parser cmdParser; + cmdParser.add("device", 'd', "mllm backend [0:`cpu` | 1:`opencl`]", false, 0); + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/smallthinker_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/smallthinker_merges.txt"); + string default_model_path = "../models/smallthinker-4ba0.6b-instruct-q4_0.mllm"; +#if defined(ARM) + default_model_path = "../models/smallthinker-4ba0.6b-instruct-kai_q4_0.mllm"; +#endif + cmdParser.add("model", 'm', "specify mllm model path", false, default_model_path); + cmdParser.add("limits", 'l', "max KV cache size", false, 500); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + int tokens_limit = cmdParser.get("limits"); + CPUBackend::cpu_threads = cmdParser.get("thread"); + BackendType device = (BackendType)cmdParser.get("device"); + assert((device == MLLM_CPU || device == MLLM_OPENCL) && "device not supports!"); + + auto tokenizer = QWenTokenizer(vocab_path, merge_path); + string chat_template_pre = "<|im_start|>system\nYou are SmallThinker. You are a helpful assistant.<|im_end|>\n<|im_start|>user\n"; + string chat_template_end = "<|im_end|>\n<|im_start|>assistant\n"; + tokenizer.set_chat_template(chat_template_pre, chat_template_end); + SmallThinkerConfig config(tokens_limit, "4ba0.6b-lm"); +#ifdef USE_OPENCL + if (device == MLLM_OPENCL) { + config.dtype = MLLM_TYPE_F16; + config.attn_implementation = "eager"; + model_path = default_model_path; + } +#endif + // config.attn_implementation = "eager"; + // config.attn_implementation = "sage_attention"; + auto model = SmallThinkerForCausalLM(config); +#ifdef USE_OPENCL + model = model.to(device); +#endif + model.load(model_path); + + vector in_strs = { + "Give me a short introduction to large language model.", + "怎样计算1+2+...+100的和?", + "Who are you?", + "背诵天下第一骈文", + "你写一首七言绝句。", + "背诵一下水调歌头。", + "清晨的阳光透过薄纱窗帘,懒洋洋地洒在木地板上,空气中飘散着咖啡豆研磨后特有的醇厚香气。窗外传来几声清脆的鸟鸣,伴随着远处隐约的车流声,构成这座都市尚未完全苏醒的独特交响。书桌上摊开着昨夜未读完的书,书页边缘已微微卷起。厨房里,水壶正发出细密的声响,预示着一天的热饮即将就绪。昨日的计划表贴在冰箱门上,几个重要的待办事项用红笔醒目地圈出。公园里晨练的人们身影绰绰,有节奏的脚步声和太极音乐交织。一只橘猫敏捷地跃上围墙,在晨光中伸展着腰肢,神态悠闲得仿佛它是这片领地的主人。街角的面包店刚拉开铁门,新鲜出炉的面包香气迫不及待地涌向街头。公交站台上,等待的乘客低头刷着手机屏幕,神情各异。云朵缓慢地在湛蓝的天空中移动,时间似乎被拉长了片刻。生活就在这些微小的、平凡的细节里徐徐展开,既不惊天动地,却也充满细碎的温暖和实在的步履。新的一天开始了。\n​​请在以上文本中找出描述“气味”的句子(复制出来),然后判断叙述者对“橘猫”的态度是正面还是负面,最后请用三个成语概括文中描绘的早晨氛围。", + "项羽已杀卿子冠军,威震楚国,名闻诸侯。乃遣当阳君、蒲将军将卒二万渡河,救巨鹿。战少利,陈馀复请兵。项羽乃悉引兵渡河,皆沉船,破釜甑,烧庐舍,持三日粮,以示士卒必死,无一还心。于是至则围王离,与秦军遇,九战,绝其甬道,大破之,杀苏角,虏王离。涉间不降楚,自烧杀。当是时,楚兵冠诸侯。诸侯军救巨鹿下者十余壁,莫敢纵兵。及楚击秦,诸将皆从壁上观。楚战士无不一以当十,楚兵呼声动天,诸侯军无不人人惴恐。于是已破秦军,项羽召见诸侯将,入辕门,无不膝行而前,莫敢仰视。项羽由是始为诸侯上将军,诸侯皆属焉。 问题:结合项羽在巨鹿之战中的战术决策与心理威慑手段,分析其如何实现『楚战士无不一以当十』的战斗效应,并论述这种军事心理学实践对诸侯将领『膝行而前,莫敢仰视』行为模式的生成机制。", + }; + mbp_init(config.num_hidden_layers, config.num_experts); + for (int i = 0; i < in_strs.size(); ++i) { + auto input_str = tokenizer.apply_chat_template(in_strs[i]); + auto input_tensor = tokenizer.tokenize(input_str); + std::cout << "[Q] " << in_strs[i] << std::endl; + std::cout << "[A] " << std::flush; + + LlmTextGeneratorOpts opt{ + .max_new_tokens = static_cast(tokens_limit - input_tensor.sequence()), + .do_sample = false, + .temperature = 0.3F, + .top_k = 50, + .top_p = 0.F, + }; + model.generate(input_tensor, opt, [&](unsigned int out_token) -> bool { + auto out_string = tokenizer.detokenize({out_token}); + auto [not_end, output_string] = tokenizer.postprocess(out_string); + if (!not_end) { return false; } + std::cout << output_string << std::flush; + return true; + }); + /* + auto output_tokens = model.generate(input_tensor, opt, tokenizer.eos_id_)[0]; + auto out_string = tokenizer.detokenize(output_tokens); + std::cout << out_string << std::endl; + */ + std::cout << "\n"; + model.clear_kvcache(); + model.profiling(); + // prinMBPtimes("10_"); + } +} diff --git a/src/Layer.hpp b/src/Layer.hpp index 509bb59de..0bb4833b7 100644 --- a/src/Layer.hpp +++ b/src/Layer.hpp @@ -114,8 +114,7 @@ class Layer { // 统一入口 vector run(vector inputs, int N = 1) { // auto start_time = mllm_time_us(); - - // ==================== [开始] 前向计算 ====================// + // ==================== [开始] op ====================// Module *module = inputs.empty() ? Module::llm_model_ptr : inputs[0].module(); /*** part.1 change backend(if) ***/ if (module && module->doChangeBn) { @@ -160,10 +159,10 @@ class Layer { std::string tensor_name = (N > 1) ? "out-" + op_->name() + "-" + std::to_string(i) : "out-" + op_->name(); out_names.push_back(tensor_name); } - // ==================== [结束] 前向计算 ====================// - // if (inputs[0].dimension() > 0) { - // auto time_end = mllm_time_us(); - // std::cout << name_ << " dispatch Layer in " << (time_end - start_time) / 1000.0F << " ms" << std::endl; + // ==================== [结束] op ====================// + // if (module && !module->doTrace) { + // auto end_time = mllm_time_us(); + // std::cout << name_ << " dispatch Layer in " << (end_time - start_time) / 1000.0F << " ms" << std::endl; // } return backend->runOp(op_, inputs, out_names, false); } diff --git a/src/Tensor.cpp b/src/Tensor.cpp index d164fe1dd..e483fc2a5 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -357,8 +357,7 @@ std::vector Tensor::runFunc(std::vector out_names, std::vector input_tensors, bool in_place) { // auto start_time = mllm_time_us(); - - // ==================== [开始] Op 缓存修改 ==================== + // ==================== [开始] Op 缓存 ==================== if (!input_tensors.empty()) { for (auto &input : input_tensors) { assert(input.backend() == input_tensors[0].backend() && "All inputs must have the same backend."); @@ -368,19 +367,21 @@ std::vector Tensor::runFunc(std::vector out_names, if (Backend::global_backends.size() == 2 && Backend::global_backends.find(MLLM_QNN) != Backend::global_backends.end()) { // 针对QNN的特殊处理 backend = Backend::global_backends[MLLM_QNN].get(); } - - // 1. 在函数内部创建一个静态缓存池,它只初始化一次,并在多次调用中保持存在。 - static std::unordered_map> op_cache; + // 1. 使用更高效的键生成方式 + static std::unordered_map> op_cache; // 改用size_t作为键类型 param["type"] = type; std::shared_ptr op_to_run; - // 2. 生成唯一的缓存键 (Cache Key) - std::stringstream key_stream; - key_stream << static_cast(type); // 加入 OpType + // 2. 使用更高效的哈希键生成 + static auto hash_combine = [](size_t seed, const auto &v) { + seed ^= std::hash>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + }; + size_t key = std::hash{}(static_cast(type)); for (const auto &pair : param) { - key_stream << ';' << pair.first << ':' << pair.second; // 加入所有参数 + key = hash_combine(key, pair.first); + key = hash_combine(key, pair.second); } - const auto key = key_stream.str(); - // 3. 查找缓存 + // 3. 查找缓存 - 现在使用更快的size_t哈希查找 auto it = op_cache.find(key); if (it != op_cache.end()) { op_to_run = it->second; @@ -396,10 +397,12 @@ std::vector Tensor::runFunc(std::vector out_names, op_to_run = std::move(op_new); op_cache[key] = op_to_run; } - // ==================== [结束] Op 缓存修改 ==================== - // if (input_tensors[0].dimension() > 0) { - // auto time_end = mllm_time_us(); - // std::cout << out_names[0] << " dispatch Func: " << type << " in " << (time_end - start_time) / 1000.0F << " ms" << std::endl; + // ==================== [结束] Op 缓存 ==================== + // Module *module = Module::llm_model_ptr; + // if (module && !module->doTrace) { + // auto end_time = mllm_time_us(); + // string name_o = out_names.empty() ? "out-" + input_tensors[0].name() : out_names[0]; + // std::cout << name_o << " dispatch Func: " << type << " in " << (end_time - start_time) / 1000.0F << " ms" << std::endl; // } // 4. 使用缓存的或新创建的 Op 执行计算 return backend->runOp(op_to_run.get(), input_tensors, out_names, in_place); @@ -524,8 +527,8 @@ Tensor Tensor::clip(vector b, vector h, vector s, vector d) for (int i = 0; i < h.size(); ++i) param["h_" + std::to_string(i)] = (float)h[i]; for (int i = 0; i < s.size(); ++i) param["s_" + std::to_string(i)] = (float)s[i]; for (int i = 0; i < d.size(); ++i) param["d_" + std::to_string(i)] = (float)d[i]; - string name_su = "clip-"; - if (!(d.size() == 2 && b.empty() && h.empty() && s.empty())) { + string name_su = "-clip-"; + if (!(d.empty() && b.empty() && h.empty() && s.empty())) { for (auto as : param) { name_su += std::to_string(int(as.second)) + "_"; } @@ -668,22 +671,22 @@ vector Tensor::topk(Tensor input, int k, Chl dim) { Tensor Tensor::sum(Chl dim) { OpParam param; param["dim"] = (float)dim; - return runFunc({name() + "sum"}, F_SUM, param, + return runFunc({name() + "-sum"}, F_SUM, param, {*this})[0]; } Tensor Tensor::argsort() { - return runFunc({name() + "argsort"}, F_ARGSORT, {}, + return runFunc({name() + "-argsort"}, F_ARGSORT, {}, {*this})[0]; } Tensor Tensor::bincount() { - return runFunc({name() + "bincount"}, F_BINCOUNT, {}, + return runFunc({name() + "-bincount"}, F_BINCOUNT, {}, {*this})[0]; } Tensor Tensor::repeat(Chl dim, int dim_size) { OpParam param; param["dim"] = (float)dim; param["dim_size"] = (float)dim_size; - return runFunc({name() + "repeat"}, F_REPEAT, param, + return runFunc({name() + "-repeat"}, F_REPEAT, param, {*this})[0]; } Tensor Tensor::masked_fill(Tensor mask_index, float value) { diff --git a/src/backends/cpu/CPUBackend.cpp b/src/backends/cpu/CPUBackend.cpp index 6e3ae45c2..b61d64a88 100644 --- a/src/backends/cpu/CPUBackend.cpp +++ b/src/backends/cpu/CPUBackend.cpp @@ -1,4 +1,5 @@ #include "CPUBackend.hpp" +#include #include #include #include @@ -8,15 +9,16 @@ #include "Backend.hpp" #include "OpDefined.hpp" #include "Types.hpp" -#include "memory/SystemMemoryManager.hpp" -#include +// #include "memory/SystemMemoryManager.hpp" +// #include +#include #include "Layer.hpp" #include "op/CPUHeadLinear.hpp" #include "op/CPULinearInt8.hpp" #include "op/CPUMultimodalRoPEPipeline.hpp" #include "op/CPUNTKRoPE.hpp" -#include "op/CPUPoEmbedding.hpp" +// #include "op/CPUPoEmbedding.hpp" #include "op/CPUSplitInput.hpp" #include "op/CPUView.hpp" #include "op/CPUAdd.hpp" @@ -47,7 +49,7 @@ #include "op/CPUVisionRoPE.hpp" #include "op/CPUMultimodalRoPE.hpp" #include "op/CPUParameter.hpp" -#include "op/CPUCat.hpp" +// #include "op/CPUCat.hpp" #include "op/CPUSubDim.hpp" #include "op/CPUQuickGELU.hpp" #include "op/CPUDivision.hpp" @@ -376,14 +378,13 @@ std::vector CPUBackend::runOp(Op *op, std::vector inputs, std::v #ifdef DEBUGOPTIME uint64_t time_end = mllm_time_us(); double inference_time_ = (time_end - time_start) / 1000.0F; // ms - if (op->name().empty()) { - if (out_names.size() > 0) - std::cout << out_names[0] << " | time: " << inference_time_ << "ms" << std::endl; - else - std::cout << "Unnamed Op | time: " << inference_time_ << "ms" << std::endl; - } else { - std::cout << op->name() << " | time: " << inference_time_ << "ms" << std::endl; + static int op_count = 0; + if (op_inference_time_.empty()) { + op_count = 0; } + string name = std::to_string(op_count++) + "--" + (op->name().empty() ? (out_names.empty() ? "out-" + input_tensors[0]->name() : out_names[0]) : op->name()); + if (op->type() == LINEAR) + op_inference_time_[name] = inference_time_; #endif vector results; @@ -431,17 +432,53 @@ std::vector CPUBackend::runForward(Module *module, std::vector i module->decoding_token_size_ = inputs[0].sequence() * inputs[0].batch(); } time_start = mllm_time_us(); +#ifdef DEBUGOPTIME + op_inference_time_.clear(); +#endif } - // Module setUp & execute auto output = module->Forward(inputs, args); if (ouilter_flag) { time_end = mllm_time_us(); double inference_time_ = (time_end - time_start) / 1000.0F; // ms module->inference_times_.push_back(inference_time_); - mllm::Module::llm_model_ptr->op_transposed_flag = true; +#ifdef DEBUGOPTIME + _print_op_inference_time(true); + std::cout << "Token inference e2e time: " << inference_time_ << "ms" << std::endl; +#endif } return output; } + +void CPUBackend::_print_op_inference_time(bool sort) { + size_t max_len = 0; + for (const auto &pair : op_inference_time_) { + max_len = std::max(pair.first.size(), max_len); + } + std::vector> sorted_pairs; + if (sort) { + sorted_pairs.assign(op_inference_time_.begin(), op_inference_time_.end()); + std::sort(sorted_pairs.begin(), sorted_pairs.end(), + [](const auto &a, const auto &b) { + return a.second > b.second; + }); + } + double token_inference_time = 0.0; + if (sort) { + for (const auto &pair : sorted_pairs) { + std::cout << std::left << std::setw(max_len) << pair.first + << " | time: " << pair.second << "ms" << std::endl; + token_inference_time += pair.second; + } + } else { + for (const auto &pair : op_inference_time_) { + std::cout << std::left << std::setw(max_len) << pair.first + << " | time: " << pair.second << "ms" << std::endl; + token_inference_time += pair.second; + } + } + std::cout << "Op times sum: " << token_inference_time << "ms" << std::endl; +} + } // namespace mllm diff --git a/src/backends/cpu/CPUBackend.hpp b/src/backends/cpu/CPUBackend.hpp index b4767fdac..f5767cee8 100644 --- a/src/backends/cpu/CPUBackend.hpp +++ b/src/backends/cpu/CPUBackend.hpp @@ -4,6 +4,7 @@ #include "Backend.hpp" #include "Op.hpp" #include "Types.hpp" +#include // #include "backends/cpu/third_party/ggml/Quantize.hpp" namespace mllm { @@ -127,6 +128,8 @@ class CPUBackend final : public Backend { Module *module, map> &activation_tensors, Backend *backend); + map op_inference_time_; + void _print_op_inference_time(bool sort = false); }; } // namespace mllm diff --git a/src/models/ling/mbp/modeling_bailing_moe_mbp_e.hpp b/src/models/ling/mbp/modeling_bailing_moe_mbp_e.hpp new file mode 100644 index 000000000..096dfc0c8 --- /dev/null +++ b/src/models/ling/mbp/modeling_bailing_moe_mbp_e.hpp @@ -0,0 +1,555 @@ +#pragma once +#include "DataType.hpp" +#include "Layer.hpp" +#include "Module.hpp" +#include "Tensor.hpp" +#include "Trace.hpp" +#include "Types.hpp" +#include "../configuration_bailing_moe.hpp" +#include "settings_bailing_moe_mbp_e.hpp" +#include "models/transformer/modeling_transformer.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _OPENMP +#include +#endif +#if defined(__ARM_NEON) && !defined(__APPLE__) +#include +#include +#endif +#define MBP_THREAD + +using namespace mllm; + +class BailingMoeMLP final : public Module { +public: + BailingMoeMLP() = default; + BailingMoeMLP(int hidden_size, int intermediate_size, const BailingMoeNameConfig &names, const std::string &base_name) { + gate_proj = Linear(hidden_size, intermediate_size, false, base_name + names._gate_proj_name); + silu = SiLU(base_name + "act"); + up_proj = Linear(hidden_size, intermediate_size, false, base_name + names._up_proj_name); + down_proj = Linear(intermediate_size, hidden_size, false, base_name + names._down_proj_name); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + // 检查是否为 MoE 专家调用(需要 layer_idx 和 expert_idx) + if (args.size() >= 2) { + // MoE 专家模式:使用异步加载 + int layer_idx = std::any_cast(args[0]); + int expert_idx = std::any_cast(args[1]); + int next_expert_idx = args.size() > 2 ? std::any_cast(args[2]) : -1; + int next_layer_idx = args.size() > 3 ? std::any_cast(args[3]) : -1; + + // 等待gate_proj加载完成 +#ifdef MBP_THREAD + { + double wait_start_time = (mllm_time_us() - start_time) / 1000.0F; // ms + std::unique_lock lock(*proj_mtxs[layer_idx][expert_idx][0]); // gate_proj + proj_cvs[layer_idx][expert_idx][0]->wait(lock, [&] { + return proj_dones[layer_idx][expert_idx][0].load(std::memory_order_acquire) || gate_proj.loaded(); + }); + double wait_end_time = (mllm_time_us() - start_time) / 1000.0F; // ms + std::string wait_key = std::to_string(layer_idx) + "_" + std::to_string(expert_idx) + "_gate_wait"; + expert_wait_times[wait_key] = {wait_start_time, wait_end_time}; + } + // 计算gate_proj时异步加载up_proj (只有当前专家需要时才加载) + if (!proj_dones[layer_idx][expert_idx][1].load(std::memory_order_acquire) && !up_proj.loaded()) { + ProjectionLoadRequest req{layer_idx, expert_idx, 1}; // 1: up_proj + { + std::lock_guard lk(projection_queue_mutex); + projection_load_requests.push(req); + } + projection_queue_cv.notify_one(); + } +#endif + assert(gate_proj.loaded() && "gate_proj should be loaded"); + double gate_start_time = (mllm_time_us() - start_time) / 1000.0F; // ms + auto x = gate_proj(inputs[0]); + x = silu(x); + double gate_end_time = (mllm_time_us() - start_time) / 1000.0F; // ms + std::string gate_key = std::to_string(layer_idx) + "_" + std::to_string(expert_idx) + "_gate"; + expert_cal_times[gate_key] = {gate_start_time, gate_end_time}; + + // gate_proj计算完成后立即释放,然后请求down_proj +#ifdef MBP_THREAD + gate_proj.free(); + if (!proj_dones[layer_idx][expert_idx][2].load(std::memory_order_acquire) && !down_proj.loaded()) { + ProjectionLoadRequest req{layer_idx, expert_idx, 2}; // 2: down_proj + { + std::lock_guard lk(projection_queue_mutex); + projection_load_requests.push(req); + } + projection_queue_cv.notify_one(); + } +#endif + + // 等待up_proj加载完成并计算 +#ifdef MBP_THREAD + { + double wait_start_time = (mllm_time_us() - start_time) / 1000.0F; // ms + std::unique_lock lock(*proj_mtxs[layer_idx][expert_idx][1]); // up_proj + proj_cvs[layer_idx][expert_idx][1]->wait(lock, [&] { + return proj_dones[layer_idx][expert_idx][1].load(std::memory_order_acquire) || up_proj.loaded(); + }); + double wait_end_time = (mllm_time_us() - start_time) / 1000.0F; // ms + std::string wait_key = std::to_string(layer_idx) + "_" + std::to_string(expert_idx) + "_up_wait"; + expert_wait_times[wait_key] = {wait_start_time, wait_end_time}; + } +#endif + assert(up_proj.loaded() && "up_proj should be loaded"); + double up_start_time = (mllm_time_us() - start_time) / 1000.0F; // ms + auto y = up_proj(inputs[0]); + x = x * y; + double up_end_time = (mllm_time_us() - start_time) / 1000.0F; // ms + std::string up_key = std::to_string(layer_idx) + "_" + std::to_string(expert_idx) + "_up"; + expert_cal_times[up_key] = {up_start_time, up_end_time}; + + // up_proj计算完成后立即释放,然后请求下一个专家的gate_proj +#ifdef MBP_THREAD + up_proj.free(); + // 请求下一个专家的gate_proj (只有确定需要时才预加载) + if (next_expert_idx >= 0) { + // 检查下一个专家的gate_proj是否需要预加载 + if (!proj_dones[layer_idx][next_expert_idx][0].load(std::memory_order_acquire)) { + ProjectionLoadRequest req{layer_idx, next_expert_idx, 0}; // 0: gate_proj + { + std::lock_guard lk(projection_queue_mutex); + projection_load_requests.push(req); + } + projection_queue_cv.notify_one(); + } + } else if (next_layer_idx >= 0) { + // 检查下一层第一个专家的gate_proj是否需要预加载 + if (!proj_dones[next_layer_idx][0][0].load(std::memory_order_acquire)) { + ProjectionLoadRequest req{next_layer_idx, 0, 0}; // 下一层第一个专家的gate_proj + { + std::lock_guard lk(projection_queue_mutex); + projection_load_requests.push(req); + } + projection_queue_cv.notify_one(); + } + } +#endif + + // 等待down_proj加载完成并计算 +#ifdef MBP_THREAD + { + double wait_start_time = (mllm_time_us() - start_time) / 1000.0F; // ms + std::unique_lock lock(*proj_mtxs[layer_idx][expert_idx][2]); // down_proj + proj_cvs[layer_idx][expert_idx][2]->wait(lock, [&] { + return proj_dones[layer_idx][expert_idx][2].load(std::memory_order_acquire) || down_proj.loaded(); + }); + double wait_end_time = (mllm_time_us() - start_time) / 1000.0F; // ms + std::string wait_key = std::to_string(layer_idx) + "_" + std::to_string(expert_idx) + "_down_wait"; + expert_wait_times[wait_key] = {wait_start_time, wait_end_time}; + } +#endif + assert(down_proj.loaded() && "down_proj should be loaded"); + double down_start_time = (mllm_time_us() - start_time) / 1000.0F; // ms + x = down_proj(x); + double down_end_time = (mllm_time_us() - start_time) / 1000.0F; // ms + std::string down_key = std::to_string(layer_idx) + "_" + std::to_string(expert_idx) + "_down"; + expert_cal_times[down_key] = {down_start_time, down_end_time}; + + // down_proj计算完成后立即释放 +#ifdef MBP_THREAD + down_proj.free(); +#endif + return {x}; + } else { + // 普通 MLP 模式:直接计算,不使用异步加载 + auto x = gate_proj(inputs[0]); + x = silu(x); + auto y = up_proj(inputs[0]); + x = x * y; + x = down_proj(x); + return {x}; + } + } + + void load() { + gate_proj.load(); + up_proj.load(); + down_proj.load(); + } + + bool loaded() { + return gate_proj.loaded() && up_proj.loaded() && down_proj.loaded(); + } + + void free() { + gate_proj.free(); + up_proj.free(); + down_proj.free(); + } + + // 将成员变量改为公有,以便异步加载时访问 + Layer gate_proj; + Layer up_proj; + Layer down_proj; + +private: + Layer silu; +}; + +class BailingMoeGate final : public Module { +public: + BailingMoeGate() = default; + BailingMoeGate(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const std::string &base_name) { + gate = Linear(config.hidden_size, config.num_experts, false, base_name + "gate"); + softmax = Softmax(DIMENSION, false, base_name + "softmax"); + num_experts_per_tok = config.num_experts_per_tok; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto scores = softmax(gate(inputs[0])); + auto experts_w_i = Tensor::topk(scores, num_experts_per_tok, DIMENSION); + auto topk_weight = experts_w_i[0]; // 1, batch*seq, 1, k + auto topk_idx = experts_w_i[1]; // 1, batch*seq, 1, k + topk_idx = topk_idx.view(-1, 1, 1, -1); // 1, 1, 1, k* batch*seq + topk_weight = topk_weight / topk_weight.sum(DIMENSION); // 1, batch*seq, 1, k + return {scores, topk_weight, topk_idx}; + } + +private: + Layer gate; + Softmax softmax; + int num_experts_per_tok{}; +}; + +class BailingMoeSparseMoeBlock final : public Module { +public: + BailingMoeSparseMoeBlock() = default; + BailingMoeSparseMoeBlock(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + experts = List(config.num_experts, config.hidden_size, config.moe_intermediate_size, names, base_name + "experts."); + gate = BailingMoeGate(config, names, base_name); + num_experts_per_tok = config.num_experts_per_tok; + num_shared_experts = config.num_shared_experts; + num_hidden_layers = config.num_hidden_layers; // 添加层数信息 + if (num_shared_experts > 0) { + shared_experts = BailingMoeMLP(config.hidden_size, + config.moe_intermediate_size * config.num_shared_experts, + names, base_name + "shared_experts."); + } + } + + // receive embeds + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + auto identity = hidden_states; + if (hidden_states.batch() > 1) { + hidden_states = hidden_states.view(1, -1, ANYDIM, -1); // 1, batch*seq, 1, hidden + } + auto gates_t = gate({hidden_states}); // 1, batch*seq, 1, num_experts + auto scores = gates_t[0]; // 1, batch*seq, 1, num_experts + auto topk_weight = gates_t[1]; // 1, batch*seq, + auto topk_idx = gates_t[2]; // 1, batch*seq, 1, k + + // 获取层索引用于异步加载 + int layer_idx = args.size() > 0 ? std::any_cast(args[0]) : 0; + hidden_states = moe_infer(hidden_states, topk_weight, topk_idx, layer_idx); // 1, batch*seq, 1, hidden + + if (num_shared_experts) { + hidden_states = hidden_states + shared_experts({identity})[0]; // add shared experts + } + if (hidden_states.batch() > 1) { + // expert_cache.view(ANYDIM, seq, -1, -1);//TODO + } + return {hidden_states}; + } + + Tensor moe_infer(Tensor hidden_states, Tensor &topk_weight, Tensor &topk_idx, int layer_idx = 0) { + auto dtype = topk_idx.dtype(); + auto device = topk_idx.device(); + topk_idx = topk_idx.fp32().cpu(); + auto idxs = topk_idx.argsort(); // 1, 1, 1, k* batch*seq + auto tokens_per_expert = topk_idx.bincount(); // (1, 1, 1, 0) 1, 1, 1, k + idxs = idxs.to(device).to(dtype); + auto token_idxs = idxs / num_experts_per_tok; // 1, 1, 1, k* batch*seq + int start_idx = 0; + int end_idx = start_idx; + auto expert_cache = Tensor::zero_like(hidden_states); // 1, batch*seq, 1, hidden + + // 收集要处理的专家,并存储相关数据 + std::map exp_token_idx_list; + std::map exp_idx_list; + std::vector sorted_keys; + + start_idx = 0; + for (int i = 0; i < experts.size(); ++i) { + if (tokens_per_expert.dimension() != 0 && i >= tokens_per_expert.dimension()) + break; + int this_token_num = tokens_per_expert.dimension() ? tokens_per_expert.d(0, 0, 0, i) : 0; + if (!this_token_num) continue; + end_idx = start_idx + this_token_num; + auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + if (topk_weight.dimension() != 1) { topk_weight = topk_weight.view(-1, -1, 1, 1); } // 1, k* batch*seq, 1, 1 + exp_token_idx_list[i] = exp_token_idx; + sorted_keys.push_back(i); + exp_idx_list[i] = exp_idx; + start_idx = end_idx; + } + + if (!sorted_keys.empty()) { + // 为第一个专家预加载gate_proj + if (!experts[sorted_keys[0]].gate_proj.loaded()) { + double time_start = (mllm_time_us() - start_time) / 1000.0F; // ms + experts[sorted_keys[0]].gate_proj.load(); + std::string expert_name = std::to_string(layer_idx) + "_" + std::to_string(sorted_keys[0]) + "_gate"; + double time_end = (mllm_time_us() - start_time) / 1000.0F; // ms + proj_load_times[expert_name] = {time_start, time_end}; + } +#ifdef MBP_THREAD + // 标记第一个专家的gate_proj为已加载 + proj_dones[layer_idx][sorted_keys[0]][0].store(true, std::memory_order_release); + proj_cvs[layer_idx][sorted_keys[0]][0]->notify_all(); +#endif + } + + for (int ii = 0; ii < sorted_keys.size(); ii++) { + int expert_id = sorted_keys[ii]; + if (exp_token_idx_list.find(expert_id) == exp_token_idx_list.end()) continue; // 退出 + if (Module::doLoad) continue; // 退出 + + // step.1 - 准备输入数据 + double time_start_ = (mllm_time_us() - start_time) / 1000.0F; // ms + + auto exp_token_idx = exp_token_idx_list[expert_id]; //(1, 1, 1, 0) 1, 1, 1, e-s + auto exp_idx = exp_idx_list[expert_id]; //(1, 1, 1, 0) 1, 1, 1, e-s + auto expert_tokens = hidden_states.clip(exp_token_idx, SEQUENCE); //(1, 0, 1, hidden) 1, e-s, 1, hidden + auto topk_weight_clip = topk_weight.clip(exp_idx, SEQUENCE); //(1, 0, 1, 1) 1, e-s, 1, 1 + + std::string expert_name_ = std::to_string(layer_idx) + "_" + std::to_string(expert_id); + double time_end_ = (mllm_time_us() - start_time) / 1000.0F; // ms + expert_clip_times[expert_name_] = {time_start_, time_end_}; + + auto time_start__ = (mllm_time_us()); // ms + double time_start = (time_start__ - start_time) / 1000.0F; // ms + + // step.2 - 执行专家计算(包含投影层级异步加载) + // 准备下一个专家信息 + std::vector mlp_args = {layer_idx, expert_id}; + if (ii < sorted_keys.size() - 1 && exp_token_idx_list[sorted_keys[ii + 1]].dimension() > 0) { + mlp_args.push_back(sorted_keys[ii + 1]); // next_expert_idx + mlp_args.push_back(-1); // next_layer_idx + } else if (ii == sorted_keys.size() - 1 && layer_idx < num_hidden_layers - 1) { + mlp_args.push_back(-1); // next_expert_idx + mlp_args.push_back(layer_idx + 1); // next_layer_idx + } else { + mlp_args.push_back(-1); // next_expert_idx + mlp_args.push_back(-1); // next_layer_idx + } + + auto expert_out = experts[expert_id]({expert_tokens}, mlp_args)[0]; //(1, 0, 1, hidden) 1, e-s, 1, + expert_out = expert_out * topk_weight_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden + expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden + experts[expert_id].free(); + + std::string expert_name = std::to_string(layer_idx) + "_" + std::to_string(expert_id); + auto time_end__ = (mllm_time_us()); // ms + double time_end = (time_end__ - start_time) / 1000.0F; // ms + +#ifdef MBP_THREAD + // 重置投影层状态 + for (int proj_type = 0; proj_type < 3; ++proj_type) { + proj_dones[layer_idx][expert_id][proj_type].store(false, std::memory_order_relaxed); + } +#endif + } + return expert_cache; // 1, batch*seq, 1, hidden + } + + void load_experts(int expert_idx, int flag = -1) { + switch (flag) { + case -1: { + experts[expert_idx].gate_proj.load(); + experts[expert_idx].up_proj.load(); + experts[expert_idx].down_proj.load(); + break; + } + case 0: { + experts[expert_idx].gate_proj.load(); + break; + } + case 1: { + experts[expert_idx].up_proj.load(); + break; + } + case 2: { + experts[expert_idx].down_proj.load(); + break; + } + default: + break; + } + } + +private: + BailingMoeMLP shared_experts; + std::vector experts; + BailingMoeGate gate; + int num_shared_experts{}; + int num_experts_per_tok{}; + int num_hidden_layers{}; // 添加层数信息 +}; + +class BailingMoeDecoder final : public Module { +public: + BailingMoeDecoder() = default; + BailingMoeDecoder(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, + config.hidden_size / config.num_attention_heads, + SPLIT_HD, PostQkv_NONE, false, + config.RoPE_type, config.rope_theta, + config.max_position_embeddings, + config.cache_limit, config.use_cache, config.use_qkv_bias, config.use_bias, + config.attn_implementation, names, base_name + names._attn_base_name); + moe = BailingMoeSparseMoeBlock(config, names, base_name + names._ffn_base_name); + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); + num_hidden_layers = config.num_hidden_layers; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + // 获取层索引,用于传递给 MoE + int layer_idx = args.size() > 0 ? std::any_cast(args[0]) : 0; + + auto hidden_states = input_layernorm(inputs[0]); + hidden_states = self_atten({hidden_states, hidden_states, hidden_states})[0]; + auto tmp = hidden_states + inputs[0]; + hidden_states = post_attention_layernorm(tmp); + + // 传递层索引给 MoE + std::vector moe_args = {layer_idx}; + hidden_states = moe({hidden_states}, moe_args)[0]; + hidden_states = hidden_states + tmp; + return {hidden_states}; + } + + MultiHeadAttention &get_attention() { + return self_atten; + } + + void load_experts(int expert_idx, int projection_type) { + moe.load_experts(expert_idx, projection_type); + } + +private: + MultiHeadAttention self_atten; + BailingMoeSparseMoeBlock moe; + Layer input_layernorm; + Layer post_attention_layernorm; + int num_hidden_layers; +}; + +class BailingMoeModel final : public Module { +public: + BailingMoeModel() = default; + BailingMoeModel(const BailingMoeConfig &config, const BailingMoeNameConfig &names, const string &base_name) { + blocks = List(config.num_hidden_layers, config, names, base_name); + norm = RMSNorm(config.hidden_size, config.rms_norm_eps, names.post_norm_name); + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + for (int i = 0; i < blocks.size(); ++i) { + // 传递层索引给每个decoder block + std::vector block_args = {i}; + hidden_states = blocks[i]({hidden_states}, block_args)[0]; + } + hidden_states = norm(hidden_states); + return {hidden_states}; + } + + void load_experts(int layer_idx, int expert_idx, int projection_type) { + if (layer_idx >= 0 && layer_idx < blocks.size()) { + blocks[layer_idx].load_experts(expert_idx, projection_type); + } + } + + void clear_kvcache() override { + for (auto &block : blocks) { + auto kvcache = block.get_attention().get_cache(); + for (auto &cache : kvcache) { cache->clearCache(); } + auto ropes = block.get_attention().get_rope(); + for (auto &rope : ropes) { rope->clearCache(); } + } + } + +private: + std::vector blocks; + Layer norm; +}; + +class BailingMoeForCausalLM final : public Module { +public: + CHAINABLE_MODULE_METHODS(BailingMoeForCausalLM) + BailingMoeForCausalLM(BailingMoeConfig &config) { + dtype = config.dtype; + auto names = config.names_config; + hidden_size = config.hidden_size; + embedding = Embedding(config.vocab_size, config.hidden_size, names.token_embd_name); + model = BailingMoeModel(config, names, names.blk_name); + lm_head = Linear(config.hidden_size, config.vocab_size, false, names.lm_head_name); + + // 初始化异步加载相关设置 + num_layers = config.num_hidden_layers; + num_experts = config.num_experts; + ling_mbp_init(num_layers, num_experts); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + clearMBPtimes(); + start_time = mllm_time_us(); + + auto x = embedding(inputs[0]).to(dtype); + std::vector empty_args; // 为 model 创建空的参数 + auto outputs = model({x}, empty_args)[0]; + if (outputs.sequence() > 1) { + outputs = outputs.clip({}, {}, {-1}, {}); + } + outputs = lm_head(outputs); + return {outputs}; + } + + void load_projection(int layer_idx, int expert_idx, int projection_type) { + switch (projection_type) { + case 0: // gate_proj + model.load_experts(layer_idx, expert_idx, 0); + break; + case 1: // up_proj + model.load_experts(layer_idx, expert_idx, 1); + break; + case 2: // down_proj + model.load_experts(layer_idx, expert_idx, 2); + break; + default: + model.load_experts(layer_idx, expert_idx, -1); + break; + } + } + + void clear_kvcache() override { + model.clear_kvcache(); + } + +private: + int hidden_size; + bool tie_embedding_words; + Layer embedding; + Layer lm_head; + BailingMoeModel model; + DataType dtype; + int num_layers{}; + int num_experts{}; +}; diff --git a/src/models/ling/mbp/projection_loader.cpp b/src/models/ling/mbp/projection_loader.cpp new file mode 100644 index 000000000..bef508778 --- /dev/null +++ b/src/models/ling/mbp/projection_loader.cpp @@ -0,0 +1,104 @@ +#include "settings_bailing_moe_mbp_e.hpp" +#include "Timing.hpp" + +using namespace std; +using namespace mllm; + +// 投影层加载线程函数的实现 +void projection_loading_thread_func() { + while (!mbp_finish.load(std::memory_order_acquire)) { + std::unique_lock lk(projection_queue_mutex); + projection_queue_cv.wait(lk, [] { + return !projection_load_requests.empty() || mbp_finish.load(std::memory_order_acquire); + }); + + if (mbp_finish.load(std::memory_order_acquire)) { + break; + } + + while (!projection_load_requests.empty()) { + auto req = projection_load_requests.top(); // 从优先队列的顶部取出最高优先级的请求 + projection_load_requests.pop(); + lk.unlock(); + + // 执行投影层加载 + { + std::unique_lock proj_lk(*proj_mtxs[req.layer][req.expert][req.projection_type]); + if (!proj_dones[req.layer][req.expert][req.projection_type].load(std::memory_order_acquire)) { + double time_start = (mllm_time_us() - start_time) / 1000.0F; + + // 使用外部加载函数 + if (load_projection_impl) { + load_projection_impl(req.layer, req.expert, req.projection_type); + } + + proj_dones[req.layer][req.expert][req.projection_type].store(true, std::memory_order_release); + + // 统一key命名格式:{layer}_{expert}_{proj_type} + string proj_type_name; + switch (req.projection_type) { + case 0: proj_type_name = "gate"; break; + case 1: proj_type_name = "up"; break; + case 2: proj_type_name = "down"; break; + default: proj_type_name = "unknown"; break; + } + string proj_name = std::to_string(req.layer) + "_" + std::to_string(req.expert) + "_" + proj_type_name; + double time_end = (mllm_time_us() - start_time) / 1000.0F; + proj_load_times[proj_name] = {time_start, time_end}; + // std::cout << "Projection loaded: " << proj_name << std::endl; + + // 刷新输出缓冲区,确保日志立即显示 + std::cout.flush(); + } + } + proj_cvs[req.layer][req.expert][req.projection_type]->notify_all(); + lk.lock(); + } + } +} + +// clip线程函数的实现 +void clip_thread_func() { + while (!mbp_finish.load(std::memory_order_acquire)) { + std::unique_lock lk(clip_queue_mutex); + clip_queue_cv.wait(lk, [] { + return !clip_requests.empty() || mbp_finish.load(std::memory_order_acquire); + }); + + if (mbp_finish.load(std::memory_order_acquire)) { + break; + } + + while (!clip_requests.empty()) { + auto req = clip_requests.front(); + clip_requests.pop(); + lk.unlock(); + + // 执行clip操作 + { + std::unique_lock clip_lk(*clip_mtxs[req.layer][req.expert]); + if (!clip_dones[req.layer][req.expert].load(std::memory_order_acquire)) { + double time_start = (mllm_time_us() - start_time) / 1000.0F; + + // 执行实际的clip操作 + auto expert_tokens = req.hidden_states.clip(req.exp_token_idx, SEQUENCE); + auto topk_weight_clip = req.topk_weight.clip(req.exp_idx, SEQUENCE); + + // 存储clip结果 + string key = std::to_string(req.layer) + "_" + std::to_string(req.expert); + { + std::lock_guard results_lk(clip_results_mutex); + clipped_data[key] = {expert_tokens, topk_weight_clip}; + } + + clip_dones[req.layer][req.expert].store(true, std::memory_order_release); + + double time_end = (mllm_time_us() - start_time) / 1000.0F; + expert_clip_times[key] = {time_start, time_end}; + } + } + clip_cvs[req.layer][req.expert]->notify_all(); + lk.lock(); + } + } +} diff --git a/src/models/ling/mbp/settings_bailing_moe_mbp.hpp b/src/models/ling/mbp/settings_bailing_moe_mbp.hpp index a0ceedda9..c5c1047cd 100644 --- a/src/models/ling/mbp/settings_bailing_moe_mbp.hpp +++ b/src/models/ling/mbp/settings_bailing_moe_mbp.hpp @@ -67,7 +67,7 @@ inline void reset_syntax_mbm(int layer_idx, int expert_idx) { dones[layer_idx][expert_idx].store(false, std::memory_order_release); } -inline void minicpmmoe_mbp_init(int num_layers, int num_experts) { +inline void ling_mbp_init(int num_layers, int num_experts) { // 初始化 loading 相关的变量 mtxs.resize(num_layers); cvs.resize(num_layers); diff --git a/src/models/ling/mbp/settings_bailing_moe_mbp_e.hpp b/src/models/ling/mbp/settings_bailing_moe_mbp_e.hpp new file mode 100644 index 000000000..7a01dfe52 --- /dev/null +++ b/src/models/ling/mbp/settings_bailing_moe_mbp_e.hpp @@ -0,0 +1,178 @@ +#pragma once +// #include +// #include +#include +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Tensor.hpp" + +using namespace std; +using namespace mllm; + +int mbp_load_layer_idx; +int mbp_load_expert_idx; + +// ========= Fine-grained Loading Globals ========= +// 投影层加载请求结构体,用于细粒度加载 +struct ProjectionLoadRequest { + int layer; + int expert; + int projection_type; // 0: gate_proj, 1: up_proj, 2: down_proj + + // 用于优先队列排序:优先按expert分组,再按projection_type排序 + bool operator<(const ProjectionLoadRequest &other) const { + if (layer != other.layer) return layer > other.layer; // 层号小的优先 + if (expert != other.expert) return expert > other.expert; // 专家号小的优先 + return projection_type > other.projection_type; // gate(0) > up(1) > down(2) + } +}; + +// 投影层加载请求队列和同步对象 +priority_queue projection_load_requests; +mutex projection_queue_mutex; +condition_variable projection_queue_cv; + +// 投影层同步对象 - [layer][expert][projection_type] +vector>>> proj_mtxs; +vector>>> proj_cvs; +vector>>> proj_dones; + +// ========= Clip Thread Globals (NEW) ========= +// 4. 新增 ClipRequest 结构体 +struct ClipRequest { + int layer; + int expert; + Tensor hidden_states; + Tensor exp_token_idx; + Tensor topk_weight; + Tensor exp_idx; +}; +// 5. 新增 clip 线程的任务队列、锁和条件变量 +queue clip_requests; +mutex clip_queue_mutex; +condition_variable clip_queue_cv; +// 6. 新增用于存储 clip 结果的 map 和其互斥锁 +map> clipped_data; +mutex clip_results_mutex; +//============ End Clip Thread Globals ============ + +atomic mbp_finish{false}; // 改为原子布尔 + +// --- Clipping Primitives (NEW) --- +// 新增 clip 线程的同步对象 +vector>> clip_mtxs; +vector>> clip_cvs; +vector>> clip_dones; + +// 修改 MAP_MINICPMMOE_MBP_HPP 中的相关部分 + +inline void reset_syntax_mbm(int layer_idx, int expert_idx) { + // 已移除专家级同步对象,不需要重置 +} + +inline void ling_mbp_init(int num_layers, int num_experts) { + // 初始化细粒度投影层相关的变量 + proj_mtxs.resize(num_layers); + proj_cvs.resize(num_layers); + proj_dones.resize(num_layers); + for (int i = 0; i < num_layers; ++i) { + proj_mtxs[i].resize(num_experts); + proj_cvs[i].resize(num_experts); + proj_dones[i].resize(num_experts); + for (int j = 0; j < num_experts; ++j) { + proj_mtxs[i][j].resize(3); // 3 projection types + proj_cvs[i][j].resize(3); + proj_dones[i][j] = std::vector>(3); + for (int k = 0; k < 3; ++k) { + proj_mtxs[i][j][k] = make_unique(); + proj_cvs[i][j][k] = make_unique(); + proj_dones[i][j][k].store(false, std::memory_order_relaxed); + } + } + } + + // 初始化 clipping 相关的变量 + clip_mtxs.resize(num_layers); + clip_cvs.resize(num_layers); + clip_dones.resize(num_layers); + for (int i = 0; i < num_layers; ++i) { + clip_mtxs[i].resize(num_experts); + clip_cvs[i].resize(num_experts); + clip_dones[i] = std::vector>(num_experts); + for (int j = 0; j < num_experts; ++j) { + clip_mtxs[i][j] = make_unique(); + clip_cvs[i][j] = make_unique(); + clip_dones[i][j].store(false, std::memory_order_relaxed); + } + } +} + +map> load_times; +map> expert_cal_times; +map> expert_clip_times; +map> expert_wait_times; +map> proj_load_times; // 新增:投影层加载时间 +uint64_t start_time; + +// 全局模型指针,用于投影层加载线程访问 +class BailingMoeV2ForCausalLM; // 前向声明 +BailingMoeV2ForCausalLM *global_model_ptr = nullptr; + +// 投影层加载函数指针 +typedef void (*LoadProjectionFunc)(int layer_idx, int expert_idx, int projection_type); +LoadProjectionFunc load_projection_impl = nullptr; + +// 新增:投影层加载线程函数 +extern void projection_loading_thread_func(); +// 新增:clip线程函数 +extern void clip_thread_func(); + +void clearMBPtimes() { + load_times.clear(); + expert_cal_times.clear(); + expert_clip_times.clear(); + expert_wait_times.clear(); + proj_load_times.clear(); // 新增:清理投影层加载时间 + clipped_data.clear(); // [请确认已添加] 清理裁剪结果,防止内存泄漏 + start_time = 0; +} +void prinMBPtimes(string start_word = "") { + double load_times_cal = 0; + cout << "load_times = [" << endl; + for (const auto &entry : proj_load_times) { + if (start_word.empty() || entry.first.substr(0, start_word.length()) == start_word) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + load_times_cal += entry.second.second - entry.second.first; + } + cout << "]" << endl; + cout << "calc_times = [" << endl; + for (const auto &entry : expert_cal_times) { + if (start_word.empty() || entry.first.substr(0, start_word.length()) == start_word) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + } + cout << "]" << endl; + cout << "clip_times = [" << endl; + for (const auto &entry : expert_clip_times) { + if (start_word.empty() || entry.first.substr(0, start_word.length()) == start_word) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + } + cout << "]" << endl; + cout << "wait_times = [" << endl; + for (const auto &entry : expert_wait_times) { + if (start_word.empty() || entry.first.substr(0, start_word.length()) == start_word) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + } + cout << "]" << endl; + std::cout << "load_times_cal = " << load_times_cal << "ms" << endl; +} \ No newline at end of file diff --git a/src/models/ling/tokenizer_bailing.hpp b/src/models/ling/tokenization_bailing.hpp similarity index 100% rename from src/models/ling/tokenizer_bailing.hpp rename to src/models/ling/tokenization_bailing.hpp diff --git a/src/models/qwen/configuration_qwen.hpp b/src/models/qwen/configuration_qwen.hpp index 6304253fa..8f3789106 100644 --- a/src/models/qwen/configuration_qwen.hpp +++ b/src/models/qwen/configuration_qwen.hpp @@ -102,6 +102,25 @@ struct QWenConfig : public TransformerConfig { sliding_window = 32768; vocab_size = 151936; tie_embedding_words = true; + } else if (billionsType == "0.5b-lm") { + attention_dropout = 0.0; + bos_token_id = 151643; + eos_token_id = 151645; + std::string hidden_act = "silu"; + hidden_size = 1024; + initializer_range = 0.02; + intermediate_size = 2816; + max_position_embeddings = 32768; + max_window_layers = 21; + model_type = "qwen2"; + num_attention_heads = 16; + num_hidden_layers = 24; + num_key_value_heads = 16; + rms_norm_eps = 1e-6; + rope_theta = 1000000.0; + sliding_window = 32768; + vocab_size = 151936; + tie_embedding_words = false; } else if (billionsType == "1.8b") { attention_dropout = 0.0; std::string hidden_act = "silu"; diff --git a/src/models/qwen3/configuration_qwen3.hpp b/src/models/qwen3/configuration_qwen3.hpp index 3712ff2f7..64e227edc 100644 --- a/src/models/qwen3/configuration_qwen3.hpp +++ b/src/models/qwen3/configuration_qwen3.hpp @@ -105,6 +105,26 @@ struct QWen3Config : public TransformerConfig { rope_theta = 1000000.0; vocab_size = 151936; tie_embedding_words = true; + } else if (billionsType == "0.6b-lm") { + attention_bias = false; + attention_dropout = 0.0; + bos_token_id = 151643; + eos_token_id = 151645; + head_dim = 128; + hidden_act = "silu"; + hidden_size = 1024; + initializer_range = 0.02; + intermediate_size = 3072; + max_position_embeddings = 40960; + max_window_layers = 28; + model_type = "qwen3"; + num_attention_heads = 16; + num_hidden_layers = 28; + num_key_value_heads = 8; + rms_norm_eps = 1e-6; + rope_theta = 1000000.0; + vocab_size = 151936; + tie_embedding_words = false; } else if (billionsType == "4b") { attention_bias = false; attention_dropout = 0.0; diff --git a/src/models/smallthinker/configuration_smallthinker.hpp b/src/models/smallthinker/configuration_smallthinker.hpp new file mode 100644 index 000000000..4493202aa --- /dev/null +++ b/src/models/smallthinker/configuration_smallthinker.hpp @@ -0,0 +1,71 @@ +#ifndef CONFIG_SMOLTHINKER_HPP +#define CONFIG_SMOLTHINKER_HPP +#include "models/transformer/configuration_transformer.hpp" + +using namespace mllm; + +class SmallThinkerNameConfig : public TransformerNameConfig { +public: + std::string blk_name; + std::string token_embd_name; + std::string post_norm_name; + std::string lm_head_name; + std::string _gate_proj_name; + + void init() { + blk_name = "model.layers."; + _attn_base_name = "self_attn."; + _ffn_base_name = "block_sparse_moe."; + _q_proj_name = "q_proj"; + _k_proj_name = "k_proj"; + _v_proj_name = "v_proj"; + _o_proj_name = "o_proj"; + _gate_proj_name = "gate"; + _up_proj_name = "up"; + _down_proj_name = "down"; + _attn_norm_name = "input_layernorm"; + _ffn_norm_name = "post_attention_layernorm"; + token_embd_name = "model.embed_tokens"; + post_norm_name = "model.norm"; + lm_head_name = "lm_head"; + } +}; + +struct SmallThinkerConfig : public TransformerConfig { + explicit SmallThinkerConfig(int token_limit, string billions = "4BA0.6B") : + cache_limit(token_limit) { + names_config.init(); + string billionsType; + std::transform(billions.begin(), billions.end(), std::back_inserter(billionsType), + ::tolower); + if (billionsType == "4ba0.6b") { + } + if (billionsType == "4ba0.6b-lm") { + tie_embedding_words = false; + } else { + throw std::runtime_error("Unsupported model size"); + } + } + + int num_experts = 32; + int num_experts_per_tok = 4; + + // std::string hidden_act = "relu"; + int hidden_size = 1536; + int intermediate_size = 768; + int max_position_embeddings = 32768; + int num_hidden_layers = 32; + int num_attention_heads = 12; + int num_key_value_heads = 2; + double rms_norm_eps = 1e-06; + float rope_theta = 1.5e6; + int vocab_size = 151936; + int head_dim = 128; // hidden_size/num_attention_heads + + int cache_limit; + RoPEType RoPE_type = RoPEType::HFHUBROPE; + SmallThinkerNameConfig names_config; + bool tie_embedding_words = true; // false; +}; + +#endif // CONFIG_SMOLTHINKER_HPP diff --git a/src/models/smallthinker/mbp/modeling_smallthinker_mbp.hpp b/src/models/smallthinker/mbp/modeling_smallthinker_mbp.hpp new file mode 100644 index 000000000..581188246 --- /dev/null +++ b/src/models/smallthinker/mbp/modeling_smallthinker_mbp.hpp @@ -0,0 +1,433 @@ +#ifndef MODELING_SMOLTHINKER_HPP +#define MODELING_SMOLTHINKER_HPP + +#include "Layer.hpp" +#include "Module.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include "../configuration_smallthinker.hpp" +#include "settings_smallthinker_mbp.hpp" +#include "models/transformer/modeling_transformer.hpp" +#include +#include +#include +#include +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(__ARM_NEON) && !defined(__APPLE__) +#include +#include +#include +#include +#endif + +#define MBP_THREAD + +using namespace mllm; + +class SmallThinkerMLP final : public Module { +public: + SmallThinkerMLP() = default; + SmallThinkerMLP(int hidden_size, int intermediate_size, const SmallThinkerNameConfig &names, const std::string &base_name) { + gate_proj = Linear(hidden_size, intermediate_size, false, base_name + names._gate_proj_name); + relu = ReLU(base_name + "relu"); + up_proj = Linear(hidden_size, intermediate_size, false, base_name + names._up_proj_name); + down_proj = Linear(intermediate_size, hidden_size, false, base_name + names._down_proj_name); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto x = gate_proj(inputs[0]); + x = relu(x); + auto y = up_proj(inputs[0]); + x = x * y; + x = down_proj(x); + return {x}; + } + + void load() { + gate_proj.load(); + up_proj.load(); + down_proj.load(); + } + bool loaded() { + return gate_proj.loaded() && up_proj.loaded() && down_proj.loaded(); + } + void free() { + gate_proj.free(); + up_proj.free(); + down_proj.free(); + } + +private: + Layer gate_proj; + Layer up_proj; + Layer down_proj; + Layer relu; +}; + +class SmallThinkerMoeBlock final : public Module { +public: + SmallThinkerMoeBlock() = default; + SmallThinkerMoeBlock(const SmallThinkerConfig &config, const SmallThinkerNameConfig &names, const string &base_name) { + experts = List(config.num_experts, config.hidden_size, config.intermediate_size, names, base_name + "experts."); + // primary_router = Linear(config.hidden_size, config.num_experts, false, base_name + "primary_router"); + sigmoid = Sigmoid(base_name + "sigmoid"); + num_experts_per_tok = config.num_experts_per_tok; + num_hidden_layers = config.num_hidden_layers; + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + int layer_idx = std::any_cast(args[0]); + if (hidden_states.batch() > 1) hidden_states = hidden_states.view(1, -1, ANYDIM, -1); // 1, batch*seq, 1, hidden + auto router_logits = inputs[1]; + auto expert_indices = inputs[2]; + auto expert_weights = sigmoid(router_logits); + expert_weights = expert_weights / expert_weights.sum(DIMENSION); // 1, batch*seq, 1, k + expert_weights = expert_weights.view(-1, -1, 1, 1); // 1, k* batch*seq, 1, 1 + // moe_infer + auto idxs = expert_indices.argsort(); // 1, 1, 1, k* batch*seq + auto tokens_per_expert = expert_indices.bincount(); // (1, 1, 1, 0) 1, 1, 1, k + auto token_idxs = idxs / num_experts_per_tok; // 1, 1, 1, k* batch*seq + int start_idx = 0; + int end_idx = start_idx; + auto expert_cache = Tensor::zero_like(hidden_states); // 1, batch*seq, 1, hidden + for (int i = 0; i < experts.size(); ++i) { + if (Module::llm_model_ptr->doTrace || (tokens_per_expert.dimension() != 0 && i >= tokens_per_expert.dimension())) { + break; + } + int this_token_num = tokens_per_expert.dimension() == 0 ? + 0 : + tokens_per_expert.d(0, 0, 0, i); + if (tokens_per_expert.dimension() != 0 && this_token_num == 0) + continue; + end_idx = start_idx + this_token_num; + // + auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + + // step.1 - 裁剪数据 + double time_start_ = (mllm_time_us() - start_time) / 1000.0F; // ms + auto expert_tokens = hidden_states.clip(exp_token_idx, SEQUENCE); //(1, 0, 1, hidden) 1, e-s, 1, hidden + auto expert_weights_clip = expert_weights.clip(exp_idx, SEQUENCE); //(1, 0, 1, 1) 1, e-s, 1, 1 + + string expert_name_ = std::to_string(layer_idx) + "_" + std::to_string(i); + double time_end_ = (mllm_time_us() - start_time) / 1000.0F; // ms + expert_clip_times[expert_name_] = {time_start_, time_end_}; + +#ifdef MBP_THREAD + // step.2 - 等待加载完成 + double time_start_w = (mllm_time_us() - start_time) / 1000.0F; // ms + if (!experts[i].loaded()) { + unique_lock lock(*mtxs[layer_idx][i]); // 局部锁 + cvs[layer_idx][i]->wait(lock, [&] { + return dones[layer_idx][i].load(memory_order_acquire); + }); + assert(dones[layer_idx][i]); + } + double time_end_w = (mllm_time_us() - start_time) / 1000.0F; // ms + expert_wait_times[expert_name_] = {time_start_w, time_end_w}; +#endif + auto time_start__ = (mllm_time_us()); // ms + double time_start = (time_start__ - start_time) / 1000.0F; // ms + + // step.3 - 专家计算 + auto expert_out = experts[i]({expert_tokens})[0]; //(1, 0, 1, hidden) 1, e-s, 1, + expert_out = expert_out * expert_weights_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden + expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden + + // step.4 - 释放专家内存 + experts[i].free(); + + string expert_name = std::to_string(layer_idx) + "_" + std::to_string(i); + auto time_end__ = (mllm_time_us()); // ms + double time_end = (time_end__ - start_time) / 1000.0F; // ms + expert_cal_times[expert_name] = {time_start, time_end}; + +#ifdef MBP_THREAD + dones[layer_idx][i] = false; // 重置状态 +#endif + + start_idx = end_idx; + } + + if (hidden_states.batch() > 1) { + // expert_cache.view(ANYDIM, seq, -1, -1);//TODO + } + return {expert_cache}; + } + + void load_experts(int expert_idx) { + experts[expert_idx].load(); + } + +private: + std::vector experts; + // Layer primary_router; + Layer sigmoid; + int num_experts_per_tok{}; + int num_hidden_layers{}; +}; + +class SmallThinkerDecoder final : public Module { +public: + SmallThinkerDecoder() = default; + SmallThinkerDecoder(const SmallThinkerConfig &config, const SmallThinkerNameConfig &names, const string &base_name) { + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, + config.hidden_size / config.num_attention_heads, + SPLIT_NONE, PostQkv_NONE, false, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, + true, false, false, + config.attn_implementation, names, base_name + names._attn_base_name); + block_sparse_moe = SmallThinkerMoeBlock(config, names, base_name + names._ffn_base_name); + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); + num_hidden_layers = config.num_hidden_layers; + primary_router = Linear(config.hidden_size, config.num_experts, false, base_name + names._ffn_base_name + "primary_router"); + num_experts_per_tok = config.num_experts_per_tok; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto router_input = inputs[0]; + int layer_idx = std::any_cast(args[0]); + if (router_input.batch() > 1) router_input = router_input.view(1, -1, 1, -1); // 1, batch*seq, 1, hidden + auto router_logits = primary_router(router_input); // 1, batch*seq, 1, num_experts + auto experts_w_i = Tensor::topk(router_logits, num_experts_per_tok, DIMENSION); + router_logits = experts_w_i[0]; // 1, batch*seq, 1, k + auto expert_indices = experts_w_i[1]; // 1, batch*seq, 1, k + expert_indices = expert_indices.view(-1, 1, 1, -1); // 1, 1, 1, k* batch*seq + if (expert_indices.dimension()) { + auto start_ptr = expert_indices.ptrAt(0, 0, 0, 0); + auto ptr_len = expert_indices.dimension(); + std::vector unique_experts; + std::set seen_experts; + for (int i = 0; i < ptr_len; ++i) { + float expert_id = start_ptr[i]; + if (seen_experts.find(expert_id) == seen_experts.end()) { + seen_experts.insert(expert_id); + unique_experts.push_back((int)expert_id); + } + } + std::sort(unique_experts.begin(), unique_experts.end()); + for (int e_i = 0; e_i < unique_experts.size(); ++e_i) { + auto expert_id = unique_experts[e_i]; + // 向加载队列申请加载 layer_idx的 expert_id专家 +#ifdef MBP_THREAD + LoadRequest req{layer_idx, expert_id}; + { + lock_guard lk(queue_mutex); + load_requests.push(req); + } + queue_cv.notify_one(); // 通知加载线程 +#endif + // std::cout << "layer " << layer_idx << " Request loading expert id: " << expert_id << std::endl; + } + } + auto hidden_states = input_layernorm(router_input); + hidden_states = self_atten({hidden_states, hidden_states, hidden_states})[0]; + auto residual = hidden_states + inputs[0]; + hidden_states = post_attention_layernorm(residual); + hidden_states = block_sparse_moe({hidden_states, router_logits, expert_indices}, layer_idx)[0]; + hidden_states = hidden_states + residual; + return {hidden_states}; + } + + MultiHeadAttention &get_attention() { + return self_atten; + } + + void load_experts(int expert_idx) { + block_sparse_moe.load_experts(expert_idx); + } + +private: + MultiHeadAttention self_atten; + SmallThinkerMoeBlock block_sparse_moe; + Layer input_layernorm; + Layer post_attention_layernorm; + Layer primary_router; + int num_hidden_layers; + int num_experts_per_tok{}; +}; + +class SmallThinkerModel final : public Module { +public: + SmallThinkerModel() = default; + SmallThinkerModel(const SmallThinkerConfig &config, const SmallThinkerNameConfig &names, const string &base_name) { + blocks = List(config.num_hidden_layers, config, names, base_name); + norm = RMSNorm(config.hidden_size, config.rms_norm_eps, names.post_norm_name); + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + int layer_idx = 0; + for (auto &block : blocks) { + hidden_states = block({hidden_states}, layer_idx)[0]; + layer_idx++; + } + hidden_states = norm(hidden_states); + return {hidden_states}; + } + + void clear_kvcache() override { + for (auto &block : blocks) { + auto kvcache = block.get_attention().get_cache(); + for (auto &cache : kvcache) { cache->clearCache(); } + auto ropes = block.get_attention().get_rope(); + for (auto &rope : ropes) { rope->clearCache(); } + } + } + + void load_experts(int layer_idx, int expert_idx) { + blocks[layer_idx].load_experts(expert_idx); + } + +private: + std::vector blocks; + Layer norm; +}; + +class SmallThinkerForCausalLM final : public Module { +public: + CHAINABLE_MODULE_METHODS(SmallThinkerForCausalLM) + SmallThinkerForCausalLM(SmallThinkerConfig &config) { + auto names = config.names_config; + hidden_size = config.hidden_size; + tie_embedding_words = config.tie_embedding_words; + embedding = Embedding(config.vocab_size, config.hidden_size, names.token_embd_name); + model = SmallThinkerModel(config, names, names.blk_name); + if (tie_embedding_words) { + lm_head = Parameter(1, config.vocab_size, 1, config.hidden_size, names.token_embd_name + ".weight"); + } else { + lm_head_layer = Linear(config.hidden_size, config.vocab_size, false, names.lm_head_name); + } + + // 初始化 mbp 相关变量 + // mbp_init(config.num_hidden_layers, config.num_experts); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + std::vector outputs; + clearMBPtimes(); +#ifdef MBP_THREAD + start_time = mllm_time_us(); + mbp_finish.store(false, std::memory_order_relaxed); + if (inputs[0].dimension() == 1) { + omp_set_max_active_levels(2); // Enable OpenMP nesting +#pragma omp parallel num_threads(2) + if (omp_get_thread_num() == 0) { // 根据线程ID决定执行哪个函数 +#if defined(__ARM_NEON) && !defined(__APPLE__) + { + struct sched_param param; + param.sched_priority = 20; // 范围 1–99,根据设备可酌情调整 + pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m); + } + // ─── 2. 绑定到大核(big cluster)以减少与小核的资源争用 ────────────── + { + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + // 假设大核是 CPU 2–3,按实际设备改为合适的核号 + CPU_SET(2, &cpuset); + CPU_SET(3, &cpuset); + // CPU_SET(6, &cpuset); // 假设小核心是CPU 6 + sched_setaffinity(pthread_self(), sizeof(cpuset), &cpuset); + // sched_setaffinity(gettid(), sizeof(cpu_set_t), &cpuset); + } +#endif + mbp_load(); + } else { + outputs = do_Forward(inputs, args); + } + } else { +#endif + outputs = do_Forward(inputs, args); +#ifdef MBP_THREAD + } +#endif + return outputs; + } + void clear_kvcache() override { + model.clear_kvcache(); + } + + std::vector do_Forward(std::vector inputs, std::vector args) { + auto x = embedding(inputs[0]); + auto outputs = model({x})[0]; + if (outputs.sequence() > 1) { + outputs = outputs.clip({}, {}, {-1}, {}); + } + if (tie_embedding_words) { + outputs = Tensor::mm(outputs, lm_head().transpose(Chl::SEQUENCE, Chl::DIMENSION)); + } else { + outputs = lm_head_layer(outputs); + } + +#ifdef MBP_THREAD + // 设置 mbp_finish 为 true,结束 mbp_load 线程 + // 1. 设置内存序保证可见性 + mbp_finish.store(true, std::memory_order_release); // 改为 release 内存序 + // 2. 主动唤醒所有等待线程 + { + std::lock_guard lk(queue_mutex); + queue_cv.notify_all(); // 必须加锁后通知 + } + // 3. 添加二次状态检查(可选) + std::atomic_thread_fence(std::memory_order_seq_cst); +#endif + return {outputs}; + } + + void load_experts(int layer_idx, int expert_idx) { + model.load_experts(layer_idx, expert_idx); + } + + void mbp_load() { + while (!mbp_finish.load(std::memory_order_acquire)) { + std::unique_lock lk(queue_mutex); + queue_cv.wait(lk, [this] { + return !load_requests.empty() || mbp_finish.load(std::memory_order_acquire); + }); + + if (mbp_finish.load(std::memory_order_acquire)) { + break; + } + + while (!load_requests.empty()) { + auto req = load_requests.front(); + load_requests.pop(); + lk.unlock(); // 释放锁以便其他线程入队 + { // 执行加载 + std::unique_lock expert_lk(*mtxs[req.layer][req.expert]); + if (!dones[req.layer][req.expert].load(std::memory_order_acquire)) { + double time_start = (mllm_time_us() - start_time) / 1000.0F; // ms + + load_experts(req.layer, req.expert); + dones[req.layer][req.expert].store(true, std::memory_order_release); + + string expert_name = std::to_string(req.layer) + "_" + std::to_string(req.expert); + double time_end = (mllm_time_us() - start_time) / 1000.0F; // ms + load_times[expert_name] = {time_start, time_end}; + } + } + cvs[req.layer][req.expert]->notify_all(); + lk.lock(); // 重新获取锁处理下一个请求 + } + } + } + +private: + int hidden_size; + bool tie_embedding_words; + Layer embedding; + Parameter lm_head; + Layer lm_head_layer; + SmallThinkerModel model; +}; + +#endif // MODELING_SMOLTHINKER_HPP \ No newline at end of file diff --git a/src/models/smallthinker/mbp/settings_smallthinker_mbp.hpp b/src/models/smallthinker/mbp/settings_smallthinker_mbp.hpp new file mode 100644 index 000000000..cb6f38018 --- /dev/null +++ b/src/models/smallthinker/mbp/settings_smallthinker_mbp.hpp @@ -0,0 +1,145 @@ +#pragma once +// #include +// #include +#include +// #include +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Tensor.hpp" + +using namespace std; +using namespace mllm; + +int mbp_load_layer_idx; +int mbp_load_expert_idx; + +struct LoadRequest { + int layer; + int expert; +}; +queue load_requests; // 替换原do_mbp_load相关变量 +mutex queue_mutex; // 队列互斥锁 +condition_variable queue_cv; // 队列条件变量 + +// ========= Clip Thread Globals (NEW) ========= +// 1. 新增 ClipRequest 结构体 +struct ClipRequest { + int layer; + int expert; + Tensor hidden_states; + Tensor exp_token_idx; + Tensor topk_weight; + Tensor exp_idx; +}; +// 2. 新增 clip 线程的任务队列、锁和条件变量 +queue clip_requests; +mutex clip_queue_mutex; +condition_variable clip_queue_cv; +// 3. 新增用于存储 clip 结果的 map 和其互斥锁 +map> clipped_data; +mutex clip_results_mutex; +//============ End Clip Thread Globals ============ + +atomic mbp_finish{false}; // 改为原子布尔 + +vector>> mtxs; // 每个层和专家一个互斥锁 +vector>> cvs; // 每个层和专家一个条件变量 +vector>> dones; // 原子布尔保证可见性 + +// --- Clipping Primitives (NEW) --- +// 4. 新增 clip 线程的同步对象 +vector>> clip_mtxs; +vector>> clip_cvs; +vector>> clip_dones; + +// 修改 MAP_MINICPMMOE_MBP_HPP 中的相关部分 + +inline void reset_syntax_mbm(int layer_idx, int expert_idx) { + // 使用原子操作重置状态 + dones[layer_idx][expert_idx].store(false, std::memory_order_release); +} + +inline void mbp_init(int num_layers, int num_experts) { + // 初始化 loading 相关的变量 + mtxs.resize(num_layers); + cvs.resize(num_layers); + dones.resize(num_layers); + for (int i = 0; i < num_layers; ++i) { + mtxs[i].resize(num_experts); + cvs[i].resize(num_experts); + dones[i] = std::vector>(num_experts); + for (int j = 0; j < num_experts; ++j) { + mtxs[i][j] = make_unique(); + cvs[i][j] = make_unique(); + dones[i][j].store(false, std::memory_order_relaxed); + } + } + // 初始化 clipping 相关的变量 + clip_mtxs.resize(num_layers); + clip_cvs.resize(num_layers); + clip_dones.resize(num_layers); + for (int i = 0; i < num_layers; ++i) { + clip_mtxs[i].resize(num_experts); + clip_cvs[i].resize(num_experts); + clip_dones[i] = std::vector>(num_experts); + for (int j = 0; j < num_experts; ++j) { + clip_mtxs[i][j] = make_unique(); + clip_cvs[i][j] = make_unique(); + clip_dones[i][j].store(false, std::memory_order_relaxed); + } + } +} + +map> load_times; +map> expert_cal_times; +map> expert_clip_times; +map> expert_wait_times; +uint64_t start_time; +void clearMBPtimes() { + load_times.clear(); + expert_cal_times.clear(); + expert_clip_times.clear(); + expert_wait_times.clear(); + clipped_data.clear(); + start_time = 0; +} +void prinMBPtimes(string start_word = "") { + double load_times_cal = 0; + cout << "load_times = [" << endl; + for (const auto &entry : load_times) { + if (start_word.empty() || entry.first.substr(0, start_word.length()) == start_word) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + load_times_cal += entry.second.second - entry.second.first; + } + cout << "]" << endl; + cout << "calc_times = [" << endl; + for (const auto &entry : expert_cal_times) { + if (start_word.empty() || entry.first.substr(0, start_word.length()) == start_word) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + } + cout << "]" << endl; + cout << "clip_times = [" << endl; + for (const auto &entry : expert_clip_times) { + if (start_word.empty() || entry.first.substr(0, start_word.length()) == start_word) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + } + cout << "]" << endl; + cout << "wait_times = [" << endl; + for (const auto &entry : expert_wait_times) { + if (start_word.empty() || entry.first.substr(0, start_word.length()) == start_word) { + cout << "(\"" << entry.first << "\" , " << entry.second.first << ", " << entry.second.second << ")," << endl; + } + } + cout << "]" << endl; + std::cout << "load_times_cal = " << load_times_cal << "ms" << endl; +} \ No newline at end of file diff --git a/src/models/smallthinker/modeling_smallthinker.hpp b/src/models/smallthinker/modeling_smallthinker.hpp new file mode 100644 index 000000000..85e16e814 --- /dev/null +++ b/src/models/smallthinker/modeling_smallthinker.hpp @@ -0,0 +1,218 @@ +#ifndef MODELING_SMOLTHINKER_HPP +#define MODELING_SMOLTHINKER_HPP + +#include "Layer.hpp" +#include "Module.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include "configuration_smallthinker.hpp" +#include "models/transformer/modeling_transformer.hpp" +#include +using namespace mllm; + +class SmallThinkerMLP final : public Module { +public: + SmallThinkerMLP() = default; + SmallThinkerMLP(int hidden_size, int intermediate_size, const SmallThinkerNameConfig &names, const std::string &base_name) { + gate_proj = Linear(hidden_size, intermediate_size, false, base_name + names._gate_proj_name); + relu = ReLU(base_name + "relu"); + up_proj = Linear(hidden_size, intermediate_size, false, base_name + names._up_proj_name); + down_proj = Linear(intermediate_size, hidden_size, false, base_name + names._down_proj_name); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto x = gate_proj(inputs[0]); + x = relu(x); + auto y = up_proj(inputs[0]); + x = x * y; + x = down_proj(x); + return {x}; + } + +private: + Layer gate_proj; + Layer up_proj; + Layer down_proj; + Layer relu; +}; + +class SmallThinkerMoeBlock final : public Module { +public: + SmallThinkerMoeBlock() = default; + SmallThinkerMoeBlock(const SmallThinkerConfig &config, const SmallThinkerNameConfig &names, const string &base_name) { + experts = List(config.num_experts, config.hidden_size, config.intermediate_size, names, base_name + "experts."); + // primary_router = Linear(config.hidden_size, config.num_experts, false, base_name + "primary_router"); + sigmoid = Sigmoid(base_name + "sigmoid"); + num_experts_per_tok = config.num_experts_per_tok; + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + if (hidden_states.batch() > 1) hidden_states = hidden_states.view(1, -1, ANYDIM, -1); // 1, batch*seq, 1, hidden + auto router_logits = inputs[1]; + auto expert_indices = inputs[2]; + auto expert_weights = sigmoid(router_logits); + expert_weights = expert_weights / expert_weights.sum(DIMENSION); // 1, batch*seq, 1, k + expert_weights = expert_weights.view(-1, -1, 1, 1); // 1, k* batch*seq, 1, 1 + // moe_infer + auto idxs = expert_indices.argsort(); // 1, 1, 1, k* batch*seq + auto tokens_per_expert = expert_indices.bincount(); // (1, 1, 1, 0) 1, 1, 1, k + auto token_idxs = idxs / num_experts_per_tok; // 1, 1, 1, k* batch*seq + int start_idx = 0; + int end_idx = start_idx; + auto expert_cache = Tensor::zero_like(hidden_states); // 1, batch*seq, 1, hidden + for (int i = 0; i < experts.size(); ++i) { + if (tokens_per_expert.dimension() != 0 && i >= tokens_per_expert.dimension()) + break; + int this_token_num = tokens_per_expert.dimension() == 0 ? + 0 : + tokens_per_expert.d(0, 0, 0, i); + if (tokens_per_expert.dimension() != 0 && this_token_num == 0) + continue; + end_idx = start_idx + this_token_num; + // + auto exp_token_idx = token_idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto exp_idx = idxs.clip({}, {}, {}, {start_idx, end_idx}); //(1, 1, 1, 0) 1, 1, 1, e-s + auto expert_tokens = hidden_states.clip(exp_token_idx, SEQUENCE); //(1, 0, 1, hidden) 1, e-s, 1, hidden + auto expert_out = experts[i]({expert_tokens})[0]; //(1, 0, 1, hidden) 1, e-s, 1, + auto expert_weights_clip = expert_weights.clip(exp_idx, SEQUENCE); //(1, 0, 1, 1) 1, e-s, 1, 1 + expert_out = expert_out * expert_weights_clip; //(1, 0, 1, hidden) 1, e-s, 1, hidden + expert_cache.scatter_add(expert_out, exp_token_idx); // 1, batch*seq, 1, hidden + // + start_idx = end_idx; + } + if (hidden_states.batch() > 1) { + // expert_cache.view(ANYDIM, seq, -1, -1);//TODO + } + return {expert_cache}; + } + +private: + std::vector experts; + // Layer primary_router; + Layer sigmoid; + int num_experts_per_tok{}; +}; + +class SmallThinkerDecoder final : public Module { +public: + SmallThinkerDecoder() = default; + SmallThinkerDecoder(const SmallThinkerConfig &config, const SmallThinkerNameConfig &names, const string &base_name) { + self_atten = MultiHeadAttention(config.hidden_size, config.num_attention_heads, + config.num_key_value_heads, + config.hidden_size / config.num_attention_heads, + SPLIT_NONE, PostQkv_NONE, false, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, + true, false, false, + config.attn_implementation, names, base_name + names._attn_base_name); + block_sparse_moe = SmallThinkerMoeBlock(config, names, base_name + names._ffn_base_name); + input_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + post_attention_layernorm = RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); + num_hidden_layers = config.num_hidden_layers; + primary_router = Linear(config.hidden_size, config.num_experts, false, base_name + names._ffn_base_name + "primary_router"); + num_experts_per_tok = config.num_experts_per_tok; + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto router_input = inputs[0]; + if (router_input.batch() > 1) router_input = router_input.view(1, -1, 1, -1); // 1, batch*seq, 1, hidden + auto router_logits = primary_router(router_input); // 1, batch*seq, 1, num_experts + auto experts_w_i = Tensor::topk(router_logits, num_experts_per_tok, DIMENSION); + router_logits = experts_w_i[0]; // 1, batch*seq, 1, k + auto expert_indices = experts_w_i[1]; // 1, batch*seq, 1, k + expert_indices = expert_indices.view(-1, 1, 1, -1); // 1, 1, 1, k* batch*seq + auto hidden_states = input_layernorm(router_input); + hidden_states = self_atten({hidden_states, hidden_states, hidden_states})[0]; + auto residual = hidden_states + inputs[0]; + hidden_states = post_attention_layernorm(residual); + hidden_states = block_sparse_moe({hidden_states, router_logits, expert_indices})[0]; + hidden_states = hidden_states + residual; + return {hidden_states}; + } + + MultiHeadAttention &get_attention() { + return self_atten; + } + +private: + MultiHeadAttention self_atten; + SmallThinkerMoeBlock block_sparse_moe; + Layer input_layernorm; + Layer post_attention_layernorm; + Layer primary_router; + int num_hidden_layers; + int num_experts_per_tok{}; +}; + +class SmallThinkerModel final : public Module { +public: + SmallThinkerModel() = default; + SmallThinkerModel(const SmallThinkerConfig &config, const SmallThinkerNameConfig &names, const string &base_name) { + blocks = List(config.num_hidden_layers, config, names, base_name); + norm = RMSNorm(config.hidden_size, config.rms_norm_eps, names.post_norm_name); + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto hidden_states = inputs[0]; + for (auto &block : blocks) { + hidden_states = block({hidden_states})[0]; + } + hidden_states = norm(hidden_states); + return {hidden_states}; + } + + void clear_kvcache() override { + for (auto &block : blocks) { + auto kvcache = block.get_attention().get_cache(); + for (auto &cache : kvcache) { cache->clearCache(); } + auto ropes = block.get_attention().get_rope(); + for (auto &rope : ropes) { rope->clearCache(); } + } + } + +private: + std::vector blocks; + Layer norm; +}; + +class SmallThinkerForCausalLM final : public Module { +public: + CHAINABLE_MODULE_METHODS(SmallThinkerForCausalLM) + SmallThinkerForCausalLM(SmallThinkerConfig &config) { + auto names = config.names_config; + hidden_size = config.hidden_size; + embedding = Embedding(config.vocab_size, config.hidden_size, names.token_embd_name); + model = SmallThinkerModel(config, names, names.blk_name); + tie_embedding_words = config.tie_embedding_words; + if (tie_embedding_words) { + lm_head = Parameter(1, config.vocab_size, 1, config.hidden_size, names.token_embd_name + ".weight"); + } else { + lm_head_layer = Linear(config.hidden_size, config.vocab_size, false, names.lm_head_name); + } + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto x = embedding(inputs[0]); + auto outputs = model({x})[0]; + if (outputs.sequence() > 1) { + outputs = outputs.clip({}, {}, {-1}, {}); + } + if (tie_embedding_words) { + outputs = Tensor::mm(outputs, lm_head().transpose(Chl::SEQUENCE, Chl::DIMENSION)); + } else { + outputs = lm_head_layer(outputs); + } + return {outputs}; + } + void clear_kvcache() override { + model.clear_kvcache(); + } + +private: + int hidden_size; + bool tie_embedding_words; + Layer embedding; + Parameter lm_head; + Layer lm_head_layer; + SmallThinkerModel model; +}; + +#endif // MODELING_SMOLTHINKER_HPP \ No newline at end of file diff --git a/src/tokenizers/BPE/Bpe.cpp b/src/tokenizers/BPE/Bpe.cpp index fd1cf72a9..8a066631c 100644 --- a/src/tokenizers/BPE/Bpe.cpp +++ b/src/tokenizers/BPE/Bpe.cpp @@ -132,22 +132,10 @@ void mllm::BPETokenizer::tokenize(const std::string &text, std::vectorvocab_map_.find(word_split); result != this->vocab_map_.end()) { - auto token_idx = result->second; - tokens.emplace_back(id_token_[token_idx].score); - } else { - if (!byte_fallback) { - tokens.emplace_back(mllm::BPETokenizer::TokenUnk); - } else { - for (const char j : word_split) { - token_id_t token_id = static_cast(j) + 3; - tokens.emplace_back(token_id); - } - } - } - } + // Use the same algorithm as the else branch for vocab-based tokenization + std::vector word_tokens; + tokenizeWordWithVocab(word, word_tokens, byte_fallback); + tokens.insert(tokens.end(), word_tokens.begin(), word_tokens.end()); } if (TokenEos > 0) { tokens.push_back(TokenEos); @@ -202,7 +190,7 @@ void mllm::BPETokenizer::tokenize(const std::string &text, std::vector(symbols_[i].ch[j]) + 3; tokens.emplace_back(token_id); } @@ -232,6 +220,63 @@ void mllm::BPETokenizer::tryMergeSymbol(size_t start, size_t end) { queue_.emplace(item); } } + +void mllm::BPETokenizer::tokenizeWordWithVocab(const std::string &word, std::vector &tokens, bool byte_fallback) { + if (auto result = this->vocab_map_.find(word); result != this->vocab_map_.end()) { + tokens.emplace_back(result->second); + // std::cout << "Word: \"" << word << "\" -> [\"" << word << "\"]" << std::endl; + return; + } + // Use greedy longest-match algorithm + size_t pos = 0; + std::vector token_strings; // For debug output + while (pos < word.size()) { + int best_len = 0; + token_id_t best_token = TokenUnk; + std::string best_substr; + // Try all possible substrings starting from current position + for (size_t len = 1; len <= word.size() - pos; ++len) { + std::string substr = word.substr(pos, len); + auto result = this->vocab_map_.find(substr); + if (result != this->vocab_map_.end()) { + // Found a match, update best if this is longer + if (len > best_len) { + best_len = len; + best_token = result->second; + best_substr = substr; + } + } + } + if (best_len > 0) { + // Found a match, add the token + tokens.emplace_back(best_token); + token_strings.push_back(best_substr); + pos += best_len; + } else { + // No match found, handle the single character + if (!byte_fallback) { + tokens.emplace_back(TokenUnk); + token_strings.push_back(""); + pos += utf8_len(word[pos]); // Skip one UTF-8 character + } else { + // Byte fallback + token_id_t token_id = static_cast(word[pos]) + 3; + tokens.emplace_back(token_id); + token_strings.push_back(std::string(1, word[pos])); + pos += 1; + } + } + } + + // std::cout << "Word: \"" << word << "\" -> ["; + // for (size_t i = 0; i < token_strings.size(); ++i) { + // std::cout << "\"" << token_strings[i] << "\""; + // if (i < token_strings.size() - 1) { + // std::cout << ", "; + // } + // } + // std::cout << "]" << std::endl; +} void mllm::BPETokenizer::tokenize(const std::string &text, std::vector &tokens, bool bos) { this->tokenize(std::move(text), tokens, bos, true); } diff --git a/src/tokenizers/BPE/Bpe.hpp b/src/tokenizers/BPE/Bpe.hpp index dbe39faeb..5c1a44f83 100644 --- a/src/tokenizers/BPE/Bpe.hpp +++ b/src/tokenizers/BPE/Bpe.hpp @@ -30,6 +30,7 @@ class BPETokenizer : public Tokenizer { std::vector symbols_; std::priority_queue, TokenItem::Compare> queue_; void tryMergeSymbol(size_t start, size_t end); + void tokenizeWordWithVocab(const std::string &word, std::vector &tokens, bool byte_fallback); std::unordered_map bytes_to_unicode_; public: diff --git a/tools/quantizer/QuantWriter.cpp b/tools/quantizer/QuantWriter.cpp index 273d8e3fc..ffea80a3d 100644 --- a/tools/quantizer/QuantWriter.cpp +++ b/tools/quantizer/QuantWriter.cpp @@ -45,6 +45,7 @@ const std::vector q23_to_q4_0_4x4_layers = { "dense_h_to_4h", "v_proj", "down_proj", + "down", }; const std::vector q4_0_kai_to_q4_0_4x4_layers = { @@ -126,7 +127,7 @@ DataType QuantWriter::getQuantizationTypeFor(const std::string &name, DataType t if (find_in_layers(name, fp32_layers)) { return MLLM_TYPE_F32; } - if (find_in_layers(name, q23_layers) && (name.find("down_proj") == std::string::npos)) { + if (find_in_layers(name, q23_layers) && (name.find("down") == std::string::npos)) { return MLLM_TYPE_Q2_K; } if (target_type == MLLM_TYPE_KLEIDIAI_Q4_0) { @@ -224,7 +225,7 @@ void QuantWriter::quantize(DataType target_quant_type, const std::string &other_ // ==================【代码修正】================== // 恢复您指出的、用于判断 N 和 K 的关键逻辑 int N, K; - if (find_in_layers(name, {"w2", "down_proj", "fc2"})) { + if (find_in_layers(name, {"w2", "down_proj", "down", "fc2"})) { N = H; if (num_floats % N != 0) { std::cerr << "FAIL! num_floats not divisible by N for " << name << std::endl; @@ -268,7 +269,8 @@ void QuantWriter::quantize(DataType target_quant_type, const std::string &other_ __exit(-1); } int K = H; - if ((is_visual && find_in_layers(name, {"fc2", "down_proj"})) || (!is_visual && find_in_layers(name, {"w2", "down_proj"}))) { + if ((is_visual && find_in_layers(name, {"fc2", "down_proj", "down"})) + || (!is_visual && find_in_layers(name, {"w2", "down_proj", "down"}))) { if (num_floats % H != 0) { std::cerr << "FAIL! num_floats not divisible by H for " << name << std::endl; __exit(-1); diff --git a/vocab/smallthinker_merges.txt b/vocab/smallthinker_merges.txt new file mode 100644 index 000000000..54f3c8765 --- /dev/null +++ b/vocab/smallthinker_merges.txt @@ -0,0 +1,151387 @@ +['Ġ', 'Ġ'] +['ĠĠ', 'ĠĠ'] +['i', 'n'] +['Ġ', 't'] +['ĠĠĠĠ', 'ĠĠĠĠ'] +['e', 'r'] +['ĠĠ', 'Ġ'] +['o', 'n'] +['Ġ', 'a'] +['r', 'e'] +['a', 't'] +['s', 't'] +['e', 'n'] +['o', 'r'] +['Ġt', 'h'] +['Ċ', 'Ċ'] +['Ġ', 'c'] +['l', 'e'] +['Ġ', 's'] +['i', 't'] +['a', 'n'] +['a', 'r'] +['a', 'l'] +['Ġth', 'e'] +[';', 'Ċ'] +['Ġ', 'p'] +['Ġ', 'f'] +['o', 'u'] +['Ġ', '='] +['i', 's'] +['ĠĠĠĠ', 'ĠĠĠ'] +['in', 'g'] +['e', 's'] +['Ġ', 'w'] +['i', 'on'] +['e', 'd'] +['i', 'c'] +['Ġ', 'b'] +['Ġ', 'd'] +['e', 't'] +['Ġ', 'm'] +['Ġ', 'o'] +['ĉ', 'ĉ'] +['r', 'o'] +['a', 's'] +['e', 'l'] +['c', 't'] +['n', 'd'] +['Ġ', 'in'] +['Ġ', 'h'] +['en', 't'] +['i', 'd'] +['Ġ', 'n'] +['a', 'm'] +['ĠĠĠĠĠĠĠĠ', 'ĠĠĠ'] +['Ġt', 'o'] +['Ġ', 're'] +['-', '-'] +['Ġ', '{'] +['Ġo', 'f'] +['o', 'm'] +[')', ';Ċ'] +['i', 'm'] +['č', 'Ċ'] +['Ġ', '('] +['i', 'l'] +['/', '/'] +['Ġa', 'nd'] +['u', 'r'] +['s', 'e'] +['Ġ', 'l'] +['e', 'x'] +['Ġ', 'S'] +['a', 'd'] +['Ġ', '"'] +['c', 'h'] +['u', 't'] +['i', 'f'] +['*', '*'] +['Ġ', '}'] +['e', 'm'] +['o', 'l'] +['ĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠ'] +['t', 'h'] +[')', 'Ċ'] +['Ġ{', 'Ċ'] +['Ġ', 'g'] +['i', 'g'] +['i', 'v'] +[',', 'Ċ'] +['c', 'e'] +['o', 'd'] +['Ġ', 'v'] +['at', 'e'] +['Ġ', 'T'] +['a', 'g'] +['a', 'y'] +['Ġ', '*'] +['o', 't'] +['u', 's'] +['Ġ', 'C'] +['Ġ', 'st'] +['Ġ', 'I'] +['u', 'n'] +['u', 'l'] +['u', 'e'] +['Ġ', 'A'] +['o', 'w'] +['Ġ', "'"] +['e', 'w'] +['Ġ', '<'] +['at', 'ion'] +['(', ')'] +['Ġf', 'or'] +['a', 'b'] +['or', 't'] +['u', 'm'] +['am', 'e'] +['Ġ', 'is'] +['p', 'e'] +['t', 'r'] +['c', 'k'] +['â', 'Ģ'] +['Ġ', 'y'] +['i', 'st'] +['--', '--'] +['.', 'ĊĊ'] +['h', 'e'] +['Ġ', 'e'] +['l', 'o'] +['Ġ', 'M'] +['Ġb', 'e'] +['er', 's'] +['Ġ', 'on'] +['Ġc', 'on'] +['a', 'p'] +['u', 'b'] +['Ġ', 'P'] +['ĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠ'] +['as', 's'] +['in', 't'] +['>', 'Ċ'] +['l', 'y'] +['ur', 'n'] +['Ġ', '$'] +[';', 'ĊĊ'] +['a', 'v'] +['p', 'ort'] +['i', 'r'] +['-', '>'] +['n', 't'] +['ct', 'ion'] +['en', 'd'] +['Ġd', 'e'] +['it', 'h'] +['ou', 't'] +['t', 'urn'] +['ou', 'r'] +['ĠĠĠĠ', 'Ġ'] +['l', 'ic'] +['re', 's'] +['p', 't'] +['=', '='] +['Ġth', 'is'] +['Ġw', 'h'] +['Ġ', 'if'] +['Ġ', 'D'] +['v', 'er'] +['ag', 'e'] +['Ġ', 'B'] +['h', 't'] +['ex', 't'] +['=', '"'] +['Ġth', 'at'] +['**', '**'] +['Ġ', 'R'] +['Ġ', 'it'] +['es', 's'] +['Ġ', 'F'] +['Ġ', 'r'] +['o', 's'] +['an', 'd'] +['Ġa', 's'] +['e', 'ct'] +['k', 'e'] +['ro', 'm'] +['Ġ', '//'] +['c', 'on'] +['Ġ', 'L'] +['(', '"'] +['q', 'u'] +['l', 'ass'] +['Ġw', 'ith'] +['i', 'z'] +['d', 'e'] +['Ġ', 'N'] +['Ġa', 'l'] +['o', 'p'] +['u', 'p'] +['g', 'et'] +['Ġ}', 'Ċ'] +['i', 'le'] +['Ġa', 'n'] +['at', 'a'] +['o', 're'] +['r', 'i'] +['Ġp', 'ro'] +[';', 'čĊ'] +['ĉĉ', 'ĉĉ'] +['t', 'er'] +['a', 'in'] +['Ġ', 'W'] +['Ġ', 'E'] +['Ġc', 'om'] +['Ġre', 'turn'] +['ar', 't'] +['Ġ', 'H'] +['a', 'ck'] +['im', 'port'] +['ub', 'lic'] +['Ġ', 'or'] +['e', 'st'] +['m', 'ent'] +['Ġ', 'G'] +['ab', 'le'] +['Ġ', '-'] +['in', 'e'] +['il', 'l'] +['in', 'd'] +['er', 'e'] +[':', ':'] +['it', 'y'] +['Ġ', '+'] +['Ġt', 'r'] +['el', 'f'] +['ig', 'ht'] +['(', "'"] +['or', 'm'] +['ul', 't'] +['st', 'r'] +['.', '.'] +['"', ','] +['Ġy', 'ou'] +['y', 'pe'] +['p', 'l'] +['Ġn', 'ew'] +['Ġ', 'j'] +['ĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġf', 'rom'] +['Ġ', 'ex'] +['Ġ', 'O'] +['l', 'd'] +['Ġ', '['] +['o', 'c'] +[':', 'Ċ'] +['Ġs', 'e'] +['Ġ', 'le'] +['----', '----'] +['.', 's'] +['{', 'Ċ'] +["'", ','] +['an', 't'] +['Ġa', 't'] +['as', 'e'] +['.', 'c'] +['Ġc', 'h'] +['<', '/'] +['av', 'e'] +['an', 'g'] +['Ġa', 're'] +['Ġin', 't'] +['âĢ', 'Ļ'] +['_', 't'] +['er', 't'] +['i', 'al'] +['a', 'ct'] +['}', 'Ċ'] +['iv', 'e'] +['od', 'e'] +['o', 'st'] +['Ġc', 'lass'] +['Ġn', 'ot'] +['o', 'g'] +['or', 'd'] +['al', 'ue'] +['al', 'l'] +['f', 'f'] +['(', ');Ċ'] +['on', 't'] +['im', 'e'] +['a', 're'] +['Ġ', 'U'] +['Ġp', 'r'] +['Ġ', ':'] +['i', 'es'] +['iz', 'e'] +['u', 're'] +['Ġb', 'y'] +['i', 're'] +['Ġ}', 'ĊĊ'] +['.', 'p'] +['Ġs', 'h'] +['ic', 'e'] +['a', 'st'] +['pt', 'ion'] +['tr', 'ing'] +['o', 'k'] +['_', '_'] +['c', 'l'] +['#', '#'] +['Ġh', 'e'] +['ar', 'd'] +[')', '.'] +['Ġ', '@'] +['i', 'ew'] +['ĉĉ', 'ĉ'] +['Ġw', 'as'] +['i', 'p'] +['th', 'is'] +['Ġ', 'u'] +['ĠT', 'he'] +['id', 'e'] +['a', 'ce'] +['i', 'b'] +['a', 'c'] +['r', 'ou'] +['Ġw', 'e'] +['j', 'ect'] +['Ġp', 'ublic'] +['a', 'k'] +['v', 'e'] +['at', 'h'] +['o', 'id'] +['Ġ=', '>'] +['u', 'st'] +['q', 'ue'] +['Ġre', 's'] +[')', ')'] +["'", 's'] +['Ġ', 'k'] +['an', 's'] +['y', 'st'] +['un', 'ction'] +['****', '****'] +['Ġ', 'i'] +['Ġ', 'us'] +['p', 'p'] +['on', 'e'] +['a', 'il'] +['==', '=='] +['n', 'ame'] +['Ġst', 'r'] +['Ġ', '/'] +['Ġ', '&'] +['a', 'ch'] +['d', 'iv'] +['yst', 'em'] +['el', 'l'] +['Ġh', 'ave'] +['er', 'r'] +['ou', 'ld'] +['ul', 'l'] +['p', 'on'] +['Ġ', 'J'] +['_', 'p'] +['Ġ=', '='] +['ig', 'n'] +['S', 't'] +['.', 'Ċ'] +['Ġp', 'l'] +[')', ';ĊĊ'] +['f', 'orm'] +['p', 'ut'] +['ou', 'nt'] +['}', 'ĊĊ'] +['d', 'd'] +['it', 'e'] +['Ġg', 'et'] +['r', 'r'] +['om', 'e'] +['Ġ', 'âĢ'] +['ar', 'am'] +['c', 'c'] +['Ġ*', '/'] +['E', 'R'] +['I', 'n'] +['le', 's'] +['_', 's'] +['on', 'g'] +['i', 'e'] +['Ġc', 'an'] +['Ġ', 'V'] +['er', 'v'] +['p', 'r'] +['Ġ', 'un'] +['ro', 'w'] +['b', 'er'] +['Ġd', 'o'] +['l', 'l'] +['Ġ', 'el'] +['Ġs', 'elf'] +['at', 'ed'] +['ar', 'y'] +['Ġ', '.'] +["'", ']'] +['u', 'd'] +['Ġ', 'en'] +['ĠT', 'h'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠ'] +['t', 'e'] +['_', 'c'] +['u', 'ct'] +['Ġa', 'b'] +['or', 'k'] +['.', 'get'] +['Ġ', '#'] +['a', 'w'] +['res', 's'] +['o', 'b'] +['N', 'ame'] +['ap', 'p'] +['[', "'"] +['Ġal', 'l'] +['or', 'y'] +['it', 'ion'] +['an', 'ce'] +['e', 'ar'] +['Ġcon', 't'] +['v', 'ent'] +['i', 'a'] +['Ġw', 'ill'] +['I', 'N'] +['ĠĠĠĠĠĠĠĠ', 'Ġ'] +['re', 'turn'] +['Ġ<', '/'] +['d', 'ata'] +[')', 'ĊĊ'] +['R', 'e'] +['p', 'le'] +['il', 'd'] +['th', 'er'] +['Ġy', 'our'] +['"', 'Ċ'] +['(', '$'] +['Ġ', 'out'] +[')', ','] +['Ġh', 'as'] +['S', 'tring'] +['s', 'o'] +['Ġ', 'up'] +['a', 'x'] +['Ġde', 'f'] +['Ġb', 'o'] +['g', 'e'] +['al', 'se'] +['O', 'N'] +['p', 'er'] +['ic', 'h'] +['Ġb', 'ut'] +['Ġ', 'Ċ'] +['Ġ', '_'] +['_', 'm'] +['ad', 'd'] +['que', 'st'] +['od', 'el'] +['s', 'elf'] +['er', 'y'] +['f', 't'] +['en', 's'] +['//', '//'] +['a', 'ke'] +['.', 'C'] +['Ġg', 'o'] +['Ġf', 'unction'] +['Ġ', 'K'] +['iv', 'ate'] +['Ġ', 'im'] +['Ġcon', 'st'] +['.', 't'] +['Ġ*/', 'Ċ'] +[')', ';čĊ'] +['Ġv', 'oid'] +['Ġs', 'et'] +['ĠS', 'ystem'] +['c', 'ri'] +['(', ')Ċ'] +['l', 'i'] +['ĉ', 'if'] +['.', 'm'] +['al', 'ly'] +['s', 'et'] +['e', 'p'] +['âĢĻ', 's'] +['b', 'o'] +['de', 'f'] +["'", ',Ċ'] +['Ġm', 'e'] +['Ġ', '!'] +['at', 'ch'] +['"', '>'] +['"', ',Ċ'] +['e', 'c'] +['ĠI', 'n'] +['p', 'h'] +['Ġ', '|'] +['_', 'f'] +['Ġv', 'ar'] +['en', 'ce'] +['I', 'd'] +['re', 'e'] +['in', 'k'] +['le', 'ct'] +['u', 'g'] +['et', 'h'] +['Ġel', 'se'] +['--------', '--------'] +['con', 't'] +['Ġs', 'o'] +['at', 'ic'] +['Ġl', 'o'] +['p', 'ro'] +['t', 'on'] +['s', 's'] +['ow', 'n'] +['ab', 'el'] +['o', 'int'] +['ou', 's'] +['el', 'd'] +['S', 'T'] +['T', 'he'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['R', 'E'] +['"', ':'] +['ol', 'or'] +['t', 'p'] +['e', 'g'] +['ke', 'y'] +['u', 'de'] +['ĠS', 't'] +['ou', 'nd'] +['Ġa', 'r'] +['"', ');Ċ'] +['en', 'er'] +['s', 'er'] +['b', 'ject'] +['ess', 'age'] +['f', 'er'] +['Ġm', 'ore'] +['ation', 's'] +['ent', 's'] +['Ġh', 'is'] +['Ġthe', 'y'] +['.', 'S'] +['Ġ', 'Y'] +['u', 'se'] +['n', 'e'] +['is', 'h'] +['ol', 'd'] +['_', 'd'] +['i', 'o'] +['i', 'eld'] +['Ġp', 'er'] +['C', 'ont'] +['ing', 's'] +['##', '##'] +['Ġd', 'ata'] +['Ġs', 'a'] +['e', 'f'] +['f', 'o'] +['Ġon', 'e'] +['en', 'g'] +['Ġd', 'is'] +['A', 'T'] +['Ġn', 'ame'] +['Ġtr', 'ue'] +['v', 'al'] +['le', 'd'] +['.', 'f'] +['Ġn', 'e'] +['Ġ', 'end'] +['.', 'T'] +['c', 're'] +['ar', 'k'] +['lo', 'g'] +['E', 'x'] +['err', 'or'] +['_', 'id'] +['ur', 're'] +['ang', 'e'] +['Ġn', 'ull'] +['rr', 'ay'] +['Ġm', 'y'] +['p', 'an'] +['ic', 't'] +['at', 'or'] +['V', 'iew'] +['L', 'ist'] +['ĉ', 'return'] +['âĢ', 'Ŀ'] +['Ġp', 're'] +['Ġ', 'x'] +['cl', 'ude'] +['ar', 'g'] +['o', 'v'] +['.', 'h'] +['Ġ', '>'] +['Ġthe', 'ir'] +["'", ')'] +['ir', 'st'] +['ic', 'k'] +['g', 'h'] +['L', 'E'] +['O', 'R'] +['Ġpr', 'ivate'] +['t', 'em'] +['čĊ', 'čĊ'] +['us', 'er'] +['Ġ', ')'] +['c', 'om'] +['.', 'A'] +['"', ';Ċ'] +['Ġ', 'id'] +['re', 'ad'] +['Ġwh', 'o'] +['_', 'b'] +['"', '>Ċ'] +['Ġt', 'ime'] +['Ġm', 'an'] +['r', 'y'] +['====', '===='] +['rou', 'p'] +['ro', 'p'] +['p', 'ublic'] +['v', 'el'] +['um', 'ber'] +['b', 'le'] +['Ġwh', 'ich'] +['********', '********'] +['Ġan', 'y'] +['Ġf', 'alse'] +['w', 'e'] +['Ġv', 'alue'] +['Ġl', 'i'] +['"', ')'] +['nd', 'er'] +['g', 'r'] +['Ġn', 'o'] +['p', 'aram'] +['f', 'ig'] +['.c', 'om'] +['Ġa', 'pp'] +['_', 'l'] +['ion', 's'] +['.', 'D'] +['ĠC', 'h'] +['Ġab', 'out'] +['Ġa', 'dd'] +['Ġs', 'u'] +['Ġstr', 'ing'] +['I', 'D'] +['Ġo', 'ver'] +['str', 'ing'] +['.', 'l'] +['our', 'ce'] +['_', 'C'] +[']', 'Ċ'] +['Ġ', 'qu'] +['ĠS', 'tring'] +['c', 'a'] +['S', 'E'] +['Ġ', 'ro'] +['s', 'h'] +['u', 'al'] +['T', 'ype'] +['s', 'on'] +['n', 'ew'] +['er', 'n'] +['Ġa', 'g'] +['A', 'R'] +[']', ';Ċ'] +[']', '.'] +['Ġ', '?'] +['ic', 'al'] +['Ġd', 'es'] +['ut', 'h'] +['i', 'x'] +['ay', 's'] +['Ġt', 'ype'] +["'", 't'] +['a', 'ult'] +['Ġin', 'ter'] +['v', 'ar'] +['.', 'b'] +['Ġp', 'art'] +['.', 'd'] +['urre', 'nt'] +['I', 'T'] +['E', 'N'] +['en', 'c'] +['(', 'f'] +['r', 'a'] +['v', 'alue'] +['ch', 'o'] +['ut', 'ton'] +['o', 'se'] +['Ġ!', '='] +['at', 'er'] +['Ã', '©'] +['re', 'ate'] +['ol', 'l'] +['p', 'os'] +['y', 'le'] +['n', 'g'] +['A', 'L'] +['us', 'ing'] +['am', 'es'] +['Ġ{', 'čĊ'] +['at', 'es'] +['el', 'y'] +['Ġw', 'ork'] +['Ġ', 'em'] +['in', 'al'] +['Ġs', 'p'] +['Ġwh', 'en'] +['.s', 'et'] +['ĠĠĠĠ', 'ĠĠ'] +[')', ':Ċ'] +['t', 'o'] +['qu', 'ire'] +['ind', 'ow'] +['le', 'ment'] +['pe', 'ct'] +['as', 'h'] +['[', 'i'] +['Ġu', 'se'] +['.', 'F'] +['pe', 'c'] +['Ġa', 'd'] +['o', 've'] +['ce', 'ption'] +['eng', 'th'] +['in', 'clude'] +['ad', 'er'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠ'] +['at', 'us'] +['T', 'h'] +['it', 'le'] +['r', 'it'] +['v', 'oid'] +['()', '.'] +['(', 'Ċ'] +['Ġof', 'f'] +['Ġo', 'ther'] +['Ġ&', '&'] +["'", ';Ċ'] +['m', 's'] +['Ġbe', 'en'] +['Ġt', 'e'] +['m', 'l'] +['c', 'o'] +['n', 'c'] +['erv', 'ice'] +['Ġ', '%'] +['**', 'Ċ'] +['an', 'n'] +['ad', 'e'] +['ĊĊ', 'ĊĊ'] +['lo', 'ck'] +['con', 'st'] +['pon', 'se'] +['Ġs', 'up'] +['+', '+'] +['d', 'ate'] +['Ġa', 'cc'] +['Ġh', 'ad'] +['Ġb', 'u'] +['ĠR', 'e'] +['Ġw', 'ere'] +['Ġf', 'ile'] +['Ġw', 'ould'] +['ĠâĢ', 'ľ'] +['v', 'en'] +['is', 's'] +['Ġ', 'our'] +['c', 'lass'] +['r', 'aw'] +['Ġy', 'ear'] +['D', 'ata'] +['Ġv', 'al'] +['Ġs', 'ome'] +['f', 'ter'] +['y', 's'] +['Ġ//', '/'] +['rou', 'nd'] +['v', 'iew'] +['Ġp', 'e'] +['Ġth', 'ere'] +['Ġsa', 'id'] +['d', 'u'] +['o', 'f'] +['l', 'ine'] +['/', '*'] +['d', 'uct'] +['Ġh', 'er'] +['ĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠ'] +['R', 'es'] +['Ġc', 'o'] +['Ġcom', 'm'] +['is', 'e'] +['m', 'in'] +['ĠĠĠĠ', 'Ċ'] +['#', 'include'] +['eth', 'od'] +['.', 'P'] +['ut', 'e'] +['Ġas', 's'] +['I', 'nt'] +['as', 'k'] +['lo', 'c'] +['Ġli', 'ke'] +['od', 'y'] +['Ġle', 't'] +['lo', 'ad'] +['Ġa', 'm'] +['ro', 'l'] +['Ġg', 'r'] +['y', 'p'] +['Ġal', 'so'] +['ĠI', 't'] +['ur', 'l'] +['if', 'ic'] +['or', 's'] +['_', 'P'] +['_', 'n'] +['ig', 'h'] +['Ġth', 'an'] +['C', 'om'] +['A', 'N'] +['U', 'L'] +['at', 'ing'] +['ĠTh', 'is'] +['re', 'f'] +['_', 'S'] +['Ġst', 'atic'] +['ro', 'll'] +['Ġj', 'ust'] +['Ġres', 'ult'] +['i', 'an'] +['id', 'th'] +['Ġthe', 'm'] +[')', ');Ċ'] +['d', 'er'] +['re', 'ak'] +['C', 'on'] +[':', '//'] +['u', 'le'] +['..', '.'] +['ar', 'ch'] +['em', 'ent'] +['Ġ<', '<'] +['us', 'h'] +['en', 'se'] +['ar', 'r'] +['Ġint', 'o'] +['c', 'ess'] +['am', 'p'] +['i', 'ed'] +['um', 'ent'] +['Ġ', '\\'] +[']', ','] +['w', 'o'] +['al', 's'] +['Ġwh', 'at'] +['an', 'c'] +['V', 'alue'] +['=', "'"] +['ol', 'um'] +['Ġp', 'os'] +['ag', 'es'] +['ay', 'er'] +['Ġs', 'c'] +['u', 'es'] +['"', ')Ċ'] +['_', 'T'] +['Ġl', 'ist'] +['(', 's'] +['Ġc', 'ase'] +['C', 'h'] +['ĉĉĉĉ', 'ĉ'] +['////', '////'] +['pon', 'ent'] +['Ġ', 'z'] +['Ġk', 'n'] +['le', 't'] +['D', 'E'] +['re', 'd'] +['Ġf', 'e'] +['Ġ}', ',Ċ'] +['Ġ', ','] +['(', 't'] +['Ġf', 'irst'] +["'", ');Ċ'] +['w', 'ord'] +['Ġ', 'import'] +['Ġa', 'ct'] +['Ġch', 'ar'] +['C', 'T'] +['ĠT', 'r'] +['op', 'le'] +['=', '{'] +['ĉ', 'f'] +['i', 'ent'] +['c', 'ent'] +['.', 'j'] +['le', 'ction'] +[')', ')Ċ'] +['Ġon', 'ly'] +['Ġpr', 'int'] +['m', 'er'] +['.', 'W'] +['o', 'ck'] +['Ġ', '--'] +['T', 'ext'] +['Ġo', 'p'] +['an', 'k'] +['Ġit', 's'] +['Ġb', 'ack'] +['[', '"'] +['Ġne', 'ed'] +['Ġc', 'l'] +['Ġs', 'ub'] +['Ġl', 'a'] +['(', '('] +['.', '"'] +['O', 'bject'] +['Ġst', 'art'] +['f', 'ile'] +['(', 'self'] +['n', 'er'] +['e', 'y'] +['Ġus', 'er'] +['Ġ', 'ent'] +['ĠC', 'om'] +['it', 's'] +['ĠC', 'on'] +['ou', 'ble'] +['ow', 'er'] +['it', 'em'] +['ver', 'y'] +['ĠW', 'e'] +['lic', 'k'] +['Ġ', 'Q'] +['ph', 'p'] +['t', 'tp'] +["'", ':'] +['ic', 's'] +['Ġu', 'nder'] +['Ġ*', 'Ċ'] +['.', 'L'] +[')', ';'] +['ic', 'es'] +['Ġre', 'g'] +[')', 'čĊ'] +['ĉ', 'public'] +['S', 'S'] +['Ġth', 'en'] +['re', 'at'] +['i', 'ous'] +['.', 'G'] +['e', 'k'] +['ire', 'ct'] +['he', 'ck'] +['cri', 'pt'] +['n', 'ing'] +['ĠU', 'n'] +['Ġm', 'ay'] +['ĠW', 'h'] +['B', 'o'] +['I', 'tem'] +['str', 'uct'] +['.', 'st'] +['re', 'am'] +['ib', 'le'] +['lo', 'at'] +['Ġor', 'g'] +['u', 'nd'] +['s', 'um'] +['_', 'in'] +['..', '/'] +['_', 'M'] +['Ġh', 'ow'] +['r', 'ite'] +["'", 'Ċ'] +['T', 'o'] +['w', 'w'] +['Ġpe', 'ople'] +['ind', 'ex'] +['.', 'n'] +['ht', 'tp'] +['(', 'm'] +['ect', 'or'] +['Ġin', 'd'] +['Ġj', 'av'] +[']', ',Ċ'] +['ĠH', 'e'] +['_', 'st'] +['f', 'ul'] +['o', 'le'] +[')', '{Ċ'] +['Ġsh', 'ould'] +['op', 'y'] +['el', 'p'] +['i', 'er'] +['_', 'name'] +['ers', 'on'] +['I', 'ON'] +['ot', 'e'] +['Ġt', 'est'] +['Ġb', 'et'] +['rr', 'or'] +['ul', 'ar'] +['ã', 'Ģ'] +['Ġ', 'Ð'] +['b', 's'] +['t', 'ing'] +['Ġm', 'ake'] +['T', 'r'] +['Ġa', 'fter'] +['ar', 'get'] +['R', 'O'] +['olum', 'n'] +['r', 'c'] +['_', 're'] +['def', 'ine'] +['Ġr', 'ight'] +['r', 'ight'] +['d', 'ay'] +['Ġl', 'ong'] +['[', ']'] +['(', 'p'] +['t', 'd'] +['con', 'd'] +['ĠP', 'ro'] +['Ġre', 'm'] +['ption', 's'] +['v', 'id'] +['.', 'g'] +['Ġ', 'ext'] +['Ġ', '__'] +["'", ')Ċ'] +['p', 'ace'] +['m', 'p'] +['Ġm', 'in'] +['st', 'ance'] +['a', 'ir'] +['a', 'ction'] +['w', 'h'] +['t', 'ype'] +['ut', 'il'] +['a', 'it'] +['<', '?'] +['I', 'C'] +['t', 'ext'] +['Ġp', 'h'] +['Ġf', 'l'] +['.', 'M'] +['cc', 'ess'] +['b', 'r'] +['f', 'ore'] +['ers', 'ion'] +[')', ',Ċ'] +['.', 're'] +['ate', 'g'] +['Ġl', 'oc'] +['in', 's'] +['-', 's'] +['tr', 'ib'] +['ĠI', 'nt'] +['Ġa', 'rray'] +[',', '"'] +['P', 'ro'] +['(', 'c'] +['ess', 'ion'] +['>', 'ĊĊ'] +['Ġs', 'he'] +['"', ']'] +['ap', 'h'] +['Ġex', 'p'] +['ert', 'y'] +['ĠS', 'e'] +['Ġp', 'ar'] +['un', 'c'] +['E', 'T'] +['Ġre', 'ad'] +['pr', 'int'] +['Ġre', 'l'] +['Ġfor', 'm'] +['Ġd', 'r'] +['Ex', 'ception'] +['in', 'put'] +['Ġtr', 'ans'] +['####', '####'] +['ord', 'er'] +['B', 'y'] +['Ġa', 'w'] +['it', 'ies'] +['u', 'ff'] +['pl', 'ay'] +['.', 'add'] +['ĠâĢ', 'ĵ'] +['Ġw', 'ant'] +['Ġcom', 'p'] +['ment', 's'] +['Ġ|', '|'] +['a', 'z'] +['b', 'e'] +['Ġn', 'umber'] +['Ġre', 'quire'] +['ĠE', 'x'] +['Ġc', 'ol'] +['Ġ', 'key'] +['em', 'ber'] +['Ġt', 'wo'] +['Ġs', 'ize'] +['Ġwh', 'ere'] +['U', 'T'] +['res', 'ult'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['ou', 'gh'] +['or', 'ld'] +['o', 'od'] +['u', 'ch'] +['at', 'ive'] +['g', 'er'] +['are', 'nt'] +['Ġ/', '*'] +['Ġar', 'g'] +['Ġwh', 'ile'] +['(', 'this'] +['Ġre', 'c'] +['Ġd', 'if'] +['St', 'ate'] +['Ġs', 'pec'] +['r', 'ide'] +['_', 'F'] +['Ġlo', 'ok'] +['A', 'M'] +['il', 'ity'] +['et', 'er'] +['âĢĻ', 't'] +['ĊĊ', 'Ċ'] +['ay', 'out'] +['----------------', '----------------'] +['ag', 'er'] +['Ġc', 'ould'] +['Ġb', 'r'] +['end', 's'] +['u', 'res'] +['Ġkn', 'ow'] +['et', 's'] +['ĠI', 'f'] +['ĠS', 'h'] +['.', 'w'] +['b', 'ack'] +['Ġs', 'er'] +['Ġ+', '='] +['Ġf', 'r'] +['()', ');Ċ'] +['Ġh', 'and'] +['I', 'nd'] +['UL', 'L'] +['I', 'm'] +['()', ';ĊĊ'] +['Ġm', 'ost'] +['Ġtr', 'y'] +['Ġn', 'ow'] +['rou', 'gh'] +['>', 'čĊ'] +['ack', 'age'] +['Ġh', 'im'] +['.', '_'] +['if', 'y'] +['Ġb', 'reak'] +['Ġ', ');Ċ'] +['re', 'n'] +['#', 'define'] +['it', 't'] +['Ġa', 'p'] +['ĉ', 'c'] +['(', 'n'] +['ĠY', 'ou'] +[':', 'ĊĊ'] +['-', 'm'] +['Ġe', 'very'] +['ust', 'om'] +['li', 'ent'] +['oc', 'ument'] +['cri', 'ption'] +['E', 'rror'] +['-', 'b'] +['Ð', '¾'] +[']', '['] +['tr', 'ans'] +['Ġp', 'oint'] +['Ġst', 'd'] +['Ġf', 'il'] +['T', 'ime'] +['Ġm', 'od'] +['Ġ', '->'] +['Ġ', 'error'] +['a', 'h'] +['Ġt', 'ext'] +['roll', 'er'] +['lo', 'se'] +['q', 'l'] +['Ġp', 'ol'] +['>', '', '<'] +['.', 'B'] +['-', 'c'] +['Ġop', 'en'] +['Ġe', 'st'] +['ĠĠĠĠĠĠĠĠ', 'Ċ'] +['Ġn', 'ext'] +['I', 'M'] +['Ñ', 'Ĥ'] +['O', 'T'] +['Ã', '³'] +['Ġf', 'ollow'] +['cont', 'ent'] +['ĠĠĠĠĠĠĠĠ', 'ĠĠĠĠ'] +['Ġin', 'clud'] +['H', 'E'] +['ĠR', 'es'] +['Ġh', 'ref'] +['Ð', '¸'] +['Ġc', 'ar'] +['yp', 'es'] +['im', 'age'] +['U', 'n'] +['Ġbo', 'ol'] +['A', 'D'] +['Ġg', 'ame'] +['.F', 'orm'] +['row', 's'] +['*', '/'] +['vel', 'op'] +['.D', 'rawing'] +['Ġp', 'ath'] +['is', 'ion'] +['Ġe', 'ach'] +['ĠP', 'l'] +['_t', 'ype'] +['P', 'ath'] +['ne', 'ction'] +['Ġa', 'v'] +["'", ').'] +['Ġsup', 'port'] +['EN', 'T'] +['re', 'm'] +['"', ').'] +['Ġo', 'wn'] +['Ġc', 'or'] +['c', 'ount'] +['m', 'iss'] +['u', 'ally'] +['Ġm', 'em'] +['st', 'd'] +['i', 'ence'] +['se', 'arch'] +['"', 'ĊĊ'] +['F', 'orm'] +['Ġs', 'ex'] +['en', 'ame'] +['Ġs', 'ign'] +['Ġ', 'et'] +['ĠĠĠĠĠĠĠĠ', 'ĠĠ'] +["',", "'"] +['ĠA', 'pp'] +['Ġth', 'ose'] +['o', 'ff'] +['Ġ', 'err'] +['Ġs', 'ystem'] +['Ġbe', 'st'] +['c', 'ode'] +['Ġs', 'ame'] +['Ġd', 'i'] +['us', 's'] +['Ġc', 'reate'] +['ath', 'er'] +['A', 'rray'] +['.', 'in'] +['f', 'e'] +['S', 'ervice'] +['U', 'N'] +['at', 's'] +['Ġ', 'Z'] +['al', 'th'] +['Ġm', 'ade'] +['tr', 'ue'] +['A', 'B'] +['Ġm', 'ark'] +['r', 'id'] +['if', 'ied'] +[',', 'čĊ'] +['y', 'n'] +['p', 'ress'] +['Ġg', 'roup'] +['Ġf', 'in'] +['ĠL', 'icense'] +['F', 'ield'] +['eg', 'er'] +['Ġw', 'orld'] +['in', 'ess'] +['t', 'y'] +['Ġpro', 'cess'] +['(', 'b'] +['Ġc', 're'] +['ar', 'n'] +['iv', 'es'] +['Ġm', 'ain'] +['ide', 'o'] +['_', 'g'] +['A', 'G'] +['val', 'id'] +['im', 'g'] +['P', 'I'] +['Ġc', 'olor'] +['Ġre', 'port'] +['Ġt', 'ake'] +['ri', 'b'] +['O', 'M'] +['Ġd', 'ay'] +['Re', 'quest'] +['Ġs', 'k'] +['b', 'ers'] +['ĉ', 's'] +['.A', 'dd'] +['o', 'ot'] +['Im', 'age'] +['Ġcom', 'ple'] +['ol', 'lection'] +['Ġto', 'p'] +['Ġf', 'ree'] +['A', 'S'] +['D', 'e'] +['ĠO', 'n'] +['I', 'G'] +['et', 'a'] +['D', 'ate'] +['Ġa', 'ction'] +['O', 'ver'] +['it', 'or'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['n', 'ot'] +['Ġind', 'ex'] +['h', 'er'] +['ic', 'on'] +['O', 'n'] +[';čĊ', 'čĊ'] +['iv', 'ity'] +['m', 'and'] +['.W', 'indows'] +['O', 'L'] +['Ġre', 'al'] +['Ġm', 'ax'] +['l', 'and'] +['..', '..'] +['r', 'aph'] +['Ġbu', 'ild'] +['le', 'g'] +['ass', 'word'] +['?', 'ĊĊ'] +['âĢ', '¦'] +['o', 'ok'] +['u', 'ck'] +['Ġm', 'essage'] +['t', 'est'] +['iv', 'ers'] +['Ġin', 'put'] +['Ġar', 't'] +['Ġbet', 'ween'] +['G', 'et'] +['ent', 'er'] +['g', 'round'] +['en', 'e'] +['Ã', '¡'] +['.l', 'ength'] +['N', 'ode'] +['(', 'i'] +['C', 'lass'] +['f', 'or'] +['ĠâĢ', 'Ķ'] +['t', 'en'] +['o', 'in'] +['Ġ', 'ke'] +['u', 'i'] +['ĠI', 'N'] +['Ġt', 'able'] +['s', 'ub'] +['ĠL', 'e'] +['Ġhe', 'ad'] +['Ġm', 'ust'] +['////////', '////////'] +['.', 'util'] +['Cont', 'ext'] +['Ġor', 'der'] +['Ġm', 'ov'] +['o', 'ver'] +['Ġcont', 'in'] +['Ġs', 'ay'] +['st', 'atic'] +['.T', 'ext'] +['Ġclass', 'Name'] +['pan', 'y'] +['Ġt', 'er'] +['he', 'ad'] +['r', 'g'] +['Ġpro', 'duct'] +['Th', 'is'] +['.', 'âĢĿ'] +['ĠB', 'ut'] +['lo', 'y'] +['Ġd', 'ouble'] +['s', 'g'] +['Ġpl', 'ace'] +['.', 'x'] +['m', 'essage'] +['Ġin', 'formation'] +['pr', 'ivate'] +['Ġo', 'per'] +['c', 'ed'] +['d', 'b'] +['">', ''] +['ater', 'ial'] +['ile', 'd'] +['Ġp', 'ut'] +['Q', 'u'] +['Ñ', 'Ģ'] +['un', 'g'] +['m', 'ap'] +['ĉĉĉĉ', 'ĉĉĉĉ'] +['Ġle', 'vel'] +['Com', 'ponent'] +['bo', 'ok'] +['cre', 'en'] +['_', 'RE'] +['Ġcon', 'fig'] +['ã', 'ģ'] +['O', 'r'] +['.', 'data'] +['Ġd', 'ocument'] +['",', '"'] +['trib', 'ute'] +['u', 'x'] +['L', 'og'] +['fer', 'ence'] +['p', 'ost'] +['_', 'e'] +['Ġloc', 'al'] +['and', 'om'] +['ass', 'ert'] +['V', 'al'] +['lect', 'ed'] +['in', 'a'] +['atab', 'ase'] +['A', 'dd'] +['Ġcont', 'ent'] +['.p', 'rint'] +['s', 'igned'] +['r', 'ic'] +['."', 'ĊĊ'] +['Ġf', 'a'] +['!', 'ĊĊ'] +['-', 'f'] +['iv', 'ed'] +['Ġ', 'quest'] +['.', 'ex'] +['Ġf', 'loat'] +['Ġde', 'velop'] +['о', 'Ð'] +['M', 'ap'] +['ad', 'ing'] +['Ġpos', 's'] +['U', 'E'] +['n', 'amespace'] +['_', 'O'] +['ĉ', 'b'] +['.G', 'et'] +['>', '('] +['j', 'son'] +['etail', 's'] +['Ġto', 'o'] +['Ġext', 'ends'] +['ĠN', 'one'] +['Ġf', 'ore'] +['(', 'String'] +['form', 'at'] +['Ġg', 'reat'] +['int', 'er'] +['ca', 'le'] +['Ñ', 'ģ'] +['r', 'on'] +['iv', 'ing'] +['E', 'nt'] +['enc', 'y'] +['x', 't'] +['o', 'y'] +['Ġmon', 'th'] +['Ġh', 'app'] +['Ġsup', 'er'] +['b', 'ar'] +['def', 'ault'] +['_', 'de'] +['ord', 's'] +['l', 'n'] +['(', '{Ċ'] +['ĠI', 'nd'] +['as', 'es'] +['Ġt', 'itle'] +['Ġcont', 'ext'] +['o', 'h'] +['-', 'p'] +['E', 'm'] +['Ġm', 'et'] +['T', 'est'] +['Ġl', 'ife'] +['_', 'v'] +['ĠU', 'S'] +['U', 'I'] +['oc', 'ation'] +['m', 'd'] +['Ġ[', 'Ċ'] +['Ġ', ']'] +['s', 'w'] +['Ġin', 'cre'] +['s', 'cript'] +['ent', 'ial'] +['w', 'ays'] +['.', 'de'] +['Ġs', 'rc'] +['Ġc', 'atch'] +['ĠA', 'meric'] +['//', 'Ċ'] +['ĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠ'] +['Ġp', 'ay'] +['pl', 'it'] +['âĢ', 'Ķ'] +['Ġc', 'oun'] +['ob', 'j'] +['.ph', 'p'] +['Ġch', 'ange'] +['eth', 'ing'] +["'", 're'] +['ast', 'er'] +['lo', 's'] +['l', 'ation'] +['ĠĠ', 'Ċ'] +['L', 'e'] +['Ã', '¤'] +['(', '{'] +['read', 'y'] +['ĠN', 'o'] +['Ġpos', 'ition'] +['Ġo', 'ld'] +['Ġbo', 'ok'] +['able', 'd'] +['b', 'ug'] +['H', 'and'] +['}', ';ĊĊ'] +['is', 'play'] +['av', 'ing'] +['Ġgo', 'ver'] +['Ġv', 'ersion'] +['S', 'ystem'] +['n', 'ect'] +['res', 'ponse'] +['St', 'yle'] +['U', 'p'] +['ang', 'u'] +['Ġth', 'ree'] +['in', 'it'] +['er', 'o'] +['Ġl', 'aw'] +['end', 'if'] +['Ġb', 'ase'] +['em', 'ail'] +['(', 'l'] +['_', 'V'] +['Ġcon', 'f'] +['AT', 'E'] +['Ġd', 'uring'] +['t', 'es'] +['Ġcon', 'sole'] +['ĠP', 'r'] +['Ġs', 'pe'] +['v', 'es'] +['p', 'ath'] +['ial', 'og'] +['d', 'ition'] +['_t', 'o'] +['ard', 's'] +['Ġagain', 'st'] +['et', 'work'] +['ĠP', 'h'] +['_', 'L'] +['c', 'ur'] +['im', 'it'] +['W', 'ith'] +['Ġp', 'ower'] +['i', 'um'] +["'", ';ĊĊ'] +['Ġw', 'om'] +['le', 'ft'] +['our', 'ces'] +['at', 'ri'] +['ĠI', 'm'] +['ĠM', 'an'] +['or', 'th'] +['$', '{'] +['qu', 'als'] +['es', 'e'] +['_s', 'ize'] +['Ġis', 's'] +['ot', 'al'] +['-', 'g'] +['i', 'que'] +['r', 'ame'] +['Ġw', 'idth'] +['er', 'g'] +[')', '('] +['itt', 'le'] +['T', 'R'] +['ĠThe', 'y'] +['enc', 'es'] +['r', 'l'] +['on', 's'] +['Ġl', 'abel'] +['.', 'y'] +['-', 't'] +['up', 'date'] +['an', 'el'] +['s', 'c'] +['.t', 'o'] +['Ġpro', 'ject'] +['Ã', '¼'] +['Ġe', 'lement'] +['Ġsu', 'ccess'] +['ĉĉ', 'Ċ'] +['.s', 'h'] +['r', 'am'] +['ch', 'ed'] +['()', ')Ċ'] +['Ġ(', 'Ċ'] +['Ġd', 'ate'] +['Ġto', 't'] +['_', 'ST'] +['A', 'll'] +['ific', 'ation'] +['ĉ', 'var'] +['Ġt', 'ri'] +['ch', 'em'] +['m', 'y'] +['Ġb', 'ig'] +['ĠA', 'd'] +['ĠA', 't'] +['ot', 's'] +['n', 'um'] +['A', 'ct'] +['Ġm', 'ap'] +['er', 'a'] +['co', 'pe'] +['.', '$'] +[',', 'âĢĿ'] +['Ġp', 'op'] +['Ġf', 'ew'] +['Ġl', 'en'] +['u', 'id'] +['et', 'ers'] +['u', 'les'] +['Ã', 'Ń'] +['s', 'ource'] +['http', 's'] +['Ġd', 'em'] +['Ġe', 'ar'] +['########', '########'] +['Ġm', 'atch'] +['or', 'ies'] +['ac', 'es'] +['ĠC', 'l'] +['Ġn', 'ode'] +['ir', 'c'] +['loc', 'al'] +['un', 'ity'] +['}', ';Ċ'] +['Ġan', 'other'] +['<', '<'] +['og', 'le'] +['Ġs', 'it'] +['ew', 'ork'] +['T', 'E'] +['.', 'I'] +['N', 'S'] +['olog', 'y'] +['ou', 'ght'] +['.C', 'ont'] +['>', '>'] +['Ġc', 'are'] +['st', 'ate'] +['ĉ', 'private'] +['Ġe', 'ffect'] +['++', ')'] +['_f', 'ile'] +['end', 'ing'] +['L', 'ine'] +['F', 'or'] +['i', 'or'] +['ĠS', 'c'] +['Ġf', 'un'] +['.S', 'ize'] +['ĉ', 'else'] +[']', ')'] +['st', 'art'] +['v', 'ious'] +['Ġ}', ','] +['our', 's'] +['Ġle', 'g'] +['Ġs', 'ervice'] +['Ġs', 'ince'] +['ir', 'on'] +['L', 'abel'] +['Ġn', 'on'] +['Ġl', 'os'] +['ict', 'ion'] +['Ġf', 'ull'] +['act', 'er'] +['bo', 'ard'] +['g', 'ress'] +['Ġt', 'urn'] +['ith', 'er'] +['.s', 'ize'] +['Ġb', 'ody'] +['res', 'h'] +['et', 'urn'] +['(', '_'] +['y', 'les'] +['orm', 'al'] +['p', 'i'] +['Ġsom', 'ething'] +['!', '--'] +['u', 'int'] +['Ġpro', 'du'] +['Ġst', 'and'] +['Ġpro', 'ble'] +['Ġav', 'ailable'] +['m', 't'] +['ĠB', 'l'] +['Ġ', '...'] +['Ġb', 'lock'] +['In', 'put'] +['Ġke', 'ep'] +['C', 'ount'] +['op', 'en'] +['Ġ[', "'"] +['Ġth', 'row'] +['uild', 'er'] +['A', 'ction'] +['Ġth', 'ings'] +['Tr', 'ue'] +['Ġ', 'url'] +['ĠB', 'o'] +['print', 'f'] +['Ġre', 'd'] +['j', 's'] +['.c', 'reate'] +['ĠO', 'r'] +['St', 'atus'] +['In', 'stance'] +['Ġcont', 'rol'] +['Ġcom', 'e'] +['Ġc', 'ustom'] +['loc', 'ation'] +['m', 'odel'] +['Ġ', 'čĊ'] +['Ġs', 'ource'] +['Ġe', 'as'] +['.', 'out'] +[']', 'ĊĊ'] +['one', 'y'] +['Ġaw', 'ait'] +['Ġpart', 'ic'] +['A', 'P'] +['ub', 'lish'] +['od', 'es'] +['_p', 'ro'] +['p', 'ly'] +['rit', 'er'] +['Ġpro', 'v'] +['Ġm', 'ill'] +['H', 'T'] +[']', ')Ċ'] +['Ġch', 'ang'] +['Ġas', 'k'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠ'] +['Ġout', 'put'] +['Ġem', 'ail'] +['.p', 'ush'] +['Ġ}', 'čĊčĊ'] +['in', 'ation'] +['atri', 'x'] +['T', 'able'] +['u', 'ccess'] +[']', ');Ċ'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġdis', 'c'] +['(', '['] +['Ġb', 'usiness'] +['he', 'ight'] +['.', 'html'] +['t', 'a'] +['f', 'ield'] +['Ġrequire', 'd'] +['_', 'R'] +['Ġgover', 'n'] +['}', 'čĊčĊ'] +['le', 'x'] +['.', ','] +['ĠS', 'et'] +['ur', 'ch'] +['//', '/'] +['t', 's'] +['a', 'f'] +['Ġm', 'ight'] +['ist', 'ory'] +['S', 'tr'] +['Ġne', 'ver'] +['Res', 'ponse'] +['ar', 'se'] +['ad', 'a'] +['ĠH', 'ow'] +['Ġ*', ')'] +['Ġ', ';'] +['Ġh', 'ard'] +['A', 'd'] +['Ġinter', 'n'] +['us', 'ed'] +['(', 'data'] +['m', 'od'] +['ann', 'el'] +['Ġn', 'p'] +['ug', 'g'] +['Ġ/', '>Ċ'] +['Ġcal', 'led'] +['b', 'ody'] +['Ġch', 'o'] +['(', 'r'] +['_s', 'et'] +['ir', 'd'] +['Ġ>', '='] +['Ġ}', ';Ċ'] +['Ġo', 'ptions'] +['ĠG', 'ener'] +['Ġhe', 'ight'] +['P', 'oint'] +['Y', 'ou'] +['et', 'y'] +['C', 'lick'] +['Ġsm', 'all'] +['Ġ', 'ide'] +['Ġacc', 'ess'] +['angu', 'age'] +['Ġprot', 'ected'] +['Ġj', 'ob'] +['ĠTh', 'ere'] +['D', 'ef'] +['Ġadd', 'ress'] +['Ġu', 'int'] +['N', 'ot'] +['o', 'o'] +['ap', 's'] +['<', 'div'] +['ain', 'ed'] +['at', 'ur'] +['Ġs', 'um'] +['-', 'w'] +['ĠD', 'ate'] +['Ġl', 'ittle'] +['Ġf', 'ri'] +['Y', 'PE'] +['Ġp', 'ort'] +['e', 'h'] +['pr', 'ing'] +['_p', 'ath'] +['Ġst', 'atus'] +['a', 'im'] +['bo', 'ol'] +['Ġap', 'pe'] +['Ġo', 's'] +['.', 'name'] +['ens', 'ion'] +['_', 'G'] +['Ġup', 'date'] +['Con', 'fig'] +['a', 'ff'] +['ER', 'R'] +['Ġ<', '='] +['at', 'ely'] +['#', 'if'] +['u', 'ction'] +['ĠT', 'e'] +['Ġl', 'ink'] +['ĠU', 'ser'] +['.f', 'ind'] +['.', 'org'] +['m', 'e'] +['Ġg', 'iven'] +['O', 'ut'] +['#', 'endif'] +['Ġbet', 'ter'] +['P', 'age'] +['Ġfe', 'el'] +['en', 'n'] +['M', 'L'] +['Ġal', 'ready'] +['Ġinclud', 'ing'] +['o', 'ogle'] +['r', 'u'] +['ic', 'ally'] +['pro', 'p'] +['le', 'an'] +['out', 'er'] +['Ġal', 'ways'] +['ord', 'ing'] +['I', 'f'] +['or', 'age'] +['Ġp', 'arent'] +['v', 'is'] +['ĉĉĉĉ', 'ĉĉĉ'] +['Ġg', 'ot'] +['st', 'and'] +['Ġle', 'ss'] +['/', 's'] +['ĠA', 'ss'] +['ap', 't'] +['ire', 'd'] +['ĠA', 'dd'] +['Ġacc', 'ount'] +['p', 'loy'] +['Ġd', 'er'] +['res', 'ent'] +['Ġl', 'ot'] +['Ġval', 'id'] +['ĉ', 'd'] +['Ġb', 'it'] +['pon', 'ents'] +['Ġfollow', 'ing'] +['_', 'ex'] +['S', 'ON'] +['Ġs', 'ure'] +['oc', 'ial'] +['Ġp', 'rom'] +['ert', 'ies'] +['he', 'ader'] +['.p', 'ro'] +['Ġbo', 'olean'] +['Ġse', 'arch'] +['k', 'en'] +['Ġor', 'ig'] +['Ġ', 'er'] +['E', 'd'] +['E', 'M'] +['a', 'ut'] +['l', 'ing'] +['al', 'ity'] +['By', 'Id'] +['b', 'ed'] +['ĉc', 'ase'] +['eth', 'er'] +['pos', 'it'] +['Ġinv', 'est'] +['ĠO', 'R'] +['Ġs', 'ays'] +['miss', 'ion'] +['AM', 'E'] +['Ġtem', 'p'] +['o', 'ad'] +['Ġre', 'st'] +['in', 'fo'] +['Ġinter', 'est'] +['A', 'rg'] +['Ġper', 'form'] +['pon', 's'] +['ĠV', 'iew'] +['Ġv', 'er'] +['l', 'ib'] +['(', 'const'] +['U', 'til'] +['List', 'ener'] +['ar', 'ge'] +['Ġm', 'ult'] +['Ġd', 'ie'] +['Ġs', 'ite'] +['../', '../'] +['E', 'L'] +['Ġval', 'ues'] +['Ġ}', ')Ċ'] +['p', 'en'] +['N', 'o'] +['ic', 'ro'] +['Ġbe', 'h'] +["Ġ'", './'] +['ac', 'y'] +['re', 'c'] +['()', '->'] +['ĉ', 'ĠĠĠ'] +['"', '))'] +['Cont', 'ent'] +['_', 'W'] +['ple', 'ment'] +['Ġw', 'on'] +['Ġv', 'ideo'] +['ad', 'i'] +['p', 'oint'] +['%', '%'] +['Ġg', 'l'] +['erv', 'ed'] +['v', 'iron'] +['I', 'F'] +['ut', 'ed'] +['ã', 'ĥ'] +["'", 'm'] +['Ġc', 'ert'] +['Ġpro', 'f'] +['Ġc', 'ell'] +['ar', 'i'] +['Ġpl', 'ayer'] +['a', 'is'] +['Ġc', 'ost'] +['Ġh', 'um'] +['(', 'R'] +['Ġoff', 'ic'] +['k', 's'] +['.t', 'ext'] +['at', 'ures'] +['Ġtot', 'al'] +['Ġ*/', 'ĊĊ'] +['o', 'pe'] +['Ġst', 'at'] +['U', 'M'] +['Ġlo', 'ad'] +['ight', 's'] +['Ġc', 'lear'] +['u', 'ro'] +['Ġte', 'chn'] +['up', 'port'] +['I', 'R'] +['Ġ', 'row'] +['Ġse', 'em'] +['Ġ', 'q'] +['Ġsh', 'ort'] +['ĠN', 'ot'] +['ip', 'p'] +['G', 'roup'] +['se', 'ction'] +['m', 'ax'] +['ir', 'l'] +['Ġover', 'ride'] +['Ġcom', 'pany'] +['Ġd', 'one'] +['"', ');čĊ'] +['Ġg', 're'] +['.', 'Re'] +['Ġbel', 'ie'] +['r', 'ist'] +['Ġhe', 'alth'] +['AN', 'T'] +['()', 'ĊĊ'] +['ĠB', 'e'] +['.', 'value'] +['ĠG', 'r'] +['ott', 'om'] +['Ġarg', 's'] +['P', 'T'] +['st', 'atus'] +['f', 'unc'] +['um', 'ents'] +['-', 'h'] +['N', 'umber'] +[':', 'čĊ'] +['ĠL', 'og'] +['er', 'ver'] +['Ġ)', ',Ċ'] +['am', 'ent'] +['Ġob', 'j'] +['in', 'c'] +['Ġchild', 'ren'] +['ic', 'y'] +['I', 'Z'] +['and', 's'] +['ab', 'ly'] +['Ġdist', 'rib'] +['Ġc', 'ur'] +['er', 'ial'] +['Ġd', 'ays'] +['re', 'ated'] +['re', 'ct'] +['-', 'l'] +['ir', 'm'] +['idd', 'en'] +['om', 'b'] +['Ġin', 'itial'] +['.j', 's'] +['Ġ', 'â'] +['Qu', 'ery'] +['Ġon', 'line'] +['im', 'al'] +['.', 'con'] +['a', 'u'] +['U', 'rl'] +['cont', 'rol'] +['ire', 'ction'] +['Ġin', 'stance'] +['OR', 'T'] +['ĠF', 'r'] +['wh', 'ere'] +['Ġjav', 'ax'] +['Ġorg', 'an'] +['ap', 'ter'] +['Ġre', 'ason'] +['o', 'ptions'] +['ĠM', 'ar'] +['(', 'a'] +['Ġwith', 'in'] +['.âĢĿ', 'ĊĊ'] +['O', 'DE'] +['_', 'DE'] +['ad', 'min'] +['end', 'ed'] +['Ġdes', 'ign'] +['ĠD', 'ata'] +['un', 'e'] +['ĠF', 'ile'] +['ro', 'ot'] +['Ġc', 'ent'] +['Ġa', 'rr'] +['_', 'add'] +['l', 'en'] +['p', 'age'] +[',', "'"] +['_', 'str'] +['Ġb', 'ro'] +['ab', 'ility'] +['ou', 'th'] +['/', 'c'] +['p', 'ose'] +['irt', 'ual'] +['ear', 'ch'] +['_', 'url'] +['arg', 'in'] +['H', 'ttp'] +['Ġs', 'chool'] +['av', 'a'] +['Ġcons', 'ider'] +['.l', 'abel'] +['ĠA', 'rray'] +['we', 'b'] +['o', 'pt'] +['.print', 'ln'] +['ul', 'ation'] +['Ġf', 'unc'] +['P', 'L'] +['Ġ"', '\\'] +['ĠT', 'ext'] +['act', 'ory'] +['(f', 'unction'] +['n', 'ull'] +['Ġen', 'g'] +['d', 'own'] +['Ġin', 'clude'] +['ĠE', 'n'] +['ĠD', 'r'] +['Ġd', 'b'] +['!', '!'] +['s', 'ide'] +['Ġin', 'it'] +['quire', 'd'] +['ĠS', 'he'] +['C', 'olumn'] +['re', 'act'] +['Ġan', 'n'] +['Ġst', 'op'] +['Ġl', 'ater'] +['ĠTh', 'at'] +['ent', 'ion'] +['d', 'f'] +['U', 'G'] +['I', 'LE'] +['Ġc', 'lient'] +['ra', 'ft'] +['ff', 'er'] +['PO', 'ST'] +['el', 'per'] +['Ġlo', 've'] +['qu', 'ote'] +['ou', 'd'] +['Ġj', 'son'] +['Ġab', 'le'] +['Ġm', 'en'] +['A', 'X'] +['ĠC', 'opyright'] +['Ã', '¶'] +['av', 'ig'] +['re', 'q'] +['C', 'lient'] +['}', ');Ċ'] +['.C', 'om'] +['er', 'c'] +['il', 't'] +['pec', 'ial'] +['_c', 'om'] +['ro', 'om'] +['.', 'Name'] +['Ġg', 'ive'] +['am', 'b'] +['i', 'ke'] +['Ġcon', 'dition'] +['cl', 'ient'] +['ator', 's'] +[':', '"'] +['Ġc', 'opy'] +['ut', 'ure'] +['ivers', 'ity'] +['ern', 'al'] +['{', '{'] +['ĠC', 'an'] +['ou', 'nc'] +['d', 'o'] +['Ġo', 'cc'] +['Ġapp', 'ro'] +['th', 'ers'] +['z', 'e'] +['Ġe', 'ither'] +['ĠF', 'l'] +['Ġimport', 'ant'] +['Ġle', 'ad'] +['at', 'tr'] +['AR', 'T'] +['E', 'qual'] +['Ġd', 'a'] +['et', 'ch'] +['ent', 'ity'] +['Ġfam', 'ily'] +['add', 'ing'] +['Ġo', 'ption'] +['Ġex', 'ist'] +['ic', 'a'] +['ĠO', 'bject'] +["'", 've'] +['v', 'ers'] +['ition', 'al'] +['out', 'put'] +['ĠTr', 'ue'] +['ĠO', 'F'] +['_t', 'ime'] +['Ġof', 'fer'] +['Ġ}', ');ĊĊ'] +['H', 'ER'] +['eg', 'in'] +['"', '"'] +['Ġw', 'ater'] +['Ġc', 'he'] +['ĠM', 'y'] +['ore', 'd'] +['Ġst', 'ep'] +['anc', 'es'] +['C', 'K'] +['A', 'Y'] +['à', '¸'] +['str', 'uction'] +['(', 'C'] +['ou', 'ch'] +['St', 'ream'] +['act', 'ive'] +['am', 'a'] +['Ent', 'ity'] +['pro', 'duct'] +['()', '{Ċ'] +['Ġgovern', 'ment'] +['ĠI', 'D'] +['aj', 'or'] +['A', 'nd'] +['Ġdis', 'play'] +['Ð', '»'] +['Ġt', 'imes'] +['Ġf', 'our'] +['Ġf', 'ar'] +['Ġpres', 'ent'] +['ĠN', 'S'] +['Ġ\\', 'Ċ'] +['ue', 'st'] +['Ġb', 'as'] +['e', 'cho'] +['ch', 'ild'] +['if', 'ier'] +['Hand', 'ler'] +['Ġl', 'ib'] +['Prop', 'erty'] +['trans', 'lation'] +['Ġro', 'om'] +['Ġon', 'ce'] +['Ġ[', ']'] +['cent', 'er'] +['================', '================'] +['Ġresult', 's'] +['Ġcontin', 'ue'] +['Ġt', 'alk'] +['_', 'get'] +['Ġg', 'row'] +['.s', 'w'] +['e', 'b'] +['ĠP', 'ublic'] +['O', 'P'] +['ec', 'ute'] +['ol', 's'] +['Ġ', '**'] +['"', ');ĊĊ'] +['Ġm', 'ass'] +['ure', 'd'] +['.c', 'lass'] +['om', 'ic'] +['Ġme', 'an'] +['ip', 's'] +['Ġa', 'ut'] +[');čĊ', 'čĊ'] +['Ġun', 'til'] +['Ġmark', 'et'] +['Ġare', 'a'] +['u', 'it'] +['Ġl', 'ength'] +['ĠW', 'ith'] +['struct', 'or'] +['e', 'vent'] +['">', '<'] +['ĠS', 'p'] +['I', 'V'] +['Ġm', 'us'] +['if', 'f'] +['Ġk', 'ind'] +['a', 'uthor'] +['ound', 's'] +['m', 'b'] +['_', 'key'] +['w', 'idth'] +['posit', 'ory'] +['Ġl', 'ight'] +['u', 'k'] +['R', 'ow'] +['oh', 'n'] +['al', 'f'] +['viron', 'ment'] +['app', 'er'] +['ollection', 's'] +['Ġs', 'ide'] +['_in', 'fo'] +['Ġex', 'ample'] +['im', 'ary'] +['Ġw', 'r'] +['Ġc', 'amp'] +['cri', 'be'] +['"', '/'] +['Ġm', 'iss'] +['w', 'ay'] +['Ġb', 'ased'] +['Ġpl', 'an'] +['V', 'is'] +['om', 'ain'] +['un', 'k'] +['Ġaw', 'ay'] +['U', 'P'] +['<', 'T'] +['O', 'S'] +['i', 'od'] +['ĠM', 'on'] +['âĢĻ', 're'] +['Ġli', 'k'] +['Ã', '§'] +['iv', 'ely'] +['.', 'v'] +['im', 'er'] +['iz', 'er'] +['S', 'ub'] +['Ġbut', 'ton'] +['ĠU', 'p'] +['Ġexper', 'ience'] +['C', 'L'] +['Ġre', 'nder'] +['_', 'value'] +['Ġn', 'ear'] +['UR', 'L'] +['al', 't'] +['Ġcoun', 'try'] +['ib', 'ility'] +['()', ',Ċ'] +['e', 'ad'] +['Ġa', 'uthor'] +['Ġspec', 'ific'] +['b', 'ase'] +['(', 'name'] +['on', 'es'] +['ĠD', 'o'] +['Ġal', 'ong'] +['y', 'ear'] +['Ġexp', 'ress'] +['.', "'"] +['en', 'v'] +['Ġbeg', 'in'] +['Ġso', 'ftware'] +['Ġim', 'p'] +['Ġw', 'in'] +['ó', 'n'] +['Ġth', 'ing'] +['Tr', 'ans'] +['ĠT', 'HE'] +['Ġ<', '?'] +['Ġwh', 'y'] +['Ġdoes', 'n'] +['i', 'j'] +['g', 'ing'] +['ĉ', 'g'] +['Ġs', 'ingle'] +['off', 'set'] +['ar', 'ning'] +['og', 'raph'] +['le', 'y'] +['_c', 'ount'] +['Ġan', 'al'] +['cre', 'ate'] +['/', 'm'] +['ĠR', 'eg'] +['un', 'ch'] +['=', '$'] +['is', 'k'] +['Ġright', 's'] +['(', 'M'] +['Ġ""', '"Ċ'] +['ap', 'er'] +['.m', 'odel'] +['Ġp', 'o'] +['em', 'pty'] +['art', 'ment'] +['Ġa', 'nt'] +['ĠWh', 'en'] +['Ġwom', 'en'] +['ĠE', 'd'] +['Ġse', 'ason'] +['Ġde', 'st'] +['Ã', '£'] +['(', 'h'] +['Ġposs', 'ible'] +['Ġse', 'ver'] +['Ġb', 'tn'] +['Ġdid', 'n'] +['Ġs', 'ent'] +['Ġen', 'c'] +['Ġcomm', 'and'] +['Ġ', '],Ċ'] +['_', 'x'] +['Ġre', 'cent'] +['ol', 'ution'] +['v', 'ector'] +['ĠB', 'y'] +['ĠM', 'ay'] +['ĠA', 'ct'] +['»', '¿'] +['Ġm', 'oney'] +['IN', 'T'] +['bs', 'ite'] +['ĉ', 'p'] +['.', 'čĊ'] +['ï', '»¿'] +['s', 'l'] +['atter', 'n'] +['ĠC', 'lass'] +['Ġto', 'ld'] +['ud', 'io'] +['c', 'urrent'] +['Ġe', 'qu'] +['Ġa', 'uto'] +['ĠSt', 'ate'] +['d', 'a'] +['ms', 'g'] +['))', ';ĊĊ'] +['Ġwork', 'ing'] +['Ġqu', 'ery'] +['ĠB', 'r'] +['Ġw', 'indow'] +['a', 'uth'] +['on', 'ly'] +['ĉ', 't'] +['Ġle', 'ast'] +['ag', 'n'] +['Ġex', 'pl'] +['it', 'ter'] +['ar', 'ing'] +['Ġc', 'olumn'] +['ĠGener', 'al'] +['":', '"'] +['er', 'al'] +['ri', 'or'] +['Ġrec', 'ord'] +['I', 'B'] +['E', 'X'] +['Ġd', 'at'] +['Ġm', 'aking'] +['u', 'ed'] +['ĠC', 'ar'] +['em', 'p'] +['"', '.'] +['ĠM', 'ed'] +['Ġc', 'lose'] +['Ġper', 'cent'] +['Ġp', 'ast'] +['(', 'g'] +[':', '('] +['Ġw', 'rite'] +['Ġm', 'ove'] +['Ġp', 'at'] +['Cont', 'rol'] +['.T', 'o'] +['Ġv', 'i'] +['*/', 'Ċ'] +['in', 'ate'] +["'", 'll'] +['ag', 'ed'] +['N', 'ull'] +['Ġspec', 'ial'] +['IZ', 'E'] +['Ġc', 'ity'] +['/*', 'Ċ'] +['ĠE', 'ng'] +['ix', 'ed'] +['in', 'ary'] +['p', 'y'] +['Ġe', 'ff'] +['ar', 'io'] +['Ġt', 'ell'] +['av', 'or'] +['Ġse', 'lect'] +['le', 'vel'] +['im', 'um'] +['op', 'er'] +['B', 'uilder'] +['I', 'P'] +["')", ',Ċ'] +['es', 'c'] +['Ġf', 'ont'] +['"', ';ĊĊ'] +['ĠA', 'm'] +['ish', 'ed'] +['ill', 's'] +['Int', 'er'] +['O', 'W'] +['Ġcour', 'se'] +['Ġl', 'ate'] +['idd', 'le'] +['Ġam', 'ount'] +['Ġas', 'ync'] +['in', 'o'] +['c', 'ul'] +['Ġ', 'ì'] +['and', 'le'] +['_', 'user'] +['Ġb', 'en'] +['ĠC', 'al'] +['Ġ$', '_'] +['ĠR', 'ep'] +['Ġen', 'ough'] +['T', 'oken'] +['.', 'user'] +['(', 'j'] +['S', 'c'] +['W', 'idth'] +['n', 'ow'] +['at', 'form'] +['Ġlook', 'ing'] +['Ġh', 'old'] +['M', 'odule'] +['IT', 'Y'] +['v', 'o'] +['is', 'on'] +['.D', 'ata'] +['y', 'c'] +['Ġp', 'ot'] +['ĠTr', 'ump'] +['id', 'ual'] +['id', 'es'] +['r', 't'] +['Ġprop', 'erty'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠ'] +['am', 'ework'] +['g', 'o'] +['Ġl', 'ow'] +['Ġpar', 'a'] +['Ġpr', 'ice'] +['ur', 'y'] +['Ġto', 'day'] +['ro', 'y'] +["Ġ'", '/'] +['Ġpol', 'it'] +["Ġ'", "'"] +['ym', 'b'] +['P', 'h'] +['Ġad', 'v'] +['Ġatt', 'ack'] +['ĠS', 'te'] +['RO', 'M'] +['an', 'a'] +['Ġme', 'ans'] +['Ġst', 'ory'] +['id', 's'] +['ak', 'en'] +['Ġme', 'et'] +['Ġm', 'om'] +['ĠâĢ', 'ĺ'] +['Ġ?', '>'] +['Ġd', 'en'] +['ob', 'ile'] +['ch', 'ange'] +['ĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĊ'] +['ic', 'i'] +['n', 'a'] +['ĠF', 'orm'] +['Ġs', 'ort'] +['Se', 'lect'] +['p', 'are'] +['Ġth', 'ought'] +['_', 'con'] +['Ġt', 'ask'] +['oc', 'us'] +['ĠD', 'E'] +['ĠM', 'in'] +['Ġo', 'pt'] +['ĉb', 'reak'] +['um', 'er'] +['K', 'E'] +['th', 'en'] +['Ġd', 'et'] +['ĠT', 'est'] +['port', 's'] +['Ġre', 'view'] +["('", '/'] +['m', 'ove'] +['Ġsw', 'itch'] +['ER', 'T'] +['p', 'atch'] +['ann', 'ot'] +['ã', 'Ĥ'] +['Ġab', 'ove'] +['it', 'ive'] +['Ġquest', 'ion'] +['ĠQ', 'u'] +['ãĢĤ', 'ĊĊ'] +['g', 'le'] +['Ġw', 'ord'] +['Ġprov', 'ide'] +['ĠR', 'eturn'] +['Ġre', 'search'] +['ã', 'o'] +['u', 'str'] +['Ġp', 'ublish'] +['chem', 'a'] +['}', '}'] +['ĠC', 'ON'] +['-', 'in'] +['all', 'back'] +['Ġco', 'ver'] +['\\', '\\'] +['c', 'olor'] +['ĠI', 'S'] +['Ġwh', 'ether'] +['im', 'ate'] +['is', 'c'] +['B', 'ar'] +['Ġd', 'iv'] +['B', 'e'] +['our', 'n'] +['Ġh', 'aving'] +['le', 'm'] +['pl', 'ayer'] +['ab', 's'] +['am', 'era'] +['ne', 'y'] +['Ġex', 'c'] +['get', 'her'] +['pl', 'ied'] +['a', 'o'] +['[', '$'] +['Ġ+', '+'] +['i', 'pe'] +['sh', 'ow'] +['/', 'd'] +['[', ':'] +['ag', 'ement'] +['le', 'v'] +['_', 'ID'] +['r', 'ary'] +['ad', 'es'] +['_', 'se'] +['a', 'use'] +['Ġem', 'ploy'] +['Ġ*/', 'čĊ'] +['Ġf', 're'] +["Ġ'", '@'] +['Ġcomple', 't'] +['Ġl', 'arge'] +['r', 'al'] +['\\', 'x'] +['Ġf', 'ac'] +['<', 'String'] +['Ġcre', 'ated'] +['up', 'er'] +['.st', 'ate'] +['Ġh', 'ost'] +['ener', 'ic'] +['/', 'b'] +['(', '!'] +['wh', 'ile'] +['i', 'as'] +['B', 'UG'] +['Ġ', ');ĊĊ'] +['Ġro', 'le'] +['Re', 'g'] +['ĠC', 'olor'] +['St', 'art'] +['Ġp', 'orn'] +['t', 'op'] +['Ġwe', 'b'] +['Ġde', 'v'] +['Ġde', 'al'] +['++', ')Ċ'] +['Int', 'eger'] +['pos', 'ition'] +['.', 'on'] +['Ġ(', '"'] +['ä', '¸'] +['Ġproble', 'm'] +['s', 'v'] +['Ġp', 'ress'] +['AB', 'LE'] +['AT', 'ION'] +['ĠSe', 'e'] +['an', 'ch'] +['Ġth', 'ough'] +['le', 'ep'] +['Ġ<', '!--'] +['Ġpoint', 's'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠ'] +['.', 'J'] +['Ġ', '::'] +['p', 'tr'] +['D', 'B'] +['++', ';Ċ'] +['.p', 'ng'] +['n', 'ode'] +['so', 'ft'] +['pon', 'd'] +['Ġe', 'ver'] +['--------------------------------', '--------------------------------'] +['M', 'enu'] +["('", '#'] +['Ġs', 'ervices'] +['p', 'g'] +['}', ')Ċ'] +['param', 's'] +['Ġact', 'ually'] +['Ġ"', '/'] +['Em', 'pty'] +['M', 'ethod'] +['Ġid', 'ent'] +['un', 'ic'] +['Ġmill', 'ion'] +['Ġa', 'ff'] +['st', 'yle'] +['Ġcon', 'c'] +['i', 'os'] +['ign', 'ment'] +['UL', 'T'] +['P', 'r'] +['"', ';čĊ'] +['Ġunder', 'stand'] +['u', 'ary'] +['Ġhapp', 'en'] +['Ġser', 'ver'] +['ĠC', 'o'] +['S', 'C'] +['Ġle', 's'] +['Ġfile', 's'] +['G', 'rid'] +['s', 'ql'] +['Ġof', 'ten'] +['Ġin', 'fo'] +['_', 'tr'] +['s', 'rc'] +['on', 'y'] +['Ġsp', 'ace'] +['um', 'b'] +['Ġpass', 'word'] +['Ġst', 'ore'] +[',', 'ĊĊ'] +['ĠWh', 'at'] +['g', 'ed'] +['ĠF', 'alse'] +['U', 's'] +['sw', 'er'] +['_', 'index'] +['Ġform', 'at'] +['m', 'ost'] +['s', 'm'] +['N', 'ew'] +['Ġd', 'etails'] +['Ġpro', 'b'] +['ĠAN', 'D'] +['()', 'čĊ'] +['il', 'ar'] +['Ġ$', '{'] +['ry', 'pt'] +['.C', 'ollections'] +['$', 'this'] +['ĠF', 'ree'] +['_', 'of'] +['(f', 'alse'] +['d', 'ated'] +['Ġ>', '>'] +['Ġf', 'ace'] +['CT', 'ION'] +['Ġs', 'ave'] +['Ġt', 'yp'] +['de', 'v'] +['("', '#'] +['AG', 'E'] +['cont', 'ainer'] +['ed', 'it'] +['Q', 'L'] +['Ġitem', 's'] +['Ġs', 'ocial'] +['i', 'en'] +['ĠRe', 'act'] +[')', '.ĊĊ'] +['Ġm', 'ar'] +['Ġre', 'du'] +['ĠR', 'E'] +['.p', 'ut'] +['Ġm', 'ajor'] +['C', 'ell'] +['n', 'ext'] +['Ġexpect', 'ed'] +['Ġy', 'et'] +['Ġin', 'div'] +['trib', 'utes'] +['at', 'is'] +['am', 'ed'] +['Ġf', 'ood'] +['S', 'ource'] +['(', 'string'] +['Ġ+', 'Ċ'] +['it', 'es'] +['d', 'r'] +['Ġmem', 'bers'] +['Ġcom', 'b'] +['item', 's'] +['ĠP', 'er'] +['T', 'H'] +['=', 'True'] +['Ġb', 'ar'] +['_', 'SE'] +['com', 'm'] +['(', 'w'] +[')ĊĊ', 'Ċ'] +['Ġs', 'end'] +['Ġin', 'c'] +['un', 'signed'] +['F', 'A'] +['Ġparam', 's'] +['app', 'ing'] +['ro', 's'] +['ug', 'in'] +['f', 'a'] +['Ġcon', 'nection'] +['Ġ}', ';ĊĊ'] +['Ġbe', 'come'] +['M', 'ode'] +['Ġe', 'v'] +['Ġdif', 'f'] +['ĠUn', 'ited'] +['He', 'ight'] +['ful', 'ly'] +['im', 'ages'] +['Ġm', 'akes'] +['Ġg', 'lobal'] +['Ġcont', 'act'] +["'", ':Ċ'] +['Ġab', 's'] +['а', 'Ð'] +['f', 'loat'] +['Ġex', 'cept'] +['ĠP', 'ol'] +['Ch', 'ild'] +['t', 'yp'] +['Ġcert', 'ain'] +['i', 'ón'] +['O', 'UT'] +['Ġim', 'pro'] +['ile', 's'] +['Ġ--', '>Ċ'] +['ĠP', 'art'] +['val', 'ues'] +['os', 's'] +['/', '**'] +['il', 'it'] +['ĠE', 'vent'] +['cur', 'ity'] +['st', 'er'] +['Ġchar', 'acter'] +['Ġnew', 's'] +['Ġ"', ','] +['Ġde', 'vice'] +['c', 'el'] +['log', 'in'] +['he', 'et'] +['Def', 'ault'] +['@', '"'] +['ĉ', 'Ġ'] +['c', 'lick'] +['(', 'value'] +['ĠA', 'b'] +['Ġpre', 'vious'] +['ERR', 'OR'] +['oc', 'al'] +['Ġm', 'aterial'] +['Ġbel', 'ow'] +['ĠCh', 'rist'] +['Ġmed', 'ia'] +['co', 'ver'] +['ĠU', 'I'] +['Ġf', 'ail'] +['Ġbl', 'ack'] +['Ġcom', 'ponent'] +['ĠAmeric', 'an'] +['Ġadd', 'ed'] +['Ġbu', 'y'] +['st', 'it'] +['Ġc', 'ame'] +['Ġde', 'lete'] +['prop', 'erty'] +['od', 'ing'] +['Ġc', 'ard'] +['rop', 's'] +['Ġhttp', 's'] +['Ġro', 'ot'] +['Ġhand', 'le'] +['C', 'C'] +['B', 'ack'] +['em', 'plate'] +['Ġget', 'ting'] +['_b', 'y'] +['m', 'ail'] +['_s', 'h'] +['.', 'assert'] +['ĠD', 'ec'] +['(', 'true'] +['Ġcom', 'put'] +['Ġcl', 'aim'] +["'", '=>'] +['ĠS', 'ub'] +['Ġa', 'ir'] +['op', 's'] +['n', 'av'] +['em', 'ents'] +['(', 'id'] +['Ġent', 'er'] +['ang', 'ed'] +['E', 'nd'] +['Ġloc', 'ation'] +['Ġn', 'ight'] +['Ġdo', 'ing'] +['ĠR', 'ed'] +['l', 'in'] +['}ĊĊ', 'Ċ'] +['vid', 'er'] +['Ġp', 'ick'] +['Ġw', 'atch'] +['ess', 'ages'] +['Ġhum', 'an'] +['Ġd', 'am'] +['p', 'end'] +['d', 'ir'] +['Ġt', 'ax'] +['Ġg', 'irl'] +['re', 'et'] +['Ġbo', 'x'] +['Ġstr', 'ong'] +['(', 'v'] +['re', 'l'] +['Ġinter', 'face'] +['Ġm', 'sg'] +['f', 'ect'] +['_', 'at'] +['Ġh', 'ouse'] +['Ġtr', 'ack'] +["'", ');ĊĊ'] +['j', 'e'] +['ĠJ', 'ohn'] +['ist', 'r'] +['(', 'S'] +['ub', 'e'] +['Ġc', 'e'] +['itt', 'ed'] +['V', 'ER'] +['*', ')'] +['p', 'arent'] +['Ġapp', 'lication'] +['an', 'y'] +['.sw', 'ing'] +['Ġp', 'ack'] +['\\', 'u'] +['Ġpr', 'act'] +['Ġse', 'ction'] +['ct', 'x'] +['Ġun', 'signed'] +['.P', 'oint'] +['ĠO', 'ne'] +['Ä', '±'] +['ip', 'le'] +['a', 'id'] +['Ñ', 'ĥ'] +['V', 'ector'] +['by', 'te'] +['Ġw', 'ait'] +['ĠÃ', 'ł'] +['Ã', '¥'] +['Ġto', 'gether'] +['Ġth', 'rows'] +['F', 'O'] +["'", '))'] +['h', 'ost'] +['is', 'ing'] +['.', 'view'] +['Ġter', 'ms'] +['fr', 'amework'] +['-', 'r'] +['Ġapp', 'ly'] +['Ġs', 'ession'] +['O', 'ptions'] +['ugg', 'est'] +['Ġo', 'thers'] +['w', 'itter'] +['Ġf', 'und'] +['In', 'it'] +['__', '('] +['ens', 'or'] +['G', 'ET'] +['Ġsever', 'al'] +['i', 'i'] +['[', 'j'] +['I', 'O'] +['Ġtem', 'plate'] +['P', 'osition'] +['Ġe', 'con'] +['ach', 'ine'] +['Ġ', 'il'] +['.s', 'pring'] +['m', 'ain'] +['el', 't'] +['im', 'ent'] +['Re', 'c'] +['m', 'm'] +['ĠUn', 'iversity'] +['urs', 'or'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠ'] +['G', 'L'] +['ict', 'ure'] +['ith', 'ub'] +['c', 'er'] +['c', 'ast'] +['F', 'rom'] +['a', 'les'] +['Ġsub', 'ject'] +['p', 'assword'] +['n', 'y'] +['Ġes', 'c'] +['.w', 'rite'] +['ï¼', 'Į'] +['Wh', 'at'] +['.', 'H'] +['Ġh', 'istory'] +['ĠF', 'e'] +['Ġindiv', 'idual'] +['un', 'it'] +['Ġ--', '>'] +['Ġd', 'u'] +['I', 'ST'] +['Ġus', 'ers'] +['f', 's'] +['f', 'alse'] +['un', 't'] +['T', 'itle'] +['Ġm', 'ot'] +['Ġf', 'uture'] +['ach', 'ed'] +['Ġstart', 'ed'] +['Ġm', 'ode'] +["Ġ'", '<'] +['_', 'array'] +['Ġa', 'x'] +["']", ';Ċ'] +['i', 'res'] +['Th', 'ere'] +['ug', 'ht'] +['t', 'ml'] +['pos', 'ed'] +['ic', 'ult'] +['Ġto', 'ok'] +['Ġg', 'ames'] +['Ġ}', '}'] +['Ġ?', '>Ċ'] +['Ġproduct', 's'] +['I', 's'] +['Ġb', 'ad'] +['ĠD', 'es'] +['.p', 'ath'] +["'", 'ĊĊ'] +['ĠP', 'ost'] +['av', 'el'] +['(', ':'] +['Ġneed', 's'] +['Ġkn', 'own'] +['F', 'l'] +['Ġex', 'ec'] +['Ġse', 'en'] +['um', 'e'] +['Ġb', 'order'] +['Ġl', 'ive'] +['tem', 'p'] +['P', 'er'] +['Ġvar', 'iable'] +['i', 'et'] +['ĠD', 'ef'] +['Ġg', 'e'] +['em', 'e'] +['_b', 'ack'] +['f', 'irst'] +['Ġprovid', 'ed'] +['////////////////', '////////////////'] +['Ġfil', 'ename'] +['Ġh', 'ope'] +['ul', 'y'] +['a', 'uto'] +['f', 'ind'] +['_', 'string'] +['b', 'tn'] +['it', 'ude'] +['At', 'tribute'] +['Ġyou', 'ng'] +['.t', 'xt'] +['Ġwe', 'bsite'] +['ĠP', 'rop'] +['Ġe', 'y'] +['>', '();Ċ'] +['ion', 'al'] +['AR', 'R'] +['iction', 'ary'] +['ur', 'ther'] +['.', ''] +['t', 'x'] +['Ġp', 'ur'] +['u', 'el'] +['ymb', 'ol'] +['u', 'ation'] +['ang', 'er'] +['Ġback', 'ground'] +['ec', 'ess'] +['ef', 'ined'] +['....', '....'] +['Ġdes', 'cription'] +['Ġrep', 'resent'] +['")', ');Ċ'] +['press', 'ion'] +['row', 'ser'] +['Ġser', 'ies'] +['ward', 's'] +['($', '_'] +['a', 'ise'] +['Ġh', 'ot'] +['ac', 'ity'] +['ri', 'es'] +['action', 's'] +['C', 'reate'] +['ad', 'io'] +['amp', 'les'] +['Ġorig', 'inal'] +['ens', 'ive'] +['f', 'ont'] +['st', 'ream'] +['', 'using'] +['.spring', 'framework'] +['ser', 'ver'] +['Ġb', 'ill'] +['AC', 'K'] +['il', 'ename'] +['Ġfr', 'ame'] +['Ġ=', 'Ċ'] +['Ed', 'it'] +['adi', 'us'] +['Ġd', 'raw'] +['ank', 's'] +['Ġd', 'eter'] +['Ġcom', 'es'] +['_', 'int'] +['Ġfore', 'ach'] +['ang', 'le'] +['Ġe', 'lect'] +['pect', 'ed'] +['He', 'ader'] +['ist', 'ration'] +['F', 'alse'] +['ĠG', 'ame'] +['Ġfil', 'ter'] +['Act', 'ivity'] +['Ġl', 'arg'] +['in', 'ition'] +['Ġ"', '<'] +['is', 'ed'] +['Ġrem', 'ove'] +['ĠTr', 'ans'] +['m', 'et'] +['se', 'e'] +['Form', 'at'] +['Com', 'mand'] +['ĠE', 'X'] +['N', 'one'] +['Ġfr', 'ont'] +['A', 'SE'] +['ĠR', 'ec'] +['ound', 'ation'] +['Ġv', 'o'] +['=', '\\"'] +['(', '*'] +['Ch', 'ange'] +['.W', 'rite'] +['g', 'roup'] +['i', 'ents'] +['u', 'y'] +['********************************', '********************************'] +['Ġd', 'ig'] +['h', 'r'] +['(', '-'] +['Ġg', 'en'] +['n', 'umber'] +['ve', 'c'] +['uro', 'pe'] +['ent', 'ry'] +['L', 'L'] +['Ġst', 'e'] +['Val', 'id'] +["']", ','] +['_p', 'aram'] +['Ġse', 'lected'] +['Ġacc', 'ording'] +['ĠD', 'is'] +['Ġ', 'util'] +['B', 'uffer'] +['_', 'error'] +['Ġass', 'oci'] +['_S', 'IZE'] +['Ġw', 'or'] +['Ġprint', 'f'] +['r', 'ag'] +['Â', 'ł'] +['D', 'D'] +['ĠV', 'al'] +['Ġact', 'iv'] +['E', 'ng'] +['et', 'ime'] +['Ġv', 'irtual'] +['a', 'ign'] +['a', 'ur'] +['ĠP', 'res'] +['ĠEx', 'ception'] +['Ġany', 'thing'] +['ĠO', 'ff'] +['Ġh', 'ours'] +['Ġw', 'ar'] +['Arg', 's'] +['ag', 'ing'] +['Ġmodel', 's'] +['ĠT', 'ime'] +['O', 'b'] +['am', 's'] +['j', 'oy'] +['Ġear', 'ly'] +['.', 'read'] +['Ġc', 'enter'] +['ĠIn', 'itial'] +['Ġl', 'anguage'] +['l', 'ength'] +['x', 'y'] +['Ġs', 'n'] +['Ġin', 'f'] +['P', 'ost'] +['Ġag', 'o'] +['Ġeas', 'y'] +['_c', 'ode'] +['ĠAN', 'Y'] +['_', 'ch'] +['Ġdown', 'load'] +['(', 'T'] +['av', 'ed'] +['âĢ', 'ĵ'] +['Ġstud', 'ents'] +['Ġf', 'ig'] +['l', 'ight'] +['x', 'x'] +['Ġbu', 'ffer'] +['ĠD', 'ep'] +['ĠM', 'ath'] +['IT', 'H'] +['Ġvar', 'i'] +['Ġd', 'ue'] +['F', 'actory'] +['Ġp', 'or'] +['Ġe', 'p'] +['ot', 'ype'] +['Ġcan', 'not'] +['Ġwh', 'ite'] +['<', 'int'] +['ter', 'n'] +['Ġreg', 'ister'] +['Ġpre', 'd'] +['cl', 'us'] +['_d', 'ate'] +['Ġ/', '**'] +['Ġa', 'uth'] +['Ġ[', ']Ċ'] +['Ġper', 'iod'] +['n', 'own'] +['Ġv', 'ot'] +['Ġs', 'creen'] +["'", 'd'] +['T', 'ypes'] +['Ġt', 'mp'] +['е', 'Ð'] +['ur', 'al'] +['Ġben', 'ef'] +['_', 'y'] +['Ġn', 'et'] +['ĠSt', 'ates'] +["']", "['"] +['ĠN', 'e'] +['ĠN', 'OT'] +['Ġn', 'eg'] +['Ġcomm', 'on'] +['s', 'cope'] +['Ġc', 'red'] +['g', 'es'] +['_T', 'YPE'] +['Ġs', 'uggest'] +['o', 'om'] +['.ĊĊ', 'Ċ'] +['Ġac', 'cept'] +['Ġr', 'andom'] +['er', 'm'] +['ĠV', 'ector'] +['w', 'ith'] +['T', 'ER'] +['(', 'str'] +['Ġres', 'pons'] +['Ġh', 'it'] +['.S', 'et'] +['gr', 'id'] +['ri', 'a'] +['Ġc', 'lick'] +['und', 'le'] +['C', 'ase'] +['ins', 'ert'] +['Util', 's'] +['Ġ""', '"'] +['Ġim', 'plement'] +['at', 'al'] +['tem', 'pt'] +['tem', 'plate'] +['oc', 'r'] +['return', 's'] +['Ġplay', 'ers'] +['us', 'ers'] +['ed', 'ef'] +['ĠTh', 'ese'] +['Ġam', 'ong'] +['Ġde', 'b'] +['h', 'a'] +['.get', 'Element'] +['Ġc', 'irc'] +['Ġan', 'swer'] +['Ġw', 'alk'] +['Ġt', 'reat'] +['ĠG', 'e'] +['ĠC', 'reate'] +['Ġa', 'ge'] +['Ġre', 'q'] +['O', 'ST'] +['ang', 'ular'] +['Ñ', 'ı'] +['Ġf', 'ive'] +['Ġdistrib', 'uted'] +['Ġfri', 'end'] +['T', 'P'] +['Ġc', 'lean'] +['ow', 's'] +['.Control', 's'] +['d', 'is'] +['Ġw', 'ords'] +['.', 'io'] +['z', 'y'] +['Ġhe', 'ader'] +['ĠC', 'heck'] +['âĢĻ', 'm'] +['j', 'ust'] +['h', 'older'] +['="', '', 'čĊ'] +['.', 'annot'] +['Ġcol', 'lection'] +["'", '.'] +['Ġsim', 'ilar'] +['Ġt', 'aken'] +['("', '%'] +['Or', 'der'] +["']", 'Ċ'] +['-m', 'd'] +['ĠT', 'H'] +['ac', 'ed'] +['Ġis', 'n'] +['/', 'j'] +['Ġs', 'on'] +['gr', 'aph'] +['ĠInt', 'eger'] +['Ġn', 'ecess'] +['re', 'en'] +['Ġ', 'um'] +['Ġ\\', '<'] +['Ġmom', 'ent'] +['Ġbr', 'ing'] +['Ġind', 'ic'] +['ys', 'is'] +['Le', 'vel'] +['ver', 'se'] +['urre', 'nc'] +['_t', 'est'] +['Ġent', 'ire'] +['D', 'own'] +['Ġ}ĊĊ', 'Ċ'] +['(', 'result'] +['ĠRe', 'ad'] +['Ã', '¨'] +['M', 'od'] +['Ġtry', 'ing'] +['")', ',Ċ'] +['Ġm', 'ember'] +['ĠC', 'or'] +['OD', 'O'] +['-', 'control'] +['un', 'time'] +['ĠS', 'im'] +['D', 'ialog'] +['pl', 'ot'] +['_', 'on'] +['Ġph', 'ys'] +['}', '/'] +['Ġn', 'amespace'] +['ĉ', 'čĊ'] +['ac', 'c'] +['Pl', 'ayer'] +['A', 'RE'] +['Ġf', 'oot'] +['Ġbo', 'ard'] +['p', 'art'] +['Ġs', 'us'] +['w', 'ise'] +['ĠM', 'c'] +['Ġp', 'ush'] +['AT', 'A'] +['Ġp', 'lease'] +['ri', 'ed'] +['we', 'et'] +['b', 'it'] +['id', 'ed'] +['V', 'E'] +['ĠS', 'w'] +['U', 'B'] +['Ġt', 'ypes'] +['ed', 'ia'] +['Ġc', 'los'] +['ace', 'book'] +['Wh', 'en'] +['Ġed', 'it'] +['ig', 'ger'] +['Ġen', 'erg'] +['Cont', 'ainer'] +['Ġph', 'ot'] +['ĠC', 'ount'] +['ĠE', 'urope'] +['.I', 's'] +['ĠR', 'uss'] +['pe', 'ed'] +['ĠS', 'tr'] +['Ġp', 'y'] +['Ġc', 'ult'] +['Ġdef', 'ined'] +['cc', 'ount'] +['Ġob', 't'] +['.L', 'ocation'] +['Ġth', 'read'] +['il', 'le'] +['Ġinst', 'ead'] +['str', 'ong'] +['ĠS', 'ec'] +['U', 'RE'] +['Ġide', 'a'] +['.', 'se'] +['em', 'y'] +['select', 'ed'] +['Con', 'nection'] +['ac', 'ing'] +['th', 'read'] +['.n', 'ext'] +['Ġc', 'oll'] +['Ġfil', 'm'] +['ist', 'ic'] +['Ġcomp', 'et'] +['Ġcon', 'n'] +['th', 'ough'] +['Ġcom', 'pan'] +['ock', 'et'] +['Ġte', 'ach'] +['=', '('] +['Ġph', 'one'] +['Ġact', 'ive'] +['de', 'lete'] +['tr', 'ies'] +['Ġm', 'o'] +['Ġde', 'ath'] +['}', ');ĊĊ'] +['oc', 'ol'] +['W', 'idget'] +['Ġart', 'icle'] +['ro', 'du'] +['and', 'id'] +['Ñ', 'ĭ'] +['ĠC', 'r'] +['k', 'a'] +['()', ':'] +['lo', 'od'] +['ĉĉĉ', 'Ċ'] +['Ġal', 'most'] +['Ġs', 'ell'] +['erv', 'let'] +['ri', 'p'] +['Un', 'it'] +['Ġapp', 'lic'] +['Ġcon', 'nect'] +['Ġfe', 'ature'] +['Ġv', 'ia'] +["'", '),'] +['Ġl', 'im'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['ĠG', 'u'] +['Eng', 'ine'] +['Ġen', 's'] +['Ġen', 'vironment'] +['b', 'lock'] +['HER', 'E'] +['N', 'ULL'] +['g', 'y'] +['t', 'ag'] +[')', ').'] +['ex', 'p'] +['Ġcom', 'pl'] +['Ġinst', 'all'] +['Ġcomple', 'te'] +['que', 'ue'] +['atur', 'al'] +['Ġgener', 'al'] +['th', 'on'] +['Ġask', 'ed'] +['o', 'res'] +['(', 'res'] +['Ġres', 'erved'] +['S', 'P'] +['ĠâĢ', '¦'] +['Å', 'Ĥ'] +['Ġsign', 'ific'] +['O', 'ff'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['ĠA', 'g'] +['ĠJ', 'ust'] +['ĠE', 'rror'] +['Ġin', 'fl'] +['ad', 'ata'] +['Ġ', 'icon'] +['ask', 's'] +["'", "'"] +['_', 'LO'] +['?', '.'] +['ac', 'count'] +['Ġ(', '*'] +["'", ')ĊĊ'] +['r', 'ap'] +['_', 'var'] +['ĠF', 'OR'] +['Ġpart', 'y'] +['ĠY', 'our'] +['c', 'at'] +['str', 'y'] +['.', 'new'] +['bo', 'ot'] +['ĠN', 'ov'] +['Ġv', 'ector'] +['Ġn', 'ormal'] +['Ġf', 'urther'] +['Re', 'pository'] +['Ġd', 'atabase'] +['att', 'le'] +['Ġmus', 'ic'] +['Ġspe', 'ed'] +['Ġd', 'oc'] +['pro', 'cess'] +['IG', 'HT'] +['.p', 'arse'] +['Ġt', 'aking'] +['Ġvi', 'ol'] +['ce', 'ed'] +['ĠA', 'fter'] +['Ġfor', 'ward'] +['Ġc', 'rit'] +['"/', '>Ċ'] +['ro', 't'] +['Ġfa', 'iled'] +['ef', 'ore'] +['Ġconc', 'ern'] +['o', 'e'] +['b', 'a'] +['Ġs', 'ender'] +['Ġter', 'm'] +['h', 'as'] +['="', '#'] +['Ġpot', 'ential'] +['N', 'um'] +['Ġpublish', 'ed'] +['.c', 'lose'] +['ĠIm', 'age'] +['str', 'aint'] +['U', 'D'] +['ĠO', 'b'] +['Ġprob', 'ably'] +['l', 'im'] +['"', ':Ċ'] +['olum', 'e'] +['Ġcon', 'sum'] +['ag', 'ue'] +['ens', 'ions'] +['Ġinvest', 'ig'] +['-', 'year'] +["')", ';'] +['-s', 'm'] +['Ġen', 'joy'] +['or', 'ig'] +['er', 'ing'] +['c', 'p'] +['le', 'ased'] +['ple', 'ments'] +['Ġreturn', 's'] +['p', 'at'] +['B', 'O'] +['ĠH', 'ouse'] +['.L', 'abel'] +['Ġwe', 'ight'] +['igh', 'b'] +['Ġcondition', 's'] +['Ġex', 'ception'] +['d', 'escription'] +['Ġtr', 'ad'] +['-', 'to'] +['Ġ{', '}'] +['Ġmod', 'ule'] +['EN', 'D'] +['.', 'ap'] +['.p', 'rops'] +['Ġcon', 'structor'] +['av', 'es'] +['Ġf', 'avor'] +['ĠN', 'ow'] +[';', 'i'] +['ĠM', 'ain'] +['_', 'k'] +['er', 'ies'] +['âĢĻ', 'll'] +['trans', 'form'] +['imest', 'amp'] +['P', 're'] +['Ġm', 'er'] +['.', 'res'] +['st', 'ant'] +['L', 'ocation'] +['_N', 'AME'] +['Ġlos', 's'] +['Ġ', 'ĊĊ'] +['n', 'et'] +['Ġeng', 'ine'] +['B', 'lock'] +['Ġiss', 'ues'] +['Ġpar', 'se'] +['ĠB', 'ar'] +['Ġst', 'ay'] +['ĠJ', 'SON'] +['Ġd', 'om'] +['air', 's'] +['w', 'ner'] +['Ġl', 'ower'] +['",', 'čĊ'] +['ĠD', 'em'] +['uf', 'act'] +['Ġp', 's'] +['Ġper', 'fect'] +['R', 'L'] +['Ġed', 'uc'] +['l', 's'] +['em', 'ory'] +['ARR', 'ANT'] +['u', 'ge'] +['Ġex', 'act'] +['.', 'key'] +['al', 'led'] +['e', 'ch'] +['ie', 'f'] +['\\', '/'] +['o', 'ke'] +['Ġfor', 'mer'] +['al', 'loc'] +['Ġs', 'ix'] +['id', 'a'] +['Ġm', 'argin'] +['Ġhe', 'art'] +['al', 'd'] +['p', 'ack'] +['.getElement', 'ById'] +['ĠW', 'ARRANT'] +['Ġr', 'ather'] +['Ġbuild', 'ing'] +['er', 'man'] +['lic', 'e'] +['Ġquest', 'ions'] +['iz', 'es'] +['le', 'ge'] +['irect', 'ory'] +['Ġj', 'e'] +['Ġc', 'as'] +['pro', 'ps'] +['ut', 'f'] +['Ġse', 'curity'] +['Ġhow', 'ever'] +['we', 'ight'] +['Ġins', 'ide'] +['Ġpres', 'ident'] +['Ch', 'ar'] +['ĠW', 'ITH'] +['.m', 'ap'] +['Ġgr', 'aph'] +['Ġt', 'ag'] +['_st', 'atus'] +['Ġat', 'tempt'] +['op', 'p'] +['us', 'es'] +['ĉ', 'const'] +['Ġr', 'ound'] +[',', '$'] +['Ġfri', 'ends'] +['Em', 'ail'] +['?', '>'] +['Res', 'ource'] +['KE', 'Y'] +['os', 'p'] +['.', 'query'] +['ĠN', 'orth'] +['able', 's'] +['ist', 'rib'] +['_c', 'lass'] +['el', 'lo'] +['Th', 'at'] +['Ð', 'º'] +['pecial', 'ly'] +['ĠPres', 'ident'] +['Ġcamp', 'aign'] +['Ġal', 't'] +['are', 'a'] +['Ġch', 'all'] +['Ġop', 'port'] +['.C', 'on'] +['Ġenerg', 'y'] +['li', 'ke'] +['.', 'string'] +['ing', 'ton'] +[')', '*'] +['y', 'y'] +['Ġprof', 'ession'] +['ir', 'th'] +['Ġse', 'g'] +['æ', 'ľ'] +['Ġh', 'or'] +['i', 'ers'] +['c', 'an'] +['Ġbeh', 'ind'] +['Pro', 'duct'] +['f', 'g'] +['ĠS', 'k'] +['.j', 'pg'] +['?', ':'] +[']', ';ĊĊ'] +['Ġcall', 'back'] +['ĠH', 'ttp'] +['Ñ', 'Į'] +['l', 'ong'] +['M', 'S'] +['AT', 'H'] +['Ġr', 'aise'] +['Ġwant', 'ed'] +['row', 'n'] +['ut', 'or'] +['l', 't'] +[']', '='] +['el', 'ine'] +['M', 'A'] +['Ġse', 'par'] +['c', 's'] +['se', 'mb'] +['D', 'is'] +['bs', 'erv'] +['ĠW', 'ill'] +['Ġpol', 'icy'] +['Ġth', 'ird'] +['ph', 'one'] +['Ġb', 'ed'] +['/', 'g'] +['.', '__'] +['ĠIn', 'c'] +['iz', 'ing'] +['.re', 'move'] +['in', 'stance'] +['.t', 'ype'] +['Ġs', 'erv'] +['E', 'ach'] +['Ġh', 'ar'] +['ĠM', 'essage'] +['(', 'key'] +['SE', 'LECT'] +['P', 'os'] +['))', ';čĊ'] +['Ġre', 'comm'] +['Ġtr', 'aining'] +['ĠE', 'nt'] +['ĠCh', 'ar'] +['ic', 'ht'] +['(f', 'ile'] +['Ġp', 'rior'] +['G', 'ame'] +['Ġex', 'it'] +['Param', 's'] +['.c', 'ore'] +['P', 'C'] +['n', 'es'] +['anc', 'ed'] +['(', 'request'] +['P', 'assword'] +['}', '>Ċ'] +['Ġm', 'ag'] +['Ġre', 'lease'] +['Ġsh', 'all'] +['ud', 'ent'] +['ĠS', 'outh'] +['and', 'o'] +[':', "'"] +['.Tab', 'Index'] +['s', 'k'] +['ann', 'er'] +['is', 'set'] +['Ġout', 'side'] +['led', 'ge'] +['Ġ', 'å'] +['ĠR', 'ob'] +['Ġim', 'm'] +['!', 'Ċ'] +['ĠWe', 'b'] +['D', 'es'] +['B', 'C'] +['anc', 'ial'] +['R', 'oute'] +['D', 'ec'] +['fer', 'ences'] +['Ġp', 'urch'] +['ĠM', 'odel'] +['ct', 'or'] +['g', 'n'] +['_st', 'art'] +['_', 'un'] +['.', '*'] +['is', 'es'] +['Ġg', 'round'] +['Ġun', 'ique'] +['Ġbe', 'aut'] +['{', '"'] +['Ġp', 'our'] +['ĠO', 'ct'] +['Ġt', 'ree'] +['set', 's'] +['_', 'res'] +["')", '->'] +['_re', 'g'] +['("', '\\'] +['Ġby', 'te'] +['B', 'l'] +['Ġd', 'ating'] +['Ġm', 'atter'] +['ĠR', 'em'] +["Ġ'", '../'] +['ĠA', 'ug'] +['ĠL', 'a'] +['Ġ$', '('] +['ourn', 'al'] +['i', 'am'] +['Ġshow', 's'] +['w', 'rite'] +['Ġb', 'all'] +['Ġsim', 'ply'] +['Ġf', 'ast'] +['Ġmem', 'ory'] +['A', 'SS'] +['ĠO', 'f'] +['ov', 'ed'] +['ant', 'e'] +['a', 'ul'] +['ist', 'ry'] +['))', ');Ċ'] +['Ġf', 'it'] +['<', 'string'] +['Ġpolit', 'ical'] +['anc', 'el'] +['_', '.'] +['c', 'ard'] +['.c', 'urrent'] +['o', 'ch'] +['_', 'image'] +['\\', 't'] +['#', 'Ċ'] +['(', 'L'] +['Ġindu', 'stry'] +['com', 'ing'] +['Ġex', 'tra'] +['Ġreport', 'ed'] +['.st', 'art'] +['Ġres', 'ources'] +['Ġim', 'g'] +['fl', 'ow'] +['_E', 'X'] +['(n', 'ull'] +['ĠP', 're'] +['Ġwr', 'ong'] +['inter', 'face'] +['Param', 'eter'] +['n', 'ers'] +['á', '»'] +['t', 'ure'] +['ers', 'ist'] +['oun', 'try'] +['Ġseem', 's'] +['al', 'ance'] +['de', 'st'] +['ĉ', 'String'] +['Ġm', 'aint'] +['Ġun', 'it'] +['act', 'ers'] +['ĠT', 'R'] +['if', 'ul'] +['export', 's'] +['pro', 'ject'] +['App', 'lication'] +['leg', 'ate'] +['Ġt', 'akes'] +['ter', 'm'] +['Ġet', 'c'] +['ust', 'er'] +['Ġappe', 'ar'] +['add', 'ress'] +['Ġf', 'em'] +['h', 's'] +['Ġh', 'om'] +[',', '-'] +['Ġdiff', 'icult'] +['Ġcom', 'ing'] +['O', 'pen'] +['Ġset', 'tings'] +['ĠW', 'ar'] +['ĠTh', 'en'] +['Ġaut', 'om'] +['ĠF', 'oundation'] +['Ġqu', 'ite'] +['D', 'escription'] +['Ġb', 'log'] +['i', 'qu'] +['P', 'S'] +['_f', 'ield'] +['J', 'son'] +['SS', 'ION'] +['ĠS', 'ch'] +['ĠL', 'O'] +['Ġdes', 'cri'] +['Ġevery', 'one'] +['Ġpret', 'ty'] +['Ġlong', 'er'] +['Ġm', 'enu'] +['Ġcurrent', 'ly'] +['se', 'c'] +['Ġrelations', 'hip'] +['################', '################'] +['ĠM', 'ap'] +['as', 'et'] +['Ġparam', 'eters'] +['Ġcr', 'ush'] +['"', 'čĊ'] +['IL', 'ITY'] +['ig', 'ration'] +['Ġc', 'out'] +['t', 'otal'] +['Ġn', 'ames'] +['nd', 'ef'] +['")', ';'] +['ri', 'end'] +['yn', 'amic'] +['Ġeff', 'ort'] +['Ġact', 'ual'] +['Ġfield', 's'] +['O', 'UN'] +['t', 'ers'] +['Ġf', 'ix'] +['_m', 'odel'] +['Ġc', 'ases'] +['C', 'A'] +['M', 'y'] +['Inter', 'face'] +['ĠS', 'E'] +[']', ']'] +['al', 'le'] +['ĠN', 'ational'] +['ĠArray', 'List'] +['in', 'line'] +['.', 'V'] +['ar', 'a'] +['ref', 'ix'] +['as', 'c'] +['Re', 'ader'] +['ĠÐ', '¿'] +['ast', 'ic'] +['(', '()'] +['C', 'l'] +['.annot', 'ation'] +['Ġperform', 'ance'] +['ail', 'y'] +['.to', 'String'] +['.n', 'et'] +['view', 's'] +['.', 'end'] +['ay', 'ers'] +['l', 'ate'] +['ĠA', 'pr'] +['ed', 'eral'] +["']", ')'] +['.b', 'ody'] +['Ġhigh', 'er'] +['_f', 'l'] +['c', 'r'] +['al', 'ert'] +['_n', 'ode'] +['ĠG', 'oogle'] +['Ġit', 'self'] +['A', 'uth'] +['urrenc', 'y'] +['Ġsignific', 'ant'] +['app', 'end'] +['Ġres', 'pect'] +['str', 'ap'] +['Ġun', 'a'] +['riter', 'ia'] +['P', 'ORT'] +['.ap', 'ache'] +['Out', 'put'] +['Ġpro', 'gress'] +['Ġm', 'id'] +['ĠM', 'icrosoft'] +['Ġres', 'ource'] +['ab', 'lish'] +['Ġd', 'im'] +['.', 'load'] +['.A', 'pp'] +['Ġd', 'irection'] +['Ġadd', 'itional'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠ'] +['Ġnum', 'bers'] +['Ġcompan', 'ies'] +['.T', 'h'] +['Ġs', 'ound'] +['user', 'name'] +['Ġstat', 'ement'] +['Ġal', 'ert'] +['Ġcon', 'tract'] +['h', 'ome'] +['_l', 'ength'] +['.Com', 'ponent'] +['e', 'v'] +['.', 'Ex'] +['ï¼', 'ļ'] +['"', ';'] +['ĠH', 'igh'] +['Ġ', ')ĊĊ'] +['ĠP', 'oint'] +['op', 'h'] +['Ġl', 'ines'] +['->', '_'] +['"', ')ĊĊ'] +['o', 'x'] +['app', 'lication'] +['Ġ', ']Ċ'] +['ĊĊĊĊ', 'ĊĊ'] +['Ġso', 'on'] +['ction', 's'] +['ing', 'er'] +['Ġj', 'oin'] +['ĠP', 'e'] +['Ġ', 'ë'] +['Ġl', 'as'] +['.', 'E'] +['c', 'ss'] +['/', 'or'] +['ĠSt', 'art'] +['ĠT', 'O'] +['Ġsub', 's'] +['con', 'n'] +['com', 'ponents'] +['DE', 'BUG'] +['qu', 'are'] +['F', 'unction'] +['end', 'ar'] +['.', 'index'] +['Ġf', 'ill'] +['Ä', 'Ļ'] +['Ġcho', 'ose'] +['h', 'ow'] +['ĠAmeric', 'a'] +['ass', 'ets'] +['--------', '----'] +['ĠV', 'alue'] +['Ġoff', 'ice'] +['Ġv', 'eh'] +['Ġtrans', 'form'] +['ĠAr', 't'] +['Ġin', 'de'] +['Ġf', 'n'] +['Ġim', 'plements'] +['ang', 'o'] +['ple', 'te'] +['+', '"'] +['t', 'mp'] +['am', 'ily'] +['Ġhas', 'h'] +['miss', 'ions'] +['E', 'ST'] +['g', 't'] +['Pro', 'vider'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠ'] +['Ġfl', 'ag'] +['Ġpartic', 'ip'] +['d', 'en'] +['ĠReturn', 's'] +['Ġnot', 'e'] +['ü', 'r'] +['p', 'm'] +['ide', 'os'] +['Ġspec', 'ified'] +['ĠE', 'N'] +['est', 'er'] +['ol', 'id'] +['Ġup', 'on'] +['(', 'std'] +['ĉ', 'v'] +["Ġ'", '\\'] +['u', 'z'] +['Ġv', 'ert'] +['Ġv', 'ict'] +['ĉ', 'self'] +['Ġ"', '$'] +['.', 'k'] +['Ġgroup', 's'] +['g', 'ithub'] +['l', 'ang'] +['Ġm', 'ut'] +['T', 'O'] +['Ġv', 'e'] +['ĠP', 'lease'] +[';ĊĊ', 'Ċ'] +['ac', 'cess'] +['Ġ{', '"'] +['re', 'a'] +['Ġr', 'isk'] +['ick', 'er'] +['og', 'gle'] +['ĉ', 'while'] +['AN', 'G'] +['.s', 'end'] +['Ġwom', 'an'] +['Ġget', 's'] +['Ġ', 'ign'] +['ĠI', 'd'] +['_', 'log'] +['ON', 'E'] +['Ġe', 'vid'] +['ĠH', 'ar'] +['_s', 'ub'] +['Ġend', 'l'] +['Ġinclud', 'ed'] +['()', ');ĊĊ'] +['ĠA', 'p'] +['ig', 'r'] +['Ġs', 'em'] +['ĠBl', 'ack'] +['d', 'oc'] +['_t', 'able'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['-', 'up'] +['Ġca', 'use'] +['Ġ', '..'] +['Ġv', 'an'] +['_d', 'ict'] +['Ġf', 'ocus'] +['IN', 'D'] +['CE', 'SS'] +['.L', 'og'] +['Ġmult', 'iple'] +['id', 'o'] +['Ġreg', 'ard'] +['-', 'M'] +['and', 'ler'] +['our', 'se'] +['Ġde', 'g'] +['.', 'U'] +['Ġadd', 'ition'] +['Ġvar', 'ious'] +['Ġrece', 'ive'] +['е', 'н'] +['ĠH', 'T'] +['Ob', 'j'] +['D', 'F'] +['Ġincre', 'ase'] +['ĠO', 'pen'] +[']', ';'] +['Ġcomm', 'it'] +['?', 'Ċ'] +['ateg', 'ories'] +['at', 'ory'] +['sh', 'ip'] +['ĠM', 'ich'] +['Ġh', 'tml'] +['rom', 'ise'] +['Ġle', 'ave'] +['Ġstr', 'ateg'] +['av', 'en'] +['ĠCon', 'sole'] +['k', 'nown'] +['-', 'n'] +['_', 'LE'] +['.com', 'ponent'] +['Ġb', 're'] +['S', 'ession'] +['i', 'ance'] +['Ġal', 'ign'] +['typ', 'edef'] +['_', 'result'] +['ĠW', 'HERE'] +['.s', 'plit'] +['Ġread', 'ing'] +['FA', 'ULT'] +['Ġc', 'lo'] +['Ġnot', 'ice'] +['_p', 'r'] +['ar', 'ter'] +['Ġlo', 'ck'] +['Ġstand', 'ard'] +['et', 'ic'] +['ell', 'ow'] +['Ġp', 'adding'] +['ĠH', 'is'] +['Ġst', 'ates'] +['_c', 'ast'] +['(', 'P'] +['a', 'a'] +['Ġintern', 'al'] +['e', 'an'] +['ĠP', 'RO'] +['ĠK', 'ey'] +['Ġes', 'pecially'] +['m', 'ing'] +['Ġc', 'ross'] +['Ġn', 'ational'] +['_', 'object'] +['f', 'ilter'] +['Ġs', 'cript'] +['.', 'update'] +['_', 'i'] +['ĠAss', 'ert'] +['/', 'core'] +['%%', '%%'] +['Ġproble', 'ms'] +['ist', 'or'] +['Ġ.', '='] +['Ġar', 'ch'] +['Ġwrit', 'ten'] +['Ġm', 'ilit'] +['M', 'ENT'] +['.', 'ch'] +['ca', 'pe'] +['ĠM', 'us'] +['_', 'config'] +['ĠA', 'PI'] +['fo', 'ot'] +['Ġim', 'ages'] +['end', 'l'] +['.', 'In'] +['F', 'irst'] +['Ġpl', 'atform'] +['.pro', 't'] +['O', 'ption'] +['st', 'e'] +['ĠT', 'ODO'] +['Ġfor', 'ce'] +['.', 'cont'] +['ĉ', 'echo'] +['ĠD', 'av'] +['P', 'tr'] +['(', 'B'] +['R', 'T'] +['ĠB', 'ase'] +[']', "['"] +['Ġann', 'ounc'] +['con', 'sole'] +['ĠP', 'y'] +['d', 's'] +['.', 'as'] +['Ġpre', 'vent'] +['ap', 'an'] +['Ġ{', "'"] +['}', '', "'"] +['Ġde', 'ad'] +['V', 'AL'] +['Q', 'UE'] +['****************************************************************', '********'] +['Ġch', 'arg'] +['R', 'eturn'] +['Ġf', 'ul'] +['d', 'om'] +['Ġr', 'ules'] +['Ġmod', 'ify'] +['Ġe', 'val'] +['h', 'am'] +['at', 'ement'] +['\\', '<'] +['ul', 'a'] +['=', 'False'] +['R', 'A'] +['Ġcont', 'ains'] +['Ġst', 'ack'] +['m', 'ar'] +['Ġ{', '}Ċ'] +['Ġund', 'efined'] +['A', 'ss'] +['ĠCh', 'ina'] +['ve', 'y'] +['*', 'Ċ'] +['Ġplay', 'ing'] +[')', '/'] +['act', 'or'] +['Ġb', 'ottom'] +['li', 'er'] +['ĠN', 'umber'] +['Ġcou', 'ple'] +['D', 'C'] +['ĠS', 'O'] +['g', 'or'] +['.set', 'Text'] +['s', 'uccess'] +['com', 'mand'] +['F', 'ilter'] +['ĠO', 'ur'] +['_', 'item'] +['Ġc', 'tx'] +['Ġro', 'ad'] +['V', 'ersion'] +['c', 'ase'] +['ur', 't'] +['av', 'ior'] +['y', 'ch'] +['semb', 'ly'] +['ĠPro', 'duct'] +['Ġh', 'eld'] +['a', 'fe'] +['Ġinclud', 'es'] +['<', 'quote'] +['Ġa', 'void'] +['ĠF', 'in'] +['ĠM', 'od'] +['Ġt', 'ab'] +['an', 'o'] +['Ã', '±'] +['ipp', 'ing'] +['-', 'e'] +['Ġins', 'ert'] +['t', 'arget'] +['ch', 'an'] +['.M', 'odel'] +['IM', 'E'] +['\\', 'Ċ'] +['Ġm', 'achine'] +['av', 'y'] +['ĠN', 'O'] +['ĠInt', 'er'] +['Ġoper', 'ation'] +['mod', 'al'] +['T', 'ag'] +[']', ':'] +['Ġprodu', 'ction'] +['Ġare', 'as'] +['Ġre', 'n'] +['_f', 'rom'] +['n', 'bsp'] +['Ġoper', 'ator'] +['m', 'en'] +['app', 'ed'] +['_p', 'er'] +['z', 'en'] +['("', '.'] +['.s', 'ave'] +['="', '{{'] +['Ġt', 'or'] +['(', 'response'] +['Ġc', 'andid'] +['Ġcon', 'v'] +['a', 'iled'] +['ĠL', 'ib'] +['com', 'p'] +['ur', 'a'] +['ï¿', '½'] +['ĠH', 'ere'] +['Ġarg', 'ument'] +['h', 'ood'] +['Ġest', 'ablish'] +['ograph', 'y'] +['Ġon', 'Click'] +['amb', 'da'] +['Ġs', 'ch'] +['Ġmov', 'ie'] +['Ġse', 'c'] +['Ġact', 'ivity'] +['Ø', '§'] +['Ġs', 'ql'] +['_', 'all'] +['inc', 'ip'] +['Ġprovid', 'es'] +['Ġs', 'ys'] +['ack', 'et'] +['Ġwas', 'n'] +['Ġus', 'es'] +['ĠF', 'unction'] +['.g', 'oogle'] +['ĠRes', 'ult'] +['Vis', 'ible'] +['ag', 'ma'] +['el', 'come'] +['ĠS', 'y'] +['ĠC', 'ent'] +['AL', 'SE'] +['ac', 'ión'] +['EX', 'T'] +['Ġl', 'icense'] +['ĠL', 'ong'] +['Ġacc', 'om'] +['Ġab', 'ility'] +['.', 'height'] +['Act', 'ive'] +['olog', 'ical'] +['ol', 'y'] +['))', ','] +['.S', 'e'] +['Ġparam', 'eter'] +['pr', 'ite'] +['AB', 'ILITY'] +['.s', 'ervice'] +['ĠG', 'roup'] +['_', 'query'] +['ĠI', 'tem'] +['in', 'ing'] +['Ġj', 'ud'] +['im', 's'] +['f', 'ix'] +['ind', 'er'] +['ag', 'ram'] +['Ġfunction', 's'] +['Ġexper', 'i'] +['ĠE', 'm'] +['Ġro', 't'] +['Ġp', 'en'] +['.b', 'tn'] +['ĠA', 'S'] +['#if', 'def'] +['Ġcho', 'ice'] +['ĠP', 'age'] +['_P', 'RO'] +['Q', 'U'] +['å', 'ı'] +['ant', 'ity'] +['Â', 'Ń'] +['word', 's'] +['Ġread', 'only'] +['Ġf', 'lex'] +['prot', 'ected'] +['ĠAn', 'y'] +['Ġchar', 'acters'] +['enc', 'ed'] +['ĠJ', 'uly'] +['il', 'er'] +['C', 'ard'] +['ur', 'ance'] +['Ġre', 'v'] +['.e', 'vent'] +['al', 'y'] +['Ġwon', 'der'] +['ĠP', 'ort'] +['Ġleg', 'al'] +['ro', 'le'] +['Ġt', 'en'] +['Ġgo', 'es'] +['M', 'P'] +['wh', 'ite'] +['):', 'čĊ'] +['))', 'čĊ'] +['Ġre', 'ference'] +['Ġm', 'is'] +['ĠPro', 'ject'] +['ick', 's'] +['>', '&'] +['C', 'ON'] +['Ġre', 'pl'] +['Ġreg', 'ular'] +['St', 'orage'] +['ram', 'ework'] +['Ġgo', 'al'] +['Ġt', 'ouch'] +['.w', 'idget'] +['Ġbu', 'ilt'] +['d', 'es'] +['P', 'art'] +['(', 're'] +['Ġw', 'orth'] +['h', 'ib'] +['g', 'ame'] +['ĠÐ', '²'] +['ac', 'ion'] +['ĠWh', 'ite'] +['(t', 'ype'] +['(', '`'] +['Ġn', 'atural'] +['Ġin', 'j'] +['Ġcal', 'cul'] +['ĠApr', 'il'] +['.', 'List'] +['Ġassoci', 'ated'] +['ĉ', 'System'] +['~', '~'] +['=', '['] +['Ġst', 'orage'] +['Ġby', 'tes'] +['Ġtr', 'avel'] +['Ġs', 'ou'] +['Ġpass', 'ed'] +['!', '='] +['as', 'cript'] +['.', 'open'] +['Ġgr', 'id'] +['Ġb', 'us'] +['Ġrec', 'ogn'] +['A', 'b'] +['Ġh', 'on'] +['ĠC', 'enter'] +['Ġpre', 'c'] +['b', 'uild'] +['HT', 'ML'] +['ĠS', 'an'] +['Ġcoun', 'tries'] +['a', 'led'] +['t', 'oken'] +['k', 't'] +['Ġqu', 'al'] +['L', 'ast'] +['ad', 'ow'] +['Ġman', 'ufact'] +['id', 'ad'] +['j', 'ango'] +['N', 'ext'] +['x', 'f'] +['.', 'a'] +['Ġporn', 'o'] +['ĠP', 'M'] +['er', 've'] +['it', 'ing'] +['_', 'th'] +['c', 'i'] +['=', 'None'] +['g', 's'] +['Ġlog', 'in'] +['at', 'ives'] +["']", ');Ċ'] +['Ä', 'ħ'] +['Ġ', 'ill'] +['I', 'A'] +['child', 'ren'] +['D', 'O'] +['Ġlevel', 's'] +['Ġ{', '{'] +['Ġlook', 's'] +['Ġ"', '#'] +['To', 'String'] +['Ġnecess', 'ary'] +['ĠĠĠ', 'Ċ'] +['c', 'ell'] +['En', 'try'] +["Ġ'", '#'] +['Ġext', 'rem'] +['Select', 'or'] +['Ġplace', 'holder'] +['L', 'oad'] +['Ġre', 'leased'] +['O', 'RE'] +['En', 'umer'] +['ĠT', 'V'] +['SE', 'T'] +['in', 'q'] +['P', 'ress'] +['ĠDep', 'artment'] +['Ġprop', 'erties'] +['Ġres', 'pond'] +['S', 'earch'] +['a', 'el'] +['Ġre', 'qu'] +['ĠB', 'ook'] +['/', 'Ċ'] +['(', 'st'] +['Ġfin', 'ancial'] +['ick', 'et'] +['_in', 'put'] +['Ġth', 'reat'] +['(', 'in'] +['Str', 'ip'] +['ì', 'Ŀ'] +['ç', 'ão'] +['Ġevid', 'ence'] +['))', ';'] +['ĠB', 'ro'] +['Ġ[', '];Ċ'] +['Ġ', 'ou'] +['b', 'uf'] +['S', 'cript'] +['d', 'at'] +['Ġr', 'ule'] +['#', 'import'] +['="', '/'] +['S', 'erial'] +['Ġstart', 'ing'] +['[', 'index'] +['a', 'e'] +['Ġcon', 'trib'] +['s', 'ession'] +['_', 'new'] +['ut', 'able'] +['o', 'ber'] +['Ġ"', './'] +['Ġlog', 'ger'] +['Ġrecent', 'ly'] +['Ġreturn', 'ed'] +['č', 'čĊ'] +['))', ')Ċ'] +['ition', 's'] +['Ġse', 'ek'] +['Ġcomm', 'unic'] +['Ġ"', '.'] +['Ġuser', 'name'] +['E', 'CT'] +['D', 'S'] +['Ġother', 'wise'] +['ĠG', 'erman'] +['.', 'aw'] +['Ad', 'apter'] +['ix', 'el'] +['Ġsystem', 's'] +['Ġd', 'rop'] +['Ġstruct', 'ure'] +['Ġ$', '("#'] +['enc', 'ies'] +['ann', 'ing'] +['ĠL', 'ink'] +['ĠRes', 'ponse'] +['Ġst', 'ri'] +['Å', '¼'] +['ĠD', 'B'] +['æ', 'Ĺ'] +['and', 'roid'] +['sub', 'mit'] +['ot', 'ion'] +['(', '@'] +['.t', 'est'] +['ĊĊĊĊ', 'ĊĊĊĊ'] +[']', ';čĊ'] +['Ġdirect', 'ly'] +['Ġ"', '%'] +['r', 'is'] +['el', 'ta'] +['A', 'IL'] +[')', '{čĊ'] +['m', 'ine'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠ'] +['(', 'k'] +['b', 'on'] +['as', 'ic'] +['p', 'ite'] +['__', '_'] +['M', 'ax'] +['Ġerror', 's'] +['ĠWh', 'ile'] +['Ġarg', 'uments'] +['Ġens', 'ure'] +['R', 'ight'] +['-b', 'ased'] +['We', 'b'] +['Ġ-', '='] +['Ġint', 'rodu'] +['ĠIn', 'st'] +['ĠW', 'ash'] +['ord', 'in'] +['j', 'oin'] +['D', 'atabase'] +['Ġgr', 'ad'] +['Ġus', 'ually'] +['IT', 'E'] +['Prop', 's'] +['?', '>Ċ'] +['ĠG', 'o'] +['@', 'Override'] +['RE', 'F'] +['Ġ', 'ip'] +['ĠA', 'ustral'] +['Ġ', 'ist'] +['View', 'ById'] +['Ġser', 'ious'] +['Ġcustom', 'er'] +['.prot', 'otype'] +['od', 'o'] +['c', 'or'] +['Ġdo', 'or'] +['ĠWITH', 'OUT'] +['Ġpl', 'ant'] +['Ġbeg', 'an'] +['Ġdist', 'ance'] +['()', ').'] +['Ġch', 'ance'] +['Ġor', 'd'] +['c', 'ame'] +['pr', 'agma'] +['Ġprot', 'ect'] +['rag', 'ment'] +['ĠN', 'ode'] +['en', 'ing'] +['Ñ', 'ĩ'] +['Ġr', 'oute'] +['ĠS', 'chool'] +['h', 'i'] +['Ġne', 'ighb'] +['A', 'fter'] +['lic', 'it'] +['Ġcon', 'tr'] +['Ġpr', 'imary'] +['A', 'A'] +['.Write', 'Line'] +['util', 's'] +['Ġb', 'i'] +['R', 'ed'] +['.L', 'inq'] +['.', 'object'] +['Ġlead', 'ers'] +['un', 'ities'] +['Ġg', 'un'] +['on', 'th'] +['ĠDe', 'v'] +['F', 'ILE'] +['Ġcom', 'ments'] +['_l', 'en'] +['ar', 'row'] +['am', 'ount'] +['R', 'ange'] +['s', 'ert'] +['Grid', 'View'] +['Ġup', 'dated'] +['ĠM', 'o'] +['Ġin', 'form'] +['oci', 'ety'] +['al', 'a'] +['A', 'ccess'] +['Ġh', 'ab'] +['Ġc', 'reat'] +['_', 'arg'] +['ĠJan', 'uary'] +['ĠD', 'ay'] +['")', 'čĊ'] +['up', 'le'] +['d', 'ocument'] +['gor', 'ith'] +['m', 'enu'] +['ĠO', 'ver'] +['b', 'b'] +['.t', 'itle'] +['_', 'out'] +['Ġle', 'd'] +['ur', 'i'] +['Ġ?', '>Ċ'] +['r', 'un'] +['Ġsc', 'ene'] +['(', 'array'] +['de', 'vice'] +['_t', 'itle'] +['ag', 'on'] +[']', 'čĊ'] +['ab', 'y'] +['Ġbe', 'came'] +['bo', 'olean'] +['Ġp', 'ark'] +['ĠC', 'ode'] +['up', 'load'] +['rid', 'ay'] +['ĠSept', 'ember'] +['F', 'e'] +['Ġs', 'en'] +['c', 'ing'] +['F', 'L'] +['C', 'ol'] +['ut', 's'] +['_p', 'age'] +['in', 'n'] +['Ġim', 'plied'] +['al', 'ing'] +['Ġyour', 'self'] +['.C', 'ount'] +['con', 'f'] +['Ġa', 'ud'] +['_in', 'it'] +['.', ')'] +['Ġw', 'rote'] +['N', 'G'] +['.', 'Error'] +['ä', '»'] +['.f', 'or'] +['Ġe', 'qual'] +['ĠRe', 'quest'] +['Ġser', 'ial'] +['Ġallow', 's'] +['X', 'X'] +['Ġm', 'iddle'] +['ch', 'or'] +['Ã', '¸'] +['erv', 'al'] +['.C', 'olumn'] +['read', 'ing'] +['Ġesc', 'ort'] +['ĠAug', 'ust'] +['Ġquick', 'ly'] +['Ġwe', 'ap'] +['ĠC', 'G'] +['rop', 'ri'] +['h', 'o'] +['Ġc', 'op'] +['(', 'struct'] +['ĠB', 'ig'] +['Ġv', 's'] +['Ġfre', 'qu'] +['.', 'Value'] +['Ġaction', 's'] +['Ġpro', 'per'] +['Ġin', 'n'] +['Ġobject', 's'] +['Ġm', 'atrix'] +['av', 'ascript'] +['Ġon', 'es'] +['.g', 'roup'] +['Ġgre', 'en'] +['Ġp', 'aint'] +['ool', 's'] +['y', 'cl'] +['enc', 'ode'] +['ol', 't'] +['com', 'ment'] +['.', 'api'] +['D', 'ir'] +['Ġun', 'e'] +['iz', 'ont'] +['.p', 'osition'] +['Ġdes', 'igned'] +['_', 'val'] +['av', 'i'] +['ir', 'ing'] +['t', 'ab'] +['Ġl', 'ayer'] +['Ġview', 's'] +['Ġre', 've'] +['ra', 'el'] +['ĠO', 'N'] +['r', 'ics'] +['n', 'p'] +['Ġc', 'ore'] +['()', ');čĊ'] +['M', 'ain'] +['Ġexp', 'ert'] +['ĉĉ', 'čĊ'] +['_', 'en'] +['Ġ/', '>'] +['ut', 'ter'] +['I', 'AL'] +['ail', 's'] +['ĠK', 'ing'] +['*/', 'ĊĊ'] +['ĠM', 'et'] +['_', 'end'] +['add', 'r'] +['or', 'a'] +['Ġ', 'ir'] +['M', 'in'] +['Ġsur', 'pr'] +['Ġre', 'pe'] +['Ġdirect', 'ory'] +['P', 'UT'] +['-', 'S'] +['Ġe', 'lection'] +['h', 'aps'] +['.p', 're'] +['c', 'm'] +['Val', 'ues'] +['Ġ"', 'Ċ'] +['c', 'olumn'] +['iv', 'il'] +['Log', 'in'] +['in', 'ue'] +['Ġbeaut', 'iful'] +['Ġse', 'cret'] +['(e', 'vent'] +['Ġch', 'at'] +['um', 's'] +['Ġorig', 'in'] +['Ġeffect', 's'] +['Ġman', 'agement'] +['ill', 'a'] +['t', 'k'] +['Ġset', 'ting'] +['ĠC', 'our'] +['Ġmass', 'age'] +['ĉ', 'end'] +['Ġhapp', 'y'] +['Ġfin', 'ish'] +['Ġc', 'amera'] +['ĠV', 'er'] +['ĠDem', 'ocr'] +['ĠH', 'er'] +['(', 'Q'] +['con', 's'] +['it', 'a'] +["Ġ'", '.'] +['{', '}'] +['ĉ', 'C'] +['Ġst', 'uff'] +['Ġ', ':Ċ'] +['ĠA', 'R'] +['T', 'ask'] +['h', 'idden'] +['er', 'os'] +['IG', 'N'] +['at', 'io'] +['ĠHe', 'alth'] +['ol', 'ute'] +['Ent', 'er'] +["'", '>'] +['ĠT', 'witter'] +['ĠCount', 'y'] +['s', 'cribe'] +['Ġ=', '>Ċ'] +['Ġh', 'y'] +['f', 'it'] +['Ġmilit', 'ary'] +['Ġsa', 'le'] +['re', 'quired'] +['n', 'on'] +['boot', 'strap'] +['h', 'old'] +['r', 'im'] +['-', 'old'] +['ĠD', 'own'] +['Ġm', 'ention'] +['cont', 'act'] +['_g', 'roup'] +['od', 'ay'] +['Ġto', 'wn'] +['Ġsol', 'ution'] +['u', 'ate'] +['ell', 'ing'] +[']', '->'] +['ot', 'es'] +['ent', 'al'] +['om', 'en'] +['osp', 'ital'] +['ĠS', 'up'] +['_', 'EN'] +['Ġsl', 'ow'] +['SE', 'SSION'] +['Ġbl', 'ue'] +['ag', 'o'] +['Ġl', 'ives'] +['Ġ', '^'] +['.', 'un'] +['in', 'st'] +['en', 'ge'] +['Ġcustom', 'ers'] +['Ġc', 'ast'] +['ud', 'get'] +['ï¼', 'ģ'] +['ic', 'ens'] +['Ġdeter', 'min'] +['Se', 'lected'] +['_', 'pl'] +['ue', 'ue'] +['Ġd', 'ark'] +['//', 'ĊĊ'] +['s', 'i'] +['ther', 'n'] +['ĠJ', 'apan'] +['/', 'w'] +['P', 'U'] +['ĠE', 'ast'] +['ov', 'ie'] +['Ġp', 'ackage'] +['Ġn', 'or'] +['Ġap', 'i'] +['b', 'ot'] +['"', '];Ċ'] +['_p', 'ost'] +['ul', 'ate'] +['Ġcl', 'ub'] +["')", ');Ċ'] +['Ġlo', 'op'] +['PI', 'O'] +['ion', 'e'] +['sh', 'ot'] +['In', 'itial'] +['Ġplay', 'ed'] +['reg', 'ister'] +['rou', 'ght'] +['_m', 'ax'] +['ac', 'ement'] +['m', 'atch'] +['raph', 'ics'] +['A', 'ST'] +['Ġexist', 'ing'] +['Ġcomple', 'x'] +['D', 'A'] +['.C', 'h'] +['.com', 'mon'] +['m', 'o'] +["Ġ'", '../../'] +['it', 'o'] +['Ġanal', 'ysis'] +['Ġdel', 'iver'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'Ċ'] +['id', 'x'] +['Ã', 'ł'] +['ong', 'o'] +['ĠEng', 'lish'] +['<', '!--'] +['Ġcomput', 'er'] +['EN', 'SE'] +['Ġp', 'as'] +['Ġr', 'ais'] +['H', 'ash'] +['Ġm', 'obile'] +['Ġo', 'wner'] +['F', 'IG'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['th', 'es'] +['Ġat', 'tr'] +['w', 'd'] +['.t', 'ime'] +['aw', 'n'] +['Ġtreat', 'ment'] +['ĠA', 'c'] +['.', 'View'] +['im', 'pl'] +['m', 'ore'] +['p', 'ass'] +['Ġh', 'a'] +['.f', 'rom'] +['Ġle', 'ading'] +['FF', 'FF'] +['(', 'error'] +['.', 'ui'] +['at', 'ar'] +['ad', 'ers'] +['d', 'ates'] +['Ġz', 'u'] +['Ġfl', 'ow'] +['T', 'arget'] +['Ġinvol', 'ved'] +['Ġi', 'o'] +['par', 'se'] +['$', '_'] +['he', 'st'] +['.', 'int'] +['-', 'item'] +['as', 'y'] +['S', 'p'] +['Ġsh', 'ift'] +['N', 'T'] +['Ġt', 'f'] +['_T', 'R'] +['.', 'web'] +['C', 'S'] +['Ġ}', ')'] +['Ġey', 'es'] +['_', 'z'] +["'", ');čĊ'] +['if', 'orn'] +['Ġ{', '@'] +['Ġn', 'ice'] +['.l', 'ist'] +['ĠĠĠĠ', 'čĊ'] +['Ġf', 'loor'] +['Ġred', 'irect'] +['ĠU', 'K'] +['(', "['"] +['Ġw', 'ish'] +['Ġcap', 't'] +['leg', 'al'] +['ĠI', 'O'] +['Ġst', 'age'] +['.', 'String'] +['ĠA', 'fr'] +['ig', 'en'] +['ĠS', 'H'] +['De', 'lete'] +['ell', 's'] +['Ġsol', 'id'] +['Ġmeet', 'ing'] +['Ġwork', 'ed'] +['Ġed', 'itor'] +['in', 'y'] +['Ð', '¼'] +['_', 'read'] +['.', 'Id'] +['e', 'ff'] +['Off', 'set'] +['ch', 'a'] +['US', 'ER'] +['ĉĉ', 'ĠĠĠ'] +['ipp', 'ed'] +['Ġd', 'ict'] +['ĠR', 'un'] +['.h', 'pp'] +['Ġan', 'g'] +['x', 'ml'] +['im', 'ple'] +['Ġmed', 'ical'] +['_t', 'oken'] +['con', 'nect'] +['Ġh', 'our'] +['Ġcont', 'roller'] +['_m', 'essage'] +['U', 'ID'] +['G', 'r'] +['and', 'ed'] +['_C', 'H'] +['Ġbook', 's'] +['Ġspe', 'ak'] +['am', 'ing'] +['Ġm', 'ount'] +['Rec', 'ord'] +['ĉ', 'struct'] +['.W', 'eb'] +['ond', 'on'] +['Ġ//', 'Ċ'] +['Ġf', 'elt'] +['.A', 'uto'] +['id', 'ge'] +['_p', 'os'] +['P', 'R'] +['Ġmod', 'ern'] +['C', 'ollection'] +['_m', 'sg'] +['C', 'D'] +['ĠL', 'o'] +['Ġsecond', 's'] +['ib', 'ly'] +['.e', 'quals'] +['Ġintern', 'ational'] +['#', 'pragma'] +['oo', 'th'] +['W', 'riter'] +['i', 'ate'] +['Ġce', 'le'] +['ĠB', 'it'] +['iv', 'o'] +['iv', 'ery'] +['r', 'd'] +['HE', 'CK'] +['Ġc', 'ache'] +['.c', 'ount'] +['Ġro', 'll'] +['.Re', 'ad'] +['RE', 'D'] +['Ġset', 'up'] +['izont', 'al'] +['model', 's'] +['arg', 'v'] +['Ġconsider', 'ed'] +['="', '../'] +['set', 'tings'] +['ĠR', 'el'] +['Ġgrow', 'th'] +['Ġm', 'ix'] +['ĠWash', 'ington'] +['Ġpl', 't'] +['ĠI', 'M'] +['á', 'º'] +['Ġturn', 'ed'] +['ĠDate', 'Time'] +['ĠW', 'ed'] +['(', 'url'] +['Ġ"', '-'] +['Ġlet', 'ter'] +['As', 'ync'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠ'] +['ĠOct', 'ober'] +['_l', 'ine'] +['Ġatt', 'ention'] +['Ġcol', 'lect'] +['ĠH', 'ash'] +['Ġim', 'ag'] +['T', 'ree'] +['Ġsit', 'uation'] +['et', 'te'] +['_n', 'o'] +['IV', 'E'] +['Ġv', 'on'] +['.t', 'arget'] +['Ġknow', 'ledge'] +['Ġdr', 'ive'] +['.p', 'ost'] +['Ġb', 'lood'] +['Ġc', 'it'] +['pr', 'imary'] +['Ġconfig', 'uration'] +['te', 'e'] +['Ġph', 'oto'] +['is', 'ode'] +['Tr', 'ace'] +['Ġg', 'ave'] +['Ġsh', 'ot'] +['ĠA', 'ir'] +['Ġm', 'other'] +['pr', 'ice'] +['Ġmor', 'ning'] +['))', '{Ċ'] +['-', 'x'] +['Ġtr', 'ade'] +['Ġdes', 'c'] +['Ġ&&', 'Ċ'] +['Ġparent', 's'] +['A', 'pi'] +['å', 'Ī'] +['t', 'ed'] +['w', 'er'] +['Ġ', 'æ'] +['Ġs', 'y'] +['ĠK', 'e'] +['Par', 'ser'] +['å', 'ħ'] +['anc', 'y'] +['Ġpie', 'ce'] +['iforn', 'ia'] +['to', 'String'] +['r', 'an'] +['id', 'ing'] +['PT', 'ION'] +['com', 'es'] +['/', 'lic'] +['.c', 'lient'] +['E', 'l'] +['L', 'ong'] +['Ġprofession', 'al'] +['ru', 'pt'] +['v', 'a'] +['Ġcomplet', 'ely'] +['Ġpract', 'ice'] +['Ġse', 'lection'] +['R', 'em'] +['in', 'i'] +['Ġc', 'am'] +['RE', 'E'] +['Ġsit', 'es'] +['p', 'a'] +['AT', 'US'] +['Ñģ', 'ÑĤ'] +['arr', 'ant'] +['*', '('] +['_', 'KEY'] +['ĠB', 'utton'] +['ĠF', 'riday'] +['se', 'qu'] +['Ġre', 'ader'] +['Ġm', 'essages'] +['è', '¯'] +['Ġbu', 'f'] +['K', 'e'] +['Ġn', 'ov'] +['H', 'P'] +['M', 'sg'] +['al', 'ign'] +['ar', 'ily'] +["Ġ'", ','] +['_w', 'ith'] +['Ġd', 'as'] +['Ġhe', 'ard'] +['at', 'omic'] +['ri', 'al'] +[')', '['] +['Ġdis', 'e'] +['@', 'end'] +['Ġg', 'old'] +['Ġf', 'air'] +['Ġsa', 'les'] +['.', 'Button'] +['str', 'ict'] +['s', 'ave'] +['Ġme', 'asure'] +['Ġ"', '+'] +['ec', 'ause'] +['View', 'Controller'] +['ĠT', 'able'] +['.p', 'aram'] +['Ġdec', 'ided'] +['((', '('] +['IN', 'FO'] +['Ġopport', 'unity'] +['T', 'e'] +['IC', 'ENSE'] +['cc', 'ording'] +['k', 'i'] +['ĠU', 'N'] +['Ġcont', 'ain'] +['Ġman', 'ager'] +['Ġp', 'ain'] +['ĠF', 'ire'] +['rom', 'e'] +['Ġpl', 'ans'] +['F', 'ound'] +['l', 'ay'] +['ĠDec', 'ember'] +['Ġinfl', 'u'] +['Ã', 'º'] +['ren', 'ch'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'Ġ'] +['az', 'ing'] +['b', 'rief'] +['c', 'all'] +['wo', 'od'] +['Ġload', 'ed'] +['Ġgr', 'and'] +['/', 'f'] +['im', 'p'] +['_', 'U'] +['ST', 'R'] +['âĢ', '¢'] +['Ġcred', 'it'] +['.C', 'olor'] +['or', 'ge'] +['QUE', 'ST'] +['Ġdiffer', 'ence'] +['ĠP', 'C'] +['w', 'args'] +['Ġp', 'ub'] +['und', 'ay'] +['Ġf', 'ra'] +['.m', 'ax'] +['Ġtri', 'ed'] +['ann', 'els'] +['s', 'end'] +['Ġreport', 's'] +['Ġad', 'ult'] +['ä', 'º'] +['Ġcons', 'ist'] +['ĠSt', 'reet'] +['ĠPro', 'gram'] +['S', 'QL'] +['M', 'atrix'] +['ounc', 'il'] +['-', 'A'] +['ĉ', 'w'] +['Ġwho', 'se'] +['Ġrel', 'ig'] +['ĠS', 'ex'] +['Ġg', 'ives'] +['n', 'one'] +['.m', 'essage'] +['(', 'G'] +['.aw', 't'] +['-', 'right'] +['ĠNov', 'ember'] +['ell', 'ig'] +['ut', 'ive'] +['Ä', 'ĥ'] +['over', 'n'] +['Ġeas', 'ily'] +['Ġide', 'as'] +['ĠÐ', '½'] +['/c', 'ss'] +['ly', 'ing'] +['el', 'le'] +['C', 'an'] +['_c', 'olor'] +['оÐ', '²'] +['Ġp', 'air'] +['ng', 'th'] +['Ġs', 'plit'] +['d', 'rop'] +['art', 'y'] +['on', 'a'] +['Ġcap', 'ital'] +['Ġhe', 'ar'] +['Ġex', 'ists'] +['ĉ', 'log'] +['em', 'o'] +['R', 'un'] +['o', 'i'] +['Ġpar', 'ser'] +['ĠM', 'ethod'] +['Ġeduc', 'ation'] +['[', 'k'] +['Ġlib', 'rary'] +['>', '";Ċ'] +['_', 'UN'] +['ĉ', 'std'] +['od', 'ed'] +['Ġcall', 's'] +['h', 'ere'] +['R', 'el'] +['Ġbr', 'and'] +['back', 'ground'] +['g', 'a'] +['_add', 'ress'] +['_param', 's'] +['C', 'ategory'] +['ĠInd', 'ia'] +['_e', 'vent'] +['Ġ', 'ing'] +['R', 'ender'] +['.c', 'l'] +['ump', 'y'] +['Ġp', 'et'] +['F', 'C'] +['ĠA', 'nt'] +['Ex', 't'] +['Ġchar', 'ge'] +['en', 'ed'] +['gr', 'ad'] +['E', 'O'] +['Ġdep', 'end'] +['Ġ', '.ĊĊ'] +['fr', 'ame'] +['Ġd', 'f'] +['Ġh', 'uge'] +['ĠP', 'ART'] +['ed', 's'] +[';', ';'] +['ĠA', 'M'] +['Ġbas', 'ic'] +['ĠL', 'et'] +['lic', 'h'] +['Ġar', 'm'] +['Ġst', 'ar'] +['Ġf', 'ederal'] +['W', 'ork'] +['Ġcar', 'ry'] +['ĠIs', 'rael'] +['(', 'obj'] +['={', '{'] +['Ġs', 'aved'] +['Ġs', 'yn'] +['Ġconst', 'ant'] +['V', 'ENT'] +['Ġpos', 'itive'] +['Ġcon', 'duct'] +['Ġsk', 'in'] +['Ġear', 'lier'] +['Ġl', 'ayout'] +['ĠI', 'P'] +['O', 'UR'] +['Ġt', 'im'] +['styles', 'heet'] +['_', 'cl'] +['ĠC', 'ard'] +['++', '){Ċ'] +['Ġtem', 'per'] +['ĠDav', 'id'] +['ĉ', 'try'] +['.d', 'art'] +['Ġwant', 's'] +['Ġp', 'icture'] +['Ġv', 'ideos'] +['ĠCom', 'm'] +['is', 'ions'] +['_M', 'AX'] +['M', 'apping'] +['-', 'content'] +['ĠE', 'ar'] +['-', 'de'] +['Ġpre', 'm'] +['br', 'uary'] +['Ġcom', 'ponents'] +['Ġthrough', 'out'] +['Ġp', 'ull'] +['Ġp', 'ages'] +['ent', 'e'] +['res', 'pond'] +['Ġg', 'as'] +['cript', 'or'] +['Ġed', 'ge'] +['Ġb', 'ound'] +['A', 'CT'] +['****', '**'] +['Ġcre', 'ating'] +['ĠC', 'H'] +['Ġnull', 'ptr'] +['B', 'r'] +['+', "'"] +['.c', 'o'] +['>', '::'] +['Ġle', 'arning'] +['.L', 'ength'] +['_S', 'H'] +['Ġpat', 'ients'] +['A', 'IN'] +['Ġk', 'ids'] +['Ġcom', 'fort'] +['Ġsh', 'own'] +['ug', 'ins'] +['ĠB', 'ack'] +['ell', 'a'] +['_C', 'L'] +['Ġl', 'at'] +['Ġdis', 'patch'] +['Ġclass', 'es'] +['.', 'at'] +['.b', 'egin'] +['Ġsuccess', 'ful'] +['b', 'an'] +['Ġobt', 'ain'] +['ĠS', 'l'] +['Ġl', 'ack'] +['iter', 'ator'] +['Th', 'read'] +['(s', 'ize'] +['Ġn', 'one'] +['.h', 'as'] +['_', 'X'] +['s', 'ort'] +['n', 'ap'] +['p', 'et'] +['b', 'in'] +['ĠCan', 'ada'] +['The', 'y'] +['Ġd', 'ans'] +['ĠM', 'at'] +['<', 'td'] +['Ġh', 'air'] +["Ġ'", "',Ċ"] +['Ġc', 'u'] +['Ġlaw', 's'] +['let', 'ed'] +['p', 'ed'] +['Ġp', 'ow'] +['Ġk', 'new'] +['_C', 'OM'] +['_', ','] +['ĠM', 'ag'] +['id', 'ents'] +['(', 'req'] +['Ġ', '),'] +['-', 'center'] +['Ġw', 'ide'] +['ĠA', 'uthor'] +['st', 'ants'] +['Ġjob', 's'] +['Ġm', 'ath'] +['et', 'imes'] +['Bo', 'olean'] +['Ġs', 'cope'] +['_', 'is'] +['Ġme', 'as'] +['Ġkey', 's'] +['el', 'ay'] +['Ġexact', 'ly'] +["'=>", "'"] +['ĠP', 'aul'] +['m', 'as'] +['ĉ', 'print'] +['(l', 'en'] +['f', 'd'] +['Ġ)', ';'] +['.', 'Event'] +['q', 'li'] +['ir', 'it'] +['ield', 's'] +['om', 'an'] +['ĠT', 'op'] +['Ġv', 'ote'] +['Ġm', 'ask'] +['Ġthem', 'e'] +['-', 'Ċ'] +['Ġpro', 'ps'] +['Ġf', 'ine'] +['Ġwrit', 'er'] +['_', 'offset'] +['c', 'ar'] +['Ġal', 'tern'] +['Ġc', 'opyright'] +['Ġdest', 'roy'] +['pp', 'er'] +['Ġgener', 'ate'] +['pp', 'ed'] +['âĢĻ', 'd'] +['ĠĠĠĠĠĠ', 'Ċ'] +['m', 'ake'] +['ĠSh', 'ow'] +['Ġb', 'rowser'] +['Ġfavor', 'ite'] +['Ġcare', 'er'] +['Ġhappen', 'ed'] +['(', 'char'] +['Ġrecomm', 'end'] +['Ġl', 'iter'] +['.f', 'ilter'] +['gr', 'ade'] +['ĠÂ', '£'] +['Ph', 'one'] +['om', 's'] +['Ġn', 'amed'] +['-', 'label'] +['ip', 'o'] +['ĠO', 'ther'] +['Ġp', 'anel'] +['Ġro', 'ck'] +['S', 'cale'] +['ĉ', 'assert'] +['Ð', '´'] +['Ġtr', 'ust'] +['fr', 'ont'] +['Ġdem', 'on'] +['A', 'r'] +['N', 'et'] +['Ġecon', 'omic'] +['foot', 'er'] +['Ġr', 'ace'] +['(n', 'ode'] +['ĠO', 'ption'] +['s', 'plit'] +['Ġphys', 'ical'] +['if', 'est'] +['Ġrem', 'oved'] +['.', 'http'] +['))', ',Ċ'] +['Ġlook', 'ed'] +["'", ';'] +['d', 'ing'] +['g', 'est'] +['atur', 'day'] +['/lic', 'enses'] +['Pr', 'ice'] +['Ġd', 'ro'] +['Ġto', 'wards'] +['Ġun', 's'] +['ĠC', 'L'] +['ĉ', 'static'] +['Ġ', 'rows'] +['Ġdef', 'ine'] +['.re', 'place'] +['Ġf', 'ather'] +['ĠDes', 'ign'] +['ass', 'ign'] +['m', 'ut'] +['De', 'vice'] +['D', 'id'] +["')", ')Ċ'] +['omet', 'ry'] +['ay', 'load'] +['Ġh', 'istor'] +['ĠP', 'aram'] +['ĠBo', 'olean'] +['Ġn', 'ature'] +['Ġj', 's'] +['Ġn', 'ation'] +['i', 'h'] +['Ġdis', 'cover'] +['se', 'm'] +['Hand', 'le'] +['ĉ', 'r'] +['ĠTe', 'chn'] +['Ġw', 'all'] +['{', '$'] +['@', 'property'] +['Ġ"', '../'] +['Ġex', 'am'] +['.d', 'raw'] +['opp', 'ing'] +['Ġnear', 'ly'] +['Ġco', 'ol'] +['Ġinde', 'pend'] +['RE', 'S'] +['Ġhand', 'ler'] +['ĠMon', 'day'] +['Ġs', 'un'] +['St', 'yles'] +['ous', 'ly'] +['Ġ', 'ĉ'] +['v', 'est'] +['D', 'isplay'] +['(', 'y'] +['atic', 'ally'] +['Ġpred', 'ict'] +['y', 'ing'] +['Ġsom', 'etimes'] +['"', ']Ċ'] +['Ġdr', 'ink'] +['Ġb', 'ul'] +['ific', 'ations'] +['.', 'insert'] +['.re', 'g'] +['Ġtest', 's'] +['Al', 'ignment'] +['Ġal', 'leg'] +['Ġat', 'tribute'] +['ĠN', 'ote'] +['Ġmy', 'self'] +['art', 's'] +['N', 'ow'] +['Ġinterest', 'ing'] +['li', 'ents'] +['Ġpop', 'ulation'] +['ĠCal', 'ifornia'] +['"', 'I'] +['å', '¹'] +['Ġgre', 'ater'] +['ues', 'day'] +['Ġth', 'ous'] +['Ġcost', 's'] +['Ġla', 'unch'] +['\\', 'Http'] +['k', 'er'] +['b', 'and'] +['ĠPl', 'ay'] +['Ġb', 'and'] +['.sh', 'ape'] +['es', 'ome'] +['art', 'icle'] +['.r', 'f'] +['Ġw', 'er'] +['á', 's'] +['em', 'bers'] +['us', 'r'] +['B', 'A'] +['ic', 'an'] +['et', 't'] +['valid', 'ate'] +['ult', 'i'] +['Ġimmedi', 'ately'] +['z', 'er'] +['Ġfig', 'ure'] +['o', 'es'] +['ell', 'er'] +['irc', 'le'] +['ĠS', 'ign'] +['.d', 'b'] +['Ġr', 'ank'] +['By', 'tes'] +['Ġproject', 's'] +['_re', 'c'] +['UL', 'AR'] +['A', 'PI'] +['ĠL', 'ine'] +['P', 'ort'] +['Ġp', 'oll'] +['Ġg', 'iving'] +['id', 'ence'] +['--', 'Ċ'] +['Ġpl', 'ot'] +['ic', 'ial'] +['Ġw', 'arrant'] +['IT', 'ION'] +['ĠD', 'ouble'] +['Ġbill', 'ion'] +['gorith', 'm'] +['Ġequ', 'ipment'] +['D', 'ATE'] +['Ġ@', '"'] +['E', 'E'] +['Ġp', 'le'] +['i', 'ation'] +['Ġhead', 'ers'] +['Ġpro', 'ced'] +['.Component', 'Model'] +['ĠOb', 'ama'] +['Ġp', 'a'] +['ĠB', 'est'] +['im', 'ately'] +['.get', 'String'] +['.', '\\'] +['mp', 'loy'] +['Ġr', 'aw'] +['_b', 'lock'] +['und', 'red'] +['"', '},Ċ'] +['.Group', 'Layout'] +['Ġb', 'rought'] +['NS', 'String'] +['th', 'row'] +['cre', 'ated'] +['.N', 'ew'] +['_', 'view'] +['C', 'P'] +['ep', 's'] +['O', 'p'] +['Ġgr', 'atis'] +["Ġ'", '"'] +['Ġinter', 'view'] +['""', '"Ċ'] +['Ġpart', 'ial'] +['Ġa', 'ria'] +['b', 'ing'] +['A', 'uthor'] +['Bo', 'ok'] +['ĠP', 'at'] +['um', 'an'] +['Us', 'ers'] +['pl', 'us'] +['ĠD', 'irect'] +['ven', 'ue'] +['al', 'pha'] +['UC', 'CESS'] +['ĠC', 'all'] +['Ġ', ');čĊ'] +['im', 'ated'] +['Ġrem', 'ain'] +['Ġant', 'i'] +['ĠL', 'ondon'] +['Ġsaf', 'ety'] +['PO', 'SE'] +['o', 'les'] +['cont', 'roller'] +['By', 'te'] +['ĠCour', 't'] +['ĠPh', 'il'] +['ĠAss', 'oci'] +['en', 'a'] +['å', 'IJ'] +['_ST', 'R'] +['co', 'in'] +['resh', 'old'] +['Ġb', 'atch'] +['_C', 'lick'] +['entic', 'ation'] +['>', "';Ċ"] +['ent', 'y'] +['Ġbegin', 'ning'] +['Ġz', 'ero'] +['ĠCon', 'vert'] +['Ġt', 'err'] +['Ġp', 'aid'] +['Ġincre', 'ased'] +['c', 'atch'] +['-s', 'ize'] +['act', 'ivity'] +['e', 'quals'] +['Ġque', 'ue'] +['Ġ"', "'"] +['ĠIntern', 'ational'] +['Ġf', 'ür'] +['urs', 'day'] +['Ġsc', 'ient'] +['all', 'ow'] +['ax', 'is'] +['Ġapp', 'ropri'] +['ed', 'ge'] +['Ġid', 'x'] +['S', 'uccess'] +['ent', 'ifier'] +[':', '\\'] +['x', 'is'] +['Ġmax', 'imum'] +['ark', 's'] +['Ġb', 'irth'] +['(', 'index'] +['Ġmay', 'be'] +['.p', 'y'] +['file', 's'] +['Ġlim', 'ited'] +['_', 'check'] +['lo', 'ok'] +['pl', 'ies'] +['Ġmov', 'ement'] +["']", '.'] +['Ġbro', 'ad'] +['ĠB', 'E'] +['ĠUn', 'ityEngine'] +['.c', 'pp'] +['ĠE', 'very'] +['Ad', 'min'] +['Ġf', 'ans'] +['p', 'ared'] +['Ċ', 'ĠĠĠĠĊ'] +['Ġfore', 'ign'] +['Ġp', 'an'] +['Ġt', 'our'] +['ĠOr', 'der'] +['Ġmov', 'ing'] +['Ġa', 'uf'] +['C', 'all'] +['c', 'b'] +['Å', 'Ł'] +['vent', 'ory'] +['ĠS', 'ql'] +['Ġful', 'ly'] +['Click', 'Listener'] +['W', 'ORD'] +['Ġannounc', 'ed'] +[')', 'čĊčĊ'] +['Ġagre', 'ed'] +['ri', 'e'] +['Ġe', 'arn'] +['_l', 'ink'] +['.', 'array'] +['(t', 'ext'] +['Ġmaterial', 's'] +[',', 'p'] +['ff', 'ff'] +['v', 'g'] +['ĠÂ', '©'] +['Ġun', 'less'] +['aj', 'ax'] +['LO', 'G'] +['Ġsex', 'ual'] +['Ġ\\', '"'] +['-', 'time'] +['Ġco', 'ach'] +['Ġsupport', 'ed'] +['Ġphot', 'os'] +['if', 'orm'] +['.C', 'reate'] +[')', ']'] +['ri', 'er'] +['Ġd', 'ialog'] +['av', 'er'] +['ig', 'e'] +[')', '+'] +['_id', 'x'] +[':', '['] +['_m', 'in'] +['ĠC', 'ong'] +['Ġpress', 'ure'] +['Ġteam', 's'] +['S', 'ign'] +['b', 'egin'] +['ri', 'an'] +['NE', 'SS'] +['L', 'S'] +['Ġimpro', 've'] +['ĠS', 'unday'] +['Ġdef', 'inition'] +['ig', 'er'] +['roll', 'ers'] +['Ġthink', 'ing'] +['T', 'emplate'] +['-', 'F'] +['Ġem', 'erg'] +['pl', 'ates'] +['ĠUS', 'A'] +['.set', 'State'] +['ĠAl', 'so'] +['re', 'v'] +['Ġen', 'able'] +['ĠC', 'O'] +['PE', 'CT'] +['Ġcon', 'cept'] +[')', '-'] +['ĠâĢ', '¢'] +['Ġset', 's'] +['Ġmean', 'ing'] +['em', 'on'] +['ĠCon', 's'] +['c', 'mp'] +['ed', 'er'] +['ann', 'ed'] +['icens', 'ed'] +['ĠS', 'uper'] +['Ġd', 'aily'] +['Ġmult', 'i'] +['_', 'u'] +['Ġchall', 'eng'] +['_m', 'ode'] +['ĠP', 'romise'] +['Ġstr', 'ict'] +['j', 'o'] +['int', 'on'] +['(', 'list'] +['On', 'ly'] +['>', '{'] +['Ġveh', 'icle'] +['í', 'ķ'] +['ĠPl', 'ayer'] +['ĠD', 'el'] +['Ġp', 'ool'] +['.', 'url'] +['nes', 'day'] +['();čĊ', 'čĊ'] +['Ġ"', ');Ċ'] +['L', 'ocal'] +['.', '");Ċ'] +['Ġorgan', 'ization'] +['re', 'nder'] +['ĠApp', 'lication'] +['Ġsum', 'mer'] +['ex', 'pected'] +['N', 'A'] +['Ġr', 'ap'] +['_', 'obj'] +['Ġsur', 'face'] +['ĠP', 'UR'] +['Ġ},', 'ĊĊ'] +['Ġvariable', 's'] +['(m', 'essage'] +['Ġop', 'in'] +['.b', 'ack'] +['а', 'н'] +['Ġwork', 'ers'] +['v', 'm'] +['C', 'o'] +['ught', 'er'] +['Ġm', 'aster'] +['Ġ"', '",'] +['Ġst', 'ories'] +['.', 'User'] +['Ġcele', 'br'] +['ines', 'e'] +['B', 'S'] +['ĠCom', 'mand'] +['ash', 'board'] +['Ġo', 'g'] +['k', 'g'] +['.', 'image'] +['.st', 'yle'] +['Ġstep', 's'] +['ĠB', 'en'] +['(', 'args'] +['ĠP', 'erson'] +[',', 'y'] +['Ġofficial', 's'] +['|', 'Ċ'] +['Ġsk', 'ills'] +['v', 'c'] +['Ġbuild', 'er'] +['Ġg', 'ar'] +['A', 'ccount'] +['ĠA', 'uth'] +['ç', 'Ķ'] +["']", ')Ċ'] +['ĠA', 'T'] +['n', 'n'] +['.', 'Int'] +['SS', 'ERT'] +['Ġeffect', 'ive'] +['LE', 'TE'] +['Ġto', 'ols'] +['AR', 'D'] +['Ġdig', 'ital'] +['D', 'ouble'] +['ĠF', 'ind'] +['R', 'C'] +['Ġin', 'line'] +['/', 'r'] +['AR', 'AM'] +['AS', 'K'] +['Ġint', 'ent'] +['a', 'ight'] +['_add', 'r'] +['Ġrequest', 's'] +['.f', 'irst'] +['Ġde', 'bug'] +['Ġsp', 'ent'] +['()', '));Ċ'] +['Å', 'Ľ'] +['Ġpr', 'incip'] +['Log', 'ger'] +['clud', 'es'] +['.', 'use'] +['Ġsur', 'v'] +['med', 'ia'] +['ĠFe', 'bruary'] +['ĠM', 'ac'] +['Ġmiss', 'ing'] +['Ġw', 'ife'] +['Ġtalk', 'ing'] +['ĠM', 'ake'] +['Ġc', 'art'] +['Ġloc', 'ated'] +['E', 'nc'] +['-', 'a'] +['ch', 'ron'] +['Ġc', 'ards'] +['Ġgu', 'y'] +['Ġp', 'ers'] +['ĠY', 'es'] +['ate', 'ver'] +['ĠA', 'ng'] +['ol', 'ar'] +['ĠE', 'ven'] +['Ġacc', 'ur'] +['ĠP', 'ower'] +['ĠG', 'old'] +['c', 'lear'] +['Pro', 'cess'] +['Ġrec', 'ords'] +['Ġk', 'illed'] +['.c', 'lear'] +['ĠWARRANT', 'IES'] +['Ġpur', 'pose'] +['pan', 'el'] +['J', 'ECT'] +['ÃŃ', 'a'] +['Ġex', 'erc'] +['W', 'S'] +['/', 'L'] +['.', 'exports'] +['Ġ__', '_'] +['Ġs', 'in'] +['S', 'ervlet'] +['Ġd', 'é'] +['.de', 'lete'] +['ro', 'ke'] +['S', 'l'] +['ug', 'h'] +['ear', 's'] +['Ġpoint', 'er'] +['Ġh', 'op'] +['all', 'ery'] +['Ġo', 'bs'] +['co', 'very'] +['ĉ', 'char'] +['ĉĉĉĉ', 'ĉĉĉĉĉĉ'] +['ĉ', 'def'] +['oc', 'ity'] +['itch', 'en'] +['ul', 'ations'] +['ĠF', 'IT'] +['Ġ', ').'] +['straint', 's'] +['vent', 'ion'] +['Ġrequ', 'ires'] +['ĠO', 'per'] +['M', 'E'] +['OUN', 'T'] +['al', 'let'] +['Ġn', 'orm'] +['I', 'RE'] +['ex', 'as'] +['Ġprogram', 's'] +['Ġwe', 'ak'] +["'", '.$'] +['u', 'ing'] +['ĉ', 'ĠĠĠĠĠĠĠ'] +['Ġm', 'il'] +['Ġf', 'irm'] +['init', 'ely'] +['_VAL', 'UE'] +['ap', 'se'] +['atis', 'f'] +['Ġdem', 'and'] +['_m', 'od'] +['Ġdescri', 'bed'] +['Ġpl', 'aces'] +['V', 'ID'] +['Ġal', 'one'] +['Ġex', 'port'] +['Ġv', 'ec'] +['ĠM', 'ax'] +['Ġactiv', 'ities'] +['ict', 'ures'] +['g', 'ener'] +['Ġm', 'a'] +['Ĥ', '¬'] +['Ġexpress', 'ion'] +['C', 'allback'] +['_', 'content'] +['ĠM', 'ost'] +['Ġtest', 'ing'] +['E', 'C'] +['CH', 'ANT'] +['Ġad', 'just'] +['.Th', 'reading'] +['(', 'ctx'] +['Ġag', 'ree'] +['ig', 'hest'] +['Ġu', 'i'] +['ĠL', 'aw'] +['.', 'Y'] +['>', '', 'ĊĊ'] +['.ex', 'ample'] +['ber', 'g'] +['Ġmov', 'ed'] +['ĉ', 'e'] +['ĠS', 'aturday'] +['Ġpay', 'load'] +['Ä', 'ĩ'] +[')', ':ĊĊ'] +['Ġbe', 'y'] +['ur', 'er'] +['<', 'script'] +['Ġs', 'ymbol'] +['Ġass', 'um'] +['Ġp', 'ul'] +['E', 'ffect'] +['Ġh', 'undred'] +['To', 'ol'] +['ak', 'ed'] +['con', 'nection'] +['Ġvo', 'ice'] +['Ġp', 'd'] +['Ġtrans', 'action'] +['Ġlink', 's'] +['E', 'rr'] +['ĠInd', 'ian'] +['T', 'C'] +['atal', 'og'] +['n', 'i'] +['s', 'ign'] +['<<', '"'] +['j', 'i'] +['y', 'a'] +['Ġdemon', 'str'] +['ul', 'ated'] +['.', 'St'] +['Ġinst', 'it'] +['Ġbo', 'ost'] +['Ġcell', 's'] +['ol', 'ic'] +['.P', 'ro'] +[':', '', ','] +['">', '', '\\'] +['Ġth', 'us'] +['ĠReg', 'ister'] +['h', 'ol'] +['ĠCh', 'inese'] +['Ġpost', 'ed'] +['Ġm', 'agn'] +['ab', 'ilities'] +['Ġdise', 'ase'] +['Ġrem', 'ains'] +['ĠPro', 'f'] +['-', 'form'] +['Ġc', 'in'] +['org', 'an'] +['ic', 'ate'] +['Ġst', 'ress'] +[']', '*'] +['Ġ', '----------------------------------------------------------------'] +['_', 'context'] +['or', 'ry'] +['Ġd', 'ied'] +['m', 'at'] +['Ġstart', 's'] +['.M', 'essage'] +['Ġrun', 's'] +['Ġgu', 'ide'] +['Ġwarrant', 'y'] +['ential', 's'] +['d', 'ict'] +['ĠS', 'ize'] +['ul', 'er'] +['Ġrespons', 'ible'] +['_SE', 'T'] +['Ġcont', 'aining'] +['ĠPr', 'ice'] +['|', '|'] +['F', 'S'] +['Ġem', 'p'] +['_b', 'utton'] +['(', 'uint'] +['Ġsu', 'ff'] +['p', 'th'] +['Ġdef', 'initely'] +['put', 'e'] +['Ġmarket', 'ing'] +['ĠW', 'H'] +['ĠS', 'ie'] +['+', '='] +['OL', 'OR'] +['Ġcons', 'ult'] +['Ġs', 'igned'] +['Ġse', 'quence'] +['le', 'e'] +['Ġrequire', 'ments'] +['h', 'y'] +['Ex', 'press'] +['M', 'T'] +['se', 'y'] +['Ġ', 'ult'] +['å', '®'] +['ellig', 'ence'] +['Ġanal', 'y'] +['Ġd', 'ress'] +['eng', 'ine'] +['ĠG', 'reat'] +['ĠAnd', 'roid'] +['ĠA', 'lex'] +['m', 'ode'] +['D', 'ictionary'] +['.D', 'ate'] +['ä', '½'] +['V', 'ICE'] +['Ġfam', 'ilies'] +['ĠRuss', 'ian'] +['ĠT', 'imes'] +['.c', 'all'] +['$', '('] +['Pro', 'file'] +['Ġf', 'older'] +['ch', 'es'] +['Ġleg', 'is'] +['_', 'row'] +['un', 'es'] +['Ù', 'Ħ'] +['Ġ}', ').'] +['Ass', 'ert'] +['ag', 'en'] +['ĠH', 'and'] +['I', 'ter'] +['Ġbig', 'gest'] +['ore', 'ach'] +['Ġpol', 'ic'] +['Ġper', 'missions'] +['Ġshow', 'ed'] +['ĠE', 'lement'] +['Ġtop', 'ic'] +['âĢĶ', 'âĢĶ'] +['ro', 'ad'] +['ĠB', 'ank'] +['rec', 'ord'] +['Ġpart', 'ners'] +['ĠR', 'ef'] +['ess', 'ions'] +['Ġass', 'ess'] +['U', 'ST'] +['ĠPart', 'y'] +['pro', 'du'] +['L', 'C'] +['Ġ', 'ul'] +['.', 'form'] +['h', 'ide'] +['c', 'opy'] +['UT', 'F'] +['ĠSO', 'FTWARE'] +['čĊčĊ', 'čĊ'] +['ĠL', 'in'] +['un', 'a'] +['ug', 'ar'] +['Ġadmin', 'istration'] +['Ġopen', 'ing'] +['Ġsc', 'an'] +['Ġcontin', 'ued'] +['com', 'ponent'] +['.s', 'p'] +['Ġhapp', 'ens'] +['um', 'my'] +['ĠP', 'R'] +['.F', 'ile'] +['ĠDown', 'load'] +['Lo', 'ading'] +['d', 'i'] +['Ġwait', 'ing'] +['_A', 'DD'] +['T', 'ab'] +['.query', 'Selector'] +['Ġecon', 'omy'] +['ĠF', 'rench'] +['t', 'xt'] +['Ġf', 'ant'] +['_', ';Ċ'] +['H', 'older'] +['S', 'H'] +['Ġn', 'umpy'] +['Ġst', 'reet'] +['Ġm', 'ale'] +['\\', 'Model'] +['ang', 'ing'] +['ĠB', 'ill'] +['Ġprevious', 'ly'] +['B', 'I'] +['ĠSec', 'ret'] +['Ġm', 'ist'] +['ĠF', 'ield'] +['up', 's'] +['ĠPro', 'cess'] +['Ġke', 'pt'] +['ĠO', 'T'] +['Ġtrad', 'itional'] +['.', 'i'] +['am', 'in'] +['Ġhelp', 's'] +['An', 'y'] +['orig', 'in'] +['ilt', 'ers'] +['j', 'u'] +['d', 'esc'] +['ĠA', 'ccount'] +['Ġ)', 'čĊ'] +['k', 'top'] +['ol', 'ly'] +['Ġf', 's'] +['Ġ', 'ê'] +['Ġ', 'ut'] +['Ġcent', 'ral'] +['(t', 'est'] +['.A', 'n'] +['Ġs', 'atisf'] +['G', 'R'] +['ĠF', 'ull'] +['Ġhe', 'at'] +['ib', 'er'] +['Ġon', 'to'] +['m', 'os'] +['S', 'chema'] +['Ġfact', 'ory'] +['"', '.$'] +['aw', 's'] +['St', 'atement'] +['(t', 'arget'] +['ĉ', 'new'] +['.b', 'e'] +['Ġg', 'uest'] +['Ġm', 'al'] +['AR', 'Y'] +['Ġre', 'ached'] +['Ġm', 'ouse'] +['Ġchall', 'enge'] +['ĉd', 'ouble'] +['ĠT', 'em'] +['Ġt', 'error'] +['Ġex', 'tract'] +['_T', 'O'] +['Ġsepar', 'ate'] +['Ġm', 'ir'] +['h', 'elp'] +['Ġcap', 'acity'] +['ĠProp', 'erty'] +['k', 'an'] +['_c', 'reate'] +['ĠL', 'ight'] +['.p', 'arent'] +['Ġunderstand', 'ing'] +['Ġeas', 'ier'] +['Ġ|', '='] +['Ġen', 'h'] +['Ġf', 'at'] +['Ġprot', 'est'] +['am', 'm'] +['_', 'AT'] +['-', 'of'] +['il', 's'] +['ĠO', 'h'] +['Ġps', 'ych'] +['Ġ$', '.'] +['ind', 's'] +['Ġrel', 'ative'] +['sh', 'op'] +['sh', 'ort'] +['ĠS', 'and'] +['uest', 'ion'] +['Ġf', 'ear'] +['/', 'ĊĊ'] +['.', 'context'] +['Ġschool', 's'] +['Ġser', 've'] +['z', 'one'] +['_d', 'b'] +['Ġmajor', 'ity'] +['ex', 'ample'] +['Ġl', 'ang'] +['ĉ', 'ĠĠ'] +['Reg', 'ister'] +['end', 'o'] +['Ġprocess', 'ing'] +['_t', 'emplate'] +['-', 'user'] +['Ġe', 'g'] +['C', 'OM'] +['ĠBl', 'ue'] +['i', 'ro'] +['Ġrem', 'ote'] +['ĠI', 'T'] +['#!', '/'] +['Ġred', 'istrib'] +['ra', 'z'] +['ĠS', 'ince'] +['ĠT', 'ur'] +['Back', 'ground'] +['==', '='] +['Ġref', 'lect'] +['Ġpro', 's'] +['c', 'md'] +['Ġwh', 'om'] +['Com', 'pat'] +['ĠA', 're'] +['Id', 'entifier'] +['ĠTh', 'om'] +['_', 'port'] +['g', 'u'] +['Ġmon', 'itor'] +['r', 'm'] +['Ġpat', 'ient'] +['ver', 'ter'] +['Ġg', 'ain'] +['-', 'ui'] +['In', 'st'] +['Ġd', 'ies'] +['A', 'rea'] +['_f', 'ilter'] +['Ġgr', 'at'] +['Ġreal', 'ity'] +['ord', 'inate'] +['ol', 'ved'] +['Cont', 'act'] +['Ġcompl', 'iance'] +['_', 'or'] +['ĠV', 'ar'] +['d', 'l'] +['Ġapp', 'end'] +['G', 'ER'] +['(m', 'ax'] +['.re', 'nder'] +['Ġd', 'ynamic'] +['ordin', 'ates'] +['_', 'options'] +['_c', 'olumn'] +['Ġb', 'atter'] +['s', 'pace'] +['L', 'a'] +['ĠS', 'ource'] +['/b', 'in'] +['Ġd', 'os'] +['ĠBo', 'ard'] +['ĠTh', 'read'] +['ĠA', 'L'] +['(', 'config'] +['ĠM', 'er'] +['Ġm', 'iles'] +['_', 'header'] +['ETH', 'OD'] +['iz', 'z'] +['Ġbenef', 'it'] +['Ġinteg', 'r'] +['(c', 'urrent'] +['ul', 'o'] +['.', 'default'] +['ĠD', 'iv'] +['Ġt', 'on'] +['o', 'th'] +['erv', 'ation'] +['ed', 'om'] +['Ġb', 'aby'] +['ce', 'ived'] +['.t', 'op'] +['rior', 'ity'] +['ĠL', 'ocal'] +['ri', 'age'] +['Ġattack', 's'] +['Ġh', 'ospital'] +['Ġfem', 'ale'] +['ĠLog', 'in'] +['ĠFl', 'or'] +['Ġch', 'ain'] +['ash', 'ion'] +['Text', 'ure'] +['S', 'ave'] +['Ġf', 'arm'] +['.cont', 'ains'] +['.T', 'est'] +['Ġknow', 's'] +['Ġgener', 'ally'] +['ip', 'eline'] +['Ġme', 'ant'] +['enc', 'ia'] +['Ġn', 'icht'] +['Ġcont', 'ents'] +['P', 'M'] +['ched', 'ule'] +['(', 'line'] +['C', 'G'] +['j', 'ob'] +['ĠRe', 'al'] +['u', 'er'] +['f', 'irm'] +['Ġ', 'Ø'] +['et', 'ro'] +['"', '`Ċ'] +['Ġspe', 'ech'] +['Ġth', 'r'] +['fore', 'ach'] +['Ġw', 'arn'] +['ĉ', 'l'] +['Ġhe', 'avy'] +['<', 'li'] +['N', 'e'] +['Ġinvestig', 'ation'] +['M', 'ath'] +['-', 'title'] +['Ġch', 'urch'] +['Ġdes', 'pite'] +['ch', 'ain'] +['Ġwh', 'atever'] +['ar', 'ian'] +['f', 'n'] +['Ġm', 'eta'] +['}', ')ĊĊ'] +['U', 'FF'] +['Ġregard', 'ing'] +['_S', 'UCCESS'] +['m', 'es'] +['ĠInt', 'ent'] +['Ġres', 'olve'] +['pos', 's'] +['ir', 'a'] +['for', 'ce'] +['o', 'ice'] +['Ã', '¢'] +['Ġp', 'm'] +['Ġup', 'dates'] +['A', 'rr'] +['Ġ', 'Ñ'] +['test', 'ing'] +['Ġto', 'ward'] +['nt', 'ax'] +['ë', 'ĭ'] +['Ġlist', 'en'] +['Ġgo', 'als'] +['Instance', 'State'] +['D', 'r'] +['Ġr', 'are'] +['Ġtr', 'ail'] +['Ke', 'ys'] +['C', 'al'] +['C', 'ar'] +['ĠPe', 'ople'] +['ĉ', 'local'] +['class', 'es'] +['Re', 'ference'] +['.for', 'Each'] +['em', 'b'] +['act', 'iv'] +['Ġpr', 'im'] +['red', 'ict'] +['Ġr', 'ad'] +['æķ', '°'] +['.B', 'ack'] +['Ġsp', 'read'] +['Ġc', 'lock'] +['Ġv', 'ir'] +['ed', 'itor'] +['Ġeffort', 's'] +['Ġbr', 'anch'] +['Ġind', 'ust'] +['Ġmot', 'or'] +['Ġam', 'b'] +['Ġdat', 'etime'] +['Ġren', 'cont'] +['ĠChrist', 'ian'] +['ĠAmeric', 'ans'] +['f', 'ull'] +['Ġf', 'mt'] +['.m', 'ain'] +['Ġca', 'used'] +['_', 'update'] +['ĠCont', 'ent'] +['AT', 'CH'] +['Ġb', 'ath'] +['ĠE', 'ach'] +['Ġr', 'adio'] +['ach', 'ment'] +['uz', 'z'] +['Sub', 'mit'] +['Ġre', 'strict'] +['ab', 'in'] +['ĠL', 'oad'] +['Ġext', 'ension'] +['Ġess', 'ay'] +['Ġh', 'at'] +['avi', 'our'] +['to', 'Be'] +['":', '['] +['Ġoffer', 'ed'] +['Ġv', 'ill'] +['(d', 'ouble'] +['æĹ', '¥'] +['b', 'c'] +['_f', 'ree'] +['ĠM', 'iss'] +['ĠB', 'er'] +['Ġ', 'è'] +['ĠL', 'ike'] +['Ġhelp', 'ed'] +['.get', 'Name'] +['_', 'AL'] +['Ġsp', 'irit'] +['ĠAp', 'ache'] +['w', 's'] +['Ġthere', 'fore'] +['(', 'params'] +['_', 'img'] +['Ġpe', 'ace'] +['Ġinc', 'or'] +['ĠEX', 'PECT'] +['Ġmin', 'or'] +['ip', 'es'] +['ĉ', 'data'] +['select', 'or'] +['c', 'ity'] +['tr', 'ie'] +['.b', 'ase'] +['_f', 'rame'] +['Ġopen', 'ed'] +['/', 'json'] +['L', 'Y'] +['n', 'u'] +['.D', 'e'] +['t', 'f'] +['m', 'argin'] +['.P', 'arse'] +['Ġp', 'i'] +['Ġe', 'q'] +['b', 'd'] +['Field', 's'] +['ĠT', 'ree'] +['Ġb', 'an'] +['ist', 'an'] +['Ċ', 'ĠĠĠĠĠĠĠĠĊ'] +['ĉg', 'l'] +['Ġprodu', 'ced'] +['s', 'ystem'] +['M', 'ark'] +['_h', 'ash'] +['Ġb', 'g'] +['Ġconst', 'it'] +['ĠLe', 'ague'] +['Ġmiss', 'ion'] +['_', 'format'] +['([', 'Ċ'] +['clus', 'ion'] +['!', '"'] +['Ð', '·'] +['b', 'reak'] +['ĉs', 'witch'] +['Ġth', 'er'] +['Trans', 'form'] +['Ġfoot', 'ball'] +['-', 'link'] +['r', 'oute'] +['.', 'auth'] +['Ġb', 'ag'] +['ov', 'ers'] +['Ġen', 'abled'] +['Ġr', 'ac'] +['(', 'I'] +['C', 'R'] +['anc', 'ing'] +['Ġman', 'aged'] +['_', 'q'] +['NG', 'TH'] +['Ġm', 'ac'] +['ĠA', 'uto'] +['ament', 'e'] +["Ġ'", "',"] +['.App', 'end'] +['Ġp', 'in'] +['.', 'item'] +['ack', 'ing'] +['Ġocc', 'as'] +['p', 'erson'] +['Ġt', 'i'] +['.Re', 'g'] +['Ġh', 'aven'] +['Ġg', 'lass'] +['Ġ"', '', ')'] +['_', 'char'] +['res', 'ource'] +['Ġep', 'isode'] +["Ġ'", '_'] +['ĠE', 's'] +['ĠEar', 'th'] +['Âł', 'Âł'] +['UP', 'DATE'] +['ĠS', 'ou'] +['u', 'is'] +['t', 'ypes'] +['Ġm', 'as'] +['Ġf', 'av'] +['Ġcon', 'struct'] +['_r', 'ate'] +['er', 'as'] +['Ġ|', 'Ċ'] +['rop', 'erties'] +['Ġext', 'ernal'] +['Ġap', 'plied'] +['Ġpre', 'fix'] +['ot', 'ed'] +['l', 'ers'] +['Ġc', 'old'] +['ĠS', 'P'] +['ĠCh', 'urch'] +['ĠOut', 'put'] +['los', 'ed'] +['ç', 'ļ'] +['ific', 'ate'] +['oper', 'ation'] +['her', 'it'] +['x', 'FF'] +['.', 'env'] +['_', 'err'] +['os', 'h'] +['D', 'irection'] +['C', 'ancel'] +['ĠFr', 'ank'] +['Ġfind', 'ing'] +['.', ')ĊĊ'] +['Ġr', 'outer'] +['ãĥ', '»'] +['s', 'es'] +['Ġc', 'row'] +['==', "'"] +['Ġs', 'and'] +['Ġr', 'id'] +['it', 'ure'] +['Ġent', 're'] +['Ġo', 'bserv'] +['Ġv', 'ac'] +['ð', 'Ł'] +['-', 'T'] +['A', 'rt'] +['n', 'ight'] +['.', 'search'] +['Ġex', 'change'] +['Ġdistr', 'ict'] +['.', 'os'] +['Ġdep', 'artment'] +['Ġdoc', 'uments'] +['Ġcent', 'ury'] +['ĠN', 'ext'] +['H', 'ost'] +['ĠK', 'IND'] +['Ġsus', 'p'] +['-', 'P'] +['re', 'nd'] +['.', 'em'] +['u', 'ite'] +['ist', 'ers'] +['(', 'json'] +['ĠAn', 'n'] +['w', 't'] +['at', 'i'] +['ĠHT', 'ML'] +['wh', 'en'] +['D', 'irectory'] +['Ġsh', 'ut'] +['<', 'a'] +['ed', 'y'] +['Ġhealth', 'y'] +['Ġtemper', 'ature'] +['ĠG', 'en'] +['Ġmet', 'al'] +['Ġsub', 'mit'] +['ĠD', 'O'] +['Ġat', 'tract'] +['Ġ{', '};Ċ'] +['ĠW', 'ord'] +['Ġl', 'l'] +['Ġseem', 'ed'] +['k', 'o'] +['I', 'ED'] +['Ġl', 'abor'] +['.Cont', 'ext'] +['Ġas', 'set'] +['y', 'ou'] +['Ġc', 'ars'] +['ĠC', 'olumn'] +['Ġr', 'é'] +['Ġs', 'quare'] +['ĠNS', 'String'] +['âĢĿ', ','] +['ap', 'es'] +['..', '.Ċ'] +['Ġthan', 'ks'] +['(', 'props'] +['Ġt', 'ick'] +['Ġexper', 'iment'] +['Ġpr', 'ison'] +['t', 'ree'] +['-', 'text'] +['ĠIO', 'Exception'] +['-w', 'idth'] +['_ST', 'ATUS'] +['f', 'ast'] +['-b', 'ody'] +['-', 'header'] +['Ġgu', 'ar'] +['cre', 'te'] +['ĠT', 'im'] +['Ġclear', 'ly'] +['ĠRepublic', 'an'] +['Ġjust', 'ify'] +['и', 'ÑĤ'] +['ĉ', 'ĠĠĠĠ'] +['c', 'ache'] +[';', '//'] +['Ġpres', 'ence'] +['Ġfact', 'ors'] +['Ġemploy', 'ee'] +[']', '))'] +['M', 'ember'] +['Ġselect', 'or'] +['b', 'or'] +['ĠM', 'ex'] +['çļ', 'Ħ'] +['ut', 'ex'] +['_t', 'ag'] +['ail', 'ure'] +['ĠN', 'et'] +['Ġre', 'li'] +['E', 'G'] +['Ġf', 'printf'] +['Ġte', 'en'] +['lo', 'ss'] +['Ġle', 'aving'] +['De', 'legate'] +['Ġbe', 'at'] +['Ġmin', 'ute'] +['sub', 'scribe'] +['Ġredistrib', 'ute'] +['Con', 'stants'] +['Ġcan', 'cer'] +['/', '{'] +['B', 'L'] +['Ġs', 'pan'] +['ĠCh', 'ild'] +['C', 'enter'] +['Ġear', 'th'] +['Y', 'S'] +['ĠLe', 'vel'] +['Ġse', 'a'] +['.s', 'upport'] +['.in', 'ner'] +['.', 'Item'] +['ill', 'ing'] +['ĠĠĠĠĊ', 'ĠĠĠĠĊ'] +['ĠL', 'abel'] +['ĠE', 'st'] +['(', 'arg'] +['bo', 'Box'] +['ĉf', 'oreach'] +['c', 'os'] +['F', 'ailed'] +['sw', 'ers'] +['Ed', 'itor'] +['r', 'ont'] +['ĠM', 'P'] +['ex', 'pr'] +['ĠL', 'ife'] +['Ġ?', '?'] +['ö', 'r'] +['Ġatt', 'end'] +['ĠQ', 'ue'] +['Ġspec', 'ies'] +['-', 'D'] +['Ġa', 'us'] +['Str', 'uct'] +['Ġadvant', 'age'] +['ost', 'on'] +['-b', 'lock'] +['in', 'itial'] +['C', 'RE'] +['Ġtr', 'uly'] +['Ġcomp', 'are'] +['or', 'ney'] +['Ġs', 'pect'] +['F', 'ull'] +['b', 'es'] +['Ġvis', 'ible'] +['Ġm', 'ess'] +['st', 'ances'] +['Ġcl', 'oud'] +['_v', 'ersion'] +['Ġf', 'urn'] +['ic', 'ago'] +['LO', 'W'] +['Ġtraff', 'ic'] +['Ġf', 'ol'] +['rypt', 'o'] +['Ġdecl', 'ar'] +['Ġsl', 'ot'] +['ĠEx', 't'] +['ĠEng', 'land'] +['ĠU', 'nder'] +['Ġt', 'a'] +['let', 'ter'] +['Ġoffic', 'er'] +['ĠDon', 'ald'] +['Y', 'es'] +['_', 'json'] +['IT', 'ableView'] +['ĠU', 'SE'] +['mploy', 'ee'] +['Ġopin', 'ion'] +['ĠA', 'ut'] +['b', 'order'] +['Ġad', 'vice'] +['Ġautom', 'atically'] +['is', 'co'] +['Ġm', 'm'] +['.', 'vis'] +['am', 'l'] +['Ġinitial', 'ize'] +['Ġ(', '{'] +['Ġ', ';ĊĊ'] +['Ġgener', 'ation'] +['Ġb', 'its'] +['clip', 'se'] +['Ġun', 'f'] +['ut', 'ors'] +['pl', 't'] +['Ġdel', 'ta'] +['est', 'roy'] +['is', 'is'] +['<', 'br'] +['Ġlimit', 'ations'] +['Ġend', 'ed'] +['ĠM', 'ad'] +['il', 'm'] +['Th', 'ese'] +['ĠMin', 'ister'] +['Ġch', 'art'] +['F', 'ragment'] +['Ġindepend', 'ent'] +['Y', 'ear'] +['Ġin', 'str'] +['Ġt', 'ags'] +['A', 'VE'] +['ĠAr', 'ch'] +['st', 'op'] +['Pro', 'gress'] +['Ġm', 'i'] +['Ġlearn', 'ed'] +['G', 'e'] +['Ġhot', 'el'] +['S', 'M'] +['T', 'YPE'] +['Ġc', 'y'] +['ERS', 'ION'] +['un', 'ately'] +['l', 'imit'] +['s', 'el'] +['Ġmov', 'ies'] +['Ġste', 'el'] +['o', 'z'] +['g', 'b'] +['ĠC', 'amp'] +['s', 'ite'] +['ĠLog', 'ger'] +['P', 'LE'] +['оÐ', '´'] +['.', 'right'] +['ĠC', 'ore'] +['Ġm', 'ixed'] +['st', 'ep'] +['Ġput', 's'] +['s', 'uper'] +['R', 'outer'] +['.', 'Http'] +['ly', 'ph'] +['ĠColor', 's'] +['Ġandroid', 'x'] +['.', 'str'] +['Ġinn', 'ov'] +['Ġde', 'ck'] +["'", '>Ċ'] +['ap', 'ers'] +[']', '('] +['cont', 'inue'] +['s', 'pec'] +['ĠR', 'oad'] +['AS', 'H'] +['ili', 'ar'] +['Ġcontin', 'ues'] +['Ġapp', 'oint'] +['Ġ#', 'Ċ'] +['ĠV', 'ir'] +['Ġ?>', '"'] +['Ġb', 'in'] +['}', '",'] +['go', 'ing'] +['e', 'ach'] +['B', 'D'] +['ĠA', 'ccess'] +['D', 'oc'] +['ĠMan', 'agement'] +['B', 'ER'] +['ask', 'et'] +['.get', 'Instance'] +['Ġestablish', 'ed'] +['so', 'cket'] +['IN', 'S'] +['ĉv', 'irtual'] +['ĉ', 'result'] +['RE', 'AD'] +['_', 'height'] +['ĠF', 'ont'] +['Ġ(', ');Ċ'] +['_', 'html'] +['Ġneighb', 'or'] +['l', 'or'] +['Ġg', 'ather'] +['Ġ}', ')ĊĊ'] +['Ġid', 'entity'] +['Ġf', 'ab'] +['p', 'adding'] +['ĠR', 'oute'] +['Enumer', 'able'] +['Ã', '´'] +['Ġfor', 'ced'] +['/j', 'query'] +['.ĊĊ', 'ĊĊĊĊ'] +['res', 'ents'] +['_', 'left'] +['.P', 'aram'] +['ĉ', 'throw'] +['ĠH', 'am'] +['Ġevent', 'ually'] +['ac', 'er'] +['p', 'ub'] +['Ġtr', 'a'] +['un', 'ique'] +['d', 'el'] +['ĠFlor', 'ida'] +['ĠC', 'lean'] +['x', 'a'] +['ĠÂ', '·'] +['Ġvalid', 'ate'] +['Vis', 'ual'] +['Ex', 'pression'] +['_f', 'unc'] +['m', 'ember'] +['ĉ', 'h'] +['tr', 'l'] +['ĉ', 'G'] +['nap', 'shot'] +['ĠProp', 'Types'] +['v', 'in'] +[']', ')ĊĊ'] +['ow', 'l'] +['if', 'ies'] +['Ġ$', "('."] +['ĠCont', 'ext'] +['ĠTo', 'ast'] +['.', 'Key'] +['Ġoffic', 'ers'] +['/', 'n'] +['s', 'n'] +['und', 'efined'] +['.', 'items'] +['ut', 'ow'] +['am', 'age'] +['Ġaccount', 's'] +['ook', 'ie'] +['Se', 'ction'] +['ici', 'ans'] +['Ġad', 'vis'] +['(', 'is'] +['[:', ','] +['ĠFr', 'ance'] +['F', 'unc'] +['ic', 'ious'] +['Ġto', 'k'] +['Ch', 'annel'] +['ĠA', 'D'] +['_N', 'UM'] +['Ġtime', 'out'] +['lem', 'ma'] +['rem', 'e'] +['u', 'j'] +['.A', 'l'] +['uc', 'lear'] +['(', 'os'] +['("', '<'] +['[', 'Ċ'] +['f', 'etch'] +['Ġb', 'al'] +['Ġgu', 'id'] +['-', 'align'] +['ĠW', 'rite'] +['ĠOn', 'ce'] +['utow', 'ired'] +['OD', 'ULE'] +['Ġp', 'itch'] +['C', 'F'] +['by', 'tes'] +['ĠCom', 'mission'] +['Ġincre', 'd'] +['P', 'ER'] +['_', 'response'] +['ĠL', 'os'] +['par', 'ser'] +['Ġass', 'ume'] +['.', 'Request'] +['ĠT', 'oken'] +['_p', 'osition'] +['Ġn', 'om'] +['-', 'term'] +['Ġrem', 'aining'] +['i', 'ostream'] +['Ġpie', 'ces'] +['ap', 'y'] +['ĠL', 'ess'] +['r', 'ange'] +['umb', 'n'] +['pr', 'ise'] +['_', 'option'] +['Im', 'pl'] +['k', 'wargs'] +['Ġbusiness', 'es'] +['Al', 'ert'] +['Ġpart', 'ies'] +['ĠCont', 'ainer'] +['ĠPr', 'ivate'] +['ĠPl', 'an'] +['Ġregister', 'ed'] +['Ġj', 'our'] +['ack', 'er'] +['ен', 'и'] +['/', '>'] +['ch', 'at'] +['se', 'ct'] +['Ġcre', 'ation'] +['olut', 'ely'] +['Ġinst', 'ant'] +['Ġdel', 'ivery'] +['ick', 'en'] +['y', 'es'] +['ĠFr', 'anc'] +['bl', 'ing'] +['end', 'a'] +['[', '('] +['_r', 'ange'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠ'] +['Ġsched', 'ule'] +['Con', 'n'] +['Ġthan', 'k'] +['x', 'd'] +['Ġh', 'ook'] +['Ġdocument', 'ation'] +['Param', 'eters'] +['H', 'ello'] +['v', 't'] +['Ġart', 'icles'] +['Ġw', 'est'] +['def', 'ined'] +['.', 'select'] +['ok', 'ens'] +['ĠV', 'AL'] +['.f', 'ile'] +['res', 'et'] +['Ġmy', 's'] +['ĠM', 'A'] +[']', '),'] +['Ġc', 'ities'] +['rel', 'ated'] +['å', 'Ľ'] +['Ġappe', 'ared'] +['Ġw', 'id'] +['.p', 'anel'] +['ĠIn', 's'] +['.', 'entity'] +['Ġde', 'cre'] +['ĠL', 'ou'] +['(t', 'ime'] +['ĠTh', 'ank'] +['.create', 'Element'] +['Ġmention', 'ed'] +['oun', 'ce'] +['ĠT', 'ry'] +['ĠW', 'all'] +['/', 'images'] +['ĠM', 'enu'] +["'", 'čĊ'] +['ĠE', 'r'] +['Ġcrit', 'ic'] +['ĠY', 'ear'] +['(', 'param'] +['Ġf', 'lo'] +['N', 'N'] +['oot', 'er'] +['Ġ', '];Ċ'] +['ĠA', 'ff'] +['"', 'github'] +['room', 's'] +['Ġh', 'yp'] +['g', 'lobal'] +['Ġa', 'vec'] +['æľ', 'Ī'] +['Ġcomplet', 'ion'] +['Ġcon', 'd'] +['onym', 'ous'] +['(', 'temp'] +['Ġst', 'ars'] +['Ġre', 'levant'] +['Ġcover', 'ed'] +['Ġel', 'im'] +['_t', 'ypes'] +['(', 'bool'] +['Ġt', 'u'] +['_ex', 'ists'] +['Ġsec', 'ure'] +['Ġst', 'ored'] +[']', '/'] +['x', 'F'] +['ĠCont', 'roller'] +['Ġm', 'igr'] +['M', 'I'] +['ĠD', 'en'] +['Ġann', 'ual'] +['U', 'IL'] +['-', 'and'] +['Ġcr', 'ime'] +['b', 'el'] +['Ġk', 'itchen'] +['@', 'g'] +['_p', 'h'] +['ourn', 'ament'] +['ĠS', 'ocial'] +['ĠS', 'pecial'] +['log', 'ger'] +['Ġt', 'ail'] +['Ġun', 'known'] +['d', 'ed'] +['Ġapp', 'rec'] +['(d', 'b'] +['c', 'f'] +['Ġass', 'ign'] +['-', 'out'] +['ĠM', 'ont'] +['d', 'p'] +['w', 'idget'] +['Ġst', 'one'] +['-', 'primary'] +['.', 'grid'] +['Result', 's'] +['az', 'z'] +['Ġda', 'ughter'] +['Ġcur', 'r'] +['Ġl', 'in'] +['Ġs', 'outh'] +['form', 's'] +['ĠO', 'UT'] +['let', 'te'] +['ak', 's'] +['ig', 'ure'] +['ĠE', 'U'] +['var', 'iable'] +['Ġb', 'rief'] +['ĠSc', 'ott'] +['Ġcon', 'ference'] +['and', 'a'] +['_', 'lock'] +['or', 'al'] +['Ġe', 'ine'] +['OR', 'S'] +['////////////////////////////////', '////////////////////////////////'] +['ess', 'o'] +['Ġr', 'is'] +['Ġg', 'ender'] +['est', 'ic'] +['L', 'icense'] +['(', 'out'] +['Ġm', 's'] +['Se', 'e'] +['Ġwill', 'ing'] +['az', 'e'] +['Ġs', 'ports'] +['Ġy', 'es'] +['l', 'u'] +['Ġp', 'urs'] +['/j', 'avascript'] +['-', 'pro'] +['nav', 'bar'] +['_pro', 'duct'] +['/', 'bootstrap'] +['Ġdr', 'iving'] +['Ġ', 'Ä'] +['Ġpro', 'pos'] +['ult', 'ip'] +['up', 'lic'] +['.', 'email'] +['Ġappro', 'x'] +['(', 'cl'] +['Ġwe', 'ar'] +['Ġrep', 'ly'] +['ass', 'et'] +['Ġ', 'ice'] +['Ġt', 'x'] +['k', 'r'] +['ĠGerman', 'y'] +['ĠGe', 'orge'] +['Ġc', 'b'] +['ĉ', 'err'] +['M', 'ove'] +['Ġpol', 'y'] +['vo', 'ice'] +['}', '"'] +['Ġan', 'imal'] +['A', 'v'] +['ĠL', 'ocation'] +['Ġn', 'ative'] +[']', '["'] +['<', 'double'] +['Ġm', 'ais'] +[',', 'int'] +['Ġpre', 'par'] +['Ġinter', 'val'] +['plement', 'ation'] +['_', 'ERR'] +['Ġb', 'ug'] +['>', '"'] +['st', 'at'] +['Ġ}', ',čĊ'] +['<', 'span'] +['Ġfa', 'ith'] +['Ġ', 'rom'] +['pre', 'v'] +['ĠE', 'lect'] +['F', 'ind'] +['Ġg', 'od'] +['ot', 'or'] +['//', '----------------------------------------------------------------'] +['orig', 'inal'] +['C', 'pp'] +['ĠSen', 'ate'] +['Ġposition', 's'] +['Ġweap', 'ons'] +['Ġco', 'ff'] +['Ġpur', 'poses'] +['p', 'ol'] +['Ġim', 'press'] +['Ġanim', 'als'] +['.', 'Entity'] +['(n', 'p'] +['Ġmur', 'der'] +['Ġ`', '`'] +['fl', 'ag'] +['Ġsol', 'utions'] +['ĠAct', 'ive'] +['Ġb', 'right'] +['.d', 'ate'] +['Ġsit', 'u'] +['ï¼', 'Ī'] +['.', 'ID'] +['Ġs', 'ie'] +['),', 'čĊ'] +['ak', 't'] +['S', 'pace'] +['.d', 'at'] +['.index', 'Of'] +['h', 'an'] +['az', 'ine'] +['ĠZ', 'e'] +['Ġcr', 'ash'] +['(', '/'] +['>', '='] +['Ð', '±'] +['iv', 'a'] +['.Auto', 'Size'] +['ĠL', 'at'] +['_', 'ext'] +['Initial', 'ize'] +['.reg', 'ister'] +['OP', 'Y'] +['Ġre', 'verse'] +['_d', 'is'] +["']", '['] +['Ġprom', 'pt'] +['ont', 'o'] +['ĠJ', 'ournal'] +['r', 'outer'] +['Ġmys', 'qli'] +['#', 'else'] +[')', '"'] +['-x', 's'] +['let', 's'] +['ph', 'an'] +['.', 'LE'] +['W', 'ill'] +['Ġaff', 'ord'] +['Ġsk', 'ill'] +['-t', 'oggle'] +['N', 'C'] +['B', 'ind'] +['T', 'S'] +['J', 'ust'] +['iter', 'al'] +['Y', 'P'] +['ĉ', 'unsigned'] +['Ġw', 'ind'] +['))', ':Ċ'] +['Ġw', 'arning'] +['ĠW', 'ater'] +['Ġd', 'raft'] +['Ġc', 'm'] +['Ġs', 'am'] +['Ġhold', 'ing'] +['z', 'ip'] +['ĠSc', 'ience'] +['Ġsup', 'posed'] +['G', 'en'] +['Ġdi', 'et'] +['<', 'h'] +['ĠP', 'ass'] +['v', 'i'] +['Ġhus', 'band'] +['�', '�'] +['n', 'ote'] +['ĠAb', 'out'] +['ĠIn', 'stitute'] +['Ġcl', 'imate'] +['.Form', 'at'] +['Ġn', 'ut'] +['est', 'ed'] +['Ġapp', 'arent'] +['Ġhold', 's'] +['f', 'i'] +['new', 's'] +['C', 'M'] +['v', 'ideo'] +["':", "'"] +['D', 'ITION'] +['p', 'ing'] +['Ġsen', 'ior'] +['w', 'a'] +['--', '>Ċ'] +['_', 'default'] +['ĠD', 'atabase'] +['re', 'p'] +['E', 'SS'] +['ner', 'gy'] +['.F', 'ind'] +['_m', 'ask'] +['Ġr', 'ise'] +['Ġk', 'ernel'] +['::', '$'] +['.', 'Q'] +['Ġoffer', 'ing'] +['de', 'cl'] +['ĠC', 'S'] +['Ġlist', 'ed'] +['Ġmost', 'ly'] +['eng', 'er'] +['Ġblock', 's'] +['ol', 'o'] +['Ġgover', 'ning'] +['\\', 'F'] +['Ġcon', 'cent'] +['.get', 'Text'] +['Ġm', 'b'] +['Ġocc', 'urred'] +['Ġchang', 'ing'] +['Sc', 'ene'] +['_C', 'ODE'] +['B', 'eh'] +['"', 'The'] +['Ġt', 'ile'] +['ĠAssoci', 'ation'] +['ĉ', 'P'] +['al', 'ty'] +['_', 'ad'] +['od', 'ies'] +['i', 'ated'] +['Ġpre', 'pared'] +['poss', 'ible'] +['Ġm', 'ort'] +['TE', 'ST'] +['Ġign', 'ore'] +['Ġcal', 'c'] +['Ġr', 's'] +['Ġassert', 'Equals'] +['Ġs', 'z'] +['ĠTH', 'IS'] +['.', '"Ċ'] +['Ġcan', 'vas'] +['j', 'ava'] +['Ġd', 'ut'] +['VAL', 'ID'] +['.s', 'ql'] +['.', 'input'] +['Ġa', 'ux'] +['S', 'up'] +['Ġart', 'ist'] +['V', 'ec'] +['_T', 'IME'] +['.string', 'ify'] +['et', 'ween'] +['ĠC', 'ategory'] +['Ġ[', '-'] +['ĠDev', 'Express'] +['ĠJ', 'ul'] +['Ġr', 'ing'] +['.', 'ed'] +['Y', 'Y'] +['L', 'et'] +['Text', 'Field'] +['Ġfl', 'at'] +['_p', 'rint'] +['ĠOT', 'HER'] +['ad', 'ian'] +['Ġcheck', 'ed'] +['e', 'le'] +['Al', 'ign'] +['stand', 'ing'] +['Ġ[', '],'] +['Ġl', 'ab'] +['uck', 'y'] +['ĠChrist', 'mas'] +['(', 'image'] +['.m', 'odule'] +['Ġl', 'ots'] +['Ġslight', 'ly'] +['(f', 'inal'] +['er', 'ge'] +['è', '¿'] +['ĠPol', 'ice'] +['ĠR', 'ight'] +['Ġaw', 'ard'] +['ĠO', 'S'] +['Ġ{', '}ĊĊ'] +['Ġp', 'tr'] +['ov', 'es'] +['ic', 'ated'] +['еÐ', '¼'] +['Ġman', 'age'] +['olid', 'ay'] +['Am', 'ount'] +['ool', 'Strip'] +['t', 'body'] +['N', 'av'] +['w', 'rap'] +['B', 'B'] +['Ġwatch', 'ing'] +['ari', 'os'] +['Ġoption', 'al'] +['_', 'K'] +['ĠL', 'icensed'] +['.M', 'ap'] +['T', 'imer'] +['ĠA', 'P'] +['ĠRe', 'v'] +['(', 'o'] +[',', 'c'] +['um', 'in'] +['eta', 'iled'] +['ĠH', 'y'] +['Ġbl', 'ank'] +['ag', 'ger'] +['ĠS', 'elf'] +['()', '['] +['.m', 'ake'] +['ear', 'n'] +['ch', 'annel'] +['<', 'pre'] +['ble', 'm'] +['_p', 'assword'] +['_s', 'p'] +['ic', 'ing'] +['e', 'z'] +['Ġthe', 'ory'] +['ĠT', 'er'] +[',', 'n'] +['log', 'o'] +['ĠHT', 'TP'] +['()', '))'] +['.h', 'andle'] +['>', ';Ċ'] +['W', 'orld'] +['Ġpy', 'thon'] +['Ġl', 'if'] +['Ġtr', 'av'] +['Ġcon', 'ven'] +['com', 'pany'] +['ĠCl', 'ub'] +['V', 'er'] +['B', 'tn'] +['Ġz', 'one'] +['product', 's'] +['ĠE', 'duc'] +['Ġver', 'ify'] +['ĠM', 'il'] +['on', 'o'] +[']', ');ĊĊ'] +['EN', 'CE'] +['Ġpack', 'et'] +['Ġc', 'er'] +['Ġen', 'umer'] +['Ġpar', 's'] +['form', 'ed'] +['Ġocc', 'up'] +['t', 're'] +['Ġexerc', 'ise'] +['D', 'ay'] +['_s', 'um'] +['Ġask', 'ing'] +['apt', 'ion'] +['Ġord', 'ers'] +['Ġsp', 'ending'] +['ĠE', 'RR'] +['.D', 'is'] +['ĠU', 'til'] +['âĢľ', 'I'] +['\\', "'"] +['?', ')'] +['/', '>Ċ'] +['Ġem', 'ot'] +['Ġinflu', 'ence'] +['ĠAfr', 'ica'] +['att', 'ers'] +['Ù', 'ħ'] +['.s', 'ession'] +['Ġch', 'ief'] +['ĉĉĉĉĉĉĉĉ', 'ĉĉĉ'] +['Ġto', 'm'] +['clud', 'ed'] +['ser', 'ial'] +['_h', 'andler'] +['.T', 'ype'] +['ap', 'ed'] +['Ġpolic', 'ies'] +['-', 'ex'] +['-', 'tr'] +['bl', 'ank'] +['mer', 'ce'] +['Ġcover', 'age'] +['Ġr', 'c'] +['_m', 'atrix'] +['_', 'box'] +['Ġcharg', 'es'] +['ĠB', 'oston'] +['P', 'e'] +['Ġcirc', 'um'] +['Ġfil', 'led'] +['Ġn', 'orth'] +['icture', 'Box'] +['ĉ', 'res'] +['è', '®'] +['Ġter', 'min'] +['Ġ[', 'â̦'] +['IRE', 'CT'] +['Ġb', 'er'] +['Ġ"', '../../'] +['ret', 'ch'] +['.c', 'ode'] +['_c', 'ol'] +['ĠGovern', 'ment'] +['Ġarg', 'v'] +['ĠL', 'ord'] +['as', 'i'] +['Ex', 'ec'] +['ĉ', 'let'] +['vert', 'is'] +['Ġdiscuss', 'ion'] +['en', 'ance'] +['out', 'ube'] +['type', 'of'] +['Ġs', 'erved'] +['ĠP', 'ut'] +['ĉ', 'x'] +['Ġs', 'weet'] +['B', 'efore'] +['ateg', 'y'] +['.', 'of'] +['ĠM', 'aterial'] +['S', 'ort'] +['ON', 'T'] +['ig', 'ital'] +['Wh', 'y'] +['Ġs', 'ust'] +['Ġ', 'ç'] +['ab', 'et'] +['Ġseg', 'ment'] +['Ġ[', '],Ċ'] +['ĠMus', 'lim'] +['Ġfind', 'ViewById'] +['c', 'ut'] +['_T', 'EXT'] +['ĠM', 'ary'] +['Ġlo', 'ved'] +['Ġl', 'ie'] +['ĠJ', 'O'] +['Ġis', 'set'] +['mon', 'th'] +['Ġpr', 'ime'] +['t', 'i'] +['ĠCar', 'ol'] +['U', 'se'] +['ĠP', 'op'] +['ĠS', 'ave'] +['Int', 'erval'] +['ex', 'ecute'] +['d', 'y'] +['ĠI', 'ran'] +['_', 'cont'] +['ĉ', 'T'] +['Ġph', 'ase'] +['check', 'box'] +['we', 'ek'] +['Ġh', 'ide'] +['Ġt', 'il'] +['Ġj', 'u'] +['C', 'ustom'] +['b', 'urg'] +['/', 'M'] +['T', 'ON'] +['Ġqu', 'ant'] +['Ġr', 'ub'] +['ix', 'els'] +['Ġinst', 'alled'] +['Ġd', 'ump'] +['Ġproper', 'ly'] +['(', 'List'] +['Ġdec', 'ide'] +['app', 'ly'] +['H', 'as'] +['Ġkeep', 'ing'] +['Ġcitiz', 'ens'] +['Ġj', 'oint'] +['p', 'ool'] +['S', 'ocket'] +['_', 'op'] +['Ġweap', 'on'] +['gn', 'ore'] +['ĠEx', 'ec'] +['ott', 'en'] +['ĠM', 'S'] +['Ġ(', '-'] +['ĠRe', 'view'] +['Ġex', 'amples'] +['Ġt', 'ight'] +['!', '('] +['D', 'P'] +['ĠMessage', 'Box'] +['Ġphot', 'ograph'] +['UR', 'I'] +['é', 't'] +['l', 'ow'] +['ĠGr', 'and'] +['.p', 'ersistence'] +['Ġmaint', 'ain'] +['Ġnum', 's'] +['Ġz', 'ip'] +['ial', 's'] +['ĠG', 'ets'] +['pe', 'g'] +['ĠB', 'uffer'] +['~~', '~~'] +['ra', 'structure'] +['ĠP', 'L'] +['u', 'en'] +['ob', 'by'] +['size', 'of'] +['Ġp', 'ic'] +['Ġse', 'ed'] +['Ġexperi', 'enced'] +['Ġo', 'dd'] +['Ġk', 'ick'] +['Ġproced', 'ure'] +['avig', 'ator'] +['-', 'on'] +[',', 'j'] +['ĠAl', 'though'] +['Ġuser', 'Id'] +['ac', 'cept'] +['Bl', 'ue'] +['IC', 'olor'] +['l', 'ayer'] +['av', 'ailable'] +['Ġend', 's'] +['.t', 'able'] +['Ġdat', 'aset'] +['b', 'us'] +['Ġexpl', 'ain'] +['(', 'pro'] +['ĠCommit', 'tee'] +['Ġnot', 'ed'] +[']', ':Ċ'] +['D', 'im'] +['std', 'io'] +['.', '",Ċ'] +['_s', 'ource'] +['ĠWe', 'ek'] +['ĠEd', 'ge'] +['Ġoper', 'ating'] +['Ġest', 'e'] +['i', 'pl'] +['ag', 'ination'] +['Ġpro', 'ceed'] +['Ġanim', 'ation'] +['.Model', 's'] +['ĠW', 'atch'] +['i', 'at'] +['Ġopp', 'on'] +['/', 'A'] +['Re', 'port'] +['Ġs', 'ounds'] +['_b', 'uf'] +['IEL', 'D'] +['Ġbu', 'nd'] +['ĉ', 'get'] +['.p', 'r'] +['(t', 'mp'] +['Ġk', 'id'] +['>ĊĊ', 'Ċ'] +['Ġy', 'ang'] +['Not', 'Found'] +['Ñ', 'Ĩ'] +['m', 'ath'] +['@g', 'mail'] +['ĠL', 'IMIT'] +['red', 'ients'] +['Ġv', 'ent'] +['avig', 'ate'] +['L', 'ook'] +['Ġrelig', 'ious'] +['Ġr', 'and'] +['ri', 'o'] +['(', 'GL'] +['_', 'ip'] +['u', 'an'] +['ici', 'ency'] +['ĠCh', 'ange'] +['>', 'čĊčĊ'] +['ĠEnt', 'ity'] +['Ġrencont', 're'] +['ĠR', 'et'] +['pl', 'an'] +['é', 'n'] +['BO', 'OL'] +['ur', 'ies'] +['tr', 'ain'] +['Def', 'inition'] +['========', '===='] +['z', 'z'] +['An', 'imation'] +['ĠO', 'K'] +['_m', 'enu'] +['.b', 'l'] +['_s', 'core'] +['Ġac', 'ad'] +['(', 'System'] +['Ġref', 'resh'] +["'=>", '$'] +['.G', 'raphics'] +['ament', 'o'] +['p', 'id'] +['t', 'c'] +['Ġt', 'ips'] +['Ġhom', 'es'] +['Ġf', 'uel'] +['â', 'ĸ'] +['_h', 'elper'] +['ĠĠ', 'čĊ'] +['ĠR', 'oom'] +['.C', 'lose'] +['_', 'attr'] +['ĠM', 'ount'] +['ĠE', 'v'] +['ar', 'ser'] +['_t', 'op'] +['e', 'ah'] +['ĠDe', 'lete'] +['ãĢ', 'į'] +['u', 'ke'] +['Ġus', 'age'] +['ar', 'ia'] +['_de', 'v'] +['Ġtext', 'ure'] +['Ġconvers', 'ation'] +['e', 'per'] +['Be', 'an'] +['d', 'one'] +['non', 'atomic'] +['ĠSe', 'cond'] +['Ġshoot', 'ing'] +['_p', 're'] +['Com', 'ponents'] +['Ġ]', 'ĊĊ'] +['__', ','] +['stit', 'ution'] +['.Ch', 'ar'] +['>', '();ĊĊ'] +['Ġpresent', 'ed'] +['Ġw', 'a'] +['ok', 'er'] +['-', 'ĊĊ'] +['in', 'er'] +['Ġbe', 'coming'] +['Ġinc', 'ident'] +['At', 't'] +['Ġreve', 'aled'] +['for', 'c'] +['Ġbo', 'ot'] +['.p', 'age'] +['Enumer', 'ator'] +['_', '->'] +['Ph', 'oto'] +['Ġs', 'pring'] +['.', '",'] +['ĠD', 'ictionary'] +['B', 'JECT'] +['Ġloc', 'ations'] +['Ġs', 'amples'] +['Input', 'Stream'] +['ĠB', 'rown'] +['Ġst', 'ats'] +['qual', 'ity'] +['Ñ', 'ħ'] +['-d', 'is'] +['Ġhelp', 'ing'] +['Ġp', 'ed'] +['(', 'se'] +['ĠWh', 'o'] +['al', 'ian'] +['int', 'ernal'] +['Ġf', 't'] +['>', '().'] +['->', '{'] +['Ġm', 'ine'] +['Ġs', 'ector'] +['Ġg', 'ro'] +['Ġopport', 'unities'] +['ĠÃ', '¼'] +['Ġm', 'p'] +['Ġalleg', 'ed'] +['Ġdoub', 't'] +['M', 'ouse'] +['Ab', 'out'] +['_p', 'art'] +['Ġch', 'air'] +['Ġstop', 'ped'] +['lo', 'op'] +['ent', 'ities'] +['Ġapp', 's'] +['ans', 'ion'] +['Ġm', 'ental'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠ'] +['F', 'R'] +['Ġdef', 'end'] +['c', 'are'] +['Ġide', 'al'] +['/', 'api'] +['ur', 'face'] +['Ġe', 'le'] +['ul', 'ator'] +['ĠR', 'ights'] +['angu', 'ages'] +['Ġfund', 's'] +['Ġad', 'apt'] +['At', 'tributes'] +['Ġdep', 'loy'] +['opt', 's'] +['Ġvalid', 'ation'] +['Ġconcern', 's'] +['u', 'ce'] +['.n', 'um'] +['ult', 'ure'] +['il', 'a'] +['Ġc', 'up'] +['Ġp', 'ure'] +['.F', 'ore'] +['ĠHash', 'Map'] +['.value', 'Of'] +['as', 'm'] +['M', 'O'] +['Ġc', 's'] +['Ġst', 'ores'] +['Ġ', '************************************************************************'] +['Ġcommunic', 'ation'] +['m', 'em'] +['.Event', 'Handler'] +['.', 'Status'] +['_', 'right'] +['.set', 'On'] +['S', 'heet'] +['Ġident', 'ify'] +['ener', 'ated'] +['order', 'ed'] +['Ġ"', '['] +['Ġs', 'we'] +['Con', 'dition'] +['ĠA', 'ccording'] +['Ġpre', 'pare'] +['Ġro', 'b'] +['P', 'ool'] +['Ġs', 'port'] +['r', 'v'] +['ĠR', 'outer'] +['Ġaltern', 'ative'] +['(', '[]'] +['ĠCh', 'icago'] +['ip', 'her'] +['is', 'che'] +['ĠDirect', 'or'] +['k', 'l'] +['ĠW', 'il'] +['key', 's'] +['Ġmy', 'sql'] +['Ġw', 'elcome'] +['k', 'ing'] +['ĠMan', 'ager'] +['Ġca', 'ught'] +[')', '}Ċ'] +['S', 'core'] +['_P', 'R'] +['Ġsur', 'vey'] +['h', 'ab'] +['He', 'aders'] +['AD', 'ER'] +['Ġdec', 'or'] +['Ġturn', 's'] +['Ġr', 'adius'] +['err', 'upt'] +['C', 'or'] +['Ġm', 'el'] +['Ġin', 'tr'] +['(', 'q'] +['ĠA', 'C'] +['am', 'os'] +['M', 'AX'] +['ĠG', 'rid'] +['ĠJes', 'us'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠ'] +['.D', 'E'] +['Ġt', 's'] +['Ġlink', 'ed'] +['f', 'ree'] +['ĠQ', 't'] +['Ġ/**', 'čĊ'] +['Ġf', 'aster'] +['ct', 'r'] +['_', 'J'] +['D', 'T'] +['.C', 'heck'] +['Ġcomb', 'ination'] +['Ġint', 'ended'] +['-', 'the'] +['-', 'type'] +['ect', 'ors'] +['am', 'i'] +['ut', 'ing'] +['Ġum', 'a'] +['X', 'ML'] +['U', 'CT'] +['A', 'p'] +['ĠR', 'andom'] +['Ġr', 'an'] +['.s', 'ort'] +['Ġsort', 'ed'] +['.', 'Un'] +['_P', 'ER'] +['it', 'ory'] +['Ġprior', 'ity'] +['ĠG', 'al'] +['ĠO', 'ld'] +['h', 'ot'] +['ĠD', 'isplay'] +['(s', 'ub'] +['_T', 'H'] +['_', 'Y'] +['ĠC', 'are'] +['load', 'ing'] +['K', 'ind'] +['_h', 'andle'] +[',', ','] +['r', 'ase'] +['_re', 'place'] +['.add', 'EventListener'] +['ĠR', 'T'] +['Ġenter', 'ed'] +['g', 'ers'] +['Ġ', 'ich'] +['(', 'start'] +['/', 'app'] +['Ġbro', 'ther'] +['M', 'emory'] +['Out', 'let'] +['Ġ', 'utf'] +['pre', 'c'] +['Ġn', 'avigation'] +['OR', 'K'] +['Ġd', 'st'] +['D', 'etail'] +['Ġaud', 'ience'] +['Ġd', 'ur'] +['Ġcl', 'uster'] +['un', 'ched'] +['Ġ', '],'] +['Ġcomfort', 'able'] +['.', 'values'] +['ĠT', 'otal'] +['Ġsn', 'ap'] +['Ġstand', 'ards'] +['Ġperform', 'ed'] +['h', 'and'] +['("', '@'] +['å', 'Ń'] +['Ġph', 'il'] +['ib', 'r'] +['tr', 'im'] +['Ġfor', 'get'] +['Ġdo', 'ctor'] +['.Text', 'Box'] +['icon', 's'] +[',', 's'] +['ĠO', 'p'] +['S', 'm'] +['St', 'op'] +['ĉ', 'List'] +['ĉ', 'u'] +['Com', 'ment'] +['_V', 'ERSION'] +['.X', 'tra'] +['P', 'erson'] +['r', 'b'] +['LO', 'B'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĊ'] +['ĠCent', 'ral'] +['IC', 'K'] +['ra', 'q'] +['Ġput', 'ting'] +['Ġm', 'd'] +['ĠL', 'ove'] +['Pro', 'gram'] +['B', 'order'] +['o', 'or'] +['Ġallow', 'ing'] +['a', 'fter'] +['Ġent', 'ries'] +['ĠMay', 'be'] +[']', ').'] +['ĠSh', 'ort'] +[')', '\\'] +['.n', 'ow'] +['f', 'riend'] +['Ġpre', 'fer'] +['ĠG', 'PIO'] +['os', 'is'] +['ĠGame', 'Object'] +['Ġsk', 'ip'] +['Ġcompet', 'ition'] +['_m', 'atch'] +['lic', 'ations'] +['_CON', 'T'] +['.group', 'Box'] +['Ġal', 's'] +['"', 'We'] +['_e', 'q'] +['l', 'an'] +['_', 'search'] +['ĠMus', 'ic'] +['as', 'is'] +['Ġb', 'ind'] +['ĠIs', 'land'] +['r', 'um'] +['(', 'E'] +['Ġse', 'at'] +['V', 'ideo'] +['Ġa', 'ck'] +['ree', 'k'] +['={', '()'] +['Ġr', 'ating'] +['Ġrestaur', 'ant'] +['DE', 'X'] +['(b', 'uf'] +['pp', 'ing'] +['ual', 'ity'] +['Ġle', 'ague'] +['Ġfoc', 'used'] +['ap', 'on'] +['$', 'data'] +['CL', 'UD'] +['CLUD', 'ING'] +['Ġabs', 'olute'] +['(', 'query'] +['Ġtell', 's'] +['A', 'ng'] +['Ġcomm', 'unities'] +['Ġhon', 'est'] +['ok', 'ing'] +['Ġap', 'art'] +['ar', 'ity'] +['/', '$'] +['_m', 'odule'] +['ĠE', 'nc'] +['.', 'an'] +['.Con', 'fig'] +['C', 're'] +['Ġsh', 'ock'] +['ĠAr', 'ab'] +['I', 'ENT'] +['/', 're'] +['Ġre', 'trie'] +['ycl', 'er'] +['is', 'a'] +['ĠO', 'rgan'] +['.', 'graph'] +['Ġ', 'í'] +['ĠB', 'AS'] +['En', 'um'] +['Ġposs', 'ibly'] +['ÑĢ', 'аÐ'] +['ĠJapan', 'ese'] +['Ġc', 'raft'] +['ĠPl', 'ace'] +['Ġtal', 'ent'] +['Ġfund', 'ing'] +['Ġconf', 'irmed'] +['Ġc', 'ycle'] +['/', 'x'] +['G', 'E'] +['Ġhe', 'aring'] +['Ġpl', 'ants'] +['Ġm', 'outh'] +['p', 'ages'] +['or', 'ia'] +['ĠRem', 'ove'] +['_t', 'otal'] +['Ġo', 'd'] +['oll', 'apse'] +['do', 'or'] +['Ġb', 'ought'] +['Ġadd', 'r'] +['AR', 'CH'] +['_d', 'im'] +['dd', 'en'] +['Ġdec', 'ades'] +['RE', 'QUEST'] +['Ġvers', 'ions'] +['f', 'ire'] +['Ġmov', 'es'] +['f', 'b'] +['Ġcoff', 'ee'] +['.con', 'nect'] +['ĠR', 'ow'] +['Ġs', 'chema'] +['S', 'cope'] +['-', 'Type'] +['Ġfight', 'ing'] +['Ġret', 'ail'] +['Ġmod', 'ified'] +['T', 'F'] +['File', 's'] +['n', 'ie'] +['_com', 'mand'] +['st', 'one'] +['Ġ', 'ÑĤ'] +['_', 'thread'] +['Ġb', 'ond'] +['ĠDevelop', 'ment'] +['Ġp', 't'] +['F', 'ORM'] +['ple', 't'] +['Ġident', 'ified'] +['c', 'pp'] +['Ġc', 'oding'] +['ok', 'ed'] +['ĠM', 'aster'] +['ID', 'TH'] +['Ġres', 'idents'] +['red', 'it'] +['ĠPh', 'oto'] +['=', '-'] +['un', 'te'] +['ate', 'ur'] +['_ST', 'ATE'] +['ĠS', 'ing'] +['Ġshe', 'et'] +['.', 'val'] +['or', 'se'] +['Ġh', 'ers'] +['Ġdetermin', 'ed'] +['Com', 'mon'] +['Ġw', 'ed'] +['_', 'queue'] +['P', 'H'] +['ĠAt', 'l'] +['cre', 'd'] +['/L', 'ICENSE'] +['Ġm', 'es'] +['Ġadv', 'anced'] +['.j', 'ava'] +['.S', 'h'] +['G', 'o'] +['k', 'ill'] +['f', 'p'] +['_set', 'tings'] +['Ġp', 'al'] +['Ġtr', 'uck'] +['Ġcomb', 'ined'] +['Ġ"', '${'] +['ĠCor', 'por'] +['Ġjo', 'ined'] +['ĠJ', 'ose'] +['ĠC', 'up'] +['un', 's'] +['est', 'ival'] +['lev', 'ision'] +['Ġbro', 'ken'] +['Ġmar', 'riage'] +['ĠWest', 'ern'] +['Ġrep', 'resents'] +['ĠT', 'itle'] +['Ġs', 's'] +['.A', 'ss'] +['ongo', 'ose'] +['ient', 'o'] +['<', '>();Ċ'] +['Ġabs', 'olutely'] +['Ġsm', 'ooth'] +['TER', 'N'] +['ĠUn', 'less'] +['W', 'ord'] +['Ġmer', 'ge'] +['ig', 'an'] +['ĠV', 'ol'] +['Ġn', 'n'] +['.get', 'Id'] +['ĠÐ', '·'] +['Ġsex', 'y'] +['Ġseek', 'ing'] +['S', 'ingle'] +['.', 'this'] +['Ġk', 'om'] +['b', 'ound'] +[';', '"'] +['Ġfont', 'Size'] +['_d', 'f'] +['Ġinj', 'ury'] +['(', 'H'] +['Ġiss', 'ued'] +['_', 'END'] +[':', 'self'] +['Ġp', 'atch'] +['Ġle', 'aves'] +['Ġad', 'opt'] +['File', 'Name'] +['ãĢ', 'IJ'] +['Ġexec', 'utive'] +['ĠBy', 'te'] +[']', '))Ċ'] +['Ġn', 'u'] +['out', 'ing'] +['clud', 'ing'] +['-', 'R'] +['.', 'options'] +['Ġsub', 'stant'] +['av', 'ax'] +['ĠB', 'UT'] +['Ġtechn', 'ical'] +['Ġtw', 'ice'] +['Ġm', 'ás'] +['Ġun', 'ivers'] +['y', 'r'] +['Ġdr', 'ag'] +['ĠD', 'C'] +['Ġs', 'ed'] +['Ġb', 'ot'] +['ĠP', 'al'] +['ĠH', 'all'] +['forc', 'ement'] +['Ġa', 'uch'] +['.m', 'od'] +['not', 'ation'] +['_file', 's'] +['.l', 'ine'] +['_fl', 'ag'] +['[', 'name'] +['Ġres', 'olution'] +['Ġb', 'ott'] +['("', '['] +['end', 'e'] +['(', 'arr'] +['F', 'ree'] +['(', '@"'] +['ĠD', 'istrict'] +['PE', 'C'] +[':', '-'] +['P', 'icker'] +['ĠJ', 'o'] +['ĠĠĠĠĠ', 'Ċ'] +['ĠR', 'iver'] +['_', 'rows'] +['Ġhelp', 'ful'] +['Ġmass', 'ive'] +['---', 'Ċ'] +['Ġmeas', 'ures'] +['ĠR', 'untime'] +['Ġwor', 'ry'] +['ĠS', 'pec'] +['ĉ', 'D'] +['ãĢ', 'ij'] +['Ġ)', '{Ċ'] +['Ġwor', 'se'] +['(f', 'ilename'] +['Ġl', 'ay'] +['Ġmag', 'ic'] +['ĠThe', 'ir'] +['ou', 'l'] +['st', 'roy'] +['ĠWh', 'ere'] +['Ġsu', 'dden'] +['Ġdef', 'e'] +['Ġb', 'inding'] +['Ġfl', 'ight'] +['ĠOn', 'Init'] +['ĠW', 'omen'] +['ĠPol', 'icy'] +['Ġdrug', 's'] +['ish', 'ing'] +["('", '../'] +['ĠM', 'el'] +['pe', 'at'] +['t', 'or'] +['Ġpro', 'posed'] +['Ġst', 'ated'] +['_RE', 'S'] +['Ġe', 'ast'] +['ĠCON', 'DITION'] +['_d', 'esc'] +['Ġwin', 'ning'] +['fol', 'io'] +['M', 'apper'] +['ĠP', 'an'] +['ĠAn', 'ge'] +['.s', 'ervlet'] +['Ġcop', 'ies'] +['L', 'M'] +['Ġv', 'm'] +['å', 'į'] +['Ġd', 'ictionary'] +['S', 'eg'] +['el', 'ines'] +['ĠS', 'end'] +['Ġ', 'iron'] +['ĠF', 'ort'] +['.d', 'omain'] +['Ġdeb', 'ate'] +['Not', 'Null'] +['e', 'q'] +['ach', 'er'] +['l', 'f'] +['ĉf', 'mt'] +['Ġlaw', 'y'] +['Ä', 'Ł'] +['ĠM', 'en'] +['Ġtr', 'im'] +['(', 'NULL'] +['Ġ!', '!'] +['Ġp', 'ad'] +['Ġfollow', 's'] +['"]', '["'] +['re', 'qu'] +['ĠE', 'p'] +['.g', 'ithub'] +['(', 'img'] +['et', 'o'] +["('", '\\'] +['S', 'ervices'] +['umbn', 'ail'] +['_m', 'ain'] +['ple', 'ted'] +['fort', 'unately'] +['Ġw', 'indows'] +['Ġpl', 'ane'] +['ĠCon', 'nection'] +['.', 'local'] +['u', 'ard'] +['}', '\\'] +['==', '"'] +['and', 'on'] +['ĠR', 'oy'] +['w', 'est'] +['ig', 'inal'] +['em', 'ies'] +['it', 'z'] +["')", ':Ċ'] +['ĠP', 'eter'] +['Ġt', 'ough'] +['Ġredu', 'ced'] +['Ġcalcul', 'ate'] +['Ġrap', 'id'] +['c', 'ustomer'] +['Ġeff', 'icient'] +['Ġmed', 'ium'] +['Ġf', 'ell'] +['.', 'ref'] +['ĠC', 'as'] +['Ġfeed', 'back'] +['S', 'peed'] +['(', 'output'] +['aj', 'e'] +['Ġc', 'ategories'] +['Ġfe', 'e'] +['}', ';'] +['Ġde', 'leted'] +['re', 'h'] +['Ġpro', 'of'] +['D', 'esc'] +['B', 'uild'] +['Ġs', 'ides'] +['.Array', 'List'] +['-', '%'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠ'] +['Ø', '±'] +['.m', 'atch'] +['л', 'и'] +['Ġfe', 'els'] +['Ġachie', 've'] +['Ġcl', 'im'] +['_', 'ON'] +['ĠC', 'D'] +['Ġteach', 'er'] +['_c', 'urrent'] +['b', 'n'] +['_P', 'L'] +['ist', 'ing'] +['En', 'able'] +['G', 'EN'] +['Ġt', 'v'] +['Ġso', 'ck'] +['Ġpl', 'ays'] +['Ġdis', 'count'] +['ĠK', 'E'] +['ĠDe', 'bug'] +['F', 'ore'] +['ĠI', 'raq'] +['Ġappear', 'ance'] +['M', 'on'] +['Ġst', 'yled'] +['ĠH', 'uman'] +['i', 'ot'] +['ĠH', 'istory'] +['Ġs', 'ac'] +['ĠC', 'ollection'] +['Ġrecomm', 'ended'] +['.Se', 'lected'] +['Ġorgan', 'izations'] +['Ġdiscover', 'ed'] +['co', 'hol'] +['ad', 'as'] +['ĠThom', 'as'] +['M', 'ay'] +['Ġcons', 'erv'] +['Ġdom', 'in'] +['ĠF', 'ollow'] +['ĠSe', 'ction'] +['ĠTh', 'anks'] +['User', 'name'] +['Ġrec', 'ipe'] +['Ġwonder', 'ful'] +['.s', 'leep'] +['_', 'if'] +['ĉĊ', 'ĉĊ'] +['orn', 'o'] +['Ġr', 'u'] +['_t', 'arget'] +['."', '"'] +['à', '¦'] +['Event', 'Args'] +['Ġinput', 's'] +['Ġf', 'if'] +['Ġv', 'ision'] +['c', 'y'] +['ĠS', 'eries'] +[')', '((('] +['Ġtr', 'ading'] +['Ġmark', 'er'] +['B', 'egin'] +['Ġtyp', 'ically'] +['Ġca', 'uses'] +['drop', 'down'] +['_DE', 'BUG'] +['Ġdet', 'ect'] +['c', 'ountry'] +['!', '");Ċ'] +['ĉ', 'R'] +['app', 'y'] +['Ġc', 'ref'] +["('", '<'] +['"', '=>'] +['ĠL', 'E'] +['read', 'er'] +['Ġadmin', 'istr'] +['Ã', 'µ'] +['uck', 'et'] +['Ġf', 'ashion'] +['.', 'char'] +['iz', 'ar'] +['Ġdis', 'able'] +['Ġsu', 'c'] +['ĠL', 'ive'] +['iss', 'ue'] +['Ġmet', 'adata'] +['fl', 'ags'] +['Ġ', 'ðŁ'] +['Ġcomm', 'itted'] +['Ġv', 'a'] +['Ġr', 'ough'] +["Ġ''", "'Ċ"] +['Ġhigh', 'light'] +['_var', 's'] +['V', 'O'] +['Ġenc', 'oding'] +['-', 'Z'] +['_s', 'ign'] +['$', '("#'] +['Ġr', 'ain'] +['reate', 'st'] +['ĠEN', 'D'] +['Se', 'lection'] +['Ġcandid', 'ates'] +['Ġs', 'av'] +['.', 'Empty'] +['Ġdec', 'isions'] +['Ġcoll', 'abor'] +['rid', 'ge'] +['fe', 'ed'] +['ress', 'ion'] +['Ġperson', 's'] +['V', 'M'] +['eg', 'a'] +['_B', 'IT'] +['A', 'ccording'] +['ack', 'ed'] +['Ġdoll', 'ars'] +['_lo', 'ss'] +['ĠC', 'ost'] +['}', '"Ċ'] +['Not', 'ification'] +['Ġpro', 'stit'] +['Ġauthor', 'ity'] +['.re', 'c'] +['Ġsp', 'okes'] +['ĠT', 'oday'] +['ist', 'ant'] +['ĠHe', 'ad'] +['âĢĿ', '.'] +['ertain', 'ment'] +['ce', 'an'] +['cul', 'ate'] +['Ġv', 'en'] +['How', 'ever'] +['_', 'arr'] +['Ġtok', 'ens'] +['G', 'raph'] +['ĠJ', 'ud'] +['ĠVir', 'gin'] +['ĠS', 'erial'] +['un', 'ning'] +['M', 'utable'] +['ag', 'ers'] +['.c', 'sv'] +['Ġdevelop', 'ing'] +['Ġinstruction', 's'] +['Ġprom', 'ise'] +['Ġrequest', 'ed'] +['_', 'encode'] +['/', '"'] +['ĠI', 'con'] +['u', 'ilt'] +['-', 'day'] +['Ġint', 'elligence'] +['.', 'IS'] +['ĠO', 'bservable'] +['ĠH', 'ard'] +['Bo', 'ol'] +['ident', 'ial'] +['.An', 'chor'] +['Ġsell', 'ing'] +['C', 'I'] +['AG', 'ES'] +['t', 'le'] +['b', 'ur'] +['UFF', 'ER'] +['R', 'Y'] +['Ġbig', 'ger'] +['Ġr', 'at'] +['Ġfam', 'ous'] +['Ġtyp', 'ename'] +['Ġexpl', 'ained'] +['}', '}Ċ'] +['Ġn', 'uclear'] +['-', 'N'] +['Ġcr', 'isis'] +['ĠEnt', 'er'] +['Ġan', 'swers'] +['/', '${'] +['/', 'pl'] +['Ġse', 'qu'] +['_n', 'ext'] +['m', 'ask'] +['Ġstand', 'ing'] +['Ġpl', 'enty'] +['ĠC', 'ross'] +['ĉ', 'ret'] +['d', 'ro'] +['ĠC', 'ast'] +['=', 'true'] +['ĠCh', 'ris'] +['ic', 'io'] +['ĠM', 'ike'] +['Dec', 'imal'] +['add', 'Component'] +['L', 'en'] +['Ġco', 'ck'] +['Ġ#', '{'] +['UR', 'N'] +['<', 'tr'] +['Ġauthor', 'ities'] +['Res', 'ources'] +['-', 'H'] +['B', 'ottom'] +['_', 'qu'] +['put', 'er'] +['ester', 'day'] +['Dis', 'patch'] +['s', 'ince'] +['Ġfam', 'iliar'] +[',', 'i'] +['V', 'C'] +['Ġm', 'ent'] +[',', 'C'] +['Ġfre', 'edom'] +['Ġr', 'outes'] +['ĠB', 'uy'] +['Ġcomm', 'ands'] +['Ġm', 'esh'] +['/', 'C'] +['ĠSet', 'tings'] +['-', 'style'] +['Ġw', 'itness'] +['Ġc', 'le'] +['Ġun', 'ion'] +['ef', 'ault'] +['are', 't'] +['Ġthought', 's'] +['Ġ', '----'] +['_pro', 'cess'] +['_', 'us'] +['ing', 'ly'] +['U', 'ES'] +['T', 'ouch'] +['ĠÐ', '¼'] +['_', 'open'] +['ĠV', 'ec'] +['Ġre', 'ward'] +['.C', 'lick'] +['/', ':'] +['Ġn', 'ie'] +['Ch', 'anges'] +['M', 'onth'] +['ï¼', 'Ł'] +['Ġexec', 'ution'] +['Ġbe', 'ach'] +['(', 'Integer'] +['ĉ', 'a'] +['/', "'"] +['.Font', 'Style'] +['Ġab', 'ort'] +['ĠS', 'ingle'] +['(', 'isset'] +['Ġd', 'p'] +['Ġ}}', ''] +['Ġ*', '='] +['ĠP', 'S'] +['Ġdanger', 'ous'] +['[', 'p'] +['OM', 'E'] +['O', 'ther'] +['ĠString', 'Builder'] +['Point', 's'] +['head', 'ing'] +['Ġc', 'urrency'] +['Ġpercent', 'age'] +['_A', 'PI'] +['Ġclass', 'ic'] +['the', 'ad'] +['ĠM', 'O'] +['F', 'E'] +['Id', 'x'] +['aw', 'ait'] +['ĠÃ', '¨'] +['Ġacc', 'ident'] +['Ġvari', 'ant'] +['Ġm', 'yst'] +['ĠL', 'and'] +['ĠB', 're'] +['Ġh', 'arm'] +['ĠA', 'cc'] +['Ġcharg', 'ed'] +['ion', 'es'] +['Vis', 'ibility'] +['ar', 'ry'] +['ĠL', 'anguage'] +['Ġwalk', 'ing'] +['"', '.ĊĊ'] +['if', 'er'] +['Ġleaders', 'hip'] +['.F', 'rom'] +['yn', 'am'] +['Ġt', 'imestamp'] +['i', 'pt'] +['ĠH', 'as'] +['REF', 'ER'] +['ĠIt', 's'] +['Ġlist', 'ener'] +['UT', 'E'] +['_d', 'escription'] +['Ġexperi', 'ences'] +['Ġcre', 'ates'] +['R', 'S'] +['c', 'art'] +['bl', 'ack'] +['Ġcho', 'ices'] +['w', 'ar'] +["Ġ''", "'"] +['Ġorder', 'ed'] +['Ġeven', 'ing'] +['Ġp', 'il'] +['Ġt', 'un'] +['ĠB', 'ad'] +['(', 'app'] +['r', 'andom'] +['Ġexp', 'licit'] +['Ġarr', 'ived'] +['Ġf', 'ly'] +['Ġecon', 'om'] +['-m', 'ail'] +['Ġlist', 's'] +['Ġarch', 'itect'] +['ĠP', 'ay'] +['Ġd', 's'] +['ĠS', 'ol'] +['Ġveh', 'icles'] +['H', 'z'] +['-', 'com'] +['Ġk', 'ing'] +['_e', 'qual'] +['ĠH', 'elp'] +['Ġab', 'use'] +['--', ';Ċ'] +['Ġex', 'tr'] +['Ġchem', 'ical'] +['ä', '¿'] +['Ġor', 'ient'] +['Ġbre', 'ath'] +['ĠS', 'pace'] +['(e', 'lement'] +['w', 'ait'] +['DE', 'D'] +['ig', 'ma'] +['Ġent', 'r'] +['Ġs', 'ob'] +['-', 'name'] +['Ġaff', 'ected'] +['ik', 'a'] +['Ġco', 'al'] +['_w', 'ork'] +['Ġhundred', 's'] +['Ġpolit', 'ics'] +['sub', 'ject'] +['Ġconsum', 'er'] +['ANG', 'E'] +['Ġrepe', 'ated'] +['S', 'end'] +['Ġ#', '['] +['Ġprot', 'ocol'] +['Ġlead', 's'] +['use', 'um'] +['E', 'very'] +['Im', 'port'] +['(c', 'ount'] +['Ġchalleng', 'es'] +['Ġnov', 'el'] +['Ġdep', 'art'] +['b', 'its'] +['.C', 'urrent'] +['Ġ`', '${'] +['ot', 'ing'] +['(', '\\'] +['Ġcreat', 'ive'] +['Ġbu', 'ff'] +['Ġintrodu', 'ced'] +['us', 'ic'] +['mod', 'ules'] +['A', 're'] +['-d', 'oc'] +['l', 'anguage'] +['_c', 'ache'] +['Ġto', 'd'] +['?', '>', '{{'] +['ĠRes', 'ource'] +['ĠSt', 'andard'] +['ĠP', 'rem'] +['up', 'dated'] +['ival', 'ent'] +['Ġas', 'sets'] +['_t', 'emp'] +['Ġinterest', 's'] +['Ġhard', 'ware'] +['ĠR', 'om'] +['ĠSh', 'are'] +["Ġ'", "'Ċ"] +['Ġ*', ','] +['ĠT', 'ake'] +['ĠIm', 'ages'] +['_C', 'HECK'] +['(type', 'of'] +['ĠJ', 'un'] +['\\<', '^'] +['Ġli', 'qu'] +['Ġwor', 'st'] +['ymb', 'ols'] +['ĉĉĉ', 'ĠĠĠ'] +['Ġdr', 'ivers'] +['ĠD', 'ocument'] +['en', 'o'] +['ĠTechn', 'ology'] +['Ġappro', 'ved'] +['ump', 's'] +['Ġs', 'now'] +['form', 'ance'] +['_A', 'SSERT'] +['u', 'its'] +['Ù', 'Ĩ'] +['Ġdiffer', 'ences'] +['.', 'Visible'] +['ĉĉĉ', 'čĊ'] +['ĠP', 's'] +['_f', 'etch'] +['Ġto', 'do'] +['.', "',Ċ"] +['Ġs', 'el'] +['ur', 'ers'] +['in', 'valid'] +['Ġt', 'weet'] +['V', 'EL'] +['Ġresearch', 'ers'] +['Ġs', 'printf'] +['ĠR', 'O'] +['Ġp', 'el'] +['.Tr', 'ans'] +['Ġil', 'legal'] +['d', 'ialog'] +['sm', 'arty'] +['l', 'g'] +['_M', 'IN'] +['Ġher', 'o'] +['f', 'inal'] +['Ġp', 'p'] +['.L', 'e'] +['Ġc', 'i'] +['ĉ', 'RT'] +['Ġsuggest', 'ed'] +['p', 'df'] +['ach', 'ing'] +['ĠR', 'o'] +['ĠProp', 'erties'] +['ĠS', 'i'] +['Ġbuy', 'ing'] +['Ġm', 'u'] +['Ġl', 'ands'] +['if', 'iers'] +['ĠF', 'ILE'] +['RO', 'UP'] +['Ġh', 'older'] +['ĠS', 'on'] +['Ġsym', 'pt'] +['.r', 'oute'] +[')', '?'] +['Ġarg', 'c'] +['Ġfor', 't'] +['Ġcas', 'ino'] +['_c', 'ategory'] +['Ġfor', 'um'] +['p', 'refix'] +['apt', 'ure'] +['T', 'ube'] +['em', 's'] +['im', 'ize'] +['Ġn', 'ue'] +['a', 'us'] +['c', 'ourse'] +['AT', 'OR'] +['()', '),'] +['Ad', 'vertis'] +['ING', 'S'] +['Ġack', 'now'] +['ĠKore', 'a'] +['pl', 'ing'] +['Ġwork', 'er'] +['PL', 'IED'] +['h', 'al'] +['ĠRich', 'ard'] +['Element', 's'] +['ĉĉĉ', 'Ġ'] +['st', 'ar'] +['Ġrelationship', 's'] +['Ġche', 'ap'] +['AC', 'H'] +['ĠX', 'ML'] +[',', '&'] +['ĠLou', 'is'] +['Ġr', 'ide'] +['_F', 'AIL'] +['Ġch', 'unk'] +['[', 's'] +['_O', 'UT'] +['Ġch', 'osen'] +['_', '['] +['/', '('] +['ĠJ', 'eff'] +['_s', 'l'] +['pr', 'iv'] +['ĠCan', 'adian'] +['Ġun', 'able'] +['_F', 'LAG'] +['Ġn', 'os'] +['h', 'igh'] +['Ġl', 'ift'] +['f', 'un'] +['()', '{'] +['el', 'ly'] +['ycler', 'View'] +['_', 'as'] +['_L', 'IST'] +['Ġr', 'adi'] +['.get', 'Value'] +['ĠAnge', 'les'] +['ĠS', 'pan'] +['_in', 'stance'] +['it', 'ors'] +['Ġm', 'igration'] +['A', 'K'] +['O', 'h'] +['Â', '®'] +['.', 'selected'] +['ĠG', 'T'] +['Ġadv', 'ance'] +['ĠSt', 'yle'] +['.Data', 'GridView'] +['e', 'ction'] +['Ñ', 'İ'] +['p', 'io'] +['ro', 'g'] +['Ġsh', 'opping'] +['ĠR', 'ect'] +['I', 'lluminate'] +['O', 'U'] +['ĉ', 'array'] +['Ġsubstant', 'ial'] +['Ġpre', 'gn'] +['Ġprom', 'ote'] +['IE', 'W'] +['.L', 'ayout'] +['Ġsign', 's'] +['/', '.'] +['Ġlet', 'ters'] +['Bo', 'ard'] +['ct', 'rl'] +['"', '\\'] +['ĠJ', 'ones'] +['Ġvert', 'ex'] +['Ġj', 'a'] +['Ġaff', 'ili'] +['Ġwe', 'alth'] +['ĉ', 'default'] +['Ġsignificant', 'ly'] +['Ġe', 'c'] +['Ġx', 's'] +['act', 'ual'] +['.p', 'er'] +['_st', 'ep'] +['an', 'vas'] +['m', 'ac'] +['Ġtrans', 'l'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Iter', 'ator'] +['Ġo', 'ch'] +['agnost', 'ic'] +['ĠD', 'uring'] +['ĠDE', 'FAULT'] +['Ġt', 'ill'] +['Ġsign', 'ature'] +['Ġb', 'ird'] +['ĠO', 'l'] +['ĠI', 'r'] +['H', 'S'] +['av', 'atar'] +['ESS', 'AGE'] +['Ġe', 'lev'] +['Ġm', 't'] +['ĠN', 'av'] +['Ġrel', 'ax'] +['Ġpl', 'ate'] +['IT', 'EM'] +['(', 'date'] +['.n', 'ot'] +['Ġgr', 'ade'] +['Ġ}', '),Ċ'] +['?', '"ĊĊ'] +['i', 'ences'] +['H', 'igh'] +['ĠD', 'IS'] +['dis', 'abled'] +['Q', 'UI'] +['Ġno', 'ise'] +['a', 'ux'] +['ĠU', 'P'] +['os', 'a'] +['Ġv', 'oc'] +['Ġ', '))'] +['oc', 'om'] +['_O', 'FF'] +['ĠD', 'b'] +['L', 'ock'] +['.e', 'clipse'] +[',', 'd'] +['ĠD', 'raw'] +['Ġ"', '('] +['Ġvis', 'ited'] +['Ġâ', 'Ī'] +['Ġsuc', 'ceed'] +['Ġim', 'possible'] +['a', 'ire'] +['ĠT', 'urn'] +['Ġd', 'ish'] +['F', 'G'] +['Ġs', 'ensor'] +['AN', 'N'] +['ab', 'a'] +['Ġsur', 'g'] +[']', ');čĊ'] +['Ġf', 'p'] +['_', 'an'] +['-', 'J'] +['-', 'G'] +['ĠJ', 'ob'] +['Con', 'vert'] +['ĠKE', 'Y'] +['Ġauth', 'ors'] +['_s', 'erver'] +['\\', 'r'] +['Ġ-*', '-'] +['f', 'lex'] +['Ġs', 'oc'] +['R', 'et'] +['Ġs', 'alt'] +['Ġâ̦', 'ĊĊ'] +['ĠC', 'lear'] +['(p', 'age'] +['-d', 'anger'] +['Ġroom', 's'] +['con', 'v'] +['#', '{'] +['.', 'op'] +['ĠA', 'rea'] +['_S', 'C'] +['h', 'en'] +['Ġbeg', 'ins'] +['-', 'y'] +['Ġexc', 'ited'] +['Ġign', 'ored'] +['Ġbon', 'us'] +['st', 'udent'] +['ĠM', 'ember'] +['Ġrel', 'atively'] +['ĠL', 'ow'] +['ĠPro', 'du'] +['ate', 'way'] +['pos', 'ure'] +['Ġth', 'ick'] +['ani', 'el'] +['(', 'view'] +['ĠCr', 'ush'] +['Ext', 'ension'] +['I', 'l'] +['e', 'ed'] +['LO', 'C'] +['.', 'im'] +['.', 'Items'] +['Ġconflic', 't'] +['.pre', 'vent'] +['Ġon', 'Create'] +['u', 'v'] +['is', 'er'] +['Ġw', 'ave'] +['M', 'ar'] +['ĠComm', 'unity'] +['ic', 'he'] +['ĠNo', 'thing'] +['[', 'm'] +['ĠLe', 'e'] +['ri', 'ends'] +['è', 're'] +['!!', '!'] +['an', 'z'] +['.', 'result'] +['ĠS', 'K'] +['_P', 'ARAM'] +['Ġdem', 'ocr'] +['Back', 'Color'] +['.ex', 'ists'] +['"', 'It'] +['(', 'options'] +['ra', 'zy'] +['as', 'er'] +['\\', 'Database'] +['al', 'endar'] +['_', 'ass'] +[';', '}Ċ'] +['vert', 'ex'] +['ine', 'craft'] +['W', 'arning'] +['arg', 'o'] +['Ġact', 'or'] +['ĠInst', 'ead'] +['ĠUs', 'ing'] +['S', 'elf'] +['@', 'interface'] +['Ġspe', 'aking'] +['ĠPar', 'is'] +['ĠL', 'ICENSE'] +['.n', 'ode'] +['ĠF', 'ood'] +['E', 'IF'] +['ĠB', 'i'] +['.', 'Start'] +['ĠI', 'B'] +['Ġun', 'iversity'] +['ĠHe', 'ader'] +['.pro', 'duct'] +['C', 'opy'] +['et', 'c'] +['r', 'ical'] +['Ġ>', '>>'] +['book', 's'] +['Ġal', 'gorithm'] +["Ġ'", '__'] +['(j', 'avax'] +['Ġnumer', 'ous'] +['Sh', 'are'] +['H', 'ave'] +['Ġrec', 'ru'] +['Ġpro', 've'] +['.sub', 'string'] +['he', 'alth'] +['е', 'л'] +['Ġdec', 'imal'] +['Ġcomm', 'ission'] +['s', 'cription'] +['x', 'C'] +['Ġsum', 'mary'] +['att', 'ed'] +['Ġclo', 'ser'] +['fin', 'ished'] +['()', '){Ċ'] +['ĠW', 'ood'] +['_field', 's'] +['k', 'u'] +['_', 'items'] +['Fl', 'ag'] +['Ġconf', 'idence'] +['ĠF', 'ederal'] +['du', 'x'] +['Ġcomp', 'at'] +['Ġvert', 'ical'] +['Ð', '¹'] +['è', 's'] +[';', '">Ċ'] +['_m', 'anager'] +['()', '))Ċ'] +['ID', 'E'] +[':', '",'] +['__', 'Ċ'] +['ĠW', 'ay'] +['Ñ', 'Ī'] +['T', 'emp'] +['ĠS', 'TR'] +['rit', 'ten'] +['S', 'ync'] +['ĠA', 'V'] +['ĠC', 'EO'] +['ĠG', 'uid'] +['Ġenvironment', 'al'] +['Ġcorrespond', 'ing'] +['ĉ', 'console'] +['Ġjust', 'ice'] +['ĠJ', 'S'] +['Ġl', 'ived'] +['g', 'ar'] +['ĠG', 'raph'] +['ĠSt', 'at'] +['Ġi', 'Phone'] +['.', 'al'] +['ĠH', 'D'] +['Ġocc', 'ur'] +['Ġth', 'reshold'] +['Ġon', 'click'] +['RE', 'G'] +['.Graphics', 'Unit'] +['M', 'eta'] +['Å', '¾'] +['Ġc', 'um'] +['.g', 'nu'] +['Ã', '«'] +['Ġobt', 'ained'] +['Ġcompl', 'aint'] +['Ġe', 'ating'] +['Ġt', 'ar'] +['_t', 'ask'] +['Ġopt', 's'] +['(', 'to'] +['P', 'ass'] +['Ġpl', 'astic'] +['t', 'ility'] +['ĠW', 'in'] +['.prevent', 'Default'] +['p', 'ile'] +['ĠG', 'ar'] +['Ġqu', 'antity'] +['_l', 'ast'] +['Ġg', 'reatest'] +['D', 'ao'] +['_D', 'IS'] +['ĠUs', 'ed'] +['ĠH', 'P'] +['rit', 'ing'] +['S', 'ION'] +['bl', 'ue'] +['d', 'omain'] +['Ġs', 'cores'] +['N', 'ormal'] +['_', 'admin'] +['ĠA', 'SSERT'] +['Th', 'en'] +['**', '*'] +['d', 'ist'] +['l', 'on'] +['Ġh', 'ate'] +['sh', 'al'] +['Image', 'View'] +['d', 'atabase'] +['Ġp', 'and'] +['Ġlog', 'ic'] +['=', 'false'] +['b', 'g'] +['ĠConfig', 'uration'] +['Ġn', 'ur'] +['O', 'G'] +['Ġmar', 'ried'] +[':', '+'] +['Ġdro', 'pped'] +['Ġreg', 'istration'] +['оÐ', '¼'] +['ult', 'iple'] +['iz', 'ers'] +['sh', 'ape'] +['.c', 'opy'] +['Ġwe', 'aring'] +['ĠC', 'ath'] +['Ġded', 'icated'] +['Ġ..', '.Ċ'] +['Ġadv', 'oc'] +['ĠF', 'amily'] +['Ġstat', 'ements'] +['em', 'atic'] +['ampions', 'hip'] +['Ġmot', 'iv'] +['ĠH', 'ave'] +['Ġbl', 'ow'] +['J', 'ob'] +['c', 'ert'] +['_v', 'ector'] +['inst', 'all'] +['ĠC', 'OPY'] +['em', 'bed'] +['D', 'IR'] +['ĠS', 'pring'] +['Ġex', 'hib'] +['cd', 'n'] +['ĠCom', 'ment'] +['ĠOption', 'al'] +['.', 'player'] +['ĠD', 'ark'] +['(', 'pos'] +['ĠSh', 'ould'] +['Ġcent', 're'] +['ĠGu', 'ard'] +['ó', 'w'] +['Ġtr', 'ouble'] +['EN', 'ER'] +['(', 'unsigned'] +['_s', 'ervice'] +['Ġn', 's'] +['ul', 'ing'] +['ĠMex', 'ico'] +['ĠN', 'Y'] +['mys', 'ql'] +['Ġl', 'ic'] +['å', 'ľ'] +['M', 'r'] +['-', 'fl'] +['ĠC', 'ustomer'] +['id', 'i'] +['Ġ?', '>ĊĊ'] +['ri', 'ble'] +['Ġп', 'ÑĢ'] +['Ġs', 'izes'] +['_STR', 'ING'] +['valid', 'ation'] +['ĠJ', 'on'] +['(', 'Http'] +['add', 'Class'] +['N', 'odes'] +['Ġfrag', 'ment'] +['Ġsp', 'oke'] +['Ġw', 'aste'] +['J', 'oin'] +['Ġill', 'ustr'] +['el', 'i'] +['c', 'ient'] +['Ġa', 'id'] +['Ġpro', 'sec'] +["')", '{Ċ'] +['Ġpass', 'ing'] +['Ġf', 'aces'] +['Sh', 'ape'] +['_', 'Z'] +['it', 'i'] +['Ġal', 'le'] +['Ġro', 'bot'] +['ĠĠĠĠĠĠĠ', 'Ċ'] +['ĠS', 'pe'] +['Ġrece', 'iving'] +['ĠD', 'etails'] +['Ġ"', ')'] +['m', 'g'] +['_RE', 'F'] +['Ġcompar', 'ison'] +['*', ','] +['ĠF', 'ound'] +['_s', 'ession'] +['(', 'U'] +['/', 'F'] +['Ġx', 'xx'] +['N', 'etwork'] +['d', 'ers'] +['Ġcap', 'ture'] +['Ġcor', 're'] +['ĠL', 'td'] +['ĠAd', 'v'] +['[', '@'] +['Ġcl', 'ip'] +['M', 'ill'] +['ĠPro', 'file'] +['Ġend', 'if'] +['Ġob', 'lig'] +['des', 'cribe'] +['.e', 'lement'] +['riter', 'ion'] +['L', 'D'] +['er', 'ed'] +['Ġfav', 'our'] +['s', 'core'] +['ĠF', 'ilter'] +['at', 'tributes'] +['Ġcheck', 's'] +['In', 'flater'] +['ĠPl', 'us'] +['Ġscient', 'ific'] +['Ġpriv', 'acy'] +['He', 'ad'] +['Ġfe', 'at'] +['Ġdeg', 'rees'] +['ĠP', 'ale'] +[';', '">'] +['Ġfil', 'ms'] +['ĠA', 'udio'] +['ĠT', 'ag'] +['ĠE', 'nergy'] +['it', 'ar'] +['par', 'ator'] +['Ġf', 'ellow'] +['Ġev', 't'] +['ĠT', 'ri'] +['ĠD', 'AM'] +['cl', 'oud'] +['ĠP', 'assword'] +['ĠDemocr', 'ats'] +['ĠAc', 'ad'] +['$', 'lang'] +['Ġre', 'b'] +['()', ')ĊĊ'] +['н', 'Ñĭ'] +['ĠB', 'ur'] +['read', 'cr'] +['Ġh', 'ex'] +['Con', 'sole'] +['ct', 'l'] +['ous', 'el'] +['ĠWill', 'iam'] +['Ġa', 'z'] +['_P', 'ORT'] +['Ġpract', 'ices'] +['Ġany', 'where'] +['ĠP', 'osition'] +['Ġ-', '>Ċ'] +['i', 'ams'] +['.user', 'name'] +['place', 'holder'] +['Ġo', 'der'] +['ĠSecret', 'ary'] +['Ġi', 'T'] +['mon', 'd'] +['event', 's'] +['?', 'âĢĿ'] +['.S', 'ub'] +['Ġatt', 'ached'] +['Ġn', 'ão'] +['Ġest', 'ate'] +['.', 'action'] +['Ġfig', 'ures'] +['Ġ}', ');čĊ'] +['Ġsubs', 'cri'] +['.t', 'ag'] +['n', 'am'] +['.', 'plot'] +['no', 'on'] +['li', 'ament'] +['Char', 'acter'] +['.t', 'ab'] +['Ġw', 'inter'] +['ĠVar', 'iable'] +['Ġtre', 'es'] +['Ġpr', 'oud'] +['(', 'V'] +['_', 'load'] +['Ġh', 'ier'] +['ĠE', 'con'] +['Ġf', 'd'] +['Ġvict', 'ims'] +['R', 'est'] +['ian', 'a'] +['Ġf', 'ake'] +['.Print', 'ln'] +['Ġstr', 'len'] +['Ġs', 'ad'] +['Ġb', 'le'] +['Pro', 't'] +['Ġbutton', 's'] +['Ġte', 'levision'] +['Ġlog', 'o'] +['ext', 'ension'] +['ĉ', 'j'] +['ste', 'in'] +['acion', 'es'] +['Ġ""', '"ĊĊ'] +['Ġsim', 'p'] +['Ġrecord', 'ed'] +['Ġbr', 'ings'] +['Ġprincip', 'al'] +['Ġfe', 'es'] +['(s', 'ource'] +['k', 'dir'] +['Ġutil', 's'] +['Ġcorrect', 'ly'] +['f', 'il'] +['Ġw', 'el'] +['P', 'air'] +['-b', 'utton'] +['s', 'cale'] +['ver', 'ify'] +['[', 'c'] +['Ġ--', '-'] +['Ġes', 'cape'] +['ik', 'es'] +['Lower', 'Case'] +['ic', 'ian'] +['Ġch', 'apter'] +['ĠT', 'YPE'] +['Ġsh', 'adow'] +['Ġaw', 'esome'] +['W', 'E'] +['el', 'if'] +['Ġl', 'ambda'] +['Ġdist', 'inct'] +['Ġb', 'are'] +['-', 'off'] +['Ġcol', 'our'] +['.append', 'Child'] +['ole', 'c'] +['ag', 'a'] +['.f', 'ill'] +['ĉs', 'uper'] +['Ġad', 'j'] +['(', 'position'] +['.get', 'Item'] +['Sh', 'ort'] +['Ġtot', 'ally'] +['V', 'D'] +['ĠT', 're'] +['_', 'ep'] +['v', 'ements'] +['ĠS', 'olution'] +['Ġfund', 'ament'] +['F', 'ollow'] +['Ġfac', 'ility'] +['Ġhappen', 'ing'] +['O', 'F'] +['.text', 'Box'] +['S', 'pan'] +['ĠÂ', '«'] +['id', 'en'] +['Ġex', 'ceed'] +['(p', 'arent'] +['Ġc', 'p'] +['ç', '»'] +['Ġhas', 'n'] +['Ġp', 'ri'] +['Ġcon', 'sequ'] +['n', 'en'] +['ĠIN', 'TO'] +['I', 'gnore'] +['ĠF', 'uture'] +['Ġcar', 'bon'] +['ĠSte', 'el'] +['f', 'mt'] +['ok', 'ie'] +['Ġs', 'pl'] +['(t', 'itle'] +['-', 'info'] +['Ġde', 'als'] +['Ġfix', 'ture'] +['e', 'a'] +['D', 'iv'] +['Ġtest', 'ed'] +['_', 'return'] +[')ĊĊ', 'ĊĊ'] +['upport', 'ed'] +['ĠC', 'ook'] +['Ġpay', 'ing'] +['ĠI', 'll'] +['Ġarrest', 'ed'] +['ĠPr', 'ime'] +['_c', 'allback'] +['>', ',Ċ'] +['dr', 'iver'] +['On', 'ce'] +['ab', 'b'] +['_by', 'tes'] +['ĠS', 'ets'] +['(', 'Object'] +['Ġc', 'c'] +['Ġsh', 'ell'] +['al', 'o'] +[');', '//'] +['(', 'log'] +['ct', 'ors'] +[')', ''] +['Ġ$', '(".'] +['.p', 'os'] +['Ġbo', 'ys'] +['Ġwed', 'ding'] +['Ġag', 'ents'] +['="', '_'] +['ĠAr', 'my'] +['Ġh', 'int'] +['v', 'ision'] +['Ġte', 'ch'] +['ĠCon', 'nect'] +['Ġleg', 'end'] +['ĠB', 'et'] +['.B', 'ase'] +['Sub', 'ject'] +['Ġl', 'it'] +['Rem', 'ove'] +['Ġ"', ':'] +['ĠF', 'inal'] +['pear', 'ance'] +['ĠiT', 'unes'] +['Ġparticip', 'ants'] +['ĠPy', 'thon'] +['Ġbus', 'y'] +['i', 'el'] +['vert', 'ices'] +['Ġtemplate', 'Url'] +['ĠC', 'lose'] +['Im', 'g'] +['ĠCorpor', 'ation'] +['t', 'imestamp'] +['Ġext', 'end'] +['Ġwe', 'bsites'] +['Ġposs', 'ibility'] +['о', 'ÑĤ'] +['Ġk', 'ö'] +['Ġme', 'at'] +['Ġrepresent', 'ation'] +['Ġ', 'ĉĉ'] +['_ST', 'ART'] +['.app', 'ly'] +['ĠVal', 'ley'] +['ĠS', 'uccess'] +['H', 'i'] +['Ġn', 'ob'] +['ĠI', 'Enumerable'] +['_', 'select'] +['ge', 'o'] +['.', '")Ċ'] +['Ġturn', 'ing'] +['Ġfab', 'ric'] +['("', '");Ċ'] +['Ġpers', 'pective'] +['é', 'Ĺ'] +['ĠS', 'n'] +['Th', 'ank'] +[';', 'j'] +['.Param', 'eters'] +['ĉ', 'ĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġfact', 's'] +['Ġun', 't'] +['.in', 'stance'] +['################################', '################################'] +['-', 'end'] +['ĠJO', 'IN'] +['ĠH', 'en'] +['Ġur', 'i'] +['åIJ', 'į'] +['Ġн', 'а'] +['ĠIn', 'fo'] +['Ġconduct', 'ed'] +['ĠÃ', '¥'] +['OUR', 'CE'] +['Ġw', 'ine'] +['J', 'ohn'] +['.Error', 'f'] +['ĠA', 'ge'] +['ound', 'ed'] +['Ġreal', 'ize'] +['Ġ]', ';'] +['Ġsub', 'sequ'] +[',', 'm'] +['(', 'User'] +['ian', 'o'] +['Ġaccom', 'pl'] +['is', 'p'] +['.st', 'd'] +['é', 'ĩ'] +['ĠB', 'ed'] +['.set', 'Attribute'] +['B', 'R'] +['ke', 'ep'] +['ĠA', 'LL'] +['Ġis', 'ol'] +['am', 'ma'] +['P', 'ackage'] +['Ġoccas', 'ion'] +['-s', 'uccess'] +['еÐ', '´'] +['ĠLIMIT', 'ED'] +['st', 'rip'] +['()', 'ĊĊĊ'] +['istrib', 'ution'] +['Color', 's'] +['Ġ+', ':+'] +['Did', 'Load'] +['al', 'er'] +['Ġt', 'id'] +['ĠL', 'ED'] +['ĠLink', 'ed'] +['ĠC', 'art'] +['()', ')čĊ'] +['_RE', 'AD'] +['Ġkill', 'ing'] +['ĠP', 'HP'] +['fe', 'ction'] +['Ġinst', 'ances'] +['c', 'v'] +['"/', '>'] +['Ġs', 'f'] +['Ġtax', 'es'] +['_', 'location'] +['ĠBit', 'coin'] +['u', 'able'] +['r', 'ank'] +['ign', 'ore'] +['tr', 'ack'] +['к', 'а'] +['Ġshould', 'n'] +['ĠO', 'P'] +['=>', '{Ċ'] +['Ġk', 'm'] +['Ġh', 'elper'] +['_', 'head'] +['ĠWh', 'ether'] +['oc', 'o'] +['_b', 'l'] +['Ġstat', 'istics'] +['Ġbeaut', 'y'] +['Ġto', 'g'] +['t', 'ip'] +['ëĭ', '¤'] +['Ġc', 'sv'] +['(s', 'ql'] +['std', 'lib'] +['we', 'ak'] +['Ġlik', 'es'] +['Ä', 'į'] +['Ġrepe', 'at'] +['Ġap', 'artment'] +['Ġem', 'ph'] +['_', 'edit'] +['Ġv', 'it'] +['ĉ', 'type'] +['E', 'ven'] +['ut', 'en'] +['Ġcircum', 'stances'] +['b', 'ian'] +['Ġs', 'ugar'] +['W', 'indows'] +['ì', 'ŀ'] +['Ġobs', 'erved'] +['/', 'data'] +['Ġcal', 'endar'] +['Ġstri', 'ke'] +['ĠR', 'ES'] +['_s', 'c'] +['f', 'ony'] +['ore', 'm'] +['(', 'z'] +['p', 'ower'] +['et', 'ect'] +['ĠS', 'at'] +['.d', 'escription'] +['Ġg', 'ang'] +['ĠS', 'ports'] +['ong', 's'] +['ĠB', 'undle'] +['.s', 'um'] +['on', 'ce'] +['Ġacc', 'used'] +['Ġexplo', 're'] +['Ġapprox', 'imately'] +['Ġlos', 'ing'] +['thes', 'is'] +['ĠF', 'und'] +['Ġdi', 'agn'] +['A', 'utowired'] +['prop', 'erties'] +['Ġ_', '.'] +['Ġc', 'nt'] +['ced', 'ure'] +['Ġy', 'y'] +['Ġgr', 'ant'] +['so', 'ck'] +['.inner', 'HTML'] +['Ġ]', ');Ċ'] +['ĠCON', 'FIG'] +["='", '$'] +[']', '];Ċ'] +['UN', 'D'] +['Ġg', 'lob'] +['Ġd', 'ire'] +['uff', 'le'] +['_M', 'EM'] +['Ġauth', 'entic'] +['>', '("'] +['Ġdec', 'ade'] +['ĠIm', 'port'] +['Ġorigin', 'ally'] +['Ġj', 'Query'] +['Ġindic', 'ate'] +['Ġours', 'elves'] +['S', 'w'] +['.l', 'bl'] +['ener', 'ate'] +['Ġbas', 'ically'] +['ĠH', 'om'] +['Ġ+', '#+'] +['ĠBrit', 'ain'] +['ĠK', 'ar'] +['to', 'Equal'] +['.st', 'op'] +['Ġmod', 'al'] +['is', 'i'] +['Ġsuggest', 's'] +['Ġd', 'type'] +['Ġt', 'ur'] +['b', 'f'] +['Ġconnection', 's'] +['ĠB', 'efore'] +['ist', 'ed'] +['m', 'ouse'] +['Ġpul', 'led'] +['.b', 'uild'] +['Ġlegis', 'lation'] +['Ġfor', 'th'] +['p', 'ad'] +['eg', 'o'] +['.N', 'ow'] +['Ġexc', 'iting'] +['}ĊĊ', 'ĊĊ'] +['Ġcom', 'pr'] +['Ġsh', 'ares'] +['Ġr', 'ig'] +['g', 'reen'] +['_', 'vec'] +['Ġenumer', 'ate'] +['A', 'uto'] +['ic', 'ator'] +['ĠR', 'ay'] +['as', 'se'] +['Ġh', 'oliday'] +['Ġnull', 'able'] +['g', 'un'] +['_d', 'etails'] +['Ġwr', 'apper'] +['se', 'q'] +['ĠYou', 'ng'] +['ju', 'ana'] +['Ġ"', '__'] +['lic', 'ense'] +['ser', 've'] +['^', '('] +['id', 'ers'] +['.Rem', 'ove'] +['rop', 'down'] +["'", 'S'] +['p', 'in'] +['(t', 'oken'] +['.D', 'efault'] +['Ġreason', 'able'] +['amp', 'ion'] +['ĠS', 'ociety'] +['Ġbe', 'i'] +['erv', 'es'] +['r', 'ad'] +['ĠF', 'ox'] +['_', 'images'] +['Ġw', 'heel'] +["')", '['] +['Ġc', 'fg'] +['(', 'By'] +['Con', 'structor'] +['Ġv', 'ary'] +['.sw', 'ift'] +['Ġpro', 'xy'] +['ĉ', 'H'] +['ĠAn', 'other'] +['ĠP', 'en'] +['Ġcheck', 'ing'] +['Ġj', 'est'] +['man', 'ager'] +['Or', 'igin'] +['ug', 's'] +['o', 'ir'] +['><', '!--'] +['Ġexpress', 'ed'] +['Ġmod', 'er'] +['Ġag', 'encies'] +['Ġi', 'h'] +['-h', 'idden'] +['ious', 'ly'] +['ĠR', 'od'] +['Ġso', 'le'] +['M', 'ed'] +['.A', 'ny'] +['Ġp', 'c'] +['b', 'al'] +['Ex', 'ample'] +['ĠS', 'ale'] +['Ġst', 'rip'] +['ĠCom', 'p'] +['Ġpresident', 'ial'] +['M', 'ost'] +['put', 'ation'] +['(', 'ref'] +['ĠF', 'our'] +['_f', 'ilename'] +['Ġen', 'forcement'] +['Ø', '¯'] +['ĠGe', 'org'] +['we', 'ights'] +['/', 'l'] +['Ġag', 'gress'] +['Ġd', 'rawing'] +['and', 'y'] +['<', 'I'] +['-', 'j'] +['ak', 'a'] +['h', 'ref'] +['Ġteach', 'ers'] +['_', 'Q'] +['(', 'it'] +['ĠM', 'B'] +['Ġtemp', 'orary'] +['ire', 'base'] +['str', 'a'] +['æĹ', '¶'] +['è', '´'] +['(', 'label'] +['ou', 'p'] +['Ġtop', 'ics'] +['Ġport', 'ion'] +['id', 'os'] +['ĠJew', 'ish'] +['Ġre', 'covery'] +['Ġstand', 's'] +['#', '['] +['Ġafter', 'noon'] +['ĠArt', 'icle'] +['_', 'att'] +['Ġexpl', 'an'] +['ĠP', 'ak'] +['.setOn', 'ClickListener'] +['.', 'children'] +['Ġi', 'k'] +['+', '('] +['l', 'ag'] +['Ġdis', 'k'] +['Ġcont', 'rovers'] +['">', '&'] +['as', 'p'] +['Ġw', 'ie'] +['ĠAustral', 'ian'] +['ĠYou', 'Tube'] +['At', 'tr'] +['cont', 'ains'] +['du', 'ce'] +['ĠM', 'att'] +['at', 'ern'] +['Ġvol', 'unte'] +['Ġnew', 'sp'] +['V', 'P'] +['olt', 'ip'] +['Ġde', 'legate'] +['_m', 'eta'] +['Ġaccur', 'ate'] +['ĠEx', 'ample'] +['%', ','] +['ĠD', 'aily'] +['Ġc', 'abin'] +['ĠS', 'W'] +['Ġlim', 'its'] +['k', 'ip'] +['Ġar', 'my'] +['Ġend', 'ing'] +['Ġb', 'oss'] +['ĠD', 'ialog'] +['Al', 'so'] +['="#', '"'] +['ord', 'an'] +['row', 'se'] +['-', 'min'] +['Ġ"', '&'] +['_', 'loc'] +['U', 'X'] +['Ġdevelop', 'ers'] +['Ġaccur', 'acy'] +['Ġmaint', 'enance'] +['Ġhe', 'av'] +['Ġfil', 'ters'] +['.T', 'oolStrip'] +['Ġn', 'arr'] +['ĠE', 'mp'] +['ORD', 'ER'] +['ĠM', 'obile'] +['.S', 'erial'] +['.out', 'put'] +['.c', 'ol'] +['M', 'aterial'] +['um', 'a'] +['Ġconsum', 'ers'] +['sh', 'ift'] +['Ġp', 'ued'] +['Ġmin', 'i'] +['c', 'ollection'] +['Ġk', 'an'] +['.c', 'enter'] +['H', 'istory'] +['Ġben', 'ch'] +['()', ');'] +['itor', 'ies'] +['Ġcrow', 'd'] +['_c', 'all'] +['Ġpow', 'ers'] +['-', 'E'] +['Ġdis', 'miss'] +['Ġtalk', 's'] +['ĠCh', 'annel'] +['for', 'ward'] +['_', 'control'] +['/s', 'rc'] +['i', 'est'] +['****************', '********'] +['Ġbet', 'a'] +['(c', 'olor'] +['_O', 'BJECT'] +['ĠA', 'pi'] +['Ġeffect', 'ively'] +['C', 'amera'] +['s', 'd'] +['uss', 'y'] +['D', 'ict'] +['ĠE', 'ffect'] +['ib', 'ilities'] +['Ġreturn', 'ing'] +['ĠF', 'ar'] +["Ġ'", "')"] +['Ġmod', 'ules'] +['il', 'ation'] +['Ġ(', '%'] +['TR', 'GL'] +['Ġst', 'orm'] +['on', 'na'] +['ĠEX', 'P'] +['Ġs', 'pons'] +['Ġdis', 'pl'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['f', 'all'] +['å', 'Į'] +['ign', 'Key'] +['_', 'US'] +['et', 'rics'] +['Ġhand', 'les'] +['T', 'L'] +['_', 'amount'] +['ow', 'a'] +['br', 'and'] +['ĠT', 'ool'] +['Ġus', 'ual'] +['.', 'Z'] +['cre', 'ment'] +['ad', 'ium'] +['st', 'ock'] +['Ġserv', 'ing'] +['ĠB', 'on'] +['Ġline', 'ar'] +['ĠT', 'arget'] +['ĠR', 'adio'] +['H', 'L'] +['Sh', 'ader'] +['om', 'atic'] +['ag', 'ues'] +['in', 'ity'] +['d', 'iff'] +['_', 'iterator'] +['qu', 'ot'] +['Ġ', ',Ċ'] +['c', 'allback'] +['Ġsympt', 'oms'] +['[', '_'] +['ĠB', 'ul'] +['ĠF', 'eb'] +['und', 'o'] +['_', 'account'] +['Ġtyp', 'edef'] +['и', 'Ñģ'] +['tr', 'as'] +['User', 'Id'] +['ĠP', 'enn'] +['ĠSup', 'reme'] +['}', '>'] +['user', 'Id'] +['ĠK', 'im'] +['Ġg', 'a'] +['Ġart', 'ists'] +['å', '¸'] +['ĠAb', 'stract'] +['ok', 'emon'] +['Ġh', 'am'] +['o', 'val'] +['Ġch', 'a'] +['at', 'en'] +['å', 'Ĩ'] +['F', 'ixed'] +['Ġvul', 'ner'] +['ĠParam', 'eters'] +['qu', 'antity'] +['.C', 'lear'] +['Servlet', 'Request'] +['Ġy', 'a'] +['Ġsou', 'l'] +['trans', 'action'] +['Ġsol', 'o'] +['Ġp', 'airs'] +['æ', 'Ķ'] +['ĠG', 're'] +['_', 'word'] +['ĠC', 'C'] +['Ġg', 'i'] +['z', 'ie'] +['Ġsched', 'uled'] +['rot', 'ation'] +['gy', 'pt'] +['ul', 'ous'] +['::', '_'] +['ĠE', 'll'] +['<', '!'] +['ĉĉ', 'ĠĠ'] +['l', 'p'] +['ah', 'a'] +['C', 'opyright'] +['Ġdr', 'am'] +['Ġdi', 'agram'] +['ĠM', 'em'] +['Ġg', 'arden'] +['Com', 'p'] +['Ġattempt', 's'] +['uff', 'ix'] +['>', '()'] +['Ġphil', 'osoph'] +['_re', 'l'] +['å', '¼'] +['Ġs', 'v'] +['.se', 'cond'] +['ant', 'o'] +['.J', 'son'] +['ĠTe', 'le'] +['_', 'local'] +['_s', 'end'] +['Ġas', 'pects'] +['ì', 'Ĺ'] +['IB', 'LE'] +['Ġr', 'ail'] +['Ġwid', 'ely'] +['ash', 'ed'] +['i', 'ar'] +['in', 'f'] +['up', 'per'] +['d', 'jango'] +['_result', 's'] +['iss', 'ing'] +['Ġequ', 'ivalent'] +['OUN', 'D'] +['Ġt', 'y'] +['Ġpotential', 'ly'] +['Advertis', 'ement'] +['ĠRec', 'ord'] +['resent', 'ation'] +['_w', 'idget'] +['ound', 'ing'] +['Ġrelig', 'ion'] +['Ġcons', 'c'] +['ĠL', 'im'] +['.', 'am'] +['H', 'tml'] +["Ġ'", ':'] +['P', 'ATH'] +['_s', 'pec'] +['ort', 'ed'] +['id', 'ades'] +['_sh', 'ape'] +['Ġkeep', 's'] +['.S', 'ave'] +['ĠL', 'oc'] +['or', 'i'] +['ĠT', 'EST'] +['unic', 'ip'] +['Ġreg', 'ions'] +['Ġbelie', 'ves'] +['/', 'en'] +['pos', 'ite'] +['{', "'"] +['pre', 'pare'] +['_', 'const'] +['s', 'ample'] +['ĠWill', 'iams'] +['Ġstr', 't'] +['_', 'Get'] +['ĠAnd', 'rew'] +['.', 'active'] +['Ġl', 'ayers'] +['Visual', 'Style'] +['az', 'y'] +['ĠK', 'n'] +['Ġac', 'id'] +['ĠAs', 'ia'] +['Ġex', 'cess'] +['ĉm', 'y'] +['Ġkey', 'board'] +['ens', 'us'] +['Ġcre', 'w'] +['Ġmiss', 'ed'] +['m', 'aster'] +['ĠW', 'ild'] +['Ġnew', 'ly'] +['Ġwin', 'ner'] +['Ġst', 'ub'] +['ic', 'ode'] +['.m', 'ove'] +['D', 'omain'] +['ĠS', 'ar'] +['Ġfore', 'st'] +['LE', 'D'] +['claim', 'er'] +['.ex', 'it'] +['ĠW', 'indow'] +['Ġres', 'istance'] +['ĠC', 'HECK'] +['("', '-'] +['ĠR', 'yan'] +['Ġp', 'ipe'] +['Ġco', 'ast'] +['DE', 'F'] +['//', '!'] +['_', 'off'] +['ex', 'it'] +['Ġult', 'imately'] +['imit', 'ive'] +['ĠKe', 'ep'] +['Ġhistor', 'ical'] +['Ġany', 'way'] +['ĠJack', 'son'] +['ock', 'er'] +['ER', 'N'] +['ĠU', 'INT'] +['y', 'ntax'] +['ER', 'Y'] +['is', 'ms'] +['Ġc', 'n'] +['Ġocc', 'urs'] +['Ġ;', ';'] +['Text', 'View'] +['A', 'E'] +['/', 'img'] +['Ġy', 'esterday'] +['-', 'default'] +['Ġt', 'iny'] +['Ġpro', 'c'] +['Ġal', 'ive'] +['ĠRE', 'G'] +['.', 'th'] +['ear', 'ing'] +['.get', 'Logger'] +['<', 'link'] +['_', 'login'] +['F', 'older'] +['ab', 'c'] +['lyph', 'icon'] +['н', 'о'] +['Ġnot', 'iced'] +['od', 'igo'] +['Ġed', 'ition'] +['im', 'ator'] +['.', 'Enabled'] +['.parse', 'Int'] +['Ġy', 'ards'] +['ĉĉĉĉĉĉĉĉ', 'ĉĉĉĉ'] +['Ġver', 'bose'] +['л', 'Ñı'] +['_B', 'Y'] +['.log', 'in'] +['.*', ';Ċ'] +['ĠM', 'id'] +['é', 'es'] +['Ġg', 'lo'] +['Ġbuild', 'ings'] +['Ġz', 'e'] +['ĠI', 'ter'] +['Ġt', 'ube'] +['ĠP', 'ot'] +['\\', 'M'] +['<', 'th'] +['br', 'idge'] +['ĠS', 'cript'] +['ĠM', 'odule'] +['Ġv', 'acc'] +['Ġinstall', 'ation'] +['v', 'y'] +['VisualStyle', 'BackColor'] +['ĠS', 'M'] +['.t', 'otal'] +['b', 'at'] +['Ġfind', 's'] +['Ġat', 'mos'] +['Sub', 'view'] +['iz', 'ard'] +['Ġrepl', 'acement'] +['lic', 'ated'] +['ap', 'is'] +['Ġlog', 'ged'] +['ĠLe', 'ft'] +['G', 'ui'] +['_', 'Type'] +['t', 'm'] +['P', 'ad'] +['Ġhouse', 'hold'] +['Ġre', 'le'] +['Ġpropos', 'al'] +['_CL', 'ASS'] +['::', '::'] +['Ġinf', 'rastructure'] +['In', 'ject'] +['/', 'html'] +['Ġad', 's'] +['iz', 'za'] +['Ġm', 'g'] +['ctr', 'ine'] +['%', 'Ċ'] +['<', 'html'] +['-', 'image'] +['Ġatt', 'orney'] +['<', 'm'] +["('", ','] +['Ġcan', 'n'] +['Ġprint', 'ln'] +['o', 'ose'] +['Ġy', 'ellow'] +['.ex', 'p'] +['p', 'ayment'] +['Ġtable', 'View'] +['aw', 'ay'] +['Ġopp', 'osition'] +['ĠAg', 'ain'] +['ĠH', 'andle'] +['Ġex', 'clusive'] +['in', 'ar'] +['é', 'r'] +['оÐ', '±'] +['ĠC', 'ODE'] +['emp', 'orary'] +['Ġre', 'act'] +['pi', 'pe'] +['c', 'z'] +['.', 'activity'] +['Ġlarg', 'ely'] +['Ġdis', 's'] +['ax', 'y'] +['es', 'is'] +['ĠR', 'en'] +['Ġc', 'orn'] +['.Use', 'VisualStyleBackColor'] +['d', 'ays'] +['Ġfr', 'uit'] +['In', 'sert'] +['_', 'enc'] +['E', 'st'] +['_de', 'c'] +['ĠL', 'uc'] +['Ġü', 'ber'] +['param', 'eters'] +['P', 'ERT'] +['ex', 'press'] +['_pro', 'file'] +['Un', 'known'] +['Ġrev', 'olution'] +['.add', 'ress'] +['_re', 'quire'] +['Ġun', 'iform'] +['ĠP', 'ack'] +['l', 'ar'] +['ĠU', 'ITableView'] +['Ġdep', 'ends'] +['Valid', 'ation'] +['conf', 'irm'] +['O', 'wner'] +['Ġt', 'rib'] +['h', 'et'] +['ĠI', 'de'] +['ans', 'as'] +['L', 'anguage'] +['u', 'et'] +['ĠP', 'o'] +['ĠSte', 've'] +['Ġcont', 'est'] +['_DE', 'FAULT'] +['Ġapparent', 'ly'] +['RE', 'EN'] +['Ġfrequ', 'ently'] +['Ġtrad', 'ition'] +['ocol', 'ate'] +['S', 'I'] +['ĠArg', 'ument'] +['F', 'ocus'] +['ert', 'e'] +['ĠL', 'ayout'] +['Ġd', 'x'] +['Ġgener', 'ator'] +['ĠW', 'ait'] +['P', 'olicy'] +['l', 'ights'] +['.Ex', 'ecute'] +['P', 'y'] +['Ġbed', 'room'] +['ed', 'a'] +['ra', 'id'] +['ĉs', 'ize'] +['Ġan', 'cient'] +['Ġp', 'ump'] +['Ġd', 'w'] +['Ġ(!', '('] +['Ġspec', 'ify'] +['(', 'status'] +['ĠF', 'BI'] +['.ex', 'ception'] +['Ġrem', 'ark'] +['ly', 'mp'] +['ant', 'ee'] +['Up', 'load'] +['ern', 'et'] +['é', '¡'] +['in', 'ent'] +['ĠR', 'ender'] +['d', 'm'] +['ĠM', 'emory'] +['r', 'ich'] +['ĠT', 'ools'] +['Ġk', 'ne'] +['Ġper', 'm'] +['b', 'ad'] +['Ġd', 'inner'] +['.res', 'et'] +['Ġj', 'Label'] +['Fe', 'ature'] +['.S', 'ervice'] +['Ġ(', '{Ċ'] +['Ġre', 'ferred'] +['.class', 'List'] +['Ġinit', 'With'] +['ĠText', 'View'] +['Ġne', 'ither'] +['Ġcount', 'y'] +['Ġ"', '{'] +['ç', '§'] +['Ġt', 'ack'] +['class', 'Name'] +['ĠUS', 'ER'] +['Ġre', 'new'] +['`', '`'] +['get', 'Name'] +['Ġb', 'rown'] +['Err', 'ors'] +['ert', 'o'] +['Ġsust', 'ain'] +['S', 'O'] +['let', 'es'] +['ĠIn', 'valid'] +['Ġen', 'emies'] +['un', 'ge'] +['Ġexist', 'ence'] +['err', 'a'] +['Ċ', 'ĠĠĊ'] +['utor', 'ial'] +['#', 'a'] +['p', 'ay'] +['char', 'ge'] +['ĠI', 're'] +['ate', 'st'] +['Ġexp', 'los'] +['Ġf', 'ired'] +['N', 'ER'] +['ĠT', 'y'] +['ic', 'ion'] +['U', 'ri'] +['Ġobvious', 'ly'] +['ĠC', 'olum'] +["Ġ'", '+'] +['ĠDe', 'vice'] +['-', 'related'] +['_', 'ARG'] +['Ġv', 'or'] +['ĠLess', 'er'] +['_O', 'P'] +['Serial', 'izer'] +['Ġup', 'grade'] +['L', 'ight'] +['Ġc', 'odes'] +['++', ';čĊ'] +['Ġwrit', 'es'] +['fo', 'od'] +['Ġé', 't'] +['@', 'section'] +['Ġtrack', 's'] +['Ġserious', 'ly'] +['ch', 't'] +['(size', 'of'] +['Ġimmedi', 'ate'] +['Ġscient', 'ists'] +['Ġ{', '$'] +['_', 'ne'] +['.Anchor', 'Styles'] +['Ġaccom', 'mod'] +['ĠHar', 'ry'] +['Ġs', 'ight'] +['ĠPale', 'st'] +['ersist', 'ent'] +['Ġ', 'Ñĥ'] +['-', 'input'] +['Ġco', 'ordinates'] +['Â', '·'] +['W', 'elcome'] +['.con', 'f'] +['Ġgre', 'w'] +['Ġb', 'old'] +['ĠC', 'PU'] +['(m', 'y'] +['Ġperfect', 'ly'] +['Ġmom', 'ents'] +['ĠM', 'ovie'] +['-', 'data'] +['yst', 'al'] +['_W', 'IDTH'] +['ĠS', 'creen'] +['æ', 'Ŀ'] +['Ġdis', 'ap'] +['Ġredu', 'ction'] +['.Get', 'Component'] +['_M', 'ODULE'] +['Ġgener', 'ic'] +['Ġd', 'y'] +['all', 'er'] +['Ġc', 'url'] +['ĠB', 'ody'] +['Ġb', 'anks'] +[',', 't'] +['av', 'g'] +['Ġev', 'il'] +['Ġmanufact', 'urer'] +['Ġrece', 'iver'] +['Column', 's'] +['Ġing', 'redients'] +['ĉ', 'out'] +['qu', 'es'] +['.L', 'oad'] +['Ġslow', 'ly'] +['ĠT', 'own'] +['ĠC', 'ell'] +['_n', 'ormal'] +['_p', 'refix'] +['ĠAl', 'ert'] +['("', '{'] +['ä', 'r'] +['âĢľ', 'The'] +['ĠM', 'D'] +['Ġcour', 'ses'] +['ath', 'an'] +['é', 'Ļ'] +['oc', 'c'] +['ĠS', 'ER'] +['es', 'ign'] +['Add', 'r'] +['=', "['"] +['("', './'] +[']', '}'] +['.f', 'ont'] +['ĠInst', 'agram'] +['ĠB', 'order'] +['od', 'a'] +['Ġh', 'all'] +['Ġr', 'um'] +['_b', 'it'] +['Ġs', 'aving'] +['_d', 'own'] +['R', 'andom'] +['_reg', 'ister'] +['(', 'Context'] +['Ġoppos', 'ite'] +['R', 'oom'] +['Y', 'ES'] +['ан', 'и'] +['Ġenjoy', 'ed'] +['_r', 'un'] +['C', 'lear'] +['âĢ', 'ĺ'] +['ĠF', 'ord'] +['on', 'ic'] +['ost', 'en'] +['"]', ')'] +['_', 'auth'] +['//', 'čĊ'] +['Ġsuff', 'icient'] +['LE', 'S'] +['Ġph', 'en'] +['Ġo', 'h'] +['_c', 'sv'] +['Ġrout', 'ine'] +['.Are', 'Equal'] +['ay', 'lor'] +['Ġb', 'asket'] +['_COM', 'M'] +['rypt', 'ed'] +['S', 'im'] +['ĠSh', 'op'] +['Ġstud', 'io'] +['at', 'os'] +['(', 'W'] +['[', 'string'] +['ä', 't'] +['og', 'a'] +['Ġsh', 'r'] +['Ġs', 'ick'] +['An', 'other'] +['Ġdo', 'ors'] +['_N', 'E'] +['ĠTH', 'REE'] +['.', 'order'] +['raz', 'il'] +['Ġmap', 's'] +['_TR', 'UE'] +['trans', 'late'] +['Ġnear', 'by'] +['Ġn', 'ach'] +['LO', 'AT'] +['b', 'atch'] +['Ġl', 'ux'] +['ash', 'es'] +['ang', 'ers'] +['â̦', 'â̦'] +['_E', 'VENT'] +['_', 'UP'] +['Ġact', 's'] +['in', 'v'] +['_M', 'ETHOD'] +['cc', 'ion'] +['Ġret', 'ain'] +['ut', 'ch'] +['ĠÐ', '±'] +['Ġknow', 'ing'] +['Ġrepresent', 'ing'] +['N', 'OT'] +['p', 'ng'] +['Con', 'tract'] +['Ġtr', 'ick'] +['ĠE', 'dition'] +['uplic', 'ate'] +['Ġcontrol', 'led'] +['c', 'fg'] +['j', 'avascript'] +['Ġmil', 'k'] +['Wh', 'ite'] +['Se', 'quence'] +['aw', 'a'] +['Ġdiscuss', 'ed'] +['ĠB', 'ush'] +['ĠY', 'ES'] +['.f', 'actory'] +['t', 'ags'] +['Ġt', 'act'] +['Ġs', 'id'] +['$', '$'] +['ĠE', 'num'] +['Ġfr', 'ames'] +['}', ');'] +['Ġreg', 'ul'] +["']", ';čĊ'] +['Reg', 'ion'] +['ff', 'f'] +['Ġc', 'ro'] +['(', 'com'] +['="', '+'] +['St', 'udent'] +['Ġdis', 'appoint'] +['RES', 'ULT'] +['Count', 'er'] +['Ġbut', 'ter'] +['ĠH', 'a'] +['ĠD', 'igital'] +['Ġb', 'id'] +['">', '{{'] +['ing', 'ers'] +['ĠC', 'ountry'] +['_t', 'pl'] +['"]', ')Ċ'] +['/', 'k'] +['d', 'ating'] +[':', '#'] +['ĠD', 'ATA'] +['yn', 'chron'] +['_b', 'ody'] +['olly', 'wood'] +['Ġval', 'or'] +['ip', 'ient'] +['o', 'ft'] +['UB', 'L'] +['doc', 's'] +['Ġsyn', 'chron'] +['Ġform', 'ed'] +['ru', 'ption'] +['Ġlist', 'a'] +['Request', 'Mapping'] +['Ġvill', 'age'] +['Ġkn', 'ock'] +['oc', 's'] +['"', '{'] +['_fl', 'ags'] +['Ġtrans', 'actions'] +['Ġhab', 'it'] +['ĠJ', 'e'] +['ed', 'en'] +['Ġa', 'ircraft'] +['ir', 'k'] +['ĠA', 'B'] +['Ġfair', 'ly'] +['.', 'inter'] +['.A', 'ct'] +['Ġinstr', 'ument'] +['remove', 'Class'] +['.com', 'mand'] +['Ñ', 'ī'] +['ĉm', 'em'] +['(', 'min'] +['Ġo', 't'] +['Ġcol', 'le'] +['=', 's'] +['time', 'out'] +['Ġid', 's'] +['ĠM', 'atch'] +['ij', 'n'] +['z', 'ero'] +['Ġnetwork', 's'] +['.g', 'ov'] +['Ġint', 'el'] +['Ġsection', 's'] +['out', 'ine'] +['(c', 'md'] +['(d', 'ir'] +['ĠLI', 'ABILITY'] +['ĠB', 'log'] +['Ġbr', 'idge'] +['ĠC', 'V'] +['con', 'vert'] +['Ġ"', ')Ċ'] +['ĠB', 'ern'] +['_P', 'O'] +['e', 'val'] +['(', 'set'] +['to', 'ol'] +['Ġpay', 'ments'] +['Beh', 'aviour'] +['Ġcon', 'crete'] +['Ġel', 'ig'] +['Ġacc', 'eler'] +['Ġh', 'ole'] +['_', 'o'] +['TE', 'GER'] +['Ġgraph', 'ics'] +['O', 'wn'] +['Form', 'atter'] +['on', 'der'] +['Ġpack', 'ages'] +['/', 'a'] +['ĠK', 'now'] +['Or', 'Default'] +['Ġdut', 'y'] +['W', 'ait'] +['н', 'а'] +['_rec', 'ord'] +['[', 't'] +['M', 'esh'] +['Ġon', 'going'] +['.be', 'ans'] +['Ġt', 'an'] +['Ġinter', 'pret'] +['ast', 'ers'] +['QU', 'AL'] +['Ġleg', 's'] +['\\', 'Request'] +['-', 'file'] +['_m', 'utex'] +['ĠS', 'aint'] +['//', '#'] +['Ġpro', 'hib'] +['(', 'info'] +[':', '='] +['lin', 'ux'] +['Ġb', 'lo'] +['ot', 'ic'] +['ĉf', 'inal'] +['_ex', 'p'] +['ĠSt', 'op'] +['ap', 'ing'] +['(s', 'aved'] +['_p', 'ush'] +['Ġe', 'ase'] +['_F', 'R'] +['pons', 'ive'] +['str', 'cmp'] +[':', 'ĊĊĊĊ'] +['ä»', '¶'] +['ol', 'i'] +['Ġextrem', 'e'] +['Ġprof', 'essor'] +['Im', 'ages'] +['.IO', 'Exception'] +['Ġaddress', 'es'] +['plement', 'ed'] +['Ġincor', 'por'] +['Ġuse', 'Effect'] +['_O', 'F'] +['ĠD', 'a'] +['n', 'ombre'] +['IR', 'ST'] +['Ġdisc', 'rim'] +['Ġcomp', 'ens'] +['greg', 'ate'] +['anc', 'ell'] +['ach', 'es'] +['ĠC', 'riteria'] +['$', 'result'] +['D', 'estroy'] +['Ġsecond', 'ary'] +['W', 'atch'] +['ĠS', 'em'] +['ĠMc', 'C'] +['Ġacad', 'emic'] +['U', 'pper'] +['::', '~'] +['ut', 'ral'] +['ĠD', 'og'] +['ad', 'ed'] +['Valid', 'ator'] +['Ġder', 'ived'] +['Ġset', 'Timeout'] +['ĠK', 'en'] +['Ġtyp', 'ical'] +['ĠB', 'ob'] +['Ġb', 'ounds'] +['ĠSe', 'ason'] +['Ġc', 'razy'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠ'] +['-r', 'outer'] +['itt', 'est'] +['ĠM', 'ir'] +['Ġemot', 'ional'] +[',', 'v'] +['c', 'n'] +['/', 'st'] +['å', '½'] +['on', 'om'] +['Ġdecl', 'ared'] +['>', '.'] +['ail', 'ing'] +['Ġ/*', '<<<'] +['Ġnorm', 'ally'] +['(M', 'e'] +['ev', 'in'] +['lik', 'ely'] +['Ġpoint', 'ed'] +['ĠSt', 'ack'] +['Ġw', 'alls'] +['.', 'Vector'] +['me', 'an'] +[']', ']Ċ'] +['Ġlist', 'ening'] +['ad', 'v'] +['Ġsw', 'ap'] +['IF', 'T'] +['Ø', 'ª'] +['.', 'argv'] +['ul', 's'] +['<', 'option'] +['not', 'ations'] +['Ġemail', 's'] +['ĠU', 'kr'] +['ast', 'a'] +['ĠTh', 'us'] +['ĠSt', 'one'] +['Ġappe', 'al'] +['.', 'âĢĻ'] +['Ġreg', 'ulations'] +['Pre', 'ferences'] +['ĠPh', 'one'] +['ul', 'f'] +['ĠD', 'R'] +['Ġtechn', 'ologies'] +['Ġpar', 'agraph'] +['Ġnecess', 'arily'] +['.e', 'ach'] +['<', 'float'] +['res', 'a'] +['Ġunder', 'st'] +['Ġf', 'inger'] +['press', 'ed'] +['-b', 'y'] +['if', 'fer'] +['w', 'atch'] +['ĠB', 'a'] +['A', 'IM'] +['Ġwe', 'ights'] +['ĠR', 'on'] +["')", '}}'] +['[', 'self'] +['--------', '--Ċ'] +['per', 'iment'] +['Ġto', 'String'] +['x', 'ic'] +['ĠC', 'amera'] +['!', 'ĊĊĊĊ'] +['aur', 'ant'] +['P', 'refix'] +['Ġinstit', 'utions'] +[':', 'int'] +['Ġex', 'posure'] +['p', 'attern'] +['ĠLin', 'ux'] +['.n', 'umber'] +['red', 'ient'] +['Argument', 'Exception'] +['ĠCh', 'ief'] +['"', '},'] +['Ġelect', 'ronic'] +['r', 'ong'] +['er', 'd'] +['sp', 'Net'] +['ra', 'it'] +['/', "',"] +['ĠOh', 'io'] +['Cont', 'rollers'] +['Ġcontin', 'uing'] +['ĠT', 'emplate'] +['ĠE', 'th'] +['s', 'z'] +['/', 'env'] +['En', 'v'] +['%', '.'] +['art', 'ers'] +[')', '(('] +['ĠT', 'ABLE'] +['ĠÃ', '®'] +['per', 'ature'] +['pro', 'gress'] +['P', 'res'] +['ê', '°'] +['im', 'plementation'] +['Ġb', 'ien'] +['Ġstre', 'ets'] +['_M', 'SG'] +['New', 's'] +['##', '#'] +[':', '/'] +['Ġcut', 'ting'] +['x', 'B'] +['ress', 'ed'] +['_EN', 'ABLE'] +['l', 'ab'] +['Ġca', 'using'] +[']', '));Ċ'] +['b', 'ra'] +['x', 'FFFF'] +['il', 'ly'] +['plet', 'ion'] +['w', 'ill'] +['_b', 'ar'] +['Ġstruct', 'ures'] +['ĠI', 'mp'] +['Û', 'Į'] +['Ġ<', '>'] +['Ġ', '----------------'] +['_B', 'UFFER'] +['.d', 'ir'] +['Ġpl', 'ain'] +['Ġpe', 'er'] +['g', 'g'] +['oint', 's'] +['Ġsomew', 'hat'] +['Ġw', 'et'] +['Ġemploy', 'ment'] +['Ġtick', 'ets'] +['ir', 'ms'] +['Ġt', 'uple'] +['s', 'is'] +['$', 'sql'] +['r', 'ig'] +['Ġcon', 'version'] +['Ġg', 'es'] +['Ġconfig', 'ure'] +['eg', 'r'] +['ĠC', 'a'] +['Ġ__', "('"] +['ou', 'ston'] +['.t', 'oken'] +['Bl', 'ack'] +['Ġmag', 'azine'] +['A', 'W'] +['.', 'IN'] +['os', 'ing'] +['Ġbro', 'ke'] +['ĠC', 'ru'] +['DE', 'LETE'] +['Ġdestroy', 'ed'] +['(M', 'ath'] +['Ġappro', 'val'] +['-d', 'om'] +['ĠI', 'II'] +['table', 'View'] +['Ġdesign', 's'] +['Ġcrush', 'ing'] +['Ġcons', 'ent'] +['dir', 'name'] +['om', 'p'] +['Ġc', 'rypt'] +['?', '('] +['or', 'ough'] +['.', 'o'] +['ĉ', 'list'] +['ams', 'ung'] +['.""', '"Ċ'] +['err', 'ing'] +['G', 'oogle'] +['_p', 'air'] +['_IN', 'IT'] +['rem', 'arks'] +['Ġg', 'ear'] +['F', 'ill'] +['l', 'ife'] +['}', '")Ċ'] +['Ġsuit', 'able'] +['Ġsurpr', 'ised'] +['_RE', 'QUEST'] +['Ġman', 'ifest'] +['att', 'en'] +['Ġfr', 'ustr'] +['ov', 'ement'] +['.c', 'lick'] +['Ġi', 'i'] +['Ġexp', 'ansion'] +['ig', 's'] +['P', 'arse'] +['.Reg', 'ular'] +['R', 'ob'] +['_l', 'ayout'] +['ì', 'ł'] +['Ġtrans', 'lation'] +['ĠBe', 'aut'] +['B', 'est'] +['_C', 'OLOR'] +['<', 'label'] +['Ġliqu', 'id'] +['IT', 'S'] +['Ġpro', 'd'] +['Ġoper', 'ate'] +['UI', 'Kit'] +['Ġn', 'atur'] +['arg', 'ument'] +['_d', 'etail'] +['ĠCent', 're'] +['Ġ"', '--'] +['Ġ}}', '"'] +['lo', 'cale'] +['.t', 'v'] +['_se', 'q'] +['Ġup', 'coming'] +['Ch', 'art'] +['ĠDiv', 'ision'] +['Ġclin', 'ical'] +['Com', 'pany'] +['S', 'epar'] +['l', 'as'] +['ĠH', 'un'] +[':', 's'] +['Ġhead', 'ing'] +['оÐ', '³'] +['Ġ"', '");Ċ'] +['[', 'id'] +['b', 'ia'] +['Ġst', 'retch'] +['ic', 'ide'] +['Ġre', 'produ'] +['.pro', 'ject'] +['leg', 'end'] +['end', 'ers'] +['Ġrespons', 'es'] +['Ġon', 't'] +['rit', 'ical'] +['Ġref', 'uge'] +['ĠL', 'i'] +['Ġ:', 'ĊĊ'] +['ĠTh', 'ree'] +['.cont', 'roller'] +['_IN', 'DEX'] +['_F', 'OR'] +['\\Model', 's'] +['j', 'ax'] +['ĉex', 'it'] +['Ġâ', 'ĸ'] +['Ġc', 'overs'] +['ĉ', 'y'] +['-', '.'] +['IND', 'OW'] +['Ġfail', 's'] +['in', 'cludes'] +['Ġf', 'ault'] +['Ġl', 'y'] +['ñ', 'o'] +['.s', 'lice'] +['ILE', 'D'] +['ĠP', 'ur'] +['ĠAs', 'ian'] +['_b', 'atch'] +['.M', 'ax'] +['v', 'l'] +['ĠCOPY', 'RIGHT'] +['Ġg', 'iant'] +['ĠMan', 'ual'] +['ĠC', 'opy'] +['Class', 'Name'] +['He', 'alth'] +['C', 'ursor'] +['IB', 'Outlet'] +['Ġt', 'we'] +['æ', '³'] +['_label', 's'] +['Ġcol', 'lected'] +['Ġfurn', 'iture'] +['Ġdeal', 'ing'] +['Control', 's'] +['ĠHot', 'el'] +['ck', 's'] +['Ġch', 'ose'] +['âĶ', 'Ģ'] +['od', 'd'] +['S', 'R'] +['Ù', 'Ĭ'] +['ì', 'Ħ'] +['Ġacc', 'ord'] +['ĠM', 'ove'] +['ĠM', 'ode'] +['ĠM', 'ock'] +['Ġthread', 's'] +['++', '++'] +['ĠO', 'ptions'] +['Ref', 'resh'] +['ĠD', 'id'] +["']", '->'] +['u', 'cc'] +['_ch', 'annel'] +['.', 'abs'] +['Ġ{', '},Ċ'] +['ĠW', 'al'] +['er', 'ior'] +['Ġmain', 'ly'] +['ĠDr', 'iver'] +['NotFound', 'Exception'] +['Ġcount', 's'] +['e', 'am'] +['Ġ&', '='] +['Q', 'uestion'] +['ĠA', 'li'] +['Ġany', 'more'] +['d', 'etail'] +['t', 'ail'] +['Ġm', 'ile'] +['ĠF', 'air'] +['Ġs', 'orry'] +['Ġsurround', 'ing'] +['Ġad', 'm'] +['De', 'v'] +['Ġmari', 'juana'] +['ĠS', 'ound'] +['ĠA', 'sh'] +['F', 'D'] +['Te', 'am'] +['.', 'port'] +['Ġ[', ']ĊĊ'] +['ub', 'ble'] +['Ġas', 'c'] +['Ġint', 'ention'] +['A', 'cc'] +['ch', 'i'] +['ust', 'ers'] +['Ġins', 'pired'] +['se', 'g'] +['CL', 'U'] +['Ġman', 'ip'] +['M', 'etadata'] +['Con', 'nect'] +['ĠB', 'eh'] +['Ġfind', 'ings'] +['Ġas', 'sembly'] +['w', 'orld'] +['Ġrem', 'ained'] +['Ġu', 'id'] +['(', '.'] +['Ġm', 'x'] +['Lo', 'op'] +['ĊĊĊĊ', 'Ċ'] +['Ġfant', 'astic'] +['wh', 'o'] +['ak', 'i'] +['ĠB', 'asic'] +['ĠY', 'et'] +['ĠUs', 'ers'] +['ik', 'ip'] +['Ġhead', 's'] +['ĠMich', 'igan'] +['_', 'it'] +['ĠTor', 'onto'] +['Ġrec', 'ording'] +['Ġsub', 'mitted'] +['_var', 'iable'] +['medi', 'ate'] +['.graph', 'ics'] +['Ġst', 'ood'] +['Ġre', 'ar'] +['vel', 'ocity'] +['_M', 'ESSAGE'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['ro', 'les'] +['ĠT', 'our'] +['_', 'year'] +['end', 'ment'] +['amp', 's'] +['ĠIre', 'land'] +['m', 'al'] +['Ġyoung', 'er'] +['Ġstrugg', 'le'] +['Ġc', 'able'] +['ĠSD', 'L'] +["('", '-'] +['an', 'es'] +['ĠNe', 'ed'] +['.R', 'ow'] +['P', 'ol'] +['ĠP', 'H'] +['_s', 'cript'] +['ag', 'em'] +['ĠB', 'as'] +['_s', 'pace'] +['.', 'loc'] +[':', 'i'] +['ad', 'r'] +['Ġengine', 'ering'] +['it', 'en'] +[')', '&'] +['Ġu', 'k'] +['ĠL', 'ittle'] +['_C', 'OUNT'] +['x', 'A'] +['Array', 'List'] +['æ', 'į'] +['Ġ"', '")Ċ'] +['An', 'chor'] +['Ġh', 'ang'] +['t', 'witter'] +['Ġcompet', 'itive'] +['.s', 'rc'] +['ãģ', 'Ĺ'] +['Ġtrans', 'late'] +['ĠCre', 'ates'] +['ook', 's'] +['ĠR', 'oll'] +["''", "'Ċ"] +['/', 'sh'] +['s', 'ome'] +['Enc', 'oding'] +['.res', 'olve'] +['Ġdesign', 'er'] +['ĠSt', 'orage'] +['Ġz', 'a'] +['ĠN', 'ever'] +['Ġsomew', 'here'] +['Ġbox', 'es'] +['.s', 'ource'] +['Ġpy', 'game'] +['Ġgrow', 'n'] +['.t', 'w'] +['()', '),Ċ'] +["',", "['"] +['Ġoppon', 'ent'] +['(s', 'rc'] +['.l', 'ayer'] +['AP', 'P'] +['ĠAct', 'iv'] +['Ġguest', 's'] +['ĠVAL', 'UES'] +['};ĊĊ', 'Ċ'] +['.n', 'ative'] +['Ġamount', 's'] +['.', 'RE'] +['Ġcl', 'one'] +['Ġwer', 'en'] +['Ġ"', '<<'] +['_', 'ac'] +['Ġbreak', 'ing'] +['Ġreli', 'able'] +['.P', 'OST'] +['ĠSk', 'y'] +["Ġ'", '&'] +['Ġsaved', 'InstanceState'] +['ast', 'ing'] +['ill', 'ion'] +['com', 'ments'] +['ult', 'y'] +['.m', 'enu'] +['/', 'config'] +['Ġ', 'ĊĊĊ'] +['T', 'ODO'] +['Ġpurch', 'ased'] +['_c', 'or'] +['ĉ', 'auto'] +['Compat', 'Activity'] +['com', 'plete'] +['_', 'graph'] +['is', 'odes'] +['Ġsitu', 'ations'] +['ĠH', 'or'] +['Re', 'ceive'] +['âĢľ', 'We'] +['Ġent', 'ities'] +['.assert', 'Equals'] +['оÐ', 'º'] +['ĠS', 'ans'] +['v', 'ince'] +['rom', 'pt'] +['=', 'Ċ'] +['Ġ/', '.'] +['.Se', 'lect'] +['yl', 'v'] +['Ġb', 'att'] +['A', 'udio'] +['Ġincreasing', 'ly'] +['.B', 'undle'] +['Ġexpl', 'ains'] +['the', 'ast'] +['.', 'offset'] +['Ġh', 'al'] +['Ġtechn', 'ique'] +['_l', 'imit'] +['Ġdraw', 'n'] +['AY', 'ER'] +['Ġfeature', 'd'] +['yy', 'yy'] +['at', 'in'] +['ph', 'en'] +['ach', 'el'] +['!', '\\'] +['l', 'ower'] +['ĠG', 'R'] +['Ġp', 'ag'] +['ĠP', 'arse'] +['Ġt', 'ou'] +['ä¸', 'Ģ'] +['D', 'istance'] +['Index', 'Path'] +['Ġh', 'ell'] +['s', 'im'] +['UT', 'TON'] +['Us', 'age'] +['elen', 'ium'] +['ĠF', 'all'] +['Ġ"', '.$'] +['ĠM', 'u'] +['Ġcr', 'uc'] +['Ġs', 'ont'] +['REF', 'IX'] +['Ġinter', 'ior'] +['ĠO', 'lymp'] +['.Auto', 'Scale'] +['par', 'a'] +['Axis', 'Alignment'] +['Ġr', 'iver'] +['D', 'to'] +['Ġwith', 'draw'] +['Re', 'act'] +['-', 'class'] +['b', 'efore'] +['_', 'alloc'] +['Cont', 'ents'] +['ĠW', 'as'] +['I', 'CT'] +['Ġform', 'ula'] +['Ġindic', 'ates'] +['ĠĠĠĠ', 'ĊĊ'] +['_st', 'ore'] +['it', 'ting'] +['ĠIt', 'alian'] +['_S', 'et'] +['_re', 'port'] +['Ġp', 'id'] +['_V', 'ER'] +['Ġw', 'ins'] +['ĠCl', 'oud'] +['")', '{Ċ'] +['ch', 'ester'] +['Ġden', 'ied'] +['Ġw', 'ird'] +['ĠSte', 'p'] +['Ġinvest', 'ors'] +['b', 'old'] +['_d', 'isplay'] +['ou', 'ver'] +['or', 'er'] +['Res', 'et'] +['Ġsurg', 'ery'] +['Ġstrateg', 'ies'] +['/m', 'aterial'] +['_', 'unit'] +['Ġc', 'ouncil'] +['.P', 'er'] +['ĠâĢ', 'ŀ'] +['Ġre', 'form'] +['F', 'ramework'] +['Ġlist', 'ing'] +['_b', 'tn'] +['Ġb', 'is'] +['%', 'd'] +['eg', 'as'] +['Ġsudden', 'ly'] +['_S', 'ER'] +['Ġa', 'o'] +['_d', 'irectory'] +['f', 'as'] +['Ġprem', 'ium'] +['Ġtrack', 'ing'] +['ĠB', 'L'] +['Ġm', 'ature'] +['Ġbath', 'room'] +["Ġ'/", "'"] +['ĠÄ', 'ij'] +['Per', 'formed'] +['Ġsold', 'iers'] +['arn', 'ings'] +['Ġwalk', 'ed'] +['-', 'con'] +['b', 'ottom'] +['Ġsurpr', 'ising'] +['Ġg', 'ene'] +['Us', 'uario'] +['.DE', 'FAULT'] +['ĠM', 'IT'] +['C', 'ODE'] +['ĠE', 'gypt'] +['p', 'icker'] +['ys', 'ql'] +['AT', 'URE'] +['d', 'etails'] +['ĠCon', 'ference'] +['In', 'formation'] +['ĠM', 'ail'] +['-d', 'own'] +['r', 'aries'] +['b', 'ro'] +['Ġsubject', 's'] +["Ġ'", '*'] +['è¯', '·'] +['or', 'ient'] +[':', '@'] +['ver', 'bose'] +['E', 'F'] +['Ġto', 'ler'] +['eng', 'ers'] +['Ġend', 'point'] +['Ġstr', 'ange'] +['Ġcol', 'on'] +['Ġpre', 'ferred'] +['de', 'p'] +['ĠE', 'V'] +['ARR', 'AY'] +['Ġw', 'he'] +['Ġp', 'up'] +['_n', 'odes'] +['Ġtalk', 'ed'] +['Ġinstit', 'ution'] +['db', 'c'] +['Ġex', 'posed'] +['te', 'en'] +['ĠFr', 'ont'] +['T', 'T'] +['_N', 'ONE'] +['\\/', '\\/'] +['pro', 'gram'] +['Ġencour', 'age'] +['.', '`'] +['sh', 'ire'] +['ĠIsl', 'am'] +['e', 'en'] +['N', 'I'] +["'", '"'] +['.W', 'idth'] +['Ġlik', 'ed'] +['Ġ{', '...'] +['ĠSystem', 's'] +['Ġvot', 're'] +['Ġmanufact', 'uring'] +['Con', 'verter'] +['ĠIn', 'f'] +['ì', 'ļ'] +['D', 'TO'] +['Ġin', 'ches'] +['Ġ', 'à¤'] +['Ã', '¹'] +['ĠChar', 'les'] +['B', 'U'] +['"))', ';ĊĊ'] +['ĠL', 'abor'] +['un', 'n'] +['Ġest', 'im'] +['m', 'obile'] +['ĠL', 'earn'] +['_C', 'ALL'] +['â', 'Ħ'] +['Ġind', 'ices'] +['Ġt', 'ub'] +['ikip', 'edia'] +['C', 'ost'] +['row', 'able'] +['ë', '¡'] +['g', 'age'] +['Ġfunction', 'ality'] +['uzz', 'le'] +['em', 'os'] +['.l', 'ib'] +['Ġd', 'ass'] +['еÐ', 'º'] +['enn', 'a'] +['Ġsh', 'ots'] +['Ġrest', 'ore'] +['/', 'D'] +['For', 'Key'] +['],', '['] +['al', 'ias'] +['l', 'int'] +['.st', 'ream'] +['æ', 'ł'] +['_FORM', 'AT'] +['Ġsil', 'ver'] +['.re', 'pository'] +['Ġlegis', 'l'] +['.B', 'order'] +['_fe', 'atures'] +['Per', 'mission'] +['Ġhous', 'es'] +['ĠW', 'ars'] +['_COM', 'P'] +['Ġinj', 'uries'] +['Ġconstant', 'ly'] +['fl', 'utter'] +['EN', 'U'] +['ĠCon', 'f'] +['Ġrecogn', 'ized'] +['Ġpract', 'ical'] +['Ġde', 'cent'] +['B', 'J'] +[']', ');'] +['ast', 'y'] +['ĠAct', 'ivity'] +['-m', 'ode'] +['Ġsl', 'ide'] +['.IsNullOr', 'Empty'] +['ĠY', 'OU'] +['P', 'ower'] +['ind', 'ices'] +['Ġqual', 'ified'] +['Ġthrow', 'n'] +['h', 'ello'] +['ĠN', 'ick'] +['l', 'ah'] +['as', 'sembly'] +['ĠSm', 'all'] +['old', 'ing'] +['Sh', 'ould'] +['ĠSil', 'ver'] +['(saved', 'InstanceState'] +['Ġtog', 'gle'] +['.N', 'ot'] +['C', 'trl'] +[':', 'nil'] +['ĠCont', 'inue'] +['ĠB', 'oot'] +['æ', 'ī'] +['ĠM', 'ur'] +['d', 'on'] +['ĠF', 'A'] +['S', 'napshot'] +['Ġassoci', 'ation'] +['fo', 'x'] +[',', 'a'] +['az', 'ione'] +[']', ')čĊ'] +['CT', 'YPE'] +['Ġf', 'ade'] +['ĠD', 'ar'] +['.n', 'avigation'] +['Ġl', 'uck'] +['SC', 'RI'] +['ĠDe', 'ad'] +['Ġterm', 'inal'] +['_LE', 'NGTH'] +['Ġeff', 'iciency'] +['Ġun', 'w'] +['Ġn', 'arrow'] +['iment', 'o'] +['(', 'Color'] +['ĠSe', 'a'] +['_', 'area'] +[',', 'A'] +['_', 'opt'] +['ĠHill', 'ary'] +['.t', 'ask'] +['ĠJ', 'ac'] +['ast', 'ed'] +['ĠAd', 'am'] +['ĠIl', 'legal'] +['Ġsearch', 'ing'] +['Instance', 'Of'] +['J', 'ava'] +['ĠForm', 'at'] +['Ġreal', 'ized'] +['ĠChild', 'ren'] +['Ġk', 'il'] +['(f', 'rame'] +['âĢĿ', '.ĊĊ'] +['Ġscen', 'ario'] +['"]', ');Ċ'] +['Ġincred', 'ible'] +['li', 'x'] +['IO', 'Exception'] +['ĠQ', 'uest'] +['il', 'ty'] +['Ġun', 'lock'] +['â', 'Ĥ¬'] +['Ġre', 'ferences'] +['ĠV', 'ert'] +['B', 'inding'] +['eg', 'ative'] +['Ġwr', 'ap'] +['.d', 'atabase'] +['(', 'content'] +['B', 'uf'] +['ĠTr', 'ad'] +['ĠA', 'ud'] +['tr', 'ace'] +['.m', 'ock'] +['Ġther', 'apy'] +['ĉ', 'L'] +['.To', 'Int'] +['ĠKing', 'dom'] +['B', 'us'] +['ha', 'ust'] +['""', '"ĊĊ'] +['(', 'end'] +['.draw', 'able'] +['[', '];Ċ'] +['ĠH', 'ospital'] +['Ġph', 'arm'] +['----', '-'] +['ĠA', 'G'] +['é', 'd'] +['>', '");Ċ'] +['Ġw', 'allet'] +['at', 'able'] +[')', '$'] +['Ġmonth', 'ly'] +['Ġdi', 'agnostic'] +['S', 'ymbol'] +['Ġiter', 'ator'] +['un', 'finished'] +['Ġimm', 'igration'] +['s', 'r'] +['RO', 'W'] +['(g', 'ame'] +['Ġclo', 'thes'] +['ĠU', 'nt'] +['Ġactiv', 'ation'] +['_C', 'on'] +['.h', 'ash'] +['Ġinitial', 'ly'] +['.H', 'ash'] +['Ġcut', 's'] +['f', 'ound'] +['ĠSt', 'ory'] +['ÑĨ', 'и'] +['ac', 'ao'] +['_T', 'YP'] +['pro', 'to'] +['est', 'r'] +['-p', 'age'] +['ah', 'r'] +['Ġincor', 'rect'] +['ĠJose', 'ph'] +['TextBox', 'Column'] +['_st', 'yle'] +['ĠD', 'aniel'] +['s', 'heet'] +['Ġl', 'iv'] +['l', 'ined'] +['Ġr', 'a'] +['R', 'untime'] +['_', 'empty'] +['sl', 'ug'] +['_', 'struct'] +['ë', 'Ĭ'] +['m', 'u'] +['Ġper', 'mitted'] +['Ġreg', 'ional'] +['Ġsob', 're'] +['ĠS', 'uch'] +['Ġ[', '_'] +['Ġro', 'of'] +['.Al', 'ignment'] +['t', 'imes'] +['.m', 'sg'] +['Ġche', 'st'] +['ĠT', 'ab'] +['Ġest', 'a'] +['ä', 'n'] +['Ġsubs', 'cription'] +['(', 'command'] +['s', 'pecial'] +['Ġme', 'al'] +['")', ':Ċ'] +['_', 'ctx'] +['Ġclos', 'ely'] +['et', 'ry'] +['-', 'be'] +['ad', 'el'] +['ĠR', 'am'] +['ig', 'est'] +['ĠSpan', 'ish'] +['Ġcommit', 'ment'] +['Ġw', 'ake'] +['*', '>('] +['P', 'HP'] +['_', '{'] +['ck', 'er'] +['<', 'List'] +['_n', 'ull'] +['ĠRes', 'erved'] +['Ġin', 'her'] +['.Column', 's'] +['.A', 'spNet'] +['_IN', 'VALID'] +['ĠParam', 'eter'] +['Ġex', 'pr'] +['}', '{'] +['Cell', 'Style'] +['Ġval', 'uable'] +['Ġfun', 'ny'] +['In', 'v'] +['Ġst', 'able'] +['*', 't'] +['Ġp', 'ill'] +['pl', 'iers'] +['ĠC', 'SS'] +['ĠCon', 'dition'] +['ĠS', 'peed'] +['ublish', 'er'] +['Ġoff', 'ensive'] +['ce', 'st'] +['ic', 'as'] +['Ġsp', 'ark'] +['ĠPro', 'te'] +['set', 'up'] +['IF', 'Y'] +['ĠT', 'ax'] +['Wh', 'o'] +['F', 'amily'] +['-', 'for'] +['.', 'uk'] +['Ġf', 'asc'] +['sv', 'g'] +['")', ').'] +['Ġbirth', 'day'] +['âĸ', 'Ī'] +['ve', 'h'] +['el', 'led'] +['Ġimport', 's'] +['ĠIsl', 'amic'] +['T', 'A'] +['ĠSt', 'an'] +['we', 'ather'] +['Ġsus', 'pect'] +['e', 'ature'] +['enn', 'es'] +['W', 'M'] +['.m', 'inecraft'] +['av', 'id'] +['è', '½'] +['.se', 'curity'] +['in', 'os'] +['G', 'ood'] +['Ġm', 'arch'] +['Ġposs', 'ess'] +['us', 'uario'] +['Con', 's'] +['am', 'ber'] +['ched', 'uler'] +['Ġhor', 'se'] +['ç', '½'] +['(b', 'ody'] +['ĠTrans', 'form'] +['_de', 'code'] +['.s', 'vg'] +['Ġf', 'oo'] +['Ġd', 'ella'] +['ext', 'ends'] +['am', 'er'] +['Ġprocess', 'ed'] +['ĠH', 'arr'] +['ĠA', 'I'] +['Ġk', 'o'] +['CH', 'AR'] +['(', '%'] +['Ġt', 'ap'] +['({', "'"] +['c', 'roll'] +['D', 'OM'] +['Ġte', 'a'] +['Ġre', 'in'] +['Ġworld', 'wide'] +['_f', 'n'] +['sh', 'a'] +['Ġb', 'ir'] +['ç', 'ões'] +['="#', '">'] +['Ġrepresent', 'ed'] +['ill', 'er'] +['(ex', 'pected'] +['Ġd', 'ance'] +['Ġvisit', 'ors'] +['.con', 'cat'] +['-b', 'it'] +['UR', 'RE'] +['ĠR', 'og'] +['v', 'p'] +['ip', 'h'] +['ĠL', 'LC'] +['it', 'led'] +['iam', 'i'] +['C', 'oll'] +['_re', 'al'] +['_sh', 'ow'] +['_f', 'older'] +['Ġd', 'ar'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġl', 'atter'] +['arch', 'y'] +['Ġb', 'ow'] +['Ġout', 'come'] +['ĠPost', 'ed'] +['Ġris', 'ks'] +['ĠThere', 'fore'] +['Ġowners', 'hip'] +['Ġpar', 'allel'] +['Ġp', 'ending'] +['ge', 'ometry'] +['Ġrecogn', 'ize'] +['ST', 'EM'] +['ĠC', 'P'] +['Ġimm', 'igr'] +['IT', 'LE'] +['ĠĠĠĠ', 'ĉĉ'] +['conn', 'ected'] +['Ġsm', 'ile'] +['(d', 'ocument'] +['\\', 'Component'] +['vert', 'ical'] +['Ġconsum', 'ption'] +['Ġsh', 'oes'] +['.', 'impl'] +['un', 'ks'] +['.', '";Ċ'] +['Ġfood', 's'] +['_', ');Ċ'] +['.assert', 'True'] +['Ġp', 'ipeline'] +['Ġcollection', 's'] +['Ġearn', 'ed'] +['ĠC', 'ert'] +['Ġpartners', 'hip'] +['(', 'action'] +['Ġc', 'd'] +['ĠV', 'ery'] +['Option', 'al'] +['Ġscre', 'ens'] +['Ġtit', 'les'] +['ener', 'ator'] +['Ġab', 'andon'] +['k', 'ind'] +['IL', 'TER'] +['Ġclos', 'ing'] +['lic', 'a'] +['_', 'inter'] +['Ġcamp', 'us'] +['set', 'ting'] +['S', 'prite'] +['ãģ', '¯'] +['_re', 'ply'] +['To', 'List'] +[':', '\\/\\/'] +['ed', 'e'] +['Ġfol', 'ks'] +['Ġbo', 'at'] +['(', 'argv'] +['Ġperman', 'ent'] +['Ġcarry', 'ing'] +['Ġconserv', 'ative'] +['import', 'ant'] +['.', 'img'] +['ĠIm', 'm'] +['Ġdim', 'ensions'] +['al', 'and'] +['s', 'ingle'] +['Ex', 'it'] +['--------', '--'] +['ari', 'ant'] +['tern', 'al'] +['Se', 'conds'] +['ĠIt', 'aly'] +['ot', 'lin'] +['.Res', 'ume'] +["='", '"'] +[')', '=='] +['cept', 'or'] +['Ġs', 'ca'] +['/m', 'ain'] +['Sec', 'urity'] +['_d', 'at'] +['Ġlet', 's'] +['Ġa', 'qu'] +['Ġwhen', 'ever'] +['b', 'erry'] +['Ġact', 'ing'] +['ant', 'i'] +['p', 'd'] +['&', 'gt'] +['æ', 'Ń'] +['Z', 'one'] +['T', 'oday'] +['!', '.'] +['To', 'Props'] +['ab', 'is'] +['it', 'able'] +['Ġg', 'al'] +[']', '{'] +['iz', 'ona'] +['Ġin', 'contri'] +['N', 'ET'] +['///', 'Ċ'] +['[', 'in'] +['_s', 'ave'] +['Ġex', 'em'] +['ĠK', 'enn'] +['Ġev', 'olution'] +['var', 's'] +['_st', 'ats'] +['-', 'only'] +['ĠColor', 'ado'] +['Ġwatch', 'ed'] +['b', 'our'] +['Ġsever', 'e'] +['Ġprofession', 'als'] +['port', 'ion'] +['Ġguar', 'ante'] +['Ð', '³'] +['Ġpush', 'ed'] +['ĠG', 'i'] +['ï', '½'] +['Ġt', 'um'] +['ĠA', 'z'] +['ĠEdge', 'Insets'] +['"))', ';čĊ'] +['is', 'se'] +['.', 'ac'] +['Set', 'ting'] +['Ġapprec', 'iate'] +['ĠValue', 'Error'] +['Ġsur', 've'] +['ĠR', 'ole'] +['.', 'Inter'] +['plot', 'lib'] +['j', 'et'] +['d', 'am'] +['Ġplatform', 's'] +['te', 'le'] +['UT', 'O'] +['ĠInt', 'ernal'] +['+', ':'] +['}', ';čĊ'] +['Gener', 'al'] +['\\', 'Entity'] +['Ġlawy', 'er'] +['qu', 'iv'] +['ĠPost', 's'] +['is', 'o'] +['Ġacc', 'um'] +['ob', 'e'] +['Ġmark', 's'] +['Ġ]', ';ĊĊ'] +['ĉ', 'text'] +['.s', 'uccess'] +['cur', 'r'] +['as', 'a'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġth', 'in'] +['_', 'over'] +['are', 'st'] +['ĠO', 's'] +['(', 'address'] +['Ġvel', 'ocity'] +['Ġ[]', ';ĊĊ'] +['="', '../../'] +['ĠPr', 'iv'] +['b', 'ow'] +['Ġguar', 'antee'] +['%', 'ĊĊ'] +['Ġeval', 'uate'] +['.LE', 'NGTH'] +['Ġin', 'ventory'] +['q', 'a'] +['_de', 'bug'] +['.On', 'ClickListener'] +['Ġl', 'ies'] +['Ġassess', 'ment'] +['dat', 'etime'] +['.background', 'Color'] +['Ġ*/', 'čĊčĊ'] +['ra', 'f'] +['un', 'wrap'] +['ĠF', 'oot'] +['Ġnot', 'ify'] +['Ġlow', 'est'] +['DO', 'CTYPE'] +['Ġl', 'anguages'] +['ex', 'tra'] +['-', 'back'] +['Ġein', 'en'] +['tem', 'plates'] +['_p', 'ass'] +['ĠM', 'ust'] +['Ġest', 'á'] +['_c', 'ore'] +['ĠSc', 'ot'] +['A', 'I'] +['Ġb', 'ias'] +['ations', 'hip'] +['Con', 'stant'] +['Ġprogram', 'ming'] +['In', 's'] +['uspend', 'Layout'] +['ĠPRO', 'VID'] +['ant', 'es'] +['Ġsh', 'irt'] +['in', 'ated'] +['.', 'OK'] +['[', 'a'] +['Ġthink', 's'] +['?', 'ĊĊĊĊ'] +['Ġregard', 'less'] +['ĠMag', 'ic'] +['ul', 'ating'] +['ĉ', 'class'] +['add', 'Group'] +['RE', 'ATE'] +['ĠS', 'U'] +['Ġsim', 'pl'] +['c', 'opyright'] +['Ġb', 'unch'] +['Ġun', 'iverse'] +['ĠE', 'rr'] +['Ġpresent', 'ation'] +['c', 'ategories'] +['Ġatt', 'ach'] +['.s', 'ign'] +['_A', 'C'] +['Ġdisc', 'ipl'] +['Ġregular', 'ly'] +['Ġprim', 'arily'] +['ink', 's'] +['[', '['] +['.r', 'and'] +['.sh', 'ould'] +['ownt', 'own'] +['="', "'"] +['Ġs', 'ans'] +['Ġsupport', 'ers'] +['se', 'quence'] +['G', 'O'] +['.', '.ĊĊ'] +['ĠS', 'pr'] +['Ġcare', 'fully'] +['U', 'IColor'] +['dest', 'roy'] +['Ġtod', 'os'] +['ĠOR', 'DER'] +['ott', 'ed'] +['Ġd', 'ont'] +['aud', 'i'] +['_', 'player'] +['g', 're'] +['ĠO', 'il'] +['<', 'body'] +['_st', 'ack'] +['.P', 'adding'] +['ĠProduct', 's'] +['Ġpriv', 'ile'] +['Ġinj', 'ured'] +['ĠF', 'urther'] +['Ġal', 'ias'] +['.Resume', 'Layout'] +['_LE', 'N'] +['Ġs', 'es'] +["']", ';ĊĊ'] +['cre', 'ens'] +['Ġdirect', 'ed'] +['.S', 'uspendLayout'] +['od', 'ge'] +['.A', 't'] +['mark', 's'] +['ĠUn', 'ivers'] +['ert', 's'] +['ĠE', 'sc'] +['Ġnav', 'bar'] +['Ġutil', 'ity'] +['agnost', 'ics'] +['Ġin', 'ject'] +['ĠD', 'NA'] +['Ġ"', ',"'] +['am', 'ar'] +['Ġe', 'u'] +['Ġrestaur', 'ants'] +['_p', 'ut'] +['ut', 'ers'] +['Tool', 'Strip'] +['t', 'w'] +['ist', 'ro'] +['Ġz', 'oom'] +['Ġleg', 'it'] +['pec', 'ific'] +['ĠC', 'ome'] +['Ġlocal', 'Storage'] +['Ġabs', 'or'] +['.P', 'anel'] +['ĠDesign', 'er'] +['Ġo', 'w'] +['IC', 'AL'] +['_', 'uri'] +['(f', 'ield'] +['Ġsup', 'erv'] +['Ex', 'ists'] +['Ġrespect', 'ively'] +['ĠSt', 'and'] +['Con', 'f'] +['uss', 'ian'] +['Ġar', 'c'] +['Ġ', 'nd'] +['uck', 's'] +['Ġre', 'str'] +['Ġseason', 's'] +['ĠCh', 'apter'] +['ĠSw', 'itch'] +['p', 'ic'] +['Ġh', 'i'] +['load', 'ed'] +['Ġfl', 'uid'] +['-b', 'tn'] +['Ġrun', 'time'] +['.', 'it'] +['B', 'N'] +['Op', 'acity'] +['as', 'ant'] +['ry', 'ption'] +['-n', 'ative'] +['Ġta', 'ught'] +['å', '¯'] +['ag', 'ment'] +['Ġm', 'ul'] +['Reg', 'istry'] +['_', 'grid'] +['ĠBro', 'ok'] +[':', 'Set'] +['Ġm', 'ongoose'] +['AM', 'ES'] +['inner', 'HTML'] +['Ġs', 'oci'] +['ĠInt', 'el'] +['get', 'Id'] +['C', 'md'] +['Ġaccess', 'ible'] +['r', 'ames'] +['le', 'ton'] +['Ġ__', '('] +['ĉ', 'delete'] +['ĠS', 'quare'] +['"', 'ĊĊĊ'] +['Ġbu', 'cket'] +['avor', 'ite'] +['ĠB', 'reak'] +['++', ']'] +['Ġbr', 'ush'] +['Ġt', 'ensor'] +['/', 'http'] +['T', 'ile'] +['Ġfunction', 'al'] +['Ġ"', '*'] +['wh', 'el'] +['Ġt', 'ent'] +['ĠChar', 'acter'] +['Ġse', 'es'] +['.', 'ST'] +['B', 'ig'] +['Ġext', 'ern'] +['Url', 's'] +['))', ')),'] +['ĠJ', 'r'] +['.B', 'uilder'] +['.', ';'] +['n', 'l'] +['_', 'Init'] +['ĠH', 'ER'] +['ż', 'e'] +['mys', 'qli'] +['_', 'icon'] +['v', 'an'] +['Ġfeel', 'ings'] +['Ġle', 'an'] +['Ġhop', 'ing'] +['T', 'V'] +['="čĊ'] +['b', 'est'] +['all', 'as'] +['ent', 'ed'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĊ'] +['_con', 'nection'] +['Ġrep', 'o'] +['en', 'abled'] +['аÐ', 'º'] +['Ġsh', 'a'] +['Ġmembers', 'hip'] +['Status', 'Code'] +['in', 'ating'] +['_s', 'm'] +['_c', 'ustom'] +['_', 'weight'] +['Ġc', 'ss'] +['St', 'at'] +['_', 'env'] +['link', 's'] +['TR', 'L'] +['ĠH', 'it'] +[',', 'r'] +['up', 'id'] +['Ġop', 'ens'] +['Ġg', 'ent'] +['_v', 'is'] +['Ġj', 'oy'] +['<', 'w'] +['_c', 'ost'] +['ĠPy', 'Object'] +['ren', 'ce'] +['ĠGeorg', 'ia'] +['ĠBro', 'ad'] +['m', 'ma'] +['â', 'Ĥ'] +['p', 'f'] +['Ġ"', '\\"'] +['Ġ(', '&'] +['om', 'o'] +['Ġliter', 'ally'] +['Ī', 'ĺ'] +['met', 'ric'] +['Ġb', 'ars'] +['z', 'ed'] +['(w', 'indow'] +['ĠIsrael', 'i'] +['Ġform', 'al'] +['ident', 'ifier'] +['.d', 'ao'] +['ĠDe', 'ath'] +['%', ';Ċ'] +['Ġdecl', 'are'] +['ar', 'ms'] +['RE', 'AM'] +['PERT', 'Y'] +['Ġconsequ', 'ences'] +['to', 'ols'] +['Pe', 'ople'] +['ĠWh', 'ich'] +['>', '();čĊ'] +['.de', 'code'] +['_A', 'CT'] +['Button', 's'] +['.f', 'loat'] +['.F', 'irst'] +['ë', '¥'] +['ĠPol', 'it'] +['ĠX', 'CT'] +['T', 'ags'] +['ĠCG', 'Float'] +['=', 'str'] +['Ġle', 'af'] +['-', 'check'] +['ĠI', 'ss'] +['.s', 'ystem'] +['log', 'out'] +['ach', 't'] +['Ang', 'le'] +['s', 'in'] +['ch', 'art'] +['INT', 'ER'] +['ĠN', 'UM'] +['B', 'asic'] +['.P', 'roperties'] +['ä¸', 'Ń'] +['_', 'change'] +['ĠB', 'razil'] +['Ab', 'stract'] +['Ġ:', '+:'] +['_', 'use'] +['а', 'л'] +['ĠL', 'y'] +['IB', 'UT'] +['Ġout', 'er'] +['Ġ--', '>čĊ'] +['Ġrel', 'ief'] +['l', 'ap'] +['qu', 'er'] +['_p', 'arent'] +['he', 'ap'] +['LO', 'SE'] +['Ġcomb', 'ine'] +['ĠR', 'ose'] +['ow', 'ers'] +['Ġproced', 'ures'] +['ĠS', 'ort'] +['an', 'im'] +['var', 'iant'] +['eh', 'icle'] +['Ġsign', 'ing'] +['Pr', 'imary'] +['c', 'urrency'] +['Ġsex', 'e'] +['o', 'en'] +['th', 'eta'] +['em', 'an'] +['Ġimpress', 'ive'] +["('", '_'] +['ĉ', 'U'] +['ĠText', 'Style'] +['_c', 'nt'] +['Ġs', 'lice'] +["('", ':'] +['Ġunderst', 'ood'] +['H', 'is'] +['Ġinform', 'ed'] +['Ġn', 'ick'] +['(T', 'AG'] +['h', 'd'] +['Ġelection', 's'] +['est', 'ure'] +['ĠS', 'anta'] +['ĠCo', 'ast'] +['.p', 'df'] +['inc', 'iple'] +['.cl', 'one'] +['b', 'orn'] +['ut', 'a'] +['Ġl', 'icensed'] +['C', 'r'] +['Ġb', 'read'] +['ĠH', 'ouston'] +['Ġn', 'od'] +['Ġhop', 'es'] +['ĠCG', 'Rect'] +['Ġgu', 'ilty'] +['.g', 'if'] +['Ġro', 'se'] +['.Com', 'mon'] +['T', 'ip'] +['AN', 'K'] +['ĠF', 'C'] +['D', 'uring'] +['ĠSym', 'fony'] +['Ġdef', 'ensive'] +['k', 'm'] +[')', '>'] +['arch', 'ive'] +['ĠU', 'RI'] +['ycl', 'ing'] +['-', 'o'] +['ĠWe', 'bsite'] +['AM', 'P'] +['ish', 'ment'] +['Ġdo', 'ctors'] +['D', 'irect'] +['AR', 'I'] +['ĠRed', 'irect'] +['ier', 'en'] +['_d', 'ist'] +['y', 'o'] +['ĠPro', 'gress'] +['Ġz', 'um'] +['Ġmem', 'or'] +['ĠE', 'D'] +['Ġj', 'ur'] +['æį', '®'] +['_T', 'ABLE'] +['Ġu', 'uid'] +['Ex', 'pr'] +['.', 'head'] +["('", '%'] +['point', 'er'] +['Ġest', 'imate'] +['ĠG', 'reg'] +['Ġlo', 'ader'] +['Ġi', 'OS'] +['Ġm', 'ens'] +['[', 'y'] +['Ġref', 'used'] +['Ġprec', 'ision'] +['is', 'ch'] +['ĠA', 'CTION'] +['Cl', 'oud'] +['s', 'With'] +['(', 'ret'] +['_ADD', 'R'] +['_con', 'f'] +['(d', 'f'] +['Ġlock', 'ed'] +['Ġr', 'ising'] +['ãĥ»', 'ãĥ»'] +['ĠM', 's'] +['Ġscen', 'es'] +['_EX', 'T'] +['_', 'raw'] +['_', 'the'] +['pe', 'ople'] +['Ġre', 'con'] +['ĠF', 'un'] +['Ġb', 'less'] +['ĠUp', 'dated'] +['ü', 'n'] +['ĠĠĠĠĠĠĠĠĠĠĠĠ', 'čĊ'] +['pe', 'ction'] +['Re', 'lease'] +['.log', 'ger'] +['ĠS', 'Y'] +['Ġcoun', 'sel'] +['ur', 'd'] +['_', 'true'] +['Ġevery', 'body'] +['iv', 'ot'] +['Ġh', 'ence'] +['ĠN', 'AS'] +['Ġoppos', 'ed'] +['unk', 'nown'] +['ĠDES', 'C'] +['ĠCh', 'air'] +['fa', 'iled'] +['ĠIN', 'CLUDING'] +['Ġwrit', 'ers'] +['{', '}Ċ'] +['ÃŃ', 't'] +['_c', 'opy'] +['}', ':'] +['ĠB', 'at'] +['Ġconvert', 'ed'] +['ed', 'ing'] +['pl', 'acement'] +['ĠH', 'ost'] +['S', 'ound'] +['и', 'м'] +['Ġs', 'ought'] +['m', 'id'] +['Ġsal', 'ary'] +['og', 'g'] +['âĦ', '¢'] +['b', 'ul'] +['Ġw', 'ir'] +['valid', 'ator'] +['_ST', 'AT'] +['.st', 'ore'] +['ĠB', 'attle'] +['ı', 'n'] +['Ġ--', '>ĊĊ'] +['Tr', 'ump'] +['d', 'ot'] +['ĠCON', 'T'] +['.f', 'etch'] +['Ġcontin', 'u'] +['w', 'as'] +['Ġfra', 'ud'] +['_t', 'mp'] +['mit', 'ter'] +['.p', 'ictureBox'] +['G', 'A'] +['Ġt', 'ournament'] +['.', 'Input'] +['[', 'r'] +['ex', 'ion'] +['cent', 'age'] +['ĠKore', 'an'] +['und', 'ef'] +['ĠAv', 'ailable'] +['resh', 'ape'] +['Ġk', 'it'] +['ĠStr', 'uct'] +['ĠS', 'UB'] +['An', 'swer'] +['_l', 'ib'] +['.t', 'witter'] +['Ġo', 're'] +['ĠDr', 'agon'] +['.Ex', 't'] +[',', 'k'] +['Ġexplan', 'ation'] +['ref', 's'] +['ĠDr', 'ive'] +['ĠTr', 'aining'] +['.H', 'as'] +['int', 'age'] +['b', 'ig'] +['olog', 'ist'] +['enn', 'is'] +['Ù', 'ĩ'] +['Ġch', 'icken'] +['ĠĠĠĠĠĠĠĠĠĠ', 'Ċ'] +['ç', 'Ľ'] +['ãģ', '§'] +['Ġpe', 'ak'] +['Ġdrink', 'ing'] +['Ġen', 'code'] +['ĠNE', 'W'] +['m', 'alloc'] +['ĉf', 'printf'] +['Ġ=', '================================================================'] +['in', 'cluding'] +['Ġprincip', 'les'] +['ĠM', 'ah'] +['st', 'orage'] +['-', 'key'] +['Ġkey', 'word'] +['%', ';'] +['Ġtr', 'ained'] +['.con', 'trib'] +['Ġk', 'v'] +['__', "':Ċ"] +['ĠB', 'oy'] +['param', 'eter'] +['Ġsu', 'ite'] +['Ġthous', 'and'] +['Ġco', 'ordinate'] +['-g', 'enerated'] +['íķ', 'ĺ'] +['gener', 'ated'] +['Ġad', 'mitted'] +['Ġp', 'ussy'] +['#', 'w'] +['Ġsw', 'im'] +['un', 'ion'] +['N', 'a'] +['ĠRoy', 'al'] +['.ch', 'annel'] +['Up', 'dated'] +['_RO', 'OT'] +['Ġv', 'ital'] +['ra', 'ction'] +['ĠCrush', 'er'] +['Ġpre', 'ced'] +['Ġhor', 'izontal'] +['Blue', 'print'] +['Ġattr', 's'] +['Ġsm', 'oke'] +['Ð', 'Ĵ'] +['.', 'Equals'] +['F', 'B'] +['ĠRes', 'ources'] +['roll', 'ing'] +['Ġpass', 'es'] +['ĠN', 'um'] +['rot', 'ate'] +['et', 'ype'] +['\\', '",'] +['Ġsens', 'itive'] +['Ġt', 'all'] +['?', 'âĢĿĊĊ'] +['Pro', 'xy'] +['i', 'y'] +['_', 'section'] +['âĢĶâĢĶ', 'âĢĶâĢĶ'] +['br', 'id'] +['Ġcirc', 'uit'] +['at', 'an'] +['EN', 'C'] +['Ġdr', 'iven'] +['Ġvot', 'ed'] +['Ġeduc', 'ational'] +['Ġinter', 'action'] +['abet', 'es'] +['Ġt', 'one'] +['ĠInitialize', 'Component'] +['Ġmer', 'ely'] +['Ġì', 'ŀ'] +['co', 'okie'] +['_', 'div'] +['ĠUIL', 'abel'] +['vel', 'y'] +['}', ');čĊ'] +['_', 'ENT'] +['#+', '#+'] +['art', 'icles'] +['ĠSou', 'thern'] +['Ġstrong', 'er'] +['ĠG', 'iven'] +['ĠE', 'ric'] +['ĠI', 'R'] +['ab', 'stract'] +['U', 'nder'] +['n', 'able'] +['Ġincre', 'ment'] +['ov', 'en'] +['Ġco', 'in'] +['_t', 'imer'] +['Ġsuffer', 'ed'] +['ĠF', 'REE'] +["']", '."'] +['ĠQue', 'en'] +['st', 'ats'] +['Ġmeet', 'ings'] +['Ġenter', 'ing'] +['Ġalong', 'side'] +['(s', 'ession'] +['it', 'als'] +['Ġfound', 'ation'] +['ĠC', 'redit'] +['.', 'div'] +['_', 'ALL'] +['pc', 'ion'] +['_st', 'at'] +['ick', 'ing'] +['Default', 's'] +['_s', 'rc'] +['Ġoutput', 's'] +['/', 'B'] +['Ġent', 'hus'] +['-b', 'l'] +['.Fore', 'Color'] +['ĉ', 'temp'] +['F', 'ace'] +['Ġinter', 'act'] +['Ġwe', 'ird'] +['M', 'ount'] +['re', 'll'] +['ud', 'ents'] +['Ġrequire', 'ment'] +['ĠS', 'us'] +['I', 'ER'] +['Ġe', 'lected'] +['re', 'ference'] +['ĠM', 'E'] +['Ġserv', 'ers'] +['.w', 'ait'] +['Ġsnap', 'shot'] +['il', 'ton'] +['Ġtri', 'es'] +['Ġt', 'ipo'] +['.T', 'ime'] +['>', 'w'] +['Ġmount', 'ain'] +['Ġp', 'ounds'] +['Ġ[', '...'] +['ex', 'ists'] +['Ġng', 'On'] +['_M', 'AP'] +['Ġf', 'lying'] +['xi', 'ety'] +['ĉ', 'value'] +['_D', 'B'] +['un', 'o'] +['Ġse', 'ats'] +['T', 'URN'] +['.', 'author'] +['!', ')'] +['or', 'ce'] +['Ġindic', 'ated'] +['.s', 'in'] +['Ġass', 'ignment'] +['im', 'iento'] +['ĠF', 'rame'] +['_g', 'en'] +['in', 'ery'] +['_', ')'] +['m', 'essages'] +['.set', 'tings'] +['ĠMe', 'an'] +['ĠM', 'useum'] +['ir', 'q'] +['att', 'ach'] +['ĠPalest', 'in'] +['_', 'QU'] +['_t', 'ags'] +['Ġcas', 'ual'] +['em', 'en'] +['ASS', 'WORD'] +['$', 's'] +['ĠC', 'irc'] +['оÐ', '¹'] +['et', 'ric'] +['/', 'P'] +['Ġep', 'och'] +['<', 'head'] +['_C', 'MD'] +['Ġg', 'it'] +['Ġpen', 'alty'] +['or', 'ph'] +['_', 'users'] +['ours', 'es'] +['.Date', 'Time'] +['atern', 'ion'] +['_pro', 'ject'] +['Ġsuper', 'ior'] +['ĠD', 'am'] +['ĠSe', 'attle'] +['X', 'Y'] +['>', 'The'] +['ĠA', 'k'] +['Ġgr', 'ass'] +['/*', 'čĊ'] +['(d', 'is'] +['Ġgun', 's'] +['Ġt', 'b'] +['ĠK', 'evin'] +['.', 'args'] +['ĠA', 'h'] +['op', 'ed'] +['(', 'J'] +['column', 's'] +['arg', 'uments'] +['ĠWith', 'Events'] +['_f', 'ull'] +['ĠDef', 'ense'] +['S', 'imple'] +['Ġdeath', 's'] +['Ġext', 'ensive'] +['ĠSt', 'ill'] +['ĠEx', 'pression'] +['ĠAg', 'ency'] +['Ġperform', 'ing'] +['F', 'X'] +['Ġus', 'uario'] +['U', 'AL'] +['S', 'ide'] +['od', 'os'] +['apt', 'op'] +['Ġcred', 'entials'] +['_c', 'ap'] +['at', 'ient'] +['ĠDis', 'ney'] +['Ġa', 'i'] +['Ġch', 'ip'] +['Ġvol', 't'] +['.make', 'Text'] +['%%%%%%%%', '%%%%%%%%'] +['Ġbelie', 'f'] +['_LO', 'C'] +['ĠC', 'ivil'] +['N', 'avigation'] +['Ġreve', 'al'] +['Ġviol', 'ent'] +['ĠF', 'il'] +['Ġc', 'atalog'] +['em', 'ed'] +['sc', 'an'] +['.', 'control'] +['Ġconstit', 'ution'] +['C', 'ountry'] +['Separ', 'ator'] +['_A', 'PP'] +['top', 'ic'] +['uet', 'ooth'] +['M', 'IN'] +['Ġdes', 'criptor'] +['y', 't'] +['ET', 'HER'] +['Ġdistrib', 'ute'] +["'", '}Ċ'] +['.tr', 'im'] +['.L', 'ine'] +['Ġl', 'bl'] +['assert', 'Equals'] +['ĠD', 'et'] +['omb', 'ok'] +['(', 'width'] +['Ġt', 'ort'] +['ĠEXP', 'RESS'] +['ac', 'o'] +['Us', 'ing'] +['ĠBr', 'and'] +['w', 'all'] +['EM', 'ENT'] +['ĠComm', 'unic'] +['<', 'uint'] +['ĠG', 'UI'] +['EG', 'IN'] +['ĠR', 'ange'] +['/', 'i'] +['ĠT', 'aylor'] +['c', 'ost'] +['Ġrespond', 'ed'] +['ĠTh', 'eme'] +['n', 'ce'] +['IS', 'H'] +['Ġfeat', 'uring'] +['Return', 's'] +['ĠK', 'r'] +['Ġ', '.Ċ'] +['Ġn', 'am'] +['_c', 'b'] +['Test', 'ing'] +['Ġ{', '},'] +['y', 'al'] +['.f', 'ield'] +['Ġ/', '='] +['_SH', 'ORT'] +['m', 'ates'] +['Test', 'Case'] +['ain', 'less'] +['Ġeval', 'uation'] +['_', 'ITEM'] +['ĠPac', 'ific'] +['ĉ', 'k'] +['Ġc', 'ant'] +['ĠR', 'os'] +[')', 's'] +['Ġf', 'et'] +['STR', 'ING'] +['ĠDis', 'pose'] +['g', 'al'] +['ĠJ', 'oin'] +['ĠP', 'orn'] +['ĠCath', 'olic'] +['AR', 'GET'] +['cp', 'u'] +['ç', 'łģ'] +['.sc', 'roll'] +['IS', 'ING'] +['ifest', 'yle'] +['anc', 'ement'] +['Ġm', 'erc'] +['ĠB', 'rowser'] +['eter', 'min'] +['Ġover', 'flow'] +['Av', 'ailable'] +['Ġbott', 'le'] +[':', 'UI'] +['ific', 'ial'] +['Ġco', 'ord'] +['clar', 'ation'] +['Ġcon', 'j'] +['G', 'LOBAL'] +['ok', 'u'] +['Ġk', 'wargs'] +['cond', 'itions'] +['ul', 'um'] +['Ġg', 'enu'] +['ĠH', 'ero'] +['å', 'İ'] +['Ġun', 'expected'] +['ĠDAM', 'AGES'] +['Ġk', 'a'] +['ĠC', 'ould'] +['UP', 'PORT'] +['ĠPh', 'otos'] +['Ġconf', 'ident'] +['Ġdet', 'ected'] +['de', 'g'] +['rg', 'b'] +['Ġstrong', 'ly'] +['Ġ}', ';čĊ'] +['Ġ)', ':'] +['Ġle', 'ct'] +['urs', 'ive'] +['RO', 'L'] +['ĠWe', 'ight'] +['Ġent', 'ertainment'] +['Ġ)', ');Ċ'] +['Ġg', 'onna'] +['Ġb', 'b'] +['.d', 'o'] +['G', 'S'] +['Ġmist', 'ake'] +['D', 'L'] +['ĠPROVID', 'ED'] +['ear', 'ning'] +['L', 'imit'] +['iss', 'ions'] +['[', 'v'] +['ä¸', 'į'] +['ir', 'ty'] +['D', 'el'] +['Ġunder', 'lying'] +['pre', 'ne'] +['Ġj', 'aw'] +['ĠD', 'I'] +['pe', 'er'] +['Ġobject', 'ive'] +['Ġde', 'posit'] +['Ġk', 'on'] +['Ġes', 'p'] +['.set', 'Visibility'] +['/', 'login'] +['<', 'typename'] +['Ġfr', 'anch'] +['/', 'e'] +['Par', 'allel'] +['Ġsc', 'ored'] +['ĠH', 'on'] +['ĠV', 'ill'] +['ig', 'a'] +['Ġant', 'icip'] +['_', 'assert'] +['ĠO', 'pt'] +['Ġdescri', 'bes'] +['w', 'an'] +['m', 'ount'] +['Ġmonitor', 'ing'] +['Ġt', 'out'] +['ëĬ', 'Ķ'] +['},', '{'] +['................', '................'] +['=', 'int'] +['Ġc', 'ust'] +['----', '--'] +['Ġatmos', 'phere'] +['P', 'AR'] +['ort', 'e'] +['IS', 'IBLE'] +['ĠI', 'ron'] +['ĠNot', 'ification'] +['.log', 'ging'] +['ĠBO', 'OL'] +['-p', 'oint'] +['Ġaf', 'raid'] +['ent', 'a'] +['Ġtom', 'orrow'] +['@', 'implementation'] +['Ġeng', 'age'] +['ĠAn', 'th'] +['ĠF', 'loor'] +['ĠU', 'l'] +['To', 'ols'] +['Ġb', 'ab'] +['Ġcare', 'ful'] +['ãģ', 'Ħ'] +['Ġcruc', 'ial'] +['Ġcalcul', 'ated'] +['ĠS', 'A'] +['Ġw', 'y'] +['D', 'X'] +['_T', 'AG'] +['ind', 'ed'] +['Ġj', 'et'] +['ĠEngine', 'ering'] +['.M', 'AX'] +['en', 'z'] +['v', 'd'] +['Ġpublic', 'ation'] +['Ġ##', '#'] +['Ġfac', 'ed'] +['ra', 'ham'] +['ĠC', 'apt'] +['As', 'set'] +['ĠCon', 'stants'] +['Ġlo', 'ans'] +['_', 'IP'] +['ĠF', 'ish'] +['Red', 'uc'] +['_m', 'at'] +['Date', 'Format'] +['_m', 'e'] +['[]', '[]'] +['Ġintegr', 'ity'] +['ĠC', 'ourse'] +['lob', 'als'] +['Ġfac', 'ilit'] +['Ġem', 'br'] +['ĠN', 'g'] +['.S', 'ystem'] +['Ġmanufact', 'urers'] +['Ġpro', 'ven'] +['.on', 'Create'] +['Ġal', 'arm'] +['ĠÂ', '§'] +['Ġcomm', 'only'] +['ic', 'os'] +['æĸ', '°'] +['ĠSt', 'ation'] +['}', ').'] +['ĠF', 'ilm'] +['w', 'i'] +['ç', 'ī'] +['Ġeng', 'aged'] +['St', 'ats'] +['Ġgovern', 'ments'] +['Ġafford', 'able'] +['_p', 'roperty'] +['Ġag', 'es'] +["('", '--'] +['Ġf', 'ör'] +['ĠProf', 'essor'] +['Ġhy', 'dro'] +['P', 'ush'] +['Ġorgan', 'ized'] +['Ac', 'cept'] +['é', 'm'] +['_c', 'ell'] +['Ġn', 'b'] +['p', 'b'] +['Art', 'icle'] +['Ġrem', 'oval'] +['Ġauth', 'entication'] +['ĠF', 'R'] +['l', 'ide'] +['Ġple', 'asure'] +['ap', 'ol'] +['Ġpart', 'ition'] +['ĠS', 'ide'] +['Ġcr', 'imes'] +['Ġdem', 'o'] +['hold', 'ers'] +['ĠPak', 'istan'] +['In', 'struction'] +['Ġexpect', 'ations'] +['.sc', 'ene'] +["Ġ'", ')'] +['h', 'es'] +['ino', 'is'] +['_P', 'ro'] +['Ġm', 'olec'] +['and', 'al'] +['_sh', 'ort'] +['Ġdefault', 's'] +['Ġn', 'ations'] +['in', 'en'] +['Ġr', 't'] +['O', 'CK'] +['P', 'acket'] +['S', 'B'] +['ĠSH', 'ALL'] +['_cont', 'ents'] +['ise', 'conds'] +['vert', 'y'] +['á', 't'] +['G', 'uid'] +['n', 'om'] +['Ġcon', 'clusion'] +['.', 'Update'] +['Ġlo', 'vely'] +['Ġem', 'it'] +['b', 'ec'] +['ĉĉĉĉ', 'Ġ'] +['Ġintel', 'lect'] +['Ġb', 'rew'] +['ec', 'ycle'] +['F', 'ire'] +['Ġad', 'mit'] +['Ġar', 'bit'] +['Ġarr', 'ang'] +['ĠM', 'IN'] +['M', 'ail'] +['ĠN', 'ative'] +['C', 'ur'] +['Ġcon', 'vent'] +['.R', 'untime'] +['"', '}Ċ'] +['.R', 'un'] +['Ġprint', 'ed'] +['Ġconven', 'ient'] +['.', 'ar'] +['m', 'ock'] +['ĠAdmin', 'istration'] +['ãģ', '¾'] +['Ġelect', 'ron'] +['fl', 'ate'] +['Ġl', 'ombok'] +['Ġjava', 'fx'] +['n', 'h'] +['Ġsup', 'plies'] +['Ġvisit', 'ing'] +['ah', 'l'] +['Ġpow', 'der'] +['Ġult', 'imate'] +['Ġorient', 'ation'] +['ut', 'as'] +['_s', 'cale'] +['Con', 'firm'] +['ph', 'ones'] +['ĠOper', 'ation'] +['/', 'T'] +['_IN', 'TER'] +['Ġair', 'port'] +['Ġmet', 'rics'] +['Ġphen', 'omen'] +['a', 'udio'] +['Ġm', 'ai'] +['(', 'K'] +['h', 'u'] +['all', 'ing'] +['rodu', 'ction'] +['ĠTrans', 'port'] +['ĠNOT', 'E'] +['æĸ', 'ĩ'] +['Ġfew', 'er'] +['_T', 'IM'] +['ì', '§'] +['к', 'и'] +['A', 'ge'] +['F', 'IN'] +['Ġì', 'Ŀ'] +['ĠAt', 'tribute'] +['group', 's'] +['er', 'k'] +['at', 'to'] +['.', 'define'] +['.AspNet', 'Core'] +['ategor', 'ia'] +['ĠS', 'ir'] +['(', 'form'] +['<', 'User'] +['.', 'round'] +['_d', 'ay'] +['.A', 'll'] +['Servlet', 'Response'] +['.N', 'o'] +['l', 'arge'] +['IG', 'H'] +['qu', 'ent'] +['Ġvir', 'us'] +['Ġret', 'ro'] +['Ġim', 'per'] +['Bit', 'map'] +['Ġv', 'ice'] +['Ġoff', 'ense'] +['ist', 'e'] +['ĠA', 'UTH'] +['Ġê', '°'] +['ToolStrip', 'MenuItem'] +['G', 'u'] +['Ġr', 'ape'] +['ĠDav', 'is'] +['Ġover', 'whel'] +[':', 'flutter'] +['-', 'table'] +['ĠCon', 'structor'] +['Pr', 'ivate'] +['e', 'ven'] +['ch', 'r'] +['Ġap', 'plies'] +['_at', 'tribute'] +['Ġcon', 'tribute'] +['E', 'VER'] +['L', 'ines'] +['ĠAf', 'ghan'] +['Vis', 'itor'] +['ĠS', 'L'] +['se', 'ason'] +['C', 'U'] +['Ġintrodu', 'ction'] +['Ġmat', 'plotlib'] +['Å', 'ij'] +['Ġnewsp', 'aper'] +['âĢĶ', 'and'] +['<', 'tag'] +['Ġin', 'i'] +['Ġd', 'iverse'] +['Ignore', 'Case'] +['ĠU', 'r'] +['Ag', 'ent'] +['Ġb', 'ull'] +['.em', 'it'] +['(', 'Exception'] +['ar', 'Layout'] +['Ġincred', 'ibly'] +['ĠTr', 'ust'] +['={', '('] +['-', 'nav'] +['Ġe', 'quals'] +['Ġl', 'ady'] +['ĠP', 'od'] +['d', 'isc'] +['al', 'am'] +['ĠI', 'V'] +['â', 'Ļ'] +['iv', 'idual'] +['ph', 'i'] +['add', 'ed'] +['Ġdifficult', 'y'] +['Ġcomp', 'act'] +['ĠAction', 'Result'] +['c', 'ers'] +['_class', 'es'] +['Non', 'Null'] +['Ġqu', 'it'] +['Ġp', 'ou'] +['S', 'witch'] +['ir', 's'] +['-', 'test'] +['ĠK', 'ind'] +['ĠCal', 'endar'] +['Ġstream', 'ing'] +['}', "',"] +['S', 'W'] +['Ġst', 'ead'] +['oc', 'a'] +['Ġprov', 'ince'] +['Ġcol', 'span'] +['Ġperson', 'nel'] +['ĠE', 'mployee'] +['Ġprodu', 'cer'] +['Ġevery', 'where'] +['od', 'b'] +['Ð', 'Ł'] +['bs', 'olute'] +['act', 'ivate'] +['Ġgr', 'inding'] +['ĠBuild', 'ing'] +['ĠSand', 'ers'] +['(s', 'c'] +['ĠOff', 'set'] +['////////', '////'] +['}', ';čĊčĊ'] +['({', '"'] +['Ġscan', 'f'] +['ĠY', 'Y'] +['ĉdef', 'er'] +['Ġj', 'ew'] +['Ġrestrict', 'ions'] +['.m', 'p'] +['[', 'l'] +['ä¸', 'ĭ'] +['label', 's'] +['red', 'icate'] +['aw', 'esome'] +['Ġw', 'aves'] +['Ġcon', 'front'] +['Ġmeas', 'ured'] +['Ġdat', 'as'] +['_ex', 'it'] +['ot', 'ton'] +['Ġshould', 'er'] +['ask', 'a'] +['+', '#'] +['ĠĠĠĠĠĠĠĠĊ', 'ĠĠĠĠĠĠĠĠĊ'] +['Ġtro', 'ops'] +['ĠU', 'nd'] +['_c', 'ard'] +['w', 'ich'] +['Ġn', 'ous'] +['Ġ"/', '"'] +['s', 'b'] +['Ġcommunic', 'ations'] +['Ex', 'port'] +['Ġdec', 'ode'] +['th', 's'] +['inter', 'pret'] +['By', 'Name'] +['ĠSp', 'irit'] +['ed', 'ges'] +['O', 'LE'] +['ĠE', 'M'] +['t', 'it'] +['ĠTh', 'rough'] +['Ġb', 'io'] +['ĠP', 'ackage'] +['or', 'ne'] +['Ġ}', '.'] +['`', ';Ċ'] +['Ġok', 'ay'] +['ĠZe', 'aland'] +['ident', 'ity'] +['(n', 'ext'] +['ĠB', 'ang'] +['Lib', 'rary'] +['Ġheav', 'ily'] +['il', 'on'] +['Ġdi', 'pl'] +['Ġrot', 'ate'] +['put', 's'] +[')', "',Ċ"] +['ĠData', 'Table'] +['Ġmay', 'or'] +['.to', 'LowerCase'] +['Ġsome', 'how'] +['ĠNor', 'thern'] +['al', 'c'] +['Ġcap', 'abilities'] +['Ġv', 'ibr'] +['+', 'Ċ'] +['ĠS', 'u'] +['ĠRes', 'et'] +['_m', 'ean'] +['Ġc', 'ig'] +['.cl', 'oud'] +['ĠB', 'and'] +['ĠF', 'actory'] +['ĠAr', 'izona'] +['_', 'io'] +['op', 'her'] +['Ġconsc', 'ious'] +['ĠÃ', '¶'] +['\\', 'Controllers'] +['_s', 'peed'] +['ĠF', 'ac'] +['_C', 'om'] +['ĠB', 'ible'] +['w', 'en'] +['ED', 'IT'] +['Ġun', 'n'] +['ĠSt', 'aff'] +['ĠIn', 'n'] +['Ġmechan', 'ism'] +['ĠM', 'embers'] +['Ġmigration', 'Builder'] +["']", ".'"] +['.get', 'Int'] +['<', 'void'] +['ĉf', 'ree'] +['oid', 's'] +['\\', 'Support'] +['Ġautom', 'atic'] +['Ġch', 'ances'] +['Ð', '¶'] +['Ġcomp', 'licated'] +['[', 'row'] +['ah', 'oo'] +['Ġ}ĊĊ', 'ĊĊ'] +['Model', 's'] +['W', 'in'] +['Ġt', 'ape'] +['ir', 'us'] +['iz', 'on'] +['on', 'omy'] +['("', '_'] +[':', '.'] +['.st', 'ereotype'] +['(', 'env'] +['_re', 'ct'] +['(w', 'ith'] +['Ġassert', 'That'] +['Ġcon', 'straints'] +['put', 'y'] +['E', 'mployee'] +['T', 'D'] +['Ġgu', 'itar'] +['ĠJew', 's'] +['.pro', 'cess'] +['Ġf', 'iction'] +['ĠSh', 'ared'] +['âĶĢ', 'âĶĢ'] +['Ġprop', 'ag'] +['.N', 'et'] +['Ġachie', 'ved'] +['ĉ', 'Q'] +['Ġn', 'urs'] +['Sh', 'ared'] +['_FAIL', 'URE'] +['Ġbeh', 'aviour'] +['Ġcol', 's'] +['ism', 'o'] +['Ġfem', 'in'] +['Ġchalleng', 'ing'] +['Ġpost', 'ing'] +['enc', 'il'] +['Ġcapt', 'ured'] +['ĠD', 'ou'] +['(', 'word'] +['ĠTur', 'key'] +['pan', 'ies'] +['Ġre', 'putation'] +['ORM', 'AL'] +['Ġelig', 'ible'] +['prot', 'ocol'] +['id', 'as'] +['(f', 'rom'] +['Ġfin', 'ance'] +['-', 'per'] +['Ġg', 'otten'] +['H', 'A'] +['d', 'uration'] +['ĠP', 'arent'] +['Ġin', 'vent'] +['Ġre', 'start'] +['ол', 'ÑĮ'] +['r', 'ition'] +['(r', 's'] +['<', 'bool'] +['i', 'ert'] +['Ġmod', 'ification'] +['ĠT', 'X'] +['readcr', 'umb'] +['b', 'ank'] +['$', '/'] +['ĠMill', 'er'] +[']', '),Ċ'] +['.Check', 'ed'] +['Ġsac', 'r'] +['se', 'curity'] +['Ġp', 'ose'] +['ĠBr', 'ad'] +['Ġfit', 'ness'] +['Ġannounc', 'ement'] +['ation', 'Token'] +['Ġserv', 'es'] +['ne', 'ed'] +['Ġge', 'ometry'] +['AR', 'S'] +['æ', 'Ģ'] +['andid', 'ate'] +['Ġs', 'prite'] +['_s', 'plit'] +['We', 'ek'] +['ad', 'ies'] +['>', '(Ċ'] +['?>', '"'] +['Ġ///', 'Ċ'] +['Ġein', 'er'] +['Ġweek', 'ly'] +['ĉlog', 'ger'] +['_p', 'op'] +['_m', 'an'] +['Ġmigr', 'ations'] +['Ġask', 's'] +['Ġb', 's'] +['Ġfall', 's'] +['.W', 'here'] +['-', 'height'] +['_fe', 'ature'] +['.M', 'in'] +['Ġhy', 'per'] +['Ġvol', 'atile'] +['Ġtw', 'enty'] +['Typ', 'ography'] +['Un', 'able'] +['D', 'et'] +[',', 'f'] +['-m', 'od'] +['Ġsett', 'lement'] +['Ġcontract', 's'] +['n', 'ome'] +['B', 'ad'] +['ĠB', 'rian'] +['(user', 'name'] +['!!', '!!'] +['Ġh', 'ack'] +['.F', 'ield'] +['H', 'R'] +['ĠJ', 'ordan'] +['iz', 'a'] +['ĠÂ', 'ł'] +['ĠSh', 'er'] +['.', 'header'] +['(', 'other'] +['ĠD', 'ub'] +['(', 'op'] +['ĠR', 'ound'] +['Ġv', 'ie'] +['Ġap', 'pl'] +['ĉ', 'J'] +['ĠIn', 'sert'] +['ĠL', 'P'] +['reg', 'on'] +['ĠM', 'PI'] +['Ġan', 'chor'] +['ac', 'a'] +['ø', 'r'] +['Ġa', 'de'] +['anch', 'or'] +['que', 'e'] +['ĠTree', 'Node'] +['Ġtarget', 'ed'] +['Ġla', 'id'] +['AB', 'EL'] +['v', 'et'] +['ĠOr', 'igin'] +['A', 'nt'] +['.', "');Ċ"] +['ex', 'pect'] +['ed', 'Reader'] +['ĠM', 'ajor'] +['Ġin', 'ch'] +['Com', 'par'] +['Ġpre', 'view'] +['Ġill', 'ness'] +['ĠCONTR', 'ACT'] +['ĠInd', 'epend'] +['u', 'uid'] +['Ġn', 'ome'] +['Ġt', 'c'] +['ĠA', 'venue'] +['is', 'an'] +['Ġph', 'rase'] +['_m', 'ove'] +['")', '['] +['Ġprov', 'ision'] +['Ġconcent', 'r'] +['_', 'IR'] +['ĠU', 't'] +['()', '+'] +['Ġn', 'as'] +['!', ','] +['ĠRob', 'in'] +['i', 'ations'] +['at', 'itude'] +['Ġp', 'x'] +['ĠWith', 'out'] +['/b', 'ash'] +['ek', 't'] +['re', 'ement'] +['Ob', 'server'] +['ĠReg', 'ion'] +['UBL', 'IC'] +['Ġ{', '//'] +['K', 'N'] +['å', '·'] +['Game', 'Object'] +['å', '¾'] +['enc', 'oding'] +['Ġ**', '*'] +['project', 's'] +['Ġt', 'k'] +['Ġche', 'ese'] +['EM', 'PL'] +['ar', 'o'] +['Ġا', 'ÙĦ'] +['Ġcons', 'ists'] +['ref', 'resh'] +['ure', 'au'] +['ĠSc', 'anner'] +['Ġso', 'il'] +['Ġfl', 'avor'] +['Data', 'Source'] +['Ex', 'ecute'] +['ени', 'е'] +['Ġsh', 'it'] +['åĪ', 'Ĩ'] +['<', 'any'] +['Ġretrie', 've'] +['Ġbelong', 's'] +['.st', 'rip'] +['abs', 'olute'] +['Ġexp', 'anded'] +['bo', 'y'] +['):', '-'] +['Ġresc', 'ue'] +['.J', 'Label'] +['Ġre', 'ly'] +['Ġal', 'ignment'] +['-f', 'amily'] +['Ġre', 'nd'] +['OLUM', 'N'] +['Ġb', 'orrow'] +['Ġqu', 'otes'] +['ĠL', 'ew'] +['Ġsh', 'ower'] +['ĠDE', 'LETE'] +['_lo', 'op'] +['!', '"ĊĊ'] +['ĉ', 're'] +['Ġattempt', 'ed'] +['aver', 'age'] +['ĠP', 'aint'] +['quis', 'ition'] +['ol', 'en'] +['Ġliter', 'ature'] +['ĠRe', 'ference'] +['_TEXT', 'URE'] +['ĠS', 'eg'] +['ĠInd', 'ust'] +['ct', 'ype'] +['D', 'UCT'] +['_H', 'OST'] +['ĠTr', 'ade'] +['Ġpl', 'ugins'] +['Ġbre', 'ast'] +['ul', 'se'] +['Ġcreat', 'ure'] +['ãģ', 'Ļ'] +['ĠW', 'i'] +['Ġsup', 'plied'] +['c', 'oll'] +['!', '("'] +['Ġfuck', 'ing'] +['ĠCh', 'rome'] +['ĠU', 'ri'] +['ĠN', 'ation'] +['Ġvert', 'ices'] +['T', 'HE'] +['ĠOr', 'iginal'] +['on', 'de'] +['Ġsh', 'arp'] +['Ġcook', 'ing'] +['Ġ{', '/*'] +['ĠPs', 'ych'] +['ĠH', 'ollywood'] +['=$', '_'] +['.D', 'ock'] +['Ġg', 'er'] +['Ġb', 'one'] +['_con', 'n'] +['_se', 'c'] +['ys', 'ics'] +['Ġ=', '"'] +['S', 'al'] +['s', 'f'] +['Ġdeep', 'ly'] +['ang', 'les'] +['T', 'erm'] +['b', 'ell'] +['ĠQu', 'ick'] +['ener', 'ation'] +['adio', 'Button'] +['åħ', '¥'] +['}čĊčĊ', 'čĊ'] +['Ġcapt', 'ion'] +['l', 'c'] +['ĠE', 'L'] +[',', '['] +['ĠĠĠĠĠĠ', 'čĊ'] +['ret', 't'] +['(m', 'ethod'] +['ĠFl', 'ash'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['W', 'ISE'] +['.s', 'cale'] +['Ġrough', 'ly'] +['_', 'child'] +['m', 'emory'] +['ay', 'ing'] +['Ġinitial', 'ized'] +['in', 'ator'] +['а', 'ÑĢ'] +['Ġsc', 'alar'] +['ĠH', 'o'] +['ai', 'res'] +['(c', 'olumn'] +['.de', 'stroy'] +['P', 'ACK'] +['Ġh', 'em'] +['ang', 'el'] +['_S', 'UB'] +['.', 'qu'] +['Ġ', '×'] +['DE', 'FAULT'] +['pos', 'itories'] +['ĠL', 'ength'] +['ĠF', 'ast'] +['Ġsign', 'als'] +['Ġ//', '$'] +['ri', 'ers'] +['Ġd', 'ummy'] +['AN', 'Y'] +['Ġperson', 'ality'] +['Ġa', 'gricult'] +['Pl', 'atform'] +['ER', 'O'] +['ĠT', 'ra'] +['Ġen', 'orm'] +['ĉ', 'W'] +['Action', 'Result'] +['Ġa', 'ver'] +['[', 'str'] +["Ġ'", '--'] +['.S', 'printf'] +['Ġdeb', 'ut'] +['Ġ', 'Ñĩ'] +['h', 'ex'] +['_', 'utils'] +['Ġp', 'b'] +['U', 'ITableView'] +['Ġz', 'ur'] +['.', 'encode'] +['Ġv', 'ag'] +['.error', 's'] +['о', 'н'] +['Ġm', 'r'] +['ĠA', 'ward'] +['Ġc', 'pu'] +['Ġpress', 'ed'] +["'", 'est'] +['ĠF', 'estival'] +["'", 'T'] +['Ġa', 'k'] +['res', 'olve'] +['.m', 'e'] +['Ġn', 'ic'] +['Ġgen', 're'] +['Ġat', 'trib'] +['ĠMo', 'on'] +['Ġarr', 'ive'] +['ĠD', 'ating'] +['Ġt', 'm'] +['.Config', 'uration'] +['.', 'red'] +['Ġgl', 'm'] +['Ġst', 'ations'] +['sw', 'itch'] +['Ġt', 'ied'] +['äº', 'º'] +['Ġ/', '>Ċ'] +['Ġsubsequ', 'ent'] +['pos', 'able'] +['-fl', 'uid'] +['Ġth', 'orough'] +['Ġpublic', 'ly'] +['apt', 'ers'] +['ĠWil', 'son'] +['_P', 'RE'] +['y', 'ard'] +['ä', '¼'] +['ĉ', 'in'] +['Ġre', 'vers'] +['Ġbul', 'let'] +['cri', 'bed'] +['nes', 'ota'] +['Ġ($', '_'] +['ann', 'on'] +['c', 'ursor'] +['Ġclo', 'thing'] +['ĠM', 'ulti'] +[':', "',"] +['Ġv', 'ess'] +['ordin', 'ator'] +['Ġein', 'em'] +['C', 'annot'] +['Ġar', 'med'] +['ĉ', 'V'] +['ä¸', 'Ĭ'] +['.F', 'lat'] +['ĠS', 'ep'] +['ĠSub', 'ject'] +['_f', 'ont'] +['Ġcharacter', 'istics'] +['D', 'one'] +['el', 'n'] +['########', '####'] +['PO', 'S'] +['Ġd', 'ensity'] +['ĠPl', 'atform'] +['-', 'items'] +['Ġo', 'vers'] +['Ġpush', 'ing'] +['ç', '¤'] +['.Con', 'nection'] +['_', 'term'] +['Ġinitial', 'ization'] +['________________', '________________'] +['ç', '¬'] +['.d', 'ocument'] +['les', 'h'] +['ĉd', 'ocument'] +['ĠP', 'in'] +['ç', 'a'] +['Ġdefinition', 's'] +['.P', 'ath'] +['_W', 'RITE'] +['Ġ', 'ĉĊ'] +['?', '>ĊĊ'] +['Ġter', 'rible'] +['be', 'an'] +['ick', 'ets'] +['ĠS', 'V'] +['B', 'uy'] +['(t', 'ask'] +['Ġreg', 'ime'] +['g', 'oogle'] +['Ġcr', 'ack'] +['.vis', 'it'] +['N', 'UM'] +['ener', 'gy'] +['Ġstr', 'uck'] +['_s', 'ample'] +['.p', 'ayload'] +['Ġre', 'vis'] +['ĠSc', 'ene'] +['Ġp', 'g'] +['Ġbreak', 'fast'] +['URRE', 'NT'] +['.char', 'At'] +['_ex', 'ception'] +['ĠAnt', 'on'] +['Ġguid', 'elines'] +['Ġex', 'haust'] +['ĠFin', 'ancial'] +['Ġind', 'ent'] +['Ġdes', 'ktop'] +['H', 'idden'] +['F', 'ailure'] +['Ġpr', 'inciple'] +['Ġ', 'iv'] +['Ġse', 'ks'] +['n', 'etwork'] +['Ġnumber', 'Of'] +['ĠAl', 'bert'] +['ĉ', 'long'] +[',', '.'] +['Ġz', 'eros'] +['f', 'ade'] +['ĠT', 'yp'] +['ĠT', 'erm'] +['ĠAr', 'ts'] +['.App', 'lication'] +['Ġbeh', 'alf'] +['æĪ', '·'] +['Ġm', 'ere'] +['(`', '${'] +['Ġaware', 'ness'] +['elp', 'ers'] +['f', 'lix'] +['Ġwe', 'igh'] +['Ġestim', 'ates'] +['.', 'child'] +['/', 'O'] +['ĠBit', 'map'] +['.b', 'ottom'] +['Ġ************************************************************************', '**'] +['Ex', 'pect'] +['ent', 'o'] +['ĠFor', 'um'] +['ver', 'al'] +['Ġj', 'ail'] +['Ġab', 'ilities'] +['ĠH', 'OLD'] +['ĠC', 'it'] +['Ġd', 'ynam'] +['Ġgr', 'ay'] +['ĉĉĉĉĉĉĉĉ', 'ĉĉĉĉĉ'] +['.next', 'Int'] +['ant', 'ly'] +['ĠAR', 'ISING'] +['(', 'private'] +['Ġreject', 'ed'] +['ĠN', 'ic'] +['Ġle', 'ather'] +['=', '{Ċ'] +['aly', 'tics'] +['th', 'etic'] +['.T', 'op'] +['.P', 'age'] +['={', '`'] +['Ġ', ';čĊ'] +['de', 'pth'] +['m', 'ann'] +['W', 'D'] +['ĠS', 'om'] +['.R', 'ight'] +['Ġ)', '}Ċ'] +['Ġtr', 'ait'] +['Ã', 'Ĺ'] +['i', 'ac'] +['Ġr', 'v'] +['S', 'ample'] +['.X', 'ml'] +['opp', 'ed'] +['ĠÑ', 'Ħ'] +['list', 's'] +['Ġt', 'ear'] +['ivers', 'ary'] +['.c', 'ollection'] +['ĠCon', 'stitution'] +['ĠHttp', 'Response'] +['Ġbr', 'ill'] +['ĠP', 'rom'] +['h', 'over'] +['ĠM', 'iami'] +['Ġarg', 'ue'] +['_f', 'loat'] +['Ġ', 'ãĤ'] +['Ġn', 'at'] +['ĠT', 'al'] +['Ġinteg', 'ration'] +['(c', 'ur'] +['Ġrem', 'oving'] +['Ġco', 'eff'] +['ĠTh', 'ough'] +['Ġfore', 'cast'] +['ĠV', 'egas'] +['S', 'ite'] +['Ġtr', 'ab'] +['ĠHen', 'ry'] +['-', 'i'] +['Ġinvol', 'ves'] +['B', 'T'] +['Ġs', 'lo'] +['In', 'voke'] +['Ġl', 'ucky'] +['r', 'at'] +['Ġ?', 'Ċ'] +['Ġhand', 'led'] +['(f', 'd'] +['cont', 'ents'] +['ĠO', 'FF'] +['R', 'F'] +['Ġst', 'y'] +['ĠM', 'otor'] +['ter', 'y'] +['t', 'ax'] +['M', 'AP'] +['ĠMr', 's'] +['Ġph', 'ones'] +['ĠUI', 'View'] +['"))', ');Ċ'] +['(', 'dev'] +['ĠIr', 'ish'] +['Ġw', 's'] +['D', 'I'] +['_OFF', 'SET'] +['ĠEvent', 's'] +['Ġst', 'ages'] +['Ġ}', '//'] +['Ġhab', 'en'] +['ST', 'ANCE'] +['ĠS', 'in'] +['ĠM', 'oney'] +['(t', 'op'] +['Ġappoint', 'ment'] +['VER', 'SION'] +['met', 'adata'] +['_com', 'ment'] +['Ġcolle', 'agues'] +['map', 's'] +['â', 'ĺ'] +['Ċ', 'ĉĊ'] +['(', 'al'] +['_re', 'q'] +['Ġf', 'ut'] +['Ġarchitect', 'ure'] +['ĠWH', 'ETHER'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['_s', 'creen'] +['Ġstyle', 'Urls'] +['Ġmon', 'ster'] +['.', 'up'] +['ph', 'ia'] +['Ġprocess', 'or'] +['ĠT', 'err'] +['=', "',"] +['ĠMan', 'ufact'] +['ĠN', 'T'] +['k', 'el'] +['ib', 'ern'] +['ĉf', 'ile'] +['A', 'li'] +['rient', 'ation'] +['Ġ//', '!'] +['ap', 'ore'] +['ane', 'ous'] +['ĠC', 'reat'] +['f', 'older'] +['Ġh', 'ay'] +['Sup', 'press'] +['(', 'left'] +['Ġe', 'uro'] +['Ġdis', 'claimer'] +['ustr', 'y'] +['sh', 'ips'] +['_f', 'd'] +['ĠF', 'a'] +['_in', 'sert'] +['Ġro', 'l'] +['if', 'ting'] +['ĠCom', 'ments'] +['_b', 'r'] +['Ġloss', 'es'] +['ĠAdd', 'ed'] +['ch', 'arg'] +['Ġп', 'о'] +['_s', 'ystem'] +['ĠS', 'ometimes'] +['ĠSp', 'ain'] +['(g', 'roup'] +['ial', 'is'] +['Ġdoll', 'ar'] +['ĠAr', 'gs'] +['qu', 'ires'] +['ĠT', 'en'] +['.s', 'css'] +['Ġsurv', 'ive'] +['us', 'age'] +['Ġj', 'un'] +['im', 'iter'] +['ï¼ģ', 'ĊĊ'] +['Ġfif', 'th'] +['t', 'oggle'] +['Ġdecl', 'ine'] +['($', '"'] +['(L', 'ong'] +['ing', 'e'] +['Ġpil', 'ot'] +['-l', 'ight'] +['-r', 'adius'] +['Ġpod', 'cast'] +['Ġnatur', 'ally'] +['P', 'ages'] +['ä¸', 'º'] +['ĠDes', 'pite'] +['Ġlight', 'ing'] +['Ġcr', 'ate'] +['ĠB', 'inary'] +['Ġredu', 'cing'] +['Ġe', 'leg'] +['ĠM', 'ouse'] +['ĠTest', 'Bed'] +['Ġbefore', 'Each'] +['_', 'ARRAY'] +['Red', 'irect'] +['Ġf', 'lood'] +['Ġsh', 'ips'] +['Ġelectric', 'ity'] +[')*', '('] +['ê', '¸'] +['ĠV', 'iet'] +['her', 'o'] +['Ġd', 'ia'] +['ĠK', 'ent'] +['he', 'art'] +['Ġthreat', 's'] +['_', 'acc'] +['Ġs', 'ymbols'] +['is', 'chen'] +['_in', 'st'] +['C', 'riterion'] +['ĠT', 'IM'] +['.', 'Height'] +['Ġ', 'âĢĻ'] +['();ĊĊ', 'Ċ'] +['Product', 's'] +['_S', 'P'] +['ĠC', 'y'] +['Ġdepend', 'ent'] +['est', 'e'] +['Ġdat', 'os'] +['d', 'it'] +['аÐ', '²'] +['IGN', 'AL'] +['Ġless', 'on'] +['">', "'"] +['ĠC', 'over'] +['ĠH', 'ope'] +['ĠT', 'imer'] +['Ġd', 'ad'] +['vid', 'ers'] +['ĠPh', 'ot'] +['/', '?'] +['rop', 'y'] +['om', 'ing'] +['as', 'ion'] +['Ġ\\', '('] +['ĠE', 'T'] +['ĠRe', 'ading'] +['Ġep', 'isodes'] +['l', 'm'] +['ech', 'a'] +['Ġne', 'uro'] +['Ġhar', 'mon'] +['Ġlib', 'eral'] +['-', 'ind'] +['D', 'ATA'] +['Ġevery', 'day'] +['Ġdiv', 'ided'] +['ĠActive', 'Record'] +['fig', 'ure'] +['U', 'A'] +['ä', '¹'] +['riend', 'ly'] +['te', 'ch'] +['.game', 'Object'] +['иÑĤ', 'ÑĮ'] +['Ġmo', 'on'] +['ft', 'ime'] +['Ġno', 'ch'] +['ĠT', 'ORT'] +['ĠV', 'M'] +['.in', 'itial'] +['(', 'child'] +['Ġmus', 'ical'] +['Ġo', 'c'] +['b', 'as'] +['ĠH', 'ay'] +['_l', 'ong'] +['Ġmem', 'set'] +['ile', 'y'] +['adel', 'phia'] +['S', 'V'] +['ro', 'at'] +['_t', 'x'] +['Ġl', 'on'] +['ĠngOn', 'Init'] +['b', 'p'] +['ĠGold', 'en'] +['AC', 'HE'] +['Ġwor', 'ried'] +['az', 'i'] +['E', 'ar'] +['T', 'ake'] +['(f', 'p'] +['bur', 'gh'] +['_', 'Data'] +['g', 'res'] +['ĠO', 'nt'] +['p', 'us'] +['Ġtrans', 'parent'] +['Ġp', 'ocket'] +['Ġr', 'am'] +['igr', 'ations'] +['.', 'čĊčĊ'] +['Ġ[', '('] +['Ġadopt', 'ed'] +['Ġreported', 'ly'] +['ĠD', 'ream'] +['Ġ}', '));Ċ'] +['los', 'ing'] +['Ġte', 'eth'] +['ĠBook', 's'] +['",', '&'] +['enn', 'y'] +['LE', 'MENT'] +['Ġg', 'el'] +['ĠPl', 'ant'] +['!', 'âĢĿ'] +['.h', 'ost'] +['ĠRep', 'ly'] +['re', 'ngth'] +['Ġrecogn', 'ition'] +['Ġ}}', '>Ċ'] +['L', 'A'] +['Ġmir', 'ror'] +['Ġassist', 'ant'] +['(', 'device'] +['Ġspirit', 'ual'] +['b', 'uilder'] +['Â', '§'] +['Ġou', 'tr'] +['Ġt', 't'] +['ĠP', 'ER'] +['Ġrad', 'ical'] +['Method', 's'] +['Ġp', 'ace'] +['ud', 'y'] +['Ġg', 'ut'] +['ĠG', 'reek'] +['Ġnon', 'atomic'] +['ĠP', 'aper'] +['_G', 'PIO'] +['Ġob', 'st'] +['.A', 'd'] +['viron', 'ments'] +['ĠS', 'ov'] +['(', 'con'] +['ĠTrans', 'action'] +['.', 'assign'] +['ĉc', 'atch'] +['el', 'ter'] +['Ġbit', 'coin'] +['_G', 'R'] +['ĠčĊ'] +['met', 'ic'] +['Ġtrans', 'formation'] +['åı', '·'] +['Ġr', 'gb'] +['istrib', 'utions'] +['Ġimp', 'licit'] +['/', 'in'] +['dest', 'ination'] +['аÑĤ', 'ÑĮ'] +['Z', 'ero'] +['Ġun', 'set'] +['.', 'where'] +['.g', 'o'] +['Ġform', 'ation'] +['Ġdeclar', 'ation'] +['()', 'čĊčĊ'] +['ĠEx', 'pl'] +['ĉĉĉ', 'ĠĠ'] +['/', 'pro'] +['.J', 'SON'] +['Ġdes', 'k'] +['.sub', 'str'] +['//----------------------------------------------------------------', '------------'] +['ly', 'n'] +['p', 'son'] +['dis', 'able'] +['ĠF', 'unc'] +['ĉ', 'Assert'] +['ĠM', 'ARK'] +['Ġdefe', 'at'] +['Ġbl', 'ind'] +['Ġconst', 'ants'] +['.', 'headers'] +['UIL', 'D'] +['Ġexp', 'enses'] +['P', 'ixel'] +['Ġh', 'r'] +['Ġf', 'el'] +['ĠEast', 'ern'] +['_d', 'el'] +['ĠC', 'ub'] +['Ġs', 'q'] +['ĉc', 'ount'] +['ĠD', 'irectory'] +['Ġex', 'clus'] +['Ġhistor', 'ic'] +['Ġ', '------------------------------------------------'] +['Ġcom', 'position'] +['Ġdata', 'GridView'] +['ĠB', 'urn'] +['ĠB', 'C'] +['M', 'aster'] +['Ġsp', 'awn'] +['Ġbe', 'aring'] +['.Set', 'Active'] +['il', 'o'] +['Ġg', 'allery'] +['Ġfound', 'ed'] +['Ġav', 'ailability'] +['.s', 'qrt'] +['Ġp', 'es'] +['ĠD', 'OM'] +['m', 'ate'] +['O', 'ct'] +['Ġmatch', 'ed'] +['it', 'ivity'] +['Ġan', 'xiety'] +['.pr', 'ice'] +['ĠIn', 'stant'] +['ì', 'Ĭ'] +['Ġt', 'ut'] +['IC', 'ollection'] +['.sh', 'ared'] +['_s', 'ql'] +['t', 'bl'] +['lib', 'rary'] +['_de', 'stroy'] +['erm', 'al'] +['ĠNot', 'es'] +['ĠE', 'in'] +['Ġsou', 'thern'] +['ĠOTHER', 'WISE'] +['Ġmac', 'ro'] +['.l', 'ower'] +['cl', 's'] +['Content', 'View'] +['.l', 'ink'] +['const', 'ant'] +['ĠB', 'es'] +['Ġsome', 'body'] +['n', 'b'] +['">', '{'] +['(', 'local'] +['..', '...'] +['ĠN', 'ull'] +['m', 'x'] +['ĠÃ', '§'] +['Ġp', 'ause'] +['--------', '---'] +['_M', 'O'] +['ĠC', 'M'] +['Ġfor', 'Key'] +['ĠD', 'VD'] +['Ġclose', 'st'] +['_DE', 'VICE'] +['ĠSte', 'phen'] +['ĠB', 'BC'] +['ĠTr', 'avel'] +['P', 'aint'] +['ĠResult', 's'] +['ĠR', 'ule'] +['Ġt', 'p'] +['Ġrat', 'ings'] +['c', 'in'] +['c', 'sv'] +['>', '/'] +['ĠG', 'OP'] +['l', 'ad'] +['Ġ', 'ÑĢ'] +['Ġindex', 'Path'] +['m', 'atrix'] +['=', 'f'] +['ars', 'ed'] +['Ġ}', ');'] +['ĠC', 'os'] +['ĠS', 'core'] +['Ġt', 'ak'] +['ĠE', 'SP'] +['ĠIN', 'C'] +['_N', 'ULL'] +['-f', 'lex'] +['"]', '['] +['int', 'o'] +['el', 'and'] +['Author', 'ization'] +['_F', 'ALSE'] +['Ġg', 'ate'] +['Ġv', 'id'] +['ist', 'ent'] +['T', 'IME'] +['Ġre', 'write'] +['Ġt', 'ie'] +['Ġarch', 'ive'] +['.event', 's'] +['.get', 'Parameter'] +['ĠPer', 'mission'] +['Ġprogram', 'me'] +['Ġ', 'é'] +['j', 'ud'] +['Ġcam', 'eras'] +['(s', 'ys'] +['ĠSy', 'rian'] +['Ġimpro', 'vements'] +['Ġh', 'ip'] +['Ġsu', 'icide'] +['Ġsch', 'olar'] +['Ġcompat', 'ible'] +['rem', 'ote'] +['.d', 'own'] +['F', 'UNCTION'] +['Ġman', 'aging'] +['ĠUI', 'Kit'] +['.', 'raw'] +['>>', '>>'] +['Ġdem', 'ands'] +['ell', 'ite'] +['Ġd', 'ent'] +['ĠM', 'icro'] +['åı', 'ĸ'] +["']", '[$'] +['ĠI', 'E'] +['im', 'ension'] +['Ġt', 'rem'] +['Ġg', 'ained'] +['.w', 'ith'] +['.', 'ok'] +['h', 'ou'] +['Ġb', 'om'] +['amp', 'aign'] +['Ġjoin', 'ing'] +['f', 'ish'] +['Ġadd', 'Subview'] +['Ġnor', 'thern'] +['.c', 'or'] +['ore', 't'] +['D', 'ie'] +['in', 'ish'] +['_com', 'p'] +['Ġatt', 'ended'] +['Ġcoll', 'apse'] +['ĠS', 'S'] +['ac', 'ent'] +['_E', 'QUAL'] +['ĠDe', 'ep'] +['R', 'GB'] +['ĉ', 'test'] +['ol', 'ves'] +['us', 'et'] +['Un', 'ityEngine'] +['w', 'riter'] +['Res', 'olver'] +[',', '%'] +['if', 'ference'] +['_re', 'move'] +['ond', 'a'] +['Ġfem', 'me'] +['de', 'code'] +['Br', 'anch'] +['Ġfl', 'ush'] +['Ġinnov', 'ative'] +['Test', 's'] +["Ġ['", './'] +['Ġcover', 'ing'] +['.', 'admin'] +['ultip', 'art'] +['(l', 'ambda'] +['', 'namespace'] +['ĠS', 'port'] +['Ġ!', '('] +['ac', 'les'] +['Ġde', 'pression'] +['ĠK', 'ong'] +['Ġp', 'ert'] +['ĠCon', 'n'] +['ĠOther', 'wise'] +['/', 'home'] +['s', 'upported'] +['Ġp', 'ink'] +['Ġinv', 'ited'] +['ñ', 'os'] +['_en', 'abled'] +['Ġ-', 'Ċ'] +['F', 'W'] +['en', 'ers'] +['ĠM', 'Y'] +['Ġsuggest', 'ions'] +['Can', 'vas'] +['Ġf', 'er'] +['ĠMarket', 'ing'] +['@', 'Test'] +['unt', 'u'] +['ĠV', 'en'] +['ĠC', 'ou'] +['iv', 'als'] +['Don', 'ald'] +['lim', 'ited'] +['ĉĉĉĉĉĉ', 'Ċ'] +['Ġanal', 'yst'] +['(', 'entry'] +['Ġrepresent', 'ative'] +['_at', 'tributes'] +['Ġf', 'ur'] +['.h', 'ide'] +['res', 'p'] +['ado', 'res'] +['rid', 'es'] +['ĠJ', 'osh'] +['ro', 'bot'] +['ĠN', 'AT'] +['Ġs', 'esso'] +['Ġintegr', 'ated'] +[':', 'true'] +['part', 's'] +['Ġst', 'upid'] +[':', 'event'] +['@end', 'section'] +['Ġp', 'u'] +['.T', 'able'] +['ĠY', 'ii'] +['`', ';ĊĊ'] +['Ġcl', 'ang'] +['="', '">'] +['eng', 'an'] +['_param', 'eters'] +['.int', 'ernal'] +['ĠMod', 'ern'] +['Ġmet', 'ric'] +['Ġsem', 'i'] +['={', '{Ċ'] +['.am', 'azon'] +['ĠB', 'B'] +['aint', 'y'] +['view', 'port'] +['Ġstart', 'Activity'] +['dis', 'patch'] +['****', '*'] +['Ġfl', 'av'] +['iffer', 'ent'] +['[', 'this'] +['Ġst', 'ake'] +['Ġarg', 'ued'] +['vious', 'ly'] +['.w', 'ork'] +['ĠO', 'ak'] +['O', 'ld'] +['(', 'async'] +['not', 'es'] +['Ġfl', 'ip'] +['Ġdis', 'ag'] +['ĠT', 'E'] +['ĉ', 'error'] +['<', "'"] +['Ġ»', 'ĊĊ'] +['Ġfilter', 'ed'] +['ĠM', 'ach'] +['Ġh', 'ung'] +['_d', 'ump'] +['_s', 'amples'] +['-dis', 'miss'] +['Ġr', 'ay'] +['Im', 'plemented'] +['D', 'K'] +['Ġj', 'ed'] +['Ġbreak', 's'] +['Ġf', 'its'] +['.', 'gr'] +['ĠZ', 'ero'] +['or', 'o'] +['Ġequ', 'ally'] +["Ġ'", '['] +['Ġconcern', 'ing'] +['<', 'meta'] +['play', 'ers'] +['_P', 'OS'] +['_s', 'im'] +['J', 'an'] +['Ġyour', 's'] +['ĉ', 'N'] +['Ġsp', 'ir'] +['Ġch', 'ampion'] +['ĠAn', 'alysis'] +['ap', 'a'] +['ĠNS', 'Log'] +['_l', 'ines'] +['ñ', 'a'] +['ĉĉ', 'ĠĠĠĠĠĠĠ'] +['.S', 'c'] +['Re', 'p'] +['etro', 'it'] +['ur', 'able'] +['M', 'IT'] +['com', 'pat'] +['own', 'ed'] +['_ind', 'ices'] +['],', 'čĊ'] +['Ġdis', 'covery'] +['ĠDie', 'go'] +['ob', 'i'] +['.', 'Index'] +['Ġtrend', 's'] +['PL', 'AY'] +['.n', 'o'] +['Ġl', 'ens'] +['_c', 'fg'] +['Ġan', 'no'] +['ag', 'an'] +['Ġperiod', 's'] +['ter', 'ms'] +['y', 'z'] +['Ġattack', 'ed'] +['ib', 'ration'] +['PEC', 'IAL'] +['_', 'grad'] +['Ġaccord', 'ance'] +['.Read', 'Line'] +['.de', 'vice'] +['ri', 'x'] +['.', 'container'] +['m', 'ay'] +['erc', 'ise'] +['ĠL', 'u'] +['Ġr', 'g'] +['ĠÑģ', 'ÑĤ'] +['ĉĉĊ', 'ĉĉĊ'] +['(', 'un'] +['TERN', 'AL'] +['Ġless', 'ons'] +['Ġalleg', 'ations'] +['Ġtrans', 'mission'] +['.Re', 'f'] +['M', 'obile'] +['ĠT', 'ournament'] +['ĠN', 'ut'] +['ĠG', 'a'] +['ĠCap', 'ital'] +['def', 'inition'] +['-', 'exp'] +['c', 'lean'] +['Ġfant', 'asy'] +['Ġenh', 'ance'] +['ent', 'ence'] +["']", ':Ċ'] +['ack', 'ets'] +['Ġcelebr', 'ate'] +['@', '",'] +['Serialize', 'Field'] +['Ġarray', 's'] +['t', 'b'] +['ĉ', 'st'] +['[', 'assembly'] +['(', 'reg'] +['.c', 'ategory'] +['Ġimpro', 'ving'] +['Ġsal', 'ope'] +['Byte', 'Array'] +['Or', 'iginal'] +['Ġ[', '{Ċ'] +['åĽ', 'ŀ'] +['ĠCl', 'in'] +['oen', 'ix'] +['ĠS', 'amsung'] +['Ġmaint', 'ained'] +['Ġag', 'enda'] +['f', 'ail'] +['Ġpres', 'ents'] +['Ġtim', 'ing'] +['.m', 'ark'] +["'", '><'] +['Ġprom', 'ot'] +['Ġin', 'cl'] +['_', 'only'] +['ë¥', '¼'] +['ĠAtt', 'orney'] +['-', 'date'] +['Ġlands', 'cape'] +['Ġf', 'u'] +['S', 'Y'] +['.p', 'rop'] +['ĠA', 'rr'] +['p', 'ag'] +['Parallel', 'Group'] +["':", 'čĊ'] +['Ġlog', 's'] +['a', 'unch'] +['unc', 'i'] +['n', 'ama'] +['Table', 'Cell'] +['iss', 'ues'] +['.', '{'] +['ec', 'urity'] +['_ex', 'ec'] +['old', 's'] +['Ġhost', 's'] +['Ġpro', 'to'] +['_', 'import'] +['_s', 'ort'] +['ĠB', 'ow'] +['ĠN', 'ormal'] +['ĠF', 'arm'] +['.create', 'ParallelGroup'] +['R', 'otation'] +['.', 'err'] +['Ġp', 'leased'] +['it', 'age'] +['.W', 'h'] +['ĉĉ', 'ĠĠĠĠ'] +['M', 'R'] +['ĠM', 'ORE'] +['ĠN', 'atural'] +['_', 'transform'] +['B', 'ASE'] +['ener', 'al'] +['ut', 'down'] +['.common', 's'] +['W', 'T'] +['Ġa', 'an'] +['.', 'Result'] +['d', 'og'] +['Ġclick', 'ing'] +['),', 'ĊĊ'] +['#', 'line'] +['Oper', 'ator'] +['Ġc', 'iv'] +['Ġm', 'erg'] +['ob', 'uf'] +['ng', 'then'] +['Ġ[', '{'] +['Ġcan', 'cell'] +['tr', 'igger'] +['.', ':'] +['W', 'ORK'] +['decl', 'are'] +['Ġdecre', 'ase'] +['ÅĽ', 'ci'] +['lo', 'om'] +['.N', 'one'] +['ĠM', 'I'] +['ĠJ', 'ason'] +['Ġhealth', 'care'] +['iam', 'ond'] +['s', 'ylvania'] +['*', 'x'] +['ĠR', 'a'] +['[', 'b'] +['Ġprint', 'ing'] +['ph', 'abet'] +['ĠLab', 'our'] +['op', 'per'] +['Ġz', 'ijn'] +['-t', 'arget'] +['_F', 'UNCTION'] +['Ġo', 'ct'] +['ени', 'Ñı'] +['åľ', '¨'] +['Ġwest', 'ern'] +['Ġcomput', 'ers'] +['ĠR', 'ET'] +['Hash', 'Map'] +['[', 'String'] +['get', 'Value'] +['_D', 'ATE'] +['.N', 'ext'] +['ĠF', 'if'] +['é', 'l'] +['ick', 'ed'] +['æ', 'İ'] +['-M', 'M'] +['Ġ{', 'ĊĊĊ'] +['Ġcontact', 's'] +['Ġdig', 'its'] +['Pro', 'du'] +['Ġunus', 'ual'] +['Ġrapid', 'ly'] +['t', 'ures'] +['Ġang', 'ry'] +['c', 'ancel'] +['xx', 'xx'] +['_p', 'arser'] +['id', 'ity'] +['_P', 'REFIX'] +['Ġme', 'hr'] +['Ġrare', 'ly'] +['et', 'he'] +['op', 'es'] +['Ġ%', '.'] +['work', 's'] +['Ġthe', 'ta'] +['Ġcontrib', 'ution'] +['ĠT', 'ony'] +['Ġsqu', 'ad'] +['аÐ', '¹'] +['Ġî', 'n'] +['th', 'ere'] +['out', 'ed'] +['ĉ', 'q'] +['Ļ', 'Ĥ'] +['g', 'ood'] +['L', 'I'] +['é¡', 'µ'] +['ĠL', 'iving'] +['iz', 'abeth'] +['Ġk', 't'] +['ĠD', 'allas'] +[']', '],Ċ'] +['Ġ/', '>ĊĊ'] +['Ġrais', 'ing'] +['/r', 'outer'] +['_g', 'ame'] +['ĠC', 'UR'] +['z', 'ens'] +['.', 'es'] +['Ġfont', 'Weight'] +['(f', 'unc'] +['not', 'ification'] +["Ġ'../../", '../'] +['Ġbl', 'ame'] +['ãĢĤ', 'ĊĊĊĊ'] +['an', 'co'] +['Id', 'entity'] +['f', 'ollow'] +['Ġart', 's'] +['x', 's'] +['Ġofficial', 'ly'] +['ĠSt', 'udio'] +['Ġrecommend', 'ations'] +['Ġloc', 'ale'] +['Ġam', 'ateur'] +['ĠEn', 'able'] +['Ġcap', 's'] +['.', 'End'] +['-', 'add'] +['_g', 'shared'] +['ĠC', 'T'] +['For', 'ce'] +['Ċ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĊ'] +['Ġor', 'ange'] +['Ġl', 'p'] +['Ġanswer', 'ed'] +['.G', 'rid'] +['Ġd', 'ual'] +['Ġstrateg', 'ic'] +['Ġnob', 'ody'] +['Ġf', 'atal'] +['_', 'est'] +['(', 'el'] +['Ġì', 'ł'] +['ĠB', 'udd'] +['A', 'IT'] +['_f', 'actor'] +['-', 'one'] +['ĠH', 'AVE'] +['"', 'čĊčĊ'] +['Pro', 'f'] +['Ġä', 'r'] +['str', 'ings'] +['Ġdir', 'ty'] +['ĠF', 'ace'] +['ĠB', 'egin'] +['ĠB', 'us'] +['Ġw', 'is'] +['åŃ', 'Ĺ'] +['Ġspe', 'aker'] +['Ġcar', 'rier'] +['ĠO', 'm'] +['Ġhad', 'n'] +['All', 'ow'] +['::', '__'] +['Ġver', 'b'] +['ĠCom', 'plete'] +['ĠE', 'asy'] +['Ġb', 'ills'] +['ĠĠ', 'ĊĊ'] +['Vert', 'ical'] +['Ġpr', 'on'] +['ĠDef', 'ine'] +['Ġlook', 'up'] +['variable', 's'] +['Ġpand', 'as'] +['um', 'es'] +['Ġinn', 'oc'] +['Ġset', 'Up'] +['ĠCh', 'ampionship'] +['art', 'ist'] +['ĠC', 'Type'] +['F', 'oundation'] +['à¹', 'Ī'] +['ĠSet', 'up'] +['Ġrec', 'ipes'] +['ĠU', 'IColor'] +['ĠF', 'ight'] +['Ġauthor', 'ized'] +['_c', 'lick'] +['_s', 'uccess'] +['ang', 'an'] +['ĠMount', 'ain'] +['ĠDo', 'ctor'] +['Ġeg', 'g'] +['ĠMedic', 'ine'] +['c', 'les'] +['`', '.Ċ'] +['[', 'int'] +['d', 'ashboard'] +['ĠApp', 'ro'] +['-d', 'r'] +['Ġprodu', 'ces'] +['Ġrent', 'al'] +['Ġre', 'load'] +['Ġarr', 'ival'] +['sp', 'ot'] +['Ġund', 'ert'] +['Ġequ', 'ipped'] +['Ġpro', 'ved'] +['Ġcent', 'ers'] +['Ġdef', 'ines'] +['al', 'so'] +['Ġop', 'acity'] +['ĠUn', 'fortunately'] +['ĠIll', 'inois'] +['Ġн', 'е'] +['ĠTem', 'ple'] +['ĠTr', 'ail'] +['ĠK', 'elly'] +['Ġmeasure', 'ment'] +['Ġsepar', 'ated'] +['-c', 'ircle'] +['H', 'ey'] +['ĠRE', 'AD'] +['ig', 'its'] +['Ġ', 'ib'] +['ĠM', 'OD'] +['atter', 'y'] +['аÐ', '·'] +['Ġv', 'end'] +['ен', 'ÑĤ'] +['ĠHttp', 'Client'] +['s', 'afe'] +['_A', 'SS'] +['ic', 'it'] +['ĠCon', 'struct'] +['ĠC', 'lo'] +['ĠS', 'ix'] +['_T', 'OKEN'] +['(b', 'lock'] +['Ġwarn', 'ed'] +['/*', '!'] +['!', 'Ċ'] +['Ġinnov', 'ation'] +['_', '"'] +['Ġ', ');čĊčĊ'] +['Ġsp', 'ots'] +['Ġcho', 'osing'] +['.c', 's'] +['Ġflex', 'ible'] +['U', 'Int'] +['Ġscr', 'atch'] +['-', 'al'] +['Ġf', 'estival'] +['Ġout', 'standing'] +['================================', '================'] +['M', 'ean'] +['ĠO', 'regon'] +['s', 'ymbol'] +['.', 'account'] +['d', 'ney'] +["''", "'"] +['!', '",'] +['Ġpart', 'icle'] +['Ã', 'ĥ'] +['[', 'MAX'] +['IV', 'ER'] +['ER', 'ENCE'] +['NS', 'Mutable'] +['ĠColum', 'bia'] +['_', 'ĊĊ'] +['.f', 'r'] +['Ġc', 'ogn'] +['V', 'R'] +['ĠMethod', 's'] +['ĠM', 'ade'] +['ĠB', 'R'] +['ĠEl', 'se'] +['Ġeg', 'gs'] +['Ġsw', 'ing'] +['ĠIn', 'v'] +['Ġdise', 'ases'] +['Ġf', 'irms'] +['Ġle', 'mma'] +['}`', ');Ċ'] +['l', 'ings'] +['Ġg', 'ym'] +['umin', 'um'] +['.T', 'rim'] +['M', 'em'] +['Ġcritic', 'ism'] +['ibern', 'ate'] +['_T', 'X'] +['ion', 'i'] +['Ġguid', 'ance'] +['Ġrepeated', 'ly'] +['Ġsup', 'plier'] +['Ġpaint', 'ing'] +['.F', 'ragment'] +['ed', 'Exception'] +['Ġw', 'iring'] +['Ġcour', 'ts'] +['W', 'EB'] +['æľ', 'ī'] +['\\', '.'] +['ill', 'ance'] +['Ġb', 'rows'] +['ĠP', 'attern'] +['PL', 'ICATION'] +['ĠSum', 'mer'] +['Ch', 'ain'] +['Ġc', 'ute'] +['mer', 'cial'] +['Ġd', 'il'] +['ĠFrank', 'lin'] +['ĉg', 'lobal'] +['IN', 'CLUDING'] +['h', 'istory'] +['Ġl', 'st'] +['Q', 't'] +['SD', 'L'] +['al', 'ia'] +['i', 'ere'] +['(', '...'] +['ĉc', 'in'] +['iff', 's'] +['vel', 'ope'] +['ĠR', 'oot'] +['cl', 'uster'] +['User', 'Name'] +['ign', 'e'] +['<', 'S'] +['Ġf', 'est'] +['Ġindic', 'ating'] +['ke', 'eper'] +['Ġc', 'ada'] +['é', 'g'] +['cons', 'in'] +['ĠG', 'B'] +['Ġl', 'b'] +['em', 'ony'] +['-icon', 's'] +['_d', 'oc'] +['Act', 'or'] +['e', 'lem'] +['.De', 'lete'] +['Ġin', 'fection'] +['ĠPriv', 'acy'] +['Ġgreat', 'ly'] +['ĠP', 'os'] +['ĠT', 'reat'] +['Fl', 'ow'] +['Ġattract', 'ive'] +['ĠMar', 'c'] +['s', 'udo'] +['tes', 'y'] +['-', 'an'] +['ab', 'ama'] +['ĠW', 'ould'] +['Ġsu', 'ck'] +['index', 'Path'] +['ĠE', 't'] +['T', 'imes'] +['Ġclub', 's'] +['_ass', 'oc'] +['Ġac', 'quired'] +['("', ':'] +['Ġint', 'ense'] +['.m', 'aps'] +['Ex', 'pected'] +['T', 'oggle'] +['Ġa', 'y'] +['Ġl', 'ifestyle'] +['-c', 'alled'] +['ĠS', 'now'] +['V', 'olume'] +['Ġcann', 'abis'] +['ĠD', 'irection'] +['ĠLim', 'ited'] +['-s', 'pecific'] +['Ġd', 'owntown'] +['/', 'icons'] +['Ġre', 'ven'] +['L', 'eg'] +['=', 'null'] +['Key', 'board'] +["')", ').'] +['Ġ""', ';čĊ'] +['Ġatt', 'itude'] +['.n', 'avigate'] +['-', 'error'] +['AM', 'PLE'] +['ĠJ', 'ay'] +['v', 'r'] +['c', 'ow'] +['.com', 'pile'] +['Ġmem', 'ories'] +['_m', 'ark'] +['ĠMin', 'nesota'] +['Ġk', 'osten'] +['Ġprob', 'ability'] +['w', 'arning'] +['Ġgen', 'etic'] +['F', 'ixture'] +['ĠHash', 'Set'] +['N', 'ombre'] +['_m', 'onth'] +['Æ', '°'] +['-', 'start'] +['xy', 'gen'] +['ĉ', 'ft'] +['i', 'agnostics'] +['ĠMat', 'thew'] +['Ġconcept', 's'] +['Ġcon', 'str'] +['.', 'State'] +['и', 'н'] +['N', 'ov'] +['Î', '±'] +['ĠP', 'anel'] +['ä¸', 'ª'] +['com', 'pare'] +['>', '()Ċ'] +['Ġapply', 'ing'] +['Ġprom', 'ised'] +['Ġo', 'x'] +['nc', 'ia'] +['ĠValid', 'ation'] +['ort', 's'] +['_c', 'ur'] +['e', 'lect'] +['ey', 'e'] +['(', 'Data'] +['Ġreport', 'er'] +['ĠB', 'uff'] +['Ġs', 'r'] +['Ġ"', ';'] +['ick', 'y'] +['Ġtemp', 'or'] +['S', 'N'] +['Ġres', 'ident'] +['pi', 'res'] +['ys', 'ical'] +['Ġend', 'orse'] +['ĠS', 'ong'] +['is', 'Empty'] +['le', 'et'] +['_', 'util'] +['Ġdist', 'ingu'] +['ĠT', 'alk'] +['ĠM', 'ot'] +['(', 'default'] +['.A', 'rg'] +['gorith', 'ms'] +['_', 'words'] +['im', 'mer'] +['_res', 'et'] +['f', 'amily'] +['W', 'W'] +['Ġsav', 'ings'] +['ĠâĢ', 'Ŀ'] +['_en', 'able'] +['side', 'bar'] +['Run', 'ning'] +['Ġal', 'i'] +['Ġtest', 'im'] +['Ġwarn', 'ings'] +['ĠCh', 'em'] +['ĠEx', 'it'] +['Ġfound', 'er'] +['pect', 'or'] +['Ġr', 'm'] +['_d', 'ataset'] +['ĠD', 'as'] +['Ġh', 'an'] +['Get', 'ty'] +['á', 'l'] +['Ġn', 'y'] +['Ġpo', 'verty'] +['Ġresult', 'ed'] +['.b', 'y'] +['ĠVis', 'it'] +['Ġobt', 'aining'] +['/', "'.$"] +['ĠĠĠĠĠĠĠĠĠĠĠ', 'Ċ'] +['sh', 'all'] +['_LE', 'FT'] +['UI', 'Image'] +['_', 'Name'] +['h', 'ave'] +['ĠN', 'ob'] +['l', 'r'] +['-', 'footer'] +['Ġn', 'aked'] +['ĠG', 'arden'] +['\\F', 'acades'] +['Ġgrad', 'uate'] +['Ġfranch', 'ise'] +['pl', 'ane'] +['Ġcontrib', 'utions'] +['Ġstring', 'With'] +['Ġc', 'rypto'] +['Ġmov', 'ements'] +['ath', 'ers'] +['Ġlif', 'etime'] +['Ġcommunic', 'ate'] +['j', 'ar'] +['ĠFr', 'agment'] +['_', 'IF'] +['ĠN', 'avy'] +['ĠF', 'igure'] +['Ġsim', 'ulation'] +['_st', 'op'] +['Ġreport', 'ers'] +['Ġvers', 'us'] +['aj', 'a'] +['ĠÎ', '±'] +['Ġgovern', 'or'] +['List', 'Item'] +['Ġse', 'aled'] +['.Back', 'ground'] +['ed', 'i'] +['ash', 'ing'] +['Ġl', 'ip'] +['ĠI', 'h'] +['mer', 'ge'] +['Ġn', 'ec'] +['el', 'ocity'] +['ATE', 'G'] +['Ġse', 'eds'] +['Ġflo', 'ating'] +['_F', 'A'] +['w', 'alk'] +['ĉ', 'user'] +['_de', 'pth'] +['Ġw', 'age'] +['@', 'app'] +['N', 'il'] +['(', '["'] +['(', 'vector'] +['Ġsecret', 'ary'] +['Ġj', 'Panel'] +['ve', 'z'] +['³³', '³³'] +['d', 'irection'] +['ĠE', 'P'] +['Ġh', 'unt'] +['Json', 'Property'] +['ĠP', 'ORT'] +[']', '",'] +['аÐ', '¿'] +['ĠFore', 'ign'] +['pan', 'ic'] +['Ġtri', 'als'] +['ĠA', 'le'] +['Ġr', 'ural'] +['-', 'value'] +['author', 'ized'] +['ĠScot', 'land'] +['.d', 'rop'] +['ĠM', 'T'] +['ç', '±'] +['row', 'th'] +['File', 'Path'] +['Ġrec', 'all'] +['if', 'le'] +['Ġc', 'el'] +['ĠSE', 'LECT'] +['k', 'n'] +['_c', 'ase'] +['Ġc', 'rop'] +['s', 'ure'] +['p', 'ot'] +['IC', 'S'] +['Ġst', 'em'] +['Ġindust', 'ries'] +['P', 'ut'] +['Ġa', 'ber'] +['road', 'cast'] +['Icon', 's'] +[')', '")Ċ'] +['æĪIJ', 'åĬŁ'] +['g', 'ui'] +['Ġassum', 'ed'] +['Ġr', 'x'] +['E', 'A'] +['è', '§'] +['EL', 'L'] +['Ġdo', 'se'] +['Ġin', 'e'] +['Ġde', 'eper'] +['l', 'ider'] +['Ġord', 'inary'] +['Ġg', 'olf'] +['_IM', 'AGE'] +['ĠN', 'AME'] +['(m', 'odule'] +['Ġat', 'om'] +['Ġbel', 't'] +['Ġoff', 'ices'] +['b', 'eta'] +['Ġphilosoph', 'y'] +['(', 'JSON'] +['-f', 'ield'] +['Ġintrodu', 'ce'] +['Ġconven', 'ience'] +['opt', 'im'] +['>', '"Ċ'] +['ath', 'y'] +['Ġemploy', 'er'] +['qu', 'ate'] +['Ġed', 'ited'] +['Arg', 'uments'] +['ĠN', 'ations'] +['__', ')'] +['Ġno', 'se'] +['ĠS', 'ample'] +["'", ')ĊĊĊ'] +['Ġc', 'ake'] +['.get', 'Attribute'] +['H', 'D'] +['Mod', 'ified'] +['Ġpredict', 'ed'] +['Å', 'Ħ'] +['an', 'ie'] +['S', 'orry'] +['(d', 'oc'] +['w', 'ind'] +['ie', 've'] +['Ġprov', 'isions'] +['AT', 'ER'] +['OT', 'E'] +['M', 'Y'] +['.A', 'utowired'] +['ĠB', 'ath'] +['.', 'Boolean'] +['Ġback', 'end'] +['.M', 'ouse'] +['ater', 'al'] +['p', 'aper'] +['Con', 'st'] +['ĠV', 'R'] +['_', 'entity'] +['_C', 'TRL'] +['ĠProte', 'ction'] +['ĠG', 'M'] +['ĠStud', 'y'] +['Ġsou', 'p'] +['ot', 'ime'] +["'", 'use'] +[']', '"'] +['/', 'users'] +['a', 'ug'] +['ĠH', 'ong'] +['_n', 'orm'] +['ãģ', '¨'] +['Ġse', 'cre'] +['(B', 'uild'] +['ĠCon', 'tract'] +['ol', 'as'] +['Ġsa', 'uce'] +['Ġaggress', 'ive'] +['Ġrac', 'ial'] +['char', 'acter'] +['@', '@'] +['Ġcomp', 'ile'] +['ĠV', 'oid'] +['_re', 'm'] +['_m', 'emory'] +['k', 'k'] +['Ġm', 'ic'] +['S', 'ame'] +['U', 'tility'] +['ĠH', 'tml'] +['ĠX', 'ml'] +['Read', 'y'] +['Ġg', 'all'] +['Ġalleged', 'ly'] +['ĉĉĉĉ', 'ĠĠĠ'] +['ĠMet', 'al'] +['ĠPerson', 'al'] +['Ġborder', 'Radius'] +['rx', 'js'] +['object', 's'] +['Ġwant', 'ing'] +['Ġb', 'owl'] +['v', 'endor'] +['offset', 'of'] +['ĠR', 's'] +['ĠR', 'ating'] +['Ġr', 'ally'] +['_N', 'ODE'] +['ĠM', 'ix'] +['Ġadvert', 'is'] +['Ġnarr', 'ative'] +['s', 'al'] +['Ġm', 'c'] +['SE', 'rror'] +['Ġf', 'ingers'] +['Ġaccom', 'pany'] +['Ġt', 'ired'] +['Ġstr', 'ide'] +['Ġgu', 'i'] +['el', 'ist'] +['Loc', 'ale'] +['Ġrele', 'ases'] +['ik', 'ing'] +['Ġan', 'ger'] +['))', ')ĊĊ'] +['alle', 'st'] +['Sum', 'mary'] +['(', 'O'] +['(f', 'or'] +['Ġbasket', 'ball'] +['Ġroad', 's'] +['ĠInst', 'all'] +['ĠF', 'ab'] +['it', 'map'] +['Ġ)', ')Ċ'] +['Ġinter', 'section'] +['ighb', 'or'] +['ĠB', 'ry'] +['ĠHER', 'E'] +['So', 'ftware'] +['elf', 'are'] +['ac', 's'] +['Ġtrail', 'er'] +['.get', 'Class'] +['ch', 'ars'] +['Ġreg', 'ulation'] +['Ġref', 'ers'] +['Ġde', 'struction'] +['Ġcontin', 'uous'] +['ĠAust', 'in'] +['é', '¢'] +['ak', 'an'] +['.w', 'indow'] +['ĠTem', 'plates'] +['Ġabs', 'ence'] +[':', 'n'] +['Ġdis', 'order'] +['fl', 'ash'] +['Ġde', 'let'] +['bo', 'ards'] +['ĠĠ', 'ĉ'] +['RO', 'P'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġac', 'qu'] +['Ġlaws', 'uit'] +['ĠRe', 'views'] +['Ġgar', 'age'] +['t', 'imer'] +['Ġe', 'j'] +['ĠRect', 'angle'] +['Ġflow', 'ers'] +['il', 'st'] +['ĠIn', 'stance'] +['S', 'uper'] +['d', 'et'] +['dis', 'posing'] +['ĠE', 'S'] +['ĠI', 'C'] +['ver', 'e'] +['S', 'k'] +['_ch', 'annels'] +['put', 'ed'] +['/', 'null'] +['nn', 'en'] +['ĠG', 'allery'] +['_g', 'lobal'] +['Auth', 'entication'] +['ĠR', 'ank'] +['Ġblock', 'ed'] +['Ġcal', 'm'] +['mark', 'et'] +['ĉ', 'val'] +['Ġa', 'ug'] +['per', 'iod'] +['ĠCon', 'stant'] +['Ġ?>', '">Ċ'] +['Ġl', 'obby'] +['p', 'al'] +['Ġs', 'ink'] +['ia', 'h'] +['Ð', '¡'] +['urn', 'ame'] +['Ġcon', 'ver'] +['Ġinvestig', 'ate'] +['Ch', 'rist'] +['H', 'ub'] +['ĠIN', 'D'] +['ĠP', 'ed'] +['ur', 'as'] +['ĉ', 'url'] +['ĠT', 'ro'] +['Ġpre', 'ferences'] +['Ġguarante', 'ed'] +['`', 'ĊĊ'] +['Ġport', 'ions'] +['Ġeval', 'u'] +["'", '>', ';ĊĊ'] +['.AutoScale', 'Mode'] +['Ġc', 'ats'] +['Ġreg', 'istry'] +['ul', 'us'] +['F', 'I'] +['p', 'ayload'] +['-', 'search'] +['Ġstay', 'ing'] +['ac', 'ious'] +['Dec', 'oration'] +['Re', 'view'] +['In', 'f'] +['Ke', 'ep'] +['it', 'is'] +[',', 'String'] +['Co', 'ord'] +['Ġper', 'o'] +['S', 'ex'] +['ĠAtl', 'anta'] +['uest', 'a'] +['Arg', 'b'] +['>', '*'] +['}', '_'] +['F', 'ooter'] +['Ġemploy', 'ed'] +['_b', 'ound'] +['v', 'ide'] +['.f', 'unc'] +['$', 'scope'] +['Ġsp', 'o'] +['ĠAn', 'al'] +['ounc', 'ed'] +['ar', 'ound'] +['Ġrestr', 'iction'] +['Ġsh', 'ops'] +['å', 'Ģ'] +['ĠLat', 'in'] +['-c', 'ol'] +['Ġbare', 'ly'] +['ĠE', 'uro'] +['E', 'r'] +['Ġfa', 'ire'] +['_d', 'istance'] +['_un', 'lock'] +['Qu', 'ote'] +['IV', 'ATE'] +['Ġå', 'Ī'] +['Ġaim', 'ed'] +['ĠRet', 'rie'] +['.', 'iter'] +['Ġwr', 'apped'] +['Ġagre', 'ements'] +['str', 'ument'] +['(', 'product'] +['Ġstud', 'ied'] +['.set', 'Value'] +['Ġy', 'e'] +['ĠC', 'ache'] +['MB', 'OL'] +['Ġquarter', 'back'] +['Ġsy', 'ntax'] +['.getElements', 'By'] +['.v', 'ersion'] +['we', 'bsite'] +['Run', 'ner'] +['_s', 'ingle'] +['at', 'iv'] +['ĠAl', 'tern'] +['ĠBeaut', 'iful'] +['right', 'arrow'] +['Ġd', 'iversity'] +['pl', 'ash'] +['(', 'co'] +['.F', 'ill'] +['Ġtyp', 'ing'] +['Ġcl', 'ar'] +['H', 'it'] +['O', 'O'] +['ac', 'co'] +['w', 'orth'] +['Ġscript', 's'] +['ĠMuslim', 's'] +['ĠL', 'L'] +['erv', 'ing'] +['(', 'boolean'] +['Ġbase', 'ball'] +['ĠC', 'AN'] +['MA', 'IL'] +['de', 'pend'] +['Ġrespect', 'ive'] +['Ġconst', 'expr'] +['.*', ';ĊĊ'] +["']", '))Ċ'] +['Ġy', 'ard'] +['Ġident', 'ical'] +['if', 'ecycle'] +['US', 'H'] +['up', 'iter'] +['.', 'validate'] +['cl', 'i'] +['IST', 'ER'] +['Ind', 'icator'] +['F', 'ail'] +['Ġdemocr', 'acy'] +['.', 'var'] +['Ġsatisf', 'ied'] +['------------', '-'] +['enc', 'er'] +['h', 'or'] +['Ġr', 'ounds'] +['DA', 'O'] +['o', 'a'] +['Ġfl', 'ask'] +['=', 'c'] +['[', ']Ċ'] +['/d', 'ist'] +['Ġpart', 'e'] +['Ġconfirm', 'ation'] +['er', 'on'] +['aw', 'are'] +[''] +['Ġdepend', 'encies'] +['ĠV', 'ideos'] +['-', 'row'] +['Ġ**', '/Ċ'] +['Ġn', 'ou'] +['Ġh', 'over'] +['æ', 'ŀ'] +['Ġn', 'in'] +['ĠUS', 'D'] +['M', 'ac'] +['_L', 'oad'] +['Ġout', 'comes'] +['_s', 'ocket'] +['Ġqu', 'eries'] +['w', 'm'] +['Ġhit', 'ting'] +['in', 'ux'] +['M', 'ich'] +['ud', 'ge'] +['AT', 'AB'] +['Ġvulner', 'able'] +['ä', '¾'] +['Ġport', 'folio'] +[':', 'YES'] +['ĉm', 'ap'] +['B', 'ound'] +['Ġiter', 'ation'] +['in', 'cess'] +['Ġact', 'ors'] +['ĠQ', 'ual'] +['_c', 'lean'] +['ãĢij', 'ãĢIJ'] +['MS', 'G'] +['G', 'reen'] +['ĠOff', 'icer'] +['Ġsm', 'oking'] +['>', "',"] +['ĠF', 'lo'] +['++', ';'] +['oly', 'gon'] +['Ġbul', 'k'] +['Ġdr', 'ama'] +['Ġexception', 's'] +['os', 'ed'] +['Ġ+', 'čĊ'] +['Ġleg', 'acy'] +['C', 'V'] +['Ġcontrib', 'uted'] +['ĠTer', 'ms'] +['Ġb', 't'] +['Ġunt', 'uk'] +['Ġal', 'ien'] +['===', 'Ċ'] +['ĉ', 'Vector'] +['Ġl', 's'] +['On', 'line'] +['.f', 'acebook'] +['num', 'eric'] +['ock', 'ets'] +['A', 'ut'] +['b', 'ury'] +['-re', 'dux'] +['ĠRed', 'istributions'] +['GLOBAL', 'S'] +['urrenc', 'ies'] +['Ġt', 'ons'] +['âĢĻ', ','] +['ĠÃ', 'ª'] +['(c', 'ol'] +['ĠS', 'ymbol'] +['Ġstay', 'ed'] +['ĠM', 'L'] +['Ġm', 'unicip'] +['Ġsex', 'o'] +['S', 'en'] +['n', 'r'] +['Ġg', 'ains'] +['Ġshort', 'ly'] +['.M', 'enu'] +['Ã', '½'] +['KN', 'OWN'] +['Ġoper', 'ators'] +['-', 'V'] +['ĠPat', 'rick'] +['/', 'add'] +['_C', 'O'] +['ir', 'ation'] +['(p', 'ost'] +['Post', 's'] +['/', '_'] +['Ġpl', 'ug'] +['Ġintellect', 'ual'] +['Ġmet', 'ab'] +['Ġpregn', 'ancy'] +['ĠPrem', 'ier'] +['n', 'm'] +['Ġpred', 'iction'] +['ĠMin', 'istry'] +['Th', 'ree'] +['val', 'uate'] +['ĠMin', 'i'] +['b', 'u'] +['оÐ', '·'] +['<', 'ul'] +['Ġd', 'd'] +['ol', 'ving'] +['ĠC', 'ut'] +['Ġs', 'chem'] +['.tr', 'ain'] +['it', 'ate'] +['Ġr', 'ice'] +['Ġbird', 's'] +['ãģ', '«'] +['m', 'iddle'] +['struction', 's'] +['Ġn', 'erv'] +['a', 'que'] +['Ġfl', 'u'] +['Ġsurv', 'ival'] +['ĠGal', 'axy'] +['ĠF', 'ant'] +['.', 'Order'] +['At', 'trib'] +['irt', 's'] +['é', 'c'] +['M', 'ovie'] +['Ġcon', 'ce'] +['qu', 'arters'] +['Ġm', 'ood'] +['.Add', 'Range'] +['Ġres', 'olved'] +['ãĥ', 'Ī'] +['Ġburn', 'ing'] +['ĉĉĉĉ', 'čĊ'] +['ĠW', 'E'] +['Ġhost', 'ing'] +['L', 'AB'] +['Ġman', 'agers'] +['Ġstre', 'ngthen'] +['<', 'const'] +['ĠFire', 'base'] +['on', 'ed'] +['ĠJ', 'ean'] +["'", '', '";čĊ'] +['ĠS', 'av'] +['.B', 'old'] +['Ġen', 'ables'] +['ĉt', 'mp'] +['Ġman', 'ually'] +['ĠS', 'qu'] +['user', 'id'] +['.f', 'unction'] +['.c', 'ache'] +['LO', 'PT'] +['.S', 'ervices'] +['dd', 'it'] +['t', 'im'] +['<', 'img'] +['ĠTh', 'ings'] +['ĠEvery', 'thing'] +['Ġa', 'pt'] +['em', 'and'] +['Ġroll', 'ing'] +['ë', '¦'] +['.', 'level'] +['Ġst', 'om'] +['ĠW', 'inter'] +['Ġview', 'ing'] +['(', 'values'] +['ocom', 'plete'] +['v', 'ia'] +['up', 'o'] +['Ġabort', 'ion'] +['i', 'ère'] +['ï¼', 'ij'] +['_B', 'UTTON'] +['_d', 'omain'] +['Ġb', 'ra'] +['ĠA', 'st'] +['in', 'as'] +['Ġstat', 'ist'] +['c', 'od'] +['L', 'R'] +['Ġdr', 'ives'] +['Ġfollow', 'ers'] +['Ġall', 'ies'] +['ĉc', 'urrent'] +['ecess', 'ary'] +['Ġdam', 'aged'] +['_', 'pt'] +['and', 'les'] +['oun', 'tries'] +['Ġsim', 'ult'] +['e', 'u'] +['Ġcontrovers', 'ial'] +['_G', 'ROUP'] +['Ġr', 'ib'] +['.', 'Info'] +[':', 'mm'] +['.n', 'ormal'] +['_ADD', 'RESS'] +['Ġ', 'íķ'] +['add', 'le'] +['ĠD', 'ur'] +['.', 'Element'] +['W', 'arnings'] +['Ġcred', 'its'] +['Ġin', 'hib'] +['Ġem', 'issions'] +['Ġh', 'az'] +['.y', 'outube'] +['ugg', 'ed'] +['Ġbo', 'ther'] +['ĠK', 'ansas'] +['ĠF', 'ixed'] +['ĠTest', 's'] +['ĠF', 'IX'] +['Un', 'iform'] +['Ġk', 'ont'] +['>>', '>'] +['st', 'ation'] +['lo', 're'] +['at', 'ype'] +['ish', 'op'] +['/', '****************************************************************'] +['Com', 'boBox'] +['Ġvac', 'ation'] +['Ġiniti', 'ative'] +['Ġdefault', 'Value'] +['con', 'cat'] +['ĠK', 'h'] +['ĠW', 'elcome'] +['ized', 'Name'] +['M', 'igration'] +['Ġgrad', 'ient'] +['H', 'ot'] +['Ġhard', 'ly'] +['el', 'o'] +['ĠStud', 'ents'] +['Ġlo', 'ose'] +['at', 'z'] +['.S', 'end'] +["'", '/'] +['Ġunivers', 'al'] +['Ġenter', 'prise'] +['Ġreg', 'ex'] +['Ġvis', 'itor'] +['ĠF', 'ly'] +['Se', 'q'] +['à¸', 'Ļ'] +['ĠVis', 'ual'] +['Ġlib', 'raries'] +['ato', 'es'] +['P', 'ayment'] +['Ġp', 'ent'] +['Ġgather', 'ed'] +['VRT', 'X'] +['ĠD', 'M'] +['S', 'plit'] +['Ġlet', 'ting'] +['Ð', 'Ŀ'] +['_error', 's'] +['ep', 'och'] +['P', 'ARAM'] +['c', 'u'] +['ÑģÑĤ', 'в'] +['ol', 'utions'] +['Edit', 'ing'] +['font', 's'] +['Ġalloc', 'ated'] +['ĠB', 'ased'] +['(', 'Y'] +['ĠJud', 'ge'] +['Ġbro', 'thers'] +['FILE', 'S'] +['ç', 'o'] +['w', 'b'] +['_P', 'I'] +["'", '^'] +['Ġs', 'word'] +['.s', 'ervices'] +['Ġn', 'l'] +['T', 'im'] +['ig', 'g'] +['ĠMo', 'ore'] +['Ġcrypt', 'oc'] +['åĩ', 'º'] +['_post', 's'] +['ot', 'ate'] +['?', "'"] +['...', '.ĊĊ'] +['Ġk', 'l'] +['="', '$'] +['Ġdec', 'oration'] +['áº', '¡'] +['ĠD', 'IRECT'] +['G', 'UI'] +[')', '=>{Ċ'] +['Ġnews', 'letter'] +['Ġprec', 'is'] +['(p', 'oint'] +['ĠEqu', 'ipment'] +['ut', 'y'] +['ĠD', 'ave'] +['Ġparticip', 'ation'] +['u', 'arios'] +['x', 'it'] +['.A', 's'] +['ET', 'ER'] +['or', 'ous'] +['Ġsh', 'ield'] +['[]', '>'] +['ilit', 'ary'] +['.', 'origin'] +['Ġprom', 'otion'] +['U', 'nt'] +['Ġc', 't'] +['TR', 'A'] +['View', 'Holder'] +['Ġsig', 'ma'] +['d', 'elta'] +['are', 'house'] +['con', 'tract'] +['(', 'Vector'] +['Ġcompet', 'e'] +['/', 'form'] +['/', 'components'] +['Ġn', 'r'] +['ĠInd', 'ones'] +['Ġо', 'ÑĤ'] +['ĠV', 'olume'] +['.f', 'iles'] +['(res', 'p'] +['/', 'models'] +['Ġsur', 'f'] +['stand', 'ard'] +['/', 'o'] +['ĠXCT', 'Assert'] +['V', 'ICES'] +['.C', 'ode'] +['SE', 'D'] +['Ġact', 'ivate'] +['D', 'elta'] +['Ġlimit', 'ation'] +['ri', 'j'] +['Ġpregn', 'ant'] +[':', '^('] +['Ġs', 'our'] +['p', 'ie'] +['Ġexp', 'ense'] +['ic', 'ation'] +['ĠL', 'arge'] +['ĠÂ', '±'] +['ĠB', 'owl'] +['(model', 's'] +['/', 'N'] +['P', 'a'] +['.re', 'load'] +['Ġwonder', 'ing'] +['Exec', 'ution'] +['ĉ', 'ĠĠĠĠĠĠ'] +['ĠG', 'raphics'] +['ĠCont', 'in'] +['_j', 'ob'] +['Ġget', 'Name'] +['ĠM', 'agn'] +['ĠD', 'WORD'] +['m', 'ad'] +['Ġn', 'h'] +['fe', 'atures'] +['}', '");Ċ'] +['he', 'ets'] +['(tr', 'ain'] +['z', 'n'] +['Ġrecru', 'it'] +['.con', 'nection'] +['Ġbar', 'rel'] +['Ġste', 'am'] +['_set', 'ting'] +['Ġang', 'ular'] +['ane', 'ously'] +['Ġb', 'il'] +['ĠN', 'orm'] +['(!', '$'] +['ib', 't'] +['%', '('] +['Ġpos', 'it'] +['ĠF', 'ather'] +['int', 'endo'] +['L', 'ive'] +['Ġport', 's'] +['Ġme', 'j'] +['Ġland', 'ing'] +['pon', 'der'] +['Ġc', 'od'] +['_HE', 'ADER'] +['.M', 'argin'] +['Ġball', 's'] +['Ġdiscuss', 'ions'] +['Ġbl', 'end'] +['H', 'ex'] +['Ġfarm', 'ers'] +['Ġmaint', 'aining'] +['ĠĠĠ', 'čĊ'] +['s', 'yn'] +['[', 'T'] +['r', 'us'] +['uff', 'ers'] +['Ġcontrib', 'utors'] +['_s', 'ys'] +['.De', 'bug'] +['Ġconstruct', 'ed'] +['om', 'es'] +['?', 'id'] +['sl', 'ider'] +['Ġsup', 'pliers'] +['scri', 'ber'] +['p', 'es'] +['Ð', 'ŀ'] +['":', 'čĊ'] +['\\', 'Controller'] +['))', 'ĊĊĊ'] +['Ġl', 'ua'] +['M', 'ulti'] +['EN', 'S'] +['S', 'rc'] +['Ġpet', 'ition'] +['Ġsl', 'ave'] +['look', 'ing'] +['V', 'ERT'] +['ĉ', 'vector'] +['S', 'pecial'] +['h', 'h'] +['an', 'ne'] +['ĠN', 'iger'] +['/', 'views'] +['z', 'ing'] +['end', 'ant'] +['<', 'C'] +['s', 'peed'] +['Ġ{', '};ĊĊ'] +['Begin', 'Init'] +['Ġf', 'open'] +['@', 'RequestMapping'] +['End', 'Init'] +['Ġp', 'unch'] +['S', 'ender'] +['é', 'Ķ'] +['get', 'Message'] +['/t', 'ypes'] +['.P', 'I'] +["('", "');Ċ"] +['oc', 'used'] +['(', 'all'] +['Ġdrop', 'down'] +[').', '__'] +['ĠV', 'in'] +['.Fore', 'ignKey'] +['can', 'f'] +['ou', 'red'] +['ĠOrgan', 'ization'] +['ĠÐ', '°'] +['ĠC', 'ulture'] +['(cl', 's'] +[',', '_'] +['rg', 'ba'] +['ìĿ', 'ĺ'] +['.data', 'GridView'] +['Ġdo', 'zen'] +['ĠG', 'es'] +['_sh', 'ared'] +['n', 'ick'] +['Ġh', 'osp'] +['om', 'eter'] +['Ġclaim', 'ing'] +['ib', 'les'] +['ri', 'k'] +['æĺ', '¯'] +['en', 'ario'] +['Ġd', 'engan'] +['ob', 'b'] +['m', 'ont'] +['_r', 'ank'] +["('/", "',"] +['Ġap', 'olog'] +['P', 's'] +['_p', 'ower'] +['ĠG', 'ree'] +['Ġful', 'fill'] +['Ġfire', 'base'] +['Ġf', 'are'] +['ĠH', 'im'] +['Ġbe', 'an'] +['â̦', '.'] +['ĠS', 'PI'] +['_R', 'X'] +['Ġper', 'ception'] +['rel', 'ative'] +['comp', 'ile'] +['u', 'um'] +['ut', 'os'] +['a', 'uc'] +['ĠAs', 'k'] +['Ġindic', 'ator'] +['/', 'th'] +['.set', 'String'] +['ĠWis', 'consin'] +['.D', 'omain'] +['Ġart', 'ificial'] +['De', 'velop'] +['ĠSar', 'ah'] +['Ġl', 'ying'] +['(', 'search'] +['ĠEmp', 'ire'] +['urr', 'ing'] +['æĹ¶', 'éĹ´'] +['="', '${'] +['Ġget', 'Id'] +['ĠP', 'ayment'] +['trans', 'ition'] +['Ġ', '].'] +['ix', 'in'] +['V', 'T'] +['-', 'select'] +['Ġdemonstr', 'ated'] +['Ġlast', 'Name'] +['employ', 'ment'] +['.get', 'Property'] +['Ġf', 'ought'] +['file', 'Name'] +['ĠP', 'ers'] +['-c', 'ard'] +['a', 'str'] +['attr', 's'] +['Ġprom', 'inent'] +['Des', 'ign'] +['anc', 'ouver'] +['ãģĹ', 'ãģ'] +['ard', 'o'] +['se', 'cret'] +['Ġr', 'ag'] +['Ġpo', 'ison'] +['-m', 'an'] +[',', 'omitempty'] +['ĉ', 'un'] +['it', 'zer'] +['ĠCas', 'ino'] +['ĠR', 'oss'] +['-', 'foot'] +['(result', 's'] +['Pl', 'an'] +['Ġlas', 'er'] +['ê¸', '°'] +['_D', 'R'] +['F', 'acebook'] +['Ġbo', 'ards'] +['st', 'a'] +[']', '],'] +['Ġt', 'iles'] +['S', 'IZE'] +['Ġ=', '~'] +['Ġprem', 'ier'] +['oc', 'ab'] +['Ġenc', 'oded'] +['Ġres', 'erve'] +['ĠAfghan', 'istan'] +['ĠList', 'Node'] +['url', 's'] +['Ġsub', 'mission'] +['Ġne', 'u'] +['Ġ#', '+#'] +['_P', 'OST'] +['Ġmo', 'ist'] +['ell', 'i'] +['ellig', 'ent'] +['.', 'alert'] +['ó', 'd'] +['b', 're'] +['ĠCol', 'lect'] +['Ġgraph', 'ic'] +['Ġlong', 'itude'] +['ĠPro', 'vid'] +['ĠCal', 'culate'] +['x', 'ffff'] +['c', 'riteria'] +['Ġw', 'aters'] +['ro', 'ck'] +['lo', 'quent'] +['ĠT', 'rib'] +['Ġbur', 'st'] +['Ġsuff', 'ix'] +['.Ext', 'ensions'] +['ish', 'es'] +['iv', 'el'] +['ĠLI', 'KE'] +['ĠGet', 'ty'] +['.Action', 'Event'] +['.s', 'lf'] +['ĠH', 'AL'] +['up', 'al'] +['E', 'AR'] +['ud', 'i'] +['_time', 'out'] +['U', 'F'] +['ĠSing', 'apore'] +['ĠAd', 'vent'] +['_int', 'erval'] +['cha', 'ft'] +['ĠE', 'mer'] +['Ġtele', 'phone'] +['ĠTur', 'k'] +['_', 'interface'] +['ĠO', 'wn'] +['Ġencour', 'aged'] +['<', 'Object'] +['_T', 'ext'] +['ĠOnt', 'ario'] +['ĠApp', 'ly'] +['.f', 'irebase'] +['Ġant', 'ib'] +['P', 'riority'] +['ene', 'z'] +['D', 'ays'] +['c', 'id'] +['urre', 'nce'] +[';', '/'] +['inn', 'ed'] +['Ñģ', 'Ñı'] +['Ġve', 'z'] +['f', 'w'] +['//', '$'] +['att', 'ack'] +['Ġstart', 'up'] +['ain', 'ers'] +['.f', 'ragment'] +['op', 'acity'] +['(', 'conn'] +['he', 'im'] +['.n', 'etwork'] +['(', 'stream'] +['ĠN', 'ON'] +['t', 'ol'] +['ĠX', 'box'] +['ĠD', 'S'] +['Ġc', 'ached'] +['Ġprostit', 'utas'] +['ĠB', 'alt'] +["('", '['] +['Ġno', 'except'] +['"', "'"] +['Ġs', 'd'] +['.', 'valid'] +['_', 'ag'] +['Ġr', 'aces'] +['Ġro', 'd'] +['itud', 'es'] +['<', '>('] +['.Pro', 'duct'] +['Form', 's'] +['NE', 'W'] +['P', 'ay'] +['ĉ', 'boolean'] +['_', 'contact'] +['ĠElect', 'ric'] +['sk', 'ip'] +['Ġw', 'ur'] +['Ġch', 'ronic'] +['_d', 'river'] +['ĠS', 'ab'] +['ĠU', 'lt'] +['ĠR', 'ad'] +['ST', 'ATUS'] +['ĠLew', 'is'] +['O', 'B'] +['Ġgift', 's'] +['.Re', 'c'] +['TR', 'UE'] +['Ġint', 'ensity'] +['Mark', 'er'] +['.com', 'pare'] +['ff', 'ic'] +['C', 'ookie'] +['ĠB', 'aby'] +['ĠBig', 'Decimal'] +['ile', 't'] +['ĠHOLD', 'ERS'] +['ĠL', 'ady'] +['Ġl', 'ung'] +['ĠAl', 'abama'] +['Ġd', 'ess'] +['`', ');Ċ'] +['ĠB', 'uilder'] +['_reg', 'ion'] +['Ġne', 'utral'] +['Bo', 'th'] +['Ġh', 'p'] +['Ġh', 'orn'] +['Ġseg', 'ments'] +['ĠE', 'C'] +['"=>', '"'] +['(', 'rec'] +['ĠP', 'i'] +['G', 'M'] +['Ġl', 'aptop'] +['Sc', 'alar'] +['is', 'd'] +['-d', 'ialog'] +['ĠAnd', 'erson'] +['Ġmist', 'akes'] +['ĠH', 'an'] +['j', 'es'] +['est', 'ination'] +['Ġprom', 'ises'] +['b', 'id'] +['ĠSc', 'ient'] +['G', 'IN'] +['ĠPer', 'formance'] +['b', 'age'] +['.', 'users'] +['le', 'ading'] +['Ġor', 'al'] +['G', 'raphics'] +['_P', 'TR'] +['h', 'ang'] +['Ġin', 'ev'] +['process', 'ing'] +['F', 'actor'] +['ĠN', 'A'] +['$', 'string'] +['Ġground', 's'] +['.Save', 'Changes'] +['c', 'lock'] +['cri', 'pcion'] +['ĠNew', 'ton'] +['g', 'c'] +['.in', 'cludes'] +['Ġbl', 'ast'] +["Ġ'-", "'"] +['Ġpued', 'e'] +['.S', 'ession'] +['Ġgre', 'p'] +['_f', 'inal'] +['ĠG', 'ay'] +['ĠG', 'ive'] +['ir', 'i'] +['-st', 'ar'] +['ĠUI', 'Image'] +['_ep', 'och'] +['ub', 'b'] +['ent', 'h'] +['Ġel', 'ite'] +['Ġcampaign', 's'] +['ĠP', 'orno'] +['_', 'assign'] +['Prot', 'ocol'] +['ĠBe', 'ing'] +['ĠAir', 'port'] +['Ġconvent', 'ional'] +['ĠW', 'at'] +['ĠC', 'I'] +['ET', 'A'] +['ĠAnth', 'ony'] +['Ġtable', 't'] +['(', 'format'] +['Ġconsist', 'ently'] +['ĠI', 'owa'] +['Ġav', 'atar'] +['.c', 'ursor'] +['!', '['] +['Ġh', 'anging'] +['H', 'er'] +['S', 'uch'] +["';ĊĊ", 'Ċ'] +['orge', 'ous'] +['()', '=='] +['Ġview', 'Model'] +['Ġ', 'ãĥ'] +['Ġel', 's'] +['ĠAg', 'ent'] +['F', 'etch'] +['ap', 'or'] +['Ġc', 'x'] +['p', 'read'] +['ĠP', 'ier'] +['oe', 'ff'] +['S', 'n'] +['ĠV', 'irtual'] +['A', 'pr'] +['.Wh', 'ite'] +['_M', 'OD'] +['ĠPoint', 's'] +['å¤', '±'] +['Ġgen', 'es'] +['Ġv', 'endor'] +['Ġmain', 'stream'] +['<', 'src'] +['ĠEl', 'izabeth'] +['Dec', 'oder'] +['-', 'state'] +['ĠG', 'lass'] +['nc', 'y'] +['adi', 'ans'] +['_m', 'on'] +['ĠRem', 'ote'] +['Ġwire', 'less'] +['ĠM', 'i'] +['å', 'ī'] +['è¡', '¨'] +['st', 'age'] +['ĠT', 'ile'] +['ll', 'ib'] +['V', 'ariant'] +['==', 'Ċ'] +['Ġgold', 'en'] +['(Q', 'String'] +['.put', 'Extra'] +['ĠD', 'om'] +['ĠAn', 'imation'] +['Ġinter', 'active'] +['if', 'act'] +['éĻ', '¤'] +['LE', 'T'] +['Ġfrequ', 'ent'] +['Ġ<', '>Ċ'] +['F', 'ilename'] +['Ġs', 'ne'] +['ĠFoot', 'ball'] +['Ġr', 'ival'] +['Ġdis', 'aster'] +['ion', 'ic'] +['ĠD', 'amage'] +['.', 'Resource'] +['-', 'en'] +['ĠT', 'ypes'] +['get', 'String'] +['(', 'board'] +['Ġb', 'ol'] +['pl', 'ain'] +['z', 'ym'] +['à¸', '²'] +['Ġsc', 'anner'] +['ild', 'er'] +['_msg', 's'] +['æ', 'ı'] +['(int', 'ent'] +['Ġde', 'struct'] +['Ġb', 'ust'] +['ĠE', 'mploy'] +['on', 'i'] +['ĠUI', 'ViewController'] +['Ġodd', 's'] +['ear', 'er'] +['Ge', 'ometry'] +['Ġy', 'ii'] +['_EX', 'PORT'] +['ĠAtt', 'ack'] +['Ġn', 'iet'] +['Ġim', 'pression'] +['ĠG', 'il'] +['_pro', 'b'] +['ĠC', 'F'] +['ĠEx', 'perience'] +['/pl', 'ugins'] +['.M', 'ethod'] +['Ġbelie', 'fs'] +['N', 'ative'] +['_b', 'uild'] +['Ġv', 'ig'] +['Ġr', 'anks'] +['cover', 'ed'] +['s', 'uch'] +['G', 'uard'] +['.p', 'ack'] +['add', 'er'] +['iv', 'ia'] +['l', 'ng'] +['Ġв', 'Ñĭ'] +['T', 'imestamp'] +['_n', 'ow'] +['Ġp', 'oker'] +['Ġun', 'c'] +['Ġsh', 'apes'] +['-t', 'ypes'] +['_per', 'iod'] +['p', 'k'] +['Ġveter', 'an'] +['Ġson', 'o'] +['Ġappoint', 'ed'] +['over', 'flow'] +['.d', 'river'] +['_c', 'at'] +['ut', 't'] +['pl', 'ant'] +['im', 'b'] +['ĠAc', 'cept'] +['Ġconc', 'ert'] +['ĉ', 'node'] +['ĉ', 'z'] +['?', '>čĊ'] +['Ġb', 'anned'] +['ĉ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġto', 'xic'] +['Ġdisap', 'pe'] +['È', 'Ľ'] +['Ġgr', 'ace'] +['ate', 'ful'] +['Re', 'ply'] +['ĠCru', 'z'] +['Ġsc', 'rap'] +['Ġkey', 'words'] +['s', 'imp'] +['Ġmort', 'gage'] +['Ġcy', 'ber'] +['ĠEx', 'ecute'] +['Ġlat', 'itude'] +['if', 'u'] +['.C', 'OM'] +['d', 'bo'] +['Ġsort', 's'] +['ĠG', 'as'] +['om', 'ial'] +['.L', 'ocal'] +['Cell', 's'] +['.Re', 'place'] +['String', 's'] +['.f', 'it'] +['ĠTh', 'ird'] +['%', '",Ċ'] +['Ġ{}', '".'] +['ĠS', 'ony'] +['Ġ[', ':'] +['Ġfall', 'en'] +['.', "')Ċ"] +['in', 'h'] +['ĠM', 'C'] +['Ġred', 'is'] +['C', 'odes'] +['Ġprofile', 's'] +['h', 'ook'] +['Reduc', 'er'] +['_F', 'UNC'] +['Ġn', 'avigate'] +['str', 'len'] +['Ġh', 'orm'] +['á', 'ŀ'] +['ĠS', 'R'] +['.', 'boot'] +['Ġdig', 'est'] +['ĉ', 'header'] +['.find', 'One'] +['æ', 'ģ'] +['Db', 'Type'] +['n', 'ia'] +['_m', 'erge'] +['Ġdon', 'ne'] +['/', 'Getty'] +['_CH', 'AR'] +['Ġb', 'ands'] +['.', 'URL'] +['art', 'ial'] +['Ġf', 'req'] +['Ġs', 'ist'] +['N', 'g'] +['Ġrender', 'ing'] +['\\', 'Core'] +['Widget', 's'] +['ĠV', 'A'] +['Ġactiv', 'ists'] +['St', 'e'] +['=', '_'] +['all', 'a'] +['St', 'amp'] +['Ġload', 's'] +['Ġx', 'x'] +['ĠL', 'earning'] +['.M', 'vc'] +['u', 'ir'] +['("', '$'] +['Ġconnect', 'ing'] +['Read', 'Only'] +['ur', 'u'] +['ĠE', 'ag'] +['B', 'IT'] +['_DE', 'L'] +['å', '§'] +['arr', 'ass'] +['ext', 'ernal'] +['ĠY', 'OUR'] +['ĠB', 'rew'] +['ĠF', 'ive'] +['Ġres', 'ize'] +['ig', 'id'] +['er', 'ation'] +['ĠÑ', 'į'] +['åĬ', 'ł'] +['ĠC', 'atch'] +['Ù', 'ģ'] +['ĠLe', 'on'] +['am', 'il'] +['.B', 'ody'] +['Cl', 'ip'] +['/', 'list'] +['.b', 'r'] +['Edit', 'Text'] +['ĉ', 'db'] +['.G', 'ame'] +['(Build', 'Context'] +['back', 'end'] +['.R', 'ed'] +['face', 'book'] +['.url', 's'] +['m', 'r'] +['rol', 'led'] +['----', '---'] +['Ġinter', 'vention'] +['Ġretire', 'ment'] +['ĠK', 'it'] +['ĠP', 'RE'] +['Upper', 'Case'] +['ĠS', 'ocket'] +['Ġ:', '-'] +['Ġstudy', 'ing'] +['ĠMet', 'ro'] +['ard', 'ed'] +['Ġconvers', 'ations'] +['C', 'alled'] +['Ġexam', 'ine'] +['ert', 'ificate'] +['.g', 'z'] +['-res', 'ponsive'] +['Ġref', 'und'] +['_n', 'etwork'] +['allow', 'ed'] +['em', 'pt'] +['Ġme', 'als'] +['C', 'ategories'] +['Ġtravel', 'ing'] +['Ġk', 'g'] +['Ġsh', 'ame'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġexplicit', 'ly'] +['Ġmath', 'ematic'] +['ĠS', 'uite'] +['ĠR', 'GB'] +['******', '/'] +['Ġmix', 'ture'] +['lear', 'ning'] +['.t', 'emplate'] +['att', 's'] +['w', 'x'] +['ĉ', 'ctx'] +['.p', 'roperties'] +['Ġdrink', 's'] +['ĠE', 'ither'] +['set', 'Text'] +['.get', 'Data'] +['.z', 'ip'] +['Ġreve', 'als'] +['<', 'table'] +['.Hash', 'Map'] +['ĠH', 'ur'] +[')', '");Ċ'] +['.f', 'ramework'] +['ĠST', 'ART'] +['feed', 'back'] +['Ġsaf', 'ely'] +['.', 'icon'] +['config', 'ure'] +['.', 'lock'] +['.l', 'ayers'] +['/>', '.Ċ'] +['Ġrank', 'ed'] +['_', 'impl'] +['ĠHand', 'les'] +['Ġhost', 'ed'] +['Ġup', 'dating'] +['al', 'bum'] +['é', 'Ŀ'] +['Ġsh', 'ader'] +['Edit', 'ors'] +['-', 'round'] +['[]', '{'] +['Ġse', 'p'] +['ĠH', 'i'] +['TE', 'M'] +['look', 'up'] +['.m', 'an'] +['_IN', 'PUT'] +['Ġthreat', 'ened'] +['_IM', 'PORT'] +['Ġd', 'rops'] +['ru', 'it'] +['s', 'id'] +['bo', 'th'] +['ĠEx', 'cel'] +['Ġj', 'er'] +['ord', 'inary'] +['еÐ', '¹'] +['V', 'IEW'] +['re', 'ply'] +['Ġ)', ':Ċ'] +['color', 's'] +['ver', 'ified'] +['_T', 'r'] +['_p', 'arse'] +['Ġcon', 'gress'] +['P', 'romise'] +['int', 's'] +['ĠM', 'other'] +['.A', 'pi'] +['ĠD', 'uration'] +['Ġfirst', 'Name'] +['inherit', 'doc'] +['ĠM', 'ars'] +['Ġa', 'pr'] +['OD', 'Y'] +['Ġvis', 'its'] +['Ġhe', 'aling'] +['let', 'ters'] +['))', ');čĊ'] +['f', 'uture'] +['.F', 'ramework'] +['Ġk', 'iss'] +['Ġinv', 'olve'] +['Ġsil', 'ent'] +['ad', 'ows'] +['Ġany', 'body'] +['s', 'ch'] +['Ġsole', 'ly'] +['-', 'img'] +['Ġprop', 'ri'] +['Ġin', 'struct'] +['Ġlic', 'enses'] +['Ġm', 'eth'] +['Ġcond', 'em'] +['ĠD', 'omain'] +['ĠHarr', 'is'] +['Ġs', 'Ã¥'] +['CE', 'PT'] +['B', 'atch'] +['@', 'extends'] +['ĠCONTR', 'IBUT'] +['.Data', 'Frame'] +['_p', 'acket'] +['rec', 'ision'] +['Ġfoc', 'using'] +['.', 'ht'] +['__', '":Ċ'] +[':', 'Get'] +['ĠK', 'C'] +['Ġpass', 'age'] +['Seg', 'ment'] +['_c', 'enter'] +['-z', 'A'] +['_B', 'L'] +['Ġconv', 'in'] +['Ġclass', 'ified'] +['ĠNS', 'Mutable'] +['_', 'ap'] +['t', 'ile'] +['Rect', 'angle'] +['(n', 'ums'] +['v', 'ens'] +['ĠUI', 'Button'] +['ĠF', 'eder'] +['am', 'o'] +['Ġout', 'line'] +['ĠPar', 'ser'] +['Ġâ', 'ī'] +['ĠWork', 's'] +['.S', 'chema'] +['Ġeng', 'ines'] +['_com', 'mon'] +['_', 'old'] +['Ġset', 'ContentView'] +['Ġ///', '<'] +['ĠB', 'T'] +['f', 'm'] +['Ġd', 'ivers'] +['_', 'weights'] +['em', 'ark'] +['ĠA', 'CT'] +['Ġpro', 'portion'] +['over', 'lay'] +['.dir', 'name'] +['ĠG', 'it'] +['_REF', 'ERENCE'] +['<', '>'] +['l', 'b'] +['_r', 'ule'] +['è´', '¥'] +['ĠPut', 'in'] +['Ġsleep', 'ing'] +['()', ':čĊ'] +['Ġpres', 'erve'] +['Ġpar', 'liament'] +['ĠLook', 'ing'] +['Ġpick', 'ing'] +['ĠDis', 'patch'] +['Ġsl', 'ip'] +['ë', 'ĵ'] +['ĠL', 'yn'] +['_sign', 'al'] +['config', 'uration'] +['ĠP', 'itt'] +['ad', 'en'] +['pro', 'cedure'] +['Ġenthus', 'i'] +['f', 'ight'] +['ĠCons', 'ider'] +['Ġt', 'orn'] +['Conn', 'ected'] +['.c', 'os'] +['_group', 's'] +['ĠTh', 'ink'] +['Ġdel', 'iber'] +['Ġres', 'id'] +['work', 'ing'] +['.column', 's'] +['ĠCal', 'led'] +['Ġes', 'lint'] +['>', '",'] +['_D', 'OWN'] +['h', 'ist'] +['ĠAdv', 'anced'] +['Ġre', 'wards'] +['act', 'ors'] +['Ġsil', 'ence'] +['Ġmy', 'th'] +['Ġne', 'ur'] +['Ġa', 'uction'] +['.Get', 'String'] +['ek', 's'] +['(', 'project'] +['ĉ', 'msg'] +['ĉ', 'output'] +['Ġcomplaint', 's'] +[',', 'S'] +['Ġt', 'bl'] +['Ġ,', 'ĊĊ'] +['ri', 'ors'] +['ah', 'ren'] +['Ġlawy', 'ers'] +['re', 'dux'] +['_s', 'ymbol'] +['off', 'ee'] +['_RES', 'ULT'] +['(', 'Name'] +['UT', 'C'] +['.current', 'Time'] +['Ġorgan', 'is'] +['.', 'arg'] +['Ġmin', 'im'] +['w', 'ick'] +['Ġrece', 'ives'] +['B', 'alance'] +['Ġspeak', 's'] +['ĠD', 'ays'] +['ĠBel', 'ow'] +['t', 'ipo'] +['P', 'resent'] +['Ġres', 'erv'] +['h', 'p'] +['Ġr', 'it'] +['_R', 'IGHT'] +['--', ')'] +['Ġchair', 'man'] +['D', 'IS'] +['ĠBO', 'OST'] +['Ġexper', 'iments'] +['__', ');Ċ'] +['Ġst', 'amp'] +['Ġf', 'ert'] +['Ġf', 'ond'] +['T', 'er'] +['el', 've'] +['ure', 'n'] +['+', 'i'] +['end', 'ency'] +['Ġvirt', 'ually'] +['...', '"'] +['ï½', 'ŀ'] +['-', 'cent'] +['_un', 'ique'] +['Ġpr', 'icing'] +['m', 'ic'] +['RES', 'H'] +['Ġ::', ':'] +['Ġan', 'notation'] +['ĠC', 'ircle'] +['ong', 'odb'] +['it', 'as'] +['Ġ%', '('] +['(', 'component'] +['Ġо', 'б'] +['(', 'port'] +['-h', 'our'] +['.', 'obj'] +['L', 'BL'] +['Ġj', 'ury'] +['GB', 'T'] +['Ġsp', 'y'] +['ĠProf', 'essional'] +['Ġ""', ';ĊĊ'] +['Ġstri', 'king'] +['Ġdiscrim', 'ination'] +['Ġp', 'ays'] +['lic', 't'] +['ent', 'es'] +['Ġthrow', 'ing'] +['ĠPl', 'ugin'] +['(', 'def'] +['ĠRuntime', 'Exception'] +['ĠM', 'igration'] +['Ġd', 'ic'] +['b', 'ag'] +['on', 'ia'] +['Ġcor', 'ruption'] +['(', 'Map'] +['Ġpr', 'z'] +['.d', 'to'] +['Ġac', 'quire'] +['State', 'ToProps'] +['Ġlo', 'ving'] +['оÐ', '¶'] +['_p', 'attern'] +['Ġemot', 'ions'] +['Ġpublish', 'er'] +['_b', 'e'] +['Ġcoup', 'les'] +['o', 'j'] +['ĠCh', 'art'] +['Ġt', 'rop'] +['.t', 'ool'] +['Ġestablish', 'ment'] +['Ġd', 'ol'] +['Ġto', 'wer'] +['Ġl', 'ane'] +['ĠSy', 'dney'] +['Ġfill', 'ing'] +['claim', 'ed'] +['Ġdialog', 'ue'] +['Ġcon', 'vention'] +['book', 'ing'] +['pare', 'ncy'] +['æ', '±'] +['ĠGener', 'ic'] +['\\', 'Schema'] +['Ġr', 'anges'] +['/', 'ch'] +['Ġpan', 'els'] +['Ġr', 'uled'] +['çĶ', 'Ł'] +['.t', 's'] +['_s', 'ets'] +['Ġclean', 'up'] +['Pre', 'vious'] +['ĠAn', 'imal'] +['($', '('] +['ĠA', 've'] +['oll', 'ar'] +['_e', 'val'] +['ĉ', 'Name'] +['(t', 'ree'] +['Ġ"', ']'] +['Ġdut', 'ies'] +["='", '/'] +['Click', 'ed'] +['Ġdifferent', 'ly'] +['ĠCl', 'ark'] +['Ġd', 'it'] +['olog', 'ists'] +['Ġsy', 'nd'] +['Ġs', 'ends'] +['-', 'known'] +['k', 'b'] +['ĠMod', 'al'] +['it', 'ative'] +['Ġr', 'acing'] +['Ġhigh', 'lights'] +['ĠSim', 'on'] +['ĠCapt', 'ain'] +['ä¿', '¡'] +['ĠC', 'B'] +['cont', 'in'] +['ar', 'an'] +['Ġphys', 'ics'] +['ret', 'ty'] +['et', 'al'] +['.m', 'd'] +['ax', 'ios'] +['Ġspeak', 'ers'] +['Ġpre', 'p'] +['Ġaward', 'ed'] +['ì§', 'Ģ'] +['ĠC', 'orn'] +['ĠN', 'ature'] +['UD', 'IO'] +['Ġpro', 'j'] +['-', 'pre'] +['[', 'u'] +['Fe', 'atures'] +['Ġis', 'Equal'] +['B', 'inary'] +['s', 'ig'] +['Ġconf', 'usion'] +['ĠH', 'at'] +['Ġkt', 'ó'] +['.config', 'ure'] +['M', 'ON'] +['/', 'edit'] +['_A', 'dd'] +[',', 'true'] +['Ġc', 'li'] +['Error', 'Message'] +['-', 'loader'] +['Dim', 'ensions'] +['ultip', 'ly'] +['Ġ{', '!!'] +['ĠSql', 'Command'] +['Ġsp', 'oken'] +['Ġp', 'ics'] +['Ġto', 'y'] +['(', 'Key'] +['ĠLo', 'op'] +['Ø', '¨'] +['E', 'ATURE'] +['in', 'ction'] +['_set', 'up'] +['w', 'rapper'] +['Ġt', 'ong'] +['c', 'ular'] +['O', 'pt'] +['.P', 'l'] +['="', ','] +['(l', 'ength'] +['um', 'n'] +['Ġch', 'rom'] +['Ġse', 'vent'] +['ĠIllegal', 'ArgumentException'] +['ĉ', 'start'] +['Ġbeg', 'un'] +['CE', 'PTION'] +['dat', 'aset'] +['ĠF', 'ailed'] +['col', 's'] +['Ġkne', 'e'] +['im', 'ore'] +['.sp', 'lice'] +['sh', 'ell'] +['ig', 'gers'] +['Ġthem', 'es'] +['ĠD', 'J'] +['ĠAss', 'istant'] +['-', '$'] +['May', 'be'] +['Ġorder', 'ing'] +['ĠInt', 'elligence'] +['ĠMass', 'achusetts'] +['Ġfail', 'ing'] +['el', 'son'] +['G', 'reat'] +['=', 'i'] +['.re', 'st'] +['Ġinv', 'ite'] +['-dis', 'able'] +['.Group', 'Box'] +['âĢĻ', 'est'] +['Ġtack', 'le'] +['g', 'v'] +['et', 'ter'] +['Ġ),', 'čĊ'] +['_r', 'ules'] +['.w', 'arn'] +['function', 's'] +['ĠChrist', 'ians'] +['Ġback', 'ed'] +['Ġsl', 'ider'] +['Ġenjoy', 'ing'] +['n', 'est'] +['Ġh', 'ij'] +['_m', 's'] +['//', '*'] +['An', 'notations'] +['ĠVariable', 's'] +['<', 'V'] +['(', 'server'] +['ĠOr', 'acle'] +['element', 's'] +['Ġorgan', 'isation'] +['_point', 'er'] +['ĠHe', 'aders'] +['[', 'd'] +['Ġdead', 'line'] +['iss', 'a'] +['Ġkn', 'ife'] +['ĠNAS', 'A'] +['ĠHe', 'ight'] +['ĠAs', 'ync'] +['Ġven', 'ue'] +['.d', 'om'] +['bour', 'ne'] +['ĠHaw', 'ai'] +['Ġmem', 'o'] +['ict', 'ions'] +['Ġsurve', 'illance'] +['om', 'i'] +['/', 'assets'] +['Ġed', 'u'] +['Ä', 'Ľ'] +['Ġro', 'ster'] +['Ġh', 'ired'] +['ĠT', 'ok'] +['Ġpl', 'acement'] +['ur', 'ations'] +['Ġset', 'State'] +['ĠMag', 'azine'] +['Ġhor', 'ror'] +['T', 'ry'] +['Ġl', 'ag'] +['ĠEvery', 'one'] +['th', 'ur'] +['))', ';čĊčĊ'] +['.', 'return'] +['Ġsy', 'mp'] +['âĸĪ', 'âĸĪ'] +['Ġn', 'ights'] +['work', 'er'] +['Ġa', 'le'] +['ennes', 'see'] +['.st', 'ep'] +['Ġsynchron', 'ized'] +['our', 'i'] +['Do', 'es'] +['.', 'change'] +['f', 'on'] +['.set', 'Background'] +['irc', 'ular'] +['+', '-'] +['ĠC', 'IA'] +['ĠJ', 'ane'] +['ĠSim', 'ilar'] +['-', 'I'] +['level', 'and'] +['Ġpros', 'pect'] +['_f', 'ound'] +['ĉc', 'olor'] +['.D', 'iagnostics'] +['Ġann', 'ounce'] +['Ġassum', 'es'] +['/', 'tr'] +['Ġb', 'd'] +['ĠCar', 'bon'] +['Ġanal', 'ys'] +['.de', 'st'] +['n', 'ik'] +['ĠL', 'ie'] +['-', 'index'] +['Draw', 'able'] +['ĠT', 'AG'] +['Ġtri', 'angle'] +['_F', 'LOAT'] +['ĉĉ', 'ĠĠĠĠĠ'] +['.bl', 'ack'] +['v', 'ue'] +['cur', 'acy'] +['Ġaffect', 's'] +['Ġsure', 'ly'] +['Sl', 'ider'] +['uk', 'i'] +['c', 'ery'] +['Ġun', 'ter'] +['.pro', 'file'] +['ord', 'on'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['le', 'ave'] +['Ġsmart', 'phone'] +['g', 'ie'] +['Ġcons', 'pir'] +['Ġt', 'utorial'] +['ç±', '»'] +['Ġc', 'ab'] +['ĠSum', 'mary'] +['*', 'ĊĊ'] +['ä', 'h'] +['"', 'This'] +['Ġsl', 'ides'] +['"', ''] +['c', 'ycle'] +['ĠB', 'ull'] +['path', 's'] +['Ġun', 'p'] +['Ġview', 'DidLoad'] +['_M', 'odel'] +['Ġassert', 'True'] +['Ġr', 'ated'] +['De', 'cl'] +['vert', 'ed'] +['ĠD', 'at'] +['b', 'rew'] +['Ġpoint', 'ing'] +['M', 's'] +['ĠPoint', 'er'] +[')', "'"] +['_n', 'on'] +['ĠSE', 'C'] +['Ġy', 'eah'] +['g', 'ency'] +['initial', 'ize'] +['f', 'ly'] +['[', 'pos'] +[',', 'g'] +['Te', 'le'] +['Ġj', 'oke'] +['Ġcl', 'ause'] +['.find', 'ById'] +['en', 'es'] +['(', 'instance'] +['Â', '£'] +['Ġs', 'lic'] +['_h', 'ome'] +['Ġ*/', '}Ċ'] +['_p', 'ages'] +['(s', 'ervice'] +['R', 'P'] +['ĠAm', 'ong'] +['.get', 'Current'] +['ãĤ', '¹'] +['Ġs', 'lee'] +['=', '', '[Ċ'] +['ol', 'er'] +['Ġlib', 'ert'] +['Ġ`', 'Ċ'] +['Ġw', 'enn'] +['l', 'ated'] +['Ġimm', 'une'] +['(', 'Node'] +['ĠPro', 'blem'] +['ĠA', 'bs'] +['log', 's'] +['Ġ', '../'] +['ĠA', 'DC'] +['Ġ}}', '">Ċ'] +['>', "');Ċ"] +['=', 'b'] +['ĠW', 'ind'] +['lah', 'oma'] +['Ġalloc', 'ate'] +['or', 'ian'] +['Ġpres', 'cription'] +['-', 'quality'] +['ĠMay', 'or'] +['in', 'ely'] +['end', 'foreach'] +['ĠCom', 'plex'] +['k', 'om'] +['T', 'Y'] +[']', '].'] +['.', 'Style'] +['_m', 'any'] +["','", '$'] +['Ġbar', 'rier'] +['ĠF', 'etch'] +['ĠMar', 'vel'] +['Ġres', 'ist'] +['ог', 'о'] +['b', 'idden'] +['ĠRun', 'nable'] +[':', 'false'] +['Ġbuild', 's'] +['ĠSt', 'age'] +['Ġd', 'ub'] +['emp', 'o'] +['.s', 'ite'] +[';ĊĊ', 'ĊĊ'] +['ĠDen', 'ver'] +['Ġre', 'vel'] +['Ġtrigger', 'ed'] +['Ġd', 'ice'] +['_f', 'ail'] +['Ġg', 'c'] +['ĉ', 'X'] +['ĠTh', 'rowable'] +['.r', 'outer'] +['ĠRev', 'olution'] +['ÑĢ', 'а'] +['_N', 'ON'] +['Ł', '¥'] +['Ġel', 'der'] +['Ġab', 'road'] +['ĠÐ', 'µ'] +['ĠAd', 'ult'] +['bl', 'r'] +['g', 'lyphicon'] +['Ġprom', 'oting'] +['Ġ', 'iz'] +['ĠS', 'olid'] +['_lo', 'ader'] +['ear', 'ly'] +['.en', 'abled'] +['-', 'edit'] +['ĠU', 'L'] +['_', 'play'] +['ĠInt', 'errupt'] +['Ġadvant', 'ages'] +['uc', 'le'] +['Ġmechan', 'ical'] +['.table', 'LayoutPanel'] +['ĠWork', 'ing'] +['Ġan', 'onymous'] +['R', 'ating'] +['ig', 'ious'] +['_ph', 'one'] +['.addAction', 'Listener'] +['Ġfr', 'an'] +['und', 'en'] +['Ġ*)', '&'] +['_', 'bool'] +['ul', 'ative'] +['Ġcon', 'e'] +['ĠM', 'ult'] +['Ġm', 'ö'] +['ĠFor', 'ward'] +[']', '):Ċ'] +['Ġconvin', 'ced'] +['act', 'ed'] +['ãģ', 'ĵ'] +['ĠConfig', 'ure'] +['Ġce', 'iling'] +['D', 'er'] +['Ġpass', 'engers'] +['Group', 's'] +['Ġsoc', 'cer'] +['/', 'W'] +['avi', 'ors'] +['sw', 'ith'] +['ĠZ', 'one'] +['.', 'Options'] +['ĠM', 'om'] +['ied', 'er'] +['Array', 's'] +['Ġtreat', 'ments'] +['Ġprotect', 'ing'] +['f', 'ac'] +['Ġpick', 'le'] +['Button', 'Item'] +['Ġblock', 'ing'] +['str', 'ar'] +['Ã', '²'] +['ĠEx', 'port'] +['Ġth', 'rew'] +['ott', 'a'] +['ĠB', 'ASE'] +['.w', 's'] +['.LE', 'ADING'] +['order', 'By'] +['_d', 'elay'] +['ĠP', 'u'] +['.d', 'll'] +['ĠCh', 'oose'] +['Pol', 'ice'] +['ĠBE', 'GIN'] +['box', 'es'] +['Ġdiam', 'ond'] +[',', 'l'] +['Ġ', 'ĉĉĉ'] +['Ġcur', 'ious'] +['t', 'v'] +['Ġerot', 'ische'] +['ack', 'ages'] +['ĉ', 'Set'] +['T', 'ick'] +['.b', 'order'] +['static', 'method'] +['Ġch', 'er'] +['in', 'voice'] +['Ġcr', 'u'] +['Ġdef', 'ect'] +['_m', 'etadata'] +['re', 'lation'] +['ik', 'an'] +['[', 'N'] +['(Q', 't'] +['(', 'Base'] +['æģ', '¯'] +['be', 'at'] +['ĠEm', 'pty'] +['ĉ', 'o'] +['_sh', 'ift'] +['Ġreg', 'ret'] +['Th', 'ose'] +['C', 'ent'] +['ĠPort', 'ug'] +['ĠIs', 'lands'] +['ĠT', 'IME'] +['Man', 'agement'] +['-s', 'p'] +['ê', 'me'] +['Ġnot', 'ion'] +['un', 'ifu'] +['P', 'K'] +['è¡', 'Į'] +['ĠCUR', 'LOPT'] +['\\"', '\\'] +['U', 'V'] +['ç', 'º'] +['d', 'ra'] +['c', 'ou'] +['=', '`'] +['ĠD', 'estroy'] +['r', 'p'] +['.c', 'ancel'] +['G', 'G'] +['r', 'untime'] +['ĠV', 'ue'] +['Ġprogress', 'ive'] +['/s', 'ervices'] +['Ġrun', 'ner'] +['_FR', 'AME'] +['.ToolStrip', 'MenuItem'] +["Ġ'", ",'"] +['d', 'elay'] +['=', 'utf'] +['Ġscreen', 'ing'] +['Ġpull', 'ing'] +['om', 'as'] +['Ġan', 'th'] +['-', 'new'] +['/', 'local'] +['Ġi', 'Pad'] +['Ġt', 'witter'] +['Ġd', 'ying'] +['Ġhe', 'aven'] +['ĠU', 'Int'] +['ĠSen', 'ator'] +['Ġpres', 'um'] +['ĠWalk', 'er'] +['Ġover', 'come'] +['ete', 'ction'] +['Ġemb', 'arrass'] +['Ch', 'ina'] +['In', 'clude'] +['RO', 'LL'] +['Ġdata', 'Type'] +['D', 'avid'] +['à¸', '£'] +['lo', 'p'] +['-m', 'onth'] +['Ġsc', 'ar'] +['ĠS', 'afe'] +['Ġ', '****************************************************************'] +['Ġaccess', 'ories'] +['Ġr', 'amp'] +['_U', 'SE'] +['Ġcontr', 'ad'] +['))', ']Ċ'] +['Ġpre', 'st'] +['ĠH', 'R'] +['ĠR', 'ap'] +['Ġus', 'ize'] +['Ġcap', 'ability'] +['Ġc', 'ort'] +['-', 'next'] +['Ġbur', 'den'] +['_read', 'er'] +['Ġ@', '@'] +['reg', 'ular'] +['ĠK', 'a'] +['M', 'AN'] +['Ġa', 'str'] +["Ġ'", "')Ċ"] +['Ġf', 'ed'] +['Ġpars', 'ing'] +['ĠY', 'ears'] +['Ġbro', 'ker'] +['":', '{"'] +['Ġa', 'kt'] +['In', 'ventory'] +['abe', 'led'] +['Ġarg', 'parse'] +['******', '*Ċ'] +['vers', 'ation'] +['Ġc', 'ord'] +['ĠT', 'i'] +['Ġhope', 'fully'] +['Ġa', 'h'] +['ver', 'b'] +['Ġst', 'olen'] +['.', 'Entry'] +['Ġexpect', 'ing'] +['O', 'rientation'] +['Ġpower', 'ed'] +['Ġp', 'ersist'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +["']", ');'] +["'))", ',Ċ'] +['ĠC', 'ash'] +['ĉ', 'item'] +['gr', 'ades'] +['rop', 'ol'] +['b', 'asic'] +['Ġ"', ');čĊ'] +['Ġaw', 'ards'] +['(r', 'ange'] +['-', 'all'] +['ĠIB', 'Outlet'] +['ĠInd', 'eed'] +['----------------------------------------------------------------', '------------'] +['Ġstom', 'ach'] +['Ġfl', 'ower'] +['Ġs', 'ew'] +['_t', 'imes'] +['av', 'is'] +['Q', 'String'] +['ĠR', 'outes'] +['_pro', 't'] +['Ġcom', 'edy'] +['Ġlog', 'out'] +['Ġwood', 'en'] +['Ġpost', 'er'] +['p', 'iece'] +['.J', 'oin'] +['ĠP', 'ok'] +['cel', 'ona'] +['mut', 'ex'] +[';čĊ', 'čĊčĊ'] +['Ġstri', 'kes'] +['Load', 'ed'] +[')', 'arg'] +['es', 'a'] +['Un', 'ited'] +['E', 'p'] +['PE', 'LL'] +['ĠAtl', 'antic'] +['ul', 'let'] +['app', 'le'] +['Ġsett', 'led'] +['a', 'con'] +['Ġprint', 'er'] +['ĠG', 'C'] +['å®', 'ļ'] +['Ġrender', 'ed'] +[',', 'âĢĻ'] +['he', 'it'] +['s', 'ocial'] +['.', 'ge'] +['ĠR', 'ick'] +['ĠUt', 'ah'] +['g', 'ot'] +['on', 'ical'] +['ĠSc', 'roll'] +['ĠSc', 'iences'] +['Ġj', 'ug'] +['Ġam', 'pl'] +['ent', 'i'] +['LE', 'FT'] +['Ġt', 'abs'] +['Ġenorm', 'ous'] +['.get', 'Key'] +['loc', 'ate'] +['.', 'EX'] +['.st', 'orage'] +['.W', 'e'] +['Ġto', 'ast'] +['ĠAdd', 'itionally'] +['ĠN', 'OW'] +['_', 'UPDATE'] +['Ġtrans', 'ferred'] +['th', 'a'] +['.D', 'isplay'] +['_', 'ui'] +['ID', 'EO'] +['Ġmeaning', 'ful'] +['ĠMos', 'cow'] +[',', 'this'] +['ĠVict', 'oria'] +['æĶ', '¹'] +['ĠÐ', 'Ł'] +['.st', 'ack'] +['ĠB', 'arn'] +['pared', 'Statement'] +[':', 'string'] +['Ġb', 'ij'] +['ĠST', 'ATE'] +['Ġemploy', 'ers'] +['ĉ', 'input'] +['(', '|'] +['Ġle', 'x'] +['in', 'voke'] +['ĉ', 'num'] +['++', ','] +['at', 'ial'] +['ors', 'es'] +['Ġfor', 'k'] +['_t', 'xt'] +['ĠAnton', 'io'] +['Ġ(', '<'] +['aver', 'se'] +['Ġdev', 'ast'] +['ãĢ', 'Ģ'] +['.D', 'ec'] +['ĠG', 'ard'] +['/', 'ui'] +['.', '%'] +['tr', 'i'] +['Ġrol', 'led'] +['Value', 'Pair'] +['itt', 'en'] +['ĠTh', 'er'] +['Ġv', 'rou'] +['ĠFl', 'ow'] +['ĠFin', 'ance'] +['ĠCom', 'b'] +['H', 'C'] +['.set', 'Visible'] +['is', 'l'] +['Ġp', 'k'] +['Ġup', 'set'] +['(', 'raw'] +['ĠV', 'ice'] +['e', 'atures'] +['ĠL', 'ang'] +['Look', 'ing'] +['ĠA', 'ST'] +['Ġtri', 'ps'] +['ĠJust', 'in'] +['b', 'rowser'] +['="', "'.$"] +['.', 'vertices'] +['-', 'co'] +['}/', '{'] +['Ġ?', ','] +['ĠD', 'omin'] +['ĠBel', 'g'] +['"', '<'] +['Ġsup', 'pose'] +['add', 'y'] +['Ġwalk', 's'] +['ERR', 'U'] +['_f', 'ilters'] +['Pre', 'ferred'] +['sc', 'ene'] +['е', 'Ñģ'] +['ĠAff', 'airs'] +['Ġ"#', '{'] +['Ġon', 'Submit'] +['Ġstock', 's'] +['/', 'view'] +['g', 'ree'] +['-', 'get'] +['h', 'it'] +['J', 'o'] +['.get', 'C'] +['Initial', 'ized'] +['ÑĤ', 'и'] +['c', 'uts'] +['(', 'Type'] +['ĠAg', 'reement'] +['ĠViet', 'nam'] +['Ġ/*', '!'] +['Ġp', 'izza'] +['-', 'view'] +['_', 'em'] +['Ġl', 'hs'] +['Ġm', 'uy'] +['ĠId', 'ent'] +['ĠF', 'riends'] +['Ġab', 'und'] +['_A', 'D'] +['.t', 'imestamp'] +['-', "'"] +['Ġd', 'uplicate'] +['Ġhun', 'ting'] +['Ġregul', 'atory'] +['ia', 'o'] +['am', 'ous'] +['ĠEnt', 'ertainment'] +['[', 'A'] +['iat', 'ric'] +['_CL', 'IENT'] +['ĠK', 'ids'] +['/p', 'kg'] +['B', 'reak'] +['))', ');ĊĊ'] +['ĠSh', 'ape'] +['Ġrel', 'ating'] +['Int', 'errupt'] +['able', 'Opacity'] +['emb', 're'] +['Ġmyst', 'ery'] +['Ġjournal', 'ists'] +['rit', 'able'] +['.L', 'ink'] +['Ġstop', 'ping'] +['CRE', 'T'] +['.D', 'B'] +['Ġpopular', 'ity'] +['Ġg', 'ew'] +['Ġim', 'pr'] +['set', 'Value'] +['FL', 'AG'] +['ĉm', 'ax'] +['Ġb', 'ake'] +['w', 'y'] +['ĠEcon', 'omic'] +['Ġen', 'contr'] +['Ġf', 'name'] +['/', 'de'] +['R', 'ank'] +['Ġbug', 's'] +['.s', 'm'] +['Ġmed', 'ian'] +['D', 'OWN'] +['ĠS', 'ure'] +['At', 'Index'] +['ĠD', 'ick'] +['Ġ(', '__'] +['.d', 'elta'] +['F', 'r'] +['Ġsuggest', 'ing'] +['ĠRec', 'yclerView'] +[',', 'e'] +['ST', 'ART'] +['/************************************************************************', '****'] +['xf', 'ord'] +['Ġrece', 'ipt'] +['CL', 'AIM'] +['read', 'only'] +['Ġeng', 'aging'] +['C', 'a'] +['as', 'ma'] +['Ġens', 'uring'] +['Eng', 'lish'] +['ĠV', 'ancouver'] +['hy', 'th'] +['Ġpurch', 'asing'] +['ĠP', 'I'] +['.', 'word'] +['(s', 'p'] +['.h', 'ome'] +[':', 'def'] +['Ġg', 'ig'] +['ĠV', 'e'] +['for', 'um'] +['ĠM', 'itch'] +['B', 'ay'] +['_F', 'L'] +['Ġs', 'oll'] +['_column', 's'] +['Ġminor', 'ity'] +['b', 'ird'] +['Ġhand', 'ed'] +['SS', 'L'] +['ST', 'AT'] +['Ġnerv', 'ous'] +['ĥ', '½'] +['Ġfile', 'Path'] +['CRE', 'ATE'] +['A', 'w'] +['Ġp', 'ens'] +['se', 'ed'] +['ĠCom', 'pute'] +['ol', 'k'] +['ĠAs', 'set'] +['re', 'ach'] +["'),", 'čĊ'] +['n', 'avigation'] +['L', 'F'] +['/', 'util'] +['ĠP', 'ub'] +['Ġâ', 'Ķ'] +['c', 'ion'] +['##', 'Ċ'] +['II', 'I'] +['Tag', 'Name'] +['Ġam', 'id'] +['per', 'mission'] +['if', 'iable'] +['xFFFF', 'FFFF'] +['н', 'и'] +['.B', 'uffer'] +['_', 'irq'] +['d', 'ark'] +['Ġret', 'val'] +['.f', 'ire'] +['produ', 'ction'] +['.list', 'en'] +['ĠWe', 'ather'] +['Ġbuy', 'ers'] +['.', 'ne'] +['er', 'p'] +['ĠP', 'ent'] +['Ġw', 'elfare'] +['Ġpage', 'Size'] +['ĠSt', 'adium'] +['ert', 'a'] +['Ġle', 'v'] +['amp', 'a'] +['P', 'ager'] +['Ġcharg', 'ing'] +['ĠNet', 'flix'] +['|', 'null'] +['_r', 'andom'] +['.x', 'path'] +['Ġst', 'ere'] +['ĠIS', 'IS'] +['pons', 'es'] +['(', 'loc'] +['ey', 'ond'] +['ĠOff', 'icial'] +['ĠMary', 'land'] +['Data', 'Type'] +['_p', 'ar'] +['{', '},'] +['ĠEn', 'joy'] +['_SH', 'IFT'] +['ĠA', 'wards'] +['_ENT', 'RY'] +['Ġseem', 'ingly'] +['entic', 'ate'] +['Ġheart', 's'] +['_', ';ĊĊ'] +['ĠH', 'IV'] +['Ġindiv', 'id'] +['ĠFl', 'ag'] +['_', 'ctrl'] +['ĠC', 'allback'] +[',', 'z'] +['ĠG', 'PU'] +['ĉ', 'obj'] +['ĠPh', 'oenix'] +['ĠB', 'US'] +['Ġrub', 'ber'] +['_A', 'UTH'] +['ĠSol', 'utions'] +['(', 'location'] +['Variable', 's'] +['.set', 'Enabled'] +['_h', 'igh'] +['W', 'O'] +['G', 'esture'] +['Ġre', 'try'] +['Ġobject', 'ForKey'] +['allow', 'een'] +['Ġm', 'os'] +['ĠC', 'ele'] +['Ġik', 'ke'] +['(c', 'ell'] +['ĠM', 'ODE'] +['ren', 'a'] +['Ġdescri', 'bing'] +['Ġph', 'i'] +['Ġr', 'd'] +['Ġdes', 'erve'] +['Ġwhe', 'els'] +['å¸', 'Ĥ'] +['Ġcrit', 'ics'] +['N', 'amespace'] +['ĠF', 'ra'] +['Ġ', 'ĊĊĊĊ'] +['Ġall', 'a'] +['Ġrequ', 'iring'] +['æľ', 'Ł'] +['ut', 'ation'] +['Ġdelay', 'ed'] +['Ġadministr', 'ative'] +['Ġb', 'ay'] +['.h', 'idden'] +['T', 'ex'] +['Ġbound', 'aries'] +['Ġ]', ');ĊĊ'] +['ĠFollow', 'ing'] +['~', '/'] +['F', 'i'] +['_con', 'v'] +['_T', 'ITLE'] +['Ġdes', 'de'] +['ICollection', 'View'] +['Ali', 'as'] +['Ġb', 'ite'] +['pat', 'ient'] +['_COMM', 'AND'] +['Com', 'pleted'] +['ĉ', 'elif'] +['(', '<'] +['B', 'usiness'] +['ĠP', 'ool'] +['Ġpurs', 'ue'] +['ĠB', 'an'] +['_st', 'eps'] +['_DE', 'CL'] +['um', 'ble'] +['Ġcom', 'bo'] +['ĠL', 'ayer'] +['.x', 'r'] +['Ġd', 'up'] +['--------', '-'] +['Ġmod', 'ifier'] +['ro', 'b'] +['re', 'z'] +['Ġath', 'letes'] +['Us', 'ed'] +['w', 'ear'] +['Ġlegit', 'imate'] +['Ġ"', 'ĊĊ'] +['Ġh', 'v'] +['St', 'd'] +['ĠH', 'old'] +['Ġsurv', 'iv'] +['ĠAll', 'iance'] +['ĠEar', 'ly'] +['Beh', 'avior'] +['(f', 'ont'] +['/lib', 's'] +['Ġrect', 'angle'] +['Ġs', 'inger'] +['Ġam', 'p'] +['Equal', 'To'] +['Ġ"', '."'] +['Ġgirl', 'friend'] +['å', '±'] +['line', 'ar'] +['obs', 'erv'] +['Ġpi', 'ù'] +['Ġcomple', 'ment'] +['With', 'Value'] +['(p', 'assword'] +['t', 'ake'] +['Bl', 'ank'] +['ĠCom', 'par'] +["'", '",'] +['_p', 'olicy'] +['m', 'ongoose'] +['_FA', 'ILED'] +['.re', 'port'] +['R', 'atio'] +['.Perform', 'Layout'] +['us', 'able'] +['m', 'ers'] +['_re', 'nder'] +['PE', 'ED'] +['Ġles', 'b'] +['ĉ', 'E'] +['_t', 'ool'] +['Ġl', 'adies'] +['о', 'Ñģ'] +['))', '))Ċ'] +[';;', ';;'] +['.d', 'ot'] +['Ġn', 'est'] +['pe', 'ak'] +['uk', 'kit'] +['ec', 'a'] +['_S', 'W'] +['Ġ&', '('] +['ĠOk', 'lahoma'] +['Ġbank', 'ing'] +['ĠN', 'intendo'] +['Ġreprodu', 'ce'] +['_element', 's'] +['_m', 'ac'] +['pro', 'xy'] +['Ġremark', 'able'] +['}/', '${'] +['Ġout', 's'] +['.has', 'Next'] +['M', 'ODE'] +['Ġan', 'ime'] +['.con', 'n'] +['Un', 'ique'] +['D', 'om'] +['Ġimportant', 'ly'] +['itt', 'y'] +['Ġju', 'ice'] +['T', 'w'] +['ĠPart', 'ners'] +['Ġattack', 'ing'] +['Ġport', 'able'] +['am', 'iento'] +['.P', 'ictureBox'] +['.g', 'en'] +['Ġopt', 'imal'] +['Ġre', 'cre'] +['Ġjournal', 'ist'] +['ĠEx', 'tract'] +['ĠMore', 'over'] +['Ġmargin', 'Top'] +['.A', 'p'] +['Ġf', 'iring'] +['Na', 'N'] +['ĉ', 'template'] +['аÐ', '´'] +['.', 'En'] +['Ġdef', 'ence'] +['ĠT', 'el'] +['il', 'en'] +['j', 'an'] +['=', 'data'] +['ĠU', 'rl'] +['ĠRe', 'uters'] +['(t', 'otal'] +['ĠFif', 'th'] +['Ġess', 'ays'] +['Ġinterpret', 'ation'] +['Ġchar', 'ity'] +['ĠR', 'ules'] +['Ġsub', 'section'] +['st', 'yled'] +['az', 'er'] +['l', 'ags'] +['L', 'IST'] +['Ġupload', 'ed'] +['Ġtr', 'ash'] +['Ġreg', 'istr'] +['Ġsell', 'er'] +[">'", ';čĊ'] +['Ġstart', 'Time'] +['ç', 'Ļ'] +['s', 'y'] +['(Http', 'ServletRequest'] +['Ġtr', 'ap'] +['G', 'C'] +['Ġembed', 'ded'] +['Ġsurround', 'ed'] +['im', 'its'] +['T', 'X'] +['yl', 'inder'] +['ĠF', 'al'] +['Ġsent', 'ences'] +['ĠJ', 'a'] +['IF', 'ICATION'] +['we', 'apon'] +['ov', 'ation'] +['Ġco', 'at'] +['Ġinter', 'pol'] +['Ġl', 'ips'] +['ĠK', 'y'] +['Ġv', 'ectors'] +['_', 'am'] +['Ġint', 'ake'] +['.w', 'orld'] +['Ġin', 'box'] +['ĠM', 'AC'] +['_', 'ab'] +['(name', 'of'] +['Ġent', 'ert'] +['Ġgather', 'ing'] +['ĠS', 'IM'] +['++', '.'] +['ny', 'a'] +["'", '}}'] +['ĠUP', 'DATE'] +['Ġp', 'ac'] +['(', 'html'] +['ĠS', 'ant'] +['i', 'ating'] +['ĠIde', 'as'] +['Ġspr', 'ay'] +['ĠH', 'art'] +['Ġver', 'ification'] +['ades', 'h'] +['/', 'modules'] +['ĠM', 'ind'] +['ĠSized', 'Box'] +['Ġsh', 'elter'] +['Ġher', 'oes'] +['att', 'y'] +['Ġcert', 'ified'] +['s', 'j'] +['Ġê', 'tre'] +['ÅĤ', 'o'] +['Ġpublish', 'ing'] +['ĠMal', 'ays'] +['.get', 'User'] +['ĠPro', 'vider'] +['ĠLinked', 'List'] +['ĠB', 'or'] +['RO', 'UND'] +['d', 'id'] +['t', 'ain'] +['p', 'ire'] +['ĠJ', 'enn'] +['t', 'el'] +['and', 'e'] +['_f', 'ront'] +['ĠMc', 'G'] +['Test', 'Method'] +['à¸', 'Ń'] +['Ġoccasion', 'ally'] +['ĠW', 'ales'] +['Ġexerc', 'ises'] +['ĠÐ', 'Ĵ'] +['-', 'plus'] +['Ġvalid', 'ator'] +['Ġpr', 'ayer'] +['L', 'ATED'] +['_', 'author'] +['Ġlab', 'our'] +['++', 'Ċ'] +['-e', 'quiv'] +['ĠG', 'PL'] +['Ġface', 'book'] +['s', 'imple'] +['g', 'ly'] +['Process', 'or'] +['ip', 'y'] +['Ġ*', '>'] +['Ġcle', 'ared'] +['ĠP', 'ush'] +['Ġpen', 'is'] +['Struct', 'ure'] +['li', 'j'] +['ĠM', 'organ'] +['Ġhand', 'ful'] +['"', '.Ċ'] +['|', '\\'] +['Ġ', '********************************'] +['ĠA', 'qu'] +['_', 'IC'] +['.load', 's'] +['Ġm', 'eter'] +['ĠMar', 'ine'] +['::', '{'] +['ĠT', 'S'] +['ĠArray', 's'] +['.T', 'itle'] +['GR', 'AM'] +['ter', 'min'] +['Ġco', 'inc'] +['El', 'se'] +['_st', 'ates'] +['-r', 'un'] +['m', 'embers'] +['ast', 'ro'] +['Ġon', 'Press'] +['Ġbe', 'ings'] +['Ġabandon', 'ed'] +['Ġtax', 'p'] +['own', 'ers'] +['.m', 'ode'] +['Ġdiagn', 'osis'] +['Ġ_', 'Ċ'] +['ĠK', 'night'] +['ĉ', 'A'] +['Ġob', 'serve'] +['),', "'"] +['!', '")Ċ'] +['ĠPar', 'a'] +['Ġvari', 'ation'] +['(', 'False'] +['ĠAnt', 'i'] +['Ġg', 'ri'] +['Ġhome', 'less'] +['?', 'v'] +['Ġbe', 'z'] +['.S', 'erver'] +['re', 'lease'] +['ĠP', 'atri'] +['Ġchar', 's'] +['Ġrank', 'ing'] +['activ', 'ation'] +['Ġw', 'ides'] +['q', 'r'] +['.S', 'ql'] +['ac', 'ular'] +['ĠB', 'ot'] +['_s', 'ync'] +['Ġhapp', 'iness'] +['Ġvolunte', 'ers'] +['Ġs', 'its'] +['/', '<'] +['[', 'e'] +['(file', 'Name'] +['Ġcap', 'ac'] +['ĠMar', 'ia'] +['f', 'ather'] +['Ġgr', 'am'] +['*', 'i'] +['Ġcas', 'o'] +['_d', 'raw'] +['ĠR', 'aw'] +['ĠIter', 'ator'] +['ĠP', 'adding'] +['P', 'D'] +['BO', 'X'] +['ĠS', 'PECIAL'] +['Ġfe', 'cha'] +['Ġv', 'ide'] +['ĠLe', 'ader'] +['ä»', '¥'] +['$', '(".'] +['Ġdiam', 'eter'] +['Ġm', 'ild'] +['Ġrock', 's'] +['app', 'ings'] +['d', 'irectory'] +['.fl', 'ush'] +['ĠJ', 'ess'] +['UN', 'IT'] +['ĠP', 'ear'] +['Ġmand', 'atory'] +['S', 'ur'] +['q', 't'] +['Ġstream', 's'] +['Ġco', 'operation'] +['ĠS', 'ac'] +['Ġche', 'aper'] +['ĉ', 'ch'] +['an', 'imation'] +['f', 'are'] +['(', 'height'] +['(', 'True'] +['N', 'Y'] +['Ġw', 'rest'] +['Ġpoll', 's'] +['Ġencounter', 'ed'] +['ĠMarket', 'able'] +['_P', 'ASSWORD'] +['_SE', 'LECT'] +['ĠArab', 'ia'] +['_c', 'lock'] +['Ġv', 'oy'] +['Ġи', 'з'] +['Ġst', 'ir'] +['is', 'ible'] +['-e', 'ffect'] +['.c', 'reated'] +['Ġto', 'ys'] +['ĠTrad', 'able'] +['Ġr', 'ust'] +['Ġstr', 'cpy'] +['_t', 'imestamp'] +['Ġtalent', 'ed'] +[',', 'null'] +['ĠJ', 'obs'] +['ĠPort', 'land'] +['Ġweak', 'ness'] +['Th', 'row'] +['ĠAng', 'el'] +['ä¿', '®'] +['Ġun', 'cert'] +['ï¼ī', 'Ċ'] +['ĠìĿ', '´'] +['Wh', 'ich'] +['Ġ[-', ']:'] +['S', 'omething'] +['Ġconv', 'icted'] +['k', 'le'] +['ed', 'ium'] +['Ġbranch', 'es'] +['Ġb', 'ases'] +['ç', '®'] +['Ġcomplex', 'ity'] +['ĠF', 'ig'] +['.', 'reshape'] +['$', 'db'] +['_CON', 'ST'] +['ĠT', 'es'] +['.r', 'untime'] +['Ġden', 'y'] +['ĠB', 'SD'] +['Ġk', 'r'] +['h', 'att'] +['ĠSt', 'atic'] +['Ġunivers', 'ities'] +['Re', 'place'] +['Ġdro', 've'] +['Ġad', 'oles'] +['_pl', 'ugin'] +['ĠL', 'GBT'] +['Ġt', 'ex'] +['du', 'ction'] +['ED', 'I'] +['ĠT', 'ed'] +['_', 'URI'] +['Ġre', 'ception'] +['art', 'en'] +['.S', 'ingle'] +['r', 'ice'] +['sc', 'ious'] +['_b', 'g'] +['Ġw', 'ages'] +['ĠS', 'ervlet'] +['UIL', 'ayout'] +['Ġform', 'atted'] +['.M', 'od'] +['<', 'class'] +['is', 'en'] +['Ġrepresent', 'atives'] +['"]', '='] +['Ġport', 'al'] +['ĠHun', 'ter'] +['Ġh', 'iring'] +['__', ')Ċ'] +['ric', 'ulum'] +['u', 'o'] +['li', 'est'] +['Ġt', 'ears'] +['L', 'at'] +['Ġliter', 'al'] +['.In', 'sert'] +['Ġc', 'urs'] +['ĠCom', 'put'] +['Ġterror', 'ism'] +['Ġswe', 'ep'] +['Ġ[]', 'čĊ'] +['Ġpass', 'enger'] +['Ġeast', 'ern'] +['Ġtwe', 'ets'] +['Ġoper', 'ated'] +['w', 'nd'] +['ĠS', 'yn'] +['.t', 'ools'] +['ĠW', 'M'] +['ul', 'ates'] +['Ġbacter', 'ia'] +['(', 'bytes'] +['.set', 'Data'] +['Ġvis', 'ibility'] +['//', '================================================================'] +['el', 'm'] +['Ġgener', 'ating'] +['Ġm', 'v'] +['Ġk', 'h'] +['j', 'en'] +['/', 'search'] +['Ġaccount', 'ing'] +['se', 'gment'] +['act', 'ic'] +['.', 'ip'] +['Ġdeploy', 'ment'] +['Ġfoot', 'er'] +['>', "',Ċ"] +['Ġexpand', 'ing'] +['ĠHam', 'ilton'] +['ĠCon', 'trib'] +['.T', 'ables'] +['Act', 'iv'] +['H', 'H'] +['ocom', 'merce'] +['_', ';'] +['Ġamong', 'st'] +['ow', 'ing'] +['ĠC', 'old'] +['AP', 'H'] +['Ġpsych', 'ological'] +['_t', 'ensor'] +['Ġpack', 'aging'] +['ĠSw', 'eden'] +['Ġp', 'are'] +['Ġag', 'gregate'] +['Ġmoder', 'ate'] +['_h', 'and'] +['Ġdesign', 'ated'] +['Ġdr', 'um'] +['Ġget', 'User'] +['ĠC', 'reek'] +['_s', 'cope'] +['ĠTrans', 'fer'] +['ĠM', 'arg'] +['Ġfight', 'ers'] +['W', 'nd'] +['ĠS', 'el'] +['ĠLa', 'unch'] +['Ġemerg', 'ing'] +['if', 'rame'] +['ĠAdd', 'itional'] +['Ġf', 'ears'] +['Ġsat', 'ellite'] +['_', ':'] +['Ġdis', 'posing'] +['Get', 'Value'] +['Http', 'Post'] +['AT', 'IVE'] +['ul', 'ary'] +['View', 's'] +['Ġatt', 'ending'] +['ĠT', 'ennessee'] +['ĠM', 'ission'] +['Ġmedic', 'ation'] +['ĠW', 'y'] +['ĠAn', 'na'] +['Ø', '¹'] +['ĠVert', 'ex'] +['.t', 'ypes'] +['O', 'rgan'] +['.DataGridView', 'TextBoxColumn'] +['ĠR', 'S'] +['Ġtemp', 'o'] +['(', 'App'] +['Version', 'UID'] +['.p', 'oint'] +['ĠD', 'utch'] +['H', 'ours'] +['L', 'U'] +['Ġqu', 'oted'] +['.b', 'uilder'] +['ĠPer', 'fect'] +['ĠAl', 'ways'] +['_t', 'wo'] +['Ġexclus', 'ively'] +['ĠC', 'ra'] +['ific', 'ar'] +['ĠA', 'WS'] +['ing', 'ham'] +['com', 'plex'] +['k', 'ernel'] +['Ġgr', 'avity'] +['Ġw', 'i'] +['Ġover', 'view'] +['ĠW', 'ant'] +['ĠW', 'P'] +['(', 'sh'] +['.', 'rotation'] +['St', 'ates'] +['ĠTe', 'en'] +['_com', 'ponents'] +['ì', 'Īĺ'] +['Re', 'ceived'] +['Ġly', 'rics'] +['rit', 'es'] +['ĉĉĉĉĉ', 'Ġ'] +['-A', 'merican'] +['[', 'num'] +['/', 'python'] +['ĠU', 'ART'] +['Ġapp', 'le'] +['ĠJon', 'athan'] +['Ġmoment', 'um'] +['à¸', '±'] +['Ĥ', '¹'] +['Ġm', 'ich'] +['and', 'ra'] +['Ġbi', 'ological'] +['ĠM', 'ens'] +['Ġ%', '%'] +['else', 'a'] +['ĠMex', 'ican'] +['.rand', 'int'] +['Ġt', 'ale'] +['ĠValid', 'ate'] +['Ġdefe', 'ated'] +['.ht', 'm'] +['Ġcop', 'per'] +['=', '/'] +['cos', 'ystem'] +['Ġr', 'ip'] +['dec', 'imal'] +['.V', 'ISIBLE'] +['ĠT', 'a'] +['ĉĉĉĉĉĉĉĉ', 'ĉĉĉĉĉĉ'] +['Ġdownload', 'ed'] +['en', 'vironment'] +['Ġnom', 'ine'] +['build', 'ing'] +['ĠSp', 'ot'] +['ipher', 'al'] +['Ġal', 'to'] +['qu', 'et'] +['ĠF', 'T'] +['/', 'get'] +['/m', 'aster'] +['W', 'IN'] +['åħ', 'ĥ'] +['W', 'est'] +['arg', 'c'] +['Ġprodu', 'cers'] +['ĠM', 'uch'] +['_st', 'orage'] +['cred', 'it'] +['CON', 'T'] +['Ġv', 'et'] +['Ġvo', 'ices'] +["('", "',"] +['Ġinstr', 'uments'] +['ĠM', 'SG'] +['es', 'se'] +['re', 'pository'] +['om', 'ics'] +['Ġdeal', 'er'] +['St', 'ill'] +['Ġb', 'anner'] +['asc', 'ii'] +['Ġrem', 'arks'] +['[', 'js'] +['Ġshort', 'er'] +['g', 'ulp'] +['Ġmyst', 'er'] +['Ġk', 'un'] +['ĠB', 'ird'] +['Ġti', 'ene'] +['n', 'ut'] +['ĠU', 'm'] +['Ġw', 'ise'] +['Y', 'eah'] +['INE', 'SS'] +['_b', 'egin'] +['-', 'heading'] +['C', 'ourse'] +['Ġ', 'čĊčĊ'] +['omb', 'ie'] +['grad', 'ed'] +['ĠG', 'PS'] +['Ġ', 'że'] +['F', 'it'] +['c', 'aption'] +['ö', 'n'] +['/', 'image'] +['l', 'ia'] +['(m', 'od'] +['Ġle', 'ak'] +['en', 'za'] +['/', 'H'] +['ĠH', 'appy'] +['D', 'ist'] +['n', 'x'] +['ĠGovern', 'or'] +['(l', 'ast'] +['te', 'acher'] +['ĠS', 'ent'] +['s', 'upport'] +['ject', 'ory'] +['Ġ', 'Ùħ'] +['Reg', 'istration'] +['ĠGr', 'ay'] +[',', 'false'] +['Ġadjust', 'ed'] +['(', 'settings'] +['<', 'R'] +['ĠM', 'age'] +['Ġpl', 'aint'] +['_', ')Ċ'] +['ĉ', 'it'] +['omet', 'ric'] +['.', 'bootstrap'] +['Ġcar', 'ries'] +['I', 'p'] +['Ġ!', '$'] +['Ġswim', 'ming'] +['ĠMar', 'io'] +['ĠQuest', 'ions'] +['P', 'ACE'] +['æĸ', '¹'] +['e', 'or'] +['}}', '"'] +['Ġo', 'ven'] +['ĠK', 'on'] +['Ġwis', 'dom'] +['Ġac', 'quisition'] +['ess', 'ment'] +['ag', 'ine'] +['Ġexpress', 'ions'] +['Sequential', 'Group'] +['F', 'ront'] +['ul', 'pt'] +['aw', 'k'] +["']", ')ĊĊ'] +['_', 'AR'] +['Ġanal', 'og'] +['ul', 'in'] +['_PR', 'INT'] +['ĠL', 'G'] +['Ġb', 'lob'] +['ĠFurther', 'more'] +['_com', 'ponent'] +['ĠC', 'ole'] +['L', 'AN'] +['SCRI', 'PTION'] +['Ġl', 'ap'] +['icens', 'ing'] +['_TIME', 'OUT'] +['ĠF', 'ro'] +['Ġli', 'ability'] +['Ġcom', 'posed'] +['.create', 'SequentialGroup'] +['_p', 'erson'] +['Ġbe', 'am'] +['ĉ', 'ĠĠĠĠĠĠĠĠ'] +['ĠNot', 'Found'] +['.', "'Ċ"] +['ÃŃ', 's'] +['.Text', 'View'] +['P', 'DF'] +['Ġk', 'ar'] +['__', "('"] +['Ġ"', ':"'] +['_m', 'essages'] +['Ġhar', 'vest'] +['.h', 'istory'] +['>', "'Ċ"] +['-f', 'old'] +['æ', 'Ĭ'] +['ĠBet', 'ter'] +['Ġ"\\', '<'] +['sp', 'acing'] +['Ġfurn', 'ished'] +['os', 'er'] +[']', '}Ċ'] +['Ġ$', '"'] +['p', 'ull'] +['.P', 'ost'] +['(', 'ip'] +['Ĺ', 'ı'] +['.f', 'ront'] +['nt', 'e'] +['ĠF', 'M'] +['g', 'uid'] +['Ġnegot', 'iations'] +['agon', 'al'] +['Ġtrem', 'end'] +['unge', 'on'] +['Ad', 'v'] +['car', 'ousel'] +['ÃŁ', 'e'] +['_DE', 'SC'] +['Ġham', 'mer'] +['áº', 'Ń'] +['ĠĠĠĠĠĠĠĠ', 'ĊĊ'] +['-c', 'ore'] +['-s', 'ervice'] +['Ġcorn', 'ers'] +['ĠS', 'F'] +['p', 'red'] +['>', 'A'] +['ĠJ', 'Label'] +['Ġrom', 'antic'] +['Ġtestim', 'ony'] +['os', 'c'] +['ĠGener', 'ation'] +['as', 'ures'] +['_int', 'ernal'] +['Ġprint', 's'] +['Ġ]', ')Ċ'] +['ĠC', 'leveland'] +['re', 'po'] +['D', 'isc'] +['Ġ"', '>Ċ'] +['��', '��'] +['Ġne', 'arest'] +['_t', 'b'] +['(', 'require'] +['EO', 'F'] +['-', 'child'] +['Ġbu', 'dd'] +['.Xtra', 'Editors'] +['alt', 'ies'] +['\\":', '\\"'] +['W', 'ords'] +['Ġloc', 'ally'] +['Ġpurch', 'ases'] +['Draw', 'er'] +['ex', 'tract'] +['Ġexec', 'ut'] +['}', "'."] +['user', 'data'] +['Ġfocus', 'es'] +['-min', 'ute'] +['ĠP', 'ublish'] +['og', 'o'] +['Ġmount', 'ains'] +['B', 'ot'] +['}', '>{'] +['Ġt', 'ension'] +['ro', 'd'] +['m', 'esh'] +['Ġtransform', 'ed'] +[',', 'R'] +['()', '}Ċ'] +['.l', 'ong'] +['Ġg', 'orgeous'] +['ĠS', 'chedule'] +['Ġol', 'dest'] +['Ġsub', 'process'] +['(', 'IN'] +['y', 'ect'] +['ĠCo', 'oper'] +['arn', 'ess'] +['ĠMon', 'itor'] +['.p', 'art'] +['ĠN', 'BC'] +['Ġc', 'otton'] +['Ġh', 'ol'] +['Ġrg', 'ba'] +['ĠB', 'io'] +['Cont', 'inue'] +['P', 'od'] +['Ġparticip', 'ating'] +['clus', 'ions'] +['(By', 'Val'] +['Ã', '¬'] +['ĠH', 'OW'] +['_set', 'opt'] +['Ġaccompany', 'ing'] +['at', 'on'] +['Ġ/', '\\'] +['ĠAuth', 'entication'] +['i', 'én'] +['ĠBar', 'ack'] +['/*', '.'] +['Ġe', 'ager'] +['ĠC', 'ancel'] +['<', 'lemma'] +['ep', 'h'] +['ĉ', 'window'] +['Ġinc', 'idents'] +['),', '('] +['.D', 'es'] +['ib', 'e'] +['ĠFunction', 's'] +['Ġhosp', 'itals'] +['Ġo', 'xygen'] +['root', 'Scope'] +['Ġd', 'rew'] +['ĉ', 'request'] +['not', 'ice'] +['ak', 'u'] +['am', 'ents'] +['f', 'ar'] +['Ġprec', 'ise'] +['_w', 'rapper'] +['Ġlisten', 'ers'] +['A', 'Z'] +['.b', 'ounds'] +['ĠA', 'verage'] +['field', 'set'] +['_', 'axis'] +['Ġexam', 'ination'] +["'", '.Ċ'] +['mon', 's'] +['++)', '{čĊ'] +['ĠForm', 's'] +['íķ', 'ľ'] +['Cpp', 'Method'] +['_tr', 'ace'] +['Ġengine', 'er'] +['ĠFl', 'at'] +['Ġrev', 'ision'] +['Ġhe', 'ating'] +['/', 'profile'] +['.r', 'u'] +['p', 'riority'] +['Ġin', 'fer'] +['_ST', 'REAM'] +['Ġ*', ')('] +['>', '$'] +['OLE', 'AN'] +['OK', 'IE'] +['IB', 'ILITY'] +['U', 'AGE'] +['ĠSur', 'vey'] +['Ġres', 'ign'] +['w', 'ing'] +['Ġsecre', 'ts'] +['Ġch', 'ips'] +['JSON', 'Object'] +['Des', 'ktop'] +['_SY', 'MBOL'] +['(res', 'ource'] +['ĠĊ'] +['Ġnew', 'est'] +['ul', 'i'] +['Ġdes', 'ert'] +['Ġd', 'ip'] +['ĠP', 'ow'] +['Ġequ', 'ation'] +['Ġposs', 'ibilities'] +['ĠF', 'ed'] +['os', 'ph'] +['Ġ[', '%'] +['Ġb', 'ubble'] +['ether', 'lands'] +['Ġc', 'ement'] +['.', 'auto'] +['_', 'AN'] +['âĢĻ', '.'] +['se', 'lection'] +['ĠB', 'ond'] +['D', 'en'] +['-', 'O'] +['.get', 'Type'] +['.W', 'indow'] +['p', 'res'] +['Ġsw', 'inger'] +['"', '})Ċ'] +['Ġp', 'ip'] +['Ġm', 'ice'] +['Ġcomp', 'ound'] +['-', 'plugin'] +['ik', 'o'] +['Ġcent', 'uries'] +['ic', 'ular'] +['-in', 'line'] +['ĉ', 'key'] +['>', '\\<'] +['EN', 'SION'] +['Ġ[', 'čĊ'] +['Ġprecis', 'ely'] +['Ġét', 'é'] +['ĠP', 'ast'] +['ĠCam', 'bridge'] +['-f', 'ull'] +['Ġanaly', 'ze'] +['ĠSte', 'ven'] +['Ġn', 'em'] +['d', 'ue'] +['ore', 'n'] +['Ġmus', 'cles'] +['ij', 'ing'] +['/', '-'] +['ĠKenn', 'edy'] +['R', 'M'] +['oss', 'ible'] +['Ġact', 'ress'] +['Ġd', 'olor'] +['å½', 'ķ'] +['Ne', 'ed'] +['.t', 'oggle'] +['ĠR', 'ace'] +['w', 'ers'] +['.m', 'aterial'] +['ĠD', 'ue'] +['ĠP', 'el'] +['#', 'print'] +['Ġindepend', 'ence'] +['ex', 'us'] +['Sh', 'adow'] +['Ġenc', 'oder'] +['(', 'level'] +['ĠSw', 'ift'] +['.d', 'oc'] +['_se', 'lection'] +['Ġserial', 'VersionUID'] +['Label', 's'] +['Ġperform', 'ances'] +['.T', 'ag'] +['ĠN', 'HL'] +['iz', 'en'] +['/', 'UIKit'] +['_CONT', 'ROL'] +['Ġearn', 'ings'] +['ĠAl', 't'] +['_H', 'ANDLE'] +['C', 'tx'] +['Ġpers', 'u'] +['Ġtr', 'an'] +['ç', '¨'] +['_CH', 'ANNEL'] +['Ġsatisf', 'action'] +['ĠG', 'P'] +['io', 'x'] +['m', 'itt'] +['land', 'o'] +['Ġp', 'ig'] +['inal', 's'] +['ê', 'ncia'] +['S', 'urface'] +['ĠU', 'UID'] +['Ġbenef', 'icial'] +['Ġsequ', 'ences'] +['ĉmem', 'set'] +['Ġmag', 'ical'] +['Â', '«'] +['Ġw', 'orn'] +['AS', 'C'] +['pop', 'up'] +['COM', 'P'] +['_b', 'efore'] +['en', 'ess'] +['U', 'i'] +['L', 'es'] +['.re', 'quire'] +['.Serial', 'izable'] +['add', 'Gap'] +['Ġauthor', 'ization'] +['.py', 'plot'] +['urr', 'ay'] +['lat', 'itude'] +['fr', 'ames'] +['aj', 's'] +['Ġcomp', 'ass'] +['Ġobserv', 'ations'] +['_s', 'up'] +['.en', 'viron'] +['Ġtri', 'ple'] +['ĠRub', 'y'] +['Ġdr', 'ain'] +['_F', 'ILTER'] +['S', 'an'] +['UM', 'P'] +['Null', 'Exception'] +['ĠG', 'ab'] +['ow', 'e'] +['ĠTurk', 'ish'] +['_se', 'quence'] +['ĠGr', 'ant'] +['uel', 'a'] +['Ġw', 'o'] +['Ġc', 'ube'] +['i', 'q'] +['Ġdis', 'orders'] +['Ġextra', 'ordinary'] +['Ġc', 'trl'] +['ĠSe', 'q'] +['ent', 'r'] +['Ġsan', 'ctions'] +['uts', 'ch'] +['Re', 'ports'] +['Ġin', 'herit'] +['Per', 'iod'] +['Ġphot', 'ography'] +['ĠF', 'ramework'] +['Ġspecial', 'ist'] +['Ġ?', 'ĊĊ'] +['_', 'selected'] +['.P', 'layer'] +['Ġal', 'location'] +['(', 'account'] +['Ġstruct', 'ural'] +['v', 'able'] +['-', 'offset'] +['.App', 'CompatActivity'] +['аÐ', '¼'] +['.Add', 'WithValue'] +['Ġicon', 's'] +['Ġshut', 'down'] +['_l', 'ow'] +['ĠCom', 'pare'] +['ĠC', 'e'] +['=', 'head'] +['l', 'am'] +['.p', 'redict'] +['_DE', 'C'] +['ĠS', 'leep'] +['ĠGr', 'atis'] +['Ġsuggest', 'ion'] +['ĠD', 'EL'] +['ca', 'ff'] +['av', 'irus'] +['No', 'thing'] +['ŀ', 'ĭ'] +['Ġwides', 'pread'] +['Ġmechan', 'isms'] +['Ġtext', 'Align'] +['occ', 'up'] +['ĠR', 'ail'] +[':', 'NS'] +['Ġf', 'iber'] +['Ġm', 'k'] +['Ġv', 'intage'] +['-l', 'ong'] +['.re', 'duce'] +['.', 'Entities'] +['(', 'record'] +['Ġple', 'asant'] +['FR', 'ING'] +['.C', 'ells'] +['OT', 'T'] +['ĉelse', 'if'] +['_con', 'firm'] +['ĠView', 'Group'] +['s', 'ym'] +['Ġpr', 'ay'] +['Ġsus', 'pected'] +['Cont', 'ains'] +['Ġb', 'orders'] +['Ġcomponent', 'Did'] +['ASS', 'ERT'] +['Ġinf', 'inite'] +['-', 'order'] +['Ġh', 'ello'] +['ĠGr', 'ade'] +['.currentTime', 'Millis'] +['apol', 'is'] +['z', 'h'] +['ĉ', 'Object'] +[':', '\\\\'] +['H', 'O'] +['val', 'uation'] +['Ġvoc', 'ab'] +['Ġcou', 'pon'] +['atab', 'ases'] +['.Get', 'Type'] +['L', 'earn'] +[']', '="'] +['ĠG', 'ary'] +['ot', 'ive'] +['Ġas', 'h'] +['Ġb', 'ib'] +['XX', 'XX'] +['Ġbal', 'anced'] +['VAL', 'UE'] +['ĠN', 'at'] +['_A', 'd'] +['<', 'E'] +['åĮ', 'º'] +['ĠMethod', 'Info'] +['L', 'IB'] +['Ġconsider', 'able'] +['ĠInd', 'ustry'] +['test', 's'] +['.set', 'Title'] +['ĠBl', 'uetooth'] +['Ġm', 'apped'] +['ĠBru', 'ce'] +['ĠMain', 'Window'] +['ĉ', 'status'] +['Ġr', 'az'] +['ĠM', 'and'] +['Ġclass', 'ification'] +['Per', 'missions'] +['Ġ----------------------------------------------------------------', '------------'] +['Ġcontain', 'ers'] +[':', 'set'] +['_x', 'ml'] +['Ġwh', 'ilst'] +['Th', 'rough'] +['Ġval', 'ign'] +['Ġworld', 's'] +['C', 'ORD'] +['ED', 'IA'] +['ÑĢ', 'ов'] +['Ġsp', 'are'] +['ĠH', 'ad'] +['ĠDE', 'F'] +['(p', 'tr'] +['Ġwarm', 'ing'] +['à¤', '¾'] +['Ġcons', 'ensus'] +['ag', 'ne'] +['CT', 'L'] +['Ġì', 'ķ'] +['.M', 'ain'] +['web', 'Element'] +['Ġp', 'ist'] +['Fl', 'ash'] +['App', 'end'] +['.tw', 'img'] +['T', 'ap'] +['Ġveget', 'ables'] +['al', 'g'] +['.s', 'ample'] +['Ġcoach', 'ing'] +['(', 'ind'] +['Cell', 'Value'] +['Check', 'Box'] +['ĠH', 'ell'] +['RO', 'OT'] +['Ġst', 'adium'] +['Ġinvestig', 'ating'] +[')', '%'] +['st', 'ed'] +['ĠW', 'riting'] +['Ġê', '²'] +['Ġun', 'o'] +['Ġ{{', '--'] +['Ġco', 'ords'] +['Ġun', 'ser'] +['organ', 'ization'] +['ĠCr', 'ime'] +['ĠDemocr', 'at'] +['Ġv', 'in'] +['/', 'file'] +['-', 'api'] +['ĠA', 'y'] +['Ġfund', 'ed'] +['ĠBre', 'xit'] +['ĠG', 'h'] +['ent', 'ina'] +['c', 'ases'] +['Ġd', 'ash'] +['Ġ!!', '}Ċ'] +['H', 'I'] +['Off', 'ice'] +['Ġcapt', 'ain'] +['Ġwor', 'ship'] +['\\', 'C'] +['Ġglo', 'be'] +['_', 'board'] +['Ġbab', 'ies'] +['Ġconsec', 'utive'] +['Ġenh', 'anced'] +['ere', 'um'] +['ĠAd', 'vis'] +['Ġgr', 'ain'] +['Ġc', 'raw'] +['ancell', 'ationToken'] +['.', 'alpha'] +['_W', 'ITH'] +['ĠO', 'tt'] +['ĠC', 'ool'] +['.b', 'atch'] +['Ġver', 'ified'] +['(c', 'allback'] +['Ġreg', 'ards'] +['ĠInt', 'Ptr'] +['ouch', 'er'] +['Ġk', 'in'] +['Ġtou', 'ched'] +['it', 'Ãł'] +['ath', 'on'] +['Ġadj', 'acent'] +['Ġaccom', 'panied'] +['LE', 'AR'] +['Ġim', 'plies'] +['Ġh', 'ill'] +['ĠBalt', 'imore'] +['="', '-'] +['Fin', 'ally'] +['S', 'am'] +['ic', 'opt'] +['Ġs', 'od'] +['Ġm', 'aj'] +['ĠSh', 'ipping'] +['Ġget', 'All'] +['Ġcoach', 'es'] +['Ġdon', 'ations'] +['il', 'ot'] +['ĠT', 'ar'] +['c', 'err'] +['Ġbad', 'ge'] +['Ġmark', 'ers'] +['ĠR', 'and'] +['ais', 'ed'] +['iss', 'ance'] +['Ġexpl', 'oring'] +['uc', 'ed'] +['ĠIndones', 'ia'] +['Ġbene', 'ath'] +['Ġmagn', 'etic'] +['Ġm', 'useum'] +['match', 'Condition'] +['Ġdis', 'rupt'] +['Ġrem', 'ind'] +['ĠT', 'M'] +['Ġ/', '><'] +['Ġf', 'ool'] +['Ġes', 'k'] +['.N', 'ull'] +['ĠD', 'ies'] +['_OUT', 'PUT'] +['_TYP', 'ED'] +['Ġpaint', 'ed'] +['Ġsoph', 'istic'] +['ĠB', 'ear'] +['*', 'n'] +['_P', 'ACK'] +['Ġdeliver', 'ing'] +['ĠC', 'OUNT'] +['åį', 'ķ'] +['Ġj', 'eg'] +['-c', 'ar'] +['f', 'name'] +['Ġr', 'anging'] +['ĠN', 'eg'] +['/', '******/'] +['ĠCH', 'AR'] +['Ġul', 'tra'] +['Gr', 'ad'] +['=', 't'] +['Ġjud', 'ges'] +['ĠD', 'ise'] +['ann', 'ers'] +['Ġsc', 'al'] +['_c', 'al'] +['ĠCON', 'NECTION'] +['_', 'embed'] +['(f', 'n'] +['ĠC', 'raft'] +['ĠP', 'as'] +['")', '->'] +['.con', 'vert'] +['.res', 'ource'] +['ĠST', 'ATUS'] +['ô', 'ng'] +['ĠT', 'it'] +['Ġclass', 'room'] +['ĠArch', 'itect'] +['ĠK', 'ings'] +['Ġstead', 'y'] +['/*', '!Ċ'] +['ĠG', 'ene'] +[')', '";Ċ'] +['ic', 'ia'] +['st', 'an'] +['ĠCon', 'struction'] +['um', 'per'] +['w', 'c'] +['ĠC', 'BS'] +['ing', 'ing'] +['-p', 'arty'] +['(d', 'river'] +['M', 'ARK'] +['Ġn', 'ested'] +['ew', 'ard'] +['Ġdepend', 'ency'] +['Ġm', 'ales'] +['ĠO', 'NE'] +['ĠProdu', 'ction'] +['][', '$'] +['ãĥ¼', 'ãĥ'] +['_LO', 'AD'] +['ĠB', 'ol'] +['el', 'ry'] +['ł', 'éϤ'] +['ĠRe', 'quire'] +['Ġpl', 'acing'] +['xx', 'x'] +['CA', 'LE'] +['Ġth', 'umb'] +['Ch', 'oose'] +['Ġprot', 'otype'] +['VO', 'ID'] +['Ġles', 'bian'] +['Ġtra', 'its'] +['Sh', 'arp'] +['Ġconsum', 'e'] +['Tr', 'uth'] +['Ġaction', 'Performed'] +['ĠEnvironment', 'al'] +['ĠDe', 'an'] +['Ġest', 'ado'] +['s', 'ame'] +['Ġnumer', 'ic'] +['Ġtrans', 'it'] +['.', 'Email'] +['-s', 'ide'] +['_R', 'UN'] +['ĠVill', 'age'] +['_OP', 'EN'] +['è', '¦'] +['.re', 'm'] +['-w', 'arning'] +['any', 'a'] +['Property', 'Changed'] +['Ġ(!', '_'] +['(', 'check'] +['il', 'ia'] +['ĠSo', 'ft'] +['st', 'eps'] +['ĠMad', 'rid'] +['Memory', 'Warning'] +['Ġhand', 'lers'] +['Ġexperi', 'encing'] +['Ġins', 'pect'] +['button', 's'] +['Receive', 'MemoryWarning'] +['chem', 'y'] +['Link', 's'] +['Ġur', 'llib'] +['.System', 'Colors'] +['ĠE', 'igen'] +['Ġpun', 'ishment'] +[':UI', 'Control'] +['bar', 'a'] +['-', 'set'] +['Ġ}čĊčĊ', 'čĊ'] +['Ġtoler', 'ance'] +['Ġinter', 'faces'] +['.', 'redirect'] +['ighb', 'ors'] +['cs', 'rf'] +['_back', 'ground'] +['.', 'Utils'] +['_H', 'T'] +['ĠInter', 'est'] +['im', 'os'] +['Ġgr', 'ants'] +['Ġexam', 'ined'] +['Ð', 'Ķ'] +['Ġc', 'f'] +['for', 'ge'] +['back', 's'] +['ĠObject', 's'] +['_s', 'ent'] +['.', 'entry'] +['ĠTH', 'EN'] +['ell', 'ido'] +['c', 'ia'] +[',', 'res'] +['/std', 'c'] +['.', 'nd'] +['(', 'Int'] +['ĠAuth', 'ors'] +['ĠApp', 'CompatActivity'] +["'", '{'] +['Ġmed', 'i'] +['M', 'usic'] +['ig', 'm'] +['ce', 'ipt'] +['Ġa', 'uss'] +['Ġtarget', 'ing'] +['ĠKe', 'ys'] +['h', 'n'] +[':', ']Ċ'] +['Ġmin', 'eral'] +['Ã', '®'] +['.c', 'a'] +['om', 'ed'] +['Ġshe', 'ets'] +['Ġc', 'amb'] +['Ġdead', 'ly'] +['.in', 'ject'] +['(', 'unit'] +['ĠSe', 'lection'] +['.g', 'ms'] +['(', 'connection'] +['Ġ$', '("'] +['é', 'mon'] +['ĠCurrent', 'ly'] +['pt', 'e'] +['_path', 's'] +['le', 'af'] +['Ġimp', 'lications'] +['pos', 'al'] +['ä½', 'į'] +['[', '/'] +['anc', 'ia'] +['é', 'Ľ'] +['m', 'ul'] +['c', 'ie'] +['Ġge', 'ile'] +['im', 'als'] +['UI', 'View'] +['Ġs', 'urre'] +['serial', 'ize'] +['IS', 'O'] +['Ġarbit', 'rary'] +['Ġsock', 'addr'] +['.f', 'n'] +['ĠM', 'erc'] +['Ġcast', 'ing'] +['Key', 'Down'] +['Ġnew', 'Value'] +['op', 'ens'] +['T', 'odo'] +['Ġflex', 'ibility'] +['ĉĉĉĉ', 'ĠĠ'] +['V', 'elocity'] +['ú', 'n'] +['row', 'ing'] +['Ġcomput', 'ed'] +['`', ')Ċ'] +['st', 'atement'] +['Ġr', 'i'] +['_c', 'art'] +['L', 'ow'] +['trans', 'fer'] +['.n', 'av'] +['Ġgr', 'ave'] +['ĠDo', 'or'] +['ĉ', 'alert'] +['.sub', 'scribe'] +['-', 'profile'] +['ĉb', 'ase'] +['ĠâĪ', 'Ĵ'] +['__', 'ĊĊ'] +['Ġengine', 'ers'] +['Ġexplos', 'ion'] +['Ġd', 'ari'] +['ĉ', 'Log'] +['on', 'al'] +['Ġisol', 'ated'] +['{', 'i'] +['ĠM', 'sg'] +['F', 'uture'] +['Ġrac', 'ist'] +['-w', 'rap'] +['ĠV', 'ers'] +['b', 'org'] +['IS', 'ION'] +['Ġ', 'ÑĢаÐ'] +['ĠY', 'an'] +['init', 'With'] +['Ġn', 'omin'] +['(', 'empty'] +['ÃŃ', 'n'] +['ãĤ', '¤'] +['ĉ', 'width'] +['Ġch', 'amber'] +['/', 'ajax'] +['EM', 'P'] +['Ġnec', 'es'] +['iv', 'os'] +['log', 'ic'] +['*)', '&'] +['cript', 's'] +['Row', 'At'] +['ib', 'lings'] +['Ġe', 'ars'] +['Ġcomput', 'ing'] +['Ġm', 'aker'] +['ĠNe', 'ither'] +['b', 'readcrumb'] +['Ġserial', 'ize'] +['ĠWith', 'in'] +['Ġd', 'ell'] +['_TR', 'ACE'] +['=', 'a'] +['Ġwish', 'es'] +['-in', 'ch'] +['ĠD', 'or'] +['Ġinnoc', 'ent'] +['ĠD', 'ol'] +['Ġint', 'ens'] +['for', 'ced'] +['ĠB', 'IT'] +['Ġphotograph', 's'] +['Ġcas', 'a'] +['ĠL', 'en'] +['\\F', 'ramework'] +['.S', 'imple'] +['Ġde', 'ar'] +[')/', '('] +['ip', 'pi'] +['Ġown', 's'] +['Pl', 'ayers'] +['Ġpropos', 'als'] +['.p', 'i'] +['us', 'alem'] +['D', 'amage'] +['Ġcal', 'ories'] +['ĠCreat', 'ive'] +['Ġ[', '$'] +['Ġ//', 'čĊ'] +['And', 'View'] +['è', 'me'] +['.c', 'ustom'] +['_f', 'actory'] +['command', 's'] +['_lo', 'ok'] +['Ġstr', 'cmp'] +['Y', 'N'] +['a', 'ired'] +['Ġaud', 'it'] +['о', 'ÑģÑĤ'] +['ĠRe', 'verse'] +['ropri', 'ate'] +['et', 'ics'] +['<', 'vector'] +['.s', 'elenium'] +['.', 'or'] +['Ġpred', 'icate'] +['Ġfinish', 'ing'] +['Ġk', 'le'] +['ĠRep', 'os'] +['ĠK', 'han'] +['ĠM', 'aking'] +['ĠF', 'S'] +['Ġp', 'ute'] +['ĉ', 'state'] +['_S', 'UPPORT'] +["'", '-'] +['orient', 'ation'] +['Ġexist', 'ed'] +['atur', 'a'] +['Ġexpect', 's'] +['ĠSh', 'adow'] +['Ġorgan', 'iz'] +['å', 'ŀĭ'] +['Ġsusp', 'ension'] +['Ġu', 'it'] +['Ġsimult', 'aneously'] +['ĠAff', 'ero'] +[':', '");Ċ'] +['Ġro', 'cket'] +['c', 'as'] +['eter', 'mine'] +['ace', 'ut'] +['x', 'l'] +['ĠA', 'MD'] +['(', 'graph'] +['ass', 'oci'] +['_C', 'R'] +['.ar', 'ange'] +['(j', 'Label'] +['Ġbe', 'ef'] +['Qu', 'ick'] +['.c', 'ard'] +[']', '):'] +['-', 'gr'] +['.G', 'ONE'] +['_C', 'LOSE'] +['ĠNe', 'v'] +['ÃŃ', 'as'] +['Ġste', 'pped'] +['ĠFre', 'edom'] +['ĠW', 'R'] +['NS', 'Array'] +['_r', 'x'] +['_d', 'ialog'] +['Ġhot', 'els'] +['Ġ(', '\\<'] +['ĠD', 'iamond'] +['Ġassum', 'ption'] +['um', 'i'] +['(', 'items'] +['č', 'ččĊ'] +['æ³', 'ķ'] +['Ġn', 'el'] +['Book', 's'] +['åİ', '¿'] +['us', 'b'] +['ĠF', 'IN'] +['æ', '¬'] +['Ġcorpor', 'ations'] +['US', 'A'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['.p', 'roperty'] +['ew', 'ise'] +['_', 'plot'] +['">', "';Ċ"] +['Ġpe', 'pper'] +['Ġsh', 'ed'] +['ĠMed', 'ium'] +['ĠC', 'ookie'] +['Ġoverse', 'as'] +['ed', 'or'] +['asure', 'ment'] +['åŃ', 'ĺ'] +["Ġ'", ".'"] +['Ġph', 'p'] +['ĠPRO', 'C'] +['Ġexception', 'al'] +['(', 'th'] +['ĠJ', 'et'] +['Ġoccup', 'ied'] +['.set', 'Image'] +['ĠRel', 'ated'] +['uck', 'er'] +['M', 'embers'] +['PR', 'INT'] +['ĠG', 'lo'] +['_V', 'IEW'] +['}', '",Ċ'] +['Ġad', 'option'] +['[]', ')Ċ'] +['ĠMiss', 'ouri'] +['ĠLin', 'coln'] +['eral', 'd'] +['Pop', 'up'] +['Ġf', 'ate'] +['-', 'bootstrap'] +['fe', 'ctions'] +['ĠP', 'oll'] +['_ARG', 'S'] +['in', 'ance'] +['-h', 'ome'] +['.', '),'] +['_d', 'one'] +[':', 'ĊĊĊ'] +['Ġdiscuss', 'ing'] +['ĠSQL', 'Exception'] +['Ġelect', 'ro'] +['ĉ', 'req'] +['Ġz', 'w'] +['Ġl', 'ui'] +['Ġover', 'night'] +['$', 'user'] +['ĠW', 'AY'] +['Ġall', 'erg'] +['Ġdisappoint', 'ed'] +['Ġradi', 'ation'] +['Ġimpress', 'ed'] +['ific', 'ates'] +['Ġto', 'b'] +['CL', 'ASS'] +['Ġc', 'uda'] +['_d', 'et'] +['-', 'post'] +['ul', 'u'] +['Trans', 'lation'] +['-h', 'and'] +['.y', 'ear'] +['ĠM', 'ongo'] +['Ġun', 'clear'] +['.', 'engine'] +['WEB', 'PACK'] +['r', 'ices'] +['_AC', 'CESS'] +['Ġh', 'olidays'] +['per', 'cent'] +['.Id', 'entity'] +['ĠG', 'ov'] +['Ġpassion', 'ate'] +['!!', '.'] +['ĠGree', 'ce'] +['plus', 'plus'] +["'))", ';'] +['G', 'P'] +['Ġexc', 'it'] +['.tab', 'Page'] +['_', 'cond'] +['Ġspons', 'or'] +['M', 'ODULE'] +['_pro', 'c'] +['Ġ$', 'Ċ'] +['Ġr', 'ational'] +['.T', 'ool'] +['Ġi', 'hr'] +['cc', 'a'] +['åĵ', 'ģ'] +['ĠE', 'state'] +['IB', 'UTE'] +['Action', 'Performed'] +['ĠS', 'olar'] +['¦', 'Ĥ'] +['Ġequ', 'ity'] +['t', 'id'] +['Ġrec', 'ip'] +['.s', 'imple'] +['m', 'k'] +['ĠL', 'uke'] +['ĠGuard', 'ian'] +['Ġenc', 'rypted'] +['Ġdomin', 'ant'] +['.', 'place'] +['ĠN', 'V'] +['Ġtong', 'ue'] +['(', 'Get'] +['Ġst', 'ainless'] +['.P', 'lay'] +['Ġe', 'b'] +['ac', 'i'] +['.b', 'uffer'] +['readcr', 'umbs'] +['Ġvacc', 'ine'] +['p', 'rom'] +['Ġuser', 'Info'] +['Ġsl', 'ug'] +['Serial', 'izedName'] +['-w', 'ide'] +['Ġre', 'actions'] +['ĠY', 'ang'] +['ĠAdd', 's'] +['(user', 'Id'] +['Ġpl', 'ates'] +['ĠM', 'EM'] +['Ġb', 'ail'] +['In', 'side'] +['et', 'ed'] +['Ġels', 'if'] +['Ġs', 'ake'] +['Ġc', 'ycles'] +['Ġì', 'Ĺ'] +['ĉ', 'I'] +['-c', 'ollapse'] +['ĠG', 'MT'] +['De', 'claration'] +['Ġg', 'ros'] +['Ġreach', 'es'] +['Ġcust', 'ody'] +['Unt', 'il'] +['t', 'u'] +['ĠCh', 'en'] +['Ġn', 'x'] +['(', 'addr'] +['ĠO', 'ffer'] +['Ġcol', 'leg'] +['ass', 'ador'] +['Ġm', 'apper'] +['ĠS', 'IGNAL'] +['ĠB', 'loom'] +['ĠH', 'oll'] +['ĠIm', 'per'] +['-d', 'es'] +['_s', 'ite'] +['Pro', 'c'] +['E', 'qu'] +['Ġat', 'omic'] +['ĠW', 'oman'] +['s', 'ent'] +['sc', 'ar'] +['Ġint', 'elligent'] +['ĠGet', 'ting'] +['ĠReg', 'istration'] +['ĠPh', 'ill'] +['Ġkill', 'er'] +['unic', 'ode'] +['Ċ', 'ĉĉĊ'] +['ĠJac', 'ob'] +['ĠCon', 'st'] +['Ġloc', 'ate'] +['Ġca', 'us'] +['ĠSch', 'olar'] +['Ġconstitution', 'al'] +['Ġinfl', 'ation'] +['ĠG', 'ot'] +['=', 'array'] +['end', 'um'] +['Ġtransl', 'ated'] +['Ġdiv', 'orce'] +['En', 'tries'] +['Ġs', 'or'] +['ĠQu', 'ote'] +['irl', 'ines'] +['U', 'K'] +['Ġexc', 'el'] +['(', 'opt'] +['ĠAD', 'V'] +[',:', ','] +['Ġcontact', 'ed'] +['ĠD', 'A'] +['Ġr', 'ings'] +['ĠIndust', 'rial'] +['.get', 'Context'] +['Ġforg', 'otten'] +['ĠT', 'an'] +['Ġp', 'ants'] +['Ġo', 'v'] +['Ġdec', 'oder'] +['ĠPart', 'ial'] +['Ġv', 'c'] +['Ġbatt', 'les'] +['A', 'rial'] +['FRING', 'EMENT'] +['ir', 'ates'] +[',', 'w'] +['aint', 'enance'] +['ĠO', 'd'] +['ĠTechn', 'ologies'] +['åī', 'į'] +['ĠCar', 'ter'] +['.find', 'All'] +['N', 'ome'] +['B', 'en'] +['ĠUs', 'age'] +['ĠP', 'icture'] +['Ġbad', 'ly'] +['_p', 'anel'] +['Ġpat', 'ent'] +['ĠProt', 'ocol'] +['lot', 'te'] +['ĉ', 'player'] +['je', 'ctions'] +['Ġd', 'ou'] +['_re', 'lease'] +['urn', 'iture'] +['_t', 'ax'] +['ĠF', 'ields'] +['.d', 'ataset'] +['_m', 'aster'] +['CLU', 'DE'] +['ĠPh', 'arm'] +['b', 'st'] +['Ġoper', 'ational'] +['.c', 'ell'] +['Ġident', 'ifying'] +['Ġj', 'wt'] +['t', 'uple'] +['ĠT', 'C'] +['ĠC', 'ro'] +['ix', 'map'] +['-', 'components'] +['gener', 'al'] +['Ġo', 'z'] +['_D', 'e'] +['_d', 'ouble'] +['ĠTo', 'o'] +['.View', 'Group'] +['g', 'ate'] +['d', 'ings'] +['ph', 'otos'] +['Ġgrand', 'e'] +['ol', 'lect'] +['_l', 'in'] +['Ġaw', 'ful'] +['f', 'ilters'] +['Ġaltern', 'ate'] +['es', 'p'] +['Ġcomp', 'ress'] +['e', 'o'] +['ĠS', 'cale'] +['Ġind', 'irect'] +['Ġinv', 'oice'] +['ĊĊĊĊĊĊĊĊ', 'ĊĊĊĊĊĊĊĊ'] +['Start', 'ing'] +['ĠPl', 'ayers'] +['ie', 'le'] +['.', 'then'] +['Or', 'd'] +['ĠT', 'uple'] +['Ġb', 'out'] +['ĠStat', 'istics'] +['Pre', 'view'] +['Ġp', 'uzzle'] +['ĠW', 'idth'] +['ST', 'ATE'] +['Ġover', 'lay'] +['ĉ', 'on'] +['Ġin', 'fr'] +['Ġsm', 'allest'] +['lock', 'ed'] +['ÑĤ', 'о'] +['ss', 'l'] +['Ġde', 'emed'] +['Ġs', 'co'] +['re', 'ck'] +['Ġj', 'Button'] +['Ġmiss', 'ions'] +['ç§', '°'] +['.Selected', 'Index'] +['T', 'ABLE'] +['Se', 'pt'] +['Ġacknow', 'ledge'] +['Ġstrt', 'otime'] +['ĠT', 'ell'] +['ĠD', 'ak'] +['Ġal', 'uminum'] +['Ġf', 'ence'] +['ĠSt', 'ars'] +['CON', 'FIG'] +['Ġretro', 'fit'] +['Ġemph', 'asis'] +['/', 'header'] +['ĠS', 'omething'] +['in', 'ished'] +["='", '".$'] +['ĠValid', 'ators'] +['Ġpol', 'ar'] +['section', 's'] +['.as', 'px'] +['Ġas', 'pir'] +['.M', 'ock'] +['Code', 'Gen'] +['Ġpe', 'ut'] +['Ġaccept', 'ing'] +['Ġback', 'ing'] +['P', 'icture'] +['/', 'ap'] +['еÐ', '³'] +['_SE', 'C'] +['-', 'use'] +['annot', 'ation'] +['Ġcogn', 'itive'] +['Ġg', 'rip'] +['h', 'our'] +['ĠLeg', 'al'] +['Ġep', 'ic'] +['.t', 'oolStrip'] +['.not', 'ify'] +['.L', 'ast'] +['OR', 'IZ'] +['M', 'iddleware'] +['cri', 'ptions'] +['l', 'ash'] +['_F', 'OUND'] +['ĠLiver', 'pool'] +['Ġ{}', '",'] +['Inst', 'all'] +['Ġn', 'it'] +['Ġfig', 'ured'] +['[', 'len'] +['.W', 'in'] +['.pl', 'atform'] +['Ġgam', 'bling'] +['(d', 't'] +['av', 'ery'] +['ĉ', 'include'] +['Wh', 'ether'] +['R', 'outing'] +['Ġther', 'ap'] +['Rem', 'ote'] +['ĠL', 'oss'] +['y', 'll'] +['Ġappro', 'ached'] +['ĠV', 'ehicle'] +['ĠAl', 'pha'] +['Ġvoc', 'ê'] +['ans', 'wers'] +['NS', 'Dictionary'] +['cons', 'ider'] +['un', 'used'] +['ĠF', 'an'] +['or', 'able'] +['f', 're'] +['ĠDIS', 'CLAIM'] +['ĠAct', 'or'] +['.', ']'] +['to', 'Have'] +['.user', 'Id'] +['Ġspeed', 's'] +['ew', 'ay'] +['Ġrec', 'urs'] +['ĠÐ', '³'] +['_pr', 'iv'] +['!', 'âĢĿĊĊ'] +['Ch', 'oice'] +['Ġsett', 'le'] +['Ġplan', 'es'] +["'", '},'] +['T', 'om'] +['IT', 'ER'] +['!', '"Ċ'] +['å', '»'] +['achel', 'or'] +['Ġsepar', 'ation'] +['Ġd', 'al'] +['ad', 'j'] +['Ġreg', 'isters'] +['r', 'iz'] +['ĠNot', 'ice'] +['Ġl', 'u'] +['Ġcour', 'age'] +['Ġax', 'es'] +['cell', 'ent'] +['.as', 'ync'] +['Ġcompat', 'ibility'] +['ç', '«'] +['Ġ!', 'ĊĊ'] +['ĉ', 'title'] +['Y', 'LE'] +['ĉ', 'message'] +['U', 'UID'] +['OLD', 'ER'] +['ĠH', 'H'] +['ĠStyle', 'Sheet'] +['Ġaccess', 'ed'] +['.', 'validation'] +['t', 'asks'] +['Ġpoll', 'ution'] +['.c', 'anvas'] +['Ġing', 'redient'] +['ĠC', 'abin'] +['A', 'h'] +['old', 'own'] +['ĠNO', 'I'] +['ĠÃ', 'Ĺ'] +['[', 'f'] +['ed', 'uc'] +['y', 'alty'] +['(n', 'ot'] +['_', 'State'] +['am', 'en'] +['Ġda', 'o'] +['ud', 'ad'] +['ell', 'ers'] +['}', '&'] +['lic', 'ity'] +['_W', 'INDOW'] +['Ġt', 'atto'] +['val', 'or'] +['.R', 'ange'] +['Ġrefer', 'enced'] +['ĠRes', 'erve'] +['M', 'oney'] +['SCRI', 'PT'] +['/', 'product'] +['cho', 'ices'] +['Ġt', 'in'] +['ãĤ', 'ĵ'] +['Ġsepar', 'ator'] +['Ġp', 'kg'] +['am', 'med'] +['ĠM', 'AT'] +['!', '!ĊĊ'] +['Ġr', 'aid'] +['Ġmotiv', 'ation'] +['ĠX', 'P'] +['ĠBack', 'ground'] +['ĠQu', 'aternion'] +['.define', 'Property'] +['ik', 'er'] +['ĉp', 'arent'] +['ĠOrigin', 'ally'] +['ant', 'age'] +['ĠH', 'ans'] +['Ġtim', 'eline'] +['.c', 'ur'] +['op', 'ic'] +['ĠSe', 'qu'] +['m', 'ust'] +['ĠCo', 'al'] +['Ġform', 'atter'] +['_R', 'GB'] +['Ġ_', '("'] +["'}", '),Ċ'] +['Ġ=', '================'] +['ĠF', 'UNCTION'] +['Ġl', 'ng'] +['ic', 'ates'] +['l', 'ive'] +['_', 'engine'] +['Ġtown', 's'] +["'))", 'ĊĊ'] +['ĠP', 'K'] +['(', 'api'] +['ĉs', 'canf'] +['pack', 'et'] +['.ph', 'one'] +['á', 'Ģ'] +['ĠAnd', 'y'] +['_N', 'AMES'] +['PL', 'Y'] +['Ġmin', 's'] +['im', 'i'] +['Ġbr', 'ick'] +['Ġbl', 'ade'] +['.std', 'out'] +['}`', ';Ċ'] +['Sh', 'ift'] +['ĉs', 'b'] +['ĠCheck', 's'] +['Ġphenomen', 'on'] +['Av', 'atar'] +['Ġmin', 'istry'] +['ro', 'se'] +['ĉ', 'File'] +['Ġtit', 'led'] +['(', 'LOG'] +['Ġg', 'an'] +['des', 'ign'] +['(),', 'čĊ'] +['Ġb', 'ones'] +['st', 'm'] +['ÅĽ', 'Äĩ'] +['ĠInput', 'Stream'] +['Ġvol', 'unt'] +['ĠSerial', 'izable'] +['Ġfight', 'er'] +['ĠDr', 'ag'] +['T', 'witter'] +['Ġsubs', 'id'] +['ç', '¼'] +['Ġfor', 'ums'] +['.load', 'ing'] +['log', 'ged'] +['_', 'this'] +['Ġterr', 'ain'] +['Ġir', 're'] +['ĠIn', 'g'] +['ĠC', 'N'] +['_object', 's'] +['.', 'uid'] +['Ġconscious', 'ness'] +['T', 'INGS'] +['ĠG', 'all'] +['Ġport', 'ray'] +['ĠDevelop', 'er'] +['Ġparticip', 'ant'] +['Ġ"', ';čĊ'] +['/', 'model'] +['ĠOper', 'ations'] +['^', '\\'] +['ĠL', 'ater'] +['Ġrais', 'es'] +['-n', 'one'] +['.m', 'eta'] +["='", '.$'] +['Fin', 'ished'] +['Ġrepl', 'acing'] +['Ġsam', 'pling'] +['ĠJ', 'en'] +['"', 'There'] +['RE', 'AL'] +['A', 'LE'] +['ìĬ', '¤'] +['Or', 'ders'] +['_param', 'eter'] +['ĠOlymp', 'ic'] +['Ġtr', 'ès'] +['Ġare', 'na'] +['i', 'ol'] +[';', '?>'] +['Ġimpact', 's'] +['ĠW', 'S'] +[':', 'get'] +['Ġfl', 'ights'] +['ĠRuss', 'ell'] +['c', 'amera'] +['F', 'n'] +['s', 'igma'] +['Ġfor', 'cing'] +['Ġloc', 'als'] +['Ġdepart', 'ure'] +['Ġcelebr', 'ation'] +['ĠS', 'ay'] +['ï¼', 'Ĵ'] +['ĠH', 'ills'] +['.has', 'OwnProperty'] +['Ġtyp', 'ings'] +['.A', 'PI'] +['Ġdon', 'ation'] +['Operation', 'Exception'] +['.Act', 'ivity'] +['c', 'plusplus'] +['ĠChar', 'lie'] +['Ġimport', 'ed'] +['Ġd', 'ann'] +['Ġoccas', 'ions'] +['Ġimplement', 'ing'] +['Ġpur', 'ple'] +['.d', 'ialog'] +['SQL', 'Exception'] +['ern', 'o'] +['Ġw', 'ars'] +['Ġpast', 'e'] +['Ġdecre', 'ased'] +['Ġhar', 'sh'] +['Ġel', 'abor'] +['input', 's'] +['ĠView', 's'] +['Ġerror', 'Message'] +['_m', 'ul'] +['ĉ', 'write'] +['ĠC', 'op'] +['ĠAnn', 'ual'] +['(b', 'utton'] +['Ġv', 'ida'] +['b', 'ars'] +['ĠHar', 'vard'] +['ĉex', 'pect'] +['Ġindex', 'es'] +['Ġdocument', 'ary'] +['Ġf', 'lesh'] +['OR', 'LD'] +['ĠD', 'elta'] +['M', 'AND'] +['Br', 'ush'] +['-c', 'olumn'] +['Ġdevelop', 'ments'] +['method', 'Visitor'] +['s', 'lice'] +['ĠP', 'DO'] +['Ġinvest', 'ing'] +['ir', 'able'] +['Ġxml', 'ns'] +['ï¼', 'Ľ'] +['art', 'a'] +['Ġthe', 'ories'] +['_c', 'ity'] +['Ġ$', '__'] +['Cre', 'ating'] +['(', 'pr'] +['D', 'ropdown'] +['ism', 'atch'] +['ĠN', 'ET'] +["']", ')){Ċ'] +['ĠVal', 'ues'] +['ĠSE', 'O'] +['ĠST', 'AT'] +['Ġe', 'cosystem'] +['Ġtem', 'pt'] +['Ġ\\', '\\'] +['Ġ//', '{Ċ'] +['ĠChrist', 'opher'] +['ĠKent', 'ucky'] +['ĠHttp', 'ServletResponse'] +['Ġhy', 'brid'] +['y', 'on'] +['Ġfeed', 'ing'] +['ĠEx', 'tra'] +['N', 'orm'] +['IT', 'CH'] +['ĠSe', 'an'] +['ĠUp', 'load'] +['m', 'un'] +['p', 'ur'] +['Ġp', 'ersistent'] +['ĠID', 'C'] +['ĠPer', 'form'] +['.m', 'erge'] +['_', 'room'] +['Mean', 'while'] +['!', "='"] +['ĠW', 'el'] +['Args', 'Constructor'] +['.D', 'atabase'] +['Ġcount', 'ing'] +['()', '*'] +['Ķ', 'åĽŀ'] +['ĠT', 'OP'] +['m', 'ill'] +['ĠD', 'T'] +['IGN', 'ED'] +['ĠK', 'B'] +['Ġcomp', 'ly'] +['S', 'outh'] +['_c', 'ollection'] +['Ch', 'apter'] +['Ġexpl', 'aining'] +['_', 'AM'] +['_t', 's'] +['c', 'ards'] +['Ġqu', 'el'] +['Ġp', 'ole'] +['Ġtouch', 'down'] +['ĠO', 'thers'] +['Ġpe', 'ers'] +['ĠType', 'Error'] +['Ġsix', 'th'] +['Ġche', 'er'] +['Ġdis', 'pute'] +['us', 'c'] +[')', '],'] +['th', 'umb'] +['Ġh', 'iding'] +['ĠS', 'IG'] +['lik', 'es'] +['ĠP', 'AGE'] +['.Ref', 'lection'] +['Ġhead', 'quarters'] +['T', 'ING'] +['ĠG', 'host'] +['M', 'LE'] +['$', 'Ċ'] +['Ġcontr', 'ary'] +['ext', 'end'] +["']", ').'] +['FF', 'ECT'] +['ĠP', 'interest'] +['úmer', 'o'] +['ric', 'ane'] +['ĉs', 'ession'] +['Ġcr', 'ystal'] +['-', 'Control'] +['overn', 'ment'] +['og', 'raf'] +['-', 'action'] +['v', 'olume'] +['ft', 'en'] +['Ġun', 'con'] +['Ġan', 'imate'] +['Ġle', 'ase'] +['sc', 'r'] +['Ġref', 'use'] +['ãĢ', 'ĭ'] +['ft', 'p'] +['in', 'formation'] +['Ġeval', 'uated'] +['Ġin', 'jection'] +['Ġj', 'ack'] +['Ġwork', 'shop'] +['æ³', '¨'] +['PT', 'H'] +['ĠT', 's'] +['off', 'er'] +['ĉ', 'os'] +['Ġking', 'dom'] +['M', 'issing'] +['Ġlaw', 'makers'] +['ext', 'Field'] +['Ġsing', 'ing'] +['ab', 'i'] +['/', 'client'] +['.m', 'edia'] +['ATEG', 'ORY'] +['Sign', 'ature'] +['%', "',Ċ"] +['ĠF', 'uck'] +['][', ':'] +['Ġsens', 'ors'] +['/', 'com'] +['ĠPr', 'imary'] +['.S', 'QL'] +['_pro', 'gram'] +['Ġp', 'ills'] +['Ġinteg', 'ral'] +['Ġfle', 'et'] +['Ġdro', 'pping'] +['.s', 'l'] +['Be', 'en'] +['Ġp', 'ets'] +['Ġadvis', 'ed'] +['Ġdr', 'agon'] +['_', 'EDIT'] +['(', 'im'] +['F', 'ER'] +['ĠDr', 'ug'] +['(r', 'andom'] +['Ġcomp', 'ression'] +['ou', 'st'] +['[', '%'] +['Ġbuy', 'er'] +['h', 'op'] +['R', 'oles'] +['man', 'age'] +['Ġpain', 'ful'] +['ĠBr', 'anch'] +['-mod', 'al'] +['en', 'ant'] +['ĠM', 'esh'] +['/', 'font'] +['ĠG', 'raham'] +['Ġâ', 'ĺ'] +['Ġn', 'c'] +['ĠFranc', 'is'] +['Ġspec', 'ification'] +['Ġdam', 'ages'] +['-', 'config'] +['Ġthe', 'oret'] +['sec', 'ure'] +['_m', 'ulti'] +['aceut', 'ical'] +['Ġdemand', 'ing'] +['en', 'ne'] +['IST', 'S'] +['()', '));ĊĊ'] +['Re', 'ason'] +['Re', 'cent'] +['ph', 'ase'] +['Ġps', 'y'] +['_M', 'AN'] +['Ġvolunte', 'er'] +['å', '¿'] +['istrib', 'uted'] +['li', 'o'] +['Ġproduct', 'ivity'] +['_com', 'm'] +['S', 'pring'] +['n', 'is'] +['.', 'weight'] +['ĠC', 'ancer'] +['Al', 'loc'] +['ĠT', 'weet'] +['Ġsepar', 'ately'] +['ĉ', 'check'] +['_p', 'roperties'] +['.', 'Unit'] +['_CL', 'K'] +['Ġg', 't'] +['Ġ(', ');ĊĊ'] +['Ġhand', 'y'] +['ĠThom', 'pson'] +['Ġunn', 'ecessary'] +['ĠRe', 'ader'] +['G', 'N'] +['=', 'request'] +['ĠU', 'tility'] +['.Re', 'pository'] +['ĠA', 'x'] +['hy', 'dr'] +['ie', 'u'] +['Ġth', 'y'] +['Ġl', 't'] +['_m', 'ail'] +['ä¿®', 'æĶ¹'] +['ail', 'and'] +['ĠPhil', 'ip'] +['Ġbit', 'ter'] +['Ġbet', 'ting'] +['Ġtim', 'ed'] +['ock', 's'] +["'", 'a'] +['Ġal', 'gorithms'] +['Ġre', 'interpret'] +['Ġto', 'ss'] +['ro', 'gen'] +['Ġhop', 'ed'] +['(', 'selected'] +['Ġvent', 'ure'] +['TE', 'X'] +['ĠLe', 'ave'] +['.Sub', 'string'] +['Ġgr', 'ateful'] +['uk', 'a'] +['ĠCon', 'sumer'] +['Ġag', 'greg'] +['C', 'ircle'] +['à¸', 'ģ'] +['_block', 's'] +['Ġleg', 'ally'] +['Ġ"', '|'] +['ãĥ', 'ĥ'] +['.', 'board'] +['.A', 'b'] +['Function', 's'] +['rec', 'ipe'] +['è', 'ĩ'] +['ĠO', 'xford'] +['Ġwho', 'les'] +['.B', 'uild'] +['_ch', 'anged'] +['h', 'ai'] +['Ġdepart', 'ments'] +['I', 'mp'] +['Ġcoal', 'ition'] +['IN', 'FRINGEMENT'] +['Ġemp', 'ower'] +['itch', 'es'] +['N', 'orth'] +['Ġinfl', 'amm'] +['ON', 'SE'] +['Ġmiss', 'ile'] +['ĠR', 'aj'] +['ĠIss', 'ue'] +['Ġat', 'oi'] +['ca', 'led'] +['.Cont', 'rollers'] +['ĠW', 'olf'] +['Ġcrush', 'ers'] +['á»', 'ĩ'] +['.A', 'uth'] +['.add', 'Attribute'] +['h', 'is'] +['Ġbo', 'ots'] +['.c', 'lean'] +['c', 'amp'] +['Ġten', 'ant'] +['Ġt', 'une'] +['Ġ{}', "'."] +['Ġwork', 'out'] +['Re', 'po'] +['Ġpartial', 'ly'] +['MI', 'SSION'] +['j', 'amin'] +['ĠS', 'B'] +['Ġdetermin', 'ation'] +["Ġ'", "');Ċ"] +['ĠB', 'eng'] +['Ġv', 'os'] +['Ġin', 'hab'] +['/', 'lang'] +['s', 'burgh'] +['Exec', 'utor'] +['h', 'one'] +['ĠCh', 'allenge'] +['_link', 's'] +['.Le', 'vel'] +['Ġunder', 'ground'] +['-c', 'ode'] +['Ġoptim', 'ization'] +['log', 'ging'] +['_de', 'st'] +['Ġsn', 'ake'] +['Ġchemical', 's'] +['_IMPORT', 'ED'] +['ado', 'op'] +['ĠTH', 'AT'] +['man', 'aged'] +['Ġredu', 'ces'] +['ĠRE', 'AL'] +['ĠG', 'uy'] +['_GENER', 'IC'] +['/', '********************************'] +['.', 'amount'] +['Ġd', 'ere'] +['get', 'Time'] +['Ġp', 'ant'] +['an', 'onymous'] +['Ġharmon', 'y'] +['ĠAl', 'an'] +['Ġscen', 'arios'] +['Ġd', 'irt'] +['ht', 'ags'] +['M', 'c'] +['Sh', 'ell'] +['r', 'in'] +['{', 'čĊčĊ'] +['.p', 'ow'] +['ĉ', 'client'] +['Ġconspir', 'acy'] +['Ġad', 'mission'] +['ĠReg', 'ional'] +['ĠView', 'Controller'] +['ĠPhilipp', 'ines'] +['Ġde', 'pos'] +['Ġp', 'ap'] +['ĠP', 'ad'] +['P', 'aul'] +['.Com', 'boBox'] +['Ġt', 'utor'] +['ĠRec', 'ipe'] +['w', 'riting'] +['Ġcontrib', 'utor'] +['OT', 'H'] +['Sm', 'all'] +['V', 'I'] +['Ġh', 'acer'] +['e', 'qu'] +['ĠEx', 'amples'] +['h', 'uman'] +['.m', 'essages'] +['ĉt', 'yp'] +['Ġ(', 'čĊ'] +['ĠS', 'SL'] +['LE', 'N'] +['ĠRom', 'ney'] +['(', 'grid'] +['ĉ', 'min'] +['Ġ>', 'ĊĊ'] +['Ġfr', 'uits'] +['Ġvot', 'er'] +['In', 'line'] +['pan', 'e'] +['ĠC', 'ollections'] +['char', 'set'] +['Ġsp', 'am'] +['z', 'b'] +['item', 'ap'] +['Ġsucceed', 'ed'] +['_C', 'OL'] +['Ġel', 'apsed'] +['im', 'eter'] +['Ġrecover', 'ed'] +['T', 'ensor'] +['hatt', 'an'] +['.set', 'up'] +['ist', 'o'] +['(', 'head'] +['ĠS', 'IZE'] +['Ġtact', 'ics'] +['Ġdist', 'ur'] +['Ġpre', 'val'] +['ici', 'os'] +['(', 'Value'] +['_c', 'ols'] +['ĠF', 'at'] +['Ġse', 'al'] +['Ġs', 'ons'] +['Ġens', 'ures'] +['Ġpress', 'ing'] +['=', '&'] +['igen', 'ous'] +['Ġharass', 'ment'] +['_', 'JSON'] +['Ġign', 'or'] +['yn', 'omial'] +['om', 'er'] +['_st', 'atic'] +['Ġsignific', 'ance'] +['Ġcirc', 'les'] +['_S', 'ystem'] +['Ġdiscipl', 'ine'] +['Ġdress', 'ed'] +['Ġs', 'phere'] +['Ġclim', 'b'] +['_', 'actions'] +['ĠB', 'ab'] +["Ġ'", "=',"] +['_s', 'chema'] +['"', 'use'] +['Ġund', 'ers'] +['Ġc', 'ups'] +['.s', 'creen'] +['/', 'new'] +['Ġappe', 'aring'] +['T', 'OP'] +['vis', 'ed'] +['cl', 'ang'] +['Ġinvestig', 'ators'] +['Ġmyster', 'ious'] +['Ġprom', 'ising'] +['Ġqual', 'ify'] +['Ġc', 'ave'] +['Ġequ', 'ip'] +['=', 'x'] +['G', 'T'] +['(', 'link'] +['.', 'velocity'] +['.', 'erase'] +['ot', 'er'] +['++++', '++++'] +['pro', 'fit'] +['Ġz', 'ones'] +['_', 'uid'] +['-', 'ser'] +['Ġobject', 'ives'] +['Ġmil', 'f'] +['web', 'kit'] +['(m', 'atch'] +['ne', 'h'] +['ĠAssoci', 'ated'] +['ĠT', 'odo'] +['=', 'd'] +['C', 'am'] +['Ġv', 'ocal'] +['Ġs', 'udo'] +['(', 'EX'] +['Ġtr', 'ou'] +['AB', 'C'] +['.b', 'ean'] +['ĠG', 'round'] +['ĠRE', 'ST'] +['we', 'ets'] +['In', 'g'] +['im', 'on'] +['_b', 'us'] +['ĠC', 'OLOR'] +['un', 'to'] +['Ġf', 'oss'] +['ĠLink', 's'] +['ä', 'ng'] +['/', 'forms'] +['pr', 'ises'] +['Ġachie', 'vement'] +['C', 'ALL'] +['ел', 'ÑĮ'] +['ĠVer', 'ify'] +['_S', 'OURCE'] +['apt', 'cha'] +['ID', 'D'] +['_re', 'ference'] +['G', 'old'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĊ'] +['Re', 'ceiver'] +['Ġa', 'j'] +['_d', 'irection'] +['}', ']'] +['ĠCom', 'pet'] +['Ġb', 'ang'] +['ĠC', 'ass'] +['-', 'url'] +['te', 'chn'] +['ĠJer', 'usalem'] +['long', 'itude'] +["'", ');čĊčĊ'] +['Ġwin', 'ners'] +['T', 'asks'] +['ĠD', 'MA'] +['Ġtool', 'tip'] +['İ', '·'] +['ĠB', 'ra'] +['_d', 'uration'] +['cur', 'y'] +['parent', 's'] +['----', '', '>('] +['ĠK', 'ir'] +['Ġint', 'ros'] +['Ġsk', 'etch'] +['Ġsk', 'illed'] +['Ġim', 'mer'] +['Ġade', 'quate'] +['_re', 'p'] +['(', 'header'] +['_', 'like'] +['Ġper', 'ceived'] +['ss', 'h'] +['Ġassum', 'ing'] +['Ġf', 'f'] +['_u', 'uid'] +['ul', 'as'] +['Ġdemocr', 'atic'] +['.', 'entities'] +['S', 'eries'] +['aph', 'ore'] +['Ġnew', 'er'] +['}', '('] +['SE', 'C'] +['ai', 'ro'] +['Ġcomm', 'od'] +['Ġprivile', 'ge'] +['Ġde', 'ux'] +['ĠH', 'op'] +[".'", '/'] +['ct', 'ic'] +['.', "';Ċ"] +['', 'C'] +['ĠWar', 'ren'] +['Ġoptim', 'izer'] +['ĠSER', 'VICES'] +['_', 'oper'] +['get', 'Attribute'] +['ĠMc', 'K'] +['_s', 'elf'] +['.r', 's'] +['"', ')ĊĊĊ'] +['Get', 'Component'] +['er', 'ce'] +['Ġt', 'ous'] +['un', 'its'] +["']", ');čĊ'] +['Z', 'oom'] +['/', 'E'] +['Ġobs', 'c'] +['Ġfast', 'est'] +['on', 'line'] +['Ġpeace', 'ful'] +['ff', 'en'] +['Ġc', 'argo'] +['ĉ', 'pr'] +['Ġseek', 's'] +['z', 'u'] +['Tr', 'im'] +['Ġw', 'ard'] +['Ġver', 'd'] +['Ġblog', 's'] +['.exception', 's'] +['ĠPrem', 'ium'] +['ĠN', 'etherlands'] +['S', 'afe'] +['Fin', 'ish'] +['ĠAl', 'bum'] +['_A', 'CC'] +['=', 'this'] +['v', 'irtual'] +[']', '>'] +['_L', 'ABEL'] +['ĠN', 'ich'] +['_w', 'in'] +['ĠA', 'aron'] +['W', 'P'] +[';', '$'] +['aim', 's'] +['ĠImage', 'View'] +['Ġend', 'less'] +['ER', 'A'] +['_DIS', 'ABLE'] +['Ġcancel', 'led'] +['-', 'us'] +['Ġins', 'pection'] +['em', 'in'] +['ĠG', 'rey'] +['-', 'open'] +['Ġiter', 'ations'] +['.', 'owner'] +['Ġk', 'eras'] +['.P', 'assword'] +['ĠR', 'y'] +['ĠIN', 'S'] +['A', 'ir'] +['ĠSe', 'veral'] +['.Tab', 'Stop'] +['ING', 'LE'] +['ĠH', 'air'] +['ĠCan', 'vas'] +['AA', 'AA'] +['Ġfl', 'aw'] +['ced', 'es'] +['.Re', 'port'] +['í', 'Ĭ'] +['ĠT', 'ips'] +['cript', 'ors'] +['.trans', 'action'] +['.S', 'pring'] +['Ġview', 'er'] +['Ġins', 'ights'] +['è¾', 'ĵ'] +['ord', 'ion'] +['U', 'INT'] +['se', 'ek'] +['ĠA', 'uf'] +['ìŀ', 'IJ'] +['Ġstr', 'ain'] +['To', 'oltip'] +['Ġd', 'z'] +['ign', 'al'] +['ad', 't'] +['Ġu', 'c'] +['fin', 'ite'] +['Ġn', 'm'] +['.c', 'md'] +['ĠMy', 'Sql'] +['[', 'data'] +['.j', 'ackson'] +['.t', 'ree'] +['Request', 'Param'] +['_', 'agent'] +['")', ']čĊ'] +['Ġass', 'ass'] +['(', 'Constants'] +[':', 'ss'] +['ĠM', 'AN'] +['+-', '+-'] +['ĠB', 'ottom'] +['print', 's'] +['ĠS', 'ame'] +['@', 'Autowired'] +['sw', 'ap'] +['ici', 'ón'] +['Ġprotest', 'ers'] +['Ġh', 'oney'] +['ĠV', 'eter'] +['(C', 'alendar'] +['-', 'ad'] +['ĠBrook', 'lyn'] +['L', 'ife'] +['_V', 'AR'] +['ze', 'ch'] +['ĠC', 'ALL'] +['_C', 'AST'] +['ĠE', 'lection'] +['Ġthick', 'ness'] +['V', 'ery'] +['_IN', 'TEGER'] +['-', 'dev'] +['))', '))'] +['ap', 'at'] +['oo', 'oo'] +['d', 'emo'] +['Ġparse', 'Float'] +['ĠR', 'ather'] +['ST', 'IT'] +['m', 'aker'] +['[', 'current'] +['chron', 'o'] +['Ġch', 'rist'] +['ãģ', 'ª'] +['ĠD', 'etail'] +['ư', 'á»'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġs', 'ul'] +['id', 'ency'] +['Q', 'ue'] +['Ġeleg', 'ant'] +['ap', 'ons'] +['Ġdish', 'es'] +['Ġinteg', 'ers'] +['(', 'read'] +['find', 'ViewById'] +['ĠAm', 'ount'] +['ĠSk', 'ip'] +['Ġhab', 'its'] +['*', ')('] +['Ġmon', 'sters'] +['M', 'AC'] +[':', 'end'] +['Ġfr', 'ank'] +['As', 'sembly'] +['Ġd', 'fs'] +['Ġne', 'ut'] +['_TYP', 'ES'] +['e', 'qual'] +['loy', 'd'] +['(', 'uri'] +['Ġch', 'i'] +['Ġdefend', 'ant'] +['Ġconflic', 'ts'] +['Ġv', 'il'] +['-', 'js'] +['ĠPe', 'ace'] +['Ġmut', 'able'] +[')', 'sender'] +['ĠF', 'ocus'] +['å»', 'º'] +['Ġapprec', 'iated'] +['s', 'leep'] +['ĠR', 'ED'] +['C', 'ulture'] +['Ġdesign', 'ers'] +['_g', 'enerator'] +['c', 'odes'] +['/', 'ex'] +['.Get', 'Value'] +['umb', 'led'] +['.scal', 'ajs'] +['per', 'or'] +['Ġveter', 'ans'] +['Ġ}', ')čĊ'] +['Ġun', 'fortunately'] +['_C', 'REATE'] +['M', 'ass'] +['ĠCL', 'AIM'] +['ĠMe', 'et'] +['_s', 'upport'] +['B', 'ank'] +['()', '.Ċ'] +['D', 'ark'] +['_LO', 'W'] +['ĠMin', 'ing'] +['ĠO', 'wner'] +['ier', 'a'] +['Client', 'e'] +['Ġencour', 'aging'] +['>', 'S'] +['Ġboy', 'friend'] +['ĠH', 'alf'] +['ĠA', 'CC'] +['A', 'ff'] +['_', 'ar'] +['-l', 'ife'] +['c', 'x'] +['.J', 'Button'] +['iz', 'ado'] +['.z', 'ero'] +['.open', 'qa'] +['ot', 'on'] +['.text', 'Content'] +['Ġto', 'll'] +['at', 'ie'] +['Ġball', 'ot'] +['-', 'number'] +['.', 'Exception'] +['ĉ', 'params'] +['c', 'ircle'] +['-m', 'ap'] +['Ġn', 'ap'] +['ĠRob', 'ot'] +['ĠI', 'ch'] +['reg', 'istration'] +['Am', 'azon'] +['roll', 'ment'] +['(', 'exp'] +['Ġt', 'anks'] +['ĠG', 'ordon'] +['Ġmach', 'inery'] +['Ġbas', 'eline'] +['æ', 'ĭ'] +['Ø', '©'] +['ĠCon', 'vention'] +['ĉ', 'config'] +['ook', 'ies'] +['m', 'ult'] +['Rec', 'ords'] +['ĠE', 'ST'] +['Ġgar', 'bage'] +['Ġcon', 'form'] +['id', 'al'] +['Ġb', 'arg'] +['Ġsurv', 'ived'] +['Ġinvestig', 'ations'] +['.contains', 'Key'] +['----------------------------------------------------------------', '----------Ċ'] +['ort', 'ion'] +['Ġhor', 'r'] +['_', 'http'] +['Ġm', 'ant'] +[']', ';čĊčĊ'] +['b', 'inary'] +['em', 'pl'] +['Ġin', 'quiry'] +['ĠMean', 'while'] +['Ġcollect', 'ing'] +['.Entity', 'Framework'] +['",', 'ĊĊ'] +['ĠP', 'ic'] +['@', 'Inject'] +['ick', 'ness'] +['ĠB', 'inding'] +['Ġcont', 'rolling'] +['re', 'verse'] +['Ġch', 'airs'] +['semb', 'led'] +['(', 'add'] +['Dis', 'abled'] +['an', 'as'] +['.trans', 'late'] +['--------', '---Ċ'] +['Ġref', 'lected'] +['"]', 'ĊĊ'] +['Ex', 'ternal'] +['Ar', 'row'] +['Single', 'ton'] +['%', 'x'] +['Ġ', 'Å'] +['Ġan', 'cest'] +['ĠOr', 'leans'] +['ĉc', 'md'] +['Ġprohib', 'ited'] +['ith', 'metic'] +['(ch', 'annel'] +['_c', 'ss'] +['For', 'ward'] +['.s', 'ocket'] +['Ġl', 'uc'] +['â', 'Ĩ'] +['ĠFire', 'fox'] +['ĠM', 'ovies'] +[')', '_'] +['.', 'ends'] +['(', 'shape'] +['Ġde', 'alt'] +['Ġs', 'aves'] +['Ġgl', 'ory'] +['Ġmej', 'or'] +['Ġbreath', 'ing'] +['Ġ', 'eller'] +['get', 'Data'] +['Ġang', 'les'] +['Ġtool', 'bar'] +['Ġsp', 'acing'] +['IP', 'S'] +['Ġflo', 'ors'] +['_ACT', 'IVE'] +['Ġsh', 'uffle'] +['/', 'shared'] +['ĠE', 'le'] +['ed', 'ish'] +['Ġweb', 'cam'] +['.ex', 'pect'] +['il', 'oc'] +['ĠIn', 'cludes'] +['Ġtweet', 'ed'] +['Ġ:', ')'] +['ĠEss', 'ay'] +['F', 'ix'] +['-b', 'etween'] +['_', 'web'] +['.con', 'v'] +['Ġrac', 'ism'] +['Ġreflect', 's'] +['um', 'm'] +['иÑĤ', 'е'] +['_f', 'ooter'] +['/d', 'ocs'] +['ĠP', 'our'] +['Ng', 'Module'] +['.initial', 'ize'] +['pattern', 's'] +['_', 'In'] +['ĠAb', 'b'] +['*', 'čĊ'] +['Ġsent', 'iment'] +['b', 'uff'] +['_count', 's'] +['Ġre', 'use'] +['ch', 'unk'] +['Ġim', 'posed'] +['Primary', 'Key'] +['Fore', 'ground'] +['Ġconsum', 'ed'] +['?', '!'] +['Ġd', 'ick'] +['Ġch', 'ron'] +['ĠF', 'ern'] +['Ġrespons', 'ive'] +['Ġin', 'sect'] +['icult', 'y'] +['Ġr', 'w'] +['Ġal', 'ike'] +['Ġsub', 'set'] +['ĠCook', 'ies'] +['ĠP', 'air'] +['Ġt', 'ier'] +['IF', 'O'] +['av', 'our'] +['ĠQ', 'U'] +[',', 'sizeof'] +['Ġmerg', 'ed'] +['m', 'v'] +['it', 'ol'] +['yl', 'on'] +['Ġjump', 'ed'] +['.', 'role'] +['ens', 'aje'] +['R', 'ules'] +['Ġb', 'rowse'] +['An', 'imator'] +['Ġy', 'oga'] +['Ġvari', 'ants'] +['Ġcour', 'tesy'] +['ur', 'an'] +['p', 'bs'] +['else', 'if'] +['Al', 't'] +['ĠL', 'ane'] +['CL', 'K'] +['IM', 'ARY'] +['_PRO', 'PERTY'] +['ï¼', 'IJ'] +['Ġch', 'an'] +['Ġgrad', 'ually'] +['Ġsh', 'ake'] +['Ġbl', 'onde'] +['...', '");Ċ'] +['-se', 'x'] +['Ġgame', 'play'] +['ac', 'ies'] +['.ref', 'resh'] +['US', 'B'] +['ĠPl', 'ot'] +['W', 'as'] +['iss', 'ippi'] +['ĠT', 'ensor'] +['Ġcryptoc', 'urrency'] +['Ġdifficult', 'ies'] +['De', 'leted'] +['With', 'out'] +['_', 'append'] +['_', 'ver'] +['"))', 'čĊ'] +['Ġhonest', 'ly'] +['Ġp', 'ivot'] +['Ġtem', 'ps'] +['_p', 's'] +['ĠUn', 'like'] +['[:', '-'] +['V', 'S'] +['_in', 'f'] +['Ġjun', 'ior'] +['Ġanim', 'ations'] +['Ġfile', 'path'] +['?', '{{', '$'] +['Ġun', 'icode'] +['pl', 'aces'] +['ĠC', 'offee'] +['.S', 'E'] +['ĠP', 'AR'] +['(t', 'xt'] +['ge', 'bra'] +['Ġf', 'ires'] +['Main', 'Window'] +['med', 'ium'] +['Ġ(', 'âĢľ'] +['Ġl', 'g'] +['Ġc', 'mp'] +['/', 'base'] +['_l', 'ayers'] +['_', 'entries'] +['Ġadmin', 'ister'] +['ĠSU', 'CH'] +['B', 'P'] +['ĠScott', 'ish'] +['ĉčĊ', 'ĉčĊ'] +['gu', 'ard'] +['ĠStr', 'ong'] +['In', 'sn'] +['ĠC', 'AP'] +['as', 'ury'] +['ĠSE', 'E'] +['C', 'lock'] +['er', 'ie'] +['\\', 'models'] +['Ġ$', '$'] +['ĠC', 'ab'] +['Ġwur', 'de'] +['Ġsold', 'ier'] +['Ġcl', 'ips'] +['Ġarrang', 'ement'] +['ĠW', 'onder'] +['ĠH', 'orn'] +['Ġsc', 'ared'] +['Ġc', 'ure'] +['m', 'kdir'] +['Ġal', 'igned'] +['ĠP', 'ink'] +['Ġland', 'ed'] +['Dim', 'ension'] +['Scroll', 'Pane'] +['.ch', 'at'] +['.W', 'ith'] +['ĠTr', 'ain'] +[']', '.Ċ'] +['Ġth', 'irty'] +['Ġdur', 'able'] +['Ġl', 'd'] +['Ġlate', 'init'] +['Ġch', 'arts'] +['Ġins', 'ult'] +['.F', 'atal'] +['_', 'ct'] +['Ġm', 'asks'] +['CLU', 'DED'] +['Pres', 'ident'] +['Ġcol', 'ours'] +['g', 'ments'] +['.at', 'tributes'] +['ĠF', 'lex'] +['ĠC', 'lock'] +['ÃŃ', 'cul'] +['im', 'en'] +['J', 'O'] +['ĠReg', 'ex'] +['_L', 'INK'] +['Ġc', 'ouch'] +['ĠIN', 'PUT'] +['Ġbe', 'ating'] +['b', 'usiness'] +['pre', 'ced'] +['.', 'unit'] +['ĠF', 'el'] +['N', 'ever'] +['osp', 'el'] +['.start', 'swith'] +['ĠE', 'PA'] +['.', 'only'] +['Ġprevent', 'ing'] +['y', 'er'] +['Column', 'Name'] +['Ġelev', 'ation'] +['fl', 'u'] +['icy', 'cle'] +['Ġoff', 'line'] +['Tool', 'bar'] +['Ġcompet', 'ing'] +[')', '].'] +['Ġm', 'og'] +['Ġis', 'Valid'] +['As', 'k'] +['_', 'av'] +['_l', 'at'] +['AN', 'C'] +['ĠJ', 'oh'] +['k', 'ers'] +['Ġgu', 'ards'] +['Ġch', 'ains'] +['ĠSimple', 'DateFormat'] +['.st', 'atic'] +['Ġvess', 'el'] +['Ġm', 'ud'] +['Ġst', 'abil'] +['Ġst', 'ret'] +['g', 'm'] +['am', 'ation'] +['ç', 'ľ'] +['-w', 'ith'] +['Ġro', 's'] +['_P', 'A'] +['Ġresult', 'ado'] +['Ġconf', 'idential'] +['ĠTok', 'yo'] +['ĉ', 'using'] +['ĠMath', 'f'] +['omb', 'ine'] +['ĠESP', 'N'] +['Ġdeal', 'ers'] +['Ġdismiss', 'ed'] +['TR', 'Y'] +['Ġte', 'ens'] +['rec', 'ords'] +['Ġw', 'ings'] +['g', 'allery'] +['account', 's'] +['_L', 'IB'] +['Ġj', 'acket'] +['ĠNS', 'Object'] +['Ġst', 'ones'] +['ĠDel', 'ivery'] +['ĠD', 'iet'] +['/w', 'atch'] +['Ġto', 'ilet'] +['ĠG', 'uest'] +['.d', 'ay'] +['Ġint', 'val'] +['Vis', 'it'] +['Ġinvestig', 'ated'] +['Ġpent', 'ru'] +['ĠThe', 'atre'] +['andid', 'ates'] +['L', 'ang'] +['ĠS', 'erv'] +['Ġcont', 'rollers'] +['Ġset', 'Title'] +['N', 'P'] +['am', 'y'] +['fl', 'at'] +['(', 'ui'] +['_d', 'ocument'] +['è', 'ĥ½'] +['ĠC', 'oin'] +['ĠAd', 'ams'] +['pt', 'ic'] +['Ġproduct', 'ive'] +['Ġaccompl', 'ished'] +['čĊčĊ', 'čĊčĊ'] +['Ġdefer', 'red'] +['ient', 'es'] +['Ġs', 'inc'] +['ol', 'ars'] +['Right', 'arrow'] +['Ġvari', 'ations'] +['(', 'offset'] +['.Layout', 'Inflater'] +['Ġsus', 'pend'] +['Ġprevent', 'ion'] +['_pr', 'ivate'] +['_', 'js'] +['âĺ', 'ħ'] +['Ġw', 'ieder'] +['at', 'um'] +['Ĵ', 'Į'] +['Ġappear', 'ances'] +['.D', 'ocument'] +['Ġvalid', 'ates'] +['cal', 'endar'] +['}', '";Ċ'] +['.d', 'emo'] +['con', 'ut'] +['Ġcorre', 'ction'] +['ĠDe', 'al'] +['Ġbatter', 'ies'] +['.d', 'uration'] +[',', '\\'] +['_m', 'arker'] +['m', 'ulti'] +['Ġh', 'alt'] +['Ġc', 'ms'] +['Ġsh', 'aped'] +['B', 'ro'] +['re', 'duce'] +['Ġ', '####'] +['CT', 'OR'] +['ĠBen', 'ef'] +['Ġicon', 'ic'] +['Ġp', 'iano'] +['Ġeffect', 'iveness'] +['|', '.Ċ'] +['Ġa', 'jax'] +['Ġv', 'olumes'] +['à¸', '¡'] +['Ġcl', 'js'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'Ċ'] +['ath', 's'] +['ra', 'its'] +['å¤', '§'] +['Ñ', 'ĸ'] +['_m', 'ult'] +['Ġfasc', 'inating'] +['A', 'verage'] +['Ġpr', 'é'] +['ĠChair', 'man'] +['.find', 'Element'] +['_p', 'in'] +['Ġcomp', 'aring'] +['Ġdark', 'ness'] +['-F', 'i'] +['-', 'server'] +['Ġselect', 'ing'] +['ster', 'dam'] +['ĠPart', 's'] +['FORM', 'ATION'] +['Ġnot', 'ing'] +['Ġp', 'ile'] +['og', 's'] +['Ġpa', 'lette'] +['_d', 'o'] +['it', 'ize'] +['()', '('] +['Ġdef', 'ining'] +['Ġremain', 'der'] +['Un', 'its'] +['_T', 'ASK'] +['Http', 'Client'] +['S', 'ocial'] +['Ġfund', 'ra'] +['N', 'R'] +['ch', 'est'] +['C', 'urrency'] +['.ad', 'apter'] +['Ġd', 'op'] +['un', 'ting'] +['ANG', 'UAGE'] +['"', 'He'] +['ĉ', 'index'] +['_p', 'ackage'] +['.I', 'con'] +['Ġrep', 'et'] +['m', 'ass'] +['="', '.$'] +['ĠS', 'ud'] +['Ġl', 'id'] +['pro', 'vince'] +['ì', 'ľ'] +['G', 'PIO'] +['Ð', 'ļ'] +['ĠMy', 'SQL'] +['Ġdoc', 's'] +['ĠG', 'A'] +['Ġip', 'sum'] +['K', 'ernel'] +['Ġaccept', 's'] +['Ġfit', 'ting'] +['Ġcu', 'ando'] +['Ġd', 'uplic'] +['ĠBro', 'ther'] +['ĠK', 'le'] +['num', 's'] +['Ġmor', 'ph'] +['Ġ', '########'] +['ĠCG', 'Point'] +['<', 'unsigned'] +['ä¾', 'ĭ'] +['ĠD', 'uke'] +['.set', 'Bounds'] +['q', 's'] +['or', 'ic'] +['j', 'er'] +['Ġregard', 'ed'] +['Http', 'Request'] +['Ġbond', 's'] +['Ġthorough', 'ly'] +['enc', 'ent'] +['Ġhighlight', 'ed'] +['Ġac', 'res'] +['Ġwork', 'place'] +['ĠL', 'ux'] +['Ġqu', 'ot'] +['.in', 'flate'] +['Ġdocument', 'ed'] +['Ġadd', 'iction'] +['Ġmut', 'ation'] +['.c', 'ity'] +['Ġbott', 'les'] +['ĠRepos', 'itory'] +['on', 'n'] +['err', 'no'] +['ARI', 'ABLE'] +['åº', '¦'] +['_B', 'EGIN'] +['gl', 'as'] +["'", '})Ċ'] +['ĠMass', 'age'] +['ĠWh', 'it'] +['reg', 'ex'] +['W', 'A'] +['Ġout', 'let'] +['-', 'head'] +['Ġexp', 'ired'] +['ĠTh', 'ai'] +['/', 'include'] +['grad', 'ient'] +['scan', 'f'] +['Ġse', 'am'] +['w', 'al'] +['ĉb', 'uf'] +['B', 'earer'] +['Ġprec', 'ious'] +['if', 'acts'] +['co', 'ord'] +['Ġexpl', 'oration'] +['.get', 'Y'] +['(h', 'andle'] +['Top', 'ic'] +['ĠV', 'ent'] +['r', 'hs'] +['----', '--Ċ'] +['ĠB', 'right'] +['Ġg', 'uild'] +['m', 'other'] +['st', 'orm'] +['Ġmunicip', 'al'] +['Ġin', 'k'] +['.T', 'YPE'] +['w', 'l'] +['...', '', '', 'manual'] +['ĠTechn', 'ical'] +['Ġcorpor', 'ation'] +['ĠH', 'W'] +['ank', 'a'] +['T', 'AIL'] +['ist', 'as'] +['Ġperform', 's'] +['ĠBeh', 'avior'] +['.F', 'or'] +['_', 'ORDER'] +['ĠK', 'ick'] +['Ġcallback', 's'] +['_d', 'r'] +['ue', 'go'] +['h', 'ub'] +['uff', 'icient'] +['sk', 'y'] +['Ġb', 'p'] +['ht', 'able'] +['ĠON', 'LY'] +['ĠAUTH', 'ORS'] +['.Arg', 'ument'] +['"', '};Ċ'] +['ĠTh', 'under'] +['ĠK', 'om'] +['.Sh', 'ould'] +['A', 'UTH'] +['ah', 'u'] +['_p', 'ayment'] +['Ġst', 'arter'] +['ìĦ', 'ľ'] +['ìļ', '©'] +['B', 'log'] +['.p', 'atch'] +['Ġgovern', 'ed'] +['ass', 'y'] +['-f', 'ound'] +['Ġthe', 'ater'] +['ĠFont', 'Weight'] +['ĠBat', 'man'] +['"', 'If'] +['.R', 'andom'] +['_d', 'elta'] +['ĠC', 'E'] +['Auth', 'enticated'] +['Ġdr', 'one'] +['Ġc', 'ous'] +['r', 'adius'] +['M', 'er'] +['(', 'None'] +['ĠN', 'J'] +['_', 'headers'] +['Ġam', 'er'] +['py', 'test'] +['ĠA', 'ctions'] +['ĉĉĉ', 'ĠĠĠĠ'] +['Ġet', 't'] +['Ġh', 'oly'] +['Ġun', 'comfort'] +['ĠN', 'in'] +['ĠDec', 'imal'] +['ĠM', 'essages'] +['.s', 'ender'] +[']', '])Ċ'] +['Ġembr', 'ace'] +['Th', 'ough'] +['/', 'sp'] +['Ġcult', 'ures'] +['Ġhigh', 'way'] +['t', 'ar'] +['.f', 'ail'] +['_h', 'idden'] +['ĠcomponentDid', 'Mount'] +['ĠW', 'right'] +['Ġj', 'ag'] +['_', 'il'] +['../../', '../'] +['ig', 'u'] +['F', 'ood'] +['Ġa', 'ce'] +['Ġa', 'ños'] +['US', 'D'] +['Ġmut', 'ual'] +['Log', 'ic'] +['Ġtem', 'ple'] +['Ġbrief', 'ly'] +['ĠT', 'rip'] +['class', 'method'] +['default', 's'] +['Ġch', 'unks'] +[',,', ',,'] +['ĠRe', 'ason'] +['$', 'id'] +['-up', 's'] +['Ġdam', 'n'] +['Ġtruck', 's'] +['Ġun', 'limited'] +['Ġsc', 'ulpt'] +['ĠC', 'ards'] +['Ġaut', 'or'] +['ĠTest', 'ing'] +['Ġdies', 'e'] +['sh', 'ops'] +['ç', '´'] +['(p', 'ayload'] +['ĠP', 'ATH'] +['ĠMem', 'orial'] +['Ġridic', 'ulous'] +['eg', 'ree'] +['-w', 'inning'] +['Ġre', 'hab'] +['Ġsophistic', 'ated'] +['wp', 'db'] +['ĉ', 'path'] +['!', '";Ċ'] +['_S', 'YS'] +['.s', 'peed'] +['Ġso', 'ap'] +['s', 'uffix'] +['W', 'rap'] +['Ġenh', 'ancement'] +['Ã', 'ī'] +['ú', 'b'] +['Ġplay', 'list'] +['Ġmix', 'ing'] +['ant', 'idad'] +['="', '";Ċ'] +['ĠRev', 'ision'] +['ĠBe', 'at'] +['.in', 'c'] +['-w', 'ay'] +['enc', 'ias'] +['ul', 'ers'] +['C', 'at'] +['id', 'el'] +['ĠSh', 'ip'] +['.set', 'Color'] +['Ġthreat', 'ening'] +['.mod', 'ules'] +['Ġafter', 'wards'] +['ĠD', 'ashboard'] +['Ċ', 'ĠĊ'] +['Sign', 'al'] +['Ġpr', 'imer'] +['orne', 'ys'] +['ici', 'ary'] +['Ġl', 'igne'] +['_p', 'redict'] +['Ġa', 'est'] +['_', 'https'] +['>', ':'] +['ĠL', 'ex'] +['Ġrencont', 'res'] +['eg', 'ral'] +['sc', 'ala'] +['_f', 'amily'] +['ÃŁ', 'en'] +['_s', 'ym'] +['Ġuncert', 'ainty'] +['ĠVAL', 'UE'] +['Ġ}', ';čĊčĊ'] +['Ġbro', 'ader'] +['Ġh', 'orses'] +['ãģ', 'Ŀ'] +['ĠK', 'al'] +['ob', 'a'] +['_IN', 'ET'] +['ĠK', 'ill'] +['j', 'query'] +['am', 'ination'] +['[', '@"'] +['Ġm', 'uj'] +['##', '#Ċ'] +['First', 'OrDefault'] +['then', 'Return'] +['C', 'he'] +['/', 'footer'] +['Ġpark', 's'] +['as', 'je'] +['ĠG', 'ulf'] +['Ġmod', 'est'] +['.', 'Init'] +['ï¼Ł', 'ĊĊ'] +['Ġpros', 'pects'] +['Ġs', 'vg'] +['Ġå', 'ı'] +['.D', 'ialog'] +['_N', 'ET'] +['Ġ(', '($'] +['Ġe', 'k'] +['ĠW', 'arning'] +['ĠM', 'K'] +['<', 'LM'] +["Ġ'", 'čĊ'] +['i', 'em'] +['h', 'etic'] +['Ġi', 'x'] +['th', 'ink'] +['-sh', 'adow'] +['ĠE', 'ld'] +['ĠNev', 'ada'] +['ĠLe', 'af'] +['ĠG', 'ROUP'] +['Ġprom', 'o'] +['ent', 'ine'] +['ĉ', 'Map'] +['ĠModel', 's'] +['ĠK', 'rist'] +['_k', 'ernel'] +['-m', 'ade'] +['Ġc', 'err'] +['As', 'sets'] +['ell', 'ar'] +['Ġinv', 'oked'] +['.v', 'ue'] +['Ġcult', 'iv'] +['C', 'losed'] +['Ġgener', 'ates'] +['ffff', 'ff'] +['thes', 'ize'] +['s', 'qrt'] +['ĠCast', 'le'] +['.c', 'ar'] +['Ġke', 'en'] +['und', 'a'] +['ĠC', 'row'] +['ĠSing', 'h'] +['y', 'thon'] +['Ġbe', 'ans'] +['l', 'arg'] +['æĸĩ', 'ä»¶'] +['Aw', 'esome'] +['unc', 'ate'] +['Path', 's'] +['o', 'ji'] +['(c', 'urr'] +['CON', 'DS'] +['Ġm', 'im'] +['Ġshould', 'ers'] +['H', 'ard'] +['ast', 'es'] +['а', 'еÑĤ'] +['Ġconv', 'ince'] +['de', 'cess'] +['m', 'ade'] +['ĠC', 'MD'] +['.', 'Im'] +['Ġcha', 'os'] +['ens', 'ively'] +['Ġcool', 'ing'] +['Ġbur', 'ied'] +["('", '@'] +['_S', 'e'] +['ĉĉĉĉĉĉĉĉ', 'ĉĉĉĉĉĉĉĉ'] +['.com', 'pany'] +['.sub', 'mit'] +['ph', 'ant'] +['Ġboot', 'strap'] +['_h', 'elp'] +['à', '§'] +['.d', 'ump'] +['Ġdif', 'er'] +['_m', 'apping'] +['Ġcirc', 'ular'] +['Ġescort', 's'] +['Ġb', 'ere'] +['Ġgrad', 'u'] +['ĠLeg', 'end'] +['im', 'edia'] +['ĠBar', 'celona'] +['Ġbed', 's'] +['åĪ', '°'] +['ãĢ', 'Ĭ'] +['_v', 'olume'] +['Ġtremend', 'ous'] +['Ġsc', 'aling'] +['Ġp', 'ins'] +['en', 'as'] +['type', 'param'] +['D', 'ashboard'] +['render', 'er'] +['Ġsp', 'i'] +['Ġ&', '$'] +['ĠSk', 'in'] +['alm', 'art'] +['Ġh', 'ockey'] +['Ġ\'"', '.$'] +['Ġerr', 'no'] +['Ġb', 'ew'] +['Follow', 'ing'] +['.M', 'odule'] +['er', 'able'] +['ĠM', 'ilitary'] +['ĠR', 'io'] +['_', 'available'] +['ĠSur', 'face'] +['Ġst', 'ab'] +['IF', 'IER'] +['ĠL', 'IST'] +['Ġd', 'ashboard'] +['Ġcl', 'usters'] +['.pl', 'ugin'] +['Ġj', 'ou'] +['ĠDec', 'or'] +['F', 'our'] +['Ġdel', 'le'] +['******', '/Ċ'] +['ia', 'z'] +['in', 'de'] +['ch', 'ing'] +['Ġget', 'Item'] +['.Add', 'ress'] +['ment', 'ed'] +['A', 'meric'] +['Pl', 'ain'] +['Ġus', 'b'] +['ĠPract', 'ice'] +['_', 'ment'] +['.bl', 'ue'] +['H', 'int'] +['ÑĢаÐ', '²'] +['Ġconn', 'ector'] +['Ġinher', 'ited'] +['и', 'в'] +['Ġinterval', 's'] +['Ġc', 'ere'] +['Ġu', 'd'] +['Ġin', 'con'] +['.Ex', 'ists'] +['ĠM', 'ic'] +['F', 'K'] +['(c', 'ard'] +['.Set', 'tings'] +['Ġexhib', 'ition'] +['Ġon', 'Pressed'] +['Ġrest', 'ored'] +['eng', 'u'] +['.', 'def'] +['Ġrec', 'v'] +['."', ');čĊ'] +['enc', 'oder'] +['ather', 'ine'] +['(', 'dest'] +['az', 'ed'] +['#', 'endregion'] +['sem', 'bl'] +[',', 'M'] +['ob', 'y'] +['Ġп', 'еÑĢ'] +['.C', 'all'] +['Ġattend', 'ance'] +['-b', 'order'] +['Ġaddress', 'ing'] +['ê', 'n'] +['ĠLe', 'v'] +['Ġb', 'ash'] +['ben', 'ch'] +['C', 'redentials'] +['Sp', 'acing'] +['(', 'of'] +['_RE', 'SET'] +['ig', 'uous'] +['Ġcr', 'uel'] +['Ġcross', 'ed'] +['Ġle', 'ur'] +['ĠG', 'olf'] +['or', 'rect'] +['Ġpack', 'ets'] +['ĠData', 'Set'] +['Ġpart', 'ly'] +['SEQU', 'ENTIAL'] +['Ġindic', 'ation'] +['ĠS', 'alt'] +['ac', 'ia'] +['Ġ*', ');Ċ'] +['ĉ', 'info'] +['ĠView', 'Bag'] +['on', 'z'] +['Ġeditor', 'ial'] +['ĠA', 'rena'] +['Ġs', 'ir'] +['_', 'Static'] +['(', 'socket'] +['s', 'u'] +['cho', 'ose'] +['.m', 'onth'] +['.M', 'y'] +['é', 'ri'] +[';', 'font'] +['do', 'es'] +['Ġcon', 'verter'] +['Ġsal', 'v'] +['Ġl', 'r'] +['Ġinflu', 'enced'] +['(f', 'eature'] +['ĠQue', 'ens'] +['let', 't'] +['_M', 'ON'] +['&', 'amp'] +['Touch', 'ableOpacity'] +['O', 'FF'] +['Ġmetab', 'ol'] +['(', 'iter'] +['Ġvit', 'amin'] +['ĠIND', 'IRECT'] +['aut', 'om'] +['_p', 'ublic'] +['Ġadjust', 'ment'] +['Ġspecial', 'ized'] +['w', 'indows'] +['.add', 'All'] +['Ġaccording', 'ly'] +['ĠJ', 'OptionPane'] +['Ġcell', 'spacing'] +['Ġqu', 'ad'] +['Ġcre', 'ep'] +['Ġout', 'lets'] +['}`', ')Ċ'] +['Ġpri', 'est'] +['_TH', 'READ'] +['ĠMar', 'x'] +['ĠBy', 'Val'] +['Ġc', 'ual'] +['éĿ', '¢'] +['Ġtempor', 'arily'] +['An', 'n'] +['ke', 'leton'] +['å', '¥'] +['ĠLO', 'C'] +['au', 'er'] +['der', 'ive'] +['Ġbeh', 'aviors'] +['as', 'ename'] +['ĠCent', 'ury'] +['Ġhor', 'rible'] +['ME', 'SS'] +['_', 'List'] +['we', 'i'] +['P', 'at'] +['ĠCh', 'oice'] +['_F', 'ROM'] +['ĉ', 'line'] +['.in', 'voke'] +['.B', 'ottom'] +['Ġnow', 'here'] +['."', 'ĊĊĊĊ'] +['_', 'export'] +['Ġstrugg', 'led'] +['.Ap', 'pearance'] +['ĠJ', 'Button'] +['ĠJer', 'emy'] +['([', '['] +['Ġkick', 'ed'] +['mar', 'shal'] +['st', 'aff'] +['es', 'ity'] +['Ġqu', 'iz'] +['_e', 'ffect'] +['Ġ}', '));ĊĊ'] +['m', 'el'] +['b', 'anner'] +['ĠP', 'IN'] +['Ġin', 'vention'] +['Ġcons', 'olid'] +['Ġop', 's'] +['ĠB', 'etween'] +['j', 'ack'] +['ern', 'ational'] +['Ġsacr', 'ifice'] +['ag', 'ation'] +['ĠJ', 'oy'] +['Ġam', 'endment'] +['ĠS', 'old'] +['Ġprison', 'ers'] +['ан', 'нÑĭ'] +['Doc', 'uments'] +[')', '])Ċ'] +['ust', 'ed'] +['ĠLine', 'arLayout'] +['os', 'o'] +['_E', 'M'] +['.s', 'elf'] +['.M', 'iddle'] +[')', '//'] +['Ġ\\', "'"] +['Ġfuck', 'ed'] +['ĠM', 'urray'] +['Ġprof', 'ound'] +['_E', 'LEMENT'] +['ult', 'a'] +['il', 'ers'] +['port', 'folio'] +['J', 'une'] +['t', 'cp'] +['mod', 'ified'] +['ĠTr', 'ace'] +['ĠK', 'el'] +['aly', 'zer'] +[')', '=>'] +['ĠRep', 'air'] +['_B', 'E'] +['Br', 'and'] +['u', 'art'] +['pre', 'view'] +['Ġiniti', 'atives'] +['run', 'ning'] +['b', 'ang'] +['ĉ', 'update'] +['ĠCo', 'ach'] +['R', 'ich'] +['Ġy', 'outube'] +['Ġrit', 'ual'] +['app', 'a'] +['ĠRobin', 'son'] +['prec', 'ision'] +['////////////////////////////////////////////////////////////////', '////////////'] +['=[', ']Ċ'] +['Ġcelebr', 'ated'] +['OT', 'O'] +['Ġin', 'clusion'] +['J', 'P'] +["'", ';čĊčĊ'] +['Ġnot', 'able'] +['(_', '.'] +['Man', 'aged'] +['Ġgu', 'ides'] +['&', 'nbsp'] +['ated', 'Route'] +['ĠAd', 'just'] +['Ġcol', 'ored'] +['_s', 'cores'] +['ĠTes', 'la'] +['_pro', 'gress'] +['.in', 'st'] +["['", '_'] +['.fl', 'ags'] +['Ġf', 'close'] +['_O', 'PER'] +['ż', 'y'] +['_n', 'ote'] +['Ġtrans', 'gender'] +['å', 'ķ'] +['RI', 'PT'] +['Ġabs', 'ent'] +['Ġam', 'et'] +['Ġoper', 'and'] +['ë', '©'] +['Ġh', 'ood'] +['to', 'LowerCase'] +['av', 'o'] +['ĠCirc', 'uit'] +['ĠL', 'ind'] +['--', '}}Ċ'] +['=', 'm'] +['Ġsup', 'press'] +['ĠM', 'AP'] +['i', 'ang'] +['-', 'admin'] +['Ġside', 'bar'] +['ĠB', 'u'] +['ĠH', 'ex'] +[',', 'F'] +['ĠSign', 'al'] +['Ġtrans', 'parency'] +['ĠFeder', 'ation'] +['/', 'V'] +['Re', 'q'] +['Ġpul', 'se'] +['Ġt', 'ends'] +['Num', 'bers'] +['%', "'"] +['Ġde', 'port'] +['dat', 'as'] +['_U', 'INT'] +['_', 'tra'] +['ok', 'o'] +['Ġ"', '?'] +['comp', 'et'] +['sole', 'te'] +['und', 'ry'] +['Ġover', 'lap'] +['}`', ',Ċ'] +['.', 'ly'] +['_sum', 'mary'] +['ĠL', 'ost'] +['.C', 'enter'] +['Ġdis', 'ability'] +['.Serial', 'ization'] +['Ġge', 'om'] +['Ġ?', ':'] +['ĠW', 'o'] +['Ġsh', 'ipped'] +['Ĥ', 'æķ°'] +['Ġu', 'gly'] +['Ġexcit', 'ement'] +['Ġext', 'erior'] +['Ġcheck', 'out'] +['Ġk', 'ur'] +[',', 'D'] +['ĠAl', 'aska'] +['Ġsyn', 'thetic'] +['ĠB', 'udget'] +['ĠSub', 'scribe'] +['Ġ&', 'Ċ'] +['ÈĻ', 'i'] +['ĠY', 'u'] +['ĉ', 'query'] +['}', '.Ċ'] +['Ġtr', 'aged'] +['ass', 'en'] +['Ġaccommod', 'ation'] +['Ġphys', 'ician'] +['Ġren', 'amed'] +['Ġtid', 'ak'] +['z', 'Äħ'] +['Ġmin', 'us'] +['ny', 'ch'] +['_EX', 'CEPTION'] +['thread', 's'] +['Ġt', 'ire'] +['_c', 'reated'] +['ens', 'ure'] +['Ġworth', 'y'] +['Ġexc', 'use'] +['Ġclo', 'th'] +['.parent', 'Node'] +['/pl', 'atform'] +['ĠU', 'FC'] +['ĠG', 'tk'] +['un', 'ny'] +['Ġg', 'ibt'] +['ke', 'ley'] +['h', 'um'] +['(t', 'x'] +['ĉ', 'dev'] +['Ġout', 'fit'] +['do', 'ors'] +['Ġf', 'on'] +['ic', 'ut'] +['vol', 'atile'] +['Ġhom', 'osex'] +['Max', 'imum'] +['Ġexp', 'end'] +['Ġ});ĊĊ', 'Ċ'] +['E', 'q'] +['ond', 'ers'] +['dep', 'artment'] +['ĠPhys', 'ics'] +['"', '});Ċ'] +['Ġpar', 'ad'] +['.S', 'tr'] +['Ġse', 'le'] +['IF', 'IED'] +['Ġdel', 'ivers'] +['iv', 'an'] +['Ġrespons', 'ibilities'] +['Ġadvoc', 'ates'] +['è', 'µ'] +['ĠR', 'ID'] +['.param', 'eters'] +['M', 'etrics'] +['ron', 'ics'] +['ĠUITableView', 'Cell'] +['A', 'bsolute'] +['ip', 'se'] +['yl', 'um'] +['MLE', 'lement'] +['_VAL', 'ID'] +['<', 'title'] +['D', 'lg'] +['p', 'aces'] +['Ġsynd', 'rome'] +['be', 'ans'] +['_d', 'atabase'] +['oz', 'illa'] +['ĠM', 'eg'] +['DB', 'G'] +['Ġl', 'ub'] +['Bag', 'Constraints'] +['ab', 'ad'] +['Ġproject', 'ed'] +['_BY', 'TE'] +['.Size', 'F'] +['st', 'reet'] +['ĊĊĊĊ', 'ĊĊĊĊĊĊ'] +['ĠLO', 'SS'] +['Ġdirect', 'ors'] +['/', 'news'] +['Ġnurs', 'ing'] +['ĠD', 'one'] +['.', 'HTTP'] +['dis', 'count'] +['ĠR', 'ot'] +['To', 'Many'] +['Ġen', 'abling'] +['Ġauss', 'i'] +['ost', 'a'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'čĊ'] +['è½', '½'] +['Ġhel', 'icopt'] +['ĠIn', 'side'] +['ä¿¡', 'æģ¯'] +['is', 'per'] +['ĠAll', 'ah'] +['ARCH', 'AR'] +['Ġroll', 's'] +['Com', 'pare'] +['X', 'P'] +['Index', 'Of'] +['S', 'UM'] +['Ġass', 'ured'] +['ĠPhys', 'ical'] +['End', 'point'] +['.G', 'lobal'] +['.d', 'etail'] +['Ġthe', 'ft'] +['.j', 'upiter'] +['Ġhum', 'or'] +['.R', 'ender'] +['A', 'lex'] +['.c', 'ap'] +['Ġbuff', 'ers'] +['Ġdis', 'pose'] +['t', 'ion'] +['.p', 'resent'] +['z', 'el'] +[',', 'P'] +['Ġdesper', 'ate'] +['.get', 'Column'] +['Ġtw', 'in'] +['ì', 'ĸ'] +['.c', 'an'] +['Ġf', 'lee'] +['ĠIran', 'ian'] +['Ġstick', 'y'] +['ĠU', 'TC'] +['L', 'T'] +['////////////////////////////////', '////////////////'] +['Ġl', 'icensing'] +['_PO', 'INT'] +['ĠM', 'aps'] +['Ġl', 'ol'] +['=', 'models'] +['-t', 'ab'] +['ĠN', 'ash'] +['_log', 'ger'] +['tor', 'ch'] +['ĠCON', 'SEQUENTIAL'] +['Not', 'Empty'] +['/', 'react'] +['Ġp', 'f'] +['Ġassert', 'ion'] +['Ġsubsequ', 'ently'] +['_c', 'an'] +['Ġpand', 'emic'] +['og', 'ue'] +['"+', 'Ċ'] +['_', 'ent'] +['_P', 'aram'] +['.ĊĊ', 'ĊĊĊĊĊĊ'] +['Res', 'earch'] +['C', 'apture'] +['Ġbel', 'oved'] +['d', 'em'] +['Ġextract', 'ed'] +['Ġf', 'ights'] +['ER', 'C'] +['(a', 'uth'] +['position', 's'] +['Ġrevers', 'ed'] +['(st', 'ack'] +['Ġ_', ')'] +['uto', 'ff'] +['_fl', 'ow'] +['ç', 'Ĥ¹'] +['(', 'Game'] +['Ġex', 'cluded'] +['ĠCS', 'V'] +['c', 'g'] +['ĠT', 'itan'] +['p', 'ause'] +['Ġcer', 'ca'] +['Ġdump', 'ster'] +['L', 'ess'] +['Ġkotlin', 'x'] +['aster', 'xml'] +['Ġpoint', 'ers'] +['Ġfl', 'ows'] +['ĠT', 'un'] +['ĠMain', 'Activity'] +['Ġdis', 'cret'] +['Ġcomb', 'inations'] +['vis', 'it'] +['_b', 'ind'] +['oot', 'ing'] +['d', 'ater'] +['_look', 'up'] +['.n', 'io'] +['Ġswe', 'at'] +['ĠR', 'd'] +['Ġscient', 'ist'] +['ĠP', 'ixel'] +['@', 'NgModule'] +['Play', 'ing'] +['Ġunf', 'old'] +['Trans', 'late'] +['ĠLaw', 'rence'] +['ĠFIX', 'ME'] +['B', 'ill'] +['ĠR', 'IGHT'] +['Ġwhere', 'ver'] +['Ġo', 'ok'] +['vid', 'ence'] +['Ġ]', '];'] +['ĠSk', 'ill'] +['unist', 'd'] +['ĠðŁ', 'ĻĤ'] +['Ġfem', 'ales'] +['--', ')Ċ'] +['İ·', 'åıĸ'] +['ĠF', 'red'] +['Over', 'all'] +['Ù', 'Ĥ'] +['Ġess', 'ence'] +['Ġthere', 'by'] +['Ġw', 'ounded'] +['ĠD', 'OWN'] +['les', 'son'] +['text', 'ure'] +['R', 'ound'] +['Ġautom', 'ated'] +['ĠÐ', '¡'] +['ĠUp', 'dates'] +['Ġsh', 'ade'] +['p', 'ublish'] +['ĠG', 'ear'] +['=', 'lambda'] +['Ġle', 'ver'] +[')', '+"'] +['h', 'ill'] +['Ġrad', 'ar'] +['ry', 'ing'] +['Ġ"', ').'] +['f', 'illed'] +['Ġline', 'up'] +['Ġd', 'l'] +['Ġworks', 'pace'] +['V', 'o'] +['_d', 't'] +['ë', '²'] +['_', 'Item'] +['NS', 'URL'] +['.', 'verify'] +['ĠHawai', 'i'] +['G', 'od'] +['M', 'arch'] +['Ġ[â̦', ']'] +['Ġpel', 'o'] +['ur', 'ious'] +['ĠPitt', 'sburgh'] +['.', 'It'] +['C', 'lean'] +['>', '\\<^'] +['Ġi', 'os'] +['s', 'ound'] +['"]', ';'] +['Ġfre', 'ed'] +['rot', 'tle'] +['ĠL', 'ower'] +['[', 'count'] +['å', 'Ŀ'] +['Ġp', 'ale'] +['ĠWay', 'ne'] +['ear', 'th'] +['_c', 'ategories'] +['U', 'CK'] +['.m', 'etadata'] +['Ġsum', 'mon'] +['H', 'OME'] +['олÑĮ', 'з'] +['Ġmanufact', 'ured'] +['Ġdo', 'ck'] +['Ġcompet', 'itors'] +['_MODE', 'L'] +['ok', 'ia'] +['ĠH', 'ey'] +['Î', '¿'] +['Ġback', 'ward'] +['ĠPO', 'SS'] +['rop', 'a'] +['Ġc', 'ri'] +['_O', 'BJ'] +['Trans', 'port'] +['-h', 'igh'] +['Ġerot', 'ik'] +['_s', 'lot'] +['Ġart', 'ic'] +['_f', 'ramework'] +['-ser', 'if'] +['ĠSql', 'DbType'] +["')", '('] +['+', '"/'] +['Ġw', 'ore'] +['S', 'il'] +['Ġst', 'oring'] +['ĠPh', 'ase'] +['u', 'ant'] +['Ġb', 'ump'] +['in', 'ho'] +['Ġd', 'ign'] +['Ġback', 's'] +['q', 'q'] +['(h', 'ash'] +['Ġge', 'o'] +['Ġt', 'ender'] +['Log', 'o'] +['!', ')Ċ'] +['ĠM', 'X'] +['ĠAr', 'thur'] +['esso', 'a'] +['_C', 'h'] +['Ġbed', 'rooms'] +['="#', '"><'] +['Ġth', 'roat'] +['ins', 'ic'] +['.int', 'eger'] +['Ġpr', 'imitive'] +['Truth', 'y'] +['Ġfacilit', 'ate'] +['Ġcreat', 'ivity'] +['ĠD', 'NS'] +['Ġg', 'ra'] +['ue', 'z'] +['Ġcount', 'less'] +['ĠPol', 'and'] +["'", 'M'] +['ĠD', 'ist'] +['Ġv', 'est'] +['Ġcert', 'ification'] +['á»', 'ij'] +['h', 'eld'] +['ext', 'ensions'] +['(', 'static'] +['Ġgr', 'ades'] +['ĠU', 'ber'] +['ãģ', 'Ł'] +['Ġ[', '])Ċ'] +['dat', 'os'] +['Ġget', 'Data'] +['ĠCh', 'arg'] +['ĠB', 'S'] +['.m', 'icrosoft'] +['.v', 'ideo'] +['.d', 'irection'] +['->{', "'"] +['l', 'ua'] +['ape', 'st'] +['Ġbo', 'iler'] +['ere', 'k'] +['Ġdec', 'ides'] +['.j', 'ar'] +['IS', 'C'] +['ĠW', 'ords'] +['(C', 'ON'] +['EMPL', 'ATE'] +['ree', 'ze'] +['sh', 'ots'] +['app', 's'] +['unt', 'ed'] +['.set', 'Name'] +['::', '<'] +['-b', 'old'] +['ê', '²'] +['å¯', 'Ĩ'] +['Long', 'rightarrow'] +['Ġunf', 'air'] +['Ġear', 'ning'] +['Ġsh', 'elf'] +['URE', 'MENT'] +['Ġid', 'le'] +['_M', 'ENU'] +['.C', 'ustom'] +['AG', 'ER'] +['-', '"'] +['_s', 'witch'] +['b', 'ecause'] +[')', 'view'] +['m', 'are'] +['_', 'condition'] +['ĠStart', 'ing'] +['M', 'vc'] +['(p', 're'] +['d', 'ump'] +['_LO', 'CK'] +['at', 'etime'] +['.c', 'allback'] +['ĠC', 'er'] +['op', 'ol'] +['ib', 'rary'] +['Ġres', 'ervation'] +['ĉĉĉĉĉĉĉ', 'Ċ'] +['lect', 'or'] +['grad', 'uate'] +['Ġgener', 'ous'] +['Ġ', 'ion'] +['ric', 'ao'] +['m', 'q'] +['_com', 'plete'] +['(c', 'ursor'] +['ĠForm', 'Control'] +[':', 'center'] +['Ġsub', 'stitute'] +['ĠPl', 'anning'] +['Ġp', 'ension'] +['Ġrecommend', 'ation'] +['ĠT', 'ags'] +['Ġg', 'ef'] +['Ġalbum', 's'] +['Ġwash', 'ing'] +['ro', 'c'] +['Ġtr', 'ains'] +['at', 'ings'] +['Ġex', 'ponent'] +['ack', 'bar'] +['-', 'ln'] +['á', 'g'] +['.Data', 'Annotations'] +['ĠE', 'IF'] +['ĠMalays', 'ia'] +['ĉ', 'PORT'] +['on', 'us'] +['Ġcle', 'ver'] +['Ġpe', 'u'] +['>', 'ĊĊĊĊ'] +['ĠArg', 'uments'] +['Ġdebug', 'ging'] +['(', 'right'] +["'", 'D'] +['com', 'pute'] +['Ġfin', 'est'] +['OR', 'AGE'] +['Ġspect', 'acular'] +['ph', 'rase'] +['Ġind', 'ia'] +['Ġlegend', 'ary'] +['b', 'irth'] +['Ġcom', 'posite'] +['Ġg', 'rows'] +['ĠT', 'D'] +['Ġep', 'id'] +['Ġlaunch', 'ing'] +[']', ']['] +['Min', 'utes'] +['ĠCh', 'a'] +['Ġclean', 'ed'] +['Ġwitness', 'es'] +['uk', 'an'] +['ĉ', 'Type'] +['Ġhab', 'e'] +['par', 'agraph'] +['ĠJ', 'Panel'] +['ĠH', 'ann'] +['Ġvar', 'ied'] +['ĠP', 'okemon'] +['ĠM', 'UST'] +['åĬ', '¨'] +['.vis', 'ibility'] +['op', 'up'] +['^', '['] +['.exp', 'and'] +['Ġ"', "',"] +['.f', 'asterxml'] +['_', 'auto'] +['ĠShe', 'et'] +['mark', 'er'] +['Par', 'cel'] +['ew', 's'] +['ĠStr', 'ategy'] +['-m', 'aking'] +['Ġun', 've'] +['Ġtrail', 'ing'] +['Ġclick', 's'] +['ĠGet', 'Component'] +['ĉ', 'content'] +['IG', 'ENCE'] +['ERN', 'EL'] +['NSMutable', 'Array'] +['Ġb', 'reat'] +['Ġharm', 'ful'] +['¶', 'Ī'] +['Ġbes', 'ides'] +['Ġb', 'oring'] +['Ġbrut', 'al'] +['v', 'ang'] +['(p', 'arse'] +['qu', 'ick'] +['Ġpy', 'test'] +['Ġswitch', 'ing'] +['()', ']Ċ'] +['Ġì', 'Ħ'] +['L', 'ER'] +['ĉf', 'ont'] +['Ġnet', 't'] +[')', ']ĊĊ'] +['(/', '\\'] +['æŀ', 'ľ'] +['to', 'Array'] +['Ġbre', 'ed'] +['ĠC', 'AR'] +['ĠWe', 'apon'] +['A', 'bs'] +['t', 'ot'] +['Ġset', 'Name'] +['apt', 'ive'] +['Ġ:', ','] +['Ġesc', 'aped'] +['ord', 'en'] +['ĠP', 'ri'] +['th', 'umbnail'] +['Ġdescri', 'ptions'] +['/', 'styles'] +['ĠPC', 'I'] +['Ġal', 'phabet'] +['astic', 'search'] +['NOT', 'E'] +['Ġc', 'ialis'] +['ĠGr', 'iff'] +['Ġpor', 'que'] +['Ġprote', 'ins'] +['pl', 'ays'] +['Ġst', 'ating'] +['Ġimag', 'ination'] +['Ġfac', 'ial'] +['ĠMe', 'chan'] +['Ġarr', 'anged'] +['_', 'used'] +['Ġarrang', 'ements'] +['ĠP', 'ipe'] +['host', 'name'] +['Ġprov', 'inc'] +['T', 'it'] +['.Flat', 'Style'] +['ĠS', 'plit'] +['ĠLo', 'ader'] +['.c', 'c'] +['Ġclin', 'ic'] +['----------------', '------------'] +['Ġb', 'aking'] +['ĠEN', 'T'] +['ne', 'ath'] +['ãĢģ', 'ĊĊ'] +['AN', 'E'] +['.EntityFramework', 'Core'] +['app', 'ers'] +['.', 'ic'] +['ĠNg', 'Module'] +['ĠF', 'ORM'] +["Ġ'", ';'] +['-pro', 'fit'] +['h', 'w'] +['en', 'emy'] +['ĠE', 'ye'] +['Ġca', 'ution'] +['t', 'own'] +['Ġur', 'ged'] +['ĠJim', 'my'] +['ynchron', 'ous'] +['-s', 'ized'] +['m', 'aking'] +[',', '{'] +[']', "',"] +['_', 'Object'] +['ah', 'oma'] +['Ġactiv', 'ist'] +['IN', 'VAL'] +['ĠCom', 'mercial'] +['ĠOr', 'lando'] +['(t', 'ab'] +['ĠØ', '¨'] +['Al', 'gorithm'] +['Ġher', 'itage'] +['Get', 'Mapping'] +['Ġfail', 'ures'] +['ri', 'os'] +['at', 'iva'] +['Ġt', 'et'] +['Ġcar', 'pet'] +['(', 'Z'] +['th', 'ree'] +['Ġdisc', 'losure'] +['.', 'ERROR'] +['_c', 'alled'] +['Ġd', 'ial'] +['Ġoccas', 'ional'] +['.E', 'rr'] +['Ġfunc', 'ion'] +['caff', 'old'] +['Ġrele', 'asing'] +['ï¼ī', 'ĊĊ'] +['_', 'Value'] +['ĠV', 'ari'] +['y', 'ellow'] +['Ġstrugg', 'les'] +['.c', 'al'] +['ĠDak', 'ota'] +['ĉc', 'lose'] +['Ġsand', 'wich'] +['Ġanaly', 'tics'] +['Ġ**', ')'] +['&', '#'] +['ĠJ', 'os'] +['Ġpass', 'ive'] +['AT', 'TR'] +['Th', 'rowable'] +['ĠM', 'un'] +['ĠU', 'int'] +['(dis', 'posing'] +['ar', 'ak'] +['ĠLe', 'aders'] +['Ġaffect', 'ing'] +['Ġitem', 'View'] +['Ġeconom', 'ics'] +['f', 'v'] +['à¹', 'Ģ'] +['.r', 'b'] +['ĠOver', 'all'] +['Ġwealth', 'y'] +['Ġev', 'olved'] +['nd', 'a'] +['ĠH', 'us'] +['re', 'strict'] +['um', 'en'] +['ĠA', 'gricult'] +['!', 'ĊĊĊ'] +['Ġexp', 'ires'] +['Ġspokes', 'person'] +['int', 'erval'] +['ĠÃ', '¢'] +['Ġque', 'en'] +['(n', 'il'] +['ing', 'o'] +['He', 'ap'] +['Ù', 'İ'] +['Ġcompl', 'ain'] +['S', 'ym'] +['ĠCl', 'one'] +['ĠR', 'u'] +['ĠW', 'ILL'] +['ĠCr', 'ystal'] +['/', 'content'] +['ing', 'en'] +['oint', 'ment'] +['Last', 'Name'] +['av', 'icon'] +['ĠIB', 'M'] +['ĠDim', 'ension'] +['an', 'h'] +['icip', 'ants'] +['ĠAn', 'ne'] +['.pro', 'gress'] +['Ġal', 'go'] +['ob', 'il'] +['ĠV', 'oice'] +['ĠF', 'E'] +['Ġg', 'li'] +['Ġv', 'ed'] +['Ġprevent', 's'] +['\\', 'Column'] +['Ġfol', 'k'] +['ett', 'i'] +['Ġm', 'n'] +['ĠCL', 'ASS'] +['Ġdisplay', 'ing'] +['ĠK', 'l'] +['ĠF', 'err'] +['d', 'uto'] +['.', 'ib'] +['Ġd', 'ados'] +["'", 'name'] +['-s', 'pace'] +['Ġit', 'alian'] +['Ġin', 'verse'] +['Ġd', 'ense'] +['ut', 'er'] +['ĠI', 'Enumerator'] +['-s', 'ign'] +['Ġnation', 'wide'] +['Ġperson', 'a'] +['Ġsol', 'ved'] +['Ġdram', 'atically'] +['Log', 'out'] +['Ġgr', 'av'] +['Ġanalys', 'es'] +['ol', 'lo'] +['Ġl', 'amp'] +['.', 'team'] +['ĠE', 'rot'] +['=', '["'] +['Ġd', 'ancing'] +['Ġ?>', '/'] +['Ġc', 'ater'] +['ff', 'e'] +['ĠSh', 'a'] +['ĠB', 'os'] +['ĠRE', 'QUIRE'] +['ĠMon', 'ster'] +['ĠR', 'B'] +['ĠI', 'DE'] +['Ġsu', 'its'] +['Ġform', 'Data'] +['(', 'theta'] +['Ġsp', 'atial'] +['=', 'NULL'] +['ĠSql', 'Connection'] +['Ġ', 'à'] +['ĠV', 'enez'] +['ĠMor', 'ning'] +['Ġpublic', 'ations'] +['ĠNON', 'INFRINGEMENT'] +['first', 'Name'] +['ud', 's'] +['W', 'ould'] +['_HE', 'AD'] +['Ġinvest', 'ed'] +['st', 'able'] +['f', 'red'] +['Ġcommand', 'er'] +['SE', 'S'] +['âĢĶ', 'a'] +['an', 'che'] +['ĠM', 'ovement'] +['ë', '³'] +['S', 'uite'] +['Ġjur', 'isdiction'] +['ë¦', '¬'] +['ĠB', 'eth'] +['j', 'Query'] +['ĠIs', 'a'] +['Ġd', 'ental'] +[',', '*'] +['ĠL', 'imit'] +['ili', 'ation'] +['="', '{'] +['b', 'ast'] +['Ġt', 'urb'] +['is', 'y'] +['O', 'OK'] +['Ġadvoc', 'ate'] +['im', 'ag'] +['LE', 'CTION'] +['л', 'ÑĮ'] +['(c', 'ategory'] +['.de', 'c'] +['Ġun', 'iqu'] +['_s', 'n'] +['Ġattract', 'ed'] +['ĠÃ', 'ī'] +['ĠRun', 'ning'] +['_', 'edges'] +['ĠDis', 'able'] +['_A', 'S'] +['åĽ', '¾'] +['Ġnetwork', 'ing'] +['_br', 'anch'] +['H', 'aving'] +['toBe', 'Truthy'] +['G', 'I'] +['Ġcamp', 's'] +['se', 'p'] +['-p', 'art'] +['Ġ)ĊĊ', 'ĊĊĊĊĊĊ'] +['ustral', 'ia'] +['ĠRe', 'ports'] +['rit', 'o'] +['Ġwa', 'ist'] +['_pl', 'us'] +['ĠW', 'W'] +['-p', 'erson'] +['Apr', 'il'] +['Ġs', 'ar'] +['.t', 'ar'] +['Ġagricult', 'ural'] +['t', 'ic'] +['Ġt', 'cp'] +['Ġset', 'Value'] +['agent', 'o'] +['ĠAp', 'pe'] +['p', 'iler'] +['CA', 'DE'] +['Ġan', 'che'] +['atch', 'er'] +['Ġcom', 'ics'] +['Ġl', 'bs'] +['_se', 'gment'] +["']", '=$'] +['itt', 'ers'] +['ich', 'er'] +['G', 'INE'] +['Ġutil', 'ize'] +['ĠC', 'ursor'] +['_ex', 'pression'] +['Ġd', 'ag'] +['<', 'long'] +['Ġr', 'hyth'] +['æı', 'IJ'] +['Ġconsult', 'ation'] +['Y', 'et'] +['"))', 'ĊĊ'] +['_M', 'AC'] +['c', 'ould'] +["Ġ'", '\\\\'] +['ĠV', 'o'] +['ĉ', 'http'] +['Ġg', 's'] +['ph', 'er'] +['-', 'grid'] +['J', 'ames'] +['J', 'ul'] +['Ġsch', 'on'] +['Ġtensor', 'flow'] +['ĠLOG', 'GER'] +['am', 'as'] +['Ġsc', 'ipy'] +['Ġconv', 'iction'] +['.', 'ag'] +['Ġadministr', 'ator'] +['))', '{čĊ'] +['Ġn', 'un'] +['"', 'group'] +['P', 'or'] +['Ġnur', 'se'] +['ex', 'pression'] +['ak', 'y'] +['ĠHe', 'avy'] +['.', 'opt'] +['.get', 'All'] +['Ġover', 'l'] +['/', '",'] +['_c', 'ountry'] +['ç', 'İ'] +['ĠG', 'ENER'] +['_r', 'oute'] +['ĠD', 'al'] +['Â', '´'] +['ol', 'oad'] +['Ġuncomfort', 'able'] +['(m', 'enu'] +['Ġhost', 'name'] +["'", '");Ċ'] +['Ġcalcul', 'ations'] +['-c', 'lick'] +['Ġprotect', 'ive'] +['ãĤ', '¯'] +['_F', 'orm'] +['ung', 's'] +['Act', 'ual'] +['m', 'f'] +['ĠProcess', 'ing'] +['ĠIn', 'ventory'] +['(m', 'atrix'] +['app', 'ropriate'] +['w', 'eg'] +['ij', 'a'] +['Ġch', 'r'] +['Ġr', 'ifle'] +['-w', 'sj'] +['k', 'ar'] +['Ġindepend', 'ently'] +['I', 'OS'] +['Ġconsist', 'ency'] +['v', 'n'] +['/s', 'ystem'] +['ĠCh', 'anges'] +['Ġexp', 'ose'] +['ici', 'ents'] +['Ġrel', 'ate'] +['ĉ', 'next'] +['è', '¨'] +['ud', 'es'] +['Ġglass', 'es'] +['F', 'XML'] +['....', '..'] +['ĠP', 'df'] +['Ġappro', 've'] +['Ġ{', '\\'] +['Ġexist', 'e'] +['))', '('] +['ARE', 'NT'] +['оÐ', '¿'] +['ĠL', 'atest'] +['ĠNiger', 'ia'] +['.Inter', 'faces'] +['Ġrem', 'oves'] +['En', 'emy'] +['Ġen', 'force'] +['vert', 's'] +['ĉ', 'pos'] +['_text', 'ure'] +['W', 'ARD'] +['ĠINC', 'IDENT'] +['(', 'container'] +['Ġdef', 'ending'] +['ĠR', 'X'] +['ĠH', 'ook'] +['br', 'is'] +['ĠFl', 'ask'] +['Gr', 'ay'] +['.', ')Ċ'] +['vis', 'ibility'] +['ĠRedirectTo', 'Action'] +['err', 'al'] +['_e', 'lem'] +['Ġres', 'on'] +['front', 'end'] +['_variable', 's'] +['ater', 'ia'] +['Ġ+', '"'] +['ave', 'led'] +['RI', 'X'] +['Ġdef', 'icit'] +['_C', 'heck'] +['YY', 'YY'] +['To', 'One'] +['sp', 'y'] +['Ġun', 'ited'] +['end', 'ent'] +['Ġp', 'ode'] +['ãģ', 'Į'] +['C', 'AT'] +['(f', 'mt'] +['ĠBon', 'us'] +['Ġre', 'ck'] +['Â', 'º'] +['Mod', 'ules'] +['Ġvac', 'uum'] +['R', 'adio'] +['ĠDAM', 'AGE'] +['P', 'en'] +['ĠPark', 'er'] +[';', ';Ċ'] +['ĠRe', 'ally'] +['_n', 'eg'] +['p', 'ending'] +['Ġnomine', 'e'] +['ĠC', 'ategories'] +['ĠUl', 'tra'] +['We', 'apon'] +['Ġdef', 'ender'] +['I', 'ss'] +['ĠG', 'ender'] +['ĠD', 'ress'] +['Ġimpr', 'ison'] +['Ġbank', 'rupt'] +['imension', 'al'] +['PH', 'A'] +['ĠStr', 'ateg'] +['ĠPROF', 'ITS'] +['Ġp', 'atri'] +['////////////////////////////////////////////////////////////////', '////////////////'] +['de', 'legate'] +['Ġfor', 'State'] +['Ġdev', 'oted'] +['_m', 'ake'] +['Ġterror', 'ists'] +['ĠS', 'nap'] +['_n', 'av'] +['ĠA', 'A'] +['ĠI', 'an'] +['ĉ', 'app'] +['Pl', 'acement'] +['_h', 'dr'] +['<', 'K'] +['Ġs', 'ang'] +['st', 'roke'] +['-', 'Q'] +['>', 'x'] +['.T', 'ask'] +['m', 'oney'] +['ib', 'aba'] +["'", '});Ċ'] +['ĠSpec', 'ific'] +['ĠLine', 'ar'] +['_O', 'PT'] +['Hash', 'Code'] +['(', 'Player'] +['.Contains', 'Key'] +['Ġcoll', 'apsed'] +['trans', 'parent'] +['_R', 'ANGE'] +['View', 'er'] +['(c', 'fg'] +['Ġsort', 'ing'] +['Ġinf', 'ected'] +['ĠN', 'ach'] +['Ġaccommod', 'ate'] +['.element', 's'] +['_P', 'ART'] +['ĠSex', 'y'] +['=', 'get'] +['(', 'year'] +['Ġx', 'hr'] +[':', ']'] +['ows', 'ki'] +['Ġsum', 'mar'] +['ĠÂ', '¿'] +['Ġint', 'e'] +['Ġwork', 'flow'] +['ĠTai', 'wan'] +['vers', 'ions'] +['åı', 'ij'] +['Ġsurprising', 'ly'] +['Ġopt', 'ical'] +['Ġpro', 'ces'] +['Ġdisag', 'ree'] +['Ġnue', 'vo'] +['ĠC', 'AM'] +['sort', 'ed'] +['le', 'ases'] +['ist', 'le'] +['Id', 'ent'] +['ĉ', 'event'] +['ject', 'ed'] +['Ch', 'unk'] +['V', 'ars'] +['.pro', 'vider'] +['Ġproceed', 'ings'] +['Ġin', 'clusive'] +['Ġart', 'work'] +['end', 'ants'] +['ï¼ļ', 'Ċ'] +['se', 'en'] +['Ġl', 'ig'] +['Ġm', 'akers'] +['_f', 'un'] +['Ġlength', 's'] +['Path', 'Variable'] +['[', 'item'] +['à¸', 'µ'] +['De', 'ad'] +['FFFF', 'FF'] +['ĠUr', 'ban'] +['up', 'les'] +['ich', 'en'] +['(null', 'ptr'] +['.s', 'pec'] +[',', 'System'] +['UR', 'ATION'] +['(j', 'ob'] +['å¼', 'ı'] +['Ġtrack', 'er'] +['Å', 'Ļ'] +['ĠM', 'R'] +['ĠSQL', 'ite'] +['Ġd', 'to'] +['Ġ;', ';Ċ'] +['Ġm', 'int'] +['ĠInt', 'roduction'] +['ca', 'o'] +['Ġquestion', 'ed'] +['Ġf', 'itted'] +['rev', 'ision'] +['s', 'q'] +['Ġm', 'ig'] +['_un', 'its'] +['_', 'async'] +['Ġf', 'lick'] +['});ĊĊ', 'Ċ'] +['Ġnot', 're'] +['}`', ','] +['F', 'ilters'] +['Ġm', 'undo'] +['_d', 'ays'] +['Ġfr', 'm'] +['ut', 'c'] +['Ġval', 's'] +['ew', 'idth'] +['ĠGener', 'ator'] +['ĠArt', 'ist'] +['ĠID', 's'] +['ĠArt', 'icles'] +['re', 'ater'] +['ĠComponent', 'Fixture'] +['.', '='] +['Ġr', 'ou'] +['-', 'no'] +['.b', 'ukkit'] +['eg', 'g'] +['ĠD', 'iff'] +['atic', 's'] +['Ñĥ', 'Ñĩ'] +['âĢĶ', 'ĊĊ'] +['ĠChar', 'lotte'] +['by', 'e'] +['Ġ}', ');čĊčĊ'] +['ĠV', 'ik'] +['ĠB', 'row'] +['Ġl', 'v'] +['ĠG', 'ib'] +['-w', 'ing'] +['GL', 'IGENCE'] +['(I', 'l'] +['ĠEngine', 'er'] +['.W', 'ait'] +['ĠP', 'ictures'] +['Ġr', 'het'] +['Ġth', 'ermal'] +['Ġpr', 'aise'] +['<', '>();ĊĊ'] +['ĠSp', 'ider'] +['P', 'ause'] +['ĠB', 'aker'] +['Ġsl', 'ower'] +['Ġ}', ']Ċ'] +['_en', 'queue'] +['Ġdisappe', 'ared'] +['ĠT', 'icket'] +['IN', 'UX'] +['_LOC', 'AL'] +['аÑģ', 'Ñģ'] +['@Inject', 'able'] +['comm', 'unity'] +['Gesture', 'Recognizer'] +['åĽ', '½'] +['Ġsca', 'les'] +['Ġ-', '('] +['/', "'+"] +['ĠS', 'it'] +['Ġexecut', 'ives'] +['ard', 'ing'] +['Ġad', 'vers'] +['Ġback', 'wards'] +['ĉ', 'context'] +['ĠH', 'amp'] +['ĠP', 'F'] +['ĠDe', 'ck'] +['ĠCra', 'ig'] +['A', 'merican'] +['Ġb', 'ell'] +['Ġpro', 'l'] +['uf', 'en'] +['Ġr', 'ng'] +['ar', 'shal'] +['ĠSim', 'ply'] +['first', 'name'] +['sh', 'ore'] +['J', 'uly'] +['Ġmort', 'ality'] +['ĠâĨĴ', 'ĊĊ'] +['Help', 'ers'] +['Ġbench', 'mark'] +['em', 'ade'] +['Ġorganis', 'ations'] +['.g', 'son'] +['ĠText', 'Field'] +['Ġciv', 'ilians'] +['.Array', 's'] +['ĠMiss', 'issippi'] +['Ġinter', 'mediate'] +['get', 'User'] +['_cl', 'uster'] +['Rel', 'ative'] +['fore', 'ign'] +['.querySelector', 'All'] +['Fore', 'ignKey'] +['Ġreason', 'ably'] +['--------', '-Ċ'] +['C', 'ards'] +['ĠK', 'am'] +['ĠTh', 'or'] +['Ġroll', 'er'] +['-e', 'lement'] +['ĠC', 'urrency'] +['dd', 'ie'] +['ALL', 'Y'] +['ĠR', 'A'] +['Ġper', 'met'] +['aa', 'aa'] +['Ġhom', 'ework'] +['ĠV', 'it'] +['Ġm', 'old'] +['ĠF', 'er'] +['[', 'start'] +['Ġstatist', 'ical'] +['Ġsc', 'ary'] +['_H', 'OME'] +['.B', 'egin'] +['Con', 'struct'] +['ogen', 'ic'] +['ĠDEAL', 'INGS'] +['Ġtamb', 'ién'] +['ix', 'on'] +['.', 'ind'] +['ac', 're'] +['Ġtransform', 's'] +['ĠN', 'ap'] +['.B', 'lock'] +['uss', 'ia'] +['pir', 'ation'] +['ul', 'ent'] +['Ġce', 'il'] +['Cl', 'ause'] +['na', 'ire'] +['T', 'ES'] +['Ġne', 'at'] +['ST', 'D'] +['ĠReg', 'Exp'] +['per', 'form'] +[':', ')'] +['Ġun', 'ions'] +['Ġs', 'ublic'] +['Ġw', 'inds'] +['lo', 'ating'] +['g', 'lich'] +['Ġp', 'agination'] +['S', 'kill'] +['App', 'ly'] +['ĠOper', 'ator'] +['ist', 'ogram'] +['Ġqual', 'ities'] +['C', 'ross'] +['Ġde', 'com'] +['],', '"'] +['ĠJ', 'uan'] +['.mod', 'al'] +['.Ch', 'ild'] +['ĠRog', 'er'] +['STIT', 'UTE'] +[':CGRect', 'Make'] +['a', 'lette'] +['Ġst', 'a'] +['as', 'ide'] +['Ġbl', 'ur'] +['ĠW', 'a'] +['if', 'etime'] +['re', 'ed'] +['control', 's'] +['Ġb', 'ins'] +['Ġп', 'ол'] +['*/', ',Ċ'] +['U', 'IS'] +['ĠR', 'ou'] +['ĠDem', 'o'] +['-', 'awesome'] +['ĠCh', 'ain'] +['Ġh', 'asta'] +['ĠB', 'art'] +['.', 'KEY'] +['Ġvend', 'ors'] +['nof', 'ollow'] +['ĠD', 'est'] +['_b', 'uilder'] +['Ġarg', 'ues'] +['_', 'answer'] +['g', 'oto'] +['ĠRES', 'ULT'] +['ĠM', 'ON'] +['Ġp', 'oder'] +['o', 'ons'] +['_C', 'ASE'] +['Ġrep', 'lic'] +['Ġfin', 'ancing'] +['ĠD', 'ATE'] +['c', 'ern'] +['_tr', 'ack'] +['t', 'ies'] +['/', 'logo'] +['ĠNE', 'GLIGENCE'] +['get', 'Type'] +['>', 'T'] +['b', 'et'] +['g', 'irl'] +['ĠINCIDENT', 'AL'] +['-s', 'ite'] +['.tr', 'igger'] +['ĠL', 'isa'] +['_input', 's'] +['Ġrel', 'atives'] +['Logged', 'In'] +['Config', 'ure'] +['I', 'K'] +['.', 'accept'] +['Res', 'ume'] +['ĠD', 'raft'] +['Ġ*', '>('] +['ĠW', 'A'] +['ed', 'ian'] +['ern', 'ess'] +['ĠLayout', 'Inflater'] +['*/', 'čĊčĊ'] +['oth', 'y'] +['Ġoblig', 'ation'] +['Sub', 'scribe'] +['Ġth', 'umbnail'] +['ex', 'ist'] +['Ġins', 'isted'] +['ĠU', 'ICollectionView'] +['ĠAng', 'ular'] +['Ġtable', 'ts'] +['ĠImp', 'act'] +['ãĢį', 'ĊĊ'] +['ah', 'o'] +['Ġcharacter', 'istic'] +['g', 'd'] +['Ġ=', '================================================'] +['our', 't'] +['`', '.'] +['App', 'ro'] +['Co', 'ordinate'] +['Rem', 'ember'] +['Ġmar', 'ine'] +[']', "=='"] +['ĠAdmin', 'istrator'] +['.get', 'Default'] +['Ġforg', 'ot'] +['ĠStruct', 'ure'] +['V', 'ue'] +['ars', 'ing'] +['m', 'oment'] +['k', 'w'] +['_c', 'ursor'] +['Att', 'ack'] +['Ġath', 'letic'] +['Ġdiagn', 'osed'] +['Ġend', 'e'] +['åĪ', 'łéϤ'] +['H', 'ouse'] +['ĠP', 'ARAM'] +['Ġw', 'iki'] +['ĠO', 'pp'] +['Ġcons', 'ervation'] +['Ġs', 'nd'] +['_t', 'em'] +['sub', 'str'] +['ĠC', 'ape'] +['.s', 'im'] +['UT', 'ION'] +['an', 'an'] +['âĢĻ', 'un'] +['Ġg', 'y'] +['-', 'work'] +['Ġcomp', 'elling'] +["='", '#'] +['ĉs', 'ub'] +['Ġdirect', 'ories'] +['íĬ', '¸'] +['Ġtouch', 'es'] +['out', 'ines'] +['.C', 'ollection'] +['s', 'chedule'] +['.l', 'at'] +['ĠDo', 'ctrine'] +['CA', 'A'] +['ĠRe', 'fer'] +['Ġshift', 's'] +['Ġlik', 'elihood'] +['pre', 'ter'] +['ĠF', 'emale'] +['Ġinter', 'cept'] +['Ġl', 'ou'] +['çĻ', '»'] +['Ġr', 'ug'] +['ĠC', 'rown'] +['Ġ************************************************************************', '****'] +['-', 'product'] +['Ġprompt', 'ed'] +['ung', 'le'] +['d', 'ocker'] +['ĠT', 'u'] +['ĠUn', 'ique'] +['_', 'Error'] +['ul', 'os'] +['Ġâ', 'Ħ'] +['Ġ(', '`'] +['Get', 'ting'] +['_s', 'cal'] +['ĠEn', 'h'] +['ü', 't'] +['Ġsust', 'ained'] +['Ġp', 'atches'] +['Ġpros', 'per'] +['ĠG', 'aza'] +['_l', 'ight'] +['Ġin', 'cons'] +['--------', 'Ċ'] +['ĉĉ', 'ĠĠĠĠĠĠ'] +['S', 'F'] +['C', 'N'] +[':', '";Ċ'] +['ĠColl', 'ins'] +['(', '*)'] +['Ġcomp', 'ilation'] +["']", 'čĊ'] +['Ġcon', 'sequence'] +[',', '...'] +['Ġd', 'm'] +['ĠB', 'LOCK'] +['Cl', 'uster'] +['Ġsk', 'i'] +['(arg', 'c'] +['T', 'uple'] +['Ġjo', 'ins'] +['ĠSher', 'iff'] +['W', 'ar'] +['ind', 'i'] +['Ġcomment', 'ed'] +['H', 'OST'] +['Ġinv', 'itation'] +['apan', 'ese'] +['Ġperm', 'its'] +['preced', 'ented'] +['_z', 'one'] +['ĠA', 'my'] +['_R', 'D'] +['Min', 'imum'] +['Ġinv', 'ocation'] +['.en', 'able'] +['icht', 'en'] +['-', 'owned'] +['"', 'id'] +['_PO', 'INTER'] +['F', 'ac'] +['Ġspecific', 'ations'] +['Ġnom', 'ination'] +['Ġg', 'p'] +['<', '('] +['Ġrob', 'ots'] +['ĠJ', 'erry'] +['Ġhold', 'ers'] +['Ġw', 'and'] +['c', 'ms'] +['Ġ}', '))Ċ'] +['.To', 'ast'] +['ĠI', 'List'] +['B', 'ased'] +['z', 'oom'] +['/', 'style'] +['ĠBe', 'ck'] +['M', 'en'] +['Ġcontrib', 'uting'] +['Ġund', 'o'] +['ĠO', 'H'] +['Ġadd', 'Object'] +['Ġe', 'igen'] +['sign', 'up'] +['éĶ', 'Ļ'] +['Ġdist', 'ant'] +['PAR', 'ATOR'] +['ĠM', 'ari'] +['Ġm', 'á'] +['E', 'mp'] +['ó', 's'] +['Ġì', 'Īĺ'] +['ev', 't'] +['+', 'j'] +['p', 'ark'] +['ĠSt', 'ay'] +['ĠD', 'un'] +['Ġso', 'y'] +['>', '%'] +['az', 'ines'] +['Ġti', 'empo'] +['(m', 'e'] +['p', 'resent'] +['.Th', 'is'] +['Ġedit', 'ors'] +['F', 'IELD'] +['.W', 'ork'] +['ĠUn', 'iverse'] +['Ġdr', 'unk'] +['.t', 'imer'] +['Ġalter', 'ed'] +['ĠN', 'ar'] +['ëł', '¥'] +['.Act', 'ive'] +['id', 'or'] +['ç', 'Ń'] +['.delta', 'Time'] +['Ġawk', 'ward'] +['&', 'quot'] +['ĠSaf', 'ari'] +['Ġtr', 'icks'] +['MENT', 'S'] +['div', 'ision'] +['Ġvary', 'ing'] +['ĠHigh', 'way'] +['Ġphotograph', 'er'] +['ĠSt', 'ewart'] +['Ġlast', 'ing'] +['.P', 're'] +['.amazon', 'aws'] +['ĠL', 'uck'] +['.D', 'escription'] +['ĠN', 'az'] +['n', 'eg'] +['Ġc', 'ó'] +['<<"', '\\'] +['ĠSur', 'v'] +['ĠU', 'nc'] +['Rec', 'ipe'] +['.Border', 'Style'] +['Ġmod', 'ifications'] +['-', 'at'] +['AT', 'FORM'] +['h', 'dr'] +['ak', 'o'] +['Ġsublic', 'ense'] +['ĠJ', 'ump'] +['Ġbe', 'im'] +['ĠMan', 'hattan'] +['.', 'bool'] +['_h', 'w'] +['ÑĤ', 'ÑĮ'] +['B', 'in'] +['Ġg', 'ateway'] +['"', '":'] +['ĠU', 'IS'] +[':"', '+'] +['-', 'def'] +['ĠReg', 'ular'] +['/', 'testing'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['string', 'stream'] +['Ġdis', 'par'] +['Ġmob', 'il'] +['-', 'read'] +['ĠAd', 'apter'] +['ĠCh', 'ampions'] +['Ġsched', 'uler'] +['Ġk', 'ills'] +['ĠM', 'ultiple'] +['ir', 'ror'] +['Ġgod', 's'] +['AD', 'O'] +['ak', 'te'] +['ĠUs', 'uario'] +['.c', 'ircular'] +['Ġre', 'cept'] +['ĠEx', 'pr'] +['Ġelder', 'ly'] +['Ġnic', 'ely'] +['Ġbest', 'e'] +['W', 'ant'] +['Ġclass', 'ical'] +['.s', 'prite'] +['obj', 'c'] +['ĠM', 'ason'] +['Ġsist', 'ema'] +['.Bl', 'ack'] +['es', 'o'] +['ĠZe', 'it'] +['Ġdiv', 'id'] +['Ġent', 'ers'] +['_sub', 'ject'] +['ĠPlan', 'et'] +['.w', 'arning'] +['ĠG', 'ram'] +['_t', 'okens'] +['Ġhousehold', 's'] +['_c', 'ustomer'] +['user', 'Name'] +['c', 'ross'] +['Ġp', 'ione'] +['Ġass', 'ists'] +['_S', 'M'] +['ib', 'o'] +['Ġlo', 'yal'] +['Ġuse', 'less'] +['#', 'elif'] +['ĠUlt', 'imate'] +['C', 'ome'] +['g', 'el'] +['Ġd', 'ich'] +['xy', 'z'] +['ik', 'el'] +['ob', 'ra'] +['_s', 'can'] +['ĠInter', 'ior'] +['ĠN', 'ice'] +['Ġpl', 'ac'] +['ĉt', 'arget'] +['Ġvir', 'al'] +['ass', 'o'] +['()', '/'] +['und', 'e'] +['ĠAd', 'obe'] +['O', 's'] +['vis', 'ited'] +['ĠO', 'W'] +['ĠFe', 'ed'] +['ĠSe', 'quence'] +['Ġman', 'ages'] +['in', 'son'] +['ĠLouis', 'iana'] +['{', '})'] +['ĠH', 'ab'] +['ĠL', 'D'] +['Ġb', 'ip'] +['pr', 'ites'] +['(e', 'lem'] +['.h', 'ibernate'] +['él', 'é'] +['Ġoh', 'ne'] +['_trans', 'action'] +['Ġann', 'unci'] +['P', 'ublished'] +['ĠH', 'onda'] +['ĠT', 'am'] +['ĠP', 'acket'] +['_', 'selector'] +['Ġchalleng', 'ed'] +['Process', 'ing'] +['-h', 'over'] +['Ġtr', 'ainer'] +['_c', 'ancel'] +['ĠNS', 'Dictionary'] +['ab', 'ric'] +['ĠM', 'LS'] +['_s', 'ensor'] +['Ġshr', 'ink'] +['ĠF', 'X'] +['th', 'reshold'] +['ĉH', 'X'] +['-m', 'ark'] +['`', '.`'] +['S', 'cheme'] +['(f', 'ull'] +['_w', 'riter'] +['ĠS', 'ys'] +['Ġf', 'led'] +['ĠC', 'in'] +['-w', 'idget'] +['ĠPre', 'vious'] +['G', 'ender'] +['_', 'question'] +['Fe', 'ed'] +['Ġscr', 'ut'] +['(p', 'refix'] +['ãĢĤ', 'ãĢĤ'] +['Ġin', 'fections'] +['Part', 's'] +['Ġhier', 'archy'] +['_DE', 'LETE'] +['ĠPat', 'ient'] +['_p', 'ay'] +['Ġprom', 'oted'] +['Ġì', 'ĭ'] +['Ġcivil', 'ian'] +['Ġagricult', 'ure'] +['ĠP', 'iece'] +['Ġst', 'ance'] +['uts', 'che'] +['Ass', 'ign'] +['.A', 'CTION'] +['F', 'ig'] +['_r', 'adius'] +['ĠS', 'ync'] +['du', 'cer'] +['f', 'ailure'] +['ens', 'ed'] +['pt', 'ime'] +['B', 'M'] +['_dat', 'etime'] +['qu', 'ivo'] +['QUE', 'UE'] +['èĢ', 'ħ'] +['Ap', 'pear'] +['Ġsum', 'mit'] +[':', 'void'] +['Ġv', 'ine'] +['è®', '¤'] +['on', 'ne'] +['_TR', 'ANS'] +['.g', 'reen'] +['_', 'cc'] +['Ġhung', 'ry'] +['Ġ"', '>'] +['()', ');čĊčĊ'] +['Ex', 'tract'] +['iz', 'ens'] +['Ġsol', 'ver'] +['Not', 'ify'] +['Ġeng', 'lish'] +['ĠSh', 'opping'] +['inter', 'faces'] +['RE', 'Q'] +['Ġil', 'leg'] +['ĠUI', 'ImageView'] +['Ġdis', 'connect'] +['ĠUnt', 'il'] +['ĠConserv', 'ative'] +['@', 'Column'] +['Ġshift', 'ed'] +['Ġ:', 'čĊ'] +['Ġf', 'ich'] +['Ġd', 'la'] +['Ġsh', 'oe'] +['"),', 'čĊ'] +['ular', 'ity'] +['_RE', 'SP'] +['We', 'ather'] +['UI', 'Application'] +['.', 'iterator'] +['Ġag', 'ing'] +['.P', 'arent'] +['ow', 'ie'] +['(e', 'qual'] +['ĠCon', 'v'] +['/', 'default'] +['Ġmeas', 'uring'] +['.pre', 'v'] +['.Is', 'Valid'] +['.F', 'at'] +['Ġs', 'Äĥ'] +['key', 'words'] +['with', 'out'] +['Ġso', 'vere'] +['Ġex', 'changes'] +['Ġm', 'elt'] +['Ġis', 'lands'] +['ĠInt', 'egr'] +['Ġjump', 'ing'] +['Ġg', 'le'] +['Ġjournal', 'ism'] +['Ġd', 'ated'] +['Local', 'ized'] +['ĠRef', 'resh'] +['Part', 'icle'] +['Ġa', 'a'] +['ĠSTR', 'ICT'] +['Ġb', 'od'] +['.Pro', 'cess'] +['_A', 'UTO'] +['ĠP', 'ublished'] +['e', 'very'] +['Ġtechn', 'ological'] +['ls', 'x'] +['Ġir', 'rit'] +['Add', 'itional'] +['Ġdel', 'imiter'] +['_l', 'anguage'] +['-', 'area'] +['bo', 'ys'] +['ĠT', 'ube'] +['Ġw', 'at'] +['Ġmechan', 'ics'] +['_', 'owner'] +['Sp', 'ell'] +['ĠSt', 'ories'] +['.Append', 'Line'] +['Table', 'View'] +['h', 'em'] +['st', 'ick'] +['oll', 'ower'] +['I', 'FF'] +['ĠU', 'V'] +['oll', 'ision'] +['S', 'UB'] +['Ġcompar', 'able'] +['Ġdon', 'de'] +['s', 'ales'] +['ll', 'vm'] +['Ġ}', '],Ċ'] +['OTT', 'OM'] +['ĠPur', 'pose'] +['L', 'ab'] +['Ġinterview', 'ed'] +['o', 'is'] +['as', 'il'] +['.set', 'Id'] +['ĠIn', 'struction'] +['--', '>'] +['ĠMod', 'ified'] +['ation', 'ally'] +['ĠMe', 'eting'] +['è¯', '¯'] +['#', 'region'] +['Ġrout', 'ing'] +['.f', 'ocus'] +['ĠYou', 'th'] +['<', 'D'] +['ĠN', 'ag'] +['contact', 's'] +['Ġform', 'ing'] +['Ġm', 'ie'] +["',['", '../'] +['ĠB', 'P'] +['Ġapp', 'et'] +['ĠTe', 'acher'] +['ĠT', 'P'] +['Ġann', 'ually'] +['outed', 'EventArgs'] +['ĠSpe', 'aker'] +['Ġre', 'name'] +['CF', 'G'] +['("', '//'] +['æİ', '¥'] +['/p', 'ages'] +['Ġpr', 'és'] +['ĠSp', 'ell'] +['.All', 'ow'] +['ĠINT', 'ERRU'] +['Ġ(', '#'] +['âĢĻ', 'ĊĊ'] +['_G', 'eneric'] +['.im', 'show'] +['_t', 'im'] +['-', 'face'] +['(&', '('] +['atin', 'um'] +['Ġrevolution', 'ary'] +['ĠH', 'ours'] +['r', 'ain'] +['Ġany', 'time'] +['Ġab', 'b'] +['.j', 'sp'] +['Scroll', 'View'] +['ĠTr', 'uth'] +['Ġanticip', 'ated'] +['Ġacc', 'ent'] +['.', 'checked'] +['Ġspec', 'ifies'] +['Ġca', 'f'] +['Ġcell', 'padding'] +['Ġcook', 'ed'] +['ĠH', 'ugh'] +['pe', 'ek'] +['_R', 'ATE'] +['Ġd', 'orm'] +['/', 'čĊ'] +['IV', 'ITY'] +['.Cont', 'roller'] +['(p', 'art'] +['.con', 'straint'] +['Ġinv', 'asion'] +['MO', 'VE'] +['Ġgl', 'uc'] +['l', 'ename'] +['Ġam', 'en'] +['eng', 'lish'] +['ĠSw', 'itzerland'] +['";ĊĊ', 'Ċ'] +['pe', 'st'] +['.col', 'lect'] +['N', 'ib'] +['ĠD', 'ict'] +['ĠE', 'mb'] +['(sub', 'ject'] +['Ġoutr', 'age'] +['Ġdec', 'iding'] +['Ġsent', 'enced'] +['F', 'echa'] +['"', 'A'] +['Ġqu', 'er'] +['Ġfont', 'Family'] +['Ġqu', 'adr'] +['-', 'Y'] +['_C', 'ACHE'] +['Ġanaly', 'zed'] +['Ġg', 'aining'] +['ĠAgain', 'st'] +['ĠSou', 'l'] +['ta', 'u'] +['Ġlight', 'weight'] +['ĠT', 'F'] +['ĠEffect', 's'] +['.T', 'ypes'] +['.add', 'Class'] +['Ġv', 'egan'] +['é', 'ģ'] +[".'", '"'] +['ĠExpl', 'orer'] +['.d', 'etect'] +['.sh', 'ift'] +['Ġoblig', 'ations'] +['last', 'Name'] +['Ġassoci', 'ations'] +['ĠTime', 'Span'] +['un', 'ter'] +['ĠF', 'resh'] +['Compat', 'ible'] +['P', 'ub'] +['id', 'ges'] +['.', 'option'] +['var', 'i'] +['.hash', 'Code'] +['Ġg', 'eb'] +['.', 'section'] +['-', 'not'] +['ĠSub', 'mit'] +['T', 'N'] +['reg', 'istry'] +['_m', 'edia'] +['Ġn', 'aj'] +['ff', 't'] +['Ġm', 'ate'] +['-th', 'ird'] +['Ġp', 'ockets'] +['est', 'a'] +['Ġb', 'ent'] +['ĠN', 'ord'] +['Ġretail', 'ers'] +['ĠMor', 'ris'] +['.""', '"ĊĊ'] +['W', 'rong'] +['Ġ', 'ÅĽ'] +['R', 'ay'] +['.', 'ec'] +['ĠB', 'ind'] +['_H', 'AND'] +['(n', 'on'] +['is', 'Valid'] +['Ġsimilar', 'ly'] +['_L', 'IMIT'] +['Ġdynam', 'ics'] +['Ġdist', 'inction'] +['ãģ', 'Ĩ'] +['<', 'N'] +['Ġor', 'th'] +['ĠToy', 'ota'] +['ĠK', 'ate'] +['ĠL', 'S'] +['or', 'ie'] +['ĠSpr', 'ings'] +['Ġf', 'reak'] +['last', 'name'] +['_M', 'ULT'] +['-st', 'ep'] +['"', '('] +['AD', 'DR'] +['Ġentert', 'aining'] +['_CON', 'F'] +['Ġdec', 'oded'] +['Ġst', 'reak'] +['Ġwait', 'ed'] +['Ġnot', 'ified'] +['rodu', 'ced'] +['vis', 'ual'] +['.Layout', 'Params'] +['æ', '°'] +['es', 'ian'] +['f', 'its'] +['s', 'pring'] +['ĠBern', 'ie'] +['User', 'Defaults'] +['Ġped', 'est'] +['Ap', 'pearance'] +['ĠW', 'iki'] +['ĠNOT', 'ICE'] +['Ġs', 'sh'] +['Ġdur', 'ante'] +['ĠZ', 'ip'] +['ı', 'r'] +['ĠNAT', 'O'] +['Ġtw', 'elve'] +['Ġro', 'yal'] +['ï', '¸'] +['Ġmer', 'chant'] +['ĠF', 'urniture'] +["']", '),Ċ'] +[',', 'X'] +['Ġfold', 'ers'] +['ĠG', 'ate'] +['ĉf', 'unc'] +['p', 'ick'] +['_us', 'uario'] +['ĠV', 'erm'] +['ment', 'ion'] +['ur', 'pose'] +['Ġalert', 's'] +['x', 'ious'] +['_s', 'ig'] +['ĠF', 'u'] +['Ġ(', ':'] +['Ġd', 'umb'] +['åħ', '³'] +['Ġaccur', 'ately'] +['éĩ', 'į'] +['R', 'B'] +['-s', 'creen'] +['ĠV', 'ER'] +['j', 'our'] +['Ġrom', 'ance'] +['uc', 'ceed'] +['.', 'choice'] +['Ġad', 'ip'] +['_d', 'ims'] +['Serial', 'izable'] +['ãĤ', 'ĭ'] +['.j', 'ob'] +['Ġpro', 'g'] +['uch', 'ar'] +['Ġg', 'ently'] +['ĠR', 'SS'] +['ict', 'ured'] +['_ENABLE', 'D'] +['ĉ', 'label'] +['aw', 'ks'] +['ĠEn', 'sure'] +['rem', 'ember'] +['ìł', 'ķ'] +['Ġtrans', 'mit'] +['{{', '$'] +['.Trans', 'action'] +['ur', 'se'] +['_rel', 'ative'] +['Ġs', 'ized'] +['ĠX', 'X'] +['ĠPr', 'incess'] +['ĠL', 'arry'] +['Ġpr', 'ó'] +['ĠÑģÑĤ', 'ÑĢ'] +['Ġs', 'isters'] +['estr', 'uct'] +['Ġcheck', 'point'] +[':', 'length'] +['ĠCar', 'los'] +['/', 'icon'] +['_T', 'ARGET'] +['T', 'okens'] +['Ġpat', 'ience'] +['ĠSe', 'lected'] +['q', 'ty'] +['.show', 'Message'] +['Ġwild', 'life'] +['ĠP', 'rops'] +['b', 'm'] +['-', 'arrow'] +['Ġpar', 'cel'] +['fire', 'base'] +['ĠBen', 'jamin'] +['cess', 'o'] +['.t', 'im'] +['ĠG', 'arc'] +['.', 'any'] +['ĠHOW', 'EVER'] +['ĠK', 'o'] +['Ġgrab', 'bed'] +['_f', 'rames'] +['Ġobject', 'AtIndex'] +['ĠADV', 'ISED'] +['Ġsub', 'ur'] +['ĉ', 'GL'] +['Ġ})', '}Ċ'] +['-l', 'ength'] +['ìĭ', 'ľ'] +['ĠPot', 'ter'] +['_b', 'uff'] +['.g', 'ui'] +['ĠEnc', 'oding'] +['E', 'lect'] +['-m', 'essage'] +['Ġ', '�'] +['Ġ', 'ÈĻi'] +['ĠArgument', 'NullException'] +['а', 'ÑĨи'] +['Ġmin', 'imize'] +['Ġrespond', 'ing'] +['$_', "['"] +['ĠInd', 'ividual'] +['á', 'c'] +['ĠIN', 'TER'] +['Ġmast', 'urb'] +['ĠB', 'in'] +["('", '$'] +['ëĵ', 'ľ'] +['Ġopen', 'ly'] +['Ġ>', '<'] +['Ġun', 'to'] +['olog', 'ically'] +['ĠM', 'ul'] +['VID', 'IA'] +['Ġsl', 'im'] +['ĠCommission', 'er'] +['(', 'on'] +['Ġunder', 'neath'] +['/', 'db'] +['v', 'ote'] +['(', 'Message'] +['ĠP', 'ope'] +['Def', 'ined'] +['Ġsw', 'ift'] +['ur', 'f'] +['Ġadapt', 'ed'] +['SE', 'L'] +['Ġreven', 'ues'] +['Ġdiv', 'ine'] +['=', 'y'] +['Grad', 'ient'] +['_', 'act'] +['Ġ/*!', '<'] +['Ġpoly', 'gon'] +['ĠF', 'DA'] +['ĠC', 'arr'] +['at', 'ables'] +['(std', 'out'] +['Ġrefr', 'iger'] +['Ġco', 'ordin'] +['avor', 'ites'] +['ÑĪ', 'и'] +['Ġcompass', 'ion'] +['ĠPOSS', 'IBILITY'] +['-', 'secondary'] +['ur', 'acy'] +['Ġcomp', 'romise'] +['_A', 'V'] +['_', 'os'] +['Ġbes', 'ide'] +['ĥ', 'Ŀ'] +['Ġl', 'n'] +['.pl', 'ugins'] +['Cap', 'acity'] +['al', 'ah'] +['.b', 'in'] +['ĠC', 'RC'] +['_b', 'alance'] +['Ġflex', 'Direction'] +['Ġam', 'bit'] +['Ġnick', 'name'] +['ĠFor', 'ces'] +['C', 'LE'] +['ĠSh', 'ell'] +['Ġs', 'ail'] +['ĠW', 'riter'] +['ĠA', 'lice'] +['d', 'w'] +['ĠInd', 'ians'] +['ĠMar', 'shall'] +['_S', 'RC'] +['Ġnormal', 'ized'] +['ĠJ', 'ag'] +['ãĤ', 'Ĵ'] +['ze', 'it'] +['r', 'pc'] +['ÃŃ', 'c'] +['.in', 'line'] +['Ġtrav', 'ers'] +['_n', 'umeric'] +['Ġutil', 'ities'] +['Ġev', 'ac'] +['IN', 'PUT'] +['ĉ', 'register'] +['M', 'X'] +['ĠCamp', 'bell'] +['Ġdatas', 'ets'] +['Ġdem', 'anded'] +['Ġinitial', 'State'] +['g', 'an'] +['Ġe', 'i'] +['Un', 'expected'] +['-', 'web'] +['tr', 'ait'] +[',', 'Y'] +['ĠT', 'odd'] +['Ġske', 'leton'] +['Ġoptim', 'ize'] +['ç¬', '¬'] +['ĠU', 'pon'] +['ĠSt', 'Object'] +['Ġap', 'lic'] +[".'", '', 'P'] +['v', 'ron'] +['.', 'UN'] +['Ġpaint', 'er'] +['izar', 're'] +['Ġl', 'av'] +['Ġp', 'om'] +['p', 'reg'] +['=', 'function'] +['(', 'serial'] +['ific', 'a'] +['um', 'ing'] +['åľ', '°'] +['ãģ', 'Ĥ'] +['-', 'op'] +['U', 'CH'] +['ĠH', 'end'] +['.prop', 'Types'] +['Ġy', 'o'] +['Ġrout', 'ines'] +['Ġcar', 'ing'] +['S', 'em'] +['Ġres', 'erves'] +['Ġprior', 'ities'] +['red', 'its'] +['IST', 'R'] +['Content', 'Type'] +['ĠSch', 'w'] +['/', 'media'] +['Ġe', 'str'] +['Ġclim', 'bing'] +['-', 'week'] +['cher', 'che'] +['s', 'ensor'] +['To', 'Array'] +['ĠMont', 'real'] +['Ġcloud', 's'] +['ĠInject', 'able'] +['ĠR', 'ice'] +['Ġpropag', 'anda'] +['_pro', 'vider'] +['Ġind', 'oor'] +['Ġin', 'aug'] +['Ġdipl', 'om'] +['Ġmess', 'aging'] +['_m', 'ut'] +['å', '¦Ĥ'] +['Ġk', 'w'] +['ON', 'S'] +['ari', 'ans'] +['R', 'PC'] +[')', ']čĊ'] +['-r', 'ay'] +['ĠS', 'or'] +['m', 'all'] +['Ġmarket', 'place'] +['Ġv', 'tk'] +['M', 'a'] +['og', 'an'] +['ig', 'i'] +['Ġspons', 'ored'] +['ĠD', 'ani'] +['.S', 'EVER'] +[">'", '.$'] +['m', 'ultipart'] +['ĠW', 'ol'] +['Ġtable', 'Name'] +['ĠUser', 'name'] +['Background', 'Color'] +['Ġf', 'right'] +['_E', 'MAIL'] +['Sept', 'ember'] +['_val', 's'] +['op', 'ia'] +['Ġsp', 'otted'] +['-', 'Ch'] +['Ġdata', 'Source'] +['/', '"Ċ'] +['ек', 'ÑĤ'] +['ĠRequest', 'Method'] +['ĠRe', 'place'] +['-d', 'o'] +['ah', 'n'] +['ĠPh', 'D'] +[']', '.ĊĊ'] +['N', 'ON'] +['g', 'ement'] +['ĠTh', 'r'] +['Ġquiet', 'ly'] +['Ġtort', 'ure'] +['Ġte', 'as'] +['ĠC', 'Y'] +['Ġa', 'tr'] +['develop', 'ment'] +['-d', 'etail'] +['Ġlight', 'er'] +['Ġarg', 'uing'] +['Ġdes', 'erves'] +['Ġcur', 'riculum'] +['_CON', 'TEXT'] +['ÅĤ', 'y'] +['H', 'ITE'] +['ĉ', 'ID'] +['/', 'uploads'] +['Ġt', 'its'] +['re', 'o'] +['_d', 'rop'] +['.', 'UTF'] +['Ġpick', 'up'] +['Ġgro', 'cery'] +['ĠP', 'ure'] +['Ġeas', 'iest'] +['Ph', 'il'] +['.f', 'eature'] +['("', '*'] +['Ġinvest', 'or'] +['t', 'ok'] +['Ġj', 'ar'] +['L', 'os'] +['âĢĶâĢĶâĢĶâĢĶ', 'âĢĶâĢĶâĢĶâĢĶ'] +['.', 'queue'] +['-s', 'peed'] +['M', 'al'] +['um', 'blr'] +['ĠCON', 'ST'] +['ĠH', 'RESULT'] +['ĠD', 'ance'] +['(file', 'Path'] +['Ġattrib', 'uted'] +['à¥', 'į'] +['ĠB', 'und'] +['co', 'ins'] +['Ġs', 'ão'] +['Ġp', 'ir'] +['person', 'al'] +['Ġpre', 'lim'] +['Ġprop', 'ose'] +['ĠT', 'L'] +[']', '])'] +['ĠSub', 'scription'] +['ĠK', 're'] +[',', 'len'] +['.First', 'OrDefault'] +[')', '--'] +['_product', 's'] +['.Get', 'Bytes'] +['Sh', 'ip'] +['Ġenc', 'rypt'] +['ĠS', 'G'] +['ĠM', 'yst'] +['h', 'ir'] +['Ġiter', 'ate'] +['Ġint', 'end'] +['.mock', 'ito'] +['Ġch', 'apters'] +['(', 'angle'] +['ĠV', 'lad'] +['è®', '¾'] +["'", '.ĊĊ'] +['Response', 'Body'] +['ĠAb', 'd'] +['de', 'al'] +['Ġbar', 'riers'] +['-out', 'line'] +['b', 'ill'] +['ĠF', 'alls'] +['_se', 'cond'] +['.', 'include'] +['.', 'ceil'] +['Ġoccup', 'ation'] +['ph', 'ony'] +['.move', 'To'] +['ĠJenn', 'ifer'] +['AST', 'ER'] +[';', '"><'] +['ĠEn', 'abled'] +['Ġtermin', 'ate'] +['ĠI', 'o'] +['l', 'ations'] +['ĠTHE', 'ORY'] +['Ġear', 'liest'] +['Ġr', 'ack'] +['ĠSc', 'ar'] +['sh', 'ake'] +['ch', 'ip'] +['Ġu', 'v'] +['Ġall', 'iance'] +['п', 'иÑģ'] +['ĠGOOD', 'S'] +['z', 'ione'] +['ĠV', 'I'] +['Ġ{', '-'] +['Ġfilter', 'ing'] +['Ġmis', 'con'] +['.Dock', 'Style'] +['Ġb', 'ush'] +['Ġj', 'unk'] +['æ', 'Į'] +['ĠQ', 'UE'] +['Ġhook', 's'] +['Ġfirm', 'ware'] +['Ġmiddle', 'ware'] +['d', 'ic'] +['ĠOak', 'land'] +['Ġarr', 'ives'] +['P', 'ayload'] +['p', 'ixel'] +[']', '|'] +['Ġstart', 'Date'] +['.P', 'RO'] +['_a', 'udio'] +['Ġmid', 'field'] +['igid', 'body'] +['ĠSw', 'iss'] +['ĠCl', 'ip'] +['ĠD', 'ump'] +['ĠText', 'Box'] +['Ġg', 'eh'] +['y', 'ield'] +['od', 's'] +['Ġrefer', 'endum'] +['Back', 'end'] +['ĠC', 'ream'] +['Ġdomin', 'ated'] +['ĠArch', 'ive'] +['Ġrid', 'ers'] +['.prepare', 'Statement'] +['Ġqu', 'ando'] +['Ġche', 'f'] +['w', 'iki'] +['in', 'el'] +['am', 'pling'] +['("', '\\\\'] +['Ġs', 'ag'] +['_pro', 'xy'] +['ãģ', 'ķ'] +['p', 'do'] +['.getElementsBy', 'TagName'] +['Ġdemonstr', 'ation'] +['ĠN', 'PC'] +['Ġarch', 'ivo'] +['end', 'ance'] +['Ġefficient', 'ly'] +['(', 'actual'] +['.t', 'ableView'] +['Ġm', 'ush'] +['Ġbe', 'ars'] +['_thread', 's'] +['j', 'as'] +['ah', 'un'] +['Ġne', 'ural'] +['Ġdesign', 'ing'] +['ĠG', 'DP'] +['Ġlift', 'ed'] +['çĽ', '®'] +['ĠJ', 'oint'] +['ĠIn', 'clude'] +['ĠGi', 'ants'] +['Ġwithdraw', 'al'] +['ĠR', 'ent'] +['n', 'ative'] +['ĠSe', 'ek'] +['gress', 'ion'] +['_C', 'PU'] +['\\', 'S'] +['ĠSh', 'ield'] +['Ġsol', 'ic'] +['Ġbo', 'om'] +['yect', 'o'] +['Ġmanufact', 'ure'] +['ĠâĢ', 'ĭ'] +['Ġb', 'box'] +['Ġearth', 'qu'] +['ollect', 'ors'] +[':@"', '%'] +['Ġlo', 'ops'] +['J', 'e'] +['alk', 'ing'] +['ĠWh', 'ats'] +['ĠBo', 'ys'] +['.', 'book'] +['ARG', 'E'] +['_p', 'ixel'] +['Ġsus', 'pects'] +['Î', '¹'] +['us', 'p'] +['ĠBM', 'W'] +['ie', 'ces'] +['(p', 'erson'] +['å¼', 'Ģ'] +['é', '»'] +['ĠPod', 'cast'] +['Ġb', 'ou'] +['(', 'Item'] +['Ã', '»'] +['(', 'Input'] +['Http', 'Get'] +['Ġb', 'urg'] +[')', '^'] +['BO', 'ARD'] +['*/', ','] +['Ġg', 'ulp'] +['ĠB', 'enn'] +['Ġdeck', 's'] +['.status', 'Code'] +['Ġac', 'ute'] +['Ġh', 'ug'] +['ug', 'u'] +['Ġp', 'led'] +[',"', '%'] +['h', 'ape'] +['Ġз', 'ап'] +['ĠMain', 'e'] +['.re', 'al'] +['Ġd', 'alam'] +['ĠMin', 'or'] +['.F', 'loat'] +['dis', 'p'] +['Ġt', 'l'] +['Ġen', 'count'] +['=>', '$'] +['Ġf', 'g'] +['te', 'es'] +['ĠRec', 'omm'] +['ä', 'l'] +['Ġchem', 'istry'] +['Block', 's'] +['O', 'ID'] +['Ġfore', 'x'] +['ĠApp', 'end'] +['Ġ{', '*'] +['ĠSup', 'ply'] +['CG', 'Float'] +['(b', 'l'] +['Ġat', 'e'] +['ador', 'a'] +['Ġg', 'ust'] +['Ass', 'oci'] +['>', '.Ċ'] +['F', 'ETCH'] +['.s', 'erial'] +['widget', 's'] +['ard', 'less'] +['ie', 'fs'] +['_F', 'ULL'] +['ernet', 'es'] +['ĠP', 'red'] +['Ø', 'Ń'] +['äº', 'ĭ'] +['ub', 'ernetes'] +['ĠL', 'aura'] +['Ġl', 'abeled'] +['High', 'light'] +['Ġanno', 'ying'] +['/', 'update'] +['(d', 'escription'] +['Ġintim', 'id'] +['$', 'c'] +['"))', ')Ċ'] +['.A', 'P'] +['Ġ[]', '*'] +['ĠEX', 'IT'] +['.H', 'ost'] +['ĠOP', 'EN'] +['.send', 'Message'] +['_c', 'amera'] +['_t', 'ile'] +['Ġth', 'erm'] +['onom', 'ous'] +['Ġdis', 'adv'] +['Ġna', 'ar'] +['index', 'Of'] +['ĠP', 'P'] +['.prot', 'ocol'] +['AF', 'E'] +['Ġtext', 'ures'] +['################################', '################'] +['umb', 'ai'] +['.st', 'ats'] +['ĠG', 'E'] +['Ġi', 'e'] +['ĠST', 'D'] +['ĠM', 'ann'] +['.ref', 'lect'] +['K', 'B'] +['Ġd', 'ive'] +['.w', 'av'] +['/*', '----------------------------------------------------------------'] +['/', 'settings'] +['.l', 'ifecycle'] +['Ġda', 'ughters'] +['or', 'us'] +['ub', 'er'] +['N', 'ING'] +['st', 'ri'] +['ĠT', 'ip'] +['Ġz', 'n'] +['Ġswitch', 'ed'] +['in', 'et'] +['uff', 'y'] +['ĠTransport', 'ation'] +['(', 'conf'] +['fr', 'ica'] +['ĠX', 'L'] +['ĠLe', 'ad'] +['_per', 'cent'] +['<', 'Map'] +['Ġthr', 'ust'] +['or', 'b'] +['ik', 'k'] +['Ġtra', 'uma'] +['Access', 'or'] +['ĠF', 'it'] +['ĠString', 'Buffer'] +['ex', 'pl'] +['(s', 'creen'] +['Ġaud', 'iences'] +['ĠO', 'PTION'] +['_', 'round'] +['[', 'node'] +['be', 'h'] +['->', '__'] +['per', 'missions'] +['ĠD', 'etermine'] +['.M', 'an'] +['Ġadv', 'ances'] +['.', 'InputStream'] +['Ġstrong', 'est'] +['Ġe', 'Bay'] +['Ġ#', '-'] +['Ġdir', 'name'] +['ĠS', 'MS'] +['Ġmedic', 'ations'] +['Ġam', 'ended'] +['Ġchurch', 'es'] +['ĠImper', 'ial'] +['$', 'row'] +['ĠMad', 'ison'] +['ĠIn', 'sp'] +['Ġaff', 'air'] +['Ġpsych', 'ology'] +['v', 'h'] +['Ġsever', 'ity'] +['âĢ', 'IJ'] +['Ġstri', 'ps'] +['A', 'H'] +['vert', 'ising'] +['Ġcon', 'se'] +['IM', 'AGE'] +['ĠSt', 'ats'] +['ĉs', 'c'] +['.C', 'ursor'] +['Ġfree', 'ze'] +['ss', 'on'] +['(x', 'ml'] +['ĠSus', 'an'] +['.t', 'ile'] +['ed', 'ed'] +['ĠĠĠĠ', 'ĉĉĉ'] +['uel', 'le'] +['ĠMitch', 'ell'] +['b', 'ased'] +['Oper', 'and'] +['½', 'æķ°'] +['ĠF', 'F'] +['ĉstr', 'cpy'] +['ounc', 'es'] +['ild', 'o'] +['.execute', 'Query'] +['Ġapproach', 'ing'] +['ĠSe', 'ven'] +['Ġn', 'uts'] +['Ġr', 'ic'] +['ass', 'ignment'] +['Ġcalcul', 'ator'] +['ĠMur', 'phy'] +['ĠB', 'ou'] +['í', 'Ħ'] +['Ġbut', 't'] +['Ġt', 'icks'] +['Project', 's'] +['il', 'ib'] +['.text', 'Color'] +['m', 'ov'] +['_log', 'o'] +['(', 'template'] +['ĠIN', 'IT'] +['Ġimage', 'View'] +['scri', 'ptions'] +['OR', 'ITY'] +['Con', 'sumer'] +['Ġun', 'precedented'] +['Ġtour', 'ist'] +['Ġbr', 'on'] +['Ġcontract', 'or'] +['Ġlic', 'ence'] +['ĠN', 'am'] +['æ', '¯'] +['(', 'transform'] +['_AT', 'T'] +['P', 'ref'] +['ĠG', 'am'] +['Ġvess', 'els'] +['Ġh', 'av'] +['L', 'ater'] +['.To', 'Lower'] +['Ġurl', 's'] +['Ġbreak', 'down'] +['Ġpen', 'alties'] +['Ġf', 'oster'] +['ĠU', 'E'] +['Ġcl', 'ue'] +['com', 'ed'] +['åIJį', 'ç§°'] +['-m', 'ain'] +['Ġp', 'ts'] +['Ġcount', 'ed'] +['ict', 's'] +['/', 'post'] +['Ġget', 'attr'] +['Ġp', 'ing'] +['ANCE', 'L'] +['Ġp', 'ec'] +['Ñħ', 'од'] +['ant', 'om'] +['ĠBlue', 'print'] +['ĠEvent', 'Emitter'] +['Ġl', 'ä'] +['æ', '²'] +['Ġstr', 'aw'] +['(', 'comp'] +["'", 'une'] +['>', 'N'] +['-', 'client'] +['es', 'Module'] +['-b', 'ase'] +['Ġret', 'reat'] +['_s', 'imple'] +['ĉĉĉĉĉĉ', 'Ġ'] +['fe', 'e'] +["')", 'čĊčĊ'] +['Control', 'Item'] +['Ġsubscri', 'bers'] +['ple', 'ase'] +['ĠE', 'ff'] +['Ġp', 'ound'] +['ĠBy', 'tes'] +['ĠTe', 'a'] +['_', 'activity'] +['Ġmax', 'im'] +['Ġop', 'code'] +['B', 'SD'] +['.', 'constant'] +[';', '}'] +['omb', 'res'] +['Ġcare', 'ers'] +[')', '.ĊĊĊĊ'] +['Ġsp', 'reading'] +['-exp', 'anded'] +['ĠOr', 'd'] +['amar', 'in'] +['Ġmob', 'ility'] +['Un', 'fortunately'] +['ak', 'k'] +['N', 'L'] +['_', 'redirect'] +['ĠP', 'G'] +['ĠS', 'ensor'] +['b', 'ol'] +['t', 'ap'] +['_MEM', 'ORY'] +['ĠUI', 'Alert'] +['plit', 'ude'] +['We', 'bsite'] +['ĠLog', 'o'] +['lo', 've'] +['[', 'ind'] +['Ġalto', 'gether'] +['Ġwonder', 'ed'] +['Ġes', 'per'] +['ĠLib', 'eral'] +['Ġo', 'ss'] +['Ġel', 'it'] +['Ġst', 'iff'] +['od', 'ox'] +['_ment', 'ions'] +['ĠDou', 'glas'] +['_p', 'id'] +['ĠC', 'K'] +['ĠinitWith', 'Frame'] +['.b', 'log'] +['p', 'kg'] +['ang', 'hai'] +['QUI', 'RED'] +['u', 'u'] +['Ġm', 'kdir'] +['AT', 'AL'] +['Ġun', 'h'] +['in', 'ces'] +['st', 'h'] +['Ġhypo', 'thesis'] +['Ġc', 'ata'] +['ĠT', 'B'] +['ĠCl', 'ar'] +['Ġpre', 'decess'] +['Ġsitu', 'ated'] +['-w', 'orld'] +['))', '/'] +['Ġhead', 'lines'] +['.st', 'at'] +['Ġout', 'break'] +['sp', 'ath'] +['_FLAG', 'S'] +['ĠServlet', 'Exception'] +['S', 'un'] +['F', 'ROM'] +['ĠD', 'ir'] +['ãĥ»ãĥ»', 'ãĥ»'] +['_co', 'ord'] +['ĠOpt', 'im'] +['Mon', 'itor'] +['.b', 'it'] +['XX', 'X'] +['Ġtod', 'as'] +['f', 'eld'] +['ÑĢ', 'и'] +['im', 'ir'] +['Ġpolit', 'ically'] +['Ġmolec', 'ular'] +['Ġtrad', 'ed'] +['Ġ{{', '$'] +['ĠSw', 'edish'] +["Ġ'@", '/'] +['_RE', 'AL'] +['Ġw', 'arehouse'] +['t', 'oday'] +[',', 'L'] +['or', 'p'] +['<', 'section'] +['-', 'br'] +['ym', 'e'] +['ĠUser', 'Service'] +['Ġlib', 'erty'] +['Ġmoment', 'o'] +['(', 'Image'] +['<', 'size'] +['S', 'ch'] +['Ġj', 'og'] +['i', 'ology'] +['arent', 'ly'] +['Ġquant', 'um'] +['ĠAb', 'u'] +['Ġr', 'im'] +['Ġman', 'a'] +['Font', 'Size'] +['Build', 'ing'] +['st', 'airs'] +['AIL', 'ABLE'] +['Ġ&', "'"] +['Ġs', 'ect'] +['Ġs', 'igh'] +['(b', 'atch'] +['.I', 'Container'] +['p', 'oll'] +['ĠCor', 'ps'] +['Î', 'µ'] +['ar', 'u'] +['ĠK', 'ay'] +['.r', 'ange'] +['_click', 'ed'] +['ĠRobert', 's'] +['.N', 'etwork'] +['fin', 'ish'] +['-', 'Man'] +['Ġcolleg', 'es'] +['ĠF', 'ine'] +['"))', ',Ċ'] +['f', 'ilm'] +['Ġrem', 'inded'] +['Ġgest', 'ure'] +['out', 'il'] +['Ġthread', 'ing'] +['Ġobj', 'et'] +['Ġt', 'ours'] +['activ', 'ated'] +['.m', 'kdir'] +['=', 'user'] +['Ġre', 'de'] +['f', 'ü'] +['_SY', 'STEM'] +['p', 'v'] +['Ġcon', 'gr'] +['Ġmass', 'asje'] +['Ġpract', 'ition'] +['Un', 'iversity'] +['Ġtab', 'index'] +['Ð', 'ĺ'] +['S', 'ets'] +['Ġcount', 'ies'] +['g', 'uest'] +['f', 'an'] +['Ġword', 'en'] +['.d', 'i'] +['на', 'Ñĩ'] +['Â', '¿'] +['ig', 'Decimal'] +['Ġsh', 'ore'] +['Ġg', 'ö'] +['Ġrep', 'airs'] +['Ġhelp', 'ers'] +['Ġcenter', 'ed'] +['OL', 'LOW'] +['Ġmap', 'StateToProps'] +['Ġc', 'ents'] +['<', 'A'] +['Ġexpect', 'ation'] +['Oct', 'ober'] +['Ġbg', 'color'] +['ca', 'les'] +['.C', 'ON'] +['ĠV', 'el'] +['Ġcry', 'ing'] +['-se', 'ason'] +['Ġfunction', 'ing'] +['_LOC', 'ATION'] +['ü', 'ss'] +['ber', 'y'] +['Par', 'a'] +['omin', 'ator'] +['-', 'le'] +['Ġeth', 'ical'] +['has', 'htags'] +['emp', 'lo'] +['Ġn', 'úmero'] +['(', 'activity'] +['.St', 'op'] +['.str', 'ftime'] +['IL', 'D'] +['Ġto', 'e'] +['ĉ', 'Node'] +['")', 'čĊčĊ'] +['ĠPu', 'erto'] +['Ġexec', 'uting'] +['ĠG', 'UID'] +['Ġoppos', 'ing'] +['al', 'ph'] +['Ġexhib', 'it'] +['_fl', 'ash'] +['Ġme', 'ille'] +['Ġjson', 'Object'] +['H', 'ero'] +['aint', 'ed'] +['_D', 'OM'] +['Ġw', 'il'] +['Ġslo', 'pe'] +['Ġm', 'Ã¥'] +['ĠIraq', 'i'] +['Ġorgan', 'ize'] +['ĉj', 'Query'] +['H', 'UD'] +['sh', 'ine'] +['.', 'we'] +['ĠSk', 'ills'] +['pons', 'or'] +['Ġcon', 'clusions'] +['Ġre', 'forms'] +['Ġrel', 'uct'] +['n', 'amed'] +['ĠOl', 'iver'] +['Ġ//', '}Ċ'] +['-', 'looking'] +['Ġf', 'og'] +['ĠH', 'O'] +['ĠF', 'ried'] +['Ġinev', 'itable'] +['ĠData', 'GridView'] +['H', 'our'] +['il', 'les'] +['log', 'ical'] +['Ġconnect', 'ivity'] +['.tw', 'ig'] +['ĠK', 'yle'] +['(d', 'st'] +['-', 'Sh'] +['ĠStud', 'ios'] +['(', 'Level'] +['.j', 'et'] +['_PRO', 'TO'] +['-de', 'coration'] +['OT', 'HER'] +['Ġread', 'ily'] +['.Param', 'eter'] +['Ġmultip', 'ly'] +['ĠL', 'IB'] +['ar', 'med'] +['Ġsoon', 'er'] +['æ', 'Ħ'] +['_', 'ES'] +['Ġfoss', 'il'] +['ĠA', 'nc'] +['âĢľ', 'This'] +['l', 'odash'] +['Py', 'thon'] +['Ġhist', 'ogram'] +['west', 'ern'] +['Ġinf', 'ant'] +['Ġco', 'ordinator'] +['Ġn', 'ib'] +[':', 'm'] +['Ġres', 'pected'] +['Ġdef', 'init'] +['&', 'T'] +['_p', 'ad'] +['ĠTr', 'igger'] +['th', 'al'] +['Ġimage', 'Named'] +['Ġbeat', 'en'] +['ĉ', 'rc'] +['ĠPal', 'ace'] +['Ġhaz', 'ard'] +['Ġisol', 'ation'] +['_', 'rc'] +['cont', 're'] +['OUT', 'PUT'] +['Ġre', 'ign'] +['ĠPl', 'ate'] +['AT', 'ES'] +['Ġfl', 'ux'] +['Ġpack', 's'] +['.get', 'Selected'] +['Ġparticip', 'ated'] +['Ġneed', 'le'] +['-de', 'pth'] +['::::', '::'] +['-l', 'aw'] +['ins', 'pace'] +['on', 'itor'] +['=', 'no'] +['ĠAt', 'omic'] +['ĠBr', 'ain'] +['Edit', 'able'] +['-s', 'c'] +['red', 'ential'] +['ĠP', 'erry'] +['k', 'ie'] +['Ġ', '----------Ċ'] +['.st', 'roke'] +['(', 'Intent'] +['Ġun', 'ity'] +['um', 'lah'] +['F', 'urther'] +['Ġpr', 'ze'] +['Ġs', 'ø'] +['ãĤ', 'Ĭ'] +['ĠPROC', 'UREMENT'] +['ĠH', 'ousing'] +['Ġatt', 'orneys'] +['Ġcomp', 'ose'] +['atter', 'ing'] +['"', 'What'] +['dra', 'ul'] +['Ġstraight', 'forward'] +['In', 'stant'] +['.J', 'TextField'] +['Ġtr', 'ades'] +['л', 'а'] +['Ġ{', '!'] +['Ġl', 'ately'] +['IM', 'G'] +['ĠA', 'ld'] +['ĠIN', 'NER'] +['Ġcart', 'oon'] +['.S', 'ource'] +['F', 'ALSE'] +['Ġd', 'ough'] +['f', 'en'] +['(', 'rect'] +['Data', 'Table'] +['N', 'ick'] +['ĠBut', 'ter'] +['read', 's'] +['_com', 'ments'] +['EN', 'V'] +['ĠConnect', 'icut'] +['-F', 'IRST'] +['ĉĉĉ', 'ĠĠĠĠĠ'] +['ach', 'i'] +['.M', 'sg'] +['re', 'ction'] +['Ġrelax', 'ed'] +['Ġsha', 'ft'] +['Ġe', 'f'] +['ĠAdd', 'ing'] +['Ġbre', 'ach'] +['Ġ', 'ï¼ļ'] +['ram', 'a'] +['Ġconduct', 'ing'] +['Ġ(', ';'] +['(g', 'l'] +['ĠCA', 'USED'] +['ash', 'i'] +['ĠF', 'LAG'] +['ĠCom', 'merce'] +['ĠIN', 'TEGER'] +['h', 'ours'] +['ĠSchool', 's'] +['Ġn', 'ucle'] +['Ag', 'ain'] +['pro', 'j'] +['Ġsevent', 'h'] +['EMPL', 'ARY'] +['(m', 'ock'] +["']", ',čĊ'] +['_S', 'PEED'] +['>', 'false'] +['Ġsp', 'a'] +['ĠN', 'ear'] +['ì', 'ķ'] +['Ġintr', 'ig'] +['_m', 'embers'] +['w', 'ave'] +['Ġanalyst', 's'] +['_O', 'S'] +['ed', 'in'] +['ĠF', 'ri'] +['Ġretrie', 'ved'] +['Reg', 'ular'] +['_', 'obs'] +['EX', 'PORT'] +["')}}", '"'] +['"', 'class'] +['__', '(('] +['b', 'ucket'] +['Ġst', 'ro'] +['ĠP', 'atch'] +['yst', 'ick'] +['ful', 'ness'] +['ap', 'os'] +['D', 'a'] +['ĉĉĉĉĉ', 'ĠĠĠ'] +['Ġen', 'rich'] +['un', 'ordered'] +['h', 'ole'] +['C', 'ong'] +['<', 'Product'] +['ĠC', 'urt'] +['(', 'the'] +['_l', 'ower'] +['Ġavoid', 'ing'] +['Ġbu', 'zz'] +['Ġv', 'iable'] +['ub', 'a'] +['-', 'is'] +['are', 'l'] +['Ġact', 'ed'] +['-d', 'etails'] +['à¸', 'ĩ'] +['ĠThe', 'ory'] +['ĠP', 'un'] +['ĠAn', 'onymous'] +['...', '"Ċ'] +['è', 'res'] +['åı', '¯'] +['ĠV', 'ision'] +['_se', 'm'] +['ash', 'a'] +['Ġcelebr', 'ity'] +['Ġend', 'Date'] +['Ġpop', 'ulate'] +['Ġcu', 'is'] +['qu', 'ant'] +['f', 'loor'] +['Ġglob', 'ally'] +['Ġcru', 'ise'] +['ĠStan', 'ley'] +['Ġb', 'ikes'] +['.get', 'Connection'] +['Ġpoor', 'ly'] +['_', 'other'] +['amp', 'ing'] +['."', ');ĊĊ'] +['od', 'i'] +['_A', 'DMIN'] +['.color', 's'] +['ĠG', 'aming'] +['>', "';ĊĊ"] +['STR', 'UCT'] +['Q', 'R'] +['ID', 's'] +['(arg', 'uments'] +['_a', 'ux'] +['(', 'Event'] +['_PR', 'IVATE'] +['ĠTre', 'k'] +['Ġdownload', 's'] +['m', 'utable'] +['_STR', 'UCT'] +['(w', 'x'] +['Ġdom', 'ains'] +['js', 'px'] +['ĠVi', 'agra'] +['Command', 's'] +['J', 's'] +['.c', 'fg'] +['Content', 'Pane'] +['ĠEdit', 'Text'] +['à¥į', 'à¤'] +['Att', 'ach'] +['ĠAR', 'M'] +['posit', 'ive'] +['ĠGener', 'ated'] +['Ġse', 'ized'] +['=', ':'] +['Ġelectron', 'ics'] +['ĠApp', 'Component'] +['/', "',Ċ"] +['.equals', 'IgnoreCase'] +['Do', 'ctrine'] +['d', 'isk'] +['ĠPolit', 'ical'] +['CH', 'O'] +['<', 'F'] +['ĉ', 'height'] +['ĠB', 'ug'] +['.', 'le'] +['ik', 'h'] +['Ġmill', 'iseconds'] +['Ġconstit', 'u'] +['m', 'ag'] +['.n', 'l'] +['-r', 'ange'] +['ang', 'gal'] +["',", '['] +['ropol', 'itan'] +['ĠÃ', 'ľ'] +['ĠU', 'C'] +['.d', 'esc'] +['-L', 'AST'] +['f', 'stream'] +['ib', 'il'] +['Ġf', 'ier'] +['VER', 'Y'] +['Ġë', '³'] +['IR', 'T'] +['_', 'UI'] +['(', 'abs'] +['Ġkne', 'es'] +['Ġro', 'okie'] +['ĠV', 'ac'] +['are', 'na'] +['comm', 'end'] +['-', '\\'] +['ĠSUB', 'STITUTE'] +['So', 'ft'] +['Ġpart', 'ir'] +['we', 'alth'] +['è¦', 'ģ'] +['(d', 'ataset'] +['ĠCl', 'imate'] +['-', 'show'] +['Ġreli', 'ability'] +['_ch', 'unk'] +['ä»', '£'] +['_st', 'ock'] +['ĠEX', 'EMPLARY'] +['ï¸', 'ı'] +['Ġv', 'ÃŃ'] +['Ġsm', 'iled'] +['Ġdr', 'ill'] +['.F', 'unction'] +['ĠS', 'I'] +['Ġreg', 'ression'] +['-', 'X'] +['ĠJ', 'ar'] +['p', 'ref'] +['ĉs', 'uccess'] +['ĠHit', 'ler'] +['Ġinst', 'inct'] +['Ġfem', 'mes'] +['Ġlo', 'ver'] +['<', 'Ċ'] +['Ġmulti', 'plier'] +['r', 'il'] +['Res', 'ize'] +['ĠAuthor', 'ization'] +['ĠK', 'an'] +['Dispatch', 'ToProps'] +['Ġc', 'rops'] +['t', 'okens'] +['ec', 'n'] +['ential', 'ly'] +['ĠINTERRU', 'PTION'] +['f', 'ake'] +['Und', 'efined'] +['ĠA', 'K'] +['ĠTest', 'Case'] +['Ġr', 'ab'] +['Ġtor', 'rent'] +['ĠO', 't'] +['B', 'ars'] +['Ġlect', 'ure'] +['Ġen', 'jo'] +['Ġrespond', 's'] +['Ġindex', 'ed'] +['Of', 'Work'] +['_ch', 'ain'] +['))', '->'] +['ĠBeaut', 'y'] +['Ġ`', '<'] +['Ġtouch', 'ing'] +['Ġ|', '--'] +['ĉf', 'lag'] +['normal', 'ize'] +['Ġtr', 'apped'] +['Ġestablish', 'ing'] +['/b', 'uild'] +['A', 'J'] +['f', 'y'] +['-', 'react'] +['av', 'n'] +['RI', 'PTION'] +['Ġk', 'ut'] +['ĠF', 'ashion'] +['ĠIn', 'form'] +['cur', 'ities'] +['<', 'byte'] +['ĠUkr', 'ain'] +['Ġs', 'ug'] +['Ġconsist', 'ing'] +['ood', 'le'] +['.', 'ctx'] +['.To', 'List'] +['Ġcomment', 'ary'] +['Ġtransf', 'ers'] +['Ġn', 'ost'] +['ih', 'ad'] +['ĠU', 'pper'] +['Ġconf', 'using'] +['miss', 'ing'] +['-', 'cl'] +['Ġbound', 'ing'] +['Ġcongress', 'ional'] +['Ġreve', 'aling'] +['d', 'h'] +['r', 'up'] +['Ġt', 'res'] +['re', 'peat'] +[',', 'ĊĊĊĊ'] +['_t', 'ac'] +['Ġexp', 'ed'] +['G', 'irl'] +['h', 'orizontal'] +['Ġ"../../', '../'] +['(', 'option'] +['Ġwe', 'iter'] +['ĉs', 'ql'] +['Ġ=>', '{Ċ'] +['Ġgar', 'lic'] +['Ġre', 'pr'] +['Ġrepl', 'ies'] +['(', 'prop'] +['Ġspir', 'its'] +['Ġins', 'pire'] +['Ġbas', 'ement'] +['.re', 'ject'] +['Ġhint', 's'] +['Ġpoll', 'ing'] +['ĉ', 'ĠĊ'] +['_r', 'ating'] +['Ġc', 'ath'] +['av', 'ier'] +['Ġcomp', 'ressed'] +['ĠV', 'S'] +[']', "'"] +['Ġjud', 'icial'] +['ĠT', 'rend'] +['tr', 'aining'] +['EST', 'AMP'] +['ogn', 'ition'] +['Ä', 'ģ'] +['SE', 'NT'] +['vent', 'ions'] +['Ġconsult', 'ant'] +['um', 'ph'] +['Ġuser', 'Service'] +[',', 'NULL'] +['k', 'h'] +['D', 'ear'] +['_B', 'AD'] +['it', 'ations'] +['Ġmet', 'aph'] +["'", 'é'] +['and', 'ise'] +['-f', 'ont'] +['.ch', 'art'] +['Ġs', 'g'] +['_', 'Controller'] +['.j', 'peg'] +['ĠUL', 'ONG'] +['ĉg', 'ame'] +['(', 'ss'] +['ĠM', 'aj'] +['ĉg', 'o'] +['ĠS', 'ad'] +['ĠB', 'erg'] +['ĠM', 'ine'] +['P', 'ack'] +['Ġres', 'istant'] +['ĠR', 'OM'] +['Ġp', 'eg'] +['ĠStan', 'ford'] +['ĠY', 'ahoo'] +['Ġsca', 'led'] +['Ġl', 'an'] +['=', '[]'] +['"/', '>', 'ččĊ'] +['Ġs', 'ud'] +['ĉ', 'background'] +['Ġsch', 'olars'] +['-m', 'uted'] +['ar', 'á'] +['Ġ=', '===='] +['Ġ__', '__'] +['C', 'reat'] +['ene', 'ver'] +['/w', 'p'] +['ĠV', 'PN'] +['Error', 'Code'] +[')', '],Ċ'] +['(b', 'uilder'] +['ĠEn', 'emy'] +['S', 'ensor'] +['us', 'a'] +['Ġtr', 'iggers'] +['Ġplayoff', 's'] +['_RE', 'Q'] +['Ġ(', '~'] +['ĠBar', 'ry'] +['Ġperman', 'ently'] +['ĠR', 'UN'] +['Ġb', 'ure'] +['.Fat', 'alf'] +['Ġch', 'ick'] +['ĉ', 'panic'] +['ps', 'i'] +['ok', 'a'] +['éĢ', 'ī'] +['>', '['] +['Ġunderstand', 's'] +['ĠJun', 'ior'] +['ĠIN', 'FO'] +['=', 'mysqli'] +['ust', 'ain'] +['-s', 'ource'] +['s', 'erv'] +['ĠC', 'REATE'] +['.', 'au'] +['Ġsell', 's'] +['ĠĠĊ', 'ĠĠĊ'] +['E', 'urope'] +['z', 'w'] +['pre', 'h'] +['ĠNS', 'A'] +['Ġx', 'y'] +['à¸', '´'] +['ĠB', 'eyond'] +['Inst', 'ead'] +['Non', 'Query'] +['Ġar', 'ise'] +['Ġavoid', 'ed'] +['.em', 'place'] +['_model', 's'] +['}', '),Ċ'] +['Ġh', 'id'] +['Ġ&', '_'] +['.p', 'oints'] +['.get', 'Width'] +['.Ex', 'ec'] +['Ġ//', '//'] +['ĠS', 'essions'] +['...', '\\'] +['ĠCol', 'omb'] +['Ġacceler', 'ation'] +['rest', 'ore'] +['Ġ', 'ile'] +['ob', 'ic'] +['<', 'Node'] +['ĠD', 'X'] +['ĠBes', 'ides'] +['.', 'age'] +['ĠCont', 'ains'] +['N', 'ational'] +['ĠIm', 'plementation'] +['Ġeff', 'ic'] +['ĠR', 'M'] +['H', 'y'] +['ĠWed', 'ding'] +['ok', 'ies'] +['Ġrec', 'ursive'] +['Ġprosec', 'utors'] +['.Se', 'lection'] +['ĠForm', 'ula'] +['Been', 'Called'] +['[i', 'i'] +['ĠFr', 'an'] +['Ġtraged', 'y'] +['_F', 'EATURE'] +['Ļ', '¨'] +['comp', 'ass'] +['ĠB', 'h'] +['?', 'ĊĊĊ'] +['.w', 'riter'] +['ĠH', 'our'] +['Db', 'Context'] +['io', 'v'] +['am', 'on'] +['re', 'pr'] +['é', 'ĥ'] +['ĉf', 'i'] +["']", ']'] +['ĠD', 'ry'] +['.', 'ro'] +['ĠO', 'bserv'] +['æł', 'ĩ'] +['Form', 'er'] +['ĠB', 'alance'] +['ĉ', 'json'] +['Ġpr', 'zy'] +['I', 'SS'] +['(', 'sock'] +['ĠL', 'INE'] +['Ġde', 'ce'] +['Ġal', 'ly'] +['Ġtend', 'ency'] +['F', 'un'] +['Ġschem', 'es'] +['Ġinter', 'ven'] +['æĺ', 'İ'] +['Ġad', 'verse'] +['quote', 'lev'] +['Ġsacr', 'ific'] +['_s', 'ide'] +['Ġmut', 'ex'] +['AG', 'IC'] +['Ġocc', 'urring'] +['ĠCommunic', 'ation'] +['um', 'ar'] +['ç¼', 'ĸ'] +['ĠTreat', 'ment'] +['.p', 'erson'] +['ĠL', 'C'] +['Ġe', 'ch'] +['(', '("'] +['ĠDise', 'ase'] +['ä', 'd'] +['ĠA', 'Z'] +['.A', 'ccount'] +['Ġcontinu', 'ously'] +['END', 'ING'] +['ĠRET', 'URN'] +['-', 'string'] +['.f', 'ilename'] +['syn', 'thesize'] +['Res', 'ponder'] +['(', 'opts'] +['reg', 's'] +['Ġn', 'uest'] +['Pe', 'er'] +['//', '------------------------------------------------'] +['Ġg', 'auge'] +['ĠK', 'in'] +['.s', 'chema'] +['Ġarr', 'ange'] +['ĠBl', 'ake'] +['_Type', 'Info'] +['C', 'over'] +['ĠHamp', 'shire'] +['P', 'aper'] +['-in', 'ner'] +['util', 'ity'] +['Ġcross', 'origin'] +['F', 'OR'] +['Ġign', 'oring'] +['ĠD', 'D'] +['av', 'an'] +['Ġtrad', 'itions'] +['Ġget', 'String'] +['Ġeth', 'ics'] +['ĠMaterial', 's'] +['DE', 'SC'] +['Ġen', 'zym'] +['io', 'let'] +['ĠCh', 'ip'] +['ĠMc', 'Donald'] +['Ġn', 'erve'] +['ç', 'Ħ'] +['")', ']'] +['æ±', 'Ĥ'] +['ĠS', 'ugar'] +['_S', 'IM'] +['j', 'peg'] +['Ġdiscret', 'ion'] +['ĠT', 'N'] +['bo', 've'] +['ĠMin', 'imum'] +['ĠForm', 'Group'] +['Ġwork', 'force'] +['ĠExec', 'ution'] +['err', 'er'] +['ĉ', 'ĠĠĠĠĉ'] +['Ġpres', 'cribed'] +['.Text', 'Align'] +['OP', 'EN'] +['ĠP', 'B'] +['im', 'ity'] +['ĠEx', 'ternal'] +['°', 'C'] +['ĠApplication', 'Controller'] +['Ġb', 'arr'] +['imp', 'licit'] +['_d', 'ot'] +['ĠCol', 'on'] +['C', 'OLOR'] +['.Pro', 'ject'] +['*', '', '}Ċ'] +['pl', 'aint'] +['get', 'Text'] +['Ġindivid', 'ually'] +['Ġcheck', 'box'] +['U', 'Y'] +['ĠL', 'amb'] +['Ġdys', 'function'] +['ĠL', 'ar'] +['à', '°'] +['ĠCre', 'ating'] +["');ĊĊ", 'Ċ'] +['"', 'They'] +['loc', 'ations'] +['_C', 'ORE'] +['Inter', 'action'] +['umbn', 'ails'] +['ĠPart', 'ner'] +['b', 'rit'] +['Ġless', 'er'] +['ĠSl', 'ot'] +['set', 'Attribute'] +['ĠW', 'ave'] +['.p', 'o'] +['/', 'store'] +['Ġbrows', 'ing'] +['_p', 'd'] +['sum', 'e'] +['s', 'ed'] +['Cur', 've'] +['Ġpl', 'asma'] +['Ġsusp', 'icious'] +['ìĿ', '¸'] +['ĠB', 'ah'] +['ĠExp', 'licit'] +['_C', 'C'] +['.Client', 'Size'] +['\\', 'View'] +['Ġsub', 'stit'] +['lo', 'on'] +['ĠG', 'AME'] +['ĠB', 'rid'] +['Ľ', '建'] +['_', 'User'] +['Ġsqu', 'ares'] +['f', 'one'] +['Ġsac', 'red'] +['ug', 'hs'] +[']', 'interface'] +['ĠTh', 'row'] +['ĠK', 'irk'] +['Ġemp', 'ire'] +['Ġassess', 'ed'] +['T', 'ax'] +['ĠHe', 'aven'] +['-b', 'uffer'] +['_STAT', 'IC'] +['én', 'é'] +['-b', 'ordered'] +['Ġpun', 'ct'] +['(m', 'ode'] +['Ġke', 'ine'] +['S', 'ent'] +['ĠCal', 'cul'] +['ĠE', 've'] +['Ġsty', 'lish'] +['Ġoil', 's'] +['.Test', 'Case'] +['Ġtrad', 'emark'] +['Ġliter', 'ary'] +['Ġconcentr', 'ations'] +['ĠRel', 'ations'] +['(', 'Class'] +['Ġstd', 'in'] +['Ġv', 'æ'] +['back', 'up'] +['.', 'VERSION'] +['.AutoScale', 'Dimensions'] +['st', 'arter'] +['Transaction', 'al'] +['-', 'panel'] +['St', 'udio'] +['k', 'c'] +['ĠCh', 'amber'] +['ĠSpi', 'el'] +['Ġr', 'ho'] +['ا', 'ÙĦ'] +['!', "'"] +['.At', 'tributes'] +['Ġmurder', 'ed'] +['apeut', 'ic'] +['Ġint', 'imate'] +['Ġtext', 'Field'] +['ĠBuff', 'alo'] +['d', 'ummy'] +['"', '%'] +['ĠLib', 'erty'] +['ob', 'ar'] +['ĠT', 'ank'] +['ĠPop', 'ular'] +['erv', 'isor'] +['ĠIn', 'iti'] +['ĠM', 'all'] +['ĠP', 'rior'] +['C', 'AP'] +['ĠCl', 'ay'] +['ĠCert', 'ificate'] +['.L', 'ock'] +['-st', 'rip'] +['-dr', 'iven'] +['/', 'all'] +['ĠMessageBox', 'Buttons'] +['_SE', 'CRET'] +['_p', 'b'] +['Ġr', 'ats'] +['ा', 'à¤'] +['Ġn', 't'] +['.R', 'outer'] +['_top', 'ic'] +['Ġt', 'ennis'] +['ĠP', 'UBLIC'] +['ĠActiv', 'atedRoute'] +["Ġ'", ',Ċ'] +['Ġcost', 'ume'] +['Ġj', 'okes'] +['.', 'Handle'] +['ĉ', 'byte'] +['Ġflav', 'ors'] +['(', 'cc'] +['Ġperson', 'as'] +['ĉ', 'image'] +['ĠN', 'azi'] +['Ġgram', 'mar'] +['Ġú', 'lt'] +['Ġval', 've'] +['Ġv', 'ic'] +['ĠR', 'achel'] +['_in', 'valid'] +['P', 'refs'] +['std', 'int'] +['(r', 'oute'] +['Ġhtml', 'specialchars'] +['Ġpe', 'oples'] +['pl', 'ine'] +['Ġn', 'v'] +['ĠQu', 'ant'] +['opp', 'ers'] +['Ġcurrent', 'User'] +['ĠC', 'atal'] +['Ġrecon', 'c'] +['Ġconj', 'unction'] +['l', 'x'] +['amb', 'urg'] +['Ġinflu', 'ential'] +['d', 'anger'] +['ind', 'ers'] +['Ġ%', '@",'] +['.config', 'uration'] +['os', 'ome'] +['.', 'identity'] +['Ġpick', 'er'] +['n', 'ost'] +['ĠDI', 'Y'] +['Aug', 'ust'] +['ab', 'lo'] +['Le', 'af'] +['ĠRec', 'o'] +['ck', 'o'] +['DO', 'C'] +['ĠH', 'erm'] +[':', 'any'] +['ĠInt', 'erview'] +['ĠT', 'ex'] +['x', 'fe'] +['(', 'work'] +['Ġle', 'ap'] +['He', 'ading'] +['Ġqu', 'arters'] +['\\', 'Bundle'] +['re', 'b'] +['Per', 'haps'] +['ĠG', 'mbH'] +['B', 'irth'] +['ĉ', 'sum'] +['ĠWat', 'son'] +['.n', 'il'] +['ç', '¡'] +['{', '}ĊĊ'] +['ica', 'id'] +['Get', 'ter'] +['"', 'name'] +['Ġ"', 'čĊ'] +['_n', 'one'] +['z', 'm'] +['ac', 'ute'] +['uest', 'o'] +['Ġs', 'ous'] +['Ġre', 'build'] +['Ġnewsp', 'apers'] +['ĠH', 'az'] +['Ġk', 'its'] +['if', 'o'] +['Bl', 'ur'] +['Ġsu', 'ited'] +['-', 'In'] +['à', '¯'] +['ĠKe', 'ith'] +['ĠNor', 'way'] +['IN', 'IT'] +['ire', 'ccion'] +['iet', 'ies'] +['_us', 'age'] +['ĠDou', 'g'] +['r', 'ise'] +['Ġtr', 'illion'] +['im', 'ited'] +['ĠR', 'EL'] +['al', 'ic'] +['Ġcritic', 'ized'] +['the', 'orem'] +['Ġce', 'ase'] +['Ġsid', 'ew'] +['ĠT', 'erry'] +['Ġsubs', 'idi'] +['Ġfirm', 'ly'] +['Ġaw', 's'] +['Ġh', 'ott'] +['Ġdress', 'ing'] +['bad', 'ge'] +['ĠApp', 'lications'] +['è¿', 'ĶåĽŀ'] +['Ġlaugh', 'ed'] +['Ġh', 'obby'] +['Ġmus', 'icians'] +['Ġ*', '.'] +['.', 'placeholder'] +['Ġcount', 'ers'] +['ĠCap', 'itol'] +['SD', 'K'] +['Ġhel', 'met'] +['and', 'box'] +['qu', 'it'] +['Ġcriminal', 's'] +['Ġteen', 'ager'] +['(', 'update'] +['G', 'l'] +['.se', 'lection'] +['Ġdis', 'charge'] +['Ġpresent', 'ing'] +['ufact', 'urer'] +['_UN', 'KNOWN'] +['Ġstress', 'ed'] +['å', 'ύ'] +['Pro', 'to'] +['_cor', 'rect'] +['ha', 'us'] +['Ġren', 'ov'] +['Ġfire', 'arms'] +['Ġtechn', 'ically'] +['-b', 'rowser'] +['Ġc', 'andy'] +['St', 'roke'] +['Ġexec', 'utor'] +['Ġocc', 'urrence'] +['ĠIP', 'v'] +['_INTER', 'FACE'] +['ĠRetrie', 've'] +['.b', 'ad'] +['Ex', 'change'] +['Nav', 'bar'] +['ĠK', 'id'] +['(get', 'ApplicationContext'] +['_ST', 'OP'] +['ĠB', 'oss'] +['List', 'eners'] +['Ġshoot', 'er'] +['ĠAl', 'b'] +['ä', 'ch'] +['Ġp', 'ix'] +['.key', 'Code'] +['al', 'one'] +['Ġabs', 'urd'] +['ĠC', 'um'] +['ĠNewton', 'soft'] +['ik', 't'] +['Ġlaugh', 'ing'] +['Ġcapital', 'ism'] +['ree', 'Node'] +['T', 'x'] +['_QU', 'ERY'] +['.S', 'leep'] +['(', 'login'] +['Web', 'Element'] +['Ġcelebr', 'ating'] +['Ġde', 'precated'] +['Ġma', 'ar'] +['Ġart', 'istic'] +['_ASS', 'OC'] +['ĠBorder', 'Radius'] +['ĉw', 'p'] +['Ġsurviv', 'ors'] +['In', 'ner'] +['-', 'red'] +['Ġprosec', 'ution'] +['_', 'pp'] +['("', '', '$'] +['Ġcomm', 'a'] +['un', 'checked'] +['graph', 'ics'] +['r', 'ors'] +['G', 'ROUND'] +['(', 'public'] +['Ġcustom', 'ized'] +['ĠArk', 'ansas'] +['ĠR', 'ew'] +['Ġexp', 'iration'] +['×', 'ķ'] +['ĠC', 'ul'] +['Ġn', 'ons'] +['.F', 'ilter'] +['Ġsen', 'ator'] +['_def', 'inition'] +['ash', 'ington'] +['ym', 'ph'] +['/', 'J'] +['Ġf', 'use'] +['ram', 'id'] +['ĠSup', 'plier'] +['Ġaut', 'ocomplete'] +['Ġ}', '),'] +['."', 'ĊĊĊ'] +['_function', 's'] +['ĉ', 'to'] +['.e', 'val'] +['ĠT', 'Object'] +['Re', 'ferences'] +['Ġhe', 'ated'] +['H', 'AL'] +['Ġ))', '}Ċ'] +['}', '$'] +['ĠB', 'arr'] +['_UN', 'IT'] +['+', '$'] +['Ġget', 'Value'] +['ip', 'ed'] +['ch', 'ied'] +['(v', 'm'] +['c', 'ue'] +['_int', 'eger'] +['_c', 'ourse'] +['th', 'ird'] +['Ġrevis', 'ed'] +['**', '/Ċ'] +['_D', 'IRECT'] +['Out', 'Of'] +['("', '('] +['ĠFe', 'el'] +['Ġre', 'ass'] +['Ġsub', 'title'] +['per', 'i'] +['n', 'f'] +['Ġenjo', 'ys'] +['Ġtreat', 's'] +[')', 'this'] +['-t', 'abs'] +['anc', 'ers'] +['Ġcontin', 'ent'] +['Ġcard', 'io'] +['S', 'er'] +['.', 'question'] +['Ġph', 'rases'] +['Valid', 'ators'] +['Ġpop', 'ul'] +['Ġl', 'ÃŃ'] +['s', 'ong'] +['_IN', 'TERNAL'] +['Ġadvis', 'er'] +['Ġp', 'uzz'] +['Ġambit', 'ious'] +['ĠT', 'ob'] +['ĠD', 'P'] +['Ġpres', 'idency'] +['Ġsurre', 'nder'] +['Ġwatch', 'es'] +['_b', 'inary'] +['ĠSo', 'on'] +['Ġcan', 'ada'] +['("', '")Ċ'] +[']', "='"] +['ĠBr', 'andon'] +['eps', 'ilon'] +['r', 'w'] +['.add', 'Child'] +['.C', 'opy'] +['Pr', 'incipal'] +['Ph', 'otos'] +['Ġmarg', 'inal'] +['Ġbas', 'ics'] +['e', 'ing'] +['M', 'ust'] +['_', 'String'] +['Ġo', 'le'] +['M', 'agento'] +['.c', 'ustomer'] +['(p', 'rev'] +['à¸', '¥'] +['Ġlo', 'yalty'] +['C', 'og'] +['Ġprot', 'ocols'] +['ĠCom', 'panies'] +['Ġtheoret', 'ical'] +['Ġaccess', 'ing'] +['ĠZ', 'en'] +['.', 'ones'] +['att', 'ice'] +['_w', 'orld'] +['z', 'es'] +['Ġtatto', 'o'] +['Ġmen', 'os'] +['Ġinter', 'sect'] +['"]', ';ĊĊ'] +['bel', 'ie'] +['Ġin', 'active'] +['.read', 'line'] +['-label', 'led'] +['.d', 'one'] +['lick', 'r'] +['ĠW', 'ORK'] +['Ġderiv', 'ative'] +['Ġd', 'atabases'] +['âĤ', 'Ĥ'] +['Ġs', 'x'] +['.is', 'Array'] +['Ġy', 's'] +['Ġp', 'ada'] +['ĠBul', 'let'] +['(`', '/'] +['is', 'Active'] +['ĠCG', 'Size'] +['(equal', 'To'] +['ĠColum', 'bus'] +['Ġmar', 'ry'] +['DE', 'V'] +['_l', 'imits'] +['ron', 'es'] +['I', 'AS'] +['Ġt', 'au'] +['min', 'o'] +['_W', 'rite'] +['ĠW', 'ine'] +['Ġ[', "['"] +['ĠP', 'ull'] +['rit', 'ers'] +['ri', 'ents'] +['Ġsh', 'ifting'] +['up', 'p'] +['_TIM', 'ER'] +['ĠCondition', 's'] +['áº', '¥'] +['ĠOr', 'ders'] +['ĠSt', 'rength'] +['æī', 'Ģ'] +['Ġvalid', 'ity'] +['Ġf', 'ot'] +['et', 'ur'] +['Ġb', 'olt'] +['åĨ', 'ħ'] +['ĠAl', 'ong'] +['os', 'hi'] +['Ġassum', 'ptions'] +['Ġmag', 'azines'] +['_S', 'PI'] +['Ġp', 'unt'] +['_PRO', 'DUCT'] +['Ġrel', 'ay'] +['ĠJ', 'avascript'] +['.', 'te'] +['-', 'es'] +['Ġwidget', 's'] +['(f', 's'] +['<', 'Item'] +['_ex', 'tra'] +['Ġrecru', 'iting'] +['E', 't'] +['Ġnecess', 'ity'] +['p', 'w'] +['Ġnov', 'els'] +['uss', 'els'] +['Cre', 'ator'] +['ĠM', 'VP'] +['ĠO', 'C'] +['th', 'ood'] +['cl', 'ients'] +['))', '*'] +['Ġcharacter', 'ized'] +['_SE', 'ND'] +['ut', 'i'] +['T', 'y'] +['.from', 'Json'] +['@', 'Service'] +['ãĤ', 'Ĥ'] +['Ch', 'ris'] +['_', 'Is'] +['ĠJohn', 'ny'] +['Ġclean', 'er'] +['ĠInitial', 'izes'] +['UN', 'K'] +['(', 'axis'] +['еÐ', '·'] +['ie', 'val'] +['ĠWar', 'riors'] +['}', ')('] +['DM', 'I'] +['âĻ', 'Ģ'] +['ĠTre', 'asury'] +['Ġfe', 'as'] +['Ġsl', 'a'] +['_EN', 'UM'] +['l', 'hs'] +['ĠIn', 'stit'] +['ipp', 'ers'] +['Line', 'ar'] +['Re', 'ading'] +['quir', 'ies'] +['-c', 'ell'] +['ch', 'rome'] +['.S', 'earch'] +['IN', 'A'] +['ç±»', 'åŀĭ'] +['ĠĊ', 'ĠĊ'] +['ĠSam', 'uel'] +['Ġmill', 's'] +['Ġdon', 'ate'] +['ĠGe', 'o'] +['(', 'rows'] +['Ġshe', 'ep'] +['Ġé', 'l'] +['ä½', 'ĵ'] +['Ġb', 'em'] +['_UN', 'USED'] +['ĠR', 'CC'] +['Ġintrodu', 'cing'] +['att', 'a'] +['ĠP', 'riority'] +['ĠF', 'B'] +['ĠSer', 'ge'] +['>', '";'] +['atch', 'ing'] +['ĠKnow', 'ledge'] +['ĉ', 'The'] +[';', 'margin'] +['less', 'ness'] +['op', 'ard'] +['um', 'atic'] +['()', '));čĊ'] +['Ġf', 'als'] +['(c', 'ache'] +['Type', 'Id'] +['éĢ', 'ļ'] +['_', 'choice'] +['ĠGo', 'th'] +['ĠS', 'ites'] +['M', 'G'] +['_b', 'order'] +['Ind', 'ices'] +['Compar', 'er'] +['ĠRed', 'istribution'] +['Ġclo', 'set'] +['Ġvers', 'atile'] +['Input', 's'] +['****************', '****'] +['Ġob', 'esity'] +['qu', 'iz'] +['gr', 'a'] +['(g', 'lobal'] +['åĬ', '¡'] +['Ġcollect', 'or'] +['Ġk', 'or'] +['ov', 'able'] +['AD', 'C'] +['ĠEvent', 'Handler'] +['.', 'nc'] +['Ġplay', 'back'] +['ient', 'os'] +['_p', 'erm'] +['_W', 'ARNING'] +['ĠOlymp', 'ics'] +['.n', 'orm'] +['ĠBroad', 'cast'] +['_sm', 'all'] +['dr', 'ive'] +['.', 'iloc'] +['Ġtyp', 'ed'] +['M', 'EM'] +['_con', 's'] +['DM', 'ETHOD'] +['Ġl', 'un'] +['.d', 'istance'] +['(p', 'ar'] +['po', 'on'] +['Ġb', 'ast'] +['activ', 'ities'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +[':', 'čĊčĊ'] +['S', 'ER'] +[')', '&&'] +['_l', 'st'] +['ĠPol', 'ish'] +['Ġknock', 'ed'] +['Ġfrustr', 'ation'] +['au', 'kee'] +['Ġph', 'osph'] +['iqu', 'id'] +['_c', 'oeff'] +['æŃ', '¤'] +['L', 'atest'] +['ĠD', 'ust'] +['T', 'ipo'] +['Ġmaint', 'ains'] +['Ġmar', 'sh'] +['inc', 'inn'] +['l', 'bl'] +['C', 'are'] +['Ġneighborhood', 's'] +['_g', 'pio'] +['ĠAr', 'senal'] +['D', 'em'] +['ĠW', 'he'] +['_h', 'ook'] +['Ġl', 'dc'] +['ĠHar', 'per'] +['ĠBer', 'keley'] +['Ġgrad', 'uated'] +['Per', 'cent'] +['Ġarr', 'iving'] +['ĠAdvent', 'ure'] +['(s', 'cope'] +["('", '*'] +['qu', 'arter'] +['ĠMar', 'ie'] +['Spe', 'aking'] +['_code', 'gen'] +['Ġimm', 'un'] +['c', 'aster'] +['ãĤ', 'Į'] +['åķ', 'Ĩ'] +['ĠDim', 'ensions'] +['.rec', 'ord'] +['Ġtext', 'o'] +['ĠMich', 'elle'] +['P', 'ending'] +['(', 'by'] +['_P', 'AR'] +['uch', 't'] +['be', 'e'] +['.Th', 'read'] +['amp', 'ire'] +['k', 'now'] +['ĠClin', 'ical'] +['Ġmargin', 'Bottom'] +['Ġdistingu', 'ish'] +['.F', 'ull'] +['.', 'undefined'] +['ĠSequ', 'elize'] +['################################################################', '############'] +['Ġeduc', 'ated'] +['_O', 'VER'] +['åº', 'ı'] +['ĠÂł', 'ĠÂł'] +['_e', 'ach'] +['Ġur', 'ge'] +['de', 'part'] +['Ġdon', 'ors'] +['ĠA', 'u'] +['Ġbill', 'ions'] +['Ġbelong', 'ing'] +['_', 'age'] +['_', 'Int'] +['Ġsub', 'stances'] +['m', 'achine'] +['!!', '!ĊĊ'] +['Ġjson', 'ify'] +['ib', 'bean'] +['ĠC', 'ad'] +['Ġend', 'Time'] +['Ġc', 'ycling'] +['ĠUIT', 'extField'] +['Ġle', 'verage'] +['Ġvan', 'illa'] +['e', 'at'] +['La', 'unch'] +['(', 'pt'] +['st', 'ates'] +['ĠControl', 's'] +['ĠRes', 'pons'] +['ĠJ', 'ake'] +['Ġas', 'leep'] +['fort', 'unate'] +['.next', 'Line'] +['Size', 'Mode'] +['ìĿ', '¼'] +['Testing', 'Module'] +['G', 'erman'] +['ĠInvest', 'ig'] +['.re', 'verse'] +['ĠB', 'ACK'] +['(', 'DateTime'] +['Ġnon', 'profit'] +['ĠEx', 'pect'] +['Ġt', 'anto'] +["']", '),'] +['ĉ', 'the'] +['M', 'ultiple'] +['(get', 'Activity'] +['_W', 'AIT'] +['Ġj', 'á'] +['de', 'cor'] +['lev', 'ance'] +['ĠGit', 'Hub'] +['min', 'ation'] +['_qu', 'antity'] +['.Sc', 'anner'] +['ĠL', 'ion'] +['éĶĻ', '误'] +['Ġd', 're'] +['Ġtan', 'tra'] +['Ġcontent', 'Type'] +['Ġf', 'id'] +['_', 'alt'] +['NS', 'IndexPath'] +['-', 'pl'] +['åĮ', 'ĸ'] +['Ġantib', 'iot'] +['table', 's'] +['ac', 'ial'] +['ĠReg', 'istry'] +['Ġol', 'ive'] +['ig', 'ers'] +['Ġsubscri', 'ber'] +['_p', 'res'] +['ĠSy', 'ntax'] +['Ġlo', 'vers'] +['.', 'Byte'] +['old', 'ers'] +['_for', 'ward'] +['al', 'ways'] +['C', 'aption'] +['Pr', 'iv'] +['ĠT', 'ampa'] +['is', 'ateur'] +['-labelled', 'by'] +['ĠTo', 'String'] +['Ġì', 'Ĥ¬'] +['Ġinit', 'iated'] +['W', 'F'] +['Ġinstitution', 'al'] +['in', 'ject'] +['ĠSc', 'r'] +['Ġdo', 'ctrine'] +['Ġsp', 'acious'] +['is', 'ure'] +['ĠAn', 'a'] +['"', 'time'] +['ess', 'aging'] +['Ġc', 'id'] +['ĠN', 'an'] +['Ġin', 'complete'] +['T', 'AG'] +['-b', 'uild'] +['Dec', 'ember'] +['Ġres', 'idual'] +['(P', 'DO'] +['ĠList', 'en'] +['Ġg', 'lyph'] +['Ġg', 'aps'] +['ne', 'a'] +['.R', 'ect'] +['Ġsa', 'u'] +['ĠPhot', 'ograph'] +['Ġexec', 'utable'] +['ĠExp', 'ert'] +['Cor', 'outine'] +['_s', 'izes'] +['ĠN', 'L'] +['.is', 'Valid'] +[');', '}Ċ'] +['-', 'reg'] +['Ġc', 'iting'] +['c', 'wd'] +['ĠOtt', 'awa'] +['ĠB', 'att'] +['Ġrenew', 'able'] +['Ġprelim', 'inary'] +['Ġas', 'ylum'] +['Ġw', 'rist'] +['Ġutil', 'iz'] +['Ġdet', 'ention'] +['F', 'ast'] +['Ġan', 'ge'] +['incinn', 'ati'] +['Ġste', 'ering'] +['ĠNa', 'N'] +['ios', 'ity'] +['/', 'page'] +['Ġè', '¿'] +['ster', 'ol'] +['Ġdis', 'g'] +['(', 'DB'] +['ĠDESC', 'RIPTION'] +['Ġ_', '$'] +['Ġobst', 'acle'] +['Ġb', 'izarre'] +['Ġextr', 'action'] +['_ex', 'pected'] +['Ġlos', 'es'] +['ĠCele', 'br'] +['Ġhtml', 'For'] +['Ġexplo', 'it'] +['олÑĮз', 'ов'] +['XY', 'Z'] +['Ġmagn', 'et'] +['amp', 'ed'] +['Ġat', 'oms'] +['S', 'ources'] +['pect', 'ives'] +['Ñģ', 'ли'] +['Ġ=', 'čĊ'] +['Ġd', 'are'] +['ĠWal', 'ter'] +['Ġbright', 'ness'] +['Ġan', 'notations'] +['ë', 'ı'] +['is', 'ke'] +['S', 'chedule'] +['.', 'images'] +['ros', 'so'] +['Ġ"', '..'] +['g', 'amma'] +['Ġin', 'structor'] +['Ġover', 'write'] +['-', 'am'] +['Ġdevast', 'ating'] +['ĠSaint', 's'] +['Ġh', 's'] +['Ġbon', 'uses'] +['$', 'output'] +['ij', 'd'] +['(Action', 'Event'] +['mon', 'itor'] +['Ġmatt', 'ress'] +['Jan', 'uary'] +['.j', 'p'] +['Ġcar', 'acter'] +['Ġim', 'pose'] +['_re', 'st'] +['ĠSign', 'ature'] +['Ġcoron', 'avirus'] +['ãģ', 'Ĭ'] +['_com', 'pare'] +['Me', 'asure'] +['it', 'ated'] +['el', 'ijk'] +['ig', 'os'] +['es', 'ar'] +['Ġrush', 'ed'] +['met', 'ry'] +['_SE', 'PARATOR'] +['_W', 'E'] +['_ATTR', 'IBUTE'] +['Ġy', 'aml'] +['Ġspec', 's'] +['ĠR', 'ah'] +['ph', 'eric'] +['ĠInvest', 'ment'] +['ä', 'll'] +['Ġappe', 'aling'] +['Ġview', 'port'] +['ç', '©'] +['Ġmargin', 'Left'] +['Ġsub', 'tract'] +['ĠED', 'IT'] +['ĉ', 'ArrayList'] +['gr', 'ading'] +['ĠF', 'ailure'] +['as', 'per'] +['EE', 'K'] +['(n', 'ow'] +['<', 'object'] +['ĠAl', 'ignment'] +['ple', 'ado'] +['q', 'tt'] +['(', 'ERROR'] +['ĠIN', 'VALID'] +['Ġuser', 'id'] +['ra', 'ises'] +['ID', 'I'] +['Ġvari', 'ance'] +['ĠN', 'il'] +['/', 'delete'] +['_M', 'AIN'] +['.T', 'oken'] +['.C', 'ategory'] +['>', ')Ċ'] +['Coll', 'ision'] +['ĠGre', 'ater'] +['ĠR', 'acing'] +['al', 'an'] +['Ġmon', 'etary'] +[',', 'new'] +['ĠS', 'orry'] +['.', 'Enable'] +['ĠInstant', 'iate'] +['oll', 'en'] +['ë©', '´'] +['ĠCall', 'ing'] +['_h', 'our'] +['AD', 'A'] +['Ġsh', 'y'] +[')', '**'] +['Ġ==', '>'] +['Ġes', 'pecial'] +['Ġinterpre', 'ted'] +['!', '="'] +['Ġpharm', 'acy'] +['.s', 'ingle'] +['ĠC', 'ialis'] +['Ġpar', 'as'] +['.to', 'UpperCase'] +['ĠDem', 'on'] +['Pr', 'ime'] +['Ġrank', 'ings'] +['Add', 'ing'] +['_H', 'ASH'] +['ĠEx', 'am'] +['Ú', '©'] +['ĠVict', 'or'] +['Ok', 'ay'] +['"]', ';čĊ'] +['Ġfort', 'une'] +['ĠF', 'ETCH'] +['exp', 'and'] +['.Inter', 'op'] +['Ġb', 'arn'] +['æ', '¶Ī'] +['ue', 'vo'] +['Ġspec', 'ulation'] +['âĶĢâĶĢ', 'âĶĢâĶĢ'] +['ĠN', 'u'] +['ĠBl', 'ues'] +['(f', 'name'] +['Ġinhab', 'it'] +['Ġ\\"', '%'] +['C', 'ES'] +['ular', 'io'] +['_c', 'r'] +['Ġvalid', 'ated'] +['Ġmid', 'night'] +['ank', 'ing'] +['Ġincorpor', 'ate'] +['Ġpurs', 'uit'] +['EX', 'P'] +['pr', 'ime'] +['P', 'id'] +['-', 'US'] +['ĠN', 'urs'] +['ĠW', 'heel'] +['é', 'ĺ'] +['Ġin', 'p'] +['Ġsupport', 'ive'] +['.m', 'ember'] +['ĠSh', 'ot'] +['.Check', 'Box'] +['Ġaff', 'irm'] +['T', 'or'] +['Full', 'Year'] +['Ġconsider', 'ably'] +['cred', 'entials'] +['_', 'opts'] +['R', 'oll'] +['(', 'round'] +['Ġcom', 'ent'] +['_U', 'ART'] +['Ġext', 'ending'] +['R', 'G'] +['result', 'ado'] +['it', 'u'] +['.get', 'Session'] +['Ġattr', 'action'] +['&', 'D'] +['$', 'html'] +['ĠJess', 'ica'] +['ĠAssoci', 'ate'] +['a', 'ñ'] +['_', 'ed'] +['ĠL', 'ag'] +['Ġorig', 'ins'] +['())', '->'] +['add', 'EventListener'] +['IAL', 'OG'] +['åIJ', '¦'] +['.Com', 'pare'] +['Al', 'bum'] +['ĠK', 'u'] +['<', 'Q'] +['arg', 'est'] +['Ġpro', 'long'] +['Ġconfig', 'urations'] +['Ġaccident', 'ally'] +['_ph', 'oto'] +["Ġ''", ';čĊ'] +['Ġver', 'se'] +['B', 'ob'] +['Ġfarm', 'ing'] +['del', 'ivery'] +['ĠM', 'ack'] +['Ġuse', 'Selector'] +['.bootstrap', 'cdn'] +['keep', 'ing'] +['en', 'y'] +['.', 'upload'] +['ĠM', 'ETHOD'] +['cre', 'ator'] +['<', '_'] +['ĠE', 'aster'] +['.', '--'] +['UI', 'Button'] +['ãĤ', 'ī'] +['om', 'eters'] +['Ġsh', 'ine'] +['Ġh', 'ogy'] +['\\', 's'] +['Ġh', 'arness'] +['.C', 'ell'] +['Ġlif', 'ting'] +['Ġcomb', 'ines'] +['ĠOcc', 'up'] +['ex', 'clude'] +['pat', 'ial'] +['Ġres', 'pir'] +['_f', 'it'] +['Ġfif', 'ty'] +['ĠM', 'ol'] +['Ġtun', 'ed'] +['-d', 'imensional'] +['Ġq', 's'] +['Ġto', 'ps'] +['>', '";ĊĊ'] +['quis', 'ite'] +['ch', 'annels'] +['/', 'res'] +['ĠAn', 'alytics'] +['.app', 'compat'] +['/', 'to'] +['Ġon', 'Error'] +['(', 'attr'] +['IR', 'M'] +['Ġrag', 'az'] +['-', 'as'] +['.Se', 'cond'] +['orient', 'ed'] +['Ġdon', 'n'] +['Ġlight', 'ning'] +['f', 'id'] +['ĠP', 'le'] +['ãģ¾', 'ãģĻ'] +['t', 'ro'] +['.Tr', 'ue'] +['O', 'bservable'] +['×', 'Ļ'] +['umb', 'ing'] +['Ġpros', 'pective'] +['-f', 'ilter'] +['Ġpurs', 'uant'] +['(p', 'oints'] +['.B', 'ind'] +['Ġp', 'alm'] +['clear', 'fix'] +['ö', 's'] +['ĠG', 'onz'] +['Ġwe', 'aken'] +['Dr', 'ive'] +['en', 'ido'] +['l', 'ld'] +['ob', 'ox'] +['ane', 'an'] +['G', 'ot'] +['ä¿', 'Ŀ'] +['Reg', 'ex'] +['æ', 'ĥ'] +['Ġsal', 'ad'] +['ass', 'is'] +['"', 'net'] +['inherit', 'Doc'] +['ĠR', 'V'] +['qu', 'ier'] +['Ġcl', 'azz'] +['ı', 'ÅŁ'] +['oster', 'one'] +['Ġair', 'line'] +['.list', 'dir'] +['Ġdownload', 'ing'] +['ĠP', 'alm'] +['w', 'aukee'] +['&', 'lt'] +['.B', 'L'] +['_IN', 'LINE'] +['off', 's'] +['<<', '('] +['_new', 's'] +['Ġch', 'ase'] +['/', '><'] +['Ġeuro', 's'] +['ĠEgypt', 'ian'] +['ĠSt', 'ainless'] +['_BO', 'OL'] +['ĠG', 'uild'] +['ĠD', 'ynam'] +['[index', 'Path'] +['Ġ', 'ï'] +['Ġmemor', 'able'] +['ĠCh', 'ampion'] +['Resource', 'Manager'] +['.Log', 'in'] +['ĠForm', 'er'] +['yp', 'ed'] +['Ġl', 'leg'] +[';', '",'] +['D', 'WORD'] +['Ġtax', 'i'] +['Ġbom', 'bs'] +['ra', 'h'] +['.t', 'ags'] +['_test', 's'] +['st', 'ones'] +['âĢĿ', ')'] +['[', 'g'] +['r', 'type'] +['Ġv', 'u'] +['Ġhost', 'ile'] +['Ch', 'ars'] +['ĠPatri', 'ots'] +['/', 'status'] +['<', 'B'] +['ĠIn', 'come'] +['ĠD', 'ad'] +['Ġpat', 'rol'] +['_CH', 'ANGE'] +['Ġup', 'graded'] +['Ġch', 'ina'] +['set', 'q'] +['Start', 'ed'] +['.U', 'ndef'] +['Ġcheck', 'sum'] +['Ġfrustr', 'ated'] +['{', 'o'] +['Ġen', 'f'] +['Ġwood', 's'] +['ĠAny', 'one'] +['Enc', 'ode'] +['ĠQt', 'Widgets'] +['are', 'as'] +['Ġshe', 'er'] +['sk', 'i'] +['end', 'point'] +['_T', 'est'] +['S', 'oup'] +['~~~~~~~~', '~~~~~~~~'] +['(f', 'iles'] +['ĉĉĉĉĉ', 'čĊ'] +['.sp', 'ark'] +['Ġval', 'ued'] +['Ġ%', 'Ċ'] +['.control', 's'] +['ĠXCTAssert', 'Equal'] +['Ġf', 'ame'] +['ĠR', 'ic'] +['D', 'OT'] +['ĠAlbert', 'a'] +['ä½', '¿'] +['os', 'al'] +['.Web', 'Controls'] +['Ġ', '------------'] +['ĠM', 'is'] +['ĠS', 'YS'] +['Non', 'null'] +['=', 'item'] +['Ġexp', 'ire'] +['Dec', 'ode'] +['_', 'operation'] +['ĠValid', 'ator'] +['.C', 'ENTER'] +['uff', 's'] +['*', 'm'] +['Ġav', 'ant'] +['æ¬', '¡'] +['âĢľ', 'You'] +['.per', 'mission'] +['...', ')'] +['ĠL', 'ic'] +['_co', 'ords'] +['.n', 'ombre'] +['c', 'lo'] +['.Int', 'ernal'] +['ĠCh', 'o'] +['_s', 'w'] +['ĉ', 'Il'] +['cl', 'k'] +['Ġcast', 'le'] +['(l', 'ayer'] +['p', 'it'] +['Ġgu', 'ided'] +['Ġâĸ', 'Ī'] +['Ġsuper', 'b'] +['Ġsup', 'plements'] +['_c', 'ent'] +['Ġpe', 'ek'] +['IN', 'ARY'] +['.Content', 'Alignment'] +['f', 'alls'] +['"))', ';'] +['W', 'all'] +[').', 'čĊ'] +['ĠD', 'anny'] +['irm', 'ingham'] +['IAL', 'IZ'] +['(', 'create'] +['"', 'In'] +['Service', 'Provider'] +['Ġpr', 'iced'] +['mac', 'ro'] +['am', 'ac'] +['.', 'box'] +['----', 'Ċ'] +['ãĥ', '«'] +['ĠS', 'uit'] +['ur', 'st'] +['br', 'u'] +['ourn', 'als'] +['num', 'ero'] +['__', '()Ċ'] +['D', 'as'] +['ĠM', 'itt'] +['ud', 'er'] +['?', '\\'] +['f', 'u'] +['[', 'B'] +['Ġ:', ')ĊĊ'] +['(int', 'er'] +['br', 'ains'] +['Ġatt', 'itudes'] +['Ver', 'ify'] +['Ġsign', 'atures'] +['ack', 'Bar'] +['Ġg', 'd'] +['J', 'ack'] +['.c', 'at'] +['Ġz', 'z'] +['war', 'f'] +['FT', 'ER'] +['");ĊĊ', 'Ċ'] +['Al', 'ive'] +['IC', 'LE'] +['ĠWh', 'atever'] +['Ġout', 'lined'] +['s', 'prite'] +['еÐ', '²'] +['_A', 'B'] +['_DE', 'PTH'] +['Ġcrush', 'ed'] +['aa', 'a'] +['(e', 'v'] +['æľ', 'º'] +['Ant', 'i'] +['IC', 'O'] +['is', 'EqualTo'] +['.s', 'un'] +['ic', 'ulo'] +['s', 'ale'] +['_h', 'ex'] +['ĠV', 'k'] +['apt', 'or'] +['Un', 'ion'] +['ĠDis', 'count'] +['list', 'a'] +['.Undef', 'Or'] +['Ġautom', 'ation'] +['N', 'or'] +['å¯', '¹'] +['åı', 'Ĥæķ°'] +['Ġref', 'lex'] +['ĠLa', 'ure'] +['.showMessage', 'Dialog'] +['.t', 'emp'] +['Ġa', 'kan'] +['Ġ__', '____'] +['.Is', 'True'] +['ARE', 'D'] +['ag', 'le'] +['E', 'nergy'] +['Ġquant', 'ities'] +['âĢĻ', 'é'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġcitizens', 'hip'] +['m', 'outh'] +['Ġin', 'appropriate'] +['ĠOut', 'door'] +['White', 'Space'] +['An', 'onymous'] +['load', 's'] +['webElement', 'Properties'] +['T', 'en'] +['Ġacc', 'idents'] +['Ġadvertis', 'ement'] +['ĠY', 'emen'] +['(c', 'all'] +['Ġsl', 'avery'] +['Ñģ', 'п'] +['ĠL', 'am'] +['_BIT', 'S'] +['ome', 'ga'] +['ĠO', 'le'] +['Ġkid', 'n'] +['_A', 'n'] +['ĠR', 'aid'] +['Cre', 'ation'] +['s', 'aved'] +['Ġpro', 'port'] +['W', 'ARNING'] +['\\', 'P'] +['Ġp', 'wd'] +['Data', 'Reader'] +['is', 'cher'] +['ade', 'on'] +['ĠP', 'redict'] +['Ġreason', 'ing'] +['Ġdestroy', 'ing'] +['H', 'el'] +['*', 'd'] +['ĠLeg', 'isl'] +['_P', 'r'] +['ĉĉĉ', 'ĠĠĠĠĠĠĠ'] +['Ġsymp', 'ath'] +['Ġch', 'ess'] +['Ġm', 'am'] +[':', 'hover'] +['Ġconvert', 's'] +['Ġp', 'ela'] +['Ġprogress', 'ion'] +['Ġ"_', '"'] +['ĠG', 'ill'] +['ĉ', 'show'] +['Ġsupposed', 'ly'] +['ac', 'curacy'] +['el', 'in'] +['Ġunf', 'olding'] +['ĠHy', 'per'] +['Ġw', 'anna'] +['Ġup', 's'] +['(', '#'] +['ĠCr', 'iminal'] +['(', 'Point'] +['at', 'Lng'] +['act', 'ly'] +['Ġcontract', 'ors'] +["']", '}'] +['draul', 'ic'] +['ód', 'igo'] +['ĠT', 'T'] +['ĠW', 'ide'] +['ĠAR', 'G'] +['_', 'ic'] +['FLAG', 'S'] +['S', 'chool'] +['Ġclear', 'ing'] +['-be', 'ing'] +['={', '['] +[',', 'const'] +['man', 'ent'] +['Over', 'lay'] +["('", '"'] +['éĩ', 'ı'] +['ĠT', 'imestamp'] +['Ġmail', 'ing'] +['ĠC', 'ake'] +['.Th', 'at'] +['Ġmed', 'itation'] +['q', 'p'] +['Ġemp', 'resa'] +['ĠL', 'ions'] +['Ġw', 'eld'] +['ĠLinked', 'In'] +['Ġc', 'ush'] +['Ġgen', 'ome'] +['.Index', 'Of'] +['ag', 'ain'] +['Ġf', 'allback'] +['Ġcamp', 'ing'] +['re', 'dd'] +['-strip', 'ed'] +['Ġd', 'v'] +['Fe', 'bruary'] +['ĠPro', 'xy'] +['us', 'k'] +['Ġdies', 'el'] +['W', 'RITE'] +['RE', 'AK'] +['L', 'orem'] +['.In', 'voke'] +['-', 'div'] +['Inter', 'ceptor'] +['ĠD', 'H'] +['ia', 'les'] +['Ġvill', 'ages'] +['Ø', '´'] +['ĠEN', 'V'] +['S', 'ys'] +['.X', 'R'] +['Ġpo', 'em'] +['Ã', 'Ĥ'] +['c', 'ade'] +['pl', 'ots'] +['Ġ{', '('] +['.g', 'it'] +['/s', 'vg'] +['nc', 'mp'] +['ĠÄ', 'į'] +['ain', 'es'] +['åĩ', '½æķ°'] +['Ġ(', ')ĊĊ'] +['ops', 'is'] +['ĠRel', 'ationship'] +['_', 'aut'] +['ĠB', 'omb'] +['ĉ', 'com'] +['*', 'sizeof'] +['off', 'icial'] +['_p', 'ayload'] +['ĉĉĉĉĉ', 'ĠĠ'] +['.m', 'anager'] +['ĠA', 'round'] +['ĉs', 'end'] +['ĠEx', 'ercise'] +['ĠB', 'illy'] +['iv', 'i'] +['Ġneed', 'ing'] +['_url', 's'] +['_t', 'asks'] +['ĠH', 'em'] +['Ġtear', 'Down'] +['enc', 'rypt'] +['.t', 'ie'] +['Ġas', 'm'] +['IC', 'H'] +['ĠCGRect', 'Make'] +['ìĦ', '±'] +['ul', 'ong'] +['Ġit', 'r'] +['ĠG', 'ST'] +['Ġoffer', 'ings'] +['ro', 'be'] +['EE', 'E'] +['oper', 'ators'] +['_PRO', 'P'] +['ind', 'ent'] +['A', 'DE'] +['or', 'f'] +['ë', 'IJ'] +['Ġbless', 'ed'] +['vas', 'cular'] +['Ġcon', 'oc'] +['H', 'appy'] +['B', 'ridge'] +['ilit', 'ation'] +['j', 'oint'] +['ĠAdmin', 'istr'] +['-', 'transform'] +['Ġmeant', 'ime'] +['/', 'K'] +['ĠBed', 'room'] +['Ġrig', 'id'] +['Ġbrows', 'ers'] +['EM', 'PTY'] +['.S', 'erialize'] +['_', 'ED'] +['Ġst', 'itch'] +['Ġj', 'an'] +['ell', 't'] +['Ġbr', 'ace'] +['Ġtr', 'ails'] +['p', 'ublished'] +['å¯Ĩ', 'çłģ'] +['}', "')Ċ"] +['Ġac', 'ids'] +['Ġ!', '!!'] +['_d', 'irect'] +['>', '());Ċ'] +['aj', 'Äħ'] +['_O', 'CC'] +['Ġplan', 'ets'] +['æ', 'Ł¥'] +['ĠDub', 'lin'] +['Ġser', 'ie'] +['.print', 'f'] +['de', 'ep'] +['`', ')'] +['Ġ\\', '$'] +['ĠÎ', '¼'] +['_V', 'IDEO'] +['end', 'ors'] +['ĠC', 'rypto'] +['F', 'ar'] +['.Trans', 'parent'] +['.T', 'R'] +['ias', 'm'] +['_tr', 'aining'] +['Ġteach', 'es'] +['ĠB', 'elt'] +['Ġlimit', 'ing'] +['ĠK', 'ath'] +['ĠIndex', 'Path'] +['Ġachie', 'vements'] +['Ġser', 'á'] +['interop', 'Require'] +['Ġdis', 'se'] +['.I', 'f'] +['arm', 'ing'] +['uls', 'ion'] +['P', 'o'] +['_DE', 'TAIL'] +['Prot', 'otype'] +['ĠC', 'AL'] +['Ġagre', 'es'] +['.v', 'o'] +['.Execute', 'NonQuery'] +['ĠTop', 'ic'] +["Ġ'", '{}'] +['Ar', 'm'] +['Ġe', 'cc'] +['M', 'ag'] +['Ġserial', 'ized'] +['ĉ', 'conn'] +['c', 'ached'] +['=', 'tf'] +['ĠByte', 'Array'] +['prot', 'obuf'] +['var', 'char'] +['ĉ', 'ASSERT'] +['Ġlist', 'e'] +['_tr', 'igger'] +['·', '¸'] +['Fe', 'el'] +['T', 'ahoma'] +['ĠL', 'ik'] +['Ġstruct', 'ured'] +['erg', 'us'] +['.In', 'itial'] +['_', 'ge'] +['cl', 'js'] +['.cont', 'act'] +['Ġand', 'ere'] +['$', 'stmt'] +['_C', 'URRENT'] +['ĠDis', 'cover'] +['$', 'res'] +['form', 'atter'] +['H', 'a'] +['vang', 'st'] +['Ġem', 'erge'] +['ãĢĤ', 'âĢĿ'] +['ĠCabin', 'et'] +['-s', 'quare'] +['éĥ', '¨'] +['Ġr', 'age'] +['ĠA', 'J'] +['ĠV', 'T'] +['sh', 'adow'] +['ĠFa', 'ith'] +['en', 'ames'] +['pret', 'ty'] +['has', 'il'] +['part', 'y'] +['Ġvar', 'char'] +['Ġf', 'otos'] +['Ġal', 'um'] +['ĠBelg', 'ium'] +['.y', 'label'] +['Ġde', 'j'] +['_num', 'bers'] +['Ġh', 'u'] +['.set', 'Adapter'] +['ĠUs', 'ually'] +['(s', 'ample'] +['.Sh', 'ared'] +['Ġbook', 'ed'] +['Ġ>>', '='] +['Ġmin', 'erals'] +['">'] +['pro', 'g'] +['bo', 'o'] +['_m', 'd'] +['_p', 'ack'] +['(ex', 'press'] +['ut', 'z'] +['\\', 'Auth'] +[',', 'id'] +['ĠCh', 'ile'] +['act', 'ice'] +['Ġrecruit', 'ment'] +['Ġpos', 'es'] +['Ġvulner', 'ability'] +['inst', 'anc'] +['or', 'um'] +['d', 'ess'] +['Ġx', 'l'] +['%%%%%%%%%%%%%%%%', '%%%%%%%%%%%%%%%%'] +['(', 'fig'] +['Ġdelet', 'ing'] +['.d', 'el'] +[')', "')Ċ"] +['ĠWeek', 'ly'] +['??', '?'] +['(str', 'cmp'] +['sm', 'ith'] +['Ġpurs', 'uing'] +['-', 'so'] +['ĠApp', 's'] +['/', "'Ċ"] +['Ġdec', 'is'] +['FO', 'RE'] +['Every', 'one'] +['Ġl', 'anes'] +['V', 'irtual'] +['.', 'attach'] +['(', 'Log'] +['ĠMed', 'icaid'] +['(', 'Path'] +['ĠTurn', 'er'] +['/', 'application'] +['Ġport', 'rait'] +['Ġopp', 'ose'] +['check', 'out'] +['Ġfinish', 'es'] +['_M', 'E'] +['Bar', 'rier'] +['S', 'ong'] +['V', 'AR'] +['Ear', 'lier'] +['rell', 'a'] +['Ġh', 'ast'] +['az', 'ar'] +['Ġpull', 's'] +['ng', 'x'] +['Ġinspir', 'ing'] +['Ñĥ', 'Ñİ'] +['-d', 'irection'] +['Ġexplos', 'ive'] +['Ġcreated', 'At'] +['st', 'o'] +['Ġwhe', 'at'] +['ĠB', 'uilt'] +["'", 'ai'] +['Ġtrack', 'ed'] +['ham', 'mad'] +['RowAt', 'IndexPath'] +['_', 'heap'] +['D', 'ue'] +['Ġconnect', 's'] +['.p', 'ublish'] +['em', 'u'] +['Ġbul', 'lets'] +['B', 'AR'] +['ol', 'ate'] +['Ġintern', 'ally'] +['Ġcatch', 'ing'] +['-p', 'assword'] +['ou', 'ched'] +['æĢ', '§'] +['e', 'ous'] +['Ġx', 'range'] +['Q', 'uality'] +['v', 'v'] +['Man', 'age'] +['(', '($'] +['ac', 'ements'] +['ĠBro', 'thers'] +['ĠHE', 'AD'] +['ĠUn', 'supported'] +['s', 'an'] +['es', 'i'] +['**', '*Ċ'] +['Ġadapt', 'ation'] +['ĠWork', 'er'] +["']", '/'] +['.save', 'fig'] +['(', 'trans'] +['Ø', '¬'] +['ne', 'e'] +['Cor', 'rect'] +['...', '")Ċ'] +['Ġsubmit', 'ting'] +['-p', 'ath'] +['ĉ', 'last'] +['iss', 'an'] +['.x', 'label'] +['ĠS', 'epar'] +['/', 'no'] +['_b', 'est'] +['ĠM', 'ills'] +['_s', 'ock'] +['(f', 'lag'] +['Ġdest', 'inations'] +['em', 'ption'] +['ĠF', 'AIL'] +['å', 'ĴĮ'] +['Ġr', 'p'] +['f', 'act'] +['ĉ', 'len'] +['D', 'AY'] +['Ġse', 'iz'] +['_d', 'st'] +['l', 'ip'] +['.Line', 'ar'] +['ĠB', 'asket'] +['$', 't'] +['$', 'i'] +['-', 'brand'] +['ĠNe', 'il'] +['ĠE', 'q'] +['Ġth', 'ou'] +['og', 'ene'] +['Ġscholar', 'ship'] +['æĽ', '´'] +['Ġs', 'wo'] +['ag', 'inator'] +['en', 'i'] +['(', 'book'] +['Ġbl', 'ink'] +['th', 'us'] +['Ġcancell', 'ationToken'] +['ĠPalestin', 'ians'] +['Ġprofit', 'able'] +['Ġback', 'pack'] +['ens', 'on'] +['<', 'Long'] +['Ġp', 'ools'] +['Ġst', 'icks'] +['Ġspokes', 'woman'] +['Be', 'ing'] +['ĠHer', 'itage'] +['ĠN', 'ike'] +['SH', 'A'] +['ĠNotImplemented', 'Exception'] +['$', 'core'] +['ĠR', 'ico'] +['/', 'latest'] +['ĠC', 'zech'] +['ner', 'Radius'] +['(l', 'ines'] +['Ġsem', 'ester'] +['Ġw', 'ounds'] +['Pro', 'cedure'] +['.m', 'ail'] +['()', '):Ċ'] +['Ġcor', 'rid'] +['ter', 'ed'] +['ĠN', 'CAA'] +['Ġgal', 'axy'] +['_k', 'ind'] +['il', 'k'] +['Ġtr', 'as'] +['_P', 'OL'] +['ĠH', 'et'] +['Ġrefuge', 'e'] +['Ġteen', 'age'] +['.b', 'inding'] +['post', 'al'] +['Ġiç', 'in'] +['ĠData', 'Type'] +['é', 'ĸ'] +['ycl', 'erview'] +[',', 'value'] +['_id', 'entifier'] +['<', 'b'] +['Ġout', 'file'] +['čĊ', 'ĠĠĠĠčĊ'] +['Ġcr', 'é'] +['Ġrespond', 'ents'] +['ĠBe', 'ast'] +['ce', 'led'] +['Ġinter', 'f'] +['-th', 'eme'] +['g', 'if'] +['ĠR', 'angers'] +['IT', 'AL'] +['Ġauthentic', 'ate'] +['Com', 'pletion'] +['urs', 'ors'] +['Ġcin', 'ema'] +['Ġdisc', 'our'] +['ĠJ', 'aw'] +['OCK', 'ET'] +['Ġpr', 'ayers'] +['ĠL', 'uis'] +['fr', 'ag'] +['=[', 'Ċ'] +['Ġbr', 'ave'] +['_p', 'ose'] +['C', 'ertificate'] +['-', 'fe'] +['ifer', 'ay'] +['ĠFl', 'ags'] +['Container', 'Gap'] +['ĠC', 'rit'] +['Result', 'Set'] +['ĉc', 'ur'] +['Ġcorrespond', 's'] +['St', 'aff'] +['.Http', 'ServletRequest'] +['Ġneur', 'ons'] +['ĠMain', 'AxisAlignment'] +['ed', 'ar'] +['Ġg', 'ad'] +['_p', 'arts'] +['ĠÎ', '²'] +['Ġf', 'x'] +['/', 'files'] +['ĠB', 'ros'] +['hip', 's'] +['Ġgluc', 'ose'] +['Ġfar', 'ms'] +['Ġment', 'ally'] +['rest', 'aurant'] +['Table', 'Name'] +['ĠMer', 'cedes'] +['.', 'Visual'] +['Ġan', 'ch'] +['inal', 'g'] +['_r', 'untime'] +['Ġpropri', 'etary'] +['Ġintent', 'ions'] +['iz', 'i'] +['S', 'lice'] +[';', '">', 'true'] +['ĠNY', 'C'] +['Ġb', 'ored'] +['ĠD', 'etect'] +['Ġapp', 'ar'] +['Ġje', 'ans'] +['ĠT', 'ak'] +['I', 'OD'] +['ĠH', 'orse'] +['(', 'FILE'] +['(', '?'] +['ri', 'que'] +['optim', 'izer'] +['n', 'at'] +['lo', 'ys'] +['ĉ', 'Token'] +['oub', 'ted'] +['u', 'ess'] +['oco', 'a'] +['Data', 'Member'] +['_P', 'OWER'] +['class', 'List'] +['Push', 'Button'] +['ĠWi', 'Fi'] +['.', 'Stream'] +['.g', 'uild'] +['Ġn', 'og'] +['ĠPortug', 'al'] +['ĠUnt', 'er'] +['Pr', 'imitive'] +['b', 'oss'] +['ĠDe', 'utsch'] +['Ġerot', 'ic'] +['Ġstr', 'conv'] +['.Try', 'Parse'] +['Ġgr', 'ams'] +['.S', 'uccess'] +['_p', 'k'] +['ĠHar', 'vey'] +['-m', 'inded'] +['.c', 'ountry'] +['[]', '"'] +['Ġang', 'el'] +['Ġbe', 'ats'] +['ĠV', 'or'] +['il', 'io'] +['.m', 'aster'] +['s', 'omething'] +['ĠP', 'ACK'] +['(', 'if'] +['Request', 'Body'] +['Ġant', 'es'] +['/w', 'idget'] +['Ġmod', 'o'] +['ĠA', 'W'] +['find', 'er'] +['Ġoptim', 'ized'] +['Ġmiss', 'iles'] +['N', 'B'] +['ĉint', 'ernal'] +['t', 'ex'] +['ĠS', 'ri'] +['Ġdam', 'aging'] +['ĠM', 'ais'] +['-', 'Allow'] +['ĠZ', 'h'] +['-', 'alt'] +['Ġ', '));ĊĊ'] +['è', 'ī'] +['Ġinflu', 'ences'] +['Ġc', 'atal'] +['_REG', 'ISTER'] +['ĠAPI', 's'] +['-cent', 'ury'] +['Ġbi', 'ology'] +['ĠAct', 'ual'] +['Ġhe', 'els'] +['TR', 'ACE'] +['_D', 'IG'] +['D', 'ataset'] +['ĠM', 'atter'] +['Ġclass', 'ifier'] +['.w', 'ikipedia'] +['ĠRog', 'ers'] +['Ġdon', 'ated'] +['raw', 'ler'] +['en', 'en'] +['Ġcas', 'inos'] +['ort', 'al'] +['Ġpr', 'ive'] +['s', 'pe'] +['duc', 'ers'] +['.', 'ep'] +['Ġgr', 'asp'] +['ac', 'ji'] +['Ġd', 'airy'] +['Ġb', 'uses'] +['.com', 'm'] +['.', 'ins'] +['ĠI', 'RS'] +['ĠBe', 'er'] +['ad', 'c'] +['o', 'ard'] +['_M', 'ET'] +["Ġ'", "+'"] +['r', 'ans'] +['Ġkind', 'a'] +['ĠâĶ', 'Ĥ'] +['ĠM', 'aur'] +['аÐ', '³'] +['Ġband', 'width'] +['ib', 'us'] +['ĠD', 'ifferent'] +['(m', 'at'] +['ĠRes', 'ume'] +['_UN', 'S'] +['est', 'ablish'] +['Ġfon', 'ction'] +['Sub', 'scription'] +['_com', 'pany'] +['Ġlight', 'ly'] +['.con', 'firm'] +['.y', 'aml'] +['ĠBo', 'ost'] +['Com', 'merce'] +['-', 'template'] +['_DEL', 'AY'] +['ĠH', 'I'] +['Ġn', 'avig'] +['(S', 'ender'] +['ĠH', 'S'] +['_', '"+'] +['ĠRE', 'QUEST'] +['Ġw', 'ifi'] +['="', '"Ċ'] +['])', '->'] +['Ġro', 'pe'] +['Ġviol', 'ated'] +['Ġgl', 'ance'] +['ĠK', 'urd'] +['Ġè', '®'] +['de', 'ck'] +['ĠIS', 'BN'] +['Ġin', 'fect'] +['ĠF', 'oo'] +['Ġget', 'ter'] +['Ġt', 'ener'] +['ap', 'pe'] +['.h', 'h'] +['_h', 'ot'] +['<', 'AM'] +['p', 'oly'] +['!', '",Ċ'] +['Ġconver', 'ting'] +['ĠW', 'WE'] +['RO', 'S'] +["('", '{'] +['Com', 'mit'] +[')', 'L'] +['ĠO', 're'] +['Ġsp', 'arse'] +['Ġdis', 'posal'] +['Ġcan', 'celed'] +['åIJ', 'İ'] +['Ġa', 'er'] +['Ġvin', 'yl'] +['á»', 'ĥ'] +['rec', 'ogn'] +['ark', 'ing'] +['Ġtrick', 'y'] +['*', 's'] +['Ġproceed', 's'] +['Ġis', 'o'] +['Ġco', 'conut'] +['Ġcraft', 'ed'] +['IEL', 'DS'] +['Ġquest', 'o'] +['Ġcomm', 'un'] +['_CON', 'NECT'] +['Ġtraff', 'icking'] +['De', 'ep'] +['a', 'ções'] +['c', 'odigo'] +['ve', 'au'] +['Ġbet', 'ray'] +['int', 'a'] +['T', 'ED'] +['æ', 'r'] +['m', 'art'] +['_B', 'US'] +['/', 'sc'] +['ial', 'ly'] +['Ġcigaret', 'tes'] +['è¯', 'ģ'] +['(n', 'n'] +['Ġmodel', 'ing'] +['/', 'products'] +['w', 'arn'] +['Ġmet', 'ro'] +['ĠI', 'v'] +['&', ')'] +['ĠC', 'able'] +['Î', '»'] +['Compar', 'ison'] +['g', 'ary'] +['ĠB', 'A'] +['P', 'ART'] +['Ġp', 'v'] +['_up', 'dated'] +['C', 'redit'] +['orth', 'y'] +['observ', 'able'] +['Ġthe', 'atre'] +['B', 'LE'] +[';', '}ĊĊ'] +['la', 'unch'] +['_str', 'ings'] +['ug', 'o'] +['ĠR', 'PG'] +['-', 'auth'] +['Ð', 'ł'] +['hol', 'm'] +['ĠP', 'and'] +['U', 'id'] +['Ġim', 'ply'] +['ìľ', '¼'] +["']", "='"] +['/', 'User'] +['Ġstr', 'cat'] +['нÑĭ', 'й'] +['Data', 'Adapter'] +['Ġland', 'sc'] +['Ġdipl', 'omatic'] +['ï¼', 'ĵ'] +['************************************************************************', '****'] +['ĠCh', 'icken'] +['Ġbc', 'rypt'] +['.In', 'f'] +['[', 'col'] +['ĠQu', 'antity'] +['-', 'position'] +['Ġdiet', 'ary'] +['Ġfil', 'mm'] +['Is', 'rael'] +['Pre', 'v'] +['ĠMill', 'ion'] +['Ġrem', 'ed'] +['Ġbill', 'ing'] +['Ġout', 'doors'] +['.t', 'm'] +['Ġn', 'ad'] +['F', 'org'] +['Z', 'Z'] +['Ġs', 'sl'] +['],', "'"] +['K', 'T'] +['f', 'req'] +['=', 'document'] +['bl', 'ur'] +['¬', '¸'] +['ĠJeff', 'erson'] +['C', 's'] +['(s', 'ave'] +['Ġstr', 'ap'] +['Ind', 'ia'] +['Ġide', 'ology'] +['BO', 'SE'] +['ĠF', 'P'] +['(', 'ans'] +['Ġfe', 'ver'] +['ĠY', 'am'] +['K', 'ing'] +['à', '²'] +['AT', 'ING'] +['bo', 'hydr'] +['roll', 'back'] +['Ġnew', 'Node'] +['ĠN', 'VIDIA'] +['Ġhon', 'our'] +['ĠCon', 'firm'] +['xb', 'd'] +['Ġsuccess', 'or'] +['/', 'u'] +['l', 'iv'] +['ourn', 'aments'] +['Att', 'achment'] +['Ġgr', 'up'] +['Ġtri', 'be'] +['Ġca', 'res'] +['e', 'ft'] +['_s', 'ame'] +["'", 'label'] +['Ġ', 'ãĢIJ'] +['M', 'otor'] +['Ġin', 'exp'] +['Ġ"', '("'] +['_POS', 'ITION'] +['Ġval', 'ley'] +['ĠResult', 'Set'] +['Ġpres', 'erved'] +['Ġmut', 'ations'] +['Ġquestion', 'ing'] +['mun', 'ition'] +['parse', 'Int'] +['ĠS', 'r'] +['ĠMet', 'adata'] +['âĢĿ', 'ï¼Į'] +['timestamp', 's'] +['Ġtrans', 'itions'] +['í', 'Ļ'] +['Ñ', 'Ĭ'] +['i', 'om'] +['.D', 'o'] +['Ġp', 'ine'] +['Ġf', 'ung'] +['Ġtrans', 'mitted'] +['ct', 'ime'] +['ĠF', 'am'] +['Re', 'vision'] +['B', 'as'] +['UP', 'ER'] +['D', 'estination'] +['toHave', 'BeenCalled'] +['Ġun', 'fortunate'] +['IN', 'ES'] +['_pro', 'f'] +['Am', 'ong'] +['ĠCy', 'ber'] +['ĠB', 'attery'] +['gen', 're'] +['ĠView', 'Model'] +['-', '='] +['Ġutil', 'ized'] +['p', 'aint'] +['.Integer', 'Field'] +['ern', 'ity'] +['comp', 'iler'] +['âĢĭ', 'ĊĊ'] +['ĠM', 'asters'] +['.To', 'Array'] +['Ġstrt', 'ol'] +['ĠUkrain', 'ian'] +['}', '));Ċ'] +['Ġsh', 'emale'] +['"', 'That'] +['for', 'all'] +['/', 'download'] +['Ġrhet', 'oric'] +['.l', 'atitude'] +['ĠWH', 'EN'] +['Ġshock', 'ing'] +['IF', 'IC'] +['.N', 'ormal'] +['_F', 'OLDER'] +['Ġdr', 'ift'] +['Ġmount', 'ing'] +['-', 'book'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'Ċ'] +['ĠWire', 'less'] +['>', '".$'] +['Ġrel', 'ies'] +['(', 'Console'] +['Int', 'ernational'] +['->', '{$'] +['M', 'id'] +['Ġdis', 'sert'] +['dd', 's'] +['Ġdepos', 'its'] +['ĉd', 'river'] +['#', 'ga'] +['pr', 'ising'] +['print', 'ln'] +['Ġpres', 'enter'] +['Ġmin', 'es'] +['C', 'SS'] +['ĠD', 'ual'] +['(!', '('] +['Ġk', 'am'] +['Ġis', 'Loading'] +['ĠProt', 'ect'] +['.', 'upper'] +['ar', 'ium'] +[']:', 'ĊĊĊ'] +['Y', 'ii'] +['-sh', 'irt'] +['ĠIM', 'AGE'] +['_color', 's'] +['Ġur', 'gent'] +['.Cont', 'ainer'] +['!', '(Ċ'] +['S', 'aturday'] +['Ġsoci', 'eties'] +['ĠTh', 'an'] +['ĠC', 'od'] +['=', '@'] +['Ġattach', 'ments'] +['.m', 'obile'] +['Ġsp', 'ite'] +['Ġb', 'ounce'] +['raw', 'l'] +['instanc', 'etype'] +['ĠTr', 'uck'] +['Ġmanip', 'ulation'] +['(', 'Config'] +['-in', 'st'] +['Ġst', 'or'] +['it', 'ution'] +['Preferred', 'Gap'] +['Ġmain', 'AxisAlignment'] +['Ġlist', 'ened'] +["''", "'ĊĊ"] +['ott', 'age'] +['-', 'project'] +['.AP', 'PLICATION'] +['ĉ', 'root'] +['Ġwh', 'it'] +['Ġb', 'ilder'] +['Ġk', 'er'] +['Ġappl', 'iances'] +['row', 'ave'] +['ìĿ', 'Ģ'] +['ematic', 's'] +['ĠO', 'rg'] +['op', 'ing'] +['_SE', 'ARCH'] +['Ġch', 'am'] +['add', 'ContainerGap'] +['Ġ(', ').'] +['ĠAr', 'row'] +['Il', 'legal'] +['Current', 'ly'] +['Ġus', 'a'] +['Ġpassword', 's'] +['Ġre', 'nown'] +['av', 'ern'] +['ĠEv', 'il'] +['Ġconc', 'at'] +['Ġdu', 'o'] +['Ġv', 'ale'] +['ĠBe', 'an'] +['Ġindic', 'ators'] +['cm', 'ath'] +['ĠP', 'ump'] +['Nov', 'ember'] +['ific', 'ant'] +['_DOM', 'AIN'] +['reg', 'ar'] +['ĠPort', 'al'] +['"', '$'] +['Ġformer', 'ly'] +['"]', ':Ċ'] +['ĠVis', 'ibility'] +['.getElementsBy', 'ClassName'] +['_RE', 'D'] +['Ġch', 'ampions'] +['à', '´'] +['Val', 'or'] +['_', 'es'] +['*', 'a'] +['-re', 'peat'] +['B', 'and'] +['.st', 'age'] +['Ġbure', 'auc'] +['C', 'nt'] +['et', 'en'] +['-', 'function'] +['Ġm', 'uito'] +['P', 'ID'] +['_', 'editor'] +['Ġcrash', 'ed'] +['de', 'ad'] +['k', 'at'] +['ag', 'h'] +['ĠEX', 'T'] +['ass', 'er'] +['-sm', 'all'] +['Ġreal', 'iz'] +['(', 'Entity'] +['ú', 's'] +['ĠAct', 'ually'] +['ĠEl', 'ite'] +['Ġhel', 'm'] +['(non', 'atomic'] +['ash', 'er'] +['Comm', 'unity'] +['all', 'eng'] +['ir', 'y'] +['ĠG', 'rowth'] +['Ġs', 'ue'] +['Ġfrequ', 'encies'] +['_des', 'criptor'] +['.At', 'tribute'] +['Ġrecip', 'ients'] +['_N', 'S'] +['/', '"+'] +['ib', 'an'] +['Ġath', 'lete'] +['ĠI', 'gn'] +['_D', 'MA'] +['(d', 's'] +['ĠRequire', 'ments'] +['AD', 'I'] +['ere', 'z'] +['\\', 'Admin'] +['br', 'aska'] +['ĠR', 'ust'] +['Rel', 'ation'] +['C', 'OD'] +['ĠV', 'ERSION'] +['em', 'ma'] +['))', '{'] +['.D', 'uration'] +['ĠC', 'amb'] +['-', 'logo'] +['Ġread', 'able'] +['Ġcre', 'ators'] +['()', '];Ċ'] +['Up', 'Down'] +['-h', 'alf'] +['.get', 'Month'] +['(s', 'f'] +['P', 'ic'] +['Ġhun', 'ger'] +['.t', 'x'] +['Ġexceed', 'ed'] +['_se', 'ed'] +['(', '^'] +['_s', 'k'] +['.per', 'form'] +['Ġ>', '::'] +['Ġm', 'ongo'] +['=', 'float'] +['bind', 'Param'] +['Sm', 'art'] +['if', 'a'] +['Ġse', 'curities'] +['Ġpre', 'jud'] +['Ġ,', '"'] +['Ġcor', 'ps'] +['Ġv', 'ra'] +['amac', 'are'] +['it', 'err'] +['(M', 'edia'] +['uch', 'e'] +['Ġc', 'ob'] +['Ġlib', 'er'] +['.', 'geometry'] +['Loc', 'ator'] +['Ġsl', 'iding'] +['Ġsurg', 'ical'] +['_C', 'UR'] +['Ġcon', 'sect'] +['[', '*'] +['ĠRes', 'ort'] +['St', 'ub'] +['_DO', 'UBLE'] +['ĠS', 'oph'] +['Ġelect', 'oral'] +['_dis', 'able'] +['ĠÑģ', 'о'] +['ĠLight', 'ning'] +['Ġment', 'ions'] +['oc', 'y'] +['Ġle', 'aked'] +['Ġrelax', 'ing'] +['Pres', 'enter'] +['v', 'sp'] +['Ġgu', 'ilt'] +['=-', '=-'] +['.re', 'ply'] +['ĠMir', 'ror'] +['C', 'amp'] +['Ġ+#+', '#+#+'] +['Ġ+#+#+#+', '#+#+'] +['.A', 'uthor'] +['Ġdirect', 'ive'] +['-h', 'ook'] +['íĦ', '°'] +['}ĊĊ', 'ĊĊĊ'] +['@', 'pytest'] +['_r', 'and'] +['m', 'is'] +['Ġcolor', 'ful'] +['u', 'je'] +['lass', 'es'] +['ĠClass', 'es'] +['.h', 'ave'] +['%', '),'] +['é¢', 'ĺ'] +['Ġdistur', 'bing'] +['sub', 'string'] +['ĠK', 'oh'] +['In', 'vest'] +['p', 'urchase'] +['Ġrec', 'ycling'] +['ĠA', 'RT'] +['ier', 'archy'] +['Ġf', 'ps'] +['.check', 'Box'] +['íķ', '´'] +['_m', 'aterial'] +['duc', 'ation'] +['Ġf', 'w'] +['ud', 'it'] +['Ġreview', 'ing'] +['ĠS', 'id'] +['S', 'yntax'] +['ĠW', 'ritten'] +['arg', 'ar'] +['UM', 'E'] +['/', 'q'] +['Class', 'ifier'] +['Off', 'icial'] +['Ġj', 'azz'] +['Ġom', 'ega'] +['Ph', 'ysics'] +['Ġl', 'ugar'] +['_access', 'or'] +['.command', 's'] +['Ab', 'ility'] +['ĠB', 'atch'] +['R', 'AM'] +['Ġencount', 'ers'] +['.', 'Qu'] +['BY', 'TE'] +['ĠD', 'istribution'] +['Ġus', 'o'] +['ĠReco', 'very'] +['appro', 'ved'] +['Ġden', 'ial'] +['/sh', 'are'] +['Linked', 'List'] +[')čĊčĊ', 'čĊ'] +['udd', 'y'] +['Ġf', 'ines'] +['Ġr', 'y'] +['Un', 'icode'] +['ĉ', 'render'] +['Ġprem', 'ises'] +['Ġp', 'on'] +['ali', 'ases'] +['/F', 'oundation'] +['c', 'uda'] +['ĠC', 'ock'] +[',:', ')'] +['(f', 'older'] +['Ġm', 'éd'] +['dr', 'ag'] +['Ġtal', 'ents'] +['ĠĠĠ', 'ĊĊ'] +['е', 'ÑģÑĤв'] +['m', 'ob'] +['.y', 'ml'] +['Ġa', 'ster'] +['Ġdis', 'cre'] +['go', 'al'] +['ĠGT', 'X'] +['ĠS', 'UCCESS'] +['ĠL', 'ONG'] +['(f', 'ind'] +['Ġsing', 'ular'] +['_s', 'z'] +['ĠEth', 'ereum'] +['..', 'Ċ'] +['Ġir', 'res'] +["'))", '{Ċ'] +['Ġmin', 'isters'] +['St', 'eps'] +['ivers', 'al'] +['ĠNever', 'theless'] +['-', 'led'] +['Ġ(', '%)'] +['ç¡', '®'] +['Ġtime', 'zone'] +['Ġstr', 'anger'] +['(re', 'nder'] +['Ġsh', 'util'] +['Ġm', 'ph'] +['Ġtri', 'o'] +['pp', 'y'] +['Ġpred', 'omin'] +['Ġend', 'ors'] +['ĠRuss', 'ians'] +['ĉ', 'row'] +['Ġw', 'izard'] +['.s', 'erialize'] +['Ġcompl', 'ained'] +['Ġs', 'ido'] +['Ġdelight', 'ed'] +['-m', 'e'] +['ĠR', 'av'] +['H', 'uman'] +['ad', 'ays'] +['rec', 'v'] +['Work', 'ing'] +['J', 'ump'] +['ĠÃ¥', 'r'] +['ĠAut', 'omatic'] +['_B', 'ase'] +['æł', '¼'] +['aur', 'ants'] +['Â', '¯'] +['æ', '¸'] +['(C', 'Type'] +['IF', 'I'] +['(', 'amount'] +['Ġbelie', 'ving'] +['=', 'mysql'] +['Ġf', 'ir'] +['Ġrest', 'oration'] +['ere', 'co'] +['Ð', '¢'] +['_', "'+"] +['Ġe', 'book'] +['Ġde', 'bris'] +['(input', 's'] +['AY', 'OUT'] +['Ġscre', 'aming'] +['av', 'ia'] +['land', 'er'] +['Ġdist', 'ress'] +['Ġas', 'sembled'] +['ĠA', 'void'] +['(', 'thread'] +['ĠR', 'PC'] +['_EX', 'IT'] +['(', 'queue'] +['и', 'ÑģÑĤ'] +['D', 'll'] +['Ġsk', 'ull'] +['_p', 'ub'] +['che', 'z'] +['min', 'ate'] +['ens', 'en'] +['Ġins', 'ane'] +['b', 'ounds'] +['ĠR', 'osen'] +['Ġcondition', 'ing'] +['process', 'ed'] +['v', 'ideos'] +['f', 'our'] +['.Con', 'v'] +['|', ';Ċ'] +['Person', 'al'] +['cer', 'pt'] +[':UIControlState', 'Normal'] +['Ġdos', 'es'] +['ĠKar', 'l'] +['ĠFre', 'qu'] +['.B', 'ASE'] +['ĠV', 'ote'] +['Ġcon', 'current'] +['ĠMessageBox', 'Icon'] +['ĠÃ', 'ĸ'] +['ĠDub', 'ai'] +['ĠR', 'etail'] +[':', 'number'] +['ĠOb', 'server'] +['ĠBig', 'Integer'] +['_', 'origin'] +['_W', 'ORK'] +['F', 'rames'] +['Ġnot', 'ably'] +['.', 'âĢľ'] +['Ġtrop', 'ical'] +['Ġn', 'iche'] +['am', 'ina'] +['.s', 'ys'] +['(t', 'okens'] +['mod', 'ify'] +['os', 'it'] +['st', 'rom'] +['ĠCom', 'ics'] +['O', 'PTION'] +['T', 'icket'] +['Ġfact', 'ories'] +['Ġdis', 'put'] +['_F', 'ile'] +['ĠFin', 'n'] +['ee', 'e'] +['ĠDisc', 'ord'] +['_m', 'oney'] +['.t', 'pl'] +['_s', 'afe'] +['L', 'B'] +['Ġgl', 'ut'] +['J', 'K'] +['.fl', 'ow'] +['-', 'cont'] +['g', 'os'] +['Ġhor', 'izon'] +['ĠR', 'ush'] +['::', '*'] +['P', 'ipe'] +['ull', 'a'] +['bor', 'ough'] +['he', 'imer'] +['(m', 'ove'] +['(', 'Text'] +['}', ');čĊčĊ'] +['w', 'elcome'] +['ĠCom', 'ponents'] +['Ġgovern', 'ance'] +['c', 'losed'] +['ĉm', 'argin'] +['Ġla', 'undry'] +['ĠTerm', 'inal'] +['iz', 'ards'] +['.', 'âĢĶ'] +['.rem', 'ote'] +['.r', 'adius'] +['ĠQue', 'bec'] +['Ġd', 'h'] +['T', 'ech'] +['ĠM', 'ist'] +['s', 'eller'] +['_l', 'iteral'] +['Ġgen', 'ius'] +['Ġbr', 'ains'] +['g', 'em'] +['ĠMe', 'asure'] +['Ġcata', 'st'] +['r', 'ance'] +['.Text', 'Field'] +['Ġconsum', 'ing'] +["Ġ'\\", "''"] +['oubted', 'ly'] +['ĠC', 'ertain'] +['E', 'v'] +['ert', 'i'] +['be', 'ing'] +['Ex', 'perience'] +['Ġ//', '['] +['ĠArab', 'ic'] +['ĠC', 'rist'] +['ĠAz', 'ure'] +['Ġhor', 'a'] +['l', 'adesh'] +['\\', 'Blueprint'] +['d', 'ar'] +['.re', 'l'] +['Ġsup', 'rem'] +['ĠRe', 'agan'] +['ĠAt', 'tributes'] +['-s', 'idebar'] +['Ġuse', 'Styles'] +['ĠA', 'irlines'] +['Ġh', 'ills'] +['/x', 'html'] +['v', 'inc'] +['_m', 'ock'] +['Ċ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĊ'] +['ĠP', 'ill'] +['.Layout', 'Style'] +['ĠCommand', 'er'] +[']', '<'] +['sign', 'ature'] +['Ġ{', '}čĊ'] +['Ġhat', 'red'] +['Ġë', 'ĭ'] +['ole', 'sterol'] +['Ġ', '********'] +['ancell', 'or'] +['c', 'rop'] +['T', 'IM'] +['ĉĉ', 'ĊĊ'] +['ys', 'qli'] +['uit', 'ive'] +['ĉun', 'set'] +['_s', 'el'] +['Ġmen', 'us'] +['t', 'ick'] +['Ġconstit', 'ute'] +['ĠElement', 's'] +['ĠRed', 'is'] +['agg', 'io'] +['_f', 'p'] +['_de', 'pend'] +['em', 'as'] +['CA', 'ST'] +['or', 'ange'] +['j', 'on'] +['ĠEm', 'ily'] +['Ġpot', 'atoes'] +['Ġre', 'ceptor'] +['ĠElect', 'ronic'] +['ĠL', 'ights'] +['Ġcomb', 'ining'] +['ĠSome', 'one'] +['Ġ########', '.'] +['ĠT', 'OD'] +['/', 'show'] +['X', 'd'] +['."', "'"] +['af', 'x'] +['Ġtr', 'agic'] +['St', 'yled'] +['ĠMar', 'co'] +['G', 'allery'] +['d', 'ale'] +['.âĢĿ', 'ĊĊĊĊ'] +['é', 'rie'] +['/s', 'ervice'] +['äº', 'Ĩ'] +['Ġamb', 'ient'] +['_SET', 'TINGS'] +['.Ad', 'apter'] +['l', 'ene'] +['Ġtrav', 'els'] +['Not', 'ice'] +['Ġcle', 'ans'] +['ĠF', 'em'] +['ch', 'air'] +['Ñĥ', 'н'] +['/', 'my'] +['_b', 'ad'] +['ĠEcon', 'omics'] +['IS', 'A'] +['_C', 'NT'] +['(M', 'enu'] +['äº', 'İ'] +['ĠR', 'idge'] +['Ġlength', 'y'] +['D', 'ot'] +['Ġjump', 's'] +['Ġhe', 'y'] +['$', 'pdf'] +['Ġw', 'orm'] +['Ġs', 'ut'] +['Ġsh', 'er'] +['iam', 'o'] +['ĠCal', 'c'] +['trie', 've'] +['Ġc', 'ops'] +['ĠCh', 'rom'] +['Ġreg', 'ulated'] +['reat', 'ment'] +['ĠHigh', 'er'] +['ok', 's'] +['Ġde', 'ze'] +['LOC', 'ATION'] +['ongs', 'To'] +['Ġfin', 'ite'] +['Ġvar', 'ies'] +['Ġposition', 'ed'] +["'", 'il'] +['éĩ', 'ij'] +['Ġh', 'ike'] +['(d', 'one'] +['play', 'list'] +['Ġad', 'a'] +['Ġcoast', 'al'] +['ĠN', 'ancy'] +['.DateTime', 'Field'] +['Cpp', 'CodeGen'] +['ĠSimilar', 'ly'] +['re', 'ur'] +['ĠCon', 'tr'] +['ĠH', 'idden'] +['ĠB', 'eta'] +['atch', 'ed'] +['_inst', 'all'] +['.', 'Output'] +['Look', 'up'] +['ĠRich', 'mond'] +['qu', 'ared'] +['Ġm', 'anga'] +['-control', 's'] +['ĠBern', 'ard'] +['L', 'arge'] +['Ġslic', 'es'] +['Ġoff', 'ence'] +['ĠM', 'ega'] +['Ġest', 'ar'] +['Ġjoint', 's'] +['Ġsum', 'm'] +['_pl', 'atform'] +['B', 'uff'] +['.add', 'Subview'] +['Ġret', 'ained'] +['Let', 'ter'] +['.d', 'im'] +['Ġess', 'ere'] +['ĠS', 'caffold'] +['EX', 'PECT'] +['ĉ', 'RE'] +['.long', 'itude'] +['ü', 'nd'] +['Ġstat', 'ue'] +['.add', 'Widget'] +['ĠCar', 'ibbean'] +['add', 'PreferredGap'] +['il', 'de'] +['UIL', 'abel'] +['ĠOp', 'port'] +['Ġimper', 'ial'] +['urs', 'ion'] +['Ġmand', 'ate'] +['Ġpromot', 'ional'] +['Ġv', 'k'] +['ia', 'ÅĤ'] +['Ġp', 'yl'] +['ĠCre', 'ation'] +['оз', 'д'] +['Ġsim', 'pler'] +['.', 'what'] +['ĠRec', 'ent'] +['St', 'orm'] +['.', 'quantity'] +['ĠL', 'ov'] +['"', '-'] +['ubb', 'les'] +['_not', 'ification'] +['(w', 'orld'] +['ur', 'ger'] +['*', '(-'] +[':', '"Ċ'] +['h', 'm'] +['ans', 'hip'] +['ĠAl', 'most'] +['Ġmotor', 'cycle'] +['_f', 'ee'] +['Ġabsor', 'b'] +['ĠVin', 'cent'] +['Ġsound', 'ed'] +['ÃŃ', 'st'] +['Ġpharm', 'aceutical'] +['ht', 'ag'] +['ĠKind', 'le'] +['ital', 'ize'] +['ĠEm', 'peror'] +['oust', 'ic'] +['Ġspecial', 'ists'] +['åħ', '¬'] +['Border', 'Style'] +['/', '\\'] +['RE', 'LATED'] +["(',", "',"] +['(ex', 'pr'] +['Ġh', 't'] +['åį', 'Ī'] +['_C', 'reate'] +['Ġspecial', 'ly'] +['Ġ[]', ';čĊ'] +['Ġhe', 'el'] +['Ġse', 'pt'] +['_', 'arch'] +['(in', 'itial'] +['%', '.ĊĊ'] +['\\",', '\\"'] +['Ġdiscuss', 'es'] +['Ġu', 'pt'] +['Ġ[', '&'] +['Ġman', 'us'] +['.h', 'and'] +['ĠM', 'AIN'] +['ĠDen', 'mark'] +['Ġ],', 'čĊ'] +['Ġcr', 'yst'] +['Ġn', 'ack'] +['Co', 'ords'] +['_in', 'ner'] +['Ġmid', 'st'] +['Ġaw', 'ake'] +['ĠÐ', 'ŀ'] +['-b', 'reak'] +['ÃŃ', 'vel'] +['_P', 'ASS'] +['ĠParam', 's'] +['Ġdet', 'r'] +['Ġsp', 'ider'] +['ĠCon', 'cept'] +['Ġpre', 'nd'] +['CH', 'ED'] +['.Ex', 'it'] +['Ġpop', 'ulated'] +['Ġvirt', 'ue'] +['_SE', 'SSION'] +['Ġnou', 'vel'] +['o', 'auth'] +['Ġд', 'аннÑĭ'] +['r', 'ink'] +['.Header', 'Text'] +['atur', 'ated'] +['Ġer', 'st'] +['Ġå', 'ħ'] +['à¥', 'ĩ'] +['_vis', 'ible'] +['ey', 'er'] +['Ġli', 'able'] +['Ġde', 'be'] +['Ġb', 'w'] +['{-', '#'] +['_W', 'IN'] +['df', 's'] +['H', 'over'] +['ĠP', 'UT'] +['-', 'angle'] +['Ġnob', 'le'] +['Ġtr', 'aces'] +['enc', 'v'] +['Ġuser', 'Data'] +['_in', 's'] +['ĠS', 'uz'] +['Ġnews', 'letters'] +['ĠMod', 'i'] +['Ġentreprene', 'urs'] +['Ġtrib', 'ute'] +['Ġrum', 'ors'] +['Ġr', 'r'] +['ĠQu', 'arter'] +['ê³', 'ł'] +['Ġfeed', 's'] +['ó', 'g'] +['Ġen', 'velope'] +['Ġle', 'ar'] +['Ġk', 'ø'] +['develop', 'er'] +['Sim', 'ilar'] +[':', '")Ċ'] +['sub', 'scription'] +['Mod', 'ifier'] +['ital', 'ic'] +['Ġn', 'asty'] +['Ġtermin', 'ation'] +['Ġchar', 'ming'] +['Ġâ', 'Ł'] +['ton', 's'] +['.tr', 'ace'] +['h', 'ots'] +['ĠU', 'R'] +['M', 'ont'] +['Ġjust', 'ified'] +['ĠG', 'ang'] +['ine', 'a'] +['Ġb', 'og'] +['(', 'ap'] +['_', '$'] +['Ġcont', 'amin'] +['.D', 'ot'] +['ĉ', 'Debug'] +['(', 'exports'] +['Ġpa', 'ired'] +['ĠAss', 'ignment'] +['Ġautom', 'obile'] +['ĵ', 'į'] +['Ġph', 'ases'] +['v', 'w'] +['@', 'SuppressWarnings'] +['=', '\\'] +['r', 'ant'] +['-', 'ed'] +['ĉ', 'await'] +['Ġcert', 'ificates'] +["'>", '"'] +['Ġint', 'act'] +['CT', 'RL'] +['M', 'ike'] +['greg', 'ation'] +['AT', 'TERN'] +['Ġre', 'public'] +['_up', 'per'] +['ili', 'ary'] +['Ġcomput', 'ation'] +['h', 'ire'] +['ĠSh', 'in'] +['_', 'ANY'] +['ĠManufact', 'urer'] +['ĠC', 'arm'] +['Ġbear', 'ings'] +['_c', 'omb'] +['c', 'ad'] +['ur', 'istic'] +['Ġwholes', 'ale'] +['Ġdon', 'or'] +['.inter', 'faces'] +['press', 'o'] +['ĠBr', 'un'] +['-c', 'lose'] +['pro', 've'] +['_S', 'K'] +['ĉf', 'rame'] +['et', 'ros'] +['ĠP', 'ain'] +['_EX', 'P'] +['ĠL', 'T'] +['_f', 's'] +['.dat', 'as'] +['ĉ', 'ss'] +['vo', 'ir'] +['ĠA', 'xis'] +['M', 'ajor'] +['="', '<'] +['[', 'h'] +['Ġprof', 'ess'] +['igr', 'ate'] +['(s', 'core'] +['Key', 'word'] +['"', 'os'] +['ĠĠĠĠ', 'ĉĊ'] +['an', 'alysis'] +['Ġre', 'play'] +['.p', 'ass'] +['\\', 'd'] +['t', 'ls'] +['Ġsan', 'ct'] +['.l', 'ight'] +['_m', 'obile'] +['ÑģÑĤ', 'ÑĮ'] +['ĉt', 'otal'] +['u', 'ity'] +['Ġpa', 'used'] +['N', 'AS'] +['Ġen', 'core'] +['lo', 'e'] +['Ġ-*', '-ĊĊ'] +['.h', 'igh'] +['am', 'pler'] +['ĠSec', 'ure'] +['Ġfrag', 'ments'] +['_', 'vel'] +['ill', 'ary'] +['ĠSte', 'in'] +['ĠD', 'awn'] +['Ġmax', 'imize'] +['à¸', '¢'] +['Ġ/', '^'] +['Ġcontin', 'ually'] +['Ġsh', 'adows'] +['ĉ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['ĠI', 'ActionResult'] +['Ġinform', 'ación'] +['C', 'HECK'] +['.Selected', 'Item'] +['b', 'undle'] +['ol', 'ley'] +['<', 'Int'] +['AIN', 'ER'] +['ĠW', 'ing'] +['tit', 'les'] +['ount', 'ain'] +['C', 'Y'] +['ĠLoc', 'ale'] +['form', 'er'] +['<', 'context'] +['R', 'adioButton'] +['_s', 'chedule'] +['Ġfab', 'ulous'] +['Rob', 'ert'] +['_PRO', 'FILE'] +['Ġg', 'ates'] +['IM', 'P'] +['ĠPent', 'agon'] +['g', 'old'] +['b', 'ach'] +['employ', 'ees'] +['R', 'otate'] +['Ġch', 'amp'] +['Ġsel', 'bst'] +['Al', 'tern'] +['Ġconvert', 'View'] +['/', ','] +['Ġ~', '('] +['St', 'reet'] +['_', 'place'] +['Ġpersonal', 'ized'] +['P', 'ublisher'] +['ĠSO', 'CK'] +['_NAMES', 'PACE'] +['ĠStand', 'ards'] +['so', 'ever'] +['_C', 'ENTER'] +['Inter', 'est'] +['ô', 't'] +['tem', 'perature'] +['View', 'port'] +['get', 'Resource'] +['Ġeat', 'en'] +['Ġsem', 'pre'] +['Ġab', 'normal'] +['Ġc', 'ylinder'] +['Ġtroub', 'les'] +['n', 'od'] +['Ñĭ', 'в'] +['g', 'ames'] +['_g', 'l'] +['Pl', 'ane'] +['g', 'rey'] +['_t', 'bl'] +['.Component', 'Placement'] +['ĠCh', 'ase'] +['Log', 'ging'] +['man', 'y'] +['ì', 'Ĩ'] +['Ġfl', 'ame'] +['="<'] +['Ġtra', 'jectory'] +['_r', 'ing'] +['Ġhydro', 'gen'] +['tr', 'on'] +['Ġstat', 'ute'] +['Ġcondition', 'al'] +['Ġtr', 'ay'] +['-s', 'chool'] +['(w', 'idget'] +['$', 'config'] +['Ġrequest', 'ing'] +['.', 'uint'] +['et', 'on'] +['brit', 'ies'] +['Of', 'Type'] +['AD', 'MIN'] +['p', 'redict'] +['Ġg', 'egen'] +['ĠH', 'app'] +['OC', 'UMENT'] +['ĠA', 'part'] +['Ġ----', '-'] +['ro', 'e'] +['u', 'ide'] +['just', 'ify'] +['ĠSqu', 'ad'] +['Ġprof', 'es'] +['.b', 'ot'] +['_c', 'urrency'] +['inn', 'en'] +['ĠM', 'umbai'] +['ĠNum', 'bers'] +['avana', 'ugh'] +['agn', 'itude'] +['âĢľ', 'There'] +['=', 'http'] +['çī', 'ĩ'] +['Ġv', 'b'] +["+'", '{{', '$'] +['Ġin', 'ode'] +['s', 'il'] +['Ġh', 'ace'] +['Ġsever', 'ely'] +['ĠOver', 'view'] +['Ġspr', 'aw'] +['Ġbeach', 'es'] +[':', 'left'] +['·', '»'] +['($', '{'] +['ĠF', 'IRST'] +['ĠSp', 'a'] +['-', 'ass'] +['Ġb', 'aise'] +['ĠN', 'ODE'] +['ĠP', 'izza'] +['P', 'et'] +['(se', 'q'] +['\\', '">Ċ'] +['CppMethod', 'Pointer'] +['Ġv', 'p'] +['Ġi', 'a'] +['_se', 'conds'] +['em', 'et'] +['/b', 'lob'] +['_TH', 'RESH'] +['...', 'čĊ'] +['D', 'est'] +['ĠN', 'H'] +['.data', 'Source'] +['it', 'és'] +['ĠJ', 'ak'] +['s', 'ell'] +['Ġwork', 'shops'] +['<', 'u'] +['Ġr', 'ivals'] +['ĠEX', 'ISTS'] +['h', 'om'] +['-t', 'oken'] +['compat', 'ible'] +['.J', 'Panel'] +['Ġphys', 'icians'] +['art', 'in'] +['Ġdes', 'irable'] +['Ġdistinct', 'ive'] +['.D', 'ep'] +['g', 'id'] +['ili', 'ate'] +[',', 'max'] +['Ġprem', 'iere'] +['Ġq', 'Debug'] +['Ġadvoc', 'acy'] +['Ġwh', 'isper'] +['P', 't'] +['Ġun', 'changed'] +['_q', 'ty'] +['请', 'æ±Ĥ'] +['Se', 'ason'] +['avel', 'ength'] +['ĠP', 'ul'] +['Ġd', 'ÃŃa'] +["']", ']],Ċ'] +['al', 'is'] +['("', '&'] +['bor', 'o'] +['Ġb', 'm'] +['ĠR', 'adi'] +['w', 'rong'] +['ĠGo', 'ing'] +['ime', 'Type'] +['ij', 'i'] +['-', 'feedback'] +['ĠN', 'ames'] +['ĠB', 'apt'] +['Ġprob', 'able'] +['ĠE', 'ther'] +['ĠPolit', 'ics'] +['_prot', 'ocol'] +['lin', 'ing'] +['S', 'at'] +['Ġcor', 'rel'] +['.Pr', 'imary'] +['(null', 'able'] +['RI', 'ORITY'] +['Ġcolor', 'ing'] +['Ġutil', 'izing'] +['d', 'as'] +['Ġexport', 'ed'] +['Ġcar', 'riers'] +['Con', 'v'] +['.', 'editor'] +['i', 'ó'] +['(h', 'andles'] +['Ġapprec', 'iation'] +['.', 'import'] +['ĠAust', 'ria'] +['ĠStr', 'ip'] +['il', 'ight'] +['Ġappropri', 'ately'] +['ĠP', 'rest'] +['ĠW', 'ir'] +['ĠUI', 'Application'] +['al', 'chemy'] +['ĠM', 'ob'] +['ĠD', 'etermin'] +['ergus', 'on'] +['register', 'ed'] +['_con', 'vert'] +['ĠVlad', 'imir'] +['.Show', 'Dialog'] +['ref', 'lect'] +['Ġsh', 'ook'] +['Ġass', 'ure'] +['ĠO', 'ften'] +['Ġcivil', 'ization'] +['Ġvocab', 'ulary'] +['fore', 'ground'] +['ĠS', 'cope'] +['Ġunw', 'anted'] +['act', 'ing'] +['Ġ(', '[]'] +['Ġmark', 'ing'] +['.', 'original'] +['ĠMO', 'VE'] +['Ġsport', 'ing'] +['ception', 's'] +['NS', 'Number'] +['S', 'izes'] +['Ġprovinc', 'ial'] +['_Tr', 'ans'] +['Ġproblem', 'atic'] +['d', 'igit'] +['ĠEm', 'ma'] +['lock', 's'] +['ĠC', 'rew'] +['ib', 'a'] +["')", ':'] +['ish', 'a'] +['Ġm', 'amm'] +['Ġocc', 'ured'] +['w', 'cs'] +['(r', 'ule'] +['Ġmerch', 'andise'] +['es', 'pecially'] +['ĠT', 'win'] +['Ġn', 'aming'] +['Ġs', 'log'] +['Ġimpro', 'ves'] +['Ġad', 'her'] +[':', 'text'] +['.h', 'adoop'] +['_HT', 'TP'] +['.to', 'List'] +['.dis', 'abled'] +['Ġl', 'enses'] +['.in', 'i'] +['ĠR', 'are'] +['ĠUb', 'untu'] +['Ġsc', 'ram'] +['ol', 'ation'] +['tit', 'ulo'] +['Every', 'thing'] +['Ġnod', 'ded'] +['icht', 'ig'] +['_const', 'ant'] +['z', 'c'] +['l', 'ift'] +['ĠNot', 'ify'] +['ond', 'o'] +['ĠIN', 'F'] +['("', '+'] +['ĠK', 'az'] +['Ġd', 'read'] +['.m', 'apper'] +['le', 'ur'] +['ĠCome', 'y'] +['ĠN', 'B'] +['ic', 'ers'] +['.P', 'ush'] +['ĠH', 'ack'] +['ĠBrazil', 'ian'] +['_pro', 'd'] +['Ġ//', 'ĊĊ'] +['Ġb', 'icycle'] +['Ġun', 'available'] +['Ġadoles', 'cent'] +['bl', 'k'] +['Ġmit', 'ig'] +['_bl', 'ue'] +['ì', 'ĺ'] +['fade', 'In'] +['ĠUtil', 'ities'] +['ĠM', 'N'] +[';', 'k'] +['<', 'style'] +['-', 'status'] +['ind', 'o'] +['Ġinn', 'ings'] +['Ġg', 'j'] +['Ġ||', '='] +['.e', 'u'] +[':', 'Number'] +['Ġcuis', 'ine'] +['ĠURL', 's'] +['ie', 'k'] +['Ġw', 'ires'] +['ĉ', 'ps'] +['ie', 'g'] +['.m', 'k'] +['so', 'ap'] +['Ġsom', 'etime'] +['Ġst', 'ap'] +['_s', 'eries'] +['.T', 'arget'] +['æ', 'º'] +['.dest', 'ination'] +['OUN', 'TER'] +['R', 'aises'] +['&', 'A'] +['Ġsmart', 'phones'] +['NI', 'Env'] +['.s', 'dk'] +['Ġhelicopt', 'er'] +['Ġim', 'pe'] +['ĠB', 'irth'] +['A', 'U'] +['b', 'readcrumbs'] +['co', 'ords'] +['Ġexplo', 'red'] +['Ġl', 'od'] +['ĠI', 'p'] +['g', 'able'] +['ian', 'e'] +['Ġart', 'ifacts'] +['Box', 'Layout'] +['ا', 'ر'] +['list', 'ener'] +['.c', 'art'] +['ĠH', 'uff'] +['ĠHind', 'u'] +['ĠData', 'Types'] +['ĠDr', 'upal'] +['IGN', 'ORE'] +['Ġoffset', 's'] +['ĠR', 'TC'] +['-', 'login'] +['æ', '®'] +['ĠQ', 'Object'] +['Ġprosec', 'utor'] +['R', 'ock'] +['_ch', 'at'] +['W', 'ay'] +['ì', '²'] +['Ġneg', 'lig'] +['Ġd', 'ude'] +[';', '<'] +['Ġdeleg', 'ates'] +['_f', 'ailed'] +['/', 'dev'] +['/', 'work'] +['(', 'New'] +['et', 'able'] +['()', '"'] +['(', 'Icons'] +['Ġp', 'ork'] +['ĠModel', 'AndView'] +['ĠV', 'IP'] +['ĠK', 'or'] +['m', 'ix'] +['Ġox', 'id'] +['ĠSC', 'REEN'] +['ĠFour', 'th'] +['/', '",Ċ'] +['Ġte', 'e'] +['ĠSte', 'vens'] +['t', 'icks'] +['Ġp', 'ledge'] +['ib', 'bon'] +['ĠLo', 'an'] +['Ġne', 'o'] +['n', 'umpy'] +['ĠShared', 'Preferences'] +['-', 'oriented'] +['ĠLogger', 'Factory'] +['ĠGraph', 'QL'] +['zen', 'ia'] +['"', '_'] +['W', 'omen'] +['.c', 'ast'] +['Ġdeliber', 'ately'] +['+', 'b'] +['ĠAr', 'n'] +['font', 'Size'] +['Ġm', 'aze'] +['Ġbl', 'amed'] +['.m', 'as'] +['}', ')čĊ'] +['eler', 'ik'] +['Ġsc', 'anning'] +['ĠWork', 'shop'] +['Ġfind', 'en'] +['Ġca', 'ut'] +['UI', 'Font'] +['(', 'return'] +['al', 'in'] +['cast', 'le'] +['////////////////////////////////////////////////////////////////', '////////'] +['Ġincent', 'ive'] +['op', 'ath'] +['b', 'lob'] +['Ġcigaret', 'te'] +['Ġfert', 'il'] +['*/', 'ĊĊĊ'] +['ĠSh', 'ar'] +['Ċ', 'ĠĠĠĠĠĠĊ'] +['Ġunc', 'ertain'] +['ĠS', 'ton'] +['Oper', 'ations'] +['ĠSp', 'encer'] +['Ġdef', 'in'] +['ĠS', 'olo'] +['on', 'est'] +['·»', 'åĬł'] +['Ġu', 'omo'] +['G', 'ive'] +['Ġdent', 'ro'] +[';', 'padding'] +['ent', 'ai'] +['ĠC', 'ars'] +['Ġenthus', 'iasm'] +['ĠOper', 'ating'] +['S', 'kip'] +['par', 'ation'] +['Ġprotect', 's'] +['Ġre', 'ver'] +['d', 'g'] +['ĠC', 'incinnati'] +['Ġconsect', 'etur'] +['Ġm', 'uss'] +['employ', 'ed'] +['a', 'uses'] +['ink', 'le'] +['.', 'Values'] +['£', '¼'] +['lo', 'v'] +['_W', 'ARN'] +['Ġbook', 'mark'] +['ĠAp', 'ollo'] +['.', 'axis'] +['Ġm', 'ét'] +['Ġop', 'ener'] +['Ġtum', 'or'] +['d', 'an'] +['Ġelement', 'ary'] +['Ġsk', 'ipped'] +['ĠK', 'er'] +['as', 'ia'] +['_res', 'p'] +['Ġdem', 'ol'] +['ĠCan', 'adians'] +['Ġt', 'astes'] +['U', 'Integer'] +["Ġ'", '${'] +['.aw', 's'] +['RO', 'ID'] +['ri', 'ans'] +['M', 'Q'] +['ord', 'able'] +['Ġcous', 'in'] +['Prop', 'agation'] +['(S', 'ession'] +['ph', 'alt'] +['UL', 'D'] +['ĠSc', 'alar'] +['Ġblo', 'ody'] +['Ġ', 'à¦'] +['.m', 'ask'] +[',', 'q'] +['ĠUn', 'its'] +['Ġcent', 'res'] +['ĠPr', 'im'] +['.', ']ĊĊ'] +['ĠSh', 'aw'] +['P', 'rom'] +['ĠTh', 'ought'] +['Check', 'er'] +['_output', 's'] +['(', 'chan'] +['E', 'INVAL'] +['Ġb', 'ob'] +['_c', 'mp'] +['P', 'ed'] +['Ġmat', 'rices'] +['Ġvrou', 'wen'] +['Ġgenu', 'inely'] +['high', 'light'] +['(d', 'isplay'] +[')', '!='] +['Ġdel', 'icate'] +['ĠL', 'uther'] +['ĠM', 'iles'] +['Ġuser', 'ID'] +['%', '='] +['ate', 'urs'] +['_B', 'UF'] +['----', '---Ċ'] +['imit', 'ives'] +['Ġsh', 'elves'] +['sl', 'ow'] +['_in', 'formation'] +['LE', 'G'] +['W', 'r'] +['.form', 's'] +['cel', 'and'] +['/', 'un'] +[':', '&'] +['.âĢĻ', 'ĊĊ'] +['="', '%'] +['Ġpro', 'st'] +['Ġfont', 'size'] +['uc', 'ión'] +['get', 'ic'] +['am', 't'] +['="', '.'] +['Dec', 'or'] +['B', 'rit'] +['Ġ""', ').'] +['Ġfound', 'ing'] +['.File', 'Name'] +['ĠT', 'ier'] +['Ġdisc', 'lose'] +['á', 'm'] +['.s', 'yn'] +['.View', 'Holder'] +['lic', 'ant'] +['_st', 'age'] +['Mon', 'day'] +['Ġdes', 'erialize'] +['t', 'alk'] +['Ġtradition', 'ally'] +['æĢ', 'ģ'] +['Ø', '®'] +['LE', 'X'] +['Ġe', 'h'] +['ĉ', 'ROM'] +['Ġ{', '})Ċ'] +['Quest', 'ions'] +['nc', 'py'] +['Ġfix', 'ing'] +['к', 'Ñĥ'] +['_', 'Key'] +[':', 'x'] +['ĠSTR', 'ING'] +['ĠÑĦ', 'ай'] +['ĉ', 'left'] +['ĠBen', 'ch'] +['ell', 'ij'] +['UR', 'RED'] +['ĠDi', 'agram'] +['}', 'catch'] +['/', 'time'] +['ĠMiss', 'ing'] +['db', 'name'] +['Ġs', 'ore'] +['ĠW', 'alt'] +['ugg', 'ing'] +['rep', 'resent'] +['ĠG', 'S'] +['ne', 'ys'] +['ĉ', 'page'] +['Ġvol', 'can'] +['(b', 'tn'] +['Ġexceed', 's'] +['Ġ', 'erg'] +['Ġpil', 'ots'] +['ĠS', 'ed'] +['ers', 'ions'] +['Ġpat', 'ron'] +['R', 'V'] +['/', 'top'] +['.', 'asset'] +['_c', 'ross'] +['.', 'Editor'] +['.t', 'b'] +['Ġwel', 'coming'] +['SC', 'REEN'] +[')', 'findViewById'] +['C', 'oder'] +['', '",Ċ'] +['_P', 'in'] +['ues', 'e'] +['Ġover', 'rides'] +['_', 'ready'] +['Adv', 'anced'] +['Ġop', 'i'] +['-c', 'art'] +['("/', '",'] +['ĠDe', 'b'] +['CR', 'Y'] +['ĠVert', 'ical'] +['ĠO', 'VER'] +['ĠCorpor', 'ate'] +['Ġ""', ';'] +['Ġste', 'pping'] +['e', 'j'] +['Ġaccus', 'ations'] +['Ġor', 'az'] +['_t', 'ail'] +['Ġindu', 'ced'] +['Ġel', 'astic'] +['Ġbl', 'own'] +[',', '//'] +['Ġbackground', 's'] +['âĢĻ', 'une'] +['-s', 'dk'] +['Ġset', 'Interval'] +['Ġincent', 'ives'] +['Ġveget', 'able'] +['_', 'On'] +['exp', 'anded'] +['p', 'ix'] +['_sh', 'ader'] +['ĠSP', 'DX'] +['@', 'example'] +['ĠW', 'rapper'] +['.Z', 'ero'] +['Pos', 'itive'] +['Ġsp', 'inner'] +['Ġinvent', 'ed'] +['ĠG', 'ates'] +['оÑĤ', 'оÑĢ'] +['Ġcompar', 'isons'] +['è', '·'] +['.pr', 'imary'] +['data', 'Provider'] +['add', 'itional'] +['ĉ', 'options'] +['s', 'napshot'] +['.set', 'Horizontal'] +['Ġ"', '{}'] +['ĠFish', 'er'] +['hal', 'ten'] +['<', 'Type'] +['Ġmax', 'Length'] +['ĠM', 't'] +['Ġê°', 'Ģ'] +['.jet', 'brains'] +['Ġident', 'ifies'] +['Ġflow', 'ing'] +['ĠDisc', 'ussion'] +['ats', 'by'] +['Ġsch', 'w'] +['ught', 'y'] +['Ġr', 'ivers'] +['.un', 'ique'] +['_PH', 'Y'] +['ed', 'ral'] +['(', 'll'] +['Ġcs', 'rf'] +['pp', 'ers'] +['ü', 'l'] +['ĠEs', 'pecially'] +['port', 'ed'] +['ĠHarr', 'ison'] +['******', '*/Ċ'] +['Text', 'Color'] +['ìĬ', 'µ'] +['w', 'ire'] +['Ġstatus', 'Code'] +['ĠFin', 'ish'] +['c', 'ence'] +['ĠMcC', 'ain'] +['ĠW', 'or'] +['(', 'await'] +['Ġ)', '->'] +['ĠRegister', 'ed'] +['IN', 'ED'] +['k', 'al'] +['par', 'ison'] +['Ġobj', 'eto'] +['V', 'i'] +['mand', 'a'] +['Ġrenew', 'ed'] +['ĠS', 'of'] +['ess', 'el'] +['.nd', 'array'] +['Ġcr', 'ap'] +['ç®', '¡'] +['.ab', 'spath'] +['(', 'up'] +['Ġclear', 'ance'] +['ĠT', 'W'] +['_C', 'OPY'] +['ĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĉ'] +['Ġforest', 's'] +['Ġarg', 'uably'] +['ĠA', 'SS'] +['he', 'y'] +['am', 'el'] +['_f', 'ore'] +['ĠSou', 'theast'] +['Ġab', 'used'] +['Ġpract', 'icing'] +['aked', 'irs'] +['ä¸', '»'] +['_res', 'ources'] +['Ġp', 'ond'] +['.F', 'ixed'] +['Last', 'Error'] +['ĠPsych', 'ology'] +['Ġ"', '//'] +['!', ':'] +['Re', 'usable'] +['Ġmens', 'aje'] +['Ġro', 'spy'] +['Ġb', 'our'] +['Ġvar', 'ieties'] +['Ġem', 'path'] +['((', '{'] +['_', 'org'] +['ĠM', 'es'] +['ĠMag', 'ento'] +['IST', 'ORY'] +['Un', 'less'] +['Ġh', 'j'] +['ĠD', 'uty'] +['J', 'un'] +[',', 'size'] +['Ġpaint', 'ings'] +['Ġdisp', 'ens'] +['d', 'art'] +['Ġbehavior', 'al'] +['Ġr', 'pc'] +['cal', 'culate'] +['fr', 'uit'] +['_m', 'm'] +['ĉp', 'thread'] +['Max', 'Length'] +['Ġc', 'urrencies'] +['_cap', 'acity'] +['ĠO', 'z'] +['Ġfire', 'arm'] +['Ġcoeff', 'icient'] +['Ġbankrupt', 'cy'] +['w', 'art'] +['Ġfat', 'igue'] +['AV', 'A'] +['Ġes', 'pa'] +['_p', 'c'] +['ĠQu', 'otes'] +['_L', 'IGHT'] +['ĠT', 'ickets'] +['Ġrel', 'ates'] +['Ġpublish', 'ers'] +['Ġunlock', 'ed'] +['Ġ//', '----------------------------------------------------------------'] +['ĠInterrupt', 'edException'] +['Ġout', 'look'] +['r', 'n'] +['Ġreb', 'els'] +['W', 'ritten'] +['Ġas', 'ian'] +['ot', 'to'] +['Ġ', 'ĉĉĉĉ'] +['_g', 'pu'] +['T', 'xt'] +['.Image', 'View'] +['Ġsu', 'is'] +['_t', 'ables'] +['.Rec', 'yclerView'] +['Ġwhat', 'soever'] +['è', 'ģ'] +[']', '++;Ċ'] +['assert', 'True'] +['_', 'verify'] +['ĠR', 'ivers'] +['Ġ', ']['] +['J', 'et'] +['id', 'ian'] +['S', 'ibling'] +['Ġgen', 'res'] +['.A', 'ccess'] +['OP', 'S'] +['Ġtr', 'ivial'] +['à¸', 'ª'] +['al', 'en'] +['в', 'ед'] +['ĠS', 'word'] +['Ġscrut', 'iny'] +['(c', 'b'] +['Ġcomm', 'erce'] +['Ġguarante', 'es'] +['_ad', 'v'] +['ĠL', 'ET'] +['rec', 'io'] +['Ġh', 'ilar'] +['Ġback', 'yard'] +['ãĢ', 'ı'] +['Ġillustr', 'ated'] +['/v', 'endor'] +['.', 'Util'] +['Ġw', 'ow'] +['LO', 'Y'] +['ĠMar', 'shal'] +['">', "'.$"] +['ĠB', 'ak'] +['Ġmod', 'ifiers'] +['d', 'ictionary'] +['ĠSt', 're'] +['m', 'ultiple'] +['"))', ','] +['ĠC', 'ort'] +["']", '").'] +['(', 'admin'] +['ĠCre', 'ator'] +['Int', 'ernet'] +['(', 'ms'] +['log', 'y'] +['DECL', 'ARE'] +['ĠMarc', 'us'] +['<<', '<<'] +['ãģ', 'ł'] +['_m', 'y'] +['(in', 'st'] +['Ġsc', 'iences'] +['ND', 'ER'] +['.', 'enter'] +['Ġit', 'u'] +['Ġbeh', 'ave'] +['P', 'an'] +['omb', 'ies'] +["='", '<'] +["'))", ';čĊ'] +['ĠM', 'ENU'] +['ĠWork', 'ers'] +['.No', 'Error'] +['Ġbind', 'ings'] +['Ġdis', 'abilities'] +['{', '\\'] +['ĠM', 'unicip'] +['Ġco', 'res'] +['ur', 'ple'] +['ĠN', 'okia'] +['us', 'ions'] +['ĠF', 'itness'] +['.handle', 'Change'] +['Ġjav', 'ascript'] +['ìļ', 'Ķ'] +['(', 'dec'] +['Ġpack', 'ing'] +['-de', 'pend'] +['Ġtrans', 'cript'] +['z', 'eros'] +['_', 'alert'] +['?', '",Ċ'] +['lib', 's'] +['±', 'оÑĤ'] +['Ġ|', 'ĊĊ'] +['tr', 'ained'] +['ĠG', 'ent'] +['ĠR', 'ab'] +['x', 'p'] +['_config', 'uration'] +['å¤', '©'] +['_', 'accept'] +['.rec', 'yclerview'] +[':', 'url'] +['ĠMu', 'hammad'] +['Ġprivile', 'ges'] +['_b', 'ank'] +['uk', 'u'] +['w', 'allet'] +['ĠRO', 'OT'] +['Ġenc', 'uent'] +['?', 'family'] +['ĉ', 'position'] +['Ġc', 'g'] +['Ġprec', 'ip'] +['method', 's'] +['_f', 'ast'] +['in', 'crement'] +['ĠT', 'iger'] +['_OCC', 'URRED'] +['qu', 'ip'] +['ĠH', 'AS'] +['_d', 'om'] +['Ġw', 'reck'] +['b', 'j'] +['Ġd', 'ern'] +['Ġorg', 'ans'] +['.', 'entries'] +['Ġ_', "('"] +['ram', 'ento'] +['ĠJam', 'ie'] +['Ġp', 'unk'] +['IP', 'P'] +['Ġprogram', 'a'] +['Ġatt', 'ain'] +['Ġpro', 'ves'] +['/s', 'ign'] +['Ġanswer', 'ing'] +['Ġl', 'adder'] +['************************', '****'] +['ĠW', 'almart'] +['ĠCONT', 'ENT'] +['duct', 'or'] +['Ġver', 'bal'] +['ĠP', 'ID'] +['c', 'rypto'] +['_CALL', 'BACK'] +['Ġ=', '================================'] +['Ġpot', 'ent'] +['Ġshort', 's'] +['.U', 'ri'] +['.un', 'iform'] +[';', 'border'] +['ĠW', 'er'] +['Ġhere', 'in'] +['ll', 'a'] +['ĠI', 'hr'] +['P', 'ixmap'] +['l', 'iteral'] +['!', ')ĊĊ'] +['g', 'eneric'] +['r', 'ust'] +['_script', 's'] +['ost', 'o'] +['it', 'us'] +['ĠCoal', 'ition'] +['Ġrem', 'ot'] +['de', 'ploy'] +['ĠEag', 'le'] +['ãĢģ', 'ãĢĮ'] +['Ġimportant', 'e'] +['ĉ', 'object'] +['Ġseason', 'al'] +['ne', 'j'] +['aid', 'u'] +['Bind', 'View'] +['ĠSi', 'erra'] +['-b', 'g'] +['Ġmake', 'Styles'] +['[', 'offset'] +['G', 'ames'] +['Ġhorm', 'one'] +['AR', 'IO'] +['head', 's'] +['(', 'select'] +['ĠStart', 'ed'] +['@', 'param'] +['_de', 'cl'] +['_b', 'log'] +['Ġa', 'ño'] +['\\', 'Api'] +['ĠMil', 'waukee'] +['Pro', 'vid'] +['An', 'imated'] +['Ġcool', 'er'] +['ĠSe', 'ed'] +['.', 'Edit'] +['Ï', 'Ħ'] +['ĠT', 'aking'] +['Ġborder', 'Color'] +['-found', 'er'] +['.Logger', 'Factory'] +['Ġ""', 'ĊĊ'] +['AL', 'T'] +['ĠL', 'ate'] +['EDI', 'ATE'] +['Ġ);ĊĊ', 'Ċ'] +['af', 'a'] +['Ġcancell', 'ation'] +['At', 'om'] +['ĠB', 'irmingham'] +['emp', 'resa'] +['HE', 'MA'] +['asc', 'al'] +['Ġup', 'side'] +['.V', 'ersion'] +['ĠF', 'older'] +['ĠE', 'ight'] +['ĠV', 'intage'] +['ĠApp', 'Delegate'] +['ĠPre', 'vention'] +['.se', 'parator'] +['ST', 'M'] +['(', 'room'] +['gener', 'ator'] +['Ġc', 'attle'] +['ĉ', 'Z'] +['ĠPart', 'icle'] +["'", '};Ċ'] +['Ġneighb', 'ours'] +['ĠState', 'less'] +['Ġalt', 'itude'] +['Ġsa', 'int'] +['об', 'ав'] +['Ġconv', 'inc'] +['ĠCont', 'ents'] +['Ġje', 'une'] +['(t', 's'] +['Serial', 'ization'] +['(c', 'ollection'] +['ĠJ', 'azz'] +['ĠD', 'od'] +['ĠR', 'och'] +['ac', 'io'] +['comm', 'ended'] +['DEF', 'INE'] +['.on', 'load'] +['Ġspecial', 'ty'] +['PL', 'ACE'] +['_MO', 'VE'] +['Ġaccount', 'able'] +['Re', 'uters'] +['Ġf', 'icken'] +['Ġde', 'pr'] +['W', 'ow'] +['V', 'oid'] +['.s', 'pace'] +['à¸', 'Ĺ'] +['Ġt', 'q'] +['ĠP', 'ets'] +['<', '$'] +['(C', 'urrent'] +['ber', 'ries'] +['plan', 'ation'] +['Ġlist', 'Of'] +['ĠTh', 'u'] +['ĠPR', 'INT'] +['Ġm', 'ismo'] +['Ġdo', 'i'] +['ch', 'k'] +['ĠUn', 'icode'] +['(', 'role'] +['Ġvir', 'gin'] +['<', 'Point'] +['_RESP', 'ONSE'] +['-h', 'ouse'] +['ĠVenez', 'uela'] +['EM', 'AIL'] +['Ġp', 'úb'] +['_ex', 'ist'] +['B', 'all'] +['.C', 'L'] +['re', 'ferences'] +['ĠBeautiful', 'Soup'] +['ĉ', 'Expect'] +['TH', 'IS'] +['Ñĥ', 'д'] +['b', 'ane'] +['Ġtemp', 'oral'] +['ER', 'IC'] +['et', 'as'] +['Ġrefresh', 'ing'] +['Ġsec', 'ular'] +['@', 'synthesize'] +['ac', 'cur'] +['Ġn', 'ella'] +['ĠS', 'OL'] +['.p', 'ipe'] +['Ch', 'annels'] +['èĩ', 'ª'] +['Ġinsert', 'ion'] +['á»', 'ĭ'] +['el', 'ia'] +['Ġadjust', 'able'] +['Can', 'ada'] +['ĠI', 'TEM'] +['Ġcur', 'ves'] +['ĠChe', 'ap'] +['let', 'ing'] +['Ġoptim', 'istic'] +['al', 'lo'] +['Ġpolit', 'ician'] +['_down', 'load'] +['=', 'edge'] +['ORT', 'H'] +['Ġmodel', 'o'] +['art', 'o'] +['.', 'rotate'] +['Ġs', 'elenium'] +['æĪ', 'ij'] +['_al', 'ias'] +['Ġrenown', 'ed'] +[".'", '.'] +['Ġc', 'zy'] +['Ġal', 'les'] +['.Com', 'piler'] +['ĠB', 'ass'] +['Conn', 'ector'] +['.R', 'ole'] +['L', 'INK'] +['Ġc', 'riterion'] +['lem', 'etry'] +['Success', 'fully'] +['/p', 'ng'] +['Ġey', 'eb'] +['asp', 'berry'] +['(', 'gr'] +['Ġd', 'angers'] +['Ġcorrect', 'ed'] +['Ġgl', 'ow'] +['Ġelabor', 'ate'] +['ĠB', 'ears'] +['aw', 'ai'] +['="', "'+"] +['Ġpromot', 'ions'] +['Ġmathematic', 'al'] +['Ġ"', '`'] +['_Generic', 'Class'] +['ĠChe', 'f'] +['.S', 'ort'] +['table', 'Name'] +['R', 'IC'] +['Ġvolunt', 'ary'] +['ĠBl', 'ade'] +['-e', 'lect'] +['ĠCom', 'bat'] +['ĠAb', 'ility'] +['Ġab', 'dom'] +['Ġd', 'uck'] +['T', 'mp'] +['åħ', '¨'] +['Ġer', 'ase'] +['.P', 'h'] +['ĠDefault', 's'] +['p', 'artment'] +['_US', 'B'] +['ê', 'te'] +[';', "'"] +['Ġp', 'ads'] +['ĠOb', 'amacare'] +['.T', 'otal'] +['Ġdiv', 'ert'] +['Ġcr', 'icket'] +['Ġrecre', 'ational'] +['(', 'red'] +['ĠC', 'le'] +['R', 'U'] +['Ġmist', 'aken'] +['ĠMont', 'ana'] +['Ġstr', 'ive'] +['_sl', 'ider'] +['ĠPl', 'astic'] +['Ġdecor', 'ated'] +['ĠV', 'P'] +['lic', 'o'] +['ĉf', 'alse'] +['Ġpre', 'fs'] +['(', '\\"'] +['_f', 'alse'] +['i', 'endo'] +['Ġ@', '$'] +['B', 'ucket'] +['act', 'ical'] +['ĠZ', 'hang'] +['.c', 'ols'] +['.B', 'inding'] +['Ġw', 'ax'] +['_ST', 'ORAGE'] +['Ġlaw', 'n'] +['Ġr', 'f'] +['.Sc', 'ene'] +['ĠCal', 'culator'] +['.d', 'esign'] +['Ġres', 'il'] +['л', 'ем'] +['E', 'mploy'] +['ĠPr', 'ices'] +['ĠP', 'WM'] +['ag', 'i'] +['.e', 'valuate'] +['ĉ', 'param'] +['Ġbr', 'ass'] +['bb', 'en'] +['Ġinflamm', 'ation'] +['ull', 'ivan'] +['Ġan', 'not'] +['Ġp', 'H'] +['iam', 'eter'] +['ĠB', 'TC'] +['(', 'box'] +['Story', 'board'] +['Ġcl', 'ay'] +['.assert', 'Raises'] +['|', 'string'] +['.App', 'ly'] +['Ġmatch', 'er'] +['und', 'ed'] +['Ġsatisf', 'ying'] +['Ġìł', 'ķ'] +['Render', 'ing'] +['_app', 'ro'] +['ind', 'rome'] +['AN', 'EL'] +['_f', 'ix'] +['br', 'ush'] +['.M', 'atch'] +['Ġsm', 'iling'] +['on', 'aut'] +['S', 'unday'] +['Ġdelet', 'ion'] +['Ġencour', 'ages'] +['P', 'ull'] +['Ġreven', 'ge'] +['Ġqu', 'arry'] +['tr', 'ade'] +['Ġc', 'ables'] +['(d', 'elta'] +['ites', 'pace'] +['Ġf', 'h'] +['.b', 'unifu'] +['Ġvi', 'el'] +['_IN', 'CLUDED'] +['ĠT', 'ail'] +['ad', 'ar'] +['of', 's'] +['Ġmet', 'als'] +['g', 'om'] +['_method', 's'] +['Ġn', 'j'] +['.St', 'd'] +['(w', 'in'] +['$', "('"] +['Ġt', 'urtle'] +['ur', 'on'] +['Ġen', 'rolled'] +['ĠH', 'z'] +['ĠBox', 'Decoration'] +['Ġp', 'ont'] +['rel', 'ationship'] +['B', 'i'] +['³', '»'] +['Ġmas', 'cul'] +['Ġsh', 'ades'] +['Ġv', 'r'] +['ĠLog', 'ic'] +['Ġa', 'in'] +['ĠD', 'IST'] +['Ġcoll', 'ar'] +['"', 'profile'] +['Generated', 'Value'] +['ĠP', 'ossible'] +['Ġe', 'ines'] +['ĥ', 'ģ'] +['.time', 'out'] +['ĠE', 'c'] +['Ġjer', 'sey'] +['.D', 'ouble'] +['Ġqual', 'ifying'] +['v', 'or'] +['CRE', 'EN'] +['_A', 'pp'] +['_rec', 'v'] +['Ġali', 'ens'] +['It', 's'] +['E', 'sc'] +['i', 'ator'] +['ĠE', 'clipse'] +['Ġg', 'h'] +['V', 'ict'] +['ĉ', 'html'] +['to', 'o'] +['.', 'const'] +['Ġant', 'erior'] +['ĠW', 'u'] +['(key', 's'] +['Ġul', 'tr'] +['_p', 'oly'] +['ĠT', 'ap'] +['ĠB', 'ud'] +['A', 'WS'] +['Ġcrash', 'es'] +['_t', 'ot'] +['Cont', 'in'] +['-h', 'anded'] +['alth', 'ough'] +['à¸', 'ļ'] +['ific', 'ent'] +['Ġde', 've'] +['ut', 'ory'] +['ĠW', 'orth'] +['_M', 'S'] +['Ġfloor', 'ing'] +['Ġsell', 'ers'] +['ĠThank', 'sgiving'] +['Ġp', 'ng'] +['Ġval', 'ores'] +['Ġslee', 've'] +['Ġfil', 'le'] +['Ð', 'IJ'] +['Ġappoint', 'ments'] +['Ġv', 'im'] +['User', 'Info'] +['BO', 'OST'] +['Ġpos', 'ed'] +['initial', 'ized'] +['.product', 's'] +['ĠLeaders', 'hip'] +['man', 'uel'] +["'", '%'] +['em', 'arks'] +['Per', 'centage'] +['(d', 'ist'] +['.', 'avatar'] +['(h', 'Object'] +['ä»', 'Ĭ'] +['_', 'iff'] +['ic', 'one'] +[';', ')'] +['_n', 'il'] +['Ġab', 'ol'] +['е', 'ÑģÑĤ'] +['Ġven', 'ues'] +['.Con', 'vert'] +['!', "')Ċ"] +['.B', 'itmap'] +['sk', 'in'] +['_C', 'OLUMN'] +['Re', 'v'] +['G', 'RESS'] +['g', 'ow'] +['Ġw', 'ished'] +['tract', 's'] +['.assert', 'False'] +['Ġscreens', 'hot'] +['Ġfo', 'is'] +['Com', 'b'] +['Line', 'Width'] +['ĠGr', 'ab'] +['Ġint', 'ensive'] +['ĉ', 'sh'] +['+', ')'] +['.first', 'Name'] +['_PRO', 'CESS'] +['Ġt', 'ilt'] +['it', 'ored'] +['.L', 'OG'] +['Ġb', 'ak'] +['Ġintention', 'ally'] +['.play', 'ers'] +['(c', 'anvas'] +['))', ')čĊ'] +['.Pro', 'vider'] +['_P', 'UBLIC'] +['T', 'alk'] +['ĠL', 'iv'] +['ched', 'ulers'] +['Ġl', 'c'] +['ad', 'ic'] +['feature', 'd'] +['.res', 'ources'] +['Full', 'Name'] +['Ġmean', 'while'] +['B', 'uffers'] +['Ġres', 'olver'] +['ĠS', 'AP'] +['_T', 'E'] +['G', 'NU'] +['ĠForms', 'Module'] +['_', 'wh'] +['ĠS', 'we'] +['.widget', 's'] +['Ġcabin', 'ets'] +['Ġsus', 'cept'] +['ĠB', 'ott'] +['activ', 'ex'] +['av', 'ar'] +['ant', 'ics'] +['Ġ"', '="'] +['_k', 'wargs'] +['Ġgame', 'Object'] +['ĠAng', 'le'] +['.I', 'ter'] +['mar', 'sh'] +['ĠB', 'irthday'] +['ĠC', 'MS'] +['request', 's'] +['ĠPear', 'l'] +['_E', 'OL'] +['Ġlin', 'ux'] +['(', 'org'] +['_M', 'ouse'] +['.con', 'structor'] +['Ġz', 'd'] +['Ġk', 'icks'] +['art', 'isan'] +['Ġe', 'ax'] +['K', 'n'] +['pon', 'ge'] +['ĠFin', 'land'] +['Ġmet', 'res'] +['ĠAss', 'essment'] +['part', 'ner'] +['/', 'pre'] +['!', "',Ċ"] +['[', 'Int'] +['Ġos', 'lo'] +['date', 'picker'] +['/', 'String'] +['op', 'lay'] +['ĠHe', 'brew'] +[',', 'double'] +['Ġtrab', 'al'] +['+"', '\\'] +['ĉ', 'EIF'] +['/', 'text'] +['_F', 'IRST'] +['ĠP', 'ete'] +['Ġe', 'go'] +['Ġextr', 'as'] +['P', 'DO'] +['Ġreg', 'ulate'] +['ĠQ', 'Widget'] +['st', 's'] +['ĠSh', 'ows'] +['ĠN', 'HS'] +['.c', 'ourse'] +['p', 'thread'] +['ĠF', 'uel'] +['.t', 'imes'] +['ĠÂ', '°'] +['Ġstr', 'ides'] +['($', "('#"] +['(', 'words'] +['Ġrhyth', 'm'] +['Ġsp', 'ont'] +['Ġsens', 'ation'] +['Ġsp', 'ike'] +['C', 'losing'] +['页', 'éĿ¢'] +['N', 'umeric'] +['Ġbreat', 'he'] +['Ġfin', 'ale'] +['_F', 'ACT'] +['in', 'ion'] +['Ġch', 'ill'] +['Ġform', 'ally'] +['ANG', 'ED'] +["Ġ'", ":'"] +['ĠпÑĢ', 'и'] +['a', 'q'] +['ĠFab', 'ric'] +['(l', 'at'] +['ĠPr', 'incipal'] +['Ġer', 'ro'] +['oc', 'ale'] +['N', 'om'] +['Ġf', 'ost'] +['_C', 'USTOM'] +['.int', 'ellij'] +['ert', 'ools'] +['Ġcl', 'asse'] +['adi', 'ents'] +['Ġfundra', 'ising'] +['EN', 'E'] +['_OPTION', 'S'] +['_', 'ob'] +['//', '}Ċ'] +['Ġprote', 'ctions'] +['.se', 'ed'] +['N', 'V'] +['term', 'inal'] +[';;', ';'] +['P', 'redicate'] +['Ġì', '¶'] +['Ġbomb', 'ing'] +['G', 'F'] +['Ġch', 'ew'] +['))', ').'] +['qual', 'ified'] +[']', '={'] +['list', 'en'] +['C', 'ENT'] +['d', 'igest'] +['E', 'ast'] +['Ġd', 'iver'] +['Ġend', 'points'] +['Ġe', 'e'] +['Ġcolle', 'ague'] +['Ġdissert', 'ation'] +['_com', 'mit'] +['_D', 'AT'] +['.', 'rc'] +['Ġbre', 'asts'] +['ĠR', 'ug'] +['ĠP', 'il'] +['Contract', 's'] +['ĠBry', 'an'] +['Web', 'View'] +['Ġconcent', 'rate'] +['ĠIn', 'ner'] +["Ġ'", '|'] +['std', 'out'] +['_S', 'ub'] +['>', '-->Ċ'] +['V', 'ol'] +['ĠS', 'SD'] +['))', '),'] +['.', 'Optional'] +['Ġnurs', 'es'] +['Ġor', 'b'] +['_', 'pe'] +[');čĊ', 'čĊčĊ'] +['pl', 'aced'] +['ess', 'er'] +['Ġther', 'apeutic'] +['Ġwhites', 'pace'] +['Ġa', 'ston'] +['Success', 'ful'] +['Ġpr', 'aised'] +['ĠW', 'es'] +['Ġe', 'ighth'] +['ir', 'al'] +['Ġvrou', 'w'] +['Ġf', 'action'] +['_b', 'ias'] +['Ġw', 'itch'] +['Ġnp', 'c'] +['(s', 'b'] +['ĠRod', 'rig'] +['_b', 'ig'] +['Dep', 'endency'] +['ĠAb', 'raham'] +['ard', 'i'] +['C', 'AR'] +['n', 'os'] +['Ġabund', 'ance'] +['Ġnut', 'rients'] +['in', 'stein'] +['.V', 'ert'] +['ĠI', 'SS'] +['<', 'U'] +['Ġsum', 's'] +['_h', 'ist'] +['Ġfar', 'mer'] +['ĠA', 'br'] +['Sh', 'ot'] +['ĠBad', 'Request'] +['Ġh', 'ass'] +['ĠR', 'ails'] +['Ġaffili', 'ated'] +['æĿ', '¥'] +['Ġer', 'f'] +['IN', 'F'] +['ĠView', 'Holder'] +['min', 'i'] +['ĠR', 'oth'] +['Ġfaith', 'ful'] +['ĠPhill', 'ips'] +['AND', 'OM'] +['].', '['] +['_P', 'AY'] +['ĠAr', 'ctic'] +['f', 'aker'] +['D', 'igit'] +['M', 'ale'] +['std', 'err'] +['se', 'ys'] +['Ġ', 'Å¡'] +['_rem', 'ote'] +['li', 'que'] +['Ġin', 'def'] +['ĠIndust', 'ries'] +['it', 'ra'] +['_p', 'airs'] +['<', 'iostream'] +['Ġsal', 'aries'] +['ik', 'en'] +['.F', 'rame'] +['PL', 'IC'] +['_S', 'PEC'] +['ĠMed', 'iterr'] +['Ġsystem', 'atic'] +['Ġinter', 'rog'] +['Icon', 'Button'] +['se', 'a'] +['int', 'ro'] +['ĠIss', 'ues'] +['enc', 'rypted'] +['Ġintern', 'ationally'] +['Ġsn', 'printf'] +['Ġpast', 'a'] +['ĠBrad', 'ley'] +['_', 'Status'] +['AL', 'K'] +['_P', 'AD'] +['.l', 'aunch'] +['<', 'select'] +['Ġhar', 'dest'] +['Ġph', 'y'] +['Ġ((', '*'] +['-s', 'lide'] +['ĠNob', 'ody'] +['S', 'u'] +['Ġas', 'ÃŃ'] +['close', 'st'] +['_initial', 'izer'] +['Ġsupport', 'er'] +['-g', 'en'] +['Ġt', 'ales'] +['Ġcor', 'p'] +['_f', 'u'] +['s', 'at'] +['ne', 'ighbor'] +['.M', 'igrations'] +['Ġal', 'gun'] +['Ġsin', 'on'] +['.S', 'pec'] +['?', ',Ċ'] +['.G', 'L'] +['m', 'ale'] +['Ġmon', 'itors'] +['yl', 'an'] +['-L', 'icense'] +['.m', 'atches'] +['ĠA', 'BS'] +['ĠM', 'ast'] +['ĠW', 'allet'] +['($', '("#'] +['Dir', 'ty'] +['Ġco', 'pe'] +['Ġinterpol', 'ation'] +['ous', 'ed'] +['ĠJ', 'ets'] +['.F', 'LAG'] +['.C', 'ancel'] +['.Event', 's'] +['ne', 'ver'] +['ĠM', 'Hz'] +['>', 'D'] +['Ġs', 'ervlet'] +['bast', 'ian'] +['Ġ>', '&'] +['S', 'ID'] +['_cl', 'k'] +['Ġdiv', 'isions'] +['}', "',Ċ"] +['Ġd', 'ildo'] +['Ġpar', 'ade'] +['m', 'ajor'] +['Ġab', 'oard'] +[';', '++'] +['Ġf', 'usion'] +['"},', '{"'] +['ĠDialog', 'Result'] +['ĉ', 'arr'] +['-', 'em'] +['_n', 'r'] +['(h', 'andler'] +['.N', 'ET'] +['.Xtra', 'Reports'] +['ĠSh', 'ah'] +['ĠB', 'rief'] +['-', ','] +['Ġprec', 'io'] +['ĉĉĉ', 'ĠĠĠĠĠĠ'] +['Ġt', 'ant'] +['ĠGrand', 'e'] +['/', 'xml'] +['_IC', 'ON'] +['ĠR', 'etro'] +['un', 'que'] +['Ġn', 'ag'] +['to', 'Fixed'] +['X', 'L'] +['Ġdecl', 'aring'] +['ĠCon', 'crete'] +['ĠAm', 'azing'] +['ĉprint', 'k'] +['Ġdeb', 'ates'] +['D', 'ATED'] +['Ġaest', 'hetic'] +['emet', 'ery'] +['Routing', 'Module'] +['ĠNash', 'ville'] +['W', 'AYS'] +['Ġw', 'olf'] +['Ġobserv', 'ers'] +['OT', 'A'] +['ans', 'on'] +['Ġe', 'a'] +['Ġgreen', 'house'] +['ĵį', 'ä½ľ'] +['Ġst', 'air'] +['Ġimmigr', 'ant'] +['_app', 'ly'] +['pe', 'are'] +['ĠBloom', 'berg'] +['_PL', 'AYER'] +['Res', 'p'] +['æŃ', '£'] +['Cho', 'oser'] +['ĠI', 'Collection'] +['P', 'eter'] +['Er', 'ro'] +['.detect', 'Changes'] +['Map', 's'] +['Ġs', 'queeze'] +['ĠHom', 'es'] +['weg', 'ian'] +['Ġformat', 'ting'] +['Ġnegot', 'iate'] +['ul', 'd'] +['ĠN', 'ep'] +['ĠQ', 'B'] +['Ġeconom', 'ies'] +['Ġ*/', ','] +['Ġredu', 'nd'] +['ĠA', 'ber'] +['.IsNullOr', 'WhiteSpace'] +['yc', 'led'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĊ'] +['_S', 'h'] +['Ġske', 'pt'] +['Ġre', 'created'] +['Ġget', 'Type'] +['Ġmarg', 'ins'] +['Ġcolon', 'ial'] +['ch', 'arts'] +['//', '@'] +['Ġprocess', 'ors'] +['è¯', '´'] +['b', 'atis'] +['æĦ', 'ı'] +['ator', 'io'] +['mention', 'ed'] +['P', 'atient'] +['Ġpre', 'y'] +['Check', 'box'] +['_x', 'path'] +['.s', 'kip'] +['ĠMorm', 'on'] +['ĠMemory', 'Stream'] +['CRE', 'MENT'] +['Ġk', 'u'] +['m', 'eld'] +['\\', 'Data'] +['ĠK', 'ernel'] +['il', 'tr'] +['éĢ', 'ģ'] +['(', 'profile'] +['Car', 'bon'] +['RO', 'LE'] +['(', 'pl'] +[']', '*('] +['.m', 'emory'] +['Ġmed', 'al'] +['Ġadvis', 'or'] +['it', 'ät'] +['Ġh', 'dr'] +['ier', 'ung'] +['ĠProvid', 'es'] +['(', 'alpha'] +['Ġteen', 'agers'] +['-', 'parser'] +['.L', 'atLng'] +[']', '()Ċ'] +['Ġfel', 'ony'] +['ĉĉĉĊ', 'ĉĉĉĊ'] +['BO', 'OK'] +['Ġsl', 'ash'] +['Ġclear', 'fix'] +['ĠPro', 'phet'] +['å®', '¹'] +['right', 'ness'] +['-f', 'i'] +['.k', 'ind'] +['ert', 'on'] +['J', 'im'] +['Ġmanip', 'ulate'] +['Ġworks', 'heet'] +['ol', 'in'] +['st', 'ars'] +['Ġart', 'ifact'] +['_EM', 'PTY'] +['ĉm', 'ain'] +['-------------', ''", ';'] +['Ġexpress', 'ing'] +['ĠI', 'Q'] +['ĠF', 'act'] +['/************************************************************************', '*******Ċ'] +['_m', 'ass'] +['))', ':'] +['Ġcon', 'dom'] +['Ġcreate', 'State'] +['omet', 'own'] +['Ġir', 'r'] +['Ġ>', '('] +['>', 'B'] +['iter', 'ation'] +['ãĥ', 'ª'] +['Ġshirt', 's'] +['ount', 'y'] +['->', '$'] +['_S', 'IGN'] +['ĠD', 'ale'] +['Ġj', 'j'] +['E', 'asy'] +['F', 're'] +['ĠN', 'y'] +['Ġch', 'lor'] +['match', 'ed'] +['ĠG', 'erm'] +['-', 'UA'] +['ĠN', 'athan'] +['educ', 'ation'] +['-y', 'ard'] +['-', 'che'] +['h', 'ouses'] +['r', 'itional'] +['Ġprox', 'imity'] +['Ġdies', 'em'] +['áºŃ', 'p'] +['Ġd', 'rought'] +['.a', 'udio'] +['ĠLe', 'o'] +['Ġfavor', 'able'] +['in', 'ch'] +['ĠD', 'aw'] +['rib', 'ly'] +['_st', 'udent'] +['id', 'able'] +['O', 'VE'] +['Ġlack', 's'] +['ounc', 'ing'] +['.b', 'usiness'] +['Ġre', 'open'] +['may', 'be'] +['_G', 'LOBAL'] +['Ġdress', 'es'] +['ĠEd', 'wards'] +['ens', 'ible'] +['ĠHard', 'ware'] +['ĠEx', 'cellent'] +['ĠTime', 'Unit'] +['CTION', 'S'] +['Ġsched', 'ules'] +['Ġseg', 'ue'] +['Op', 'ens'] +['am', 'men'] +['-', 'Identifier'] +['Ġst', 'aring'] +['Ġhapp', 'ily'] +['ĠH', 'ob'] +["'", '_'] +['Ġ"', ');'] +['ament', 'os'] +['et', 'ched'] +['Ġ/>', '}Ċ'] +['.', 'Users'] +['Ġinterrupt', 'ed'] +['Contact', 's'] +['Ġreg', 'istro'] +['in', 'burgh'] +['CH', 'A'] +['_', 'imp'] +['ph', 'is'] +['s', 'ay'] +['Ġretail', 'er'] +['.N', 'ODE'] +['/', 'maps'] +['_L', 'AST'] +['ĠCh', 'arge'] +['_g', 'uard'] +['Coll', 'ider'] +['ĠStateless', 'Widget'] +['":', '["'] +['("', '../../'] +['iox', 'ide'] +['ĠS', 'und'] +["Ġ''", ';'] +['un', 'set'] +['add', 'Widget'] +['л', 'Ñİ'] +['el', 'les'] +['alk', 'er'] +['A', 'rc'] +['Ġded', 'uct'] +['G', 'UILayout'] +['ĠV', 'illa'] +['Ġfor', 'bidden'] +['_', 'where'] +['Ġ\\', '/'] +['ĠT', 'ib'] +['_A', 'X'] +[']', 'čĊčĊ'] +['ĠB', 'ir'] +['Ġb', 'end'] +['ĠMA', 'KE'] +['ĠM', 'ET'] +['Ġfut', 'ures'] +['Ġweight', 'ed'] +['""', '"čĊ'] +['Ġauthor', 'ize'] +['(pro', 'gram'] +['},', '{"'] +['Ġcoeff', 'icients'] +['ê', 's'] +['Per', 'Page'] +['ĠBath', 'room'] +['ĠPublish', 'ing'] +['G', 'PL'] +['Ġsub', 'missions'] +['ĠNUM', 'BER'] +['j', 'Äħ'] +['Ġaddition', 'ally'] +['em', 'pre'] +['ĠSh', 'el'] +['ot', 'yp'] +['S', 'olution'] +['Ġth', 'under'] +['_', 'ec'] +['ĠĊ', 'ĠĠĠĠĊ'] +['ĠF', 'ellow'] +['Ġk', 'ay'] +['Ġnew', 'State'] +['ONT', 'AL'] +['Im', 'plementation'] +['.L', 'ook'] +['Ġ', 'ents'] +['Ġl', 'ors'] +['ĠB', 'IG'] +['f', 'ab'] +['Ġaver', 'aged'] +['ĠFe', 'edback'] +['ĠW', 'ells'] +['Ġm', 'artial'] +['Ġind', 'ul'] +['ĠComm', 'unist'] +['ĠFore', 'x'] +['ĠAgricult', 'ure'] +['"', '['] +['Ġqu', 'ar'] +['ĠK', 'ont'] +['ĉ', 'view'] +['.', 'Bytes'] +['des', 'ktop'] +['ĠM', 'akes'] +['akes', 'peare'] +['.Null', 'able'] +['Ġspot', 'light'] +['V', 'B'] +['ow', 'y'] +['(t', 'orch'] +['tr', 'idge'] +['_b', 'ounds'] +['Ġapolog', 'ize'] +['.add', 'Item'] +['ant', 'd'] +['*', ');Ċ'] +[',', 'u'] +['(g', 'en'] +['ç»', 'ĵ'] +['re', 'ator'] +['ĠC', 'ord'] +['ou', 'pper'] +['.m', 'etro'] +['Ġ', 'ew'] +['ĠW', 'ORD'] +['.A', 'fter'] +['Ġdet', 'ained'] +['ĠHam', 'mer'] +['ex', 'isting'] +['Ġo', 'st'] +['Ġmon', 'ument'] +['-c', 'ustom'] +['User', 'ID'] +['ĠN', 'om'] +['Ġre', 'jection'] +['(d', 'im'] +['Ġsingle', 'ton'] +['ĉd', 'ie'] +['ari', 'ance'] +['re', 'ports'] +[']', '!='] +['eld', 'a'] +['Ġpreval', 'ence'] +['_reg', 's'] +['."', '.'] +['Ġfemin', 'ist'] +['Code', 'c'] +['Ġ', '**Ċ'] +['(label', 's'] +['_M', 'ARK'] +['FA', 'ILED'] +['Ġadminister', 'ed'] +['W', 'N'] +['ĠĠĠĠĠĠĠĠ', 'ĉĉ'] +['Ġn', 'oun'] +['w', 'ig'] +['Ġg', 'otta'] +['Ġr', 'if'] +['-', 'im'] +['ĠPaul', 'o'] +['ĠCommand', 'Type'] +[']', '))ĊĊ'] +['-z', 'ero'] +['Tr', 'aining'] +['Ġl', 'ord'] +['_', 'art'] +['re', 'ddit'] +['C', 'ert'] +['Ġpes', 'o'] +['R', 'ot'] +['Ġend', 'anger'] +['.d', 'r'] +['user', 'Info'] +['un', 'ts'] +['n', 'v'] +['ĠTrail', 'er'] +['-f', 'irst'] +['(m', 'ake'] +['Ġbenef', 'ici'] +['-bl', 'ack'] +['i', 'ÃŁ'] +['Ġund', 'oubtedly'] +['Ġm', 'ex'] +['ĠAnc', 'ient'] +['(', 'as'] +['Ġdes', 'cent'] +['P', 'ick'] +['Ġrep', 'lica'] +['$', 'obj'] +['ä', 'hr'] +['Ġar', 'rows'] +['ft', 'y'] +['ĠLib', 'ya'] +['ug', 'a'] +['charg', 'ed'] +['T', 'ur'] +['Ġh', 'omic'] +['iss', 'en'] +['ĠF', 'ake'] +['Ġbe', 'ers'] +['Ġsc', 'attered'] +['(', 'Time'] +['UT', 'IL'] +['Ġbureauc', 'r'] +['/pl', 'ain'] +['Ġstick', 'ing'] +['FA', 'IL'] +['ĠC', 'ovid'] +['Th', 'ird'] +['_p', 'resent'] +['ĠPier', 're'] +['Ġë', 'ª'] +['Ġ[...', ']ĊĊ'] +['Pro', 'b'] +['ĠTra', 'ffic'] +['ica', 'o'] +['do', 'ctor'] +['Ġ),', 'ĊĊ'] +['T', 'abs'] +['al', 'u'] +['ï¼ļ', 'âĢľ'] +['Ġinher', 'ent'] +['_N', 'o'] +['rit', 'is'] +['ĠPro', 'of'] +['.b', 'asename'] +['ä¼', 'ļ'] +['Ġch', 'im'] +['ĠProt', 'ected'] +['c', 'rit'] +['Ġpr', 'one'] +['Ġк', 'он'] +['ĠHero', 'es'] +['Ġan', 'xious'] +['Ġan', 'os'] +['Ġweek', 'ends'] +['Ġs', 'ext'] +['Ġredu', 'cer'] +['=', 'UTF'] +['h', 'alf'] +['ĠS', 'aw'] +['.m', 'm'] +['Ġnue', 'va'] +['.current', 'Target'] +['.l', 'ua'] +['_EXT', 'ENSION'] +['ĉ', 'reg'] +['ĠC', 'trl'] +['_', 'align'] +['accept', 'able'] +['Ġrush', 'ing'] +['fr', 'ac'] +['Ġbo', 'asts'] +['F', 'ive'] +['Â', '±'] +['ĠTem', 'perature'] +['>', '):'] +['Ġchar', 'ter'] +['RE', 'ATED'] +['Ġsubject', 'ed'] +['Ġop', 'c'] +['health', 'y'] +['使', 'ç͍'] +['ĠScient', 'ific'] +['Ġfra', 'u'] +['ri', 'ages'] +['à¸', 'Ķ'] +['.in', 'ventory'] +['ation', 'ale'] +['M', 'ad'] +['min', 'utes'] +['>>', '();Ċ'] +['ĠEn', 'v'] +['Ġrecord', 'ings'] +['Ġsusp', 'icion'] +['sql', 'ite'] +['ĉ', 'read'] +['ãģ', '¦'] +['Ġwor', 'ries'] +['.put', 'String'] +['ĠSh', 'anghai'] +['(', 'uid'] +['r', 'er'] +['ĠvÃŃ', 'de'] +['")', ':'] +['Ġmethod', 'ology'] +['Ġк', 'оÑĤоÑĢ'] +['cc', 'c'] +['av', 'ad'] +['Ġindu', 'ction'] +['ĉ', 'Thread'] +[',', 'string'] +['ạ', 'i'] +['neh', 'men'] +['u', 'ition'] +['Ġ*', '__'] +['.em', 'f'] +['Ġì', 'ľ'] +['/th', 'emes'] +['ĠN', 'ine'] +['.', 'One'] +['ĠEm', 'bed'] +['Ġf', 'az'] +['u', 'ations'] +['Ġpriv', 'ately'] +['Ġl', 'ing'] +['[', 'F'] +['ush', 'i'] +['Ġlaunch', 'es'] +['(', 'KEY'] +['G', 'MT'] +['Ġaim', 'ing'] +['pat', 'ible'] +['ĠB', 'iden'] +['i', 'w'] +['ĠD', 'egree'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġ$', "('<"] +['á', 'rios'] +['to', 'UpperCase'] +['ìł', 'ľ'] +['ĠE', 'UR'] +['Ġovers', 'ight'] +['Ġtable', 'sp'] +['Up', 'dates'] +['.m', 'akedirs'] +['Ġhum', 'idity'] +['/', 'template'] +['Al', 'ways'] +['(', 'IS'] +['_c', 'ert'] +['D', 'ig'] +['Ġunder', 'way'] +['ort', 'on'] +['ĠHur', 'ricane'] +['Ġsp', 'ends'] +['ĠSeg', 'ment'] +['Ġfl', 'ies'] +['ĠT', 'oggle'] +['ĠLyn', 'ch'] +['Ġs', 'enses'] +['ĠK', 'os'] +['set', 'Enabled'] +['ist', 'ically'] +['Ġtest', 'er'] +['Ġadministr', 'ators'] +['Ġtag', 'ged'] +['Ð', 'ĵ'] +['Ġshort', 'cut'] +['ĠRes', 'olution'] +['Ġsuperv', 'ision'] +['ĠAsh', 'ley'] +['Tr', 'acking'] +['ul', 'atory'] +['and', 'el'] +['ist', 'en'] +['Ġun', 're'] +['(d', 'iff'] +['ANT', 'S'] +['Ġr', 'ider'] +['Ġs', 'Äħ'] +['.S', 'eries'] +['_', 'orders'] +['ORIZ', 'ONTAL'] +['Ġret', 'ention'] +['ãĢĤ', '', 'čĊčĊ'] +['Ġdi', 'agonal'] +['ĠC', 'ancellationToken'] +['_', 'Internal'] +['Ġru', 'in'] +['.Q', 't'] +['ocr', 'atic'] +['T', 'el'] +['ĠAn', 'swers'] +['m', 'atic'] +['Ġx', 'p'] +['at', 'em'] +['_j', 'obs'] +['_', 'any'] +['Ġsen', 'iors'] +['Ġland', 'mark'] +['ĠQ', 'List'] +['Ġman', 'eu'] +['ot', 'ify'] +['/', '";Ċ'] +['/', 'server'] +['ĠPhil', 'osoph'] +['uten', 'ant'] +['(', 'io'] +['h', 'z'] +['Ġauthentic', 'ated'] +['d', 'v'] +['-', 'Compatible'] +['Origin', 'ally'] +[',', 'function'] +['ãĢĤ', 'čĊ'] +['ĠRepresent', 'ative'] +['as', 'ily'] +['irc', 'uit'] +['.d', 't'] +['(m', 'ath'] +['.M', 'arshal'] +['[', ','] +['ĠC', 'ities'] +['_', 'turn'] +['|', ')Ċ'] +['Ġcant', 'idad'] +['al', 'ter'] +['ĉ', 'ui'] +['ĠNe', 'braska'] +['Ġsk', 'irt'] +['.b', 'g'] +['Shared', 'Preferences'] +['(', 'style'] +['Ġg', 'rief'] +['g', 'ew'] +['Ġsaf', 'eg'] +['ol', 'ang'] +['_l', 'ists'] +['ì', 'Ľ'] +['Ġgran', 'ite'] +['Ġhott', 'est'] +['.j', 'dbc'] +['.C', 'ustomer'] +['Ġâī', '¤'] +['Ġwa', 'ar'] +['_sc', 'ene'] +["+'", '/'] +['ĠJ', 'TextField'] +['Ġse', 'ating'] +['Ġwe', 'ars'] +['Ġ`', '/'] +['C', 'ases'] +['ĠY', 'outube'] +['ı', 'm'] +['Ġbal', 'con'] +[',', 'G'] +['Meta', 'Data'] +['-', 'price'] +['SC', 'R'] +['Un', 'ity'] +['Ġtr', 'unk'] +['={`', '${'] +['Ġearthqu', 'ake'] +['Part', 'ial'] +['Ġsub', 'st'] +['Ġelim', 'in'] +['="', "'."] +['//*', '[@'] +['Ġsuperv', 'isor'] +['vro', 'let'] +['_', 'article'] +['Ġp', 'ane'] +['b', 'io'] +['Ġmot', 'ors'] +['N', 'M'] +['F', 'rank'] +['Ġon', 'ion'] +['-', 'word'] +['Item', 'ClickListener'] +['Ġb', 'rit'] +['end', 'encies'] +['Com', 'puter'] +['_r', 'unning'] +['(', 'day'] +['-', 'he'] +['(n', 'amed'] +['ĠS', 'ach'] +['о', 'Ñĩ'] +['c', 'ampaign'] +['.Ab', 'stract'] +['(w', 'rapper'] +['.p', 'ay'] +['Ġu', 'w'] +['Ge', 'o'] +['r', 'ails'] +['/', 'select'] +['icht', 'e'] +['son', 's'] +['E', 'VENT'] +['Ġal', 'iment'] +['Pro', 'viders'] +['A', 'wait'] +['_INTER', 'VAL'] +['.', 'off'] +['Ġgl', 'uten'] +['_cl', 'oud'] +['Ġw', 'en'] +['.ex', 'tract'] +['ĉ', 'button'] +['/', 'MM'] +['Part', 'y'] +['Ġdem', 'ographic'] +['_err', 'no'] +['Ġh', 'iking'] +["('", "')Ċ"] +['",', '@"'] +['Ġw', 'it'] +['r', 'á'] +['olog', 'ie'] +['ĠSt', 'yles'] +['ĠBrowser', 'Module'] +['.Request', 'Mapping'] +['ic', 'ans'] +['P', 'AGE'] +['cre', 'ation'] +['ĠF', 'erguson'] +['ud', 'ed'] +['num', 'bers'] +['ĠGT', 'K'] +['Ġpresent', 'ations'] +['ĠB', 'obby'] +['_s', 'pan'] +['est', 'yle'] +['Ġilleg', 'ally'] +['abel', 'a'] +['Ġbattle', 'field'] +['cap', 'acity'] +['ter', 'ror'] +[']', '");Ċ'] +['Ġwar', 'rior'] +['le', 'ader'] +['ĠDB', 'G'] +['ĠRe', 'venue'] +['Ġvig', 'il'] +['Ġcounter', 'parts'] +['(', 'Error'] +['ACT', 'ER'] +['Ġhe', 'eft'] +['Ġselection', 's'] +['ze', 'ug'] +['t', 'om'] +['-t', 'wo'] +['.', ';Ċ'] +['_st', 'atement'] +['ĠA', 'id'] +['ĠV', 'ul'] +['_r', 'gb'] +['Ġpr', 'izes'] +['Ġedit', 'able'] +['ĉ', 'form'] +['ın', 'ı'] +['.de', 'cor'] +['D', 'emo'] +['lic', 'es'] +['Ġen', 'ctype'] +['rat', 'ulations'] +['ĠR', 'OS'] +['_ch', 'ars'] +['ĠJ', 'ahr'] +['part', 'ial'] +['Ñĥ', 'ÑĤ'] +['ĠRe', 'ceive'] +['ĠL', 'ands'] +['AP', 'TER'] +['Ġch', 'opped'] +['..', '"'] +['ĠAn', 'aly'] +['ĠU', 'ID'] +['ĠR', 'adeon'] +['ĠB', 'ee'] +['Ġun', 'm'] +['>', 'M'] +['.find', 'all'] +['Token', 'izer'] +['ĠWH', 'AT'] +['Ġs', 'j'] +['D', 'rawing'] +['E', 'ss'] +['ON', 'D'] +['Ĭ', '¶'] +['(p', 'acket'] +['âĢĶ', 'but'] +['Inv', 'ocation'] +['ĠN', 'uclear'] +['?', ';Ċ'] +['Ġgrand', 'es'] +['ĠC', 'rypt'] +['rem', 'ark'] +["Ġ'../../", '../../'] +['Ġin', 'ability'] +['m', 'agic'] +['c', 'ats'] +['Ġsim', 'ulate'] +[':', '${'] +['in', 'flate'] +['Ġen', 'er'] +[':', 'NO'] +['ip', 'les'] +['Ġmer', 'it'] +['ĠR', 'ated'] +['Ġgl', 'ue'] +['/b', 'log'] +['Ġg', 'ren'] +['Ġthr', 'illed'] +['.C', 'H'] +['unc', 'an'] +['ĠPR', 'IMARY'] +['Ġper', 'sec'] +['Ġfe', 'ared'] +['.M', 'IN'] +['ĠThe', 'ater'] +['é', 'Ĵ'] +['ategor', 'ie'] +['æ®', 'µ'] +['Ġappet', 'ite'] +['s', 'quare'] +['ĠAlex', 'and'] +['.User', 'Id'] +['_g', 't'] +['_', 'enter'] +['Ġgradu', 'ates'] +['Fragment', 'Manager'] +['Author', 'ize'] +['-N', 'LS'] +['(M', 'y'] +['Ġtri', 'umph'] +['ust', 'ing'] +['_PARAM', 'S'] +['Char', 'acters'] +['(:', ',:,'] +['_B', 'UILD'] +['M', 'Hz'] +['Ġwash', 'ed'] +['Ġun', 'cle'] +['Ste', 've'] +['ard', 'own'] +['', '${'] +['_confirm', 'ation'] +['Ġtro', 'phy'] +['Work', 's'] +['ĠElect', 'ronics'] +['ĠMediterr', 'anean'] +['_m', 'etrics'] +['Ġannounc', 'ing'] +['ĠD', 'AY'] +['_pro', 'to'] +['Ġp', 'ear'] +['base', 'Url'] +['ĉĉĉĉĉĉĉĉ', 'Ċ'] +['Ġcoord', 'ination'] +[':', 'N'] +['.an', 'imate'] +['ĠC', 'otton'] +['_h', 'it'] +['â', 'ľ'] +['Ġjet', 'zt'] +['if', 'ter'] +['(f', 'ields'] +['own', 'load'] +['ific', 'acion'] +['.c', 'uda'] +['ĠLi', 'u'] +['>', 'equals'] +['ĠA', 'ce'] +['ÑĢаÐ', '¼'] +['ĠSuper', 'man'] +['ĠGarc', 'ia'] +['Ġarrest', 's'] +['ag', 'ar'] +['Ġ{}', ')'] +['Ġmac', 'ros'] +['rou', 'pe'] +['ê', 'tre'] +['Ġtw', 'isted'] +['str', 'uments'] +['_', '("'] +['_', 'vertices'] +['ĠTrans', 'ition'] +['и', 'к'] +['[', 'max'] +['m', 'ind'] +['Ġaccess', 'Token'] +['Ġun', 'le'] +['m', 'us'] +['c', 'op'] +['ĠF', 'actor'] +['Ġcon', 'ced'] +['Ġre', 'tr'] +['.l', 'inalg'] +['-s', 'lider'] +['ob', 'l'] +['_Static', 'Fields'] +['Ġz', 'ombie'] +['s', 'elling'] +['Ġch', 'ap'] +['Ġsh', 'aking'] +['ĠTrans', 'late'] +['ĠAm', 'sterdam'] +['ĠE', 'TH'] +['_EX', 'TERN'] +['k', 'd'] +['_d', 'isc'] +['Ġpreced', 'ing'] +['Ġpri', 'x'] +['Object', 'Name'] +['_mod', 'ified'] +['ard', 'ware'] +['Ġ?>', '">'] +['ĠD', 'W'] +['`', '${'] +['Ġ?>', '">ĊĊ'] +['Ġspin', 'ning'] +['_p', 'ending'] +['Match', 'ers'] +['.', 'Keys'] +['ĠP', 'V'] +['en', 'us'] +['ant', 'is'] +['Ġdisc', 'ard'] +['Ġh', 'aul'] +['Ġem', 'pir'] +['Ġpath', 'way'] +['Ġo', 'ak'] +['м', 'ен'] +['-ind', 'uced'] +['Ġimp', 'air'] +['ĠCal', 'gary'] +['.is', 'Hidden'] +['d', 'z'] +['_', 'include'] +['Ġg', 'm'] +["Ġ'", "('"] +['P', 'Y'] +['uggest', 'ions'] +['Ġcommod', 'ity'] +['c', 'ro'] +['/', 'sub'] +['Ġget', 'Instance'] +['ĠLeg', 'acy'] +['ĠK', 'il'] +['B', 'al'] +['(', 'short'] +['In', 'form'] +['+', 'x'] +['*', 'r'] +['ĠHope', 'fully'] +['or', 'ate'] +['Ġmach', 'en'] +['Ġtreat', 'y'] +['ĠO', 'ri'] +['.p', 'ublic'] +['-h', 'orizontal'] +['Ġtact', 'ic'] +['Ġb', 'ord'] +['w', 'ares'] +['Ġam', 'mo'] +['ĠL', 'ists'] +['Ġequ', 'ations'] +['/', 'her'] +['ĠNS', 'W'] +['B', 'ounding'] +['_C', 'ollections'] +['Ġav', 'ail'] +['.Drop', 'Down'] +['è', '°'] +['Ġh', 'h'] +['Ġl', 'Ãł'] +['.p', 'b'] +['Ġmemor', 'ial'] +['ĠAT', 'TR'] +['Ġexhaust', 'ed'] +['Ġt', 'sp'] +['ĉ', 'redirect'] +['Ġlik', 'ewise'] +['ST', 'ER'] +['L', 'java'] +['Ġcondem', 'ned'] +['oca', 'ust'] +['(str', 'ict'] +['Ġexem', 'pt'] +['Ġs', 'ms'] +['Ġex', 'agger'] +['S', 'YS'] +['Ġl', 'ounge'] +[':', '^'] +['Ġto', 'dd'] +['de', 'b'] +['ator', 'ial'] +['ĠPort', 'er'] +['Ġtu', 'ition'] +['Ġexem', 'pl'] +['Ġp', 'aren'] +['.line', 'To'] +['Ġkid', 'ney'] +['Ġç', 'a'] +['Ġc', 'ui'] +['ï¼Į', '请'] +['X', 'C'] +['Ġmo', 'ż'] +['Ġnomin', 'ated'] +['l', 'ung'] +['Im', 'Gui'] +['ĠB', 'uzz'] +['Ġstere', 'o'] +['port', 'al'] +['res', 'as'] +['Ġk', 'lass'] +['Ġdraft', 'ed'] +['Ġproject', 'ile'] +['/g', 'pl'] +['(param', 'eters'] +['*', ')Ċ'] +['Ġassist', 'ed'] +['ĠNS', 'Integer'] +['s', 'itemap'] +[':n', 'th'] +['.View', 's'] +['.Argument', 'Parser'] +['Ġme', 'er'] +['z', 'ier'] +['ĠD', 'ig'] +['Ċ'] +['Ġpl', 'ag'] +['p', 'ine'] +['Ġblank', 'et'] +['Ġ:', '', '-'] +['Ġl', 'cd'] +['------------', '---'] +['("', '"'] +['Ġtact', 'ical'] +['ĠRon', 'ald'] +['ex', 'tr'] +['ĠF', 'est'] +['Ġf', 'uer'] +['-n', 'avigation'] +['Ġk', 'b'] +['gh', 'ost'] +['Ġhandle', 'Change'] +['_cl', 's'] +['()', '!='] +['Com', 'parator'] +['.v', 'm'] +['ĠCo', 'x'] +['_re', 'view'] +['/', '@'] +['_c', 'ookie'] +['Ġrecogn', 'ised'] +['ld', 'ap'] +['Thread', 's'] +['ĠSex', 'ual'] +['ĠB', 'earing'] +['(S', 'QL'] +['Ġx', 'r'] +['Ġth', 'igh'] +['URL', 'Connection'] +['ĠSU', 'V'] +['Ġm', 'Context'] +['Ġinc', 'idence'] +['ĠE', 'ste'] +['.s', 'up'] +['_t', 'e'] +['(EX', 'IT'] +['C', 'MD'] +['/', '">'] +['Al', 'most'] +['ĠU', 'ne'] +['Ġand', 'eren'] +['ĠSingle', 'ton'] +['Ġb', 'ore'] +['Th', 'ink'] +['Ġn', 'arc'] +[']', 'initWith'] +['_sh', 'op'] +['(str', 'ategy'] +['!', "',"] +['her', 'its'] +['ĠDes', 'k'] +['_m', 'achine'] +['.net', 'ty'] +['ı', 'nda'] +['=', '<'] +['ĠQ', 'R'] +['ĠS', 'idebar'] +['.split', 'Container'] +['Ġon', 'Success'] +['Ġmon', 'key'] +['En', 'joy'] +['(n', 'odes'] +['pect', 'rum'] +['Ġ(*', '('] +['ĉU', 'INT'] +[',', 'height'] +['ĠNetwork', 's'] +['.t', 'ail'] +['.l', 'inspace'] +['Ġ"', '...'] +['List', 'en'] +['Æ', '¡'] +['.Ch', 'annel'] +['-', 'defined'] +['Re', 'peat'] +['ad', 'just'] +['ER', 'M'] +['_', 'application'] +['.assert', 'NotNull'] +['-', 'stream'] +['Ġr', 'abbit'] +['Ġposition', 'ing'] +['Ġw', 'oke'] +['Ġf', 'ing'] +['Ġmulti', 'player'] +['Ġregister', 'ing'] +['un', 'til'] +['Ã¥', 'n'] +['(', '::'] +['uss', 'ions'] +['Ġpot', 'ato'] +['ĠE', 'quals'] +['.S', 'up'] +['/ap', 'ache'] +['Ġ(', '='] +['.', '")'] +['.p', 'tr'] +['ĠSpe', 'ech'] +['.cl', 'ip'] +['ĠGab', 'riel'] +['Ġmusic', 'ian'] +['/', 'issues'] +['.sh', 'op'] +['ĠH', 'ier'] +['_RE', 'T'] +['_b', 'ucket'] +['ãĥ', '¡'] +['av', 's'] +['Ġro', 'z'] +['fl', 'ower'] +['Write', 'Barrier'] +['ĠMil', 'an'] +['Ġlegisl', 'ature'] +['ĠD', 'oll'] +['Ġprov', 'ing'] +['.concat', 'enate'] +['âķ', 'IJ'] +['Ġg', 'char'] +['cdn', 'js'] +['b', 'les'] +['ĠList', 'ing'] +['л', 'о'] +['.xr', 'Label'] +['ĠS', 'ak'] +['just', 'ice'] +['ĠVal', 'entine'] +['un', 'less'] +['Ġp', 'iger'] +['(r', 'un'] +['Ġtest', 'ified'] +['AN', 'A'] +['ĠRem', 'oves'] +['))', '));Ċ'] +['rec', 'ated'] +['ĠRuntime', 'Method'] +['Ġcon', 'qu'] +['ãĤ', '¢'] +['Ġt', 'issues'] +['ail', 'er'] +['ét', 'é'] +['-', 'Star'] +['Ġfl', 'ames'] +['.set', 'Icon'] +['Ġsup', 'ern'] +['Ġvag', 'ina'] +['-', 'variable'] +['Ġwell', 'ness'] +['C', 'UR'] +['Ġbel', 'le'] +['.get', 'Request'] +['Ġp', 'oco'] +['ben', 'h'] +['ag', 'ens'] +['Ġsp', 'ill'] +['ĠJ', 'ur'] +['Ġdispatch', 'er'] +['н', 'ого'] +['emon', 'ic'] +['(dir', 'name'] +['ĠÐ', 'Ķ'] +['Ġpas', 'se'] +['Ġg', 'anz'] +['ric', 'ing'] +['E', 'U'] +['Ġmuj', 'eres'] +['ess', 'en'] +['.at', 'tribute'] +['j', 'j'] +['ĉĉ', 'ĠĊ'] +['[', '^'] +['Ġstrtol', 'ower'] +['lex', 'er'] +['ect', 'ar'] +['hot', 'el'] +['.s', 'quare'] +['Ġr', 'all'] +['Ġlower', 'ed'] +['hand', 'led'] +['Mark', 'et'] +['ĠUs', 'es'] +['iv', 'as'] +['.B', 'usiness'] +['ãģĹãģ', '¦'] +['D', 'IV'] +['Ġw', 'asted'] +['Ġav', 'oir'] +['ê', 'm'] +['_ACC', 'OUNT'] +['.', 'et'] +['ĉ', 'SDL'] +['k', 'ap'] +['Ġf', 'ox'] +['up', 'pet'] +['{', '},Ċ'] +['",', "'"] +['F', 'avorite'] +['P', 'END'] +['ĠA', 'ES'] +['}', '),'] +['Ġded', 'uction'] +['Ġpol', 'ÃŃt'] +['Ġcomponent', 'Will'] +['ĠT', 'elerik'] +['_SE', 'LF'] +['Ġm', 'use'] +['C', 'raft'] +['Ġd', 'ens'] +['à¤', '¿'] +['(', 'tp'] +['Ġt', 'asty'] +['Ġbal', 'ances'] +['Ġded', 'ication'] +['ĠWall', 'ace'] +['Ġun', 'law'] +['\\">', '\\'] +['Ġm', 'um'] +['-', 'update'] +['ement', 'e'] +['Ġs', 'oda'] +['Re', 'public'] +['as', 'mine'] +['é', 'ric'] +['(', 'Status'] +['ĠJson', 'Convert'] +['ĠD', 'isk'] +['.Red', 'irect'] +['Ġfilm', 'ing'] +['/m', 'ol'] +['R', 'o'] +['Ġv', 'ille'] +['Ġtrab', 'aj'] +['Ġsyn', 'thesis'] +['reg', 'a'] +['Ġr', 'l'] +['S', 'cheduler'] +['ISH', 'ED'] +['current', 'User'] +['(error', 's'] +["'", 'h'] +['_b', 'ot'] +['x', 'imo'] +['ĠUS', 'ART'] +['_s', 'uper'] +['_DEC', 'REF'] +['н', 'ой'] +['_RO', 'W'] +['Ġprom', 'otes'] +['ĠT', 'A'] +['Ġhor', 'as'] +['ĠRep', 'resents'] +['Ġname', 'of'] +['ĠEx', 'c'] +['ĠGar', 'age'] +['Ġse', 'ine'] +[',', '#'] +['Ġher', 'b'] +['/', 'resources'] +['Ġple', 'aded'] +['.r', 'adioButton'] +['Ġæ', 'ĺ'] +['O', 'ps'] +['ĠN', 'est'] +['c', 'string'] +['ĠDef', 'ence'] +['Ġref', 'ere'] +['_le', 'af'] +['Ġrevel', 'ation'] +['ë', '§'] +['.execute', 'Update'] +['_W', 'ORLD'] +['Ġexp', 'ans'] +['("', '\\"'] +['j', 'ab'] +['Ġdoub', 'ts'] +['ĠGe', 'ometry'] +['Ġintrodu', 'ces'] +['Ġsen', 'ators'] +['Ġcan', 'al'] +['.h', 'elper'] +['ĠBi', 'ology'] +['_SE', 'NS'] +['.pre', 'vious'] +['-t', 'ouch'] +['ab', 'it'] +['Ġimpact', 'ed'] +['Ġbr', 'ackets'] +['.d', 'irect'] +['acc', 'um'] +['Ġtest', 'osterone'] +['ĉ', 'action'] +['ĠCh', 'ance'] +['Ġpe', 'aks'] +['CppCodeGen', 'WriteBarrier'] +['Ġun', 'belie'] +['_p', 'ress'] +['.R', 'el'] +['ang', 'led'] +['/', 'templates'] +['--', '>čĊ'] +['l', 'ime'] +['Ġsufficient', 'ly'] +['_', 'nt'] +['Exp', 'and'] +['.is', 'file'] +['Ġis', 'Empty'] +['Ġq', 't'] +['Ġmul', 'her'] +['ac', 'ob'] +['Ge', 'orge'] +['å¸', '¸'] +['Ġass', 'im'] +['as', 'o'] +['Ġcompr', 'ised'] +['O', 'V'] +['(CON', 'FIG'] +['ĉw', 'riter'] +['Ġdes', 'p'] +['Ġten', 'ure'] +['(c', 'r'] +['.p', 'ool'] +['ĠB', 'rend'] +['Ġc', 'ensor'] +['(time', 'out'] +['Ġple', 'a'] +['.W', 'rap'] +['Ġtight', 'ly'] +['ĠW', 'ere'] +['ĠI', 'gnore'] +['abe', 'i'] +['Ġbr', 'idges'] +['Ġcondem', 'n'] +['Ġsimp', 'licity'] +['Ġrout', 'inely'] +['Ġblack', 's'] +['j', 'b'] +['ĠP', 'it'] +['U', 'tf'] +['Ġ/', 'Ċ'] +['re', 'load'] +['Ġset', 'Object'] +['/g', 'lobal'] +['Ġf', 'atty'] +['Ġsock', 's'] +['Could', 'n'] +['Ġerot', 'isk'] +['æĿ', '¡'] +['ĠPress', 'ure'] +['ĠM', 'az'] +['n', 'pos'] +['tol', 'ower'] +['ĠE', 'Q'] +['ute', 'ur'] +['ĠM', 'oment'] +['Ġet', 'a'] +['{{', '--'] +['Ġgraph', 's'] +['ĠGu', 'ar'] +['r', 'ine'] +['(', '--'] +['ĠHttp', 'Status'] +['(st', 'udent'] +['*', 'np'] +['Ġrail', 'way'] +['Ġas', 'ynchronous'] +['_v', 'm'] +["']", ",'"] +[',', 'text'] +['mer', 'chant'] +['(G', 'uid'] +['ĠG', 'ra'] +['ix', 'er'] +['fetch', 'All'] +['.add', 'Listener'] +['fl', 'ip'] +['*', '$'] +['>', '(),'] +['Ġsun', 'light'] +['ass', 'igned'] +['Ġab', 'c'] +['ĠC', 'OLUMN'] +['ĠðŁĻĤ', 'ĊĊ'] +[')', '...'] +['Ġen', 'semble'] +['Ġnew', 'line'] +['_S', 'INGLE'] +['ied', 'ad'] +['Ġdark', 'er'] +['orm', 'ap'] +['Ġl', 'ion'] +['pl', 'its'] +['Ġillustr', 'ation'] +['ĠI', 'EEE'] +['Ġv', 'ista'] +['ous', 'ands'] +['******', '*'] +['ĠTom', 'my'] +['Ġh', 'ue'] +['S', 'el'] +['Ġa', 'ura'] +['ĠTher', 'apy'] +['Ġanim', 'ator'] +['.con', 'straints'] +['Ġv', 'ague'] +['("', '")'] +['Ġvill', 'ain'] +['Ġbless', 'ing'] +['Ġstring', 'Builder'] +['ĠM', 'isc'] +['ĠD', 'IR'] +['f', 'ax'] +['-', 'node'] +['ĠWalk', 'ing'] +['ĠA', 'U'] +['s', 'ess'] +['Ġgr', 'ill'] +['VERT', 'ISE'] +['ĠF', 'oods'] +['Ġt', 'ournaments'] +['Ã', 'ĵ'] +['ĠMar', 'sh'] +['Ġw', 'onders'] +['Long', 'itude'] +['.Command', 'Text'] +['=', 'input'] +['_enc', 'oder'] +['page', 'Size'] +['Ġget', 'State'] +['>', '>Ċ'] +['.g', 'rey'] +['p', 'od'] +['Ġread', 'ings'] +['Ġre', 'consider'] +['Start', 'up'] +['Ġexc', 'er'] +['.b', 'alance'] +['_c', 'ycle'] +['_T', 'ime'] +['LOC', 'AL'] +['ĠE', 'FI'] +['ĠRe', 'yn'] +['.set', 'Foreground'] +['by', 'n'] +['Ġdis', 'connected'] +['ACT', 'IVE'] +['Ġembed', 'ding'] +['ick', 'ers'] +['Ġsurround', 'ings'] +['*', 'c'] +['Ġgar', 'ant'] +['Ġb', 'f'] +['Ġw', 'ipe'] +['Ġ', 'ä¸ĭ'] +['_T', 'RA'] +['ado', 'x'] +['ç', 'ķ'] +['Ġsu', 'cks'] +['ĠS', 'ongs'] +['ĠAssoci', 'ates'] +['ĠB', 'ald'] +['ĠB', 'rett'] +['ven', 'ile'] +['Ġv', 't'] +['Ġin', 'ade'] +['Ġres', 'igned'] +['ĠGl', 'enn'] +['.p', 'attern'] +['.Data', 'Bind'] +['Ñĥ', 'м'] +['Layout', 'Inflater'] +['ch', 'et'] +['ĠTest', 'ament'] +['.m', 's'] +['Ġp', 'av'] +['ĠReact', 'DOM'] +['ur', 'dy'] +['AD', 'ATA'] +['M', 'u'] +['/', 'actions'] +['ĠJ', 's'] +['_ex', 'tract'] +['ĠBr', 'ing'] +[':', 'id'] +['str', 't'] +['iv', 'ation'] +['Ġoutr', 'ight'] +['az', 'u'] +['loy', 'ment'] +['и', 'Ñı'] +['al', 'do'] +['ĠP', 'ublisher'] +['E', 'ducation'] +['Pa', 'lette'] +['_d', 'rv'] +['Ġ($', '('] +['ĠAnd', 'a'] +['Ġrem', 'edy'] +['Ġincons', 'istent'] +['te', 'ction'] +['Ġregul', 'ators'] +['Ġshort', 'est'] +['(p', 'air'] +['ĠInstall', 'ation'] +['Ġdefend', 'ants'] +['Ġ(', ');'] +['-l', 'arge'] +['M', 'el'] +['Ġthreat', 'en'] +['н', 'Ñı'] +['Ġfet', 'ish'] +['ot', 'ine'] +['_d', 'ic'] +['Ġ<', '$'] +['Ġst', 'agger'] +['sp', 'i'] +['$', 'response'] +['S', 'erv'] +['-b', 'orn'] +['j', 'os'] +['ĉ', 'img'] +['ĉW', 'HERE'] +['_l', 't'] +['å½', 'ĵ'] +['.c', 'ost'] +['ĠT', 'ue'] +['.label', 's'] +['ĠL', 'V'] +['wcs', 'store'] +['ĠJes', 'se'] +['à¸', '«'] +['Tr', 'ade'] +['Ġpredecess', 'or'] +['ë', 'Ĥ'] +['fin', 'ally'] +['_g', 'eneral'] +['ogg', 'ler'] +['_REG', 'ION'] +['n', 'ement'] +['Ġblog', 'ger'] +['ĠHar', 'bor'] +['ĠD', 'ataset'] +['[', 'w'] +['Ġattend', 'ees'] +['.', 'ico'] +['max', 'imum'] +['.Un', 'lock'] +['_SY', 'NC'] +['ág', 'ina'] +['Ġdown', 's'] +['ĠW', 'ii'] +['])', '/'] +['Ġkick', 'ing'] +['unic', 'ation'] +['ĠD', 'AC'] +['ĠID', 'S'] +['ĠR', 'ental'] +['Ġcurrent', 'Time'] +['Ġvacc', 'ines'] +['ĠDev', 'il'] +['Ġn', 'ors'] +['_m', 'ouse'] +['urre', 'ction'] +['(n', 'o'] +['Ġ>', 'čĊ'] +['Ġaggress', 'ion'] +['Ġbre', 'eding'] +['.s', 'ymbol'] +['im', 'an'] +['Absolute', 'Path'] +['ĠWH', 'O'] +['_fl', 'ush'] +['-', 'root'] +['arn', 'a'] +['&', 'M'] +['Ġf', 'athers'] +['ĠR', 'ocket'] +['ive', 'au'] +['Ġw', 'ander'] +['Ġcom', 'pos'] +['ĠWar', 'rior'] +['ĠSe', 'at'] +['ĠClin', 'ic'] +['_in', 'voice'] +['(dis', 'patch'] +['Product', 'o'] +['at', 'uring'] +['oss', 'ier'] +['ĠM', 'AY'] +['Ġd', 'agger'] +['Ġsanit', 'ized'] +['ĠR', 'FC'] +['Ġpro', 'ph'] +['Ġur', 'ine'] +['Ġgr', 'ind'] +['ĠExp', 'anded'] +['des', 'cripcion'] +['-f', 'w'] +['ĠK', 'erry'] +['=', 'name'] +['Ġch', 'k'] +['Ġnation', 'ally'] +['Ġthe', 'e'] +['In', 'c'] +['Ġ?', '>>'] +['.R', 'adioButton'] +['.Http', 'ServletResponse'] +['/', 'Y'] +['ĉf', 'ield'] +['Ġhom', 'me'] +['y', 'per'] +['Ph', 'ysical'] +['=', 'v'] +['Ġdr', 'iv'] +['ĠErr', 'ors'] +['Ġc', 'Äĥ'] +['De', 'ath'] +['ĠW', 'INDOW'] +['Ġpo', 'et'] +['ĠSh', 'arp'] +['ĠImm', 'utable'] +['ĉ', 'create'] +['Ġge', 'ht'] +['ĠRe', 'form'] +['ais', 'er'] +['ĠInitial', 'ization'] +['Ġimm', 'unity'] +['.com', 'pose'] +['Ġlat', 'ency'] +['ĠLeban', 'on'] +['ĠPar', 'ad'] +['Ġfu', 'els'] +['ĠEx', 'hib'] +['co', 'h'] +['%', '">Ċ'] +['ĠCL', 'I'] +[')', 'initWith'] +['-Z', 'a'] +['_C', 'LEAR'] +['reg', 'n'] +['Ġfin', 'ances'] +['.st', 'andard'] +['_C', 'ATEGORY'] +['.lib', 'rary'] +['Ġtravel', 'ers'] +['_w', 'p'] +['ĠE', 'valuation'] +['start', 'ing'] +['Ġ', ')),Ċ'] +['ep', 'isode'] +['ĠV', 'ariant'] +['Ġda', 'emon'] +['ĠJul', 'ia'] +['ĠN', 'R'] +['Ġdoub', 'les'] +['<', 'v'] +['/r', 'untime'] +['Ġinterpre', 'ter'] +['ĠIN', 'DEX'] +['ĠHol', 'mes'] +['_D', 'IM'] +['Ġp', 'addle'] +['_ex', 'ample'] +['Ġfore', 'ground'] +['.r', 'outes'] +['Ġs', 'owie'] +['S', 'UCCESS'] +['ĠC', 'DC'] +['ĠB', 'D'] +['_', '-'] +['as', 'ured'] +['W', 'riting'] +['Ġcurrent', 'Page'] +['(', 'answer'] +['ĠASC', 'II'] +['à', '¨'] +['Ġsocial', 'ly'] +['yy', 'y'] +['ĠSpecial', 'ist'] +['(c', 'ustomer'] +['ist', 'ani'] +['ke', 'st'] +['ĠM', 'ak'] +['Ġth', 'o'] +['.', 'pt'] +['(', 'comment'] +['ĠCon', 'verter'] +['g', 'am'] +['b', 'ins'] +['.', 'tele'] +['ĠVeter', 'ans'] +['_AL', 'LOC'] +['олÑĮзов', 'аÑĤ'] +['inn', 'amon'] +[';', 'width'] +['oh', 'l'] +['Ġfant', 'as'] +['Ġs', 'ung'] +['ĉ', 'K'] +['(', 'Json'] +['Ġneighbour', 'hood'] +['Ġv', 'ow'] +['Ġs', 'ins'] +['on', 'acci'] +['Ġepoch', 's'] +['im', 'agen'] +['.Ch', 'ange'] +['.my', 'batis'] +['Se', 'ek'] +['W', 'ER'] +['管', 'çIJĨ'] +['Ġinter', 'ess'] +['_', 'Event'] +['eder', 'land'] +['Ġterr', 'itor'] +['Ġci', 'udad'] +['uck', 'ed'] +['Ġsn', 'ack'] +['Ġtransport', 'ed'] +['ĠMan', 'ifest'] +['ĠD', 'AT'] +['_th', 'eta'] +['Ġw', 'ont'] +['.ĊĊ', 'ĊĊĊĊĊĊĊĊ'] +['Ĭ¶', 'æĢģ'] +['ĠEp', 'ic'] +['De', 'ck'] +['l', 'tra'] +['_Z', 'ERO'] +['Ġ[]', ';'] +['/', 'scripts'] +['Ġ----------------------------------------------------------------', '----------------'] +['æĥ', 'ħ'] +['Ġwe', 'ed'] +['N', 'BC'] +['Ġrap', 'ed'] +['ĠG', 'ateway'] +['[', 'M'] +['ĠTime', 'out'] +['ench', 'mark'] +['.View', 'Model'] +['Ġporn', 'os'] +['ĠY', 'a'] +['th', 'ritis'] +['ĠFly', 'nn'] +['Ġme', 'ga'] +['ac', 'in'] +['Ġtrib', 'al'] +['.app', 'le'] +['ĠB', 'lo'] +['â', 'n'] +['ib', 'i'] +['ro', 'v'] +['ĠL', 'ives'] +['^', '.'] +['get', 'Request'] +['ĠEst', 'ablish'] +['cont', 'ainers'] +['Ġst', 'arring'] +['Ġcele', 'brities'] +['ĠRel', 'ative'] +['ĠHe', 'ights'] +['Ġtq', 'dm'] +['ĠNorth', 'west'] +['iv', 'ic'] +['ĉ', 'cl'] +['Ġautom', 'otive'] +['ent', 'ric'] +['Ġfort', 'unate'] +['Ġfire', 'place'] +['se', 'ud'] +['nick', 'name'] +[';', 's'] +['_C', 'AL'] +['h', 'alt'] +['(n', 's'] +['_de', 'leted'] +['Develop', 'ment'] +['m', 'ovies'] +['Ġident', 'ities'] +['Ġprompt', 'ly'] +['ا', 'ÙĨ'] +['Ġant', 'e'] +['Ġ"', "','"] +['åı', '£'] +['imp', 'se'] +['Ġy', 'ap'] +['Type', 'Name'] +['Ġb', 'itch'] +['Ġassoci', 'ates'] +['HE', 'ME'] +['-', 'empty'] +['ĠØ', 'ª'] +['ol', 'vers'] +['Ġpist', 'ol'] +['Sc', 'oped'] +['ag', 'ner'] +["']", "=='"] +['ĠI', 'MP'] +['ex', 'c'] +['Ġo', 'mitted'] +['Ġmind', 'set'] +['Ġ[]', '('] +['Ġor', 'n'] +['_C', 'AM'] +['A', 'vg'] +['Localized', 'String'] +['ĠN', 'atur'] +['Ġcom', 'poser'] +['ĠPlay', 'ing'] +['Ġover', 'd'] +['_', 'utf'] +['.s', 'k'] +['ĠF', 'ol'] +['$', 'page'] +[',', 'Object'] +['Ġbe', 'es'] +['al', 'ary'] +['bul', 'let'] +['_lib', 'rary'] +['O', 'ffer'] +['loc', 'ated'] +['Ġ(_', ','] +['âĢľ', 'He'] +['ĠOwn', 'ers'] +[')', ').Ċ'] +['Ġb', 'ri'] +['.Ad', 'min'] +['kt', 'ion'] +['лÑİ', 'Ñĩ'] +['Ġerot', 'ici'] +['Cancel', 'led'] +['Ġa', 'gr'] +['re', 'views'] +['_d', 'ma'] +['RI', 'CT'] +['Ġg', 'fx'] +['mp', 'i'] +['pp', 'o'] +['Ġ//', '@'] +['Ġupper', 'case'] +['Ġcommit', 'ting'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['User', 'Data'] +['Ġv', 'ai'] +['ĉs', 'ort'] +['Ġcongr', 'at'] +['Ġd', 'ioxide'] +['д', 'а'] +['.', 'area'] +['ĠJosh', 'ua'] +['ĠK', 'och'] +['_b', 'reak'] +['az', 'ure'] +['ist', 'ical'] +['_AL', 'PHA'] +['_', 'views'] +['Ġelim', 'inating'] +['OM', 'B'] +['en', 'umer'] +['ĠHy', 'dro'] +['(*', '('] +['ERT', 'ICAL'] +['Ġinev', 'itably'] +['Ġst', 'ole'] +['-e', 'ast'] +['ier', 'on'] +['Ġl', 'inger'] +['/d', 'oc'] +['Å', 'º'] +['ĠAl', 'ready'] +['as', 'io'] +['Ġ--', 'Ċ'] +['Ġabb', 'rev'] +['ĠAt', 'om'] +['h', 'im'] +['ĠINS', 'ERT'] +['s', 'un'] +['âĻ', 'ª'] +['CON', 'NECT'] +['er', 'ator'] +['ĠM', 'anning'] +['Ġ:', '('] +['g', 'as'] +['=>', "'"] +['Ġquery', 'set'] +[';', '}čĊ'] +['ĠPop', 'ulation'] +['uted', 'String'] +['res', 'ident'] +['_F', 'ONT'] +['ĠRes', 'pond'] +['Ġobsc', 'ure'] +['Ġo', 'bservable'] +['ĠContrib', 'utors'] +['k', 'on'] +['ĠMus', 'k'] +['ex', 'ao'] +['ĠT', 'ub'] +['Boot', 'Application'] +['S', 'OR'] +['.H', 'orizontal'] +['.find', 'By'] +['.p', 'ower'] +['Ġposit', 'ively'] +['ven', 'ience'] +['ĠJ', 'ong'] +['Ġwh', 'istle'] +['Ġз', 'наÑĩ'] +['Ġl', 'ending'] +['Ġdestruct', 'ive'] +['Ġon', 'Delete'] +['author', 'ization'] +['();', '?>'] +['_', 'original'] +['sc', 'ience'] +['at', 'ra'] +['?,', '?,'] +['ĠAs', 'c'] +['Ġconvinc', 'ing'] +['$', 'a'] +['org', 'en'] +['_D', 'ate'] +['ĠPro', 'vide'] +['Ġlon', 'ely'] +[')', "'Ċ"] +['ex', 'change'] +[';', '?>Ċ'] +['.f', 'ast'] +['S', 'amples'] +['L', 'ondon'] +["']", ')čĊ'] +['ĠI', 'onic'] +['Ġp', 'esso'] +['ĠKn', 'ights'] +['ĠR', 'af'] +['_attr', 's'] +['Ġrepe', 'al'] +['>', 'Main'] +['ĠOrder', 'ed'] +['_N', 'ew'] +['="', '">", '";Ċ'] +['ĠS', 'ERVER'] +['ĠHE', 'ADER'] +['_', 'velocity'] +['ĠIn', 'voke'] +['.timestamp', 's'] +['Ġs', 'ulf'] +['I', 'QUE'] +['Ġinhabit', 'ants'] +['ph', 'ins'] +['azz', 'o'] +['Ġmon', 'o'] +['Leg', 'end'] +['Ġnon', 'ce'] +['IF', 'E'] +[';', '";Ċ'] +['-', 'create'] +['"', '",Ċ'] +['per', 'mit'] +['ĠImm', 'igration'] +['Ġpath', 'name'] +['ffect', 'ive'] +['âĻĢ', 'âĻĢ'] +['Ġex', 'ams'] +['-', 'event'] +['ĠT', 'ill'] +['[m', 'id'] +['F', 'IX'] +[';', 'color'] +['(', 'Order'] +['_tra', 'its'] +['Ġorder', 'By'] +['Ġs', 'unt'] +['ĠNich', 'olas'] +['Ø', '²'] +['Ġsun', 'ny'] +['in', 'ers'] +['Ġaccess', 'ibility'] +['ĠH', 'B'] +['.com', 'p'] +['ĉ', 'op'] +['Ġminor', 'ities'] +['ethe', 'us'] +['Ġcollabor', 'ative'] +['pr', 'it'] +['H', 'IR'] +['Ġwr', 'aps'] +['ĉd', 'raw'] +['g', 'od'] +['ĠI', 'X'] +['.app', 's'] +['ĠN', 'M'] +['Ġirre', 'levant'] +['ĠT', 'igers'] +['Ġdi', 'ag'] +['G', 'V'] +['ĠAccess', 'ories'] +['k', 'ont'] +['Ġsimpl', 'ify'] +['ĠF', 'avorite'] +['_t', 'ools'] +['([]', ');Ċ'] +['Ġtow', 'ers'] +['B', 'es'] +['Ġhun', 'ter'] +['Ġsal', 'on'] +['(b', 'uff'] +['ĉ', 'debug'] +['Ġmal', 'ware'] +['M', 'oving'] +['-', 'options'] +[')', "+'"] +['ĠLO', 'VE'] +['_S', 'OCKET'] +['_f', 'in'] +['ĠDel', 'aware'] +['Ġsher', 'iff'] +['-in', 'valid'] +['ĠF', 'ULL'] +['Ġп', 'од'] +['el', 'as'] +['"', 'strings'] +['ĠRepresent', 'atives'] +['s', 'urface'] +['res', 'olved'] +['ht', 'docs'] +['))', ':čĊ'] +['Ġpress', 'ures'] +['Ġnorm', 's'] +['Ġpl', 'a'] +['Ġs', 'urname'] +['Ġpost', 'al'] +['ĠDep', 'art'] +['Ġsla', 'ughter'] +['or', 'ida'] +['Ġhe', 'bben'] +['Ġdes', 'ar'] +['comp', 'act'] +['_L', 'ANG'] +['åIJ', 'Ī'] +['op', 'oly'] +['_r', 'ad'] +['ĠST', 'DMETHOD'] +['L', 'azy'] +['ĠĠĠ', 'ĉ'] +['...', ','] +['(', 'web'] +['ĠP', 'ont'] +['Ġet', 'was'] +['Ġup', 'ward'] +['_h', 'at'] +['Ġ],', 'ĊĊ'] +['Ġbase', 'Url'] +['Ġworry', 'ing'] +['-add', 'on'] +['(get', 'Class'] +['S', 'PI'] +['Ġcapt', 'uring'] +[')', '},Ċ'] +['Effect', 's'] +['Ġcompet', 'ent'] +['Ġf', 'oul'] +['Ġsubscri', 'bing'] +['ĠO', 'BJECT'] +['IX', 'EL'] +['b', 'ucks'] +['(', 'edge'] +['(p', 'ass'] +['ĠPet', 'erson'] +['Ġbo', 'obs'] +['ĠD', 'elay'] +['_s', 'quare'] +['el', 'im'] +['ot', 'ers'] +['_P', 'C'] +['%', 'E'] +['on', 'click'] +['ĠSV', 'G'] +['Ġto', 'pped'] +['Ġf', 'ist'] +['sm', 'art'] +['ĠR', 'alph'] +['(', 'owner'] +['j', 'ours'] +['Ġbron', 'ze'] +['ĠArgument', 'Exception'] +['(', 'original'] +['_S', 'CALE'] +['_c', 'p'] +['Ġrecomm', 'ends'] +['.set', 'Style'] +['S', 'ure'] +['L', 'AND'] +['Ġrepe', 'ating'] +['M', 'att'] +['.', 'Visibility'] +['Ġenter', 'prises'] +['.Set', 'up'] +['(sc', 'ene'] +['ĠRe', 'active'] +['ur', 'ge'] +['b', 'w'] +['.P', 'ut'] +['p', 'ersist'] +['.c', 'ookie'] +['ĠAud', 'i'] +['`', 's'] +['sup', 'plier'] +['(', 'Form'] +['Â', '¡'] +['_s', 'o'] +['Į', 'Ģ'] +['ĠLeg', 'ion'] +['t', 'te'] +['N', 'd'] +['L', 'oss'] +['(', 'attrs'] +['.sc', 'atter'] +['Ġg', 'room'] +['Ġgl', 'impse'] +['Ġn', 'ails'] +['Ġcum', 'ulative'] +['Ġf', 'azer'] +['_s', 'ervices'] +['.N', 'um'] +['ib', 'ilit'] +['_res', 'olution'] +['ĠT', 'x'] +['umin', 'ium'] +['op', 'a'] +['.s', 'chedule'] +['sm', 'tp'] +['à¸', 'ķ'] +['ur', 'ry'] +['ü', 'k'] +['go', 'og'] +['_sign', 'ature'] +['.int', 'o'] +['ĠSte', 'ps'] +['Ġhome', 'owners'] +['ĠNS', 'URL'] +['ĠP', 'AC'] +['ĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĊĊ'] +['>', "')Ċ"] +['en', 'h'] +['Ġinc', 'ap'] +['$', 'MESS'] +['Ġmo', 'ins'] +['ĠF', 'i'] +['Ġoff', 'season'] +['press', 'ions'] +['>', '.Ċ'] +['ĠGr', 'ass'] +['ĠGo', 'al'] +['_p', 'df'] +['Hand', 'lers'] +['Ġstack', 's'] +['.get', 'FullYear'] +['=[', '];Ċ'] +['è½', '¦'] +[',', 'V'] +['(s', 'plit'] +['Ñĥн', 'к'] +['Ġbake', 'ca'] +['Ġ~', '/.'] +['pe', 'z'] +['t', 'ails'] +['ĠG', 'len'] +['Ġset', 'Image'] +['ĠCom', 'ic'] +['B', 'LOCK'] +['ĉ', 'This'] +['o', 'ader'] +['Ġcapital', 'ist'] +['_ST', 'EP'] +['(', 'Boolean'] +['ĠCor', 'rect'] +['r', 'ina'] +['Ġconc', 'aten'] +['å®', 'ŀ'] +['()', ':ĊĊ'] +['Ġun', 'anim'] +['ll', 'i'] +['al', 'ars'] +['-', 'ne'] +['Ġdiv', 'or'] +['ĠKick', 'starter'] +['].', '_'] +['<', 'number'] +['/m', 'enu'] +['GR', 'APH'] +['vis', 'itor'] +['Ġimpro', 'per'] +['_N', 'EXT'] +['Ġb', 'isa'] +['background', 'Color'] +['/', 'input'] +['Ġmo', 'i'] +['Go', 'al'] +['li', 'qu'] +['Ġmiscon', 'duct'] +['Ġcompr', 'ises'] +['aw', 'ns'] +['ĠP', 'ie'] +['ra', 'is'] +['role', 'um'] +['Ġcur', 'se'] +['y', 'u'] +['_p', 'oll'] +['.current', 'User'] +['ES', 'H'] +['])', '['] +['Ġstory', 't'] +[')?', ';Ċ'] +['*', '='] +['ĠB', 'urg'] +['/', 'layout'] +['_back', 'end'] +[';', '?>', '*', "'+"] +['åĿ', 'Ģ'] +['ac', 'ency'] +['(', 'URL'] +['_h', 'alf'] +['=', 'l'] +['Ġlist', 'View'] +['(', 'section'] +['.to', 'Array'] +['+', '/'] +['ĠRodrig', 'uez'] +['ist', 'ream'] +['Ġelig', 'ibility'] +['::', '-'] +['.new', 'Instance'] +['P', 'B'] +['ĠAs', 'sets'] +['ĠCom', 'posite'] +['ĠL', 'abs'] +['ĠHam', 'as'] +['++', ');Ċ'] +['Ġbl', 'k'] +['ĠNe', 'o'] +['L', 'uc'] +['@', 'login'] +['Ġun', 'aware'] +['.m', 'et'] +['_RE', 'LEASE'] +['(', 'ST'] +['AM', 'IL'] +['ri', 'ke'] +['Ġ(', '){Ċ'] +['(s', 'printf'] +['ĠAccount', 's'] +['ĠV', 'IEW'] +['ĠA', 'j'] +['ãĤ', '°'] +['Ġwh', 'isk'] +['Ġid', 'i'] +['Ġro', 'de'] +['Ġih', 'n'] +['ĠElement', 'ary'] +['Q', 'ty'] +['Ġintrig', 'uing'] +['Ġå', '¤'] +['J', 'obs'] +['ĉ', 'offset'] +['ĠAh', 'med'] +['ĠTal', 'iban'] +['Ġè', 'İ·åıĸ'] +['Ġinject', 'ed'] +['.Auth', 'entication'] +['_line', 'ar'] +['.Dec', 'imal'] +['Ġapp', 'les'] +['Ġshare', 'holders'] +['Ġb', 'aked'] +['.d', 'iff'] +['ĠE', 'ddie'] +['ok', 'ers'] +['Ġconfront', 'ed'] +['vo', 'ices'] +['Ġt', 'us'] +['ĠSp', 'in'] +['N', 'ODE'] +['_', 'Un'] +['CT', 'X'] +['/g', 'oogle'] +['Tem', 'perature'] +["Ġ'", "')."] +['Ġmagn', 'ificent'] +['Ġstart', 'Index'] +['semb', 'les'] +['Any', 'one'] +['z', 'k'] +['eh', 'en'] +['ĠD', 'ame'] +['.', 'strict'] +['Ġrepl', 'aces'] +['Ġline', 'back'] +['Ġpush', 'es'] +['Ġche', 'ek'] +['ĠSh', 'i'] +['_BY', 'TES'] +['RE', 'A'] +['ả', 'n'] +['_CON', 'NECTION'] +['G', 'ateway'] +['ĠTr', 'avis'] +['ĠA', 'X'] +['ĠBas', 'ically'] +['ĠUp', 'grade'] +['à', 'ª'] +['th', 'emes'] +['erm', 'o'] +['k', 'or'] +['F', 'emale'] +['_att', 'ach'] +['ĠìĤ¬', 'ìļ©'] +['Ġpo', 'z'] +['============', '==Ċ'] +['(s', 'ymbol'] +['ĠS', 'ector'] +['__', ')ĊĊ'] +['_p', 'adding'] +['ï¼ļ', '"'] +['Ġf', 'abs'] +['Ġr', 'anged'] +['set', 'Name'] +['Ġp', 'error'] +['â', 'Ĺ'] +['ĠFile', 'Reader'] +['Ġful', 'filled'] +['_C', 'urrent'] +['Ġdom', 'inate'] +['Ġsm', 'ugg'] +['Post', 'Mapping'] +['_for', 'ce'] +['Ġb', 'loc'] +['ĠG', 'iant'] +['(v', 'ideo'] +['ĠC', 'U'] +['System', 'Service'] +['Ġ', 'elf'] +['Ġkont', 'akt'] +['ë', 'ª'] +['ke', 'es'] +['gt', 'k'] +['Ġparam', 'Int'] +['Ġmark', 'up'] +['u', 'ales'] +['Ġaccount', 'ed'] +['Ġgang', 'bang'] +['RY', 'PT'] +['ĠW', 'rong'] +['Ġcred', 'ited'] +['ĠM', 'ESSAGE'] +['Ġfl', 'aws'] +['Ġbb', 'w'] +['Ġmetab', 'olic'] +['ĠO', 'EM'] +['/', 'event'] +['(C', 'ollectors'] +['mont', 'on'] +['ap', 'pear'] +['Ġopt', 'ed'] +['Ġche', 'at'] +['Ġd', 'av'] +['ĠPro', 'ceed'] +['Ġê', '¸'] +['ank', 'ed'] +['и', 'з'] +['ans', 'k'] +['ĠH', 'ang'] +['ĠC', 'ler'] +['Ġdis', 'gu'] +['Ġc', 'map'] +['.cl', 'js'] +['Ġa', 'ument'] +['le', 'z'] +['ĠJo', 'ined'] +['_re', 'ceived'] +['Ġa', 'erial'] +['ot', 'el'] +['Ġgre', 'et'] +['"', 's'] +['ĠGen', 'esis'] +['ĠCal', 'if'] +['pan', 'ion'] +['Ġtail', 'ored'] +['m', 'apping'] +['and', 'Expect'] +['.tr', 'ack'] +['at', 'omy'] +['ĠO', 'w'] +['ull', 'ah'] +['.Y', 'es'] +['ĠSimple', 'Name'] +['db', 'h'] +["'", 'en'] +['Ġnons', 'ense'] +['Ġphilosoph', 'ical'] +['(get', 'Context'] +['Ġis', 'so'] +['ĠA', 'CE'] +['start', 'Date'] +['Ġb', 'ÄĻd'] +['ĠAUTH', 'OR'] +['ĠGlo', 'be'] +['Ġinsect', 's'] +['_A', 'l'] +['ush', 'ing'] +['è®', '°'] +['/', 'Home'] +['ĠLocal', 'Date'] +['need', 'ed'] +['hes', 'ive'] +['Ġill', 'usion'] +['äº', 'Į'] +['Ġtr', 'at'] +['x', 'o'] +['/d', 'etail'] +['_M', 'ATCH'] +['Ġbroad', 'band'] +['Ġw', 'al'] +['ĠIllegal', 'StateException'] +['IRE', 'CTION'] +['Ġnor', 'theast'] +['es', 'ium'] +['ĠClient', 'e'] +['ul', 'ance'] +['nt', 'y'] +['Ġt', 'ecn'] +['Dev', 'ices'] +['Ġgr', 'ains'] +['ĠO', 'g'] +['ĠS', 'EL'] +['ud', 'iant'] +['Ġ++', ';Ċ'] +['Ġexplan', 'ations'] +['oc', 'co'] +['Ġdi', 'ets'] +['Ġco', 'hort'] +['(', 'controller'] +['.Iter', 'ator'] +['-r', 'ich'] +['ro', 'cess'] +['G', 'D'] +['Ġcar', 'bohydr'] +['Ġfri', 'ed'] +['ĠEmploy', 'ment'] +['ìŀ', '¥'] +['ĠLeon', 'ard'] +['_', '${'] +['qu', 'ares'] +['Ġcompan', 'ions'] +['Ġpar', 'is'] +['Ġstim', 'ulation'] +['ĠZ', 'oo'] +['Ġre', 'levance'] +['ĠCol', 'our'] +['Ġspe', 'ar'] +['ot', 'ional'] +['ĠL', 'ite'] +['ĠK', 'osten'] +['ĠÃ', '³'] +['_att', 'achment'] +['orph', 'ic'] +['Ġdam', 'it'] +['Ġd', 'lg'] +['Ġthr', 'ive'] +['CH', 'ANGE'] +['ĠApp', 'arently'] +['Ġat', 'ual'] +['Ġroot', 'ed'] +['(', 'images'] +['aw', 'i'] +['ari', 'at'] +['Ġch', 'erry'] +['STAT', 'IC'] +['m', 'nt'] +['ĠUser', 'Id'] +['il', 'let'] +['ĠHis', 'panic'] +['Ġn', 'ak'] +['Ġcent', 'ro'] +['Ġdim', 's'] +['_initial', 'ize'] +['ı', 'k'] +['ĠCent', 'ers'] +['RE', 'N'] +['Ġevolution', 'ary'] +['ĠTop', 'ics'] +['_d', 'amage'] +['em', 'er'] +['Ġr', 'und'] +['Ġpun', 'ished'] +['Ġcub', 'ic'] +['f', 'air'] +['[]', ';ĊĊ'] +['Ġinstant', 'iate'] +['Ġover', 'see'] +['-', 'delete'] +['unte', 'er'] +['start', 'Time'] +['ĠP', 'ipeline'] +['_G', 'AME'] +['ĠC', 'ir'] +['ĉ', 'Null'] +['.Format', 'ting'] +['uc', 'umber'] +['ĠR', 'ide'] +['Ġz', 'oo'] +['Ġcheck', 'er'] +['åIJ', 'Į'] +['=', 'C'] +['Ġg', 'rit'] +['");', '//'] +['_x', 'y'] +['ĠDe', 'claration'] +['Ġcall', 'able'] +['F', 'oo'] +['ĠList', 'Item'] +['Ġin', 'accur'] +['ml', 'in'] +['ĉ', 'Data'] +['Ġev', 'olving'] +['aw', 'an'] +['Ġca', 'fe'] +['fol', 'k'] +['_ID', 'X'] +['ĠAny', 'thing'] +['ĠPalest', 'ine'] +['ĠGrid', 'View'] +['Ġcol', 'ony'] +['ĠGerm', 'ans'] +['(', '+'] +['.p', 'id'] +['.js', 'x'] +['ĠSuper', 'ior'] +['Christ', 'ian'] +['ĠL', 'ect'] +['ĉ', 'Game'] +['Ġinstrument', 'al'] +['Anim', 'ations'] +['д', 'ал'] +['ĠMos', 'es'] +['ĉĉčĊ', 'ĉĉčĊ'] +['z', 's'] +['k', 'te'] +['ä¸', 'ļ'] +['_D', 'IST'] +['bit', 'map'] +['d', 'B'] +['Ġp', 'ersistence'] +['ÑĢ', 'оÑģ'] +['$', 'l'] +['B', 'ron'] +['Ġ{', '|'] +['_ch', 'art'] +['ĠCon', 'sum'] +['Ġh', 'emp'] +['Ġ"', '))Ċ'] +['Ġattack', 'ers'] +['Ġknowledge', 'able'] +['Ġc', 'et'] +['Ġvir', 'uses'] +["'", 'I'] +['Ġpitch', 'er'] +['Ġsweep', 'ing'] +['=', 'list'] +['apt', 'ops'] +['.de', 'pth'] +['Ġinstruct', 'ed'] +['ĠR', 'us'] +['benh', 'avn'] +['Ġи', 'н'] +['S', 'ports'] +['Ġon', 'set'] +['æĿ', 'ĥ'] +['.', 'RED'] +['_s', 'i'] +['ĠP', 'ST'] +['.on', 'Change'] +['>', 'tag'] +['ĠR', 'oh'] +['_char', 'acter'] +['ĠLaw', 's'] +['ĠB', 'achelor'] +['_s', 'wap'] +['.re', 'activex'] +['Ġreward', 'ing'] +['Med', 'ium'] +['-', '['] +['ĠRec', 'ently'] +['J', 'oint'] +['part', 'ition'] +['ĠMin', 'utes'] +['Ġind', 'o'] +['Ġabsor', 'bed'] +['ĠG', 'N'] +['_IN', 'D'] +['Ġsab', 'er'] +['Sp', 'awn'] +['output', 's'] +['ĠJeff', 'rey'] +['Ġmed', 'ieval'] +['h', 'ed'] +['Gu', 'ide'] +['Ġpsy', 'cho'] +['Ġgl', 'am'] +['E', 'lim'] +['äd', 'chen'] +['_pl', 'ain'] +['ĠS', 'au'] +['-f', 'our'] +['Ġanaly', 'zing'] +['QU', 'ERY'] +['Ġtom', 'ato'] +['_button', 's'] +['V', 'EN'] +['.set', 'Status'] +['.', 'Url'] +['+', 'ĊĊ'] +['Ġcompl', 'aining'] +['deg', 'ree'] +['conf', 'irmed'] +['Ġsub', 't'] +['p', 'arsed'] +['Ġtor', 'que'] +['Ġtroub', 'led'] +['ĠT', 'ARGET'] +['Ġtrad', 'emarks'] +['ĠCo', 'ordinate'] +['ĠV', 'iv'] +['Ġ//', '}ĊĊ'] +['Ġapr', 'ès'] +['.get', 'Position'] +['(Key', 'Code'] +['ĠSil', 'va'] +['Ġmet', 'eor'] +['Ġendorse', 'ment'] +['Over', 'view'] +['ĠP', 'oss'] +['.In', 'ject'] +['Ġeven', 'ly'] +['Ġvisual', 'ization'] +['Ġw', 'char'] +['ĠH', 'DMI'] +['Ġfun', 'ct'] +['ick', 'name'] +["','", "','"] +['Ġfor', 'wards'] +['Managed', 'Object'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠ'] +['ĉ', 'server'] +['ĠOut', 'look'] +['ĠChron', 'icle'] +['Ġdub', 'bed'] +['Ġd', 'ok'] +['ĠW', 'ear'] +['.A', 'L'] +['pare', 'n'] +['.', 'Interface'] +['Inter', 'faces'] +['.c', 'od'] +['Ġd', 'ib'] +['.Global', 'ization'] +['ĠAcad', 'emic'] +['Ġass', 'ms'] +['Aut', 'om'] +['Ġl', 'w'] +['ĠN', 'W'] +['Ġ&&', 'čĊ'] +['Ġproble', 'ma'] +['ĠManufact', 'uring'] +['lim', 'its'] +['-m', 'obile'] +['Ġfil', 'me'] +['/', 'map'] +['Ġdo', 'it'] +['ĠIn', 'k'] +['Ġsu', 'ed'] +['.', 'arr'] +['Ġunder', 'min'] +['ĠPro', 'c'] +['croll', 'View'] +['__', '$'] +['Ġsidew', 'alk'] +['(', 'that'] +['à¸', '·'] +['[', 'q'] +['gram', 'mar'] +['Ġt', 'ë'] +['qu', 'ito'] +['Ġspir', 'al'] +['ext', 'ended'] +['Ġf', 'ocal'] +['Ġdig', 'ging'] +['p', 'as'] +['ĠT', 'all'] +['.pro', 'xy'] +['it', 'ures'] +['TR', 'ACT'] +['ĠRe', 'alm'] +['Ġf', 'eder'] +['Ġorient', 'ed'] +['ĠAltern', 'ative'] +['Ġo', 'we'] +['Ġsour', 'ced'] +['ink', 'er'] +['.d', 'et'] +['S', 'ep'] +['ĠQ', 'ui'] +['ĠPal', 'mer'] +['(_', ','] +['s', 'amples'] +['oy', 'er'] +['ull', 'an'] +['que', 'z'] +['Ed', 'ges'] +['Ġsh', 'out'] +['ĠA', 'chie'] +['Ġha', 'ar'] +['_Con', 'struct'] +['Ġprem', 'ature'] +['Ġre', 'vert'] +["').", 'Ċ'] +['Ġs', 'chn'] +['filter', 'ed'] +['null', 'ptr'] +['S', 'aved'] +['itect', 'ure'] +['CL', 'A'] +['Ġv', 'l'] +['st', 'ell'] +['ĉ', 'Me'] +['ĠL', 'ip'] +['n', 'ational'] +['Ġwh', 'olly'] +['Ġspr', 'ings'] +['.T', 'imer'] +['ĉs', 'rc'] +['els', 'en'] +['åħ', '¶'] +['Ġcommunic', 'ating'] +['ĠQu', 'iz'] +['Ġt', 'eng'] +['Ġge', 'z'] +['ĠOut', 'side'] +['.S', 'ign'] +['(c', 's'] +['Ġdisput', 'es'] +['ĠWe', 'iss'] +['ann', 'es'] +['>', 'No'] +['ĠB', 'ach'] +['.remove', 'All'] +['re', 'fer'] +['/d', 'ashboard'] +['ĠA', 'jax'] +['Index', 'Changed'] +['ĠWe', 'ak'] +["'", '"Ċ'] +['Ġs', 'ights'] +['access', 'Token'] +['ĠJ', 'oi'] +['(d', 'omain'] +['ĉc', 'v'] +['Ġcontin', 'uation'] +['Ġpl', 'um'] +['ad', 'ir'] +['.set', 'Message'] +['Ġ', 'ï¼Į'] +['Ġsw', 'allow'] +['ĠL', 'amp'] +['Ġq', 'w'] +['Ġu', 'u'] +['C', 'oin'] +['ub', 'ic'] +['ĠDe', 'als'] +['r', 'ace'] +['Ġdict', 'ator'] +['Ġmem', 'e'] +['turn', 'ed'] +['ĠJul', 'ie'] +['.grid', 'Column'] +['Ġpup', 'py'] +['Ġp', 'am'] +['Ġ)', '{čĊ'] +['Ġinv', 'iting'] +['Ġf', 'rench'] +['v', 'im'] +['Ġwr', 'apping'] +['Ġ#-', '}Ċ'] +['([', '-'] +['Ear', 'ly'] +['Ġsh', 'iny'] +['.f', 'aces'] +['Ġreb', 'ell'] +['abc', 'def'] +['ä', 'lt'] +['Ġest', 'imation'] +['ph', 'ys'] +['los', 'ures'] +['_RE', 'L'] +['Ġex', 'clusion'] +['ĠSk', 'ype'] +['we', 'ise'] +['-st', 'op'] +['no', 'thing'] +['ĠE', 'gg'] +['is', 'ors'] +['Rich', 'ard'] +['Ġcounsel', 'ing'] +['Ġcomm', 'em'] +['ĠQ', 'MessageBox'] +['ĠSy', 'nd'] +['ĠFro', 'st'] +['ĠCompet', 'ition'] +['ĠAw', 'ake'] +['Ġt', 'ed'] +['ic', 'iones'] +['ĠDev', 'Components'] +['VERTISE', 'MENT'] +['ott', 'i'] +['.run', 'ner'] +['Ġuniqu', 'ely'] +['.fl', 'ag'] +['ĉ', 'rs'] +['_g', 'eneric'] +['Ġ``', '`Ċ'] +['ACH', 'INE'] +['Ġme', 'in'] +['(', 'Application'] +['(', 'br'] +['Ġrat', 'ios'] +[':', ','] +['ĠXCT', 'est'] +['ustain', 'able'] +['-', 'www'] +['it', 'les'] +['_T', 'EMP'] +['Ġs', 'yst'] +['umeric', 'UpDown'] +['ĉassert', 'True'] +['Ġw', 'f'] +['.', 'peek'] +['ĠBul', 'g'] +['Ġterr', 'ifying'] +['.M', 'ODE'] +['ĠG', 'W'] +['á', 'r'] +['Ġf', 'ic'] +['Ġcommit', 'ments'] +['-', 'tech'] +['ĠL', 'iquid'] +['ope', 'z'] +['z', 'heimer'] +['a', 'ña'] +['-m', 'edia'] +['(', 'animated'] +['_go', 'al'] +['Ġg', 'um'] +['yst', 'one'] +['.S', 'ET'] +['ĠW', 'end'] +['set', 'CellValue'] +['Ġmsg', 's'] +['c', 'ash'] +['AL', 'LOC'] +['/', 'aws'] +['Ġmic', 'rowave'] +['.Point', 'er'] +['ĉ', 'Console'] +['_s', 'orted'] +['ĠFil', 'ip'] +['Pro', 'd'] +['Ġ//!', '<'] +['ing', 'roup'] +['Ġk', 's'] +['_T', 'RI'] +['Ġteas', 'poon'] +['ĠAT', 'T'] +['Ġrecover', 'ing'] +['ĠG', 'LOBAL'] +['.P', 'ar'] +['Ġ/>', ';Ċ'] +['Ġmar', 'ble'] +['ul', 'ators'] +['ĠC', 'ycle'] +['Ġher', 'bs'] +['_m', 'etric'] +[')', '!'] +['_C', 'LOCK'] +['_', 'Button'] +['H', 'arry'] +['è¿', 'Ľ'] +['Ġstr', 'ains'] +['ĠApp', 'Bar'] +['ĠCh', 'an'] +['/v', 'ideo'] +['Ġb', 'am'] +['.Pro', 'gress'] +['$', 'f'] +['lem', 'en'] +['Ġir', 'regular'] +['ĠD', 'uncan'] +['ĠM', 'int'] +['-v', 'ideo'] +['à¦', '¾'] +['ó', 'wn'] +['ĠEM', 'PTY'] +['Ġstack', 'ed'] +['ĠH', 'A'] +['_c', 'ut'] +['Ġwhere', 'in'] +['ĠW', 'ays'] +['(count', 'er'] +['è¯', 'ķ'] +['Form', 'Group'] +['Ġble', 'w'] +['c', 'ourses'] +['Ġproduct', 'os'] +['ry', 's'] +['ĠRest', 'r'] +['Ġsty', 'ling'] +['>', 's'] +['Ġp', 'iv'] +['Ġit', 'ertools'] +['get', 'Repository'] +['ĠI', 'k'] +['_dev', 'ices'] +['lay', 'ui'] +['Ġhalf', 'way'] +['Ġfran', 'ç'] +['Ġtun', 'ing'] +['O', 'A'] +['_N', 'ode'] +['ar', 'de'] +['Ġfier', 'ce'] +['lic', 'ted'] +['#', 'čĊ'] +['Ġbreak', 'through'] +['ĠE', 'rik'] +['Ġb', 'ride'] +['Ġ.', '"'] +['cul', 'us'] +['ins', 'ide'] +['ĠIndian', 'apolis'] +['ĠE', 'E'] +['Ġy', 'og'] +['urre', 't'] +['.f', 's'] +['.', 'grad'] +['_c', 'ards'] +['_ac', 'curacy'] +['_ep', 'i'] +['qu', 'eda'] +['/', 'org'] +['é', 'ªĮ'] +['Ġcom', 'pte'] +['))', '['] +['Out', 'side'] +['G', 'reater'] +['ĠRender', 'er'] +['.', 'actor'] +['Account', 's'] +['Id', 'le'] +['_h', 'ours'] +['ern', 'er'] +['Jo', 'ined'] +['Ġmen', 'j'] +['requ', 'ires'] +['ĠO', 'PER'] +['.remove', 'Child'] +['ĉs', 'p'] +['Ġes', 'se'] +['r', 'ift'] +['xF', 'E'] +['ĠSh', 'akespeare'] +['________', '____'] +['Ġbudget', 's'] +['Model', 'State'] +['fill', 'able'] +['-', 'component'] +['oc', 'os'] +['ĠBUT', 'TON'] +['/', 'io'] +[',', 'out'] +['s', 'ms'] +['Th', 'omas'] +['ĠAr', 'med'] +['res', 'ume'] +['Ġrot', 'ating'] +['ĠV', 'ault'] +['Ġse', 'us'] +['.', '(*'] +['Ġa', 'mino'] +['Ġ[]', ');ĊĊ'] +['Ġprov', 'oc'] +['no', 'x'] +['.Get', 'Enumerator'] +['====', '===Ċ'] +['æĸ', 'Ļ'] +['_sc', 'roll'] +['Ġfil', 'med'] +['ĠS', 'oci'] +['g', 'ap'] +['g', 'ro'] +['V', 'ote'] +['"', 'But'] +['_R', 'C'] +['An', 'imal'] +['Â', 'Ģ'] +['ib', 'ile'] +['Ġaw', 'aken'] +['ore', 'st'] +['in', 'ja'] +['ĠI', 'van'] +['(', 'Command'] +['Ġ', '*****'] +['Î', '·'] +['Ġkv', 'inder'] +['/h', 'elpers'] +['_c', 'ases'] +['t', 'g'] +['ìĦ', '¸'] +['Register', 'ed'] +['ĉp', 'ass'] +['_d', 'igits'] +['Ġcont', 'our'] +['Ġinf', 'ants'] +['Ġjust', 'ification'] +['ĠFort', 'unately'] +['Con', 'tr'] +['ĠonCreate', 'View'] +['_S', 'AMPLE'] +['Ġallow', 'Null'] +['Ġn', 'ud'] +['Ġfet', 'ched'] +['_e', 'qu'] +['ĠUn', 'able'] +['=\\"', '"'] +['>', '{Ċ'] +['Ġcommit', 'tees'] +['ist', 'ema'] +['+', '".'] +['ÃŃ', 'an'] +['m', 'ant'] +['Ġsou', 'theast'] +['ï¼Į', 'Ċ'] +['dialog', 's'] +['PRO', 'JECT'] +['charg', 'er'] +['-', 'port'] +['(u', 'uid'] +['.', 'export'] +['S', 'ix'] +['ĠR', 'P'] +['P', 'rem'] +['Ġconsc', 'ience'] +['Ġmargin', 'Right'] +['_d', 'istribution'] +['y', 'aml'] +['res', 'izing'] +['D', 'ock'] +['ĠLoc', 'ations'] +['G', 'Y'] +['Se', 'ed'] +['B', 'UFFER'] +['oss', 'ip'] +['ull', 'en'] +['Th', 'ings'] +['-', 'self'] +['.p', 'oll'] +['PL', 'AYER'] +['Ġå', '®'] +['G', 'ROUP'] +['ĠA', 'way'] +['Ġg', 'ospel'] +['xf', 'd'] +['M', 'ary'] +['ĠPort', 'able'] +['T', 'URE'] +['Ġutil', 'is'] +['Ġse', 'it'] +['Ġstr', 'and'] +['Ġtrans', 'c'] +['Ġ(', '^'] +['ĠAl', 'fred'] +['.m', 'em'] +['.c', 'ircle'] +['Ġ~', '/'] +['for', 'cing'] +['Ġr', 'iot'] +['pro', 'x'] +['TH', 'ON'] +['iz', 'ación'] +['ĠN', 'I'] +['ro', 'st'] +['Ġdis', 'pro'] +['_in', 'stances'] +['ï¼Į', 'âĢľ'] +['ograph', 'er'] +['end', 'as'] +['ĠIsa', 'ac'] +['ĠP', 'ine'] +['/d', 'is'] +['Ġcolor', 'With'] +['iter', 'ate'] +['_str', 'ide'] +['Ġpun', 'to'] +['.Event', 'Args'] +['(', 'center'] +['Ġneighb', 'oring'] +['ĠPr', 'ison'] +['ĠMess', 'enger'] +['Ġepid', 'emic'] +['da', 'o'] +['_com', 'plex'] +['Ġgr', 'avel'] +['_D', 'IP'] +['é', 'ment'] +['ĠA', 'ri'] +['_bit', 'map'] +['.qu', 'it'] +['(', 'valid'] +['Ġp', 'end'] +['Ġrespir', 'atory'] +['Ġre', 'bound'] +['Default', 'Value'] +['ãĥ', 'Ń'] +['Ġcomm', 'its'] +['.test', 's'] +['_f', 'r'] +['it', 'et'] +['.s', 'f'] +['Ġspace', 'craft'] +['c', 'ritical'] +['Ġde', 'pressed'] +['ĠAny', 'Object'] +['Ġun', 'b'] +['Ġdisc', 'ern'] +['(m', 'ysql'] +['L', 'atin'] +['ĠB', 'og'] +['ĠWild', 'life'] +['To', 'File'] +['iox', 'id'] +['@', 'RestController'] +['Ġ"$', '('] +['Ġ<<', '"'] +['Ġdefect', 's'] +['Ġdat', 'um'] +['h', 'in'] +['Ġreal', 'izar'] +['any', 'ahu'] +['ĠS', 'ig'] +['@', 'Data'] +['ad', 'aptive'] +['ĠC', 'atherine'] +['.c', 'r'] +['ĠCO', 'OKIE'] +['Ġp', 'ictured'] +['ĠFight', 'er'] +['Query', 'able'] +['ĠAny', 'way'] +['ĠGL', 'FW'] +['_n', 'amespace'] +['_', 'ft'] +['Ġ]', ')'] +['Organ', 'ization'] +['Ġconstit', 'utes'] +['Ġqu', 'and'] +['(ch', 'unk'] +['"/', '>čĊ'] +['ĠL', 'akes'] +['main', 'window'] +['Car', 'thy'] +['sp', 'in'] +['(c', 'sv'] +[':', 'red'] +['-com', 'merce'] +['à¸', '¹'] +['Ġdiscover', 'ing'] +['Ġe', 'co'] +['_f', 'ac'] +['inc', 'eton'] +['ĠGre', 'ens'] +['j', 'wt'] +['Ø', 'µ'] +['ĠBron', 'cos'] +['ĠGood', 's'] +['(G', 'TK'] +['Ġreturn', 'Value'] +['Ġsi', 'empre'] +['Ġneut', 'r'] +['w', 'ent'] +['ĠN', 'atal'] +['Ġenthusi', 'astic'] +['á»', 'į'] +['F', 'N'] +['/d', 'atabase'] +['C', 'atalog'] +['Ġbr', 'un'] +['ĠK', 'ash'] +['_P', 'l'] +['isc', 'rim'] +[',', 'width'] +['Ġin', 'mates'] +['Ass', 'ignment'] +['ĠH', 'aven'] +['Ġplay', 'ground'] +['ex', 'am'] +['@', 'Controller'] +['ul', 'iar'] +['.get', 'Parent'] +['Ġ"', ';ĊĊ'] +[':', 'size'] +['iss', 'ors'] +['Ġf', 'is'] +['Ġal', 'c'] +['ens', 'ation'] +['ĠN', 'ixon'] +['Ġmight', 'y'] +['-', 'str'] +['_s', 'pecial'] +['_A', 'DC'] +['ĠTw', 'ig'] +['um', 'bling'] +['-', 'address'] +['Ġher', 'oin'] +['Y', 'TE'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĊ'] +['F', 'riend'] +['Ġa', 've'] +['ĠP', 'NG'] +['ĠKurd', 'ish'] +['DataSet', 'Changed'] +['Ġbl', 'ades'] +['br', 'al'] +['St', 'eam'] +['Ġsig', 'u'] +['IRT', 'UAL'] +['ac', 'os'] +['UD', 'P'] +['(d', 'atabase'] +['he', 'c'] +['ĠString', 's'] +['_scal', 'ar'] +['ĉd', 'esc'] +['ĠT', 'LS'] +[';', '"Ċ'] +['ĠCor', 'byn'] +['Simple', 'Name'] +['u', 'ell'] +['ĠEnt', 're'] +['ell', 'ites'] +['-', 'place'] +['Ġfrank', 'ly'] +['ĠE', 'rf'] +['CE', 'L'] +['Ġpa', 'ÃŃs'] +['Ġh', 'edge'] +['Ġlat', 'ent'] +['ĠIR', 'Q'] +['ĠH', 'erald'] +['ĠP', 'rec'] +['ë³', '´'] +['.T', 'EXT'] +['Sal', 'ary'] +['Ġaut', 'umn'] +['Ġtrav', 'ail'] +['.S', 'um'] +['Ġc', 'ared'] +['M', 'or'] +['Ġint', 'uitive'] +['Ġj', 'ournals'] +['_', 'IT'] +['ĠT', 'rou'] +['ä¼', 'ł'] +['Has', 'ColumnName'] +['Com', 'posite'] +['Ġsp', 'ice'] +['_d', 'isk'] +['_CODE', 'S'] +['ĠInt', 'roduced'] +['ion', 'a'] +['Ġnue', 'stra'] +['o', 'ct'] +['ĠĠĠĠĊĠĠĠĠĊ', 'ĠĠĠĠĊ'] +['(param', 'eter'] +['Ġstud', 'ios'] +['Ġproject', 'Id'] +['Ġbd', 'sm'] +['.Sql', 'Client'] +['im', 'izer'] +['ĠC', 'ARD'] +['+', 't'] +['a', 'an'] +['.s', 'ol'] +['_Ad', 'just'] +['Ġright', 'eous'] +['ĠLog', 'ging'] +['.f', 'ilters'] +['_T', 'AB'] +['ĉs', 'ys'] +['roph', 'ic'] +['other', 'apy'] +['ĠB', 'rowse'] +['key', 'board'] +['R', 'ON'] +['+', '\\'] +['ro', 'pped'] +['Ġext', 'ensively'] +['f', 'k'] +['Ġl', 'ime'] +['year', 's'] +['Ex', 'c'] +['Ġs', 'ph'] +['Ġche', 'ating'] +['and', 'ro'] +['ÃŃ', 'o'] +['Ġpr', 'ince'] +['o', 'ire'] +['ĠD', 'estination'] +['ĠConvert', 's'] +['Ġup', 'stream'] +['o', 'led'] +['Ġserv', 'ants'] +['Ġsem', 'antic'] +['Ġcr', 'unch'] +['Ġevent', 'ual'] +['run', 'ner'] +['/', 'error'] +['Sp', 'in'] +['Ġsecret', 'ly'] +['Ġas', 'semble'] +['.P', 'erson'] +['end', 'error'] +['_', '<'] +['Ġp', 'endant'] +['S', 'leep'] +['ĠChem', 'istry'] +['Ġboss', 'es'] +['l', 'k'] +['))', '),Ċ'] +['Block', 'ly'] +['DE', 'VICE'] +['Ġreflect', 'ing'] +['Ġam', 'ple'] +['Mill', 'iseconds'] +['ĠPresident', 'ial'] +['Ġus', 'uarios'] +['ĠN', 'Z'] +['ĠSal', 'ary'] +['ĠA', 'manda'] +['_n', 'p'] +['j', 'ury'] +['Ġkö', 'n'] +['Ġtherap', 'ist'] +['Ġhomosex', 'ual'] +['ĠDr', 'ake'] +['-w', 'indow'] +['ĠLoc', 'ated'] +['.D', 'river'] +['ĠV', 'IDEO'] +['Ġmerch', 'ants'] +['ĠC', 'hest'] +['-', 'lock'] +['/', 'php'] +['Ġmil', 'ano'] +['_ST', 'YLE'] +['arg', 'er'] +['ide', 'a'] +['G', 'UID'] +['adv', 'anced'] +['me', 'al'] +['Options', 'ItemSelected'] +["='", '%'] +['ĠCh', 'am'] +[':', 'data'] +['(st', 'at'] +['Will', 'Appear'] +['Ġinform', 'al'] +['aj', 'i'] +['Ġre', 'productive'] +['ĠC', 'AS'] +['ãģ', '£'] +['F', 'UNC'] +['ĠR', 'uth'] +[')+', '('] +['CON', 'ST'] +['ĠF', 'ans'] +['Ġgroup', 'Id'] +['xffff', 'ffff'] +['Ġsam', 'pler'] +['Ġ}}', '">'] +['.', 'the'] +['Ġh', 'ollow'] +['W', 'AY'] +['ĠFac', 'ulty'] +['Attrib', 'utedString'] +['ĠLook', 's'] +['ĠR', 'ex'] +['j', 'k'] +['ĠM', 'IL'] +['Ġb', 'ard'] +['.L', 'ong'] +['Ġliv', 'est'] +['Ġsk', 'al'] +['ic', 'ism'] +['MA', 'IN'] +['Ġmu', 'cho'] +['B', 'ODY'] +['Ġes', 'e'] +['ĉ', 'use'] +['F', 'oot'] +['.SQL', 'Exception'] +['Ġinherit', 'ance'] +['re', 'ceived'] +['Ġput', 'as'] +['ed', 'is'] +['als', 'a'] +['ĠError', 'Message'] +['Book', 'ing'] +['Ġtr', 'act'] +['ac', 'z'] +['ĠC', 'ant'] +['_reg', 'ex'] +['Ġide', 'ological'] +['Ġj', 'ihad'] +['h', 'os'] +['/s', 'ys'] +['col', 'm'] +['(p', 'ool'] +['Ġest', 'án'] +['ĠP', 'ending'] +['em', 'ás'] +['Ġktó', 'ry'] +['));ĊĊ', 'Ċ'] +['trans', 'actions'] +['Ġw', 'ield'] +['it', 'ere'] +['ert', 'ure'] +['_s', 's'] +['Ġstretch', 'ing'] +['Ġprison', 'er'] +['.Read', 'All'] +['Ġbes', 'ch'] +['--', ';čĊ'] +['Ġcr', 'isp'] +['_SC', 'AN'] +['Ġa', 'e'] +['Str', 'ict'] +['ĠMin', 'neapolis'] +['ĠBo', 'eing'] +['ar', 'is'] +['re', 'k'] +['_p', 'ipe'] +['Ġpri', 'ests'] +['(E', 'IF'] +['eh', 'icles'] +['ĠInter', 'active'] +['b', 'etween'] +['ĉNull', 'Check'] +['ĠBl', 'air'] +['ĠL', 't'] +['_in', 'line'] +['eth', 'yl'] +['Â', '¼'] +['_p', 'ackages'] +['Ġbarrel', 's'] +['_', 'he'] +['Ġreg', 'exp'] +['_', 'pts'] +['_H', 'andler'] +['ing', 'ular'] +['ĠN', 'issan'] +['ĠR', 'anch'] +['Ġper', 'ch'] +['Un', 'supported'] +['Sm', 'ith'] +['ĠLeg', 'ends'] +['M', 'i'] +['Ġg', 'f'] +['st', 'eder'] +['Ġacqu', 'iring'] +['Ġsim', 'ulator'] +['()', ',"'] +['re', 'ceive'] +['Ġin', 'place'] +['A', 'CTION'] +['ĠWeb', 'Driver'] +['files', 'ystem'] +['<', 'Order'] +['lo', 'pen'] +['ĠHE', 'IGHT'] +['.set', 'Border'] +['į', '°'] +['__', '["'] +['Ġcl', 'amp'] +['Seg', 'oe'] +['b', 'ands'] +['to', 'List'] +['amb', 'a'] +[">'", '+Ċ'] +['Ġcred', 'ible'] +['am', 'at'] +['play', 'ing'] +['.setImage', 'Resource'] +['qu', 'el'] +['Ġpod', 'r'] +['ge', 'om'] +['E', 'k'] +['ĠQ', 'atar'] +['Ġg', 'eld'] +['?', "',Ċ"] +['Ġc', 'yl'] +['(', 'ax'] +['ĠW', 'I'] +['ur', 'ally'] +['ĠBr', 'asil'] +['Ġsen', 'za'] +['ale', 'y'] +['on', 'en'] +['Ġb', 'ah'] +['Ġmolec', 'ule'] +['R', 'ad'] +['è¿', '°'] +['AN', 'CH'] +['-', 'background'] +['-', 'agent'] +['Ġprol', 'ifer'] +[':', 'boolean'] +['Ġt', 'ide'] +['erial', 'izer'] +['_', ';čĊ'] +['F', 'ee'] +['**', ')'] +['erg', 'y'] +['ĠHon', 'or'] +['.Log', 'ging'] +['ir', 'is'] +['Ġunder', 'mine'] +['ĠD', 'y'] +['Ġt', 'yr'] +['Ġde', 'que'] +['Ġdam', 'er'] +['([]', ')Ċ'] +['.layout', 'ControlItem'] +['pe', 'ated'] +['C', 'AN'] +['rag', 'ments'] +['L', 'and'] +[')', ']);Ċ'] +['ĠS', 'ah'] +['ĠDE', 'CL'] +['With', 'in'] +['ĠN', 'amespace'] +['an', 'other'] +['sem', 'bling'] +['.des', 'cribe'] +['Con', 'sum'] +['ĠF', 'ear'] +['g', 'iven'] +['Or', 'ange'] +['<', 'boolean'] +['Ġstead', 'ily'] +['pa', 'Repository'] +['Ġresult', 'Set'] +['_', 'ENTER'] +['_re', 'peat'] +['Ġt', 'ones'] +['ĠPRO', 'P'] +['n', 'al'] +['part', 'icle'] +['Ġsign', 'aling'] +['Ġaccess', 'ory'] +['ĉĉĉĉĉĉ', 'ĠĠ'] +['Ġvie', 'le'] +['ĠNo', 'ah'] +['-', 'ag'] +['Ġmur', 'ders'] +['Ġa', 'ired'] +['ĠPL', 'AY'] +['ĠS', 'ullivan'] +['_C', 'ore'] +['Ġul', 'ong'] +['Ġblog', 'ging'] +['>', 'This'] +['Ġdata', 'Index'] +['Ġprint', 'able'] +['ĠE', 'yes'] +['_target', 's'] +['(P', 'y'] +['.', 'over'] +['Ġbr', 'u'] +['am', 'pton'] +['Ġplaint', 'iff'] +['<', 'Key'] +['b', 'ull'] +['ĠâŁ', '¨'] +['Iss', 'ue'] +['.cor', 'nerRadius'] +['C', 'ritical'] +['_p', 'hi'] +['.', 'angle'] +['Ġdynam', 'ically'] +['!', '");čĊ'] +['>', ');Ċ'] +['in', 'vest'] +['.*', 'ĊĊ'] +['Ġt', 'élé'] +['Ġsuper', 'f'] +['Ġcas', 'cade'] +['DT', 'D'] +['Ġviv', 'id'] +['Ġsubsid', 'ies'] +['ĠH', 'ass'] +['Ġcoll', 'aps'] +['Ġcer', 'amic'] +['{}', '".'] +['ĠLeak', 'age'] +['-tr', 'ash'] +['coll', 'apsed'] +['-s', 'ocial'] +['ĠCh', 'ad'] +['Ġincl', 'ined'] +['Ġst', 'o'] +['Ġstory', 'board'] +['.p', 'ayment'] +['stack', 'overflow'] +['ĠRaid', 'ers'] +['Ġ#', "'"] +['olic', 'ies'] +['ìľ¼', 'ë¡ľ'] +['em', 'ap'] +['Ġk', 'j'] +['Ġqu', 'ota'] +['ĠGard', 'ens'] +['ë²', 'Ī'] +['ĠAng', 'els'] +['Ġof', 't'] +['Ġlower', 'case'] +['Ġi', 'Param'] +['Ġche', 'apest'] +['un', 'ta'] +['_p', 'kt'] +['ic', 'ators'] +['Ġle', 'urs'] +['Ġdecre', 'ases'] +['ĉ', 'define'] +['PRE', 'C'] +['amm', 'ers'] +['ĠPre', 'paredStatement'] +['(d', 'irection'] +['Ġcre', 'ws'] +['ark', 'ed'] +['ĠMem', 'phis'] +['ĠS', 'ell'] +['G', 'TK'] +['Ġm', 'aid'] +[':', 'disable'] +['éĽ', 'Ĩ'] +['ĠP', 'f'] +['Ġal', 'beit'] +['open', 'h'] +['?>', '">Ċ'] +['.get', 'Source'] +['(s', 'cale'] +['D', 'u'] +['ĠP', 'IL'] +['_ref', 'resh'] +['Ġbet', 's'] +['(c', 'ar'] +['ĠV', 'on'] +['|', '--------------------------------------------------------------------------Ċ'] +['ĠGr', 'at'] +['M', 'uch'] +['(', 'Dialog'] +['.stop', 'Propagation'] +['Ġte', 'k'] +['Ġex', 'its'] +["'],", '$'] +['Ġphone', 'Number'] +['uc', 's'] +['ec', 'imal'] +['------------', '--'] +['in', 'p'] +['.po', 'jo'] +['Ġcor', 'pus'] +['Ġpractition', 'ers'] +['.p', 'ic'] +['"', 'testing'] +['Ġstring', 'By'] +['.Not', 'Null'] +['Ġr', 'ang'] +['.D', 'ynamic'] +['_R', 'ender'] +['аÑĤ', 'а'] +['Wait', 'ing'] +['ĠW', 'ik'] +['Ġoverwhel', 'med'] +['%', '">'] +['ĠA', 'E'] +['}}', '>Ċ'] +['u', 'w'] +['_t', 'yp'] +['Ġbuck', 'ets'] +['Ġgre', 'eting'] +['Ġla', 'ughter'] +['Ġant', 'agon'] +['uggest', 'ion'] +['-', 'email'] +['ĉt', 'op'] +['Ġer', 'os'] +['_tr', 'i'] +['Ġiss', 'uing'] +['Ġh', 'á'] +['Ġisol', 'ate'] +['Over', 'flow'] +[',', 'E'] +['Ġnut', 'ritional'] +['ĠAbb', 'ott'] +['Ġn', 'f'] +['.t', 'ouch'] +['.fetch', 'all'] +['_z', 'ip'] +['")', '}Ċ'] +['Ġam', 'at'] +['ĠC', 'isco'] +['Ġn', 'Ã¥'] +['PLE', 'X'] +['Ġse', 'i'] +['f', 'oto'] +['.to', 'Json'] +['å¤', 'ļ'] +['ĠKle', 'in'] +['Ġlib', 'c'] +['Ġmin', 'ers'] +['å', '¢'] +['-', 'print'] +['ĠP', 'ride'] +['T', 'odos'] +['Ġmask', 'ed'] +['Ġset', 'Data'] +['Ġtele', 'fon'] +['Ġunh', 'appy'] +['ĠT', 'ables'] +['ge', 'b'] +['(', 'debug'] +['_all', 'owed'] +['-', 'access'] +['Ġlog', 'istics'] +['Ġg', 'ems'] +['ĠM', 'ature'] +['Ġr', 'sp'] +['ĠAl', 'le'] +['.get', 'Bytes'] +['\\', 'web'] +['ynchron', 'ized'] +['Par', 'agraph'] +['Ġth', 'rottle'] +['.sql', 'ite'] +['cons', 'ulta'] +['ĠSe', 'ah'] +['C', 'e'] +['Ġsub', 'mar'] +['ER', 'E'] +['V', 'ous'] +['Ġre', 'ddit'] +['Ġsql', 'alchemy'] +['-m', 'ile'] +['oc', 'ide'] +['P', 'our'] +['}}', '">Ċ'] +['st', 'ead'] +['Ġ@', '('] +['Ġ[', '])'] +['ĠAd', 's'] +['Ġover', 'load'] +['r', 'idden'] +['ĠDes', 'ert'] +['ĠW', 'rap'] +['ĠPortug', 'uese'] +['et', 'z'] +['ĉf', 'irst'] +['Ġmile', 'stone'] +['æĹ', 'ł'] +['Ñĥ', 'Ñī'] +['(s', 'uccess'] +['<', 'Vector'] +['co', 'ol'] +['Ġ[', ']);Ċ'] +['erv', 'als'] +['Ġin', 'vert'] +['"', 'io'] +['cur', 'so'] +['fr', 'agment'] +['Ġfeas', 'ible'] +['.set', 'Position'] +['Ġel', 'm'] +['Ġimag', 'in'] +['@', 'Spring'] +['Ġb', 'ats'] +['pu', 'és'] +['ga', 'lement'] +['ns', 'ic'] +['gi', 'ene'] +['ell', 'ation'] +['ĠBa', 'iley'] +['Sh', 'ar'] +['ĠT', 'ul'] +['ĠH', 'K'] +['Ġfree', 'zing'] +['gl', 'm'] +['ce', 'ans'] +['-c', 'ut'] +['_c', 'ircle'] +['åij', 'ĺ'] +['n', 'egative'] +['Ġind', 'ian'] +['s', 'alt'] +['Ġt', 'ing'] +['ĉm', 'od'] +['Ġs', 'int'] +['ak', 'in'] +['um', 'l'] +['ĠText', 'Input'] +['Ġpop', 'ped'] +['T', 'MP'] +['Ġpark', 'ed'] +['×Ļ', '×'] +['ĠF', 'usion'] +['Ġhe', 'ater'] +['ET', 'F'] +['ro', 'zen'] +['h', 'all'] +['ĠM', 'ik'] +['lev', 'ard'] +['-', 'heart'] +['ĉ', 'order'] +['M', 'aking'] +['Ġpled', 'ged'] +['Ġdir', 's'] +['$', 'post'] +['ĠH', 'err'] +['stant', 'iate'] +[',', '"Ċ'] +['.get', 'Color'] +['ĠS', 'AT'] +['Ġtimed', 'elta'] +['ĠM', 'ai'] +['ĉm', 'ethod'] +['Ġid', 'iot'] +['ĠTr', 'av'] +['ident', 'ified'] +['ĠDiv', 'ine'] +['.get', 'Path'] +['D', 'ash'] +['Ġinf', 'iltr'] +['Ġhandle', 'Submit'] +['bro', 'ok'] +['.g', 'eneric'] +['.short', 'cuts'] +['................................', '................................'] +['Ġdat', 'ings'] +['ĠM', 'V'] +['', '#'] +['}', '"ĊĊ'] +['Ġimprison', 'ment'] +['ason', 'ic'] +['rou', 'd'] +['uc', 'ion'] +['æĬ', '¥'] +['Ġdia', 'lect'] +['Ġon', 'Mouse'] +['const', 'expr'] +['.label', 'Control'] +['Ġwe', 'aker'] +['Ġman', 'kind'] +['ĠRE', 'CE'] +['Ġd', 'iz'] +['Ġapp', 'Bar'] +['Ġqu', 'é'] +['f', 'ra'] +['_default', 's'] +['Ġal', 'iqu'] +['_at', 'om'] +[':', 'indexPath'] +['Ġmiss', 'es'] +['Ġvis', 'ually'] +['ĠH', 'ands'] +['STR', 'U'] +['i', 'ates'] +['_', 'asset'] +['F', 'inder'] +['mid', 't'] +['Ġsn', 'acks'] +['(__', "('"] +['.', 'uri'] +['ĠIn', 'strument'] +['ven', 'ir'] +['($', '__'] +['.Dot', 'NetBar'] +['Ġconfig', 's'] +['Ġguess', 'ed'] +['ि', 'à¤'] +['Ġinitial', 'izer'] +['Ġ?', '",'] +['ĠVer', 'izon'] +['man', 'ifest'] +['ge', 'ben'] +['.d', 'etails'] +['G', 'ate'] +['pons', 'ible'] +['ĠEl', 'im'] +[',', 'str'] +['Ġwrit', 'ings'] +['ĠD', 'erek'] +['ĠCo', 'ordinator'] +['Ġpill', 'ow'] +['Ġnotice', 'able'] +['R', 's'] +['Ġduplic', 'ates'] +['ern', 'els'] +['k', 'J'] +['.z', 'z'] +['oll', 'and'] +['ĠSE', 'CTION'] +['_f', 'name'] +['uff', 'led'] +["'].'", '', '")Ċ'] +['ĠD', 'ollar'] +['Ġem', 'oji'] +['Car', 'ousel'] +['-', 'player'] +['Ġadjust', 'ing'] +['Ġjug', 'a'] +['alleng', 'es'] +['g', 'ene'] +['(body', 'Parser'] +['lop', 'edia'] +['ĠBeh', 'ind'] +['Ġslee', 'ves'] +['Ġdrag', 'ging'] +['ĠChe', 'vrolet'] +['Ġb', 'iz'] +['iv', 'ities'] +['ĠFrequ', 'ency'] +[',', 'char'] +['.W', 'HITE'] +['_pre', 'view'] +[')', "';Ċ"] +['_', 'ax'] +['ION', 'S'] +['.c', 'pu'] +['.input', 's'] +['UB', 'E'] +['_fe', 'ed'] +['ĠSup', 'plement'] +['!', ').'] +['es', 'us'] +['ĠU', 'DP'] +['Ġmicro', 'phone'] +['Ġconf', 'irms'] +['.is', 'NotEmpty'] +['":"', '",Ċ'] +['_S', 'CREEN'] +['ĉ', 'expected'] +['+-+-', '+-+-'] +['ĠH', 'ait'] +['fast', 'call'] +['Ġdep', 'ict'] +['v', 'b'] +['_p', 'icture'] +['ĉd', 'escription'] +['ĠW', 'ife'] +['uc', 'i'] +['Ġv', 'icious'] +['ä»', 'ĸ'] +['ue', 'ba'] +['Ġset', 'User'] +['ãģ', '¡'] +['Ġd', 'iving'] +['Ġoper', 'a'] +['user', 'content'] +['ar', 'ah'] +[')', '},'] +['y', 'un'] +['vel', 't'] +['Ġun', 'covered'] +['Ġh', 'ips'] +['Ġosc', 'ill'] +['Ġassert', 'ing'] +['ĠX', 'i'] +['.re', 'store'] +['ke', 'a'] +['Ġsp', 'elling'] +['Ġder', 'ive'] +['ab', 'we'] +['ĠD', 'ow'] +['.set', 'Type'] +['_v', 's'] +['Ġco', 'zy'] +['.c', 'ategories'] +['O', 'rg'] +['_m', 'gr'] +['Ġd', 'ungeon'] +['collection', 'View'] +['ĠBl', 'ank'] +['ac', 'ias'] +['ä', 'ä'] +['_clean', 'up'] +['_ACT', 'IVITY'] +['Ġtri', 'angles'] +['.Menu', 'Item'] +['Ġip', 'hone'] +['ĠW', 'on'] +[']', ']ĊĊ'] +['ĠCompar', 'ison'] +['.D', 'oc'] +['Ġcan', 'onical'] +['ĠSud', 'an'] +["')", '{'] +['Up', 'Inside'] +['b', 'uiltin'] +['ENC', 'Y'] +['x', 'be'] +['Ġch', 'uck'] +['Ġcontrad', 'ict'] +['Ġnuest', 'ro'] +['Ġarchitect', 'ural'] +['ĠF', 'ib'] +['Ġcomp', 'ares'] +['*', 'k'] +['C', 'fg'] +['çĦ', '¡'] +['nt', 'en'] +['Match', 'es'] +['ĠDOWN', 'LOAD'] +['_HAND', 'LER'] +['man', 'agement'] +['[', 'S'] +['EN', 'G'] +['ÂĢ', 'Â'] +['f', 'ang'] +['Ġsl', 'ipped'] +['ĠL', 'anka'] +['esc', 'aping'] +['Ġtack', 'les'] +['ĠPed', 'ro'] +['.P', 'rop'] +[".'", "'"] +['.G', 'enerated'] +['.New', 'Guid'] +['at', 'rigesimal'] +['ill', 'on'] +['Ġstat', 'istic'] +['spec', 'ies'] +['hold', 'ing'] +['Dr', 'upal'] +['Ġfundament', 'ally'] +['Ġbond', 'age'] +['Ġres', 'olutions'] +['Inline', 'Data'] +['\\', 'Type'] +['est', 'ion'] +['.w', 'rap'] +['Ġwar', 'riors'] +['ĠLOC', 'AL'] +['Arch', 'ive'] +['Ġembr', 'aced'] +['á»', '§'] +['.V', 'er'] +['ĠAff', 'ordable'] +['oles', 'ale'] +['ĠAp', 'plied'] +['ĠCon', 'version'] +['m', 'ega'] +['_c', 'am'] +['Ġcer', 'emon'] +['aur', 'us'] +['ĠVol', 'k'] +['.op', 'ens'] +['/', 'about'] +['ĠSt', 'd'] +['j', 'ournal'] +['())', '{čĊ'] +[',"', '\\'] +['(', 'Arrays'] +['ĠD', 'ense'] +['ase', 'ña'] +['än', 'ner'] +['/', 'stat'] +['user', 'Data'] +['Ġg', 'erman'] +['Ġt', 'z'] +['worth', 'y'] +['Format', 'Exception'] +['ph', 'erd'] +['Ġsm', 'iles'] +['ĠWh', 'enever'] +['(', 'adapter'] +['.bad', 'logic'] +['Ġbrief', 'ing'] +['.Grid', 'Column'] +['-', 'char'] +['dim', 'ension'] +['ĠC', 'opper'] +['Ġnin', 'th'] +["Ġ'", '{{'] +['Ġr', 'av'] +['_T', 'able'] +['Ġderiv', 'atives'] +['ĠR', 'aise'] +['ĠF', 'ut'] +['arm', 'or'] +['-p', 'adding'] +['Ġre', 'min'] +['ĉ', 'style'] +['ĠMembers', 'hip'] +['Ġspread', 's'] +['Ġgall', 'eries'] +['ĠClar', 'ke'] +['Ġcon', 'ception'] +['min', 'ute'] +['Ġab', 'usive'] +['_ad', 'j'] +['Ġterr', 'ific'] +['Ġover', 't'] +['our', 'cing'] +['Ġentr', 'ada'] +['level', 's'] +['Ġcrit', 'ique'] +['Ġrespect', 's'] +['ĠM', 'MA'] +['i', 'ene'] +['Ġenc', 'aps'] +['ĠRay', 'mond'] +['Div', 'ider'] +['iv', 'able'] +['b', 'az'] +['Ġ@', '_;Ċ'] +['ĠCl', 'aire'] +['Ġur', 'ging'] +['CE', 'E'] +['Ġtransform', 'er'] +['disc', 'ord'] +['ĠJ', 'ourney'] +['t', 'os'] +['Ġcompet', 'itions'] +['ĠO', 'BJ'] +['ĠB', 'is'] +['Ġrelax', 'ation'] +['id', 'y'] +['_IN', 'STANCE'] +['ĠP', 'ref'] +['d', 'ados'] +['ici', 'encies'] +['ĠMedia', 'Query'] +['ĠC', 'ube'] +['ĠStr', 'ange'] +['g', 'pu'] +['(d', 'ays'] +['_Init', 'Struct'] +['Ġfinger', 'print'] +['em', 'at'] +['ĠGe', 'cko'] +['Ġr', 'ails'] +['ĠL', 'um'] +['str', 'action'] +['ig', 'ung'] +['(m', 'ovie'] +['_d', 'ictionary'] +['_int', 'errupt'] +['ĠQ', 'C'] +['ik', 'ed'] +['append', 'Child'] +['rec', 'ipient'] +['r', 'é'] +['V', 'e'] +['Ġtow', 'el'] +['.last', 'IndexOf'] +['Ġplace', 'bo'] +['ĠW', 'ie'] +['.es', 'p'] +['(', 'Debug'] +['oper', 'ative'] +['Ġdece', 'ased'] +['&', 'id'] +['ĉm', 'utex'] +['el', 'ic'] +['Ġb', 'apt'] +['ĉ', 'čĊčĊ'] +['Ġfar', 'ther'] +['H', 'alf'] +['.dis', 'able'] +['.menu', 'Strip'] +['le', 'ccion'] +['Ġresult', 'Code'] +['Ġc', 'ans'] +['-e', 'lection'] +['f', 'emale'] +['_F', 'IX'] +['aus', 'ible'] +['ĠP', 'OWER'] +['Ġrecon', 'struction'] +['Ġsc', 'ans'] +['.Xtra', 'Bars'] +['âĢĺ', 's'] +['Rem', 'oved'] +['Ġparagraph', 's'] +['_m', 'argin'] +['Ġl', 'ymph'] +['Ġb', 'os'] +['ling', 'ton'] +['ĠBapt', 'ist'] +['Ġadvertis', 'ements'] +['ĠMan', 'age'] +['/', 'yyyy'] +['IO', 'US'] +['ENC', 'ES'] +['ĠF', 'iction'] +['ĉm', 'enu'] +['ĠFile', 'OutputStream'] +['ov', 'an'] +['ĠF', 'eng'] +['Ġsk', 'ipping'] +['get', 'Class'] +['ann', 'i'] +['Ġreb', 'ounds'] +['Ġpublic', 'ity'] +['Ġing', 'res'] +['use', 'ment'] +['Ġthought', 'ful'] +['.Ch', 'art'] +['Ġhat', 'te'] +['pass', 'port'] +['Ġhook', 'ed'] +['ĠL', 'ens'] +['Ġflag', 'ship'] +['Ġst', 'ip'] +['ĠG', 'EN'] +['Ġcl', 'ues'] +['ip', 'v'] +['ĠR', 'ise'] +['ĠG', 'ew'] +['tab', 'lename'] +['Ġfore', 'most'] +['_', 'validate'] +['_an', 'alysis'] +['oll', 'a'] +['Ġqual', 'ifications'] +['Ġdistrib', 'utions'] +['ĠFl', 'ower'] +['Ġt', 'ense'] +['Ġthank', 'ful'] +['Ġcl', 'utch'] +['Ġun', 'ified'] +['ro', 'ads'] +['Ġsit', 'i'] +['Ġst', 'all'] +['_P', 'RIORITY'] +['c', 'stdlib'] +['_USER', 'NAME'] +['.by', 'tes'] +['?', 'page'] +['ermal', 'ink'] +['ĠVe', 'get'] +['/v', 'nd'] +['-', 'author'] +['.N', 'ONE'] +['ĠCon', 'current'] +['ĠC', 'ry'] +['Ġstart', 'ers'] +['ĠInter', 'action'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠ'] +['ĠLE', 'VEL'] +['E', 'll'] +['Ġcom', 'boBox'] +['ĠTh', 'eresa'] +['te', 'k'] +['_H', 'andle'] +['Ġab', 'y'] +['.g', 'dx'] +[',', 'end'] +['(L', 'ocal'] +['O', 'l'] +['kn', 'ife'] +['ar', 'ial'] +['ĠH', 'off'] +['Ġprostituer', 'ade'] +['Do', 'ctor'] +['Inst', 'ances'] +['.Set', 'Value'] +['ĉf', 'rom'] +['Ġlux', 'urious'] +['Ind', 'ent'] +['Alloc', 'ator'] +['_D', 'RAW'] +['(",', '",'] +['ĠFr', 'ances'] +['Ġgroup', 'Box'] +['(s', 'chema'] +['Print', 'f'] +['OR', 'IES'] +['-', 'gradient'] +['Ġre', 'put'] +['ar', 'in'] +['_D', 'ONE'] +['in', 'cre'] +['ig', 'nty'] +['Ġex', 'ert'] +['Ġ-', '.'] +['/', 'App'] +['-th', 'rough'] +['Ġdecl', 'ining'] +['Ġdess', 'ert'] +['Ġinc', 'umb'] +['Ġdesign', 'ation'] +['.P', 'ORT'] +[',', 'strong'] +['Ġsand', 'box'] +['Ġw', 'ines'] +['ĠP', 'av'] +['$', 'str'] +['ask', 'ell'] +['Ġh', 'ö'] +['ĠP', 'Y'] +['Get', 'Instance'] +['Text', 'Input'] +['game', 'Object'] +['/', 'events'] +['created', 'At'] +['Ġlocal', 'Var'] +['ĠWH', 'ITE'] +['per', 'ed'] +['ile', 'ge'] +['eff', 'icient'] +[',', 'color'] +['c', 'ate'] +['ĠC', 'afe'] +['Ġsimilar', 'ities'] +['Ġp', 'umps'] +['ĠHung', 'ary'] +['.User', 'name'] +['Ġsk', 'ate'] +['Ġtouchdown', 's'] +['Ġacceler', 'ate'] +['ĠH', 'elen'] +['OM', 'EM'] +['ĠK', 'un'] +['_v', 'ol'] +['Ġfind', 'All'] +['ĠMens', 'chen'] +['a', 'head'] +[');', '"'] +['kom', 'men'] +['Ġpossess', 'ed'] +['.arg', 'max'] +['.trans', 'ition'] +['AR', 'P'] +['OLUM', 'E'] +['(s', 'cript'] +['ĠÐ', 'ĺ'] +['ĠF', 'inding'] +['on', 'ces'] +['I', 'o'] +['B', 'old'] +['Ġrenew', 'al'] +['_D', 'IALOG'] +['Ġdis', 'reg'] +['INT', 'ERN'] +['Ġt', 'oute'] +['Ġelect', 'r'] +['ĠG', 'ross'] +['ĉ', 'true'] +['.F', 'ields'] +['ĠW', 'IDTH'] +['ĠD', 'ent'] +['ĠÃ', 'ģ'] +['NS', 'Notification'] +['Ġa', 'os'] +['Ġme', 'lee'] +['.', 'Validation'] +['ĠDE', 'C'] +['-depend', 'ent'] +['Ġsu', 'ic'] +['T', 'raits'] +['$', 'message'] +['ĠD', 'ear'] +['ĉ', 'FILE'] +['l', 'anguages'] +['.P', 'rot'] +['.add', 'r'] +['-g', 'eneration'] +['IC', 'ON'] +['Ġtrans', 'plant'] +['-d', 'escription'] +['Ġch', 'asing'] +['Ġche', 'es'] +['Ġ}', '*/Ċ'] +['Tr', 'ad'] +['qu', 'eries'] +['/widget', 's'] +['sub', 'package'] +['Ġes', 'pec'] +['Ġcr', 'acked'] +['Ġcompet', 'itor'] +['P', 'urchase'] +['-', 'team'] +['olec', 'ular'] +['or', 'Thunk'] +['&', 'P'] +['Ġrel', 'ent'] +['/', '#{'] +['Ġproduct', 'Id'] +['Ġè', '¾'] +['ĠL', 'av'] +['ĠAl', 'ter'] +['.M', 'ode'] +['AD', 'IO'] +['gr', 'p'] +['æ', '·»åĬł'] +['Qu', 'it'] +['Ġdepth', 's'] +['-c', 'ategory'] +['ĠD', 'ATABASE'] +['S', 'PELL'] +['ĠFal', 'con'] +['ĠQString', 'List'] +["Ġ''", '.'] +['ĠIn', 'stitution'] +['d', 'amage'] +['az', 'or'] +['bel', 'ongsTo'] +['ver', 'ages'] +['ĠN', 'ONE'] +['ipp', 'ets'] +[',', '\\Ċ'] +['Ġfoot', 'print'] +['_', 'archive'] +['n', 'ak'] +['.get', 'Field'] +['ĠRef', 'lection'] +["Ġ'", ']'] +['ĠH', 'BO'] +['_dis', 'count'] +['Ġin', 'cest'] +['ĠD', 'odge'] +['ĠW', 'ade'] +['.N', 'O'] +['"', 'encoding'] +['ĠBlock', 'chain'] +['Ġlaws', 'uits'] +['ĠM', 'aint'] +['ch', 'ten'] +['Ġét', 'ait'] +['Ġktó', 're'] +['_', 'ctl'] +['(t', 'imer'] +['B', 'attle'] +['iz', 'o'] +['ay', 'ed'] +['I', 'OR'] +['ĠGlas', 'gow'] +['Ġsyn', 'th'] +['_log', 's'] +['.p', 'ose'] +['_Adjust', 'orThunk'] +['((', '&'] +['Ġuns', 'ure'] +['yst', 'ate'] +['íķĺ', 'ëĬĶ'] +['O', 'ULD'] +['.', 'ng'] +['Ġdefault', 'dict'] +['work', 'space'] +['Ġselect', 'ive'] +['Picker', 'Controller'] +['YNAM', 'IC'] +['.method', 's'] +['Ġpath', 'ways'] +['ĠF', 'ew'] +['K', 'G'] +['CRY', 'PT'] +['follow', 'ing'] +['ĠD', 'LC'] +['ĠS', 'ara'] +['Ġpres', 'et'] +['estruct', 'or'] +['ĠK', 'urt'] +['Ġair', 'plane'] +['Ġo', 'mp'] +['ĠParent', 's'] +['ĠMart', 'inez'] +['.com', 'plete'] +['Ġbroad', 'ly'] +['Ġsc', 'are'] +['ĠM', 'é'] +['Ġelim', 'ination'] +['Ġpou', 'red'] +['/', 'sw'] +['Ġcom', 'un'] +['Ġm', 'asc'] +['ĠOrgan', 'ic'] +['ĠString', 'Utils'] +['il', 'ateral'] +['Ġreluct', 'ant'] +['-', 'age'] +['Ġn', 'z'] +['."', '\\'] +['Ġpast', 'or'] +['ale', 'z'] +['Ġe', 'fect'] +['pro', 'v'] +['/', 'init'] +['Ġp', 'enn'] +['und', 's'] +['Ġs', 'size'] +['ĠPro', 'j'] +['bas', 'ename'] +['Ġsh', 'ells'] +['ĠNe', 'ck'] +['ĠEn', 'forcement'] +['vid', 'ed'] +['st', 'own'] +['S', 'phere'] +['$', 'r'] +['uss', 'en'] +['af', 'il'] +['ĠTele', 'gram'] +['Ġanaly', 'tical'] +['нÑĭ', 'е'] +['us', 'ually'] +['x', 'n'] +['Ġhistor', 'ian'] +['ĠGreg', 'ory'] +['ol', 'ph'] +['ĠUn', 'a'] +['Ġcon', 'tributes'] +['%', '-'] +['anti', 'ago'] +['ÑĢ', 'ед'] +['.reg', 'ion'] +['Ġab', 'rupt'] +['ĠUnsupported', 'OperationException'] +['ĠT', 'ASK'] +['_f', 'inish'] +['Ġnot', 'orious'] +['ĠV', 's'] +['ĠM', 'Q'] +['Ġsun', 'set'] +['Ġun', 'acceptable'] +['ar', 'cer'] +['Ġill', 'umin'] +['ĠOr', 'b'] +['Ġb', 'h'] +['E', 'ste'] +['_dis', 'patch'] +['Ġr', 'ipped'] +['Ġtou', 'jours'] +['ĠPar', 'cel'] +['_', 'll'] +['.user', 'Name'] +['.class', 'es'] +['S', 'OURCE'] +['(', 'Number'] +['ел', 'Ñı'] +['Ġhead', 'phones'] +['(s', 'ide'] +['const', 'itution'] +['ann', 'ah'] +['čĊ', 'ĠĠĠĠĠĠĠĠčĊ'] +['Ġcl', 'iff'] +['-', 'ref'] +['Ġmo', 'strar'] +['ĠPow', 'ell'] +['+', 'y'] +['ĠB', 'G'] +['_f', 'ragment'] +['.P', 'ort'] +['Ġreal', 'izing'] +['param', 'ref'] +['Ġh', 'ometown'] +['@', 'Table'] +['+"', '', '--}}Ċ'] +['F', 'rench'] +['Entity', 'Manager'] +['ĠPl', 'ain'] +['////////////////////////////////////////////////////////////////', '////'] +['Â', '³'] +['(', 'RE'] +['c', 'apt'] +['Ġorgan', 'isms'] +['Ġj', 'ets'] +['ol', 'ocation'] +['ĠApp', 'RoutingModule'] +['Ġgl', 'orious'] +['æľ', 'į'] +['Ġdisc', 'arded'] +['ĉĉĉĉ', 'ĠĠĠĠĠ'] +['ĠArn', 'old'] +['l', 'ug'] +['Ġpar', 'l'] +['Ġhorm', 'ones'] +['Ġm', 'ah'] +['ĠSon', 'ic'] +['Ġorgan', 'izers'] +['_PL', 'ATFORM'] +['.in', 'v'] +['Ġch', 'ord'] +['vent', 'ional'] +['ĉ', 'of'] +['Ep', 'isode'] +['.', 'Enum'] +['unk', 't'] +['ĠD', 'h'] +['ĠJ', 'ared'] +['ĠN', 'ak'] +['Ġint', 'ends'] +['End', 'ian'] +['Ġa', 'ustralia'] +['_c', 'v'] +['(res', 'olve'] +['Ġclin', 'ics'] +['lik', 'ed'] +['ASH', 'INGTON'] +['in', 'ha'] +["'", '*'] +['ĠN', 'P'] +['_b', 'eh'] +['Ġh', 'f'] +['Ġw', 'ür'] +['c', 'ategoria'] +['$', 'form'] +['Ġsub', 'way'] +['Ġis', 'Active'] +['pop', 'ular'] +['C', 'our'] +['Ġco', 'oldown'] +['Ġa', 'insi'] +['ĠGL', 'uint'] +['ere', 'al'] +['Ġarray', 'Of'] +['Ġh', 'atch'] +['========', '=='] +['ress', 'es'] +['_P', 'P'] +['.', '^'] +['_dec', 'ay'] +['ĠB', 'less'] +['met', 'rics'] +['ĠCOPY', 'ING'] +['ĠDump', 'ster'] +['ĠJos', 'é'] +['ĠDesign', 's'] +['<'] +['Ġ"', '}Ċ'] +['time', 'zone'] +['Ġe', 'er'] +['max', 'cdn'] +['ĠE', 'SC'] +['ig', 'aret'] +['_conn', 'ected'] +['_re', 'verse'] +['Ġquestion', 'able'] +['ĠUS', 'C'] +['Ġtut', 'ti'] +['Ġdrop', 'out'] +['ĠActiv', 'ities'] +['ĠW', 'inds'] +["'))", ');Ċ'] +['Ġcon', 'gest'] +['ÄŁ', 'ı'] +['Ġprolong', 'ed'] +['è¿', 'Ļ'] +['ĠCross', 'AxisAlignment'] +['LE', 'EP'] +['ĠVAL', 'ID'] +['ĠG', 'az'] +['Ġdepend', 'ence'] +['ĠP', 'rix'] +['.Compiler', 'Services'] +['j', 'ump'] +['Ġstr', 'at'] +['c', 'irc'] +['ĠC', 'USTOM'] +['x', 'aa'] +['Ġb', 'mp'] +['Ġb', 'ureau'] +['Ġw', 'aren'] +['N', 'X'] +['(', 'Window'] +['ĠChrist', 'ie'] +['_F', 'E'] +['Ġt', 'n'] +['ĠOm', 'ega'] +['communic', 'ations'] +['Home', 'Page'] +['com', 'pletion'] +['Ġsupply', 'ing'] +['YP', 'ES'] +['á', 'vel'] +['åĪ', '¶'] +['(c', 'lick'] +['\\', 'Contracts'] +['/', 'questions'] +['Ġe', 'z'] +['AM', 'S'] +['.m', 'esh'] +["Ġ'", '', '\\Ċ'] +['Rob', 'ot'] +['Json', 'Object'] +['ĠD', 'F'] +['ĠProcess', 'or'] +['_sh', 'ould'] +['.prot', 'obuf'] +['-', 'users'] +['Ġemb', 'ry'] +['F', 'ONT'] +['Ġstart', 'ups'] +['ĠData', 'Source'] +[')', '#'] +['uro', 's'] +['_C', 'olor'] +['Ġstand', 'alone'] +['}', '['] +['j', 'd'] +['Ġforg', 'ive'] +['Ġng', 'x'] +['ĠGener', 'ally'] +['Ġconfig', 'urable'] +['/', 'order'] +['Ġv', 'as'] +["')", '";Ċ'] +['ĠR', 'R'] +['ĠT', 'roy'] +['Ġcomprom', 'ised'] +['ĠSw', 'an'] +['int', 'endent'] +['Cent', 'ral'] +['_', 'keeper'] +['Ġar', 'quivo'] +['ĠRead', 'Only'] +['_cur', 've'] +['k', 'v'] +['ent', 'in'] +['è', '±'] +['ĠE', 'y'] +['.im', 'read'] +['ĠP', 'am'] +['if', 'fe'] +['at', 'ivity'] +['xb', 'c'] +['Ġgr', 'im'] +['-f', 'illed'] +['names', 'e'] +["']", ':'] +['Ġa', 'ur'] +['ĠGib', 'son'] +['.Mouse', 'Event'] +['Ġl', 'ado'] +['avad', 'oc'] +['Ġfam', 'il'] +['ĠM', 'oder'] +['f', 'ps'] +['ãĢĢ', 'ãĢĢ'] +['-', 'example'] +['ĠAl', 'zheimer'] +['ĠU', 'tf'] +['_arg', 'uments'] +['Con', 'clusion'] +['text', 'Content'] +['rem', 'aining'] +['Ġinterrupt', 's'] +['ĠBack', 'up'] +['ĠM', 'ong'] +['Ġrecept', 'ors'] +['h', 'istor'] +['.cor', 'outines'] +['Ġsh', 'outed'] +['Al', 'arm'] +['Ġcomb', 'ust'] +['Ġg', 'rote'] +['ult', 'ural'] +['(', 'ids'] +['----------------------------------------------------------------', '----------------'] +['ipl', 'inary'] +['O', 'pts'] +['ĠY', 'ale'] +['local', 'Storage'] +['Ġequ', 'ival'] +['ĠF', 'leet'] +['\\', 'b'] +['*', 'pi'] +['ĠQ', 'Label'] +['æ', '¡'] +['Ġv', 'x'] +['ĠA', 'CL'] +['Ġsu', 'cesso'] +['Ġper', 'c'] +['ĠNot', 're'] +['Ġan', 'arch'] +['R', 'ing'] +['sp', 'b'] +['Ġstr', 'pos'] +['st', 'ores'] +['ĠMap', 'le'] +['(Main', 'Activity'] +['("', '"))'] +['Ġview', 'Holder'] +['Qu', 'ad'] +['Ġig', 'ual'] +['ors', 'che'] +['.m', 'argin'] +['Ġind', 'ie'] +['Ġfr', 'anc'] +['ĠForm', 'Builder'] +['ĠPart', 'icip'] +['.fl', 'ash'] +['Ġstorm', 's'] +['U', 'lt'] +['Ġf', 'en'] +['[', 'new'] +['E', 'ver'] +['="', 'Ċ'] +['Ġlocal', 'ized'] +['_f', 'ollow'] +['Ġn', 'ave'] +['Ġdomin', 'ance'] +['(t', 'ile'] +['J', 'ournal'] +['ĠV', 'C'] +['Ġpenet', 'ration'] +['ï¼', 'ķ'] +['Ġcomp', 'artment'] +['Ġb', 'ids'] +['Form', 'atted'] +['******', '/ĊĊ'] +['(c', 'ity'] +['âĢĶ', 'it'] +['[', 'C'] +['Ġuse', 'Callback'] +['a', 'ub'] +[')', '?.'] +['ĠV', 'AR'] +['ĠSe', 'bastian'] +['ĠM', 'oss'] +['Ġabund', 'ant'] +['G', 'reg'] +['ÑĤ', 'а'] +['_c', 'i'] +['Ġbib', 'li'] +['CR', 'M'] +['ĠAt', 'tempt'] +['ism', 'e'] +['d', 'ash'] +['ãĢ', 'İ'] +['_m', 'u'] +['.Formatting', 'Enabled'] +['Ind', 'eed'] +['-d', 'irect'] +['Ġsuck', 'ing'] +['Ġp', 'ne'] +['ocab', 'ulary'] +['ĠPack', 'ers'] +['.N', 'avigation'] +['Ġp', 'ied'] +['cri', 'bing'] +['ĠSt', 'uart'] +['.To', 'Double'] +['ĠSecond', 'ary'] +['S', 'aving'] +['ĠD', 'ut'] +['ĠM', 'add'] +['M', 'agic'] +[',', 'H'] +['.document', 'Element'] +['ĠB', 'ST'] +['Ġdiff', 'ers'] +['Ġmore', 'over'] +['_', 'nd'] +['SE', 'ARCH'] +['п', 'ÑĢав'] +['æ', '´'] +['to', 'Match'] +['Ġdecre', 'asing'] +['-m', 'ember'] +['amp', 'us'] +['(', 'boost'] +['D', 'aily'] +['Data', 'GridView'] +['ĠHttp', 'Context'] +['Ġh', 'ipp'] +['_work', 'ers'] +['-l', 'anguage'] +['é', 'ĵ'] +['Ġconsist', 'ed'] +['ath', 'ing'] +['ĠMer', 'cury'] +['$', 'content'] +['Ġpract', 'iced'] +['ĠMod', 'ules'] +['_D', 'AY'] +['Ġweakness', 'es'] +['ĠL', 'odge'] +['Ġn', 'ar'] +['ĠM', 'ate'] +['Ġj', 'p'] +['ĠHttp', 'Headers'] +['Ġsm', 'o'] +['ĠT', 'OKEN'] +[']', ')('] +['Ġaqu', 'i'] +['sw', 'agen'] +['Ġs', 'rv'] +['ĉ', 'ans'] +['A', 'round'] +['ĠMan', 'uel'] +['Ġfiction', 'al'] +['ĠIM', 'G'] +['Ġ.', "'"] +['ĠB', 'erry'] +['Ġwall', 'paper'] +['sex', 'ual'] +['ier', 'o'] +['Ġ', 'çļĦ'] +['ìĨ', 'Į'] +['Backing', 'Field'] +['ĠAd', 'rian'] +['BASE', 'PATH'] +['Ġrepe', 'ats'] +['Ġbl', 'ues'] +['Ġunp', 'redict'] +['_c', 'oll'] +['st', 'acle'] +['ĠT', 'umblr'] +['ĠEl', 'f'] +['Ġass', 'urance'] +['Ġc', 'ensus'] +['ĠIM', 'PORT'] +['END', 'ER'] +['an', 'os'] +['Ġ=', '('] +['ĠEll', 'is'] +['"', 'ĊĊĊĊ'] +['.w', 'in'] +['ĠA', 'bove'] +['al', 'on'] +['_t', 'ick'] +['Ġrepresent', 'ations'] +['Ġæ', 'ķ'] +['w', 'id'] +['ĠAr', 'ms'] +['List', 'a'] +['_f', 'ailure'] +['_c', 'm'] +['.Flat', 'Appearance'] +['Ġthr', 'one'] +['P', 'atch'] +['ĠV', 'oy'] +['eng', 'l'] +['Ġnegot', 'iating'] +['>', '`'] +['Ġshoot', 's'] +['ĠF', 'PS'] +['.Y', 'ear'] +['ĠK', 'iss'] +['enc', 'ión'] +['reet', 'ing'] +['From', 'File'] +['Ġresign', 'ation'] +['Ø', '·'] +['Ġtw', 'ins'] +['ưá»', '£'] +['Ġge', 'bru'] +['.get', 'Content'] +['.T', 'ree'] +['ĠEmploy', 'ees'] +['ĠF', 'IFA'] +['Ġcert', 'ainty'] +['(C', 'l'] +['Ġtot', 'als'] +['edit', 'able'] +['à¥', 'Ģ'] +['.Report', 'ing'] +['M', 'as'] +['qu', 'iet'] +['.r', 'ules'] +['ĠV', 'O'] +['con', 'exion'] +[',', 'K'] +['Ġalloc', 'ator'] +['ĠPow', 'der'] +['\\', 'Repository'] +['Be', 'at'] +['_t', 'ipo'] +["Ġ['", "',"] +['_IN', 'TR'] +['Ġ<<', '<'] +['<', 'hr'] +['")', '=='] +['ugg', 'age'] +['ĠC', 'raw'] +['Ġé', 'galement'] +['Ġg', 'inger'] +['Ġprim', 'era'] +['Ġprod', 'uto'] +['lt', 'k'] +['.User', 'Name'] +['Ġstr', 'error'] +['m', 'ith'] +['_n', 'b'] +['Ġdis', 'comfort'] +["'];", '?>', '");čĊ'] +['drop', 'IfExists'] +['ĠB', 'eg'] +['_H', 'AL'] +['Ġcross', 'AxisAlignment'] +['ĠE', 'vidence'] +['Ġpec', 'uliar'] +['Ġinstit', 'ute'] +['ve', 'is'] +['Ġf', 'ft'] +['Ã', 'ģ'] +['Ġzo', 'ekt'] +['an', 'aly'] +['ĠHom', 'eland'] +['Ġpen', 'etr'] +['udden', 'ly'] +['ĉ', 'element'] +['ĠB', 'ren'] +['ĠTr', 'udeau'] +['ĠCub', 'an'] +['j', 'am'] +['us', 'lim'] +['_e', 'v'] +['Ġst', 'ems'] +['}', '%'] +['Ŀ', 'å§ĭ'] +['Ġbrand', 'ing'] +['Ġcorrespond', 'ence'] +['.j', 'query'] +['¢', 'åįķ'] +['ĠRead', 's'] +['(Http', 'StatusCode'] +['ass', 'in'] +['(s', 'lot'] +['ĠGrad', 'uate'] +['///', '<'] +['Ġinform', 'ations'] +['EN', 'ABLE'] +['Ġp', 'uis'] +['Ġfind', 'er'] +['ĠBr', 'is'] +['Ġnett', 'steder'] +['_m', 'id'] +['Ġo', 'gs'] +['ĠSter', 'ling'] +['Ġar', 'rog'] +['str', 'ftime'] +['|', 'ĊĊ'] +['Ġvo', 'x'] +['ĠReg', 'ardless'] +['Ġes', 'o'] +['ĠCom', 'fort'] +['.Boolean', 'Field'] +['Ġu', 'h'] +['AC', 'Y'] +['Ġsque', 'ez'] +['ĠV', 'ic'] +['cont', 'ro'] +['.', 'lo'] +['Ġ', 'ire'] +['ĠCom', 'edy'] +['ë', '¶'] +['Ġorigin', 'ated'] +['Ġsh', 'ipment'] +['|', 'max'] +['_g', 'uid'] +['lev', 'ation'] +['на', 'Ñı'] +['(', 'undefined'] +['ĠD', 'DR'] +['Ġshoot', 'ings'] +['ĠLat', 'ino'] +['END', 'OR'] +['Ġaver', 'aging'] +['Ġgre', 'eted'] +['Ġthe', 'aters'] +['о', 'е'] +['Ġd', 'B'] +['Ġg', 'st'] +['Ġdef', 'inite'] +['.', 'Storage'] +['.h', 'er'] +['Ġa', 'fore'] +['ĠRe', 'ality'] +['ĠGod', 's'] +['vers', 'ed'] +['Ġhands', 'ome'] +['Ġex', 'cluding'] +['(', 'ad'] +['Qu', 'otes'] +['ĠS', 'cheme'] +['?', 'q'] +['ĠT', 'amil'] +['T', 'icks'] +['Ġp', 'est'] +["'", 'n'] +['Ġporn', 'ography'] +['_mod', 'al'] +['Ġ', '----------'] +['Ġdis', 'posable'] +['F', 'REE'] +['Ġsh', 'ark'] +['C', 'HE'] +['Ġdep', 'icted'] +['Ġdemonstr', 'ations'] +['ĠK', 'illed'] +['ĠR', 'ULE'] +['Ġobs', 'essed'] +['Ġsimpl', 'ified'] +['Post', 'al'] +['Ġconcept', 'ual'] +['Ġp', 'st'] +['L', 'as'] +['_PRO', 'JECT'] +['ucceed', 'ed'] +['ol', 'u'] +['ÄŁ', 'i'] +['Ġpersonal', 'ities'] +['Ġres', 'hape'] +['Ġenc', 'losed'] +['ĉp', 'tr'] +['Ġtutor', 'ials'] +['Ġexpl', 'oded'] +['_DIRECT', 'ORY'] +['åĨħ', '容'] +['Ġcan', 'on'] +['Ġrecogn', 'ise'] +['P', 'AD'] +['ĠAppro', 'x'] +['ĠRest', 'ore'] +['ĠImport', 'ant'] +['Ġheav', 'ier'] +['.Se', 'quential'] +['Ear', 'th'] +['ĠMil', 'k'] +['.set', 'Request'] +['.t', 'em'] +['Ġre', 'construct'] +['Ġskept', 'ical'] +['_Pr', 'ivate'] +['BU', 'F'] +['qu', 'a'] +[':', 'a'] +['Ġse', 'k'] +['Ġd', 'well'] +['oss', 'a'] +['Ġreward', 'ed'] +['и', 'й'] +['(top', 'ic'] +['_part', 'ition'] +['Ġ__', '________________'] +['Key', 'words'] +['ĠFr', 'anco'] +['L', 'ite'] +['Ġn', 'aken'] +['Ġз', 'а'] +['O', 'BJECT'] +['Ġcraft', 's'] +['ĠSw', 'ap'] +['.X', 'na'] +['.Con', 'nect'] +['Ġbalcon', 'y'] +['(re', 'al'] +['ĠBarn', 'es'] +['b', 'ir'] +['ĠTw', 'enty'] +['ay', 'an'] +['at', 'ars'] +['ĠProp', 'el'] +['ĠIh', 'nen'] +['Up', 'grade'] +['Ġcur', 'b'] +['-', 'second'] +['Ġn', 'eph'] +['.p', 'res'] +['ìŀ', 'ħ'] +['.se', 'q'] +['Ġp', 'added'] +['"', '?'] +['j', 'l'] +['ãĥ', '¬'] +["')", '', 'a'] +['Co', 'ordinates'] +['Ġen', 'acted'] +['ENT', 'S'] +['Ġl', 'ac'] +['.f', 'inal'] +['ĠPhp', 'Storm'] +['c', 'alled'] +['Ġin', 'quiries'] +['.m', 'iddleware'] +['ĠD', 'owntown'] +['/', "';Ċ"] +['Ġkil', 'omet'] +['ac', 'cel'] +['Ġqu', 'ien'] +['w', 'string'] +['set', 'Data'] +['Ġman', 'era'] +['Ġmod', 'ular'] +['rim', 'p'] +['Ġtar', 'iffs'] +['âĢĻ', 'il'] +['_TH', 'ROW'] +['/c', 'olor'] +['ĠHT', 'MLElement'] +['Ġcar', 'ro'] +['Ġpr', 'ere'] +['Ġplot', 'ting'] +['ĠPos', 'itive'] +['ĠMach', 'ines'] +['OT', 'ES'] +['á»', 'Ľ'] +['ple', 'asant'] +['Ġal', 'te'] +['Ġa', 'inda'] +['th', 'ese'] +['Ġc', 'ors'] +['ip', 'ay'] +['ĠAdvis', 'ory'] +['ĠRub', 'io'] +['j', 'q'] +['Ġl', 'imestone'] +['Ġdet', 'ached'] +['设', 'ç½®'] +['ten', 'ant'] +['ĠDep', 'th'] +['al', 'ore'] +['ĠÑģÑĤÑĢ', 'ок'] +['ĠF', 'ORE'] +['ĠL', 'ay'] +['p', 'resentation'] +[')', "');Ċ"] +['.sub', 'plots'] +['Ï', 'ĥ'] +['N', 'OW'] +['G', 'ar'] +['hand', 'les'] +['ab', 'ra'] +['put', 'ies'] +['ĠElect', 'rical'] +['M', 'iddle'] +['rop', 'ic'] +['ĠJ', 'D'] +['ĠD', 'yn'] +['ĠB', 'ristol'] +['ĠMc', 'Carthy'] +['Ġstri', 'ker'] +['Ġenumer', 'able'] +['ĠEv', 'an'] +['.default', 's'] +['qu', 'ences'] +[')', '||'] +['ĉt', 'oken'] +['â', 'Ĺı'] +['-d', 'ropdown'] +['ST', 'ORE'] +['ĠGraph', 'ic'] +['(', 'pp'] +['Ex', 'pl'] +['Ġup', 'wards'] +['ĠD', 'istributed'] +['ĠW', 'EB'] +['J', 'er'] +['is', 'NaN'] +['çĶŁ', 'æĪIJ'] +['>', 'R'] +['üss', 'en'] +['ef', 's'] +['Ġun', 'cover'] +['Ġl', 'ud'] +['.cal', 'culate'] +['Ġint', 'ptr'] +['Ġmidfield', 'er'] +['.', 'Headers'] +['Ġm', 'f'] +['ere', 'f'] +['.M', 'etro'] +['ĠSpe', 'aking'] +[':', 'b'] +['Ġcryptoc', 'urrencies'] +['Ġdem', 'ons'] +['ĉ', 'EXPECT'] +['Ġw', 'icked'] +['y', 'outube'] +[':', 'Int'] +['ĠHind', 'i'] +['ĠC', 'AT'] +['ĠØ', '¹'] +['r', 'ar'] +['om', 'ore'] +['/', 'per'] +['/lic', 'ense'] +['Ġre', 'im'] +['Ġawait', 'ing'] +['Ġle', 'thal'] +['ĠE', 'F'] +['round', 'ed'] +['ĠPl', 'atinum'] +['ĠвÑģ', 'е'] +['.co', 'ords'] +['.De', 'vice'] +['/', 'item'] +['ĠW', 'enn'] +['compile', 'Components'] +['ĠK', 'inder'] +['.remove', 'Item'] +['Ġand', 'a'] +['bn', 'b'] +['Ġpr', 'a'] +['(', 'transaction'] +['Ġembarrass', 'ing'] +['ĉ', 'BOOL'] +['.content', 'View'] +['Ġevent', 'data'] +['at', 'ore'] +['Ġprovided', 'In'] +['ir', 'ma'] +['Ġz', 'ona'] +['_H', 'W'] +['æ', 'Ļ'] +['Ġst', 'ove'] +['Ġcounter', 'part'] +['_Pro', 'duct'] +['_MAN', 'AGER'] +['Ġinfr', 'ing'] +['ĠE', 'RA'] +['_p', 'arty'] +['Ñ', 'ij'] +['Ġin', 'ici'] +['_', 'Request'] +['Ġmir', 'acle'] +['Ġcancel', 'Button'] +['S', 'py'] +['at', 'ó'] +['Ġpol', 'ish'] +['ĠNic', 'ole'] +['.display', 'Name'] +['\\Request', 's'] +['Ġuse', 'History'] +['Router', 'Module'] +['Ġst', 'ared'] +['ID', 'ER'] +['Ñĥнк', 'ÑĨи'] +['Ġnot', 'a'] +['$', 'arr'] +['pec', 'ified'] +['Ġto', 'pp'] +['_DR', 'IVER'] +['/', 'ng'] +['å', 'ł'] +['_t', 'm'] +['%', 'timeout'] +['<', 's'] +['Ġ(', '*)'] +['ĠHttp', 'Request'] +['_TR', 'ACK'] +['(n', 'ote'] +['ĠExp', 'lore'] +['_s', 'erv'] +['Ġç', '»'] +['B', 'inder'] +['+', '",'] +['.', 'att'] +['ĠEth', 'i'] +['Ġc', 'ódigo'] +["='", '\\'] +['.l', 'ines'] +['(', 'Of'] +['å°', 'Ĩ'] +['miss', 'ible'] +['Ġv', 'é'] +['Ġac', 'oustic'] +['Ġcraft', 'ing'] +['n', 'it'] +['.b', 'a'] +['ĠLuc', 'y'] +['Ġi', 'Pod'] +['Ġpup', 'ils'] +['-m', 'ax'] +['_w', 'r'] +['(c', 'p'] +['ĠRE', 'PORT'] +['Ġd', 'ns'] +['ĠRe', 'ferences'] +['Ġundert', 'aken'] +['Ġkø', 'benhavn'] +['Ġch', 'ai'] +['ĠC', 'roat'] +['_', 'Log'] +['rown', 'ed'] +['_m', 'ed'] +['ĉ', 'date'] +['#', '__'] +['Ġcost', 'umes'] +['ĠRe', 'quires'] +['aff', 'le'] +['ç', 'Ĭ¶æĢģ'] +['-S', 'emit'] +['ela', 'ide'] +['еÑĤ', 'од'] +['Ġp', 'estic'] +['Ġd', 'ra'] +['DOC', 'UMENT'] +['Ġ...', 'čĊ'] +['}`', '}Ċ'] +['ĠA', 'uction'] +['ĠD', 'ock'] +['xxxx', 'xxxx'] +['(get', 'String'] +['ħ', 'į'] +['Ġborder', 'Width'] +['ĠMach', 'inery'] +['Ġpredict', 'able'] +['.S', 'H'] +['Ġam', 'plitude'] +['.for', 'Root'] +['IN', 'avigation'] +['Table', 'Model'] +['at', 'trib'] +['Ġmaneu', 'ver'] +['Ġexc', 'av'] +['B', 'ERS'] +['Ġd', 'apat'] +['Ġinstall', 'ations'] +['.A', 'sync'] +['Ġr', 'ays'] +['=', 'âĢĿ'] +[';', 'ččĊ'] +['.c', 'rypto'] +['_db', 'g'] +['ĠEnum', 'erable'] +['Of', 'Size'] +['_epoch', 's'] +['m', 'w'] +['M', 'ENU'] +['out', 'line'] +['ĠP', 'apers'] +['============', 'Ċ'] +['Ġuniform', 's'] +['ĠG', 'ig'] +['-', 'package'] +['ĠJen', 'kins'] +['ĠHome', 'Page'] +['.is', 'Selected'] +['Ġmechan', 'ic'] +['M', 'K'] +['ĠS', 'ounds'] +['//----------------------------------------------------------------------------', '-Ċ'] +['Ġresearch', 'ing'] +['Ġinf', 'os'] +['ograph', 'ics'] +['ers', 'et'] +["(['", '/'] +['ĠTim', 'ber'] +['.', 'agent'] +['.to', 'JSON'] +['_command', 's'] +['par', 'ing'] +['_ad', 'just'] +['.n', 'ome'] +['(g', 'lm'] +['Status', 'Bar'] +['file', 'path'] +['?', 'âĢĻ'] +['Ġdetect', 'ive'] +['Ġunser', 'er'] +['ĠTib', 'et'] +['EN', 'DED'] +['(se', 'ed'] +['Ġsne', 'ak'] +['Ġam', 'or'] +['="', '//'] +['ĠPan', 'thers'] +['all', 'ax'] +['ĠL', 'IVE'] +['ĉD', 'WORD'] +[']=', '-'] +['Ġtorn', 'ado'] +['/', 'min'] +['Ġlung', 's'] +['-c', 'urrent'] +['ĠBook', 'ing'] +['åĪĹ', '表'] +['Ġenjoy', 'ment'] +['à¤', '°'] +['J', 'A'] +['typ', 'ed'] +['.B', 'tn'] +['f', 'at'] +['ug', 'al'] +['ĠSh', 'ares'] +['Ġdis', 'gr'] +['ĠB', 'AR'] +['ĠFO', 'X'] +['Op', 'code'] +['ĠS', 'z'] +['key', 'down'] +['iction', 'aries'] +['Ġdetail', 'ing'] +['}', '))Ċ'] +['Ġp', 'ok'] +['Ġdemonstr', 'ating'] +['Ġnot', 'ation'] +['l', 'ayers'] +['@', 'if'] +['ĠN', 'PR'] +['.strict', 'Equal'] +['ĠRec', 'ipes'] +['.T', 'ensor'] +['Ġliqu', 'or'] +['Ġdeb', 'ts'] +['.ends', 'With'] +['W', 'heel'] +['.P', 'os'] +['CS', 'V'] +['$', 'arity'] +['Ġun', 'stable'] +['(', 'loss'] +['ENS', 'OR'] +['Ġele', 'ven'] +['ĠL', 'opez'] +['ĠHop', 'kins'] +['con', 'om'] +['ĠS', 'eth'] +['Ġpo', 'ems'] +['Qu', 'ant'] +['Ġg', 'sl'] +['Ġsy', 'rup'] +['Ġs', 'ibling'] +['Ġc', 'ass'] +['-v', 'ous'] +['ö', 't'] +['_P', 'ATTERN'] +['_SE', 'CTION'] +['est', 'imated'] +['up', 'grade'] +['.m', 'ongodb'] +['ĠBo', 'at'] +['_C', 'TX'] +['Ġfetch', 'ing'] +['ust', 'in'] +['pi', 'el'] +['M', 'arg'] +['Ref', 'lection'] +['Ġd', 'uct'] +['ĠMunicip', 'al'] +['Ġb', 'x'] +['.Get', 'Current'] +['ml', 'ink'] +['ĠAccount', 'ing'] +['ĠGene', 'va'] +['_P', 'os'] +['Ġpass', 'er'] +['Ġhear', 'ings'] +['com', 'pan'] +['Ġfrag', 'ile'] +['Initial', 'izer'] +['walk', 'er'] +['.M', 'aterial'] +['ĠHun', 'ting'] +['trys', 'ide'] +['Ġk', 'at'] +['Ġcl', 'erk'] +['á', 'Ł'] +['do', 'ing'] +['ĉg', 'roup'] +['Ġsan', 'ction'] +['.l', 'b'] +['ĠL', 'azy'] +['ĠCon', 'straint'] +['P', 'agination'] +['Ġpou', 'vez'] +['ĠInd', 'icates'] +['M', 'ER'] +['Ġcour', 's'] +['Ġyear', 'ly'] +['Ġgros', 'se'] +['abb', 'rev'] +['ĠD', 'ON'] +['Ġproceed', 'ed'] +['ent', 'lich'] +['Ġproperty', 'Name'] +['ĠTe', 'aching'] +['st', 'adt'] +['Ġc', 'utoff'] +['orn', 'ers'] +['Ġa', 'frica'] +['Ġrend', 'ers'] +['ĠYan', 'kees'] +['ĠTool', 'bar'] +['sp', 'aces'] +['.fill', 'Style'] +['Ġseg', 'undo'] +['_str', 'len'] +['.F', 'irebase'] +['å¤', 'Ħ'] +['Ġmention', 'ing'] +['\\', '('] +['ĠVal', 've'] +['Set', 'ter'] +['Ġsp', 'ans'] +['ĠAl', 'cohol'] +['ĠLet', 'ters'] +['\\x', 'e'] +['ĠT', 'K'] +['_B', 'LE'] +['.get', 'Result'] +['<', 'Player'] +['ĠP', 'att'] +['Ġeas', 'ing'] +['Ġtur', 'key'] +['ĠF', 'en'] +["')", '"'] +['Ġconf', 'ined'] +['Ġin', 'clus'] +['Sup', 'erview'] +['(with', 'Identifier'] +['enc', 'ial'] +['Ġstuff', 'ed'] +['Th', 'eta'] +['Ġeconom', 'ists'] +['}', '));ĊĊ'] +['co', 'okies'] +['ĠRo', 'ose'] +['ĠChe', 'ese'] +['Ġfich', 'ier'] +['Ġen', 'forced'] +['AB', 'B'] +['no', 'ÅĽci'] +['_AL', 'LOW'] +['Ġrecru', 'ited'] +['Ġexpend', 'iture'] +['-n', 'ight'] +['Ġassert', 'NotNull'] +['_ex', 'ecute'] +['ĠØ', '¯'] +['IN', 'DEX'] +['_F', 'MT'] +['Ġresc', 'ued'] +['ĠMonth', 'ly'] +['ĠCons', 'ervation'] +['ĠG', 'eb'] +['Ob', 'ama'] +['Ep', 'och'] +['ic', 'ies'] +['ĠOr', 't'] +['Ġso', 'it'] +['(', 'icon'] +['F', 'riends'] +['m', 'ol'] +['Ġground', 'ed'] +['ĠC', 'ause'] +['ad', 'ena'] +['WE', 'EN'] +['ĠL', 'un'] +['IT', 'IVE'] +['.', 'loop'] +['_un', 'til'] +['Ġcor', 'r'] +['.ed', 'ges'] +['Ġhyp', 'oth'] +['ched', 'uling'] +['trans', 'lator'] +['ĠÐ', 'ľ'] +['R', 'om'] +['ãĢij', 'ĊĊ'] +['ĠX', 'amarin'] +['Ġviol', 'ating'] +['.', 'anchor'] +['---', 'ĊĊ'] +['Ġtr', 'ader'] +['AD', 'VERTISEMENT'] +['Ġuns', 'ere'] +['ĠD', 'AO'] +['Ġbl', 'ond'] +['ĠP', 'AT'] +['.g', 'lob'] +['Ġè¾', 'ĵ'] +['Ġsplit', 'ting'] +['Ġun', 'subscribe'] +['Ġatmos', 'pheric'] +['ĠTr', 'im'] +['Ġcit', 'ation'] +['Ġin', 'ference'] +['ĠF', 't'] +['ĠDar', 'win'] +['find', 'One'] +['ĠG', 'el'] +['(', 'Convert'] +['Ġaccess', 'or'] +[';', 'text'] +['(s', 'orted'] +['Ġjud', 'ged'] +[');', '\\'] +[':', 'p'] +['Ġme', 'ine'] +['ĠS', 'lim'] +['.Command', 's'] +['Ġper', 'ceive'] +['coh', 'olic'] +['<', 'Data'] +['.entry', 'Set'] +['Ġassert', 'False'] +['ĠPat', 'rol'] +['ense', 'm'] +['ÅĤ', 'Äħ'] +['¨', '¡'] +['W', 'IDTH'] +['ĠRes', 'cue'] +['ĠU', 'IF'] +['_THRESH', 'OLD'] +['ĠMich', 'el'] +['ATER', 'IAL'] +['opens', 'ource'] +['ĠD', 'iana'] +['Ġinv', 'ites'] +['_B', 'ODY'] +['Ġreserv', 'oir'] +['Ġro', 'i'] +['c', 'ust'] +['(t', 'c'] +['ï¼ģ', '");Ċ'] +['Ġfest', 'ivals'] +['Ġperform', 'ers'] +['Ġclim', 'bed'] +['Ġj', 'ungle'] +['String', 'Length'] +['Ġunlaw', 'ful'] +['ier', 're'] +['vertis', 'ement'] +['Ġst', 'akes'] +['Ġh', 'ats'] +['Mod', 'ify'] +['ĠLET', 'TER'] +['.H', 'ide'] +['Ġstat', 'utory'] +['_', 'white'] +['ĠPer', 'l'] +['uten', 'berg'] +['em', 'ple'] +['.W', 'orld'] +['Ġoverlook', 'ed'] +['Ġcon', 'cludes'] +['/*', '================================================================'] +['-w', 'ise'] +['ĉ', 'stream'] +['pop', 'ulation'] +['Ġevent', 'o'] +['Ġillustr', 'ations'] +['ft', 's'] +['Ġaut', 'of'] +['ĠPro', 'cedure'] +['Ġdes', 'erved'] +['-t', 'imes'] +['Ġg', 'ol'] +['N', 'SError'] +['cre', 'st'] +['ĠPak', 'istani'] +['any', 'ch'] +['get', 'Current'] +['Ġl', 'ar'] +['nt', 'l'] +['ĠRe', 'becca'] +['Ġm', 'ateria'] +['Ġfind', 'By'] +['/', 'ad'] +['Callback', 's'] +['ĠAl', 's'] +['ĠKat', 'ie'] +['ĠObservable', 'Collection'] +['ĠDocument', 'ation'] +['Typ', 'ed'] +['ĠCulture', 'Info'] +['ĠTim', 'othy'] +['Ġlater', 'al'] +['"', 'type'] +['Ġun', 'authorized'] +['Ġteach', 'ings'] +['Ġdebug', 'ger'] +['[', 'value'] +['Ġal', 'ors'] +['Ġu', 'z'] +['Ġsc', 'atter'] +['Ġdown', 'ward'] +['Ġmig', 'li'] +['status', 'Code'] +['Ġ(', '))'] +['ĠM', 'W'] +['Ġм', 'ож'] +['RO', 'SS'] +['.b', 'uf'] +['Ġfair', 'y'] +['ĠInf', 'rastructure'] +['=>', '"'] +['t', 'lement'] +['$', '("'] +['From', 'String'] +['ĠB', 'ild'] +['Ġconvent', 'ions'] +['_n', 'ative'] +['ĠIns', 'pector'] +['ĠP', 'ist'] +['ub', 'ar'] +['Ġreg', 's'] +['ĠP', 'ilot'] +['Th', 'us'] +[">'", '+'] +['Ġc', 'ela'] +['.new', 's'] +['(', 'Product'] +['L', 'iving'] +['R', 'ussia'] +['Ġfac', 'et'] +['et', 'ical'] +["Ġ['", '$'] +['/', '['] +['ĠD', 'ire'] +['Ġg', 'ases'] +['ĠIN', 'FORMATION'] +['ĠE', 'at'] +['ĠFor', 'ums'] +['ĠChar', 'acters'] +['_m', 'et'] +['Ġìĭ', 'ľ'] +['Ġk', 'ings'] +['ach', 'ie'] +['ĠL', 'ambda'] +['Ġtim', 'ers'] +['ĠLight', 'ing'] +['ĠCase', 'y'] +['add', 'ir'] +['and', 'ex'] +['.', 'answer'] +['ĠH', 'ip'] +['ĠPr', 'incip'] +['Start', 'Date'] +['Ġ', 'ãĢĮ'] +['t', 'res'] +['Ġ&', '#'] +['.Max', 'Value'] +['ĠPro', 'blems'] +['Ġlat', 'ex'] +['Of', 'Class'] +['ĠLyn', 'n'] +['//', "'"] +['Ġvoy', 'age'] +['Ġshut', 'tle'] +['ĠRoll', 'er'] +['ĠRuntime', 'Error'] +['uy', 'a'] +['D', 'ic'] +['ĉb', 'uilder'] +['Ġbul', 'lying'] +['Ġsimple', 'st'] +['.c', 'alled'] +['ĠL', 'R'] +['Ġmor', 'ality'] +['Ġst', 'urdy'] +['tr', 'acking'] +['.sw', 'agger'] +['_B', 'IND'] +['IT', 'OR'] +['-url', 'encoded'] +['ĠÑ', 'ħ'] +['ĠTr', 'inity'] +['Ġtr', 'aps'] +['Ġ|', '-'] +['Ġset', 'Text'] +['Ġbarg', 'ain'] +['Ġbr', 'akes'] +['.get', 'Code'] +['Ġmigr', 'ate'] +['Ġrib', 'bon'] +[')', 'return'] +['Ġcharg', 'er'] +['ac', 'om'] +['ADI', 'US'] +['ĠAmb', 'assador'] +['-a', 'fter'] +['Ġann', 'i'] +['ĉs', 'pin'] +['Con', 'cept'] +['ĠHend', 'erson'] +['ĠH', 'OST'] +['.r', 'ank'] +['ĠNor', 'theast'] +['Ġber', 'lin'] +['Ġrequ', 'is'] +['.f', 'eed'] +['Ġsource', 'Mapping'] +['ĠRen', 'contre'] +['.', 'ajax'] +['nest', 'js'] +['Ġtre', 'k'] +['ĠN', 'acional'] +['Ġ&', '['] +['Ġpay', 'able'] +['ort', 'ex'] +['Ġde', 'pt'] +['field', 'Name'] +['Ġcomple', 'tes'] +['ĠR', 'VA'] +['Ġon', 'ions'] +['al', 'ignment'] +['Form', 'ats'] +["Ġ'", '{$'] +['Hash', 'Set'] +['ĠB', 'od'] +['.Invariant', 'Culture'] +['Ġsettlement', 's'] +['Ġhy', 'dr'] +['.', 'updated'] +['vent', 'h'] +['(', 'seconds'] +['="/', '"'] +['Ġweb', 'page'] +['(', 'ĊĊ'] +['Ġt', 'ir'] +['Ġto', 'es'] +['ĠBr', 'ick'] +['Ġamb', 'ition'] +['P', 'ot'] +['=', 'max'] +['ET', 'IME'] +['Ġdep', 'ot'] +['c', 'alls'] +['ĠNor', 'wegian'] +['`', ':'] +['Ġbur', 'ger'] +['Ġprofess', 'ors'] +['ĠAl', 'locate'] +['-third', 's'] +['-ch', 'art'] +['Ġfor', 'd'] +['*', 'N'] +['.k', 'otlin'] +['Ġpaper', 'work'] +['ĠDE', 'VICE'] +['%', '@",'] +['res', 'pect'] +['(m', 'p'] +['é', '«ĺ'] +['-', 'if'] +['Ġcush', 'ion'] +['ob', 'ot'] +['Ġpar', 'c'] +['SP', 'ACE'] +['ĠNet', 'anyahu'] +['Ġself', 'ish'] +['fe', 'at'] +['Ġclient', 'es'] +['-to', 'ols'] +['Ġpor', 'ch'] +['Ġj', 'q'] +['.', 'verbose'] +['Ġlib', 'erals'] +[']', ')ĊĊĊ'] +['p', 'ies'] +['Not', 'Blank'] +['(', 'term'] +['ÈĽ', 'i'] +['_Param', 's'] +['.normal', 'ize'] +['B', 'ullet'] +['AS', 'IC'] +['(h', 'ex'] +['_client', 'e'] +['+', ','] +['_D', 'I'] +['Ġforth', 'coming'] +['}', '")]Ċ'] +['se', 'o'] +['U', 'm'] +['>', 'Name'] +['Ġcomfort', 'ably'] +['irection', 'al'] +['W', 'ITH'] +['/', 'pr'] +['ĠP', 'oor'] +['ĠVit', 'amin'] +['v', 'ic'] +['G', 'H'] +['Ġprior', 'it'] +['ĠN', 'N'] +['ĠC', 'losed'] +['¤', 'í'] +['Ġis', 'Open'] +['\\', 'Console'] +['And', 'Feel'] +['.S', 'UCCESS'] +['_OPER', 'ATION'] +['pol', 'ation'] +['ĠT', 'as'] +['ps', 'z'] +['>', "'."] +['C', 'URRENT'] +['V', 'endor'] +['host', 's'] +['ĠE', 'rd'] +['>tag', 'ger'] +['ĠsourceMapping', 'URL'] +['Ġmar', 'athon'] +['_c', 'losed'] +['Ġexem', 'ption'] +['Ġrecogn', 'izes'] +['ides', 'how'] +["'", '$'] +["('/", "');Ċ"] +['m', 'its'] +['war', 'z'] +['ĠCh', 'erry'] +['µ', '¬'] +['n', 'or'] +['port', 'e'] +['Ġw', 'l'] +['_back', 'up'] +['.get', 'Boolean'] +['.get', 'Resource'] +['Ġdefinit', 'ive'] +['.', 'EditText'] +['Ġs', 'ÃŃ'] +['.C', 'ONT'] +['ĠPL', 'AYER'] +['.c', 'ards'] +['ĠSh', 'ore'] +["('/", "')Ċ"] +['cl', 'uir'] +['Web', 'Driver'] +['(m', 'onth'] +['-re', 'lease'] +['Ġins', 'pector'] +['å', '£'] +['ĠN', 'F'] +['_cl', 'ip'] +['åŃ', 'IJ'] +['Ġinteract', 'ing'] +['.t', 'mp'] +["Ġ''", "'ĊĊ"] +['Ġde', 'e'] +['Ġfro', 'st'] +['"]', '))Ċ'] +['ĠPl', 'aces'] +['Th', 'rows'] +['f', 'ork'] +['/', 'day'] +['i', 'Phone'] +['ĠM', 'IC'] +['Ġfold', 'ing'] +['Ġcro', 're'] +['ĠCh', 'iefs'] +['pher', 'ical'] +['(', 'price'] +['.Write', 'String'] +['Ġexit', 'ing'] +[']', "',Ċ"] +['ight', 'ing'] +['Ing', 'redient'] +['(', 'vertex'] +['Ġscroll', 'View'] +['h', 'f'] +[':', 'new'] +['SE', 'N'] +['se', 'ctor'] +['Ġsp', 'ins'] +['ĠS', 'cheduler'] +['ote', 'chn'] +['sem', 'icolon'] +['Font', 'OfSize'] +['ĠSpecific', 'ally'] +['fl', 'amm'] +['.Object', 'Id'] +['Ġcont', 'a'] +['_per', 'missions'] +['ĉF', 'ROM'] +['IC', 'ODE'] +['/', 'kg'] +['ĠHot', 'els'] +['-m', 'ed'] +['ĠD', 'in'] +['Ġn', 'avy'] +['get', 'Param'] +['Ġm', 'end'] +['Ġportray', 'ed'] +['ĠMet', 'ropolitan'] +['Paint', 'er'] +['Ġref', 'erral'] +['_g', 'ood'] +['Ġmar', 'vel'] +['osa', 'ic'] +['>', '(&'] +['.', 'ur'] +['Ġest', 'os'] +['Will', 'iam'] +['Ġtim', 'ber'] +['Ġquel', 'ques'] +['ĠDoc', 'uments'] +['.X', 'aml'] +['Ġbatch', 'es'] +['éģ', 'ĵ'] +['ĠRe', 'leased'] +['T', 'ail'] +['CO', 'OKIE'] +['he', 'id'] +['_st', 'ation'] +['ĠV', 'ia'] +['S', 'ale'] +['ĠRe', 'peat'] +['Ġprom', 'in'] +['ĠZ', 'o'] +['-', 'forward'] +['ĠI', 'on'] +['it', 'ary'] +['Ġj', 'us'] +['-', 'request'] +['Ġproud', 'ly'] +['ĠStream', 'ing'] +['(Mouse', 'Event'] +['ĠS', 'print'] +['_', 'rotation'] +['Re', 'positories'] +['Ġt', 'art'] +['ĠÑģ', 'в'] +['Ġm', 'appings'] +['è', 'ª'] +['C', 'u'] +['C', 'ycle'] +['Ġb', 'un'] +['ĉl', 'ua'] +['ãĥ', 'ī'] +['Ġ((', '!'] +['Ġcollect', 'ively'] +['ĠCon', 'd'] +['Ġwsz', 'yst'] +['(l', 'ib'] +['openh', 'agen'] +['_s', 'kip'] +['.Column', 'Header'] +['é', 'Ĥ'] +['peri', 'enced'] +['ı', 'è¿°'] +['_p', 'rops'] +['Ġcontr', 'ace'] +['Ġmatch', 'up'] +['ab', 'etic'] +['.m', 'embers'] +['RE', 'CT'] +['(d', 'at'] +['Ġs', 'og'] +['ren', 'om'] +['_M', 'ethod'] +['Custom', 'ers'] +['full', 'name'] +['Z', 'N'] +['re', 'try'] +['Ġk', 'ap'] +['ĠNe', 'u'] +['è', 'Ĭ'] +['add', 'Child'] +['will', 'Return'] +['_p', 'ermalink'] +['Ġener', 'getic'] +['ĠW', 'et'] +['ĠMor', 'r'] +['Ġg', 'cd'] +['count', 's'] +[',', 'type'] +['d', 'ig'] +['(', 'Login'] +['Ġcr', 'acks'] +['Ġbacter', 'ial'] +['ĠMe', 'at'] +['ĠArm', 'strong'] +['ĠBron', 'ze'] +['Ġapprox', 'imate'] +['_dir', 's'] +['lig', 'a'] +['ÅĤ', 'ad'] +['Ġkind', 'ness'] +['Ġcont', 're'] +['ĠE', 'VERY'] +['M', 'ET'] +['Ġannounc', 'ements'] +['g', 'pio'] +['ĠWaitFor', 'Seconds'] +['ĠPhotos', 'hop'] +['Ġdis', 'contin'] +['/', 'dd'] +['Ġtop', 'ology'] +['an', 'ical'] +['.', 'interface'] +['auc', 'oup'] +['.Hash', 'Set'] +['ARI', 'ANT'] +['(r', 'outes'] +['ĠT', 'eh'] +['Ġh', 'ype'] +[']', '").'] +['Ġsl', 'am'] +['Ġbro', 'th'] +['-', 'inter'] +['ĠR', 'id'] +['-m', 'anager'] +['Cancel', 'ar'] +['ĠP', 'agination'] +['Ġsound', 'track'] +['Ġpost', 'erior'] +['Ġscr', 'ub'] +['cre', 'ating'] +['-', '*'] +['ir', 'teen'] +['.d', 'y'] +['.s', 'ymmetric'] +['Ġ""', '.'] +['============', '==='] +['Ġch', 'assis'] +['ĠnumberOf', 'Rows'] +['Develop', 'er'] +['_b', 'ins'] +['ĠO', 'UR'] +['ri', 'eb'] +['Pro', 's'] +['Ġwi', 'ÄĻ'] +['"', 'd'] +['Ġasync', 'io'] +['ze', 'igen'] +['_s', 'pi'] +['.A', 'LL'] +['Ġscre', 'ws'] +['Ch', 'inese'] +['Ġapi', 'Key'] +['Ġun', 'successful'] +['ĠSeah', 'awks'] +['OR', 'G'] +['ç«', 'ł'] +['Ġprofession', 'ally'] +['ĠCou', 'pon'] +['åŃĹ', '段'] +['Con', 'vention'] +['Ġpol', 'ym'] +['æī', 'ĭ'] +['Ġsalv', 'ation'] +['Ġengine', 'ered'] +['ĠW', 'rest'] +['ĠG', 'CC'] +['Ġwar', 'mer'] +['Layout', 'Constraint'] +['Ġag', 'grav'] +['Script', 's'] +['vent', 'ure'] +['Ġrefriger', 'ator'] +['Ġinnov', 'ations'] +['ĠRun', 'ner'] +['N', 'IC'] +['ĠRoll', 'ing'] +['Control', 'Events'] +['Ġlo', 'os'] +['p', 'ac'] +['ĉ', 'panel'] +['ef', 'e'] +['ĠBudd', 'ha'] +['------------', '--Ċ'] +['åº', 'ĵ'] +['(for', 'Key'] +['Ġl', 'umin'] +['Ġ(', '?'] +['ĠA', 'IDS'] +[',', 'user'] +['im', 'ientos'] +['content', 'Type'] +['ant', 'lr'] +['é', '¦'] +['ĠW', 'elt'] +['Produ', 'ction'] +['m', 'ight'] +['ĠV', 'II'] +['",', '('] +['Ġobserv', 'ing'] +['Ġdeliber', 'ate'] +['(', 'control'] +['Ġwith', 'd'] +['Ġsem', 'ana'] +['ST', 'ACK'] +['uch', 'en'] +['N', 'ice'] +['ĠDeutsch', 'land'] +['ĠSpec', 'ifies'] +['d', 'ma'] +['iz', 'io'] +['ĠF', 'acts'] +['_pop', 'up'] +['ĠDirect', 'ors'] +['{', ':'] +['[', 'R'] +['ĠÑį', 'леменÑĤ'] +['Ġpl', 'at'] +['Ġdirect', 'ing'] +['ä¸', 'ī'] +['ĠGil', 'bert'] +['â̦', '.ĊĊ'] +['.q', 'ml'] +['Ġthere', 'after'] +['Ġdis', 'position'] +['d', 'raft'] +['Ġsurge', 'on'] +['ĠIns', 'ider'] +['Bl', 'end'] +['ĠT', 'rev'] +['tr', 'insic'] +['Top', 'ics'] +['rie', 've'] +['_FILE', 'NAME'] +['Ġaut', 'res'] +['J', 'ose'] +['Produ', 'cer'] +['er', 'us'] +['Ġpet', 'it'] +['ĠN', 'EXT'] +['ĠF', 'ilters'] +['Ġreplic', 'ate'] +['"]', ').'] +['Ġl', 'enders'] +[']', '",Ċ'] +[';', 'charset'] +['Cpp', 'Object'] +['Ġfl', 'oral'] +['ĠT', 'ipo'] +['Ġcirc', 'uits'] +['e', 'asy'] +['(&', '$'] +['itt', 'a'] +['ery', 'l'] +['_COMM', 'ON'] +["'}}", '>Ċ'] +['-back', 'ed'] +['(var', 'iable'] +['(', 'Index'] +['Ġvo', 'ir'] +['_loc', 'ations'] +['++)', '{'] +['ĠLouis', 'ville'] +['Ġgrat', 'itude'] +['.Mock', 'ito'] +['ĠP', 'owers'] +['ie', 'urs'] +['Ġge', 'ographic'] +['ra', 'le'] +['Ġc', 'ra'] +['ĠSp', 'urs'] +['iph', 'ertext'] +['AC', 'ION'] +['-', 'common'] +['Ġvict', 'ories'] +['ĠFinal', 's'] +['.sh', 'uffle'] +['-m', 'illion'] +['_PRO', 'C'] +['ass', 'ume'] +['Ġil', 's'] +['DB', 'C'] +['Boot', 'Test'] +['Ġl', 'avor'] +['.test', 'ing'] +['.', 'ast'] +['"]', '/'] +['m', 'oid'] +['Ġqual', 'ification'] +['ges', 'ch'] +['ĉ', 'put'] +['Ġair', 'ports'] +['J', 'I'] +['Te', 'acher'] +['_un', 'iform'] +['Ġn', 'ama'] +['ĠB', 'ast'] +['ert', 'ype'] +['c', 'apture'] +['get', 'All'] +['ĠReyn', 'olds'] +['oo', 'led'] +['.com', 'ments'] +['Ġch', 'in'] +[').', '*'] +['Ġи', 'ли'] +['t', 'gl'] +['ud', 'os'] +['Ġd', 'ÃŃas'] +['ch', 'ai'] +['.pro', 'gram'] +['Ġps', 'z'] +['ĉ', 'icon'] +['ph', 'il'] +['ent', 'ral'] +['_WR', 'AP'] +['ov', 'i'] +['Ġnost', 'alg'] +['In', 'finity'] +['ĉy', 'ield'] +['Ġvit', 'amins'] +['Qu', 'aternion'] +['S', 'ink'] +['_g', 'oods'] +['Ġ', '........'] +['ĠW', 'ings'] +['ur', 'idad'] +['-st', 'ory'] +['"]', ')ĊĊ'] +['idel', 'ity'] +['Type', 'Def'] +['G', 'tk'] +['Ġí', 'Į'] +['_M', 'ain'] +['Ġche', 'z'] +['ĠR', 'aven'] +['Ġpay', 'roll'] +['Ġfreel', 'ance'] +['LL', 'U'] +['ĠM', 'end'] +['ed', 'ay'] +['Api', 'ModelProperty'] +['.Form', 'BorderStyle'] +['Ġeconom', 'ist'] +['stan', 'bul'] +['Ġfre', 'ight'] +['-A', 'gent'] +['(m', 'eta'] +['Ġsym', 'metry'] +["Ġ'", '..'] +['.C', 'alendar'] +['-', 'aut'] +['g', 'f'] +['p', 'ent'] +['yc', 'lopedia'] +['Ġwish', 'ing'] +['ĊĊĊĊĊĊĊĊ', 'ĊĊĊĊ'] +['Ġgentle', 'man'] +['Ġê', '³'] +['=', '#'] +['Ġlect', 'ures'] +['âĢľ', 'In'] +['Ġ!', '_'] +['Ġh', 'b'] +['ĠV', 'endor'] +['Recent', 'ly'] +['_n', 'otes'] +['æıIJ', '示'] +['"', 'My'] +['Headers', 'Height'] +['_S', 'O'] +['Ġunw', 'illing'] +['Ġsuper', 'hero'] +['g', 'io'] +['ps', 'y'] +['ĠPe', 'er'] +['j', 'avax'] +['&', 'apos'] +['ĠCr', 'isis'] +['ord', 'inal'] +['Mem', 'cpy'] +['++++++++', '++++++++'] +['-', 'val'] +['Ġwork', 'book'] +['-', 'ap'] +['=', 'k'] +['Ġmetal', 'lic'] +['_', 'peer'] +['By', 'PrimaryKey'] +['_S', 'D'] +['u', 'ator'] +['_SH', 'ADER'] +[')', 'Math'] +['.Trans', 'form'] +['Ġc', 'ows'] +['Ph', 'i'] +['ĠC', 'lem'] +['(_', '("'] +['ĠL', 'ud'] +['-d', 'elay'] +['ĠSec', 'urities'] +['ĠOrth', 'odox'] +['Sym', 'fony'] +['(re', 'port'] +['Ġent', 'ertain'] +['E', 'PS'] +['iz', 'oph'] +['ex', 'ual'] +['IR', 'D'] +['ä»', 'İ'] +['Ġl', 'ith'] +['Ġsanit', 'ize'] +['Ġfemin', 'ine'] +['IS', 'BN'] +['.auth', 'entication'] +['_p', 'ipeline'] +['/', 'constants'] +['ĠCON', 'F'] +['Ġluc', 'r'] +['ric', 'ia'] +['.t', 'tf'] +['.set', 'Content'] +['Ġst', 'an'] +['ore', 'an'] +['ĠL', 'loyd'] +['.raw', 'Value'] +['Ġg', 'or'] +['ĠBrow', 'ns'] +['Re', 'gression'] +['Ġlower', 'ing'] +['na', 'issance'] +['Ġbl', 'ows'] +['Ġam', 'azed'] +['Ġun', 'related'] +['Re', 'views'] +['Ġrub', 'y'] +['ĠMod', 'ifier'] +['Ġgi', 'ants'] +['.', 'thread'] +['Ġcontain', 'ment'] +['ĠStart', 'Coroutine'] +['um', 'at'] +['ore', 'lease'] +['ĠR', 'andy'] +['@', 'endif'] +['D', 'igest'] +['Ġsubur', 'ban'] +['="', ');Ċ'] +['Ġann', 'once'] +['.', 'variable'] +['\\F', 'oundation'] +['Ġa', 'cre'] +['V', 'an'] +['Ġt', 'uples'] +['d', 'ns'] +['ĠStand', 'ing'] +['_l', 'arge'] +['Ġbox', 'ing'] +['Support', 'ActionBar'] +['ĠFort', 'une'] +['ĠR', 'um'] +['_m', 'ultiple'] +['arch', 'ical'] +['Ġf', 'write'] +['_', 'quote'] +['Ġfool', 'ish'] +['Ġcompr', 'ising'] +['Ġо', 'п'] +['-', 'selected'] +['v', 'f'] +['ma', 'id'] +['N', 'ama'] +['(d', 'atetime'] +['Ġindirect', 'ly'] +['g', 'art'] +['fix', 'tures'] +['ch', 'os'] +['ĠH', 'alo'] +['Ġrec', 'urring'] +['-', 'news'] +['v', 'il'] +['ĠNurs', 'ing'] +['-', 'produ'] +['ĠH', 'Q'] +['\\Http', 'Foundation'] +['enc', 'i'] +['au', 'en'] +['Ġv', 'y'] +['ocr', 'acy'] +['Ġdeleg', 'ation'] +['Ġas', 'phalt'] +['Ġset', 'Selected'] +['k', 'ok'] +['/', 'rest'] +['met', 'ics'] +['ĠNS', 'Date'] +['Ġtravel', 'led'] +['Ġrec', 'ib'] +['Ġm', 'ime'] +['CL', 'IENT'] +['ĠG', 'U'] +['ĠH', 'ANDLE'] +['/', 'Q'] +['[', 'z'] +['Ġbother', 'ed'] +['ĠBB', 'Q'] +['ç', 'as'] +['_ex', 'amples'] +['_F', 'IN'] +['Ġwhite', 'Color'] +['Ġastr', 'onom'] +['-d', 'ir'] +['Ġsovere', 'ign'] +['Ġb', 'reeze'] +['Ġin', 'ning'] +['ĠEd', 'monton'] +['g', 'li'] +['.blog', 'spot'] +['js', 'x'] +['Ġvers', 'a'] +['ĠMoh', 'ammed'] +['.J', 'ob'] +['-t', 'oggler'] +['Ġп', 'олÑĮзоваÑĤ'] +['ard', 'on'] +['Ġnew', 'born'] +['Ġnav', 'al'] +['note', 'q'] +['Ġtum', 'blr'] +['Ġh', 'entai'] +['ĠTyp', 'ically'] +['Ġlo', 'ot'] +['.S', 'prite'] +['Fl', 'ight'] +['Ġw', 'avelength'] +['-s', 'k'] +['ĠEl', 'le'] +['_', 'exports'] +['Ġ', 'Ñı'] +['ĠI', 'H'] +['izoph', 'ren'] +['Ġí', 'ģ'] +['_pr', 'imary'] +['Ġmo', 'is'] +['ĠB', 'N'] +['Ġsystem', 'ic'] +['Ġdifer', 'entes'] +['IN', 'CT'] +["Ġ''", 'ĊĊ'] +['$', 'q'] +['Widget', 'Item'] +['cl', 'ide'] +['$', 'file'] +['L', 'emma'] +['/', 'table'] +['ag', 'rid'] +['ĠMongo', 'DB'] +['int', 'e'] +['Ġapp', 'rent'] +['ÂŃ', 'ing'] +['.D', 'b'] +['ĠÃ', 'Ĥ'] +['ham', 'mer'] +["='", "';Ċ"] +['Ġbro', 'kers'] +['it', 'lement'] +['sembl', 'ies'] +['E', 'le'] +['{', 'x'] +['Ġlast', 'name'] +['<', '-'] +['Ġfl', 'atten'] +['_b', 'and'] +['.R', 'oot'] +['.read', 'FileSync'] +['====', '=='] +['.r', 'x'] +['?', 'čĊ'] +['Ġmetaph', 'or'] +['T', 'i'] +['con', 'te'] +['Ġdeb', 'it'] +['Ġcont', 'empt'] +['Cpp', 'Type'] +['æĶ', '¯'] +['Form', 'Field'] +['r', 'atio'] +['os', 'opher'] +['Ġimpl', 'ant'] +['P', 'URE'] +['Ġal', 'ta'] +['_man', 'agement'] +['Ġref', 'ine'] +['ĠCheck', 'Box'] +['ĠChar', 'l'] +['-', 'version'] +['cond', 'itional'] +['ven', 'ues'] +['Ġrif', 'les'] +['Ġoff', 'spring'] +['Ġmill', 'ing'] +['Ġshar', 'ply'] +['Ġunder', 'water'] +['(', 'origin'] +['_', 'Control'] +['Ġ.', '$'] +['Pl', 'ugins'] +['Ġdry', 'ing'] +['Ġillustr', 'ates'] +['-', 'u'] +['Ġveget', 'arian'] +['n', 'pc'] +['He', 'art'] +[';', "',Ċ"] +['com', 'ma'] +['te', 'enth'] +['as', 'an'] +['/s', 'pec'] +['_m', 'oves'] +['-m', 'argin'] +['Ġing', 'en'] +['³³', 'Âł'] +['Ġpro', 'jet'] +['Ġo', 'tra'] +['Ġbr', 'as'] +['.', 'utc'] +['Ġsle', 'pt'] +['=', 'sub'] +['ab', 'ilit'] +['post', 'er'] +['Ġs', 'dk'] +['ounc', 'ill'] +['Ġw', 'd'] +['Pre', 'paredStatement'] +['ĠDr', 'um'] +['(', 'attribute'] +['ĠEther', 'net'] +['ĉ', 'DB'] +['Cal', 'ifornia'] +['c', 'ube'] +['[', 'I'] +['.C', 'reated'] +['ĠH', 'M'] +['Ġtr', 'acing'] +['Forms', 'Module'] +['-', 'you'] +['.c', 'urrency'] +['feed', 'ing'] +['Ġt', 'body'] +['L', 'i'] +['acc', 'ion'] +['n', 'as'] +['Ġtr', 'ouver'] +['N', 'ONE'] +['"}', ',čĊ'] +['Ġf', 'tp'] +['With', 'Identifier'] +['pol', 'ate'] +['File', 'Info'] +['Ġpurs', 'ued'] +['ĠĠĠĠčĊ', 'ĠĠĠĠčĊ'] +['DE', 'SCRIPTION'] +['}', '*/Ċ'] +['From', 'Nib'] +['Ġdecor', 'ative'] +['_S', 'SL'] +['(ch', 'at'] +['T', 'LS'] +['Ġsurpr', 'ises'] +['al', 'culate'] +['ĠS', 'plash'] +['(', 'Configuration'] +['ĠS', 'EM'] +['im', 'son'] +['/lib', 'rary'] +['<', 'Double'] +['.', 'robot'] +['³³³³', '³³³³'] +['ĠCP', 'F'] +['ĠUnder', 'standing'] +['Ġcos', 'metic'] +['ĠX', 't'] +['t', 'ips'] +['+', 'k'] +['("', "'"] +['ĠP', 'DT'] +['W', 'AR'] +['.get', 'Object'] +['ĠTrad', 'itional'] +['.sl', 'ug'] +['ĠDi', 'pl'] +['="', '",'] +['ĠFil', 'ms'] +['ĠAn', 'im'] +['.h', 'elp'] +['Ġemb', 'assy'] +['ĠBoot', 's'] +['Ġb', 'unk'] +['-r', 'isk'] +['Ġp', 'ci'] +['Ġ/', '\\.'] +['ĠI', 'PT'] +['Ġcrash', 'ing'] +['Ġip', 'v'] +['_', 'ke'] +['ĠRES', 'P'] +['.Log', 'Error'] +['Ġinade', 'quate'] +['I', 'on'] +['ĠF', 'ür'] +['ric', 'ula'] +['Ġshould', 'Be'] +['al', 'ready'] +['\']."', ''] +['G', 'ED'] +['fa', 'q'] +['Ġoption', 'ally'] +['_D', 'is'] +['ĠSuccess', 'ful'] +['ĠC', 'ensus'] +['Ġinc', 'arcer'] +['_C', 'ARD'] +['Ġav', 'iation'] +['ĠG', 'ym'] +['Author', 'ity'] +['.B', 'ean'] +['sh', 'ader'] +['Not', 'Exist'] +['_Text', 'Changed'] +['ĠST', 'OP'] +['(', 'team'] +['"', 'H'] +['w', 'g'] +['Ġgr', 'inder'] +['Ġstri', 'pe'] +['Ġpres', 'ervation'] +['Cl', 'aim'] +['avers', 'al'] +['ware', 'house'] +['target', 's'] +['Tr', 'ust'] +['Ġal', 'lev'] +[',', 'www'] +['ous', 'se'] +['_ch', 'an'] +['_S', 'ize'] +['system', 's'] +['Ġobj', 'ection'] +['ĠK', 'ane'] +['Ġcor', 'ros'] +['ĠD', 'SL'] +['Ġu', 'a'] +['ĠM', 'H'] +['ĠStrateg', 'ic'] +['_t', 'cp'] +['Ġê°', 'Ĵ'] +['Ġborrow', 'ed'] +['ĠA', 'ch'] +['ĉ', 'command'] +['Ġg', 'ps'] +['le', 'ston'] +['iche', 'ver'] +['ĠU', 'A'] +['Ġassault', 'ed'] +['Ġspecial', 'izes'] +['ĉ', 'search'] +['Hot', 'el'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'čĊ'] +['ĠP', 'itch'] +['Ġ', 'Ùģ'] +['READ', 'Y'] +['Ġparent', 'al'] +['Ġg', 'éné'] +['Ġdonn', 'ées'] +['Ġdet', 'ain'] +['T', 'ARGET'] +['Ġprotagon', 'ist'] +['Ġclear', 'Interval'] +['ĠIcon', 'Button'] +['ĠGet', 'All'] +['Type', 'Info'] +['E', 'H'] +['âĢľ', 'They'] +['Ġ{', '['] +['Ġg', 'ag'] +['Ġ', 'Ú©'] +['ĠD', 'ropdown'] +['.f', 'ree'] +['g', 'one'] +['im', 'ens'] +['Ġinst', 'al'] +['ĉc', 'url'] +['_C', 'AN'] +['ĠB', 'one'] +['ï¼', 'Ķ'] +['ony', 'ms'] +['-g', 'overnment'] +['.binding', 'Navigator'] +['ĠD', 'ans'] +['ĠMc', 'L'] +['(', 'en'] +['>(', '_'] +['ÐĴ', 'Ñĭ'] +['.*', ';čĊ'] +['=', 'j'] +['-c', 'or'] +['S', 'on'] +['.ToolStrip', 'Item'] +['-', 'around'] +['_X', 'ML'] +['end', 'Date'] +['Ġsl', 'ack'] +['Ġrot', 'ated'] +['Ġno', 'qa'] +['Ġc', 'ottage'] +['Ġencontr', 'ar'] +['_s', 'kill'] +['hou', 'ette'] +['!', 'čĊ'] +['.', 'weather'] +['Ġemphas', 'ized'] +['å®', '¶'] +['ĠÑģ', 'пиÑģ'] +['ĠComp', 'iler'] +['(', 'android'] +['ĠâĢ', 'º'] +['.', 'turn'] +['Ġsup', 'pression'] +['_c', 'alls'] +['Ġ*', '@'] +['(str', 'len'] +['.h', 'ex'] +['ĠB', 'ills'] +['ĠR', 'SA'] +['Ï', 'Ĥ'] +['ĠEs', 'cape'] +['ement', 'ia'] +['Ġfront', 'end'] +['Ġp', 'int'] +['_ex', 'c'] +['zz', 'o'] +['[', '],Ċ'] +['Ġ"\',\'', '"'] +['.', 'Environment'] +['Ġafore', 'mentioned'] +['Ġend', 'ure'] +['prot', 'otype'] +['ther', 'apy'] +['ss', 'i'] +['D', 'eg'] +['_pl', 'ugins'] +['.user', 'Info'] +['Print', 'er'] +['ĠPRO', 'GRAM'] +['Ġru', 'ins'] +['Ġempir', 'ical'] +['Ġcraw', 'l'] +['ĠBo', 'iler'] +['-', 'comment'] +['.sub', 'plot'] +['_', 'et'] +["Ġ'.", "',"] +['min', 'or'] +['ĠCustom', 's'] +['Ġy', 'aw'] +['under', 'line'] +['ĠCom', 'o'] +['(', "('"] +['(m', 'ean'] +['Ġcha', 'que'] +['ĠBlock', 's'] +['.r', 'ad'] +['ilib', 'rium'] +['Ġweb', 'driver'] +['Ġmel', 'hor'] +['d', 'ana'] +['ĠAb', 'use'] +['ĠSouth', 'west'] +['ĠP', 'aren'] +['PERT', 'IES'] +['ĉ', 'IL'] +['Ġscre', 'am'] +['v', 'u'] +['Ġin', 'comes'] +['Ġn', 'im'] +['Ġl', 'ace'] +['Ġcompens', 'ate'] +['Re', 'verse'] +['D', 'at'] +['_att', 'ack'] +['Ġn', 'our'] +['ach', 'en'] +['ce', 'k'] +['<', 'Func'] +['w', 'ie'] +['com', 'pressed'] +['-m', 'atch'] +['("', '")]Ċ'] +['im', 'ized'] +['.', 'orientation'] +['.compare', 'To'] +['Ġmass', 'aggi'] +['Ġìľ', 'Ħ'] +['Ġel', 'bow'] +['Ġant', 'ioxid'] +['undred', 's'] +['/', 'tools'] +['ĠR', 'OW'] +['an', 'mar'] +['ĠW', 'ow'] +['_t', 'icket'] +['Program', 'ming'] +['Ġthe', 'or'] +['-re', 'view'] +['()', ')));Ċ'] +['ĠRichard', 'son'] +['ĠP', 'ocket'] +[']', '[]'] +['am', 'pp'] +['_', 'health'] +['ĠP', 'OP'] +['ĠNav', 'al'] +['Gu', 'ess'] +['Ġancest', 'or'] +['.Get', 'All'] +['.local', 'Scale'] +['ĠM', 'apper'] +['Ġaccum', 'ulation'] +['Ġsim', 'ulated'] +['ĠDr', 'ivers'] +['Ġd', 'és'] +['cur', 'ring'] +['Ġele', 'phant'] +['Ġadvert', 'ised'] +['Ġmail', 'box'] +['SH', 'IFT'] +['ĠMon', 'ica'] +['Ġan', 'c'] +['Ġward', 'robe'] +['Ing', 'redients'] +['Ġ||', 'čĊ'] +['ipp', 'y'] +['Ġantibiot', 'ics'] +['av', 'ings'] +['(c', 'x'] +['ĠFerr', 'ari'] +['ĠAn', 'imator'] +['.d', 'type'] +['rem', 'oved'] +['order', 'by'] +['Ġc', 'res'] +['oc', 'ê'] +['Ġp', 'ym'] +['ĠCirc', 'ular'] +['@', 'index'] +['ĠW', 'arm'] +['S', 'ay'] +['ĠAss', 'istance'] +['Ġcur', 'tain'] +['ĠMont', 'e'] +['IL', 'ER'] +['ĠC', 'VE'] +['ĠD', 'uck'] +['ĠAll', 'ows'] +['_f', 'ire'] +['ĠDer', 'by'] +['Ġre', 'pos'] +['Ġhttp', 'Client'] +['Ġpsych', 'iat'] +['Ġnow', 'adays'] +['Ġcaut', 'ious'] +['ĠComput', 'ing'] +['Ġcompletion', 'Handler'] +['ĠWel', 'sh'] +['ĠB', 'EST'] +['Ġstress', 'ful'] +['_P', 'E'] +['æĹ¥', 'æľŁ'] +['ĠData', 'Frame'] +['ĉ', 'Integer'] +['_P', 'rint'] +['M', 'oves'] +['Ġtransform', 'ing'] +['.B', 'atch'] +['y', 'ahoo'] +['Position', 's'] +['ze', 'j'] +['Ġno', 'od'] +['io', 'res'] +['_', '*'] +['Ġcl', 'k'] +['ĠF', 'loyd'] +['Ġh', 'ap'] +['font', 'size'] +['Ġn', 'az'] +['.not', 'ification'] +['ĠDep', 'ression'] +['Ġac', 'ne'] +['***', 'ĊĊ'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĊ'] +['.cont', 'ents'] +['yn', 'th'] +['ĠStra', 'ight'] +["')}}", '">', '"+'] +['Ġtoken', 'izer'] +['Ġsovere', 'ignty'] +['ĠP', 'ence'] +['()', '");Ċ'] +['Ġpesso', 'as'] +['.G', 'e'] +['ĠIn', 'cluded'] +['Ġpag', 'ina'] +['Ġex', 'posing'] +['е', 'ÑĪ'] +['_SC', 'RIPT'] +['/$', "',"] +['Th', 'umbnail'] +['×', 'Ķ'] +['webElement', 'X'] +['webElementX', 'paths'] +['press', 'ure'] +['ĠCur', 'ry'] +['_C', 'P'] +['OL', 'UTION'] +['ILE', 'S'] +['prot', 'ect'] +['ool', 'a'] +['Work', 'space'] +['{', '};Ċ'] +['ĠU', 'NS'] +['Ġsymp', 'athy'] +['ro', 'ker'] +['Ġrem', 'odel'] +['ĉc', 'ell'] +['Ġat', 'op'] +['.Full', 'Name'] +['Ġfa', 'ut'] +['ĠE', 'asily'] +['_d', 'ynamic'] +['Ġfr', 'amed'] +['Ġmot', 'ive'] +['è·', '¯'] +['s', 'am'] +['Ġmar', 'ca'] +['ĠText', 'EditingController'] +['Ġde', 'structor'] +['cre', 'am'] +['Ġr', 'ude'] +['ĠB', 'old'] +['ĠInd', 'igenous'] +['Ġg', 'ens'] +['Ġrel', 'acion'] +['(s', 'ystem'] +['ĠUIF', 'ont'] +['_char', 'ge'] +['UST', 'ER'] +['E', 'V'] +['.N', 'amespace'] +['Ġmer', 'ger'] +['Ġcal', 'loc'] +['g', 'ang'] +['Bad', 'Request'] +['Ġs', 'per'] +['-d', 'esign'] +['Ġâ', 'ĩ'] +['Ch', 'an'] +['Ġorgan', 'ism'] +[',', ')'] +['=', 'id'] +['_pl', 'ane'] +['ĠC', 'ases'] +['elf', 'ast'] +['ĠLegisl', 'ature'] +['ĠF', 'aker'] +['Ġinv', 'oking'] +['-', 'utils'] +['().', "'"] +['.f', 'ace'] +['Ġguard', 'ian'] +['my', 'Modal'] +['Ġclip', 'board'] +['ĠAT', 'M'] +['Ġpe', 'as'] +['ĠS', 'ylv'] +['.c', 'alc'] +['ĠContact', 's'] +['int', 'Value'] +['Ġmodify', 'ing'] +['ĠBar', 'b'] +['.', 'loss'] +['_per', 'centage'] +['Ask', 'ed'] +['(l', 'st'] +['ategor', 'ical'] +['-', 'files'] +['ĠRoman', 'ia'] +['.A', 'c'] +['Ġh', 'ai'] +['ĠF', 'lying'] +['Ġ', 'ż'] +['j', 'p'] +['ĠTr', 'ainer'] +['.', 'arc'] +['_de', 'g'] +['Ġtrace', 'back'] +['Or', 'Fail'] +['F', 'LOW'] +['.', 'old'] +['oy', 'a'] +['g', 'mt'] +['is', 'empty'] +['Ġvacc', 'ination'] +['Ġob', 'solete'] +['recogn', 'ized'] +['Ġru', 'ined'] +['ĠRe', 'in'] +['ĠTr', 'acking'] +['xf', 'b'] +['ا', 'ÛĮ'] +['Ġvæ', 're'] +['Ġbr', 'yster'] +['ĠIT', 'S'] +['Ġdest', 'iny'] +['Ġsw', 'ear'] +['Ġred', 'es'] +['Ġcl', 'f'] +['Ġfl', 'ipped'] +['ĉ', 'head'] +['Bl', 'uetooth'] +['ĠOver', 'rides'] +[':', 'Boolean'] +['_', '='] +['_l', 'r'] +['sp', 'awn'] +[':', 'index'] +['VAL', 'UES'] +['is', 'key'] +['?', '");Ċ'] +['.syn', 'thetic'] +['ĠCheck', 'ing'] +['struct', 'ures'] +['ip', 'ing'] +['Ġvoc', 'als'] +['-', 'Up'] +['ĠManufact', 'urers'] +['ĠMar', 'riage'] +['代', 'çłģ'] +['Ġgar', 'ner'] +['_C', 'lient'] +['par', 'allel'] +['RI', 'END'] +['Ġvine', 'gar'] +['seg', 'ue'] +['J', 'B'] +['Ġcontact', 'ing'] +['ĠCar', 'roll'] +['Ġout', 'reach'] +['t', 'ensor'] +['_var', 'iant'] +['Ġthe', 'at'] +['lic', 'able'] +['{', '|'] +['t', 'iny'] +['_', 'letter'] +['Ġp', 'encil'] +['HeadersHeight', 'SizeMode'] +['ilt', 'ro'] +['.auto', 'configure'] +['.d', 'rag'] +['.use', 'State'] +['ĠB', 'MI'] +['h', 'int'] +['Com', 'pile'] +['*', '\\'] +['en', 'ary'] +['Ġl', 'vl'] +['.C', 'ache'] +['+', '="'] +['_t', 'v'] +['ruit', 'ment'] +['Ġf', 'read'] +['Art', 'icles'] +['f', 'ila'] +['Ġpack', 'aged'] +['âĺ', 'Ĩ'] +['AT', 'HER'] +['ĠPl', 'anned'] +['s', 'cheme'] +['Ġdi', 'ary'] +['Ġoff', 'enses'] +['/', '', 'F'] +['ĠSt', 'ick'] +['Ġc', 'erc'] +['ĠS', 'lee'] +['ĉĉ', 'ĠĠĠĠĠĠĠĠ'] +['<', 'Image'] +['Ġè®', '¾'] +['-', 'editor'] +['pie', 'ces'] +['ĠD', 'rama'] +['Ġ//', '////////////////'] +['ĠT', 'asks'] +['AR', 'C'] +['g', 'ateway'] +['.get', 'cwd'] +['.M', 'etadata'] +['Ġguess', 'ing'] +['åľ°', 'åĿĢ'] +['Ġsm', 'arter'] +['ĠGet', 'Enumerator'] +['Ġe', 'fter'] +['/', 'operators'] +['ĠGL', 'float'] +['Ġf', 'ør'] +['Ġop', 'aque'] +['ä¿Ŀ', 'åŃĺ'] +['Sp', 'read'] +['SY', 'STEM'] +['Ġinv', 'ersion'] +['ĠBasket', 'ball'] +['Ġsim', 'ulations'] +['Ġden', 'ies'] +['Ġa', 'vez'] +['_list', 'ener'] +['Ġenh', 'ancing'] +['ĠMy', 'th'] +['ĠL', 'akers'] +['_M', 'D'] +['Nd', 'Ex'] +['D', 'ATABASE'] +['Ġt', 'á»'] +['ar', 'th'] +['[', 'left'] +['Ġcontest', 's'] +['st', 'ile'] +['(K', 'ERN'] +['_f', 'c'] +['_p', 'm'] +['Ġpres', 'idents'] +['Ġhospital', 'ity'] +['Ġfade', 'In'] +['RO', 'PERTY'] +['_m', 'aps'] +['ĠDefinition', 's'] +['Ġassess', 'ing'] +['Ġus', 'ar'] +['Ġquant', 'itative'] +['mo', 'z'] +['Be', 'autiful'] +['[', '(('] +['b', 'ons'] +['f', 'requency'] +['Cont', 'ain'] +['Ġpuzz', 'les'] +['ĠCast', 'ro'] +['Ġv', 'illa'] +['Ġkind', 'ly'] +['Font', 'Awesome'] +['ern', 'a'] +['epoch', 's'] +['_dat', 'as'] +['ĉ', 'ip'] +['.p', 'adding'] +['ĠCont', 'est'] +['Ġed', 'itions'] +['Ġdispro', 'portion'] +['ĠI', 'CO'] +['Ġcome', 'back'] +['=', 'value'] +['ri', 'ad'] +['-s', 'ort'] +['Sub', 'mitted'] +['(n', 'etwork'] +['ĠC', 'el'] +['Ġinstall', 'ment'] +['l', 'ashes'] +['.List', 'View'] +['ĠV', 'atican'] +['(Media', 'Type'] +['IV', 'ED'] +['reach', 'able'] +[':', 'Is'] +['ĠC', 'ITY'] +['äº', '¬'] +['ĠHelp', 'ful'] +['Ġba', 'ÅŁ'] +['%', 'čĊ'] +['Ġpsych', 'iatric'] +['Ġrec', 'ycled'] +['FORM', 'AT'] +['ĠG', 'row'] +['b', 'ine'] +['G', 'it'] +['.s', 's'] +['ĠWe', 'apons'] +['ĠSt', 'y'] +['_', 'arrow'] +['*', 'self'] +['ire', 'ment'] +['Ġdeg', 'li'] +['App', 'Delegate'] +['_b', 'anner'] +['Ġcoordin', 'ated'] +['ĠWeb', 'cam'] +['Ġcelebr', 'ations'] +['.', 'act'] +['********************************', '****************'] +['(', 'show'] +['Ġweek', 'day'] +['Ġconc', 'erts'] +['ол', 'н'] +['cl', 'in'] +['Ġcr', 'on'] +['ĠN', 'im'] +['.set', 'Vertical'] +['ĠEll', 'en'] +['س', 'ت'] +['ĠS', 'AM'] +['E', 'ff'] +['g', 'z'] +['ste', 'am'] +['Ġant', 'ique'] +['ph', 'ysical'] +['ĠForm', 'Data'] +['.set', 'ter'] +['ĠPO', 'INT'] +['B', 'on'] +['Ġflav', 'our'] +['erv', 'ention'] +['_ENT', 'ITY'] +['ĉ', 'ĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġintr', 'insic'] +['Ġæ', 'İ'] +['append', 'To'] +['aram', 'el'] +[')', '])'] +['ĠRecomm', 'end'] +[')', 'm'] +['OutOf', 'Range'] +['Ġkn', 'ight'] +['Ġsat', 'ellites'] +['ĠTit', 'ans'] +['Ġweigh', 'ed'] +['ĠD', 'ana'] +['e', 'ase'] +['Ġs', 'ip'] +['S', 'IM'] +['ĠDevelop', 'ers'] +['mal', 'ink'] +['/', 'check'] +['_P', 'LL'] +['n', 'ung'] +['Ġdry', 'er'] +['=', 'A'] +['.d', 'w'] +['_S', 'QL'] +['Ġsub', 'plot'] +['D', 'ROP'] +['Ġprot', 'otypes'] +['Ġhour', 'ly'] +['display', 'Name'] +['Ġas', 'i'] +['ĠViol', 'ence'] +['Ġastr', 'onaut'] +['Ġdat', 'atype'] +['Ġinformation', 'al'] +['Ġinvestig', 'ative'] +['etermin', 'ed'] +['ren', 'al'] +[';', "'>"] +['ĉc', 'ol'] +['V', 'G'] +['_', 'boolean'] +['re', 'cent'] +['Ġ*', ')ĊĊ'] +['ĠRain', 'bow'] +['om', 'men'] +['Ġl', 'ur'] +['Ġopp', 'ression'] +['(",', '");Ċ'] +['ĠFac', 'ility'] +['DEF', 'INED'] +['Ġne', 'on'] +['Ġoff', 'ender'] +['AF', 'P'] +['ĠClean', 'ing'] +['[]', '):'] +['Ġund', 'ocumented'] +['.Re', 'positories'] +['ĠG', 'uitar'] +['аÑģÑģ', 'ив'] +['Sk', 'ills'] +['Ġtestim', 'on'] +['rypt', 'ography'] +['ĠAm', 'ber'] +['ĠSt', 'alin'] +['Ġl', 'one'] +['Ġap', 'enas'] +['Ġdies', 'es'] +['ĠAr', 'duino'] +['è½', '¬'] +['==', '-'] +['_A', 'ct'] +['Ġc', 'oded'] +['âĸ', 'ł'] +['amb', 'urger'] +['-link', 's'] +['Ġarm', 'our'] +['.H', 'igh'] +['get', 'Content'] +['st', 'ag'] +['Ġhe', 'ck'] +['ĠìĹ', 'Ĩ'] +['ĠMc', 'Connell'] +['ĠCon', 'cert'] +['ĠAl', 'loc'] +['ä', 're'] +['.replace', 'All'] +['Ġpart', 'itions'] +['rot', 't'] +['ĠF', 'le'] +['_T', 'REE'] +['reason', 'able'] +['ĠReport', 'ing'] +['Ġbillion', 'aire'] +['s', 'cores'] +['min', 's'] +['-', 'eye'] +['M', 'ORE'] +['ab', 'ort'] +['ĠSW', 'T'] +['Ġin', 'verted'] +['ĠTe', 'achers'] +[';', 'n'] +['Ġast', 'ro'] +['н', 'ов'] +['ани', 'ÑĨ'] +['product', 'o'] +['c', 'ountries'] +['ĠO', 'wen'] +['Ġcont', 'amination'] +['Ġv', 'ibe'] +['ĠEll', 'i'] +['.s', 'cript'] +['ĠOl', 'ive'] +['D', 'MA'] +['v', 'ier'] +[':', 'semicolon'] +['-m', 'odule'] +['gress', 'ive'] +['ag', 'u'] +['_', 'players'] +['Ġresult', 'ados'] +['start', 'ed'] +['scroll', 'Top'] +['====', '='] +['Ġweigh', 'ing'] +['Ġ[[', '['] +['z', 'ahl'] +['(', 'NS'] +['ĠAssert', 'ion'] +['le', 'ague'] +['.setText', 'Color'] +['ĉ', 'Message'] +['Ġmom', 's'] +['_A', 'F'] +['.', 'wh'] +['AL', 'S'] +['Ġaut', 're'] +[']', 'ĊĊĊĊ'] +['.op', 'acity'] +['ĠBudd', 'hist'] +['Ġde', 'af'] +['ĠOrgan', 'isation'] +['(G', 'lobal'] +['ens', 'ch'] +['Ġhead', 'ache'] +['ĠAli', 'en'] +['_in', 'ode'] +['ĠSt', 'ark'] +['Ġæ', 'ī'] +['-l', 'nd'] +['ore', 'f'] +['_fe', 'at'] +['Ġpedest', 'rian'] +['Ġnom', 'inal'] +['Ġbal', 'loon'] +['Ġspr', 'ites'] +['Prototype', 'Of'] +['ĠA', 'post'] +['ĠF', 'EATURE'] +['O', 'H'] +['Ġre', 'cess'] +['ĠDon', 'na'] +['con', 'sumer'] +['$', 'GLOBALS'] +['ĠG', 'IF'] +['-', 'frame'] +['In', 'icio'] +['Ġpass', 'ages'] +['Date', 'String'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠ'] +['.by', 'te'] +['B', 'ug'] +['initial', 'izer'] +['p', 'kt'] +['od', 'ium'] +['ĠD', 'ER'] +['.', 'ops'] +['ler', 'i'] +['Ġgift', 'ed'] +['Ġdet', 'ach'] +['ter', 'rain'] +['elt', 'ers'] +['ãģ', 'ı'] +['.', 'loader'] +['ĠN', 'GO'] +['str', 'ncmp'] +['K', 'h'] +['(font', 'Size'] +['ro', 'cket'] +['Ġpreced', 'ent'] +['ĠAur', 'ora'] +['ĠEx', 'periment'] +['is', 'phere'] +['Enc', 'oded'] +['ĠâĢĵ', 'ĊĊ'] +['Ġpy', 'ramid'] +['ĠAnn', 'iversary'] +['of', 'il'] +['ë', 'Ł'] +['(', 'plugin'] +['C', 'oeff'] +['Ġcooper', 'ate'] +['Ġpredomin', 'antly'] +['IS', 'M'] +['Ph', 'rase'] +['_DEF', 'INE'] +['Fl', 'ip'] +['AMIL', 'Y'] +['ĠMark', 'ets'] +['ĠStream', 'Reader'] +['ĠComb', 'ine'] +['Ġmanus', 'cript'] +['z', 'za'] +[',', 'tp'] +['Wh', 'atever'] +['IT', 'ICAL'] +['ighb', 'our'] +['Data', 'Provider'] +['.Text', 'ure'] +['priv', 'acy'] +['.S', 'DK'] +['Ġre', 'charge'] +['Ġc', 'pp'] +['ĠC', 'FG'] +['(h', 'older'] +['(p', 'y'] +['m', 'ot'] +['Ġsav', 'oir'] +['ĠR', 'osa'] +['ĠPC', 's'] +['Ġí', 'Ļ'] +['.her', 'oku'] +['Ġf', 'ren'] +['ĠR', 'iley'] +['ag', 'ate'] +['Ġs', 'ond'] +['.x', 'lsx'] +['Ġh', 'acked'] +['st', 'ad'] +['G', 'i'] +['Ġsan', 'ity'] +['ĠSql', 'DataAdapter'] +['...', '",'] +['ĠP', 'ussy'] +['Ġ', '****************'] +['Ġhass', 'le'] +['_P', 'ARENT'] +['ĠU', 'AE'] +['Ġbegin', 'ners'] +['(', 'Client'] +['Ġstatist', 'ically'] +['.h', 'our'] +['ed', 'elta'] +['Ġtr', 'action'] +['uel', 've'] +['ar', 'at'] +['Ġsa', 'una'] +['IN', 'VALID'] +['Ġindict', 'ment'] +['AL', 'LE'] +['Ġdiss', 'ent'] +['ĠTyp', 'ography'] +['Ġintention', 'al'] +['s', 'it'] +['ĠAn', 'imals'] +['Ġcoun', 'tryside'] +['Ġu', 'art'] +['}', '\\"'] +['Ġseam', 'less'] +['¾', '示'] +['Ġaut', 'os'] +['Ġ"\'', '";Ċ'] +['Fl', 'ush'] +['ANN', 'OT'] +['Ġal', 'gebra'] +['ass', 'oc'] +['ĠW', 'aters'] +['Ġprepar', 'ations'] +['ron', 'ym'] +['[,', ']'] +['S', 'ans'] +['Ġarm', 'ies'] +['ipe', 'g'] +['Ġcream', 'y'] +['.', 'art'] +['et', 're'] +['ĠAn', 'imated'] +['Ġun', 'pleasant'] +['eme', 'an'] +['g', 'reat'] +['i', 'Äħ'] +['ĠEar', 'lier'] +['Ġch', 'ic'] +['Ġpres', 'erving'] +['(ex', 'ec'] +['ĠInvest', 'igation'] +['ĉG', 'PIO'] +['Ġrig', 'orous'] +['ij', 'o'] +['=', 'num'] +['Ġtool', 'Strip'] +[')', 'set'] +['+"', '&'] +['ĠAcc', 'eler'] +['Ġdevelopment', 'al'] +['is', 'posable'] +['Ġflaw', 'ed'] +['re', 'ne'] +['Up', 'dating'] +['Ġwatch', 'dog'] +['Ġden', 'ominator'] +['Ġsubur', 'bs'] +['Ġ...', ')'] +['Ġconv', 'ictions'] +['c', 'losure'] +['.I', 'P'] +['Ġtransl', 'ates'] +['.sw', 't'] +['.Tr', 'ace'] +['Ġmet', 'tre'] +['.is', 'Enabled'] +['ĠEffect', 'ive'] +['.to', 'Int'] +['Ġen', 'chant'] +['Ġst', 'unned'] +['Ġpo', 'i'] +['/', 'code'] +['ad', 'm'] +['.datab', 'inding'] +['ĠL', 'orem'] +['________________________________', '________________________________'] +['Ġled', 'ger'] +['Ġcar', 'a'] +['ĠG', 'ir'] +['Ġwa', 'its'] +['Un', 'o'] +['Ġc', 'wd'] +['è¾', 'ij'] +['ĠT', 'Result'] +['Ġre', 'jo'] +['Ġem', 'itted'] +['ĠWest', 'minster'] +['ä¸Ģ', '个'] +['ne', 'k'] +['_T', 'is'] +['Ġen', 'act'] +['ĉ', 'with'] +['org', 'ia'] +['Ġj', 'ue'] +['Per', 'form'] +['SP', 'ATH'] +['.top', 'ic'] +['ĠD', 'aten'] +['áº', '§'] +['Ġsit', 'io'] +['_M', 'M'] +['"', 'So'] +['b', 'ial'] +['Ġsc', 'oped'] +['Re', 'quires'] +['ĠT', 'OTAL'] +['ĠCh', 'ancellor'] +['(', 'contents'] +['Ġste', 'alth'] +['dev', 'ices'] +['-p', 'ass'] +['ili', 'h'] +['ĠMal', 'colm'] +['ĠDep', 'ot'] +['Ġconfig', 'ur'] +['a', 'ussian'] +['_con', 'straint'] +['в', 'еÑĤ'] +['G', 'RA'] +['ĠR', 'ates'] +['.dataGridView', 'TextBoxColumn'] +['ĠNob', 'el'] +['it', 'ics'] +['Ġignor', 'ant'] +['ĠReport', 'er'] +['ĠEb', 'ola'] +['ĠSh', 'ock'] +['_re', 'lation'] +['ĠNin', 'ja'] +[')', 'c'] +['Ġt', 'icker'] +['.is', 'Checked'] +['ĠSup', 'pliers'] +['ĠRap', 'id'] +['Level', 's'] +['âĤ¬', 'âĦ¢'] +['ĉ', 'queue'] +['Ġch', 'op'] +['ĠUn', 'ix'] +['re', 'ject'] +['-c', 'alendar'] +['(s', 'ort'] +['è', 'ne'] +['erc', 'icio'] +['Ġh', 'ect'] +['CALL', 'TYPE'] +['rou', 'pon'] +['Ġrent', 'als'] +['auth', 'ors'] +['{', 'name'] +['ĠF', 'IFO'] +['Ġl', 'assen'] +['ĠN', 'ous'] +['Ġsn', 'apped'] +['Ġfert', 'ility'] +['"', 'log'] +['click', 'ed'] +['Ġplant', 'ing'] +['Ġg', 'b'] +['/', 'output'] +['PE', 'AT'] +['Ġc', 'ategoria'] +['Ġb', 'ach'] +['Prof', 'essor'] +['in', 'th'] +['"]', 'čĊ'] +['Rec', 'order'] +['ser', 'de'] +['ĠTrans', 'mission'] +['tr', 'ad'] +['Ġtur', 'bo'] +['_VER', 'TEX'] +['\\', 'Event'] +['il', 'ver'] +['Ġbod', 'ily'] +['ĠS', 'ources'] +['Ġkill', 'ings'] +['.xr', 'TableCell'] +['Ġfold', 'ed'] +['/', 'legal'] +['un', 'er'] +['ĠR', 'ifle'] +['ĠM', 'IDI'] +['_Selected', 'IndexChanged'] +['.Size', 'Type'] +['ĠWeb', 'Socket'] +['Ġsele', 'ccion'] +['S', 'and'] +['ot', 'ros'] +['Ġenv', 'ision'] +['/', 'etc'] +['ĠMel', 'issa'] +['Sp', 'ot'] +['но', 'е'] +['_', 'ARM'] +['At', 'tempt'] +['ĠB', 'I'] +['ãģ', 'Ķ'] +['ĠD', 'U'] +['Ġback', 'lash'] +['str', 'ide'] +['/', 'classes'] +['Ġtext', 'Color'] +['_st', 'aff'] +['ob', 'lin'] +['agent', 'a'] +['.c', 'ollections'] +['ill', 'age'] +["'", 'čĊčĊ'] +['fl', 'atten'] +['_s', 'ales'] +['_M', 'ASTER'] +['T', 'W'] +['_d', 'a'] +['P', 'itch'] +['ph', 'ies'] +['Ġz', 'ombies'] +['ĠV', 'ERY'] +['ĠPharm', 'acy'] +['Ġprogress', 'Bar'] +['Ġhas', 'htag'] +['S', 'idebar'] +['@', 'stop'] +['(p', 'c'] +['ол', 'ж'] +['MA', 'KE'] +['ĠCor', 'on'] +['Ġkv', 'inner'] +['ĠM', 'aid'] +['b', 'ob'] +['.title', 'Label'] +['Ġsuccess', 'es'] +['ĠDemocr', 'acy'] +['ĠSurg', 'ery'] +['Ġcou', 'gar'] +['Ġcur', 'so'] +['Ġl', 'oro'] +['ist', 'ency'] +['Sen', 'ior'] +['æ', 'k'] +['ĠA', 'AA'] +['ĠBO', 'OK'] +['к', 'о'] +['W', 'STR'] +['Ġ*/', ',Ċ'] +['oy', 'al'] +['.v', 'ector'] +['ĠS', 'PEC'] +['SS', 'F'] +['Ġcomp', 'uls'] +['ĠAppe', 'als'] +['ĠW', 'inston'] +['ĠMock', 'ito'] +['con', 'trib'] +['.', 'available'] +['entity', 'Manager'] +['ari', 'as'] +['_s', 'ale'] +['_r', 's'] +['Ġdec', 'oding'] +['Ġloc', 'ator'] +['ol', 'ith'] +['Ġk', 'ol'] +['Ġasc', 'ii'] +['ĠR', 'ut'] +['/', 'interface'] +['ĉĉĉĉĉĉ', 'ĠĠĠ'] +['ĠN', 'umer'] +['.fl', 'ip'] +['-d', 'el'] +['Ġbol', 'ster'] +['on', 'omic'] +['Ġz', 'm'] +['L', 'G'] +['Find', 'By'] +['Ġadapt', 'ive'] +['lo', 'o'] +['Ġv', 'ue'] +['(re', 'verse'] +['_c', 'anvas'] +['.', 'roles'] +['ific', 'ado'] +['ven', 'ient'] +['"', 'As'] +['ĠEn', 'tr'] +['al', 'igned'] +['Ġbere', 'its'] +['///', 'ĊĊ'] +['.g', 'wt'] +['.', 'employee'] +['_cl', 'i'] +['Ġanticip', 'ate'] +['éĻ', 'IJ'] +['Ġp', 'ik'] +['Ġmush', 'rooms'] +['(t', 't'] +['Ġo', 'ma'] +['ĠSan', 'chez'] +['_g', 'oogle'] +['.', 'Valid'] +['ĠFile', 'Name'] +['iv', 'ative'] +['k', 'ed'] +['-w', 'ar'] +['Ġm', 'aturity'] +['и', 'д'] +['Ġmin', 'er'] +['Reduc', 'ers'] +['ĠLat', 'Lng'] +['_ST', 'D'] +['D', 'igits'] +['Cal', 'c'] +['-up', 'load'] +['Ġhand', 'ic'] +['ี', 'à¹Ī'] +['egr', 'ated'] +['ĠST', 'M'] +['C', 'lients'] +['ĠTur', 'bo'] +['SY', 'NC'] +['Ġphotograph', 'ers'] +['.', 'Out'] +['.char', 'acter'] +['B', 'UILD'] +['.un', 'lock'] +['Ġar', 'ises'] +['ĠCommand', 's'] +['("', '");čĊ'] +['_F', 'ORE'] +[';', "',"] +['+"', "'"] +['.', 'Images'] +['")', '{'] +['ĠM', 'eyer'] +['Ġneg', 'atively'] +['ĠD', 'LL'] +['Ġex', 'e'] +['Ġdef', 'iciency'] +['Ġwild', 'ly'] +['-s', 'witch'] +['con', 'struction'] +['Ġexception', 'ally'] +['ĠL', 'iz'] +['/j', 'ava'] +['Ġtheir', 's'] +['ĠCont', 'emporary'] +['l', 'is'] +['.fill', 'Rect'] +['ĠN', 'FC'] +['Ġre', 'he'] +['(num', 'bers'] +['Ġr', 'aster'] +['Ġfig', 'uring'] +['Ġshow', 'c'] +['ĠJ', 'ill'] +['Ġarc', 'ade'] +['ĠConstruct', 's'] +['md', 'l'] +["('", '|'] +['Ġident', 'ifiers'] +['Ġst', 'ellar'] +['(', 'Connection'] +['Ġ"', '{{'] +['y', 'or'] +['(m', 'ysqli'] +['Ġdo', 've'] +['Of', 'Birth'] +['.dis', 'connect'] +['_h', 'i'] +['Ġzw', 'ischen'] +['ĠGr', 'und'] +['i', 'ros'] +['_A', 'rray'] +['.on', 'click'] +['ans', 'om'] +['An', 'swers'] +['ĉ', 'remove'] +['F', 'a'] +['Ġhur', 'ry'] +['-in', 'f'] +['Ġget', 'Class'] +['ĠReg', 'ulation'] +['ĠFLAG', 'S'] +['m', 'isc'] +['K', 'en'] +['_', 'heading'] +['G', 'Hz'] +['-', 'entry'] +['Ġbi', 'ography'] +['S', 'ig'] +['-m', 'f'] +['Watch', 'er'] +['âĢľ', 'A'] +['}', 'px'] +['Ġsp', 'icy'] +['_s', 'q'] +['L', 'ost'] +['(tr', 'ack'] +['а', 'ли'] +['Desc', 'ending'] +['<', 'bits'] +['qu', 'ine'] +['ĠAdv', 'oc'] +['_S', 'N'] +['ĠHann', 'ah'] +['PO', 'P'] +['Ġem', 'itter'] +['Ġc', 'yn'] +['ĠC', 'AD'] +['?', ').'] +['/', 'set'] +['ĠS', 'ister'] +['ĠEnd', 'point'] +['Ġmen', 'or'] +['Ġinter', 'p'] +['r', 'k'] +['id', 'le'] +['Ġout', 'fits'] +['.', 'vertex'] +['Ġc', 'lic'] +['ARE', 'N'] +['Ġpost', 'ure'] +['ĠOpport', 'unity'] +['v', 'x'] +['ĠFor', 'bes'] +['.D', 'irection'] +['Ġres', 'ide'] +['Ġremember', 'ing'] +['nest', 'y'] +['Auto', 'resizing'] +['pro', 'viders'] +['ĠA', 'H'] +['Ġhur', 'ting'] +['ĠL', 'ily'] +['eval', 'uate'] +['lij', 'k'] +['p', 'apers'] +['ĠSm', 'ash'] +['ĠL', 'AST'] +['Ġwell', 's'] +['w', 'asher'] +['_RO', 'LE'] +['ĠD', 'anger'] +['*', '(('] +['_re', 'pository'] +['ĠRes', 'olve'] +['ĠRoom', 's'] +['_R', 'G'] +['ĠQ', 'T'] +['o', 'op'] +['ĠHe', 'ap'] +['Ġslow', 'ing'] +['Ġgrat', 'uite'] +['_c', 'atalog'] +['Ġpol', 'ynomial'] +['L', 'y'] +['pc', 's'] +['F', 'ox'] +['ĠC', 'yr'] +['Ġdim', 'in'] +['/', 'month'] +['S', 'alt'] +['Ġh', 'ind'] +['.P', 'ER'] +['For', 'um'] +['c', 'en'] +['_p', 'ol'] +['íĺ', '¸'] +['Ġin', 'ser'] +['(', '~'] +['@', 'test'] +['ĠGold', 'man'] +['Ġupload', 'ing'] +['F', 'c'] +['Ġkom', 'mer'] +['Ġm', 'itt'] +['_log', 'ged'] +['Ġbu', 'cks'] +['-l', 'ayer'] +[')', '};Ċ'] +['ĠO', 'M'] +['Ġv', 'eg'] +['col', 'our'] +['Ġоб', 'ÑĬ'] +['Std', 'String'] +['_', 'que'] +['ĠT', 'ian'] +['Ġspecial', 'ize'] +['и', 'п'] +['Ġк', 'л'] +['tr', 'ial'] +['-', 'edge'] +['Ġm', 'ars'] +['OG', 'LE'] +['Ġempath', 'y'] +['ĠB', 'om'] +['Ġcoll', 'isions'] +['Ġcart', 'e'] +['ĠTe', 'il'] +['ĠM', 'PL'] +['Ġporn', 'ô'] +['Ġa', 'irlines'] +['A', 'ws'] +['N', 's'] +['ĠSp', 'awn'] +['(', 'use'] +['é»', 'ĺ认'] +['Ġy', 'acc'] +['st', 'or'] +['Ġconf', 'ess'] +['Ġpe', 'que'] +['r', 'age'] +['?', '"Ċ'] +['/dat', 'atables'] +['ĠSh', 'ower'] +['__', '/'] +['Ġcryst', 'als'] +['Ġbus', 'car'] +['ĠH', 'aus'] +['iz', 'ação'] +['_', 'entities'] +['ķ', 'Į'] +['ļ', 'Į'] +['x', 'cc'] +['v', 'irt'] +['-che', 'vron'] +['(', 'Result'] +['c', 'ake'] +['COM', 'E'] +['Ġprohib', 'it'] +['ĠCh', 'ess'] +['Ġbe', 'aucoup'] +['ĠÑĩ', 'ÑĤо'] +['R', 'UN'] +['ĠI', 'K'] +['ó', 'ÅĤ'] +['_', 'Update'] +['Ġsle', 'ek'] +['ĠSpec', 'ify'] +['_c', 'redentials'] +['ÅŁ', 't'] +['ĠUser', 'Name'] +['ĉ', 'Value'] +['Ġarray', 'List'] +['Ġex', 'changed'] +['ips', 'is'] +['.re', 'lated'] +['ĠSe', 'ite'] +['_B', 'AR'] +['ĠL', 'em'] +['ĠW', 'ATCH'] +['ĠC', 'lients'] +['Ġ.', '*'] +['ĠEar', 'l'] +['-re', 'port'] +['Ġforeign', 'ers'] +['Ġstrengthen', 'ing'] +['ĉ', 'Description'] +['(g', 'o'] +['.tool', 'bar'] +['Ġcalcul', 'ates'] +['ĉs', 'ource'] +['Ġcz', 'as'] +['Ġre', 'cl'] +['ab', 'o'] +['Ġlocal', 'host'] +['Ġ^', '{Ċ'] +['.P', 'op'] +['ĠDes', 'igned'] +['\\', 'Abstract'] +['H', 'old'] +['ĠGuid', 'elines'] +['ipl', 'ine'] +['Ġc', 'aching'] +['.Re', 'ader'] +['_ext', 'ernal'] +['.str', 'ptime'] +['ĠWeek', 'end'] +['-M', 'ar'] +['ĠBe', 'i'] +['Ġ{*', '}'] +['ĠR', 'ud'] +['Ġexpl', 'or'] +['ĠBou', 'levard'] +['C', 'ash'] +['Ġprep', 'ares'] +['Ġserial', 'ization'] +['ew', 'ater'] +['Ġad', 'c'] +[':', 'ĊĊĊĊĊĊ'] +['Re', 'fer'] +['Ġsc', 'anned'] +['}', '}ĊĊ'] +['ĠF', 'ul'] +['Ġtour', 'ing'] +['ãĥĥ', 'ãĤ¯'] +['>', '(('] +['sur', 'vey'] +['Ġí', 'ĺ'] +['...', "')Ċ"] +['ĠDiv', 'ider'] +['os', 'l'] +['_C', 'ANCEL'] +['_pre', 'pare'] +['st', 'in'] +['ĠHe', 'ath'] +['.Primary', 'Key'] +['ĠâĨ', 'IJ'] +['ĠLocal', 'DateTime'] +['Ġcooper', 'ative'] +['L', 'earning'] +['.en', 'queue'] +['Ġgo', 'og'] +['ĠReg', 'ression'] +['im', 'ates'] +['Ġvoy', 'eur'] +['ĠDr', 'ink'] +['pl', 'ug'] +['Ġl', 'ender'] +['man', 'a'] +['Ġperson', 'nes'] +['yp', 'se'] +['Ġun', 'link'] +['ĠRav', 'ens'] +['Ġhur', 'd'] +['Ġperiod', 'ically'] +['ARG', 'S'] +['ĠG', 'H'] +['char', 'acters'] +['...', '"ĊĊ'] +['-', 'establish'] +['Ġd', 'n'] +['(', 'condition'] +['ĠGr', 'avity'] +['Ġest', 'as'] +['_f', 'ocus'] +['Creat', 'ure'] +['(s', 'ite'] +['Ġc', 'arr'] +['ĠR', 'L'] +['ĠR', 'I'] +['ĠM', 'oto'] +['AS', 'F'] +['ĠLuck', 'ily'] +['ĉ', 'Route'] +['Ġent', 'ropy'] +['("', ',"'] +['Col', 'lect'] +['(', 'contact'] +['ĠFlo', 'rence'] +['Ġpremium', 's'] +['Ġlif', 'ecycle'] +['Ġb', 'ans'] +['x', 'ef'] +['Web', 'Kit'] +['ĠFlo', 'ating'] +['Ġcos', 'a'] +['Spec', 'ific'] +['ĠLo', 'ans'] +['b', 'read'] +['Ġdes', 'criptors'] +['Ġ{', ':.'] +['TH', 'READ'] +['ĠT', 'rent'] +['Ġsc', 'op'] +['Q', 'A'] +['ĠAnt', 'ar'] +['p', 'el'] +['_d', 'ifference'] +['_ch', 'anges'] +['(...', ')'] +['ĠR', 'otation'] +['ĠLG', 'PL'] +['ĠJ', 'UST'] +['(T', 'ask'] +['_sub', 'set'] +['ĠTR', 'ANS'] +['åĬ', 'Ľ'] +['ĠSc', 'out'] +['-p', 'opup'] +['Ġsm', 'oked'] +['_C', 'lass'] +['Ġturn', 'over'] +['br', 'akk'] +['ĠRock', 'y'] +['t', 'as'] +['.Regular', 'Expressions'] +['ĠElli', 'ott'] +['ĠSp', 'inner'] +['DU', 'CTION'] +['Ġlib', 're'] +['Ġmol', 'to'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠ'] +['ĠF', 'TP'] +['m', 'peg'] +['(f', 'eatures'] +['Ġb', 'ald'] +['ĠV', 'id'] +['Ġsh', 'outing'] +['L', 'int'] +['Ġsock', 'ets'] +['Ġpro', 'w'] +['Ġnouvel', 'le'] +['isc', 'ard'] +['ĠS', 'ponsor'] +['Ġconsult', 'a'] +['))', ');'] +['Ind', 'ian'] +['ĠR', 'aspberry'] +['Ġteam', 'mate'] +['ĠJ', 'WT'] +['ĠGh', 'ana'] +['Ġc', 'akes'] +['pr', 'imer'] +['form', 'a'] +['erg', 'arten'] +['_M', 'anager'] +['Ġpre', 'season'] +['G', 'AME'] +['|', '"'] +['ĠBro', 'ck'] +['Ġoccup', 'y'] +['Ġdecor', 'ations'] +['á', 'nd'] +['Ġc', 'ot'] +['Ġpar', 'an'] +['D', 'isk'] +['rem', 'ain'] +['>', '?'] +['Str', 'ong'] +['Ġfr', 'ance'] +['ĠE', 'ra'] +['-c', 'r'] +['.Buffer', 'edReader'] +['ĠParad', 'ise'] +['ĠV', 'AT'] +['ĠAnd', 'ers'] +['Ġlim', 'b'] +['amp', 'oo'] +['Ġimper', 'ative'] +['UT', 'ILITY'] +['ĠRec', 'ognition'] +['Ġragaz', 'ze'] +['Ġpop', 's'] +['yp', 'ress'] +['Ġemb', 'argo'] +['//', '{Ċ'] +['Ġsy', 'll'] +['P', 'TR'] +['åŃĺ', 'åľ¨'] +['Ġdid', 'nt'] +['Mail', 'er'] +['Ġacad', 'emics'] +['ĠFra', 'uen'] +['ne', 'ider'] +['-', 'rel'] +['Ġrain', 'bow'] +['(', 'In'] +['Ġslic', 'ed'] +['============', '=Ċ'] +['(s', 'end'] +['NSMutable', 'Dictionary'] +['v', 'os'] +['(p', 'ackage'] +['Ġord', 'inance'] +['view', 'er'] +['ĠSant', 'os'] +['-s', 'elling'] +['Ġgo', 'v'] +['ett', 'le'] +['Ġfound', 'ers'] +['Ġw', 'aking'] +['sl', 'ashes'] +['-p', 'ound'] +['re', 'cht'] +['ا', 'ت'] +['.on', 'Click'] +['Ġn', 'ord'] +['st', 'änd'] +['_', 'when'] +['UT', 'ERS'] +['ic', 'c'] +['Ġcaps', 'ule'] +['ĠW', 'id'] +['M', 'arc'] +['à¸', '¸'] +['ro', 'red'] +['UG', 'E'] +['LO', 'UD'] +['ĠAud', 'it'] +['ip', 'ients'] +['op', 'ian'] +['ĠS', 'ue'] +['Ġwur', 'den'] +['.H', 'elpers'] +['Ġf', 'actions'] +['[', 'np'] +['-th', 'an'] +['Ġre', 'co'] +['Ġk', 'as'] +['Ġcmd', 's'] +['/n', 'etwork'] +['xb', 'f'] +['get', 'Color'] +['Ġbi', 'ased'] +['ĠL', 'ak'] +['D', 'atas'] +['vent', 's'] +['Ġë', '²'] +['_P', 'S'] +['.', 'Validate'] +['Inv', 'oker'] +['Ġne', 'uen'] +['Ġju', 'venile'] +['V', 'ISION'] +['Ġdev', 'ote'] +['Ġlin', 'ha'] +['Ġdiscount', 'ed'] +['\\', 'Config'] +['Ġworth', 'while'] +['Ġskin', 'ny'] +['ĠC', 'ourses'] +['le', 'ys'] +['ĠMort', 'gage'] +['K', 'evin'] +['Ġannounc', 'es'] +['])', '*'] +['res', 'ervation'] +['Ġæķ', '°'] +['Ġprejud', 'ice'] +['ĠString', 'Comparison'] +['Ġbe', 'ard'] +['-w', 'in'] +['ĠS', 'ão'] +['ĉ', 'ms'] +['j', 'al'] +['ĠE', 'arn'] +['_', 'ports'] +['ĠN', 'ombre'] +['_C', 'OR'] +['ĠB', 'UILD'] +['.s', 'ound'] +['Y', 'ellow'] +['Ġlineback', 'er'] +['Ġchar', 'itable'] +['j', 'ug'] +['_NON', 'NULL'] +['ĠD', 'ental'] +['">', '${'] +['ĉm', 'atch'] +['R', 'ussian'] +['Ġvers', 'ch'] +['Ġp', 'inned'] +['Ġadopt', 'ing'] +['Options', 'Menu'] +['P', 'ag'] +['Ġpair', 'ing'] +['Ġt', 'read'] +['erc', 'ises'] +['ĠSp', 'read'] +[')', 'i'] +['ĠB', 'AD'] +['_t', 'f'] +['UI', 'ImageView'] +['pop', 'ulate'] +['b', 'ab'] +['ĠÏ', 'ĥ'] +['[', '++'] +['Ġopi', 'oid'] +['Ġ##', 'Ċ'] +['d', 'type'] +['ĠStart', 's'] +["('/", "')"] +['Ġperson', 'als'] +['-mark', 'et'] +['Ġredund', 'ant'] +['ĠEss', 'ential'] +['Ġscrap', 'y'] +['Ġи', 'м'] +['a', 'cl'] +['Ġcre', 'ar'] +['ĠB', 'end'] +['Ġrel', 'ieve'] +['-', 'room'] +['w', 'ife'] +['Ġv', 'Ãł'] +['ĠQ', 'Point'] +['Ġqu', 'asi'] +['Ġmethod', 'Name'] +['\\x', 'c'] +['ĠPer', 'u'] +['/', 'The'] +['.', 'orm'] +['Ġv', 'iz'] +['/p', 'df'] +['Loc', 'ated'] +['Ġconfront', 'ation'] +['ĠChampionship', 's'] +['Ġhyp', 'ert'] +['Ġd', 'j'] +['ĠUser', 'Info'] +['ĠåĪ', 'Ľå»º'] +['\\x', 'b'] +['(s', 'im'] +['Ġ==', 'Ċ'] +['Ġst', 'aging'] +['Ġdr', 'astically'] +['åŃ', '¦'] +['l', 'ords'] +['.', 'less'] +['вед', 'иÑĤе'] +['ĠB', 'ucket'] +['ĠM', 'am'] +['.', 'term'] +['_p', 'i'] +['c', 'zy'] +['.p', 'ub'] +['prec', 'io'] +['ĠV', 'irt'] +['Ġrom', 'an'] +['it', 'at'] +['L', 'ex'] +['_inf', 'os'] +['Ä', '°'] +['.', 'other'] +['VE', 'LO'] +['Ġp', 'onder'] +['Ġh', 'anno'] +['(', 'Page'] +['do', 'i'] +['Ġpol', 'ite'] +['Ġprogram', 'mer'] +['D', 'ies'] +['$', 'd'] +['Ġrep', 'lication'] +['add', 'Column'] +['fr', 'ican'] +['Ġl', 'eng'] +['be', 'er'] +['o', 'it'] +['Ġw', 'asting'] +['yl', 'im'] +['me', 'asure'] +['N', 'eg'] +['Ġpart', 'ie'] +['.con', 'sole'] +['ĠGu', 'inea'] +['TE', 'L'] +['_f', 'act'] +['.ch', 'unk'] +['Ġl', 'ent'] +['Ġall', 'er'] +['Ġà¤', 'ķ'] +['_id', 'le'] +['Ġad', 'missions'] +['JSON', 'Array'] +['Ġv', 'ibration'] +['.h', 'elpers'] +['å¤', 'ĸ'] +['Ġh', 'en'] +['j', 'ohn'] +['Ġì', 'ĥĿ'] +['Ġjud', 'gement'] +['Ġge', 'en'] +['ter', 'ra'] +['^', '{'] +['ĠI', 'z'] +['Ġc', 'â'] +['inst', 'ances'] +['Ġthreat', 'ens'] +['Ġm', 'üssen'] +['Kind', 'OfClass'] +['Ġstoryt', 'elling'] +['_d', 'emo'] +['ri', 'as'] +['Priv', 'acy'] +['h', 'ift'] +['ĠY', 'i'] +['es', 'or'] +['íķ', 'ł'] +['ens', 'itivity'] +['.W', 'riter'] +['à¸', 'Ĥ'] +['D', 'istrict'] +['.get', 'JSONObject'] +['Im', 'pro'] +['(get', 'Resources'] +['ĠS', 'PELL'] +['rodu', 'ce'] +['Ġslow', 'ed'] +['Ġlin', 'ewidth'] +['Ġhonest', 'y'] +['ĠCo', 'ord'] +['ĠF', 'ork'] +['ĠDispatch', 'Queue'] +['ĠCl', 'iff'] +['ĠW', 'iring'] +['_TIM', 'ESTAMP'] +['oll', 'ah'] +['av', 'oid'] +['++', '];Ċ'] +['sem', 'antic'] +['-c', 'ss'] +['Ġv', 'eto'] +['ĠM', 'err'] +['Ġlegisl', 'ators'] +['CEE', 'DED'] +['Ġquestion', 'naire'] +['ĠP', 'ills'] +['Cal', 'culate'] +['(c', 'ore'] +["'", 'e'] +['Ġdis', 'like'] +['ĠPre', 'ferences'] +['_EX', 'TERNAL'] +['è°', 'ĥ'] +['Ġd', 'odge'] +['æľį', 'åĬ¡'] +['.n', 'ames'] +['.draw', 'Image'] +['_p', 'rom'] +['uck', 'land'] +['Ġ<$', '>'] +['ı', 'z'] +['/s', 'ite'] +['é¡', '¹'] +['rop', 'he'] +['Ġcomp', 'elled'] +['Ġl', 'aptops'] +['Ġun', 'i'] +['C', 'LOSE'] +['Ġcasual', 'ties'] +['ĠUn', 'iform'] +['Term', 'inal'] +['.', '","'] +['D', 'AT'] +['(T', 'reeNode'] +['ĠGand', 'hi'] +['(st', 'mt'] +['AX', 'B'] +['*', 'M'] +['Ġumb', 'rella'] +['an', 'imal'] +['Ġgr', 'pc'] +['Ġwhere', 'by'] +['Ġfloat', 's'] +['ĉ', 'arg'] +['Ġdb', 'g'] +['Ġexceed', 'ing'] +['Event', 'Type'] +['.SaveChanges', 'Async'] +['Ġ{', '{{'] +['Ġow', 'ed'] +['ahren', 'heit'] +['Ġì', '§'] +['Ġequ', 'ipo'] +['ur', 'ai'] +['Ġid', 'ol'] +[']', '")Ċ'] +['_m', 'ajor'] +['Ġentire', 'ty'] +['inger', 'print'] +['ç', 'os'] +['/', 'account'] +['ĉ', 'right'] +['urs', 'os'] +['ĠE', 'DT'] +['_INS', 'ERT'] +['Ġsh', 'ining'] +['Ġ<', ':'] +['Edge', 'Insets'] +['Ġcolon', 'ies'] +['.', 'IM'] +['ĉĠ', 'ĉ'] +['RO', 'AD'] +['CC', 'CC'] +['pl', 'acing'] +['Ġget', 'Activity'] +['em', 'acs'] +["'", '%('] +['.click', 'ed'] +['ĠTh', 'em'] +['is', 'ia'] +['Bus', 'car'] +['.re', 'name'] +['Ġo', 'ath'] +['Ġafter', 'ward'] +['ĠU', 'FO'] +['AP', 'S'] +['ĠJackson', 'ville'] +['.s', 'ome'] +['Conf', 'irmed'] +['.s', 'can'] +['ig', 'Integer'] +['Decor', 'ator'] +['sh', 'ield'] +['ress', 'ive'] +['.d', 'id'] +['请', 'è¾ĵåħ¥'] +['Ġsh', 'utter'] +['D', 'am'] +['Ġparent', 'ing'] +['ey', 'ed'] +['$', 'item'] +['-de', 'velop'] +['Ġextract', 's'] +['Ġdecentral', 'ized'] +['ĠEl', 'sa'] +['_sp', 'in'] +['])', '+'] +['-in', 'itial'] +['Ġmult', 'itude'] +['Ġsens', 'ory'] +['ĠMODE', 'L'] +['Ġsafeg', 'uard'] +['ì', '¹'] +['Ġhunt', 'ers'] +['ĠT', 'iny'] +['IN', 'O'] +['decor', 'ate'] +['ĠNo', 'Such'] +['H', 'o'] +['(', 'Response'] +['Ġr', 'uler'] +['ĉ', 'short'] +['Ġc', 'aster'] +['Ġclient', 'Id'] +['Ġp', 'db'] +['ëı', 'Ħ'] +['it', 'ic'] +['ĠGame', 'State'] +['Ġnew', 'Item'] +[')ĊĊ', 'ĊĊĊĊ'] +['ou', 'is'] +['n', 'oc'] +['.BL', 'ACK'] +['_V', 'ECTOR'] +['----------', '', '();'] +['.get', 'P'] +['any', 'e'] +['Ġneur', 'on'] +['if', 'old'] +['ĠK', 'nown'] +['Bit', 'coin'] +['Any', 'way'] +['ay', 'ette'] +["Ġ'", "['"] +['Ãł', 'nh'] +['m', 'gr'] +['Ġcor', 'related'] +['Ġn', 'ause'] +['Ġment', 'ality'] +['has', 'Many'] +['ĠF', 'G'] +['amp', 'ie'] +['IT', 'U'] +['F', 's'] +['.S', 'p'] +['_b', 'etween'] +['Dep', 'endencies'] +['ou', 'g'] +['Place', 'holder'] +['=', 'text'] +['ĠMan', 'aging'] +['ocal', 'ypse'] +['åĮ', 'Ĺ'] +['_m', 'ag'] +['f', 'ld'] +['â', 'ij'] +['C', 'AM'] +['ĠHelp', 'ers'] +['Ġd', 'ost'] +['/', 'out'] +['Ġassass', 'ination'] +['.get', 'Image'] +['ĠKenn', 'y'] +[".'", ')ĊĊ'] +['){', '//'] +['ĠR', 'anger'] +['Ġg', 'ek'] +['Ġsinc', 'ere'] +['<', 'Value'] +['ĠD', 'OT'] +['ĠVict', 'ory'] +['Ġleg', 'ends'] +['Ġpr', 'isons'] +['(ex', 'pression'] +['ĠR', 'abbit'] +['_s', 'entence'] +['Ġbit', 'es'] +['Ġon', 'Failure'] +['ĠâĪ', 'Ī'] +['K', 'im'] +['.g', 'ender'] +['ĠÎ', '»'] +['Ġ[', '.'] +['"]', ');'] +['land', 'ing'] +['-d', 'igit'] +['TE', 'MP'] +['ĉ', 'entry'] +['Ġstrt', 'ok'] +['Ġdesc', 'endants'] +['um', 'no'] +['Ġlean', 'ing'] +['Ġspecific', 's'] +['q', 'n'] +['ĠSp', 'art'] +['Ġpor', 'r'] +['EDIATE', 'K'] +['Ġse', 'per'] +["'", 'aut'] +['ĠSTE', 'P'] +['ĠBorder', 'Layout'] +['Ġret', 'ros'] +['ĠSalv', 'ador'] +['ĠEN', 'GINE'] +['x', 'dc'] +['T', 'weet'] +['v', 'k'] +['Ġì', '²'] +[']', '<<'] +['het', 'ics'] +['c', 'oding'] +['Re', 'ach'] +['.re', 'q'] +['gu', 'ide'] +['.s', 'cope'] +['sh', 'irt'] +['rog', 'ate'] +['SET', 'TING'] +['ĠProte', 'in'] +['Ġe', 'ing'] +['.', 'EMPTY'] +['.d', 'f'] +['Ġclear', 'er'] +['Ġc', 'rossover'] +['ĠTo', 'ys'] +['Ġco', 'ated'] +['.M', 'onth'] +['ĠAtt', 'ach'] +['/', 'run'] +['.t', 'abs'] +['Ġogs', 'Ã¥'] +['B', 'rown'] +['.D', 'ATE'] +['Ġf', 'os'] +['åŃĹ', '符'] +['W', 'ood'] +['-th', 'ree'] +['her', 'ited'] +['Ġ', 'rop'] +['(', 'ac'] +['Ġembod', 'iment'] +['ĠKenn', 'eth'] +['Ġcan', 'non'] +['Ġb', 'idding'] +['čĊ'] +['.get', 'Resources'] +['Ġl', 'ump'] +['_const', 's'] +['(', 'ext'] +['ĉd', 'ir'] +['â', 'Ŀ'] +['Ġpadding', 'Top'] +['Ġobs', 'ession'] +['Ġb', 'anning'] +['ĠApp', 'Module'] +['Ġpart', 'isan'] +['Ġcatalog', 'ue'] +['Ġmin', 'ors'] +['Ġpitch', 'es'] +['we', 'ep'] +['Ġundert', 'ake'] +['Ġthem', 'ed'] +['aud', 'it'] +['.scroll', 'Top'] +['Ġr', 'er'] +['Ġsympt', 'om'] +['Ġopen', 'ings'] +['.block', 's'] +['open', 'id'] +['Ġas', 'sh'] +['-s', 'ave'] +['ĠP', 'ig'] +['Ġreg', 'ain'] +['Ġin', 'icial'] +['/f', 'avicon'] +['ĉ', 'exp'] +['Ġsp', 'ices'] +['isk', 'a'] +['claim', 's'] +['m', 'ak'] +['definition', 's'] +['Ġcorrespond', 'ent'] +['ĠCann', 'abis'] +['__', ',Ċ'] +['ĠL', 'ucky'] +['ĠGa', 'ussian'] +['ĠN', 'early'] +['C', 'AD'] +["']", ']Ċ'] +['Ġadequ', 'ately'] +['ĠT', 'ITLE'] +['constitution', 'al'] +['-m', 'm'] +['_', 'override'] +['Ġbl', 'as'] +['.ready', 'State'] +['Ġremin', 'is'] +['Ġrein', 'forced'] +['ĠColl', 'abor'] +['Ġdecor', 'ating'] +['Ġb', 'achelor'] +['ERRU', 'PT'] +['Ġup', 'right'] +['ip', 'ation'] +['ĠNob', 'le'] +['Ġvalue', 'ForKey'] +['Ġset', 'Loading'] +['.I', 'gnore'] +['å', 'ģ'] +['G', 'lobals'] +['ĠM', 'ent'] +['AS', 'SES'] +['Ġlim', 'bs'] +['ĠH', 'UD'] +['inc', 'i'] +['.', 'iv'] +['ĠQ', 'ModelIndex'] +['F', 'use'] +['Ġped', 'al'] +['_F', 'REQ'] +['(', 'verbose'] +['Ġlong', 'itud'] +['ĠChar', 'ter'] +['ê', '·¸'] +['Ġbund', 'les'] +['.', 'ignore'] +['um', 'bo'] +['EM', 'A'] +['....', '...'] +['s', 'x'] +['.C', 'ard'] +['Ġhe', 'ute'] +['Ġste', 'er'] +['j', 'umlah'] +['Ġ{', '_'] +['_Check', 'ed'] +['Ġf', 'ax'] +['ĠG', 'ust'] +['itch', 'ens'] +['Ġ', '))ĊĊ'] +['Ġremark', 'ably'] +['/', 'XML'] +['-', 'remove'] +['_b', 't'] +['Ġinc', 'ub'] +['.p', 'ackage'] +['.current', 'Thread'] +['ĠHigh', 'lander'] +['.s', 'ide'] +['s', 'plash'] +['Ġ', 'ici'] +['=', 'D'] +['Ġp', 'uck'] +['Ġball', 'ots'] +['Ġhug', 'ely'] +['co', 'eff'] +['Ġp', 'Data'] +['.C', 'OLUMN'] +['ĠHe', 'aling'] +['Ġord', 'in'] +['!', '),'] +["Ġ'", "',čĊ"] +['(m', 'd'] +['ĠS', 'ask'] +['<', 'strong'] +['Ġsurviv', 'or'] +['.s', 'eries'] +['Ġcaffe', 'ine'] +['Ġ`', '('] +['.TRA', 'ILING'] +['_', 'Input'] +['("', '^'] +['z', 'd'] +['&', ');Ċ'] +['ĠP', 'ing'] +['Ġv', 'oucher'] +['.r', 'ating'] +['-sh', 'irts'] +['ĠRetrie', 'ves'] +['.al', 'ibaba'] +['Or', 'acle'] +['_MO', 'V'] +['Old', 'Data'] +['Ġ/*', 'čĊ'] +['Ġg', 'boolean'] +['Ġ=>', 'čĊ'] +['Ġr', 'á'] +['Ġbl', 'unt'] +['ĠImage', 'Icon'] +['if', 'ik'] +['RT', 'C'] +['Ġfib', 'ers'] +['Ġto', 'ile'] +['.s', 'ent'] +['ĠPy', 'Qt'] +['$', 'app'] +['Ġmed', 'io'] +['Ġgrant', 'ing'] +['Ġtsl', 'int'] +['ĠM', 'ö'] +['(fig', 'size'] +['Ġhur', 'ricane'] +['Ġlif', 'es'] +['ĠÃ', 'Ħ'] +['rocess', 'ing'] +['_st', 'andard'] +['-', 'option'] +["'))", ')'] +['Ġvac', 'ant'] +['å·', '¥'] +['ĠH', 'ollow'] +['handle', 'Change'] +['Ġdiv', 'ider'] +['ĠEngine', 'ers'] +['Ġsv', 'ens'] +['Ġcompl', 'iant'] +['t', 'anggal'] +['ĠC', 'redits'] +['ĠEm', 'irates'] +['Rule', 'Context'] +['Ġreal', 'ization'] +['Ġdistr', 'acted'] +[']+', '='] +['Ġaug', 'ment'] +['ĠD', 'w'] +['ot', 'p'] +['or', 'rent'] +['Edit', 'ar'] +['.st', 'ock'] +['St', 'udy'] +['pe', 'ctions'] +['ĠGame', 'Manager'] +['=', 'cut'] +['Ġf', 'lock'] +['ĠRom', 'ans'] +['th', 'em'] +['-h', 'op'] +['Ġscreens', 'hots'] +['Ġ/*', '!Ċ'] +['Ġconvers', 'ions'] +['Ġnormal', 'ization'] +['(config', 'uration'] +['Ġa', 'eros'] +['_se', 'curity'] +['!', "'Ċ"] +['B', 'onus'] +['ĠDR', 'IVER'] +['ĉ', 'Date'] +['t', 'ie'] +['ĠWy', 'oming'] +['St', 'and'] +['it', 're'] +['Ġsh', 'oppers'] +['Ġdisadv', 'antage'] +['Ġlik', 'ing'] +['ç¬', 'ij'] +['Ġunderstand', 'able'] +['SE', 'E'] +['Ġh', 'oy'] +['Ġnin', 'ete'] +['Ġcon', 'fer'] +['Ġnow', 'rap'] +['ĠV', 'ern'] +[',', 'čĊčĊ'] +['imest', 'ep'] +['Layout', 'Manager'] +['à', '·'] +['ĉw', 'ait'] +['PLE', 'TED'] +['J', 'apan'] +['Ġindu', 'ce'] +['Ġå', '¯'] +['оз', 'в'] +['_END', 'POINT'] +['.h', 'orizontal'] +['Ġacceler', 'ated'] +['rim', 'on'] +['IV', 'ES'] +['Trans', 'actions'] +['Le', 'an'] +['ĠSO', 'UR'] +['wh', 'ether'] +['y', 'g'] +['Ġo', 'id'] +['ĠEntity', 'Manager'] +['OUN', 'TRY'] +['Ġfil', 'a'] +['OLUM', 'NS'] +['IN', 'UE'] +['ĠAn', 'chor'] +['TR', 'AN'] +['wo', 'o'] +['block', 'quote'] +['ĠN', 'urse'] +['ĠCar', 'p'] +['Ġrede', 'em'] +['.', 'try'] +['ĠJ', 'P'] +['Ġtimestamp', 's'] +['Ġ?>', '"><'] +['ĠREM', 'OVE'] +['ĠStar', 'bucks'] +['Re', 'ally'] +['Ġflood', 'ed'] +['.C', 'allback'] +['Drop', 'Down'] +['ip', 'ro'] +['Ġt', 'ended'] +['l', 'te'] +['Ġproport', 'ions'] +['-', 'te'] +['ĠR', 'ena'] +['lic', 'ate'] +['for', 'ces'] +['.ex', 'tra'] +['.auth', 'enticate'] +['в', 'од'] +['¡', '°'] +['Ġfor', 'ControlEvents'] +['Ġsen', 'ha'] +['Ġke', 'in'] +['Ġmin', 'ist'] +['ĠPre', 'ference'] +['ĠTele', 'graph'] +['Ñĥ', 'п'] +['str', 'pos'] +['Ġillness', 'es'] +['Ġp', 'igs'] +['Ġget', 'Intent'] +['S', 'ol'] +['ĠÂ', '¡'] +['(c', 'pu'] +['[', 'prop'] +['s', 'creens'] +["');", '?>'] +['ĠAct', 's'] +['Ġstr', 'dup'] +['Ġaver', 'ages'] +['an', 'al'] +['ĠCas', 'ual'] +['Group', 'Box'] +['ĠHand', 'book'] +['/', 'comments'] +['Ġnumber', 'ed'] +['Ġbroadcast', 'ing'] +['çĽ', 'ij'] +['.native', 'Element'] +['.m', 'u'] +['Ġupdated', 'At'] +['ĠDoes', 'n'] +['.A', 'C'] +['.c', 'oll'] +['Ġrec', 'order'] +['_sh', 'a'] +['B', 'g'] +['b', 'il'] +['Ġbol', 'ts'] +['Ġç', '¬'] +['Ġim', 'posing'] +['ĠInformation', 'en'] +['_flash', 'data'] +['e', 'conomic'] +['Rem', 'ark'] +['uc', 'as'] +['ĠOff', 'icers'] +['ĠT', 'ER'] +['W', 'alk'] +['Ġmerc', 'ado'] +['_g', 'enerate'] +['H', 'Y'] +['Call', 'ing'] +['s', 'nap'] +['script', 'Id'] +['.', 'operation'] +['ĠFl', 'ame'] +['l', 'iness'] +['Ġrent', 'ed'] +['_t', 'oggle'] +['-ch', 'anging'] +['ĠT', 'Y'] +["'", 'util'] +['EE', 'P'] +['Ġgraph', 'ql'] +['ĠUn', 'i'] +['Ġimp', 'ulse'] +['.B', 'asic'] +['Ġenerg', 'ies'] +['M', 'ARY'] +['ĠMar', 'cel'] +['Ġmort', 'al'] +['Ġf', 'res'] +['m', 'ens'] +['m', 'otion'] +['Ġsample', 'd'] +['âĢľ', 'That'] +['id', 'ay'] +['qu', 'ipment'] +['get', 'Int'] +['ĠA', 'bsolute'] +[",'", '"'] +['un', 'ed'] +['.sh', 'are'] +['Ġ}', ')('] +['mm', 'm'] +['ĠR', 'ising'] +['ä»', '»'] +['Ġun', 'employed'] +['x', 'fa'] +['.f', 'ollow'] +['ĉĉĉĉ', 'ĠĠĠĠĠĠ'] +['sl', 't'] +['.P', 'hone'] +['Ġkn', 'ives'] +['Ġe', 've'] +['on', 'Click'] +[']', '))čĊ'] +['ĠW', 'itness'] +['ĉ', 'NS'] +['ĠE', 'OS'] +['ĠSte', 'fan'] +['ĠPri', 'est'] +['âĢĶ', 'which'] +['Get', 'String'] +['.', 'By'] +['Ġup', 'stairs'] +['Ġdetr', 'iment'] +['bro', 'ken'] +['emb', 'ro'] +['Ġnic', 'otine'] +['il', 'ion'] +['Ġaston', 'ishing'] +['_', 'aff'] +['ĠLess', 'on'] +['Ġaccident', 'al'] +['od', 'or'] +['Ġdec', 'ir'] +['Ġnew', 'Name'] +['+', '.'] +['çĽ', '¸'] +['igs', 'list'] +['ĠG', 'ithub'] +['Ġsuccess', 'ive'] +['rac', 'ial'] +['Ġen', 'viron'] +['éªĮ', 'è¯ģ'] +['Ġredirect', 'ed'] +['T', 'OTAL'] +['Ġgrab', 'bing'] +['ĠL', 'ance'] +['Ġfor', 'fe'] +['_C', 'B'] +['å¾', '®'] +['El', 'apsed'] +['_w', 'ay'] +['(Dialog', 'Interface'] +['_me', 'asure'] +['x', 'bb'] +['D', 'og'] +['Dep', 'art'] +['-s', 'rc'] +['res', 'olver'] +['with', 'standing'] +['_sh', 'ell'] +['ĠLast', 'Name'] +['ĠAv', 'iation'] +['Ġbegin', 'ner'] +['("%', '.'] +['(to', 'ol'] +['Ġн', 'ов'] +[':', 'init'] +['(A', 'PI'] +['ĠMorr', 'ison'] +['vt', 'Color'] +['Ġstap', 'le'] +['/', 'INFO'] +['Ġsupern', 'atural'] +['Ġste', 'ak'] +['tim', 'eline'] +['zz', 'le'] +['"', '`ĊĊ'] +['Second', 'ary'] +['ĠNep', 'al'] +['.String', 'Utils'] +['Ġad', 'am'] +['Ġ(', '...'] +['Ġsub', 'stitution'] +['Ġboard', 'ing'] +['ĠKey', 'word'] +['ĠAss', 'ault'] +['dbc', 'Template'] +['Ġorder', 'Id'] +['(', 'engine'] +['.assert', 'That'] +['ĠVen', 'us'] +['Ġhomic', 'ide'] +['ĠA', 'val'] +['Ġg', 'utter'] +['ĠSupport', 'ed'] +['/p', 'art'] +['Ġac', 'claimed'] +['H', 'istor'] +['Ġmes', 'es'] +['ü', 'ber'] +['ĠRen', 'ew'] +['Ġgr', 'as'] +['ĠE', 'k'] +['Ġin', 'file'] +['ind', 'y'] +['.m', 'usic'] +['.S', 'croll'] +['ĠA', 'ges'] +['ĠNar', 'uto'] +['ĠG', 'ather'] +['Ġconfirm', 'ing'] +['=', '("'] +['Ġpitch', 'ed'] +['ole', 'y'] +['Fr', 'ance'] +["+'", '"'] +['$', 'total'] +['Ġon', 'de'] +['Ġd', 'itch'] +['_s', 'igma'] +['Ġcontinu', 'ity'] +['re', 'ward'] +['-', 'load'] +['Ġproces', 'o'] +['Lock', 'ed'] +['st', 'aw'] +['Ġsp', 'inal'] +['l', 'azy'] +['!', '=='] +['j', 'est'] +['Ġd', 'un'] +['ĠRod', 'gers'] +['ĉ', 'grid'] +['Ġlog', 'os'] +['ĠBeng', 'al'] +['.s', 'uper'] +['Provid', 'es'] +['Ġnut', 'rient'] +['.T', 'imestamp'] +['IZ', 'ATION'] +['åĨ', 'Į'] +['Ġf', 'ats'] +['ĠX', 'xx'] +['ct', 'ica'] +['Target', 's'] +['Ġcont', 'ours'] +['Ġre', 'ordered'] +[':', 'Array'] +['Ġtoler', 'ate'] +['V', 'ir'] +['Ġter', 'ribly'] +['Ġbr', 'icks'] +['(&', '_'] +['h', 'b'] +['Port', 'al'] +['ĠB', 'read'] +['.', 'which'] +['ÂŃ', 't'] +['as', 'InstanceOf'] +['Ġj', 'object'] +['ĉ', 'length'] +['_M', 'T'] +[';', '">čĊ'] +['_EX', 'IST'] +['Ġmat', 'ernal'] +['RE', 'L'] +['Ġê²½', 'ìļ°'] +['he', 'e'] +['Ġlayout', 's'] +['ĠL', 'ap'] +['ais', 'y'] +['Ġst', 'umbled'] +['ĠU', 'IG'] +['ĠS', 'co'] +['Ġimp', 'aired'] +['RES', 'SED'] +['Ġab', 'uses'] +['V', 'F'] +['AR', 'B'] +['.N', 'AME'] +['r', 'ch'] +['prim', 'ir'] +['_com', 'pleted'] +['Ġp', 'enny'] +['Ch', 'rome'] +['(b', 'egin'] +['ern', 'en'] +['-', 'checkbox'] +['Plain', 'OldData'] +['ĠL', 'PC'] +['r', 'ade'] +['sp', 'ir'] +['Ġcon', 'ceived'] +['T', 'ips'] +['ĠIo', 'T'] +['ĠG', 'an'] +['èģ', 'Ķ'] +['Ġbi', 'ases'] +['Ġconsult', 'ants'] +['ple', 'd'] +['_', 'ht'] +['associ', 'ated'] +['],', 'ĊĊ'] +['Ġdelight', 'ful'] +['ĠÑĤ', 'ек'] +['Hel', 'vetica'] +['(', 'load'] +['-exp', 'and'] +['_W', 'IDGET'] +['to', 'a'] +['ĠA', 'kt'] +['Ġom', 'n'] +['Ġcl', 'auses'] +['Int', 'el'] +['*/', '}Ċ'] +['_reg', 'istration'] +['Ġold', 'Value'] +['Ġrest', 'oring'] +['Ġun', 'real'] +['O', 'VER'] +['ĉĊĉĊ', 'ĉĊ'] +['AT', 'S'] +['_pro', 'be'] +['Ġdiv', 'isor'] +['.update', 'Dynamic'] +['å¹', '³'] +['Produ', 'ces'] +['st', 'amp'] +['.j', 'boss'] +['ĉt', 'ask'] +['!', '(:'] +['Ġpsych', 'ic'] +['@', 'class'] +['M', 'artin'] +['ĠPass', 'ed'] +['clar', 'ations'] +['h', 'el'] +['а', 'Ñĩ'] +['ĉc', 'opy'] +['-b', 'in'] +['z', 'an'] +['ig', 'ram'] +['া', 'à¦'] +['(s', 'ig'] +['ĠC', 'aval'] +['_', '##'] +['Ġ%', '='] +['out', 'lined'] +['ĠAc', 'id'] +['Ġunpredict', 'able'] +['-d', 'ashboard'] +['Hex', 'String'] +['+', 'c'] +['.P', 'ublic'] +['áº', '©'] +['Ġconvey', 'or'] +['ĠE', 'B'] +['Ġselect', 's'] +['Ġknock', 'ing'] +['ĠC', 'ec'] +['IBUT', 'ES'] +['owa', 'Äĩ'] +['g', 'atsby'] +['*', 'v'] +['ent', 'ropy'] +['Ġdispatch', 'ed'] +['Ġcam', 'el'] +['ĠSat', 'urn'] +['Ġover', 'weight'] +['(', 'phone'] +['par', 'able'] +['%', 'B'] +['_v', 'ectors'] +['Ġbrew', 'ing'] +['ĠT', 'k'] +['ĠDownload', 's'] +['ĠS', 'aved'] +['.Pr', 'ice'] +['Ġcur', 'ved'] +['ĠParen', 'thood'] +['è', '¶'] +['.p', 'nl'] +['plet', 'ely'] +['.D', 'ay'] +['Ġadvertis', 'ers'] +['Ġej', 'ec'] +['Ġpr', 'zed'] +['ë', '¯'] +['!', "';Ċ"] +['ĠK', 'ush'] +['ĠT', 'AB'] +['Ġquest', 's'] +['Ġcoinc', 'idence'] +['umm', 'ies'] +['ĠKash', 'mir'] +['ĠEth', 'ics'] +['_g', 'rowth'] +['Ġakt', 'iv'] +['Ġgroup', 'ing'] +['å¢', 'ŀ'] +['_tr', 'uth'] +['åIJ', '¬'] +['t', 'odos'] +['is', 'et'] +['Tex', 'Coord'] +['ä', 'tt'] +['ĠZ', 'ur'] +['ro', 'ys'] +['_M', 'AGIC'] +['Ġbrew', 'ery'] +['(', 'State'] +['ĠSM', 'ALL'] +['ĠPl', 'ants'] +['it', 'bart'] +['each', 'er'] +['ĠAd', 'elaide'] +['L', 'u'] +['Ġf', 'ick'] +['und', 'les'] +['_load', 'ed'] +['и', 'е'] +['P', 'oll'] +['rit', 'ic'] +['EL', 'Y'] +['Ġ+', "'"] +['ĠProf', 'ession'] +['Ġst', 'amps'] +['ĠS', 'ew'] +['scroll', 'View'] +['Ġcomm', 'unist'] +['/pro', 'blems'] +['}čĊčĊ', 'čĊčĊ'] +[',', 'o'] +['Ġu', 'dp'] +['Ġob', 'ese'] +['appro', 've'] +['ancell', 'ation'] +['_G', 'ame'] +['ĠHas', 'htable'] +['adaptive', 'Styles'] +['Ġpossess', 'es'] +['.match', 'er'] +['function', 'al'] +['M', 'rs'] +['ĉs', 'ave'] +['ĠDb', 'Type'] +['Ġk', 'en'] +['get', 'Context'] +['Ġm', 'ans'] +['(', 'rel'] +['ĠBrother', 'hood'] +[')', '`Ċ'] +['è§', '£'] +['.In', 'formation'] +['OutOfRange', 'Exception'] +['ĠS', 'ek'] +['C', 'as'] +['Ġblog', 'gers'] +['E', 'ither'] +['("', '""'] +['Ġpin', 'ch'] +['Ġco', 'arse'] +[')', 'p'] +['ĠP', 'ulse'] +['Ġlear', 'nt'] +['Ġdent', 'ist'] +['Ġon', 'change'] +['Ġdirect', 'ives'] +['(', 'actions'] +['ny', 'der'] +['ĠSh', 'ir'] +['T', 'rait'] +['_de', 'p'] +['ĠP', 'ET'] +['ĠRE', 'P'] +['.App', 'Settings'] +['cu', 'ador'] +['iden', 'av'] +['Ġenv', 'i'] +['Ġsl', 'ammed'] +['ĠSh', 'oot'] +['Ġdate', 'Format'] +['.j', 'oda'] +['ve', 'ys'] +['Ġ)', '.ĊĊ'] +['Ġcare', 'g'] +['ĠPar', 'allel'] +['_', 'translation'] +['.function', 's'] +['.', 'obs'] +['Runtime', 'Exception'] +['[]', '='] +['over', 'view'] +['ĠSch', 'l'] +['Ġno', 'isy'] +['ĠOn', 'PropertyChanged'] +['S', 'ending'] +['Ġunf', 'amiliar'] +['U', 'pon'] +['ĠPrint', 's'] +['.t', 'yp'] +['Ġflee', 'ing'] +['ĉm', 'ove'] +['(', 'Un'] +['Ġq', 'r'] +['×', 'ľ'] +['_b', 'eta'] +['Ġsk', 'ies'] +['ĉm', 'e'] +['W', 'ND'] +['Ġstick', 'ers'] +['bl', 'as'] +['Ġinsert', 's'] +['Ġvers', 'es'] +['ĠD', 'ew'] +['Ġtang', 'ible'] +['Ġhe', 'cho'] +['P', 'OL'] +['Ġte', 'ardown'] +['om', 'nia'] +['IB', 'E'] +['.c', 'over'] +['_str', 'ategy'] +['^', '-'] +['set', 'Position'] +['u', 'ale'] +['S', 'igned'] +['Ġif', 'ace'] +['as', 'eline'] +['.set', 'Time'] +['ĠMin', 'eral'] +['ĠFight', 'ing'] +['sk', 'ins'] +['Ġdiscrim', 'in'] +['Ġdans', 'k'] +['ĠPr', 'inceton'] +['ac', 'ist'] +['Ġ(', '));Ċ'] +['tr', 'acks'] +['imon', 'ial'] +['ad', 'ecimal'] +['EP', 'ROM'] +['ugg', 'le'] +['.Not', 'ification'] +['$', 'mail'] +['c', 'antidad'] +['ĠJ', 'ung'] +['Ġseek', 'ers'] +['Ġpl', 'ausible'] +['t', 'ier'] +['еÐ', '¶'] +['Ġr', 'apper'] +['ĠMan', 'a'] +['ĠHttp', 'StatusCode'] +['Ġburn', 't'] +['los', 'es'] +['ĠF', 'oto'] +['ĠJson', 'Object'] +['Inst', 'agram'] +['Ġsys', 'call'] +['Ġreal', 'ities'] +['ĠMAT', 'LAB'] +[':^', '{Ċ'] +['TER', 'M'] +['ĠC', 'bd'] +['ĠPar', 'agraph'] +['Ġtrav', 'és'] +['Ġconstruct', 'ing'] +['Ġsw', 'al'] +['Ġp', 'ige'] +['LL', 'LL'] +['-ex', 'isting'] +['G', 'ets'] +['Ġmelt', 'ed'] +['Ġmitig', 'ate'] +['H', 'en'] +['Ġh', 'm'] +['im', 'as'] +['ĠA', 'o'] +['ĠP', 'erez'] +['ĠD', 'AL'] +['Ġëĭ', '¤'] +['Ġdiv', 'is'] +['Storyboard', 'Segue'] +['ĠMod', 'ify'] +['ĠÃľ', 'ber'] +['_O', 'VERRIDE'] +['.p', 'em'] +['unt', 'os'] +['Ġespa', 'ñ'] +['Ġ{', '?'] +['ĠP', 'AY'] +['_ip', 'v'] +['ĠF', 'ury'] +['__', '.__'] +['el', 'ow'] +['-center', 'ed'] +['check', 's'] +['_', 'Reg'] +['-J', 'avadoc'] +['ĉ', 'load'] +['ĠLik', 'ewise'] +['ا', 'Ùħ'] +['UN', 'E'] +['.se', 'm'] +['x', 'cb'] +['ĠC', 'ave'] +['_s', 'leep'] +['Ġsil', 'ently'] +['ĠExt', 'reme'] +['.To', 'Upper'] +['ĉC', 'HECK'] +['Ġc', 'ue'] +['ĠQ', 'ByteArray'] +['Ġcorrupt', 'ed'] +['ĠD', 'é'] +['Ġimp', 'ed'] +['Get', 'Name'] +['Ġinaccur', 'ate'] +['Ġso', 'ber'] +['е', 'е'] +['Ġbar', 'code'] +['--', '){Ċ'] +['ink', 'i'] +['Ġé', 'p'] +['Ġd', 'ri'] +['ĠAL', 'T'] +['>>>>', '>>>>'] +['ont', 'a'] +['[', 'L'] +['Ġinter', 'es'] +['ver', 'ting'] +['Ġdi', 'agnostics'] +['p', 'dev'] +['è', '©'] +['ĠIntegr', 'ated'] +[').', "'"] +['_g', 'c'] +['$', 'text'] +['.g', 'ames'] +['ĠT', 'erra'] +["'", 'Re'] +['.trans', 'fer'] +['_F', 'IFO'] +['get', 'Model'] +['Ġbl', 'and'] +['ĠCole', 'man'] +['Ġpr', 'imes'] +['Ġæ', 'Ī'] +['Ġcross', 'es'] +['n', 'k'] +['G', 'ING'] +["Ġ'", '^'] +['ĠB', 'lob'] +['Ġinter', 'course'] +['ĠBl', 'vd'] +['Ġweigh', 's'] +['_reg', 'ular'] +['ĠPer', 'th'] +['Ġsepar', 'ating'] +['Ġb', 'illed'] +['.tab', 'Control'] +['Ġpup', 'pet'] +['Ġutil', 'ization'] +['Ġâĸ', 'ł'] +['Ġsucc', 'es'] +['Ġl', 'amps'] +['_pro', 'j'] +['E', 'ric'] +['Ġren', 'ovation'] +['ĠFam', 'ilies'] +['ĠB', 'its'] +['part', 'ials'] +['-M', 'en'] +['s', 'olution'] +['Ġd', 'warf'] +['.IN', 'TEGER'] +['ĠLO', 'CK'] +['.', 'ct'] +['Ġexcer', 'pt'] +['ĠP', 'ix'] +['ĠFirst', 'Name'] +['ANT', 'ED'] +['ĠAd', 'mir'] +['-h', 'elp'] +['P', 'rior'] +['ĠAl', 'ign'] +['.IN', 'STANCE'] +['Line', 'Edit'] +["('/", ':'] +['Ġin', 'et'] +['od', 'us'] +['.p', 'kl'] +['ĠK', 'Y'] +['up', 'ert'] +['Ġn', 'erves'] +['_grad', 'ient'] +['}', "','"] +['_un', 'ref'] +['Ġs', 'aturated'] +['ĠConn', 'ected'] +['ĠF', 'N'] +['EX', 'IT'] +['Ġtele', 'port'] +['Ġav', 'ait'] +['Page', 'Route'] +['Ġdivor', 'ced'] +['(l', 'ang'] +['f', 'st'] +['ĠT', 'yr'] +['Ġmess', 'enger'] +['if', 'stream'] +['X', 'S'] +['ĠBank', 'ing'] +['Ġinfect', 'ious'] +['ĠM', 'ons'] +['_LO', 'OP'] +['Ġzur', 'ück'] +['Ġobt', 'ener'] +['/re', 'pos'] +['V', 'el'] +['ac', 'ro'] +['Ġuser', 'Repository'] +['style', 'Type'] +['ĠS', 'RC'] +['VML', 'INUX'] +['rec', 'ursive'] +['/', 'bar'] +['_ch', 'ip'] +['omin', 'ated'] +['ĠN', 'it'] +['âĢĶ', 'to'] +['ĠBudd', 'h'] +['ом', 'еÑĢ'] +['ĠM', 'AG'] +['ĠC', 'HE'] +['_d', 'en'] +['.', 'raises'] +['_de', 'gree'] +['Ġpump', 'kin'] +['_tem', 'plates'] +['_M', 'EDIA'] +['ĠTim', 'eline'] +['Ġb', 'ots'] +['Object', 'Type'] +['Ġbu', 'ys'] +['.post', 's'] +['C', 'AL'] +['wait', 'ing'] +['ĠDani', 'els'] +['Ġd', 'abei'] +['ĠS', 'igma'] +['il', 'or'] +['ig', 'el'] +[',', 'W'] +['AD', 'S'] +['(', 'panel'] +['ì²', '´'] +['it', 'ating'] +['.p', 'alette'] +['Ġmos', 'quito'] +['Ġt', 'ego'] +['(parse', 'Int'] +['Ġdes', 'pués'] +['p', 'romise'] +['Ġw', 'ij'] +['types', 'cript'] +['ĠT', 'v'] +['_IDENT', 'IFIER'] +[').ĊĊ', 'Ċ'] +['_fl', 'at'] +['its', 'u'] +['US', 'R'] +['ex', 'perience'] +['-f', 'it'] +['ph', 'inx'] +['_th', 'resh'] +['Ġide', 'ally'] +['ĠFre', 'eman'] +[',', 'DB'] +['_r', 'w'] +['çŃ', 'ī'] +['U', 'b'] +['_stat', 'istics'] +['="', '"><'] +['Ġch', 'ore'] +['Ġy', 'ork'] +['inst', 'alled'] +['Add', 'itionally'] +['Ġp', 'stmt'] +['yl', 'ko'] +['::', 'Ċ'] +['Fore', 'st'] +['Ġhead', 'set'] +['Ġgall', 'on'] +['ÑĢ', 'ем'] +['Ġwithdraw', 'n'] +['ĠC', 'andidate'] +['Ġmel', 'ting'] +['Ġfree', 'zer'] +['Ġh', 'l'] +['_HE', 'LP'] +['m', 'ime'] +['(', '/*'] +['Ġth', 'irst'] +['$', 'return'] +['member', 'of'] +['еÐ', '±'] +['ĠHttp', 'ServletRequest'] +['(', 'ob'] +['_', 'Result'] +['Ġassert', 'ed'] +['Ġfulfill', 'ing'] +['Ġstret', 'ches'] +['par', 'ated'] +['-f', 'unded'] +['Ġå', 'Ľ'] +['ing', 'les'] +['_c', 'a'] +['.', 'condition'] +['ĠDis', 'plays'] +['Ġor', 'ang'] +['ĠC', 'RE'] +['Ġgl', 'Bind'] +['ĠSelect', 'or'] +['/', 'type'] +['ĠAlex', 'a'] +['ched', 'ules'] +['ĠPen', 'insula'] +['Ġpar', 'ity'] +['ĉ', 'dest'] +['ĠDo', 'ors'] +['čĊ', 'ĉčĊ'] +['_dim', 'ension'] +['Ġa', 'load'] +['.St', 'oredProcedure'] +['(p', 'aren'] +['ĠBur', 'ke'] +["')", ']Ċ'] +['-', 'engine'] +['Ġqu', 'ir'] +['ĠHy', 'brid'] +['ĠDo', 'e'] +['Ġout', 'lines'] +['ĠTrend', 's'] +['_N', 'V'] +['per', 'iments'] +['ĠH', 'in'] +['?', "',"] +['ĉ', 'Text'] +['F', 'UL'] +['Ġsm', 'ells'] +['Ġs', 'lick'] +['Ġmis', 'erable'] +['ĠArray', 'Adapter'] +['Ġparam', 'String'] +['H', 'om'] +['_l', 'iterals'] +['us', 'uarios'] +['Ġprompt', 'ing'] +['_l', 'azy'] +['ĠActiv', 'ation'] +['_', 'oc'] +['We', 'ak'] +['Ġan', 'ecd'] +['ĠU', 'CLA'] +['=', 're'] +['isse', 'ment'] +['ĠEsc', 'orts'] +['Ex', 'cellent'] +['ĠP', 'ause'] +['Ġre', 'positories'] +['T', 'OR'] +['ari', 'ate'] +['_is', 'o'] +['up', 'dates'] +['hal', 'b'] +['udi', 'ante'] +['ë¡', 'Ŀ'] +['Ġna', 'ive'] +['ĠP', 'eg'] +['ĠL', 'ounge'] +['ARG', 'IN'] +['(b', 'in'] +['On', 'ClickListener'] +['ĠFA', 'ILED'] +['Ġl', 'ite'] +['Ġd', 'zie'] +['ĠL', 'iteral'] +['iv', 'or'] +['fc', 'ntl'] +['Ġe', 'ats'] +['Ġq', 'ed'] +['Un', 'lock'] +['rid', 'ing'] +['und', 'ai'] +['=', 'M'] +['AT', 'TER'] +['Configure', 'Await'] +['ici', 'as'] +['ustom', 'ed'] +['Ġsuccess', 'ion'] +['end', 'Time'] +['ĠJ', 'upiter'] +['Ġjud', 'ging'] +['d', 'ration'] +['_d', 'ocs'] +['.m', 'o'] +['Ġeduc', 'ators'] +['ĠV', 'ine'] +['Con', 'd'] +['[', 'out'] +['q', 'b'] +['\\', 'Validator'] +['Ġmean', 'ings'] +['Ġpresent', 'ly'] +['Ġdiv', 'iding'] +['otten', 'ham'] +['asc', 'ular'] +['Ġtrail', 'ers'] +['ĠC', 'LOSE'] +['ам', 'и'] +['âĢĻ', 'ai'] +['ĠG', 'ain'] +['w', 'or'] +['Ġpl', 'anner'] +['Ġdistrib', 'uting'] +['v', 'at'] +['month', 's'] +['x', 'label'] +['H', 'F'] +['V', 'iol'] +['.BASE', 'LINE'] +['еÑĤ', 'ÑģÑı'] +['ĠR', 'otate'] +['Ġtx', 'n'] +[':', 'bold'] +['Ġb', 'loss'] +['Forg', 'ery'] +['(', 'embed'] +['Ġjak', 'o'] +['s', 'printf'] +['the', 'ir'] +['Ġexhib', 'its'] +['-', 'static'] +['he', 'cy'] +['get', 'ActiveSheet'] +['.c', 'lients'] +['ãģ', 'į'] +['_h', 'ide'] +['[', 'word'] +['C', 'b'] +['add', 'Item'] +['ax', 'e'] +['_r', 'adio'] +['al', 'ion'] +['mod', 'ifier'] +['Ġsat', 'uration'] +['Ġden', 'om'] +['_p', 'ixels'] +['m', 'ess'] +['(f', 'l'] +['at', 'if'] +['Ġse', 'cs'] +['Ġpro', 'stitution'] +['Ġgrand', 'children'] +['Ġparad', 'ise'] +['ĠF', 'eld'] +['_B', 'INARY'] +['it', 'ous'] +['à¹', 'Ħ'] +['Ġflash', 'ing'] +['-s', 'ided'] +['Ġcontrad', 'iction'] +['/*', 'ĊĊ'] +['y', 'label'] +['ĠT', 'et'] +['Ġadm', 'ire'] +['res', 'o'] +['Ġlet', 'z'] +['ĠSE', 'ARCH'] +['sl', 'ots'] +['ĠRew', 'ards'] +['ĠH', 'og'] +['ĠNS', 'Data'] +['st', 'ash'] +['F', 'all'] +['ĠA', 'mer'] +['Line', 'arLayout'] +['/', 'photos'] +['Ġfe', 'ather'] +['Ġ|', 'čĊ'] +['Download', 's'] +['.Start', 'sWith'] +['Ġ//', '#'] +['ine', 'Transform'] +['Ġaff', 'id'] +['V', 'tbl'] +['ĠRog', 'ue'] +['scri', 'bed'] +['Ġfa', 'uc'] +['ĠMon', 'roe'] +['Ġdecl', 'ares'] +['mod', 'ern'] +['re', 'on'] +['ay', 'be'] +['P', 'ASS'] +['f', 'ers'] +['_MULT', 'I'] +['ĠMath', 'ematics'] +['Ġsud', 'ah'] +['_ATT', 'ACH'] +['Ġnumber', 'With'] +['ĠSol', 'omon'] +['j', 'in'] +['ograf', 'ia'] +['ö', 'l'] +['_d', 'esign'] +['cul', 'ated'] +['ĠL', 'una'] +['ies', 'z'] +['Ġ=>', "'"] +['Ġrevel', 'ations'] +['Al', 'ong'] +['(', 'ed'] +['ĠF', 'ilename'] +['Ġy', 'label'] +['Sec', 'ure'] +['Ġbus', 'ca'] +['agn', 'osis'] +['_RE', 'CE'] +['Ġoverl', 'apping'] +['Ext', 'ent'] +['Ġanticip', 'ation'] +['Check', 's'] +['ĠALS', 'O'] +['or', 'c'] +['iling', 'ual'] +['it', 'ational'] +['Ġadv', 'ancement'] +['ou', 'ro'] +['ĠP', 'redicate'] +['å¾', 'Ĺ'] +['er', 'ia'] +['ĠPier', 'ce'] +['or', 'io'] +['Ġmer', 'its'] +['Ġpe', 'anut'] +['.P', 'ackage'] +['ĠCon', 'duct'] +['_SENS', 'OR'] +['Ġbo', 'iling'] +['Ġin', 'tra'] +['ĠI', 'GN'] +['ĠF', 'ur'] +['.Ref', 'resh'] +['ĠRe', 'ach'] +['_dec', 'oder'] +['.Ex', 'p'] +['ĠÑĤ', 'ак'] +['p', 'ill'] +[',', 'Q'] +['ĠGr', 'ill'] +['Ġpop', 'ping'] +['.A', 'g'] +['Ġpro', 'yecto'] +['Ġmile', 'age'] +['Ġec', 'ological'] +[']', ']);Ċ'] +['ĠÂ', 'Ń'] +['sub', 'plot'] +['ac', 'ad'] +['ĠTry', 'ing'] +['rec', 'ipes'] +['$', 'criteria'] +['ĠPers', 'ian'] +['-b', 'ound'] +['M', 'ASK'] +['ĠG', 'esture'] +['Ġk', 'k'] +['ĠP', 'VC'] +['Ġprohib', 'ition'] +['Ġcom', 'ando'] +['ĠLO', 'OK'] +['Sh', 'opping'] +['Ġdist', 'ortion'] +['<', 'Boolean'] +['.Get', 'Length'] +['um', 'pt'] +['\\', 'Product'] +['ell', 'ery'] +['Ġfire', 'wall'] +['form', 'atted'] +['.red', 'is'] +['Ġes', 'a'] +['ĠRh', 'ode'] +['S', 'om'] +['.n', 'on'] +["Ġ'", ').'] +['Ġget', 'View'] +['ạ', 'n'] +['pr', 'us'] +['Mat', 'thew'] +['Ġs', 'ia'] +['ĠF', 'ors'] +['G', 'PU'] +['ient', 'ras'] +['_IN', 'ST'] +['Ġol', 'arak'] +['Ġimport', 'ing'] +['T', 'CP'] +['/', '");Ċ'] +['e', 'ither'] +['Ġfresh', 'ly'] +['c', 'ascade'] +['(char', 'acter'] +['ĠJe', 'ep'] +['ot', 'ics'] +['_', 'UTIL'] +['.Xtra', 'Printing'] +['.first', 'Child'] +['ĠEx', 'cell'] +['Ġd', 'vd'] +['Ġt', 'aller'] +['Ġr', 'as'] +['yp', 'ass'] +['Ġassign', 's'] +['Ġgri', 'ev'] +['-m', 'ore'] +['J', 'D'] +['ĠBurn', 's'] +["'", '>čĊ'] +['.D', 'ependency'] +['.Query', 'String'] +['.O', 'wner'] +['Ġexp', 'iry'] +['Th', 'u'] +['(', 'Vec'] +['Ġhazard', 'ous'] +['Ġr', 'pm'] +['AP', 'ON'] +['Ġadd', 'Target'] +['sv', 'ille'] +['p', 'Net'] +['ĠIm', 'g'] +['ĠTIM', 'ER'] +['.An', 'imation'] +['Ġbe', 'k'] +['Ġass', 'ort'] +['Ġle', 'bih'] +['Ġbody', 'Parser'] +['Ġvibr', 'ating'] +['ID', 'L'] +['Ġbutter', 'knife'] +['int', 'ers'] +['Ġpersu', 'ade'] +['ĠLGBT', 'Q'] +['è', 'ĭ'] +['.s', 'oft'] +['Ġbe', 'ams'] +['_s', 'ur'] +['.D', 'ef'] +['Ġl', 'abs'] +['ĉ', 'plt'] +['Ġsk', 'ins'] +['Ġtransf', 'erring'] +['Ġimag', 'inary'] +['_E', 'nd'] +[';', 'background'] +['Ġl', 'aps'] +['_COM', 'MENT'] +['(S', 'DL'] +['ond', 's'] +['.Rec', 'ord'] +['ĠIm', 'plements'] +['_t', 'icks'] +['()', '))ĊĊ'] +['Ġa', 'rose'] +[']', '?'] +['ĠM', 'p'] +['ĠI', 'Command'] +['Ġsculpt', 'ure'] +['Ġcontract', 'ed'] +['<', 'HTML'] +['Ġcal', 'end'] +['at', 'y'] +['/', 'Sub'] +['Ġkv', 'inn'] +['_', 'IGNORE'] +['ĠSh', 'ane'] +['ML', 'S'] +['Ġstim', 'ulate'] +['Part', 'ition'] +['Ġm', 'un'] +['ó', 'm'] +['eral', 'a'] +['-', 'account'] +['.B', 'inary'] +['c', 'é'] +['Ġse', 'ize'] +['connection', 's'] +['ĠĊ', 'ĠĠĠĠĠĠĠĠĊ'] +['ĠDi', 'agnostic'] +['V', 'ISIBLE'] +['ĠRun', 's'] +['Ġimpress', 'ions'] +['s', 'uite'] +['ob', 'le'] +['~', '-'] +['ak', 'ukan'] +['<', 'Person'] +['ĠN', 'os'] +['ĠG', 'ui'] +['.wait', 'For'] +['RE', 'SET'] +['Ġpost', 'pon'] +['Dis', 'cover'] +['arr', 'ison'] +['sh', 'aw'] +['b', 'lood'] +['AJ', 'OR'] +['æĽ´', 'æĸ°'] +['ĠM', 'use'] +['æĶ', '¶'] +['Ġret', 'aining'] +['ot', 'te'] +['Ġmos', 'que'] +['ĠS', 'ne'] +['Ġstandard', 'ized'] +['Ġmain', 'land'] +['_th', 'ree'] +['unge', 'ons'] +['get', 'Doctrine'] +['Ġwh', 'ale'] +['Ġag', 'g'] +['ĠP', 'orsche'] +['now', 'led'] +['lat', 'ent'] +['ĠRel', 'ation'] +['Ġ//', "'"] +['Ġshut', 'ting'] +['ĠRem', 'ix'] +['_c', 'ov'] +['Ġs', 'ailing'] +['Ġv', 'owed'] +['Ġp', 'ots'] +['out', 'u'] +['Ġhair', 'y'] +['cast', 's'] +['Rel', 'oad'] +['Ġre', 'connect'] +['ter', 'a'] +['.child', 'Nodes'] +['ĠR', 'ack'] +['Ġcurrent', 'Index'] +['Ġall', 'en'] +['Ġ', 'ç͍æĪ·'] +['ĠC', 'ubs'] +['[', 'X'] +['_SE', 'Q'] +['_RE', 'MOVE'] +['.get', 'Action'] +['(/', '^'] +['err', 'ar'] +['Ġ', 'ether'] +['cur', 've'] +['Ġsl', 'ap'] +['Ġu', 'om'] +['O', 'thers'] +['Ġen', 'gr'] +['Dis', 'position'] +['Ġst', 'aged'] +['E', 'ye'] +['ĠA', 'ux'] +['auth', 'enticate'] +['Ġ$', '?'] +['ĠAndre', 'as'] +['Ġset', 'w'] +['.A', 'rt'] +['Ġforecast', 's'] +['Ġa', 'unt'] +['-m', 'iddle'] +['Ġmis', 'd'] +['des', 'k'] +['Ġescort', 'e'] +['ĠCas', 'a'] +['rop', 'ical'] +['Ġexem', 'ple'] +['plan', 'et'] +['(U', 'INT'] +['Ġwh', 'ip'] +['ĠPC', 'B'] +['clide', 'an'] +['="', '\\'] +['Ġox', 'ide'] +['Ġsucceed', 's'] +['der', 'ived'] +['ĠEcon', 'om'] +['_co', 'ordinates'] +['ir', 'as'] +['D', 'raft'] +['Ġvisual', 'ize'] +['B', 'rian'] +['_ASS', 'UME'] +['ĠObject', 'Id'] +['Ġtrain', 'ers'] +['_FOR', 'CE'] +['Ġcon', 'soles'] +['-', 'process'] +['lic', 'her'] +['ĠSim', 'mons'] +['T', 'aking'] +['ĠCl', 'aims'] +['Ġdiffé', 'rent'] +['Activity', 'Result'] +['Ġsn', 's'] +['éĢī', 'æĭ'] +['ĠCr', 'us'] +['Ġll', 'am'] +['r', 'ab'] +['ĠJo', 'an'] +['AA', 'A'] +['ĉf', 'ilter'] +['ish', 'ops'] +['get', 'ting'] +['à', 'µ'] +['Ġquant', 'o'] +['P', 'ast'] +['ov', 'ich'] +['Ġin', 'justice'] +['ĠF', 'LOAT'] +['Ġal', 'right'] +['\\', 'DB'] +['(', 'GameObject'] +['u', 'ish'] +['(b', 'ot'] +['Ġgall', 'ons'] +['ĠR', 'é'] +['ĠS', 'aid'] +['ĠSTDMETHOD', 'CALLTYPE'] +['ais', 'ing'] +['_process', 'or'] +['ell', 'idos'] +['ter', 'dam'] +['ĠBe', 'am'] +['Text', 'Area'] +['Ġret', 'orno'] +['.M', 'ake'] +['Ġ$', '("<'] +['Ġlock', 'down'] +['Ġremed', 'ies'] +['Ġve', 'el'] +['x', 'ee'] +['do', 'ctype'] +['F', 'il'] +['ĠExp', 'and'] +['Ġemp', 'loys'] +['Ġsession', 'Storage'] +['Ph', 'p'] +['P', 'ublish'] +['Ġret', 'al'] +['f', 'abs'] +['ynam', 'ics'] +['Ġtoss', 'ed'] +['ĠnumberOfRows', 'InSection'] +['x', 'path'] +['\\', 'modules'] +['Ġdis', 'astr'] +['ĠM', 'ULT'] +['.M', 'esh'] +['-st', 'age'] +['Ġs', 'df'] +['it', 'ung'] +['ug', 'es'] +['Ġ?>', '">\''] +['kin', 'son'] +['Ġк', 'ол'] +['ogn', 'itive'] +['_', 'li'] +['Ġim', 'minent'] +['Ġaff', 'inity'] +['.sign', 'al'] +['Ġnot', 'ch'] +['ĠSteel', 'ers'] +['max', 'length'] +['K', 'K'] +['ĠEug', 'ene'] +['_P', 'WM'] +['ro', 'i'] +['Ġâ', 'Ĺı'] +['ĠH', 'amburg'] +['.M', 'ust'] +['Ġax', 'e'] +['en', 'ef'] +['Ġamb', 'itions'] +['ĠSpec', 'ies'] +['ĠSt', 'ress'] +['Ġa', 'while'] +['Ġб', 'Ñĥд'] +['Ġwith', 'stand'] +['ĠDec', 'oder'] +['_in', 'ventory'] +['Ġ{', 'ččĊ'] +['Ġt', 'gt'] +['Ġrail', 'road'] +['W', 'ASHINGTON'] +['Ġnegot', 'iated'] +['N', 'ST'] +['-', 'phone'] +[',', 'U'] +['Ġexerc', 'ising'] +['á»', '¥'] +['_P', 'IXEL'] +['av', 'ors'] +['iter', 'ated'] +['Ġv', 'ampire'] +['ad', 'al'] +['In', 'grese'] +['Ġun', 'g'] +['ject', 'ive'] +['.c', 'ells'] +['Ġn', 'ano'] +['Ġmark', 'down'] +['_R', 'ULE'] +['(event', 's'] +['Ġl', 'uggage'] +['MESS', 'AGE'] +['ig', 'keit'] +['$', 'count'] +['Attribute', 'Name'] +['IG', 'INAL'] +['_E', 'nt'] +['ĠB', 'F'] +['ĠCOM', 'MENT'] +['_in', 'i'] +['ĠEurope', 'ans'] +['ĠB', 'elle'] +['åij', '½'] +[')', "['"] +['åº', 'Ķ'] +['ĠUse', 'ful'] +['.re', 'ference'] +['()', '",'] +['_', 'grade'] +['ĠK', 'aw'] +['Ġsent', 'encing'] +['Ġsocial', 'ism'] +['mon', 'ster'] +['_L', 'AYER'] +['Ġdee', 'pest'] +['w', 'k'] +['ĠNo', 'ise'] +['###', 'ĊĊ'] +['Ġpr', 'éc'] +['ot', 'le'] +['ÑĤ', 'е'] +['a', 'uf'] +['ib', 'al'] +['Ġcon', 'quer'] +['>', 'Email'] +['Ġamb', 'ulance'] +['O', 'AD'] +['Ġ("', '%'] +['ĠF', 'I'] +['.f', 'ixture'] +['Ġter', 'se'] +['ĠĠĠĠ', 'ĉĉĉĉ'] +['Ġsanct', 'uary'] +['ug', 'i'] +['ĠCom', 'parator'] +['Definition', 's'] +['Ġast', 'hma'] +['Ġl', 'act'] +['Ġhard', 'wood'] +['.c', 'lock'] +['Ġattract', 'ing'] +['ĠM', 'our'] +['(d', 'istance'] +['ic', 'its'] +['Ġbon', 'ne'] +['ĠAC', 'CESS'] +['.Deserialize', 'Object'] +['ĠTyp', 'ed'] +['Ġje', 'u'] +['Ġapp', 'Id'] +['ĠCl', 'ara'] +['ĠH', 'F'] +['ĠRe', 'ich'] +['ipp', 'les'] +['//----------------------------------------------------------------', '----------------'] +['_del', 'ivery'] +['erial', 'ization'] +['Ġplaint', 'iffs'] +['Sc', 'ient'] +['sh', 'opping'] +['ĠD', 'ummy'] +['ĠW', 'ald'] +['Group', 'Name'] +['Ġins', 'cription'] +['el', 'og'] +['::::', '::::'] +['_', 'ld'] +['Back', 'Pressed'] +['.R', 'aw'] +['ĠOn', 'Trigger'] +['Ġmuse', 'ums'] +['ĠBe', 'en'] +['ĠAdvent', 'ures'] +['Ġsl', 'ate'] +['Ġlet', 't'] +['Ġsu', 'nd'] +['ĠG', 'in'] +['ĠMechan', 'ical'] +['.s', 'hip'] +['App', 'Component'] +['Ġdest', 'ined'] +['Ġdw', 'elling'] +['Prof', 'iler'] +['Pre', 'pare'] +['ze', 'ich'] +['Ġsil', 'icon'] +['(h', 'as'] +['Ġ#', '%'] +['VID', 'EO'] +['Ġcollabor', 'ate'] +['L', 'in'] +['Ġsc', 'opes'] +['(', 'className'] +['(s', 'd'] +['and', 'in'] +['.h', 'am'] +['Service', 'Impl'] +['-des', 'cribed'] +['Ġiron', 'y'] +['st', 'ial'] +['ĠHu', 'awei'] +['(re', 'po'] +['Ġunexpected', 'ly'] +['ĠK', 'ai'] +['.inst', 'all'] +['\\x', 'f'] +['Ġexhib', 'ited'] +['_T', 'CP'] +['ĠO', 'x'] +['_CH', 'O'] +['Ġprostitu', 'erte'] +['Ġv', 'ä'] +['Ġsit', 'o'] +['Ġconstitu', 'ents'] +['ĠContin', 'ued'] +['ĠS', 'AVE'] +['r', 'ss'] +['/', 'message'] +['ub', 'es'] +['Ġmisd', 'emean'] +['Ġtax', 'ation'] +['Ġstory', 'line'] +['h', 'air'] +['ĠFind', 's'] +['S', 'IG'] +['ver', 'ification'] +['~', '='] +['.h', 'p'] +['Iter', 'able'] +['Ñĭ', 'е'] +['ator', 'i'] +['Ġc', 'tr'] +['R', 'x'] +['_', ');ĊĊ'] +['d', 'ag'] +['.p', 'in'] +['Ġp', 'seud'] +['Ġinv', 'o'] +['ÑģÑĤ', 'ÑĢ'] +['_p', 'ix'] +['为', '空'] +['Ġsw', 'orn'] +['âĢĶ', 'or'] +['_reg', 'istry'] +['Ġdis', 'asters'] +['ĠRO', 'I'] +['ĠâĢ', 'ķ'] +['akt', 'u'] +['fore', 'st'] +['be', 'iten'] +['âĢĶ', 'I'] +['ue', 'va'] +['eg', 't'] +['Ġsp', 'ikes'] +['URE', 'S'] +['ĠRecomm', 'ended'] +['Ġexplo', 'ited'] +['ĠFreder', 'ick'] +['_COMP', 'LETE'] +['ĠDr', 'ugs'] +['!!!!', '!!!!'] +['ĠR', 'iv'] +['ST', 'OP'] +['RO', 'OM'] +['ĠP', 'ASSWORD'] +['C', 'ookies'] +['.E', 'l'] +['á»', 'Ń'] +['ĠB', 'ert'] +['Ġhash', 'ed'] +['ic', 'ester'] +['Ġdecor', 'ator'] +['Ġquery', 'String'] +[':', ';Ċ'] +['Ġ"', '["'] +['oto', 'pe'] +['-A', 'meric'] +['ĠMatthew', 's'] +['UR', 'AL'] +['âĢľ', ','] +['Sum', 'mer'] +['f', 'os'] +['_CONT', 'AINER'] +['_A', 'CK'] +['Ġfil', 'tr'] +['_dis', 'p'] +['_', 'Re'] +['Ġfac', 'ile'] +['а', 'ÑĪ'] +['Ġìķ', 'Ĭ'] +['Ġe', 'ben'] +['Ġspr', 'ink'] +['ĠQ', 'uint'] +['>', 'V'] +['Ġhistor', 'ians'] +['our', 'met'] +['ĠMonitor', 'ing'] +['led', 'ger'] +['c', 'ott'] +['Ġw', 'are'] +['GG', 'LE'] +['c', 'ars'] +['ĠM', 'EDIATEK'] +['Ġvol', 'upt'] +['_', 'View'] +['HE', 'L'] +['(c', 'opy'] +['(st', 'ats'] +['Ġchrom', 'osome'] +['ĠCurt', 'is'] +['-', 'conf'] +['(', 'asset'] +['Ġhv', 'or'] +['File', 'System'] +['<', '>();čĊ'] +['oc', 'oder'] +['ĠC', 'annon'] +[')', 'x'] +['ĠSm', 'ooth'] +['ĠS', 'AS'] +['_', 'ce'] +['ĉ', 'prev'] +['_m', 'ovie'] +['E', 'c'] +['_w', 'all'] +['<', 'Button'] +['ĠF', 'AST'] +['Ġon', 'View'] +['ul', 'an'] +['ĠS', 'UPPORT'] +['Ġgesch', 'ichten'] +['ĠS', 'ons'] +['Im', 'm'] +['$', 'IFn'] +['Ġfair', 'ness'] +['Ġd', 'pi'] +['ats', 'u'] +['J', 'osh'] +['Equal', 'ity'] +['Ġ}', '()Ċ'] +['_', 'less'] +['ĠR', 'atio'] +['ĠC', 'ats'] +['ĠS', 'tern'] +['Mon', 'ster'] +['Ġmer', 'cury'] +['ü', 'hr'] +['Ġplus', 'ieurs'] +['.des', 'erialize'] +['sc', 'opy'] +['.F', 'alse'] +[')', 'animated'] +['ĠExp', 'erts'] +['Ġ"")', '{Ċ'] +['.W', 'hen'] +['see', 'also'] +['.un', 'pack'] +['LE', 'M'] +['.select', 'All'] +['Ġperception', 's'] +['ud', 'ing'] +['ir', 'ling'] +['ĠPrint', 'ing'] +['gram', 's'] +['ĠFile', 'Stream'] +['erv', 'ille'] +['il', 'og'] +['ic', 'mp'] +['_C', 'ount'] +['Ġlivest', 'ock'] +['-', 'ca'] +['doc', 'uments'] +['Ġpo', 'les'] +['ĉw', 'ant'] +['Ġflu', 'ores'] +['Ġstand', 'point'] +['ĠH', 'uge'] +['Ġradi', 'ans'] +['ĠUIB', 'ar'] +['EDI', 'UM'] +['ĠHistor', 'ic'] +['_h', 'older'] +['ĠMar', 'ines'] +['Ġt', 'ä'] +['.L', 'ight'] +['quir', 'er'] +['ason', 'ry'] +['div', 'ider'] +['ĠFl', 'utter'] +['_f', 'b'] +['restrict', 'ed'] +['ĠEvery', 'body'] +['N', 'ão'] +['Ġkn', 'ot'] +['ĠT', 'witch'] +['Ġhall', 'way'] +['(C', 'ollider'] +['Input', 'Element'] +['?', ')Ċ'] +['/', 'off'] +['/', ')'] +['play', 'ed'] +['[', 'OF'] +['Ġbat', 'ting'] +['_d', 'l'] +['Ġcom', 'edian'] +['Ġé', 'v'] +['ĠD', 'EM'] +['ĠEd', 'en'] +[':', 'white'] +["'", "',"] +['Con', 'struction'] +['acer', 'b'] +['Ġtask', 'ed'] +['.man', 'age'] +['Rel', 'ationship'] +['Ġph', 'on'] +['n', 'z'] +['_B', 'GR'] +['Validate', 'AntiForgeryToken'] +['_', 'air'] +['âĢľ', 'When'] +['Ġgl', 'fw'] +['ĠCon', 'versation'] +['_T', 'OTAL'] +[',', 'Z'] +['Ġg', 'raz'] +['Ġiter', 'able'] +['ĠP', 'ASS'] +['Ġadvert', 'ise'] +['Ġmö', 'glich'] +['/', 'train'] +['ĠVolk', 'swagen'] +['Ġcreep', 'y'] +['Ġ"', ')čĊ'] +['QU', 'ENCE'] +['Ġalt', 'ar'] +['Ġed', 'its'] +['comp', 'iled'] +['aw', 'ning'] +['ĠD', 'ungeon'] +['Ġo', 'sg'] +['Navigation', 'Bar'] +['Ġtrend', 'ing'] +['ĠE', 'co'] +['ogg', 'les'] +['cd', 'ot'] +['|', '-'] +['S', 'ie'] +['ec', 'ret'] +['ĠN', 'egative'] +['ĠL', 'ing'] +['ĠD', 'IM'] +['ĠC', 'WE'] +['ĠCar', 'rier'] +['Ġcar', 'tridge'] +['_us', 'b'] +['=', 'os'] +['ĠJack', 'ie'] +['Ġo', 'tras'] +['Ġcommod', 'ities'] +['ĠP', 'resentation'] +[')&&', '('] +['ĠMar', 'tha'] +['ĠCath', 'olics'] +['ĠM', 'ond'] +['об', 'Ñĭ'] +['_', 'absolute'] +['Ġash', 'amed'] +['pons', 'ors'] +['t', 'al'] +['Ġsad', 'ness'] +['Ġpu', 'ò'] +['F', 'ade'] +['-pre', 'view'] +['ĠRequest', 's'] +['ĠCal', 'vin'] +['h', 'orn'] +['Reuse', 'Identifier'] +['(pro', 'vider'] +['/app', 's'] +['ime', 'o'] +['ĉ', 'Class'] +['S', 'amsung'] +['ĠW', 'ORLD'] +['Ġc', 'innamon'] +['dot', 'env'] +['ĠI', 'User'] +['ĠDE', 'V'] +['_C', 'har'] +['.ib', 'atis'] +['et', 'i'] +['/', 'me'] +['s', 'st'] +['.s', 'ym'] +['ĠRug', 'by'] +['-m', 'aster'] +['aj', 'ar'] +['ĠY', 'EAR'] +['Ġo', 'dp'] +['ĠR', 'oles'] +['Ġbip', 'artisan'] +['ail', 'le'] +['Ġblock', 'er'] +['Ġgre', 'ens'] +['.SE', 'CONDS'] +['Ġbelie', 'vers'] +['ĠL', 'ikes'] +['F', 'LOAT'] +['Ġm', 'ak'] +['Ġg', 'cc'] +['âķIJ', 'âķIJ'] +['("', '~/'] +['SCRIPT', 'OR'] +['Ġton', 'nes'] +['ĠS', 'ang'] +['Ġtrans', 'pose'] +['enn', 'ai'] +['P', 'red'] +['Ġsoll', 'te'] +['.github', 'usercontent'] +['(', 'print'] +['ĠH', 'ole'] +['çľ', 'ĭ'] +['ad', 'get'] +['Ġprompt', 's'] +['Ġgen', 'etically'] +['ĠH', 'od'] +['Ġvert', 'ically'] +['_control', 's'] +['ÑģÑĤ', 'ан'] +['")', '{čĊ'] +['$', 'title'] +['Ġ}', '),ĊĊ'] +['Ġstate', 'wide'] +['ĠCor', 'respond'] +['ĠAt', 'tr'] +['it', 'ant'] +['Element', 'Type'] +['Ġout', 'ward'] +['Ġfam', 'ilia'] +['(', 'article'] +['Ġbl', 'at'] +['Âł', 'Ċ'] +['Ġgl', 'Get'] +['ĠRe', 'ceiver'] +['Ġ%', '-'] +['ad', 'am'] +['W', 'inner'] +['Ġtail', 'or'] +['_p', 'wd'] +['ert', 'en'] +['St', 'an'] +['ĉ', 'all'] +['al', 'ive'] +['strt', 'otime'] +['�', 's'] +['s', 'essions'] +['$', 'conn'] +['ass', 'ist'] +['Ġchat', 'ting'] +['ĠM', 'ant'] +['Ġ%', '@'] +['Ġ""', ');ĊĊ'] +['Ġd', 'gv'] +['Ġíķ', '¨'] +['.re', 'peat'] +['_M', 'essage'] +['Ġadvis', 'ers'] +['/', 'path'] +['Ġk', 'es'] +[')', '}', '.ĊĊ'] +['ogen', 'esis'] +['ĠOPTION', 'S'] +['upt', 'ools'] +['Ġmilit', 'ant'] +['Ġex', 'ited'] +['ig', 'ar'] +['ĠCOM', 'M'] +['ĠDis', 'posable'] +['ay', 'cast'] +['Ġrow', 'span'] +['Ġsyn', 'thes'] +['Ġsond', 'ern'] +['ĠĊ'] +['ĠJ', 'acket'] +['R', 'ATION'] +['.getSelected', 'Item'] +['-', 'init'] +['ĠReg', 'isters'] +['_se', 'p'] +['ĠTool', 'kit'] +['.d', 'ict'] +['Ġx', 'label'] +['\\', 'Table'] +['t', 'oc'] +['_com', 'bo'] +['ĠComp', 'act'] +['Ġr', 'ugged'] +['à¥ĩ', 'à¤'] +['-man', 'agement'] +["')}}", '">Ċ'] +['ĠSt', 'amp'] +['ı', 'l'] +['ro', 'x'] +['Ġlandsc', 'apes'] +['_NOT', 'E'] +['mon', 'ary'] +['c', 'ab'] +['Ġmo', 'et'] +['x', 'af'] +['rc', 'ode'] +['-', 'cli'] +['_g', 'ate'] +['[', 'event'] +['SP', 'ORT'] +['g', 'ia'] +['ĠS', 'UPER'] +['/', 'Login'] +['_sh', 'utdown'] +['int', 'errupt'] +['Ġpret', 'ending'] +['Ġfr', 'inge'] +['ĠRed', 's'] +['ĠC', 'UDA'] +['ĠUN', 'IX'] +['v', 'it'] +['Ġbr', 'ig'] +['dr', 'v'] +['ĠConn', 'ector'] +['There', 'fore'] +['Ġl', 'ia'] +['D', 'etection'] +['_', 'actor'] +['Ġtemp', 'file'] +['Ġecc', 'entric'] +['-', 'role'] +['Ġpad', 'x'] +['d', 'ent'] +['West', 'ern'] +['Ġê', '·¸'] +['ĠApplication', 'Record'] +['Ġcampaign', 'ing'] +['_run', 'ner'] +['ĠC', 'ivic'] +['ale', 'igh'] +['Ġdire', 'kt'] +['.s', 'ul'] +['ĠĠ', 'ĉĉĉ'] +['ant', 'en'] +['Ġiss', 'uer'] +['Ġassert', 'ions'] +['(', 'orig'] +['AT', 'IO'] +['Ġlean', 'ed'] +['ä', 's'] +['.D', 'TO'] +['expl', 'ode'] +['.O', 'bservable'] +['Ġstagger', 'ing'] +['Ġkidn', 'apped'] +['Ġprogram', 'mers'] +['ĠInn', 'ov'] +['.param', 'eter'] +['Ġdom', 'ination'] +['Ġske', 'ptic'] +['Ġæĺ', '¯'] +['Ġavoid', 's'] +['.Ver', 'ify'] +['ub', 'by'] +['ĠAS', 'N'] +['Ġformat', 'o'] +['ĠBeat', 'les'] +['_b', 'rand'] +['Ġin', 'set'] +['y', 'outu'] +['Ġto', 'c'] +['-f', 'inal'] +['Show', 'ing'] +['ĠD', 'oub'] +['ĠM', 'esa'] +['Ad', 'j'] +['_m', 'edium'] +['Cre', 'ates'] +['(end', 'point'] +['ĉ', 'UP'] +['bb', 'ie'] +['Ġst', 'alk'] +['.datab', 'ind'] +['.S', 'can'] +['ag', 'ents'] +['$', ','] +['ind', 'ividual'] +['+', ')/'] +['ĉv', 'm'] +['(not', 'ification'] +['Ġin', 'ex'] +['ĠClass', 'ification'] +['ren', 'o'] +['Ġo', 'lig'] +['-r', 'ated'] +['Ġform', 'ulation'] +["',", '{'] +['Ġa', 'cept'] +['_un', 'pack'] +['_C', 'A'] +['.P', 'ow'] +['ĉ', 'im'] +['Ġal', 'uminium'] +['AN', 'O'] +['Ġx', 'n'] +['Ġcó', 'mo'] +['ĠIng', 'redient'] +['Ġseiz', 'ures'] +['åħ', '±'] +['ific', 'ador'] +['Ġsigu', 'iente'] +['ĠIn', 'fragistics'] +['Ġduplic', 'ated'] +['ĠDe', 'e'] +['Ġn', 'ø'] +['ĠAC', 'CEPT'] +['(c', 'rate'] +['иÑĤ', 'елÑĮ'] +['-', 'less'] +['Ġinf', 'inity'] +['An', 'alyzer'] +['-D', 'ay'] +['rit', 't'] +['(c', 'in'] +['ĠG', 'y'] +['Ġmulti', 'plied'] +['uch', 'i'] +['ĠBald', 'win'] +['/', 'ip'] +['Ġshort', 'cuts'] +['.A', 'DD'] +['Ġvig', 'or'] +['_in', 'struction'] +['(', ';'] +['_', 'eta'] +['è¿', 'ŀ'] +['utor', 'ials'] +['Ġboost', 'ing'] +['b', 'v'] +['Ġacknowled', 'ges'] +['List', 'ening'] +['FA', 'Q'] +[';', 'b'] +['((', '-'] +['Ġarchitect', 's'] +['Ġz', 'we'] +['Ġpul', 's'] +['Ġget', 'Count'] +['ver', 'bs'] +['ãĢ', 'ľ'] +['(C', 'ollection'] +['k', 're'] +['Ġjuris', 'dictions'] +['_b', 'ridge'] +['ĠCr', 'ack'] +['ĠDiff', 'iculty'] +['K', 'O'] +['Res', 'ervation'] +['_re', 'quires'] +['T', 'our'] +['ãģĹãģ', 'Ł'] +['.set', 'Current'] +['Ġk', 'y'] +['ĠAlb', 'any'] +['Ġè', '§'] +['ll', 'er'] +['agn', 'a'] +['work', 'ers'] +['.bl', 'ank'] +['ĠPr', 'ayer'] +['M', 'IC'] +['Ġresil', 'ience'] +['Te', 'X'] +['ĠL', 'anguages'] +['st', 'udy'] +['ĉc', 'urr'] +['Ġenzym', 'es'] +['Sl', 'ug'] +['ĠíĮ', 'Į'] +['str', 'al'] +['Ġtum', 'ors'] +['Ġseg', 'unda'] +["='", '{'] +['in', 'struction'] +['ĠL', 'isp'] +['/', 'info'] +['Ġ"', '{$'] +[',:', '),'] +['Ġg', 'v'] +['(', 'ErrorMessage'] +["Ġ'", '='] +['}-', '${'] +['.Doc', 'uments'] +['"', 'Well'] +['Ġreminis', 'cent'] +['Ġg', 'az'] +['iro', 'pr'] +['eh', 'r'] +['Ġsup', 'pressed'] +['ers', 'h'] +['.scroll', 'To'] +['Ġcad', 'ena'] +['Ġgame', 'State'] +['ÃŃ', 'm'] +['(', 'conv'] +['ĠTom', 'orrow'] +['ĠC', 'CT'] +['M', 'ongo'] +['ul', 'g'] +['.C', 'amera'] +['.hand', 'lers'] +['m', 'ph'] +['Ġst', 'k'] +['Ġgen', 'etics'] +['AC', 'ING'] +['Tr', 'ivia'] +['ĠB', 'am'] +['(m', 'arker'] +['.St', 'retch'] +['ĠSun', 'ni'] +['ĠBet', 'ty'] +['.t', 'olist'] +['un', 'likely'] +['.Rect', 'angle'] +['ob', 'solete'] +['IL', 'ON'] +['inner', 'Text'] +['emb', 'ourg'] +['a', 'N'] +['ĠV', 'ehicles'] +['un', 'lock'] +[':', 'utf'] +['n', 'ob'] +['ĠSee', 'ing'] +['ĠNE', 'VER'] +['Ġt', 'ls'] +['Ġfil', 'les'] +['Ġbenef', 'ited'] +['ĠCl', 'int'] +['*/', '),'] +['.f', 'old'] +['Ġpos', 'ible'] +['A', 'DED'] +['th', 'ouse'] +['.D', 'AL'] +['ĠO', 'dd'] +['ro', 'kes'] +['ĠSun', 'ny'] +['ĠPartial', 'Eq'] +['_B', 'uffer'] +['ĠLe', 'vi'] +['long', 'rightarrow'] +['eld', 'on'] +['g', 'ages'] +['_w', 'arn'] +['.Create', 'Table'] +['ĠD', 'ip'] +['_', 'questions'] +['.log', 'ic'] +['Ġ#', '"'] +['={()', '=>'] +['Ġt', 'ep'] +['Ġju', 'icy'] +['ì', 'Ĥ¬'] +['en', 'ko'] +['ia', 'lect'] +['Ù', 'ī'] +['Ġon', 'board'] +['Ġæ', 'ı'] +['ĉ', 'rt'] +['_', 'UTF'] +['ĠQ', 'Action'] +['âĢ', 'ŀ'] +['(', 'Component'] +['(a', 'udio'] +['.h', 'it'] +['g', 'te'] +['Ġprogram', 'med'] +['state', 'Params'] +['Ġpoly', 'ester'] +['f', 'ires'] +['by', 'ss'] +[']', '=('] +['_', 'quality'] +['Of', 'Day'] +['ĠFair', 'y'] +['Ġy', 'elled'] +['op', 'l'] +['(user', 'Name'] +['ĠD', 'ifference'] +['Ġevalu', 'ations'] +['iff', 'any'] +['Ġcycl', 'ists'] +['Ġc', 'idade'] +['Ġtext', 'book'] +['Ġprof', 'iling'] +['__', '),'] +['de', 'a'] +['.', 'activate'] +['Ġindic', 'ations'] +['Ð', 'ķ'] +['Touch', 'UpInside'] +['Ġinval', 'uable'] +['ĠM', 'ASK'] +['Ġcont', 'end'] +['F', 'req'] +['Ġrecru', 'its'] +['(int', 'erval'] +['ĠUser', 'Profile'] +["Ġ'./", '../'] +['ed', 'u'] +['_C', 'allback'] +['Ġanal', 'ogy'] +['ĠTro', 'phy'] +['app', 'hire'] +['V', 'ideos'] +['ĠCh', 'er'] +['ĠH', 'av'] +['â̦', '"'] +['.', 'validator'] +['g', 'fx'] +['ĠU', 'Object'] +['class', 'names'] +['tri', 'angle'] +['ĠEnc', 'oder'] +['.s', 'py'] +['Ġpred', 'ators'] +['=', 'status'] +['-s', 'afe'] +[':', '",Ċ'] +['ĠIn', 'cluding'] +['Ġ{}', ';čĊ'] +['*', 'cos'] +['Ġend', 'ured'] +['.sul', 'ake'] +['Ġnurs', 'ery'] +['Ġfrag', 'rance'] +['Ġre', 'building'] +['Ġn', 'th'] +['ĠFr', 'aser'] +['.set', 'Date'] +['ĠV', 'ince'] +['_RE', 'ST'] +['Ġvent', 'ilation'] +['æµ', '·'] +['cri', 'bes'] +['.as', 'm'] +['lp', 'Vtbl'] +['ĠA', 'be'] +['uis', 'ine'] +[',', 'array'] +['ĉ', 'className'] +['err', 'als'] +["Ġ'", 'ĊĊ'] +['Check', 'out'] +['Ġsol', 'icit'] +['A', 'ux'] +['_c', 'apture'] +['Ġrib', 's'] +['rag', 'on'] +['vi', 'ol'] +['top', 'ics'] +['Function', 'Flags'] +['ĠM', 'arty'] +['b', 'ike'] +['ĠT', 'ucker'] +['(k', 'ernel'] +['ĠO', 'ps'] +['Close', 'Operation'] +['/d', 'emo'] +['ild', 'a'] +['ĠlÃŃ', 'nea'] +['APP', 'ING'] +['Ġsu', 'ites'] +['.visit', 'VarInsn'] +['ur', 'us'] +['ĠMin', 'ute'] +['(m', 'anager'] +['Ġbutter', 'fly'] +['Ġap', 'are'] +['Ġw', 'olves'] +['J', 'WT'] +['ĠSal', 'on'] +['ĉd', 'elay'] +['-es', 'lint'] +['is', 'ations'] +['.r', 'pc'] +[')|', '('] +['ĠSnap', 'chat'] +['/m', 'm'] +['M', 'N'] +['cer', 'ies'] +['.text', 'Alignment'] +['ĠFrank', 'furt'] +['Ġad', 'o'] +['(new', 'Value'] +['(', 'access'] +['(', 'Expression'] +['ĠSign', 'In'] +['ĠHait', 'i'] +['_t', 'p'] +['.set', 'Parameter'] +['Min', 'ute'] +['Ġmanual', 's'] +['ric', 'anes'] +['ĠP', 'TR'] +['ĠOut', 'er'] +['Ġget', 'line'] +['oc', 'ations'] +['_C', 'D'] +['ĠLy', 'on'] +['/g', 'ui'] +['_l', 'ive'] +['id', 'an'] +['.ge', 'om'] +['Ġborder', 'Bottom'] +['im', 'uth'] +['_check', 'point'] +['Ġme', 'u'] +['ĠIr', 'ving'] +['Ġpeu', 'vent'] +['(M', 'AX'] +['ĠAR', 'CH'] +['Ġp', 'ov'] +['.source', 'forge'] +['Ġjam', 'ais'] +['Ġar', 'k'] +['ĠBaghd', 'ad'] +['ĠC', 'LEAR'] +['Menu', 'Bar'] +['Ġtro', 'is'] +['CHED', 'ULE'] +['Ġ#', 'čĊ'] +['(C', 'all'] +['$', 'order'] +['(M', 'aterial'] +['Ġencontr', 'ado'] +['$', 'list'] +['ĠMETHOD', 'S'] +['.begin', 'Transaction'] +['_M', 'AG'] +['Style', 'Sheet'] +['Ġmaj', 'ors'] +['Ġindef', 'initely'] +['clean', 'up'] +['Ġhom', 'eland'] +['(d', 'to'] +['D', 'ates'] +['P', 'resentation'] +['ĠD', 'K'] +['={`', '/'] +['ĉ', 'Key'] +['(', 'Block'] +['_check', 'box'] +['ne', 'eds'] +['Ġon', 'Complete'] +['ric', 'o'] +['Ġgle', 'ich'] +['Ġx', 'm'] +['O', 'OD'] +['B', 'etter'] +['ĠSQL', 'ITE'] +['.', 'Book'] +['x', 'ad'] +['ĠG', 'one'] +['ĉd', 'p'] +['Ġdev', 'otion'] +['Ġst', 'm'] +['Ġobs', 'ess'] +['ĠBack', 'end'] +['Qu', 'eries'] +['I', 'k'] +['//', '****************************************************************'] +['Ġdivid', 'ends'] +['.parent', 'Element'] +['}', '")ĊĊ'] +['ĠMaterial', 'PageRoute'] +[':', 'num'] +['Ġexp', 'lic'] +['ĠO', 'L'] +['le', 'ast'] +['O', 'ops'] +['iment', 'os'] +['Ġins', 'urers'] +['Ġhero', 'ic'] +['ĉf', 'ields'] +['.img', 'ur'] +['.btn', 'Cancel'] +['ĠDetect', 'ive'] +['(s', 'm'] +['ĠMutable', 'LiveData'] +['.l', 'ab'] +['((', '['] +['Ġha', 'irst'] +['ĠTrans', 'actions'] +['å¼Ģ', 'å§ĭ'] +['Ġstd', 'Class'] +['uent', 'o'] +['G', 'IS'] +['_c', 'od'] +['Instruction', 's'] +['C', 'alls'] +['Pointer', 'Type'] +['ĠR', 'w'] +['Ġassort', 'ment'] +['ĠD', 'IG'] +['+', 'r'] +['_C', 'ERT'] +['Ġinst', 'ability'] +['Ġv', 'ib'] +['on', 'as'] +['Ġro', 'ku'] +['ap', 'ellido'] +['Ġan', 'gl'] +['prene', 'ur'] +['Ġfluid', 's'] +['ise', 'ase'] +['Ġde', 'ed'] +['qu', 'ist'] +['_CONST', 'ANT'] +['Ġequ', 'ilibrium'] +['_de', 'legate'] +['ĠQuant', 'um'] +['re', 'i'] +['Cap', 'abilities'] +['rect', 'angle'] +['?', '><'] +['al', 'ien'] +['ĠJ', 'ug'] +['D', 'NA'] +['T', 'ickets'] +['Occ', 'urs'] +['ĠHaw', 'k'] +['.setHorizontal', 'Group'] +['\\', 'Collection'] +['ff', 'iti'] +['Ġre', 'arr'] +['.setVertical', 'Group'] +['Ġc', 'avity'] +['Ġadult', 'e'] +['Fac', 'ade'] +['-', 'wh'] +['ĠL', 'OL'] +['Ø', '°'] +['Ġgrand', 'parents'] +['Sw', 'ift'] +['ĉw', 'x'] +['æīĢ', 'æľī'] +['if', 'en'] +['ff', 'set'] +['B', 'eyond'] +['//', '}ĊĊ'] +['Ġw', 'ager'] +['Ġb', 'ury'] +['Ġcomm', 'ence'] +['reg', 'istro'] +['sc', 'ient'] +['ĠPer', 'cent'] +['Ġд', 'олж'] +['(', 'identifier'] +['.set', 'Model'] +['Ġs', 'eldom'] +['nt', 'on'] +['Ġappl', 'iance'] +['am', 'us'] +['rys', 'ler'] +['Ġpant', 'ies'] +['engu', 'ins'] +['Ġmim', 'ic'] +['Ġon', 'Changed'] +['Ġal', 'coholic'] +['.reload', 'Data'] +['Ch', 'arge'] +['ĠF', 'ax'] +['Ġj', 'ScrollPane'] +['Emp', 'resa'] +['Ġsh', 'attered'] +['x', 'ba'] +['Font', 's'] +['?', 's'] +['Ġpost', 'season'] +['ret', 'ain'] +['_r', 'ates'] +['Ġrequest', 'Code'] +['.t', 'odo'] +['´', 's'] +['CH', 'K'] +['ĠKeep', 'ing'] +['enge', 'ance'] +['Ġvs', 'code'] +['IPP', 'ING'] +['Default', 'CloseOperation'] +['_', 'raise'] +['ĠO', 'culus'] +['ogram', 's'] +['ra', 'j'] +['pc', 'i'] +['Ġcorros', 'ion'] +['.handle', 'Submit'] +['Access', 'ible'] +['ĠP', 'iano'] +['l', 'ittle'] +['AC', 'L'] +['Äĩ', 'e'] +['.un', 'wrap'] +['ĠCon', 'vers'] +['ĠLe', 'ben'] +['ione', 'er'] +['ĠMer', 'chant'] +['ĠJ', 'orge'] +['Ġembr', 'acing'] +['Ġvent', 'a'] +['á', 'st'] +['Ġvi', 'ene'] +['<', 'QString'] +['Ġexplos', 'ions'] +['Ġdistur', 'bed'] +['."', '<'] +['m', 'emo'] +['ĠAb', 'original'] +['Ġcomple', 'to'] +['Tex', 'Parameter'] +['Ġuom', 'ini'] +['(', 'agent'] +['Ñĥ', 'ÑĢ'] +['ĠWh', 'olesale'] +['/', 'am'] +['ĠBook', 'mark'] +['dr', 'agon'] +['Ġglo', 've'] +['Ġ"', '"));Ċ'] +['iv', 'ariate'] +['now', 'rap'] +['In', 'Children'] +['.B', 'r'] +['Ġcon', 'exion'] +['Ġback', 'bone'] +['Ġe', 'clipse'] +['Ġpersec', 'ution'] +["':", 'ĊĊ'] +['/', 'link'] +['ĠP', 'ero'] +['and', 'as'] +['ĠT', 'ek'] +['.', '");'] +['-an', 'alysis'] +['Ġer', 'ad'] +['Mar', 'shal'] +['Ġanch', 'ors'] +['og', 'er'] +['Ġconver', 'gence'] +['st', 'icky'] +['Ġnave', 'g'] +['int', 'ern'] +['_DE', 'SCRIPTOR'] +['ĠConsult', 'ant'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'Ċ'] +['ĠA', 'uch'] +['Ġer', 're'] +['ÅĽ', 'li'] +['ĠHor', 'izon'] +['col', 'a'] +['Install', 'ation'] +['hot', 'mail'] +['C', 'NN'] +['.C', 'ollectors'] +['ch', 's'] +['(tr', 'ace'] +['ĠEnc', 'rypt'] +['Ġ----', '--'] +['ĠBase', 'Controller'] +['Ġag', 'ua'] +['Ġre', 'active'] +['id', 'l'] +['Ġclass', 'Names'] +['ĉ', 'Session'] +['ĠDod', 'gers'] +['H', 'ad'] +['_l', 'v'] +['Is', 'Valid'] +['ĠHEL', 'P'] +['ut', 'to'] +['ĠVer', 'ification'] +['Ġget', 'env'] +['_p', 'a'] +['.b', 'mp'] +[':', 'f'] +['ĠLou', 'ise'] +["('", ';'] +['/', 'socket'] +['Gr', 'anted'] +['.c', 'alendar'] +['(', 'IP'] +['ĠP', 'X'] +['.R', 'oom'] +['Ġprogram', 'm'] +['ens', 'i'] +['Ġtablesp', 'oons'] +['Ġle', 've'] +['Ġmo', 'str'] +['.t', 'ipo'] +['/', 'an'] +['(d', 'i'] +['Ġb', 'iod'] +['Ġdb', 'Context'] +['ĠJS', 'X'] +['ĉ', 'results'] +['.', 'END'] +['ht', 'e'] +['l', 'ify'] +['P', 'recision'] +['èĬ', 'Ĥ'] +['ARS', 'ER'] +[')did', 'ReceiveMemoryWarning'] +['at', 'tempt'] +['IS', 'P'] +['&', 'a'] +['_P', 'OP'] +['ĠT', 'ac'] +['Ġprepared', 'Statement'] +['Ġзап', 'иÑģ'] +['Ġow', 'ing'] +[',', 'start'] +['Ġreview', 'er'] +['Ġr', 'st'] +['Ġprop', 'Types'] +['Ġrock', 'y'] +['_lo', 'cale'] +['ĠStrateg', 'ies'] +['ĠWe', 'ber'] +['.C', 'ascade'] +['_equal', 'To'] +['Ġcos', 'as'] +['ĠDe', 'letes'] +['ĠMax', 'im'] +['Ġsh', 'rimp'] +['re', 'trieve'] +['.In', 'clude'] +['IG', 'IN'] +['ĠO', 'E'] +[']', ');čĊčĊ'] +['.en', 'umer'] +['Ġco', 'ef'] +['_N', 'ull'] +['R', 'a'] +['ty', 'ard'] +['ĠSh', 'awn'] +['keep', 'ers'] +['Ġq', 'q'] +['_s', 'b'] +['om', 'ens'] +['ĠExec', 'utes'] +['#', '"'] +['TT', 'Y'] +['ĠValue', 'Type'] +[');', '*/Ċ'] +['ĠAbs', 'olutely'] +['ĠT', 'ottenham'] +['/', 'art'] +['Ġbless', 'ings'] +['Ġswift', 'ly'] +['b', 'uster'] +['Ġa', 'vid'] +['COM', 'M'] +[',', 'temp'] +['Ġ}', '?>Ċ'] +['-g', 'rowing'] +['Ġdeep', 'copy'] +['A', 'ck'] +['egg', 'ies'] +['Ġ__', '("'] +['Ġno', 'ir'] +['terror', 'ism'] +['Ġanth', 'em'] +['ag', 'ency'] +['_PACK', 'AGE'] +['ĠC', 'losure'] +['.reg', 'istry'] +['Ġmamm', 'als'] +['<', 'L'] +['U', 'ICollectionView'] +['ĠLED', 's'] +['Ġvol', 'ley'] +['(', 'Buffer'] +['_N', 'ATIVE'] +['lib', 'c'] +['impl', 'ode'] +['Scroll', 'Bar'] +['ĠMar', 'ion'] +['.Con', 'tracts'] +['_A', 't'] +['ĠWe', 'instein'] +['compare', 'To'] +['ĠH', 'ose'] +['en', 'ity'] +['.create', 'Query'] +['_r', 'outer'] +['Ġstim', 'uli'] +['Ġ++', ')'] +['ĠCh', 'amp'] +['ĠBay', 'ern'] +['ass', 'a'] +['.v', 'a'] +['Ġdistrib', 'utors'] +['Ġfile', 'private'] +['Ġdepart', 'ed'] +['cc', 'cc'] +['@', 'click'] +['ĠL', 'unch'] +['>', 'L'] +['Ġbl', 'uetooth'] +['.De', 'ep'] +['-', 'standing'] +['ác', 'il'] +['Ġro', 'oft'] +['ĠPath', 's'] +['_iter', 'ations'] +['Invalid', 'ArgumentException'] +['.s', 'pi'] +['ĠUIAlert', 'Action'] +['uy', 'e'] +['sign', 'in'] +['.p', 'riority'] +['ĠEss', 'ays'] +["='", '{$'] +['Ġè¿', 'ĶåĽŀ'] +['_s', 'igned'] +['.p', 'ersist'] +['Ġred', 'esign'] +['To', 'Lower'] +['ĠNew', 'man'] +['=', 'start'] +['ĠIsrael', 'is'] +['asis', 'wa'] +['Spe', 'ech'] +['Ġnum', 'eros'] +['hand', 'lers'] +['ĠW', 'ong'] +['Ġм', 'еÑĤод'] +['We', 'ights'] +['ĠGu', 'jar'] +['te', 'il'] +['ĠNon', 'etheless'] +['_E', 'FFECT'] +['Ġv', 'ect'] +['ĠO', 'sc'] +['Ġco', 'ats'] +['ĠW', 'heat'] +['Ġge', 'ek'] +['ĠPRO', 'PERTY'] +['w', 'orm'] +['_const', 'ants'] +['ĠB', 'oulder'] +['ĠP', 'arm'] +['co', 'le'] +['Ġdefault', 'Center'] +['ĠRou', 'ge'] +[':', 'A'] +['xc', 'f'] +['ĠVen', 'ice'] +['med', 'ian'] +['Ġred', 'emption'] +['F', 'resh'] +['Ġcos', 'm'] +['Ġfig', 'ur'] +['Ġref', 'urb'] +['CO', 'PE'] +['.c', 'd'] +['Ġch', 'ords'] +['ĠS', 'gt'] +['Å', 'į'] +['VP', 'N'] +['ĠS', 'END'] +['ain', 'en'] +['_account', 's'] +['Ġtent', 'h'] +['Ġdiss', 'olved'] +['<', 'App'] +['ĠCover', 'age'] +['use', 'State'] +['é', 'ro'] +['..', '<'] +['Ġì', '£¼'] +['Ġdream', 'ing'] +['ĠFore', 'cast'] +['.C', 'ursors'] +['Ġvis', 'as'] +['/', 'script'] +['_start', 'ed'] +['Ġga', 'str'] +['(P', 'RO'] +['];', '//'] +['.T', 'ile'] +['*', 'sin'] +['(', 'Adapter'] +['ĠSand', 'ra'] +['_S', 'IG'] +['ard', 'ash'] +['ĠO', 'val'] +['Ġdescri', 'pcion'] +['(s', 'l'] +['ĠDes', 'criptor'] +['Ġ`', '$'] +['/f', 'ree'] +['ĠKey', 'words'] +['Ġt', 'udo'] +['ion', 'ale'] +['(f', 'ound'] +['.x', 'yz'] +['ĠGeneration', 'Type'] +['_DISABLE', 'D'] +['(', 'area'] +['Ġel', 'ites'] +['Ġh', 'ombre'] +['(m', 'essages'] +['ĠR', 'ac'] +['Ġext', 'ingu'] +['ĠEst', 'a'] +['op', 'o'] +['.', 'vel'] +['mouse', 'out'] +['Ġconv', 'olution'] +['ĠHand', 'ling'] +['Ġceil', 'ings'] +['T', 'ek'] +['ĠAre', 'as'] +['.writer', 'ow'] +['<', 'View'] +['ĠCorn', 'ell'] +['_B', 'IN'] +['.in', 'valid'] +["''", "'čĊ"] +['ie', 'ż'] +['_P', 'osition'] +['Ġk', 'idding'] +['PC', 'ODE'] +['Ġwatch', 'er'] +['lo', 'x'] +['Ġâ', 'Ĺ'] +['D', 'ave'] +['_all', 'ow'] +['Ġbis', 'exual'] +['Ġun', 'ordered'] +['ĠSch', 'we'] +['_se', 'gments'] +['Ġt', 'earing'] +['IN', 'LINE'] +['Ġund', 'es'] +['.g', 'oods'] +['.c', 'am'] +['ĠL', 'W'] +['ĉ', 'where'] +['Cal', 'culator'] +['-th', 'reat'] +['-', 'alert'] +['ĠSuz', 'uki'] +['ĠIP', 'A'] +['ĠAtt', 'achment'] +['AC', 'CESS'] +['(d', 'type'] +['O', 'pp'] +['_s', 'ymbols'] +['Ġdans', 'ke'] +['l', 'age'] +['or', 'get'] +['res', 'olution'] +['е', 'Ñĩ'] +['ĠQ', 'Color'] +['ĠBar', 'rett'] +['аÑĨи', 'Ñı'] +['=', "\\'"] +['ĠNav', 'Controller'] +['/', 'ref'] +['(c', 'ountry'] +['_H', 'DR'] +['Ġterse', 'but'] +['pet', 'ition'] +['Ġsu', 'f'] +['cred', 'its'] +['à¹', 'Į'] +['x', 'm'] +['ĠDav', 'ies'] +['.re', 'ddit'] +['Ġw', 'oven'] +['ĠO', 'bl'] +['ĠK', 'M'] +['ĠConsider', 'ing'] +['ens', 'ored'] +['.per', 'iod'] +['Ġd', 'dl'] +['$', 'wp'] +['Ġextrem', 'ist'] +[';', '\\Ċ'] +['Ġk', 'im'] +['al', 'ers'] +['Ġspan', 'ning'] +['Ġco', 'herent'] +['Ġconse', 'gu'] +['.text', 'Label'] +['.g', 'eneral'] +['_d', 'ashboard'] +['л', 'ение'] +['k', 'ick'] +['_P', 'ID'] +['ĠExt', 'ensions'] +['reg', 'exp'] +['ĠCl', 'ause'] +['_m', 'ov'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠ'] +['ĠR', 'eward'] +['ĠLEG', 'O'] +['A', 'k'] +['=-=-', '=-=-'] +['ĉ', 'parser'] +['Ġon', 'ze'] +['éĢ', 'Ģ'] +['âĢĿ', 'ãĢĤ'] +['_b', 'all'] +['(r', 'hs'] +['Ġch', 'orus'] +['<', 'count'] +['as', 'urable'] +['Ġwirk', 'lich'] +['ĠEr', 'in'] +['ĠMS', 'NBC'] +['Ġet', 'ter'] +['ĠC', 'ron'] +['_F', 'LOW'] +['Ġ,', 'čĊ'] +['Ġcal', 'idad'] +['ĠFile', 'Writer'] +['ĉ', 'stmt'] +['(', 'Byte'] +['_p', 'at'] +['Ġte', 'lescope'] +['Ġgre', 'ed'] +['ĠT', 'ort'] +['(w', 'rite'] +['\\', 'application'] +['ĉRT', 'LR'] +['ĠConfiguration', 'Manager'] +['Un', 'ix'] +['End', 'Time'] +['In', 'cludes'] +['ĠHar', 'vest'] +['en', 'berg'] +['ĠAustral', 'ians'] +['Ġë', 'ĵ'] +['Ġr', 'n'] +['Ġreput', 'able'] +['Ġbl', 'ending'] +['UL', 'ATION'] +['ĠBrend', 'an'] +['d', 'ad'] +['Ġm', 'ø'] +['ĠW', 'oo'] +['_d', 'c'] +['U', 'ne'] +['Ġr', 'ue'] +['with', 'in'] +['ang', 'ep'] +['Ġp', 'ouch'] +['\\"', '",'] +['ĠS', 'ic'] +['âĢĿ', '),'] +['aly', 'ze'] +['ĠG', 'ef'] +['c', 'overs'] +['Ġd', 'bo'] +['replace', 'All'] +['ĉ', 'Logger'] +['Try', 'ing'] +['[', 'state'] +['-p', 'iece'] +['éĸ', 'ĵ'] +['beh', 'avior'] +['all', 'ows'] +['l', 'rt'] +['_p', 'ython'] +['ert', 'ura'] +['-c', 'ountry'] +['ĠT', 'G'] +['.UI', 'Manager'] +['b', 'ens'] +['ale', 'x'] +['ĠBre', 'itbart'] +['b', 'ac'] +['Ġpredict', 's'] +['Ġg', 'ab'] +['Ġcard', 'inal'] +['.Time', 'Unit'] +['ĠVis', 'itor'] +['ĠM', 'ing'] +['Ġliv', 're'] +['Ġparent', 'Id'] +['port', 'un'] +['Ġdimension', 'al'] +['ĠV', 'est'] +['en', 'ic'] +['à', '³'] +['Ġ', 'Ùĩ'] +['ĠBL', 'UE'] +['Ġitem', 'Count'] +['Ġfe', 'athers'] +['ĉp', 'stmt'] +['ĠPol', 'ar'] +['{', '//'] +['und', 'i'] +['Ñĥ', 'ж'] +['z', 'ar'] +['Error', 'Response'] +['ì', 'ĥģ'] +['Rep', 'resentation'] +['*', '_'] +['+', ']'] +['pre', 'pend'] +["Ġ'", '>'] +['Ġlegitim', 'acy'] +['Ġo', 'o'] +['S', 'linky'] +['Ġnation', 'als'] +['.', 'words'] +[';', 'p'] +['tr', 'ap'] +['oman', 'ip'] +['Ġc', 'ues'] +['Ġgradu', 'ating'] +['Ġsem', 'aphore'] +['"]', ');ĊĊ'] +['ace', 'y'] +['RE', 'ET'] +['Gr', 'ab'] +['ĠFel', 'ix'] +['(', 'Id'] +['_ne', 'ighbors'] +['Ġmeaning', 'less'] +['(d', 'el'] +['Ġj', 'eder'] +['ĠContent', 'Values'] +['.abs', 'olute'] +['/', 'cl'] +['Ġx', 'b'] +['dat', 'um'] +['Ġtort', 'ured'] +['Ġrub', 'bing'] +['S', 'cores'] +['ĠðŁĺ', 'ī'] +['Ġav', 'ons'] +['Ġam', 'sterdam'] +['E', 'OS'] +['H', 'al'] +['Ġtrust', 'worthy'] +['#', '='] +['.EX', 'TRA'] +['Ġman', 'o'] +['is', 'icing'] +['-s', 'upport'] +['ĉc', 'ursor'] +['ĠSp', 'o'] +['aim', 'assage'] +['M', 'ission'] +['[]', '{"'] +['Ġprint', 'ers'] +['G', 'REEN'] +['Ġt', 'eg'] +['Ġabdom', 'inal'] +['!', 'ĊĊĊĊĊĊ'] +['.Sh', 'ort'] +['аз', 'в'] +['ĠGift', 's'] +['}', '")'] +['(b', 'inding'] +['x', 'ce'] +['âĢ', 'ij'] +['inf', 'os'] +['Form', 'Data'] +['Ġd', 'art'] +['Ġele', 'ms'] +['(in', 'v'] +['Y', 'L'] +['t', 'in'] +['GEN', 'ER'] +['á»', '¯'] +['ĠT', 'aken'] +['uck', 'le'] +[':', 'e'] +['Ġspect', 'ral'] +['.b', 'aidu'] +['/', "');Ċ"] +['Ġgre', 'edy'] +['es', 'ion'] +[',,,,', ',,,,'] +['Ġ/>', ',Ċ'] +['Internal', 'ServerError'] +['NSNotification', 'Center'] +['ĠA', 'i'] +['Ġsp', 'it'] +['Ġaug', 'mented'] +['Ġstandard', 'UserDefaults'] +['FIN', 'ITY'] +['R', 'ace'] +[':', 'C'] +['ĠRE', 'CORD'] +['ĠHigh', 'light'] +["Ġ'", '`'] +['Ġdef', 'icits'] +['Ġne', 'i'] +['Ġresearch', 'ed'] +['T', 'a'] +['Ġc', 'opp'] +['.Get', 'HashCode'] +['):', 'čĊčĊ'] +['On', 'Click'] +['ĠWell', 'ington'] +['Ġrev', 'ival'] +['æ¯', 'Ķ'] +['éĹ', '®'] +['ĠN', 'SS'] +['Ġfor', 'n'] +['Ġint', 'é'] +['ĠKu', 'wait'] +['_fl', 'ip'] +['_', 'bo'] +['_', '\\'] +['Ġocc', 'urrences'] +['ĠScient', 'ists'] +['S', 'RC'] +['og', 'ens'] +['igr', 'ant'] +['RE', 'MOTE'] +['ĠS', 'ID'] +['.', 'opts'] +['u', 've'] +['()', '])Ċ'] +['Ġlibert', 'arian'] +['ĠGl', 'ide'] +['les', 'en'] +['Ġform', 'e'] +['ow', 'ania'] +['Ġannoy', 'ed'] +['Def', 's'] +['ĠExec', 'utor'] +['Ġcast', 's'] +['.set', 'Checked'] +['ĠSh', 'aring'] +['.Serialize', 'Object'] +['Ġselect', 'ors'] +['_', 'OTHER'] +['ë¯', '¸'] +['(s', 'uper'] +['(', 'OS'] +['_VER', 'IFY'] +['id', 'unt'] +['<', 'header'] +['Ġ/>', "';Ċ"] +['Ġvidé', 'o'] +['ĠNeg', 'ro'] +['ĠL', 'ords'] +['ĠT', 'ours'] +['Ġsoft', 'ly'] +['.re', 'ceive'] +['ĠE', 'RC'] +['Ġdata', 'Set'] +['Bad', 'ge'] +['ĉ', 'Event'] +['Ġper', 'l'] +['Ġ{}', '\\'] +['(s', 'entence'] +['Or', 'Update'] +['Ġdim', 'inish'] +['P', 'IN'] +['(d', 'raw'] +['.To', 'DateTime'] +['.Equal', 'To'] +['(p', 'in'] +['-p', 'encil'] +['lu', 'ent'] +['ĠCall', 'er'] +['Ġplay', 'ful'] +['-', "'+"] +['x', 'ca'] +['sw', 'ick'] +['){', '}Ċ'] +['}:', '${'] +['ĠM', 'eth'] +['.get', 'Cell'] +['.b', 'reak'] +['Ġy', 'max'] +["='", 'Ċ'] +['ĠH', 'iro'] +['(', 'TRUE'] +['as', 'urer'] +['Ġcu', 'er'] +['U', 'ber'] +['.', 'Operation'] +['Ġol', 'an'] +['Ġthr', 'illing'] +['<', 'Response'] +['ĠF', 'emin'] +['Ġtravers', 'al'] +['Ġp', 'oc'] +['Ġset', 'Status'] +['decl', 'ar'] +['std', 'afx'] +['Ġaddict', 'ive'] +['ĠB', 'tn'] +['Ġexplos', 'ives'] +['ĠCook', 'ing'] +['ĠPl', 'aint'] +['Ġaccum', 'ulator'] +['ĠApp', 'ointment'] +[',', 'password'] +['ĠF', 'AR'] +['lu', 'et'] +['Further', 'more'] +['decl', 'spec'] +['_Static', 's'] +['.D', 'ictionary'] +['">', "'."] +['ĉ', 'valid'] +['"', '",'] +['In', 'strument'] +['>', 'J'] +['Ġno', 'str'] +['ĠR', 'ift'] +['_P', 'ort'] +['Ġvec', 'es'] +['[', "['"] +['Ġrall', 'ies'] +['-', 'series'] +['Ġv', 'v'] +['.', 'uc'] +['Ġr', 'tn'] +['State', 'Changed'] +['(', 'ins'] +['ĠCl', 'a'] +['------------', 'Ċ'] +['c', 'us'] +['ĠRel', 'oad'] +['//----------------------------------------------------------------', '--------------------------------'] +['.se', 'conds'] +['_dest', 'ination'] +['Ġscrew', 'ed'] +['>', 'c'] +['Th', 'ickness'] +['Design', 'er'] +['Ġgr', 'ids'] +['n', 'Äħ'] +['(', 'cookie'] +['T', 'rip'] +['-M', 'obile'] +['Ġv', 'oll'] +['Ġgen', 'ital'] +['Ġconf', 'isc'] +['ĠConfeder', 'ate'] +['Ġweb', 'View'] +['Ġm', 'ise'] +['Ġcl', 'er'] +['(se', 'lection'] +['$', 'date'] +['Ġshar', 'pen'] +['rag', 'en'] +['And', 'Update'] +['Ġrem', 'ix'] +['Ġh', 'tons'] +['R', 'W'] +['M', 'PI'] +['Ġretrie', 'val'] +['Ġric', 'hest'] +['.Dec', 'ode'] +[':init', 'Components'] +['ĠT', 'Value'] +['S', 'aint'] +['@', 'include'] +['ĠPER', 'SON'] +['.se', 'p'] +['ĠLD', 'AP'] +['g', 'ba'] +['Ġgro', 'ÃŁe'] +['Ġreli', 'ably'] +['ĠD', 'FS'] +['.getItem', 'Id'] +['Ġprés', 'ent'] +['.get', 'Token'] +['Ġch', 'inese'] +['ĠMe', 'al'] +['Y', 'OU'] +['">', '>ĊĊ'] +['b', 'ower'] +['Ġsw', 'apped'] +['/', 'install'] +['Ġs', 'inks'] +['etr', 'ize'] +['Ġdecl', 'ines'] +['ĉm', 'ysql'] +['ĠC', 'String'] +['ĠMotion', 'Event'] +['.L', 'anguage'] +['R', 'oad'] +['ÑĤ', 'еÑĢ'] +['asc', 'imento'] +["'))", '->'] +['.', 'about'] +['(', 'editor'] +['ĠR', 'atings'] +['in', 'come'] +['Å¡', 'e'] +['.de', 'queueReusableCell'] +['ĠAust', 'rian'] +['Ġs', 'ulla'] +['ĠTrib', 'unal'] +['ĠDid', 'n'] +['ов', 'аÑĢ'] +['Ġins', 'pections'] +['B', 'oss'] +['Ġcock', 'tails'] +['Ġapolog', 'ized'] +['_sub', 'plot'] +['op', 'al'] +['+', '=('] +['Ġreson', 'ance'] +['ib', 'u'] +['Ġë', '¦¬'] +['rom', 'a'] +['res', 'erve'] +['pl', 's'] +['ĠT', 'ah'] +['ax', 'ies'] +['OP', 'LE'] +['ĠDar', 'ren'] +['ĠZ', 'ombie'] +['_M', 'ap'] +['Ġ]', ')ĊĊ'] +['ĠQ', 'i'] +['ĠS', 'ail'] +['Ġrestrict', 'ive'] +['Ġeros', 'ion'] +['-', 'par'] +['WH', 'ITE'] +['Ġold', 'u'] +['Ġap', 'erture'] +['Ġbit', 'coins'] +['text', 'o'] +['ĠCom', 'cast'] +['Ġtime', 'less'] +['en', 'kins'] +['Ġfeed', 'er'] +['/', 'tmp'] +['res', 'den'] +["+'", '_'] +['.D', 'estroy'] +['Ġç', 'ok'] +['ĠD', 'OCUMENT'] +['.l', 'ng'] +['.tag', 'Name'] +['Ġk', 'ullan'] +['eg', 'rate'] +['Ġ(*', '.'] +['ç¼ĸ', 'è¾ij'] +['Ġhand', 'shake'] +['s', 'oc'] +['_', 'geometry'] +['ĠDam', 'ascus'] +['Min', 'or'] +['ĠK', 'afka'] +['ìĹ', '¬'] +['Fl', 'orida'] +['_com', 'pute'] +['.ex', 'pr'] +['Ġpar', 'alle'] +['ĠD', 'iaz'] +['c', 'ir'] +['[', 'target'] +['Ġj', 'oking'] +['Ġgl', 'or'] +['(set', 'q'] +['_hand', 'lers'] +['H', 'ang'] +['Ġf', 'err'] +['rim', 'inal'] +['ĉĠĠĠĠ', 'ĉĉ'] +['ent', 'ies'] +['def', 'ines'] +['-t', 'ax'] +['json', 'p'] +['ĠU', 'PS'] +['met', 'ro'] +['__', ';Ċ'] +['ĠUg', 'anda'] +[']))', ':Ċ'] +['_t', 'd'] +['x', 'ae'] +['l', 'w'] +['.', 'OS'] +['ĠLog', 'ged'] +['ac', 'id'] +['ĠMay', 'o'] +['as', 'pect'] +['Ġvag', 'inal'] +['Ġinitial', 'izing'] +['Ġster', 'oids'] +['f', 'iction'] +['G', 'RE'] +['g', 'end'] +['Ġli', 'abilities'] +['ĠL', 'ets'] +['M', 'ech'] +['(', 'nc'] +['(', 'change'] +['Ġconnect', 'ors'] +[':', 'k'] +['Ġt', 'ast'] +['!', '");ĊĊ'] +['th', 'ings'] +['ro', 'phy'] +['luet', 'ooth'] +['ĠSign', 'Up'] +['.', 'ctrl'] +['Ġthere', 'in'] +['ord', 'a'] +['.', 'escape'] +['ig', 'ator'] +['Ġpet', 'rol'] +['Ġspec', 'imen'] +['Ġdeb', 'uted'] +['-', 'Pro'] +['Ġcr', 'ises'] +['.add', 'View'] +['ëı', 'Ļ'] +['-d', 'oor'] +['Ġmon', 'et'] +['Ġmill', 'is'] +['Ġv', 'ier'] +['Internal', 'Enumerator'] +['Ġadmin', 's'] +['ĠL', 'air'] +['z', 'in'] +['get', 'Query'] +['umb', 'les'] +['L', 'IMIT'] +['ĠV', 'ig'] +['_s', 'ong'] +['<', 'Character'] +['::', '.'] +['_h', 'om'] +['_b', 'p'] +['ĠSup', 'ervisor'] +['sub', 'mission'] +['ab', 'ile'] +['Ġno', 'i'] +['Or', 'Create'] +['Ġpe', 'el'] +['Ġon', 'Start'] +['Ġsent', 'iments'] +['veh', 'icles'] +['Ġclass', 'rooms'] +['Ġs', 'zer'] +['Ġb', 'ending'] +['Ġlong', 'evity'] +['Ġa', 'cl'] +['ĠAle', 'ppo'] +['ĠU', 'M'] +['ĠR', 'icht'] +['Ġmultip', 'rocessing'] +['DOM', 'AIN'] +['","', '+'] +['_Y', 'EAR'] +['Ġsc', 'rape'] +['Ġsol', 'itary'] +['Ġ"]', '";Ċ'] +['/', 'errors'] +['ìŀ', '¬'] +['ľ', 'ëł¥'] +['b', 'etter'] +['ĉ', 'number'] +['ĠL', 'F'] +['ĠAc', 'ross'] +['Pub', 'Med'] +['\\"', '"'] +['ĠExcell', 'ence'] +['Ġus', 'ando'] +['ĠU', 'IP'] +['Activity', 'Indicator'] +['_V', 'OID'] +['Ġbre', 'eds'] +['ï½', '¥'] +['uest', 'as'] +['ĠTre', 'asure'] +['ustral', 'ian'] +['(f', 'ace'] +['ĠT', 'ennis'] +['ĉ', 'Int'] +['ĠHans', 'en'] +['ç', 'µ'] +[':', 'I'] +['Ġâľ', 'Ķ'] +['GR', 'AY'] +['O', 'USE'] +['Ġhe', 'pat'] +['ł', 'í'] +['A', 'IR'] +['ó', 'ż'] +['Ġque', 'ued'] +['vinc', 'ia'] +['ĠChrom', 'ium'] +['Ġcompet', 'ence'] +['ung', 'al'] +['ill', 'i'] +['Ġget', 'By'] +['ĠF', 'inder'] +['Ġincap', 'able'] +['Ġs', 'add'] +['Ġc', 'ites'] +['ĠChurch', 'ill'] +['S', 'dk'] +['More', 'over'] +['As', 'pNet'] +['(', 'Float'] +['$', 'password'] +['ĠConn', 'or'] +['-s', 'ession'] +['_d', 'm'] +['*', '))'] +['Ġde', 'utsch'] +['ĠN', 'X'] +['Ġper', 'ks'] +['_S', 'ORT'] +['_TO', 'OL'] +['_V', 'ISIBLE'] +['.as', 'p'] +['æĪ', 'ĸ'] +['ĠBre', 'ath'] +['D', 'etect'] +['ĠD', 'uel'] +['.c', 'mb'] +['[', 'it'] +['.Set', 'Bool'] +['Ġnarc', 'iss'] +['Ġab', 'ide'] +['Ġej', 'emplo'] +['ĠâĦ', 'ķ'] +['Ġm', 'ornings'] +['Ġcomput', 'es'] +['.s', 'sl'] +['j', 't'] +['Ġmuch', 'os'] +['_S', 'S'] +['[', 'end'] +['Ġbas', 'in'] +['Ġalgun', 'os'] +['ĠCroat', 'ia'] +['lin', 'ewidth'] +['(t', 'ags'] +['(h', 'idden'] +['ÃŃc', 'io'] +['Ġap', 'ar'] +['ĠÐ', '¶'] +['ä¸', 'İ'] +['.', 'food'] +['ĠR', 'ural'] +['Ġbread', 'th'] +['å½', '±'] +['(s', 'ess'] +['+', '")'] +['ĠP', 'aste'] +['Ġserv', 'idor'] +['ĠBit', 'Set'] +['ĠTr', 'an'] +['la', 'us'] +['v', 'ette'] +['ey', 'es'] +['ĠCL', 'ICK'] +['ĠV', 'III'] +['ĠTurn', 's'] +['ĠLe', 'Bron'] +['ĠM', 'uj'] +['ĠD', 'eg'] +['ĠAdult', 's'] +['_s', 'uite'] +['process', 'able'] +['ĠPH', 'Y'] +['g', 'hest'] +['.F', 'ail'] +['ĠSl', 'ack'] +['ce', 'j'] +['\\', 'Carbon'] +['Ġsuper', 'star'] +['Ġhold', 'ings'] +['(', 'forms'] +["Ġ'#", "'"] +['M', 'ultip'] +['("[', '%'] +['-s', 'olid'] +['/', 'url'] +['-t', 'ier'] +['[', 'length'] +['ĠStream', 'Writer'] +['ĠMarket', 'place'] +['get', 'text'] +['_T', 'ICK'] +['ĠFor', 'ge'] +['Ġblack', 'jack'] +['ĠDO', 'ES'] +['ĠM', 'atters'] +['w', 'aves'] +['Ġwhisper', 'ed'] +['Ġl', 'ush'] +['ìĺ', '¤'] +['d', 'igital'] +['Ġwr', 'ink'] +['ĠH', 'ogan'] +['Ġrust', 'ic'] +['.Apply', 'Resources'] +['ĠHard', 'y'] +['os', 'omes'] +['A', 'UT'] +['.ST', 'ATE'] +['Ġnarr', 'atives'] +['ĉ', 'store'] +['b', 'ib'] +['ĉ', 'Scanner'] +['ĠC', 'ody'] +['\\', 'Repositories'] +['Ġre', 'union'] +['and', 'um'] +['âĢĻ', 'h'] +['Ġsn', 'iff'] +['NS', 'Bundle'] +['Ġcompreh', 'end'] +['_US', 'AGE'] +['_', 'occ'] +['URRE', 'NCY'] +['J', 'NI'] +['Ġspecial', 'izing'] +['Ġvis', 'ions'] +['Ġdol', 'ore'] +['Ġv', 'á'] +['ĠChe', 'vy'] +['ĠSt', 'yled'] +['imp', 'act'] +['all', 'en'] +['Ġk', 'art'] +['ĠTable', 't'] +['st', 'uff'] +['re', 'esome'] +['аÑĤ', 'оÑĢ'] +['//----------------------------------------------------------------', '-----------Ċ'] +['_Ad', 'min'] +['Ġcell', 'phone'] +['Ġaut', 'oplay'] +['Ġcamb', 'io'] +['Ġmar', 'itime'] +['_BO', 'OT'] +['-', 'quarter'] +['Ġlat', 'ina'] +['ĠAJ', 'AX'] +['e', 'quiv'] +['ĠFront', 'ier'] +['ĠX', 'Y'] +['}', ']Ċ'] +['ĠR', 'ough'] +['.pro', 'to'] +['Ġcorrect', 'ness'] +['Ġfac', 'il'] +['ĠRe', 'ached'] +['ãģĿ', 'ãģ®'] +['V', 'IS'] +['.p', 's'] +['Ġstr', 'ncpy'] +['Ġdiff', 'usion'] +['.start', 'Activity'] +['��', '�'] +['Ġaccom', 'p'] +['AMES', 'PACE'] +['imon', 'ials'] +['ĠBl', 'ast'] +['aby', 'rin'] +['Ġd', 'ome'] +['Ġextr', 'av'] +['Ġy', 'en'] +['Ġcul', 'inary'] +['P', 'RI'] +['ĠComm', 'unities'] +['n', 'id'] +['_oper', 'ations'] +['.h', 's'] +['ĠMil', 'ton'] +['Ġno', 'ises'] +['Autoresizing', 'Mask'] +['(c', 'id'] +['}ĊĊ', 'ĊĊĊĊ'] +[']', '},Ċ'] +['ĠD', 'etection'] +['tab', 'la'] +['Ġlib', 'erties'] +['_D', 'YNAMIC'] +['w', 'get'] +['ĠT', 'ür'] +['ĠP', 'ascal'] +['Trans', 'parent'] +['Delay', 'ed'] +[']', '()'] +['ĠHer', 'bert'] +['<', 'ActionResult'] +['ch', 'allenge'] +['Ġmush', 'room'] +['.insert', 'Before'] +['ĠR', 'in'] +['Ġhum', 'our'] +['Ġf', 'ø'] +['api', 'Key'] +['alloc', 'ated'] +['Ġconf', 'ession'] +['.', '",čĊ'] +['ĉassert', 'That'] +['ĠS', 'ORT'] +['ĠL', 'ORD'] +['Ġexport', 'er'] +['.set', 'Level'] +['p', 'okemon'] +['ash', 'tra'] +['Ġf', 'é'] +['ur', 'ator'] +['(M', 'SG'] +['Ġt', 'up'] +['ĠH', 'ull'] +['Ġyield', 'ed'] +['.Sub', 'ject'] +['\\', 'Route'] +['!', '?'] +['ĠÑĥ', 'дал'] +['\\', 'Security'] +['-', 'ar'] +['Ġalleg', 'ation'] +['(', 'Settings'] +['ä', 'nder'] +['Ġell', 'ipse'] +['ĠRetro', 'fit'] +['Ġregul', 'ating'] +['ĠM', 'olly'] +['ĠL', 'ok'] +['_C', 'ustom'] +['ĠProm', 'o'] +['is', 'in'] +['Ġres', 'umed'] +['Ġmet', 'ropolitan'] +['.error', 'Message'] +[':', '-------------'] +['Ġpas', 'ado'] +['th', 'ank'] +['_De', 'lete'] +['ĠBright', 'on'] +[',', 'unsigned'] +['ä½ľ', 'èĢħ'] +['Ġaspir', 'ations'] +['-h', 'ow'] +['R', 'ose'] +['=', '(('] +['_ne', 'eded'] +['_pl', 'ural'] +['<', 'Application'] +['ĠW', 'EEK'] +['ĠUn', 'lock'] +['ĠT', 'EMP'] +['S', 'ou'] +['Ġschizophren', 'ia'] +['Ġt', 'roll'] +['Ġcomplement', 'ary'] +['ĠNET', 'WORK'] +['Ġbl', 'ir'] +['Ġprogress', 'Dialog'] +['"', '%('] +['ĠAttribute', 'Set'] +['ĉ', 'ts'] +['.iter', 'items'] +['è¯', 'Ŀ'] +['Ġesc', 'rit'] +['v', 'ous'] +['_pl', 'aces'] +['H', 'K'] +['Ġseg', 'uir'] +['_f', 'w'] +['ĠR', 'ounded'] +['Ġdis', 'posit'] +['è§', 'Ĩ'] +['par', 'm'] +['w', 'ow'] +['STRU', 'CTION'] +['.', 'allow'] +['ĠChar', 'Sequence'] +['ĉ', 'extern'] +['Ġprosec', 'uted'] +['Ġmort', 'ar'] +['ĠJ', 'uda'] +['-', 'msg'] +['Ġest', 'ud'] +['.get', 'Description'] +['Ġs', 'ow'] +['amb', 're'] +['Ġrom', 'a'] +['En', 'h'] +['bon', 'us'] +['Ġsqu', 'at'] +['Ġdist', 'ra'] +['ed', 'Image'] +['Ġpe', 'ppers'] +['-per', 'formance'] +[',', 'ĊĊĊ'] +[',', 'file'] +['ĠM', 'IME'] +['_con', 'cat'] +['AB', 'S'] +['-f', 'ashion'] +['Ġunder', 'cover'] +['One', 'ToMany'] +['Ġre', 'claim'] +['C', 'OPY'] +['Ġb', 'inds'] +['ĠT', 'ape'] +['Ġg', 'ossip'] +['ĠEqu', 'ity'] +['/', 'Card'] +['.', 'activ'] +["'", 'am'] +['Ġdrain', 'age'] +['<', 'Scalars'] +['ĠonBind', 'ViewHolder'] +['()', '?.'] +['Ġs', 'orrow'] +['ĠI', 'b'] +['up', 'y'] +['_U', 'UID'] +['ĠCh', 'arm'] +['ĠElection', 's'] +['.on', 'Destroy'] +['ĠInterest', 'ingly'] +['ounding', 'Box'] +['_d', 'etection'] +['-h', 'eld'] +['_', 'unknown'] +['Ġrefr', 'ain'] +['Ġmét', 'odo'] +['Ġe', 'Book'] +['EN', 'OMEM'] +['Ġd', 'ang'] +['Prof', 'essional'] +['Ġd', 'ictionaries'] +['/m', 'ysql'] +['ĠST', 'UD'] +['Ġmas', 'se'] +['s', 'cape'] +['Ġdre', 'i'] +[':', 'name'] +['.log', 'o'] +['Sign', 'Up'] +['Ġt', 'ahun'] +['(', 'theme'] +['ĠFem', 'me'] +['Ġbom', 'ber'] +['ĠJ', 'ade'] +['ĠT', 'ay'] +['Ġsubmar', 'ine'] +['_cl', 'ause'] +['zy', 'ch'] +['Ġsimult', 'aneous'] +['Ġcas', 'os'] +['.', 'boolean'] +['(l', 'hs'] +['Ġcontin', 'ental'] +['-s', 'ale'] +['ĉ', 'env'] +['ĠC', 'ute'] +['ĠFactory', 'Girl'] +['ab', 'us'] +['/', 'value'] +['Ġj', 'adx'] +['Ġst', 'ern'] +['>', '>ĊĊ'] +['Ġsurf', 'aced'] +['Ġìł', 'Ģìŀ¥'] +['pl', 'atz'] +['ĉ', 'email'] +['cept', 'ors'] +['">', '('] +['Ġep', 'ile'] +['è¯', '»'] +['ĠDe', 'bt'] +['åij', 'Ĭ'] +['N', 'OP'] +['"', 'https'] +[':', 'j'] +['Form', 'Item'] +['_L', 'ICENSE'] +['.get', 'Double'] +['ĠAg', 'enda'] +['ĉf', 'inally'] +['(f', 'ilters'] +['(', 'av'] +['ç¾', 'İ'] +['AP', 'ER'] +['Ġl', 'ava'] +['еÑĢ', 'ж'] +['))', '))ĊĊ'] +['Ġfault', 'y'] +['_n', 'm'] +['Ġtr', 'ava'] +['(B', 'itmap'] +['Ġspeed', 'ing'] +['>', "')."] +['Ġscreen', 'ed'] +['_', 'roll'] +['ĠMac', 'Book'] +['ĠA', 'UD'] +['Ġdiagn', 'ose'] +['.G', 'enerate'] +['Ġ^', '^'] +['Ġstr', 's'] +['[', 'Test'] +['Ġr', 'ansom'] +['ĠDH', 'CP'] +['eld', 'en'] +['Ġinterpret', 'ations'] +['()', '].'] +['flat', 'Map'] +['Ġline', 'Height'] +['_m', 'ount'] +['ĠW', 'izards'] +['Ġsl', 'uts'] +['eh', 'ler'] +['od', 'al'] +['Ġmilit', 'ia'] +['å', '²'] +['earn', 'ed'] +['Ġmis', 'ery'] +['int', 'val'] +['f', 'und'] +['Ġh', 'ides'] +['Ġdi', 'arr'] +['ĠWes', 'ley'] +['Ġx', 'mm'] +['Ġqu', 'em'] +['ĠAr', 'abs'] +['if', 'th'] +['ategor', 'ized'] +['Dis', 'posable'] +['P', 'ure'] +['_NOT', 'IFY'] +['sn', 'ippet'] +['ĠGar', 'rett'] +['.run', 'ning'] +['.', 'weights'] +['Ġ(', '--'] +['Ġin', 'variant'] +['äºĭ', 'ä»¶'] +['ĠAll', 'owed'] +['dir', 's'] +['Ġpass', 'ions'] +['Ġl', 'ad'] +['ĠFl', 'ush'] +['men', 'us'] +[':', 'block'] +['Ġcompr', 'a'] +['.ch', 'omp'] +['alloc', 'ator'] +['Ġcur', 'ated'] +['ĠKnow', 'ing'] +['ĠPatt', 'erson'] +['Ġtel', 'ah'] +["'", 'ex'] +['Ġdo', 'omed'] +['Ġphil', 'anth'] +['ott', 'y'] +['.st', 'yles'] +['Own', 'ed'] +['Ġallerg', 'ies'] +['=', 'params'] +['oc', 'ese'] +['it', 'elist'] +['ĠS', 'ending'] +['b', 'ef'] +['orr', 'ar'] +['ĠN', 'ão'] +['ĠF', 'argo'] +['ĠL', 'ub'] +['ĠComb', 'ined'] +['_g', 'iven'] +['ĉĉĉĉĉ', 'ĠĠĠĠ'] +['Ġreconc', 'iliation'] +['Pattern', 's'] +['az', 'ard'] +['Ġbiom', 'ass'] +['ĠH', 'ouses'] +['resp', 'uesta'] +['cc', 'o'] +['/top', 'ics'] +['ĠY', 'uk'] +['Ġweaken', 'ed'] +['_c', 'alendar'] +['Ġmulher', 'es'] +['ĠMar', 'l'] +['Ġs', 'ine'] +['ĠT', 'il'] +['ĠSou', 'ls'] +['ĠDe', 'utsche'] +['ĠF', 'OLLOW'] +['Ġpip', 'elines'] +['ĠBever', 'ly'] +['_DIP', 'SETTING'] +['"', '#'] +['ĠPro', 'to'] +['.b', 'ig'] +['ĠSav', 'ings'] +['ĠT', 'anz'] +['j', 'un'] +['ĠG', 'amma'] +['ĠS', 'add'] +['Ġadvis', 'ors'] +['Ġro', 'ast'] +['Ġun', 'ters'] +['ud', 'ies'] +['_l', 'on'] +['-point', 'er'] +['ĠElement', 'Ref'] +['\\', 'Builder'] +['example', 'Input'] +['.web', 'driver'] +['data', 'Type'] +['ĠQu', 'ite'] +['ĠCelt', 'ics'] +['u', 'il'] +['-def', 'ense'] +['b', 'ish'] +['ĠUI', 'Window'] +['ĠS', 'uddenly'] +['.h', 'ot'] +['.re', 'ason'] +['Ġg', 'ör'] +['AM', 'D'] +['.M', 'ulti'] +['auth', 'enticated'] +['reg', 'ions'] +[';', '('] +['а', 'ÑĢам'] +['ĠKir', 'by'] +['$', 'route'] +['PREC', 'ATED'] +['ĠDur', 'ham'] +['ow', 'o'] +['ĠPer', 'forms'] +['Ġdisreg', 'ard'] +['n', 'st'] +['ĠP', 'ols'] +['Ġget', 'P'] +['"]', ':'] +['-col', 'ored'] +['(', 'Keys'] +['ĠAl', 'leg'] +['_mod', 'ify'] +['_', 'loading'] +['str', 'ained'] +['Ġat', 'roc'] +['_p', 'hr'] +['<', 'Sprite'] +['Ġsatisf', 'actory'] +['m', 'anship'] +['.p', 'ipeline'] +['T', 'ony'] +['Ġth', 'ief'] +['pol', 'ator'] +['(', 'lock'] +['bur', 'st'] +['ĠOptim', 'ization'] +['Ġsurf', 'ing'] +['"', 'Yes'] +['Ġdesc', 'ended'] +['æ', 'Ĵ'] +['_C', 'lear'] +['Ġc', 'ries'] +['ĠFro', 'zen'] +['D', 'IRECT'] +['-', 'Con'] +['ĠLe', 'icester'] +['å¥', '³'] +['O', 'OM'] +['=', 'db'] +['Ġget', 'Message'] +['<', 'Student'] +['_b', 'atches'] +['.M', 'ask'] +['_', 'eth'] +['\\', ')'] +['Ġsom', 'a'] +['C', 'atch'] +['[', 'ch'] +['Own', 'ers'] +['ind', 'le'] +[':', 'auto'] +['.', 'vert'] +['iv', 'r'] +['.set', 'Location'] +['Ġfl', 'uent'] +['_END', 'IAN'] +['ĠCar', 'lo'] +['cept', 's'] +['add', 'Action'] +['.o', 'auth'] +['<', 'UnityEngine'] +['re', 'ements'] +['.S', 'kip'] +['?', ')ĊĊ'] +['.default', 'Props'] +['Ġc', 'abe'] +['ĠSh', 'en'] +['eros', 'is'] +['ĠPro', 'fit'] +['Ġpo', 'is'] +['_C', 'REATED'] +['Ġremove', 'From'] +['(w', 's'] +['?', 'action'] +['(', 'Field'] +['Ġerr', 'one'] +['.min', 'imum'] +['ĠRetrie', 'ved'] +['Ġd', 'ado'] +['ĠPR', 'IVATE'] +['-s', 'pec'] +['Ġg', 'zip'] +['p', 'data'] +['Ġpos', 'Y'] +['(l', 'ow'] +['Ġqual', 'quer'] +['/', 'cloud'] +['ê²', 'Į'] +['(', 'common'] +['ĠAr', 'beit'] +['organ', 'isation'] +['Ġtid', 'y'] +['ĠRol', 'and'] +['(', 'ph'] +['.z', 'one'] +['Ġgent', 'lemen'] +['ượ', 'c'] +['å±', '±'] +['Ġenc', 'losure'] +['ĠMan', 'afort'] +['ĉ', 'Color'] +['St', 'encil'] +['N', 'ic'] +['Ġthe', 'orem'] +['ĠV', 'G'] +['Ġcol', 'oured'] +['V', 'BoxLayout'] +['uls', 'ive'] +['Drag', 'on'] +['c', 'ff'] +['et', 'est'] +['ens', 'a'] +['of', 'day'] +['.A', 'zure'] +[':UIControlEvent', 'TouchUpInside'] +['_up', 'dates'] +['Ġtrend', 'y'] +['ug', 'as'] +['weak', 'Self'] +['Ġr', 'idge'] +['ib', 'ri'] +['Ġì¶', 'Ķ'] +['(C', 'G'] +['ĠMon', 'key'] +['.write', 'Int'] +['.tim', 'edelta'] +['ViewController', 'Animated'] +['ĠProvid', 'ence'] +['ãģ', 'Ī'] +['Ġbl', 'ends'] +['/Sub', 'threshold'] +['ĠAp', 'pl'] +['Ġat', 'an'] +['Ġreload', 'Data'] +['umb', 'otron'] +['st', 'üt'] +['O', 'Auth'] +['ĠG', 'iving'] +['ĠìĦ', '¤'] +['ĠFinn', 'ish'] +['check', 'ing'] +['.', 'Embed'] +['sequ', 'elize'] +['Ġinitial', 'izes'] +['ĠOs', 'lo'] +['Ø', '¶'] +['get', 'Extension'] +['_AL', 'T'] +['(bl', 'ank'] +['Ġfatal', 'Error'] +['Ġdem', 'ise'] +['****', '*Ċ'] +['ĠX', 'S'] +['(A', 'F'] +['ĠEn', 's'] +['an', 'tha'] +['ĠP', 'OR'] +['Ġn', 'ich'] +['.N', 'amed'] +['Ġgig', 'antic'] +['ĠObserv', 'atory'] +['.Res', 'olve'] +['ĠPay', 'ments'] +['g', 'uild'] +['Ġcurrent', 'State'] +['============', '===Ċ'] +['ĠS', 'ey'] +['p', 'Data'] +['Ġdead', 'lines'] +['Ġcentral', 'ized'] +['ĠScholar', 'ship'] +['_s', 'upported'] +['.ch', 'rome'] +['()', ']);Ċ'] +['Ġc', 'yan'] +['ĠC', 'age'] +['Auth', 'ors'] +['_', 'čĊ'] +['/', 'os'] +['k', 'im'] +['de', 'e'] +['.t', 'ex'] +['Ġyours', 'elves'] +['Ġm', 'gr'] +['Ġal', 'k'] +['-inst', 'all'] +['Ġdraft', 'ing'] +['Ġrum', 'or'] +['Ġstat', 'ues'] +['Pool', 'ing'] +['ol', 'ina'] +['AAAA', 'AAAA'] +['/*', '----------------------------------------------------------------------------'] +['Ġextrem', 'ists'] +['Cal', 'cul'] +['ighth', 'ouse'] +['In', 'set'] +['(IN', 'PUT'] +['Ġsynchron', 'ization'] +['iv', 'irus'] +['.', 'axes'] +['ĠG', 'ap'] +['-', 'An'] +['_T', 'emplate'] +['Ġgam', 'er'] +['ĠCr', 'icket'] +['Ġl', 'int'] +['Ġauthor', 'itarian'] +['NS', 'UInteger'] +['Ġred', 'o'] +['Ġadip', 'iscing'] +['_F', 'ETCH'] +['che', 'id'] +['ĠF', 'ang'] +['.', 'indices'] +['t', 'one'] +['д', 'ел'] +['Ġ{{--', '<'] +['bra', 'him'] +['Ġsal', 'a'] +['get', 'Code'] +['Ġcommunic', 'ated'] +['start', 'sWith'] +['ert', 'z'] +['Read', 'able'] +['Item', 'Id'] +['oref', 'errer'] +['cred', 'ible'] +['á', 'ria'] +['Ġcombine', 'Reducers'] +['**', '/ĊĊ'] +['Ġbl', 'iss'] +['Ġad', 'orn'] +['dep', 'ends'] +['ĠRO', 'OM'] +['Ġfr', 'aming'] +['Ġ?', "',"] +['aut', 'y'] +['_p', 'ot'] +['_t', 'abs'] +['Ex', 'act'] +[',', '",'] +["Ġ'}", "';Ċ"] +['Ġarbit', 'r'] +['ahr', 'ain'] +['.getString', 'Extra'] +['Ġ$', '\\'] +['Ġoutput', 'Stream'] +['Ġcomm', 'enc'] +['an', 'us'] +['ch', 'y'] +['<', 'Employee'] +['Ġhex', 'atrigesimal'] +['Ġn', 'acional'] +['(serial', 'izers'] +['_put', 'char'] +['_S', 'AFE'] +['ential', 'Action'] +['ItemSelected', 'Listener'] +['.Dis', 'patch'] +['Conf', 'lict'] +['_', 'about'] +['os', 'aur'] +['Bound', 'ary'] +['Ġclear', 'Color'] +['(', 'Location'] +['ĠMON', 'TH'] +['ĠT', 'aste'] +['-', 'General'] +['ĠW', 'AR'] +['Ġer', 'halten'] +['-s', 'aving'] +['Ġcou', 'pling'] +['-tr', 'igger'] +['m', 'otor'] +['Ġy', 'yyy'] +['ĠPat', 'ent'] +['pt', 'o'] +['Ġmisdemean', 'or'] +['vas', 'ion'] +['ĠAdmir', 'al'] +['à¹ī', 'า'] +['_P', 'WR'] +['Ġdevast', 'ated'] +['fol', 'ios'] +['ITU', 'DE'] +['urre', 'ct'] +['Ġrobot', 'ic'] +['ĠSan', 'ct'] +['ĠHawai', 'ian'] +['.R', 'oute'] +['-', 'condition'] +['Ġr', 'k'] +['/****************************************************************************', 'Ċ'] +['create', 'Element'] +['ĠK', 'op'] +['ign', 'ant'] +['.', 'rollback'] +['Ġsal', 'ud'] +['_', "',"] +['ĠAN', 'SI'] +['Ex', 'cept'] +['ĠDraw', 'able'] +['.Utc', 'Now'] +['":[', '{Ċ'] +['Ġk', 'ole'] +['L', 'ua'] +['ĠBel', 'ieve'] +['Com', 'put'] +['Ġhall', 'uc'] +['ĠSign', 's'] +['r', 'st'] +['.h', 'u'] +['ĠKN', 'OW'] +['W', 'i'] +['ĠBr', 'ass'] +['ĠR', 'as'] +['@', 'hotmail'] +['Ġsed', 'iment'] +['Ġap', 'k'] +['Ġì', 'ĥģ'] +['_reg', 'ions'] +['Ġpod', 'ium'] +['<', 'Book'] +['ж', 'е'] +['Ġsix', 'teen'] +['ĠAli', 'as'] +['Ġinfr', 'ared'] +['ĠV', 'ander'] +['ĠLe', 'ading'] +['uc', 'ing'] +[',:', ',:'] +['_h', 'or'] +['w', 'at'] +['Ġdé', 'cou'] +['_W', 'idget'] +['S', 'ounds'] +['_n', 'avigation'] +['Ġschn', 'ell'] +['(g', 'enerator'] +['uc', 'ene'] +['Ġrem', 'ake'] +['IP', 'v'] +['Ġré', 'al'] +['_IN', 'CREMENT'] +['Ġhypoth', 'etical'] +['_', 'ang'] +['Ġof', 's'] +['Ġ!', 'Ċ'] +['.com', 'pleted'] +['Get', 'Type'] +['Ġkom', 'men'] +['ál', 'ido'] +['add', 'On'] +['Ġz', 'ÅĤ'] +['UL', 'A'] +['_ind', 'icator'] +["']", 'ĊĊĊ'] +['ap', 'ache'] +['_S', 'elect'] +['ĠGre', 'ene'] +['Wh', 'ats'] +['_an', 'im'] +['Ġrepet', 'itive'] +['m', 'uch'] +['ĠTh', 'reshold'] +['Ġl', 'f'] +['(C', 'ategory'] +['con', 'e'] +['M', 'ix'] +['_MET', 'ADATA'] +['ays', 'ia'] +['Ne', 'ighbors'] +['ĉĊ', 'ĉĉĊ'] +['IP', 'HER'] +['ĠFr', 'ag'] +['ĠC', 'ells'] +['Ġnames', 'paces'] +['(', 'back'] +['ĠRest', 'aurants'] +['sv', 'c'] +['Ġл', 'и'] +['ote', 'ch'] +['-s', 'l'] +['¥', '¿'] +['ĠW', 'T'] +['ĠRed', 'uction'] +['Ġd', 'otted'] +['ĉf', 'ound'] +['ĠTE', 'AM'] +['B', 'orn'] +['ĠM', 'ush'] +['ĠCompar', 'able'] +['Ġh', 'itch'] +['AT', 'O'] +['Ġmax', 'Height'] +['begin', 'Transaction'] +['ÃŃ', 'v'] +['_b', 'n'] +['Ġher', 'd'] +['Ġrevers', 'al'] +['ĠH', 'ond'] +['del', 'imiter'] +['Ġconf', 'use'] +['Ġh', 'ops'] +['Ġcent', 'roid'] +['Ġcourt', 'room'] +['.decor', 'ators'] +['Ġm', 'pi'] +['ĠImpro', 'ved'] +['IN', 'NER'] +['ĠBang', 'alore'] +['ĠT', 'amb'] +['Ġbo', 'ast'] +['()', '))čĊ'] +['Ġil', 'licit'] +['ĠMor', 'occo'] +['greg', 'ator'] +['_res', 'ume'] +['Ġcrack', 'down'] +['Ġport', 'raits'] +['/h', 'igh'] +['(', "\\'"] +['Ġay', 'ud'] +['_fe', 'edback'] +['Ġc', 'ate'] +['/', 'avatar'] +['Ġhe', 'b'] +['Point', 'Cloud'] +['Ġå', 'ĴĮ'] +['Ġ<', '!['] +['Ġget', 'Resources'] +['}', ':{'] +['Oper', 'ating'] +['ĠF', 'og'] +['ĉt', 'ab'] +['ĠResearch', 'ers'] +['Ġfabric', 'ation'] +['.datas', 'ets'] +['ĠCamp', 'o'] +['ĠKa', 'uf'] +['Ġd', 'll'] +['lig', 't'] +[']', '));ĊĊ'] +['st', 'ellen'] +['ACK', 'ET'] +['l', 'vl'] +['ĠGl', 'ory'] +['.date', 'Time'] +['Ġcomm', 'ute'] +['ĠonCreate', 'ViewHolder'] +['ĠX', 'Element'] +['ĠT', 'okens'] +['<', 'thead'] +['_p', 'ick'] +['ì', '¤'] +['v', 'on'] +['depart', 'ure'] +['(render', 'er'] +['phone', 'Number'] +['(P', 'erson'] +['gen', 'es'] +['ĠL', 'ars'] +['Ġ)', '{ĊĊ'] +['ĠJson', 'Result'] +['Ġmet', 'odo'] +['VO', 'KE'] +['.get', 'UserId'] +['Acc', 'eler'] +['ĉ', 'required'] +['Ġchampionship', 's'] +['Build', 'Context'] +['/t', 'ask'] +['/re', 'leases'] +['C', 'ategoria'] +['_over', 'lay'] +['Ġscar', 'ce'] +['_l', 'im'] +['n', 'gr'] +['ah', 'len'] +['ĠArt', 'ificial'] +['sp', 'read'] +['Ġbow', 'ling'] +['.an', 'alysis'] +['SM', 'TP'] +['ĉp', 'assword'] +['Ġbath', 's'] +[']', ')){Ċ'] +['current', 'ly'] +['ac', 'iente'] +['_se', 'parator'] +['Ġde', 'ber'] +['ĠDis', 'abled'] +['i', 'ères'] +['Ġâ', 'ķ'] +['_process', 'ing'] +['Ġprotest', 'ing'] +['ĠR', 'OT'] +['gr', 'ab'] +['Ġз', 'ак'] +['Ġpro', 'active'] +['word', 'press'] +['ĠSe', 'ver'] +['ind', 'en'] +['Ġw', 'ikipedia'] +['){', 'čĊčĊ'] +['_w', 'indows'] +['is', 'lation'] +['Ġun', 'rest'] +['Ġdismiss', 'al'] +['.N', 'UM'] +['_F', 'AST'] +['iss', 'ued'] +['ĠF', 'ACE'] +['_u', 'nder'] +['Ġpl', 'ugged'] +['Ġå', '°'] +['ĠbÄĻd', 'zie'] +['ĠI', 'CC'] +['Ġcombust', 'ion'] +['Ġkiss', 'ed'] +['Ġstar', 'red'] +['ĠW', 'atts'] +['Ġspi', 'elen'] +['-p', 'urpose'] +['ĠE', 'val'] +['arg', 'es'] +[',', 'result'] +['techn', 'ology'] +['Ġnational', 'ity'] +['ic', 'us'] +['ĠN', 'ug'] +['ĠÑĤ', 'о'] +['ĉĉĉĉĉĉĉ', 'ĠĠ'] +['col', 'o'] +['Ġg', 'astro'] +['ante', 'ed'] +['OL', 'ID'] +['.b', 'ias'] +['_t', 'ele'] +['.ins', 'pect'] +['Ġve', 'il'] +['.', 'footer'] +['Ġneglig', 'ence'] +['Ġjud', 'gments'] +['Room', 's'] +['yn', 'n'] +['ĉcount', 'er'] +['occup', 'ation'] +['Ġ', 'çĶŁ'] +['un', 'as'] +['Ġ(^', ')('] +['L', 'ambda'] +['f', 'el'] +['.Param', 's'] +['Ġд', 'обав'] +['set', 'Layout'] +['Ġdeport', 'ation'] +['Ġlocal', 'Object'] +['ĠPharm', 'aceutical'] +['cept', 'ive'] +['ĠN', 'ome'] +['Equ', 'ipment'] +['F', 'an'] +['Un', 'iversal'] +['ĉ', 'socket'] +['Ġgr', 'in'] +['Ġex', 'poses'] +['Ġhab', 'er'] +['Ġsincer', 'ely'] +['Ġc', 'ams'] +['Ġm', 'ü'] +['en', 'ia'] +['E', 'mer'] +['C', 'rypto'] +['Sl', 'ow'] +['(x', 'hr'] +['!', '=('] +['-s', 'ervices'] +['ĠP', 'W'] +['Ġprend', 're'] +['Ġm', 'ädchen'] +['em', 'ons'] +['озв', 'ÑĢаÑī'] +['.M', 'anager'] +['ì', 'Ļ'] +['Ġg', 'raf'] +['-', 'ra'] +['met', 'rical'] +['/', 'fl'] +['Ġc', 'emetery'] +['g', 'ens'] +['Ġp', 'ÅĻ'] +['ĠMySql', 'Command'] +['-', 'To'] +['Ġv', 'Ã¥'] +['Ġa', 'irst'] +['oment', 'um'] +['Ġserv', 'o'] +['m', 'illion'] +['ĠMir', 'anda'] +['"', 'She'] +['Ġadvoc', 'ating'] +['-c', 'aption'] +['ĠAt', 'tribution'] +['Ġwel', 'che'] +['_v', 'endor'] +['ĉ', 'Status'] +['arr', 'is'] +['Ġprint', 'k'] +['","', '#'] +['Ġrel', 'ativ'] +['if', 'ferences'] +['izz', 'es'] +['Ġdec', 'imals'] +['ĠPro', 'v'] +['.max', 'imum'] +['Ar', 'n'] +['Ġhelicopt', 'ers'] +['_B', 'OTTOM'] +['ch', 'ure'] +['od', 'ings'] +["'", '('] +['"))', ');čĊ'] +['(', 'bean'] +['.f', 'd'] +['F', 'und'] +['Ġhang', 's'] +['app', 'id'] +['/k', 'ernel'] +['.p', 'oi'] +['.Min', 'Value'] +['-', 'validation'] +['L', 'uke'] +['c', 'df'] +['ĠFun', 'eral'] +['ĠS', 'amples'] +['ĉ', 'de'] +['Ġto', 'astr'] +['Ġtax', 'able'] +['Ġcl', 'ustering'] +["Ġ'\\", "'"] +['Ġre', 'straint'] +['ec', 'ed'] +['ch', 'ains'] +['ãĢĤ', 'ï¼Ī'] +['_GR', 'APH'] +['Ġfue', 'led'] +['éľ', 'Ģ'] +['H', 'p'] +['å¤', 'į'] +['T', 'iles'] +['Ġa', 'unque'] +['J', 'C'] +['Ġhost', 'age'] +['ĠE', 'sk'] +['Ġm', 'av'] +['Ġgest', 'ion'] +['Ġb', 'anners'] +['}', '{$'] +['.int', 'Value'] +[".'", '"ĊĊ'] +['_M', 'ATRIX'] +['Ġce', 'ased'] +['ĠG', 'OD'] +['_CAM', 'ERA'] +['.Allow', 'User'] +['tr', 'acked'] +['C', 'ook'] +['b', 'airro'] +['(', 'company'] +['Ġview', 'point'] +['.get', 'Writer'] +['ĠN', 'ets'] +['w', 'ives'] +['Ġ(', '))Ċ'] +['example', 'Modal'] +['ĉ', 'child'] +['Ġmyth', 'ology'] +['Ġ//', '"'] +['_', 'axes'] +['ib', 'old'] +['.D', 'ark'] +['ĠMax', 'well'] +['Ġg', 'pointer'] +['olic', 'itud'] +['B', 'at'] +['ul', 'ner'] +['bal', 'anced'] +['mail', 'er'] +['Ġcont', 'empor'] +['æīĭ', 'æľº'] +['("', '__'] +['Ġ"', ')"'] +['re', 'ar'] +['ĠHu', 'ang'] +[']', "')Ċ"] +['×', '©'] +['FT', 'A'] +['ĠCalling', 'Convention'] +['ĠOutput', 's'] +['P', 'k'] +['.Re', 'ference'] +['lect', 'ual'] +['Ġ)', ':ĊĊ'] +['Ġbrace', 'let'] +['ug', 'er'] +['ĉ', 'Error'] +['S', 'weet'] +['("/', '");Ċ'] +['h', 'x'] +['Ġun', 'reasonable'] +['Inter', 'preter'] +['Ġlo', 'ft'] +['_product', 'o'] +['Ġsoci', 'etal'] +['.P', 'arser'] +['ĠAd', 'apt'] +['.', 'foo'] +['(', 'where'] +['.F', 'eature'] +['ĠYam', 'aha'] +['g', 'lass'] +['For', 'ge'] +['Ġprohib', 'its'] +['Ġcapac', 'ities'] +['Ġíķ¨', 'ìĪĺ'] +['Ġper', 'mutation'] +['Ġih', 'm'] +['F', 'ld'] +['el', 'ial'] +['========', '===Ċ'] +['@', 'Configuration'] +['Ġge', 'ared'] +['ios', 'o'] +['iest', 'a'] +['trans', 'lations'] +['Input', 'Change'] +['Pop', 'ular'] +['ĠPL', 'US'] +['Ġv', 'f'] +['_F', 'ree'] +['b', 'box'] +['Ġcaus', 'al'] +['PI', 'LE'] +['Ġsch', 'ö'] +['Ġiron', 'ic'] +['M', 'ir'] +['.', '@'] +['åį', 'Ĺ'] +['Ġè', 'ĩ'] +['R', 'ew'] +['ul', 'ence'] +['fl', 'en'] +['Ġcan', 'Activate'] +['-', 'response'] +['Ġacc', 'ents'] +['ign', 'ored'] +['°', 'F'] +['.Dependency', 'Injection'] +['ĉ', 'point'] +['Ġconting', 'ent'] +['Ġsqu', 'ash'] +['Ġpar', 'ms'] +['ĠC', 'emetery'] +['Ġdelta', 'Time'] +['ĠD', 'OS'] +['Ġvan', 'ished'] +['аÑĢам', 'еÑĤ'] +['ĠD', 'PS'] +['t', 'foot'] +['ĠZ', 'us'] +['_IN', 'STALL'] +['G', 'AN'] +['Ġar', 'b'] +['Ġmunicipal', 'ities'] +['Into', 'Constraints'] +['AutoresizingMask', 'IntoConstraints'] +[',', 'image'] +['_', 'ignore'] +['Ġdanger', 'ously'] +['quis', 'a'] +['pl', 'uck'] +['Ġhar', 'us'] +['up', 'pe'] +['Http', 'Exception'] +['Br', 'acket'] +[".'", "'ĊĊ"] +['ĠT', 'ol'] +['ĠView', 'er'] +['zb', 'ollah'] +['.Code', 'Analysis'] +['ì', 'nh'] +['Ġcorrect', 'amente'] +['.d', 'a'] +['ĠAl', 'ger'] +['×', 'IJ'] +['ba', 'um'] +['ĠPan', 'ther'] +['part', 'icipant'] +['å¿', 'ħ'] +['-s', 'up'] +['Ġem', 'ulator'] +['Ġf', 'ading'] +['ĠW', 'olver'] +['cre', 'ates'] +['Ġbook', 'ings'] +['.Q', 'uestion'] +['§', 'è¡Į'] +['Ġstress', 'es'] +['Ġre', 'written'] +['.PI', 'PE'] +['ed', 'es'] +['Ġc', 'bd'] +['":', '"/'] +['Ġenh', 'ancements'] +['_s', 'y'] +['B', 'IN'] +['ĠSl', 'ip'] +['Ins', 'pect'] +['ĠW', 'eg'] +['Ġcon', 'gregation'] +['Ġ_', ':'] +['_r', 'm'] +['Frame', 'buffer'] +["Ġ'&", '#'] +['ĠFall', 'out'] +['Is', 'Required'] +['ĠPear', 'son'] +['ĠF', 'ACT'] +['Ġrel', 'ie'] +['ĉ', 'box'] +['ĠShe', 'pherd'] +['ĠWiki', 'Leaks'] +['ĠCollect', 'or'] +['Ġres', 'ized'] +['method', 'Name'] +['Ġevent', 'Type'] +['ĠA', 'then'] +['Des', 'criptors'] +['Ġb', 'ers'] +['-', 'oper'] +['ĠInitial', 'ly'] +['å', '¡'] +['_B', 'TN'] +['ĠĠĠĠĠĠĠĠĠ', 'čĊ'] +['á', 'b'] +['_c', 'ampaign'] +['_w', 'atch'] +['F', 'ord'] +['-date', 'picker'] +['Ġvis', 'c'] +['Ġsat', 'u'] +['_s', 'ms'] +['Ġcont', 'ador'] +['-s', 'vg'] +['ĠDO', 'I'] +['$', 'args'] +['Ġkn', 'ob'] +['.B', 'OLD'] +['Ġdeb', 'ated'] +['img', 's'] +['sock', 'opt'] +['tr', 'uth'] +['ĠFe', 'es'] +['Ġh', 'Wnd'] +['_f', 'ood'] +['Ġab', 'ras'] +['Ġnot', 'ions'] +['ĠT', 'od'] +[':', 'create'] +['ĠConf', 'lict'] +['Us', 'uarios'] +['OT', 'OS'] +['Ġm', 'sm'] +['K', 'HTML'] +['([', '('] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['Ġ}', ']'] +['w', 'izard'] +['Ġm', 'ientras'] +['Ġdata', 'List'] +['Ġemerg', 'es'] +['Äĥ', 'ng'] +['.Read', 'Int'] +['PG', 'A'] +['ILL', 'ISE'] +['I', 'Enumerator'] +['(t', 'uple'] +['Christ', 'mas'] +['Look', 'AndFeel'] +['og', 'enerated'] +['Ġ#', 'ĊĊ'] +['control', 'led'] +['Ġex', 'quisite'] +['Ġa', 'cest'] +['Read', 'Write'] +['G', 'ain'] +['ãĢį', 'ãĢĮ'] +['Ġcopyright', 'ed'] +['Ġdo', 'om'] +['.Table', 'LayoutPanel'] +['ĠD', 'ort'] +['Ġch', 'ili'] +['Ġwer', 'k'] +['ĠEVENT', 'S'] +['ĠBe', 'acon'] +['Ġship', 'ments'] +['Ġse', 'bagai'] +['up', 'on'] +['ut', 'om'] +['.con', 'verter'] +['.Drop', 'Table'] +['={', '}Ċ'] +['f', 'ic'] +['~', 'ĊĊ'] +['Ġlesb', 'ians'] +['_n', 'a'] +['Fore', 'ign'] +['ĉ', 'then'] +['/', 'ms'] +['Ġor', 'i'] +['get', 'Property'] +['ĉsn', 'printf'] +['hes', 'ion'] +['ãģ', '¤'] +['"}', ',"'] +['Ġac', 'rylic'] +['P', 'ers'] +['@', 'Enable'] +['I', 'sl'] +['(C', 'ard'] +['.', 'Stack'] +['L', 'icensed'] +['_G', 'UID'] +[':', 'title'] +['Ġh', 'ust'] +['Ġprincipal', 'Table'] +['an', 'itize'] +['/', 'embed'] +['Ġens', 'ured'] +['ĠE', 'GL'] +['ÙĪ', 'ر'] +['ĠåĪ', 'Ĩ'] +['/', ',Ċ'] +['Ġfundra', 'iser'] +['Key', 'Name'] +['Ġmarch', 'ed'] +['_VAL', 'UES'] +['ĠSc', 'enario'] +['Ġmet', 'ic'] +['_ass', 'oci'] +['ĠPast', 'or'] +['ĉĉĉĉĉĉĉĉ', 'ĉĉĉĉĉĉĉĉĉĉ'] +['er', 'ate'] +['Ġinv', 'itations'] +['quo', 'ise'] +['Ġbl', 'aming'] +['Ġd', 'aring'] +['UM', 'MY'] +['Ġrich', 'er'] +['em', 'aker'] +['ĠIdent', 'ification'] +['ĠìĿ', '¸'] +['ĠBinding', 'Flags'] +['ch', 'as'] +['Ġresil', 'ient'] +['_p', 'g'] +['Ġre', 'leg'] +['ĠI', 'RA'] +['ST', 'E'] +['Ġtr', 'actor'] +['-', 'loading'] +['ĠPre', 'viously'] +['ĠV', 'acc'] +['/', 'be'] +['Ġn', 'Ã¥r'] +['Ġurl', 'encode'] +['ĠNor', 'folk'] +['.Re', 'lease'] +['ĠNe', 'utral'] +['ä¸Ń', 'åĽ½'] +['ĠAr', 'lington'] +['Ġalleg', 'es'] +['ĠW', 'riters'] +['Test', 'er'] +['ĠR', 'ally'] +['Ġc', 'á'] +['ĉ', 'Print'] +['Ġâĩ', 'Ĵ'] +['ĠUser', 'Controller'] +['ĠSeek', 'ing'] +['.V', 'AL'] +['List', 'Node'] +['_', 'ff'] +['ĠPhill', 'ip'] +['FA', 'CT'] +['Ġc', 'aramel'] +['ĠM', 'ultip'] +['ĠCom', 'pared'] +['ĠSer', 'bia'] +['Ł', '³'] +['Ġrev', 'ive'] +['ĠK', 'anye'] +['Ġver', 'ge'] +['ĠBulg', 'aria'] +['get', 'Body'] +['Ġ|', '>'] +['ce', 'ph'] +['.DateTime', 'Picker'] +['."', ';ĊĊ'] +['ĠT', 'ie'] +[',', 'item'] +['Ġm', 'enn'] +['G', 'as'] +['och', 'a'] +['_v', 'irtual'] +['Ġmaster', 'piece'] +['_se', 'quences'] +['L', 'TE'] +['ĠSub', 'mission'] +['Call', 'er'] +['$', '\\'] +['S', 'port'] +['ag', 'us'] +['Constraint', 'Maker'] +['Ġcol', 'oc'] +['Ġw', 'ig'] +['ĠÐ', '£'] +['ĉ', 'Array'] +['Look', 's'] +['ĠGT', 'A'] +['.st', 'eps'] +['atch', 'ewan'] +['_r', 'anges'] +['ext', 'Alignment'] +['ĠBren', 'nan'] +['Ġab', 'straction'] +['uler', 'Angles'] +['.m', 'isc'] +['Ġantib', 'odies'] +['Ġexponent', 'ial'] +['ĠCH', 'ANNEL'] +['exp', 'ense'] +["'", 'y'] +['Ġdetect', 'ives'] +['Ġpur', 'ported'] +['Y', 'STEM'] +['Ġradio', 'active'] +['ĠLat', 'ina'] +['.Enc', 'oding'] +['.T', 'AG'] +['x', 'in'] +['D', 'egree'] +['ur', 'acion'] +['pr', 'ices'] +['ĠRefer', 'entialAction'] +['Ġr', 'arity'] +['Ġp', 'iles'] +['g', 'ende'] +['_project', 's'] +['_g', 'lobals'] +['.start', 'Time'] +['Ġê', 'µ¬'] +['SE', 'CTION'] +['_p', 'ublish'] +['F', 'ault'] +['DD', 'L'] +['_p', 'rior'] +['M', 'om'] +['Ġth', 'icker'] +['Ġsequ', 'elize'] +['Ġessential', 's'] +['str', 'as'] +['in', 'tr'] +['>(', '()'] +['.man', 'agement'] +['e', 'il'] +['éĹ', 'Ń'] +['A', 'ware'] +['.C', 'ity'] +['ĠAr', 'bit'] +['_D', 'M'] +['_key', 'board'] +['L', 'Object'] +['-', 'webpack'] +['ĠNew', 'port'] +['Ġprincipal', 'Column'] +['leg', 'ant'] +['Ġp', 'allet'] +['Ġfract', 'ure'] +['Ġg', 'mail'] +['.M', 'eta'] +['A', 'bove'] +['.Key', 'Event'] +['j', 'it'] +['_mac', 'ro'] +['_P', 'USH'] +['á»', '©'] +['/', 'controller'] +['åĬł', 'è½½'] +['Ġsuperf', 'icial'] +['exter', 'ity'] +['Ġmens', 'agem'] +['W', 'ind'] +['ist', 'on'] +['.open', 'api'] +['и', 'ÑĢов'] +['ĠSerial', 'izer'] +['uct', 'ive'] +['Ġz', 'ar'] +['Pl', 'aces'] +['.St', 'atic'] +['B', 'a'] +['Ġin', 'advert'] +['ĠIndones', 'ian'] +['_IP', 'V'] +['(h', 'orizontal'] +['Ġget', 'Title'] +['ide', 'press'] +['ĠConsole', 'Color'] +['ip', 'ers'] +['$', 'out'] +['Ġfest', 'ive'] +['Ġeven', 'ings'] +['.Get', 'Data'] +['uit', 'ka'] +['ĠManual', 's'] +['uss', 'ed'] +['_M', 'ax'] +['.Ch', 'at'] +['ĠA', 'ircraft'] +['=', 'com'] +['FO', 'UND'] +['ap', 'ro'] +['Ġtre', 'asures'] +['_al', 'ive'] +['Ġgad', 'get'] +['ek', 'ing'] +['Button', 'Down'] +['B', 'rowsable'] +['.PER', 'MISSION'] +['P', 'ASSWORD'] +['ĠH', 'ASH'] +['f', 'é'] +['\\', 'TestCase'] +['LO', 'SS'] +['o', 'thers'] +[',', 'J'] +['Ġassh', 'ole'] +['wer', 'k'] +['Ġm', 'ã'] +['.', 'ie'] +['ev', 'il'] +['kont', 'akte'] +['////////////////////////////////////////////////////////////////////////////////', 'Ċ'] +['=', 'sys'] +['ĉ', 'lock'] +['--', ';ĊĊ'] +['_F', 'UN'] +['Fill', 'Color'] +['ó', 'a'] +['pre', 'nd'] +['Ġcompress', 'or'] +['M', 'other'] +['ĠAr', 'cher'] +['.g', 'oto'] +['Ġwür', 'de'] +['Ġbam', 'boo'] +['ï¼', 'İ'] +['ĠT', 'rees'] +['Ġb', 'umper'] +['Ġsa', 'usage'] +['ĠEl', 'asticsearch'] +['Ġhor', 'izontally'] +['ĠG', 'ul'] +['Im', 'mutable'] +['Ġlos', 'er'] +['Ġabort', 'ed'] +['-d', 'emo'] +['ĠH', 'atch'] +['Ġund', 'e'] +['Ġprocess', 'o'] +['-c', 'all'] +['In', 'come'] +['å', 'ĥ'] +['_', 'returns'] +['\']."', "'"] +['(s', 'w'] +['C', 'BS'] +['am', 'ilies'] +['ĠYour', 'self'] +['ĠH', 'olt'] +['.M', 'ON'] +['à§', 'ĩ'] +['ÑĪ', 'е'] +['an', 'on'] +['ĠFont', 'Awesome'] +['produ', 'cer'] +['j', 'r'] +['Ġm', 'au'] +['ĉint', 'er'] +['Ġdish', 'onest'] +['Ġmagn', 'a'] +['ĠCollect', 'ive'] +['Ġvra', 'iment'] +['Ġcho', 'ix'] +['st', 'ay'] +['Ġweld', 'ing'] +['r', 'ising'] +[',', 'min'] +['ĠF', 'ate'] +['g', 'lob'] +['RGB', 'A'] +['Ġdet', 'te'] +['V', 'en'] +['Ġembarrass', 'ment'] +['.DE', 'LETE'] +['greg', 'ar'] +['-re', 'nder'] +['(b', 'ucket'] +['">', 'ĊĊĊ'] +['.wait', 'Key'] +['Bus', 'y'] +['Ġdifferent', 'iation'] +['ĠC', 'ST'] +['.Con', 'stant'] +['Ġline', 'Number'] +['(m', 'atches'] +['Ġweb', 'socket'] +['Ġbar', 'red'] +['Ġpued', 'es'] +['M', 'ono'] +['C', 'ORE'] +['I', 'ID'] +['ĠĠĠĠ', 'čĊčĊ'] +['Ġpúb', 'lico'] +['lean', 'ing'] +['Ġcleans', 'ing'] +['Ġcr', 'is'] +['ĠDev', 'ils'] +['_SET', 'TING'] +['unt', 'ary'] +['.', ');Ċ'] +['Ċ', 'ĠĠĠĊ'] +['[', 'curr'] +['ts', 'y'] +['ĠAlex', 'is'] +['rit', 'el'] +['Ġpet', 'roleum'] +['.pre', 'processing'] +['m', 'atter'] +['For', 'Result'] +['-', 'license'] +['Ġtrav', 'ellers'] +['ĠDispatch', 'er'] +['enn', 'ifer'] +['Ġdigest', 'ive'] +['P', 'ED'] +['hib', 'ition'] +['MAS', 'ConstraintMaker'] +['ĠW', 'att'] +['Ben', 'ef'] +['.set', 'View'] +['d', 'to'] +['TE', 'E'] +['ĠPel', 'osi'] +['_EX', 'TRA'] +['Ġmed', 'als'] +['x', 'hr'] +['fore', 'cast'] +['Ġn', 'argin'] +['oun', 's'] +['-f', 'ill'] +['_CUR', 'SOR'] +['Ġsuperv', 'ised'] +['Ġtur', 'f'] +['ĠEd', 'gar'] +['POS', 'ITION'] +['Ġcategory', 'Id'] +['â', 'ī'] +['_', 'ER'] +['á»§', 'a'] +['Sh', 'own'] +['.', 'll'] +['_POL', 'ICY'] +['(),', "'"] +['ĠPre', 'v'] +['ĠString', 'Field'] +['ĉG', 'lobal'] +['ass', 'ed'] +['Through', 'out'] +['o', 'stringstream'] +['.awt', 'extra'] +['Ġslo', 'pes'] +['ĠSe', 'quential'] +['Ġgi', 'orn'] +['Ġz', 'elf'] +['Ġvers', 'atility'] +['lene', 'ck'] +['.c', 'gi'] +['Ġdou', 'bling'] +['ĠBang', 'kok'] +['Ġbu', 'urt'] +['Ġusu', 'ário'] +['st', 'udio'] +['Ġje', 'unes'] +['Ġm', 'uted'] +['Ġ', 'ips'] +['_f', 'raction'] +['&&', '('] +['Ġst', 'unt'] +["');", '?>čĊ'] +['Ġev', 'apor'] +['b', 'able'] +['ĠPR', 'ICE'] +['Ġæ', '³'] +['lu', 'cent'] +['Ġv', 'amp'] +['ĠTechn', 'ician'] +['Ġuniqu', 'eness'] +['M', 'es'] +['ur', 'ban'] +['.param', 'etrize'] +['ĠRe', 'play'] +['S', 'essions'] +['em', 'br'] +['-Americ', 'ans'] +['_PRO', 'XY'] +['Ġp', 'ian'] +['Ġtri', 'e'] +['ĠD', 'estructor'] +['Game', 'State'] +['ĠIM', 'F'] +['ch', 'in'] +['Ġport', 'e'] +['ĠSw', 'al'] +['åŁ', 'İ'] +['Sub', 'string'] +['im', 'ing'] +['/L', 'ibrary'] +['Ġfright', 'ened'] +['w', 'rites'] +['Ġrecurs', 'os'] +['ar', 'Result'] +['_INIT', 'IALIZ'] +['ĠBad', 'ge'] +['_c', 'rc'] +['E', 'ight'] +['ĠDIST', 'INCT'] +['Ġth', 'ro'] +['@', 'Xml'] +['ĠLegend', 'ary'] +['-t', 'witter'] +['_e', 'asy'] +['Ġ+', '++'] +['(D', 'ATA'] +['.L', 'ocale'] +['Ġk', 'ä'] +['Ġn', 'urt'] +['Ġcr', 'uis'] +['_', 'ios'] +['Ġsens', 'ing'] +['_L', 'ine'] +['Ċ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĊ'] +['pon', 'g'] +['ole', 'on'] +['Ġwild', 'card'] +['ç͍æĪ·', 'åIJį'] +['Ġbeg', 'ging'] +['R', 'od'] +['ĠÃ', 'İ'] +['_C', 'ELL'] +['Research', 'ers'] +['.', 'selector'] +['_', 'ing'] +['Ġaspir', 'ing'] +['Ġimm', 'ortal'] +['Ġy', 'min'] +['_', 'robot'] +['Ġpl', 'ur'] +['B', 'TC'] +['ĠD', 'ID'] +['Ġpier', 'cing'] +['*', 'u'] +['_DEFIN', 'ED'] +['ĠTh', 'i'] +['ita', 'ire'] +['(m', 'edia'] +['-', 'ons'] +['Ġche', 'fs'] +['Ġ"*', '.'] +['/', 'AP'] +['Ġraz', 'or'] +['Ġsearch', 'Data'] +['Ġ=', '&'] +['Ġ', 'ãĢĤ'] +['Ġm', 'ourn'] +['ting', 'ham'] +['Ġo', 'li'] +['ĠVern', 'on'] +['_R', 'S'] +['ŀ', 'æĢ§'] +['Ġf', 'ácil'] +['ang', 'en'] +['cel', 'ain'] +['Ġa', 'il'] +['le', 'st'] +['ĠQ', 'COMPARE'] +['g', 'ain'] +['ĠÎ', 'µ'] +['ĠK', 'ob'] +['ĠF', 'ault'] +['_config', 's'] +['ç»ĵ', 'æŀľ'] +['.', '+'] +['cal', 'ar'] +['(color', 's'] +['M', 'ul'] +['_', 'ART'] +['Ġexperiment', 'ing'] +['erm', 'en'] +['ĠAng', 'lo'] +['.Fixed', 'Single'] +['Se', 'a'] +['Ġc', 'txt'] +['.s', 'lider'] +['C', 'ollapse'] +['G', 'rey'] +['Ġf', 'ld'] +['-pro', 'of'] +['.cap', 'acity'] +['get', 'Parent'] +['ĠCom', 'pliance'] +['Ġburg', 'l'] +['-', 'rec'] +['Ġover', 'written'] +['M', 'U'] +['Ġrout', 'ers'] +['ĉ', 'Model'] +['Ġfantas', 'ies'] +['av', 'ian'] +['_p', 'rec'] +['ĠSc', 'andin'] +['Ġ//', '<'] +['/o', 'ct'] +['Ġceremon', 'ies'] +['Month', 's'] +['und', 'y'] +['Ġqu', 'ed'] +['ĠN', 'ou'] +['ĠV', 'ibr'] +['.r', 'gb'] +['Ġcit', 'rus'] +['Ġbr', 'aces'] +['-upper', 'case'] +['get', 'Table'] +['Ġdop', 'o'] +['ĠK', 'err'] +['_CH', 'ILD'] +['-', 'cloud'] +['ĉ', 'Matrix'] +['Ġgard', 'ening'] +['S', 'ing'] +['al', 'most'] +['Require', 'ments'] +['ugu', 'ay'] +['(', 'Property'] +['sub', 'scriber'] +['FA', 'ST'] +['re', 'action'] +['(l', 'p'] +[')', '})Ċ'] +['`', ').'] +['.w', 'allet'] +['_ex', 'change'] +['.Max', 'imum'] +['ĠVer', 'b'] +['âĶ', 'ģ'] +['()', '<'] +['ï¼Ľ', 'Ċ'] +['RO', 'T'] +['C', 'ARD'] +['ub', 'it'] +['{', '@'] +['_k', 'el'] +['ĠTool', 'tip'] +['My', 'SQL'] +['Main', 'Activity'] +['ar', 'f'] +['Ġm', 'align'] +['Ġse', 'inen'] +['ap', 'ist'] +['Ġ<', '%'] +['Method', 'Impl'] +['M', 'il'] +['ĠM', 'ick'] +['.de', 'pend'] +['<', 'ID'] +['Ġpredict', 'ive'] +['ĠAP', 'PLICATION'] +['le', 'f'] +['dim', 'ensions'] +['Ġconoc', 'er'] +['/', 'conf'] +['ĠTr', 'acy'] +['F', 'oto'] +['_rem', 'aining'] +['=', 'file'] +['Ġpage', 'Index'] +['ĠPar', 'ish'] +['Ġt', 'exas'] +['ĠM', 'AGIC'] +['ĠH', 'ew'] +['d', 'ifference'] +['Ġalt', 'ura'] +['c', 'um'] +['ĉdata', 'Type'] +['Ġcaracter', 'es'] +['avi', 'ours'] +['ĠV', 'OID'] +['è¿', 'ij'] +['P', 'UBLIC'] +['B', 'io'] +['ĠstringBy', 'Appending'] +['Parse', 'Exception'] +['ĠS', 'uff'] +['ĠN', 'orton'] +['/d', 'etails'] +['.n', 'ull'] +['>>', '&'] +['ĉ', 'ok'] +['-l', 'ow'] +['.', 'usuario'] +['n', 'ested'] +['X', 'B'] +['OUR', 'S'] +['.Border', 'Color'] +['Ġb', 'row'] +['ĠÐ', 'ķ'] +['cor', 'r'] +['ĠRed', 'skins'] +['.get', 'Tag'] +['.get', 'Transaction'] +['Ġst', 'igma'] +['hard', 't'] +['ĠPlayer', 'Prefs'] +['als', 'y'] +['uc', 'son'] +['L', 'anguages'] +['ĠOl', 'ivia'] +['Ġt', 'ac'] +['Ġb', 'li'] +['Ġc', 'aval'] +['Ġconsolid', 'ated'] +['Ġper', 'il'] +['Ġde', 'le'] +['Ġform', 'ulated'] +['Ġhigh', 'ways'] +['.sp', 'awn'] +['==', '$'] +['ĠN', 'iet'] +['Ġv', 'eggies'] +['yp', 'o'] +['-r', 'ule'] +['ĠV', 'ie'] +['/e', 'pl'] +['Ġenf', 'ants'] +['string', 'Literal'] +['Ġtou', 'ghest'] +['buy', 'er'] +['Ġcov', 'ariance'] +['Ġil', 'i'] +['ĠSoph', 'ie'] +['ĠB', 'AB'] +['Ġ"', '),'] +['ĠU', 'k'] +['current', 'Index'] +['_user', 'data'] +['.code', 'c'] +['ĠPun', 'jab'] +['ĠSN', 'P'] +['l', 'ol'] +['adv', 'ance'] +['Ġcom', 'fy'] +['Json', 'Ignore'] +['Ġfashion', 'able'] +['ĠI', 'CON'] +['Ġor', 'a'] +['ĠP', 'ricing'] +['<', 'num'] +['ĠI', 'RC'] +['ER', 'V'] +['ĠMe', 'in'] +['ĠID', 'ictionary'] +['AD', 'OW'] +['is', 'New'] +['ĠDev', 'on'] +['at', 'l'] +['(request', 'Code'] +['ĉ', 'PreparedStatement'] +['IM', 'PORT'] +['Ġmar', 'ital'] +['_SELECT', 'ED'] +['get', 'Response'] +['ar', 'Down'] +['B', 'V'] +['ib', 'Name'] +['ĠP', 'ATCH'] +['ä', 'än'] +['Ġda', 'ar'] +['ĠFile', 'Mode'] +['Ġm', 'arty'] +['.Spring', 'Application'] +['c', 'ene'] +['amp', 'oline'] +['get', 'Size'] +['Rest', 'art'] +['æķ', 'Ī'] +['.project', 's'] +['ĠEthi', 'opia'] +['Ġstatus', 'es'] +['T', 'ION'] +['(b', 'g'] +['ĠX', 'unit'] +['Temp', 'orary'] +['ĠEng', 'agement'] +['Ġx', 'f'] +['Ġprox', 'ies'] +['Ġgen', 'esis'] +['Pager', 'Adapter'] +['ĠSl', 'ave'] +['Ġsung', 'lasses'] +['ĠCh', 'loe'] +['Ġko', 'ji'] +['ad', 'em'] +['ĉ', 'JSONObject'] +['Î', '³'] +['Ġh', 'ors'] +['*', 'w'] +['ó', 'r'] +['es', 'ch'] +['Ġcritic', 'ised'] +['z', 'ial'] +['ĠSale', 'm'] +['.Vert', 'ical'] +['ĠR', 'ash'] +['>', 'E'] +['ter', 'ing'] +['/s', 'creens'] +['Ġheight', 'ened'] +['аÑĢ', 'ÑĤ'] +['Author', 'ities'] +['_b', 'box'] +['ün', 'st'] +['.font', 'Size'] +['ĠBO', 'OLEAN'] +['div', 'ide'] +['ĠSlo', 'ven'] +['uc', 'er'] +['Ù', 'Ĵ'] +['st', 'ub'] +['Ġnavig', 'ating'] +[':', 'animated'] +['_N', 'OW'] +['_v', 'ect'] +['}', '{Ċ'] +['@', '('] +['Ġtele', 'com'] +['Ġcontract', 'ing'] +['ĠAss', 'ange'] +['Ġextract', 'ing'] +['Ġgr', 'ö'] +['c', 'obra'] +['.D', 'IS'] +['Ġcr', 'ab'] +['Ġtw', 'itch'] +['Ġvert', 's'] +['Ġreject', 's'] +['ĉ', 'format'] +['Ġreg', 'eneration'] +['.S', 'ys'] +['s', 'olve'] +['ĉd', 'ialog'] +['sh', 'i'] +['m', 'eter'] +['(b', 'est'] +['valid', 'ators'] +['Ġon', 'wards'] +['Ġg', 'uru'] +['Ġmoder', 'ator'] +['ow', 'ied'] +['ex', 'periment'] +['r', 'ub'] +['Ġm', 'qtt'] +['ĠCa', 'ucas'] +['Ġnational', 'ism'] +['Ġm', 'ange'] +['ĉ', 'ImGui'] +['/', 'Edit'] +['Ġin', 'h'] +['Ġint', 'ellig'] +['ero', 'kee'] +['ĉ', 'export'] +['Ġdiscrim', 'inate'] +['sub', 'tract'] +['ĠM', 'oodle'] +['ens', 'er'] +['ĠGuid', 'es'] +['R', 'AP'] +['-h', 'ot'] +['_gr', 'p'] +['.p', 'icture'] +['X', 'A'] +['Ġinit', 'View'] +['_Com', 'm'] +['Ġoverd', 'ose'] +['Ġ+', 'ĊĊ'] +['ĠSil', 'ent'] +['show', 's'] +['Ġinterpol', 'ate'] +['Form', 'ation'] +['Ġb', 'isc'] +['mark', 'ets'] +['(', 'SC'] +['Z', 'e'] +['ĠNetwork', 'ing'] +['Ġad', 'renal'] +['ĠG', 'uns'] +['ete', 'or'] +['Decl', 'ared'] +['orget', 'own'] +['Ġk', 'arena'] +['/', 'password'] +['_address', 'es'] +['ITER', 'AL'] +['B', 'uzz'] +['ĠCon', 'way'] +['(c', 'ase'] +['P', 'WD'] +['he', 'iro'] +['(', 'act'] +['**', 'čĊ'] +['());ĊĊ', 'Ċ'] +['Ġan', 'v'] +['Ġ.', '.ĊĊ'] +['(Menu', 'Item'] +['(m', 'ail'] +['_section', 's'] +['ĉ', 'net'] +['Ġpl', 'ut'] +['Ġw', 'rench'] +['/', 'object'] +['ĠI', 'st'] +['ĠV', 'IS'] +['/p', 'ub'] +['al', 'ten'] +['Ġguit', 'ars'] +['Ġantibiot', 'ic'] +['ï¼', 'ĸ'] +['Â', '¹'] +['Ġ"', '+"'] +['form', 'ula'] +['Ġbab', 'es'] +['ĠP', 'rompt'] +['Ġen', 'im'] +['/', 'player'] +['ĉ', 'ref'] +['Ġby', 'Äĩ'] +['Ġconsum', 'es'] +['ĠH', 'ast'] +['ĠT', 'ao'] +["Ġ'", '))Ċ'] +['Ġcl', 'am'] +['Ġthigh', 's'] +['Ġmot', 'if'] +['Api', 'Operation'] +['ĠW', 'L'] +['get', 'C'] +['ĉf', 'lags'] +['oint', 'ments'] +['Ġeconom', 'ical'] +['need', 'le'] +['x', 'ls'] +['pr', 'actice'] +['ut', 'zer'] +['time', 'ofday'] +['-', 'output'] +['Ġfind', 'ById'] +['ĠBudd', 'y'] +['Ðŀ', 'ÑĤ'] +['Se', 'ven'] +['ĠB', 'ark'] +['Ġenv', 'oy'] +['_al', 'gorithm'] +['åĪ', '©'] +['Ġball', 'istic'] +['ç§', '»'] +['r', 'ades'] +['ĉd', 'oc'] +['rodu', 'cing'] +['ĠE', 'ating'] +['Un', 'mount'] +['/data', 'Tables'] +['_b', 'onus'] +['Ġl', 'itt'] +['pp', 's'] +[')', 'localObject'] +['per', 'f'] +['ĠHel', 'vetica'] +['sh', 'utdown'] +['/', 'ml'] +['.t', 'okens'] +['ĠHard', 'core'] +[',', 'row'] +['/b', 'g'] +['Sc', 'aler'] +['âĢĶ', 'as'] +['_log', 'its'] +['âĢĻ', 'int'] +['ĉ', 'App'] +['Imp', 'licit'] +['.F', 'printf'] +['ET', 'O'] +['Ġterr', 'a'] +['Ġpossess', 'ing'] +['.r', 'strip'] +[',', '),'] +['=', 'yes'] +['ĠStr', 'ipe'] +['?', '='] +['ne', 'utral'] +['.g', 'ood'] +['Ġk', 'ennen'] +['ĠS', 'ung'] +['f', 'ault'] +['ystate', 'change'] +['Can', 'adian'] +["','", '".$'] +['ĠM', 'its'] +['æ', 'nd'] +['ĠSTR', 'UCT'] +['ĠURL', 'WithString'] +['ĠCom', 'pass'] +['Ġ--', 'ĊĊ'] +['ĠNS', 'LayoutConstraint'] +['|', 'min'] +['-ad', 'just'] +['Ġreb', 'uilt'] +['L', 'IGHT'] +['/', 'se'] +['-m', 'ount'] +['vp', 'n'] +['valid', 'ated'] +['(Q', 'Object'] +['Ġign', 'ition'] +['ĠCharg', 'ers'] +['RYPT', 'O'] +[']initWith', 'Frame'] +['ĠFl', 'uid'] +['Ġcad', 're'] +['Ġnomin', 'ations'] +['Ne', 'ill'] +['ĠH', 'ou'] +['Ġcurrent', 's'] +['_g', 'ene'] +['(in', 'p'] +['Par', 'is'] +['z', 'ÄĻ'] +['ag', 'gregate'] +['Ġass', 'oc'] +['weet', 'ed'] +['err', 'at'] +['âĢĵ', 'ĊĊ'] +["Ġ'/", "',Ċ"] +['fix', 'ture'] +['ĠH', 'ighest'] +['amb', 'ient'] +['Ġch', 'mod'] +['Ġcon', 'te'] +['Ġsens', 'ual'] +['Ġgar', 'ment'] +['z', 'ers'] +['ĠPower', 'ed'] +['dom', 'ains'] +['R', 'eward'] +['i', 'omanip'] +['Ġcock', 'pit'] +['out', 'file'] +['Ġbuilt', 'in'] +['Ġins', 'isting'] +['.', 'vars'] +['zip', 'code'] +['Ġ', '����'] +['f', 'ails'] +['Ġconsolid', 'ation'] +['_', 'oid'] +['Plan', 'et'] +['Ġ=', '",'] +['ĉ', 'el'] +['UIL', 'T'] +['ät', 'z'] +['af', 'ari'] +['ĠMc', 'Cl'] +['Tim', 'eline'] +['Est', 'a'] +['Ġfr', 'am'] +['Y', 'E'] +['Ġcere', 'bral'] +['Of', 'Month'] +['ĠP', 'regn'] +['Ġкл', 'аÑģÑģ'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĊ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĊ'] +['ĠF', 'res'] +['Appro', 'ved'] +['.S', 'pecial'] +['ĠProtest', 'ant'] +['Ġallerg', 'y'] +['_p', 'cm'] +['ĉC', 'opyright'] +['Ġsuper', 'Class'] +['"', 'strconv'] +['ĠMoh', 'amed'] +["Ġ'", '//'] +['Fore', 'Color'] +['Ar', 'thur'] +['ĠJ', 'ungle'] +['Ġve', 'ins'] +['S', 'ad'] +['Ġback', 'ups'] +['ĠOp', 'inion'] +['û', 't'] +['Ġinter', 'mitt'] +['ody', 'n'] +['ĠChrist', 'ina'] +['Ġand', 're'] +['Ġevac', 'uation'] +['pa', 'lette'] +['h', 'orse'] +['ĠRes', 'ident'] +['ĠHass', 'an'] +['.N', 'il'] +['Ġa', 'isle'] +['ĠG', 'rowing'] +['Ġblog', 'info'] +['/s', 'ql'] +['_io', 'ctl'] +['Sc', 'aling'] +['ĠMon', 'ad'] +['_c', 'pp'] +['ĠH', 'utch'] +['ĠApple', 'WebKit'] +['Exp', 'ense'] +['_J', 'OB'] +['Ġpoint', 'less'] +['From', 'Body'] +['ant', 'al'] +['Ġdepict', 'ing'] +['ĠC', 'ELL'] +['Ġref', 'in'] +['ĠC', 'NC'] +['ì¹', 'ĺ'] +['_dim', 'ensions'] +['ĠS', 'AN'] +['Ġa', 'ft'] +['Ġfoot', 'steps'] +['cc', 'oli'] +['_PH', 'ONE'] +['/m', 'ath'] +['-k', 'ind'] +['ĠMe', 'ans'] +['ich', 'ael'] +['.g', 'una'] +['Ġinaug', 'uration'] +['-dr', 'iving'] +['(', 'delete'] +['Ġtotal', 'Count'] +['_M', 'C'] +['.Ext', 'ension'] +['Com', 'mercial'] +['Ġz', 'Index'] +['<', 'Customer'] +['"', 'g'] +['-sh', 'are'] +['Ġp', 'act'] +['ag', 'ara'] +['ĠS', 'IL'] +['_m', 'odes'] +['ĠM', 'olecular'] +['Ġsystem', 'atically'] +['<', 'G'] +['_s', 'cr'] +['ĠO', 'ro'] +['as', 'ers'] +['Ġb', 'ic'] +['Ġdest', 'roys'] +['PI', 'PE'] +['.Start', 'Position'] +['Ġc', 'á»§a'] +['ire', 'z'] +['.B', 'unifu'] +['_F', 'unction'] +['Ġs', 'ü'] +['_f', 'uture'] +['ĠWe', 'alth'] +['ĠNatur', 'ally'] +['æĢ', '»'] +['_y', 'es'] +['Ġabrupt', 'ly'] +['String', 'Encoding'] +['ĠCGPoint', 'Make'] +['Ġz', 'h'] +['Ġimp', 'erson'] +['Ġpiv', 'otal'] +['ĠSom', 'alia'] +['Ġsegment', 'ation'] +['_AN', 'AL'] +['ĠLogin', 'Component'] +['Cons', 'ult'] +['Ġtr', 'uncated'] +[']', '";Ċ'] +['.get', 'Config'] +['Ġintern', 'ship'] +['B', 'aby'] +['ê°', 'ľ'] +['Ġstrengthen', 'ed'] +['_M', 'I'] +['b', 'asket'] +['Ġnicht', 's'] +['ĠTV', 's'] +['ĠSh', 'an'] +['ãĤ', 'µ'] +['rac', 'use'] +['.Re', 'LU'] +['/', 'interfaces'] +['ĠgetItem', 'Count'] +['Ġret', 'iring'] +['Ġspecial', 's'] +['Ġentity', 'Manager'] +['bel', 'ief'] +['Ġs', 'older'] +['da', 'ughter'] +['ij', 'kl'] +['Ġutil', 'izes'] +['.f', 'ixed'] +['S', 'U'] +['Ġdr', 'astic'] +['Ġh', 'acks'] +['gr', 'und'] +['ĠM', 'U'] +['ĠSt', 'arter'] +['.Com', 'ponents'] +['_m', 'otor'] +['Gold', 'en'] +['Ġl', 'odge'] +['Ġ', '));'] +['ĠCor', 'inth'] +['иÑĩ', 'еÑģÑĤво'] +['ón', 'ico'] +['gre', 'SQL'] +['ĠFl', 'uent'] +['Ġmar', 'c'] +['.Load', 'Scene'] +['.Group', 's'] +['Ġer', 'h'] +['ĠAut', 'umn'] +['St', 'opped'] +['Ġitalian', 'o'] +['Ġmin', 'ions'] +['ĠAssert', 'ions'] +['Ġm', 'ux'] +['B', 'u'] +['Ġ----------------------------------------------------------------', '--------------------------------'] +['ĉ', 'up'] +['read', 'ystatechange'] +['_M', 'eta'] +['Ġcurrent', 'Date'] +['ĠChap', 'man'] +['Und', 'o'] +['Se', 'an'] +['ap', 'r'] +['Ġpar', 'm'] +['_', 'icons'] +['ĠSt', 'a'] +['á', 'z'] +['Ġsub', 'division'] +['Ġalter', 'ing'] +['P', 'NG'] +['ponent', 'ial'] +['Ġpost', 'gres'] +['ĠB', 'DS'] +['-ex', 'istent'] +['ĠBrad', 'ford'] +['ĠO', 'MX'] +['_W', 'HITE'] +['_PRO', 'GRAM'] +['q', 'c'] +['Ġtypings', 'Slinky'] +['ĠP', 'ics'] +['_M', 'ETA'] +['IT', 'TER'] +['_sub', 'scription'] +['IRON', 'MENT'] +['ĠHy', 'undai'] +['();ĊĊ', 'ĊĊ'] +['ĠØ', '³'] +['Ġj', 'ac'] +['Ġelimin', 'ates'] +[')', '});Ċ'] +['Ġcomp', 'rend'] +['ĉ', 'insert'] +['_f', 'aces'] +['">', '$'] +['Ġeb', 'ay'] +['Ġcapt', 'ive'] +['pl', 'iant'] +['ĠCalcul', 'ates'] +['ol', 'ta'] +['est', 'ing'] +['_re', 'vision'] +['Ġm', 'ús'] +['+', 'm'] +['","', '","'] +['WH', 'AT'] +['Ġcompassion', 'ate'] +['h', 'arga'] +['[', 'random'] +['Ġmod', 'ulo'] +['(s', 'n'] +['Ġoccup', 'ations'] +['////', 'Ċ'] +['ĉ', 'board'] +['ĠB', 'alk'] +['wi', 'Äħ'] +['ĠW', 'ifi'] +['.Pro', 'file'] +[':m', 'aj'] +['ĉm', 'at'] +['LOCK', 'S'] +['(j', 'Button'] +["Ġ('", '$'] +['M', 'ur'] +['æĮ', 'ī'] +['b', 'ble'] +['Ġf', 'rog'] +['-h', 'ide'] +['Ġbroad', 'caster'] +['à¸', 'ŀ'] +['ha', 'led'] +['Ġam', 'using'] +['_predict', 'ions'] +['_in', 'tr'] +['Ġe', 'agle'] +['аÑĤ', 'елÑĮ'] +['Ġget', 'List'] +['ps', 'ilon'] +['Ġcharacter', 'ization'] +['AR', 'DS'] +['Ġre', 'location'] +['Ġr', 'ulers'] +['P', 'AY'] +['ĠDef', 'initely'] +['_A', 'ction'] +['Ġclos', 'ures'] +['Ġfact', 'ual'] +['odyn', 'amic'] +['Ġpreca', 'utions'] +['nie', 'j'] +['ĠPart', 'ies'] +['ĠSub', 'aru'] +['Ġcous', 'ins'] +['ar', 'beit'] +['.m', 'oney'] +['gun', 'ta'] +['(', 'and'] +['get', 'item'] +['.Style', 'Priority'] +['Ġsl', 'id'] +['single', 'ton'] +['Ġg', 'arn'] +['ĠP', 'AS'] +['Ġd', 'azz'] +['a', 'ż'] +['Ġbog', 'us'] +['ĠM', 'og'] +['Ġrival', 'ry'] +['is', 'ol'] +['Ġland', 'marks'] +['ñ', 'as'] +['B', 'ern'] +['ĠSach', 's'] +['Ġ"', ')ĊĊ'] +['Ġhost', 'ility'] +['_m', 'ex'] +['m', 'ere'] +['M', 'ot'] +['p', 'ictureBox'] +['Def', 'ense'] +['Ġaffid', 'avit'] +['other', 'wise'] +['.d', 'irectory'] +['_', 'UnityEngine'] +['-b', 'log'] +['.s', 'kin'] +['ph', 'em'] +['Ap', 'ellido'] +['er', 'chant'] +['[', 'class'] +['Ġw', 'art'] +['."', '['] +['ale', 'ur'] +['/', 'back'] +['ĠĠĠĠ', 'ĉĠĠĠ'] +['Ġprecip', 'itation'] +['Ġob', 'struction'] +['Ġp', 'Obj'] +['Ġr', 'upt'] +['UCK', 'ET'] +['ay', 'e'] +['æİ', 'Ĵ'] +['g', 'x'] +['Ġe', 'cl'] +['Ġsecre', 'cy'] +['/', 'Header'] +['ĠLes', 'b'] +['Ġle', 'i'] +['ĠBullet', 'in'] +['Ġgive', 'away'] +['.H', 'ome'] +['_RO', 'OM'] +['"', 'W'] +['Ġcow', 'ork'] +['_', 'ra'] +['ĠC', 'ycling'] +['ĠP', 'aw'] +['Ġpup', 'il'] +['/', 'arch'] +['ĠFile', 'Utils'] +['é¦', 'ĸ'] +['r', 'sp'] +['Ġfreed', 'oms'] +['ĠL', 'ear'] +['}`', ').'] +['Ġbow', 'ls'] +['/b', 'lock'] +['_log', 'ging'] +['Ġmeth', 'ane'] +['Ġhorn', 's'] +['Ġwonder', 'fully'] +['Ġalter', 'ations'] +['Ġex', 'ile'] +['ls', 'en'] +['_p', 'ause'] +['_L', 'ANGUAGE'] +['ĠUS', 'DA'] +['_m', 'ysql'] +['_AM', 'OUNT'] +['ĠL', 'IFE'] +['Ġyoung', 'sters'] +['Ġri', 'ots'] +['[', 'E'] +['Ġun', 'forgettable'] +[',', '},Ċ'] +['Dis', 'posed'] +['ĠAss', 'assin'] +['UN', 'G'] +['ĠNew', 'sp'] +['User', 'Service'] +[':', 'aload'] +['+', "',"] +['Ġsett', 'lers'] +['Ġscre', 'ams'] +['Ġincon', 'venience'] +['.R', 'otate'] +['Ġj', 'ars'] +['ĠP', 'uzzle'] +['Ġm', 'est'] +['ars', 'i'] +['ĠSh', 'arma'] +['|', '('] +['.d', 's'] +['ĠSac', 'red'] +['_e', 'vt'] +['Ġexpress', 'es'] +['Ġh', 'och'] +['ĠD', 'uch'] +['.c', 'alls'] +['th', 'r'] +['ĠShe', 'ffield'] +['.Alert', 'Dialog'] +['Ġrad', 'ically'] +['Ġtr', 'ous'] +['Ġprev', 'ailing'] +['ĠWW', 'II'] +['âĢĻ', 'n'] +['ens', 'ely'] +['ĠY', 'esterday'] +['ĠSir', 'ius'] +['Ġkill', 'ers'] +['ĠF', 'FT'] +['Ġo', 'val'] +["')", ':čĊ'] +['Ġìłķ', 'ë³´'] +['our', 'age'] +['ĠCheck', 'box'] +['Work', 'book'] +['.def', 'er'] +['_f', 'loor'] +['Ġc', 'ouncill'] +['Ġnors', 'ke'] +['mo', 'il'] +['ore', 'a'] +['Ġmarket', 'ed'] +['_S', 'UR'] +['x', 'AA'] +['Ġst', 'ained'] +['e', 'ut'] +['ĠM', 'eng'] +['Ġi', 'eee'] +['.', 'extern'] +['eg', 'ie'] +['Ġr', 'app'] +['ĠPy', 'ongyang'] +["'", 'class'] +['M', 'ob'] +['Ġinitial', 'Value'] +['_w', 'ave'] +['Ġj', 'ab'] +['Ġmascul', 'ine'] +['Ġampl', 'ifier'] +['Ġt', 'ty'] +['Path', 'Component'] +['_', 'xt'] +['ĠG', 'FP'] +['/', 'sec'] +['ĉdis', 'patch'] +['mark', 'down'] +['ĠS', 'chn'] +['bo', 'le'] +['·', '·'] +['mouse', 'move'] +['Ġerr', 'Msg'] +['Ġas', 'ign'] +['_m', 'ono'] +['To', 'Selector'] +['ĠZ', 'u'] +['(R', 'ect'] +['ĠError', 'Code'] +['lat', 'in'] +['ang', 'ible'] +['v', 'tk'] +['CG', 'Size'] +['P', 'okemon'] +['Ġclass', 'mates'] +['Ġattract', 's'] +['ĠT', 'atto'] +['ult', 'an'] +['ol', 'óg'] +['Ġhalt', 'ed'] +['à¤', '¨'] +['ĠK', 'art'] +['Ġ', 'ue'] +['_Init', 'Structure'] +['Test', 'Class'] +['ĠAir', 'bnb'] +['_', '",'] +['Ġchar', 'coal'] +['Ġip', 'c'] +['ĠSt', 'retch'] +['.g', 'lide'] +['lates', 'AutoresizingMaskIntoConstraints'] +['Ġpot', 'ion'] +['ITT', 'LE'] +['Ġcount', 'ert'] +['_h', 'd'] +['pre', 'pared'] +['Ad', 's'] +['ĠV', 'ampire'] +['rob', 'ots'] +['.Create', 'Index'] +['Status', 'Label'] +['Ġt', 'ucked'] +['af', 'ür'] +['U', 't'] +['Ġswe', 'ater'] +['_F', 'N'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĉ'] +['ata', 'ka'] +['Ġeyeb', 'rows'] +['ac', 'oes'] +['ud', 'en'] +['.LinearLayout', 'Manager'] +['Ġsw', 'ay'] +['Ġmult', 'in'] +['()', ')))Ċ'] +['ĠNS', 'UInteger'] +['ĠMy', 'Base'] +['Part', 'ner'] +['uts', 'chen'] +['ĠC', 'ater'] +['.setBackground', 'Color'] +['Ġaccompl', 'ishment'] +['_pro', 'blem'] +['.d', 'td'] +['Ġpage', 'Number'] +['Ġj', 'ackets'] +['Ġcro', 'pped'] +['u', 'els'] +['ĠH', 'ep'] +['Ġc', 'apped'] +['*', 'Math'] +['_callback', 's'] +['Ġpub', 'b'] +['ĠBrun', 'swick'] +['.res', 'pond'] +['["', '_'] +['Ġbed', 'ding'] +['hyth', 'm'] +['O', 'X'] +['(s', 'peed'] +['Ġpestic', 'ides'] +['Ġ----', '---'] +['.Bl', 'ue'] +['Ġnood', 'les'] +['ĠGo', 'es'] +['Ġs', 'aver'] +['o', 'xy'] +['_com', 'pletion'] +['ĠSw', 'inger'] +['Ġget', 'Date'] +['Ġmind', 'ed'] +['int', 'egration'] +['ĠLot', 'us'] +['(st', 'op'] +["(',", "');Ċ"] +['Ġflood', 's'] +['ĠWork', 'flow'] +['Ġerupt', 'ed'] +['Mac', 'ro'] +['ĠSau', 'ce'] +['Ġevent', 'Name'] +['\\', 'Input'] +['Break', 'ing'] +['ĉ', 'when'] +['_p', 'w'] +['IND', 'ER'] +['ĠWell', 'ness'] +['Ġvox', 'el'] +['ĠM', 'ell'] +['ĠM', 'EDIA'] +['SE', 'NS'] +['ĠFund', 's'] +['ĠM', 'ild'] +['<', 'Array'] +['-', 'this'] +['ump', 'ed'] +['/f', 'w'] +['ĠDb', 'Context'] +['W', 'I'] +['girl', 's'] +['H', 'OW'] +["');", '?>Ċ'] +['Ġtempt', 'ing'] +['Ġtest', 'ament'] +['Ġb', 'ible'] +['Ġconsult', 'ed'] +['ĠIndex', 'Error'] +['è¨', 'ĺ'] +['Ġkey', 'pad'] +['izz', 'o'] +['(', 'ok'] +['Ġwhats', 'app'] +['ĠRemote', 'Exception'] +['Ġteam', 'ed'] +['âĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶ', 'âĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶ'] +['»', ','] +['Ġget', 'Time'] +['di', 'ag'] +['iss', 'y'] +['Ġh', 'ed'] +['Ġkn', 'ots'] +['j', 'om'] +['Ġfun', 'nel'] +['-m', 'ails'] +['Ġexport', 'ing'] +['ĠV', 'L'] +['ĠK', 'arn'] +['ĠBuddh', 'ism'] +['ĠAll', 'an'] +['_R', 'ADIUS'] +['Ġw', 'ording'] +['ĠFor', 'get'] +['ĠCor', 'ona'] +['ip', 'hy'] +['Ġlim', 'burg'] +['ugg', 'y'] +['ĠUser', 'Repository'] +['im', 'in'] +['(e', 'le'] +['Ġlabel', 'led'] +['ç¤', '¾'] +['ĠH', 'erman'] +['.q', 'q'] +['Ġ"', '));Ċ'] +['ie', 'ber'] +['.Trans', 'late'] +['ry', 'n'] +['Ġdes', 'env'] +['um', 'd'] +['Sim', 'ply'] +['ĉm', 'ode'] +['R', 'pc'] +['ĠVal', 'encia'] +['Ġstaff', 'ers'] +['Ġsel', 'v'] +['ĠSpi', 'ke'] +['Ġdel', 'ic'] +['Ġer', 'u'] +['_D', 'T'] +['J', 'udge'] +['á»', 'ķ'] +['ĠBas', 'in'] +['.m', 'utable'] +['"', 'url'] +['Ġtar', 'iff'] +['ĠSlee', 've'] +['Ġfl', 'are'] +['.drop', 'out'] +['Ġbr', 'ides'] +['))', ',čĊ'] +['_con', 'straints'] +['de', 'struct'] +['Out', 'line'] +['Ġdisappe', 'ars'] +['_lock', 'ed'] +['ĠNS', 'LocalizedString'] +['ck', 'e'] +['ĉ', 'null'] +['ad', 'resse'] +['Ġto', 'pping'] +['ĠJ', 'oker'] +['b', 'ishop'] +['но', 'ÑģÑĤÑĮ'] +['and', 'ering'] +['_', 'amp'] +['=', 'time'] +['_S', 'pace'] +['_P', 'ULL'] +["'", '='] +['Ġant', 'iqu'] +['Ġc', 'ach'] +['___', 'ĊĊ'] +['ON', 'ES'] +['о', 'Ñı'] +['Ġun', 'read'] +['.p', 'olicy'] +['oooo', 'oooo'] +['ëŁ', '¬'] +['Ġu', 'sted'] +['ĠRe', 'ce'] +['Ġal', 'lem'] +['ãĥ¼', 'ãĤ¹'] +['ĠThought', 's'] +['ve', 'illance'] +['istr', 'ate'] +['_l', 'ane'] +['Ġfam', 'ed'] +['.Get', 'Name'] +['Ġsmo', 'other'] +['ĠQual', 'ified'] +['az', 'ers'] +['_', 'geo'] +['F', 'ax'] +['ĠM', 'inds'] +['ĠR', 'aises'] +['Ġtrans', 'cripts'] +['Con', 'versation'] +['Ġremark', 'ed'] +['ëĤ', 'ĺ'] +['d', 'ling'] +['Ġdeploy', 'ing'] +['Ġshared', 'Application'] +['Ġk', 'p'] +['FontAwesome', 'Icon'] +['_d', 'ummy'] +['reib', 'en'] +['ĠJane', 'iro'] +['Direction', 's'] +['.get', 'Bean'] +['s', 'ass'] +['Ġcommand', 'ers'] +['v', 'ation'] +['error', 'Code'] +['ĠAl', 'loy'] +['.local', 'ized'] +['Ð', 'ij'] +['Ġdish', 'washer'] +['ĠSou', 'p'] +['N', 'u'] +['_D', 'efault'] +['Ġune', 'ven'] +['Ġ/>', '";Ċ'] +['-B', 'ased'] +['Ġseam', 'lessly'] +['-', 'null'] +['ĠX', 'C'] +['Ġst', 'ew'] +['(d', 'elay'] +['AT', 'ORS'] +['ĠWhe', 'eler'] +['"', '', 'H'] +['e', 'ast'] +['.', 'air'] +['âĢľ', 'But'] +['Object', 'Context'] +['success', 'fully'] +['_l', 'and'] +['Ġfold', 's'] +['_CO', 'ORD'] +['Ġsub', 'po'] +['.get', 'Address'] +['in', 'str'] +['Material', 's'] +['Ñĥ', 'ÑģÑĤ'] +['de', 'posit'] +['-l', 'ast'] +['_GR', 'AY'] +['=', 'find'] +['Ġmut', 'ant'] +['Ġlesb', 'ienne'] +['let', 'cher'] +['RO', 'UGH'] +['ure', 'ka'] +['.c', 'apture'] +['Ġen', 'n'] +['Ġ([', '['] +['ĠFl', 'u'] +['Ġtask', 'Id'] +['ĠHus', 'sein'] +['.f', 'older'] +['Ġa', 'usterity'] +['ISTR', 'ATION'] +['_', 'Impl'] +['注', 'æĦı'] +['Ġdec', 'ree'] +['-', 'chat'] +['Ġimp', 'lication'] +['Ġguess', 'es'] +['ul', 'kan'] +['An', 'alytics'] +['.', 'plus'] +['COM', 'MAND'] +['е', 'ли'] +['»', 'ĊĊ'] +['_S', 'ITE'] +['Ġequal', 'To'] +['Support', 'FragmentManager'] +['ĠRec', 'ording'] +['å®Į', 'æĪIJ'] +['Ġbag', 'gage'] +['Ġpitch', 'ers'] +['ĠE', 'h'] +['o', 'que'] +['ĉc', 'nt'] +['Ġ=>', '$'] +['/', 'foo'] +['IR', 'A'] +['ĠSat', 'ellite'] +['bor', 'ah'] +['Ġ}}', '"Ċ'] +['ĠEnd', 's'] +['ĠSpr', 'ay'] +[',', 'param'] +['.Ch', 'rome'] +['*', 'q'] +['th', 'ought'] +['ibr', 'ated'] +['Ġth', 'ieves'] +['Ġbenefici', 'aries'] +['Enter', 'ed'] +['ottes', 'ville'] +['Ġveter', 'in'] +['By', 'ID'] +['qu', 'ipe'] +['um', 'ption'] +['-', 'unit'] +['Execution', 'Context'] +['@', 's'] +['ĠG', 'iov'] +['.Tool', 'Tip'] +['_f', 'riend'] +['(', 'attributes'] +['Ġdump', 'ing'] +['ĠJ', 'C'] +['_D', 'OCUMENT'] +['ĠArm', 'our'] +['(', 'insert'] +['.Horizontal', 'Alignment'] +['ĠQ', 'ed'] +['ãģĦ', 'ãģ¾ãģĻ'] +['/g', 'it'] +['ĠY', 'YYY'] +['ĠCard', 'iff'] +['Ġap', 'a'] +['organ', 'ic'] +['ĠWhere', 'as'] +['Ġæ', 'Ŀ'] +['ĠM', 'ia'] +['Ġdemol', 'ition'] +['Ġsc', 'ars'] +['Ġp', 'ai'] +['Ġre', 'tries'] +['Ġr', 'q'] +['ĠDen', 'is'] +['(', 'Utils'] +['Ġallev', 'iate'] +['ĠP', 'IC'] +['id', 'ue'] +['Ġacknowled', 'ging'] +['Ġ//', '////////////////////////////////'] +['ç¡®', 'å®ļ'] +['Ä', '«'] +['\\', 'Json'] +['.b', 'inary'] +['Ġx', 'type'] +['sign', 'als'] +['ĠAp', 'pearance'] +['&', 'r'] +['}', 's'] +['C', 'i'] +['ĠI', 'llum'] +['por', 'ate'] +['h', 'og'] +['Ġindex', 'Of'] +['\\', 'Command'] +['_par', 'allel'] +['ĠSher', 'lock'] +['í', 'ĥ'] +['Ġ"', '")čĊ'] +['////////////////////////////////////////////////////////////////', '////////////////////////////////'] +['Ġcritic', 'ize'] +['ĠSo', 'ap'] +['ĠMatch', 'er'] +['Ġgr', 'illed'] +['*', 'T'] +['Ġad', 'ore'] +['ull', 'ing'] +['Ġjed', 'och'] +['_ref', 's'] +['lean', 'up'] +['ĠJ', 'AXB'] +['Ġro', 'ses'] +['ĠL', 'iam'] +['size', 'i'] +['Ġget', 'char'] +['Ġtar', 'de'] +['-to', 'oltip'] +['Ġqual', 'ifier'] +['ĠInter', 'mediate'] +['_W', 'indow'] +['ĠMal', 'ta'] +['Dis', 'connect'] +['ew', 'here'] +['Camp', 'o'] +['Ġirr', 'ational'] +['led', 'o'] +['ĠD', 'N'] +['ARG', 'V'] +['Ġout', 'ro'] +['Ġth', 'irteen'] +['Jose', 'ph'] +['M', 'AR'] +['/g', 'l'] +['J', 'ess'] +['ĠPsych', 'iat'] +['Ġpadding', 'Bottom'] +['-', 'loop'] +['/', 'fonts'] +['_se', 'en'] +['Te', 'ams'] +['React', 'DOM'] +['(m', 'an'] +['(x', 'path'] +['.get', 'SimpleName'] +['>(', '*'] +['ĠP', 'vt'] +['Ġel', 'ders'] +['Ġp', 'ies'] +['.user', 'Agent'] +['-', 'region'] +['ĠGree', 'ks'] +['(f', 'ragment'] +['st', 'u'] +['Ġcouncil', 's'] +['Ġst', 'amina'] +['ĠGod', 'dess'] +['è', '¥¿'] +['Ġphilosoph', 'ers'] +['Ġpers', 'one'] +['ĠL', 'ose'] +['ĠCL', 'R'] +['ĠD', 'ocs'] +['Ġso', 'ak'] +['ĠHOLD', 'ER'] +['Ġb', 'ells'] +['hash', 'Code'] +['R', 'ATE'] +['_WE', 'IGHT'] +['in', 'ous'] +['end', 'ra'] +['oph', 'obic'] +['Ġpro', 'se'] +['Ġfin', 'ely'] +['/o', 'auth'] +['(s', 'pace'] +['ad', 'ge'] +['ĠM', 'ama'] +['Ġstring', 'Buffer'] +['Ġst', 'int'] +['Ġmis', 'ma'] +['Ġvill', 'ains'] +['ĠCrime', 'a'] +['Ġdipl', 'oma'] +['Ġпо', 'Ñģл'] +['ĠBe', 'a'] +['(j', 'oin'] +['Ġíķ', '´'] +['CH', 'AT'] +['per', 'ing'] +['ĠC', 'ros'] +['Ġmon', 'keys'] +['Ġpred', 's'] +['yl', 'a'] +[',,', ','] +['Ġvibr', 'ator'] +['ĠN', 'U'] +['åħ', 'Ī'] +['f', 'ant'] +['z', 'et'] +['Ġb', 'ietet'] +['un', 'ft'] +['sw', 'orth'] +['.F', 'low'] +['Ġpsy', 'ched'] +['ĠContin', 'ental'] +['>', 't'] +['Ġqu', 'ilt'] +['.', 'UP'] +['Ġexpans', 'ive'] +['Dis', 'pose'] +['(l', 'anguage'] +['C', 'aps'] +['_Z', 'ONE'] +['Ġrec', 'ycle'] +['ĠMan', 'aged'] +['current', 'Color'] +['.b', 'roadcast'] +['sign', 'In'] +['.p', 'rom'] +['ll', 'u'] +['ue', 'blo'] +['Ġpunch', 'es'] +['Ġautom', 'at'] +['Ġassign', 'ing'] +['Ġcreate', 'User'] +['ĠAll', 'ied'] +['Ġconduct', 'or'] +['Ĥ', '¨'] +['Ġs', 'addle'] +['Ġd', 'ni'] +['omed', 'ical'] +['-W', 'est'] +['Positive', 'Button'] +['Ġit', 'alic'] +['?', '['] +['(tr', 'igger'] +['Ġele', 'phants'] +['":"', '","'] +['Ġcal', 'iber'] +['raft', 'ed'] +['d', 'igits'] +['Ġmar', 'shal'] +['mill', 'iseconds'] +['mark', 'ers'] +['m', 'om'] +['/', 'place'] +['Ġhol', 'istic'] +[':', 't'] +['#', ','] +['Ġb', 'oto'] +['Ġnause', 'a'] +['ĠSh', 'ooting'] +['ite', 'ch'] +['Ġtext', 'Status'] +['<', 'Class'] +['ĠDes', 'cribe'] +['Ġbuff', 'et'] +['g', 'il'] +['Ġlog', 'its'] +['std', 'call'] +['mod', 's'] +['ĠSk', 'ull'] +['ĠB', 'are'] +['h', 'ope'] +['ĠIn', 'tr'] +['F', 'air'] +['ĉ', 'pt'] +['Ġacompan', 'h'] +['Ġf', 'kk'] +['_r', 'pc'] +['Inst', 'alled'] +['_', 'ans'] +['.get', 'Minutes'] +['â̦', '"ĊĊ'] +['-', 'thread'] +['Ġpres', 'chool'] +['AIL', 'S'] +['Ġdiff', 'ic'] +['(', 'convert'] +['ĠN', 'ath'] +['ĠDO', 'J'] +['Ġreg', 'imes'] +['Ġenthusi', 'ast'] +['Ġwarrant', 'ies'] +['Ġfasc', 'inated'] +['_b', 'inding'] +['_N', 'ot'] +['oft', 'en'] +['_R', 'W'] +['/m', 'ail'] +['Ġtitle', 'Label'] +['Ġvill', 'agers'] +['ĠJ', 'iang'] +['Ġsw', 'agger'] +['.Row', 'Index'] +['_img', 's'] +['rap', 'y'] +['VER', 'AGE'] +['.', 'Up'] +['Ġno', 'op'] +['c', 'io'] +['ĉ', 'ST'] +['Ġdecre', 'ment'] +['Ġmagn', 'esium'] +['_', 'rotate'] +['S', 'it'] +['Ġnieu', 'we'] +['Ġter', 'med'] +['íķ', '©ëĭĪëĭ¤'] +['Ġur', 'g'] +['_t', 'ouch'] +['Ġsw', 'arm'] +['Ġcl', 'ave'] +['th', 'est'] +['ĠL', 'af'] +['H', 'X'] +['ĠH', 'ulk'] +['Ġplaint', 'ext'] +['ĠSof', 'a'] +['get', 'Session'] +['L', 'ed'] +['Ġecosystem', 's'] +['he', 'i'] +['ĠK', 'ills'] +['Ġhus', 'bands'] +['Ñħ', 'ÑĢан'] +['(d', 'om'] +['_t', 'iles'] +['Nib', 'Name'] +['Ġdon', 'ating'] +['.', 'acc'] +['Ġlifes', 'pan'] +['.b', 'n'] +['_RG', 'CTX'] +['æ', '¥'] +['ans', 'en'] +['Ġmod', 'elling'] +['Layout', 'Params'] +['ĠonChange', 'Text'] +['rs', 'a'] +['-', 'location'] +['.P', 'e'] +['(b', 'us'] +['(s', 'ong'] +['Ġprodu', 'k'] +['ĠSH', 'OULD'] +['ĠC', 'J'] +['Ġs', 'os'] +['ĠHome', 'Controller'] +['.load', 'ed'] +['(D', 'ocument'] +['.s', 'ocial'] +['t', 'iles'] +['Ġl', 'ame'] +['=', 'df'] +['.parse', 'Long'] +['Ġpr', 'ac'] +['Ġdet', 'ox'] +['ĠV', 'E'] +['Ġpunt', 'os'] +['Ġdo', 'ctr'] +['Ġan', 'cor'] +['CA', 'PE'] +['Ġc', 'mb'] +['çĦ', '¶'] +['*)', '"'] +['://', '/'] +['Value', 'Type'] +['Ġmort', 'gages'] +[';', 'q'] +['ĠRock', 'ets'] +['s', 'port'] +['UG', 'C'] +['ct', 's'] +['ãĤ', 'ģ'] +['ie', 'ur'] +['ĠAppe', 'al'] +['(n', 'b'] +['////////////////////////////////////////////////', '////////'] +['IM', 'ATION'] +['ĠC', 'res'] +['ĠMan', 'ip'] +['C', 'ause'] +['at', 'ypes'] +['man', 'ufacturer'] +['#', '----------------------------------------------------------------------------'] +['Ġsp', 'or'] +['es', 'on'] +['Ġpun', 'ched'] +['Ġbook', 'marks'] +['ĠBul', 'k'] +['Complete', 'Listener'] +['ĠTalk', 'ing'] +['ĠEr', 'nest'] +['Ġrub', 'bish'] +['k', 'ills'] +['ĠDE', 'FIN'] +['Ġneighbour', 'ing'] +['ar', 'lo'] +['ĠP', 'CA'] +['ĉm', 'atrix'] +['lo', 'k'] +['Ġat', 'las'] +['ĠG', 'ur'] +['Ġw', 'yn'] +['-n', 'egative'] +['Ġt', 'ul'] +['Ġre', 'lic'] +['ĠV', 'oltage'] +['ĠPre', 'is'] +['ĠJ', 'NICALL'] +['ĠPM', 'ID'] +['ak', 'et'] +['ĉ', 'attr'] +['Ġet', 'iqu'] +['ĠM', 'J'] +['ĠG', 'mail'] +['cl', 'r'] +['_exec', 'ution'] +['éĶ', '®'] +['pos', 'itor'] +['.', 'af'] +['N', 'r'] +['Ge', 'orgia'] +['Top', 'ology'] +['Ġperch', 'é'] +['Ġmus', 'lim'] +['Ġepid', 'emi'] +['Ġsab', 'ot'] +['act', 'us'] +['Ġë', 'ĮĢ'] +['ĠIO', 'Error'] +['.', 'est'] +['p', 'refs'] +['ĠKr', 'ish'] +['.Read', 'Key'] +['NAS', 'A'] +['u', 'ção'] +['_D', 'b'] +['umer', 'ator'] +['W', 'ide'] +['(st', 'atement'] +['.end', 'point'] +['....', '.....'] +['Ġ[', '*'] +['stream', 's'] +['m', 'time'] +['P', 'x'] +['at', 'r'] +['Ġt', 'pl'] +['R', 'oman'] +['Ġscen', 'ic'] +['.n', 'z'] +['ĠSe', 'conds'] +['sub', 'menu'] +['Ġìĭ', '¤í'] +['_b', 'undle'] +['Ġde', 'ÄŁ'] +['ĠS', 'isters'] +['pre', 'ferences'] +['Ġport', 'a'] +['Ad', 'visor'] +['max', 'Length'] +['ĠG', 'REAT'] +['__', '(Ċ'] +['ole', 'st'] +['ĠLabel', 's'] +['Ġen', 'fer'] +['ĠĠĠĠĠĠ', 'ĊĊ'] +['ĠThe', 'ft'] +['_F', 'ILL'] +['ĠW', 'ise'] +[')', 'application'] +['un', 'ami'] +['>', '())Ċ'] +['ADD', 'RESS'] +['B', 'ST'] +['et', 'zt'] +['ĠQ', 'gs'] +['S', 'ense'] +['Exception', 'Handler'] +['ĠCh', 'u'] +['.get', 'OwnProperty'] +['Ġexerc', 'ised'] +['iot', 'ic'] +['ĠRe', 'leases'] +['Ġp', 'interest'] +['ol', 'ie'] +['is', 'oft'] +['Ġsequ', 'encing'] +['Ġpad', 're'] +[']', '));čĊ'] +['(r', 'adius'] +['.m', 'ed'] +['aint', 'ies'] +['.Object', 'Model'] +['Ġem', 'ple'] +['Ġseg', 'uro'] +['St', 'ars'] +['Ġqual', 'itative'] +['lem', 'n'] +['á»', '±'] +['>', '").'] +['Ġg', 'x'] +['-c', 'ert'] +['ĠAST', 'M'] +['Ġfull', 'name'] +['Ġte', 'lemetry'] +['ĠCamb', 'odia'] +['_', 'ul'] +['ĠCl', 'are'] +['C', 'USTOM'] +['Q', 'C'] +['ĠUn', 's'] +['ĠHTTP', 'S'] +['ĠPark', 'inson'] +['ancy', 'box'] +["','", '.'] +['T', 'ue'] +['.get', 'Last'] +['Ġab', 'i'] +['Äħ', 'd'] +['A', 'st'] +['ĠEd', 'iting'] +['.Un', 'ity'] +['j', 'mp'] +['Ġm', 'ats'] +['Ġshared', 'Preferences'] +['Capt', 'ain'] +['.page', 'Size'] +['Ġr', 'tl'] +['Ġan', 'meld'] +['Runtime', 'Object'] +['Ġdemand', 'e'] +['("', ';'] +['se', 'ite'] +['-head', 'ed'] +['ĠK', 'ra'] +['ĠF', 'ONT'] +['`', '\\'] +['Class', 'NotFoundException'] +['.', 'avg'] +['atic', 'al'] +['A', 'j'] +['Ġpermit', 'ting'] +['Pro', 'j'] +['ERR', 'Q'] +['Ġcre', 'ampie'] +['ĠBuy', 'er'] +['-mod', 'ules'] +['ĠSund', 'ays'] +['|', '`Ċ'] +['Ġday', 'time'] +['Ġ+', '('] +['Ġgl', 'itch'] +['ĠOper', 'and'] +['Ġtox', 'ins'] +['iny', 'a'] +['D', 'NS'] +['ĠS', 'as'] +['C', 'ake'] +['ĠNation', 'als'] +['.add', 'To'] +['Ġs', 'inking'] +['Ġcompreh', 'ension'] +['Ġsc', 'or'] +['ag', 'ements'] +['Ġt', 'ard'] +['Ġmarch', 'ing'] +['ĠM', 'TV'] +['Ġs', 'ane'] +['Create', 'Info'] +['áº', '¯'] +['Ġend', 'Index'] +['ĉ', 'layout'] +['ĠåIJ', 'į'] +['S', 'ITE'] +['ĠT', 'HERE'] +['Ġ[', "{'"] +['opath', 'ic'] +['Ġtrans', 'mitter'] +['/', 'body'] +['Ġp', 'und'] +['ĠC', 'losing'] +['Ġset', 'attr'] +['Ġbound', 'ed'] +['At', 'las'] +['sum', 'ing'] +['(t', 'imes'] +['par', 'er'] +['yn', 'om'] +['fe', 'it'] +['Ġf', 'rem'] +['-', 'leg'] +['ĠBr', 'as'] +['>', '#'] +['Ġì¶', 'ľëł¥'] +['ĠIN', 'STANCE'] +['ĠC', 'ouch'] +['_host', 's'] +['lik', 'elihood'] +['.M', 'arker'] +['ĠM', 'asks'] +['Ġcere', 'al'] +['util', 'ities'] +['Ġelement', 'al'] +['Ġdist', 'orted'] +['in', 'active'] +['c', 'ry'] +['W', 'L'] +['UPPORT', 'ED'] +['.Th', 'rows'] +['/s', 'chema'] +['ser', 'ie'] +['."', "',"] +['ĠBened', 'ict'] +['-p', 'icker'] +['ig', 'gs'] +['ĠPir', 'ate'] +['åij¨', 'æľŁ'] +['ĠTh', 'ema'] +['ĠSouth', 'ampton'] +['Ġarray', 'With'] +['ĠPaul', 'a'] +['Ġpredict', 'or'] +['-', 'Ass'] +['.user', 'id'] +['Ġper', 'i'] +['Ġexagger', 'ated'] +['ur', 'ate'] +['arse', 'ille'] +['ĠCon', 'cent'] +['ĠP', 'ik'] +['Ġ@', '_;ĊĊ'] +['Ġform', 'ations'] +['Ġden', 'omin'] +['"/>', '.Ċ'] +['ended', 'or'] +['Ġpan', 'cre'] +['Ġam', 't'] +['Ġon', 'Resume'] +['on', 'Delete'] +['ĠB', 'CH'] +[')', '("'] +['m', 'ovement'] +['Ġpot', 'assium'] +['', 'čĊčĊ'] +['ĠMah', 'm'] +['}', '";ĊĊ'] +['Ġd', 'q'] +['ĠPublish', 'ers'] +['ĠAm', 'pl'] +['ĠDani', 'elle'] +['Ġt', 'ern'] +['èµ', '·'] +['no', 'ÅĽÄĩ'] +['e', 'in'] +['ĠAsync', 'Storage'] +['un', 'ger'] +['rou', 'w'] +['Ġsc', 'issors'] +['/', 'assert'] +['.b', 'ucket'] +['/', 'archive'] +['_M', 'an'] +['Ġint', 'oler'] +['Ġ()', '=>'] +['ĠÐĴ', 'Ñĭ'] +['Ġsa', 'i'] +['.x', 'y'] +['."', 'čĊ'] +['Ġur', 'inary'] +['es', 'ub'] +['IST', 'ICS'] +['ĠÎ', 'º'] +['Ġcompl', 'iments'] +['Ġtypings', 'Japgolly'] +['ih', 'ar'] +['Exp', 'ansion'] +['ĠS', 'erving'] +['_st', 'udents'] +['ĠX', 'BOOLE'] +['(', 'il'] +['Ġì²', 'ĺ'] +['Ġj', 'ó'] +['(t', 'ol'] +['(', 'JS'] +['ĉC', 'G'] +['ĠD', 'RAW'] +['tw', 'ig'] +['Ġo', 'at'] +['_sm', 'ooth'] +['ĠC', 'SL'] +['Ġos', 'ob'] +['Ġens', 'uing'] +['Ġbank', 'er'] +['ĠBack', 'pack'] +['_p', 'ing'] +['Ġwish', 'list'] +['=', 'ax'] +['ĉĠĠĠ', 'Ċ'] +['Dis', 'ney'] +['stead', 'y'] +['">', '%'] +['Ġproph', 'ets'] +['ĠZ', 'X'] +['Ġminimal', 'ist'] +['.PL', 'AIN'] +['Se', 'attle'] +['.', 'ordinal'] +['ĠPI', 'PE'] +['Ġret', 'orna'] +['Ġjug', 'ador'] +['ĠB', 'ret'] +['ĠâĶ', 'ľ'] +['Ġpl', 'ush'] +['UL', 'ATOR'] +['Sort', 'ing'] +['.grid', 'y'] +['ect', 'omy'] +['_', 'activ'] +['r', 'ack'] +['Inter', 'active'] +['ĠAntar', 'ctica'] +['Ġv', 'engeance'] +['en', 'so'] +['_k', 'nown'] +['up', 'plier'] +['.Mod', 'ules'] +['ĠConnection', 'State'] +['éļ', 'IJèĹı'] +['@', 'FindBy'] +['Ġpl', 'acer'] +['\\', 'model'] +['<', '()>'] +['.is', 'Successful'] +['-g', 'ood'] +['b', 'z'] +['ĠDr', 'aco'] +['Ass', 'istant'] +['-ex', 'tra'] +['аб', 'лиÑĨ'] +['Ġhyp', 'ocrisy'] +['Ġt', 'st'] +['ĠA', 'gr'] +['$', 'txt'] +['Ġlog', 'istic'] +['lic', 'ensed'] +['ĠH', 'of'] +['Ġt', 'at'] +['(', 'iv'] +['Ġinto', 'xic'] +['post', 'Id'] +['_st', 'rike'] +['Ġhum', 'iliation'] +['pc', 'odes'] +['"', 'sync'] +['(rec', 'ipe'] +['+', 'N'] +['rent', 'e'] +['ĉ', 'Client'] +['ycop', 'g'] +['ĠZur', 'ich'] +['ĠPro', 'files'] +['C', 'ountries'] +['Ġp', 'ict'] +['Ġroll', 'out'] +['requ', 'encies'] +['Ġpatch', 'ed'] +['Ġcar', 'tridges'] +['Ġsh', 'ading'] +['J', 'ar'] +['Ġsalv', 'age'] +['ĠTax', 'es'] +['Ġstand', 'by'] +['apor', 'an'] +['E', 'igen'] +['.', 'angular'] +['ĠN', 'ested'] +['äº', '«'] +['Ġis', 'Visible'] +['ĠDw', 'ight'] +['_BR', 'ANCH'] +['.D', 'elay'] +['Ġk', 'end'] +['Ġfacilit', 'ated'] +['.flat', 'Map'] +['Ġs', 'anta'] +['ĉS', 'end'] +['/m', 'essages'] +['Ġof', 'Type'] +['ĉs', 'wap'] +['#', 'plt'] +['ĠTur', 'ks'] +['N', 'ES'] +['Ġprogress', 'ively'] +['ĠRes', 'idence'] +['ĠT', 'REE'] +['Ġno', 'en'] +['d', 'io'] +['Ġn', 'elle'] +['Ġsog', 'ar'] +['itt', 'i'] +['week', 'ly'] +['Ġambigu', 'ity'] +['_Set', 'tings'] +['W', 'are'] +['.ne', 'o'] +['_D', 'ST'] +['Ġæĸ', '¹'] +['pre', 'p'] +['lob', 'by'] +['@', 'email'] +['/m', 'ovie'] +['Ġfun', 'kc'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'Ċ'] +['ÂŃ', 's'] +['Ġguard', 'ians'] +['-', 'pos'] +['Ġconfig', 'uring'] +['ĠC', 'PS'] +['ĠDe', 'us'] +['Ġvidé', 'os'] +['_', 'empresa'] +['Ġsl', 'apped'] +['<', 'Model'] +['Ġunders', 'cores'] +['U', 'h'] +['.access', 'Token'] +['SET', 'S'] +['ĠS', 'parse'] +['ĠCal', 'd'] +[':', 'path'] +['ĠS', 'ervers'] +['=', 'batch'] +['Ġkn', 'itting'] +['Ġx', 'a'] +['Ġsearch', 'Bar'] +['Ġsn', 'ag'] +['Ġinf', 'used'] +['.b', 'am'] +['le', 'ver'] +['Ġtax', 'onomy'] +['Ã', 'İ'] +['Ġatt', 'aching'] +['Ġh', 'ern'] +['_N', 'OP'] +['Click', 'able'] +['(P', 'arse'] +['ĠDynam', 'o'] +['-b', 'uilder'] +['Ġdere', 'g'] +['Ġsc', 'attering'] +['è¿Ľ', 'è¡Į'] +['an', 'zi'] +['ĠShe', 'pard'] +['">', "',Ċ"] +['_X', 'DECREF'] +['ĠBuzz', 'Feed'] +['_M', 'ARGIN'] +['P', 'LOY'] +['.sm', 'all'] +['Ġm', 'imeType'] +['Ġh', 'olog'] +['ĉc', 'amera'] +['li', 'as'] +['Ġsusp', 'ense'] +['ody', 'nam'] +['b', 'au'] +['Ġgrave', 'yard'] +['_n', 'amed'] +['":"', "'"] +['Ġ********************************', '****************'] +['Ġgame', 'Over'] +['ĠLENG', 'TH'] +['ĉs', 'creen'] +['Ġdo', 'InBackground'] +['_depend', 'encies'] +['Ġr', 'tc'] +['/', 'up'] +['_', 'ROM'] +['H', 'all'] +['Ġdef', 'iciencies'] +['(', 'te'] +["'", '#'] +['_e', 'quiv'] +['Ġpre', 'order'] +['ĠA', 'xe'] +['ом', 'Ñĥ'] +['.send', 'File'] +['Ġfil', 't'] +['ĠLim', 'its'] +['ĠCaval', 'iers'] +['.dis', 'count'] +['âĨ', 'IJ'] +['ĠW', 'it'] +['QRST', 'UV'] +['Ġi', 'j'] +['Ġt', 'egen'] +['Ġ:', '",'] +['diff', 'iculty'] +['p', 'unkt'] +['ĠEmail', 's'] +['ch', 'lor'] +['(f', 'un'] +['.U', 'int'] +['ĠSt', 'all'] +['_', 'verified'] +['u', 'D'] +['File', 'Type'] +['Ġple', 'asures'] +['Ġjud', 'iciary'] +['Ġsh', 'am'] +['ip', 'ur'] +['_PL', 'US'] +['off', 'ers'] +['(', 'foo'] +['_G', 'T'] +['ĉc', 'ore'] +['ENT', 'ION'] +['ĠLib', 'eration'] +['Command', 'Line'] +['_de', 'partment'] +['.A', 'r'] +['_ne', 'ighbor'] +['ĠSub', 'mitted'] +['ĠĊ'] +['Ġdro', 'its'] +['Ġhomosexual', 's'] +['Ġab', 'duction'] +['ĉw', 'idget'] +['$', 'headers'] +['ĠD', 'AR'] +['Ġfl', 'a'] +['th', 'reat'] +['Ġlou', 'is'] +['.Get', 'Property'] +['"', 'Just'] +['(f', 'rames'] +['ry', 'o'] +['prof', 'ession'] +['|', 'i'] +['íķ´', 'ìĦľ'] +['(s', 'v'] +['Ġun', 'recognized'] +['I', 'onic'] +['F', 'ashion'] +['Screen', 'State'] +['ĠIn', 'coming'] +['Not', 'Nil'] +['Ġsync', 'ing'] +['em', 'ie'] +['Ġtherm', 'o'] +['_pro', 'cs'] +['Ġincons', 'istency'] +['rel', 'igious'] +['.m', 'j'] +['Ġperson', 'n'] +['Ġmoment', 'os'] +['or', 'arily'] +['Ġæ', 'Ĭ'] +['_ne', 'urons'] +['Ill', 'ustr'] +['im', 'oto'] +['il', 'ik'] +['ĠW', 'oj'] +['Tr', 'ading'] +['Ġapp', 'are'] +['Ġentre', 'prises'] +['ach', 'at'] +['ĠÂ', '¬'] +['Ġne', 'igh'] +['BUTTON', 'DOWN'] +['ĠMah', 'er'] +['ag', 'han'] +['-h', 'ash'] +['"', 'f'] +['Ġclient', 'ele'] +['.add', 'Button'] +['ĉ', 'SP'] +['Q', 'i'] +['Ġgr', 'ated'] +['POS', 'ITE'] +[':', '>'] +['ĠHow', 'ell'] +['ĠCompar', 'ative'] +['ĠIS', 'C'] +['ÂŃ', 'i'] +['O', 'cean'] +['D', 'avis'] +['ĠFil', 'me'] +['W', 'ins'] +['ĠJ', 'IT'] +['oc', 'cer'] +['ĠC', 'orm'] +['ENCH', 'MARK'] +['rch', 'ive'] +['ica', 'ção'] +['Ġm', 'ata'] +['Ġchild', 'birth'] +['ĠOption', 'ally'] +['En', 's'] +['Ġx', 'http'] +['Ġel', 'ucid'] +['_Osc', 'InitStruct'] +['))', '):Ċ'] +['Ġint', 'uit'] +['ĠDon', 'ate'] +['Ġcorrel', 'ates'] +['>', 'Delete'] +['Ġequ', 'ipe'] +['Ġb', 'oca'] +['Ġinfl', 'atable'] +['er', 'ah'] +['ĠDateTime', 'Kind'] +['Ġcal', 'ves'] +['\\', 'Lib'] +['Ġem', 'lrt'] +['ĠTr', 'ilogy'] +['ĠP', 'anc'] +['ĠD', 'uis'] +['ĠpelÃŃcul', 'a'] +['WAR', 'DS'] +['_DE', 'TECT'] +['-section', 'al'] +['dh', 'cp'] +['For', 'Row'] +['-de', 'struct'] +['ĠPres', 'enter'] +['/s', 'lick'] +[',', 'on'] +['ĠCit', 'adel'] +['logged', 'in'] +['_sub', 'type'] +['Ġsig', 'ue'] +['Ġc', 'uring'] +['ĠFire', 'wall'] +['Ġfluores', 'cence'] +['ĠItal', 'ians'] +['иÑĤ', 'ÑģÑı'] +['.get', 'Style'] +['In', 'Seconds'] +['j', 'ie'] +['-S', 'mith'] +['Ġx', 'link'] +['Ġsub', 'missive'] +['он', 'ÑĤ'] +['arbon', 'ate'] +['ĠF', 'aul'] +['_go', 'als'] +['ĠCommission', 'ers'] +['chart', 'Instance'] +['_POST', 'FIELDS'] +['Ġmed', 'ial'] +['Ġman', 'os'] +['Ġdel', 't'] +['sv', 'm'] +['.Ap', 'is'] +['ep', 'hy'] +['Ġasym', 'pt'] +['Ġapp', 'Delegate'] +['Ġimpro', 'bable'] +['ck', 'a'] +['sim', 'd'] +['/', 'Error'] +['.', 'âĢĵ'] +['ĠP', 'TS'] +['de', 'er'] +['Ġs', 'ina'] +['m', 'agnitude'] +['ID', 'ADE'] +["']", "}'"] +['Ġmay', 'ores'] +['ĉ', 'comment'] +['/', 'console'] +['"', '@'] +['v', 'olt'] +['.s', 'ell'] +['ĠM', 'acy'] +['Ġmel', 'od'] +['Ġim', 'ágenes'] +['_ch', 'g'] +['Ġin', 'out'] +['ident', 'e'] +[')', "'),Ċ"] +['d', 'ni'] +['.b', 'lob'] +['Ġtyp', 'ography'] +['Ġe', 'erie'] +['_O', 'ID'] +['pes', 'an'] +['aj', 'an'] +['Ġch', 'opping'] +['Ġbl', 'uff'] +['ad', 'f'] +['_b', 'ases'] +['.Form', 'atter'] +['Ġ\\', '%'] +['ĠPage', 'Info'] +['Car', 'rier'] +['ĠCal', 'ibration'] +['com', 'o'] +['-b', 'odied'] +['Ġfinanc', 'ier'] +['ĠIN', 'A'] +['.', 'ERR'] +['Ġhood', 'ie'] +['ĠSan', 'ity'] +['gu', 'arded'] +['.opend', 'aylight'] +['ISM', 'ATCH'] +['High', 'lights'] +['ün', 'k'] +['ani', 'em'] +['anger', 'ed'] +['assign', 'ments'] +['Ġregistr', 'ado'] +['ĠU', 'PPER'] +['ampil', 'kan'] +['ash', 'ire'] +['ĠNik', 'ola'] +['ĠC', 'FL'] +['ĠH', 'DC'] +['Ġp', 'oids'] +['ĠIP', 's'] +['Ġprevent', 'ative'] +['ips', 'oid'] +['if', 'ix'] +['.c', 'amel'] +['.g', 'a'] +['V', 'olumes'] +['-', 'ste'] +['Y', 'ahoo'] +['_s', 'ibling'] +['H', 'ighest'] +['opt', 'group'] +['Ġkvin', 'na'] +['âĢĿ', 'ãĢĤĊĊ'] +['ĠAppl', 'iances'] +['Ġ"', '><'] +["')", '")Ċ'] +['ht', 't'] +['ĠIdent', 'ified'] +['Ġpenc', 'ils'] +['Ġmember', 'Id'] +['Ġappend', 'String'] +['.load', 'Data'] +['Ġmock', 'Mvc'] +['Ġj', 'ub'] +['ĠSl', 'ut'] +['ĠTai', 'pei'] +['st', 'att'] +['Pol', 'it'] +['Ġpart', 'ager'] +['Did', 'Change'] +['Incre', 'ases'] +[')', '}.'] +['ĠB', 'aba'] +['_CL', 'IP'] +['[', 'unit'] +['Ġк', 'лÑİÑĩ'] +['Ġalc', 'uni'] +['ĠL', 'ola'] +['Ġcl', 'inging'] +['@', 'PostMapping'] +['(con', 'cat'] +['Ġss', 'id'] +['ĠFa', 'uc'] +['ok', 'it'] +['ĠRecord', 'ed'] +['á', 'lez'] +['($', "('<"] +['.assertIs', 'Not'] +['Ġk', 'ali'] +['V', 'olt'] +['Ġwarm', 'ly'] +['Ġsca', 'res'] +['get', 'ti'] +['füh', 'rt'] +['_d', 'oes'] +['.', 'EMAIL'] +['im', 'ations'] +['Ġspring', 'fox'] +['ĠDec', 'om'] +['arc', 'y'] +['Ġgl', 'itches'] +['ĠM', 'off'] +['ĠV', 'oll'] +['.b', 'etween'] +['Ġcoord', 'en'] +['ĠPart', 'icularly'] +['GB', 'P'] +['Ġsem', 'ble'] +['East', 'ern'] +['_M', 'SB'] +['])', '{čĊ'] +['m', 'organ'] +['ĠE', 'VAL'] +['d', 'ere'] +['HO', 'USE'] +['mo', 'ire'] +['ist', 'ique'] +['_l', 'stm'] +['-com', 'mit'] +['yster', 'ious'] +['Ġtw', 'ink'] +['-th', 'umbnails'] +['en', 'ÃŃ'] +[":'", "',"] +['Ġblack', 'out'] +['ĠFlo', 'ors'] +['Ġso', 'fas'] +['Ġou', 'i'] +['lesh', 'oot'] +['ĠRa', 'q'] +['-', 'abs'] +['Ġk', 'ra'] +['M', 'ining'] +['sha', 'ft'] +['.set', 'Columns'] +['Cl', 'azz'] +['PRE', 'TTY'] +['.play', 'list'] +['éĸ', '¢'] +['-Sah', 'aran'] +['M', 'ING'] +['ĉ', 'bl'] +['è®', '®'] +['j', 'f'] +['DO', 'CKER'] +['hope', 'fully'] +['(', 'ignore'] +['ĠUsers', 'Controller'] +['ĠMitar', 'beiter'] +['ĠL', 'ES'] +['Ham', 'ilton'] +['-m', 'etadata'] +['ĠK', 'K'] +['ikt', 'ig'] +['Ġwoll', 'te'] +['egr', 'ator'] +[']', 'bool'] +[',', 'current'] +['Ġvalue', 'Type'] +['Ġexcav', 'ation'] +['ol', 'and'] +['Ġv', 'erv'] +['/file', 'path'] +['Auth', 'Provider'] +['Ġpro', 'crast'] +['ĉ', 'ULONG'] +['_MEM', 'BERS'] +['Ġup', 'lift'] +['ĠAut', 'onomous'] +['Ġart', 'works'] +['ĠOut', 'reach'] +['Ġp', 'ore'] +['Home', 'page'] +['Dialog', 'Title'] +['ĠGener', 'ating'] +['PAR', 'SE'] +['Ġsem', 'anas'] +['Ġhuman', 'o'] +['JSGlobal', 'Scope'] +['Ġvol', 'te'] +['Ġb', 'ella'] +['(is', 'instance'] +['Ġpl', 'c'] +['\\C', 'atalog'] +['Ġeste', 'emed'] +['éĽ', '·'] +['(s', 'uffix'] +['Ġswe', 'eps'] +['ĉ', 'ORDER'] +['Ġdo', 'ivent'] +['ĠSw', 'arm'] +['ĠComp', 'iled'] +['get', 'Page'] +['AD', 'R'] +['.R', 'ichTextBox'] +['ĠN', 'aming'] +['ag', 'ged'] +['ĠG', 'ANG'] +['r', 'asing'] +['ode', 'led'] +['Ġg', 'ala'] +['ĠJS', 'Name'] +['dd', 'f'] +['Ġill', 'ust'] +['ĠLans', 'ing'] +['[', 'port'] +['-de', 'ath'] +['Ġdin', 'heiro'] +['ĠE', 'ighth'] +['Ġb', 'ian'] +['st', 'Ã¥'] +['Ġvers', 'ión'] +['ĠLinear', 'Gradient'] +['ĠHard', 'ing'] +['.', '*)'] +['ec', 'zy'] +['$', 'header'] +['Ġv', 'Ã¥r'] +['Un', 'checked'] +['Ġko', 'je'] +['ĠPal', 'adin'] +['()', ')),'] +['G', 'iving'] +['()', '})Ċ'] +['Ġd', 'ips'] +['F', 'riendly'] +['Ġport', 'rays'] +['Ġhel', 'ium'] +['Ġinsurg', 'ency'] +['_ex', 'piry'] +['ĠstringByAppending', 'String'] +['Ġa', 'antal'] +['s', 'lope'] +['m', 'ast'] +['.get', 'Integer'] +['Ġ################', '########'] +['_PIPE', 'LINE'] +['Ġdens', 'ely'] +['Ġmut', 'ating'] +['m', 'idi'] +['ĠSe', 'it'] +['ay', 'ne'] +['NOW', 'LED'] +['ĠDes', 'mond'] +['ĠF', 'Name'] +['ĠN', 'airobi'] +['\\', 'Context'] +['Ġcalc', 'ular'] +['-d', 'en'] +['Ġc', 'ott'] +[']', '):čĊ'] +['ĠRecommend', 'ation'] +['ĠRole', 'x'] +['Ġvalidation', 'Result'] +['.p', 'at'] +['Ġn', 'Ãły'] +['ĠRest', 'Client'] +['ĠG', 'PI'] +['ĠAshe', 'ville'] +['ĠO', 'SP'] +['ĠPER', 'MISSION'] +['ÐĶ', 'аÑĤа'] +['/', 'notification'] +['K', 'night'] +['_W', 'ord'] +['ĠB', 'ender'] +['rank', 'ing'] +['Ġpart', 'ida'] +['_res', 'ervation'] +['Ì', 'Ģ'] +['Ġm', 'Name'] +['Ġget', 'ch'] +['Ġb', 'orr'] +['Ġdilig', 'ent'] +['Disc', 'uss'] +['æŃ£', 'åľ¨'] +['ape', 'ake'] +['ion', 'ed'] +['-N', 'azi'] +['.c', 'um'] +['ĠK', 'ron'] +['=$', "('#"] +['/s', 'ingle'] +['Ġerot', 'isch'] +['ĠV', 'ib'] +['Ġrat', 'ified'] +['Ġconcert', 'ed'] +['ĠREG', 'ARD'] +['Ġdo', 'br'] +['.Driver', 'Manager'] +["'", 'r'] +['Port', 'able'] +['ĉs', 'uite'] +['Ġrel', 'aciones'] +['ĠD', 'op'] +['emplo', 'i'] +['DO', 'B'] +['Ġcr', 'umbs'] +['Ġx', 'ls'] +['_App', 'lication'] +["(':", "',"] +['Ġ----------------------------------------------------------------', '--------Ċ'] +['m', 'se'] +['Ġber', 'k'] +['ĠReturn', 'Value'] +['ĠBel', 'ly'] +['Ġcam', 'ar'] +['ĠPe', 'ek'] +['els', 'ing'] +['Ġnot', 'ifies'] +['ĠTr', 'istan'] +['ĠG', 'AR'] +['em', 'me'] +['ĠElev', 'ated'] +['_C', 'SV'] +['(ch', 'alk'] +['Ġtw', 'enties'] +['ĠSearch', 'Result'] +['=', 'search'] +['ĠMix', 'ing'] +['ý', 't'] +['Ġrecru', 'iter'] +['ĠIDE', 'OGRAPH'] +['ĠA', 'go'] +['(', 'Operation'] +['$', 'values'] +['Ġworld', 'ly'] +['ĠRosen', 'berg'] +['ĠConfigure', 'Services'] +['>*', 'Ċ'] +['Ġsn', 'ork'] +['_op', 'acity'] +['ĠinitWith', 'NibName'] +['i', 'ado'] +['A', 'AC'] +['Ġ]', ').'] +[';', 'z'] +['_par', 'agraph'] +['Ġnos', 'es'] +['stand', 's'] +['if', 'r'] +['_m', 'E'] +['I', 'raq'] +['.P', 'redicate'] +['ena', 'ire'] +[']]', '];Ċ'] +['Ġun', 'idad'] +['Ġretire', 'es'] +['_h', 'ello'] +['Ġmode', 'le'] +['ĠUIT', 'ableViewController'] +['f', 'write'] +['_num', 'ero'] +['_vis', 'ited'] +['Ġrece', 'be'] +['(', 'Notification'] +['Fant', 'astic'] +['_sub', 'menu'] +['ĠP', 'EM'] +['ĠCup', 'ertino'] +['approx', 'imately'] +['class', 'ed'] +['.Read', 'String'] +['Ġdomic', 'ile'] +['_P', 'W'] +['Ġball', 'park'] +['ĠK', 'ale'] +['con', 'tra'] +['_f', 'avorite'] +['/', 'of'] +['Qu', 'ite'] +['ĠOT', 'A'] +['Ġacceler', 'ometer'] +['did', 'n'] +['|', '^'] +['ĠRohing', 'ya'] +['ivic', 'rm'] +['ann', 'abin'] +['обÑĭ', 'ÑĤи'] +['or', 'ado'] +["')", '+'] +['Ha', 'unted'] +[',', 'ID'] +['(', 'UIAlertAction'] +['ur', 'v'] +['_b', 'el'] +['ĠMex', 'icans'] +['/', 'terms'] +['ĠPaint', 'er'] +['Input', 'Label'] +['ĠV', 'inci'] +['ĠRos', 'ie'] +['\\', 'uc'] +['<', 'Menu'] +['Ġcool', 'ant'] +['(current', 'User'] +['_d', 'ual'] +[')', '"},Ċ'] +['&', 'p'] +['Ġconver', 'ged'] +['Ġrestr', 'ain'] +['ĠYugosl', 'avia'] +['=', 'target'] +['Ġimp', 'uls'] +['ds', 'a'] +['Search', 'Tree'] +['Ġh', 'box'] +['ĠImp', 'ress'] +['§', 'Ãĥ'] +['get', 'FullYear'] +['(d', 'a'] +['ĠY', 'YS'] +['.al', 'ignment'] +['.Get', 'Text'] +['.token', 'ize'] +['ĠOlymp', 'us'] +['Ġmur', 'ky'] +['ore', 'station'] +['Ġdiss', 'atisfaction'] +['ĉT', 'Array'] +['_', 'kses'] +['.Add', 'Singleton'] +['ĠStart', 'Time'] +['Ġfan', 'atic'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĉ'] +['Ġentity', 'Type'] +['.', 'override'] +['Ġ', '-------------'] +['ĠDat', 'agram'] +['f', 'out'] +['(with', 'Id'] +['Ġ#', '__'] +['Ł', 'èĥ½'] +['ek', 'yll'] +['.f', 'riends'] +['ame', 'leon'] +['Ġz', 'ach'] +['.simple', 'Button'] +['ret', 'orno'] +['Ġkon', 'k'] +['/s', 'mall'] +['ĠQuick', 'ly'] +['un', 'read'] +['Don', 'ate'] +['Detail', 'View'] +['Ġdu', 'a'] +['Ġpenetr', 'ated'] +['OM', 'UX'] +['Ġn', 'ir'] +['_p', 'data'] +['"],', '["'] +['Ġlow', 'es'] +['Ġdop', 'ing'] +['Ġas', 'ymmetric'] +['Ġneed', 'less'] +['our', 'cem'] +['Ġup', 'ro'] +['ĠGu', 'zzle'] +['af', 'b'] +['Ġsext', 'reffen'] +['-c', 'ollar'] +['Ġcol', 'ossal'] +['Mon', 'key'] +['n', 'ish'] +['Ġhandle', 'Message'] +['Incre', 'ased'] +['*', 'dx'] +['ĠChatt', 'anooga'] +['f', 'org'] +['ĠOr', 'den'] +['Ġsh', 'ri'] +['ĠV', 'and'] +['Ġ"', '@"'] +['Image', 'Sharp'] +['ĠWild', 'cats'] +['pon', 'ible'] +['.sc', 'enes'] +['Ġpaint', 'ers'] +['ĠPf', 'izer'] +['ĠZ', 'ah'] +['To', 'Local'] +['ĠFl', 'am'] +['Ġé', 'taient'] +['))', '^'] +['ĠSand', 'box'] +['ĠTR', 'ADE'] +['Ġchrom', 'ium'] +['Ġac', 'claim'] +['Ġpac', 'man'] +['´', 't'] +[')', 'reader'] +['M', 'ari'] +['.Dispatch', 'er'] +['.A', 'DMIN'] +['ĠRem', 'ed'] +['Sw', 'eden'] +['Ġoverl', 'ays'] +['.', 'er'] +['Ġp', 'ang'] +['Ġclean', 'ly'] +['aven', 'port'] +['Toy', 'ota'] +['patch', 'es'] +['Ġv', 'tx'] +['ĠE', 'is'] +['cl', 'ado'] +['ĠR', 'itch'] +['RO', 'LS'] +['Ġh', 'ade'] +['Ġconspic', 'uous'] +['Ġdo', 'cks'] +['(j', 'q'] +['ĠPrem', 'iership'] +['ĠBe', 'z'] +['ĠâĦ', 'ĸ'] +['ĠÑĥ', 'Ñģл'] +['_tot', 'als'] +['Ġprov', 'a'] +['ĠC', 'ue'] +['Ġsa', 'úde'] +['ĠGame', 'Controller'] +['IM', 'IZE'] +[',', 'port'] +['ãĢĤ', '('] +['.C', 'decl'] +['Instant', 'iationException'] +['Ġcoll', 'age'] +['ĠIO', 'C'] +['Ġb', 'ais'] +['Ġon', 'Finish'] +['-st', 'ars'] +['set', 'Size'] +['Ġmog', 'ul'] +['Ġdis', 'illusion'] +['Ġche', 'vy'] +['(S', 'chedulers'] +['(', 'IR'] +['_loc', 's'] +['Ġcann', 'ons'] +['Ġcancell', 'ing'] +['/b', 'us'] +['Ġbuf', 'io'] +['ĠY', 'ours'] +['ĠPik', 'achu'] +['Ġter', 'me'] +['r', 'Ã¥'] +['f', 'ahren'] +['Ġowner', 'Id'] +['Ġoblig', 'atory'] +['Ġcul', 'p'] +['Ġacid', 'ity'] +['-m', 'ult'] +['ĠBam', 'boo'] +["Ġ'", '">'] +['_g', 's'] +['Ġcomp', 'il'] +['n', 'ard'] +['-ex', 'c'] +['Ġrh', 'yme'] +['Ġbut', 'to'] +['s', 'ays'] +['ant', 'asy'] +['ë', '¸'] +['Ġcitt', 'Ãł'] +['Ġche', 'g'] +['Time', 'String'] +['Ġpos', 'itivity'] +['ĠD', 'abei'] +['Ġw', 'ang'] +['Ġes', 'cre'] +['"', 'c'] +['ĉv', 'ideo'] +['ĠRank', 'ed'] +['.str', 'ings'] +['>>', '>('] +['Ġин', 'ÑĤеÑĢ'] +['Ġrest', 'a'] +['[:', ',:'] +['Ġrend', 're'] +['Ġdes', 'er'] +['J', 'os'] +['Ġdis', 'ruptions'] +['Ġоп', 'еÑĢ'] +['s', 'ampling'] +['sup', 'press'] +['Ġcontainer', 'View'] +['ĠSeam', 'less'] +['Ġair', 'y'] +['Ġon', 'load'] +['.Window', 'Manager'] +['ĠPL', 'A'] +['br', 'aco'] +['.set', 'PositiveButton'] +['Ġp', 'du'] +['Ġg', 'si'] +['ĠC', 'li'] +['_gr', 'adients'] +['Ñı', 'д'] +['ĠWh', 'isper'] +['c', 'stdint'] +['Ġl', 'äng'] +['Ġform', 'ulations'] +['én', 'om'] +['ourn', 'emouth'] +['[$', '_'] +['Ġordin', 'arily'] +['.set', 'Username'] +['Ġfacult', 'ies'] +['MIT', 'TED'] +['/', 'values'] +['Ġwe', 'ir'] +['ĠA', 'pt'] +['M', 'Z'] +['ĉc', 'f'] +['uck', 'en'] +['ĉĉĉĉĉĉĉĉ', 'ĉĉĉĉĉĉĉĉĉĉĉĉ'] +['def', 'ense'] +['[i', 'Var'] +['ĠBusiness', 'Exception'] +['Select', 'ors'] +['(co', 'ordinates'] +['ĠRes', 'ets'] +['ĠDr', 'inks'] +['ole', 'ans'] +['(st', 'ypy'] +['_IO', 'C'] +['.x', 'xx'] +['ĠSl', 'ater'] +['ĠBel', 'ize'] +['Ġ/', '************************************************************************'] +['add', 'in'] +['_ep', 'isodes'] +['Ġis', 'chem'] +['legal', 'ArgumentException'] +['D', 'anny'] +['Ġp', 'ared'] +['.code', 'haus'] +['ĠAss', 'y'] +['ĉ', 'Rect'] +['â', 'ŀ'] +['.list', 'a'] +['Ġв', 'аÑĪ'] +['Ġv', 'ets'] +['HW', 'ND'] +['ison', 'er'] +['Ġx', 'o'] +['Ġor', 'ally'] +['ĠSt', 'mt'] +['.r', 'nn'] +['ĠD', 'PI'] +['ĠStr', 'ikes'] +['.setViewport', 'View'] +['Ġèĩª', 'åĬ¨çĶŁæĪIJ'] +['Y', 'ELLOW'] +['GL', 'enum'] +['part', 'ners'] +['ĠImp', 'licit'] +['Ġtak', 'o'] +['âĢĻ', 'elle'] +['Ġerm', 'ög'] +['total', 'Count'] +['G', 'il'] +['ĉ', 'work'] +['Ġpr', 'atic'] +['in', 'ati'] +['ab', 'ies'] +['ĠSk', 'inner'] +['Ġspir', 'ited'] +['Ġpancre', 'atic'] +['Ġh', 'df'] +["'", 'em'] +['Ġpsych', 'osis'] +['olic', 'it'] +['Ġ"', '{"'] +['_at', 'ual'] +['Ġé', 'lect'] +['TE', 'AM'] +['Ġd', 'ak'] +['ĠSW', 'AT'] +['.Fragment', 'Manager'] +['Ġprovision', 'ing'] +['l', 'ifetime'] +['_EXTENSION', 'S'] +['ĠC', 'ASCADE'] +['Ġ!', '['] +['(K', 'P'] +['Ġv', 'em'] +['ĠInterr', 'acial'] +["']", '},Ċ'] +['sp', 'acer'] +['_k', 'v'] +['W', 'arehouse'] +['R', 'DD'] +['_f', 'sm'] +['.Stretch', 'Image'] +[',', 'Yes'] +['ĠRefuge', 'e'] +['ĠBr', 'inging'] +['Ġv', 'álido'] +['.inter', 'section'] +['Ġsp', 'ooky'] +['_port', 'al'] +['Ġmo', 'th'] +['ĠZ', 'odiac'] +['ĠSOC', 'IAL'] +['M', 'imeType'] +["']", '}}'] +['_Bl', 'ue'] +['Ġbot', 'anical'] +['Ġfr', 'ags'] +['Ġfamil', 'ial'] +['-', 'du'] +['Ġse', 'izing'] +['(block', 's'] +['.r', 'd'] +['.check', 'NotNull'] +['Ġmis', 'er'] +['Ġmax', 'x'] +['ĠK', 'nee'] +['View', 'Item'] +['Inner', 'HTML'] +['D', 'anger'] +['((', '__'] +['Ġprz', 'ypad'] +['create', 'Url'] +['**', ','] +['ĠDecor', 'ating'] +['ATEG', 'Y'] +['?>', '/'] +['.Design', 'er'] +['hex', 'digest'] +['ĠEvery', 'where'] +['all', 'eries'] +['.TEXT', 'URE'] +['.Block', 's'] +['z', 'ell'] +['Ġpre', 'ço'] +['S', 'uddenly'] +['input', 'Email'] +['(s', 'ync'] +['.b', 'd'] +['gold', 'en'] +['>', "');"] +['ĠDick', 'inson'] +['>>', '(Ċ'] +['ĠQUE', 'UE'] +['Ġget', 'Column'] +['ĠS', 'AND'] +['.p', 'iece'] +['lic', 'er'] +['Fl', 'utter'] +['Ġget', 'Version'] +['Ġresource', 'Id'] +['og', 'l'] +['ÅĤ', 'aw'] +['.Br', 'anch'] +['ĉ', 'web'] +['Ġfr', 'amerate'] +['PP', 'P'] +['Ġfr', 'ay'] +['C', 'NT'] +['Ġinformat', 'ie'] +["']", 'čĊčĊ'] +['ne', 'as'] +['Header', 'Code'] +['Ġæ', '¸'] +['Ġtr', 'g'] +['raw', 'types'] +['H', 'onda'] +['Ġmark', 'eter'] +['Ġrequest', 'Data'] +['ĠP', 'g'] +['ĉ', 'not'] +['Ġpage', 'Info'] +['Ġakt', 'uellen'] +['ãģķ', 'ãĤĵ'] +['ĠA', 'MS'] +['push', 'ViewController'] +['ĉ', 'AL'] +['Ġv', 'ests'] +['produ', 'ce'] +['-m', 'ême'] +['ĠRah', 'man'] +['F', 'unny'] +['E', 'Z'] +['_', 'Valid'] +['Ġsquad', 'ron'] +['Ġl', 'ash'] +['Ġ', 'irm'] +['ias', 'co'] +['ĠPar', 'an'] +['Ġpet', 'ites'] +['ĠDec', 'ay'] +['Ġun', 'initialized'] +['priv', 'ileged'] +['Ġm', 'bedtls'] +['å¤ĩ', '注'] +['Ġ^', '.'] +['Ġec', 'static'] +['D', 'etroit'] +['Ġpart', 'en'] +['Ġsou', 'venir'] +['.get', 'Login'] +['моÑĤ', 'ÑĢ'] +['en', 'ção'] +['ĠmÃŃn', 'imo'] +['ĠAccess', 'ed'] +['ri', 'ó'] +['M', 'ic'] +['ĠV', 'ocal'] +['.Set', 'String'] +['Ġmens', 'ajes'] +['åĢ', 'į'] +['Ġattr', 'avers'] +['ĠA', 'ph'] +["Ġ'", ');čĊ'] +['ünd', 'e'] +['Ġench', 'anted'] +['ĠRoot', 'State'] +['ĠCLOSE', 'D'] +['ĉĉĉĉĉĉĉĉ', 'čĊ'] +['Ġcal', 'iente'] +['or', 'ris'] +['Ġphysic', 'ists'] +['h', 'wnd'] +['_v', 'i'] +['Ġráp', 'ido'] +['Ġcapital', 'ized'] +['ed', 'By'] +['Ġmach', 'ining'] +['Ġhub', 'by'] +['ĠSt', 'acy'] +['.B', 'us'] +['dr', 'ink'] +['H', 'ur'] +['Ġprop', 'ia'] +['Unit', 'Test'] +['Ġmiscon', 'ception'] +['__', '));Ċ'] +['/d', 'c'] +['ĠMay', 'weather'] +['_m', 'C'] +['.create', 'From'] +['ĠQ', 'Painter'] +['rops', 'ych'] +['inn', 'itus'] +['ay', 'as'] +['Ġg', 'eg'] +['(d', 'w'] +['Ġus', 'ado'] +['Ġtrick', 'le'] +['Ġann', 'ihil'] +['ĠP', 'asta'] +['Ġ++', 'Ċ'] +['(Expected', 'Conditions'] +['.post', 'Value'] +['ic', 'ap'] +['ĠDon', 'etsk'] +['_s', 'oup'] +['-p', 'ublish'] +['ĠP', 'b'] +['ment', 'ions'] +['AC', 'CEPT'] +['.P', 'ull'] +[',âĢĻ', 'âĢĻ'] +['Ġret', 'arded'] +['_AT', 'OM'] +['ĠTermin', 'ator'] +['-c', 'ourt'] +['ĠCLLocation', 'Coordinate'] +['Ġrever', 'ence'] +['ĠS', 'SC'] +['ut', 'ely'] +['ĠW', 'ON'] +['ĠG', 'SL'] +['fre', 'i'] +['.get', 'Longitude'] +['Ġopen', 'FileDialog'] +['.B', 'utter'] +['-', 'important'] +['_M', 'ANY'] +['ĠG', 'ong'] +['âĢľ', 'How'] +['Ġg', 'orge'] +['=', 'msg'] +['ĠEz', 'ek'] +['create', 'Command'] +[':', 'checked'] +['Ġinf', 'ographic'] +['.W', 'EST'] +['Dir', 's'] +['Ġguard', 'a'] +['Ġbeet', 'le'] +['<', 'small'] +['-', 'android'] +['Ġcred', 'itor'] +['ĠM', 'éd'] +['Ġfinal', 'ist'] +['Ġab', 'l'] +['ne', 'v'] +['_inter', 'action'] +['ĠMonter', 'ey'] +['j', 'ah'] +['Ġcand', 'ies'] +['ĠQu', 'incy'] +['èª', 'Ń'] +['Ġbatch', 'Size'] +['ak', 'it'] +['Ġo', 'be'] +['(p', 'ara'] +['Ġexperiment', 'ed'] +['Ġcouncill', 'ors'] +['Ġcl', 'ashed'] +['s', 'qu'] +['-st', 'rokes'] +['ĠG', 'K'] +['ĠEx', 'pires'] +['Ġprosec', 'utions'] +['ĠCreat', 'ures'] +['Ġy', 'ö'] +['x', 'lim'] +['_IM', 'P'] +['Entry', 'Point'] +['ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ', 'ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ'] +['.Default', 'CellStyle'] +['Ġbre', 've'] +['ĠBrit', 'ann'] +['Ġsweat', 'y'] +['Ġle', 'th'] +['Ġflash', 'back'] +['per', 'manent'] +['ĠJ', 'DK'] +['_D', 'etails'] +['E', 'uro'] +['p', 'pt'] +['Ġrich', 'TextBox'] +['/', 'board'] +['Ġtr', 'ance'] +['.c', 'ycle'] +["');", '");Ċ'] +['Ġtox', 'in'] +['_de', 'init'] +['Ġover', 'arching'] +['Ġconfig', 'parser'] +['ĠKaw', 'asaki'] +['.th', 'umb'] +['Ġplay', 'a'] +['ĠJose', 'f'] +['+', '_'] +['Ġzero', 'es'] +['Ġa', 'up'] +['ĠH', 'ari'] +['comm', 'itted'] +['N', 'it'] +['.file', 'Path'] +['ĠDis', 'abilities'] +['man', 'ufact'] +['-al', 'igned'] +['.RE', 'SET'] +['Ġrust', 'y'] +['E', 'y'] +['Ġou', 'sted'] +['cos', 'a'] +['Struct', 'ured'] +['.get', 'D'] +['Ġs', 'ábado'] +['>', 'Loading'] +['_m', 'A'] +['.get', 'Random'] +['bl', 'ings'] +['Ġchees', 'es'] +['tt', 'i'] +['.', 'âĢ¢'] +['ĠBurg', 'ess'] +['ender', 'it'] +['.', "',čĊ"] +['("', '"+'] +['ac', 'b'] +['%', 'p'] +['index', 'ed'] +['_pred', 'icate'] +['nes', 'ia'] +['Ġb', 'ied'] +['ĠC', 'IT'] +['(', 'Pos'] +['_r', 'adi'] +['ä»·', 'æł¼'] +['B', 'iz'] +['ĠAdoles', 'cent'] +['Ġvi', 'ên'] +['c', 'ycl'] +['_C', 'ancel'] +['Ġcon', 'clusive'] +['Ġappell', 'ate'] +['inform', 'atics'] +['S', 'J'] +['Ġelect', 'ive'] +['role', 'Id'] +['Fetch', 'er'] +['ĉ', 'Command'] +['("', '(%'] +['Ġf', 'art'] +['IL', 'A'] +['get', 'Block'] +['A', 'USE'] +['Ġд', 'ан'] +['ĠAr', 'te'] +['Ġnot', 'ifying'] +['Ġge', 'le'] +['.s', 'ame'] +['ĠReg', 'el'] +['ĠBa', 'ÅŁ'] +['.c', 'reation'] +['ĠV', 'N'] +['_comm', 'unity'] +['Ġuns', 'ustainable'] +['SE', 'X'] +['Ġgrid', 'Size'] +['res', 'cia'] +['avers', 'able'] +["(',", "')["] +['ĠPh', 'elps'] +['á»ķ', 'i'] +['ANCE', 'LED'] +['-', 'IS'] +['.run', 'ners'] +['ĠSt', 'okes'] +['.P', 'rodu'] +['Ġwh', 'ipping'] +['_ac', 'quire'] +['Ġinvestig', 'ación'] +['f', 'ried'] +['.copy', 'With'] +['ĠHard', 'cover'] +['-', 'Se'] +['áŀ¶', 'áŀ'] +['inv', 'itation'] +['les', 'ai'] +['ĠD', 'orm'] +['ĠÑģпиÑģ', 'ка'] +['Ġconcaten', 'ated'] +['oph', 'il'] +['Ġthink', 'er'] +['/font', 'awesome'] +['ĠLe', 'opard'] +['Ġ"/', '");Ċ'] +['Ġresidual', 's'] +['ĠMic', 'rowave'] +['Ġconform', 'e'] +['th', 'rop'] +['Ġdis', 'emb'] +['ĠO', 'MG'] +['ĠDisc', 'ipline'] +['ĠAc', 'robat'] +['/re', 'pository'] +['df', 'a'] +['_M', 'ED'] +['buf', 'io'] +['Ġméth', 'ode'] +['_H', 'OLD'] +['ias', 'i'] +['_', 'legacy'] +[')', 'ččĊ'] +['æ£', 'Ģ'] +['Get', 'ProcAddress'] +['Ġy', 'ay'] +['ot', 'ence'] +['order', 'id'] +['-t', 'w'] +['Ġdear', 'ly'] +['In', 'coming'] +['/', 'il'] +['Ġneu', 'rop'] +['uc', 'z'] +[');', 'čččĊ'] +['ĠInnov', 'ative'] +['Ġprof', 'und'] +['ig', 'mat'] +['Selection', 'Mode'] +['re', 'levant'] +['.G', 'O'] +['Ġbru', 'ises'] +['Ġs', 'ach'] +['ode', 'f'] +['Ġre', 'imb'] +['/d', 'esktop'] +['-s', 'pot'] +['und', 'ance'] +['Ent', 'ropy'] +['\\', 'core'] +['Ġsug', 'er'] +['ĠM', 'vc'] +['ĠGN', 'OME'] +['_ind', 'x'] +['ĠYY', 'STYPE'] +['ĠMat', 'lab'] +['ĠC', 'IF'] +['Ġ*', '))'] +['Ġproduct', 'List'] +['ĠAl', 'right'] +['ac', 'emark'] +['ÑĤи', 'в'] +['mod', 'ification'] +['int', 'ernational'] +['Ġhom', 'ers'] +['Ġdict', 's'] +['ĠQ', 'Font'] +['.SQL', 'ite'] +['Ġtransplant', 'ation'] +['ĠMessageBox', 'Button'] +['ĠEl', 'ves'] +["']", '])Ċ'] +['(Q', 'Icon'] +['Ġcin', 'emas'] +['CO', 'ORD'] +['-', 'China'] +['Ġkh', 'ẩu'] +['æĪij', 'çļĦ'] +['Ġskull', 's'] +['Ġpain', 'staking'] +['f', 'ce'] +['.XR', 'Label'] +['Ġspec', 'ifier'] +['Ġpref', 'erring'] +['/', 'activity'] +['(', 'Photo'] +['á', 'lt'] +['.l', 'ot'] +["'", "'."] +['ann', 'once'] +['.google', 'code'] +['-p', 'df'] +['ĠP', 'oke'] +['_A', 'CL'] +['Ġend', 'owed'] +['dis', 'cover'] +['.om', 'g'] +['Ġwood', 'land'] +['.M', 'agic'] +['Ġvol', 'ont'] +['Not', 'Allowed'] +['Ġch', 'ave'] +['BM', 'W'] +["','", "=',"] +['ĠS', 'IX'] +['æĪij', '们'] +['Ġkos', 'her'] +['Ġaspir', 'ation'] +['int', 'l'] +['_ref', 'ptr'] +["'+", 'Ċ'] +['ment', 'or'] +['.cl', 'ub'] +['Window', 'State'] +['.A', 'RR'] +['Ġz', 'za'] +['Ġmessage', 'Type'] +['.e', 'qu'] +['Th', 'or'] +['Ġin', 'just'] +['Ġg', 'ums'] +['Ġborder', 'Side'] +['////', '/'] +['ĠTrans', 'mit'] +['Ġbuf', 'size'] +['Ġh', 'ak'] +['Ġell', 'as'] +['R', 'ANDOM'] +['ĉm', 'c'] +['Ġpe', 'a'] +['ek', 'o'] +['document', 'o'] +['Ġhyster', 'ia'] +['Ġaren', 'as'] +['Ġgun', 'men'] +['Ġm', 'ike'] +['Ġimp', 'unity'] +['atis', 'ation'] +['_Z', 'ero'] +['_COMP', 'ANY'] +['ĠG', 'ors'] +['Ġuse', 'Class'] +['(', 'redis'] +['ĠRUN', 'NING'] +['ĠB', 'air'] +['vel', 'te'] +["Ġ','", '.'] +['аÑĤÑĮ', 'ÑģÑı'] +['ö', 'st'] +['encode', 'URIComponent'] +['_re', 'strict'] +['Ġdec', 'als'] +['ĠPed', 'ido'] +['Ġalter', 'cation'] +['Dis', 'plays'] +['ĠApp', 'licants'] +['C', 'US'] +['Text', 'area'] +['ĠAng', 'ola'] +['.f', 'uture'] +['ĠUS', 'HORT'] +['Ġsuppress', 'ing'] +['Ġset', 'zen'] +['AP', 'olynomial'] +['Ġto', 'ch'] +['Ġhall', 'mark'] +['Ġ$', '$$'] +['ĠCHAR', 'SET'] +['.r', 'pm'] +['ĠD', 'ich'] +['----------------', '----'] +['_p', 'arm'] +['è¿', 'ĺ'] +['acc', 'iones'] +['h', 'ait'] +['WAR', 'DED'] +['_r', 'outing'] +['ĠN', 'OM'] +['Ġen', 'clave'] +['ĠLot', 'to'] +['ĉf', 'r'] +['complex', 'Content'] +['ĠBall', 'ard'] +['k', 'ube'] +['/w', 'in'] +['.getColumn', 'Model'] +['_RE', 'PLACE'] +['Header', 'Value'] +['Ġest', 'udiantes'] +['Ġap', 'is'] +['Ġb', 'pm'] +['ĠType', 'Name'] +['And', 'Get'] +['rit', 'a'] +['Pl', 'ans'] +['>', 'Note'] +['Ġfet', 'isch'] +['Ġton', 'ed'] +['_g', 'oto'] +['ons', 'ense'] +['Ġm', 'olds'] +['Ġinfiltr', 'ation'] +['ĠGuerr', 'ero'] +['ub', 'bo'] +['ck', 'i'] +['($', '(".'] +['_', 'activities'] +['(ch', 'anges'] +['Ġof', 'App'] +['ĠKe', 'pler'] +['ĠD', 'emp'] +['ĠCont', 'inent'] +['.T', 'icks'] +['ĠUn', 'signed'] +['ĠJah', 'res'] +['Ġfresh', 'men'] +['ĠArch', 'ived'] +['ĠкоÑĤоÑĢ', 'Ñĭй'] +["Ġ'", '::'] +['T', 'utorial'] +['C', 'c'] +['Ġtable', 'LayoutPanel'] +['from', 'Json'] +['.level', 's'] +['_trans', 'ient'] +['Ġendors', 'ing'] +['ĠD', 'IC'] +['la', 'uf'] +['Ġsh', 'red'] +['_E', 'MIT'] +['ific', 'antly'] +['AL', 'A'] +['/', 'proto'] +['Ġnarrow', 'ing'] +['U', 'tc'] +['Fact', 'ors'] +['Ġsent', 'ient'] +['æŀ', 'IJ'] +['lix', 'ir'] +['ĠC', 'ROSS'] +['met', 'eor'] +['Ġgro', 'in'] +['Ġm', 'db'] +['ĠRot', 'terdam'] +['Ġcom', 'ida'] +['ĠOp', 'Code'] +['ĠDefault', 'Value'] +['Permissions', 'Result'] +['Ġheter', 'ogeneous'] +['Ġm', 'oot'] +['Ġde', 'ceived'] +['-in', 'dependent'] +['ĠObject', 'OutputStream'] +['Ġover', 'power'] +['.d', 'up'] +['Ġl', 'db'] +['Ġdomest', 'ically'] +['Ġbest', 'ellen'] +['Ġlo', 'v'] +['ĠContract', 'ors'] +['Tri', 'angles'] +['Ġfod', 'der'] +['Ġfilm', 'es'] +['ä¼', 'ģ'] +['Ġrev', 'olver'] +['Startup', 'Script'] +['/', 'validation'] +['ĠResource', 'Type'] +['i', 'ÅŁ'] +['ĠL', 'az'] +['f', 'ef'] +['Ġlst', 'm'] +['{', '*'] +['.', 'attachment'] +['.h', 'its'] +['ew', 'ith'] +['DO', 'G'] +['Al', 'abama'] +['Ġmedium', 's'] +['.m', 'Context'] +['-c', 'ols'] +['åı', 'ĭ'] +['.not', 'ice'] +['Ġat', 'tn'] +['ĠP', 'acking'] +['ĠL', 'n'] +['_COM', 'PLEX'] +['/', 'Users'] +['.sav', 'etxt'] +['ĠR', 'ounds'] +['?,?,', '?,?,'] +['Ġing', 'l'] +['ĠR', 'OC'] +['_f', 'emale'] +['ĠSt', 'ard'] +[']]', ';'] +['Ġwrest', 'lers'] +['Ġtorrent', 's'] +['Ġsin', 'h'] +['', 'ĊĊ'] +['ë³', 'µ'] +['s', 'ense'] +['how', 'ever'] +['.Ph', 'ysics'] +['Inf', 'rastructure'] +['ĠSac', 'r'] +['F', 'el'] +['ĠD', 'ISTRIBUT'] +['é', 'ments'] +['ĠValid', 'ates'] +['################################################', '############'] +['Ġ|', '/'] +['Ġes', 'l'] +['Ġré', 'seau'] +['ĠB', 'ip'] +['BY', 'TES'] +['_W', 'ATER'] +['Turn', 'ing'] +['EL', 'S'] +['Ġj', 'uxtap'] +['Ġlesb', 'ische'] +['ý', 'ch'] +['(', 'Unknown'] +['Ne', 'o'] +['@', 'JsonProperty'] +['Ġal', 'umnos'] +['ĠRaq', 'qa'] +['ime', 'i'] +['.get', 'Bounds'] +['.Mouse', 'EventHandler'] +['####', '###'] +['Generic', 'Type'] +['/c', 'ms'] +['Ġturn', 'o'] +['Ġм', 'ин'] +['Ġfolk', 'lore'] +['ĠE', 'vo'] +['Ġconduct', 'ivity'] +['Ġle', 'ben'] +['Ġgear', 'box'] +['-v', 's'] +['ĠÏ', 'Ĩ'] +['Ġdrink', 'ers'] +['Ġcon', 'exao'] +['ĠTe', 'eth'] +['Ġget', 'Arguments'] +['ĠR', 'AT'] +['ent', 'ious'] +['E', 'duc'] +['+', 'W'] +['ĠInstitution', 'al'] +['ĠB', 'ord'] +['is', 'Equal'] +['(p', 'wd'] +['Ġign', 'ited'] +['ĠR', 'ousse'] +['Ġimpact', 'ful'] +['ĠM', 'alk'] +['Ġg', 'eral'] +['ĠP', 'ivot'] +['Ġa', 'zt'] +['Ġcsv', 'file'] +['ĠR', 'ope'] +['ĠSOL', 'UTION'] +['ĠArbit', 'rary'] +['Ġlet', 'to'] +['.Mouse', 'Adapter'] +['Ġ}', '}}'] +['ĠSail', 'or'] +['der', 'a'] +['Put', 'ting'] +['Ġconcentr', 'ates'] +['Ġauth', 'Domain'] +['âĢĿ', 'çļĦ'] +['-f', 'inals'] +[',', 'strlen'] +['Mu', 'on'] +['ĠOrd', 'inary'] +['fire', 'fox'] +['ĠLa', 'TeX'] +['ĠH', 'und'] +['engine', 'ering'] +['/', 'blue'] +['ed', 'TextBox'] +['("', '");'] +['ĠC', 'DDL'] +['ke', 'pt'] +['ĠGet', 'String'] +['K', 'ir'] +['()', "='"] +['ĠO', 'CD'] +['ant', 'ium'] +['$', 'menu'] +['ĠAppalach', 'ian'] +['Secret', 'ary'] +['ë¥', 'ĺ'] +['ี', 'ย'] +['Sem', 'antic'] +['Ġ*', '['] +['est', 'one'] +['ung', 'kin'] +['Max', 'Y'] +['-t', 'one'] +['"}', ';čĊ'] +['_P', 'art'] +['<', 'Member'] +['tr', 'am'] +['Ġtrans', 'istor'] +['Ġ----------------------------------------------------------------', '----------Ċ'] +['ĠDes', 'de'] +['Ġright', 'ful'] +['ĠCorn', 'el'] +['æ', 'ij'] +['.H', 'OUR'] +['Ġsidel', 'ined'] +['ref', 'errer'] +['m', 'aze'] +['Ġhol', 'ster'] +['Ġcripp', 'led'] +['ĠDate', 'Formatter'] +['oph', 'age'] +['_m', 'D'] +['Ġdes', 'elect'] +['ra', 'ud'] +['ĠPK', 'K'] +['row', 'Data'] +['Ġlock', 'smith'] +['.res', 'ponses'] +['(product', 'Id'] +['_ST', 'MT'] +['Key', 'Type'] +['.Th', 'en'] +['z', 'ee'] +['Ġcr', 't'] +['ĠGrand', 'ma'] +['@', 'Resource'] +['Ġbit', 'wise'] +['-c', 'mpr'] +['ãĢĤ', 'www'] +['zeit', 'ig'] +['&', 'display'] +['Cart', 'Item'] +['-', 'No'] +['Ġnum', 'éro'] +['Ġm', 'aur'] +['Ġinst', 'ancia'] +['ĉd', 't'] +['_n', 'pc'] +['Ġskate', 'board'] +['âĢľ', 'All'] +['ĠCrow', 'd'] +['Ġä', 'n'] +['Ġb', 'raz'] +['ca', 'e'] +['yn', 'et'] +['/p', 'm'] +['/s', 'creen'] +['OPT', 'ARG'] +['ĠV', 'Box'] +['Ġle', 'opard'] +['_g', 'reater'] +['c', 'pt'] +['<', 'dd'] +['Ġmechan', 'ically'] +['osp', 'els'] +[')', 'f'] +['.l', 'wjgl'] +['.get', 'Port'] +['ĠP', 'REF'] +['.Add', 'Transient'] +['pp', 'ard'] +['Ġí', 'ļĮ'] +['Ether', 'net'] +['Ġsal', 'ine'] +['(level', 's'] +['Ġservice', 'Provider'] +['.A', 'ngle'] +['alt', 'itude'] +['illa', 'ume'] +['Ġs', 'cape'] +['_CAL', 'C'] +['_', 'quest'] +['ĠDiss', 'ertation'] +['ĠE', 'DM'] +['-C', 'ds'] +['Ġhon', 'orary'] +['st', 'ops'] +['Ġsub', 'dir'] +['ĠV', 'H'] +['ĠChe', 'at'] +['Ġright', 'fully'] +['Q', 'E'] +['.Write', 'Byte'] +['fig', 'ures'] +['enn', 'ie'] +['(', 'DBG'] +['Ġvoks', 'ne'] +['Ġexp', 'ended'] +['UN', 'ICATION'] +['il', 'inx'] +['ĠRec', 'ap'] +['_', 'verts'] +['Ġtra', 'umat'] +['Ġget', 'Player'] +['Ġverb', 'ess'] +['Ġcultiv', 'ating'] +['Ġiniti', 'ator'] +['Th', 'ông'] +['find', 'First'] +['_per', 'ms'] +['Ġbu', 'c'] +['Ġ"""', 'čĊčĊ'] +['T', 'YPES'] +['object', 'Manager'] +['(Configuration', 'Manager'] +['Ġtim', 'id'] +['Ġsnap', 'chat'] +['Ġcon', 'seg'] +['ĉd', 'istance'] +['_right', 's'] +['_D', 'es'] +['ĠF', 'lesh'] +['-', 'ver'] +['Ġa', 'fl'] +['fra', 'uen'] +['Ġblas', 'ph'] +['ĠQual', 'ität'] +['ma', 'f'] +['Monitor', 'ing'] +['.D', 'iff'] +['Ġshore', 'line'] +['Ġresponse', 'Body'] +['mem', 'set'] +['<', 'decimal'] +['Smarty', 'HeaderCode'] +['Ġin', 'sets'] +['ĠBinary', 'Tree'] +['amed', 'a'] +['Ġn', 'ihil'] +['ĠN', 'ay'] +['ym', 'ology'] +['ĠW', 'G'] +['Ġt', 'api'] +['ĠInst', 'alled'] +['m', 'aintenance'] +[')}', '"Ċ'] +['ĠX', 'O'] +['-per', 'iod'] +['s', 'ar'] +['Ġning', 'una'] +['ORM', 'AT'] +['.set', 'PrototypeOf'] +['ĠK', 'b'] +['ĠHen', 'rik'] +['ét', 'ique'] +['ĠLah', 'ore'] +['ĉ', 'Address'] +['Ġmel', 'ts'] +['N', 'y'] +['_adv', 'ance'] +['Ġveloc', 'idad'] +['Ġalum', 'no'] +['Ġsanit', 'izer'] +['Ġph', 'ishing'] +['ĠCom', 'et'] +['Ġch', 'iar'] +['ĉs', 'pec'] +['trim', 'med'] +['(state', 'arr'] +['on', 'nen'] +['Re', 'venue'] +['L', 'ens'] +['Ġcha', 'ired'] +['ĠAss', 'umes'] +['Tr', 'ash'] +['_un', 'set'] +['\\', 'Bridge'] +['Point', 'Size'] +['ĠPol', 'ic'] +['Ġsex', 'uales'] +['ĉd', 'fs'] +['ĠWide', 'String'] +['Ġaccru', 'ed'] +['Y', 'W'] +['_S', 'CHEDULE'] +['Ġk', 'ite'] +['Ġparach', 'ute'] +['[', 'table'] +['Ġactive', 'ClassName'] +['.Qu', 'ad'] +['Israel', 'i'] +['ĠÅ', 'ĵ'] +['Ġho', 'og'] +['Ġch', 'á»ī'] +['ew', 'ear'] +['Ġtire', 'lessly'] +['set', 'Error'] +['.get', 'Amount'] +['.set', 'Items'] +['ĠM', 'anson'] +['ĠBay', 'esian'] +['_F', 'lag'] +['AC', 'HER'] +['/', 'original'] +['Ġimm', 'ac'] +['ĠLos', 'ing'] +["'", '>ĊĊ'] +['L', 'ic'] +['ĠMir', 'age'] +['ĠAssembly', 'FileVersion'] +['Te', 'V'] +['ĠValue', 'EventListener'] +['-s', 'olving'] +['Th', 'o'] +['rou', 'lette'] +['_W', 'P'] +['Ġunint', 'errupted'] +['Ġfield', 'Type'] +['.T', 'yped'] +['Ġam', 'our'] +['Ġmock', 'ery'] +['(v', 'ol'] +['ĠSub', 'committee'] +['ĠR', 'uf'] +['ero', 'x'] +[':UIButtonType', 'Custom'] +['ĠBl', 'ur'] +['Ġwy', 'kon'] +['nc', 'es'] +['ASH', 'BOARD'] +['!!', '");Ċ'] +['Ġmurder', 'ers'] +['.d', 'aily'] +['ĠDI', 'AG'] +['j', 'ing'] +['Ġdol', 'phin'] +['Ġl', 'òng'] +['Ġb', 'ö'] +['ĠV', 'ocabulary'] +['.St', 'Object'] +["')", '">'] +['Ġz', 'un'] +['Ġscrim', 'mage'] +['tr', 'éal'] +['ĠL', 'ig'] +['[', 'vi'] +['C', 'ole'] +['Ġfrost', 'ing'] +['.Pl', 'ayers'] +['-', 'translate'] +['Fe', 'els'] +['=\\"', '/'] +['.Butter', 'Knife'] +['Ġ?>', ';Ċ'] +['Ġav', 'i'] +['inn', 'ie'] +['.F', 'ailure'] +['Ġsp', 'indle'] +['Configuration', 'Exception'] +['_h', 'op'] +['Ġpos', 'ição'] +['ĠA', 'wait'] +['UIImage', 'PickerController'] +['ĉ', 'day'] +['Ġgen', 'om'] +['C', 'ab'] +['ĠÑĢ', 'езÑĥлÑĮÑĤаÑĤ'] +['OR', 'IGINAL'] +['Ġejac', 'ulation'] +['(t', 'cp'] +['SE', 'COND'] +['Ġton', 'ic'] +['ĠList', 'Box'] +['Ġ', 'ĉĉĊ'] +['()', '>Ċ'] +['Ġqu', 'atre'] +['ượ', 'ng'] +['with', 'Errors'] +['.M', 'aybe'] +[',', 'â̦'] +['token', 'Id'] +['_UN', 'DEF'] +['Ġfresh', 'ness'] +['ĠAmend', 'ments'] +['.map', 'box'] +['.C', 'V'] +['(b', 'log'] +['_get', 'time'] +['.', 'quest'] +['s', 'parse'] +['Ġres', 'ale'] +['Ġenthusi', 'astically'] +['ĠProstit', 'utas'] +['W', 'a'] +['C', 'argo'] +['.Parcel', 'able'] +['SENS', 'OR'] +['ĠRy', 'u'] +['La', 'ughs'] +['_N', 'ative'] +['/', 'pg'] +['yst', 's'] +['Ġphot', 'oc'] +['ç®', 'Ģ'] +['ado', 'pt'] +['.spec', 'ies'] +['conc', 'iliation'] +['Adjust', 'ed'] +['.Firebase', 'Auth'] +['ut', 'tle'] +['ord', 'ination'] +['Ġm', 'unch'] +['ĠSt', 'ake'] +['.p', 'ing'] +['ank', 'er'] +['(QString', 'Literal'] +['Ġsub', 'script'] +['ĠĠ', 'ĉĊ'] +['ĠM', 'CC'] +['_C', 'md'] +['se', 'xy'] +['i', 'ou'] +['ĠM', 'ANY'] +['Ġn', 'anny'] +['TR', 'AIN'] +['Ġflour', 'ishing'] +['ĠW', 'atches'] +['ĠQ', 'Map'] +['ĠF', 'erm'] +['Ġwas', 'm'] +['ĠA', 'bed'] +['_', 'UD'] +['ĠGlass', 'es'] +['+', 'v'] +['Att', 'end'] +['.Ch', 'ain'] +['Ġdec', 'ency'] +['ĠSupplement', 'ary'] +['h', 'unter'] +['-t', 'xt'] +['Ġ"', '}";Ċ'] +['.set', 'WindowTitle'] +['("', ''] +['Ġmasc', 'ara'] +['(', 'Profile'] +['åĬŁ', 'èĥ½'] +['imit', 'é'] +['Ġwild', 'fires'] +['-', 'ROM'] +['.is', 'On'] +['(group', 'Id'] +['Re', 'pair'] +['accum', 'ulate'] +['Ġ<', '",'] +['Ġhand', 'written'] +['Ġach', 'eter'] +['ĠM', 'GM'] +['ĠIr', 'ma'] +['->{', '_'] +['ge', 'e'] +['cr', 'iminal'] +['Ġèĭ¥', 'è¦ģ'] +['Ġmoment', 'arily'] +['")', '!='] +['_l', 'it'] +['Ġexpires', 'In'] +['."', ').'] +['éķ¿', '度'] +['Ġfr', 'ække'] +['vl', 'c'] +['Ġor', 'bs'] +['),', '$'] +['Ġvent', 'ured'] +['/', '>\\'] +['char', 'm'] +['N', 'uitka'] +['eld', 'ig'] +['aton', 'in'] +['W', 'itness'] +['-l', 'at'] +['Ġset', 'Hidden'] +['Ġrelic', 's'] +['Ġcons', 'ulate'] +['.', 'IGNORE'] +['"', 'After'] +['Ġset', 'Address'] +['Ġbeste', 'ht'] +["Ġ''", ')ĊĊ'] +['.x', 'axis'] +['Ġser', 'ão'] +['Ġmis', 'led'] +['_UN', 'IFORM'] +['ĠV', 'IA'] +['inc', 'r'] +['Ġzen', 'ith'] +['Ġvis', 'cosity'] +['Ġthin', 'ly'] +['.get', 'SharedPreferences'] +['.Error', 'Code'] +['"),', '"'] +['ĠMillion', 'en'] +['Ġ/>', ')Ċ'] +['Scroll', 'Indicator'] +['-se', 'eking'] +['ĠPOLIT', 'ICO'] +['as', 'ca'] +['_r', 'l'] +['N', 'avig'] +['(full', 'file'] +['Ġsol', 'itude'] +['Ġju', 'ven'] +['Ġhaul', 'ing'] +['ĠMac', 'ros'] +['ĠG', 'ry'] +['Ġexerc', 'itation'] +['ĠATT', 'ACK'] +['Tick', 'Count'] +['Ġr', 'ites'] +['Ġdo', 'e'] +['Particle', 'System'] +['Ġsl', 'u'] +['Window', 'Text'] +['ĠClass', 'Name'] +['Ġsl', 'ander'] +['ĉ', 'Port'] +['j', 'ong'] +['?', 'a'] +['.D', 'ial'] +['âĢĶ', 'at'] +['$obj', 'PHPExcel'] +['Ġso', 'ar'] +['EN', 'N'] +['appe', 'ared'] +['Ġquot', 'id'] +['em', 'achine'] +['Ġn', 'ip'] +['Ġmicro', 'time'] +['ĠAl', 'ma'] +[';', '!'] +['----------------------------------------------------------------', '--------------------------------'] +['ĠPass', 'age'] +['Ġdump', 'sters'] +['ĠEx', 'clude'] +['Ġsuggest', 'ive'] +['ĠCircularProgress', 'Indicator'] +['_cl', 'r'] +['Array', 'Type'] +['ILL', 'A'] +['Elapsed', 'Time'] +['Dr', 'iven'] +['Ġresource', 'Name'] +['ĠG', 'arrison'] +['ser', 'ir'] +['-a', 'head'] +['Ġp', 'innacle'] +['ĠEs', 'presso'] +['S', 'parse'] +['Ġass', 'ays'] +['ĠGirl', 'friend'] +['im', 'id'] +["]='", '\\'] +['ONGL', 'ONG'] +['Ġportray', 'ing'] +['L', 'ane'] +['Ġb', 'úsqueda'] +['Ġrein', 'forcements'] +['ĠSpread', 'sheet'] +['ĠArray', 'Collection'] +[',', 'arr'] +['light', 'box'] +['ic', 'ana'] +['<', '"'] +['build', 'ers'] +['K', 'id'] +['ĠMat', 'SnackBar'] +['EX', 'PR'] +['od', 'cast'] +['ĠFound', 'ations'] +['Ġind', 's'] +["='", '${'] +['F', 'izz'] +['-function', 'al'] +['(work', 'space'] +['Ġstem', 'med'] +['_p', 'atches'] +['ĠJar', 'vis'] +['READ', 'ING'] +['Ġdisrespect', 'ful'] +['ĠQ', 'Dom'] +['Ġ$', '{Ċ'] +['est', 'atus'] +['Re', 'ached'] +['!', '.ĊĊ'] +['IL', 'T'] +['ĠN', 'DEBUG'] +['ĠCour', 'age'] +['birth', 'date'] +['ĠT', 'ing'] +['Ġutil', 'izado'] +['án', 'chez'] +['Out', 'door'] +['Ġhand', 'guns'] +['Ref', 'Count'] +['É', 'Ļ'] +['rom', 'o'] +['Ġt', 'ts'] +['.S', 'he'] +['ĠP', 'ane'] +['ãĢij,', 'ãĢIJ'] +['ĠIO', 'CTL'] +['/', 'black'] +['ins', 'cription'] +['Ġbi', 'opsy'] +['ĠTime', 'Interval'] +['.Test', 'Check'] +['ĠGUI', 'Style'] +['ĠCap', 'ability'] +['ĠBeit', 'rag'] +['don', 'nees'] +['T', 'reatment'] +['.back', 'up'] +['Ġsign', 'ings'] +['ĠB', 'oca'] +['dr', 'm'] +['.M', 'AIN'] +['Ġgo', 'ede'] +['ĠMark', 'up'] +['G', 'REE'] +['ĠBase', 'Service'] +['.C', 'reator'] +['Ġj', 'ails'] +['ĠK', 'ahn'] +['Ip', 'Address'] +['ACH', 'I'] +['Ġinhib', 'ited'] +['Ġ@', '$_'] +['ĠAss', 'ass'] +['Ġenvi', 'ado'] +['Hero', 'es'] +['ÐŁ', 'еÑĢ'] +['ĠM', 'aven'] +['.l', 's'] +['Ġ', 'ive'] +['|', 'RF'] +['Ġresize', 'Mode'] +['Ġrum', 'pe'] +['_attach', 'ments'] +['T', 'U'] +['Ġtact', 'ile'] +['Attempt', 'ing'] +['Ġro', 'bin'] +['y', 'aw'] +['Ġmerc', 'enaries'] +['ĠHab', 'itat'] +['end', 'date'] +['Ġo', 'xy'] +['ĉR', 'andom'] +['oh', 'on'] +['Is', 'Null'] +['ĠValidation', 'Result'] +['ãĥ', 'ļ'] +['um', 'bed'] +['pp', 'v'] +['Ġar', 'p'] +['ich', 'ick'] +['_r', 'nn'] +['ĠT', 'FT'] +['Tex', 'Image'] +['"', 'On'] +['ĠSam', 'pler'] +['top', 'l'] +['Ġj', 'ane'] +['y', 'ling'] +['ĠUN', 'ICODE'] +['Tab', 'Index'] +['<', '{Ċ'] +['s', 'uspend'] +['uv', 'ian'] +[',', 'application'] +['ол', 'иÑĩеÑģÑĤво'] +['y', 'at'] +['ez', 'ier'] +['ĠCH', 'UNK'] +['ĠAd', 'ler'] +['/', 'Add'] +['ĠKey', 'Value'] +['Ġspos', 'ób'] +['Sam', 'pling'] +['ch', 'ers'] +['_AM', 'D'] +['R', 'u'] +['.Must', 'Compile'] +['N', 'ation'] +['Ass', 'oc'] +['Man', 'aging'] +['ĠEng', 'l'] +['_G', 'B'] +['Ġsucc', 'inct'] +['Ġdis', 'liked'] +['ĠI', 'ke'] +['Bullet', 'in'] +['_ARCH', 'IVE'] +['Prop', 'osal'] +['Ġjog', 'ging'] +['.C', 'REATED'] +['Ġch', 'ol'] +['è£', 'ħ'] +['Į', '¨'] +['-p', 'ush'] +['Ġreserv', 'a'] +['core', 'v'] +['è', 'tre'] +['TH', 'R'] +['Ġincompet', 'ence'] +['Ġchar', 'isma'] +['æĦ', 'Ł'] +['Ġ"', '=='] +['BT', 'N'] +['ĠLoc', 'ator'] +['iv', 'et'] +["('.", "')Ċ"] +['Ġfor', 'IndexPath'] +['ô', 'me'] +['Ġcapac', 'it'] +['w', 'aters'] +['ĠWR', 'ONG'] +['ho', 'a'] +['ĠM', 'IPS'] +['Ġem', 'iss'] +['ĠJacqu', 'eline'] +['(c', 'mp'] +['Ġe', 'ens'] +['Le', 'o'] +['.tim', 'ing'] +['CLUS', 'ION'] +['Ġ("', '-'] +['åĵ', 'Ī'] +['.k', 'ode'] +['ĠUnd', 'ert'] +['Ġbew', 'ild'] +['ĠEss', 'en'] +['.h', 'd'] +['Ġren', 'egot'] +['Ġm', 'ower'] +['Ġl', 'sp'] +['Ġpen', 'chant'] +['Ġman', 'oe'] +['Ġag', 'li'] +['Ġrec', 'al'] +['ĠOPER', 'ATION'] +['(^', ')('] +['ĠÎ', '½'] +['ĠSc', 'oped'] +['Ġ@', '"Ċ'] +['=', 'label'] +['[', 'loc'] +['Int', 'l'] +['ĠN', 'z'] +['table', 't'] +['.Column', 'Name'] +['Ġscreen', 'Size'] +['DB', 'us'] +['co', 'oked'] +['-', 'registration'] +['âĢľ', 'One'] +['-n', 'on'] +['ĠwiÄĻ', 'c'] +['Ġcost', 'a'] +['.add', 'Tab'] +['.', 'conditions'] +['ĠH', 'ess'] +['MEM', 'ORY'] +['ĠAval', 'anche'] +['()', '}}Ċ'] +['Ġtri', 'plet'] +['Ġl', 'abyrinth'] +['ĠNode', 'List'] +['ĠNY', 'T'] +['Ġy', 'eni'] +['d', 'ff'] +['.Html', 'Controls'] +['AV', 'IS'] +['/', 'Math'] +['Ġmem', 'cmp'] +['اØ', '¡'] +['оÑģ', 'ÑĮ'] +['c', 'rap'] +['(p', 'ages'] +['Ġl', 'xml'] +['ĠQ', 'DateTime'] +['_t', 'cb'] +['Ġopen', 'id'] +['Ġsyn', 'aptic'] +['ĠMD', 'MA'] +['(s', 'lug'] +['igm', 'atic'] +['en', 'or'] +['Ġcr', 'amped'] +['G', 'OP'] +['Ń', 'IJ'] +['.is', 'File'] +['ĠD', 'ifferential'] +['Ġ="', '";Ċ'] +['ĉĉĉ', 'ĠĠĠĠĉ'] +['ĠC', 'ooke'] +['ĉU', 'FUNCTION'] +['Ġpersever', 'ance'] +['Relative', 'Layout'] +['IMPORT', 'ANT'] +['Ġex', 'on'] +['Ġо', 'н'] +['ib', 'ase'] +['(C', 'ONT'] +['n', 'ovation'] +['ä½', 'ķ'] +['[', 'sub'] +['Admin', 'Controller'] +['HTTP', 'Header'] +['cre', 'ar'] +['ĠN', 'IR'] +['ĠDrop', 'DownList'] +['Ġval', 'ide'] +['Ġde', 'hydration'] +['.', "']"] +['(W', 'IN'] +['Ġ...', '\\'] +['Ġphotos', 'hop'] +['ĉ', 'Init'] +['_c', 'ou'] +['Ġtime', 'Zone'] +['dar', 'win'] +['rom', 'atic'] +['Navigation', 'ItemSelectedListener'] +['br', 'ates'] +[']', '--;Ċ'] +['Ġtraged', 'ies'] +['ĠPed', 'iatrics'] +['SM', 'ART'] +['-A', 'PI'] +['ĠMessage', 'Lookup'] +['ĉ', 'vo'] +['Ġprejud', 'ices'] +['Ġm', 'A'] +['U', 'ps'] +['ĠMISS', 'ING'] +['ĉ', 'ad'] +['C', 'ream'] +['ĠT', 'b'] +['ĠMon', 'a'] +['_', 'ghost'] +['ĉt', 'ypes'] +['Em', 'b'] +['ĠDocument', 'ary'] +["');ĊĊ", 'ĊĊ'] +['Ġl', 'up'] +['_', 'Reference'] +['ĠB', 'ATCH'] +['Ġintertw', 'ined'] +['<', 'Cell'] +['ĠCab', 'r'] +['n', 'ation'] +['Ġis', 'Connected'] +['.remove', 'Listener'] +['Ġcon', 'g'] +['_t', 'i'] +['ĠSil', 'icone'] +['Ġê²°', 'ê³¼'] +['ĠW', 'AN'] +['ĠG', 'ibraltar'] +['/', 'response'] +['ĉp', 'erson'] +['ch', 'ants'] +['V', 'IP'] +['em', 'ergency'] +['Pixel', 'Format'] +['-', 'Am'] +['Ġsouth', 'western'] +['_pl', 'l'] +['if', 'ers'] +['_ON', 'CE'] +['ĠF', 'ayette'] +['.nc', 'bi'] +['_P', 'anel'] +['.Q', 'ual'] +['Ġpol', 'ys'] +['Ġcreate', 'StackNavigator'] +['�', 't'] +['Ġlay', 'offs'] +['ĠBl', 'anco'] +['Fe', 'at'] +['ĠV', 'imeo'] +['_ch', 'i'] +['_l', 'ifetime'] +['POINT', 'S'] +[',', 'private'] +['Ġunb', 'earable'] +['print', 'ing'] +['Ġc', 'gi'] +['.B', 'ACK'] +['Ġintern', 's'] +['ĠNew', 'ly'] +['inf', 'eld'] +['(', 'IB'] +['ĠK', 'ata'] +['ĠDef', 'endants'] +['Th', 'r'] +['é¢', 'Ħ'] +['_V', 'F'] +['FFFF', 'FFFF'] +['Ġdavid', 'jl'] +['Ġbitter', 'ly'] +['S', 'uggestions'] +['.set', 'Cancelable'] +['FIN', 'AL'] +['ason', 's'] +['_rw', 'lock'] +['_WRAP', 'PER'] +['Ġhapp', 'iest'] +['(row', 'Index'] +['ós', 'ito'] +['TOT', 'YPE'] +['Autom', 'ation'] +['Log', 'File'] +['Ġcons', 'olation'] +['ãĥ', 'Ģ'] +['Ġt', 'êm'] +['Ġpr', 'er'] +['rg', 'yz'] +['ĠG', 'eg'] +['ĉd', 'to'] +['.default', 'Value'] +['ĠK', 'ami'] +['ĠA', 'SE'] +['optim', 'ized'] +['Ġíı', '¬'] +['Ġorigin', 'ates'] +['err', 'Msg'] +['Ġespa', 'ço'] +['(S', 'YS'] +['ĠMc', 'B'] +['d', 'ance'] +['_det', 'ected'] +['Ġfr', 'ü'] +['ĉĉ', 'ĠĠĠĠĉĉ'] +['<', 'Date'] +['(com', 'b'] +['ĠDec', 'ide'] +['\\', 'Field'] +['ĠProp', 'osed'] +['R', 'ib'] +['Ġdis', 'likes'] +['ĠW', 'ien'] +['ĉ', 'Document'] +['Ġtr', 'af'] +['Ġst', 'oria'] +['ĠT', 'ells'] +["')", '=='] +['C', 'ri'] +['(', 'VALUE'] +['ĠBurn', 'ett'] +[',', 'void'] +['Ġdan', 'h'] +['Ġc', 'cp'] +['Block', 'chain'] +[':"-', '"`Ċ'] +['IC', 'lient'] +['IS', 'ODE'] +['Iss', 'uer'] +[')', '}čĊ'] +[',', 'but'] +['ĠU', 'ph'] +['(', 'Sub'] +['Ġtélé', 'phone'] +['ĠonData', 'Change'] +['Ġmarsh', 'aller'] +['-an', 'alytics'] +[',', 'content'] +['Ġdeb', 'acle'] +['_Value', 'Changed'] +['Ġfa', 'una'] +['Ġ#', '=>'] +['Ġf', 'oyer'] +["'util", 'isation'] +['ĠMü', 'ller'] +['ĠFet', 'ish'] +['Ġdefault', 'Manager'] +['Ġback', 'track'] +['B', 'ah'] +['Exp', 'licit'] +['_A', 'SCII'] +['Ġm', 'Activity'] +['(M', 'sg'] +['Ġê²', 'Į'] +['ĠTER', 'MS'] +['ĠAng', 'ie'] +['HS', 'V'] +['ĠMos', 'que'] +['.N', 'ames'] +['íĬ', '¼'] +['rest', 'e'] +['_p', 'arms'] +['Ġgap', 'ing'] +['Ġcro', 'pping'] +['Data', 'Frame'] +['Ġrespons', 'iveness'] +['_', 'undo'] +['_tr', 'an'] +['.', 'terminate'] +['Ġitalian', 'e'] +['Ġwalk', 'through'] +['Ġattract', 'iveness'] +['д', 'е'] +['_ST', 'S'] +['_', 'learn'] +['Ġchocol', 'ates'] +['ier', 'archical'] +['-th', 'inking'] +['Ġ', ')))'] +['ish', 'ments'] +['.Log', 'f'] +['ĠTM', 'Z'] +['ĠCan', 'ary'] +['fo', 'il'] +['ĠVacc', 'ine'] +['.v', 'x'] +['ĠSur', 'round'] +['Inter', 'mediate'] +['Ġi', 'ov'] +['v', 'ais'] +["';", '";Ċ'] +['ï½ŀ', 'ĊĊ'] +['éĢģ', 'æĸĻ'] +['â̦', 'it'] +['Se', 'ats'] +['Cl', 'ar'] +['W', 'ars'] +['ĠHutch', 'inson'] +['ĠHas', 'an'] +['!', "')ĊĊ"] +['ĠRich', 'ie'] +['che', 'iden'] +['($', "('"] +['Y', 'ork'] +['Ġl', 'ids'] +['Ġal', 'phanumeric'] +['ĠG', 'lock'] +['.sh', 'apes'] +['Ġspark', 'ing'] +['_', 'epsilon'] +['uplic', 'ated'] +['.dir', 'ty'] +['])', '=='] +['ĠìľĦ', 'ì¹ĺ'] +['Ġsc', 'n'] +['Ġ/', '****************************************************************'] +['_PRE', 'VIEW'] +['_H', 'C'] +['ield', 'ing'] +['f', 'gets'] +['ĠAdd', 'ison'] +['Ġproduct', 'Service'] +['-', 'figure'] +['(ret', 'val'] +['z', 'ano'] +['Ġaut', 'ob'] +['ĉs', 'd'] +['_n', 'umer'] +['ĠSet', 'LastError'] +['ĠF', 'ior'] +['ific', 'ance'] +['Unt', 'itled'] +['Ġin', 'field'] +['Ġ{}', '));Ċ'] +['Ġsp', 'ac'] +['Ġro', 'okies'] +['(des', 'cribing'] +['ng', 'en'] +['ி', 'à®'] +['.r', 'df'] +['.M', 'utex'] +['Ġkne', 'eling'] +['ĠQ', 'E'] +['set', 'Max'] +['Read', 'Stream'] +['Ġvent', 'as'] +['s', 'ut'] +['cm', 'peq'] +['.WriteAll', 'Text'] +['ĠEx', 'perienced'] +['$', '__'] +['Ġka', 'um'] +['ĠL', 'IS'] +['Ġdocument', 'os'] +['_HE', 'ALTH'] +['icont', 'ains'] +['Ġart', 'isans'] +['OWN', 'ER'] +['Ġblink', 'ed'] +['get', 'Display'] +['Ġto', 'en'] +['Ġrow', 'Num'] +['Ġav', 'ril'] +['Ġinv', 'is'] +['ĠK', 'ear'] +['toBe', 'InTheDocument'] +['ap', 'ur'] +['Ġr', 'acked'] +['ĠMc', 'Master'] +['_ATTR', 'IB'] +['H', 'az'] +['Ġfact', 'ura'] +['/', 'ts'] +['ĠÑĢаз', 'меÑĢ'] +['Ġz', 'f'] +['Ġshort', 'fall'] +['.f', 'asta'] +['ĠCONST', 'ANT'] +['.man', 'aged'] +['g', 'ems'] +['Shared', 'Pointer'] +['Ġblur', 'ry'] +['b', 'rightness'] +['(', 'components'] +['Ġ...', '"ĊĊ'] +['SE', 'LL'] +['ĠIllustr', 'ator'] +['.get', 'Channel'] +['Ġtrou', 'vé'] +['yst', 'ers'] +['Ġvo', 'is'] +['ĠLind', 'en'] +['Ġem', 'ojis'] +['Ġb', 'rawl'] +['ĠMS', 'R'] +['ĠE', 'lo'] +['ĠCroat', 'ian'] +['Popup', 'Menu'] +['L', 'ewis'] +['.J', 'WT'] +['Ġaston', 'ished'] +['B', 'ush'] +['(item', 'Id'] +['Ġdet', 'achment'] +['ĠEnc', 'ore'] +['å°', 'Ķ'] +['Ġre', 'kl'] +['Ġcr', 'am'] +[')$', '/'] +['.get', 'Host'] +['_re', 'commend'] +['-', 'HT'] +['_cal', 'ibration'] +['Auth', 'enticate'] +['.firebase', 'app'] +['UN', 'IX'] +['ĉC', 'amera'] +['ĠHE', 'AP'] +['I', 'deal'] +['.', 'office'] +['Ġgoof', 'y'] +['(S', 'ymbol'] +['Ġjou', 'er'] +['_part', 'itions'] +['Ġrapid', 'ement'] +['ĠGN', 'UNET'] +['id', 'User'] +['Ġsuperv', 'ise'] +['(', 'Contact'] +['AW', 'N'] +['ãģ', 'ĺ'] +['Ġna', 'am'] +['Ġa', 'ust'] +['åľ¨', '线'] +['_soft', 'max'] +['Allow', 'Anonymous'] +['amm', 'able'] +['RO', 'UTE'] +['*', 'D'] +['Ġad', 'en'] +['ĠCrist', 'ina'] +['ĠCrist', 'iano'] +['Ġblood', 'stream'] +['sub', 'class'] +['_person', 'a'] +['CH', 'ILD'] +['-k', 'now'] +['Ġnavigation', 'Options'] +['ĠZuk', 'unft'] +['ĠPix', 'ar'] +['Ty', 'ler'] +['Ġunder', 'world'] +['Ġsincer', 'ity'] +['Ġdispens', 'er'] +['Ġk', 'ter'] +['idd', 'ers'] +['.add', 'Node'] +['-', 'checked'] +['Ġke', 'yst'] +['ĠW', 'TO'] +['.sign', 'als'] +['Ġadvent', 'urer'] +['ĠP', 'ang'] +['\\', 'R'] +['=', 'pos'] +['Ġdispens', 'aries'] +['ĠClo', 'set'] +['("{', '\\"'] +['ide', 'on'] +['Ġnécess', 'aire'] +['()', '"Ċ'] +['_RECE', 'IVED'] +['Ġrésult', 'ats'] +['Ġmod', 'en'] +['ĠIceland', 'ic'] +[';', 'd'] +['.', 'allowed'] +['(new', 'User'] +['Ġmerc', 'iless'] +['.Wait', 'For'] +['Ġday', 'care'] +['ĠCon', 'veyor'] +['ç', 'ĸ'] +['ð', '¬'] +['ç', 'ĥ'] +['ç', 'Ĺ'] +['ç', 'ł'] +['è', 'Ħ'] +['é', '²'] +['å', '¦'] +['çĿ', 'Ģ'] +['å¾', 'Ī'] +['é', 'ħ'] +['ç', 'ĭ'] +['é', 'ª'] +['æ', 'Ĥ'] +['é', '¥'] +['è', 'ħ'] +['æĥ', '³'] +['å', '¨'] +['é', '¹'] +['ç', 'Ĥ'] +['å', 'Ĵ'] +['ç', 'Į'] +['è´', '¨'] +['æ', '¢'] +['æ°', 'Ķ'] +['ð', '«'] +['æķ', 'Ļ'] +['ç', 'Ł'] +['å', 'Ħ'] +['åıij', 'å±ķ'] +['åĪ', 'Ľ'] +['è', 'ij'] +['æ', 'ħ'] +['å', 'ŀ'] +['åģ', 'ļ'] +['æĪ', 'ĺ'] +['æ', 'IJ'] +['å¼', 'º'] +['æ·', '±'] +['åĩ', 'ł'] +['ç', '¿'] +['å', '©'] +['è', 'ŀ'] +['å§', 'Ķ'] +['åIJ', 'Ħ'] +['è', 'İ'] +['é', '¸'] +['é', 'º'] +['åı', 'Ĺ'] +['èģ', 'Į'] +['å', 'ĺ'] +['æ', '½'] +['é£', 'İ'] +['èIJ', '¥'] +['åħ', 'ļ'] +['è', 'ľ'] +['éĤ', '£'] +['é¢', 'Ĩ'] +['ç', 'ij'] +['é', '³'] +['æľ', '¯'] +['ä»', 'Ģ'] +['æĪ', '¿'] +['ç²', '¾'] +['å', 'ª'] +['é', 'Ĩ'] +['å¤', 'ª'] +['èĤ', '¡'] +['è', 'Ľ'] +['åħ', 'ī'] +['æŀ', 'ģ'] +['åĬ', 'ŀ'] +['è', 'ĵ'] +['ç', 'ĺ'] +['å', '´'] +['å', 'Ĺ'] +['èĬ', '±'] +['çł', 'Ķ'] +['å¿', '«'] +['å¸', 'Ī'] +['è¶', 'Ĭ'] +['è§', 'Ĥ'] +['æ', '¤'] +['æ', '¦'] +['ç', 'ŀ'] +['èĤ', '²'] +['çĪ', '±'] +['çĻ', '½'] +['ä¸', 'ĸ'] +['ä»Ģ', 'ä¹Ī'] +['çľ', '¼'] +['å', '³'] +['è', 'Ĵ'] +['æ', 'ĵ'] +['è¢', '«'] +['å¹', '²'] +['çĹ', 'ħ'] +['å£', '«'] +['ç', 'Ĵ'] +['è', '¸'] +['æ', '¾'] +['å·¥', 'ä½ľ'] +['è®', '©'] +['çĥ', 'Ń'] +['è¾', 'ĥ'] +['åĦ', '¿'] +['åĬ', '©'] +['ç§', '¯'] +['ç', '³'] +['ç', 'ĵ'] +['ç', '£'] +['å', 'Ĥ'] +['è', '¹'] +['è', 'ļ'] +['å·', '±'] +['çĻ', '¾'] +['åĬ', '¿'] +['èµ', 'Ľ'] +['æ', '¨'] +['æ', '¿'] +['è', 'ĸ'] +['æĿ', 'ij'] +['å¸', '¦'] +['å¢', 'ĥ'] +['æĬ', '¤'] +['é', 'Ń'] +['å', '«'] +['èĩª', 'å·±'] +['æµ', 'İ'] +['ä½', 'İ'] +['åĮ', '»'] +['éĺ', '²'] +['åĨ', 'ľ'] +['è', 'Ĩ'] +['ç', 'Ĩ'] +['é', '«'] +['åĨ', 'Ľ'] +['æĪ', 'ı'] +['åį', 'ĩ'] +['æĸ', '¯'] +['ä½', 'ı'] +['èIJ', '½'] +['åħ', '»'] +['èĩ', '´'] +['ç', 'Ĭ'] +['ç', 'ĩ'] +['ç', 'ħ'] +['è', 'Ķ'] +['ä¼ģ', 'ä¸ļ'] +['åĽ', '¢'] +['æī', 'į'] +['æł', '¡'] +['åĩ', 'Ĩ'] +['å¥', 'ĩ'] +['åī', '¯'] +['é', '¼'] +['æ¼', 'Ķ'] +['é©', '¬'] +['èµ', '°'] +['ç¥', 'ŀ'] +['åħ', 'ĭ'] +['æľ', 'Ľ'] +['æ²', '¹'] +['è¾', '¹'] +['åį', 'ĥ'] +['å¾', 'Ģ'] +['åĪ', 'ĩ'] +['æ', '©'] +['ç', '¶'] +['å', 'Ļ'] +['éĻ', 'ħ'] +['çī', 'Į'] +['社', 'ä¼ļ'] +['游', 'æĪı'] +['æĸ', '½'] +['ç', 'ħ§'] +['æİ', '§'] +['æ»', '¡'] +['è¯', 'Ĩ'] +['éĩį', 'è¦ģ'] +['è¶', '³'] +['çķ', 'Ļ'] +['ç»', 'Ĩ'] +['åį', 'ı'] +['éĢ', 'Ĥ'] +['æ', 'ĩ'] +['æ', '§'] +['é', 'Ħ'] +['è', 'Ŀ'] +['å¸Ĥ', 'åľº'] +['ç»ı', 'æµİ'] +['ä¹', 'ł'] +['æĸĩ', 'åĮĸ'] +['éļ', '¾'] +['ä¹', 'IJ'] +['åĨ', '³'] +['æ¬', '¢'] +['è§', 'ī'] +['åĽ', 'Ń'] +['åħ', '´'] +['åħ', 'ħ'] +['ä¸', '¾'] +['æī', '¹'] +['è', 'ķ'] +['æĬ', 'Ĭ'] +['æĬĢ', 'æľ¯'] +['ç©', '¶'] +['第', 'ä¸Ģ'] +['ä¾', '¿'] +['åĵ', 'į'] +['çİ', '©'] +['åĿ', 'ļ'] +['èŀ', 'į'] +['åį', 'Ĭ'] +['åĸ', 'ľ'] +['å±', 'Ĥ'] +['ç¦', '»'] +['ä»', 'ħ'] +['é', 'Ł'] +['åij', '³'] +['å¿', 'µ'] +['åŃ', '£'] +['ç´', '§'] +['ä¹', 'ħ'] +['é', '¤'] +['é', 'ŀ'] +['è', '¤'] +['åĢ', 'Ļ'] +['åĨ', 'µ'] +['ç', 'ٳ'] +['åģ', '¥'] +['æĢ', 'İ'] +['å®', 'Ŀ'] +['è¡', 'Ģ'] +['åŁ', 'Ł'] +['æĹ', '©'] +['çŁ¥', 'éģĵ'] +['è´', 'Ł'] +['åį', 'ļ'] +['å·', '´'] +['äº', '²'] +['å±', 'ŀ'] +['ä¸', '¥'] +['äº', 'ī'] +['å¯', 'Ł'] +['è', 'º'] +['ç', '°'] +['建', '设'] +['产', 'ä¸ļ'] +['åIJ', 'ĥ'] +['åŃ', '©'] +['æĹ', 'ħ'] +['æł', '¹'] +['æĿ', 'IJ'] +['ä¼', 'Ĺ'] +['éļ', 'ı'] +['å®', 'ĺ'] +['åº', 'ķ'] +['å½', '©'] +['å¯', 'Į'] +['æ¸', '©'] +['åį', '«'] +['åī', '§'] +['çĽ', 'Ĭ'] +['æĬ', 'Ĺ'] +['è´', '¢'] +['çº', 'ª'] +['æ', 'Ĩ'] +['çĶŁ', 'æ´»'] +['çº', '¢'] +['çĶŁ', '产'] +['è¿', 'ľ'] +['éĴ', '±'] +['åĶ', '®'] +['ç¾', '¤'] +['çı', 'Ń'] +['æ¥', '¼'] +['éĩ', 'ĩ'] +['èī', 'º'] +['å±', 'ħ'] +['åģ', 'ĩ'] +['è°', 'Ī'] +['æĻ', 'ļ'] +['é', '¬'] +['èĪ', 'ª'] +['å®', '³'] +['è', 'Ĺ'] +['ç', 'į'] +['å', 'µ'] +['çİ', 'ĭ'] +['åº', '·'] +['è', 'İ·'] +['ç»', 'Ń'] +['äº', 'ļ'] +['é£', 'Ł'] +['åİ', 'ĭ'] +['æĭ', 'Ľ'] +['èĮ', 'ĥ'] +['è®', '¸'] +['åĽ', '´'] +['é', '½'] +['éĻ', 'į'] +['çº', '³'] +['åĵ', 'ª'] +['æķĻ', 'èĤ²'] +['å·²', 'ç»ı'] +['å¾', '·'] +['æŀ', 'Ĺ'] +['å®ī', 'åħ¨'] +['é¾', 'Ļ'] +['大', 'å®¶'] +['éĿ', 'Ĵ'] +['åº', 'ľ'] +['æ²', '³'] +['åı', '¤'] +['èį', '¯'] +['åĿ', 'ĩ'] +['æĻ', 'º'] +['ä¹', '¡'] +['çķ', '¥'] +['åĨ', '·'] +['ç¦', 'ı'] +['å®', '¤'] +['ç»', '´'] +['æī', '¿'] +['å±', 'Ĭ'] +['è¯', 'ī'] +['åĪ', '»'] +['è', 'Ł'] +['æ', 'ª'] +['å°±', 'æĺ¯'] +['è¿Ļ', '个'] +['ä¸Ń', 'å¿ĥ'] +['ä¸ĸ', 'çķĮ'] +['åŁİ', 'å¸Ĥ'] +['éĿŀ', '常'] +['åĪ', 'Ĵ'] +['åı', 'Į'] +['æĢİ', 'ä¹Ī'] +['åΰ', 'äºĨ'] +['æľ', 'ĥ'] +['åı', '²'] +['ä¾', 'Ĩ'] +['å¾', 'ĭ'] +['å¥', 'ĸ'] +['ç»', 'Ī'] +['åª', 'Ĵ'] +['å®', 'ģ'] +['è¯', '¾'] +['èģĮ', 'ä¸ļ'] +['åħ', 'į'] +['æµ', 'ĭ'] +['æĢ', '¥'] +['æķ', 'ij'] +['çĭ', '¬'] +['èŃ', '¦'] +['é¤', 'IJ'] +['æĦ', '¿'] +['è´', '«'] +['çĸ', 'ij'] +['å', 'ļ'] +['å¥', '¹'] +['åı', 'Ī'] +['åĽł', '为'] +['ä¸į', 'æĺ¯'] +['å¤', 'Ł'] +['æĸ¹', 'éĿ¢'] +['éķ', 'ĩ'] +['äº', 'Ĵ'] +['éħ', 'Ĵ'] +['è®', '²'] +['çĸ', 'Ĺ'] +['æĺ', '¥'] +['æ¹', 'ĸ'] +['å¤', 'ľ'] +['è´£', 'ä»»'] +['人', 'æ°ij'] +['åħ', '°'] +['çŁ', 'Ń'] +['æķ', 'ħ'] +['åĩ', 'ı'] +['æĻ', '®'] +['äº', '®'] +['ä¾', 'Ŀ'] +['åį', '°'] +['éĿ', 'Ļ'] +['åĢ', 'ĭ'] +['å¾', 'ģ'] +['åIJ', '¸'] +['ç¼', 'º'] +['æĶ', '»'] +['åĩ', 'Ģ'] +['åħ', '¸'] +['åĽ', 'º'] +['è®', '¿'] +['ç', '¹'] +['ç', 'Ģ'] +['æıIJ', 'ä¾Ľ'] +['ç»', 'ĩ'] +['å¾Ī', 'å¤ļ'] +['çłĶ', 'ç©¶'] +['è·', 'Ł'] +['主', 'è¦ģ'] +['æĥħ', 'åĨµ'] +['çŃ', 'ĸ'] +['æŃ', '»'] +['大', 'åѦ'] +['æĶ¿', 'åºľ'] +['å½±', 'åĵį'] +['ä¹', '°'] +['åħ', 'Ń'] +['éĻ', '©'] +['åħ', '«'] +['æŁ', 'IJ'] +['è´¨', 'éĩı'] +['åį', 'ł'] +['å·', '®'] +['æĽ´', 'å¤ļ'] +['æľ', 'ĭ'] +['éĿ', '©'] +['å®', '£'] +['çł', '´'] +['è½', '»'] +['åº', '§'] +['æĺ', '¾'] +['ç¨', '³'] +['è´', 'µ'] +['èĥ', 'Į'] +['èī', '¯'] +['çĸ', '«'] +['æ¯', 'Ĵ'] +['ä¹', 'İ'] +['åĢ', 'Ł'] +['è¿', '·'] +['çŃ', 'Ķ'] +['æ¿', 'Ģ'] +['åij', '¼'] +['äºĨ', 'ä¸Ģ'] +['è¶', '£'] +['ä¼', '´'] +['ä¼', 'Ļ'] +['è', '¼'] +['ð¬', 'Ń'] +['åĽ½', 'å®¶'] +['æ´»', 'åĬ¨'] +['çݰ', 'åľ¨'] +['ç§ij', 'æĬĢ'] +['åį', '¡'] +['ä¸į', 'åIJĮ'] +['个', '人'] +['è®°', 'èĢħ'] +['ä¸į', 'æĸŃ'] +['éĹ', '»'] +['ä¹', 'Ŀ'] +['èij', 'Ĺ'] +['ç»', '¼'] +['ä¸', 'ĥ'] +['æł', 'ij'] +['æľĭ', 'åıĭ'] +['åį', 'ĸ'] +['ä¼', '¤'] +['æ²', 'Ļ'] +['åĸ', 'Ħ'] +['å¥', 'Ĺ'] +['è½', '®'] +['ç©', '¿'] +['è¡', '¥'] +['ä¸Ģ', 'å®ļ'] +['çª', 'ģ'] +['çĿ', '£'] +['è¿', '½'] +['å¨', 'ģ'] +['åı', '¦'] +['åĽ', '°'] +['æŀ', '¶'] +['ç»', 'Ŀ'] +['æķ', '£'] +['æİ', '¢'] +['æ´', 'Ĺ'] +['ä¸', '´'] +['ä¼', '¼'] +['è´', '¸'] +['ä¸', '°'] +['æĺ¯', 'ä¸Ģ'] +['ç«', 'ŀ'] +['è¿', 'İ'] +['èģ', 'ļ'] +['è', '«'] +['æį', 'Ł'] +['æī', '§'] +['é©', '¾'] +['è¿', 'Ŀ'] +['è', '¥'] +['è', 'ł'] +['ä»ĸ', '们'] +['æĹ¶', 'åĢĻ'] +['å®', 'ĥ'] +['人', 'åijĺ'] +['è¿Ļ', 'æł·'] +['å·¥', 'ç¨ĭ'] +['åĪĽ', 'æĸ°'] +['åŃ©', 'åŃIJ'] +['å¸', 'Į'] +['éĥ¨', 'åĪĨ'] +['éĵ', '¶'] +['代', '表'] +['é¦', 'Ļ'] +['å¸', '®'] +['æİ¨', 'è¿Ľ'] +['çĽ', 'ĺ'] +['积', 'æŀģ'] +['éĥ¨', 'éŨ'] +['åŁ', '¹'] +['æŃ', '¦'] +['ä¸į', 'ä¼ļ'] +['çŃ', 'ij'] +['éĢ', 'Ļ'] +['çİ©', 'å®¶'] +['æĭ', '¿'] +['åİ', 'Ĥ'] +['æ¯', 'Ľ'] +['çģ', 'µ'] +['æŃ', 'Į'] +['ç', '»¿'] +['å¦', 'Ī'] +['çĽ', 'Ľ'] +['é¦', 'Ĩ'] +['é¡', 'º'] +['èĦ', '¸'] +['å°', '¼'] +['ä¸', '½'] +['å¥', '¥'] +['éģ', 'ĩ'] +['è¯', 'į'] +['å°', 'ģ'] +['ä¸', 'Ŀ'] +['好', 'çļĦ'] +['æĭ', 'ħ'] +['èĦ', '±'] +['æģ', '¶'] +['åİ', 'ļ'] +['åĬ', '³'] +['çĽ', 'Ł'] +['æĬ', 'ĺ'] +['åı', '¥'] +['æĢ', 'Ģ'] +['æŁ', 'ĵ'] +['书', 'è®°'] +['åĨ', 'ł'] +['é²', 'ľ'] +['æ', '¦Ĥ'] +['éļ', 'IJ'] +['å¹', 'ħ'] +['èµ', 'ŀ'] +['å¹', 'ķ'] +['æ¥', 'Ń'] +['éģ', 'Ĺ'] +['åĪ', '¤'] +['è', 'ĺ'] +['å', '¶'] +['æĬķ', 'èµĦ'] +['è¡Į', 'ä¸ļ'] +['äº', 'ij'] +['çݯ', 'å¢ĥ'] +['åѦ', 'çĶŁ'] +['åIJĪ', 'ä½ľ'] +['åģ¥', '康'] +['é£', 'ŀ'] +['ä¸Ģ', 'æŃ¥'] +['ä¸Ģ', '缴'] +['åıij', 'çĶŁ'] +['éĺ', '¿'] +['é¢Ĩ', '导'] +['åĸľ', '欢'] +['åºĶ', '该'] +['çĤ', 'º'] +['è®', 'Ń'] +['æĿ', 'Ģ'] +['æ¸', '¯'] +['交', 'éĢļ'] +['éĺ', '¶'] +['éĴ', '¢'] +['ä»', '¤'] +['å°', '½'] +['æ¯', 'į'] +['è¡', '£'] +['ç²', 'ī'] +['é¡', '¶'] +['ä¹Ł', 'ä¸į'] +['æĬ', 'ĵ'] +['èĭ', '¦'] +['å¹', '¸'] +['ç¤', '¼'] +['第', 'ä¸ī'] +['大', 'çļĦ'] +['éģ', 'İ'] +['çĥ', 'Ł'] +['éģ', '¿'] +['ä»', 'į'] +['åº', 'Ĩ'] +['æĢ', 'ķ'] +['è°', '¢'] +['çĽ', 'ĸ'] +['å°', 'Ħ'] +['éľ', '²'] +['æĸ', 'Ĺ'] +['ç', 'Ĭ¶'] +['åŃ', '¸'] +['æ¯', 'ķ'] +['å·', '¨'] +['çŁ', '¿'] +['çļ', 'ĩ'] +['å¸', 'Ń'] +['çĹ', 'ĩ'] +['æī', '¬'] +['å»', '¶'] +['ä¾', '§'] +['æ·', '¡'] +['çļĦ', 'ä¸Ģ'] +['ç¶', '²'] +['æ´', 'ģ'] +['ç', '¸'] +['è§', 'Ī'] +['çŃ', '¹'] +['ç§', 'ĺ'] +['è¯', 'Ĭ'] +['çı', '¾'] +['èª', 'ī'] +['æ¯', '«'] +['ð', '¨'] +['åį', '´'] +['æĪIJ', '为'] +['èĥ½', 'åĬĽ'] +['é»', 'Ħ'] +['æĹħ', '游'] +['èĪ', '¬'] +['æ¯Ķ', 'è¾ĥ'] +['èµ·', 'æĿ¥'] +['äºĨ', 'è§£'] +['èĩª', 'çĦ¶'] +['ä¸Ģ', '次'] +['åŁº', 'æľ¬'] +['æĽ', '¾'] +['综', 'åIJĪ'] +['èı', 'ľ'] +['è§ī', 'å¾Ĺ'] +['第', 'äºĮ'] +['è·', 'ij'] +['æ³', '¢'] +['åĢ', 'Ĵ'] +['ç¡', 'Ģ'] +['åħ', 'µ'] +['èį', 'ī'] +['çĶ', '³'] +['çĶ', '°'] +['æĤ', '£'] +['è§Ħ', 'å®ļ'] +['èĥ', 'ľ'] +['èµĦ', '产'] +['æ¢', '¦'] +['æľ', 'Ŀ'] +['è¿Ļ', 'éĩĮ'] +['å¤', '«'] +['æĮ', '¥'] +['ä½', 'Ľ'] +['å®', 'Ī'] +['éĽ', '¶'] +['æĸ', '¼'] +['ç¯', 'ĩ'] +['å²', 'Ľ'] +['åĵ', '¥'] +['éŃ', 'Ķ'] +['ä¸į', 'åΰ'] +['æī', 'ĺ'] +['åº', 'Ĭ'] +['æ¬', '§'] +['èį', '£'] +['æ±', 'ĩ'] +['æī', '©'] +['åģ', 'ı'] +['å¢', 'Ļ'] +['è®', '¯'] +['å©', 'ļ'] +['æĥ', 'ł'] +['æ´', 'ĭ'] +['å®', 'ľ'] +['æ¶', '¦'] +['æħ', '¢'] +['éĢ', 'ı'] +['å®', '½'] +['é¡', '¾'] +['ç´', '¯'] +['æ±', '¡'] +['çĪ', 'Ĩ'] +['ç§', 'Ł'] +['æĥ', 'Ĭ'] +['æ¶', '¨'] +['é¥', '°'] +['éĺ', 'µ'] +['é¥', '®'] +['æļ', 'ĸ'] +['åº', 'Ł'] +['æĹ', 'Ĺ'] +['éļ', 'Ķ'] +['ç¶', 'ĵ'] +['åĭ', 'Ļ'] +['å¯', '¦'] +['éĢ', 'Ķ'] +['æī', '«'] +['çĥ', 'Ī'] +['éĽ', '»'] +['åĪ', 'ij'] +['éĹ', 'ľ'] +['éĹ', 'ª'] +['å¥', 'ĭ'] +['å', 'Ĥ¨'] +['ç¼', '©'] +['ä¾', 'µ'] +['å', '¬'] +['ð¬', '¶'] +['åĽ½', 'éĻħ'] +['ç»Ħ', 'ç»ĩ'] +['ä¸ĵ', 'ä¸ļ'] +['åıij', 'çݰ'] +['å¸Į', 'æľĽ'] +['ç»ı', 'èIJ¥'] +['åı', '«'] +['æĿ¥', '说'] +['éļ', 'ľ'] +['ä»»', 'ä½ķ'] +['交', 'æĺĵ'] +['éĩį', 'çĤ¹'] +['çļ', '®'] +['ç»', 'į'] +['æ´', '¾'] +['ç§ij', 'åѦ'] +['åºĶ', 'ç͍'] +['建', 'çŃij'] +['èĤ', 'ī'] +['æĶ¹', 'éĿ©'] +['åŁº', 'ç¡Ģ'] +['æ±', 'ī'] +['åĩº', 'æĿ¥'] +['è¿Ļ', 'ä¹Ī'] +['åĪ', 'ļ'] +['åĿ', 'IJ'] +['ä¸į', 'ä»ħ'] +['ä¼ļ', 'è®®'] +['éĿ', 'ł'] +['åªĴ', 'ä½ĵ'] +['æ°', '¸'] +['åĨ', '²'] +['èĭ', 'ı'] +['å¤', '®'] +['çĪ', '¶'] +['åł', 'Ĥ'] +['å®ŀ', 'éĻħ'] +['è¡', 'Ĺ'] +['ç«', '¥'] +['éĺ', 'ħ'] +['äºĭ', 'æĥħ'] +['åİŁ', 'åĽł'] +['éħ', '¸'] +['以', 'æĿ¥'] +['å¨', '±'] +['å®', '«'] +['åĿ', 'Ĺ'] +['ç»', '©'] +['éĩ', 'İ'] +['ä¸į', 'å¾Ĺ'] +['ä¼ł', 'å¥ĩ'] +['ç¡', '¬'] +['åİ', 'ħ'] +['æĹ', '¢'] +['ç»', 'ĥ'] +['èĦ', 'ij'] +['å¼', '±'] +['æİ', 'Į'] +['è´', '´'] +['æĮ', 'Ĥ'] +['åħ³', 'éĶ®'] +['å°', 'ļ'] +['é¥', 'Ń'] +['åº', 'Ħ'] +['çĻ', '¼'] +['åľ', 'ĭ'] +['æİ', 'Ī'] +['个', 'æľĪ'] +['äº', 'Ī'] +['å¸', 'ģ'] +['è·', 'Ŀ'] +['æ²', 'ī'] +['ç«', 'Ł'] +['åĨ', '¬'] +['æĬ', '½'] +['éĨ', 'Ĵ'] +['å¼', 'Ł'] +['è§', '¦'] +['èģ', 'ĺ'] +['è±', 'Ĩ'] +['æļ', '´'] +['åijĬ', 'è¯ī'] +['è±', 'ª'] +['èµ', '¢'] +['è·', '¨'] +['è³', 'ĩ'] +['çĪ', '¸'] +['æĬ', '±'] +['æµ', 'ª'] +['éº', '»'] +['ä»', 'ª'] +['è¡', '¡'] +['å¥', '¶'] +['çģ', '¾'] +['èµ', '¶'] +['èĤ', '¥'] +['å§', 'IJ'] +['åĢ', 'º'] +['éľ', 'ĩ'] +['è®', '¢'] +['æ¬', 'Ĭ'] +['ç', '·'] +['å»', 'ī'] +['ä¿', 'Ĺ'] +['å¿', 'ĺ'] +['å¦', 'ĩ'] +['ç¼', 'ĵ'] +['åŃ', 'ķ'] +['æ¼', '«'] +['è£', 'ģ'] +['çĩ', 'ĥ'] +['é»', 'ĺ'] +['çī', '¢'] +['çĪ', '·'] +['æĬ', 'µ'] +['å®', '¾'] +['æľī', 'ä¸Ģ'] +['è¿', '¹'] +['è¿', '«'] +['è²', 'Į'] +['æľī', 'çļĦ'] +['ð¬', 'ĺ'] +['è¿ĺ', 'æĺ¯'] +['æīĢ', '以'] +['ä¹Ł', 'æĺ¯'] +['è¿Ļ', 'äºĽ'] +['对', 'äºİ'] +['åIJ', '§'] +['缮', 'åīį'] +['èĩªå·±', 'çļĦ'] +['èĥ½', 'å¤Ł'] +['å¦Ĥ', 'ä½ķ'] +['æľº', 'æŀĦ'] +['åıª', 'æĺ¯'] +['ç½ij', 'ç«Ļ'] +['åħ¨', 'éĿ¢'] +['为', 'äºĨ'] +['å¼Ģ', 'åıij'] +['æĸ°', 'éĹ»'] +['éĩij', 'èŀį'] +['ç»', '§'] +['客', 'æĪ·'] +['ä¸Ģ', 'èµ·'] +['èĮ', '¶'] +['åħ³', '注'] +['æ°´', 'å¹³'] +['åİĨ', 'åı²'] +['å¢ŀ', 'éķ¿'] +['é', '±'] +['åŁº', 'éĩij'] +['åº', 'Ń'] +['åı', '¶'] +['ä¿', 'ĥ'] +['éĽ', '¨'] +['æ¶Ī', 'è´¹'] +['èĪ', '¹'] +['çŁ¥', 'è¯Ĩ'] +['æĪĺ', 'çķ¥'] +['ç»ı', 'éªĮ'] +['å³', '°'] +['æĽ', '²'] +['èĦ', 'ļ'] +['åĨ', '°'] +['å¤', 'ı'] +['å½', 'Ĵ'] +['ç¬', 'Ķ'] +['èĻ', 'ij'] +['çĶ', '²'] +['åľ', 'Ī'] +['è¯', 'Ĺ'] +['é½', 'IJ'] +['容', 'æĺĵ'] +['çłĶ', 'åıij'] +['éª', '¨'] +['çº', '¸'] +['è·', 'µ'] +['æĹ', '§'] +['çķ', '¶'] +['åĪ', '¸'] +['è´', '·'] +['åı', '¬'] +['ç§', 'ĭ'] +['æ¶', '²'] +['è¡Į', 'æĶ¿'] +['çĮ', '®'] +['èĤ', '¤'] +['éĢ', 'IJ'] +['è¶Ĭ', 'æĿ¥'] +['è¶ĬæĿ¥', 'è¶Ĭ'] +['æĦı', 'è§ģ'] +['èĪ', 'ŀ'] +['åī', 'Ĥ'] +['æ¶', 'ī'] +['ç¨ĭ', '度'] +['åħ¬', 'åħ±'] +['æ¢', '°'] +['æľ', '«'] +['çº', '¯'] +['åĶ', '±'] +['æ´', '²'] +['æĬ', '¢'] +['æ¤', 'į'] +['å¿', 'Ļ'] +['ä¼', '°'] +['å¼', '¹'] +['æ³', 'ī'] +['æľĢ', '大'] +['è¶', 'ĭ'] +['å·', '§'] +['ç¦', 'ģ'] +['æī', '¶'] +['åį', '±'] +['çı', 'ł'] +['çĨ', 'Ł'] +['æĭ', 'ľ'] +['主', 'ä¹ī'] +['æĿ', 'Ĥ'] +['éĻ', 'Ħ'] +['éģ', 'į'] +['æIJ', 'Ń'] +['æĮ', '¯'] +['å¤ļ', 'å¹´'] +['æķ', '¬'] +['æij', 'Ħ'] +['çº', '·'] +['å¼', 'ĥ'] +['æ¹', '¿'] +['å¨', 'ĺ'] +['æ¡', '£'] +['é©', '¶'] +['æľ', 'Ĺ'] +['æ®', 'ĸ'] +['æ¦', 'ľ'] +['åĵ', '¡'] +['ä¸Ģ', 'ä½ĵ'] +['æŁ¥', 'çľĭ'] +['ç¹', 'ģ'] +['æµ', 'ĵ'] +['åħ¬', 'å®ī'] +['æ½', 'ľ'] +['è´', '¯'] +['éª', 'Ĺ'] +['æ', 'IJľ'] +['å·', '¡'] +['è', '¬'] +['é', 'Ĭ'] +['å§Ķ', 'ä¼ļ'] +['æĤ', 'ł'] +['åī', '©'] +['æı', 'Ń'] +['åŃ£', '度'] +['ð', '«ĺ'] +['ð¬', '¬'] +['ä', '´'] +['ð', 'ª'] +['ä½Ĩ', 'æĺ¯'] +['éĥ½', 'æĺ¯'] +['å¹³', 'åı°'] +['åѦ', 'ä¹ł'] +['åĵģ', 'çīĮ'] +['ä¸', 'Ķ'] +['è¿Ļ', 'ç§į'] +['æĶ¿', 'çŃĸ'] +['æĭ', '¬'] +['认', '为'] +['ä¸Ģ', 'èά'] +['æłĩ', 'åĩĨ'] +['æĶ¯', 'æĮģ'] +['模', 'å¼ı'] +['åħ³', 'ç³»'] +['çļĦ', 'æĺ¯'] +['è¿Ļ', 'ä¸Ģ'] +['ä¸į', 'è¦ģ'] +['çĶ', 'ļ'] +['ç²¾', 'ç¥ŀ'] +['æĭ', '¥'] +['åĪ©', 'ç͍'] +['ä¿Ŀ', 'æĬ¤'] +['ä½ľ', 'ç͍'] +['èĭ', '¥'] +['åĽ½', 'åĨħ'] +['ä»ĭ', 'ç»į'] +['ä¸Ģ', 'ä¸ĭ'] +['å·¥', 'ä¸ļ'] +['缮', 'æłĩ'] +['æľĢ', 'åIJİ'] +['ä»·', 'å̼'] +['å°', 'į'] +['éĵ', 'ģ'] +['è°', 'ģ'] +['ç»ĵ', 'æŀĦ'] +['éĽ', 'ª'] +['æĻº', 'èĥ½'] +['ä¼ł', '绣'] +['ä½ĵ', 'èĤ²'] +['çĶŁ', 'æĢģ'] +['æĭ', 'į'] +['æİ', 'ª'] +['åĨľ', 'ä¸ļ'] +['çī¹', 'èī²'] +['è§Ħ', '模'] +['æĹ¶', '代'] +['è¿ĩ', 'ç¨ĭ'] +['éĴ', 'Ī'] +['æĿ', '¾'] +['åĶ', 'IJ'] +['åĮ»', 'çĸĹ'] +['çģ', '¯'] +['åζ', 'éĢł'] +['æł¸', 'å¿ĥ'] +['ä¸į', 'åı¯'] +['ç³»', 'åĪĹ'] +['åIJ', 'ī'] +['åľ', '£'] +['åĢ', 'ij'] +['ä½', '³'] +['æĿ¥', 'çľĭ'] +['æ¯Ķ', 'èµĽ'] +['ä¸ĭ', 'æĿ¥'] +['åĩº', 'äºĨ'] +['å¹²', 'éĥ¨'] +['å¾®', 'ä¿¡'] +['å½ĵ', 'åľ°'] +['åį', '·'] +['åį«', 'çĶŁ'] +['ä¼', 'Ł'] +['çĸ«', 'æĥħ'] +['è°', '·'] +['åĩł', '个'] +['éĺ', '´'] +['çĶŁ', 'çī©'] +['å°', '¤'] +['ä¼', 'Ĭ'] +['èĤ', '¯'] +['éĿ¢', '积'] +['åĪĽ', 'éĢł'] +['æı', '¡'] +['åľ', 'Ĩ'] +['æĻ', 'ĵ'] +['æĪIJ', 'äºĨ'] +['åĩ', '¡'] +['çĸ', '¾'] +['ç«ŀ', 'äºī'] +['è®', '¨'] +['主', 'é¢ĺ'] +['é²', 'ģ'] +['è¿', 'ª'] +['ä¿', 'Ħ'] +['æĢ', 'ª'] +['ä¸', '¦'] +['èĻ', 'ļ'] +['æ½', '®'] +['çĥ', '§'] +['èĢ', '³'] +['æ±', 'ł'] +['éĢĤ', 'åIJĪ'] +['æł¹', 'æľ¬'] +['åĬł', '缣'] +['ç͵', 'è§Ĩ'] +['æ·', '·'] +['ç¼', 'ĺ'] +['çª', 'Ĺ'] +['çĬ', '¯'] +['æĥ', '¯'] +['æĦı', 'ä¹ī'] +['åĬŀ', 'æ³ķ'] +['ä¼', 'ij'] +['æ»', 'ij'] +['åĭ', 'ĩ'] +['æķ', '¢'] +['å¯', '»'] +['è¦', 'Ĩ'] +['éĢ', 'ĥ'] +['ç»ı', 'çIJĨ'] +['åĿ', 'ı'] +['æ³', '½'] +['ä¹', 'ĺ'] +['åĪ', 'º'] +['å±', 'ı'] +['é¡', '¿'] +['äº', '¡'] +['éĤ', 'Ģ'] +['åħ', '¼'] +['åĭ', '¤'] +['æ®', 'ĭ'] +['æĺ', 'ł'] +['æ¯ķ', 'ä¸ļ'] +['æĪ', 'ª'] +['è·', 'Į'] +['å£', 'ģ'] +['åı¦', 'ä¸Ģ'] +['羣', 'å®ŀ'] +['ç£', '¨'] +['è¯', 'ļ'] +['å¿ħ', 'è¦ģ'] +['æģ', 'ĭ'] +['æĩ', 'Ĥ'] +['å¾', 'Ĵ'] +['è°', 'ĵ'] +['æķ', 'ı'] +['æ', 'ύ'] +['èĥ', '¸'] +['æĭ', '¼'] +['å¦', 'Ļ'] +['è¯', '¸'] +['èģ', 'Ĭ'] +['æĤ', 'ī'] +['éº', '¼'] +['åĩ', 'Ń'] +['èĪ', 'Ĵ'] +['æ¶', 'Ĥ'] +['è¿', 'ģ'] +['æ²', '¿'] +['å¡', 'ij'] +['æĽ', '¿'] +['æ¾', '³'] +['å¿', 'į'] +['èĢ', 'Ĺ'] +['éľ', '¸'] +['åĩł', 'å¹´'] +['åĪ', 'Ĭ'] +['èĦ', 'ī'] +['èħ', 'IJ'] +['æ¡', 'Į'] +['çº', 'ł'] +['æ»', 'ļ'] +['æĤ', '²'] +['åĨ', 'Ĵ'] +['å¦', '¹'] +['çķ', 'ħ'] +['çº', 'µ'] +['æij', 'ĩ'] +['å¤', 'º'] +['è·¯', 'ä¸Ĭ'] +['å¿', '½'] +['èĸ', 'ª'] +['æģ', 'IJ'] +['æĦı', 'æĢĿ'] +['å«', 'Į'] +['æı', '´'] +['æ°', '§'] +['èĢ', 'Ģ'] +['éĺ', '»'] +['è½', '¨'] +['å¹', '»'] +['æį', 'ķ'] +['åĿ', '¦'] +['åĵĪ', 'åĵĪ'] +['çĭ', 'IJ'] +['æ»', '¨'] +['è²', '»'] +['è¿', 'Ł'] +['人', 'éĥ½'] +['ç»', 'ĺ'] +['åı', '¹'] +['çµ', 'IJ'] +['æī', '°'] +['æ»', 'ĭ'] +['å¥', 'ij'] +['åĭ', 'Ł'] +['ç¢', 'º'] +['ð', '¦'] +['éĽĨ', 'åĽ¢'] +['æĿ', 'İ'] +['å¼Ģ', 'å±ķ'] +['æıIJ', 'åįĩ'] +['åħ¨', 'åĽ½'] +['æ±½', '车'] +['åѦ', 'æł¡'] +['æł¹', 'æį®'] +['è¿Ļ', 'æĺ¯'] +['åĩº', 'çݰ'] +['éĻ', 'Ī'] +['ç½', 'Ĺ'] +['èİ·', 'å¾Ĺ'] +['åĪ', 'ĺ'] +['éĶĢ', 'åĶ®'] +['æľª', 'æĿ¥'] +['éľĢ', 'æ±Ĥ'] +['å®ŀ', 'æĸ½'] +['åĿļ', 'æĮģ'] +['åħ¨', 'çIJĥ'] +['éĵ¶', 'è¡Į'] +['æİ§', 'åζ'] +['é¡', '»'] +['åľ°', 'åĮº'] +['æīĵ', 'éĢł'] +['çļĦ', 'è¯Ŀ'] +['帮', 'åĬ©'] +['ä½ĵ', 'ç³»'] +['è¾¾', 'åΰ'] +['è§Ħ', 'åĪĴ'] +['åŁ¹', 'è®Ń'] +['两', '个'] +['æĬ¥', 'åijĬ'] +['åľ°', 'æĸ¹'] +['å®Į', 'åħ¨'] +['æİ', 'ī'] +['ç»ĵ', 'åIJĪ'] +['宣', 'ä¼ł'] +['æ³ķ', 'å¾ĭ'] +['èīº', 'æľ¯'] +['ç͵', 'å½±'] +['èª', 'ª'] +['ä¸Ģ', 'çĤ¹'] +['è¶ħ', 'è¿ĩ'] +['ç͵', 'åŃIJ'] +['æĢĿ', 'æĥ³'] +['æķĻ', 'åѦ'] +['éĺ¶', '段'] +['åķĨ', 'ä¸ļ'] +['çī©', 'æµģ'] +['åĪĽ', 'ä¸ļ'] +['æĸ¹', 'æ¡Ī'] +['çݰ', '代'] +['æ¡', '¥'] +['èIJ½', 'å®ŀ'] +['带', 'æĿ¥'] +['产', 'çĶŁ'] +['ç§', 'Ģ'] +['æ³', '°'] +['ä¹', '±'] +['åħ·', 'ä½ĵ'] +['åĸ', 'Ŀ'] +['èĵ', 'Ŀ'] +['å®', 'Ĺ'] +['åįĩ', '级'] +['æ·±', 'åħ¥'] +['ä¿Ŀ', 'éĻ©'] +['ç®Ģ', 'åįķ'] +['çĹ', 'Ľ'] +['稳', 'å®ļ'] +['è¾', 'Ĩ'] +['å±ŀ', 'äºİ'] +['å·', 'Ŀ'] +['ä¸į', 'å°ij'] +['åĴ', '¨'] +['举', '西'] +['å½¢', 'å¼ı'] +['娱', 'ä¹IJ'] +['æŃ£', '常'] +['é¸', '¡'] +['åħħ', 'åĪĨ'] +['å®ŀ', 'è·µ'] +['éĩĮ', 'éĿ¢'] +['è·', '³'] +['èĻ', 'İ'] +['æĪIJ', 'éķ¿'] +['æļ', 'Ĺ'] +['çĿ', '¡'] +['ç½', 'ª'] +['çIJĨ', '念'] +['æĮ', 'ij'] +['èµĦ', 'æľ¬'] +['å¤ļ', 'å°ij'] +['ä¸ĭ', 'éĿ¢'] +['å¸', 'Ŀ'] +['åħ¬', 'å¼Ģ'] +['æ¸', 'IJ'] +['éķ', '·'] +['å±', 'ĭ'] +['欢', 'è¿İ'] +['å¿ĥ', 'çIJĨ'] +['çĤ', 'İ'] +['æ¹', '¾'] +['è®', 'ĵ'] +['éĤ', 'Ħ'] +['ç³', 'ĸ'] +['ä¹', 'Į'] +['åĬ', '±'] +['çī', 'Ļ'] +['èħ', '¿'] +['å²', 'Ĺ'] +['ä¼', 'į'] +['æĪIJ', 'åijĺ'] +['åŃ', 'Ķ'] +['å°ı', 'ç¼ĸ'] +['èij', '£'] +['æ³', '¡'] +['åħĪ', 'è¿Ľ'] +['åħ', '§'] +['åĺ', '´'] +['è´', 'Ŀ'] +['è', '»'] +['æIJ', 'ŀ'] +['æ³', 'Ľ'] +['é¸', 'Ł'] +['ç½', '²'] +['èĽ', 'ĭ'] +['主', 'ä»»'] +['缮', 'çļĦ'] +['ä¹', 'ı'] +['æ´', '¥'] +['æĪ', '´'] +['严', 'æł¼'] +['çħ', '¤'] +['çĮ', '«'] +['åĶ', '¯'] +['å°', 'Ĭ'] +['çĶ', 'ľ'] +['åŀ', 'ĥ'] +['åľ', '¾'] +['æĭ', 'Ł'] +['çĦ', '¦'] +['é«', 'Ķ'] +['å®', 'ı'] +['æ©', 'Ł'] +['é©', '»'] +['æĹ', 'ģ'] +['å½', '»'] +['éĥ½', 'ä¸į'] +['æij', '©'] +['ä»', 'ĵ'] +['ä¹', '³'] +['å²', '¸'] +['è°', 'ĭ'] +['大', 'å¤ļ'] +['çģ', 'Ń'] +['èħ', '¾'] +['æŁ', 'ľ'] +['èĪ', 'į'] +['åħļ', 'çļĦ'] +['å°', 'ĺ'] +['åįģ', 'å¹´'] +['æĭ', 'Ĵ'] +['è£', '¡'] +['æŁ', 'Ķ'] +['å¹', '¼'] +['éĶ', 'ģ'] +['ä¸ĵ', '项'] +['æī', 'İ'] +['驾', 'é©¶'] +['ç¢', 'İ'] +['è¢', 'ĭ'] +['éĶ', 'ĭ'] +['å£', '®'] +['å°', 'ĸ'] +['ç͵', 'æ±ł'] +['è¿', 'Ķ'] +['æ¼', 'ı'] +['å¾', 'ª'] +['èı', 'Į'] +['èĥ', 'ĥ'] +['è¾', 'ħ'] +['éĢ', 'Ĵ'] +['èĥ', 'İ'] +['éĻ', 'ª'] +['å¯', '¿'] +['å¥', 'Ķ'] +['çĮ', 'Ľ'] +['çº', '¹'] +['çŁ¥', 'åIJį'] +['å¿', 'Ĩ'] +['æ¡', 'ĥ'] +['æ£', 'ĭ'] +['éĢ', 'Ĩ'] +['çĤ', '¼'] +['ç±', 'į'] +['çī', '§'] +['æł·', 'çļĦ'] +['è¾', 'Ľ'] +['åł', 'Ĩ'] +['å®ŀ', 'åľ¨'] +['ä¼', 'ı'] +['å®', '¿'] +['èµ', 'ı'] +['è£', 'Ĥ'] +['åįĬ', 'å¹´'] +['åĢ', '¾'] +['满', 'æĦı'] +['æ¢', '¯'] +['æĦı', 'åij³'] +['åŃ', '¤'] +['ç¥', 'Ŀ'] +['æĻ', '¶'] +['èµ', 'Ķ'] +['åģ', '¿'] +['èĦ', 'Ĥ'] +['ç½', 'ļ'] +['ç¢', 'į'] +['æ²', 'ĥ'] +['æ', 'ĵį'] +['å´', 'ĩ'] +['æļ', 'Ĥ'] +['è·', 'ĥ'] +['æIJ', '¬'] +['å©', 'Ĩ'] +['é', 'ī'] +['éī', '´'] +['åħ´', 'è¶£'] +['èIJ¥', 'ä¸ļ'] +['è®', 'Ĭ'] +['èĦ', 'ı'] +['è¾', 'Ī'] +['å·ŀ', 'å¸Ĥ'] +['è´«', 'åĽ°'] +['ç©', '·'] +['ä¸Ń', 'å°ı'] +['æ¼', 'Ĥ'] +['çĻ', 'Į'] +['èľ', 'ľ'] +['ä¼Ļ', 'ä¼´'] +['çī', 'µ'] +['æĤ', 'Ł'] +['éĻ', '·'] +['èµĽ', 'åŃ£'] +['æ¨', '£'] +['åģ', '¶'] +['æĺ', 'Ĩ'] +['è¢', 'Ń'] +['æį', 'IJ'] +['èī', '°'] +['æ', 'Ĥ¬'] +['çĶ', '¢'] +['èij', '¡'] +['çĽ', 'Ĺ'] +['å©', '´'] +['å°', 'İ'] +['çº', '½'] +['åĢ', '¡'] +['æī', '®'] +['è¨', 'Ń'] +['æĬ', 'ij'] +['ç¡', 'ķ'] +['è¾', 'ĸ'] +['éĥ', 'ģ'] +['è¾', '©'] +['éĤ', '»'] +['çݰ', 'åĩº'] +['è¦', 'ı'] +['å½', '¹'] +['éĺ', 'Ķ'] +['åī', 'µ'] +['è¯', '±'] +['æĥ', 'ij'] +['æ·', 'Ģ'] +['é¢', 'Ī'] +['ä¾', '¦'] +['æģ', '°'] +['æ£Ģ', 'å¯Ł'] +['éĨ', '«'] +['çĦ¶', 'æĺ¯'] +['åĭ', 'ĥ'] +['èĮ', '«'] +['ä', 'ĵ'] +['ð', '¬¸'] +['ä½ľ', '为'] +['çļĦ', '人'] +['éĤ£', 'ä¹Ī'] +['ç¾İ', 'åĽ½'] +['è¿ĺ', 'æľī'] +['æıIJ', 'é«ĺ'] +['èĻ', '½'] +['åħ·', 'æľī'] +['åĮħ', 'æĭ¬'] +['æĪĸ', 'èĢħ'] +['ä¸į', 'è¿ĩ'] +['ä¸Ĭ', 'æµ·'] +['åĮ»', 'éĻ¢'] +['èµĦ', 'éĩij'] +['çĶļ', 'èĩ³'] +['åζ', '度'] +['è§£', 'åĨ³'] +['èģĶ', 'ç½ij'] +['ç»§', 'ç»Ń'] +['建', 'ç«ĭ'] +['è¿Ľ', 'ä¸ĢæŃ¥'] +['æĿIJ', 'æĸĻ'] +['ä»Ĭ', '天'] +['å¿ħ', 'é¡»'] +['åIJĦ', 'ç§į'] +['çݰ', 'åľº'] +['ä»ĸ', 'çļĦ'] +['å¢ŀ', 'åĬł'] +['é¢Ĩ', 'åŁŁ'] +['åıĤ', 'ä¸İ'] +['æĮģ', 'ç»Ń'] +['ä¹ĭ', 'ä¸Ģ'] +['çī¹', 'åĪ«'] +['é±', '¼'] +['åħ±', 'åIJĮ'] +['åĬ', 'ª'] +['çİ', 'ī'] +['人', '们'] +['åħĪ', 'çĶŁ'] +['ä¼ĺ', 'åĬ¿'] +['ä¿Ŀ', 'æĮģ'] +['ä½ľ', 'åĵģ'] +['çī', 'Ľ'] +['æĪIJ', 'æľ¬'] +['æĶ¶', 'åħ¥'] +['åıĬ', 'æĹ¶'] +['è´Ł', 'è´£'] +['æİ¥', 'åıĹ'] +['èį', 'IJ'] +['åıª', 'è¦ģ'] +['羣', 'çļĦ'] +['导', 'èĩ´'] +['æľº', 'åζ'] +['è¡Į', 'åĬ¨'] +['æĸ°', 'çļĦ'] +['å®Į', 'åĸĦ'] +['为', 'ä»Ģä¹Ī'] +['ä¸Ń', '央'] +['æĪIJ', 'ç«ĭ'] +['æĦŁ', 'è§ī'] +['åıĺ', 'åĮĸ'] +['åıĹ', 'åΰ'] +['å¹¶', 'ä¸į'] +['åŃ', 'Ļ'] +['æĸ½', 'å·¥'] +['æĺİ', 'æĺ¾'] +['è¿ĩ', 'åİ»'] +['åıij', 'æĮ¥'] +['羣', 'æŃ£'] +['åŁº', 'åľ°'] +['æĺİ', 'ç¡®'] +['èĥ', '¡'] +['许', 'å¤ļ'] +['ä¸Ģ', 'å¹´'] +['æĸ¹', 'åIJij'] +['æģ', '©'] +['缸', 'ä¿¡'] +['åľ', '³'] +['详', 'ç»Ĩ'] +['äºĭ', 'ä¸ļ'] +['çĶŁ', 'åij½'] +['åĴ¨', '询'] +['æĸĩ', 'æĺİ'] +['çij', 'ŀ'] +['绿', 'èī²'] +['èİ', '«'] +['æĦı', 'è¯Ĩ'] +['æĬķ', 'åħ¥'] +['åĬł', 'å¿«'] +['æ¢', 'ħ'] +['ç¿', '»'] +['å¼Ģ', 'æĶ¾'] +['æĻ®', 'éĢļ'] +['åįı', 'ä¼ļ'] +['æĪIJ', '绩'] +['ä»', 'Ļ'] +['å¯', 'Ĵ'] +['è¯ģ', 'åΏ'] +['认', 'è¯Ĩ'] +['ä¸', '¹'] +['大', 'éĩı'] +['è¿', 'ħ'] +['åģļ', 'åΰ'] +['设', 'æĸ½'] +['è´¸', 'æĺĵ'] +['èĥ½', 'æºIJ'] +['æĹ¶', 'æľŁ'] +['ä¸Ģ', '天'] +['æ²»', 'çIJĨ'] +['åĺ', 'ī'] +['å®', 'ĩ'] +['丰', 'å¯Į'] +['举', 'è¡Į'] +['æĪIJ', 'æŀľ'] +['èĤ¯', 'å®ļ'] +['çĭ', 'Ĺ'] +['åĬ¨', 'åĬĽ'] +['æ£', '®'] +['åĩł', 'ä¹İ'] +['åĽł', 'ç´ł'] +['æ°ij', 'æĹı'] +['æ´', 'ŀ'] +['ç½ij', 'åıĭ'] +['åIJĪ', 'çIJĨ'] +['广', '大'] +['æ®', 'Ĭ'] +['æ´', 'Ľ'] +['æĿ', '¯'] +['èĴ', 'Ļ'] +['ç͍', 'äºİ'] +['èŀį', 'èµĦ'] +['ç¥', 'ĸ'] +['æľº', '械'] +['举', 'åĬŀ'] +['èĩª', 'åĬ¨'] +['åĬŀ', 'åħ¬'] +['é»', 'ŀ'] +['éĽ', 'Ħ'] +['å̼', 'å¾Ĺ'] +['çĮ', 'ª'] +['以', '为'] +['æĺ', 'Į'] +['è·Ŀ', '离'] +['åIJ¸', 'å¼ķ'] +['ç»', 'ķ'] +['éļ', 'Ĩ'] +['计', 'ç®Ĺ'] +['éĺŁ', 'ä¼į'] +['大', 'ä¼ļ'] +['å¼ķ', 'èµ·'] +['çī¹', 'çĤ¹'] +['èĥ', '¶'] +['å¹´', 'è½»'] +['æľ¬', '身'] +['æľº', 'åħ³'] +['å®ĺ', 'æĸ¹'] +['éĥ', 'ij'] +['æµ', 'Ļ'] +['è§Ĵ', 'èī²'] +['èij£', 'äºĭ'] +['为', '主'] +['æĹł', '论'] +['ä¹ł', 'æĥ¯'] +['æ¥', 'ļ'] +['æĭ', 'ĵ'] +['绣', '计'] +['åħ', 'Ħ'] +['广', 'æ³Ľ'] +['åį', 'Ģ'] +['污', 'æŁĵ'] +['è«', 'ĭ'] +['èĬĤ', '缮'] +['ä¼', '¦'] +['è¦Ĩ', 'çĽĸ'] +['èĢ', 'IJ'] +['æī¶', 'è´«'] +['ç»ı', 'åİĨ'] +['éĩįè¦ģ', 'çļĦ'] +['èĤ¡', '举'] +['æĭĽ', 'èģĺ'] +['åĽĽ', '个'] +['æĩ', 'ī'] +['èĥ', 'ŀ'] +['æij', 'Ĩ'] +['é«ĺ', 'éĢŁ'] +['éº', '¦'] +['åİŁ', 'åĪĻ'] +['èİ', '±'] +['æĽ´', '好'] +['éķ', 'ľ'] +['åĩ', 'Į'] +['åŀĥ', 'åľ¾'] +['éĢ', '²'] +['çģ', '°'] +['éĵ', 'º'] +['äºĭ', 'æķħ'] +['çĶ', 'ĺ'] +['空', 'æ°Ķ'] +['é¾', 'Ħ'] +['èı', '²'] +['çĵ', '¶'] +['æĺ', '¨'] +['æĹ¥', 'æĬ¥'] +['æµ', '®'] +['åľ°', 'åĽ¾'] +['åij', 'Ī'] +['大', 'åĬĽ'] +['ç»', 'ª'] +['å¸', 'ħ'] +['æľį', 'åĭĻ'] +['ä¸į', 'éĶĻ'] +['乡', 'æĿij'] +['å±', '¥'] +['å¹³', 'æĸ¹'] +['éĹ', '²'] +['æī', '£'] +['ç´ł', 'è´¨'] +['èµ', '´'] +['éģ', 'Ń'] +['èIJ', '¨'] +['èĩª', '主'] +['éĩij', 'å±ŀ'] +['èī¯', '好'] +['两', 'å¹´'] +['æ³', '¥'] +['é¢', 'ľ'] +['ç²¾', '彩'] +['ä¸Ń', 'åįİ'] +['æĻ', 'ĭ'] +['ä¹ł', 'è¿ij'] +['ä¹łè¿ij', 'å¹³'] +['æĪĺ', '士'] +['åģļ', 'çļĦ'] +['éª', 'ij'] +['æ»', '´'] +['çĵ', 'ľ'] +['çīĪ', 'æĿĥ'] +['èĤ', 'ł'] +['æľĥ', 'åĵ¡'] +['çı', 'į'] +['ç¨', '®'] +['ä', '»¿'] +['çī©', 'ä¸ļ'] +['åĢĭ', '人'] +['å¦', '»'] +['ä¼', '¸'] +['æ±', 'Ĺ'] +['æĹ', 'º'] +['çIJĨ', 'æĥ³'] +['æij', '¸'] +['è¿Ŀ', 'æ³ķ'] +['å®Į', 'æķ´'] +['åİ', '¦'] +['è¸', 'ı'] +['æĸ', 'ij'] +['æ¡', 'Ĥ'] +['ä½ĵ', 'åζ'] +['å¸', '«'] +['æĿ', 'Ĩ'] +['æ®', '¿'] +['æ¯', 'ģ'] +['é¦', 'Ī'] +['è§Ĵ', '度'] +['æ¬', '£'] +['çĥ', '¦'] +['èĤ', 'º'] +['éĩĩ', '访'] +['æij', 'ĺ'] +['æĮ', '¡'] +['æ·', 'ĺ'] +['åħ»', 'èĢģ'] +['çĤ', '¸'] +['è¿', 'Ī'] +['åİ', 'ī'] +['åĿ', 'Ĭ'] +['è¾', '£'] +['åĩ', 'Ŀ'] +['æ³', 'ª'] +['çĸ', 'ı'] +['æİ', 'ĺ'] +['åĥı', 'æĺ¯'] +['éĽ', 'ķ'] +['ç¼', 'Ŀ'] +['èį', '·'] +['æį', '·'] +['åł', '¡'] +['åı¥', 'è¯Ŀ'] +['çĸ', '¼'] +['æł', 'ı'] +['éģ', 'µ'] +['ç¢', '³'] +['å·¥', 'åķĨ'] +['æIJ', 'º'] +['åĪ', '¥'] +['ä¹', 'Ļ'] +['æĹ', 'ĭ'] +['æĥ', 'ľ'] +['ä¸Ģ', '大'] +['å±Ĥ', '次'] +['èµ', 'ĸ'] +['æĬ', '¬'] +['æ¨', 'Ĥ'] +['è¯', 'ŀ'] +['åħ', 'Ĵ'] +['ç¯', '®'] +['èĤ', 'ĥ'] +['å§', '¿'] +['æĬ', 'ļ'] +['çĵ', '·'] +['ç͵', 'åĬ¨'] +['æĸ°', 'åĨł'] +['æ¶', 'µ'] +['ç¢', 'ij'] +['æ·', '®'] +['æĹ', '¨'] +['è¸', 'ª'] +['æ¸', 'Ķ'] +['æĦ', 'Ī'] +['åı', 'Ķ'] +['åįĹ', 'çľģ'] +['ç¾', '©'] +['å§Ķ', '书记'] +['è²', '¸'] +['æ¶', 'Į'] +['è«', 'ĸ'] +['èIJ', 'Ħ'] +['æı', 'ı'] +['å¿', '§'] +['è¾', '¦'] +['å¦', 'Ĩ'] +['æī', 'Ń'] +['åij', 'µ'] +['éģ', '¥'] +['è¨', '±'] +['ä»', 'ĩ'] +['åįģ', 'ä¸ī'] +['åī', '²'] +['èª', 'į'] +['èĪ', '°'] +['é¢', 'ĩ'] +['é¥', '±'] +['çĭ', 'ł'] +['é«ĺ', 'çļĦ'] +['çµ', '±'] +['æħ', 'İ'] +['é¢', 'ģ'] +['åIJĪ', 'éĢĤ'] +['æµ', '´'] +['èµ', 'ĭ'] +['æĬ', '¼'] +['å¦', '¥'] +['éĻ¢', 'éķ¿'] +['èĢ', 'ķ'] +['è¾', '¨'] +['æħ', '°'] +['åįģ', 'åĽĽ'] +['æľ', 'µ'] +['èĵ', 'Ħ'] +['æŀ', '¢'] +['å»', '·'] +['æĤ', 'Ħ'] +['æ¶', '¯'] +['çŁ', '©'] +['åŃIJ', 'éĩĮ'] +['çĬ', '¹'] +['å±Ģ', 'éķ¿'] +['é', 'IJ'] +['å¥', 'ł'] +['ä¼ļ', 'éķ¿'] +['æĵ', 'ļ'] +['ä¸į', 'åıĬ'] +['åįģ', 'ä¹Ŀ'] +['æ¬', 'º'] +['èº', 'º'] +['éĺ', 'IJ'] +['çº', 'Į'] +['è¨', '»'] +['åĨ', 'Ĭ'] +['èŃ', 'ĺ'] +['é«ĺ', 'çŃī'] +['èħ', 'º'] +['å¤', 'ķ'] +['ç»', 'ij'] +['åĶ', '¤'] +['èķ', '´'] +['çķ', 'ľ'] +['æħ', 'ĭ'] +['åı', 'Ļ'] +['åı', 'ĥ'] +['å³', '¡'] +['人', '大'] +['éħ', '¿'] +['éģ', '©'] +['å¥', '¢'] +['åı£', 'æ°Ķ'] +['éĮ', 'Ħ'] +['é', 'ı'] +['åĭ', 'ĺ'] +['è´', '¿'] +['éļ', 'ª'] +['é', 'ĭ'] +['éļ', '¶'] +['ð', '¥'] +['ð¬', '£'] +['ð', '£'] +['ð«', 'į'] +['ð¬', '³'] +['ð«', 'ĵ'] +['ð«', 'Ħ'] +['ð«', 'Ł'] +['ð¨', '±'] +['ä', 'Ĺ'] +['以', 'åıĬ'] +['æľī', 'éĻIJ'] +['åij', '¢'] +['åIJ', 'Ĺ'] +['çľĭ', 'åΰ'] +['计', 'åĪĴ'] +['è¿Ľ', 'åħ¥'] +['缴', 'æİ¥'] +['åĪĨ', 'æŀIJ'] +['åıª', 'æľī'] +['设', 'å¤ĩ'] +['åħ¶', 'å®ŀ'] +['åĬł', '强'] +['ä¸Ń', 'çļĦ'] +['ä¿Ŀ', 'éļľ'] +['èĢģ', 'å¸Ī'] +['人', 'æīį'] +['å¾Ĺ', 'åΰ'] +['é£İ', 'éĻ©'] +['ä¸Ģ', 'ç§į'] +['空', 'éĹ´'] +['æĪij', 'åĽ½'] +['ä¹ĭ', 'åīį'] +['ä¸ĵ', 'å®¶'] +['æĿ', '¨'] +['æĹ¥', 'æľ¬'] +['群', 'ä¼Ĺ'] +['åıĤ', 'åĬł'] +['æķĪ', 'æŀľ'] +['æľī', 'åħ³'] +['å®¶', 'åºŃ'] +['åĮº', 'åŁŁ'] +['åĬª', 'åĬĽ'] +['éļı', 'çĿĢ'] +['æĹł', 'æ³ķ'] +['交', 'æµģ'] +['è¡Į', '为'] +['æ£Ģ', 'æŁ¥'] +['æľŁ', 'éĹ´'] +['å¦Ĥ', 'æŃ¤'] +['èĤ¡', '份'] +['å½ĵ', 'æĹ¶'] +['è£ħ', 'å¤ĩ'] +['åĩĨ', 'å¤ĩ'] +['éħĴ', 'åºĹ'] +['è¿IJ', 'åĬ¨'] +['æıIJ', 'åĩº'] +['å·¦', 'åı³'] +['æİª', 'æĸ½'] +['é£Ł', 'åĵģ'] +['æ¶Īè´¹', 'èĢħ'] +['åѦ', 'éĻ¢'] +['æĮĩ', '导'] +['è¿IJ', 'èIJ¥'] +['éĩį', '大'] +['åĨľ', 'æĿij'] +['éĢł', 'æĪIJ'] +['æĶ¿', 'æ²»'] +['éĴĪ', '对'] +['æŃ£', 'å¼ı'] +['åıĸ', 'å¾Ĺ'] +['éĤ£', '个'] +['éĽĨ', 'ä¸Ń'] +['åıª', 'èĥ½'] +['å¿«', 'éĢŁ'] +['身', 'ä½ĵ'] +['åħļ', 'åijĺ'] +['èģĶ', 'åIJĪ'] +['åĬĽ', 'éĩı'] +['éĥ½', 'æľī'] +['æ', 'ħ§'] +['å¡', 'Ķ'] +['åĪ«', '人'] +['表', 'çݰ'] +['æķħ', 'äºĭ'] +['ä¸Ģ', 'åĪĩ'] +['å°', 'ĩ'] +['èµĦ', 'æĸĻ'] +['åŁ¹', 'åħ»'] +['éĺħ', '读'] +['æľī', '人'] +['èIJ¥', 'éĶĢ'] +['çĽij', 'çĿ£'] +['çݯ', 'ä¿Ŀ'] +['èĢĥ', 'èĻij'] +['æ·±', 'åľ³'] +['严', 'éĩį'] +['èĮĥ', 'åĽ´'] +['å§Ķ', 'åijĺ'] +['çĽij', '管'] +['ä¸ī', '个'] +['è£ħ', 'ä¿®'] +['åħ¬', 'éĩĮ'] +['åĪĨ', 'åĪ«'] +['çIJĨ', 'è§£'] +['éŁ', '©'] +['åĬł', 'å·¥'] +['认', '羣'] +['ä¸į', '好'] +['åİ»', 'å¹´'] +['éĻį', 'ä½İ'] +['æľº', 'ä¼ļ'] +['åįı', 'è®®'] +['符', 'åIJĪ'] +['å¢ŀ', '强'] +['æĬĢ', 'èĥ½'] +['é¦ĸ', 'åħĪ'] +['ç§', '¦'] +['ä¸', 'ģ'] +['å°', '¾'] +['æľī', 'äºĨ'] +['åľ°', '产'] +['æ¸', 'ł'] +['æĸ¹', '便'] +['ç§»', 'åĬ¨'] +['éĢŁ', '度'] +['å°¤', 'åħ¶'] +['éĢļ', 'çŁ¥'] +['åĿ', 'Ľ'] +['éģ¿', 'åħį'] +['æģ', '¢'] +['è´', '¡'] +['èģĮ', 'å·¥'] +['å®ŀ', 'åĬĽ'] +['æĺ¯ä¸Ģ', 'ç§į'] +['åIJ¯', 'åĬ¨'] +['çĸ¾', 'çĹħ'] +['æĿ¥', 'äºĨ'] +['缸', '对'] +['çݰ', 'å®ŀ'] +['èŀį', 'åIJĪ'] +['åIJĮ', 'æł·'] +['åħ¬', 'åijĬ'] +['çī¹', 'æ®Ĭ'] +['ç´', '«'] +['ä¸ĭ', 'åİ»'] +['ä¼ł', 'æĴŃ'] +['æľĢ', '好'] +['ä¼ĺ', 'è´¨'] +['æ²', 'Ĵ'] +['æĮ', 'º'] +['æĹ', '¦'] +['è¯', 'º'] +['ä¸Ģ', 'åIJį'] +['éģĵ', 'è·¯'] +['示', 'èĮĥ'] +['è¿ĩ', 'æĿ¥'] +['åIJĮ', 'åѦ'] +['é¼', 'ĵ'] +['æĿ', 'Ń'] +['æľ¬', '次'] +['åIJĮ', 'æĦı'] +['ä¸ĸ', '纪'] +['ç¾', 'Ĭ'] +['æ¬', '²'] +['å·¥', 'èīº'] +['çĵ', '¦'] +['人', '士'] +['æľī', 'æīĢ'] +['ä»İ', 'äºĭ'] +['æľī', 'å¾Īå¤ļ'] +['ä¸į', 'äºĨ'] +['å²Ĺ', 'ä½į'] +['åıĺ', 'å¾Ĺ'] +['åĬ³', 'åĬ¨'] +['å¤Ħ', 'äºİ'] +['å¹³', 'åĿĩ'] +['å½¢', '象'] +['å¡', 'ŀ'] +['åħ±', '享'] +['çĿ', 'Ľ'] +['åĪ©', '润'] +['æŃ£', 'æĺ¯'] +['å¾Ģ', 'å¾Ģ'] +['缸', 'æ¯Ķ'] +['æ¨', 'ª'] +['åĪ', '·'] +['æµĻ', 'æ±Ł'] +['大', 'éĥ¨åĪĨ'] +['å¤ļ', '个'] +['æĤ¨', 'çļĦ'] +['ç͵', 'åķĨ'] +['å¾®', 'åįļ'] +['å§ĭ', 'ç»Ī'] +['çĬ¯', '罪'] +['æĺ¯', 'åľ¨'] +['ç»Ħ', 'åIJĪ'] +['åİŁ', 'æĿ¥'] +['æ¸ħ', 'æ¥ļ'] +['åIJĦ', 'åľ°'] +['æĦŁ', 'åıĹ'] +['å½ĵ', 'ä¸Ń'] +['è¶ĭ', 'åĬ¿'] +['æĻ¯', 'åĮº'] +['羣', 'æĺ¯'] +['ä¾Ľ', 'åºĶ'] +['转', 'åŀĭ'] +['çĭ', 'Ĥ'] +['èĨ', 'ľ'] +['èĭ', 'Ĺ'] +['å¿', 'ł'] +['å¾Ī', '大'] +['èĤ¡', 'æĿĥ'] +['ç¾İ', 'åħĥ'] +['æİĴ', 'åIJį'] +['åĬ¨', 'çī©'] +['éĶ', 'ħ'] +['å¢', '¨'] +['主', 'å¸Ń'] +['å¾Ī', '好'] +['ç»Ŀ', '对'] +['æĿ', 'ľ'] +['转', 'è½½'] +['çĴ', 'ĥ'] +['æĿij', 'æ°ij'] +['åIJ', '¨'] +['åĽŃ', 'åĮº'] +['é«ĺ', '度'] +['çī©', 'è´¨'] +['è¾', 'ī'] +['æĹ¥', '常'] +['æı', 'Ĵ'] +['ä¸ī', 'å¹´'] +['ä½ĵ', 'çݰ'] +['æīį', 'æĺ¯'] +['代', 'çIJĨ'] +['ä¸į', '管'] +['æģ', 'Ĵ'] +['åľ°', 'ä½į'] +['ç²', '®'] +['èĸ', 'Ħ'] +['æĺİ', 'çϽ'] +['ä¸Ģ', 'èĩ´'] +['æĽ', '¼'] +['åĵ', 'Ń'] +['åĩ', '¤'] +['åĬ', '²'] +['æķ', 'Į'] +['æĪĺ', 'æĸĹ'] +['主', 'ä½ĵ'] +['åħ¬', 'å¸ĥ'] +['åıĤ', 'èĢĥ'] +['èĪª', '空'] +['å¯', 'º'] +['åѦ', 'ä¼ļ'] +['åıį', 'æĺł'] +['ç¾İ', '丽'] +['太', 'éĺ³'] +['建', 'æĪIJ'] +['æħ¢', 'æħ¢'] +['åIJĦ', '个'] +['éĤ', '¦'] +['ç»Ħ', 'æĪIJ'] +['ä¸ī', '大'] +['éĶ', '¦'] +['大å¤ļ', 'æķ°'] +['æ¦Ĥ', '念'] +['éŃ', 'Ĥ'] +['åħ¬', 'çĽĬ'] +['èį', 'Ĵ'] +['身', '份'] +['æ·±', 'åĪ»'] +['åħ', '©'] +['ç»ı', 'åħ¸'] +['åIJĦ', '项'] +['èĻ', 'ķ'] +['è¿Ľ', 'æŃ¥'] +['åįģ', 'äºĮ'] +['æī§', 'æ³ķ'] +['æĥ³', 'åΰ'] +['æĦŁ', 'æŁĵ'] +['åķĨ', 'åĬ¡'] +['å°ı', 'ç»Ħ'] +['èĶ', '¬'] +['çıŃ', 'åŃIJ'] +['åIJĮ', 'å¿Ĺ'] +['éĿ¢', '临'] +['çĤ', 'Ĵ'] +['å¤ļ', 'ç§į'] +['è§Ĥ', 'çĤ¹'] +['åĵª', 'éĩĮ'] +['å°', 'Ŀ'] +['å§', 'Ĩ'] +['èħ', '¹'] +['åŁİ', 'åĮº'] +['太', 'å¤ļ'] +['çĹħ', 'æ¯Ĵ'] +['åľ¨', 'äºİ'] +['æīĢ', 'è°ĵ'] +['æĻ', '°'] +['æŀ', 'Ŀ'] +['æĭ', 'ĸ'] +['å®', 'ħ'] +['æķ´', 'æ²»'] +['ä½ı', 'æĪ¿'] +['åģ', '·'] +['çĨ', 'Ĭ'] +['èµ', 'ģ'] +['æ°', 'Ľ'] +['æł¼', 'å±Ģ'] +['åŁºç¡Ģ', 'ä¸Ĭ'] +['èĥ', 'Ĩ'] +['åħ', '½'] +['鼶', 'åĶ®'] +['åĿ', '¡'] +['女', 'åŃ©'] +['æĴ', 'ŀ'] +['åħ¨', 'åĬĽ'] +['åĴ', 'ĸ'] +['èĤ', '©'] +['çľ', 'ī'] +['èĩ³', 'äºİ'] +['åħļ', 'ç»Ħ'] +['ä¸Ģ', 'ä»¶'] +['æĭ', 'Ĩ'] +['äºĭ', 'å®ŀ'] +['åĤ', '³'] +['æ¹', 'ĺ'] +['ç¶²', 'ç«Ļ'] +['循', 'çݯ'] +['åIJĮ', 'æ¯Ķ'] +['æĭ', 'Ķ'] +['åĮ»', 'èį¯'] +['åħ»', 'æ®ĸ'] +['åĽº', 'å®ļ'] +['å®ŀéĻħ', 'ä¸Ĭ'] +['è®°', 'å¾Ĺ'] +['åĪ©', 'äºİ'] +['æĤ', '¦'] +['æĭ', '³'] +['èĤ', 'Ŀ'] +['æķĪ', 'çĽĬ'] +['è©', '²'] +['æ°ij', '主'] +['çĹĩ', 'çĬ¶'] +['é¢', '¨'] +['å¹¼', 'åĦ¿'] +['å§', 'ij'] +['æĪ', 'Ĵ'] +['ä¸ĭ', 'çļĦ'] +['æ¸', '¡'] +['å¹´', 'åºķ'] +['è®°', 'å¿Ĩ'] +['åIJ', 'IJ'] +['大', 'å¹ħ'] +['å¾', '½'] +['åħ¬', 'ä¼Ĺ'] +['ä¿¡', 'å¿ĥ'] +['çİ', 'Ľ'] +['ä¼ļ', 'ä¸Ĭ'] +['ä¹', 'Ķ'] +['æijĦ', 'å½±'] +['æ£ĭ', 'çīĮ'] +['éĻ', 'ķ'] +['åºĶ', 'æĢ¥'] +['æĶ¶', 'è´¹'] +['æİ§', 'èĤ¡'] +['仪', 'å¼ı'] +['çŀ', '¬'] +['æīĢ', 'åľ¨'] +['ç¢', '°'] +['å§', 'ĵ'] +['é¡', 'Į'] +['æĶ¯', 'éĥ¨'] +['使', 'åij½'] +['çĤ', 'ī'] +['å¯', 'Ħ'] +['ç¿', '¼'] +['åľ°', 'ä¸ĭ'] +['è¾', 'ŀ'] +['ä¿', '±'] +['主', 'æĮģ'] +['è´§', 'å¸ģ'] +['æģ', '¨'] +['èĤ', 'Į'] +['çĽ', 'Ī'] +['éĶ', '»'] +['å¿Ĺ', 'æĦ¿'] +['ç±»', 'ä¼¼'] +['æĮ', 'ĸ'] +['éĢ', '»'] +['ç¸', '½'] +['纪', '念'] +['åķ', '¥'] +['å¼', '¯'] +['åIJį', 'åŃĹ'] +['åģ¥', '身'] +['çļĦ', 'å¿ĥ'] +['é©', '±'] +['èĥĮ', 'åIJİ'] +['æ³ķ', 'å¸Ī'] +['ç²', 'Ĵ'] +['èĥ½', 'éĩı'] +['è¾', '°'] +['èī', '³'] +['å½', '¼'] +['段', 'æĹ¶éĹ´'] +['åIJĪ', 'æ³ķ'] +['æĵ', '¦'] +['ç¾', '½'] +['åİ', '¨'] +['æĪij', '说'] +['äºĭ', 'åĬ¡'] +['åĩł', '天'] +['åħ', 'ģ'] +['ç¼', '´'] +['åį', 'ĵ'] +['两', 'ç§į'] +['çĭ¬', 'çī¹'] +['å¸', '¶'] +['éĴ', '»'] +['æĥ', '©'] +['é¢Ĩ', 'åħĪ'] +['è¶³', 'å¤Ł'] +['å£', '³'] +['æĦıåij³', 'çĿĢ'] +['åĪĨ', 'å¸ĥ'] +['ä¹', 'ĥ'] +['éģ', 'ĭ'] +['ä½', '©'] +['è°', '±'] +['çģ', '£'] +['èį', '¡'] +['è´¯', 'å½»'] +['å¹', '¾'] +['ç£', 'ģ'] +['åħ¸', 'åŀĭ'] +['åī', 'ĩ'] +['åĨ', '»'] +['æ¬', 'ł'] +['ä¸į', 'ä¹ħ'] +['æµ', '¦'] +['éŃ', 'ħ'] +['å¼Ģ', 'äºĨ'] +['使ç͍', 'èĢħ'] +['è¿Ļ', '款'] +['å°', 'Ī'] +['èĦ±', 'è´«'] +['æĶ»', 'åĿļ'] +['ç®Ĺ', 'æĺ¯'] +['ç¨', 'Ģ'] +['æĹł', '人'] +['åł', 'µ'] +['å¥', 'ı'] +['éĥ½', 'å¸Ĥ'] +['åı¯', 'è§ģ'] +['ä¸į', 'åĩº'] +['æ', '·»'] +['äº', 'ı'] +['ç¾İ', '好'] +['èĥ', 'ĸ'] +['éŁ', 'µ'] +['æłĩ', 'å¿Ĺ'] +['èĬĤ', 'èĥ½'] +['æĬ', '«'] +['å°', 'º'] +['å¯', '¸'] +['ä¸Ģ', '代'] +['é¢', 'Ĺ'] +['èĢ', '¶'] +['èĴ', '¸'] +['åĸ', '®'] +['æ', '»¿'] +['çĮ', 'ľ'] +['æµ', 'Ĩ'] +['åŁ', 'ĥ'] +['åįĥ', 'ä¸ĩ'] +['èµ', 'Į'] +['èģ', '²'] +['ä½ľ', 'é£İ'] +['è³', 'ª'] +['å¯', '¨'] +['å¹´', '人'] +['åį°', '象'] +['æ¡', '¶'] +['æĴ', '¤'] +['åįģ', 'äºĶ'] +['æ¯', 'ħ'] +['æ²', 'ª'] +['åĽ½', 'æľī'] +['大éĩı', 'çļĦ'] +['å¾', '¡'] +['å¯', 'ĵ'] +['è¦', 'ĸ'] +['æ¼Ĥ', '亮'] +['çľ', 'ł'] +['ç', 'ĤŃ'] +['é»', 'İ'] +['èĻ', '¹'] +['åĪ©', 'äºļ'] +['èŃ', 'ī'] +['æµ', 'ı'] +['åįģ', 'åħ«'] +['ä¸', '¢'] +['è¾', '½'] +['æľīä¸Ģ', 'äºĽ'] +['æħ', 'Ī'] +['åģľ', '车'] +['å®', 'ł'] +['è§£', 'æĶ¾'] +['æľī', 'å¤ļ'] +['éĤ', 'Ĭ'] +['常', 'è§ģ'] +['æĬ', '¹'] +['çº', '¤'] +['è¦', 'ª'] +['æ¡', 'Ĩ'] +['èİ', 'ŀ'] +['æ°§', 'åĮĸ'] +['è¿Ļ', 'ä»¶'] +['åĩ', '°'] +['æŁ', '´'] +['åıij', 'ç͵'] +['é¼', 'ł'] +['转', 'åĮĸ'] +['å¨', 'ĥ'] +['æĮ', '¤'] +['ç½', '©'] +['å¯Ĩ', 'åĪĩ'] +['æĪij', 'ä¸į'] +['é«ĺ', 'æĸ°'] +['ä¸Ģ', 'ç¯ĩ'] +['è¿Ľ', 'ç¨ĭ'] +['è¡', '°'] +['è¿ĺ', 'ä¸į'] +['ç', 'ħĮ'] +['æĸ°', 'åįİ'] +['èĤ', '¿'] +['æ»', '©'] +['ä¸Ģ', 'æµģ'] +['è¯', 'Ī'] +['å®ŀ', 'ä½ĵ'] +['å¤ĸ', 'åĽ½'] +['èº', '²'] +['èµ', 'ł'] +['è¦', 'º'] +['æ¢', 'Ŀ'] +['ä¸į', 'è§ģ'] +['è¨', 'Ĭ'] +['åĮ', '¹'] +['åį', 'µ'] +['çĩ', '¥'] +['æħ', 'ķ'] +['é½', '¿'] +['å®', '´'] +['é¥', '¼'] +['èij¡', 'èIJĦ'] +['å°ı', 'å¿ĥ'] +['æģ', '¼'] +['éĻ', 'Į'] +['æĺ', 'Ĥ'] +['åĥ', '¹'] +['èĬ', 'Ŀ'] +['æ¯ı', '个人'] +['åīį', 'æıIJ'] +['ä½ĵ', 'ä¼ļ'] +['æ¨', 'Ļ'] +['æIJľ', 'çĭIJ'] +['对', 'åħ¶'] +['ä¸', '§'] +['èľ', 'Ĥ'] +['æµ', '¸'] +['èª', '¿'] +['åĿ', 'ª'] +['é¢', 'ĸ'] +['åIJį', '为'] +['ç¬', '¼'] +['èĪ', 'Į'] +['æľ¬', '书'] +['èģ', '¯'] +['çº', 'º'] +['ç®Ģ', '缴'] +['éĽ', '¢'] +['ç¾İ', 'çļĦ'] +['éļ', '¨'] +['é«ĺ', 'å³°'] +['è¿Ļ', 'å®¶'] +['å', 'Ĥ¬'] +['å°', '¸'] +['ç¡ķ', '士'] +['èŃ', '·'] +['è°', '¨'] +['æĺ', 'ı'] +['æĶ¿', 'åįı'] +['è¡', 'Ķ'] +['ç¿', 'Ĵ'] +['åľ', 'Ĵ'] +['åĽ½', 'æ°ij'] +['主', 'è§Ĵ'] +['è£', 'ķ'] +['ä¼', 'ª'] +['åº', 'ŀ'] +['æ°ij', 'èIJ¥'] +['æĥ', '§'] +['ç§ĺ', '书'] +['çĹ', 'ķ'] +['çϾ', 'åĪĨ'] +['æº', '¶'] +['æĹł', 'çĸij'] +['çļĦ', 'çľ¼'] +['æĵ', 'İ'] +['ä¼Ł', '大'] +['å½', '°'] +['åħ¬å®ī', 'å±Ģ'] +['ç³', 'ķ'] +['å¼', '¥'] +['åĤ', 'Ļ'] +['ä¹', '¾'] +['毫', 'ä¸į'] +['注', 'æĺİ'] +['åī¯', 'æĢ»'] +['æĦ', 'ī'] +['æķ', '¦'] +['é¦', '¨'] +['æĶ', 'Ģ'] +['éĢ', 'Ŀ'] +['åı¯', 'éĿł'] +['å¤', '¸'] +['åľ', 'ĺ'] +['éĿ¢', 'ä¸Ĭ'] +['æĬ', 'ĸ'] +['èĦ', 'Ĩ'] +['é©', '°'] +['ä¼', 'IJ'] +['å¦', '¨'] +['å®ļ', 'äºĨ'] +['ç³', 'Ĭ'] +['æŃ', '¡'] +['éĥ¨', 'éķ¿'] +['ç§', 'ī'] +['èĪ', 'Ĩ'] +['åĪij', 'äºĭ'] +['åIJ', 'µ'] +['æ¤', 'Ĵ'] +['è¡', 'ĵ'] +['è±', '«'] +['èı', '©'] +['åŃ', 'µ'] +['é¥', '²'] +['å°±', '好'] +['åł', 'ª'] +['ä¸ī', 'è§Ĵ'] +['åľº', 'æ¯ĶèµĽ'] +['ä¸į', 'åģľ'] +['æĵ', 'ħ'] +['åħ¨', 'æĸĩ'] +['æ³', 'ģ'] +['åѦ', 'ä½į'] +['æ±', '°'] +['éł', 'ĺ'] +['åı', 'ł'] +['éļ', 'Ľ'] +['å¸', 'IJ'] +['çľĭ', 'åĩº'] +['åĮ', 'ł'] +['å±Ģ', 'éĿ¢'] +['æ³', 'Į'] +['è°', 'Ĭ'] +['åIJĮ', 'æľŁ'] +['æĬķ', 'æłĩ'] +['å¥', '´'] +['æĿ¥çľĭ', 'çľĭ'] +['èĦ', '¾'] +['èŀ', 'º'] +['æŃ', 'ī'] +['çĽ', '¯'] +['ç¨İ', 'åĬ¡'] +['å»', 'Ĭ'] +['æİ', '©'] +['æħ', '¨'] +['çĽ', '¼'] +['èĬ', 'Ĵ'] +['è®', 'Ģ'] +['æĮ', '£'] +['èĮ', 'ħ'] +['æĸ', '¥'] +['æ¤', 'ħ'] +['åΰ', 'æĿ¥'] +['èijĹ', 'ä½ľ'] +['çĭ', '±'] +['äºĮ', 'æīĭ'] +['ä»İ', 'æĿ¥'] +['çĸ', '²'] +['åºĬ', 'ä¸Ĭ'] +['æĸ°', '浪'] +['æ³', 'Ħ'] +['å¢ŀ', 'å̼'] +['ä¸', 'Ľ'] +['æļ', 'ij'] +['ä»İ', 'ä¸ļ'] +['æ·', 'ĭ'] +['å¤ļ', 'æł·'] +['æľ', '´'] +['份', 'é¢Ŀ'] +['æŀ', '£'] +['西', 'çľģ'] +['æľ¬', 'è´¨'] +['æ·±', 'æ·±'] +['èī', 'ĩ'] +['ç»', 'µ'] +['产', 'å̼'] +['æ¼', 'ł'] +['èħ', '»'] +['çŃ', 'Ľ'] +['åİ', 'Į'] +['æģ', 'Ń'] +['å«Į', 'çĸij'] +['æĪ', '¶'] +['æ»', 'ŀ'] +['èĨ', 'Ģ'] +['åĬ', '£'] +['座', 'è°Ī'] +['常', 'æĢģ'] +['çļĦ', 'æĥħ'] +['è¦', '½'] +['å¯', 'Ĥ'] +['åĮ', 'Ĩ'] +['èĩ', 'º'] +['é¡', '¯'] +['çķ', 'ı'] +['éģ', '£'] +['åį', 'ľ'] +['çŃī', 'å¥ĸ'] +['è²', '¬'] +['æº', '¯'] +['é', 'İ'] +['çĤ¹', '头'] +['èĵ', '¬'] +['æ±', 'º'] +['éħ', '¬'] +['éģ', 'Ĭ'] +['è³', '¼'] +['註', 'åĨĬ'] +['æľ¬', 'æĬ¥'] +['çµ', 'ķ'] +['æ´»', 'æĢ§'] +['åħ', 'ij'] +['éĮ', '¯'] +['åĨ', '¶'] +['åĸ', '»'] +['æº', 'ĸ'] +['èĤ', '¢'] +['æº', 'ĥ'] +['æĹ', '¬'] +['åī', 'Ĭ'] +['çIJĨ', 'äºĭ'] +['å±', 'ł'] +['æ²', '§'] +['èļ', 'Ģ'] +['鼻', 'åŃIJ'] +['为', 'æŃ¢'] +['常', 'å§Ķ'] +['çµ', 'Ĥ'] +['éĬ', '·'] +['çĭ', 'Ģ'] +['ä¾', '£'] +['èĥ', 'Ģ'] +['èŃ', '°'] +['ç͍', '车'] +['åĻ', 'ª'] +['æŃ', '·'] +['åį', 'Ķ'] +['åĪ', '¹'] +['竣', 'æĺ¯'] +['é©', 'Ĺ'] +['èIJ', 'Ŀ'] +['çĻ', '«'] +['çĹ', '«'] +['æŃ', '§'] +['å¼', 'Ĭ'] +['åª', '½'] +['çı', 'Ĭ'] +['è¡', '·'] +['éľ', 'ī'] +['åŁº', 'çĿ£'] +['éļ', '±'] +['æ°', '¨'] +['ç»', '¸'] +['å°¼', 'æĸ¯'] +['çĥ', 'ĺ'] +['æľŁ', 'åĨħ'] +['è°', 'ħ'] +['éĽ', 'ĩ'] +['éļ', 'Ļ'] +['å', 'ĸī'] +['åī', '¥'] +['çĹ', 'ĺ'] +['æĮ', '½'] +['çĵ', '£'] +['æ¹', 'Ľ'] +['æ¨', '±'] +['æ¾', 'İ'] +['æ¹', 'ĥ'] +['åĨ¬', '奥'] +['æ£', 'µ'] +['å®', '°'] +['åŀ', 'Ĵ'] +['æ§', 'ĭ'] +['ä¾', 'Ī'] +['èĮ', 'Ħ'] +['åĺ', '¿'] +['èı', 'ĩ'] +['ç', 'ĻĤ'] +['åĬ', 'ĥ'] +['é', 'į'] +['èĶ', '½'] +['çŀ', 'Ń'] +['æķ', 'ŀ'] +['ä¹', 'ĸ'] +['éŁ', '§'] +['è¾', 'ľ'] +['æĩ', 'Ī'] +['ä½', '£'] +['çŀ', '»'] +['åŁ', 'Ķ'] +['èĪ', 'ħ'] +['å®ŀ', 'äºĭ'] +['é', '¨'] +['å§', '¥'] +['çµ', '¡'] +['åĺ', '»'] +['çķ', '¢'] +['æ²ĥ', 'å°Ķ'] +['è¿', 'Ħ'] +['èĤ', 'ĩ'] +['æħ', 'ij'] +['ã', '§'] +['ä', 'ı'] +['ð', 'ł'] +['ð¬', 'ĩ'] +['ð«', 'Ń'] +['ð«', 'IJ'] +['ã', '³'] +['©', '½'] +['ð«', 'ł'] +['ã', 'Ľ'] +['ð¬', 'į'] +['é', '¿'] +['ð¬', 'Ĵ'] +['ã', 'Ļ'] +['ð¬', '¤'] +['ð', '¬´'] +['ð«', 'ĸ'] +['ð', '¤'] +['ã', '¬'] +['ä', '²'] +['ð«', 'Ķ'] +['ð«', 'ļ'] +['è¦ģ', 'æ±Ĥ'] +['ä¸Ģ', 'äºĽ'] +['å®ŀ', 'çݰ'] +['èĢĮ', 'ä¸Ķ'] +['åĽł', 'æŃ¤'] +['çͱ', 'äºİ'] +['åħ³', 'äºİ'] +['çĦ¶', 'åIJİ'] +['æİ¨', 'åĬ¨'] +['ä¸Ģ', 'æł·'] +['æĮī', 'çħ§'] +['è¿Ļæł·', 'çļĦ'] +['å½¢', 'æĪIJ'] +['æľī', 'äºĽ'] +['æĽ´', 'åĬł'] +['ç»ı', 'è¿ĩ'] +['建', 'è®®'] +['æ²»', 'çĸĹ'] +['ä½ł', '们'] +['æīį', 'èĥ½'] +['ä¿ĥ', 'è¿Ľ'] +['åijĺ', 'å·¥'] +['ä½ĵ', 'éªĮ'] +['èĪ', 'ĩ'] +['åģļ', '好'] +['ä¿Ŀ', 'è¯ģ'] +['æķ´', '个'] +['æĺ¯', 'ä¸Ģ个'] +['éĩĩ', 'ç͍'] +['çIJĨ', '论'] +['æ¯Ķ', 'å¦Ĥ'] +['ä¸Ĭ', 'çļĦ'] +['æİ¨', 'èįIJ'] +['çͳ', '请'] +['天', '空'] +['éĥ¨', 'èIJ½'] +['åįģ', 'åĪĨ'] +['æĿ¥', 'èĩª'] +['ä¹ĭ', 'éĹ´'] +['è°ĥ', 'æķ´'] +['æ¯ı', '天'] +['è°ĥ', 'æŁ¥'] +['æĤ£', 'èĢħ'] +['è¿ĩç¨ĭ', 'ä¸Ń'] +['é¦Ļ', '港'] +['广', 'åijĬ'] +['éĿ¢', '对'] +['满', 'è¶³'] +['éķ¿', 'æľŁ'] +['è§Ħ', 'èĮĥ'] +['æķ´', 'ä½ĵ'] +['æĶ¹', 'åıĺ'] +['æĻº', 'æħ§'] +['å¦Ī', 'å¦Ī'] +['å¦Ĥ', 'ä»Ĭ'] +['åIJĪ', 'åIJĮ'] +['éĥ½', 'ä¼ļ'] +['åĦ¿', 'ç«¥'] +['åĩı', 'å°ij'] +['éŁ³', 'ä¹IJ'] +['ç»ı', '常'] +['ä¸Ĭ', 'å¸Ĥ'] +['ä¼ĺ', 'ç§Ģ'] +['çļĦ', 'éĩįè¦ģ'] +['ä¸Ģ', 'æĿ¡'] +['æµ·', 'å¤ĸ'] +['åı¦', 'å¤ĸ'] +['ä¸Ģ', 'å®¶'] +['åİĭ', 'åĬĽ'] +['大', 'åŀĭ'] +['çľĭ', 'çĿĢ'] +['åĪ', 'Ģ'] +['幸', 'ç¦ı'] +['æİ¨', '广'] +['åIJ', 'Ľ'] +['å¾', 'IJ'] +['æī¾', 'åΰ'] +['äºİ', 'æĺ¯'] +['èĩª', '身'] +['ä¸Ģ', 'ä½į'] +['åľŁ', 'åľ°'] +['åĬł', 'åħ¥'] +['æİ¢', 'ç´¢'] +['æ¢', 'ģ'] +['主', 'åĬ¨'] +['å°±', 'ä¸ļ'] +['女', 'æĢ§'] +['çªģ', 'çł´'] +['ä¸įåIJĮ', 'çļĦ'] +['è¿IJ', 'è¾ĵ'] +['èĩª', 'çͱ'] +['å±ħ', 'æ°ij'] +['æŃ¤', '次'] +['çļĦ', 'æĹ¶éĹ´'] +['å®¶', 'éķ¿'] +['ä¸Ģ个', '人'] +['æ£Ģ', 'æµĭ'] +['åĨħ', 'éĥ¨'] +['广', 'å·ŀ'] +['缴', 'æĴŃ'] +['ä»İ', 'èĢĮ'] +['è´·', '款'] +['åı¬', 'å¼Ģ'] +['æĶ¹', 'éĢł'] +['人', 'çĶŁ'] +['å±ķ', '示'] +['æ¯ı', 'å¹´'] +['女', '人'] +['çļĦ', 'æĸ¹å¼ı'] +['æķĪ', 'çİĩ'] +['å±±', '举'] +['æ¸ł', 'éģĵ'] +['ä¼¼', 'ä¹İ'] +['æ¡Ī', 'ä»¶'] +['åĪ©', 'çĽĬ'] +['çľĭ', 'çľĭ'] +['å¿ĥ', 'éĩĮ'] +['ç»´', 'æĬ¤'] +['å®Ŀ', 'å®Ŀ'] +['ç½ij', 'ä¸Ĭ'] +['论', 'åĿĽ'] +['å°±', 'åı¯ä»¥'] +['ä¸į', 'è¶³'] +['æģ¢', 'å¤į'] +['å¸ĥ', 'å±Ģ'] +['è´¡', 'çĮ®'] +['ä¸ĭ', 'éĻį'] +['æİĮ', 'æı¡'] +['çļ®', 'èĤ¤'] +['å·¥', 'åħ·'] +['éĩį', 'åºĨ'] +['åĵģ', 'è´¨'] +['æİ¨', 'åĩº'] +['çĶ·', '人'] +['æī¿', 'æĭħ'] +['çªģ', 'åĩº'] +['èĢĮ', 'è¨Ģ'] +['æ²', 'Ł'] +['åįı', 'è°ĥ'] +['æĺ¯', 'ä»Ģä¹Ī'] +['æ±', '¤'] +['æĴ', 'ij'] +['çĭ¬', 'ç«ĭ'] +['çݯ', 'èĬĤ'] +['æī©', '大'] +['æ´', 'ª'] +['æĿ', '°'] +['çĽ', 'IJ'] +['ä»', 'ģ'] +['æ¶ī', 'åıĬ'] +['èĢģ', '人'] +['åį³', '使'] +['åįĹ', '京'] +['éħį', 'åIJĪ'] +['é¬', '¼'] +['çζ', '亲'] +['ç½Ĺ', 'æĸ¯'] +['å°ı', 'åĮº'] +['æķĻ', 'æİĪ'] +['åĨ³', 'çŃĸ'] +['é¢Ħ', '计'] +['æľ¬', '人'] +['ä¼', '¯'] +['ç«', '¹'] +['åΰ', 'åºķ'] +['å¸Ĥ', 'æ°ij'] +['åĩº', 'åı£'] +['éĩĩ', 'è´Ń'] +['æĢ»', 'ç»ĵ'] +['æŃ¦', 'æ±ī'] +['åĬł', '大'] +['广', '举'] +['æµģ', 'ç¨ĭ'] +['人', 'åı£'] +['å¦Ĥæŀľ', 'ä½ł'] +['åĩº', 'åİ»'] +['åĩ', 'ī'] +['åĨľ', 'æ°ij'] +['çݰ', '象'] +['åĬĽ', '度'] +['ç»Ļ', 'äºĪ'] +['åħļ', 'å§Ķ'] +['è¯Ń', 'è¨Ģ'] +['线', 'ä¸Ĭ'] +['æĢİ', 'æł·'] +['åĦ¿', 'åŃIJ'] +['ç¡®', 'å®ŀ'] +['ä¹ĭ', 'å¤ĸ'] +['éĥ½', 'åľ¨'] +['èī', '¾'] +['çļĦ', 'æĥħåĨµ'] +['éĩĮ', 'çļĦ'] +['åĽ´', 'ç»ķ'] +['æĽ´å¤ļ', 'çļĦ'] +['ä¾Ŀ', 'æ³ķ'] +['åħ¬', 'åĽŃ'] +['å®¶', 'éĩĮ'] +['æ¯į', '亲'] +['ä¸į', 'åĨį'] +['èĭ', '¹'] +['æ³ķ', 'éĻ¢'] +['飩', 'åĽ½'] +['缸', 'å½ĵ'] +['ä¸į', 'çŁ¥'] +['è¯Ħ', 'ä¼°'] +['ä¸į', 'ç͍'] +['顺', 'åĪ©'] +['éĩį', 'è§Ĩ'] +['è´¢', 'åĬ¡'] +['ä»ĸ', 'åĢij'] +['åıij', 'è¡Į'] +['ä¸ĵ', 'éŨ'] +['åħ·', 'å¤ĩ'] +['å¹¶', 'ä¸įæĺ¯'] +['è¶³', 'çIJĥ'] +['é', 'ŀĭ'] +['åıij', '表'] +['æ°¸', 'è¿ľ'] +['èIJ¥', 'åħ»'] +['éħį', 'å¥Ĺ'] +['æķ´', 'åIJĪ'] +['è´', 'º'] +['åĽŀ', 'çŃĶ'] +['æĶ¶', 'çĽĬ'] +['ä¹Ł', '许'] +['è»', 'Ĭ'] +['æİ¥', '触'] +['æĶ»', 'åĩ»'] +['åĽĽ', 'å·Ŀ'] +['æĢ§', 'èĥ½'] +['åĽŀ', 'åΰ'] +['èħ', '°'] +['ä¹Ł', '没æľī'] +['å¼', 'Ħ'] +['设', 'ç«ĭ'] +['éĺ²', 'æİ§'] +['æĬĢ', 'å·§'] +['éĢļ', '常'] +['è´¢', 'æĶ¿'] +['éĥ¨', 'ç½²'] +['åľº', 'æĻ¯'] +['æ±Ł', 'èĭı'] +['表', 'è¾¾'] +['åĸ', '·'] +['女', 'åĦ¿'] +['èĪ', '¶'] +['çµ', '¦'] +['ä¼ļ', 'åijĺ'] +['æĪĸ', '许'] +['äº', '©'] +['举', 'æĸ¹'] +['天', 'æ´¥'] +['è¿ij', 'å¹´'] +['çľĭ', 'æĿ¥'] +['æ¯Ķ', 'ä¾ĭ'] +['å²', '©'] +['éĵ', 'ľ'] +['çİ', '»'] +['å®ŀ', 'éªĮ'] +['æĢĿ', 'ç»´'] +['æĭħ', 'å¿ĥ'] +['æ²', 'Ī'] +['身', 'è¾¹'] +['æ·±', 'åĮĸ'] +['ç²¾', 'åĩĨ'] +['ç§ģ', 'æľį'] +['æ¶Ī', 'éĺ²'] +['åİ»', 'äºĨ'] +['ç»Ĩ', 'èĥŀ'] +['çIJĥ', 'éĺŁ'] +['æĺİ', 'æĺŁ'] +['é£Ł', 'çī©'] +['å¾Ī', 'å¿«'] +['让', 'ä½ł'] +['ä¿¡', 'ç͍'] +['å͝', 'ä¸Ģ'] +['åħ¶', 'å®ĥ'] +['çŃī', 'æĸ¹éĿ¢'] +['å¾ĭ', 'å¸Ī'] +['æŃ»', '亡'] +['æ', 'ٳ'] +['ä¸Ģ', 'æī¹'] +['ä¸Ĭ', '涨'] +['æľº', 'åľº'] +['å½¢', 'åĬ¿'] +['æĦ¿', 'æĦı'] +['éĽĨ', 'ä½ĵ'] +['æĸ°', 'åŀĭ'] +['æįŁ', '失'] +['æĽ', '¸'] +['ä¸ĭ', 'åįĪ'] +['æ¯ı', '次'] +['æĪIJ', 'å°±'] +['åħ¬', 'è·¯'] +['èĻ', '«'] +['åĴ', '±'] +['西', 'å®ī'] +['æľĢ', 'ä½³'] +['ç§ij', 'çłĶ'] +['å¤į', 'æĿĤ'] +['æľº', 'åύ'] +['çα', 'æĥħ'] +['çħ§', 'çīĩ'] +['å¹´', 'é¾Ħ'] +['è³ĩ', 'æĸĻ'] +['ç²', 'Ĺ'] +['åĩĨ', 'ç¡®'] +['åĬł', 'ä¸Ĭ'] +['åĩº', 'çīĪ'] +['è°', 'IJ'] +['å®¶', 'å±ħ'] +['èĥĮ', 'æĻ¯'] +['ä¸Ģ', '线'] +['äºĭ', '项'] +['åĬ¨', 'ä½ľ'] +['ç¥', '¥'] +['æĢ»', 'ä½ĵ'] +['æĪ¿', 'åŃIJ'] +['ä¹Ł', 'å°±æĺ¯'] +['大', 'æ¦Ĥ'] +['é«ĺ', 'æķĪ'] +['åIJ', '¹'] +['æİ', 'ĪæĿĥ'] +['éĻĦ', 'è¿ij'] +['æ¡Ī', 'ä¾ĭ'] +['éĹ', '¹'] +['çΏ', 'çΏ'] +['彩', '票'] +['æĢ', 'Ĵ'] +['举', 'æĬ¥'] +['æĻ®', 'éģį'] +['çķĻ', 'ä¸ĭ'] +['è¡£', 'æľį'] +['æĹłè®º', 'æĺ¯'] +['åħħ', '满'] +['æ·±', '度'] +['æ¡', 'ij'] +['æĪª', 'èĩ³'] +['带æĿ¥', 'çļĦ'] +['éĻ', 'µ'] +['æĦŁ', 'æĥħ'] +['èµ', 'ļ'] +['åĵª', 'äºĽ'] +['æķ´', 'æĶ¹'] +['æĪIJ', 'çĨŁ'] +['å¨', 'ľ'] +['é¼', '»'] +['çŁ', 'Ľ'] +['çĽ', '¾'] +['好', '好'] +['第', 'åĽĽ'] +['åĨł', 'åĨĽ'] +['è´¢', 'å¯Į'] +['æľĢ', '好çļĦ'] +['车', 'åŀĭ'] +['éĸ', 'Ģ'] +['åį³', 'å°Ĩ'] +['åĪĨ', '为'] +['éĿĴ', 'å²Ľ'] +['纷', '纷'] +['ä»Ĭ', 'æĹ¥'] +['å¹³', 'è¡¡'] +['å¹³æĸ¹', 'ç±³'] +['éĤ£', 'ç§į'] +['åĩº', 'çĶŁ'] +['éĿĴ', 'æĺ¥'] +['人', '群'] +['人', 'å·¥'] +['ä¹ĭ', 'ä¸ĭ'] +['æ¹ĸ', 'åĮĹ'] +['åľ¨', 'æŃ¤'] +['åįļ', '士'] +['æĹ¶', 'åĪ»'] +['æ²³', 'åĮĹ'] +['æĶ¾', 'å¼ĥ'] +['éĢļ', 'éģĵ'] +['森', 'æŀĹ'] +['çĸ', 'Ĩ'] +['æķ', '¸'] +['èĬ', '³'] +['æīĵ', 'åĩ»'] +['æĽ', '¹'] +['åĮĸ', 'åѦ'] +['æĥ³', '象'] +['ä¸ĩ', '人'] +['è´¢', 'ç»ı'] +['åħĥ', 'ç´ł'] +['ä¼ļ', '计'] +['åħ¨', 'ä½ĵ'] +['æĦ', 'Ľ'] +['é«ĺ', 'ä¸Ń'] +['æľº', 'éģĩ'] +['声', 'éŁ³'] +['æĹħ', 'è¡Į'] +['æµ', '©'] +['æŁ', '±'] +['å°ij', 'å¹´'] +['åĽ½', 'å¤ĸ'] +['èijĹ', 'åIJį'] +['çĶŁ', 'åŃĺ'] +['å§', 'ľ'] +['带', 'é¢Ĩ'] +['é¢ľ', 'èī²'] +['ä¸Ĭ', 'ä¸ĭ'] +['产ä¸ļ', 'éĵ¾'] +['æĽ´', '好çļĦ'] +['å²', 'Ń'] +['ä¼ĺ', 'æĥł'] +['便', 'æĺ¯'] +['åħ§', '容'] +['ä¸Ģ', 'åıª'] +['çIJ', '´'] +['梦', 'æĥ³'] +['ç§Ł', 'èµģ'] +['å¼Ģ', 'åIJ¯'] +['è´Ń', 'çī©'] +['åĮħ', 'åIJ«'] +['åĪ©', 'çİĩ'] +['èµ·', 'äºĨ'] +['æľī', 'åĬĽ'] +['éĤ£', 'éĩĮ'] +['审', 'æī¹'] +['对', 'æīĭ'] +['çݰ', 'éĩij'] +['天', 'çĦ¶'] +['çĽ', 'Ĵ'] +['çĪ', '½'] +['å¿ħ', 'çĦ¶'] +['åĮĸ', 'å·¥'] +['ä¸ĵ', 'åĪ©'] +['åķ', '¡'] +['å¼Ģ', 'å¿ĥ'] +['人', 'ä½ĵ'] +['éģĵ', '士'] +['æĢģ', '度'] +['空', 'è°ĥ'] +['æĭĽ', 'åķĨ'] +['å§', '»'] +['第', 'äºĶ'] +['æ£', 'Ĵ'] +['ä¸Ģ', 'ç³»åĪĹ'] +['åį±', 'æľº'] +['转', 'åıĺ'] +['åľº', 'æīĢ'] +['é¸', '£'] +['æĪ¿', 'éĹ´'] +['éĢ', '¼'] +['è¯ķ', 'çĤ¹'] +['对', 'å¤ĸ'] +['åĩº', 'åı°'] +['åľ¨', 'è¿Ļ'] +['åİĤ', 'å®¶'] +['å·¨', '大'] +['ç®Ģ', 'ä»ĭ'] +['çľĭ', 'äºĨ'] +['åħļ', '建'] +['æĮĩ', 'æĮ¥'] +['çŁ³', 'æ²¹'] +['ä¸į', 'åı¯èĥ½'] +['èİ', '²'] +['ä¸į', '太'] +['åĪĽ', 'æĦı'] +['第', 'ä¸Ģ个'] +['è´µ', 'å·ŀ'] +['è¿ĩ', 'äºĨ'] +['æľ¬', 'æĿ¥'] +['éģĵ', 'å¾·'] +['çŃĶ', 'æ¡Ī'] +['éĻ', '¶'] +['ä¸Ģ', 'è·¯'] +['èĤ', 'ĸ'] +['æ¸ħ', 'æ´ģ'] +['æľī', 'æľº'] +['åIJį', 'åįķ'] +['æĿ', '±'] +['åij¼', 'åIJ¸'] +['ä¸', 'Ī'] +['ç¦ı', '建'] +['è¯ķ', 'éªĮ'] +['å¼ķ', 'åıij'] +['ä¹Ł', '没'] +['ä¸į', 'ä½ı'] +['çĨŁ', 'æĤī'] +['èIJ', '¬'] +['ä¸į', 'èī¯'] +['çł', 'ĸ'] +['èĩ´', 'åĬĽ'] +['çѾ', '订'] +['åIJ', 'Ĭ'] +['ä¾', '¯'] +['çĺ', '¦'] +['å§ij', 'å¨ĺ'] +['æĸ', '¤'] +['妻', 'åŃIJ'] +['æĺ¥', 'èĬĤ'] +['çĪ', '¬'] +['æĽ', 'Ŀ'] +['çĥŃ', 'æĥħ'] +['éķ¿', 'æ²Ļ'] +['èIJ¥', 'éĢł'] +['éħ', '·'] +['éĵ', 'Ŀ'] +['åŁºæľ¬', 'ä¸Ĭ'] +['åij¨', 'åĽ´'] +['ä»Ģ', '麼'] +['认', 'åı¯'] +['åĪĨ', 'åŃIJ'] +['ä¸Ģ', 'æĸ¹éĿ¢'] +['è½', '´'] +['å¼', '·'] +['马', 'ä¸Ĭ'] +['éĽ', '¾'] +['èĩ', '£'] +['å°', '¿'] +['çĶŁ', 'æĦı'] +['å®ī', 'å¾½'] +['ç¥ŀ', 'ç»ı'] +['åĩº', 'å¸Ń'] +['èį¯', 'åĵģ'] +['çIJĨ', 'çͱ'] +['åįı', 'åIJĮ'] +['æµģ', 'åĬ¨'] +['åıij', 'åĬ¨'] +['åĿļ', 'å®ļ'] +['表', 'æĺİ'] +['åIJİ', 'éĿ¢'] +['ä¹ī', 'åĬ¡'] +['å¦', 'ĸ'] +['æľī', 'åı¯èĥ½'] +['å¹´è½»', '人'] +['大', 'éĻĨ'] +['å²', '³'] +['ä¸į', 'èµ·'] +['çŀ¬', 'éĹ´'] +['ä¸įå¾Ĺ', 'ä¸į'] +['çѾ', '约'] +['åIJĪ', 'æł¼'] +['åħļ', 'æĶ¯éĥ¨'] +['æµİ', 'åįĹ'] +['便', 'åĪ©'] +['éļı', 'æĹ¶'] +['å¥', 'ī'] +['ç§°', '为'] +['产', 'æĿĥ'] +['åIJ', 'ķ'] +['çĽ', 'Ĩ'] +['课', 'åłĤ'] +['ç·', 'ļ'] +['æ£', 'ī'] +['线', 'ä¸ĭ'] +['èĩª', 'è¡Į'] +['举', 'æİª'] +['åݦ', 'éŨ'] +['èĩª', 'ä¿¡'] +['å½±', 'è§Ĩ'] +['ä»', 'Ķ'] +['çĶŁæ´»', 'ä¸Ń'] +['æĿĥ', 'çĽĬ'] +['çϽ', 'èī²'] +['å°±', 'ä¸į'] +['è¿Ľ', 'å±ķ'] +['æ¯ı', 'æĹ¥'] +['ä¾Ľ', 'ç»Ļ'] +['æĿĥ', 'åĪ©'] +['æĹł', 'æķ°'] +['çIJĨ', 'è´¢'] +['ä¾Ŀ', 'æĹ§'] +['ä¸Ĭ', 'åįĪ'] +['è¯Ĩ', 'åĪ«'] +['çĽĪ', 'åĪ©'] +['çł', 'Ĥ'] +['许', 'åı¯'] +['åIJĮ', 'äºĭ'] +['åĺ', 'Ľ'] +['éģ', '¸'] +['çĿĢ', 'åĬĽ'] +['éŨ', 'åı£'] +['ä¸į', 'å¤ļ'] +['åħ¶', '次'] +['ç¢', '§'] +['çī©', 'çIJĨ'] +['åĨħ', 'å¿ĥ'] +['çϾ', 'å§ĵ'] +['æĢ»', '绣'] +['å¹²', 'åĩĢ'] +['积', 'ç´¯'] +['åıį', 'é¦Ī'] +['æłij', 'ç«ĭ'] +['社', '交'] +['ç§', '©'] +['åįģ', 'ä¸Ģ'] +['éĤ', 'ĵ'] +['驱', 'åĬ¨'] +['å±ķ', 'è§Ī'] +['èĪĴ', 'éĢĤ'] +['åŁº', 'åĽł'] +['å·®', 'å¼Ĥ'] +['转', '让'] +['å°ı', 'å§IJ'] +['æł·', 'åŃIJ'] +['ç¿', 'Ķ'] +['é«ĺ', 'åħ´'] +['å½±åĵį', 'åĬĽ'] +['æīĭ', 'ç»Ń'] +['缸', 'åIJĮ'] +['缸', 'åºĶ'] +['æĻ', 'Ĵ'] +['è§', 'Ģ'] +['å¸Ĥ', 'å§Ķ'] +['èĬ', '¯'] +['å±ķ', 'çݰ'] +['åľ°', 'çIJĥ'] +['éĤ', 'ª'] +['ä¸Ģå®ļ', 'çļĦ'] +['åħģ', '许'] +['ä¿¡', 'ä»»'] +['æī', 'ij'] +['éĻ¢', 'æł¡'] +['ç®Ģ', 'ç§°'] +['åģļ', 'æ³ķ'] +['ä¹ĭ', 'è·¯'] +['æĹĹ', 'ä¸ĭ'] +['èħ', 'Ķ'] +['æ¶Ī', '失'] +['ä¸ĸçķĮ', 'ä¸Ĭ'] +['åŁİ', '乡'] +['èĪŀ', 'åı°'] +['å¾Ī', '大çļĦ'] +['绣', 'çѹ'] +['åħ¬', 'å¹³'] +['èĤ', '¾'] +['çļĦ', '好'] +['æ±', 'ģ'] +['çľ¼', 'åīį'] +['éĽ', '£'] +['å¹', '½'] +['åħ±', '产'] +['主', 'åĬŀ'] +['å¤Ħ', 'ç½ļ'] +['åº', 'Ļ'] +['éģĵ', 'çIJĨ'] +['å¼', 'µ'] +['æİ¥', 'çĿĢ'] +['çĮ', 'İ'] +['çģ', 'Į'] +['çͱ', 'æŃ¤'] +['人', 'åĬĽ'] +['æµģ', 'è¡Į'] +['ä¾', 'ł'] +['åı¯ä»¥', '说'] +['èĴ', 'ĭ'] +['å½¢', 'æĢģ'] +['æĹ¥', 'åŃIJ'] +['æ¼', 'Ĩ'] +['çķĻ', 'åѦ'] +['缸', 'éĹľ'] +['æľĢ', 'å¤ļ'] +['åĩŃ', 'åĢŁ'] +['åħ¬', '交'] +['æĮĸ', 'æİĺ'] +['æĿĤ', 'å¿Ĺ'] +['主', '人'] +['éļľ', 'ç¢į'] +['æł¡', 'éķ¿'] +['æĸ¹', 'ä½į'] +['ä¸Ĭ', 'çıŃ'] +['å¤ļ', 'åħĥ'] +['è', 'ĥģ'] +['éŃħ', 'åĬĽ'] +['èĮ', 'Ĥ'] +['åħħ', 'ç͵'] +['强', '大'] +['çĥ', '¤'] +['å¥ĭ', 'æĸĹ'] +['å®ŀ', 'ç͍'] +['éĺ', 'ģ'] +['ç»Ļ', 'äºĨ'] +['æľ¬', 'ç§ij'] +['æł', 'ĭ'] +['æĭ', '¨'] +['æķĻ', 'ç»ĥ'] +['éĥ½', 'çŁ¥éģĵ'] +['æ¯ķä¸ļ', 'çĶŁ'] +['ç¢', 'Ĺ'] +['åŀ', 'Ĥ'] +['è®', '¼'] +['å®ģ', 'æ³¢'] +['åѦ', 'èĢħ'] +['è°¢', 'è°¢'] +['åŁİ', 'éķĩ'] +['æĢİä¹Ī', 'åĬŀ'] +['éģ', 'Ķ'] +['æĪIJ', '交'] +['æ½ľ', 'åĬĽ'] +['åį', '§'] +['æĸ°', 'å¼Ģ'] +['éħį', 'å¤ĩ'] +['主', 'åĬĽ'] +['åij³', 'éģĵ'] +['çĥ', 'Ĥ'] +['é£ŀ', 'è¡Į'] +['å«', 'ģ'] +['大', '大'] +['ç»Ļ', '大家'] +['å¤ĸ', 'éĿ¢'] +['éĨ', 'ī'] +['åıij', 'è¨Ģ'] +['æĹ©', 'é¤IJ'] +['åIJĦ', 'èĩª'] +['å®', 'Ļ'] +['èį£', 'èªī'] +['æĬ«', 'éľ²'] +['é¡', 'ŀ'] +['åĨħ', 'çļĦ'] +['èĤ', 'ª'] +['è¾', 'IJ'] +['æ³', 'µ'] +['æĬ', 'Ľ'] +['æĺŁ', 'æľŁ'] +['ä¸Ģ', '带'] +['çĶŁ', 'ç´ł'] +['ç»ı', 'éĶĢ'] +['åĩ', '¶'] +['åľ°', 'ä¸Ĭ'] +['åij½', 'è¿IJ'] +['åĵ', '²'] +['ä¸Ĭ', 'åİ»'] +['æĸĩ', 'çī©'] +['è¯', 'ij'] +['æĮ¯', 'åħ´'] +['éķ¿', 'æĹ¶éĹ´'] +['ç¥', 'Ń'] +['åIJĪ', 'èĤ¥'] +['è¿Ŀ', 'è§Ħ'] +['èģ', 'ª'] +['ä½İ', 'äºİ'] +['éĢĤ', 'å½ĵ'] +['æľī', 'åºı'] +['æľ¬', 'ç½ij'] +['çķĻ', 'è¨Ģ'] +['æĥ³', 'æ³ķ'] +['çѾ', 'ç½²'] +['å§', 'ļ'] +['æĢ§', 'æł¼'] +['èĴĻ', 'åı¤'] +['æŁ', 'ı'] +['åŀ', '«'] +['åѦ', 'åİĨ'] +['ä»ħ', 'ä»ħ'] +['讲', 'è¯Ŀ'] +['éĶ', 'IJ'] +['æĢ', 'ĸ'] +['åī', 'ª'] +['èĭ', 'į'] +['åIJ', 'ĵ'] +['强', 'çĥĪ'] +['åģ¥', 'åħ¨'] +['çĸ', '¯'] +['åı¤', '代'] +['å¥', 'Ī'] +['ä¸į', 'çĦ¶'] +['乡', 'éķĩ'] +['æľĭåıĭ', '们'] +['åĤ', 'ħ'] +['èģ', '½'] +['个', 'æĢ§'] +['æ³ķ', 'è§Ħ'] +['å°ı', 'éķĩ'] +['çĶ»', 'éĿ¢'] +['第', 'åħŃ'] +['ç¶²', 'è·¯'] +['åīį', 'æĻ¯'] +['åIJ¬', '说'] +['ä¼ł', 'åªĴ'] +['æĿ¡', 'ä¾ĭ'] +['åĪ«', 'çļĦ'] +['ä¸į', 'æĩĤ'] +['顾', 'éĹ®'] +['强', '度'] +['éĺ¿', 'éĩĮ'] +['èµ°', 'åĬ¿'] +['å¸', '½'] +['çļĦ', 'ç¡®'] +['åĮº', 'åĪ«'] +['éĮ', '¢'] +['主', '管'] +['ä¸Ģ', 'çľĭ'] +['æĸ', 'ľ'] +['åŃĺåľ¨', 'çļĦ'] +['ä»', '²'] +['åį±', '害'] +['éĵ', 'Ń'] +['游æĪı', 'ä¸Ń'] +['éħ', '±'] +['é¾Ļ', '头'] +['人', 'å¿ĥ'] +['éĢĢ', 'ä¼ij'] +['æµı', 'è§Ī'] +['åĬ', '«'] +['éĺ²', 'æ²»'] +['ç®', 'Ń'] +['å±', 'Ī'] +['è¾½', 'å®ģ'] +['å£', '¤'] +['è¿İ', 'æĿ¥'] +['éŀ', 'į'] +['ç͍', 'æĿ¥'] +['大', 'åľ°'] +['ä»', '°'] +['éĢļ', '讯'] +['å¼Ģ', 'å·¥'] +['è£', '¤'] +['å¦Ĥ', 'åIJĮ'] +['éª', '¤'] +['éĺŁ', 'åijĺ'] +['è½', '©'] +['ç¾İ', 'æľ¯'] +['èĻ', 'Ł'] +['åIJĮ', 'ä¸Ģ'] +['åľ', 'ĸ'] +['书', 'æ³ķ'] +['æīĵ', 'åį°'] +['åIJ«', 'æľī'] +['éĽĨ', 'æĪIJ'] +['éĹ', '·'] +['å¸Ĥåľº', 'ä¸Ĭ'] +['æĹģ', 'è¾¹'] +['åľ°', 'æĿ¿'] +['产çĶŁ', 'çļĦ'] +['ç²', '¤'] +['éĩį', 'ç»Ħ'] +['è¡Ģ', 'æ¶²'] +['çŃ', 'ĭ'] +['åĬŀ', 'äºĭ'] +['常è§ģ', 'çļĦ'] +['ä¸Ĭ', 'åįĬå¹´'] +['å±ı', 'å¹ķ'] +['åIJī', 'æŀĹ'] +['å·', '©'] +['åĸľ', 'çα'] +['ç¿', 'ł'] +['ä¸ī', 'ç§į'] +['æ¡Ĩ', 'æŀ¶'] +['举', 'èİŀ'] +['çĶĺ', 'èĤĥ'] +['èĬ', '¬'] +['åĽ¾', '书'] +['åĩ¤', 'åĩ°'] +['æ°Ķ', 'åĢĻ'] +['å°', '´'] +['å°', '¬'] +['两', '天'] +['è¾ħ', '导'] +['åĢŁ', '款'] +['æĹ¥', 'èµ·'] +['æ´', 'Ĵ'] +['ä¸Ģ', '度'] +['è¹', 'Ī'] +['æ½', 'Ń'] +['æī', 'ĩ'] +['çĻ', 'ľ'] +['æĸ°', 'åħ´'] +['åĤ', '²'] +['诸', 'å¤ļ'] +['è´', 'ª'] +['éĻ·', 'åħ¥'] +['èĪ', 'Ł'] +['èĤº', 'çĤİ'] +['ä¸Ģ', 'æł·çļĦ'] +['åİ', 'ĺ'] +['åľ°', 'çIJĨ'] +['æĬķ', '注'] +['éļ', 'Ĭ'] +['åħī', 'ä¼ı'] +['ä¿Ŀ', 'åģ¥'] +['åħ', 'Ķ'] +['åħ¬', 'åĬ¡'] +['æīĵ', 'çł´'] +['çĶ·', 'åŃ©'] +['åĬ³', 'åĬ¡'] +['ä½ł', 'ä¼ļ'] +['ç͍', 'åľ°'] +['æº', '¢'] +['åıij', 'è¾¾'] +['èĤ', 'ļ'] +['è¿ĩ', 'äºİ'] +['èĩ', 'Ĥ'] +['éĢĻ', '樣'] +['è½»', 'è½»'] +['ä¸Ń', 'åħ±'] +['åIJĦ', 'åĽ½'] +['åĶ', 'ĩ'] +['å®ŀ', 'ä¹ł'] +['èĻ', '¾'] +['æ§', '½'] +['ä¸į', 'ä¸Ĭ'] +['åħį', 'çĸ«'] +['åįł', 'æį®'] +['å·¥', 'ä¼ļ'] +['åĽ', 'Ĭ'] +['èĪª', '天'] +['åı¯', 'çα'] +['æĸĹ', 'äºī'] +['çĺ', '¤'] +['å¦Ĥ', 'æľī'] +['éĽ', 'ĸ'] +['对', 'æĪij'] +['åĩº', 'ç§Ł'] +['好', 'çľĭ'] +['太', '大'] +['æ°´', 'åĪ©'] +['åĬ¿', 'åĬĽ'] +['åħ¨', 'æ°ij'] +['ç½', '¢'] +['èµ¢', 'å¾Ĺ'] +['ç͵', 'ä¿¡'] +['车', 'éĹ´'] +['æĻĤ', 'åĢĻ'] +['å°ij', 'æķ°'] +['éĵ', '¸'] +['åħ³', 'èģĶ'] +['ä¸įä»ħ', 'ä»ħ'] +['为', 'æĤ¨'] +['åĴ', '¸'] +['æľº', 'åĬ¨'] +['è£', 'Ļ'] +['åĵį', 'åºĶ'] +['éģ', 'ł'] +['è²', '·'] +['ç©', '´'] +['å¢', 'ħ'] +['éĶ', '¡'] +['çµ', 'Ħ'] +['çģ«', '车'] +['è³ĩ', 'è¨Ĭ'] +['åĨ³', 'èµĽ'] +['污', 'æ°´'] +['èª', 'ŀ'] +['å´', 'Ľ'] +['ç´§', 'å¯Ĩ'] +['缺', 'å°ij'] +['å¤ļ', '人'] +['æĢ»', '书记'] +['éĶ', 'Ī'] +['èij', 'Ľ'] +['å¿ĺ', 'è®°'] +['éĻĮ', 'çĶŁ'] +['éķ¿', '大'] +['åħĪè¿Ľ', 'çļĦ'] +['ç¡', 'ħ'] +['åıij', 'æĺİ'] +['å©´', 'åĦ¿'] +['æīİ', 'å®ŀ'] +['èĽĭ', 'çϽ'] +['ä¸Ģ', 'çϾ'] +['缮', 'åħī'] +['æ', 'ħĮ'] +['åĬł', 'æ²¹'] +['åIJ', 'ŀ'] +['ä¸Ģ', '群'] +['ä¸Ń', 'ä»ĭ'] +['å¸', 'ĸ'] +['å¿', 'Į'] +['èģĮ', 'èĥ½'] +['广', 'æĴŃ'] +['çĽij', 'å¯Ł'] +['ç§ĺ', 'å¯Ĩ'] +['çĭ', '®'] +['è¿Ļ', 'æĿ¡'] +['éĢ', '¢'] +['æĢ', '¨'] +['åįģ', 'åħŃ'] +['è©', '¦'] +['说', 'åΰ'] +['åĩĿ', 'èģļ'] +['æĮĩ', '示'] +['æ°', '¢'] +['å¼', 'ĺ'] +['éĺ', 'Ģ'] +['æĸ', '©'] +['éł', 'ħ'] +['ä¸Ģ', 'å¼Ģå§ĭ'] +['æİĴ', 'è¡Į'] +['åľ¨', 'æĪij'] +['纪', 'å½ķ'] +['æĬ', 'Ħ'] +['æł', 'ª'] +['说', 'æ³ķ'] +['ä¸Ń', 'èį¯'] +['好', 'å¤ļ'] +['åıª', 'ä¸įè¿ĩ'] +['çķĻ', 'åľ¨'] +['个', 'å°ıæĹ¶'] +['认', 'çŁ¥'] +['çķ', '«'] +['è§ģ', 'è¿ĩ'] +['å°ı', 'å¾®'] +['ä½Ľ', 'å±±'] +['çľ', '¾'] +['讲', 'è¿°'] +['æ¢', '³'] +['ç§°', 'åı·'] +['æĹ¥', 'æĻļ'] +['è¢', 'ĸ'] +['åķ', '¤'] +['æľª', 'ç»ı'] +['æľĢ', 'æĹ©'] +['æī®', 'æ¼Ķ'] +['è¡Ģ', '管'] +['çº', '±'] +['æĥħ', 'èĬĤ'] +['第', 'ä¸ĥ'] +['æį', '§'] +['ä»', 'Ĺ'] +['æ¿Ģ', 'çĥĪ'] +['æĹł', '线'] +['ä¸į', '容æĺĵ'] +['å¼Ģ', 'å¹ķ'] +['æĸ°', 'çĶŁ'] +['ä¸ĵ', '注'] +['èij', '±'] +['åįĹ', 'æµ·'] +['çĩ', 'Ł'] +['èµ·', 'ä¾Ĩ'] +['æ´¾', 'åĩº'] +['åĦ', 'Ĵ'] +['ä¾', '¨'] +['è¼', 'ĥ'] +['åįļ', 'è§Ī'] +['éĢ', '¾'] +['åĮ', 'Ģ'] +['ç»ıæµİ', 'åѦ'] +['æ¸', 'Ĺ'] +['ä¿Ŀ', 'èŃ·'] +['çī', 'º'] +['çī', '²'] +['çİ', '«'] +['çij', '°'] +['æľĢåIJİ', 'ä¸Ģ'] +['æĶ¿', 'åĬ¡'] +['æ§', 'Ľ'] +['èĻķ', 'çIJĨ'] +['éļIJ', 'æĤ£'] +['æī¿', 'åĮħ'] +['æ¥', 'µ'] +['æ¡', '©'] +['çĽ', '²'] +['导', 'åIJij'] +['èĩ´', 'å¯Į'] +['ç¼', 'Ĩ'] +['æģĭ', 'çα'] +['ä¸į', 'åĬ¨'] +['ç»Ļ', '人'] +['å·', '¢'] +['表', 'æĥħ'] +['举', 'åįĹ'] +['åĨħ', 'å¤ĸ'] +['è¾Ī', 'åŃIJ'] +['åı', 'ī'] +['åįļ', 'ä¼ļ'] +['åĬŁ', 'æķĪ'] +['æ¸', '´'] +['å±', '¬'] +['æİĴ', 'éϤ'] +['éĢ', 'Ľ'] +['ä¸Ģ', 'ä¼ļ'] +['ä¸į', 'å¼Ģ'] +['å¼Ģ', 'å¥ĸ'] +['é»ij', 'é¾Ļ'] +['é»ijé¾Ļ', 'æ±Ł'] +['å¿«', 'ä¸ī'] +['度', 'åģĩ'] +['åĿ', '¤'] +['éĤ®', 'ä»¶'] +['æĩ', 'Ĵ'] +['ä¾Ľ', 'ç͵'] +['å»', '£'] +['好', 'è¯Ħ'] +['ç§ĺ书', 'éķ¿'] +['æĪĺ', 'åľº'] +['好', 'å¥ĩ'] +['ä¾µ', 'æĿĥ'] +['æĨ', '¾'] +['æľĢ', 'åĪĿ'] +['æī¹', 'åıij'] +['åİ', 'ķ'] +['è¼', 'ķ'] +['æŀ', '¯'] +['ä¸ļ', 'åĨħ'] +['è´Ń', 'æĪ¿'] +['ä¸į', 'åľ¨'] +['纪', 'å§Ķ'] +['æīĢ', 'éľĢ'] +['å¸Ĥ', 'éķ¿'] +['è³', '½'] +['å¼ķ', 'æĵİ'] +['çģµ', 'éŃĤ'] +['éĬ', 'Ģ'] +['æ»', '¤'] +['çĿ', 'IJ'] +['å¤ļ', '项'] +['åĽŀ', '头'] +['èī', 'ĺ'] +['å¤į', 'å·¥'] +['éĥ¨', 'ä»¶'] +['ç´§', 'ç´§'] +['æŁIJ', 'ç§į'] +['使', 'åħ¶'] +['æĸ°', '人'] +['æŀ', 'ļ'] +['æ³ķ', 'å®ļ'] +['å·´', 'å·´'] +['æ¶µ', 'çĽĸ'] +['ç¨', '»'] +['æĭ', '¾'] +['æĻ', 'ķ'] +['è½', '¿'] +['éĢļ', 'è¡Į'] +['åĵ', 'Ģ'] +['æ³', 'Ĭ'] +['温', '馨'] +['éĽĨ', 'èģļ'] +['çĨ', 'Ļ'] +['åĩ', 'ij'] +['åįģ', 'ä¸ĥ'] +['æ°Ķ', 'æģ¯'] +['æıIJä¾Ľ', 'çļĦ'] +['æ³', '³'] +['奥', 'è¿IJ'] +['çģ¾', '害'] +['åĩĢ', 'åĮĸ'] +['è·¨', 'è¶Ĭ'] +['åĵª', 'æĢķ'] +['éŁ', '¿'] +['å¢ŀ', 'æ·»'] +['çĦ', 'Ĭ'] +['æ®ĭ', 'çĸ¾'] +['ç¢', 'Į'] +['æĤ', 'Ķ'] +['è§ģ', 'è¯ģ'] +['è¾ĸ', 'åĮº'] +['å¿ĥ', 'èĦı'] +['éļ', '§'] +['åį', '¸'] +['åı¯èĥ½', 'æĢ§'] +['æľī', 'è¶£'] +['åī¯', '书记'] +['åĮĸ', 'å¦Ĩ'] +['ä¿', 'Ĥ'] +['æ£', 'ļ'] +['éĨ', 'ĩ'] +['带', '头'] +['éł', 'Ī'] +['追', 'ç©¶'] +['æij', 'Ķ'] +['è¿Ļ', 'éĥ¨'] +['ä¸į', '论'] +['ç¥', '¸'] +['å', '³»'] +['éģ', 'ķ'] +['çĶŁ', 'èĤ²'] +['å¤', 'ł'] +['å¤ĸ', '交'] +['è¯Ħ', '为'] +['ä»İ', 'å°ı'] +['å°ı', 'å°ı'] +['é', '¥¿'] +['æĴ', '¼'] +['è·¨', 'å¢ĥ'] +['被', 'åijĬ'] +['åįĹ', 'å®ģ'] +['身', 'å¿ĥ'] +['åĨį', 'çĶŁ'] +['æīĢ', '说'] +['æĹ¶éĹ´', 'åĨħ'] +['åĪĹ', 'åħ¥'] +['éĿĴ', 'æµ·'] +['çα', '好'] +['çª', 'Ħ'] +['èĪ', 'Ī'] +['è¿ĩ', '渡'] +['æ¿', 'Ł'] +['éĽ', 'Ģ'] +['审', 'è®®'] +['åĽ½', 'èµĦ'] +['æŃ¥', 'ä¼IJ'] +['轨', 'éģĵ'] +['ä¿¡', '念'] +['ä¸ī', 'åĪĨ'] +['çĨ', '¬'] +['åѵ', 'åĮĸ'] +['ç¼', 'ł'] +['éĥ', 'Ĭ'] +['èĪĴ', 'æľį'] +['纪', 'æ£Ģ'] +['ä¸Ģä¸ĭ', 'åŃIJ'] +['鼻', '話'] +['è²', 'ł'] +['éĴ', '¥'] +['åĮ', 'Ļ'] +['çĹ', '´'] +['è¶', 'ģ'] +['ç»', '£'] +['çĪ', 'µ'] +['è½', '°'] +['éª', 'Ħ'] +['å§', '¨'] +['æĭ', 'ĺ'] +['çĮ', '´'] +['è®', '¶'] +['è¿Ļ', '座'] +['çį', '¨'] +['æ·ĺ', 'æ±°'] +['çĹħ', 'ä¾ĭ'] +['æ²Ļ', 'åıij'] +['è§Ĩ', '为'] +['头', 'æĿ¡'] +['å¿ħè¦ģ', 'çļĦ'] +['åı¯', 'è°ĵ'] +['è¯Ŀ', '说'] +['ç¯', 'Ħ'] +['æĹ©', 'çĤ¹'] +['æŀ¢', '纽'] +['ç¾', '¡'] +['çα', 'åĽ½'] +['çªģ', 'åıij'] +['éĢ', 'Ĭ'] +['æ½', 'į'] +['èį£', 'èĢĢ'] +['èŁ', '¹'] +['æ¦Ĥ', 'çİĩ'] +['å¾Ī', 'ä¹ħ'] +['æĥ', 'ķ'] +['è¨', '´'] +['åľĨ', '满'] +['çļ', '±'] +['åĪĨ', 'æ³Į'] +['åħħ', 'è¶³'] +['çľĭ', 'æ³ķ'] +['è¾', 'Ł'] +['æĭ', '¦'] +['æĭ', '©'] +['对', 'åºĶ'] +['为', 'æł¸å¿ĥ'] +['èħ', 'Ĭ'] +['å¤ļ', 'ä¹Ī'] +['æµ', 'ij'] +['å®ı', 'è§Ĥ'] +['èĦ', 'ĸ'] +['åIJĪ', 'èµĦ'] +['çĶŁ', '涯'] +['å®ŀ', 'è´¨'] +['ä¼ĺ', 'çĤ¹'] +['ç͍', 'æ°´'] +['寿', 'åij½'] +['æ²', '«'] +['åIJ', 'ģ'] +['è©', '¹'] +['åĽ½', 'éĺ²'] +['å´', '©'] +['åĿ', 'İ'] +['èĨ', 'ı'] +['ä¸Ģ', 'è½®'] +['éģĹ', '产'] +['æ¹¾', 'åĮº'] +['ç»', 'İ'] +['åįķ', '纯'] +['æ¾', 'Ħ'] +['åīį', 'åĪĹ'] +['身', 'å½±'] +['é»ĺ', 'é»ĺ'] +['æį', 'ī'] +['çĴ', '°'] +['èı', 'Ĭ'] +['æĢ', 'ľ'] +['åħĭ', 'æĢĿ'] +['æĢ»', 'å±Ģ'] +['çĩĥ', 'æĸĻ'] +['ä¸ļ', 'æĢģ'] +['åIJĦ', 'æł·'] +['åĴ', '½'] +['åĩº', 'èī²'] +['åĪĿ', 'å¿ĥ'] +['åı', 'Ľ'] +['çłĶ', '讨'] +['è¡', '«'] +['åİĨ', 'ç¨ĭ'] +['ç¦', '½'] +['è¶³å¤Ł', 'çļĦ'] +['èį', 'Ĩ'] +['çľĭ', 'å¾ħ'] +['è´', '©'] +['åĨ³', 'å¿ĥ'] +['è£', '¹'] +['å¸Ī', 'èĮĥ'] +['åŀ', 'Ħ'] +['æĿ', 'ł'] +['åĩ', '¸'] +['çĬ¹', '豫'] +['çĥŃ', 'è¡Ģ'] +['åIJĪ', 'ä¼Ļ'] +['éħ', 'µ'] +['èIJ½', 'åľ¨'] +['åįł', 'åľ°'] +['è¡', '¬'] +['èĵ', 'ī'] +['æĦ', '¤'] +['æ¸', 'Ĭ'] +['åĪĨ', 'æķ°'] +['ç¬ij', 'çĿĢ'] +['太', 'å¹³'] +['çĤ', '«'] +['æİ¨', 'ä»ĭ'] +['æĸ¯', 'åĿ¦'] +['å½¢', '容'] +['æĵ', 'Ĭ'] +['æĦŁ', 'åħ´è¶£'] +['åĨĽ', '人'] +['åĩĮ', 'æĻ¨'] +['对', 'çħ§'] +['åıij', 'çĹħ'] +['å·', '¾'] +['èĪ', 'ī'] +['æª', '¢'] +['ç¬ij', 'äºĨ'] +['ç¡®', 'è¯Ĭ'] +['è´Ł', 'åĢº'] +['壮', '大'] +['æĪ', 'ļ'] +['äºĴ', 'èģĶ'] +['èª', '²'] +['èħ', '¦'] +['æĹ', '±'] +['åıĹ', '欢è¿İ'] +['åį', 'ī'] +['éĻ¢', '士'] +['æ©', '¡'] +['ä¸Ģ', '对'] +['è¾', '±'] +['æ²', 'Ĥ'] +['åı²', 'ä¸Ĭ'] +['æIJ', 'ı'] +['å´', 'ĸ'] +['代', 'è°¢'] +['ç£', '·'] +['é¡', 'ĺ'] +['æµ', 'ĩ'] +['常', 'ç͍'] +['åį', 'ij'] +['åĩº', 'åĽ½'] +['è¯', 'ł'] +['稳', 'æŃ¥'] +['ç»ı', '纪'] +['å¤ļ', 'å¤ļ'] +['æīĢ', 'å¾Ĺ'] +['为', '主é¢ĺ'] +['ä¸Ģ', 'åĪĨ'] +['æł', '½'] +['é¡', '§'] +['çº', '²'] +['åĥ', 'ħ'] +['å£', 'ĵ'] +['åĦ', 'ª'] +['ç¿', '°'] +['æİ', 'Ģ'] +['人', '为'] +['åª', '³'] +['æ´', '½'] +['èĿ', '¶'] +['å¤į', 'åħ´'] +['ä¼ļ', 'å½±åĵį'] +['åIJĦ', 'çķĮ'] +['éĤ£', 'ä¸Ģ'] +['é¢', '¤'] +['çĢ', 'ı'] +['çĢı', '覽'] +['å¯', 'ŀ'] +['åı¯', 'æĢķ'] +['åį³', 'æĹ¶'] +['çķ', '´'] +['ä¸ĭ', 'åįĬå¹´'] +['ç¬Ķ', 'è®°'] +['éĻĦ', 'åĬł'] +['çĥŃ', 'æ°´'] +['å¥', '¸'] +['ç£', 'ħ'] +['æĿ', 'ī'] +['æ¸ħ', 'åįİ'] +['éĸ', '±'] +['ç°', '¡'] +['å¤Ħ', 'å¤Ħ'] +['åIJĪ', 'éĩij'] +['æ²³', 'æµģ'] +['ç´', '°'] +['è´Ł', 'éĿ¢'] +['çļĦ', '羣å®ŀ'] +['åύ', '械'] +['èĴ', 'IJ'] +['西', 'äºļ'] +['å·', 'ħ'] +['ç²', '¹'] +['åİŁ', 'æĸĩ'] +['æŀ', 'ķ'] +['è¡Ģ', 'åİĭ'] +['åļ', '´'] +['å¸', 'ĺ'] +['åĨ', 'Ģ'] +['æĮ', '«'] +['ç͵', 'è·¯'] +['å°ı', 'ä¼Ļä¼´'] +['èĿ', '´'] +['æľĢ', 'å¿«'] +['æĭ', 'Į'] +['å®', 'ª'] +['æĸ', '·'] +['ç¿', 'ħ'] +['åĴ', '³'] +['åĹ', '½'] +['ç¾', 'ŀ'] +['躺', 'åľ¨'] +['èµĽ', '车'] +['æ²', 'IJ'] +['éĻIJ', '度'] +['为', 'ä¸Ģä½ĵ'] +['èĴ', 'ľ'] +['å¹', '«'] +['æIJ', 'ħ'] +['åĭ', 'ĭ'] +['åī', 'ĸ'] +['纳', 'ç¨İ'] +['éķ¿', 'æķĪ'] +['ç½', 'ķ'] +['åī¯', 'æľ¬'] +['ç©', 'į'] +['éĴ', '©'] +['ç¹', '¼'] +['åĽ½', 'åľŁ'] +['è¼', 'ī'] +['ä¸į', 'å¿ĺ'] +['èѦ', '示'] +['çģ', '¿'] +['å¿ĥ', 'å¾Ĺ'] +['æĦ', 'ļ'] +['忽', 'çķ¥'] +['åĽŀ', 'äºĭ'] +['åįł', 'æľī'] +['æ·', 'Ħ'] +['çī', '¡'] +['çĽij', 'äºĭ'] +['ç¿', '¡'] +['éĴĪ对', 'æĢ§'] +['çª', 'ĥ'] +['è£', '½'] +['èĨ', 'Ŀ'] +['ç³', 'Ł'] +['港', 'æ¾³'] +['太', '太'] +['æ¾', '¡'] +['ç»Ĩ', 'åĮĸ'] +['åĶ®', 'åIJİ'] +['å®ŀåľ¨', 'æĺ¯'] +['ç«', '£'] +['çį', '²'] +['å̾', 'åIJij'] +['å¼ķ', 'ç͍'] +['é¹', 'ħ'] +['ç¬ij', '容'] +['ä¹IJ', 'è¶£'] +['æ°ij', 'æĶ¿'] +['éŨ', 'æĪ·'] +['å±', 'ģ'] +['è¿·', '失'] +['éĶ', 'Į'] +['å°ı', '康'] +['åĭ', 'ī'] +['æ³', '¼'] +['ä¾ĭ', 'åŃIJ'] +['ä¸ī', 'ä½į'] +['å»', 'ł'] +['èĶ', 'ĵ'] +['广', 'éĺĶ'] +['èĢ', 'į'] +['èĢģ', 'èĻİ'] +['åĭŁ', 'éĽĨ'] +['èĦļ', 'æŃ¥'] +['æĭ', '¯'] +['åŃĹ', 'åı·'] +['çĦ', '°'] +['é¢', 'ł'] +['èļ', 'Ĥ'] +['èļ', 'ģ'] +['é£', '¯'] +['人', 'æĢ§'] +['æĴ', '°'] +['åİ', '¢'] +['å±Ģ', 'éĻIJ'] +['æľª', 'æĪIJ'] +['åĵª', 'åĦ¿'] +['大', 'åıij'] +['ä¸į', 'å®ļ'] +['å¾ģ', 'æ±Ĥ'] +['éĥ', 'µ'] +['åĢº', 'æĿĥ'] +['çα', 'ä½ł'] +['èº', 'ģ'] +['ä»ħ', 'ä¾Ľ'] +['è¿ľ', 'å¤Ħ'] +['éĨ', 'Ľ'] +['åĥ', 'µ'] +['积æŀģ', 'æĢ§'] +['æİ', '¡'] +['åīį', 'ä¸ī'] +['äºİ', 'ä¸Ģä½ĵ'] +['çŀ', 'Ħ'] +['çĿ', 'ģ'] +['æ²', '¸'] +['åħ±', 'èµ¢'] +['éĢĢ', 'å½¹'] +['è´Ŀ', 'å°Ķ'] +['æİ', 'ı'] +['æĪ', '²'] +['è¡', 'į'] +['éĶ', 'Ĥ'] +['ä¸ĩ', 'ä½Ļ'] +['ç§ij', 'åĪĽ'] +['æ¼Ķ', 'åͱ'] +['欧', 'åħĥ'] +['æ·¡', 'æ·¡'] +['éĿĴ', 'å±±'] +['èĹ', 'Ŀ'] +['ç»', '½'] +['令', 'çīĮ'] +['éĽĨ', '群'] +['ä½ľ', 'çī©'] +['çĢ', 'ij'] +['å¤', '¯'] +['ç½ij', '游'] +['åħ«', '大'] +['éª', 'ļ'] +['èª', 'ĵ'] +['ä¼ļ', 'å±ķ'] +['åħļ', 'åı²'] +['æ£Ģå¯Ł', 'éĻ¢'] +['åĸ', 'ĺ'] +['éĺ', '±'] +['èĢĮ', 'åĩº'] +['éĢļ', '车'] +['éĴ', 'ĵ'] +['æĥħ', '人'] +['æ¸', 'Ľ'] +['ä¸Ń', 'ç§ĭ'] +['çĪ', 'Ń'] +['åıª', 'åī©'] +['æĺ', 'Ķ'] +['éĩİ', 'çĶŁ'] +['ç¡', '«'] +['èIJĿ', 'åįľ'] +['æĬµ', 'æĬĹ'] +['çĻ«', 'çĹ«'] +['éĻ', 'Ģ'] +['èĶ', 'ļ'] +['å¸', 'ľ'] +['满', '满'] +['èı', '±'] +['éļĨ', 'éĩį'] +['æĺŁ', '级'] +['æ½', 'ĩ'] +['åħ¬', 'åħĥ'] +['è°', '£'] +['æ¯Ķ', 'äºļ'] +['æ¡Į', 'åŃIJ'] +['èµ', '£'] +['è²', '¼'] +['æĦ¿', 'æľĽ'] +['é¡', '½'] +['æ´¾', 'éģ£'] +['ç¥', 'Ľ'] +['åª', 'ļ'] +['éĺ', 'ľ'] +['èij', '«'] +['èĬ', '¦'] +['æ³', '»'] +['å¡', 'Į'] +['çĭ', 'Ń'] +['å»ī', 'æĶ¿'] +['å¥ij', 'æľº'] +['æĹĹ', 'èΰ'] +['æĥ', '«'] +['严', 'åİī'] +['åıĭ', 'æĥħ'] +['å¦', 'Ĭ'] +['å¨', 'ł'] +['åĵª', 'å®¶'] +['èĨ', '¨'] +['è¶', 'Ł'] +['æĮ', 'ª'] +['èĻ', 'IJ'] +['é', 'łģ'] +['çŀ', '©'] +['éº', 'Ł'] +['ç¨', '£'] +['èģĶ', 'éĢļ'] +['åı', '®'] +['çİĭ', 'èĢħ'] +['ä¸į', 'ç¡®å®ļ'] +['ç', 'ijľ'] +['è°', 'İ'] +['çī¢', 'è®°'] +['ç¢', '¼'] +['æĬ¤', 'èĤ¤'] +['é¡', '·'] +['çĦ', 'ķ'] +['åģļ', '强'] +['éļ±', 'ç§ģ'] +['éļ±ç§ģ', 'æ¬Ĭ'] +['åıĹ', '害'] +['ä¸į', 'çͱ'] +['çĥ', '¹'] +['é¥', 'ª'] +['é©', '³'] +['ä¼', '½'] +['ä¸Ŀ', '绸'] +['è¥', 'Ħ'] +['åįģ', 'ä½Ļ'] +['éº', 'Ĺ'] +['æ¬Ĭ', 'åĪ©'] +['èģ', 'ŀ'] +['åı¤', 'èĢģ'] +['éģ', 'ı'] +['åIJĦ', 'å¼ı'] +['å°±', 'è¡Į'] +['åħ¥', 'å¢ĥ'] +['ç', 'ĥģ'] +['èľ', 'ĺ'] +['èĽ', 'Ľ'] +['çº', '¬'] +['çŁ', '«'] +['è»', 'Ł'] +['æ´Ĺ', 'è¡£'] +['æĦ', '§'] +['é¢Ħ', 'æ¡Ī'] +['éľ', 'Ĩ'] +['æ·±', 'åİļ'] +['éĺ¿', 'æĭī'] +['åĨĻ', 'åŃĹ'] +['åį', '¦'] +['éķ', 'Ģ'] +['模', 'æł·'] +['åĤ', 'į'] +['æIJ', 'į'] +['èĸ', '¯'] +['åł', 'ħ'] +['åħ¬', '积'] +['è¨', 'İ'] +['ä¼ł', 'æŁĵ'] +['æ¯', '¯'] +['çIJĨ', 'å·¥'] +['åĨ·', 'éĵ¾'] +['ç«ĭ', 'æĸ¹'] +['æ¢', 'Ń'] +['åľ£', 'è¯ŀ'] +['综', 'èīº'] +['çİ©', 'ç¬ij'] +['æĥ³', 'ä¸įåΰ'] +['æijĩ', '头'] +['æ·', '¹'] +['åģĩ', 'æĹ¥'] +['åĢ', 'ĺ'] +['èĢ', '½'] +['èİ', 'ĵ'] +['åŁ', '·'] +['èĩª', 'è´¸'] +['åįĬ', '天'] +['æª', 'Ķ'] +['æ¾İ', 'æ¹ĥ'] +['éķ', 'ij'] +['ä¸', '«'] +['éĩĮ', 'ç¨ĭ'] +['å¼Ģ', 'èįĴ'] +['èı', 'ı'] +['å®Ŀ', 'è´µ'] +['èŃ', '¬'] +['åķ', 'Ł'] +['æŁ', 'ł'] +['æª', '¬'] +['é©', 'Ń'] +['æ±', 'Ľ'] +['çĨĬ', 'çĮ«'] +['èķ', 'ī'] +['éļı', 'ä¹ĭ'] +['å±', 'ij'] +['è¾ĥ', '强'] +['èĥ', '³'] +['èĨ', 'Ĭ'] +['éĿĻ', 'éĿĻ'] +['åĴ', 'ª'] +['æĭĽ', 'åij¼'] +['代', 'è¨Ģ'] +['ä¿¡', 'ç®±'] +['è£ħ', 'éħį'] +['æĤ', 'į'] +['åįķ', '车'] +['èIJ', 'İ'] +['å¤ļ', '彩'] +['éĻ', '¸'] +['ä»İ', '严'] +['æ©', 'Ħ'] +['æ¦', 'Ħ'] +['éĢ', '®'] +['éĩĮ', 'æĸ¯'] +['å§¿', 'æĢģ'] +['太', 'æŀģ'] +['éĩ', 'Ŀ'] +['æº', 'ī'] +['è¿', 'Ń'] +['ç§', '¸'] +['ç§', 'Ĩ'] +['å·¥', 'å§Ķ'] +['æ±', 'ķ'] +['èģ', 'Ĩ'] +['ä½', '¬'] +['ç¼', 'ħ'] +['çĶ', '¸'] +['åī¯', 'å±Ģéķ¿'] +['éĹ', 'º'] +['èª', '¤'] +['è¤', 'IJ'] +['ä¸į', 'éĻIJ'] +['èħ', 'ķ'] +['åij', 'ķ'] +['çŁ', '¶'] +['åĨľ', 'å®¶'] +['管', 'å§Ķä¼ļ'] +['é¥', 'º'] +['èĬ', 'ľ'] +['æ¾', 'Ī'] +['è©', '¢'] +['å¨ģ', 'å°¼æĸ¯'] +['ä½ķ', 'åĨµ'] +['å°ı', 'ä¼Ļ'] +['奢', 'ä¾Ī'] +['è¿Ļ', 'ç¯ĩ'] +['è¯', 'µ'] +['竳', 'ç¨ĭ'] +['ç´', 'Ģ'] +['éIJ', 'ĺ'] +['éĤ', '¢'] +['ç³', 'Ļ'] +['ç¼', 'Ģ'] +['ä¹', 'Ĵ'] +['ä¹', 'ĵ'] +['çī¢', 'åĽº'] +['åĿ', 'ŀ'] +['å¼', 'Ī'] +['ä¾ĭ', 'å¤ĸ'] +['å»', '³'] +['è§Ħ', '竳'] +['èĬ', 'Ļ'] +['ç¯', '·'] +['èº', '¯'] +['æł', 'Ī'] +['åĿļ', 'å®ŀ'] +['åŁº', '建'] +['çĿĢ', 'çľ¼'] +['ç·', '´'] +['èij', '©'] +['ç¼', 'ļ'] +['æ¦', 'Ĩ'] +['主', 'åĭķ'] +['ç¥', 'Ģ'] +['äºĴ', 'éĢļ'] +['å°¤', '为'] +['å®', 'Ľ'] +['éª', '¼'] +['æ±', '²'] +['ä¾', 'ĥ'] +['æĤł', 'ä¹ħ'] +['æij', '§'] +['æĭ', 'ĩ'] +['é«', 'ĵ'] +['éº', 'Ĵ'] +['éĻ', 'Ľ'] +['æŀ', '¸'] +['æĿ', 'ŀ'] +['è´', '¬'] +['å°ı', 'é¾Ļ'] +['åĵ', '®'] +['èĵ¬', 'åĭĥ'] +['åĮ', 'Ī'] +['çķľ', 'çī§'] +['å¨', '©'] +['个', 'å¤ļ'] +['æ²', '¥'] +['æĺ', '§'] +['çĦ', 'ļ'] +['æĬij', 'éĥģ'] +['çĸ', '¡'] +['èĺ', 'ij'] +['éģİ', 'ç¨ĭ'] +['æ©', '±'] +['éĿ', 'ĵ'] +['大', 'çIJĨ'] +['é«', '¦'] +['åĪĨ', '辨'] +['æ¸', '¤'] +['çĸ', '¤'] +['åĬ¨', 'èĥ½'] +['å¼ł', 'å®¶'] +['ä¸ĩ', 'åįĥ'] +['æ»', '¥'] +['é¥', '¥'] +['åºŁ', 'å¼ĥ'] +['å¸', '³'] +['æ¼', '³'] +['è±', 'IJ'] +['ä»', 'ij'] +['å«', 'ī'] +['å¦', 'Ĵ'] +['çŀ', 'Ĵ'] +['è¡', 'ħ'] +['çĭ', '¸'] +['å¾ģ', 'ç¨ĭ'] +['éĤ', '¯'] +['éĥ', '¸'] +['ç¥', 'Ī'] +['ç¥', '·'] +['è¶', '´'] +['ç»ĵæŀĦ', 'æĢ§'] +['è§Ĩ', 'åIJ¬'] +['è¬', 'Ŀ'] +['çĴ', 'Ģ'] +['çĴ', '¨'] +['åĩº', 'å¤Ħ'] +['è¯', 'Ģ'] +['å¾', 'ĺ'] +['å¾', 'Ĭ'] +['çľ', '¨'] +['åĸ', 'ĩ'] +['åı', 'Ń'] +['åĺ', '²'] +['çķ', '¸'] +['å¹²', 'äºĭ'] +['æļ', '§'] +['æ²', 'Ľ'] +['åĦ', 'Ħ'] +['å»', 'ĵ'] +['åİ¿', 'éķ¿'] +['èĥ', 'ļ'] +['çIJ', '¢'] +['çŃ', '·'] +['éĩ', 'ĭ'] +['ä¾', '®'] +['åIJ', '©'] +['åĴ', 'IJ'] +['åĮ', '¿'] +['æĬ¬', 'èµ·'] +['æ³', '£'] +['æ¶', '¤'] +['éº', '½'] +['æĽ', 'Ļ'] +['åī¯', 'éĻ¢éķ¿'] +['åħļ', 'åĴĮ'] +['æķ£', 'åıij'] +['润', 'æ»ij'] +['åĵ', 'º'] +['æĥ', '¬'] +['漫', 'éķ¿'] +['ä¸į', 'æĩĪ'] +['åŁ', 'ł'] +['åĹ', 'ĵ'] +['èĢģ', 'çĪ·'] +['è®', '½'] +['æĪĺ', 'ç»ĦåIJĪ'] +['æ£', 'ł'] +['åħ¨', 'åŁŁ'] +['èł', '¢'] +['è¯', '¡'] +['åīį', 'çŀ»'] +['æķ', 'Ľ'] +['ä¸Ģ', 'å°ģ'] +['å¹', 'Ĥ'] +['èİ', 'Ĩ'] +['è¯Ŀ', 'è¯Ń'] +['ç»Ĩ', 'åĪĻ'] +['å±', '¿'] +['åµ', 'Į'] +['éĢ', 'į'] +['åĺ', '±'] +['æ¸', '²'] +['çĥ', '¯'] +['çĿ', '¹'] +['é¦', 'Ĵ'] +['èħ', '¥'] +['æĬĹ', 'åĩ»'] +['çĿ', '«'] +['èį', 'Ķ'] +['éļ', 'İ'] +['æ³ī', 'æ°´'] +['è¬', 'Ĥ'] +['ç', 'Ĥ¬'] +['åĩı', 'æİĴ'] +['è¸', 'Ĭ'] +['è', '·»'] +['æ·', 'Į'] +['éľ', '¾'] +['å¥ĩ', '纳'] +['å¯', 'Ŀ'] +['æ¤', 'İ'] +['æŁ', '¬'] +['æĸ¯', 'åŁº'] +['åħ¬', 'ç«ĭ'] +['è¨', 'ĵ'] +['é£', 'Ļ'] +['é©', '¿'] +['åĤ', 'µ'] +['èĽ', 'Ļ'] +['ç¯ĩ', '竳'] +['åĪĨ', 'æĶ¯'] +['ä¸Ĭ', 'å¹´'] +['çŃ', 'Ŀ'] +['ç¼', '¤'] +['èĢģ', 'æĹ§'] +['åĻ', '¬'] +['æľ', '¦'] +['èĥ', '§'] +['æ¶Ī', 'è²»'] +['æĵ', 'Ķ'] +['æ¦', '´'] +['æ¿', 'Ĵ'] +['ç³', '¯'] +['æ³', '¸'] +['æį', 'Ĩ'] +['ç»', 'ļ'] +['èµ', 'İ'] +['çIJ', 'IJ'] +['èµ', 'Ĥ'] +['æħ', '®'] +['æ²', 'Į'] +['çĦ', 'Ļ'] +['æĴŃ', 'æĬ¥'] +['æ·', 'ĩ'] +['åĪĩ', 'åħ¥'] +['çij', 'ķ'] +['çĸ', 'µ'] +['éģ', '´'] +['ç¨', 'ļ'] +['ç©', '©'] +['èŀ', 'ĥ'] +['æ£', 'ķ'] +['æĨ', '§'] +['æĨ', '¬'] +['ä¼', 'º'] +['æ¯', 'Ĺ'] +['æį', 'į'] +['æĬ', 'ī'] +['ç´', 'Ĭ'] +['å¼', 'Ľ'] +['æĭ', 'Ń'] +['æĹı', 'èĩªæ²»'] +['åĿ', '·'] +['ç«', '¶'] +['è©', '³'] +['è¿Ħ', 'ä»Ĭ'] +['è°', '´'] +['çŀŃ', 'è§£'] +['æŁ', '¿'] +['é¢', 'Ĭ'] +['ç°', '§'] +['çĥŁ', 'èĬ±'] +['ä¾', '¥'] +['çĿ', '¦'] +['éħ', 'Ŀ'] +['æ°', 'ĵ'] +['çIJ', 'ī'] +['å§', 'Ĭ'] +['æ²', '®'] +['æħ', '·'] +['èľ', 'ķ'] +['çij', 'ļ'] +['éĩĩ', 'çŁ¿'] +['åł', '°'] +['åºķ', 'èķ´'] +['èĨ', '³'] +['è¾', 'ķ'] +['éŁ', 'Ń'] +['åĴ', 'Ļ'] +['ç²', '½'] +['åī', 'Ķ'] +['æ²', '¦'] +['èĤ', '´'] +['éķ', '¶'] +['æĺ', '¼'] +['è¾', 'Ĺ'] +['å©', 'ª'] +['åĮ', '®'] +['æĸ', 'ĵ'] +['æ±', '¶'] +['éĥ', '´'] +['éł', '»'] +['çª', 'Ĵ'] +['è¢', '±'] +['åĽ', '±'] +['èĢ', 'ĺ'] +['è', 'ļĮ'] +['çĭ', 'Ļ'] +['çĹ', '¹'] +['ç¥', 'ī'] +['æı', '®'] +['æ·', 'Ĩ'] +['ç£', 'ĭ'] +['éĺ', 'ª'] +['æ', '«'] +['ã', '¸'] +['Ļ', '¶'] +['ã', 'ij'] +['ð£', '²'] +['ä', '¢'] +['ã', 'Ń'] +['ð¬', '¨'] +['ð¬', 'Ģ'] +['ð¬', '®'] +['ð¬', '¯'] +['ð¬', 'ľ'] +['ðª', '¨'] +['ð«', 'Ĺ'] +['ð¬', 'Ĭ'] +['ð¬', '±'] +['ð¬', 'Ł'] +['ä', 'İ'] +['ð', '¡'] +['ä', 'ĥ'] +['ã', 'ł'] +['ð', '©'] +['ð©', '¾'] +['ð¬', 'º'] +['ð¬', 'Ļ'] +['ãĢ', 'Ķ'] +['ãĢ', 'ķ'] +['çļĦ', 'æĹ¶åĢĻ'] +['æľīéĻIJ', 'åħ¬åı¸'] +['ä¹ĭ', 'åIJİ'] +['ä¸ļ', 'åĬ¡'] +['åķ', 'Ĭ'] +['èϽ', 'çĦ¶'] +['æĭ¥', 'æľī'] +['äºĴ', 'èģĶç½ij'] +['éĤ£', 'äºĽ'] +['ä½ł', 'çļĦ'] +['åĨ³', 'å®ļ'] +['éϤ', 'äºĨ'] +['åĽ¢', 'éĺŁ'] +['åı¯', 'æĺ¯'] +['以', 'åIJİ'] +['社', 'åĮº'] +['çļĦ', 'éĹ®é¢ĺ'] +['å¹¶', 'ä¸Ķ'] +['æķĻ', 'å¸Ī'] +['å°±', 'ä¼ļ'] +['天空', 'éĥ¨èIJ½'] +['æľĢ', 'ç»Ī'] +['å½ĵ', 'çĦ¶'] +['ä¹Ł', 'æľī'] +['ç¡®', 'ä¿Ŀ'] +['æĥ³', 'è¦ģ'] +['è´Ń', 'ä¹°'] +['人', 'çļĦ'] +['åIJ', '´'] +['çļĦ', 'åıijå±ķ'] +['ä¸į', 'çŁ¥éģĵ'] +['软', 'ä»¶'] +['æĪij们', 'çļĦ'] +['çζ', 'æ¯į'] +['åī', 'ij'] +['èĢĮ', 'æĺ¯'] +['å®ī', 'æİĴ'] +['åIJİ', 'æĿ¥'] +['çļĦ', 'åľ°æĸ¹'] +['èµ', 'µ'] +['èĢĥ', 'è¯ķ'] +['çªģ', 'çĦ¶'] +['ä¸Ģå®ļ', 'è¦ģ'] +['åζ', 'ä½ľ'] +['è¯Ħ', 'ä»·'] +['åħį', 'è´¹'] +['è´¹', 'ç͍'] +['绣', 'ä¸Ģ'] +['çĦ¶', 'èĢĮ'] +['è¿Ļ', '次'] +['éĿĴ', 'å¹´'] +['人', 'ç±»'] +['äº', '¦'] +['让', '人'] +['è´Łè´£', '人'] +['éĩĩ', 'åıĸ'] +['çļĦ', 'äºĭæĥħ'] +['ä¹Ł', 'ä¼ļ'] +['车', 'è¾Ĩ'] +['æĽ´', 'æĺ¯'] +['强', 'åĮĸ'] +['æĪij', 'åĢij'] +['以', 'åīį'] +['ä¼ĺ', 'åĮĸ'] +['å§Ķåijĺ', 'ä¼ļ'] +['åĽ°', 'éļ¾'] +['å¹´', '度'] +['ä½į', 'äºİ'] +['æĮĩ', 'åĩº'] +['åĨį', '次'] +['åĬŀ', 'çIJĨ'] +['æ¯ı', '个'] +['对', 'æĸ¹'] +['è¿Ľè¡Į', 'äºĨ'] +['æľĢ', 'é«ĺ'] +['课', 'ç¨ĭ'] +['身', 'ä¸Ĭ'] +['æĽ¾', 'ç»ı'] +['åĮ»', 'çĶŁ'] +['å®ī', 'è£ħ'] +['æľ', '±'] +['è¿IJ', 'è¡Į'] +['åıĮ', 'æĸ¹'] +['æľĢ', '大çļĦ'] +['æŀĦ', '建'] +['è¿ŀ', 'ç»Ń'] +['çļĦ', 'å°ı'] +['她', 'çļĦ'] +['çŃī', 'çŃī'] +['æĶ¹', 'åĸĦ'] +['åIJĦ', 'ç±»'] +['éģĩ', 'åΰ'] +['æľī', 'çĿĢ'] +['人', 'çī©'] +['æĢ»', 'æĺ¯'] +['è¿ħ', 'éĢŁ'] +['åζ', 'å®ļ'] +['å®ĥ', '们'] +['å®ĺ', 'ç½ij'] +['è¿ĺ', 'è¦ģ'] +['ç»Ī', 'äºİ'] +['æĪ¿', 'åľ°äº§'] +['è¯ģ', 'æĺİ'] +['èĤ¡', '票'] +['åºĶ', 'å½ĵ'] +['èĭ±', 'åĽ½'] +['è¿IJ', 'ç͍'] +['æľĢ', 'æĸ°'] +['享', 'åıĹ'] +['让', 'æĪij'] +['æĻļ', 'ä¸Ĭ'] +['å¾', 'ŀ'] +['å°ı', '说'] +['å°¤åħ¶', 'æĺ¯'] +['è®Ń', 'ç»ĥ'] +['åħ¨', 'å¸Ĥ'] +['æĮij', 'æĪĺ'] +['æľī', 'çĤ¹'] +['带', 'çĿĢ'] +['çļĦ', 'ä¸ľè¥¿'] +['é£İ', 'æł¼'] +['é»Ħ', 'éĩij'] +['å¼ķ', '导'] +['æŃ¤', 'å¤ĸ'] +['æľĢ', 'è¿ij'] +['追', 'æ±Ĥ'] +['强', 'è°ĥ'] +['ä¹Ł', 'åı¯ä»¥'] +['æĦŁ', 'åΰ'] +['èĩª', 'æĪij'] +['çī¹åĪ«', 'æĺ¯'] +['æĪIJ', 'éĥ½'] +['éĢIJ', 'æ¸IJ'] +['å¿«', 'ä¹IJ'] +['ä¹ĭ', 'ä¸Ń'] +['æĬķèµĦ', 'èĢħ'] +['ä»ĸ们', 'çļĦ'] +['æ°', 'ı'] +['å·¥ä½ľ', '人åijĺ'] +['äºĨ', 'ä¸Ģ个'] +['åķ', '¦'] +['ä¸Ģ', 'åĢĭ'] +['åŁº', 'å±Ĥ'] +['æ²Ł', 'éĢļ'] +['第ä¸Ģ', '次'] +['å¹¶', '没æľī'] +['çļĦ', 'å·¥ä½ľ'] +['åľ¨', 'è¿ĻéĩĮ'] +['æŀ', 'ª'] +['æĶ¯', 'æĴij'] +['æĹ¶', 'å°ļ'] +['æĿ¥', 'åΰ'] +['æĶ¶', 'è´Ń'] +['éĿ©', 'åij½'] +['æĺ¯', 'ä¸įæĺ¯'] +['讨', '论'] +['ä¸ļ', '绩'] +['å°±', 'èĥ½'] +['ç«ĭ', 'åį³'] +['è¡Ĺ', 'éģĵ'] +['åľ¨', 'ä¸Ģèµ·'] +['æľĪ', '份'] +['é«ĺ', '端'] +['å¾Ī', 'éļ¾'] +['ä¿Ħ', 'ç½Ĺæĸ¯'] +['æīĭ', '段'] +['åģļ', 'åĩº'] +['ä¼Ĺ', 'å¤ļ'] +['å®ŀ', 'è¡Į'] +['æīĵ', 'å¼Ģ'] +['游', '客'] +['ä¾Ŀ', 'çĦ¶'] +['å°±', 'åĥı'] +['离', 'å¼Ģ'] +['说', 'éģĵ'] +['æĸ°', 'èĥ½æºIJ'] +['æº', 'ª'] +['äº', 'ķ'] +['令', '人'] +['ä¸Ģ', 'åľº'] +['æĪij', 'æĥ³'] +['两', '人'] +['èĩ³', 'å°ij'] +['çļĦ', 'çĶŁæ´»'] +['æĺ¯', '个'] +['èĭ±', 'è¯Ń'] +['æ²Ĵ', 'æľī'] +['æĢĿ', 'èĢĥ'] +['éĻIJ', 'åζ'] +['åı°', 'æ¹¾'] +['ä¸Ģ', 'æĹ¦'] +['çļĦ', 'ä¸Ģ个'] +['é«ĺ', '级'] +['åĬŀåħ¬', '室'] +['å¾·', 'åĽ½'] +['æĪij', 'å°±'] +['å®ļ', 'ä½į'] +['éĢĤ', 'åºĶ'] +['æĮĩ', 'æłĩ'] +['åħ¨', 'çľģ'] +['ä¸Ĭ', 'è¿°'] +['å®ĥ', 'çļĦ'] +['åĽŀ', 'å®¶'] +['欧', 'æ´²'] +['éĵģ', 'è·¯'] +['é¼ĵ', 'åĬ±'] +['çļĦ', 'å½±åĵį'] +['é«ĺ', 'æł¡'] +['天', 'ä¸ĭ'] +['é«ĺ', 'è´¨éĩı'] +['æĿŃ', 'å·ŀ'] +['èµĦ', '讯'] +['æĶ¾', 'åľ¨'] +['æľī', 'ä¸Ģ个'] +['å°±', 'è¦ģ'] +['ä¸Ĭ', 'éĿ¢'] +['è§£', 'éĩĬ'] +['éĢIJ', 'æŃ¥'] +['å°½', '管'] +['æľī', 'ä»Ģä¹Ī'] +['çļĦ', 'äºĭ'] +['çĻ»', 'è®°'] +['人æ°ij', 'å¸ģ'] +['è§Ĥ', 'ä¼Ĺ'] +['è§Ĥ', 'å¯Ł'] +['ç͵', 'èĦij'] +['çļĦ', 'åIJĮæĹ¶'] +['ä½ľ', 'ä¸ļ'] +['宣', 'å¸ĥ'] +['çļĦ', 'ä½ľç͍'] +['åĽŀ', 'æĿ¥'] +['éļ¾', '以'] +['æīĢæľī', 'çļĦ'] +['å°ı', 'åѦ'] +['æıIJ', 'åīį'] +['æ¤į', 'çī©'] +['åĩ', '¯'] +['ä¸Ĭ', 'äºĨ'] +['å°±', 'åľ¨'] +['åħĪ', 'åIJİ'] +['æīĭ', 'æľ¯'] +['éĥ', 'Ń'] +['éĿ¢', 'åīį'] +['æ¯ķ', '竣'] +['äºĮ', 'æĺ¯'] +['红', 'èī²'] +['éĺ³', 'åħī'] +['èĭ¹', 'æŀľ'] +['å¾Īå¤ļ', '人'] +['ç»Ļ', 'æĪij'] +['åĵ', '¦'] +['çľ¼', 'çĿĽ'] +['éł', 'Ń'] +['ä¸Ģ', 'æĺ¯'] +['åıijå±ķ', 'çļĦ'] +['åıį', 'åºĶ'] +['æĪ¿', 'å±ĭ'] +['æľŁ', 'å¾ħ'] +['ç§į', 'æ¤į'] +['æĸĩ', 'åѦ'] +['åį³', 'åı¯'] +['é¦ĸ', '次'] +['èĭ±', 'éĽĦ'] +['å¤ļ', '次'] +['åĮħ', 'è£ħ'] +['æ²³', 'åįĹ'] +['ä¹ĭéĹ´', 'çļĦ'] +['ä»į', 'çĦ¶'] +['åIJ¬', 'åΰ'] +['èij£äºĭ', 'éķ¿'] +['è§Ħ', 'åĪĻ'] +['ä¸Ģ', '份'] +['大', 'ä¼Ĺ'] +['使', 'å¾Ĺ'] +['è¿Ľ', 'åı£'] +['ä¸Ģ', 'çīĩ'] +['æĢ§', 'çļĦ'] +['çļĦ', '大'] +['æĪij', 'æĺ¯'] +['äºĴ', 'åĬ¨'] +['æ°', '£'] +['çļ', 'Ĩ'] +['åħ¬åı¸', 'çļĦ'] +['ä¸Ģ', 'è¾¹'] +['åıĬ', 'åħ¶'] +['èī¯', '好çļĦ'] +['æĭĵ', 'å±ķ'] +['å½ĵ', 'å¹´'] +['广', 'åľº'] +['åģļ', 'äºĨ'] +['åŁº', 'äºİ'] +['æıIJ', 'éĨĴ'] +['åħĦ', 'å¼Ł'] +['èĢģ', 'æĿ¿'] +['è¿ij', 'æĹ¥'] +['çĬ¶', 'åĨµ'] +['注', 'éĩį'] +['åĪļ', 'åĪļ'] +['è°ĥ', 'çłĶ'] +['å¿ĥ', 'ä¸Ń'] +['æĬĬ', 'æı¡'] +['éļı', 'åIJİ'] +['ä¸į', 'å¤Ł'] +['åĪĽ', 'ä½ľ'] +['ç«Ļ', 'åľ¨'] +['缸', 'äºĴ'] +['çĸ«æĥħ', 'éĺ²æİ§'] +['å¹´', '代'] +['带', 'åĬ¨'] +['伤', '害'] +['竣', 'çĦ¶'] +['å¼ķ', 'è¿Ľ'] +['ç´¯', '计'] +['让', 'æĪij们'] +['åĽŀ', 'æĶ¶'] +['æĬ¥', 'åIJį'] +['åĬ©', 'åĬĽ'] +['èģĶ', '缣'] +['çŃĸ', 'çķ¥'] +['åij¨', 'è¾¹'] +['åĭ', 'Ĵ'] +['è¿ĺ', 'åľ¨'] +['æµģ', 'éĩı'] +['寻', 'æī¾'] +['ç͵', 'åĬĽ'] +['èι', 'èζ'] +['è¿ĺ', 'èĥ½'] +['æĭħ', 'ä»»'] +['çļĦæĥħåĨµ', 'ä¸ĭ'] +['çļĦ', 'åİŁåĽł'] +['缺', 'ä¹ı'] +['çIJĥ', 'åijĺ'] +['å²ģ', 'çļĦ'] +['çĶ·', 'åŃIJ'] +['å·¥', 'èµĦ'] +['è¿ijå¹´', 'æĿ¥'] +['åij', 'Ģ'] +['æıIJä¾Ľ', 'äºĨ'] +['她', '们'] +['å®¶', 'åħ·'] +['çĩ', 'ķ'] +['è½»', 'æĿ¾'] +['æł¡', 'åĽŃ'] +['èĢĥ', 'æł¸'] +['åį±', 'éĻ©'] +['åħļ', 'ç»Ħç»ĩ'] +['æĢ»', 'ç»ıçIJĨ'] +['çļĦ', 'æĸ°'] +['çİ»', 'çĴĥ'] +['è¿Ļ', 'ä½į'] +['对', 'æŃ¤'] +['å®¶', '人'] +['çļĦ', 'è¦ģæ±Ĥ'] +['温', '度'] +['æĮĩ', 'æķ°'] +['缴', 'åΰ'] +['æŃ¤', 'æĹ¶'] +['æ¹ĸ', 'åįĹ'] +['éĥ½', 'è¦ģ'] +['ä½ľ', 'åĩº'] +['åIJĦ', 'ä½į'] +['èĢĥ', 'çĶŁ'] +['ä¾Ŀ', 'æį®'] +['说', 'è¯Ŀ'] +['æĪij', 'ä¹Ł'] +['å·¥', 'åİĤ'] +['åıĺ', 'æĪIJ'] +['ä»ĸ', '人'] +['æĪij', 'è§īå¾Ĺ'] +['åIJĦ', '级'] +['ä¼łå¥ĩ', 'ç§ģæľį'] +['ä¸Ĭ', 'åįĩ'] +['好', 'åĥı'] +['åĬł', 'éĢŁ'] +['äºĮ', 'åįģ'] +['è¢', 'ģ'] +['è£ħ', '饰'] +['éĥ½', 'èĥ½'] +['ä¸Ģ', 'å¼ł'] +['åĬ¨', 'æĢģ'] +['å¹´', 'çļĦ'] +['è¿Ļ', 'å°±æĺ¯'] +['ä¹Ł', 'è¦ģ'] +['èµĦ', 'æł¼'] +['æĪĺ', 'äºī'] +['æĦŁ', 'è°¢'] +['åŁ¹', 'èĤ²'] +['天', 'æ°Ķ'] +['女', '士'] +['åı¯èĥ½', 'ä¼ļ'] +['çļĦ', '产åĵģ'] +['ä¹Ł', 'å°±'] +['主è¦ģ', 'æĺ¯'] +['åĪº', 'æ¿Ģ'] +['ç»Ļ', 'ä½ł'] +['大', 'æķ°æį®'] +['åĮ»', 'åѦ'] +['åĪ', '¤æĸŃ'] +['ä»ĸ', '说'] +['表', 'æ¼Ķ'] +['äºļ', 'æ´²'] +['ä¸ĵ', 'é¢ĺ'] +['ç«ŀäºī', 'åĬĽ'] +['éĤ£', 'æł·'] +['å±ķ', 'å¼Ģ'] +['å¹³', 'æĹ¶'] +['æİ¥', 'ä¸ĭæĿ¥'] +['æī¿', '诺'] +['æ³ķ', 'åĽ½'] +['åħ³', 'å¿ĥ'] +['ä¼ļ', 'æľī'] +['éĤĢ', '请'] +['é¢Ħ', 'éĺ²'] +['对', 'æİ¥'] +['好', 'äºĨ'] +['åĴ±', '们'] +['çļĦ', 'æĦŁè§ī'] +['æĢĿ', 'è·¯'] +['éĥ½', '没æľī'] +['çļĦ', 'æĸ¹æ³ķ'] +['女', 'åŃIJ'] +['åı¸', 'æ³ķ'] +['è¿ĺ', 'ä¼ļ'] +['è¶ĬæĿ¥è¶Ĭ', 'å¤ļ'] +['åĽł', 'çĤº'] +['æµ·', 'åįĹ'] +['人', 'æķ°'] +['å°Ĩ', 'ä¼ļ'] +['ä¸ļ', '主'] +['é¤IJ', '饮'] +['å±ħ', 'ä½ı'] +['åıij', 'åĩº'] +['è¿ij', 'æľŁ'] +['å¼ķ', 'é¢Ĩ'] +['æľºåύ', '人'] +['åĩºæĿ¥', 'çļĦ'] +['çľĭ', 'è§ģ'] +['ä¿', 'Ĭ'] +['让', 'ä»ĸ'] +['ä¸į', 'æĥ³'] +['å·¥ä½ľ', 'çļĦ'] +['è¡¥', 'åħħ'] +['æµ', 'ħ'] +['çī¹', 'å¾ģ'] +['ä¸Ĭå¸Ĥ', 'åħ¬åı¸'] +['ç¾İ', 'é£Ł'] +['广', '西'] +['æ¯ı', 'ä¸Ģ个'] +['èIJ½', 'åľ°'] +['åĵģ', 'ç§į'] +['åĴĮ', 'è°IJ'] +['å½»', 'åºķ'] +['é«ĺ', 'èĢĥ'] +['æĺ¨', '天'] +['åīį', 'å¾Ģ'] +['çĽij', 'æµĭ'] +['çϾ', '度'] +['åľ¨', 'ä¸ŃåĽ½'] +['çļĦ', 'éľĢæ±Ĥ'] +['亿', 'ç¾İåħĥ'] +['åѦ', 'æľ¯'] +['æĶ¶', 'åΰ'] +['æĿ¿', 'åĿĹ'] +['ä¸Ģ', '段'] +['æŀĦ', 'æĪIJ'] +['ä¼ģä¸ļ', 'çļĦ'] +['表', 'éĿ¢'] +['æķ´', 'çIJĨ'] +['ç»ĵ', 'å©ļ'] +['人', 'å®¶'] +['åģľ', 'æŃ¢'] +['åѦ', 'ç§ij'] +['æĺ¾', 'å¾Ĺ'] +['ä¼ij', 'æģ¯'] +['é¢Ħ', 'æľŁ'] +['æĪĸ', 'æĺ¯'] +['çļĦ', '主è¦ģ'] +['åºĶ', '对'] +['èµ°', 'äºĨ'] +['ä¸Ń', 'éĹ´'] +['èµ°', 'è¿Ľ'] +['åijĪ', 'çݰ'] +['æIJŃ', 'éħį'] +['é¹', 'ı'] +['æĺ¯', 'åĽłä¸º'] +['æĥħ', '绪'] +['å®ļ', 'æľŁ'] +['社ä¼ļ', '主ä¹ī'] +['çŃī', '级'] +['磼', 'çĽ¾'] +['é£ŀ', 'æľº'] +['èĩ³', 'ä»Ĭ'] +['æĶ¶', 'éĽĨ'] +['çļĦ', 'æķħäºĭ'] +['åĪĩ', 'å®ŀ'] +['å®ŀçݰ', 'äºĨ'] +['å½¢', 'æĪIJäºĨ'] +['åįĹ', 'æĸ¹'] +['ä¸Ń', 'åѦ'] +['æµ·', 'æ´ĭ'] +['åIJ¦', 'åĪĻ'] +['æĭį', 'æijĦ'] +['大åѦ', 'çĶŁ'] +['åĩºçݰ', 'äºĨ'] +['æĦı', 'å¤ĸ'] +['ä¹Ł', 'èĥ½'] +['çļĦ', 'èĥ½åĬĽ'] +['åĿIJ', 'åľ¨'] +['åĪĻ', 'æĺ¯'] +['èĢĥ', 'å¯Ł'] +['å°Ĭ', 'éĩį'] +['éĺ²', 'æŃ¢'] +['ç´§', 'å¼ł'] +['读', '书'] +['åĩº', 'è¡Į'] +['å°±', 'æľī'] +['å±¥', 'è¡Į'] +['çݰ代', 'åĮĸ'] +['åĽ½', 'åĬ¡'] +['åĽ½åĬ¡', 'éĻ¢'] +['ç»´', 'ä¿®'] +['åİŁ', 'åĪĽ'] +['æĺ¯', 'æĮĩ'] +['ä¼ij', 'éĹ²'] +['çĤ', '®'] +['æĸ°', 'æĹ¶ä»£'] +['éĢĻ', 'åĢĭ'] +['ä¸į', 'æķ¢'] +['å®Į', 'ç¾İ'] +['ç»Ĩ', 'èĬĤ'] +['éŃ', 'ı'] +['èͬ', 'èıľ'] +['é¢Ĩ导', 'çıŃåŃIJ'] +['è¶ħ', '级'] +['è¡Į', 'æĥħ'] +['人工', 'æĻºèĥ½'] +['åį°', '度'] +['åŁºç¡Ģ', '设æĸ½'] +['åıĪ', 'æĺ¯'] +['èį¯', 'çī©'] +['åIJ¸', 'æĶ¶'] +['åį´', 'æĺ¯'] +['éĥ', 'İ'] +['å¥ĸ', 'åĬ±'] +['çļĦ', 'æľĭåıĭ'] +['ä¿Ŀ', 'çķĻ'] +['è§Ħ', 'å¾ĭ'] +['æĸ°', 'çĸĨ'] +['è¿ĺ', 'åı¯ä»¥'] +['æİ¥', 'è¿ij'] +['æŃ¤', 'åīį'] +['æī¹', 'åĩĨ'] +['æĢİä¹Ī', 'æł·'] +['çļĦ', 'ä½įç½®'] +['ä¸Ģ', 'åĿĹ'] +['æĭĴ', 'ç»Ŀ'] +['顾', '客'] +['ä¹Ł', 'åľ¨'] +['ä¸Ģ', 'çĶŁ'] +['éĥ¨', 'éĺŁ'] +['å¹´', 'åīį'] +['æĸ¹éĿ¢', 'çļĦ'] +['å°Ŀ', 'è¯ķ'] +['羣æŃ£', 'çļĦ'] +['ç¦ģ', 'æŃ¢'] +['è¿ĺ', '没æľī'] +['æ°ij', 'çĶŁ'] +['èµ°', 'åIJij'] +['èĦ¸', 'ä¸Ĭ'] +['å½ĵ', '天'] +['éĽĨåĽ¢', 'åħ¬åı¸'] +['çļĦä¸Ģ', 'ç§į'] +['西', 'æĸ¹'] +['åĽŀ', 'åºĶ'] +['ä¸Ģ', '声'] +['常', '常'] +['æıIJ', 'åΰ'] +['èħ¾', '讯'] +['æľį', 'è£ħ'] +['为', 'ä½ķ'] +['äºij', 'åįĹ'] +['å°±', 'ç®Ĺ'] +['ä¼ł', 'æī¿'] +['åıį', 'èĢĮ'] +['ä¸ĩ', 'åIJ¨'] +['è´¢', '产'] +['å¦Ĥ', 'ä¸ĭ'] +['æĹ¥', 'åīį'] +['åİŁ', 'æľ¬'] +['æľĢ', 'éĩįè¦ģçļĦ'] +['认', 'è¯ģ'] +['ä¸Ģ', 'éģĵ'] +['ä¿¡æģ¯', 'åĮĸ'] +['å¾Ĺ', 'åΰäºĨ'] +['é̲', 'è¡Į'] +['æĪij', 'è¦ģ'] +['éĢļ', 'ä¿¡'] +['室', 'åĨħ'] +['èµļ', 'éĴ±'] +['æĶ¶', 'èĹı'] +['è§£åĨ³', 'æĸ¹æ¡Ī'] +['æĪ¿', '产'] +['çĭ', '¼'] +['æ´»', 'åĬĽ'] +['ç»ıæµİ', 'åıijå±ķ'] +['çŃī', 'å¾ħ'] +['ä¹Ł', 'å¾Ī'] +['åĿ', 'ij'] +['å¾Ī', '好çļĦ'] +['éļ¾', '度'] +['ä¸į', 'å¦Ĥ'] +['人æ°ij', 'æĶ¿åºľ'] +['åĩº', 'åıij'] +['åīį', 'æľŁ'] +['æ¼Ķ', 'åijĺ'] +['女', 'çĶŁ'] +['èģļ', 'çĦ¦'] +['审', '计'] +['é¢Ħ', 'æµĭ'] +['ä¾Ŀ', 'æīĺ'] +['äºĶ', 'å¹´'] +['è¡¥', 'è´´'] +['æ¸ħ', 'æĻ°'] +['éª', 'Ĥ'] +['çľĭ', 'èµ·æĿ¥'] +['çļĦ', 'åŃ©åŃIJ'] +['é¢ij', 'éģĵ'] +['ä½ı', 'å®ħ'] +['éĿ¢', 'åIJij'] +['æľĢ', 'ä½İ'] +['æĹ¢', 'çĦ¶'] +['ä¸Ģ', 'å¥Ĺ'] +['æķ°', 'åѦ'] +['群', 'ä½ĵ'] +['åĮĹ京', 'å¸Ĥ'] +['å±ħ', 'çĦ¶'] +['æ°Ľ', 'åĽ´'] +['éĢĶ', 'å¾Ħ'] +['çļĦ', 'åŁºç¡Ģä¸Ĭ'] +['èģĮ', 'è´£'] +['åı¯èĥ½', 'æĺ¯'] +['åĨĽ', 'äºĭ'] +['æĪIJ', 'æķĪ'] +['åŃ©åŃIJ', '们'] +['计ç®Ĺ', 'æľº'] +['èµ', '¤'] +['产ä¸ļ', 'åıijå±ķ'] +['å·¨', '大çļĦ'] +['å·¥', '人'] +['çĶŁ', 'éķ¿'] +['éĥ½', 'åı¯ä»¥'] +['çļĦ', 'æľºä¼ļ'] +['èµĦ', 'è´¨'] +['çĹĽ', 'èĭ¦'] +['ç²ī', 'ä¸Ŀ'] +['å¢', 'ĵ'] +['å¹³', 'å®ī'] +['管', 'éģĵ'] +['è·Ł', 'çĿĢ'] +['饮', 'é£Ł'] +['åķĨ', 'å®¶'] +['å¤ļ', 'å®¶'] +['åı¸', 'æľº'] +['åºĶ该', 'æĺ¯'] +['éĢı', 'éľ²'] +['认', 'å®ļ'] +['è¡Įä¸ļ', 'çļĦ'] +['çļĦ', 'ä¼ģä¸ļ'] +['æ¯ı', 'ä¸Ģ'] +['èĮĥåĽ´', 'åĨħ'] +['è¾ĥ', '大'] +['è´', '¤'] +['大', 'èµĽ'] +['å¤ļ', 'äºĨ'] +['é¸', '¿'] +['临', 'åºĬ'] +['åľ¨', 'è¿Ļ个'] +['çļĦ', 'åĨħ容'] +['éĶĢ', 'éĩı'] +['å¾Ī', 'å°ij'] +['åŃ', 'Ł'] +['ç»´', 'æĮģ'] +['åĴĸ', 'åķ¡'] +['æľ¬', 'åľ°'] +['èī²', '彩'] +['å¹¶', 'éĿŀ'] +['èĢĮ', 'å·²'] +['温', 'æļĸ'] +['èIJ', '§'] +['æĬĵ', 'ä½ı'] +['èĢĮ', 'ä¸įæĺ¯'] +['åĸ', 'Ĭ'] +['çļĦ', 'åħ³ç³»'] +['çī©', 'åĵģ'] +['éĤ£', 'æĺ¯'] +['åĨľ', '产åĵģ'] +['è¿Ļ', 'æĹ¶'] +['å©ļ', 'å§»'] +['æ°´', 'æŀľ'] +['æĶ¶', 'èİ·'] +['ä»ĺ', 'åĩº'] +['客æĪ·', '端'] +['æ¼Ķ', 'åĩº'] +['åħ¨', 'æĸ°'] +['è¿Ļ', 'ä¹Łæĺ¯'] +['æĺ¯', 'çͱ'] +['è§Ĥ', '念'] +['æľī', '个'] +['éĢł', 'åŀĭ'] +['èĥľ', 'åĪ©'] +['ä¸ī', 'æĺ¯'] +['è¶ħ', 'å¸Ĥ'] +['åħļ建', 'å·¥ä½ľ'] +['æĶ¾', 'å¿ĥ'] +['线', 'è·¯'] +['æĭĽ', 'çĶŁ'] +['åIJĥ', 'é¥Ń'] +['è½', 'ī'] +['å°½', 'éĩı'] +['è§ģ', 'åΰ'] +['åIJĮæ¯Ķ', 'å¢ŀéķ¿'] +['åįİ', '为'] +['æĪij', 'å¸Ĥ'] +['æıIJ', 'åĩºäºĨ'] +['æ°ij', 'èѦ'] +['åįļ', 'çī©'] +['åįļçī©', 'é¦Ĩ'] +['è¯ļ', 'ä¿¡'] +['åīį', 'éĿ¢'] +['å±±', '西'] +['è¾ħ', 'åĬ©'] +['转', 'ç§»'] +['æĽ´', '为'] +['丰å¯Į', 'çļĦ'] +['åį', '¢'] +['å¿«', 'éĢĴ'] +['æĺ¾', 'èijĹ'] +['çī©', 'èµĦ'] +['åΰ', 'è¾¾'] +['æľī', 'åĪ©äºİ'] +['åij', 'Ĩ'] +['åŃ©åŃIJ', 'çļĦ'] +['ä¸į', 'ä½Ĩ'] +['çłĶç©¶', 'éĻ¢'] +['çͳ', 'æĬ¥'] +['æļ', '¨'] +['æ°ij', 'éĹ´'] +['åį', '»'] +['çļĦ', 'å£°éŁ³'] +['å¸Ĥåľº', 'çļĦ'] +['ä¸Ģ', 'åı¥'] +['çľģ', '级'] +['æĿ¥', 'çļĦ'] +['åĵª', '个'] +['æīį', 'ä¼ļ'] +['åĪĨ', 'éħį'] +['èĶ', '¡'] +['ä»ĸ', 'åľ¨'] +['åħ±', 'æľī'] +['å¡', 'ĺ'] +['èĴ', 'Ĥ'] +['éľ', 'į'] +['åıĤ', 'è§Ĥ'] +['ä¸Ī', '夫'] +['ä¾Ŀ', 'éĿł'] +['æľī', 'æĹ¶'] +['äºĨ', 'å¾Īå¤ļ'] +['ä¸ĸçķĮ', 'æĿ¯'] +['å®¶', 'æĹı'] +['ä¸į', 'éľĢè¦ģ'] +['大', 'å¸Ī'] +['èŀį', 'åħ¥'] +['éĿŀ', 'æ³ķ'] +['çĹħ', '人'] +['åIJİ', 'æľŁ'] +['大家', 'éĥ½'] +['ç½ij', 'åĿĢ'] +['åİŁ', 'æĸĻ'] +['便', 'å®ľ'] +['æ¶', 'Ľ'] +['仿', 'ä½Ľ'] +['å·®', 'è·Ŀ'] +['åı¦ä¸Ģ', 'æĸ¹éĿ¢'] +['产åĵģ', 'çļĦ'] +['èµ', '«'] +['æĥħåĨµ', 'ä¸ĭ'] +['éĴ¢', 'éĵģ'] +['æľ¬', 'ç«Ļ'] +['纳', 'åħ¥'] +['å·²', 'æľī'] +['æľī', '没æľī'] +['ä¼°', '计'] +['é£', 'ĺ'] +['æľŁ', 'è´§'] +['åĢĭ人', 'è³ĩæĸĻ'] +['ä¸ĵä¸ļ', 'çļĦ'] +['çĪĨ', 'åıij'] +['èĩ´åĬĽ', 'äºİ'] +['çİ°åľ¨', 'çļĦ'] +['æľī', 'åĵªäºĽ'] +['çł´', 'åĿı'] +['æķ°åŃĹ', 'åĮĸ'] +['åľ°', 'éĿ¢'] +['é»ij', 'èī²'] +['å¹¼åĦ¿', 'åĽŃ'] +['çļĦ', 'ç²¾ç¥ŀ'] +['äº', 'Ń'] +['导', 'æ¼Ķ'] +['çݰ', 'æľī'] +['æŃ¦', 'åύ'] +['èĭı', 'å·ŀ'] +['çİ', 'Ħ'] +['æ±Ł', '西'] +['å»¶', '伸'] +['论', 'æĸĩ'] +['è¾ĥ', '为'] +['çİ©', 'æ³ķ'] +['é¼', 'İ'] +['åIJĮ', 'æŃ¥'] +['éĩĬ', 'æĶ¾'] +['æĽĿ', 'åħī'] +['åĿļ', 'åĨ³'] +['å§Ķ', 'æīĺ'] +['å°Ĩ', 'åľ¨'] +['äºĪ', '以'] +['ä½ľ', 'æĸĩ'] +['èĢĮ', 'åľ¨'] +['ä¼ĺ', 'åħĪ'] +['åĽŀ', 'åİ»'] +['ä¿®', 'å¤į'] +['åĽ½åĨħ', 'å¤ĸ'] +['çŃĸ', 'åĪĴ'] +['åıij', 'æĶ¾'] +['å¿ĥ', 'æĥħ'] +['çļĦ', 'åİĨåı²'] +['éĿ¢', 'è¯ķ'] +['举', 'åĮĹ'] +['ä¿¡', 'åı·'] +['ç²®', 'é£Ł'] +['è¯ģ', '书'] +['æŁIJ', 'äºĽ'] +['è¿IJ', 'ä½ľ'] +['åĨ²', 'åĩ»'] +['çĥŃ', 'çĤ¹'] +['æĹ¶', 'æĹ¶'] +['æĹ¶æĹ¶', '彩'] +['åľ°', 'çĤ¹'] +['ä¸Ģä½ĵ', 'åĮĸ'] +['éļ¾', 'é¢ĺ'] +['æĽ', '°'] +['ç«ĭ', 'åĪ»'] +['æĺ¯', 'éĿŀ常'] +['åħ±', 'åĴĮ'] +['åħ±åĴĮ', 'åĽ½'] +['æ¿Ģ', 'åĬ±'] +['æľīæķĪ', 'çļĦ'] +['å¤Ħ', 'ç½®'] +['该', 'åħ¬åı¸'] +['æ£Ģ', 'éªĮ'] +['èѦ', 'æĸ¹'] +['è´', '¾'] +['äºĨä¸Ģ', 'ä¸ĭ'] +['ä»Ĭ', 'åIJİ'] +['çħ', '®'] +['ç͍', 'åĵģ'] +['读', 'èĢħ'] +['æĪij', 'åľ¨'] +['åĽŀ', 'å¤į'] +['ä¸Ģ', '座'] +['è¿ĺ', '没'] +['å®ļ', 'åζ'] +['没', 'æĥ³åΰ'] +['å¤', '¹'] +['ä¼ł', 'éĢĴ'] +['ä¸Ģ', '款'] +['强', '大çļĦ'] +['çļĦ', 'è¡Į为'] +['å¤ı', '天'] +['åıijåĬ¨', 'æľº'] +['é¢ĨåŁŁ', 'çļĦ'] +['å®ŀéªĮ', '室'] +['ä¸Ģ', 'æĬĬ'] +['æĺ¯', '为äºĨ'] +['éĻķ', '西'] +['æĭħ', 'ä¿Ŀ'] +['è¾¾', 'æĪIJ'] +['è¦ģ', 'æĺ¯'] +['æĺİ', '天'] +['ç»Ļ', 'ä»ĸ'] +['建ç«ĭ', 'äºĨ'] +['ä¸į', 'è¡Į'] +['ä¸Ń', 'æĸĩ'] +['åľ°', '说'] +['åIJİ', 'çļĦ'] +['çĽij', 'æİ§'] +['éĢ', '¸'] +['æĢ»', 'éĥ¨'] +['æľ¬', 'æĸĩ'] +['é¹', '¿'] +['æĻ¯', 'è§Ĥ'] +['çļĦ', '缮æłĩ'] +['èĽ', 'ĩ'] +['åĨ', '¯'] +['ä¸Ń', 'åĮ»'] +['æķĪ', 'åºĶ'] +['产', 'éĩı'] +['åŃ', 'Ŀ'] +['è´¦', 'æĪ·'] +['è¿Ŀ', 'åıį'] +['èij£äºĭ', 'ä¼ļ'] +['京', '举'] +['责任', 'ç¼ĸè¾ij'] +['åķı', 'é¡Į'] +['çα', 'å¿ĥ'] +['èѦ', 'å¯Ł'] +['é¤IJ', 'åİħ'] +['å¸Ĥ', 'æĶ¿åºľ'] +['天', '天'] +['æĸ°', 'é²ľ'] +['éĥij', 'å·ŀ'] +['è¶ħ', 'è¶Ĭ'] +['å½', 'Ń'] +['çŁ¥è¯Ĩ', '产æĿĥ'] +['åĽŀ', 'å¿Ĩ'] +['è·¯', '线'] +['å»ī', 'æ´ģ'] +['éĿĴ', 'å°ijå¹´'] +['åıĸå¾Ĺ', 'äºĨ'] +['çľĭ', 'åΰäºĨ'] +['é¦', '¬'] +['ç²¾', 'åĵģ'] +['åľ°', 'éĵģ'] +['æĮģ', 'æľī'] +['ä¸ĭ', 'äºĨ'] +['æľī', 'æĹ¶åĢĻ'] +['ä¸Ģ', '人'] +['æĴ', 'Ĵ'] +['ä»Ķ', 'ç»Ĩ'] +['èĢģ', 'åħ¬'] +['äºĭå®ŀ', 'ä¸Ĭ'] +['èģĶ', 'èµĽ'] +['ä¾ĽåºĶ', 'éĵ¾'] +['é¢Ħ', 'ç®Ĺ'] +['åζéĢł', 'ä¸ļ'] +['å®īåħ¨', 'çĶŁäº§'] +['俱', 'ä¹IJ'] +['俱ä¹IJ', 'éĥ¨'] +['çļĦ', 'æł¸å¿ĥ'] +['æīĵ', 'ç®Ĺ'] +['å½±', 'çīĩ'] +['æIJŃ', '建'] +['ä¹Ł', 'ä¸įä¼ļ'] +['æĭħ', 'å½ĵ'] +['å±Ĥ', 'éĿ¢'] +['åѦ', 'åijĺ'] +['临', 'æĹ¶'] +['缸', 'ç»ĵåIJĪ'] +['对', 'æ¯Ķ'] +['ä»ĸ', 'æĺ¯'] +['æĸ°', 'åĮº'] +['è¿Ľ', 'åİ»'] +['çϾ', 'å¹´'] +['ä¿', '©'] +['å°½', 'å¿«'] +['ç͵åŃIJ', 'åķĨåĬ¡'] +['æĽ´', 'æľī'] +['æ¸ħ', 'çIJĨ'] +['åı¦', 'ä¸Ģ个'] +['åĤ', '»'] +['ä»Ģä¹Ī', 'æł·çļĦ'] +['æĺ¯', 'æľĢ'] +['åij¨', 'å¹´'] +['å¾Ī', '容æĺĵ'] +['åĽ¢', 'ç»ĵ'] +['ç´', 'Ħ'] +['æĹ©', 'å·²'] +['çļĦ', 'åıĺåĮĸ'] +['éľ', 'ŀ'] +['æĹ¥', 'ä¸ĬåįĪ'] +['失', 'åİ»'] +['ä¸Ń', 'åľĭ'] +['çļĦä¸Ģ', 'äºĽ'] +['å°ı', 'åŃ©'] +['ä¸ĭ', 'è·Į'] +['éĶ»', 'çĤ¼'] +['é', 'ij'] +['éij', '«'] +['å¿ĹæĦ¿', 'èĢħ'] +['èĤ¡', 'å¸Ĥ'] +['èµĽ', 'äºĭ'] +['许åı¯', 'è¯ģ'] +['åı¯', 'æĮģç»Ń'] +['åijĬè¯ī', 'è®°èĢħ'] +['éĢ»', 'è¾ij'] +['å¼ķ', 'åħ¥'] +['çļĦ', 'è¿ĩç¨ĭä¸Ń'] +['è§Ĩ', 'è§ī'] +['èĩªæ²»', 'åĮº'] +['è¯ģ', 'æį®'] +['è£ħ', 'ç½®'] +['第ä¸ī', 'æĸ¹'] +['å¹´', 'æĿ¥'] +['å¹¿ä¸ľ', 'çľģ'] +['带æĿ¥', 'äºĨ'] +['éķ¿', 'æ±Ł'] +['访', 'éĹ®'] +['å·®', 'ä¸įå¤ļ'] +['æĺ¯', 'æĪij'] +['éģŃ', 'éģĩ'] +['æĬĵ', '好'] +['é«ĺ', 'è¾¾'] +['å¹¶', 'åľ¨'] +['èĩª', 'è§ī'] +['ä¾ĽåºĶ', 'åķĨ'] +['æĥħ', 'æĦŁ'] +['ä½ı', 'äºĨ'] +['çļĦ', 'èģĮä¸ļ'] +['çļĩ', 'å¸Ŀ'] +['西', 'éĥ¨'] +['åĴĮ', 'å¹³'] +['çļĦ', 'åĬĽéĩı'] +['æ±', 'ª'] +['åħħåĪĨ', 'åıijæĮ¥'] +['æĬķ', 'è¯ī'] +['èµ·', 'åΰ'] +['äºĴ', '缸'] +['æ¾³', 'éŨ'] +['æİ¥', 'åΰ'] +['æ°´', 'æ³¥'] +['模', 'åŀĭ'] +['ä¸Ģ', 'åįĬ'] +['ç§©', 'åºı'] +['æĪij们', 'åľ¨'] +['æī¿', '认'] +['ä¸Ģ', 'éĥ¨åĪĨ'] +['åįł', 'æ¯Ķ'] +['å¦ĩ', '女'] +['ç²', 'ĺ'] +['äºĨè§£', 'åΰ'] +['ä¸Ģå®ļ', 'ä¼ļ'] +['åIJĦ', '大'] +['èµ°', 'åĩº'] +['为', '大家'] +['é«ĺ', 'éĵģ'] +['åı¯ä»¥', 'åľ¨'] +['ä½Ĩ', 'åľ¨'] +['çĶŁæĢģ', 'çݯå¢ĥ'] +['èı', '¯'] +['çļĦ', 'ä»·æł¼'] +['麻', 'çĥ¦'] +['æ¿Ģ', 'åıij'] +['éĤ£', 'å°±'] +['çļĦ', 'æł·åŃIJ'] +['为', 'æŃ¤'] +['天', 'åľ°'] +['çļĦ', '缮çļĦ'] +['åĢº', 'åΏ'] +['å·²', 'ç¶ĵ'] +['åĽĽ', '大'] +['åIJĮæĹ¶', 'ä¹Ł'] +['å½¼', 'æŃ¤'] +['æĭ¿', 'åΰ'] +['åIJ«', 'éĩı'] +['åįģ', '大'] +['éļ¾', 'éģĵ'] +['å¼', 'Ĺ'] +['ä¸Ģ', '段æĹ¶éĹ´'] +['çħ§', '顾'] +['æķ°æį®', 'æĺ¾ç¤º'] +['æĪIJ为', 'äºĨ'] +['èµ°', 'åΰ'] +['æľ¬', 'åħ¬åı¸'] +['ç»Ī', '端'] +['ä¹Ł', 'ä¸įæĺ¯'] +['头', 'åıij'] +['大', '约'] +['é£İ', 'æĻ¯'] +['æ¶Ī', 'èĢĹ'] +['审', 'æŁ¥'] +['äºī', 'åıĸ'] +['æ³ķ', 'æ²»'] +['äºĭ', 'çī©'] +['ç¼ĵ', 'è§£'] +['æĥ', '¨'] +['缸åºĶ', 'çļĦ'] +['çļĦ', 'æķĪæŀľ'] +['åıį', 'å¤į'] +['åıijçĶŁ', 'äºĨ'] +['éĢĻ', 'äºĽ'] +['ç»ĥ', 'ä¹ł'] +['åݨ', 'æĪ¿'] +['å¼Ģ', 'æĭĵ'] +['欣', 'èµı'] +['夫', '妻'] +['ä¸į', 'ä¸Ģæł·'] +['产', 'èĥ½'] +['èĬ¯', 'çīĩ'] +['è¦ģ', 'ç´ł'] +['åıį', '对'] +['çİĩ', 'åħĪ'] +['è´§', 'çī©'] +['æĹ¥', 'ç͵'] +['ä½ľ', 'å®¶'] +['æĶ¹', 'è¿Ľ'] +['æĪIJ', 'åĪĨ'] +['åĽł', 'èĢĮ'] +['åĩı', 'èĤ¥'] +['æ½', 'ĺ'] +['å±±ä¸ľ', 'çľģ'] +['åĬ', 'Ŀ'] +['åŁ', 'ĭ'] +['æŃ¦', 'è£ħ'] +['æ±ĩ', 'æĬ¥'] +['ä¸Ģ个', 'æľĪ'] +['çĥŃ', 'éŨ'] +['大', 'éģĵ'] +['æ´»', 'åĭķ'] +['éĥ½', 'å¾Ī'] +['ç͵', '梯'] +['ç´§', 'æĢ¥'] +['åĢº', 'åĬ¡'] +['客', 'æľį'] +['ä¸Ģ', 'éĥ¨'] +['ä½ł', 'æĺ¯'] +['çݰ', 'çĬ¶'] +['æŃ£ç¡®', 'çļĦ'] +['ä¹ĭ', 'å¤Ħ'] +['ç¼ĸ', 'åζ'] +['ä½ł', 'åı¯ä»¥'] +['çŃī', 'åľ°'] +['èİ', 'ī'] +['对', 'è¯Ŀ'] +['æ·ĺ', 'å®Ŀ'] +['è°ĥ', 'èĬĤ'] +['æİĴ', 'æĶ¾'] +['åºĵ', 'åŃĺ'] +['ç´', 'ļ'] +['çļĦ', 'ä¼ĺåĬ¿'] +['æĿĥ', 'å¨ģ'] +['以ä¸ĭ', 'ç®Ģç§°'] +['ä¸Ģ', '项'] +['èģļ', 'éĽĨ'] +['ä¼łç»Ł', 'çļĦ'] +['æ··', 'åIJĪ'] +['è¿Ļä¸Ģ', 'çĤ¹'] +['ä¸Ģ', 'çľ¼'] +['æĹł', 'éĻIJ'] +['èİ·å¾Ĺ', 'äºĨ'] +['éĢī', 'æīĭ'] +['åζ', 'åĵģ'] +['åįı', 'ä½ľ'] +['çĭ¬çī¹', 'çļĦ'] +['ä¸Ģ', '级'] +['è¿Ļ个', 'éĹ®é¢ĺ'] +['æĸ', 'Į'] +['æĺ¯', 'æĪij们'] +['æķĮ', '人'] +['æ¸ħ', 'æ´Ĺ'] +['ä¸Ģ缴', 'åľ¨'] +['å°ı', 'ç±³'] +['çļĦ', 'è¿ĩç¨ĭ'] +['åľ¨', 'åĮĹ京'] +['ä¸Ģ', 'æĶ¯'] +['æĹ©', 'ä¸Ĭ'] +['æĸĩ', 'èīº'] +['ç¦ı', 'åĪ©'] +['é£Ł', 'ç͍'] +['æĦŁ', 'åĬ¨'] +['åħ¨', 'ç¨ĭ'] +['æĶ¯', 'åĩº'] +['æĸ°', '建'] +['å¸', 'ķ'] +['æĺ¾', 'çĦ¶'] +['羣', 'çļĦæĺ¯'] +['æĸ°éĹ»', 'ç½ij'] +['èĥ½', 'åIJ¦'] +['åįı', 'åĬ©'] +['亲', 'èĩª'] +['å¾Ī', 'æľī'] +['çϼ', 'å±ķ'] +['æĦı', '大'] +['æĦı大', 'åĪ©'] +['ç͵', 'ç½ij'] +['æĹ¥', 'çĽĬ'] +['çĨ', '±'] +['èĤĮ', 'èĤ¤'] +['çĶ·', 'æĢ§'] +['ç»Ħ', '建'] +['çŃī', 'éĹ®é¢ĺ'] +['æ¶Ī', 'éϤ'] +['æĬ¤', 'çIJĨ'] +['å¡ij', 'æĸĻ'] +['ä¹Į', 'åħĭ'] +['ä¹Įåħĭ', 'åħ°'] +['åķĨ', 'æłĩ'] +['çIJ', '³'] +['æĸ°', 'æīĭ'] +['çļĦ', 'çī¹çĤ¹'] +['åĴ', '¬'] +['å½ĵ', 'ä¸ĭ'] +['设计', 'å¸Ī'] +['èµĶ', 'åģ¿'] +['第', 'åįģ'] +['æĻºèĥ½', 'åĮĸ'] +['å¼Ģåıij', 'åĮº'] +['åı¯ä»¥', 'éĢļè¿ĩ'] +['åħ±äº§', 'åħļ'] +['åİī', '害'] +['çģµ', 'æ´»'] +['æĹ¶', 'åħī'] +['éĥ¨', 'ä½į'] +['人', 'æĸĩ'] +['è¿Ľ', 'æĿ¥'] +['ä¹ĭ', 'æīĢ以'] +['ä¸ī', 'åįģ'] +['çļĦ', 'åѦçĶŁ'] +['éĺ²', 'æĬ¤'] +['åĽ½', '产'] +['æ·±åľ³', 'å¸Ĥ'] +['éĤ£', 'å°±æĺ¯'] +['åΰ', 'ä½į'] +['çī¹', 'æľĹ'] +['çľĹ', 'æĻ®'] +['å®ŀ', 'æĹ¶'] +['åı°', 'çģ£'] +['èĢĮ', 'ä¸į'] +['æĮĩ', 'å®ļ'] +['åĿ', 'Ŀ'] +['èħIJ', 'è´¥'] +['çī¹', 'å®ļ'] +['å¢ŀ', 'éĢŁ'] +['æłĩ', 'çѾ'] +['æĪ¿', 'ä»·'] +['æĦ', 'ģ'] +['贯彻', 'èIJ½å®ŀ'] +['æĢ§', 'è´¨'] +['çłĶç©¶', 'çĶŁ'] +['ç¾İ', '容'] +['æī¹', 'è¯Ħ'] +['ç©¶', '竣'] +['人åĬĽ', 'èµĦæºIJ'] +['éĸĭ', 'å§ĭ'] +['åĽŀ', 'å½Ĵ'] +['èIJ¥', 'åķĨ'] +['èIJ¥åķĨ', 'çݯå¢ĥ'] +['ä¸ŃåĽ½', '人'] +['çļĦ', 'åŁºæľ¬'] +['è¯Ŀ', 'é¢ĺ'] +['æłĩåĩĨ', 'åĮĸ'] +['西', 'èĹı'] +['åĭ', '¾'] +['çļĦ', '设计'] +['ç®Ģåįķ', 'çļĦ'] +['å¤į', 'åζ'] +['æ¸IJ', 'æ¸IJ'] +['以', 'å¤ĸ'] +['èģĶ', 'åĬ¨'] +['两', '次'] +['æĢ§', 'åĴĮ'] +['æĽ´', '大'] +['çļĦ', 'åIJįåŃĹ'] +['éŁ', '¦'] +['ä½ł', 'è¦ģ'] +['å¢ĥ', 'å¤ĸ'] +['æĹ©', 'æľŁ'] +['åĪĿ', 'æŃ¥'] +['è´¦', 'åı·'] +['害', 'æĢķ'] +['æĺ¨', 'æĹ¥'] +['åĪļ', 'æīį'] +['ç¥ŀ', 'ç§ĺ'] +['ç²¾', 'å¿ĥ'] +['æµģ', 'éĢļ'] +['åħ¨', 'æĸ¹ä½į'] +['以', 'å¾Ģ'] +['ä¹Ł', 'å°Ĩ'] +['æĺ¯', 'ä¸ŃåĽ½'] +['åĽ½å®¶', '级'] +['å°Ĩ', 'åĨĽ'] +['æij', 'Ĭ'] +['æľĢ', '为'] +['第ä¸Ģ', 'æĹ¶éĹ´'] +['æ¶Ī', 'æ¯Ĵ'] +['å°Ĩ', 'äºİ'] +['å¨ģ', 'èĥģ'] +['èĭ±', 'æĸĩ'] +['æīĭ', 'ä¸Ń'] +['çIJĥ', 'è¿·'] +['è§Ĥ', 'çľĭ'] +['离', 'å©ļ'] +['æľ¬', 'åľŁ'] +['åĪĨ', 'æķ£'] +['æĻ', '´'] +['è¦ģ', '注æĦı'] +['浪', 'è´¹'] +['管', 'æİ§'] +['åĩº', 'åĶ®'] +['æĢ»', 'è£ģ'] +['ä¸Ģ', 'éĺµ'] +['å¨', 'ĩ'] +['äºĶ', '个'] +['å½ĵ', 'åĪĿ'] +['çºł', '纷'] +['ä¸ĵ', 'ç͍'] +['å¤ĩ', 'æ¡Ī'] +['åĪĿ', 'æľŁ'] +['å®ĥ', 'æĺ¯'] +['åĮº', 'åĿĹ'] +['åĮºåĿĹ', 'éĵ¾'] +['大', 'è¿ŀ'] +['è¿Ļ', 'ç±»'] +['åıĺ', 'æĪIJäºĨ'] +['éĤĦ', 'æĺ¯'] +['åįļ', '客'] +['çı¾', 'åľ¨'] +['ä¸Ģ', 'æĸ¹'] +['å®ĮæĪIJ', 'äºĨ'] +['è¿Ļ个', 'æĹ¶åĢĻ'] +['åħ¨', 'å¹´'] +['ä¸Ĭ', '线'] +['ç½', 'IJ'] +['ç«ŀ', 'èµĽ'] +['åĩºçīĪ', '社'] +['åĵ¥', 'åĵ¥'] +['å¯', '«'] +['å¾Ĺ', '以'] +['èĬ±', 'åĽŃ'] +['äºĨ', 'èµ·æĿ¥'] +['èĦ±è´«', 'æĶ»åĿļ'] +['çļĦ', 'åİŁåĪĻ'] +['讲', 'è§£'] +['æ¶Ī', 'åĮĸ'] +['æįŁ', '害'] +['æļĤ', 'æĹ¶'] +['å¾Ĺ', 'çŁ¥'] +['éĢĤ', 'ç͍'] +['éŨ', 'åºĹ'] +['è§£', '读'] +['æĻ®', 'åıĬ'] +['人æ°ij', 'æ³ķéĻ¢'] +['åī¯', '主任'] +['å¿ĥ', 'çģµ'] +['è¯Ĭ', 'æĸŃ'] +['ç¾İ', '女'] +['æŁ', '¯'] +['å¹´', '以æĿ¥'] +['æ´»', 'è·ĥ'] +['åĢŁ', 'åĬ©'] +['åħ±', '建'] +['è¯ī', '讼'] +['æĶ¾', 'æĿ¾'] +['çªĹ', 'åı£'] +['ä¼ģ', 'æ¥Ń'] +['åĬł', 'æĭ¿'] +['åĬłæĭ¿', '大'] +['ä¹°', 'äºĨ'] +['主', 'æµģ'] +['æĩĤ', 'å¾Ĺ'] +['å°Ĩ', 'åħ¶'] +['éĢı', 'æĺİ'] +['å·¥ä½ľ', 'ä¸Ń'] +['èĤ¡', 'ä»·'] +['æ¡£', 'æ¡Ī'] +['没æľī', 'ä»»ä½ķ'] +['åijĬ', 'çŁ¥'] +['å¹´', 'åĪĿ'] +['æĹ¥', 'ä¸ĭåįĪ'] +['åİĤ', 'åķĨ'] +['èĬĤ', 'å¥ı'] +['主', '导'] +['è£', 'Ŀ'] +['åħ³éĶ®', 'è¯į'] +['èģĬ', '天'] +['åĨĻ', 'ä½ľ'] +['æĶ¹éĿ©', 'å¼ĢæĶ¾'] +['æľī', 'æľĽ'] +['éĢļ', 'æĬ¥'] +['èIJ', 'Į'] +['æĢ»', 'é¢Ŀ'] +['çŁŃ', 'æľŁ'] +['ä¸Ģ', 'çķª'] +['çĶŁæ´»', 'çļĦ'] +['åĮĸ', 'çļĦ'] +['æĺ¥', '天'] +['è¿Ļ', 'åľº'] +['æĸ°å¼Ģ', 'ä¼łå¥ĩ'] +['æĺ¯', 'è¦ģ'] +['å°ļ', 'æľª'] +['åıĺ', 'æĽ´'] +['ä¸Ģ', 'åij¨'] +['客', 'è§Ĥ'] +['æĹ¥', 'èĩ³'] +['é¹', '°'] +['çİ', '²'] +['å°Ĩ', 'æĿ¥'] +['客', '人'] +['åıĺ', 'éĿ©'] +['说', 'äºĨ'] +['åİŁ', 'çIJĨ'] +['èģĮ', 'åĬ¡'] +['åıĪ', 'æľī'] +['ä¸Ģ', 'åı¥è¯Ŀ'] +['æĦŁ', 'åıĹåΰ'] +['ç¬Ķ', 'èĢħ'] +['ç§»', 'æ°ij'] +['西', 'åįĹ'] +['ä¹ĥ', 'èĩ³'] +['æŃ£', 'è§Ħ'] +['åĪĿ', 'ä¸Ń'] +['çĬ', '¬'] +['å½ĵ', 'äºĭ'] +['å½ĵäºĭ', '人'] +['æĪij们', 'è¦ģ'] +['åħ¥', 'åı£'] +['éĤ£', 'æĹ¶'] +['æľīéĻIJ', '责任'] +['å°ij', '女'] +['è¿Ļä¹Ī', 'å¤ļ'] +['åĪĨ', 'åħ¬åı¸'] +['å®ĩ', 'å®Ļ'] +['çļĦ', 'éĢīæĭ©'] +['å§IJ', 'å§IJ'] +['åıij', 'èµ·'] +['è»', 'į'] +['æĽ´å¥½', 'åľ°'] +['éĻĨ', 'ç»Ń'] +['æľ¬', 'æľįåĭĻ'] +['å«', '©'] +['èµ¶', 'ç´§'] +['èĦĤ', 'èĤª'] +['第äºĮ', '天'] +['æĪij', 'ä¼ļ'] +['两', 'ä½į'] +['æķ', '²'] +['åħ¬å®ī', 'æľºåħ³'] +['ç§ijæĬĢ', 'åĪĽæĸ°'] +['å°º', '寸'] +['è¾IJ', 'å°Ħ'] +['å®Ĺ', 'æķĻ'] +['转', 'æį¢'] +['åĩº', 'çİ°åľ¨'] +['ä¸Ģ', 'é¢Ĺ'] +['æľŁ', 'éĻIJ'] +['åIJĮåѦ', '们'] +['åĮĹ', 'æĸ¹'] +['ä½ł', 'å°±'] +['ä¸Ģ带', 'ä¸Ģè·¯'] +['èĢģ', 'å©Ĩ'] +['游æĪı', 'çݩ家'] +['çļĦ', 'ç»ĵæŀľ'] +['è¡¥', 'åģ¿'] +['å¤ĸ', 'è´¸'] +['对', 'å¾ħ'] +['ç»´', 'çĶŁç´ł'] +['ç»ıéĶĢ', 'åķĨ'] +['è¿ĺ', 'å°Ĩ'] +['åŃIJ', '女'] +['æĽ´', 'é«ĺ'] +['ä¸į', '大'] +['éī´', 'å®ļ'] +['让', 'ä»ĸ们'] +['æīĢè°ĵ', 'çļĦ'] +['æŃ»', 'äºĨ'] +['帮', 'æī¶'] +['åĵ²', 'åѦ'] +['以ä¸Ĭ', 'çļĦ'] +['çļĦ', 'åħ³éĶ®'] +['æĹ©', 'å°±'] +['æĬ¥', 'ä»·'] +['éģµ', 'å®Ī'] +['æī©', 'å¼ł'] +['æĺ¯', 'å¾Ī'] +['å¼Ģ', 'éĢļ'] +['æĸ°', 'åĬł'] +['æĸ°åĬł', 'åĿ¡'] +['ç¿»', 'è¯ij'] +['询', 'éĹ®'] +['é¸', 'Ń'] +['ä½ĵ', 'åĨħ'] +['两', '个人'] +['çĪ', '¹'] +['éľ', 'ľ'] +['乡æĿij', 'æĮ¯åħ´'] +['çĿ¡', 'è§ī'] +['å®ĺ', 'åijĺ'] +['åĪĽ', 'å§ĭ'] +['åĪĽå§ĭ', '人'] +['ä¼Ĺ', '人'] +['åį³', '便'] +['çĸ«', 'èĭĹ'] +['ä¼ģä¸ļ', 'å®¶'] +['æ¸', '£'] +['ç²¾', 'åĬĽ'] +['å¤ĸ', 'éĥ¨'] +['èģª', 'æĺİ'] +['è¿Ļ', 'ä¹Ł'] +['å½ķ', 'åıĸ'] +['åĨ²', 'çªģ'] +['åħ¨', '身'] +['åŃ£', 'èĬĤ'] +['忽', 'çĦ¶'] +['çļĦ', 'æĢģ度'] +['åĤ¨', 'å¤ĩ'] +['ä¿Ŀ', 'åħ»'] +['çļĦ', 'æĥ³æ³ķ'] +['ä¸Ĭæµ·', 'å¸Ĥ'] +['æIJº', 'æīĭ'] +['çļĦ', 'ä¿¡æģ¯'] +['åķĨ', 'åľº'] +['çļĦ', 'æĢĿæĥ³'] +['æĿĥ', 'åĬĽ'] +['毫', 'æĹł'] +['æĢĢ', 'åŃķ'] +['硬', 'ä»¶'] +['åĨħ', 'èĴĻåı¤'] +['æİ¢', '讨'] +['åħ»', 'çĶŁ'] +['çļĦ', '表çݰ'] +['空', 'ä¸Ń'] +['æģIJ', 'æĢĸ'] +['å¾Ī', 'é«ĺ'] +['ç»ıæµİ', '社ä¼ļ'] +['ä¸Ĭ', 'æĿ¥'] +['å»¶', 'ç»Ń'] +['éĩį', 'å¤į'] +['éĺ²', 'èĮĥ'] +['çļĦ', 'å½¢å¼ı'] +['æľĪ', 'åºķ'] +['èĢģ', '年人'] +['绿', 'åĮĸ'] +['å±±', 'åĮº'] +['æĭ¿', 'åĩº'] +['æĹħ', '客'] +['æĽ´', 'æį¢'] +['åħ¬', '主'] +['èĬĤ', '约'] +['åħ¨', 'åİ¿'] +['åĽŀ', 'æĬ¥'] +['çIJĨ', 'æĢ§'] +['çĸ¯', 'çĭĤ'] +['æ¶ī', 'å«Į'] +['åī§', 'æĥħ'] +['åĨ¬', 'åŃ£'] +['åIJİ', 'ç»Ń'] +['è¿Ļæĺ¯', 'ä¸Ģ个'] +['æ¼Ķ', '讲'] +['ä¸Ģ', 'å±Ĥ'] +['æľīåħ³', 'éĥ¨éŨ'] +['æĹł', 'å¥Ī'] +['ç§į', 'ç±»'] +['缸åħ³', 'çļĦ'] +['æĪĸèĢħ', 'æĺ¯'] +['æī¶', 'æĮģ'] +['å¤ļ', 'æķ°'] +['çļĦ', 'ä½ľåĵģ'] +['ä¸ĭ', 'ä¸ĢæŃ¥'] +['å¸Ī', 'åĤħ'] +['é«ĺéĢŁ', 'åħ¬è·¯'] +['好', 'åıĭ'] +['ä¼ĺç§Ģ', 'çļĦ'] +['è¿Ľ', 'äºĨ'] +['æģIJ', 'æĢķ'] +['äºĨ', 'åIJ§'] +['大', 'è§Ħ模'] +['çļĦ', 'ä¸ĸçķĮ'] +['æĢĢ', 'çĸij'] +['å·', '·'] +['åħ´', 'å¥ĭ'] +['æĪ', '°'] +['æĿij', 'éĩĮ'] +['æľĭåıĭ', 'åľĪ'] +['åĨ¬', '天'] +['ä¸Ńåįİ', '人æ°ij'] +['åįı', 'åķĨ'] +['è¯Ħ', 'éĢī'] +['æĹ', 'Ń'] +['å¢ŀåĬł', 'äºĨ'] +['åıĹ', '伤'] +['ä¸Ģ', 'èĤ¡'] +['便', 'æį·'] +['ä¸', 'ij'] +['é¹', '¤'] +['å¤ĸ', 'è§Ĥ'] +['å·¥ç¨ĭ', 'å¸Ī'] +['åĴĮ', 'åħ¶ä»ĸ'] +['è¿Ļ', 'å°±'] +['ä¸Ńå°ı', 'ä¼ģä¸ļ'] +['西', 'åĮĹ'] +['åĽ½æľī', 'ä¼ģä¸ļ'] +['èĭ¥', 'æĺ¯'] +['åı¯', 'æĥľ'] +['çĶŁ', 'æĹ¥'] +['åĩ', '½'] +['ä¹°', 'åįĸ'] +['ç¥Ŀ', 'ç¦ı'] +['人æ°ij', '群ä¼Ĺ'] +['åħī', 'æĺİ'] +['åħ¬', 'å¯ĵ'] +['æĺ¯', 'è°ģ'] +['æĪij', 'çŁ¥éģĵ'] +['è¯Ń', 'æĸĩ'] +['æķı', 'æĦŁ'] +['ä¸įéĶĻ', 'çļĦ'] +['æĿ¥', '讲'] +['æ³¢', 'åĬ¨'] +['çļĦ', '第ä¸Ģ'] +['åľ°', 'éľĩ'] +['åľ¨', 'åħ¨åĽ½'] +['骨', 'å¹²'] +['å®ī', 'ç½®'] +['å®¶', 'ç͵'] +['ä¸İ', 'æŃ¤'] +['ä¸İæŃ¤', 'åIJĮæĹ¶'] +['åıĹ', 'çģ¾'] +['çĥŃ', '线'] +['çļĦ', 'æĬĢæľ¯'] +['æµĭ', 'éĩı'] +['ä¾Ŀ', 'èµĸ'] +['ä¸ŃåĽ½', 'çļĦ'] +['çī¹', 'æĢ§'] +['è¾ĥ', 'é«ĺ'] +['è¸', '©'] +['ä¼ļ', 'åľ¨'] +['建', 'éĢł'] +['导', 'èĪª'] +['æĥ³', 'èµ·'] +['åħ¨', 'ä¸ĸçķĮ'] +['建', 'æĿIJ'] +['ç¯', 'Ģ'] +['çļĦ', 'åŁºç¡Ģ'] +['èĩªåĬ¨', 'åĮĸ'] +['åīį', 'åIJİ'] +['çĿ¡', 'çľł'] +['æİ¨', 'è¡Į'] +['æį®', 'äºĨè§£'] +['ä»Ģä¹Ī', 'æĹ¶åĢĻ'] +['ä¸į', 'åĸľæ¬¢'] +['çħ¤', 'çĤŃ'] +['éĤ£ä¹Ī', 'å¤ļ'] +['å¸Ĥåľº', 'åĮĸ'] +['ä¸į管', 'æĺ¯'] +['ç«ĭ', 'åľº'] +['éĥ½', '没'] +['课', 'é¢ĺ'] +['æĪij们', 'å°Ĩ'] +['è¿ĩ', 'çļĦ'] +['åĨį', 'åĬłä¸Ĭ'] +['çĪ', '¾'] +['身', 'æĿIJ'] +['çĶ·', '女'] +['è¿ľ', 'è¿ľ'] +['çĶ·', 'çĶŁ'] +['èĩªèº«', 'çļĦ'] +['è´Ł', 'æĭħ'] +['çϾ', 'ä¸ĩ'] +['西', 'çıŃ'] +['西çıŃ', 'çīĻ'] +['åĩĢ', 'åĪ©æ¶¦'] +['æ¾³', '大'] +['澳大', 'åĪ©äºļ'] +['ä¸į', 'åİ»'] +['æī¿', 'åıĹ'] +['楼', 'çĽĺ'] +['å¢ĥ', 'åĨħ'] +['æ··', 'åĩĿ'] +['æ··åĩĿ', 'åľŁ'] +['æĢĿæĥ³', 'æĶ¿æ²»'] +['å¸Ĥ', 'åĮº'] +['æĭĽ', 'æłĩ'] +['åĽ¢', 'ä½ĵ'] +['è¿Ľ', '度'] +['åĨĽ', 'éĺŁ'] +['åıį', 'å¼¹'] +['äºĨä¸Ģ', 'äºĽ'] +['æİ¥', 'å¾ħ'] +['çļĦ', 'åŃ¦ä¹ł'] +['éħį', 'éĢģ'] +['é£Łåĵģ', 'å®īåħ¨'] +['æĽ¿', '代'] +['æĺ¯', '以'] +['éĢļ', 'ç͍'] +['çłĶç©¶', 'æīĢ'] +['ç¦', 'ħ'] +['æī', 'Ķ'] +['éļĶ', '离'] +['ä¸ĩ', 'å¹³æĸ¹ç±³'] +['çļĦ', 'è§Ħå®ļ'] +['ç»Ļ', 'æĪij们'] +['æ¿Ģ', 'åħī'] +['ä¼ļ', 'åĩºçݰ'] +['çŁŃ', 'ä¿¡'] +['ç©¿', 'çĿĢ'] +['æ²Ī', 'éĺ³'] +['æķĻ', 'æĿIJ'] +['éĺ²', 'çĸ«'] +['ä¼ĺ', 'èī¯'] +['约', 'å®ļ'] +['æĪij', 'çľģ'] +['åħ¬', 'æ°ij'] +['éģ¸', 'æĵ'] +['é쏿ĵ', 'ĩ'] +['å·²', 'æĪIJ为'] +['ä¸į', 'å¿ħ'] +['ç¥ĸ', 'åĽ½'] +['å¹¶', 'æľª'] +['åľŁ', '壤'] +['å¾®', 'ç¬ij'] +['äºĭä¸ļ', 'åįķä½į'] +['çļĦ', '游æĪı'] +['åħ¬', '示'] +['åIJĪçIJĨ', 'çļĦ'] +['çª', 'Ŀ'] +['æ°Ķ', '象'] +['å®¶', 'ä¸Ń'] +['亮', '缸'] +['åį«', 'æĺŁ'] +['è®°', 'è½½'] +['è§Ĩ', 'éĩİ'] +['åľ°åĮº', 'çļĦ'] +['ä½Ĩ', 'ä»ĸ'] +['èĤĮ', 'èĤī'] +['äºı', 'æįŁ'] +['åĬŀ', 'åѦ'] +['ä¸Ģ', 'è¡Į'] +['è¯ŀ', 'çĶŁ'] +['åıijå¸ĥ', 'çļĦ'] +['çļĦ', 'æľįåĬ¡'] +['çļĦ', 'çłĶç©¶'] +['åij¨', 'æľ«'] +['产ä¸ļ', 'åĽŃ'] +['é«ĺ', '温'] +['æĪIJåĬŁ', 'çļĦ'] +['æŃ¥', '骤'] +['åŃĺ', 'åĤ¨'] +['åŃIJ', 'åħ¬åı¸'] +['让', '她'] +['ä¸Ń', 'æľī'] +['åĺī', '宾'] +['å¦', '®'] +['æĺİ', 'å¹´'] +['äºĨ', 'åIJĹ'] +['äºī', 'è®®'] +['æĪ', 'Ī'] +['ä¸Ģ', 'æľ¬'] +['ç¾İ丽', 'çļĦ'] +['ä½ł', '说'] +['大', '人'] +['æĶ»', 'çķ¥'] +['ä¸į', 'æľĥ'] +['å¾ħ', 'éģĩ'] +['ä¸Ģ', 'è¾Ĩ'] +['çīĪæĿĥ', 'æīĢæľī'] +['æ°ij', 'ä¼Ĺ'] +['åĬŁ', '夫'] +['å±ķ', 'ä¼ļ'] +['大', 'èĦij'] +['æ¯ı', 'æľĪ'] +['å°ı', '麦'] +['æµĻæ±Ł', 'çľģ'] +['çļĦ', 'æīĢæľī'] +['ä¸ĭ', 'æ»ij'] +['èĵĿ', 'èī²'] +['è¦ģ', 'æĥ³'] +['åѦçĶŁ', 'çļĦ'] +['å½ĵ', 'ä½ł'] +['ä½ľ', 'æĪĺ'] +['å®¶', '乡'] +['å¤ļ', 'åIJį'] +['é«ĺ', 'äºİ'] +['åĿļ', '强'] +['è¿ŀ', 'éĶģ'] +['åIJİ', 'æŀľ'] +['人', 'äºĭ'] +['ç´', 'ħ'] +['æ¿Ģ', 'åĬ¨'] +['è¿Ľ', 'æĶ»'] +['ç©', 'Ĩ'] +['ä¸', 'ĺ'] +['让', 'èĩªå·±'] +['以', 'æŃ¤'] +['夫', '人'] +['å¼Ģ', '设'] +['æ°Ķ', 'è´¨'] +['鸡', 'èĽĭ'] +['çĦ¡', 'æ³ķ'] +['åIJĥ', 'äºĨ'] +['åĪĨåĪ«', '为'] +['èģĶåIJĪ', 'åĽ½'] +['å½ĵ', '代'] +['å¦Ĥæŀľ', 'æĺ¯'] +['è¿ľ', 'ç¨ĭ'] +['åĸ', 'Ĥ'] +['è®°', 'ä½ı'] +['æ¸ħ', 'åįķ'] +['åIJĪä½ľ', 'ä¼Ļä¼´'] +['åİ»', 'åģļ'] +['æķħ', 'éļľ'] +['模', 'æĭŁ'] +['å¸Ī', 'çĶŁ'] +['åīį', 'æĿ¥'] +['ç͵è§Ĩ', 'åī§'] +['çĥŃ', 'çα'] +['éľ²', 'åĩº'] +['é«ĺ', 'å±Ĥ'] +['ç͵', 'åύ'] +['纪', 'å¾ĭ'] +['å¼Ģåıij', 'åķĨ'] +['éķ¿', 'å®ī'] +['è½½', 'ä½ĵ'] +['çļĦ', 'å°±æĺ¯'] +['被', '人'] +['åıĹ', 'çIJĨ'] +['篮', 'çIJĥ'] +['èİ', 'İ'] +['交', 'ç»Ļ'] +['æľªæĿ¥', 'çļĦ'] +['两', '大'] +['åIJķ', 'å¸ĥ'] +['çŃī', '人'] +['çļĦ', 'æĹ¥åŃIJ'] +['åIJĪä½ľ', '社'] +['æĮij', 'éĢī'] +['åŃĺ', '款'] +['ç³»ç»Ł', 'çļĦ'] +['æĬĬ', 'å®ĥ'] +['没æľī', 'ä»Ģä¹Ī'] +['ä»İ', 'æŃ¤'] +['ä¸Ń', 'åįĪ'] +['çĸ¼', 'çĹĽ'] +['å·©', 'åĽº'] +['浪', '漫'] +['缸åħ³', 'éĥ¨éŨ'] +['éķ¿', 'åŁİ'] +['纤', 'ç»´'] +['ä¸Ĭ', 'éŨ'] +['çĪĨ', 'çĤ¸'] +['èµ·', 'çĤ¹'] +['çļĦ', 'éĢļçŁ¥'] +['èĢĮ', 'æĿ¥'] +['çļĦ', 'èĢģ'] +['æīĭ', 'éĩĮ'] +['è¯Ń', 'éŁ³'] +['è¾Ľ', 'èĭ¦'] +['æ±Łèĭı', 'çľģ'] +['ç͍', 'äºĨ'] +['身份', 'è¯ģ'] +['æľī', 'åĬ©'] +['æľīåĬ©', 'äºİ'] +['çī©', 'èģĶç½ij'] +['åĩº', 'éŨ'] +['å¼Ł', 'åŃIJ'] +['æĥ', '¹'] +['è¿Ļä»¶', 'äºĭ'] +['æĪij们', 'åı¯ä»¥'] +['çļĦ', 'çĶŁåij½'] +['æľīä¸Ģ', 'ç§į'] +['åºĹ', 'éĵº'] +['åıĮ', 'æīĭ'] +['çļĦ', 'æ¶Īæģ¯'] +['èĢIJ', 'å¿ĥ'] +['å°´', 'å°¬'] +['éĤ£', '天'] +['é¦ĸ', 'æī¹'] +['æĺ¯ä¸Ģ', 'å®¶'] +['人', 'æ°Ķ'] +['åıį', 'æŃ£'] +['æĪij', 'åĴĮ'] +['å®ł', 'çī©'] +['ä¸į', '对'] +['寻', 'æ±Ĥ'] +['缸', 'ä¼¼'] +['åľ¨', 'ç¾İåĽ½'] +['åı«', 'åģļ'] +['åĹ', 'İ'] +['ç«ĭ', 'è¶³'] +['ç͍', 'éĢĶ'] +['åħ', 'Ĩ'] +['大', 'æ°Ķ'] +['åIJij', 'ä¸Ĭ'] +['ä»ĸ', 'å°±'] +['é¡¹çĽ®', '建设'] +['èĭ¥', 'å¹²'] +['æĺ¯', 'æľī'] +['æ¿Ģ', 'æĥħ'] +['çļĦ', 'æĦıä¹ī'] +['æĺ', 'Ń'] +['严éĩį', 'çļĦ'] +['å¯Ĩ', 'éĽĨ'] +['èĪŀ', 'è¹Ī'] +['èį£', 'èİ·'] +['èİ·', 'æĤī'] +['æ±Ł', 'åįĹ'] +['åģĩ', 'å¦Ĥ'] +['æĪ·', 'å¤ĸ'] +['线', 'ç´¢'] +['ç§ģ', '人'] +['转åŀĭ', 'åįĩ级'] +['çļĦ', 'ä»·å̼'] +['åįķ', 'çĭ¬'] +['èĢģ', 'çϾå§ĵ'] +['å°į', 'æĸ¼'] +['åĽ½éĻħ', 'åĮĸ'] +['ä¼°', 'å̼'] +['æľįåĬ¡', 'ä¸ļ'] +['èĩ', 'Ń'] +['æİī', 'äºĨ'] +['è§£åĨ³', 'äºĨ'] +['ä¹Ł', 'ä¸įèĥ½'] +['åħ', '¹'] +['æĸ¯', 'çī¹'] +['æķħ', 'æĦı'] +['è¿ĩ', '度'] +['èĬĤ', 'æĹ¥'] +['çϽ', 'çĻľ'] +['çϽçĻľ', 'é£İ'] +['ç»§', 'æī¿'] +['äºĨ', 'ä¸įå°ij'] +['äºĮ', '人'] +['è§ģ', 'éĿ¢'] +['æĥ³', 'æĥ³'] +['å¤į', 'åIJĪ'] +['康', 'å¤į'] +['åİ¿', 'åŁİ'] +['åľ¨', 'åĽ½åĨħ'] +['åľº', 'åľ°'] +['é϶', 'çĵ·'] +['è¿Ļ', '项'] +['çľ¼', 'ä¸Ń'] +['çł', '¸'] +['æĦŁè§ī', 'åΰ'] +['æŀľ', 'çĦ¶'] +['æĶ¾', 'åħ¥'] +['约', 'æĿŁ'] +['æİĴ', 'æŁ¥'] +['车', '主'] +['çļĦ', 'æĦıæĢĿ'] +['æĸ°', 'åŁİ'] +['æĥ³', 'çĿĢ'] +['éģ', 'Ĥ'] +['èĮ¶', 'åı¶'] +['ä¹°', 'æĪ¿'] +['åĨľ', 'æĪ·'] +['é«ĺ', 'æīĭ'] +['çİī', 'ç±³'] +['æĸ°åĨł', 'èĤºçĤİ'] +['çħ§', 'æĺİ'] +['æĮĩ', 'åįĹ'] +['è¸', '¢'] +['æķij', 'æı´'] +['æĻ¯', 'çĤ¹'] +['ç¨İ', 'æĶ¶'] +['çļĦ', 'æīĭ'] +['æŃ£', '好'] +['è¦ģ', 'æĬĬ'] +['éļı', 'æĦı'] +['åħ¶å®ŀ', 'æĺ¯'] +['ç»Ļ', 'èĩªå·±'] +['è°Ī', 'åΤ'] +['æ¯ı天', 'éĥ½'] +['æĢģ', 'åĬ¿'] +['é¢Ħ', '约'] +['åİĨåı²', 'ä¸Ĭ'] +['å®Ŀ', 'è´Ŀ'] +['åīį', 'è¿Ľ'] +['ä¹Łå°±æĺ¯', '说'] +['çļĦ', 'æĦıè§ģ'] +['åı£', '罩'] +['åİĺ', 'ç±³'] +['èĬ±', 'è´¹'] +['ä½ĵèĤ²', 'æĬķæ³¨'] +['åħ¬ä¼Ĺ', 'åı·'] +['èijĹåIJį', 'çļĦ'] +['å¼Ģ', 'æĪ·'] +['æĭį', 'åįĸ'] +['å²ģ', 'æľĪ'] +['åĨħ', 'æ¶µ'] +['å®Įæķ´', 'çļĦ'] +['é«ĺ', 'åİĭ'] +['åħ¬åĬ¡', 'åijĺ'] +['使ç͍', 'çļĦ'] +['çĶŁäº§', '线'] +['妹', '妹'] +['èµ°', '访'] +['æĺ¯', 'åı¯ä»¥'] +['åľ¨', 'å®¶'] +['æļ´', 'åĬĽ'] +['æ³°', 'åĽ½'] +['è´¨', 'çĸij'] +['ä¸į', 'éģİ'] +['天çĦ¶', 'æ°Ķ'] +['缺', 'çĤ¹'] +['å°ı', 'åŀĭ'] +['ä¸įä»ħ', 'æĺ¯'] +['é»ij', 'æļĹ'] +['æ¢', '¨'] +['æĸĩ', 'æĹħ'] +['è¦ģ', 'æľī'] +['ä¸Ń', 'å±±'] +['çļĦ', 'æķ°æį®'] +['å¾Ĺ', 'å¾Ī'] +['以', '便'] +['对', 'ä»ĸ'] +['åĬł', '以'] +['çϼ', 'çı¾'] +['设', 'å®ļ'] +['èĤļ', 'åŃIJ'] +['éĿ', 'ĸ'] +['å¥ī', 'çĮ®'] +['ä¸į', 'åıĺ'] +['åı£', 'ç¢ij'] +['åľ¨', 'åĵªéĩĮ'] +['ä½', 'IJ'] +['è¿Ļ', '两个'] +['çļĦ', 'æĸ¹åIJij'] +['æŀ', '«'] +['äºĮ', '次'] +['çīĩ', 'åĮº'] +['éł', 'IJ'] +['ç£', 'Ĭ'] +['æĭ¿', 'çĿĢ'] +['å·²ç»ı', 'æĪIJ为'] +['ä¹ĭ', 'ä¸Ĭ'] +['å®Ĺ', 'æĹ¨'] +['奶', '奶'] +['é«ĺæĸ°', 'åĮº'] +['社', 'æľĥ'] +['è·Ł', '踪'] +['æľįåĬ¡', 'ä¸Ńå¿ĥ'] +['æī', '¯'] +['æīĭ', 'æĮĩ'] +['礼', 'çī©'] +['宿', 'èĪį'] +['ç͍', 'å¿ĥ'] +['æıIJé«ĺ', 'äºĨ'] +['亮', 'çĤ¹'] +['ä¸į', 'æĦ¿æĦı'] +['æĴŃ', 'æĶ¾'] +['å¤ļå°ij', 'éĴ±'] +['没', 'ä»Ģä¹Ī'] +['æķ°', 'åįģ'] +['æĢ»', 'çĽij'] +['çļĦ', 'åŁİå¸Ĥ'] +['æī¾', 'åΰäºĨ'] +['åĨħ', 'åľ°'] +['åΰ', 'çİ°åľ¨'] +['æĪĺæĸĹ', 'åĬĽ'] +['åİŁ', 'å§ĭ'] +['åĥ', '§'] +['åĢĴ', 'æĺ¯'] +['æľĢ', 'åħ·'] +['è´«åĽ°', 'æĪ·'] +['éĢģ', 'åΰ'] +['级', 'åĪ«'] +['åĩº', 'èµĦ'] +['æĪª', 'æŃ¢'] +['ç§į', 'åŃIJ'] +['èĥ½', 'ä¸įèĥ½'] +['幸', 'è¿IJ'] +['èĸ', 'ĩ'] +['项', 'éĵ¾'] +['æĮĤ', 'çīĮ'] +['ä¸Ģ', '樣'] +['ä¹ĺ', '客'] +['èIJ½', 'åIJİ'] +['ä½Ĩ', 'æĪij'] +['æĹ©', 'åľ¨'] +['åĬ¨', '漫'] +['å¹³', 'çŃī'] +['对', 'ä½ł'] +['ä¸į', 'æĢķ'] +['å¤ĸ', 'çķĮ'] +['å¤ļå¹´', 'æĿ¥'] +['é¦ĸ', '个'] +['æ²³', 'åįĹçľģ'] +['æĪĸ', 'åħ¶ä»ĸ'] +['éķľ', '头'] +['åįĹ', 'æĺĮ'] +['ä¸Ģ', 'éĿ¢'] +['éĢłæĪIJ', 'çļĦ'] +['å´', 'Ķ'] +['çŃ', 'Ĵ'] +['æķĻèĤ²', 'éĥ¨'] +['åľ°', 'åŁŁ'] +['æĺĨ', 'æĺİ'] +['å·´', 'é»İ'] +['æīĭ', '游'] +['ä¸Ģ', 'æĹ¶'] +['çł', 'į'] +['é¡¶', '级'] +['åħ±', '计'] +['åİŁ', 'æ²¹'] +['è¾ī', 'çħĮ'] +['说', 'æĺ¯'] +['æĸ°åįİ', '社'] +['ç»ıåİĨ', 'äºĨ'] +['ä¸į', 'æŃ¢'] +['è¦ģ', 'ä¹Ī'] +['èĢħ', 'çļĦ'] +['æĢ»', 'æĬķèµĦ'] +['è¡Į', 'é©¶'] +['ä¸Ĭ', 'å¸Ŀ'] +['å¹´', '纪'] +['çIJ', '¼'] +['ä¼ł', '说'] +['ç²¾', 'èĭ±'] +['æĸ¹', 'éĴĪ'] +['æ±Ł', 'æ¹ĸ'] +['æĪIJ', 'çĤº'] +['æĢ»', 'éĩı'] +['æĬķ', 'æĶ¾'] +['åĬ¨', 'çĶ»'] +['èĹ', '¤'] +['ç͵', 'æºIJ'] +['éĴ', 'Ļ'] +['åIJĮ', 'è¡Į'] +['æĻ®éĢļ', 'çļĦ'] +['åĽ¾ä¹¦', 'é¦Ĩ'] +['è¯Ī', 'éªĹ'] +['æħĪ', 'åĸĦ'] +['è¿Ļ', '份'] +['主æĮģ', '人'] +['å°±', 'è¿Ļæł·'] +['èĢĮ', 'æĪIJ'] +['èĩªè¡Į', '车'] +['ä¸ŃåĽ½', 'çī¹èī²'] +['èĤ¿', 'çĺ¤'] +['åIJ', '¾'] +['å¼Ł', 'å¼Ł'] +['åıĹ', 'çĽĬ'] +['éĢīæĭ©', 'äºĨ'] +['æĺİæĺ¾', 'çļĦ'] +['æĬ¥', 'èĢĥ'] +['ç¬ij', 'éģĵ'] +['éĽĸ', 'çĦ¶'] +['温', 'å·ŀ'] +['éĿŀ', 'æ´²'] +['ç§į', 'ç§į'] +['åıĤåĬł', 'äºĨ'] +['è´§', 'è¿IJ'] +['éļı', '便'] +['å°±', '没æľī'] +['ç¸', '£'] +['央', 'è§Ĩ'] +['ç©¿', 'è¶Ĭ'] +['çļĦ', 'çݰ象'] +['åĩł', '次'] +['çļĦ', 'é£İéĻ©'] +['æŃĮ', 'æĽ²'] +['æľ¬', 'å±Ĭ'] +['å¹´', 'åĨħ'] +['ä¸į', 'è¶ħè¿ĩ'] +['è¿ĩ', 'å¤ļ'] +['å¿ħé¡»', 'è¦ģ'] +['ç»ĵ', '论'] +['åĢŁ', 'éī´'] +['ç¥ŀ', 'å¥ĩ'] +['æľŁ', 'æľĽ'] +['ä¸ĵ', '享'] +['éĿŀ常', 'éĩįè¦ģ'] +['æĦıè¯Ĩ', 'åΰ'] +['åIJĪ', 'å¹¶'] +['æĬĬ', 'èĩªå·±'] +['å¥Ĺ', 'è£ħ'] +['éŃĶ', 'æ³ķ'] +['å¤ı', 'åŃ£'] +['ä¸į', 'åĥı'] +['å¢ĥ', 'çķĮ'] +['æĥĬ', 'åĸľ'] +['æľīä¸Ģ', '天'] +['çĦ¦', 'çĤ¹'] +['æĪij', '认为'] +['åħ°', 'å·ŀ'] +['ç͵', 'æ°Ķ'] +['èģĶç³»', 'æĪij们'] +['ç§ij', 'æĻ®'] +['她', '说'] +['çļĦ', 'æĸĩ竳'] +['å¥ĩ', 'æĢª'] +['åıĭ', '好'] +['饮', 'æĸĻ'] +['çļĦ', 'æĶ¯æĮģ'] +['çŃĶ', 'åºĶ'] +['éĩį', 'éĩı'] +['çij', '¶'] +['åĩı', 'è½»'] +['ç§ijåѦ', 'å®¶'] +['å·´', '西'] +['éĩijèŀį', 'æľºæŀĦ'] +['åħļ', 'å§Ķ书记'] +['貸', '款'] +['ç²¾', 'èĩ´'] +['ä»İ', 'æľª'] +['åį°', 'åĪ·'] +['åĽŀ', '顾'] +['é¦ĸ', 'éĥ½'] +['åıij', 'èĤ²'] +['éĹ®', 'éģĵ'] +['è¾¾', 'åΰäºĨ'] +['å¿į', 'ä¸įä½ı'] +['æīį', 'æľī'] +['æįIJ', 'èµł'] +['ä½Ľ', 'æķĻ'] +['ä¸į', 'æ¸ħ'] +['éĺŁ', 'éķ¿'] +['缸', 'åıį'] +['æĬ¥', 'èѦ'] +['大', 'åħ¨'] +['欧', '缣'] +['帮', 'å¿Ļ'] +['çļĦ', 'æĻĤåĢĻ'] +['缮', 'å½ķ'] +['è¶³', '以'] +['èī°', 'éļ¾'] +['ä»ĸ', 'ä¹Ł'] +['å·¥', 'ä½ľèĢħ'] +['头', 'èĦij'] +['缺', 'éĻ·'] +['æĪIJç«ĭ', 'äºĨ'] +['å°±', 'å¼Ģå§ĭ'] +['认', 'åIJĮ'] +['é»Ħ', 'èī²'] +['çĹħ', 'æĥħ'] +['覺', 'å¾Ĺ'] +['è¿Ļ', '两'] +['ä¿¡', 'ä»°'] +['åľĭ', 'å®¶'] +['ä¸įä»ħä»ħ', 'æĺ¯'] +['çĭ¬', 'å®¶'] +['èά', 'çļĦ'] +['æĿIJ', 'è´¨'] +['æµ·', 'ä¸Ĭ'] +['çĤº', 'äºĨ'] +['æľºåĬ¨', '车'] +['缸å½ĵ', 'äºİ'] +['å¤ļåħĥ', 'åĮĸ'] +['æĽ´', '大çļĦ'] +['èĽ', '®'] +['åģĩ', 'æľŁ'] +['å¼ı', 'çļĦ'] +['交éĢļ', 'è¿IJè¾ĵ'] +['çľģ', 'å§Ķ'] +['ä¸į', 'ç®Ĺ'] +['æĶ¾', 'ä¸ĭ'] +['éĹ', '¯'] +['人', 'åľ¨'] +['港', 'åı£'] +['æĹ¨', 'åľ¨'] +['åij½', '令'] +['æŁIJ', '个'] +['å¹³', '稳'] +['åıª', '好'] +['人', '人'] +['äº', 'ŀ'] +['äºĮ', 'ç»´'] +['äºĮç»´', 'çłģ'] +['æŀģ', '为'] +['åĪ«', 'å¢ħ'] +['åħ¶', 'ä½Ļ'] +['大', 'äºĭ'] +['主管', 'éĥ¨éŨ'] +['æĹł', 'éĶ¡'] +['éĹ', 'µ'] +['éģŃ', 'åΰ'] +['说', 'è¿ĩ'] +['为', 'ä½ł'] +['è§£', 'çŃĶ'] +['éªĮ', 'æĶ¶'] +['çļĦ', 'ç»ıéªĮ'] +['åĮ¹', 'éħį'] +['çģ«', 'ç®Ń'] +['豪', 'åįİ'] +['æŁIJ', 'æŁIJ'] +['çļĦ', 'æĹ¶ä»£'] +['书', 'éĿ¢'] +['æģĴ', '大'] +['å»¶', 'éķ¿'] +['ä¸Ģ', 'åIJĮ'] +['æľª', 'èĥ½'] +['交', 'æį¢'] +['çĶ¢', 'åĵģ'] +['çŃī', 'åΰ'] +['åĪĨ', '离'] +['æīĵ', 'ç͵è¯Ŀ'] +['å¹²', 'çĩ¥'] +['è¾ĥ', 'å¤ļ'] +['å¤ļå¹´', 'çļĦ'] +['èĥĮæĻ¯', 'ä¸ĭ'] +['为', 'ä¾ĭ'] +['æijĺ', 'è¦ģ'] +['å´Ľ', 'èµ·'] +['æŃ¤', 'åĪ»'] +['æľī', 'æľºä¼ļ'] +['æĿ¡', '款'] +['é¢Ĩ导', 'å°ıç»Ħ'] +['çļĦ', '身ä½ĵ'] +['åįķ', 'ä¸Ģ'] +['央', 'è¡Į'] +['ä¸įæĸŃ', 'æıIJé«ĺ'] +['ä»·å̼', 'è§Ĥ'] +['èĬ', '½'] +['èIJ', 'į'] +['æ³ķå¾ĭ', 'æ³ķè§Ħ'] +['ä¸į', 'éĶĪ'] +['ä¸įéĶĪ', 'éĴ¢'] +['åĩº', 'äºİ'] +['èĻļ', 'æĭŁ'] +['æį®', 'æĤī'] +['çĥ¦', 'æģ¼'] +['åħ¨', 'æĸ°çļĦ'] +['æī«', 'æıı'] +['çĻ»', 'éĻĨ'] +['èīºæľ¯', 'å®¶'] +['çļĦ', 'é£Łçī©'] +['çļĦ', 'åŃĺåľ¨'] +['客', 'åİħ'] +['æĪij们', 'å°±'] +['æŁ¥çľĭ', 'æĽ´å¤ļ'] +['è¯Ħ', '审'] +['å¸Ĥ', 'åł´'] +['è¬', 'Ľ'] +['å·¨', '头'] +['ä¸ŃåĽ½', 'ç»ıæµİ'] +['äºĨ', 'èĩªå·±çļĦ'] +['åĨ³', 'è®®'] +['çĽijçĿ£', '管çIJĨ'] +['æĬķ', '票'] +['åĨį', '度'] +['è¡Į', 'çĤº'] +['注', 'åħ¥'] +['ä½ľä¸º', 'ä¸Ģ个'] +['æ¯ı个人', 'éĥ½'] +['åįķ', 'åħĥ'] +['è¦ģ', 'çŁ¥éģĵ'] +['被', '称为'] +['ä¹ĭ', 'éĻħ'] +['è§£', 'éϤ'] +['ä¸', '¸'] +['æº', '«'] +['ä¸ī', 'æĺŁ'] +['é²ľ', 'æĺİ'] +['ä¹Ł', 'éĥ½'] +['æĹ¶', 'æľº'] +['åĩº', 'æīĭ'] +['æĥħ', 'å½¢'] +['åķĨ', 'è´¸'] +['éĢī', '举'] +['对', 'èĩªå·±'] +['çĶŁ', 'åĬ¨'] +['åħĭ', 'æľį'] +['个', 'ä½ĵ'] +['èĭ', 'ij'] +['ç¨', '±'] +['大', 'åݦ'] +['æĺ¯', '对'] +['åĪ©', 'æģ¯'] +['è¿IJåĬ¨', 'åijĺ'] +['åĮĸ', 'è§£'] +['åīį', '沿'] +['æĦŁ', 'æģ©'] +['æĢ»', 'ä¹ĭ'] +['é«ĺæĸ°', 'æĬĢæľ¯'] +['åĿĩ', '为'] +['åħ¨', 'åĮº'] +['æ°Ķ', 'æ°Ľ'] +['åı¯ä»¥è¯´', 'æĺ¯'] +['ä½ı', '宿'] +['åħļåijĺ', 'å¹²éĥ¨'] +['åĹ', '¯'] +['è·µ', 'è¡Į'] +['çļĦ', 'ä¸ĵä¸ļ'] +['èĢĥ', 'éªĮ'] +['èķ', '¾'] +['åħ¬', 'åŃIJ'] +['çļĦ', 'çĬ¶æĢģ'] +['æ½®', 'æµģ'] +['ä¿¡', 'æīĺ'] +['è´', '¼'] +['åIJĦ', 'æĸ¹'] +['æķij', 'åĬ©'] +['éĿŀ常', 'çļĦ'] +['æ¡¥', 'æ¢ģ'] +['åħ¬', 'æĸ¤'] +['ä¼¼', 'çļĦ'] +['çľĭ', '好'] +['å±Ģ', 'éĥ¨'] +['å®ī', 'éĿĻ'] +['éħį', 'ä»¶'] +['常', 'è§Ħ'] +['å¼Ģ', '车'] +['第äºĮ', '次'] +['ä¸Ĭ', '级'] +['åıĤ', 'èµĽ'] +['å®¶', 'å±ŀ'] +['强', 'åĬ¿'] +['åľ¨', 'ä»ĸ'] +['åIJij', 'åīį'] +['ä¹ĭ', 'åľ°'] +['éĥ', '¡'] +['è¡Į', 'ç¨ĭ'] +['èѦ', 'åijĬ'] +['è§Ħå®ļ', 'çļĦ'] +['åķĨ', 'åŁİ'] +['äºĶ', '大'] +['æķĻ', '室'] +['åįģ', 'è¶³'] +['æīĢ以', 'åľ¨'] +['å°Ĩ', 'ç»§ç»Ń'] +['çŃī', 'æĸ¹å¼ı'] +['å®¶', 'ä¼ģä¸ļ'] +['交', 'ä»ĺ'] +['çĤ¹', 'è¯Ħ'] +['ç»ĵ', 'ç®Ĺ'] +['ä¹Ł', 'åı¯'] +['å¤ĸ', 'æ±ĩ'] +['è¿Ļç§į', 'æĥħåĨµ'] +['æİĪ', 'äºĪ'] +['å¸ĥ', 'ç½®'] +['æĪIJç«ĭ', 'äºİ'] +['é¢Ħ', 'èѦ'] +['管çIJĨ', '人åijĺ'] +['å©ļ', '礼'] +['ç»ĵæĿŁ', 'åIJİ'] +['åħ¥', 'éĢī'] +['æĹł', 'æ¯Ķ'] +['åĴĮ', 'åıijå±ķ'] +['çϽ', 'éħĴ'] +['çİ©', 'åħ·'] +['ä¸ĩ', 'ç¾İåħĥ'] +['çļĦ', 'æĪIJ绩'] +['æĭį', 'çħ§'] +['èĢĥèĻij', 'åΰ'] +['ä¼ģä¸ļ', 'åıijå±ķ'] +['äºĨ', '个'] +['çĶŁ', 'æ°Ķ'] +['çļĦ', '女人'] +['äºĶ', 'åįģ'] +['çĪ·', 'çĪ·'] +['纽', '约'] +['éĥ½', '被'] +['ä¸Ĭ', '课'] +['çĽ', '¡'] +['ä¼łç»Ł', 'æĸĩåĮĸ'] +['æ½ľ', 'åľ¨'] +['åıij', 'å°Ħ'] +['ä¸Ģ', '身'] +['éĺ²', 'å®Ī'] +['åĪ', '®'] +['é¢ĺ', '缮'] +['åľ¨', 'åĨħçļĦ'] +['ç¾İ', '好çļĦ'] +['è¿ĻéĩĮ', 'çļĦ'] +['ä¸Ģ', 'ä¸Ŀ'] +['人', 'åĿĩ'] +['åĢ¡', '导'] +['身', 'åIJİ'] +['æī©', 'å±ķ'] +['大', 'éŨ'] +['å°±', '被'] +['该', 'é¡¹çĽ®'] +['æŀ¶', 'æŀĦ'] +['ä¸Ģ', 'åı£'] +['ä¿¡æģ¯', 'æĬĢæľ¯'] +['å¼Ģ', 'ä¸ļ'] +['æĶ¶', 'åıĸ'] +['ç½ij', '页'] +['æĶ¯', 'æı´'] +['å°ģ', 'éĹŃ'] +['å¡ij', 'éĢł'] +['大', 'èĥĨ'] +['å¿«éĢŁ', 'åıijå±ķ'] +['çľĭ', 'ä¼¼'] +['æ¸', 'Ŀ'] +['è¿Ļæł·', 'ä¸Ģ个'] +['模', 'åĿĹ'] +['注æĦı', 'åΰ'] +['çł´', 'è§£'] +['èĩª', 'ä»İ'] +['åijµ', 'åijµ'] +['ä¹ĭ', 'å¾Į'] +['ä¹ĭ', 'æĹħ'] +['è·Ł', 'æĪij'] +['æ³ķ', '人'] +['æİĴè¡Į', 'æ¦ľ'] +['åĿļ', 'å®Ī'] +['好', 'å¤Ħ'] +['çŁ³', '头'] +['å¹¶', 'å°Ĩ'] +['èĪ', '±'] +['æŃ', 'ĩ'] +['两', '岸'] +['å¤ļ', 'ä¹ħ'] +['象', 'å¾ģ'] +['个æĢ§', 'åĮĸ'] +['çļĦ', 'è§Ĵ度'] +['å¸', 'Ĩ'] +['ç¦ı', 'å·ŀ'] +['æŁ¥', 'å¤Ħ'] +['两', 'åĽ½'] +['åIJ¸å¼ķ', 'äºĨ'] +['é¦ĸ', 'å¸Ń'] +['大', 'åĵ¥'] +['é¤', 'Ĭ'] +['涨', 'å¹ħ'] +['éĢī', 'ç͍'] +['許', 'å¤ļ'] +['èIJ½', 'æĪ·'] +['åĵĪ', 'å°Ķ'] +['åĵĪå°Ķ', '滨'] +['åģļ', 'ä»Ģä¹Ī'] +['以', 'åħį'] +['é¾', 'į'] +['æĹł', 'éľĢ'] +['åΰåºķ', 'æĺ¯'] +['æĢ', '¡'] +['åijĬè¯ī', 'ä½ł'] +['éĺ²', 'æ°´'] +['è¿Ļ', 'æĹ¶åĢĻ'] +['欢', 'ä¹IJ'] +['转', 'åIJij'] +['è¿Ļ个', 'åľ°åĽ¾'] +['åħ¥', 'é©»'] +['èįī', 'åİŁ'] +['æĹ¶ä»£', 'çļĦ'] +['åıĺ', 'åĬ¨'] +['åĬłå¼º', '对'] +['åģ¶', 'å°Ķ'] +['å®Ī', 'æĬ¤'] +['æ°Ķ', '温'] +['人', 'éĹ´'] +['æľĿ', 'é²ľ'] +['ç»ı', 'è´¹'] +['åĽŃ', 'æŀĹ'] +['å·¥', 'åľ°'] +['è§Ħ', 'æł¼'] +['åĩł', 'åįģ'] +['è¯ķ', 'åĽ¾'] +['å¦', 'ĥ'] +['éĤ£', 'æĹ¶åĢĻ'] +['å¼ĺ', 'æī¬'] +['ä¸ļ', 'çķĮ'] +['çļĦ', 'éĢŁåº¦'] +['ä¼ļ', 'ä¸įä¼ļ'] +['èIJ¥', 'æĶ¶'] +['å°ıå¾®', 'ä¼ģä¸ļ'] +['çľĭ', 'è¿ĩ'] +['æĬĬ', 'ä»ĸ'] +['éģµ', '循'] +['è¿Ļ', 'è¾¹'] +['没æľī', '人'] +['å£', '¶'] +['æ¹ĸ', 'åįĹçľģ'] +['æŀģ', 'åħ¶'] +['çļĦ人', 'çĶŁ'] +['ä»ĸ', 'è¿ĺ'] +['转åĮĸ', '为'] +['èµ°', 'è¿ĩ'] +['æĬ±', 'çĿĢ'] +['çīĽ', '奶'] +['ä¸ĩ', '亩'] +['å¿ĥ', 'æĢģ'] +['æĹ¥å¸¸', 'çĶŁæ´»'] +['ä½ĵ', 'æ£Ģ'] +['æĻ', 'ĥ'] +['çŃī', 'é¢ĨåŁŁ'] +['æĩī', '該'] +['åı¯ä»¥', 'çľĭåΰ'] +['æī¾', 'ä¸įåΰ'] +['èĢģ', 'å¹´'] +['æĬĬ', 'æĪij'] +['积', 'åĪĨ'] +['梳', 'çIJĨ'] +['ç»', '³'] +['çļĦ', 'æĶ¿æ²»'] +['å¸Ŀ', 'åĽ½'] +['éĻª', 'ä¼´'] +['æ´Ľ', 'éĺ³'] +['åħ¬', 'æŃ£'] +['å¼Ģ', 'åı£'] +['çī¹èī²', 'çļĦ'] +['åĽ°', 'å¢ĥ'] +['ä¸Ĭ', 'æľī'] +['ç«ĭ', 'ä½ĵ'] +['æīĵ', 'å·¥'] +['åķ¤', 'éħĴ'] +['åľ¨', 'éĤ£éĩĮ'] +['éĤ£', 'è¾¹'] +['个', 'åĪ«'] +['ä¸Ģå®ļ', 'æĺ¯'] +['çļĦéĩįè¦ģ', 'æĢ§'] +['主', 'å¼ł'] +['åĴĮ', 'æľįåĬ¡'] +['ä¸Ĭ', 'ç½ij'] +['è¡¥', 'åĬ©'] +['åıª', 'éľĢ'] +['å¼', '¦'] +['éģ', '®'] +['åĬĽ', 'äºī'] +['度', 'è¿ĩ'] +['èij', '¬'] +['é¡¿', 'æĹ¶'] +['éĦ', 'ī'] +['纺', 'ç»ĩ'] +['åľ°', 'åĿĹ'] +['ä¿¡ç͍', 'åį¡'] +['ç½ļ', '款'] +['åijĬè¯ī', 'æĪij'] +['éĽ', 'Ļ'] +['书', 'çĶ»'] +['è¨Ń', 'è¨Ī'] +['æĢ»', 'ä¼ļ'] +['åΤ', 'åĨ³'] +['ä¿¡', 'èªī'] +['个', 'èĤ¡'] +['å¹³', '常'] +['æĢİ', '麼'] +['ä½ĵ', 'çİ°åľ¨'] +['é»Ħ', 'æ²³'] +['åĽĽå·Ŀ', 'çľģ'] +['羣', '缸'] +['åIJĦ项', 'å·¥ä½ľ'] +['åĬ¨', 'åijĺ'] +['å³°', 'ä¼ļ'] +['ä¸Ģ', 'æľŁ'] +['æľī', 'ä¸Ģå®ļçļĦ'] +['é«ĺ度', 'éĩįè§Ĩ'] +['ç¹ģ', 'èį£'] +['åıijçݰ', 'äºĨ'] +['ç½ij', '红'] +['æīĭ', 'æ³ķ'] +['å®¶', 'åĽŃ'] +['仪', 'åύ'] +['è¾ĥ', 'ä½İ'] +['çļĦ', 'å®īåħ¨'] +['æ¡', 'IJ'] +['ä»ĺ', '款'] +['æĬij', 'åζ'] +['åįĵ', 'è¶Ĭ'] +['æŃ£', 'éĿ¢'] +['åĵ', 'ij'] +['强', 'åζ'] +['ä»Ĭ天', 'çļĦ'] +['æĪĺ', 'èĥľ'] +['楼', 'å¸Ĥ'] +['æĭ¿', 'ä¸ĭ'] +['é¢ľ', 'å̼'] +['举', 'éĥ¨'] +['çłĶ', 'åζ'] +['çļĦ', 'æĪĺçķ¥'] +['åľ¨', 'ä¸Ģ个'] +['ä¸ī', '人'] +['å®Į', 'äºĨ'] +['æĸ°', 'æĬĢæľ¯'] +['ç»ıæµİ', 'æķĪçĽĬ'] +['å¯Į', 'æľī'] +['æ¾³', 'æ´²'] +['åĬ©', 'çIJĨ'] +['é¢Ĩ', 'åıĸ'] +['è°', 'Ń'] +['çĩĥ', 'çĥ§'] +['ç´ł', 'åħ»'] +['éĤĦ', 'æľī'] +['è¿Ľ', 'èĢĮ'] +['ä»Ģä¹Ī', 'æĺ¯'] +['çłĶç©¶', 'ä¸Ńå¿ĥ'] +['éĢĤ', 'ç͍äºİ'] +['æİ¥', 'æĶ¶'] +['失', 'æľĽ'] +['äºĮ', '级'] +['éĹ´', 'çļĦ'] +['åİŁ', 'æłĩé¢ĺ'] +['èªį', 'çĤº'] +['æį', '¡'] +['对', 'çĿĢ'] +['对', 'éĿ¢'] +['ä¸Ń', 'åİŁ'] +['éĵ', 'ĥ'] +['çĶŁäº§', 'çļĦ'] +['åıijå¸ĥ', 'ä¼ļ'] +['士', 'åħµ'] +['è¿Ļ', 'åı¥è¯Ŀ'] +['ç¼´', '纳'] +['ä¸Ģ个', '个'] +['åѸ', 'çĶŁ'] +['çĸij', 'éĹ®'] +['交', 'èѦ'] +['示èĮĥ', 'åĮº'] +['天', '使'] +['åľ¨', 'ä¸Ĭæµ·'] +['åIJĮ', 'æĻĤ'] +['è½»', 'æĺĵ'] +['å͝ä¸Ģ', 'çļĦ'] +['çĥŃ', 'éĹ¹'] +['ä¹IJ', 'è§Ĥ'] +['çļĦ', '身份'] +['åĸĦ', 'äºİ'] +['大', 'åİħ'] +['èĤ¯å®ļ', 'æĺ¯'] +['éĺ²', 'çģ«'] +['å¤ĸ', 'åĩº'] +['æį®', '说'] +['é¡¹çĽ®', 'çļĦ'] +['ä¸Ģ', 'åı°'] +['èĻļ', 'åģĩ'] +['ä¸Ģ', 'ç¬Ķ'] +['ç«ĭ', 'æ³ķ'] +['严', 'èĤĥ'] +['æī¿', 'åĬŀ'] +['åįģ', 'åĩł'] +['çļĦ', '空éĹ´'] +['æľ¬', 'ç½ijç«Ļ'] +['åģļ', 'å¾Ĺ'] +['ä¿Ŀ', '温'] +['æľĪ', 'åĪĿ'] +['åľ¨', 'ç½ijä¸Ĭ'] +['åIJĦ', 'æĸ¹éĿ¢'] +['ä¸ī', '天'] +['交æĺĵ', 'æīĢ'] +['è§£', 'æŀIJ'] +['åħļ', 'ä¸Ń央'] +['è¿Ľ', 'åĩºåı£'] +['åĴĮ', '社ä¼ļ'] +['次', 'æķ°'] +['ä¹ĭ', 'å®¶'] +['ç»´', '度'] +['æ´¾åĩº', 'æīĢ'] +['产çĶŁ', 'äºĨ'] +['带', 'æľī'] +['å¾Ī', '强'] +['æľīäºĽ', '人'] +['å¹´', 'åIJİ'] +['äºĨ', '许å¤ļ'] +['å¯Ĩ', '度'] +['åѦ', 'æľŁ'] +['çıł', 'æµ·'] +['æľĢå¤ļ', 'çļĦ'] +['è¾¹', 'ç¼ĺ'] +['容', 'éĩı'] +['第äºĮ', '个'] +['ä¸Ģ缴', 'æĺ¯'] +['ä¸į', 'ç¦ģ'] +['æŃ', '²'] +['ä»ĭç»į', 'äºĨ'] +['ä¼ĺ', 'éĽħ'] +['æ¯Ķ', 'è¼ĥ'] +['èģĮ', 'ä½į'] +['温', 'æŁĶ'] +['æľī', 'éĴ±'] +['æľĢ', 'é«ĺçļĦ'] +['åįļè§Ī', 'ä¼ļ'] +['ä¸į', 'æĪIJ'] +['éĶĻ', 'äºĨ'] +['è¯ģ', 'çĽij'] +['è¯ģçĽij', 'ä¼ļ'] +['æĪIJ', '人'] +['åĿĩ', 'åĮĢ'] +['æľī', 'åĪ©'] +['è¶Ĭ', 'åįĹ'] +['æīĵ', 'äºĨ'] +['好', 'åIJĥ'] +['ç³»', 'çµ±'] +['è·Ł', 'éļı'] +['çļĦ', 'åľ°ä½į'] +['æŃ£', 'å¦Ĥ'] +['ç¨į', 'å¾®'] +['åį°', 'åıij'] +['åĪĽ', 'ç«ĭ'] +['é£İ', 'åħī'] +['å°Ĩ', 'æĪIJ为'] +['ä¸į', 'é«ĺ'] +['é¢ij', 'ç¹ģ'] +['设', 'æľī'] +['ä¼', 'ŀ'] +['æĭĨ', 'éϤ'] +['å½±', 'åĥı'] +['æ¸Ĺ', 'éĢı'] +['å¹´', 'å¼Ģå§ĭ'] +['ç½ij', 'æĺĵ'] +['è¦ģ', 'åģļ'] +['ç͵åĬ¨', '车'] +['羣', 'å¿ĥ'] +['æµ·', 'åĨĽ'] +['ä¼ł', 'æĿ¥'] +['å·®', 'åĪ«'] +['è°¨', 'æħİ'] +['çĥŁ', 'åı°'] +['åįĥ', 'å¹´'] +['è¯ģ', 'å®ŀ'] +['çIJ', 'ª'] +['çļĦ', 'åħ·ä½ĵ'] +['åΰ', 'å¤Ħ'] +['ä¸į', 'å®ľ'] +['èľ', 'Ģ'] +['èĥ½åĬĽ', 'åĴĮ'] +['çīº', 'çī²'] +['çļĦ', 'éĴ±'] +['大', 'éĺŁ'] +['é¦ĸ', 'è¦ģ'] +['ä¸į', 'æĦ¿'] +['çİ«', 'çij°'] +['人æ°ij', 'ç½ij'] +['è¿ĺæĺ¯', 'è¦ģ'] +['åĽĽ', 'å¹´'] +['æįŁ', '伤'] +['çļĦ', 'åģļæ³ķ'] +['éĿ', 'Ī'] +['è¡Ķ', 'æİ¥'] +['åIJĪ', 'æĪIJ'] +['没', '人'] +['éŨ', 'æ§Ľ'] +['ä¿¡', 'è´·'] +['çļĦ', '缸åħ³'] +['举', 'é£İ'] +['社', 'ä¿Ŀ'] +['ä¸ĭ', '游'] +['åĿĹ', 'éĴ±'] +['è¿ĩ', 'åIJİ'] +['çļĦ', 'åºĶç͍'] +['é¥', '¶'] +['é¢ģ', 'åıij'] +['ä¸Ģ', 'å¤Ħ'] +['åįİ', 'å¤ı'] +['为', 'ä¼ģä¸ļ'] +['åıª', 'ä¼ļ'] +['ä¾µ', '害'] +['çļĦ', 'åĬŁèĥ½'] +['åѸ', 'ç¿Ĵ'] +['ä¸Ńåįİ', 'æ°ijæĹı'] +['åıijå¸ĥ', 'äºĨ'] +['è¿İ', 'æİ¥'] +['æĪij', 'èĩªå·±'] +['è¿ĺ', 'éľĢè¦ģ'] +['太éĺ³', 'èĥ½'] +['åİ»', 'ä¸ĸ'] +['æĺ¯', 'ä½ł'] +['åIJĪ', 'åĬĽ'] +['ç»ĺ', 'çĶ»'] +['åı°', 'åĮĹ'] +['çĿ£', 'ä¿ĥ'] +['åĮĹ', 'éĥ¨'] +['æľī', 'å¤ļå°ij'] +['å¾Ī', 'éĩįè¦ģ'] +['åĪĴ', 'åĪĨ'] +['åı·', '线'] +['æĶ¾', '大'] +['ä¼ļ', '被'] +['èİ·', 'å¥ĸ'] +['ä¹ĭ', 'åĨħ'] +['失', 'åİ»äºĨ'] +['çݩ家', '们'] +['éĩĩ', 'éĽĨ'] +['å£', '¹'] +['å®¶', 'ä¼Ļ'] +['çϽ', '天'] +['åĽłä¸º', 'ä»ĸ'] +['社ä¼ļ', 'æ²»çIJĨ'] +['å¼Ģ', 'åĪĽ'] +['ç͵', 'ç¼Ĩ'] +['æĸ°', 'ä¸Ģ代'] +['å¹¶', 'è´Ń'] +['å°±', 'å·²ç»ı'] +['çļĦ', '社ä¼ļ'] +['éϤ', 'éĿŀ'] +['åı¯ä»¥', 'ç͍'] +['å©', 'ī'] +['æ¯Ķè¾ĥ', '好'] +['å®ŀ', 'ä¸ļ'] +['åĪĽ', 'åĬŀ'] +['æıIJ', 'èµ·'] +['é»', 'ĥ'] +['ä½ı', 'åľ¨'] +['å¸Ĥ', 'æĶ¿'] +['éĿ¢ä¸´', 'çļĦ'] +['èĥ½', 'åľ¨'] +['çŁŃ', 'çŁŃ'] +['羣', '人'] +['æĺİ', 'æĺİ'] +['èµĦ', 'åĬ©'] +['çļĦ', 'ä¸įåIJĮ'] +['å°ı', 'æľĭåıĭ'] +['é¢ĺ', 'æĿIJ'] +['ç¾İ', 'åij³'] +['æĺŁ', '座'] +['ä¸į', 'ä¸Ģæł·çļĦ'] +['çľĭ', 'ä¸Ĭåİ»'] +['ä¸Ģ', 'æł¹'] +['广', 'å·ŀå¸Ĥ'] +['åıijçĶŁ', 'çļĦ'] +['é«ĺ', 'ç§ijæĬĢ'] +['ä¸Ģ', 'è¾ĪåŃIJ'] +['交', 'åıī'] +['ä½ĵç³»', '建设'] +['åĽłä¸º', 'æĪij'] +['çıį', 'æĥľ'] +['ä¸Ĭ', 'åѦ'] +['æĪĺ', 'æľ¯'] +['æŃ¤', 'ç±»'] +['交', 'å¾Ģ'] +['æĮī', 'æij©'] +['人们', 'çļĦ'] +['åħ¶', '實'] +['åİŁ', 'æĿIJæĸĻ'] +['渴', 'æľĽ'] +['缸', 'å¤Ħ'] +['å¾®', 'å¾®'] +['æ®', '·'] +['ä¹ĺ', 'åĿIJ'] +['å¼Ģå±ķ', 'äºĨ'] +['é«ĺ', 'åĵģè´¨'] +['æĹłäºº', 'æľº'] +['ä¸įæĺ¯', 'å¾Ī'] +['çļĦ', 'æĬķèµĦ'] +['èĬĤ', 'çľģ'] +['èĩ', 'ī'] +['ç²¾', 'éĢī'] +['çļĦ', 'æłĩåĩĨ'] +['åįĹ', 'éĥ¨'] +['认è¯Ĩ', 'åΰ'] +['å¹³', 'éĿĻ'] +['èĹ', '¥'] +['æī«', 'é»ij'] +['æī«é»ij', 'éϤ'] +['æī«é»ijéϤ', 'æģ¶'] +['éĢĻ', '種'] +['建çŃij', 'éĿ¢ç§¯'] +['ç¡®', 'ç«ĭ'] +['管çIJĨ', 'åĬŀæ³ķ'] +['æĦı', 'å¿Ĺ'] +['ä¸', '¨'] +['让', 'åŃ©åŃIJ'] +['æķij', 'çģ¾'] +['å½ĵ', 'ä»Ĭ'] +['çģ«', 'çģ¾'] +['åIJĦ', 'éĥ¨éŨ'] +['ä¾µ', 'çĬ¯'] +['æ¯ı', 'åij¨'] +['æı', '½'] +['ä¸Ģ次', 'æĢ§'] +['åħ¶ä»ĸ', '人'] +['éĶĻ', 'è¿ĩ'] +['ä¸İ', 'åħ¶'] +['åĭĩ', 'æ°Ķ'] +['çĩĥ', 'æ°Ķ'] +['é¦ĸ', 'å±Ĭ'] +['æľį', '饰'] +['ç²', '¥'] +['å®Į', 'æ¯ķ'] +['å°±', 'æĬĬ'] +['åĬŀäºĭ', 'å¤Ħ'] +['ä¸Ģä¼ļ', 'åĦ¿'] +['离', 'ä¸įå¼Ģ'] +['å¦Ĥæŀľ', 'æĤ¨'] +['ä»ĵ', 'åºĵ'] +['导', 'å¸Ī'] +['åIJĪéĢĤ', 'çļĦ'] +['毫', 'ç±³'] +['å®īåħ¨', 'æĢ§'] +['ä¾Ŀ', 'çħ§'] +['产ä¸ļ', 'åĮĸ'] +['ä½ł', 'çľĭ'] +['羣çļĦ', 'å¾Ī'] +['åѤ', 'çĭ¬'] +['éĺ²', '御'] +['å¾Ī', 'ç®Ģåįķ'] +['é£İ', 'æ°´'] +['ä½Ĩ', 'ä¹Ł'] +['æİ¨', 'åĩºäºĨ'] +['æ°ijèIJ¥', 'ä¼ģä¸ļ'] +['çłģ', '头'] +['å¤įæĿĤ', 'çļĦ'] +['ç»ĦæĪIJ', 'éĥ¨åĪĨ'] +['åħħ满', 'äºĨ'] +['è¿ij', 'åĩłå¹´'] +['çľģ', 'æĶ¿åºľ'] +['æľī', 'å¿ħè¦ģ'] +['éĻ', '³'] +['ä¹ĭ', 'ç±»'] +['ä¹ĭç±»', 'çļĦ'] +['æĢ§', 'ä»·'] +['æĢ§ä»·', 'æ¯Ķ'] +['åķĨ', 'åºĹ'] +['å¸Ĥ', 'å̼'] +['人æīį', 'åŁ¹åħ»'] +['æ·±', 'åıĹ'] +['管çIJĨ', 'å±Ģ'] +['æģIJ', 'æĥ§'] +['ä»ħ', 'æľī'] +['æĬµ', 'è¾¾'] +['æµ·', 'åħ³'] +['èµĭ', 'äºĪ'] +['äºĭ', 'åĦ¿'] +['ä»·', 'éĴ±'] +['æīĭ', 'ä¸Ĭ'] +['èĩª', 'å¾ĭ'] +['åħ³', 'çα'] +['享', 'æľī'] +['éģĹ', 'æĨ¾'] +['å¾Īå¿«', 'å°±'] +['æĽ´', 'å¿«'] +['æłĩ', 'è¯Ĩ'] +['åºĨ', 'ç¥Ŀ'] +['ä¹Ł', '好'] +['ä¸į', 'æĺĵ'] +['æĪij', 'å¾Ī'] +['æĶ¹éĿ©', 'åıijå±ķ'] +['å¤ĸ', 'åľ°'] +['æĬµ', 'æĬ¼'] +['è¯Ĺ', '人'] +['åİķ', 'æīĢ'] +['æĸ°', 'åªĴä½ĵ'] +['èĸ', 'Ľ'] +['è°Ī', 'è¯Ŀ'] +['ä¸Ģå®ļ', 'ç¨ĭ度'] +['èµ°', 'åľ¨'] +['æľĢ', '强'] +['åĬŁ', 'çİĩ'] +['åħ±', 'è¯Ĩ'] +['大', 'æ¡¥'] +['ä¸ĭ', 'æĸ¹'] +['å¤ĸ', 'èµĦ'] +['ç¢', '±'] +['å·¡', 'è§Ĩ'] +['æ¹ĸåĮĹ', 'çľģ'] +['个', 'çϾåĪĨ'] +['个çϾåĪĨ', 'çĤ¹'] +['çļĦ', '责任'] +['çļĦ', 'åĵģçīĮ'] +['åĬ©', 'æİ¨'] +['åĪĽéĢł', 'äºĨ'] +['ä»»', 'èģĮ'] +['å¿«', 'æį·'] +['æĿij', 'åºĦ'] +['åİ»', 'çľĭ'] +['æīį', 'èĥ½å¤Ł'] +['å±', '¤'] +['æĪij', 'å®¶'] +['æĺ¯ä¸Ģ', '款'] +['ç¾', 'ħ'] +['åĨ°', 'éĽª'] +['æŀģ', '大'] +['çģ¯', 'åħī'] +['éĨ', 'ĭ'] +['ä¸İ', 'åħ¶ä»ĸ'] +['æıIJåĩº', 'çļĦ'] +['éĿł', 'è¿ij'] +['è°ĥ', 'åĬ¨'] +['å°½', 'åı¯èĥ½'] +['åıij', 'åĬĽ'] +['ç»Ļ', '她'] +['éĢĤ', 'éĩı'] +['è·¨', 'åĽ½'] +['åħĪ', 'è¡Į'] +['æĸ°', 'æĿIJæĸĻ'] +['ä½ľ', 'äºĨ'] +['满', 'äºĨ'] +['ä¸į', '满'] +['çļĦçľ¼', 'çĿĽ'] +['çľĭ', 'å¾Ĺ'] +['è¿Ļ', 'ä¸Ģ次'] +['é½IJ', 'åħ¨'] +['çļĦä¸Ģ', 'éĥ¨åĪĨ'] +['ä¸', 'Ļ'] +['æ¸ħ', 'æĸ°'] +['說', 'æĺİ'] +['身边', 'çļĦ'] +['æīĢæľī', '人'] +['å½°', 'æĺ¾'] +['è±', '¹'] +['åį', '¿'] +['è¿IJ', '转'] +['æĮĩ', 'å¼ķ'] +['å¸Ĥ', 'åħ¬å®īå±Ģ'] +['åıĤ', 'å±ķ'] +['ä¹ĭ', 'æĹ¶'] +['éĩijèŀį', 'æľįåĬ¡'] +['èµĦæľ¬', 'å¸Ĥåľº'] +['èĥ½', '让'] +['å¿ĺ', 'äºĨ'] +['天', 'åłĤ'] +['æ¯Ķå¦Ĥ', '说'] +['éĬĢ', 'è¡Į'] +['èĽĭ', 'ç³ķ'] +['çĶ', '©'] +['æł¸', 'å®ŀ'] +['æĻ®', '京'] +['ä¼ĺ', 'ç¾İ'] +['åı£', 'èħĶ'] +['漫', 'çĶ»'] +['çľ¼', 'éĩĮ'] +['äºĨ', 'ä¸ĭæĿ¥'] +['æĪij们', 'ä¹Ł'] +['ä¾', 'į'] +['为', 'ä¸Ńå¿ĥ'] +['å¥ĩ', '迹'] +['éĿĴ', 'çĿIJ'] +['æĪªèĩ³', '缮åīį'] +['åĩº', 'ä¾Ĩ'] +['æĢ»', 'åħ¬åı¸'] +['å¼¥', 'è¡¥'] +['ç®Ĺ', 'æ³ķ'] +['å·¥ä½ľ', '室'] +['æīĢ以', 'æĪij'] +['æ°´', 'åĪĨ'] +['æīĢ', 'å±ŀ'] +['ä¸į', '说'] +['ä½Ĩæĺ¯', 'åľ¨'] +['è¦ģ', 'åİ»'] +['åĪĽä¸ļ', 'èĢħ'] +['ä¸į', 'æ¸ħæ¥ļ'] +['åĽĽ', 'åij¨'] +['æĺ¯', 'ä»İ'] +['çļĦ', 'æł¹æľ¬'] +['çģ', '¶'] +['æ¯Ľ', 'æ³½'] +['æ¯Ľæ³½', '举'] +['æµ·', 'åı£'] +['åĽĽ', 'åįģ'] +['ä¹Ł', '被'] +['èģ', '·'] +['ä¸Ģ', 'æīĭ'] +['绩', 'æķĪ'] +['çļĦ', 'çĶ·äºº'] +['书', 'ç±į'] +['ä¸Ģ', 'èĦ¸'] +['大', 'äºİ'] +['鼶', 'éĥ¨ä»¶'] +['åħ³', 'æĢĢ'] +['å¹³', 'ç±³'] +['æļ´', 'éľ²'] +['å¾Ĺ', 'å¤ļ'] +['ä¸ī', '级'] +['æľ¬', 'åij¨'] +['两', 'èĢħ'] +['对', 'ä¸ŃåĽ½'] +['åıª', 'è§ģ'] +['欧', 'ç¾İ'] +['å¦Ĥæŀľ', 'æľī'] +['å·²ç»ı', 'æĺ¯'] +['çľĭ', 'å®Į'] +['çģ«', 'éĶħ'] +['èµ', 'IJ'] +['ä¸Ģ', 'éģį'] +['æĦŁ', 'åĨĴ'] +['ç»ĵ', 'å±Ģ'] +['ä»ĵ', 'åĤ¨'] +['å®ŀ', 'åľ°'] +['å̻', 'ç»ıçIJĨ'] +['ä¹Łä¸į', 'çŁ¥éģĵ'] +['碰', 'åΰ'] +['åIJĪ', '计'] +['客æĪ·', 'çļĦ'] +['ç½Ĺ', '马'] +['æĦī', 'å¿«'] +['é£', 'Ľ'] +['çĥŃ', 'çĥĪ'] +['伦', 'æķ¦'] +['åĮ»', 'ä¿Ŀ'] +['éĺ¿éĩĮ', 'å·´å·´'] +['åĨį', '说'] +['为', 'åŁºç¡Ģ'] +['çĶŁäº§', 'ç»ıèIJ¥'] +['è¿ĻäºĽ', '人'] +['åĪĹ', '车'] +['æ²³åĮĹ', 'çľģ'] +['è¿Ļ', '段'] +['æ´»åĬ¨', 'ä¸Ń'] +['å©', '·'] +['çĶŁ', 'çIJĨ'] +['ä¸ŃåĽ½', '人æ°ij'] +['éĦ', 'Ĥ'] +['åIJ¬', 'åıĸ'] +['å¤į', 'ä¹ł'] +['æľī', 'çĽĬ'] +['æĶ¶', 'æĭ¾'] +['å¾Ī', 'åı¯èĥ½'] +['ç½ij绾', '游æĪı'] +['们', 'çļĦ'] +['èµĭ', 'èĥ½'] +['éļ¾', 'å¾Ĺ'] +['åĪĨ', 'æīĭ'] +['羣', 'è¯ļ'] +['åħ¬åı¸', 'åľ¨'] +['åĿĩ', 'è¡¡'] +['åı£', 'åij³'] +['çīµ', '头'] +['ä¸Ģèά', 'çļĦ'] +['轿', '车'] +['çŃī', 'äºİ'] +['æ²ī', 'é»ĺ'] +['æĪij', 'éĥ½'] +['å°ı', 'ç¨ĭåºı'] +['ä¸Ģ', 'åī¯'] +['æī¿', 'è½½'] +['åľ°', 'è´¨'] +['çķĮ', 'éĿ¢'] +['ç͵', 'æľº'] +['çĦ¦', 'èĻij'] +['éĶĢåĶ®', 'é¢Ŀ'] +['æĸ°', '车'] +['ä¸Ĭ', '游'] +['主', 'æ¼Ķ'] +['éļIJ', 'ç§ģ'] +['åıijå±ķ', 'æĪĺçķ¥'] +['çļĦ', 'åĬªåĬĽ'] +['å¼Ģ', 'åħ³'] +['è§£åĨ³', 'éĹ®é¢ĺ'] +['çĿ£', '导'] +['对', 'æĬĹ'] +['å¾Īå¤ļ', '人éĥ½'] +['æĹł', 'æķĪ'] +['产åĵģ', 'è´¨éĩı'] +['å®ī', 'å¿ĥ'] +['åįİ', '人'] +['ä¸į', '符åIJĪ'] +['èĩª', 'å®¶'] +['éĺµ', '容'] +['çļĦ', 'åIJĦç§į'] +['çļĦ', 'çIJĨ念'] +['çļĦ', 'æĸĩåĮĸ'] +['为', 'èĩªå·±'] +['å±±', 'æ°´'] +['游', 'æ³³'] +['éľĩ', 'èį¡'] +['çĶŁæ´»', 'æĸ¹å¼ı'] +['è¿ľ', '离'] +['çŁ³', 'åĮĸ'] +['æŃ¤', 'äºĭ'] +['æĺ¯', '羣çļĦ'] +['çļĦ', 'æ¯Ķä¾ĭ'] +['ç͍', 'ç͵'] +['奥è¿IJ', 'ä¼ļ'] +['ä¿Ŀ', 'å®ī'] +['èĽĭçϽ', 'è´¨'] +['çļĦ', 'å¿ĥçIJĨ'] +['å·', '«'] +['åı·', 'çłģ'] +['æ°Ķ', 'ä½ĵ'] +['åıij', 'æĶ¹'] +['åıijæĶ¹', 'å§Ķ'] +['åĮ»', 'å¸Ī'] +['æ¶Ĥ', 'æĸĻ'] +['æĺ', 'Ĭ'] +['å¸Ĥ', '级'] +['ä¸ĸçķĮ', 'çļĦ'] +['åĪĨåĪ«', 'æĺ¯'] +['çł´', '产'] +['ä¸Ģ', 'æĿ¯'] +['æĭī', 'å¼Ģ'] +['å¹³', 'åĩ¡'] +['çļĦ', 'åıijçĶŁ'] +['åĬ¨', 'æīĭ'] +['ä¸Ģ缴', '以æĿ¥'] +['æīĭ', 'å·¥'] +['éĩĮéĿ¢', 'çļĦ'] +['æĹł', 'åħ³'] +['ä»ĭ', 'åħ¥'] +['èµ°', 'ä¸Ĭ'] +['å°±æĺ¯', 'è¦ģ'] +['å¹´', 'éĹ´'] +['åĩº', 'çı¾'] +['å½±', 'éŁ¿'] +['å¹ħ', '度'] +['éĽ', 'ģ'] +['éģĵ', 'åħ·'] +['缮çļĦ', 'åľ°'] +['åIJİ', 'èĢħ'] +['ä¸Ĭ', 'æ¼Ķ'] +['äºĨ', 'åĩł'] +['æ®ĭçĸ¾', '人'] +['å¿Ļ', 'ç¢Į'] +['æĺ¯åIJ¦', 'æľī'] +['å¹¶', '对'] +['ä¼ļ', '导èĩ´'] +['æ°´', 'åºĵ'] +['ç»Ĩ', 'èĩ´'] +['åIJİ', 'æĤĶ'] +['å¿ĥ', 'æĢĿ'] +['åģļ', 'äºĭ'] +['åİĤ', 'æĪ¿'] +['çĿ', '¿'] +['è¿IJèIJ¥', 'åķĨ'] +['头', 'éĥ¨'] +['çļĦ', 'è§Ĵèī²'] +['æĺ¯', 'ä»ĸ'] +['æĹ¢', 'æľī'] +['å°ıæĹ¶', 'åĢĻ'] +['强', 'åĬ²'] +['主', 'æĴŃ'] +['åħ¨åĽ½', 'åIJĦåľ°'] +['æį', 'ı'] +['æįŁ', 'åĿı'] +['åķĨ', 'ä¼ļ'] +['ä¿Ŀ', 'ç½Ĺ'] +['çľģ', 'å¸Ĥ'] +['éļ§', 'éģĵ'] +['æľī', 'ä¸įå°ij'] +['è¦ģ', 'åľ¨'] +['建设', 'é¡¹çĽ®'] +['ç³ĸ', 'å°¿'] +['ç³ĸå°¿', 'çĹħ'] +['æĿ¡ä»¶', 'ä¸ĭ'] +['ä¼ĺè´¨', 'çļĦ'] +['é¦ĸ', 'åıij'] +['å½ĵæĹ¶', 'çļĦ'] +['丰', 'çͰ'] +['大', 'çĽĺ'] +['缸', 'ç»§'] +['å®ģ', 'å¤ı'] +['åħ¥', 'ä½ı'] +['æĪij', 'è¿ĺ'] +['åħĭ', 'æĸ¯'] +['å®ļ', 'ä»·'] +['å¹³æĸ¹', 'åħ¬éĩĮ'] +['çļĦ', 'çŁ¥è¯Ĩ'] +['æĪij们', 'ä¼ļ'] +['åħĥ', 'å®Ŀ'] +['ä½ĵ', 'éĩį'] +['è³', '£'] +['对', 'æĪij们'] +['çŁ³', 'å®¶'] +['çŁ³å®¶', 'åºĦ'] +['ç²¾', 'åįİ'] +['å½¢', 'çĬ¶'] +['åıĹ', 'åΰäºĨ'] +['ä¿®', '订'] +['ç¾İ', 'åľĭ'] +['é«ĺ', 'æ¸ħ'] +['çľ¼', 'éķľ'] +['è§īå¾Ĺ', 'èĩªå·±'] +['带', 'ç»Ļ'] +['åĶ®', 'ä»·'] +['éŨ', '票'] +['åŃķ', 'å¦ĩ'] +['ç͵è§Ĩ', 'åı°'] +['åıij', 'ä½ľ'] +['çļĦ', 'åij³éģĵ'] +['éķ¿', 'è¿ľ'] +['åħ¬åħ±', 'æľįåĬ¡'] +['æŃ£å¸¸', 'çļĦ'] +['æľī', 'è¿ĩ'] +['é£İ', 'æĥħ'] +['æ¯Ķ', 'éĩį'] +['åIJ', '»'] +['管çIJĨ', 'å·¥ä½ľ'] +['综åIJĪ', 'æĢ§'] +['å·²', '被'] +['说', 'èµ·'] +['æİĴ', 'æ°´'] +['ä¸įæĸŃ', 'åľ°'] +['æĥħ', 'æĢĢ'] +['è¾ĵ', 'éĢģ'] +['è¿ĩ', 'æķı'] +['çļĦ', 'åı¯èĥ½æĢ§'] +['æľį', 'ç͍'] +['æľī', '许å¤ļ'] +['å§Ķ', 'åī¯ä¹¦è®°'] +['åĮĸå¦Ĩ', 'åĵģ'] +['æļĤ', 'åģľ'] +['æĬķèµĦ', '人'] +['çıŃ', '级'] +['说', 'çĿĢ'] +['åįĹ', 'åĮĹ'] +['åĪĨ', 'è¡Į'] +['çıł', 'å®Ŀ'] +['å¯', '¶'] +['å¢ŀ', 'å¤ļ'] +['被', 'åĬ¨'] +['ç®Ĭ', 'çļĦ'] +['éĹľ', 'ä¿Ĥ'] +['çļĦ', 'èĦ¸'] +['æĥ', 'Ł'] +['ä¸į', 'ä¸Ģå®ļ'] +['ç¶', 'Ń'] +['çģ«', 'çĪĨ'] +['ç§Ł', 'éĩij'] +['çŀ', '§'] +['éĩį', '建'] +['è·', 'ª'] +['ä¸Ģ', '種'] +['çļĦ', 'åIJĪä½ľ'] +['å®ī', 'æħ°'] +['ä»į', 'æĺ¯'] +['ä¸ĵä¸ļ', 'åĮĸ'] +['è°ĥ', 'è§£'] +['ä¸į', '妨'] +['éĢĻ', 'æĺ¯'] +['å¿ħ', 'éłĪ'] +['ä¼Ĭ', 'æľĹ'] +['å¾Ĺ', 'äºĨ'] +['æľįåĬ¡', 'å¹³åı°'] +['å§', '¬'] +['åħĪ', 'éĶĭ'] +['çİĭ', 'åŃIJ'] +['çļĦä¸Ģ', 'åĪĩ'] +['æĢ»', 'çIJĨ'] +['åĵ', '¼'] +['çª', 'ij'] +['çļĦå¿ĥ', 'æĥħ'] +['çļĦ', 'éĩį大'] +['çij', 'Ł'] +['ä¸Ģ', 'ç¬ij'] +['åıijå±ķ', 'ä¸Ń'] +['åģ¥åº·', 'åıijå±ķ'] +['åĵģçīĮ', 'çļĦ'] +['ç¦', '®'] +['ä½Ļ', '人'] +['ä»Ĭå¹´', '以æĿ¥'] +['æķ°', 'çłģ'] +['çѾ', 'è¯ģ'] +['åİ»', 'æī¾'] +['åŁºéĩij', 'ä¼ļ'] +['æĬ±', 'æĢ¨'] +['æŃ£', 'å½ĵ'] +['çıŃåŃIJ', 'æĪIJåijĺ'] +['ä¸į', 'åIJĪæł¼'] +['åζ', 'å®ļäºĨ'] +['ç¼ĵ', 'æħ¢'] +['åζ', '约'] +['æłı', '缮'] +['å¸Ĥåľº', 'ç»ıæµİ'] +['ç»ĦæĪIJ', 'çļĦ'] +['严', 'å³»'] +['æĹ¥', '讯'] +['ä¸ĢçĤ¹', 'çĤ¹'] +['æĺ¯', 'æĢİä¹Ī'] +['çļĦ', 'çħ§çīĩ'] +['éĺ»', 'æŃ¢'] +['模', 'ç³Ĭ'] +['ç¼', '¸'] +['éģķ', 'åıį'] +['æIJ¬', 'è¿ģ'] +['éĩij', 'éĴ±'] +['å½', '¬'] +['ä¸į', 'å®ī'] +['æĪĺçķ¥', 'åIJĪä½ľ'] +['å¡«', 'åĨĻ'] +['讲', 'ç©¶'] +['åħħåĪĨ', 'åĪ©ç͍'] +['èĥ½', 'å¤ł'] +['èij¡èIJĦ', 'éħĴ'] +['éĩĩç͍', 'äºĨ'] +['åľ¨', 'ä»Ĭå¹´'] +['ä¸Ńå°ı', 'åѦ'] +['åľ¨', 'æĦı'] +['çļĦ', 'åİĭåĬĽ'] +['ä¸į', '幸'] +['åζ', 'èį¯'] +['åı¯ä»¥', '让'] +['被', 'è¯Ħ为'] +['ç»Ĩ', 'èıĮ'] +['æĪı', 'åī§'] +['åįĬ', '导'] +['åįĬ导', 'ä½ĵ'] +['è§Ĩ', 'è§Ĵ'] +['åĸľ', 'æŃ¡'] +['å¾ģ', 'æĶ¶'] +['è°ĭ', 'åĪĴ'] +['æŀģ', '大çļĦ'] +['çĤ¹', 'èµŀ'] +['è®°èĢħ', 'ä»İ'] +['两', 'åIJį'] +['èĩª', 'åĬ©'] +['èµ·', 'æŃ¥'] +['æĬ¤', '士'] +['å®Ŀ', '马'] +['太', 'åŃIJ'] +['å°ıå°ı', 'çļĦ'] +['温', 'æ³ī'] +['åĩºç§Ł', '车'] +['ç§Ł', 'æĪ¿'] +['两', 'å®¶'] +['éľĩ', 'æĴ¼'] +['ç§ī', 'æī¿'] +['ä¸Ģä»¶', 'äºĭ'] +['çĥĪ', '士'] +['å®ĺ', 'åħµ'] +['转', '身'] +['ä¹IJ', 'åĽŃ'] +['çĻĮ', 'çĹĩ'] +['模', 'èĮĥ'] +['æĦ', '£'] +['è¿ĩåİ»', 'çļĦ'] +['代', 'ä»·'] +['çļĦ', 'æ¦Ĥ念'] +['åĩł', 'çϾ'] +['è´µ', 'éĺ³'] +['æĭħ', 'å¿§'] +['éĢĤ', 'å®ľ'] +['çݯå¢ĥ', 'ä¿ĿæĬ¤'] +['çĥ', '«'] +['ä½ł', 'æĥ³'] +['æŃ¤', 'åIJİ'] +['ä½ł', 'ä¹Ł'] +['çį', 'İ'] +['éϤ', 'æŃ¤'] +['éϤæŃ¤', 'ä¹ĭå¤ĸ'] +['è°ĥ', '度'] +['ç§ij', '缮'] +['æīĢ说', 'çļĦ'] +['åĬ', 'ĩ'] +['忽', 'è§Ĩ'] +['ä¸ī', '次'] +['ä¸Ģ', 'æĹ¥'] +['åŀĤ', '缴'] +['ç«ŀ', 'æĬĢ'] +['éĿ¢', 'åĮħ'] +['大', 'æĪĺ'] +['æIJº', '带'] +['å¦Ĥæŀľ', '没æľī'] +['åħ»', 'æĪIJ'] +['åĩº', 'è¡Ģ'] +['çα好', 'èĢħ'] +['æīĵ', 'éĢļ'] +['èµ·', 'è¯ī'] +['åijĪ', 'çݰåĩº'] +['æŃĮ', 'æīĭ'] +['åľ¨', 'å¤ĸ'] +['é¢Ĩ导', 'å¹²éĥ¨'] +['åĨ', '¥'] +['èĪĨ', '论'] +['æıIJ', 'åıĸ'] +['éĺ¿', 'å°Ķ'] +['æľĽ', 'çĿĢ'] +['ä¸ī', 'äºļ'] +['è²', '¡'] +['åĪ', '·æĸ°'] +['æĻļ', 'æĬ¥'] +['è¿ĺæľī', 'ä¸Ģ个'] +['åĨ°', 'ç®±'] +['ç½ij', 'çĤ¹'] +['åĩº', 'åħ·'] +['强çĥĪ', 'çļĦ'] +['æĪij', 'çĽ¸ä¿¡'] +['å¸ĮæľĽ', 'èĥ½'] +['çīĻ', '齿'] +['äºĭ', 'å®ľ'] +['ä¸ļåĨħ', '人士'] +['代', 'æĽ¿'] +['åıĺ', 'å½¢'] +['éĽ', '²'] +['è°ĥ', 'æİ§'] +['åĪĽæĸ°', 'åĪĽä¸ļ'] +['æĭĨ', 'è¿ģ'] +['æł¸', 'æŁ¥'] +['éĢ', 'Ĺ'] +['åħ¥', 'åѦ'] +['æĦı', 'åIJij'] +['æı', 'Ľ'] +['ä¸ĭ', '次'] +['ä¼ł', 'è¾ĵ'] +['ä»ĸ们', 'åľ¨'] +['èĢĮä¸Ķ', 'è¿ĺ'] +['æĹ¥', 'åľ¨'] +['æķĻ', 'è®Ń'] +['æ´»', 'çĿĢ'] +['çļĦ', 'æľīæķĪ'] +['å¤įå·¥', 'å¤į'] +['å¤įå·¥å¤į', '产'] +['æĺ¯ä¸Ģ', 'ä»¶'] +['çŃī', 'çĿĢ'] +['å¾', '©'] +['åĭĩ', 'æķ¢'] +['éģŃ', 'åıĹ'] +['å¥Ķ', 'é©°'] +['讲', '座'] +['说', 'å®Į'] +['ç»Ļ', 'åĩº'] +['è°', '¦'] +['è¯Ĭ', 'çĸĹ'] +['çĽ²', '缮'] +['客', 'è¿IJ'] +['å°±', 'è¿ŀ'] +['å¼Ģ', 'åħĥ'] +['å¼Ģåħĥ', 'æ£ĭçīĮ'] +['ä¸įæĸŃ', 'æıIJåįĩ'] +['ç͍æĪ·', 'çļĦ'] +['æĴ', 'ķ'] +['ä¾Ľ', 'æ°´'] +['ç¶ĵ', 'æ¿Ł'] +['ä¸Ń', 'åĮ»èį¯'] +['èģĶ', 'æĥ³'] +['åħ¬äº¤', '车'] +['èĪª', 'çıŃ'] +['æĬĢ', 'è¡ĵ'] +['å¼ķèµ·', 'çļĦ'] +['å°', '¹'] +['èµĦ', 'æ·±'] +['åĽ½èµĦ', 'å§Ķ'] +['èĺ', 'Ń'] +['é¼»', 'åŃIJ'] +['éĹ', '½'] +['æİĴ', 'éĺŁ'] +['è§Ĥ', 'åħī'] +['éģĹ', 'åĿĢ'] +['举', '京'] +['é¥Ń', 'åºĹ'] +['ä¸įæĸŃ', 'çļĦ'] +['å°±æĺ¯', 'ä¸Ģ个'] +['éķ¿', 'ä¹ħ'] +['çļĦ', 'è§ĤçĤ¹'] +['å¨', '¶'] +['æĪij', 'çİ°åľ¨'] +['çķ', '°'] +['å¾Ĺ', 'åĩº'] +['å¿ħ', 'å®ļ'] +['ä¸į', 'åıĹ'] +['åıª', 'éľĢè¦ģ'] +['åĽ°', 'æī°'] +['ç§ijåѦ', 'æĬĢæľ¯'] +['çīĽ', 'èĤī'] +['è¾ĥ', 'é«ĺçļĦ'] +['è·ij', 'æŃ¥'] +['æ²', '¾'] +['èı©', 'èIJ¨'] +['æľĢ', 'å¾Į'] +['ä¿Ŀ', 'å¯Ĩ'] +['æ²»', 'å®ī'] +['éĤ', '±'] +['常', 'è¯Ĩ'] +['èĦ¸', 'èī²'] +['åĮĹ', '大'] +['æ±ĩ', 'èģļ'] +['æijĨ', 'èĦ±'] +['é¾Ļ头', 'ä¼ģä¸ļ'] +['女', 'åıĭ'] +['çŃī', 'å·¥ä½ľ'] +['ä¸Ń', 'ç¾İ'] +['èģĮ', 'åľº'] +['èĦij', 'è¢ĭ'] +['åĨĻ', 'çļĦ'] +['饲', 'æĸĻ'] +['åĬ³', 'åĬ¨åĬĽ'] +['å±', '¯'] +['æĮģ', 'èĤ¡'] +['åĽ¾', 'åĥı'] +['è¿ĩåİ»', 'äºĨ'] +['è²', '¨'] +['è¾', '²'] +['éĹ®', 'æĪij'] +['è·Ł', 'ä½ł'] +['çĶŁ', 'æŃ»'] +['审', 'ç¾İ'] +['é¢Ĺ', 'ç²Ĵ'] +['ä¸Ń', 'æĸ¹'] +['åĬł', 'çĥŃ'] +['æĹħè¡Į', '社'] +['çϼ', 'çĶŁ'] +['ä¸į', 'åłª'] +['åĤ', '·'] +['æ¥', 'ł'] +['åĬŀ', 'æ¡Ī'] +['æŁ', 'Ħ'] +['æĹ¢', 'æĺ¯'] +['å¤Ħ', 'åĪĨ'] +['羣å®ŀ', 'çļĦ'] +['æĬ¥', '纸'] +['å¸Ī', 'çζ'] +['å®īå¾½', 'çľģ'] +['åī¯', '主å¸Ń'] +['ä¹ĭ', 'éģĵ'] +['导', 'å¼¹'] +['åŃ¦æł¡', 'çļĦ'] +['åŁİå¸Ĥ', 'çļĦ'] +['è°Ī', 'åΰ'] +['æ¢', 'Ĺ'] +['å¹³', 'éĿ¢'] +['说', 'ä»Ģä¹Ī'] +['é¢ij', 'çİĩ'] +['éķ¿', 'ä¸īè§Ĵ'] +['çļĦ', 'åĪ©çĽĬ'] +['é»', '¨'] +['è±Ĩ', 'èħIJ'] +['å®ŀéĻħ', 'æĥħåĨµ'] +['æŀĹ', 'ä¸ļ'] +['纪æ£Ģ', 'çĽijå¯Ł'] +['ä½ı', 'éĻ¢'] +['çļĦ', 'æķ´ä½ĵ'] +['åīį', 'è¡Į'] +['æĮ', '¨'] +['çħ¤', 'çŁ¿'] +['å̻', 'è£ģ'] +['å°ı', 'åIJĥ'] +['æŀģ', '端'] +['å©Ĩ', 'å©Ĩ'] +['çݰ', 'è´§'] +['è¯Ĺ', 'æŃĮ'] +['éĴ¥', 'åĮĻ'] +['缩', 'çŁŃ'] +['ä½Ĩ', 'è¿Ļ'] +['æĸ°', 'åĵģ'] +['è¿Ļ', '对'] +['çŁ¥åIJį', '度'] +['å¿ĹæĦ¿', 'æľįåĬ¡'] +['大', 'å±Ģ'] +['è¡¡', 'éĩı'] +['ä½ĵçݰ', 'äºĨ'] +['æ¡ĥ', 'èĬ±'] +['åIJ¸å¼ķ', 'åĬĽ'] +['åł', '¤'] +['æĵħ', 'éķ¿'] +['åĴ', 'Ĵ'] +['缸', 'æľº'] +['ä¸Ģ', 'ç«Ļ'] +['ä¸Ģç«Ļ', 'å¼ı'] +['æľĢ', 'ç¾İ'] +['æ°¸', 'ä¹ħ'] +['çļĦ', 'éĥ¨åĪĨ'] +['åĪĨ', 'å·¥'] +['å·¥ç¨ĭ', '建设'] +['æIJŃ', 'è½½'] +['æ°´', 'ä¸Ń'] +['èĮ', '¨'] +['çļĦ', 'æĵįä½ľ'] +['绣', 'æ²»'] +['çķħ', 'éĢļ'] +['åħļçļĦ', 'åįģ'] +['è¼', '¸'] +['æ¸', '¬'] +['ç¾İ', 'è§Ĥ'] +['ä¸į', 'åĪ©'] +['åıį', 'æĢĿ'] +['éªĦ', 'åĤ²'] +['æłĩ', 'çļĦ'] +['æĿĢ', '人'] +['éĺ¿', '姨'] +['é£Ł', 'æĿIJ'] +['åIJĥ', 'çļĦ'] +['åIJİ', 'åĨį'] +['çŁ', '£'] +['两', 'ä¾§'] +['æ¸ħ', 'æ°´'] +['è¿Ľ', 'çIJĥ'] +['å¼Ģå§ĭ', 'äºĨ'] +['åIJ¬', 'äºĨ'] +['çĦĬ', 'æİ¥'] +['çŁ', '®'] +['å¨', 'Ł'] +['为', '人'] +['éĢģ', 'ç»Ļ'] +['åĨĴ', 'éĻ©'] +['æķ', '·'] +['ç»Ī', 'æŃ¢'] +['æīį', 'çŁ¥éģĵ'] +['è¿IJ', 'æ°Ķ'] +['éĢļ', 'é£İ'] +['æĥĬ', 'è®¶'] +['ç§ijåѦ', 'éĻ¢'] +['æıIJ', 'éĹ®'] +['太', 'åİŁ'] +['缸åIJĮ', 'çļĦ'] +['ä»', 'ķ'] +['èģ', 'ĸ'] +['æĥħ', 'æ³ģ'] +['é¢Ĩ导', '人'] +['åĩºæĿ¥', 'äºĨ'] +['沿', '线'] +['éĻ', '½'] +['æĦŁ', '覺'] +['ä»į', 'åľ¨'] +['æ©', 'Ļ'] +['约', '为'] +['åĸĿ', 'éħĴ'] +['ç͍', 'èį¯'] +['ä¸ĭ', 'ä¸Ģ'] +['æ³ķ', 'å®ĺ'] +['顺', 'åºı'] +['åģļ', 'ä¸Ģ个'] +['åĭ', '¢'] +['æŃ', 'ª'] +['ç͵', 'ç«ŀ'] +['ä¼´', 'éļıçĿĢ'] +['ä¹ĭ', 'åĬĽ'] +['ä¹ĭ', '人'] +['äºij', '计ç®Ĺ'] +['åĪ«äºº', 'çļĦ'] +['ç§ijåѦ', 'åıijå±ķ'] +['第', 'åħ«'] +['å¹²', 'æī°'] +['女', 'ç¥ŀ'] +['è¿Ļæł·', 'åģļ'] +['å¤Ħ', 'åľ¨'] +['æ°´', 'è´¨'] +['éķ¿', 'æĺ¥'] +['å¸Ĥåľº', 'éľĢæ±Ĥ'] +['ç»´', 'æĿĥ'] +['è̳', 'æľµ'] +['æĸĩåĮĸ', 'çļĦ'] +['奶', 'ç²ī'] +['ä¼ł', 'è¾¾'] +['æīĭæľº', 'çīĪ'] +['æĽ¾', 'åľ¨'] +['äºĮ', 'æľŁ'] +['åİŁåĽł', 'æĺ¯'] +['æºIJ', '头'] +['åıĪ', 'èĥ½'] +['è£', '¸'] +['æĬĢæľ¯', 'åĪĽæĸ°'] +['æĸĩåĮĸ', 'æĹħ游'] +['åıij', '票'] +['å¹´', '级'] +['ä½ł', 'ä¸į'] +['ä¹ĭ', 'å¿ĥ'] +['æķ°', 'çϾ'] +['åIJij', 'å¾Ģ'] +['èĢģ', 'å®¶'] +['åľĭ', 'éļĽ'] +['çļĦ', 'é«ĺ度'] +['æľĿ', 'éĺ³'] +['æ¸ħ', 'éϤ'] +['èĩª', 'æľī'] +['书', 'ä¸Ń'] +['游æĪı', 'è£ħå¤ĩ'] +['ä¸ĩ', 'å¤ļ'] +['驾驶', 'åijĺ'] +['ä½ł', 'çŁ¥éģĵ'] +['åĽ½', 'åºĨ'] +['é£Ł', 'åłĤ'] +['æİ¥', 'åı£'] +['æĢ»', 'æķ°'] +['åħ¶ä»ĸ', 'çļĦ'] +['çĶŁåij½', 'çļĦ'] +['ä½ł', 'åľ¨'] +['çļĦ', '缮åħī'] +['è¿Ļ', 'æĸ¹éĿ¢'] +['éĥ½', '说'] +['çĸĹ', 'æ³ķ'] +['åĭĩ', '士'] +['åľ¨', 'åħ¨çIJĥ'] +['ä¿ĿéĻ©', 'åħ¬åı¸'] +['çĿ£', 'æŁ¥'] +['åĸĦ', 'èī¯'] +['表', 'å½°'] +['è¹', '²'] +['è·¯', '段'] +['æľĥåĵ¡', 'è¦ı'] +['æľĥåĵ¡è¦ı', 'ç¯Ħ'] +['æĪ·', 'åŀĭ'] +['ä¿ĥ', '使'] +['ä¿®', '建'] +['é«ĺ', 'æ°´å¹³'] +['åģļ', 'åĩºäºĨ'] +['主', 'åľº'] +['è¡Į', 'èµ°'] +['空', 'çϽ'] +['æľī人', '说'] +['è¿Ļ个', 'ä¸ĸçķĮ'] +['åIJį', 'ä¹ī'] +['å®Į', 'ç¾İçļĦ'] +['羡', 'æħķ'] +['åıĬ', 'åħ¶ä»ĸ'] +['åı¯', 'ç͍'] +['æĭ', 'IJ'] +['è¾ĥ', '大çļĦ'] +['æĬĢæľ¯', 'åĴĮ'] +['å°¼', 'äºļ'] +['çϾ', 'è´§'] +['æı', 'ī'] +['éĢī', 'è´Ń'] +['éĺŁ', 'åıĭ'] +['ä¼ł', 'æĦŁ'] +['ä¼łæĦŁ', 'åύ'] +['åıªè¦ģ', 'ä½ł'] +['为ä»Ģä¹Ī', 'è¦ģ'] +['ä¸ĵ注', 'äºİ'] +['ä½Ļ', 'é¢Ŀ'] +['åħ¸åŀĭ', 'çļĦ'] +['缮åīį', 'å·²'] +['欲', 'æľĽ'] +['èģĶ', '绾'] +['æµģ', 'ä¼ł'] +['çļĦ', 'å®¶åºŃ'] +['åı·', 'åı¬'] +['çıį', 'è´µ'] +['ä¼Ł', '大çļĦ'] +['éī´', 'äºİ'] +['è·Ł', 'ä»ĸ'] +['产', 'çī©'] +['ä¸į', 'å·²'] +['è¿Ŀæ³ķ', 'è¡Į为'] +['头', 'ä¸Ĭ'] +['åĪĨ', 'è§£'] +['åı¯ä»¥', 'çľĭåĩº'] +['æł¡', 'åĮº'] +['åŃĹ', 'ä½ĵ'] +['ä¿®', 'çĤ¼'] +['çĶļèĩ³', 'æĺ¯'] +['微信', 'åħ¬ä¼Ĺ'] +['åıĸ', '代'] +['èIJ¥ä¸ļ', 'æĶ¶åħ¥'] +['æ½į', 'åĿĬ'] +['ä½ł', 'èĥ½'] +['社ä¼ļ', 'ä¿Ŀéļľ'] +['æ¯ĶèµĽ', 'ä¸Ń'] +['污水', 'å¤ĦçIJĨ'] +['夫', 'å¦ĩ'] +['ä¸Ģ', 'å¹ħ'] +['沿', 'æµ·'] +['åı£', 'æĦŁ'] +['ä½Ĩ', 'åį´'] +['å½ĵ', 'æĹ¥'] +['çļĦ', 'æľĢ大'] +['æ¯ı', 'ä¸Ģä½į'] +['没', 'äºĭ'] +['çī¹', 'åĪ¥'] +['å¼Ģ', 'åѦ'] +['è·¯', 'éĿ¢'] +['å¿ĥçIJĨ', 'åѦ'] +['æĶ¾', 'ç½®'] +['éĩįåºĨ', 'å¸Ĥ'] +['ä½ł', 'èĩªå·±'] +['æ¶Īè´¹èĢħ', 'çļĦ'] +['ä¸Ģ', 'æ³¢'] +['èѦ', 'æĥķ'] +['åį§', '室'] +['注', 'å°Ħ'] +['é£İ', '鼨'] +['沿', 'çĿĢ'] +['åijĬ', '訴'] +['表', 'çݰåĩº'] +['åĽĽ', 'æĺ¯'] +['åı¤', 'åħ¸'] +['æĽ´', 'éĩįè¦ģçļĦ'] +['好', 'äºĭ'] +['çľ¼', '泪'] +['æ¨', 'ĵ'] +['审', 'åΤ'] +['碰', 'æĴŀ'] +['车', 'ç«Ļ'] +['è¿Ľåħ¥', 'äºĨ'] +['éĽĨ', 'åIJĪ'] +['æł¼', 'å¤ĸ'] +['宾', 'é¦Ĩ'] +['æĶ¯ä»ĺ', 'å®Ŀ'] +['她', 'æĺ¯'] +['æĺ¯', 'å¦Ĥä½ķ'] +['人', '次'] +['çļĦ', 'æĪIJåĬŁ'] +['æĹł', 'åĬĽ'] +['æµ·', 'æĭĶ'] +['æĺ¥', 'åŃ£'] +['éĥ½', 'ä¸įä¼ļ'] +['çŃī', 'å¤ļç§į'] +['ä¸Ģ个', 'å°ı'] +['åģľè½¦', 'åľº'] +['让', 'æĽ´å¤ļ'] +['è¿Ļ', 'çĤ¹'] +['æĪIJ', 'åĵģ'] +['éĴ', 'ī'] +['éģĩ', 'è§ģ'] +['çıŃ', '主任'] +['æĦı', 'æĦ¿'] +['çļĦ', 'åIJĮåѦ'] +['游', 'è§Ī'] +['åİĭ', '缩'] +['åľ¨', 'ä¼łå¥ĩ'] +['å¼¹', 'æĢ§'] +['æĹ¥', 'åĨħ'] +['ç¦ı建', 'çľģ'] +['è§Ĵ', 'èIJ½'] +['åĪĨ', 'å¼Ģ'] +['ä¼ļ', '让'] +['å¤ĸ', 'åĽ´'] +['çĨŁæĤī', 'çļĦ'] +['çĨ', 'Ķ'] +['ä¸ĩ', 'è¾Ĩ'] +['å¤ľ', 'éĹ´'] +['车', '身'] +['ä¸Ń', 'æľŁ'] +['å®ĮåĸĦ', 'çļĦ'] +['åĵģ', 'ç±»'] +['åıĭ', 'è°Ĭ'] +['éĢīæĭ', 'Ķ'] +['éªij', '士'] +['å½', '¦'] +['çļĦ', 'çľĭæ³ķ'] +['åĽ½', 'çİĭ'] +['è¾£', 'æ¤Ĵ'] +['åıijå¸ĥ', 'æĹ¶éĹ´'] +['åı¤', 'åŁİ'] +['éļı', 'æľº'] +['ç«', 'ĸ'] +['å¼Ģ', 'è¾Ł'] +['ä¼Ĺ', 'çĶŁ'] +['没', 'åĬŀæ³ķ'] +['åįĥ', 'éĩĮ'] +['æĿ¥æºIJ', 'äºİ'] +['çļĦ', 'æĿĥåĪ©'] +['æ¯Ķ', 'åĪĨ'] +['满æĦı', 'çļĦ'] +['ä¿®', 'è¡Į'] +['åĿ', 'ł'] +['大', 'æµ·'] +['èİ', '¹'] +['åĩº', '身'] +['è«', 'ĩ'] +['åħ³', 'èĬĤ'] +['åIJį', '人'] +['éľĢè¦ģ', '注æĦı'] +['æĹ©', 'æĻ¨'] +['å¤ĸ', 'åįĸ'] +['åıĪ', 'è¦ģ'] +['æ¶ī', 'æ¡Ī'] +['çĶ³è¯·', '人'] +['éĻĦè¿ij', 'çļĦ'] +['åĬłå¿«', 'æİ¨è¿Ľ'] +['æĸ°', 'å¹´'] +['大', 'è¡Ĺ'] +['ä¸Ģ', 'é»ŀ'] +['èĭı', 'å®ģ'] +['æĤĦ', 'æĤĦ'] +['èĦ¾', 'æ°Ķ'] +['å¸Į', 'èħĬ'] +['éļı', 'åį³'] +['æķ¢', 'äºİ'] +['å®ŀè·µ', 'ä¸Ń'] +['æĺ¯', '没æľī'] +['æľīè¶£', 'çļĦ'] +['æĿ¥èĩª', 'äºİ'] +['è£ģ', 'åΤ'] +['女', 'åŃ©åŃIJ'] +['èĩ³', 'åħ³'] +['èĩ³åħ³', 'éĩįè¦ģ'] +['æĻº', 'åĬĽ'] +['èµ°', 'åĩºåİ»'] +['çŁŃ', 'æĿ¿'] +['大', 'åĽ½'] +['çļĦ', '认è¯Ĩ'] +['å¹´', 'å¤ľ'] +['åĨį', 'åΰ'] +['åIJĮ', 'æł·çļĦ'] +['å¯Ĩ', 'å°ģ'] +['å¤ĸ交', 'éĥ¨'] +['çĶŁ', 'æķĪ'] +['æĤ¨', 'åı¯ä»¥'] +['ä½ł', 'åĢij'] +['è¿ĩ', 'å¹´'] +['å¼', 'ĵ'] +['è¡Į', 'æĿİ'] +['æ¯Ķ', 'èµ·'] +['身', 'é«ĺ'] +['è¿Ļ个', '人'] +['ä¸Ń', 'å¤ĸ'] +['éģĵ', 'æŃī'] +['çĽ¯', 'çĿĢ'] +['亲', 'åŃIJ'] +['éĹ', '¸'] +['çϽ', 'äºij'] +['èĦĸ', 'åŃIJ'] +['ä¸ĢåĪĩ', 'éĥ½'] +['æ·', 'ij'] +['è°', 'ľ'] +['åģ¶', 'çĦ¶'] +['éĿł', 'è°±'] +['é«ĺ', '管'] +['ä¸ĭ', 'åıij'] +['æĶ¾', 'åΰ'] +['ç±»', 'åĪ«'] +['ä¸ĭ', 'åĪĹ'] +['æ··', 'ä¹±'] +['åIJĪæ³ķ', 'æĿĥçĽĬ'] +['çݯ', 'çIJĥ'] +['æľīæķĪ', 'åľ°'] +['åķĨ', 'æĪ·'] +['æ¹ĸ', '人'] +['æµ·', '岸'] +['æĬķ', '产'] +['两', '个æľĪ'] +['éĥ½', 'éĿŀ常'] +['å¢ŀ强', 'äºĨ'] +['æĿ¥', 'åΰäºĨ'] +['åī©', 'ä½Ļ'] +['æĤ¨çļĦ', 'åŃ©åŃIJ'] +['æµģ', 'æ°´'] +['æŃ£', 'ä¹ī'] +['天', 'çĮ«'] +['åģļ', 'è¿ĩ'] +['ä½ķ', 'æĹ¶'] +['æĪij', 'åİ»'] +['çľģ', '份'] +['å¥ĸ', 'éĩij'] +['该', 'å¦Ĥä½ķ'] +['ä¸ĭ', 'çıŃ'] +['åģ¶', 'åĥı'] +['æijĨ', 'æĶ¾'] +['æĸ°', '模å¼ı'] +['æĬķ', 'è³ĩ'] +['è·¯', 'åı£'] +['åĨľæ°ij', 'å·¥'] +['大', 'åѸ'] +['ä»¶', 'äºĭ'] +['æł¹æľ¬', 'ä¸į'] +['æµĵ', '度'] +['æµĵ', 'åİļ'] +['è½®', 'èĥİ'] +['æĪ¿', 'ä¼ģ'] +['éĿŀ常', '好'] +['ä»İ', 'ä¸Ń'] +['人', 'æł¼'] +['ç¿', 'ģ'] +['æĹ¶éĹ´', 'åĴĮ'] +['è¿Ļ', 'ä¸įæĺ¯'] +['åΏ', 'åķĨ'] +['æĥĬ', '人'] +['åύ', 'å®ĺ'] +['åĩĨ', 'åĪĻ'] +['æĥħ', 'æĻ¯'] +['æĽ´', 'é«ĺçļĦ'] +['åѦ', 'å®¶'] +['泡', '沫'] +['åľ°æĸ¹', 'æĶ¿åºľ'] +['å°±', 'çŁ¥éģĵ'] +['åij¼', 'åIJģ'] +['ç»ı', 'è´¸'] +['èĬ±', 'éĴ±'] +['æľī', 'ä¸Ģ次'] +['æĦŁ', 'æħ¨'] +['ä¸Ģ', 'åįĥ'] +['å¤ľ', 'æĻļ'] +['詹', 'å§Ĩ'] +['詹å§Ĩ', 'æĸ¯'] +['è¦ģ', 'éĹ»'] +['ç»', 'Ĵ'] +['æºIJ', 'äºİ'] +['çļĦ', 'è´¨éĩı'] +['注æĦı', 'äºĭ项'] +['æħ¢', 'æĢ§'] +['稳å®ļ', 'çļĦ'] +['建设', 'åĴĮ'] +['æĻ¯', '象'] +['éĩı', 'åĮĸ'] +['çļĦ', '話'] +['è¯Ħ', '级'] +['æº', 'ľ'] +['红', 'åĮħ'] +['éĢļ', 'éģİ'] +['社ä¼ļ', '责任'] +['æĸ°', '产åĵģ'] +['åĨ·', 'éĿĻ'] +['çľĭ', 'ä¸įåΰ'] +['èģĶ', 'éĤ¦'] +['éŃ', 'Ħ'] +['çļĦ', 'åīįæıIJ'] +['çļĦåīįæıIJ', 'ä¸ĭ'] +['è¾ĥ', '好'] +['çļĦ', 'æĦŁæĥħ'] +['客æĪ·', 'æıIJä¾Ľ'] +['çĭ¬', 'èĩª'] +['å¢ŀ', 'æĶ¶'] +['æĸĩ', 'çĮ®'] +['æĭ¼', 'åij½'] +['管çIJĨ', 'åĴĮ'] +['æµģåĬ¨', 'æĢ§'] +['åħ¨', 'å®¶'] +['ä¸Ĭ', 'æĸ¹'] +['æİ¨åĩº', 'çļĦ'] +['ä¸ī', 'åĽ½'] +['ä¸Ģ个', 'æĺ¯'] +['æĸ°', 'ä¸Ģè½®'] +['æĸĩåĮĸ', 'éģĹ产'] +['æ®', 'º'] +['大', 'æ¹¾åĮº'] +['éĥ½', 'éľĢè¦ģ'] +['çļĦ', 'å®ŀéĻħ'] +['ç·', 'Ĭ'] +['大', 'å¥ĸ'] +['åħī', 'èĬĴ'] +['便', 'äºİ'] +['çļĦ', '表æĥħ'] +['æ¼Ķ', 'ç»İ'] +['红', 'åĨĽ'] +['å½ĵ', 'æĪij'] +['æ²»', 'æĦĪ'] +['é¢Ŀ', '度'] +['éĿ', 'ľ'] +['ä»»ä½ķ', '人'] +['è¡Ĺ', '头'] +['çī¹', 'æĸ¯'] +['çĸ¯', 'æĭī'] +['åĮ»çĸĹ', 'æľºæŀĦ'] +['ç»Ļ', 'åŃ©åŃIJ'] +['è§Ħ', '磩'] +['è£', 'ľ'] +['çļĦ', '身影'] +['ä¸ĵ', 'æłı'] +['æĿ¥', '临'] +['ç«¥', 'å¹´'] +['å¤į', 'èĭı'] +['è¨', 'Ĥ'] +['åŀĭ', 'åı·'] +['åĽ¾', 'æ¡Ī'] +['ç®Ģ', 'åİĨ'] +['æĭ', '±'] +['èį·', 'åħ°'] +['ä»»', 'æĦı'] +['æī¿', 'æİ¥'] +['è¿Ļ', 'æīį'] +['客', '车'] +['æľĿ', 'çĿĢ'] +['éłħ', '缮'] +['åı°', 'é£İ'] +['çļĦ', 'æĪ¿åŃIJ'] +['éª', 'ı'] +['æĿ±', '西'] +['éģĹ', 'ä¼ł'] +['è¶Ĭ', 'å¤ļ'] +['äºĨ', 'ä»ĸçļĦ'] +['ä¸Ĭ', 'åij¨'] +['管çIJĨ', 'åĪ¶åº¦'] +['失', 'ä¸ļ'] +['çĶ·', 'åıĭ'] +['æİ¥', 'ç§į'] +['å¨ģ', 'åIJį'] +['çĴ°', 'å¢ĥ'] +['åıijçĶŁ', 'åľ¨'] +['个', 'åĽ½å®¶'] +['åĪĽæĸ°', 'åıijå±ķ'] +['æĶ¹åıĺ', 'äºĨ'] +['åģ¥åº·', 'çļĦ'] +['å̼å¾Ĺ', 'ä¸Ģ'] +['å̼å¾Ĺä¸Ģ', 'æıIJ'] +['åĽ¢', 'ä¼Ļ'] +['åģĩ', '设'] +['åı°', 'ä¸Ĭ'] +['è§ĦèĮĥ', 'åĮĸ'] +['éĻª', 'åIJĮ'] +['座', 'æ¤ħ'] +['åı¯', 'æĢľ'] +['åħĭæĢĿ', '主ä¹ī'] +['æ³ķå¾ĭ', '责任'] +['ä¸Ģ', 'é¡¿'] +['æĬ¬', '头'] +['为', 'éĩįçĤ¹'] +['è¿ľ', 'æ´ĭ'] +['éĢı', 'è¿ĩ'] +['åħ¨çIJĥ', 'åĮĸ'] +['è¶£', 'åij³'] +['票', 'æĪ¿'] +['æ¯ı', '人'] +['åIJĦç§į', 'åIJĦæł·'] +['äºĨ', 'åĩºæĿ¥'] +['ç»Ŀ对', 'æĺ¯'] +['ä¸ĭ', 'å±ŀ'] +['ä¸Ģ', 'åıĮ'] +['è¿Ļ', 'åĿĹ'] +['æĬĹ', 'çĸ«'] +['è¦ģ', 'çĤ¹'] +['å½¢æĪIJ', 'çļĦ'] +['æĪij', 'çľĭ'] +['ä¸ĩ', 'éĩĮ'] +['èĢĥ', 'çłĶ'] +['为', 'åħ¶'] +['æ°ij', '宿'] +['å¤ļ', 'ä½į'] +['大', 'èĩ´'] +['ä»ĺ', 'è´¹'] +['åħ¥', 'æīĭ'] +['å±ħ', 'å®¶'] +['æīĢåľ¨', 'åľ°'] +['人', '身'] +['è¿ĩ', 'å¾Ĺ'] +['è¯ķ', 'è¯ķ'] +['访', 'è°Ī'] +['åĬł', 'éĩį'] +['å°±', 'ä¸įä¼ļ'] +['çĶŁäº§', 'ä¼ģä¸ļ'] +['åĽŀ', 'åĽ½'] +['åºķ', '线'] +['èµ¶', 'åΰ'] +['æĶ¯', 'éĺŁ'] +['æĪij们', 'éĥ½'] +['éĤ®', 'æĶ¿'] +['缴', 'èĩ³'] +['éĴ¢', 'çIJ´'] +['åħ', 'ľ'] +['çłĶ讨', 'ä¼ļ'] +['æľĪ', '亮'] +['åĿļæĮģ', '以'] +['åħ¬å®ī', 'éĥ¨'] +['éĴ¢', '管'] +['å°ı', 'çϽ'] +['ç½®', 'ä¸ļ'] +['èģ', 'ĭ'] +['书', 'åĨĻ'] +['æĿ', 'ı'] +['éħį', 'æĸ¹'] +['èĢĮ', 'åıĪ'] +['çijŀ', '士'] +['çķĮ', 'çļĦ'] +['èĢģ', '大'] +['æĪIJçĨŁ', 'çļĦ'] +['å¹²', 'ä»Ģä¹Ī'] +['ä¸ĵ项', 'æĸĹäºī'] +['çŃī', 'å¤ļ个'] +['èĦ±', '离'] +['ä¸ī', '个æľĪ'] +['çłĶç©¶', 'åijĺ'] +['æĹĭ', '转'] +['æŀģ', 'èĩ´'] +['åħį', 'è´£'] +['åħįè´£', '声æĺİ'] +['å¾Īå¤ļ', 'çݩ家'] +['车', 'ä¸Ĭ'] +['交', 'äºĴ'] +['å·²', 'æĺ¯'] +['ä¸Ģ', 'å°ı'] +['çļĦ', 'éĩįçĤ¹'] +['èĬ±', 'äºĨ'] +['ä¸į', 'æĺİ'] +['æľīåħ³', 'è§Ħå®ļ'] +['çĬ¹', 'å¦Ĥ'] +['çľ', '¸'] +['å¯', '¡'] +['çļĦ', 'è¡£æľį'] +['åĮħ', '裹'] +['身', 'åŃIJ'] +['å¸ĪèĮĥ', '大åѦ'] +['äºĭ', 'åħĪ'] +['线', 'æĿ¡'] +['æ³ķ', 'åζ'] +['åħ»', 'æĬ¤'] +['稳å®ļ', 'æĢ§'] +['éĤ', 'µ'] +['åŀĦ', 'æĸŃ'] +['é¡', 'į'] +['èĢĥ', 'åı¤'] +['æĿł', 'æĿĨ'] +['èĭı', 'èģĶ'] +['æ°´', 'ç͵'] +['åħ·ä½ĵ', 'çļĦ'] +['æ¿Ģ', 'æ´»'] +['æĪij', 'æł¡'] +['åĪļ', 'å¼Ģå§ĭ'] +['åĩ¸', 'æĺ¾'] +['ç¦', '¾'] +['åħ¼', 'èģĮ'] +['éĢı', 'éģİ'] +['åľ¨', '游æĪıä¸Ń'] +['社ä¼ļ', 'åıijå±ķ'] +['好', 'çİ©'] +['å¹»', 'æĥ³'] +['ä¸į', '代表'] +['注æĦı', 'åĬĽ'] +['æ£', 'į'] +['ç͍', 'æīĭ'] +['ç¾İ', '人'] +['许å¤ļ', '人'] +['å¾Ī', 'æĺ¯'] +['çļĦ', 'çłĶåıij'] +['æīĵ', 'åĩº'] +['åIJĪä¼Ļ', '人'] +['ä¸Ģ', 'å¤ľ'] +['ç¼ĵ', 'ç¼ĵ'] +['ä¿®', 'æŃ£'] +['æĦŁ', 'çŁ¥'] +['ç»Ī', '身'] +['æ¿Ģ', 'ç´ł'] +['çݯå¢ĥ', 'ä¸ĭ'] +['次', 'ä¼ļè®®'] +['ç»ıæµİ', 'å¢ŀéķ¿'] +['æī', 'Ľ'] +['åıij', 'éħµ'] +['åĪĨæŀIJ', 'å¸Ī'] +['åľ¨', 'æľªæĿ¥'] +['主è¦ģ', 'æľī'] +['ä¸Ģ', 'åŃ£åº¦'] +['çļĦ', '说æ³ķ'] +['ä»İæĿ¥', '没æľī'] +['è´§', '车'] +['缩', 'å°ı'] +['太', 'è¿ĩ'] +['æķĪ', 'åĬĽ'] +['ä¸į', 'ä¸ĭ'] +['æĬķ', '稿'] +['èį¯', 'ä¸ļ'] +['ç»Ħ', 'éķ¿'] +['ç«Ļ', 'çĤ¹'] +['å¾Ī', 'åĸľæ¬¢'] +['éIJ', 'µ'] +['åĬ¿', '头'] +['æ¼ı', 'æ´ŀ'] +['æĦ¤', 'æĢĴ'] +['åħħ', 'å®ŀ'] +['åĪĽä¸ļ', 'æĿ¿'] +['çĪ', 'ª'] +['æľª', 'å¿ħ'] +['åºķ', 'éĥ¨'] +['å¾Ĺ', 'åĪĨ'] +['人æ°ij', 'åĮ»éĻ¢'] +['äºĮæīĭ', 'æĪ¿'] +['å·²ç»ı', '被'] +['大', '楼'] +['æĸ°', 'æĪ¿'] +['辦', 'æ³ķ'] +['ç͍', 'åĬĽ'] +['æĭĵ', '宽'] +['åĨħ', 'åľ¨'] +['æĴŃ', 'åĩº'] +['饰', 'æ¼Ķ'] +['ä¹Ł', '让'] +['ä½ľ', 'çĤº'] +['çī©ä¸ļ', '管çIJĨ'] +['åį´', 'ä¸į'] +['为', 'ä¸ŃåĽ½'] +['å±Ģ', 'åĬ¿'] +['ä¸į', 'èĤ¯'] +['æľĢ', 'æĸ°çļĦ'] +['åı¯ä»¥', 'éĢīæĭ©'] +['æĺ¾', 'çݰ'] +['å°±', 'ç®Ĺæĺ¯'] +['åľ¨', 'æł¡'] +['é¾', 'Ł'] +['两', 'æĿ¡'] +['çļĦ', 'å®ŀåĬĽ'] +['è¶Ĭ', '好'] +['她', 'åľ¨'] +['å¿ł', 'è¯ļ'] +['ä¹Ł', 'éľĢè¦ģ'] +['游æĪı', 'æĵįä½ľ'] +['è¶ħ', 'åĩº'] +['å¦Ĥæŀľ', 'ä¸į'] +['æīĢåľ¨', 'çļĦ'] +['ä½ł', 'è¿ĺ'] +['以', 'åĨħ'] +['æľī', 'ä¸Ģå®ļ'] +['åı¯', 'è¾¾'] +['è·ij', 'åΰ'] +['åī', 'Ľ'] +['建ç«ĭ', 'åģ¥åħ¨'] +['æķ´', '车'] +['åīį', 'æĸ¹'] +['éĹ´', 'æİ¥'] +['çѹ', 'å¤ĩ'] +['çĸ²', 'åĬ³'] +['离', 'å¼ĢäºĨ'] +['æ±', 'Ŀ'] +['éĿ¢', 'éĥ¨'] +['ä¹ĭåīį', 'çļĦ'] +['åıĺ', '为'] +['å¦Ĥæŀľ', '说'] +['对', 'ä»ĺ'] +['åĿĩ', 'åı¯'] +['被åijĬ', '人'] +['ç²¾', 'ç¾İ'] +['èģļ', 'ä¼ļ'] +['çĿĢ', 'æĢ¥'] +['è°·', 'æŃĮ'] +['ä¸Ģ', 'åı·'] +['红', 'åĪ©'] +['ä¼łå¥ĩ', '游æĪı'] +['å»', 'ĸ'] +['è´', 'ŀ'] +['ä¹°', 'åΰ'] +['éŃ', 'ļ'] +['ä½ĵ', 'è´¨'] +['å°ij', 'äºĨ'] +['æ³ī', 'å·ŀ'] +['åIJ', 'Ł'] +['ç»Ŀ', 'ä¸į'] +['é»ij', 'æģ¶'] +['é»ijæģ¶', 'åĬ¿åĬĽ'] +['ä¸Ĭ', 'æĺł'] +['çļĦè¯Ŀ', 'é¢ĺ'] +['ä¸ĩ人', '次'] +['ä¸ĸ', 'éĹ´'] +['ç͍', 'å·¥'] +['è´¯', 'ç©¿'] +['å®Ŀ', 'çŁ³'] +['ä½ł', '好'] +['åĪĩ', 'åī²'] +['强', 'åĽ½'] +['åĽŀ', 'èIJ½'] +['æ°´', 'æĻ¶'] +['模', '仿'] +['æ´ª', 'æ°´'] +['éĢĻ', '麼'] +['åįģä¸ī', 'äºĶ'] +['ä½', 'ij'] +['éĻ', 'Ħä»¶'] +['çļĦ', 'å¢ŀéķ¿'] +['éĻĦ', 'å±ŀ'] +['çݰ', 'å·²'] +['帮', 'ä½ł'] +['éĩij', 'çīĮ'] +['é«ĺ', 'åİŁ'] +['åľ¨', 'å®¶éĩĮ'] +['éĺ²', 'èħIJ'] +['ç¡®å®ŀ', 'æĺ¯'] +['宣', '讲'] +['天', 'æīį'] +['ç»ıèIJ¥', '管çIJĨ'] +['éĶħ', 'çĤī'] +['åIJĪ', 'ä¸Ģ'] +['è§Ĥ', 'èµı'] +['éķ¿', 'è¾¾'] +['主ä¹ī', 'æĢĿæĥ³'] +['éĤ£', '麼'] +['é£İ', 'äºij'] +['为主', 'çļĦ'] +['æļij', 'åģĩ'] +['æĮģ', 'ä¹ħ'] +['å¼Ĥ', 'åľ°'] +['å¼Ģ', 'éŨ'] +['模', 'æĿ¿'] +['æī¹', '次'] +['ä¸į', '便'] +['天', 'çĶŁ'] +['åĩł', '个æľĪ'] +['ä¸ĵ', 'ç§ij'] +['åı¦', 'æľī'] +['åħ¬å¸ĥ', 'çļĦ'] +['æĩ', '·'] +['åľº', 'åIJĪ'] +['çļĦå¿ĥ', 'æĢģ'] +['è¿ĺ', '好'] +['å®ŀ', 'æĪĺ'] +['èĢģå¸Ī', 'çļĦ'] +['åħ©', 'åĢĭ'] +['åı¯', 'åľ¨'] +['éĤ£', 'ä½į'] +['å¥ł', 'å®ļäºĨ'] +['ä¿ĥ', 'éĶĢ'] +['æı´', 'åĬ©'] +['ä¸ĩ', 'çī©'] +['æĥħ', 'æĬ¥'] +['é¦ĸåħĪ', 'è¦ģ'] +['æĸĩåĮĸ', 'åĴĮ'] +['éĥ½', 'å·²ç»ı'] +['ä¸Ĭ', 'ä¸ĸ纪'] +['åĨľ', 'åľº'] +['大', 'æī¹'] +['æĺİçϽ', 'äºĨ'] +['çļĦ', 'æĪIJéķ¿'] +['çļĦ', 'æ¯ĶèµĽ'] +['失', '误'] +['åģļ', 'æĪIJ'] +['ä»Ĭ天', 'å°ıç¼ĸ'] +['é¢Ĩ', 'è¢ĸ'] +['æıIJåįĩ', 'äºĨ'] +['å¾IJ', 'å·ŀ'] +['ä»į', 'æľī'] +['è¿ĩ', '滤'] +['å¹½', 'é»ĺ'] +['çĥŃ', 'éĩı'] +['ä¸Ģ', 'é¦ĸ'] +['æ¼Ĥ亮', 'çļĦ'] +['åĩł', 'ç§į'] +['åĢ¡', 'è®®'] +['å°±åı¯ä»¥', 'äºĨ'] +['æİĴ', 'åĪĹ'] +['éĩį', 'éĩį'] +['ä¼ģä¸ļ', 'åĴĮ'] +['ä¸ĵ', 'å±ŀ'] +['çħ', 'İ'] +['亲', 'æĪļ'] +['çϾåĪĨ', 'ä¹ĭ'] +['稿', 'ä»¶'] +['è¿ĺ', 'å¾Ĺ'] +['人', 'åĵ¡'] +['äºī', '夺'] +['æĽ´', '容æĺĵ'] +['大', 'èĩªçĦ¶'] +['鼻', 'èħ¦'] +['太', '空'] +['åľ°', 'å¤Ħ'] +['å¤', '¢'] +['ä»ĸ', '对'] +['å¿ħ', 'å°Ĩ'] +['ä¸į', 'å½ĵ'] +['严', 'è°¨'] +['åĩº', 'åľº'] +['å·²ç»ı', 'æľī'] +['é¢Ĩ', 'åĨĽ'] +['é«ĺ', 'æ¡£'] +['ä¸Ģ', 'æīĢ'] +['æł', 'Ĺ'] +['让', 'åѦçĶŁ'] +['æĽ¹', 'æĵį'] +['æŁIJ', 'ä¸Ģ'] +['伸', 'åĩº'] +['èĬ±', 'åįī'] +['æ¸ħ', 'éĨĴ'] +['èģĶç³»', 'æĸ¹å¼ı'] +['åĪĨ', 'å±Ģ'] +['èħ', '³'] +['æ©¡', 'èĥ¶'] +['éķ¿', 'å¾Ĺ'] +['绿', 'åľ°'] +['è¢', 'į'] +['çļĦ', 'èīºæľ¯'] +['女', 'æľĭåıĭ'] +['ä¸Ń', 'è¶ħ'] +['离', 'åŃIJ'] +['å¤ļæł·', 'åĮĸ'] +['éĺ³', 'åı°'] +['ä½İ', '碳'] +['ä¸Ģ', 'ç±»'] +['çŃīæĸ¹éĿ¢', 'çļĦ'] +['å¾Ĺ', '好'] +['模', 'åħ·'] +['ä¸ĩ', '亿'] +['çķĻ', 'æĦı'] +['临', 'æ²Ĥ'] +['å°ij', 'éĩı'] +['çľĭ', 'åIJij'] +['ç»ıèIJ¥', 'èĢħ'] +['çķĻä¸ĭ', 'äºĨ'] +['åĿı', 'äºĨ'] +['åijĬ', 'åĪ«'] +['羣', 'çIJĨ'] +['ç¼´', 'è´¹'] +['æĬĬ', 'ä½ł'] +['çļĦ', 'ä»»åĬ¡'] +['æĪij', '对'] +['ä¹°', 'åħ¥'] +['çĻ»', 'ä¸Ĭ'] +['æľī', '两个'] +['ä¸Ģ', '头'] +['æĵį', 'æİ§'] +['åħ¨', 'è¦ĨçĽĸ'] +['çĿĢ', 'æīĭ'] +['å¢Ļ', 'éĿ¢'] +['å¤ļ', 'æĸ¹'] +['åı¯çα', 'çļĦ'] +['ä¹Ł', 'åı¯èĥ½'] +['æľĢ', 'æľī'] +['è¿ĻäºĽ', 'éĥ½æĺ¯'] +['æĥ', '¡'] +['å®', '®'] +['å¾Ī', 'å°ı'] +['éĹ®é¢ĺ', 'æĺ¯'] +['åĿĩ', 'æľī'] +['å¾ģ', 'éĽĨ'] +['说', 'åĩº'] +['æľī', 'æĦı'] +['é¢', 'Ĥ'] +['æī¬', 'å·ŀ'] +['åķĨä¸ļ', '模å¼ı'] +['çĶŁ', 'èĤĸ'] +['æįIJ', '款'] +['å²', 'Ĥ'] +['ç¾İ', 'æĻ¯'] +['è¿ĺ', '羣'] +['æĭ¥', 'æĬ±'] +['身ä½ĵ', 'åģ¥åº·'] +['æ·±', 'å¤Ħ'] +['çľ¼', 'ç¥ŀ'] +['çļĦ', '形象'] +['ä¼ĺ', 'è¶Ĭ'] +['å½ĵ', 'æĪIJ'] +['åĮº', 'åĪĨ'] +['åİ»', 'éϤ'] +['注', 'å®ļ'] +['å§IJ', '妹'] +['åĮº', 'åĨħ'] +['é©', 'ļ'] +['æļĹ', '示'] +['æĺİ', '亮'] +['æħ°', 'éĹ®'] +['å¸Ĥåľº', '份é¢Ŀ'] +['çĮª', 'èĤī'] +['çļĦ', 'èµĦéĩij'] +['åİĨ', 'ç»ı'] +['å§ĭç»Ī', 'åĿļæĮģ'] +['çĶŁ', 'æľº'] +['ä¸į', '顾'] +['éĩij', 'åĪļ'] +['大', '声'] +['éĻķ', '西çľģ'] +['é²', 'į'] +['åĨľä¸ļ', 'åĨľæĿij'] +['æľī', '害'] +['éŨ', 'è¯Ĭ'] +['æ¯ı', 'ä¸Ģ次'] +['çļĦ', 'åĽłç´ł'] +['é¢Ŀ', 'å¤ĸ'] +['åİ¿', '级'] +['çļĩ', 'åIJİ'] +['åĽ½', 'ä¼ģ'] +['é¦ĸ', 'éĢī'] +['ç¼ĸ', 'åĨĻ'] +['æĭ¿', 'èµ·'] +['åģ·', 'åģ·'] +['ä¸İ', 'ä¸ŃåĽ½'] +['åįĸ', 'å®¶'] +['ç»Ļ', 'ä»ĸ们'] +['ç¥ŀ', 'è¯Ŀ'] +['åѸ', 'æł¡'] +['æĪij', 'ä¸Ģ缴'] +['çŁ¥éģĵ', 'äºĨ'] +['åį', 'Ĵ'] +['åĴĮ', 'åľ°åĮº'] +['ä»Ģä¹Ī', 'éĥ½'] +['çĶ»', 'å®¶'] +['æľ¬', 'çĿĢ'] +['ä½Ļ', 'åIJį'] +['审', 'çIJĨ'] +['ä¸Ģ', 'åIJij'] +['åıijå±ķ', 'è¶ĭåĬ¿'] +['åĮº', 'éĹ´'] +['注åĨĮ', 'èµĦæľ¬'] +['çIJ', '¦'] +['ä¸į', 'åı¯ä»¥'] +['çļĦ', 'åĦ¿åŃIJ'] +['å̼', 'çıŃ'] +['ä¸¥æł¼', 'çļĦ'] +['å®ŀä½ĵ', 'ç»ıæµİ'] +['æľī', 'æĿĥ'] +['æĪij', 'åıĪ'] +['éĵ¶', 'æ²³'] +['ç«ĭ', '马'] +['æĿĢ', 'äºĨ'] +['åĮħ', '容'] +['管', 'å®¶'] +['身', 'é«Ķ'] +['éĵ', 'ħ'] +['å°ı', 'åŃIJ'] +['管çIJĨ', 'ç³»ç»Ł'] +['æľīçļĦ', '人'] +['é£İ', 'ç͵'] +['æĻºèĥ½', 'åζéĢł'] +['ç²¾', 'ç¡®'] +['æĭĽåķĨ', 'å¼ķ'] +['æĭĽåķĨå¼ķ', 'èµĦ'] +['äºĮæīĭ', '车'] +['åİ¿', 'å§Ķ'] +['èīº', '人'] +['å¥', 'ķ'] +['è¿İ', 'æĿ¥äºĨ'] +['ç»ĵæĿŁ', 'äºĨ'] +['çļĦ', 'ä¼łç»Ł'] +['æĭ¼', 'æIJı'] +['奥', '迪'] +['çĸij', 'æĥij'] +['ä¹ĭ', 'æĹ¥èµ·'] +['æłĩå¿Ĺ', 'çĿĢ'] +['åľ°', 'åįĢ'] +['è¯ł', 'éĩĬ'] +['åΰ', 'æľŁ'] +['åħ¨', 'éĥ½'] +['çŁŃ', 'æļĤ'] +['æĺ¯', 'æĪijåĽ½'] +['æĪij', 'å·²ç»ı'] +['æ»´', 'æ»´'] +['天', 'èµĭ'] +['对', '她'] +['åį«çĶŁ', 'éĹ´'] +['çĶŁäº§', 'åŁºåľ°'] +['æĹ¥', 'è®°'] +['çļĦ', 'æķĻåѦ'] +['åĵ', 'ĩ'] +['æ°ij', 'äºĭ'] +['è¿ĺ', 'åİŁ'] +['æīĭ', 'ä¸ŃçļĦ'] +['çļĦ', 'èī¯å¥½'] +['æ·', '«'] +['ä¸Ńåħ±', 'ä¸Ń央'] +['åĪ', 'ĥ'] +['åĵ', 'Ħ'] +['åľ¨', 'ä»ĸçļĦ'] +['å°Ī', 'æ¥Ń'] +['åľº', 'éĿ¢'] +['éĤ»', 'å±ħ'] +['çĹ', 'Ĵ'] +['å¦', 'Ħ'] +['å¤ĸ', 'ç§ij'] +['ä¸į', 'éĢĤ'] +['举åĬŀ', 'çļĦ'] +['é', 'Ĥ¹'] +['åħļçļĦ', '建设'] +['çϼ', '表'] +['è·¨', 'çķĮ'] +['æ²ī', 'æ·Ģ'] +['大', 'çīĩ'] +['è¶Ĭ', 'é«ĺ'] +['å°Ĩ', 'æĺ¯'] +['è§ī', 'éĨĴ'] +['åĤ¨', 'åŃĺ'] +['å¢ŀ', '大'] +['ä¸į', '让'] +['æķ´', 'å½¢'] +['å¹³åı°', 'ä¸Ĭ'] +['åĩł', 'ä½į'] +['è¯ī', 'æ±Ĥ'] +['好', 'ä¸į好'] +['åľ', 'į'] +['æĸĩ', 'æľ¬'] +['é̲', 'åħ¥'] +['ç´', 'į'] +['æł¹', 'æĵļ'] +['èįī', 'æ¡Ī'] +['åħŃ', '个'] +['åĭ', '¿'] +['åζ', 'æĪIJ'] +['饮', 'æ°´'] +['æ°¸', 'æģĴ'] +['èĩª', 'æĿĢ'] +['åı¸', '马'] +['éļ¾', 'çĤ¹'] +['为', 'æĪij们'] +['å¼', '§'] +['åī©', 'ä¸ĭçļĦ'] +['åĩĨå¤ĩ', '好'] +['çļĦ', 'æľĢä½³'] +['èģĶåIJĪ', 'ä¼ļ'] +['æĤ£èĢħ', 'çļĦ'] +['æĪijä¸į', 'çŁ¥éģĵ'] +['ä¸ĭ', 'ä¸Ģ个'] +['åıijå±ķ', 'æĸ¹åIJij'] +['ç¬', '¨'] +['æīĢ以', 'æĪij们'] +['åĨĻ', 'äºĨ'] +['éĢł', 'æĪIJäºĨ'] +['æ²Ļ', 'æ¼ł'] +['çŃĽ', 'éĢī'] +['çģ¾', 'åĮº'] +['ä¸Ĭ', 'çľĭ'] +['éħ', '¶'] +['æ»ļ', 'åĬ¨'] +['éļ¾', 'åħį'] +['åIJī', 'åĪ©'] +['ä¸Ģ', 'ä¸Ģ'] +['ç²¾', 'å¯Ĩ'] +['伸', 'æīĭ'] +['礼', '仪'] +['åħ¨', 'æĺ¯'] +['è¶Ĭ', '大'] +['ä¸Ń', 'æłĩ'] +['åıĸ', 'åĨ³'] +['åıĸåĨ³', 'äºİ'] +['éĢĶ', 'ä¸Ń'] +['讨', 'åİĮ'] +['æīĭ', 'åĨĮ'] +['第', 'ä¹Ŀ'] +['åŃĶ', 'åŃIJ'] +['çĦ¶', 'å¾Į'] +['ä¸Ģ', 'åħ±'] +['æµ·', 'æĬ¥'] +['款', 'å¼ı'] +['æķ´', '天'] +['è¾¹', 'çķĮ'] +['è·¯', 'è¾¹'] +['æĻĭ', '级'] +['åIJIJ', 'æ§½'] +['çļĦ', 'åħ³æ³¨'] +['æĪij', '没æľī'] +['å°±æĺ¯', 'åľ¨'] +['缮', 'çļĦæĺ¯'] +['åį³ä½¿', 'æĺ¯'] +['é¡¶', 'å°ĸ'] +['å·²ç»ı', 'åľ¨'] +['å®īåħ¨', 'éļIJæĤ£'] +['æłĩ', 'æĿĨ'] +['åįĹ', 'éĢļ'] +['ä¼ļ', '对'] +['座', 'ä½į'] +['èµ¢å¾Ĺ', 'äºĨ'] +['åİŁæĿ¥', 'çļĦ'] +['身', '为'] +['书', 'åºĹ'] +['è¢Ń', 'åĩ»'] +['ä»Ĭ', 'æĻļ'] +['以', 'èī²'] +['以èī²', 'åĪĹ'] +['æĬĸ', 'éŁ³'] +['åį´', '没æľī'] +['丧', '失'] +['çļĦ', 'å±ĢéĿ¢'] +['åįģåĽĽ', 'äºĶ'] +['çŃī', '缸åħ³'] +['æ±ĩ', 'æĢ»'] +['å¤ĸ', '表'] +['为', 'æ°ij'] +['éľĩ', 'æĥĬ'] +['å¥Ĺ', 'è·¯'] +['çĬ¯ç½ª', 'å«Įçĸij'] +['å°Ĩ', '以'] +['çİĩ', 'é¢Ĩ'] +['éħĴ', 'åIJ§'] +['è¡Įä¸ļ', 'åıijå±ķ'] +['å¹´', 'èĩ³'] +['åύ', 'æĿIJ'] +['åĴĮ', 'æĬĢæľ¯'] +['æľĢ', 'å°ı'] +['è¿Ļä¸Ģ', 'åĪĩ'] +['èģĮ', 'ç§°'] +['å½ĵ', 'ä½ľ'] +['æİĢ', 'èµ·'] +['åĴ', 'ĭ'] +['ä¸Ń', 'éĥ¨'] +['æīĭ', 'èĩĤ'] +['ç½¢', 'äºĨ'] +['媳', 'å¦ĩ'] +['æ´½', 'è°Ī'] +['æĹ¶ä»£', 'ä¸ŃåĽ½'] +['人çĶŁ', 'çļĦ'] +['æŀģ', 'éĻIJ'] +['ç¦', 'Ħ'] +['åĮº', 'æĶ¿åºľ'] +['æľ¬', 'éĴ±'] +['礼', 'åĵģ'] +['çļĦ', 'éĤ£ä¸ª'] +['侦', 'æŁ¥'] +['太å¤ļ', 'çļĦ'] +['å®ŀæĸ½', 'æĸ¹æ¡Ī'] +['é«ĺ', 'æłĩåĩĨ'] +['æĮĩæĮ¥', 'éĥ¨'] +['å̾', 'æĸľ'] +['çī¹èī²', '社ä¼ļ'] +['çµIJ', 'æŀľ'] +['éĴ»', 'çŁ³'] +['ç§»', 'æ¤į'] +['çī¹', 'ç§į'] +['èĩª', 'æĦ¿'] +['æĭľ', 'çĻ»'] +['åįķ', '身'] +['åį´', 'åıĪ'] +['åĪ¥', '人'] +['åIJĪ', 'è§Ħ'] +['æľº', 'ç͵'] +['çī¹', 'æĦı'] +['å½ĵåīį', 'ä½įç½®'] +['ä¹°', 'å®¶'] +['åIJĪ', '约'] +['èĤ©', 'èĨĢ'] +['为', 'åĩĨ'] +['å®¶', 'è£ħ'] +['çļĦ', 'çĥŃæĥħ'] +['éĿŀ', 'éģĹ'] +['çļĦ', 'éŃħåĬĽ'] +['åİŁ', 'åijĬ'] +['社ä¼ļ', 'åIJĦçķĮ'] +['ä¹°', 'çļĦ'] +['å¤ļ', 'åIJĥ'] +['éĽķ', 'å¡ij'] +['èµ·', 'ä¹ī'] +['åĬł', 'åī§'] +['éĤ£ä¸Ģ', 'åĪ»'] +['å°Ĩ', 'è¿Ľä¸ĢæŃ¥'] +['æ¡Ĥ', 'æŀĹ'] +['æĽ´', '强'] +['对', 'ä¼ģä¸ļ'] +['æĹł', 'æĦı'] +['ä¹łè¿ijå¹³', 'æĸ°'] +['æµģ', '失'] +['å¾®', '软'] +['缸', '对äºİ'] +['座è°Ī', 'ä¼ļ'] +['主', 'èIJ¥ä¸ļ'] +['主èIJ¥ä¸ļ', 'åĬ¡'] +['ç§ģ', 'åĭŁ'] +['å±ķ示', 'äºĨ'] +['常æĢģ', 'åĮĸ'] +['è²', '´'] +['符', 'åı·'] +['å¹´è½»', 'çļĦ'] +['å°±', 'éľĢè¦ģ'] +['ä¹Ł', 'æĽ¾'] +['çļĦæĥħ', '绪'] +['è¾¾', 'æłĩ'] +['èĩ', '¨'] +['ä½į', 'å±ħ'] +['ä»ħ', '为'] +['é¦ĸ', 'å®¶'] +['éĺ´', 'éĺ³'] +['ä¸įåĨį', 'æĺ¯'] +['åĽłä¸º', 'å®ĥ'] +['ä¼ģä¸ļ', 'åľ¨'] +['çĺ', '¾'] +['åIJ¬', 'è§ģ'] +['åİŁ', 'æľī'] +['åζ', 'è£ģ'] +['å¯Ĥ', 'å¯ŀ'] +['éĢļè¿ĩ', '对'] +['æ»ij', 'éĽª'] +['è¿Ļ', 'å¼ł'] +['çļĦ', 'çIJĨè§£'] +['æĸ°', 'ä¸ŃåĽ½'] +['è¿Ļ', 'åĦ¿'] +['ä½İ', 'ä»·'] +['æĥ³', 'è¿ĩ'] +['çļĦ', 'ä¿¡å¿ĥ'] +['建çŃij', 'çī©'] +['çļĦ', 'é¢ľèī²'] +['ä¸į', 'åºĶ该'] +['æĹłçĸij', 'æĺ¯'] +['å¼ķèµ·', 'äºĨ'] +['åħ¨', 'åijĺ'] +['æĿ°', 'åĩº'] +['è¿Ļæĺ¯', 'æĪij'] +['èª', '°'] +['èĺ', 'ĩ'] +['éĺµ', 'åľ°'] +['åħħ', 'å̼'] +['çŁ¿', 'ä¸ļ'] +['çĿĢ', 'ä»ĸ'] +['ä¿¡', '访'] +['ä¸ĩ', 'è¾¾'] +['æij©', 'æĵ¦'] +['å¼Ģ', '端'] +['èı²', 'å¾ĭ'] +['èı²å¾ĭ', '宾'] +['车', 'åŃIJ'] +['æľ¬èº«', 'çļĦ'] +['çģ«è½¦', 'ç«Ļ'] +['常', 'å·ŀ'] +['为', '代表'] +['为代表', 'çļĦ'] +['广', 'ç͵'] +['亲', '人'] +['åı³', 'æīĭ'] +['éĽĨ', 'è£ħ'] +['éĽĨè£ħ', 'ç®±'] +['çļĦ', 'åį°è±¡'] +['æ©Ł', 'æľĥ'] +['åĮĨ', 'åĮĨ'] +['åħī', 'ç͵'] +['大', 'æĸ¹'] +['è¿ĺ', 'æľª'] +['åĪ©', '好'] +['ç»Ŀ', '大å¤ļæķ°'] +['åľ¨', 'è¿Ļç§į'] +['ä¸Ģ', 'ç»Ħ'] +['æĸ°', 'èĤ¡'] +['转', 'åıij'] +['æ³ķ', 'åºŃ'] +['æĹł', 'æīĢ'] +['éģĵ', 'è·¯ä¸Ĭ'] +['çŁ¿', 'å±±'] +['èij', 'ī'] +['æĶ¶', 'åĽŀ'] +['ç§°', 'ä¹ĭ'] +['ç§°ä¹ĭ', '为'] +['æıŃ', 'éľ²'] +['åı£', '岸'] +['åIJ', '¼'] +['å¿ĥ', 'æĥ³'] +['çļĦ', '梦æĥ³'] +['éĽ', '¯'] +['ä¹ĭ', 'åĪĿ'] +['å¥ĸ', '项'] +['订', 'éĺħ'] +['èĵĿ', '天'] +['åĿ¦', 'åħĭ'] +['ç«ĭ', 'æ¡Ī'] +['èģĶ', 'æīĭ'] +['ä½Ĩæĺ¯', 'æĪij'] +['帮', 'æĪij'] +['ä»ħ', '代表'] +['说', 'æĪij'] +['çļĦ', 'è¶ĭåĬ¿'] +['æ¯Ķè¾ĥ', '大'] +['èµ°', 'å»Ĭ'] +['éĩįçĤ¹', 'é¡¹çĽ®'] +['èµĮ', 'åľº'] +['åIJį', 'çīĩ'] +['æĦŁ', 'åı¹'] +['åľ¨', 'åľ°ä¸Ĭ'] +['åıij', 'çĥŃ'] +['èĮĥ', 'çķ´'] +['çļĦ', 'éģĵè·¯'] +['éĩij', 'èī²'] +['ä»ĸ', 'åıĪ'] +['ä¼ļ', '产çĶŁ'] +['æ°ij', 'åĽ½'] +['å®ĺæĸ¹', 'ç½ijç«Ļ'] +['æĶ¶çĽĬ', 'çİĩ'] +['çļĦ', 'åΰæĿ¥'] +['çļĦ', 'åĬŀæ³ķ'] +['æĶ¹', 'åζ'] +['ä¸ĩ', 'ç§ij'] +['ä¸į', 'äºĪ'] +['è¿ĻäºĽ', 'éĹ®é¢ĺ'] +['çα', 'ä¸Ĭ'] +['çIJĥ', 'åľº'] +['è´£', '令'] +['æİĪ', '课'] +['åľ¨', 'é¦Ļ港'] +['ç»Ĩ', 'èħ»'] +['å¤ļ', 'ä¸ĩ'] +['åIJĮ', 'å¹´'] +['大', '使'] +['æĸ', 'ĭ'] +['ä¹Ł', '为'] +['æĥł', 'å·ŀ'] +['åIJī', '祥'] +['çͰ', 'åĽŃ'] +['åĽ½å®¶', 'éĺŁ'] +['éĩį', 'çĶŁ'] +['åľ¨', 'åħ¶'] +['é¦Ļ', 'åij³'] +['è´Ł', 'èį·'] +['亲', 'åĪĩ'] +['èĩª', '豪'] +['没', 'éĶĻ'] +['åĽłä¸º', 'åľ¨'] +['æĺŁ', 'æĺŁ'] +['éĤ', 'ij'] +['è¿ĺæľī', 'å¾Īå¤ļ'] +['æij©', 'æīĺ'] +['æij©æīĺ', '车'] +['æŃ¥', 'è¡Į'] +['管çIJĨ', 'ä½ĵç³»'] +['èĦļ', 'ä¸ĭ'] +['éģİ', 'åİ»'] +['æ±ī', 'è¯Ń'] +['对', 'ä¸įèµ·'] +['çļĦ', 'ç»ıåİĨ'] +['åıĬ', '缸åħ³'] +['ä¸įå°ij', '人'] +['éĩį', 'ç£ħ'] +['åĬ³åĬ¨', 'èĢħ'] +['大åĬĽ', 'åıijå±ķ'] +['æĢİä¹Ī', 'åģļ'] +['çĭĹ', 'çĭĹ'] +['举åįĹ', 'äºļ'] +['åĭĩ', 'äºİ'] +['åħ¬', 'éĸĭ'] +['çĵ·', 'çłĸ'] +['åıĤ', 'çħ§'] +['广æĴŃ', 'ç͵è§Ĩ'] +['举', 'åĬ¨'] +['æ±Ł', '西çľģ'] +['æķĪ', 'èĥ½'] +['å͝', 'æľī'] +['éĿ¢', 'è²Į'] +['èĩªåĬ¨', '驾驶'] +['æ¦ľ', 'åįķ'] +['å½ĵ', 'æĪij们'] +['仲', 'è£ģ'] +['æľ¨', 'æĿIJ'] +['ç±³', 'åħ°'] +['çϽ', 'éĵ¶'] +['çļĦ', '人éĥ½'] +['å°±', 'åĥıæĺ¯'] +['æŃ¥', 'åħ¥'] +['åįł', 'ç͍'] +['åĩ»', 'è´¥'] +['让', '大家'] +['ä¼ļ', 'è®©ä½ł'] +['åİ¿', 'æĶ¿åºľ'] +['è¦ģ', 'ç͍'] +['çŃī', 'å½¢å¼ı'] +['åįĩ', 'é«ĺ'] +['责任', 'æĦŁ'] +['å¤ĩ', 'ç͍'] +['ä»ĸ', '认为'] +['æ¸ħåįİ', '大åѦ'] +['ä»ĸ', 'èĩªå·±'] +['éĸ±', 'è®Ģ'] +['太平', 'æ´ĭ'] +['éĶģ', 'å®ļ'] +['çŃ', 'Ĩ'] +['è¿Ļ', 'çīĩ'] +['æī§', 'æĶ¿'] +['è¿ĶåĽŀ', 'æIJľçĭIJ'] +['å°±', 'æŃ¤'] +['éģĩ', 'åΰäºĨ'] +['å¼Ģå¹ķ', 'å¼ı'] +['管çIJĨ', 'éĥ¨éŨ'] +['å§¿', 'åĬ¿'] +['设', 'æĥ³'] +['åĽĽ', 'åŃ£'] +['æĬĢæľ¯', '人åijĺ'] +['å·®', 'çĤ¹'] +['è¾ŀ', 'èģĮ'] +['èĢģ', '師'] +['çļĦ', 'æĦŁåıĹ'] +['ä¹Ł', 'éĿŀ常'] +['å¹´', 'ä¸ĬåįĬå¹´'] +['æĢª', 'çī©'] +['èĮĥ', 'æĸĩ'] +['æĪĺ', 'å½¹'] +['åIJ«', 'ä¹ī'] +['åħ¨', 'è¿ĩç¨ĭ'] +['èĢĮ', 'éĿŀ'] +['éĢļ讯', 'åijĺ'] +['è¿Ļæł·', 'æīįèĥ½'] +['æľº', 'ç»Ħ'] +['è£', 'ı'] +['çķ¶', 'çĦ¶'] +['èµĮ', 'åįļ'] +['åIJĦ', 'æľī'] +['å·¥ä½ľ', 'æľºåζ'] +['äºĭ', 'åIJİ'] +['åī§', 'éĻ¢'] +['å±Ĭ', 'æĹ¶'] +['åĺ´', 'éĩĮ'] +['主', '线'] +['ä¸Ģ', 'åľĪ'] +['主è¦ģ', 'åİŁåĽł'] +['å°¸', 'ä½ĵ'] +['åĮ»çĸĹ', 'åĻ¨æ¢°'] +['ä½ł', 'æĢİä¹Ī'] +['ä½Ĩ', 'çͱäºİ'] +['æĹ¶', '空'] +['çĶ·', 'æľĭåıĭ'] +['çĶľ', 'èľľ'] +['é«ĺ', 'åľ°'] +['æĻ', 'ĸ'] +['èĴIJ', 'éĽĨ'] +['åĩĿèģļ', 'åĬĽ'] +['å¤ĩ', 'åıĹ'] +['æĸĩ', 'åĪĽ'] +['马', 'æĿ¥'] +['马æĿ¥', '西äºļ'] +['æŁ´', 'æ²¹'] +['使', '人'] +['æķĻ', 'ä¼ļ'] +['ç§ĭ', '天'] +['æĺİ', 'çıł'] +['åħŃ', 'åįģ'] +['çݯå¢ĥ', 'ä¸Ń'] +['æ¸ħ', 'æĻ¨'] +['积æŀģ', 'åıĤä¸İ'] +['å·ħ', 'å³°'] +['为', 'æľŁ'] +['çѾ', 'åŃĹ'] +['æĦŁ', 'æ¿Ģ'] +['ç§ĭ', 'åŃ£'] +['æĿij', 'åŃIJ'] +['æ¢ħ', '西'] +['æļ´', '鼨'] +['çĶŁæ´»', 'åľ¨'] +['çªĹ', 'æĪ·'] +['æģ¶', 'åĬ£'] +['纯', 'ç²¹'] +['åľ¨', 'æİ¥åıĹ'] +['没', 'èĥ½'] +['è¡Į', '人'] +['åĭ', 'º'] +['æĭ¨', 'æīĵ'] +['ä½ľ', 'åĩºäºĨ'] +['çļĦ', '主é¢ĺ'] +['æľª', 'ä¾Ĩ'] +['ä¸Ń', 'æľĢ'] +['æ¾', 'ľ'] +['é«ĺ', 'è¡Ģåİĭ'] +['åħ´', 'èµ·'] +['æŃ£', 'èĥ½éĩı'] +['åŁ¹è®Ń', 'çıŃ'] +['æİ¥', 'åħ¥'] +['çĦ¶åIJİ', 'åĨį'] +['åѦçĶŁ', '们'] +['é¢ĨåħĪ', 'çļĦ'] +['çģ«', 'çĥŃ'] +['ä¸ĵ', 'èģĮ'] +['æĪĸèĢħ', '说'] +['建', 'è¨Ń'] +['é»', 'ı'] +['对', 'åħ¬åı¸'] +['çī¹', 'æľīçļĦ'] +['åħī', 'èį£'] +['å½ĵ', 'åľº'] +['éĿ¢', 'åŃIJ'] +['èµĦ产', '管çIJĨ'] +['æĹ¶æľŁ', 'çļĦ'] +['çŀ', 'İ'] +['åįİ', '举'] +['åıĪ', 'ä¸Ģ次'] +['èĥİ', 'åĦ¿'] +['å®ļ', 'çĤ¹'] +['头', 'çĹĽ'] +['æ¶²', 'ä½ĵ'] +['æĺ¯ä¸Ģ', 'ä½į'] +['帽', 'åŃIJ'] +['å¹´', 'èµ·'] +['ä¸į', 'ä½İäºİ'] +['è¾ĥ', 'å°ij'] +['éĿ¢ä¸´', 'çĿĢ'] +['å±Ĥ', 'å±Ĥ'] +['èĿ´', 'èĿ¶'] +['èī°', 'èĭ¦'] +['éĺ¿', 'æł¹'] +['éĺ¿æł¹', 'å»·'] +['æ¦Ĥ', 'æĭ¬'] +['请', 'éĹ®'] +['èµ·', 'åºĬ'] +['å±Ģ', 'å±Ģéķ¿'] +['稳', 'åģ¥'] +['å¦Ĥæŀľ', 'æĪij们'] +['éħĴ', 'ç²¾'] +['æĪ·', 'åı£'] +['æĦŁ', 'æĤŁ'] +['æĪij们', 'éľĢè¦ģ'] +['æĬĢ', 'èīº'] +['èĩª', 'åªĴä½ĵ'] +['è¿Ľ', 'åĮĸ'] +['æ¿ĢçĥĪ', 'çļĦ'] +['ä½ĵ', '温'] +['èļ', 'ķ'] +['èĩ´', 'è¾ŀ'] +['宪', 'æ³ķ'] +['ä¸Ģ', 'çŃīå¥ĸ'] +['çĵ¶', 'é¢Ī'] +['æĥł', 'æ°ij'] +['èµ°', 'è·¯'] +['çݰ', 'ä»»'] +['åķĨ', 'éĩı'] +['ä¸ĭ', '车'] +['åĪ', 'ł'] +['責', 'ä»»'] +['èŀįåIJĪ', 'åıijå±ķ'] +['ç´ł', 'æĿIJ'] +['æ²¹', 'ä»·'] +['åģļ', '人'] +['çŀ', 'ª'] +['æĶ¹éĿ©', 'åĪĽæĸ°'] +['çļĦ', 'åĮºåĪ«'] +['è·¨å¢ĥ', 'ç͵åķĨ'] +['æ¶īåıĬ', 'åΰ'] +['æīĺ', '管'] +['æĪij', 'è¿ĺæĺ¯'] +['åĿIJ', 'æłĩ'] +['ç½ij', '讯'] +['å½ĵåľ°', 'çļĦ'] +['追', '溯'] +['åľŁ', 'è̳'] +['åľŁè̳', 'åħ¶'] +['åºķ', 'ä¸ĭ'] +['åĩł', 'åįģå¹´'] +['ç©¿', 'è¿ĩ'] +['çĶŁæĢģ', 'æĸĩæĺİ'] +['æİ¨', 'èĸ'] +['æİ¨èĸ', '¦'] +['éł', 'Ĩ'] +['åĴ³', 'åĹ½'] +['åĪĨ', 'æĪIJ'] +['çĹķ', '迹'] +['æĪ·', 'ç±į'] +['éĥ½', 'ä¸įèĥ½'] +['æĻļ', 'ä¼ļ'] +['åĢ', '©'] +['ä½ĵ', 'åĬĽ'] +['è¿Ļ个', 'èģĮä¸ļ'] +['æĹł', 'å½¢'] +['åıª', 'æĥ³'] +['è¿Ľ', 'åıĸ'] +['æĿĢ', 'æŃ»'] +['èĦ', 'Ĭ'] +['äºij', 'åįĹçľģ'] +['æľª', 'çŁ¥'] +['ç¾İ', 'èģĶ'] +['ç¾İèģĶ', 'åĤ¨'] +['å¤ĸ', 'å½¢'] +['诱', 'æĥij'] +['çĽ', '£'] +['è¡Į', '使'] +['åłĨ', '积'] +['çĨŁ', 'ç»ĥ'] +['éĺIJ', 'è¿°'] +['æľĢ大', 'éĻIJ度'] +['å·¡', 'æŁ¥'] +['夺', 'åĨł'] +['ä¼ģä¸ļ', 'æĸĩåĮĸ'] +['çĭ®', 'åŃIJ'] +['ä¿Ŀ', 'å®Ī'] +['ä¸ºæł¸å¿ĥ', 'çļĦ'] +['æī©', 'æķ£'] +['åζéĢł', 'åķĨ'] +['æŁĶ', '软'] +['为ä¸Ģä½ĵ', 'çļĦ'] +['游', 'çİ©'] +['çĶŁ', 'çĹħ'] +['幫', 'åĬ©'] +['åͱ', 'æŃĮ'] +['æīį', 'åı¯ä»¥'] +['宽', 'æĿ¾'] +['è¦ģ', 'æ¯Ķ'] +['æĺ¯', 'æĢİæł·'] +['çģ°', 'èī²'] +['çİĭ', 'åĽ½'] +['æIJħ', 'æĭĮ'] +['计', 'éĩı'] +['åij¨åĽ´', 'çļĦ'] +['æĻºèĥ½', 'æīĭæľº'] +['常', 'åĬ¡'] +['常åĬ¡', 'åī¯'] +['é©', '´'] +['å°Ĩ', 'è¿ij'] +['寻', '常'] +['ä¸ŃåĽ½', 'å¸Ĥåľº'] +['容', 'åύ'] +['å±±', 'ä¸Ĭ'] +['èĥĮåIJİ', 'çļĦ'] +['亲', 'å¯Ĩ'] +['æīĢ以', '说'] +['éİ', '®'] +['çļĦ', 'çIJĨçͱ'] +['大', 'åŁİå¸Ĥ'] +['常', 'å¹´'] +['æĹħ游', 'ä¸ļ'] +['å°±æĺ¯', 'è¿Ļæł·'] +['åĨį', 'æĿ¥'] +['é«ĺ', 'ä½į'] +['åĨħ', '饰'] +['æŀĦ', 'éĢł'] +['ä¸Ģ', 'èµ·æĿ¥'] +['çͳ', 'è«ĭ'] +['å·²ç»ı', 'å¼Ģå§ĭ'] +['çļĦ', 'åĬ¨ä½ľ'] +['被', 'è¿«'] +['éģį', 'å¸ĥ'] +['åīĸ', 'æŀIJ'] +['å°ı', 'äºĭ'] +['å¿ĥ', 'ä¸ŃçļĦ'] +['ä½ĵåζ', 'æĶ¹éĿ©'] +['çļĩ', 'å®¶'] +['æķĻ', 'åłĤ'] +['åIJĥ', 'å®Į'] +['åĽ½æ°ij', 'åħļ'] +['æĺİç¡®', 'äºĨ'] +['åıijå±ķ', 'è§ĦåĪĴ'] +['第ä¸Ģ', 'æŃ¥'] +['å¾Ĺ', 'èµ·'] +['åľ¨', 'åĵª'] +['çļĦ', 'è·¯ä¸Ĭ'] +['é»', 'Ķ'] +['çķ¶', 'æĻĤ'] +['大åĬĽ', 'æĶ¯æĮģ'] +['åıĮ', 'éĩį'] +['çŁ¥éģĵ', 'èĩªå·±'] +['åIJĪä½ľ', 'åįıè®®'] +['æ°Ķ', 'åĬ¿'] +['éķ¿æķĪ', 'æľºåζ'] +['ç½ķ', 'è§ģ'] +['åĽŀ', 'æĿ¥äºĨ'] +['ä»ĸ', 'ä¼ļ'] +['ä¸Ń', 'æĸ°'] +['ä¸Ńæĸ°', 'ç½ij'] +['çļĦ', 'åķĨåĵģ'] +['èµł', 'éĢģ'] +['決', 'å®ļ'] +['å¸Ĥåľº', 'çĽij管'] +['çķĻ', 'åѦçĶŁ'] +['ç͵', 'åİĭ'] +['äºļ', '马'] +['äºļ马', 'éĢĬ'] +['è¿ĺæĺ¯', 'æ¯Ķè¾ĥ'] +['ä¿ĥè¿Ľ', 'äºĨ'] +['æµģ', 'åħ¥'] +['æijĦ', 'åĥı'] +['æijĦåĥı', '头'] +['æıIJ', 'åıĬ'] +['åıij', 'æİĺ'] +['æī¾', 'åĩº'] +['æ¢Ŀ', 'ä»¶'] +['ç¹¼', 'çºĮ'] +['æĪij', 'åĸľæ¬¢'] +['å¥', 'İ'] +['æ¦ľ', 'æł·'] +['å¼Ģ', 'èĬ±'] +['æ²ī', 'éĩį'] +['åŁº', 'åĩĨ'] +['ä»ħä»ħ', 'æĺ¯'] +['轨éģĵ', '交éĢļ'] +['åĶIJ', 'å±±'] +['çŃī', 'ä¸Ģç³»åĪĹ'] +['ä¸įè¿ĩ', 'æĺ¯'] +['åŃĺåľ¨', 'çĿĢ'] +['èĬ±', 'çĶŁ'] +['å¤', '·'] +['ç»Ī', 'ç©¶'] +['ä¹Łæĺ¯', 'ä¸Ģ个'] +['åįģ', 'åŃĹ'] +['èĸª', 'éħ¬'] +['伤', 'å¿ĥ'] +['æĺ¥', 'ç§ĭ'] +['åĨ·', 'åį´'] +['ç²¾', 'çģµ'] +['çļĦ', 'åľ°åĽ¾'] +['æ¯Ķ', 'çī¹'] +['æ¯Ķçī¹', 'å¸ģ'] +['æĢ§', 'åĪ«'] +['ä½Ļ', 'ä¸ĩåħĥ'] +['ä¸įå¿ĺ', 'åĪĿå¿ĥ'] +['å¿ĥ', 'çĸ¼'] +['æĽ²', '线'] +['é«ĺ', 'ä½İ'] +['è¦ı', 'å®ļ'] +['æĻ¯', 'èī²'] +['è¦ģ', '说'] +['åħ¬åı¸', 'å°Ĩ'] +['æ¶²', 'åİĭ'] +['è¿Ŀ', '约'] +['åİļ', '度'] +['åºŀ', '大çļĦ'] +['è¿ĺæĺ¯', 'å¾Ī'] +['é¦ĸåħĪ', 'æĺ¯'] +['çµ', '²'] +['åĬ¡', 'å®ŀ'] +['並', 'ä¸Ķ'] +['å¢ŀ', 'è¿Ľ'] +['ç»Ħç»ĩ', 'å¼Ģå±ķ'] +['èµ·æĿ¥', 'äºĨ'] +['è¾ĥ', 'å°ı'] +['导', '游'] +['两', 'åľ°'] +['ç¿', 'ĺ'] +['çģ¿', 'çĥĤ'] +['é£İ', 'éĩĩ'] +['æĶ¯', '线'] +['æĶ¯çº¿', 'ä»»åĬ¡'] +['娱ä¹IJ', 'åľĪ'] +['天津', 'å¸Ĥ'] +['åĮħ', 'åĽ´'] +['æľ¬', 'èµĽåŃ£'] +['éĩįè¦ģ', '讲è¯Ŀ'] +['åıĮ', 'åIJij'] +['åįİ', '丽'] +['éĶ', '¤'] +['åĦ¿', '女'] +['åįĸ', 'åĩº'] +['ä¾Ĩ', '說'] +['ä»ĭç»į', 'ä¸Ģä¸ĭ'] +['åIJ¦', '认'] +['åĭ', 'Ŀ'] +['æĻ®éĢļ', '人'] +['çļĦ', 'åĬ¨åĬĽ'] +['涨', 'åģľ'] +['åŁºéĩij', '管çIJĨ'] +['ä¸Ģ个', 'éĩįè¦ģ'] +['è¿IJ', 'æ²³'] +['çħ', 'ŀ'] +['è´¢æĶ¿', 'éĥ¨'] +['è¡Įä¸ļ', 'åįıä¼ļ'] +['éĥ½', 'å°Ĩ'] +['è¨Ģ', '论'] +['ä¸ĭ', 'ä¾Ĩ'] +['墨', '西'] +['墨西', 'åĵ¥'] +['åĽłä¸º', 'ä»ĸ们'] +['æĢİä¹Ī', 'åĽŀäºĭ'] +['åĬłå¤§', '对'] +['èĬ', 'Ń'] +['çīĮ', 'åŃIJ'] +['ä¼ļ', '使'] +['妹', 'åŃIJ'] +['ç«Ļ', 'éķ¿'] +['å¿ħ', 'å¤ĩ'] +['æłij', 'æľ¨'] +['æģ¶', 'æĦı'] +['æ²³', 'éģĵ'] +['å¯Į', 'è£ķ'] +['ç¹ģ', 'åįİ'] +['代表', 'åĽ¢'] +['æµij', '身'] +['é¦ĸ', 'ä½į'] +['èĪªç©º', 'åħ¬åı¸'] +['鼻', 'å½±'] +['ä¸ĵ', 'è¾ij'] +['æ°´', 'æºIJ'] +['ä¸Ń', 'æ¯Ĵ'] +['並', 'ä¸į'] +['èĢĮ', 'åİ»'] +['é', 'ĥĿ'] +['äºİ', 'æŃ¤'] +['æĸĩåĮĸ', '建设'] +['èĤ¯å®ļ', 'ä¼ļ'] +['å¸ĮæľĽ', '大家'] +['æıı', 'åĨĻ'] +['ä½İ', 'è°ĥ'] +['æĸ°åħ´', '产ä¸ļ'] +['æ·Ħ', 'åįļ'] +['æĶ¾', 'å¼Ģ'] +['çļĦ', 'æĢ§æł¼'] +['çĸ¾çĹħ', 'çļĦ'] +['æķ´', 'é¡¿'] +['线ä¸Ĭ', '线ä¸ĭ'] +['éĢī', '项'] +['çļĦ', '认åı¯'] +['æķ´', 'é½IJ'] +['çĶļ', 'ä¹Ī'] +['çľģ', 'åĨħ'] +['åı¤', '人'] +['æ°ij', 'ä¿Ĺ'] +['çī¡', '丹'] +['éŨ', 'çªĹ'] +['éĤ£', 'æł·çļĦ'] +['çĽijäºĭ', 'ä¼ļ'] +['ç¿¡', 'ç¿ł'] +['ç¦', '¹'] +['åįĥä¸ĩ', 'ä¸įè¦ģ'] +['æĶ¶', '缩'] +['çļĦ', 'æĸĩåŃĹ'] +['åĴĮ', 'å°ļ'] +['æĮĩ', '令'] +['åħ±äº§', 'åħļåijĺ'] +['çļĦ', 'çĪ¶äº²'] +['å®Į', 'å·¥'] +['åĬ¡', 'å·¥'] +['马', 'æĭī'] +['马æĭī', 'æĿ¾'] +['æµĭ', 'è¯Ħ'] +['å²', 'ļ'] +['ä¸į', 'åģļ'] +['ä¸ĥ', 'å¹´'] +['åĿĩ', 'ä»·'] +['主', 'è§Ĥ'] +['å¾Ī', 'ä¸įéĶĻ'] +['èĤ¡ä¸ľ', '大ä¼ļ'] +['äºĶ', 'ä¸Ģ'] +['é£İ', 'åIJ¹'] +['å¼Ģ', 'éĩĩ'] +['è¿Ļä¹Ī', '大'] +['èĥ½', 'çľĭåΰ'] +['èĢĥ', 'è¯Ħ'] +['åį³', '便æĺ¯'] +['çݰ代', 'åĨľä¸ļ'] +['æ¯Ķè¾ĥ', 'é«ĺ'] +['è¦ģ', 'çľĭ'] +['没', 'äºĨ'] +['è§£', '決'] +['çݯ', 'æ¯Ķ'] +['åĨ²', 'åĬ¨'] +['æ·±', 'å¤ľ'] +['åĩł', 'åįĥ'] +['ä¿', 'ı'] +['ç½ij', 'æ°ij'] +['å°±', '没'] +['ä»ĸ', '表示'] +['éĩı', 'åŃIJ'] +['æĹ©é¤IJ', 'åĬłçĽŁ'] +['åįĬ', 'å²Ľ'] +['æIJŀ', 'ç¬ij'] +['ä¸Ĭ', 'æĬ¥'] +['å¯', '©'] +['é¢Ħ', '订'] +['èľĤ', 'èľľ'] +['æŁ¥', 'æī¾'] +['ä¼Ĺ', 'æīĢ'] +['ä¼ĹæīĢ', 'åij¨'] +['ä¼ĹæīĢåij¨', 'çŁ¥'] +['æĹ©', 'æĹ¥'] +['åıij', 'æī¬'] +['åĴĮ', '个人'] +['åĬłåħ¥', 'äºĨ'] +['åĸ®', 'ä½į'] +['åĪĨ', 'æĺİ'] +['第ä¸Ģ', 'æī¹'] +['ç¾İ', 'åĨĽ'] +['æĿĢ', 'æīĭ'] +['éŨ', 'å¤ĸ'] +['åķĨ', 'åľĪ'] +['ä¸Ģ', 'åĪ»'] +['çļĦçľ¼', 'ç¥ŀ'] +['éľ', 'Ħ'] +['äºĽ', 'ä»Ģä¹Ī'] +['åĬł', 'æ·±'] +['æ¯ı', 'ä½į'] +['å¸Ĥ', 'éĿ¢ä¸Ĭ'] +['åıĶ', 'åıĶ'] +['çļĦ', 'éĤ£ç§į'] +['粤', '港澳'] +['è´´', 'å¿ĥ'] +['æĸĩåĮĸ', '产ä¸ļ'] +['红', 'æĹĹ'] +['åĺī', 'åħ´'] +['æĶ¶', 'çĽĺ'] +['å®ĮæĪIJ', 'åIJİ'] +['ä¼ģä¸ļ', '管çIJĨ'] +['纵', '横'] +['ä¸į', 'ä¿¡'] +['æĪIJ', 'éĥ½å¸Ĥ'] +['æ´Ĺ', '澡'] +['举è¡Į', 'çļĦ'] +['çĶ¢', 'çĶŁ'] +['ç©¿', 'ä¸Ĭ'] +['åĪļ', '好'] +['åħī', '线'] +['æīĵ', 'æŀ¶'] +['è¿Ļ', 'æľ¬ä¹¦'] +['åĶ®åIJİ', 'æľįåĬ¡'] +['åĩł', 'åĪĨ'] +['ä¸Ĭ', '次'] +['ä¸į', 'åĪĨ'] +['产', 'åIJİ'] +['éģ¿', 'å¼Ģ'] +['ç»Ī', 'æŀģ'] +['代表', '大ä¼ļ'] +['æ¼Ķ', 'æĬĢ'] +['åĽŀ', 'è´Ń'] +['åѦ', 'è´¹'] +['éĺ»', 'ç¢į'] +['ä¸Ģ大', 'æī¹'] +['ç«£', 'å·¥'] +['åĨ³', 'å®ļäºĨ'] +['ä½Ĩ', 'å¦Ĥæŀľ'] +['ç͵', 'æµģ'] +['ä¸Ŀ', '毫'] +['èĥ½å¤Ł', 'åľ¨'] +['éĶĢåĶ®', 'æĶ¶åħ¥'] +['åľ¨', 'åŃ¦æł¡'] +['æ°´', 'åĩĨ'] +['è§Ĩ', '线'] +['èĩª', 'åľ¨'] +['åķĨä¸ļ', 'éĵ¶è¡Į'] +['为äºĨ', '让'] +['çį²', 'å¾Ĺ'] +['çݩ家', 'æľĭåıĭ'] +['éĿ¢', 'èĨľ'] +['åĪĨ', 'åī²'] +['åī§', 'æľ¬'] +['ç«', 'Ń'] +['说', 'å¾Ĺ'] +['æĥ³', 'çŁ¥éģĵ'] +['çļĦ人', 'çī©'] +['èĮħ', 'åı°'] +['åIJĮ', 'ä¸Ģ个'] +['æķ°æį®', 'ä¸Ńå¿ĥ'] +['çĶ', 'Ħ'] +['åĸľ', 'æĤ¦'] +['ä¸ĭæĿ¥', 'çļĦ'] +['å®ļ', 'åIJij'] +['æŀģ', 'åħ·'] +['çļĦ', 'åľŁåľ°'] +['éĤ£', 'åĢĭ'] +['æijĦ', 'åħ¥'] +['äºĨ', 'æĪijçļĦ'] +['马', 'è·¯'] +['åħ¨', '社ä¼ļ'] +['è®®', 'æ¡Ī'] +['å±ĭ', 'åŃIJ'] +['åIJį', 'åı«'] +['åĮ', 'ª'] +['åľ¨', 'å¤ĸéĿ¢'] +['åįİ', 'åįĹ'] +['åıij', 'è´§'] +['å¯Ĵ', 'åĨ·'] +['é«ĺçŃī', 'æķĻèĤ²'] +['详ç»Ĩ', 'çļĦ'] +['个', 'é¡¹çĽ®'] +['çĶŁäº§', 'åĬĽ'] +['æĹ¶', '常'] +['å°±', 'æľĥ'] +['ä¸ĩ', 'èĤ¡'] +['éĻĮçĶŁ', '人'] +['æıı', 'ç»ĺ'] +['å½ĵ', 'çĦ¶æĺ¯'] +['æĭī', 'åĬ¨'] +['éĵ¾', 'æĿ¡'] +['æī£', 'éϤ'] +['ä¸Ģ缴', 'éĥ½'] +['å°ı', 'åŃ©åŃIJ'] +['伤', 'åı£'] +['第äºĮ', 'å±Ĭ'] +['è´Ń', 'ç½®'] +['çļĩ', '马'] +['æĹł', 'èģĬ'] +['表', 'åĨ³'] +['诸', 'å¦Ĥ'] +['åĵį', 'èµ·'] +['é£İ', 'æļ´'] +['ä¸Ģæµģ', 'çļĦ'] +['ç', '·¨'] +['è§£æĶ¾', 'åĨĽ'] +['室', 'å¤ĸ'] +['å°±', 'è¿Ļä¹Ī'] +['å³', '¶'] +['æīĢæľī', '人éĥ½'] +['æIJľç´¢', 'å¼ķæĵİ'] +['çļĦ', 'æĪIJæľ¬'] +['åħļ', 'æĶ¿'] +['åıijè¡Į', '人'] +['çļĦ', 'äºĭå®ŀ'] +['对', '该'] +['åıĹ', 'æįŁ'] +['ä¿Ħ', 'ä¹Į'] +['é²ľ', 'èĬ±'] +['åĨľ', 'èį¯'] +['æŀģ', 'éĢŁ'] +['æĢ¥', 'æĢ§'] +['两', 'ä¼ļ'] +['ä¸Ģèά', 'æĿ¥è¯´'] +['æµ·', 'é²ľ'] +['åĨ', 'Ī'] +['ç͍', '人'] +['çĶ¨äºº', 'åįķä½į'] +['åĢ', 'ª'] +['åĦª', 'æĥł'] +['æł¹', 'æºIJ'] +['åĽ¢', 'è´Ń'] +['ç¾İ', 'æ´²'] +['ä¸ĭ', 'è¡Į'] +['å¹´', 'æľ«'] +['èľ', '¡'] +['è¯ģ', 'ä»¶'] +['åľ¨', 'æĪijåĽ½'] +['ä¸į', 'åºĶ'] +['æĮī', 'æĹ¶'] +['åłª', 'ç§°'] +['åľº', 'ä¸Ĭ'] +['å¹²éĥ¨', 'èģĮå·¥'] +['æľī', 'å¾Ī大çļĦ'] +['æķ°åŃĹ', 'ç»ıæµİ'] +['æ¼Ķ', 'ç»ĥ'] +['æį®', 'ç»Łè®¡'] +['å¾Ģ', 'æĿ¥'] +['广åijĬ', 'æľįåĬ¡'] +['çļĦ', 'è·Ŀ离'] +['æŃ', '¸'] +['è¨Ģ', 'è¯Ń'] +['被', 'èªī'] +['被èªī', '为'] +['åĭī', '强'] +['å°Ĭ', 'æķ¬'] +['ä¸ĩ', '亿åħĥ'] +['ä¸ŃåĽ½', 'åĽ½éĻħ'] +['å¹²', 'é¢Ħ'] +['å¹´', '产'] +['èĢķ', 'åľ°'] +['èĮ', 'İ'] +['åį³', 'æĺ¯'] +['æĺ¨', 'æĻļ'] +['æĪIJ为', 'ä¸Ģ个'] +['çºł', 'æŃ£'] +['åij½', 'åIJį'] +['é¢ģ', 'å¸ĥ'] +['çĮľ', 'æµĭ'] +['ä¿ĿèŃ·', 'æĶ¿çŃĸ'] +['æĭ', '¢'] +['æ´»', 'æ³¼'] +['çŃī', 'éĥ¨éŨ'] +['åѦ', 'åΰ'] +['å¢ŀå̼', 'ç¨İ'] +['èĪª', '线'] +['åĨ', '¤'] +['åįģ', 'åĩłå¹´'] +['æİ§èĤ¡', 'èĤ¡ä¸ľ'] +['ä¸Ģ', 'éŨ'] +['个', 'å·¥ä½ľ'] +['ä¸ªå·¥ä½ľ', 'æĹ¥'] +['æĸ°', '西'] +['æĸ°è¥¿', 'åħ°'] +['论', 'è¯ģ'] +['ä»', 'Ĩ'] +['åı¦å¤ĸ', 'ä¸Ģ个'] +['æĶ¹', 'ç¼ĸ'] +['严', 'ç¦ģ'] +['åĸľ', '好'] +['个人', 'ä¿¡æģ¯'] +['满æĦı', '度'] +['åĵ', '¨'] +['å¸Ī', 'èµĦ'] +['æĶ¹', '为'] +['ç«ŀäºī', '对æīĭ'] +['åĩº', 'çĤī'] +['åķĨ', '人'] +['大', 'æ£ļ'] +['æĮĩ导', 'ä¸ĭ'] +['å¦ĩ', 'ç§ij'] +['è¼', 'ª'] +['æī', 'ģ'] +['åIJĮæĹ¶', 'è¿ĺ'] +['å¹¶', 'éĢļè¿ĩ'] +['æĪĺ', 'éĺŁ'] +['èĶĵ', 'å»¶'] +['ä¿', 'ŀ'] +['éĢĤå½ĵ', 'çļĦ'] +['åīį', 'è¾Ī'] +['åĵģ', 'åij³'] +['湿', 'åľ°'] +['æĪIJ', 'åŀĭ'] +['ä¸į', 'åıªæĺ¯'] +['æĥ©', 'ç½ļ'] +['åĩºåı°', 'äºĨ'] +['çİ©', '游æĪı'] +['æīį', 'åıijçݰ'] +['åºĶ', 'èģĺ'] +['å¤ĸ', 'æĿ¥'] +['åįł', 'é¢Ĩ'] +['å±ķ', 'æľĽ'] +['å«', 'Ĥ'] +['港', 'èĤ¡'] +['æ¡Į', 'ä¸Ĭ'] +['æĶ¯', 'æŁ±'] +['çļĦæĥħ', 'å½¢'] +['广éĺĶ', 'çļĦ'] +['æĶ¯', 'è¡Į'] +['å´©', 'æºĥ'] +['æľĪ', 'ä¸Ń'] +['æľĪä¸Ń', 'æĹ¬'] +['ç»į', 'åħ´'] +['临', 'è¿ij'] +['æĬ¤', 'æłı'] +['æļ', '®'] +['åįķ', 'èģĮä¸ļ'] +['è¾¹', 'å¢ĥ'] +['æĹ¥', 'çħ§'] +['ä¸Ģ', 'åłĨ'] +['缴', 'å¾Ħ'] +['åħ±åIJĮ', 'ä½ĵ'] +['æĸ°åįİ', 'ç½ij'] +['æīĵ', '好'] +['ç͵åĬ¨', '汽车'] +['ä¸į', 'æĺİçϽ'] +['éĢĻ', '裡'] +['缼', '大'] +['çİĭ', 'æľĿ'] +['åĨį', 'ä¸Ģ次'] +['åĬŀåħ¬', 'åİħ'] +['è´¨', 'æĬ¼'] +['åIJĪ', 'åĩ»'] +['人们', '对'] +['鼶', 'é£Ł'] +['éĥ½ä¸į', 'çŁ¥éģĵ'] +['çļĦ', 'è¯Ńè¨Ģ'] +['åĭŁéĽĨ', 'èµĦéĩij'] +['åĬ¨', 'èĦī'] +['å½', '¤'] +['è¿Ļ', 'åĩłå¹´'] +['çŁŃ', 'è§Ĩé¢ij'] +['太', 'é«ĺ'] +['常', 'å§Ķä¼ļ'] +['åĬł', 'çıŃ'] +['éĩį', 'å¿ĥ'] +['åªĴä½ĵ', 'æĬ¥éģĵ'] +['没', 'æ³ķ'] +['éĹ»', 'åIJį'] +['çĥŃ', '度'] +['å¹¿æ³Ľ', 'çļĦ'] +['åħŃ', '大'] +['çī©', 'ä½ĵ'] +['ä¸į', '该'] +['é¢ĺ', '主'] +['精彩', 'çļĦ'] +['为', 'è¿Ľä¸ĢæŃ¥'] +['èĻ', 'ŀ'] +['åĽº', 'çĦ¶'] +['è´µå·ŀ', 'çľģ'] +['çºł', 'ç»ĵ'] +['代çIJĨ', '人'] +['æ³ķå®ļ', '代表'] +['åı¦ä¸Ģ', 'ç§į'] +['ä¸į', 'åIJ«'] +['æĭ¯', 'æķij'] +['ä¼ļ', 'ç»Ļ'] +['è¯Ĺ', 'è¯į'] +['åIJĮ', 'ç±»'] +['å¾Ĺ', 'ä¸įåΰ'] +['æĬĵ', 'ç´§'] +['以', 'åħ¶'] +['åħ¥', 'åħļ'] +['è¿ĺ', 'åı¯'] +['æľŁ', 'åĪĬ'] +['å¾Īå¤ļ', 'æĹ¶åĢĻ'] +['æĹ¥', 'åIJİ'] +['åħ¬', '约'] +['ä¸Ģ', '举'] +['æ¯Ķè¾ĥ', 'å¤ļ'] +['éĩij', 'æ²Ļ'] +['æį', 'ŀ'] +['æİĴ', 'åĩº'] +['æŃ¦', 'æľ¯'] +['ä¸į', 'æĸ·'] +['ä¸Ń', 'èĢĥ'] +['ä¿¡', 'èµĸ'] +['ä»İä¸ļ', '人åijĺ'] +['çģ«', 'çĦ°'] +['éĨĴ', 'æĿ¥'] +['ä½İ', '温'] +['é̾', 'æľŁ'] +['åĬ±', 'å¿Ĺ'] +['éħ', '¥'] +['åı¯è°ĵ', 'æĺ¯'] +['è¿Ļ', 'æĦıåij³çĿĢ'] +['é¢ł', 'è¦Ĩ'] +['åĮĹ京', '大åѦ'] +['ä¸ĵ', '线'] +['åıĬ', '以ä¸Ĭ'] +['è¨', 'ª'] +['èĢĮ', 'åIJİ'] +['çŁ¥', 'ä¹İ'] +['ä¸Ģ对', 'ä¸Ģ'] +['å¨ĥ', 'å¨ĥ'] +['çģ¾', 'éļ¾'] +['åħ¨', 'å±Ģ'] +['æīĢå¾Ĺ', 'ç¨İ'] +['å®ŀ', 'æĥł'] +['èļĤ', 'èļģ'] +['ä¹Ł', 'çŁ¥éģĵ'] +['温', 'åĴĮ'] +['èIJ½', 'ä¸ĭ'] +['åŀĭ', 'ä¼ģä¸ļ'] +['åĨį', 'ä¹Ł'] +['ä¾Ľ', 'çĥŃ'] +['é«ĺ', 'æ½®'] +['çĢı覽', 'åύ'] +['çļĦ', '巨大'] +['åħĪ', '天'] +['å¹´', 'ä¸ŃåĽ½'] +['类似', 'çļĦ'] +['çIJĨäºĭ', 'ä¼ļ'] +['空', 'éĸĵ'] +['çģµ', 'æĦŁ'] +['åĬĽ', 'æ°Ķ'] +['带', 'ä¸Ĭ'] +['ä¸į好', 'æĦıæĢĿ'] +['æľī', 'ä½ķ'] +['å·²', 'åľ¨'] +['åıĸ', 'åĩº'] +['è¿Ŀæ³ķ', 'çĬ¯ç½ª'] +['åŃ¦ä¹ł', '贯彻'] +['åľ°', '带'] +['楼', '梯'] +['çŃī', 'æĥħåĨµ'] +['ä»İ', 'åīį'] +['çļĦ', 'ä¹łæĥ¯'] +['ç³Ł', 'ç³ķ'] +['å°±', 'èĥ½å¤Ł'] +['è©', 'ķ'] +['ä¸Ģ', 'å¾ĭ'] +['æĮ«', 'æĬĺ'] +['åİŁæĸĩ', 'åľ°åĿĢ'] +['å½ĵ', 'å±Ģ'] +['ä¸į', 'éĢļ'] +['æķ°', 'åįĥ'] +['éĺŁä¼į', '建设'] +['æĹ¶', 'èĬĤ'] +['åģļ', 'èµ·'] +['çļĦ', 'è®°å¿Ĩ'] +['ç½ij绾', 'å®īåħ¨'] +['åĩ¡', 'æĺ¯'] +['æ°', '¯'] +['éĽķ', 'åĪ»'] +['åŁĥ', 'åıĬ'] +['æĪij', 'åı¯ä»¥'] +['çĽij', 'çIJĨ'] +['æĽ´', 'åħ·'] +['åŁİ', '管'] +['èĭ', '¯'] +['åı¥', 'åŃIJ'] +['èĭ¥', 'æľī'] +['ä»İæĿ¥', 'ä¸į'] +['缸åħ³', 'è´Łè´£'] +['å®īåħ¨', 'æĦŁ'] +['æĽ´', 'è¦ģ'] +['çļĦæĥħ', 'æĦŁ'] +['çī¢', 'çī¢'] +['è¾ĥ', '好çļĦ'] +['æ°', '®'] +['ç¬ij', 'è¯Ŀ'] +['车', 'å±ķ'] +['ä¹ĭ', 'ç¾İ'] +['ç®Ģ', '约'] +['ç±»åŀĭ', 'çļĦ'] +['èĢģ', 'åĮĸ'] +['çľĭ', 'ä½ł'] +['è¿ĩ', 'åĪĨ'] +['éŨ', 'åīį'] +['ä¸Ģ', 'éĹ´'] +['æĥ³', 'åİ»'] +['åª', 'Ľ'] +['åľŁ', 'è±Ĩ'] +['åıĪ', 'ç§°'] +['ä¸Ń', 'ä¿¡'] +['åŃĺ', 'éĩı'] +['马', 'äºij'] +['èĩ´', '使'] +['åħĪ', 'åīį'] +['èĢģ', 'åŃIJ'] +['æīĵ', 'æī®'] +['æ¯ķä¸ļ', 'äºİ'] +['æ¯ķä¸ļ', 'åIJİ'] +['ç¾İ好', 'çĶŁæ´»'] +['å·¥ä¸ļ', 'ä¼ģä¸ļ'] +['就好', 'äºĨ'] +['èħIJ', 'èļĢ'] +['çıį', 'çıł'] +['åΰ', 'è¿ĻéĩĮ'] +['æīĢéľĢ', 'çļĦ'] +['è¿Ļæĺ¯', 'åĽłä¸º'] +['çIJĨæĥ³', 'çļĦ'] +['å·®å¼Ĥ', 'åĮĸ'] +['é', '®'] +['é®', '®'] +['äºļ', '太'] +['æĹł', 'ç©·'] +['æıIJ', 'çݰ'] +['ä¸ĵä¸ļ', 'æĬĢæľ¯'] +['çĶ¢', 'æ¥Ń'] +['åѦ', 'åŃIJ'] +['ç§ij', 'å¹»'] +['åįłåľ°', 'éĿ¢ç§¯'] +['ä¸į', 'åĩĨ'] +['æľªæĪIJ', '年人'] +['æĶ¶', 'å½ķ'] +['è¿ĺ', '款'] +['éĴ¢', 'çŃĭ'] +['æ¼', '¢'] +['å¾Ĺ', 'æĦı'] +['综åIJĪ', 'ä½ĵ'] +['æŀģ', 'é«ĺ'] +['åįķ', 'è¯į'] +['é«ĺæķĪ', 'çļĦ'] +['骨', '头'] +['æī§', 'çĿĢ'] +['缼', 'ä¸ĸ'] +['模', 'çī¹'] +['æĽ´', 'èĥ½'] +['ç»Ŀ', 'æľĽ'] +['对åºĶ', 'çļĦ'] +['æ¨', 'Ĭ'] +['æĸ°', 'ä¸ī'] +['æĸ°ä¸ī', 'æĿ¿'] +['æģ°', 'æģ°'] +['åIJį', 'å®¶'] +['æł¸å¿ĥ', 'æĬĢæľ¯'] +['个', 'å°ı'] +['æĢİä¹Ī', 'ä¼ļ'] +['说', 'ä¸įå®ļ'] +['西', 'çĵľ'] +['åĵ', 'İ'] +['ç¢', 'Ł'] +['å¿ħ', 'ä¸įåı¯'] +['å¿ħä¸įåı¯', 'å°ij'] +['ä¹ĭ', 'éĸĵ'] +['åĪĨ', '管'] +['交éĢļ', 'äºĭæķħ'] +['å¼Ģ', 'åĬŀ'] +['å¾ģæ±Ĥ', 'æĦıè§ģ'] +['äº', '¨'] +['鼻åŃIJ', 'éĥµ'] +['鼻åŃIJéĥµ', 'ä»¶'] +['ä¿¡æģ¯', 'æľįåĬ¡'] +['ä½ł', 'è§īå¾Ĺ'] +['缴', 'è§Ĥ'] +['å·²', 'å®ĮæĪIJ'] +['åĪĨ', 'ä¼ļ'] +['åĽŀ', 'åįĩ'] +['éļ', '»'] +['好', '人'] +['äºĨè§£', 'ä¸Ģä¸ĭ'] +['åį«', 'æµ´'] +['æľĢ', 'çα'] +['åºŀ', '大'] +['客', 'æĪ¿'] +['çijŀ', 'åħ¸'] +['éĥ½', 'ä¸įæĺ¯'] +['é¤', '¨'] +['èĹ', 'ī'] +['çļĦ', 'åIJĦ项'] +['为', '缮æłĩ'] +['çļĦ', 'è®¤çŁ¥'] +['å½±åĵįåĬĽ', 'çļĦ'] +['夸', 'å¼ł'] +['佩', 'æĪ´'] +['æ±ĩ', 'çİĩ'] +['çļĦ', 'çαæĥħ'] +['æĺ¥', 'é£İ'] +['æĺ¯', 'æĪijçļĦ'] +['æ¨', '¹'] +['åįĬ', 'å°ıæĹ¶'] +['å±±', 'åİ¿'] +['å±±', '西çľģ'] +['èĢĮ', 'è¿Ļ'] +['æĽ´å¤ļ', 'ä¿¡æģ¯'] +['è¿ĺ', 'æľīä¸ĢäºĽ'] +['ç²¾', 'ç»ĨåĮĸ'] +['ç¾İ', 'åѦ'] +['çͱ', 'æĸ¼'] +['ä»ħä¾Ľ', 'åıĤèĢĥ'] +['å¾Ī', 'é«ĺçļĦ'] +['åıł', 'åĬł'] +['è¿Ļä¹Ī', '说'] +['å±ķ', 'åĩº'] +['åĽĽ', 'å¤Ħ'] +['ä¸ĩ', 'å®¶'] +['æĭĽ', 'åĭŁ'] +['çļĦ', '强大'] +['æĤ£', 'æľī'] +['å°ı', 'äºİ'] +['ä¹Łè®¸', 'æĺ¯'] +['对', 'èĩªå·±çļĦ'] +['èģĮä¸ļ', 'æķĻèĤ²'] +['æĿ¥', 'è¿Ľè¡Į'] +['æ¡£', '次'] +['æīĵ', 'èµ¢'] +['éĥ½æľī', 'çĿĢ'] +['åº', '¸'] +['è¯Ń', 'æ°Ķ'] +['çͲ', 'éĨĽ'] +['空', 'åĨĽ'] +['车', 'åĨħ'] +['åĽłä¸º', 'ä½ł'] +['å®ŀ', 'æķĪ'] +['æĥħ', 'ä¾£'] +['åıijè¾¾', 'åĽ½å®¶'] +['éķľ', 'åŃIJ'] +['æ¯į', 'å©´'] +['ä½Ĩæĺ¯', 'ä»ĸ'] +['积æŀģ', 'æİ¨è¿Ľ'] +['大å¹ħ', '度'] +['çļĦ', '女åĦ¿'] +['é¤IJ', 'æ¡Į'] +['åIJ¬', 'å¾Ĺ'] +['çļĦ', '积æŀģæĢ§'] +['好', 'åIJ§'] +['æĹ¥', 'æ¶Īæģ¯'] +['æľī', 'ä»»ä½ķ'] +['æ¯Ĵ', 'åĵģ'] +['æĹ©çĤ¹', 'åĬłçĽŁ'] +['第ä¸Ģ', '天'] +['å°½', 'åĬĽ'] +['æł', 'ĸ'] +['主', 'æīĵ'] +['æĺ¯ä¸Ģ', 'åIJį'] +['çĪĨ', 'æĸĻ'] +['äºĭä¸ļ', 'åıijå±ķ'] +['å¾®', 'åķĨ'] +['äºİä¸Ģä½ĵ', 'çļĦ'] +['çĶŁ', 'çĮª'] +['èĩªçĦ¶', 'èµĦæºIJ'] +['çŀĦ', 'åĩĨ'] +['è§Ħ模', 'åĮĸ'] +['å¹¶', 'ä¸İ'] +['èĤ¥', 'èĥĸ'] +['å®¶', 'ç͍'] +['大', 'çĪ·'] +['é¢Ħ', 'åijĬ'] +['æĿ¥', 'åģļ'] +['éĺ³', 'åİ¿'] +['æŀĦ', 'çŃij'] +['é¢ģ', 'å¥ĸ'] +['åİĨåı²', 'æĸĩåĮĸ'] +['æľįåĭĻ', 'æĪĸ'] +['æĢ»', 'åĨ³èµĽ'] +['åıij', 'åŀĭ'] +['æĪij', '羣çļĦ'] +['æĽ', '¦'] +['åıĤ', 'ä¼ļ'] +['èĦĨ', 'å¼±'] +['åĩĨ', 'åħ¥'] +['èħ¹', 'éĥ¨'] +['åı¸', '令'] +['æĤ²', 'åī§'] +['天', 'ä¸Ĭ'] +['åı£', 'ä¸Ń'] +['ä¸ĩ', '个'] +['åѦ', 'ä¸ļ'] +['æıIJ', 'åĢ¡'] +['两', 'è¾¹'] +['大', 'èĤ¡ä¸ľ'] +['åı¤', 'éķĩ'] +['è¡Ģ', 'ç³ĸ'] +['çļĦ', 'ç¨ĭ度'] +['æ£ī', 'èĬ±'] +['åIJİ', 'åı°'] +['å°±', 'åĮ»'] +['æķ´', 'æķ´'] +['èĴ', '²'] +['çĽĪåĪ©', 'èĥ½åĬĽ'] +['ç±', '½'] +['èĦ', '«'] +['çľĭ', 'éĩį'] +['å®¶', 'éķ·'] +['èģĺ', 'ç͍'] +['èµĽ', 'éģĵ'] +['åīį', 'èĢħ'] +['建', 'èѰ'] +['å¾ĭå¸Ī', 'äºĭåĬ¡'] +['èīºæľ¯', 'åĵģ'] +['æľī', 'èĩªå·±çļĦ'] +['åIJ¦', 'å®ļ'] +['社', 'åĽ¢'] +['åij¨', 'äºĶ'] +['带', 'åΰ'] +['å·¥ä½ľ', 'ä¼ļè®®'] +['èĤ¡', 'æľ¬'] +['å¤ĸ', 'åĮħ'] +['å®¶', 'åħ¬åı¸'] +['çĽij', 'çĭ±'] +['èĪ', 'Ĭ'] +['åIJį', 'æł¡'] +['西', 'æ¹ĸ'] +['è¶ħè¿ĩ', 'äºĨ'] +['åįĹ', 'å±±'] +['ç»Ħ', 'ä»¶'] +['å̼å¾Ĺ', '注æĦı'] +['æĮ£', 'æīİ'] +['äºĭ', '迹'] +['ç¶ĵ', 'çĩŁ'] +['ç§ij', '室'] +['好', 'åIJĹ'] +['æ¤ħ', 'åŃIJ'] +['åľĪ', 'åŃIJ'] +['ä½Ĩ', '她'] +['æµģ', 'çķħ'] +['åIJĦèĩª', 'çļĦ'] +['èģĮ', 'åijĺ'] +['è¡į', 'çĶŁ'] +['åħ¨', 'åľº'] +['æĴ¤', 'éĶĢ'] +['åį´', '被'] +['å®ģ', 'éĿĻ'] +['åīį', 'æīĢ'] +['åīįæīĢ', 'æľª'] +['åīįæīĢæľª', 'æľī'] +['主', 'ä¸ļ'] +['åĮĹ', 'ç¾İ'] +['è¯Ħ', 'å®ļ'] +['åĵģ', 'å°Ŀ'] +['大家', 'éĥ½åľ¨'] +['主', 'å¸ħ'] +['ç»Ĩ', 'å¿ĥ'] +['ä¿¡æģ¯', 'æĬ«éľ²'] +['çļĦ', 'ç«ŀäºī'] +['éĢĻæ¨£', 'çļĦ'] +['ç§ijåĪĽ', 'æĿ¿'] +['éĩĩ', 'æijĺ'] +['票', 'æį®'] +['éĢIJ', 'å¹´'] +['èĭ±', 'è¶ħ'] +['è¡Įä¸ļ', 'åĨħ'] +['人', '寿'] +['åIJİ', 'åĭ¤'] +['å¦Ĥ', 'æĦı'] +['ç¬Ķ', 'è¯ķ'] +['æ·¡æ·¡', 'çļĦ'] +['ä¸į', 'èĪĴæľį'] +['ä½ĵ', '积'] +['ä¹Łä¸į', 'è¦ģ'] +['éĿ¢', 'æĸĻ'] +['æł·', 'æľ¬'] +['ç¥', 'ģ'] +['æĮī', 'è§Ħå®ļ'] +['大æ¦Ĥ', 'æĺ¯'] +['æĥħåĨµ', 'è¿Ľè¡Į'] +['åIJĦ', 'åįķä½į'] +['çļĦ', 'ç¬ij容'] +['åĩºèī²', 'çļĦ'] +['代表', 'æĢ§'] +['çļĦ', 'ç¾İ好'] +['éĴ', '¦'] +['å¾®', 'çĶŁçī©'] +['è¶Ĭ', 'æĺ¯'] +['æĸ¹', 'åı¯'] +['å¹²', 'èĦĨ'] +['éģĬ', 'æĪ²'] +['çļĦ', 'åħ´è¶£'] +['éĹ®', 'è´£'] +['åĽłä¸º', 'æĪij们'] +['èĢĥ', 'éĩı'] +['çĶŁ', 'çĶŁ'] +['éĺ»', 'åĬĽ'] +['ä¸į', 'åħģ许'] +['æıIJ', 'è®®'] +['åĩı', 'æĮģ'] +['åıªæĺ¯', 'ä¸Ģ个'] +['æĪij', 'æĬĬ'] +['åıijçݰ', 'èĩªå·±'] +['å¢ŀ', 'å¹ħ'] +['å¦', 'į'] +['èĹĿ', 'è¡ĵ'] +['ä¸Ģå®¶', '人'] +['åĪĨ', '级'] +['çļĦ', 'æķ°éĩı'] +['è½®', 'èŀįèµĦ'] +['çŃī', 'åĽłç´ł'] +['大', '夫'] +['èģĺ', '请'] +['é£İ', 'æľº'] +['绽', 'æĶ¾'] +['ä»»ä½ķ', 'ä¸Ģ个'] +['éł', 'Ĥ'] +['éĺ¶', '级'] +['æĬĬ', '她'] +['è¿Ľ', 'åĨĽ'] +['èĥ½', 'åģļåΰ'] +['åŁ¹è®Ń', 'æľºæŀĦ'] +['çī©', 'æĸĻ'] +['ç«¥', 'è¯Ŀ'] +['æĮĩ导', 'æĦıè§ģ'] +['éĺ', '®'] +['æ·±åħ¥', 'æİ¨è¿Ľ'] +['主', 'æľº'] +['æ¸Ķ', 'ä¸ļ'] +['ä¸į', 'æľį'] +['æµĵ', 'éĥģ'] +['è¡Ĺ', 'ä¸Ĭ'] +['ä¾Ŀ', '次'] +['æĹ¶', '段'] +['æ¢', 'µ'] +['çļĦ', 'åĸľçα'] +['å¾Ī', 'éķ¿'] +['åĪĿ', '级'] +['æŀľ', 'æĸŃ'] +['æĬ¢', 'æķij'] +['é¼ĵ', 'èĪŀ'] +['ä¾Ľ', 'éľĢ'] +['æ·±åħ¥', 'å¼Ģå±ķ'] +['产ä¸ļ', 'éĽĨ群'] +['åĻª', 'éŁ³'] +['åIJ¬', 'çĿĢ'] +['æ·±åĪ»', 'çļĦ'] +['å¿į', 'åıĹ'] +['ç͵', 'ç£ģ'] +['强', 'èĢħ'] +['æ»ĭ', 'åij³'] +['æĽ¼', 'èģĶ'] +['åı¯ä»¥', '缴æİ¥'] +['大', 'ç±³'] +['æŃ·', 'åı²'] +['æĶ¿åĬ¡', 'æľįåĬ¡'] +['åħ¬', 'å¼ı'] +['社', '群'] +['éģĵ士', 'èģĮä¸ļ'] +['ä¹ĭ', 'æĥħ'] +['æµ·', 'æ°´'] +['æ¼Ķ', 'å¥ı'] +['åºĹ', 'éĩĮ'] +['迹', '象'] +['åıijå±ķ', 'çIJĨ念'] +['é«ĺ', '空'] +['åij¨', 'åĪĬ'] +['åĽŀ', 'åΰäºĨ'] +['ä¸į', 'éĢĤåIJĪ'] +['åłµ', 'å¡ŀ'] +['åĬ', 'Ī'] +['æ°´', 'ä¸Ĭ'] +['çĢij', 'å¸ĥ'] +['纳ç¨İ', '人'] +['çĩĥ', 'æ²¹'] +['å·¥ç¨ĭ', 'é¡¹çĽ®'] +['峡', 'è°·'] +['æľī', 'éĴĪ对æĢ§'] +['åľĨ', 'å½¢'] +['æľ¬', 'å¸Ĥ'] +['è¿Ļ', 'è¯Ŀ'] +['管çIJĨ', 'èĢħ'] +['ç¡®è¯Ĭ', 'çĹħä¾ĭ'] +['æĬĬ', 'æīĭ'] +['彩', 'èī²'] +['ä¸Ĭ', 'åīį'] +['夯', 'å®ŀ'] +['ç¾Ĭ', 'èĤī'] +['å¾Ģ', 'å¹´'] +['æĵħ', 'èĩª'] +['è¿·', '人'] +['èĪª', 'æ¯į'] +['ç²¾', 'ç»Ĩ'] +['åľ¨', 'æĪijçļĦ'] +['åĪĽ', 'æĬķ'] +['麦', 'åħĭ'] +['æľĪ', 'ç»ı'] +['åĮĹ', 'æµ·'] +['ä¹ĭ', 'æĺŁ'] +['åı¶', 'åŃIJ'] +['å¸Ĥåľº', 'ç«ŀäºī'] +['è¿Ļ', 'äºĭ'] +['åıĥ', 'èĪĩ'] +['产', 'åľ°'] +['åĶ', 'ī'] +['åķĨåĵģ', 'æĪ¿'] +['èĪª', 'è¿IJ'] +['ä¼ĺ', 'å¼Ĥ'] +['ä»ĸ们', 'æĺ¯'] +['鼨', 'æ°´'] +['è¯į', 'æ±ĩ'] +['åĨľ', 'çͰ'] +['欧', 'éĺ³'] +['çŁŃ', '线'] +['管', 'ç½ij'] +['æł¹', 'åŁº'] +['åıªæľī', 'ä¸Ģ个'] +['éŀĭ', 'åŃIJ'] +['å¸Ĥ', 'å§Ķ书记'] +['åĪ»', 'æĦı'] +['è¡Į', '车'] +['åıĪ', '被'] +['åı¯éĿł', 'æĢ§'] +['è´', '±'] +['ä»»', 'åij½'] +['åºĶ', 'åľ¨'] +['å°±', 'å¾Ĺ'] +['æľįåĬ¡', 'ä½ĵç³»'] +['æĶ¿', 'æĿĥ'] +['åıijè¨Ģ', '人'] +['è¿ĩ', 'å¾Ģ'] +['两', 'åıª'] +['èϽ', '说'] +['éĢģ', 'ä¸Ĭ'] +['ä»Ģä¹Ī', 'äºĭ'] +['æķ£', 'æĸĩ'] +['æİĮ', 'æİ§'] +['èĸĦ', 'å¼±'] +['ä¸ĭéĿ¢', 'å°±'] +['主è¦ģ', 'åĨħ容'] +['å¾Ī', 'éĩįè¦ģçļĦ'] +['å°±', '说'] +['çϽèī²', 'çļĦ'] +['éĤ£ä¸ª', 'æĹ¶åĢĻ'] +['ç»ı纪', '人'] +['çļĦ', 'æ¯į亲'] +['ç¬Ķè®°', 'æľ¬'] +['åºķ', 'å±Ĥ'] +['è¿ij', '代'] +['è§£', '说'] +['è²ł', '責'] +['æľĢ大', 'åĮĸ'] +['åķĨ', 'éĵº'] +['æł¡', 'åıĭ'] +['æ²', 'ģ'] +['ä¸į', 'åĩºæĿ¥'] +['éĻ·', 'éĺ±'] +['ç¨', 'ħ'] +['åħ¬å¸ĥ', 'äºĨ'] +['åĩĢ', 'å̼'] +['çĽ¸å¯¹', 'è¾ĥ'] +['ç¬', 'Ľ'] +['æł¸', 'ç®Ĺ'] +['åįİ', '侨'] +['æĢ¥', 'æķij'] +['æĮº', '好'] +['åħĴ', 'ç«¥'] +['äºĮ', 'èĥİ'] +['åĩº', 'èĩª'] +['åĿ', 'Ł'] +['æīĭ', 'ä¸ĭ'] +['å±', '¡'] +['åĪĽéĢł', 'æĢ§'] +['ä¸¥æł¼', 'æĮīçħ§'] +['åĨį', 'åİ»'] +['举', '缣'] +['人', 'æµģ'] +['äºĨä¸Ģ', '声'] +['å°ıæĹ¶', 'åīį'] +['è´µ', 'æĹı'] +['éľ', 'ĸ'] +['ä¹Łæĺ¯', 'éĿŀ常'] +['éĢ', '±'] +['çľĭäºĨ', 'çľĭ'] +['ç¹ģ', 'æ®ĸ'] +['èĩ³', 'æŃ¤'] +['é¢Ħ', 'å¤ĩ'] +['å¾Ī', 'æĺİæĺ¾'] +['æ¼Ķ', 'èīº'] +['åĿIJ', 'çĿĢ'] +['ä¿Ħ', 'åĨĽ'] +['åľ¨', 'è¿ĩåİ»'] +['ä¹ĭ', 'äºĭ'] +['æĬĵ', 'èİ·'] +['åĿIJ', 'ä¸ĭ'] +['çͱ', 'ä¸ŃåĽ½'] +['ä¹Ł', 'å¼Ģå§ĭ'] +['çŃĶ', 'å¤į'] +['åŀĥåľ¾', 'åĪĨç±»'] +['éĴĵ', 'é±¼'] +['åIJĦ', '種'] +['缸', 'éģĩ'] +['ä¸įåģľ', 'çļĦ'] +['æī¹', 'éĩı'] +['éĩįè¦ģ', 'ä½ľç͍'] +['å§Ķ', 'å±Ī'] +['åħŃ', 'å¹´'] +['ä¸ĥ', 'åįģ'] +['ä¹ĭ', 'æĪĺ'] +['é£İéĻ©', '管çIJĨ'] +['éŁ³', 'æ¨Ĥ'] +['è¡ĮæĶ¿', 'å¤Ħç½ļ'] +['æľ¬', 'äºĭ'] +['æĴ°', 'åĨĻ'] +['èģļ', 'åIJĪ'] +['éĢĤ', 'æĹ¶'] +['æIJ¬', 'å®¶'] +['ç¢İ', 'çīĩ'] +['缼', 'å®´'] +['ç®Ģ', 'æ´ģ'] +['åı¬', 'éĽĨ'] +['ç®Ģ', 'åĮĸ'] +['åĮĹ京', 'æĹ¶éĹ´'] +['第ä¸ī', 'å±Ĭ'] +['æĿ¥', 'åĽŀ'] +['常ç͍', 'çļĦ'] +['京', 'æ´¥'] +['京津', 'åĨĢ'] +['梦', 'å¹»'] +['è¯ķ', 'è¡Į'] +['æľº', 'åºĬ'] +['åΰ', 'æľĢåIJİ'] +['åĬ©', 'æīĭ'] +['åĪĨ', '彩'] +['åĩº', 'åĵģ'] +['åι', '车'] +['åIJ¯', 'åıij'] +['ä¾§', 'éĿ¢'] +['æ¯ı', 'å½ĵ'] +['缸åħ³', 'è§Ħå®ļ'] +['ä¸ĸ', '人'] +['è´Ń', '车'] +['å¿ĥ', '缮'] +['å¿ĥ缮', 'ä¸Ń'] +['äºĶ', 'éĩij'] +['è¿ĺ', 'è®°å¾Ĺ'] +['ä¾Ŀ', 'çĦ¶æĺ¯'] +['æıIJ', 'æ¡Ī'] +['ç͵åķĨ', 'å¹³åı°'] +['åģļ', 'åΰäºĨ'] +['æĿľ', 'ç»Ŀ'] +['å®ī', 'åįĵ'] +['ä¸ĸçķĮ', 'åIJĦåľ°'] +['åīį', 'éĢĶ'] +['æ´Ĺ', 'åĩĢ'] +['å¥ĭ', 'åĬĽ'] +['åŁİå¸Ĥ', '建设'] +['å¤ļ', 'åĬŁèĥ½'] +['ä¼ļ', 'éĢłæĪIJ'] +['åıijå¸ĥ', 'ä¼ļä¸Ĭ'] +['ç©¶', '竣æĺ¯'] +['åĪĨ', '红'] +['çŁ¥', 'èŃĺ'] +['éĿ¢', 'æĿ¿'] +['æĹł', '声'] +['æĢ¥', 'éľĢ'] +['失', 'çľł'] +['çΏ', 'å¦Ī'] +['äº', 'Ĥ'] +['åħ¨', 'æĻ¯'] +['ç»ıåħ¸', 'çļĦ'] +['åī§', 'ä¸Ń'] +['é¢Ĩ导', 'ä¸ĭ'] +['åħļ', 'åĨħ'] +['åħ¥', 'ä¾µ'] +['æĭī', 'æĸ¯'] +['ä¸Ģ', 'å¹ķ'] +['åĬł', 'ä¹ĭ'] +['èĤ', 'Ĩ'] +['èĭ±', 'æł¼'] +['èĭ±æł¼', 'åħ°'] +['å·§', 'åħĭ'] +['å·§åħĭ', 'åĬĽ'] +['ä¸Ģ', 'å¿ĥ'] +['èģ', 'Ĥ'] +['å¾Ģå¾Ģ', 'æĺ¯'] +['管çIJĨ', 'å±Ĥ'] +['çĻ»', 'åħ¥'] +['建ç«ĭ', 'èµ·'] +['建', 'åĽ½'] +['åŃIJ', '宫'] +['åºĶ', 'ä»ĺ'] +['æİ¢', 'ç©¶'] +['第ä¸Ģ', 'ä½į'] +['ä½Ļ', 'å®¶'] +['çŃī', 'æ´»åĬ¨'] +['æīĢ', 'èĩ´'] +['è¾ĥ', 'å¿«'] +['æĺ¯', 'éĿŀ'] +['æıIJ', 'åIJį'] +['äºĮ', 'èĢħ'] +['åıªåī©', 'ä¸ĭ'] +['åħ¶ä¸Ń', 'åĮħæĭ¬'] +['ç¼ĸ', 'ç¨ĭ'] +['çł´', 'ç¢İ'] +['ä¸Ń', '举'] +['å·¥ä½ľ', 'æĬ¥åijĬ'] +['çѾ', 'åIJį'] +['éħĴ', 'ä¸ļ'] +['çŁ¥', 'æĻĵ'] +['çĥŃ', 'å¿ĥ'] +['éĿŀ', 'åĩ¡'] +['èIJ¥ä¸ļ', 'æī§'] +['èIJ¥ä¸ļæī§', 'çħ§'] +['人大', '代表'] +['ä¸Ģ个', 'æĸ°çļĦ'] +['å¨ģ', 'æµ·'] +['éĤ£', '人'] +['涨', 'ä»·'] +['æ¶Ī', 'çģŃ'] +['éļ¾', 'å¿ĺ'] +['ç¶ĵ', 'é©Ĺ'] +['åı£', 'è¢ĭ'] +['ç³»', 'æķ°'] +['æĸĩ', 'ä¸Ń'] +['好', '转'] +['æĸ°', '鼶åĶ®'] +['讲述', 'äºĨ'] +['å¼Ģ', 'çĽĺ'] +['çķĻ', 'ç»Ļ'] +['æħ¢æħ¢', 'çļĦ'] +['æĤ²', '伤'] +['æľ¬', 'æľŁ'] +['äºĨ', 'å¤ļå°ij'] +['è¿Ļ', '让'] +['åIJĮ', 'çŃī'] +['æ¸ħ', 'æĺİ'] +['个', 'åŁİå¸Ĥ'] +['æºĸ', 'åĤĻ'] +['åĩłä¹İ', 'æĺ¯'] +['强', 'åĬĽ'] +['ä¿', '¯'] +['æ°´', '稻'] +['åĽºå®ļ', 'çļĦ'] +['æł¸', 'åĩĨ'] +['说', 'æľį'] +['顯', '示'] +['è¿Ļ', 'å¥Ĺ'] +['æĻºæħ§', 'åŁİå¸Ĥ'] +['å±ĭ', 'é¡¶'] +['ä¸į', 'æĿ¥'] +['çĶŁ', 'é²ľ'] +['çŁ¥', 'æĥħ'] +['æĬķ', '身'] +['åijĬè¯ī', 'æĪij们'] +['ä¸ī', 'åĽĽ'] +['ä¸ĩ', 'ä¸Ģ'] +['è¾Ĩ', '车'] +['为', 'ä¹ĭ'] +['åΰ', 'æĹ¶åĢĻ'] +['è¿Ļ', 'æīįæĺ¯'] +['åIJį', 'çīĮ'] +['åºŁ', 'æ°´'] +['åݻ年', 'åIJĮæľŁ'] +['å¹´', 'éĻIJ'] +['éģĭ', 'åĭķ'] +['åıĮ', 'çľ¼'] +['è¦ģ', 'ç´§'] +['对', 'çŃĸ'] +['åľº', 'é¦Ĩ'] +['çϾ', 'ç§ij'] +['è¶Ĭ', 'éĩİ'] +['å¯Į', 'åIJ«'] +['大å¤ļæķ°', '人'] +['æľĢ', 'å°ij'] +['åı¬', 'åͤ'] +['åħ¸', 'èĮĥ'] +['åĨľ', 'æľº'] +['æŃ£', 'æĸĩ'] +['åºĶç͍', 'äºİ'] +['æ·±', 'èĢķ'] +['ä¿', 'Ń'] +['ä»Ģä¹Ī', 'ä¸ľè¥¿'] +['å¥Ĺ', 'é¤IJ'] +['å½ĵ', 'éĢī'] +['å·¦', 'æīĭ'] +['è°ĥ', 'çIJĨ'] +['æĻļ', 'é¤IJ'] +['éļ¾', 'åħ³'] +['åĩŃ', 'è¯ģ'] +['çα', '人'] +['æĮĩ', 'è´£'] +['è´£', 'ç¼ĸ'] +['çļĦä¸Ģ', '款'] +['éĵ', '²'] +['åįģ', '个'] +['èĢ', '»'] +['æľįåĬ¡', 'åķĨ'] +['åľ°', 'çĭ±'] +['è¿ŀ', 'å¿Ļ'] +['åĽ°', 'æĥij'] +['çļ', 'ĵ'] +['ä¸į', 'åIJĥ'] +['çİ°åľ¨', 'å·²ç»ı'] +['çĽĺ', 'çĤ¹'] +['ä¸įåģľ', 'åľ°'] +['管çIJĨ', '模å¼ı'] +['è¿Ļ', '段æĹ¶éĹ´'] +['æ¤', '°'] +['礼', 'åĮħ'] +['æµģ', '转'] +['æī«', 'çłģ'] +['éĽĨä¸Ń', 'åľ¨'] +['æ±Ĥ', 'åĬ©'] +['åįĬ', '个'] +['å¿«éĢŁ', 'å¢ŀéķ¿'] +['å¾Ģ', 'ä¸ĭ'] +['è¯Ħ', 'åĪĨ'] +['å°±', 'æĥ³'] +['åķĨåĬ¡', 'éĥ¨'] +['æľī', 'éĹ®é¢ĺ'] +['èİ·', 'åĪ©'] +['æ¯Ľ', 'çĹħ'] +['æĦŁ', 'åºĶ'] +['èī¯', 'æĢ§'] +['åĪĨ', 'æŃ§'] +['åĨ', 'ī'] +['æĪij们', 'çİ°åľ¨'] +['è¦ģ', 'åĬłå¼º'] +['å·§', 'å¦Ļ'] +['èŀº', 'æĹĭ'] +['åĪĩ', 'æį¢'] +['çĭ', 'Ħ'] +['顺', 'çķħ'] +['å°¤åħ¶', 'æĺ¯åľ¨'] +['èĬĿ', '麻'] +['éļ¾', 'è¿ĩ'] +['æĹĹ', 'å¸ľ'] +['å¤į', 'åį°'] +['å¤įåį°', 'ä»¶'] +['å¿ħ', 'éľĢ'] +['对å¤ĸ', 'å¼ĢæĶ¾'] +['éļ¾', 'åıĹ'] +['åİŁæĿ¥', 'æĺ¯'] +['ç®Ĺ', 'äºĨ'] +['é«ĺ', 'å±±'] +['离', 'èģĮ'] +['çµĦ', 'ç¹'] +['çµĦç¹', 'Ķ'] +['å±ģ', 'èĤ¡'] +['çϾ', 'å®¶'] +['éģĩ', 'ä¸Ĭ'] +['æĺĶ', 'æĹ¥'] +['ä¸į', '容'] +['çĽij管', 'éĥ¨éŨ'] +['主', 'æĦı'] +['æµģ', 'åŁŁ'] +['è·Į', 'å¹ħ'] +['èĩ³', 'ä¸Ĭ'] +['åĪ«', '说'] +['æĺ¯', 'æ¯Ķè¾ĥ'] +['å®ıè§Ĥ', 'ç»ıæµİ'] +['å¸Ĥåľº', '主ä½ĵ'] +['污æŁĵ', 'çī©'] +['æķij', 'æ²»'] +['丰', 'æĶ¶'] +['åŃĺ', 'æĶ¾'] +['åĩ', 'Ħ'] +['éĩij', 'å±±'] +['æį¢', 'äºĨ'] +['ä¸ĵ', '人'] +['éĹľ', 'æĸ¼'] +['æĹ¢', 'è¦ģ'] +['åĽ½', 'è¶³'] +['éļ', 'ĭ'] +['åıį', 'åĩ»'] +['èµ·', '身'] +['åħĪ', 'æĺ¯'] +['å¸ĮæľĽ', 'èĥ½å¤Ł'] +['åζ', '订'] +['åºĹ', 'éĿ¢'] +['åĸ', 'Ģ'] +['æķĻ', 'ä½ł'] +['éĻį', '温'] +['åĬĽ', 'æ±Ĥ'] +['ä¸ī', 'çϾ'] +['çī©', 'ä»·'] +['丢', '失'] +['å¢Ļ', 'ä¸Ĭ'] +['éĥ¨', '份'] +['æł·', 'æĿ¿'] +['ä¹ĭ', 'æĦı'] +['ç½ij', 'å°ıç¼ĸ'] +['ä¸ĸ', 'ä¸Ĭ'] +['è°ĥ', 'è¯ķ'] +['污æŁĵ', 'éĺ²æ²»'] +['å½±', 'éĻ¢'] +['å®Įåħ¨', 'åı¯ä»¥'] +['éĢļ', 'åħ³'] +['ä¹īåĬ¡', 'æķĻèĤ²'] +['没æľī', 'åĬŀæ³ķ'] +['èĢ', '¿'] +['å¦', '³'] +['æĹł', 'æĥħ'] +['å¾Ĺ', 'çĽĬ'] +['å¾ĹçĽĬ', 'äºİ'] +['æľŁ', 'çĽ¼'] +['娱ä¹IJ', 'åľº'] +['çͲ', 'æĸ¹'] +['ä¸Ģ', 'æ±½'] +['çĹ', '°'] +['çĸij', 'ä¼¼'] +['æĸ°æµª', 'å¾®åįļ'] +['强', 'è¡Į'] +['å½ĵ', 'ä»ĸ'] +['èĥ', 'º'] +['ç͍æĪ·', 'æıIJä¾Ľ'] +['åĮº', 'å§Ķ'] +['æĦ¿', 'æĻ¯'] +['æĬĺ', 'æī£'] +['失', '踪'] +['è¿«', 'åĪĩ'] +['åŃĹ', 'æ¯į'] +['åĴ', '¯'] +['èªį', 'èŃĺ'] +['ä»Ģä¹Ī', 'æĦıæĢĿ'] +['çĽĴ', 'åŃIJ'] +['å½ķ', 'éŁ³'] +['建设', 'å·¥ç¨ĭ'] +['ä¸ļ', 'ä½Ļ'] +['å®ŀè·µ', 'æ´»åĬ¨'] +['羣', '空'] +['çĤ', 'ĸ'] +['åľ¨', 'è·¯ä¸Ĭ'] +['主è¦ģ', 'åĮħæĭ¬'] +['该', 'æĢİä¹Ī'] +['æĢ»', 'æľī'] +['æĢ§', 'æĦŁ'] +['æ°ij', 'èĪª'] +['å¼Ģ', 'åºĹ'] +['欺', 'éªĹ'] +['çªģ', 'åĩ»'] +['缺', '失'] +['æī§', 'ä¸ļ'] +['åľ°', 'éģĵ'] +['å¹¶', 'æĹł'] +['æ°ij', 'åĬŀ'] +['ç»Ħç»ĩ', 'çĶŁæ´»'] +['æĪij', 'å¦Ī'] +['è¨ĺ', 'èĢħ'] +['管', 'åζ'] +['æī¾', '个'] +['èĹ', '»'] +['çĤİ', 'çĹĩ'] +['äºĴ', 'åĬ©'] +['æµıè§Ī', 'åύ'] +['çݩ家', 'æĿ¥è¯´'] +['éĻįä½İ', 'äºĨ'] +['è£', 'Ķ'] +['æĮ£', 'éĴ±'] +['åķĨ', 'æľº'] +['æĶ¹', 'è£ħ'] +['æµģ', '浪'] +['æĶ¿', 'æ³ķ'] +['èĢģ', '头'] +['çĶŁäº§', 'åĴĮ'] +['ç©', 'Ĺ'] +['亲', 'çα'] +['亲çα', 'çļĦ'] +['å±¥', 'èģĮ'] +['åŁİ', 'éĩĮ'] +['ç»Ĩ', 'åĪĨ'] +['åĬ³åĬ¨', 'åIJĪåIJĮ'] +['åľ¨', 'æĹ¥æľ¬'] +['å¨ģ', 'å°Ķ'] +['åį«', 'è§Ĩ'] +['éĢ£', 'çµIJ'] +['çĿĢ', 'éĩį'] +['æĬĺ', '磨'] +['åĽ¾', '为'] +['çľ', '·'] +['å·¥', 'åºı'] +['æĵ', 'ģ'] +['æĵģ', 'æľī'] +['ç½ijç«Ļ', 'åľ°åĽ¾'] +['çļĦä¸Ģ', '大'] +['ç»Ħç»ĩ', 'å®ŀæĸ½'] +['æĬĽ', 'å¼ĥ'] +['åĴĮ', 'æĶ¯æĮģ'] +['æ³ķ', 'åĪĻ'] +['浪', 'æ½®'] +['çݰ', 'æľīçļĦ'] +['åĩł', 'çİĩ'] +['为', '客æĪ·'] +['åįģ', 'ä¸ĩ'] +['è', '¹Ħ'] +['çªģåĩº', 'éĹ®é¢ĺ'] +['åıĥ', 'åĬł'] +['éĥ½ä¼ļ', 'æľī'] +['çĽ', '¤'] +['è°ģ', 'éĥ½'] +['æīĭ', 'åĬ¨'] +['缴', 'è¾¾'] +['çĤ¹', 'å¤ļ'] +['éĺ¶', 'å±Ĥ'] +['ä¸į', 'ä½³'] +['éĤ£', '段'] +['滨', 'æµ·'] +['æĺ¯', 'åĽ½åĨħ'] +['æĪij', 'å¸ĮæľĽ'] +['åIJĽ', 'åŃIJ'] +['è§Ĥ', 'éŁ³'] +['åģļ', 'é¥Ń'] +['æ±½', 'è»Ĭ'] +['åħ³', 'ç¨İ'] +['çľ¼åīį', 'çļĦ'] +['æ°´', 'éĿ¢'] +['è̳', 'æľº'] +['追', '踪'] +['æİ¨', 'éĢģ'] +['éĴ±', 'åĮħ'] +['æģ¶', 'å¿ĥ'] +['æµ·', 'åŁŁ'] +['å·', 'į'] +['å¼Ģ', 'æĿ¥'] +['表', 'æĢģ'] +['仪', '表'] +['å¹³', 'åİŁ'] +['åįģ', 'å¤ļå¹´'] +['ä¹Ł', 'æĹłæ³ķ'] +['åħ¼', '顾'] +['è¡£', 'æŁľ'] +['æł½', 'åŁ¹'] +['æĪ¿', 'æºIJ'] +['设ç«ĭ', 'äºĨ'] +['ä¸ĩ', 'åIJį'] +['æķ°', 'é¢Ŀ'] +['è¦ģ', 'åĿļæĮģ'] +['åIJīæŀĹ', 'çľģ'] +['请', 'èģĶç³»'] +['ç»ıåİĨ', 'è¿ĩ'] +['çļĦ', 'æľ¬è´¨'] +['åħ¥', 'éŨ'] +['æľ¬', 'æ¡Ī'] +['çİĩ', 'è¾¾åΰ'] +['åı°', 'éĺ¶'] +['éĴ', 'ŀ'] +['æĪij', 'èĥ½'] +['èݲ', 'èĬ±'] +['éĴ', 'ł'] +['ä¸Ģ', 'äºĭ'] +['åİŁ', 'æľīçļĦ'] +['æ¯ı', 'åĢĭ'] +['æ¯Ķäºļ', '迪'] +['æ£ĭçīĮ', '游æĪı'] +['ä¸įä¼ļ', 'æľī'] +['å½Ĵ', 'æĿ¥'] +['äºĶ', 'çϾ'] +['è¿ĩ', 'é«ĺ'] +['鼷', 'è¾¾'] +['ä¸Ģèµ·', 'åİ»'] +['æķĻ', '导'] +['å°±', 'è¯Ĭ'] +['å°±', 'å¾Ī'] +['ä¸įåIJĮ', 'äºİ'] +['ä¿', 'º'] +['å¸ĸ', 'åŃIJ'] +['æĶ¿åįı', 'å§Ķåijĺ'] +['çĸ«æĥħ', 'å½±åĵį'] +['åĪĨ', 'è£Ĥ'] +['为ä»Ģä¹Ī', 'ä¼ļ'] +['äºĶ', 'æĺŁ'] +['å°ij', 'åĦ¿'] +['æĬ¢', 'éĻ©'] +['梦', 'è§ģ'] +['è®°èĢħ', 'éĩĩ访'] +['å±±', 'è·¯'] +['æĪij', '个人'] +['æ²Ļ', '滩'] +['è¹', 'Ń'] +['æĶ¹', 'è®Ĭ'] +['æĸ°åŀĭ', 'åĨł'] +['æĸ°åŀĭåĨł', 'çĬ¶'] +['åĮ»', 'æĬ¤'] +['åĮ»æĬ¤', '人åijĺ'] +['æµ·', 'å°Ķ'] +['åħ³äºİ', 'æĪij们'] +['éϤ', 'å¤ĸ'] +['åº', 'ļ'] +['宣', 'åijĬ'] +['ä¸ī', 'åįĥ'] +['æ¦', '¨'] +['ç§ijæĬĢ', '大åѦ'] +['ä¸ĥ', 'åħ«'] +['顺', 'åºĶ'] +['çΏçΏ', 'å¦Īå¦Ī'] +['éĢī', 'åıĸ'] +['åī§', 'çĥĪ'] +['乡æĿij', 'æĹħ游'] +['积æŀģ', 'æİ¢ç´¢'] +['表çݰ', '为'] +['å¾Ī', 'æ¸ħæ¥ļ'] +['大', 'åĨĽ'] +['æĿ¥', 'ç͵'] +['å¥Ĺ', 'æĪ¿'] +['çݰ', 'è¡Į'] +['享', 'åıĹåΰ'] +['çľĭ', 'çĤ¹'] +['åĽºå®ļ', 'èµĦ产'] +['以', '人为'] +['以人为', 'æľ¬'] +['ä¸į', 'å®Į'] +['éĻį', '鼨'] +['åģļçļĦ', 'äºĭæĥħ'] +['å¹¶', 'äºİ'] +['顽', '强'] +['èĢ', '¸'] +['åĺ´', 'å·´'] +['缸åħ³', 'ä¿¡æģ¯'] +['æĪij', '没'] +['æĪĺçķ¥', 'æĢ§'] +['æĢĿ', '念'] +['åĪĺ', 'å¤ĩ'] +['åĬ©', 'æĶ»'] +['é£İ', 'è²Į'] +['éĿ¢å¯¹', 'éĿ¢'] +['积æŀģ', 'å¼Ģå±ķ'] +['çĸĹ', 'æķĪ'] +['çľĭ', '书'] +['缺', 'åı£'] +['åĽ½æ°ij', 'ç»ıæµİ'] +['使ç͍', 'æĿĥ'] +['éģ¥', 'è¿ľ'] +['å¡«', 'è¡¥'] +['第ä¸ī', '人'] +['åįĬ', 'å¤ľ'] +['æŃ¦æ±ī', 'å¸Ĥ'] +['æĪij', 'åıijçݰ'] +['ä¼ĺæĥł', 'æĶ¿çŃĸ'] +['é£İ', 'åı£'] +['å°±', 'ä¸įèĥ½'] +['为', '主è¦ģ'] +['æµģ', 'åĩº'] +['å´ĩ', 'æĭľ'] +['å¹¶', 'ä¸įèĥ½'] +['é«ĺ', 'ä¸ī'] +['ä¸ĸçķĮä¸Ĭ', 'æľĢ'] +['æĥ³', 'å¿ħ'] +['åħ¶', 'æīĢ'] +['åĢĻ', 'éĢī'] +['åĢĻéĢī', '人'] +['ä¸į', 'çα'] +['åī¯', 'ä½ľç͍'] +['人æ°ij', 'æĹ¥æĬ¥'] +['æĪij', 'ä¸įæĺ¯'] +['å®ŀ', 'çī©'] +['ç͵', 'åİĤ'] +['ä¹Ł', 'ç®Ĺæĺ¯'] +['æľī', 'éĹľ'] +['æľī', 'èĥ½åĬĽ'] +['æĮĤ', 'åľ¨'] +['çľ¼', 'ä¸ĭ'] +['约', 'ç¿°'] +['å°ı', 'åѦçĶŁ'] +['èµ·', 'åΰäºĨ'] +['å·¥', '夫'] +['åIJĮ', 'å¿ĥ'] +['åĿ¦', 'è¨Ģ'] +['çł', 'Į'] +['åıijæĮ¥', 'äºĨ'] +['èģĮä¸ļ', 'éģĵå¾·'] +['è¿ĻäºĽ', 'å¹´'] +['念', '头'] +['èĢģ', 'é¼ł'] +['åħ¨', 'èµĦ'] +['åħ¨èµĦ', 'åŃIJ'] +['ä¸Ģ', 'åij³'] +['å¤ļ', 'ä¸ĩåħĥ'] +['æł¼', 'æľĥ'] +['éķ¿', 'éĢĶ'] +['带', 'èµ°'] +['èĭ±', '寸'] +['æĸĩ', 'ä½ĵ'] +['对', 'ä»ĸ们'] +['åĵŃ', 'äºĨ'] +['å¡«', 'æĬ¥'] +['çīĪæĿĥ', '声æĺİ'] +['ç͵', '线'] +['è´Ńçī©', 'ä¸Ńå¿ĥ'] +['饱', '满'] +['ä½İ', '头'] +['强', 'è¿«'] +['ä¿Ŀ', 'æ´ģ'] +['欧', 'åĨł'] +['缸', 'è¿ŀ'] +['认', 'è´Ń'] +['çģ«', 'æĺŁ'] +['é«ĺ', 'å°Ķ'] +['é«ĺå°Ķ', '夫'] +['èij«', 'èĬ¦'] +['æłĩ', '注'] +['çļĦ', 'çIJĨæĥ³'] +['æł¸', 'éħ¸'] +['æł¸éħ¸', 'æ£Ģæµĭ'] +['åĬ', 'ī'] +['ä¸Ģèά', 'æĺ¯'] +['æĢĿ', 'ç´¢'] +['轨', '迹'] +['çĥŃ', '带'] +['éĻ', '£'] +['åĩĨç¡®', 'æĢ§'] +['æĪ´', 'çĿĢ'] +['åľ¨', 'çĶŁæ´»ä¸Ń'] +['æīĢ', 'èĥ½'] +['æľ¯', 'åIJİ'] +['带', 'ä½ł'] +['ç¥', 'ł'] +['æ®ĭ', 'éħ·'] +['ä¹Ł', 'åıªæĺ¯'] +['çͳ', 'è´Ń'] +['举åĬŀ', 'äºĨ'] +['æľī', 'æĦıä¹ī'] +['æĹº', '缼'] +['åľ¨', 'ç¶²'] +['åľ¨ç¶²', 'è·¯ä¸Ĭ'] +['å¾Ī大', 'ç¨ĭ度'] +['管', 'è¾ĸ'] +['çĸ«æĥħ', 'æľŁéĹ´'] +['触', 'æij¸'] +['éĺ¶æ®µ', 'æĢ§'] +['ä¼ļ', 'è§īå¾Ĺ'] +['çļĦ', 'çĶ»éĿ¢'] +['æİ¥åıĹ', 'äºĨ'] +['表达', 'äºĨ'] +['éĤĵ', 'å°ı'] +['éĤĵå°ı', 'å¹³'] +['åħļ', 'é£İ'] +['åħļé£İ', 'å»īæĶ¿'] +['åķĨ', 'åѦéĻ¢'] +['åħij', 'æį¢'] +['é£Łåĵģ', 'èį¯åĵģ'] +['éĿŀ常', '好çļĦ'] +['çľ', '¯'] +['纳', 'ç±³'] +['åĬ¨', 'æijĩ'] +['åĽŀ', 'éģ¿'] +['çľĭ', 'èijĹ'] +['款', '项'] +['åħ«', 'å¹´'] +['åģļ', '个'] +['æĸĩ', 'æ¡£'] +['éĩijèŀį', 'ç§ijæĬĢ'] +['åħ¶ä¸Ń', 'æľī'] +['äºĨä¸Ģ', 'ç³»åĪĹ'] +['æĹĹèΰ', 'åºĹ'] +['ç§°', 'èµŀ'] +['éĽ¢', 'éĸĭ'] +['åζ', 'åĨ·'] +['å®¶', 'éŨåı£'] +['åįģ', 'å¤ļ'] +['ä¼´', 'ä¾£'] +['çľĭ', 'çĹħ'] +['æĭī', 'çĿĢ'] +['æī', 'Ĵ'] +['çĸ²', 'æĥ«'] +['å°ijæķ°', 'æ°ijæĹı'] +['åĽ¾', 'å½¢'] +['è½', '§'] +['å¢ŀ', 'éĩı'] +['饲', 'åħ»'] +['çģ«', 'å±±'] +['æ¯ı', '个æľĪ'] +['ä½ľä¸º', 'ä¸ĢåIJį'] +['è½´', 'æī¿'] +['æĸĩ', '书'] +['ç¼', 'ķ'] +['åħ·ä½ĵ', 'æĥħåĨµ'] +['çĹĽ', 'çĤ¹'] +['缴', 'éĶĢ'] +['å¡', 'Ĭ'] +['ä¹Ł', 'æľĥ'] +['çĥŃ', 'æ½®'] +['å¹³', 'æ°ij'] +['æ¼Ķåͱ', 'ä¼ļ'] +['æķĻ', 'çłĶ'] +['éĢĥ', 'éģ¿'] +['ä¸Ģ', 'è´¯'] +['å°±', 'è¶Ĭ'] +['å®ŀ', 'å®ŀåľ¨'] +['å®ŀå®ŀåľ¨', 'åľ¨'] +['ä¹łè¿ijå¹³', 'æĢ»'] +['æº', 'º'] +['å¿ĥ', 'åºķ'] +['éķ¿', 'å¾ģ'] +['媽', '媽'] +['第ä¸ī', '次'] +['åĩº', 'æ¼Ķ'] +['çĭĢ', 'æ³ģ'] +['å°Ķ', 'æĸ¯'] +['代çIJĨ', 'åķĨ'] +['çĨ', 'ı'] +['çļĦ', '对象'] +['ç͵', 'éĩı'] +['è¡Į', 'åĪĹ'] +['åĽ½', '人'] +['è·ij', 'äºĨ'] +['åįĶ', 'åĬ©'] +['èIJ¥', 'è¿IJ'] +['å¸Ī', 'åħĦ'] +['æ¦', '®'] +['æĥ³', 'åĥı'] +['æĢ§', '强'] +['ç§ijåѦ', 'çłĶç©¶'] +['å»¶', 'å®ī'] +['ä¸¥æł¼', 'èIJ½å®ŀ'] +['é¢Ĩ', 'ä¼ļ'] +['缸', 'å·®'] +['è·¯', '人'] +['çĶ', '«'] +['æľī', 'ä»·å̼'] +['æľīä»·å̼', 'çļĦ'] +['ç¾İ', 'åĽ¢'] +['æ°ij主', 'çĶŁæ´»'] +['æĪij', 'æīį'] +['ç¾İåĽ½', '人'] +['æ°Ķ', 'åij³'] +['åıį', 'å°Ħ'] +['çļĦ', 'åĨ³å¿ĥ'] +['大', 'è±Ĩ'] +['交', '代'] +['è¿Ľ', 'åĩº'] +['åıį', 'æĬĹ'] +['æĮĩ', 'çļĦæĺ¯'] +['ä»·', 'ä½į'] +['è¿Ľ', 'é©»'] +['ä¸Ĭ', 'çϾ'] +['ä½į', 'åĪĹ'] +['ä¸ŃåĽ½', 'ä¼ģä¸ļ'] +['çļĦ好', 'å¤Ħ'] +['主', 'ç¼ĸ'] +['æ±½', 'æ²¹'] +['ä½Ĩ', 'æĪij们'] +['æĢİä¹Ī', 'çľĭ'] +['é»Ħ', 'å±±'] +['å¤ļ', 'åªĴä½ĵ'] +['åIJİ', 'åį«'] +['èİ·å¾Ĺ', 'æĽ´å¤ļ'] +['åĬ¡', 'å¿ħ'] +['为', 'å¥ijæľº'] +['é¦ĸ', '饰'] +['ä¸ĩ', 'åįļ'] +['è¶ĬæĿ¥è¶Ĭ', '大'] +['ä¸ĵ项', 'è¡ĮåĬ¨'] +['å¥ĭ', 'è¿Ľ'] +['ä»į', 'çĦ¶æĺ¯'] +['è´¨', 'æĦŁ'] +['å¦Ĥæŀľ', 'ä¸įæĺ¯'] +['ç«Ļ', 'èµ·æĿ¥'] +['ä¹¾', 'éļĨ'] +['åı¯æĢķ', 'çļĦ'] +['å¯Į', 'è´µ'] +['æ¸ħ', 'ç®Ĺ'] +['åIJij', 'ä¸ĭ'] +['åĢ', 'ļ'] +['çļĦ', 'çŃĶæ¡Ī'] +['èι', 'ä¸Ĭ'] +['çļĦ羣å®ŀ', 'æĢ§'] +['çŃī', 'åĬŁèĥ½'] +['åĸľ', 'åī§'] +['å¨ģ', 'åĬĽ'] +['æĸ°', 'é¢ĸ'] +['æł¸', 'ç͵'] +['æĬ¥', 'éĶĢ'] +['æķħ', '乡'] +['ä¼´', 'éļı'] +['éŀ', 'Ń'] +['å¦Ĭ', 'å¨ł'] +['åĪĨ', 'åĮĸ'] +['æľī', 'å¾Ī大'] +['æĢİä¹Ī', '说'] +['æĻĤ', '代'] +['产', 'åĩº'] +['ä»ĭç»į', '说'] +['å¤ĦçIJĨ', 'åύ'] +['èĨ¨', 'èĥĢ'] +['åī¯', 'å¸Ĥéķ¿'] +['çļĦ', '妻åŃIJ'] +['æł·', 'åĵģ'] +['åIJĮæ¯Ķ', 'ä¸ĭéĻį'] +['åħĥ', 'å·¦åı³'] +['ç͍', 'èĩªå·±çļĦ'] +['é«ĺ', 'éĽĦ'] +['æĺ¥', 'æĻļ'] +['ä¹Ł', 'æľīå¾Īå¤ļ'] +['çľ¼', 'çIJĥ'] +['æķ£', 'æŃ¥'] +['ä»ĸ们', 'éĥ½'] +['第ä¸Ģ', 'å®¶'] +['åĬŀ', '好'] +['å®ī', 'éĺ²'] +['ä¸Ģ', 'ä¸ĩ'] +['åľ¨', 'éĩĮéĿ¢'] +['éŁ³', 'é¢ij'] +['åı£', 'åı·'] +['ä¸Ģ', 'è¶Ł'] +['ç¦ı', 'çī¹'] +['é³', 'ŀ'] +['æĥĬ', 'èī³'] +['æĸ°', 'å¨ĺ'] +['绿èī²', 'åıijå±ķ'] +['ä¸Ń', 'å¼ı'] +['ä¹Ł', 'åıªæľī'] +['çݰ', '身'] +['åı¯', 'ä¾Ľ'] +['æ¯ı', 'ä¸Ģ个人'] +['第ä¸ī', 'èĢħ'] +['åľ°', 'å½¢'] +['éĴ¢', 'ç»ĵæŀĦ'] +['çĽijçĿ£', 'æ£ĢæŁ¥'] +['åı«', 'æĪij'] +['èĩ´', 'æķ¬'] +['æ´Ĺ', 'æīĭ'] +['ä¸ĭ', 'è°ĥ'] +['康', 'çĨĻ'] +['æĪIJ交', 'éĩı'] +['ä¹Ł', 'æĪIJ为'] +['åħī', 'æ»ij'] +['å®Įæķ´', 'æĢ§'] +['çģ', '¼'] +['ç¶²', 'éłģ'] +['éķ¿', '寿'] +['éģ©', 'ç͍'] +['çļĦä¸Ģ', '项'] +['çŀ©', '缮'] +['æĬĬ', 'èĩªå·±çļĦ'] +['éĵ¶è¡Į', 'åį¡'] +['å°±', 'å¿ħé¡»'] +['ç¾İ', 'çϽ'] +['éŀį', 'å±±'] +['æľ¬', 'é¢Ĩ'] +['ä¸Ģ', 'ç¢Ĺ'] +['æīĵ', 'æ³ķ'] +['æĤ¨', '好'] +['对', 'åŃ©åŃIJ'] +['æĬ¥éģĵ', 'ç§°'] +['ä¼ł', 'åĩº'] +['大', 'èĩ£'] +['ç¬', 'ĭ'] +['çĽ', 'ı'] +['é¾', 'ļ'] +['缴', '线'] +['æĻº', 'åºĵ'] +['ç§Ł', '车'] +['é£İ', 'åij³'] +['çľĭ', 'ä¸Ģä¸ĭ'] +['æİ¨', 'éĶĢ'] +['éĥ¨', 'éĥ¨éķ¿'] +['è´¨éĩı', 'åĴĮ'] +['åĪĬ', 'çĻ»'] +['å·¥ä¸ļ', 'åĮĸ'] +['çİĩ', '为'] +['鼶', 'ä»¶'] +['硬', 'åĮĸ'] +['ä¸Ĭ', 'åįĥ'] +['ç»ıéªĮ', 'å̼'] +['å¹³', 'è¡Į'] +['声', 'éģĵ'] +['æľįåĬ¡', 'è´¨éĩı'] +['çĶŁ', 'çĶ¢'] +['æľĢ', '容æĺĵ'] +['ä¸Ģ', 'æŀļ'] +['å¹´', 'æĬ¥'] +['åħ¬', 'ç½ij'] +['åħ¬ç½ij', 'å®ī'] +['åħ¬ç½ijå®ī', 'å¤ĩ'] +['çļĦ', 'èĥ½éĩı'] +['å®ŀéĻħ', 'è¡ĮåĬ¨'] +['è¦ģ', 'ä¸įè¦ģ'] +['æĹ¥æľ¬', '人'] +['è̶', '稣'] +['ç¼ĸ', 'åī§'] +['æ¶', '©'] +['åį°', 'å°¼'] +['ä¸Ĭä¸ĭ', '游'] +['åĩł', 'åı¥'] +['ä¸Ń', 'éĵģ'] +['ç°¡', 'åĸ®'] +['èĩª', '带'] +['çĶŁ', 'äºİ'] +['ä¸Ģ', 'åı£æ°Ķ'] +['åĭ¤', 'å¥ĭ'] +['éĻį', 'ä»·'] +['å±ķçݰ', 'äºĨ'] +['å¸ĥ', 'æĭī'] +['ä¼ļ', 'éĢīæĭ©'] +['çļĦ', 'ç»ıåħ¸'] +['好', 'æľĭåıĭ'] +['车', 'éģĵ'] +['æķ´', 'åĢĭ'] +['åľ', 'ĵ'] +['éķ¿æľŁ', '以æĿ¥'] +['æĬķ', 'å½±'] +['çļĩ', 'åĨł'] +['è¿ĩ', '大'] +['åijĬè¯ī', 'ä»ĸ'] +['ä¼ģä¸ļ', 'æıIJä¾Ľ'] +['æĬ½', '象'] +['éĢĤ', '度'] +['çļĦ', '女åŃ©'] +['èµ·', 'ä¼ı'] +['çļĦ', 'åĬŁæķĪ'] +['ä¸ĵ项', 'æķ´æ²»'] +['åı¯', 'éĢļè¿ĩ'] +['ä¸įåIJĮ', 'ç¨ĭ度'] +['å¼Ĥ', 'è®®'] +['åĩĢ', 'èµĦ产'] +['åij', 'Ĺ'] +['ä»Ģä¹Ī', 'åij¢'] +['å·¡', 'éĢ»'] +['è¸ı', 'ä¸Ĭ'] +['ä½Ĩ', 'å®ĥ'] +['ç²¾', '度'] +['管', 'å±Ģ'] +['第ä¸Ģ', 'åIJį'] +['åĨħ', 'åŃĺ'] +['æijĨ', 'åľ¨'] +['åī©', 'ä¸ĭ'] +['主ä½ĵ', '责任'] +['çĤ¹', 'åįĬ'] +['以', 'èĩ³äºİ'] +['åħ»èĢģ', 'ä¿ĿéĻ©'] +['æĦŁåıĹ', 'åΰäºĨ'] +['çŁ¥åIJį', 'çļĦ'] +['å¯Į', '豪'] +['妥', 'åĸĦ'] +['åŃĻ', 'åŃIJ'] +['éĵ', 'Ĥ'] +['说', 'èĩªå·±'] +['让', 'æĤ¨'] +['æķ°', 'æİ§'] +['çļĦçľ¼', 'åħī'] +['注', 'éĶĢ'] +['çļĦ', 'çģµéŃĤ'] +['è¿ĺ', 'ä¸įéĶĻ'] +['éĹ®', 'ä»ĸ'] +['èĩªä¸»', 'çłĶåıij'] +['èĵ', 'ĭ'] +['ç´«', 'èī²'] +['åĽ½å®¶', 'å®īåħ¨'] +['è¾½å®ģ', 'çľģ'] +['ä¹Ł', 'æ¯Ķè¾ĥ'] +['ç¾İ', 'èĤ¡'] +['ä¸įç¡®å®ļ', 'æĢ§'] +['å¿ĥ', '头'] +['æĪ', '³'] +['级', 'åĪ«çļĦ'] +['论', 'è¿°'] +['çļĦ', 'åĽŀçŃĶ'] +['ä¿Ŀè¯ģ', 'éĩij'] +['çŃī', 'è¡Įä¸ļ'] +['幸ç¦ı', 'æĦŁ'] +['æŃ§', 'è§Ĩ'] +['æľº', '票'] +['æ´¾', '人'] +['èĩ´', 'åij½'] +['åĺ´', 'è§Ĵ'] +['æĸ°éĹ»', 'ä¸Ńå¿ĥ'] +['æĶ¾å¼ĥ', 'äºĨ'] +['å®ľ', 'å±ħ'] +['åĨĻ', 'ä¸ĭ'] +['éĹ®', 'çŃĶ'] +['è¿ĻéĩĮ', 'æĺ¯'] +['å¤ļ', 'åľ°'] +['åĮºåŁŁ', 'åĨħ'] +['åīµ', 'æĸ°'] +['çľĭ', 'ä»ĸ'] +['æī§æ³ķ', '人åijĺ'] +['åĬ¨', 'æľº'] +['éŁ³', 'åĵį'] +['çļĦ', 'åij½è¿IJ'] +['é¡¶', 'éĥ¨'] +['åĵ', 'Ł'] +['éĥ½', 'æľĥ'] +['æīĵéĢł', 'æĪIJ'] +['æĦı', 'åĽ¾'] +['çļ', 'ĸ'] +['åĢĴ', 'åħ¥'] +['å·´', 'èIJ¨'] +['åĬ©', 'åѦ'] +['å¤į', 'åı¤'] +['åIJ¯', 'ç͍'] +['åĽ½éĻħ', 'å¸Ĥåľº'] +['åĤ¨', 'èĥ½'] +['é»ijé¾Ļæ±Ł', 'çľģ'] +['ä¹ĺ', '车'] +['è¿IJåĬ¨', 'ä¼ļ'] +['ä¿Ŀ', 'åĪ©'] +['çŁ³', 'æĿIJ'] +['çµ', '®'] +['çĤĴ', 'ä½ľ'] +['çļĦ', 'ä¿¡ä»»'] +['å°±', 'æĪIJäºĨ'] +['åı¯', 'è§Ĥ'] +['çļĩ', 'ä¸Ĭ'] +['è¿Ļ', 'åĩłå¤©'] +['ä¸Ģ', 'éĶ®'] +['åĨ·', 'åĨ»'] +['ä¿Ŀ', 'åį«'] +['æł¸', 'æ¡ĥ'] +['åIJĪä½ľ', 'åħ³ç³»'] +['éĢģ', 'åĩº'] +['æĹĹ', 'ä¸ĭçļĦ'] +['åľ¨', 'ä¹İ'] +['为', '广大'] +['åįĪ', 'é¤IJ'] +['ä¸ĵ', '访'] +['æĪĸ', 'å°Ĩ'] +['éĿĴå²Ľ', 'å¸Ĥ'] +['å¥Ķ', 'è·ij'] +['æĹ¥', 'æĬ¥éģĵ'] +['å¥ij', 'åIJĪ'] +['æĸ°', 'æĺ¥'] +['ä¸į', 'å°ıå¿ĥ'] +['两', 'ä¸ī'] +['æĦıæĢĿ', 'æĺ¯'] +['åĨ·', 'èĹı'] +['çļĦ', 'çĹĩçĬ¶'] +['æĢ§', 'åij½'] +['è¶ħ', 'æłĩ'] +['å¯Ĩ', '碼'] +['ç§ijæĬĢ', 'èĤ¡ä»½'] +['äºĨä¸Ģ', 'æī¹'] +['çĿ£', 'å¯Ł'] +['åªĴ', 'ä»ĭ'] +['å°Ħ', 'æīĭ'] +['ä¿®', 'åħ»'] +['çīĩ', 'åĪ»'] +['éĢĤåIJĪ', 'èĩªå·±'] +['åıªè¦ģ', 'æĺ¯'] +['åIJĥ', 'è¿ĩ'] +['éĩij', 'éĵ¶'] +['缴', 'å±ŀ'] +['åѦ', 'éĹ®'] +['åİĭ', 'åζ'] +['çªĹ', 'å¤ĸ'] +['æĶ¶', 'åΰäºĨ'] +['åħ¨åĽ½', '人大'] +['ä½Ĩæĺ¯', '对äºİ'] +['åľ¨', 'æķ´ä¸ª'] +['çļĦ', 'èĥĮåIJİ'] +['åĩıå°ij', 'äºĨ'] +['åıį', 'èħIJ'] +['åıįèħIJ', 'åĢ¡'] +['åıįèħIJåĢ¡', 'å»ī'] +['æĹ', '·'] +['åĪĨ', 'æľŁ'] +['åľ¨', 'æ·±åľ³'] +['æīĵ', 'çĿĢ'] +['æī«', 'ä¸Ģ'] +['æī«ä¸Ģ', 'æī«'] +['æĶ¿åºľ', 'éĥ¨éŨ'] +['æİ¥', 'è¿ŀ'] +['å±ŀäºİ', 'èĩªå·±'] +['åŃIJ', 'å¼¹'] +['åIJĮæł·', 'æĺ¯'] +['æĢ»', 'åħ±'] +['车', 'ä¼ģ'] +['æ¢', 'ĵ'] +['åħ¬', 'é¡·'] +['åıij', '声'] +['éĴ', 'Ľ'] +['èµ°åĬ¿', 'åĽ¾'] +['主', 'èIJ¥'] +['åĸ', 'Ķ'] +['æķ°æį®', 'åĪĨæŀIJ'] +['ä¸į', 'è¿ľ'] +['æľī', 'åIJį'] +['æľīåIJį', 'çļĦ'] +['åģ¿', 'è¿ĺ'] +['å¾Ī', 'ä½İ'] +['è®ĵ', '人'] +['èĿ', 'ī'] +['é«ĺ', 'è´µ'] +['å°ij', '许'] +['æ°', 'Ł'] +['å¹', '¢'] +['亲', 'æĥħ'] +['è¿Ļä»¶', 'äºĭæĥħ'] +['ç͍', 'é¤IJ'] +['缸åħ³', 'æĸ°éĹ»'] +['å°±', 'åºĶ该'] +['ç»Ī', 'çĤ¹'] +['æĺ¯', 'å¤ļå°ij'] +['çĻ»', 'åľº'] +['è¯ķ', '管'] +['è¯ķ管', 'å©´åĦ¿'] +['åģļ', '大'] +['åģļ大', 'åģļ强'] +['çļĦ', 'ä¾ĭåŃIJ'] +['åħ«', '个'] +['æĺİ', 'æĹ¥'] +['çĤ', '³'] +['èµ°', 'åİ»'] +['éģ', 'º'] +['å¢', '©'] +['ä½ĵä¼ļ', 'åΰ'] +['åĴ', 'ı'] +['ä¸ĭ', 'è¾¾'] +['å¤į', 'åıij'] +['追', 'éĢIJ'] +['æīĵ', 'åĵį'] +['çļĦ', 'éļ±ç§ģæ¬Ĭ'] +['åħ·æľī', 'ä¸Ģå®ļ'] +['è¿Ļä¹Ī', 'å¤ļå¹´'] +['æłij', 'æŀĹ'] +['æľĢ', 'éķ¿'] +['åIJĮ', 'èĥŀ'] +['åħī', 'æ³½'] +['åŁŁ', 'åIJį'] +['æĮĩ', 'åIJij'] +['åıĹ害', 'èĢħ'] +['æłij', 'èĦĤ'] +['æľīå¤ļ', '大'] +['大', 'éĿ¢ç§¯'] +['æĹł', 'ç¼Ŀ'] +['æĶ¹', 'æŃ£'] +['æĽ´å¤ļ', 'çļĦæĺ¯'] +['æľŁ', 'æľ«'] +['æŃ', '¼'] +['ä¹ī', 'ä¹Į'] +['éĤ£', 'ä½ł'] +['çļĦ', '第ä¸Ģ个'] +['èĮ', 'µ'] +['å°', '§'] +['èį', '«'] +['ä¸įä»ħ', 'åı¯ä»¥'] +['æ¶Į', 'çݰ'] +['æĢ»', 'éĿ¢ç§¯'] +['æĸ°éĹ»', 'åıijå¸ĥ'] +['æ°ij', 'ç͍'] +['å°±', '读'] +['æīĵ', 'è´¥'] +['å¤ĸ', 'è¯Ń'] +['æĪij们', 'ä¸Ģèµ·'] +['é¢Ħ', 'å®ļ'] +['çĥ¹', '饪'] +['æľĢ', '主è¦ģ'] +['æľĢ主è¦ģ', 'çļĦ'] +['çīĮ', 'çħ§'] +['åĽł', 'åħ¶'] +['ä½İ', 'ä¸ĭ'] +['ä¼ļ', 'åIJĮ'] +['è§ģ', 'è§£'] +['éĹ´', 'éļĶ'] +['æķĻ', 'ç¨ĭ'] +['å°', 'ī'] +['å¸Ĥ', 'ä¸Ńå¿ĥ'] +['åħ³éĶ®', 'æĺ¯'] +['æµ·', 'åįĹçľģ'] +['çī¹åĪ«', 'æĺ¯åľ¨'] +['ä¸ŃåĽ½', '大éĻĨ'] +['åħħè¶³', 'çļĦ'] +['æĹ¢', 'èĥ½'] +['åĤ³', 'çµ±'] +['çijľ', 'ä¼½'] +['åħ¥', 'åĽ´'] +['æħ¢æħ¢', 'åľ°'] +['æĬ¥', 'éħ¬'] +['æī¹', 'å¤į'] +['å·¥ä¸ļ', 'åĽŃåĮº'] +['ä¸İ', 'åıijå±ķ'] +['èĥ¸', 'éĥ¨'] +['åľ¨', 'ç½ij绾'] +['åľ¨ç½ij绾', 'ä¸Ĭ'] +['交', 'è°Ī'] +['æĽ´', 'æĶ¹'] +['åįłæľī', 'çİĩ'] +['ä¸Ŀ绸', 'ä¹ĭè·¯'] +['è¡', 'Ľ'] +['çłĶ', 'åΤ'] +['åĪ', 'ª'] +['åĪª', 'éϤ'] +['è¿Ļ', 'åıª'] +['çļĦ', 'æ°Ķæģ¯'] +['åĬł', 'å·ŀ'] +['éĴ', '§'] +['çIJĨäºĭ', 'éķ¿'] +['ä¸ĸ', 'å®¶'] +['æµģè¡Į', 'çļĦ'] +['å¾Ī', 'æľīåı¯èĥ½'] +['们', 'éĥ½'] +['ç»ıèIJ¥', '模å¼ı'] +['è¡Įä¸ļ', 'ä¸Ń'] +['éĢļçŁ¥', '书'] +['åij½', 'é¢ĺ'] +['æľ¬', 'ç¶²ç«Ļ'] +['æ²Ļ', 'çī¹'] +['åıij', 'åħī'] +['é«ĺ', 'ä»·'] +['å·²', 'çĦ¶'] +['åıĮ', 'åįģä¸Ģ'] +['ä¸Ĭ', 'è¯ī'] +['ç¿ħ', 'èĨĢ'] +['è¿Ļä¸Ģ', 'å¹´'] +['大ä¼ļ', 'ä¸Ĭ'] +['éĩ', 'ī'] +['å®Įåħ¨', 'æĺ¯'] +['å¾Ĺ', '太'] +['ä¸Ģèά', '人'] +['è¿ĺ', 'ç®Ĺ'] +['æĬĺ', 'åıł'] +['æĬķ', 'æľº'] +['çĤ¹', 'çĩĥ'] +['çݰéĩij', 'æµģ'] +['åħĶ', 'åŃIJ'] +['ç½ij', 'æł¼'] +['æİ¥', 'è¿ĩ'] +['ä¾Ľ', 'è´§'] +['éĺ´', 'å½±'] +['åİŁ', 'åħĪ'] +['æį', '£'] +['å·¦', 'ä¾§'] +['åħĭ', 'æĭī'] +['æīĵ', 'åį¡'] +['ç§ij', 'æ¯Ķ'] +['æ±ĩ', 'éĽĨ'] +['åľ°çIJĨ', 'ä½įç½®'] +['è¯Ħ', 'å§Ķ'] +['ç»ĵåIJĪ', 'èµ·æĿ¥'] +['è¿Ľåħ¥', 'åΰ'] +['åı¯', 'è¡Į'] +['åı¯è¡Į', 'æĢ§'] +['让', 'å®ĥ'] +['åĪ¶åº¦', 'æĶ¹éĿ©'] +['çĶĺèĤĥ', 'çľģ'] +['åĵ', 'Ĺ'] +['åģı', 'åģı'] +['è¡£', 'çī©'] +['ç¥Ŀ', 'è´º'] +['æºIJ', 'èĩª'] +['å¹¶ä¸į', '代表'] +['åĽ½', '度'] +['好', 'åĿı'] +['æĿ', 'ĸ'] +['æĿŃ', 'å·ŀå¸Ĥ'] +['湿', '度'] +['é²', '¸'] +['åįļ', '彩'] +['æ³°', 'å±±'] +['æĿij', 'èIJ½'] +['æĸ°', 'èģŀ'] +['èĤ', 'ĭ'] +['åı¤èĢģ', 'çļĦ'] +['çļĦ', 'ç§ĺå¯Ĩ'] +['ä¸Ģ个', 'éĹ®é¢ĺ'] +['éģı', 'åζ'] +['åįĥ', '亿'] +['è¿ĩ', '硬'] +['å°Ħ', 'åĩ»'] +['èĩªçĦ¶', 'æĺ¯'] +['产', 'åĮº'] +['çĤ¹', 'çĤ¹å¤´'] +['åı¯ä»¥', '帮åĬ©'] +['说', 'å®ŀ'] +['说å®ŀ', 'è¯Ŀ'] +['æĪij', 'åıªæĺ¯'] +['ä¹ĭ', 'ä½Ļ'] +['åIJĮæĹ¶', 'ä¹Łæĺ¯'] +['ä¸ŃåĽ½', 'éĺŁ'] +['建æĪIJ', 'åIJİ'] +['ä¹IJ', 'è§Ĩ'] +['åij¨', 'å²ģ'] +['èį¯', 'åºĹ'] +['éĩij', 'åįİ'] +['严éĩį', 'å½±åĵį'] +['è´¨', 'åľ°'] +['æĹħ', 'éģĬ'] +['åħµ', 'åύ'] +['æķĻèĤ²', 'æķĻåѦ'] +['离', 'åİ»'] +['åIJĦå¼ı', 'åIJĦæł·'] +['ä»ĭ', 'ç´'] +['ä»ĭç´', '¹'] +['å¼Ģ', '头'] +['å°Ĩ', 'èĩªå·±çļĦ'] +['åIJ¬', 'åĬĽ'] +['ä¿¡æģ¯', 'ç³»ç»Ł'] +['ä»İ', 'æł¹æľ¬'] +['ä»İæł¹æľ¬', 'ä¸Ĭ'] +['æİĮ', '声'] +['欢', 'åĸľ'] +['å±ķ', 'åĮº'] +['åķ', '¸'] +['太å¤ļ', 'äºĨ'] +['éĹ²', 'ç½®'] +['èĥ¡', 'èIJĿåįľ'] +['å§Ķ', 'å®£ä¼ł'] +['å§Ķå®£ä¼ł', 'éĥ¨'] +['åįĹ', 'éĺ³'] +['å·ŀ', 'åĮº'] +['ä¸İ', 'æĹ¶'] +['ä¸İæĹ¶', '俱'] +['ä¸İæĹ¶ä¿±', 'è¿Ľ'] +['å«Įçĸij', '人'] +['èī¯', 'å¿ĥ'] +['头', 'é¡¶'] +['è´¢', 'æĬ¥'] +['ä½Ľ', 'æ³ķ'] +['å¾', 'µ'] +['åİŁ', 'ä»¶'] +['åĭ', 'ŀ'] +['çĶ·', '篮'] +['å¤ĸåĽ½', '人'] +['è¿Ŀ', '纪'] +['æī¾', 'äºĨ'] +['æįķ', 'æįī'] +['缸', 'è¯Ĩ'] +['æIJľ', 'éĽĨ'] +['çļĦ', 'ä¼Łå¤§'] +['ä¸ī', 'ç»´'] +['å°±è¡Į', 'äºĨ'] +['çĭIJ', 'æľĪ'] +['çĭIJæľĪ', 'å±±'] +['å¸ĮæľĽ', 'éĢļè¿ĩ'] +['èĢĮ', '对äºİ'] +['éĿ¢', 'å°į'] +['åĨĽ', 'åĽ¢'] +['è¡Ĺ', 'åĮº'] +['æĤ¬', 'æĮĤ'] +['便', 'ç§ĺ'] +['æľīä¸Ģ', 'çĤ¹'] +['ä¼ļè®®', 'ä¸Ĭ'] +['ä¸ĭ', 'æīĭ'] +['廣', 'åijĬ'] +['äºĶ', 'è¡Į'] +['çŃī', 'åĢĻ'] +['ç´§ç´§', 'åĽ´ç»ķ'] +['æĭ¿', 'äºĨ'] +['æ¡Į', 'éĿ¢'] +['ç¥ŀ', 'æĥħ'] +['éĽĦ', 'åİļ'] +['çŀ', '³'] +['楼', 'ä¸ĭ'] +['å½', 'ª'] +['äºĭ', 'åıij'] +['åĨį', 'è§ģ'] +['é¤', 'ĺ'] +['é¢Ħ', 'åĶ®'] +['åİ»', 'çľĭçľĭ'] +['æĪij们', 'åºĶ该'] +['ä¸ī', 'å®¶'] +['æµ', 'Ĭ'] +['ä¹IJ', 'éĺŁ'] +['çľĭ', 'ä¸įè§ģ'] +['èĦij', 'åŃIJ'] +['æĮģ', 'æľīçļĦ'] +['çϽ', 'èıľ'] +['éĹª', 'çĥģ'] +['åĸĿ', 'æ°´'] +['æİ§åζ', 'ç³»ç»Ł'] +['ä¸ĵ', 'åĮº'] +['æľĿ', 'å»·'] +['æĪij', 'å¿ĥéĩĮ'] +['å±ķ', 'åİħ'] +['èľĺ', 'èĽĽ'] +['åĨ»', 'ç»ĵ'] +['ç²', 'ª'] +['åº', 'IJ'] +['åIJij', '社ä¼ļ'] +['åĨ³çŃĸ', 'éĥ¨ç½²'] +['çŁŃ', 'æľŁåĨħ'] +['æĸ°', 'ä¸ļæĢģ'] +['æľ', 'Ķ'] +['æĹ¶', 'æĬ¥'] +['使', 'ä¹ĭ'] +['åĽł', 'åŃIJ'] +['åıĤä¸İ', 'èĢħ'] +['çļĦ', '年轻人'] +['æīĭ', '表'] +['å°ģ', 'éĶģ'] +['为ä»Ģä¹Ī', 'ä¸į'] +['åIJ¸', 'çĥŁ'] +['æ¯Ĵ', 'ç´ł'] +['åĪij', 'æ³ķ'] +['磫', 'æŃ£'] +['身', 'æĹģ'] +['åİŁ', 'è°ħ'] +['çĽij', 'æĬ¤'] +['æŃ¤', 'å¤Ħ'] +['éļ¨', 'æĻĤ'] +['æŀľ', 'å®ŀ'] +['åĮ»çĸĹ', 'æľįåĬ¡'] +['ä¸į', 'åIJĪçIJĨ'] +['æIJŀ', '好'] +['çļĦ', 'èĦļæŃ¥'] +['å¤ĸ', 'å¥Ĺ'] +['ç¶ĵ', 'éģİ'] +['æĶ¾', 'ç¼ĵ'] +['åģľ', 'çķĻ'] +['æĺŁ', 'çIJĥ'] +['çļĦä¸Ģ', 'éĿ¢'] +['åĩł', 'ä½ķ'] +['è½®', 'åĽŀ'] +['æ¯Ľ', 'å·¾'] +['ä¿®', 'çIJĨ'] +['ä¸įçŁ¥', 'ä¸į'] +['ä¸įçŁ¥ä¸į', 'è§ī'] +['æķ´', '个人'] +['æ¯ģ', 'çģŃ'] +['åı°', 'å·ŀ'] +['使ç͍', '寿åij½'] +['é»ij', 'çϽ'] +['æij¸', 'ç´¢'] +['é¼ł', 'æłĩ'] +['éĿ©', 'æĸ°'] +['éº', 'µ'] +['ä¸ĵéŨ', '为'] +['å¾Īå¤ļ', 'æľĭåıĭ'] +['å·¥ä½ľ', 'ç»Ħ'] +['åIJĪ', 'å½±'] +['çĤº', 'ä»Ģ麼'] +['æŀģ', '度'] +['çļĦ', 'è¿ĽæŃ¥'] +['å½ĵ', 'ä¹ĭ'] +['å½ĵä¹ĭ', 'æĹł'] +['å½ĵä¹ĭæĹł', 'æĦ§'] +['è´´', 'è¿ij'] +['å°º', '度'] +['åľ¨', 'çİ°åľº'] +['éĻį', '临'] +['åħ»èĢģ', 'éĩij'] +['ç£', 'ķ'] +['åı¯ä»¥', '使'] +['管çIJĨ', 'æ°´å¹³'] +['æľ¬æĬ¥', 'è®°èĢħ'] +['æ³ķ', '令'] +['åį¡', '车'] +['举', 'æµ·'] +['å¤ļ', 'éĩį'] +['åħ¶', 'éĹ´'] +['ç´', 'Ļ'] +['éĩį大', 'é¡¹çĽ®'] +['æ±Ĺ', 'æ°´'] +['ç»Ħ', 'å§Ķä¼ļ'] +['ä¿¡æģ¯', 'åħ¬å¼Ģ'] +['ä¸į论', 'æĺ¯'] +['ä¸Ģ', 'åIJ¬'] +['èĴ¸', 'æ±½'] +['æıŃ', 'ç§ĺ'] +['è¶ħ', 'éģİ'] +['触', 'åıij'] +['å©', '¦'] +['åħ³èģĶ', '交æĺĵ'] +['å°±', 'ç»Ļ大家'] +['好', 'ä¹ħ'] +['åĢŁ', 'è´·'] +['游æĪı', 'è§Ĵèī²'] +['å¼ĢåIJ¯', 'äºĨ'] +['æİ', 'ł'] +['åħļçļĦ', 'åįģä¹Ŀ'] +['ä¸ĭ', '鼨'] +['çŁŃ', 'æĹ¶éĹ´åĨħ'] +['å¯', 'ħ'] +['导', 'åħ¥'] +['å·¥ä½ľ', 'ç»ıéªĮ'] +['ä¹Ł', 'åıªèĥ½'] +['鼷', 'éľĨ'] +['è·Ł', 'è¿Ľ'] +['åį¡', 'éĢļ'] +['é¢ĩ', 'æľī'] +['æľº', 'ä½ĵ'] +['æĪĺ士', 'èģĮä¸ļ'] +['女', '主'] +['ä½ĵåζ', 'æľºåζ'] +['è¶³', 'åįı'] +['èĪĴéĢĤ', 'çļĦ'] +['åĢŁ', 'åı£'] +['æī¹', 'åΤ'] +['æķ°', 'å̼'] +['è«', '¾'] +['éĺ¿æĭī', '伯'] +['åĺ', 'İ'] +['æħ', '¶'] +['è¾¾', '人'] +['å¼Ģ', 'æ°´'] +['大', '鼨'] +['温', '室'] +['ä½İ', 'è¿·'] +['ä»į', 'æĹ§'] +['éªĹ', 'åŃIJ'] +['亲', 'å±ŀ'] +['çIJĨ', 'æĻº'] +['æľ¬', 'åŁºéĩij'] +['å¨', 'ħ'] +['åĨĻåŃĹ', '楼'] +['å¢Ļ', 'å£ģ'] +['å®', 'µ'] +['èϽ', 'çĦ¶æĺ¯'] +['顺', 'çĿĢ'] +['åħ«', 'åį¦'] +['åķĨ', 'ç͍'] +['ä¸į', '失'] +['è¿·', 'èĮ«'] +['顺', '便'] +['æļij', 'æľŁ'] +['欺', 'è´Ł'] +['é¢ij', 'é¢ij'] +['该', 'æł¡'] +['æĸĻ', 'çIJĨ'] +['æ·±', 'æĥħ'] +['åīį', 'éĶĭ'] +['ä¿Ŀ', 'èŃī'] +['èģĮä¸ļ', 'çĶŁæ¶¯'] +['åħ¬', 'å¼Ģåıij'] +['åħ¬å¼Ģåıij', 'è¡Į'] +['åħ¥', 'æĪ·'] +['éł', 'ĵ'] +['å̾', 'åIJ¬'] +['éŃ', 'ģ'] +['æĦī', 'æĤ¦'] +['åĽŀ', 'åIJĪ'] +['åħ¨åĬĽ', '以'] +['åħ¨åĬĽä»¥', 'èµ´'] +['åĥ¹', 'å̼'] +['èĥ½åĬĽ', '强'] +['ç»ı', 'å¼Ģ'] +['ç»ıå¼Ģ', 'åĮº'] +['è¿ľ', 'æĸ¹'] +['çļĦ', 'éģĵçIJĨ'] +['缴', 'åįĩ'] +['缴åįĩ', 'æľº'] +['为主é¢ĺ', 'çļĦ'] +['ç»Ļ', 'æĤ¨'] +['è¿ĺ', 'æĥ³'] +['æ¯Ķ', 'æĪij'] +['åĨľ', 'çī§'] +['æµ·', 'åºķ'] +['çŃ¾è®¢', 'äºĨ'] +['对äºİ', 'æĪij们'] +['æĹ¶', '许'] +['éĶ®', 'çĽĺ'] +['å®ŀéĻħ', 'æİ§åζ'] +['çļĦ', 'æ¨¡æł·'] +['åıįæĺł', 'äºĨ'] +['代', 'åĬŀ'] +['åĮ»', 'ç͍'] +['éĽĨ', 'ç»ĵ'] +['åıijå±ķ', 'åīįæĻ¯'] +['æĮĩ', 'çĿĢ'] +['åįİ', 'åĮĹ'] +['è¿Ļ', 'åĩłä¸ª'] +['åIJį', 'æ°Ķ'] +['åĤį', 'æĻļ'] +['èĩª', 'åıij'] +['æ³¢', 'åħ°'] +['大åĬĽ', 'æİ¨è¿Ľ'] +['èĩª', 'ç§°'] +['èįĨ', 'å·ŀ'] +['æIJį', '害'] +['äºĨä¸Ģ', 'åı¥'] +['æľĢåĪĿ', 'çļĦ'] +['éĩijèŀį', 'å᱿ľº'] +['æĢĢ', '念'] +['è¡Į', 'åĭķ'] +['女', 'æİĴ'] +['ä¸į', 'è§£'] +['ä¼ł', 'éĶĢ'] +['转载', '请'] +['饰', 'åĵģ'] +['åıª', '为'] +['ä¸İ', 'ä¼Ĺ'] +['ä¸İä¼Ĺ', 'ä¸įåIJĮ'] +['èĥ½', 'èĢĹ'] +['èı©', 'æıIJ'] +['è¿ij', '两年'] +['è¿Ķ', '乡'] +['马ä¸Ĭ', 'å°±'] +['äºĮ', 'çŃīå¥ĸ'] +['æ°´', '管'] +['æ³ķ', 'åѦ'] +['çģŃ', 'çģ«'] +['大', 'å§IJ'] +['åij¨', '转'] +['æľī', 'æľŁ'] +['æľīæľŁ', 'å¾Ĵ'] +['æľīæľŁå¾Ĵ', 'åĪij'] +['å°į', 'æĸ¹'] +['ç¥ŀ', 'èī²'] +['æ²¹', 'èĦĤ'] +['ä¸ī', 'çĤ¹'] +['ä¸į', 'åĪ©äºİ'] +['äºĭä¸ļ', 'éĥ¨'] +['å°±', 'è·Ł'] +['å¼Ģ', 'æĶ¯'] +['å°ı', '女åŃ©'] +['åħ±åIJĮ', 'åĬªåĬĽ'] +['çĶļèĩ³', 'è¿ĺ'] +['è¿Ļ', 'åIJį'] +['è¿Ļ', 'ç¬Ķ'] +['çݯ', 'åį«'] +['æľī', 'ç§į'] +['è§Ĩ', 'åĬĽ'] +['çĨŁ', 'çŁ¥'] +['åħ¬ç§¯', 'éĩij'] +['æ¶Īéĺ²', 'å®īåħ¨'] +['é¢ĩ', '为'] +['大', 'èħ¿'] +['éĿ', '¶'] +['çī¹', 'æķĪ'] +['æľįåĬ¡', 'åĮº'] +['å¼Ģ', 'åĩº'] +['深度', 'èŀįåIJĪ'] +['æĹł', 'å¿§'] +['æŁ¥', 'éĺħ'] +['ç»Ī', 'ç»ĵ'] +['ä¿Ŀ', 'ç¨İ'] +['è¨İ', 'è«ĸ'] +['å½ĵ', 'åģļ'] +['è·³', 'èĪŀ'] +['å¯', '§'] +['女', 'çİĭ'] +['è®°èĢħ', 'åľ¨'] +['åħ¨', '产ä¸ļéĵ¾'] +['è´¯', 'éĢļ'] +['åħ´', 'ä¸ļ'] +['éĻį', 'åΰ'] +['å°ģ', 'éĿ¢'] +['åħ¨éĿ¢', 'æİ¨è¿Ľ'] +['奶', 'èĮ¶'] +['éĢī', 'åĿĢ'] +['äºĨä¸Ģ', 'åľº'] +['åIJĮ', 'ä¼´'] +['è®®', '论'] +['æIJ', 'ĵ'] +['诸', 'èijĽ'] +['诸èijĽ', '亮'] +['å¹²', 'åĺĽ'] +['æµģ', 'æĦŁ'] +['ä¸ĵä¸ļ', 'çŁ¥è¯Ĩ'] +['ç͵', 'ç«Ļ'] +['åĩı', 'å¼±'] +['åĩº', 'åħ¥'] +['åIJĦ', 'çľģ'] +['éĿŀ常', 'é«ĺ'] +['åľ°', '毯'] +['åıij', 'æĸĩ'] +['çĦ', 'ī'] +['çĥ§', 'çĥ¤'] +['å£ģ', '纸'] +['æģ¶', 'åĮĸ'] +['èĬ', '¸'] +['èĥĸ', 'åŃIJ'] +['çĩ', 'Ĵ'] +['çľģ', 'éĴ±'] +['çϾ', '强'] +['çIJĨå·¥', '大åѦ'] +['éĴ¢', 'æĿIJ'] +['åĽ½æľī', 'èµĦ产'] +['æĪĺ', 'æľº'] +['æ³Ħ', 'éľ²'] +['åIJİéĿ¢', 'çļĦ'] +['æ°´', 'èµĦæºIJ'] +['æ¢ħ', 'èĬ±'] +['åĨĻ', 'çĿĢ'] +['ä¹ĭ', '声'] +['æĹł', 'åı¯'] +['æĺİ', 'æľĿ'] +['ç«ĭæĸ¹', 'ç±³'] +['ç·', '£'] +['æĶ¾', 'è¿ĩ'] +['ç¦ı', 'çͰ'] +['å¾Ĺ', 'ä½ı'] +['åıĹ', 'ä¼Ĺ'] +['ä¸Ń', '级'] +['çĹħ', 'åıĺ'] +['ä¸Ģ', 'çŀ¬éĹ´'] +['æĿĥ', 'éĩį'] +['人æĢ§', 'åĮĸ'] +['åĮ»çĸĹ', 'åį«çĶŁ'] +['ä¸įåΰ', 'ä½į'] +['æĻºèĥ½', 'å®¶å±ħ'] +['饮', 'ç͍'] +['æ¼Ķ', 'åıĺ'] +['é«ĺ', 'ç´łè´¨'] +['ä¹Ļ', 'æĸ¹'] +['åģľ', 'çķĻåľ¨'] +['èİ·', 'æī¹'] +['ç©¿', 'æ¢Ń'] +['客', 'åľº'] +['æĮ½', 'åĽŀ'] +['京', 'åŁİ'] +['çĶŁåij½', 'åĬĽ'] +['實', 'éļĽ'] +['çĩ', 'Ī'] +['åĨį', 'çݰ'] +['çݰå®ŀ', 'ä¸Ń'] +['æľī', 'ä¿¡å¿ĥ'] +['çĸı', 'éĢļ'] +['åĺ´', 'åĶĩ'] +['鼷', 'éĶĭ'] +['èıľ', 'åįķ'] +['éħ', '¯'] +['è¶ħ', 'é«ĺ'] +['å¾Ī', 'é«ĺåħ´'] +['çĶŁ', 'æ®ĸ'] +['éĢł', 'ä»·'] +['误', 'åĮº'] +['æĨ', 'ĭ'] +['好', 'æ¶Īæģ¯'] +['å´', 'Ń'] +['以', 'èĩ´'] +['å¼Ģ', 'çİ©ç¬ij'] +['çĽij', 'è§Ĩ'] +['å·¡', 'å¯Ł'] +['å¾·', 'å·ŀ'] +['æĹ©', 'æĹ©'] +['éĹª', 'ç͵'] +['æĪª', 'åĽ¾'] +['åı¯ä»¥', 'æł¹æį®'] +['æīĭ', 'èīº'] +['æİ¥', '轨'] +['ç§į', 'æĹı'] +['æĢĢ', 'éĩĮ'] +['åİ»', 'åĮ»éĻ¢'] +['ä¸Ģ', 'äºĮ'] +['å¼Ģ', 'éĺĶ'] +['åĩı', 'éĢŁ'] +['ä½Ĩ', 'ä»İ'] +['éĢĻ', 'ä¸Ģ'] +['åĩı', 'åħį'] +['主é¢ĺ', 'æķĻèĤ²'] +['å¼Ģå·¥', '建设'] +['è¹', '¦'] +['æľĪ', '饼'] +['ä¸ĭ', 'æ²ī'] +['å°Ĭ', '严'] +['éĻ', 'ĩ'] +['å®ŀ', 'æľ¨'] +['å»ł', 'åķĨ'] +['声', 'ç§°'] +['èĢĥ', 'åľº'] +['å¸ĥ', 'é²ģ'] +['èĩª', 'æĿ¥'] +['èĩªæĿ¥', 'æ°´'] +['éĴ', '¾'] +['å¹´', '以ä¸Ĭ'] +['大', 'åıĶ'] +['ä»ĸ', 'å·²ç»ı'] +['åħ¨', 'æĿij'] +['èģĶç³»', 'ç͵è¯Ŀ'] +['为', '导åIJij'] +['åΤ', 'å¤Ħ'] +['对', 'éĺµ'] +['缮', 'æ¨Ļ'] +['åIJį', 'é¢Ŀ'] +['客', 'æ°Ķ'] +['横', 'åIJij'] +['çŃī', 'åĨħ容'] +['åĩł', 'çĤ¹'] +['è°Ī', '论'] +['ä¸į', 'ä¹ı'] +['å±ķ', 'çݰåĩº'] +['è¾ĥ', 'éķ¿'] +['éĢĨ', '转'] +['å°ı', 'æĻĤ'] +['æĺ¯', 'å¤ļä¹Ī'] +['æľ¬', 'æľĪ'] +['è¿ij', 'è§Ĩ'] +['æĪIJç«ĭ', '以æĿ¥'] +['代表', 'çĿĢ'] +['æĬ¥', 'å¤į'] +['æĪı', 'æĽ²'] +['è¨Ń', 'åĤĻ'] +['åħ¥', 'èĤ¡'] +['å¾ģ', 'æľį'] +['é«ĺ', 'åĩº'] +['èĪŀåı°', 'ä¸Ĭ'] +['å¿ĥ', 'åĬ¨'] +['两', 'çĤ¹'] +['缸', 'çķ¶'] +['èĻ', 'Ľ'] +['主', '页'] +['åĩł', 'å®¶'] +['æĹł', 'ä¸į'] +['åįı', 'å®ļ'] +['æĸ', 'IJ'] +['å¯ĵ', 'æĦı'] +['åħ¨', '线'] +['æįķ', 'é±¼'] +['åı¯ä»¥', 'ä»İ'] +['æľī', 'è¿Ļæł·çļĦ'] +['æģ¶', 'éŃĶ'] +['åĮħ', 'åŃIJ'] +['æģ', '¤'] +['å¼Ģå¥ĸ', 'ç»ĵæŀľ'] +['ä¸į', 'æŃ»'] +['èĹ', 'į'] +['弯', 'æĽ²'] +['æµ·', '峡'] +['éĶĢ', 'æ¯ģ'] +['çļĦ', 'çĭ¬çī¹'] +['示', 'æĦı'] +['ä¸įèĥ½', 'åĨį'] +['èĥ½', 'æĬĬ'] +['éĺ²', '线'] +['ä¸įå°ij', 'äºİ'] +['æ±', 'Ģ'] +['çļĦ', 'éĤ£ä¸Ģ'] +['羣', 'æĥħ'] +['åŀ', '®'] +['被', 'æīĵ'] +['åĽ½', 'å®ī'] +['ç¾İ', 'å¦Ļ'] +['è¿Ļ', 'åĩł'] +['åĩº', 'éģĵ'] +['æľįåĬ¡', 'äºİ'] +['æĪIJæŀľ', '转åĮĸ'] +['æīį', 'åįİ'] +['天', 'é¹ħ'] +['åĩł', '个人'] +['åĢĺ', 'èĭ¥'] +['è̽', '误'] +['æĬĹ', 'æĪĺ'] +['è¡Į', 'éĬ·'] +['æĿ¥', 'è¢Ń'] +['åĢŁ', 'éĮ¢'] +['èįī', 'èİĵ'] +['ä¸¥æł¼', 'æī§è¡Į'] +['举è¡Į', 'äºĨ'] +['å¤ĸ', 'ç±į'] +['å·²', 'è¾¾'] +['æĿij', 'åħļæĶ¯éĥ¨'] +['è¡', 'Ŀ'] +['éĻį', 'èĩ³'] +['æµ·', 'éĩı'] +['é¤IJ', 'é¦Ĩ'] +['æĢ¥', 'å¿Ļ'] +['æ·±', 'è¿ľ'] +['å¾Ģ', 'è¿Ķ'] +['ç¨İåĬ¡', 'å±Ģ'] +['å¹¿æ³Ľ', 'åºĶç͍'] +['è®®', 'åijĺ'] +['æĹł', 'æķĮ'] +['çľ¼', 'åħī'] +['çĥŃè¡Ģ', 'ä¼łå¥ĩ'] +['æŃ', 'IJ'] +['äºĨ', 'äºĽ'] +['è¿Ŀ', 'èĥĮ'] +['è¿Ļ', 'æĺ¯ä¸Ģç§į'] +['ä¸į', '稳å®ļ'] +['大家', 'åĪĨ享'] +['表', 'çı¾'] +['åīį', 'åįģ'] +['è·¯', 'è¿ĩ'] +['æĴ', '©'] +['åIJĮ', 'æĥħ'] +['ä¹ł', 'ä¿Ĺ'] +['åıij', 'è´¢'] +['åºĶ', 'æľīçļĦ'] +['æĿİ', 'æŁIJ'] +['èĤ', 'Ľ'] +['马', 'åħĭ'] +['éĢļ', 'åijĬ'] +['å·¨', '人'] +['ä¸Ģ', 'åĽ¢'] +['éĢĻ', '次'] +['ä¸į', 'äºĨè§£'] +['æĸ½', 'è¡Į'] +['èij¡èIJĦ', 'çīĻ'] +['åıĺå¾Ĺ', 'æĽ´åĬł'] +['æı', '£'] +['åĪĽæĸ°', 'èĥ½åĬĽ'] +['çķħ', 'éĶĢ'] +['表', 'æī¬'] +['æ¯Ķ', 'åĪ©'] +['æ¯ĶåĪ©', 'æĹ¶'] +['åĮ»çĸĹ', 'ä¿ĿéĻ©'] +['æĵį', '纵'] +['伤', '亡'] +['æµİ', 'å®ģ'] +['åıĺ', 'äºĨ'] +['æľ¬æ¬¡', 'æ´»åĬ¨'] +['åľŁ', '豪'] +['æĥ³', 'åĬŀæ³ķ'] +['æĺ', 'ķ'] +['å½ĵ', 'æĻļ'] +['åĩº', 'å±Ģ'] +['çĥŃ', 'è®®'] +['è°Ī', 'è°Ī'] +['æĻĭ', 'åįĩ'] +['åĬ¿', 'å¿ħ'] +['çĻ»', 'å±±'] +['éĤ£', 'åĦ¿'] +['åIJĥ', 'åΰ'] +['ä¹ĭ', 'åŁİ'] +['å¿«', 'æĿ¥'] +['æ¹Ľ', 'æ±Ł'] +['第ä¸ī', '个'] +['åħ¨éĿ¢', 'æıIJåįĩ'] +['å¥ĸ', 'åѦ'] +['å¥ĸåѦ', 'éĩij'] +['æĬķåħ¥', '使ç͍'] +['é½IJ', 'é²ģ'] +['åı¯ä»¥', 'æĬĬ'] +['åĴĮ', 'ä»ĸçļĦ'] +['è´ŃæĪ¿', 'èĢħ'] +['æŃ£å¼ı', 'åIJ¯åĬ¨'] +['åįİ', '润'] +['ä¸įæĸŃ', 'å®ĮåĸĦ'] +['éĴ¢', 'æĿ¿'] +['ç´¯', '积'] +['满', 'èĦ¸'] +['åĽĽ', 'æĸ¹'] +['è´¢', 'çī©'] +['ä»ĸ们', 'ä¼ļ'] +['å¤ı', 'æĹ¥'] +['éĤ£', '个人'] +['éĿł', 'çĿĢ'] +['çĤ¹', 'äºĨ'] +['çĤ¹äºĨ', 'çĤ¹å¤´'] +['æ©', 'ĭ'] +['åıĪ', '好'] +['åıĪ好', 'åıĪ'] +['åıĪ好åıĪ', 'å¿«'] +['éĺµ', 'éĺµ'] +['å°ģ', '建'] +['æľ¬', 'çͰ'] +['çī©ä¸ļ', 'æľįåĬ¡'] +['èĩªè´¸', 'åĮº'] +['åIJ', 'ı'] +['便åĪ©', 'åºĹ'] +['åĽ½å®¶', 'æłĩåĩĨ'] +['éĿ¢', 'ç²ī'] +['èī°', 'è¾Ľ'] +['æĶ»', 'åħ³'] +['æīĵ', 'åĮħ'] +['车', 'éĺŁ'] +['人', 'éĢī'] +['åı¯', 'ä¸įæĺ¯'] +['äºĮ', 'åįģå¹´'] +['åIJį', 'å¸Ī'] +['浦', '举'] +['åħ¬', 'è¯ģ'] +['è¿IJ', 'éĢģ'] +['æĺ¯', 'æľĢ好çļĦ'] +['æŁĶ', 'åĴĮ'] +['çİĭ', 'æŁIJ'] +['çĹħ', 'æĪ¿'] +['åĨ¶', 'éĩij'] +['ä¸Ģä»¶', 'äºĭæĥħ'] +['åį', '¤'] +['åı¯', 'æİ§'] +['çī', 'Ł'] +['æĭ', 'Ĥ'] +['å·²', 'äºİ'] +['人', 'éĢł'] +['çĶŁçī©', 'åĮ»èį¯'] +['ä½ĵ', 'çݰåĩº'] +['èĤ²', 'åĦ¿'] +['èĢģ', 'å®ŀ'] +['åľĸ', 'çīĩ'] +['è«', '¸'] +['ç´¯', 'äºĨ'] +['æĦŁåħ´è¶£', 'çļĦ'] +['åĽ¾çīĩ', 'æĿ¥æºIJ'] +['ä¹Ł', 'æĺ¯ä¸Ģç§į'] +['æ¾İæ¹ĥ', 'æĸ°éĹ»'] +['æĹ¶', '表示'] +['åħī', 'è¾ī'] +['æĬ¥', 'åºŁ'] +['å²ģ', 'æĹ¶'] +['éħ', '®'] +['æ£Ģ', 'ä¿®'] +['åıĺ', 'éĢŁ'] +['åıĺéĢŁ', 'ç®±'] +['åľ¨', 'èģĮ'] +['éı', '¡'] +['æį', 'Ĥ'] +['çĿ£', 'åĬŀ'] +['æ°¸', 'ä¸į'] +['åģļ', 'ä¸ĢäºĽ'] +['åİĨ', 'æĹ¶'] +['å·¥ç¨ĭ', 'æľºæ¢°'] +['æģ°', 'å½ĵ'] +['å°±', 'åľ¨äºİ'] +['ç§°', 'åij¼'] +['éĢļ常', 'æĺ¯'] +['æł·', 'å¼ı'] +['åij¨', 'ä¸Ģ'] +['èĭ±', 'éķij'] +['åĿĩ', '线'] +['ä¼ł', 'éĹ»'] +['ç͍æĪ·', 'ä½ĵéªĮ'] +['èµŀ', 'åIJĮ'] +['骨', 'æĬĺ'] +['为主', 'ä½ĵ'] +['æ±Ł', 'å±±'] +['æ¸ħ', 'æľĿ'] +['æĶĢ', 'åįĩ'] +['ä¸į', 'çĽ¸ä¿¡'] +['éĿ', '´'] +['æŃ¦', 'åĬŁ'] +['åĭ¤', 'åĬ³'] +['æĿ¥', 'æī¾'] +['å°Ĩ', 'æĮģç»Ń'] +['丫', '头'] +['æ¨Ļ', 'æºĸ'] +['è£', '´'] +['深深', 'çļĦ'] +['åŃķ', 'èĤ²'] +['è§ĦåĪĴ', '建设'] +['æ¸ħ', 'çν'] +['ç²¾åĩĨ', 'æī¶è´«'] +['æīĵçł´', 'äºĨ'] +['è¿Ļä¸Ģ', '天'] +['å·¥ä½ľ', 'æĢ»ç»ĵ'] +['æĹħ', 'ç¨ĭ'] +['举', 'èIJ¥'] +['æĶ¾', 'å°Ħ'] +['æľī', 'åĩłä¸ª'] +['éĿŀ', 'çī©è´¨'] +['åIJĥ', 'å¾Ĺ'] +['åĹ', '¨'] +['ä¼ļ', 'åıijçĶŁ'] +['篮', 'æĿ¿'] +['å¼Ģ', 'å°ģ'] +['麻', 'å°Ĩ'] +['èıı', 'æ³½'] +['ä¸į', 'åIJĪ'] +['ç³»åĪĹ', '产åĵģ'] +['èѬ', 'å¦Ĥ'] +['ç¾İ', 'èªī'] +['èĩªå·±', 'åĸľæ¬¢'] +['交æĺĵ', 'ä¸Ńå¿ĥ'] +['åIJĪ', 'åͱ'] +['使', 'æĪij'] +['åĥı', 'ç´ł'] +['带', 'éĺŁ'] +['ä½Ĩ', '对äºİ'] +['æĬĬ', 'è¿Ļ个'] +['èĤĿ', 'èĦı'] +['åįķ纯', 'çļĦ'] +['æĶ»åĿļ', 'æĪĺ'] +['缼', 'ä¼ļ'] +['åijµ', 'æĬ¤'] +['æª', 'Ģ'] +['èµ¶', 'ä¸Ĭ'] +['æ¥', 'Ĭ'] +['ä¹ħ', 'äºĨ'] +['ç¡', 'Ŀ'] +['çŃĶ', 'é¢ĺ'] +['ä¿ĿæĮģ', 'çĿĢ'] +['è§ģ', 'è¯Ĩ'] +['çĤ¹', 'åĦ¿'] +['åįĬ', '个æľĪ'] +['æ»', 'ĩ'] +['浸', '泡'] +['ä¼ł', 'éĢģ'] +['åľ¨', 'å¸Ĥåľºä¸Ĭ'] +['ä¹ĭ', '乡'] +['çī¹', 'éķ¿'] +['éĽ', 'ŀ'] +['èª', 'ł'] +['身', 'å¤Ħ'] +['æŁł', '檬'] +['身', 'ç©¿'] +['çľģ', 'åħ¬å®ī'] +['çľģåħ¬å®ī', 'åİħ'] +['åıĻ', 'åĪ©äºļ'] +['åĩł', 'åĪĨéĴŁ'] +['人', 'åĢij'] +['åľ°', '段'] +['èĩª', 'åѦ'] +['ä¹Ł', 'è¶ĬæĿ¥è¶Ĭ'] +['èģĮ', 'æĿĥ'] +['æĸ', '§'] +['èĩ', '»'] +['å½Ĵ', '纳'] +['驾', 'é©Ń'] +['éĥ¨åĪĨ', 'åľ°åĮº'] +['没æľī', 'æĥ³åΰ'] +['æĴ', 'ĩ'] +['ä¹Į', 'é²ģ'] +['ä¹Įé²ģ', 'æľ¨'] +['ä¹Įé²ģæľ¨', 'é½IJ'] +['èĤ²', '人'] +['çļĦ', 'æŃ¥ä¼IJ'] +['å»¶', 'æľŁ'] +['æ²¹', 'æ°Ķ'] +['åģļ', 'å®Į'] +['åľ£', 'åľ°'] +['丰', 'åİļ'] +['宽', '带'] +['åı¯éĿł', 'çļĦ'] +['åºŃ', 'éĻ¢'] +['åŃ', 'ľ'] +['å°ı康', '社ä¼ļ'] +['å®īåħ¨', '管çIJĨ'] +['å¹´', '第'] +['æİĴ', '污'] +['èĥĮ', 'åĮħ'] +['å®¶', 'ä½ı'] +['åħ¶å®ŀ', 'å°±æĺ¯'] +['ä¼ļ', 'è§ģ'] +['帮åĬ©', 'ä¼ģä¸ļ'] +['ç½ij', 'è´Ń'] +['æĺ¯', 'ä¸įä¼ļ'] +['飯', 'åºĹ'] +['æŃ»', 'åİ»'] +['åħįçĸ«', 'åĬĽ'] +['æľ', 'ķ'] +['åĸĿ', 'äºĨ'] +['è½»', 'å¾®'] +['个æľĪ', 'åĨħ'] +['ç»Ħ', 'åĽ¢'] +['åĴĮ', 'å®ĮåĸĦ'] +['é¸', '½'] +['æıIJ', 'éĢŁ'] +['西å®ī', 'å¸Ĥ'] +['ä¸Ńå¿ĥ', '主任'] +['æĹ¶éĹ´', '为'] +['æľŁ', 'æĿĥ'] +['è¶', 'ķ'] +['ä¸įä»ħ', 'è¦ģ'] +['æľį', 'ä»İ'] +['é¡ĺ', 'æĦı'] +['ä¸į', 'å°ı'] +['ä¸įå°ı', 'çļĦ'] +['ç°', 'ĩ'] +['çª', '¦'] +['åĪĩ', 'æĪIJ'] +['åĵĪ', 'åĪ©'] +['天', '羣'] +['ä¸Ģ次', '次'] +['éĩij', 'å¸ģ'] +['æĢİä¹Ī', 'èĥ½'] +['ç½ij', 'è´·'] +['ä¼ļ计', 'å¸Ī'] +['çŁŃ', '缺'] +['对', 'æłĩ'] +['åıĺå¾Ĺ', 'æĽ´'] +['åīį', 'åĩłå¤©'] +['éĺ²', 'æ±Ľ'] +['彩', 'èϹ'] +['åĵģ', 'ä½į'] +['表', 'æł¼'] +['严', 'å¯Ĩ'] +['æ¯Ľ', 'åĪ©çİĩ'] +['çļĦ', 'åį±å®³'] +['å½ķ', 'åζ'] +['æ°´', 'åĬ¡'] +['èĥ½å¤Ł', '让'] +['å¹³', 'æĿ¿'] +['ä¹³', 'æĪ¿'] +['è¸ı', 'å®ŀ'] +['é¦ĸ', 'åĪĽ'] +['é¦Ļ', 'èķī'] +['æĬ¥', '表'] +['ä¸Ģ', 'æĬ¹'] +['åĩºçĶŁ', 'äºİ'] +['è²»', 'ç͍'] +['åĩº', '让'] +['åIJĪæ³ķ', 'æĢ§'] +['å°¼', 'åħĭ'] +['åĨ°', 'åĨ·'] +['é¦Ļ', 'æ°Ķ'] +['åı·', 'ç§°'] +['èµ·', 'çłģ'] +['åŁİ', 'åİ¿'] +['çİ©', 'èĢį'] +['ä¸Ĭ', 'éĻIJ'] +['ä¼ļè®®', 'ç²¾ç¥ŀ'] +['æĹģè¾¹', 'çļĦ'] +['便', 'ä¼ļ'] +['æıŃ', 'æĻĵ'] +['çİ©', 'æĦı'] +['éĽª', 'å±±'] +['åIJij', 'çĿĢ'] +['ä½ĵèĤ²', 'åľ¨çº¿'] +['说æĺİ', '书'] +['åĮĸ', 'èĤ¥'] +['åħļç»Ħ', '书记'] +['åĬ¨', '人'] +['ä¹ĭ', 'æīĢ'] +['æľĪ', 'èĩ³'] +['æľĢå¿«', 'çļĦ'] +['èĬĤ', 'åģĩæĹ¥'] +['ä¸ĵ', 'åľº'] +['èĢĥ', 'ä¸Ĭ'] +['çª', 'Ł'] +['é²ľ', 'è¡Ģ'] +['è¾ĥ强', 'çļĦ'] +['æĤĦ', 'çĦ¶'] +['å¤ļ个', 'åĽ½å®¶'] +['çªĹ', 'å¸ĺ'] +['æŀģ', 'å¤§åľ°'] +['ä¸įç͍', 'æĭħå¿ĥ'] +['è¿Ļä¹Ī', 'åģļ'] +['åĥ¹', 'æł¼'] +['ç¾İ丽', '乡æĿij'] +['å°ıæĹ¶', 'åĨħ'] +['ç´§', 'è¿«'] +['大', 'çģ«'] +['èĥ³', 'èĨĬ'] +['æĵįä½ľ', 'ç³»ç»Ł'] +['æ®ĭ', 'çķĻ'] +['åĨĻ', 'åĩº'] +['ç¦ģ', 'å¿Į'] +['åĬłçĽŁ', 'åºĹ'] +['è¿ij', 'çϾ'] +['便', 'åı¯'] +['æķ´æĶ¹', 'æİªæĸ½'] +['éĩĩ访', 'æĹ¶'] +['åĶIJ', '代'] +['æ·±åĮĸ', 'æĶ¹éĿ©'] +['çŁ', '¢'] +['éĥ½', 'åĸľæ¬¢'] +['è¶ĬæĿ¥è¶Ĭ', 'é«ĺ'] +['èĬ±', 'æľµ'] +['头', 'çĸ¼'] +['å®ī', '康'] +['å¢ŀéķ¿', 'çİĩ'] +['çľ¼', 'çľĭ'] +['å°±æĺ¯', '为äºĨ'] +['èĢĮ', '导èĩ´'] +['åĬłå¿«', '建设'] +['èĬ±', 'æł·'] +['åĨħå¿ĥ', 'çļĦ'] +['æĺĨ', 'å±±'] +['è³ĩ', 'æºIJ'] +['åĽŀåΰ', 'å®¶'] +['èıĬ', 'èĬ±'] +['æ°´', 'éĩı'] +['å¾ģ', 'ä¿¡'] +['è¡ĮæĶ¿', 'åĮº'] +['ä¹ĥ', 'æĺ¯'] +['æĬķèµĦ', 'é¡¹çĽ®'] +['å«ģ', 'ç»Ļ'] +['ç¥ŀ', 'åľ£'] +['ç¨', 'ł'] +['æľ¬æĿ¥', 'å°±'] +['éĢIJ', 'ä¸Ģ'] +['èģĮä¸ļ', 'æĬĢæľ¯'] +['ä¸įèī¯', 'ä¿¡æģ¯'] +['æīĺ', 'è¿IJ'] +['åIJ¯', '示'] +['ä¹ĭ', 'åħ§å®¹'] +['éŁ', '¶'] +['奢', 'åįİ'] +['æıŃ', '示'] +['æĪIJ为', 'ä¸ŃåĽ½'] +['æ¶Īè´¹', 'åĵģ'] +['åħ¬', 'ç͍'] +['æIJŀ', 'å®ļ'] +['请', 'ä½ł'] +['æŁ', 'ļ'] +['åĨħ', 'è¡£'] +['ä½Ĩ', 'ä»ĸ们'] +['ä¿Ŀ', '湿'] +['该', 'åİ¿'] +['饱', 'åĴĮ'] +['æİ¨', 'åIJij'] +['èµĦæĸĻ', 'æĺ¾ç¤º'] +['ä¸į', 'å½±åĵį'] +['人', '人éĥ½'] +['åıijå±ķ', '壮大'] +['åħ»èĢģ', 'æľįåĬ¡'] +['çĶŁæ´»', 'æ°´å¹³'] +['åIJĦ', 'åİ¿'] +['ä½ł', 'éľĢè¦ģ'] +['说', 'çļĦæĺ¯'] +['å¤ĸ', 'åªĴ'] +['æŃ¤', '人'] +['次', 'è¦ģ'] +['追', 'èµ¶'] +['åºĶ该', 'å¦Ĥä½ķ'] +['æĹ¥', 'åĩĮæĻ¨'] +['çķ¥', 'æľī'] +['éĥ½', 'æĥ³'] +['游', 'ä¹IJ'] +['è¿Ļ款', '游æĪı'] +['å¹³', 'æ·¡'] +['æĺ¯ä¸Ģ', 'åĢĭ'] +['å¤ĩ', 'èĢĥ'] +['åζ', 'æŃ¢'] +['ä¸Ģå®ļ', 'èĥ½'] +['å¾Ĵ', 'å¼Ł'] +['以', 'çĤº'] +['åįĥ', 'åħĥ'] +['äºĶ', 'åħŃ'] +['迪', '士'] +['迪士', 'å°¼'] +['éĺ³', 'æĢ§'] +['åĨ¬å¥¥', 'ä¼ļ'] +['å°±æĺ¯', 'åĽłä¸º'] +['æĮĤ', 'éĴ©'] +['æ¦Ĥ', 'åĨµ'] +['åıªè¦ģ', 'æľī'] +['æ²¹', 'çĶ»'] +['åľ°', 'æłĩ'] +['ä¸Ĭ', 'è°ĥ'] +['产ä¸ļ', 'åĽŃåĮº'] +['åħ«', 'åįģ'] +['æ£', '±'] +['æ¶²', 'æĻ¶'] +['æĿij', 'å§Ķä¼ļ'] +['çŃ¾çº¦', '仪å¼ı'] +['è¿Ļ', 'åħ¶ä¸Ń'] +['åĨĻ', 'éģĵ'] +['示èĮĥ', 'åŁºåľ°'] +['éĩİçĶŁ', 'åĬ¨çī©'] +['鼻åŃIJ', 'ä¿¡ç®±'] +['åĽ½éĻħ', 'è´¸æĺĵ'] +['人', 'æĿĥ'] +['ä¿Ŀ', '管'] +['èĭ¥', 'æĤ¨'] +['åİĭ', 'æĬij'] +['é»', 'Ľ'] +['åľ°', 'çľĭçĿĢ'] +['éĻ', '°'] +['ä¸Ģå¹´', 'å¤ļ'] +['ä»İ', '容'] +['ä¸Ń', 'æĸŃ'] +['å¯Ł', 'è§ī'] +['ç§»', '交'] +['éĶ', '¯'] +['æĪĸ许', 'æĺ¯'] +['ç¶', 'ł'] +['两', '项'] +['æľĢ', 'åĸľæ¬¢'] +['æľĢåĸľæ¬¢', 'çļĦ'] +['å¤ľ', 'éĩĮ'] +['åIJĮ', 'ä»ģ'] +['åĪĽæĸ°', '驱åĬ¨'] +['è°ģ', 'èĥ½'] +['é£', '¾'] +['åħī', 'åѦ'] +['åİ', 'Ħ'] +['èĦ±', 'é¢ĸ'] +['èĦ±é¢ĸ', 'èĢĮåĩº'] +['è¿', '¦'] +['æĺ¯', 'ä¸įåı¯èĥ½'] +['çª', '¥'] +['èĥ½', '满足'] +['宽', '度'] +['伦', 'çIJĨ'] +['åı¯ä»¥', 'èİ·å¾Ĺ'] +['转', 'ä¼ļ'] +['å±±', 'æĿij'] +['éĵº', '设'] +['åĩº', 'åĩ»'] +['æĸĩåĮĸ', 'èīºæľ¯'] +['ä¼ļè®®', '室'] +['æŃĮ', '声'] +['æ»', 'Ķ'] +['èIJİ', '缩'] +['æľįåĬ¡', 'åijĺ'] +['åıij表', 'äºĨ'] +['æĸ¼', 'æĺ¯'] +['æĺİç¡®', 'è§Ħå®ļ'] +['ç»´', 'å¥ĩ'] +['æ°´', '产'] +['æĬķ', 'ä¿Ŀ'] +['éĺ´', 'éģĵ'] +['èµ¶', 'å¿«'] +['夺', 'å¾Ĺ'] +['ä¸ĭ', 'åįķ'] +['çµģ', 'åħ¬åı¸'] +['çݯ', 'ç»ķ'] +['å½', 'Ī'] +['ä½ľé£İ', '建设'] +['æĹħ游', 'æĻ¯åĮº'] +['æľī', 'æĽ´å¤ļçļĦ'] +['丰å¯Į', 'å¤ļ彩'] +['çIJĨè´¢', '产åĵģ'] +['åĩº', 'å·®'] +['ä»İ严', 'æ²»'] +['ä»İ严治', 'åħļ'] +['缸', 'å¹²'] +['æ»ĭ', '润'] +['主åĬŀ', 'æĸ¹'] +['åī§', 'åľº'] +['æ»ļ', 'çIJĥ'] +['æ©Ħ', 'æ¦Ħ'] +['èĩªä¸»', 'åĪĽæĸ°'] +['éĢļ', 'å¾Ģ'] +['æł¼', 'å°Ķ'] +['çļĦ', 'ä¼ĺçĤ¹'] +['èĥĮ', 'ä¸Ĭ'] +['çª', 'ľ'] +['çĪĨ', 'åĩº'] +['å¹³', 'æķ´'] +['ä¸Ģ', 'èĦļ'] +['åħ¨ä½ĵ', 'åijĺå·¥'] +['éĻIJ', 'å®ļ'] +['åŁİéķĩ', 'åĮĸ'] +['æ·', '³'] +['éĢ®', 'æįķ'] +['è¡ĮåĬ¨', '计åĪĴ'] +['æīĵ', 'å¾Ĺ'] +['åİļ', 'éĩį'] +['纪å½ķ', 'çīĩ'] +['åĿļ', 'ä¿¡'] +['央', 'ä¼ģ'] +['åĨį', 'ä¹Łä¸į'] +['天', '涯'] +['åıĤèĢĥ', 'èµĦæĸĻ'] +['æľī', 'æ¯Ĵ'] +['åIJ¸', '纳'] +['è¶Ĭ', 'åıij'] +['éĩįè¦ģ', 'æĦıä¹ī'] +['åĽ½éĺ²', 'éĥ¨'] +['è¿Ļ个', 'è¡Įä¸ļ'] +['æĻ®', 'æŁ¥'] +['å¼Ĥ', 'æĢ§'] +['å»¶', 'è¿Ł'] +['å°ı', 'å¹ħ'] +['èī²', 'æĥħ'] +['综åIJĪ', 'æ²»çIJĨ'] +['æŃ£æĺ¯', 'åĽłä¸º'] +['产ä¸ļ', 'ç»ĵæŀĦ'] +['çłĶç©¶', 'æĬ¥åijĬ'] +['åģľ', 'ä¸ĭ'] +['éķ¿', 'èĢģ'] +['éĩĿ', 'å°į'] +['åįĹ京', 'å¸Ĥ'] +['çģĮ', 'æºī'] +['转', 'è¿IJ'] +['欺', 'è¯Ī'] +['éĢł', 'åģĩ'] +['åĪĨå¸ĥ', 'å¼ı'] +['æĦŁ', '触'] +['æĪij', 'å½ĵæĹ¶'] +['åıij', 'è§ī'] +['åĽ¾', '纸'] +['æĶ¹', 'èī¯'] +['çĭł', 'çĭł'] +['åĨ²', 'åĪº'] +['æĸ°', '京'] +['æĸ°äº¬', 'æĬ¥'] +['ç¥ŀ', 'åύ'] +['秸', 'ç§Ĩ'] +['çĪ', 'º'] +['å°Ĩ', 'è¿İæĿ¥'] +['å·¥', 'ä¿¡'] +['工信', 'éĥ¨'] +['éĻIJ', 'éĩı'] +['æŃ¢', 'æįŁ'] +['åѦä¼ļ', 'äºĨ'] +['åįİ', '缼'] +['åįİ缼', 'é¡¿'] +['å¾Į', 'ä¾Ĩ'] +['ä¸ĭéĿ¢', 'æĺ¯'] +['ä¸ĭéĿ¢æĺ¯', 'å°ı'] +['æIJ¬', 'è¿IJ'] +['ç¾İæľ¯', 'é¦Ĩ'] +['æ¸ħ', 'åĩī'] +['å¤ļå¹´', 'åīį'] +['è©', 'ŀ'] +['åįĥ', 'ç±³'] +['表', 'è¿°'] +['æ±Ł', 'éŨ'] +['åĬłæ²¹', 'ç«Ļ'] +['æľ¬', 'èĥ½'] +['导', '读'] +['åĽ´', 'è§Ĥ'] +['å¹¶', 'åIJij'] +['åŁºæľ¬', 'æĥħåĨµ'] +['æīĵ', 'å¼ĢäºĨ'] +['è¿Ļ', 'ä¸ī个'] +['æ±ķ', '头'] +['强', 'æľīåĬĽ'] +['强æľīåĬĽ', 'çļĦ'] +['è¿Ľ', 'åľº'] +['ä¹Ŀ', 'æ±Ł'] +['çIJĥ', 'æĺŁ'] +['好çľĭ', 'çļĦ'] +['大', 'æĪ·'] +['æ¹', '¯'] +['å¥ĩ', 'å¦Ļ'] +['ä¹IJ', 'åύ'] +['æĪijçļĦ', 'å¿ĥ'] +['çľī', '头'] +['åĨľä¸ļ', 'çĶŁäº§'] +['ç¼ĸ', 'çłģ'] +['åŁº', 'ç¤'] +['åŁºç¤', 'İ'] +['天', 'æĸĩ'] +['åĢĭ人', 'è³ĩè¨Ĭ'] +['åİ»', 'è¿ĩ'] +['èģĨ', 'åIJ¬'] +['æĶ¾', 'åģĩ'] +['ä¸į', 'åħ·å¤ĩ'] +['æ·Ģ', 'ç²ī'] +['大', '佬'] +['åħ¨', '天'] +['åħ¨éĿ¢', '建æĪIJ'] +['éļIJ', 'å½¢'] +['ç¼ħ', 'ç͏'] +['åIJ', '³'] +['è¡ĮæĶ¿', 'æī§æ³ķ'] +['åŁİ', 'åł¡'] +['èİ«', 'æĸ¯'] +['èİ«æĸ¯', 'ç§ij'] +['æīĢæľī', 'æĿĥ'] +['éĽĨ', 'åľĺ'] +['å±Ģ', 'åī¯å±Ģéķ¿'] +['åĩłä¹İ', '没æľī'] +['æ´ģ', 'åĩĢ'] +['ç͵影', 'èĬĤ'] +['åŃ©', 'ç«¥'] +['æīĢ', 'åģļçļĦ'] +['æ¸ħ', '代'] +['æĸ°', 'çīĪ'] +['éĵĿ', 'åIJĪéĩij'] +['为', 'æĬĵ'] +['为æĬĵ', 'æīĭ'] +['åΤ', 'å®ļ'] +['çī¹', '产'] +['æīĭ', 'æ©Ł'] +['ä¸įåı¯', 'æĪĸ'] +['ä¸įåı¯æĪĸ', '缺'] +['å¸Ĥåľº', 'è§Ħ模'] +['åĿ', '¯'] +['åĮ»', 'åѦéĻ¢'] +['å¿«', 'è¦ģ'] +['èĮ', 'ľ'] +['æĬĺ', 'èħ¾'] +['äºĨ', 'è¿ĩæĿ¥'] +['æĬ¥åijĬ', 'æľŁåĨħ'] +['çī©', 'ç§į'] +['ç»Łè®¡', 'å±Ģ'] +['æī©', '建'] +['æ¶', 'ħ'] +['责任', '人'] +['éĺ', 'İ'] +['è¯Ħ', 'è®®'] +['å¾Ģ', 'äºĭ'] +['æīĢ', '示'] +['æķ´', 'æ´ģ'] +['éĹº', 'èľľ'] +['æĹħ', 'éĢĶ'] +['å®ŀ', 'è®Ń'] +['ä¹ĭ', 'ç§°'] +['å·´', '士'] +['éĢŁåº¦', 'å¿«'] +['ä¸įä»ħ', 'å¦ĤæŃ¤'] +['å®Ŀè´µ', 'çļĦ'] +['åºŁ', 'çī©'] +['æ²³', 'æ°´'] +['æİ¥', '纳'] +['ç²¾', 'æ¹Ľ'] +['åħ¶æ¬¡', 'æĺ¯'] +['顺', 'å¾·'] +['åħ¬åħ±', 'åį«çĶŁ'] +['è¤IJ', 'èī²'] +['ä¸į', 'æĥľ'] +['æĬĢæľ¯', 'æľįåĬ¡'] +['æİ', '·'] +['æ±Ĥ', 'èģĮ'] +['ä¸ī', '峡'] +['æĬķåħ¥', 'åΰ'] +['太', 'åIJİ'] +['åIJ¯åĬ¨', '仪å¼ı'] +['缴æİ¥', 'å½±åĵį'] +['æĸ°', '款'] +['个', '乡éķĩ'] +['çϾ', '亿'] +['åº', '«'] +['ä¹Ł', 'æŃ£æĺ¯'] +['åı¶', 'çīĩ'] +['æľĢæĹ©', 'çļĦ'] +['æĪĺ', '绩'] +['å·¥', 'æľŁ'] +['æĻļ', 'æľŁ'] +['è¿Ļæł·', '说'] +['è¯į', 'è¯Ń'] +['ä¾', 'Ħ'] +['æķ£', 'çĥŃ'] +['éĽĨæĪIJ', 'çĶµè·¯'] +['åIJį', 'è¯į'] +['æĻº', 'åķĨ'] +['æĭ¥', 'åłµ'] +['çĭĤ', '欢'] +['è¿Ļ', 'èά'] +['æµ´', '室'] +['åijķ', 'åIJIJ'] +['æľªæĿ¥', 'åıijå±ķ'] +['ä¸īä½į', 'ä¸Ģä½ĵ'] +['åªĴ', 'é«Ķ'] +['ä¸įå¾Ĺ', '转载'] +['åĽłä¸º', '她'] +['æĺ¾ç¤º', 'å±ı'] +['ä¾Ľ', 'æļĸ'] +['éĨ«', 'éĻ¢'] +['æľī', 'æĦıæĢĿ'] +['æľīæĦıæĢĿ', 'çļĦ'] +['娱ä¹IJ', 'åŁİ'] +['åįµ', 'å·¢'] +['åĪĽéĢł', 'åĬĽ'] +['竳', 'èĬĤ'] +['人大', '常å§Ķ'] +['èĢĮ', 'çİ°åľ¨'] +['å¤ĸ', 'å©Ĩ'] +['å¢ŀ', 'æĮģ'] +['äºĶ', 'åįĥ'] +['èĢģå¸Ī', '们'] +['æ´Ľ', 'æĿī'] +['æ´ĽæĿī', '磶'] +['æİĮæı¡', 'äºĨ'] +['ä¸ŃåĽ½', 'æĸĩåĮĸ'] +['æĸ°', 'æĶ¿'] +['主è¦ģ', 'ç͍äºİ'] +['åıij', 'çĥ§'] +['类似', 'äºİ'] +['åĮĹ', 'æŀģ'] +['æĪij们', '认为'] +['å¼¥', '漫'] +['åħ¨çIJĥ', 'ç»ıæµİ'] +['é¢', 'IJ'] +['ä¸Ģèµ·', 'è£ħä¿®'] +['æĶ', 'Ĵ'] +['æĭī', 'èIJ¨'] +['帶', 'ä¾Ĩ'] +['åĨ·', 'æ°´'] +['ä¸ī', 'åĨľ'] +['æĿ¿', 'æĿIJ'] +['è¿ŀ', 'è¿ŀ'] +['éĵ', '®'] +['ç»ıèIJ¥', 'çIJĨ念'] +['å±±', 'é¡¶'] +['å¾Ī', 'æĥ³'] +['çĺ', '«'] +['å§ĭç»Ī', 'ä¿ĿæĮģ'] +['åľ¨', '广å·ŀ'] +['ä¸įåIJĮ', 'æĦı'] +['åıĺ', 'åİĭ'] +['åıĺåİĭ', 'åύ'] +['产', 'éĶĢ'] +['表', 'éĿ¢ä¸Ĭ'] +['æīĢ以', 'ä»ĸ'] +['ç»ıéªĮ', '丰å¯Į'] +['éĥ¨', 'å§Ķ'] +['åħµ', 'åĽ¢'] +['æīĢ', 'è¿°'] +['æķ¦', 'çħĮ'] +['ç»ıèIJ¥', 'èĮĥåĽ´'] +['åı£', 'è¯Ń'] +['失', 'ä¿¡'] +['æ¯ı个人', 'çļĦ'] +['æīĭ', 'æĮģ'] +['æģIJ', 'æħĮ'] +['åł¡', 'åŀĴ'] +['é¦', 'ħ'] +['éĵ¸', 'éĢł'] +['æĭ¿', 'åĩºæĿ¥'] +['æİ¢', 'æµĭ'] +['大家', 'ä¸Ģèµ·'] +['å¥', '§'] +['å®ŀè´¨', 'æĢ§'] +['å°ı', 'åĦ¿'] +['èĩº', 'åįĹ'] +['èĩºåįĹ', 'å¸Ĥ'] +['å¼Ģåıij', 'èĢħ'] +['åı¯', 'æł¹æį®'] +['ç®±', 'åŃIJ'] +['饺', 'åŃIJ'] +['å¿Ļ', 'çĿĢ'] +['æĿ¥', 'ä¸įåıĬ'] +['缸', 'ä¼ł'] +['åĽ½', 'ç½ij'] +['èħ¹', 'æ³»'] +['è¿ĻéĩĮ', 'æľī'] +['é£İ', 'æĻ¯åĮº'] +['åıĤ', 'ä¿Ŀ'] +['æŃ»', 'èĢħ'] +['æĪ´', 'ä¸Ĭ'] +['æ©Ł', 'æ§ĭ'] +['è¯ķéªĮ', 'åĮº'] +['ä¼ł', 'æİĪ'] +['æµ·', 'è¾¹'] +['泪', 'æ°´'] +['缸åħ³', 'åĨħ容'] +['éĥij', 'å·ŀå¸Ĥ'] +['åħij', 'çݰ'] +['两', 'åij¨'] +['èĬľ', 'æ¹ĸ'] +['ç͵åŃIJ', 'ä¿¡æģ¯'] +['红', 'å¤ĸ'] +['æĹħ游', 'å±Ģ'] +['å¾Ģå¾Ģ', 'ä¼ļ'] +['è¿ħ', 'çĮĽ'] +['ä¼ł', '羣'] +['æ¸ħ', 'æ¾Ī'] +['å°±', 'è¿ij'] +['微信', '群'] +['ç³»åĪĹ', 'æ´»åĬ¨'] +['ç»ı常', 'ä¼ļ'] +['è§Ĥ', 'æµĭ'] +['å¿ĥå¾Ĺ', 'ä½ĵä¼ļ'] +['éĻĪ', 'åĪĹ'] +['åĮĹ', 'æĸĹ'] +['è«', '®'] +['è«®', 'è©¢'] +['è¿ĺæĺ¯', 'ä¼ļ'] +['æµĭ', 'ç®Ĺ'] +['æĺŁ', '空'] +['宽', '容'] +['çī©ä¸ļ', 'åħ¬åı¸'] +['æĪĴ', 'æĮĩ'] +['å¸ħ', 'æ°Ķ'] +['ä¸ĢæŃ¥', 'æŃ¥'] +['åħ±', '鸣'] +['åĨ³', 'ä¸į'] +['æİ¥', '管'] +['å¦ĩ', 'èģĶ'] +['æ¯Ķ', 'åĸ»'] +['é²ģ', 'è¿ħ'] +['æĮģ', 'çºĮ'] +['缸', '亲'] +['å¨ģå°¼æĸ¯', '人'] +['ç«ĭ', '项'] +['åĪ', 'Ŀå§ĭ'] +['èĩª', 'åζ'] +['è¿Ī', 'è¿Ľ'] +['ä¸Ĭ', 'æ±½'] +['å®ı', 'ä¼Ł'] +['æł¹æľ¬', '没æľī'] +['æĸ°åĨł', 'çĹħæ¯Ĵ'] +['åĵª', 'ç§į'] +['康', 'åħ»'] +['è¡°', 'èĢģ'] +['å½ķ', 'åĥı'] +['é«Ķ', 'é©Ĺ'] +['ç»ij', 'å®ļ'] +['é¢Ŀ', '头'] +['äºĶ', 'æľĪ'] +['èĬ±', 'å¼Ģ'] +['ä¸Ģ线', 'åŁİå¸Ĥ'] +['åΰ', 'åľº'] +['æĬķ', 'éĻį'] +['çĹĺ', 'çĹĺ'] +['åıĹ', 'ä¸įäºĨ'] +['æīİ', 'æł¹'] +['æĽ´', 'ä½ķåĨµ'] +['æĬ½', 'æŁ¥'] +['åĩº', 'è·¯'] +['审议', 'éĢļè¿ĩ'] +['ä¸į', 'åĥħ'] +['èī²', 'è°ĥ'] +['çϾ', 'ä½Ļ'] +['èĤł', 'éģĵ'] +['æ·±åİļ', 'çļĦ'] +['马', 'åĬĽ'] +['æĹ©', 'æĻļ'] +['æŃĮ', 'èĪŀ'] +['éĺ²', 'æĻĴ'] +['æľĢåIJİ', 'ä¸Ģ个'] +['樱', 'èĬ±'] +['å°ıä¼Ļ', 'åŃIJ'] +['åľ¨', 'å½ĵåľ°'] +['å°ıä¼Ļä¼´', '们'] +['èµ·', 'æºIJ'] +['åħ¨', 'åªĴä½ĵ'] +['ç°', '½'] +['éħ±', 'æ²¹'] +['æĹłè®º', 'å¦Ĥä½ķ'] +['裤', 'åŃIJ'] +['åģľ', '产'] +['ä¸įçͱ', 'å¾Ĺ'] +['çīµ', 'å¼ķ'] +['ä¼ł', 'åĬ¨'] +['ä¹Ŀ', 'é¾Ļ'] +['åĬł', 'åĽº'] +['ä¹Łä¸į', 'æķ¢'] +['æĬĢæľ¯', 'æĶ¯æĮģ'] +['ä¸Ĭ', 'å²Ĺ'] +['ç»ıéªĮ', 'åĴĮ'] +['æł¼', 'æŀĹ'] +['åIJ¸', 'éĻĦ'] +['æľªæĪIJ', 'å¹´'] +['奢ä¾Ī', 'åĵģ'] +['追', 'æį§'] +['好', 'ä¸į容æĺĵ'] +['èķ´', 'åIJ«'] +['ä¿Ŀ', 'å®ļ'] +['æĬ¥', 'ä¸ļ'] +['æµ·', 'åĨħå¤ĸ'] +['ä½ł', 'çİ°åľ¨'] +['æ²¹', 'èĢĹ'] +['è´¨éĩı', '管çIJĨ'] +['æ½ľ', 'æ°´'] +['丽', 'æ±Ł'] +['转', 'åħ¥'] +['è¿Ļä¹Ī', 'ä¹ħ'] +['æĺİ', '代'] +['责任', 'åζ'] +['éĩį', 'å·¥'] +['大', 'å·´'] +['触', 'åıĬ'] +['èµ·', 'åĪĿ'] +['大', 'å¦Ī'] +['æĸ¯', 'å¡Ķ'] +['åĨĽ', 'å·¥'] +['书', 'éĻ¢'] +['å³', '¨'] +['æİ¨', 'çIJĨ'] +['è¿Ļç¯ĩ', 'æĸĩ竳'] +['è¿ģ', 'ç§»'] +['åľ¨', 'åIJĮä¸Ģ'] +['ç»Ĩ', 'ç»Ĩ'] +['åīĬ', 'å¼±'] +['书', 'æĪ¿'] +['ç¶ĵ', '常'] +['è¯ķ', 'é¢ĺ'] +['æĤ£', 'ä¸Ĭ'] +['çĻ«çĹ«', 'çĹħ'] +['åĨ²', 'æ´Ĺ'] +['å¤ĸ', 'æı´'] +['åħĭ', 'åζ'] +['åįģ', 'æľĪ'] +['åģļ', 'ä¸įåΰ'] +['ç¾İ', 'åĮĸ'] +['å¦Ĥ', 'æľŁ'] +['è¿ĺ', 'éľĢ'] +['天', 'åºľ'] +['å°±', 'æĦıåij³çĿĢ'] +['çļĦç¡®', 'æĺ¯'] +['éªĹ', 'å±Ģ'] +['å°ıç»Ħ', 'èµĽ'] +['è©', '©'] +['ä¹Ŀ', 'å¹´'] +['æĻĵ', 'å¾Ĺ'] +['çłĶç©¶', '人åijĺ'] +['大', 'éħĴåºĹ'] +['ç§ij', 'åѸ'] +['åħŃ', 'åIJĪ'] +['çķĮ', 'å®ļ'] +['车', 'è½½'] +['å¼Ģ', 'çĿĢ'] +['毫', 'æĹłçĸij'] +['毫æĹłçĸij', 'éĹ®'] +['è¿IJ', 'ç»´'] +['ç¦ģ', 'åĮº'] +['èĦ±', 'èIJ½'] +['讲', 'å¸Ī'] +['产ä¸ļ', 'åŁºåľ°'] +['é«ĺ', 'æĢ§èĥ½'] +['åħī', '彩'] +['çݰ', 'éĺ¶æ®µ'] +['åĩ', '¿'] +['è¾ĥ', 'å·®'] +['饮', 'çĶ¨æ°´'] +['éĸĭ', 'çϼ'] +['ç½ij', 'åIJ§'] +['çĮ´', 'åŃIJ'] +['æŃ¦', 'æŀĹ'] +['å®ī', 'åİ¿'] +['ä¸įåı¯', 'æĢĿ'] +['ä¸įåı¯æĢĿ', 'è®®'] +['éĬ·', 'åĶ®'] +['è´«', 'ç©·'] +['为', 'åķ¥'] +['éº', 'ĵ'] +['å¹¾', 'åĢĭ'] +['è§Ħ模', '以ä¸Ĭ'] +['æı', 'ļ'] +['被', 'åĽ°'] +['缺', 'å¸Ń'] +['å¿«', 'é¤IJ'] +['æĬ¢', 'åįł'] +['æĻ', 'Ł'] +['å¤į', 'æ´»'] +['æľ¬æĬ¥', '讯'] +['åĪĽ', 'ä¸ĭ'] +['æµ·', '滩'] +['éĩı', '产'] +['å¦Ĥä½ķ', 'åİ»'] +['车', 'ä½į'] +['å¯', 'ĩ'] +['äºĮ', 'åįģåĽĽ'] +['ç»ıæµİ', 'æįŁå¤±'] +['éħįå¥Ĺ', '设æĸ½'] +['åŁºæľ¬', 'éĿ¢'] +['äºī', '论'] +['就好', 'åĥı'] +['çłĶç©¶', 'æĪIJæŀľ'] +['éĻĪ', 'è¿°'] +['æīĵ', 'åĬ¨'] +['ä¸ĭ', 'å·´'] +['ç§Ĵ', 'éĴŁ'] +['对', '人ä½ĵ'] +['æĬĢæľ¯', 'çłĶåıij'] +['åİŁ', 'åŃIJ'] +['æĺ¯ä¸Ģ', '项'] +['äºĨä¸Ģ', '份'] +['æĮĩ', 'çͲ'] +['ç͍', 'éĩı'] +['è¿ĺä¸į', 'å¤Ł'] +['æĶ¿åºľ', 'éĩĩè´Ń'] +['çŁ¥è¯Ĩ', 'çĤ¹'] +['ä¸ŃåĽ½', '梦'] +['å¾Ī', 'å¼Ģå¿ĥ'] +['礼', 'è²Į'] +['éĿŀ常', 'å¤ļ'] +['éĿŀ常å¤ļ', 'çļĦ'] +['åĽ', 'ļ'] +['æĹħ', 'é¦Ĩ'] +['å°½', 'æĥħ'] +['æŃĮ', 'åͱ'] +['æ²Ļ', 'é¾Ļ'] +['车', 'åİ¢'] +['客', 'æµģ'] +['åģı', 'å·®'] +['积累', 'äºĨ'] +['æ¡', 'Ķ'] +['çĶ»', 'çĶ»'] +['ä¹Ł', 'åºĶ该'] +['åºĶç͍', 'ç¨ĭåºı'] +['èĥĥ', 'èĤł'] +['以', 'å¾Į'] +['豪', 'å®ħ'] +['æ·±', 'åĬłå·¥'] +['缴', 'è¨Ģ'] +['åĮĸ', 'çŁ³'] +['åĽ½', 'éģĵ'] +['ä¸ĥ', '个'] +['ä»İèĢĮ', '使'] +['èĤł', 'èĥĥ'] +['æĹ¥', 'è¶ĭ'] +['çζ', 'åŃIJ'] +['ç·', '©'] +['æĭĽ', 'çīĮ'] +['产', 'å¦ĩ'] +['çķª', 'èĮĦ'] +['æĪij', 'éĻ¢'] +['建çŃij', 'å·¥ç¨ĭ'] +['å±ķè§Ī', 'ä¼ļ'] +['å®¶éķ¿', '们'] +['åĨľ', 'ä½ľçī©'] +['æĹ¥', 'å¤ľ'] +['æĶ»', 'æĵĬ'] +['è§Ħ', 'éģ¿'] +['èĪŁ', 'å±±'] +['便', 'æ°ij'] +['åħ«', 'åŃĹ'] +['ä¸į', 'æĽ¾'] +['æĶ¯', 'éħį'] +['çĨ¬', 'å¤ľ'] +['人', 'é¡ŀ'] +['ç´Ģ', 'éĮĦ'] +['ç»ıèIJ¥', 'æ´»åĬ¨'] +['大', '涨'] +['å¸Ĥå§Ķ', '常å§Ķ'] +['åĪĨ', 'éIJĺ'] +['ä¸Ģ个', 'èģĮä¸ļ'] +['çĹħ', 'åĽł'] +['è¿Ļ', '对äºİ'] +['ä¸įå¾Ĺä¸į', '说'] +['åıijç͵', 'æľº'] +['æľīæīĢ', '帮åĬ©'] +['缮æłĩ', 'ä»»åĬ¡'] +['åĽł', 'åľ°'] +['åĽłåľ°', 'åζ'] +['åĽłåľ°åζ', 'å®ľ'] +['å°Ĩ', 'è¾¾åΰ'] +['ç²Ĺ', 'ç³Ļ'] +['稳', 'åĽº'] +['å«', '£'] +['çİ°åľ¨', 'å¾Īå¤ļ'] +['ä¸ĸçķĮ', '级'] +['å¼ł', 'æŁIJ'] +['çĤ¹', 'ç¼Ģ'] +['èij', 'µ'] +['社ä¼ļ', 'ç»Ħç»ĩ'] +['å¾Ģ', 'åIJİ'] +['åĬł', 'æģ¯'] +['åĻª', '声'] +['æľī', 'åħ´è¶£'] +['为æĤ¨', 'æıIJä¾Ľ'] +['æ²¹', 'æ¼Ĩ'] +['ç¬¬åĽĽ', 'å±Ĭ'] +['çļĩ', '宫'] +['ä¹Ĵ', 'ä¹ĵ'] +['ä¹Ĵä¹ĵ', 'çIJĥ'] +['éļ¨', 'èijĹ'] +['éģ©', 'åIJĪ'] +['åįĹ', 'éĿŀ'] +['æĵ', '´'] +['西', 'æ´ĭ'] +['åĬł', 'å¯Ĩ'] +['æĪIJåĬŁ', '举åĬŀ'] +['åı£', 'æ°´'] +['æĪIJ', '年人'] +['æīĢ', 'æıIJä¾ĽçļĦ'] +['éļĶ', 'å£ģ'] +['åľ¨', '京'] +['å½ĵåľ°', 'æĹ¶éĹ´'] +['çŃī', 'åIJĦç§į'] +['é£İ', 'æ°Ķ'] +['å±ĭ', 'éĩĮ'] +['ä¸Ģ', 'åŃĹ'] +['çļĦæĹ¶éĹ´', 'éĩĮ'] +['åĺ¿', 'åĺ¿'] +['å¿«', '讯'] +['ä¸Ń', 'åľº'] +['ä¸Ģ', 'çĵ¶'] +['æ»', 'ķ'] +['é¢Ĩ', 'è·ij'] +['好', 'èݱ'] +['好èݱ', 'åĿŀ'] +['没', 'åħ³ç³»'] +['åĩº', 'å¢ĥ'] +['ä¸įæĺ¯', 'ä¸Ģ个'] +['éĥ½æĺ¯', 'éĿŀ常'] +['éľĩ', 'åĬ¨'] +['èİ·', 'èĥľ'] +['åįļ', 'å¼Ī'] +['æĬļ', 'åħ»'] +['对', 'ç«ĭ'] +['æľįåĬ¡', 'æľºæŀĦ'] +['è°£', 'è¨Ģ'] +['社ä¼ļ', 'ç§ijåѦ'] +['åIJ¬è¯´', 'è¿ĩ'] +['æī', '³'] +['æīĵ', '磨'] +['åı£', 'æľį'] +['好', 'åĥıæĺ¯'] +['以åıĬ', 'åħ¶ä»ĸ'] +['çī¹', 'è´¨'] +['亲', 'è¿ij'] +['ä¸Ģ', 'ç»ı'] +['æ¶', 'Ŀ'] +['éŃĶ', 'æľ¯'] +['éģĵè·¯', '交éĢļ'] +['è§Ħ模', 'æľĢ大'] +['å®ŀæĸ½', 'æĦıè§ģ'] +['ä¹', 'ŀ'] +['ä¸Ģ', 'ä¸ĸ'] +['åŁ·', 'è¡Į'] +['è±Ĩ', 'çĵ£'] +['åĪĹ', '为'] +['æķħ', '宫'] +['çĶŁ', 'åij½åij¨æľŁ'] +['ä¸īç§į', 'èģĮä¸ļ'] +['详ç»Ĩ', 'ä»ĭç»į'] +['å®Į', 'å¤ĩ'] +['岩', 'çŁ³'] +['éļı', 'æīĭ'] +['é£', '²'] +['æķĪæŀľ', 'åĽ¾'] +['ç§ĭ', 'åĨ¬'] +['åĬŁ', 'å¾·'] +['è§Ħ竳', 'åĪ¶åº¦'] +['æĹ¥', 'æ¸IJ'] +['æīĢ', 'éľĢè¦ģ'] +['æīĢéľĢè¦ģ', 'çļĦ'] +['å²Ľ', 'ä¸Ĭ'] +['åĩº', 'åľŁ'] +['åĽ¾', 'æĸĩ'] +['ç§ijæĬĢ', 'è¿ĽæŃ¥'] +['éĢļ', 'èĥĢ'] +['èĢģ', '太太'] +['èĭĹ', 'æľ¨'] +['éĵ¶', 'å·Ŀ'] +['å¸IJ', '篷'] +['éĿŀ', 'è¦ģ'] +['éħį', 'ç͵'] +['å¤Ħ', 'å¢ĥ'] +['èĤ¡æĿĥ', 'æĬķèµĦ'] +['ä¸Ģ缴', 'åΰ'] +['åĿĩ', 'çͱ'] +['æĬĹ', 'æĹ¥'] +['æį®', 'ä»ĭç»į'] +['ä½ł', 'åĸľæ¬¢'] +['åĪĽæĸ°', 'åŀĭ'] +['åıĺ', 'è¿ģ'] +['è§Ĩ', 'å¯Ł'] +['å®Įåħ¨', '没æľī'] +['åħĥ', 'æĹ¦'] +['åı¯', 'ä¿¡'] +['åı¦', 'è¡Į'] +['æĿij', '级'] +['åħ¥', 'åľº'] +['æIJŃ', 'æ¡£'] +['ä¹Ł', 'åĽłæŃ¤'] +['æį¢', 'æĪIJ'] +['ä¸į', 'è´Ł'] +['äºĨ', '大éĩıçļĦ'] +['éģĶ', 'åΰ'] +['å¸Ĥ', 'åİ¿'] +['å¹´', 'è¼ķ'] +['å¿«', 'æīĭ'] +['å¸Į', 'å°Ķ'] +['èĩª', 'èIJ¥'] +['éĽª', 'èĬ±'] +['æIJ', 'ģ'] +['çľ¼', 'ç§ij'] +['æŃ£', '確'] +['çļĦ', 'å§¿æĢģ'] +['åĿļå®ŀ', 'çļĦ'] +['æĮĩ', '纹'] +['æªĶ', 'æ¡Ī'] +['ç½®', 'äºİ'] +['佩', 'æľį'] +['豪', 'éŨ'] +['åĵ', 'Ĵ'] +['æģ°', '好'] +['檢', 'æŁ¥'] +['åĪĿ', 'è¡·'] +['大', 'åĶIJ'] +['约', 'ä¼ļ'] +['èĴ¸', 'åıij'] +['çѹ', 'åĪĴ'] +['å¹´', 'ç»Ī'] +['è¡Į', 'æ¥Ń'] +['åħ±', 'éĿĴ'] +['åħ±éĿĴ', 'åĽ¢'] +['ä¼ļ', 'å¼ķèµ·'] +['ä¸Ń', 'ç§ij'] +['ä¸Ńç§ij', 'éĻ¢'] +['æĮ¯', 'åĬ¨'] +['åį´', 'åıijçݰ'] +['ä¸įåĬ¨', '产'] +['èĮ', '¹'] +['æĪ¿éĹ´', 'éĩĮ'] +['è´§å¸ģ', 'æĶ¿çŃĸ'] +['æ²»', 'çĻĤ'] +['æħİ', 'éĩį'] +['å¡ŀ', 'å°Ķ'] +['åĽ½', 'ç±į'] +['åĽł', 'æŀľ'] +['çŃī', 'çī¹çĤ¹'] +['å±±', 'è°·'] +['ä¸ĭ', 'è¼ī'] +['è®ĵ', 'æĪij'] +['饮', 'éħĴ'] +['è¿Ļ个', '游æĪı'] +['ç»Ŀ', '大éĥ¨åĪĨ'] +['åĴ¨è¯¢', 'æľįåĬ¡'] +['å¹²', 'æ´»'] +['è®®', 'ä¼ļ'] +['æ¦Ĥ', 'è¿°'] +['åĪĨ', 'åĮº'] +['æŃ»', 'åIJİ'] +['ç«Ļ', 'çĿĢ'] +['主è¦ģ', 'é¢Ĩ导'] +['åIJĮ', 'åŁİ'] +['大', 'æłij'] +['对', 'åѦçĶŁ'] +['社ä¼ļ', 'ä¿ĿéĻ©'] +['å¢ŀ', 'èµĦ'] +['主人', 'åħ¬'] +['å®£ä¼ł', 'æķĻèĤ²'] +['æĸĩåĮĸ', '交æµģ'] +['客', 'æĪ¶'] +['çŁ¥åIJį', 'åĵģçīĮ'] +['æ»ŀ', 'åIJİ'] +['äºĴ', 'è¡¥'] +['æĦŁ', '人'] +['åī', '¿'] +['åIJİ', '代'] +['äºī', '龸'] +['æķĻèĤ²', 'åŁ¹è®Ń'] +['éĿĻ', 'èĦī'] +['ä¹ı', 'åĬĽ'] +['说', 'åĩºæĿ¥'] +['çİĭèĢħ', 'èį£èĢĢ'] +['åĢ', '«'] +['åįĩ', 'èµ·'] +['éķ', 'ģ'] +['åĩº', '游'] +['éĢļè¡Į', 'è¯ģ'] +['å·¥ä½ľ', 'å²Ĺä½į'] +['åĮł', 'å¿ĥ'] +['æĭ¿', 'æĿ¥'] +['æ´Ĺè¡£', 'æľº'] +['æĪijä¸į', 'æĥ³'] +['é¢Ħ', 'è§ģ'] +['æ¼Ķ', '示'] +['ä¸Ģ缴', '没æľī'] +['è·Ł', '她'] +['对çħ§', 'æ£ĢæŁ¥'] +['ç°', '¿'] +['ä¸ĵ', 'å¿ĥ'] +['è®®', 'äºĭ'] +['åīį', '端'] +['åį¡', 'å°Ķ'] +['è¨Ń', 'å®ļ'] +['设置', 'äºĨ'] +['å©ļ', '纱'] +['åľ¨', 'åĽ½å¤ĸ'] +['åı³', 'ä¾§'] +['è³¼', 'çī©'] +['å¥ĩ', 'èij©'] +['å¢ŀåĬł', 'å̼'] +['好', 'è¿IJ'] +['åĽ½éĻħ', 'æľºåľº'] +['ä¸ĭ', 'ç§°'] +['缮åīį', '为æŃ¢'] +['ç¥ŀ', 'ä»Ļ'] +['å®ĥ', 'åı¯ä»¥'] +['æ¾Ħ', 'æ¸ħ'] +['èĥ½', '使'] +['游', 'åĩ»'] +['游åĩ»', 'éĺŁ'] +['åĩ', '¹'] +['ä¸įè¦ģ', 'åĨį'] +['åĨ³', 'èĥľ'] +['åĨ³', 'æĪĺ'] +['æĭ', '½'] +['缼', 'åħ¸'] +['å¾Ī好', 'åľ°'] +['æľĢ', 'ç¾İçļĦ'] +['åĥ', 'ļ'] +['å·´', 'åŁº'] +['å·´åŁº', 'æĸ¯åĿ¦'] +['æľĢ', 'éĢĤåIJĪ'] +['é«ĺ', 'èģĮ'] +['ä¿Ŀ', 'å§Ĩ'] +['æİĪ', 'æ¬Ĭ'] +['说åΰ', 'è¿ĻéĩĮ'] +['æİ¨', 'å¼Ģ'] +['çİĩ', 'è¾¾'] +['ä¸īåĪĨ', 'ä¹ĭä¸Ģ'] +['管çIJĨ', 'ä¸Ńå¿ĥ'] +['交', 'æ±ĩ'] +['森æŀĹ', 'åħ¬åĽŃ'] +['å¾Ģ', 'ä¸Ĭ'] +['éªij', 'è¡Į'] +['æį®', 'æŃ¤'] +['纽', '带'] +['ç»', 'ŀ'] +['ä¸ī', 'æĸ¹'] +['æĦıä¹ī', 'ä¸ĬçļĦ'] +['æİ¨', 'è¿Ł'] +['å¤ļæł·', 'æĢ§'] +['æĥ³', 'èµ·äºĨ'] +['æİĴåIJį', '第'] +['å·¨', 'é¢Ŀ'] +['æĿŁ', 'ç¼ļ'] +['å®ī', 'å®ļ'] +['äºĭ', '實'] +['çļĦ', 'æĦ¿æľĽ'] +['è£ħå¤ĩ', 'åζéĢł'] +['人', 'å±ħ'] +['人å±ħ', 'çݯå¢ĥ'] +['å¿ĺè®°', 'äºĨ'] +['该', '游æĪı'] +['楼', 'ä¸Ĭ'] +['å¼Ģ', 'ä¼ļ'] +['æģ', '³'] +['åıĭæĥħ', 'éĵ¾æİ¥'] +['ç¡', 'Ĵ'] +['ç»ĻäºĪ', 'äºĨ'] +['åģı', '好'] +['åĵ', 'ī'] +['交éĢļ', 'å®īåħ¨'] +['éĽ', 'Į'] +['æ²»', 'çĹħ'] +['è§īå¾Ĺ', 'å¾Ī'] +['衬', 'è¡«'] +['å¿ĥ', 'æĦ¿'] +['æ´ŀ', 'å¯Ł'] +['æ°ij', 'æ£Ģå¯ŁéĻ¢'] +['æıIJ', 'çĤ¼'] +['è¦ģ', 'è¿Ľä¸ĢæŃ¥'] +['驾', '车'] +['æĻ®', 'æĥł'] +['æķ', 'ĸ'] +['ç¦ı', 'éŁ³'] +['éĢģ', 'è¾¾'] +['è§ĦåĪĴ', '设计'] +['æīĭ', 'å¥Ĺ'] +['å®ī', 'ä¿Ŀ'] +['è¿ĺä¸į', 'å¦Ĥ'] +['åīį', 'è¿°'] +['æłĩ', 'è®°'] +['ç´§', 'æİ¥çĿĢ'] +['æ§', 'IJ'] +['深深', 'åľ°'] +['满满', 'çļĦ'] +['æĺ¥', 'è¿IJ'] +['æĹ¥', '产'] +['çα', 'æĬ¤'] +['åħ¨', 'æĹ¥'] +['åħ¨æĹ¥', 'åζ'] +['转', 'åĬ¨'] +['ç¥Ń', 'ç¥Ģ'] +['ä¹°', 'ä¸ľè¥¿'] +['对', 'æľªæĿ¥'] +['æ¶Ī失', 'äºĨ'] +['åļ´', 'éĩį'] +['ä¸ī', 'æĿ¡'] +['éħ¸', '奶'] +['éĽĨåĽ¢', 'èĤ¡ä»½'] +['西', 'è·¯'] +['åıª', 'å¾Ĺ'] +['éĢģ', 'åİ»'] +['çĭł', 'æĬĵ'] +['åĪ©ç͍', 'çİĩ'] +['ä¸ĭ', 'åij¨'] +['å¥ĭ', 'æĪĺ'] +['æĺ¥èĬĤ', 'æľŁéĹ´'] +['è´Ł', '责任'] +['æĺĤ', 'è´µ'] +['å°¾', 'å·´'] +['ç¯ĩ', 'æĸĩ竳'] +['åħ', '®'] +['è®Ĭ', 'æĪIJ'] +['å¹', '¹'] +['çĻ»', 'éĮĦ'] +['ä½', 'Ī'] +['å·¥', 'åĮł'] +['åĵªæĢķ', 'æĺ¯'] +['åıį', 'åĵį'] +['ç§', 'ĥ'] +['åĩº', '轨'] +['æĹ¥', 'åĨĽ'] +['åIJį', 'èªī'] +['æķı', 'éĶIJ'] +['æľįåĬ¡', 'æ°´å¹³'] +['çħ§', 'å°Ħ'] +['ä¼Ĭ', 'æĭī'] +['ä¼Ĭæĭī', 'åħĭ'] +['åĨħ', 'éĺģ'] +['èĬĴ', 'æŀľ'] +['ä¸ĩ', 'åĪĨ'] +['éĢĢ', '款'] +['缴æĴŃ', 'éĹ´'] +['æĭ¿', 'åΰäºĨ'] +['å°İ', 'èĩ´'] +['空æ°Ķ', 'ä¸Ń'] +['客æĪ·', 'æľįåĬ¡'] +['è¿IJ', 'åĬ¿'] +['ç»ĵ', 'çŁ³'] +['ä¸į', 'å¿ħè¦ģçļĦ'] +['èĥ¶', 'åĽĬ'] +['çIJĨ', 'ä¼ļ'] +['æĬ½', 'åĩº'] +['空æ°Ķ', 'è´¨éĩı'] +['æ¯ķ', '竣æĺ¯'] +['åĨ·', 'æ¼ł'] +['ä¸Ģ', 'å¦Ĥ'] +['ä¸Ģå¦Ĥ', 'æĹ¢'] +['ä¸Ģå¦ĤæĹ¢', 'å¾Ģ'] +['æĤ£', 'çĹħ'] +['åĬł', 'æĮģ'] +['èµŀ', 'åĬ©'] +['é«', '®'] +['åij½', 'ä¸Ń'] +['æĦıä¹ī', 'ä¸Ĭ'] +['ä¸į', 'èĪį'] +['åģļ', '梦'] +['æīĵ', 'æī«'] +['æĺŁ', 'åħī'] +['æĸŃ', 'è£Ĥ'] +['åħ¨', 'å¥Ĺ'] +['è£ģ', 'å®ļ'] +['马', 'åħĭæĢĿ'] +['骨', '骼'] +['ä¸Ģ', 'è·¯ä¸Ĭ'] +['å®ļ', 'æĹ¶'] +['å·¥ç¨ĭ', 'æĬĢæľ¯'] +['å½¼', 'å¾Ĺ'] +['æ±²', 'åıĸ'] +['ä¸Ģ', 'è§Ī'] +['åIJµ', 'æŀ¶'] +['ä¿Ĺ', 'ç§°'] +['æłª', 'æ´²'] +['åºŁ', 'æĹ§'] +['è¡Į', 'æĺŁ'] +['åıijçĶŁ', 'åıĺåĮĸ'] +['é¦ĸ', 'ä»ĺ'] +['åįģåĪĨ', 'éĩįè¦ģ'] +['æĬĬ', 'è¿ĻäºĽ'] +['ç¥ŀ', 'å·ŀ'] +['æıIJä¾Ľ', 'åķĨ'] +['æ¥', '·'] +['å±', 'İ'] +['çĬ¶', 'åħĥ'] +['åŁİ', 'å¢Ļ'] +['çľĭ', 'ä¸Ģçľĭ'] +['çĶŁäº§', 'èĥ½åĬĽ'] +['åŁºæľ¬ä¸Ĭ', 'éĥ½'] +['æīĵ', 'æī°'] +['åĪĿ', '次'] +['åĩº', '示'] +['åħ¶ä¸Ń', 'ä¸Ģ个'] +['çĶŁæĢģ', 'ç³»ç»Ł'] +['æīĭ', 'æİĮ'] +['æµİåįĹ', 'å¸Ĥ'] +['åľĭ', 'åħ§'] +['æŃ£', 'å̼'] +['å¹¾', 'ä¹İ'] +['æİ¨èįIJ', 'éĺħ读'] +['è¿Ń', '代'] +['è°ĥ', 'ä¾ĥ'] +['饮', 'åĵģ'] +['å¢Ļ', 'ä½ĵ'] +['åıĺ', 'çݰ'] +['äºĨ', '好'] +['äºĨ好', 'åĩł'] +['ä¸į', 'çķĻ'] +['çĪ', '²'] +['å°½', 'æĹ©'] +['æŃ£åľ¨', 'è¿Ľè¡Į'] +['åĩº', 'éĻ¢'] +['æĿĢ', '害'] +['æıIJ', '款'] +['åıijå±ķ', '空éĹ´'] +['åīį', '身'] +['ä¸įæĸŃ', 'å¢ŀ强'] +['æ·±', 'å±Ĥ次'] +['容', '纳'] +['éĤ£', '份'] +['å·¥ä½ľ', 'æķĪçİĩ'] +['æľ¬', 'åĽ½'] +['失', 'èIJ½'] +['æŃ£', 'åĽłä¸º'] +['èĬĤ', 'æ°´'] +['ä¸ĭ', 'ä¸Ģ代'] +['çłĶåıij', 'ä¸Ńå¿ĥ'] +['ä¸į', 'çIJĨ'] +['å®Į', '好'] +['ä¿ĿæĬ¤', 'åĮº'] +['ç»ĵæŀĦ', 'è°ĥæķ´'] +['å¥ł', 'å®ļ'] +['宣', 'ç§°'] +['éĺ»', 'æĮ¡'] +['æĴ¤', '离'] +['ä¸į', 'æĸ¹ä¾¿'] +['åĴ', 'ķ'] +['ç¬ijäºĨ', 'ç¬ij'] +['çݯå¢ĥ', '污æŁĵ'] +['ä½ı', 'æĪ·'] +['ç»Ŀ', 'ç¼ĺ'] +['éϤ', 'å°ĺ'] +['é«ĺ', 'å°ļ'] +['æĢİä¹Ī', 'åı¯èĥ½'] +['éĿ¢', 'èī²'] +['åķĨ', 'æ¥Ń'] +['çĸ', '¹'] +['èµĦæºIJ', 'ä¼ĺåĬ¿'] +['è¾ĸåĮº', 'åĨħ'] +['èĢĢ', 'çľ¼'] +['æij§', 'æ¯ģ'] +['ä¸ĸçķĮ', 'ç»ıæµİ'] +['å¼ķ', 'æĿ¥'] +['ä¸Ģ', 'åĪĻ'] +['æĭĩ', 'æĮĩ'] +['æĬµ', '御'] +['éĽ', 'į'] +['åĩĨå¤ĩ', 'å·¥ä½ľ'] +['çıł', 'ä¸īè§Ĵ'] +['ç¨Ģ', 'åľŁ'] +['èİ·å¾Ĺ', 'æĦŁ'] +['æĪIJåĬŁ', 'çİĩ'] +['ç½ij', '约'] +['ç½ij约', '车'] +['èĦ', 'IJ'] +['æķ¬', 'ä¸ļ'] +['éĩij', 'ä»·'] +['ç²¾', 'é«ĵ'] +['ä¹°', '车'] +['åħ³', 'åı£'] +['åĨį', 'å¤ļ'] +['æŀģ', 'åĵģ'] +['åIJĦ', 'å®¶'] +['举æĬ¥', 'ç͵è¯Ŀ'] +['èļ', 'Ĭ'] +['æĸ¹', 'å½¢'] +['ç§ijæĬĢ', 'æĪIJæŀľ'] +['æľĢ好', 'æĺ¯'] +['éĹ®', 'åĢĻ'] +['红', 'éħĴ'] +['åĽĽ', 'ç§į'] +['ç¿Ĵ', 'æħ'] +['ç¿Ĵæħ', '£'] +['åŀ', '¦'] +['éĤ£', 'åıª'] +['é¢Ĩ', 'æĤŁ'] +['çľ¼', 'éĥ¨'] +['æ³°', 'å®ī'] +['ä»»', 'æľŁ'] +['磨', 'æįŁ'] +['æĽ¿', 'æį¢'] +['åħ¸', '礼'] +['符åIJĪ', 'æĿ¡ä»¶'] +['è¿ĺæľī', 'ä»Ģä¹Ī'] +['åħ±äº«', 'åįķ车'] +['åı¯', 'åĪĨ为'] +['åŃ£', 'åIJİ'] +['åŃ£åIJİ', 'èµĽ'] +['举èİŀ', 'å¸Ĥ'] +['å¿ĥ', 'æĦı'] +['æīŃ', 'æĽ²'] +['ä½ľä¸º', 'ä¸Ģç§į'] +['è¿Ļ', 'éĥ¨åĪĨ'] +['åıĤä¸İ', 'åΰ'] +['ç½ij', 'çIJĥ'] +['實', 'çı¾'] +['ç»Ħ', 'è£ħ'] +['åIJij', 'å¤ĸ'] +['å·¥ä½ľ', 'æĸ¹æ¡Ī'] +['åįģ', 'æĿ¡'] +['課', 'ç¨ĭ'] +['颤', 'æĬĸ'] +['åĵ', '©'] +['éĤ®', 'å¯Ħ'] +['äº', '¢'] +['åħį', 'è²»'] +['ç§', '¤'] +['åºĶæĢ¥', '管çIJĨ'] +['åĽĽ', 'äºĶ'] +['éºĴ', 'éºŁ'] +['å¾Ĵ', 'æŃ¥'] +['è¨ĺ', 'å¾Ĺ'] +['çĴ', 'IJ'] +['æĺ¯åIJ¦', 'ä¼ļ'] +['æĦıè§ģ', 'åıįé¦Ī'] +['éļ¾', 'æĢª'] +['çª', 'į'] +['交', 'æİ¥'] +['两', 'åįĥ'] +['æĩī', 'ç͍'] +['æľŁ', 'éĸĵ'] +['æIJ¬', 'åΰ'] +['è®®', 'é¢ĺ'] +['碧', 'æ¡Ĥ'] +['碧æ¡Ĥ', 'åĽŃ'] +['åģļ', 'çĶŁæĦı'] +['éĻĽ', 'ä¸ĭ'] +['è·', 'ĭ'] +['èĢģ人', 'å®¶'] +['带', 'åĽŀ'] +['æŀ¸', 'æĿŀ'] +['è¡Į', 'éķ¿'] +['åĨħ容', 'ç®Ģä»ĭ'] +['æ¢', '¢'] +['æĮĩ', 'æİ§'] +['éĩį', 'çĹĩ'] +['ç½ijåıĭ', '们'] +['çı¾', '代'] +['ç±»', '产åĵģ'] +['å¥Ķ', 'æ³¢'] +['æ¸', 'º'] +['ç²ī', 'ç¢İ'] +['è¿Ļ', 'åıªæĺ¯'] +['æ£Ģå¯Ł', 'æľºåħ³'] +['é½', 'Ĭ'] +['æĪ¿', 'ç§Ł'] +['å¾·', 'æĭī'] +['å²ģ', '以ä¸Ĭ'] +['纯', 'åĩĢ'] +['åĪĨå¸ĥ', 'åľ¨'] +['èĥ½', 'å¾Ĺåΰ'] +['ä¸į', 'å°½'] +['ç«ŀ', 'ä»·'] +['çļĦ', '带é¢Ĩ'] +['çļĦ带é¢Ĩ', 'ä¸ĭ'] +['ä¸Ńèį¯', 'æĿIJ'] +['æĿij', 'éķĩ'] +['ä¸įåı¯', 'éģ¿åħį'] +['éľ²', '天'] +['å°ı', 'å§ijå¨ĺ'] +['çī©', 'ä»¶'] +['èijĹä½ľ', 'æĿĥ'] +['æĭĺ', 'çķĻ'] +['éĥ½', 'è§īå¾Ĺ'] +['æĽ²', 'æĬĺ'] +['æ·»åĬł', 'åīĤ'] +['åı¬', 'åĽŀ'] +['æīİå®ŀ', 'æİ¨è¿Ľ'] +['æĬĦ', 'è¢Ń'] +['åĮĸ', '身'] +['缴', 'èIJ¥'] +['ä¹Ł', 'å¸ĮæľĽ'] +['èį£èªī', 'ç§°åı·'] +['åįĸ', 'ç»Ļ'] +['æľī', 'ä¸įåIJĮçļĦ'] +['å¥ĩ', 'çī¹'] +['éĥ½', '认为'] +['å¦', 'ŀ'] +['æĪIJéķ¿', '为'] +['辩', 'æĬ¤'] +['主', 'æķĻç»ĥ'] +['æ³ķå¸Ī', 'èģĮä¸ļ'] +['æ¤į', 'åħ¥'] +['ç´¢', 'å°¼'] +['åIJ¬', 'è¿ĩ'] +['ä¹łæĥ¯', 'äºĨ'] +['夺', 'åıĸ'] +['éŁ', 'ĵ'] +['æľ¬è´¨', 'ä¸Ĭ'] +['æİ¥', 'åĬĽ'] +['äºij', '端'] +['è¦ģ', 'åģļ好'] +['è·¯', 'çģ¯'] +['åįıåIJĮ', 'åıijå±ķ'] +['æľī', 'å¾ħ'] +['æ°´', 'åŁŁ'] +['æIJľçĭIJ', 'é¦ĸ页'] +['è´¨éĩı', 'å®īåħ¨'] +['åįģäºĮ', 'äºĶ'] +['åĵ®', 'åĸĺ'] +['èĵ¬åĭĥ', 'åıijå±ķ'] +['åIJį', '声'] +['身', '亡'] +['çİĭ', 'åºľ'] +['åİŁåĪĻ', 'ä¸Ĭ'] +['çĥĺ', 'å¹²'] +['éģĹ', 'æ¼ı'] +['éĿ¢', '缮'] +['åĽ½', 'ä¼ļ'] +['ä¸Ģ缴', 'éĥ½æĺ¯'] +['æľīä¸Ģ', 'ä½į'] +['éħį', 'æľī'] +['éĻª', 'çĿĢ'] +['ä¼ģ', 'åĽ¾'] +['æĮī', 'ä¸ĭ'] +['èĵĿ', 'åĽ¾'] +['æ©', 'ĺ'] +['大å¤ļ', 'æĺ¯'] +['辩', '论'] +['æĹĭ', 'å¾ĭ'] +['æĬ¥', 'éĢģ'] +['æĿ¡', 'è§Ħå®ļ'] +['åĬ¨', 'éĿĻ'] +['åĮĪ', '奴'] +['æĭľ', '访'] +['ä¸Ģ', 'åĪĢ'] +['ä»ĸ', 'çŁ¥éģĵ'] +['主', 'æĿĥ'] +['ä»ĸ', 'æĽ¾'] +['æĴŃ', 'ç§į'] +['å£ģ', 'åŀĴ'] +['çī¢è®°', '使åij½'] +['åľ¨è¿Ļ', 'æĸ¹éĿ¢'] +['æīĭ', 'èħķ'] +['æĶ¯', 'æŀ¶'] +['ä¾Ĩ', 'èĩª'] +['éĩį', 'å¡ij'] +['å¤ļ', 'å±Ĥ次'] +['ä»ĭ', 'è´¨'] +['éĿ¢', 'åŃĶ'] +['æ½®', '湿'] +['åİ¿', 'åŁŁ'] +['游æĪı', 'å½ĵä¸Ń'] +['å£', 'ŀ'] +['åĪĹ', 'åĩº'] +['èµĽ', 'åĮº'] +['å¤ļ', 'åįĬ'] +['éĩįçĤ¹', 'å·¥ä½ľ'] +['æĪij们', 'å¿ħé¡»'] +['æŁı', 'æŀĹ'] +['é²ģ', 'èĥ½'] +['æĸ½', 'å±ķ'] +['åIJĦ', 'åĮº'] +['åħį', 'ç¨İ'] +['èµĽ', 'åIJİ'] +['æľĢ', 'éĩįè¦ģ'] +['ä¸Ģ个', '好çļĦ'] +['è¿Ŀæ³ķ', 'è¿Ŀè§Ħ'] +['äºĨè§£', 'æĽ´å¤ļ'] +['æķ¬', '请'] +['ç¬ijçĿĢ', '说'] +['ä¸įæĸŃ', 'åıijå±ķ'] +['æijĦå½±', 'å¸Ī'] +['以', 'éĺ²'] +['çĤ¸', 'å¼¹'] +['声', 'åĵį'] +['ç¤', 'ģ'] +['æĩ', '¿'] +['èĪĨ', 'æĥħ'] +['èĩªçͱ', 'è´¸æĺĵ'] +['æķı', 'æį·'] +['ä¸ī大', 'éĺ¶æ®µ'] +['èĭ', 'Ķ'] +['æĹº', 'åŃ£'] +['ä¸į', '满æĦı'] +['微信', 'åı·'] +['ä¿®', '为'] +['çł´', 'è£Ĥ'] +['éĢĥ', '离'] +['æ¯ı', 'èĤ¡'] +['è¾¾', 'ä¸įåΰ'] +['æ¯ıå¹´', 'éĥ½'] +['çģ¯', '笼'] +['æŃ¤', 'åŁºç¡Ģä¸Ĭ'] +['åĥı', '个'] +['åĪĨ', '娩'] +['æĻ', '¾'] +['ä¸į', 'èĩ³äºİ'] +['红', '线'] +['误', 'è§£'] +['举', 'è·¯'] +['æ·®', 'å®ī'] +['产', 'åѦ'] +['产åѦ', 'çłĶ'] +['èī¾', 'æ»ĭ'] +['è»ĭ', 'çĹħ'] +['åīįæıIJ', 'æĺ¯'] +['æ¯ı', 'ä¸Ģ天'] +['ä¸ĥ', '大'] +['æłij', 'åı¶'] +['èµ°', 'å¾Ĺ'] +['è¿Ļ', '两ç§į'] +['æİı', 'åĩº'] +['æİ', 'IJ'] +['é¢Ĩ导', 'èĢħ'] +['ä¸Ģ', 'æľµ'] +['个å¤ļ', 'æľĪ'] +['ä¸Ń', 'åħ³'] +['ä¸Ńåħ³', 'æĿij'] +['课åłĤ', 'æķĻåѦ'] +['大', 'åĴĸ'] +['éģĭ', 'ç͍'] +['è¯ļ', 'æĦı'] +['ç»Ħ', 'åĽ¾'] +['è¯ķ', 'çĿĢ'] +['ä¹Ķ', 'æ²»'] +['è¿ĺ', 'ä¸įæĺ¯'] +['æľī', 'æĽ´å¥½çļĦ'] +['åIJİ', 'å¤ĩ'] +['æĸ°çĶŁ', 'åĦ¿'] +['æ°Ķ', 'è¡Ģ'] +['æ²¥', 'éĿĴ'] +['å±ı', 'éļľ'] +['æ¥Ń', 'åĭĻ'] +['æĪij', '以为'] +['éķ¿', '缸'] +['èĢģ', 'çΏ'] +['éķĩ', 'æ±Ł'] +['æľºæ¢°', '设å¤ĩ'] +['ä½Ĩæĺ¯', 'å¦Ĥæŀľ'] +['åĿļå®ļ', 'ä¸į'] +['åĿļå®ļä¸į', 'ç§»'] +['åĨ²', 'éĶĭ'] +['ç®Ģ缴', 'æĺ¯'] +['åĤ¨', 'èĵĦ'] +['纯', 'ç͵åĬ¨'] +['漫', 'æŃ¥'] +['举', 'èµ·'] +['æģ¶', 'æĢ§'] +['è¨ĺ', 'éĮĦ'] +['èģĮèĥ½', 'éĥ¨éŨ'] +['åħ¨', 'éķ¿'] +['鼻', 'è¦ĸ'] +['ä¹³', 'èħº'] +['ä½ķ', 'å¤Ħ'] +['æ¶Ī', 'æŀģ'] +['æŃ£', 'å¤Ħäºİ'] +['å®ī', 'å®ģ'] +['æĪIJ', 'éķ·'] +['åıĻ', 'è¿°'] +['æºĥ', 'çĸ¡'] +['ä½Ĩ', 'çİ°åľ¨'] +['女', 'æĺŁ'] +['å©´', 'å¹¼åĦ¿'] +['æĬķ', 'èŀįèµĦ'] +['éĹ®', 'éĹ®'] +['æıŃ', 'å¼Ģ'] +['è¯', 'ı'] +['åIJį', 'å½ķ'] +['èĺij', 'èıĩ'] +['åIJĬ', 'é¡¶'] +['æ¹ĸ', 'åĮº'] +['åįĸ', 'åľº'] +['建', 'ç¯'] +['建ç¯', 'ī'] +['èİ', '½'] +['åIJ¬', 'åIJ¬'] +['ç«ŀäºī', 'ä¼ĺåĬ¿'] +['åĩº', 'ä»»'] +['æľī', '两ç§į'] +['橱', 'æŁľ'] +['è¤', 'ª'] +['è¯ķ', 'åį·'] +['ç»ıæµİ', 'æĬĢæľ¯'] +['æ·±', 'å±Ĥ'] +['éĩįè¦ģ', 'åĨħ容'] +['é£İ', 'æİ§'] +['çĬ¶æĢģ', 'ä¸ĭ'] +['éĥ¨', 'éĸĢ'] +['广', 'æ±½'] +['è§Ĥ', 'æij©'] +['éģĹ', 'çķĻ'] +['转', 'è´¦'] +['æĮģ', 'ä»ĵ'] +['æĢ»', '计'] +['åľĺ', 'éļĬ'] +['æĪ¿', '举'] +['éĺĢ', 'éŨ'] +['åħ¬', 'åħ³'] +['åħ³', 'åĪĩ'] +['èĤ', 'ĺ'] +['æķ¸', 'æĵļ'] +['ä¸ī', 'åįģå¹´'] +['è§ģè¯ģ', 'äºĨ'] +['å±', 'Ĩ'] +['çģ°', 'å°ĺ'] +['æ¦ľ', 'é¦ĸ'] +['è¦ĨçĽĸ', 'çİĩ'] +['ä»Ļ', '女'] +['çĶŁäº§', 'æĢ»'] +['çĶŁäº§æĢ»', 'å̼'] +['æĪ¿', 'è´·'] +['æ±Ł', 'åĮº'] +['åħħç͵', 'æ¡©'] +['çϾ', 'åIJĪ'] +['確', 'èªį'] +['转', 'ç§»åΰ'] +['éĥ½', 'æĹłæ³ķ'] +['纪念', 'é¦Ĩ'] +['çŃ¾ç½²', 'äºĨ'] +['å¹¶ä¸į', 'å¤ļ'] +['æĮ', 'ł'] +['ä¸į太', '好'] +['ä¸ĸ', '代'] +['误', '导'] +['é«ĺå³°', '论åĿĽ'] +['åħ¼', '容'] +['龸', 'æ°Ķ'] +['æĿ¥', '访'] +['æīĢ', '带æĿ¥çļĦ'] +['æĺ¯ä¸Ģ', 'éĥ¨'] +['æĻļ', 'é¥Ń'] +['åİĨ', '代'] +['åIJ¦', 'åīĩ'] +['ä¹ħ', 'ä¹ħ'] +['æľīæķĪ', 'æľŁ'] +['诱', 'åıij'] +['æĢ»', 'èµĦ产'] +['æľ¬èº«', 'å°±æĺ¯'] +['çĶŁäº§', 'åİĤå®¶'] +['æĹ¶', '髦'] +['èĢIJ', 'ç͍'] +['ä»İå°ı', 'å°±'] +['æĿ¡', '约'] +['èĭ±', 'åĭĩ'] +['ä¿Ĺ', 'è¯Ŀ说'] +['寺', 'åºĻ'] +['å¿ĥçIJĨ', 'åģ¥åº·'] +['ä»Ģä¹Ī', 'äºĭæĥħ'] +['æ±ī', 'åŃĹ'] +['çķĻ', 'ä½ı'] +['åįĹ', 'è·¯'] +['ä¸ī', '项'] +['丢', 'äºĨ'] +['æĥ³', 'åΰäºĨ'] +['çѹ', 'éĽĨ'] +['éĻĦåĬł', 'å̼'] +['西', 'è£ħ'] +['ä¹ĭ', 'ä½ľ'] +['åģļçļĦ', 'äºĭ'] +['çķ¶', 'æĤ¨'] +['çķ¶æĤ¨', 'åľ¨'] +['é¦ĸ', '款'] +['ä¸įåľ¨', 'ä¹İ'] +['å·¥ç¨ĭ', 'æĸ½å·¥'] +['éļIJ', 'éļIJ'] +['åıĺ', '身'] +['沿', 'éĢĶ'] +['æĤł', 'æĤł'] +['ä¿Ŀ', 'æļĸ'] +['çĶŁæ´»', 'åŀĥåľ¾'] +['渤', 'æµ·'] +['æŃ¦', 'ä¾ł'] +['女', '主è§Ĵ'] +['举', 'ä¾ĭ'] +['æ', '·¨'] +['çϽ', 'é¢Ĩ'] +['è£Ļ', 'åŃIJ'] +['è¿Ķ', 'è¿ĺ'] +['è¿Ī', 'åĩº'] +['é¾Ļ', 'éŨ'] +['ç»ıæµİ', 'ä½ĵ'] +['æĶ¶', 'å®ĺ'] +['çķĮ', 'éĻIJ'] +['è·³', 'åĩº'] +['åįĩ', 'å̼'] +['绵', 'éĺ³'] +['çĸ¤', 'çĹķ'] +['çľĭ', 'æ¸ħ'] +['æĭĴ', 'çµķ'] +['è¥Ħ', 'éĺ³'] +['课', 'å¤ĸ'] +['åŃIJ', 'åŃĻ'] +['æŃĮ', 'è¯į'] +['æĪIJ', 'åIJį'] +['溶', 'æ¶²'] +['åĦĴ', 'å®¶'] +['åķĨä¸ļ', 'åĮĸ'] +['辨', 'åĪ«'] +['å¤ļ', 'è¾¾'] +['ç½ij', 'åºĹ'] +['ä¹Ŀ', '大'] +['ä¹Ŀ大', 'ç²¾ç¥ŀ'] +['æŃ¤', '举'] +['è¿ŀ', 'è½½'] +['ä¸Ģ', 'åĢĭ人'] +['èī²', 'æ³½'] +['æ¶µçĽĸ', 'äºĨ'] +['è¦ı', 'åĬĥ'] +['åĽ½', 'æĥħ'] +['åį«çĶŁ', 'åģ¥åº·'] +['积æŀģ', 'åĵįåºĶ'] +['æĭ', 'Ļ'] +['åζ', 'åĬ¨'] +['æĥ³è±¡', 'åĬĽ'] +['çļĦ', 'ä¹IJè¶£'] +['å¼łå®¶', 'çķĮ'] +['å´', 'İ'] +['éĩį', 'åŀĭ'] +['å¤ĸ', 'å¢Ļ'] +['æĶ¾', 'åѦ'] +['è®¤çľŁ', 'åŃ¦ä¹ł'] +['è´¬', 'å̼'] +['æ³ķ', 'æ¡Ī'] +['æĬ¤èĤ¤', 'åĵģ'] +['éĻ·åħ¥', 'äºĨ'] +['请', 'æĤ¨'] +['åŀ', '¢'] +['æķĻèĤ²', 'èµĦæºIJ'] +['交æĺĵ', 'å¹³åı°'] +['æĹ¶', 'è£ħ'] +['ä¼łæŁĵ', 'çĹħ'] +['æ¹ĸ', 'æ³Ĭ'] +['èµĦ', '管'] +['åݨ', 'å¸Ī'] +['éĹľ', 'éį'] +['éĹľéį', 'µ'] +['åĵĪåĵĪ', 'åĵĪ'] +['çĽĹ', 'çªĥ'] +['çĶľ', 'ç¾İ'] +['åºĦ', 'åĽŃ'] +['缮åīį', 'å·²ç»ı'] +['è¾¹', 'ä¸Ĭ'] +['çģ«', 'èĬ±'] +['æĬ¥', 'è®°èĢħ'] +['æģĭ', 'æĥħ'] +['ç´§', 'åĩij'] +['æ°´', 'æµģ'] +['è¿Ļæĺ¯', 'æĪij们'] +['æ³¥', 'åľŁ'] +['æĽ¾', 'ä»»'] +['æĸ¹', 'è¨Ģ'] +['åij¨', 'åħŃ'] +['åı·', '楼'] +['ä¼ij', 'åģĩ'] +['误', 'ä¼ļ'] +['åĽ½', 'åĢº'] +['åīį', 'å¤ķ'] +['两', 'å¼ł'] +['éĹ', '«'] +['éŃĶ', '鬼'] +['æĬĬ', 'æĮģ'] +['èĬĤèĥ½', 'çݯä¿Ŀ'] +['æ¸ħæ´ģ', 'èĥ½æºIJ'] +['èĤ¥', 'æĸĻ'] +['é«ĺ', 'é¢ij'] +['å°±', 'æľīäºĨ'] +['交', 'ä¼ļ'] +['没', 'éĴ±'] +['éĽħ', 'æĢĿ'] +['è¦ģ', 'åıĬæĹ¶'] +['åŁ¹åħ»', 'åѦçĶŁ'] +['欣', 'åĸľ'] +['çĥŃæ°´', 'åύ'] +['é¾Ļ', 'æ¹ĸ'] +['äºĮ', '楼'] +['æĸ°æµª', 'è´¢ç»ı'] +['æĸ°', 'åĬ¨èĥ½'] +['èµ£', 'å·ŀ'] +['æĭ³', '头'] +['æµģ', 'åIJij'] +['ä¹Łæĺ¯', 'å¾Ī'] +['åıij', 'åĶ®'] +['ä¸Ń', 'åIJ«æľī'] +['åIJĵ', 'å¾Ĺ'] +['å·¨', 'æĺŁ'] +['æĹł', 'æīĢè°ĵ'] +['æ¯Ľ', 'åŃĶ'] +['åħ¬åħ±', '交éĢļ'] +['çĤİ', 'çĥŃ'] +['èµ·', 'èįī'] +['åĬłçĽŁ', 'åķĨ'] +['说', 'ä¸įåĩº'] +['大åѦ', 'æ¯ķä¸ļ'] +['å·¥ä¸ļ', 'åĽŃ'] +['éłĺ', 'åŁŁ'] +['åºĨ', 'åħ¸'] +['æµģ', '产'] +['èģ²', 'éŁ³'] +['ä¼¼ä¹İ', 'æĺ¯'] +['è´§', 'æºIJ'] +['æ·±', 'åĪĩ'] +['æ²»çĸĹ', 'æĸ¹æ³ķ'] +['èµĦæºIJ', 'éħįç½®'] +['ç¶²', 'åıĭ'] +['çĶ', '£'] +['äº', '¥'] +['躲', 'åľ¨'] +['社', 'ç§ij'] +['è»Ł', 'é«Ķ'] +['女', 'è£ħ'] +['æŃ¡', 'è¿İ'] +['综åIJĪ', 'å®ŀåĬĽ'] +['æł¼', 'å°ĩ'] +['åħļåı²', 'åŃ¦ä¹ł'] +['æľĢ', 'åŁºæľ¬'] +['æľĢåŁºæľ¬', 'çļĦ'] +['çľĭ', 'æľĽ'] +['åıĹ', 'è´¿'] +['ä¸įä»ħ', 'èĥ½'] +['ä½ķ', 'å¿ħ'] +['ä¸Ģ个', 'å°ıæĹ¶'] +['ç¾', 'Į'] +['æĭĽ', 'æĶ¶'] +['çĤĴ', 'èĤ¡'] +['æĿij', 'å¹²éĥ¨'] +['缸', 'çα'] +['æ½ľ', 'èĥ½'] +['ä¹', 'į'] +['æĹ¶', 'è¾°'] +['欣', 'æħ°'] +['éĵ¶', 'è¡Įä¸ļ'] +['çĭŃ', 'çªĦ'] +['éĩįçĤ¹', 'é¢ĨåŁŁ'] +['çݰå®ŀ', 'çĶŁæ´»'] +['éĮ¯', '誤'] +['æĸ°', 'è§Ħ'] +['滥', 'ç͍'] +['æĹ¶', 'ä¸į'] +['æĹ¶ä¸į', 'æĹ¶'] +['帳', 'èĻŁ'] +['ç¨Ģ', '缺'] +['åIJij', '举'] +['ä¿Ŀåģ¥', 'åĵģ'] +['çıŃ', 'éķ¿'] +['äºĴ', 'åĭķ'] +['笼', '罩'] +['æ½', 'Ľ'] +['æļĸ', 'å¿ĥ'] +['è½°', 'çĤ¸'] +['åºĨ', '幸'] +['è²Į', 'ä¼¼'] +['æĵ', 'º'] +['èĢIJ', '磨'] +['ä¸ĵä¸ļ', '人士'] +['ä¸Ģèά', 'éĥ½æĺ¯'] +['æ¼³', 'å·ŀ'] +['åħ¨', 'èĩªåĬ¨'] +['å½ķ', 'ç͍'] +['大', 'è·Į'] +['æľīæķĪ', 'æĢ§'] +['èĩª', 'åĭķ'] +['ä¸ī个', 'æĸ¹éĿ¢'] +['港', 'åĮº'] +['ä¿¡', '貸'] +['éĢļ', 'è¯Ŀ'] +['é«ĺ', '涨'] +['æ³Ħ', 'æ¼ı'] +['éħį', 'ä¸Ĭ'] +['åħļ', 'å·¥å§Ķ'] +['被', '认为'] +['被认为', 'æĺ¯'] +['ä¸įä¼ļ', 'åĨį'] +['è°ĥ', 'åīĤ'] +['åıĤ', 'èĤ¡'] +['èĦ±', 'åıij'] +['å¿ł', 'å®ŀ'] +['åĨħ', 'åĪĨæ³Į'] +['ç¹ģ', 'å¿Ļ'] +['åıĮ', 'åĪĽ'] +['é©»', 'æĿij'] +['åĪĴ', 'ç®Ĺ'] +['éģİ', 'ä¾Ĩ'] +['åľ£', 'ç»ı'] +['èıľ', '鸣'] +['æĭ¼', 'å¤ļå¤ļ'] +['ä¸ŃåĽ½', '汽车'] +['çĥŁ', 'èįī'] +['缴', 'æµģ'] +['äºĨä¸Ģ', 'åı£æ°Ķ'] +['ä½İ', 'æĪIJæľ¬'] +['æī¾', 'åĽŀ'] +['èĩª', 'åįij'] +['總', 'æĺ¯'] +['æĸĩåĮĸ', 'åĪĽæĦı'] +['天', 'æ²³'] +['樱', 'æ¡ĥ'] +['éªij', 'åħµ'] +['éĩĮéĿ¢', 'æľī'] +['çİ', '®'] +['èĥ½', 'æī¾åΰ'] +['éĢĥ', 'è·ij'] +['åĪĩ', 'å°Ķ'] +['åĪĩå°Ķ', '西'] +['以ä¸ĭ', 'æĺ¯'] +['å²³', 'éĺ³'] +['çļĦ', 'æ¦Ĥçİĩ'] +['æĬµ', 'åζ'] +['å¸Ī', 'äºĭåĬ¡'] +['å¸ĪäºĭåĬ¡', 'æīĢ'] +['åĩĨ', 'æĹ¶'] +['屬', 'æĸ¼'] +['订', 'è´Ń'] +['åįłæį®', 'äºĨ'] +['ä¸Ń', 'éĢĶ'] +['å°', 'ĭ'] +['é»ij', '马'] +['åİ¿', 'åħ¬å®īå±Ģ'] +['ä¸ĥ', 'æľĪ'] +['èī²', 'ç´ł'] +['å¿ĥèĦı', 'çĹħ'] +['æĹ¶', 'éĻIJ'] +['æ¯į', 'åħ¬åı¸'] +['å¹ķ', 'åIJİ'] +['ä¸Ĭ', 'æ¦ľ'] +['å̾åIJij', 'äºİ'] +['纸', 'ä¸Ĭ'] +['æ¡', 'ĵ'] +['éĽĨä½ĵ', 'ç»ıæµİ'] +['æĥħ', 'å¢ĥ'] +['è¦ģ', 'åģļåΰ'] +['ç©į', '極'] +['åıª', 'æĢķ'] +['æ¹ĺ', '西'] +['çļ±', '纹'] +['åħ¨', 'åľĭ'] +['çĦ¡', 'è«ĸ'] +['好', 'æĦŁ'] +['åįķ', 'ä»·'] +['è¿Ľç¨ĭ', 'ä¸Ń'] +['æĺĨ', 'ä»ij'] +['åĪĽ', '客'] +['åħħ', 'æĸ¥'] +['åħĪ', 'æĬĬ'] +['该', 'æĢİä¹ĪåĬŀ'] +['åĵģ', 'å¾·'] +['åħ¨éĿ¢', 'åıijå±ķ'] +['è¨Ī', 'åĬĥ'] +['æĢ»', 'å·¥ä¼ļ'] +['ä½Ľå±±', 'å¸Ĥ'] +['æĬĹ', 'è¡¡'] +['å¼Ģ', 'åľº'] +['éĴ±', 'å¸ģ'] +['åıĭ', '们'] +['å«ī', 'å¦Ĵ'] +['ç´¢', 'èµĶ'] +['è®Ĭ', 'åĮĸ'] +['æĮ¤', 'åİĭ'] +['æĮij', 'è¡ħ'] +['çŃī', 'ä¸Ģæī¹'] +['æĿ¨', '欢'] +['ä¸ĵå®¶', 'åѦèĢħ'] +['èĥ½', 'è¾¾åΰ'] +['èµ°', 'è¿ij'] +['è´«åĽ°', 'åľ°åĮº'] +['éĻIJ', 'æľŁ'] +['ä¸į', '平衡'] +['åĽ½åĨħ', 'å¸Ĥåľº'] +['èµĽ', 'åľº'] +['éħį', 'èµĦ'] +['è¦ģ', 'èĢĥèĻij'] +['ä¸ĩ', 'åı°'] +['æľĪ', 'æľ«'] +['éĶ', '¥'] +['åŃ', '«'] +['æİ¥è§¦', 'åΰ'] +['åĩº', '产'] +['æķĻ', 'åѸ'] +['ä½ľ', 'å¼Ĭ'] +['çļĦ', 'æľĢåIJİä¸Ģ'] +['ä¿ĥ', 'æĪIJ'] +['åIJ¸', 'åıĸ'] +['æ½ľ', 'èīĩ'] +['被', 'éªĹ'] +['è¾ĵ', 'äºĨ'] +['çĭIJ', 'çĭ¸'] +['åįĩ', 'éĻį'] +['è¿ĻäºĽ', 'ä¸ľè¥¿'] +['æĬķèµĦ', 'åŁºéĩij'] +['çĶŁçī©', 'åѦ'] +['ç½ij绾', 'èIJ¥éĶĢ'] +['åIJij', 'è®°èĢħ'] +['èįī', 'åľ°'] +['æĢ', '¯'] +['æľįåĬ¡', 'èĥ½åĬĽ'] +['éĥģ', 'éĹ·'] +['åįķ', 'åĵģ'] +['å¾Ĺ', '罪'] +['æĺĵ', 'äºİ'] +['个å¤ļ', 'å°ıæĹ¶'] +['éĩį', 'ä»»'] +['ä¸Ĭ', 'å®ĺ'] +['æľ¬', 'éĩij'] +['çı¾', 'åł´'] +['溢', 'ä»·'] +['æĺŁ', 'è¾°'] +['æ´»åĬ¨', 'çİ°åľº'] +['丹', '麦'] +['å¸Ŀ', 'çİĭ'] +['æŁ¥', 'æĺİ'] +['åŃĺåľ¨', 'äºİ'] +['é¦Ļ', 'æ°´'] +['æĬ½', 'æ£Ģ'] +['å®ŀéĻħä¸Ĭ', 'æĺ¯'] +['æĸ°', 'å¾ģç¨ĭ'] +['è´¢åĬ¡', '管çIJĨ'] +['æİ', 'Ľ'] +['åĨľ', 'åİĨ'] +['éĥ½', 'èĥ½å¤Ł'] +['éĤ¯', 'éĥ¸'] +['羣', '實'] +['ç»', 'Ĭ'] +['åĨµ', 'ä¸Ķ'] +['ç½®', '身'] +['ç¥Ī', '祷'] +['çĿģ', 'å¼Ģ'] +['æĮĩ', 'çĤ¹'] +['å¼Ģ', 'æľº'] +['西', 'å®ģ'] +['åĮĹ', '约'] +['积', 'æ°´'] +['åĩº', 'åĬ¨'] +['åıijå±ķ', '模å¼ı'] +['转', 'æĬĺ'] +['èĢĥ', 'çĤ¹'] +['æľī', 'ç½ijåıĭ'] +['è´«åĽ°', 'æĿij'] +['æĪij们', 'çŁ¥éģĵ'] +['åĪĨ', 'éĶĢ'] +['å±±', 'èĦī'] +['æ¯Ķ', 'æĭŁ'] +['ä¼°', 'ç®Ĺ'] +['æĶ¹', '建'] +['壮', 'è§Ĥ'] +['ç§ī', 'æĮģ'] +['æı', 'ª'] +['ç¦', 'Ģ'] +['åĮĸåѦ', 'åĵģ'] +['ä¸ŃåĽ½', 'åζéĢł'] +['ä¸Ģ', 'æŀ¶'] +['æīį', 'è¡Į'] +['æĭĽ', 'å¾ħ'] +['åıĺ', 'æį¢'] +['åīį', '线'] +['幸', '好'] +['è¿Ļæł·', 'çļĦè¯Ŀ'] +['å¿ĥ', 'è¡Ģ管'] +['æĢ§', 'çĸ¾çĹħ'] +['åħ¨', 'èĥ½'] +['åĪij', '侦'] +['ä¿¡æģ¯', 'åıijå¸ĥ'] +['æĺ¾', 'çĦ¶æĺ¯'] +['éĿĴ', 'éĵľ'] +['åIJĥ', 'ä»Ģä¹Ī'] +['ç͵', 'ä»·'] +['æ³ķå¾ĭ', 'è§Ħå®ļ'] +['çħ', '²'] +['çĵ·', 'åύ'] +['èĤī', 'ç±»'] +['æıĴ', 'åħ¥'] +['åĹ', 'ľ'] +['è¿Ł', 'è¿Ł'] +['ä¸ĢçĤ¹', 'éĥ½ä¸į'] +['è¿ĺ', 'åĮħæĭ¬'] +['èĪį', 'ä¸įå¾Ĺ'] +['æłĩå¿Ĺ', 'æĢ§'] +['æľĪ', '以æĿ¥'] +['ç³ĸ', 'æŀľ'] +['éĥ½', 'åºĶ该'] +['çݯå¢ĥ', 'åį«çĶŁ'] +['èĪª', 'è¡Į'] +['éĥij', 'éĩį'] +['ç½ij', 'æĬķ'] +['åįģ', 'ä½³'] +['ç§ģ', 'ä¸ĭ'] +['æļ´', 'è·Į'] +['åĬłå¿«', 'åıijå±ķ'] +['产åĵģ', 'çłĶåıij'] +['åĪĽéĢł', 'åĩº'] +['æĢ»', 'è§īå¾Ĺ'] +['åºķ', 'çĽĺ'] +['èķ', 'Ĭ'] +['åĩºå¸Ń', 'ä¼ļè®®'] +['主', 'æĿ¿'] +['æĹ¥æĻļ', 'éĹ´'] +['å®ĺæĸ¹', 'å¾®åįļ'] +['å¼ķç͍', 'æĹ¥æľŁ'] +['åī¯', 'æķĻæİĪ'] +['ç͵åŃIJ', '产åĵģ'] +['è¡°', 'éĢĢ'] +['çķĻ', 'åŃĺ'] +['çģ«', 'åĬĽ'] +['çĴ', '§'] +['çļ', 'Ĥ'] +['åħ¼', 'åħ·'] +['éĩį', 'è¿Ķ'] +['é¢Ĩ', 'çķ¥'] +['åĪĩ', 'éϤ'] +['åĨįçĶŁ', 'èĥ½æºIJ'] +['å®ŀåľ¨', '太'] +['çIJĨ论', 'ä¸Ĭ'] +['ä¸ī', 'å±Ĥ'] +['ä¸ĸçķĮ', 'åIJĦåĽ½'] +['å®ľ', 'æĺĮ'] +['è̳', 'è¾¹'] +['宽', 'æķŀ'] +['æ±ī', 'æĹı'] +['çϽ', 'çϽ'] +['è¿ĻéĩĮ', 'éĿ¢'] +['çĶŁæ´»', 'ä¹łæĥ¯'] +['èµŀ', 'èµı'] +['çĶ·', '士'] +['ä¸Ń', 'ä¿Ħ'] +['车', '祸'] +['åīĤ', 'éĩı'] +['éϤ', 'åİ»'] +['å·¦', 'è¾¹'] +['çŃij', 'çī¢'] +['çīĽ', 'å¸Ĥ'] +['å®¶', 'åĬ¡'] +['åķ', 'ĥ'] +['ç½®', 'æį¢'] +['ç´«', 'å¤ĸ'] +['ç´«å¤ĸ', '线'] +['å¾Ģ', 'åīį'] +['åĬĽ', 'åѦ'] +['ç´§', 'è·Ł'] +['缮çļĦ', 'åľ¨äºİ'] +['ç»', '®'] +['ç¥', 'Ĥ'] +['宣', 'è¨Ģ'] +['äºĮ', 'æ°§åĮĸ'] +['äºĮæ°§åĮĸ', '碳'] +['æĹł', 'ç¼ĺ'] +['ç²¾', 'éĢļ'] +['è¨', 'º'] +['å¼ķåıij', 'äºĨ'] +['æľĢ', 'åħĪ'] +['æ´¾', 'é©»'] +['ä¸į', 'å¿į'] +['æĪij', 'çΏ'] +['å¹´', 'ä¸ĭåįĬå¹´'] +['æ·ĭ', 'å·´'] +['没', 'éĹ®é¢ĺ'] +['åºĹ', 'åĨħ'] +['è·Ł', 'æĪij说'] +['çĶŁäº§', 'çĶŁæ´»'] +['è§Ĥ', 'æľĽ'] +['æ¸', 'į'] +['被', 'æī§è¡Į'] +['被æī§è¡Į', '人'] +['èĪ', 'ľ'] +['æİ', 'º'] +['ä¸Ģ', 'ç§Ĵ'] +['èįī', 'åĿª'] +['åij¼', 'åĴĮ'] +['åij¼åĴĮ', '浩'] +['åij¼åĴĮ浩', 'çī¹'] +['人æ°ij', 'éĵ¶è¡Į'] +['çĦķ', 'åıij'] +['è¯ģåΏ', '交æĺĵ'] +['çķ', 'Ķ'] +['æľº', 'èĥ½'] +['å¦', '¾'] +['æĻļ', 'å¹´'] +['å·¥åķĨ', 'èģĶ'] +['åİŁ', 'åŀĭ'] +['è§Ĵ度', 'çľĭ'] +['æĬ¥', '社'] +['è¯į', 'æĿ¡'] +['躲', 'éģ¿'] +['éĩį', 'åIJ¯'] +['å¤ķ', 'éĺ³'] +['èĤ¡æĿĥ', '转让'] +['åľ¨', 'ä¸Ģ'] +['åľ¨ä¸Ģ', 'æĹģ'] +['社ä¼ļ', 'åĮĸ'] +['åıijå±ķ', 'åİĨç¨ĭ'] +['æĭĸ', 'æ¬ł'] +['使', 'èĢħ'] +['ä¸İ', 'åIJ¦'] +['æĸ°', 'å±ĢéĿ¢'] +['ä»Ĭ天', 'æĪij们'] +['é½IJ', 'èģļ'] +['对', 'æĪij说'] +['éĢĴ', '交'] +['æľª', 'æĽ¾'] +['èİ', 'Ĭ'] +['éĸ', 'ī'] +['亲', 'æīĭ'] +['è§Ĵ', 'éĢIJ'] +['æľī', 'é»ŀ'] +['ç¨İ', 'çİĩ'] +['ä½İ', '声'] +['é»ĺ', 'å¥ij'] +['æĻ®', 'æ³ķ'] +['大', 'ä¸ĵ'] +['第äºĮ', '大'] +['ä½ı', 'åĿĢ'] +['æĶ¾', 'è¿Ľ'] +['äºĮ', 'æĪĺ'] +['亲', '身'] +['åĽº', 'åĮĸ'] +['ä¸ĭ', '乡'] +['åħ³éĶ®', 'æĬĢæľ¯'] +['åĽŀ', 'æĥ³'] +['æĬ¥', 'åĪĬ'] +['æ¶Ĥ', 'æĬ¹'] +['èĹı', 'çĿĢ'] +['ç¥Ŀ', 'æĦ¿'] +['åįĩ', '温'] +['çĶļèĩ³', 'è¿ŀ'] +['åħ¬åħĥ', 'åīį'] +['ç¾İ', 'æĸ¹'] +['è¯ļ', 'å®ŀ'] +['æĹł', 'åģ¿'] +['åīµ', 'æ¥Ń'] +['å°ıå¿ĥ', '翼'] +['å°ıå¿ĥ翼', '翼'] +['两', 'æīĭ'] +['温馨', 'æıIJ示'] +['仿', '羣'] +['æĥ', '¶'] +['èĥ¡', 'åŃIJ'] +['å·¥ä½ľ', 'ç«Ļ'] +['硬', 'çĽĺ'] +['ç«', '¿'] +['åĤ³', 'éĢģ'] +['åħ¨', 'æł¡'] +['é²ľ', 'æ´»'] +['çĴĢ', 'çĴ¨'] +['ç»ĵ', 'å°¾'] +['æį¢', 'æĿ¥'] +['æĪ', 'Ģ'] +['ä½İ', 'ä½į'] +['ä¸ĩåħĥ', '以ä¸Ĭ'] +['åĬł', 'åĪĨ'] +['æİ¨ä»ĭ', 'ä¼ļ'] +['çIJĨ', 'èµĶ'] +['å¾·', 'å°Ķ'] +['æĬĹ', 'è®®'] +['æ´', '¼'] +['åĸ', '§'] +['åŁİ', 'éĻħ'] +['å¾Ī', 'æ£Ĵ'] +['人', 'æŃ»äº¡'] +['ä¼ļå±ķ', 'ä¸Ńå¿ĥ'] +['äºĴèģĶ', 'äºĴéĢļ'] +['èĸĦ', 'èĨľ'] +['éĩį', 'é»ŀ'] +['ç¦ģ', 'æ¯Ĵ'] +['åĨ·', 'ç¬ij'] +['大家', 'åı¯ä»¥'] +['é¦ĸ', '缸'] +['è¿ij', 'è·Ŀ离'] +['æµ®', 'çݰ'] +['ç§ĺ', 'è¯Ģ'] +['èµ·', 'é£ŀ'] +['æIJ', '¶'] +['羣', 'åģĩ'] +['æģ', 'ķ'] +['å°ı', 'åºĹ'] +['æ°ij', 'çľ¾'] +['åıijå¸ĥ', 'åħ¬åijĬ'] +['ä¾§', 'éĩį'] +['å¾ĺ', 'å¾Ĭ'] +['æĢ', 'Ķ'] +['æª', 'IJ'] +['æķ°', '缮'] +['åī¯', 'ç§ĺ书éķ¿'] +['两', 'åı¥'] +['éļIJ', 'çŀĴ'] +['åıĮ', 'åıĮ'] +['æīĭ', 'æĦŁ'] +['èij¡', '京'] +['éģĹ', 'å¿ĺ'] +['é¬', '¥'] +['è¿Ļ个', 'åľ°æĸ¹'] +['说', 'çļĦè¯Ŀ'] +['å·¡', 'åĽŀ'] +['è¿Ŀ', '竳'] +['æī¾', 'å·¥ä½ľ'] +['æĶ¯', 'çIJĥéĺŁ'] +['裡', 'éĿ¢'] +['æĺ¾ç¤º', 'åĩº'] +['èĩ³', 'å°Ĭ'] +['两', '级'] +['åīį', '段æĹ¶éĹ´'] +['çĺ¦', '身'] +['èĤ¢', 'ä½ĵ'] +['æ¯į', '親'] +['æīĭç»Ń', 'è´¹'] +['汽车', 'è¡Įä¸ļ'] +['æİ©', 'çĽĸ'] +['æİ§èĤ¡', 'éĽĨåĽ¢'] +['åı£', 'å¾Ħ'] +['æĶ¿çŃĸ', 'æİªæĸ½'] +['æµ·', '绵'] +['åħ¨', 'éķĩ'] +['äºĭ', 'åħ³'] +['å¸Ń', 'æī§è¡Į'] +['å¸Ńæī§è¡Į', 'å®ĺ'] +['éĤ£', '次'] +['åı¯èĥ½', 'åĩºçݰ'] +['ä¸Ńå¿ĥ', 'åŁİå¸Ĥ'] +['ç¿»', '身'] +['ä¹Ł', 'ç®Ĺ'] +['ä¾µ', 'çķ¥'] +['åĸĩ', 'åıŃ'] +['æ¯ı次', 'éĥ½'] +['è§', 'ħ'] +['éĻ¢', 'éĻ¢éķ¿'] +['å§ĭ', 'äºİ'] +['èѦ', 'åĬ¡'] +['èį¯', 'æĿIJ'] +['å±ł', 'æĿĢ'] +['æľ¬èº«', 'å°±'] +['éļıæĹ¶', 'éļı'] +['éļıæĹ¶éļı', 'åľ°'] +['åĶ®', 'åįĸ'] +['æĹłäºº', '驾驶'] +['é¢', 'ħ'] +['åĵģ', '質'] +['åĺ²', 'ç¬ij'] +['è·ij', 'åİ»'] +['åħĭ', 'éĩĮæĸ¯'] +['çķ¸', 'å½¢'] +['ä¿®', '饰'] +['磩', 'éĺµ'] +['éŁ³ä¹IJ', 'ä¼ļ'] +['æŁ³', 'å·ŀ'] +['é½', '¡'] +['ä¼ļ', 'è°Ī'] +['æŃ£', 'çīĪ'] +['ä¹Ł', 'åIJĮæł·'] +['æļ§', 'æĺ§'] +['è¡ĮæĶ¿', 'éĥ¨éŨ'] +['ä¹ĸ', 'ä¹ĸ'] +['èĤ¤', 'èī²'] +['æĹ¶', 'ä»»'] +['羣', 'åĪĩ'] +['æľĪ', 'ä¸ĭ'] +['æľĪä¸ĭ', 'æĹ¬'] +['举æĸ¹', 'è´¢å¯Į'] +['è£ħä¿®', 'åħ¬åı¸'] +['éĢĢ', 'è¿ĺ'] +['åĭĺ', 'å¯Ł'] +['åĵ¥', '伦'] +['åĵ¥ä¼¦', 'æ¯Ķäºļ'] +['çĭ¬', 'ä¸Ģ'] +['çĭ¬ä¸Ģ', 'æĹł'] +['çĭ¬ä¸ĢæĹł', 'äºĮ'] +['è°ĥ', 'åij³'] +['åİĭ', 'è¿«'] +['åħ¨çIJĥ', 'æľĢ大'] +['åī¯', 'æł¡éķ¿'] +['æĽ´', 'ä½İ'] +['åĪĨéĴŁ', 'åIJİ'] +['åĽŀ', 'ä¾Ĩ'] +['åζ', 'åīĤ'] +['åijĬè¯ī', '大家'] +['çĤ¹', 'éĴŁ'] +['åįģä¸ī', 'å±Ĭ'] +['åij¨', 'åĽĽ'] +['è¿Ļæł·', 'ä¸Ģ'] +['è¿Ļæł·ä¸Ģ', 'æĿ¥'] +['èĭ', 'Ł'] +['æľĽ', 'åİ»'] +['æĪIJ', 'è¯Ń'] +['å½ĵ', 'åį³'] +['ç¬ij', '声'] +['ä¹ĭ', 'åĬ¿'] +['åĪijäºĭ', 'æ¡Īä»¶'] +['æĮĤ', 'çĿĢ'] +['ä½ķ', 'ç§į'] +['å°ı', '游æĪı'] +['åĽ½å®¶', 'æĪĺçķ¥'] +['åĨ·', 'åĨ·'] +['å®ľ', '宾'] +['æIJº', 'ç¨ĭ'] +['è¶ĭ', 'äºİ'] +['åıį', 'çľģ'] +['常', '说'] +['ä¸ĩ', 'æĪ·'] +['åĥµ', 'å°¸'] +['åįĥä¸ĩ', 'åĪ«'] +['åıijçݰ', 'éĹ®é¢ĺ'] +['åı¯', 'çŁ¥'] +['éŨæĪ·', 'ç½ijç«Ļ'] +['åģ¥åº·', '产ä¸ļ'] +['åı³', 'è¾¹'] +['æµ·', 'è¿IJ'] +['è¿ij', 'ä¹İ'] +['åĮ»', 'æ²»'] +['æĢ»', 'ç®Ĺ'] +['ä¸Ģ', 'åĪĨéĴŁ'] +['æĭ', '§'] +['ä¹Ł', 'æľīä¸ĢäºĽ'] +['ä¾Ľç͵', 'åħ¬åı¸'] +['å»ī', 'ä»·'] +['帮', 'ä»ĸ'] +['æŃ¤æ¬¡', 'æ´»åĬ¨'] +['åıªèĥ½', '说'] +['èĬ', 'ĭ'] +['çīĩ', '段'] +['åŃĺåľ¨', 'éĹ®é¢ĺ'] +['ä½łä¼ļ', 'åıijçݰ'] +['è½®', 'å»ĵ'] +['ç½ij', 'éĢļ'] +['滨', 'æ±Ł'] +['æİĪ', 'ä¿¡'] +['é»İ', 'æĺİ'] +['ä¸į', 'å±ŀäºİ'] +['约', 'åįł'] +['éķ¿æ²Ļ', 'å¸Ĥ'] +['èĥļ', 'èĥİ'] +['åħĥ', 'ä»¶'] +['éĻĨ', 'åĨĽ'] +['è³¼', 'è²·'] +['æĮĩ', 'æľĽ'] +['å®ŀä¹ł', 'çĶŁ'] +['çī¹çĤ¹', 'æĺ¯'] +['çıł', 'æ±Ł'] +['çľĭ', 'ä¸įåĩº'] +['ä¸įè§ģ', 'äºĨ'] +['ç¼', 'ī'] +['éĺµ', 'èIJ¥'] +['åĶIJ', 'æľĿ'] +['没', 'å¿ħè¦ģ'] +['åĽ½åľŁ', 'èµĦæºIJ'] +['ç»ıæµİåѦ', 'å®¶'] +['åIJĪèĤ¥', 'å¸Ĥ'] +['çIJ¢', '磨'] +['ç¡®', 'åĪĩ'] +['åŁİå¸Ĥ', 'åıijå±ķ'] +['çŃ·', 'åŃIJ'] +['人æ°ij', 'æľįåĬ¡'] +['满', 'åĪĨ'] +['è¿·', 'ä¿¡'] +['ä½ľèĢħ', 'æľ¬äºº'] +['æĸĩ竳', 'æĿ¥æºIJ'] +['ç«Ļ', 'ç«ĭ'] +['æŀĦ', 'æĪIJäºĨ'] +['è¾Ľ', 'åĭ¤'] +['è¶ħ', '强'] +['éĶ', 'ļ'] +['åīįä¸ī', 'åŃ£åº¦'] +['å°±', 'è§īå¾Ĺ'] +['å´ĩ', 'é«ĺ'] +['è¶Ĭ', 'ä¾Ĩ'] +['è¶Ĭä¾Ĩ', 'è¶Ĭ'] +['å¸Ĥåľº', 'èIJ¥éĶĢ'] +['综åIJĪ', 'ç´łè´¨'] +['åŃ', 'ļ'] +['ä¾®', 'è¾±'] +['äºĮ', 'åŃĹ'] +['å·¥ä½ľ', 'ä»»åĬ¡'] +['åı²ä¸Ĭ', 'æľĢ'] +['æľĢ', 'ä¼ĺ'] +['åIJ©', 'åĴIJ'] +['表', 'çϽ'] +['èİ«', 'åIJį'] +['èİ«åIJį', 'åħ¶'] +['èİ«åIJįåħ¶', 'å¦Ļ'] +['å¹', '£'] +['åIJĮå¿Ĺ', '们'] +['建设', 'çĶ¨åľ°'] +['åĦ', 'Ģ'] +['éħį', 'åģ¶'] +['å¼', '©'] +['åͱ', 'çīĩ'] +['æīĭ', 'èĦļ'] +['åħ¼', 'ä»»'] +['åģľ', 'æĶ¾'] +['æŃ£', 'å®Ĺ'] +['æĸ°', 'åĨľæĿij'] +['åĤ¬', 'çĶŁ'] +['æīĢ', 'åŃ¦æł¡'] +['念', 'ä½Ľ'] +['åͤ', 'éĨĴ'] +['åħ±', 'åĪĽ'] +['æĭī', 'ä¸ģ'] +['èĥĮ', 'çĿĢ'] +['çĶŁæĢģ', 'ä¿ĿæĬ¤'] +['åı£', '头'] +['æĸ¹åIJij', 'çĽĺ'] +['調', 'æķ´'] +['æĭĽèģĺ', 'ä¿¡æģ¯'] +['åħ¶ä»ĸ', 'åĽ½å®¶'] +['ç®Ģ', 'æĺĵ'] +['åĮ¿', 'åIJį'] +['è¯Ħ', 'æµĭ'] +['æĺ¯ä¸Ģ', '座'] +['çīµ', 'æīĭ'] +['è¶³', '迹'] +['çIJĨè§£', 'åĴĮ'] +['æľĢ', 'åıĹ'] +['å¿ĥ', 'è·³'] +['çζ', '親'] +['éĿŀ常', 'åĸľæ¬¢'] +['èĭ¦', 'éļ¾'] +['æĬĢ', 'å¸Ī'] +['æ°ij', 'æĦı'] +['æĪĺ', 'åĽ½'] +['æĽ¿', 'è¡¥'] +['æ´¥', 'è´´'] +['ä¸ŃåĽ½', 'ä¼łç»Ł'] +['åIJĦ', 'è¡Į'] +['åIJĦè¡Į', 'åIJĦ'] +['åIJĦè¡ĮåIJĦ', 'ä¸ļ'] +['第äºĶ', 'å±Ĭ'] +['èį·', 'èĬ±'] +['æĦı', 'èŃĺ'] +['票', 'ä»·'] +['åĪĨ', 'æµģ'] +['æĿİ', 'çϽ'] +['æ±Ł', 'åĮĹ'] +['æİĴ', 'æĸ¥'] +['ä½ĵ', 'éĩı'] +['åĮħåIJ«', 'äºĨ'] +['åĪĺ', 'æŁIJ'] +['çݰ', 'å¦Ĥä»Ĭ'] +['å·¥èīº', 'åĵģ'] +['è¿Ļç§į', 'æĸ¹æ³ķ'] +['åĬŀåħ¬', '楼'] +['ç͵', 'å·¥'] +['çħ', 'Ļ'] +['åį¡', 'çīĩ'] +['å¹´', 'å¹´åºķ'] +['ä¸ĵ项', 'èµĦéĩij'] +['åĮ»', 'ç§ij'] +['åĮ»ç§ij', '大åѦ'] +['åĽŀ头', 'çľĭ'] +['ä¸į', 'å±ij'] +['èĩª', '驾'] +['没', 'æĶ¶'] +['æīĵ', 'çĮİ'] +['èĦ¸', 'éĥ¨'] +['åıĥ', 'èĢĥ'] +['å°Ĩ', '士'] +['è´«åĽ°', '人åı£'] +['çIJĨæĥ³', '信念'] +['é£İ', 'å°ļ'] +['人æīį', 'éĺŁä¼į'] +['çij', '¾'] +['æĿ¥', 'è¿ĻéĩĮ'] +['æ´Ĺ', '涤'] +['å¹´', 'èĸª'] +['èĭį', 'çϽ'] +['ä¸ĩ', 'äºĭ'] +['课', 'æľ¬'] +['åºĵ', 'éĩĮ'] +['çī¹', 'æ´¾'] +['ç´¾', 'åijĺ'] +['èµŀ', 'ç¾İ'] +['ç©¿', 'æĪ´'] +['製', 'ä½ľ'] +['èµŀ', 'æĪIJ'] +['ä¸Ģ', 'ä¾§'] +['å½ĵåľ°', '人'] +['æĭ', 'İ'] +['纸', 'è´¨'] +['ä½Ļ', '个'] +['éĶĤ', 'çĶµæ±ł'] +['æľº', 'åŀĭ'] +['éĻ¢', 'éϢ士'] +['åģļ', 'å·¥'] +['å¼ł', 'è´´'] +['ç¥Ľ', 'æĸij'] +['æ®ĸ', 'æ°ij'] +['å¥ij', '约'] +['æ¹ĺ', 'æ½Ń'] +['æIJ', 'ĸ'] +['åŃĺ', 'è´§'] +['交éĢļ', '大åѦ'] +['è¶ģ', 'çĿĢ'] +['æĸĩçī©', 'ä¿ĿæĬ¤'] +['å¤ĩ', 'æĪĺ'] +['éĩĩ', '纳'] +['åįĬ', 'æľĪ'] +['æľĢ', 'åħ³éĶ®'] +['æľĢåħ³éĶ®', 'çļĦ'] +['æİ¥', 'éĢģ'] +['æĶ¶', 'åī²'] +['åıį', 'åĢĴ'] +['çĥ', 'Ľ'] +['æ', '½Ķ'] +['ä¼Łå¤§', 'å¤įåħ´'] +['çļĦè¯Ŀ', 'è¯Ń'] +['容', 'å¿į'] +['å®ļ', 'éĩı'] +['æķ', 'Ĺ'] +['åĵģçīĮ', '形象'] +['æīŃ', '转'] +['åĽ½å®¶', 'éĩįçĤ¹'] +['èĨĿ', 'çĽĸ'] +['ä¸Ģ', '楼'] +['大', 'éϏ'] +['éĤª', 'æģ¶'] +['åĽŀ', 'åij³'] +['çĮ', '¿'] +['çĿ¡', 'åīį'] +['æĹł', 'è¾ľ'] +['çĹħæ¯Ĵ', 'æĦŁæŁĵ'] +['æľºæ¢°', 'åĮĸ'] +['çĤ¹', '亮'] +['溶', 'è§£'] +['åĩłä¹İ', 'æīĢæľī'] +['è·ij', 'éģĵ'] +['ç͵è§Ĩ', 'æľº'] +['åı', '¨'] +['æijĩ', 'äºĨ'] +['æijĩäºĨ', 'æijĩ头'] +['èĩª', 'è´Ł'] +['综åIJĪ', 'åĪ©ç͍'] +['èĩª', 'å¦Ĥ'] +['åİŁ', 'ä¾Ĩ'] +['ä¹Łä¸į', 'æĥ³'] +['èĬĤ', '课'] +['è¿ĩ', 'åī©'] +['çͲ', 'çĬ¶'] +['çͲçĬ¶', 'èħº'] +['æĸ°', 'ä¸ĸ纪'] +['èĩªä¸»', 'åĵģçīĮ'] +['é«ĺ', 'å±Ĥ次'] +['ä¸Ģ', 'è§Ĵ'] +['è¡Į', 'äºĭ'] +['ç¥ĸ', 'åħĪ'] +['å©ļ', 'åIJİ'] +['éĹ´', 'éļĻ'] +['ç¼Ŀ', 'éļĻ'] +['è¿Ļ', 'æĶ¯'] +['ä¸įæĸŃ', 'åĪĽæĸ°'] +['å¾®', 'åŀĭ'] +['æĽĻ', 'åħī'] +['享', 'ç͍'] +['ä¸ŃåĽ½', 'ç§»åĬ¨'] +['éĹŃ', 'çݯ'] +['æī§', 'æĦı'] +['åıijå±ķ', 'æł¼å±Ģ'] +['æł¸å¿ĥ', 'åĮº'] +['éªļ', 'æī°'] +['åħļåĴĮ', 'åĽ½å®¶'] +['ä¸ŃåĽ½', 'æĶ¿åºľ'] +['帶', 'èijĹ'] +['ä¸ĩåįĥ', 'çĵ¦'] +['åħ©', '人'] +['äºİæĺ¯', 'æĪij'] +['åĽº', 'ä½ĵ'] +['çªģ', 'å¦Ĥ'] +['çªģå¦Ĥ', 'åħ¶'] +['çªģå¦Ĥåħ¶', 'æĿ¥'] +['éĩĮç¨ĭ', 'ç¢ij'] +['çα', 'ç¾İ'] +['æŁ¥', 'éªĮ'] +['åıĮ', 'èµ¢'] +['éĹª', 'åħī'] +['楼', 'å®ĩ'] +['æĻ', 'ı'] +['æľī', 'è¶³å¤ŁçļĦ'] +['æŁĶ', 'æĢ§'] +['ä¿¡æģ¯', 'å®īåħ¨'] +['管', '线'] +['å¹¶', 'ä¸įä¼ļ'] +['åύ', 'ä»¶'] +['ä½ł', 'åºĶ该'] +['çĿĢ', 'å®ŀ'] +['æĺİ', 'æ¸ħ'] +['æĬĹ', 'çĶŁç´ł'] +['æīĵ', 'æŃ»'] +['å®Įåħ¨', 'ä¸įåIJĮ'] +['èĬ±', 'æ¤Ĵ'] +['æĶ¾', '宽'] +['ä½İ', '端'] +['åĽĽ', 'èĤ¢'] +['åĮĹ京', 'èµĽè½¦'] +['éĽĨ', 'å¸Ĥ'] +['æľª', 'å©ļ'] +['大å¹ħ', 'æıIJåįĩ'] +['建çŃij', '设计'] +['çĭ¬', 'æľīçļĦ'] +['æİ¢', 'éĻ©'] +['æ²³æµģ', 'åŁŁ'] +['æħķ', '容'] +['被', 'çĽĹ'] +['åĵº', 'ä¹³'] +['èı', 'ģ'] +['æĥ¬', 'æĦı'] +['è¶ĬæĿ¥è¶Ĭ', '好'] +['广大', '群ä¼Ĺ'] +['å¾·', 'èĤ²'] +['å¸Ĥåľº', 'ä»·æł¼'] +['奥', 'å·´'] +['奥巴', '马'] +['èĬĤ缮', 'ä¸Ń'] +['两', '款'] +['ä¸ĩä½Ļ', 'åħĥ'] +['ç»´', 'å°Ķ'] +['çĶŁçī©', 'ç§ijæĬĢ'] +['åIJ¬', 'èµ·æĿ¥'] +['çł', 'ļ'] +['æĭŁ', 'å®ļ'] +['æ²¹', 'çͰ'] +['声', 'èªī'] +['建çŃij', 'ä¸ļ'] +['éĻIJ', 'è´Ń'] +['çīĩ', 'åŃIJ'] +['çķľ', '禽'] +['ç½ij', 'é¦ĸ页'] +['ä¼Ĺ', 'çѹ'] +['æĴŀ', 'åĩ»'] +['åīį', 'ä¸įä¹ħ'] +['åīį', 'ä¸ĸ'] +['åĽĽä¸ª', 'æĦıè¯Ĩ'] +['æµĭ', 'ç»ĺ'] +['éĺ²', '空'] +['漫éķ¿', 'çļĦ'] +['æ²IJ', 'æµ´'] +['æ¯Ķè¾ĥ', 'ç®Ģåįķ'] +['æµĭ', 'å®ļ'] +['åĽŀ', 'è°ĥ'] +['让', '人们'] +['èĴĭ', 'ä»ĭ'] +['èĴĭä»ĭ', 'çŁ³'] +['ç»ĵ', 'æĻ¶'] +['å¢ŀæ·»', 'äºĨ'] +['æĿ¡', 'è¯Ħ论'] +['åī¯', 'ä¼ļéķ¿'] +['ä½ı', 'æīĢ'] +['ç»Ļ', 'åĩºäºĨ'] +['è°ĥ', 'éħį'] +['æ²', 'ĸ'] +['æľī', 'ç͍'] +['æľīç͍', 'çļĦ'] +['ä¸ĢæĿ¡', 'é¾Ļ'] +['éĩİ', 'å¤ĸ'] +['ç¼ĺ', 'åĪĨ'] +['æ°¸è¿ľ', 'ä¸įä¼ļ'] +['æŀľ', 'æłij'] +['大åıij', 'å¿«ä¸ī'] +['麻', 'éĨī'] +['äºij', 'éĽĨ'] +['åİ»', 'åĵªéĩĮ'] +['åħ¥', 'å¸Ĥ'] +['ä»»', 'æĢ§'] +['建', 'æ¡£'] +['建档', 'ç«ĭ'] +['建档ç«ĭ', 'åį¡'] +['ä¸Ģ', '棵'] +['社', 'åįĢ'] +['缸', 'ä¼´'] +['åļ', '·'] +['å¡«', 'åħħ'] +['ä¸Ģ', 'æĹı'] +['ç¾', 'ģ'] +['åıĸ', 'è¯ģ'] +['èΰ', 'éĺŁ'] +['åİĤ', 'åĮº'] +['è¡·', 'å¿ĥ'] +['åıijå±ķ', 'éĺ¶æ®µ'] +['é«ĺ', '强度'] +['åĹĵ', 'åŃIJ'] +['é¢Ĩ', 'è¡Ķ'] +['楼', '主'] +['大', 'èĴľ'] +['æŀķ', '头'] +['ç²®', 'æ²¹'] +['é»Ħ', 'çĵľ'] +['æĵ', 'Ĵ'] +['å°ı', 'çĭĹ'] +['æĶ¹éĿ©', 'å§Ķ'] +['åįģ', 'åĪĨéĴŁ'] +['é²ľ', 'èī³'] +['åħ³', 'ç¾½'] +['çĭĢ', 'æħĭ'] +['å®ŀç͍', 'æĢ§'] +['å°ij', 'è§ģ'] +['é£ŀ', 'æī¬'] +['çͰ', 'éĩİ'] +['æIJ', 'Ĥ'] +['è¿Ļ个', 'è¯į'] +['åºĶæĢ¥', 'é¢Ħæ¡Ī'] +['è§Ĵ度', 'æĿ¥çľĭ'] +['æķ¬', 'çķı'] +['æ³ķ', 'å®Ŀ'] +['åĸĦ', 'æĦı'] +['æīĵ', 'æĸŃ'] +['对', 'åĨ³'] +['çµķ', 'å°į'] +['åĢŁ', 'æŃ¤'] +['å¼Ģ', 'æºIJ'] +['å°ı', '說'] +['ç¥', 'º'] +['å²ģ', '以ä¸ĭ'] +['éĢĢå½¹', 'åĨĽäºº'] +['ä¸įä¹ħ', 'åīį'] +['åĩº', 'åİĤ'] +['讽', 'åĪº'] +['æĿ¥çľĭçľĭ', 'åIJ§'] +['éŃĶ', 'åħ½'] +['çķĻ', 'ä¸ĭæĿ¥'] +['å±ħ', '室'] +['åłħ', 'æĮģ'] +['çľĭ', 'äºĨä¸Ģ'] +['çľĭäºĨä¸Ģ', 'çľ¼'] +['éĽĨåĽ¢', 'æĹĹä¸ĭ'] +['æĪĺ', 'æĪĺç»ĦåIJĪ'] +['è®¤çľŁ', 'èIJ½å®ŀ'] +['汽车', '产ä¸ļ'] +['çī©çIJĨ', 'åѦ'] +['æķ', 'µ'] +['éĴ', 'Ŀ'] +['åĽ¢', 'éķ¿'] +['ä¸įæĸŃ', 'æī©å¤§'] +['èĤ©', 'è´Ł'] +['åıijå±ķ', '缮æłĩ'] +['è³ĩ', 'éĩij'] +['åīį', 'ç½®'] +['ä¸ŃåĽ½', 'åı¤ä»£'] +['æŃ»', 'åĪij'] +['åħħåĪĨ', 'ä½ĵçݰ'] +['åħ³', 'éŨ'] +['ç¾İ', 'æĦŁ'] +['æīĵ', 'åħ¥'] +['æĬijéĥģ', 'çĹĩ'] +['å°ij', 'çĪ·'] +['æłij', 'æŀĿ'] +['æ¶Īæģ¯', 'ç§°'] +['æ´Ľ', 'åħĭ'] +['åį', '¯'] +['è¿Ī', 'åIJij'] +['æİ¨', 'åĭķ'] +['ä»İä¸ļ', 'èĢħ'] +['åİ»', 'ä¹°'] +['欢', 'å¿«'] +['æĭ¥', 'æĮ¤'] +['马', 'æ¡¶'] +['æĬĬ', 'æİ§'] +['æĶ¿', 'åħļ'] +['å¼ł', 'æī¬'] +['客', 'æłĪ'] +['红', 'æĺŁ'] +['éĢģ', 'æĿ¥'] +['åħ¨åŁŁ', 'æĹħ游'] +['èĩª', 'ç§ģ'] +['åįģäºĮ', 'æĿ¡'] +['åı¹', 'æģ¯'] +['ä¸Ģ', 'èīĺ'] +['ä¿Ŀ', 'è´¹'] +['æĸ½å·¥', 'çİ°åľº'] +['æľī', '幸'] +['ç»Ń', 'èĪª'] +['åı¯èĥ½', 'æľĥ'] +['èĥĮ', 'åıĽ'] +['ä½£', 'éĩij'] +['ä¸ī', 'çŃīå¥ĸ'] +['å¾Ī', '满æĦı'] +['游æĪı', 'åľ¬'] +['群', 'éĩĮ'] +['æŀĦ', 'ä»¶'] +['åºı', 'å¹ķ'] +['太', 'æ¹ĸ'] +['æľ¨', 'è´¨'] +['æĻĭ', 'æ±Ł'] +['çµĤ', 'æĸ¼'] +['è·³', 'è·ĥ'] +['åĢºæĿĥ', '人'] +['çŃī', '诸å¤ļ'] +['æĶ¾', 'åĩº'] +['åħ³éĶ®', 'æĹ¶åĪ»'] +['æĦŁæŁĵ', 'èĢħ'] +['é£ŀè¡Į', 'åijĺ'] +['èĥĨ', 'åĽº'] +['èĥĨåĽº', 'éĨĩ'] +['æĬ±', 'æŃī'] +['åij¨', 'äºĮ'] +['æĸ°', 'æĹ¶æľŁ'] +['åĨ·éĵ¾', 'çµģ'] +['è¿Ļç§į', 'æĸ¹å¼ı'] +['该', 'æĿij'] +['åĽŀ', 'é¦Ī'] +['åŁºçĿ£', 'æķĻ'] +['人', 'åıĤ'] +['æŀ¯', 'çĩ¥'] +['æī¹åıij', 'å¸Ĥåľº'] +['åħħåĪĨ', 'èĤ¯å®ļ'] +['å¸Ĥ', 'æĶ¿åįı'] +['äºĭ', 'æ¥Ń'] +['龸', 'çİĭ'] +['çĥŃ', 'æIJľ'] +['åįģä¹Ŀ', '大'] +['ä¼´', 'æľī'] +['ç¾İåĽ½', 'æĢ»ç»Ł'] +['åŁİå¸Ĥ', '管çIJĨ'] +['ä¸ĭ', '令'] +['èĥ¸', 'åı£'] +['åıª', 'çŁ¥éģĵ'] +['åij¨', 'ä¸ī'] +['ç͍', 'æĪ¶'] +['éŃ', '¯'] +['å¿ĥ', 'è¡Ģ'] +['带头', '人'] +['åĮ»', 'åĬ¡'] +['åĮ»åĬ¡', '人åijĺ'] +['æİ§åζ', 'åύ'] +['ä½ľåĵģ', 'åĨħ容'] +['æĪĺ', 'åıĭ'] +['åİĨ', 'å¹´'] +['ä¸į', 'åħĭ'] +['ä¸įåħĭ', 'ä¸įåıĬ'] +['æĹ¥', 'æŃ£å¼ı'] +['è±IJ', 'å¯Į'] +['ç¨İ', 'è´¹'] +['æĹ¶', 'æķĪ'] +['å±ķ', 'ä½į'] +['è¡¡', 'éĺ³'] +['æĪ¿', '貸'] +['çĪĨ', '款'] +['ä¹IJ', 'æĦı'] +['çĶ·', '主'] +['å¯', '¬'] +['æľĥ', 'èѰ'] +['ä¹ĭ', 'å¤ľ'] +['åIJĮ', '樣'] +['ä¸įè¦ģ', '太'] +['ä¼Ĭ', 'æĸ¯'] +['ä¼Ĭæĸ¯', 'åħ°'] +['åŁºæľ¬', 'åİŁåĪĻ'] +['åİ»', 'æİī'] +['ä½İ', 'ä¿Ŀ'] +['个', '交æĺĵ'] +['个交æĺĵ', 'æĹ¥'] +['èģĬ', 'èģĬ'] +['åĽĽ', 'ä½į'] +['åħļç»Ħ', 'æĪIJåijĺ'] +['主è¦ģ', 'ä»İäºĭ'] +['å½±', 'éŁ³'] +['åĨĴ', 'åĩº'] +['åij¼åIJ¸', 'éģĵ'] +['è¾¾', 'å°Ķ'] +['æľ¨', 'åľ°æĿ¿'] +['诡', 'å¼Ĥ'] +['çģ¯', 'åħ·'] +['çģ«', 'çĥ§'] +['è§£', 'èĦ±'] +['æĦĪ', 'åıij'] +['æ¹ĸ', 'å·ŀ'] +['é£İ', 'ä¿Ĺ'] +['æĸ°', 'å½¢åĬ¿'] +['æĸ°å½¢åĬ¿', 'ä¸ĭ'] +['è²', 'Ŀ'] +['èĦ', 'ĵ'] +['åĬ¨åĬĽ', 'çĶµæ±ł'] +['é£ŀ', 'èι'] +['飧', 'æĢ§'] +['åĪ©', 'çī©'] +['åĪ©çī©', '浦'] +['ä¸į', '认è¯Ĩ'] +['ç¼ĸ', 'ç»ĩ'] +['ä½ľ', 'åĿĬ'] +['èģĮä¸ļ', 'æĬĢèĥ½'] +['çľĭ', 'è¦ĭ'] +['åĽ´', 'æ£ĭ'] +['æĺı', 'è¿·'] +['å½Ĵ', 'å±ŀäºİ'] +['æĤ¬', 'å´ĸ'] +['éĨ«', 'çĻĤ'] +['å®ĭ', '代'] +['åºĦ', 'æĿij'] +['èĹ', 'ķ'] +['çĮĽ', 'çĦ¶'] +['çĩĥæĸĻ', 'çĶµæ±ł'] +['å®ŀä½ĵ', 'åºĹ'] +['ä¸įè¶³', '以'] +['æĥħ', 'ç·'] +['æĥħç·', 'Ĵ'] +['å»Ĭ', 'åĿĬ'] +['ç͵', 'åı°'] +['åºĶ', 'åĬĽ'] +['ä¸Ńå°ı', 'åѦçĶŁ'] +['èĥ¡', 'åIJĮ'] +['éī´', 'åĪ«'] +['åĨħ', 'ç½®'] +['ä¹±', '象'] +['æ¬Ĭ', 'çĽĬ'] +['å¼ĢæĶ¾', 'å¼ı'] +['åįļ', 'æĸĩ'] +['讲', '课'] +['çŃī', 'åİŁåĽł'] +['ç©·', '人'] +['交', 'æĽ¿'] +['æĬ¤', 'çħ§'] +['åıijå±ķ', 'æľºéģĩ'] +['客', 'åķĨ'] +['åıį', 'ä¹ĭ'] +['ç±³', 'é¥Ń'] +['å¹¶', 'åıij'] +['å¹¶åıij', 'çĹĩ'] +['æ±ī', 'åŃIJ'] +['æŀľ', 'åĽŃ'] +['对æĪij', 'æĿ¥è¯´'] +['åģı', 'åIJij'] +['æī¹', '示'] +['读', 'åIJİ'] +['读åIJİ', 'æĦŁ'] +['æĺİ', 'æĻº'] +['åĽ´', 'çĿĢ'] +['åıį', '转'] +['æĿ¨', 'å¹Ĥ'] +['ä¸ĵ', 'åįĸ'] +['ä¸ĵåįĸ', 'åºĹ'] +['åıĹ', 'éĻIJ'] +['åºŁ', 'è¯Ŀ'] +['æŀģ', 'å°ij'] +['åįĪ', 'åIJİ'] +['è¿Ľ', 'ä¿®'] +['åīĬ', 'åĩı'] +['æľ¬ç§ij', 'çĶŁ'] +['ä¼ĺ', 'éĢī'] +['åħī', 'çħ§'] +['åıĻ', 'äºĭ'] +['åıĸ', 'æļĸ'] +['åĮĹ', 'è·¯'] +['æ¦', 'ķ'] +['èİĨ', 'çͰ'] +['楼', 'å±Ĥ'] +['天', 'èĬ±'] +['天èĬ±', 'æĿ¿'] +['çĤ', 'ľ'] +['å·²ç»ı', 'æľīäºĨ'] +['è¶', '¾'] +['çͳ', 'åįļ'] +['ç͵', 'éĺ»'] +['åĬŁ', '课'] +['æŃ¥', 'æŃ¥'] +['éĤ£ä¹Ī', '容æĺĵ'] +['æŃ¤', 'æĸĩ'] +['ä½', '°'] +['计', 'è¾ĥ'] +['çīĩ', 'éĿ¢'] +['ç͵影', 'éĻ¢'] +['ä¸į', 'åħ¬å¹³'] +['ä¸ī', 'æľŁ'] +['æĹħ游', 'èµĦæºIJ'] +['å¤ļç§į', 'å½¢å¼ı'] +['è£Ĥ', 'ç¼Ŀ'] +['åIJİ', 'æİĴ'] +['硬', '度'] +['åĽŀ', 'æļĸ'] +['éģĵ', 'æķĻ'] +['è´«', 'è¡Ģ'] +['æ¸ħ', 'é¦Ļ'] +['伤', 'çĹħ'] +['æĦı', '義'] +['çļĦ', 'ç¼ĺ'] +['çļĦç¼ĺ', 'æķħ'] +['åºĦ', '严'] +['åıªæĺ¯', '为äºĨ'] +['æīĵ', 'æĬĺ'] +['以', 'ä¾Ĩ'] +['滿', 'è¶³'] +['çİĽ', '丽'] +['風', 'éļª'] +['æĸĩ', 'ç§ij'] +['éħįå¤ĩ', 'äºĨ'] +['è¿Ľ', 'é£Ł'] +['æ¶', '¡'] +['è·¯', 'ç¨ĭ'] +['åı«', '声'] +['ä¸Ńå¿ĥ', 'åŁİåĮº'] +['æľīæīĢ', 'ä¸įåIJĮ'] +['å¼µ', 'è²¼'] +['é¢Ħ', 'æĬ¥'] +['æľīå¤ļ', 'ä¹Ī'] +['è¿Ľè¡Į', 'åħ¨éĿ¢'] +['æĽ¾', 'ç¶ĵ'] +['ä¸ī', '代'] +['å®ı', '大'] +['æ¸ħ', 'æī«'] +['éĢī', 'åĩº'] +['åĵª', 'ä¸Ģ个'] +['主', '義'] +['ä¾Ŀ', 'æĵļ'] +['çļ®', 'éĿ©'] +['èµ¶', 'æĿ¥'] +['çŃĽ', 'æŁ¥'] +['æ¨', 'Ł'] +['ä¿Ŀ', 'èįIJ'] +['åIJĥ', 'æĥĬ'] +['æľĭåıĭ们', '对'] +['ä»ĸ', 'æĺ¯ä¸Ģ个'] +['åºŁ', 'æ°Ķ'] +['æ»', 'ħ'] +['è´¢', 'ç¨İ'] +['æĿij', 'æĿijæ°ij'] +['èµĦ产', 'è´ŁåĢº'] +['å®ī', 'å¨ľ'] +['缮åīį', 'åĽ½åĨħ'] +['æĦŁè§ī', 'èĩªå·±'] +['çµIJ', 'åIJĪ'] +['éͦ', 'æłĩ'] +['éͦæłĩ', 'èµĽ'] +['æĽ´', 'æ·±'] +['åŁº', 'æķ°'] +['éħ¿', 'éħĴ'] +['çī¹èī²', '产ä¸ļ'] +['åİĭ', 'å®ŀ'] +['ä¾Ŀæ³ķ', '追究'] +['æ·¡', 'å®ļ'] +['ç®Ģ缴', 'å°±æĺ¯'] +['å£ĵ', 'åĬĽ'] +['æ°ij', 'å¿ĥ'] +['ä¸į', 'åIJĪéĢĤ'] +['çͱæŃ¤', 'åı¯è§ģ'] +['èµŀ', 'èªī'] +['æ¾', '¤'] +['åĩłå¹´', 'åīį'] +['åIJī', 'ä»ĸ'] +['çł´', 'æįŁ'] +['轻轻', 'åľ°'] +['å²Ľ', '屿'] +['æĦı', 'å¢ĥ'] +['ä»Ģä¹Ī', 'åı«'] +['åģĩ', 'è£ħ'] +['éĢģ', 'è´§'] +['å¹ķ', 'å¢Ļ'] +['妥', 'åįı'] +['åĽ½', 'æĹĹ'] +['äºĨ', 'å¾Īä¹ħ'] +['åĪĨ辨', 'çİĩ'] +['ç´', 'Ķ'] +['éĺ³', 'åĮº'] +['åĩŃ', 'çĿĢ'] +['åģľè½¦', 'ä½į'] +['京', 'éĥ½'] +['éĶ', '£'] +['æĵ', '¾'] +['è¿Ľ', 'éŨ'] +['åĪĺ', 'æµ·'] +['åĽĽ', '级'] +['女', 'è¶³'] +['è¡ĮæĶ¿', '审æī¹'] +['éģ¥', 'æİ§'] +['ä¸į', 'éĮ¯'] +['å¾Ĺ', 'å¾Ī好'] +['为', '缮çļĦ'] +['ä»į', 'æľª'] +['ç²¾', 'è£ħ'] +['éĢį', 'éģ¥'] +['å°½', '头'] +['çºł', 'ç¼ł'] +['éłĺ', 'å°İ'] +['æĭħ', 'è´Ł'] +['æĪĸèĢħ', 'åħ¶ä»ĸ'] +['åıªä¸įè¿ĩ', 'æĺ¯'] +['åı®', 'åĺ±'] +['åģĩ', 'åĨĴ'] +['æļĸ', 'æ°Ķ'] +['çĽIJ', 'åŁİ'] +['被', 'è§Ĩ为'] +['诺', 'è´Ŀå°Ķ'] +['ç»ĻäºĨ', 'æĪij'] +['è¿ij', 'åįĥ'] +['éĩį', 'åĽŀ'] +['éĨĴ', 'äºĨ'] +['ç͵', 'è§£'] +['忽çķ¥', 'äºĨ'] +['èĥĮ', 'éĥ¨'] +['æĸĩæĺİ', 'åŁİå¸Ĥ'] +['æº', 'ħ'] +['è²', 'ĵ'] +['æĬµ', 'æĮ¡'] +['åĸľæ¬¢', 'åIJĥ'] +['éĿĻéĿĻ', 'åľ°'] +['å¾Ī', 'æ·±'] +['åŁºç¡Ģ', 'çŁ¥è¯Ĩ'] +['è¿ĩ', 'éĶĻ'] +['çIJĨ', 'ç§ij'] +['交æµģ', 'åIJĪä½ľ'] +['èĪ', 'Ķ'] +['調', 'æŁ¥'] +['æħĪ', 'æĤ²'] +['éĴ', '°'] +['èĩ´', 'ç͵'] +['å®£ä¼ł', 'æ´»åĬ¨'] +['åıĺ', 'éĩı'] +['çļĦ人', 'æĿ¥è¯´'] +['æĹ¶', 'éļĶ'] +['ä¸į管', 'ä½ł'] +['缸', 'è¿ij'] +['è´µ', 'éĩijå±ŀ'] +['ä¹Łä¸į', 'åı¯èĥ½'] +['ç²ī', 'æľ«'] +['åįĹ', 'çĵľ'] +['çϽ', '马'] +['åħī', 'æºIJ'] +['éĩij', 'å¥ĸ'] +['çĭ¬', 'è§Ĵ'] +['çĭ¬è§Ĵ', 'åħ½'] +['妨', 'ç¢į'] +['ç»Ļ', 'åĬĽ'] +['ä½Ĩ', 'ä»į'] +['å¼łå®¶', 'åı£'] +['èIJ¬', 'åħĥ'] +['渲', 'æŁĵ'] +['éķ¿å¤§', 'äºĨ'] +['è®°èĢħ', 'äºĨè§£'] +['æĢĢ', 'çĿĢ'] +['è¦ģ', 'åѦä¼ļ'] +['游æĪı', '代'] +['游æĪı代', 'ç»ĥ'] +['äºĮ', 'çϾ'] +['æĦıè¯Ĩ', 'å½¢æĢģ'] +['çİ', 'º'] +['计åĪĴ', 'çĶŁèĤ²'] +['æī¾', 'åĩĨ'] +['åħ°', 'èĬ±'] +['è¿Ļ座', 'åŁİå¸Ĥ'] +['污', 'æ³¥'] +['å®ĺæĸ¹', '微信'] +['å½Ĵ', 'å±ŀ'] +['æ°§', 'æ°Ķ'] +['éģİç¨ĭ', 'ä¸Ń'] +['åį°è±¡', 'æ·±åĪ»'] +['稳', '妥'] +['çµIJ', 'æĿŁ'] +['åŃķ', 'æľŁ'] +['çī¹', 'æĿĥ'] +['åĿļ', 'åĽº'] +['顺', 'åĬ¿'] +['æŀľ', 'èͬ'] +['éĨ«', '師'] +['åİ', '®'] +['ä¹Łæĺ¯', 'å¦ĤæŃ¤'] +['é¦Ĵ', '头'] +['缸', 'åĬ©'] +['å¹²', '线'] +['ä¸Ģ', 'æľ¬ä¹¦'] +['ç»', '¥'] +['æĮ¯', 'å¥ĭ'] +['èĤ¾', 'èĦı'] +['åĭķ', 'çī©'] +['é£ŀ', 'è·ĥ'] +['èıľ', 'åĵģ'] +['å¤ļ', 'ä½Ļ'] +['å¤ļä½Ļ', 'çļĦ'] +['éĢĿ', 'ä¸ĸ'] +['æģĭ', '人'] +['å¼Ģåıij', 'åĪ©ç͍'] +['顺', '丰'] +['éĩİ', 'å¿ĥ'] +['æł¡', 'å¤ĸ'] +['æģIJ', 'é¾Ļ'] +['éĿ¢', 'åħ·'] +['éķ¿', 'è¾Ī'] +['éļı', 'å¤Ħ'] +['éļıå¤Ħ', 'åı¯è§ģ'] +['ç´§', '缺'] +['éĩį', 'ä¸Ń'] +['éĩįä¸Ń', 'ä¹ĭ'] +['éĩįä¸Ńä¹ĭ', 'éĩį'] +['奥', 'æĸ¯'] +['奥æĸ¯', 'åį¡'] +['ä¸Ģ个', 'å¤ļ'] +['ä¸Ģ个å¤ļ', 'æľĪ'] +['ä¸įåı¯', '缺å°ij'] +['æĸ°', 'æł¼å±Ģ'] +['æıIJ', 'æĮ¯'] +['è¡Į', 'è´¿'] +['æ¼Ĥ', 'æµģ'] +['èģĬ', 'åŁİ'] +['åħ´', '建'] +['è´¨', 'æ£Ģ'] +['ç§ģæľį', '游æĪı'] +['æĽ´', 'éĩįè¦ģ'] +['è´', '®'] +['çħ', 'ľ'] +['转åıĺ', '为'] +['è¿Ļ', '两年'] +['ä¿Ŀ', 'é²ľ'] +['æī§', 'æķĻ'] +['çĥ', '¨'] +['å¼Ģåıij', '建设'] +['è¿IJèIJ¥', '管çIJĨ'] +['误', 'å·®'] +['京', 'åī§'] +['å¸IJ', 'åı·'] +['å·¥ä½ľ', 'ä½ľé£İ'] +['ä¸ĸ', 'ä¿Ĺ'] +['çϽ', '宫'] +['天', 'åĽ½'] +['å¤©åĽ½', 'ç»§ç»Ń'] +['å·´', 'æĸ¯'] +['èIJ¥', 'åĪ©'] +['åĵģ', 'æł¼'] +['æĿijæ°ij', '们'] +['æĪ¿', '车'] +['çŃī', 'çĹĩçĬ¶'] +['å¦Ĥ', 'å®ŀ'] +['å®', '¸'] +['å±Ĥ', '级'] +['éĶĻ', 'è¿ĩäºĨ'] +['ç»ĵ', 'å®ŀ'] +['ç¬ij', 'èĦ¸'] +['羣å®ŀ', 'æĢ§'] +['éĥ½å¸Ĥ', 'æĬ¥'] +['é¥Ń', 'èıľ'] +['åºĶ', '注æĦı'] +['æĬ½', 'çĥŁ'] +['伪', 'éĢł'] +['åīį', 'ä¸Ģ天'] +['éŃĶ', 'é¾Ļ'] +['éŃĶé¾Ļ', '令çīĮ'] +['约', 'è°Ī'] +['绣çѹ', 'æİ¨è¿Ľ'] +['让', 'ç͍æĪ·'] +['åħ¨éĿ¢', 'èIJ½å®ŀ'] +['å¼Ħ', 'å¾Ĺ'] +['è°Ī', 'æģĭçα'] +['鸣', 'æĪIJéķ¿'] +['鸣æĪIJéķ¿', 'è®°'] +['æ´ĭ', 'æ´ĭ'] +['çĸı', 'æķ£'] +['éĿ¢ç§¯', '约'] +['æµĵ', '缩'] +['æĸ¯', 'é¡¿'] +['çĶŁæĢģ', 'åľĪ'] +['æī§', '导'] +['ç§»', 'éĢģ'] +['齿', 'è½®'] +['æł¹æľ¬', 'å°±ä¸į'] +['缩', 'åĩı'] +['èµ°', 'ä¸ĭåİ»'] +['çĿ«', 'æ¯Ľ'] +['ä¹Łä¸į', 'éĶĻ'] +['åıįæĺł', 'åĩº'] +['èĭ¦', 'æģ¼'] +['缸åħ³', 'æĶ¿çŃĸ'] +['é«ĺ', '楼'] +['ç²ī', 'èī²'] +['æĬķèµĦ', 'é¢Ŀ'] +['ä¸į', 'ç»ı'] +['ä¸įç»ı', 'æĦı'] +['å®ģ', 'æĦ¿'] +['èĪĮ', '头'] +['æ»ĭ', 'çĶŁ'] +['å®ģ', 'åİ¿'] +['åīįåĪĹ', 'èħº'] +['åĩ', '³'] +['é£Ł', '欲'] +['åıĸ', 'èĥľ'] +['éĻ¢', 'åŃIJ'] +['ç´łè´¨', 'æķĻèĤ²'] +['滨', 'å·ŀ'] +['æĬ¢', 'æĬĵ'] +['å¼Ĥ', 'åij³'] +['åĴ', 'ļ'] +['åĬ', 'į'] +['宽', 'éĺĶ'] +['æļ´', '涨'] +['æĥł', 'åıĬ'] +['è§Ħ', 'ç¨ĭ'] +['ä¾Ľ', 'åħ»'] +['éĢģ', 'å¾Ģ'] +['å±±', 'åºĦ'] +['举', 'äºļ'] +['å±ķ', 'é¦Ĩ'] +['è§£', 'éĶģ'] +['æĹł', 'è§Ĩ'] +['éĻį', 'èIJ½'] +['è¿ŀ', 'äºij'] +['è¿ŀäºij', '港'] +['åıĤ', 'è°ĭ'] +['çİ', 'ĸ'] +['ç¬', 'ĥ'] +['èĢĹ', 'è´¹'] +['æī¿', 'å¾·'] +['社ä¼ļ', 'æķĪçĽĬ'] +['åįĹæµ·', 'ç½ij'] +['åĪĽ', '伤'] +['èIJ', '±'] +['åħħ', 'æ²Ľ'] +['ç½ijç«Ļ', '建设'] +['大', 'åºĨ'] +['åĨį', 'éĢł'] +['åŃĹ', 'æł·'] +['åħ¨æ°ij', 'åģ¥èº«'] +['èĮ«', 'èĮ«'] +['æµ®', 'åĬ¨'] +['åīį', 'åı°'] +['å¢ŀ', '设'] +['éĢĽ', 'è¡Ĺ'] +['åĢĴ', 'éĹŃ'] +['æ³ķå¾ĭ', '顾éĹ®'] +['çĸ', '®'] +['çĹħ', 'çĹĩ'] +['空', 'åīį'] +['请', 'æķĻ'] +['èĥľ', 'ä»»'] +['æĿĢ', 'èıĮ'] +['æĪĺæĸĹ', 'æľº'] +['ç»ĺ', 'åζ'] +['å¤Ħ', 'æĸ¹'] +['çªģ', 'åĽ´'] +['çĮ«', 'åĴª'] +['æĬ¥åijĬ', 'æĺ¾ç¤º'] +['ç¿', 'Ł'] +['çķ¶', 'åľ°'] +['æľĢ', 'éļ¾'] +['纪', 'å§Ķ书记'] +['ä½İ', 'åİĭ'] +['èĻļ', '空'] +['è¿Ļéĥ¨', 'ç͵影'] +['产ä¸ļ', 'åįĩ级'] +['è°·', 'çα'] +['è°·çα', 'åĩĮ'] +['æĬ¼', 'éĩij'] +['女', 'æĸ¹'] +['éĴ»', 'çłĶ'] +['æļĹ', 'æļĹ'] +['è¿·', 'ä½ł'] +['æīĢ', 'è¬Ĥ'] +['å¨ģ', 'å»ī'] +['å¼Ģ', 'æľĹ'] +['å²', 'Ķ'] +['çģ«', 'çĤ¬'] +['åIJĪçIJĨ', 'æĢ§'] +['åħ¬', 'åĬŀ'] +['ä¼ļ', 'ä¼ļéķ¿'] +['éĺ´', 'è°ĭ'] +['å¼Ģ', 'å±Ģ'] +['æĻ®éĢļ', 'è¯Ŀ'] +['åį¡', 'æĭī'] +['å°ij', 'åIJĥ'] +['éĹª', 'èĢĢ'] +['æŀľ', 'æ±ģ'] +['æī§è¡Į', 'åĬĽ'] +['è°', 'Ľ'] +['æĬ¢', 'åĬ«'] +['é«ĺéĢŁ', 'åıijå±ķ'] +['éŁ', '¬'] +['åįĹ', 'æ²Ļ'] +['é«ĺçŃī', 'åŃ¦æł¡'] +['æį¢', '个'] +['åı¯èĥ½', 'åŃĺåľ¨'] +['æĬ', 'Ĵ'] +['è°±', 'åĨĻ'] +['被', 'æĬĵ'] +['æĿ¯', 'åŃIJ'] +['èĬĤèĥ½', 'åĩıæİĴ'] +['æ°ĶåĢĻ', 'åıĺåĮĸ'] +['åĪĨ', 'åĪ¥'] +['ä¸Ń', 'æŀ¢'] +['欢', 'åij¼'] +['åħī', '纤'] +['è¿Ļ', '群'] +['çľ¼', 'çķĮ'] +['åħ±åIJĮ', 'åıijå±ķ'] +['çݰ', 'ä»Ĭ'] +['éĹ»', 'è¨Ģ'] +['çī¹èī²', 'å°ıéķĩ'] +['æķij', '人'] +['éĻį', 'æ°´'] +['ä¸ĸçķĮ', 'ä¸Ģæµģ'] +['å°±', 'é¤IJ'] +['çŀ', '¥'] +['å¤į', 'ä»ĩ'] +['ç¾½', 'æ¯Ľ'] +['ç¾½æ¯Ľ', 'çIJĥ'] +['è´©', 'åįĸ'] +['æºIJ', 'æ³ī'] +['æĢ»ä½ĵ', 'è§ĦåĪĴ'] +['åĬ¨', 'æĦŁ'] +['ä¸Ģ', '审'] +['åĢŁ', 'éĴ±'] +['è§ģ', 'æķĪ'] +['èĬ±', 'èįī'] +['åIJĮ', 'ä¸ļ'] +['æŁ¥', 'è©¢'] +['åĽ½éĻħ', 'åIJĪä½ľ'] +['ä¾Ľ', 'åĽ¾'] +['åģ', '´'] +['æł', 'ĵ'] +['缸', 'éĢļ'] +['è°Ī', 'åıĬ'] +['è¿ĩç¨ĭ', 'å½ĵä¸Ń'] +['é¦Ļ', 'èıĩ'] +['åįģåĽĽ', 'æĿ¡'] +['ä¸Ģå¼Ģå§ĭ', 'å°±'] +['ä¸ĵ', 'åijĺ'] +['æĺİ', '顯'] +['æīĵéĢł', 'åĩº'] +['ä¸ĭéĿ¢', 'æĪij们'] +['æľº', 'æ²¹'] +['åı°', 'è¯į'] +['åŃIJ', 'å¼Ł'] +['æľĢ', '常è§ģçļĦ'] +['æĪij', 'è®°å¾Ĺ'] +['ç»', '°'] +['æĤ¬', 'æµ®'] +['è¿ĺ', '羣æĺ¯'] +['æĮĤ', 'åı·'] +['åıĭ', 'åĸĦ'] +['éĩį', '伤'] +['çħ§', '亮'] +['æŃ¦', 'èѦ'] +['åĩºçݰ', 'éĹ®é¢ĺ'] +['è¸Ĭ', 'è·ĥ'] +['åľ°çIJĥ', 'ä¸Ĭ'] +['å¸Ĥ', '人大'] +['åıĹ害', '人'] +['å²', 'IJ'] +['åIJĮ', 'åѸ'] +['éĩijèŀį', 'å¸Ĥåľº'] +['æľīçļĦ', 'çݩ家'] +['å¸Ĥ', 'æķĻèĤ²'] +['å¸ĤæķĻèĤ²', 'å±Ģ'] +['åIJĦ', 'å¼Ĥ'] +['ç·ļ', 'ä¸Ĭ'] +['æģ', 'º'] +['æľī', '大éĩıçļĦ'] +['åķĨ', 'æĬ¥'] +['åįķ', 'åįķ'] +['åħ¨', 'é¢Ŀ'] +['ä¾ĿæĹ§', 'æĺ¯'] +['好', 'åĩłä¸ª'] +['åĸ', 'µ'] +['éĩį', 'æķ´'] +['çĶŁæ´»', 'è´¨éĩı'] +['æİ¢', '访'] +['åį°', 'èĬ±'] +['缼', 'è¡Į'] +['å¾®', 'è§Ĥ'] +['èĪį', 'å¾Ĺ'] +['åºŁå¼ĥ', 'çī©'] +['积', 'èĵĦ'] +['å®ļ', 'å±ħ'] +['æĤ', '¼'] +['èĮ', '¸'] +['çļĦ', '帮åĬ©'] +['çļĦ帮åĬ©', 'ä¸ĭ'] +['亿', 'åIJ¨'] +['åŃĶ', 'éĽĢ'] +['è¿ĻæĿ¡', 'è·¯'] +['é¥', 'µ'] +['æĦĪ', 'åĬł'] +['éķ', 'į'] +['ä½ľ', 'æ¡Ī'] +['èįĶ', 'æŀĿ'] +['太', 'å°ij'] +['è·»', '身'] +['åħ¬çĽĬ', 'æ´»åĬ¨'] +['çϽ', 'æĸij'] +['æĬĢæľ¯', 'æ°´å¹³'] +['å¸', '§'] +['æĹł', 'çŁ¥'] +['åºĶ该', 'æĢİä¹Ī'] +['éĢĢ', 'å¸Ĥ'] +['æ¸', 'Ń'] +['åħ»', 'çĮª'] +['é©', '¼'] +['群', 'å²Ľ'] +['大', 'åį«'] +['ä¹ĺ', 'çĶ¨è½¦'] +['èı²', 'å°Ķ'] +['è´´', 'åIJ§'] +['åģľ', 'ä¸ĭæĿ¥'] +['æľīæľº', 'ç»ĵåIJĪ'] +['åĪ»', 'èĭ¦'] +['çļĦ', 'åľ°'] +['çļĦåľ°', 'æŃ¥'] +['è¯Ĭ', 'æīĢ'] +['å¼Ģ', 'æĪĺ'] +['èĢģ', 'çīĮ'] +['çѹ', 'çłģ'] +['åħ«å¤§', '以æĿ¥'] +['楼', 'æĪ¿'] +['åŃĻ', 'æĤŁ'] +['åŃĻæĤŁ', '空'] +['åħĴ', 'åŃIJ'] +['第ä¸Ģ', 'æĿ¡'] +['社交', 'åªĴä½ĵ'] +['æĥ³', 'èµ·æĿ¥'] +['大', 'æ´ĭ'] +['æĭ¼', 'éŁ³'] +['è¿Ľ', 'åįļä¼ļ'] +['è¿ĩ', 'åħ³'] +['æ²', '¼'] +['ç©¿', 'æIJŃ'] +['éĤ£', 'ä¸Ģ天'] +['çł´', 'éŨ'] +['æĬķæłĩ', '人'] +['èµ¢', 'å®¶'] +['èĻļ', 'å¼±'] +['æ¿', 'ĥ'] +['å®ī', 'æ£Ģ'] +['客', 'å®¶'] +['çĭ¬ç«ĭ', 'èij£äºĭ'] +['æīĭ', 'åĬ¿'] +['åīµ', 'éĢł'] +['åľĨ满', 'å®ĮæĪIJ'] +['为主', '线'] +['好å¥ĩ', 'å¿ĥ'] +['é¢Ĩ', 'åľŁ'] +['çª', 'ĸ'] +['åħ¸åŀĭ', 'æ¡Īä¾ĭ'] +['çªģåıij', 'äºĭä»¶'] +['åºķ', 'æ°Ķ'] +['头', 'æĻķ'] +['å®Ľ', 'å¦Ĥ'] +['è§', '¸'] +['æ¸ħ', 'æ·¡'] +['åļ', '¼'] +['åģľ', 'ç͵'] +['ç²ī', 'å°ĺ'] +['éĻįä½İ', 'æĪIJæľ¬'] +['æĶ¾', 'æīĭ'] +['è®°èĢħ', '表示'] +['æĭĸ', 'å»¶'] +['éª', 'ĩ'] +['æ®ĭ', 'å¿į'] +['çľģ', 'æķĻèĤ²'] +['çľģæķĻèĤ²', 'åİħ'] +['é«ĺ', 'é¢Ŀ'] +['éĦ', 'Ļ'] +['æ¥', 'ŀ'] +['åĨħ', 'ç§ij'] +['èIJ¥ä¸ļ', 'é¢Ŀ'] +['åŁº', 'çŁ³'] +['æµģ', 'æ·Į'] +['主', 'æĹ¨'] +['éĺIJ', 'éĩĬ'] +['建', 'åįİ'] +['æĥĬ', 'åı¹'] +['çī¢åĽº', 'æłijç«ĭ'] +['æĺ¯åIJ¦', 'åŃĺåľ¨'] +['建', 'åĨĽ'] +['éĽ¾', 'éľ¾'] +['åħ¬', '认'] +['åħ¬è®¤', 'çļĦ'] +['æ°¨', 'åŁº'] +['æ°¨åŁº', 'éħ¸'] +['åīį', 'åĩłå¹´'] +['åι', 'éĤ£'] +['æ±Ł', '举'] +['å·¥', 'æ¥Ń'] +['ä¸ĢçĤ¹', 'ä¹Łä¸į'] +['ä¿®', '士'] +['äºĨä¸Ģ', 'éģį'] +['åĪ', 'ģ'] +['æ»ļ', 'æ»ļ'] +['åĪĨ', 'æł¡'] +['羣', 'çα'] +['è¡Ģ', 'èĦī'] +['æĢ¥', 'åī§'] +['ä¸Ģ群', '人'] +['ç¾', '¯'] +['æĪIJ', 'é¾Ļ'] +['ç²¾ç¥ŀ', 'çĹħ'] +['缸åħ³', '人åijĺ'] +['éĿĵ', '丽'] +['ä¸ī', 'åŃ£åº¦'] +['åĪĴ', 'å®ļ'] +['ä¸ĸçķĮ', '第ä¸Ģ'] +['éĢļ', 'ä¿Ĺ'] +['åķĨä¸ļ', 'åľ°äº§'] +['åĬŁèĥ½', 'æĢ§'] +['èµĦæľ¬', '主ä¹ī'] +['详', 'è§ģ'] +['æĬĵ', 'æįķ'] +['æĸĩ', 'æĺĮ'] +['å®Ŀ', 'å®ī'] +['è£ħéħį', 'å¼ı'] +['æºIJ', 'æºIJ'] +['æºIJæºIJ', 'ä¸įæĸŃ'] +['çĶŁ', 'æĢķ'] +['纵', 'åIJij'] +['å£', '½'] +['çľ¼', 'è¢ĭ'] +['èĤī', 'ä½ĵ'] +['åı¤', 'ä»Ĭ'] +['èŀį', 'åªĴä½ĵ'] +['åģ', 'ī'] +['æł¼', 'æľĥåĵ¡'] +['çĥ', '·'] +['åĬŁ', 'ç͍'] +['æīŃ', '磩'] +['绿èī²', 'éĢļéģĵ'] +['åī§', 'ç»Ħ'] +['å¼±', 'åĬ¿'] +['è´¨éĩı', 'éĹ®é¢ĺ'] +['éĻIJ', 'é¢Ŀ'] +['éª', 'Ĩ'] +['éģµ', 'ä¹ī'] +['å¯Ŀ', '室'] +['æĥ³', '念'] +['åł±', 'åijĬ'] +['ä»ħ', '次'] +['ä»ħ次', 'äºİ'] +['èŀį', 'åĪĽ'] +['æĭĽèģĺ', 'ä¼ļ'] +['åºĬ', 'åŀ«'] +['转åŀĭ', 'åıijå±ķ'] +['ä¸ŃåĽ½', 'çĶµä¿¡'] +['åIJ¬', 'è¯Ŀ'] +['è«ĭ', 'æ±Ĥ'] +['大éĥ¨åĪĨ', '人'] +['æ´»', 'å¾Ĺ'] +['åĵŃ', 'æ³£'] +['è¶', 'Ļ'] +['åıijçĹħ', 'çİĩ'] +['ä¸į', '符'] +['åĨĽ', 'å®ĺ'] +['é¢Ī', 'æ¤İ'] +['æĸ°åĨł', 'çĸ«æĥħ'] +['æŁ¬', 'åŁĶ'] +['æŁ¬åŁĶ', '寨'] +['ä»»ä½ķ', 'å½¢å¼ı'] +['人', 'éĻħ'] +['人éĻħ', 'åħ³ç³»'] +['æĢ»', 'æī¿åĮħ'] +['å¹³åĿĩ', 'æ¯ı'] +['æģŃ', 'åĸľ'] +['åĦ', 'ĺ'] +['åħµ', '马'] +['è¿Ł', 'åΰ'] +['å·¥', '伤'] +['çīĪæĿĥ', 'å½Ĵ'] +['çīĪæĿĥå½Ĵ', 'åİŁ'] +['æĭ¥', 'æĬ¤'] +['ç³Ĭ', 'æ¶Ĥ'] +['å¹²', 'æ¶ī'] +['å°ij', 'ä¸įäºĨ'] +['æĥ³', 'æī¾'] +['è´¹', 'çİĩ'] +['该', 'éĻ¢'] +['èŀį', 'åĮĸ'] +['è¿İ', 'åIJĪ'] +['è§ĨåIJ¬', 'èĬĤ缮'] +['æł¼', 'ç¶²ç«Ļ'] +['çľī', 'æ¯Ľ'] +['欢è¿İ', '大家'] +['å®¶åºŃ', 'æķĻèĤ²'] +['ä¾µ', 'èļĢ'] +['ç»Ļ', 'ä½łä»¬'] +['è¡Ģæ¶²', '循çݯ'] +['å¯Ħ', 'æīĺ'] +['å°ĸ', 'åı«'] +['以ä¸ĭ', 'åĩłä¸ª'] +['è¿ĺ', '以为'] +['åħ¶ä»ĸ', 'çݩ家'] +['ç¬ij', 'ç¬ij'] +['æīĵ', 'åIJ¬'] +['èĩªçĦ¶', 'ç§ijåѦ'] +['åŁº', 'ç«Ļ'] +['ä¹Ŀ', 'å·ŀ'] +['ä¿Ŀ', '驾'] +['ä¿Ŀ驾', 'æĬ¤'] +['ä¿Ŀ驾æĬ¤', 'èĪª'] +['æĶ¾', 'çľ¼'] +['çŁ¥åIJį', 'ä¼ģä¸ļ'] +['ç¸', '®'] +['ç¨', '½'] +['æļ', 'ĩ'] +['使ç͍', '網路'] +['é¢Ħ', 'çķĻ'] +['大', '象'] +['åıijæĺİ', 'ä¸ĵåĪ©'] +['æĸĩ', '娱'] +['éĢł', 'ç¦ı'] +['湿', '润'] +['éĿ¢', 'æĿ¡'] +['æ¶Īè´¹', 'åįĩ级'] +['è®Ĭ', 'å¾Ĺ'] +['åĩł', 'åIJį'] +['ä»', 'Ħ'] +['认', 'æ¸ħ'] +['è¿ľ', 'æĻ¯'] +['æıĴ', '座'] +['诸', '侯'] +['åıĺ', 'æĢģ'] +['ç¦ı', '彩'] +['è´§', 'æŀ¶'] +['失', 'æİ§'] +['ç§»åĬ¨', '端'] +['ä¸Ĭ', 'åı¸'] +['éĢł', '纸'] +['å¸ĥ', 'æľĹ'] +['çĴ', 'ĩ'] +['åı°', 'åįĹ'] +['åĮĹ京', 'åĨ¬å¥¥'] +['èĵĿ', 'çīĻ'] +['éķ¿', 'çŁŃ'] +['æĬĺ', 'å°Ħ'] +['ç»ij', 'æŀ¶'] +['å¯Ĵ', 'åģĩ'] +['转', 'åŁºåĽł'] +['æĢ¥', 'äºİ'] +['æŃ£', 'åĵģ'] +['åħħ', '滿'] +['大', '纲'] +['æĬĹ', 'ä½ĵ'] +['è¨ĵ', 'ç·´'] +['æĶ¶', 'ç´§'] +['æ¯Ķ', 'è³½'] +['åħµ', 'åĬĽ'] +['æľ¬', 'æĽ¸'] +['äºĮ', '代'] +['æĢ¥', 'è¯Ĭ'] +['æĸĩ', 'æ¡Ī'] +['ç»ı', 'åķĨ'] +['æĻ¨', 'æĬ¥'] +['æ£', 'ĺ'] +['æĢ»ä¹¦è®°', 'åľ¨'] +['åıĹ', 'éĤĢ'] +['äºĶ', 'åĽĽ'] +['å²Ń', 'åįĹ'] +['çα', 'åIJĥ'] +['åŁĥ', 'å°Ķ'] +['å¿ĥ', 'å¢ĥ'] +['è¦ĨçĽĸ', 'éĿ¢'] +['å®ŀåľ¨æĺ¯', '太'] +['æł¹', 'åºķ'] +['纷纷', '表示'] +['åĹ', 'ħ'] +['éļıçĿĢ', 'æĹ¶éĹ´'] +['åİĨåı²', 'æĤłä¹ħ'] +['éħ', 'ī'] +['æĢ»', 'éĺŁ'] +['主é¢ĺ', 'æ´»åĬ¨'] +['éĹ®', 'åį·'] +['é©¿', 'ç«Ļ'] +['æı¡', 'ä½ı'] +['åı¯èĥ½', '导èĩ´'] +['æ°ij', 'éĸĵ'] +['éĸĭ', 'åķŁ'] +['ä½Ĩ', 'ä¸įéĻIJ'] +['ä½Ĩä¸įéĻIJ', 'äºİ'] +['åįģ', 'éĩĮ'] +['å¨', '¥'] +['æįŁ', 'èĢĹ'] +['çĸı', '导'] +['çݯ', 'æ°§'] +['ç¥ŀ', 'éĢļ'] +['çα', 'å°Ķ'] +['çαå°Ķ', 'åħ°'] +['æľ´', 'å®ŀ'] +['å¿«', 'æĬ¥'] +['æĶ¶', 'åıĹ'] +['æĪĸ', '許'] +['èĥĮ', 'éĿ¢'] +['æĸĩåĮĸ', 'ä¼łåªĴ'] +['ä¸ī', 'åĢĭ'] +['æĶ»', 'åĬ¿'] +['å®ī', '举'] +['å®ī举', 'å°¼'] +['åĿĩ', 'å·²'] +['顾', 'èĻij'] +['éĦ', 'Ń'] +['è¿Ļå®¶', 'åħ¬åı¸'] +['åħ¬åijĬ', 'ç§°'] +['æıIJä¾Ľ', 'ä¼ĺè´¨'] +['稳æŃ¥', 'æİ¨è¿Ľ'] +['å¤į', 'è¯ķ'] +['å°Ĩ', 'é¢Ĩ'] +['è°Ī', 'èµ·'] +['å¨', 'Ħ'] +['è¿ŀ', '线'] +['æ©Ł', 'éĹľ'] +['åºĶç͍', 'åľºæĻ¯'] +['çĶ»', 'åĥı'] +['è´¢', 'è¿IJ'] +['ä¿Ŀ', 'éļª'] +['çĹħ', 'çIJĨ'] +['æ¯Ľ', '主å¸Ń'] +['ä¸Ŀ', '毫ä¸į'] +['çα', 'å¥ĩ'] +['çαå¥ĩ', 'èīº'] +['ä¸ĵå®¶', 'ç»Ħ'] +['åij¼', 'åͤ'] +['éĭ', '¼'] +['çģ', '¸'] +['é¢ĨåħĪ', 'åľ°ä½į'] +['æıIJ', 'æĭĶ'] +['龸', 'éģĵ'] +['å±±', 'åĿ¡'] +['èĿ', 'İ'] +['沸', 'èħ¾'] +['该', '项'] +['ä»Ĭ', 'çĶŁ'] +['ä¸Ģç¯ĩ', 'æĸĩ竳'] +['æĸ¹å¼ı', 'è¿Ľè¡Į'] +['é»ij', '客'] +['æĶ¹', 'åĬ¨'] +['主', 'é¡Į'] +['æķ£', 'å¸ĥ'] +['ä»Ģä¹Ī', 'åľ°æĸ¹'] +['åĮĸ', 'åIJĪ'] +['åĮĸåIJĪ', 'çī©'] +['éĿĻ', 'ç͵'] +['æĢ»', 'æĶ¶åħ¥'] +['å§Ķ', 'ç»Ħç»ĩ'] +['å§Ķç»Ħç»ĩ', 'éĥ¨'] +['éĿĻ', 'æĢģ'] +['èĢģ', 'åŃĹåı·'] +['室', 'åıĭ'] +['éĥ½ä¸į', 'æķ¢'] +['æŀ¶', 'åŃIJ'] +['çģµ', 'æķı'] +['审', 'è§Ĩ'] +['æĤ£', 'åĦ¿'] +['å±±', '寨'] +['èĸª', 'èµĦ'] +['é©°', 'æı´'] +['éĥ¨åĪĨ', 'åĨħ容'] +['好', 'ä¼¼'] +['æĪIJåijĺ', 'åĽ½'] +['åľ¨æĪij', 'çľĭæĿ¥'] +['åħ³æ³¨', '度'] +['éĻĪ', 'æŁIJ'] +['è¿Ļç§į', 'äºĭæĥħ'] +['éĢī', 'å®ļ'] +['ç²¾', 'åŃIJ'] +['å£ģ', 'çĶ»'] +['æ±Ł', 'æ·®'] +['é«ĺ', 'æĺĤ'] +['æł¼', 'åĬĽ'] +['è¼', '©'] +['åѦ', 'åłĤ'] +['æĤ¨', 'åIJĮæĦı'] +['ä¸ĢåĪĩ', 'éĥ½æĺ¯'] +['æ½', '¤'] +['éĸ', 'ĥ'] +['å¸ĮæľĽ', 'èĩªå·±'] +['ä¿', 'ĺ'] +['æ±Ł', 'åİ¿'] +['æ³', '¾'] +['ç§ij', 'æķĻ'] +['æīĵ', 'è¿Ľ'] +['ä¸į', 'æħİ'] +['å¯Ĵ', 'åĨ¬'] +['æ¸Ķ', 'æ°ij'] +['鼷', 'æĸ¯'] +['主', 'å®°'] +['æĹħ游', '度åģĩ'] +['ç͵åŃIJ', 'éĤ®ä»¶'] +['æ±Ĥ', 'å©ļ'] +['éļİ', '段'] +['åģ¥èº«', 'æĪ¿'] +['注æĺİ', 'åĩºå¤Ħ'] +['äºĭæķħ', 'åıijçĶŁ'] +['级', '以ä¸Ĭ'] +['åŃĺ', 'æ´»'] +['æĸ½', 'èĤ¥'] +['èľľ', 'èľĤ'] +['åµ', '©'] +['æĮĸæİĺ', 'æľº'] +['æĬĹ', 'æĭĴ'] +['ä¼ł', '导'] +['æĺ¯ä»Ģä¹Ī', 'åij¢'] +['ä¸Ĭå¹´', 'åIJĮæľŁ'] +['建', 'åħļ'] +['çĶŁ', 'æħĭ'] +['ä¿Ŀ', 'ä½ı'] +['款', '车åŀĭ'] +['人', 'èĦī'] +['éļIJ', 'èͽ'] +['失', 'æķĪ'] +['éģ¿', 'åŃķ'] +['ç®Ģ', '便'] +['谢谢', 'ä½ł'] +['å®Ī', 'ä½ı'] +['æĶ¾', 'æĺł'] +['è¨Ī', 'çķ«'] +['çݰ代', 'çµģ'] +['é¤IJ', '廳'] +['æķħ', 'å±ħ'] +['大', '大å°ı'] +['大大å°ı', 'å°ı'] +['çī¹åĪ«', '声æĺİ'] +['éģį', 'åıĬ'] +['å¿ĥçIJĨ', 'åĴ¨è¯¢'] +['è³', '´'] +['çĮ®', 'è¡Ģ'] +['å·²ç»ı', 'è¾¾åΰ'] +['æīĵ', 'æĭĽåij¼'] +['åıĮ', 'è¾¹'] +['ä¸Ģæĸ¹éĿ¢', 'æĺ¯'] +['å´ĩ', 'å°ļ'] +['éĺ¿', 'å¯Į'] +['éĺ¿å¯Į', 'æ±Ĺ'] +['æĮģ', 'æľī人'] +['è±', 'ģ'] +['é£İ', 'çŃĿ'] +['åĬ¨', 'èį¡'] +['äºĨä¸Ģ', 'ä¼ļ'] +['äºĨä¸Ģä¼ļ', 'åĦ¿'] +['ä¸ĩ', '象'] +['çľĭ', 'ç͵è§Ĩ'] +['åįģä¸ī', 'æĿ¡'] +['çĮĽ', 'çĥĪ'] +['è¦ģ', 'ä¸įçĦ¶'] +['太æŀģ', 'æĭ³'] +['å¼ķ', 'çĪĨ'] +['ç»ıè¿ĩ', 'å¤ļå¹´'] +['游æĪı', 'éĩĮçļĦ'] +['é¾Ļ', 'æ³ī'] +['æłĩ', 'éħį'] +['è®ĵ', 'ä»ĸåĢij'] +['éĢł', 'æŀĹ'] +['åĮºåŁŁ', 'æĢ§'] +['亿', 'ä¸ĩ'] +['æĪĺçķ¥', 'å¸ĥå±Ģ'] +['éķĩ', 'æĶ¿åºľ'] +['åĶ®', '票'] +['çĶŁäº§', 'å·¥èīº'] +['éķĩ', 'åħļå§Ķ'] +['ä¸Ńå°ı', 'åŀĭ'] +['æľ¨', 'è̳'] +['æ²³', 'è¾¹'] +['èĦ¾', 'èĥĥ'] +['欢è¿İ', 'æĤ¨'] +['åıĺ', 'å¼Ĥ'] +['缤', '纷'] +['åŀĥåľ¾', 'æ¡¶'] +['辩', 'è¯ģ'] +['车', 'åºĵ'] +['æ¯Ķ', 'çİĩ'] +['åħ´', 'æĹº'] +['详ç»Ĩ', 'äºĨè§£'] +['å®ī', 'å±ħ'] +['çħ§', 'æĸĻ'] +['æĸ¹', 'æīį'] +['èµ', '¦'] +['åĨ', 'ķ'] +['å¥Ķ', 'èµ´'] +['å®Ŀ', '鸡'] +['åľº', 'åĿĩ'] +['缮åīį', 'æŃ£åľ¨'] +['åIJŀ', 'åϬ'] +['è¿°', 'èģĮ'] +['æĩ', 'µ'] +['å¥ĩ', 'çijŀ'] +['ä»į', 'å°Ĩ'] +['èĪī', '辦'] +['å·¥åķĨ', 'å±Ģ'] +['å¡ij', 'èĥ¶'] +['åĬŀ', 'å®ŀäºĭ'] +['æĸ¹', 'æĸ¹éĿ¢'] +['æĸ¹æĸ¹éĿ¢', 'éĿ¢'] +['æĸĩåĮĸ', 'èĬĤ'] +['åħ¥', 'èģĮ'] +['é¸', '¥'] +['ç©¿', 'éĢı'] +['以', 'ä¹łè¿ijå¹³'] +['åį±', 'éļª'] +['æľ¦', 'èĥ§'] +['åİĨåı²', 'æĢ§'] +['æķŀ', 'å¼Ģ'] +['ä¼Ļä¼´', 'åħ³ç³»'] +['çŁ¿', 'åĮº'] +['åĽ½éĻħ', 'åľ¨çº¿'] +['ä¼łå¥ĩ', 'éĩĮéĿ¢'] +['è¿ij', 'äºĽ'] +['è¿ijäºĽ', 'å¹´'] +['åĬ£', 'åĬ¿'] +['æĶ»åĩ»', 'åĬĽ'] +['æĻº', 'éĢł'] +['ç¦', '§'] +['çİĭ', 'åħĪçĶŁ'] +['éĨ«', 'çĶŁ'] +['åĽĽ', '项'] +['å®ŀ', 'æĻ¯'] +['åĪĿ', 'åĪĽ'] +['å¿ĥ', '裡'] +['æĻ¶', 'ä½ĵ'] +['交', 'éĻħ'] +['让', 'æ¶Īè´¹èĢħ'] +['课', 'æĸĩ'] +['æİĴ', 'æ°Ķ'] +['å¹¶ä¸į', 'æĦıåij³'] +['缸', '声'] +['第ä¸Ģ', 'å±Ĭ'] +['åİŁ', 'èijĹ'] +['éĽ', 'ľ'] +['没æľī', '太大'] +['è¡¥', 'æ°´'] +['çµģ', 'ä¼ģä¸ļ'] +['第äºĮ', 'æī¹'] +['åħ¶å®ĥ', 'éĹ®é¢ĺ'] +['æİĮ', 'éŨ'] +['责任', 'å¿ĥ'] +['é¤IJ', 'åħ·'] +['ç¾Ĭ', 'æ¯Ľ'] +['没æľī', 'å¿ħè¦ģ'] +['ä¹IJ', 'åĽ¢'] +['è¿Ľ', 'åŁİ'] +['ä¸ĢçĤ¹', 'åĦ¿'] +['身', 'å½¢'] +['çļ®èĤ¤', 'çĹħ'] +['æĺ', '±'] +['å¢ŀ', 'èĩ³'] +['èģ²', 'æĺİ'] +['æıIJ', 'è´¨'] +['ä½ĵèĤ²', 'åľº'] +['çѹ', '建'] +['é¬', 'Ĩ'] +['车', 'çīĮ'] +['éļĶ', 'éŁ³'] +['è´Łè´£', 'åIJĮå¿Ĺ'] +['丰', 'ç¡ķ'] +['ä½Ľ', 'éĻĢ'] +['äºī', 'åIJµ'] +['åº', '¶'] +['æ·¡', 'æ°´'] +['å°ı', 'çĶ·åŃ©'] +['ç§ģ', 'èĩª'] +['åĮĸ', 'è¿Ľç¨ĭ'] +['æĪĺ士', 'æĿ¥è¯´'] +['æ²¹', 'èħ»'] +['èĦ±è´«', 'èĩ´å¯Į'] +['æĹ¥å¸¸', 'å·¥ä½ľ'] +['交', 'èŀį'] +['åĨľ', 'è´¸'] +['åĨľè´¸', 'å¸Ĥåľº'] +['åĵĪ', 'çĻ»'] +['ç͵', 'è´¹'] +['èµ', 'ĺ'] +['åıĮ', 'èħ¿'] +['æĵĶ', 'å¿ĥ'] +['æĿ¥', '形容'] +['使åij½', 'æĦŁ'] +['éĤ£ä¹Ī', 'ç®Ģåįķ'] +['èĬĻ', 'èĵī'] +['åĢŁæ¬¾', '人'] +['ç§Ģ', '丽'] +['è®ĵ', 'ä»ĸ'] +['严åİī', 'æīĵåĩ»'] +['è³', 'ŀ'] +['æļ', '«'] +['çħ¤', 'æ°Ķ'] +['çά', 'ä¸Ĭ'] +['æ½ĩ', 'æ´Ĵ'] +['太', 'ä¹ħ'] +['åij½', 'åIJį为'] +['è·¯', 'çͱ'] +['è·¯çͱ', 'åύ'] +['é©', '¯'] +['æıIJ', 'æĹ©'] +['æĬĹåĩ»', 'çĸ«æĥħ'] +['åĩ', 'Ľ'] +['交', 'åıĭ'] +['éĶĢåĶ®', 'æ¸łéģĵ'] +['毫ä¸į', 'çĬ¹è±«'] +['èIJ¥', 'åľ°'] +['çłĶç©¶', '表æĺİ'] +['é±¼', 'ç±»'] +['æį¢', 'å±Ĭ'] +['æİ¡', 'åıĸ'] +['çī', 'Ĩ'] +['缼', 'å¼Ģ'] +['æ²§', 'æ¡ij'] +['åºŃ', '审'] +['ç»ı', 'æŁ¥'] +['åĬł', 'å¼·'] +['缸æ¯Ķ', 'äºİ'] +['ä¸ĵ', 'çıŃ'] +['ä½ĵ', 'åŀĭ'] +['被', '害'] +['被害', '人'] +['æĶ¶', '款'] +['åħ·æľī', 'èī¯å¥½'] +['é«ĺå³°', 'æľŁ'] +['åģı', 'ä½İ'] +['åĦ', 'Ł'] +['åĨľä¸ļ', 'ç§ijæĬĢ'] +['ç®Ĭ', 'æĥħåĨµ'] +['å¦Ĥæŀľ', 'çݩ家'] +['éķ¿', '约'] +['第åħŃ', 'å±Ĭ'] +['åħ¬å¼Ģ', 'æĭĽèģĺ'] +['åĪĩ', 'æĸŃ'] +['è¿«', '使'] +['çĸĹ', 'ç¨ĭ'] +['第äºĮ', 'ç§į'] +['ä¸į', 'åħį'] +['å¹²', 'èѦ'] +['çŁ³', '榴'] +['åĹ', '£'] +['两', 'ç±»'] +['çε', '士'] +['åŁİ乡', 'å±ħæ°ij'] +['æŃ¤', '项'] +['缴', 'è¾ĸ'] +['缴è¾ĸ', 'å¸Ĥ'] +['åij¼', 'åºĶ'] +['éĴ', '¯'] +['ç¦ı', 'å¾·'] +['æľº', '身'] +['æĵį', 'åľº'] +['æ¿Ĵ', '临'] +['人群', 'ä¸Ń'] +['èĤ¡', 'æ°ij'] +['åŃ', '½'] +['æ³ķ', 'åħ°'] +['é¨', 'İ'] +['糯', 'ç±³'] +['æĢ»', 'çļĦ'] +['æĢ»çļĦ', 'æĿ¥è¯´'] +['åħ¸', 'éĽħ'] +['æĸ°', 'éĻĪ'] +['æĸ°éĻĪ', '代谢'] +['缮', 'çĿ¹'] +['é¢Ħ', 'è¨Ģ'] +['è·Į', 'çł´'] +['æĸ°', 'ç¯ĩ竳'] +['æ¯Ĵ', 'æĢ§'] +['åĸĿ', 'èĮ¶'] +['æŁ¥', 'èİ·'] +['亮', '丽'] +['çĶŁäº§', 'åķĨ'] +['æĶ¹', 'æĪIJ'] +['为äºĨ', 'æĽ´å¥½'] +['æ·±', '交'] +['深交', 'æīĢ'] +['æİ', 'ĥ'] +['ä¹Ļ', 'èĤĿ'] +['泸', 'å·ŀ'] +['åħĪè¿Ľ', 'æĬĢæľ¯'] +['è¾ĵ', 'ç»Ļ'] +['æķ£', 'æĪ·'] +['æĢĿç»´', 'æĸ¹å¼ı'] +['åºĹ', '主'] +['è°ĭ', 'æ±Ĥ'] +['游æĪı', 'æĬĢå·§'] +['ä¸Ģå¹´', '级'] +['çľ¼', 'è§Ĵ'] +['ä¸Ńä»ĭ', 'æľºæŀĦ'] +['å·§', 'åIJĪ'] +['éĺ²', 'çĽĹ'] +['导', 'è´Ń'] +['æĪ', 'Ĭ'] +['æĽ´', 'éĢĤåIJĪ'] +['åŁºæľ¬', 'ä¿¡æģ¯'] +['马', 'ä¸ģ'] +['åħ»æ®ĸ', 'åľº'] +['åıį', 'è¿ĩæĿ¥'] +['æİ¨', 'å´ĩ'] +['å¯ĨåĪĩ', 'åħ³æ³¨'] +['åŁºéĩij', 'ç»ıçIJĨ'] +['æĮī', 'éĶ®'] +['åĨħéĥ¨', 'æİ§åζ'] +['æĪIJåijĺ', 'åįķä½į'] +['æľ¯', 'è¯Ń'] +['åζ', 'æľį'] +['åĪļ', 'éľĢ'] +['æ£Ģ', 'ç´¢'] +['大大', 'æıIJé«ĺ'] +['åģ¥åº·', '管çIJĨ'] +['èĩª', 'æŃ¤'] +['客æĪ·', 'éľĢæ±Ĥ'] +['丰', 'èĥ¸'] +['èµ·', 'éĩį'] +['èµ·éĩį', 'æľº'] +['æ¬ł', '缺'] +['æ¡Ī', 'åŃIJ'] +['æĥħ人', 'èĬĤ'] +['åħļ', 'æł¡'] +['è¢', 'ľ'] +['该', 'åī§'] +['迷失', 'ä¼łå¥ĩ'] +['ç»ļ', '丽'] +['åķ', 'ª'] +['æĹł', 'ç§ģ'] +['é̲', 'ä¸ĢæŃ¥'] +['第ä¸Ģ', '竳'] +['åύ', 'åħ·'] +['åĨľ', 'èµĦ'] +['確', '實'] +['åºı', 'åĪĹ'] +['娱ä¹IJ', 'å¹³åı°'] +['èŀįèµĦ', 'ç§Łèµģ'] +['èµĦæºIJ', 'åħ±äº«'] +['èģ½', 'åΰ'] +['æIJŀ', 'å¾Ĺ'] +['ç»§ç»Ń', 'ä¿ĿæĮģ'] +['åIJ¯', 'èĴĻ'] +['çľ', 'º'] +['ä¸Ŀ', 'è·¯'] +['设æĸ½', '建设'] +['æİ¥', 'åľ°'] +['æİ¥åľ°', 'æ°Ķ'] +['第ä¸ī', 'åŃ£åº¦'] +['åŁº', 'è°ĥ'] +['åıij', 'éŁ³'] +['社ä¼ļ', 'èµĦæľ¬'] +['éĽĩ', '主'] +['è¿ŀ', 'èĥľ'] +['没', 'åķ¥'] +['å»', '¢'] +['èµ¶', 'èµ´'] +['æ¼Ķ', 'åĮĸ'] +['åı¤', 'æĢª'] +['çİĭ', 'çĪ·'] +['é¢Ħ', 'åħĪ'] +['å¼Ģ', 'åħ·'] +['åĽŀ', 'é¦ĸ'] +['åľ°ä¸ĭ', 'æ°´'] +['å°ıç¼ĸ', 'ä¸Ģèµ·'] +['èµİ', 'åĽŀ'] +['åľ°', 'è²Į'] +['åĪĿ', 'ä¸ī'] +['åı¯', 'ç͍äºİ'] +['éģĹ', '迹'] +['è¿Ļ', 'æī¹'] +['èĸª', 'æ°´'] +['å¿ħçĦ¶', 'ä¼ļ'] +['æ²', '½'] +['éį', 'ĭ'] +['第ä¸Ģ', 'éĥ¨'] +['åĪĬ', 'çī©'] +['å®ŀ', 'ä¾ĭ'] +['æ¸ħ', 'åĩĢ'] +['ä¸Ĭ', 'èµĽåŃ£'] +['åĽ¾', '表'] +['éĤ®', 'è½®'] +['åĵª', '裡'] +['缸', 'è§ģ'] +['æī°', 'ä¹±'] +['æ¯ı', 'æ¯ı'] +['è¿Ļ', 'è¾ĪåŃIJ'] +['ç¡«', 'éħ¸'] +['äºī', '缸'] +['溯', 'æºIJ'] +['åĩº', 'ä¼Ĺ'] +['çİī', 'çŁ³'] +['åħ±', 'çĶŁ'] +['æĹ¶éĹ´', '段'] +['éĩįè¦ģ', 'æĮĩ示'] +['æ¶Īè´¹', 'éľĢæ±Ĥ'] +['éķ¿', 'éķ¿'] +['éķ¿éķ¿', 'çļĦ'] +['å®ī', 'æĬļ'] +['å¢ŀ', 'é«ĺ'] +['æľ¬', 'è½®'] +['亲', 'çľ¼'] +['é£İ', 'æ³¢'] +['èĢģ', 'å¦Ī'] +['æĶ¶è´¹', 'æłĩåĩĨ'] +['åĨħ', 'éĻĨ'] +['æĮ¥', 'åıij'] +['åįĩ', 'åѦ'] +['èĥ¸', 'åīį'] +['åģı', 'è¿ľ'] +['纯', 'æ´ģ'] +['æĸ½å·¥', 'åįķä½į'] +['身', 'ä»·'] +['è´¢', 'åĬĽ'] +['çº', '¶'] +['è£ħ', 'çͲ'] +['æĺ¾ç¤º', 'åύ'] +['毫', 'åįĩ'] +['æ·±', 'çŁ¥'] +['è̶', 'ç©'] +['è̶ç©', 'Į'] +['è¾ĥ', 'éĩı'] +['åľ¨', 'è¿ĩ渡'] +['åľ¨è¿ĩ渡', 'æľŁ'] +['èĮ', 'Ĺ'] +['ä¸Ģ个', 'æĺŁæľŁ'] +['èĬ', '·'] +['è´¿', 'èµĤ'] +['æ¿', 'ķ'] +['æĩĤ', 'äºĭ'] +['ç§', '§'] +['åħħ', 'å½ĵ'] +['åĽ½', 'ç«ĭ'] +['èĬ±', 'çĵ£'] +['éĤĦ', 'è¦ģ'] +['åħ¬', 'åľĴ'] +['触', 'åĬ¨'] +['æ³°', 'å·ŀ'] +['ä»Ģä¹Ī', 'æł·'] +['æ»ĭ', 'åħ»'] +['è¯Ħ', 'åΤ'] +['æĮ¥', 'æīĭ'] +['èĦ', 'Ī'] +['å§¥', 'å§¥'] +['è¿IJ', 'è´¹'] +['æ¯ħ', 'åĬĽ'] +['å¿ĥ', 'æĻº'] +['ä¸į', 'æİĴéϤ'] +['第ä¸ī', '代'] +['éĢĢ', 'è´§'] +['æĺŁ', 'éĻħ'] +['æ°¸', 'åĪ©'] +['æĬ¤', 'åį«'] +['çıŃ', '车'] +['è¨Ģ', 'è¡Į'] +['ç¹', 'ª'] +['主åĬ¨', 'æĢ§'] +['å·¥ç¨ĭ', 'è´¨éĩı'] +['éĥĬ', 'åĮº'] +['ä¸Ģ', 'æłĭ'] +['ä½Ĩ', 'å®ŀéĻħä¸Ĭ'] +['ä¸ī大', 'èģĮä¸ļ'] +['åij¼', 'åı«'] +['女', 'åħĴ'] +['è¯ģåΏ', 'æĬķèµĦ'] +['èĢĥ', 'æħ®'] +['çĤ«', 'èĢĢ'] +['æ²»', '好'] +['åĺ', '¶'] +['èĥ', '¤'] +['åħīä¼ı', 'åıijç͵'] +['åĩł', 'æŃ¥'] +['æīĢ', 'æīĢ'] +['æīĢæīĢ', 'éķ¿'] +['çħ§', 'æł·'] +['åĵ¥', '们'] +['è¯', 'Ľ'] +['è¿Ļä¸Ģ', 'åĪ»'] +['çŁ¿', 'çī©è´¨'] +['ä¸įå¾Ĺ', 'å·²'] +['åIJĮ', '缣'] +['ç»Ĩ', 'å¾®'] +['è·¯', 'èĻİ'] +['çϾ', 'èĬ±'] +['æ··', 'æ²Į'] +['ä¸Ĭæµ·', 'è¯ģåΏ'] +['éĢĢ', 'ç¨İ'] +['èµŀ', 'åı¹'] +['æī®æ¼Ķ', '游æĪı'] +['åIJį', 'åĪĹ'] +['åIJįåĪĹ', 'åīį'] +['åIJįåĪĹåīį', 'èĮħ'] +['ç±³', 'å°Ķ'] +['ä»Ģä¹Ī', 'åİŁåĽł'] +['å®īåħ¨', 'ä¿Ŀéļľ'] +['ä¸Ģåıª', 'æīĭ'] +['ä¹³', 'ä¸ļ'] +['ä¸į', 'çĶĺ'] +['æĥħ', 'åķĨ'] +['æĮ¡', 'ä½ı'] +['åİŁåĽł', 'ä¹ĭä¸Ģ'] +['è¿Ļ', '两天'] +['çĥĺ', 'çĦĻ'] +['è±', '¬'] +['ä½ł', '以为'] +['没', 'è§ģè¿ĩ'] +['åĵªå®¶', '好'] +['åīį', 'ä»»'] +['è¿Ľ', 'è´§'] +['éĢĢ', 'åĽŀ'] +['串', 'èģĶ'] +['èĩ³', 'æĸ¼'] +['åĨ°', 'æ·ĩ'] +['åĨ°æ·ĩ', 'æ·ĭ'] +['æŁ¥çľĭ', '详æĥħ'] +['çı¾', '實'] +['æİ¨', 'æµĭ'] +['æİ¥', 'æīĭ'] +['éļ¶', 'å±ŀäºİ'] +['åŁİå¸Ĥ', '群'] +['æĿİ', 'åħĪçĶŁ'] +['çŁ¿', 'æ³īæ°´'] +['çī¹', 'ä»·'] +['æĽ´å¤ļ', '精彩'] +['ç¨ĭ', 'å¼ı'] +['读', 'æĩĤ'] +['å±ı', 'èͽ'] +['奥', 'æŀĹ'] +['奥æŀĹ', 'åĮ¹'] +['奥æŀĹåĮ¹', 'åħĭ'] +['红', 'èĸ¯'] +['å¥', '®'] +['å®Ŀ', 'çİī'] +['ç¶²', '絡'] +['è²', '§'] +['欧', 'å¼ı'] +['çϽ', 'ç³ĸ'] +['èĩªçĦ¶', 'çģ¾å®³'] +['åijĬè¯ī', '她'] +['å»', 'ļ'] +['çĤ¹åĩ»', 'æŁ¥çľĭ'] +['é£İ', '湿'] +['èµĦ产', 'éĩįç»Ħ'] +['ä¹Łä¸į', 'ä¾ĭå¤ĸ'] +['åįĬ', '个å°ıæĹ¶'] +['åIJ¸å¼ķ', 'æĽ´å¤ļ'] +['æĹ¶éĹ´', 'èĬĤçĤ¹'] +['æĶ¶', '纳'] +['åIJ¸', 'æ¯Ĵ'] +['èĢģ', '乡'] +['çIJ', 'ħ'] +['æľĢ', 'çµĤ'] +['åıį', 'æĦŁ'] +['ç͍', '微信'] +['çĶ¨å¾®ä¿¡', 'æī«'] +['éĢŁ', 'çİĩ'] +['大', 'çĨĬçĮ«'] +['åı¯', 'æĥ³'] +['åı¯æĥ³', 'èĢĮ'] +['åı¯æĥ³èĢĮ', 'çŁ¥'] +['åĴ', '§'] +['èµ°', 'åħ¥'] +['碳', 'éħ¸'] +['èĮĥ', 'åĨ°'] +['èĮĥåĨ°', 'åĨ°'] +['被', 'åΤ'] +['积æŀģ', 'æİ¨åĬ¨'] +['è¶³', 'è¶³'] +['ç²Ĵ', 'åŃIJ'] +['大', 'å®Ĺ'] +['大å®Ĺ', 'åķĨåĵģ'] +['ç½ij绾', 'ç§ijæĬĢ'] +['æĽ¼', 'åŁİ'] +['å·²', 'ä¹ħ'] +['å·²ä¹ħ', 'çļĦ'] +['秦', 'çļĩ'] +['秦çļĩ', 'å²Ľ'] +['ä»»', 'æķĻ'] +['å͝', 'ç¾İ'] +['æ·¡', 'åĮĸ'] +['æ¡Ĥ', 'èĬ±'] +['çŁ¥è¯Ĩ', 'åĪĨåŃIJ'] +['æĩĴ', 'å¾Ĺ'] +['主', 'åħ¬'] +['设计', 'çIJĨ念'] +['è³', 'º'] +['æīĢ', 'æıIJä¾Ľ'] +['æīĢæıIJä¾Ľ', 'ä¹ĭ'] +['æĶ»', 'åħĭ'] +['åĤ', '¾'] +['è¯Ń', 'æ³ķ'] +['åįĥ', 'åı¤'] +['éĸĭ', 'æĶ¾'] +['第ä¸Ģ', 'èĬĤ'] +['éĤĦ', 'æ²Ĵ'] +['éĢĥ', 'çĶŁ'] +['æ³', 'Ĺ'] +['åİ¿', 'å§Ķ书记'] +['ä½ľèĢħ', 'æīĢæľī'] +['çħ', '½'] +['ç»', 'ħ'] +['æł', 'ħ'] +['æľ´', 'ç´ł'] +['çijķ', 'çĸµ'] +['åĮħ', 'åĮħ'] +['æ°ij主', 'åħļ'] +['ä¸į', 'è¿ľå¤Ħ'] +['å¥ĩ', 'å¼Ĥ'] +['åĺ»', 'åĺ»'] +['æī', '¼'] +['ç¿»', 'å¼Ģ'] +['æĢİ', 'èĥ½'] +['éģ´', 'éĢī'] +['è§£', 'éĩĭ'] +['å¹¼', 'ç¨ļ'] +['è¦ģ', '好好'] +['è¶´', 'åľ¨'] +['ç´¢', 'åıĸ'] +['ç»Ī', 'çĶŁ'] +['åħ¨', 'æµģç¨ĭ'] +['éģ©', 'çķ¶'] +['åįıè°ĥ', 'åıijå±ķ'] +['æĬ¥', 'ä»ĩ'] +['ç§ijæĬĢ', 'åĽŃ'] +['ä»Ģä¹Ī', 'éĥ½ä¸į'] +['æľĢåIJİ', 'ä¸Ģ次'] +['ç»Ļ人', 'ä¸Ģç§į'] +['æł¸', 'å®ļ'] +['被', 'åĪĹåħ¥'] +['æĦı', 'æĥ³ä¸įåΰ'] +['èĢĥ', 'æŁ¥'] +['åľ¨æŃ¤', 'ä¹ĭåīį'] +['æīĵ', 'çIJĥ'] +['è¶ĬæĿ¥è¶Ĭ', 'å°ij'] +['å®ļ', 'å¾ĭ'] +['è¡ĮæĶ¿', 'æľºåħ³'] +['ä½ıæĪ¿', 'åħ¬ç§¯'] +['å°ıå§IJ', 'å§IJ'] +['ä¸ī', 'èı±'] +['ä¿®', 'è¡¥'] +['èŀĥ', 'èŁ¹'] +['西', 'çͲ'] +['æĢ', 'ł'] +['çŃī', 'å¤ļ项'] +['产ä¸ļ', 'éĽĨèģļ'] +['ä»·æł¼', 'ä¸Ĭ涨'] +['åħ¬åħ±', 'åľºæīĢ'] +['è¢ĭ', 'åŃIJ'] +['æĨ§', 'æĨ¬'] +['çļĦæĸ¹å¼ı', 'æĿ¥'] +['åΰ', 'è´¦'] +['çģ', '½'] +['å·´', 'èı²'] +['å·´èı²', 'çī¹'] +['æ¼Ķ', 'ä¹ł'] +['èŃ¦ç¤º', 'æķĻèĤ²'] +['çķı', 'æĥ§'] +['å¼ķ', 'æµģ'] +['æĶ¶', 'æĶ¯'] +['å±Ĥ', 'åĩº'] +['å±Ĥåĩº', 'ä¸į'] +['å±Ĥåĩºä¸į', 'ç©·'] +['æijĩ', 'æ»ļ'] +['辦', 'çIJĨ'] +['纵', 'è§Ĥ'] +['æķij', 'æµİ'] +['å®¶', 'éĥ½çŁ¥éģĵ'] +['åĮ', '¯'] +['å°ı', '鸣'] +['ä»»', 'åĭĻ'] +['计', 'åħ¥'] +['ç«ŀ', 'éĢī'] +['å¼ĢèįĴ', 'æĹ¶æľŁ'] +['åij¨', 'æģ©'] +['åij¨æģ©', 'æĿ¥'] +['交', 'ç»ĩ'] +['çķ¢', 'æ¥Ń'] +['æł¹æį®', 'èĩªå·±'] +['æĸ°äºº', 'çݩ家'] +['åѵåĮĸ', 'åύ'] +['éĩĩ', 'æļĸ'] +['å¹³åĿĩ', 'æ°´å¹³'] +['åħ¬å¼Ģ', '课'] +['失', 'åĪ©'] +['伺', 'æľį'] +['çĬ', 'ģ'] +['忽', 'æĤł'] +['主è¦ģ', 'éĽĨä¸Ń'] +['æ¤į', 'æłij'] +['æ¯Ĺ', 'éĤ»'] +['èĩº', 'çģ£'] +['åĩºåĽ½', 'çķĻåѦ'] +['æĬĹ', 'éľĩ'] +['æĥ©', 'æĪĴ'] +['å¹´åºķ', 'åīį'] +['åĴ¸', 'éĺ³'] +['æ°ij', 'å±ħ'] +['大çIJĨ', 'çŁ³'] +['éĿ', '³'] +['éķ', 'ĸ'] +['æ¸ħ', 'è¿ľ'] +['è£ħ', 'è½½'] +['èĩ', 'Ģ'] +['å½±', 'ä¸ļ'] +['å¼Ł', 'åħĦ'] +['æĤ²', 'è§Ĥ'] +['çĿĢçľ¼', 'äºİ'] +['æįį', 'åį«'] +['åī¥', '夺'] +['ç¯', 'Ĩ'] +['å¾Ī', 'éķ¿æĹ¶éĹ´'] +['è¥', 'Ł'] +['第ä¸Ģ', 'çϾ'] +['ä¸ĢåĪĨ', 'éĴ±'] +['æĸ°éĹ»', 'è®°èĢħ'] +['éķ·', 'æľŁ'] +['æ³ķ', 'æĪĺç»ĦåIJĪ'] +['è°ģ', 'çŁ¥éģĵ'] +['èħ°', 'éĥ¨'] +['æ±ī', 'åł¡'] +['åħ¥', 'çĿ¡'] +['åįĸ', 'æİī'] +['æ¶Īè²»', 'èĢħ'] +['æĥ¯', 'ä¾ĭ'] +['æĥ³', 'äºĨ'] +['æĥ³äºĨ', 'æĥ³'] +['èĢģæĹ§', 'å°ıåĮº'] +['ä¼ł', 'è¨Ģ'] +['åĪĨæķ°', '线'] +['æµģ', '泪'] +['ç»Ħç»ĩ', 'é¢Ĩ导'] +['äºļ', 'åĨĽ'] +['å¢ŀå̼', 'æľįåĬ¡'] +['å¾', '¹'] +['ä¼', '¶'] +['äºĽ', '许'] +['å¸ĥ', 'èݱ'] +['强', 'æĤį'] +['宫', 'å»·'] +['绿', 'èĮ¶'] +['åĮ', '¡'] +['å¾Ī', 'æŃ£å¸¸'] +['æĺ¥', 'å¤ı'] +['æ¯', 'Ļ'] +['è¯Ħ', 'æ¯Ķ'] +['åĩ¡', 'äºĭ'] +['æĬī', 'æĭ©'] +['åĢĴ', 'éľī'] +['éĩį', '度'] +['åįıä¼ļ', 'ä¼ļéķ¿'] +['å¿§', 'èĻij'] +['ä¸ĭ', 'ä¸Ģç¯ĩ'] +['沪', 'æ·±'] +['æĪ', 'İ'] +['æīĵ', 'ä»Ĺ'] +['åįĪ', 'é¥Ń'] +['å¹´é¾Ħ', '段'] +['ä¸ŃåĽ½', 'è¶³çIJĥ'] +['设计', 'æĸ¹æ¡Ī'] +['åºĶç͍', 'æŁ¥çľĭ'] +['é¢Ħ', 'æĸĻ'] +['åĹ', '¡'] +['ç¥ĸ', 'çζ'] +['çļĦä¸Ģ', 'åijĺ'] +['æ´Ĺ', 'å¹²åĩĢ'] +['åİĨåı²', 'æĸ°'] +['åİĨåı²æĸ°', 'é«ĺ'] +['çĭ¬', 'åħ·'] +['æħĭ', '度'] +['æīĵ', '交'] +['æīĵ交', 'éģĵ'] +['é»Ħ', 'çŁ³'] +['çĽ¼', 'æľĽ'] +['çī§', 'åľº'] +['转', '弯'] +['åįĩ', 'åįİ'] +['åĨį', 'ä¹Łæ²¡æľī'] +['èĭ±', 'æīį'] +['æĽ´', 'åIJį为'] +['åĢŁ', 'ç͍'] +['çºł', 'éĶĻ'] +['ç»Ŀ对', 'ä¸įä¼ļ'] +['çİĭ', 'çīĮ'] +['çĽĨ', 'åľ°'] +['失', 'è°ĥ'] +['好', '象'] +['é³', '¥'] +['ä¿Ŀ', 'ä¿®'] +['åĽĽä¸ª', 'èĩªä¿¡'] +['头', 'çļ®'] +['åİŁ', 'åīĩ'] +['æĬ¥', 'æ¡Ī'] +['奴', 'éļ¶'] +['å³', 'Ļ'] +['è°ĥ', 'æĸĻ'] +['ä¹Ł', '許'] +['èIJ½', 'åΰ'] +['èIJ½åΰ', 'å®ŀ'] +['èIJ½åΰå®ŀ', 'å¤Ħ'] +['çĦļ', 'çĥ§'] +['çĶŁæ´»', 'çݯå¢ĥ'] +['åºĶ', 'åıĬæĹ¶'] +['è¶Ĭ', 'è¿ĩ'] +['æĦŁ', 'è¬Ŀ'] +['æĻ¯', 'å¾·'] +['æĻ¯å¾·', 'éķĩ'] +['çĬ', 'Ģ'] +['身', 'éĤĬ'] +['ç¨İåĬ¡', 'æĢ»å±Ģ'] +['åĩĢ', 'åľŁ'] +['ä¾µ', 'åįł'] +['åĬ¨', 'å·¥'] +['å¹´', 'ä¹ĭ'] +['å¹´ä¹ĭ', 'ä¹ħ'] +['第äºĮ', 'èĬĤ'] +['åĬ¨çī©', 'åĽŃ'] +['第ä¸Ģ', '书记'] +['éħ', 'ļ'] +['çĶŁäº§', '设å¤ĩ'] +['æŁIJç§į', 'ç¨ĭ度'] +['åľ', 'Ń'] +['åĩŃåĢŁ', 'çĿĢ'] +['éĺħ', 'è§Ī'] +['çϽ', 'æ²Ļ'] +['æ²¹', 'çĥŁ'] +['çªģçł´', 'åı£'] +['åıĹ', 'å½±åĵį'] +['åı¯ä»¥', 'æĽ´å¥½'] +['å³°', 'å̼'] +['æĿĤ', 'è´¨'] +['宿', 'è¿ģ'] +['çĽĺ', 'æ´»'] +['æ¿Ģ', 'èµ·'] +['åĦ¿', 'ç§ij'] +['åĿIJ', 'èIJ½åľ¨'] +['æĮª', 'å¨ģ'] +['æµ·', 'å²Ľ'] +['绣', '绣'] +['éĻ', '¨'] +['ä¼ĺ', 'äºİ'] +['å°Ī', 'å®¶'] +['ä¸Ģ', 'éĤĬ'] +['èIJ', 'Ĭ'] +['äºĨä¸Ģ', 'åı£'] +['æ²ĥå°Ķ', 'æ²ĥ'] +['æŃ£å¸¸', '使ç͍'] +['æĻ®éģį', 'åŃĺåľ¨'] +['丰', '满'] +['çĶ»', 'åį·'] +['åºĶ', 'æĶ¶'] +['åºĶæĶ¶', 'è´¦'] +['åºĶæĶ¶è´¦', '款'] +['å®Įæķ´', 'çĥŃ'] +['å®Įæķ´çĥŃ', 'æ¦ľ'] +['注', 'è§Ĩ'] +['çĨ', 'Ħ'] +['èº', '¬'] +['éĶĢåĶ®', '人åijĺ'] +['è¶ĭ', 'åIJij'] +['çĦ¦', 'æĢ¥'] +['åįģå¹´', 'åīį'] +['ä¼łç»Ł', '产ä¸ļ'] +['質', 'éĩı'] +['åĩ¤åĩ°', 'ç½ij'] +['èµĦæºIJ', 'æķ´åIJĪ'] +['æ¶Į', 'åħ¥'] +['æĸĩåĮĸ', 'ä¼łæĴŃ'] +['çķĮ', '第ä¸Ģ'] +['æ°´', 'æ³µ'] +['宫', '殿'] +['æİ¢', '寻'] +['ä¿®', 'åīª'] +['æĦı', 'è¦ĭ'] +['ç´Ĭ', 'ä¹±'] +['æĽ', 'ī'] +['çϽ', 'è¡£'] +['èĻİ', 'åį«'] +['ç´§', 'æī£'] +['å¤Ħå¤Ħ', 'éķ¿'] +['åĪĽå»º', 'å·¥ä½ľ'] +['红', 'æŀ£'] +['饼', 'å¹²'] +['äºĨ', 'åįĬ天'] +['ä¼ļå½±åĵį', 'åΰ'] +['çĽ¸ä¿¡', '大家'] +['èħ¾', 'é£ŀ'] +['å°±', 'å¦ĤåIJĮ'] +['ä¸ĭéĿ¢', 'å°ıç¼ĸ'] +['æ°ijèIJ¥', 'ç»ıæµİ'] +['æĻ', '¦'] +['è£ħ', 'æī®'] +['é»ij', 'å¤ľ'] +['常', 'å¾·'] +['å·¥ä¸ļ', '大åѦ'] +['æĺİ', 'çŁ¥'] +['éĺŁåijĺ', '们'] +['åIJ¬', '课'] +['æ¯ı', 'éļĶ'] +['羣æĺ¯', '太'] +['åIJĪä½ľ', 'åħ±èµ¢'] +['çIJĨ', 'åıij'] +['æīį', 'å¹²'] +['çľĭ', 'èµ·ä¾Ĩ'] +['殿', 'ä¸ĭ'] +['å®ī', 'éĺ³'] +['æīĢ', '产çĶŁçļĦ'] +['éĽĩ', 'ä½£'] +['æĬ¬èµ·', '头'] +['æį®', 'æĬ¥éģĵ'] +['éļĨéĩį', '举è¡Į'] +['交', 'éĶĻ'] +['è¶ħ', 'é¢Ŀ'] +['åĮĸ', 'çĸĹ'] +['é¡', 'Ĩ'] +['纵', 'æ·±'] +['çĪ±åĽ½', '主ä¹ī'] +['éĻ¢', 'åī¯éĻ¢éķ¿'] +['è®', '³'] +['羣æŃ£', 'åģļåΰ'] +['åѤ', 'åįķ'] +['èĩªçĦ¶', 'èĢĮ'] +['èĩªçĦ¶èĢĮ', 'çĦ¶'] +['ä¿®', '身'] +['èĬ', '¹'] +['æģ¯', 'æģ¯'] +['æģ¯æģ¯', '缸åħ³'] +['驾', 'æł¡'] +['æİ©', '饰'] +['æ³½', 'è¿ŀ'] +['æ³½è¿ŀ', 'æĸ¯åŁº'] +['举', 'æŃ¢'] +['管çIJĨ', 'ä½ĵåζ'] +['åħ¶ä¸Ń', 'ä¹ĭä¸Ģ'] +['æĿ¾', 'å¼Ľ'] +['æĭ¦', 'æĪª'] +['åį«', 'åģ¥'] +['åį«åģ¥', 'å§Ķ'] +['ä»İ', 'åݻ年'] +['åĤ', '¢'] +['è´Ń', '票'] +['åĽ¾', 'æłĩ'] +['æ²³', '西'] +['æ°ijæĶ¿', 'å±Ģ'] +['ç§ģ', 'èIJ¥'] +['å¤ĸåĽ½', 'è¯Ń'] +['å¹²', 'è´§'] +['æĵ¦', 'æĭŃ'] +['åľ°', 'ä¸Ń'] +['åľ°ä¸Ń', 'æµ·'] +['æµĵ', 'æµĵ'] +['æµĵæµĵ', 'çļĦ'] +['å§ĭ', '建'] +['å§ĭ建', 'äºİ'] +['ç¶ĵ', 'æŃ·'] +['è·¯', 'æ¼Ķ'] +['æļ´', 'é£İ'] +['åŁº', 'è¾ħ'] +['æī¶è´«', 'å·¥ä½ľ'] +['ä¸Ģ缴', 'å¤Ħäºİ'] +['æĥħ', 'è¶£'] +['äºĮ', 'åŃ£åº¦'] +['åİĮ', 'æģ¶'] +['顺åĪ©', 'å®ĮæĪIJ'] +['æŁ¥', 'å°ģ'] +['é¡¶', '端'] +['ä¸į', 'åŃķ'] +['ä¸Ģ大', 'åłĨ'] +['被', 'æ·ĺæ±°'] +['æĺ¯', 'ç͍æĿ¥'] +['æľĢ', 'åIJĪéĢĤ'] +['亮', 'çľ¼'] +['å¹¶ä¸įæĺ¯', 'å¾Ī'] +['ç§ijçłĶ', 'éĻ¢'] +['ç§ijçłĶéĻ¢', 'æīĢ'] +['ç²', 'Ł'] +['é¢Ī', 'éĥ¨'] +['é»ĺé»ĺ', 'åľ°'] +['é«ĺä¸Ń', 'çĶŁ'] +['æĹıèĩªæ²»', 'åİ¿'] +['æķĻåѦ', 'è´¨éĩı'] +['æĪĺ', 'çģ«'] +['åĿİ', 'åĿ·'] +['æIJŃ', 'ä¹ĺ'] +['è¯Ĺ', 'æĦı'] +['åĪij', 'èѦ'] +['åĩº', 'æ±Ĺ'] +['åįģåħŃ', 'æĿ¡'] +['请', 'åıĬæĹ¶'] +['åĨľä¸ļ', '大åѦ'] +['èIJ½', 'åı¶'] +['æĢ»', 'èĢĮè¨Ģ'] +['æĢ»èĢĮè¨Ģ', 'ä¹ĭ'] +['æĿľ', 'åħ°'] +['æĿľåħ°', 'çī¹'] +['éĻª', 'ä½ł'] +['åħ¬', 'æĬ¥'] +['çķĻè¨Ģ', 'æĿ¿'] +['éĺħ', 'åİĨ'] +['ç«¶', 'çĪŃ'] +['ç»Ļ', 'åĪ«äºº'] +['æĹ¥æĬ¥', '社'] +['åĿIJ', 'èIJ½'] +['åĿIJèIJ½', 'äºİ'] +['éĩij', 'åŃĹ'] +['éĩijåŃĹ', 'å¡Ķ'] +['åĽ', '¤'] +['è¯Ŀ', 'åī§'] +['æĮģç»Ń', 'æİ¨è¿Ľ'] +['æ¼ı', 'æ°´'] +['詳', 'ç´°'] +['æĢĢ', 'æĬ±'] +['åıĺ', 'å¹»'] +['饥', '饿'] +['éļIJ', '身'] +['个', 'èµĽåŃ£'] +['åĵ¡', 'å·¥'] +['æģ¢å¤į', 'æŃ£å¸¸'] +['äºĨ', '好å¤ļ'] +['æĺŁ', 'å·´'] +['æĺŁå·´', 'åħĭ'] +['åħī', 'çݯ'] +['å¸ħ', 'åĵ¥'] +['çϽ', 'éĽª'] +['ç¨į', 'ç¨į'] +['计', 'æıIJ'] +['æĦĽ', 'æĥħ'] +['éİ', 'ĸ'] +['ä¿¡', 'éĺ³'] +['è§Ģ', 'å¯Ł'] +['å¦Ĥæŀľä½ł', 'æĥ³'] +['缸æ¯Ķ', 'ä¹ĭä¸ĭ'] +['è§£', 'å¼Ģ'] +['æīĵåį°', 'æľº'] +['身', '躯'] +['ç²¾ç¥ŀ', 'æĸĩæĺİ'] +['èĤ¡', 'æĮĩ'] +['å¾®', 'åĪĽ'] +['红', 'èĮ¶'] +['èĩ´', 'çĻĮ'] +['æģ©', 'æĸ½'] +['èħ¿', 'éĥ¨'] +['大åŀĭ', 'å¤ļ人'] +['å®ī', 'åĢį'] +['è¾ħ导', 'åijĺ'] +['èĪª', 'éģĵ'] +['å¸ĥ', 'å°Ķ'] +['åįĹå®ģ', 'å¸Ĥ'] +['ä¸ĬçıŃ', 'æĹı'] +['ä¾§', 'ç»ĵæŀĦæĢ§'] +['追', 'éļı'] +['å½ĵåľ°', 'æĶ¿åºľ'] +['èµ°', 'åĩºæĿ¥'] +['éĩijèŀį', 'ä¸ļ'] +['丼', '书'] +['é¡¹çĽ®', 'ç»ıçIJĨ'] +['è¿ĩ', 'æĪ·'] +['骨', 'æŀ¶'] +['è¡', 'Ļ'] +['ä»Ģ', '麽'] +['èħ', 'ĭ'] +['è¦ģ', '害'] +['åľ¨', 'åºĬä¸Ĭ'] +['代è¨Ģ', '人'] +['並', 'å°ĩ'] +['åIJĦ个', 'æĸ¹éĿ¢'] +['è°´', 'è´£'] +['åħ±', 'æĮ¯'] +['åį³å°Ĩ', 'åΰæĿ¥'] +['èĤº', 'çĻĮ'] +['ä¾Ľ', 'éĶĢ'] +['丼', 'æŀĹ'] +['èµ', 'ĥ'] +['åįģä½Ļ', 'å¹´'] +['åĭĺ', 'æİ¢'] +['飵', 'åij³'] +['èĭ¦', 'ç¬ij'] +['æľĢ大', 'ç¨ĭ度'] +['éĩįçĤ¹', 'åħ³æ³¨'] +['ä¹ĭ', '举'] +['满', 'æĢĢ'] +['åıĹåΰ', 'å½±åĵį'] +['æĭĽ', 'æĬķæłĩ'] +['è¡¥', 'é½IJ'] +['西', '红'] +['西红', 'æŁ¿'] +['é¬', '§'] +['è£ħ', 'åį¸'] +['éĤ»', 'éĩĮ'] +['èĤĩ', 'äºĭ'] +['æİĴ', 'æ¯Ĵ'] +['åѤ', 'åĦ¿'] +['鼶', 'è·Ŀ离'] +['å®ŀ', 'å¹²'] +['çľĭ', 'æŁ¥çľĭ'] +['æĶ¶è´¹', 'ç«Ļ'] +['ç»', '·'] +['åħ¬çĽĬ', 'æĢ§'] +['éĢĴ', 'ç»Ļ'] +['æĶ»', 'æīĵ'] +['æĺŁçº§', 'éħĴåºĹ'] +['æĺİ', 'åªļ'] +['çį¨', 'ç«ĭ'] +['è¯Ŀè¯Ń', 'æĿĥ'] +['ä¸ĢæŃ¥', 'ä¸ĢæŃ¥'] +['书æ³ķ', 'å®¶'] +['æľªç»ı', 'æİĪæĿĥ'] +['çŁ³', 'èĨı'] +['åĩŃ', 'ä»Ģä¹Ī'] +['çļĦ', 'æĹ¥'] +['çļĦæĹ¥', 'åŃIJéĩĮ'] +['诱', '人'] +['çϾåĪĨ', 'çϾ'] +['èĪĪ', 'è¶£'] +['å¼ł', 'åħĪçĶŁ'] +['èĢģçĪ·', 'åŃIJ'] +['æ³¢', 'çī¹'] +['åŁºéĩij', '份é¢Ŀ'] +['æ²Ļåıij', 'ä¸Ĭ'] +['å¥ĭæĸĹ', '缮æłĩ'] +['æ°¢', 'èĥ½'] +['æ²ĥå°Ķ', 'çİĽ'] +['義', 'åĭĻ'] +['éŁ³', 'ç®±'] +['æ²ī', '浸'] +['æ²ī浸', 'åľ¨'] +['èĭ±', 'åľĭ'] +['çģ¯', 'çģ«'] +['è¿Ľ', '项'] +['两', '端'] +['ä¹Ķ', '丹'] +['èĦ¸', 'é¢Ĭ'] +['åıijå±ķ', 'æ½ľåĬĽ'] +['åĭķ', 'ä½ľ'] +['åĵĪ', 'ä½Ľ'] +['å®´', 'ä¼ļ'] +['æ§', 'į'] +['ç«ĭ', 'å¿Ĺ'] +['ç¡ķ士', 'åѦä½į'] +['åĭĭ', '竳'] +['è¿Ļ', 'åľºæ¯ĶèµĽ'] +['æĮģ', 'å¹³'] +['éķĢ', 'éĶĮ'] +['èĭ±', 'çī¹'] +['èĭ±çī¹', 'å°Ķ'] +['æķĻ', 'èģĮå·¥'] +['åĬŁ', 'åĬĽ'] +['该', 'æ¡Ī'] +['ä¸Ģ', 'æ¢Ŀ'] +['åĺī', 'å¹´'] +['åĺīå¹´', 'åįİ'] +['è¿«', 'ä¸įåıĬ'] +['è¿«ä¸įåıĬ', 'å¾ħ'] +['è¿Ļ个', 'æĹ¶ä»£'] +['精彩', 'æĴŃæĬ¥'] +['人', 'èĦ¸'] +['人èĦ¸', 'è¯ĨåĪ«'] +['æ£Ģå¯Ł', 'å®ĺ'] +['å°ı', 'èħ¿'] +['éĨĴ', '缮'] +['åħļ', 'æĢ»'] +['åħļæĢ»', 'æĶ¯'] +['æĪ', 'Ł'] +['èĮ«', 'çĦ¶'] +['è±Ĩ', 'æµĨ'] +['主', 'æ²»'] +['éĿĴæµ·', 'çľģ'] +['åĪijäºĭ', '责任'] +['çł', '°'] +['ä¹ĭ', 'æ¬ĬåĪ©'] +['äºĶ', 'å®ĺ'] +['è¿·', 'æĥij'] +['åħ¥', 'åºĵ'] +['å®¶', '纺'] +['å¼¹', 'ç°§'] +['åįģäºĶ', 'æĿ¡'] +['ç»Ļ', 'å®Ŀå®Ŀ'] +['èĪªç©º', 'èĪªå¤©'] +['å¾Ģ', 'å¤ĸ'] +['å¼ķ', 'åĬĽ'] +['çľ¼', 'çļ®'] +['æ¶ī', 'è¶³'] +['æĿ¥', '宾'] +['åľ¨çº¿', 'è§Ĵèī²'] +['çĥŃ', 'éĶĢ'] +['æµģ', 'éĢĿ'] +['泡', '泡'] +['éĻį', 'å¹ħ'] +['è´ŁéĿ¢', 'å½±åĵį'] +['红', '楼'] +['红楼', '梦'] +['éļĶ', 'çĿĢ'] +['ä¾¥', '幸'] +['许', 'ä¹ħ'] +['åĴĮ', 'çĿ¦'] +['èŃ', '½'] +['使ç͍èĢħ', 'æĪĸ'] +['ä¹°', 'åįķ'] +['è¿', '´'] +['é£İ', 'æīĩ'] +['æķĻ', '師'] +['æ¡ĮåŃIJ', 'ä¸Ĭ'] +['å¾Ī', 'æ¼Ĥ亮'] +['åł±', 'å°İ'] +['第ä¸Ģ', 'åŃ£åº¦'] +['ç©©', 'å®ļ'] +['æĤ²', 'åĵĢ'] +['çĿĢåĬĽ', 'æīĵéĢł'] +['æĮ', 'Ł'] +['è·¯', 'æ¡¥'] +['åij', 'IJ'] +['åľ£è¯ŀ', 'èĬĤ'] +['çļĩ', 'åŃIJ'] +['ä»ĩ', 'æģ¨'] +['éħĿ', 'éħ¿'] +['ä¸į', 'éĹ´'] +['ä¸įéĹ´', 'æĸŃ'] +['æĮĩ', 'å°ĸ'] +['ä¸ŃåĽ½', 'ç½ij游'] +['åŀ', '£'] +['æĦıè§ģ', '建议'] +['æ¯ħ', 'çĦ¶'] +['亮', '度'] +['èģĶ', 'è°Ĭ'] +['å½ķ', 'åħ¥'] +['åĦ', '²'] +['å¨ĺ', 'å®¶'] +['ç§ij', 'å°Ķ'] +['ä¹Łæ²¡', 'ä»Ģä¹Ī'] +['æł¹æį®', 'ä¸įåIJĮ'] +['åı¶', 'ä¿®'] +['å̼', 'å®Ī'] +['æľ«', '端'] +['åĪ', '¨'] +['åĤµ', 'åĭĻ'] +['èģ¯', 'åIJĪ'] +['å¥ĩ', 'å¹»'] +['èĻļ', 'æŀĦ'] +['é»Ħ', 'æĺı'] +['å¹³', 'åĿ¦'] +['æµģ', 'æ°ĵ'] +['æĸ°', 'åŁºå»º'] +['æĮ½', 'æķij'] +['åįİ', 'å°Ķ'] +['åįİå°Ķ', 'è¡Ĺ'] +['æľĢ', 'åıĹæ¬¢è¿İ'] +['ç»Ń', '约'] +['å¼Ĭ', '端'] +['éŃĶ', 'æ³ķå¸Ī'] +['éŃĶæ³ķå¸Ī', 'åĴĮ'] +['åħ·ä½ĵ', 'åĨħ容'] +['çIJī', 'çĴĥ'] +['æī©', '容'] +['èĮ¶', 'åĽŃ'] +['主ä¹ī', 'èĢħ'] +['ç«ĭ', 'éĿ¢'] +['æİ¥åıĹ', 'éĩĩ访'] +['åĩº', 'åħ¥å¢ĥ'] +['ç§ij', 'åįı'] +['éĴ', '³'] +['çµIJ', 'æ§ĭ'] +['ç»ĵæŀľ', 'æĺ¾ç¤º'] +['åı°', 'è´¦'] +['å°±', 'æĿ¥çľĭçľĭ'] +['èĩª', 'æķij'] +['åıį', 'æĩī'] +['åİ»', 'åĵªåĦ¿'] +['è¿Ļ', 'é¦ĸ'] +['è¿Ļé¦ĸ', 'æŃĮ'] +['åIJ¬', 'ä¼Ĺ'] +['å¤ĸ', '壳'] +['ä½ĵèĤ²', 'é¦Ĩ'] +['實', 'æĸ½'] +['èŀº', 'ä¸Ŀ'] +['æĭī', 'åįĩ'] +['çĮĽ', 'åľ°'] +['åħ¨åĽ½', '人æ°ij'] +['æĤī', 'å°¼'] +['æĹı', '群'] +['åĽ¢', 'åijĺ'] +['两个', 'å°ıæĹ¶'] +['åľ¨', 'çݩ家'] +['åľ¨çݩ家', 'ä¸Ń'] +['çĶľ', 'çĶľ'] +['æĬķ', 'è¡Į'] +['åįĶ', 'æľĥ'] +['éĻ', '¡'] +['åĬłå·¥', 'åİĤ'] +['æ¦Ĩ', 'æŀĹ'] +['æŃ»', 'è§Ĵ'] +['åĨħ', 'å¹ķ'] +['æīĢæľī', 'æĥħèĬĤ'] +['åĪ·', 'åį¡'] +['æ°´', 'èĤ¿'] +['èĥĥ', 'åı£'] +['å«Į', 'å¼ĥ'] +['æ²®', '丧'] +['ä¸īå¹´', '级'] +['æ¶Ĥ', 'å±Ĥ'] +['å¿ĥ', '仪'] +['å¿ĥ仪', 'çļĦ'] +['å¤', 'Ń'] +['é¦ĸ', 'è½®'] +['æĹłè®ºæĺ¯', 'åħ¶'] +['éĢı', 'æ°Ķ'] +['äºĮ', 'åįģäºĶ'] +['ç®', '«'] +['åĬŁ', 'åĬ³'] +['çѾ', 'ä¸ĭ'] +['æ²ī', 'è¿·'] +['æķij', 'åij½'] +['éĹª', 'éĹª'] +['åIJĥ', 'äºı'] +['å±ķ', 'åĵģ'] +['åį³æĹ¶', 'åıijçĶŁ'] +['ç¶', 'ľ'] +['ç¶ľ', 'åIJĪ'] +['æłĩ', 'æĺİ'] +['çľĭ', 'ç͵影'] +['åħ¬', '竳'] +['éĺ¿', '森'] +['éĺ¿æ£®', '纳'] +['身', 'åĪĽéĢł'] +['身åĪĽéĢł', 'çļĦ'] +['æ¸Ľ', 'å°ij'] +['å̼å¾Ĺ', 'åħ³æ³¨'] +['鼶åĶ®', 'åķĨ'] +['æįĨ', 'ç»ij'] +['è¸ı', 'åħ¥'] +['èĽ', 'Ł'] +['æŁ´', '纳'] +['èĢģ', 'åħµ'] +['绿èī²', 'çݯä¿Ŀ'] +['é¹', 'Ń'] +['麻', 'æľ¨'] +['æıŃ', 'çīĮ'] +['è¿Ļ款', '车'] +['ç¾İ', 'å¾·'] +['ç¾İå¾·', 'åħ¬åı¸'] +['æ¶', '§'] +['è°ģ', 'çŁ¥'] +['æ´ĭ', 'èij±'] +['æ¯į', 'æł¡'] +['ä¸Ģ', 'éĹª'] +['çĶ·', '主è§Ĵ'] +['æĹłçº¿', 'ç͵'] +['å±ł', 'å®°'] +['æĺ¯', 'éŁ©åĽ½'] +['æĺ¯éŁ©åĽ½', '娱'] +['容', 'è²Į'] +['åĿĩ', '使åħ¶'] +['太', 'å¿«'] +['å¹´', 'çͱ'] +['å¹´çͱ', '缼'] +['èĭ¦', 'èĭ¦'] +['åĬĽ', 'è¿ĺæĺ¯'] +['åĬĽè¿ĺæĺ¯', 'èĩª'] +['æĨ', '©'] +['èģ¯', '絡'] +['åĶ', '¾'] +['åħ·æľī', 'æĪĺ士'] +['追', 'éĹ®'] +['åłĨ', 'æĶ¾'] +['åıį', '驳'] +['å®ŀäºĭ', 'æ±Ĥ'] +['å®ŀäºĭæ±Ĥ', 'æĺ¯'] +['åѸ', 'éĻ¢'] +['åįģ', 'åĩłä¸ª'] +['æķij', 'æĬ¤'] +['æķijæĬ¤', '车'] +['ç½ij绾', 'ä¼łæĴŃ'] +['åįģåħ«', 'å±Ĭ'] +['éĥ¨', 'åī¯'] +['éĥ¨åī¯', 'éĥ¨éķ¿'] +['çĹ´', 'è¿·'] +['管çIJĨ', 'æĿ¡ä¾ĭ'] +['èŀį', '为ä¸Ģä½ĵ'] +['æĢ»', '产å̼'] +['è³', 'ĵ'] +['ä¸ĥ', 'æĺŁ'] +['çıŃ', 'ç»Ħ'] +['绣', 'é¢Ĩ'] +['请', '大家'] +['éĩij', 'éϵ'] +['èĪħ', 'èĪħ'] +['æµ·', 'æ¹¾'] +['æĸ½', 'çŃĸ'] +['享', 'èªī'] +['éº', '¥'] +['端', 'åįĪ'] +['绿', 'åŁİ'] +['確', 'ä¿Ŀ'] +['å·´', 'æĭī'] +['åĨĴ', 'çĿĢ'] +['æħ·', 'æħ¨'] +['个人', 'è§ĤçĤ¹'] +['ä¹Ļ', 'çĥ¯'] +['ç¡ħ', 'è°·'] +['éĸĭ', 'å±ķ'] +['å°ļ', '书'] +['åĿļ', '飧'] +['åº', 'µ'] +['èĢģ', 'é¾Ħ'] +['èĢģé¾Ħ', 'åĮĸ'] +['羨', 'çľ¼'] +['绿', 'æ°´'] +['绿水', 'éĿĴå±±'] +['书', 'é¦Ļ'] +['主åĬĽ', 'åĨĽ'] +['æīįæĺ¯', '羣æŃ£'] +['æĬ¢', 'åħĪ'] +['æĪIJå°±', 'æĦŁ'] +['éĩį', 'æŀĦ'] +['éĴ¢', 'åİĤ'] +['æĪIJ', '份'] +['èĬ±', '纹'] +['ä¹ĭ', 'äºī'] +['å¹²', 'ç»Ĩèĥŀ'] +['æĹ¢', 'åı¯ä»¥'] +['ç¹ģ', 'çIJIJ'] +['æĦļ', 'èł¢'] +['éĿŀ常', 'æĺİæĺ¾'] +['ä½ĵ', '彩'] +['æĬĢ', 'æ³ķ'] +['æĿĨ', 'èıĮ'] +['å¹¿æ³Ľ', 'åħ³æ³¨'] +['åĮĹ', 'å®ĭ'] +['å§Ĭ', '妹'] +['åįı', 'åĬŀ'] +['æ·®', 'åįĹ'] +['çĥ', 'ı'] +['æ´Ĺ', 'èĦ¸'] +['åıĹ', '访'] +['åıĹ访', 'èĢħ'] +['éĩįè¦ģ', 'åĽłç´ł'] +['å½±è§Ĩ', 'åī§'] +['综èīº', 'èĬĤ缮'] +['èľķ', 'åıĺ'] +['äºĮ', '线'] +['äºĮ线', 'åŁİå¸Ĥ'] +['ä¼Ĭ', 'å§ĭ'] +['çıĬ', 'çijļ'] +['èĩª', 'æŁ¥'] +['åħ¥', 'åĽŃ'] +['åĩ¶', 'æīĭ'] +['åħ¬', 'è¯ī'] +['éģĩ', 'éļ¾'] +['éĩĩçŁ¿', 'çŃī'] +['èĩª', 'çIJĨ'] +['åĸ·', 'æ¶Ĥ'] +['æī©', 'åħħ'] +['éĢı', 'è§Ĩ'] +['é«ĺéĢŁ', 'å¢ŀéķ¿'] +['åĽ¾', 'çĶ»'] +['ç¾', '¹'] +['èĤĩ', 'åºĨ'] +['è¾ľ', 'è´Ł'] +['èµĶ', 'ä»ĺ'] +['è·', '¡'] +['åģ¥åº·', 'æĪIJéķ¿'] +['以ä¸Ĭ', 'åѦåİĨ'] +['åıĸå¾Ĺ', '以åıĬ'] +['æ²ī', '积'] +['åįģä¹Ŀ', 'å±Ĭ'] +['缸éĹľ', 'æľįåĭĻ'] +['æī§', 'åĭ¤'] +['åī¯', 'åİ¿éķ¿'] +['å¯', '°'] +['åģľ', 'æ»ŀ'] +['æ·¹', '没'] +['çŁ³', 'çģ°'] +['çį', '¸'] +['åĢ', '¦'] +['ç¾İ', 'åªĴ'] +['æķĻ', 'æ¡Ī'] +['åĬł', 'çĽĸ'] +['åħ¬å¼Ģ', 'èµĽ'] +['å¥ł', 'åŁº'] +['æĺĨ', 'èĻ«'] +['çŀ', 'ħ'] +['磷', 'éħ¸'] +['äºī', 'åĪĽ'] +['çİĭ', 'æĻĵ'] +['ç¼ĵ', 'åĨ²'] +['åİļ', 'åİļ'] +['åİļåİļ', 'çļĦ'] +['æŀ£', 'åºĦ'] +['ç²¾', 'çĽĬ'] +['ç²¾çĽĬ', 'æ±Ĥ'] +['ç²¾çĽĬæ±Ĥ', 'ç²¾'] +['åĪĨæĶ¯', 'æľºæŀĦ'] +['å®ŀæĸ½', 'ç»ĨåĪĻ'] +['æĸ°', 'èµĽåŃ£'] +['總', 'çµ±'] +['éĢł', 'è¡Ģ'] +['é¢ĩ', 'åħ·'] +['é»Ħ', 'åŁĶ'] +['è¡Ģ', 'èĦĤ'] +['交éĢļ', 'å·¥åħ·'] +['å³', '¥'] +['æĹıèĩªæ²»', 'å·ŀ'] +['寺', 'éĻ¢'] +['確', 'å®ļ'] +['æ¦Ĥ念', 'èĤ¡'] +['æĦŁ', 'å®ĺ'] +['æŁľ', 'åı°'] +['åĶ', 'Ķ'] +['çŀŃè§£', '並'] +['æĢ»', 'ä»·'] +['åIJ¸', 'åħ¥'] +['æĢ', '¼'] +['æĻļ', 'éĹ´'] +['å±Ĭ', 'æ¯ķä¸ļçĶŁ'] +['çĶŁ', 'å§ľ'] +['éĺħ读', 'åħ¨æĸĩ'] +['å¾Ĺåΰ', 'æľīæķĪ'] +['æIJľ', 'æķij'] +['åİĨ', 'æĿ¥'] +['èŃī', 'æĺİ'] +['åĥ', '»'] +['èĨ³', 'é£Ł'] +['åĦĦ', 'åħĥ'] +['æīĵ', 'åİĭ'] +['宾', '客'] +['åķ', '¼'] +['ä¸ĢçϾ', 'å¤ļ'] +['æ·±åħ¥', '人å¿ĥ'] +['æ¢ħ', 'å·ŀ'] +['çłĶ', 'åѦ'] +['åħ³', 'ä¹İ'] +['è¼', 'Ľ'] +['亲', 'åıĭ'] +['éħį', 'æĸĻ'] +['æĪij', 'çĪ±ä½ł'] +['è´¸æĺĵ', 'æĪĺ'] +['æľī', 'èī²'] +['æľīèī²', 'éĩijå±ŀ'] +['æįIJ', 'åĬ©'] +['为', 'é¦ĸ'] +['为é¦ĸ', 'çļĦ'] +['å¯Į', 'åĬĽ'] +['çĶ·', 'ç¥ŀ'] +['é³', '³'] +['æµĩ', 'æ°´'] +['åIJ', '±'] +['æĺİç¡®', 'æıIJåĩº'] +['åı¹', 'äºĨ'] +['åı¹äºĨ', 'åı£æ°Ķ'] +['礼', 'æĭľ'] +['è¿Ļ个', 'åIJįåŃĹ'] +['ä¿¡', 'å¾Ĵ'] +['å¿Ĺ', '强'] +['éĻIJ', 'æĹ¶'] +['æĶ¶', 'è²»'] +['åĨľå®¶', 'ä¹IJ'] +['å°ıé¾Ļ', 'èϾ'] +['èIJ½', 'å¹ķ'] +['æ§', 'Ł'] +['åѦ', '龸'] +['æĪĸ', 'å¤ļ'] +['æĪĸå¤ļ', 'æĪĸ'] +['æĪĸå¤ļæĪĸ', 'å°ij'] +['座è°Ī', 'ä¼ļä¸Ĭ'] +['æ¶', '¼'] +['éŃĶ', 'çİĭ'] +['å²', '±'] +['é¡¶', 'å±Ĥ'] +['é¡¶å±Ĥ', '设计'] +['èĦij', 'åŃIJéĩĮ'] +['éĻ¢', 'åŃIJéĩĮ'] +['轩', 'è¾ķ'] +['身å¿ĥ', 'åģ¥åº·'] +['èħ', 'ij'] +['éĹľ', '注'] +['åıĤåĬł', 'ä¼ļè®®'] +['ä¸Ńåįİ', 'æĸĩåĮĸ'] +['追', '寻'] +['å®ī', 'çĦ¶'] +['é£Ļ', 'åįĩ'] +['éŁŃ', 'èıľ'] +['é¸', '¦'] +['åĤ¨', 'éĩı'] +['çĶ·', 'æĸ¹'] +['å¤ĩ', '份'] +['æijĶ', 'åĢĴ'] +['润æ»ij', 'æ²¹'] +['é̼', 'è¿ij'] +['çͳ', 'è¯ī'] +['鸣', 'ç±»'] +['çŁ³æ²¹', 'åĮĸå·¥'] +['åĿļ', 'æŀľ'] +['è¿Ļå®¶', 'ä¼Ļ'] +['æĭĴ', 'ä¸į'] +['羣', 'çļ®'] +['è·Ŀ', 'éĽ¢'] +['è¿ĺ', 'æĮº'] +['éĽķ', 'åĥı'] +['åĪĿ', 'æģĭ'] +['æıIJä¾Ľ', 'æĽ´å¤ļ'] +['æŁ¥çľĭ', 'åħ¨æĸĩ'] +['æķ°åŃĹ', 'è´§å¸ģ'] +['åĸī', 'åĴĻ'] +['åı¦ä¸Ģ', 'ä½į'] +['åĤ¬', 'åĮĸ'] +['åĤ¬åĮĸ', 'åīĤ'] +['ä»İæĿ¥', '没'] +['å¯ĨåĪĩ', '缸åħ³'] +['éĥ¨', '主任'] +['产åĵģ', 'ç»ıçIJĨ'] +['並', 'åIJĮæĦı'] +['èIJ½', 'åħ¥'] +['å±ıå¹ķ', 'ä¸Ĭ'] +['åħ¬åı¸', '竳ç¨ĭ'] +['æį¢', 'åı¥è¯Ŀ'] +['æį¢åı¥è¯Ŀ', '说'] +['ä½į', 'æĸ¼'] +['ä½', 'Ķ'] +['åĩ»', 'æĿĢ'] +['缸', 'è¾ĥ'] +['缸è¾ĥ', 'äºİ'] +['ç²½', 'åŃIJ'] +['åįĹ', 'æŀģ'] +['宫', 'é¢Ī'] +['è£ģ', 'åijĺ'] +['æĺİ', 'ç»Ĩ'] +['ä»·å̼', 'éĵ¾'] +['åĽĽä¸ª', 'æĸ¹éĿ¢'] +['æĥħåĨµ', 'æĿ¥çľĭ'] +['æĮij', 'åīĶ'] +['æ®', 'ĺ'] +['æŀģ', 'åĬĽ'] +['çĸij', 'éļ¾'] +['æĬµæĬĹ', 'åĬĽ'] +['æĢ¥', 'éĢŁ'] +['æĪ', 'Į'] +['ä½İ', 'ä¼°'] +['éĹª', 'è¿ĩ'] +['æģ', '¬'] +['èµŀ', 'æī¬'] +['ä»ĸ', 'å¦Ī'] +['æĪIJ为', 'ä¸ĢåIJį'] +['æ´Ĺ', '礼'] +['é¢Ħ计', 'å°Ĩ'] +['åħĪè¿Ľ', 'åįķä½į'] +['è¼', 'Ķ'] +['éĢĥ', 'èĦ±'] +['çݰ', 'åŃĺ'] +['èĢģèĻİ', 'æľº'] +['åįģä¸ĥ', 'æĿ¡'] +['åı¦ä¸Ģ', 'åįĬ'] +['温', 'æĥħ'] +['åī¥', '离'] +['ä¸ĸ', 'è´¸'] +['å®ĺ', 'åı¸'] +['å¾Ī', 'å·®'] +['éĹ´', 'è·Ŀ'] +['请', '注æĦı'] +['åı²', 'è¯Ĺ'] +['åĪ©', 'åύ'] +['è¿IJ', 'ç®Ĺ'] +['沦', '为'] +['該', '使ç͍èĢħ'] +['èĮ', '¬'] +['éͦ', '绣'] +['åı²', 'æĸĻ'] +['çģµ', 'æ´»æĢ§'] +['èģĶ', '社'] +['æĹł', 'åĬ©'] +['æĬĹ', 'æ°§åĮĸ'] +['èıľ', 'èĤ´'] +['éĢł', 'èι'] +['æİī', 'èIJ½'] +['å¤į', 'æŁ¥'] +['åĭĥ', 'åĭĥ'] +['åij¼', '声'] +['給', 'äºĪ'] +['åIJĮäºĭ', '们'] +['ç½', '°'] +['è¯ķ', 'æİ¢'] +['åħ³éĶ®', 'åŃĹ'] +['æįIJ', 'çĮ®'] +['ç»Łè®¡', 'æķ°æį®'] +['åĪĽ', 'ä½ľèĢħ'] +['ä¸ĭ', 'åįĬ'] +['ä¸ĭåįĬ', 'åľº'] +['æī¿æĭħ', '责任'] +['端', 'æŃ£'] +['ç©¿', 'è¡£'] +['ä¼ł', 'çIJĥ'] +['åĬ©', 'éķ¿'] +['åĩ', '±'] +['éķ¶', 'åµĮ'] +['é£ŀ', 'ç¿Ķ'] +['è¾ĵ', 'åįµ'] +['è¾ĵåįµ', '管'] +['ä¸ĩ', 'åħ¬éĩĮ'] +['æİ¨å¹¿', 'åºĶç͍'] +['å¿«', 'æ¨Ĥ'] +['ç§', '½'] +['èī°', 'å·¨'] +['åIJ¬', 'å®Į'] +['åĿļ', '硬'] +['奥', 'åľ°'] +['å¥¥åľ°', 'åĪ©'] +['é¢', 'ĵ'] +['èĻIJ', 'å¾ħ'] +['ä¾Ľ', 'æ±Ĥ'] +['éľī', 'ç´ł'] +['伪', 'è£ħ'] +['乡', 'åľŁ'] +['åĩ¡', 'æľ¬ç½ij'] +['åĩ¡æľ¬ç½ij', '注'] +['ä¼Ĭ', 'åĪ©'] +['è¡¡', 'æ°´'] +['æĽ´', 'åĥıæĺ¯'] +['åĪĨéĴŁ', 'å·¦åı³'] +['è¦ı', '模'] +['äºĶ', 'åĪĨéĴŁ'] +['åºĹ', 'åĬłçĽŁ'] +['åĽ°', 'éĽ£'] +['åħ³', 'åģľ'] +['æĢĿ', '绪'] +['åĴ½', 'åĸī'] +['缸', '符'] +['çĥ¦', 'èºģ'] +['æĻĤ', 'æľŁ'] +['åijĪ', 'çı¾'] +['è§£', 'æķ£'] +['诱', '导'] +['éļĶ', 'çĥŃ'] +['çĮ', '¶'] +['åįĹ', 'å®ĭ'] +['æ·±åħ¥', 'äºĨè§£'] +['çŃĶ', 'çĸij'] +['æĺ¼', 'å¤ľ'] +['åįĥ', 'ä¼ı'] +['åĬ³åĬ¡', 'æ´¾éģ£'] +['红', 'è±Ĩ'] +['åĿı', 'äºĭ'] +['çĤ¹', 'æ»´'] +['å°±ä¸ļ', 'å²Ĺä½į'] +['约', 'åIJĪ'] +['åħį', 'éϤ'] +['éĢĨ', 'åĬ¿'] +['éĩį', 'éĩijå±ŀ'] +['å®ĺ', '宣'] +['ä½İ', 'å»ī'] +['æģ¨', 'ä¸įå¾Ĺ'] +['å¾Ĺ', '天'] +['å¾Ĺ天', 'çĭ¬'] +['å¾Ĺ天çĭ¬', 'åİļ'] +['ä¸Ģå°ģ', 'ä¿¡'] +['æĬ½', 'å¥ĸ'] +['è¾Ĺ', '转'] +['çķĻ', 'å®Ī'] +['çķĻå®Ī', 'åĦ¿ç«¥'] +['çŃĶ', 'åį·'] +['å·¨', 'åŀĭ'] +['æľĢ好', 'ä¸įè¦ģ'] +['æµĻæ±Ł', '大åѦ'] +['æĨ', '¨'] +['æı¡', 'æīĭ'] +['éĴĪ', 'ç»ĩ'] +['æİĴ', '骨'] +['çĤ', '½'] +['å°ģ', 'è£ħ'] +['åįĢ', 'åŁŁ'] +['空æ°Ķ', 'åĩĢåĮĸ'] +['åħī', 'å½±'] +['åĢĴ', 'å¡Į'] +['å§ļ', 'æĺİ'] +['æ¤į', '被'] +['åѦ', 'åīį'] +['åѦåīį', 'æķĻèĤ²'] +['èĬĿ', 'åĬł'] +['èĬĿåĬł', 'åĵ¥'] +['缩', 'æ°´'] +['ä½', 'Ł'] +['åľ¨çº¿', 'åĴ¨è¯¢'] +['èµı', 'æŀIJ'] +['éĿĴ', 'èĽĻ'] +['æĬ±', 'ä½ı'] +['èĮĤ', 'åIJį'] +['åħ¨åĬĽ', 'æīĵéĢł'] +['åįļ士', 'åѦä½į'] +['æ²§', 'å·ŀ'] +['åĻ', '¢'] +['æĿĤ', 'çī©'] +['åĪ»', 'çĶ»'] +['æį', 'ħ'] +['å¾®', 'éĩı'] +['å¾®éĩı', 'åħĥç´ł'] +['ä¸Ģ', 'åĽŀäºĭ'] +['鸡', 'èĤī'] +['åĪ©æ¶¦', 'çİĩ'] +['æīį', 'ç®Ĺ'] +['å¾®', 'å¦Ļ'] +['棵', 'æłij'] +['è´ª', '婪'] +['åĩı', 'å̼'] +['梦', 'å¢ĥ'] +['åı¯', 'è§Ĩ'] +['åı¯è§Ĩ', 'åĮĸ'] +['广大', 'å¸Ĥæ°ij'] +['ä¸ĵä¸ļ', 'ä»İäºĭ'] +['ç»ı', '纬'] +['ç´§', 'çĽ¯'] +['çŁ¥', 'å·±'] +['è¤', 'ļ'] +['æĸĩåĮĸ', 'åºķèķ´'] +['åݦéŨ', 'å¸Ĥ'] +['临', '港'] +['对åħ¶', '羣å®ŀ'] +['岸', 'è¾¹'] +['è¦ĸ', 'çĤº'] +['æĬĹ', 'çĻĮ'] +['åĶIJ', 'å®ĩ'] +['ä¸įå¾Ĺ', 'è¶ħè¿ĩ'] +['å¨ģ', 'æħij'] +['æ¡Ĩæŀ¶', 'åįıè®®'] +['èµ°', 'ç§ģ'] +['åĽ¢', 'å§Ķ'] +['夸', '大'] +['æ¬', 'Ħ'] +['ç¥ŀç»ı', 'ç³»ç»Ł'] +['æijĦå½±', 'ä½ľåĵģ'] +['èĬ', '¥'] +['å®ī', 'åºĨ'] +['æµ·', '滨'] +['æŀĦ', 'æĢĿ'] +['çīµ', 'æĮĤ'] +['åı', '©'] +['éĺIJ', 'æĺİ'] +['éģ', 'ģ'] +['ç²¾', 'æ²¹'] +['ç©´', 'ä½į'] +['æĬ¤', '身'] +['æĬ¤èº«', '符'] +['æĮĩ', 'å°İ'] +['åŃĺåľ¨', 'ä¸Ģå®ļ'] +['å¯Ĥ', 'éĿĻ'] +['æµ·å¤ĸ', 'å¸Ĥåľº'] +['éĿ', '¡'] +['综åIJĪ', 'å¾ģ'] +['ä¿', 'IJ'] +['è¨Ī', 'ç®Ĺ'] +['æĺİ', 'æľĹ'] +['äºļ', 'è¿IJ'] +['äºļè¿IJ', 'ä¼ļ'] +['åīįçŀ»', 'æĢ§'] +['åĮ®', 'ä¹ı'] +['产ä¸ļ', 'æī¶è´«'] +['èĦij', 'æµ·'] +['èĦijæµ·', 'ä¸Ń'] +['åħļçļĦ', 'é¢Ĩ导'] +['åĪĺ', 'éĤ¦'] +['æµģ', 'æĺŁ'] +['æĵ', 'Ĥ'] +['æĶĢ', 'çĻ»'] +['åĴ', 'Ķ'] +['ä¸Ģä¸ĭåŃIJ', 'å°±'] +['è¯Ĭ', 'æ²»'] +['使', 'åĬ²'] +['åīµ', 'ä½ľ'] +['éĵŃ', 'è®°'] +['éĴ±', 'è´¢'] +['æĹ¥æĬ¥', 'è®°èĢħ'] +['çĥŁ', 'çģ«'] +['èĥľ', 'è´Ł'] +['åįļ', '主'] +['ä¸ŃåĽ½', 'èģĶéĢļ'] +['ç½ijç«Ļ', 'é¦ĸ页'] +['å°±', 'å¤Ł'] +['å°±å¤Ł', 'äºĨ'] +['æīij', 'åħĭ'] +['å±ħ', 'å§Ķä¼ļ'] +['è°', '¬'] +['å®īåħ¨', 'äºĭæķħ'] +['åķĨ', 'çĶ¨è½¦'] +['循çݯ', 'ç»ıæµİ'] +['æ·', '¤'] +['èĢĥ', 'è¯ģ'] +['å®Ŀ', 'èĹı'] +['å®Į', 'ç»ĵ'] +['çłĶåıij', 'æĬķåħ¥'] +['å²', 'ij'] +['æģŃ', 'æķ¬'] +['离', 'éĢĢä¼ij'] +['æ°´', '墨'] +['å©', '¶'] +['è¯Ĺ', 'åı¥'] +['å®ģæ³¢', 'å¸Ĥ'] +['å¼±', 'çĤ¹'] +['åģľ', 'çīĮ'] +['奶', 'æ²¹'] +['å¥ĩ纳', 'æ²³'] +['æĨ', 'Ĥ'] +['社ä¼ļ', 'å®ŀè·µ'] +['è´Ŀ', '壳'] +['çłĤ', 'æµĨ'] +['èι', 'åıª'] +['宣', 'æī¬'] +['综åIJĪ', 'æķ´æ²»'] +['åĤ', 'ij'] +['æ°ijæĹı', 'æĸĩåĮĸ'] +['éĩį', 'çݰ'] +['积', 'æ·Ģ'] +['åħ¬', 'çĦ¶'] +['çħ', 'ī'] +['缸', 'èģļ'] +['æ±', '¾'] +['纹', 'çIJĨ'] +['çĩĥ', 'çħ¤'] +['æŃ¤', 'ç§į'] +['ç¾İ', 'å¦Ĩ'] +['åįĥ', 'çĵ¦'] +['çIJ', 'Ľ'] +['驾驶', 'è¯ģ'] +['éĺ¶', '梯'] +['ä¸Ŀ', 'ä¸Ŀ'] +['å¾Īå¤ļ', 'äºĭæĥħ'] +['åħī', 'éĺ´'] +['èijĹä½ľ', 'æ¬Ĭ'] +['åħ§', 'éĥ¨'] +['çĽ¸å¯¹', 'æĿ¥è¯´'] +['éĸ', 'Ĵ'] +['éľĩ', 'æħij'] +['說', '話'] +['æĨ', 'ij'] +['ç«¥', 'è£ħ'] +['ä½ıæĪ¿', 'åĴĮ'] +['ä½ıæĪ¿åĴĮ', 'åŁİ'] +['å·²ç»ı', 'è¶ħè¿ĩ'] +['侦', 'å¯Ł'] +['çŁ¿', 'çī©'] +['ä¾Ľ', '大家'] +['çī¹', 'éĤĢ'] +['ç¨ĭåºı', 'åijĺ'] +['çķľçī§', 'ä¸ļ'] +['æ°', 'ª'] +['çij', 'ª'] +['åĢĴ', 'åľ¨'] +['åĢĴåľ¨', 'åľ°'] +['æ¯', 'Ģ'] +['梯', 'éĺŁ'] +['æİ¥', 'èijĹ'] +['æĬĹ', 'èıĮ'] +['è¤', 'ĩ'] +['ç¬', 'Ļ'] +['æ¯Ķ', 'ä¸Ĭå¹´'] +['鸡', '汤'] +['åŃ¦ä¹ł', 'æĪIJ绩'] +['æĸij', 'æĸĵ'] +['åħĪ', '导'] +['åĪĹ', '举'] +['è°ĥæŁ¥', 'æĺ¾ç¤º'] +['æ©', '«'] +['ä¹Ŀ', 'åįģ'] +['è°¢', '飵'] +['è·¨è¶Ĭ', 'å¼ı'] +['女æĢ§', 'æľĭåıĭ'] +['èIJ¥åħ»', 'ä»·å̼'] +['å®ŀè·µ', 'ç»ıéªĮ'] +['èĭı', 'å·ŀå¸Ĥ'] +['çĵ¶', 'åŃIJ'] +['æĸ°', 'çļĦä¸Ģ'] +['æĸ°çļĦä¸Ģ', 'å¹´'] +['æĺİ', 'æĻ°'] +['å®ł', 'çα'] +['åŃĹ', '第'] +['æľĹ', '诵'] +['纳', 'æĸ¯'] +['éĢĨ', 'è¡Į'] +['è«ĭ', 'æĤ¨'] +['è«ĭæĤ¨', 'æıIJä¾Ľ'] +['èĥ¸', 'æĢĢ'] +['第ä¸ĥ', 'å±Ĭ'] +['强', '壮'] +['代', 'åŃķ'] +['æ±¶', 'å·Ŀ'] +['å®¶', 'åĸ»'] +['å®¶åĸ»', 'æĪ·'] +['å®¶åĸ»æĪ·', 'æĻĵ'] +['èħ', '®'] +['åIJ¯', '迪'] +['æĹł', 'éļľç¢į'] +['èĻķçIJĨ', 'åıĬ'] +['æĿ¥', 'åİĨ'] +['å®ŀ', 'åĬ¡'] +['ä¹Ł', 'éļıä¹ĭ'] +['æĬĢèĥ½', 'åŁ¹è®Ń'] +['åѤ', 'ç«ĭ'] +['åī', 'ģ'] +['éĥ´', 'å·ŀ'] +['æĶ¶', 'æķĽ'] +['éł»', 'éģĵ'] +['èį£', '幸'] +['èİ«', 'è¿ĩäºİ'] +['æŃ¤', 'æĻĤ'] +['纪å§Ķ', 'çĽij'] +['纪å§ĶçĽij', 'å§Ķ'] +['缸', 'éĤ»'] +['åı¦ä¸Ģ', 'è¾¹'] +['çªĴ', 'æģ¯'] +['æľīå¾Īå¤ļ', 'ç§į'] +['æ¯ı', 'éĢ¢'] +['éĹ®', 'ä¸ĸ'] +['ç´¯', 'ç´¯'] +['éĿĴæĺ¥', 'æľŁ'] +['è·¯', 'åĨµ'] +['åħĭ', 'èݱ'] +['è¿Ħä»Ĭ', '为æŃ¢'] +['æĥĬ', 'å¥ĩ'] +['è·¨', '度'] +['éħ¿', 'éĢł'] +['åĩ', 'ĭ'] +['è¿ij', 'ä¸īå¹´'] +['åĨħ', '马'] +['åĨħ马', 'å°Ķ'] +['æı', 'į'] +['è¿Ľå±ķ', 'æĥħåĨµ'] +['èĮ', '§'] +['æľīåºı', 'æİ¨è¿Ľ'] +['æĢ»', 'åĨłåĨĽ'] +['æĪIJ绩', 'åįķ'] +['éĽ»è©±', 'åıĬ'] +['ç´§å¯Ĩ', 'ç»ĵåIJĪ'] +['åºĬ', 'ä½į'] +['é¹', 'Ĭ'] +['æķ£åıij', 'çĿĢ'] +['åĭŁ', 'èµĦ'] +['æ°¨', 'éħ¸'] +['彩', 'ç¥ŀ'] +['è®Ģ', 'åıĸ'] +['éĩį', '温'] +['ä¸Ń', 'åŃĺåľ¨çļĦ'] +['ç¾İ', 'éºĹ'] +['ä¸įæĸŃ', 'å¢ŀåĬł'] +['è½®', 'æµģ'] +['æİ¥', 'åIJ¬'] +['å¹´', '产å̼'] +['åįĥ', 'åħĭ'] +['æĪĺåľº', 'ä¸Ĭ'] +['çħ§', 'é¡§'] +['å¹²éĥ¨', 'éĺŁä¼į'] +['åį°', '竳'] +['ä¸Ģèĩ´', 'æĢ§'] +['è¿ŀ', 'å¤ľ'] +['åħħ', 'è£ķ'] +['é»ij', 'åIJįåįķ'] +['åĩĢ', 'æ°´'] +['ä¸Ģ大', 'æĹ©'] +['åĮħ', '袱'] +['çĬ¯', 'è§Ħ'] +['çIJĨ', 'è«ĸ'] +['æŀģ', 'æĺĵ'] +['éª', '¸'] +['å¨ĺ', 'å¨ĺ'] +['åĽ¢', 'åľĨ'] +['亿åħĥ', '以ä¸Ĭ'] +['åĪ©ç͍', 'æĤ¨çļĦ'] +['带æĿ¥', 'æĽ´å¤ļ'] +['ä¸Ń央', '空è°ĥ'] +['æľĪ', 'èĸª'] +['çĮľ', 'æĥ³'] +['åĪº', '客'] +['ä½ľ', 'æģ¯'] +['åįķ', 'è°ĥ'] +['äºĴ', 'åĪ©'] +['å¦Ĥæľī', 'ä¾µæĿĥ'] +['å°ı', 'å·§'] +['åįģ', 'åł°'] +['åĵĪåĵĪ', 'åĵĪåĵĪ'] +['è¾¹', 'éĻħ'] +['æłĩ', 'è¯Ń'] +['åĪĩåħ¥', 'çĤ¹'] +['éĢĨ', 'è¢Ń'] +['è¯ķ', 'åīĤ'] +['绿', 'è±Ĩ'] +['è®', 'ļ'] +['åŁºçĿ£', 'å¾Ĵ'] +['å£', '¬'] +['åħ¨', 'æĺİæĺŁ'] +['éĢī', 'ç§Ģ'] +['èĪĮ', 'å°ĸ'] +['ä¸įåIJĮ', 'ç±»åŀĭ'] +['çĥŁ', 'åĽ±'] +['çģµ', 'æ°Ķ'] +['åĮº', '管å§Ķä¼ļ'] +['åĨľ', 'åī¯'] +['åĨľåī¯', '产åĵģ'] +['èĶļ', 'æĿ¥'] +['沪', 'æĮĩ'] +['åħ»æ®ĸ', 'æĪ·'] +['æĸĹ', 'å¿Ĺ'] +['é¦ĸ', 'é¢Ĩ'] +['è¡Ģ', 'èħ¥'] +['åĬł', 'ç´§'] +['ä¸Ģèĩ´', '好è¯Ħ'] +['第ä¸ī', 'èĬĤ'] +['æī¬', 'å°ĺ'] +['交éĢļ', 'æŀ¢çº½'] +['鼶', 'ç¢İ'] +['é»ij', 'æ´ŀ'] +['çľĭ', 'ä¸įæĩĤ'] +['å±ŀ', 'å®ŀ'] +['主', 'åŁİåĮº'] +['å¨', 'Ľ'] +['å¨Ľ', 'æ¨Ĥ'] +['ç¬ij', 'æĦı'] +['èϹ', 'æ¡¥'] +['åIJĦ个', 'çݯèĬĤ'] +['çķ¥', 'å¾®'] +['èĢķ', 'èĢĺ'] +['æľ¬', 'åľºæ¯ĶèµĽ'] +['æĪIJ', 'è´¥'] +['éĢī', 'èĤ¡'] +['èªŀ', 'è¨Ģ'] +['çŃĶ', '辩'] +['èĩª', 'ä¹ł'] +['æ£', 'º'] +['ä¸ĩ', '欧åħĥ'] +['åģľ', 'å·¥'] +['对åħ¶', 'è¿Ľè¡Į'] +['积æŀģ', 'éħįåIJĪ'] +['ä¹¾', 'åĿ¤'] +['å¦ĸ', 'æĢª'] +['èļĮ', 'åŁł'] +['èµĦ产', 'è¯Ħä¼°'] +['è°ĥ', 'çļ®'] +['éϤ', 'å¤ķ'] +['åĽ´', 'å¢Ļ'] +['æľį', 'å½¹'] +['æ·±', 'æ¸Ĭ'] +['é¢Ħ', 'åζ'] +['ç', 'ĥ½'] +['å®ī', '稳'] +['建', 'æŀĦ'] +['çĭĻ', 'åĩ»'] +['主åĭķ', '註åĨĬ'] +['éĥ½æľī', 'èĩªå·±'] +['æİĴåIJį', '第ä¸Ģ'] +['麻', 'è¾£'] +['çĢ', 'ļ'] +['çĥŁèĬ±', 'çĪĨ'] +['çĥŁèĬ±çĪĨ', '竹'] +['èĩªçĦ¶', 'ä¿ĿæĬ¤'] +['ä»Ļ', 'å¢ĥ'] +['为äºĨ', 'éģ¿åħį'] +['åĨ·', 'åºĵ'] +['è§£æĶ¾', 'æĢĿæĥ³'] +['åĪĿ', 'äºĮ'] +['ä½ĵ', 'è´´'] +['é¦ĸ', 'å¯Į'] +['迪', 'æĭľ'] +['æļĤ', 'ç¼ĵ'] +['æĶ¯æĮģ', 'åĬĽåº¦'] +['侦', 'æİ¢'] +['马', 'åĪº'] +['åĮĹ', 'æ±½'] +['ç¹', 'ŀ'] +['è°İ', 'è¨Ģ'] +['éĢ£', 'çºĮ'] +['å·', '³'] +['ä»»ä½ķ', 'æĹ¶åĢĻ'] +['车', 'èģĶç½ij'] +['åįķ', '项'] +['å¸Ń', 'åį·'] +['建çŃij', 'æĿIJæĸĻ'] +['ä¸Ńç§ĭ', 'èĬĤ'] +['ç¡ķ士', 'çłĶç©¶'] +['ç§ģ', 'ç«ĭ'] +['åħļåĴĮ', 'æĶ¿åºľ'] +['æľ¬æ¬¡', '交æĺĵ'] +['èººåľ¨', 'åºĬä¸Ĭ'] +['ç½ijåıĭ', 'è¯Ħ论'] +['å¦', 'Ŀ'] +['害', 'ç¾ŀ'] +['åħ¬ç«ĭ', 'åĮ»éĻ¢'] +['ä¸', 'ŀ'] +['çĶŁçī©', 'è´¨'] +['åºĶ', 'éĤĢ'] +['æĬ½', 'åıĸ'] +['åĩł', 'å¼ł'] +['æijĺ', 'ç¼ĸ'] +['ç»ĺ', 'æľ¬'] +['详', 'è§£'] +['强', '硬'] +['æľĢ', 'åħĪè¿ĽçļĦ'] +['æĭĽ', 'èĤ¡'] +['æĭĽèĤ¡', '书'] +['åįĥ', 'æĸ¹'] +['åįĥæĸ¹', 'çϾ'] +['åįĥæĸ¹çϾ', '计'] +['éħį', 'éŁ³'] +['驾', 'çħ§'] +['å¾ģ', 'æĪĺ'] +['èªĵ', 'è¨Ģ'] +['æĭľ', 'å¸Ī'] +['æĭľå¸Ī', 'åѦ'] +['æĭľå¸ĪåѦ', 'èīº'] +['æĬ±', 'åĽ¢'] +['ç±³', 'ç²ī'] +['éĿŀ常', 'éĢĤåIJĪ'] +['èĪª', 'æµ·'] +['å±¥', '约'] +['åįģåħ«', 'æĿ¡'] +['éĶ»', 'éĢł'] +['éĩįè¦ģ', '举æİª'] +['åıijæĮ¥', 'ä½ľç͍'] +['æ·', 'ļ'] +['人', '社'] +['人社', 'å±Ģ'] +['è¯ķçĤ¹', 'å·¥ä½ľ'] +['éĺľ', 'éĺ³'] +['æ¡ĥ', 'åľĴ'] +['æ°ij', 'ä¼ģ'] +['æ´ģ', 'çϽ'] +['è´µ', '宾'] +['åħ¬', '社'] +['è§ī', 'æĤŁ'] +['è®°å¿Ĩ', 'åĬĽ'] +['æľĥåĵ¡', '註åĨĬ'] +['æŃ¤', 'æ¡Ī'] +['麻', 'çĹ¹'] +['çı', 'Ģ'] +['æĸ©', 'èİ·'] +['çĶ·', 'åŃ©åŃIJ'] +['å±ĢéĻIJ', 'äºİ'] +['åĭĺ', 'æŁ¥'] +['åIJĥ', '饱'] +['èĬ¬', 'åħ°'] +['æ£ķ', 'èī²'] +['ç¦ı', 'ç¥ī'] +['çͳ', 'èĬ±'] +['æµ·', 'çĽĹ'] +['èĶ', 'ij'] +['æĸĩ', 'åѸ'] +['æ´»æĢ§', 'çĤŃ'] +['缴', 'éĢļ车'] +['è°¢', 'éĤĢ'] +['躺', 'çĿĢ'] +['åľ', 'ĥ'] +['æ¯ıæĹ¥', 'ç»ıæµİ'] +['åħ¬åħ±', 'æĸĩåĮĸ'] +['讲', 'æķħäºĭ'] +['å¯Ł', 'çľĭ'] +['æĤł', 'éĹ²'] +['åľ°', 'åĿª'] +['æ¶Į', 'çݰåĩº'] +['é«ĺçŃī', 'éĻ¢æł¡'] +['èĮĦ', 'åŃIJ'] +['éĺ²', 'åį«'] +['ä¾ĭ', 'è¡Į'] +['æĺ¾', 'éľ²'] +['æĸ°', '常æĢģ'] +['ç»Ŀ', 'ä½³'] +['å¯Į', 'æ°ij'] +['以', '人æ°ij'] +['以人æ°ij', '为'] +['éĤ¢', 'åı°'] +['å±ķ', 'æ¼Ķ'] +['çϼ', 'å¸ĥ'] +['è´Ł', 'è½½'] +['åģı', '离'] +['æ°¸', 'éģł'] +['éĩįè¦ģ', 'åİŁåĽł'] +['åįıä¼ļ', 'ä¼ļåijĺ'] +['éļ¾', 'æ°ij'] +['çĶŁäº§', '车éĹ´'] +['çģµ', 'åĬ¨'] +['两年', 'åīį'] +['æĸ¹', 'åľĨ'] +['æ´»', 'ä¸ĭåİ»'] +['ä¸ĸçķĮ', 'è§Ĥ'] +['éªĹ', 'åıĸ'] +['ç¾İ', 'è²Į'] +['èĥ½', 'çľĭåĩº'] +['çϼ', 'æı®'] +['è§Ĥ', 'å½±'] +['åī', 'ĥ'] +['åIJĪèµĦ', 'åħ¬åı¸'] +['å©', '§'] +['å¹²', 'æĹ±'] +['åħŃ', '个æľĪ'] +['尤为', 'éĩįè¦ģ'] +['èĤ', '½'] +['秦', 'åĽ½'] +['æīĺ', 'ç¦ı'] +['建çŃij', 'å¸Ī'] +['åįĩ级', 'æĶ¹éĢł'] +['å°ı', 'é¢Ŀ'] +['å°ıé¢Ŀ', '贷款'] +['两个', 'ç»´æĬ¤'] +['æĭį', 'æĭį'] +['åı¯', 'çĸij'] +['æį¢', 'åıĸ'] +['æŃ¦', '士'] +['èµĸ', '以'] +['èµĸ以', 'çĶŁåŃĺ'] +['æĮ', 'ļ'] +['殿', 'åłĤ'] +['èĩªçĦ¶', 'çķĮ'] +['ç£ģ', 'åľº'] +['å¦Ĥä½ķ', 'çľĭå¾ħ'] +['ä»ĬæĹ¥', '头æĿ¡'] +['西', 'åŁŁ'] +['èİ·', 'è¯Ħ'] +['風', 'æł¼'] +['ä¿Ħ', 'åĽ½'] +['æīĵ', 'æĭ¼'] +['å®£ä¼ł', 'çīĩ'] +['å¾Ī', 'æĸ¹ä¾¿'] +['ä¾Ľç»Ļ', 'ä¾§'] +['纪念', 'ç¢ij'] +['毫', 'åħĭ'] +['èĬ³', 'é¦Ļ'] +['å·¥åķĨ', 'éĵ¶è¡Į'] +['请', 'çĤ¹åĩ»'] +['ç¼', 'ª'] +['æĹłæķ°', '次'] +['èį¯', 'å¸Ī'] +['èħ', '¸'] +['游', 'èīĩ'] +['åĮ', '¾'] +['å·¡', 'èĪª'] +['æ²»çIJĨ', 'ä½ĵç³»'] +['èIJ¥éĢł', 'èī¯å¥½'] +['æ··', 'æ·Ĩ'] +['éĢļ', 'çķħ'] +['åĬ³', 'ç´¯'] +['ä»ĵ', 'ä½į'] +['å¢ŀ', 'éķ·'] +['éļIJ', '约'] +['æĿĤå¿Ĺ', '社'] +['åħ»', 'èĤ²'] +['åı¯èĥ½', 'åıijçĶŁ'] +['èĢĥ', '試'] +['西', 'ä¾§'] +['åĬł', 'åĢį'] +['主æĮģ', 'åı¬å¼Ģ'] +['çķ¢', '竣'] +['éĹ®', '询'] +['æµ·', 'æ£ł'] +['èĹ', '©'] +['注æĺİ', 'æĿ¥æºIJ'] +['æ£Ģ', 'çĸ«'] +['请', 'åģĩ'] +['æĬļ', 'æij¸'] +['èĵĦ', 'çĶµæ±ł'] +['è·Ł', 'ä¸įä¸Ĭ'] +['çݰ代', '社ä¼ļ'] +['çѹ', 'èµĦ'] +['ä½ĵèĤ²', '彩票'] +['å»¶', '误'] +['è¾Ľ', 'è¾£'] +['éĿ¢', '容'] +['åį°', 'è®°'] +['çģŃ', '亡'] +['ç´ł', 'é£Ł'] +['åħ´', 'èĩ´'] +['éľĢè¦ģ', 'ç͍'] +['éľĢè¦ģç͍', 'åΰ'] +['å®Ŀ', 'å¦Ī'] +['ç£ĭ', 'åķĨ'] +['éļ¶', 'å±ŀ'] +['è´¡çĮ®', 'åĬĽéĩı'] +['åħ¬åħ±', 'èµĦæºIJ'] +['大', 'éĺª'] +['åĨĽ', 'è®Ń'] +['æĤ¬', '念'] +['社ä¼ļ', '稳å®ļ'] +['å¹²äºĭ', 'åĪĽä¸ļ'] +['æľī', 'æĿ¡ä»¶'] +['æľīæĿ¡ä»¶', 'çļĦ'] +['ä¸Ģå¹´', 'ä¸Ģ度'] +['åİ', '¥'] +['强', '奸'] +['豪', '车'] +['æİĮ', 'æŁľ'] +['æ°´åĪ©', 'å·¥ç¨ĭ'] +['å³', 'ª'] +['积æŀģ', 'ä½ľç͍'] +['æµ·', 'æ·Ģ'] +['æµ·æ·Ģ', 'åĮº'] +['çĥŃ', 'æĴŃ'] +['åĿļæĮģ', 'ä¸įæĩĪ'] +['åıĮ', 'èĦļ'] +['绣', 'æĪĺ'] +['ä»»ä½ķ', '人éĥ½'] +['åľ°ä¸ĭ', '室'] +['åĨ¶', 'çĤ¼'] +['è°ħ', 'è§£'] +['æ¸Ķ', 'èι'] +['太éĺ³', 'åŁİ'] +['被', 'æįķ'] +['计ç®Ĺ', 'åύ'] +['西', 'åĮ»'] +['èĪĴ', 'å¿ĥ'] +['æ¡', '¦'] +['éģ', '²'] +['åĬ', 'ij'] +['è¨', 'Ĺ'] +['èİ', 'º'] +['åĸ', '¬'] +['çĵ', '¯'] +['åĺ', 'ĺ'] +['åł', 'ķ'] +['æķ', 'Ŀ'] +['åij', '¦'] +['èĭ', 'ŀ'] +['æŃ', '¹'] +['æĵ', '¬'] +['æ£', 'Ħ'] +['èĪ', 'µ'] +['å¥', 'ª'] +['çļ', 'ĭ'] +['æĶ', '¸'] +['åľ', '©'] +['ç¤', 'Ļ'] +['ç¢', 'ĺ'] +['éı', 'Ī'] +['æĦ', 'ķ'] +['ç¹', '³'] +['èĺ', '¸'] +['è²', 'Ĥ'] +['æ¼', '²'] +['æij', '¹'] +['æĶ', 'Ŀ'] +['åŃ', '¢'] +['èķ', 'Ń'] +['é¨', '°'] +['æ½', '¼'] +['éħ', '°'] +['æĴ', '¥'] +['è¹', '¬'] +['é¨', 'Ļ'] +['è¸', '¹'] +['éģ', 'IJ'] +['çĺ', 'Ģ'] +['èĽ', '¤'] +['æĤ', 'ĸ'] +['çĴ', 'ŀ'] +['ç£', 'IJ'] +['æİ', '°'] +['è¾', 'Ĭ'] +['å¾', 'ij'] +['æİ', 'ĸ'] +['éģ', 'ŀ'] +['éĤ', '¸'] +['éĽ', 'ı'] +['æĨ', 'İ'] +['æľ', '½'] +['çį', '»'] +['ç®', 'Ķ'] +['è¤', '¶'] +['æļ', '¢'] +['æĺ', 'µ'] +['çı', 'Ĥ'] +['æĤ', '¸'] +['åģ', 'µ'] +['åĻ', 'ľ'] +['å£', '¯'] +['æĴ', '®'] +['æģ', 'į'] +['å©', 'ķ'] +['ç¯', '±'] +['éĺ', 'Ļ'] +['çī', 'ł'] +['è£', 'ĺ'] +['è³', '¢'] +['éĩ', 'ľ'] +['éĵ', 'ł'] +['èİ', 'ĺ'] +['æ®', 'Ĩ'] +['çĻ', '¸'] +['è´', 'ı'] +['ç²', '±'] +['å«', '¡'] +['åĨ', '¢'] +['è¤', 'Ĵ'] +['æĩ', 'Ĭ'] +['éľ', 'ĵ'] +['å¡', 'µ'] +['æĭ', '£'] +['å»', 'Ł'] +['é£', '½'] +['é¢', 'Į'] +['åļ', 'İ'] +['æ·', 'º'] +['èĨ', 'ł'] +['åİ', 'Ń'] +['åļ', 'ĩ'] +['åij', 'ĥ'] +['çĴ', 'ĭ'] +['çŃ', '±'] +['æĭ', '·'] +['èį', '§'] +['éĶ', '°'] +['åŃ', '°'] +['èĵ', 'ĵ'] +['èĨ', '½'] +['æŀ', 'ī'] +['åĸ', '½'] +['çĽ', 'Ķ'] +['çŃ', 'IJ'] +['ç¾', 'ļ'] +['è', 'ħĮ'] +['è¾', '«'] +['æ³', 'ĵ'] +['çĶ', '¬'] +['èŁ', '²'] +['åĸ', 'ª'] +['å¦', 'ĵ'] +['è¬', 'Ģ'] +['çĤ', 'Ĭ'] +['æĽ', 'ľ'] +['æ±', 'IJ'] +['è´', 'Ī'] +['èį', 'Ģ'] +['æĬ', 'ł'] +['ç¢', '¾'] +['æ«', 'ĥ'] +['éŀ', 'ł'] +['èij', 'Ĩ'] +['ç¥', '¯'] +['å½', 'Ŀ'] +['é¦', 'į'] +['åĮ', '£'] +['æľ', 'Ń'] +['åĿ', 'Ĥ'] +['ä¿', 'ij'] +['èĵ', '®'] +['çij', 'Ľ'] +['æī', 'ī'] +['èĩ', 'Ł'] +['è²', '«'] +['çİ', '¥'] +['æ·', '¼'] +['åİ', '²'] +['é³', 'Į'] +['å³', 'Ń'] +['åij', 'Ľ'] +['é', '§'] +['é§', 'IJ'] +['éģ', '·'] +['ä¿', 'ª'] +['æĢ', 'Ĥ'] +['è¾', 'į'] +['å±', 'į'] +['åĭ', 'ģ'] +['å¥', 'ļ'] +['éļ', 'ħ'] +['éĴ', '´'] +['è¼', 'Ŀ'] +['å®', '¦'] +['èIJ', 'ĥ'] +['çĺ', 'ĭ'] +['æĨ', '¶'] +['æĤ', 'ħ'] +['è¾', 'Ļ'] +['åij', 'ľ'] +['çł', 'º'] +['éĢ', 'ŀ'] +['æµ', 'ļ'] +['éĸ', '£'] +['èĸ', '©'] +['éĻ', 'ĭ'] +['çĤ', 'Ļ'] +['èª', 'ķ'] +['ä¸', 'Ł'] +['é¹', '½'] +['ç±', 'Į'] +['è´', '°'] +['éĭ', 'ª'] +['çľ', '©'] +['æĴ', 'IJ'] +['èĨ', 'º'] +['éŀ', 'ĺ'] +['ç¾', '²'] +['çª', '®'] +['ç´', 'IJ'] +['æ®', '´'] +['çº', '¾'] +['èº', 'į'] +['ç´', 'ĭ'] +['çĦ', 'ĸ'] +['çĶ', 'º'] +['çī', '½'] +['çĤ', '¯'] +['ç¼', 'Ķ'] +['æ¯', 'ĵ'] +['å¬', '°'] +['æ¢', '§'] +['äº', 'Ł'] +['è¢', 'ħ'] +['çį', 'Ħ'] +['è¿', '¥'] +['æ¼', '¾'] +['çĿ', 'ij'] +['ç¸', '¾'] +['é¦', 'ĭ'] +['é¤', 'ħ'] +['æ', '¹Ħ'] +['æĺ', 'ĩ'] +['æŀ', 'Ń'] +['èĸ', '°'] +['æŁ', 'ij'] +['æ¦', '»'] +['åĻ', 'Ĺ'] +['åĻ', '´'] +['æ£', '£'] +['åĶ', '§'] +['çĨ', '¹'] +['è¼', '¯'] +['å¢', 'Ł'] +['é²', '²'] +['æĪ', 'Ľ'] +['èī', '¦'] +['èĬ', '®'] +['åĺ', 'Ł'] +['å¸', '¥'] +['å¿', '»'] +['çĮ', 'Ŀ'] +['å¯', 'µ'] +['è³', '¦'] +['èĽ', '¾'] +['æ»', '¾'] +['çĤ', 'ķ'] +['éĵ', '¬'] +['èĴ', '¿'] +['éĴ', '¨'] +['çĥ', 'Ļ'] +['ç²', 'ķ'] +['æĥ', '¦'] +['æº', '§'] +['é¢', 'į'] +['éħ', '£'] +['å³', '¦'] +['ç±', 'ģ'] +['çĥ', 'ĥ'] +['åĨ', 'Ĺ'] +['åı', 'ģ'] +['çĽ', '§'] +['ç½', 'µ'] +['éĴ', 'Ĺ'] +['å¬', 'ī'] +['è°', 'ı'] +['ç³', '§'] +['è¾', 'Ń'] +['æ·', '¬'] +['èŁ', 'Ĵ'] +['è¯', '©'] +['è¦', 'ĥ'] +['çĻ', 'ĸ'] +['é½', 'Ĵ'] +['çĪ', 'IJ'] +['ç®', 'į'] +['ç¼', 'İ'] +['ç£', 'º'] +['è¯', '«'] +['è¤', '²'] +['æĵ', 'ł'] +['èIJ', '¦'] +['çĿ', '¬'] +['è°', 'į'] +['éĦ', '°'] +['æł', '¾'] +['é¡', 'ı'] +['ç¸', '±'] +['æ¡', '¨'] +['éĨ', '¬'] +['è¥', '²'] +['è®', 'ª'] +['å©', 'º'] +['èį', 'Ł'] +['åĮ', 'Ŀ'] +['çĨ', 'ł'] +['èĽ', 'Ĭ'] +['æ¸', 'ļ'] +['å´', '½'] +['é²', '¤'] +['åķ', '°'] +['åĮ', 'ķ'] +['ä¸', 'IJ'] +['è®', '¥'] +['åı', '½'] +['åı', '¼'] +['çļ', '¿'] +['è¿', 'Ĥ'] +['åIJ', 'Ĩ'] +['å±', '¹'] +['èĩ', '¼'] +['è®', '¹'] +['é©', '®'] +['çº', '«'] +['æ±', 'ŀ'] +['æĬ', '¡'] +['èĭ', 'ĩ'] +['åIJ', 'ł'] +['åIJ', 'Ń'] +['åIJ', '®'] +['å²', 'ĸ'] +['ä½', 'ĥ'] +['çĭ', 'Ī'] +['åº', 'ĩ'] +['åIJ', 'Ŀ'] +['éĹ', '°'] +['æ±', '¹'] +['å¿', '±'] +['æĭ', 'Ħ'] +['æĭ', 'Ĺ'] +['èĮ', 'ī'] +['èĭ', 'Ľ'] +['èĮ', 'ģ'] +['çŁ', '¾'] +['èĻ', 'ı'] +['åij', '»'] +['åĴ', 'Ħ'] +['å¿', '¿'] +['èĤ', '®'] +['çĭ', 'ŀ'] +['çĸ', 'Ł'] +['çĸ', 'Ļ'] +['çĸ', 'ļ'] +['æ³', 'ŀ'] +['å¸', 'ļ'] +['å±', 'ī'] +['è¿', '¢'] +['é©', '¹'] +['ç', 'İ·'] +['çıĬ', 'ó'] +['çıĬó', 'ł'] +['çıĬół', 'Ħ'] +['çıĬółĦ', 'ģ'] +['æĮ', 'İ'] +['æĭ', '´'] +['åŀ', 'Ľ'] +['èį', '¤'] +['æ®', 'ĥ'] +['çĽ', '¹'] +['åĵ', 'Ĩ'] +['è´', '»'] +['æ¯', '¡'] +['çĭ', '°'] +['çĭ', '¡'] +['æŁ', 'Ĵ'] +['æģ', 'ĥ'] +['è¯', '¬'] +['è¢', 'Ħ'] +['è¯', '²'] +['èļ', '¤'] +['èĢ', 'Ļ'] +['åŁ', 'Ĥ'] +['æį', 'İ'] +['æį', 'Į'] +['æ¢', 'Ĩ'] +['é', 'ħĮ'] +['çł', '¾'] +['æ®', 'ī'] +['åĶ', 'ł'] +['æĻ', 'Į'] +['èļ', '£'] +['èļ', 'ª'] +['èļ', 'ĵ'] +['é¸', '¯'] +['åĶ', 'ģ'] +['åĶ', 'Ĩ'] +['åĢ', 'Ķ'] +['èĪ', 'Ģ'] +['è±', 'º'] +['èĥ', '°'] +['é¸', 'µ'] +['é¸', '³'] +['é¦', 'ģ'] +['ç¾', 'Ķ'] +['æ¶', '£'] +['æ¶', 'ķ'] +['æĤ', '¯'] +['è¯', '½'] +['è°', 'Ĩ'] +['ç¥', 'Ł'] +['ç»', '¢'] +['æį', 'º'] +['æį', '¶'] +['æį', '»'] +['æİ', 'Ĥ'] +['èı', 'ł'] +['èIJ', '¤'] +['éħ', 'Ĺ'] +['çľ', '¶'] +['åķ', 'Ħ'] +['èļ', '¯'] +['èĽ', 'Ģ'] +['åĶ', '¬'] +['å¸', '·'] +['éĵ', 'IJ'] +['éĵ', 'Ľ'] +['åģ', 'İ'] +['å¾', 'Ļ'] +['èĦ', '¯'] +['è±', 'ļ'] +['çĮ', 'ĸ'] +['çĹ', 'Ĭ'] +['æ¶', '®'] +['æĥ', 'Ń'] +['æĤ', '´'] +['æĥ', 'ĭ'] +['è°', 'ļ'] +['æı', '©'] +['æIJ', 'Ģ'] +['æIJ', 'Ķ'] +['æ¦', 'Ķ'] +['æ¤', 'Ń'] +['éĽ', '³'] +['åĸ', '³'] +['è·', 'Ľ'] +['èľ', 'ĵ'] +['èľ', 'Ĵ'] +['é¹', 'ĥ'] +['éĶ', 'Ħ'] +['çĶ', '¥'] +['çŃ', 'ı'] +['çĮ', '©'] +['çĮ', '¬'] +['çĮ', '¾'] +['çĹ', '¢'] +['çĹ', 'ª'] +['æĥ', '°'] +['çª', 'ĺ'] +['è°', '¤'] +['éļ', 'ĺ'] +['å©', '¿'] +['é¹', 'ī'] +['çij', 'Ļ'] +['æĸ', 'Ł'] +['æ¤', '¿'] +['éħ', 'ª'] +['éĽ', '¹'] +['åĹ', '¦'] +['è·', '·'] +['è·', 'º'] +['è·', '¤'] +['èľ', 'Ī'] +['èľ', 'Ĺ'] +['å¹', 'Į'] +['é¦', 'ı'] +['èª', 'Ĭ'] +['æ¼', 'ĵ'] +['è¤', 'Ĥ'] +['èĶ', 'Ĺ'] +['èĶ', '¼'] +['åħ', '¢'] +['è£', '³'] +['èľ', '»'] +['èĿ', 'ĩ'] +['åĺ', 'Ģ'] +['éĶ', '¹'] +['ç®', 'ķ'] +['ç®', '©'] +['çĺ', '©'] +['çĺ', 'Ł'] +['æ¼', '±'] +['å¯', '¥'] +['éª', '¡'] +['æĴ', 'µ'] +['æĴ', '¬'] +['è±', 'Į'] +['åĺ', '¹'] +['èĿ', 'ł'] +['èĿ', 'Į'] +['èĿ', 'Ĺ'] +['èĿ', 'Ļ'] +['éķ', 'IJ'] +['ç¨', '¼'] +['ç¯', 'ĵ'] +['èĨ', 'Ľ'] +['é²', '«'] +['çĺ', 'ª'] +['é²', '¨'] +['æĨ', 'Ķ'] +['ç¿', '©'] +['è¤', '¥'] +['ç¼', 'Ń'] +['åĻ', '©'] +['çĵ', '¢'] +['éľ', 'İ'] +['è¸', '±'] +['è¹', 'Ĥ'] +['èŁ', 'Ĩ'] +['é¹', '¦'] +['ç¯', '¡'] +['çĺ', '¸'] +['çª', '¿'] +['ç¼', '°'] +['èĹ', 'IJ'] +['è¹', 'ĭ'] +['èŁ', 'ĭ'] +['èŁ', 'Ģ'] +['èµ', '¡'] +['èĩ', 'Ĭ'] +['é³', 'Ħ'] +['ç³', 'ł'] +['æĩ', '¦'] +['åļ', '£'] +['éķ', '°'] +['é³', 'į'] +['ç°', '¸'] +['çĻ', '£'] +['é³', 'ĸ'] +['é¬', 'ĵ'] +['èł', 'ķ'] +['éľ', '¹'] +['èº', 'ı'] +['é»', '¯'] +['çĵ', '¤'] +['çŁ', 'Ĺ'] +['ä¹', 'Ĥ'] +['ä¹', 'ľ'] +['åħ', 'Ģ'] +['å¼', 'ĭ'] +['åŃ', 'ij'] +['åŃ', 'ĵ'] +['å¹', 'º'] +['äº', 'ĵ'] +['å', '»¿'] +['ä¸', 'ı'] +['åį', 'ħ'] +['ä»', 'ĥ'] +['ä»', 'ī'] +['ä»', 'Ĥ'] +['åĪ', 'Ī'] +['çĪ', '»'] +['åį', 'ŀ'] +['éĹ', '©'] +['è®', '£'] +['å¤', '¬'] +['çĪ', '¿'] +['æ¯', 'ĭ'] +['éĤ', 'Ĺ'] +['éĤ', 'Ľ'] +['èī', '½'] +['èī', '¿'] +['åı', 'µ'] +['ä¸', 'ķ'] +['åĮ', 'ľ'] +['åĬ', '¢'] +['åį', 'Ł'] +['åı', '±'] +['åı', '»'] +['ä»', '¨'] +['ä»', 'Ł'] +['ä»', '¡'] +['ä»', '«'] +['ä»', 'ŀ'] +['åį', '®'] +['æ°', 'IJ'] +['çĬ', '°'] +['åĪ', 'į'] +['éĤ', 'Ŀ'] +['éĤ', 'Ļ'] +['è®', '¦'] +['è®', '§'] +['è®', '«'] +['å°', '»'] +['éĺ', '¡'] +['å°', 'ķ'] +['å¼', 'ģ'] +['èĢ', 'Ĵ'] +['çİ', 'İ'] +['çİ', 'ij'] +['åľ', '¬'] +['æī', '¦'] +['åľ', 'ª'] +['åľ', '¹'] +['æī', 'ª'] +['åľ', '®'] +['åľ', '¯'] +['èĬ', 'Ĭ'] +['èĬ', 'į'] +['èĬ', 'Ħ'] +['èĬ', '¨'] +['èĬ', 'ij'] +['èĬ', 'İ'] +['èĬ', 'Ĺ'] +['äº', 'ĺ'] +['åİ', 'į'] +['å¤', '¼'] +['æĪ', 'į'] +['å°', '¥'] +['ä¹', '©'] +['æĹ', '¯'] +['æĽ', '³'] +['å²', 'Į'] +['å±', 'º'] +['åĩ', '¼'] +['åĽ', '¡'] +['éĴ', 'ĩ'] +['ç¼', '¶'] +['æ°', 'ĺ'] +['æ°', 'ĸ'] +['çī', 'Ŀ'] +['ä¼', 'İ'] +['ä¼', 'Ľ'] +['ä¼', '¢'] +['ä½', '¤'] +['ä»', 'µ'] +['ä¼', '¥'] +['ä¼', '§'] +['ä¼', 'ī'] +['ä¼', '«'] +['åĽ', 'Ł'] +['æ±', 'Ĩ'] +['åĪ', 'ĸ'] +['å¤', 'Ļ'] +['æĹ', '®'] +['åĪ', 'İ'] +['çĬ', '·'] +['çĬ', '¸'] +['èĪ', 'Ľ'] +['åĩ', '«'] +['é', 'Ĥ¬'] +['é¥', '§'] +['æ±', 'Ķ'] +['æ±', 'ľ'] +['æ±', 'Ĭ'] +['å¿', 'ĸ'] +['å¿', 'ı'] +['è®', '´'] +['è®', 'µ'] +['è®', '·'] +['èģ', '¿'] +['èī', '®'] +['åİ', '¾'] +['å¦', 'ģ'] +['çº', '¡'] +['çº', '£'] +['çº', '¥'] +['çº', '¨'] +['çİ', 'ķ'] +['çİ', 'Ļ'] +['æĬ', 'Ł'] +['æĬ', 'Ķ'] +['åľ', '»'] +['åĿ', 'į'] +['æĬ', 'ĥ'] +['ã§', 'IJ'] +['èĬ', '«'] +['èĬ', '¾'] +['èĭ', 'Ī'] +['èĭ', '£'] +['èĭ', 'ĭ'] +['èĬ', '¼'] +['èĭ', 'Į'] +['èĭ', 'ģ'] +['èĬ', '©'] +['èĬ', 'ª'] +['èĬ', '¡'] +['èĬ', 'Ł'] +['èĭ', 'Ħ'] +['èĭ', 'İ'] +['èĭ', '¡'] +['æĿ', 'Į'] +['æĿ', 'ĵ'] +['æĿ', 'Ī'] +['å¿', 'ij'] +['åŃ', 'Ľ'] +['éĤ', '´'] +['éĤ', '³'] +['å¥', 'ģ'] +['è±', 'ķ'] +['å¿', 'Ĵ'] +['æ¬', '¤'] +['è½', '«'] +['è¿', 'ĵ'] +['éĤ', '¶'] +['å¿', 'IJ'] +['åį', '£'] +['éĤ', 'º'] +['æĹ', '°'] +['åij', 'ĭ'] +['åij', 'Ĵ'] +['åij', 'ĵ'] +['åij', 'Ķ'] +['åij', 'ĸ'] +['æĹ', '¸'] +['åIJ', '¡'] +['èĻ', '¬'] +['åIJ', '½'] +['åIJ', '£'] +['åIJ', '²'] +['å¸', 'ı'] +['å²', 'Ī'] +['å²', 'ĺ'] +['åħ', 'ķ'] +['åĽ', 'µ'] +['åĽ', '«'] +['éĴ', 'Ĭ'] +['éĴ', 'ĭ'] +['é', 'ĴĮ'] +['è¿', 'ķ'] +['æ°', 'Ļ'] +['æ°', 'ļ'] +['çī', '¤'] +['ä½', 'ŀ'] +['ä½', 'ļ'] +['ä½', 'Ŀ'] +['ä½', 'Ĺ'] +['å½', '·'] +['ä½', 'ĺ'] +['ä½', '¥'] +['è±', '¸'] +['åĿ', 'Į'] +['èĤ', 'Ł'] +['å¥', 'Ĥ'] +['åĬ', '¬'] +['çĭ', 'ģ'] +['é¸', 'ł'] +['é¥', '¨'] +['é¥', '©'] +['é¥', '«'] +['é¥', '¬'] +['åº', 'ij'] +['åº', 'ĭ'] +['çĸ', 'Ķ'] +['çĸ', 'ĸ'] +['èĤ', 'ĵ'] +['éĹ', '±'] +['éĹ', '³'] +['çĤ', 'Ģ'] +['æ²', '£'] +['æ²', 'ħ'] +['æ²', 'Ķ'] +['æ²', '¤'] +['æ²', 'ı'] +['æ²', 'ļ'] +['æ±', '©'] +['æ±', '¨'] +['æ²', '¨'] +['æ±', '´'] +['æ²', 'Ĩ'] +['æ²', '©'] +['æ³', 'IJ'] +['æĢ', 'ĥ'] +['æĢ', 'Ħ'] +['å¿', '¡'] +['å¿', '¤'] +['å¿', '¾'] +['æĢ', 'ħ'] +['å¿', 'ª'] +['æĢ', 'Ĩ'] +['å¿', 'Ń'] +['å¿', '¸'] +['è¯', 'Ĥ'] +['è¯', 'ĥ'] +['è¯', 'ħ'] +['è¯', 'ĭ'] +['è¯', 'Į'] +['è¯', 'Ĵ'] +['éĻ', 'Ĥ'] +['éĻ', 'ī'] +['å¦', '©'] +['å¦', 'ª'] +['å¦', '£'] +['å¦', 'Ĺ'] +['å¦', '«'] +['å§', 'Ĵ'] +['å¦', '¤'] +['åĬ', 'Ń'] +['åĪ', 'Ń'] +['éĤ', '°'] +['çº', 'Ń'] +['çº', '°'] +['çº', '´'] +['çİ', '¡'] +['çİ', 'Ń'] +['çİ', 'ł'] +['çİ', '¢'] +['çİ', '¦'] +['çĽ', 'Ĥ'] +['å¿', 'Ŀ'] +['åĮ', '¦'] +['åĿ', '©'] +['æĬ', '¨'] +['æĭ', '¤'] +['åĿ', '«'] +['æĭ', 'Ī'] +['åŀ', 'Ĩ'] +['æĬ', '»'] +['åĬ', '¼'] +['æĭ', 'ĥ'] +['æĭ', 'Ĭ'] +['åĿ', '¼'] +['åĿ', '»'] +['ã§', 'Ł'] +['åĿ', '¨'] +['åĿ', 'Ń'] +['æĬ', '¿'] +['åĿ', '³'] +['èĭ', '·'] +['èĭ', '¤'] +['èĮ', 'ı'] +['èĭ', '«'] +['èĭ', 'ľ'] +['èĭ', '´'] +['èĭ', 'Ĵ'] +['èĭ', 'ĺ'] +['èĮ', 'Į'] +['èĭ', '»'] +['èĭ', 'ĵ'] +['èĮ', 'ļ'] +['èĮ', 'Ĩ'] +['èĮ', 'ij'] +['èĮ', 'ĵ'] +['èĮ', 'Ķ'] +['èĮ', 'ķ'] +['è', 'ĮĢ'] +['èĭ', 'ķ'] +['æŀ', '¥'] +['æŀ', 'ĩ'] +['æĿ', 'ª'] +['æĿ', '³'] +['æŀ', '§'] +['æĿ', 'µ'] +['æŀ', '¨'] +['æŀ', 'ŀ'] +['æŀ', 'ĭ'] +['æĿ', '»'] +['æĿ', '·'] +['æĿ', '¼'] +['çŁ', '¸'] +['ç', 'łĢ'] +['åĪ', '³'] +['å¥', 'Ħ'] +['æ®', 'ģ'] +['éĥ', 'ı'] +['è½', 'Ń'] +['éĥ', 'ħ'] +['é¸', '¢'] +['çĽ', '±'] +['æĺ', 'Ļ'] +['æĿ', '²'] +['æĺ', 'ĥ'] +['åĴ', 'Ĥ'] +['åij', '¸'] +['æĺ', 'Ģ'] +['æĹ', '»'] +['æĺ', 'ī'] +['çĤ', 'ħ'] +['çķ', 'Ģ'] +['èĻ', '®'] +['åĴ', 'Ģ'] +['åij', '·'] +['é»', '¾'] +['åij', '±'] +['åij', '¤'] +['åĴ', 'Ĩ'] +['åĴ', 'Ľ'] +['åij', '¶'] +['åij', '£'] +['åĴ', 'Ŀ'] +['å²', '¢'] +['å²', '¿'] +['å²', '¬'] +['å²', '«'] +['å¸', 'Ļ'] +['å²', '£'] +['å³', 'ģ'] +['åĪ', '¿'] +['å²', '·'] +['åī', 'Ģ'] +['å¸', 'Ķ'] +['å³', 'Ħ'] +['æ²', 'ĵ'] +['åĽ', '¹'] +['ç½', 'Ķ'] +['éĴ', 'į'] +['éĴ', 'İ'] +['éĴ', 'ı'] +['éĴ', 'Ĵ'] +['éĴ', 'ķ'] +['éĤ', '¾'] +['è¿', '®'] +['çī', '¦'] +['ç«', 'º'] +['è¿', '¤'] +['ä½', '¶'] +['ä¾', 'ij'] +['ä¾', 'ī'] +['èĩ', '¾'] +['ä¾', 'Ĺ'] +['ä¾', 'ı'] +['ä¾', '©'] +['ä½', '»'] +['ä½', '¾'] +['ä¾', 'ª'] +['ä½', '¼'] +['ä½', '¯'] +['ä¾', '¬'] +['å¸', 'Ľ'] +['ä¾', 'Ķ'] +['å¾', 'Ĥ'] +['åĪ', '½'] +['éĥ', 'Ħ'] +['ç±', '´'] +['çĵ', '®'] +['æĪ', 'Ĺ'] +['èĤ', '¼'] +['äı', 'Ŀ'] +['èĤ', '±'] +['èĤ', '«'] +['è¿', '©'] +['éĥ', 'ĩ'] +['çĭ', 'İ'] +['çĭ', 'į'] +['çĭ', 'Ĵ'] +['åĴ', 'İ'] +['é¥', '¯'] +['é¥', '´'] +['åĨ', '½'] +['åĨ', '¼'] +['åº', 'ĸ'] +['çĸ', 'ł'] +['çĸ', 'Ŀ'] +['åħ', 'ĸ'] +['åĬ', '¾'] +['ð¬', 'ī'] +['ð¬ī', '¼'] +['çĤ', 'ĺ'] +['çĤ', 'Ŀ'] +['çĤ', 'Ķ'] +['æ³', 'Ķ'] +['æ²', 'Ń'] +['æ³', '·'] +['æ³', '±'] +['æ³', 'ħ'] +['æ³', 'ł'] +['æ³', 'º'] +['æ³', 'ĸ'] +['æ³', '«'] +['æ³', '®'] +['æ²', '±'] +['æ³', '¯'] +['æĢ', 'Ļ'] +['æĢ', 'µ'] +['æĢ', '¦'] +['æĢ', 'Ľ'] +['æĢ', 'ı'] +['æĢ', 'į'] +['ã', '¤'] +['ã¤', 'ĺ'] +['æĢ', '©'] +['æĢ', '«'] +['æĢ', '¿'] +['å®', 'ķ'] +['ç©', '¹'] +['å®', 'ĵ'] +['è¯', 'ĵ'] +['è¯', 'Ķ'] +['è¯', 'ĸ'] +['è¯', 'ĺ'] +['æĪ', '¾'] +['è¯', 'Ļ'] +['æĪ', '½'] +['éĥ', 'ĵ'] +['è¡', '©'] +['ç¥', 'Ĩ'] +['ç¥', 'İ'] +['ç¥', 'ĩ'] +['è¯', 'ľ'] +['è¯', 'Ł'] +['è¯', '£'] +['è¯', '¤'] +['è¯', '§'] +['è¯', '¨'] +['æĪ', 'ķ'] +['éĻ', 'Ķ'] +['å¦', '²'] +['å¦', '¯'] +['å§', 'Ĺ'] +['å¸', 'ij'] +['åŃ', '¥'] +['é©', '½'] +['èĻ', '±'] +['è¿', '¨'] +['ç»', 'Ģ'] +['ç»', 'ģ'] +['ç»', 'Ĥ'] +['é©', '·'] +['é©', '¸'] +['ç»', 'ī'] +['ç»', 'Į'] +['éª', 'Ģ'] +['çĶ', '¾'] +['çı', 'ı'] +['çı', 'IJ'] +['çı', 'ij'] +['çİ', '³'] +['é¡', '¸'] +['çı', 'ī'] +['çı', 'Ī'] +['æĭ', '®'] +['åŀ', 'Ń'] +['æĮ', 'Ŀ'] +['æĮ', 'ŀ'] +['åŀ', '¤'] +['èµ', '³'] +['è´', '²'] +['åŀ', '±'] +['åŀ', 'Į'] +['åŀ', '§'] +['åŀ', 'ĵ'] +['æĮ', '¦'] +['åŀ', 'ł'] +['èį', 'ļ'] +['èį', 'ij'] +['è´', '³'] +['èį', 'ľ'] +['èİ', 'Ĵ'] +['èĮ', '¼'] +['èĮ', '´'] +['èĮ', '±'] +['èİ', 'Ľ'] +['èį', 'ŀ'] +['èĮ', '¯'] +['èį', 'ı'] +['èį', 'ĩ'] +['èį', 'ĥ'] +['èį', 'ł'] +['èĮ', 'Ń'] +['åŀ', '©'] +['èį', '¥'] +['èį', '¦'] +['èį', '¨'] +['èį', '©'] +['åī', 'ĭ'] +['èį', 'ª'] +['èį', '¬'] +['èį', '®'] +['æŁ', '°'] +['æł', 'ī'] +['æŁ', 'ĺ'] +['æł', 'Ĭ'] +['æŁ', '©'] +['æŀ', '°'] +['æł', 'Į'] +['æŁ', 'Ļ'] +['æŀ', 'µ'] +['æŀ', '³'] +['æŁ', 'ŀ'] +['æŁ', 'Ŀ'] +['æł', 'Ģ'] +['æŁ', '¢'] +['æł', 'İ'] +['æŁ', 'Ī'] +['æŁ', 'ģ'] +['æŀ', '·'] +['æŁ', '½'] +['åī', 'Į'] +['éħ', 'Ĭ'] +['éĥ', '¦'] +['çĶ', 'Ń'] +['çł', 'Ĺ'] +['çł', 'ĺ'] +['çł', 'Ĵ'] +['æĸ', '«'] +['çł', 'Ń'] +['çł', 'ľ'] +['èĢ', '·'] +['èĻ', 'º'] +['æ®', 'Ĥ'] +['æ®', 'ĩ'] +['æ®', 'Ħ'] +['è½', '±'] +['è½', '²'] +['è½', '³'] +['è½', '¶'] +['è½', '¸'] +['èĻ', '¿'] +['æ¯', 'ĸ'] +['è§', 'ĩ'] +['å°', 'ľ'] +['åĵ', 'IJ'] +['çľ', 'Ħ'] +['çľ', 'į'] +['ðł', '³'] +['ðł³', 'IJ'] +['éĥ', '¢'] +['çľ', 'ĩ'] +['çľ', 'Ĭ'] +['çľ', 'Ī'] +['ç¦', 'º'] +['åĵ', 'Ĥ'] +['åĴ', '´'] +['æĽ', '·'] +['æĺ', '´'] +['åĴ', '¦'] +['åĵ', 'ĵ'] +['åĵ', 'Ķ'] +['çķ', 'İ'] +['åij', '²'] +['èĥ', 'Ħ'] +['çķ', 'ĭ'] +['çķ', 'Ī'] +['èĻ', '¼'] +['èĻ', '»'] +['çĽ', 'ħ'] +['åĴ', '£'] +['åĵ', 'ķ'] +['åī', 'IJ'] +['éĥ', '§'] +['åĴ', '»'] +['åĽ', '¿'] +['åĴ', '¿'] +['åĵ', 'Į'] +['åĵ', 'Ļ'] +['åĵ', 'ļ'] +['åĴ', '©'] +['åĴ', '¤'] +['åĵ', 'Ŀ'] +['åĵ', 'ı'] +['åĵ', 'ŀ'] +['å³', '£'] +['ç½', 'ĺ'] +['å³', 'Ĵ'] +['å³', '¤'] +['å³', 'ĭ'] +['è´', '¶'] +['éĴ', 'ļ'] +['éĴ', '¡'] +['éĴ', '£'] +['éĴ', '¤'] +['éĴ', '«'] +['æ°', '¡'] +['çī', '¯'] +['éĥ', 'ľ'] +['ç§', 'ķ'] +['ç§', 'Ń'] +['ç«', '½'] +['ç¬', 'Ī'] +['ä¿', '¦'] +['ä¿', '¨'] +['ä¿', 'ħ'] +['åı', 'Ł'] +['åŀ', '¡'] +['çī', '®'] +['ä¿', '£'] +['ä¿', 'ļ'] +['çļ', 'Ī'] +['ä¿', 'Ł'] +['éĢ', 'ħ'] +['å¾', 'ĩ'] +['å¾', 'ī'] +['èĪ', '¢'] +['éĥ', 'Ĺ'] +['ä¿', 'İ'] +['éĥ', '¤'] +['çĪ', '°'] +['éĥ', 'Ľ'] +['çĵ', '´'] +['èĥ', '¨'] +['èĥ', 'ª'] +['èĥ', 'Ľ'] +['èĥ', 'Ĥ'] +['èĥ', 'Ļ'] +['èĥ', 'į'] +['èĥ', 'Ĺ'] +['è', 'ĥĿ'] +['æľ', 'IJ'] +['èĥ', '«'] +['é¸', '¨'] +['åĮ', 'į'] +['çĭ', '¨'] +['çĭ', '¯'] +['é£', 'ij'] +['çĭ', '©'] +['çĭ', '²'] +['è¨', 'ĩ'] +['éĢ', 'Ħ'] +['æĺ', 'Ŀ'] +['é¥', '·'] +['é¥', '¸'] +['é¥', '¹'] +['åŃ', 'ª'] +['å¨', 'Ī'] +['åº', '¥'] +['çĸ', '¬'] +['çĸ', '£'] +['çĸ', '¥'] +['çĸ', 'Ń'] +['åº', 'ł'] +['ç«', 'ij'] +['é£', 'Ĵ'] +['éĹ', '¼'] +['éĹ', '¾'] +['éĹ', '¿'] +['éĺ', 'Ĥ'] +['ç¾', 'ij'] +['è¿', '¸'] +['ç±', '¼'] +['éħ', 'ĭ'] +['çĤ', '»'] +['çĥ', 'Ģ'] +['çĤ', '·'] +['æ´', '±'] +['æ´', '¹'] +['æ´', '§'] +['æ´', 'Į'] +['æµ', 'ĥ'] +['æ´', 'ĩ'] +['æ´', 'Ħ'] +['æ´', 'Ļ'] +['æ¶', 'İ'] +['æ´', 'İ'] +['æ´', '«'] +['æµ', 'į'] +['æ´', '®'] +['æ´', 'µ'] +['æµ', 'Ĵ'] +['æµ', 'Ķ'] +['æµ', 'ķ'] +['æ´', '³'] +['æģ', '¸'] +['æģ', 'ĵ'] +['æģ', '¹'] +['æģ', '«'] +['æģ', '»'] +['æģ', 'Ĥ'] +['æģ', 'ª'] +['æģ', '½'] +['å®', '¥'] +['æī', 'ĥ'] +['è¡', '²'] +['è¡', '½'] +['è¡', '¿'] +['è¢', 'Ĥ'] +['ç¥', 'ľ'] +['ç¥', 'ĵ'] +['ç¥', 'ļ'] +['è¯', '®'] +['ç¥', 'Ĺ'] +['ç¥', '¢'] +['è¯', '°'] +['è¯', '³'] +['é¸', '©'] +['æĺ', '¶'] +['åĴ', '«'] +['å¼', 'Ń'] +['çī', 'ģ'] +['èĥ', '¥'] +['éĻ', 'Ł'] +['å§', '®'] +['å¨', 'Ĩ'] +['å§', 'Ŀ'] +['å§', '£'] +['å§', 'ĺ'] +['å§', '¹'] +['ç¾', '¿'] +['çĤ', '±'] +['çŁ', 'ľ'] +['ç»', 'Ķ'] +['éª', 'ģ'] +['éª', 'ħ'] +['ç»', 'Ĺ'] +['ç»', 'Ľ'] +['éª', 'Ī'] +['èĢ', 'ĸ'] +['æĮ', 'Ī'] +['çı', '¥'] +['çı', 'Ļ'] +['é¡', '¼'] +['çı', '°'] +['çı', '©'] +['çı', '§'] +['çı', '£'] +['çı', 'ŀ'] +['çIJ', '¤'] +['çı', '²'] +['æģ', 'ļ'] +['åŁ', 'ķ'] +['åŁ', 'ĺ'] +['åŁ', 'Ļ'] +['åŁ', 'ļ'] +['æĮ', '¹'] +['èĢ', 'Ĩ'] +['èĢ', 'Ħ'] +['åŁ', 'Ĵ'] +['æį', 'ĭ'] +['è´', '½'] +['åŀ', '¸'] +['æį', 'ĥ'] +['çĽ', 'į'] +['èį', '¸'] +['èİ', '³'] +['èİ', '´'] +['èİ', 'ª'] +['èİ', 'ł'] +['èİ', 'ľ'] +['èİ', 'ħ'] +['èį', '¼'] +['èİ', '©'] +['èį', '½'] +['èİ', '¸'] +['èį', '»'] +['èİ', '¨'] +['é¸', 'ª'] +['èİ', '¼'] +['æł', '²'] +['æł', '³'] +['æ¡', '¡'] +['æ¡', 'İ'] +['æ¡', '¢'] +['æ¡', '¤'] +['æ¢', 'ĥ'] +['æł', 'Ŀ'] +['æ¡', 'ķ'] +['æ¡', 'ģ'] +['æ¡', '§'] +['æ¡', 'ħ'] +['æł', 'Ł'] +['æ¡', 'ī'] +['æł', '©'] +['éĢ', 'ij'] +['éĢ', 'ĭ'] +['å½', '§'] +['é¬', '²'] +['è±', 'ĩ'] +['éħ', 'IJ'] +['éĢ', '¦'] +['åİ', 'Ŀ'] +['åŃ', '¬'] +['çł', 'Ŀ'] +['çł', '¹'] +['çł', '§'] +['çł', '·'] +['çł', 'Ł'] +['çł', '¼'] +['çł', '¥'] +['çł', '£'] +['åī', 'ŀ'] +['çł', '»'] +['è½', '¼'] +['è½', '¾'] +['è¾', 'Ĥ'] +['é¸', '«'] +['è¶', '¸'] +['é¾', 'Ģ'] +['é¸', '¬'] +['èĻ', 'Ķ'] +['çľ', '¬'] +['åĶ', 'Ľ'] +['çľ', 'Ļ'] +['åĵ', '§'] +['åĵ', '½'] +['æĻ', 'ģ'] +['é¸', '®'] +['è¶', 'µ'] +['è¶', '¿'] +['çķ', 'Ľ'] +['èļ', '¨'] +['èļ', 'ľ'] +['èļ', 'į'] +['èļ', 'ĭ'] +['èļ', '¬'] +['èļ', 'Ŀ'] +['èļ', '§'] +['åĶ', '¢'] +['åľ', 'Ħ'] +['åĶ', '£'] +['åĶ', 'ı'] +['çĽ', 'İ'] +['åĶ', 'ij'] +['å´', 'Ĥ'] +['å´', 'ĥ'] +['ç½', '¡'] +['ç½', 'Ł'] +['è§', 'Ĭ'] +['èµ', 'ħ'] +['éĴ', '²'] +['éĴ', 'µ'] +['éĴ', '¹'] +['éĴ', 'º'] +['éĴ', '½'] +['éĴ', '¼'] +['éĴ', '¿'] +['éĵ', 'Ģ'] +['éĵ', 'Ħ'] +['éĵ', 'Ĩ'] +['éĵ', 'Ī'] +['éĵ', 'ī'] +['éĵ', 'Ĭ'] +['éĵ', 'ĭ'] +['éĵ', 'Į'] +['é', 'ĵį'] +['ä', '¥'] +['ä¥', '½'] +['éĵ', 'İ'] +['æ°', '©'] +['æ°', '¤'] +['æ°', '¦'] +['æ¯', 'ª'] +['èĪ', 'IJ'] +['ç§', '£'] +['ç§', '«'] +['çĽ', 'ī'] +['ç¬', 'Ħ'] +['ç¬', 'ķ'] +['ç¬', 'Ĭ'] +['ç¬', 'ı'] +['ç¬', 'Ĩ'] +['ä¿', '¸'] +['ä¿', 'µ'] +['åģ', 'Į'] +['ä¿', '³'] +['ä¿', '¶'] +['åĢ', '¬'] +['åĢ', 'ı'] +['æģ', 'ģ'] +['åĢ', 'Ń'] +['ä¿', '¾'] +['åĢ', 'ľ'] +['éļ', '¼'] +['éļ', '½'] +['åĢ', 'Į'] +['åĢ', '¥'] +['èĩ', '¬'] +['éĥ', '«'] +['åĢ', '¨'] +['è¡', 'Ħ'] +['é¢', 'Ģ'] +['å¾', 'ķ'] +['èĪ', '«'] +['è¡', '¾'] +['èĥ', '¯'] +['èĥ', '±'] +['èĥ', '´'] +['èĥ', 'Ń'] +['èĦ', 'į'] +['èĥ', '¼'] +['èĦ', 'Ĵ'] +['é¸', '±'] +['é¸', '²'] +['çĭ', '·'] +['çĮ', 'ģ'] +['çĭ', '³'] +['çĮ', 'ĥ'] +['çĭ', 'º'] +['éĢ', 'ĸ'] +['æ¡', 'Ģ'] +['é¥', '½'] +['åĩ', 'ĩ'] +['æĮ', 'Ľ'] +['äº', '³'] +['çĸ', '³'] +['çĸ', '´'] +['çĸ', '¸'] +['çĸ', '½'] +['çĹ', 'Ī'] +['çĸ', '±'] +['çĹ', 'Ĥ'] +['çĹ', 'ī'] +['è¡', '®'] +['é¢', 'ĥ'] +['æģ', '£'] +['æĹ', 'Ĩ'] +['æĹ', 'Ħ'] +['æĹ', 'ĥ'] +['éĺ', 'ĥ'] +['éĺ', 'Ħ'] +['è¨', 'ļ'] +['éĺ', 'Ĩ'] +['æģ', 'Ļ'] +['ç²', 'ij'] +['çĥ', 'ľ'] +['çĥ', '©'] +['çĥ', 'Ĭ'] +['åī', '¡'] +['éĥ', '¯'] +['çĥ', '¬'] +['æ¶', 'ij'] +['æµ', '¯'] +['æ¶', 'ŀ'] +['æ¶', 'Ł'] +['å¨', 'ij'] +['æ¶', 'ł'] +['æµ', 'ŀ'] +['æ¶', 'ĵ'] +['æµ', '¥'] +['æ¶', 'Ķ'] +['æµ', 'ľ'] +['æµ', 'ł'] +['æµ', '£'] +['æĤ', 'ļ'] +['æ', 'ĤŃ'] +['æĤ', 'Ŀ'] +['æĤ', 'Ĵ'] +['æĤ', 'Į'] +['æĤ', 'Ľ'] +['çª', 'Ī'] +['åī', 'ľ'] +['è¯', '¹'] +['è¯', '¼'] +['è¢', 'Ĵ'] +['è¢', '¢'] +['è¯', '¿'] +['è°', 'Ģ'] +['è°', 'Ĥ'] +['è°', 'Ħ'] +['è°', 'ĩ'] +['å±', 'IJ'] +['å±', 'Ļ'] +['éĻ', '¬'] +['åĭ', 'IJ'] +['å¥', 'ĺ'] +['çī', 'Ĥ'] +['èļ', '©'] +['éĻ', '²'] +['å¨', 'Į'] +['å¨', 'ī'] +['å¨', '²'] +['å¨', '´'] +['å¨', '£'] +['å¨', 'ĵ'] +['å©', 'Ģ'] +['çķ', 'ļ'] +['éĢ', '¡'] +['ç»', 'ł'] +['éª', 'Ĭ'] +['ç»', '¡'] +['éª', 'ĭ'] +['ç»', '¦'] +['ç»', '¨'] +['éª', 'İ'] +['éĤ', 'ķ'] +['é¸', '¶'] +['å½', 'Ĺ'] +['èĢ', 'ľ'] +['çĦ', 'ĺ'] +['èĪ', 'Ĥ'] +['çIJ', 'ı'] +['çIJ', 'ĩ'] +['éº', '¸'] +['æı', '¶'] +['åŁ', '´'] +['åŁ', '¯'] +['æį', '¯'] +['æİ', '³'] +['æİ', '´'] +['åŁ', '¸'] +['åŁ', 'µ'] +['èµ', '§'] +['åŁ', '¤'] +['æį', 'Ń'] +['éĢ', 'µ'] +['åŁ', 'Ŀ'] +['åł', 'ĭ'] +['åł', 'į'] +['æİ', '¬'] +['é¸', '·'] +['æį', '½'] +['æİ', 'Ĭ'] +['åł', 'ī'] +['æİ', '¸'] +['æį', '©'] +['æİ', '®'] +['æĤ', '«'] +['åŁ', 'Ń'] +['åŁ', '½'] +['æİ', 'ĩ'] +['æİ', '¼'] +['èģ', 'ĥ'] +['èIJ', 'ģ'] +['èı', 'ĺ'] +['åł', 'ĩ'] +['èIJ', 'ĺ'] +['èIJ', 'ĭ'] +['èı', '½'] +['èı', 'ĸ'] +['è', 'IJľ'] +['èIJ', '¸'] +['èIJ', 'ij'] +['æ£', '»'] +['èı', 'Ķ'] +['èı', 'Ł'] +['èIJ', 'ı'] +['èı', '¹'] +['èı', 'ª'] +['èı', 'ħ'] +['èı', 'Ģ'] +['èı', '°'] +['èı', '¡'] +['æ¢', '¿'] +['æ¢', 'ı'] +['è§', 'ĭ'] +['æ¡', '´'] +['æ¡', '·'] +['æ£', 'ģ'] +['æ¡', '«'] +['æ£', 'Ĥ'] +['åķ', '¬'] +['éĥ', '¾'] +['æķ', 'ķ'] +['è±', 'ī'] +['éĦ', 'Ħ'] +['éħ', 'ŀ'] +['ç¡', 'İ'] +['ç¡', 'Ń'] +['ç¡', 'ĸ'] +['ç¡', 'Ĺ'] +['ç¡', 'IJ'] +['ç¡', 'ĩ'] +['ç¡', 'Į'] +['é¸', '¸'] +['çĵ', 'ł'] +['åĮ', 'ı'] +['åİ', '©'] +['æ®', 'Ĵ'] +['æ®', 'ĵ'] +['æ®', 'į'] +['èµ', 'ī'] +['éĽ', '©'] +['è¾', 'Ħ'] +['åł', 'ij'] +['çľ', 'Ń'] +['çľ', '¦'] +['åķ', '§'] +['æĻ', '¡'] +['æĻ', '¤'] +['çľ', 'µ'] +['åľ', 'Ĭ'] +['åĸ', 'ı'] +['åķ', 'ī'] +['åĭ', 'ĸ'] +['æĻ', 'ŀ'] +['åĶ', 'µ'] +['æĻ', 'Ĺ'] +['åķ', 'Ń'] +['çķ', '¦'] +['è¶', 'º'] +['åķ', '®'] +['è·', 'Ħ'] +['èļ', '¶'] +['è', 'ĽĦ'] +['èĽ', 'İ'] +['èĽ', 'Ĩ'] +['èļ', '°'] +['åľ', 'ī'] +['èļ', '±'] +['èĽ', 'ī'] +['èĽ', 'ı'] +['èļ', '´'] +['åķ', 'ģ'] +['åķ', 'ķ'] +['åĶ', '¿'] +['åķ', 'IJ'] +['åĶ', '¼'] +['åĶ', '·'] +['åķ', 'ĸ'] +['åķ', 'µ'] +['åķ', '¶'] +['åķ', '·'] +['åĶ', '³'] +['åĶ', '°'] +['åķ', 'ľ'] +['å¸', '»'] +['å´', 'ļ'] +['å´', '¦'] +['å¸', '¼'] +['å´', '®'] +['å´', '¤'] +['å´', 'Ĩ'] +['èµ', 'ĩ'] +['èµ', 'Ī'] +['èµ', 'Ĭ'] +['éĵ', 'ij'] +['éĵ', 'Ĵ'] +['éĵ', 'Ĺ'] +['éĵ', 'Ļ'] +['éĵ', 'Ł'] +['éĵ', '¡'] +['éĵ', '¢'] +['éĵ', '£'] +['éĵ', '¤'] +['éĵ', '§'] +['éĵ', '¨'] +['éĵ', '©'] +['éĵ', 'ª'] +['éĵ', '«'] +['éĵ', '¯'] +['éĵ', '°'] +['éĵ', '±'] +['éĵ', '³'] +['éĵ', 'µ'] +['éĵ', '·'] +['çī', '¾'] +['é¸', '¹'] +['ç§', '¾'] +['éĢ', '¶'] +['ç¬', 'º'] +['çŃ', 'ĩ'] +['ç¬', '¸'] +['ç¬', 'ª'] +['ç¬', '®'] +['ç¬', 'ł'] +['ç¬', '¥'] +['ç¬', '¤'] +['ç¬', '³'] +['ç¬', '¾'] +['ç¬', 'ŀ'] +['åģ', '¾'] +['åģ', 'ĥ'] +['åģ', 'ķ'] +['åģ', 'Ī'] +['åĤ', 'Ģ'] +['åģ', '¬'] +['åģ', '»'] +['çļ', 'ij'] +['çļ', 'İ'] +['é¸', '»'] +['å¾', 'ľ'] +['èĪ', '¸'] +['èĪ', '»'] +['èĪ', '´'] +['èĪ', '·'] +['é¾', 'Ľ'] +['ç¿', 'İ'] +['èĦ', '¬'] +['èĦ', 'ĺ'] +['èĦ', '²'] +['åĮ', 'IJ'] +['çĮ', 'Ĺ'] +['çĮ', '¡'] +['çĮ', 'ŀ'] +['æĸ', 'Ľ'] +['çĮ', 'ķ'] +['é¦', 'Ĺ'] +['é¦', 'ĥ'] +['é¦', 'Ħ'] +['é¸', '¾'] +['åº', '¹'] +['åº', '¾'] +['çĹ', 'Ķ'] +['çĹ', 'į'] +['ç¿', 'Ĭ'] +['æĹ', 'Į'] +['æĹ', 'İ'] +['è¢', '¤'] +['éĺ', 'ĩ'] +['éĺ', 'Ī'] +['éĺ', 'ī'] +['éĺ', 'Ĭ'] +['éĺ', 'ĭ'] +['éĺ', 'į'] +['éĺ', 'ı'] +['ç¾', 'Ł'] +['ç²', 'Ŀ'] +['çĦ', 'IJ'] +['çĦ', 'ĵ'] +['çĦ', 'Ĺ'] +['æ·', 'ħ'] +['æ·', 'ŀ'] +['æ¸', 'İ'] +['æ¶', '¿'] +['æ·', 'ĸ'] +['æĮ', '²'] +['æ·', 'ł'] +['æ¶', '¸'] +['æ¸', 'ij'] +['æ·', '¦'] +['æ·', 'Ŀ'] +['æ¶', 'ª'] +['æ·', 'Ļ'] +['æ¶', '«'] +['æ¸', 'Į'] +['æĤ', '»'] +['æĤ', '±'] +['æ', 'ĥĿ'] +['æĥ', 'ĺ'] +['æĥ', 'Ĩ'] +['æĥ', 'ļ'] +['æĥ', 'ĩ'] +['æĥ', '®'] +['çª', 'ķ'] +['è°', 'Į'] +['æī', 'Ī'] +['çļ', '²'] +['è°', 'ij'] +['è£', 'Ĩ'] +['è¢', '·'] +['è£', 'ī'] +['è°', 'Ĵ'] +['è°', 'Ķ'] +['è°', 'ķ'] +['è°', 'ĸ'] +['è°', 'Ĺ'] +['è°', 'Ļ'] +['è°', 'Ŀ'] +['éĢ', '¯'] +['éĥ', '¿'] +['éļ', 'Ī'] +['ç²', 'ľ'] +['éļ', 'į'] +['éļ', 'Ĺ'] +['å©', 'Ĭ'] +['å¨', '¼'] +['å©', '¢'] +['å©', 'µ'] +['èĥ', '¬'] +['è¢', 'Ī'] +['ç¿', 'Į'] +['æģ', '¿'] +['æ¬', '¸'] +['ç»', '«'] +['éª', 'IJ'] +['ç»', '¯'] +['ç»', '±'] +['éª', 'Ĵ'] +['ç»', '²'] +['éª', 'ĵ'] +['ç»', '¶'] +['ç»', 'º'] +['ç»', '»'] +['ç»', '¾'] +['éª', 'ĸ'] +['ç¼', 'ģ'] +['èĢ', 'ł'] +['çIJ', '«'] +['çIJ', 'µ'] +['çIJ', '¶'] +['çIJ', '¥'] +['çIJ', '¨'] +['çIJ', '°'] +['çIJ', '®'] +['çIJ', '¯'] +['çIJ', '¬'] +['çIJ', 'ļ'] +['è¾', 'ĩ'] +['é¼', 'ĭ'] +['æı', '³'] +['åł', 'ŀ'] +['æIJ', '½'] +['æı', '¸'] +['æı', 'ł'] +['åł', 'Ļ'] +['è¶', 'Ħ'] +['æı', 'ĸ'] +['é¢', 'ī'] +['å¡', 'Ħ'] +['æı', '¿'] +['èĢ', 'ĭ'] +['æı', 'Ħ'] +['èĽ', '©'] +['èĽ', '°'] +['å¡', 'Ĩ'] +['æij', 'Ĵ'] +['æı', 'Ĩ'] +['æİ', '¾'] +['èģ', 'Ĵ'] +['èij', 'ij'] +['èij', 'ļ'] +['éĿ', '°'] +['éĿ', '¸'] +['èij', '³'] +['èij', 'º'] +['èij', '¸'] +['èIJ', '¼'] +['èij', '¶'] +['è', 'ĴĮ'] +['èij', 'Ń'] +['æ¥', '®'] +['æ', '£¼'] +['æ¤', 'Ł'] +['æ£', '¹'] +['æ¤', '¤'] +['æ£', '°'] +['èµ', 'į'] +['æ¤', 'ĭ'] +['æ¤', 'ģ'] +['æ¤', 'ª'] +['æ¤', 'IJ'] +['é¹', 'ģ'] +['éħ', '¤'] +['éħ', '¢'] +['éħ', '¡'] +['é¹', 'Ĥ'] +['æ®', 'ļ'] +['æ®', 'Ľ'] +['éĽ', '±'] +['è¾', 'ĭ'] +['æ¤', 'ł'] +['è¾', 'İ'] +['çĿ', 'Ħ'] +['çĿ', 'ĩ'] +['çĿ', 'ĥ'] +['æĪ', '¢'] +['åĸ', 'ĭ'] +['åĹ', 'Ĵ'] +['åĸ', 'ĥ'] +['åĸ', '±'] +['åĸ', '¹'] +['æĻ', '·'] +['åĸ', 'Ī'] +['è·', 'ĸ'] +['è·', 'Ĺ'] +['è·', 'ŀ'] +['è·', 'ļ'] +['è·', 'İ'] +['è·', 'ı'] +['è·', 'Ĩ'] +['èĽ', '±'] +['èĽ', '²'] +['èĽ', 'Ń'] +['èĽ', '³'] +['èĽ', 'IJ'] +['èĽ', 'Ķ'] +['èĽ', 'ŀ'] +['èĽ', '´'] +['èĽ', 'ĺ'] +['åĸ', 'ģ'] +['åĸ', 'Ł'] +['åķ', '¾'] +['åĹ', 'ĸ'] +['åĸ', 'ij'] +['åĹ', 'Ł'] +['åĹ', 'ŀ'] +['åĸ', 'Ļ'] +['åµ', 'ĺ'] +['åµ', 'ĸ'] +['å´', '´'] +['éģ', 'Ħ'] +['è©', 'Ī'] +['åµ', 'İ'] +['å', 'µ¬'] +['åµ', 'Ľ'] +['åµ', '¯'] +['åµ', 'Ŀ'] +['åµ', '«'] +['å¹', 'Ħ'] +['åµ', 'ĭ'] +['èµ', 'ķ'] +['éĵ', '»'] +['éĵ', '¼'] +['éĵ', '¿'] +['éĶ', 'ĥ'] +['éĶ', 'Ĩ'] +['éĶ', 'ĩ'] +['éĶ', 'ī'] +['éĶ', 'ı'] +['éĶ', 'ij'] +['éĶ', 'Ĵ'] +['éĶ', 'Ķ'] +['éĶ', 'ķ'] +['æİ', '£'] +['çŁ', '¬'] +['æ°', '°'] +['æ¯', '³'] +['æ¯', '½'] +['çĬ', 'Ĭ'] +['çĬ', 'Ħ'] +['çĬ', 'ĭ'] +['é', '¹Ħ'] +['çĬ', 'į'] +['åµ', 'ĩ'] +['é»', 'į'] +['ç¨', 'ĥ'] +['ç¨', 'Ĥ'] +['çŃ', 'ļ'] +['çŃ', 'µ'] +['çŃ', 'Į'] +['åĤ', '£'] +['åĤ', 'Ī'] +['èĪ', 'Ħ'] +['çī', 'į'] +['åĤ', '¥'] +['åĤ', '§'] +['éģ', 'ij'] +['åĤ', '©'] +['å¾', '¨'] +['åª', 'Ń'] +['çķ', '²'] +['å¼', 'ij'] +['ç¿', 'ķ'] +['é¹', 'Ĩ'] +['èħ', 'Ī'] +['èħ', 'ĵ'] +['èħ', 'Ĩ'] +['èħ', '´'] +['èħ', 'ļ'] +['èħ', '±'] +['é±', '¿'] +['é²', 'Ģ'] +['é²', 'Ĥ'] +['çĮ', '¢'] +['çĮ', '¹'] +['çĮ', '¥'] +['é£', 'ĵ'] +['è§', 'ŀ'] +['è§', 'ļ'] +['çĮ', '±'] +['é¢', 'İ'] +['é£', '§'] +['é¦', 'ĩ'] +['é¦', 'Ĭ'] +['äº', 'µ'] +['èĦ', 'Ķ'] +['è£', 'Ĵ'] +['çĹ', '£'] +['çĹ', '¨'] +['çĹ', '¦'] +['çĹ', 'ŀ'] +['çĹ', '¤'] +['çĹ', '§'] +['èµ', 'ĵ'] +['ç«', '¦'] +['çĵ', '¿'] +['åķ', '»'] +['é¢', 'ı'] +['é¹', 'ĩ'] +['éĺ', 'ij'] +['éĺ', 'Ĵ'] +['éĺ', 'ķ'] +['ç²', 'ŀ'] +['éģ', 'Ĵ'] +['åŃ', '³'] +['çĦ', '¯'] +['çĦ', 'ľ'] +['çĦ', '±'] +['é¹', 'Ī'] +['æ¸', '«'] +['æ¹', '®'] +['æ¹', 'İ'] +['æ¹', 'ľ'] +['æ¹', 'į'] +['æ¹', '«'] +['æº', '²'] +['æ¹', 'Ł'] +['æº', 'Ĩ'] +['æ¹', '²'] +['æ¹', 'Ķ'] +['æ¹', 'ī'] +['æ¸', '¥'] +['æ»', 'ģ'] +['æĦ', 'ł'] +['æĥ', 'º'] +['æĦ', '¦'] +['æĥ', '´'] +['æĦ', 'Ģ'] +['æĦ', 'İ'] +['æĦ', 'Ķ'] +['åĸ', '¾'] +['å¯', 'IJ'] +['è°', 'Ł'] +['è£', '¢'] +['è£', 'İ'] +['è£', '¥'] +['ç¥', '¾'] +['è°', 'ł'] +['è°', '¡'] +['è°', '¥'] +['è°', '§'] +['åŃ', '±'] +['å¼', '¼'] +['å·', '½'] +['éª', 'ĺ'] +['åª', 'ª'] +['å·', '¯'] +['ç¿', 'ļ'] +['çļ', '´'] +['éª', 'Ľ'] +['ç¼', 'Ĥ'] +['ç¼', 'ĥ'] +['ç¼', 'Ħ'] +['å½', 'ĺ'] +['ç¼', 'ĩ'] +['ç¼', 'Ī'] +['ç¼', 'Į'] +['ç¼', 'ij'] +['ç¼', 'Ĵ'] +['ç¼', 'Ĺ'] +['é£', '¨'] +['èĢ', '¢'] +['çij', 'ģ'] +['çij', 'Ĺ'] +['çij', 'Ħ'] +['éģ', '¨'] +['éª', 'ľ'] +['éŁ', '«'] +['é«', '¡'] +['å¡', '¬'] +['éĦ', '¢'] +['è¶', 'Ķ'] +['è¶', 'ij'] +['æij', 'ħ'] +['æij', 'ģ'] +['èľ', 'ĩ'] +['æIJ', 'ĭ'] +['æIJ', 'ª'] +['æIJ', 'IJ'] +['æIJ', 'Ľ'] +['æIJ', 'ł'] +['æij', 'Ī'] +['å½', 'Ģ'] +['æ¯', 'Ĥ'] +['æIJ', '¦'] +['æIJ', '¡'] +['èĵ', 'ģ'] +['æĪ', '¡'] +['è', 'ĵį'] +['éĦ', 'ŀ'] +['èĵ', 'IJ'] +['èĵ', '¦'] +['é¹', 'ĭ'] +['èĴ', '½'] +['èĵ', 'ĸ'] +['èĵ', 'Ĭ'] +['èĴ', '¯'] +['èĵ', 'Ł'] +['èĵ', 'ij'] +['èĴ', 'º'] +['èĵ', 'ł'] +['èĴ', 'Ł'] +['èĴ', '¡'] +['èĴ', '¹'] +['èĴ', '´'] +['èĴ', 'Ĺ'] +['èĵ', '¥'] +['æ¥', 'Ķ'] +['æ¥', 'Ĥ'] +['æ¥', 'Ŀ'] +['æ¥', '«'] +['æ¥', '¸'] +['æ¤', '´'] +['æ§', 'Į'] +['æ¥', '¯'] +['çļ', 'Ļ'] +['æ¦', 'Ī'] +['æ§', 'İ'] +['æ¦', 'ī'] +['æ¥', '¦'] +['æ¥', '£'] +['æ¥', '¹'] +['æ¤', '½'] +['åī', '½'] +['éħ', '©'] +['èľ', 'ĥ'] +['ç¢', 'Ľ'] +['ç¢', 'ĵ'] +['ç¡', '¼'] +['ç¢', 'ī'] +['ç¢', 'ļ'] +['ç¢', 'ĩ'] +['ç¢', 'ľ'] +['é¹', 'Į'] +['è¾', 'ı'] +['é¾', 'ĥ'] +['é¾', 'ħ'] +['è¨', '¾'] +['ç²', '²'] +['çĿ', 'ļ'] +['åĹ', 'ª'] +['éŁ', 'ª'] +['åĹ', '·'] +['åĹ', 'ī'] +['çĿ', '¨'] +['çĿ', '¢'] +['éĽ', 'İ'] +['çĿ', '¥'] +['åĹ', 'ij'] +['åĹ', '«'] +['åĹ', '¬'] +['åĹ', 'Ķ'] +['åĹ', 'Ŀ'] +['æĪ', '¥'] +['åĹ', 'Ħ'] +['çħ', '¦'] +['æļ', 'Ħ'] +['éģ', '¢'] +['æ', 'ļĮ'] +['è·', '¬'] +['è·', '¶'] +['è', '·¸'] +['è·', 'IJ'] +['è·', '£'] +['è·', '¹'] +['èĽ', '¸'] +['èľ', 'Ĭ'] +['èľ', 'į'] +['èľ', 'ī'] +['èľ', '£'] +['çķ', '¹'] +['èĽ', '¹'] +['åĹ', '¥'] +['åĹ', '²'] +['åĹ', '³'] +['åĹ', 'Į'] +['åĹ', 'į'] +['åĹ', 'IJ'] +['åĹ', '¤'] +['åĹ', 'µ'] +['ç½', '¨'] +['åµ', 'Ĭ'] +['åµ', '´'] +['éª', '°'] +['éĶ', 'Ĺ'] +['éĶ', 'Ľ'] +['éĶ', 'ľ'] +['éĶ', 'Ŀ'] +['éĶ', 'ŀ'] +['éĶ', 'Ł'] +['éĶ', '¢'] +['éĶ', '¨'] +['éĶ', '©'] +['éĶ', 'Ń'] +['éĶ', '±'] +['éĽ', 'ī'] +['æ°', '²'] +['çĬ', 'ı'] +['æŃ', 'ĥ'] +['ç¨', 'ŀ'] +['ç¨', 'Ĺ'] +['ç¨', 'Ķ'] +['çŃ', 'ł'] +['çŃ', '¢'] +['çŃ', '®'] +['çŃ', '²'] +['çī', 'Ĵ'] +['æķ', '«'] +['å¾', 'Ń'] +['æĦ', 'Ĩ'] +['èī', 'Ħ'] +['è§', 'İ'] +['æ¯', '¹'] +['è²', 'Ĭ'] +['è²', 'ħ'] +['è²', 'ī'] +['é¢', 'Ķ'] +['èħ', 'ł'] +['èħ', '©'] +['èħ', '¼'] +['èħ', 'Ń'] +['è', 'ħ§'] +['å¡', 'į'] +['åª', 'µ'] +['é²', 'ħ'] +['é²', 'Ĩ'] +['é²', 'ĩ'] +['é²', 'Ī'] +['é²', 'ĭ'] +['é²', 'IJ'] +['èĤ', 'Ħ'] +['é¹', 'IJ'] +['é£', 'ķ'] +['è§', '¥'] +['éģ', 'Ľ'] +['é¦', 'IJ'] +['é¹', 'ij'] +['äº', '¶'] +['çĺ', 'ĥ'] +['çĹ', '±'] +['çĹ', '¼'] +['çĹ', '¿'] +['çĺ', 'IJ'] +['çĺ', 'ģ'] +['çĺ', 'Ĩ'] +['éº', 'Ĥ'] +['æŃ', 'Ĩ'] +['æĹ', 'Ĵ'] +['éĺ', 'ĸ'] +['éĺ', 'Ĺ'] +['ç¾', '§'] +['è±', '¢'] +['ç²', '³'] +['çĮ', '·'] +['çħ', '³'] +['çħ', '¨'] +['çħ', 'ħ'] +['çħ', 'Ĭ'] +['çħ', '¸'] +['çħ', 'º'] +['æ»', 'Ł'] +['æº', '±'] +['æº', 'ĺ'] +['æ¼', 'Ń'] +['æ»', '¢'] +['æº', '¥'] +['æº', '½'] +['è£', 'Ł'] +['æº', '»'] +['æº', '·'] +['æ»', 'Ĺ'] +['æ»', '«'] +['æº', '´'] +['æ»', 'ı'] +['æ»', 'ĥ'] +['æ»', '¦'] +['æº', 'ı'] +['æ»', 'Ĥ'] +['æ»', 'ĵ'] +['æº', 'Ł'] +['æ»', 'ª'] +['æĦ', '«'] +['æħ', 'Ĭ'] +['é²', 'İ'] +['éª', 'ŀ'] +['çª', 'ł'] +['çª', '£'] +['è£', '±'] +['è£', '¨'] +['è£', '¾'] +['è£', '°'] +['ç¦', 'Ĭ'] +['è°', '©'] +['è°', 'ª'] +['åª', '¾'] +['å«', '«'] +['åª', '²'] +['å«', 'Ĵ'] +['å«', 'Ķ'] +['åª', '¸'] +['ç¼', 'Ļ'] +['ç¼', 'ľ'] +['ç¼', 'Ľ'] +['è¾', 'Ķ'] +['éª', 'Ŀ'] +['ç¼', 'Ł'] +['ç¼', '¡'] +['ç¼', '¢'] +['ç¼', '£'] +['éª', 'Ł'] +['èĢ', '¥'] +['çĴ', 'Ī'] +['çij', 'Ń'] +['çį', 'Ĵ'] +['è§', 'ı'] +['æħ', 'Ŀ'] +['å«', 'ł'] +['åı', 'Ĩ'] +['æij', '½'] +['å¢', 'ģ'] +['æĴ', 'Ĥ'] +['æij', 'ŀ'] +['æĴ', 'Ħ'] +['ç¿', '¥'] +['è¸', 'ħ'] +['æij', 'Ń'] +['å¢', 'ī'] +['å¢', 'Ĵ'] +['æ¦', 'ĸ'] +['ç¶', '¦'] +['èĶ', '«'] +['èĶ', '·'] +['éĿ', 'º'] +['éĿ', '¼'] +['éŀ', 'ħ'] +['éĿ', '¿'] +['çĶ', 'į'] +['èĶ', '¸'] +['èĶ', 'Ł'] +['èĶ', 'º'] +['æĪ', '¬'] +['èķ', 'ĸ'] +['èĶ', '»'] +['èĵ', '¿'] +['æĸ', '¡'] +['é¹', 'ķ'] +['èĵ', '¼'] +['æ¦', 'Ľ'] +['æ¦', '§'] +['æ¦', '«'] +['æ¦', 'Ń'] +['æ§', 'Ķ'] +['æ¦', '±'] +['æ§', 'ģ'] +['æ§', 'ł'] +['æ¦', '·'] +['åĥ', '°'] +['éħ', '½'] +['éħ', '¹'] +['ç¢', '¡'] +['ç¢', '´'] +['ç¢', '£'] +['ç¢', '²'] +['èĩ', '§'] +['è±', '¨'] +['æ®', '¡'] +['éľ', 'ģ'] +['èľ', 'ļ'] +['é¾', 'ĩ'] +['é¾', 'Ī'] +['ä', 'ģ'] +['äģ', 'ĸ'] +['çĿ', '½'] +['åĺ', 'ŀ'] +['åĺ', 'Ī'] +['åĺ', 'Į'] +['åĺ', 'ģ'] +['æļ', 'Ŀ'] +['è¸', 'Į'] +['è¸', 'ī'] +['èľ', 'ŀ'] +['èľ', '¥'] +['èľ', '®'] +['èĿ', 'Ī'] +['èľ', '´'] +['èľ', '±'] +['èľ', '©'] +['èľ', '·'] +['èľ', '¿'] +['èŀ', 'Ĥ'] +['èľ', '¢'] +['åĺ', '¡'] +['é¹', 'Ĺ'] +['åĺ', '£'] +['åĺ', '¤'] +['åĺ', 'ļ'] +['åĹ', '¾'] +['åĺ', '§'] +['ç½', '´'] +['ç½', '±'] +['å¹', 'Ķ'] +['å¶', 'Ĥ'] +['å¹', 'Ľ'] +['èµ', 'Ļ'] +['ç½', 'Ĥ'] +['éª', '·'] +['éª', '¶'] +['é¹', 'ĺ'] +['éĶ', '²'] +['éĶ', '´'] +['éĶ', '¶'] +['éĶ', '·'] +['éĶ', '¸'] +['éĶ', 'µ'] +['éķ', 'Ĥ'] +['çĬ', 'Ĵ'] +['ç®', 'IJ'] +['ç®', '¦'] +['ç®', '§'] +['ç®', '¸'] +['ç®', '¬'] +['ç®', 'ħ'] +['ç®', 'ª'] +['ç®', 'ľ'] +['ç®', '¢'] +['ç®', 'ĵ'] +['åĥ', 'ĸ'] +['åĦ', 'Ĩ'] +['åĥ', '³'] +['åĥ', 'Ń'] +['åĬ', 'ģ'] +['åĥ', '®'] +['éŃ', 'ĥ'] +['éŃ', 'Ĩ'] +['çĿ', '¾'] +['èī', 'ĭ'] +['éĦ', '±'] +['èĨ', 'Ī'] +['èĨ', 'ij'] +['é²', 'ij'] +['é²', 'Ķ'] +['é²', 'ļ'] +['é²', 'Ľ'] +['é²', 'Ł'] +['çį', 'IJ'] +['è§', '«'] +['éĽ', 'Ĵ'] +['å¤', '¤'] +['é¦', 'ij'] +['éĬ', '®'] +['å¡', '¾'] +['çĺ', 'Į'] +['çĺ', 'Ĭ'] +['çĺ', 'ĺ'] +['çĺ', 'Ļ'] +['æĹ', 'ĸ'] +['èĨ', 'Ĥ'] +['éĺ', 'ļ'] +['éĦ', '¯'] +['é²', 'ŀ'] +['ç²', '¿'] +['ç²', '¼'] +['ç³', 'ģ'] +['æ§', 'Ĭ'] +['é¹', 'ļ'] +['çĨ', 'ĺ'] +['çĨ', '¥'] +['æ½', '¢'] +['æ¼', 'ķ'] +['æ»', '¹'] +['æ¼', '¯'] +['æ¼', '¶'] +['æ½', 'ĭ'] +['æ½', '´'] +['æ¼', 'ª'] +['æ¼', 'ī'] +['æ¼', '©'] +['æ¾', 'ī'] +['æħ', 'µ'] +['æIJ', '´'] +['çª', '¨'] +['å¯', '¤'] +['ç¶', '®'] +['è°', '®'] +['è¤', '¡'] +['è¤', 'Ļ'] +['è¤', 'ĵ'] +['è¤', 'Ľ'] +['è¤', 'Ĭ'] +['è°', '¯'] +['è°', '°'] +['è°', '²'] +['å±', '£'] +['é¹', 'Ľ'] +['å«', '±'] +['å«', 'ĸ'] +['å«', '¦'] +['å«', 'ļ'] +['å', '«ĺ'] +['é¼', 'IJ'] +['çŀ', 'Ģ'] +['é¹', 'ľ'] +['éª', 'ł'] +['ç¼', '¥'] +['ç¼', '¦'] +['ç¼', '§'] +['ç¼', '¨'] +['éª', '¢'] +['ç¼', '«'] +['èĢ', '¦'] +['èĢ', '§'] +['çĴ', 'ľ'] +['çĴ', 'İ'] +['çĴ', 'ģ'] +['å¥', 'Ń'] +['é«', '¯'] +['é«', '«'] +['æĴ', '·'] +['æĴ', 'ħ'] +['èµ', 'Ń'] +['æĴ', '¸'] +['éĭ', 'Ĩ'] +['æĴ', 'Ļ'] +['æĴ', 'º'] +['å¢', 'Ģ'] +['èģ', '©'] +['è§', 'IJ'] +['éŀ', 'ij'] +['èķ', 'Ļ'] +['éŀ', 'Ĵ'] +['èķ', 'Ī'] +['èķ', '¨'] +['èķ', '¤'] +['èķ', 'ŀ'] +['èķ', 'º'] +['çŀ', '¢'] +['èķ', 'ĥ'] +['èķ', '²'] +['èµ', 'ľ'] +['æ§', '¿'] +['æ¨', '¯'] +['æ§', 'Ń'] +['æ¨', 'Ĺ'] +['æ¨', 'ĺ'] +['æ§', '²'] +['éĨ', 'Į'] +['éĨ', 'ħ'] +['éĿ', '¥'] +['éŃ', 'ĩ'] +['é¤', 'į'] +['ç£', 'Ķ'] +['ç£', 'Ļ'] +['éľ', 'Ī'] +['è¾', 'ĺ'] +['é¾', 'ī'] +['é¾', 'Ĭ'] +['è§', 'ij'] +['çŀ', 'Į'] +['ç', 'ŀĭ'] +['çŀ', 'ij'] +['åĺ', 'Ń'] +['åĻ', 'İ'] +['åĻ', '¶'] +['é¢', 'Ļ'] +['æļ', '¹'] +['åĻ', 'ĺ'] +['è¸', 'Ķ'] +['è¸', 'Ŀ'] +['è¸', 'Ł'] +['è¸', 'Ĵ'] +['è¸', '¬'] +['è¸', '®'] +['è¸', '¯'] +['è¸', 'º'] +['è¸', 'ŀ'] +['èĿ', '½'] +['èĿ', '¾'] +['èĿ', '»'] +['èĿ', '°'] +['èĿ', '®'] +['è', 'ŀĭ'] +['èĿ', 'ĵ'] +['èĿ', '£'] +['è', 'Ŀ¼'] +['åĺ', '¬'] +['é¢', 'ļ'] +['åĻ', 'į'] +['åĻ', 'Ļ'] +['åĻ', 'Į'] +['åĻ', 'Ķ'] +['é¢', 'Ľ'] +['å¹', 'ŀ'] +['å¹', '¡'] +['å¶', 'Ļ'] +['å¶', 'Ŀ'] +['éª', 'º'] +['éķ', 'Ĭ'] +['éķ', 'ī'] +['éķ', 'Į'] +['éķ', 'ı'] +['éķ', 'Ĵ'] +['éķ', 'ĵ'] +['éķ', 'Ķ'] +['ç¨', '·'] +['ç®', '´'] +['ç¯', 'ij'] +['ç¯', 'ģ'] +['ç¯', 'Į'] +['çī', 'ĸ'] +['åĦ', 'ĭ'] +['èĻ', '¢'] +['é¹', 'ŀ'] +['èĨ', 'ĺ'] +['é²', 'ł'] +['é²', '¡'] +['é²', '¢'] +['é²', '£'] +['é²', '¥'] +['é²', '§'] +['é²', '©'] +['çį', 'Ĺ'] +['çį', 'ł'] +['è§', '¯'] +['é¦', 'ĵ'] +['é¦', 'Ķ'] +['éº', '¾'] +['å»', 'Ľ'] +['çĺ', 'Ľ'] +['çĺ', '¼'] +['çĺ', '¢'] +['çĺ', 'ł'] +['é½', 'ij'] +['ç¾', '°'] +['ð¥', '»'] +['ð¥»', 'Ĺ'] +['ç³', 'Į'] +['ç³', 'į'] +['ç³', 'ħ'] +['çĨ', 'ľ'] +['ç', 'Ĩµ'] +['æ¾', 'į'] +['æ¾', 'Į'] +['æ½', '¸'] +['æ½', '¦'] +['æ½', '²'] +['éĭ', 'Ī'] +['æ½', 'Ł'] +['æ½', 'º'] +['å¯', '®'] +['çª', '³'] +['è°', '³'] +['è¤', '´'] +['è¤', 'Ł'] +['è¤', '«'] +['è°', 'µ'] +['çĨ', '¨'] +['å±', '¦'] +['åĭ', '°'] +['æĪ', '®'] +['èĿ', '¥'] +['ç¼', '¬'] +['ç¼', '®'] +['ç¼', '¯'] +['éª', '£'] +['çķ', '¿'] +['èĢ', '©'] +['èĢ', '¨'] +['èĢ', 'ª'] +['çĴ', 'Ł'] +['éĿ', 'Ľ'] +['çĴ', 'ł'] +['çĴ', 'ĺ'] +['èģ', '±'] +['èŀ', '¯'] +['é«', '»'] +['é«', 'Ń'] +['é«', '¹'] +['æĵ', 'Ģ'] +['çĶ', 'ı'] +['æĵ', 'ŀ'] +['ç¸', 'ł'] +['ç£', '¬'] +['é¢', 'ŀ'] +['èķ', '»'] +['é¢', 'Ł'] +['èĸ', '¤'] +['èĸ', '¨'] +['æª', 'ł'] +['èĸ', 'ı'] +['èĸ', '®'] +['èĸ', 'ľ'] +['èĸ', 'ħ'] +['æ¨', '¾'] +['æ©', 'Ľ'] +['æ©', 'ĩ'] +['æ¨', 'µ'] +['æª', 'İ'] +['æ©', '¹'] +['æ¨', '½'] +['æ¨', '¨'] +['æ©', '¼'] +['å¢', '¼'] +['æ©', 'IJ'] +['ç¿', '®'] +['éĨ', 'IJ'] +['éĨ', 'į'] +['éĨ', 'ļ'] +['ç£', '²'] +['èµ', 'Ŀ'] +['æ®', 'ª'] +['éľ', 'ı'] +['éĮ', '¾'] +['è¾', 'ļ'] +['éģ', '½'] +['æ°', 'ħ'] +['çŀ', 'Ł'] +['çŀ', 'ł'] +['çŀ', '°'] +['åļ', 'Ħ'] +['åļ', 'Ĩ'] +['åĻ', '¤'] +['æļ', '¾'] +['è¹', 'Ģ'] +['è¸', 'µ'] +['è¸', '½'] +['è¹', 'ī'] +['è¹', 'ģ'] +['èŀ', '¨'] +['èŀ', 'Ī'] +['èŀ', 'ħ'] +['èŀ', 'Ń'] +['èŀ', 'ł'] +['èŀ', 'Ł'] +['åĻ', '±'] +['åĻ', '«'] +['åĻ', '»'] +['åĻ', '¼'] +['ç½', '¹'] +['åľ', 'ľ'] +['ä', '¦'] +['ä¦', 'ĥ'] +['éķ', 'Ĺ'] +['éķ', 'ĺ'] +['éķ', 'ļ'] +['éķ', 'Ľ'] +['éķ', 'Ŀ'] +['éķ', 'ŀ'] +['éķ', 'ł'] +['æ°', 'ĩ'] +['æ°', 'Ĩ'] +['ç©', 'ij'] +['ç¯', 'Ŀ'] +['ç¯', '¥'] +['ç¯', '¦'] +['ç¯', 'ª'] +['ç¯', 'Ļ'] +['çĽ', '¥'] +['åĬ', 'ĵ'] +['ç¿', '±'] +['éŃ', 'ī'] +['éŃ', 'Ī'] +['å¾', '¼'] +['æŃ', 'Ļ'] +['èĨ', '¦'] +['èĨ', 'Ļ'] +['é²', '®'] +['é²', '±'] +['é²', '³'] +['é²', '´'] +['é²', 'µ'] +['é²', '·'] +['é²', '»'] +['çį', '´'] +['çį', 'Ń'] +['çį', '¬'] +['éĤ', 'Ĥ'] +['é¹', '§'] +['å»', '¨'] +['èµ', 'Ł'] +['çĺ', '°'] +['å»', 'ª'] +['çĺ', '¿'] +['çĺ', 'µ'] +['çĺ', '´'] +['çĻ', 'ĥ'] +['çĺ', '³'] +['éº', 'ĩ'] +['éº', 'Ī'] +['å', '¬´'] +['å£', 'ħ'] +['ç³', 'Ĺ'] +['çĶ', 'ij'] +['çĩ', 'İ'] +['çĩ', 'ł'] +['çĩ', 'Ķ'] +['çĩ', '§'] +['æ¿', 'ij'] +['æ¿', 'ī'] +['æ½', 'ŀ'] +['æ¾', '§'] +['æ¾', '¹'] +['æ¾', '¥'] +['æ¾', '¶'] +['æ¿', 'Ĥ'] +['è¤', '°'] +['çª', '¸'] +['å¬', 'ĸ'] +['çĬ', 'Ł'] +['éļ', '°'] +['å¬', 'Ĺ'] +['é¢', '¡'] +['ç¼', '±'] +['ç¼', '²'] +['ç¼', '³'] +['çĴ', '©'] +['çĴ', 'ª'] +['èŀ', '«'] +['æĵ', '¤'] +['å£', 'ķ'] +['è§', '³'] +['ç½', 'Ħ'] +['æĵ', '¢'] +['èĸ', '¹'] +['éŀ', '¡'] +['éŀ', '¬'] +['èĸ', '·'] +['èĹ', 'ĵ'] +['èĹ', 'ģ'] +['æª', 'Ħ'] +['æª', '©'] +['æĩ', 'ĭ'] +['éĨ', '¢'] +['ç¿', '³'] +['ç¤', 'ħ'] +['ç£', '´'] +['é¹', '©'] +['é¾', 'ĭ'] +['é¾', 'Į'] +['è±', '³'] +['å£', 'ij'] +['é»', '»'] +['åļ', 'ı'] +['åļ', 'ħ'] +['è¹', 'ij'] +['è¹', 'Ĵ'] +['è¹', 'Ĭ'] +['è', 'Ł¥'] +['èŀ', '¬'] +['èŀ', 'µ'] +['çĸ', 'ĥ'] +['èŀ', '³'] +['èŁ', 'ij'] +['åļ', 'ĵ'] +['ç½', '½'] +['ç½', '¾'] +['å¶', '·'] +['é»', 'ľ'] +['é»', 'Ŀ'] +['é«', 'ģ'] +['é«', 'Ģ'] +['éķ', '¡'] +['éķ', '¢'] +['éķ', '£'] +['éķ', '¦'] +['éķ', '§'] +['éķ', '©'] +['éķ', 'ª'] +['éķ', '«'] +['ç½', 'ħ'] +['ç°', 'Į'] +['ç¯', '¾'] +['ç¯', '¼'] +['ç°', 'ĸ'] +['ç°', 'ĭ'] +['é¼', '¢'] +['åĦ', '¡'] +['é¹', 'ª'] +['é¼', '¾'] +['çļ', '¤'] +['éŃ', 'į'] +['é¾', 'ł'] +['ç¹', 'ĩ'] +['è²', 'ĺ'] +['éĤ', 'Ī'] +['è²', 'Ķ'] +['èĩ', 'Į'] +['èĨ', '»'] +['èĩ', 'Ĩ'] +['èĩ', 'ĥ'] +['é²', '¼'] +['é²', '½'] +['é³', 'Ģ'] +['é³', 'ĥ'] +['é³', 'ħ'] +['é³', 'ĩ'] +['é³', 'Ĭ'] +['èŀ', '½'] +['çĩ', '®'] +['é¹', '«'] +['ç³', 'ľ'] +['ç¸', '»'] +['çĻ', 'į'] +['éº', 'ĭ'] +['æĩ', 'ij'] +['æ¿', '¡'] +['æ¿', '®'] +['æ¿', 'ŀ'] +['æ¿', 'ł'] +['æ¿', '¯'] +['è¹', 'ĩ'] +['è¬', 'ĩ'] +['éĤ', 'ĥ'] +['è¥', 'ģ'] +['æª', 'Ĺ'] +['æ', 'ĵĺ'] +['åŃ', 'º'] +['éļ', '³'] +['å¬', '·'] +['èŁ', 'Ĭ'] +['é¹', '¬'] +['éį', 'ª'] +['éı', 'Ĭ'] +['é¬', 'Ī'] +['é¬', 'ĥ'] +['çŀ', '½'] +['éŀ', '¯'] +['éŀ', '¨'] +['éŀ', '«'] +['éŀ', '§'] +['éŀ', '£'] +['èĹ', 'ľ'] +['èĹ', 'ł'] +['éĨ', 'ª'] +['è¹', 'Ļ'] +['ç¤', 'ĵ'] +['çĩ', '¹'] +['é¤', '®'] +['çŀ', '¿'] +['æĽ', 'Ľ'] +['é¢', '¢'] +['èº', 'ĩ'] +['è¹', 'ļ'] +['èŁ', 'Ľ'] +['èŁ', 'ª'] +['èŁ', 'ł'] +['èŁ', '®'] +['é¹', '®'] +['é»', 'ł'] +['é»', 'Ł'] +['é«', 'ħ'] +['é«', 'Ĥ'] +['éķ', '¬'] +['éķ', 'Ń'] +['éķ', '¯'] +['é¦', '¥'] +['ç°', 'Ł'] +['ç°', 'ª'] +['é¼', '¬'] +['éĽ', 'ł'] +['èī', 'Ł'] +['é³', 'İ'] +['é³', 'ı'] +['é³', 'IJ'] +['çĻ', 'ŀ'] +['çĻ', 'Ķ'] +['ç³', '¨'] +['è¹', '©'] +['éİ', 'ı'] +['éĤ', 'ĭ'] +['é¬', 'ı'] +['æĶ', 'ī'] +['éŀ', '²'] +['éŀ', '´'] +['èĹ', '¿'] +['èĺ', '§'] +['èĺ', 'ħ'] +['éĨ', '®'] +['éĨ', '¯'] +['éħ', 'ĥ'] +['éľ', 'ª'] +['éľ', 'Ń'] +['éľ', '¨'] +['é»', '¼'] +['åļ', '¯'] +['è¹', '°'] +['è¹', '¶'] +['è¹', '½'] +['è¹', '¼'] +['è¹', '´'] +['è¹', '¾'] +['è¹', '¿'] +['èł', 'ĸ'] +['èł', 'ĵ'] +['èŁ', '¾'] +['èł', 'Ĭ'] +['é»', '¢'] +['é«', 'ĭ'] +['é«', 'Į'] +['éķ', '²'] +['ç±', 'Ģ'] +['é½', 'ģ'] +['éŃ', 'ij'] +['èī', '¨'] +['é³', 'ĵ'] +['é³', 'Ķ'] +['é³', 'ķ'] +['é³', 'Ĺ'] +['é³', 'Ļ'] +['éı', 'ĸ'] +['ç¾', '¸'] +['ã¸', 'Ĩ'] +['çĢ', '£'] +['çĢ', 'Ľ'] +['è¥', '¦'] +['è°', '¶'] +['è¥', 'ŀ'] +['éª', '¥'] +['ç¼', 'µ'] +['çĵ', 'Ĵ'] +['æĶ', 'ĺ'] +['èĺ', '©'] +['èĺ', 'ĸ'] +['éĨ', '´'] +['éľ', '°'] +['éħ', 'Ĩ'] +['çŁ', 'į'] +['èº', 'ħ'] +['é¼', 'į'] +['å·', 'ī'] +['é»', '©'] +['é»', '¥'] +['é»', 'ª'] +['éķ', '³'] +['éķ', '´'] +['é»', '§'] +['çº', 'Ĥ'] +['çĴ', 'º'] +['é¼', '¯'] +['èĩ', 'ľ'] +['é³', 'ľ'] +['é³', 'Ŀ'] +['é³', 'Ł'] +['çį', '¾'] +['åŃ', 'Ģ'] +['éª', '§'] +['ç', 'ĵĺ'] +['é¼', 'Ļ'] +['éĨ', 'º'] +['ç¤', '´'] +['é¢', '¦'] +['æĽ', '©'] +['é³', '¢'] +['éº', 'Ŀ'] +['å¤', 'Ķ'] +['çĪ', 'Ŀ'] +['çģ', 'ı'] +['ç¦', '³'] +['éIJ', '¾'] +['ç¾', '¼'] +['èł', '¡'] +['èĢ', '±'] +['é¹', '³'] +['æ°', 'į'] +['é¥', 'ķ'] +['èº', 'IJ'] +['é«', 'ij'] +['éķ', 'µ'] +['ç©', '°'] +['é¥', 'Ķ'] +['é¬', '»'] +['é¬', 'Ł'] +['è¶', '±'] +['æĶ', '«'] +['æĶ', '¥'] +['é¢', '§'] +['èº', 'ľ'] +['é¼', '¹'] +['çĻ', '¯'] +['èł', '²'] +['èł', '¹'] +['èº', 'ŀ'] +['è¡', '¢'] +['çģ', 'ŀ'] +['è¥', '»'] +['çº', 'Ľ'] +['é¬', '£'] +['æĶ', '®'] +['åĽ', 'Ķ'] +['é¦', 'ķ'] +['æĪ', 'Ĩ'] +['çĪ', '¨'] +['é½', 'ī'] +['äº', 'į'] +['å°', '¢'] +['å½', '³'] +['åį', '¬'] +['æ®', '³'] +['ðł', '϶'] +['æ¯', 'Į'] +['éĤ', 'ĺ'] +['æĪ', 'ĭ'] +['åľ', '¢'] +['æ°', 'ķ'] +['ä¼', 'ĭ'] +['ä»', 'Ŀ'] +['åĨ', '®'] +['æ°', '¿'] +['æ±', 'Ī'] +['æ°', '¾'] +['å¿', 'ī'] +['å®', 'Ħ'] +['ð¬£', 'Ļ'] +['è®', '±'] +['æī', 'ŀ'] +['åľ', '²'] +['åľ', '«'] +['èĬ', 'ı'] +['èĬ', 'ĥ'] +['æľ', '³'] +['æľ', '¸'] +['ð¨', 'Ļ'] +['ð¨Ļ', '¸'] +['éĤ', '¨'] +['åIJ', 'Ĵ'] +['åIJ', 'ĸ'] +['å±', '¼'] +['å±', '¾'] +['è¾', '¿'] +['éĴ', 'Ĩ'] +['ä»', '³'] +['ä¼', '£'] +['ä¼', 'Ī'] +['çĻ', '¿'] +['çĶ', 'ª'] +['éĤ', 'ł'] +['çĬ', '´'] +['åĨ', '±'] +['éĤ', '¡'] +['ð¬ĩ', 'ķ'] +['æ±', 'ĭ'] +['ä', 'ľ'] +['äľ', '£'] +['è®', '»'] +['ð¬£', 'ŀ'] +['åŃ', 'ĸ'] +['ð¬ĺ', 'ĵ'] +['çº', '©'] +['çİ', 'Ĵ'] +['çİ', 'ĵ'] +['çİ', 'ĺ'] +['çİ', 'ļ'] +['åĪ', '¬'] +['ð«Ń', 'Ł'] +['åĿ', 'ľ'] +['åĿ', 'ī'] +['æī', '½'] +['ð«Ń', '¢'] +['åĿ', 'ĭ'] +['æī', 'º'] +['ã§', 'ij'] +['æ¯', 'IJ'] +['èĬ', '°'] +['èĬ', '£'] +['èĭ', 'Ĭ'] +['èĭ', 'ī'] +['èĬ', 'ĺ'] +['èĬ', '´'] +['èĬ', 'ł'] +['ð«', 'ĩ'] +['ð«ĩ', 'Ń'] +['èĬ', '¤'] +['æĿ', 'ķ'] +['æĿ', 'Ļ'] +['æĿ', 'Ħ'] +['æĿ', '§'] +['æĿ', '©'] +['å°', 'ª'] +['å°', '¨'] +['è½', 'ª'] +['ð«IJ', 'Ħ'] +['åĿ', 'Ĵ'] +['èĬ', 'Ī'] +['æĹ', '´'] +['æĹ', 'µ'] +['åij', 'Ļ'] +['ã', 'ķ'] +['ãķ', '®'] +['å²', 'į'] +['ð«', 'µ'] +['ð«µ', '·'] +['å²', 'ł'] +['å²', 'ľ'] +['åij', 'ĩ'] +['åĨ', 'ı'] +['è§', 'ĥ'] +['å²', 'Ļ'] +['ä¼', '¾'] +['ãij', 'ĩ'] +['ä¼', 'Ń'] +['ä½', 'ĸ'] +['ä¼', '²'] +['ä½', 'ģ'] +['é£', 'ı'] +['çĭ', 'ĥ'] +['éĹ', '¶'] +['æ±', '§'] +['æ±', '«'] +['ð£²', 'ĺ'] +['ð£²', 'Ĺ'] +['æ²', 'Ħ'] +['æ²', 'ĺ'] +['ð¬ĩ', 'Ļ'] +['æ±', 'Ń'] +['ã³', 'ĩ'] +['æ²', 'ĩ'] +['å¿', '®'] +['å¿', '³'] +['å¿', 'º'] +['ð¬£', '¡'] +['ç¥', 'ĥ'] +['è¯', 'ĩ'] +['éĤ', '²'] +['è¯', 'İ'] +['è¯', 'IJ'] +['å±', 'ĥ'] +['ð«', '¸'] +['ð«¸', '©'] +['å²', 'Ĭ'] +['éĺ', '½'] +['ä¢', 'º'] +['éĺ', '¼'] +['å¦', '§'] +['å¦', 'ĺ'] +['ð¨', 'ļ'] +['ð¨ļ', 'ķ'] +['çº', '®'] +['é©', '²'] +['ð«ĺ', 'ľ'] +['çº', '»'] +['ð¬ĺ', 'ĺ'] +['ð«ĺ', 'Ŀ'] +['çº', '¼'] +['çİ', '¤'] +['çİ', 'ŀ'] +['çİ', '±'] +['çİ', 'Ł'] +['éĤ', '½'] +['éĤ', '¿'] +['åĿ', '¥'] +['åĿ', '°'] +['åĿ', '¬'] +['åĿ', '½'] +['å¼', 'Ĩ'] +['èĢ', 'µ'] +['ä¢', '¼'] +['ð¦', 'Ń'] +['ð¦Ń', 'ľ'] +['èĮ', 'ĭ'] +['èĭ', '§'] +['èĭ', '¾'] +['èĭ', 'ł'] +['æŀ', 'ħ'] +['ãŃ', 'İ'] +['æŀ', 'ĺ'] +['æŀ', 'į'] +['çŁ', '¼'] +['çŁ', '»'] +['åĮ', '¼'] +['ð¬¨', 'Ĥ'] +['ð¬Ģ', '©'] +['ð¬Ģ', 'ª'] +['æĹ', '¿'] +['æĺ', 'Ħ'] +['æĺ', 'Ĵ'] +['æĺ', 'Ī'] +['åĴ', 'ī'] +['åĴ', 'ĩ'] +['åĴ', 'į'] +['å²', 'µ'] +['å²', '½'] +['å²', '¨'] +['å²', 'ŀ'] +['å³', 'Ĥ'] +['ã', 'Ł'] +['ãŁ', 'ĥ'] +['åĽ', '·'] +['ð¬¬', '©'] +['éĴ', 'IJ'] +['éĴ', 'Ķ'] +['éĴ', 'ĸ'] +['çī', '¥'] +['ä½', '´'] +['åŀ', 'Ī'] +['ä¾', 'ģ'] +['ä¾', '¹'] +['ä½', '¸'] +['ä½', 'º'] +['éļ', '¹'] +['ãij', 'Ĭ'] +['ä¾', 'Ĥ'] +['ä½', '½'] +['ä¾', 'ĺ'] +['éĥ', 'Ī'] +['èĪ', 'ł'] +['éĥ', 'IJ'] +['éĥ', 'ĥ'] +['æĶ', '½'] +['èĤ', 'Ń'] +['èĤ', '¸'] +['èĤ', '·'] +['çĭ', 'ī'] +['çĭ', 'Ŀ'] +['é¥', '³'] +['å¿', 'ŀ'] +['çĤ', 'Į'] +['çĤ', 'Ĩ'] +['æ³', 'Ļ'] +['æ²', 'º'] +['æ³', 'Ĥ'] +['æ³', 'ľ'] +['æ³', 'ĥ'] +['æ³', 'ĩ'] +['æĢ', 'Ĭ'] +['å³', 'ĥ'] +['ç©', '¸'] +['ç¥', 'ĭ'] +['ç¥', 'Ĭ'] +['ð«į', '£'] +['ð¬£', '³'] +['ð¬', '©½'] +['é¸', '¤'] +['å¼', '¢'] +['å¼', '¨'] +['éĻ', 'ij'] +['ð¬®', '¿'] +['éĻ', 'İ'] +['ð¬¯', 'Ģ'] +['åį', 'º'] +['ä¹', '¸'] +['å¦', 'Ń'] +['å§', 'Ī'] +['ð«', '°'] +['ð«°', 'Ľ'] +['è¿', '³'] +['åı', 'ķ'] +['ð¬³', 'µ'] +['é©', 'µ'] +['ð¬³', '¶'] +['ä', 'Į'] +['äĮ', '¹'] +['é©', 'º'] +['ð«ł', 'Ĭ'] +['ç»', 'ĭ'] +['ç»', 'IJ'] +['çł', 'ī'] +['èĢ', 'Ķ'] +['ãĽ', 'ĥ'] +['çİ', '¶'] +['çı', 'ĩ'] +['çı', 'ħ'] +['ð¬į', 'Ľ'] +['çı', 'ĭ'] +['çİ', '¹'] +['çı', 'Į'] +['çİ', '¿'] +['éŁ', '¨'] +['åŀ', 'ļ'] +['åŀ', '¯'] +['åŀ', 'Ļ'] +['åŀ', '²'] +['åŁ', 'ı'] +['åŀ', 'į'] +['èĢ', 'ĩ'] +['é¿', 'į'] +['åŀ', 'İ'] +['åŀ', '´'] +['åŀ', 'Ł'] +['åŀ', 'ŀ'] +['æĮ', 'ĵ'] +['åŀ', 'µ'] +['åŀ', 'ı'] +['æĭ', '¶'] +['èį', 'ĸ'] +['èį', 'ģ'] +['èį', 'Ļ'] +['èį', 'Ľ'] +['èĮ', 'Ī'] +['èĮ', '½'] +['èį', 'Ħ'] +['èĮ', 'º'] +['ð¬ľ', '¬'] +['èį', 'ĵ'] +['èĮ', '³'] +['ð¦', '°'] +['ð¦°', '¡'] +['èĮ', 'Ľ'] +['èį', 'Ń'] +['ãŃ', 'ķ'] +['æŁ', '·'] +['æŁ', 'ĥ'] +['æŁ', 'Ĭ'] +['æŀ', '¹'] +['æł', 'IJ'] +['æŁ', 'ĸ'] +['éĥ', 'ļ'] +['åī', 'ħ'] +['ä´', 'ĵ'] +['è¿', 'º'] +['åİ', 'ĸ'] +['çł', 'Ĩ'] +['çł', 'ij'] +['çł', 'Ħ'] +['èĢ', 'ı'] +['å¥', 'ĵ'] +['ä', '¶'] +['ä¶', '®'] +['è½', 'µ'] +['è½', '·'] +['è½', '¹'] +['è½', 'º'] +['æĺ', 'º'] +['ðª', '¾'] +['ðª¾', '¢'] +['æĺ', '½'] +['çĽ', '·'] +['åĴ', '¡'] +['åĴ', 'º'] +['æĺ', '³'] +['æĺ', '£'] +['æĺ', '¤'] +['æĺ', '«'] +['æĺ', '¡'] +['åĴ', '¥'] +['æĺ', 'ª'] +['èĻ', '·'] +['èĻ', '¸'] +['åĵ', 'ĥ'] +['å³', 'ĺ'] +['èĢ', 'ij'] +['å³', 'Ľ'] +['ðª¨', '°'] +['å³', 'Ĺ'] +['å³', '§'] +['å¸', '¡'] +['éĴ', 'ĺ'] +['ð«ĵ', '§'] +['éĴ', 'ľ'] +['ð¬¬', '®'] +['ð¬¬', '±'] +['ð¬¬', 'Ń'] +['éĴ', 'ª'] +['éĴ', '¬'] +['éĴ', 'Ń'] +['çŁ', '§'] +['ç§', '¬'] +['ä¿', '«'] +['èĪ', 'ģ'] +['ä¿', 'ľ'] +['ä¿', 'Ļ'] +['ä¿', 'į'] +['åŀ', 'ķ'] +['è¡', 'İ'] +['èĪ', '£'] +['å¼', 'ĩ'] +['ä¾', '´'] +['é¸', '§'] +['äı', '¡'] +['èĥ', 'ł'] +['ð¦', '϶'] +['èĥ', 'Ī'] +['èĥ', '©'] +['èĥ', '£'] +['æľ', 'ı'] +['é£', 'IJ'] +['è¨', 'Ħ'] +['é¥', '»'] +['åº', '¤'] +['çĸ', '¢'] +['çĤ', '£'] +['çĤ', 'Ł'] +['ã', '¶'] +['ã¶', '²'] +['æ´', 'Ń'] +['æ´', 'ĺ'] +['æ´', 'ĵ'] +['æ´', '¿'] +['ã³', 'ļ'] +['æ³', 'ļ'] +['æµ', 'Ī'] +['æµ', 'ī'] +['æ´', '¸'] +['æ´', 'ij'] +['æ´', '¢'] +['æ´', 'Ī'] +['æ´', 'ļ'] +['æ´', 'º'] +['æ´', '¨'] +['æµ', 'IJ'] +['ã³', 'ĺ'] +['æ´', '´'] +['æ´', '£'] +['æģ', 'Ķ'] +['å®', '¬'] +['çª', 'Ģ'] +['æī', 'Ĥ'] +['è¢', 'Ĩ'] +['ç¥', 'ı'] +['ç¥', 'IJ'] +['ç¥', 'ķ'] +['åı', 'ļ'] +['éĻ', '§'] +['éĻ', 'ŀ'] +['å¨', 'Ģ'] +['å§', 'ŀ'] +['å§', '±'] +['å§', '¤'] +['å§', '¶'] +['å§', '½'] +['æŀ', '²'] +['ç»', 'ĸ'] +['éª', 'ĥ'] +['ð¬ĺ', '¡'] +['ð¬³', '½'] +['ð¬ĺ', '©'] +['ð«Ħ', '§'] +['å½', 'ĸ'] +['éª', 'ī'] +['æģ', 'Ŀ'] +['çı', 'ª'] +['çı', 'Ľ'] +['çı', '¹'] +['çIJ', 'Ĭ'] +['çİ', '¼'] +['çı', 'ĸ'] +['ðª', 'Ł'] +['ðªŁ', 'Ŀ'] +['çı', '½'] +['çı', '¦'] +['çı', '«'] +['çı', 'Ĵ'] +['ð¬į', '¤'] +['çı', '¢'] +['çı', 'ķ'] +['çı', 'Ŀ'] +['ð«Ń', '¼'] +['åŁ', 'Ĺ'] +['åŀ', '¾'] +['åŀ', 'º'] +['åŁ', 'Ĩ'] +['åŀ', '¿'] +['åŁ', 'Į'] +['åŁ', 'ĩ'] +['èİ', '°'] +['èĮ', 'Ŀ'] +['ð¬ľ', '¯'] +['éĦ', 'Ģ'] +['èİ', '¶'] +['èİ', 'Ŀ'] +['äĵ', 'ĸ'] +['èİ', 'Ļ'] +['æł', '»'] +['æ¡', 'ł'] +['ð¬', 'Ĥ'] +['ð¬Ĥ', '©'] +['æ¡', 'Ħ'] +['æ¢', 'ł'] +['æł', '´'] +['æ¢', '´'] +['æł', 'Ĵ'] +['éħ', 'İ'] +['éħ', 'ı'] +['ð«ł', 'Ĩ'] +['çł', 'µ'] +['çł', 'ł'] +['çł', '«'] +['çł', '¬'] +['ç¡', 'ģ'] +['æģ', '§'] +['ç¿', 'ĥ'] +['éĥ', 'ª'] +['ð¨', 'IJ'] +['ð¨IJ', 'Ī'] +['è¾', 'Ģ'] +['è¾', 'ģ'] +['ð¬', 'Į'] +['ð¬Į', 'Ĺ'] +['åī', 'ķ'] +['èµ', 'Ģ'] +['åĵ', '¢'] +['æĻ', 'ħ'] +['æĻ', 'Ĭ'] +['åĶ', 'Ŀ'] +['åĵ', '³'] +['åĵ', '±'] +['åĨ', 'Ķ'] +['æĻ', 'Ķ'] +['æĻ', 'IJ'] +['çķ', 'ĸ'] +['èļ', 'Ħ'] +['èļ', 'Ĩ'] +['ð«', 'ij'] +['ð«ij', '¡'] +['å¸', '±'] +['å´', 'ģ'] +['å³', '¿'] +['ðª¨', '¶'] +['å´', 'Ħ'] +['å¸', '¨'] +['å', '´Ģ'] +['èµ', 'Ĩ'] +['ð¬', '¬¸'] +['éĴ', '·'] +['ð¬¬', '»'] +['ð¬¬', '¹'] +['ð¬¬', '¿'] +['ð¬Ń', 'ģ'] +['çľ', 'ļ'] +['çĶ', '¡'] +['ç¬', '«'] +['åĢ', '»'] +['åĢ', '´'] +['èĦ', '©'] +['åĢ', '®'] +['åĢ', 'ķ'] +['åĢ', 'ŀ'] +['ð«', '¢'] +['ð«¢', '¸'] +['åĢ', 'ĵ'] +['åĢ', '§'] +['è¡', 'ĥ'] +['èĻ', 'Ĵ'] +['èĪ', 'Ń'] +['èĪ', '¯'] +['èĪ', '¥'] +['çĵ', 'ŀ'] +['é¬', '¯'] +['é¸', '°'] +['èĦ', 'İ'] +['æľ', 'ĵ'] +['èĥ', '²'] +['èĻ', 'ĵ'] +['é±', '½'] +['çĭ', '´'] +['å³', '±'] +['çĭ', '»'] +['çľ', '¢'] +['ð«Ĺ', '§'] +['åĭ', 'į'] +['çĹ', 'Ħ'] +['çĸ', '°'] +['çĹ', 'ĥ'] +['ç«', 'ĺ'] +['ç¾', 'ĸ'] +['ç¾', 'ĵ'] +['æ¡', 'Ĭ'] +['æķ', 'ī'] +['çĥ', 'ł'] +['çĥ', 'Ķ'] +['çĥ', '¶'] +['çĥ', '»'] +['ð¬Ĭ', 'Ī'] +['æ¶', 'į'] +['æµ', '¡'] +['æµ', 'Ń'] +['æµ', '¬'] +['æ¶', 'Ħ'] +['æ¶', '¢'] +['æ¶', 'IJ'] +['æµ', '°'] +['æµ', 'Ł'] +['æµ', 'Ľ'] +['æµ', '¼'] +['æµ', '²'] +['æ¶', 'ĺ'] +['æĤ', 'Ī'] +['æĤ', 'ĥ'] +['æĤ', '¢'] +['ð¬Ĵ', 'Ī'] +['å®', '§'] +['çª', 'ħ'] +['çª', 'Ĭ'] +['çª', 'İ'] +['æī', 'ħ'] +['æī', 'Ĩ'] +['è¢', 'ª'] +['è¢', 'Ĺ'] +['è¢', '¯'] +['ç¥', '§'] +['éļ', 'º'] +['åł', '²'] +['çĸ', 'į'] +['ð¨', 'º'] +['ð¨º', 'Ļ'] +['éĻ', '´'] +['ç', 'ĥĿ'] +['çł', '®'] +['ãĽ', 'ļ'] +['åĵ', '¿'] +['ç¿', 'Ģ'] +['ç¿', 'Ĥ'] +['åī', 'Ł'] +['ð¬³', '¿'] +['ð«Ħ', '¨'] +['ç»', '¤'] +['éª', 'į'] +['ð¬ĺ', '«'] +['ä', 'Ĥ'] +['äĤ', '®'] +['çIJ', 'İ'] +['çı', '¸'] +['çı', 'µ'] +['çIJ', 'Ħ'] +['çIJ', 'Ī'] +['çIJ', 'Ģ'] +['çı', 'º'] +['æİ', 'Ń'] +['åł', 'İ'] +['åł', 'IJ'] +['åŁ', '¼'] +['æİ', 'İ'] +['åŁ', '«'] +['åł', 'Į'] +['æĻ', '¢'] +['ð«', '®'] +['ð«®', 'ĥ'] +['æİ', 'ŀ'] +['åŁ', 'ª'] +['å£', '¸'] +['ãĻ', 'į'] +['èģ', 'į'] +['èı', 'Ŀ'] +['èIJ', 'ļ'] +['èı', '¥'] +['èİ', '¿'] +['äĵ', '«'] +['åĭ', 'ļ'] +['äĵ', '¬'] +['èIJ', 'Ĩ'] +['èı', 'Ĥ'] +['èı', 'į'] +['èı', '¼'] +['èIJ', '£'] +['äĵ', '¨'] +['èı', 'ī'] +['äĵ', 'Ľ'] +['æ¢', '¼'] +['æ¢', '½'] +['æ¡', '²'] +['æ¢', '¾'] +['æ¡', '¯'] +['æ¢', '£'] +['æ¢', 'Į'] +['æ¡', '¹'] +['æķ', 'Ķ'] +['åİ', '£'] +['ç¡', 'Ķ'] +['é¿', 'İ'] +['ç¡', 'Ļ'] +['ç¡', 'ļ'] +['ç¡', 'Ĭ'] +['ç¡', 'į'] +['åĭ', 'Ķ'] +['ä´', 'ķ'] +['é¾', 'ģ'] +['éĢ', '´'] +['åĶ', 'ª'] +['åķ', '«'] +['ç¿', 'Ī'] +['ã', '«'] +['ã«', '°'] +['æĻ', 'Ļ'] +['çķ', '¤'] +['ð¬±', 'ĸ'] +['è¶', '¼'] +['è·', 'Ĥ'] +['èĽ', 'ĥ'] +['èļ', '²'] +['ð¬Ł', '½'] +['èļ', 'º'] +['åķ', '´'] +['äİ', 'ĥ'] +['å´', '§'] +['å´', 'Ł'] +['å´', 'ŀ'] +['å´', 'Ĵ'] +['å´', 'Į'] +['å´', '¡'] +['éĵ', 'ı'] +['ð«ĵ', '¯'] +['ð«Ł', '¹'] +['éĵ', 'ķ'] +['ð«Ł', '¼'] +['éĵ', 'ĸ'] +['éĵ', 'ĺ'] +['éĵ', 'ļ'] +['éĵ', 'ŀ'] +['éĵ', '¥'] +['éĵ', '´'] +['çī', '»'] +['çī', '¿'] +['ç¨', 'Ĩ'] +['ç¬', '±'] +['ç¬', '¯'] +['åģ', '°'] +['åģ', '¡'] +['é¸', 'º'] +['åģ', 'Ń'] +['åģ', '²'] +['åģ', 'ģ'] +['ã', '¿'] +['ã¿', 'ł'] +['éĦ', 'ħ'] +['åģ', 'ĵ'] +['å¾', 'Ľ'] +['è¡', 'Ĵ'] +['èĪ', '³'] +['èĪ', '²'] +['é¸', '¼'] +['æĤ', 'Ĩ'] +['éĦ', 'ĥ'] +['çĵ', '»'] +['ä', 'Ŀ'] +['äĿ', 'Ļ'] +['èĦ', '¶'] +['èĦ', 'ŀ'] +['èĦ', 'Ł'] +['äı', '²'] +['é±', '¾'] +['çĮ', 'ĩ'] +['çĮ', 'Ĭ'] +['çĮ', 'Ħ'] +['è§', 'ĸ'] +['ðł', 'ħ'] +['ðłħ', '¤'] +['åº', '±'] +['åº', '¼'] +['åº', '³'] +['çĹ', 'ĵ'] +['ä´', 'Ķ'] +['ç«', '«'] +['åł', 'ĥ'] +['éĺ', 'Į'] +['ç¾', 'Ŀ'] +['ç¾', 'ķ'] +['çĦ', 'Ĩ'] +['çĥ', 'º'] +['çĦ', 'Į'] +['æ·', 'ı'] +['ð¬ĩ', '¹'] +['æ·', 'Ł'] +['æ·', 'ľ'] +['æ·', '´'] +['æ·', '¯'] +['æ¹', '´'] +['æ¶', '´'] +['ð¬į', '¡'] +['ã', '¥'] +['ã¥', 'Ħ'] +['æĥ', 'Ľ'] +['æĥ', 'Ķ'] +['æĤ', '°'] +['æĥ', 'Ļ'] +['å¯', 'ģ'] +['éĢ', 'Ń'] +['ð¬¤', 'ĩ'] +['ð«į', '¯'] +['è¢', '¼'] +['è£', 'Ī'] +['ç¥', '²'] +['ð¬¤', 'Ĭ'] +['ð«į', '²'] +['è°', 'ŀ'] +['èī', '´'] +['å¼', '¸'] +['å¼', '¶'] +['ð¬¯', 'İ'] +['éļ', 'ĥ'] +['å©', 'ŀ'] +['å¨', 'µ'] +['å©', '¼'] +['åª', 'ĸ'] +['å©', '³'] +['å©', 'į'] +['å©', 'Į'] +['å©', '«'] +['å©', '¤'] +['å©', 'ĺ'] +['å©', 'ł'] +['ð¬ĺ', '¬'] +['ð¬ĺ', 'Ń'] +['ð¬´', 'Ĥ'] +['ð«ĺ', '¦'] +['ç»', '¹'] +['ð«Ł', 'ħ'] +['ð¬ĺ', '¯'] +['éª', 'ķ'] +['ð«ĺ', '§'] +['çµ', 'ľ'] +['çı', '·'] +['çIJ', '²'] +['çIJ', '¡'] +['çIJ', 'Ł'] +['çIJ', 'Ķ'] +['çIJ', 'Ń'] +['åł', '¾'] +['åł', '¼'] +['æı', 'ķ'] +['ãĻ', 'ĺ'] +['åł', '§'] +['åĸ', 'Ĩ'] +['åł', '¨'] +['å¡', 'ħ'] +['åł', 'ł'] +['çµ', '·'] +['ðª', '£'] +['ðª£', '»'] +['ð¡', 'İ'] +['ð¡İ', 'ļ'] +['è', 'ijľ'] +['æĥ', 'İ'] +['èIJ', '³'] +['èij', 'Ļ'] +['éĿ', '¬'] +['èij', '´'] +['èĴ', 'ĩ'] +['èĴ', 'Ī'] +['éĦ', 'ļ'] +['èĴ', 'ī'] +['èĵ', 'ĩ'] +['èIJ', '©'] +['èij', '°'] +['èij', 'İ'] +['éĦ', 'ij'] +['èĴ', 'İ'] +['èij', 'ĸ'] +['èĴ', 'Ħ'] +['èIJ', '¹'] +['æ£', '¤'] +['æ£', '½'] +['æ£', '«'] +['æ¤', 'ĵ'] +['æ¤', 'ij'] +['ð¬', 'ĥ'] +['ð¬ĥ', 'Ĭ'] +['é¹', 'Ģ'] +['æ¤', 'Ĩ'] +['æ£', 'ĵ'] +['æ£', '¬'] +['æ£', 'ª'] +['æ¤', 'Ģ'] +['æ¥', 'Ĺ'] +['ð¬', '·'] +['ð¬·', 'ķ'] +['çĶ', '¦'] +['éħ', '¦'] +['è§', 'Į'] +['å¥', '¡'] +['çļ', 'ķ'] +['ç¡', 'ª'] +['æ¬', '¹'] +['è©', 'Ł'] +['ð«IJ', 'IJ'] +['è¾', 'Į'] +['æ£', 'IJ'] +['é¾', 'Ĥ'] +['ð¬', '¹'] +['ð¬¹', '¼'] +['é»', '¹'] +['çī', 'ļ'] +['çĿ', 'İ'] +['æĻ', '«'] +['æĻ', 'ª'] +['æĻ', '±'] +['ð', '§'] +['ð§', '¿'] +['ð§¿', '¹'] +['èĽ', 'ij'] +['çķ', '¯'] +['æĸ', 'Ŀ'] +['åĸ', '¤'] +['å´', '¶'] +['åµ', 'ģ'] +['ð«', '¶'] +['ð«¶', 'ĩ'] +['å´', '¾'] +['åµ', 'ħ'] +['å´', '¿'] +['åµ', 'ļ'] +['ç¿', 'Ļ'] +['ð«ĸ', '®'] +['åľ', 'Į'] +['åľ', 'IJ'] +['èµ', 'ij'] +['èµ', 'Ĵ'] +['é¿', 'ı'] +['éĵ', '¹'] +['ð¬Ń', 'Ĭ'] +['éĵ', '½'] +['ð¨±', 'ĩ'] +['ð«ĵ', '¶'] +['éĶ', 'Ĭ'] +['éĶ', 'į'] +['éĶ', 'İ'] +['ð¬Ń', 'İ'] +['éĶ', 'ĵ'] +['çĬ', 'ĩ'] +['é¢', 'ĭ'] +['ç¨', 'Į'] +['çŃ', 'Ģ'] +['çŃ', 'ĺ'] +['çŃ', 'ľ'] +['çŃ', '¥'] +['çŃ', 'ħ'] +['åĤ', 'ĥ'] +['åĤ', 'ī'] +['ç¿', 'Ľ'] +['åĤ', 'Ĵ'] +['åĤ', 'ķ'] +['èĪ', '¾'] +['çķ', '¬'] +['ð«ĸ', '¯'] +['èĦ', '¿'] +['èħ', 'ĺ'] +['ä', 'IJ'] +['äIJ', 'ĥ'] +['èħ', 'Ļ'] +['èħ', 'Ĵ'] +['ð¬±', 'Ł'] +['é²', 'ĥ'] +['çĮ', '°'] +['ð«', 'Ľ'] +['ð«Ľ', 'Ń'] +['çĮ', '¯'] +['ã', 'º'] +['ãº', 'Ħ'] +['é¦', 'ī'] +['åĩ', 'ĵ'] +['éĦ', 'Ĺ'] +['ð«', '·'] +['ð«·', '·'] +['å»', 'ĭ'] +['å»', 'Ĩ'] +['éĦ', 'Į'] +['ç²', '¢'] +['éģ', 'Ĩ'] +['æĹ', 'IJ'] +['ð¬®', '±'] +['çĦ', 'ŀ'] +['ð¬Ĭ', '¤'] +['æ¬', '»'] +['ð£', '¸'] +['ð£¸', '£'] +['æº', 'ļ'] +['æº', 'ģ'] +['æ¹', 'Ŀ'] +['æ¸', '°'] +['æ¹', 'ĵ'] +['ã', '´'] +['ã´', 'Ķ'] +['æ¸', 'Ł'] +['æº', 'ł'] +['æ¸', '¼'] +['æº', 'ĩ'] +['æ¹', '£'] +['æ¹', 'ij'] +['æº', 'ŀ'] +['æĦ', 'IJ'] +['æĦ', 'ĥ'] +['æķ', '©'] +['çĶ', '¯'] +['æ£', '¨'] +['æī', 'Ĭ'] +['è£', '£'] +['ç¥', '¼'] +['å©', '»'] +['åª', 'Ĩ'] +['åª', 'ŀ'] +['ãĽ', '¹'] +['åª', 'ĵ'] +['åª', 'Ĥ'] +['åª', 'Ħ'] +['æ¯', 'µ'] +['çŁ', 'ŀ'] +['ð¬´', 'ĥ'] +['ð«ĺ', '¨'] +['ç¼', 'Ĭ'] +['ç¼', 'IJ'] +['éª', 'Ļ'] +['çij', 'ĥ'] +['çij', 'ĵ'] +['çij', 'ħ'] +['çij', 'Ĩ'] +['ä´', 'ĸ'] +['çij', 'ĸ'] +['çij', 'Ŀ'] +['çij', 'Ķ'] +['çij', 'Ģ'] +['ð¤', '§'] +['ð¤§', 'Ľ'] +['çij', '³'] +['çij', 'Ĥ'] +['å¶', 'ħ'] +['çij', 'ij'] +['éģ', 'ĺ'] +['é«', '¢'] +['å¡', '¥'] +['åł', '½'] +['èµ', 'ª'] +['æij', 'Ľ'] +['å¡', 'Ŀ'] +['æIJ', 'Ĵ'] +['æIJ', 'Į'] +['èĴ', '±'] +['èĴ', '¨'] +['èĵ', 'ı'] +['èĶ', 'Ģ'] +['èĵ', '¢'] +['èĵ', 'Ĥ'] +['èĴ', '»'] +['èĵ', '£'] +['æ¤', '¹'] +['æ¥', 'ª'] +['æ¦', 'ĥ'] +['æ¦', 'ħ'] +['æ¥', 'Ĵ'] +['æ¥', '©'] +['æ¦', 'ĩ'] +['æ¤', '¸'] +['æ¥', 'Ļ'] +['æŃ', 'ħ'] +['ð¬', 'ª'] +['ð¬ª', '©'] +['ç¢', 'ĥ'] +['ç¢', 'ı'] +['ð¬Ĵ', 'Ķ'] +['ç¢', 'Ī'] +['äĥ', 'ħ'] +['ç¡', '¿'] +['éĦ', 'ł'] +['è¾', 'Ĵ'] +['ð¬¨', 'İ'] +['ð«IJ', 'ĵ'] +['é¾', 'Ĩ'] +['è§', 'ľ'] +['ä', '£'] +['ä£', 'ĺ'] +['æļ', 'ķ'] +['é¹', 'į'] +['ð«', '«'] +['ð««', 'ĩ'] +['ã¬', 'Ĭ'] +['æļ', 'ħ'] +['è·', '±'] +['èľ', 'IJ'] +['èľ', 'İ'] +['åµ', '²'] +['èµ', 'Ĺ'] +['éª', '±'] +['éĶ', 'ĸ'] +['ð«ĵ', '¹'] +['éĶ', 'ĺ'] +['éĶ', '³'] +['éĶ', '§'] +['éĶ', 'ª'] +['ð¬Ń', 'ļ'] +['éĶ', '«'] +['éĶ', '¬'] +['ð¬Ń', 'Ľ'] +['ç¨', 'ij'] +['ç¨', 'Ļ'] +['ä', 'ħ'] +['äħ', 'Ł'] +['ð¬', 'ķ'] +['ð¬ķ', 'Ĥ'] +['çŃ', '»'] +['çŃ', '¼'] +['çŃ', '¶'] +['çŃ', '¦'] +['çŃ', '¤'] +['åĤ', 'º'] +['é¹', 'İ'] +['åĥ', 'ĩ'] +['èī', 'ħ'] +['èī', 'ī'] +['è°', '¼'] +['è²', 'Ĩ'] +['èħ', '½'] +['èħ', '¨'] +['èħ', '¯'] +['é²', 'ī'] +['é²', 'Ĭ'] +['é²', 'Į'] +['ä²', 'Ł'] +['ð¬¶', 'ĭ'] +['ð¬¶', 'į'] +['é²', 'ı'] +['éĽ', 'Ĭ'] +['çĮ', 'º'] +['é£', 'Ķ'] +['è§', 'Ł'] +['ð¦', 'Ŀ¼'] +['é¦', 'Į'] +['è£', 'Ľ'] +['å»', 'Ĵ'] +['çĺ', 'ħ'] +['éĦ', 'ĺ'] +['é¹', 'Ĵ'] +['éĦ', 'ľ'] +['éº', 'Ģ'] +['éĦ', '£'] +['éĺ', 'ĺ'] +['ð«Ķ', '¶'] +['çħ', 'ģ'] +['çħ', 'ĥ'] +['çħ', '´'] +['çħ', 'ĭ'] +['çħ', 'Ł'] +['çħ', 'ĵ'] +['æ»', 'ł'] +['æº', 'į'] +['æº', '¹'] +['æ»', 'Ĩ'] +['æ»', 'ī'] +['æº', '¦'] +['æº', 'µ'] +['æ¼', '·'] +['æ»', '§'] +['æ»', 'ĺ'] +['æ»', 'į'] +['æĦ', 'Ń'] +['æħ', '¥'] +['æħ', 'Ĩ'] +['å¡', '±'] +['ð«', 'ĮĢ'] +['è', '£¼'] +['ç¦', 'ĭ'] +['ç¦', 'Ķ'] +['ç¦', 'ĺ'] +['ç¦', 'Ĵ'] +['è°', '«'] +['é¹', 'Ķ'] +['ð«ĸ', '³'] +['æĦ', 'į'] +['å«', 'Ħ'] +['åª', '±'] +['æĪ', '¤'] +['åĭ', 'ł'] +['æĪ', '£'] +['ð«ĺ', 'ª'] +['ð«ĺ', '¬'] +['ç¼', 'ŀ'] +['èĢ', '¤'] +['çij', '§'] +['ð«', 'ŀ'] +['ð«ŀ', '©'] +['çij', '¨'] +['çij', '±'] +['çij', '·'] +['çij', '¢'] +['æĸ', 'ł'] +['æij', 'ı'] +['å¢', 'ķ'] +['å¢', 'Ī'] +['å¢', 'IJ'] +['å¢', 'ĺ'] +['æij', '´'] +['éĬ', 'İ'] +['ð¡', 'IJ'] +['ð¡IJ', 'ĵ'] +['å¢', 'ļ'] +['æĴ', 'ĸ'] +['ðª', '¤'] +['ðª¤', 'Ĺ'] +['éĿ', '½'] +['éŀ', 'ģ'] +['èĶ', 'Į'] +['èĶ', 'Ī'] +['èĵ', '°'] +['èĶ', '¹'] +['èĶ', 'Ĭ'] +['åĺ', 'ı'] +['æ¦', '°'] +['æ¦', 'ij'] +['æ§', 'ļ'] +['ð£', 'Ĺ'] +['ð£Ĺ', 'ĭ'] +['æ§', 'ľ'] +['æ¦', 'į'] +['çĸ', 'IJ'] +['ð¬¸', 'ĺ'] +['éħ', 'º'] +['éħ', '¾'] +['éħ', '²'] +['éħ', '´'] +['ç¢', '¶'] +['äĥ', 'İ'] +['ð¬Ĵ', 'Ĺ'] +['ç¢', '¨'] +['ð¥', 'Ķ'] +['ð¥Ķ', '²'] +['ç¢', '¹'] +['ç¢', '¥'] +['åĬ', 'Ĥ'] +['ð«ļ', 'ĸ'] +['ä´', 'Ĺ'] +['å¤', '¥'] +['çŀ', 'į'] +['é¹', 'ĸ'] +['ã¬', 'İ'] +['è·', '½'] +['èľ', '¾'] +['å¹', 'ĸ'] +['å¶', 'į'] +['åľ', 'Ļ'] +['ð¨±', 'ı'] +['éĶ', 'º'] +['éĶ', '¼'] +['éĶ', '½'] +['ð¬Ń', '¤'] +['éĶ', '¾'] +['éĶ', '¿'] +['éķ', 'ĥ'] +['éķ', 'Ħ'] +['éķ', 'ħ'] +['é¦', 'Ŀ'] +['é¹', 'Ļ'] +['ç®', '¨'] +['ç®', 'ĸ'] +['åĬ', 'Ħ'] +['åĥ', '¬'] +['åĥ', '¦'] +['åĥ', 'Ķ'] +['åĥ', 'İ'] +['æ§', 'ĥ'] +['ãĻ', '¦'] +['é²', 'Ĵ'] +['é²', 'ķ'] +['ð«ļ', 'ķ'] +['é²', 'ĸ'] +['é²', 'Ĺ'] +['é²', 'ĺ'] +['é²', 'Ļ'] +['ð¬¶', 'IJ'] +['ð¬¶', 'ı'] +['ð', '©½'] +['ð©½', '¾'] +['å¤', 'IJ'] +['çį', 'į'] +['é£', 'Ĺ'] +['ð¬¸', 'ļ'] +['åĩ', 'ĺ'] +['å»', 'ij'] +['å»', 'Ļ'] +['çĺ', 'Ĺ'] +['çĺ', '¥'] +['çĺ', 'ķ'] +['é²', 'Ŀ'] +['éĦ', '«'] +['çĨ', 'ĩ'] +['æ¼', '¹'] +['æ¼', 'ĸ'] +['æ½', 'Ĩ'] +['æ¼', '¤'] +['æ½', '©'] +['æ¼', '¼'] +['æ¼', '´'] +['ã', '½'] +['ã½', 'ı'] +['æ¼', 'Ī'] +['æ¼', 'ĭ'] +['æ¼', '»'] +['æħ', '¬'] +['çª', '¬'] +['çª', 'Ń'] +['ã', '®'] +['ã®', '¾'] +['ð¬¤', 'Ŀ'] +['è¤', 'ķ'] +['ç¦', 'Ľ'] +['ç¦', 'ļ'] +['éļ', '©'] +['å«', 'ķ'] +['å«', 'Ń'] +['å«', 'ľ'] +['å«', 'ª'] +['ð¬', 'ĻĤ'] +['ã', '»'] +['ã»', '¬'] +['éº', '¹'] +['çĴ', 'Ĩ'] +['æ¼', '¦'] +['åı', 'ĩ'] +['å¢', '£'] +['å¢', '¦'] +['å¢', '¡'] +['åĬ', 'IJ'] +['èĸ', 'ģ'] +['èķ', '°'] +['èĶ', 'ĥ'] +['é¼', 'Ĵ'] +['æ§', '±'] +['é¹', 'Ŀ'] +['ç£', 'ı'] +['ç£', 'ī'] +['æ®', '£'] +['æħ', 'Ń'] +['éľ', 'ħ'] +['æļ', 'µ'] +['æļ', '²'] +['æļ', '¶'] +['è¸', '¦'] +['è¸', '£'] +['äĹ', 'ĸ'] +['èĿ', 'ĺ'] +['èĿ', '²'] +['èĿ', '¤'] +['åĻ', 'ĩ'] +['å', 'ĻĤ'] +['åĻ', 'Ģ'] +['ç½', '¶'] +['å¶', '²'] +['å¶', 'ĵ'] +['ãł', 'ĩ'] +['å¶', 'Ł'] +['å¶', 'Ĵ'] +['éķ', 'Ĩ'] +['éķ', 'Ī'] +['éķ', 'ĭ'] +['éķ', 'İ'] +['ð¬Ń', '©'] +['éķ', 'ķ'] +['ç¨', '¹'] +['åĦ', 'ĩ'] +['çļ', 'ŀ'] +['çļ', 'Ľ'] +['ä´', 'ĺ'] +['èī', 'İ'] +['èī', 'ı'] +['é¹', 'Ł'] +['ð©¾', 'ĥ'] +['é²', '¦'] +['é²', 'ª'] +['é²', '¬'] +['æ©', '¥'] +['è§', 'Ń'] +['é¹', 'ł'] +['é¹', '¡'] +['ç³', 'ĩ'] +['ç³', 'Ī'] +['ç¿', '¦'] +['é¹', '¢'] +['é¹', '£'] +['çĨ', 'Ľ'] +['æ½', 'ĸ'] +['æ½', 'µ'] +['ã', 'µ'] +['ãµ', 'IJ'] +['æ¾', 'Ĥ'] +['æ¾', 'Ľ'] +['çij', '¬'] +['æ½', '½'] +['æ½', '¾'] +['æ½', 'ı'] +['æĨ', 'Ń'] +['æĨ', 'ķ'] +['ð¬¸', '£'] +['æĪ', 'Ń'] +['è¤', '¯'] +['ç¦', '¤'] +['ð«į', '½'] +['å«', '½'] +['éģ', '¹'] +['ð¬´', 'Ĭ'] +['çĴ', '¥'] +['çĴ', '²'] +['çĴ', 'Ĵ'] +['æĨ', 'Ļ'] +['æĵ', 'IJ'] +['éĦ', '¹'] +['èĸ', '³'] +['éŀ', 'Ķ'] +['é»', 'ĩ'] +['ð¬', 'ŀ'] +['ð¬ŀ', 'Ł'] +['èķ', 'Ĺ'] +['èĸ', '¢'] +['èķ', '¹'] +['æ©', 'ŀ'] +['æ©', 'ij'] +['æ©', '¦'] +['éĨ', 'ij'] +['è§', '±'] +['ç£', '¡'] +['ð¥', 'ķ'] +['ð¥ķ', '¢'] +['ç£', 'ľ'] +['è±', '®'] +['ð«Ł', '¦'] +['ð¬º', 'Ī'] +['ð«ł', 'ľ'] +['é¹', '¾'] +['èĻ', '¤'] +['æļ', '¿'] +['æĽ', 'Į'] +['æĽ', 'Ī'] +['ã¬', 'ļ'] +['è¹', 'ħ'] +['è¸', '¶'] +['äĹ', 'Ľ'] +['èŀ', 'Ĺ'] +['çĸ', 'ģ'] +['ãł', 'ĵ'] +['å¹', 'ª'] +['ðª', '©'] +['ðª©', 'ĺ'] +['å¶', '¦'] +['ð¬Ń', '¬'] +['ð¨±', 'ij'] +['ð¬Ń', '¯'] +['é¦', 'ŀ'] +['ç©', 'Ħ'] +['ç¯', 'ļ'] +['ç¯', '¯'] +['ç°', 'ī'] +['é¼', '½'] +['è¡', 'ł'] +['çĽ', '¦'] +['èŀ', '£'] +['ç¸', '¢'] +['é²', 'Ń'] +['é²', '¯'] +['é²', '°'] +['é²', 'º'] +['é²', '¹'] +['ð«Ĺ', '´'] +['äº', '¸'] +['çĻ', 'Ģ'] +['çĺ', 'Ń'] +['ð¬¸', '¦'] +['ç¾', '±'] +['ç³', 'Ĵ'] +['çĩ', 'ĭ'] +['çĨ', '»'] +['çĩ', 'Ĭ'] +['çĩ', 'ļ'] +['çĩ', 'ı'] +['æ¿', '©'] +['æ¿', 'ĭ'] +['æ¾', 'ª'] +['æ¾', '½'] +['æ¾', '´'] +['æ¾', 'Ń'] +['æ¾', '¼'] +['æĨ', '·'] +['æĨ', 'º'] +['æĩ', 'Ķ'] +['é»', 'ī'] +['å¬', 'Ľ'] +['é¹', '¨'] +['ç¿', '¯'] +['ð«Ħ', '·'] +['çĴ', '±'] +['ð¤', '©½'] +['çĴ', '¬'] +['çĴ', '®'] +['é«', '½'] +['æĵ', '¿'] +['èĸ', '¿'] +['èĸ', '¸'] +['æª', 'ij'] +['æ«', 'Ĩ'] +['æª', 'ŀ'] +['éĨ', '¨'] +['ç', '¹Ħ'] +['ç£', '¹'] +['ç£', '»'] +['çŀ', '«'] +['çŀ', 'µ'] +['è¹', 'IJ'] +['èŁ', 'ı'] +['ã', 'ĺ'] +['ãĺ', 'İ'] +['ð¬Ń', '³'] +['éķ', '¤'] +['ð¬Ń', '¶'] +['ð«Ķ', 'į'] +['éķ', '¥'] +['éķ', '¨'] +['ð¬Ń', '¸'] +['ð¨±', 'Ķ'] +['ð¬Ń', '¼'] +['ð«Ķ', 'İ'] +['çŁ', '°'] +['ç©', 'Ļ'] +['ç©', 'ľ'] +['ç©', 'Ł'] +['ç°', 'ķ'] +['ç°', 'ĥ'] +['ç°', 'ı'] +['åĦ', '¦'] +['éŃ', 'ĭ'] +['æĸ', '¶'] +['èī', 'ļ'] +['ð¬¸', 'ª'] +['è°', '¿'] +['ä²', 'ł'] +['ð¬¶', 'Ł'] +['é²', '¾'] +['ð¬¶', 'ł'] +['é²', '¿'] +['é³', 'ģ'] +['é³', 'Ĥ'] +['é³', 'Ī'] +['é³', 'ī'] +['çį', '¯'] +['äĹ', 'ª'] +['é¦', 'ĺ'] +['è¥', 'ķ'] +['è¥', 'ļ'] +['ð¬¶', '¨'] +['èŀ', '±'] +['çĶ', 'ĵ'] +['å¬', '¬'] +['å¬', '¥'] +['ð¦', 'Ī'] +['ð¦Ī', '¡'] +['ð«Ħ', '¸'] +['çĵ', 'Ģ'] +['éĩ', 'IJ'] +['é¬', '¶'] +['çĪ', 'ĩ'] +['éŀ', '³'] +['éŀ', '®'] +['ð¬Ł', 'ģ'] +['èĹ', 'Ł'] +['èĹ', '¦'] +['èĹ', '¨'] +['é¹', '²'] +['æª', '«'] +['é»', '¡'] +['ç¤', 'ŀ'] +['ç¤', 'Į'] +['ð¥', 'ĸ'] +['ð¥ĸ', '¨'] +['è¹', '¢'] +['è¹', 'ľ'] +['èŁ', '«'] +['äĹ', '´'] +['åļ', 'ļ'] +['é«', 'ĥ'] +['éķ', '®'] +['éķ', '±'] +['éħ', 'Ĥ'] +['é¦', '§'] +['ç°', 'ł'] +['ç°', 'Ŀ'] +['ç°', '°'] +['é¼', '«'] +['é¼', '©'] +['çļ', '¦'] +['èĩ', 'ij'] +['ä²', '¢'] +['é³', 'ij'] +['é³', 'Ĵ'] +['é¹', '±'] +['é¹', '¯'] +['çĻ', 'Ĺ'] +['ð¦', 'Ĵ'] +['ð¦Ĵ', 'į'] +['æĹ', 'ŀ'] +['ç¿', '·'] +['åĨ', 'ģ'] +['äİ', 'ĸ'] +['çĢ', 'Ķ'] +['çĢ', 'į'] +['çĢ', 'Į'] +['è¥', 'ľ'] +['ä´', 'Ļ'] +['ð¬Ļ', 'Ĭ'] +['åļ', 'Ń'] +['ã', '°'] +['ã°', 'Ģ'] +['é¬', '·'] +['éĨ', 'Ń'] +['è¹', '¯'] +['èł', 'ĭ'] +['ç¿', '¾'] +['é³', 'ĺ'] +['åĦ', '³'] +['åĦ', '´'] +['é¼', 'Ĺ'] +['ð¬¶', 'Ń'] +['ð©¾', 'Į'] +['é³', 'ļ'] +['é³', 'Ľ'] +['éº', 'ij'] +['éº', 'ĸ'] +['èł', 'ĥ'] +['å½', 'Ł'] +['å¬', '¿'] +['é¬', 'Ĵ'] +['èĺ', 'ĺ'] +['æ¬', 'Ĥ'] +['é', 'Ĩµ'] +['é¢', '¥'] +['çĶ', 'Ĺ'] +['ð¨', 'Ł'] +['ð¨Ł', 'ł'] +['å·', 'ĩ'] +['éħ', 'ħ'] +['é«', 'İ'] +['çĬ', '¨'] +['ð¬¶', '®'] +['ð¨', 'Ń'] +['ð¨Ń', 'ī'] +['ã¸', 'Į'] +['çĪ', 'Ķ'] +['çĢ', '±'] +['çĢ', '¹'] +['çĢ', '¼'] +['çĢ', 'µ'] +['è¥', '«'] +['åŃ', 'ħ'] +['éª', '¦'] +['ð¬Ļ', 'ĭ'] +['èĢ', '°'] +['ð¤', '«'] +['ð¤«', 'ī'] +['çĵ', 'ĸ'] +['é¬', 'ĺ'] +['è¶', '¯'] +['ð¬º', 'ĵ'] +['ç½', 'į'] +['é¼', '±'] +['é³', 'ł'] +['é³', '¡'] +['é³', '£'] +['çĪ', 'Ł'] +['çĪ', 'ļ'] +['çģ', 'Ī'] +['éŁ', 'Ĥ'] +['ç³', 'µ'] +['èĺ', '¼'] +['ç¤', 'µ'] +['é¹', '´'] +['èº', 'Ķ'] +['çļ', 'Ń'] +['é¾', '¢'] +['é³', '¤'] +['äº', '¹'] +['ç±', '¥'] +['é¼', '·'] +['ð«ļ', 'Ń'] +['çİ', 'ĥ'] +['éĨ', '¾'] +['é½', 'ĩ'] +['è§', '¿'] +['èł', '¼'] +['×', '§'] +['×', '¤'] +['×', 'Ľ'] +['×ķ×', 'ª'] +['×', '¡'] +['×Ļ×', 'Ŀ'] +['×', '¦'] +['×', 'Ĵ'] +['×', 'ĺ'] +['×ķ×', '¨'] +['×', 'Ŀ'] +['×ķ×', 'ľ'] +['×', 'ĸ'] +['à¹', 'Ĥ'] +['ï', 'º'] +['ðŁ', 'į'] +['ðŁ', 'IJ'] +['×Ļ×', '¨'] +['ï', '»'] +['ðŁ', 'ij'] +['ðĿ', 'IJ'] +['ðŁ', 'ı'] +['ðŁ', 'Ķ'] +['ðŁ', 'Į'] +['ðŁ', 'İ'] +['ðŁ', 'ĵ'] +['×', 'Ł'] +['ðĿ', 'ij'] +['×ķ×', 'ĵ'] +['ï', '¦'] +['Ġ×', 'ķ'] +['×ķ×', 'ij'] +['à¸Ń', 'à¸ĩ'] +['ðĿ', 'ĺ'] +['×Ļ×', 'ª'] +['ðĿ', 'ķ'] +['à¸Ĺ', 'ีà¹Ī'] +['اØ', '¦'] +['ðŁ', '¤'] +['×ķ×', 'Ł'] +['ر', 'ÙĬ'] +['×Ļ×', 'ľ'] +['ร', 'ะ'] +['า', 'ย'] +['ï', '¯'] +['ï', '®'] +['า', 'ม'] +['â', 'ĩ'] +['ðŁ', '¥'] +['ï', 'Ń'] +['ðĿ', 'Ļ'] +['×ķ×', 'ł'] +['á', '½'] +['Ġ×', 'Ľ'] +['ðŁ', 'ļ'] +['â', 'ļ'] +['ï', '§'] +['×ij', 'ר'] +['×Ļ×', 'ł'] +['á', '´'] +['Ġ×', 'Ĺ'] +['á', '¼'] +['ðĿ', 'Ĺ'] +['Ġ×', '¢'] +['×Ļ×', 'Ķ'] +['ãģ£', 'ãģŁ'] +['ãģĵ', 'ãģ¨'] +['á', '¸'] +['ÙĬ', 'ÙĨ'] +['ãģª', 'ãģĦ'] +['ا', 'ع'] +['à¸', '¨'] +['à¹Ī', 'à¸ĩ'] +['×Ļ×', 'ĵ'] +['×ŀ', 'ש'] +['á', 'Ī'] +['׳', '×Ļ'] +['×Ļ×', 'ij'] +['ï', '¥'] +['ðĿ', 'ĵ'] +['Ġ×', 'Ļ'] +['×', 'ļ'] +['ั', 'à¸ĩ'] +['â', 'ĵ'] +['ï', '¤'] +['ĠاÙĦ', 'Ø£'] +['า', 'à¸ģ'] +['à¹ī', 'à¸Ļ'] +['à¹Ģ', 'ร'] +['×ķ×', 'Ŀ'] +['á', '¹'] +['à¸', '¶'] +['×Ļ×', '§'] +['à¸', 'ĭ'] +['à¸Ħ', 'ร'] +['à¸', 'ĺ'] +['ั', 'à¸ģ'] +['ðŁ', 'ķ'] +['ÙĪ', 'ÙĨ'] +['à¸Ń', 'ย'] +['â', 'Ĭ'] +['ðĿ', 'Ĵ'] +['ĠاÙĦ', 'ع'] +['า', 'à¸Ļ'] +['×Ļ×', 'Ł'] +['ÙĦ', 'ÙĬ'] +['×Ļ×', '©'] +['à¸Ľ', 'ระ'] +['à¹Ģ', 'à¸Ľ'] +['Ġ×', 'ł'] +['×ķ×', '¡'] +['à¸', 'ł'] +['Ùħ', 'ÙĨ'] +['×ķ×', '¢'] +['×ķ×', 'ŀ'] +['â', 'Į'] +['ðŁ', '§'] +['à¹ĩ', 'à¸Ļ'] +['à¸', 'į'] +['ã', 'İ'] +['á', 'µ'] +['ĠاÙĦ', 'س'] +['×ķ×', '§'] +['ห', 'ล'] +['ðŁ', 'ĩ'] +['â', 'ı'] +['ðŁ', '¦'] +['Ġ×Ķ', '×ŀ'] +['ÙĪ', 'ا'] +['Ġ×', 'ª'] +['ר', '×IJ'] +['à¸Ń', 'à¸Ļ'] +['à¸', '©'] +['à¹Ī', 'ว'] +['×ķ×', '¦'] +['í', 'Ĺ'] +['ã', 'Ħ'] +['ï', '¨'] +['ï', '¹'] +['â', 'İ'] +['ï', '²'] +['ðĿ', 'ļ'] +['ð', 'IJ'] +['à¸Ħ', 'ว'] +['ห', 'à¸Ļ'] +['Ġ×', '¨'] +['ب', 'ÙĬ'] +['ร', 'à¹Į'] +['ر', 'ا'] +['Ø´', 'ر'] +['×ķ×', 'Ĺ'] +['×ķ×', '¤'] +['×ķ×', '©'] +['×ķ×', 'Ĵ'] +['í', 'Ŀ'] +['â', 'Ľ'] +['à¸ķ', 'ิ'] +['à¹Ģ', 'à¸ģ'] +['ï', '³'] +['ï', '±'] +['à¸Ķ', 'à¹ī'] +['ë', '¹'] +['ï', '¬'] +['á', '¿'] +['ðŁ', 'Ľ'] +['ðĿ', 'ĸ'] +['à¹Īา', 'à¸ĩ'] +['ู', 'à¹ī'] +['Ġ×Ķ', '×IJ'] +['ĠاÙĦ', 'ØŃ'] +['פ', 'ר'] +['ÙĪ', 'Ùħ'] +['à¹Ģ', 'ล'] +['í', 'ĸ'] +['×Ļ×', '¢'] +['ì', 'Ī'] +['í', 'ĵ'] +['ðŁ', 'ħ'] +['á', 'ł'] +['à¸Ħว', 'าม'] +['à¸Ī', 'ะ'] +['׳', '×Ķ'] +['Ġ×', '§'] +['à¸', 'Ł'] +['à¹ī', 'à¸ĩ'] +['ห', 'ม'] +['ت', 'Ùħ'] +['׾', '×Ļ'] +['ÙĬ', 'د'] +['à¹Ī', 'à¸Ļ'] +['×Ĺ', 'ר'] +['ש', 'ר'] +['à¹Ģ', 'à¸Ĺ'] +['×ŀ', 'ר'] +['ë', 'ĸ'] +['ع', 'ÙĦ'] +['×ŀ', '×¢'] +['â', '²'] +['׾', '×Ķ'] +['Ġ×', '¤'] +['à¸Ń', 'à¸ģ'] +['س', 'ÙĦ'] +['×Ļ×', 'ŀ'] +['ÙĤ', 'ÙĬ'] +['í', 'İ'] +['ت', 'ØŃ'] +['×Ļ×', '¡'] +['×Ļ×', 'Ĺ'] +['í', 'Ľ'] +['ï', '°'] +['â', '½'] +['á', 'ī'] +['á', 'Ĭ'] +['á', '¨'] +['Ùĩ', 'ا'] +['Ġ׾', '×Ķ'] +['×ķ×', 'IJ'] +['Ùħ', 'ا'] +['à¹īà¸Ń', 'à¸ĩ'] +['ر', 'ب'] +['ĠاÙĦ', 'ج'] +['×ŀ', '×ĵ'] +['Ùħ', 'ÙĦ'] +['ت', 'ر'] +['à¹Ģ', 'à¸Ķ'] +['×§', 'ר'] +['í', 'ħ'] +['ì', '¼'] +['ê', '¿'] +['ã', 'Ī'] +['á', 'IJ'] +['ðŁ', 'Ĺ'] +['ê', '¦'] +['á', 'ĭ'] +['ðĿ', 'Ķ'] +['à¹Ģà¸Ľ', 'à¹ĩà¸Ļ'] +['à¹ĥ', 'ห'] +['ม', 'า'] +['ว', 'à¹Īา'] +['ม', 'ี'] +['ี', 'à¹ī'] +['à¹Ħม', 'à¹Ī'] +['ÙĨ', 'ÙĬ'] +['Ø', '¤'] +['ร', 'า'] +['×ķ', '×Ļ'] +['ãĤĪ', 'ãģĨ'] +['ิ', 'à¸Ķ'] +['×Ļ×', '¤'] +['×Ĺ', '׾'] +['ÙĤ', 'د'] +['à¹Ģ', 'ส'] +['×Ļ×', 'ĺ'] +['à¸ģ', 'ล'] +['ר', '׼'] +['×ķ×', 'Ľ'] +['×Ļ×', 'Ľ'] +['ë', 'Ī'] +['ë', 'ĥ'] +['ðŁ', 'ĸ'] +['á', 'ħ'] +['â', '¼'] +['ã', 'ī'] +['à¹Ħ', 'à¸Ķà¹ī'] +['ת', '×Ļ'] +['×Ļ×', 'IJ'] +['ĠاÙĦ', 'Ø¥'] +['à¸ł', 'า'] +['ร', 'ิ'] +['ÙĤ', 'Ø©'] +['ØŃ', 'د'] +['ê', '»'] +['ì', '±'] +['ת', '×Ĺ'] +['ì', 'º'] +['â', 'ĭ'] +['á', 'Ħ'] +['á', '¾'] +['â', 'µ'] +['â', '¾'] +['ĠÙĪ', 'اÙĦ'] +['׳', '×ķ'] +['Ù', 'Ģ'] +['ÙĬ', 'ا'] +['à¸ģ', 'à¹ĩ'] +['×ŀ', '×Ķ'] +['ãģĦ', 'ãĤĭ'] +['ع', 'د'] +['ĠاÙĦ', 'ÙĨ'] +['Ġ×Ķ', 'ש'] +['Ø', '¦'] +['ั', 'à¹īà¸ĩ'] +['ร', 'ัà¸ļ'] +['ÙĪ', 'ÙĤ'] +['ãģ§', 'ãģį'] +['à¹Ģ', 'à¸ŀ'] +['׼', '׾'] +['×ĺ', 'ר'] +['ั', 'à¸Ķ'] +['à¸Ń', 'า'] +['ì', '¢'] +['à¸Ń', 'à¸ļ'] +['à¸ķ', 'ร'] +['à¹Ģ', 'à¸Ĭ'] +['ì', 'Ķ'] +['ãģĹ', 'ãģ¾'] +['ë', 'ģ'] +['ë', 'ķ'] +['ðŁ', 'Ļ'] +['â', 'Ĵ'] +['á', '¶'] +['à¹ģ', 'ล'] +['ÙĨ', 'ا'] +['à¹ĥห', 'à¹ī'] +['à¹Ħ', 'à¸Ľ'] +['×', '£'] +['ั', 'ว'] +['า', 'à¸ĩ'] +['×ĵ', 'ר'] +['×ij', '׾'] +['פ', '×Ļ'] +['Ġ×', 'ĵ'] +['ĠاÙĦ', 'Ùģ'] +['à¹Ģ', 'à¸Ĥ'] +['ש', '×Ķ'] +['×IJ', 'ר'] +['ë', '¬'] +['ãģ«', 'ãģª'] +['ÑĢ', 'о'] +['ว', 'ิ'] +['Ùħ', 'ر'] +['×IJ', 'ת'] +['Ùĥ', 'ر'] +['س', 'ب'] +['ÙĨ', 'ت'] +['ãģĹ', 'ãģĦ'] +['ا', 'ج'] +['à¸Ń', 'รà¹Į'] +['Ùĥ', 'ÙĦ'] +['س', 'Ùħ'] +['ส', 'ิ'] +['×Ļ×', '¦'] +['ë', 'Ŀ'] +['í', 'ľ'] +['ì', 'ī'] +['á', 'Ĩ'] +['Ùĩ', 'Ùħ'] +['à¸Ļ', 'ีà¹ī'] +['ãģĤ', 'ãĤĭ'] +['ãģĦ', 'ãģ¦'] +['س', 'ÙĬ'] +['׾', '×IJ'] +['د', 'ر'] +['ãģ', 'ļ'] +['ÙĪ', 'ج'] +['ĠاÙĦ', 'Ø®'] +['ص', 'ر'] +['í', 'ı'] +['à¹īา', 'à¸ĩ'] +['ุ', 'à¸Ķ'] +['×ķ×', 'ĺ'] +['×ij', '×¢'] +['í', 'Ĩ'] +['à¸Ĭ', 'า'] +['ร', 'ม'] +['ש', '×ŀ'] +['×ŀ', 'ס'] +['ê', '´'] +['ì', '´'] +['ë', 'ľ'] +['ì', '¿'] +['ì', '©'] +['ë', '»'] +['â', '¤'] +['ðŁ', 'Ĩ'] +['á', 'Į'] +['á', 'ķ'] +['ذ', 'ا'] +['à¸Ĺ', 'ำ'] +['à¸ķ', 'à¹Ī'] +['ĠاÙĦ', 'ÙĤ'] +['ÙĦ', 'Ùĥ'] +['ู', 'à¹Ī'] +['à¸Ħ', 'ุ'] +['ÙĬ', 'Ùħ'] +['׳', '×Ļ×Ŀ'] +['ืà¹Ī', 'à¸Ń'] +['ÙĪ', 'ع'] +['ãĤ', 'ĩ'] +['ا', 'ÙĤ'] +['Ġ×ij', '×¢'] +['à¹Ģ', 'ม'] +['ج', 'Ùħ'] +['á»', '«'] +['ãģĵãģ¨', 'ãģĮ'] +['ب', 'د'] +['×ķ×', 'Ķ'] +['ש', '׾'] +['Ùĩ', 'ر'] +['à¹Ģ', 'à¸Ļ'] +['ãģ', '¹'] +['í', 'ĭ'] +['ì', '»'] +['ì', '½'] +['ë', 'Ń'] +['ì', 'Į'] +['í', 'Ģ'] +['ë', 'Į'] +['ë', 'º'] +['ã', 'Ĭ'] +['à¹ĥ', 'à¸Ļ'] +['Ġ×', 'Ĵ'] +['à¹', 'Ĩ'] +['à¸Ī', 'าà¸ģ'] +['ว', 'ย'] +['à¹ĥ', 'à¸Ĭ'] +['à¸ĩ', 'าà¸Ļ'] +['ĠاÙĦ', 'Ø´'] +['ا', 'ØŃ'] +['à¹īา', 'à¸Ļ'] +['ืà¹Ī', 'à¸Ńà¸ĩ'] +['×IJ', '×Ļ'] +['ب', 'ÙĦ'] +['ãģ¨', 'æĢĿ'] +['׳', 'ס'] +['ãģ¾', 'ãģĽ'] +['Ùĥ', 'ÙĨ'] +['×¢', 'ר'] +['ĠاÙĦ', 'د'] +['ש', 'ת'] +['í', 'ŀ'] +['Ùħ', 'س'] +['ص', 'ÙĦ'] +['×ķ׳', '×Ķ'] +['ار', 'Ø©'] +['ÙĦ', 'Ùħ'] +['ส', 'ม'] +['Ø£', 'ÙĨ'] +['ת', 'ר'] +['×IJ', '×ŀ'] +['ع', 'ب'] +['Ø®', 'ت'] +['ãĤ', 'ĥ'] +['ì', '¡'] +['ì', '£'] +['ив', 'а'] +['ส', 'ั'] +['ึ', 'à¸ģ'] +['ì', '¸'] +['ë', 'Ĩ'] +['алÑĮ', 'н'] +['ì', '³'] +['ì', 'į'] +['ê', '¼'] +['ê', '½'] +['ì', 'ı'] +['ã', 'Į'] +['ã', 'ı'] +['ï', '©'] +['ê', 'ª'] +['á', 'İ'] +['Ġ×', 'ĸ'] +['à¸ģ', 'ัà¸Ļ'] +['×Ļ', '×ķ'] +['à¸Ħ', 'à¸Ļ'] +['׳', '×ķת'] +['à¸ľ', 'ูà¹ī'] +['à¹ĥ', 'à¸Ī'] +['ãģĦ', 'ãģŁ'] +['Ùģ', 'ر'] +['×ĺ', '×Ļ'] +['צ', '×Ļ'] +['ãĤĤ', 'ãģ®'] +['ĠاÙĦ', 'ص'] +['ãģ¾ãģĽ', 'ãĤĵ'] +['د', 'Ø©'] +['×ij', '×Ļ'] +['ĠاÙĦ', 'ر'] +['Ġ×ŀ', '×IJ'] +['ส', 'ำ'] +['à¹Ģ', 'ห'] +['ع', 'ر'] +['ãģª', 'ãģı'] +['à¸ģร', 'ะ'] +['×ij', '×ĵ'] +['à¹Ģ', 'à¸Ī'] +['×Ļ×', 'ļ'] +['×Ĺ', '×Ļ'] +['ÙĬ', 'ع'] +['ש', '×ij'] +['ÙĨ', 'Ø©'] +['ÙĪ', 'ض'] +['ÙĦ', 'Ùģ'] +['ÙĢ', 'ÙĢ'] +['פ', '×¢'] +['í', 'Ī'] +['×ŀ', '×§'] +['à¸', 'IJ'] +['ØŃ', 'Ø©'] +['ا', 'ص'] +['Ñĭв', 'а'] +['à¸Ħ', 'ม'] +['ว', 'ั'] +['à¸Ľ', 'ล'] +['ì', 'Ł'] +['í', 'ļ'] +['ë', '´'] +['ë', 'ij'] +['ë', 'ī'] +['ë', 'ĩ'] +['ì', '¨'] +['ë', '±'] +['ë', 'İ'] +['â', '¬'] +['á', '¥'] +['á', 'Ĺ'] +['á', 'Ľ'] +['á', 'į'] +['Å', '©'] +['à¸Ķ', 'ี'] +['ô', 'i'] +['Ġ×', '¡'] +['׾', '×ķ'] +['á»Ŀ', 'i'] +['à¸Ħุ', 'à¸ĵ'] +['â', 'y'] +['à¸Ļ', 'า'] +['×Ĺ', '×ĵ'] +['×ĵ', '×Ļ'] +['ห', 'า'] +['ج', 'ÙĦ'] +['à¹Ģ', 'ว'] +['ãĤĩ', 'ãģĨ'] +['Ùħ', 'Ø©'] +['ĠاÙĦ', 'Ùĥ'] +['Ġ×Ķ', '×¢'] +['ج', 'ر'] +['×ĸ', 'ר'] +['ا', 'Ø·'] +['׼', 'ת'] +['×ķ׳', '×Ļ×Ŀ'] +['ØŃ', 'Ùħ'] +['ê', '¶'] +['ر', 'Ùĥ'] +['Ġ׾', '×¢'] +['×ķ×', 'ĸ'] +['ส', 'ร'] +['צ', '׾'] +['Ø', '¢'] +['ا', 'ست'] +['à¹Ī', 'ม'] +['Ø®', 'ر'] +['צ', '×¢'] +['×Ļר', '×ķת'] +['اد', 'Ø©'] +['Ø´', 'ار'] +['×ŀ', '×Ĺ'] +['í', 'Ĵ'] +['à¹Ģร', 'ีย'] +['×Ĺ', '×§'] +['اØ', '«'] +['ร', 'à¸ĩ'] +['à¹Ģ', 'à¸ķ'] +['à¸Ī', 'ำ'] +['à¸', 'Ŀ'] +['à¹Īา', 'ย'] +['à¸Ħ', 'ล'] +['ÙĤ', 'ÙĪ'] +['иÑĩеÑģ', 'к'] +['à¸ĵ', 'à¹Į'] +['ั', 'ย'] +['Ùħ', 'ع'] +['ë', '¨'] +['ë', '¿'] +['ë', '®'] +['ï', '´'] +['ì', '¥'] +['ì', '«'] +['ë', 'µ'] +['á', '¡'] +['â', 'į'] +['ð', 'ĵ'] +['â', '°'] +['à¸Ĥ', 'à¸Ńà¸ĩ'] +['Ù', 'ĭ'] +['à¸ģ', 'ัà¸ļ'] +['ãģ®', 'ãģ§'] +['à¹ī', 'ว'] +['à¸Ńย', 'à¹Īาà¸ĩ'] +['ãģ', 'Ń'] +['á»ĩ', 't'] +['à¸ķ', 'à¹īà¸Ńà¸ĩ'] +['×ŀ', '×Ļ'] +['à¹ģ', 'à¸ļ'] +['×Ĵ', 'ר'] +['ÙĪ', 'Ùģ'] +['ÙĤ', 'ÙĦ'] +['à¸łà¸²', 'à¸ŀ'] +['ר', '×Ļ'] +['ล', 'า'] +['ÙĬ', 'س'] +['Ġ×', '¦'] +['ÙĬ', 'Ùģ'] +['Ġ×', 'ĺ'] +['à¸ľ', 'ล'] +['á', 'ng'] +['ร', 'ว'] +['Ġ×ŀ', 'ש'] +['×IJ', '×ķת'] +['×ĸ', '×Ķ'] +['ู', 'à¸ģ'] +['à¸Ļ', 'ัà¸ģ'] +['اÙĨ', 'ÙĬ'] +['د', 'ا'] +['ãģ', '³'] +['׼', 'ף'] +['ãĤī', 'ãĤĮ'] +['ãĤĮ', 'ãģ°'] +['ת', '×§'] +['ú', 'c'] +['ÙĪ', 'ز'] +['×Ļר', '×Ķ'] +['Ġn', 'gh'] +['án', 'h'] +['Ġ×ķ', '×IJ'] +['á»', 'ħ'] +['ส', 'ุà¸Ķ'] +['ë', 'į°'] +['ا', 'ض'] +['اÙĦ', 'ÙĬ'] +['ب', 'ار'] +['ع', 'Ùħ'] +['à¸ļ', 'า'] +['ت', 'ج'] +['à¸ŀ', 'ร'] +['×ķר', '×Ķ'] +['ả', 'ng'] +['Ø®', 'ÙĦ'] +['à¸', 'ī'] +['ắ', 'c'] +['ש', '×Ļ×Ŀ'] +['í', 'Ķ'] +['Ùģ', 'س'] +['×Ļ×', 'Ĵ'] +['п', 'ÑĢ'] +['ĠاÙĦ', 'Ø«'] +['س', 'Ø·'] +['ร', 'ูà¹ī'] +['ีà¹Ī', 'ย'] +['à¸Ń', 'à¸Ķ'] +['ãģª', 'ãĤĬ'] +['×Ĵ', '×ĵ'] +['ãģĦ', 'ãģ¾ãģĹãģŁ'] +['ס', '×§'] +['Ø®', 'ص'] +['la', 'ÅŁ'] +['ен', 'но'] +['ب', 'ØŃ'] +['ส', 'à¸Ļ'] +['à¸', '®'] +['ר×IJ', 'ש'] +['Ùħ', 'ÙĪ'] +['دÙĬ', 'د'] +['ษ', 'า'] +['×ķ×', 'ļ'] +['ãĥ§', 'ãĥ³'] +['à¸ķ', 'ุ'] +['Ġê', 'µ'] +['ĠÑģв', 'о'] +['צ', '×ij'] +['à¸Ń', 'ม'] +['à¸Ľ', 'ร'] +['ت', 'ع'] +['×Ķ', 'ת'] +['اÙħ', 'ÙĦ'] +['×ŀ', '׳'] +['ç', '¶ļ'] +['à¸', '¤'] +['í', 'į'] +['ë', 'ĺ'] +['ë', '¤'] +['ì', 'ij'] +['â', '´'] +['ã', 'ĭ'] +['Ġب', 'اÙĦ'] +['á»ģ', 'u'] +['ĠاÙĦ', 'ÙĦ'] +['à¸ķ', 'ัว'] +['ذ', 'Ùĩ'] +['ึ', 'à¸ĩ'] +['à¹ĥà¸Ĭ', 'à¹ī'] +['á»ĵ', 'ng'] +['à¸Ļ', 'ั'] +['ม', 'าà¸ģ'] +['ãĥ', 'Ł'] +['×ŀ', '×ķ'] +['à¸Ĺ', 'ย'] +['á»Ļ', 'i'] +['áº', '±'] +['ả', 'o'] +['à¹Ĥ', 'à¸Ķ'] +['×IJ', '׾'] +['ส', 'าม'] +['ÙĪ', 'ب'] +['à¸Ĺ', 'ุ'] +['ย', 'ัà¸ĩ'] +['×¢', 'ת'] +['×ķ׳', '×ķת'] +['à¸Ĥ', 'ึ'] +['à¸Ĥึ', 'à¹īà¸Ļ'] +['à¸ģ', 'à¹Ī'] +['áº', '«'] +['á»ij', 'c'] +['ãģĹ', 'ãĤĩãģĨ'] +['á»ĭ', 'ch'] +['Ġ×IJ', '×ķת'] +['Ġש', '×IJ'] +['׼', '×ķ׾'] +['á»Ļ', 'c'] +['ع', 'Ø©'] +['à¸Ĺ', 'ี'] +['à¹Ģ', 'à¸Ń'] +['Ùĥ', 'ت'] +['ãģ', '»'] +['áº', '»'] +['ìĹ', 'ħ'] +['à¸Ń', 'à¸Ńà¸ģ'] +['اÙĨ', 'ت'] +['à¹Ħ', 'ร'] +['Ġ×IJ', '×Ĺר'] +['Ø·', 'ر'] +['ÙĨ', 'د'] +['ื', 'à¹īà¸Ń'] +['Ø·', 'ÙĦ'] +['×IJ', '×Ķ'] +['uy', 'ên'] +['í', 'ĸī'] +['×ij', '×Ķ'] +['à¸Ħ', 'à¹Ī'] +['à¸Ĭ', 'à¹Īว'] +['ãģĤãĤĬ', 'ãģ¾ãģĻ'] +['ÙĬ', 'ب'] +['×§', '׾'] +['ãĥ', 'Ļ'] +['Ä', '©'] +['س', 'ر'] +['า', 'ว'] +['ãĤ', '±'] +['à¸ļ', 'ริ'] +['ר', '×Ĵ'] +['á»ĥ', 'u'] +['ØŃ', 'ت'] +['×ķ×ŀ', '×Ļ'] +['ب', 'ÙĨ'] +['êµ', 'IJ'] +['ÄŁ', 'u'] +['ãģª', 'ãĤĵ'] +['×ij', '×§'] +['Ġפ', 'ר'] +['ắ', 'n'] +['ØŃ', 'ÙĦ'] +['×ij', '×Ĺ'] +['ấ', 'u'] +['×ij', '×ķ×ĵ'] +['ãĥ', '¯'] +['Ġ׾', '×§'] +['ั', 'à¸į'] +['à¸ŀ', 'ิ'] +['×Ĺ', '×Ķ'] +['×ĸ', '׼'] +['ãĥ¼ãĥ', 'ł'] +['ÑĤ', 'елÑĮ'] +['×ŀ', '×Ļ×ĵ'] +['ÙĬ', 'Ø®'] +['áº', '³'] +['ت', 'ص'] +['à¸ĺ', 'ิ'] +['è¾', '¼'] +['ì', 'ĵ'] +['Ùĥ', 'Ø©'] +['ÙĤ', 'ب'] +['à¸Ħ', 'à¹Į'] +['à¹īา', 'ย'] +['à¸ĵ', 'ะ'] +['า', 'ะ'] +['ë', 'Ĵ'] +['ê', '¾'] +['ë', '·'] +['ì', 'ĩ'] +['ê', 'º'] +['ì', 'ģ'] +['ë', 'Ģ'] +['ì', '¾'] +['ë', '½'] +['ë', 'ļ'] +['ì', 'Ń'] +['ì', 'İ'] +['á', 'ij'] +['ë', 'Ĺ'] +['ê', 'Ĵ'] +['à', '¡'] +['à', '¬'] +['ðIJ', 'Į'] +['ã', 'ĩ'] +['ðĿ', 'Ħ'] +['Ġ׾', '×IJ'] +['ãģ¨', 'ãģĦãģĨ'] +['Ġn', 'hi'] +['×Ļ', '×ķת'] +['Ġש', '×Ķ'] +['à¹ģล', 'à¹īว'] +['Æ°á»Ľ', 'c'] +['à¸Ķà¹ī', 'วย'] +['à¸Ĺ', 'าà¸ĩ'] +['׳', 'ת'] +['פ', 'ת'] +['à¹ģ', 'à¸ķà¹Ī'] +['ư', 'ng'] +['à¸Ńย', 'ูà¹Ī'] +['à¹ī', 'ำ'] +['Ġ×IJ', '׾'] +['Ùĥ', 'Ùħ'] +['ấ', 'p'] +['ล', 'à¸ĩ'] +['ãģŁ', 'ãĤģ'] +['×Ĵ', '׾'] +['ห', 'ร'] +['ĠÑĢ', 'е'] +['à¹Ģà¸Ĥ', 'à¹īา'] +['ÙĤ', 'ر'] +['Ġ×Ķ', 'ס'] +['ÙĪ', 'ÙĬ'] +['สาม', 'าร'] +['สามาร', 'à¸ĸ'] +['Äĥ', 'n'] +['à¸Ń', 'ี'] +['פ', '×ķ'] +['×Ļ׳', '×ķ'] +['ว', 'ัà¸Ļ'] +['ặ', 'c'] +['íķ', 'Ļ'] +['×ŀ', 'ת'] +['ê', 'u'] +['áº', '¹'] +['Ùģ', 'ÙĬ'] +['×ŀ', 'צ'] +['à¸Ħ', 'า'] +['ãģĿ', 'ãģĨ'] +['ãĢ', 'ħ'] +['ا', 'ز'] +['ا', 'Ùĩ'] +['ר', '×Ļ×Ŀ'] +['ấ', 'n'] +['ห', 'าร'] +['ạ', 't'] +['ÙĨ', 'Ùĩ'] +['à¹Ģ', 'à¸Ħร'] +['ج', 'Ùĩ'] +['׼', '×Ļ'] +['ắ', 't'] +['à¸Ħ', 'à¹īา'] +['ر', 'Ø©'] +['ãĥ', 'ı'] +['Ùĥ', 'ÙĪÙĨ'] +['ứ', 'ng'] +['Ġìļ', '°'] +['ย', 'à¹Į'] +['à¹Īว', 'à¸Ļ'] +['à¸ģ', 'ำ'] +['Ø«', 'ر'] +['Ñģ', 'и'] +['ĠاÙĦ', 'Ø·'] +['Ġ×Ķ', 'צ'] +['ĠØ', '·'] +['ĠاÙĦ', 'ÙĪ'] +['ê¹', 'Į'] +['ØŃ', 'ÙĬ'] +['ار', 'ات'] +['à¹Ģ', 'à¸ĭ'] +['ب', 'ا'] +['г', 'ÑĢ'] +['ร', 'ี'] +['ืà¸Ń', 'à¸Ļ'] +['ع', 'ت'] +['ÙĤ', 'اÙĦ'] +['د', 'Ùħ'] +['Ø', '¡'] +['Ġ×ŀ', '×§'] +['×ĵ', '×Ļ×Ŀ'] +['×¢', '׾'] +['ãģ', 'Ĵ'] +['ëĭ', 'ĺ'] +['×¢', '×Ķ'] +['Ġìĸ', '´'] +['Ñģ', 'ÑĮ'] +['ÙĤ', 'Ø·'] +['ãĥ', 'Ľ'] +['èĢĥ', 'ãģĪ'] +['à¹ģ', 'à¸Ļ'] +['ÙĪ', 'ات'] +['â', 'u'] +['ĠìĤ¬', 'ëŀ'] +['ห', 'ว'] +['ĠاÙĦØ£', 'Ùħ'] +['Ġ×Ķ', '×ŀש'] +['ب', 'ÙĪ'] +['à¸Ĭ', 'à¸Ļ'] +['ãĤĵ', 'ãģ§ãģĻ'] +['ว', 'à¸Ļ'] +['à¸ģร', 'รม'] +['×ŀ', '×ķ×ĵ'] +['Ùĥ', 'اÙĨ'] +['×ķ×', '£'] +['ол', 'ог'] +['ت', 'ÙĨ'] +['à¸ķ', 'à¹Į'] +['ê²', 'ĥ'] +['ר', '×ĺ'] +['ừ', 'ng'] +['×ķ×ij', '×Ķ'] +['Ùħ', 'ØŃ'] +['ĠÐ', '§'] +['פ', '×Ĵ'] +['ส', 'à¸ĸ'] +['ãģĭ', 'ãĤĬ'] +['ını', 'z'] +['à¹Ģ', 'ย'] +['ãĥ¼', 'ãĥ³'] +['ãģĬ', 'ãĤĬ'] +['פ', 'ש'] +['ิ', 'à¸ķ'] +['Ø·', 'ÙĨ'] +['×Ļת', '×Ļ'] +['×IJ', '׳'] +['ç', 'ek'] +['ì', 'ª'] +['×ŀ', '×ij'] +['ศ', 'า'] +['ãĤ¹', 'ãĤ¿'] +['à¸ļ', 'ุ'] +['×ĵ', '×ijר'] +['ãģĦ', 'ãģı'] +['ส', 'ะ'] +['à¹Ģ', 'หล'] +['ิ', 'à¸ĩ'] +['à¸ŀ', 'ัà¸Ļ'] +['ãģĦ', 'ãģŁãģł'] +['ãĤĤ', 'ãĤī'] +['à¹ī', 'ม'] +['ãģĵãģ¨ãģĮ', 'ãģ§ãģį'] +['าร', 'à¹Į'] +['ุ', 'à¸ĩ'] +['í', 'ij'] +['ì', '¯'] +['ë', '¼'] +['í', 'Ĥ'] +['ì', '·'] +['ê', '¡'] +['á', 'ı'] +['á', 'Ĵ'] +['ðĿ', 'ľ'] +['á', '©'] +['ðŁ', 'Ħ'] +['ðIJ', '¤'] +['Ġש', '׾'] +['Ġ×ŀ', '×Ķ'] +['à¹ģล', 'ะ'] +['Ġ׼', '׾'] +['áº', '½'] +['á»Ļ', 'ng'] +['ذ', 'ÙĬ'] +['л', 'е'] +['×', '¥'] +['ãģª', 'ãģ©'] +['ĠÙĪ', 'Ø£'] +['หà¸Ļ', 'à¹īา'] +['ãģ¾', 'ãģ§'] +['à¸ķà¹Ī', 'à¸Ń'] +['à¸Ĺ', 'ัà¹īà¸ĩ'] +['ãģł', 'ãģij'] +['à¹ģà¸ļ', 'à¸ļ'] +['à¹Ģร', 'า'] +['פ', '׾'] +['ãģŁ', 'ãģĦ'] +['à¹Ģล', 'ย'] +['ãģ£ãģ¦', 'ãģĦãĤĭ'] +['ế', 'p'] +['ึ', 'à¹Īà¸ĩ'] +['ê', '´Ģ'] +['ê³', 'Ħ'] +['׼', '×ķ'] +['à¹Ģร', 'ืà¹Īà¸Ńà¸ĩ'] +['×§', '×Ļ'] +['êµ', 'Ń'] +['פ', 'ס'] +['ت', 'ÙĬ'] +['ãĥ', 'Ħ'] +['Ġ×Ķ', '×Ĺ'] +['г', 'и'] +['ר×IJ', '׾'] +['×ŀ', '׾'] +['ĠØ£', 'ÙĬ'] +['Ġع', 'ÙĦÙĬ'] +['ãģĭ', 'ãģ£ãģŁ'] +['ש', '×Ļ'] +['д', 'Ñĥ'] +['×ŀ', 'ף'] +['׳', '×ĺ'] +['׳', '×Ļת'] +['mi', 'ÅŁ'] +['׼', '×Ŀ'] +['Ġ×ij', 'ר'] +['Ġ׾', '×ij'] +['ĠÐ', 'Ľ'] +['ç', 'e'] +['×ķ׳', '×Ļ'] +['ãĤĪãģĨ', 'ãģ«'] +['פ', '×ķר'] +['ãĥ', 'į'] +['Ùĥ', 'ÙĬ'] +['×Ĺ', 'ת'] +['Ùģ', 'ÙĦ'] +['Ġ×Ķ', '×§'] +['Ġ×Ķ', '×ij'] +['Ġ×ŀ', 'ס'] +['à¹Īา', 'à¸Ļ'] +['п', 'еÑĢ'] +['à¹Īา', 'ว'] +['Ġ×ij', '×IJ'] +['ĠÙĪ', 'Ùĩ'] +['à¸Ļ', 'ำ'] +['Ġ×ij', 'ש'] +['׳', '×§'] +['ãģ©', 'ãģĨ'] +['ש', '×ķת'] +['×ĵ', '×Ķ'] +['à¹Ģ', 'à¸ļ'] +['ÙĨ', 'س'] +['Ġìļ°', '리'] +['ส', 'à¹Īวà¸Ļ'] +['ล', 'ัà¸ĩ'] +['ج', 'ز'] +['Ġ×Ĺ', '×Ļ'] +['Ùĥ', 'ثر'] +['ล', 'ะ'] +['Ùĩ', 'د'] +['ĠÙĪ', 'ب'] +['اÙĦ', 'Ùħ'] +['à¹ģ', 'ม'] +['Æ¡', 'i'] +['Ġ×ij', '×Ĺ'] +['ữ', 'a'] +['à¹Ģà¸Ĺ', 'ศ'] +['à¸ķ', 'ัà¹īà¸ĩ'] +['ог', 'да'] +['׾', '×§'] +['د', 'د'] +['สร', 'à¹īาà¸ĩ'] +['à¸Ĭ', 'ี'] +['Ùģ', 'ض'] +['à¹ģ', 'ห'] +['uy', 'á»ĩn'] +['ร', 'ัà¸ģ'] +['á»ĩ', 'm'] +['ส', 'า'] +['פ', '×§'] +['ีย', 'à¸ĩ'] +['à¸ķ', 'à¹Īาà¸ĩ'] +['à¸Ħร', 'ัà¹īà¸ĩ'] +['ØŃ', 'ÙĤ'] +['à¹Ģ', 'à¸Ńà¸ĩ'] +['ائ', 'ÙĬ'] +['×ĺ', '×¢'] +['اÙĦ', 'Ø©'] +['ิ', 'à¹Īม'] +['ãĤ', '½'] +['د', 'Ùī'] +['Ġר', '×IJ'] +['ãģ£', 'ãģ¨'] +['ãĥĥ', 'ãĥĹ'] +['ÙĬر', 'Ø©'] +['ê±', '´'] +['×ŀ', '×IJ'] +['×ķ', '×ķ'] +['ب', 'ع'] +['ãģ', '²'] +['ร', 'าย'] +['×ĵ', '×Ŀ'] +['ت', 'Ùģ'] +['à¸ķ', 'à¸ģ'] +['ạ', 'ng'] +['ãĤĴ', 'è¦ĭ'] +['à¸Ĭ', 'ั'] +['ưá»', 'Ł'] +['Æ°á»Ł', 'ng'] +['ج', 'ب'] +['×ķ×ŀ', 'ר'] +['ĠìĤ¬ëŀ', 'Į'] +['ó', 'ng'] +['ร', 'ั'] +['Ġ×Ķ', '×ĸ'] +['ר', 'צ'] +['Ġ×Ĺ', '×ĵ'] +['ذ', 'ÙĦÙĥ'] +['×ķר', '×Ļ'] +['ãģ¡', 'ãĤĥ'] +['Ùģ', 'ع'] +['Ġ׾', 'צ'] +['á', 'i'] +['à¹ĩ', 'à¸ļ'] +['ãģ', 'İ'] +['à¸ģ', 'ิ'] +['ạ', 'c'] +['ë©', '°'] +['ãģª', 'ãĤĭ'] +['×ķ׾', '×Ŀ'] +['à¹ģ', 'à¸Ĺ'] +['×ķ×', '¥'] +['м', 'еÑĤ'] +['ü', 'ÅŁ'] +['ÑĢ', 'Ñı'] +['à¸', 'Ĵ'] +['ÑģÑĤ', 'оÑı'] +['ع', 'ÙĪØ¯'] +['Ùħ', 'ار'] +['Ø·', 'Ø©'] +['à¸ŀ', 'ื'] +['к', 'ÑĢ'] +['à¹ģ', 'à¸ģ'] +['à¹Ĥ', 'รà¸ĩ'] +['×ij', '×Ļ×ĺ'] +['ê²', 'ł'] +['×ķ׾', '×Ķ'] +['ØŃ', 'ر'] +['ืà¹Ī', 'à¸Ńà¸Ļ'] +['×ķ×ij', 'ר'] +['×Ĺ', 'ש'] +['ãĥķãĤ', '¡'] +['×ŀ', '×ĺ'] +['ú', 't'] +['Ġd', 'ön'] +['ắ', 'ng'] +['ëł', 'ĩ'] +['ẳ', 'ng'] +['ว', 'à¸ģ'] +['ص', 'د'] +['Ø®', 'Ø·'] +['à¸Ń', 'ั'] +['ãĤı', 'ãĤĮ'] +['سÙĦ', 'اÙħ'] +['à¹Ģร', 'à¹ĩ'] +['×Ļש', '×Ļ'] +['ج', 'اÙĦ'] +['ãģij', 'ãĤĭ'] +['à¸Ĭา', 'à¸ķิ'] +['ÙĪØ§', 'ÙĤ'] +['à¹Ĥ', 'à¸Ļ'] +['ãģ¦', 'ãģĹãģ¾'] +['اع', 'Ø©'] +['ãĤŃ', 'ãĥ£'] +['à¸į', 'า'] +['ÙĦا', 'ÙĤ'] +['ิ', 'à¸ģ'] +['ĠÑģ', 'ов'] +['ÑĢаÐ', 'º'] +['×Ļ׳', '×Ļ'] +['ü', 'ÄŁ'] +['Ã¼ÄŁ', 'ü'] +['×§', '×ij'] +['à¹Ī', 'à¸Ńà¸ĩ'] +['Ġger', 'çek'] +['à¸Ĺ', 'ั'] +['ов', 'аниÑı'] +['×ŀ', '׼'] +['س', 'Ø©'] +['×Ļ×', '£'] +['le', 'ÅŁ'] +['Ùħ', 'ؤ'] +['ĠìĿ', 'ĺ'] +['à¸IJ', 'าà¸Ļ'] +['ĠÑģ', 'об'] +['Ġêµ', 'Ń'] +['×¢', 'צ'] +['з', 'в'] +['ส', 'à¸ĩ'] +['ز', 'ÙĦ'] +['ãģı', 'ãĤĮ'] +['и', 'ÑĢÑĥ'] +['ت', 'Ø£'] +['п', 'олн'] +['ìĺ', 'Ģ'] +['ÙĨ', 'Ø´'] +['׼', '×IJ'] +['Ùħ', 'Ø´'] +['à¸Ķ', 'à¹Į'] +['ÙĪ', 'ÙĬÙĦ'] +['à¹ģ', 'à¸Ĥ'] +['ãģ£ãģ¦', 'ãģĹãģ¾'] +['но', 'ÑģÑĤ'] +['в', 'л'] +['Ùħ', 'ÙĤ'] +['را', 'ج'] +['å¤', 'ī'] +['ë', 'Ľ'] +['â', '¸'] +['ì', 'IJ'] +['à', '»'] +['á', 'ļ'] +['â', '»'] +['ê', 'Ļ'] +['â', '§'] +['ð', 'Ĵ'] +['ðĿ', 'ĩ'] +['Ġ×IJ', 'ת'] +['ĠÙĦ', 'ÙĦ'] +['ĠØ£', 'ÙĨ'] +['Ġ×ķ', '×Ķ'] +['ãģ«', 'ãģ¯'] +['Ġ×Ļ', 'ש'] +['ت', 'Ùĩ'] +['ÃŃ', 'nh'] +['ÙĬ', 'ات'] +['Ġ×ij', '×ŀ'] +['à¸Ļั', 'à¹īà¸Ļ'] +['à¸Ļ', 'à¹īำ'] +['Ãł', 'o'] +['à¸ķ', 'าม'] +['ãģ®', 'ãģ¯'] +['d', 'ır'] +['Ġn', 'ghi'] +['ặ', 't'] +['×ŀ', '×Ļ×Ŀ'] +['ãģ¦', 'ãģĦãĤĭ'] +['Ġ×ij', 'ת'] +['หร', 'ืà¸Ń'] +['Ġس', 'ÙĬ'] +['ãģª', 'ãĤī'] +['à¹Ĥà¸Ķ', 'ย'] +['ı', 'yor'] +['à¸Ńี', 'à¸ģ'] +['á»ĩ', 'nh'] +['Ñĭ', 'м'] +['à¸Ĺุ', 'à¸ģ'] +['Ġ׾', '×Ĺ'] +['Ġ×Ķ', 'ר'] +['Ġ×Ķ', '×Ļ'] +['à¸ŀ', 'ระ'] +['à¹Ģว', 'ลา'] +['ĠØ', 'º'] +['ẫ', 'n'] +['m', 'Ä±ÅŁ'] +['׼', '×Ķ'] +['á»ij', 'n'] +['ãģ§', 'ãģĹãĤĩãģĨ'] +['ãĥ', '¢'] +['à¸Ľ', 'ี'] +['ס', '×Ļ'] +['ãģĵ', 'ãĤį'] +['Ġ׾', 'פ'] +['ร', 'à¸ĸ'] +['ê¸', 'Ī'] +['à¸ģ', 'วà¹Īา'] +['ë', '¬´'] +['á»į', 'ng'] +['ãĤĵ', 'ãģ§'] +['ãĤĪãģĨ', 'ãģª'] +['á»ĵ', 'i'] +['ãĤ', '¬'] +['ส', 'à¹Īà¸ĩ'] +['×Ļ׳', '×Ķ'] +['à¸ĸ', 'ูà¸ģ'] +['à¸Ī', 'ัà¸Ķ'] +['Ġ×Ķ', '×Ĵ'] +['ãĥ', 'ľ'] +['×ŀ', '×ķת'] +['ÙĪ', 'Ùĥ'] +['ëĭ', '¨'] +['ĠØ', '«'] +['ãģ®', 'ãģĮ'] +['à¹Ģห', 'à¹ĩà¸Ļ'] +['ع', 'ا'] +['à¸Ļ', 'ิ'] +['Å', 'ŀ'] +['à¸Ń', 'ะ'] +['ãģĪ', 'ãĤĭ'] +['Ø«', 'ÙĦ'] +['ØŃÙħ', 'د'] +['à¹Ģà¸ģ', 'ิà¸Ķ'] +['פ', 'שר'] +['פ', '×Ķ'] +['ม', 'ิ'] +['ئ', 'ÙĬس'] +['à¸Ĺำ', 'à¹ĥหà¹ī'] +['×¢', '×ĵ'] +['ìĭ', '¤'] +['à¸Ĭà¹Īว', 'ย'] +['ĠاÙĦÙħ', 'ÙĨ'] +['ز', 'ÙĬ'] +['ع', 'ÙĬ'] +['Ġ׼', '×IJ'] +['ạ', 'nh'] +['á»', '¹'] +['ãĤĵ', 'ãģª'] +['ส', 'ู'] +['צ', 'ר'] +['Æ°á»Ľ', 'ng'] +['×ķ', '×ķ×Ķ'] +['à¹Ĥ', 'ล'] +['ĠاÙĦ', 'Ùĩ'] +['ว', 'า'] +['หล', 'าย'] +['Ñī', 'е'] +['à¸Ĥ', 'à¹īà¸Ń'] +['à¹īà¸Ń', 'ย'] +['ب', 'Ø·'] +['ка', 'Ñı'] +['ĠØ', '¢'] +['Ġи', 'Ñģ'] +['ĠاÙĦ', 'غ'] +['à¸ģ', 'า'] +['à¸Ļ', 'à¹Īา'] +['ÙĬ', 'ÙĪ'] +['×ij', '×ķר'] +['á»ħ', 'n'] +['ว', 'à¸ĩ'] +['×Ļ×', 'ĸ'] +['ì²', 'Ń'] +['н', 'им'] +['ëŁ', '°'] +['×Ĵ', '×ķר'] +['ص', 'ØŃ'] +['ÙĦ', 'ÙĪ'] +['×Ĺ', '×ķת'] +['ส', 'ุ'] +['رÙĬ', 'ÙĤ'] +['ס', '×ĺ'] +['Ġ×ŀ', '×¢'] +['ãĥĨ', 'ãĤ£'] +['à¸Ħ', 'ิà¸Ķ'] +['ãĤį', 'ãģĨ'] +['à¹Ħ', 'ล'] +['à¸Ļ', 'à¹Į'] +['á»ı', 'i'] +['ÑģÑĤÑĢ', 'о'] +['ส', 'à¸Ķ'] +['ส', 'าร'] +['ÙĪÙĦ', 'Ø©'] +['ầ', 'm'] +['ร', 'à¹Īว'] +['รà¹Īว', 'ม'] +['ร', 'ุ'] +['ĠاÙĦس', 'ÙĬ'] +['ìĺ', 'ģ'] +['Ġ×ŀ', '×ij'] +['פ', '×ĺ'] +['à¸ķิ', 'à¸Ķ'] +['×ĺ', '×Ļ×Ŀ'] +['Ġë', '¬´'] +['ÙĤد', 'Ùħ'] +['Ġdü', 'ÅŁ'] +['ائ', 'ÙĦ'] +['м', 'Ñĭ'] +['ØŃ', 'س'] +['ÙĪ', 'ص'] +['×Ļ×§', '×Ķ'] +['ãģ§ãģ¯', 'ãģªãģĦ'] +['à¹Ģ', 'หม'] +['оÑĢ', 'ÑĤ'] +['í', 'Ĩµ'] +['ãģ', 'IJ'] +['к', 'ÑĢа'] +['ีย', 'ว'] +['ع', 'ار'] +['ئ', 'Ø©'] +['íĥ', 'Ģ'] +['ãģ«ãģª', 'ãĤĬ'] +['ج', 'Ø©'] +['ÙĪÙĤ', 'ع'] +['ÑĮ', 'Ñı'] +['×ķצ', '×Ķ'] +['ש', '×Ŀ'] +['ب', 'ÙĤ'] +['Ġ×Ļ', '×Ķ'] +['ÙĬ', 'Ø·'] +['ım', 'ız'] +['д', 'еÑĢж'] +['×Ļש', 'ר×IJ׾'] +['غ', 'ÙĬر'] +['ร', 'à¸Ńà¸ĩ'] +['à¹Ģรีย', 'à¸Ļ'] +['Ġ×Ķ', '×ĺ'] +['หม', 'าย'] +['Ùħ', 'Ùĩ'] +['اÙģ', 'Ø©'] +['Ġо', 'ÑĢг'] +['ÙĪ', 'Ùī'] +['ãĥ©', 'ãĤ¤'] +['×ŀ', '׳×Ķ'] +['ĠÄij', 'o'] +['Ġг', 'оÑĢ'] +['اÙħ', 'Ø©'] +['æ¥', '½'] +['Ø«', 'ÙĬر'] +['à¸ģิ', 'à¸Ī'] +['á»ĵ', 'n'] +['ÙĨ', 'ب'] +['ÑĢÑĥ', 'д'] +['ìĹ', 'Ī'] +['Ġ×Ĺ', '×ijר'] +['ÑĢаÐ', '¶'] +['ạ', 'ch'] +['ت', 'ÙĪ'] +['à¹Ĥ', 'ม'] +['×ij', '×Ļ×ij'] +['Ġí', 'Ĩµ'] +['aca', 'ģı'] +['جÙĦ', 'س'] +['à¹Ģà¸Ľ', 'ล'] +['ว', 'à¸Ķ'] +['à¸Ń', 'ล'] +['ãģŁ', 'ãĤĬ'] +['à¸Ľ', 'ัà¸į'] +['Ġìķ', 'Į'] +['عر', 'Ùģ'] +['à¹Ħ', 'à¸Ł'] +['Ø£', 'Ø®'] +['å¤ļ', 'ãģĦ'] +['à¸Ķ', 'ัà¸ĩ'] +['Ø´', 'Ùģ'] +['ãģ£ãģ¦', 'ãģĦãģ¾ãģĻ'] +['׼', '×ł×¡'] +['ÑĨ', 'е'] +['еÑģ', 'п'] +['Ùħ', 'اÙħ'] +['à¸ŀื', 'à¹īà¸Ļ'] +['иÑĩеÑģ', 'ки'] +['Ø®', 'د'] +['Ùĥ', 'ÙĪÙħ'] +['Ġ×Ķ', 'ר×IJש'] +['ت', 'اب'] +['é£Ł', 'ãģ¹'] +['ื', 'à¸Ļ'] +['оÑĢ', 'о'] +['Ġb', 'öl'] +['×ķ×Ĺ', '×ĵ'] +['دÙĬ', 'ر'] +['ắ', 'm'] +['د', 'ع'] +['ãģķ', 'ãģĽ'] +['à¸ĺ', 'ร'] +['à¸ĺร', 'รม'] +['ãģĭ', 'ãĤĤ'] +['å¤ļ', 'ãģı'] +['r', 'ä'] +['س', 'ع'] +['×Ļ׾', '×Ķ'] +['ض', 'ر'] +['ĠاÙĦ', 'شر'] +['×ĸ', '×ķר'] +['×¢', '×ijר'] +['ạ', 'm'] +['алÑĮ', 'но'] +['ر', 'ÙĨ'] +['اÙħ', 'ج'] +['׼', '×ļ'] +['d', 'ıģ'] +['д', 'ен'] +['ض', 'ا'] +['ÙĦÙĬ', 'Ùħ'] +['Ġê·¸', '룬'] +['تÙħ', 'اع'] +['ار', 'ÙĬØ®'] +['à¹Ĥ', 'à¸ķ'] +['ĠÑģ', 'ÑĢед'] +['Ġ׳', '×ķס'] +['ÙĤ', 'بÙĦ'] +['оÑĤ', 'ов'] +['le', 'ÅŁtir'] +['Ġм', 'еÑģÑĤ'] +['سÙĦ', 'Ùħ'] +['Ġ×¢', 'צ'] +['ĠاÙĦس', 'ÙĦ'] +['еÑĤ', 'ÑĮ'] +['اب', 'Ø©'] +['н', 'ак'] +['สà¸ĸ', 'าà¸Ļ'] +['Ġ×ij', '׳'] +['à¸ļ', 'ัà¸Ļ'] +['׼', '׳'] +['Ġö', 'ÄŁ'] +['ãģ¨', 'è¨Ģ'] +['uy', 'ến'] +['di', 'ÄŁ'] +['áºŃ', 'u'] +['ÑĢ', 'аÑģ'] +['ãĤ·', 'ãĥ§ãĥ³'] +['n', 'ız'] +['×ķ×ĵ', '×Ķ'] +['ت', 'س'] +['Ùħ', 'اÙĦ'] +['à¹Ģห', 'à¸ķุ'] +['ย', 'ว'] +['à¸ŀ', 'ัà¸ģ'] +['ãģĦ', 'ãģªãģĦ'] +['Ġк', 'аÑĩ'] +['ล', 'à¹Į'] +['ר׼', 'ת'] +['ÅŁt', 'ur'] +['×ŀ', '×ķס'] +['ãģ', '¥'] +['б', 'ол'] +['عÙħ', 'اÙĦ'] +['×ķר', 'ת'] +['ÑĨи', 'он'] +['ศ', 'ึà¸ģ'] +['à¸', 'ı'] +['ÑĢ', 'ен'] +['اس', 'ÙĬ'] +['ائ', 'ر'] +['à¹Ĥ', 'à¸Ľà¸£'] +['Ġse', 'ç'] +['غ', 'ÙĬ'] +['Ñį', 'ÑĤ'] +['ен', 'н'] +['ãģª', 'ãģ®'] +['×Ļש', '×Ķ'] +['×Ļפ', '×ķר'] +['ãģŁãĤģ', 'ãģ«'] +['ز', 'Ø©'] +['Ġç', 'oc'] +['ãĤ¯', 'ãĥª'] +['ÑĪ', 'ен'] +['ãĤı', 'ãģij'] +['رÙĬ', 'د'] +['ĠÑĢ', 'аÑģÑģ'] +['Ùĥ', 'ات'] +['ส', 'à¸Ńà¸ļ'] +['ce', 'ÄŁi'] +['ãĤ¿', 'ãĤ¤'] +['à¸ļ', 'ร'] +['ĠاÙĦ', 'بر'] +['׳', '×ķ×¢'] +['r', 'ün'] +['را', 'ض'] +['ศา', 'ส'] +['à¸ķ', 'รà¹Į'] +['ãģį', 'ãģŁ'] +['×ķ׾', '×ĵ'] +['еÑĢ', 'и'] +['íĹ', 'ĺ'] +['ắ', 'p'] +['ت', 'عÙĦ'] +['Ùĥ', 'د'] +['иÑĤелÑĮ', 'но'] +['Ø·', 'Ùģ'] +['Ġав', 'ÑĤом'] +['Ġ×ŀ', 'צ'] +['ÑĪи', 'Ñħ'] +['ات', 'Ùģ'] +['ĠÑħ', 'оÑĤ'] +['Ùİ', 'ا'] +['ãģı', 'ãĤĭ'] +['×Ķ', 'פ'] +['à¹Ĥ', 'à¸Ĺ'] +['à¹ģ', 'à¸ŀ'] +['à¹Ī', 'à¸Ńย'] +['ĠاÙĦÙħ', 'Ø´'] +['à¸ģาร', 'à¸ĵà¹Į'] +['ани', 'з'] +['×Ķ', '׾'] +['ظ', 'Ùħ'] +['ย', 'ุ'] +['li', 'ÄŁ'] +['à¹Ħ', 'à¸Ĥ'] +['à¸ĸ', 'ืà¸Ń'] +['ö', 'z'] +['ãģij', 'ãģ¦'] +['à¹Ģ', 'à¸ľ'] +['ุ', 'ม'] +['ãĥĹ', 'ãĥ¬'] +['Ġ×Ķ×IJ', '×Ĺר'] +['خت', 'ÙĦÙģ'] +['à¸', 'İ'] +['ÙĦا', 'ØŃ'] +['Ġdü', 'zen'] +['צ', '×Ķ'] +['س', 'اء'] +['×ķר', '×ļ'] +['×ķ×ĵ', '×Ļ'] +['ÑĢа', 'ÑĦ'] +['ÅŁt', 'ır'] +['ãģ«', 'åħ¥'] +['ãģĪ', 'ãģ°'] +['ص', 'ÙĪÙĦ'] +['ĠÐľ', 'оÑģ'] +['ا', 'Ùĩر'] +['ãģ£', 'ãģ'] +['ĠлÑİ', 'б'] +['×Ļ×¢', '×Ķ'] +['Ġ×Ķ×ŀ', '×§'] +['สิ', 'à¸Ĺ'] +['สิà¸Ĺ', 'à¸ĺิ'] +['×Ļ׳', '×Ŀ'] +['ÙĦا', 'Ùģ'] +['à¸ŀัà¸Ļ', 'à¸ĺ'] +['×ķ×IJ', '×Ķ'] +['ม', 'ั'] +['à¸Ĥ', 'à¸ĵะ'] +['д', 'оÑĢ'] +['ãģ¨', 'ãģª'] +['à¸ģระ', 'à¸Ĺ'] +['ac', 'ı'] +['×ķ׾', '×ķ×Ĵ'] +['Ñĥ', 'ÑĪ'] +['ãĥ¥', 'ãĥ¼'] +['ãĥ', '¦'] +['Ùħ', 'ست'] +['Ġa', 'ÅŁ'] +['ש', '×§'] +['פ', 'ת×Ĺ'] +['าย', 'à¸Ļ'] +['í', 'ĩ'] +['ë', '¢'] +['ï', '·'] +['í', 'ī'] +['ì', 'µ'] +['ì', '¬'] +['ðĿ', 'Ľ'] +['ì', 'Ĵ'] +['ë', 'Ļ'] +['ê', '§'] +['á', 'ĸ'] +['â', '¨'] +['â', '±'] +['á', 'ĺ'] +['ð', 'ĸ'] +['à', 'ł'] +['á', 'Ķ'] +['ðIJ', 'Ń'] +['ữ', 'ng'] +['Å©', 'ng'] +['Ġ×Ķ', 'ת'] +['ĠاÙĦ', 'ا'] +['Ġ×ŀ', 'ת'] +['à¸ĸ', 'ึà¸ĩ'] +['ò', 'n'] +['á»ĭ', 'nh'] +['нÑĭ', 'м'] +['Ġc', 'ả'] +['à¸Ķ', 'ู'] +['Ġ', 'à¹ģà¸ķà¹Ī'] +['Ġ×ij', '×Ķ'] +['ó', 'i'] +['ãģ¨', 'ãģĹãģ¦'] +['ú', 'ng'] +['ĠØ', '°'] +['Ġ×Ķ', '׳'] +['Ġب', 'ÙĨ'] +['ÙĦ', 'اÙĦ'] +['à¹Ħ', 'à¸Ĺย'] +['á»ĩ', 'p'] +['t', 'ı'] +['ม', 'ัà¸Ļ'] +['ằ', 'ng'] +['á»ij', 't'] +['к', 'ом'] +['à¸ĭ', 'ึà¹Īà¸ĩ'] +['à¸Ħร', 'ัà¸ļ'] +['à¸ļ', 'à¹īาà¸Ļ'] +['ĠاÙĦ', 'ÙĬ'] +['l', 'ü'] +['ÙĪ', 'س'] +['ãģł', 'ãģ£ãģŁ'] +['à¹Ģ', 'à¸ĩ'] +['Ġê³', 'µ'] +['н', 'Ñĥ'] +['ãĤĪ', 'ãĤĬ'] +['м', 'Ñĥ'] +['à¹Ģà¸Ĥ', 'า'] +['ãĤ', 'Ģ'] +['ни', 'е'] +['ãģ«ãģª', 'ãĤĭ'] +['áºŃ', 'y'] +['ĠÙĪ', 'ا'] +['ëł', '¤'] +['ש', '×ķ'] +['á', 'p'] +['×ĵ', '×ķ'] +['ãģ§', 'ãģĹãģŁ'] +['ع', 'ض'] +['Ñģк', 'ой'] +['æĦŁ', 'ãģĺ'] +['ÑİÑĤ', 'ÑģÑı'] +['Ġ×Ļ', '׼×ķ׾'] +['ãĤĵ', 'ãģł'] +['в', 'и'] +['à¹Ģล', 'à¹Īà¸Ļ'] +['ìĿ´', 'ëĭ¤'] +['ĠÙĦ', 'Ùĩ'] +['à¸Ħ', 'ืà¸Ń'] +['ت', 'Ùĥ'] +['Ùħ', 'ÙĥÙĨ'] +['a', 'ģı'] +['׳', '×ĵ'] +['ë¯', '¼'] +['à¹Ħ', 'ว'] +['สำ', 'ห'] +['สำห', 'รัà¸ļ'] +['Ñģл', 'ед'] +['t', 'ır'] +['ĠÙĦ', 'ÙĬ'] +['ĠاÙĦع', 'ÙħÙĦ'] +['×ij', '×ķת'] +['×ij', '×Ļ×Ŀ'] +['à¸Ħ', 'ำ'] +['à¹Ģà¸Ħร', 'ืà¹Īà¸Ńà¸ĩ'] +['lı', 'ģı'] +['ืà¸Ń', 'à¸ĩ'] +['ج', 'د'] +['íŀ', 'Ī'] +['ìĭ', '¬'] +['×¢', '×ķת'] +['ส', 'ิà¸Ļ'] +['Ñĩ', 'и'] +['ر', 'ض'] +['à¹Ģà¸Ľ', 'ิà¸Ķ'] +['à¸Ħ', 'à¹Īา'] +['ìĦ', 'ł'] +['ÙĪØ±', 'Ø©'] +['×§', '×ĺ'] +['ìľ', 'ł'] +['ع', 'ÙħÙĦ'] +['×IJ', '×Ļ×Ŀ'] +['׾', '×Ļ×Ŀ'] +['à¹ĥห', 'à¸į'] +['à¹ĥหà¸į', 'à¹Ī'] +['ừ', 'a'] +['á»į', 'i'] +['ãģ', '¶'] +['ÃŃ', 'ch'] +['ãĥĩ', 'ãĤ£'] +['×ķר', '×Ļ×Ŀ'] +['Ñģ', 'о'] +['ìķ', '½'] +['ов', 'а'] +['Ñĩ', 'аÑģÑĤ'] +['à¹Ģà¸Ī', 'à¹īา'] +['п', 'ÑĢо'] +['Ġ×ŀ', '×Ĺ'] +['ãĥ', 'İ'] +['×ķ×Ļ', '×ķת'] +['Ġд', 'е'] +['ë§', 'Ī'] +['ì§', 'ģ'] +['×Ļפ', '×Ķ'] +['ĠاÙĦع', 'اÙĦÙħ'] +['ë¥', '´'] +['ר×IJ', '×Ķ'] +['uy', 'á»ĥn'] +['×¢', '×Ļ'] +['ม', 'ืà¸Ń'] +['Ø¥', 'ÙĨ'] +['ร', 'ู'] +['ĠØ', '²'] +['×Ļ', '×ķ×Ŀ'] +['à¸ķ', 'à¹īà¸Ļ'] +['ãģ¦', 'ãģĦãģ¾ãģĻ'] +['Ùħ', 'اÙĨ'] +['ĠÐ', '¥'] +['à¸Ľà¸£à¸°', 'à¹Ģà¸Ĺศ'] +['á»', '³'] +['׾', '×ij'] +['à¹Ģà¸Ķ', 'à¹ĩ'] +['ãģŁ', 'ãģ¡'] +['à¸Ĺี', 'ม'] +['à¸Ļ', 'ะ'] +['ìĹ', '°'] +['Ġìł', 'Ģ'] +['ÙĦ', 'Ùĩ'] +['ợ', 'i'] +['ĠاÙĦ', 'ز'] +['د', 'ار'] +['ãĤ³', 'ãĥ³'] +['м', 'ин'] +['à¹ģห', 'à¹Īà¸ĩ'] +['à¸Ķ', 'ัà¸ļ'] +['׼', 'ר'] +['ж', 'а'] +['íĸ', 'Ī'] +['×ŀ', '×ĸ'] +['ợ', 'i'] +['à¸Ķ', 'า'] +['Ġع', 'بد'] +['à¹ģ', 'ร'] +['×IJת', 'ר'] +['×¢', '׳×Ļ'] +['à¹Ģ', 'à¸Ħ'] +['×ķצ', 'ר'] +['ì§Ģ', 'ë§Į'] +['ائ', 'Ùħ'] +['Ø£', 'س'] +['uy', 'á»ģn'] +['Ġ×IJ', '׳'] +['×Ĺ', '׳×ķ'] +['×ĸ', '×Ļ'] +['ร', 'à¹īาà¸Ļ'] +['ĠÐł', 'оÑģ'] +['ĠÐłÐ¾Ñģ', 'Ñģ'] +['رب', 'ÙĬØ©'] +['t', 'ür'] +['ãĤĭ', 'ãģĵãģ¨'] +['ظ', 'ر'] +['б', 'Ñĭ'] +['à¸Ĺีà¹Ī', 'สุà¸Ķ'] +['Ġצ', 'ר'] +['èĩª', 'åĪĨ'] +['л', 'аÑģ'] +['ĠÑı', 'в'] +['ĠÑıв', 'лÑı'] +['à¸ŀร', 'à¹īà¸Ńม'] +['à¸Ńา', 'à¸Ī'] +['à¸ļริ', 'à¸ģาร'] +['Ġç', 'ı'] +['ëį', 'ĺ'] +['ĠاÙĦÙħ', 'ست'] +['ت', 'Ø´'] +['ש', '×ķ×ij'] +['ãĤ', '´'] +['Ġyap', 'ıl'] +['ĠاÙĦ', 'ذ'] +['ุ', 'à¹Īม'] +['à¸ĸ', 'à¹īา'] +['ìĦ', '¤'] +['ì°', '¨'] +['в', 'аÑĢ'] +['à¹Ģà¸ŀ', 'ิà¹Īม'] +['Æ°á»Ľ', 'i'] +['Ùĥ', 'س'] +['à¸Ńย', 'าà¸ģ'] +['ãģ¦', 'ãĤĤ'] +['Ġг', 'од'] +['ÙĬ', 'ار'] +['à¸ķ', 'à¸Ńà¸Ļ'] +['Ġиг', 'ÑĢ'] +['à¹Ħà¸Ķà¹ī', 'รัà¸ļ'] +['ĠاÙĦÙħ', 'ر'] +['ÙĤ', 'ت'] +['Ġë', 'ĺ'] +['Ġëĺ', 'IJ'] +['ẩ', 'n'] +['ãģĻãĤĭ', 'ãģĵãģ¨'] +['×Ĵ', '×Ŀ'] +['Ġ×ij', '×ij'] +['ت', 'د'] +['ÙĪ', 'ار'] +['ãĤ', '®'] +['п', 'ол'] +['Ġм', 'ог'] +['تر', 'Ùĥ'] +['ÙĪ', 'Ø«'] +['Ġç', 'ık'] +['ا', 'Ø©'] +['à¹Ģà¸Ķ', 'ียว'] +['มี', 'à¸Ħวาม'] +['Ġ×ŀ', '×Ĵ'] +['ص', 'Ùģ'] +['ĠТ', 'ак'] +['Ġ׼', 'ת'] +['×Ļ×ĵ', '×Ļ'] +['ов', 'оÑĢ'] +['ầ', 'y'] +['สิ', 'à¹Īà¸ĩ'] +['ب', 'ت'] +['ür', 'ü'] +['ÙĨ', 'ج'] +['หล', 'ัà¸ģ'] +['×Ļ×Ķ', '×Ŀ'] +['ÙĤ', 'ص'] +['з', 'Ñĭ'] +['×Ľ×ª', '×ij'] +['ư', 'u'] +['m', 'ız'] +['ĠìĦ', '¸'] +['л', 'ог'] +['Ùħ', 'ÙĬÙĦ'] +['ÙĬ', 'ج'] +['íĴ', 'Ī'] +['à¸ŀ', 'à¸ļ'] +['ห', 'ัว'] +['з', 'на'] +['ר', '×§'] +['à¹Ĥ', 'ร'] +['Ġ×ij', 'ס'] +['ĠBaÅŁ', 'kan'] +['ĠëĶ', '°'] +['à¸Ń', 'ัà¸Ļ'] +['ีà¹Īย', 'ว'] +['н', 'еÑģ'] +['à¹Ģà¸Ķ', 'ิà¸Ļ'] +['ÙĬ', 'اÙĨ'] +['×ķ׾', '×Ļ'] +['ا', 'خت'] +['צ', '×ķת'] +['ãģĵ', 'ãģĵ'] +['ĠاÙĦ', 'اÙĨ'] +['ĠпÑĢо', 'ÑĨ'] +['ãģ¾', 'ãģł'] +['׼', 'ס'] +['ĠاÙĦ', 'Ø¢'] +['ÙĬ', 'ز'] +['ĠاÙĦد', 'ÙĪÙĦ'] +['Ġíķĺ', 'ëĤĺ'] +['ض', 'ع'] +['ê»', 'ĺ'] +['ÅĽ', 'wi'] +['ย', 'ิ'] +['ãģ¡ãĤĥ', 'ãĤĵ'] +['ĠÙħ', 'Ø´'] +['à¸ĺ', 'ี'] +['ãģ¨', 'ãģį'] +['׳×Ļ', '×ķת'] +['Ġë', '¯'] +['Ġë¯', '¸'] +['Ġs', 'ı'] +['ëĭĪ', 'ê¹Į'] +['Ġп', 'л'] +['غ', 'ÙĦ'] +['à¹ģ', 'รà¸ĩ'] +['ب', 'ÙĬر'] +['ãģĤãĤĬ', 'ãģ¾ãģĽãĤĵ'] +['ê·', '¼'] +['Ġy', 'üz'] +['ĠdeÄŁ', 'er'] +['åł´', 'åIJĪ'] +['á»', '¡'] +['м', 'аÑĤ'] +['รา', 'à¸Ĭ'] +['ÙĪØ±', 'ÙĬ'] +['ж', 'ен'] +['ãģ¾', 'ãĤĬ'] +['ãģ®', 'ä¸Ń'] +['×Ļ×ĵ', '×¢'] +['à¸Ń', 'ุ'] +['à¸ļ', 'à¸Ńล'] +['à¸Ľà¸±à¸į', 'หา'] +['ز', 'Ùħ'] +['ÄŁ', 'a'] +['à¸Ń', 'ืà¹Ī'] +['à¸Ńืà¹Ī', 'à¸Ļ'] +['п', 'л'] +['Ġне', 'обÑħодим'] +['׼', '×ij'] +['à¹Ģ', 'ศ'] +['קר', '×Ķ'] +['ì²', 'ĺ'] +['ëł', '¨'] +['×ŀ×§', '×ķ×Ŀ'] +['jÄħ', 'c'] +['Ùĩ', 'ÙĦ'] +['Ġ×¢', '×ij×ķ×ĵ'] +['à¹Ħม', 'à¹ī'] +['à¸ģล', 'ัà¸ļ'] +['×ķ׼', '׾'] +['×§', '×ĵ'] +['اÙĦ', 'ÙĬØ©'] +['ر', 'Ùĩ'] +['ãģij', 'ãĤĮãģ°'] +['ĠÙĨ', 'Ù쨳'] +['ãĤ¢', 'ãĥ«'] +['ìĹ', 'Īëĭ¤'] +['×§', '×ķר'] +['н', 'еÑĢ'] +['ب', 'اب'] +['ãĤ', '¶'] +['سب', 'ب'] +['ÙĦ', 'ÙĬÙĦ'] +['ص', 'ÙĨ'] +['ص', 'در'] +['ế', 'm'] +['à¸Ĭà¹Īว', 'à¸ĩ'] +['ØŃ', 'ÙĨ'] +['Ġ×ij', '×Ĵ'] +['×ŀ', '×ķ×¢'] +['׾', '×Ĺ'] +['大', 'ãģį'] +['ت', 'ب'] +['н', 'еÑĤ'] +['×Ļ×ij', '×Ķ'] +['б', 'л'] +['ãĥĹ', 'ãĥª'] +['اص', 'Ø©'] +['ãģ¤', 'ãģij'] +['×Ļ×ŀ', '×ķש'] +['ãģĮ', 'ãģĤ'] +['ëĭ', '´'] +['ãģĭãĤĤ', 'ãģĹ'] +['ãģĭãĤĤãģĹ', 'ãĤĮ'] +['ãģ¡', 'ãĤī'] +['×ij', '×ĺ'] +['Ġba', 'ÄŁ'] +['×Ļ×Ĺ', 'ס'] +['×ij', '×ķ×¢'] +['ล', 'ี'] +['פע', '×Ļ׾'] +['им', 'и'] +['g', 'ÅĤ'] +['Ġим', 'е'] +['خد', 'اÙħ'] +['×IJ', '×Ļר'] +['Ġy', 'apt'] +['ãģ¨', 'ãģĦ'] +['à¸ĩ', 'à¹Īาย'] +['׾×Ļ', '×ķ'] +['ØŃد', 'Ø«'] +['را', 'ÙĤ'] +['ĠÄIJ', 'i'] +['اد', 'ر'] +['ãģĵãģ¨', 'ãĤĤ'] +['×ij', '×Ļר'] +['Ġв', 'з'] +['ض', 'اÙģ'] +['ת', '×ķ׼'] +['ÑĢ', 'ом'] +['ر', 'ات'] +['à¹Ģà¸Ĺ', 'à¹Īา'] +['ãģĺ', 'ãĤĥ'] +['ãģĿ', 'ãģĵ'] +['اج', 'تÙħاع'] +['à¹īà¸Ń', 'à¸Ļ'] +['ÙĤ', 'Ùħ'] +['ë³', '¸'] +['Ä', 'ŀ'] +['ש', '×Ļ×ķ'] +['×ij', '׳×Ļ'] +['ìľĦ', 'ìĽIJ'] +['à¹ģ', 'à¸Ī'] +['×Ĺ', '×ķר'] +['دÙĬ', 'ÙĨØ©'] +['ت', 'Ø·'] +['ằ', 'm'] +['ò', 'a'] +['ย', 'à¸Ńà¸Ķ'] +['Ġëĭ', '¹'] +['สุ', 'à¸Ĥ'] +['×ĵר', '×ļ'] +['د', 'ÙĨ'] +['س', 'ÙĬÙĨ'] +['ÙĪÙĤ', 'Ùģ'] +['ÑĨ', 'Ñĭ'] +['г', 'оÑĤов'] +['еж', 'дÑĥ'] +['à¸ŀ', 'วà¸ģ'] +['اÙĤ', 'تص'] +['اÙĤتص', 'اد'] +['cz', 'ÄĻ'] +['ni', 'ÄĻ'] +['ÑĢ', 'еб'] +['ØŃ', 'ÙĪ'] +['à¸Ĺ', 'à¹Į'] +['ãĤĪ', 'ãģŃ'] +['д', 'ж'] +['à¸ģล', 'à¹Īาว'] +['دÙĬ', 'Ø«'] +['ãĤ³', 'ãĥŁ'] +['ÙĤ', 'ÙĪÙħ'] +['Ġت', 'ØŃ'] +['à¹Ģ', 'à¸ķิ'] +['اÙģ', 'ظ'] +['à¸Ī', 'ุ'] +['رÙĬ', 'اض'] +['×ŀש', '×ļ'] +['à¹Ĥ', 'ย'] +['еÑĢ', 'е'] +['ãģ¿', 'ãģŁãģĦ'] +['ìĿ´', 'ëĿ¼'] +['ĠاÙĦÙħ', 'ÙĪ'] +['ĠÑģÑĤ', 'о'] +['à¹Ģรà¹ĩ', 'ว'] +['Ġд', 'еÑĤ'] +['ĠÑģ', 'дел'] +['à¹Ģà¸Ĭ', 'ืà¹Īà¸Ń'] +['פ', '׳×Ļ'] +['ÙĪØ¶', 'ÙĪØ¹'] +['×ij', 'ס'] +['à¹ģ', 'à¸Ķ'] +['ó', 'c'] +['ริ', 'ม'] +['ÑĢаÐ', '´'] +['ìĪ', 'ł'] +['ãĥ¼ãĤ', 'º'] +['ãģ«', 'ãģĬ'] +['и', 'но'] +['פ', '×Ļ׾'] +['à¸Ĭั', 'à¹Īà¸Ļ'] +['×Ĺ×ĵ', 'ש'] +['à¹Ģà¸Ļ', 'ืà¹Īà¸Ńà¸ĩ'] +['׳', '×Ļס'] +['غ', 'رب'] +['ãĤ¸', 'ãĥ£'] +['ส', 'ัà¸ĩ'] +['à¹Ģ', 'à¸Ĺีà¹Ī'] +['à¹Ģà¸Ĺีà¹Ī', 'ยว'] +['ëŁ', '¼'] +['à¹ģ', 'à¸Ł'] +['ãĥ¼ãĤ', '·'] +['ãĥ¼ãĤ·', 'ãĥ§ãĥ³'] +['Ġвоз', 'мож'] +['جÙħ', 'ÙĪØ¹'] +['×ijר', '×Ļ×Ŀ'] +['ãĥĪ', 'ãĥ©'] +['ĠкаÑĩ', 'еÑģÑĤв'] +['Ø·', 'ÙĬ'] +['ÑĤ', 'Ñı'] +['צ', '×ķ×¢'] +['ÄŁ', 'ını'] +['ع', 'ÙĦÙī'] +['ا', 'ذ'] +['ÙĪØ§ÙĤ', 'ع'] +['Ùħ', 'ÙĪØ§'] +['ائ', 'ÙĬÙĦ'] +['к', 'ол'] +['á»ģ', 'm'] +['à¸ľà¸¥', 'ิà¸ķ'] +['×Ļ׳', '×ĺר'] +['س', 'Ùĥ'] +['ש', '×Ļר'] +['ศึà¸ģ', 'ษา'] +['à¸ļ', 'ั'] +['Ñĩ', 'аÑģ'] +['×ķפ', '×Ķ'] +['×Ļפ', '×ķ׾'] +['ĠاÙĦس', 'اب'] +['رÙĬ', 'ب'] +['ĠاÙĦ', 'بÙĬ'] +['ãĤ¹', 'ãĥĨ'] +['Ñĩ', 'ен'] +['à¹ģ', 'à¸ľ'] +['Ġ׳', 'ש'] +['ز', 'ÙĬد'] +['ØŃ', 'اد'] +['ëį', 'Ķ'] +['رÙĪ', 'ع'] +['à¸Ĺุ', 'à¸Ļ'] +['ส', 'มา'] +['c', 'zeÅĦ'] +['×Ļ×ĵ', '×Ķ'] +['ãģ§', 'ãģĤ'] +['Ġçoc', 'uk'] +['Ø®', 'ب'] +['à¸ļ', 'าย'] +['à¸Ľà¸£à¸°', 'à¸Ĭา'] +['×ŀש', '׾'] +['ãģª', 'ãģĭ'] +['à¸ģ', 'าย'] +['ãĥģ', 'ãĥ£'] +['аÑĢ', 'и'] +['ĠÑĩ', 'а'] +['à¸Ķ', 'ำ'] +['à¸Ĺั', 'à¹Īว'] +['Ñĥ', 'Ñħ'] +['Ġö', 'z'] +['Ġì¢', 'ĭ'] +['ج', 'رÙĬ'] +['ائ', 'ÙĤ'] +['à¸ł', 'ัย'] +['Ø·', 'ار'] +['د', 'ارة'] +['Ä©', 'nh'] +['Ø«', 'ÙĨ'] +['zell', 'ik'] +['اÙĦ', 'ت'] +['Ġg', 'eli'] +['ãĥķãĤ', '©'] +['ол', 'од'] +['رب', 'ع'] +['שת', '×ŀש'] +['à¸ļร', 'ร'] +['íĿ', '¬'] +['Ġü', 'rün'] +['Ġê·¸', 'ëłĩ'] +['ศาส', 'à¸ķรà¹Į'] +['ãģ', 'ľ'] +['×Ļ×ij', '׾'] +['ĠпÑĢед', 'ÑģÑĤав'] +['سط', 'ÙĬÙĨ'] +['ãĤĴ', '使'] +['Ġпом', 'оÑī'] +['×ķ×§', 'ר'] +['ãĥ¯', 'ãĥ¼'] +['Ġyö', 'net'] +['×Ļ×§', 'ר'] +['à¸Ĥ', 'า'] +['еÑĢи', 'ал'] +['ØŃ', 'Ùģ'] +['Ġ×Ļ', 'צ'] +['à¸Ĺ', 'ิ'] +['å£', '²'] +['à¸Ļ', 'à¸Ńà¸ģ'] +['×ķ׼', 'ר'] +['íĻ', 'ľ'] +['á»§', 'y'] +['ĠاÙĦÙĤ', 'ر'] +['×Ļ×ij', '×ķת'] +['ÅĽ', 'ni'] +['Ùħ', 'شار'] +['ượ', 't'] +['ĠÙĦ', 'دÙĬ'] +['ÑĤ', 'ел'] +['ĠØ¥', 'ÙĦÙĬ'] +['عÙĦ', 'ÙĪÙħ'] +['ìķ', 'ĺ'] +['в', 'иÑĤ'] +['à¸Ħ', 'ะ'] +['yr', 'ı'] +['ãģ¨', 'ãģ£ãģ¦'] +['à¹Ģ', 'à¸ī'] +['à¸ĸ', 'าม'] +['ÙĤ', 'ار'] +['عÙĦ', 'اÙħ'] +['ặ', 'ng'] +['Ùħ', 'ÙĴ'] +['×Ļ×ŀ', 'ת'] +['سب', 'Ø©'] +['ãĤ¯', 'ãĥ©'] +['×ķס', '×£'] +['ĠпÑĢ', 'ин'] +['ãģĦ', 'ãĤį'] +['س', 'اس'] +['عت', 'بر'] +['วิ', 'à¸Ĺย'] +['วิà¸Ĺย', 'า'] +['س', 'Ùĥر'] +['ãĤ·', 'ãĥ§'] +['ãģ', 'ģ'] +['ัà¸ģ', 'ษ'] +['×ij', '×ķ×Ķ'] +['ห', 'ย'] +['ãģ¾', 'ãĤĮ'] +['ĠоÑĢг', 'аниз'] +['каз', 'ал'] +['ĠÑģв', 'Ñıз'] +['uy', 'ết'] +['ĠпÑĢо', 'из'] +['Ġ×§', '×ĺ'] +['à¹ģà¸ģ', 'à¹ī'] +['п', 'ÑĥÑģ'] +['Ġê·¸', 'ê²ĥ'] +['ëĬ', 'IJ'] +['л', 'екÑģ'] +['ãĥ¼ãĥ', 'Ĺ'] +['à¸ķ', 'ำ'] +['ת×Ĺ', '×Ļ׾'] +['à¸Ńà¸ĩ', 'à¸Ħà¹Į'] +['áº', 'µ'] +['׳', 'צ'] +['Ø£', 'Ø´'] +['Ø´', 'Ùĩ'] +['ย', 'ะ'] +['à¸ģ', 'à¸İ'] +['ĠاÙĦØ¥', 'سÙĦاÙħ'] +['ед', 'ÑĮ'] +['ãģ²', 'ãģ¨'] +['ëıĦ', 'ë¡Ŀ'] +['ãģ©', 'ãģ®'] +['Ñĥ', 'в'] +['еÑĩ', 'ение'] +['ĠاÙĦت', 'ج'] +['ãģ«', 'è¡Į'] +['Ġп', 'озв'] +['ãĤı', 'ãĤĬ'] +['ÙĦ', 'اث'] +['íķĺ', 'ìĺĢ'] +['Ġм', 'аÑĢ'] +['Ġkon', 'uÅŁ'] +['ãĥ¬', 'ãĤ¹'] +['ãĤĴ', 'æĮģ'] +['ĠоÑģ', 'нов'] +['×Ĺ', '×ij'] +['ÙĪØ¬', 'ÙĪØ¯'] +['פ', '×ķף'] +['в', 'оÑĢ'] +['Ġн', 'ик'] +['ãģĭ', 'ãĤĭ'] +['ÅŁtır', 'ma'] +['×Ļס', '×ĺ'] +['Ø£', 'ÙĦ'] +['ห', 'à¹Į'] +['и', 'она'] +['лÑĮ', 'н'] +['Ġг', 'оÑģ'] +['ĠÐľÐ¾Ñģ', 'к'] +['ÑĢ', 'об'] +['×ķ×IJ', '×Ļ'] +['ãģĬãĤĬ', 'ãģ¾ãģĻ'] +['ãģ£ãģ', '±'] +['к', 'л'] +['à¸Ļ', 'à¸Ķà¹Į'] +['رÙĬ', 'Ùģ'] +['اس', 'ب'] +['ĠÑĢ', 'еÑĪ'] +['Ġд', 'ол'] +['ãģ¹', 'ãģį'] +['×Ļ×ij', '×ķר'] +['м', 'еÑī'] +['Ġна', 'ÑĪ'] +['à¹ģ', 'à¸Ľà¸¥'] +['ÑĢ', 'иÑĤ'] +['кÑĥ', 'Ñģ'] +['и', 'ÑĢа'] +['аÑĤ', 'ÑĥÑĢ'] +['ÙĪØ§', 'صÙĦ'] +['à¹Ģà¸ľ', 'ย'] +['à¸Ń', 'ำ'] +['à¹Ģà¸ģ', 'ิà¸Ļ'] +['غ', 'Ùħ'] +['ãģĻ', 'ãģİ'] +['lı', 'kl'] +['ÅĦ', 'sk'] +['ê²', '¬'] +['×Ļ׼', '×Ķ'] +['×Ĺ', 'ש×ij'] +['ÙĪØ±', 'ÙĬØ©'] +['Ġд', 'ейÑģÑĤв'] +['×Ĺ׾', '×ĺ'] +['Ġ׾', '×ŀ×¢'] +['צ׾', '×Ļ×Ĺ'] +['еÑĩ', 'а'] +['Ùģ', 'اع'] +['×Ĵ', '×Ļ×ĵ'] +['áºŃ', 'm'] +['ÄĻ', 'b'] +['Ø´', 'ع'] +['ãģı', 'ãĤĬ'] +['à¸ŀ', 'ุ'] +['ед', 'еÑĢ'] +['à¸Ĥ', 'à¸Ļ'] +['à¸Ħ', 'าร'] +['ĠболÑĮ', 'ÑĪ'] +['ãģı', 'ãģªãĤĬ'] +['à¸ĵ', 'า'] +['×ĵ', '×ķ×Ĵ'] +['Ġм', 'н'] +['ä¸Ĭ', 'ãģĮ'] +['ç¶ļ', 'ãģį'] +['ฤ', 'ษ'] +['à¸', 'Ĩ'] +['Ø®', 'ÙĬ'] +['à¹Ģà¸Ĺ', 'à¸ŀ'] +['สั', 'ม'] +['à¹Ģส', 'à¸Ļ'] +['à¹Ģสà¸Ļ', 'à¸Ń'] +['ãĥ', '´'] +['Ġи', 'ÑģÑĤ'] +['با', 'شر'] +['ĠÑĥ', 'ÑĢов'] +['×ŀ', '×ķ×ĸ'] +['ab', 'ı'] +['wa', 'ż'] +['×ķצ', '×IJ×Ķ'] +['ÑĤ', 'веÑĢ'] +['à¸ŀัà¸Ļà¸ĺ', 'à¹Į'] +['׳', '×Ĵ×ĵ'] +['ãĤĭ', 'ãģĵãģ¨ãģĮãģ§ãģį'] +['ĠÑĤÑĢ', 'еб'] +['à¸ģร', 'ุà¸ĩ'] +['ØŃت', 'اج'] +['à¹Ģ', 'à¸Ħล'] +['ã', 'Ĩ'] +['ÄĻ', 'tr'] +['Ġszcz', 'eg'] +['Ġר', 'ש'] +['à¸Ĺ', 'à¸ĺ'] +['Ġн', 'ек'] +['Ġнек', 'оÑĤоÑĢ'] +['в', 'ÑĪ'] +['Ð', '¬'] +['à¹Īว', 'ย'] +['ล', 'ุ'] +['б', 'ÑĢÑı'] +['หม', 'ูà¹Ī'] +['à¹ģ', 'à¸ķà¸ģ'] +['ר׼', '×Ļ×Ŀ'] +['Ġí', 'ĸī'] +['ã', 'i'] +['Ùĥر', 'Ø©'] +['â', 'Ń'] +['í', 'IJ'] +['ã', 'į'] +['á', 'ģ'] +['â', '®'] +['â', '¥'] +['ì', '®'] +['à', '¿'] +['â', '¿'] +['á', 'Ĥ'] +['á', '¤'] +['â', 'ł'] +['í', 'Ł'] +['ðIJ', 'į'] +['ðIJ', '°'] +['ðĿ', 'Ĩ'] +['ðŁ', 'Ī'] +['Ġ×¢', '׾'] +['Ġع', 'ÙĨ'] +['ĠÙħ', 'ع'] +['Ġ×ĸ', '×Ķ'] +['ĠÙħ', 'ا'] +['Ġm', 'Ãł'] +['Ġd', 'ụ'] +['á»ĩ', 'c'] +['а', 'Ñħ'] +['s', 'ı'] +['íķĺ', 'ê³ł'] +['Ġ×ķ', '×ij'] +['ĠÐŁ', 'о'] +['×ķת', 'ר'] +['ĠÙĦ', 'Ùħ'] +['Ġ×ķ', '׾'] +['ãģĹãģ¦', 'ãģĦãĤĭ'] +['Ġ×ŀ', '×Ļ'] +['Ġب', 'ÙĬÙĨ'] +['з', 'а'] +['ĠÙĥ', 'اÙĨ'] +['Ġ×Ķ', '×Ļ×Ķ'] +['ëħ', 'Ħ'] +['×IJ', '×ķ'] +['д', 'и'] +['ĠпеÑĢ', 'е'] +['d', 'ı'] +['Ġ׾', 'ש'] +['Ġש', '×ŀ'] +['ãģĮ', 'ãģĤãĤĭ'] +['ãģĦ', 'ãģĦ'] +['ÑĢ', 'е'] +['×§', '×ķ'] +['и', 'ли'] +['м', 'е'] +['ÙĬ', 'ت'] +['ãģ§', 'ãģĤãĤĭ'] +['Ġв', 'о'] +['à¹ĥ', 'หม'] +['à¹ĥหม', 'à¹Ī'] +['Ġש', '×ij'] +['Ġ', 'à¹Ĥà¸Ķย'] +['ÙĬ', 'Ùĩ'] +['ãģ§ãģĻ', 'ãģĮ'] +['ãģ¨', 'ãģ¯'] +['ר', '×ķ'] +['Ġ', 'à¸ĭึà¹Īà¸ĩ'] +['ãģ§ãģį', 'ãĤĭ'] +['м', 'о'] +['à¹Ģà¸ŀ', 'ืà¹Īà¸Ń'] +['צ', '×ķ'] +['×ĺ', '×ķ'] +['ìķ', 'Ī'] +['Ġh', 'á»į'] +['à¹Ģà¸ĩ', 'ิà¸Ļ'] +['ĠاÙĦ', 'ب'] +['Ġ', 'มี'] +['ë¬', '¼'] +['Ñģ', 'е'] +['ëĵ¤', 'ìĿ´'] +['Ġë§', 'IJ'] +['Ġl', 'Ỽ'] +['a', 'ÅĤ'] +['×Ĺ', '×ijר'] +['Ġd', 'á»±'] +['ÙĬ', 'Ø«'] +['Ġth', 'á»ĭ'] +['à¸ģà¹Ī', 'à¸Ńà¸Ļ'] +['Ġ×ij', '׼׾'] +['ãģ', '¸'] +['ã썿ĢĿ', 'ãģĦãģ¾ãģĻ'] +['ả', 'nh'] +['ย', 'า'] +['Ùģ', 'ا'] +['ส', 'ี'] +['à¸ķ', 'า'] +['ë²', 'ķ'] +['ãĥª', 'ãĥ¼'] +['รา', 'à¸Ħา'] +['Ġ×ķ', '׾×IJ'] +['ãģ¨', 'ãģĵãĤį'] +['à¹Ģล', 'ืà¸Ń'] +['di', 'ÄŁi'] +['ÙĪ', 'اÙĨ'] +['Ġ׾×Ķ', 'ת'] +['รว', 'ม'] +['פ', '×Ļ×Ŀ'] +['à¸ľ', 'ม'] +['ж', 'и'] +['c', 'ı'] +['ÑĢ', 'од'] +['Ġkar', 'ÅŁÄ±'] +['×Ĵ', '×ķ'] +['ãģ«', 'ãģ¤'] +['ãģ«ãģ¤', 'ãģĦãģ¦'] +['r', 'Ãł'] +['×Ļ×ķת', 'ר'] +['ĠìĨ', 'Į'] +['×§', '×Ķ'] +['ÑģÑĤв', 'о'] +['ãģij', 'ãģ©'] +['g', 'é'] +['à¸Ķ', 'à¹īาà¸Ļ'] +['çļĦ', 'ãģ«'] +['ĠÙĬ', 'ÙħÙĥÙĨ'] +['ìĨ', 'į'] +['ÙĬ', 'Ùĥ'] +['à¹Ħว', 'à¹ī'] +['Ñģки', 'й'] +['ì', 'm'] +['Ġ׾×IJ', '×Ĺר'] +['à¸Ńา', 'หาร'] +['Ġà¹Ģ', 'à¸ŀ'] +['รา', 'ะ'] +['ล', 'ูà¸ģ'] +['ÑģÑĤ', 'а'] +['Ġìľ', 'ł'] +['ÙĤ', 'ÙĪÙĦ'] +['б', 'оÑĢ'] +['Ñģк', 'ого'] +['หล', 'ัà¸ĩ'] +['à¸Ĥ', 'à¹Īาว'] +['à¹Ģม', 'ืà¸Ńà¸ĩ'] +['ê°', 'ģ'] +['t', 'Ãł'] +['ÙĬ', 'ÙĬÙĨ'] +['عر', 'ض'] +['ë°', '©'] +['Ġëı', 'Ļ'] +['Ġà¹Ģ', 'à¸Ľ'] +['Ġà¹Ģà¸Ľ', 'à¹ĩà¸Ļ'] +['ç', 'i'] +['li', 'ÄŁi'] +['ìĹIJ', 'ê²Į'] +['ãĤ¿', 'ãĥ¼'] +['Ġ׾', 'ת'] +['פ', '×ķת'] +['à¸Ĥ', 'à¸Ń'] +['ر', 'س'] +['ìł', 'IJ'] +['à¸ľ', 'à¹Īาà¸Ļ'] +['ÑĦ', 'и'] +['ج', 'ÙĨ'] +['ì¢', 'ħ'] +['Ġ×Ķ', 'פ'] +['Ġn', 'go'] +['á»ĭ', 'a'] +['Ġtá»', 'ķ'] +['Ġê·¸', '리'] +['à¹Ģม', 'ืà¹Īà¸Ń'] +['ذ', 'Ùĥر'] +['ìĸ', 'ij'] +['ìĹ', 'Ń'] +['×ĺ', '׾'] +['k', 'ı'] +['Ġع', 'ÙħÙĦ'] +['Ġع', 'ÙĨد'] +['à¸ĭ', 'ืà¹īà¸Ń'] +['Ġê±', '°'] +['в', 'е'] +['r', 'ü'] +['à¹Ģ', 'à¸Ńา'] +['ส', 'à¹Į'] +['à¸Ī', 'à¸Ļ'] +['ס', 'ת'] +['Ġgi', 'ả'] +['ãĤĭ', 'ãģ¨'] +['à¸ģำ', 'ลัà¸ĩ'] +['н', 'ей'] +['à¸Ī', 'ริ'] +['à¸Īริ', 'à¸ĩ'] +['Ġë', 'į'] +['Ġëį', 'Ķ'] +['à¸Ħà¹Ī', 'ะ'] +['ì', 'n'] +['Ġsü', 're'] +['Ġqu', 'y'] +['à¸ļ', 'าà¸ĩ'] +['åıĸ', 'ãĤĬ'] +['ר', '×Ĺ'] +['×ij', 'ת'] +['ãģĮ', 'ãģĤãĤĬãģ¾ãģĻ'] +['ר', 'ש'] +['ìĹIJ', 'ëĬĶ'] +['Ġ×IJ', 'פשר'] +['ay', 'ı'] +['ãģĮ', 'ãĤī'] +['ØŃ', 'ب'] +['ан', 'Ñģ'] +['س', 'ÙĪ'] +['ĠпÑĢ', 'е'] +['د', 'ÙĪ'] +['ãģ«', 'ãĤĪ'] +['à¹Ģà¸ģ', 'ม'] +['สู', 'à¸ĩ'] +['m', 'akt'] +['makt', 'ad'] +['maktad', 'ır'] +['Ġön', 'em'] +['×Ļ×ŀ', '×Ļ×Ŀ'] +['б', 'о'] +['ÙĪ', 'ÙĬØ©'] +['รู', 'à¸Ľ'] +['à¹Ĥล', 'à¸ģ'] +['Ùħ', 'ÙĬع'] +['ÑģÑĤ', 'Ñĥп'] +['à¹Ĥ', 'à¸Ń'] +['دÙĬ', 'ÙĨ'] +['ì¤', 'ij'] +['ãģĹãģ', 'ı'] +['à¹Ģส', 'ีย'] +['в', 'Ñĭ'] +['Ùħ', 'ت'] +['íĺ', 'Ħ'] +['ãĥIJ', 'ãĥ¼'] +['ا', 'Ø´'] +['×§', 'ס'] +['Ġtá»', '¥'] +['ล', 'à¸Ķ'] +['Ùģ', 'Ø©'] +['í', 'ijľ'] +['ر', 'ج'] +['k', 'ÅĤad'] +['ĠÅŁ', 'ey'] +['ĠØ£', 'Ùħ'] +['Ġà¹Ģ', 'ม'] +['Ġب', 'ÙĦ'] +['Ñģ', 'каÑı'] +['ãģ¨', 'ãģ®'] +['Ġìĭ', '¤'] +['ấ', 'm'] +['ห', 'à¹īà¸Ńà¸ĩ'] +['à¸Ĭ', 'ม'] +['d', 'ü'] +['Ġç', 'ek'] +['Ġê³', 'ł'] +['×Ĵ', '×ij'] +['à¸Ĭี', 'วิ'] +['à¸Ĭีวิ', 'à¸ķ'] +['Ù쨶', 'ÙĦ'] +['à¸', '¯'] +['ç', 'ı'] +['Ġب', 'Ø´'] +['ĠÙĩ', 'ÙĨا'] +['ãģį', 'ãģ¾ãģĹãģŁ'] +['t', 'ü'] +['Ġìĺ', 'ģ'] +['ĠTür', 'k'] +['к', 'ÑĤ'] +['פר', 'ס'] +['ãģ¨ãģĦãģĨ', 'ãģĵãģ¨'] +['í', 'ĶĦ'] +['à¹ģร', 'à¸ģ'] +['ר', '×ķף'] +['Ġar', 'as'] +['×ŀצ', '×IJ'] +['Ġtá»', 'ī'] +['س', 'ا'] +['à¸ŀ', 'à¸Ń'] +['ĠاÙĦÙħ', 'ØŃ'] +['ãĥ', '¤'] +['ĠاÙĦ', 'است'] +['Ùģ', 'ÙĨ'] +['×Ļ×ŀ', '×Ķ'] +['ر', 'ت'] +['ãģ¨', 'ãĤĤ'] +['Ġна', 'Ñģ'] +['п', 'ÑĢи'] +['Ġ×Ĺ', '×ķ'] +['и', 'ла'] +['ÙĬ', 'Ø´'] +['Ġgö', 'z'] +['Ġ×ij', '׳×Ļ'] +['ım', 'ı'] +['ĠÑĤ', 'еÑħ'] +['Ġh', 'á»Ļ'] +['غ', 'ر'] +['к', 'он'] +['اØŃ', 'ت'] +['Ġ', 'à¸ŀ'] +['à¸Ń', 'à¸Ńà¸Ļ'] +['à¸Ńà¸Ńà¸Ļ', 'à¹Ħล'] +['à¸Ńà¸Ńà¸Ļà¹Ħล', 'à¸Ļà¹Į'] +['Ñħ', 'о'] +['Ñı', 'в'] +['à¹ģ', 'สà¸Ķ'] +['à¹ģสà¸Ķ', 'à¸ĩ'] +['à¹Ģà¸ŀ', 'ียà¸ĩ'] +['ÑĤ', 'ов'] +['ا', 'ÙĬ'] +['Ġ×Ķ', '×ĵ'] +['Ġ×ķ', '׼'] +['ãĤī', 'ãģĦ'] +['×ķפ', 'ף'] +['Ġë', '¶Ī'] +['ล', 'à¸Ńà¸ĩ'] +['Ø·', 'اÙĦ'] +['Ġн', 'и'] +['ĠÙħ', 'ست'] +['ế', 'c'] +['Ġש', '׼'] +['ĠëķĮ', '문'] +['วัà¸Ļ', 'à¸Ĺีà¹Ī'] +['×Ļ׾', '×ĵ'] +['ØŃ', 'ا'] +['е', 'ÑĨ'] +['Ġc', 'ứ'] +['×ĵ', '×ķר'] +['ĠÙħ', 'ØŃ'] +['ר׼', '×ij'] +['بÙĬ', 'ع'] +['ни', 'и'] +['ĠاÙĦØ£', 'ÙĪÙĦ'] +['à¸Ħว', 'ร'] +['ã썿ĢĿ', 'ãģĨ'] +['ĠС', 'о'] +['ائ', 'ÙĬØ©'] +['ر', 'اء'] +['оÑģ', 'об'] +['Ġب', 'Ø£ÙĨ'] +['×¢', '×ķ×ĵ'] +['ĠÑĤ', 'е'] +['ãģĵ', 'ãģĨ'] +['ÑģÑĤ', 'ÑĢа'] +['ай', 'н'] +['Ġsö', 'z'] +['ت', 'ÙĨا'] +['à¸Ń', 'ิ'] +['ặ', 'p'] +['ĠìķĦ', 'ëĭĪ'] +['íķ', 'Ń'] +['Ġר×IJ', 'ש'] +['Ġ', 'à¹Ħà¸Ķà¹ī'] +['Ġ×Ĵ', '×ĵ'] +['Ġס', 'פר'] +['обÑī', 'е'] +['ĠÙĪ', 'Ø¥'] +['ada', 'ÅŁ'] +['ãģ¡', 'ãĤĩ'] +['×§', '×ķ׾'] +['ÑĢ', 'ез'] +['ĠdÃ¼ÅŁ', 'ün'] +['Ġ×ij', '×IJ×ŀ'] +['Ġìĸ´', 'ëĸ'] +['ער', '×ij'] +['н', 'ее'] +['ĠÑģÑĤÑĢ', 'ан'] +['س', 'اÙĨ'] +['yn', 'ı'] +['ĠاÙĦر', 'ئÙĬس'] +['ãģĹãģ', 'ª'] +['Ġ׳', 'ת'] +['ãģ«ãģª', 'ãģ£ãģŁ'] +['g', 'ü'] +['åıĹ', 'ãģij'] +['׾', 'ת'] +['ìł', 'Ī'] +['ëĬĶ', 'ëį°'] +['Ø®', 'ÙĬر'] +['à¸ķà¹īà¸Ńà¸ĩ', 'à¸ģาร'] +['ĠÙĦ', 'Ø£ÙĨ'] +['Ġch', 'á»ĭ'] +['ÙĪ', 'Ø©'] +['à¹ĥ', 'ส'] +['ë¶Ģ', 'íĦ°'] +['íķĺ', 'ë©´'] +['ữ', 'u'] +['à¹Ģหม', 'ืà¸Ńà¸Ļ'] +['б', 'еÑĢ'] +['ĠìĿ´', 'ìļ©'] +['ĠÑģ', 'еб'] +['wiÄĻ', 'ks'] +['Ġ׳', '×¢'] +['ÑĤ', 'ÑĥÑĢ'] +['Ġngh', 'Ä©'] +['ש', '×ķ×ĺ'] +['ti', 'ÄŁi'] +['Ġde', 'ÄŁi'] +['×IJ', '×ij'] +['Ġ×ŀ', '×ŀ'] +['ãĥĹ', 'ãĥŃ'] +['wa', 'ÅĤ'] +['à¸Ī', 'ึà¸ĩ'] +['Ø®', 'دÙħ'] +['×IJ', '×Ŀ'] +['Ä±ÅŁ', 'ı'] +['cz', 'Äħ'] +['ר', '×ĵ'] +['ĠÑĢ', 'Ñĥб'] +['خر', 'Ùī'] +['ãģ®', 'æĸ¹'] +['Ġд', 'енÑĮ'] +['×Ĺ', '×Ļ×Ŀ'] +['еÑĤ', 'е'] +['ëĤ', 'ľ'] +['×IJ', '×Ĵ'] +['×¢', '×ķר'] +['ë³', 'Ħ'] +['åIJĮ', 'ãģĺ'] +['ãĤ', '²'] +['ר', '×ļ'] +['×ķש', '×IJ'] +['ìľ', '¡'] +['ا', 'Ø®'] +['צ', '×Ļ×Ķ'] +['á»±', 'a'] +['ãģĪ', 'ãģ¦'] +['ש×Ķ', '×ķ'] +['ан', 'ÑĤ'] +['ลา', 'à¸Ķ'] +['ин', 'г'] +['ë¡', 'ł'] +['اع', 'د'] +['ÙĪ', 'سط'] +['Ġв', 'оп'] +['Ġвоп', 'ÑĢоÑģ'] +['Ùħ', 'ÙĬÙĨ'] +['à¸Ħ', 'à¸ĩ'] +['×Ļר', '×Ļ×Ŀ'] +['c', 'ów'] +['ê²', '©'] +['Ġê·¸', '룰'] +['Ġì§', 'Ħ'] +['Ġש', '׾×Ķ'] +['à¹Ģร', 'ิà¹Īม'] +['à¸Ĭ', 'à¸Ńà¸ļ'] +['д', 'еÑĤ'] +['ÑİÑī', 'иÑħ'] +['à¸ļ', 'à¸Ńà¸ģ'] +['æĢĿ', 'ãģĦ'] +['ع', 'ÙĬد'] +['ס', '×ŀ'] +['×Ĵ', '×Ļ×¢'] +['צ', '×ĵ'] +['ب', 'ات'] +['ĠëͰ', 'ëĿ¼'] +['à¸Ī', 'ัà¸ĩ'] +['ãģłãģij', 'ãģ§'] +['×¢', '×Ļר'] +['ĠÑĩ', 'ел'] +['ĠÑĩел', 'ов'] +['ĠÑĩелов', 'ек'] +['ãĥĥ', 'ãĥģ'] +['à¹Ģà¸ģ', 'ีà¹Īยว'] +['à¸Ķ', 'ิ'] +['Ġפ', '×¢'] +['×Ļ×ŀ', '×Ļ'] +['ë°', 'ĺ'] +['Ø®', 'ار'] +['×ij', '×Ļת'] +['×¢', '×Ļ×Ŀ'] +['ü', 'yor'] +['ãĤģ', 'ãģ¦'] +['к', 'лад'] +['Ġ', 'à¸Īาà¸ģ'] +['à¹Ģà¸Ħ', 'ย'] +['ส', 'à¸Ńà¸ĩ'] +['à¹ģ', 'à¸Ħà¹Ī'] +['ẫ', 'u'] +['หà¸Ļ', 'ัà¸ĩ'] +['ש׾', '×ķ×Ŀ'] +['اÙĨ', 'ÙĬØ©'] +['åĩº', 'ä¼ļ'] +['åĩºä¼ļ', 'ãģĦ'] +['à¸ł', 'าย'] +['à¸ļา', 'à¸Ĺ'] +['à¸Ĭา', 'ว'] +['mu', 'ÅŁ'] +['Ġ׾ק', '×ij׾'] +['ãĤ·', 'ãĥ£'] +['Ġİ', 'ÅŁ'] +['×Ĵ×ĵ', '×ķ׾'] +['ج', 'عÙĦ'] +['ë³', 'Ģ'] +['ยิ', 'à¹Īà¸ĩ'] +['à¸Ļ', 'าย'] +['à¸Ļ', 'ีà¹Ī'] +['วิ', 'à¸ĺี'] +['ãĤī', 'ãģªãģĦ'] +['ëł', 'Ī'] +['Ġ문', 'ìłľ'] +['Ġ', 'à¸ģ'] +['à¸Ĺำ', 'à¸ĩาà¸Ļ'] +['à¹Ģว', 'à¹ĩà¸ļ'] +['ÑĦ', 'е'] +['楽', 'ãģĹ'] +['สำ', 'à¸Ħ'] +['สำà¸Ħ', 'ัà¸į'] +['ر', 'Ùħ'] +['ãģķãĤĮ', 'ãģ¦'] +['Ġоб', 'ла'] +['ר×IJ', '×Ļ'] +['หม', 'à¸Ķ'] +['ÙĨ', 'ÙĬØ©'] +['ли', 'н'] +['Ġe', 'ÄŁ'] +['it', 'im'] +['ëł', '¹'] +['ص', 'اÙĦ'] +['ÅĽ', 'l'] +['à¸ľ', 'ิà¸Ķ'] +['ãĥŀ', 'ãĥ³'] +['åħ¥', 'ãĤĮ'] +['à¹Ģà¸ķ', 'à¸Ńรà¹Į'] +['ار', 'ÙĬ'] +['ĠÐ', '¦'] +['d', 'ür'] +['ส', 'วย'] +['ë¦', '½'] +['رÙĥ', 'Ø©'] +['Ġh', 'ã'] +['×Ļת', '×Ķ'] +['à¸Ĥ', 'à¸Ļา'] +['à¸Ĥà¸Ļา', 'à¸Ķ'] +['à¸Īำ', 'à¸Ļ'] +['à¸Īำà¸Ļ', 'วà¸Ļ'] +['ש', '×ķ×§'] +['Ġд', 'ом'] +['ì±', 'ħ'] +['ãģĭ', 'ãģij'] +['פ', '×ķ׾'] +['à¸Ĭ', 'าย'] +['Ñģ', 'моÑĤÑĢ'] +['Ñģл', 'Ñĥж'] +['ש', '×IJ׾'] +['кÑĢÑĭ', 'ÑĤ'] +['Ġìŀ', 'ĺ'] +['é«ĺ', 'ãģĦ'] +['ĠÑĢ', 'Ñĥк'] +['ÙĨ', 'ص'] +['д', 'ав'] +['ưá»', '¡'] +['ưỡ', 'ng'] +['ر', 'اÙħ'] +['×Ļ׳', '×Ļ×Ŀ'] +['ãĥ©', 'ãĥ¼'] +['ëĦ', '¤'] +['Ġت', 'ع'] +['l', 'ke'] +['好', 'ãģį'] +['æĮģ', 'ãģ¡'] +['Ġë§', 'İ'] +['Ġy', 'ük'] +['ĠÑģоÑģÑĤ', 'ав'] +['енÑĤ', 'ÑĢ'] +['pe', 'ÅĤ'] +['à¹Ģà¸Ľà¸¥', 'ีà¹Īย'] +['à¹Ģà¸Ľà¸¥à¸µà¹Īย', 'à¸Ļ'] +['íı', 'ī'] +['ãĤĦ', 'ãģĻ'] +['×Ĺ', '×ĸ'] +['×ijר', '×Ķ'] +['ë£', '¨'] +['ìĶ', 'Ģ'] +['بØŃ', 'Ø«'] +['à¹Ģà¸ķ', 'à¹ĩ'] +['ów', 'i'] +['ب', 'Ùĩ'] +['ãģį', 'ãģ¾ãģĻ'] +['Ġ×¢', '×ŀ'] +['×Ĵ', '×ķ׾'] +['ез', 'д'] +['ÙĬÙģ', 'Ø©'] +['สà¸Ļ', 'à¹ĥà¸Ī'] +['Ġת', '׾'] +['Ñı', 'Ñī'] +['Ġس', 'ÙĨ'] +['ĠÙĪØ§', 'ØŃد'] +['ĠÑģ', 'м'] +['lad', 'ı'] +['ı', 'ld'] +['×Ļר', 'ת'] +['ีย', 'à¸Ļ'] +['ת×Ĺ', 'ת'] +['Ġж', 'из'] +['à¸ŀ', 'ั'] +['à¸ŀั', 'à¸Ĵ'] +['à¸ŀัà¸Ĵ', 'à¸Ļา'] +['à¸Ĭ', 'ิ'] +['ا', 'Ø®ÙĦ'] +['ãģ£ãģ¦', 'ãģĦãģŁ'] +['รั', 'à¸IJ'] +['ãĤģ', 'ãĤĭ'] +['à¹Ĥ', 'à¸ģ'] +['ĠT', 'á»ķ'] +['Ġh', 'akk'] +['ر', 'Ùģ'] +['ìł', 'Ģ'] +['Ñģ', 'об'] +['ãģª', 'ãģijãĤĮãģ°'] +['Ùĩ', 'ÙĪ'] +['Ġë²', 'ķ'] +['ãĤ', 'Ĩ'] +['ĠاÙĦس', 'عÙĪØ¯'] +['Ġ×IJ', 'תר'] +['اØ', 'º'] +['Ġ׾', '×ĵ'] +['à¹ģ', 'à¸ķ'] +['à¹ģà¸ķ', 'à¹Īà¸ĩ'] +['íĮ', 'Į'] +['Ñĥп', 'иÑĤÑĮ'] +['à¸ŀืà¹īà¸Ļ', 'à¸Ĺีà¹Ī'] +['×ij', 'ת×Ļ'] +['à¹ĩ', 'à¸ģ'] +['ÅĤ', 'at'] +['Ġê°ľ', 'ìĿ¸'] +['ìłķ', 'ë³´'] +['ÑĤ', 'ал'] +['Ġgü', 'ven'] +['Ġİ', 'l'] +['Ġê°', 'ģ'] +['Ġب', 'ت'] +['×ŀ', '×ķ׳×Ķ'] +['ĠاÙĦØŃ', 'ÙĥÙĪÙħ'] +['ÙĤ', 'ات'] +['à¹ģ', 'à¸ģà¹Ī'] +['ห', 'าà¸ģ'] +['н', 'ÑĮ'] +['à¸Ľ', 'รัà¸ļ'] +['มา', 'à¸ĵ'] +['Ġне', 'Ñģк'] +['ĠØ', '¶'] +['สม', 'ั'] +['สมั', 'à¸Ħร'] +['ãģĮ', 'ãģĤãĤĬ'] +['м', 'еÑģÑĤ'] +['Ġ×IJ', 'צ׾'] +['Ġкомп', 'ани'] +['ס', 'ר'] +['ÙĬÙħ', 'Ø©'] +['ĠÑħ', 'оÑĢо'] +['ĠÑħоÑĢо', 'ÑĪ'] +['Ġ×Ļ', '×ķ×ĵ'] +['ü', 's'] +['×Ĵ', '×Ļש'] +['à¸ļ', 'à¸Ĺ'] +['تÙĨ', 'ظ'] +['ว', 'าà¸ĩ'] +['ม', 'หา'] +['Ġ׼', '×ķ׾'] +['à¸Ĥ', 'à¹īาà¸ĩ'] +['ë°', 'ľ'] +['г', 'од'] +['д', 'ан'] +['ãģĭãĤĤãģĹãĤĮ', 'ãģ¾ãģĽãĤĵ'] +['ãģĵ', 'ãģ¡ãĤī'] +['ãĥIJ', 'ãĤ¤'] +['ece', 'ÄŁi'] +['دÙĬ', 'دة'] +['ÙĨ', 'Ùī'] +['Ġëĭ¤', 'ìĿĮ'] +['ว', 'ี'] +['غ', 'ا'] +['ли', 'з'] +['à¹Ģà¸Ķ', 'ิ'] +['à¹Ģà¸Ķิ', 'ม'] +['ĠÙĬ', 'ست'] +['Ġy', 'ılı'] +['ko', 'ÅĦ'] +['ãģ§ãģĹãĤĩãģĨ', 'ãģĭ'] +['ãģĤ', 'ãģª'] +['ãģĤãģª', 'ãģŁ'] +['ÑĨ', 'ен'] +['ĠÙĪ', 'ز'] +['×IJ', '×Ļש'] +['à¹Ī', 'à¸Ń'] +['ر', 'ØŃ'] +['ê´', 'ij'] +['ÑĢа', 'ÑģÑĤ'] +['Ġ×Ķ', '׾'] +['ãģĹãģ¦', 'ãĤĤ'] +['×ŀר', '׼'] +['×ŀר׼', '×ĸ'] +['éģķ', 'ãģĦ'] +['ãģŁ', 'ãģı'] +['ĠÑģ', 'Ñĥд'] +['в', 'еÑģÑĤи'] +['ĠíķĦ', 'ìļĶ'] +['ãĥķ', 'ãĤ§'] +['ÑĤелÑĮ', 'но'] +['à¹Ģà¸ŀ', 'ืà¹Īà¸Ńà¸Ļ'] +['ÅĤu', 'ż'] +['à¹Ģà¸Ķิà¸Ļ', 'à¸Ĺาà¸ĩ'] +['ש', '×ķר'] +['Ġ×ŀ', '×ĵ'] +['×ķ×¢', '׾'] +['ÙĦ', 'اÙħ'] +['à¹Ħ', 'à¸ĭ'] +['л', 'ей'] +['кÑĥ', 'ÑĢ'] +['áº', '¢'] +['à¸Ĺ', 'าà¸Ļ'] +['ì§', 'ij'] +['ĠгоÑĢ', 'од'] +['ר', 'ס'] +['׾', '×ķ×Ĵ'] +['mas', 'ını'] +['Ġл', 'ÑĥÑĩ'] +['ล', 'à¹Īา'] +['ìļ', '¸'] +['ש', '×ĺ'] +['ĠÐĺ', 'н'] +['í', 'Ĥ¤'] +['ÙĪÙĦ', 'ا'] +['ìķ', 'ł'] +['ĠØ£ÙĬ', 'ضا'] +['Ùĥ', 'ار'] +['ĠاÙĦت', 'ع'] +['ส', 'ูà¹Ī'] +['ãĤ', '¼'] +['×ij', '×Ļ×IJ'] +['ย', 'à¸ģ'] +['ĠØŃ', 'ÙĤ'] +['ر', 'بÙĬ'] +['ãģĺãĤĥ', 'ãģªãģĦ'] +['รัà¸ģ', 'ษา'] +['Ñħод', 'иÑĤ'] +['à¸ķ', 'à¸Ńà¸ļ'] +['׳', '×ĺ×Ļ'] +['ĠاÙĦÙħ', 'ج'] +['تÙħ', 'ع'] +['ов', 'аÑĤÑĮ'] +['ÙĦ', 'ÙĬÙĨ'] +['×Ļ×ŀ', '×ķת'] +['Ġm', 'ù'] +['n', 'ÄĻ'] +['Ġد', 'ÙĬ'] +['׼', 'ש×Ļ×ķ'] +['Ġhi', 'ç'] +['ë', 'ijIJ'] +['ÙĪ', 'اء'] +['ÙĪ', 'Ø·'] +['ĠاÙĦ', 'بÙĦ'] +['à¹ģม', 'à¹ī'] +['×§', '×ķת'] +['ÙĪØ¬', 'د'] +['å§ĭ', 'ãĤģ'] +['ÙĬ', 'ئة'] +['Ġë§', '¤'] +['ص', 'بØŃ'] +['פ', '×IJ'] +['г', 'оÑĢ'] +['ס', '×Ķ'] +['بÙĬ', 'ÙĤ'] +['ย', 'าà¸ģ'] +['Ġн', 'ад'] +['ÙĬ', 'Ùij'] +['Ġب', 'ÙĪ'] +['ס', '×ķר'] +['Ùħ', 'ÙĥاÙĨ'] +['ר', '×ij'] +['×Ĵ', '×ĸ'] +['צ', 'ת'] +['b', 'ilit'] +['л', 'аг'] +['ĠN', 'go'] +['×IJ', '×ķר'] +['à¸ķ', 'à¸Ļ'] +['íĬ', '¹'] +['à¸Ĺีà¹Ī', 'à¸Ķี'] +['à¸Ľà¸£à¸°', 'à¸Īำ'] +['ов', 'ание'] +['ãģĦ', 'ãģ¤'] +['ãĥĥãĤ¯', 'ãĤ¹'] +['åIJĪ', 'ãĤı'] +['åIJĪãĤı', 'ãģĽ'] +['×Ļ׳', '×ķ×Ļ'] +['ạ', 'y'] +['Ø«', 'ÙĤ'] +['ĠпÑĢ', 'об'] +['ĠпÑĢоб', 'лем'] +['ÅŁ', 'eh'] +['ÅŁeh', 'ir'] +['ع', 'ادة'] +['اÙĨ', 'ÙĪÙĨ'] +['à¸ķัว', 'à¹Ģà¸Ńà¸ĩ'] +['ì¶', 'ķ'] +['ı', 'lan'] +['б', 'ан'] +['ãĥ³', 'ãĥī'] +['à¸Ī', 'ี'] +['Ġ×Ķש', '׳×Ļ'] +['п', 'оÑĤ'] +['×ķ׾', '×Ļ×Ŀ'] +['ล', 'ัà¸ļ'] +['ĠÑį', 'ÑĤи'] +['×ij×§', 'ש'] +['ë¹Ħ', 'ìĬ¤'] +['à¸Ńยà¹Īาà¸ĩ', 'à¹Ħร'] +['×Ļ׾', '×Ļ'] +['à¹ĥà¸Ĭ', 'à¹Ī'] +['ĠاÙĦ', 'ÙĥÙĦ'] +['ãĥļ', 'ãĥ¼ãĤ¸'] +['ص', 'Ø©'] +['ÑĤи', 'ÑĢ'] +['ãĤĵ', 'ãģ©'] +['зÑĭ', 'к'] +['wy', 'ż'] +['Ùĩ', 'ÙĬ'] +['ĠÙħ', 'ÙĦÙĬ'] +['Ġвид', 'е'] +['ظ', 'اÙħ'] +['دا', 'ÙĪÙĦ'] +['×ŀ', 'ת×Ļ'] +['Ġs', 'ık'] +['à¹Ģà¸ķิ', 'ม'] +['ãĤ¢', 'ãĤ¤'] +['ка', 'Ñħ'] +['צ', '×Ļ׾'] +['à¹Ģà¸Ĭ', 'à¹Īà¸Ļ'] +['м', 'аг'] +['маг', 'аз'] +['магаз', 'ин'] +['à¸Ľ', 'ั'] +['à¸Ľà¸±', 'à¸Ī'] +['Ġש', '×Ļר×ķת'] +['ีย', 'ม'] +['ãĥĸ', 'ãĥ«'] +['Ġد', 'ÙĪÙĦ'] +['קר', '×Ļ×Ŀ'] +['Ùĩ', 'Ùı'] +['ов', 'о'] +['Ġü', 'ret'] +['د', 'ÙĪÙĨ'] +['à¹ģà¸Ļ', 'ว'] +['à¹Ģà¸Ļ', 'ืà¹īà¸Ń'] +['ĠÑĦ', 'оÑĤ'] +['ãĥ', 'ĺ'] +['ãģ¤', 'ãģĭ'] +['Ñı', 'Ñģ'] +['ĠíķĺëĤĺ', 'ëĭĺ'] +['ائ', 'ع'] +['Ġп', 'лаÑĤ'] +['ìĺ', 'Ī'] +['Ġdost', 'ÄĻp'] +['ÙĪØ¬', 'Ùĩ'] +['Ġ×Ķ', '×Ĺ×Ļ'] +['׳', '×Ļ×§'] +['д', 'ей'] +['í', 'ĽĦ'] +['ı', 'y'] +['بØŃ', 'ر'] +['à¹Ģส', 'ริม'] +['Ġ׾', '×Ĵ'] +['ذÙĩ', 'ب'] +['ج', 'ÙĬÙĦ'] +['رÙĥ', 'ز'] +['Ġë', 'ħ'] +['Ġëħ', '¸'] +['פ×Ļ׾', '×ķ'] +['ãģ¾', 'ãģļ'] +['iri', 'ÅŁ'] +['ĠÙĥ', 'ÙĬÙģ'] +['Ġ×ij', 'צ'] +['Ġêµ', 'IJ'] +['ÑĢоÑģ', 'Ñģ'] +['ĠØ´', 'ÙĬ'] +['Ġiç', 'er'] +['×Ĵ', '×ķ×ij×Ķ'] +['мен', 'но'] +['×¢', '×ij×Ļר'] +['×ķ×ŀ', '×Ķ'] +['ãĤī', 'ãģĹãģĦ'] +['ãģ', '¼'] +['Ñī', 'ин'] +['è²·', 'ãģĦ'] +['جÙħÙĪØ¹', 'Ø©'] +['Ġdön', 'em'] +['Ġ×ij', '×IJר'] +['в', 'еÑģÑĤ'] +['×ķר', '×ķת'] +['س', 'Ùģ'] +['à¹ģà¸Ĺ', 'à¸Ļ'] +['Ġд', 'окÑĥменÑĤ'] +['Ġا', 'ÙĬ'] +['ج', 'اÙĨ'] +['צ×ķ×¢', '×Ļ'] +['ĠоÑģ', 'об'] +['ĠاÙĦÙħ', 'س'] +['ÑĢаÐ', '±'] +['à¸ł', 'ู'] +['à¸Ķ', 'าว'] +['л', 'екÑĤ'] +['ع', 'ÙĤ'] +['×ķ×ĵ', '×ķת'] +['Ġol', 'u'] +['Ġolu', 'ÅŁtur'] +['ãģ¾', 'ãģ¾'] +['ед', 'ин'] +['à¹Ģ', 'à¸Ńà¸ģ'] +['ãĤµ', 'ãĤ¤'] +['ëĦ', 'Ī'] +['Ø·', 'ÙĨÙĬ'] +['Ø·', 'ÙĤØ©'] +['ĠÐł', 'аз'] +['ÙĦ', 'Ùij'] +['Ñĩ', 'ем'] +['Ġ׾', '×ĺ'] +['สั', 'à¹Īà¸ĩ'] +['سر', 'ائÙĬÙĦ'] +['Ġפר', '×ĺ×Ļ'] +['д', 'еÑģÑĮ'] +['Ġ׳', '׼'] +['اÙĨ', 'ب'] +['ÙĬا', 'Ø©'] +['Ùħ', 'بر'] +['Ġk', 'ı'] +['à¸Ľ', 'à¸ı'] +['à¸Ľà¸ı', 'ิ'] +['à¸ļั', 'à¸ķิ'] +['׳', 'ת×Ļ'] +['ìĨ', '¡'] +['ر', 'اب'] +['à¹ĥ', 'à¸ķ'] +['à¹ĥà¸ķ', 'à¹ī'] +['×Ļ׳', 'ת'] +['ÙĪ', 'ÙĬر'] +['Ġ×Ķ×ŀ', '×Ļ'] +['ей', 'ÑĩаÑģ'] +['×§', '×ķ×ij'] +['در', 'اس'] +['ĠÙħ', 'ÙĤ'] +['رÙĬ', 'ÙĨ'] +['Ø®', 'اص'] +['ãģĬ', 'éĩij'] +['Ġج', 'دا'] +['ãģĨ', 'ãģ¡'] +['ëħ', '¸'] +['ır', 'ım'] +['æ§', 'ĺ'] +['ãģ«', 'å¯'] +['ãģ«å¯', '¾'] +['ÑĨ', 'ев'] +['Ġv', 'ard'] +['ĠÐIJ', 'н'] +['e', 'ÄŁ'] +['ÑģÑĤв', 'енно'] +['Ð', '¨'] +['س', 'د'] +['à¸ģ', 'ุ'] +['à¹ģà¸ľ', 'à¸Ļ'] +['รูà¹ī', 'ส'] +['รูà¹īส', 'ึà¸ģ'] +['ات', 'ØŃاد'] +['Ñij', 'ÑĤ'] +['×Ĺ', '×ķ×§'] +['ãģĻ', 'ãģIJ'] +['Ø·', 'ÙĦاÙĤ'] +['Ġ×§', '×ķ×ĵ'] +['à¹ĥà¸Ĭ', 'à¹īà¸ĩ'] +['à¹ĥà¸Ĭà¹īà¸ĩ', 'าà¸Ļ'] +['ãĥ¼ãĤ', '¿'] +['Ġs', 'ür'] +['ÑĢ', 'ок'] +['ë³', 'ij'] +['สมา', 'à¸Ĭ'] +['สมาà¸Ĭ', 'ิà¸ģ'] +['ãĥķ', 'ãĥ¬'] +['è¾¼', 'ãģ¿'] +['ãĤ»', 'ãĥ³'] +['Ġê°Ģ', 'ì§Ģ'] +['à¸ľ', 'à¹īา'] +['ÑįÑĤ', 'омÑĥ'] +['иÑĤ', 'ел'] +['à¸ł', 'ั'] +['à¸', 'ij'] +['ãĥĸ', 'ãĥ©'] +['×Ľ×ª', '×ķ×ij'] +['׳', '×Ŀ'] +['ен', 'нÑĭе'] +['×¢', '×¨×Ľ×ª'] +['Ġì', 'Ĥ'] +['ĠìĤ', '´'] +['à¸Ĥ', 'à¹īา'] +['׳', '×ķס'] +['ãĥ¬', 'ãĥĵ'] +['ÑĢ', 'еÑģ'] +['à¹Ģล', 'à¸Ĥ'] +['Ø«', 'اÙĦ'] +['ìĹ', 'Ĩ'] +['ĠÑĩ', 'аÑģÑĤ'] +['า', 'ศ'] +['ãĥª', 'ãĤ¢'] +['u', 'ç'] +['×Ļ׼', '×ķת'] +['ล', 'à¹īาà¸Ļ'] +['i', 'ë'] +['ãĤ¸', 'ãĤ§'] +['à¸Ī', 'à¸Ń'] +['ÙĪ', 'ØŃد'] +['×Ļצ', '×ķ×ij'] +['Ġ×ij', 'ש׾'] +['ок', 'о'] +['ض', 'Ø©'] +['ذ', 'ر'] +['ĠÑĥ', 'д'] +['İ', 'L'] +['×ķצ', '×Ļ×Ŀ'] +['×ĸ', '×ŀף'] +['à¸Ľ', 'à¸ģ'] +['íķĻ', 'êµIJ'] +['س', 'اÙħ'] +['à¹Ħ', 'à¸Ķ'] +['ละ', 'à¹Ģà¸Ń'] +['ละà¹Ģà¸Ń', 'ีย'] +['ละà¹Ģà¸Ńีย', 'à¸Ķ'] +['ả', 'y'] +['аÑĨи', 'он'] +['ãĤ¹', 'ãĤ¯'] +['פ', '×ķס'] +['ร', 'à¹Īาà¸ĩ'] +['ен', 'нÑĭй'] +['ع', 'ÙĨ'] +['عÙĦ', 'ÙĨ'] +['ائ', 'Ùģ'] +['d', 'ÄĻ'] +['ؤ', 'ÙĪÙĦ'] +['׾×ķ', '×ķ'] +['Ġ×ij', 'ש×ij'] +['ä»Ĭ', 'åĽŀ'] +['ĠاÙĦج', 'ÙĨ'] +['د', 'اد'] +['wa', 'Äĩ'] +['ãĥª', 'ãĥ³'] +['ĠìŀIJ', 'ìĭł'] +['اÙĨ', 'ÙĬا'] +['ãĥ¡', 'ãĥª'] +['ÙĦ', 'ÙĪÙĨ'] +['à¸Ĺ', 'à¹Īà¸Ńà¸ĩ'] +['à¸Ĺà¹Īà¸Ńà¸ĩ', 'à¹Ģà¸Ĺีà¹Īยว'] +['اÙģ', 'ÙĬ'] +['Ġли', 'ÑĪ'] +['Ùħ', 'ÙĬØ©'] +['оÑĤ', 'веÑĤ'] +['Ñĩ', 'ин'] +['Ã', 'Ĭ'] +['ãĥ¡', 'ãĥ³'] +['å®', 'Ł'] +['éļĽ', 'ãģ«'] +['ĠÑĢаÐ', '¹'] +['ãĤ¦', 'ãĥ³'] +['×Ļר', '×ķש'] +['×Ļר×ķש', '׾×Ļ×Ŀ'] +['ม', 'ะ'] +['Ġar', 'a'] +['каз', 'аÑĤÑĮ'] +['à¸ķ', 'ัà¸Ķ'] +['ÑĥÑİ', 'ÑĤ'] +['Ġü', 'st'] +['×Ĵ', '×ķ×ij'] +['×Ĵ×ķ×ij', '×ķת'] +['mal', 'ı'] +['ег', 'од'] +['егод', 'нÑı'] +['اÙģ', 'ÙĤ'] +['à¸Ĭ', 'à¹Īà¸Ńà¸ĩ'] +['Ġö', 'zellik'] +['×Ļצ', '×ķר'] +['Ġmi', 'ÄĻd'] +['Ġili', 'ÅŁ'] +['Ġна', 'Ñħод'] +['×¢', '×ĸר'] +['׾', '×Ľ×ª'] +['ÙĨت', 'اج'] +['ĠÑģ', 'ем'] +['à¸Ī', 'à¹Īาย'] +['à¸ķร', 'ว'] +['à¸ķรว', 'à¸Ī'] +['פר', '×ķ'] +['à¸Ĥ', 'ัà¸ļ'] +['ãģ', 'ŀ'] +['Ġп', 'ло'] +['к', 'олÑĮ'] +['×ŀ×¢', '×ĺ'] +['íķĺ', 'ìĭľ'] +['jÄħ', 'ce'] +['ÙĨ', 'اÙĨ'] +['ลี', 'à¸ģ'] +['н', 'ÑĥÑĤ'] +['Ġоб', 'ÑĢаз'] +['Ùĥ', 'بر'] +['ĠاÙĦÙĪ', 'Ø·ÙĨ'] +['ãģķãģĽ', 'ãģ¦'] +['ÙĤ', 'اء'] +['×ŀ×ĵ', '×Ļ׳'] +['y', 'ü'] +['פ', '×Ļת'] +['׳', '×ķף'] +['ÙħÙĨ', 'ظ'] +['หà¸Ļ', 'ัà¸ģ'] +['ìŀ', 'Ī'] +['ãĤ«', 'ãĥ¼ãĥī'] +['ع', 'ÙĨÙĬ'] +['п', 'од'] +['ض', 'اء'] +['à¸Ļ', 'à¸ķà¹Į'] +['×ŀש', 'פ'] +['ว', 'à¹Į'] +['ר', '×ķ×§'] +['ส', 'ืà¹Īà¸Ń'] +['פק', '×Ļ×ĵ'] +['ãģªãĤī', 'ãģªãģĦ'] +['ĠìŬ', '룬'] +['ÙĦ', 'ج'] +['Ñī', 'иÑĤ'] +['ãĥĥ', 'ãĤ·'] +['ÙĦÙĬ', 'س'] +['ĠÙĦ', 'Ùħا'] +['ìł', 'ij'] +['×ij', '×Ļף'] +['ãĥģ', 'ãĤ§'] +['Ġgü', 'ç'] +['Ġch', 'ứ'] +['×ķצ', '×IJ'] +['קר', '×ij'] +['à¹Ĥ', 'à¸ŀ'] +['оÑĩ', 'но'] +['סק', '×Ļ'] +['ש׾', '×Ŀ'] +['صر', 'Ùģ'] +['ĠL', 'Ãł'] +['×¢', '×Ļת'] +['á»', '·'] +['à¹Ĥ', 'à¸Ńà¸ģ'] +['à¹Ĥà¸Ńà¸ģ', 'า'] +['à¹Ĥà¸Ńà¸ģา', 'ส'] +['Ġ×Ķ', '×ĵ×ijר'] +['à¸Ļั', 'à¹Īà¸Ļ'] +['ز', 'ر'] +['нак', 'о'] +['íļ', 'į'] +['ãĤĤ', 'ãģ¡'] +['ãĤĤãģ¡', 'ãĤį'] +['ãĤĤãģ¡ãĤį', 'ãĤĵ'] +['اÙħ', 'ت'] +['عد', 'اد'] +['и', 'нÑĭ'] +['ÅĤy', 'w'] +['à¸Ħ', 'à¸ĵะ'] +['à¸Ĺ', 'ะ'] +['kt', 'ör'] +['×Ļ×Ĺ', '×Ķ'] +['Ġм', 'е'] +['Ġме', 'ÑģÑı'] +['׳×Ķ', '×Ĵ'] +['ĠÑģ', 'ÑĥÑīеÑģÑĤв'] +['à¸Ļ', 'ัà¸Ļ'] +['ÑĦ', 'ÑĦ'] +['ек', 'ÑĤив'] +['عÙĦÙĪÙħ', 'ات'] +['б', 'Ñĥд'] +['à¸Ļัà¸ģ', 'à¸ĩาà¸Ļ'] +['หà¸Ļà¹īา', 'à¸Ĺีà¹Ī'] +['ÙĤÙĬ', 'ÙĤ'] +['ãĤ·', 'ãĥ³'] +['ãģ«', 'éĸ¢'] +['×IJר', '×Ĵ'] +['ĠпÑĢ', 'оÑĤ'] +['ĠпÑĢоÑĤ', 'ив'] +['ĠìŀĪ', 'ìĸ´'] +['ÙĤÙĬ', 'ÙĤØ©'] +['ìĹ', 'ĩ'] +['k', 'ür'] +['ãģ«ãģªãĤĬ', 'ãģ¾ãģĹãģŁ'] +['Ġде', 'ÑıÑĤ'] +['ĠдеÑıÑĤ', 'елÑĮ'] +['פ×ķר', '×ĺ'] +['à¸Ł', 'à¹īา'] +['à¹Ģ', 'à¸ł'] +['ĠавÑĤом', 'аÑĤ'] +['×ĸ', '×Ļ×§'] +['Ġold', 'uk'] +['ع', 'اÙħ'] +['ĠÑĤ', 'оÑĢ'] +['yrı', 'ca'] +['ê', 'Ì'] +['ãĤŃ', 'ãĥ³ãĤ°'] +['ãģ«', 'ãģ¨ãģ£ãģ¦'] +['à¹Ģà¸ī', 'à¸ŀ'] +['à¹Ģà¸īà¸ŀ', 'าะ'] +['ãģ¯', 'ãģļ'] +['×ŀ', '×IJ×Ļ'] +['สะ', 'à¸Ķ'] +['สะà¸Ķ', 'วà¸ģ'] +['ìľ¼', 'ë©°'] +['à¸ģ', 'ี'] +['à¸', '¬'] +['Ġ×¢', '×ķש'] +['à¸łà¸²', 'ษา'] +['à¸Ĺ', 'ัà¸Ļ'] +['ac', 'akt'] +['acakt', 'ır'] +['اع', 'دة'] +['ĠÑĥÑģл', 'Ñĥг'] +['ס', 'ר×ĺ'] +['×ķ×ŀ', '×ķת'] +['×Ķ', '×ķר'] +['×ŀ', '×ķ×ij'] +['×ŀ×ķ×ij', 'ף'] +['سÙĬ', 'اس'] +['اتÙģ', 'اÙĤ'] +['×Ķ', 'צ׾'] +['Ùħؤ', 'س'] +['Ġp', 'ó'] +['Ġк', 'ни'] +['×Ļ׼', '×ķ׾'] +['à¹Ģหล', 'ืà¸Ń'] +['׼׾', '׼'] +['׳', '×ĸ'] +['ÑĪи', 'е'] +['r', 'ès'] +['ĠاÙĦØŃ', 'ÙĤ'] +['лÑı', 'ÑĢ'] +['ห', 'à¸į'] +['หà¸į', 'ิà¸ĩ'] +['ר×Ĵ', '×Ļש'] +['à¹Ģส', 'à¹īà¸Ļ'] +['ש×ij', '×ķף'] +['ô', 'tel'] +['ап', 'ÑĢ'] +['апÑĢ', 'имеÑĢ'] +['اب', 'ÙĦ'] +['ĠÑĢаз', 'виÑĤ'] +['Ġп', 'олÑĮз'] +['ĠС', 'еÑĢ'] +['×ķ×ij', '×Ļ'] +['r', 'óż'] +['ìĭ', 'Ń'] +['ãĤ¯', 'ãĥĪ'] +['ãģĹ', 'ãĤĪãģĨ'] +['à¸ģร', 'ม'] +['ØŃ', 'ÙĥÙĪÙħ'] +['à¹Ĥ', 'à¸ļ'] +['à¸Ĺ', 'à¹īาย'] +['ĠM', 'á'] +['ĠÑĤ', 'Ñĭ'] +['à¸Ħร', 'ัว'] +['ÑĢÑĥ', 'б'] +['ạ', 'p'] +['Ġm', 'ÅĤ'] +['ĠmÅĤ', 'od'] +['Ġgör', 'Ã¼ÅŁ'] +['Ġgeli', 'ÅŁ'] +['ươ', 'i'] +['×ŀש', '×§'] +['ÙĢÙĢ', 'ÙĢÙĢ'] +['รา', 'ว'] +['ãģĹãģ', '£'] +['ãģĹãģ£', 'ãģĭãĤĬ'] +['ĠÐļ', 'он'] +['Ġk', 'ê'] +['à¹Ĥà¸Ĺ', 'ร'] +['èIJ½', 'ãģ¡'] +['åĩº', 'ãģ¦'] +['ล', 'ัà¸ģษ'] +['Ġ×Ĵ', '×ij×ķ×Ķ'] +['ãĥĻ', 'ãĥ«'] +['ê±°', 'ëĤĺ'] +['ë§', 'IJ'] +['×Ļ׾', '×ĵ×Ļ×Ŀ'] +['ĠëĦ', 'Ī'] +['×ŀר', '×Ļ'] +['ร', 'ส'] +['ãĥŃ', 'ãĥ³'] +['и', 'ло'] +['ноÑģÑĤÑĮ', 'Ñİ'] +['×ĸר', '×Ĺ'] +['п', 'он'] +['Ġ×Ķש', '׾'] +['ê²ł', 'ìĬµëĭĪëĭ¤'] +['Ġki', 'ÅŁ'] +['ĠÐļ', 'и'] +['ว', 'ร'] +['د', 'اع'] +['ÅŁ', 'im'] +['ÙĨ', 'Ùij'] +['в', 'аÑĤ'] +['را', 'Ùĥ'] +['ب', 'اÙĦ'] +['ид', 'е'] +['Ġ×Ķ×ŀ', '×Ĺ'] +['ìĸ', 'µ'] +['تÙģ', 'اع'] +['Ø£', 'ت'] +['ëĬ', 'ĺ'] +['ש', '×Ļת'] +['ست', 'Ùħر'] +['ĠÑĦ', 'ак'] +['ĠاÙĦØ£Ùħ', 'رÙĬ'] +['ëŀ', '¨'] +['اس', 'Ùħ'] +['Ġa', 'ÄŁ'] +['Ġç', 'ev'] +['Ùĥ', 'ÙĪØ±'] +['ãģķ', 'ãģ¾'] +['Ġç', 'öz'] +['Ġر', 'س'] +['Äħ', 'da'] +['สà¸Ļ', 'ุ'] +['ãģĹãģ¦', 'ãģıãĤĮ'] +['н', 'Ñİ'] +['leÅŁ', 'me'] +['ãĤª', 'ãĥ³'] +['ãģ¨', 'ãģªãĤĬ'] +['ava', 'ÅŁ'] +['×ĺ', '×Ļ×ij'] +['ØŃ', 'ض'] +['×ķצ', '×IJ×ķת'] +['ÙĨ', 'ÙħÙĪ'] +['ı', 't'] +['ĠÑħ', 'а'] +['ĠÑħа', 'ÑĢак'] +['ĠÑħаÑĢак', 'ÑĤеÑĢ'] +['Ġd', 'ÅĤ'] +['ãĥĹ', 'ãĥ©'] +['à¸Ĭ', 'ุม'] +['à¹Ī', 'à¸Ńà¸Ļ'] +['×ķ×ij', '׾'] +['Ñģ', 'ол'] +['×ĵ', '×Ĵ'] +['аÑĢ', 'аÑĤ'] +['n', 'ivers'] +['Ġgerçek', 'leÅŁtir'] +['ĠاÙĦ', 'ÙĦÙĬ'] +['ระ', 'ยะ'] +['ĠÙħ', 'ختÙĦÙģ'] +['Ġgö', 'nder'] +['Ùģ', 'ار'] +['do', 'ÄŁ'] +['doÄŁ', 'an'] +['ص', 'ÙĦاØŃ'] +['Ġyay', 'ın'] +['ãĥĨ', 'ãĥ³'] +['รว', 'à¸Ī'] +['×Ļ×Ĺ', '×Ļ×ĵ'] +['ünk', 'ü'] +['ÑĨи', 'алÑĮн'] +['à¸ļ', 'ู'] +['ม', 'ุ'] +['h', 'ä'] +['Ø®', 'Ùģ'] +['å¢', 'Ĺ'] +['å¢Ĺ', 'ãģĪ'] +['еÑĩ', 'но'] +['ĠاÙĦس', 'ÙĨ'] +['à¸Ĥ', 'าว'] +['im', 'di'] +['Ð', '«'] +['à¸Ļà¸Ńà¸ģ', 'à¸Īาà¸ģ'] +['à¸ļา', 'ล'] +['ת', 'ש'] +['Ġdüzen', 'le'] +['мÑĭ', 'Ñģл'] +['ãģı', 'ãģª'] +['ż', 'u'] +['Ġwsp', 'óÅĤ'] +['Ġн', 'аз'] +['ınd', 'aki'] +['تر', 'Ø©'] +['ÅŁ', 'ek'] +['Ġö', 'd'] +['ĠÙĪ', 'Ùĥ'] +['Ġпозв', 'олÑı'] +['Ġת', '×ķ׼'] +['ÙħÙĨ', 'تج'] +['ë§', 'ī'] +['ĠاÙĦØ«', 'ÙĦاث'] +['аÑĨи', 'Ñİ'] +['ÙĪØ±', 'ÙĪ'] +['Ñĭв', 'аеÑĤ'] +['خص', 'ص'] +['ĠاÙĦÙģ', 'ÙĦ'] +['ĠاÙĦÙģÙĦ', 'سطÙĬÙĨ'] +['Ø¥', 'جر'] +['إجر', 'اء'] +['اÙĨت', 'Ø®'] +['اÙĨتخ', 'اب'] +['ار', 'ÙĬØ©'] +['×ķ', 'Ö'] +['Ø¢', 'ÙĨ'] +['×ŀ×¢', '×ķת'] +['Ġм', 'ал'] +['Ġ×IJ', '×Ĺ'] +['à¸Ĺ', 'à¹īà¸Ńà¸ĩ'] +['ze', 'ÅĽ'] +['Ġë§Į', 'ëĵ¤'] +['رÙĬ', 'ع'] +['äºĭ', 'ãĤĴ'] +['à¸ļริ', 'หาร'] +['׾', '×ŀ×Ļ×ĵ'] +['Ġм', 'Ñĥж'] +['ت', 'رÙĪ'] +['ĠباÙĦ', 'Ø¥'] +['פ', '×Ļ×§'] +['ز', 'ÙħØ©'] +['ĠÃ¶ÄŁ', 'renc'] +['ãĥ', '¶'] +['اÙħ', 'عة'] +['×§×ij', '×ķצ'] +['×ŀ', '׳×ķת'] +['رÙĬ', 'Ùħ'] +['Ġо', 'каз'] +['ãģłãģij', 'ãģ©'] +['Ġh', 'ız'] +['Ġש', '×IJת'] +['ãĤ¢', 'ãĥ¼'] +['Ġmożli', 'wo'] +['ìĦ', '¼'] +['ÙĪ', 'اب'] +['ог', 'ÑĢаÑĦ'] +['Ġعبد', 'اÙĦ'] +['ãĤĴ', 'è¡Į'] +['ب', 'ÙĬÙĦ'] +['Ġİ', 'ç'] +['ย', 'าย'] +['ĠÑĥ', 'ÑĩаÑģÑĤ'] +['ÑĦ', 'еÑģÑģ'] +['ÑĦеÑģÑģ', 'иона'] +['áº', '¤'] +['ÙĨ', 'ÙĬÙĨ'] +['عد', 'ÙĦ'] +['สร', 'ร'] +['دÙĬ', 'ÙĦ'] +['×ij', '×Ļ×§'] +['czy', 'ÅĤ'] +['ÑĢом', 'е'] +['Ġм', 'ед'] +['ìĻ', 'Ķ'] +['ãĥ©', 'ãĤ¤ãĥ³'] +['ĠÑĤ', 'еп'] +['еÑĢ', 'ÑĮ'] +['i', 'ÄŁi'] +['в', 'ели'] +['ÑĢи', 'ÑģÑĤ'] +['ס', '×ķפ'] +['×ŀ׾', '×Ĺ'] +['ĠاÙĦØ¥', 'ÙĨ'] +['Ġ׾×Ķ', 'ש'] +['è¶Ĭ', 'ãģĹ'] +['ĠÑĢ', 'Ñĭ'] +['×ķ×IJ', 'ר'] +['رÙĩ', 'اب'] +['פ', '×ķ×IJ×Ļ'] +['ĠгоÑģ', 'Ñĥд'] +['ĠгоÑģÑĥд', 'аÑĢ'] +['ĠгоÑģÑĥдаÑĢ', 'ÑģÑĤв'] +['ĠاÙĦØ£Ùħ', 'ÙĬر'] +['Ùħ', 'ج'] +['à¹Ģหม', 'าะ'] +['ÑĢ', 'ев'] +['à¸Ĭี', 'à¸ŀ'] +['ãĥķ', 'ãĥĪ'] +['иÑĩ', 'но'] +['ĠاÙĦÙħ', 'ؤ'] +['Ġi', 'ht'] +['íħ', 'ľ'] +['د', 'ÙĨÙĬ'] +['ر', 'ص'] +['ла', 'ÑģÑĤ'] +['à¹Ģหล', 'à¹Īา'] +['ılı', 'r'] +['ร', 'à¸ĵà¹Į'] +['×ŀש', '×Ļ×ļ'] +['Ġd', 'á»ĭ'] +['Ø·Ùģ', 'اÙĦ'] +['×ĺ', '×ķף'] +['Ġ×ij', '×Ļ׳'] +['ãģ¾', 'ãģ£ãģŁ'] +['лож', 'ениÑı'] +['تØŃ', 'ر'] +['ب', 'اØŃ'] +['à¹Ģส', 'ืà¹īà¸Ń'] +['ãģĻ', 'ãģĶ'] +['lt', 'ür'] +['à¸ĩ', 'าม'] +['Ġt', 'ü'] +['ĠпÑĢ', 'им'] +['ĠпÑĢим', 'ен'] +['Ġhay', 'at'] +['ëĥ', 'IJ'] +['ëĭ', 'Į'] +['׳×Ļ', '×ķ'] +['вед', 'ен'] +['ìħ', '¨'] +['à¸Ī', 'ัย'] +['à¸ģà¹Ī', 'à¸Ń'] +['Ġв', 'од'] +['оÑģÑĤ', 'оÑı'] +['н', 'аÑĤ'] +['à¹ģ', 'หล'] +['سÙħ', 'ÙĬ'] +['à¸Ķำ', 'à¹Ģà¸Ļ'] +['à¸Ķำà¹Ģà¸Ļ', 'ิà¸Ļ'] +['w', 'ód'] +['ö', 'yle'] +['ãĥĢ', 'ãĤ¤'] +['ÑĪи', 'й'] +['меÑī', 'ен'] +['ãģĹãģ¾', 'ãģĨ'] +['ãĥī', 'ãĥ©'] +['ÙĪØ¶', 'ØŃ'] +['à¸Ńà¸Ļ', 'ุ'] +['ĠاÙĦ', 'اجتÙħاع'] +['laÅŁ', 'ma'] +['à¸Ħ', 'à¸Ńà¸Ļ'] +['×ŀר', '×Ļ×Ŀ'] +['ÙĨ', 'اÙħج'] +['שר', '×ķת'] +['اÙĦ', 'Ø£'] +['Ġksi', 'Äħż'] +['Ġа', 'н'] +['ÑĢаÐ', '¹'] +['اÙĩر', 'Ø©'] +['×ŀ×ĵ', '×Ķ'] +['ä¸Ģ', 'ç·'] +['ä¸Ģç·', 'Ĵ'] +['ä¸Ģç·Ĵ', 'ãģ«'] +['ÑĢиÑĤ', 'оÑĢ'] +['d', 'ıkl'] +['à¹ģ', 'à¸ĸ'] +['à¹ģà¸Ĥ', 'à¹Īà¸ĩ'] +['екÑĤ', 'оÑĢ'] +['×ŀס', '×¢'] +['ÑĢак', 'ÑĤи'] +['u', 'ÄŁu'] +['×ķ×ij', 'ת'] +['สู', 'à¸ķร'] +['ĠçalÄ±ÅŁ', 'm'] +['ĠçalÄ±ÅŁm', 'alar'] +['Ġа', 'на'] +['ãĥĽ', 'ãĥ¼ãĥł'] +['Ġböl', 'üm'] +['Ġب', 'ص'] +['ол', 'оÑģ'] +['ĠìķĬ', 'ëĬĶ'] +['à¹Ī', 'ะ'] +['ÙĪ', 'تر'] +['ä¹', 'Ĺ'] +['ست', 'خداÙħ'] +['פ×Ļ', '×Ļס'] +['פ×Ļ×Ļס', '×ij'] +['פ×Ļ×Ļס×ij', '×ķ×§'] +['Ġк', 'ÑĢаÑģ'] +['ли', 'к'] +['رÙĬ', 'ØŃ'] +['×ŀש', '׾×Ķ'] +['à¹Ģย', 'ีà¹Īย'] +['à¹Ģยีà¹Īย', 'ม'] +['в', 'иÑģ'] +['ом', 'н'] +['ÄŁ', 'un'] +['ãĥŃ', 'ãĥ¼ãĥ³'] +['Ø£', 'تÙĬ'] +['à¸ķร', 'ี'] +['çͳ', 'ãģĹ'] +['تÙħ', 'ر'] +['ìĹ', 'ĪìĬµëĭĪëĭ¤'] +['ĠÙĪ', 'غÙĬر'] +['red', 'ni'] +['ĠاÙĦص', 'Ùģ'] +['Ġна', 'ÑģÑĤоÑı'] +['ĠнаÑģÑĤоÑı', 'Ñī'] +['à¸ķ', 'รา'] +['ĠÑĥÑģл', 'ов'] +['ĠÑĥÑģлов', 'иÑı'] +['ÑĨ', 'еп'] +['×Ķ', '×Ĺ׾×ĺ'] +['Ø·', 'ÙĬع'] +['ĠB', 'akan'] +['ĠاÙĦ', 'رÙĪ'] +['илÑĮ', 'но'] +['Ġм', 'еÑĤ'] +['à¸Ķ', 'à¸Ńà¸ģ'] +['ãģĭãĤī', 'ãģªãģĦ'] +['Ġпо', 'ÑģÑĤоÑı'] +['ĠпоÑģÑĤоÑı', 'н'] +['ĠÑĩ', 'аÑģ'] +['ü', 'c'] +['wr', 'ó'] +['б', 'ÑĥÑĢ'] +['ãĥIJ', 'ãĥĥãĤ¯'] +['ãĥ©ãĥ³', 'ãĥī'] +['Ġо', 'гÑĢ'] +['สั', 'à¸į'] +['สัà¸į', 'à¸įา'] +['มั', 'à¹Īà¸Ļ'] +['à¸Ħ', 'à¸Ńม'] +['al', 'ık'] +['Ġн', 'ед'] +['üm', 'üz'] +['ĠÅĽ', 'wie'] +['é', 'rio'] +['×Ļ×IJ', '×Ķ'] +['دÙħ', 'ات'] +['ı', 'rl'] +['ĠоÑĤ', 'з'] +['ĠоÑĤз', 'Ñĭв'] +['ä»ĺ', 'ãģį'] +['Ġkaż', 'de'] +['мин', 'иÑģÑĤ'] +['ãĤ°', 'ãĥ«'] +['ë°', 'ĸ'] +['ез', 'н'] +['اÙĦ', 'Ùģ'] +['Ġש', 'ק׾'] +['Ùħ', 'ض'] +['ãĥĿ', 'ãĥ¼ãĥĪ'] +['ÙħÙĨ', 'ت'] +['ÙĤÙĬ', 'اÙħ'] +['Ø´', 'ÙĨ'] +['×Ļר', '×ķ×¢'] +['ãĤŃãĥ£', 'ãĥ³'] +['доÑĢ', 'ов'] +['×ŀ', '×Ļת×Ļ'] +['ÙĪÙĦ', 'ÙĪØ¬'] +['Ùĥ', 'اÙģ'] +['ĠÑĢаз', 'лиÑĩ'] +['иÑĤ', 'еÑĤ'] +['н', 'олог'] +['ลà¸ĩ', 'à¸Ĺุà¸Ļ'] +['Ġyak', 'laÅŁ'] +['ãĥ¬', 'ãĤ¤'] +['ê²ł', 'ëĭ¤'] +['æ±Ĥ', 'ãĤģ'] +['رÙĪ', 'Ùģ'] +['Ġí', 'Ĭ'] +['ĠíĬ', '¹'] +['ãģ£', 'ãģıãĤĬ'] +['à¸Ħวาม', 'à¸Ħิà¸Ķ'] +['×Ķ', '×Ļס×ĺ'] +['Ø¥', 'ÙĤ'] +['ãģ¦', 'ãģĦ'] +['à¹Ĥ', 'à¸Ĭ'] +['ĠBü', 'yük'] +['ĠФ', 'едеÑĢ'] +['ÑĨи', 'н'] +['ÑĢов', 'а'] +['ĠاÙĦ', 'اÙĤتصاد'] +['Ġch', 'á'] +['à¸ĺ', 'าà¸Ļ'] +['ë¥', 'ł'] +['à¹Ħ', 'à¸ķ'] +['ÃŃ', 'pio'] +['Ùĭ', 'ا'] +['Ġоб', 'Ñıз'] +['Ùĩ', 'ج'] +['Ġì¤ij', 'ìļĶ'] +['ãģ®', 'ãģ§ãģ¯ãģªãģĦ'] +['بار', 'اة'] +['ãĤ¤', 'ãĥ«'] +['Ġн', 'оÑĢм'] +['á»ī', 'nh'] +['m', 'ö'] +['mö', 'glich'] +['ÑĨи', 'п'] +['ãĤ¢', 'ãĤ¯'] +['×Ķ', '×Ļ'] +['ÑĨи', 'алÑĮно'] +['ĠÅĽ', 'wi'] +['ت', 'ÙĤ'] +['ĠÑģÑĤо', 'им'] +['بÙĬ', 'عÙĬ'] +['Ġ׾', 'ש×ŀ'] +['г', 'лÑı'] +['глÑı', 'д'] +['ãģ¦', 'ãģıãĤĮ'] +['ÄĻd', 'zi'] +['à¸Ĥ', 'ั'] +['à¸Ĥั', 'à¹īà¸Ļ'] +['Ø·', 'ÙĤ'] +['ĠìĹ', 'Ń'] +['ãģ£ãģ¦ãģĹãģ¾', 'ãģĨ'] +['ĠdeÄŁer', 'l'] +['ĠdeÄŁerl', 'endir'] +['Ġü', 'lk'] +['Ġмн', 'ог'] +['à¹', 'ĭ'] +['ë¿', 'IJ'] +['ĠУ', 'кÑĢа'] +['ÄŁ', 'ini'] +['Ġбез', 'оп'] +['Ġбезоп', 'аÑģ'] +['à¸Ńà¸Ńà¸ģ', 'à¹ģà¸ļà¸ļ'] +['اØ', '¸'] +['ØŃد', 'اث'] +['л', 'еÑĢ'] +['×Ļ×', '¥'] +['×Ļ׳×ĺר', '׳×ĺ'] +['lar', 'ınız'] +['ØŃÙĬ', 'ØŃ'] +['ż', 'eli'] +['à¸Ń', 'ัà¸ĩ'] +['à¸Ńัà¸ĩ', 'à¸ģ'] +['à¸Ńัà¸ĩà¸ģ', 'ฤษ'] +['ĠоÑĤ', 'лиÑĩ'] +['ั', 'ส'] +['ëŀ', 'į'] +['ож', 'но'] +['ãĤ¹', 'ãĥĿ'] +['ĠÑħ', 'оÑĩ'] +['Ġк', 'ап'] +['еÑĩ', 'ен'] +['ØŃÙĦ', 'Ø©'] +['ÙĬا', 'Ùĩ'] +['на', 'л'] +['×ķצ', 'ר×Ļ×Ŀ'] +['Ġk', 'ald'] +['åĥ', 'į'] +['ĠاÙĦØ´', 'خص'] +['Ġз', 'на'] +['Ġwz', 'gl'] +['ż', 'ycz'] +['ê°', 'Ŀ'] +['à¸ŀ', 'ลัà¸ĩ'] +['íģ', '¼'] +['Ġö', 'l'] +['Ġb', 'ụ'] +['Ø´', 'Ùĩر'] +['Ġз', 'ам'] +['Ġд', 'ев'] +['×Ļ×ĺ', 'ת'] +['تعÙĦ', 'ÙĤ'] +['ÙĪÙħ', 'Ø©'] +['ãĤĴ', 'ä½ľ'] +['ãģį', 'ãģ¦'] +['í', 'ĥĿ'] +['ras', 'ında'] +['ãĤĴ', 'æİ¢'] +['ĠÙħ', 'باشر'] +['راج', 'ع'] +['Ġв', 'озд'] +['ÙħØŃ', 'ا'] +['×ķש', 'ר'] +['ĠиÑģÑĤ', 'оÑĢ'] +['ม', 'ัà¸ģ'] +['t', 'ıģ'] +['Ø«', 'ار'] +['تر', 'ÙĨت'] +['à¹ģà¸Ĥ', 'à¹ĩ'] +['à¹ģà¸Ĥà¹ĩ', 'à¸ĩ'] +['п', 'оÑĩ'] +['Ġ×ij', '×IJ×ķת'] +['ë¯', 'Ģ'] +['ëĿ¼', 'ëıĦ'] +['à¸Ĭ', 'ัà¸Ķ'] +['ส', 'à¸ķà¹Į'] +['ãĥĭ', 'ãĥĥãĤ¯'] +['ид', 'енÑĤ'] +['Ġг', 'ÑĢÑĥпп'] +['ت', 'Ø®'] +['áº', 'ł'] +['ย', 'ืà¸Ļ'] +['ย', 'ัà¸Ļ'] +['ó', 'ry'] +['T', 'Ãľ'] +['ãģĹ', 'ãĤĥ'] +['ĠпÑĢов', 'ед'] +['лÑı', 'еÑĤ'] +['Ùħ', 'Ø®'] +['ย', 'à¸Ńม'] +['×Ľ×ł×¡', 'ת'] +['ĠاÙĦÙħ', 'ÙĨت'] +['Ġol', 'mad'] +['ר׼', '×ĸ×Ļ'] +['Ġв', 'ÑģÑĤÑĢ'] +['ĠиÑģ', 'Ñģлед'] +['ÑĤвеÑĢ', 'ж'] +['بد', 'ÙĪ'] +['еÑĢ', 'ÑĤ'] +['ï»', '·'] +['±', 'ħ'] +['สัม', 'à¸ŀัà¸Ļà¸ĺà¹Į'] +['ิ', 'à¹Īà¸Ļ'] +['צ', '×Ļ×ij'] +['wiÄĻ', 't'] +['Ġì°', '¸'] +['Ġz', 'wiÄħz'] +['سب', 'ÙĪØ¹'] +['ãĥĥ', 'ãĤ°'] +['à¸Ľà¸¥', 'à¸Ńà¸Ķ'] +['à¸Ľà¸¥à¸Ńà¸Ķ', 'à¸łà¸±à¸¢'] +['ãĤĤ', 'ãĤĬ'] +['ÙĤد', 'س'] +['Ġspr', 'z'] +['Ġsprz', 'eda'] +['Ġist', 'edi'] +['Ġk', 'hu'] +['Ġд', 'ен'] +['Ġko', 'ÅĦ'] +['Ġ×ij', '×Ĺ×Ļ'] +['à¹Ģà¸Ĺ', 'à¹īา'] +['×ķס', '×Ļ×£'] +['ãĥĭ', 'ãĥ¥ãĥ¼'] +['ĠпÑĢед', 'оÑģÑĤ'] +['ĠпÑĢедоÑģÑĤ', 'ав'] +['à¹Ĥ', 'à¸Ł'] +['é', 'v'] +['ĠاÙĦص', 'ØŃ'] +['صØŃ', 'اب'] +['à¹Ģà¸Ī', 'à¹ĩà¸ļ'] +['вл', 'ек'] +['วั', 'à¸ķ'] +['à¸ĸ', 'ุ'] +['ãģĵãģ¨ãģĮãģ§ãģį', 'ãģ¾ãģĻ'] +['ÙĤÙĬ', 'ÙĤÙĬ'] +['×ķ×Ĺ', 'ר'] +['Ñĭ', 'ÑĪ'] +['ĠоÑĤ', 'но'] +['ĠоÑĤно', 'ÑĪ'] +['об', 'илÑĮ'] +['Ùģ', 'ØŃ'] +['ı', 'nt'] +['ınt', 'ı'] +['Ġ׾', '×ij×ĵ'] +['í', 'İĺìĿ´ì§Ģ'] +['ãĥĬ', 'ãĥ«'] +['ĠÙħ', 'ساء'] +['×Ļ×ĺ', '×ij'] +['ÑĮ', 'еÑĢ'] +['ëĦ', '·'] +['Ñĭ', 'ÑĤа'] +['ĠоÑĩ', 'еÑĢ'] +['à¸Ķ', 'ืà¹Ī'] +['à¸Ķืà¹Ī', 'ม'] +['ĠN', 'gh'] +['ت', 'عب'] +['ÙĦاÙĤ', 'ات'] +['×ķ׾×ķ×Ĵ', '×Ļ×Ķ'] +['ĠìĿ´', 'ê²ĥ'] +['Ġ×Ķ', '×ijר'] +['ìľ', 'µ'] +['à¹Ģà¸Ħล', 'ืà¹Īà¸Ńà¸Ļ'] +['Ùĩ', 'Ø©'] +['à¸Īำ', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['å¤ī', 'ãģĪ'] +['wi', 'ÅĽcie'] +['ch', 'od'] +['chod', 'zÄħ'] +['в', 'ÑĢо'] +['×ŀ×Ĺ', '×Ļר'] +['Ġy', 'ı'] +['Ġyı', 'll'] +['ì¡', 'Į'] +['à¹Ħ', 'หว'] +['ãģªãģı', 'ãģª'] +['Ġзав', 'иÑģ'] +['ĠìĺĪ', 'ìĪĺ'] +['Ùģ', 'ذ'] +['á»§', 'ng'] +['à¸ŀุ', 'à¸Ĺà¸ĺ'] +['з', 'н'] +['lay', 'an'] +['ãĤ', '¡'] +['à¸ģà¹ĩ', 'à¸ķาม'] +['ĠsaÄŁ', 'lam'] +['ร', 'à¸ĵ'] +['ĠÑģ', 'иÑĤ'] +['ĠÑģиÑĤ', 'Ñĥ'] +['ĠاÙĦت', 'ÙĨ'] +['×Ķ', '×ĸ'] +['ĠØ·', 'ÙĪÙĬÙĦ'] +['ta', 'ÅĤ'] +['Ġgö', 'rd'] +['å¤ī', 'ãĤı'] +['ëĥ', '¥'] +['à¸Ħà¹Ī', 'à¸Ńย'] +['×IJ', '×ķ×ĺ'] +['ëħ', 'IJ'] +['ãĥ©ãĥ³', 'ãĤ¹'] +['วั', 'à¸Ĵ'] +['วัà¸Ĵ', 'à¸Ļ'] +['Ġol', 'uÅŁ'] +['פע', '×ķ׾'] +['Ġszczeg', 'óÅĤ'] +['à¸Ħา', 'สิ'] +['à¸Ħาสิ', 'à¹Ĥà¸Ļ'] +['pow', 'ied'] +['ĠÑĤ', 'еб'] +['หà¸Ļ', 'à¹Īวย'] +['Ġм', 'ил'] +['ØŃ', 'Ùĥ'] +['à¸Ĺ', 'à¸Ķ'] +['ĠмаÑĤ', 'еÑĢиал'] +['ÅĤ', 'ow'] +['à¹Ģà¸ģ', 'ีย'] +['ĠÑģов', 'еÑĢ'] +['ãĤ', '©'] +['à¸Ľ', 'ริ'] +['Ġи', 'Ñİ'] +['наÑĩ', 'ен'] +['ÑĢен', 'д'] +['mu', 'ÅŁtur'] +['ĠпÑĢод', 'Ñĥк'] +['з', 'д'] +['Ñı', 'ÑĤи'] +['ÑıÑĤи', 'Ñı'] +['à¹Ģม', 'ีย'] +['رات', 'ÙĬج'] +['Ġam', 'acı'] +['ש', '×ķ׾'] +['ש×ķ׾', '×Ĺ'] +['สะ', 'à¸Ńา'] +['สะà¸Ńา', 'à¸Ķ'] +['פ×Ĵ', '×¢'] +['عب', 'Ø©'] +['d', 'ın'] +['íħ', 'Ķ'] +['Ġ×ŀש', '×Ĺ×§'] +['Ġfi', 'yat'] +['Ġз', 'аÑı'] +['ĠзаÑı', 'в'] +['à¹Ĥ', 'หล'] +['à¹Ĥหล', 'à¸Ķ'] +['à¸ģรุà¸ĩ', 'à¹Ģà¸Ĺà¸ŀ'] +['צ×Ļ', '×Ļף'] +['ìļ', '±'] +['Ùħ', 'ب'] +['Ùħب', 'اد'] +['land', 'ır'] +['Ġв', 'еÑģÑĮ'] +['Ġh', 'ük'] +['ĠÐĴ', 'оз'] +['ÑĩиÑĤ', 'Ñĭва'] +['ว', 'ล'] +['×ķצ', '×¢'] +['à¸Ĥà¸ĵะ', 'à¸Ĺีà¹Ī'] +['ĠaÅŁ', 'aģı'] +['׾×IJ', '×ķ×ŀ×Ļ'] +['tr', 'zym'] +['Ã¤ÃŁ', 'ig'] +['owo', 'ÅĽci'] +['ãģĿ', 'ãĤĤ'] +['Ġroz', 'wiÄħz'] +['ĠgÅĤ', 'ówn'] +['м', 'онÑĤ'] +['×ŀ', '×ķ×ŀ'] +['ĠÑģÑĤ', 'ан'] +['ÙĦا', 'ÙĤØ©'] +['p', 'rowad'] +['prowad', 'zi'] +['ĠÑģоÑģÑĤ', 'оÑı'] +['×Ļ×IJ', '×ķת'] +['r', 'ı'] +['g', 'ı'] +['ãĥij', 'ãĥij'] +['Ġна', 'лиÑĩ'] +['×Ķ', 'צע'] +['Ġ׳', '×Ķ'] +['à¸Ħ', 'ัà¸ļ'] +['ع', 'راض'] +['и', 'ж'] +['Ùĩ', 'ائÙĬ'] +['ãĤī', 'ãģı'] +['ож', 'еÑĤ'] +['Ġоб', 'оÑĢ'] +['ĠобоÑĢ', 'Ñĥд'] +['Ø£', 'سÙĦ'] +['à¹ĩ', 'à¸Ķ'] +['ÑĢÑĥ', 'ÑĤ'] +['دÙĬ', 'ÙħÙĤ'] +['دÙĬÙħÙĤ', 'را'] +['Ġjest', 'e'] +['×ķ×ķ', '×Ļר'] +['×ij×ĵ', '×Ļ×§'] +['деÑĢж', 'ива'] +['ãģĬ', 'ãģı'] +['ewn', 'ÄĻtr'] +['ewnÄĻtr', 'zn'] +['à¸ŀ', 'ฤ'] +['Ġ×IJ', '×ķ×Ķ'] +['ת×Ĺ', '×ķש'] +['Ġz', 'ob'] +['д', 'Ñĥм'] +['ĠÑģ', 'Ñĭ'] +['ÙĬر', 'ا'] +['ĠwiÄĻ', 'ks'] +['à¹ģà¸ķà¸ģ', 'à¸ķà¹Īาà¸ĩ'] +['lar', 'aras'] +['lararas', 'ı'] +['íĺ', 'Ģ'] +['ëī', '´'] +['×ķ×Ĵ', '׾'] +['ĠоÑĤ', 'меÑĤ'] +['ĠÑĢ', 'ан'] +['ت', 'ÙĥÙĦ'] +['иÑĤелÑĮ', 'н'] +['à¸Ľà¸£à¸°', 'วั'] +['à¸Ľà¸£à¸°à¸§à¸±', 'à¸ķิ'] +['ìŀ', 'ĸ'] +['мож', 'но'] +['pie', 'czeÅĦ'] +['pieczeÅĦ', 'st'] +['ëª', '»'] +['ìĬ', '¨'] +['×ŀס', '×ŀ'] +['á»', '¦'] +['ศ', 'ิ'] +['ศิ', 'ล'] +['ศิล', 'à¸Ľ'] +['ĠÅļ', 'w'] +['ãĥĥ', 'ãĤ·ãĥ§ãĥ³'] +['unit', 'Ãł'] +['Ġmiesz', 'ka'] +['Ġmieszka', 'ÅĦ'] +['pr', 'zed'] +['przed', 'si'] +['przedsi', 'ÄĻb'] +['przedsiÄĻb', 'ior'] +['à¸Ľà¸£à¸°', 'สิà¸Ĺà¸ĺิ'] +['à¸Ľà¸£à¸°à¸ªà¸´à¸Ĺà¸ĺิ', 'à¸łà¸²à¸ŀ'] +['ย', 'à¹Ī'] +['ìķ', 'Ļ'] +['รว', 'à¸Ķ'] +['รวà¸Ķ', 'à¹Ģรà¹ĩว'] +['å½ĵ', 'ãģŁãĤĬ'] +['äl', 'le'] +['Ñĥ', 'еÑĤÑģÑı'] +['ã', 'n'] +['ëł', 'µ'] +['th', 'è'] +['ãĤĴ', 'åĪ©ç͍'] +['ì', 'µľ'] +['íĵ', '¨'] +['à¸Ĺ', 'ัà¸ļ'] +['า', 'à¸Ħม'] +['ãģ', 'ĩ'] +['ëĤ', 'Į'] +['à¹Ģà¸Ľà¸¥', 'à¹Īา'] +['â', '¦'] +['ë', '¾'] +['ê', 'Ģ'] +['ê', 'ĩ'] +['â', '¡'] +['ðŁ', 'Ł'] +['ã', 'IJ'] +['â', 'º'] +['á', 'Ń'] +['á', 'Ļ'] +['á', 'ĵ'] +['á', '²'] +['ðĵ', 'ı'] +['á', '¬'] +['â', '¯'] +['ä', '¨'] +['ê', 'Ŀ'] +['ê', '«'] +['ð', 'ij'] +['ðĵ', 'ĥ'] +['ðĿ', 'ħ'] +['<', 'unk'] +[''] +[''] +[''] +['Ġع', 'ÙĦÙī'] +['Ġm', 'á»Ļt'] +['Ġv', 'Ỽi'] +['Ġng', 'ưá»Ŀi'] +['ĠØ¥', 'ÙĦÙī'] +['Ġnh', 'ững'] +['Ġth', 'á»ĥ'] +['Ġ×IJ', '×ķ'] +['Ġ×¢', '×Ŀ'] +['ا', 'Ùĭ'] +['Ġ', 'à¹ģละ'] +['ĠÙĦ', 'ا'] +['Ġnh', 'ư'] +['ĠاÙĦت', 'ÙĬ'] +['Ġ×Ķ', '×ķ×IJ'] +['ĠÄij', 'ến'] +['ĠØ£', 'ÙĪ'] +['Ġv', 'á»ģ'] +['ĠlÃł', 'm'] +['Ġs', 'ẽ'] +['Ġc', 'Å©ng'] +['Ġ', 'ợ'] +['ĠÄij', 'ó'] +['Ġnhi', 'á»ģu'] +['Ġt', 'ại'] +['Ġtr', 'ên'] +['Ġ×Ĵ', '×Ŀ'] +['Ġnh', 'Ãł'] +['Ġ׼', '×Ļ'] +['Ġs', 'á»±'] +['ĠÄij', 'ầu'] +['Ġb', 'á»ĭ'] +['ĠÙĩ', 'ذا'] +['Ġnh', 'ất'] +['Ġph', 'ải'] +['Ġhi', 'á»ĩn'] +['Ġdụ', 'ng'] +['ĠÄij', 'á»Ļng'] +['ĠاÙĦÙĦ', 'Ùĩ'] +['ĠØ', 'Į'] +['ĠÙĥ', 'ÙĦ'] +['Ġvi', 'á»ĩc'] +['Ġn', 'Äĥm'] +['Ġth', 'ì'] +['Ġh', 'á»įc'] +['ĠÙĪ', 'ت'] +['t', 'é'] +['Ġا', 'ÙĨ'] +['Ġt', 'ôi'] +['Ġ×IJ', '׳×Ļ'] +['Ġ׾', '×Ļ'] +['Ġ×ŀ', '×ķ'] +['Ġng', 'Ãły'] +['Ġn', 'Æ°á»Ľc'] +['Ġ×Ķ', '×Ļ×IJ'] +['Ġ×IJ', '×Ļ'] +['Ġh', 'Æ¡n'] +['ĠÙĩ', 'ذÙĩ'] +['ĠÙĪ', 'ÙĬ'] +['ĠاÙĦ', 'ذÙĬ'] +['Ġ×ķ', '×ŀ'] +['Ġgi', 'á'] +['Ġnh', 'ân'] +['Ġch', 'ÃŃnh'] +['Ġm', 'ình'] +['ĠÐĿ', 'а'] +['Ġth', 'ế'] +['Ġ×Ļ', '×ķתר'] +['Ġ×IJ', '×Ŀ'] +['Ġn', 'ên'] +['Ġh', 'ợ'] +['Ġhợ', 'p'] +['Ġc', 'òn'] +['ĠÙĩ', 'ÙĪ'] +['Ġc', 'Æ¡'] +['Ġr', 'ất'] +['ĠVi', 'á»ĩt'] +['Ġب', 'عد'] +['Ġש', '×Ļ'] +['Ġth', 'á»Ŀi'] +['Ġc', 'ách'] +['ĠÄij', 'á»ĵng'] +['Ġн', 'о'] +['Ġtr', 'ưá»Ŀng'] +['Ø', 'Ł'] +['ĠÄij', 'á»ĭnh'] +['ĠÄiji', 'á»ģu'] +['×Ļ', '×Ļ×Ŀ'] +['Ġth', 'á»±c'] +['n', 'ın'] +['Ġh', 'ình'] +['Ġn', 'ói'] +['Ġc', 'ùng'] +['Ġ×Ķ', '×Ķ'] +['ĠØ¥', 'ÙĨ'] +['Ġ×IJ', '×ij׾'] +['Ġnh', 'ưng'] +['Ġbi', 'ết'] +['Ġж', 'е'] +['Ġch', 'úng'] +['ĠÄij', 'ang'] +['Ġذ', 'ÙĦÙĥ'] +['Ġl', 'ên'] +['Ġkh', 'ách'] +['Ġn', 'Ãło'] +['Ġs', 'á»Ń'] +['Ġkh', 'ác'] +['Ġë°', 'ı'] +['Ġl', 'ý'] +['×Ļ', '×Ļ'] +['ĠÄij', 'ây'] +['Ġ׾', '×ŀ'] +['Ġc', 'ần'] +['Ġtr', 'ình'] +['Ġph', 'át'] +['ãģ«', 'ãĤĤ'] +['п', 'о'] +['Ġn', 'Äĥng'] +['Ġb', 'á»Ļ'] +['Ġv', 'ụ'] +['ĠÄij', 'á»Ļ'] +['Ñĩ', 'е'] +['Ġnh', 'áºŃn'] +['Ġtr', 'Æ°á»Ľc'] +['Ġ×¢', '×ĵ'] +['Ġh', 'Ãłnh'] +['ĠØ®', 'ÙĦاÙĦ'] +['Ġl', 'ượng'] +['Ġc', 'ấp'] +['Ġtá»', '±'] +['Ġv', 'ì'] +['Ġt', 'ư'] +['Ġch', 'ất'] +['Ġ׼', '×ŀ×ķ'] +['Ġg', 'ì'] +['Ġש', '׳'] +['Ġt', 'ế'] +['ת', '×ķ'] +['Ġnghi', 'á»ĩp'] +['Ġm', 'ặt'] +['ĠÙĥ', 'Ùħا'] +['Ġ×ij', '×Ļף'] +['Ġר', '×§'] +['Ġth', 'ấy'] +['Ġmá', 'y'] +['ĠÙģ', 'Ùī'] +['Ġd', 'ân'] +['Ġ×IJ', '×Ĺ×ĵ'] +['Ġt', 'âm'] +['Ġ׼', '×ļ'] +['Ġ׾', '×ķ'] +['в', 'о'] +['Ġt', 'ác'] +['Ġto', 'Ãłn'] +['ĠÙĪ', 'Ùħ'] +['Ġk', 'ết'] +['Ġ', 'หรืà¸Ń'] +['ĠÙĪØ§ÙĦ', 'Ùħ'] +['ĠÄiji', 'á»ĥm'] +['Ġ×ĸ', '×ķ'] +['Ġ×ij', '×ķ'] +['׼', '×ķת'] +['Ġh', 'á»Ļi'] +['Ġb', 'ằng'] +['ت', 'Ùĩا'] +['Ġ׼', '×ĵ×Ļ'] +['Ġ×Ķ', '×Ŀ'] +['Ġxu', 'ất'] +['ĠÙĤ', 'د'] +['Ġb', 'ảo'] +['Ġt', 'á»ijt'] +['Ġt', 'ình'] +['ĠÙĩ', 'ÙĬ'] +['ĠÄij', 'á»iji'] +['Ġthi', 'ết'] +['Ġhi', 'á»ĩu'] +['Ġti', 'ếp'] +['Ġt', 'ạo'] +['ת', '×Ķ'] +['Ġch', 'á»§'] +['o', 'ÅĽÄĩ'] +['Ġgi', 'ú'] +['Ġgiú', 'p'] +['ĠÃ', '½'] +['Ġqu', 'ả'] +['Ġlo', 'ại'] +['Ġc', 'ô'] +['ĠÃ', '´'] +['Ġô', 'ng'] +['Ġ×Ķ', '×ķ'] +['ĠاÙĦÙĬ', 'ÙĪÙħ'] +['ĠtÃŃ', 'nh'] +['г', 'а'] +['Ġph', 'òng'] +['Ġ', 'Äĥn'] +['Ġع', 'اÙħ'] +['Ġv', 'á»ĭ'] +['lar', 'ını'] +['r', 'ÃŃa'] +['Ġt', 'Ỽi'] +['ĠÄij', 'ưá»Ŀng'] +['Ġgi', 'Ỽi'] +['Ġb', 'ản'] +['Ġc', 'ầu'] +['Ġnhi', 'ên'] +['Ġb', 'á»ĩnh'] +['Ġth', 'ưá»Ŀng'] +['Ġ×IJ', '×Ļף'] +['ĠÄij', 'á»ģ'] +['Ġh', 'á»ĩ'] +['Ġ×Ļש', 'ר×IJ׾'] +['Ġqu', 'á'] +['ĠÐĹ', 'а'] +['ãģ®', 'ãģ§ãģĻãģĮ'] +['ĠÐŁ', 'ÑĢи'] +['Ġph', 'ần'] +['ĠÙĪ', 'ÙĦا'] +['ĠlỼ', 'n'] +['Ġtr', 'á»ĭ'] +['Ġcả', 'm'] +['Ġм', 'о'] +['Ġd', 'ùng'] +['ĠاÙĦ', 'Ùī'] +['ĠعÙĦÙĬ', 'Ùĩ'] +['ĠìŀĪ', 'ìĬµëĭĪëĭ¤'] +['ÙĬ', 'ÙĤ'] +['ĠÙĤ', 'بÙĦ'] +['Ġho', 'ặc'] +['ĠØŃ', 'ÙĬØ«'] +['Ġ', 'à¸Ĺีà¹Ī'] +['Ġغ', 'ÙĬر'] +['ĠÄij', 'ại'] +['Ġsá»ij', 'ng'] +['нÑĭ', 'ми'] +['Ġth', 'ức'] +['Ġפ', '×Ļ'] +['ĠÄiji', 'á»ĩn'] +['ãģª', 'ãģĭãģ£ãģŁ'] +['Ġgi', 'ải'] +['Ġv', 'ẫn'] +['Ġи', 'Ñħ'] +['Ġö', 'nce'] +['Ġv', 'áºŃy'] +['Ġmu', 'á»ijn'] +['Ġ', 'ảnh'] +['à¹ĥà¸Ļ', 'à¸ģาร'] +['ĠQu', 'á»ijc'] +['Ġk', 'ế'] +['׳', '×IJ'] +['Ġס', '×Ļ'] +['Ġy', 'êu'] +['ãģ®', 'ãģĭ'] +['ĠÄij', 'ẹ'] +['ĠÄijẹ', 'p'] +['Ġch', 'ức'] +['Ġy', 'ıl'] +['ĠTür', 'kiye'] +['d', 'é'] +['ĠÙĤ', 'اÙĦ'] +['Ġd', 'á»ĭch'] +['ĠolduÄŁ', 'u'] +['Ġch', 'á»įn'] +['Ġت', 'Ùħ'] +['หà¸Ļ', 'ึà¹Īà¸ĩ'] +['ãģķãĤĮ', 'ãģŁ'] +['Ġph', 'áp'] +['ìĽ', 'Ķ'] +['Ġti', 'á»ģn'] +['ãģĹ', 'ãģ¾ãģĹãģŁ'] +['Ġש', '׾×IJ'] +['ÙĦ', 'Ø©'] +['Ġ׾פ', '׳×Ļ'] +['Ġ×ij', '×Ļת'] +['ĠH', 'Ãł'] +['ĠØŃ', 'ت'] +['ĠØŃت', 'Ùī'] +['Ġ×¢', '×ķ×ĵ'] +['Ġn', 'ó'] +['Ġth', 'áng'] +['à¹Ģลืà¸Ń', 'à¸ģ'] +['ר', '×Ķ'] +['Ġt', 'Äĥng'] +['Ġcá', 'i'] +['Ġtri', 'á»ĥn'] +['Ġ×IJ×ķת', '×ķ'] +['ìłģ', 'ìĿ¸'] +['ĠC', 'ông'] +['Ġ׾×Ķ', '×Ļ×ķת'] +['Ġг', 'ода'] +['и', 'Ñİ'] +['Ġب', 'عض'] +['Ġ', 'à¸ģาร'] +['èī¯', 'ãģĦ'] +['ÙĪ', 'ت'] +['Ġli', 'ên'] +['ĠÐĿ', 'о'] +['ĠÐĿ', 'е'] +['çļĦ', 'ãģª'] +['ĠÙħ', 'ت'] +['ĠÑĤак', 'же'] +['ĠкоÑĤоÑĢ', 'Ñĭе'] +['Ġ×Ļ', '×ĵ×Ļ'] +['Ġtr', 'á»įng'] +['ãĤµ', 'ãĤ¤ãĥĪ'] +['ìłģ', 'ìľ¼ë¡ľ'] +['Ġt', 'áºŃp'] +['Ġש', '׾×Ļ'] +['íķĺ', 'ê²Į'] +['Ġt', 'Ãłi'] +['ĠÐ', '¯'] +['Ġr', 'á»ĵi'] +['ا', 'Ùĥ'] +['Ġth', 'ương'] +['Ġ×Ķ', '×ĸ×Ķ'] +['ĠÙĪ', 'ÙħÙĨ'] +['à¸Ĺีà¹Ī', 'มี'] +['Ġcu', 'á»Ļc'] +['Ġbü', 'yük'] +['ãģ¨', 'ãģĭ'] +['Ġ×ij', '×Ļ×ķתר'] +['Ġl', 'ần'] +['Ġgö', 're'] +['Ġtr', 'ợ'] +['Ġ×ĺ', '×ķ×ij'] +['ÑĤÑĮ', 'ÑģÑı'] +['Ġth', 'á»ijng'] +['Ġ׼', 'ש'] +['Ġti', 'êu'] +['Ġ×ŀ×IJ', '×ķ×ĵ'] +['Ø', 'Ľ'] +['k', 'Äħ'] +['Ġ', 'à¹ĥà¸Ļ'] +['Ġv', 'ấn'] +['Ġש', '׾×ķ'] +['ĠÄij', 'á»ģu'] +['Ùģ', 'ت'] +['Ġê²ĥ', 'ìĿ´'] +['Ġh', 'óa'] +['ĠاÙĦع', 'اÙħ'] +['ĠÙĬ', 'ÙĪÙħ'] +['к', 'ой'] +['Ġbi', 'á»ĩt'] +['ÑģÑĤ', 'о'] +['Ġ×Ķ', '×Ļ×ķ'] +['à¸Ĺีà¹Ī', 'à¸Īะ'] +['Ġ×ĵ', '×Ļ'] +['Ġ×IJ', '×ļ'] +['Ġá', 'n'] +['ص', 'ÙĪØ±'] +['Ġtr', 'ÃŃ'] +['ĠÐŁÑĢ', 'о'] +['Ġl', 'á»±c'] +['ãģĹãģ¦', 'ãģĦãģ¾ãģĻ'] +['Ġb', 'Ãłi'] +['Ġ×ĸ', '×IJת'] +['Ġb', 'áo'] +['à¸ļ', 'à¸Ļ'] +['ĠëĮĢ', 'íķľ'] +['Ġti', 'ế'] +['Ġtiế', 'ng'] +['Ġb', 'ên'] +['ãģķãĤĮ', 'ãĤĭ'] +['s', 'ión'] +['Ġt', 'ìm'] +['×¢', '×ķ'] +['m', 'é'] +['ни', 'Ñı'] +['ãģ»', 'ãģ©'] +['Ġà¹Ģà¸ŀ', 'ราะ'] +['ب', 'Ø©'] +['Ġë¶', 'Ħ'] +['Ġ×IJ', '×ĸ'] +['à¸Ĺ', 'à¹Īาà¸Ļ'] +['ת', '×Ŀ'] +['Ġth', 'êm'] +['Ġho', 'ạt'] +['y', 'ı'] +['×ĸ', '×ķ'] +['Ġgi', 'á»Ŀ'] +['Ġb', 'án'] +['à¸Ĥ', 'าย'] +['Ñĩ', 'а'] +['Ġ', 'à¹Ĩ'] +['ĠاÙĦÙħ', 'ت'] +['ĠоÑĩ', 'енÑĮ'] +['Ġb', 'ất'] +['Ġtr', 'ẻ'] +['ÑĤ', 'ÑĢ'] +['ĠØ£', 'ÙĨÙĩ'] +['ĠØ«', 'Ùħ'] +['Ġ׼', '×ŀ×Ķ'] +['Ġkh', 'ó'] +['Ġr', 'ằng'] +['ĠÙĪ', 'ÙģÙĬ'] +['ни', 'й'] +['Ġho', 'Ãłn'] +['t', 'ó'] +['Ġ×IJ', 'שר'] +['ĠìĥĿ', 'ê°ģ'] +['Ñģ', 'а'] +['Ġ׼', '×ijר'] +['ĠÑįÑĤ', 'ом'] +['lar', 'ının'] +['Ġch', 'ưa'] +['з', 'и'] +['Ġd', 'ẫn'] +['ĠÐļ', 'ак'] +['ج', 'ÙĪ'] +['ĠбÑĭ', 'ло'] +['ĠÙĬ', 'ت'] +['n', 'ı'] +['ÅĤ', 'am'] +['ĠÙĪÙĩ', 'ÙĪ'] +['×ij', '×ķ'] +['п', 'и'] +['ר', 'ת'] +['Ġqu', 'á»ijc'] +['ж', 'д'] +['ĠÄij', 'Æ¡n'] +['Ùĥت', 'ب'] +['Ġm', 'ắt'] +['ระ', 'à¸ļ'] +['ระà¸ļ', 'à¸ļ'] +['ĠÙĥ', 'اÙĨت'] +['Ġth', 'ân'] +['สิà¸Ļ', 'à¸Ħà¹īา'] +['×Ĵ', '×Ļ'] +['Ġph', 'ương'] +['à¹Ħมà¹Ī', 'à¹Ħà¸Ķà¹ī'] +['ĠìĦ', '±'] +['ĠC', 'ác'] +['Ġ×Ķ×ŀ', '×ķ'] +['ĠÑĤ', 'ем'] +['Ġ×ĵ', '×ķ'] +['à¸Ńะ', 'à¹Ħร'] +['Ġv', 'Äĥn'] +['ãģª', 'ãģ®ãģ§'] +['ĠN', 'á»Ļi'] +['Ġ×¢', '×ķ'] +['ãĤīãĤĮ', 'ãĤĭ'] +['Ġs', 'áng'] +['Ġgö', 'ster'] +['ãģĵãģ¨', 'ãĤĴ'] +['Ġtaraf', 'ından'] +['Ġм', 'а'] +['ĠпоÑģл', 'е'] +['Ġ׳', '×Ļת'] +['Ġ׳×Ļת', 'ף'] +['Ġл', 'еÑĤ'] +['Ġ׾', '׳×ķ'] +['Ñģ', 'Ñģ'] +['Ġ×Ļ', '×ķ'] +['п', 'е'] +['ĠÙĪ', 'ÙĦÙĥ'] +['ĠÙĪÙĦÙĥ', 'ÙĨ'] +['Ġngo', 'Ãłi'] +['ĠÄij', 'á»ĭa'] +['r', 'zÄħd'] +['dz', 'iaÅĤ'] +['ĠÙħ', 'ر'] +['иÑĤÑĮ', 'ÑģÑı'] +['Ġ×IJ×Ĺר', '×Ļ'] +['Ġ׾', '׼׾'] +['à¸Ĥ', 'à¹īà¸Ńม'] +['à¸Ĥà¹īà¸Ńม', 'ูล'] +['Ġб', 'ол'] +['Ġбол', 'ее'] +['جÙħ', 'ع'] +['л', 'еÑĤ'] +['Ġl', 'á»ĭch'] +['ĠÙħ', 'Ø«ÙĦ'] +['Ġ그리', 'ê³ł'] +['Ġth', 'ứ'] +['ĠdeÄŁ', 'il'] +['ÙĪ', 'ØŃ'] +['Ġש׾', '×ļ'] +['ĠÙħ', 'ØŃÙħد'] +['Ġn', 'ếu'] +['ĠÄij', 'á»ķi'] +['Ġv', 'ừa'] +['Ġm', 'á»įi'] +['Ġо', 'ни'] +['Ġl', 'úc'] +['ĠÙĬ', 'ÙĥÙĪÙĨ'] +['ì§', 'Ī'] +['Ġש׾', '׳×ķ'] +['ĠÐĶ', 'о'] +['Ġש', '׳×Ļ'] +['ล', 'ิ'] +['×IJ', 'פשר'] +['Ġs', 'ức'] +['ê¶', 'Į'] +['Ġ', 'ứng'] +['à¹Ħมà¹Ī', 'มี'] +['Ø·ÙĦ', 'ب'] +['ĠÑĩ', 'ем'] +['Ġch', 'uyên'] +['Ġth', 'ÃŃch'] +['Ġ×ķ', '×Ļ'] +['íķ', '©'] +['ĠÙħ', 'صر'] +['д', 'о'] +['ĠÄij', 'ất'] +['Ġch', 'ế'] +['à¸Ĭ', 'ืà¹Īà¸Ń'] +['Ġìĭ', 'ł'] +['ĠØ¥', 'ذا'] +['Ġر', 'ئÙĬس'] +['Ġש', '×Ļש'] +['Ġgiả', 'm'] +['Ñģ', 'ка'] +['lar', 'ında'] +['Ġs', 'ợ'] +['ĠtÃŃ', 'ch'] +['ĠÙĦ', 'ÙĥÙĨ'] +['Ġب', 'Ùħ'] +['×¢', '×ķ×ij'] +['×¢×ķ×ij', '×ĵ'] +['ÅĤÄħ', 'cz'] +['ları', 'na'] +['Ġש', '×Ŀ'] +['ĠÙĦ', 'ت'] +['Ġש×Ķ', '×ķ×IJ'] +['t', 'ów'] +['Ġëĭ¤', '른'] +['ĠØ£', 'Ùĥثر'] +['ãģ®', 'ãģ§ãģĻ'] +['׼', '×Ļ×Ŀ'] +['ĠolduÄŁ', 'unu'] +['ãģĭ', 'ãģª'] +['ãĤĤ', 'ãģĨ'] +['ÙĬ', 'ØŃ'] +['Ġnh', 'ìn'] +['Ġngh', 'á»ĩ'] +['ãģ«ãģª', 'ãģ£ãģ¦'] +['п', 'а'] +['Ġquy', 'ết'] +['ÙĦ', 'ÙĤ'] +['t', 'á'] +['Ġlu', 'ôn'] +['ĠÄij', 'ặc'] +['Ġ×IJ', 'ר'] +['Ġtu', 'á»ķi'] +['s', 'ão'] +['ìĻ', '¸'] +['ر', 'د'] +['ĠبÙĩ', 'ا'] +['Ġ×Ķ×Ļ', '×ķ×Ŀ'] +['×ķ', '×ķ×Ļ'] +['ãģ§ãģĻ', 'ãģŃ'] +['ĠÑĤ', 'ого'] +['Ġth', 'á»§'] +['ãģĹãģŁ', 'ãģĦ'] +['ر', 'ÙĤ'] +['Ġb', 'ắt'] +['г', 'Ñĥ'] +['Ġtá»', 'Ń'] +['ÑĪ', 'а'] +['Ġ', 'à¸Ľà¸µ'] +['Ġ×Ķ×IJ', '×Ŀ'] +['íı', '¬'] +['ż', 'a'] +['Ġ×IJת', '×Ķ'] +['Ġn', 'á»Ļi'] +['Ġph', 'ÃŃ'] +['ĠÅŁek', 'ilde'] +['Ġl', 'á»Ŀi'] +['d', 'ıģı'] +['Ġ׼×IJ', 'ף'] +['Ġt', 'üm'] +['Ġm', 'ạnh'] +['ĠM', 'ỹ'] +['ãģĿ', 'ãĤĵãģª'] +['Ġnh', 'á»ı'] +['ãģª', 'ãģĮãĤī'] +['Ġb', 'ình'] +['ı', 'p'] +['à¸ŀ', 'า'] +['ĠÄij', 'ánh'] +['ĠÙĪ', 'ÙĦ'] +['ר', '×ķת'] +['Ġ×IJ', '×Ļ×ļ'] +['Ġch', 'uyá»ĥn'] +['Ùĥ', 'ا'] +['ãĤĮ', 'ãĤĭ'] +['à¹ģม', 'à¹Ī'] +['ãĤĪ', 'ãģı'] +['ĠÙĪ', 'ÙĤد'] +['íĸ', 'Īëĭ¤'] +['Ġn', 'Æ¡i'] +['ãģ«ãĤĪ', 'ãģ£ãģ¦'] +['Ġvi', 'ết'] +['Ġà¹Ģà¸ŀ', 'ืà¹Īà¸Ń'] +['ëIJĺ', 'ëĬĶ'] +['اد', 'ÙĬ'] +['ĠÙģ', 'Ø¥ÙĨ'] +['ì¦', 'Ŀ'] +['ĠÄij', 'ặt'] +['Ġh', 'Æ°á»Ľng'] +['Ġx', 'ã'] +['Ġönem', 'li'] +['ãģł', 'ãģ¨'] +['Ġm', 'ẹ'] +['Ġ×ij', '×Ļ'] +['Ġ×ĵ', '×ijר'] +['Ġv', 'áºŃt'] +['ĠÄij', 'ạo'] +['Ġdá»±', 'ng'] +['ĠÑĤ', 'ом'] +['ĠÙģÙĬ', 'Ùĩا'] +['Ġج', 'ÙħÙĬع'] +['Ġthu', 'áºŃt'] +['st', 'ÄĻp'] +['Ġti', 'ết'] +['Ø´', 'ÙĬ'] +['Ġе', 'Ñīе'] +['ãģĻãĤĭ', 'ãģ¨'] +['ĠmÃł', 'u'] +['ĠÑįÑĤ', 'ого'] +['Ġv', 'ô'] +['ĠÐŃ', 'ÑĤо'] +['Ġth', 'áºŃt'] +['Ġn', 'ữa'] +['Ġbi', 'ến'] +['Ġn', 'ữ'] +['Ġ׾', '׼×Ŀ'] +['×Ļ', '×Ļף'] +['Ġس', 'ت'] +['ĠÐŀ', 'ÑĤ'] +['Ġph', 'ụ'] +['ê¹Į', 'ì§Ģ'] +['Ġ׾', '×ļ'] +['Ġk', 'ỳ'] +['à¹ĥ', 'à¸Ħร'] +['Ġg', 'ây'] +['ĠÙĦ', 'ÙĦÙħ'] +['Ġtụ', 'c'] +['ت', 'ÙĬÙĨ'] +['Ġtr', 'ợ'] +['Ġ׾', 'פ×Ļ'] +['Ġb', 'á»ij'] +['ĠÐļ', 'а'] +['ĠÄij', 'ình'] +['ow', 'Äħ'] +['s', 'ında'] +['Ġkhi', 'ến'] +['s', 'ız'] +['Ġк', 'огда'] +['ס', '׾'] +['ĠбÑĭ', 'л'] +['à¸Ļ', 'à¹īà¸Ńย'] +['обÑĢаÐ', '·'] +['Ġê²ĥ', 'ìĿ´ëĭ¤'] +['ëĵ¤', 'ìĿĢ'] +['ãģ¸', 'ãģ®'] +['Ġà¹Ģม', 'ืà¹Īà¸Ń'] +['Ġph', 'ục'] +['Ġ×Ĺ', '׾ק'] +['Ġh', 'ết'] +['ĠÄij', 'a'] +['à¹Ģà¸Ķà¹ĩ', 'à¸ģ'] +['íĺ', 'ķ'] +['l', 'ÃŃ'] +['ê¸', 'ī'] +['Ġع', 'دد'] +['ĠÄij', 'á»ĵ'] +['Ġg', 'ần'] +['Ġ×Ļ', '×ķ×Ŀ'] +['Ġs', 'Ä©'] +['ÑĢ', 'Ñıд'] +['Ġquy', 'á»ģn'] +['Ġ×IJ', '׾×IJ'] +['Ùĩ', 'Ùħا'] +['׳', '×Ļ×Ķ'] +['׾', '×ķת'] +['Ġ×Ķר', '×ij×Ķ'] +['Ġti', 'ên'] +['Ġal', 'ın'] +['Ġd', 'á»ħ'] +['人', 'ãģĮ'] +['но', 'Ñģ'] +['л', 'ÑģÑı'] +['ĠÄij', 'ưa'] +['ส', 'าว'] +['иÑĢов', 'ан'] +['Ġ×ŀס', 'פר'] +['×Ĵ', 'ף'] +['Ġki', 'ến'] +['ĠÐ', '¨'] +['p', 'é'] +['б', 'Ñĥ'] +['ов', 'ой'] +['б', 'а'] +['ĠØ¥', 'ÙĦا'] +['×IJ', '׾×Ļ'] +['Ġx', 'ây'] +['Ġb', 'ợi'] +['Ġש', '×ķ'] +['人', 'ãģ®'] +['×§', '×Ļ×Ŀ'] +['à¹Ģà¸Ķ', 'ืà¸Ńà¸Ļ'] +['Ġkh', 'á'] +['Ġ×ķ', '׾×Ķ'] +['×ĵ', '×ķת'] +['Ġ×¢', '×ij×ķר'] +['Ġبش', 'ÙĥÙĦ'] +['ĠÙĩÙĨا', 'Ùĥ'] +['ÑĤ', 'ÑĢа'] +['Ġ', 'íķĺëĬĶ'] +['ร', 'à¸Ńà¸ļ'] +['owa', 'ÅĤ'] +['h', 'é'] +['Ġdi', 'á»ħn'] +['Ġ×Ķ', '׼׾'] +['ĠØ£', 'س'] +['Ġch', 'uyá»ĩn'] +['ระ', 'à¸Ķัà¸ļ'] +['ĠNh', 'ững'] +['Ġ×IJ', '×Ĺת'] +['ĠØŃ', 'ÙĪÙĦ'] +['л', 'ов'] +['׳', 'ר'] +['Ġ×ķ', '׳'] +['Ġch', 'Æ¡i'] +['Ġiç', 'inde'] +['ÑģÑĤв', 'Ñĥ'] +['Ġph', 'á»ij'] +['ĠÑģ', 'Ñĥ'] +['ç§ģ', 'ãģ¯'] +['Ġch', 'ứng'] +['Ġv', 'á»±c'] +['à¹ģ', 'à¸Ń'] +['Ġl', 'áºŃp'] +['Ġtừ', 'ng'] +['å°ij', 'ãģĹ'] +['ĠNg', 'uy'] +['ĠNguy', 'á»ħn'] +['ĠÙģÙĬ', 'Ùĩ'] +['Ġб', 'а'] +['×Ļ', '×Ļת'] +['Ġ×ľ×¢', 'ש×ķת'] +['Ġ×ŀ', '׼'] +['Ġnghi', 'á»ĩm'] +['Ġм', 'ного'] +['Ġе', 'е'] +['ëIJĺ', 'ìĸ´'] +['Ġl', 'ợi'] +['Ġ׾', '׾×IJ'] +['Ġ׼', 'ף'] +['Ġch', 'ÃŃ'] +['ãģ§', 'ãģ®'] +['×Ĺ', '×ķ'] +['ש', '×ķ×Ŀ'] +['Ġ×ŀ', 'ר'] +['ĠÐĶ', 'лÑı'] +['Å', 'ģ'] +['Ġ׼×IJ', 'שר'] +['ĠM', 'á»Ļt'] +['ĠÙĪØ§ÙĦ', 'ت'] +['ĠìĿ´', '룰'] +['ÅŁ', 'a'] +['Ġchi', 'ến'] +['Ġaras', 'ında'] +['Ġ×ij', '×IJתר'] +['ãģķãĤĮ', 'ãģ¦ãģĦãĤĭ'] +['Ø´', 'ÙĥÙĦ'] +['Ġt', 'ượng'] +['Ġت', 'ت'] +['ĠC', 'ó'] +['Ġb', 'á»ı'] +['Ġtá»ī', 'nh'] +['Ġkh', 'ÃŃ'] +['ĠпÑĢ', 'оÑģÑĤ'] +['ĠпÑĢоÑģÑĤ', 'о'] +['ĠÙĪ', 'ÙĤاÙĦ'] +['Ġgi', 'áo'] +['ĠN', 'ếu'] +['×IJ', '×ŀר'] +['×¢×ł×Ļ', '×Ļף'] +['íİ', '¸'] +['Ùĩد', 'Ùģ'] +['ĠB', 'á»Ļ'] +['Ġb', 'Ãłn'] +['Ġng', 'uyên'] +['Ġgü', 'zel'] +['ส', 'าย'] +['ì²', 'ľ'] +['×ŀ', '×ķר'] +['Ġph', 'ân'] +['ס', 'פק'] +['×§', '×ij׾'] +['ĠاÙĦÙħ', 'تØŃ'] +['ĠاÙĦÙħتØŃ', 'دة'] +['ائ', 'د'] +['Ġ×IJ', '×ŀר'] +['Ġki', 'ÅŁi'] +['ì¤', 'Ģ'] +['Ġtr', 'uyá»ģn'] +['ĠÙĦ', 'Ùĩا'] +['ĠÐľ', 'а'] +['à¸ļริ', 'ษ'] +['à¸ļริษ', 'ั'] +['à¸ļริษั', 'à¸Ĺ'] +['Ġש', '׳×Ļ×Ŀ'] +['Ġмен', 'Ñı'] +['ÅŁ', 'e'] +['Ġdi', 'á»ĩn'] +['Ġ×IJ׳', '×Ĺ׳×ķ'] +['k', 'ü'] +['Ġc', 'á»ķ'] +['Ġm', 'á»Ĺi'] +['w', 'ä'] +['Ùħ', 'ÙĬ'] +['Ġhi', 'á»ĥu'] +['ëĭ', '¬'] +['Ġ×Ķ', '×Ĺ׾'] +['Ġt', 'ên'] +['Ġki', 'á»ĩn'] +['ÙĨ', 'ÙĤÙĦ'] +['Ġv', 'á»ĩ'] +['×ĵ', 'ת'] +['ĠÐłÐ¾ÑģÑģ', 'ии'] +['л', 'Ñĥ'] +['ĠاÙĦع', 'ربÙĬØ©'] +['ĠØ·', 'رÙĬÙĤ'] +['Ġ×Ķ×ij', '×Ļת'] +['Ñģ', 'еÑĢ'] +['Ġм', 'не'] +['ä', 'u'] +['Ġtri', 'á»ĩu'] +['ĠÄij', 'á»§'] +['Ġר', '×ij'] +['ت', 'ÙĩÙħ'] +['à¸ĭ', 'ี'] +['Ġì§Ģ', 'ê¸Ī'] +['li', 'ÅĽmy'] +['د', 'عÙħ'] +['ãģł', 'ãĤįãģĨ'] +['Ñģки', 'е'] +['Ġh', 'á»ıi'] +['Ġ×§', '×ķ'] +['ÑĢÑĥ', 'Ñģ'] +['ÙĨ', 'ظر'] +['ãģ®', 'ãĤĤ'] +['Ġ×Ķ', '׼×Ļ'] +['ĠìĽ', 'IJ'] +['ÙĪ', 'Ùĩ'] +['ĠÙĪ', 'Ùİ'] +['ĠB', 'ạn'] +['п', 'лаÑĤ'] +['Ġ×ŀ', '×ŀש'] +['лÑİ', 'б'] +['ĠнÑĥж', 'но'] +['Ġth', 'ư'] +['ãģ', 'µ'] +['ãģı', 'ãĤīãģĦ'] +['ر', 'Ø´'] +['ר', '×ķ×Ĺ'] +['ĠÙĬ', 'تÙħ'] +['Ġצר', '×Ļ×ļ'] +['Ġph', 'á'] +['ม', 'à¸Ńà¸ĩ'] +['Ġ×ij×IJ', '×ķפף'] +['Ġcả', 'nh'] +['Ġíķľ', 'ëĭ¤'] +['Ġ×Ķ×ŀ', 'ת'] +['à¸ķà¹Īาà¸ĩ', 'à¹Ĩ'] +['มี', 'à¸ģาร'] +['Ñģки', 'Ñħ'] +['ĠÐĴ', 'Ñģе'] +['Ġا', 'ÙĪ'] +['ج', 'ÙĬ'] +['ãģĵãģ¨', 'ãģ¯'] +['Ġd', 'Ãłi'] +['Ġh', 'á»ĵ'] +['èĩªåĪĨ', 'ãģ®'] +['à¹Ħ', 'หà¸Ļ'] +['ëĵ¤', 'ìĿĦ'] +['ĠV', 'Äĥn'] +['Ġд', 'аж'] +['Ġдаж', 'е'] +['Ñĭ', 'ми'] +['лаÑģ', 'ÑĮ'] +['ÙĬ', 'ÙĪÙĨ'] +['ÙĨ', 'ÙĪ'] +['c', 'ó'] +['ãģĹãģ¦', 'ãģĦãģŁ'] +['ãģł', 'ãģĭãĤī'] +['طاÙĦ', 'ب'] +['Ġc', 'á»Ńa'] +['п', 'ÑĢоÑģ'] +['ãģªãģ©', 'ãģ®'] +['รุ', 'à¹Īà¸Ļ'] +['Ġchi', 'ếc'] +['л', 'Ñĭ'] +['ĠÑıвлÑı', 'еÑĤÑģÑı'] +['Ġn', 'á»ķi'] +['ãģ®', 'ãģĬ'] +['Ġ×IJת', '×Ŀ'] +['ĠëķĮ문', 'ìĹIJ'] +['à¸ģล', 'าà¸ĩ'] +['ĠbaÅŁ', 'ka'] +['ìĦ', 'Ŀ'] +['ĠÑĨ', 'ел'] +['Ùģ', 'ÙĤ'] +['ãģ«ãĤĪ', 'ãĤĭ'] +['ÙĤ', 'ا'] +['Ġçı', 'kar'] +['Ġcứ', 'u'] +['Ø·', 'ا'] +['Ġש', 'ת'] +['à¹Ĥ', 'à¸Ħ'] +['Ġ×ŀ', '׾'] +['Ġ×Ķ', 'פר'] +['Ġг', 'де'] +['ĠØ®', 'Ø·'] +['åīį', 'ãģ«'] +['c', 'jÄĻ'] +['Ġ×Ĺ', 'ש×ķ×ij'] +['ר×Ĵ', '×¢'] +['Ġkho', 'ảng'] +['ĠÄij', 'á»Ŀi'] +['ĠÐł', 'е'] +['Ġо', 'на'] +['Ġ×IJ', '׳×ķ'] +['ãģ®', 'ãģ«'] +['ĠاÙĦذ', 'ÙĬÙĨ'] +['кÑĥ', 'п'] +['ãĤµ', 'ãĥ¼ãĥ'] +['ãĤµãĥ¼ãĥ', 'ĵ'] +['ãĤµãĥ¼ãĥĵ', 'ãĤ¹'] +['в', 'ал'] +['г', 'е'] +['Ġgi', 'ữa'] +['ĠKh', 'ông'] +['ĠâĹ', 'ĭ'] +['à¸ģล', 'ุà¹Īม'] +['ĠÙħÙĨ', 'ذ'] +['à¸Ń', 'à¹Īาà¸Ļ'] +['ĠÑģп', 'оÑģоб'] +['ĠÄij', 'á»Ļi'] +['Ġdi', 'ÄŁer'] +['Ġ', 'à¸ĸà¹īา'] +['Ùħ', 'Ø«ÙĦ'] +['Ġ×Ķ×IJ', '×Ļ'] +['Ġد', 'ÙĪÙĨ'] +['ÙĬر', 'اÙĨ'] +['Ñī', 'и'] +['بÙĨ', 'اء'] +['ĠØ¢', 'خر'] +['ظ', 'Ùĩر'] +['Ġ×ij', '׼'] +['ĠاÙĦÙħ', 'ع'] +['ãĥ', 'Ĵ'] +['Ġt', 'ất'] +['Ġm', 'ục'] +['ĠdoÄŁ', 'ru'] +['ãģŁ', 'ãĤī'] +['Ġס', '×ķ'] +['Ġx', 'ác'] +['ร', 'à¸Ń'] +['ĠcÄĥ', 'n'] +['Ġон', 'л'] +['Ġонл', 'айн'] +['Ġk', 'ý'] +['Ġch', 'ân'] +['Ġ', 'à¹Ħมà¹Ī'] +['اØŃ', 'Ø©'] +['r', 'án'] +['׳×Ļ', '×Ļ×Ŀ'] +['Ġ×ij', 'ף'] +['ĠÐ', 'ĸ'] +['à¸ķร', 'à¸ĩ'] +['д', 'Ñĭ'] +['Ġs', 'ắc'] +['ÙĦ', 'ت'] +['ãĥŃ', 'ãĥ¼'] +['ĠÙĦ', 'ÙĨ'] +['Ġר', '×ķ'] +['Ġd', 'Æ°á»Ľi'] +['à¹Ģ', 'à¸ĺ'] +['à¹Ģà¸ĺ', 'à¸Ń'] +['e', 'ÄŁi'] +['Ġ×ķ', 'ש'] +['ĠÙĦ', 'Ø£'] +['Ġg', 'ặp'] +['Ġc', 'á»ij'] +['ãģ¨', 'ãģ¦ãĤĤ'] +['رÙĪ', 'س'] +['Ġ׾×Ķ', '×Ļ'] +['Ġë³', '¸'] +['ä¸Ĭ', 'ãģĴ'] +['Ġm', 'ức'] +['Ñħ', 'а'] +['Ġìŀ', '¬'] +['à¸ī', 'ัà¸Ļ'] +['ÑĢÑĥ', 'ж'] +['Ġaç', 'ık'] +['ÙĪ', 'اÙĦ'] +['Ġ×ĸ', '×ŀף'] +['人', 'ãģ¯'] +['ع', 'ÙĬÙĨ'] +['Ñı', 'Ñħ'] +['Ġ×Ĵ×ĵ', '×ķ׾'] +['ר', '×ķ×ij'] +['g', 'ó'] +['ëĿ¼', 'ê³ł'] +['Ġark', 'adaÅŁ'] +['ÙĨ', 'شر'] +['Ġгод', 'Ñĥ'] +['ĠболÑĮ', 'ÑĪе'] +['ãģ¡ãĤĩ', 'ãģ£ãģ¨'] +['Ġcâ', 'u'] +['Ġs', 'át'] +['íĶ', '¼'] +['Ġti', 'ến'] +['íķ´', 'ìķ¼'] +['ĠÙĪ', 'Ø£ÙĨ'] +['à¸Ļ', 'าà¸Ļ'] +['Ġ×ij×IJ×ŀ', 'צע'] +['Ġ×ij×IJ×ŀצע', '×ķת'] +['Ġ׾', 'ר'] +['Ġqu', 'ản'] +['ĠÙĪØ§ÙĦ', 'Ø£'] +['Ġ×IJ×ķת', '×Ķ'] +['Ġìĸ´ëĸ', '¤'] +['Ġê²ĥ', 'ìĿĢ'] +['ØŃس', 'ÙĨ'] +['Ġm', 'ất'] +['à¸Ħ', 'ูà¹Ī'] +['ãĥ¬', 'ãĥ¼'] +['ĠÐĶ', 'а'] +['Ġol', 'ması'] +['Ġthu', 'á»Ļc'] +['׳', '×Ĺ'] +['íĨ', 'ł'] +['Ġsö', 'yle'] +['ãģĿãģĨ', 'ãģ§ãģĻ'] +['Ġت', 'ÙĥÙĪÙĨ'] +['л', 'ÑĥÑĩ'] +['׾', '×Ļ×ļ'] +['ĠØ£', 'ØŃد'] +['ли', 'ÑģÑĮ'] +['ĠвÑģ', 'его'] +['Ġ×Ķר', '×ij'] +['Ġëª', '»'] +['o', 'ÄŁ'] +['oÄŁ', 'lu'] +['ĠìĦ', 'ł'] +['Ġк', 'аÑĢ'] +['à¸łà¸²', 'à¸Ħ'] +['e', 'ÅĦ'] +['Ġ', 'à¸ģà¹ĩ'] +['Ġa', 'ynı'] +['Ġb', 'Ãł'] +['ãģªãĤĵ', 'ãģ¦'] +['Ġ모', 'ëĵł'] +['ÙĤر', 'ار'] +['ãģĹãģª', 'ãģĦ'] +['ĠÐĴ', 'о'] +['ĠÙĪÙĩ', 'ÙĬ'] +['ни', 'ки'] +['ãĤĮ', 'ãģŁ'] +['Ġchu', 'ẩn'] +['ר', '×¢'] +['Ùģ', 'رÙĬÙĤ'] +['ãĤĴ', 'åıĹãģij'] +['ĠÄij', 'úng'] +['б', 'е'] +['׼', '×ķ×Ĺ'] +['п', 'Ñĥ'] +['Ġ×ķ', '×Ĵ×Ŀ'] +['×ŀ', '׳×Ļ'] +['íĸ', '¥'] +['צ', '×Ļ×Ŀ'] +['à¸ĭ', 'ิ'] +['Ùĩ', 'ÙĨ'] +['н', 'ем'] +['Ġ×ij×ij', '×Ļת'] +['ر', 'ع'] +['Ġ', 'ส'] +['ĠÄIJ', 'Ãł'] +['íķĺ', 'ëĭ¤'] +['Ġ', 'ấy'] +['×Ĺ', '×ķ×ĵ'] +['×Ĺ×ķ×ĵ', 'ש'] +['ĠÑĩеÑĢ', 'ез'] +['Ñĥ', 'л'] +['ĠB', 'ình'] +['Ġê²ĥ', 'ìĿĦ'] +['Ġ×Ĵ', 'ר'] +['ä»ĺ', 'ãģij'] +['×Ĺ׾', '×§'] +['Ġت', 'ÙĦÙĥ'] +['à¹ĥส', 'à¹Ī'] +['sz', 'Äħ'] +['ÙĤ', 'اÙħ'] +['د', 'ÙĪØ±'] +['ĠÙģ', 'ÙĤØ·'] +['Ġh', 'ữu'] +['Ġмог', 'ÑĥÑĤ'] +['Ġg', 'á»įi'] +['Ġ×§', 'ר'] +['à¸Īะ', 'มี'] +['ت', 'ÙĤدÙħ'] +['Ġع', 'بر'] +['Ġ׾×Ķ', '×Ŀ'] +['ĠÑģам', 'о'] +['ס', '×ĵר'] +['Ġc', 'Ãłng'] +['r', 'ÃŃ'] +['Ġìŀ', '¥'] +['ëĵ¤', 'ìĿĺ'] +['ĠÙĦ', 'Ùĥ'] +['п', 'оÑĢÑĤ'] +['Ġkh', 'ả'] +['ĠÑģеб', 'Ñı'] +['׳', 'ף'] +['Ġد', 'ÙĪØ±'] +['Ġm', 'ợ'] +['Ġcâ', 'y'] +['Ġf', 'ark'] +['Ġfark', 'lı'] +['а', 'ÑİÑĤ'] +['Ġtr', 'á»±c'] +['wiÄĻks', 'z'] +['Ġthu', 'á»ijc'] +['Ġت', 'ØŃت'] +['ت', 'ÙĦ'] +['ов', 'Ñĭе'] +['ëĤ', 'ł'] +['Ġв', 'ам'] +['بÙĦ', 'غ'] +['Ġê°Ļ', 'ìĿĢ'] +['íĮ', 'IJ'] +['ÙĦ', 'ب'] +['Ġnas', 'ıl'] +['Ġод', 'ин'] +['м', 'ан'] +['ĠعÙĦÙĬ', 'Ùĩا'] +['б', 'и'] +['Ġפ', 'ש×ķ×ĺ'] +['×ijר', '×Ļ'] +['Ġש', '׳×Ķ'] +['Ġëı', 'Ħ'] +['ĠÄIJ', 'ại'] +['Ġ×IJ×ķת', '×Ŀ'] +['ĠاÙĦØŃ', 'ر'] +['Ġб', 'о'] +['à¸Ī', 'ุà¸Ķ'] +['Ġr', 'õ'] +['ĠdeÄŁi', 'ÅŁ'] +['Ġëĭ', '¨'] +['ĠÑģлÑĥÑĩ', 'а'] +['ĠÑģлÑĥÑĩа', 'е'] +['Ġ×IJ׳', 'ש×Ļ×Ŀ'] +['×ĵ', '×£'] +['ש×ij', 'ת'] +['Ġש׾', '׼×Ŀ'] +['Ġch', 'ú'] +['nik', 'ów'] +['Ġtan', 'ı'] +['Ġcá', 'o'] +['ĠÄij', 'á'] +['Ġ×IJ', '×ĵ×Ŀ'] +['Ġê°', 'ķ'] +['Ġnhi', 'á»ĩm'] +['Ġ׾', 'ס'] +['Ġ×Ľ×ª', '×ij'] +['Ġ×Ķס', 'פר'] +['ĠÄij', 'Äĥng'] +['Ġë', 'ijIJ'] +['à¸ľ', 'ิ'] +['à¸ľà¸´', 'ว'] +['ج', 'ا'] +['Ġê°', 'IJ'] +['ر', 'Ø£'] +['ست', 'خدÙħ'] +['ãģ«ãģªãĤĬ', 'ãģ¾ãģĻ'] +['Ġtá»', '·'] +['×ĺ', '×ķר'] +['г', 'овоÑĢ'] +['Ġв', 'оÑģ'] +['ĠÙħÙĨ', 'Ùĩا'] +['иÑĢов', 'аÑĤÑĮ'] +['ĠÄij', 'ầy'] +['׳', '×Ĵ'] +['ĠÙħ', 'ÙĪ'] +['ĠÙħ', 'ÙĪÙĤع'] +['ר׼', '×Ļ'] +['ت', 'Ùı'] +['ëª', '¨'] +['Ġת', '×ķ'] +['ÙĬا', 'Ùĭ'] +['à¹ĥ', 'à¸Ķ'] +['ãĤĬ', 'ãģ¾ãģĻ'] +['à¸Ńยูà¹Ī', 'à¹ĥà¸Ļ'] +['ĠØ£', 'ÙĪÙĦ'] +['ĠØ£', 'خرÙī'] +['Ġc', 'ư'] +['ص', 'ار'] +['×ŀ×Ĺ', 'ש×ij'] +['б', 'ÑĢа'] +['ÅĦ', 'ski'] +['б', 'ÑĢ'] +['ĠÙĬ', 'Ùı'] +['à¸ģ', 'ิà¸Ļ'] +['Ġch', 'á»ijng'] +['Ùħ', 'Ùı'] +['Ġ', 'à¸Ħืà¸Ń'] +['Ġت', 'ÙĨ'] +['t', 'ÃŃ'] +['y', 'Äĩ'] +['Ġm', 'ạng'] +['Ùģ', 'ÙĪ'] +['Ġdü', 'nya'] +['×§', 'ר×IJ'] +['Ġ×§', '׾'] +['ĠØŃ', 'اÙĦ'] +['c', 'ÃŃa'] +['Ġà¹Ģ', 'รา'] +['Ġר', '×ķצ×Ķ'] +['Ġá', 'p'] +['ë°', 'ķ'] +['ا', 'ÙĤØ©'] +['ни', 'Ñİ'] +['Ġ×IJ', '׾×ķ'] +['Ġ×ŀס', '×ķ'] +['ãģ§ãģ¯', 'ãģªãģı'] +['Ġtr', 'ả'] +['Ġ×§', 'שר'] +['mi', 'ÅŁtir'] +['Ġl', 'ưu'] +['Ġh', 'á»Ĺ'] +['ĠбÑĭ', 'ли'] +['Ġl', 'ấy'] +['عÙĦ', 'Ùħ'] +['Ġö', 'zel'] +['æ°Ĺ', 'ãģĮ'] +['Ġ×ĵ', 'ר×ļ'] +['Ùħ', 'د'] +['s', 'ını'] +['׳', '×ķש×IJ'] +['r', 'ów'] +['Ñĩ', 'еÑĢ'] +['êµIJ', 'ìľ¡'] +['ĠÐľ', 'о'] +['л', 'ег'] +['ĠV', 'Ỽi'] +['วัà¸Ļ', 'à¸Ļีà¹ī'] +['ÑİÑī', 'ие'] +['ãģĬ', 'ãģĻ'] +['ãģĬãģĻ', 'ãģĻ'] +['ãģĬãģĻãģĻ', 'ãĤģ'] +['ëı', 'ħ'] +['Ġ×Ļ×Ķ', '×Ļ×Ķ'] +['×ŀ', '×ĺר'] +['Ñı', 'ми'] +['Ġl', 'á»±a'] +['ĠÄij', 'ấu'] +['à¹Ģส', 'ียà¸ĩ'] +['Ġt', 'ương'] +['ëĵ', '±'] +['ĠÑģÑĤ', 'аÑĢ'] +['à¹ĥ', 'à¸ļ'] +['ว', 'ัà¸Ķ'] +['Ġİ', 'stanbul'] +['Ġ', 'à¸Īะ'] +['à¸ķ', 'ลาà¸Ķ'] +['Ġب', 'ÙĬ'] +['à¹ģà¸Ļ', 'ะ'] +['à¹ģà¸Ļะ', 'à¸Ļำ'] +['س', 'اعد'] +['Ġب', 'Ø£'] +['Ġki', 'á»ĥm'] +['ØŃ', 'سب'] +['à¸Ĭั', 'à¹īà¸Ļ'] +['Ġ×ķ', '×¢×ķ×ĵ'] +['ов', 'ÑĭÑħ'] +['оÑģ', 'нов'] +['Ġtr', 'Æ°á»Łng'] +['צ', '×ij×¢'] +['ĠÃŃ', 't'] +['Ġk', 'ỹ'] +['cr', 'é'] +['Ñı', 'м'] +['êµ', '°'] +['ãģĮ', 'ãģªãģĦ'] +['ÙĬÙĦ', 'Ø©'] +['ãĥķ', 'ãĤ£'] +['ر', 'Ùī'] +['ĠÙĬ', 'جب'] +['Ġ×IJ', '×£'] +['Ġc', 'á»±c'] +['ãĤīãĤĮ', 'ãģŁ'] +['Ġ', 'à¸ľà¸¹à¹ī'] +['Ġ', 'à¸Ń'] +['lar', 'ımız'] +['Ġkad', 'ın'] +['Ġê·¸', 'ëŀĺ'] +['Ġê·¸ëŀĺ', 'ìĦľ'] +['ĠëĺIJ', 'ëĬĶ'] +['ĠÄij', 'ả'] +['ĠÄijả', 'm'] +['Ġ×IJ', '×ķ×ŀר'] +['Ġy', 'ếu'] +['ci', 'Äħ'] +['ciÄħ', 'g'] +['Ġt', 'á»ij'] +['Ġש×IJ', '׳×Ļ'] +['Ġdz', 'iaÅĤa'] +['Ñī', 'а'] +['ĠÄij', 'Ãłn'] +['s', 'ına'] +['ãģĵãĤĮ', 'ãģ¯'] +['Ġ×ij', '׾×Ļ'] +['Ġ×ij', '×Ļשר×IJ׾'] +['л', 'оÑģÑĮ'] +['Ġgi', 'ữ'] +['ê°', 'IJ'] +['ÑĢ', 'он'] +['تج', 'ار'] +['г', 'лав'] +['в', 'ин'] +['Ġh', 'ạn'] +['Ġyapı', 'lan'] +['ب', 'س'] +['Ġ', 'à¸ŀรà¹īà¸Ńม'] +['ê´Ģ', '리'] +['mÄ±ÅŁ', 'tır'] +['b', 'ü'] +['r', 'ück'] +['ĠBaÅŁkan', 'ı'] +['ĠÙĦ', 'ÙĬس'] +['Ġs', 'Æ¡'] +['à¸Īัà¸ĩ', 'หว'] +['à¸Īัà¸ĩหว', 'ัà¸Ķ'] +['د', 'اء'] +['Ġ×Ķ', '׼'] +['v', 'ÃŃ'] +['ש', '×IJר'] +['Ġh', 'Æ°á»Łng'] +['Ġb', 'óng'] +['ĠCh', 'ÃŃnh'] +['Äħ', 'c'] +['à¹Ģà¸ģีà¹Īยว', 'à¸ģัà¸ļ'] +['Ġtá»', '©'] +['Ġtứ', 'c'] +['ĠÑĨ', 'веÑĤ'] +['Ġt', 'á»iji'] +['ĠnghÄ©', 'a'] +['ÙĦا', 'عب'] +['د', 'ÙĦ'] +['Ġפע', '×Ŀ'] +['h', 'ör'] +['à¸Ĭ', 'ุà¸Ķ'] +['à¸ŀ', 'ู'] +['à¸ŀู', 'à¸Ķ'] +['п', 'аÑģ'] +['ĠÅŁ', 'u'] +['Ġt', 'Æ°á»Łng'] +['خار', 'ج'] +['Ġâ', 'm'] +['ĠинÑĤеÑĢ', 'еÑģ'] +['ен', 'нÑĭÑħ'] +['×IJ', '׳×Ļ'] +['بد', 'Ø£'] +['ëĿ¼', 'ëĬĶ'] +['ì¹', '´'] +['æĸ¹', 'ãģĮ'] +['ли', 'в'] +['Ġ', 'à¸Ħà¸Ļ'] +['ער', '×ļ'] +['à¸Ĥà¸Ńà¸ĩ', 'à¸Ħุà¸ĵ'] +['п', 'ад'] +['Ġc', 'ạnh'] +['ĠëĤ', '¨'] +['ĠÄij', 'âu'] +['Ġbi', 'á»ĥu'] +['ãĤĤ', 'ãģĤãĤĭ'] +['׾', '×Ĵ'] +['Ġ', 'สำหรัà¸ļ'] +['Ġxu', 'á»ijng'] +['ס', '×ķ'] +['Ġذ', 'ات'] +['ĠÐľ', 'е'] +['ع', 'اÙĦÙħ'] +['×IJ', 'ס'] +['ب', 'ÙĬØ©'] +['Ø´', 'ا'] +['и', 'ем'] +['ĠNg', 'ưá»Ŀi'] +['íĺ', 'ij'] +['Ñģл', 'ов'] +['Ġп', 'а'] +['Ġm', 'ẫu'] +['ĠпÑĢоÑĨ', 'еÑģÑģ'] +['ĠNh', 'Ãł'] +['пÑĢо', 'из'] +['пÑĢоиз', 'вод'] +['à¸łà¸²à¸¢', 'à¹ĥà¸Ļ'] +['Ġ', 'à¸ļาà¸Ĺ'] +['×ŀ', '׳×ķ'] +['ĠоÑĢг', 'ан'] +['רצ', '×ķ'] +['×ķ×ŀ', '×Ļ×Ŀ'] +['Ġyaz', 'ı'] +['Ġd', 'ù'] +['ãĥ¬', 'ãĥ³'] +['ÙĪÙĦ', 'ÙĬ'] +['ย', 'ู'] +['Ġtr', 'ò'] +['à¹Ģà¸ŀ', 'ลà¸ĩ'] +['Ġ×ŀ', '׾×IJ'] +['à¸ķ', 'ล'] +['à¸ķล', 'à¸Ńà¸Ķ'] +['ĠÄij', 'ạt'] +['Ġ×Ĺ×ĵ', 'ש'] +['p', 'óÅĤ'] +['Ġ×ŀ', '×ĵ×Ļ'] +['ujÄħ', 'c'] +['×ŀ׳×Ķ', '׾'] +['Ġש×ij', '×ķ'] +['Ġ×Ķ×ŀש', 'פ×ĺ'] +['Ġ×IJ', '׾×Ķ'] +['ĠÙĪ', 'ذÙĦÙĥ'] +['à¹Ģà¸ŀ', 'ราะ'] +['ĠÄijo', 'Ãłn'] +['Ġíķ¨', 'ê»ĺ'] +['Ġd', 'ục'] +['Ø´', 'ت'] +['Ġ', 'ula'] +['Ġula', 'ÅŁ'] +['Ġqu', 'ý'] +['Ġ×Ķ', '×Ĵ×ĵ×ķ׾'] +['à¸ķัà¹īà¸ĩ', 'à¹ģà¸ķà¹Ī'] +['Ġש', 'ר'] +['Ø´', 'Ùĩد'] +['׳', 'ש×Ļ×Ŀ'] +['à¸ŀ', 'ล'] +['رÙĪ', 'ا'] +['ãĤĮ', 'ãģ¦'] +['Ġн', 'иÑħ'] +['Ġдел', 'а'] +['ãģ§ãģį', 'ãģªãģĦ'] +['ÅĤo', 'ż'] +['×IJ', '×Ĺר'] +['ì', '½Ķ'] +['ãĤ¢', 'ãĥĥãĥĹ'] +['د', 'Ù쨹'] +['Ġti', 'á»ĩn'] +['Ġkh', 'á»ı'] +['Ġkhá»ı', 'e'] +['ĠاÙĦع', 'اÙħØ©'] +['ãģ«', 'ãģĤãĤĭ'] +['ĠÄij', 'á»Ļc'] +['ì¡', '±'] +['Ġc', 'ụ'] +['й', 'ÑĤе'] +['Ġзак', 'он'] +['ĠпÑĢо', 'екÑĤ'] +['ìĸ', '¸'] +['ÙĦ', 'ØŃ'] +['ĠçalÄ±ÅŁ', 'ma'] +['ãĤĴ', 'ãģĻãĤĭ'] +['Ñħ', 'и'] +['ع', 'اد'] +['Ġ׳', '×ŀצ×IJ'] +['Ġר', '×Ļ'] +['à¸Ńà¸Ńà¸ģ', 'มา'] +['ĠT', 'ôi'] +['Ġth', 'ần'] +['ĠÙĬ', 'ا'] +['ล', 'าย'] +['Ġав', 'ÑĤо'] +['Ġsı', 'ra'] +['ĠÙĥ', 'Ø«ÙĬر'] +['Ùħ', 'ÙĬز'] +['ĠاÙĦع', 'ÙĦÙħ'] +['æĸ¹', 'ãģ¯'] +['×ķ×¢', '×ĵ'] +['Ġобла', 'ÑģÑĤи'] +['×Ļ׾', '×Ļ×Ŀ'] +['ãģĮ', 'åĩº'] +['à¸ĺ', 'ุ'] +['à¸ĺุ', 'ร'] +['à¸ĺุร', 'à¸ģิà¸Ī'] +['ÙĤت', 'ÙĦ'] +['ר×IJ', '×ķ'] +['Ġng', 'u'] +['Ġngu', 'á»ĵn'] +['Ġ', 'มา'] +['Ġпл', 'ан'] +['t', 'ório'] +['Ġcu', 'á»iji'] +['Ñģк', 'ом'] +['ĠاÙĦÙħ', 'اض'] +['ĠاÙĦÙħاض', 'ÙĬ'] +['Ġ×ij×¢', '׾'] +['Ġר', '×ij×Ļ×Ŀ'] +['Ġlu', 'áºŃn'] +['Ùĥ', 'ÙĪ'] +['à¸Ĺัà¹īà¸ĩ', 'หมà¸Ķ'] +['в', 'ан'] +['Ġtho', 'ại'] +['à¹Ħ', 'à¸Ń'] +['б', 'иÑĢ'] +['ĠاÙĦ', 'ض'] +['ت', 'ا'] +['ĠÑĢ', 'од'] +['ĠV', 'Ãł'] +['×ŀ', '×Ļף'] +['ĠбÑĭ', 'ла'] +['к', 'ами'] +['ĠÐĶ', 'е'] +['t', 'ık'] +['קר', '×Ļ'] +['ĠeÄŁ', 'itim'] +['ĠÙĥ', 'بÙĬر'] +['ب', 'Ùĥ'] +['ĠÙĦ', 'ÙĪ'] +['в', 'ой'] +['Ġ', 'ãģĵãģ®'] +['ĠÑĤ', 'ÑĢÑĥд'] +['my', 'ÅĽl'] +['Ġs', 'ư'] +['à¸ŀ', 'ีà¹Ī'] +['Ġ', 'à¹ģลà¹īว'] +['×¢', '×§'] +['Ġ×Ĺ×ijר', 'ת'] +['ระ', 'หว'] +['ระหว', 'à¹Īาà¸ĩ'] +['×Ļ', '×Ļ×Ķ'] +['ĠاÙĦÙĨ', 'اس'] +['ün', 'ü'] +['Ġ׾', '×ŀ×Ķ'] +['Ġch', 'ương'] +['ĠH', 'á»ĵ'] +['ار', 'ت'] +['ãĤĪãģĨ', 'ãģ§ãģĻ'] +['l', 'á'] +['×§×Ļ', '×Ļ×Ŀ'] +['æľ¬', 'å½ĵ'] +['æľ¬å½ĵ', 'ãģ«'] +['ãģĵãĤĵ', 'ãģª'] +['Ñģ', 'ов'] +['Ġ×ķ', '×Ĺ'] +['à¹Ģà¸ģ', 'à¹ĩà¸ļ'] +['Ġк', 'ÑĤо'] +['à¹Ĥร', 'à¸Ħ'] +['ĠØ´', 'رÙĥØ©'] +['ع', 'زÙĬ'] +['عزÙĬ', 'ز'] +['Ø·ÙĦ', 'ÙĤ'] +['п', 'ÑĥÑģÑĤ'] +['Ùģ', 'تØŃ'] +['ëŀ', 'Ģ'] +['Ġhã', 'y'] +['ض', 'Ùħ'] +['ë¦', '°'] +['åł´åIJĪ', 'ãģ¯'] +['ãĤª', 'ãĥ¼'] +['Ġh', 'ắn'] +['Ġ×IJ', '×ij×Ļ×ij'] +['Ġש׾×Ķ', '×Ŀ'] +['Ġ×Ķ×Ļ', '×Ļת×Ķ'] +['ĠاÙĦد', 'ÙĪÙĦØ©'] +['ĠاÙĦ', 'ÙĪÙĤ'] +['ĠاÙĦÙĪÙĤ', 'ت'] +['ãģĤ', 'ãģ¾ãĤĬ'] +['Ġta', 'ÅŁÄ±'] +['İ', 'N'] +['×¢', 'סק'] +['ãģ¦', 'ãģĦãģŁ'] +['Ġtá»ķ', 'ng'] +['ĠاÙĦØ¥', 'ÙĨس'] +['ĠاÙĦØ¥ÙĨس', 'اÙĨ'] +['ÑĢ', 'еÑĪ'] +['Ġg', 'ái'] +['ĠÑĨ', 'ен'] +['ĠÙģ', 'ÙĤد'] +['Ùħ', 'ات'] +['ãģķãĤĵ', 'ãģ®'] +['Ġph', 'ù'] +['×ĺ', '×Ķ'] +['ĠÙĪØ§ÙĦ', 'تÙĬ'] +['Ġب', 'Ùĥ'] +['ìĿ´', 'ëĤĺ'] +['к', 'Ñģ'] +['Ùħ', 'ÙĬر'] +['Ġv', 'ùng'] +['ĠاÙĦØ´', 'عب'] +['ĠNh', 'ưng'] +['ãĥĢ', 'ãĥ¼'] +['Ġ×Ĺ×Ļ', '×Ļ×Ŀ'] +['ĠØ´', 'خص'] +['×§', '×ķ×ĵ'] +['ê²', 'Ģ'] +['×¢', 'ש'] +['×¢', '×ķ׾×Ŀ'] +['צ', '×ķר'] +['ع', 'ÙĤد'] +['ĠiÅŁ', 'lem'] +['Ġ×Ķ×ij', '×IJ'] +['Ġd', 'ưỡng'] +['à¸Ł', 'รี'] +['Ġph', 'ÃŃa'] +['ãģ®ä¸Ń', 'ãģ§'] +['Ġп', 'и'] +['Ġng', 'Ãłnh'] +['ним', 'а'] +['ĠÙĩ', 'ÙĦ'] +['Ġ×ķ', '×IJת'] +['ĠÄij', 'áng'] +['é', 'quipe'] +['ĠÑįÑĤ', 'оÑĤ'] +['Ġgö', 'rev'] +['ë§', '¤'] +['Ġqu', 'ân'] +['å¼ķ', 'ãģį'] +['æĻĤ', 'ãģ«'] +['Ġب', 'Ùħا'] +['×ŀ', '×Ļת'] +['Ġü', 'lke'] +['Ġ×ŀ×§', '×ķ×Ŀ'] +['×ij', 'ף'] +['æ°Ĺ', 'æĮģãģ¡'] +['Ġë§İ', 'ìĿĢ'] +['Ġyük', 'sek'] +['ÑĨ', 'енÑĤÑĢ'] +['ĠÙħ', 'جÙĦس'] +['ç§ģ', 'ãģ®'] +['ÙĤد', 'ر'] +['Ġë¶Ģ', 'ë¶Ħ'] +['Ġì°', '¨'] +['خر', 'ج'] +['ãģĭ', 'ãģªãĤĬ'] +['ë³´', 'ëĭ¤'] +['Ġ×ŀ', '×Ļ×ĵ×¢'] +['peÅĤ', 'ni'] +['Ġx', 'á»Ń'] +['ìĹIJìĦľ', 'ëĬĶ'] +['ĠباÙĦ', 'Ùħ'] +['ĠÙĪ', 'Ùħا'] +['ĠÑįÑĤ', 'ой'] +['ب', 'ÙĬÙĨ'] +['n', 'ü'] +['ØŃ', 'ز'] +['ØŃز', 'ب'] +['ĠÑĢабоÑĤ', 'а'] +['ĠNh', 'áºŃt'] +['ÙĦ', 'اء'] +['Ġëĵ', '¤'] +['Ġëĵ¤', 'ìĸ´'] +['ãĤĦãģĻ', 'ãģĦ'] +['×Ĺ×ĸ', '×§'] +['Ġ×Ķ×Ĺ', '×ijר×Ķ'] +['п', 'иÑĤ'] +['ãģĭãĤī', 'ãģ®'] +['Ġë§IJ', 'ìĶĢ'] +['Ġפ', '×ķ'] +['ÙĦ', 'Ùİ'] +['à¹Ģà¸ķà¹ĩ', 'ม'] +['ĠÐļ', 'о'] +['Ġm', 'ówi'] +['Ġt', 'ÃŃn'] +['ר×Ĵ', 'ש'] +['פר', '×§'] +['Ġtr', 'ạng'] +['ĠÐŀ', 'н'] +['×Ĺ', '×ķ×¥'] +['ĠعÙĨد', 'Ùħا'] +['Ġب', 'ر'] +['使', 'ãģĦ'] +['Ġr', 'á»Ļng'] +['ëĮĢ', 'ë¡ľ'] +['íĪ', '¬'] +['Ġktóry', 'ch'] +['в', 'ид'] +['ลูà¸ģ', 'à¸Ħà¹īา'] +['Ġmog', 'Äħ'] +['Ġש', '×Ĺ'] +['×ij', '×Ĺר'] +['ãĥĸ', 'ãĥŃãĤ°'] +['ĠTh', 'Ãłnh'] +['Ġ×Ķ', 'ר×Ļ'] +['ĠÑģÑĤ', 'аÑĤÑĮ'] +['ĠH', 'á»Ļi'] +['à¸ļ', 'à¹īาà¸ĩ'] +['çī¹', 'ãģ«'] +['ĠÄIJ', 'ức'] +['èĢħ', 'ãģ®'] +['×¢', '×ŀ×ķ×ĵ'] +['×ĺר', '×Ķ'] +['Ð', '¥'] +['ĠÙħ', 'Ùħا'] +['Ġe', 'ÅŁ'] +['ĠнеобÑħодим', 'о'] +['ник', 'ов'] +['Ġüzer', 'inde'] +['a', 'ÅĤa'] +['Ġchá»ĭ', 'u'] +['ĠاÙĦ', 'دÙĬÙĨ'] +['أخ', 'بار'] +['ĠÄij', 'au'] +['ãģĮ', 'å¤ļãģĦ'] +['jÄħ', 'cych'] +['د', 'Ø®ÙĦ'] +['ları', 'nd'] +['larınd', 'an'] +['Ġs', 'ẻ'] +['à¸ŀิ', 'à¹Ģศ'] +['à¸ŀิà¹Ģศ', 'ษ'] +['ת', 'ף'] +['t', 'ıģı'] +['Ġlu', 'áºŃt'] +['ĠÅŀ', 'e'] +['ãĤ«', 'ãĥ¼'] +['ãģ®', 'ãģĤãĤĭ'] +['Ġ×Ķ×IJ', 'תר'] +['ĠاÙĦØ¢', 'ÙĨ'] +['ıld', 'ı'] +['Ġá', 'o'] +['ĠнаÑĩ', 'ал'] +['Ġvi', 'á»ĩn'] +['Ġ×ij×¢', '×ķ׾×Ŀ'] +['з', 'наÑĩ'] +['×Ļ×ĺ', '×Ķ'] +['к', 'ам'] +['ĠÐĺ', 'з'] +['à¹Ģà¸Ĥ', 'ียà¸Ļ'] +['à¸Ļ', 'à¹īà¸Ńà¸ĩ'] +['ÑĤ', 'ÑĢо'] +['à¹Ģ', 'à¸Ł'] +['Ġжиз', 'ни'] +['Ġ', 'สà¹Īวà¸Ļ'] +['Ġv', 'áºŃn'] +['Ġê´Ģ', '볨'] +['Ġl', 'âu'] +['ס', '×ĺר'] +['×§', 'ש'] +['س', 'ÙĬر'] +['Ġ×IJ×ķת', '×Ļ'] +['Ġm', 'ôi'] +['ائ', 'ب'] +['Ġо', 'ÑģÑĤа'] +['Ġm', 'ón'] +['Ġ×ij', '×ŀ×§×ķ×Ŀ'] +['Ġد', 'اخÙĦ'] +['Ġ×IJ', '×ķר'] +['Ġв', 'аÑģ'] +['Ùĥ', 'Ø´Ùģ'] +['ìĺ', '¨'] +['à¸ĸ', 'à¹Īาย'] +['Ġkullan', 'ıl'] +['Ġt', 'ô'] +['ãģ«', 'ãĤĪãĤĬ'] +['ĠëĺIJ', 'íķľ'] +['Ġ×¢×ij×ķ×ĵ', '×Ķ'] +['Ġri', 'ê'] +['Ġriê', 'ng'] +['Ġyak', 'ın'] +['ز', 'ا'] +['Å', '»'] +['×IJ', '×ķ׼׾'] +['شار', 'Ùĥ'] +['Ġб', 'еÑģ'] +['×', '´'] +['Ġا', 'بÙĨ'] +['ĠTá»ķ', 'ng'] +['ÙĨ', 'ظ'] +['ÅĽwi', 'ad'] +['ãĤµ', 'ãĥ¼'] +['ห', 'าย'] +['ĠG', 'ün'] +['Ġhakk', 'ında'] +['à¹Ģà¸Ĥà¹īา', 'มา'] +['ز', 'ÙĨ'] +['ĠÐł', 'о'] +['Ġbi', 'á»ĥn'] +['ãģ©', 'ãģĵ'] +['Ùģ', 'عÙĦ'] +['ز', 'ع'] +['פר', '×ĺ'] +['Ġ×Ķ', 'ף'] +['Ø£', 'ÙĩÙĦ'] +['Ġth', 'ất'] +['ØŃ', 'ÙħÙĦ'] +['Ñĩ', 'Ñĥ'] +['ĠìĤ¬', 'ìĭ¤'] +['ì°', '¸'] +['ĠìľĦ', 'íķ´'] +['ÙĪ', 'ظ'] +['ĠÐŁ', 'од'] +['Ġkho', 'ản'] +['ÑĤ', 'ен'] +['ĠÙģ', 'اÙĦ'] +['Ñģ', 'ад'] +['à¸Ļ', 'à¸Ńà¸Ļ'] +['ĠاÙĦسعÙĪØ¯', 'ÙĬØ©'] +['"', 'ØĮ'] +['ĠاÙĦ', 'ÙĴ'] +['ãĤī', 'ãģļ'] +['Ġto', 'án'] +['Ġch', 'ắc'] +['׼', '×Ļר'] +['m', 'éd'] +['méd', 'ia'] +['ز', 'ÙĪ'] +['Ġyan', 'ı'] +['פ', '׳×Ļ×Ŀ'] +['ØŃ', 'ظ'] +['Ġб', 'еÑģп'] +['ĠбеÑģп', 'лаÑĤ'] +['ĠбеÑģплаÑĤ', 'но'] +['ĠØ£', 'ÙħاÙħ'] +['à¸Ń', 'าย'] +['à¸Ńาย', 'ุ'] +['ר', 'שת'] +['Ġg', 'á»ĵ'] +['Ġgá»ĵ', 'm'] +['Ġu', 'á»ijng'] +['ص', 'ب'] +['k', 'ır'] +['ãĥij', 'ãĥ¼'] +['Ġ׾×ĵ', 'עת'] +['Ġк', 'ÑĥпиÑĤÑĮ'] +['׾', '×ķ×Ĺ'] +['ÙĪØ¶', 'ع'] +['ÙĤÙĬ', 'Ùħ'] +['à¸Ľ', 'า'] +['ж', 'ив'] +['à¸Ķ', 'ิà¸Ļ'] +['×IJ', '×ķפ'] +['à¹Ģล', 'à¹ĩà¸ģ'] +['ãĥĥ', 'ãĥī'] +['иÑĩеÑģки', 'Ñħ'] +['ĠCh', 'á»§'] +['кÑĢ', 'аÑģ'] +['ÙĪ', 'صÙĦ'] +['p', 'ÅĤat'] +['м', 'оÑĢ'] +['Ġ×Ķ×IJ', '×ķ'] +['à¸Ń', 'ิà¸Ļ'] +['Ġíķľ', 'êµŃ'] +['гÑĢ', 'е'] +['Ġìłľ', 'ê³µ'] +['ì°', '½'] +['Ġê°ľìĿ¸', 'ìłķë³´'] +['Ġngh', 'á»ĭ'] +['à¸ĭ', 'า'] +['ØŃس', 'اب'] +['Ġby', 'ÅĤa'] +['ÙħÙĦ', 'Ùĥ'] +['иÑĩеÑģки', 'е'] +['Ġb', 'ác'] +['ض', 'ØŃ'] +['ê¸', '¸'] +['ש', '×ŀ×¢'] +['Ġìĸ´ëĸ', '»'] +['Ġìĸ´ëĸ»', 'ê²Į'] +['ìĽ', 'Į'] +['ات', 'Ùĩ'] +['à¹Ĥรà¸ĩ', 'à¹ģ'] +['à¹Ĥรà¸ĩà¹ģ', 'รม'] +['خد', 'ÙħØ©'] +['ĠÐł', 'а'] +['׼×ķ׾', '×Ŀ'] +['×ŀש', '×Ĺ×§'] +['ĠÙĪ', 'ÙĥاÙĨ'] +['ס', '×ķ×£'] +['ĠاÙĦØŃÙĥÙĪÙħ', 'Ø©'] +['Ġ×ij', '×ĺ'] +['Ġtr', 'áºŃn'] +['Ġ×Ķ×¢', '×ķ׾×Ŀ'] +['ĠÃŃ', 'ch'] +['t', 'Äħ'] +['ש×ŀ', '×ķ'] +['Ġ×Ķר×IJש', '×ķף'] +['Ġíķĺ', 'ê³ł'] +['ãģķ', 'ãĤī'] +['ãģķãĤī', 'ãģ«'] +['ãģ«', 'ãģĹãģ¦'] +['Ġ', 'à¸ľà¸¡'] +['ãģ®', 'ãĤĪãģĨãģª'] +['ĠÙĪ', 'ÙĤت'] +['ãĥį', 'ãĥĥãĥĪ'] +['ÙĦ', 'عب'] +['ÙĪ', 'Ø´'] +['ìĺ', '¬'] +['Ġ', 'หาà¸ģ'] +['Ġm', 'iaÅĤ'] +['à¸Ĺ', 'à¸Ńà¸ĩ'] +['иÑĤ', 'а'] +['ا', 'صر'] +['ил', 'ÑģÑı'] +['з', 'е'] +['à¸Ľà¸£à¸°', 'มาà¸ĵ'] +['ãģĿãĤĮ', 'ãģ¯'] +['Ġb', 'ır'] +['Ġbır', 'ak'] +['صÙĨ', 'اع'] +['Ð', '®'] +['Ø´', 'عر'] +['Ġ׳', '×Ĵ×ĵ'] +['Ġب', 'سبب'] +['ãĥĿ', 'ãĤ¤'] +['ãĥĿãĤ¤', 'ãĥ³ãĥĪ'] +['ĠاÙĦج', 'ÙĪ'] +['ĠнеÑģк', 'олÑĮко'] +['Ġki', 'ếm'] +['Ùģ', 'Ùİ'] +['Ġض', 'د'] +['×ij×Ļ×ĺ', '×ķ×Ĺ'] +['تاب', 'ع'] +['ÙĨ', 'ز'] +['ĠB', 'ản'] +['Ġaç', 'ıkl'] +['Ġaçıkl', 'ama'] +['Ġ', 'à¸Ħุà¸ĵ'] +['à¸Ĺ', 'า'] +['ÅĤ', 'ów'] +['Ø·', 'ب'] +['ÙĨ', 'ØŃÙĨ'] +['Ġ×ŀ×§', '×ķר'] +['Ġİ', 's'] +['Ġдом', 'а'] +['Ġ', 'วัà¸Ļ'] +['Ġd', 'Ãłnh'] +['Ñı', 'н'] +['ми', 'ÑĢ'] +['Ġm', 'ô'] +['ĠvÃł', 'ng'] +['ص', 'اب'] +['s', 'ının'] +['à¸Ħ', 'ืà¸Ļ'] +['Ø®', 'بر'] +['×ĸ׼', '×ķ'] +['Ġ×ŀ', 'ש×Ķ×ķ'] +['m', 'ü'] +['Ġкомпани', 'и'] +['Ġ×Ķ×¢', '×Ļר'] +['ĠÙĥ', 'ÙĪ'] +['ÙĤÙĦ', 'ب'] +['ĠlỼ', 'p'] +['и', 'ки'] +['׳', '×ij'] +['à¹Ĥ', 'à¸Ħร'] +['à¹Ĥà¸Ħร', 'à¸ĩ'] +['à¹Ĥà¸Ħรà¸ĩ', 'à¸ģาร'] +['×ŀ×ķ×¢', '×ĵ'] +['ÑıÑĤ', 'ÑģÑı'] +['หลัà¸ĩ', 'à¸Īาà¸ģ'] +['ени', 'Ñİ'] +['Ġש', '×¢'] +['Ġb', 'Æ°á»Ľc'] +['ãĥ¡', 'ãĥ¼ãĥ«'] +['ãĤĦ', 'ãĤĬ'] +['Ġ×Ļ×ķ×ĵ', '×¢'] +['Ġê´Ģ', 'íķľ'] +['ĠاÙĦØ£', 'Ùħر'] +['Ġböl', 'ge'] +['ĠÑģв', 'ой'] +['ÙĦ', 'س'] +['Ġ×ŀ×Ļ', '×ķ×Ĺ×ĵ'] +['ĠëĤ´', 'ìļ©'] +['ĠØ£', 'جÙĦ'] +['ĠÄIJ', 'ông'] +['Ġ×ŀ', '×ł×ª'] +['Ġìĭľ', 'ê°Ħ'] +['Ùĥ', 'Ùİ'] +['ãģ¨ãģĦãģĨ', 'ãģ®ãģ¯'] +['Ġnale', 'ży'] +['تÙĨظ', 'ÙĬÙħ'] +['ĠÑģозд', 'а'] +['Ġph', 'é'] +['Ġphé', 'p'] +['ãģ§ãģį', 'ãģ¾ãģĻ'] +['Ġع', 'ÙĦÙħ'] +['大ãģį', 'ãģª'] +['ãĤ²', 'ãĥ¼ãĥł'] +['í', 'ħĮ'] +['Ġ׼×ķ׾', '׾'] +['ĠинÑĤеÑĢ', 'неÑĤ'] +['ĠT', 'ừ'] +['ãģ¨', 'ãģªãĤĭ'] +['ز', 'اÙĦ'] +['Ġktóry', 'm'] +['Ġnh', 'é'] +['ìĪ', 'ľ'] +['н', 'ев'] +['д', 'еÑĢ'] +['ãĤ¢', 'ãĥĹãĥª'] +['i', 'á»ĩu'] +['×ij', '×Ļ׾'] +['Ġت', 'س'] +['ĠÄIJ', 'ây'] +['ĠاÙĦØ®', 'اصة'] +['Ġà¹Ģ', 'à¸Ĭ'] +['Ġà¹Ģà¸Ĭ', 'à¹Īà¸Ļ'] +['ص', 'اد'] +['Ġd', 'ạng'] +['س', 'عر'] +['Ġש', '×Ļ×ŀ×ķש'] +['×Ĵ', '×Ļ×Ŀ'] +['ãģĮãģĤ', 'ãģ£ãģŁ'] +['п', 'ÑĢов'] +['пÑĢов', 'од'] +['Ġ×IJ', '×Ļ׳×ķ'] +['Ġ׾', 'ר×IJ'] +['Ġ׾ר×IJ', '×ķת'] +['ĠØ£', 'Ù쨶ÙĦ'] +['ĠØŃ', 'ÙĦ'] +['ĠØ£', 'بÙĪ'] +['ê°', 'ķ'] +['Ġì§', 'ij'] +['ãģ®', 'ãĤĪãģĨãģ«'] +['Ġפ', '׳×Ļ'] +['ס', '×Ļ×Ŀ'] +['ĠÙĪÙĩ', 'ذا'] +['Ġka', 'ç'] +['Ġé', 'én'] +['Ġê±', '´'] +['ë°', 'Ķ'] +['Ñĥ', 'з'] +['à¸Ĥà¸Ńà¸ĩ', 'à¹Ģรา'] +['i', 'ÅĤ'] +['ĠÐľ', 'Ñĭ'] +['Ġch', 'ết'] +['ĠاÙĦØ«', 'اÙĨÙĬ'] +['×IJ', '×§'] +['Ġ×ķ', '×¢×ľ'] +['ĠاÙĦØ·', 'ب'] +['×ij×ĺ', '×Ĺ'] +['Ġج', 'دÙĬدة'] +['Ġع', 'دÙħ'] +['ع', 'ز'] +['สิà¹Īà¸ĩ', 'à¸Ĺีà¹Ī'] +['ãģĻ', 'ãĤĮãģ°'] +['ĠÄij', 'ô'] +['ì£', 'ł'] +['د', 'ÙĤ'] +['н', 'омÑĥ'] +['Ġk', 'á»ĥ'] +['ãĤ¢', 'ãĥ³'] +['å¤ļãģı', 'ãģ®'] +['à¸Ľà¸£à¸°', 'à¸ģ'] +['à¸Ľà¸£à¸°à¸ģ', 'à¸Ńà¸ļ'] +['פע×Ļ׾', '×ķת'] +['ĠÑģÑĤ', 'ол'] +['may', 'ı'] +['ãģ¤', 'ãģĦ'] +['Ġyılı', 'nda'] +['Ġ', 'à¸Īึà¸ĩ'] +['koÅĦ', 'cz'] +['ĠTh', 'ông'] +['Ġак', 'ÑĤив'] +['н', 'ÑģÑĤ'] +['нÑģÑĤ', 'ÑĢÑĥ'] +['ĠÃĸ', 'z'] +['Ġת', '×ŀ×Ļ×ĵ'] +['ĠÙĥ', 'ÙĨت'] +['Ñģ', 'иÑģÑĤем'] +['pr', 'és'] +['prés', 'ent'] +['Ġn', 'â'] +['Ġnâ', 'ng'] +['gÅĤ', 'os'] +['ĠÙĪØ²', 'ÙĬر'] +['ØŃ', 'صÙĦ'] +['Ġиме', 'еÑĤ'] +['ØŃ', 'رÙĥØ©'] +['à¸ŀ', 'à¹Īà¸Ń'] +['ãĤĴ', 'ãģĬ'] +['Ġاست', 'خداÙħ'] +['×IJ×Ļר', '×ķ×¢'] +['ä»ĸ', 'ãģ®'] +['Ġש×Ķ', '×Ŀ'] +['ãģĹãģŁ', 'ãĤī'] +['ש×ŀ', '×Ļ'] +['Ñģ', 'ла'] +['m', 'ı'] +['Ġbaz', 'ı'] +['Ġíķĺ', 'ì§Ģë§Į'] +['×ĵ', '׾'] +['Ġyapt', 'ıģı'] +['ãĥĬ', 'ãĥ¼'] +['׾', '×Ļ׾×Ķ'] +['ãģ¨ãģĦ', 'ãģ£ãģŁ'] +['änd', 'ig'] +['ĠÅŁ', 'a'] +['ĠÙģÙĬ', 'Ùħا'] +['иÑĤ', 'елÑı'] +['×ŀ', '×ķש'] +['à¸Ĥ', 'à¸Ńà¸ļ'] +['l', 'ük'] +['Ġh', 'á»ĵi'] +['Ġëª', 'ħ'] +['ĠاÙĦÙĥ', 'Ø«ÙĬر'] +['צ', '×IJ'] +['Ġhaz', 'ır'] +['طر', 'Ùģ'] +['ا', 'ÙĬا'] +['ĠÄij', 'ôi'] +['ен', 'д'] +['ÙĦ', 'غ'] +['×Ĺ', '×ĸ×ķר'] +['ĠвÑģ', 'ег'] +['ĠвÑģег', 'да'] +['ëIJĺ', 'ê³ł'] +['×ĵ', '×ķ×ĵ'] +['ан', 'а'] +['د', 'ÙĪÙĦØ©'] +['Ġho', 'ạch'] +['ع', 'ÙĦا'] +['عÙĦا', 'ج'] +['Ġ×ķ', '×¢×ĵ'] +['×Ķ', '×Ŀ'] +['ки', 'й'] +['ÙĦ', 'ÙIJ'] +['Ġ×¢', '׾×Ļ×ķ'] +['ÑİÑī', 'ий'] +['Ġng', 'á»§'] +['صÙĨ', 'ع'] +['ĠاÙĦع', 'راÙĤ'] +['à¸ķà¹Īà¸Ń', 'à¹Ħà¸Ľ'] +['ãģŁãģı', 'ãģķãĤĵ'] +['Ġph', 'ạm'] +['ÙĦ', 'اÙĨ'] +['ات', 'Ùĩا'] +['Ġbö', 'yle'] +['تÙĨ', 'ÙģÙĬ'] +['تÙĨÙģÙĬ', 'ذ'] +['Ġש×Ķ', '×Ļ×IJ'] +['Ñģ', 'Ñĥ'] +['ย', 'าว'] +['Ġש', '×ķ׳×Ļ×Ŀ'] +['Ġ×ŀ', '×ķ׾'] +['ĠÑģ', 'ил'] +['Ġ×IJ×Ĺר', '×Ļ×Ŀ'] +['Ġph', 'á»§'] +['ÙĤØ·', 'ع'] +['ĠTh', 'á»§'] +['à¸Ľà¸£à¸°à¹Ģà¸Ĺศ', 'à¹Ħà¸Ĺย'] +['ÙĨ', 'ÙĤ'] +['ĠÄijo', 'ạn'] +['Ġب', 'Ø¥'] +['п', 'ÑĢедел'] +['×ķת', '×ķ'] +['Ġy', 'arı'] +['пÑĢ', 'е'] +['ĠczÄĻ', 'ÅĽci'] +['ØŃ', 'ÙĥÙħ'] +['×ķ׳', '×Ļת'] +['פע', '׾'] +['ãĤĴ', 'ãģĹãģ¦'] +['Ġktó', 'rzy'] +['׾', '×Ŀ'] +['ĠÄIJi', 'á»ģu'] +['ĠкоÑĤоÑĢ', 'аÑı'] +['ĠìĿ´', 'ìĥģ'] +['ãģĤ', 'ãģ£ãģŁ'] +['Ġ×ŀ×ĵ', '×ķ×ijר'] +['פ', '×ķ×¢×ľ'] +['d', 'ım'] +['éĢļ', 'ãĤĬ'] +['ĠбÑĥд', 'ÑĥÑĤ'] +['à¹Ģวà¹ĩà¸ļ', 'à¹Ħà¸ĭ'] +['à¹Ģวà¹ĩà¸ļà¹Ħà¸ĭ', 'à¸ķà¹Į'] +['ا', 'خر'] +['×Ĺ', '×Ļ׾'] +['Ġ×Ļ', '׾'] +['Ġ×Ļ׾', '×ĵ×Ļ×Ŀ'] +['×Ĺ', '×Ļפ'] +['×Ĺ×Ļפ', '×ķש'] +['Ġd', 'òng'] +['Ġש', '×ĸ×Ķ'] +['ÑĮ', 'е'] +['ãģĤ', 'ãģ¨'] +['ìŀIJ', 'ê°Ģ'] +['×IJ', '×ĵ'] +['Ġü', 'z'] +['Ġüz', 'ere'] +['ظ', 'ÙĦ'] +['Ġ×IJ', '×ķ׾×Ļ'] +['Ġ×ij', '×Ļ×ķ×Ŀ'] +['ÙĦ', 'ات'] +['Ġm', 'ê'] +['ì¹', '¨'] +['تØŃ', 'د'] +['تØŃد', 'Ø«'] +['ĠØ®', 'اصة'] +['Ġب', 'رÙĨ'] +['ĠبرÙĨ', 'اÙħج'] +['ĠH', 'Ãłn'] +['×Ĺ', 'ס'] +['ĠÙĪ', 'ÙĦÙħ'] +['×¢', '×Ŀ'] +['Ġm', 'ı'] +['à¸Ł', 'ัà¸ĩ'] +['ש', '×¢×Ķ'] +['ÙĪÙģ', 'ÙĤ'] +['ס', '×ij×Ļר'] +['алÑĮ', 'нÑĭй'] +['×Ĺש', '×ķ×ij'] +['Ġn', 'Ãłng'] +['ë³', '¼'] +['ĠкоÑĤоÑĢ', 'ÑĭÑħ'] +['Ġ×Ĺ', '×ķ×§'] +['t', 'ör'] +['ĠлÑĥÑĩ', 'ÑĪе'] +['ãĥij', 'ãĥ³'] +['ลà¹Īา', 'สุà¸Ķ'] +['Ġج', 'دÙĬد'] +['ÙĬد', 'Ø©'] +['à¸Ĺ', 'รà¸ĩ'] +['ãĤĪãĤĬ', 'ãĤĤ'] +['ÙĦ', 'ÙĦ'] +['ãĤĤ', 'ãģ£ãģ¨'] +['ש×ĺ', '×Ĺ'] +['Ġ×ķ', '×IJ×Ļ'] +['Ġgi', 'á»ijng'] +['Ø¥', 'ضاÙģ'] +['×§', 'ת'] +['ë§', 'Ŀ'] +['Ġzosta', 'ÅĤ'] +['ÑĢ', 'оз'] +['×Ļפ', '×Ļ×Ŀ'] +['Ġ׼׾', '׾'] +['ת×ķ׼', 'ף'] +['dıģ', 'ını'] +['ÙĤ', 'سÙħ'] +['ĠÑģ', 'ÑĩиÑĤ'] +['ĠÑģÑĩиÑĤ', 'а'] +['×ĺ', '×ķת'] +['Ġ', 'ưu'] +['ĠØ¢', 'ÙĦ'] +['Ġм', 'ом'] +['Ġмом', 'енÑĤ'] +['ĠاÙĦتع', 'ÙĦÙĬÙħ'] +['×¢×ľ', '×ķת'] +['Ġch', 'ữa'] +['Ġy', 'ön'] +['Ġtr', 'Ãł'] +['ĠØŃ', 'ÙĬÙĨ'] +['à¸ĭ', 'ั'] +['ĠC', 'á'] +['×¢', '×ĸ'] +['ĠاÙĦØ£', 'ÙħÙĨ'] +['c', 'ÃŃ'] +['Ġv', 'á»ijn'] +['Ġ', 'à¸Ļาย'] +['об', 'ÑĢа'] +['×§', '×IJ'] +['Ġthi', 'ếu'] +['ãĥŀ', 'ãĥ¼'] +['ส', 'วà¸Ļ'] +['Ġg', 'á»Ń'] +['Ġgá»Ń', 'i'] +['Ġê', '¹'] +['Ġê¹', 'Ģ'] +['Ġthi', 'á»ĩn'] +['ÙĤ', 'ع'] +['w', 'ÄĻ'] +['Ġн', 'ам'] +['ÑĤ', 'ол'] +['Ġs', 'ân'] +['ס', '×ķ×Ĵ'] +['Ġgeç', 'ir'] +['ÑĤ', 'он'] +['ев', 'а'] +['ĠÙĪ', 'ضع'] +['Ġع', 'شر'] +['Ñģ', 'ло'] +['à¸Ī', 'ัà¸ļ'] +['ãĤ·', 'ãĥ¼'] +['ãĤĤ', 'ãģĤãĤĬãģ¾ãģĻ'] +['Ġv', 'ẻ'] +['ĠÄIJ', 'á»ĥ'] +['ر', 'Ù쨹'] +['ĠاÙĦØ£ÙĪÙĦ', 'Ùī'] +['ÑĤ', 'аÑĢ'] +['ãģªãģı', 'ãģ¦'] +['Ùħ', 'Ùİ'] +['qu', 'ÃŃ'] +['×¢×ł×Ļ', '×Ļ׳'] +['г', 'ен'] +['Ġh', 'ôm'] +['à¸Ī', 'า'] +['Ġnh', 'Ỽ'] +['ĠاÙĦع', 'ربÙĬ'] +['×IJ', 'ף'] +['Ġl', 'á»Ļ'] +['Ġje', 'ÅĽli'] +['à¹Ģà¸Ĺà¹Īา', 'à¸Ļัà¹īà¸Ļ'] +['ĠØ£ÙĨ', 'Ùĩا'] +['Ġt', 'uy'] +['Ġtuy', 'á»ĩt'] +['Ġت', 'ص'] +['Ġتص', 'ÙĨÙĬ'] +['ĠتصÙĨÙĬ', 'Ùģ'] +['Ġê·¸ëŁ¬', 'ëĤĺ'] +['о', 'ÑĨен'] +['à¸ģิà¸Ī', 'à¸ģรรม'] +['ãĤĦ', 'ãģ£ãģ¦'] +['Ġkh', 'á»ıi'] +['Ġl', 'á»ĩ'] +['ĠاÙĦÙħج', 'تÙħع'] +['à¸Ńาà¸Ī', 'à¸Īะ'] +['à¸Īะ', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['ов', 'Ñĭй'] +['ר', '×Ŀ'] +['ร', 'à¹īà¸Ńà¸Ļ'] +['ש', '×ŀש'] +['人', 'ãģ«'] +['Ġüzer', 'ine'] +['פר', '×Ļ'] +['du', 'ÄŁu'] +['Ñĩ', 'ик'] +['Ġmù', 'a'] +['Ġ×ŀת', '×ķ×ļ'] +['Ġc', 'áºŃp'] +['Ġت', 'ارÙĬØ®'] +['×ij׾', 'ת×Ļ'] +['Ġì¢', 'Ģ'] +['ÙĦ', 'ع'] +['ب', 'اÙĨ'] +['Ġch', 'út'] +['Ġ×Ķ×ĸ', '×ŀף'] +['n', 'ée'] +['ĠLi', 'ên'] +['ĠÙĦÙĦ', 'Ø£'] +['ØŃد', 'ÙĪØ¯'] +['Ġ×¢', '׼ש×Ļ×ķ'] +['в', 'оз'] +['Ġyapt', 'ı'] +['Ġоб', 'о'] +['à¹ĥหà¹ī', 'à¸ģัà¸ļ'] +['Ġ×ij×Ķ', '×Ŀ'] +['ãģı', 'ãģ¦'] +['ر', 'أس'] +['ĠÑģÑĢед', 'ÑģÑĤв'] +['ĠB', 'Ãłi'] +['ãģĵãģ¨', 'ãģ«'] +['ĠìĤ¬', 'íļĮ'] +['Ġ모', 'ëijIJ'] +['×ij', '×IJ'] +['Ġtr', 'ắng'] +['ĠاÙĦبÙĦ', 'د'] +['ĠHo', 'Ãłng'] +['ли', 'бо'] +['ĠдÑĢÑĥг', 'иÑħ'] +['İ', 'R'] +['Ñĥм', 'а'] +['ĠJe', 'ÅĽli'] +['ãĤĤ', 'ãģĹ'] +['Ġv', 'òng'] +['Ġ×IJתר', '×Ļ×Ŀ'] +['ĠÄij', 'á»įc'] +['Ġв', 'оÑĤ'] +['ãģł', 'ãģĮ'] +['ë°', '°'] +['à¸Ķู', 'à¹ģล'] +['Ġ×ŀ', '׼׾'] +['ìĹIJ', 'ëıĦ'] +['г', 'аз'] +['Ġ׳×ķס', 'פ×Ļ×Ŀ'] +['ãģĵãģ¨', 'ãģ§'] +['Ġت', 'ÙĪ'] +['ãģ§', 'ãģĤãĤĬ'] +['à¸Ļั', 'à¹Īà¸ĩ'] +['ĠможеÑĤ', 'е'] +['sz', 'ÄĻ'] +['ãģ®', 'ãģł'] +['ĠÙħÙĨ', 'Ùĩ'] +['Ġb', 'á»ķ'] +['Ġb', 'üt'] +['Ġbüt', 'ün'] +['ë³´', 'ê³ł'] +['Ġch', 'á»ĵng'] +['à¹ģà¸Ī', 'à¹īà¸ĩ'] +['ĠV', 'ì'] +['ĠØŃ', 'ر'] +['Ġgi', 'ản'] +['ĠÙħ', 'دÙĬÙĨØ©'] +['تط', 'بÙĬÙĤ'] +['à¸Ī', 'ิ'] +['æĹ¥', 'ãģ®'] +['б', 'ил'] +['à¸ģ', 'à¸Ńà¸ĩ'] +['ê³', '³'] +['ĠØ£', 'Ùħا'] +['ìĨ', 'IJ'] +['Ġtr', 'ái'] +['ĠвÑģ', 'ем'] +['Ġس', 'ÙĨØ©'] +['ĠÑģай', 'ÑĤ'] +['Ġг', 'оÑĤов'] +['п', 'Ñĭ'] +['ĠëIJ', 'ł'] +['ĠاÙĦØ®', 'Ø·'] +['ĠاÙĦرئÙĬس', 'ÙĬØ©'] +['Ġíķ', '©ëĭĪëĭ¤'] +['ĠìķĦëĭĪ', 'ëĿ¼'] +['ĠìĿ´', 'ëłĩ'] +['ĠìĿ´ëłĩ', 'ê²Į'] +[')', 'ØĮ'] +['h', 'ält'] +['ĠØ£', 'Ùħر'] +['Ġع', 'Ùħر'] +['à¸ģà¹ĩ', 'à¸Īะ'] +['Ġ', 'à¸Ĺำà¹ĥหà¹ī'] +['Ġc', 'ân'] +['Ġ×ij', '׾'] +['Ġ×ij׾', '×ij×ĵ'] +['פ', 'סק'] +['ĠÙĬ', 'ÙĤÙĪÙĦ'] +['н', 'ÑĥÑĤÑĮ'] +['à¹ģ', 'à¸Ħ'] +['Ġ×§', 'צת'] +['Ġn', 'ằm'] +['Ġh', 'òa'] +['bilit', 'Ãł'] +['ĠìĹĨ', 'ëĭ¤'] +['Ġ׼', 'פ×Ļ'] +['ÑĢ', 'ож'] +['лаг', 'а'] +['Ġ×Ķש', '×Ļ'] +['ĠNgo', 'Ãłi'] +['ĠÙĪ', 'ج'] +['ĠÙĪØ¬', 'ÙĪØ¯'] +['ĠìľĦ', 'íķľ'] +['Ġus', 'ÅĤug'] +['Ġtu', 'ần'] +['d', 'ź'] +['×ŀ', '×ķף'] +['ĠاÙĦع', 'دÙĬد'] +['Ġch', 'ẳng'] +['สุà¸Ĥ', 'à¸łà¸²à¸ŀ'] +['Ġ×ij', '×ĵר×ļ'] +['ĠÑģеб', 'е'] +['ĠìŀĪ', 'ìĿĦ'] +['ĠاÙĦØŃ', 'اÙĦ'] +['Ġd', 'á'] +['Ġc', 'ưá»Ŀi'] +['Ġnghi', 'ên'] +['ie', 'ÅĦ'] +['ĠD', 'ương'] +['ï¼', 'ħ'] +['Ø´', 'د'] +['ãģĦãģ¤', 'ãĤĤ'] +['ĠвÑĭб', 'оÑĢ'] +['Ġc', 'á»Ļng'] +['ש', '×Ļ׳×ķ×Ļ'] +['Ġch', 'ạy'] +['Ġ×ij×¢', '׾×Ļ'] +['اخ', 'بار'] +['íķĺ', 'ë©°'] +['ż', 'Äħ'] +['ج', 'از'] +['Ġ׳', 'ר×IJ×Ķ'] +['ศ', 'ู'] +['ศู', 'à¸Ļ'] +['ศูà¸Ļ', 'ยà¹Į'] +['×Ĵ', '×¢'] +['Ġ×¢', '×ĵ×Ļ'] +['Ġ×¢×ĵ×Ļ', '×Ļף'] +['بر', 'ا'] +['ÑĨи', 'й'] +['ĠÄIJ', 'á»ĵng'] +['ÙĤ', 'اÙĨÙĪÙĨ'] +['ĠÄij', 'ứng'] +['ãģĹãģŁ', 'ãĤĬ'] +['Ġ×Ĺ×Ļ', '×Ļ'] +['Ġë', 'IJľ'] +['ĠëIJľ', 'ëĭ¤'] +['Ġм', 'еждÑĥ'] +['à¸ŀวà¸ģ', 'à¹Ģà¸Ĥา'] +['ĠB', 'ắc'] +['ล', 'ำ'] +['ë°', '±'] +['ĠíĻ', 'ķ'] +['มาà¸ģ', 'ม'] +['มาà¸ģม', 'าย'] +['бан', 'к'] +['à¸Ńา', 'à¸ģาร'] +['Ġh', 'Ãł'] +['Ġ׾', '׳'] +['à¸Ń', 'à¸Ń'] +['Ġë°Ķ', 'ë¡ľ'] +['л', 'ом'] +['m', 'ática'] +['ĠØŃ', 'د'] +['اب', 'ت'] +['à¸Ĺีà¹Ī', 'à¸Ļีà¹Ī'] +['Ġco', 'ÅĽ'] +['ÙģÙĬ', 'دÙĬ'] +['ÙģÙĬدÙĬ', 'ÙĪ'] +['ĠмеÑģÑĤ', 'о'] +['Ġph', 'út'] +['มาà¸ģ', 'à¸ģวà¹Īา'] +['×IJ', 'פ'] +['ب', 'ÙIJ'] +['ĠPh', 'ú'] +['ì±', 'Ħ'] +['ĠÙĪ', 'سÙĦÙħ'] +['à¸Īี', 'à¸Ļ'] +['поÑĤ', 'ÑĢеб'] +['Ġ×Ĺ×ĵ', 'ש×ķת'] +['Ø´', 'ÙĪ'] +['Ġעצ', '×ŀ×ķ'] +['ĠعÙħÙĦ', 'ÙĬØ©'] +['à¸Ħุà¸ĵ', 'à¸łà¸²à¸ŀ'] +['ãģ¾ãģĻ', 'ãģĮ'] +['دع', 'ÙĪ'] +['طر', 'ÙĤ'] +['à¹Ħมà¹Ī', 'à¸ķà¹īà¸Ńà¸ĩ'] +['ë²', 'Ķ'] +['ìĬ', '¹'] +['Ġk', 'ÃŃch'] +['ĠìĹĨ', 'ëĬĶ'] +['ĠÑĤ', 'ам'] +['ĠÙĨ', 'ØŃÙĪ'] +['ĠاÙĦÙĤ', 'اÙĨÙĪÙĨ'] +['×Ĺ', '×ķ×Ŀ'] +['Ġk', 'ız'] +['Ġ×ĵ', '×Ļף'] +['ĠвÑĢем', 'ени'] +['ãģ£ãģŁ', 'ãĤĬ'] +['ĠØ´', 'Ùĩر'] +['ĠìĦľ', 'ë¹ĦìĬ¤'] +['×¢', 'ש×Ķ'] +['Ġgi', 'ác'] +['ĠاÙĦسÙĦ', 'اÙħ'] +['Ġ×IJ', 'ש'] +['ĠполÑĥÑĩ', 'а'] +['à¸Īัà¸Ķ', 'à¸ģาร'] +['к', 'оÑĢ'] +['Ġ×Ķ×ĺ', '×ķ×ij'] +['ราย', 'à¸ģาร'] +['주', 'ìĿĺ'] +['à¹ģà¸ķà¹Ī', 'ละ'] +['Ġê·¸ëŁ°', 'ëį°'] +['à¸Ĺีà¹Ī', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['Ġת', '×ķ×ļ'] +['بÙĬ', 'اÙĨ'] +['Ð', 'Ļ'] +['oÅĽci', 'Äħ'] +['ÑĤ', 'ок'] +['ĠÃ', 'Ķ'] +['ĠÃĶ', 'ng'] +['à¹Ħมà¹Ī', 'à¹ĥà¸Ĭà¹Ī'] +['ãģ¿', 'ãģ¦'] +['ÐŁ', 'о'] +['ĠЧ', 'ÑĤо'] +['íĻ', '©'] +['×ĺ', '×ij×¢'] +['меÑĤ', 'ÑĢ'] +['Ġ×ij', '×ŀ×Ķ'] +['Ġ×ij×ŀ×Ķ', '׾'] +['Ġ×ij×ŀ×Ķ׾', '×ļ'] +['Ñĩ', 'ÑĮ'] +['×§', 'ש×Ķ'] +['з', 'нак'] +['знак', 'ом'] +['uj', 'ÄĻ'] +['×Ļצ', 'ר'] +['ĠاÙĦÙħ', 'ÙĦÙĥ'] +['ı', 'yla'] +['×IJ×ŀ', 'ת'] +['à¸Ľ', 'ิà¸Ķ'] +['×IJ', '×Ĺ×ĵ'] +['ر', 'اد'] +['Ġm', 'áºŃt'] +['ëĭ¤', 'ëĬĶ'] +['Ġl', 'ạnh'] +['ש׾', '×ķש'] +['ØŃ', 'دÙĬØ«'] +['ت', 'ز'] +['å¹´', 'ãģ®'] +['Ġк', 'ваÑĢ'] +['ĠкваÑĢ', 'ÑĤиÑĢ'] +['ä½ľ', 'ãĤĬ'] +['رÙĪ', 'ب'] +['ов', 'ан'] +['ĠТ', 'е'] +['à¸Īำ', 'à¸ģ'] +['à¸Īำà¸ģ', 'ัà¸Ķ'] +['ب', 'اط'] +['×Ĵ', 'ת'] +['Ġм', 'аÑĪ'] +['ĠмаÑĪ', 'ин'] +['×Ļצ', '×Ķ'] +['ãģ»', 'ãģ¨'] +['ãģ»ãģ¨', 'ãĤĵãģ©'] +['ÃŃ', 'do'] +['ĠÑı', 'зÑĭк'] +['à¸ļ', 'ิà¸Ļ'] +['สà¸ĸาà¸Ļ', 'à¸Ĺีà¹Ī'] +['ĠìĹ', '´'] +['ãĤ¦', 'ãĤ§'] +['Ġc', 'Ãł'] +['п', 'ан'] +['åı£', 'ãĤ³ãĥŁ'] +['Ġر', 'د'] +['اÙĤ', 'ت'] +['ĠÙĥ', 'ب'] +['ĠÙĥب', 'ÙĬرة'] +['ÑģÑĤ', 'ал'] +['ש×ŀ', '×Ĺ'] +['pos', 'ición'] +['ĠÙħÙĦÙĬ', 'ÙĪÙĨ'] +['ĠìĿ´', 'ìķ¼'] +['ĠìĿ´ìķ¼', '기'] +['Ġh', 'út'] +['ĠÅĽw', 'iat'] +['Ġë°©', 'ë²ķ'] +['ĠÑģв', 'еÑĤ'] +['Ġвиде', 'о'] +['ĠاÙĦÙĨ', 'ظاÙħ'] +['Ġtr', 'á»Ŀi'] +['ĠëĮĢ', 'íķ´ìĦľ'] +['ר', '×ŀת'] +['ت', 'داÙĪÙĦ'] +['×ķר', '×ĵ'] +['ת', '×ŀ'] +['ת×ŀ', '×ķ׳×ķת'] +['Ġ×ŀ', 'ף'] +['Ġдв', 'а'] +['Ġ×Ķ×§', '×ķ'] +['æĹ¥', 'ãģ«'] +['Ġ×Ķ×Ĵ', '×Ļ×¢'] +['à¹Ģà¸ŀิà¹Īม', 'à¹Ģà¸ķิม'] +['Ùħار', 'س'] +['Ġê²ĥ', 'ìŀħëĭĪëĭ¤'] +['ãģªãģĦ', 'ãģ¨'] +['Ġnhi', 'á»ĩt'] +['ëIJ', '©ëĭĪëĭ¤'] +['Ġ×ij׳', '×ķש×IJ'] +['Ġê°Ģ', 'ìŀ¥'] +['Ġv', 'ợ'] +['ĠÄij', 'óng'] +['צ×Ļ׾', '×ķ×Ŀ'] +['ê´Ģ', 'ê³Ħ'] +['в', 'аÑı'] +['×IJ', '×Ļ×ĸ'] +['×IJ×Ļ×ĸ', '×Ķ'] +['ĠÙĨ', 'ظاÙħ'] +['ÙħØŃ', 'اÙ쨏'] +['Ġt', 'ải'] +['기', 'ëıĦ'] +['à¸Ľà¸±à¸Ī', 'à¸Īุ'] +['à¸Ľà¸±à¸Īà¸Īุ', 'à¸ļัà¸Ļ'] +['׼', '×ĵ×ķר'] +['ĠìķĦ', 'ìĿ´'] +['׼׳', '×Ļס'] +['à¹Ģ', 'à¸ķร'] +['à¹Ģà¸ķร', 'ียม'] +['Ġngo', 'ại'] +['ĠدÙĪÙĦ', 'ار'] +['Ġr', 'ẻ'] +['Ġkh', 'Äĥn'] +['عد', 'د'] +['Ø´', 'عب'] +['czy', 'Äĩ'] +['ĠاÙĦ', 'Ùĥر'] +['ĠÑĩеловек', 'а'] +['ĠÙĪ', 'Ø¥ÙĨ'] +['×IJ', '×ĺ'] +['Ġth', 'Æ¡'] +['ĠاÙĦ', 'رÙĬاض'] +['оп', 'ÑĢедел'] +['опÑĢедел', 'ен'] +['×Ķ', '×ŀש×ļ'] +['ĠÐĿ', 'ово'] +['з', 'Ñĭва'] +['ĠاÙĦدÙĪÙĦ', 'ÙĬ'] +['ĠÄij', 'áp'] +['Ġк', 'ÑĢед'] +['ĠкÑĢед', 'иÑĤ'] +['ов', 'ого'] +['Ġm', 'ôn'] +['à¸Ľà¸£à¸°', 'à¹Ĥย'] +['à¸Ľà¸£à¸°à¹Ĥย', 'à¸Ĭà¸Ļ'] +['à¸Ľà¸£à¸°à¹Ĥยà¸Ĭà¸Ļ', 'à¹Į'] +['ÑģÑĤ', 'е'] +['ĠTh', 'á»ĭ'] +['د', 'ÙĬØ©'] +['×ŀצ', '×ķ'] +['Ùģ', 'ات'] +['×§', '×ĵ×Ŀ'] +['ìĿ´ëĿ¼', 'ê³ł'] +['ÙĪ', 'Ø®'] +['Ġ×Ĺ', '×ĸ'] +['ĠÑĦоÑĤ', 'о'] +['׾', '×Ļת'] +['ت', 'Ùİ'] +['ÙĪ', 'بر'] +['й', 'ÑĤи'] +['ĠÃ¶ÄŁ', 'ren'] +['Ġ×Ķ×ĸ', '×ķ'] +['Ġv', 'á»įng'] +['ÙĤÙĪ', 'Ø©'] +['ĠT', 'ây'] +['ĠÐĿ', 'и'] +['Ġש', '×ķ×ij'] +['ãģ¨è¨Ģ', 'ãĤıãĤĮ'] +['ãģ©', 'ãĤĵãģª'] +['×Ĺ', 'צ×Ļ'] +['ï½', 'ľ'] +['Ġ×ķ×Ķ', '×ķ×IJ'] +['ä¸Ģ', 'ãģ¤'] +['ĠÑģÑĤо', 'иÑĤ'] +['ni', 'Äħ'] +['×ĺר', '×Ļ'] +['ĠдеÑĤ', 'ей'] +['нÑı', 'ÑĤÑĮ'] +['ĠÑģдел', 'аÑĤÑĮ'] +['Ġë§İ', 'ìĿ´'] +['ä½ķ', 'ãģĭ'] +['ãģĽ', 'ãĤĭ'] +['à¹Ħ', 'หม'] +['à¸ķิà¸Ķ', 'à¸ķà¹Īà¸Ń'] +['Ġ×ij', 'ת×Ĺ'] +['Ġ×ijת×Ĺ', '×ķ×Ŀ'] +['ìĻ', 'Ħ'] +['ì§Ģ', 'ëĬĶ'] +['ÑģÑĤ', 'аÑĤ'] +['ÑıÑģ', 'н'] +['ü', 'b'] +['Ġth', 'ả'] +['Ġ×ij×IJ×ŀ', 'ת'] +['Ġt', 'uyến'] +['×ĵ', '×Ļר×Ķ'] +['Ġ×IJ', '×Ļש×Ļ'] +['×ĸ׼', 'ר'] +['ãģ°', 'ãģĭãĤĬ'] +['Ġx', 'ét'] +['׼', '×Ļ×ķ'] +['׼×Ļ×ķ', '×ķף'] +['diÄŁ', 'ini'] +['ĠاÙĦÙħ', 'ÙĪØ¶ÙĪØ¹'] +['Ġh', 'áºŃu'] +['à¸Īาà¸ģ', 'à¸ģาร'] +['×ijס', '×Ļס'] +['Ġ×ŀ×Ĵ', '×Ļ×¢'] +['×ij', '×Ļ×¢'] +['ĠÙĪ', 'جÙĩ'] +['à¹ģà¸Ķ', 'à¸ĩ'] +['à¸Ļ', 'าà¸ĩ'] +['ĠÅŀ', 'a'] +['ì', '¡´'] +['ë¡', 'Ģ'] +['à¸ķ', 'ะ'] +['Ġ×Ķ×Ĺ×Ļ', '×Ļ×Ŀ'] +['Ùģ', 'ÙĬد'] +['ãģ§ãģĻ', 'ãģĭãĤī'] +['ê·', 'ľ'] +['ź', 'ni'] +['ĠлÑİ', 'дей'] +['Ġyüz', 'de'] +['ıy', 'orum'] +['ĠاÙĦ', 'بØŃر'] +['e', 'ño'] +['п', 'аÑĢ'] +['ÙĬ', 'ÙĤØ©'] +['об', 'ÑĢ'] +['ר', '×ķ×ļ'] +['ت', 'ÙĪÙĤع'] +['ĠاÙĦØ´', 'ÙĬØ®'] +['åĪĿ', 'ãĤģãģ¦'] +['ĠÑĤ', 'елеÑĦ'] +['ĠÑĤелеÑĦ', 'он'] +['Ġth', 'ôi'] +['Ġ×Ļ׼×ķ׾', '×Ļ×Ŀ'] +['ĠÅŁ', 'irk'] +['ĠÅŁirk', 'et'] +['Ġìļ°ë¦¬', 'ê°Ģ'] +['ĠÄij', 'ông'] +['Ġת', '×ķ×ĵ×Ķ'] +['ÑģмоÑĤÑĢ', 'еÑĤÑĮ'] +['ĠÙĦ', 'ÙĩÙħ'] +['Ġ׾', '׼'] +['ĠN', 'ó'] +['ĠØŃ', 'اÙĦØ©'] +['ãģĦ', 'ãģij'] +['קר', '×ķ'] +['az', 'ı'] +['ãĤ³', 'ãĥ¼'] +['ĠÙĦÙĦ', 'ت'] +['s', 'ınız'] +['ĠH', 'ải'] +['기', 'ìĪł'] +['ยัà¸ĩ', 'à¹Ħมà¹Ī'] +['ëĭ¤', 'ê³ł'] +['פ', '×Ĺ'] +['Ġ׾×Ĵ', '×ij×Ļ'] +['Ġع', 'ÙĨÙĩ'] +['Ġк', 'аз'] +['Ġказ', 'ино'] +['ب', 'ÙĪØ±'] +['ÑĦ', 'еÑĢ'] +['Ġê°Ļ', 'ìĿ´'] +['تس', 'جÙĬÙĦ'] +['ĠاÙĦÙħ', 'رÙĥز'] +['ĠTh', 'ái'] +['д', 'аÑĤÑĮ'] +['×ŀ×Ļ', '×Ļ׾'] +['Ġpay', 'laÅŁ'] +['ãģ¤', 'ãģ®'] +['à¹Ģร', 'ืà¸Ń'] +['n', 'ça'] +['׳', '×ķ×Ĺ'] +['Ġ×IJ', 'פ×Ļ׾×ķ'] +['ãģ¨', 'èĢĥãģĪ'] +['ãģ¨ãģĹãģ¦', 'ãģ¯'] +['à¹Ģà¸Ī', 'à¸Ń'] +['×ŀ', 'פ'] +['Ġg', 'iriÅŁ'] +['л', 'иÑĤ'] +['ÑĤ', 'елÑı'] +['Ñij', 'н'] +['æ°Ĺ', 'ãģ«'] +['Ġg', 'ó'] +['Ġgó', 'p'] +['åĪĩ', 'ãĤĬ'] +['Ġ×Ķ', '×Ĺ×ĵש'] +['ж', 'ал'] +['Ġ×ĵ', 'עת'] +['éģķ', 'ãģĨ'] +['à¹Ģà¸Ĥà¹īา', 'à¹Ħà¸Ľ'] +['Ġס', 'ר×ĺ'] +['e', 'ña'] +['æĸ°', 'ãģĹãģĦ'] +['ر', 'Ùİ'] +['ĠÐIJ', 'ÑĢ'] +['Ġph', 'ản'] +['à¸Īะ', 'à¹Ħà¸Ķà¹ī'] +['Ġ×ijצ', '×ķר×Ķ'] +['Ø´', 'اÙĩ'] +['شاÙĩ', 'د'] +['ÙĪØ±', 'د'] +['à¹Ģà¸Ļืà¹Īà¸Ńà¸ĩ', 'à¸Īาà¸ģ'] +['или', 'ÑģÑĮ'] +['à¹ģละ', 'à¸ģาร'] +['Ġ×Ķ', '×ĸ׼'] +['Ġ×Ķ×ĸ׼', '×ķ×Ļ×ķת'] +['ei', 'ÃŁ'] +['ãĥ', '¨'] +['ìĥ', 'Ī'] +['ĠÃĩ', 'a'] +['Æ', '¯'] +['ש', '×Ĵ'] +['ÙĬÙĨ', 'Ø©'] +['ร', 'à¹īà¸Ńà¸ĩ'] +['ãĤµ', 'ãĥ³'] +['ÑĢоÑģÑģ', 'ий'] +['ÑĢоÑģÑģий', 'Ñģк'] +['a', 'ÄŁa'] +['ĠнаÑĩ', 'ина'] +['Ġص', 'ÙĦÙī'] +['à¸Ĺุà¸ģ', 'à¸Ħà¸Ļ'] +['íļĮ', 'ìĤ¬'] +['Ġли', 'ÑĨ'] +['Ø´', 'ÙĬر'] +['ĠØ´ÙĬ', 'Ø¡'] +['ÙĬÙĨ', 'ا'] +['Ġפ', '×Ĺ×ķת'] +['Ġiçer', 'is'] +['Ġiçeris', 'inde'] +['ĠØ£', 'ØŃÙħد'] +['Ġże', 'by'] +['ì´', 'Ŀ'] +['Ġп', 'оказ'] +['Ġи', 'менно'] +['หà¸Ļัà¸ĩ', 'ส'] +['หà¸Ļัà¸ĩส', 'ืà¸Ń'] +['ĠÑĤÑĢ', 'е'] +['สัà¸ĩ', 'à¸Ħม'] +['Ø¥', 'ÙIJ'] +['ãģĮ', 'å¿ħè¦ģ'] +['ÙĬÙij', 'Ø©'] +['פ', 'צ'] +['íĭ', '°'] +['ĠÙħ', 'جاÙĦ'] +['׳', 'פש'] +['к', 'ан'] +['×Ĺ', '×ķפ'] +['×Ĺ×ķפ', 'ש'] +['ì²ĺ', 'ëŁ¼'] +['ов', 'аÑı'] +['з', 'ов'] +['Ġh', 'ạ'] +['Ġdzi', 'ÄĻki'] +['×Ļר', '×ķ'] +['Ġ׾', '×ŀצ'] +['Ġ׾×ŀצ', '×ķ×IJ'] +['×Ļ×ĵ', '×ķ'] +['Ġs', 'ợ'] +['Ġ׾×Ķ', '×Ĵ×Ļ×¢'] +['×§', '×ij×¢'] +['Ġchi', 'á»ģu'] +['ãĥŀ', 'ãĤ¤'] +['Ġd', 'Ãłng'] +['à¹ģà¸Ł', 'à¸Ļ'] +['Ġü', 'ye'] +['×Ļ׳', '×Ĵ'] +['à¹Ģรีย', 'à¸ģ'] +['ç§ģ', 'ãģĮ'] +['th', 'é'] +['ĠÑĦ', 'илÑĮ'] +['ĠÑĦилÑĮ', 'м'] +['ĠNg', 'Ãły'] +['Ġж', 'ен'] +['Ġжен', 'Ñīин'] +['ج', 'ÙĬد'] +['n', 'ç'] +['à¸Ľ', 'รา'] +['×Ļ×ŀ', '×ķ'] +['Ġn', 'á»ģn'] +['×IJ', '×ķ׾×Ŀ'] +['Ġвозмож', 'ноÑģÑĤÑĮ'] +['Ġëĭ¤', 'ìĭľ'] +['è¦ĭ', 'ãģŁ'] +['à¸ĸ', 'à¸Ļ'] +['à¸ĸà¸Ļ', 'à¸Ļ'] +['mız', 'ı'] +['ĠÙħ', 'جÙħÙĪØ¹Ø©'] +['c', 'jÄħ'] +['ĠÐł', 'Ф'] +['à¸ģำ', 'หà¸Ļ'] +['à¸ģำหà¸Ļ', 'à¸Ķ'] +['ĠìŬ', '기'] +['land', 'ı'] +['ни', 'ÑĨ'] +['ÑģÑĤв', 'е'] +['Ġ×ĵ', '×ijר×Ļ×Ŀ'] +['Ġsk', 'ÅĤad'] +['ãĤĬ', 'ãģ¾ãģĹãģŁ'] +['ĠоÑĤ', 'кÑĢÑĭÑĤ'] +['нÑı', 'ÑĤ'] +['ĠÑģво', 'ей'] +['à¸Ī', 'ิà¸ķ'] +['ĠкаÑĩеÑģÑĤв', 'е'] +['Ġet', 'tiÄŁi'] +['ìĤ¬', 'íķŃ'] +['ĠاÙĦÙĬ', 'ÙħÙĨ'] +['иÑĩеÑģки', 'й'] +['ë¸', 'Į'] +['Ġ×ij×IJר', '×¥'] +['Ġا', 'سÙħ'] +['Ġиз', 'веÑģÑĤ'] +['r', 'ão'] +['Ġatt', 'ivitÃł'] +['à¹Ģà¸Ľà¹ĩà¸Ļ', 'à¸ģาร'] +['ĠاÙĦد', 'Ùĥت'] +['ĠاÙĦدÙĥت', 'ÙĪØ±'] +['ĠÙĪØ§ØŃد', 'Ø©'] +['ĠÑģ', 'ÑĩеÑĤ'] +['ĠпÑĢ', 'иÑĩ'] +['ĠпÑĢиÑĩ', 'ин'] +['ĠÙĪØ²', 'ارة'] +['Ġh', 'uyá»ĩn'] +['ĠÙĥ', 'تاب'] +['à¹ģà¸Ļ', 'à¹Īà¸Ļ'] +['à¹ģà¸Ļà¹Īà¸Ļ', 'à¸Ńà¸Ļ'] +['Ġgün', 'ü'] +['г', 'ÑĢÑĥз'] +['ĠاÙĦØ®', 'اص'] +['Ġgör', 'ül'] +['׾', '×ŀ×ĵ'] +['Ġìłķ', 'ëıĦ'] +['×ķ×ij', '×Ļ׾'] +['Ġ×ŀ×§', 'צ×ķ×¢×Ļ'] +['ĠоÑģоб', 'енно'] +['à¸Ľà¸£à¸°', 'à¸ģา'] +['à¸Ľà¸£à¸°à¸ģา', 'ศ'] +['aca', 'ģını'] +['ë¶', 'ģ'] +['à¸łà¸¹', 'มิ'] +['ĠÑį', 'лекÑĤ'] +['ĠÑįлекÑĤ', 'ÑĢо'] +['Ġ×§', 'ש×Ķ'] +['سÙĦ', 'Ø·'] +['à¸Ĭà¸Ļ', 'ะ'] +['×¢', '×Ļ׾'] +['ĠЧ', 'е'] +['à¹ģà¸Ļ', 'à¹Ī'] +['lı', 'ÄŁ'] +['lıģ', 'ın'] +['Ġ×ŀ×¢', '×¨×Ľ×ª'] +['好ãģį', 'ãģª'] +['มาà¸ģ', 'à¸Ĥึà¹īà¸Ļ'] +['×ŀ×¢', '×ijר'] +['ĠاÙĦÙħ', 'غرب'] +['ĠпеÑĢ', 'и'] +['ĠпеÑĢи', 'од'] +['Ġnh', 'ạc'] +['ا', 'ÙĪÙĬ'] +['ĠÙĪ', 'عÙĦÙī'] +['أخ', 'ذ'] +['ĠC', 'ô'] +['תר', '×ij×ķת'] +['×Ĵ', '×Ķ'] +['Ġktóre', 'j'] +['×IJ', '×Ļת'] +['×ij', '×ķ×IJ'] +['д', 'елÑĮ'] +['รี', 'วิ'] +['รีวิ', 'ว'] +['ж', 'Ñĥ'] +['Ġ×ij×Ĺ', '×ķ'] +['еÑĪ', 'ÑĮ'] +['ĠØ£', 'ÙĦÙģ'] +['ĠاÙĦÙĪ', 'Ø·ÙĨÙĬ'] +['ĠاÙĦÙħÙĨ', 'Ø·ÙĤØ©'] +['nÄħ', 'Äĩ'] +['Ġthi', 'ên'] +['иÑĩеÑģк', 'ой'] +['ĠاÙĦÙħ', 'ÙĦ'] +['Ġع', 'Ùħ'] +['ס', 'פר'] +['Ġnh', 'óm'] +['ÙĪØµ', 'Ùģ'] +['ĠCh', 'úng'] +['Ġر', 'ÙĤÙħ'] +['ãģ¾ãģĹãģŁ', 'ãģĮ'] +['al', 'ité'] +['ล', 'ม'] +['ĠëĤ´', 'ê°Ģ'] +['׾ק', '×ķ×Ĺ'] +['ĠS', 'Æ¡n'] +['pos', 'ição'] +['mi', 'ÄĻ'] +['Ġtr', 'ánh'] +['ĠÄIJ', 'á»Ļ'] +['׼', '×Ĺ'] +['ãģĤ', 'ãģ£ãģ¦'] +['à¸Ńย', 'à¹Īา'] +['Ġ×ŀ×Ĺ', '×Ļר'] +['Ġ×Ķ', '×Ļת×Ķ'] +['à¸Ľ', 'à¹Īา'] +['à¸Ńืà¹Īà¸Ļ', 'à¹Ĩ'] +['Ø´', 'ÙĤ'] +['×ł×¡', '×Ļ'] +['ë¦', '¼'] +['ãģ¦ãģĹãģ¾', 'ãģĨ'] +['Ġ×ŀ', 'צ×ij'] +['ãģ«', 'åĩº'] +['ÙħÙĪØ§', 'Ø·ÙĨ'] +['ยัà¸ĩ', 'มี'] +['алÑĮ', 'нÑĭе'] +['san', 'ız'] +['Ø¥', 'سرائÙĬÙĦ'] +['ĠvÃł', 'i'] +['ì¤', 'Ħ'] +['ã썿ĢĿ', 'ãģ£ãģ¦'] +['×Ļ', '×ķ׳×Ļ'] +['çĶŁ', 'ãģį'] +['Ġs', 'âu'] +['Ñĩ', 'иÑģÑĤ'] +['Ġl', 'á»ħ'] +['ĠGi', 'á'] +['à¸Ńุ', 'à¸Ľ'] +['à¸Ńà¸¸à¸Ľ', 'à¸ģร'] +['à¸Ńà¸¸à¸Ľà¸ģร', 'à¸ĵà¹Į'] +['Ġnh', 'ẹ'] +['r', 'ö'] +['ס', '×ĺ×Ļ'] +['ãģķãĤĵ', 'ãģĮ'] +['Ġd', 'ầu'] +['ع', 'Ùİ'] +['ت', 'را'] +['×Ĵ×ĵ', '׾'] +['Ġtécn', 'ica'] +['׼', '׳×Ļ×Ŀ'] +['תק', 'ש'] +['תקש', '×ķרת'] +['Ġн', 'его'] +['ét', 'ait'] +['Ġm', 'á»ģm'] +['Ñģ', 'еÑĤ'] +['Ġnh', 'áºŃt'] +['Ġ×ŀ', '×¢×ľ'] +['Ġ×Ķ×¢', '×ij×ķ×ĵ'] +['Ġ×Ķ×¢×ij×ķ×ĵ', '×Ķ'] +['Ġ×Ĵ', '×Ļ׾'] +['ãģ¯', 'ãģªãģĦ'] +['ائ', 'ØŃ'] +['Ġз', 'деÑģÑĮ'] +['×IJ', '×Ļ׳×ĺר'] +['Ùħ', 'ÙIJ'] +['Ġ×Ļ', '×Ĺ×ĵ'] +['ر', 'اÙģ'] +['ì²ĺ', '리'] +['×ĵ', '×¢×ķת'] +['ì¹', 'ľ'] +['ĠТ', 'о'] +['ĠTh', 'ế'] +['ì¶', '©'] +['Ġ׳׼', '×ķף'] +['عÙĬ', 'Ø´'] +['ни', 'з'] +['Ġج', 'اÙĨب'] +['×ŀ×§', 'צ×ķ×¢'] +['à¹Ĥ', 'à¸ĭ'] +['Ñģ', 'ÑĥÑĤ'] +['ìĸ´', 'ìļĶ'] +['ãĤĴè¦ĭ', 'ãģ¦'] +['ار', 'د'] +['Ġaç', 'ıl'] +['ĠاÙĦØŃ', 'ÙĬاة'] +['à¸ģà¹ĩ', 'à¹Ħà¸Ķà¹ī'] +['ãģĿãĤĮ', 'ãĤĴ'] +['عض', 'ÙĪ'] +['Ġг', 'ÑĢаж'] +['ĠгÑĢаж', 'дан'] +['à¸Īะ', 'à¸ķà¹īà¸Ńà¸ĩ'] +['ĠìĿ´', '룬'] +['ĠìĿ´ë٬', 'íķľ'] +['Ġtr', 'ách'] +['ÙĨ', 'Ùİ'] +['Ġkı', 'sa'] +['Ã', 'Ķ'] +['ÑĪ', 'ка'] +['ãģ®', '人'] +['ĠÐŁ', 'оÑģ'] +['ĠÐŁÐ¾Ñģ', 'ле'] +['Ñĥ', 'лÑĮ'] +['ÙĪØ§', 'جÙĩ'] +['ÙĤ', 'رب'] +['à¸Ľà¸ıิ', 'à¸ļัà¸ķิ'] +['ê°', 'Ļ'] +['Ġ×ŀ', '׳'] +['ĠÑģво', 'и'] +['بر', 'اÙħج'] +['Ġر', 'ÙĪ'] +['пÑĢ', 'од'] +['пÑĢод', 'аж'] +['Ġby', 'ÅĤy'] +['วั', 'ย'] +['Ġgör', 'ün'] +['ĠÃ', 'Ī'] +['ÑİÑī', 'им'] +['ĠÑĤак', 'ой'] +['Ùģ', 'ÙĪØ±'] +['ĠÙģ', 'عÙĦ'] +['Ġб', 'ел'] +['ëIJ', 'ł'] +['er', 'ÃŃa'] +['ĠÑģво', 'Ñİ'] +['Ġl', 'ã'] +['Ġlã', 'nh'] +['à¹Ģà¸ŀืà¹Īà¸Ń', 'à¹ĥหà¹ī'] +['ÙĤ', 'ÙĨ'] +['تط', 'ÙĪÙĬر'] +['Ġsay', 'ı'] +['ĠÑģ', 'ейÑĩаÑģ'] +['Ġ×IJ×Ĺר', 'ת'] +['×§', '×ķפ×Ķ'] +['×§×ķר', 'ס'] +['Ġس', 'Ùħ'] +['Ġ×ĺ', '×Ļפ×ķ׾'] +['ìĿ´ëĿ¼', 'ëĬĶ'] +['دراس', 'Ø©'] +['èµ·', 'ãģĵ'] +['×Ĺ', '×Ļ׳'] +['×Ĺ×Ļ׳', '×ķ×ļ'] +['×ĵ', '×§'] +['Ġë§', 'ŀ'] +['Ġком', 'анд'] +['ĠÐij', 'о'] +['Ġиг', 'ÑĢÑĭ'] +['à¸ļ', 'ี'] +['ĠØ£', 'Ùİ'] +['в', 'ен'] +['ĠاÙĦج', 'دÙĬد'] +['ĠÙĦ', 'Ø¥'] +['Ġ×ķ×IJ', '׳×Ļ'] +['Ġ×Ķס', '×Ļ'] +['иÑĩеÑģк', 'ого'] +['رÙĪ', 'ØŃ'] +['à¸ģาร', 'ศึà¸ģษา'] +['ĠTr', 'ưá»Ŀng'] +['иг', 'ÑĢа'] +['ıl', 'ması'] +['Ġм', 'аÑģÑģ'] +['ãģ¨ãģį', 'ãģ«'] +['à¸Ĺีà¹Ī', 'à¸ľà¹Īาà¸Ļ'] +['à¸Ĺีà¹Īà¸ľà¹Īาà¸Ļ', 'มา'] +['ĠاÙĦساب', 'ÙĤ'] +['Ġ×ŀ×¢', '×ĺ'] +['в', 'аÑĤÑĮ'] +['m', 'Ã¼ÅŁ'] +['Ġ׾', '׼×ļ'] +['Ġt', 'á»ĭch'] +['Ùģ', 'ÙĩÙħ'] +['تد', 'رÙĬب'] +['Ø´', 'Ùĥ'] +['Ġ×ij', '×ŀ×Ļ'] +['Ġ×ij×ŀ×Ļ', '×ķ×Ĺ×ĵ'] +['ÙĤØ·', 'اع'] +['ãģª', 'ãģĹ'] +['×ķצ', '×Ļ×IJ'] +['ĠÙĪ', 'سÙĬ'] +['з', 'Ñĥ'] +['Ġy', 'at'] +['Ġyat', 'ırım'] +['ë§', 'İ'] +['Ġth', 'ắng'] +['ãģĬ', '客'] +['ãģĬ客', 'æ§ĺ'] +['ĠThi', 'ên'] +['ãģ«å¯¾', 'ãģĹãģ¦'] +['ÑĢ', 'иÑģ'] +['ÙĨت', 'ائ'] +['ÙĨتائ', 'ج'] +['Ġ×ŀ', 'שר'] +['Ġ×ŀשר', '×ĵ'] +['Ġتع', 'اÙĦ'] +['ĠتعاÙĦ', 'Ùī'] +['ש', '׳×Ļ'] +['Ùĩ', 'اÙħ'] +['×IJ׳', 'ש×Ļ×Ŀ'] +['Ġżyc', 'ia'] +['ĠÑĢÑĥб', 'лей'] +['ÙĬ', 'ض'] +['Ġkat', 'ıl'] +['ĠÙħ', 'ÙĪØ¶ÙĪØ¹'] +['Ġvard', 'ır'] +['ĠÙħÙĨ', 'Ø·ÙĤØ©'] +['ĠTr', 'ần'] +['Ġв', 'еÑģ'] +['ü', 'p'] +['Ùħ', 'ÙĪÙĨ'] +['ÑĪ', 'ли'] +['Ġn', 'óng'] +['Ø®', 'ÙĦÙģ'] +['ĠС', 'ÑĤа'] +['Ġд', 'оÑĢ'] +['ĠдоÑĢ', 'ог'] +['ĠwÅĤa', 'ÅĽnie'] +['eÄŁ', 'in'] +['Ġhi', 'á»ĥm'] +['ĠС', 'ам'] +['ê»ĺ', 'ìĦľ'] +['ĠÑĦ', 'а'] +['ãģ»', 'ãģĨ'] +['ãģ»ãģĨ', 'ãģĮ'] +['×ķפ', '×Ļ×¢'] +['ê°', 'Ī'] +['د', 'ÙĪÙĦ'] +['Ġthu', 'ê'] +['Ġch', 'á»Ĺ'] +['Ġëĭ¹', 'ìĭł'] +['ãģij', 'ãĤĮ'] +['ãģijãĤĮ', 'ãģ©'] +['ë³´', 'íĺ¸'] +['ãģķãĤĮ', 'ãģ¦ãģĦãģ¾ãģĻ'] +['Ġнад', 'о'] +['ĠìĤ¬ëŀĮ', 'ëĵ¤'] +['à¹Ģà¸Ĥ', 'à¸ķ'] +['สม', 'ัย'] +['z', 'ÅĤ'] +['ت', 'ÙĪØ±'] +['Ġש', 'ת×Ļ'] +['v', 'ê'] +['Ġ×ijת', '×ķ×ļ'] +['à¸Ĭ', 'ัย'] +['ãģĦ', 'ãģ£ãģŁ'] +['ìĿ', 'ij'] +['Ġt', 'ầ'] +['Ġtầ', 'ng'] +['ש', '׼ר'] +['Ġê¸', 'Ģ'] +['Ġ×Ķש', '׳×Ķ'] +['Ġا', 'ÙĨÙĩ'] +['ç«ĭ', 'ãģ¡'] +['r', 'és'] +['füh', 'ren'] +['ر', 'ØŃÙħ'] +['ê·', '¹'] +['ĠâĢ', '«'] +['Ġsu', 'ất'] +['à¸Ł', 'ิ'] +['ÙĬ', 'Ùĩا'] +['ĠاÙĦ', 'اتØŃاد'] +['Ġt', 'uyá»ĥn'] +['ãģ¾', 'ãĤĭ'] +['Ġm', 'ại'] +['Ġng', 'ân'] +['ãĤ°', 'ãĥ©'] +['欲', 'ãģĹãģĦ'] +['س', 'ار'] +['ãĤĤãģ®', 'ãģ§ãģĻ'] +['ки', 'е'] +['Ġseç', 'im'] +['åħ¥', 'ãĤĬ'] +['ãģªãģ©', 'ãĤĴ'] +['ÑĤ', 'ÑĢи'] +['ĠÑģп', 'еÑĨ'] +['ĠØ£', 'د'] +['Ġод', 'но'] +['ÑĪ', 'ел'] +['ãĥĩ', 'ãĥ¼ãĤ¿'] +['ãĤ·', 'ãĤ¹ãĥĨ'] +['ãĤ·ãĤ¹ãĥĨ', 'ãĥł'] +['è¡Į', 'ãģį'] +['ã썿ĢĿ', 'ãģ£ãģŁ'] +['à¹Ģà¸ģิà¸Ķ', 'à¸Ĥึà¹īà¸Ļ'] +['ĠÑĤ', 'ож'] +['ĠÑĤож', 'е'] +['Ġs', 'ạch'] +['ĠÑģ', 'ÑĢок'] +['Ġкли', 'енÑĤ'] +['ĠÙħØ´', 'رÙĪØ¹'] +['Ġalt', 'ında'] +['Ġì', '·¨'] +['ä¸Ń', 'ãģ®'] +['ãģķãģĽ', 'ãĤĭ'] +['ãģĻ', 'ãģ¹'] +['ãģĻãģ¹', 'ãģ¦'] +['ê°ľ', 'ë°ľ'] +['ĠÄij', 'êm'] +['ãģªãģĦ', 'ãģ®ãģ§'] +['ì²', 'ł'] +['×¢', '×ij×ĵ'] +['Ġd', 'ấu'] +['à¸Ħà¸Ļ', 'à¸Ĺีà¹Ī'] +['ĠC', 'ách'] +['تع', 'ÙĦÙĬÙħ'] +['Ġh', 'ại'] +['ãĤ»', 'ãĥķãĥ¬'] +['ĠÙĨÙ쨳', 'Ùĩ'] +['ĠíĨµ', 'íķ´'] +['ÑĪ', 'ло'] +['Ġнап', 'ÑĢав'] +['ĠнапÑĢав', 'лен'] +['ÑĢÑĥ', 'Ñĩ'] +['íĶ', 'Į'] +['Ġ×ijר', '×Ļ×IJ'] +['ãģ®', 'ãģ¿'] +['ãģ«ãģĬ', 'ãģĦãģ¦'] +['×ij', '׳ק'] +['ãĤ¨', 'ãĥ³'] +['Ø«ÙĦ', 'اث'] +['Ġm', 'ỹ'] +['ĠÑģай', 'ÑĤе'] +['Ġе', 'мÑĥ'] +['ت', 'غÙĬ'] +['تغÙĬ', 'ÙĬر'] +['خص', 'ÙĪØµ'] +['ÑĤе', 'ли'] +['Ġ×ķ׾', '׼ף'] +['פע', '×Ŀ'] +['Ġпо', 'ÑįÑĤомÑĥ'] +['ر', 'اÙĨ'] +['иÑĤел', 'ей'] +['пиÑģ', 'ан'] +['×¢', '×¥'] +['ĠìĤ¬', 'ìĹħ'] +['Ùħ', 'ز'] +['جÙħ', 'ÙĬع'] +['ë©´', 'ìĦľ'] +['à¸ľà¸¥à¸´à¸ķ', 'à¸łà¸±'] +['à¸ľà¸¥à¸´à¸ķà¸łà¸±', 'à¸ĵ'] +['à¸ľà¸¥à¸´à¸ķà¸łà¸±à¸ĵ', 'à¸ij'] +['à¸ľà¸¥à¸´à¸ķà¸łà¸±à¸ĵà¸ij', 'à¹Į'] +['ĠпÑĢ', 'имеÑĢ'] +['ãĤŃ', 'ãĥ¼'] +['l', 'â'] +['Ġch', 'Äĥm'] +['缮', 'ãģ®'] +['ãģĦ', 'ãģĭ'] +['ãģ¨è¨Ģ', 'ãģĨ'] +['×ĸ', '×ķ×Ĵ'] +['Ġ×ij', '×ĵ×Ļ'] +['Ġ×ij×ĵ×Ļ', '×ķ×§'] +['ãģĬ', 'åºĹ'] +['à¸ķà¸Ńà¸Ļ', 'à¸Ļีà¹ī'] +['Ġph', 'á»iji'] +['п', 'ÑĤ'] +['สà¸Ļ', 'าม'] +['Ø·', 'ÙĪ'] +['ص', 'اØŃ'] +['صاØŃ', 'ب'] +['ĠD', 'ü'] +['ĠDü', 'nya'] +['Ġп', 'ока'] +['п', 'ал'] +['ĠÄij', 'ảo'] +['ĠاÙĦÙģ', 'ÙĪØ±'] +['ĠاÙĦÙģÙĪØ±', 'Ùĥس'] +['Ġmá', 'u'] +['кÑĢ', 'еп'] +['ĠاÙĦس', 'اعة'] +['ĠгоÑĢ', 'ода'] +['Ùģ', 'صÙĦ'] +['ай', 'ÑĤе'] +['Ġд', 'ог'] +['Ġдог', 'овоÑĢ'] +['ĠØ¥', 'ذ'] +['Ġ×ij׼׾', '׾'] +['ÙĬ', 'تÙĩ'] +['×Ĵ', '×ijר'] +['Ġbir', 'ç'] +['Ġbirç', 'ok'] +['문', 'íĻĶ'] +['ãģĿãģĨ', 'ãģª'] +['را', 'ØŃ'] +['ĠÙħ', 'رة'] +['ĠденÑĮ', 'ги'] +['f', 'ä'] +['à¸Ĥà¹īา', 'ว'] +['ĠÑģов', 'ÑĢем'] +['ĠÑģовÑĢем', 'енн'] +['׾×Ĺ', '×¥'] +['èī¯', 'ãģı'] +['ĠÙģ', 'Ø£'] +['Ġ×ķ', '×ĸ×Ķ'] +['Ġз', 'ани'] +['Ġзани', 'ма'] +['Ġê°Ģì§Ģ', 'ê³ł'] +['Ġh', 'Æ¡i'] +['ãģªãģ®', 'ãģĭ'] +['ãĥĨ', 'ãĥ¬ãĥĵ'] +['Ġר', '×ij×ķת'] +['à¸ķ', 'ี'] +['Ġ×ijש', '×ł×ª'] +['ĠT', 'ại'] +['Ġthu', 'áºŃn'] +['Ñģ', 'ел'] +['Ñij', 'м'] +['dzi', 'Äĩ'] +['ĠÑģ', 'ка'] +['ĠÑģка', 'Ñĩ'] +['ĠÑģкаÑĩ', 'аÑĤÑĮ'] +['×ķ×ŀ', '×ķ'] +['г', 'ла'] +['Ġмин', 'ÑĥÑĤ'] +['åĩº', 'ãģĻ'] +['Ġ×Ĺ×Ļ', '×Ļ×ij'] +['Ġת', '×Ĵ×ķ×ij×Ķ'] +['à¸£à¸¹à¸Ľ', 'à¹ģà¸ļà¸ļ'] +['ни', 'ÑĨа'] +['Ġİ', 'n'] +['ĠØ£', 'ع'] +['Ġض', 'ÙħÙĨ'] +['Ùħ', 'ثاÙĦ'] +['ĠyaÅŁ', 'an'] +['ĠìŰ', '구'] +['ĠL', 'ê'] +['ש׾', '×Ĺ'] +['ãģı', 'ãģªãĤĭ'] +['ìĹĨ', 'ìĿ´'] +['ĠÑĤ', 'ÑĢи'] +['ĠÑĩаÑģÑĤ', 'о'] +['Ġоб', 'ÑĢаÑĤ'] +['п', 'ло'] +['د', 'Ø®'] +['دخ', 'ÙĪÙĦ'] +['س', 'Ùĩ'] +['à¸Ń', 'าà¸ģ'] +['à¸Ńาà¸ģ', 'าศ'] +['Ġ׼', '×ĸ×Ķ'] +['Ġ×Ķ×¢', 'סק'] +['ĠاÙĦØ£', 'ÙĨ'] +['å¹´', 'ãģ«'] +['×¢', 'ש×ķ'] +['Ġש', '×¢×ķת'] +['Ġm', 'Ãłn'] +['×IJר', '×Ļ'] +['sı', 'yla'] +['Ù쨱', 'ÙĤ'] +['ни', 'Ñħ'] +['Ġت', 'ست'] +['è¦ĭ', 'ãģ¦'] +['ØŃا', 'ÙĪÙĦ'] +['×IJ', '×Ļ׼×ķת'] +['ĠbaÅŁ', 'ladı'] +['st', 'Äħ'] +['stÄħ', 'pi'] +['à¸Ĺีà¹Ī', 'à¹Ģรา'] +['ÙĤر', 'ر'] +['ج', 'اب'] +['Ġ×ijר', '×ķר'] +['à¹Ģà¸Ĥà¹īา', 'à¹ĥà¸Ī'] +['×ŀ×Ĺ', 'קר'] +['al', 'ım'] +['Ġס', '×Ļפ×ķר'] +['ãģ§ãģĤ', 'ãĤĮãģ°'] +['Ġש×ŀ', '×ķר×ķת'] +['Ġ×ķ', '×ŀ×Ķ'] +['ãģĵ', 'ãģĿ'] +['id', 'ée'] +['ä¸ĭ', 'ãģķãģĦ'] +['تÙĨا', 'ÙĪÙĦ'] +['Ġ', 'ลà¹īาà¸Ļ'] +['Ġìļ°ë¦¬', 'ëĬĶ'] +['اÙĨ', 'ا'] +['ÑģÑĤ', 'ой'] +['б', 'оÑĤ'] +['ĠyaÅŁ', 'am'] +['kö', 'y'] +['Ø¥', 'ÙĦ'] +['ÑĢ', 'Ñĭв'] +['기', 'ìĹħ'] +['Ġ×Ķ×ŀ', '×ĵ'] +['Ġ×Ķ×ŀ×ĵ', '×Ļ׳×Ķ'] +['د', 'ب'] +['×¢', '×Ļ׳×Ļ'] +['×ŀ', 'ת×Ĺ'] +['Ġפ', 'ר×Ļ'] +['ãĥĭ', 'ãĥ¼'] +['اÙħ', 'ÙĬ'] +['Ġnh', 'ằm'] +['ãĤĮ', 'ãģªãģĦ'] +['ت', 'عرÙģ'] +['Ġë§Ī', 'ìĿĮ'] +['ìĵ', '°'] +['Ġh', 'ấp'] +['ר×Ĵ', '×Ļ׾'] +['ب', 'Ùİ'] +['Ġr', 'Äĥng'] +['gl', 'Äħd'] +['ĠÑģиÑģÑĤем', 'Ñĭ'] +['Ġkh', 'óa'] +['ãģ§ãģĻ', 'ãĤĪãģŃ'] +['大ãģį', 'ãģı'] +['기', '를'] +['Ġké', 'o'] +['ÙĪ', 'Ø¡'] +['ج', 'اÙħ'] +['جاÙħ', 'ع'] +['Ġ×¢', '×Ļצ×ķ×ij'] +['t', 'éri'] +['Ġת', 'ש'] +['Ġ×IJ', '×ij×Ļ'] +['ĠCh', 'ương'] +['à¸ļริ', 'à¹Ģว'] +['à¸ļริà¹Ģว', 'à¸ĵ'] +['ãģ¤', 'ãģı'] +['Ġ×Ĺ', '×ķ׾'] +['עת', '×Ļ×ĵ'] +['ש', '×Ļ×ŀ×Ķ'] +['ëĤ', '¨'] +['Ġש×IJ', '×Ļף'] +['ĠÙĪØ§ÙĦ', 'Ø¥'] +['ÑĦ', 'а'] +['Ġkh', 'ám'] +['Ġ×ĺ', '×ķ×ij×Ķ'] +['ĠвÑĭ', 'Ñģ'] +['ĠвÑĭÑģ', 'око'] +['ĠاÙĦØŃ', 'دÙĬØ«'] +['人', 'ãĤĤ'] +['d', 'Ã¼ÄŁÃ¼'] +['×Ļ×Ĺ', '×ķ×ĵ'] +['تع', 'ÙĦÙĬ'] +['تعÙĦÙĬ', 'ÙĤ'] +['l', 'ö'] +['تØŃ', 'دÙĬد'] +['н', 'его'] +['ĠÑĥд', 'об'] +['Ġ׾', '×ŀ×Ļ'] +['Ġר', '×ķצ×Ļ×Ŀ'] +['Ġج', 'اء'] +['Ġ×ij', '×ĸ×ŀף'] +['à¸Ľà¸ģ', 'à¸ķิ'] +['é«ĺ', 'ãģı'] +['à¸Ľà¸¥', 'า'] +['Ġart', 'ık'] +['Ġbug', 'ün'] +['×§', '׳×Ļ'] +['Ġkho', 'á'] +['ĠÙħ', 'رÙĥز'] +['ĠìŀIJ', '기'] +['در', 'جة'] +['×ŀש', 'ר×ĵ'] +['Ġgi', 'ấy'] +['Ġch', 'óng'] +['×§', 'פ'] +['ÙĬب', 'Ø©'] +['ĠczÄĻ', 'sto'] +['в', 'али'] +['Ùĥ', 'ب'] +['ìŁ', 'ģ'] +['ส', 'à¸ļาย'] +['à¸Ľà¸£à¸°à¸Ĭา', 'à¸Ĭà¸Ļ'] +['×Ĵ', '×ķ×£'] +['ëŁ', 'ī'] +['ãģ®', 'ãģĵãģ¨'] +['ล', 'à¸Ń'] +['Ġngh', 'á»ī'] +['åŃIJ', 'ãģ©'] +['åŃIJãģ©', 'ãĤĤ'] +['à¹Ħà¸Ķ', 'à¹īà¸Ńย'] +['à¹Ħà¸Ķà¹īà¸Ńย', 'à¹Īาà¸ĩ'] +['×ĵ', '×¢'] +['ĠاÙĦت', 'Ùī'] +['ĠÑģов', 'еÑĤ'] +['Ġqual', 'itÃł'] +['åĩº', 'ãģĹ'] +['ĠÑĢÑĥк', 'ов'] +['ĠÑĢÑĥков', 'од'] +['ราย', 'ละà¹Ģà¸Ńียà¸Ķ'] +['ãģªãģĭ', 'ãģªãģĭ'] +['기', 'ê´Ģ'] +['Ġ×Ĺ', '×ķש'] +['Ġ×Ĺ×ķש', '×ij'] +['л', 'оÑĤ'] +['à¸Ļะ', 'à¸Ħรัà¸ļ'] +['×§×ij', '×ķצ×Ķ'] +['Ġth', 'ái'] +['Ġש', '×ij×Ķ'] +['ĠÑĪ', 'кол'] +['ĠÙĦ', 'ÙĥÙĦ'] +['à¹ĥà¸Ļ', 'à¸Ĭà¹Īวà¸ĩ'] +['ĠÙħ', 'ÙĥاÙĨ'] +['ë', 'ķĮ'] +['Ġc', 'ải'] +['ĠCh', 'ÃŃ'] +['ÑĥÑĩ', 'а'] +['ìĿ', 'µ'] +['Ġx', 'ảy'] +['à¸Ĭà¸Ļ', 'ิà¸Ķ'] +['Ġc', 'áºŃu'] +['к', 'ÑĢов'] +['ss', 'é'] +['ĠÙĨ', 'ÙĪØ¹'] +['ĠТ', 'а'] +['Ø®', 'Ùħس'] +['פ×ķס', '×ĺ'] +['Ġm', 'ắc'] +['ĠÄij', 'em'] +['à¸ģาร', 'à¹ĥà¸Ĭà¹ī'] +['ר', '×ķס'] +['ĠÐĽ', 'е'] +['Ġth', 'á»Ń'] +['รà¹Īาà¸ĩ', 'à¸ģาย'] +['üz', 'ü'] +['æĹ¥æľ¬', 'ãģ®'] +['ê³¼', 'ìłķ'] +['ש', '×Ļ×IJ'] +['ĠìŀĪ', 'ê³ł'] +['×ij', '×ķ׾'] +['ìķ', 'ħ'] +['ĠÙĪØ§ÙĦ', 'ا'] +['ĠÐĽ', 'и'] +['ĠвÑģ', 'Ñij'] +['Ġużytk', 'ow'] +['×Ĺ', '×ķ׾'] +['ر', 'Ù쨶'] +['Ġson', 'uç'] +['ãģĦ', 'ãģ¾ãģĽãĤĵ'] +['ìĤ¬', 'ìĹħ'] +['ëĪ', 'Ħ'] +['ÑĤ', 'ек'] +['Ġud', 'ziaÅĤ'] +['л', 'ез'] +['Ġ×Ķ×Ļ', '×Ļת×Ļ'] +['ãĤīãĤĮ', 'ãģ¦'] +['Ùħس', 'ؤÙĪÙĦ'] +['ر', 'ار'] +['ÑĤ', 'ан'] +['ĠÄij', 'Ãło'] +['Ġר', '×ķ×ij'] +['Ġ×ijש×ij', '×Ļ׾'] +['ä»ĬåĽŀ', 'ãģ¯'] +['ãĤ¸', 'ãĥ¥'] +['Ġ×¢', '×ijר'] +['ãģĽ', 'ãģ¦'] +['п', 'олÑĮ'] +['ak', 'lı'] +['Ġk', 'ÃŃnh'] +['د', 'ت'] +['лож', 'ение'] +['ĠاÙĦÙħ', 'ص'] +['ĠاÙĦÙħص', 'رÙĬ'] +['à¸Īริà¸ĩ', 'à¹Ĩ'] +['ĠاÙĦشر', 'ÙĥØ©'] +['ĠÄij', 'á»ı'] +['ãĥĽ', 'ãĥĨ'] +['ãĥĽãĥĨ', 'ãĥ«'] +['Ñį', 'кон'] +['Ñįкон', 'ом'] +['ĠÙĪ', 'عÙĨ'] +['Ġת', '׳'] +['Ġ×ª×ł', '×IJ×Ļ'] +['ĠاÙĦدÙĪÙĦ', 'ÙĬØ©'] +['Ġì§Ģ', 'ìĹŃ'] +['ãģ§ãģĻ', 'ãģĭ'] +['Ġв', 'аÑĢи'] +['ĠваÑĢи', 'анÑĤ'] +['ĠاÙĦع', 'رب'] +['ел', 'а'] +['Ġt', 'Æ°á»Ľng'] +['sk', 'Äħ'] +['Ġm', 'ặc'] +['ส', 'ัà¸ģ'] +['ãĥĵ', 'ãĥ¼'] +['Ġ×ij', '×Ĵ׾'] +['Ġ×ij×Ĵ׾', '׾'] +['ãĥķãĤ¡', 'ãĥ³'] +['×ij', '×Ļצ'] +['×ij×Ļצ', '×ķ×¢'] +['ли', 'ÑģÑĤ'] +['à¸Ł', 'ุ'] +['à¸Łà¸¸', 'à¸ķ'] +['à¸Łà¸¸à¸ķ', 'à¸ļà¸Ńล'] +['à¸Ŀ', 'à¹Īาย'] +['ìŀIJ', 'ìĿĺ'] +['Ġس', 'ÙĪÙģ'] +['Ġש', '×Ķת'] +['Ġê±', '¸'] +['×¢', '×ij×ķ×ĵ'] +['ãģĻãĤĭ', 'ãģĵãģ¨ãģĮ'] +['ĠÑĩа', 'ÑģÑĤÑĮ'] +['ãĤ¢', 'ãĥ¡ãĥª'] +['ãĤ¢ãĥ¡ãĥª', 'ãĤ«'] +['Ġtak', 'ım'] +['Ġs', 'Ỽ'] +['ĠsỼ', 'm'] +['שר', '×Ķ'] +['è¨Ģ', 'ãģĨ'] +['л', 'ан'] +['ì»', '¤'] +['׼', '׳×Ķ'] +['ÙĪÙģ', 'ÙĬ'] +['íĹ', 'Ī'] +['lu', 'ÄŁu'] +['ĠëĮĢ', 'íķ´'] +['Ġ׾×ij', '×Ļת'] +['Ġ×Ķר×IJש', '×ķ׳×Ķ'] +['ص', 'Ùħ'] +['Ġsö', 'yled'] +['Ġsöyled', 'i'] +['à¸Ľ', 'าà¸ģ'] +['Ġard', 'ından'] +['ãģĪ', 'ãģŁ'] +['à¸Ĺัà¹Īว', 'à¹Ħà¸Ľ'] +['Ġ׳×ķס', '×£'] +['б', 'олÑĮ'] +['ãĤĵãģ§ãģĻ', 'ãģijãģ©'] +['ĠлиÑĪ', 'ÑĮ'] +['Ġ×ij', '×IJ×Ļ'] +['ĠбÑĭ', 'ÑģÑĤÑĢо'] +['ส', 'ัà¸Ļ'] +['Ġ×ij', 'פ׳×Ļ'] +['л', 'еÑĩ'] +['ĠاÙĦØ®', 'بر'] +['Ġsó', 'c'] +['Ġth', 'ú'] +['Ġп', 'ÑıÑĤ'] +['ãģĬ', 'é¡ĺ'] +['ãģĬé¡ĺ', 'ãģĦ'] +['ÑĤ', 'ин'] +['ãģ«ãģ¤ãģĦãģ¦', 'ãģ¯'] +['פ', 'ף'] +['Ġдв', 'ÑĥÑħ'] +['à¸į', 'ีà¹Ī'] +['à¸įีà¹Ī', 'à¸Ľ'] +['à¸įีà¹Īà¸Ľ', 'ุ'] +['à¸įีà¹Īà¸Ľà¸¸', 'à¹Īà¸Ļ'] +['оп', 'еÑĢ'] +['ĠاÙĦب', 'شر'] +['ĠاÙĦÙħ', 'اÙĦ'] +['ıyor', 'uz'] +['تØŃ', 'ÙħÙĬÙĦ'] +['à¸ģ', 'ะ'] +['éĸĵ', 'ãģ«'] +['×Ĺ', '×ķש'] +['ĠNg', 'uyên'] +['ãģĦãģ¦', 'ãģĦãĤĭ'] +['дÑĥ', 'ÑĪ'] +['ש', 'פע'] +['ÑĪ', 'Ñĥ'] +['å®Ł', 'éļĽãģ«'] +['ĠÑĢай', 'он'] +['ĠCh', 'á»ī'] +['ÙĨ', 'صر'] +['Ġìļ', '´'] +['Ġìļ´', 'ìĺģ'] +['Ġ×Ķ×ĵ', '×Ļף'] +['ØŃد', 'د'] +['ر', 'ز'] +['ĠاÙĦد', 'Ùħ'] +['ĠPh', 'áp'] +['ÑĤ', 'ÑģÑı'] +['è¦ĭ', 'ãģĪ'] +['Ġti', 'á»ĥu'] +['Ġs', 'á»Ńa'] +['а', 'ÑİÑĤÑģÑı'] +['ĠB', 'á'] +['Ġ×ķ', '׼׾'] +['Ð', 'ĸ'] +['ÑĪ', 'им'] +['ìĿ´', 'ëĬĶ'] +['л', 'ев'] +['d', 'ık'] +['Ġprés', 'ente'] +['Ġara', 'ç'] +['صد', 'ÙĤ'] +['Ġпом', 'ог'] +['ĠاÙĦشر', 'ÙĤ'] +['ĠÙĪØ§ÙĦ', 'ذÙĬ'] +['رÙĬ', 'ا'] +['×ij', '׳×ķת'] +['Ġng', 'á»ĵi'] +['ר', '×ķפ'] +['ר×ķפ', '×IJ'] +['Ġth', 'ấp'] +['ãĤĦ', 'ãģ¯'] +['ãĤĦãģ¯', 'ãĤĬ'] +['ĠاÙĦج', 'دÙĬدة'] +['éĿŀ常', 'ãģ«'] +['ÙĬÙĦ', 'ÙĬ'] +['ìª', '½'] +['تع', 'اÙħÙĦ'] +['ãģł', 'ã썿ĢĿãģĦãģ¾ãģĻ'] +['Ùħ', 'Ùħ'] +['иÑĤе', 'ли'] +['ãĤµãĤ¤', 'ãĤº'] +['اد', 'ات'] +['ĠاÙĦÙħ', 'اÙĦÙĬØ©'] +['Ùĥات', 'ب'] +['к', 'ли'] +['веÑĢ', 'Ñħ'] +['ни', 'Ñĩ'] +['Ġ×ľ×¢', '×ij×ķ×ĵ'] +['׾', '×Ļ×Ķ'] +['ØŃ', 'Ùİ'] +['ãĤ¤', 'ãĥĻ'] +['ãĤ¤ãĥĻ', 'ãĥ³ãĥĪ'] +['Ġת', '×Ĵ×ķ×ij×ķת'] +['ÑĦ', 'он'] +['ĠдÑĢÑĥг', 'ие'] +['×IJ', '×ĸ×ķר'] +['Ġper', 'ò'] +['ìķ', 'ŀ'] +['åĢŁ', 'ãĤĬ'] +['ר', 'צ×Ļ'] +['×IJ', '×ĸ'] +['алÑĮ', 'нÑĭÑħ'] +['Ġê²ĥ', 'ìľ¼ë¡ľ'] +['ĠпÑĢав', 'о'] +['ĠاÙĦØ£', 'رض'] +['à¹Ģà¸Ĺ', 'à¸Ħ'] +['à¹Ģà¸Ĺà¸Ħ', 'à¹Ĥà¸Ļ'] +['à¹Ģà¸Ĺà¸Ħà¹Ĥà¸Ļ', 'à¹Ĥล'] +['à¹Ģà¸Ĺà¸Ħà¹Ĥà¸Ļà¹Ĥล', 'ย'] +['à¹Ģà¸Ĺà¸Ħà¹Ĥà¸Ļà¹Ĥลย', 'ี'] +['צ', 'ר×Ļ'] +['ĠÐļ', 'Ñĥ'] +['ıl', 'ma'] +['決', 'ãĤģ'] +['ا', 'ÙĪ'] +['Ġ×ĵ', '×§×ķת'] +['à¸Ħร', 'ู'] +['ĠÙħست', 'ÙĪÙī'] +['à¸Ľ', 'à¹īà¸Ńà¸ĩ'] +['à¸Ľà¹īà¸Ńà¸ĩ', 'à¸ģัà¸Ļ'] +['×ĵ', '×ķ×ŀ×Ķ'] +['ĠÑģ', 'егоднÑı'] +['س', 'ÙĪÙĤ'] +['ר×Ĺ', '×ķ×ij'] +['ĠØ¥', 'دارة'] +['Ñħ', 'ож'] +['éģİ', 'ãģİ'] +['à¸Ħ', 'à¸Ń'] +['нÑĥ', 'л'] +['×ķ׼', '×Ķ'] +['ÙĪ', 'اÙģÙĤ'] +['׼׾', '׾'] +['Ġ×Ķ', '×ĵ×ķ'] +['Ġl', 'Ä©nh'] +['Ġkh', 'ảo'] +['×IJ×ŀ', 'צע'] +['ë¨', '¸'] +['Ġ׼', '×Ļצ'] +['Ġ׼×Ļצ', '×ĵ'] +['Ġдолж', 'нÑĭ'] +['หว', 'ัà¸ĩ'] +['ãĥĩ', 'ãĤ¶'] +['ãĥĩãĤ¶', 'ãĤ¤ãĥ³'] +['Ġng', 'á»Ŀ'] +['ä¸Ń', 'ãģ«'] +['à¸ģลัà¸ļ', 'มา'] +['جÙħ', 'اÙĦ'] +['à¸Ķัà¸ĩ', 'à¸ģลà¹Īาว'] +['س', 'ÙĥÙĨ'] +['س', 'ÙĨ'] +['Ġözellik', 'le'] +['з', 'еÑĢ'] +['rz', 'ÄĻ'] +['×ŀ', '×ķר×Ķ'] +['Ġl', 'ạ'] +['×ŀ', '×Ļ׳×Ļ'] +['ר', '×Ļת'] +['ãģĿãĤĮ', 'ãģĮ'] +['ãģĭ', 'ãĤĮ'] +['ĠÙĬÙħÙĥÙĨ', 'Ùĥ'] +['öff', 'entlich'] +['г', 'ан'] +['ĠاÙĦØŃ', 'ÙĦ'] +['ĠmiÄĻd', 'zy'] +['ĠÑĩа', 'ÑģÑĤи'] +['ujÄħ', 'cy'] +['ĠbaÄŁ', 'lı'] +['ĠiliÅŁ', 'ki'] +['Ùģ', 'اء'] +['ãĥª', 'ãĥ³ãĤ°'] +['Ġhã', 'ng'] +['ĠконÑĤ', 'ÑĢ'] +['ĠконÑĤÑĢ', 'ол'] +['к', 'оп'] +['ש', '×Ļ×¢'] +['ש×Ļ×¢', '×ķר'] +['ĠÐĴ', 'аÑĪ'] +['Ġ×Ķ', 'תק'] +['ÙħÙĨ', 'ع'] +['ĠpolÃŃt', 'ico'] +['Ġг', 'олов'] +['ĠØ¥', 'ÙĬ'] +['Ø¥', 'ÙĨتاج'] +['à¸ļ', 'ิ'] +['Ġг', 'овоÑĢ'] +['ĠговоÑĢ', 'иÑĤ'] +['Ġph', 'á»ķ'] +['ĠÑģем', 'ÑĮ'] +['ãģ¯', 'ãģĤãĤĬãģ¾ãģĽãĤĵ'] +['ĠÙĪ', 'است'] +['×ŀש', 'פ×ĺ'] +['з', 'ем'] +['×ŀ×ĵ', '×ijר'] +['Ġíģ', '°'] +['ĠìĿ´', 'ë²Ī'] +['ê°Ģ', 'ëĬĶ'] +['Ġì§Ģ', 'ìĽIJ'] +['Ġca', 'ÅĤy'] +['Ġgeli', 'ÅŁtir'] +['Ñģк', 'ое'] +['pos', 'é'] +['Ġkh', 'ô'] +['à¸ķิà¸Ķ', 'à¸ķาม'] +['miss', 'ão'] +['Ġ׾', '×ŀר'] +['Ġ׾×ŀר', '×ķת'] +['Ġb', 'ó'] +['à¸ķรวà¸Ī', 'สà¸Ńà¸ļ'] +['Ġngh', 'á»ģ'] +['Ġб', 'из'] +['Ġбиз', 'неÑģ'] +['ÑģÑĤ', 'еÑĢ'] +['ÙĪ', 'Ùİ'] +['楽', 'ãģĹãģ'] +['楽ãģĹãģ', '¿'] +['ãģĵãĤĮ', 'ãģĭãĤī'] +['wiÄħ', 'zan'] +['ส', 'à¸Ńà¸Ļ'] +['Ùħ', 'ÙĪØ±'] +['׳×ĵ', '׾'] +['Ġ×Ķ×IJ', '×ĵ×Ŀ'] +['Ġм', 'олод'] +['ØŃ', 'Ùħا'] +['ØŃÙħا', 'ÙĬØ©'] +['ÑģÑĤ', 'ÑĢан'] +['Ġbu', 'á»ķi'] +['ת×Ļ', '×Ļ×Ŀ'] +['abile', 'ceÄŁi'] +['L', 'İ'] +['à¹Ģย', 'à¸Ńะ'] +['à¸Ī', 'ร'] +['س', 'ÙĥاÙĨ'] +['à¸Ļ', 'ัà¸Ķ'] +['Ġm', 'ấy'] +['ĠÐij', 'а'] +['s', 'ÅĤaw'] +['ĠÙģ', 'ÙĦا'] +['ĠкоÑĤоÑĢ', 'ой'] +['Ġпло', 'Ñī'] +['ĠплоÑī', 'ад'] +['ãĤĤ', 'ãģĤãĤĬ'] +['sz', 'czÄĻ'] +['×Ļפ', '×ķ'] +['ש×ŀ', 'ת'] +['owa', 'ÅĤa'] +['Ġn', 'ông'] +['צ×ij', '×IJ'] +['ĠìŀĪ', 'ìĹĪ'] +['ãģ¾', 'ãģ¨'] +['ãģ¾ãģ¨', 'ãĤģ'] +['ÙĤÙĪ', 'ات'] +['ãģ¿', 'ãĤĵãģª'] +['Ġ׼', '×ŀ×¢×ĺ'] +['Ġx', 'úc'] +['ï¼', 'Ĩ'] +['r', 'ÄĻ'] +['rÄĻ', 'cz'] +['×ĵ', '×ŀ×Ļ'] +['Ġt', 'áºŃn'] +['à¸Ķ', 'วà¸ĩ'] +['ê²½', 'ìłľ'] +['п', 'ÑĥÑĤ'] +['Ø£', 'ربع'] +['Ġ×ŀ', 'שת×ŀש'] +['ãĤ¿ãĤ¤', 'ãĥĹ'] +['Ġìłľ', 'ê°Ģ'] +['Ġ׾', '׼ף'] +['ĠобÑĢаз', 'ом'] +['ÙĬÙĥ', 'ا'] +['w', 'ÅĤ'] +['wÅĤ', 'asn'] +['ĠاÙĦÙĪØ·ÙĨ', 'ÙĬØ©'] +['بÙĬ', 'ب'] +['×ŀ', '׾×Ļ'] +['к', 'ÑĢаÑĤ'] +['기', 'ìĹIJ'] +['ÙĤ', 'اد'] +['ĠÙĦ', 'دÙī'] +['à¸Ħวาม', 'รูà¹ī'] +['×ŀ×ĵ×Ļ׳', '×Ļ×ķת'] +['ê²', '¨'] +['Ġíĺ', 'Ħìŀ¬'] +['ש', 'ת×Ļ'] +['м', 'ол'] +['Ġmá', 'i'] +['à¸ŀิ', 'ม'] +['à¸ŀิม', 'à¸ŀ'] +['à¸ŀิมà¸ŀ', 'à¹Į'] +['หล', 'วà¸ĩ'] +['Ġx', 'uyên'] +['×Ĺ', 'סר'] +['رÙĪ', 'ÙĨ'] +['ãģĿãģĨ', 'ãģĦãģĨ'] +['ãģĿãĤĮ', 'ãģŀ'] +['ãģĿãĤĮãģŀ', 'ãĤĮ'] +['Ġ׼', 'ש×Ķ'] +['ÐŁ', 'ÑĢав'] +['×ŀ×ij', 'צע'] +['ع', 'رب'] +['Ġbü', 'yü'] +['פ×Ļת', '×ķ×Ĺ'] +['à¸Ī', 'à¸ļ'] +['ĠØ£', 'Ùĥبر'] +['שר', 'ת'] +['×ŀ׼', 'ש×Ļר'] +['ĠÙĪ', 'Ùħع'] +['ãģ®', 'ãģŁãĤģãģ«'] +['à¸Ļ', 'ัà¸ļ'] +['ì°', '°'] +['ãĥª', 'ãĥķãĤ©'] +['ãĥªãĥķãĤ©', 'ãĥ¼ãĥł'] +['Ġc', 'ưá»Ŀng'] +['ĠìłĢ', 'íĿ¬'] +['ÙħÙĨظ', 'ÙħØ©'] +['Ġhiç', 'bir'] +['ãģ§ãģ¯', 'ãģĤãĤĬãģ¾ãģĽãĤĵ'] +['ร', 'à¸Ńย'] +['ëIJľ', 'ëĭ¤'] +['ãģĻãģIJ', 'ãģ«'] +['к', 'ла'] +['Ġürün', 'ler'] +['Ġki', 'á»ĥu'] +['ĠëĤĺ', 'ëĬĶ'] +['ÑĤ', 'ки'] +['Ñģ', 'им'] +['Ġchá»ī', 'nh'] +['ãĤĤ', 'ãģªãģĦ'] +['ศ', 'รี'] +['æĽ¿', 'ãģĪ'] +['ta', 'ÅŁ'] +['Ġب', 'ÙĥÙĦ'] +['Ġ×ķ', '×Ļש'] +['vis', 'ão'] +['ä¼', 'Ŀ'] +['ä¼Ŀ', 'ãģĪ'] +['ÙĦ', 'د'] +['׾', '×Ļ×ŀ'] +['׾×Ļ×ŀ', '×ķ×ĵ'] +['t', 'ória'] +['د', 'Ùij'] +['اÙħ', 'ر'] +['Ġê·¸ëłĩ', 'ê²Į'] +['Ġmateria', 'ÅĤ'] +['à¸Ĺ', 'รา'] +['à¸Ĺรา', 'à¸ļ'] +['ã쮿ĸ¹', 'ãģĮ'] +['ãģ¦', 'ãģįãģŁ'] +['ض', 'غ'] +['ضغ', 'Ø·'] +['ĠÙĬ', 'عÙĨÙĬ'] +['ел', 'о'] +['×IJ×Ķ', '×ij×Ķ'] +['×¢', '×ŀ'] +['ÅŁ', 'ık'] +['ìŀIJ', 'ëĬĶ'] +['ãĤ¿', 'ãĥ³'] +['Ġb', 'áºŃt'] +['×ŀשפ', '×Ĺ×Ķ'] +['к', 'ÑĢи'] +['б', 'ли'] +['สั', 'à¸ķ'] +['สัà¸ķ', 'วà¹Į'] +['ĠسÙĨ', 'ÙĪØ§Øª'] +['ĠPh', 'ương'] +['ãģ¦ãģĹãģ¾', 'ãģ£ãģŁ'] +['ãģª', 'ãģľ'] +['Ġ×ij×IJ', '×ķ'] +['Ġc', 'án'] +['س', 'جÙĦ'] +['Ġl', 'ẽ'] +['ãĤ±', 'ãĥ¼ãĤ¹'] +['Ġ×§', '×Ļ×ij׾'] +['à¸ļà¸Ĺ', 'à¸Ħวาม'] +['Ġ×ķ', '׼ף'] +['ĠпÑĢедÑģÑĤав', 'лен'] +['Ġn', 'á»iji'] +['Ġcoment', 'ário'] +['ени', 'ем'] +['Ġtá»', 'ı'] +['l', 'Ãł'] +['Ġש×Ķ', '×Ļ×Ķ'] +['Ñģл', 'ав'] +['ĠاÙĦ', 'ÙĪÙĦا'] +['ĠاÙĦÙĪÙĦا', 'ÙĬات'] +['ÙĦج', 'ÙĨØ©'] +['×§×ķר', '×IJ'] +['бÑĭ', 'ÑĤ'] +['Ġì', '¦'] +['Ġì¦', 'ī'] +['ãģ§ãģĻ', 'ãģĹ'] +['หรืà¸Ń', 'à¹Ħมà¹Ī'] +['за', 'ÑīиÑĤ'] +['ÙģÙĦ', 'سطÙĬÙĨ'] +['Ġmi', 'á»ħn'] +['à¹Ģย', 'à¹ĩà¸Ļ'] +['ĠçalÄ±ÅŁ', 'an'] +['×Ļ×Ĵ', '×Ķ'] +['ĠE', 'ÄŁ'] +['ĠEÄŁ', 'itim'] +['ãĥĥãĤ·', 'ãĥ¥'] +['Ġоп', 'Ñĭ'] +['ĠопÑĭ', 'ÑĤ'] +['ر', 'غ'] +['رغ', 'ب'] +['ĠÑģво', 'иÑħ'] +['à¸Ľà¸£à¸°', 'à¸ķ'] +['à¸Ľà¸£à¸°à¸ķ', 'ู'] +['Ġ×ŀ×IJ', '×ĵ'] +['׼', '×ķ׳×Ļ×Ŀ'] +['à¸Ļ', 'ี'] +['ĠвÑĭ', 'Ñħод'] +['ãģ®ä¸Ń', 'ãģ«'] +['פ', '׾×IJ'] +['ĠÙĪ', 'ÙĦÙĬس'] +['פ×ķר', 'ס'] +['פ×ķרס', '×Ŀ'] +['Ùħ', 'سÙĦÙħ'] +['Ġng', 'ôi'] +['×ĵ', '×ŀ×ķת'] +['ãĤĴ使', 'ãģ£ãģ¦'] +['ĠпомоÑī', 'ÑĮÑİ'] +['Ø£', 'سر'] +['бл', 'ок'] +['ÙĤ', 'Ùĩ'] +['ãģĹãģ¾', 'ãģĦ'] +['ãģ¨', 'ãģĹãģŁ'] +['Ġп', 'еÑģ'] +['ãĥī', 'ãĥ«'] +['×Ĺ', '×Ŀ'] +['ãģĹãģª', 'ãģĮãĤī'] +['ĠÐŁ', 'ÑĢед'] +['ãĥģãĤ§', 'ãĥĥãĤ¯'] +['å¼·', 'ãģĦ'] +['ש', '×Ļר×ķת'] +['д', 'аеÑĤ'] +['×Ļ×ij', '×ķ'] +['Ġgen', 'ç'] +['ил', 'аÑģ'] +['илаÑģ', 'ÑĮ'] +['ĠبÙĦ', 'د'] +['æĤ', 'ª'] +['æĤª', 'ãģĦ'] +['Ġ×ŀ', 'שת'] +['æ§ĺ', 'ãĢħ'] +['æ§ĺãĢħ', 'ãģª'] +['à¸ĺรรม', 'à¸Ĭาà¸ķิ'] +['ĠÙĥ', 'اÙħÙĦ'] +['ĠاÙĦس', 'Ùħ'] +['×ij×ĺ', '×Ļ×Ĺ'] +['c', 'á'] +['g', 'ência'] +['ãĤ¹ãĤ¿', 'ãĥ¼'] +['à¸Ĺำ', 'à¸ģาร'] +['×Ļ׾', 'ת'] +['Ġ×Ļ', '×ķצ×IJ'] +['w', 'ój'] +['à¸ļุ', 'à¸Ħ'] +['à¸ļุà¸Ħ', 'à¸Ħล'] +['ع', 'تÙħ'] +['عتÙħ', 'د'] +['ãģĿãĤĮ', 'ãģ«'] +['ĠاÙĦت', 'ارÙĬØ®'] +['ÙĤر', 'اء'] +['Ġyönet', 'im'] +['×§', 'שר'] +['ĠÑģп', 'оÑĢÑĤ'] +['Ġר×IJש', '×ķף'] +['Ġseñ', 'al'] +['Ġch', 'ắn'] +['çĦ¡', 'ãģĦ'] +['ĠдоÑģÑĤ', 'аÑĤ'] +['ĠдоÑģÑĤаÑĤ', 'оÑĩно'] +['Ġá', 'gua'] +['à¸ģร', 'à¸ĵ'] +['à¸ģรà¸ĵ', 'ี'] +['Ġ×ŀש', '×ķ'] +['Ġtr', 'ải'] +['ë²', 'Į'] +['ujÄħ', 'cych'] +['Ù쨱', 'د'] +['à¹ĥ', 'à¸ģล'] +['à¹ĥà¸ģล', 'à¹ī'] +['ãĤĭ', 'ãģ®ãģ¯'] +['ר×ķ', '×ķ×Ĺ'] +['ÙĨ', 'Ùĥ'] +['ĠاÙĦÙĨ', 'ÙĤ'] +['ãģ®ãģ§', 'ãģĹãĤĩãģĨ'] +['ãģ®ãģ§ãģĹãĤĩãģĨ', 'ãģĭ'] +['Ùħ', 'عرÙģ'] +['ÙħعرÙģ', 'Ø©'] +['ÑĥÑī', 'е'] +['Ġ×ij×¢', '×Ļקר'] +['ت', 'صÙĦ'] +['Ġ×Ķ×IJ', 'ר'] +['Ġ×Ķ×IJר', '×¥'] +['ĠÅŀ', 'i'] +['à¸Ĥา', 'à¸Ķ'] +['íŀ', 'ĺ'] +['ãģªãĤĵ', 'ãģ¨'] +['ĠìĤ¬ëŀ', 'ij'] +['l', 'Ã¼ÄŁÃ¼'] +['ب', 'اء'] +['ĠاÙĦØ¢', 'خر'] +['Ġfam', 'ÃŃlia'] +['ĠTh', 'áng'] +['Ñī', 'ениÑı'] +['ãĤ¯', 'ãĥŃ'] +['ĠTh', 'ứ'] +['æĽ¸', 'ãģį'] +['ен', 'ной'] +['ìŀ', '¡'] +['бл', 'аг'] +['благ', 'о'] +['п', 'ов'] +['à¹ģ', 'ว'] +['à¸ĩ', 'à¸Ħà¹Į'] +['à¸Ńัà¸Ļ', 'à¸Ķัà¸ļ'] +['ãģĤ', 'ãģĴ'] +['ร', 'à¹īาย'] +['ün', 'ün'] +['Ġ×Ļ׼×ķ׾', '×Ķ'] +['з', 'он'] +['ĠÐľ', 'и'] +['маÑĤ', 'еÑĢиал'] +['Ġë³´', 'ë©´'] +['ØŃÙģ', 'ظ'] +['ê', 'Ìģ'] +['ãģ«', 'ãģĻãĤĭ'] +['Ġת', '×IJ'] +['Ġ×Ķס', '×ķ'] +['ĠÑģÑĤ', 'оÑĢ'] +['ĠÑģÑĤоÑĢ', 'он'] +['ãĥĪ', 'ãĥĥãĥĹ'] +['ÅĤo', 'ÅĽÄĩ'] +['ëħ', '¼'] +['ëĵ', 'Ŀ'] +['ĠÙĪØ§ÙĦ', 'ع'] +['ì¶', 'Ķ'] +['Ġ×Ļצ', '×IJ'] +['ĠÑĢаз', 'дел'] +['алÑĮ', 'наÑı'] +['×IJ׳', 'ש×Ļ'] +['spo', 'ÅĤ'] +['spoÅĤ', 'ec'] +['spoÅĤec', 'zn'] +['Ø¥', 'عÙĦ'] +['إعÙĦ', 'اÙĨ'] +['ÙĤÙĪ', 'Ùī'] +['íķĺë©´', 'ìĦľ'] +['تط', 'ÙĪØ±'] +['Ġsi', 'êu'] +['Ỽ', 't'] +['д', 'ви'] +['дви', 'ж'] +['Ġqu', 'ần'] +['k', 'ıl'] +['ĠпÑĢи', 'зна'] +['ĠH', 'ã'] +['ĠHã', 'y'] +['ĠباÙĦ', 'ت'] +['man', 'ın'] +['ãĤ«', 'ãĥ«'] +['Ġk', 'á»·'] +['×§', '׾×Ļ'] +['ëIJĺ', 'ì§Ģ'] +['تعÙĦ', 'Ùħ'] +['ìĭľ', 'ìĦ¤'] +['ìĭ', '¶'] +['íĺ', '¼'] +['Ùĥ', 'ÙĬÙģ'] +['売', 'ãĤĬ'] +['วิ', 'à¸Ĭา'] +['б', 'ал'] +['ĠØ£', 'ØŃ'] +['Ġдолж', 'ен'] +['รา', 'à¸ĩ'] +['ราà¸ĩ', 'วั'] +['ราà¸ĩวั', 'ล'] +['Ùħ', 'اء'] +['ج', 'ار'] +['Å', 'ļ'] +['Ġ×ŀ×IJ', '×ĸ'] +['ר', '×ŀ×Ķ'] +['ãģĭãĤĤãģĹãĤĮ', 'ãģªãģĦ'] +['ét', 'ude'] +['czÄħ', 'c'] +['Ġg', 'ór'] +['×ł×¡', '×Ķ'] +['Ùħ', 'ÙĬد'] +['ĠÐŁ', 'еÑĢе'] +['Ø£', 'خر'] +['ãģĿãģ®', 'å¾Į'] +['à¹Ģà¸Ķียว', 'à¸ģัà¸Ļ'] +['×ŀ', '×Ĵ×ķ'] +['×ŀ×Ĵ×ķ', '×ķף'] +['д', 'ов'] +['mas', 'ına'] +['×¢', '׳×Ķ'] +['ãĤ±', 'ãĥĥãĥĪ'] +['ס', '×¢'] +['סע', '×Ļ×£'] +['ĠT', 'ư'] +['Ġt', 'óc'] +['íĻľ', 'ëıĻ'] +['ĠÐŀ', 'д'] +['ĠÐŀд', 'нако'] +['Ġdol', 'ayı'] +['ؤ', 'Ùĥد'] +['ê³Ħ', 'íļį'] +['׾', 'ר'] +['в', 'еÑĩ'] +['Ġkh', 'ợi'] +['Ġth', 'á»§y'] +['×ĵ', 'ף'] +['ร', 'à¸ģ'] +['à¸ļั', 'à¸ķร'] +['à¹Ģà¸ģ', 'à¹Īา'] +['ĠاÙĦØ«', 'اÙĦ'] +['ĠاÙĦثاÙĦ', 'Ø«'] +['Ġpod', 'rá'] +['ער', '×Ļ'] +['ÙĨج', 'اØŃ'] +['Ġkh', 'ắc'] +['ì¸', '¡'] +['İ', 'M'] +['ãĤ»', 'ãĥĥãĥĪ'] +['ż', 'enia'] +['Ġ׾×Ĺ', '×ijר'] +['er', 'Ãł'] +['ì', '´Ī'] +['Ġkü', 'ç'] +['Ġküç', 'ük'] +['ات', 'ÙĩÙħ'] +['à¸ĭ', 'à¹Į'] +['Ùħشار', 'ÙĥØ©'] +['ĠاÙĦ', 'بط'] +['Ġd', 'ây'] +['ен', 'нÑĭм'] +['à¸Ĺีà¹Ī', 'à¹Ħมà¹Ī'] +['ÙĤ', 'Ùİ'] +['Ġv', 'ượt'] +['Ġtr', 'ì'] +['Ġwp', 'ÅĤyw'] +['A', 'Åŀ'] +['з', 'о'] +['ĠاÙĦس', 'ÙĬد'] +['à¸Ĺะ', 'à¹Ģล'] +['ĠÑģодеÑĢж', 'а'] +['ع', 'Ø·ÙĬ'] +['ĠاÙĦع', 'ÙĨ'] +['èĢħ', 'ãģĮ'] +['à¹Ģ', 'หà¸Ļ'] +['à¹Ģหà¸Ļ', 'ืà¸Ń'] +['Ġb', 'ÃŃ'] +['Ġüzer', 'inden'] +['ĠV', 'Å©'] +['Ġnu', 'ôi'] +['ÙĨ', 'Ùħ'] +['алÑĮ', 'ного'] +['×¢', '×Ļף'] +['ØŃ', 'ضر'] +['ĠоÑĤ', 'дел'] +['ëª', 'ĩ'] +['ìķ', '¡'] +['ĠÙĦدÙĬ', 'Ùĩ'] +['ìĻ', 'ľ'] +['Ġse', 'ktör'] +['Ġвозмож', 'но'] +['ĠÐĶ', 'ж'] +['Ġh', 'ô'] +['äºĭ', 'ãģĮ'] +['иÑĢов', 'ание'] +['алÑĮ', 'ной'] +['Ġ미', 'êµŃ'] +['ر', 'ØŃÙĦ'] +['ĠÑįк', 'Ñģ'] +['пÑĢав', 'лÑı'] +['Ġnh', 'á»Ŀ'] +['ĠÄij', 'ẩ'] +['ĠÄijẩ', 'y'] +['Ùģ', 'Ùĥر'] +['ĠÙĪØ£', 'ضاÙģ'] +['ãĥIJ', 'ãĤ¹'] +['ת×ķ׼', '׳×Ļת'] +['ÑĤел', 'ей'] +['ĠØ¥ÙĦÙĬ', 'Ùĩ'] +['ãģ¨è¨Ģ', 'ãģ£ãģ¦'] +['Ġдв', 'е'] +['Ġch', 'ấp'] +['ĠL', 'ö'] +['à¸Ħล', 'ิ'] +['à¸Ħลิ', 'à¸Ľ'] +['Ġس', 'ÙĪØ±'] +['ĠسÙĪØ±', 'ÙĬا'] +['×ŀ×Ĺ', '×ķ'] +['st', 'ä'] +['д', 'об'] +['Ġni', 'á»ĩm'] +['ãģ®', '大'] +['פר×ķ', '×Ļ×§'] +['פר×ķ×Ļ×§', '×ĺ'] +['ĠCh', 'âu'] +['Ġ×ŀ×Ķ', '×Ŀ'] +['Ñģк', 'им'] +['ĠполÑĥÑĩ', 'иÑĤÑĮ'] +['ÙĬ', 'ÙĪÙħ'] +['Ø«', 'ÙĪØ±'] +['פ×ķ׾', '×Ļ×ĺ'] +['פ×ķ׾×Ļ×ĺ', '×Ļ'] +['ĠмеÑģÑı', 'ÑĨ'] +['åħ¨', 'ãģ¦'] +['ĠاÙĦÙħ', 'جÙĦس'] +['ĠاÙĦت', 'اÙĦÙĬ'] +['Ġ×Ĺ', 'ר'] +['åIJij', 'ãģij'] +['׼', '×ŀ×Ķ'] +['б', 'ед'] +['Ø£', 'عض'] +['أعض', 'اء'] +['ÙĪÙĦ', 'د'] +['วà¹Īา', 'à¸Īะ'] +['Ġb', 'ánh'] +['à¸Ļิ', 'ย'] +['à¸Ļิย', 'ม'] +['à¸Ľà¸£à¸°', 'à¸ģัà¸Ļ'] +['ÑģÑĤав', 'иÑĤÑĮ'] +['à¸ŀ', 'à¸Ļัà¸Ļ'] +['ĠÑį', 'ÑĦÑĦ'] +['ĠÑįÑĦÑĦ', 'екÑĤив'] +['Ġав', 'ÑĤоÑĢ'] +['ĠÄIJ', 'Äĥng'] +['Ġth', 'Æ°á»Łng'] +['ãĤĴ', 'æĦŁãģĺ'] +['à¸ģัà¸ļ', 'à¸ģาร'] +['å¾Į', 'ãģ«'] +['Ġya', 'ÄŁ'] +['ست', 'اÙĨ'] +['Ġli', 'á»ģn'] +['ãģĦ', 'ãģ¾'] +['i', 'êu'] +['à¹Ĥà¸Ķ', 'à¸Ļ'] +['ĠÙĦ', 'ذÙĦÙĥ'] +['à¹Ĥรà¸ĩ', 'à¹Ģรียà¸Ļ'] +['צ', '×Ļ×Ĵ'] +['ĠاÙĦÙħ', 'عÙĦÙĪÙħات'] +['ç§ģ', 'ãģŁãģ¡'] +['à¸Ĺีà¹Ī', 'à¸Ħุà¸ĵ'] +['ãģ«ãģª', 'ãģ£ãģ¦ãģĦãĤĭ'] +['×ŀ×ĵ', '×Ļ׳×Ķ'] +['ס', '׼×Ŀ'] +['Ġв', 'не'] +['à¸ŀ', 'à¸Ļัà¸ģà¸ĩาà¸Ļ'] +['ÑĢ', 'ей'] +['à¹Ģà¸Īà¹īา', 'หà¸Ļà¹īาà¸Ĺีà¹Ī'] +['ĠHi', 'á»ĩn'] +['Ġméd', 'ico'] +['ĠتØŃ', 'ÙĤÙĬÙĤ'] +['ÑĮ', 'ÑĤе'] +['miÅŁ', 'ti'] +['ÙĤÙĬ', 'ادة'] +['ãĤı', 'ãģĭãĤĬ'] +['มา', 'à¸Īาà¸ģ'] +['ëħ', 'Ģ'] +['ãģ«éĸ¢', 'ãģĻãĤĭ'] +['×IJר×Ĵ', '×ķף'] +['m', 'ètre'] +['Ġעצ', '×ŀ×Ļ'] +['ĠCh', 'úa'] +['รูà¹ī', 'à¸Ī'] +['รูà¹īà¸Ī', 'ัà¸ģ'] +['ì£', 'Ħ'] +['ëĭ', 'µ'] +['à¹ģà¸Ĺ', 'à¹ī'] +['Ġgeç', 'en'] +['Ġlan', 'ça'] +['ĠاÙĦ', 'بØŃØ«'] +['×ĵ', '×ŀ×ķ'] +['ãģ¯', 'ãģĺ'] +['ãģ¯ãģĺ', 'ãĤģ'] +['Ġdön', 'Ã¼ÅŁ'] +['è¿ij', 'ãģı'] +['à¹Ģส', 'ม'] +['à¹Ģสม', 'à¸Ń'] +['ëĿ', '½'] +['Ġü', 'ç'] +['á»', 'ŀ'] +['ÑĪ', 'аÑı'] +['à¸Ĺ', 'ร'] +['ØŃ', 'ÙĤÙĬÙĤØ©'] +['à¸Ĥà¸Ńà¸ĩ', 'à¸ģาร'] +['Ġ무', 'ìĹĩ'] +['Ġ×Ķ', '׼ר'] +['ĠاÙĦص', 'ÙĬÙĨ'] +['ĠлÑİ', 'ди'] +['à¸ķ', 'าย'] +['ب', 'ÙĪÙĦ'] +['Ġvi', 'êm'] +['Ġthi', 'á»ĩu'] +['à¸ģ', 'à¸Ķ'] +['Ġ׾', '×ĵ×ijר'] +['פ', '׳×Ķ'] +['×IJר', '×ij×¢'] +['س', 'Ùī'] +['ĠاÙĦسÙĬ', 'اس'] +['ĠاÙĦسÙĬاس', 'ÙĬØ©'] +['yd', 'ı'] +['ÙĪØŃØ¯', 'Ø©'] +['ĠдеÑıÑĤелÑĮ', 'ноÑģÑĤи'] +['Ġ×ķ×Ķ', '×ŀ'] +['п', 'еÑĩ'] +['пеÑĩ', 'аÑĤ'] +['иÑĢов', 'аниÑı'] +['ĠÑģ', 'ог'] +['ĠÑģог', 'лаÑģ'] +['Ġ׼', '×ĵ'] +['Ġ׼×ĵ', '×IJ×Ļ'] +['ĠиÑģполÑĮзов', 'аÑĤÑĮ'] +['ס', 'פ×ķר×ĺ'] +['Ġil', 'çe'] +['exp', 'érience'] +['ĠTh', 'á»Ŀi'] +['İ', 'K'] +['à¹Ħà¸Ł', 'à¸Łà¹īา'] +['ëĵ¤', 'ìĹIJê²Į'] +['à¸Ľà¸£à¸°', 'à¹Ģà¸ł'] +['à¸Ľà¸£à¸°à¹Ģà¸ł', 'à¸Ĺ'] +['Ġmü', 'mk'] +['Ġmümk', 'ün'] +['Ġ×IJ×ķת', '׳×ķ'] +['ìĦ±', 'ìĿĦ'] +['ĠìĿ´', 'ìľł'] +['زÙĬ', 'ارة'] +['Ġolduk', 'ça'] +['r', 'ób'] +['ĠØ£', 'ÙĨا'] +['Ġ×Ķ', '×ij×Ļ'] +['Ñģ', 'ен'] +['×¢', '×Ļקר'] +['×Ļ×ĵ', '×ķ×¢'] +['d', 'zÄħ'] +['Ùħ', 'عÙĦÙĪÙħات'] +['Ø´', 'اب'] +['Ġpar', 'ça'] +['à¸Ļะ', 'à¸Ħะ'] +['ب', 'اس'] +['ĠÑĤоÑĢ', 'г'] +['ĠÑĤоÑĢг', 'ов'] +['Ġ×Ĺ', '×ĵר'] +['׼', 'ר×ĺ'] +['׼ר×ĺ', '×Ļס'] +['ĠA', 'yrıca'] +['êÌ', '£'] +['ìľ', '¨'] +['ĠÑĤак', 'ие'] +['Ġ×ŀצ', '×ķ×Ļ'] +['ãĥ©ãĥ³', 'ãĤŃãĥ³ãĤ°'] +['ש×Ļ×ķ', '×ķ×§'] +['åīį', 'ãģ®'] +['ĠB', 'ảo'] +['Ñī', 'Ñĥ'] +['æĹ©', 'ãģı'] +['ĠPh', 'òng'] +['à¸ŀระ', 'ราà¸Ĭ'] +['פ', '×Ĺ×ķת'] +['Ġг', 'л'] +['Ġгл', 'аз'] +['à¸Ĺ', 'à¹Īา'] +['Ġd', 'ạy'] +['ÑĢ', 'оÑģÑĤ'] +['à¹Ĥà¸Ķย', 'à¹Ģà¸īà¸ŀาะ'] +['Ġqu', 'áºŃn'] +['Ġ×Ĺ×ijר', '×ķת'] +['m', 'ême'] +['mÄ±ÅŁ', 'tı'] +['ĠاÙĦت', 'داÙĪÙĦ'] +['Ġn', 'ạn'] +['Ġ×Ķ', '×ĵ×Ļ'] +['ĠاÙĦØ·', 'رÙĬÙĤ'] +['×Ĵ', '×ķת'] +['Ġ×Ķ', '×ĵר×ļ'] +['ujÄħ', 'ce'] +['Ġch', 'ữ'] +['ãĤĤãģ®', 'ãģ®'] +['ë°', 'Ľ'] +['ãģķãĤĵ', 'ãģ¯'] +['Ġyard', 'ım'] +['ĠاÙĦع', 'Ùħ'] +['Ġì§Ħ', 'íĸī'] +['Ġ×Ļ', '×Ĺ'] +['Ġ×Ļ×Ĺ', 'ס×Ļ'] +['ĠاÙĦÙħ', 'دÙĬÙĨØ©'] +['Ġc', 'ú'] +['à¸ģี', 'ฬ'] +['à¸ģีฬ', 'า'] +['Ġni', 'ên'] +['mis', 'ión'] +['׳×Ļס', '×Ļ'] +['׳×Ļס×Ļ', '×ķף'] +['Ġвоз', 'ÑĢаÑģÑĤ'] +['Ġ×¢×ķש', '×Ķ'] +['ĠÙħ', 'دÙĬر'] +['Ñı', 'ÑģÑĮ'] +['ØŃ', 'جÙħ'] +['íĻĺ', 'ê²½'] +['ĠاÙĦØ£', 'خرÙī'] +['u', 'ÃŁer'] +['ĠاÙĦعاÙĦÙħ', 'ÙĬØ©'] +['ĠNg', 'á»įc'] +['êµIJ', 'íļĮ'] +['ä¸Ĭ', 'ãģ§'] +['×Ļ×Ķ', '×ķ×ĵ'] +['×Ļ×Ķ×ķ×ĵ', '×Ļ×Ŀ'] +['Ùħس', 'اعدة'] +['Ġжиз', 'нÑĮ'] +['ĠпоÑĤ', 'омÑĥ'] +['ĠاÙĦÙħ', 'ÙħÙĦ'] +['ĠاÙĦÙħÙħÙĦ', 'ÙĥØ©'] +['ĠG', 'ör'] +['ر', 'ÙIJ'] +['×ŀ×§', '×ķ×ŀ×ķת'] +['åĩºæĿ¥', 'ãĤĭ'] +['ÑĦ', 'ÑĤ'] +['ĠìĿ´', 'ìłľ'] +['ĠÑĢ', 'ем'] +['ĠÑĢем', 'онÑĤ'] +['ת', '×ķ×ļ'] +['æĻĤ', 'ãģ¯'] +['ãĤīãĤĮ', 'ãģªãģĦ'] +['alt', 'ı'] +['å®¶', 'ãģ®'] +['ĠاÙĦØ¥', 'عÙĦاÙħ'] +['리', 'ëĬĶ'] +['ãģĭãĤī', 'ãģ¯'] +['ĠH', 'ạ'] +['ãģĤ', 'ãģ®'] +['×ĵ×Ļ', '×ķף'] +['رÙĬ', 'س'] +['Ġsoci', 'etÃł'] +['ĠاÙĦÙĥ', 'بÙĬر'] +['Ġ×ij', '×ŀס'] +['Ġ×ij×ŀס', '×Ĵר'] +['Ġ×ij×ŀס×Ĵר', 'ת'] +['ĠìŀĪ', 'ìľ¼ë©°'] +['Ġn', 'ặng'] +['Ùĩ', 'Ùī'] +['ĠB', 'Ãł'] +['×ŀר', '×ķ'] +['Ġj', 'ÄĻ'] +['ĠjÄĻ', 'zy'] +['ĠjÄĻzy', 'k'] +['Ġ׼', '×ŀ×ķ×ijף'] +['×¢', '׾×Ķ'] +['à¸Ĺีà¹Ī', 'à¹Ħà¸Ķà¹ī'] +['ãģ¾', 'ãģĹãĤĩãģĨ'] +['×ŀס', 'פר'] +['Т', 'Ðŀ'] +['سÙĬاس', 'Ø©'] +['Ġкажд', 'Ñĭй'] +['ë²', 'ł'] +['t', 'ım'] +['y', 'á»ĩn'] +['ร', 'ีà¹Ī'] +['ĠдеÑĤ', 'Ñģк'] +['วิà¸ĺี', 'à¸ģาร'] +['m', 'ówi'] +['×ĺ×¢', '×Ŀ'] +['×Ķצ׾', '×Ĺ×Ķ'] +['ض', 'ÙĬÙģ'] +['ĠÑħоÑĤ', 'Ñı'] +['ãĤĵãģ§', 'ãģĦãĤĭ'] +['à¸Ħา', 'à¸Ķ'] +['à¸Ħร', 'à¸ļ'] +['Ġк', 'ÑĥÑĢÑģ'] +['ĠbaÅŁ', 'arı'] +['×ijר', '×ķ'] +['ÙĬع', 'Ø©'] +['ĠÐĿ', 'Ñĥ'] +['à¸Ħวาม', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['Ġ׾', '×ŀש׾'] +['Ġì¢ĭ', 'ìĿĢ'] +['Ùħؤس', 'س'] +['Ùħؤسس', 'ات'] +['Ġpréc', 'is'] +['Ġth', 'ảo'] +['à¸ģà¹ĩ', 'à¸Ħืà¸Ń'] +['Ġש', '׼׾'] +['führ', 'ung'] +['ãģĦ', 'ãģ§'] +['à¹ģละ', 'มี'] +['à¸ģà¹ĩ', 'มี'] +['Ġש', 'ש'] +['м', 'ел'] +['Ġкни', 'г'] +['ĠباÙĦ', 'ÙĨ'] +['ĠباÙĦÙĨ', 'سبة'] +['Ġald', 'ı'] +['ÑĤ', 'ай'] +['Ġ×Ĺ×ĵ', 'ש×Ļ×Ŀ'] +['å®Ł', 'ãģ¯'] +['ع', 'ÙĪØ§'] +['ĠìĿĺ', '미'] +['из', 'м'] +['ÑĢабоÑĤ', 'аÑĤÑĮ'] +['Ùģ', 'ص'] +['Ġ×ij׳', '×ķסף'] +['ãģ¨ãģĹãģ¦', 'ãĤĤ'] +['à¹Ģà¸Ľà¹ĩà¸Ļ', 'à¸Ĺีà¹Ī'] +['ĠÑģлед', 'ÑĥеÑĤ'] +['èĢĥãģĪ', 'ãģ¦'] +['Ġ׼', '×Ļ×ķ×Ŀ'] +['ÑģÑĤ', 'Ñĭ'] +['׼׾׼', '׾×Ļ'] +['æµģ', 'ãĤĮ'] +['ãĤĴ', 'ãģ¤ãģij'] +['Ñĩ', 'аÑĤ'] +['×Ļ׼', '×ķף'] +['×Ļר', '×Ļ'] +['ları', 'yla'] +['ãĤ¤', 'ãĥ¡'] +['ãĤ¤ãĥ¡', 'ãĥ¼ãĤ¸'] +['׳×ĸ', '×§'] +['Ġci', 'ò'] +['Ġs', 'ın'] +['Ġsın', 'ır'] +['à¸Ļ', 'à¸Ħร'] +['к', 'аÑĤ'] +['Ġl', 'á»Ĺi'] +['ëŀ', 'Į'] +['تÙģ', 'اص'] +['تÙģØ§Øµ', 'ÙĬÙĦ'] +['ëĨ', 'ĵ'] +['ĠÙħ', 'ض'] +['il', 'miÅŁ'] +['بار', 'Ùĥ'] +['ÐĿ', 'Ðĺ'] +['Ġth', 'ẩm'] +['Ġ×IJ×ķת', '×ļ'] +['ĠпÑĢин', 'им'] +['ĠпÑĢиним', 'а'] +['Ġyö', 'nt'] +['Ġyönt', 'em'] +['Ġ×ŀ×§', '×ij׾'] +['Ġktó', 'rego'] +['ê·', 'Ģ'] +['شر', 'Ùģ'] +['د', 'اÙħ'] +['ãģĦãĤį', 'ãģĦãĤį'] +['ĠAl', 'ém'] +['Ġgör', 'ü'] +['Ġgörü', 'nt'] +['Ġgörünt', 'ü'] +['د', 'س'] +['ÑĪ', 'ки'] +['г', 'ÑĢад'] +['Ġl', 'ạc'] +['Ġs', 'ữa'] +['ãĤīãĤĮ', 'ãģ¾ãģĻ'] +['o', 'Ãłi'] +['Ñī', 'ен'] +['ãģĭ', 'ãģªãģĦ'] +['Ġп', 'оп'] +['Ġпоп', 'Ñĥ'] +['ĠпопÑĥ', 'лÑıÑĢ'] +['ĠاÙĦÙħ', 'ÙĪÙĤع'] +['rä', 'g'] +['ï¼', '¡'] +['íķ', 'Ħ'] +['ãĤĴè¦ĭ', 'ãĤĭ'] +['اÙħ', 'ا'] +['ĠاÙĦØŃ', 'رب'] +['ĠÐŁ', 'а'] +['Ġ׾', '×IJתר'] +['Ġt', 'á»ijc'] +['×ij', '׾×Ķ'] +['ر', 'ئÙĬس'] +['в', 'Ñĥ'] +['ÙĬ', 'دÙĬ'] +['каз', 'ан'] +['Ġ×Ĺ', 'ש×ij×ķף'] +['h', 'ôtel'] +['×¢', '×ķ׳×Ķ'] +['ب', 'ÙĨÙĬ'] +['×ŀ', '×ķ׾'] +['Ġд', 'нÑı'] +['éĽ£', 'ãģĹãģĦ'] +['вед', 'ениÑı'] +['Ġ×ķ', '×ŀת'] +['н', 'апÑĢимеÑĢ'] +['ÙĤ', 'ابÙĦ'] +['Ġrésult', 'at'] +['ĠÑĢазвиÑĤ', 'иÑı'] +['ر', 'Ùij'] +['ìłĦ', '문'] +['ĠاÙĦÙħ', 'زÙĬد'] +['ĠìľĦ', 'íķ´ìĦľ'] +['ëĨ', 'į'] +['íĻ', 'ķ'] +['ĠThi', 'ết'] +['íĮ', '¨'] +['malı', 'dır'] +['Ġcz', 'ÅĤ'] +['ĠczÅĤ', 'owie'] +['ĠczÅĤowie', 'k'] +['ĠÙĦ', 'بÙĨ'] +['ĠÙĦبÙĨ', 'اÙĨ'] +['üs', 'ü'] +['ãģªãĤĵ', 'ãģł'] +['Ġżyc', 'ie'] +['ĠÑħоÑĢоÑĪ', 'о'] +['æĸ¹', 'ãģ«'] +['ëĭ¤', 'ë©´'] +['иÑĩеÑģ', 'каÑı'] +['ער', '×Ļ׼'] +['ער×Ļ׼', 'ת'] +['ãģ¾ãģĽãĤĵ', 'ãģ§ãģĹãģŁ'] +['ĠÑģоб', 'ой'] +['Ġg', 'á»Ĺ'] +['Ġдел', 'аÑĤÑĮ'] +['da', 'Äĩ'] +['аÑĢ', 'а'] +['róż', 'ni'] +['à¹Ģล', 'ีà¹ī'] +['à¹Ģลีà¹ī', 'ย'] +['à¹Ģลีà¹īย', 'à¸ĩ'] +['à¸Ŀ', 'าà¸ģ'] +['Ġت', 'ÙĤ'] +['ĠتÙĤ', 'دÙĬ'] +['ĠتÙĤدÙĬ', 'Ùħ'] +['หà¸Ļ', 'ุà¹Īม'] +['Ġmü', 'cade'] +['Ġmücade', 'le'] +['ì§Ģ', '를'] +['ãĤ¤', 'ãĤ¹'] +['ĠØ£', 'ساس'] +['jÄħce', 'go'] +['ĠÅŁ', 'eh'] +['н', 'ÑĤеÑĢ'] +['ÑĨи', 'Ñİ'] +['ï»', '»'] +['ÑİÑī', 'его'] +['à¹Ĥà¸Ľà¸£', 'à¹ģ'] +['à¹Ĥà¸Ľà¸£à¹ģ', 'à¸ģรม'] +['Ġmie', 'Äĩ'] +['ØŃÙĥÙĪÙħ', 'Ø©'] +['ãģ§ãģĹãģŁ', 'ãģĮ'] +['×Ļס', '×Ķ'] +['ãĤĤãģ®', 'ãĤĴ'] +['Ġ×ŀ', '×IJת'] +['สุà¸Ķ', 'à¸Ĺà¹īาย'] +['Ġc', 'Å©'] +['ÙĨ', 'سب'] +['ĠпÑĢ', 'оÑĩ'] +['Ġд', 'ней'] +['ĠÑįÑĤи', 'Ñħ'] +['׾', '×ŀת'] +['нÑı', 'Ñı'] +['Ñį', 'к'] +['Ġì§Ģ', 'ëĤľ'] +['มหา', 'วิà¸Ĺยา'] +['มหาวิà¸Ĺยา', 'ล'] +['มหาวิà¸Ĺยาล', 'ัย'] +['d', 'ão'] +['ĠMá', 'y'] +['ĠêµŃ', 'ê°Ģ'] +['à¸ļุ', 'รี'] +['×Ĵ', '×Ļ׾'] +['ĠÑĤÑĭ', 'ÑģÑı'] +['ĠÑĤÑĭÑģÑı', 'Ñĩ'] +['Ùģ', 'Ùĥ'] +['ĠÐĺ', 'Ñģ'] +['è¡Į', 'ãĤıãĤĮ'] +['פר', '×ĵ'] +['ãģ¤', 'ãģį'] +['à¸Ħร', 'à¸Ńà¸ļ'] +['à¸Ħรà¸Ńà¸ļ', 'à¸Ħรัว'] +['à¸Ĥึà¹īà¸Ļ', 'มา'] +['ä»ĬæĹ¥', 'ãģ¯'] +['ĠìĤ¬ëŀĮ', 'ìĿ´'] +['עצ', '×ŀ×Ķ'] +['п', 'оÑĢ'] +['ĠK', 'ỳ'] +['Ġ', 'Æ¡n'] +['Ġth', 'Äĥm'] +['Ùģ', 'اÙĤ'] +['ãģļ', 'ãģ«'] +['Ġ׾', 'קר'] +['Ġ׾קר', '×ķ×IJ'] +['اÙģ', 'ÙĬØ©'] +['Ùħ', 'ÙİØ§'] +['г', 'аÑĢ'] +['ص', 'ÙĦا'] +['صÙĦا', 'Ø©'] +['Ġ×ŀ', '×ĸ×Ķ'] +['lı', 'ģını'] +['Ġ×IJ', '×Ļ׳×Ķ'] +['к', 'ÑĢо'] +['Ġng', 'ươi'] +['Ġв', 'ним'] +['Ġвним', 'ание'] +['jÄħ', 'cy'] +['ÙĢÙĢÙĢÙĢ', 'ÙĢ'] +['Ñģ', 'Ñħод'] +['ãģªãĤĵ', 'ãģĭ'] +['×ŀ', '×Ļ׾'] +['Ġ×Ķ×IJ', '×Ĺ'] +['ãĤı', 'ãģªãģĦ'] +['ع', 'سÙĥر'] +['ĠìĦ¸', 'ê³Ħ'] +['ĠÑĩ', 'его'] +['ĠÑģÑĢед', 'ÑģÑĤва'] +['ĠÐł', 'аÑģ'] +['ãģª', 'ãģģ'] +['ÙĨ', 'Ù쨳'] +['ר×Ļ', '×ķף'] +['Ñģ', 'Ñĥд'] +['ĠìĿ¸', 'ê°Ħ'] +['ĠاÙĦÙħ', 'ÙĤبÙĦ'] +['ÙĨ', 'عÙħ'] +['تÙĪ', 'Ù쨱'] +['ש', '×ij×¢'] +['ı', 'lm'] +['ılm', 'Ä±ÅŁ'] +['Ġ×ľ×ª', 'ת'] +['تص', 'Ùģ'] +['×Ķפ', '×ķ×ļ'] +['à¹ĥà¸Ļ', 'à¸Ľà¸µ'] +['ìĿ´', 'ê³ł'] +['Ùģ', 'ÙĪØ²'] +['à¸ľà¸¥', 'à¸ĩาà¸Ļ'] +['ĠGi', 'áo'] +['à¸ļà¸Ńà¸ģ', 'วà¹Īา'] +['Ġd', 'Ä±ÅŁ'] +['ĠdÄ±ÅŁ', 'ında'] +['ì£', '½'] +['Ġdzie', 'ÅĦ'] +['к', 'ÑĨии'] +['и', 'ÑĨе'] +['ãģ®', 'ä¸Ģ'] +['ع', 'Ø´'] +['пÑĢ', 'еÑģÑģ'] +['หà¸Ļ', 'à¹Īà¸Ńย'] +['ลัà¸ģษ', 'à¸ĵะ'] +['Ġpossibilit', 'Ãł'] +['à¹Ħà¸Ķà¹īรัà¸ļ', 'à¸ģาร'] +['หย', 'ุà¸Ķ'] +['Ġphi', 'ên'] +['çĶŁ', 'ãģ¾ãĤĮ'] +['Ø·', 'ÙĪÙĦ'] +['ÑĦ', 'ин'] +['f', 'ür'] +['ØŃ', 'ÙĬاة'] +['íĸ', 'ĪìĬµëĭĪëĭ¤'] +['׼', '׳×ķת'] +['à¸Ľà¸£à¸°', 'ส'] +['à¸Ľà¸£à¸°à¸ª', 'à¸ļ'] +['à¸Ľà¸£à¸°à¸ªà¸ļ', 'à¸ģารà¸ĵà¹Į'] +['ëIJĺ', 'ìĹĪ'] +['Ġkaż', 'dy'] +['Ġl', 'uyá»ĩn'] +['ĠоÑĢганиз', 'аÑĨии'] +['å°ij', 'ãģªãģı'] +['ÑģÑĤÑĢо', 'ен'] +['Ġtécn', 'ico'] +['×§', '×Ķ׾'] +['Ġ×ķ×IJ', '×Ĺ'] +['ĠعÙĦÙĬ', 'Ùĥ'] +['Ñī', 'ение'] +['Ġ×Ķ', '×Ļ׾×ĵ×Ļ×Ŀ'] +['ÙĪØ³', 'ائÙĦ'] +['Ġ×ķ', '×Ķת'] +['تÙħ', 'ÙĬز'] +['ĠÑģ', 'казал'] +['Ġпол', 'и'] +['Ġ×Ķ×ŀ', 'ס'] +['ÙĦÙij', 'Ùİ'] +['Ùħؤس', 'سة'] +['Ġ×ŀ', '×Ļ×ĵ'] +['ãģ£', 'ãģ¡'] +['ĠëĦĪ', '무'] +['à¸ŀ', 'ี'] +['Ġt', 'ặng'] +['Ġt', 'ấn'] +['ר', 'ש×Ŀ'] +['Ġméd', 'ica'] +['Ġ×¢', '×ķ×ŀ'] +['Ġ×¢×ķ×ŀ', '×ĵ'] +['ÑĦ', 'оÑĢ'] +['Ùħر', 'Ø©'] +['Ġvat', 'anda'] +['Ġvatanda', 'ÅŁ'] +['Ġдел', 'о'] +['à¸Ļ', 'ม'] +['ãģ¨', 'åIJĮãģĺ'] +['Ùģ', 'Ùī'] +['Ñģ', 'оÑĢ'] +['Ġ×Ķס', 'ר×ĺ'] +['Ġép', 'oca'] +['ìłķ', 'ì±ħ'] +['ĠÑģвÑıз', 'ан'] +['ض', 'رب'] +['ĠÙĦ', 'ÙĨا'] +['Ġuży', 'wa'] +['ĠاÙĦج', 'ÙĬØ´'] +['Ñİ', 'ÑĢ'] +['×ijס', '×ķ×£'] +['Ġм', 'Ñĥ'] +['ĠмÑĥ', 'зÑĭк'] +['bilit', 'é'] +['Ġma', 'ç'] +['س', 'Ùİ'] +['ت', 'ÙĦÙĥ'] +['ãģ', '¬'] +['ÙĬ', 'ÙĦا'] +['ÑĪ', 'ла'] +['ÙĢÙĢ', 'ÙĢ'] +['Ġод', 'ной'] +['зв', 'ан'] +['ĠÑģ', 'ÑĢаз'] +['ĠÑģÑĢаз', 'Ñĥ'] +['ÙĨ', 'ظÙħ'] +['را', 'Ùĩ'] +['ĠÙĦÙĩ', 'ذا'] +['׼', '×ķר'] +['Ġ×Ķש', '×ij×ķ×¢'] +['Ġ×Ķש', 'ת'] +['ĠQu', 'ảng'] +['ãĥ«', 'ãĥ¼'] +['ãģĪ', 'ãģªãģĦ'] +['×ĺ', '×IJ'] +['Ġmi', 'á»ģn'] +['ĠPh', 'áºŃt'] +['ĠاÙĦس', 'ÙĪÙĤ'] +['Ä', 'Ĥ'] +['ĠاÙĦج', 'Ùħع'] +['ĠاÙĦجÙħع', 'Ø©'] +['ÑİÑī', 'ей'] +['a', 'ÅĤem'] +['عت', 'ÙĤد'] +['Ø£', 'ÙĦÙħ'] +['Ñģ', 'ке'] +['ĠìĿ´', 'íķ´'] +['ÙĨس', 'Ø®'] +['è¨Ģ', 'ãģĦ'] +['д', 'обав'] +['سب', 'ÙĤ'] +['×¢×ķר', 'ר'] +['ÑĤи', 'п'] +['ãģĿãģĵ', 'ãģ§'] +['vis', 'ión'] +['عÙĪØ¯', 'Ø©'] +['ë¨', '¹'] +['×ŀ', '×ĸר×Ĺ'] +['ĠØ¥', 'ØŃ'] +['Ġ׾×ij', '×Ļף'] +['Ġ׾צ', '×IJת'] +['Ġyard', 'ı'] +['Ġyardı', 'mc'] +['Ġyardımc', 'ı'] +['İ', 'Z'] +['×§', 'פ×Ķ'] +['tr', 'é'] +['liÄŁ', 'ini'] +['клÑİÑĩ', 'а'] +['Ġüret', 'im'] +['Ġa', 'yrı'] +['ĠkiÅŁ', 'iler'] +['à¸Ħ', 'à¹īà¸Ļ'] +['à¸Ħà¹īà¸Ļ', 'หา'] +['ĠS', 'á»±'] +['Ġ׼', 'ס'] +['Ġ×Ľ×¡', '×£'] +['ĠÑĤак', 'иÑħ'] +['ĠXu', 'ân'] +['Ġл', 'ег'] +['Ġлег', 'ко'] +['Ø«ÙĤ', 'اÙ쨩'] +['ÐĿ', 'Ðŀ'] +['ãĤ¹ãĤ¿', 'ãĥĥ'] +['ãĤ¹ãĤ¿ãĥĥ', 'ãĥķ'] +['åIJĪ', 'ãģĦ'] +['Ġ×Ķש', '×Ļ×ŀ×ķש'] +['man', 'ız'] +['ĠÐĴ', 'аÑģ'] +['g', 'ün'] +['ìľĦìĽIJ', 'íļĮ'] +['Ġwsp', 'óln'] +['ĠÑģв', 'ое'] +['í', 'ĥģ'] +['à¹Ģà¸Ļ', 'ีย'] +['ÙĪØ¨', 'Ø©'] +['в', 'Ñıз'] +['ı', 'dır'] +['ëIJĺ', 'ìĹĪëĭ¤'] +['ĠdeÄŁi', 'ÅŁtir'] +['ãĤĭ', 'ãģĵãģ¨ãģĮ'] +['Ġ×Ĺ×ĵ', 'ש×Ķ'] +['ãĤīãĤĮ', 'ãģ¦ãģĦãĤĭ'] +['×Ĺ×Ļ', '×Ļ×ij'] +['ĠÐļ', 'аÑĢ'] +['׳×Ļת', '×ķ×Ĺ'] +['Ġ×§×ĺ', 'ף'] +['ר', '×ĸ'] +['ÙĪ', 'غ'] +['èªŃ', 'ãģ¿'] +['Ġت', 'ÙĤÙĪÙħ'] +['ĠÙĥ', 'اÙĦ'] +['à¸Ŀ', 'ึà¸ģ'] +['Ġë°ľ', 'ìĥĿ'] +['ológ', 'ico'] +['ر', 'اع'] +['à¹ģà¸ģà¹ī', 'à¹Ħà¸Ĥ'] +['ĠÑĢабоÑĤ', 'Ñĥ'] +['ÙĨÙij', 'Ùİ'] +['à¸Ńยูà¹Ī', 'à¸Ĺีà¹Ī'] +['ĠاÙĦØ«', 'اÙĨÙĬØ©'] +['ĠNh', 'ân'] +['Ñħ', 'ваÑĤ'] +['ö', 'ne'] +['Ġع', 'دة'] +['à¹ģ', 'สà¸ĩ'] +['ÑĤ', 'оп'] +['пÑĥÑģ', 'ка'] +['شر', 'اء'] +['ĠÐļ', 'ом'] +['Ġפע', '×ķ׾×Ķ'] +['ìĤ¬', 'ìĿ´'] +['ìĤ¬ìĿ´', 'íĬ¸'] +['è¡Į', 'ãģ£ãģ¦'] +['Ġ×Ķ', '×Ķת'] +['ĠÑģÑĤ', 'оÑĢо'] +['ĠÑģÑĤоÑĢо', 'нÑĭ'] +['در', 'س'] +['à¸ĭ', 'ู'] +['à¸ķà¹Ī', 'ำ'] +['ĠØ£', 'بÙĬ'] +['под', 'об'] +['ãģ«', 'ãģ¦'] +['ار', 'تÙģØ§Ø¹'] +['ĠÙħ', 'ؤ'] +['ик', 'ов'] +['ge', 'führt'] +['มืà¸Ń', 'à¸ĸืà¸Ń'] +['ĠÙĦ', 'ÙĤد'] +['ĠØ£ÙĨ', 'Ùij'] +['سÙĬ', 'طر'] +['ãģ¾ãģļ', 'ãģ¯'] +['ס', '×ĵ'] +['Ñģк', 'олÑĮко'] +['ãģ¿ãģŁãģĦ', 'ãģª'] +['×ĵר', '×Ĵ'] +['×¢', '×Ļ×ĵ'] +['à¹ĥหà¹ī', 'à¸ļริà¸ģาร'] +['ĠÐĶ', 'и'] +['×ij×¢', '×Ļ×ķת'] +['Ġ×Ķ×Ĺ', '×ķ'] +['пиÑģ', 'ÑĮ'] +['ĠاÙĦØ®', 'ÙĦ'] +['б', 'ав'] +['Ġİ', 'lk'] +['ĠاÙĦØ®', 'Ùħ'] +['ĠاÙĦØ®Ùħ', 'ÙĬس'] +['ĠÙĬ', 'ÙĤÙĪÙħ'] +['æĻĤ', 'ãģ®'] +['ĠsÅĤ', 'ow'] +['ĠØ£', 'ÙĩÙħ'] +['Ø®ÙĦ', 'ÙĤ'] +['ĠØ£', 'صبØŃ'] +['Ġchứ', 'a'] +['Ġth', 'ác'] +['Ùģ', 'اÙĦ'] +['Ġch', 'á»Ŀ'] +['ĠاÙĦØ®', 'ار'] +['ĠاÙĦخار', 'ج'] +['ĠاÙĦخارج', 'ÙĬØ©'] +['Ø·', 'ائر'] +['Ġt', 'Ãł'] +['ĠtÃł', 'u'] +['à¸ģล', 'à¹īà¸Ńà¸ĩ'] +['ĠاÙĦÙħر', 'Ø£'] +['ĠاÙĦÙħرأ', 'Ø©'] +['åħ¨', 'ãģı'] +['ĠÃĸ', 'n'] +['çļĦ', 'ãģ«ãģ¯'] +['Ġpiè', 'ce'] +['×Ĵ', '×Ļ×ij'] +['ĠاÙĦ', 'ÙĪØ§ÙĤع'] +['ä»Ĭ', 'ãģ®'] +['ĠاÙĦÙħ', 'ÙĤ'] +['cz', 'nÄħ'] +['Ù쨹', 'اÙĦ'] +['ен', 'ного'] +['ĠÑĦак', 'ÑĤ'] +['ìĭł', 'ì²Ń'] +['ĠÐŀ', 'ни'] +['ĠاÙĦبÙĦ', 'اد'] +['ов', 'иÑĩ'] +['ëı', 'Į'] +['ÑĦ', 'ÑĥнкÑĨи'] +['Ġìĸ´', 'ëĬIJ'] +['ãĥķãĤ©', 'ãĥ¼'] +['d', 'ÃŃ'] +['ил', 'оÑģÑĮ'] +['Ùħ', 'Ùī'] +['ĠاÙĦØ£ÙħرÙĬ', 'Ùĥ'] +['ĠاÙĦØ£ÙħرÙĬÙĥ', 'ÙĬØ©'] +['×ĺ', '×Ļפ×ķ׾'] +['íĶĦ', 'ë¡ľê·¸'] +['íĶĦë¡ľê·¸', 'ëŀ¨'] +['Ġש', '×ķ׳×ķת'] +['Ø´', 'ÙħÙĦ'] +['ĠпаÑĢ', 'а'] +['Ġ×Ķ×Ĺ', '×ķ×§'] +['ÙĪØ²', 'ارة'] +['ãģ¨', 'ãģĻãĤĭ'] +['Ġqu', 'ảng'] +['ĠaÄŁ', 'ır'] +['ĠاÙĦÙĦ', 'ج'] +['ĠاÙĦÙĦج', 'ÙĨØ©'] +['ê¸', '´'] +['ĠT', 'ân'] +['ج', 'ÙħÙĦ'] +['д', 'ол'] +['à¹ģà¸ŀ', 'à¸Ĺย'] +['à¹ģà¸ŀà¸Ĺย', 'à¹Į'] +['Ġר×IJ', 'ש×Ļ'] +['Ñī', 'ей'] +['Ġçev', 're'] +['Ġкомп', 'лекÑģ'] +['Ġ×ij', '×ŀש×ļ'] +['Ġalt', 'ın'] +['ĠØ£', 'عÙħاÙĦ'] +['ĠÑģво', 'его'] +['ãĤĪ', 'ãģĦ'] +['×Ĺ׾', '×Ļ×ĺ'] +['×ŀ׳', '×¢'] +['Ġר', '×ij×Ķ'] +['ĠØ£ÙĬضا', 'Ùĭ'] +['×ĸ', '׾'] +['ĠاÙĦسÙĬ', 'اسÙĬ'] +['æĢĿ', 'ãģĨ'] +['קר', '×§'] +['קרק', '×¢'] +['ĠاÙĦÙģ', 'رÙĬÙĤ'] +['б', 'иÑĤ'] +['×§', '׳×Ķ'] +['ĠØ¥', 'ÙĨÙĩ'] +['ĠÐĴ', 'ам'] +['Ðł', 'Ðŀ'] +['ãĥĪ', 'ãĥª'] +['å¿ħè¦ģ', 'ãģª'] +['Ġch', 'âu'] +['ç¶ļ', 'ãģij'] +['Ġçöz', 'üm'] +['gÅĤ', 'ow'] +['ع', 'ÙĤÙĦ'] +['売', 'ãĤĭ'] +['i', 'ết'] +['à¸Ĭิ', 'à¹īà¸Ļ'] +['ĠØŃÙĤ', 'ÙĪÙĤ'] +['Ø·ÙĦ', 'ع'] +['ĠÄij', 'en'] +['ĠÙĥ', 'اÙ쨩'] +['ãģ®', 'ãģĶ'] +['Ġë', '¬'] +['Ġë¬', '¼'] +['Ġ물', 'ë¡ł'] +['Ġرس', 'ÙĪÙĦ'] +['з', 'ам'] +['зам', 'ен'] +['Ġkullan', 'ıcı'] +['×¢', '×ķ׾'] +['èī²', 'ãĢħ'] +['ÑĪи', 'ÑĢ'] +['Ġ×Ĺ', 'ש'] +['Ġwy', 'gl'] +['Ġwygl', 'Äħda'] +['ש', '×Ļ×ŀ×ķש'] +['å¿ĺ', 'ãĤĮ'] +['×¢', '×Ļצ×ķ×ij'] +['ĠاÙĦس', 'ÙĪØ±ÙĬ'] +['å°ij', 'ãģªãģĦ'] +['Ġпо', 'иÑģк'] +['สำ', 'à¸Ļัà¸ģà¸ĩาà¸Ļ'] +['Ġ×ŀצ', '×ĵ'] +['Ġmü', 'ÅŁ'] +['ĠmÃ¼ÅŁ', 'ter'] +['ĠmÃ¼ÅŁter', 'i'] +['ĠÙħÙĨ', 'ÙĩÙħ'] +['à¸ķำ', 'à¹ģ'] +['à¸ķำà¹ģ', 'หà¸Ļ'] +['à¸ķำà¹ģหà¸Ļ', 'à¹Īà¸ĩ'] +['ÅĽ', 'mie'] +['Ġש', '×ł×ª'] +['Ġ×Ķ', 'פ×Ļ'] +['פר', 'ש'] +['×¢×ijר', '×Ļת'] +['สà¸Ļ', 'ัà¸ļ'] +['สà¸Ļัà¸ļ', 'สà¸Ļุ'] +['สà¸Ļัà¸ļสà¸Ļุ', 'à¸Ļ'] +['è¨Ģ', 'ãģ£ãģ¦'] +['à¸ģาร', 'à¸Īัà¸Ķ'] +['ĠMo', 'że'] +['из', 'аÑĨии'] +['ứ', 't'] +['ĠÙĪØ¨', 'عد'] +['ĠdeÄŁ', 'ild'] +['ĠdeÄŁild', 'ir'] +['Ġת', '×ŀ'] +['Ġ×ŀ×ŀ', '׳×ķ'] +['話', 'ãĤĴ'] +['ĠÑĨ', 'ена'] +['Ġth', 'úc'] +['×Ļ×ŀ', '×ķף'] +['ĠB', 'áo'] +['ãĤĴ', 'åıĸãĤĬ'] +['å®ī', 'ãģĦ'] +['Ġ×¢×ķש', '×Ļ×Ŀ'] +['èĩªåĪĨ', 'ãģĮ'] +['l', 'ée'] +['ãĤĭ', 'ãģ®ãģ§'] +['иÑĢÑĥ', 'еÑĤ'] +['ãģ¦', 'ãĤĭ'] +['ست', 'ر'] +['ĠاÙĦØŃ', 'ÙĬ'] +['×Ļ׾', '×ķת'] +['Ġ×Ĺ', '×ij'] +['ÙĤر', 'Ø£'] +['تÙħ', 'ÙĥÙĨ'] +['س', 'ائÙĦ'] +['prü', 'f'] +['ãģĭ', 'ãģijãģ¦'] +['ĠÑģоб', 'ÑģÑĤвенно'] +['ĠìľĦ', 'íķĺìŬ'] +['׾', '×Ļ×ĺ'] +['ãģĮ', 'å¤ļãģı'] +['ÙĬت', 'Ùĩا'] +['ç«ĭ', 'ãģ¦'] +['ม', 'à¸Ńà¸ļ'] +['ìĭľ', 'ìŀ¥'] +['оÑĢ', 'а'] +['Ġs', 'avaÅŁ'] +['×ĺ×Ļ×ij', '×Ļ'] +['×ij', '׳×ķ'] +['Ùħا', 'ذا'] +['기', 'ê°Ħ'] +['ãģªãģ©', 'ãģ§'] +['Ġ×ŀ', 'ת×Ĺ×Ļ׾'] +['Ġnhi', 'á»ħ'] +['Ġnhiá»ħ', 'm'] +['ка', 'ÑĢ'] +['каÑĢ', 'ÑĤ'] +['Ġ׾×Ķ', 'שת×ŀש'] +['׳', '×Ļ×Ĺ'] +['اد', 'ÙĬØ©'] +['ราย', 'à¸ĩาà¸Ļ'] +['Ġprzy', 'kÅĤad'] +['Ñī', 'ий'] +['ØŃض', 'ÙĪØ±'] +['Ġh', 'ôn'] +['Ã', 'Ŀ'] +['ת', '×ķצ×IJ×ķת'] +['راب', 'Ø·'] +['Ġb', 'ếp'] +['ĠполÑĥÑĩ', 'и'] +['åĩºä¼ļãģĦ', 'ç³»'] +['à¸Ľà¸¥', 'à¹Īà¸Ńย'] +['ĠاÙĦØ´', 'باب'] +['اÙĩ', 'ÙĦ'] +['ä»Ĭ', 'ãģ¾ãģ§'] +['رج', 'ع'] +['ãĤ¶', 'ãĥ¼'] +['ÙĤ', 'Ùģ'] +['ĠGro', 'ÃŁ'] +['ĠíļĮ', 'ìĽIJ'] +['اج', 'ر'] +['Ġ×ij×ŀ', 'קר×Ķ'] +['Ġseg', 'urança'] +['fü', 'hl'] +['ãģ¦', 'ãģĦãģı'] +['หม', 'à¸Ń'] +['ĠкоÑĤоÑĢ', 'ом'] +['ĠN', 'Äĥm'] +['ĠdÅĤ', 'ugo'] +['ÙħÙĨ', 'ØŃ'] +['ש×ķ', '×ķ×Ļ'] +['ĠØ£ÙĬ', 'اÙħ'] +['ส', 'à¸łà¸²à¸ŀ'] +['r', 'zÄħ'] +['شر', 'Ùĥات'] +['ãĤĴ', 'èĢĥãģĪ'] +['д', 'аÑĢ'] +['à¸Ľà¸£à¸°', 'à¸Ĭุม'] +['Ġ×ķ×IJ', '×ĸ'] +['i', 'á»ĩn'] +['Ġt', 'ươi'] +['ש', '×Ļ×Ĺ'] +['à¸Ń', 'à¹Īà¸Ńà¸Ļ'] +['æĽ¸', 'ãģĦãģ¦'] +['Ġng', 'ữ'] +['×ij×Ļ×ĺ', '×Ĺ'] +['×ij×Ļ×ĺ×Ĺ', '×ķף'] +['Ġs', 'ẵ'] +['Ġsẵ', 'n'] +['ì§Ģ', 'ëıĦ'] +['ĠпÑĢ', 'еп'] +['ĠпÑĢеп', 'аÑĢаÑĤ'] +['Ġна', 'ÑĥÑĩ'] +['ĠÃľ', 'nivers'] +['ĠÃľnivers', 'ites'] +['ĠÃľniversites', 'i'] +['Ġ×Ĵ×ĵ', '×ķ׾×Ķ'] +['Ġ×Ķ', '×ł×ª'] +['Ġ×Ķ×ł×ª', '×ij×¢'] +['ãģ§ãģĤ', 'ãģ£ãģŁ'] +['Ġmies', 'iÄħ'] +['ĠmiesiÄħ', 'c'] +['г', 'ÑĢам'] +['гÑĢам', 'м'] +['Ġبش', 'Ø£ÙĨ'] +['ĠÑħ', 'ÑĢ'] +['×§', '×Ļ×ĵ'] +['×§×Ļ×ĵ', '×ķ×Ŀ'] +['Ø´', 'Ùĥر'] +['Ġ', 'á»ķ'] +['Ġá»ķ', 'n'] +['ãģĮãģĤ', 'ãģ£ãģ¦'] +['ãģķãĤĮ', 'ãģ¾ãģĻ'] +['Ġ×Ĺ', '×ķ×ĵ'] +['Ġ×Ĺ×ķ×ĵ', 'ש×Ļ×Ŀ'] +['ÙħÙĪØ§', 'جÙĩ'] +['ÙħÙĪØ§Ø¬Ùĩ', 'Ø©'] +['أش', 'خاص'] +['ب', 'غ'] +['à¹Ģรียà¸Ļ', 'รูà¹ī'] +['ãģĹãģ¦', 'ãģĦãģı'] +['Ġs', 'ạn'] +['å¿ħ', 'ãģļ'] +['׳', '×Ļ×Ĵ'] +['׳×Ļ×Ĵ', '×ķ×ĵ'] +['باÙĦ', 'غ'] +['×Ĺ', 'ש×ŀ'] +['×Ĺש×ŀ', '׾'] +['Ġnap', 'raw'] +['Ġnapraw', 'dÄĻ'] +['Ø´Ùĩ', 'اد'] +['×IJ', '×ķ×Ķ'] +['×IJ×ķ×Ķ', '×ij'] +['и', 'ÑĨÑĭ'] +['Ġ×Ķ', 'ר׼×ij'] +['ëŀ', 'ij'] +['Ġת', '×¢'] +['Ġ×Ķ', '×Ļש'] +['Ġ×Ķ×Ļש', 'ר×IJ'] +['Ġ×Ķ×Ļשר×IJ', '׾×Ļ'] +['Ø£', 'ÙħÙĨ'] +['ÑİÑī', 'аÑı'] +['sk', 'ór'] +['LER', 'İ'] +['Ġ×Ķ×IJ×Ĺר', '×ķף'] +['×¢', '׳ק'] +['ĠÙĪ', 'ÙĥÙĦ'] +['ãģĵãģĵ', 'ãģ§'] +['Ġqu', 'án'] +['liÄŁ', 'in'] +['à¸ģà¸İ', 'หมาย'] +['Ø·', 'Ùħ'] +['Ø£', 'جÙĩ'] +['أجÙĩ', 'زة'] +['ĠEr', 'doÄŁan'] +['ãģ§', 'ãģĬ'] +['Ġв', 'ÑĢа'] +['ĠвÑĢа', 'Ñĩ'] +['ĠPh', 'ó'] +['à¸Ĭั', 'à¹Īว'] +['à¸Ĭัà¹Īว', 'à¹Ĥม'] +['à¸Ĭัà¹Īวà¹Ĥม', 'à¸ĩ'] +['Ġph', 'úc'] +['×Ļפ', '×ķת'] +['×¢×Ļ', '×ķף'] +['Ġduż', 'o'] +['ãĥģ', 'ãĥ¼ãĥł'] +['ĠÙĬ', 'Ùİ'] +['Ġзад', 'аÑĩ'] +['Ġ×Ĵ×ij×ķ×Ķ', '×Ķ'] +['Ġ׼', '׼׾'] +['лож', 'ен'] +['ét', 'at'] +['Ġng', 'Äĥn'] +['èµ·', 'ãģį'] +['ĠTi', 'ến'] +['ص', 'عب'] +['Ġexperi', 'ência'] +['Ø®', 'Ùħ'] +['à¸ģาร', 'à¸Ĺำà¸ĩาà¸Ļ'] +['س', 'ÙĬد'] +['ĠD', 'á»±'] +['ĠкоÑĤоÑĢ', 'ого'] +['lad', 'ıģı'] +['Ġkh', 'á»ķ'] +['Ġê³Ħ', 'ìĨį'] +['Ñī', 'ик'] +['สà¹Īวà¸Ļ', 'à¸ķัว'] +['з', 'оÑĢ'] +['ÙĨ', 'Ùı'] +['Ġ', 'à¸Ķัà¸ĩ'] +['Ġà¸Ķัà¸ĩ', 'à¸Ļัà¹īà¸Ļ'] +['Ġc', 'ấu'] +['ĠÄij', 'á»ijc'] +['о', 'ÑĦ'] +['ĠاÙĦØ£', 'عÙħاÙĦ'] +['ãģªãģı', 'ãģ¦ãĤĤ'] +['×ķ׼', '×Ļ×Ŀ'] +['à¹ģ', 'à¸Ľ'] +['ĠB', 'ên'] +['ãĥ¯', 'ãĥ³'] +['Ġgi', 'ám'] +['ĠÅŀ', 'u'] +['Ġd', 'áng'] +['ع', 'ÙĦÙĬ'] +['à¹Ģà¸ģ', 'ษ'] +['à¹Ģà¸ģษ', 'à¸ķร'] +['ÙĪØ¬', 'ب'] +['н', 'нÑĭе'] +['ÙĤ', 'ضاء'] +['à¸Ħว', 'à¸ļ'] +['à¸Ħวà¸ļ', 'à¸Ħุ'] +['à¸Ħวà¸ļà¸Ħุ', 'ม'] +['ãģ¤', 'ãģ¤'] +['ĠVi', 'á»ĩc'] +['×ŀ×ij', '×ĺ'] +['ש×Ļת', '×ķ×£'] +['Ġв', 'едÑĮ'] +['k', 'aza'] +['kaza', 'ÅĤ'] +['à¸ķำ', 'รวà¸Ī'] +['ãĤ¿', 'ãĥ«'] +['Ġпов', 'Ñĭ'] +['ĠповÑĭ', 'ÑĪен'] +['ĠS', 'ợ'] +['ĠìĦ¤', 'ëªħ'] +['ĠÃĩ', 'ünkü'] +['ìĥĿ', 'íĻľ'] +['Ö', '¾'] +['ãĤĮ', 'ãģ¦ãģĦãĤĭ'] +['Ġ×ij', 'ר×IJש'] +['ר', '×ķ×Ĵ'] +['Ġо', 'ÑĦи'] +['ĠоÑĦи', 'ÑĨиалÑĮн'] +['ĠÑĥ', 'ÑģÑĤанов'] +['ĠÑĥÑģÑĤанов', 'лен'] +['ĠاÙĦÙħ', 'صر'] +['ĠاÙĦÙħصر', 'ÙĬØ©'] +['ĠÐŁÐ¾', 'ÑįÑĤомÑĥ'] +['ÙĨ', 'صÙģ'] +['ĠÙĪØ§ÙĦ', 'ÙĨ'] +['Ġh', 'Ãłi'] +['à¸Ħ', 'ิ'] +['ĠApr', 'ès'] +['ì³', 'IJ'] +['à¹Ģà¸ĭ', 'ีย'] +['×ĵ', '×ŀ×Ķ'] +['activ', 'ité'] +['à¸Ħิà¸Ķ', 'วà¹Īา'] +['ÑĤ', 'ÑĢен'] +['à¹Ģ', 'ฮ'] +['ãĥı', 'ãĤ¤'] +['ãģĮ', 'å¢ĹãģĪ'] +['ен', 'наÑı'] +['Ġìĺ¤', 'ëĬĺ'] +['ãĥ¢', 'ãĥ³'] +['Ġкон', 'еÑĩно'] +['ĠÙħÙĤ', 'ابÙĦ'] +['cl', 'é'] +['Ġh', 'ü'] +['Ġth', 'ẳng'] +['ìłģ', 'ìĿ´'] +['ĠÐIJ', 'лекÑģ'] +['ĠÐIJлекÑģ', 'ан'] +['ĠÐIJлекÑģан', 'дÑĢ'] +['ãĥŀãĥ³', 'ãĤ·ãĥ§ãĥ³'] +['ãģ²ãģ¨', 'ãģ¤'] +['ãģª', 'ãģĬ'] +['à¹Ģà¸Īà¹īา', 'à¸Ĥà¸Ńà¸ĩ'] +['ëĵľ', '리'] +['Ø´', 'اء'] +['ĠsaÄŁ', 'lık'] +['ĠÅŁ', 'imdi'] +['×Ļ×IJ', '׾'] +['تأ', 'Ø«ÙĬر'] +['Ø£', 'سب'] +['أسب', 'اب'] +['ĠвÑĭполн', 'ен'] +['л', 'ок'] +['ש', '×Ļ×ij×Ķ'] +['Ġl', 'ắm'] +['ĠTr', 'Æ°á»Ľc'] +['Ġ×Ķ×¢', '׾'] +['리', '를'] +['ĠÑĢ', 'еж'] +['ĠÑĢеж', 'им'] +['int', 'é'] +['inté', 'gr'] +['×Ĵ', '׳×Ļ'] +['ĠاÙĦØ´', 'عر'] +['Ġmil', 'hões'] +['Ġpeque', 'ño'] +['ãĤ³', 'ãĥ¼ãĤ¹'] +['×ķ׼', '×Ĺ'] +['à¹Ģà¸Ĭ', 'à¹īา'] +['شر', 'ÙĤ'] +['Ġh', 'ương'] +['รัà¸IJ', 'à¸ļาล'] +['à¸ģล', 'าย'] +['à¸ģลาย', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['Ġпод', 'Ñħод'] +['תש', '×ķ×ij×Ķ'] +['ãģıãģª', 'ãģ£ãģ¦'] +['ĠاÙĦØ£Ùħ', 'Ùħ'] +['ĠH', 'á»įc'] +['ĠwspóÅĤ', 'pr'] +['ĠwspóÅĤpr', 'ac'] +['Ñĩ', 'Ñĥв'] +['ÑĩÑĥв', 'ÑģÑĤв'] +['ÃŃst', 'ico'] +['à¹Ģà¸ģ', 'าะ'] +['ìĽ', 'Ģ'] +['Ġназ', 'ад'] +['ãĤĭ', 'ãĤĪãģĨãģ«'] +['ĠС', 'Ш'] +['ĠСШ', 'ÐIJ'] +['м', 'он'] +['ĠAs', 'ÃŃ'] +['×ķר', '×Ĵ'] +['полн', 'ен'] +['×ŀס', '׾'] +['×ŀ×¡×ľ', '×ķ׾'] +['à¹Ģลืà¸Ń', 'à¸Ķ'] +['à¹Ģริà¹Īม', 'à¸ķà¹īà¸Ļ'] +['ĠاÙĦØ¥', 'Ùħ'] +['ĠاÙĦØ¥Ùħ', 'ارات'] +['צ×Ķ', 'ר'] +['ãĥ¡ãĥª', 'ãĥĥãĥĪ'] +['ĠпоÑĤ', 'ом'] +['в', 'из'] +['ĠÙģ', 'ترة'] +['å¾Į', 'ãģ®'] +['ÐĿ', 'ÐIJ'] +['×ŀס', 'ר'] +['ÙĬر', 'ÙĬ'] +['pr', 'é'] +['Ġte', 'ÅŁek'] +['ĠteÅŁek', 'kür'] +['Ġöd', 'eme'] +['د', 'اÙĨ'] +['ãģ¾', 'ãģĹãģ¦'] +['缮', 'ãģ«'] +['ĠÑĤ', 'еÑĩение'] +['l', 'ard'] +['lard', 'ır'] +['à¹Ģรา', 'à¸Īะ'] +['ס', 'פ×Ļ'] +['ĠÙĪÙĥ', 'ذÙĦÙĥ'] +['Ġh', 'át'] +['Ġt', 'á»Ļc'] +['à¸Ħุ', 'ย'] +['Ġb', 'ức'] +['ØŃ', 'ÙĬÙĨ'] +['èģŀ', 'ãģĦãģ¦'] +['Ùħؤ', 'شر'] +['ĠNh', 'ư'] +['Ġмен', 'ее'] +['ละ', 'à¸Ħร'] +['Ñģ', 'ин'] +['ĠÑĢ', 'ек'] +['ĠÑĢек', 'л'] +['ĠÑĢекл', 'ам'] +['ĠÙģ', 'ÙĩÙĪ'] +['Ġ׾', '×ĸ'] +['×Ļ׳', '×ķת'] +['ĠÅŁ', 'art'] +['ÑģÑĤав', 'ка'] +['Ġíı¬', 'íķ¨'] +['ãģ«è¡Į', 'ãģı'] +['ï¼', 'Ŀ'] +['ĠпозволÑı', 'еÑĤ'] +['Ġת×ķ׼', '׾×ķ'] +['ов', 'ал'] +['صÙĦ', 'Ø©'] +['Ġ׾ש', '׳×ķת'] +['ĠÐĺ', 'гÑĢ'] +['ÙħÙĨتج', 'ات'] +['Ġsat', 'Ä±ÅŁ'] +['Ñģ', 'ко'] +['ĠاÙĦØ«ÙĦاث', 'اء'] +['Ġ×Ķ×ĵ×ijר', '×Ļ×Ŀ'] +['ãģĹãģ¾', 'ãģĹãĤĩãģĨ'] +['بÙĤ', 'Ùī'] +['åĬĽ', 'ãĤĴ'] +['ĠÃĩ', 'ok'] +['ãĥģ', 'ãĥ¥'] +['à¹Ģà¸Ĭ', 'ืà¹īà¸Ń'] +['ยุ', 'à¸Ħ'] +['ศา', 'ล'] +['Ġ×§×ķ×ĵ', '×Ŀ'] +['×ĸר', '×Ļ×Ŀ'] +['ãģ®', 'åł´åIJĪ'] +['ĠìķĬ', 'ìķĺ'] +['ãģĤãĤĬãģ¾ãģĻ', 'ãģĮ'] +['×IJ', 'שר'] +['è¡Į', 'ãģı'] +['ãģ»', 'ãģĭ'] +['æ°Ĺ', 'ãģ«ãģªãĤĭ'] +['й', 'деÑĤ'] +['íķĺìĺĢ', 'ëĭ¤'] +['ستÙħر', 'ار'] +['ĠÐŁÑĢ', 'е'] +['ĠÑģ', 'боÑĢ'] +['ĠìķĦ', '무'] +['ç§ģ', 'ãĤĤ'] +['ع', 'ص'] +['Ġн', 'иÑĩ'] +['ĠниÑĩ', 'его'] +['ĠпÑĢи', 'ем'] +['×§', '×ķ×ŀ'] +['ĠìĪĺ', 'ëıĦ'] +['Ġì', '¡´'] +['Ġì¡´', 'ìŀ¬'] +['ĠØ£', 'Ø«ÙĨ'] +['ĠأثÙĨ', 'اء'] +['ĠÙĪØ§ÙĦ', 'ØŃ'] +['ãģĮ', 'ãģ§ãģįãĤĭ'] +['Ġת', '×Ķ'] +['Ġת×Ķ', '×Ļ×Ķ'] +['ר', 'ף'] +['ĠÑģвÑıз', 'и'] +['×Ĵ', 'שת'] +['Ñģп', 'екÑĤ'] +['ס', '×ij×Ļ×ij'] +['ס×ij×Ļ×ij', '×Ķ'] +['ĠíķĦìļĶ', 'íķľ'] +['ت', 'خصص'] +['Ġж', 'ив'] +['Ġжив', 'оÑĤ'] +['ĠMay', 'ıs'] +['تع', 'ا'] +['تعا', 'ÙĪÙĨ'] +['ĠعÙĨ', 'Ùĩا'] +['ów', 'ki'] +['ĠاÙĦÙģÙĦسطÙĬÙĨ', 'ÙĬ'] +['ãģłãģijãģ§', 'ãģªãģı'] +['ìĿ¸', 'ì§Ģ'] +['ĠاÙĦس', 'ÙĪØ¯'] +['ĠاÙĦسÙĪØ¯', 'اÙĨ'] +['إجراء', 'ات'] +['Ġkö', 'tü'] +['Ġ×Ļ', 'תר'] +['×Ĵ', '×Ļש×Ķ'] +['Ġצ', '×ķר×ļ'] +['รà¸ĸ', 'ย'] +['รà¸ĸย', 'à¸Ļà¸ķà¹Į'] +['Ñħ', 'оÑĤ'] +['Ðł', 'ÐIJ'] +['ÙĪ', 'Ø·ÙĨ'] +['Ġsay', 'ısı'] +['ס', '×Ĺר'] +['Ùħ', 'ÙĪÙĦ'] +['ãĤĴæĮģ', 'ãģ£ãģ¦'] +['ع', 'اÙĨ'] +['Ġt', 'á»Ļi'] +['ĠвÑĭ', 'ÑĪе'] +['Ġt', 'ầm'] +['ãĥĪ', 'ãĥ¬'] +['×Ļצ', '×ķ'] +['ม', 'ุม'] +['س', 'ÙĪØ¯'] +['ìłĦ', 'ìŀIJ'] +['ãĤµ', 'ãĥŃãĥ³'] +['ìĤ°', 'ìĹħ'] +['ĠоÑģнов', 'ан'] +['Ø®', 'Ù쨶'] +['רצ', '×Ķ'] +['بÙĬ', 'ض'] +['×ķÖ', '¹'] +['ס×Ļ', '×Ļ×¢'] +['Ġש', '×IJ×Ļ'] +['ĠاÙĦÙĤر', 'Ø¢ÙĨ'] +['ĠТак', 'же'] +['×ŀש', '×ŀ×¢×ķת'] +['س', 'ÙĩÙĦ'] +['Ġ×Ķ', '׳×Ķ'] +['ãĤĴ', 'ãģĹãģ¦ãģĦãĤĭ'] +['×Ļ', '×Ļס'] +['×Ķ', '×ķ×IJ'] +['ĠB', 'ÃŃ'] +['Ġмал', 'о'] +['ĠëͰëĿ¼', 'ìĦľ'] +['Ġר', '×Ĺ×ij'] +['ãģĮ', 'é«ĺãģĦ'] +['ÙĪ', 'اس'] +['ìĤ', '¼'] +['׳', '×¢'] +['ãģ£', 'ãģ¡ãĤĥ'] +['ĠT', 'üm'] +['à¸Ńีà¸ģ', 'à¸Ķà¹īวย'] +['ãģĹãģ¦', 'ãģıãģłãģķãģĦ'] +['ÙĨØ´', 'اط'] +['ãĥĹ', 'ãĥ©ãĥ³'] +['али', 'ÑģÑĮ'] +['×ĵ', '×ľ×ª'] +['Ġwc', 'zeÅĽ'] +['ĠwczeÅĽ', 'niej'] +['ĠÑįÑĤ', 'им'] +['Ġthá»ĭ', 't'] +['à¸ļ', 'ัà¸į'] +['à¸ļัà¸į', 'à¸Ĭี'] +['ãģļ', 'ãģ£ãģ¨'] +['ÑĢ', 'ин'] +['Ġswo', 'jÄħ'] +['íķĺëĬĶ', 'ëį°'] +['Ġë§Įëĵ¤', 'ìĸ´'] +['تش', 'Ùĥ'] +['تشÙĥ', 'ÙĬÙĦ'] +['ائ', 'Ùĩ'] +['Ġ׾פ', '×Ĺ×ķת'] +['ãĥĭ', 'ãĥ¥'] +['ãĥĭãĥ¥', 'ãĥ¼ãĤ¹'] +['׼×IJ', 'ף'] +['ãģ§ãģį', 'ãģŁ'] +['зв', 'он'] +['Ġsta', 'ÅĤ'] +['×Ĺ×ijר', 'ת×Ļ'] +['ĠØ£', 'عÙĦÙĨ'] +['à¹ģà¸ļà¸ļ', 'à¸Ļีà¹ī'] +['بد', 'Ø¡'] +['ãĤģ', 'ãģŁ'] +['Ġ×ŀש', '×ŀ×¢×ķת'] +['Ġ×ŀש×ŀ×¢×ķת', '×Ļ'] +['ör', 'ü'] +['Ġh', 'ạnh'] +['z', 'ähl'] +['ĠL', 'ý'] +['Ġ×ij', '×Ķת'] +['Ġ×ij×Ķת', '×IJ×Ŀ'] +['б', 'аÑĢ'] +['ì¦', 'Ī'] +['ä»ĬåĽŀ', 'ãģ®'] +['Ġy', 'ü'] +['Ġyü', 'ks'] +['Ġyüks', 'el'] +['ãĤ½', 'ãĥ¼'] +['ãģĤ', 'ãĤĮ'] +['ת', '׾×ŀ×Ļ×ĵ'] +['ãģ¤', 'ãģª'] +['×ij', '׳×Ļ×Ŀ'] +['Ġx', 'ếp'] +['ĠмÑĥж', 'Ñĩин'] +['ĠاÙĦÙĥ', 'تاب'] +['׼', '×ŀ×ķת'] +['Ġç', 'e'] +['Ġçe', 'ÅŁ'] +['ĠçeÅŁ', 'it'] +['ĠçeÅŁit', 'li'] +['×ĵ', '×Ļר×ķת'] +['à¸ļุ', 'à¸į'] +['ĠاÙĦØ¥', 'ÙĦÙĥ'] +['ĠاÙĦØ¥ÙĦÙĥ', 'ترÙĪ'] +['ĠاÙĦØ¥ÙĦÙĥترÙĪ', 'ÙĨÙĬ'] +['ĠباÙĦØ¥', 'ض'] +['ĠباÙĦإض', 'اÙ쨩'] +['Ġyö', 'nel'] +['Ġyönel', 'ik'] +['mys', 'ÅĤ'] +['à¸Ķà¹īวย', 'à¸ģาร'] +['à¸ģาร', 'à¸Ĺำ'] +['ов', 'Ñĭм'] +['Ø£', 'زÙħØ©'] +['æİ¢', 'ãģĹ'] +['íļ', '¨'] +['Ġ×ķ×IJ', '×Ŀ'] +['Ġnghi', 'êm'] +['ÑĪ', 'ин'] +['ка', 'л'] +['Ġcrian', 'ças'] +['èĩªåĪĨ', 'ãģ§'] +['Ġн', 'ай'] +['Ġнай', 'ÑĤи'] +['ĠS', 'á»ij'] +['ĠÃ¶ÄŁrenc', 'iler'] +['ãĥ¶', 'æľĪ'] +['Ñģ', 'ан'] +['ĠJ', 'á'] +['ĠkonuÅŁ', 'ma'] +['شر', 'Ø·'] +['ëĪ', 'Ī'] +['ar', 'rière'] +['ضر', 'ÙĪØ±Ø©'] +['ãĥĶ', 'ãĥ³'] +['×¢', 'שר'] +['аÑĢ', 'ÑĮ'] +['جÙħ', 'اع'] +['Ġdé', 'co'] +['Ġ×Ļ×Ķ', '×ķ×ĵ×Ļ'] +['à¸ŀ', 'ลาà¸Ķ'] +['ĠÙĬ', 'ÙĥÙĨ'] +['Ġج', 'اÙħعة'] +['Ø·', 'بÙĤ'] +['Ġbo', 'ÅŁ'] +['×ķ', '×ķ×IJ'] +['×ŀ×ĵ', '×¢'] +['×§×ij×ķצ', 'ת'] +['פ', '×Ļר'] +['jÄħc', 'ym'] +['ÙħØ´', 'ا'] +['Ùħشا', 'ÙĥÙĦ'] +['צ', 'פ×ķף'] +['Ø¥', 'ست'] +['×ŀ׼', 'ר'] +['سÙħ', 'ع'] +['Ġкак', 'ой'] +['ÑĤ', 'воÑĢ'] +['ØŃ', 'ج'] +['Ù쨱', 'ض'] +['пÑĢав', 'лен'] +['Ġник', 'ак'] +['Ġmi', 'á»ĩ'] +['Ġmiá»ĩ', 'ng'] +['ü', 'ÃŁ'] +['иÑĢов', 'ал'] +['׾', '×ŀ×ķת'] +['次', 'ãģ®'] +['ÙĦ', 'Ø·'] +['à¸ķ', 'ัà¸Ļ'] +['×Ķ', 'ת×Ĺ×Ļ׾'] +['Ġfoto', 'ÄŁ'] +['ĠfotoÄŁ', 'raf'] +['طر', 'ØŃ'] +['à¸Ńà¸Ńà¸ģ', 'à¹Ħà¸Ľ'] +['Ġy', 'ên'] +['Ġп', 'ок'] +['Ġпок', 'Ñĥп'] +['ĠпокÑĥп', 'а'] +['ÑĨ', 'Ñĥ'] +['Ġкомп', 'ÑĮÑİ'] +['ĠкомпÑĮÑİ', 'ÑĤеÑĢ'] +['ĠاÙĦÙĥ', 'رÙĬÙħ'] +['تص', 'Ùħ'] +['تصÙħ', 'ÙĬÙħ'] +['Ġоказ', 'а'] +['Ġzar', 'ówn'] +['Ġzarówn', 'o'] +['ëĮĢ', 'ì¶ľ'] +['ãĤ»ãĥ³', 'ãĤ¿ãĥ¼'] +['Ġjako', 'ÅĽci'] +['æĤ', '©'] +['æĤ©', 'ãģ¿'] +['Ø£ÙĨ', 'ÙĪ'] +['Ø£ÙĨÙĪ', 'اع'] +['ë¹', 'ł'] +['Ġìłķ', 'ë§IJ'] +['Ġk', 'ẻ'] +['ĠÑģай', 'ÑĤа'] +['Ġ×Ķ', 'ער×ij'] +['Ùĩ', 'ز'] +['pres', 'ión'] +['ĠÑģÑĤ', 'ен'] +['ãģ£ãģ¦', 'ãĤĭ'] +['Ġhız', 'lı'] +['Ðļ', 'ÐIJ'] +['×ŀשפ', '×Ĺת'] +['ĠÙĨ', 'Ùĩا'] +['ĠÙĨÙĩا', 'ÙĬØ©'] +['ãģ¾', 'ãģĦ'] +['о', 'ÑħÑĢан'] +['ร', 'à¹īà¸Ńย'] +['ล', 'ึà¸ģ'] +['ĠÙĪØ¨', 'اÙĦ'] +['ãĤĤãģ®', 'ãģĮ'] +['ר׼', '×Ļ×ij'] +['ãĤ¤', 'ãĥ¤'] +['س', 'ؤ'] +['سؤ', 'اÙĦ'] +['ĠÙĦØ£ÙĨ', 'Ùĩ'] +['ĠkonuÅŁ', 'tu'] +['Ðļ', 'ÑĥпиÑĤÑĮ'] +['Ġש×IJת', '×Ķ'] +['ĠÙĪØ§ÙĦ', 'س'] +['Ġmożliwo', 'ÅĽci'] +['Ġpró', 'b'] +['ëĶ', '°'] +['ãģ©', 'ãĤĮ'] +['ĠÐľ', 'ин'] +['ĠоÑĢганиз', 'м'] +['ãģ«å¯¾', 'ãģĻãĤĭ'] +['ĠPr', 'é'] +['Ġpriv', 'é'] +['ch', 'è'] +['ãģĦãģŁãģł', 'ãģį'] +['สà¸Ļุ', 'à¸ģ'] +['ajÄħ', 'ce'] +['ĠD', 'zi'] +['ĠDzi', 'ÄĻki'] +['ÅĤat', 'w'] +['r', 'än'] +['rän', 'k'] +['æĿ¥', 'ãģŁ'] +['Ġ×Ķ×Ļ×Ķ', '×ķ×ĵ×Ļ'] +['ãĤ¬', 'ãĥ¼'] +['ĠÑĢаÐ', '´'] +['ĠÑĢад', 'и'] +['к', 'ÑĤив'] +['Ø£', 'Ùĩد'] +['Ø£Ùĩد', 'اÙģ'] +['ש', '×IJ×Ļר'] +['ãģ¦', 'ãģĦãģªãģĦ'] +['Ġfr', 'üh'] +['Ġок', 'ол'] +['Ġокол', 'о'] +['Ġreg', 'ião'] +['ĠÑĩиÑģ', 'ле'] +['Ġpon', 'iew'] +['Ġponiew', 'aż'] +['ìĦ¼', 'íĦ°'] +['Ġb', 'ầu'] +['Ġê', '·'] +['Ġê·', 'ľ'] +['Ġê·ľ', 'ìłķ'] +['ĠH', 'òa'] +['ĠÑĤ', 'оÑĤ'] +['ãĤĤ', 'å¤ļãģĦ'] +['ĠاÙĦإسÙĦاÙħ', 'ÙĬØ©'] +['ãģĭ', 'ãģĦ'] +['Ñį', 'н'] +['ĠÑĥказ', 'ан'] +['ĠÑĤак', 'ое'] +['ï¼', '³'] +['ëĮĢ', 'íķĻ'] +['Ġgen', 'iÅŁ'] +['ĠاÙĦØ®', 'ÙĬ'] +['ĠاÙĦØ®ÙĬ', 'ارات'] +['ãĤĴè¡Į', 'ãģĨ'] +['ש', '×ŀ×Ķ'] +['ĠLÃł', 'm'] +['ÙĪÙĨ', 'ÙĬ'] +['Ġ×IJ', '׾×Ļ×ķ'] +['Ä', 'ĺ'] +['à¹Ħมà¹Ī', 'สามารà¸ĸ'] +['人', 'ãģ¨'] +['بر', 'ز'] +['×Ļס', '×ķ×ĵ'] +['×Ĵ', '׾×Ļ'] +['ĠÙĬ', 'ÙĨا'] +['ĠÙĬÙĨا', 'ÙĬر'] +['ĠкаÑĢÑĤ', 'ин'] +['Ġt', 'ôn'] +['à¹Ģ', 'à¸ģร'] +['à¸Ħ', 'à¸Ķี'] +['Ġ׾×IJ', '×ķר×ļ'] +['ãĤĤãĤī', 'ãģĨ'] +['ãģĭ', 'ãģĭãĤĭ'] +['ани', 'и'] +['Ġara', 'ÅŁtırma'] +['ÙĦاØŃ', 'ظ'] +['ãģĦ', 'ãĤĦ'] +['ĠT', 'Ãłi'] +['Ġ', 'à¸Ļà¸Ńà¸ģà¸Īาà¸ģ'] +['Ġà¸Ļà¸Ńà¸ģà¸Īาà¸ģ', 'à¸Ļีà¹ī'] +['ĠÄIJ', 'ảng'] +['ãģ£ãģ¦', 'ãģįãģŁ'] +['Ġà¸ĭึà¹Īà¸ĩ', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['Ġt', 'ả'] +['Ġmożliwo', 'ÅĽÄĩ'] +['ĠS', 'ản'] +['Ġİ', 'ki'] +['Ġc', 'ắt'] +['س', 'Ø£ÙĦ'] +['Ġbak', 'ım'] +['Ø´', 'ب'] +['à¸ķ', 'ีà¹ī'] +['à¸ŀ', 'ยาย'] +['à¸ŀยาย', 'าม'] +['สั', 'à¸Ľ'] +['à¸ªà¸±à¸Ľ', 'à¸Ķา'] +['à¸ªà¸±à¸Ľà¸Ķา', 'หà¹Į'] +['ë°', 'Ģ'] +['еÑĢ', 'Ñĭ'] +['Ġc', 'ánh'] +['Ġthu', 'ế'] +['ت', 'بع'] +['ãģ«åħ¥', 'ãĤĮ'] +['Ñİ', 'ÑģÑĮ'] +['íļĮ', 'ìĿĺ'] +['ç°¡', 'åį'] +['ç°¡åį', 'ĺ'] +['ç°¡åįĺ', 'ãģ«'] +['Ġtr', 'úc'] +['ĠاÙĦÙĥ', 'ÙĪÙĬ'] +['ĠاÙĦÙĥÙĪÙĬ', 'ت'] +['ãĤıãģij', 'ãģ§ãģĻ'] +['ĠÑģв', 'об'] +['ĠÑģвоб', 'од'] +['ĠÑĥÑĩаÑģÑĤ', 'ник'] +['สิ', 'à¹īà¸Ļ'] +['ĠпÑĢо', 'ÑĦеÑģÑģиона'] +['ĠпÑĢоÑĦеÑģÑģиона', 'лÑĮн'] +['Ñģп', 'оÑĢ'] +['×Ĺ', '×ķ×ij×Ķ'] +['Ùħع', 'ÙĨÙī'] +['ĠاÙĦÙģ', 'ترة'] +['สูà¸ĩ', 'สุà¸Ķ'] +['ãĤı', 'ãģļ'] +['ĠÄij', 'è'] +['ĠÄijè', 'n'] +['æ¯Ķ', 'ãģ¹'] +['า', 'à¸ĺิ'] +['Ġmoż', 'emy'] +['à¹ģ', 'à¸ĭ'] +['à¸Īะ', 'à¹Ħมà¹Ī'] +['Ġs', 'ắp'] +['Ðļ', 'Ðŀ'] +['Ġprá', 'ctica'] +['ÙĪÙĥ', 'اÙĦØ©'] +['è¾¼', 'ãĤĵãģ§'] +['ológ', 'ica'] +['Ġе', 'Ñī'] +['ĠеÑī', 'Ñij'] +['تع', 'دÙĬÙĦ'] +['ĠØ£', 'Ùĥد'] +['Ġצר', '×Ļ׼'] +['Ġצר×Ļ׼', '×Ļ×Ŀ'] +['Ø«', 'Ùħ'] +['Ġк', 'ÑĢÑĥ'] +['ĠкÑĢÑĥ', 'п'] +['×ij×Ļ×§', '×ķרת'] +['Ġì¡°', 'ê¸Ī'] +['ãģ¨ãģį', 'ãģ¯'] +['Ġb', 'ạc'] +['ĠÑĢаÑģ', 'пол'] +['ĠÑĢаÑģпол', 'ож'] +['ĠÑĢаÑģполож', 'ен'] +['ز', 'ÙĬÙĨ'] +['ĠÐļ', 'ÑĢоме'] +['ĠاÙĦÙĨ', 'ظر'] +['×Ķ', '×ķ×ĵ'] +['ĠاÙĦس', 'بت'] +['ã썿ĢĿ', 'ãģĦ'] +['Ġpa', 'ÅĦst'] +['ĠpaÅĦst', 'w'] +['ĠÙĦÙĬ', 'ست'] +['ĠбÑĥд', 'Ñĥ'] +['à¸Ĺัà¸Ļ', 'à¸Ĺี'] +['ร', 'าม'] +['ØŃ', 'صÙĪÙĦ'] +['ãģĹãģ¦ãģıãĤĮ', 'ãĤĭ'] +['ĠاÙĦØ¥', 'سرائÙĬÙĦ'] +['ĠاÙĦإسرائÙĬÙĦ', 'ÙĬ'] +['ãģĵãĤĮ', 'ãģ¾ãģ§'] +['ìĤ¬', '를'] +['Ġs', 'ürü'] +['à¹Ģว', 'à¸Ńรà¹Į'] +['à¹Ģà¸ĭ', 'à¸Ńรà¹Į'] +['Ġutilis', 'é'] +['ĠÑģиÑģÑĤем', 'а'] +['Ġdw', 'ó'] +['Ġdwó', 'ch'] +['Ġpróp', 'rio'] +['Ġëĵ±', 'ìĿĦ'] +['arr', 'êt'] +['ĠЧ', 'а'] +['×IJ×ŀ', '׳×ķת'] +['عار', 'ض'] +['à¹Ģà¸ģม', 'สà¹Į'] +['Ġ׾×Ķ', '×ij×Ļף'] +['Ġ׾', '×ij×Ĺ'] +['Ġ׾×ij×Ĺ', '×ķר'] +['สา', 'à¸Ĥา'] +['ĠÐľÐ¾Ñģк', 'ве'] +['ب', 'عد'] +['ĠاÙĦÙĤر', 'ار'] +['ĠÄIJ', 'á»ĭa'] +['Ġ×Ĺ', '×Ĵ'] +['Ùģ', 'تر'] +['ÙĪÙĨ', 'Ø©'] +['Ġ×Ķ×ĸ', '×IJת'] +['å¸Ĥ', 'ãģ®'] +['ãģ»', 'ãģĹãģĦ'] +['Ġ×ij×¢', '×Ļר'] +['ĠÑĤеп', 'еÑĢÑĮ'] +['ìĬµ', 'ëĭĪê¹Į'] +['à¹Ħม', 'à¹Īว'] +['à¹Ħมà¹Īว', 'à¹Īา'] +['à¹Ħมà¹Īวà¹Īา', 'à¸Īะ'] +['×ŀ', '×IJ×Ķ'] +['æĥħ', 'åł±'] +['æĥħåł±', 'ãĤĴ'] +['غ', 'ÙĨ'] +['Ġпо', 'Ñı'] +['ĠпоÑı', 'ви'] +['éģİ', 'ãģĶ'] +['تش', 'غ'] +['تشغ', 'ÙĬÙĦ'] +['в', 'ел'] +['Ġ×Ĺ', '×ŀ'] +['ãģ¨ãģªãĤĬ', 'ãģ¾ãģĻ'] +['Ġra', 'ÄŁ'] +['ĠraÄŁ', 'men'] +['ãģĭ', 'ãģ©ãģĨ'] +['ãģĭãģ©ãģĨ', 'ãģĭ'] +['ен', 'ко'] +['ì§Ģ', 'ê³ł'] +['Ġ×IJ׾', '×Ļ×Ķ'] +['ĠØ£', 'ÙĦ'] +['à¸Īำ', 'หà¸Ļ'] +['à¸Īำหà¸Ļ', 'à¹Īาย'] +['nız', 'ı'] +['Ġ׾ק', '×Ĺת'] +['Ø£', 'ÙĩÙħ'] +['Ø£ÙĩÙħ', 'ÙĬØ©'] +['ت', 'غÙĬر'] +['ש', '×Ĺר'] +['ס×ķפ', 'ר'] +['×ĵ', '×Ļר'] +['èī¯', 'ãģĭãģ£ãģŁ'] +['×ŀ׾×Ĺ', '×ŀ×Ķ'] +['ÑģÑĤв', 'ие'] +['ÑĤ', 'ÑĢаÑĤ'] +['ĠاÙĦØ£', 'Ø®'] +['ĠاÙĦأخ', 'ÙĬرة'] +['ĠاÙĦØŃ', 'صÙĪÙĦ'] +['Ġcréd', 'ito'] +['צ', '×Ļ×¢'] +['ãĥ¬', 'ãĥĻãĥ«'] +['بر', 'ÙĬ'] +['ëIJ', 'IJ'] +['ãģł', 'ãģ£ãģ¦'] +['Ġreal', 'tÃł'] +['س', 'Ù쨱'] +['×ķ׳', '×ķ'] +['×Ĵ', '×ķ×ĵ'] +['×Ĵ×ķ×ĵ', '׾'] +['ฮ', 'า'] +['ãģĹãģ¦', 'ãģĬãĤĬãģ¾ãģĻ'] +['Ġg', 'Ãł'] +['Ġ׾×ij', 'צע'] +['å¼ķ', 'è¶ĬãģĹ'] +['Ġ×ŀ', '×Ļ׾×Ļ'] +['Ġ×ŀ×Ļ׾×Ļ', '×ķף'] +['Ùħ', 'در'] +['Ùħدر', 'سة'] +['פ', '×ķ×ĺ'] +['à¸Ļà¹īำ', 'มัà¸Ļ'] +['ëģ', 'Ŀ'] +['ع', 'Ùĥس'] +['ĠÙĤ', 'ض'] +['ĠÑĢÑĭ', 'б'] +['خط', 'Ø·'] +['×ŀ×ķס', '×ĵ'] +['Ġ׼׾', '׾×Ļ'] +['ĠкоÑĤоÑĢ', 'ое'] +['צ×Ļ', '×ķף'] +['ĠмеÑģÑĤ', 'а'] +['ãģĭ', 'ãģ¤'] +['г', 'ÑĢÑĥпп'] +['׾', '×Ļ׾'] +['ת', '×ķ×IJר'] +['ë³µ', 'ì§Ģ'] +['à¹ģà¸ľ', 'à¹Īà¸Ļ'] +['Ġ×ij×¢', 'ת'] +['æĻĤéĸĵ', 'ãĤĴ'] +['ï¼', '£'] +['ãģ¨ãģĦãģĨãģĵãģ¨', 'ãģ§'] +['Ġ׾×Ķ', '×§'] +['Ġ׾', '×ĸ×Ķ'] +['ĠìłĢ', 'ëĬĶ'] +['ĠاÙĦØ¥', 'رÙĩاب'] +['ĠìŀĪëĬĶ', 'ëį°'] +['ĠÑĤ', 'огда'] +['Ġ×Ķ', 'צ×Ļ'] +['×ķ׾', '×ĺ'] +['Ġר', 'פ×ķ×IJ×Ļ'] +['ãģĵãģ¨', 'ãģ§ãģĻ'] +['ĠÄij', 'ÃŃch'] +['ØŃ', 'ÙĬا'] +['Ġ×Ķ×ŀש', '×Ĺ×§'] +['ãģľ', 'ãģ²'] +['Ġ×ŀ×IJ', 'פשר'] +['ãģ¿', 'ãģ¾ãģĹãģŁ'] +['ĠاÙĦØ£ÙħÙĬر', 'ÙĥÙĬ'] +['Ùħج', 'تÙħع'] +['Ġس', 'اب'] +['Ġساب', 'ÙĤ'] +['׼', '×Ļ׾'] +['áº', '¾'] +['ãĥª', 'ãĤ¹ãĥĪ'] +['Ġì', 'ĥ'] +['Ġìĥ', 'Ī'] +['ĠìĥĪ', 'ë¡ľ'] +['ĠìĥĪë¡ľ', 'ìļ´'] +['ĠD', 'á»ĭch'] +['à¹Ģหมาะ', 'สม'] +['ĠاÙĦÙĨ', 'بÙĬ'] +['׾', '׾'] +['ÙĨ', 'ع'] +['Ðĵ', 'лав'] +['Ðĵлав', 'наÑı'] +['Ùħر', 'ض'] +['Ġ×ķ', '×ĵ'] +['ت', 'ÙĤÙĬ'] +['تÙĤÙĬ', 'ÙĬÙħ'] +['Ġb', 'ảng'] +['ĠÙģ', 'ÙĤاÙĦ'] +['×¢', '×ŀ×Ļ'] +['д', 'ÑĢа'] +['Ġsu', 'á»ijt'] +['سر', 'عة'] +['Ġc', 'á»Ń'] +['Ġ×Ķ', '×Ļ×Ĺ×Ļ×ĵ'] +['سع', 'ÙĬد'] +['à¸Ńา', 'à¸Ĭีà¸ŀ'] +['Ġس', 'ÙĪØ§Ø¡'] +['ãĤ½', 'ãĥķãĥĪ'] +['Ġл', 'иÑĩно'] +['ĠÐļ', 'оÑĢ'] +['اÙĩ', 'تÙħ'] +['اÙĩتÙħ', 'اÙħ'] +['à¸Ń', 'à¸Ķี'] +['à¸Ńà¸Ķี', 'à¸ķ'] +['ãģIJ', 'ãĤīãģĦ'] +['Ġiht', 'iya'] +['Ġihtiya', 'ç'] +['ãģ¾ãģ§', 'ãģ®'] +['ìĭľ', 'ìĬ¤'] +['ìĭľìĬ¤', 'íħľ'] +['ÑĢÑĥ', 'ÑĪ'] +['ãĤĦ', 'ãģ£ãģ±'] +['ãĤĦãģ£ãģ±', 'ãĤĬ'] +['к', 'еÑĢ'] +['Ġ', 'ży'] +['Ġży', 'w'] +['кл', 'он'] +['Ġl', 'ượt'] +['Ã', '¾'] +['да', 'Ñĩи'] +['tür', 'k'] +['غ', 'ÙĪ'] +['ĠигÑĢ', 'ок'] +['Ġph', 'ê'] +['Ġש', '×¢×ľ'] +['ĠاÙĦÙħ', 'دÙĨÙĬ'] +['ĠìŬ룬', 'ë¶Ħ'] +['ער', '×Ļ×Ŀ'] +['Ñħод', 'ÑıÑĤ'] +['Ġx', 'ứ'] +['ÐĹ', 'а'] +['ĠÙģ', 'رص'] +['à¸Īะ', 'à¸Ĺำà¹ĥหà¹ī'] +['íģ', '´'] +['×¢', '×ij×ķר'] +['à¹Ģหลà¹Īา', 'à¸Ļีà¹ī'] +['èĢĥãģĪ', 'ãĤĭ'] +['ÑĢ', 'еÑģÑĤ'] +['н', 'нÑĭй'] +['Ġc', 'ầm'] +['دا', 'Ø®ÙĦ'] +['ĠÙħÙĦÙĬ', 'ار'] +['ĠÐIJ', 'л'] +['ĠвÑĢем', 'ен'] +['à¸Ĭà¹Īวย', 'à¹ĥหà¹ī'] +['ר×Ļ', '×ķת'] +['ëĵ', '¯'] +['飲', 'ãģ¿'] +['׳', '׾'] +['שת', '×£'] +['ĠاÙĦسعÙĪØ¯', 'ÙĬ'] +['u', 'ÃŁ'] +['ìĿ¸', 'ëį°'] +['ĠìĿ¼', 'ë°ĺ'] +['ÅĤ', 'ÄĻ'] +['Ġm', 'á»iji'] +['×ŀ', '×Ļ׳'] +['ĠاÙĦØ£', 'Ø·Ù쨧ÙĦ'] +['Ġçı', 'kan'] +['é', 'cole'] +['×§', '×Ļש'] +['×§×Ļש', '×ķר'] +['ĠоÑģ', 'ÑĥÑīеÑģÑĤв'] +['ĠоÑģÑĥÑīеÑģÑĤв', 'лÑı'] +['×ij', '×IJר'] +['à¹Ħà¸Ľ', 'à¸Ķà¹īวย'] +['Ġ×¢', '×ķ׾×Ķ'] +['à¸ģà¹ĩ', 'à¹Ħมà¹Ī'] +['ãĥ¢', 'ãĥĩ'] +['ãĥ¢ãĥĩ', 'ãĥ«'] +['تØŃ', 'ÙĪÙĦ'] +['Ġод', 'ного'] +['ת×Ĺ×Ļ׾', 'ת'] +['Ġت', 'Ø®'] +['Ġch', 'cia'] +['Ġchcia', 'ÅĤ'] +['ãĥIJ', 'ãĥ³'] +['èĢħ', 'ãģ¯'] +['ĠÙħ', 'ØŃÙĦ'] +['Ñģл', 'ож'] +['Ñģлож', 'н'] +['Ġt', 'ÄĻ'] +['Ġçı', 'kt'] +['Ġçıkt', 'ı'] +['ĠC', 'Æ¡'] +['à¹Ħà¸Ķà¹ī', 'à¹Ģลย'] +['ır', 'ken'] +['à¹Ģà¸Ĥà¹īา', 'สูà¹Ī'] +['ÙħØŃ', 'Ùĥ'] +['ÙħØŃÙĥ', 'ÙħØ©'] +['à¸Ħุ', 'à¹īม'] +['à¸Ļà¹Īา', 'à¸Īะ'] +['лÑİ', 'д'] +['де', 'ÑģÑı'] +['деÑģÑı', 'ÑĤ'] +['ĠлÑİб', 'ой'] +['تØŃر', 'ÙĬر'] +['צע', '×ĵ'] +['Ġе', 'Ñij'] +['ĠاÙĦØŃ', 'ÙĥÙħ'] +['Ġص', 'باØŃ'] +['à¹Ģà¸ļ', 'à¸Ńรà¹Į'] +['Ġróż', 'nych'] +['ги', 'б'] +['ĠÑģ', 'оÑĤ'] +['ĠÑģоÑĤ', 'ÑĢÑĥд'] +['ĠÑģоÑĤÑĢÑĥд', 'ник'] +['ĠобÑĬ', 'ем'] +['פ', '×ĺר'] +['ãģĻãģĶ', 'ãģı'] +['ãģ«éĸ¢', 'ãģĹãģ¦'] +['в', 'ол'] +['Ø«', 'ÙħاÙĨ'] +['Ġd', 'ần'] +['æĬ', 'ľ'] +['æĬľ', 'ãģij'] +['Ġ×¢', 'ש'] +['Ġעש', '×ķ×Ļ'] +['ס', '×ķף'] +['ãģªãģ®', 'ãģ§ãģĻ'] +['ãģ¯', 'ãģ©ãģĨ'] +['×ŀ×¢', 'ר×ij'] +['ï¼', '°'] +['Ùħ', 'صر'] +['ÙħÙĨ', 'اسب'] +['ÙħÙĨاسب', 'Ø©'] +['ä¸Ĭ', 'ãģ®'] +['×IJ×Ļש', '×ķר'] +['ĠìĦ¤', 'ì¹ĺ'] +['×ŀ×ĵ×Ļ׳', '×ķת'] +['×ŀר', 'ת'] +['ãĤĭ', 'ãģ®ãģĮ'] +['د', 'Ùİ'] +['ĠاÙĦشر', 'Ùĥات'] +['ìĭľ', 'ê°Ħ'] +['ĠÑĢеÑĪ', 'ение'] +['ãģĻãĤĭ', 'ãģ®ãģ¯'] +['ĠìŀIJìĭł', 'ìĿĺ'] +['׾', '×ŀ×ķ'] +['ãģ¨ãģĵãĤį', 'ãģ§'] +['Ġ×§', 'צר'] +['Ġmã', 'i'] +['Ġkü', 'ltür'] +['ãĥ©ãĤ¤', 'ãĥĸ'] +['à¸ľà¸¹à¹ī', 'หà¸įิà¸ĩ'] +['æĻĤéĸĵ', 'ãģĮ'] +['клÑİÑĩ', 'и'] +['diÄŁ', 'iniz'] +['มาà¸ģ', 'à¹Ĩ'] +['تØŃ', 'ÙħÙĦ'] +['Ġh', 'ạt'] +['ãĤ¦', 'ãĤ£'] +['п', 'ле'] +['×ŀ', '׾×IJ'] +['ÅĤ', 'ó'] +['Ġg', 'á»ijc'] +['Ġ×IJ', '×ķ×ĵ×ķת'] +['หว', 'าà¸Ļ'] +['ĠاÙĦ', 'ÙĪØ²'] +['ĠاÙĦÙĪØ²', 'راء'] +['ëĵ¤', 'ê³¼'] +['Ġص', 'ØŃ'] +['ĠصØŃ', 'ÙĬÙ쨩'] +['Ġм', 'м'] +['تد', 'Ø®ÙĦ'] +['Ġpersön', 'lich'] +['Ġز', 'ÙĬ'] +['ĠزÙĬ', 'ادة'] +['ãĤ·', 'ãĤ¢'] +['Ġng', 'ắn'] +['à¸Ħล', 'ิà¸ģ'] +['Ġs', 'ông'] +['Ġtü', 'ket'] +['Ñį', 'ÑĦÑĦ'] +['ÑįÑĦÑĦ', 'екÑĤ'] +['ש', '×Ļ×ij'] +['Ġا', 'عت'] +['ت', 'ض'] +['تض', 'ÙħÙĨ'] +['ĠاÙĦÙħØ´', 'رÙĪØ¹'] +['Ġprodu', 'ção'] +['ĠпÑĢимен', 'Ñı'] +['ни', 'ÑĨÑĭ'] +['주', 'ëĬĶ'] +['ر', 'Ùı'] +['Ġm', 'Æ¡'] +['Ġhayat', 'ı'] +['ëŁ', '½'] +['Ġü', 'cret'] +['Ġyan', 'ında'] +['Ġpr', 'ática'] +['×ij×Ļ×§', '×ķר'] +['Ãľ', 'N'] +['Ñģ', 'оÑĤ'] +['ãĤıãģij', 'ãģ§'] +['Ġдол', 'го'] +['ת', '׼×ķ'] +['ĠìķĦ', 'ëĭĮ'] +['ë', 'į°ìĿ´'] +['Ġç', 'iz'] +['Ġcho', 'Äĩ'] +['Ġ×Ķ', '×Ļת'] +['Ġ×Ķ×Ļת', 'ר'] +['Ġso', 'át'] +['׼', '×ij×ĵ'] +['à¹Ģล', 'à¹Īา'] +['Ġд', 'еÑĢ'] +['ĠдеÑĢ', 'ев'] +['ãĤĴ', 'åħ¥ãĤĮ'] +['×Ĺ', '×ķס'] +['×Ĺ×ķס', 'ר'] +['ج', 'ÙĬÙĨ'] +['t', 'ón'] +['onn', 'é'] +['Ġпол', 'ноÑģÑĤÑĮÑİ'] +['人', 'ãģŁãģ¡'] +['Ġpr', 'êt'] +['ëł', '¸'] +['Ġdéc', 'embre'] +['cı', 'lar'] +['Ġת', 'ת'] +['Ġê²½ìļ°', 'ìĹIJëĬĶ'] +['ÙĪ', 'عد'] +['è¦ĭ', 'ãĤĭ'] +['วิ', 'à¸Īัย'] +['ë', '¶Ī'] +['ز', 'ÙĪØ§'] +['زÙĪØ§', 'ج'] +['d', 'ì'] +['ãģ§ãģĻ', 'ãĤĪ'] +['Ġвод', 'о'] +['ĠÙĬ', 'ÙĪØ¬Ø¯'] +['Ñģ', 'оÑģÑĤоÑı'] +['Ðŀ', 'С'] +['ĠÄIJ', 'ó'] +['×Ĺ', 'פש'] +['Ġצ', '×Ļ×ij×ķר'] +['ĠاÙĦÙĤ', 'Ø·'] +['ĠاÙĦÙĤØ·', 'اع'] +['Ġиме', 'ÑİÑĤ'] +['Ġph', 'áºŃn'] +['×Ľ×¡', 'פ×Ļ'] +['полн', 'иÑĤелÑĮ'] +['éĻIJ', 'ãĤĬ'] +['ĠÑģ', 'ÑĢав'] +['ĠÑģÑĢав', 'н'] +['ÙħاÙĦ', 'Ùĥ'] +['×ĵר', '×ķ×Ŀ'] +['çļĨ', 'ãģķãĤĵ'] +['ØŃÙĤ', 'ÙĤ'] +['à¹ģหล', 'à¹Īà¸ĩ'] +['ĠاÙĦر', 'سÙħÙĬ'] +['оÑĩ', 'ки'] +['×ĺ', '×ij×Ĺ'] +['Ġcan', 'lı'] +['Ġ׾', '׾'] +['Ġ׾׾', '×ŀ×ķ×ĵ'] +['×ŀ×ij', '×ķ'] +['ת', '׼'] +['×ª×Ľ', '׳×Ļת'] +['ĠاÙĦÙħ', 'شار'] +['ĠاÙĦÙħشار', 'ÙĥØ©'] +['İ', 'Åŀ'] +['ĠسÙĬ', 'اسÙĬ'] +['в', 'олÑĮ'] +['ĠÑģ', 'пÑĢав'] +['æĿ¥', 'ãģ¦'] +['פ×ķר', '×ķ×Ŀ'] +['สำ', 'à¹Ģรà¹ĩ'] +['สำà¹Ģรà¹ĩ', 'à¸Ī'] +['ĠÅŁ', 'öyle'] +['Ġzosta', 'ÅĤa'] +['ĠH', 'ü'] +['ר', '×ķש'] +['د', 'ÙĦÙĬÙĦ'] +['ÑĢи', 'д'] +['ש', 'ף'] +['×ŀ×§', '×ķר'] +['ĠÑĥ', 'Ñĩ'] +['ĠÑĥÑĩ', 'еб'] +['ĠÑį', 'ÑĤа'] +['ков', 'а'] +['à¸ķà¸Ļ', 'à¹Ģà¸Ńà¸ĩ'] +['ÙĨ', 'ÙIJ'] +['à¸Ńีà¸ģ', 'à¸Ħรัà¹īà¸ĩ'] +['ระ', 'à¸ļุ'] +['Ġd', 'ữ'] +['ĠاÙĦØŃ', 'اÙĦÙĬ'] +['׼', '×ķ׼'] +['׼×ķ׼', '×ij'] +['Ġ×ŀ×IJ', 'שר'] +['Ġtr', 'ụ'] +['ÑĤел', 'ем'] +['Ġв', 'ли'] +['Ġвли', 'Ñı'] +['Ġש×IJת', '×Ŀ'] +['Ġuw', 'ag'] +['Ġuwag', 'ÄĻ'] +['×ĺ', '×Ļת'] +['×IJ', '×ĵ×Ŀ'] +['à¸Ķ', 'ุ'] +['Ġ×Ķ×IJ', '׾×Ķ'] +['Ġkar', 'Ä±ÅŁ'] +['ĠÄIJ', 'á»iji'] +['да', 'ÑİÑĤ'] +['ãģªãģ®', 'ãģ«'] +['Äħ', 'cych'] +['à¹Ģà¸Ļ', 'à¹īà¸Ļ'] +['ãģĹãģ¦', 'ãģĹãģ¾ãģĨ'] +['int', 'érieur'] +['ĠfÃŃs', 'ica'] +['ĠÐŁ', 'ол'] +['ãģĹãģ', 'ķ'] +['à¸Ĺำ', 'à¹Ħม'] +['ĠL', 'âm'] +['ĠاÙĦÙħ', 'سÙĦÙħ'] +['ĠاÙĦÙħسÙĦÙħ', 'ÙĬÙĨ'] +['ص', 'ØŃØ©'] +['ìĹ', 'Ħ'] +['à¹Ģà¸Ķà¹ĩ', 'à¸Ķ'] +['ĠÑĥ', 'ÑĩеÑĤ'] +['â', 'Ìģ'] +['Ġب', 'ÙĦا'] +['ĠاÙĦاجتÙħاع', 'ÙĬ'] +['פרס', '×Ŀ'] +['ãĥķ', 'ãĥ©'] +['ĠÐļ', 'огда'] +['mie', 'ÅĽci'] +['ĠبÙĬÙĨ', 'Ùħا'] +['Ġ×ŀ×IJ', '×ŀר×Ļ×Ŀ'] +['Ġ×ij×IJ', '×ĸ×ķר'] +['×ķש', '×Ļ×Ŀ'] +['ĠÑģдел', 'а'] +['entr', 'ée'] +['à¹Ģ', 'à¸Ħà¹īา'] +['Ñĥг', 'л'] +['ĠاÙĦÙģ', 'ÙĨÙĬ'] +['ĠÐĴ', 'оÑĤ'] +['à¸Ĺีà¹Ī', 'มา'] +['×ķצ', '×Ĵ'] +['ÙĤد', 'رة'] +['Ġëª', '©'] +['Ġ목', 'ìłģ'] +['íıī', 'ê°Ģ'] +['ĠاÙĦØ£', 'ربع'] +['ĠاÙĦأربع', 'اء'] +['פס', '×Ļ×§'] +['ĠÑıвлÑı', 'ÑİÑĤÑģÑı'] +['ب', 'ÙĪÙĨ'] +['ì°', '¾'] +['×ŀ×¢', 'ר׼'] +['×ŀ×¢×¨×Ľ', '×ķת'] +['ãĤ·', 'ãĤ§'] +['ĠباÙĦ', 'Ø£'] +['íĸĪ', 'ëįĺ'] +['ĠاÙĦبر', 'ÙĨاÙħج'] +['ĠاÙĦØ£', 'ØŃد'] +['Ġm', 'Å©'] +['ĠmÅ©', 'i'] +['п', 'аÑĤ'] +['ب', 'Ø«'] +['ĠÑĨ', 'енÑĭ'] +['Ġ×ijת', '׾'] +['è¨Ģ', 'ãĤıãĤĮ'] +['ĠاÙĦÙħ', 'جاÙĦ'] +['ĠìĦ¸', 'ìĥģ'] +['Ġ×Ĵ', '×ķפ'] +['ĠнаÑĪ', 'ей'] +['Ġкомп', 'аниÑı'] +['б', 'ин'] +['öl', 'ü'] +['×Ļ', '×Ļ×ĺ'] +['Ġ×ŀס', 'פ×Ļ×§'] +['ยัà¸ĩ', 'à¸Ħà¸ĩ'] +['ĠЧ', 'и'] +['Ġан', 'ÑĤи'] +['ĠÑģÑĢед', 'и'] +['สà¹Īวà¸Ļ', 'à¹ĥหà¸įà¹Ī'] +['оÑĩ', 'ка'] +['íĬ¹', 'ë³Ħ'] +['ว', 'à¹Īาà¸ĩ'] +['гоÑĢ', 'од'] +['با', 'Ùĥ'] +['à¹Ģส', 'ีà¹Īย'] +['à¹Ģสีà¹Īย', 'à¸ĩ'] +['ãĤĤãĤī', 'ãģĦ'] +['×§', '×ķ×Ŀ'] +['ãģĽ', 'ãģļ'] +['ĠاÙĦÙĤ', 'اÙĩرة'] +['Ġ×ij', '׼×ļ'] +['Ùħشار', 'ÙĬع'] +['باØŃ', 'Ø«'] +['Ġпо', 'Ñĩ'] +['ĠпоÑĩ', 'ÑĤи'] +['ĠÑĦоÑĢм', 'а'] +['S', 'İ'] +['Ġ×ŀצ', '×Ļ×¢'] +['ล', 'ื'] +['ลื', 'ม'] +['ĠÑĤ', 'еÑĢ'] +['ĠÑĤеÑĢ', 'ÑĢиÑĤоÑĢ'] +['ĠÑĤеÑĢÑĢиÑĤоÑĢ', 'ии'] +['Ġв', 'меÑģÑĤ'] +['ĠвмеÑģÑĤ', 'е'] +['dıkl', 'arı'] +['op', 'ération'] +['à¹Ĥ', 'ห'] +['ص', 'دÙĬ'] +['صدÙĬ', 'ÙĤ'] +['íĸī', 'ìłķ'] +['تج', 'ا'] +['تجا', 'ÙĪØ²'] +['Ġsu', 'ç'] +['Ġar', 'ty'] +['Ġarty', 'ku'] +['Ġartyku', 'ÅĤ'] +['ãĤ·ãĥ§', 'ãĥĥãĥĹ'] +['ש', 'פ'] +['שפ', '×Ļ×¢'] +['Ġ×Ķש', '×Ļר×ķת'] +['à¹ģà¸ĸ', 'ม'] +['ë¸', 'Ķ'] +['Ġuk', 'ÅĤad'] +['Ġ×ķ', '׼×Ļ'] +['หล', 'าà¸ģ'] +['หลาà¸ģ', 'หลาย'] +['æĸ¹', 'ãĤĤ'] +['Ġpodr', 'óż'] +['ĠE', 'ÄŁer'] +['Ġком', 'наÑĤ'] +['ĠÑģам', 'ÑĭÑħ'] +['Ġв', 'кÑĥÑģ'] +['б', 'еж'] +['Ġ×ij', '×§×ķ'] +['æİĽ', 'ãģij'] +['ãģ¿', 'ãĤĭãģ¨'] +['ĠiliÅŁ', 'kin'] +['ĠÙĬ', 'عÙħÙĦ'] +['Ġпод', 'аÑĢ'] +['Ġyaz', 'ılı'] +['ãĤĴ', 'å¾Ĺ'] +['Ġwyst', 'ÄĻp'] +['à¸Ĺีà¹Ī', 'à¹ĥà¸Ĭà¹ī'] +['ØŃاد', 'Ø«'] +['ÙĪ', 'ÙĬد'] +['кÑĥ', 'лÑĮÑĤ'] +['кÑĥлÑĮÑĤ', 'ÑĥÑĢ'] +['à¸ģาร', 'à¹ģà¸Ĥà¹Īà¸ĩ'] +['à¸ģารà¹ģà¸Ĥà¹Īà¸ĩ', 'à¸Ĥ'] +['à¸ģารà¹ģà¸Ĥà¹Īà¸ĩà¸Ĥ', 'ัà¸Ļ'] +['ÙħÙĪ', 'ظ'] +['ÙħÙĪØ¸', 'Ùģ'] +['ÙĬÙħ', 'ÙĬ'] +['ãĤĵãģ§ãģĻ', 'ãģĮ'] +['diÄŁ', 'im'] +['diÄŁim', 'iz'] +['ĠÐŁ', 'еÑĢ'] +['ĠÐŁÐµÑĢ', 'в'] +['Ġm', 'ão'] +['ĠÑģ', 'ез'] +['ĠÑģез', 'он'] +['Ġ×Ķ×ŀ', '×¢'] +['Ùħ', 'جÙħÙĪØ¹Ø©'] +['ĠинÑĦоÑĢм', 'аÑĨии'] +['i', 'ếc'] +['ã', 'ng'] +['ĠÄij', 'ấy'] +['ãģĶ', 'ç´'] +['ãģĶç´', '¹'] +['ãģĶç´¹', 'ä»ĭ'] +['Ġad', 'ım'] +['à¹Ħ', 'หล'] +['Ġп', 'ÑĢакÑĤи'] +['ĠпÑĢакÑĤи', 'Ñĩ'] +['ĠпÑĢакÑĤиÑĩ', 'еÑģ'] +['ĠпÑĢакÑĤиÑĩеÑģ', 'ки'] +['ĠاÙĦÙĨ', 'Ù쨳'] +['ĠÑĢабоÑĤ', 'е'] +['ÙĦÙĬ', 'Ùģ'] +['ĠاÙĦجÙĨ', 'ÙĪØ¨'] +['Ġвод', 'Ñĭ'] +['ì¹', 'Ļ'] +['Ġм', 'иÑĢа'] +['ĠÄij', 'ừng'] +['ĠпÑĢоÑĤив', 'о'] +['ĠÑģÑĤÑĢан', 'Ñĭ'] +['ล', 'ู'] +['ìĤ', '¶'] +['kre', 'ÅĽl'] +['Ġbul', 'und'] +['Ġbulund', 'uÄŁu'] +['à¹ģ', 'สà¸Ļ'] +['ãĤ±', 'ãĤ¢'] +['ת×Ĺ', '×ķ×ŀ×Ļ'] +['ר׼', '×Ķ'] +['Ġ׾ק', '×ķ×Ĺ'] +['Ġ׾ק×ķ×Ĺ', '×ķת'] +['Ġ×Ľ×ª', '×ķ×ijת'] +['ĠÙĦ', 'ÙĥÙħ'] +['ب', 'شر'] +['Ġr', 'Ãłng'] +['Ġ×ŀ×Ķ', '×ŀ'] +['Ġ×IJ×Ĺר', '×ķת'] +['Ġб', 'он'] +['Ġбон', 'ÑĥÑģ'] +['ï½', 'Ĺ'] +['à¹ģ', 'ยà¸ģ'] +['ãģĤãģªãģŁ', 'ãģ®'] +['ĠÑĥÑĩаÑģÑĤ', 'ие'] +['ĠE', 'yl'] +['ĠEyl', 'ül'] +['ĠçalÄ±ÅŁmalar', 'ı'] +['Ø®', 'طر'] +['ìĿ', '½'] +['à¸ģาร', 'à¹ĥà¸Ĭà¹īà¸ĩาà¸Ļ'] +['Ġана', 'лиз'] +['תק', '×ij׾'] +['ни', 'ем'] +['Ġİ', 'ns'] +['Ġİns', 'an'] +['ĠبÙĪ', 'اس'] +['ĠبÙĪØ§Ø³', 'طة'] +['Ġ׳', '×Ľ×ł×¡'] +['Ġ×Ķ×ŀ', '×Ļ×ĵ×¢'] +['Ġç', 'o'] +['Ġço', 'ÄŁu'] +['á»', 'ĺ'] +['ĠêµŃ', '민'] +['ãĤĤ', 'ãģĦãģĦ'] +['Ġ׼', '׾×Ļ'] +['ĠÑģÑĢед', 'не'] +['g', 'ÅĤo'] +['gÅĤo', 'ÅĽ'] +['Ġneg', 'ó'] +['Ġnegó', 'cio'] +['ĠÑĢ', 'егиÑģÑĤ'] +['ĠÑĢегиÑģÑĤ', 'ÑĢа'] +['ĠÑĢегиÑģÑĤÑĢа', 'ÑĨии'] +['Ġtr', 'á»ĵng'] +['ĠпÑĢ', 'Ñı'] +['ĠпÑĢÑı', 'мо'] +['ëłĪ', 'ìĿ´'] +['Ġk', 'ém'] +['к', 'ле'] +['à¸Ļำ', 'มา'] +['ĠÑĦ', 'ин'] +['ĠÑĦин', 'анÑģ'] +['ĠÑĦинанÑģ', 'ов'] +['Ġki', 'á»ĩm'] +['ยัà¸ĩ', 'à¹Ħ'] +['ยัà¸ĩà¹Ħ', 'à¸ĩ'] +['ย', 'ิà¸ĩ'] +['à¹Ĥ', 'à¸Ľ'] +['ĠполÑĥÑĩ', 'ил'] +['×Ļ×ĸ', '×Ŀ'] +['à¹ģละ', 'à¸Ħวาม'] +['Ġво', 'обÑīе'] +['ص', 'ÙĬر'] +['ãĥı', 'ãĥ³'] +['ĠاÙĦÙĤ', 'اد'] +['ĠاÙĦÙĤاد', 'Ùħ'] +['Ġب', 'دÙĪÙĨ'] +['ع', 'ظÙħ'] +['ת', '׳×ķ×¢'] +['×ª×ł×ķ×¢', '×Ķ'] +['Ø£', 'ÙħÙĦ'] +['ãģķ', 'ãģĪ'] +['ÑĤ', 'ем'] +['ÑĤем', 'пеÑĢ'] +['ÑĤемпеÑĢ', 'аÑĤÑĥÑĢ'] +['Ġ׾', '×Ļצ×ķר'] +['Ġr', 'ÄĻk'] +['ر', 'سÙĦ'] +['ìŀIJ', '를'] +['Ġ×Ļצ', '×Ļרת'] +['ÙĨ', 'بÙĬ'] +['Ñĩ', 'наÑı'] +['تØŃ', 'ÙĦÙĬÙĦ'] +['Ġм', 'ик'] +['Ġмик', 'ÑĢо'] +['ĠS', 'öz'] +['Ġfor', 'ça'] +['Ñģ', 'он'] +['ĠاÙĦع', 'را'] +['ĠاÙĦعرا', 'ÙĤÙĬ'] +['ĠH', 'á»ĵng'] +['ãģĻãĤĭ', 'ãģŁãĤģãģ«'] +['à¸Ĺีà¹Ī', 'à¸Ńยูà¹Ī'] +['Ġ×ķ×IJ', '×£'] +['ص', 'ÙĬد'] +['ĠìķĬ', 'ê³ł'] +['ร', 'ัà¸ĩ'] +['ĠاÙĦت', 'ÙĪØ§ØµÙĦ'] +['à¹Ģม', 'à¸ķร'] +['Ñĥ', 'ÑģÑĤÑĢой'] +['ÑĥÑģÑĤÑĢой', 'ÑģÑĤв'] +['m', 'ıyor'] +['Ġبا', 'سÙħ'] +['Ġ×ķ', '׼×ķ'] +['ĠG', 'ül'] +['á»', 'IJ'] +['Ãī', 'tat'] +['غ', 'اÙĦ'] +['Ø¥', 'ÙĨØ´'] +['Ø¥ÙĨØ´', 'اء'] +['T', 'İ'] +['à¸Ĥà¹īา', 'ม'] +['Ġtro', 'ch'] +['Ġtroch', 'ÄĻ'] +['Ø¥', 'ص'] +['إص', 'ابة'] +['ĠØ«', 'اÙĨÙĬ'] +['ĠاÙĦص', 'ØŃØ©'] +['Ġ×ĸ×Ķ', '×ķ'] +['jÄħ', 'cej'] +['ãĥĢ', 'ãĥ³'] +['ìĿ¸', 'ìĿ´'] +['Ġв', 'олоÑģ'] +['ëIJĺ', 'ë©´'] +['Ġzak', 'ÅĤad'] +['ãģĻ', 'ãģĵãģ¨'] +['以ä¸Ĭ', 'ãģ®'] +['Ġ×Ķ×ŀ×§', '×ķ×Ŀ'] +['ÙħØ´', 'اÙĩ'] +['ÙħشاÙĩ', 'دة'] +['Ñĩ', 'ив'] +['ب', 'Ø´'] +['ย', 'à¹īาย'] +['Ġsür', 'dür'] +['ĠN', 'ẵ'] +['ĠNẵ', 'ng'] +['ĠигÑĢ', 'аÑĤÑĮ'] +['Ġê·¸ëŁ¬', 'ë©´'] +['ãĥķ', 'ãĥ«'] +['ล', 'à¹Īะ'] +['Ġtend', 'rá'] +['Ġb', 'Ãły'] +['à¹Ģà¸Ľà¹ĩà¸Ļ', 'à¸ľà¸¹à¹ī'] +['Ġok', 'o'] +['Ġoko', 'ÅĤo'] +['w', 'ÅĤa'] +['wÅĤa', 'ÅĽci'] +['wÅĤaÅĽci', 'w'] +['æĢĿ', 'ãĤı'] +['ĠYa', 'ÅŁ'] +['ĠB', 'á»ĩnh'] +['íı', 'Ń'] +['بÙĬ', 'د'] +['קר', 'ף'] +['à¹Ģศ', 'ร'] +['à¹Ģศร', 'ษ'] +['à¹Ģศรษ', 'à¸IJ'] +['à¹Ģศรษà¸IJ', 'à¸ģิà¸Ī'] +['ĠاÙĦØ£', 'ÙĪØ±ÙĪ'] +['ĠاÙĦØ£ÙĪØ±ÙĪ', 'بÙĬ'] +['fl', 'äche'] +['ä¹Ĺ', 'ãĤĬ'] +['Ġb', 'á»ģn'] +['Ùĩ', 'ب'] +['æľĢ', 'ãĤĤ'] +['Ġsa', 'ç'] +['à¸Ńำ', 'à¹Ģà¸ł'] +['à¸Ńำà¹Ģà¸ł', 'à¸Ń'] +['ĠØ£', 'ج'] +['ĠاÙĦد', 'اخÙĦ'] +['ĠاÙĦداخÙĦ', 'ÙĬØ©'] +['×ĺ', '×ķ×ij'] +['ãĤĤ', 'ãģªãģı'] +['Ġли', 'ÑĨа'] +['à¹ģลà¹īว', 'à¸ģà¹ĩ'] +['×ĸ׼', '×Ļר'] +['Ġqu', 'Ãł'] +['ĠÙĥ', 'ذÙĦÙĥ'] +['صØŃ', 'Ùģ'] +['ĠÃĤ', 'u'] +['ÙĪØ¨', 'ا'] +['à¹Ģà¸Ľà¸¥à¸µà¹Īยà¸Ļ', 'à¹ģà¸Ľà¸¥'] +['à¹Ģà¸Ľà¸¥à¸µà¹Īยà¸Ļà¹ģà¸Ľà¸¥', 'à¸ĩ'] +['à¸ķัว', 'à¸Ńยà¹Īาà¸ĩ'] +['Ġráp', 'ida'] +['Ġtas', 'ar'] +['Ġtasar', 'ım'] +['ĠعÙĦÙĬ', 'ÙĩÙħ'] +['ס', '×ķ׾'] +['c', 'ılı'] +['cılı', 'k'] +['Ġر', 'غÙħ'] +['ìĭľ', 'íĤ¤'] +['Ġ×IJ׾', '×§'] +['Ġ×IJ׾ק', '×ĺר'] +['Ġ×IJ׾ק×ĺר', '×ķ׳×Ļ'] +['à¹ģà¸ļ', 'à¹Īà¸ĩ'] +['Ġh', 'ạng'] +['ãģ£ãģ¦', 'ãģıãĤĮ'] +['ĠÙĨ', 'تÙĬ'] +['ĠÙĨتÙĬ', 'جة'] +['ıkl', 'ı'] +['غ', 'اÙĨ'] +['à¸Ĥà¹īà¸Ń', 'à¸Ħวาม'] +['à¸Ľà¸¥', 'าย'] +['ĠØ£', 'Ùħس'] +['à¸Ĺีà¹Ī', 'à¹Ģà¸ģีà¹Īยว'] +['à¸Ĺีà¹Īà¹Ģà¸ģีà¹Īยว', 'à¸Ĥ'] +['à¸Ĺีà¹Īà¹Ģà¸ģีà¹Īยวà¸Ĥ', 'à¹īà¸Ńà¸ĩ'] +['Ġdé', 'fin'] +['Ġdéfin', 'i'] +['ÙģÙĨ', 'اد'] +['ÙģÙĨاد', 'ÙĤ'] +['à¹Ħà¸Ķà¹ī', 'วà¹Īา'] +['ãģªãģĦ', 'ãĤĪãģĨãģ«'] +['Ġpróp', 'ria'] +['ĠPh', 'át'] +['ãĤĦãģĻ', 'ãģı'] +['สวย', 'à¸ĩาม'] +['ê³ł', 'ìļĶ'] +['Ñı', 'еÑĤ'] +['ãģĭãĤĤãģĹãĤĮãģ¾ãģĽãĤĵ', 'ãģĮ'] +['تر', 'جÙħ'] +['ĠкÑĢаÑģ', 'ив'] +['Ġ×ŀ', 'ר×IJש'] +['д', 'еж'] +['ĠÙĬ', 'ÙĪÙĨ'] +['ĠÙĬÙĪÙĨ', 'ÙĬÙĪ'] +['Ñģк', 'оÑĢ'] +['ĠKas', 'ım'] +['ê³Ħ', 'ìķ½'] +['к', 'оÑģ'] +['Ġна', 'ÑĢÑĥ'] +['ĠнаÑĢÑĥ', 'ÑĪен'] +['Ġdu', 'że'] +['acc', 'ès'] +['Ġh', 'á»ĵng'] +['Ġv', 'Å©'] +['ãģĦãģŁ', 'ãģĹãģ¾ãģĻ'] +['Ġ×ĺ', '×Ļ'] +['Ġ×ĺ×Ļ', '×ķ׾'] +['lıkl', 'arı'] +['Ġqu', 'ê'] +['ëħ¸', 'ëıĻ'] +['ìķ', 'Ķ'] +['CI', 'ÃĵN'] +['Ġt', 'ắc'] +['press', 'ão'] +['ĠìŀĪ', 'ìľ¼'] +['สิà¸Ĺà¸ĺิ', 'à¹Į'] +['íĥ', 'Ħ'] +['Ġ×Ķ×ŀ', '×ŀש׾×Ķ'] +['å¬ī', 'ãģĹãģĦ'] +['ĠÄIJ', 'ặc'] +['ÙĨ', 'زÙĦ'] +['ĠдÑĢÑĥг', 'ой'] +['д', 'ÑĥÑĤ'] +['ìĪ', 'Ļ'] +['Ġth', 'ụ'] +['à¹Ģส', 'ร'] +['à¹Ģสร', 'à¹ĩ'] +['à¹Ģสรà¹ĩ', 'à¸Ī'] +['Ġto', 'plant'] +['Ġtoplant', 'ı'] +['×IJ×ŀ', 'ף'] +['×ķ׾', 'ת'] +['п', 'омн'] +['Ġyo', 'ÄŁun'] +['ÅĦsk', 'iego'] +['ì°', '©'] +['ĠØ«', 'ÙĦاث'] +['ĠØ«ÙĦاث', 'Ø©'] +['Ġl', 'ắng'] +['ë¦', '´'] +['ราà¸Ĭ', 'à¸ģาร'] +['ĠÑģлов', 'а'] +['á»', 'Ĩ'] +['à¸Ķี', 'à¸ģวà¹Īา'] +['ãģĶãģĸ', 'ãģĦãģ¾ãģĻ'] +['Ġд', 'из'] +['Ġдиз', 'айн'] +['fé', 'rence'] +['lıkl', 'ar'] +['ãģªãĤĵ', 'ãģ§ãģĻ'] +['ajÄħ', 'cy'] +['Ġëĭ¤', 'ìĸij'] +['Ġëĭ¤ìĸij', 'íķľ'] +['×§', '×Ļר'] +['ØŃ', 'ار'] +['ส', 'ูà¹ī'] +['Ġz', 'ro'] +['Ġzro', 'bi'] +['Ġzrobi', 'Äĩ'] +['×ŀ', '×Ļ׼×Ķ'] +['à¸Ĭà¹Īวย', 'à¹Ģหลืà¸Ń'] +['ĠÑįÑĤ', 'Ñĥ'] +['ë´', 'ī'] +['楽', 'ãģĹãģĦ'] +['س', 'ÙĪØ±'] +['íķĺ', 'ê±°ëĤĺ'] +['Ùħؤ', 'تÙħر'] +['Ġpoc', 'zÄħ'] +['ĠpoczÄħ', 'tk'] +['ĠpoczÄħtk', 'u'] +['Ġع', 'ربÙĬ'] +['اÙĦØ£', 'ر'] +['اÙĦأر', 'دÙĨ'] +['à¸Ķ', 'ร'] +['Åĵ', 'uvre'] +['ĠÙĪÙĥ', 'اÙĨت'] +['ĠÅĽ', 'redni'] +['Ø®', 'ضر'] +['Ġch', 'uyến'] +['н', 'ÑĤ'] +['ĠìķĮ', 'ê³ł'] +['Ġv', 'á»Ŀi'] +['Ġ×ij', '×Ļ×ĵ×Ļ'] +['×ŀ×ĵ', '×ķ×ijר'] +['ÙĪ', 'Ù쨱'] +['ÙĬ', 'Ø¡'] +['׳', '×Ľ×¡'] +['ĠÐĽ', 'а'] +['л', 'он'] +['Ġx', 'ấu'] +['Ùģ', 'ÙĬÙĨ'] +['Ġfé', 'vrier'] +['ĠÐŀ', 'на'] +['ĠV', 'á»ģ'] +['ĠÅŁey', 'ler'] +['ĠполÑĥÑĩ', 'ен'] +['з', 'ад'] +['Ġn', 'ét'] +['à¹Ħà¸Ľ', 'ยัà¸ĩ'] +['×Ĺש×ij', '×ķ'] +['à¸ļัà¸Ļ', 'à¸Ĺ'] +['à¸ļัà¸Ļà¸Ĺ', 'ึà¸ģ'] +['Ġgerçek', 'leÅŁ'] +['иÑĩеÑģк', 'ое'] +['ìĪĺ', 'ê°Ģ'] +['Ø«', 'بت'] +['ãģ¤', 'ãģ¾ãĤĬ'] +['ĠÑĥÑģловиÑı', 'Ñħ'] +['ëĭ¤', 'ê°Ģ'] +['ราย', 'à¹Ħà¸Ķà¹ī'] +['׼×IJ', '×ij'] +['à¹Ĥà¸Ľà¸£', 'à¹Ĥม'] +['à¹Ĥà¸Ľà¸£à¹Ĥม', 'à¸Ĭัà¹Īà¸Ļ'] +['j', 'ähr'] +['jähr', 'ige'] +['×§', '׳×Ļ×Ŀ'] +['×ŀ', '×ķ×§'] +['×ŀ×ķ×§', '×ĵ'] +['ãģ«è¡Į', 'ãģ£ãģ¦'] +['Ø¢', 'ÙĦ'] +['вед', 'ение'] +['Ġ׾', '×Ľ×ª×ķ×ij'] +['جÙħ', 'Ùĩ'] +['جÙħÙĩ', 'ÙĪØ±ÙĬØ©'] +['à¸ī', 'à¸ļ'] +['à¸īà¸ļ', 'ัà¸ļ'] +['ĠC', 'òn'] +['à¸ľ', 'สม'] +['ãģªãģ©', 'ãģĮ'] +['×IJ×Ķ', '×ij'] +['ĠдейÑģÑĤв', 'иÑı'] +['y', 'ız'] +['à¹Ħมà¹Ī', 'à¹Ģà¸Ħย'] +['ج', 'ÙĪØ²'] +['×Ķ×Ĺ׾×ĺ', '×Ķ'] +['f', 'ällt'] +['ãĥĵ', 'ãĤ¸'] +['ãĥĵãĤ¸', 'ãĥį'] +['ãĥĵãĤ¸ãĥį', 'ãĤ¹'] +['Ġ×IJ', '×Ļ׳×Ŀ'] +['ĠнаÑħод', 'иÑĤÑģÑı'] +['Ġdzi', 'ÅĽ'] +['ست', 'Ø·ÙĬع'] +['׾', '×Ļף'] +['Ø®', 'ÙĦاÙģ'] +['Ùĩ', 'ÙIJ'] +['Ġatr', 'ás'] +['íĺ', 'ģ'] +['ãĤĴ', 'ãģĶ'] +['Ġ×Ķ×ŀ', '×ķצר'] +['ĠBakan', 'lıģı'] +['ÑİÑī', 'ее'] +['ÙħÙĨ', 'اط'] +['ÙħÙĨاط', 'ÙĤ'] +['Ùģ', 'د'] +['à¸Ļำ', 'à¹Ħà¸Ľ'] +['Ġв', 'аж'] +['Ġваж', 'но'] +['Ġm', 'ạch'] +['׼', '׳×ķ'] +['بع', 'Ø«'] +['lan', 'ması'] +['Ġa', 'yr'] +['Ġayr', 'ıl'] +['ìĤ¬', 'íļĮ'] +['d', 'ÃŃa'] +['p', 'ÅĤyw'] +['اÙħ', 'ÙĬØ©'] +['íĺ', 'ľ'] +['×IJ׳', '×Ĵ׾'] +['×IJ׳×Ĵ׾', '×Ļת'] +['ĠìŀĪëĭ¤', 'ëĬĶ'] +['Ġس', 'اعة'] +['ĠëĤĺ', 'íĥĢ'] +['b', 'ö'] +['à¸Ħ', 'ัà¸Ļ'] +['ĠdziaÅĤ', 'ania'] +['Ø©', 'Ùĭ'] +['Ġng', 'Å©'] +['׳צ', '×Ĺ'] +['ãģ¯', 'ãģĤãĤĭ'] +['ĠyaÅŁ', 'ında'] +['st', 'ück'] +['car', 'acter'] +['caracter', 'ÃŃsticas'] +['Ġr', 'á»Ńa'] +['ĠÙħختÙĦÙģ', 'Ø©'] +['ãģ«ãģĬ', 'ãģijãĤĭ'] +['à¹ģà¸ŀ', 'à¸ĩ'] +['วิ', 'à¹Īà¸ĩ'] +['ת', 'פ×ķ'] +['سا', 'ÙĩÙħ'] +['使', 'ãģĨ'] +['Ùĥ', 'رÙĬ'] +['×IJ', 'פ×Ļ'] +['........', '.......'] +['ĠÑĤак', 'им'] +['×Ļ׼', '×ķ×Ļ'] +['Ø´', 'بÙĩ'] +['ج', 'ÙĬر'] +['ãģĿãģ®', 'ãģ¾ãģ¾'] +['ac', 'jÄĻ'] +['ĠاÙĦت', 'رÙĥ'] +['ĠاÙĦترÙĥ', 'ÙĬ'] +['ĠпÑĢав', 'илÑĮно'] +['Ġت', 'عÙħÙĦ'] +['à¸ģล', 'à¹īา'] +['Ġbi', 'ên'] +['Ġ×ij׳×Ļ', '×Ļת'] +['Ġкл', 'Ñĥб'] +['Ġ×ŀ', 'ש×Ķ'] +['в', 'ÑĪий'] +['ãģĵãģ¨ãģĮãģ§ãģį', 'ãĤĭ'] +['à¸ŀัà¸Ļà¸ĺ', 'ุ'] +['à¸ŀัà¸Ļà¸ĺุ', 'à¹Į'] +['ר', '×ķ×Ŀ'] +['ĠاÙĦÙģ', 'رÙĨ'] +['ĠاÙĦÙ쨱ÙĨ', 'سÙĬ'] +['à¹Ģà¸Ľà¹ĩà¸Ļ', 'à¸Ħà¸Ļ'] +['ãģĹãģ¦', 'ãģĬãĤĬ'] +['Ġth', 'ầy'] +['ãĤĵ', 'ãģłãģijãģ©'] +['ìĶ', '¨'] +['Ùħ', 'دÙĨ'] +['ت', 'ÙĪÙĨ'] +['ĠмеÑĤ', 'ал'] +['ĠмеÑĤал', 'л'] +['Ġin', 'ÃŃcio'] +['à¸Ńà¸Ńà¸ģ', 'à¸Īาà¸ģ'] +['ëĴ', '¤'] +['Ġcu', 'á»ijn'] +['Ġbu', 'á»Ļc'] +['ÙĨ', 'سÙĬ'] +['ä', 'cht'] +['×ŀ', '×Ļ׳×Ļ×Ŀ'] +['ãģķ', 'ãģ¦'] +['ãģĮ', 'ãģ§ãģį'] +['ÑĬ', 'ем'] +['Ġtá', 'i'] +['ĠЧ', 'ÑĤ'] +['ĠЧÑĤ', 'обÑĭ'] +['à¸Ľà¸¥', 'ูà¸ģ'] +['à¸Ĭุม', 'à¸Ĭà¸Ļ'] +['н', 'Ñģкий'] +['Ġv', 'ững'] +['Ġ×Ķ', '׾×ij'] +['ë', 'le'] +['Ġש', '×¢×ijר'] +['в', 'аÑĤÑĮÑģÑı'] +['б', 'ой'] +['ع', 'ÙĪÙĨ'] +['à¹ģà¸Ķ', 'à¸Ļ'] +['Ġספר', '×Ļ×Ŀ'] +['Ġt', 'uyên'] +['Ġnhi', 'êu'] +['ĠQu', 'ý'] +['Ġh', 'uyết'] +['ãĤı', 'ãģĭãĤīãģªãģĦ'] +['Ġ×ŀ', '׼ף'] +['Ġ×Ķ', 'ק׾'] +['Ġ׾×IJ', '×ķר'] +['ĠÄIJi', 'á»ĩn'] +['Ø´', 'ؤ'] +['شؤ', 'ÙĪÙĨ'] +['Ġ×ŀ×Ĺ', 'פש'] +['ĠпоÑģÑĤоÑıн', 'но'] +['×ŀ', '×Ļר'] +['ìħ', 'Ķ'] +['Ðŀ', 'Ñģ'] +['ÐŀÑģ', 'нов'] +['×ĸ', '×Ļת'] +['ĠH', 'á'] +['ĠÑĩаÑģ', 'ов'] +['×IJ', '×ķ׾×Ļ'] +['Ġm', 'át'] +['Ø®', 'رÙĪ'] +['خرÙĪ', 'ج'] +['ÙĤ', 'ضا'] +['ÙĤضا', 'ÙĬا'] +['à¹Ģà¸Ľ', 'à¸Ńรà¹Į'] +['ĠÙĬ', 'ÙĪÙĦ'] +['ĠÙĬÙĪÙĦ', 'ÙĬÙĪ'] +['à¹Ĥà¸Ĺ', 'ษ'] +['׳', 'פ׾'] +['ת', '×ķש'] +['ת×ķש', '×ij×Ļ'] +['Ġv', 'ários'] +['×ŀ', 'ר×IJ×Ķ'] +['ëĿ¼', 'ìĿ´'] +['ÙĨ', 'غ'] +['×ij', 'צע'] +['г', 'он'] +['ĠÄIJ', 'ược'] +['ع', 'Ùı'] +['пÑĥÑģ', 'к'] +['ĠÙĪØ§ÙĦ', 'Ùģ'] +['üc', 'ü'] +['×Ļ×§', '×Ļ×Ŀ'] +['Ġس', 'بÙĬÙĦ'] +['׾×ij', 'ף'] +['ĠاÙĦÙĤ', 'رÙĨ'] +['ס', '×ķת'] +['ĠQu', 'áºŃn'] +['ãģĵãĤĮ', 'ãģĮ'] +['ãĥĸ', 'ãĥ©ãĥ³ãĥī'] +['×Ĵ', '×ŀר'] +['Ġwarto', 'ÅĽci'] +['ĠÙĪØ¨', 'ÙĬÙĨ'] +['Ġd', 'ạ'] +['ÐIJ', 'в'] +['ÐIJв', 'ÑĤо'] +['Ġol', 'acaktır'] +['à¸Ļ', 'à¸Ĺà¹Į'] +['Ùħ', 'طار'] +['Ġ×¢', '×§×ij'] +['Ġת', 'פ'] +['ãģĹãģ¦', 'ãģĦãģ¦'] +['צ', '×ŀ×Ĺ'] +['à¸Ī', 'à¸Ńà¸ĩ'] +['Ġö', 'de'] +['ìį', '¨'] +['ÙĨ', 'اس'] +['調', 'ãģ¹'] +['ĠогÑĢ', 'омн'] +['ë³´', 'íĹĺ'] +['×ĺ', '×§'] +['×ĺ×§', 'ס×ĺ'] +['ĠbaÅŁ', 'v'] +['ĠbaÅŁv', 'uru'] +['Ġpom', 'ys'] +['Ġpomys', 'ÅĤ'] +['ãģ«', 'ä¹Ĺ'] +['Ġש', '׼ף'] +['ĠاÙĦÙħس', 'ؤÙĪÙĦ'] +['Ġз', 'ан'] +['Ġзан', 'ÑıÑĤ'] +['Ġd', 'ương'] +['ãĥĹãĥ¬', 'ãĤ¤'] +['ล', 'à¸ļ'] +['ÑĤи', 'ка'] +['ĠAr', 'alık'] +['Ġнед', 'о'] +['Ġm', 'á»Ļ'] +['Ġor', 'an'] +['Ġoran', 'ı'] +['Ġktó', 'r'] +['Ġktór', 'Äħ'] +['Ġ×Ķ×IJ×Ĺר', '×ķ׳×ķת'] +['ائ', 'ÙĨ'] +['ÅĦ', 's'] +['ÅĦs', 'ka'] +['åĽ½', 'ãģ®'] +['×ŀ', '×ĺ×Ļ'] +['ĠвопÑĢоÑģ', 'Ñĭ'] +['à¸Ńà¸ĩà¸Ħà¹Į', 'à¸ģร'] +['×ŀ', '×ķצ×IJ'] +['Ġpó', 'ź'] +['Ġpóź', 'niej'] +['ש×ŀ', '×IJ׾'] +['Ġk', 'aps'] +['Ġkaps', 'am'] +['Ġkapsam', 'ında'] +['Ġmá', 'quina'] +['ĠÅĽwie', 'cie'] +['Ġho', 'Ãłng'] +['Ġöz', 'gü'] +['×Ĵ×ķר', '×Ŀ'] +['ãģĤ', 'ãģŁãĤĬ'] +['à¸ķัà¸Ķ', 'สิà¸Ļ'] +['à¸ķัà¸Ķสิà¸Ļ', 'à¹ĥà¸Ī'] +['б', 'ÑĢи'] +['ãģ«ãģªãĤĭ', 'ãģ¨'] +['ت', 'ÙĥÙĪÙĨ'] +['Ġ×ķ×Ķ', '×Ļ×IJ'] +['Ġchi', 'ếu'] +['ÑģÑĤан', 'ав'] +['ÑģÑĤанав', 'ли'] +['ÑģÑĤанавли', 'ва'] +['×ŀ', '×ķ×Ĵ'] +['c', 'ité'] +['ĠK', 'örper'] +['Ġש', '×Ĵ×Ŀ'] +['ع', 'ظ'] +['عظ', 'ÙĬÙħ'] +['Ġ×Ķ×IJ', '×Ļש×Ļ'] +['Ġmat', 'ière'] +['ĠÙģ', 'ÙĪÙĤ'] +['Ġk', 'to'] +['Ġkto', 'ÅĽ'] +['à¸Ļ', 'à¹Ĥย'] +['à¸Ļà¹Ĥย', 'à¸ļาย'] +['å¾ħ', 'ãģ¡'] +['à¹Ģม', 'à¸Ļ'] +['à¹Ģมà¸Ļ', 'ู'] +['A', 'ÃĩÃĥO'] +['Ġt', 'ù'] +['Ġtù', 'y'] +['ãĥĪ', 'ãĥ³'] +['ĠоÑĤ', 'каз'] +['Ġ×ŀ', '×ķצר'] +['ül', 'ü'] +['ãģķãĤĵ', 'ãģ«'] +['Ġ×Ĺ', '×ķ×ij'] +['קר', '×Ļ×IJ×Ķ'] +['ĠاÙĦØ®', 'دÙħات'] +['ĠÙĦÙħ', 'دة'] +['ر', 'ؤ'] +['رؤ', 'ÙĬØ©'] +['ãĤĴè¦ĭ', 'ãģ¤ãģij'] +['à¸Ł', 'า'] +['Ġréuss', 'i'] +['à¸Ļัà¸ģ', 'à¹Ģรียà¸Ļ'] +['ĠÑĩиÑģ', 'л'] +['à¸ģาร', 'à¹Ģลà¹Īà¸Ļ'] +['Ġhaz', 'ırl'] +['Ġhazırl', 'an'] +['ĠпеÑĢв', 'Ñĭй'] +['ли', 'м'] +['ĠоÑĤзÑĭв', 'Ñĭ'] +['Ġwy', 'jÄħ'] +['ĠwyjÄħ', 'tk'] +['ĠØ£', 'ÙĤÙĦ'] +['ס', '×ļ'] +['Ġê²°', 'ìłķ'] +['Ġ׾×ŀ×¢', 'ש×Ķ'] +['Ġl', 'ắp'] +['à¹ģà¸ļ', 'ร'] +['à¹ģà¸ļร', 'à¸Ļà¸Ķà¹Į'] +['วà¹Īา', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['Ġب', 'دا'] +['Ġبدا', 'ÙĬØ©'] +['ãģ¨ãģĦãģĨ', 'ãģ®ãģĮ'] +['иÑĩеÑģк', 'им'] +['à¸ģาร', 'à¸ŀัà¸Ĵà¸Ļา'] +['Ġb', 'Ãło'] +['Ġmia', 'ÅĤa'] +['y', 'waÄĩ'] +['ĠMär', 'z'] +['ĠÙĨ', 'سبة'] +['Ġéconom', 'ique'] +['×ĸ', '×ŀ'] +['×ĸ×ŀ', '׳×Ļ×Ŀ'] +['æŃ¢', 'ãĤģ'] +['Ġt', 'á»§'] +['íķĺ', 'ìĭł'] +['Ġkażde', 'go'] +['stra', 'ÃŁe'] +['à¸Ĭ', 'ีà¹ī'] +['à¹Ģ', 'à¸ļา'] +['ÑĢеÑģ', 'ÑĥÑĢÑģ'] +['ев', 'ой'] +['Ø´', 'باب'] +['à¸ķà¹Īาà¸ĩ', 'à¸Ľà¸£à¸°à¹Ģà¸Ĺศ'] +['Ġ×IJ', '×Ļש'] +['Ġ×IJ×Ļש', '×Ļת'] +['×Ļ', '×ķפ'] +['×Ļ×ķפ', '×Ļ'] +['ĠìļĶ', '구'] +['ì¡°', 'ìĤ¬'] +['ãģ£ãģŁ', 'ãĤī'] +['׾', '×Ļ×§'] +['миниÑģÑĤ', 'ÑĢ'] +['ãĤĤãģ®', 'ãģ¯'] +['Ġl', 'ương'] +['Ġна', 'и'] +['Ġнаи', 'бол'] +['Ġнаибол', 'ее'] +['íİ', 'ĺ'] +['à¹ģà¸ŀ', 'à¹ī'] +['ãĤŃ', 'ãĥ¥'] +['ĠкоÑĤоÑĢ', 'Ñĭм'] +['à¹ģà¸Ĺ', 'à¸ĩ'] +['à¹ģà¸Ĺà¸ĩ', 'à¸ļà¸Ńล'] +['Ġ׳', '×Ļ×Ķ'] +['Ġ׳×Ļ×Ķ', '×ķ׾'] +['âĤ', 'ª'] +['ĠGi', 'ải'] +['ĠиÑģполÑĮзов', 'а'] +['ëł¥', 'ìĿĦ'] +['ãģĹãģĭ', 'ãĤĤ'] +['à¸ģà¹ĩ', 'à¸ķà¹īà¸Ńà¸ĩ'] +['ĠÑĢ', 'еб'] +['ĠÑĢеб', 'ен'] +['ĠÑĢебен', 'ка'] +['ت', 'ÙĪØ§ØµÙĦ'] +['ãĤ°ãĥ«', 'ãĥ¼ãĥĹ'] +['ãĤĦ', 'ãĤī'] +['à¹Ģà¸Ľà¸´à¸Ķ', 'à¸ķัว'] +['б', 'ÑĢо'] +['ë°ĸ', 'ìĹIJ'] +['ÙĨ', 'ÙİØ§'] +['×Ķ', '×Ĵ'] +['×Ķ×Ĵ', '׳×Ķ'] +['à¸Ĺ', 'รั'] +['à¸Ĺรั', 'à¸ŀ'] +['à¸Ĺรัà¸ŀ', 'ยà¹Į'] +['Ġkh', 'á»iji'] +['עצ', '×ŀ×ķ'] +['бол', 'езн'] +['Ġë°Ľ', 'ìķĦ'] +['ม', 'à¸Ļ'] +['มà¸Ļ', 'ุ'] +['มà¸Ļุ', 'ษ'] +['มà¸Ļุษ', 'ยà¹Į'] +['âĹ', 'Ĩ'] +['×ŀ', 'צ׾×Ļ×Ĺ'] +['Ñıв', 'ление'] +['Ùħ', 'Ø·ÙĦ'] +['ÙħØ·ÙĦ', 'ÙĪØ¨'] +['Ø®', 'اÙĦÙģ'] +['ت', 'ÙĪÙĤÙģ'] +['ãģ§ãģį', 'ãģ¾ãģĽãĤĵ'] +['оÑģÑĤ', 'ей'] +['м', 'еÑĩа'] +['기', 'ëĬĶ'] +['תש', '×¢'] +['ص', 'ÙĬب'] +['Ġ×ij×¢', '×ķ×ĵ'] +['à¸Ĥà¸Ńà¸ĩ', 'à¹Ģà¸Ĥา'] +['ÑĤÑı', 'ж'] +['ĠÑĥ', 'пÑĢав'] +['ĠÑĥпÑĢав', 'лениÑı'] +['Ġgén', 'ér'] +['Ġth', 'ÃŃ'] +['פ', '×ļ'] +['Ġر', 'Ùħض'] +['ĠرÙħض', 'اÙĨ'] +['Ġtr', 'uyá»ĩn'] +['Ø¥', 'عداد'] +['ãĤµ', 'ãĥĿãĥ¼ãĥĪ'] +['Ġпол', 'но'] +['Ø®', 'اÙħ'] +['ÐŁ', 'еÑĤ'] +['ÐŁÐµÑĤ', 'еÑĢ'] +['ÐŁÐµÑĤеÑĢ', 'бÑĥÑĢ'] +['ÐŁÐµÑĤеÑĢбÑĥÑĢ', 'г'] +['ÙħÙĨت', 'دÙī'] +['ãģķãĤĮ', 'ãģ¾ãģĹãģŁ'] +['ĠëĮĢ', 'íķĺìŬ'] +['à¸ľà¸¹à¹ī', 'à¸Ĺีà¹Ī'] +['Ġ×ŀ×IJ', '×ķ'] +['׾', '׳×ĵ'] +['оÑĩ', 'нÑĭе'] +['ĠнаÑĩ', 'ала'] +['Ġ׾', '×Ļ׾×ĵ×Ļ×Ŀ'] +['ов', 'ое'] +['ãģĻãĤĭãģĵãģ¨', 'ãģ§'] +['ĠاÙĦÙĨ', 'Ùģ'] +['ĠاÙĦÙĨÙģ', 'Ø·'] +['ìŀĪ', 'ëĬĶ'] +['غ', 'ÙĨÙĬ'] +['פ', '×ĵ'] +['ãĤ', '¾'] +['ĠCr', 'é'] +['ãģ©', 'ãģ¡ãĤī'] +['Ø«', 'اÙĨ'] +['ÑĢаб', 'аÑĤ'] +['ÑĢабаÑĤ', 'Ñĭва'] +['Ġê°Ļ', 'ëĭ¤'] +['à¸Ī', 'ั'] +['à¸Īั', 'à¸ģร'] +['Ġch', 'ụ'] +['Ġchụ', 'p'] +['Ġм', 'аÑģÑĤ'] +['ĠмаÑģÑĤ', 'еÑĢ'] +['Ġn', 'ắm'] +['ĠÑģÑĤ', 'али'] +['Ġ×Ķ×IJ', '×Ļר×ķ×¢'] +['ãĤ½', 'ãĥ³'] +['åĪĨ', 'ãģĭãĤĬ'] +['Ø·', 'بع'] +['بد', 'ا'] +['gr', 'áfico'] +['г', 'еÑĢ'] +['à¸Ķำà¹Ģà¸Ļิà¸Ļ', 'à¸ģาร'] +['Ġsal', 'dır'] +['Ġsaldır', 'ı'] +['в', 'ÑĪиÑħ'] +['ãģĭãģ£ãģŁ', 'ãģ§ãģĻ'] +['Ġyapı', 'yor'] +['ĠاÙĦÙģ', 'ت'] +['צר', 'פת'] +['з', 'доÑĢов'] +['×ij×¢', '׾'] +['Ġ×IJ', '×ŀ×Ļת×Ļ'] +['Ġоб', 'Ñĭ'] +['ĠобÑĭ', 'Ñĩ'] +['ĠобÑĭÑĩ', 'но'] +['Ġ׾', '×ķ×ŀר'] +['ت', 'ÙĥÙĨ'] +['تÙĥÙĨ', 'ÙĪÙĦÙĪØ¬'] +['تÙĥÙĨÙĪÙĦÙĪØ¬', 'ÙĬا'] +['Ġhakk', 'ı'] +['ĠÑĢаÐ', '²'] +['ĠÑĢав', 'но'] +['رÙĬ', 'Ùĥ'] +['Ġ×ij', '×ŀ×Ļ×ĵ'] +['Ġ×ij×ŀ×Ļ×ĵ', '×Ķ'] +['à¹ģà¸ģ', 'à¹īว'] +['Ġìĸ', 'ĺ'] +['Ġìĸĺ', '기'] +['ãģĹãģ¦', 'ãģĦãģ¾ãģĹãģŁ'] +['Ġkı', 'sm'] +['Ġkısm', 'ı'] +['ê±', '¸'] +['åĨħ', 'ãģ®'] +['ì§', 'ķ'] +['à¹Ģหมืà¸Ńà¸Ļ', 'à¸ģัà¸Ļ'] +['ĠÙģ', 'ÙIJ'] +['ĠÙģÙIJ', 'ÙĬ'] +['ÙĤ', 'اعدة'] +['Ġmoż', 'esz'] +['Ùħ', 'صاÙĦ'] +['ÙħصاÙĦ', 'ØŃ'] +['ãģ¾ãģŁ', 'ãģ¯'] +['б', 'ег'] +['Ġs', 'ıc'] +['Ġsıc', 'ak'] +['Ñĩ', 'иÑģ'] +['ÑĩиÑģ', 'лен'] +['Ġн', 'ог'] +['ãĥģãĥ£', 'ãĥ³'] +['ãĥ«', 'ãĥī'] +['Ġgi', 'ó'] +['Ġs', 'ını'] +['Ġsını', 'f'] +['ив', 'аÑĤÑĮ'] +['Ġqu', 'ên'] +['Ġì', 'łģ'] +['Ġìłģ', 'ìļ©'] +['ĠJo', 'ão'] +['Ùģ', 'اد'] +['ĠGl', 'ück'] +['à¸Ĺ', 'à¸Ńà¸Ķ'] +['Ġg', 'ói'] +['ï¼', 'Ĭ'] +['Ġdé', 'tail'] +['ĠدÙĬ', 'سÙħ'] +['ĠدÙĬسÙħ', 'بر'] +['ë¡ľ', 'ìĦľ'] +['×ŀ', '×ķ×Ĺ'] +['à¹Ħ', 'ฮ'] +['ĠоÑĤ', 'д'] +['ĠоÑĤд', 'ÑĭÑħ'] +['Ġkh', 'uyến'] +['à¸Ħ', 'à¸Ńย'] +['Ġج', 'ÙĨÙĬ'] +['ĠجÙĨÙĬ', 'Ùĩ'] +['ĠاÙĦد', 'ÙģØ§Ø¹'] +['à¸Ļà¹īำ', 'หà¸Ļัà¸ģ'] +['ĠìĤ¬ëŀĮ', 'ëĵ¤ìĿ´'] +['Ġth', 'ừa'] +['ĠÃ¶ÄŁrenc', 'i'] +['ĠпомоÑī', 'и'] +['ĠczÄĻ', 'ÅĽÄĩ'] +['ש', '×ĺר'] +['ĠN', 'hi'] +['ĠNhi', 'á»ģu'] +['׳', 'צ×Ļ'] +['ĠнаÑĪ', 'ем'] +['ĠkarÅŁÄ±', 'laÅŁ'] +['Ġ×Ķש', '׳×Ļ×Ŀ'] +['ĠÄIJ', 'ưá»Ŀng'] +['Ġtr', 'ú'] +['ĠÑĢазлиÑĩ', 'нÑĭÑħ'] +['ĠاÙĦØ´', 'Ùĩر'] +['Ġ×ľ×¢', '×ķ׾×Ŀ'] +['ØŃ', 'جر'] +['ĠÄij', 'á»ķ'] +['ĠìĿĺ', 'íķ´'] +['à¸ļ', 'à¹Īà¸Ńย'] +['Ġ×Ķ', '×Ļ׾×ĵ'] +['ãģ¨ãģª', 'ãģ£ãģŁ'] +['Ġ×Ĺ×ķ', '×ķת'] +['Ġש×Ļר×ķת', '×Ļ'] +['Äħ', 'cy'] +['س', 'رÙĬ'] +['K', 'İ'] +['פ', '׳×ķ'] +['ÑģÑĤÑĢÑĥк', 'ÑĤÑĥÑĢ'] +['ÑĤ', 'ÑĢÑĥд'] +['Ġ×Ķ', 'קר'] +['Ġ×Ķקר', '×ķ×ij'] +['Ġth', 'áºŃm'] +['èģŀ', 'ãģį'] +['ÙĤÙĪ', 'ÙĬ'] +['клÑİÑĩ', 'ен'] +['ÑĤе', 'Ñħ'] +['ÑĤеÑħ', 'нолог'] +['è¡Į', 'ãģ£ãģŁ'] +['Ġ×ķ×IJ', '×Ļף'] +['ĠÅŁek', 'lin'] +['ĠÅŁeklin', 'de'] +['r', 'ô'] +['ÑĢ', 'ог'] +['Ġнов', 'Ñĭе'] +['Ġס', '×ij×Ļ×ij'] +['Ġtecn', 'ologÃŃa'] +['ס', '׼'] +['×¡×Ľ', '×ķ×Ŀ'] +['ĠÅŀ', 'ub'] +['ĠÅŀub', 'at'] +['Ġ×Ķ×ŀ', '׾×IJ'] +['Ġwy', 'pos'] +['Ġwypos', 'aż'] +['ãģ¯', 'ä½ķ'] +['ãĤ¬', 'ãĥ³'] +['ê°', 'ĸ'] +['Ġкак', 'ие'] +['Ġçocuk', 'lar'] +['Ġ׾צ', '×ĵ'] +['Ġkay', 'ıt'] +['ĠмеÑģÑĤ', 'е'] +['Ùħ', 'دÙĬÙĨØ©'] +['Ġ׼', '×Ĵ'] +['Ġ׼×Ĵ', '×ķף'] +['ãģĹãģ¦', 'ãĤĭ'] +['ĠÙħا', 'ÙĬÙĪ'] +['ãģ£ãģ¦ãģĹãģ¾', 'ãģ£ãģŁ'] +['ĠпÑĢогÑĢамм', 'Ñĭ'] +['à¹ģล', 'à¸Ļà¸Ķà¹Į'] +['ãĥ¯', 'ãĤ¤'] +['ער', '×ķ×¥'] +['Ñģ', 'ид'] +['ĠB', 'öyle'] +['Ġì²ĺ', 'ìĿĮ'] +['Ġת', 'פק×Ļ×ĵ'] +['ĠTr', 'ên'] +['íĥ', 'Ī'] +['ĠÐłÐ¾ÑģÑģ', 'ий'] +['ĠÐłÐ¾ÑģÑģий', 'Ñģкой'] +['Ġs', 'Ãłn'] +['Ġrè', 'gle'] +['ĠyaklaÅŁ', 'ık'] +['à¹Ģล', 'ิà¸ģ'] +['Ġد', 'ائÙħ'] +['Ġ×ķ', '×Ĵ'] +['اب', 'ر'] +['Ġb', 'è'] +['ĠاÙĦ', 'ÙĤدÙħ'] +['ĠÑĢеÑĪ', 'ениÑı'] +['hi', 'ên'] +['ÑĤи', 'к'] +['Ä', 'Ħ'] +['à¸ļรร', 'ยาà¸ģ'] +['à¸ļรรยาà¸ģ', 'าศ'] +['רצ', '×ķף'] +['åĭķ', 'ãģį'] +['ĠGä', 'ste'] +['Ġ기', '본'] +['ĠÙĬ', 'عرÙģ'] +['ĠS', 'á»Ń'] +['gÅĤ', 'ÄĻb'] +['à¹Ģà¸Ń', 'ส'] +['×IJ×ŀ', '×Ļף'] +['Ġп', 'Ñĥнк'] +['ĠпÑĥнк', 'ÑĤ'] +['Ġ×Ļ×ķ×ĵ', '×¢×Ļ×Ŀ'] +['ãĤ«', 'ãĥ©ãĥ¼'] +['Ġ×ijס', '×ĵר'] +['Ġbu', 'á»ĵn'] +['й', 'ÑĤ'] +['йÑĤ', 'еÑģÑĮ'] +['ãĤĴ', 'æ±ĤãĤģ'] +['Ġ×IJת', '׼×Ŀ'] +['Ġ모', '르'] +['ظ', 'رÙĪÙģ'] +['Ñĩ', 'еÑģÑĤво'] +['ìĸ´', 'ìĦľ'] +['Ġод', 'на'] +['Ġkap', 'ı'] +['Ġëħ¸', 'ëł¥'] +['ĠKü', 'che'] +['ĠاÙĦت', 'Ø´'] +['Ø·', 'ÙĬب'] +['ĠíĬ¹', 'íŀĪ'] +['ĠвÑĭп', 'ÑĥÑģ'] +['ĠвÑĭпÑĥÑģ', 'к'] +['×ĵ', 'ת×Ļ'] +['Ġu', 'ÄŁ'] +['ĠuÄŁ', 'ra'] +['ائ', 'Ùĩا'] +['Ġtho', 'át'] +['ãģª', 'ãĤĤãģ®'] +['Ñij', 'ÑĢ'] +['기', 'ê°Ģ'] +['ĠgeliÅŁ', 'me'] +['تØŃ', 'ÙĤ'] +['تØŃÙĤ', 'ÙĤ'] +['Ġоп', 'аÑģ'] +['б', 'ÑĢоÑģ'] +['ห', 'ุ'] +['หุ', 'à¹īà¸Ļ'] +['ì¼', 'Ģ'] +['ãĤ¹', 'ãĥŀ'] +['ãĤ¹ãĥŀ', 'ãĥĽ'] +['Ø£', 'Ù쨱'] +['Ø£Ù쨱', 'اد'] +['ĠTh', 'á»±c'] +['Ġth', 'ắ'] +['ãĥªãĥ³', 'ãĤ¯'] +['Ġni', 'á»ģm'] +['ĠHö', 'he'] +['عÙħ', 'ار'] +['ÙĥÙĪØ±', 'ÙĪÙĨ'] +['ÙĥÙĪØ±ÙĪÙĨ', 'ا'] +['ĠÄIJ', 'ến'] +['ĠÑģам', 'ом'] +['ĠÑĤ', 'еле'] +['ĠÄijo', 'án'] +['à¸Ħวามà¸Ħิà¸Ķ', 'à¹Ģหà¹ĩà¸Ļ'] +['Ġд', 'иÑģк'] +['Ø£', 'Ø·Ù쨧ÙĦ'] +['ม', 'ารà¹Į'] +['à¸Ĺ', 'หาร'] +['à¸Ĺ', 'à¸Ļ'] +['Ġب', 'عÙĬد'] +['ĠاÙĦÙĩ', 'ÙĨد'] +['åĩº', 'ãģĹãģ¦'] +['Ġkar', 'de'] +['Ġkarde', 'ÅŁ'] +['×Ķ×Ļס×ĺ', '×ķר'] +['×Ķ×Ļס×ĺ×ķר', '×Ļ×Ķ'] +['éģ¸', 'ãģ³'] +['ع', 'اÙħÙĦ'] +['à¸Ĥ', 'ยาย'] +['Ġtü', 'rl'] +['Ġtürl', 'ü'] +['ĠìĿ¼', 'ìĿ´'] +['Ġmaté', 'ria'] +['Ġ׼׾', '×ķ×ŀר'] +['ãĥģãĥ£', 'ãĥ¼'] +['جÙħ', 'اعة'] +['ĠÑģво', 'им'] +['Ø¥ÙĤ', 'اÙħØ©'] +['ä¾ĭ', 'ãģĪãģ°'] +['س', 'اب'] +['Ø¢', 'خر'] +['ÙĤ', 'دÙĬر'] +['×IJ×ŀ', '×Ļ'] +['ìĸ', '»'] +['Ġ׳×ķס', 'פת'] +['ĠÐĴ', 'лад'] +['ĠÐĴлад', 'им'] +['ĠÐĴладим', 'иÑĢ'] +['Ġest', 'ará'] +['ãģĵãģĨ', 'ãģĦãģĨ'] +['ãĤĴ', '使ç͍'] +['มา', 'à¸ķร'] +['มาà¸ķร', 'à¸IJาà¸Ļ'] +['ãģ£ãģ', '½'] +['Ġn', 'ú'] +['Ġnú', 'i'] +['ย', 'าà¸ĩ'] +['ĠاÙĦج', 'ÙĨس'] +['Ġüst', 'ün'] +['ëľ', '»'] +['ãĤ»', 'ãĥ«'] +['ãģ¦ãģĦ', 'ãģįãģ¾ãģĻ'] +['Ġ×Ĺ', '×ķ×ĸ'] +['Ġ×Ĺ×ķ×ĸ', 'ר'] +['ĠÐĵ', 'лав'] +['à¹Ĥà¸Ĭ', 'à¸Ħ'] +['íı', 'IJ'] +['ÙĨت', 'ظر'] +['Ġ×Ĵ', '×ij×Ļ'] +['ع', 'ÙĤب'] +['int', 'ér'] +['intér', 'êt'] +['×ŀ', 'פ×Ĵ'] +['×ŀפ×Ĵ', 'ש'] +['Ġth', 'ù'] +['اÙģ', 'ت'] +['Ġ×ŀש', 'פ'] +['Ġ×ŀשפ', '×ĺ×Ļ'] +['ĠÙħ', 'ÙĪØ§ÙĤع'] +['è¦', 'ļ'] +['è¦ļ', 'ãģĪ'] +['×ĵ', '×Ļף'] +['à¹Ģรืà¹Īà¸Ńà¸ĩ', 'ราว'] +['ãģ¾', 'ãģĤ'] +['Ġgh', 'ế'] +['иÑĢÑĥ', 'ÑİÑĤ'] +['à¸ģ', 'ว'] +['à¸ģว', 'à¹īาà¸ĩ'] +['Ġпов', 'еÑĢ'] +['ĠповеÑĢ', 'Ñħ'] +['ĠповеÑĢÑħ', 'ноÑģÑĤ'] +['׳', '×ĵר'] +['Ġкон', 'ÑĨе'] +['Ġдолж', 'на'] +['Ġ×Ļש', '×Ļר'] +['acaģı', 'z'] +['ìĹ', 'Ķ'] +['Ġn', 'ÃŃvel'] +['Ġö', 'r'] +['Ġör', 'nek'] +['Ùĥ', 'Ùģ'] +['ĠФедеÑĢ', 'аÑĨии'] +['Ġ구', 'ìĦ±'] +['หัว', 'à¹ĥà¸Ī'] +['ĠV', 'áºŃy'] +['м', 'ед'] +['мед', 'и'] +['меди', 'ÑĨин'] +['медиÑĨин', 'Ñģк'] +['از', 'ÙĬ'] +['×Ĵ×ij', '×ķ׾'] +['ÑĦ', 'ÑĢ'] +['Ġzus', 'ätzlich'] +['à¸ģ', 'à¸ģ'] +['ĠاÙĦاÙĤتصاد', 'ÙĬØ©'] +['Ġh', 'è'] +['lu', 'ÄŁun'] +['ج', 'Ùİ'] +['à¹Ħà¸Ł', 'ลà¹Į'] +['ÄIJ', 'T'] +['ãģĿãģ®', 'ä»ĸ'] +['à¸Ĺิ', 'à¹īà¸ĩ'] +['ĠاÙĦØ£', 'ÙĪ'] +['ر', 'سÙħ'] +['æ°Ĺ', 'ãģ¥'] +['ìĿ´', 'ë©°'] +['ÑĮ', 'ев'] +['ص', 'Ø·'] +['ĠاÙĦاست', 'Ø«'] +['ĠاÙĦاستث', 'Ùħار'] +['à¸Ńา', 'à¸Ħาร'] +['ĠÑĤоÑĩ', 'но'] +['ĠV', 'ân'] +['à¸Ń', 'ร'] +['à¸Ńร', 'à¹Īà¸Ńย'] +['ĠاÙĦس', 'ÙĨØ©'] +['Ġc', 'Æ°á»Ľi'] +['×Ļ×Ķ', 'ף'] +['íį', '¼'] +['話', 'ãģĹ'] +['âĹ', 'ĭ'] +['ĠìķĬ', 'ìĿĢ'] +['ãĥ¡', 'ãĥ¼ãĤ'] +['ãĥ¡ãĥ¼ãĤ', '«'] +['ãĥ¡ãĥ¼ãĤ«', 'ãĥ¼'] +['ĠÑĤеп', 'ло'] +['å½¼', 'ãĤī'] +['Ġİ', 'z'] +['Ġİz', 'mir'] +['íĻ', 'į'] +['Ġr', 'ượ'] +['Ġrượ', 'u'] +['æĢĿãģĦ', 'åĩº'] +['ĠPh', 'ạm'] +['Ġchá', 'u'] +['צ×Ļ', '×ķת'] +['ĠìĿ¼', '본'] +['ìĤ¬', 'ëĬĶ'] +['ĠÑģозд', 'ан'] +['Ġar', 'acı'] +['Ġ×¢', 'ר'] +['Ġער', '×Ļ׼×Ķ'] +['ĠíķĺëĤĺëĭĺ', 'ìĿĺ'] +['dzi', 'ÅĤ'] +['à¸Ľà¸£à¸°', 'à¸ĺาà¸Ļ'] +['Ġser', 'ÃŃa'] +['ĠìŀĪ', 'ëıĦë¡Ŀ'] +['در', 'ج'] +['íķľëĭ¤', 'ëĬĶ'] +['à¸Ńา', 'à¸Ĺ'] +['à¸Ńาà¸Ĺ', 'ิà¸ķ'] +['à¸Ńาà¸Ĺิà¸ķ', 'ยà¹Į'] +['ÑĤелÑĮ', 'нÑĭй'] +['ĠØ®', 'دÙħات'] +['×ŀ׳', '×ĺ'] +['Ġl', 'ược'] +['ĠS', 'Ãłi'] +['ĠÙĪ', 'اض'] +['ĠÙĪØ§Ø¶', 'ØŃ'] +['غ', 'از'] +['ĠdoÄŁ', 'al'] +['Ġ×ijש', '×Ŀ'] +['Ġд', 'лин'] +['ĠØ¥', 'طار'] +['Ġ×ijס', 'פר'] +['ãĤĴ', 'ä¸İ'] +['ãĤĴä¸İ', 'ãģĪ'] +['Ġë²ķ', 'ë¥ł'] +['ĠÑĥ', 'вели'] +['ĠÑĥвели', 'Ñĩи'] +['ส', 'à¹Ħà¸ķ'] +['สà¹Ħà¸ķ', 'ลà¹Į'] +['à¹Ħ', 'à¸ģล'] +['×ij×Ĺ', 'ף'] +['ĠìĿ´', 'íĽĦ'] +['Ġm', 'unic'] +['Ġmunic', 'ÃŃpio'] +['تÙħ', 'Ø«ÙĦ'] +['ĠÄij', 'áo'] +['H', 'ôtel'] +['Ġl', 'á»Ńa'] +['ĠÄij', 'ẳng'] +['Ñĩ', 'ки'] +['Ø´', 'رÙĪ'] +['شرÙĪ', 'Ø·'] +['ĠìĿ´', '를'] +['ÙĬ', 'Ùĭا'] +['×ŀ׾', '×ļ'] +['×ŀ×Ķ', '×Ļר×ķת'] +['ĠобÑıз', 'аÑĤелÑĮ'] +['ĠобÑıзаÑĤелÑĮ', 'но'] +['é', 'nergie'] +['Ġmud', 'ança'] +['Ġm', 'ụ'] +['Ġmụ', 'n'] +['Ġn', 'º'] +['ĠاÙĦت', 'عا'] +['ĠاÙĦتعا', 'ÙĪÙĨ'] +['ĠاÙĦاجتÙħاع', 'ÙĬØ©'] +['Ġп', 'лаÑģÑĤ'] +['Ġëĵ±', 'ìĿĺ'] +['ãĥIJãĤ¤', 'ãĤ¯'] +['Ùĩج', 'ÙĪÙħ'] +['ĠSa', 'úde'] +['Ġì¤ijìļĶ', 'íķľ'] +['Ġ×Ķצ', '×Ļ×ij×ķר'] +['תק', 'ף'] +['ĠاÙĦعاÙĦÙħ', 'ÙĬ'] +['ĠболÑĮÑĪ', 'ой'] +['ĠÙĥ', 'ÙĦÙħ'] +['ĠÙĥÙĦÙħ', 'Ø©'] +['ãģ®ãģ§ãģ¯ãģªãģĦ', 'ãģ§ãģĹãĤĩãģĨãģĭ'] +['ĠÙħ', 'باراة'] +['Ġש×IJ', '׳'] +['Ġש×IJ׳', '×Ĺ׳×ķ'] +['ãĤ¹ãĤ¿', 'ãĤ¤ãĥ«'] +['ĠSa', 'ÄŁ'] +['ĠSaÄŁ', 'lık'] +['Ġh', 'ư'] +['׳', '×Ĺ×Ķ'] +['Ġ×ij', 'קר×ij'] +['Ø·', 'عÙħ'] +['ห', 'ิà¸Ļ'] +['à¸Ĺุà¸ģ', 'วัà¸Ļ'] +['à¸Ħรัà¹īà¸ĩ', 'à¸Ĺีà¹Ī'] +['ĠlÃł', 'nh'] +['Ġdonn', 'é'] +['ãģĽ', 'ãģĦ'] +['جز', 'ÙĬرة'] +['доÑĢ', 'ож'] +['ì¼', 'ľ'] +['تÙĨظ', 'ÙĬÙģ'] +['ãĥģ', 'ãĥ§'] +['Ġald', 'ıģı'] +['ج', 'اج'] +['ĠÑĤ', 'омÑĥ'] +['à¸Ľ', 'ิ'] +['Ġ×ijר', 'שת'] +['ãģıãģªãĤĬ', 'ãģ¾ãģĻ'] +['ĠпÑĢин', 'ÑĨип'] +['Ġ×Ĺ', '׾×ķ'] +['ëı', '¼'] +['×ķ×Ĵ', 'ש'] +['س', 'س'] +['à¸Ľ', 'ู'] +['Ġh', 'ầu'] +['æĦŁãģĺ', 'ãĤĭ'] +['ï¼', '´'] +['د', 'ÙĪØ§'] +['ĠÑģм', 'ог'] +['scri', 'ção'] +['Ġth', 'áºŃn'] +['Ġר', '×ķ×IJ×Ķ'] +['обÑĢаж', 'ен'] +['ĠاÙĦتج', 'ارÙĬØ©'] +['Ø·', 'بÙĬع'] +['jÄħc', 'Äħ'] +['íĸī', 'ìľĦ'] +['Ġнов', 'Ñĭй'] +['Ġ×ŀ', '×Ĺ×ĵש'] +['æĮ¯', 'ãĤĬ'] +['gu', 'é'] +['Ġ×IJ', '×Ļר×ķ×¢'] +['Ġ×IJ×Ļר×ķ×¢', '×Ļ×Ŀ'] +['ĠاÙĦ', 'ذÙĩب'] +['×ĵ', '×IJ'] +['ت', 'اÙĨ'] +['ãģł', 'ãģĹ'] +['à¸Ńั', 'à¸ķรา'] +['à¹Ĥ', 'à¸Ī'] +['بÙĦ', 'اد'] +['×Ķ×Ļ', '×Ļ׳×ķ'] +['ĠÑģп', 'е'] +['ĠÑģпе', 'ÑĨиалÑĮно'] +['ĠÅĽwi', 'ata'] +['ãĤĵãģ§ãģĻ', 'ãĤĪ'] +['شر', 'ÙĥØ©'] +['ĠpÅĤ', 'yt'] +['Ġsitu', 'é'] +['Ġ׼×IJ', '׾×Ķ'] +['ס', '×ijר'] +['Ġkaż', 'd'] +['Ġkażd', 'ym'] +['ãĤĴæĮģ', 'ãģ¤'] +['׾×Ķ', '׾'] +['׾×Ķ׾', 'ף'] +['ĠwÅĤ', 'as'] +['ĠwÅĤas', 'ne'] +['ĠsaÄŁ', 'lan'] +['×ŀ×¢', '׾×Ķ'] +['ĠاÙĦا', 'ÙĪÙĦ'] +['ìĹIJìĦľ', 'ëıĦ'] +['×IJ×Ļר', '×ķפ×Ķ'] +['تÙĤ', 'ÙĨÙĬØ©'] +['Ùħ', 'ائ'] +['Ùħائ', 'Ø©'] +['Ġcompañ', 'ÃŃa'] +['Ġsü', 'rek'] +['Ġsürek', 'li'] +['ĠиÑģ', 'кÑĥÑģ'] +['ĠиÑģкÑĥÑģ', 'ÑģÑĤв'] +['ĠB', 'ürger'] +['ת', '×Ĺר'] +['ת×Ĺר', '×ķת'] +['à¸ŀรà¹īà¸Ńม', 'à¸ģัà¸ļ'] +['Ø´', 'Ùħ'] +['à¸ĸืà¸Ń', 'วà¹Īา'] +['è¾¼', 'ãĤĢ'] +['ä¼ij', 'ãģ¿'] +['ĠاÙĦØ£', 'ب'] +['ĠÑģÑĤоим', 'оÑģÑĤÑĮ'] +['ĠпÑĢав', 'а'] +['may', 'ın'] +['ห', 'วย'] +['ĠاÙĦØ·', 'بÙĬعÙĬ'] +['à¸Ĺีà¹Ī', 'à¸ŀัà¸ģ'] +['ĠEst', 'á'] +['Ñĭва', 'ÑİÑĤ'] +['ب', 'سÙĬ'] +['بسÙĬ', 'Ø·'] +['Ġ×ij×¢', '×ijר'] +['åı¯èĥ½', 'ãģ§ãģĻ'] +['Ġ×ĵ', '×ķ׾'] +['Ġ×ĵ×ķ׾', 'ר'] +['Ùĩ', 'ÙİØ§'] +['воÑĢ', 'оÑĤ'] +['ãģ¦', 'ãģĦãģ¾ãģĹãģŁ'] +['à¹Ĥà¸Ĺร', 'ศ'] +['à¹Ĥà¸Ĺรศ', 'ั'] +['à¹Ĥà¸Ĺรศั', 'à¸ŀ'] +['à¹Ĥà¸Ĺรศัà¸ŀ', 'à¸Ĺà¹Į'] +['Ġ×§', '׳'] +['ĠاÙĦØ«', 'ÙĨ'] +['ĠاÙĦØ«ÙĨ', 'ائÙĬØ©'] +['Ġco', 'ût'] +['à¸ķิà¸Ķ', 'à¸ķัà¹īà¸ĩ'] +['Ġö', 'rg'] +['Ġörg', 'üt'] +['ĠاÙĦØ®', 'ÙĦÙĬ'] +['ĠاÙĦØ®ÙĦÙĬ', 'ج'] +['Ġb', 'á»įn'] +['×ķ׾×ķ×Ĵ', '×Ļ'] +['ëŀ', 'ľ'] +['ĠÐij', 'олÑĮ'] +['ĠÐijолÑĮ', 'ÑĪ'] +['×Ĵ', '×ijר×Ļ×Ŀ'] +['ÙĤ', 'ÙĬد'] +['×ij×Ļ×ĺ', '×ķ×Ļ'] +['æīĵ', 'ãģ¡'] +['Ġol', 'muÅŁ'] +['f', 'äh'] +['fäh', 'ig'] +['ล', 'าà¸Ļ'] +['ĠÙĤ', 'طر'] +['ש', 'פ×Ķ'] +['èªŃ', 'ãĤĵãģ§'] +['à¸Ĥ', 'วา'] +['Ġchi', 'ếm'] +['ãĤ¤ãĥ³', 'ãĤ¿'] +['ãĤ¤ãĥ³ãĤ¿', 'ãĥ¼ãĥ'] +['ãĤ¤ãĥ³ãĤ¿ãĥ¼ãĥ', 'į'] +['ãĤ¤ãĥ³ãĤ¿ãĥ¼ãĥį', 'ãĥĥãĥĪ'] +['Ġ׾ש×ŀ', '×ķר'] +['Ġت', 'رÙĥ'] +['ĠترÙĥ', 'ÙĬا'] +['ר', '×ķ×ĺ'] +['ã썿ĢĿ', 'ãģĦãģ¾ãģĹãģŁ'] +['ĠاÙĦت', 'ÙĤ'] +['Ġd', 'ư'] +['ãģ¦ãģıãĤĮ', 'ãĤĭ'] +['ãģĹãģŁ', 'ãģĵãģ¨'] +['Ġróż', 'ne'] +['ĠاÙĦØ·', 'ÙģÙĦ'] +['ĠPost', 'é'] +['Ġ×ŀש', '×ķ×Ŀ'] +['Ñį', 'ÑĢ'] +['ĠÑĢабоÑĤ', 'аеÑĤ'] +['ãĤ·', 'ãĥª'] +['ãĤ·ãĥª', 'ãĥ¼ãĤº'] +['Ġ×ij×Ķ', '×Ĺ׾×ĺ'] +['×§×Ķ', '×Ļ׾×Ķ'] +['ãĤ«', 'ãĥ¡'] +['ãĤ«ãĥ¡', 'ãĥ©'] +['ï¼', '¯'] +['ĠìĤ¬', 'ìĿ´'] +['Ġk', 'ì'] +['Ġth', 'Æ°á»Ľc'] +['ض', 'بط'] +['ÙĤب', 'ÙĪÙĦ'] +['åĪ¥', 'ãģ®'] +['Ġparticul', 'ière'] +['ĠÑģво', 'ем'] +['Ġ×¢', 'סק'] +['Ġעסק', '×Ļ×Ŀ'] +['×ij×Ĺ', '×Ļר×ķת'] +['×ij', '×Ļ׳×ķ'] +['à¸ĭ', 'à¸Ń'] +['Ġ×¢', '×ķ×ijר'] +['ãģłãģ£ãģŁ', 'ãģ®ãģ§'] +['ıld', 'ıģı'] +['Ùħ', 'دار'] +['Ùħدار', 'س'] +['주', 'ìĭľ'] +['à¸Ńา', 'ศ'] +['à¸Ńาศ', 'ัย'] +['Ġt', 'ấm'] +['à¸ŀิ', 'à¸Ī'] +['à¸ŀิà¸Ī', 'าร'] +['à¸ŀิà¸Īาร', 'à¸ĵา'] +['ÑĤелÑĮ', 'нÑĭе'] +['Ñģк', 'ÑĥÑİ'] +['Ðľ', 'Ðĺ'] +['à¹Ģà¸ģ', 'า'] +['à¹Ģà¸ģา', 'หล'] +['à¹Ģà¸ģาหล', 'ี'] +['×ĵ', '×Ĺ'] +['à¹Ģà¸Ĭ', 'ิà¸ĩ'] +['Ġد', 'ÙĤÙĬÙĤØ©'] +['íķĻ', 'ìĥĿ'] +['Ġש×IJ', '׾×Ķ'] +['Ġcontr', 'ôle'] +['Ġsit', 'uação'] +['à¸Ĥà¸Ńà¸ĩ', 'à¸ľà¸¹à¹ī'] +['ÙĨ', 'Ø·ÙĤ'] +['ê³¼', 'íķĻ'] +['หลาย', 'à¸Ħà¸Ļ'] +['Ġn', 'ắng'] +['ÙĤ', 'Ùı'] +['ì¡°', 'ê±´'] +['Ñ', 'ķ'] +['ãĥĥ', 'ãģ¨'] +['×ŀ', '×Ļ׾×Ķ'] +['Gr', 'ün'] +['×Ļ', '×Ļ×¢'] +['×Ļ×Ļ×¢', '×ķ×¥'] +['×ŀ׳', '׼'] +['ë', 'ŃIJ'] +['×ŀ×¢', '×ŀ×ĵ'] +['สำ', 'à¸Ļัà¸ģ'] +['ج', 'دد'] +['à¸Ħ', 'ัà¸Ķ'] +['Ġ×Ķ×ŀש', 'פ'] +['Ġ×Ķ×ŀשפ', '×Ĺ×Ķ'] +['×ŀש', 'ק׾'] +['ÙĦ', 'Ùı'] +['Ġty', 'tu'] +['Ġtytu', 'ÅĤ'] +['ÑĪ', 'ей'] +['ĠìĿ¼', 'ë¶Ģ'] +['ÑĪ', 'ение'] +['Ġph', 'óng'] +['ĠìĹŃ', 'ìĤ¬'] +['ãĤ«', 'ãĥ³'] +['Ġtú', 'i'] +['ĠÙĨ', 'ÙĪÙģ'] +['ĠÙĨÙĪÙģ', 'Ùħبر'] +['gr', 'ün'] +['ĠاÙĦØ´', 'ÙħاÙĦ'] +['ÅĽwi', 'adc'] +['ÅĽwiadc', 'zenie'] +['ער', '×Ķ'] +['Ġ×¢', '×ķ×ij'] +['Ġ×¢×ķ×ij', '×ĵ×Ļ×Ŀ'] +['×ĵ×ķ×Ĵ', '×ŀ×IJ'] +['ä»Ĭ', 'ãģ¯'] +['Ġv', 'ão'] +['ĠТ', 'ем'] +['Ñģ', 'илÑĮ'] +['Ġch', 'ợ'] +['Ùħ', 'را'] +['Ùħرا', 'ÙĤب'] +['à¹Ħมà¹Ī', 'รูà¹ī'] +['Ġر', 'ائع'] +['×IJ׳', '×Ĺ׳×ķ'] +['สà¹Īà¸ĩ', 'à¹Ģสริม'] +['צ', '×Ĺ'] +['ĠìŀĪìĸ´', 'ìĦľ'] +['Ġkur', 'ulu'] +['Ġkurulu', 'ÅŁ'] +['ĠÃĸ', 'zellik'] +['ĠÃĸzellik', 'le'] +['Ġת', '×Ļ×§'] +['Ġgh', 'é'] +['Ġspr', 'zÄĻ'] +['ĠsprzÄĻ', 't'] +['ער', '×ķת'] +['را', 'ØŃØ©'] +['ãģ£', 'ãģį'] +['ãģ£ãģį', 'ãĤĬ'] +['ĠìķĦ', 'ëŀĺ'] +['stit', 'uição'] +['Ġдолж', 'но'] +['×Ķ', 'רש'] +['×Ķרש', '×ŀ×Ķ'] +['×Ķ׾', '×ļ'] +['ãģ¡', 'ãģª'] +['ãģ¡ãģª', 'ãģ¿'] +['ãģ¡ãģªãģ¿', 'ãģ«'] +['פ', '×Ĺ×ĵ'] +['ĠاÙĦج', 'ÙħÙĬع'] +['×ij×¢', '׾×Ļ'] +['Ġtr', 'ùng'] +['Ġפ', 'ת×Ĺ'] +['×ŀ׾×Ĺ', '×ŀת'] +['ãĥĨ', 'ãĥ¼ãĥ'] +['ãĥĨãĥ¼ãĥ', 'ŀ'] +['Ùħ', 'تاب'] +['Ùħتاب', 'عة'] +['Ġ모', 'ìĬµ'] +['ÙĬ', 'ص'] +['åIJĪ', 'ãģĨ'] +['ĠY', 'ap'] +['ĠYap', 'ı'] +['ĠÑģ', 'казаÑĤÑĮ'] +['ëª', '°'] +['à¸Ĺีà¹Ī', 'สำà¸Ħัà¸į'] +['ĠìĹĨ', 'ìĬµëĭĪëĭ¤'] +['Ġnh', 'ắc'] +['Ġülk', 'eler'] +['Ġмног', 'ие'] +['íķĺ', 'ìħ¨'] +['มาà¸ģ', 'à¸Ĺีà¹Īสุà¸Ķ'] +['à¸ģ', 'à¹īา'] +['à¸ģà¹īา', 'ว'] +['Ġİ', 'yi'] +['л', 'еж'] +['леж', 'а'] +['ãĤ¸', 'ãĥ§'] +['à¸Ĺั', 'à¸ŀ'] +['ا', 'ÙĪØ±'] +['Ġ×Ĺ×ijר', '×Ļ'] +['Ġ׾', 'ש×Ŀ'] +['ì²', '«'] +['ĠT', 'á»Ń'] +['×ŀ', '×ķ׳×Ļ'] +['ÙĤ', 'ÙĪØ¯'] +['à¸ģระ', 'à¹Ģà¸Ľ'] +['à¸ģระà¹Ģà¸Ľ', 'à¹ĭ'] +['à¸ģระà¹Ģà¸Ľà¹ĭ', 'า'] +['ĠпÑĢоблем', 'Ñĭ'] +['Ġaç', 'ıs'] +['Ġaçıs', 'ından'] +['Ġ×Ķ×ŀ', '׼'] +['ĠÙħع', 'ظÙħ'] +['ÙĤÙĬ', 'اس'] +['ĠпÑĢод', 'олж'] +['ĠпÑĢодолж', 'а'] +['Ġver', 'diÄŁi'] +['ĠпÑĢед', 'меÑĤ'] +['ãģĦãģ¾ãģĻ', 'ãģĮ'] +['ĠëͰ', '른'] +['ĠاÙĦ', 'ÙĤÙĬاÙħ'] +['ĠØ¥ÙĦÙĬ', 'Ùĩا'] +['Т', 'ÐIJ'] +['п', 'оз'] +['ãĤ·', 'ãĥ¥'] +['ä¸ĬãģĮ', 'ãĤĬ'] +['à¹Ģà¸Ķิม', 'à¸ŀัà¸Ļ'] +['à¸ģุ', 'ล'] +['ØŃر', 'ÙĬØ©'] +['×§×ij×ķצ', '×ķת'] +['ë¯', '¿'] +['ĠاÙĦÙħ', 'ÙĨا'] +['ĠاÙĦÙħÙĨا', 'Ø·ÙĤ'] +['ĠвÑĭп', 'ол'] +['ĠвÑĭпол', 'нÑı'] +['ãĥĭ', 'ãĤ¢'] +['Ġê²°', 'êµŃ'] +['×Ĺ', '×ķ×ŀ'] +['×Ĺ×ķ×ŀ', 'ר×Ļ×Ŀ'] +['ĠУкÑĢа', 'инÑĭ'] +['ห', 'à¸Ńม'] +['ר', '×Ļס'] +['ĠÑħоÑĤ', 'ел'] +['ĠобÑĢаз', 'ованиÑı'] +['Ġkh', 'ẳng'] +['Ġm', 'ưa'] +['Ġgör', 'me'] +['Ġgüç', 'lü'] +['سع', 'Ùī'] +['มัà¹Īà¸Ļ', 'à¹ĥà¸Ī'] +['íķĺ', 'ê²łìĬµëĭĪëĭ¤'] +['Ġпол', 'Ñĥ'] +['Ġfün', 'f'] +['ã썿ĢĿ', 'ãģ£ãģ¦ãģĦãģ¾ãģĻ'] +['Ġê·¸ê²ĥ', 'ìĿĢ'] +['ĠdÃ¼ÅŁÃ¼n', 'ce'] +['ìŀ', 'ł'] +['ĠH', 'Æ°á»Ľng'] +['ĠTi', 'á»ĥu'] +['Ġç', 'ift'] +['ãģij', 'ãģ°'] +['à¸Īà¸Ļ', 'à¸ĸึà¸ĩ'] +['à¸Ĺำ', 'à¹Ħà¸Ķà¹ī'] +['ĠìŀIJ', 'ì²´'] +['Ġd', 'õ'] +['Ġdõ', 'i'] +['à¸Ī', 'ัà¸Ļ'] +['à¸Īัà¸Ļ', 'à¸Ĺ'] +['à¸Īัà¸Ļà¸Ĺ', 'รà¹Į'] +['ece', 'ÄŁini'] +['׳×ķ×¢', 'ר'] +['غ', 'ار'] +['ĠاÙĦØ£ÙħرÙĬ', 'ÙĥÙĬ'] +['داع', 'Ø´'] +['ĠбезопаÑģ', 'ноÑģÑĤи'] +['Ġб', 'Ñİ'] +['ĠбÑİ', 'дж'] +['ĠбÑİдж', 'еÑĤ'] +['ãĥĬ', 'ãĤ¤'] +['à¸ŀà¸ļ', 'วà¹Īา'] +['da', 'ÄŁ'] +['×IJ', '×ķפף'] +['íĹ', 'Į'] +['ãĥĢãĤ¤', 'ãĤ¨'] +['ãĥĢãĤ¤ãĤ¨', 'ãĥĥãĥĪ'] +['ĠëĮĢ', 'íĨµ'] +['ĠëĮĢíĨµ', 'ëł¹'] +['D', 'İ'] +['Ø£', 'ØŃداث'] +['ĠA', 'ÄŁ'] +['ĠAÄŁ', 'ust'] +['ĠAÄŁust', 'os'] +['ØŃÙĦ', 'ÙĪÙĦ'] +['Ġw', 'ÅĽ'] +['ĠwÅĽ', 'ród'] +['ĠÑģо', 'оÑĤвеÑĤ'] +['ĠÑģооÑĤвеÑĤ', 'ÑģÑĤв'] +['ĠÑģооÑĤвеÑĤÑģÑĤв', 'ии'] +['ĠLu', 'áºŃt'] +['Ġ׼׾', 'פ×Ļ'] +['Ġв', 'еÑī'] +['ĠвеÑī', 'еÑģÑĤв'] +['×§', '×Ļ×¥'] +['ĠبÙĩ', 'ذا'] +['عا', 'Ø´'] +['à¹Ģà¸Ľà¹ĩà¸Ļ', 'à¹Ģรืà¹Īà¸Ńà¸ĩ'] +['Т', 'Ðķ'] +['Ġ×ij×IJ', '×Ļ׳×ĺר׳×ĺ'] +['س', 'عد'] +['Ġ×Ķ×ĺ', '×Ļפ×ķ׾'] +['פ', '×Ļס'] +['à¸ĩà¹Īาย', 'à¹Ĩ'] +['ĠGer', 'ät'] +['׾', '×Ļ×ĵ×Ķ'] +['ĠÑĢ', 'иÑģк'] +['׾ק', '×Ĺ'] +['н', 'наÑı'] +['ר', '×Ļ×ĵ'] +['п', 'ÑĢакÑĤи'] +['пÑĢакÑĤи', 'к'] +['à¸Ĥัà¹īà¸Ļ', 'à¸ķà¸Ńà¸Ļ'] +['à¸Ļà¹Īา', 'รัà¸ģ'] +['larınız', 'ı'] +['à¸Ńà¸Ļุ', 'à¸įา'] +['à¸Ńà¸Ļุà¸įา', 'à¸ķ'] +['ĠzdjÄĻ', 'cia'] +['Ġb', 'ây'] +['Ñģ', 'ÑĢ'] +['ÑģÑĢ', 'оÑĩ'] +['ãĥĭ', 'ãĥ³ãĤ°'] +['Ġö', 'ner'] +['Ġöner', 'i'] +['Ġнов', 'ÑĭÑħ'] +['دع', 'ÙĪØ©'] +['Ġg', 'ắn'] +['ĠاÙĦÙĦ', 'بÙĨ'] +['ĠاÙĦÙĦبÙĨ', 'اÙĨÙĬ'] +['ãĥĨãĤ£', 'ãĥ¼'] +['Ġص', 'ØŃÙĬØŃ'] +['ем', 'ÑĭÑħ'] +['çĸ²', 'ãĤĮ'] +['ĠпÑĢо', 'иÑģ'] +['ĠпÑĢоиÑģ', 'ÑħодиÑĤ'] +['ส', 'à¸ķิ'] +['ĠT', 'ết'] +['Ġ×Ķ׾', '׾×ķ'] +['à¹Ģรืà¹Īà¸Ńà¸ĩ', 'à¸Ļีà¹ī'] +['×ŀ×ij', '׳×Ķ'] +['Ġconte', 'údo'] +['Ġا', 'خت'] +['Ġاخت', 'ÙĬار'] +['Ùħ', 'سÙĦ'] +['ÙħسÙĦ', 'سÙĦ'] +['ëı', 'Ī'] +['Ġ׾', '×Ļ×ĵ'] +['à¸ŀิ', 'à¸ĺี'] +['ĠÑģов', 'Ñģ'] +['ĠÑģовÑģ', 'ем'] +['ãģĮãģĤãĤĬ', 'ãģ¾ãģĹãģŁ'] +['Ġsó', 'ng'] +['Ø¥', 'صÙĦاØŃ'] +['ë§', 'ģ'] +['Ùģ', 'ÙĬر'] +['ĠJe', 'żeli'] +['ìłľ', 'ëıĦ'] +['d', 'ÅĤug'] +['ìĥģ', 'ìĿĦ'] +['Ġc', 'áºŃn'] +['Ġhá»į', 'p'] +['Ø£', 'ست'] +['أست', 'اذ'] +['Ġ×ŀ', '×Ļש×Ķ'] +['Ġ×ŀ×Ļש×Ķ', '×ķ'] +['Ġd', 'Ãły'] +['Ġch', 'Ãłng'] +['ãģ¡ãĤĥãĤĵ', 'ãģ¨'] +['ĠÄij', 'ám'] +['Ġsw', 'ój'] +['Ġpoder', 'á'] +['ĠоÑĤлиÑĩ', 'а'] +['Ġpéri', 'ode'] +['ünd', 'ig'] +['×ĺ×¢', 'ף'] +['ÑģÑĤÑĢо', 'иÑĤелÑĮ'] +['ר', 'ת×Ļ'] +['Ġ×Ļ×Ķ', '×Ļ×ķ'] +['׾', 'ס'] +['ĠاÙĦÙħÙĨ', 'زÙĦ'] +['à¸Ļิ', 'à¹īว'] +['иÑĦ', 'ика'] +['иÑĦика', 'ÑĨи'] +['ðŁĺ', 'ī'] +['Ġad', 'ına'] +['ãĢĤãĢĤ', 'ãĢĤ'] +['×IJ', '×Ļף'] +['ס', '×Ļר'] +['ĠÙĬ', 'عد'] +['çŃĶ', 'ãģĪ'] +['اÙĦ', 'جز'] +['اÙĦجز', 'ائر'] +['енÑĮ', 'к'] +['ร', 'ห'] +['รห', 'ัส'] +['ĠTürk', 'çe'] +['ê¾', '¸'] +['Ġ×Ļ', '×ķ׼׾'] +['Ġש', '×ķ׳×Ķ'] +['Ġ×ij×ŀ', 'צ×ij'] +['ĠдейÑģÑĤв', 'иÑĤелÑĮно'] +['ĠبأÙĨ', 'Ùĩ'] +['×ŀ×§', '×ĵ'] +['Ġ×Ķש', '×§'] +['Ø®ÙĬ', 'ارات'] +['Ġf', 'ı'] +['Ġfı', 'rs'] +['Ġfırs', 'at'] +['ëij', 'ĺ'] +['ĠìĦľ', 'ìļ¸'] +['Ġ×Ķ×Ĵ', '×ķ×£'] +['ر', 'عا'] +['رعا', 'ÙĬØ©'] +['ĠK', 'ết'] +['к', 'Ñģи'] +['ĠÑĥÑģлÑĥг', 'и'] +['ноÑģÑĤ', 'ей'] +['ìļ´', 'ëıĻ'] +['ĠобÑĬ', 'Ñı'] +['ĠобÑĬÑı', 'вл'] +['н', 'еж'] +['×Ķפ', '×ļ'] +['Ġ×ij×¢', '×Ļ׳×Ļ'] +['ëĨ', 'Ĵ'] +['ĠпÑĢоÑĨ', 'ед'] +['ĠпÑĢоÑĨед', 'ÑĥÑĢ'] +['Ġiht', 'iy'] +['Ġihtiy', 'acı'] +['Ġë°Ķ', 'ëŀį'] +['Ġë°Ķëŀį', 'ëĭĪëĭ¤'] +['à¸ģล', 'ัว'] +['ĠÑģл', 'ожно'] +['×§×Ļ', '×Ļ×ŀת'] +['ĠÄIJ', 'ình'] +['ĠÙħ', 'ÙĦÙģ'] +['Ġà¹Ĥà¸Ķย', 'มี'] +['Ġkat', 'kı'] +['تØŃ', 'ÙĪÙĬÙĦ'] +['à¹Ħ', 'à¸ŀ'] +['ĠH', 'á»į'] +['ñ', 'e'] +['Ġдо', 'Ñħод'] +['Ġtho', 'ải'] +['íķĺìŬ', 'ìķ¼'] +['ãĤ¹ãĥĿ', 'ãĥ¼ãĥ'] +['ãĤ¹ãĥĿãĥ¼ãĥ', 'Ħ'] +['ĠG', 'òn'] +['Ġk', 'è'] +['Ġkè', 'm'] +['é̲', 'ãĤģ'] +['ãĤ¹', 'ãĥ¼ãĥ'] +['ãĤ¹ãĥ¼ãĥ', 'ij'] +['ãĤ¹ãĥ¼ãĥij', 'ãĥ¼'] +['ĠgiÃł', 'u'] +['ĠØ¥', 'عادة'] +['Ġ׾', '×ķ×§'] +['Ġ׾×ķ×§', '×Ĺ'] +['ĠÑħоÑĩ', 'еÑĤ'] +['×ĺ', '׾×ķ×ķ'] +['×ĺ׾×ķ×ķ', '×Ļ×ĸ'] +['×ĺ׾×ķ×ķ×Ļ×ĸ', '×Ļ×Ķ'] +['Ġth', 'uyết'] +['ãģĿãĤĮ', 'ãģ§'] +['Ġvard', 'ı'] +['à¹Ħร', 'à¹ī'] +['ع', 'بد'] +['ĠRep', 'ública'] +['ãĥ¼ãĤ¿', 'ãĥ¼'] +['Ġ×ŀ×IJ', '×ķת'] +['à¹Ħà¸Ľ', 'à¹ģลà¹īว'] +['Ġyapıl', 'acak'] +['ãĤ¹ãĤ¿', 'ãĥ¼ãĥĪ'] +['ãģ»', 'ãģ¼'] +['Ġko', 'ÅŁ'] +['ĠмаÑĤ', 'еÑĢи'] +['Ġsiè', 'cle'] +['ĠاÙĦÙħ', 'ختÙĦÙģ'] +['ĠاÙĦÙħختÙĦÙģ', 'Ø©'] +['Ġ׾ק', 'ר×IJ'] +['Ġ׾קר×IJ', 'ת'] +['Ġ×Ķפ', '×ķ×¢×ľ'] +['Ġt', 'òa'] +['Ġr', 'Æ¡i'] +['åij¨', 'ãĤĬ'] +['à¸Ŀ', 'à¸Ļ'] +['j', 'ÅĽÄĩ'] +['ĠìķĬ', 'ìĿĦ'] +['اÙĨت', 'ÙĤاÙĦ'] +['ëĸ', 'ł'] +['ив', 'аеÑĤ'] +['ãĥĪ', 'ãĥ«'] +['ĠاÙĦÙģÙĦسطÙĬÙĨ', 'ÙĬØ©'] +['à¸ģลà¹Īาว', 'วà¹Īา'] +['ا', 'Ùĥت'] +['ĠÃĸ', 'l'] +['ĠÑĢе', 'ÑĪи'] +['ĠÑĢеÑĪи', 'л'] +['Ġ׳×ķס', 'פ×ķת'] +['Ġìłķ', 'ì¹ĺ'] +['вл', 'еÑĩен'] +['Ùħر', 'ØŃÙĦØ©'] +['Ġcome', 'ça'] +['Ġy', 'ık'] +['ìĤ', '´'] +['à¸ĺ', 'à¸Ļา'] +['à¸ĺà¸Ļา', 'à¸Ħาร'] +['à¸Ńà¸Ļ', 'า'] +['à¸Ńà¸Ļา', 'à¸Ħ'] +['à¸Ńà¸Ļาà¸Ħ', 'à¸ķ'] +['Ġpeque', 'ña'] +['ä»ķ', 'äºĭãĤĴ'] +['Ġب', 'ذÙĦÙĥ'] +['Ġнов', 'ого'] +['ãģĹãģ¦', 'ãģĦãģªãģĦ'] +['ĠاÙĦÙħ', 'ÙĬاÙĩ'] +['à¸ģà¹ĩ', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['Ġж', 'ÑĥÑĢ'] +['ĠжÑĥÑĢ', 'нал'] +['в', 'еÑģ'] +['خت', 'ار'] +['Ġ매', 'ìļ°'] +['ĠM', 'ã'] +['ĠавÑĤомаÑĤ', 'Ñĭ'] +['ضع', 'Ùģ'] +['ĠاÙĦÙģ', 'Ùĥر'] +['ãģ§ãģĻ', 'ãģ®ãģ§'] +['ãĥ¡ãĥ³', 'ãĥIJãĥ¼'] +['Ġк', 'ÑĢÑĥг'] +['ĠاÙĦسÙĦ', 'طة'] +['à¸Ħรัà¹īà¸ĩ', 'à¹ģรà¸ģ'] +['à¸ģระà¸Ĺ', 'รว'] +['à¸ģระà¸Ĺรว', 'à¸ĩ'] +['ÑĨ', 'ов'] +['éķ·', 'ãģĦ'] +['大ãģį', 'ãģĦ'] +['Ġgeç', 'miÅŁ'] +['ìĦ±', 'ìĿ´'] +['Ġצר', '×Ļ׼×Ķ'] +['Ġм', 'оÑī'] +['ĠмоÑī', 'н'] +['Ġ×§', '×Ļש'] +['Ġ×§×Ļש', '×ķר×Ļ×Ŀ'] +['ĠNas', 'ıl'] +['г', 'ÑĢан'] +['Ġ×ŀ', '×ķצר×Ļ×Ŀ'] +['Ġ×ŀס', '×ķ×Ĵ'] +['Ġy', 'ür'] +['Ġyür', 'üt'] +['Ġ׾×Ĺ', 'צ×ķ'] +['×ķÖ', '¼'] +['ĠìŀĪ', 'ìĹĪëĭ¤'] +['Ġter', 'ör'] +['ĠTh', 'ương'] +['ĠÙĪ', 'ÙĬÙħ'] +['ĠÙĪÙĬÙħ', 'ÙĥÙĨ'] +['ج', 'ÙĪÙĨ'] +['ĠÙĪØºÙĬر', 'Ùĩا'] +['×ŀ', 'פ×ķ'] +['×Ĵ×ķר', '×ŀ×Ļ×Ŀ'] +['׼×ij', '×Ļש'] +['ĠاÙĦÙĦ', 'غ'] +['ĠاÙĦÙĦغ', 'Ø©'] +['شر', 'Ùĥ'] +['ĠاÙĦر', 'اب'] +['ĠاÙĦراب', 'ع'] +['ĠпÑĢ', 'ек'] +['ĠпÑĢек', 'ÑĢаÑģ'] +['ĠпÑĢекÑĢаÑģ', 'н'] +['Ġenerg', 'ÃŃa'] +['×§×ĵ', '×ŀ×Ļ'] +['ãģıãģª', 'ãģ£ãģŁ'] +['ĠÄij', 'ứ'] +['ĠÄijứ', 'a'] +['Serv', 'i'] +['Servi', 'ço'] +['Ġkald', 'ır'] +['åĥį', 'ãģį'] +['Ġод', 'еж'] +['Ġодеж', 'д'] +['물', 'ìĿĦ'] +['ãģĿãģĨ', 'ãģ§'] +['ãģĮãģĤ', 'ãĤĮãģ°'] +['ìĻ', 'ķ'] +['צ×ĵ', '×§'] +['Ġart', 'ır'] +['Ġile', 'ti'] +['Ġileti', 'ÅŁim'] +['ãĤĪãģĨ', 'ãģ§'] +['ãĥĪ', 'ãĥ¼'] +['ãĤ¢', 'ãĥĭ'] +['ãĤ¢ãĥĭ', 'ãĥ¡'] +['×ĺ×Ļ', '×Ļ׾'] +['ãĥķ', 'ãĥªãĥ¼'] +['ãĥĿ', 'ãĥ³'] +['ÐŁÑĢ', 'о'] +['Ġع', 'اÙĦÙĬØ©'] +['ĠÃ¶ÄŁ', 'ret'] +['ĠÃ¶ÄŁret', 'men'] +['ĠкаÑĩеÑģÑĤв', 'а'] +['Ġ×Ķ×ĺ', '×ij×¢'] +['Ġзна', 'Ñİ'] +['ãģ¦', 'ãģıãĤĭ'] +['Ġm', 'ừng'] +['ÙħÙĪ', 'ت'] +['ש', '×ķ×ŀר'] +['×Ĺ׾', '×ij'] +['Ġwzgl', 'ÄĻ'] +['ĠwzglÄĻ', 'du'] +['ë²Ī', '째'] +['Ġtá»', 'ĵ'] +['Ġtá»ĵ', 'n'] +['ãĥ¯ãĥ¼', 'ãĤ¯'] +['Ġpo', 'życz'] +['Ġpożycz', 'k'] +['×Ļ', '×ķצר×Ļ×Ŀ'] +['Ùĥر', 'Ùħ'] +['Ġг', 'аÑĢ'] +['ĠгаÑĢ', 'ан'] +['ĠгаÑĢан', 'ÑĤи'] +['ล', 'à¹īาà¸ĩ'] +['Ġìĺģ', 'íĻĶ'] +['×ĺ', '×Ļס'] +['Ġth', 'ẻ'] +['ĠìŀĪëĭ¤', 'ê³ł'] +['اÙĦت', 'ز'] +['اÙĦتز', 'اÙħ'] +['Ġна', 'ÑĪи'] +['is', 'ée'] +['ãģĵãĤĮ', 'ãĤĴ'] +['Ġm', 'ẽ'] +['ض', 'ÙĦ'] +['بÙĪ', 'ت'] +['Ġ׼', '׼×Ķ'] +['h', 'ợ'] +['ĠاÙĦس', 'ÙĪØ±ÙĬØ©'] +['Ġ×ľ×¢', '×ķ×ŀ'] +['Ġ×ľ×¢×ķ×ŀ', 'ת'] +['ĠbaÅŁ', 'ar'] +['ĠbaÅŁar', 'ılı'] +['е', 'ÑģÑĤÑĮ'] +['à¸Ħร', 'ี'] +['à¸Ħรี', 'ม'] +['ĠìłĦ', 'ì²´'] +['ĠسÙĬ', 'ÙĥÙĪÙĨ'] +['Ġ×ŀ×ĵ', '×ķ×¢'] +['ĠëķĮ문', 'ìĿ´ëĭ¤'] +['Ġc', 'ứng'] +['ger', 'ät'] +['Ġм', 'иÑĢ'] +['ĠмиÑĢ', 'е'] +['ĠÙĥÙĬÙģ', 'ÙĬØ©'] +['Ġפר', '×ĺ×Ļ×Ŀ'] +['Ġgo', 'ÅĽci'] +['иÑĤ', 'еÑģÑĮ'] +['ÑĥÑĪ', 'ки'] +['ؤ', 'ÙħÙĨ'] +['Ġ×IJ', '׼ף'] +['ĠاÙĦر', 'جÙĦ'] +['Ġl', 'á»įc'] +['à¹Ģรีย', 'à¸ģวà¹Īา'] +['ãģĵãģ®', 'ãĤĪãģĨãģª'] +['ë§Į', 'íģ¼'] +['Ġп', 'еÑĩ'] +['ÙĪÙĦ', 'ات'] +['ĠÃľ', 'ye'] +['liÄŁ', 'inde'] +['à¸Ħะ', 'à¹ģà¸Ļ'] +['à¸Ħะà¹ģà¸Ļ', 'à¸Ļ'] +['ãĤĭãģĵãģ¨', 'ãģ¯'] +['วิ', 'à¹Ģà¸Ħร'] +['วิà¹Ģà¸Ħร', 'าะ'] +['วิà¹Ģà¸Ħราะ', 'หà¹Į'] +['Ġвозмож', 'ноÑģÑĤи'] +['ĠاÙĦÙĨ', 'ساء'] +['ãĥīãĥ©', 'ãĥŀ'] +['Ġgü', 'c'] +['Ġgüc', 'ü'] +['Ġt', 'ưá»Ŀng'] +['Ġacomp', 'aña'] +['ãĤ¤', 'ãĥ©'] +['×§', 'צ×ij'] +['ĠY', 'ö'] +['ĠYö', 'net'] +['ĠYönet', 'im'] +['สัม', 'à¸ľ'] +['à¸ªà¸±à¸¡à¸ľ', 'ัส'] +['à¸Ļ', 'าม'] +['ĠÄij', 'ợi'] +['à¹ģหà¹Īà¸ĩ', 'à¸Ĭาà¸ķิ'] +['ãģĿãĤĮ', 'ãģ§ãĤĤ'] +['ät', 'ig'] +['ת', '×ķ×Ŀ'] +['ĠbaÅŁ', 'lat'] +['ĠвÑģ', 'ей'] +['ת', '×Ļ×§'] +['ת×Ļ×§', '×ķף'] +['ĠNg', 'ô'] +['ĠGesch', 'ä'] +['ĠGeschä', 'fts'] +['Ø£', 'Ùħ'] +['Ø£Ùħ', 'راض'] +['à¹Ģà¸Ĺ', 'à¸Ħà¸Ļ'] +['à¹Ģà¸Ĺà¸Ħà¸Ļ', 'ิ'] +['à¹Ģà¸Ĺà¸Ħà¸Ļิ', 'à¸Ħ'] +['Ġм', 'енÑĮ'] +['ĠменÑĮ', 'ÑĪе'] +['Ġöl', 'ç'] +['Ġölç', 'ü'] +['ĠÙĬ', 'جعÙĦ'] +['ĠÄij', 'ỡ'] +['ש', '×Ļ׾'] +['ש×Ļ׾', '×ķ×ij'] +['ĠGr', 'Ã¶ÃŁe'] +['ĠÙĩ', 'اتÙģ'] +['รà¹īาà¸Ļ', 'à¸Ńาหาร'] +['×Ķ׾', '×Ļ׼'] +['×Ķ׾×Ļ׼', '×Ļ'] +['иÑĢÑĥ', 'ÑİÑī'] +['èĭ¥', 'ãģĦ'] +['ĠÃĸ', 'zel'] +['ãģĦãģŁ', 'ãĤī'] +['à¸Ħำ', 'à¸ĸาม'] +['Ġzosta', 'ÅĤy'] +['Ġ×Ķס', '×Ļפ×ķר'] +['×Ķ', '×ķ׾'] +['×Ķ×ķ׾', '×ļ'] +['à¹Ģà¸Ĭà¹Īà¸Ļ', 'à¸ģัà¸Ļ'] +['à¹Ĥ', 'à¸Ĩ'] +['à¹Ĥà¸Ĩ', 'ษ'] +['à¹Ĥà¸Ĩษ', 'à¸ĵา'] +['×IJר', 'צ×ķת'] +['×Ĵר', 'פ×Ļ'] +['Ġao', 'ût'] +['ĠÙĬ', 'رÙĬد'] +['ت', 'ÙĪØ¬'] +['تÙĪØ¬', 'ÙĬÙĩ'] +['ĠÑįÑĤ', 'ап'] +['ãĤ¹ãĤ¿', 'ãĥ³'] +['Ġkr', 'ó'] +['Ġkró', 'tk'] +['ãĤĴ使', 'ãģĨ'] +['ì', '·¨'] +['éĸ¢', 'ãĤı'] +['à¸Ķà¹īวย', 'à¸Ħวาม'] +['à¸Ļำ', 'à¹Ģสà¸Ļà¸Ń'] +['Ġa', 'yrıca'] +['à¸Ī', 'à¹īาà¸ĩ'] +['ĠÑĦоÑĤ', 'огÑĢаÑĦ'] +['Ġв', 'еÑĩ'] +['ĠвеÑĩ', 'еÑĢ'] +['åĩº', 'ãģĹãģŁ'] +['ĠÐ¥', 'о'] +['Ġ×ŀ', 'ר×Ĵ×Ļש'] +['à¹ĥหà¹ī', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['ãĤĴ', '缮'] +['ãĤĴ缮', 'æĮĩ'] +['׾', '×ŀ×Ļ×Ŀ'] +['nÄħ', 'ÅĤ'] +['ĠÑģÑĤ', 'анд'] +['ĠÑģÑĤанд', 'аÑĢÑĤ'] +['ĠSü', 'd'] +['ĠT', 'âm'] +['اخت', 'بار'] +['à¹Ģà¸ģ', 'à¸Ńรà¹Į'] +['Ùħس', 'رØŃ'] +['Ġbi', 'á»ĩn'] +['ب', 'Ùı'] +['Ġص', 'اÙĦ'] +['ĠصاÙĦ', 'ØŃ'] +['ĠPh', 'ụ'] +['íľ', '´'] +['ãĥ¬ãĥĵ', 'ãĥ¥ãĥ¼'] +['Ġbụ', 'ng'] +['Ġrég', 'ime'] +['ĠØ£', 'Ø´Ùĩر'] +['ĠÑĢабоÑĤ', 'ник'] +['à¸Ŀ', 'ัà¸Ļ'] +['اع', 'تÙħ'] +['اعتÙħ', 'اد'] +['Ġзам', 'еÑĤ'] +['ãģ¾', 'ãģ£ãģ¦'] +['Ġch', 'ặt'] +['æĿ¥', 'ãĤĭ'] +['ĠاÙĦÙĤ', 'ÙĪØ§Øª'] +['ãģ«åħ¥', 'ãģ£ãģ¦'] +['تØŃ', 'اÙĦÙģ'] +['Ùħ', 'زÙĬد'] +['ĠÙĬ', 'صÙĦ'] +['ìĹ', '¼'] +['à¹Ģà¸Ĭ', 'à¹ĩ'] +['à¹Ģà¸Ĭà¹ĩ', 'à¸Ħ'] +['Ġk', 'á»ĭ'] +['Ġká»ĭ', 'p'] +['ĠìķĦ', 'ì§ģ'] +['×IJ׳', '×Ĵ'] +['Ġобла', 'ÑģÑĤÑĮ'] +['Ġpomoc', 'Äħ'] +['Ġ×ķ', 'ש׾'] +['ëĵł', 'ì§Ģ'] +['ĠGi', 'ám'] +['ĠSt', 'ück'] +['Ġchá', 'y'] +['ĠëĤĺ', 'ìĺ¤'] +['ש', '×Ļ×ĺת'] +['×ŀ×ĵ', 'ר'] +['×ŀ×ĵר', '×Ļ×ļ'] +['Ġsüre', 'ç'] +['к', 'ва'] +['×ij׾', '×Ļ×Ŀ'] +['×Ķ', 'ת×Ļ'] +['×Ķת×Ļ', '×Ļ×Ĺס'] +['ÙĤب', 'اÙĦ'] +['Ġס', '×ķ×Ĵ'] +['Ġס×ķ×Ĵ', '×Ļ'] +['ÑģÑĤ', 'олÑĮ'] +['ä½ķ', 'ãĤĤ'] +['×ĸ׼', '×ķר'] +['è²·', 'ãģĨ'] +['å®ī', 'ãģı'] +['à¸Ħรัà¹īà¸ĩ', 'à¸Ļีà¹ī'] +['kö', 'p'] +['ĠÑģеÑĢ', 'виÑģ'] +['оÑĩ', 'нÑĭÑħ'] +['ê±°', 'ëŀĺ'] +['تأ', 'Ùĥ'] +['تأÙĥ', 'ÙĬد'] +['×ĵ', '׾ק'] +['Ġпо', 'Ñĩем'] +['ĠпоÑĩем', 'Ñĥ'] +['пиÑģ', 'аÑĤÑĮ'] +['×ij', 'שר'] +['ĠH', 'Ãłng'] +['ĠT', 'ìm'] +['Ġtr', 'ừ'] +['ãĤ»', 'ãĥĥãĤ¯ãĤ¹'] +['×ķ׳', '×Ĵ'] +['mız', 'da'] +['п', 'Ñģи'] +['ĠìŀĪ', '기'] +['Ġr', 'út'] +['ز', 'اÙĨ'] +['تÙĨ', 'ÙĪØ¹'] +['ÙħÙĤ', 'ا'] +['ÙħÙĤا', 'ÙĪÙħØ©'] +['Ġ׾צ', '×ķר×ļ'] +['Ġ×ij', '×Ļר×ķש׾×Ļ×Ŀ'] +['ãĥ´', 'ãĤ£'] +['eb', 'ile'] +['ebile', 'ceÄŁi'] +['ãĥ¦', 'ãĥ¼ãĤ'] +['ãĥ¦ãĥ¼ãĤ', '¶'] +['ãĥ¦ãĥ¼ãĤ¶', 'ãĥ¼'] +['ãĤĴä½ľ', 'ãĤĭ'] +['Ñģ', 'меÑĢ'] +['ÑģмеÑĢ', 'ÑĤ'] +['Ġì§', 'ģ'] +['Ġì§ģ', 'ìłij'] +['ĠÐŁ', 'аÑĢ'] +['ØŃ', 'اض'] +['ØŃاض', 'ر'] +['Ùħ', 'ÙĥاÙģ'] +['ÙħÙĥاÙģ', 'ØŃØ©'] +['ล', 'ิà¸Ļ'] +['ãģ¦', 'ãģįãģ¦'] +['ÑĢоÑģ', 'л'] +['ĠÄ°ÅŁ', 'te'] +['ÙĤص', 'ÙĬر'] +['Ġ×ij×Ĵ', '×Ļ׾'] +['Ġ×ŀת', '×IJ×Ļ×Ŀ'] +['Ġ×Ķ', '×Ĺ×ĵ'] +['Ġ×Ķ×Ĺ×ĵ', 'ש×Ķ'] +['ר', '×ķ×¢'] +['Ġprodukt', 'ów'] +['ĠÙħ', 'صدر'] +['не', 'ÑĨ'] +['ĠاÙĦعÙħÙĦ', 'ات'] +['Ġçık', 'ma'] +['Ġد', 'بÙĬ'] +['×§', '×Ļף'] +['ת', '×IJר'] +['ת×IJר', '×Ļ×ļ'] +['׳×Ļ', '×Ļ×ĵ'] +['صر', 'اع'] +['l', 'ève'] +['צ', '×Ļר'] +['à¸Ķ', 'ัà¸Ļ'] +['à¹ĥหà¹ī', 'à¹Ħà¸Ķà¹ī'] +['ãĤ¿ãĤ¤', 'ãĥł'] +['Ġgi', 'ảng'] +['С', 'ÐŁ'] +['ĠاÙĦÙħ', 'ØŃÙĦ'] +['ĠاÙĦÙħØŃÙĦ', 'ÙĬØ©'] +['ĠT', 'ất'] +['׾', '×ķ×ĺ'] +['h', 'á»ķ'] +['Ġam', 'éric'] +['Ġaméric', 'ain'] +['Ġ×ijש׾', '×ij'] +['Ġ׾×IJ', '×ķ×ŀ×Ļ'] +['Ġpe', 'ça'] +['ĠÑĢаз', 'нÑĭÑħ'] +['ãģĦãĤĭ', 'ãģ¨'] +['ãĥĩ', 'ãĥ³'] +['ס', 'קר'] +['Ġ×Ķ×ŀ×Ĺ', '×Ļר'] +['ãģ¨ãģĦãģĨ', 'ãĤĤãģ®'] +['رت', 'بط'] +['ĠиÑģÑĤ', 'оÑĩ'] +['ĠиÑģÑĤоÑĩ', 'ник'] +['สมัà¸Ħร', 'สมาà¸Ĭิà¸ģ'] +['Ġ', 'à¸Ĺัà¹īà¸ĩ'] +['Ġà¸Ĺัà¹īà¸ĩ', 'à¸Ļีà¹ī'] +['ĠT', 'áºŃp'] +['ãģ£ãģ¦', 'ãģĦãģĨ'] +['ĠاÙĦÙĪ', 'صÙĪÙĦ'] +['Ġdéc', 'ada'] +['Ġо', 'ÑĦоÑĢм'] +['ĠоÑĦоÑĢм', 'лен'] +['สำหรัà¸ļ', 'à¸ģาร'] +['Ġog', 'óln'] +['ãģĨãģ¡', 'ãģ«'] +['Ġvá', 'rias'] +['ãģĻãģİ', 'ãĤĭ'] +['ÙĪ', 'Ùĩا'] +['à¹Ĥà¸Ľà¸£', 'à¸Ķ'] +['ĠÐłÐ¾ÑģÑģ', 'иÑı'] +['人', 'ãĢħ'] +['ãģĹãģ¦', 'ãģįãģŁ'] +['Ġsı', 'rasında'] +['Ġng', 'ôn'] +['س', 'ÙĨØ©'] +['تÙħ', 'تع'] +['×ŀ׼', '×ij×Ļ'] +['Ġnh', 'ấn'] +['×¢', '×ŀ×Ļ×ĵ'] +['á»', '¨'] +['ж', 'иÑĤÑĮ'] +['ãĤī', 'ãģĽ'] +['gr', 'áf'] +['gráf', 'ica'] +['ĠÙĤ', 'ÙĪÙĦ'] +['ĠÙĤÙĪÙĦ', 'Ùĩ'] +['ëĭ¨', 'ì²´'] +['ห', 'à¹īา'] +['หà¹īา', 'ม'] +['使', 'ãģ£ãģ¦'] +['ת', '×Ļ×ij'] +['ת×Ļ×ij', 'ת'] +['i', 'á»ĥu'] +['à¹ģ', 'à¸Ĭม'] +['à¹ģà¸Ĭม', 'à¸Ľ'] +['à¹ģà¸Ĭà¸¡à¸Ľ', 'à¹Į'] +['áº', '¬'] +['ĠëĤĺ', 'ëĿ¼'] +['ĠÙħباشر', 'Ø©'] +['Ġtr', 'Äĥm'] +['سÙĥ', 'ÙĪ'] +['ĠاÙĦذ', 'Ùī'] +['Ġbi', 'ç'] +['Ġbiç', 'im'] +['ت', 'راجع'] +['Ġоб', 'еÑģп'] +['ĠобеÑģп', 'еÑĩ'] +['ĠобеÑģпеÑĩ', 'ива'] +['Ġвозд', 'ÑĥÑħ'] +['Ñĭв', 'аÑĤÑĮ'] +['ÙĦ', 'ØŃÙĤ'] +['ĠMü', 'dü'] +['ĠMüdü', 'rl'] +['ĠMüdürl', 'Ã¼ÄŁÃ¼'] +['Ġyapt', 'ır'] +['Ġפר', 'ס'] +['Ġפרס', '×ķ×Ŀ'] +['Ø·', 'ÙĪØ±'] +['ÑģÑĤв', 'оваÑĤÑĮ'] +['ìŀ¥', 'ìĿĦ'] +['à¸Ĺีà¹Īà¸Ķี', 'à¸Ĺีà¹Īสุà¸Ķ'] +['à¸Ńั', 'ล'] +['ÑĢ', 'Ñİ'] +['Ùħست', 'ÙĤبÙĦ'] +['Ñģл', 'ÑĥÑĪ'] +['ÑģлÑĥÑĪ', 'а'] +['èªį', 'ãĤģ'] +['Ġ׾', '×Ļ×ŀ'] +['Ġ׾×Ļ×ŀ', '×ķ×ĵ×Ļ'] +['ת', 'ש×ķ×ij'] +['תש×ķ×ij', '×ķת'] +['ĠgerçekleÅŁtir', 'il'] +['ĠاÙĦ', 'اتÙ쨧ÙĤ'] +['ĠÑĥÑĢов', 'не'] +['ĠÑĤ', 'ÑĢав'] +['Ġ×Ķ×ŀ', '×ķף'] +['ØŃÙģ', 'اظ'] +['ĠÙħ', 'ÙIJ'] +['ĠÙħÙIJ', 'ÙĨ'] +['ĠÙħÙIJÙĨ', 'ÙĴ'] +['Ġdem', 'ás'] +['×ŀ×ķ×ĸ', '×Ļ×§×Ķ'] +['ש', '×Ļ×Ĺ×Ķ'] +['Ġb', 'ú'] +['алÑĮ', 'нÑĭм'] +['ãĤı', 'ãģŁ'] +['ãĤıãģŁ', 'ãģĹ'] +['ĠاÙĦÙħÙĪ', 'اد'] +['ת', '׼׳'] +['×ª×Ľ×ł', '×ķף'] +['ãĥŃ', 'ãĥĥãĤ¯'] +['hi', 'ếu'] +['ĠÑĥ', 'ме'] +['ÙħØŃا', 'ÙĪÙĦØ©'] +['×IJ', '×ķשר'] +['Ġкон', 'кÑĥÑĢ'] +['ĠконкÑĥÑĢ', 'Ñģ'] +['Ġ×ŀ', '×ij×Ĺ'] +['Ġ×ŀ×ij×Ĺ', '×Ļ×ł×ª'] +['Ġan', 'lam'] +['Ġanlam', 'ı'] +['Ġli', 'á»ĩt'] +['Ġв', 'Ñħод'] +['ĠH', 'ình'] +['ĠÙĨ', 'ÙĬ'] +['ĠÙĨÙĬ', 'ÙĪØ²'] +['ãĤ¸ãĥ£', 'ãĥ¼'] +['×ij', '×Ļ×¥'] +['ÑĤелÑĮ', 'нÑĭÑħ'] +['à¸Ĺุà¸ģ', 'à¸Ńยà¹Īาà¸ĩ'] +['ĠkiÅŁ', 'inin'] +['Ø£', 'Ùĥثر'] +['ĠиÑģÑĤоÑĢ', 'ии'] +['Ġë³Ģ', 'íĻĶ'] +['פ׾', 'ס×ĺ'] +['×¤×ľ×¡×ĺ', '×Ļ׳×Ļ'] +['ĠÑģ', 'еÑĤ'] +['ĠÑģеÑĤ', 'и'] +['dıģ', 'ımız'] +['íķĺ', 'ëıĦë¡Ŀ'] +['×Ķ', 'ר'] +['×Ķר', '×ij×Ķ'] +['ãģĻãĤĭãģĵãģ¨', 'ãģ¯'] +['Ġphi', 'ếu'] +['تØŃ', 'سÙĬÙĨ'] +['ĠÅĽ', 'rod'] +['ĠÅĽrod', 'ow'] +['ĠÅĽrodow', 'isk'] +['ĠÑĢаÑģ', 'Ñħод'] +['بر', 'ÙĬد'] +['Ġر', 'ÙĬ'] +['ĠرÙĬ', 'اÙĦ'] +['Ġ×ķ', '׼×ļ'] +['ì§Ģ', 'ìļĶ'] +['׼', '×ŀ×ķ'] +['Ġ×¢×ľ', '×Ļ×Ķ×Ŀ'] +['f', 'ÃŃcio'] +['Ġkar', 'arı'] +['tıģ', 'ını'] +['ĠС', 'ов'] +['ĠСов', 'еÑĤ'] +['ãģĬéĩij', 'ãĤĴ'] +['м', 'еждÑĥ'] +['междÑĥ', 'на'] +['междÑĥна', 'ÑĢод'] +['междÑĥнаÑĢод', 'н'] +['Ġm', 'á»Ŀi'] +['ĠاÙĦØ¥', 'ÙĬر'] +['ĠاÙĦØ¥ÙĬر', 'اÙĨÙĬ'] +['ĠاÙĦرÙĪ', 'سÙĬ'] +['ص', 'ÙĨد'] +['صÙĨد', 'ÙĪÙĤ'] +['ĠاÙĦØ¥ÙĨ', 'ترÙĨت'] +['Ġt', 'ắm'] +['ĠÑĤак', 'ого'] +['Ġ×ij', '׾×ķ×Ĵ'] +['Ġü', 'crets'] +['Ġücrets', 'iz'] +['×Ĺ×ĸ', '×Ļר'] +['ìĸ´', 'ìķ¼'] +['ĠPh', 'ần'] +['ï¼', 'ľ'] +['Ġ×ĺ', '×ij×¢'] +['Ġ×ĺ×ij×¢', '×Ļ'] +['×IJ×ŀ', '×IJ'] +['اÙĤ', 'ÙĦ'] +['Ġcondi', 'ções'] +['ÙĤات', 'ÙĦ'] +['ĠÑĢезÑĥлÑĮÑĤаÑĤ', 'е'] +['ĠÑģво', 'ими'] +['צ×ij', '×Ļ×¢'] +['gé', 'ni'] +['Ġz', 'es'] +['Ġzes', 'po'] +['Ġzespo', 'ÅĤ'] +['ÑĪ', 'ив'] +['Ġפר×ĺ×Ļ', '×ķת'] +['Ùħست', 'Ø´Ùģ'] +['ÙħستشÙģ', 'Ùī'] +['شر', 'ع'] +['Ġko', 'ÅĽci'] +['Ġ×Ķ×IJ', '×Ļ׳×ĺר׳×ĺ'] +['ĠЧ', 'еÑĢ'] +['поÑĩ', 'ÑĤ'] +['Ġactiv', 'ités'] +['çŁ¥', 'ãģ£ãģ¦'] +['Ġ×ij', '×ĸ×Ķ'] +['Ġyüz', 'den'] +['ãģªãĤĬ', 'ãģ¾ãģĽãĤĵ'] +['Ġíĺ', '¹'] +['Ġíĺ¹', 'ìĿĢ'] +['Ġ×ŀש', '׳×Ķ'] +['ĠÐĴ', 'еÑĢ'] +['Ġ×ij×IJ×ķת', '×ķ'] +['éĿ¢', 'çϽ'] +['éĿ¢çϽ', 'ãģĦ'] +['شر', 'ØŃ'] +['gr', 'ünde'] +['Ùģ', 'Ø´'] +['Ù쨴', 'ÙĦ'] +['Ġsé', 'jour'] +['ë´', 'IJ'] +['Ġr', 'ôle'] +['Ø´', 'عار'] +['ем', 'Ñĭе'] +['ĠاÙĦج', 'سÙħ'] +['алÑĮ', 'ное'] +['Ġìĥģ', 'íĥľ'] +['ï¼', '¤'] +['ë¯Ģ', 'ë¡ľ'] +['ĠÙĨ', 'ÙĤØ·'] +['ĠÙĨÙĤØ·', 'Ø©'] +['ãģĿãģĨ', 'ãģł'] +['ãģĻãĤĭ', 'ãģ®ãģĮ'] +['ห', 'ู'] +['Ġnh', 'á»ĭ'] +['Ġeconóm', 'ica'] +['ס×ĺ', '×ķ×ĵ'] +['ס×ĺ×ķ×ĵ', '׳×ĺ'] +['มี', 'à¹Ĥà¸Ńà¸ģาส'] +['Ġgest', 'ão'] +['รูà¹ī', 'วà¹Īา'] +['Ġlo', 'ạt'] +['ĠاÙĦÙħ', 'Ùı'] +['ĠاÙĦØŃ', 'ÙħÙĦ'] +['ĠاÙĦعÙħÙĦ', 'ÙĬØ©'] +['Ġê²ĥ', 'ëıĦ'] +['ĠÐľÐ¾Ñģк', 'ва'] +['×§×ĺ', '×ķר'] +['Ġпод', 'ÑĢоб'] +['ĠподÑĢоб', 'н'] +['Ġl', 'ưng'] +['ت', 'Ù쨳'] +['تÙ쨳', 'ÙĬر'] +['ĠاÙĦ', 'بع'] +['ĠاÙĦبع', 'ض'] +['ئ', 'ت'] +['Ðķ', 'ÐĿ'] +['ìŰ', '구'] +['à¹ĥหà¹ī', 'à¸Ħุà¸ĵ'] +['ãģĤãĤĬ', 'ãģ¾ãģĹãģŁ'] +['Ġbir', 'ka'] +['Ġbirka', 'ç'] +['Ġİ', 'sl'] +['Ġİsl', 'am'] +['çĹĽ', 'ãģ¿'] +['Ġh', 'ảo'] +['Ġм', 'аÑı'] +['ĠiÅŁ', 'çi'] +['ש', '×'] +['ש×', 'ģ'] +['à¸ģาร', 'à¹Ģมืà¸Ńà¸ĩ'] +['×ķ×Ķ', 'ר'] +['Ġch', 'ó'] +['ëĨ', 'Ģ'] +['Ġyan', 'lı'] +['Ġyanlı', 'ÅŁ'] +['幸', 'ãģĽ'] +['×IJר×Ĵ', '×ķ׳×Ļ'] +['à¸Ńาà¸Ī', 'าร'] +['à¸Ńาà¸Īาร', 'ยà¹Į'] +['ĠинÑĦоÑĢм', 'аÑĨиÑİ'] +['Ðĵ', 'Ðŀ'] +['׳', '×Ĺש'] +['ĠìķĮ', 'ìķĦ'] +['ĠÑħаÑĢакÑĤеÑĢ', 'иÑģÑĤ'] +['ĠÑħаÑĢакÑĤеÑĢиÑģÑĤ', 'ик'] +['à¸Ħุà¸ĵ', 'สามารà¸ĸ'] +['è¦ĭ', 'ãģĪãĤĭ'] +['à¸Ĭัà¸Ķ', 'à¹Ģà¸Ī'] +['à¸Ĭัà¸Ķà¹Ģà¸Ī', 'à¸Ļ'] +['ĠdziaÅĤ', 'al'] +['ĠdziaÅĤal', 'noÅĽci'] +['à¹Ĥà¸ŀ', 'สà¸ķà¹Į'] +['ĠÐļ', 'ол'] +['ĠÙģ', 'ÙĩÙĬ'] +['Ġ×ŀ', 'פ׳×Ļ'] +['Ġ×Ķ×§', 'שר'] +['Ùħر', 'Ùĥ'] +['ÙħرÙĥ', 'ز'] +['Ġho', 'á'] +['Ġа', 'пп'] +['Ġапп', 'аÑĢаÑĤ'] +['Ġp', 'ami'] +['Ġpami', 'ÄĻ'] +['ĠpamiÄĻ', 'ta'] +['Ġç', 'ünkü'] +['×ĵ', '×ķף'] +['ãģ¯', 'ãģĵãģ¡ãĤī'] +['ĠM', 'Ãł'] +['ĠÙĬ', 'ÙĤدÙħ'] +['ĠпÑĢ', 'ез'] +['ĠпÑĢез', 'иденÑĤ'] +['à¸Ńุ', 'à¸ķ'] +['à¸Ńุà¸ķ', 'สา'] +['à¸Ńุà¸ķสา', 'ห'] +['à¸Ńุà¸ķสาห', 'à¸ģรรม'] +['ì§Ģ', 'ìĽIJ'] +['Ġ×IJפשר', '×ķת'] +['sch', 'üt'] +['schüt', 'z'] +['ĠTi', 'ên'] +['Ġsay', 'ılı'] +['ĠгÑĢÑĥпп', 'Ñĭ'] +['оÑĩ', 'нÑĭй'] +['Ġ×ľ×¢', '×ŀ×ķ×ĵ'] +['Ġwr', 'zeÅĽ'] +['ĠwrzeÅĽ', 'nia'] +['ĠÄIJ', 'ầu'] +['à¹Ģà¸Ĥà¹īา', 'รà¹Īวม'] +['nız', 'da'] +['Ø®ÙĬ', 'ص'] +['Ġgü', 'nc'] +['Ġgünc', 'el'] +['ĠÙĦÙĩ', 'ذÙĩ'] +['ĠÙĬ', 'عتبر'] +['lé', 'gi'] +['ãĤı', 'ãģĭãĤĭ'] +['Ġr', 'ừng'] +['ظ', 'Ùĩ'] +['ظÙĩ', 'ÙĪØ±'] +['Ġ×ŀ×ij', '×Ļף'] +['Ġ기', 'íĥĢ'] +['åĪĩ', 'ãĤĮ'] +['lan', 'mÄ±ÅŁ'] +['à¸Ĺีà¹Ī', 'มีà¸Ħวาม'] +['Ġh', 'á»ģ'] +['ت', 'ÙĪØ¬Ùĩ'] +['ĠاÙĦØ¥', 'دارة'] +['Ġú', 'til'] +['ס', 'פ×ķ'] +['à¸Ħวาม', 'รัà¸ģ'] +['à¹Ĥ', 'ฮ'] +['Ġпол', 'иÑĤ'] +['ĠполиÑĤ', 'ик'] +['Ġsat', 'ın'] +['ĠÅŀ', 'imdi'] +['×ŀ', '×ķר×Ļ×Ŀ'] +['ìķĺ', 'ëĭ¤'] +['×Ĺ', '×ķ×ķ'] +['×Ĺ×ķ×ķ', '×Ļ×Ķ'] +['à¸Ħà¸Ńม', 'à¸ŀิ'] +['à¸Ħà¸Ńมà¸ŀิ', 'ว'] +['à¸Ħà¸Ńมà¸ŀิว', 'à¹Ģà¸ķà¸Ńรà¹Į'] +['Ġا', 'ذا'] +['تخ', 'اذ'] +['ãĤ¨', 'ãĥ«'] +['Ġpossibilit', 'é'] +['ยืà¸Ļ', 'ยัà¸Ļ'] +['Ġü', 'nivers'] +['Ġünivers', 'ite'] +['ĠاÙĦد', 'ÙĪØ±ÙĬ'] +['ĠìķĬëĬĶ', 'ëĭ¤'] +['ĠìĦľ', 'ë¡ľ'] +['ØŃ', 'اÙĦ'] +['Ġë', '¨'] +['Ġë¨', '¼'] +['Ġ먼', 'ìłĢ'] +['à¸Ĺีà¹Ī', 'à¸ĸูà¸ģ'] +['ì§', 'ľ'] +['Ġsk', 'óry'] +['лÑĮ', 'ÑĨ'] +['à¹ĥà¸Ĭà¹ī', 'à¹Ģวลา'] +['×ij×§', 'שת'] +['Ġذ', 'ÙĪ'] +['æĹ¥', 'ãĢħ'] +['ĠкоÑĤоÑĢ', 'ÑĥÑİ'] +['ĠÑĥÑĢов', 'енÑĮ'] +['ê¹', '¨'] +['à¹Ħ', 'à¸Ĺ'] +['ãĤµ', 'ãĥĹãĥª'] +['ãĤ¸', 'ãĥ§ãĥ³'] +['ãģĻ', 'ãģ¹ãģį'] +['ĠG', 'ór'] +['ãĥĪ', 'ãĤ¤'] +['ãĥĪãĤ¤', 'ãĥ¬'] +['ĠyaÅŁ', 'ama'] +['Ġdá»ĭ', 'p'] +['Ġb', 'ữa'] +['à¸ĭ', 'ุ'] +['Ġöl', 'üm'] +['ãģ£ãģ¦', 'ãģıãĤĭ'] +['à¸ģาร', 'à¸Ħà¹īา'] +['ש', 'ער'] +['ĠÑĤип', 'а'] +['Ġг', 'еÑĢ'] +['ĠгеÑĢ', 'о'] +['רק', '×¢'] +['Ġu', 'waż'] +['Ġuważ', 'a'] +['ש×ŀ', 'ף'] +['Ġhast', 'alık'] +['ãĤıãĤĮ', 'ãĤĭ'] +['ba', 'ÅŁÄ±'] +['Ñĩ', 'ÑĤо'] +['Ġ×ij', '×ŀר׼×ĸ'] +['Ġìļ°ë¦¬', 'ìĿĺ'] +['ĠÙĥاÙĨ', 'ÙĪØ§'] +['ĠØ£', 'بر'] +['Ġأبر', 'ÙĬÙĦ'] +['ì¸', 'µ'] +['à¹Ħà¸Ĥ', 'à¹Ī'] +['ĠÙĪ', 'ÙĦÙĪ'] +['à¸Ĺ', 'ัว'] +['à¸Ĺัว', 'รà¹Į'] +['ĠÙĪØ£', 'Ùĥد'] +['à¸Ĭ', 'วà¸Ļ'] +['׾', '×ķ×§'] +['æį', '¨'] +['æį¨', 'ãģ¦'] +['Ġİç', 'in'] +['p', 'éri'] +['Ġy', 'al'] +['Ġyal', 'nız'] +['ÑĮÑı', 'н'] +['Ġg', 'ắng'] +['à¸ģà¹ĩ', 'ยัà¸ĩ'] +['ĠУкÑĢа', 'ин'] +['ĠÑģ', 'ами'] +['ĠпÑĢовед', 'ен'] +['à¸ķà¸ģ', 'à¹ģà¸ķà¹Īà¸ĩ'] +['ĠQu', 'ân'] +['é', 'paration'] +['ĠbaÅŁ', 'ında'] +['Ġzn', 'ale'] +['Ġznale', 'ź'] +['Ġznaleź', 'Äĩ'] +['ãĤ±', 'ãĥ¼'] +['ãĥİ', 'ãĥ¼'] +['à¸ĸูà¸ģ', 'à¸ķà¹īà¸Ńà¸ĩ'] +['ëª', '¸'] +['Ġëı', 'Į'] +['ĠëıĮ', 'ìķĦ'] +['ĠSch', 'üler'] +['Ġпод', 'гоÑĤов'] +['ĠподгоÑĤов', 'к'] +['ع', 'رÙĪ'] +['عرÙĪ', 'ض'] +['la', 'ÅŁtır'] +['ĠÑģоÑģÑĤав', 'лÑıеÑĤ'] +['ĠпÑĢоиз', 'вод'] +['ĠпÑĢоизвод', 'ÑģÑĤва'] +['ĠоÑģнов', 'е'] +['ĠØ´', 'ÙħاÙĦ'] +['à¸ģร', 'ี'] +['ĠgörÃ¼ÅŁ', 'me'] +['оÑĩ', 'ек'] +['Ġ×Ĺ×ijר', '×Ļ×Ŀ'] +['ÙħØ®', 'اط'] +['Ùħخاط', 'ر'] +['ï¼', 'Ń'] +['ר', 'פ×IJ'] +['ĠM', 'ẹ'] +['ยà¸Ńม', 'รัà¸ļ'] +['Ġv', 'ết'] +['Ø®', 'ذ'] +['ĠاÙĦت', 'Ø·'] +['ĠاÙĦتط', 'بÙĬÙĤ'] +['à¸Ļ', 'ึà¸ģ'] +['Ġ×Ķ', '×Ľ×ł×¡×ª'] +['ĠогÑĢ', 'ани'] +['ĠогÑĢани', 'Ñĩен'] +['ĠÃĩ', 'alÄ±ÅŁ'] +['ĠاÙĦÙħÙĨت', 'دÙī'] +['à¸Īำà¸Ļวà¸Ļ', 'มาà¸ģ'] +['ĠÑĤоÑĢ', 'ÑĢ'] +['ĠÑĤоÑĢÑĢ', 'енÑĤ'] +['ĠìĤ´', 'ìķĦ'] +['à¸ŀลัà¸ĩ', 'à¸ĩาà¸Ļ'] +['à¸Ĭ', 'ัà¸Ļ'] +['ĠÐIJн', 'дÑĢ'] +['Ġréalis', 'é'] +['×ŀש', '×IJ'] +['à¹ģ', 'à¸Ĭ'] +['à¹ģà¸Ĭ', 'รà¹Į'] +['Ġб', 'ог'] +['มา', 'à¹ģลà¹īว'] +['ĠاÙĦÙĨ', 'ار'] +['Ġolmad', 'ıģı'] +['×ĵ', '×¢×Ķ'] +['ĠÑĥ', 'веÑĢ'] +['ĠÑĥвеÑĢ', 'ен'] +['ãĤĭ', 'ãĤĤãģ®'] +['Ø£', 'د'] +['أد', 'ÙĪØ§Øª'] +['Ġ×Ķ×ĸ', '×ķ×Ĵ'] +['Ø¥', 'عÙĦاÙħ'] +['h', 'á»ı'] +['ĠNä', 'he'] +['ĠÑĤ', 'еÑģÑĤ'] +['Ġ×ŀ', '×ķ׼ר'] +['Ġë¬¸ìłľ', 'ê°Ģ'] +['ת', '×ķצ×IJ×Ķ'] +['m', 'ó'] +['mó', 'vel'] +['ĠاÙĦتج', 'ارة'] +['Ġмног', 'иÑħ'] +['обÑī', 'а'] +['Ġ×¢', 'סק×Ļ'] +['ĠEdu', 'cação'] +['×§', 'ש×Ļ×Ŀ'] +['é', 'tabl'] +['établ', 'issement'] +['Ġд', 'еле'] +['иÑĢÑĥ', 'еÑĤÑģÑı'] +['Ø¢', 'ثار'] +['Ġ×Ķ×ŀ', 'ר׼×ĸ×Ļ'] +['ãĥIJ', 'ãĥ«'] +['ĠвÑģÑĤÑĢ', 'еÑĩ'] +['ãģĴ', 'ãĤĭ'] +['Ġci', 'Äħ'] +['ĠciÄħ', 'gu'] +['ÙĬ', 'ست'] +['à¸łà¸²', 'ว'] +['à¸łà¸²à¸§', 'ะ'] +['Ø£', 'Ùħر'] +['Ġо', 'жи'] +['Ġожи', 'да'] +['Ġ', 'á»§y'] +['ãĥŀ', 'ãĥ«'] +['ر', 'اس'] +['оÑĩ', 'ной'] +['ת', '×Ĵ×ķ×ij×ķת'] +['تع', 'رÙĬÙģ'] +['ĠÑģо', 'ÑĨиалÑĮно'] +['ãĤĴ', 'éĸĭ'] +['ĠиÑģÑģлед', 'ова'] +['Ġd', 'ú'] +['Ġdú', 'vida'] +['Ġsk', 'ÅĤ'] +['ĠskÅĤ', 'ada'] +['Ġhä', 'ufig'] +['ĠвÑĭб', 'ÑĢ'] +['ĠвÑĭбÑĢ', 'аÑĤÑĮ'] +['ãģ®ãģ§ãģ¯ãģªãģĦ', 'ãģĭ'] +['ĠÑģ', 'илÑĮно'] +['ÑĤвеÑĢж', 'ден'] +['ר', 'פ'] +['רפ', '×ķ×IJ×Ķ'] +['æĢĿ', 'ãģĦãģ¾ãģĻ'] +['ØŃر', 'ص'] +['ש×ķת', '×£'] +['Ùħس', 'جد'] +['à¹Ĥà¸Ĭ', 'วà¹Į'] +['ем', 'ÑģÑı'] +['в', 'ÑĪие'] +['Ġм', 'л'] +['Ġмл', 'н'] +['Ġ׾×Ķ', '×ij×Ļ×IJ'] +['ĠÙĬ', 'تعÙĦÙĤ'] +['à¸ķ', 'ูà¹ī'] +['Ġп', 'ÑĢаз'] +['ĠпÑĢаз', 'д'] +['ĠпÑĢазд', 'ник'] +['Ġн', 'ем'] +['Ġнем', 'ного'] +['Ġs', 'Ãłng'] +['تÙĨ', 'سÙĬ'] +['تÙĨسÙĬ', 'ÙĤ'] +['Ġtá»', 'Ŀ'] +['Ġмед', 'и'] +['ãģ«', 'æĪ'] +['ã쫿Ī', '»'] +['à¸Ħว', 'à¹īา'] +['ãģĭ', 'ãģijãĤĭ'] +['×ij׾', '×ķת'] +['ĠÑįк', 'Ñģп'] +['ĠÑįкÑģп', 'еÑĢÑĤ'] +['Ġдев', 'ÑĥÑĪ'] +['ĠдевÑĥÑĪ', 'к'] +['ĠØŃ', 'ص'] +['ÙĨØ´', 'Ø£'] +['ãģĮãģĤãĤĭ', 'ãģ®ãģ§'] +['Ġت', 'راÙħ'] +['ĠتراÙħ', 'ب'] +['أس', 'ÙĪØ§ÙĤ'] +['Ġ׾פ', '׳×ķת'] +['Ġا', 'ï»·'] +['ãģ«', 'ãģı'] +['ãģ«ãģı', 'ãģĦ'] +['ĠØ£', 'عÙĦÙī'] +['Ġ׾×Ķ', '×ŀש×Ļ×ļ'] +['rä', 'u'] +['ש×ŀ', '×Ļ×Ŀ'] +['åĪĨ', 'ãģij'] +['ãģĻ', 'ãģ§'] +['ãģĻãģ§', 'ãģ«'] +['×Ķ׾', '׼×Ķ'] +['×Ĺ׾', '×Ļ×£'] +['Ġì', '±ħ'] +['Ġì±ħ', 'ìŀĦ'] +['à¹Ģà¸Ī', 'ริ'] +['à¹Ģà¸Īริ', 'à¸į'] +['éģĬ', 'ãģ³'] +['ج', 'سد'] +['สา', 'à¸ĺ'] +['สาà¸ĺ', 'าร'] +['สาà¸ĺาร', 'à¸ĵ'] +['Ġbas', 'ın'] +['ÑĢаÐ', '³'] +['г', 'ад'] +['Ġho', 'ÅŁ'] +['íķ', 'µ'] +['×ij×Ĺ', '×Ļר×Ķ'] +['×ŀס', '×ļ'] +['Ġìłľ', 'íĴĪ'] +['تÙħ', 'ÙĪÙĬÙĦ'] +['ĠL', 'ưu'] +['ë¡ľ', 'ë¶ĢíĦ°'] +['Ġп', 'об'] +['Ġпоб', 'ед'] +['ÙħÙĨ', 'ذ'] +['常', 'ãģ«'] +['ÙĤ', 'س'] +['ĠاÙĦÙħ', 'صدر'] +['ĠÙĪØ§ÙĦ', 'است'] +['Ġkh', 'ắp'] +['ĠاÙĦج', 'اÙĨب'] +['Ġng', 'uyá»ĩn'] +['éĸĵ', 'éģķãģĦ'] +['ĠÑģÑĤ', 'ÑĢа'] +['ĠÑģÑĤÑĢа', 'Ñħ'] +['ĠÑģÑĤÑĢаÑħ', 'ов'] +['รี', 'à¸ļ'] +['Ġx', 'ương'] +['Ġì°', '¾'] +['Ġì°¾', 'ìķĦ'] +['Ġng', 'ại'] +['г', 'ал'] +['à¸ĭ', 'ีà¹Ī'] +['Ġ×ij', 'פ×Ļ×Ļס×ij×ķ×§'] +['Ц', 'енÑĤÑĢ'] +['Ġaval', 'iação'] +['Ġeconóm', 'ico'] +['×ĸ', 'ף'] +['ĠÐľ', 'ак'] +['Ġinter', 'és'] +['à¸ģล', 'ิà¹Īà¸Ļ'] +['ÑģÑĤÑĮ', 'Ñİ'] +['ĠÄij', 'ương'] +['å¼·', 'ãģı'] +['ĠKh', 'ách'] +['à¹Ģà¸Ļืà¹īà¸Ń', 'หา'] +['ĠYaz', 'ı'] +['è²·', 'ãģ£ãģ¦'] +['Ðł', 'Ðķ'] +['à¹Ģà¸ŀิà¹Īม', 'à¸Ĥึà¹īà¸Ļ'] +['สม', 'à¸ļู'] +['สมà¸ļู', 'รà¸ĵà¹Į'] +['Ġм', 'иÑĢов'] +['×Ĵ', '׳×Ļ×Ŀ'] +['ĠÄij', 'ức'] +['à¸Ń', 'ารà¹Į'] +['ص', 'اص'] +['ãģĬ', 'ãĤĪ'] +['ãģĬãĤĪ', 'ãģ³'] +['êÌ', 'ī'] +['ĠاÙĦÙħؤ', 'تÙħر'] +['ĠاÙĦÙħر', 'ØŃÙĦØ©'] +['สà¸Ńà¸ļ', 'à¸ĸาม'] +['Ġà¸Īาà¸ģ', 'à¸Ļัà¹īà¸Ļ'] +['Ġت', 'عد'] +['ãģĿãģ®', 'ãģŁãĤģ'] +['Ġkh', 'áng'] +['à¸Ļ', 'ิà¸Ķ'] +['ãĥĬ', 'ãĥ³'] +['ëĦ¤', 'ìļĶ'] +['ĠاÙĦ', 'اØŃت'] +['ĠاÙĦاØŃت', 'ÙĦاÙĦ'] +['ìļ', 'ķ'] +['Ġмод', 'ели'] +['ĠпÑĢоÑĨ', 'енÑĤ'] +['à¸ŀวà¸ģ', 'à¹Ģรา'] +['Ġ×Ķצ', '×ĵ'] +['Ġ×Ķצ×ĵ', '×ĵ×Ļ×Ŀ'] +['ständ', 'e'] +['׳', '×Ĵר'] +['Ġdot', 'yc'] +['Ġdotyc', 'zÄħ'] +['ĠdotyczÄħ', 'ce'] +['ĠÅĽ', 'wiÄĻt'] +['×ŀר', '×Ķ'] +['ãģĻãģĶ', 'ãģĦ'] +['ãĥĩãĤ£', 'ãĥ³ãĤ°'] +['à¸ģาร', 'สรà¹īาà¸ĩ'] +['ë', 'Ĥ¬'] +['Ġì°¸', 'ìŬ'] +['Ñģ', 'Ñħ'] +['ÑģÑħ', 'ем'] +['ÙħÙĪ', 'س'] +['Ġn', 'ấu'] +['Ġ׾×ŀ×¢', '׾×Ķ'] +['à¹Ģà¸Ľ', 'à¹īา'] +['à¹Ģà¸Ľà¹īา', 'หมาย'] +['Ġmù', 'i'] +['ائ', 'ز'] +['íĽ', 'Ī'] +['×Ĺ×ij', '×ķר×Ķ'] +['à¸ľà¸¹à¹ī', 'à¹ĥà¸Ĭà¹ī'] +['Ġpa', 'ź'] +['Ġpaź', 'dzi'] +['Ġpaździ', 'ern'] +['Ġpaździern', 'ika'] +['ลà¸ĩ', 'à¹Ħà¸Ľ'] +['ÙĤ', 'اع'] +['Ġch', 'áºŃm'] +['Ġözellik', 'leri'] +['ĠÄIJ', 'o'] +['ĠÄIJo', 'Ãłn'] +['ж', 'ение'] +['Ġh', 'ẳ'] +['Ġhẳ', 'n'] +['ĠaÅŁ', 'k'] +['ï½', 'į'] +['ãĥij', 'ãĤ¹'] +['×Ķ×ķר', '×IJ×ķת'] +['ĠÅ', '»'] +['ĠÅ»', 'y'] +['×ŀ×ĸ', '׾'] +['ĠÑĥ', 'кÑĢа'] +['ĠÑĥкÑĢа', 'ин'] +['à¹Ģà¸Ĭ', 'ิ'] +['à¹Ģà¸Ĭิ', 'à¸į'] +['Ðł', 'Ðĺ'] +['ĠzwiÄħz', 'ku'] +['×Ķ×Ĺ׾×ĺ', 'ת'] +['ãĤĵãģ§ãģĻ', 'ãĤĪãģŃ'] +['ãģ¦', 'ãģĬãĤĬ'] +['лож', 'иÑĤÑĮ'] +['×ŀ', '×ķ׳×Ļ×Ŀ'] +['ฮ', 'ิ'] +['ì°', '¬'] +['ĠاÙĦÙħØ´', 'ترÙĥ'] +['ĠdÃ¼ÅŁ', 'ük'] +['аг', 'енÑĤ'] +['ĠاÙĦØ£', 'سبÙĪØ¹'] +['ĠÙĤ', 'رÙĬب'] +['ин', 'д'] +['инд', 'ив'] +['индив', 'ид'] +['индивид', 'Ñĥ'] +['индивидÑĥ', 'алÑĮн'] +['för', 'der'] +['Ġseç', 'en'] +['Ġseçen', 'ek'] +['Ġét', 'ant'] +['ĠлÑİб', 'им'] +['каз', 'ÑĭваеÑĤ'] +['ว', 'ิà¸Ļ'] +['Ġ×Ķ×ij', '×IJ×Ļ×Ŀ'] +['Ġд', 'ов'] +['Ġдов', 'олÑĮ'] +['ĠдоволÑĮ', 'но'] +['×¢×ĵ', '×Ļ×£'] +['Ġok', 're'] +['Ġokre', 'ÅĽ'] +['ĠokreÅĽ', 'lon'] +['Ġت', 'رÙĬد'] +['à¹Ģมืà¹Īà¸Ń', 'วัà¸Ļà¸Ĺีà¹Ī'] +['ãĤĪ', 'ãģĭãģ£ãģŁ'] +['Cum', 'h'] +['Cumh', 'ur'] +['Cumhur', 'ba'] +['Cumhurba', 'ÅŁ'] +['CumhurbaÅŁ', 'kan'] +['CumhurbaÅŁkan', 'ı'] +['Ġn', 'ợ'] +['à¸ľà¸¹à¹ī', 'à¹Ģลà¹Īà¸Ļ'] +['Ġcompl', 'ète'] +['à¹Ģà¸ŀ', 'ศ'] +['د', 'ÙIJ'] +['Ġdü', 'z'] +['Ġdüz', 'ey'] +['ãģ§ãģĤãĤĭ', 'ãģĵãģ¨'] +['ext', 'érieur'] +['×', '³'] +['Ġinform', 'ação'] +['ãĤ¯ãĥª', 'ãĥĭãĥĥãĤ¯'] +['ĠPub', 'li'] +['ĠPubli', 'é'] +['ר', '×ķ×ĵ'] +['à¸Ħวาม', 'à¸Ľà¸¥à¸Ńà¸Ķà¸łà¸±à¸¢'] +['ĠØ£ÙĬ', 'ض'] +['ĠØ£ÙĬض', 'Ùĭا'] +['ت', 'سبب'] +['ãģ¤', 'ãĤĤãĤĬ'] +['из', 'ма'] +['à¸Ĥึà¹īà¸Ļ', 'à¹Ħà¸Ľ'] +['Ùĥ', 'ÙIJ'] +['ÙĦ', 'ÙĪÙħ'] +['Ġש', 'צר'] +['Ġשצר', '×Ļ×ļ'] +['ãģ¯', 'ãĤĤãģ¡ãĤįãĤĵ'] +['Ġк', 'ан'] +['Ġкан', 'ал'] +['ãģ«ãģª', 'ãģ£ãģ¦ãģĦãģ¾ãģĻ'] +['ĠاÙĦØ£', 'Ùĥثر'] +['ت', 'اØŃ'] +['ÙĨت', 'Ùĩ'] +['ÙĨتÙĩ', 'اء'] +['ا', 'ÙĪÙĬØ©'] +['ĠBug', 'ün'] +['н', 'Ñģкого'] +['à¸Ķ', 'à¹Īวà¸Ļ'] +['é', 'volution'] +['ãģ£ãģ¦', 'ãģĦãģ¾ãģĹãģŁ'] +['ãĤ', 'ħ'] +['ĠV', 'ương'] +['à¸łà¸²à¸ŀ', 'ย'] +['à¸łà¸²à¸ŀย', 'à¸Ļ'] +['à¸łà¸²à¸ŀยà¸Ļ', 'à¸ķรà¹Į'] +['Ġ×Ķ', 'צ׾×Ļ×Ĺ'] +['ĠاÙĦإسÙĦاÙħ', 'ÙĬ'] +['ÙĦÙĬ', 'ب'] +['Ġed', 'ição'] +['ÑģÑĤÑĢ', 'ел'] +['Ġkh', 'úc'] +['ÙĨÙħÙĪ', 'ذ'] +['ÙĨÙħÙĪØ°', 'ج'] +['׾', 'צ×Ķ'] +['ÑģÑĤав', 'ил'] +['à¸ĸ', 'า'] +['สรà¹īาà¸ĩ', 'à¸Ħวาม'] +['ãģĦ', 'ãģ£ãģ±'] +['ãģĦãģ£ãģ±', 'ãģĦ'] +['ÑģÑĤав', 'лен'] +['ĠاÙĦ', 'ÙĤدس'] +['Ġng', 'ược'] +['ب', 'Ø®'] +['ส', 'หร'] +['สหร', 'ั'] +['สหรั', 'à¸IJ'] +['ĠØ£', 'غ'] +['Ġأغ', 'سط'] +['Ġأغسط', 'س'] +['ãģĨ', 'ãģ¾'] +['ãģĨãģ¾', 'ãģı'] +['ĠêµŃ', 'ìłľ'] +['ØŃض', 'ار'] +['Ġd', 'ừng'] +['æĬ¼', 'ãģĹ'] +['ت', 'ÙĪØ§'] +['تÙĪØ§', 'جد'] +['ש×ŀ', '×Ĺ×Ķ'] +['ãģı', 'ãĤĵ'] +['Ġ×ij×¢', 'צ'] +['Ġ×ijעצ', '×Ŀ'] +['×ŀ', '׳×Ļ×ķת'] +['×ķ', '×Ļ×ĵ'] +['×ķ×Ļ×ĵ', '×IJ×ķ'] +['à¸Ĭ', 'ิà¸ĩ'] +['Ġprac', 'ÄĻ'] +['Ġз', 'аÑĤ'] +['ĠзаÑĤ', 'ем'] +['ĠìŀIJ', 'ìľł'] +['Ġì¤', 'Ģ'] +['Ġì¤Ģ', 'ë¹Ħ'] +['Ġb', 'áºŃ'] +['ĠbáºŃ', 'c'] +['Ġ×Ķ×ŀ', 'צ×ij'] +['ĠÙĤ', 'ÙĬÙħØ©'] +['à¹Ģà¸Ń', 'à¹Ģà¸Ĭ'] +['à¹Ģà¸Ńà¹Ģà¸Ĭ', 'ีย'] +['Ġperch', 'è'] +['ĠاÙĦع', 'سÙĥر'] +['ĠاÙĦعسÙĥر', 'ÙĬØ©'] +['ج', 'ÙĬب'] +['ëŀ', 'µ'] +['Ùħ', 'Ùĩر'] +['ÙħÙĩر', 'جاÙĨ'] +['Ùħ', 'راÙĥ'] +['ÙħراÙĥ', 'ز'] +['Ġод', 'нако'] +['à¸Ķี', 'à¹Ĩ'] +['Ġצ', 'פ×ķ'] +['Ġkullan', 'ılan'] +['Ġк', 'ино'] +['ãĥĨãĤ£', 'ãĥ³ãĤ°'] +['ĠGi', 'Ỽi'] +['ت', 'ÙĪØ²'] +['تÙĪØ²', 'ÙĬع'] +['ย', 'ิà¸Ļ'] +['ยิà¸Ļ', 'à¸Ķี'] +['Ġc', 'Åĵur'] +['ĠiÅŁ', 'aret'] +['Ġ×ij×¢', '×ĸר'] +['Ġ×ij×¢×ĸר', 'ת'] +['Ġп', 'аÑĨи'] +['ĠпаÑĨи', 'енÑĤ'] +['ãģ¿ãģŁãģĦ', 'ãģ§ãģĻ'] +['в', 'ез'] +['ли', 'на'] +['од', 'е'] +['Ġ×IJ×ķת', 'ף'] +['dıģ', 'ınız'] +['ĠÐIJ', 'в'] +['ĠÐIJв', 'ÑĤоÑĢ'] +['ï¼', '®'] +['ĠC', 'ần'] +['ĠاÙĦا', 'Ø®'] +['ĠاÙĦاخ', 'بار'] +['Ġê±°', 'ìĿĺ'] +['Ġat', 'enção'] +['Ġgeld', 'iÄŁi'] +['ãĤª', 'ãĤ¹'] +['ãĤªãĤ¹', 'ãĤ¹'] +['ãĤªãĤ¹ãĤ¹', 'ãĥ¡'] +['ев', 'Ñĭе'] +['кÑĢÑĭ', 'л'] +['à¹Ģà¸Ĭ', 'ียà¸ĩ'] +['à¹Ģà¸Ĭียà¸ĩ', 'à¹ĥหมà¹Ī'] +['Ġmar', 'ço'] +['ĠاÙĦÙħ', 'ادة'] +['Ġг', 'ол'] +['Ġsprzeda', 'ży'] +['Ġíķ´', 'ê²°'] +['ĠÐķ', 'го'] +['ê¹', 'Ģ'] +['Ġ׾ק×ij׾', 'ת'] +['ĠاÙĦÙģ', 'ÙĨاÙĨ'] +['Ġcomunic', 'ación'] +['à¹Ģสà¹īà¸Ļ', 'à¸Ĺาà¸ĩ'] +['íĺ', '¹'] +['à¸Ĭ', 'ำ'] +['à¸Ĭำ', 'ระ'] +['Ġ׼', '×IJ×ŀ'] +['Ġ׼×IJ×ŀ', '×ķר'] +['à¸Ĭ', 'à¹Īาà¸ĩ'] +['ز', 'Ùĩر'] +['Ġklient', 'ów'] +['ива', 'ÑİÑĤ'] +['ан', 'г'] +['׳', '×ļ'] +['Ġg', 'á»įn'] +['Ãľ', 'R'] +['ìĺģ', 'ìĥģ'] +['Ġغ', 'زة'] +['ìĿĮ', 'ìĿĦ'] +['Ġbez', 'po'] +['Ġbezpo', 'ÅĽ'] +['ĠbezpoÅĽ', 'redni'] +['ĠاÙĦÙħ', 'ÙĪØ§'] +['ĠاÙĦÙħÙĪØ§', 'Ø·ÙĨ'] +['ĠاÙĦÙħÙĪØ§Ø·ÙĨ', 'ÙĬÙĨ'] +['ãĤĮ', 'ãģ¾ãģĻ'] +['ĠмаÑĤ', 'Ñĩ'] +['×IJ', '×ķף'] +['Ġر', 'سÙħÙĬ'] +['ĠÑįк', 'он'] +['ĠÑįкон', 'ом'] +['ĠÑįконом', 'иÑĩеÑģк'] +['ãĥľ', 'ãĥ¼'] +['Ġд', 'иÑĢ'] +['ĠдиÑĢ', 'екÑĤоÑĢ'] +['ĠÑģк', 'оÑĢо'] +['à¸ļ', 'ำ'] +['à¸ļำ', 'ร'] +['à¸ļำร', 'ุà¸ĩ'] +['ĠÑĦ', 'ÑĥÑĤ'] +['ĠÑĦÑĥÑĤ', 'бол'] +['Ġ×IJ', '×Ļ׾'] +['Ġì¤ij', 'êµŃ'] +['ìľ', '¤'] +['eÄŁ', 'e'] +['à¹Ħ', 'à¸ģà¹Ī'] +['tra', 'î'] +['traî', 'n'] +['ĠÑĤ', 'ÑĢÑĥб'] +['à¹Ģà¸ļ', 'ื'] +['à¹Ģà¸ļื', 'à¹īà¸Ńà¸ĩ'] +['à¹ģม', 'à¸Ļ'] +['ĠتØŃ', 'دÙĬØ«'] +['Ġ׼', 'עת'] +['ØŃ', 'اسب'] +['lı', 'ÄŁa'] +['×§×Ļ', '×Ļ×ŀ×Ļ×Ŀ'] +['оÑģÑĤ', 'ÑĮÑİ'] +['à¸Ŀ', 'ั'] +['à¸Ŀั', 'à¹Īà¸ĩ'] +['Ø´', 'غÙĦ'] +['ìĽ', '¹'] +['Ġкажд', 'ого'] +['Ġbölüm', 'ü'] +['หà¸Ļ', 'ี'] +['Ġistedi', 'ÄŁi'] +['Ġtr', 'ưng'] +['ãĥ', 'Į'] +['ฮ', 'à¸Ń'] +['Ø£ÙĨ', 'Ø´'] +['Ø£ÙĨØ´', 'طة'] +['ĠاÙĦÙħ', 'سÙĬ'] +['ĠاÙĦÙħسÙĬ', 'ØŃ'] +['ลัà¸ģษ', 'à¸ĵà¹Į'] +['Ġn', 'á»Ńa'] +['à¸Ĺีà¹Ī', 'à¸ķà¹īà¸Ńà¸ĩà¸ģาร'] +['ÑĪ', 'ек'] +['л', 'Ñij'] +['Ġש', '×Ļ×Ķ'] +['Ġש×Ļ×Ķ', '×Ļ×Ķ'] +['Ġkhu', 'ôn'] +['ĠÑĤÑĢеб', 'ованиÑı'] +['Ġ×ľ×¢', '×ĸ×ķר'] +['ĠاÙĦع', 'Ùħر'] +['ราà¸Ħา', 'à¸ĸูà¸ģ'] +['ÙĩÙı', 'ÙħÙĴ'] +['ü', 'st'] +['üst', 'ü'] +['Ġден', 'ег'] +['Ġn', 'ạ'] +['à¸Ĥà¸Ļ', 'ม'] +['Ġбл', 'аг'] +['Ġблаг', 'од'] +['Ġблагод', 'аÑĢ'] +['ĠблагодаÑĢ', 'Ñı'] +['Ø¥', 'سÙĦاÙħ'] +['à¸Ļิ', 'ว'] +['çŁ¥', 'ãĤīãģªãģĦ'] +['Ø«', 'ÙĤØ©'] +['Ġг', 'олоÑģ'] +['×IJ×ķר', '×Ĺ'] +['Ġtr', 'ứng'] +['Ġод', 'ном'] +['ĠkoÅĦ', 'cu'] +['Ġ×ķ', 'רק'] +['Wi', 'ÄĻ'] +['WiÄĻ', 'cej'] +['Ġ×IJ', '×Ļ׼×ķת'] +['Ġ×IJ×Ļ׼×ķת', '×Ļ'] +['Ñģ', 'оÑģ'] +['Ġje', 'żeli'] +['以ä¸ĭ', 'ãģ®'] +['å°ı', 'ãģķ'] +['å°ıãģķ', 'ãģª'] +['олог', 'ии'] +['Ġоб', 'ÑģлÑĥж'] +['ĠобÑģлÑĥж', 'ива'] +['Ùĥت', 'ابة'] +['Ġê´Ģ', 'ìĭ¬'] +['×¢', 'ש×Ļר'] +['Ġaras', 'ındaki'] +['ĠÑĢай', 'она'] +['ÙĪØ§', 'جب'] +['Ġ×ij×Ĺ×Ļ', '×Ļ'] +['íķ´', '주'] +['Ġg', 'óc'] +['ай', 'л'] +['ĠT', 'ình'] +['æļ®', 'ãĤī'] +['æļ®ãĤī', 'ãģĹ'] +['æĻĤ', 'ãģ«ãģ¯'] +['ĠгоÑĢод', 'е'] +['Ġ׼×IJ', '×Ļ׾'] +['Ġ׼×IJ×Ļ׾', '×ķ'] +['ĠC', 'á»Ļng'] +['ãģ©ãģĨ', 'ãģĹãģ¦ãĤĤ'] +['×Ĺ', '×ķ×£'] +['تØŃ', 'رÙĥ'] +['ĠÑģлов', 'ам'] +['à¸Īะ', 'à¸Ĭà¹Īวย'] +['ĠاÙĦÙħست', 'ÙĤبÙĦ'] +['ÙĤ', 'ض'] +['ÙĤض', 'ÙĬ'] +['×ijס', '×ķפ'] +['×ijס×ķפ', '×ķ'] +['iÄĻ', 'Äĩ'] +['ĠY', 'ıl'] +['Ø´', 'ÙĬØ®'] +['à¸Ħุà¸ĵ', 'à¸Īะ'] +['ש×ŀ', '×ķת'] +['Ġت', 'عرض'] +['Ġanál', 'ise'] +['ĠÑģоб', 'иÑĢа'] +['à¹Ģà¸ŀ', 'à¸Ĭ'] +['à¹Ģà¸ŀà¸Ĭ', 'ร'] +['Ġв', 'ели'] +['Ġвели', 'к'] +['สั', 'à¹īà¸Ļ'] +['Ġpop', 'ulação'] +['รà¹Īวม', 'à¸ģัà¸Ļ'] +['×Ĺ', '×ŀ'] +['×Ĺ×ŀ', '×Ļש×Ļ'] +['ס', '×Ļס'] +['åĨħ', 'ãģ§'] +['Ġsob', 'Äħ'] +['ĠY', 'ay'] +['ĠYay', 'ın'] +['ãĥ¡', 'ãĥĭãĥ¥ãĥ¼'] +['ĠпÑĢедоÑģÑĤав', 'лÑı'] +['ãģł', 'ã썿ĢĿãģĨ'] +['Ġê³ł', 'ê°Ŀ'] +['Ġод', 'ним'] +['à¹ĥà¸Ļ', 'à¹Ģรืà¹Īà¸Ńà¸ĩ'] +['Ġs', 'á»ķ'] +['ĠÐĹ', 'деÑģÑĮ'] +['Ġизмен', 'ениÑı'] +['ĠìĿ¼', 'ìĿĦ'] +['ãģªãģ®', 'ãģł'] +['клад', 'Ñĭва'] +['ÑĢ', 'ма'] +['Ġ×ķ×ij', '׼׾'] +['تأ', 'ÙħÙĬÙĨ'] +['ĠпÑĢи', 'ÑıÑĤ'] +['ĠпÑĢиÑıÑĤ', 'н'] +['Ùħ', 'Ùħار'] +['ÙħÙħار', 'سة'] +['ãģ¨ãģª', 'ãģ£ãģ¦'] +['Ġج', 'ÙħÙĬÙĦ'] +['Ġì§', 'Ī'] +['Ġì§Ī', '문'] +['Ġquest', 'ão'] +['i', 'é'] +['ié', 'ndo'] +['หà¹īà¸Ńà¸ĩ', 'à¸ŀัà¸ģ'] +['ãĥij', 'ãĥ¼ãĥĪ'] +['ÑĤвеÑĢж', 'да'] +['н', 'Ñģкой'] +['з', 'ал'] +['มุ', 'à¹Īà¸ĩ'] +['á»', 'Ĭ'] +['Ġ×Ķ×IJ×Ĺר', '×ķ׳×Ķ'] +['ĠTh', 'ư'] +['주', '민'] +['ĠاÙĦع', 'ب'] +['év', 'én'] +['évén', 'ement'] +['ÙĤÙĪ', 'اعد'] +['د', 'Ùı'] +['ĠìķĬ', 'ìĬµëĭĪëĭ¤'] +['Ġë³´', '기'] +['Ġyapıl', 'ması'] +['à¹Ģร', 'าà¸ģ'] +['à¹Ģราà¸ģ', 'à¹ĩ'] +['ØŃ', 'ذر'] +['ÙĤ', 'صر'] +['ãģ¦ãģĹãģ¾', 'ãģĦãģ¾ãģĹãģŁ'] +['Ġà¹Ģà¸Ľà¹ĩà¸Ļ', 'à¸ķà¹īà¸Ļ'] +['ãģ¨', 'ãģ«'] +['ãģ¨ãģ«', 'ãģĭ'] +['ãģ¨ãģ«ãģĭ', 'ãģı'] +['н', 'ÑĨе'] +['зв', 'Ñĥк'] +['ãģĹãĤĪãģĨ', 'ãģ¨'] +['ĠاÙĦصØŃ', 'ÙĬØ©'] +['Ġש×Ķ', '×Ļ×ķ'] +['ĠDi', 'ÄŁer'] +['ÙĤÙĦ', 'ÙĤ'] +['ãĤ¸ãĥ£', 'ãĥ³'] +['Ġr', 'á»Ŀi'] +['Ġл', 'еÑĩ'] +['ĠлеÑĩ', 'ениÑı'] +['تب', 'اد'] +['تباد', 'ÙĦ'] +['צ', 'פ×Ķ'] +['à¸Ħวาม', 'à¹Ģหà¹ĩà¸Ļ'] +['ĠØ´', 'ب'] +['Ġشب', 'ÙĥØ©'] +['ר', '×Ļ×§'] +['Ùħ', 'عد'] +['Ùħعد', 'ات'] +['dıģ', 'ında'] +['Ġ×ijש', '׳×Ļ×Ŀ'] +['Ġ×Ķ', '×Ļשר×IJ׾'] +['Ġ×Ķ×Ļשר×IJ׾', '×Ļת'] +['Ġsı', 'nav'] +['׳צ', '×Ļ×Ĵ'] +['วัà¸ķ', 'à¸ĸุ'] +['ĠاÙĦبر', 'ÙĦÙħ'] +['ĠاÙĦبرÙĦÙħ', 'اÙĨ'] +['t', 'ivitÃł'] +['ãĤĵãģł', 'ãĤįãģĨ'] +['×§×Ļ', '×Ļ×ŀ'] +['ÙĦÙĬ', 'Ùĥ'] +['ĠÄij', 'ò'] +['ĠÄijò', 'i'] +['ĠÐĺн', 'ÑĤеÑĢ'] +['ĠÐĺнÑĤеÑĢ', 'неÑĤ'] +['ãģ«ãģ¨ãģ£ãģ¦', 'ãģ¯'] +['ãģ£', 'ãģĵ'] +['×§', '×ķס'] +['ست', 'ØŃÙĤ'] +['æķĻ', 'ãģĪãģ¦'] +['ãĥĢ', 'ãĥ¡'] +['ĠÙħÙĨ', 'زÙĦ'] +['à¹Ģà¸ĭ', 'à¹ĩà¸Ļ'] +['使', 'ãģĪãĤĭ'] +['è¦ĭ', 'ç©į'] +['è¦ĭç©į', 'ãĤĤãĤĬ'] +['Ø£', 'Ùģ'] +['Ø£Ùģ', 'Ùĥار'] +['Ġиг', 'ÑĢов'] +['ĠигÑĢов', 'Ñĭе'] +['Ġm', 'ÄĻż'] +['ĠmÄĻż', 'czy'] +['ĠmÄĻżczy', 'zn'] +['ĠاÙĦØŃ', 'ÙĤÙĬÙĤÙĬ'] +['ع', 'بر'] +['׼×ķ׾', '׳×ķ'] +['íĿ', '¥'] +['×ŀ×IJ', '×ķ×Ĺר'] +['خت', 'ص'] +['ãĥŀ', 'ãĥŀ'] +['Ġ×IJ×Ĺ', '×ķ×ĸ'] +['í', 'ĮĢ'] +['Ġr', 'á»iji'] +['Ġв', 'ÑĤоÑĢ'] +['ĠвÑĤоÑĢ', 'ой'] +['Ġl', 'ẫn'] +['пÑĢ', 'ом'] +['пÑĢом', 'ÑĭÑĪ'] +['пÑĢомÑĭÑĪ', 'лен'] +['пÑĢомÑĭÑĪлен', 'н'] +['ĠоÑĤноÑĪ', 'ениÑı'] +['Ġs', 'ứ'] +['Ġм', 'обилÑĮ'] +['ĠмобилÑĮ', 'н'] +['ĠÑįÑĤ', 'омÑĥ'] +['Ġt', 'ạp'] +['ĠìĤ¬', 'ê±´'] +['ĠìķĮ', '볤'] +['Ùĥ', 'Ùı'] +['ÙĥÙı', 'ÙħÙĴ'] +['Ġ×§', '×ķר×Ķ'] +['ĠÑĦ', 'иÑĢ'] +['ĠÑĦиÑĢ', 'м'] +['Ġsık', 'ıntı'] +['׳', '׼'] +['׳׼', '×ķף'] +['ÙĪÙĦÙĪØ¬', 'ÙĬ'] +['ØŃ', 'اÙĨ'] +['Ġlo', 'ạn'] +['Ġ×IJ׾', '×£'] +['Ġm', 'ắn'] +['abh', 'äng'] +['abhäng', 'ig'] +['ĠÑĥÑĢов', 'нÑı'] +['Ġ׾×ij×ĵ', '×ķ×§'] +['ÙĬ', 'ÙħÙĨ'] +['lay', 'ın'] +['Ġh', 'ải'] +['Ġзав', 'од'] +['ĠìķĦ', '주'] +['สà¸ĸ', 'า'] +['สà¸ĸา', 'à¸ļัà¸Ļ'] +['Ġgüven', 'lik'] +['à¹Ģà¸Ķ', 'à¹Īà¸Ļ'] +['×ij×ĵ', '×§'] +['Ġë', 'Ī'] +['ĠëĪ', 'Ħ'] +['ĠëĪĦ', '구'] +['éĩįè¦ģ', 'ãģª'] +['รà¸Ńà¸ĩ', 'รัà¸ļ'] +['sch', 'lie'] +['schlie', 'ÃŁen'] +['Ġìĸ', '¼'] +['Ġìĸ¼', 'ë§Ī'] +['Ġìĸ¼ë§Ī', 'ëĤĺ'] +['ÑĤи', 'ки'] +['íķľëĭ¤', 'ê³ł'] +['ãģłãģ£ãģŁ', 'ãĤī'] +['Ġ×Ķ', '×Ļ×ĺ×ij'] +['ãģªãģijãĤĮãģ°', 'ãģªãĤīãģªãģĦ'] +['â', 'Ì'] +['âÌ', '£'] +['Ġph', 'ạt'] +['ak', 'Ä±ÅŁ'] +['ãģ¦ãģĹãģ¾', 'ãģĦãģ¾ãģĻ'] +['à¹Ģà¸ĭ', 'à¹ĩ'] +['ĠС', 'егоднÑı'] +['Ġinsan', 'ların'] +['Ġdévelop', 'pe'] +['ת', 'פר'] +['תפר', '×Ļ×ĺ'] +['اÙĨت', 'شار'] +['ê°', 'ij'] +['Fran', 'çois'] +['Ø£ÙĦ', 'ع'] +['Ø£ÙĦع', 'اب'] +['ãĤĴ', 'è¶ħ'] +['ãĤĴè¶ħ', 'ãģĪ'] +['Ġê°Ļ', 'ìĬµëĭĪëĭ¤'] +['ãĤ³', 'ãĥ¬'] +['ĠмеÑģÑı', 'ÑĨев'] +['íĮ', 'ħ'] +['ĠاÙĦج', 'اÙħعة'] +['ìĿ¸', 'íĦ°'] +['ìĿ¸íĦ°', 'ëĦ·'] +['×ĵר', '×ķש'] +['ĠÙĪØ£', 'شار'] +['ĠпÑĢав', 'ила'] +['ãģĿãģĵ', 'ãģ«'] +['×Ĺ', '×ŀ×ĵ'] +['à¹Ģหà¸ķุ', 'à¸ģารà¸ĵà¹Į'] +['Ġê²½', 'íĹĺ'] +['ãģ¶', 'ãĤĬ'] +['׾', 'ש'] +['׾ש', '×ķף'] +['à¹Ģ', 'à¸ĸ'] +['ĠDo', 'ÄŁu'] +['ĠиÑģполÑĮзов', 'ание'] +['Ġçoc', 'uÄŁu'] +['магазин', 'е'] +['ĠÄiji', 'á»ĥn'] +['Ġas', 'lı'] +['Ġaslı', 'nda'] +['Ġdoen', 'ça'] +['Ġس', 'اع'] +['Ġساع', 'ات'] +['ĠиÑģполÑĮзов', 'аниÑı'] +['ר', '×ķצ×Ļ×Ŀ'] +['ĠзнаÑĩ', 'иÑĤ'] +['ĠÑĢаÐ', '¼'] +['ĠÑĢам', 'каÑħ'] +['ê±°', '리'] +['Ġп', 'ÑĭÑĤа'] +['ãĥģ', 'ãĥ³'] +['Ġпо', 'Ñģк'] +['ĠпоÑģк', 'олÑĮ'] +['ĠпоÑģколÑĮ', 'кÑĥ'] +['Ø¥', 'بر'] +['إبر', 'اÙĩ'] +['إبراÙĩ', 'ÙĬÙħ'] +['ĠÑĤÑĢ', 'еÑħ'] +['ĠGen', 'ç'] +['س', 'ÙĪÙģ'] +['Ġve', 'ÃŃculo'] +['ĠNg', 'ân'] +['ĠоÑĩеÑĢ', 'едÑĮ'] +['à¸Ħร', 'ึà¹Īà¸ĩ'] +['×IJ', '×ij×Ļ'] +['à¸ķ', 'à¹īม'] +['ãĤĴè¡Į', 'ãģĦ'] +['ĠاÙĦساب', 'ÙĤØ©'] +['на', 'ÑĨи'] +['наÑĨи', 'она'] +['наÑĨиона', 'лÑĮн'] +['Ġgest', 'ión'] +['ت', 'ÙĤد'] +['ĠاÙĦبÙĬ', 'اÙĨ'] +['ĠاÙĦبÙĬاÙĨ', 'ات'] +['ĠاÙĦ', 'اÙĨتخاب'] +['ĠاÙĦاÙĨتخاب', 'ات'] +['à¹Ģà¸Ĭ', 'à¹Īา'] +['×ĵ', '×IJ×Ĵ'] +['Ġ׾×Ĵ', '×ŀר×Ļ'] +['Ġت', 'ØŃتاج'] +['Ġth', 'ôn'] +['à¸ķ', 'à¹īà¸Ńà¸Ļ'] +['à¸ķà¹īà¸Ńà¸Ļ', 'รัà¸ļ'] +['女', 'ãģ®'] +['女ãģ®', 'åŃIJ'] +['Ġth', 'ợ'] +['Ø·', 'ØŃÙĨ'] +['ารà¹Į', 'à¸Ķ'] +['ת', '×ŀ×Ļ×ĵ'] +['ĠÑģам', 'Ñĭм'] +['Ġìĭľ', 'íĸī'] +['Ø¥', 'صد'] +['إصد', 'ار'] +['ĠNgh', 'á»ĩ'] +['ìķ', 'ķ'] +['س', 'ئ'] +['سئ', 'ÙĦ'] +['à¸Ń', 'าร'] +['à¸Ńาร', 'ม'] +['à¸Ńารม', 'à¸ĵà¹Į'] +['à¹ģ', 'ฮ'] +['׳×ĺ', '׾'] +['Ġì¢ĭ', 'ìķĦ'] +['×ķ׾', '׾'] +['Ġ×ij', '×Ľ×ª×ij'] +['ãĤ«', 'ãĥ©'] +['צע', '×Ļר×Ļ×Ŀ'] +['تعب', 'ÙĬر'] +['Ġ×ŀ', 'קר×Ķ'] +['ĠÑĦак', 'ÑĤоÑĢ'] +['Ġت', 'ÙħاÙħ'] +['ĠتÙħاÙħ', 'ا'] +['ëį', 'ķ'] +['Ġv', 'ưá»Ŀ'] +['Ġvưá»Ŀ', 'n'] +['Ġd', 'Ä±ÅŁÄ±'] +['ãģĦ', 'ãģ¡'] +['Ġ׾ק', '׳×ķת'] +['ĠاÙĦع', 'ÙĦاÙĤات'] +['п', 'Ñĥб'] +['пÑĥб', 'ли'] +['Ø¥', 'ÙĬÙħ'] +['Ø¥ÙĬÙħ', 'اÙĨ'] +['à¸Ńำ', 'à¸Ļา'] +['à¸Ńำà¸Ļา', 'à¸Ī'] +['åIJ«', 'ãģ¾ãĤĮ'] +['ãĤĭ', 'ãģŁãĤģãģ«'] +['ס', '×Ĵ'] +['ס×Ĵ', '׳×ķף'] +['تØŃ', 'دÙĬ'] +['Ġaup', 'rès'] +['ĠاÙĦج', 'Ùĩا'] +['ĠاÙĦجÙĩا', 'ز'] +['Ġ×ŀ', 'ת×Ĺת'] +['ен', 'нÑĥÑİ'] +['Ġз', 'им'] +['à¸ģา', 'à¹ģà¸Ł'] +['Ġ×ijת', '×ķר'] +['Ġngh', 'è'] +['Ġnghè', 'o'] +['ĠÐĽ', 'Ñİ'] +['ĠÐĽÑİ', 'б'] +['תק', 'צ×Ļ×ij'] +['×ŀ×¢', 'ש×Ķ'] +['ĠاÙĦبÙĬ', 'ت'] +['צ', '×Ļפ'] +['ĠобÑıз', 'ан'] +['ĠM', 'á»Ĺi'] +['ĠТ', 'ÑĥÑĢ'] +['ĠÙĪØ¨', 'اÙĦت'] +['ĠÙĪØ¨Ø§ÙĦت', 'اÙĦÙĬ'] +['Ġdéc', 'ision'] +['Ġب', 'د'] +['Ġبد', 'أت'] +['Ġc', 'ục'] +['Ġb', 'ask'] +['Ġbask', 'ı'] +['Ġhat', 'ırl'] +['Ġhatırl', 'a'] +['å°ı', 'ãģķãģĦ'] +['Ġgerçek', 'ten'] +['à¸ľ', 'ัà¸ģ'] +['åı¯èĥ½', 'ãģª'] +['×ŀ×IJ', 'ס'] +['Ġcr', 'ÃŃtica'] +['ĠìĿĺ', 'ìĽIJ'] +['عÙĤ', 'ÙĪØ¯'] +['×ĺ', '׼׳'] +['×ĺ׼׳', '×ķ׾×ķ×Ĵ×Ļ×Ķ'] +['è¨Ģ', 'ãģĪãģ°'] +['ĠÙĤ', 'ÙĨا'] +['ĠÙĤÙĨا', 'Ø©'] +['ĠìĿ´ê²ĥ', 'ìĿĢ'] +['ت', 'صر'] +['à¸Ł', 'ัà¸Ļ'] +['ĠÑĢе', 'ÑĨеп'] +['ĠÑĢеÑĨеп', 'ÑĤ'] +['ĠبÙĨ', 'Ù쨳'] +['ÑĢо', 'ÑĪ'] +['ĠмаÑĢ', 'ÑĤа'] +['Ġson', 'ras'] +['Ġsonras', 'ı'] +['×ķ×ij', 'ש'] +['ãĥª', 'ãĤ¹ãĤ¯'] +['ĠFranç', 'ais'] +['á»', 'ļ'] +['ê°', 'Ķ'] +['Ġ×Ķ×ijר', '×Ļת'] +['פ', '×Ļצ'] +['פ×Ļצ', '×ķ×Ļ'] +['ĠÙĦÙħا', 'ذا'] +['ĠÐļи', 'ев'] +['ĠÑģ', 'мÑĭÑģл'] +['ê¸Ī', 'ìľµ'] +['ãĤ·ãĥ£', 'ãĥ«'] +['ãĥ©', 'ãĤ¤ãĥĪ'] +['ìĽ', 'ĥ'] +['×ŀ', '×Ĺר'] +['ãĨ', 'į'] +['Ġkullan', 'ım'] +['Ġ×IJצ׾', '׳×ķ'] +['Ġt', 'Ãłn'] +['ãĥı', 'ãĥ¼'] +['ãģ¨', 'ãģ¨ãĤĤ'] +['ãģ¨ãģ¨ãĤĤ', 'ãģ«'] +['ÑĢ', 'ег'] +['ÑĢег', 'и'] +['ÑĢеги', 'он'] +['ãģªãģı', 'ãģªãĤĭ'] +['Ġch', 'ảy'] +['Ġج', 'ÙĩØ©'] +['ÅĦsk', 'iej'] +['à¸Ńี', 'à¹Ģม'] +['à¸Ńีà¹Ģม', 'ล'] +['ãģį', 'ãģ£ãģ¨'] +['ĠìĺĪ', 'ìĤ°'] +['Ġkit', 'abı'] +['Ġedu', 'cação'] +['Ġbul', 'uÅŁ'] +['олог', 'иÑı'] +['Ġкон', 'кÑĢ'] +['ĠконкÑĢ', 'еÑĤ'] +['×Ĵ', '×Ļר'] +['ĠпÑĢед', 'лаг'] +['ĠпÑĢедлаг', 'аеÑĤ'] +['ĠY', 'ên'] +['Ġíķľ', 'ë²Ī'] +['Ġ×ŀ', 'ר׼×ĸ×Ļ'] +['à¹Ģà¸Ľà¸´à¸Ķ', 'à¹Ģà¸ľà¸¢'] +['ÑĤвеÑĢ', 'д'] +['ĠH', 'á»ĩ'] +['ĠÐĵ', 'ÑĢ'] +['à¸Ŀ', 'à¹īา'] +['×Ķ', 'שק'] +['×Ķשק', '×¢×Ķ'] +['Ġна', 'Ñĥк'] +['ìłIJ', 'ìĿĦ'] +['Ġн', 'елÑĮ'] +['ĠнелÑĮ', 'з'] +['ĠнелÑĮз', 'Ñı'] +['г', 'ин'] +['ĠB', 'öl'] +['ĠBöl', 'ge'] +['Ġв', 'ла'] +['Ġвла', 'ÑģÑĤи'] +['à¹Ģà¸Ļ', 'à¹ĩ'] +['à¹Ģà¸Ļà¹ĩ', 'à¸ķ'] +['ê³', '¨'] +['Ġö', 'ld'] +['Ġöld', 'ür'] +['׼׳', '×¢'] +['ĠاÙĦÙĩ', 'ÙĬئة'] +['ت', 'ارÙĬØ®'] +['ĠÐij', 'ÑĢ'] +['ĠÑģ', 'мож'] +['ĠÑģмож', 'еÑĤе'] +['ĠL', 'úc'] +['à¹Ħà¸Ľ', 'à¸ĸึà¸ĩ'] +['ĠBakan', 'ı'] +['Ġerklä', 'rt'] +['ĠÐIJ', 'на'] +['Ġsc', 'ène'] +['åķı', 'ãģĦ'] +['åķıãģĦ', 'åIJĪãĤıãģĽ'] +['ÙħÙĩ', 'ÙĨد'] +['ÙħÙĩÙĨد', 'س'] +['Ġн', 'азвание'] +['ив', 'аниÑı'] +['ãĤĴ', 'å¤īãģĪ'] +['ä»ĺãģį', 'åIJĪ'] +['ãĥij', 'ãĤ½'] +['ãĥijãĤ½', 'ãĤ³ãĥ³'] +['æĺİ', 'ãĤī'] +['æĺİãĤī', 'ãģĭ'] +['à¹Ģà¸Ńà¸ģ', 'สาร'] +['à¹Ģà¸ģิà¸Ļ', 'à¹Ħà¸Ľ'] +['л', 'еп'] +['ãģĹãģŁ', 'ãĤĤãģ®'] +['ĠC', 'âm'] +['ĠCâm', 'ara'] +['×§×ķ׾', '׳×ķ×¢'] +['Ġ×ij×Ĵ', '×Ļף'] +['Ġoc', 'zy'] +['Ġoczy', 'wiÅĽcie'] +['att', 'ivitÃł'] +['ãĥĵ', 'ãĥ¥ãĥ¼'] +['Ġeduc', 'ación'] +['İ', 'YE'] +['ê¹Į', 'ìļĶ'] +['ãĤ¨', 'ãĥªãĤ¢'] +['н', 'еÑģÑĤи'] +['Ġm', 'óg'] +['Ġmóg', 'ÅĤ'] +['Ġ×§×ĺ', '׳×Ļ×Ŀ'] +['ĠPr', 'ä'] +['Ġ×ľ×¢', '×ij×ķר'] +['بÙĨ', 'Ùī'] +['з', 'ол'] +['зол', 'оÑĤ'] +['Ġwn', 'ÄĻtr'] +['ĠwnÄĻtr', 'z'] +['Ġconstr', 'ução'] +['รัà¸ļ', 'รà¸Ńà¸ĩ'] +['س', 'جÙĨ'] +['Ġ×§', '×ķ׳'] +['ס', '×Ļפ×ķר'] +['ĠÙħ', 'دÙī'] +['رض', 'Ùī'] +['п', 'лав'] +['ï¼', '¥'] +['Ġil', 'a'] +['Ġila', 'ç'] +['ãĤĭ', 'ãģ¹ãģį'] +['ĠÙħ', 'ÙĪÙĤÙģ'] +['à¸ģร', 'ุ'] +['à¸ģรุ', 'à¸ĵา'] +['chodzÄħ', 'c'] +['ĠÑĤÑĭ', 'Ñģ'] +['Ðķ', 'вÑĢо'] +['ĠÙĬ', 'ØŃدث'] +['ãĥ¡', 'ãĤ¤ãĥ³'] +['ĠاÙĦص', 'ØŃÙĬ'] +['ĠÐĶ', 'ан'] +['دع', 'اء'] +['ãĤ´', 'ãĥ¼ãĥ«'] +['ש', '×ł×ª×Ļ'] +['×©×ł×ª×Ļ', '×Ļ×Ŀ'] +['à¸Ķà¹īวย', 'à¸ģัà¸Ļ'] +['Ġol', 'acaģı'] +['Ġ×ij', '×ŀ×Ĺ×Ļר'] +['×Ķ', '×§'] +['×Ķ×§', '×ŀת'] +['ãĥ¢', 'ãĥİ'] +['ĠçalÄ±ÅŁ', 'tı'] +['Ġjó', 'venes'] +['ãģĦãģı', 'ãĤī'] +['ĠÙħ', 'عدÙĦ'] +['ĠC', 'Å©ng'] +['ĠSeg', 'ún'] +['Ġdönem', 'de'] +['Ġ׾', '×Ļ×ĵ×Ļ'] +['ãģį', 'ãģ¡'] +['ãģįãģ¡', 'ãĤĵ'] +['ãģįãģ¡ãĤĵ', 'ãģ¨'] +['Ù쨱', 'ÙĨس'] +['Ù쨱ÙĨس', 'ا'] +['åIJij', 'ãģį'] +['Ġcamp', 'aña'] +['ĠÑģам', 'оÑģÑĤоÑı'] +['ĠÑģамоÑģÑĤоÑı', 'ÑĤелÑĮно'] +['á»', 'Ģ'] +['ÙĤ', 'ÙĪØ§'] +['س', 'ÙĦاØŃ'] +['à¸ģระ', 'à¹ģ'] +['à¸ģระà¹ģ', 'ส'] +['ĠполÑĮз', 'Ñĥ'] +['n', 'qu'] +['nqu', 'ête'] +['รà¹Īวม', 'à¸ģัà¸ļ'] +['ëĬIJ', 'ëĥIJ'] +['à¸Ĺีม', 'à¸Ĭาà¸ķิ'] +['Ġyıll', 'ık'] +['ìĬ', '¬'] +['ĠØ£', 'صØŃاب'] +['ill', 'é'] +['Ġdó', 'la'] +['Ġdóla', 'res'] +['Ġк', 'ож'] +['Ġкож', 'и'] +['ล', 'à¹īà¸Ń'] +['à¹Ģรีย', 'à¸ļร'] +['à¹Ģรียà¸ļร', 'à¹īà¸Ńย'] +['à¹Ģà¸ŀ', 'ิ'] +['à¹Ģà¸ŀิ', 'à¹Īà¸ĩ'] +['ÑĢиÑĤоÑĢ', 'и'] +['Ġí', 'ijľ'] +['Ġíijľ', 'íĺĦ'] +['ĠпеÑĢ', 'ев'] +['ĠпеÑĢев', 'од'] +['פ×Ĵ', '×Ļ×¢×Ķ'] +['ĠdeÄŁerlendir', 'me'] +['Ùģ', 'ائ'] +['ĠвÑĭ', 'год'] +['ınız', 'ı'] +['×ķ׼', '×Ļ×Ĺ'] +['ĠдоÑģÑĤ', 'иг'] +['Ġng', 'Ãłn'] +['æĢĿ', 'ãģ£ãģŁ'] +['ĠÐķ', 'ÑģÑĤÑĮ'] +['ĠاÙĦر', 'غÙħ'] +['ĠzwiÄħz', 'ane'] +['رب', 'Ø·'] +['à¸Ļ', 'ึà¸ĩ'] +['Ġ׾×Ĺ', '×ķ×§'] +['Ġszczeg', 'óln'] +['Ġszczególn', 'ie'] +['Ġبا', 'ستخداÙħ'] +['ĠfÃŃs', 'ico'] +['×¢', 'ס'] +['עס', '×ķ×§'] +['سÙĦ', 'ÙĪÙĥ'] +['Ġا', 'ØŃد'] +['Ñĩ', 'ÑijÑĤ'] +['×ĸ׼', '×Ķ'] +['Ġl', 'á»ĩnh'] +['ĠÙĪ', 'ØŃت'] +['ĠÙĪØŃØª', 'Ùī'] +['à¸Ħวาม', 'สามารà¸ĸ'] +['à¸Ńยูà¹Ī', 'à¹ģลà¹īว'] +['à¸ģาร', 'à¹Ģà¸Ķิà¸Ļà¸Ĺาà¸ĩ'] +['تخ', 'ذ'] +['צ×Ļ', '×ķ×ĵ'] +['ĠاÙĦØ£', 'س'] +['ĠاÙĦأس', 'ÙĩÙħ'] +['Ġt', 'á»ĩ'] +['ãģ£ãģ¦', 'ãģĦãģ¦'] +['สร', 'ุ'] +['สรุ', 'à¸Ľ'] +['Ġком', 'ÑĦ'] +['ĠкомÑĦ', 'оÑĢÑĤ'] +['ìĺ¤', 'ëĬĶ'] +['ĠÑĢаз', 'в'] +['ĠÑĢазв', 'ива'] +['л', 'анд'] +['h', 'änge'] +['ĠبÙĨ', 'سبة'] +['à¹Ģà¸Ĥ', 'ียว'] +['עצ', '×Ŀ'] +['Ġ׾', '×ľ×Ľ×ª'] +['Ñģо', 'ÑĨиалÑĮн'] +['Ġëĭ¤ìĿĮ', 'ê³¼'] +['Ġרש', '×ķ×ŀ'] +['×ŀר', '×Ĺ×ij'] +['س', 'ÙĤØ·'] +['Ġalan', 'ı'] +['ĠÄij', 'á»ĩ'] +['é£Łãģ¹', 'ãĤĭ'] +['à¸Ķ', 'ึà¸ĩ'] +['Ġgegen', 'über'] +['ĠبÙĩ', 'ذÙĩ'] +['à¸ĸืà¸Ń', 'à¹Ģà¸Ľà¹ĩà¸Ļ'] +['ëķ', 'ħ'] +['à¸Ħà¸Ļ', 'à¹Ħà¸Ĺย'] +['ãĤ¢', 'ãĤ¦'] +['ãĤ¢ãĤ¦', 'ãĥĪ'] +['ศ', 'ัà¸ģ'] +['ศัà¸ģ', 'à¸Ķิ'] +['ศัà¸ģà¸Ķิ', 'à¹Į'] +['ÙĤÙĪ', 'اÙĨ'] +['ÙĤÙĪØ§ÙĨ', 'ÙĬÙĨ'] +['Ġhá»Ļ', 'p'] +['ãģªãģıãģª', 'ãģ£ãģ¦'] +['Ġ×IJ', '×ŀ׳'] +['Ġ×IJ×ŀ׳', '×Ŀ'] +['à¹Ģà¸ķ', 'ืà¸Ńà¸Ļ'] +['ĠзавиÑģ', 'им'] +['ĠзавиÑģим', 'оÑģÑĤи'] +['ת', '×Ļ×IJ'] +['ת×Ļ×IJ', '×ķר'] +['å§ĭãĤģ', 'ãģŁ'] +['Ġng', 'á»į'] +['Ġngá»į', 't'] +['íĴ', 'į'] +['ê³¼', 'ìŀ¥'] +['Ġb', 'ại'] +['ãģ§ãģį', 'ãģ¦'] +['Ġcomeç', 'ar'] +['à¸Ľà¸£', 'าà¸ģ'] +['à¸Ľà¸£à¸²à¸ģ', 'à¸ı'] +['Ġгод', 'Ñĭ'] +['м', 'еÑģ'] +['ĠاÙĦÙħست', 'ÙĪÙī'] +['ĠÑģам', 'Ñĭе'] +['л', 'леÑĢ'] +['ãģ£ãģ¦ãģĹãģ¾', 'ãģĦãģ¾ãģĻ'] +['ãģ¨ãģ®', 'ãģĵãģ¨'] +['bi', 'ó'] +['à¸ģล', 'à¹Īà¸Ńà¸ĩ'] +['ĠاÙĦز', 'ÙĪØ¬'] +['ãģ«è¡Į', 'ãģ£ãģŁ'] +['à¸Ħà¹Ī', 'à¸Ńà¸Ļ'] +['à¸Ħà¹Īà¸Ńà¸Ļ', 'à¸Ĥà¹īาà¸ĩ'] +['ĠbaÄŁ', 'l'] +['ĠbaÄŁl', 'ant'] +['ĠbaÄŁlant', 'ı'] +['確', 'ãģĭ'] +['確ãģĭ', 'ãģ«'] +['ãĥľ', 'ãĥ¼ãĥ«'] +['çµĤ', 'ãĤıãĤĬ'] +['ש', '×ŀר'] +['à¸Ĺีà¹Ī', 'สามารà¸ĸ'] +['ÙĦ', 'زÙħ'] +['д', 'аеÑĤÑģÑı'] +['รัà¸ļ', 'à¸Ľà¸£à¸°'] +['รัà¸ļà¸Ľà¸£à¸°', 'à¸Ĺาà¸Ļ'] +['å¤ī', 'ãĤıãĤĬ'] +['ï¼', '¢'] +['ĠìĺĪìĪĺ', 'ëĭĺ'] +['ãĤĪãģĨ', 'ãģ¨'] +['มัà¸ģ', 'à¸Īะ'] +['ĠH', 'ương'] +['ÙĨ', 'Ù쨰'] +['×ŀ×ĵ', '×ĵ'] +['ĠìĿ¸', 'ìłķ'] +['Ñħод', 'иÑĤÑĮ'] +['ĠзавиÑģ', 'иÑĤ'] +['×ķ×ĵ', '×Ļ×¢'] +['ãģĵãģ¨ãģĮ', 'ãģĤãĤĬãģ¾ãģĻ'] +['ع', 'راÙĤ'] +['سط', 'ØŃ'] +['à¸ģำ', 'à¹Ħร'] +['ëĵ¤', 'ëıĦ'] +['×Ļצ', '×Ļר×Ķ'] +['ãģĨ', 'ãģĵãģ¨'] +['ÙĦا', 'ØŃÙĤ'] +['ãģĦ', 'ãĤĮãģ°'] +['ĠиÑģполÑĮз', 'ÑĥÑİÑĤ'] +['ĠB', 'ợi'] +['Ġשק׾', '×Ļ×Ŀ'] +['ÑĨи', 'кл'] +['ÐIJ', 'Ðŀ'] +['Ġ×ijש', '׳×Ķ'] +['ÙĨØ´', 'Ø·'] +['Ġש', '×Ļ׳×ķ×Ļ'] +['Ġש×Ļ׳×ķ×Ļ', '×Ļ×Ŀ'] +['Ġpobl', 'ación'] +['ĠH', 'ưng'] +['ระ', 'ว'] +['ระว', 'ัà¸ĩ'] +['رÙĬاض', 'Ø©'] +['ر', 'صد'] +['تÙĤ', 'ÙĦÙĬ'] +['تÙĤÙĦÙĬ', 'د'] +['Ġülk', 'em'] +['Ġülkem', 'iz'] +['à¸Ĭ', 'ะ'] +['ãĤ¯ãĥª', 'ãĥ¼ãĥł'] +['èģŀ', 'ãģĦãģŁ'] +['Ġwa', 'ż'] +['Ġważ', 'ne'] +['ê±°', 'ëĵł'] +['ê±°ëĵł', 'ìļĶ'] +['×ŀ×IJ', '×ij×§'] +['×Ĺ×ĵ', 'ש×ķת'] +['ĠW', 'roc'] +['ĠWroc', 'ÅĤaw'] +['ĠKü', 'ltür'] +['s', 'ist'] +['sist', 'ência'] +['×¢×ĸר', '×Ķ'] +['Ġg', 'ương'] +['รà¹īาà¸Ļ', 'à¸Ħà¹īา'] +['ĠÙĪØ£', 'ÙĪØ¶ØŃ'] +['ánd', 'ose'] +['ãĤ·', 'ãĥ¼ãĥ³'] +['×IJ׳', 'ר×Ĵ'] +['×IJ׳ר×Ĵ', '×Ļ×Ķ'] +['ãģªãģĦ', 'ãģ§ãģĻ'] +['Ġkh', 'á»§ng'] +['Ġ문', 'ìĦľ'] +['Ġ×ij', '×ĵ×ijר'] +['×ĵ', '×Ļ×ķ'] +['×ĵ×Ļ×ķ', '×ķ×Ĺ'] +['Ġré', 'gl'] +['ÙħÙĪ', 'اد'] +['об', 'оÑĢ'] +['обоÑĢ', 'оÑĤ'] +['Ġ×Ķ', '×ij׾'] +['Ġ×Ķ×ij׾', '×ķ×Ĵ'] +['ØŃ', 'اÙħ'] +['ĠاÙĦع', 'اص'] +['ĠاÙĦعاص', 'ÙħØ©'] +['пеÑĢ', 'аÑĤоÑĢ'] +['ت', 'Ø®ÙĦ'] +['تخÙĦ', 'ص'] +['ãģŁãģł', 'ãģĹ'] +['ت', 'سÙħ'] +['à¹Ĥรà¸ĩ', 'à¸ŀ'] +['à¹Ĥรà¸ĩà¸ŀ', 'ยา'] +['à¹Ĥรà¸ĩà¸ŀยา', 'à¸ļาล'] +['ĠY', 'ük'] +['ĠYük', 'sek'] +['Ġש', '׳×Ļת'] +['Ġש׳×Ļת', 'ף'] +['liÄŁ', 'e'] +['Ġפ', 'ת'] +['Ġפת', '×ķ×Ĺ'] +['Ġbe', 'ÄŁ'] +['ĠbeÄŁ', 'en'] +['Ġ×ŀ', '×ķר'] +['Ġ×ŀ×ķר', '׼×ij'] +['Ġرس', 'اÙĦØ©'] +['íĨµ', 'ìĭł'] +['Ġaval', 'ia'] +['Ġavalia', 'ções'] +['Ġman', 'h'] +['Ġmanh', 'ã'] +['Ġìķ', 'ŀ'] +['Ġìķŀ', 'ìľ¼ë¡ľ'] +['ÙĤ', 'تر'] +['ÙĤتر', 'ØŃ'] +['à¹Ģà¸ģ', 'ืà¸Ń'] +['à¹Ģà¸ģืà¸Ń', 'à¸ļ'] +['Ġpropos', 'é'] +['Ø£', 'Ùħا'] +['Ø£Ùħا', 'ÙĥÙĨ'] +['ĠÐŀ', 'Ðŀ'] +['ĠÐŀÐŀ', 'Ðŀ'] +['ÙħÙĤ', 'ار'] +['ÙħÙĤار', 'ÙĨØ©'] +['ëĦ', 'IJ'] +['ãģĦãģŁãģł', 'ãģı'] +['ÙĤ', 'ÙĬÙĦ'] +['Ġна', 'ÑĪиÑħ'] +['ãĤ«', 'ãĥĥãĥĹ'] +['×Ĺ׾', 'ת'] +['Ġëĭ¤', 'ë§Į'] +['à¸Ĺัà¹Īว', 'à¹Ĥลà¸ģ'] +['ãĥį', 'ãĤ¿'] +['ØŃس', 'اس'] +['ãģ«ãģª', 'ãĤĮ'] +['ج', 'ائ'] +['جائ', 'زة'] +['é', 'change'] +['é', 'conom'] +['économ', 'ie'] +['Т', 'Ðĺ'] +['סת', '׼׾'] +['à¸Ĺัà¹īà¸ĩ', 'สà¸Ńà¸ĩ'] +['ĠاÙĦØ®', 'اÙħ'] +['ĠاÙĦخاÙħ', 'س'] +['×§', '×ĺ×¢'] +['au', 'waż'] +['à¸ľà¸¹à¹ī', 'à¸Ĭาย'] +['à¹ģà¸Ľà¸¥', 'à¸ģ'] +['åIJĮæĻĤ', 'ãģ«'] +['зн', 'аниÑı'] +['ãģĦãģŁãģł', 'ãģįãģ¾ãģĹãģŁ'] +['Ġ×ŀ×ij', '׾×Ļ'] +['à¸Ĥà¸Ń', 'à¹ĥหà¹ī'] +['ĠاÙĦت', 'ربÙĬØ©'] +['Ġdécou', 'vert'] +['Ġżyc', 'iu'] +['apr', 'ès'] +['Ġy', 'ab'] +['Ġyab', 'anc'] +['Ġyabanc', 'ı'] +['ĠbaÅŁ', 'layan'] +['ìĹĪ', 'ëįĺ'] +['Ġhes', 'abı'] +['Ġë§Į', 'ìķ½'] +['ë§', 'Īëĭ¤'] +['ĠTh', 'ánh'] +['ãĥ´', 'ãĤ¡'] +['à¸Ľà¸£à¸±à¸ļ', 'à¸Ľà¸£'] +['à¸Ľà¸£à¸±à¸ļà¸Ľà¸£', 'ุà¸ĩ'] +['ĠM', 'ặc'] +['à¹Ģหà¸ķุ', 'à¸ľà¸¥'] +['ĠÐij', 'ез'] +['Ġcapac', 'itÃł'] +['ÅĤe', 'ÅĽ'] +['ĠпÑĢе', 'им'] +['ĠпÑĢеим', 'ÑĥÑīеÑģÑĤв'] +['ĠÅļ', 'wiÄĻt'] +['Ġpubli', 'é'] +['×ŀ×¢', 'צ×ij'] +['Ùħشار', 'Ùĥات'] +['à¸łà¸²', 'ษ'] +['à¸łà¸²à¸©', 'ี'] +['Ġdeux', 'ième'] +['ĠÙħØŃ', 'اÙ쨏'] +['ĠÙħØŃاÙ쨏', 'Ø©'] +['ĠSch', 'ön'] +['ï½', '¤'] +['Ġ×Ķ', '×ij×¢'] +['Ġ×Ķ×ij×¢', '×Ļ×Ķ'] +['ĠÙĪØ§ÙĦ', 'ÙĦÙĩ'] +['è¨Ģ', 'ãģ£ãģŁ'] +['à¸ķ', 'à¹īาà¸Ļ'] +['วร', 'รà¸ĵ'] +['à¸Ĺิ', 'ศ'] +['ĠbaÅŁ', 'ına'] +['Ġmog', 'ÄĻ'] +['ש', '×Ļפ×ķר'] +['ĠÙĪ', 'عد'] +['ĠÙĪØ¹Ø¯', 'Ùħ'] +['Ġhistó', 'rico'] +['Ġk', 'ısı'] +['ĠìĿ´', 'ê²Į'] +['ĠPol', 'ÃŃtica'] +['ĠÑģиÑĤÑĥ', 'аÑĨии'] +['ĠkoÅĦ', 'ca'] +['×ij×ĵ', '×Ļ×§×Ķ'] +['ĠاÙĦسÙĬ', 'ارات'] +['ãģªãĤī', 'ãģ°'] +['ãĤµ', 'ãĥ©'] +['ãĤĭãģĵãģ¨ãģĮãģ§ãģį', 'ãĤĭ'] +['Ġdecis', 'ão'] +['×ķ', '×ķ×ĵ'] +['lä', 'ss'] +['läss', 'ig'] +['Ġ׾', '×Ļשר×IJ׾'] +['ĠÙĬ', 'أتÙĬ'] +['ר', '×ķ×ĸ'] +['ö', 'ÄŁ'] +['Ã¶ÄŁ', 'ret'] +['Ã¶ÄŁret', 'im'] +['Ġд', 'ек'] +['Ġдек', 'аб'] +['Ġдекаб', 'ÑĢÑı'] +['Ġש', '×Ĺ×ķר'] +['ãģ¦ãģıãĤĮ', 'ãģŁ'] +['عب', 'ارة'] +['Ġélect', 'rique'] +['ĠاÙĦتÙĨ', 'ÙħÙĬØ©'] +['جر', 'Ùī'] +['ĠìĪĺ', 'íĸī'] +['à¸Ĺ', 'ู'] +['ĠÑĢе', 'алÑĮно'] +['Ñģп', 'оÑģоб'] +['à¸Ħล', 'à¹īาย'] +['Ġس', 'عÙĪØ¯'] +['ön', 'ü'] +['ĠÙģ', 'ÙħÙĨ'] +['تÙĥ', 'ÙĪ'] +['تÙĥÙĪ', 'ÙĬÙĨ'] +['ĠкаÑĩ', 'еÑģÑĤво'] +['ĠконÑĤ', 'ак'] +['ĠконÑĤак', 'ÑĤ'] +['Ġsöz', 'leÅŁme'] +['à¸Ń', 'à¹īาà¸ĩ'] +['Ġت', 'ÙĪÙģ'] +['ĠتÙĪÙģ', 'ÙĬر'] +['×Ķ×ĸ', '×ĵ'] +['×Ķ×ĸ×ĵ', '×ŀ׳×ķת'] +['ĠØ·ÙĪÙĬÙĦ', 'Ø©'] +['Ġtér', 'mino'] +['Ġ×IJ', '×Ļפ×Ķ'] +['ãĥĵ', 'ãĥ«'] +['ส', 'à¹Ĥม'] +['สà¹Ĥม', 'สร'] +['ĠاÙĦ', 'اث'] +['ĠاÙĦاث', 'ÙĨÙĬÙĨ'] +['ев', 'иÑĩ'] +['Ġopin', 'ión'] +['à¸Ľ', 'วà¸Ķ'] +['åı¤', 'ãģĦ'] +['ร', 'à¹Īา'] +['ĠB', 'iaÅĤ'] +['ĠÑģÑĤ', 'ал'] +['ĠÑģÑĤал', 'о'] +['ó', 'logo'] +['ĠìķĦ', 'ëĭĪëĭ¤'] +['Ġ×IJ', '×Ļת'] +['Ġ×IJ×Ļת', '×ķ'] +['à¹Ģหà¹ĩà¸Ļ', 'วà¹Īา'] +['à¸ļ', 'ารà¹Į'] +['çĦ', '¼'] +['çĦ¼', 'ãģį'] +['ĠìĿ´ìļ©', 'ìŀIJ'] +['ĠнекоÑĤоÑĢ', 'Ñĭе'] +['ks', 'z'] +['ksz', 'taÅĤ'] +['ksztaÅĤ', 'c'] +['ãĤŃãĥ£', 'ãĥĥãĤ·'] +['ãĤŃãĥ£ãĥĥãĤ·', 'ãĥ³ãĤ°'] +['Ġro', 'ÅĽ'] +['ĠroÅĽ', 'lin'] +['ÑĢаж', 'а'] +['×ij׳×Ļ', '×Ļ×Ķ'] +['à¸Ľà¸£', 'สิ'] +['à¸Ľà¸£à¸ªà¸´', 'à¸ķ'] +['Ġgörd', 'ü'] +['×ŀ׳×Ķ', '×Ļ×Ĵ'] +['å¤īãĤı', 'ãģ£ãģ¦'] +['Ġ×IJ', '×Ķ'] +['Ġ×IJ×Ķ', '×ijת×Ļ'] +['à¹Ģร', 'à¹Īà¸ĩ'] +['Ġön', 'ünde'] +['Ġê·¸', 'ëĥ¥'] +['пол', 'иÑĤ'] +['полиÑĤ', 'иÑĩеÑģк'] +['ãĥ¡', 'ãĥĩãĤ£'] +['ãĥ¡ãĥĩãĤ£', 'ãĤ¢'] +['ĠDet', 'ay'] +['ĠDetay', 'lı'] +['ĠاÙĦصÙģ', 'ØŃØ©'] +['à¸ģาร', 'à¹Ģà¸ĩิà¸Ļ'] +['Ġìµľ', 'ê·¼'] +['׼', 'ש׾'] +['ï¼', '©'] +['вÑĪ', 'его'] +['íķĺ', 'ìĭ¤'] +['ĠÐŃ', 'ÑĤ'] +['ĠÐŃÑĤ', 'оÑĤ'] +['ส', 'ื'] +['สื', 'à¸ļ'] +['Ġng', 'ừng'] +['ĠдокÑĥменÑĤ', 'ов'] +['дав', 'аÑĤÑĮ'] +['ĠاÙĦشخص', 'ÙĬØ©'] +['Ġצ', '×¢×Ļר'] +['در', 'Ùĥ'] +['س', 'ØŃب'] +['à¹Ħมà¹Ī', 'à¸Ħà¹Īà¸Ńย'] +['Ġ×Ķ×ŀ×§', '×ķ×ŀ×Ļ'] +['สัà¹Īà¸ĩ', 'à¸ĭืà¹īà¸Ń'] +['Ġê·¸ê²ĥ', 'ìĿĦ'] +['ãģĤãĤĭ', 'ãģĦ'] +['ãģĤãĤĭãģĦ', 'ãģ¯'] +['×IJ×ķ×ĺ', '×ķ×ij'] +['×IJ×ķ×ĺ×ķ×ij', '×ķס'] +['к', 'ÑĨион'] +['ĠÐľ', 'ожно'] +['ãģı', 'ãģł'] +['ãģıãģł', 'ãģķ'] +['ĠинÑĦоÑĢм', 'аÑĨиÑı'] +['ï»', 'Ł'] +['Ġìŀij', 'ìĹħ'] +['Ġ×Ļ', '×ķסף'] +['Ø¥', 'دارة'] +['ĠاÙĦØŃ', 'اج'] +['×ł×¡', '×Ļ×¢×Ķ'] +['из', 'аÑĨиÑı'] +['×IJ׾', '×ij'] +['×IJ׾×ij', '×ķ×Ŀ'] +['п', 'ед'] +['Ġ×§×ĺ', '׳×Ķ'] +['ĠÙĨÙ쨳', 'Ùĩا'] +['ĠMinist', 'ério'] +['Ġп', 'ен'] +['Ġпен', 'Ñģи'] +['ãĥIJ', 'ãĥ©ãĥ³ãĤ¹'] +['Ġ×Ķת', '×ķר×Ķ'] +['Ġt', 'ạm'] +['ĠìĹŃ', 'ìĭľ'] +['ï½', '¡'] +['Ġth', 'á»±'] +['Ġ', 'ısı'] +['ì»', '¨'] +['ãģĹãģ£ãģĭãĤĬ', 'ãģ¨'] +['Ġx', 'ưa'] +['Ġc', 'ặp'] +['×Ĺ', '×Ļ×ij×ķר'] +['วัà¸Ĵà¸Ļ', 'à¸ĺรรม'] +['st', 'är'] +['stär', 'ke'] +['ĠÑģам', 'Ñĭй'] +['p', 'isa'] +['pisa', 'Äĩ'] +['ĠoluÅŁ', 'an'] +['ĠاÙĦØ¥', 'ÙħاÙħ'] +['ĠcÄĥ', 'ng'] +['Ġgü', 'nl'] +['Ġgünl', 'ük'] +['Ġ׳ש', '×IJר'] +['Ġkhi', 'á»ĥn'] +['ç¶ļ', 'ãģijãĤĭ'] +['stit', 'ución'] +['Ġcapac', 'ité'] +['Ġj', 'aki'] +['Ġjaki', 'ÅĽ'] +['вÑĪ', 'иÑģ'] +['вÑĪиÑģ', 'ÑĮ'] +['פע×ķ׾', '×ķת'] +['ĠØŃ', 'ÙĬات'] +['ĠØŃÙĬات', 'Ùĩ'] +['Ġник', 'огда'] +['ÐĽ', 'Ь'] +['Ġ×Ķ×¢', '×ķ×ij'] +['Ġ×Ķ×¢×ķ×ij', '×ĵ×Ķ'] +['Ġch', 'Ãło'] +['หลาย', 'à¹Ĩ'] +['ĠÑı', 'н'] +['ĠÑıн', 'ваÑĢ'] +['ĠÑıнваÑĢ', 'Ñı'] +['à¸Īำà¹Ģà¸Ľà¹ĩà¸Ļ', 'à¸ķà¹īà¸Ńà¸ĩ'] +['Ġhö', 'her'] +['ãģķãĤĮãģ¦', 'ãģĦãģŁ'] +['สà¸ĩ', 'สั'] +['สà¸ĩสั', 'ย'] +['ĠاÙĦ', 'اس'] +['ĠاÙĦاس', 'ÙĦاÙħ'] +['ĠاÙĦØ´', 'Ùħس'] +['สà¸ĸาà¸Ļ', 'ี'] +['ãĤ¯ãĥ©', 'ãĤ¹'] +['à¸ŀร', 'ร'] +['à¸ŀรร', 'à¸Ħ'] +['p', 'õ'] +['põ', 'e'] +['Ġpor', 'ém'] +['à¸Ľà¸£à¸°', 'สà¸ĩ'] +['à¸Ľà¸£à¸°à¸ªà¸ĩ', 'à¸Ħà¹Į'] +['powied', 'zie'] +['powiedzie', 'Äĩ'] +['Ġмог', 'Ñĥ'] +['Ġж', 'ел'] +['Ġжел', 'ез'] +['ĠاÙĦØ«', 'ÙĤ'] +['ĠاÙĦØ«ÙĤ', 'اÙģÙĬ'] +['ĠпÑĢав', 'ило'] +['Ġgdy', 'ż'] +['פש', '×ķ×ĺ'] +['ÑĢабоÑĤ', 'ка'] +['ĠÙĥ', 'رة'] +['Ø´', 'دد'] +['Ùħار', 'Ùĥ'] +['Ùħ', 'ÙĥØ©'] +['Ġпод', 'пиÑģ'] +['×ĺ×ķ', '×ķ×Ĺ'] +['ĠÅĽ', 'c'] +['ĠÅĽc', 'ian'] +['Ġر', 'جاÙĦ'] +['Ġ×ª×ľ', '×ķ×Ļ'] +['и', 'ÑĪ'] +['иÑĪ', 'ÑĮ'] +['Ġmé', 'dec'] +['Ġmédec', 'in'] +['ëįĶ', 'ëĿ¼ëıĦ'] +['ĠÑĤеб', 'Ñı'] +['Ġ׾×Ķ', '×ķס×Ļ×£'] +['ãģĬ', '話'] +['Ġà¹ģà¸ķà¹Ī', 'à¸ģà¹ĩ'] +['د', 'اÙģ'] +['داÙģ', 'ع'] +['ĠC', 'ùng'] +['ãĥ»ãĥ»', 'ãĥ»ãĥ»'] +['ê¶', 'ģ'] +['Ġdeber', 'ÃŃa'] +['หà¸Ļà¹Īวย', 'à¸ĩาà¸Ļ'] +['Ġva', 'ÌĢ'] +['Ġעצ', '×ŀ'] +['Ġעצ×ŀ', '×Ŀ'] +['à¹Ģà¸Ĭืà¹Īà¸Ń', 'วà¹Īา'] +['שק', '×¢'] +['Ġ×Ķ', '׼×ķ׾'] +['Ġ×Ķ׼×ķ׾', '׾'] +['ни', 'бÑĥд'] +['нибÑĥд', 'ÑĮ'] +['ĠëĦĪ', 'íĿ¬'] +['Ġоб', 'ÑĢаÑī'] +['ĠобÑĢаÑī', 'а'] +['Ġ×¢×ij×ķ×ĵ', 'ת'] +['ĠاÙĦÙħÙĨت', 'خب'] +['ıy', 'ord'] +['ıyord', 'u'] +['ÙĪ', 'ذ'] +['×Ĺש', '×Ļ×ij×ķת'] +['Ġ×Ķ×¢', '×Ļ×§'] +['Ġ×Ķ×¢×Ļ×§', 'ר×Ļ'] +['ì¢', 'Į'] +['ยุ', 'à¹Ĥร'] +['ยุà¹Ĥร', 'à¸Ľ'] +['Ġа', 'пÑĢ'] +['ĠапÑĢ', 'елÑı'] +['sz', 'ed'] +['szed', 'ÅĤ'] +['д', 'он'] +['à¹Ģà¸ķิ', 'à¸ļ'] +['à¹Ģà¸ķิà¸ļ', 'à¹Ĥà¸ķ'] +['кол', 'о'] +['Ġkażde', 'j'] +['å¸', '°'] +['帰', 'ãĤĬ'] +['Ġмил', 'ли'] +['Ġмилли', 'он'] +['ç¾İåij³', 'ãģĹãģĦ'] +['ت', 'ÙĤار'] +['تÙĤار', 'ÙĬر'] +['ĠìĿ´', '루'] +['ĠìĿ´ë£¨', 'ìĸ´'] +['Ġsprzeda', 'ż'] +['×Ķ', '×ķצ×IJ×ķת'] +['ãĤ¢ãĤ¯', 'ãĤ»'] +['ãĤ¢ãĤ¯ãĤ»', 'ãĤ¹'] +['ר', '×ķ×¥'] +['ĠгоÑģÑĥдаÑĢÑģÑĤв', 'енн'] +['Ø£', 'ØŃÙĥ'] +['Ø£ØŃÙĥ', 'اÙħ'] +['ĠoluÅŁ', 'u'] +['ĠA', 'ç'] +['ĠAç', 'ık'] +['ãĤ¸', 'ãĥ¼'] +['ç´ł', 'æĻ´'] +['ç´łæĻ´', 'ãĤīãģĹãģĦ'] +['Ġ×ijש×ij', '×ķ×¢'] +['ب', 'ذ'] +['بذ', 'ÙĦ'] +['สา', 'à¹Ģหà¸ķุ'] +['Ġpoz', 'osta'] +['Ġpozosta', 'ÅĤ'] +['ØŃر', 'Ùħ'] +['Ġimport', 'ância'] +['leÅŁtir', 'me'] +['Ġд', 'ÑĢев'] +['Ġmó', 'vil'] +['ĠA', 'ynı'] +['Ġна', 'лог'] +['Ġналог', 'ов'] +['Ġ×Ĺ', '×Ļפ×Ķ'] +['ĠÑĦоÑĢм', 'Ñĥ'] +['à¸Ĺà¸Ķ', 'สà¸Ńà¸ļ'] +['ĠksiÄħż', 'ki'] +['Ġma', 'ÅĤe'] +['Ùħس', 'Ø£ÙĦ'] +['ÙħسأÙĦ', 'Ø©'] +['ï¼¾', 'ï¼¾'] +['ç', 'ãeste'] +['év', 'iter'] +['Ġкон', 'ÑģÑĤÑĢÑĥк'] +['ĠконÑģÑĤÑĢÑĥк', 'ÑĨи'] +['ï¾', 'ŀ'] +['Ġת×ķ׼', '׳'] +['ãĤ¹ãĥĪ', 'ãĥ¬ãĤ¹'] +['ĠاÙĦاÙĤتصاد', 'ÙĬ'] +['×ŀ×ĵ', '×Ļ'] +['Ġw', 'ÅĤad'] +['ĠwÅĤad', 'z'] +['Ø®', 'ÙĪÙģ'] +['ĠмаÑĤеÑĢиал', 'ов'] +['ãģ¨ãģ£ãģ¦', 'ãĤĤ'] +['Ġznaj', 'du'] +['Ġznajdu', 'jÄħ'] +['Ùģ', 'ئة'] +['ãģ©ãģ®', 'ãĤĪãģĨãģª'] +['æĬij', 'ãģĪ'] +['׳', '×Ĺ׾'] +['Ġdü', 'ny'] +['Ġdüny', 'an'] +['Ġdünyan', 'ın'] +['гÑĢ', 'ани'] +['гÑĢани', 'Ñĩ'] +['Ġ×Ķש׾', '×Ļש×Ļ'] +['Ġ×Ķ×IJ', 'ש'] +['åıĬ', 'ãģ³'] +['ìĭŃ', 'ìĭľ'] +['ìĭŃìĭľ', 'ìĺ¤'] +['Ġдол', 'л'] +['Ġдолл', 'аÑĢ'] +['Ġпов', 'ÑĤоÑĢ'] +['Ġ×Ĺ', '×Ļ׳×Ŀ'] +['ת', 'פת×Ĺ'] +['Ñĥв', 'ели'] +['Ñĥвели', 'Ñĩен'] +['ãĤ«', 'ãĥª'] +['raw', 'id'] +['rawid', 'ÅĤow'] +['×ķ', '×ķ׾'] +['ãĥŁ', 'ãĥ¥'] +['ì½', 'ĺ'] +['ĠBy', 'ÅĤ'] +['Ðľ', 'ÐIJ'] +['ع', 'ÙIJ'] +['ĠÑģовеÑĢ', 'ÑĪ'] +['ĠÑģовеÑĢÑĪ', 'енно'] +['Ġм', 'ой'] +['Ġ×ķ׾×IJ', '×Ĺר'] +['æħ', '£'] +['æħ£', 'ãĤĮ'] +['ØŃ', 'اÙ쨏'] +['Ġ무', 'ë£Į'] +['à¸Ħà¸ĵะ', 'à¸ģรรม'] +['à¸Ħà¸ĵะà¸ģรรม', 'à¸ģาร'] +['Ġìĸ´', 'ëĶĶ'] +['Ġdif', 'eren'] +['Ġdiferen', 'ça'] +['ĠاÙĦØ£', 'ساس'] +['ĠاÙĦأساس', 'ÙĬØ©'] +['Ġ׾×IJ×Ĺר', '×ķ׳×Ķ'] +['ê·', 'ł'] +['Ġ×Ķש׳×Ļ', '×Ļ×Ķ'] +['ìľĦìĽIJ', 'ìŀ¥'] +['ลุ', 'à¸ģ'] +['ç', 'iler'] +['Ġ×Ķ×IJ', '׾×ķ'] +['èģŀ', 'ãģı'] +['Ġ×ķ×IJ', 'פ×Ļ׾×ķ'] +['ĠÑĢе', 'ализ'] +['ĠÑĢеализ', 'аÑĨи'] +['ระยะ', 'à¹Ģวลา'] +['Ġجدا', 'Ùĭ'] +['تب', 'اع'] +['Ġveh', 'ÃŃculo'] +['Ġдол', 'г'] +['à¸Ľà¸£à¸´', 'มาà¸ĵ'] +['ì¦', 'IJ'] +['Ġ׾', '×ŀ×§×ķ×Ŀ'] +['ĠìĤ¬', 'ì§Ħ'] +['à¸Ĭ', 'à¹īา'] +['Ġ×ŀ×¢', '×ķ׾×Ķ'] +['Ġgö', 'rm'] +['Ġgörm', 'ek'] +['ĠÙĪÙĩ', 'ذÙĩ'] +['пеÑĢ', 'в'] +['пеÑĢв', 'ÑĭÑħ'] +['ê·¸', 'ëŀĺ'] +['ĠاÙĦبر', 'ÙĬØ·'] +['ĠاÙĦبرÙĬØ·', 'اÙĨÙĬ'] +['ĠиÑİ', 'нÑı'] +['ĠÐĵ', 'оÑĢ'] +['Ġ׾', 'ש׾×Ŀ'] +['ÐIJ', 'ÐĿ'] +['Ġназ', 'наÑĩен'] +['о', 'оÑĢ'] +['ооÑĢ', 'Ñĥж'] +['Ġöz', 'elli'] +['Ġözelli', 'ÄŁi'] +['Ġни', 'же'] +['ç¶ļ', 'ãģijãģ¦'] +['Ġа', 'ÑĢенд'] +['Ġkat', 'ılı'] +['Ġkatılı', 'm'] +['ĠØ¥', 'Ø·ÙĦاÙĤ'] +['ĠÙĪØ¥', 'ذا'] +['Ġок', 'ÑĤÑı'] +['ĠокÑĤÑı', 'бÑĢÑı'] +['à¹Ĥà¸ķ', 'à¹'] +['à¹Ĥà¸ķà¹', 'Ĭ'] +['à¹Ĥà¸ķà¹Ĭ', 'ะ'] +['Ġolduk', 'ları'] +['Ùħ', 'ÙĪÙĤع'] +['ëĤ', '©'] +['ã썿ĢĿ', 'ãģ£ãģ¦ãģĦãĤĭ'] +['Ġש', '×Ļ׼×ķ׾'] +['วา', 'à¸Ķ'] +['س', 'ÙĬÙĦ'] +['à¸Ĥ', 'วั'] +['à¸Ĥวั', 'à¸į'] +['تØŃ', 'ÙĥÙħ'] +['ì', 'ĤŃ'] +['Ġconna', 'ît'] +['׳', 'פת×Ĺ'] +['Ġch', 'ặ'] +['Ġchặ', 'n'] +['ĠÙħ', 'ØŃÙħ'] +['ĠÙħØŃÙħ', 'ÙĪØ¯'] +['ãģ', '´'] +['ĠпÑĢодÑĥк', 'ÑĨии'] +['зд', 'ÑĢав'] +['ãģĶ', 'è¦'] +['ãģĶè¦', '§'] +['×IJ×ij', '×IJ'] +['Ġvé', 'ritable'] +['ĠØ·', 'ÙģÙĦ'] +['ãĥĪãĥ©', 'ãĥĸãĥ«'] +['ê³', '¡'] +['Ġת', '×ŀ×ķ׳×Ķ'] +['Ġki', 'ên'] +['ĠÙĤ', 'ادر'] +['Ø¥ÙĤ', 'ÙĦÙĬÙħ'] +['ĠпÑĢед', 'пÑĢи'] +['ĠпÑĢедпÑĢи', 'ÑıÑĤиÑı'] +['Ġb', 'Äĥng'] +['Ġay', 'ında'] +['Ġg', 'ấp'] +['еÑħ', 'ал'] +['Ġgi', 'Ãłnh'] +['Ġд', 'ав'] +['Ġдав', 'но'] +['ìĺĢ', 'ëĭ¤'] +['à¸Ļัà¸ģ', 'à¹Ģà¸ķ'] +['à¸Ļัà¸ģà¹Ģà¸ķ', 'ะ'] +['Ùħست', 'شار'] +['ست', 'راتÙĬج'] +['ستراتÙĬج', 'ÙĬ'] +['رÙħ', 'ز'] +['Ġt', 'Ä©nh'] +['ë¡', 'Ń'] +['ĠÑĩ', 'еÑĤ'] +['ĠÑĩеÑĤ', 'Ñĭ'] +['ĠÑĩеÑĤÑĭ', 'ÑĢе'] +['ĠEnt', 'ão'] +['Ġص', 'غ'] +['Ġصغ', 'ÙĬرة'] +['×ij×Ļ×ĺ', '×ķ׾'] +['خط', 'ÙĪØ·'] +['ĠÑĢазвиÑĤ', 'ие'] +['Ġamacı', 'yla'] +['à¸Ĺี', 'วี'] +['Ġо', 'ÑģÑĤ'] +['ĠоÑģÑĤ', 'алÑĮн'] +['ש×ķ׾×Ĺ', 'ף'] +['Ġ׼', '׳×Ļס'] +['Ġ׼׳×Ļס', '×Ķ'] +['Ġd', 'áºŃy'] +['ĠyaÅŁ', 'ayan'] +['Ġ×ŀ×Ķ', '×ķ×ķ×Ķ'] +['ĠÑĥ', 'Ñģи'] +['ĠÑĥÑģи', 'ли'] +['×ŀ', 'פ×Ļ'] +['ĠпÑĢовед', 'ениÑı'] +['Ġر', 'ب'] +['Ġرب', 'Ùħا'] +['ĠاÙĦØ£', 'ÙĪØ³Ø·'] +['Ġìľł', 'ì§Ģ'] +['Ġprac', 'ownik'] +['Ġpracownik', 'ów'] +['×ŀס', '×ķרת'] +['ÙĤار', 'ب'] +['à¸Ħวาม', 'รูà¹īสึà¸ģ'] +['à¹ģหล', 'ะ'] +['ĠاÙĦÙĨ', 'ÙĤد'] +['Ġ×IJ׾', 'פ×Ļ'] +['Ùħس', 'ئ'] +['Ùħسئ', 'ÙĪÙĦ'] +['ев', 'ÑĭÑħ'] +['клÑİÑĩ', 'ениÑı'] +['×ij', '×Ļ׳'] +['×ij×Ļ׳', '×Ļ×Ķ×Ŀ'] +['ש', '×ķ×IJ×Ķ'] +['ĠÅŁ', 'ark'] +['ĠÅŁark', 'ı'] +['Ġsü', 'rec'] +['Ġsürec', 'in'] +['à¹Ģà¸Ħร', 'à¸Ķ'] +['à¹Ģà¸Ħรà¸Ķ', 'ิà¸ķ'] +['ãĥIJ', 'ãĥ¬'] +['ĠØ´', 'Ø£ÙĨ'] +['à¹Ģà¸Ńา', 'à¹Ħวà¹ī'] +['niÄĻ', 'cie'] +['רצ', '×Ĺ'] +['ĠaÅŁ', 'ama'] +['׳', 'פ×Ĵ×¢'] +['Ġth', 'á»Ŀ'] +['Ġkhu', 'ẩn'] +['diÄŁ', 'inde'] +['ÑıÑī', 'иÑħ'] +['ãĥĺ', 'ãĥ«'] +['Ġüber', 'h'] +['Ġüberh', 'aupt'] +['ĠÑĤÑĢеб', 'ова'] +['ĠdÅĤ', 'ugi'] +['×ĺ', '×Ļף'] +['à¸Ĥà¸Ļาà¸Ķ', 'à¹ĥหà¸įà¹Ī'] +['ĠاÙĦØ£', 'Ùĩ'] +['ĠاÙĦØ£Ùĩ', 'ÙĦÙĬ'] +['ĠMü', 'd'] +['ĠMüd', 'ürü'] +['Ġ×Ļ×Ķ', '×ķ×ĵ×Ķ'] +['Ñĭв', 'аеÑĤÑģÑı'] +['س', 'اط'] +['×Ķת', '׳×Ķ×Ĵ'] +['×Ķ×ª×ł×Ķ×Ĵ', '×ķת'] +['à¸ģาร', 'à¸ľà¸¥à¸´à¸ķ'] +['íĴ', 'Ģ'] +['สà¸ĸาà¸Ļ', 'à¸ģารà¸ĵà¹Į'] +['Ġо', 'ÑĦ'] +['ĠоÑĦ', 'иÑģ'] +['ĠÙĦ', 'عبة'] +['Ġstron', 'ÄĻ'] +['Ġר×IJ', '×ķ×Ļ'] +['×Ĺ', '×ij׾'] +['ĠÑĢÑĭ', 'н'] +['ĠÑĢÑĭн', 'ке'] +['Ġ׾×ŀ×¢', 'ף'] +['اس', 'ÙĦ'] +['ห', 'ัà¸Ļ'] +['Ġ×IJ', '×Ĺ×Ļ'] +['ĠпÑĢод', 'ол'] +['ê°Ģ', 'ìŀħ'] +['Ġ×ijר', '×Ĺ'] +['Ġ×ijר×Ĺ', '×ij×Ļ'] +['дж', 'еÑĢ'] +['Ġ׾', '×Ĺ׾'] +['Ġ׾×Ĺ׾', '×ķ×ĺ'] +['Ġ׾×Ĺ׾×ķ×ĺ', '×Ļף'] +['ศาส', 'à¸Ļา'] +['ãĤ¢ãĤ¤', 'ãĥĨ'] +['ãĤ¢ãĤ¤ãĥĨ', 'ãĥł'] +['Ġפר', '×ķפ'] +['جز', 'اء'] +['ล', 'à¸Ńย'] +['Ġc', 'iaÅĤa'] +['Ġgi', 'ết'] +['ĠзнаÑĩ', 'иÑĤелÑĮно'] +['Ġolmad', 'ıģ'] +['Ġolmadıģ', 'ını'] +['н', 'д'] +['нд', 'екÑģ'] +['تأ', 'Ùĥد'] +['Ġìĸ', '¸'] +['Ġìĸ¸', 'ìłľ'] +['ay', 'dın'] +['ãĥī', 'ãĥ¬ãĤ¹'] +['Ġs', 'ắt'] +['Ġíĺ¸', 'íħĶ'] +['Ġë¶', 'ģ'] +['Ġë¶ģ', 'íķľ'] +['ãĥij', 'ãĤ¤'] +['Ġ×ŀש×Ĺ×§', '×Ļ'] +['à¸Ħà¸Ļ', 'à¸Ńืà¹Īà¸Ļ'] +['Ġиз', 'гоÑĤов'] +['ĠизгоÑĤов', 'лен'] +['à¹Ģà¸ģีย', 'ร'] +['à¹Ģà¸ģียร', 'à¸ķิ'] +['תק', 'שר'] +['ĠÑĢаÑģ', 'ÑĩеÑĤ'] +['ส', 'à¹Ģà¸ķ'] +['Ġl', 'änger'] +['ĠiÅŁ', 'let'] +['ĠiÅŁlet', 'me'] +['Ġع', 'ÙĦÙĬÙĨ'] +['ĠعÙĦÙĬÙĨ', 'ا'] +['é', 'lection'] +['ĠاÙĦغ', 'ربÙĬØ©'] +['íĭ', 'Ģ'] +['ãĤĤãĤī', 'ãģĪ'] +['Ġкни', 'ги'] +['Ø£', 'سÙħ'] +['أسÙħ', 'اء'] +['Ġth', 'á»ı'] +['Ġthá»ı', 'a'] +['หà¸Ļ', 'ู'] +['Ġ×ł×¢', 'ש×Ķ'] +['à¸łà¸²à¸¢', 'à¹ĥà¸ķà¹ī'] +['à¸ŀื', 'à¸Ĭ'] +['رÙĬ', 'Ø·'] +['Ùģ', 'ÙĪØ¶'] +['ãģĤãĤĬãģĮãģ¨ãģĨãģĶãģĸ', 'ãģĦãģ¾ãģĹãģŁ'] +['ש', '×ĵ×Ķ'] +['Ġng', 'á»±c'] +['ĠÑģеÑĢ', 'ÑĮ'] +['ĠÑģеÑĢÑĮ', 'езн'] +['T', 'ôi'] +['Ġfiyat', 'ları'] +['ĠвÑģ', 'Ñİ'] +['ĠC', 'ódigo'] +['Ġ×Ķש', '×IJ'] +['Ġ×Ķש×IJ', '׾×Ķ'] +['ĠP', 'ública'] +['Ø¥', 'Ø®'] +['إخ', 'ÙĪØ§ÙĨ'] +['ĠзаÑıв', 'ил'] +['ãĥ¦', 'ãĥ¼'] +['ר×IJ', '×Ļת'] +['vol', 'ución'] +['Ġsz', 'ko'] +['Ġszko', 'ÅĤy'] +['جرÙĬ', 'دة'] +['Ġpens', 'é'] +['ìī', '¬'] +['ĠBüyük', 'ÅŁehir'] +['ĠØ£Ùħ', 'رÙĬ'] +['ĠØ£ÙħرÙĬ', 'ÙĥÙĬ'] +['à¸Ļัà¸ģ', 'ศึà¸ģษา'] +['Ġtod', 'av'] +['Ġtodav', 'ÃŃa'] +['ĠС', 'ан'] +['ĠСан', 'кÑĤ'] +['íķĺ', 'ìŀIJ'] +['ØŃÙĪ', 'اÙĦ'] +['׼', '×ķשר'] +['à¹Ģลย', 'à¸Ħรัà¸ļ'] +['Ġal', 'gu'] +['Ġalgu', 'ém'] +['Ùģ', 'ز'] +['Ġçek', 'il'] +['Ġ×ĵ', 'ר׼×Ļ×Ŀ'] +['ãĥIJ', 'ãĥ©'] +['à¸ģà¹ĩ', 'สามารà¸ĸ'] +['สà¹Īวà¸Ļ', 'ลà¸Ķ'] +['íı', '°'] +['ĠP', 'úb'] +['ĠPúb', 'lico'] +['à¹ģà¸Ļว', 'à¸Ĺาà¸ĩ'] +['×IJת', '×Ĵר'] +['Ø´', 'اش'] +['شاش', 'Ø©'] +['ci', 'ÅĽni'] +['ĠÃľ', 'rün'] +['ÙĦÙĪ', 'ØŃ'] +['ĠاÙĦ', 'بÙĨ'] +['ĠاÙĦبÙĨ', 'Ùĥ'] +['ì¡°', 'ì¹ĺ'] +['Ġorganiz', 'ación'] +['ãģĤãĤĬãģĮãģ¨ãģĨãģĶãģĸ', 'ãģĦãģ¾ãģĻ'] +['s', 'ätze'] +['ĠÑģем', 'ей'] +['ÙĤ', 'صد'] +['ÑģÑĤв', 'еннÑĭе'] +['Ġpréc', 'éd'] +['Ġprécéd', 'ent'] +['à¸ģรุà¸ĩà¹Ģà¸Ĺà¸ŀ', 'ฯ'] +['ãģ¨è¨Ģ', 'ãģĦ'] +['×ij׳×Ļ', '×Ļף'] +['ĠØŃ', 'ÙĪ'] +['ĠØŃÙĪ', 'اÙĦÙĬ'] +['סק', 'ס'] +['ĠsaÄŁlam', 'ak'] +['Ġ׾', 'צ×Ļ×Ļף'] +['×§×ĵ', 'ש'] +['Ġ×Ķ×ŀ', '×¢×¨×Ľ×ª'] +['Ġ׾×Ķ', '×¢×ij×Ļר'] +['Ġg', 'ünd'] +['Ġgünd', 'em'] +['ĠнаÑĪ', 'его'] +['à¹ĥà¸Ļ', 'à¸ŀืà¹īà¸Ļà¸Ĺีà¹Ī'] +['à¹Ģà¸Ħร', 'ืà¸Ń'] +['à¹Ģà¸Ħรืà¸Ń', 'à¸Ĥ'] +['à¹Ģà¸Ħรืà¸Ńà¸Ĥ', 'à¹Īาย'] +['ظ', 'اÙĩرة'] +['ÙħÙĨ', 'ظÙħ'] +['ÙħÙĨظÙħ', 'ات'] +['Ùħت', 'از'] +['追', 'ãģĦ'] +['dı', 'kt'] +['dıkt', 'an'] +['ĠëįĶ', 'ìļ±'] +['ĠÐĿ', 'апÑĢимеÑĢ'] +['tw', 'ór'] +['×ŀ×ķ×¢', 'צ×Ķ'] +['Ùĥ', 'ÙĪÙĥ'] +['Ð', '©'] +['×ŀ×ĺ', 'פ׾'] +['ó', 'lica'] +['訪', 'ãĤĮ'] +['ĠëĮĢ', 'ë¶Ģ'] +['ĠëĮĢë¶Ģ', 'ë¶Ħ'] +['ãĤ¯ãĥª', 'ãĥĥãĤ¯'] +['ãĤĴ', 'éģ¸'] +['ãĤĴéģ¸', 'ãģ¶'] +['Ġpow', 'sta'] +['Ġpowsta', 'ÅĤ'] +['Ġraz', 'ón'] +['×ij', '×ķ×Ĺר'] +['ĠÑģообÑī', 'ил'] +['Ġ×§', '×ij×ķ×¢'] +['r', 'êt'] +['à¸Ķี', 'à¸Ĥึà¹īà¸Ļ'] +['×ŀס', '×¢×ĵ'] +['×ŀסע×ĵ', '×ķת'] +['ĠÃĸ', 'sterreich'] +['Ġ׳', '×Ĺש×ij'] +['Ùħباد', 'رة'] +['ì´', 'ī'] +['×Ĵ', '׳×ĺ×Ļ'] +['ä¿¡', 'ãģĺ'] +['du', 'ÄŁ'] +['duÄŁ', 'unu'] +['Ġph', 'ú'] +['ĠاÙĦØ£', 'Ø®ÙĬر'] +['Ġت', 'عتبر'] +['landır', 'ıl'] +['ãģ¨ãģ¯', 'ãģĦ'] +['ãģ¨ãģ¯ãģĦ', 'ãģĪ'] +['ĠاÙĦ', 'Ø·ÙĦ'] +['ĠاÙĦØ·ÙĦ', 'اب'] +['ĠN', 'º'] +['éģ¿', 'ãģij'] +['اÙĦ', 'Ùħع'] +['اÙĦÙħع', 'رÙĪÙģ'] +['ส', 'à¸łà¸²'] +['éĽ¢', 'ãĤĮ'] +['ĠпомоÑī', 'ÑĮ'] +['Ġзна', 'еÑĤ'] +['ãĥĹãĥ¬', 'ãĤ¼'] +['ãĥĹãĥ¬ãĤ¼', 'ãĥ³ãĥĪ'] +['Ġsup', 'érieur'] +['Ġש׾', '×Ļש×Ļ'] +['ĠاÙĦÙĨ', 'ÙĪØ¹'] +['ãĤĵãģ§ãģĻ', 'ãģŃ'] +['à¸Ńà¸ļ', 'รม'] +['Ġgi', 'á»įng'] +['Ġwzgl', 'ÄĻd'] +['ĠاÙĦÙģ', 'ÙĤر'] +['è', 'rent'] +['Ġ×ŀ×IJ', '×Ĺ'] +['Ġ×ŀ×IJ×Ĺ', '×ķר×Ļ'] +['×Ĵ', '×Ĵ'] +['×Ļ', '×Ļ×ij'] +['ÙħÙĦ', 'اب'] +['ÙħÙĦاب', 'س'] +['Ġhük', 'ü'] +['Ġhükü', 'met'] +['Ġ×ŀ×Ĵ', '×Ļ×ij'] +['ĠÐŀ', 'Ñĩ'] +['ĠÐŀÑĩ', 'енÑĮ'] +['æĹ©', 'ãģĦ'] +['Ġconstr', 'ucción'] +['Ġth', 'ượng'] +['ï¼', 'ĭ'] +['Ġcor', 'ação'] +['à¹Ģหล', 'à¹ĩà¸ģ'] +['ĠBaÅŁ', 'b'] +['ĠBaÅŁb', 'akan'] +['éĢ£', 'ãĤĮ'] +['ãģĻãĤĭ', 'ãģĵãģ¨ãģĮãģ§ãģįãģ¾ãģĻ'] +['ĠÙĤ', 'اÙħت'] +['Ġا', 'Ùĥثر'] +['ÙģØ§Ø¹', 'ÙĦ'] +['ĠÑĦ', 'оÑĢ'] +['ĠÑĦоÑĢ', 'Ñĥм'] +['غ', 'ذÙĬ'] +['ĠiÅŁ', 'le'] +['ĠiÅŁle', 'ml'] +['ĠiÅŁleml', 'eri'] +['ĠìĤ¬ëŀĮ', 'ìĿĢ'] +['Ġìŀij', 'ìĦ±'] +['Ġë§Ī', '볨'] +['Ùħ', 'جÙĦس'] +['หม', 'ู'] +['д', 'в'] +['дв', 'иг'] +['двиг', 'а'] +['à¹Ģสีย', 'à¸Ĭีวิà¸ķ'] +['×Ķת', 'פת×Ĺ'] +['×Ķתפת×Ĺ', '×ķת'] +['ĠмеÑĤ', 'ÑĢо'] +['ĠÑģ', 'енÑĤ'] +['ĠÑģенÑĤ', 'Ñı'] +['ĠÑģенÑĤÑı', 'бÑĢÑı'] +['ê³', '§'] +['Ġ׾', 'פע'] +['Ġ×ľ×¤×¢', '×ŀ×Ļ×Ŀ'] +['à¹Ģà¸ļ', 'ีย'] +['詳', 'ãģĹãģı'] +['çķ°', 'ãģªãĤĭ'] +['Ġİl', 'çe'] +['ĠAt', 'at'] +['ĠAtat', 'ür'] +['ĠAtatür', 'k'] +['รุ', 'à¹Īà¸ĩ'] +['Ġkald', 'ı'] +['Ġ주', 'ìŀ¥'] +['Ġprés', 'ence'] +['Ġн', 'аб'] +['Ġнаб', 'лÑİ'] +['ĠнаблÑİ', 'да'] +['ĠÑģам', 'ого'] +['×Ĵ', '×ķש'] +['×ŀ×ĺ', '×ķפ'] +['×ŀ×ĺ×ķפ', '׾'] +['ĠвÑĭб', 'иÑĢа'] +['ĠìŀIJ', '리'] +['åĪĨ', 'ãģĭãĤīãģªãģĦ'] +['Ġз', 'Ñĥб'] +['Ġש׼', '×ijר'] +['Ġد', 'ائ'] +['Ġدائ', 'Ùħا'] +['ĠпаÑĢ', 'ÑĤи'] +['ï¼', '²'] +['ĠاÙĬ', 'ضا'] +['ĠÑħ', 'оз'] +['ĠÑħоз', 'Ñı'] +['ĠÑħозÑı', 'й'] +['ĠÑħозÑıй', 'ÑģÑĤв'] +['ĠاÙĦØ£', 'ج'] +['ĠاÙĦأج', 'ÙĨب'] +['ĠاÙĦأجÙĨب', 'ÙĬØ©'] +['ĠÐĹ', 'на'] +['ĠAp', 'ós'] +['ĠÑį', 'неÑĢ'] +['ĠÑįнеÑĢ', 'ги'] +['Ġy', 'ans'] +['Ġyans', 'ı'] +['ĠJust', 'i'] +['ĠJusti', 'ça'] +['Ġpré', 'vu'] +['ม', 'วล'] +['ìŀ¥', 'ëĭĺ'] +['à¸ģระ', 'à¸ļ'] +['à¸ģระà¸ļ', 'วà¸Ļ'] +['à¸ģระà¸ļวà¸Ļ', 'à¸ģาร'] +['×ŀ', '×ŀ'] +['×ŀ×ŀ', '×ķצע'] +['Ġh', 'ẹ'] +['Ġhẹ', 'n'] +['зд', 'ание'] +['Ġak', 'ÅŁ'] +['ĠakÅŁ', 'am'] +['×ĺ', '×ķפ'] +['Ġgere', 'kt'] +['Ġgerekt', 'i'] +['Ġgerekti', 'ÄŁini'] +['Ġnar', 'z'] +['Ġnarz', 'ÄĻdzi'] +['é', 'po'] +['épo', 'que'] +['ĠTh', 'ần'] +['Ġwys', 'oko'] +['Ġwysoko', 'ÅĽci'] +['à¸ľà¸¹à¹ī', 'à¸Ľ'] +['à¸ľà¸¹à¹īà¸Ľ', 'à¹Īวย'] +['ĠÙĬ', 'بدÙĪ'] +['ÑĤелÑĮ', 'ного'] +['Ġвз', 'глÑıд'] +['Ġjed', 'nÄħ'] +['ĠìĿĺ', '견'] +['Ġ', 'à¸Ĥà¸ĵะà¸Ĺีà¹Ī'] +['פ', '×Ļ×ĵ'] +['ìĥģ', 'ëĭ´'] +['Ġm', 'ỡ'] +['×Ķ', '×ŀ׾'] +['×Ķ×ŀ׾', 'צ×ķת'] +['ĠÑģоÑģÑĤ', 'о'] +['ĠÑģоÑģÑĤо', 'иÑĤ'] +['Ġав', 'и'] +['Ġави', 'а'] +['ĠL', 'änder'] +['تص', 'ÙĪÙĬر'] +['×ŀ×ĵ', '×Ļ×Ķ'] +['ìłĪ', 'ì°¨'] +['ãģ¨', 'ãĤĬ'] +['ãģ¨ãĤĬ', 'ãģĤ'] +['ãģ¨ãĤĬãģĤ', 'ãģĪ'] +['ãģ¨ãĤĬãģĤãģĪ', 'ãģļ'] +['ĠÑĢ', 'Ñıд'] +['ĠÑĢÑıд', 'ом'] +['ĠNh', 'ất'] +['ĠاÙĦÙĥ', 'اÙħÙĦ'] +['×Ĺ׾', '׾'] +['ĠGi', 'ấy'] +['צ', '×ĺר'] +['צ×ĺר', '×£'] +['Ġ׾×ij', '×ĺ׾'] +['Ġим', 'еÑĤÑĮ'] +['ס×ŀ', '×ķ×ļ'] +['Ġparticip', 'ação'] +['íķľëĭ¤', 'ë©´'] +['ÙħÙĨت', 'دÙĬ'] +['ÙħÙĨتدÙĬ', 'ات'] +['ĠeÄŁ', 'len'] +['g', 'änge'] +['رب', 'ØŃ'] +['ãĤ®', 'ãĥ£'] +['ĠاÙĦر', 'ÙĤÙħ'] +['à¸ĭ', 'à¹īำ'] +['ĠH', 'óa'] +['×ŀר', '×Ĺ×§'] +['ØŃÙħ', 'اÙħ'] +['بÙĪ', 'Ùĥ'] +['ĠArt', 'ÃŃculo'] +['ãĥĦ', 'ãĤ¢ãĥ¼'] +['×Ķפ', '׼×Ķ'] +['×Ĺ׾', '×ķף'] +['ĠпеÑĢе', 'Ñħод'] +['len', 'miÅŁ'] +['زر', 'اعة'] +['Ġseñ', 'or'] +['ãģ£ãģ¦', 'ãģįãģ¦'] +['Ø¥', 'Ø´'] +['إش', 'ارة'] +['Ġpod', 'ÃŃa'] +['ĠÃľ', 'lke'] +['н', 'ÑģкаÑı'] +['Ġadapt', 'é'] +['Ġdüzen', 'len'] +['Ġdüzenlen', 'en'] +['ĠÑģÑĤ', 'ала'] +['ĠÙĬ', 'ØŃتاج'] +['Ġn', 'ier'] +['Ġnier', 'uch'] +['Ġnieruch', 'omo'] +['Ġnieruchomo', 'ÅĽci'] +['ãģĵãģ¨ãģĮ', 'ãģĤãĤĭ'] +['ยà¸Ńà¸Ķ', 'à¹Ģยีà¹Īยม'] +['ĠÙħ', 'ج'] +['ĠÙħج', 'اÙĨÙĬ'] +['Ġз', 'аб'] +['Ġзаб', 'ол'] +['Ġзабол', 'ев'] +['Ġзаболев', 'аниÑı'] +['ĠÅĽ', 'ro'] +['ĠÅĽro', 'dk'] +['ĠÅĽrodk', 'ów'] +['Ġ×Ķ', '׾×IJ×ķ×ŀ×Ļ'] +['Ġdok', 'ÅĤad'] +['ĠdokÅĤad', 'nie'] +['ãģŁãģı', 'ãģªãģĦ'] +['ãģ¯ãģļ', 'ãģ§ãģĻ'] +['ã썿ĢĿ', 'ãģ£ãģ¦ãģĦãģŁ'] +['é', 'cran'] +['ìĹħ', 'ì²´'] +['trzym', 'aÅĤ'] +['ÑģÑĤв', 'еннÑĭй'] +['ĠNot', 'ÃŃc'] +['ĠNotÃŃc', 'ias'] +['Ùħ', 'رÙĬ'] +['ÙħرÙĬ', 'ض'] +['æ°Ĺ', 'è»'] +['æ°Ĺè»', '½'] +['æ°Ĺ軽', 'ãģ«'] +['ëĵ', '£'] +['Ġ×ĵ', '×ķ×IJר'] +['Ġ׾', '×ŀ׳'] +['Ġ׾×ŀ׳', '×ķ×¢'] +['ĠçalÄ±ÅŁ', 'ıyor'] +['ĠÅŁ', 'idd'] +['ĠÅŁidd', 'et'] +['ĠM', 'ặt'] +['Ġate', 'ÅŁ'] +['ĠполÑĥÑĩ', 'ениÑı'] +['à¹Ģà¸Ħรืà¹Īà¸Ńà¸ĩ', 'มืà¸Ń'] +['Ġgrö', 'ÃŁer'] +['د', 'ائ'] +['دائ', 'رة'] +['Ġbul', 'un'] +['Ġbulun', 'maktadır'] +['à¹Ģห', 'ร'] +['à¹Ģหร', 'ีย'] +['à¹Ģหรีย', 'à¸į'] +['à¸Ļัà¸ģ', 'à¸Ĺà¹Īà¸Ńà¸ĩà¹Ģà¸Ĺีà¹Īยว'] +['Ġalan', 'ında'] +['ĠÑĥ', 'зна'] +['Ġл', 'еÑĩение'] +['売', 'ãĤĮ'] +['Ġçev', 'ir'] +['Ġdeste', 'ÄŁi'] +['ĠheiÃŁ', 't'] +['âĸ', '²'] +['ØŃ', 'Ø·'] +['à¸Ħำ', 'à¸ķà¸Ńà¸ļ'] +['ãĤªãĥ³', 'ãĥ©ãĤ¤ãĥ³'] +['Ġ×ij×Ĺ×Ļ', '×Ļ×Ŀ'] +['ãĥ¦', 'ãĥĭ'] +['Ġdüzenle', 'me'] +['Ġmodal', 'itÃł'] +['سر', 'Ø·'] +['سرط', 'اÙĨ'] +['×ŀ׼', '×ķף'] +['ĠданнÑĭ', 'й'] +['تر', 'ت'] +['ترت', 'ÙĬب'] +['à¸ļาà¸ĩ', 'à¸Ħà¸Ļ'] +['ĠÄIJ', 'á»ĭnh'] +['ม', 'ูล'] +['มูล', 'à¸Ħà¹Īา'] +['ÙĨ', 'ÙĤص'] +['à¸ģาร', 'รัà¸ģษา'] +['ĠÑĦ', 'он'] +['ĠÑĦон', 'д'] +['ãĤĪãģĨ', 'ãģ«ãģªãģ£ãģŁ'] +['Ùħع', 'اÙĦ'] +['ÙħعاÙĦ', 'جة'] +['ĠOs', 'man'] +['ĠOsman', 'lı'] +['иÑĩеÑģк', 'ом'] +['à¸Ńยาà¸ģ', 'à¸Īะ'] +['ãģķãģ¾', 'ãģĸ'] +['ãģķãģ¾ãģĸ', 'ãģ¾'] +['ãģķãģ¾ãģĸãģ¾', 'ãģª'] +['Ġת', '×ķ׼׾'] +['×¢', 'צ×ij'] +['ĠاÙĦع', 'سÙĥ'] +['ĠاÙĦعسÙĥ', 'رÙĬ'] +['Ġvé', 'hic'] +['Ġvéhic', 'ule'] +['Ġ×Ļצ', '×Ĺ×§'] +['ĠاÙĦÙĪ', 'ØŃ'] +['ĠاÙĦÙĪØŃ', 'ÙĬد'] +['ĠاÙĦع', 'دÙĪ'] +['ĠQu', 'ản'] +['Ġê³µ', 'ëıĻ'] +['بد', 'ÙĦ'] +['ĠÄij', 'ảng'] +['Ġm', 'á»ĩnh'] +['Ġnie', 'zb'] +['Ġniezb', 'ÄĻ'] +['ĠniezbÄĻ', 'dn'] +['Ġyayın', 'lan'] +['обÑī', 'и'] +['Ġgö', 'tür'] +['צ', 'פ'] +['צפ', '×ķ×Ļ'] +['ĠÙĦÙĬ', 'بÙĬ'] +['ĠÙĦÙĬبÙĬ', 'ا'] +['ØŃ', 'ÙĪØ§'] +['Ġд', 'об'] +['Ġдоб', 'ÑĢо'] +['иÑĢÑĥ', 'ем'] +['ĠاÙĦØŃÙĥÙĪÙħ', 'ÙĬØ©'] +['m', 'Ã¤ÃŁig'] +['Ġed', 'ición'] +['влек', 'аÑĤелÑĮ'] +['влекаÑĤелÑĮ', 'н'] +['Ġת', 'ש׾×ķ×Ŀ'] +['Ġ×Ķש', '×ķ׳×Ļ×Ŀ'] +['มิ', 'à¸ĸุ'] +['มิà¸ĸุ', 'à¸Ļ'] +['มิà¸ĸุà¸Ļ', 'ายà¸Ļ'] +['é£Łãģ¹', 'ãģ¦'] +['ĠìĪĺ', 'ì§ij'] +['ס', '×ij×Ļ'] +['ĠиÑİ', 'лÑı'] +['Ġà¹Ħà¸Ķà¹ī', 'à¹ģà¸ģà¹Ī'] +['׾×Ĺ', '×Ŀ'] +['tr', 'ä'] +['trä', 'gt'] +['ãģĿãĤĤ', 'ãģĿãĤĤ'] +['ÐĿ', 'Ðķ'] +['Ġв', 'нÑĥÑĤ'] +['ĠвнÑĥÑĤ', 'ÑĢи'] +['ãģ¨', 'ä¸Ģç·Ĵãģ«'] +['ãĤ«', 'ãĥķãĤ§'] +['Ġ×ij×Ĺ', '×ĵר'] +['×Ĺ', '×ŀש'] +['ãĤ¨', 'ãĥį'] +['ãĤ¨ãĥį', 'ãĥ«'] +['ãĤ¨ãĥįãĥ«', 'ãĤ®'] +['ãĤ¨ãĥįãĥ«ãĤ®', 'ãĥ¼'] +['à¸Ĥà¸Ńà¸ĩ', 'à¸ķัวà¹Ģà¸Ńà¸ĩ'] +['بÙĤ', 'اء'] +['פס', '×Ļ׼'] +['פס×Ļ׼', '×ķ׾×ķ×Ĵ'] +['ãĥ¡', 'ãĥĥ'] +['ãĥ¡ãĥĥ', 'ãĤ»'] +['ãĥ¡ãĥĥãĤ»', 'ãĥ¼ãĤ¸'] +['ÙĦ', 'ÙĤب'] +['A', 'Äŀ'] +['שק', '×Ļ×¢'] +['ÙĤ', 'ساÙħ'] +['×ĵ×ķ×Ĵ', '×ŀ×Ķ'] +['æ·±', 'ãģĦ'] +['íĸĪ', 'ëĬĶëį°'] +['ĠrozwiÄħz', 'anie'] +['à¸Ļัà¹Īà¸Ļ', 'à¹Ģà¸Ńà¸ĩ'] +['×Ļצ', '×ij'] +['Ġtr', 'ông'] +['à¹ĥà¸Ĭà¹ī', 'à¸ļริà¸ģาร'] +['ĠاÙĦÙħÙĪ', 'سÙħ'] +['ĠдеÑĤ', 'и'] +['ãģĹãģĭ', 'ãģªãģĦ'] +['ס', '×Ļף'] +['Ġréfé', 'rence'] +['à¹ģห', 'à¹īà¸ĩ'] +['ãĤĤãĤī', 'ãģ£ãģŁ'] +['Ġ׾', 'ר׼'] +['Ġ׾ר׼', '×ķש'] +['شع', 'ÙĪØ±'] +['ĠÐij', 'ог'] +['Ġlaz', 'ım'] +['Ġ×Ļש', '׳×Ŀ'] +['Ġп', 'аÑĢÑĤ'] +['ĠпаÑĢÑĤ', 'неÑĢ'] +['ĠÑĥ', 'ника'] +['ĠÑĥника', 'лÑĮн'] +['Ġmaté', 'riel'] +['×ŀר', '×§'] +['Ġph', 'ưá»Ŀng'] +['Ġз', 'ай'] +['Ġзай', 'м'] +['Ùģ', 'ÙĤد'] +['Univers', 'itÃł'] +['×¢', 'ר׼×Ļ×Ŀ'] +['Ġba', 'ño'] +['Ġн', 'оÑı'] +['ĠноÑı', 'бÑĢÑı'] +['à¸Ľ', 'à¹īาย'] +['Ġt', 'ats'] +['Ġtats', 'äch'] +['Ġtatsäch', 'lich'] +['ĠÑĤÑĢ', 'еÑĤÑĮ'] +['Ñį', 'м'] +['ãĥĻ', 'ãĥ¼ãĤ¹'] +['Ġnh', 'á»±a'] +['ìĬ¤', 'íģ¬'] +['ĠعبداÙĦ', 'ÙĦÙĩ'] +['Ġת', '×ķר×Ķ'] +['أش', 'ÙĬ'] +['أشÙĬ', 'اء'] +['ĠÙĦÙĦ', 'غا'] +['ĠÙĦÙĦغا', 'ÙĬØ©'] +['Ùħ', 'ÙĪØ§ÙĤ'] +['ÙħÙĪØ§ÙĤ', 'Ùģ'] +['ĠgÅĤówn', 'a'] +['Ġart', 'Ä±ÅŁ'] +['Ġ×ŀ×§', '×ķ×ŀ×Ļ'] +['ãĤ¯ãĥ©', 'ãĥĸ'] +['Ġس', 'ÙĪÙī'] +['ĠìŬ', 'ìĦ±'] +['اس', 'ر'] +['اسر', 'ائÙĬÙĦ'] +['Ġ׳', '×Ľ×ª×ij'] +['ย', 'à¹īà¸Ńà¸Ļ'] +['Ġdeber', 'á'] +['Ġph', 'ẫu'] +['ÑİÑī', 'ем'] +['ĠÙĦدÙĬ', 'ÙĨا'] +['×ŀ×ĺ', '×Ķ'] +['Ġ׳', '×ķ׾×ĵ'] +['ĠвÑģÑĤÑĢ', 'еÑĩа'] +['ãĤīãĤĮ', 'ãģ¦ãģĦãģ¾ãģĻ'] +['ĠcaÅĤ', 'ej'] +['ย', 'ึ'] +['ยึ', 'à¸Ķ'] +['поÑĤ', 'ен'] +['поÑĤен', 'ÑĨи'] +['Ġл', 'иÑĤ'] +['ĠлиÑĤ', 'еÑĢ'] +['ĠлиÑĤеÑĢ', 'аÑĤÑĥÑĢ'] +['Ġкажд', 'ом'] +['ĠíĮ', 'IJ'] +['ĠíĮIJ', 'ëĭ¨'] +['à¸Ī', 'ู'] +['Ġpres', 'ença'] +['ãģªãĤĵ', 'ãģ§'] +['Ùħ', 'ÙĬاÙĩ'] +['ин', 'ÑĦоÑĢм'] +['инÑĦоÑĢм', 'аÑĨион'] +['инÑĦоÑĢмаÑĨион', 'н'] +['ĠìŀIJ', 'ìŰ'] +['ר׼', 'ש'] +['Ġöd', 'ül'] +['ç¶ļ', 'ãģı'] +['Ġп', 'Ñģ'] +['ĠпÑģ', 'иÑħ'] +['ĠпÑģиÑħ', 'олог'] +['ت', 'ذÙĥر'] +['Ġìŀħ', 'ìŀ¥'] +['ล', 'à¸Ķà¹Į'] +['ìĦł', 'ê±°'] +['ãģ£ãģ¦', 'ãģĬãĤĬãģ¾ãģĻ'] +['Ġ×Ļ', '×¢'] +['Ġ×Ļ×¢', '×§×ij'] +['ĠاÙĦØ·', 'عاÙħ'] +['ãĥĨ', 'ãĤ¹ãĥĪ'] +['ĠTu', 'ấn'] +['Ġparticip', 'ación'] +['×ŀ×ķ×ŀ', '×Ĺ×Ķ'] +['×Ĵר', 'ס×Ķ'] +['ĠاÙĦتÙĨ', 'ÙģÙĬ'] +['ĠاÙĦتÙĨÙģÙĬ', 'ذÙĬ'] +['ĠбезопаÑģ', 'н'] +['ge', 'f'] +['gef', 'ähr'] +['Ø´', 'ÙĪØ±'] +['Ġmy', 'ÅĽli'] +['ÙĪØ§', 'Ø´ÙĨ'] +['ÙĪØ§Ø´ÙĨ', 'Ø·ÙĨ'] +['׳×ķס', '×¢'] +['Ùĥ', 'Ùĩ'] +['ÙĥÙĩ', 'رب'] +['ÙĥÙĩرب', 'اء'] +['Ġmus', 'iaÅĤ'] +['ìĭ', '¸'] +['ãĥĸãĥ©', 'ãĥĥãĤ¯'] +['Ġcré', 'é'] +['ÙĨÙĩ', 'ار'] +['owo', 'ÅĽÄĩ'] +['ÙħØŃا', 'ÙĥÙħ'] +['ĠwÅĤa', 'ÅĽ'] +['ĠwÅĤaÅĽ', 'c'] +['ĠwÅĤaÅĽc', 'iciel'] +['ĠÙĬ', 'ؤ'] +['ĠÙĬؤ', 'دÙĬ'] +['×ŀ×¢', '×ķ׳'] +['×IJ', '×ij׾'] +['خط', 'Ø£'] +['ĠÑħ', 'олод'] +['×ĸ', '×ķ׾'] +['ãģĵãĤĮ', 'ãĤī'] +['ãģĵãĤĮãĤī', 'ãģ®'] +['Ġbás', 'ica'] +['ฤ', 'à¸Ķ'] +['ฤà¸Ķ', 'ูà¸ģ'] +['ฤà¸Ķูà¸ģ', 'า'] +['ฤà¸Ķูà¸ģา', 'ล'] +['èIJ½ãģ¡', 'çĿĢ'] +['ãģªãģĦ', 'ãģĵãģ¨'] +['ص', 'ÙĪÙħ'] +['ÙĨج', 'ØŃ'] +['׳ק', '×ķ×ĵ'] +['׳ק×ķ×ĵ', 'ת'] +['кл', 'аÑģÑģ'] +['íķĺìĭľ', 'ëĬĶ'] +['ëĦ', 'ĺ'] +['Ġש×IJ', '×Ļ׳×ķ'] +['ĠС', 'ейÑĩаÑģ'] +['may', 'acaģı'] +['Ġyap', 'ılır'] +['Ġcategor', 'ÃŃa'] +['عب', 'اد'] +['ĠТ', 'еп'] +['ĠТеп', 'еÑĢÑĮ'] +['×Ķ×Ļס×ĺ', '×ķר×Ļ'] +['h', 'ế'] +['ãĤ³', 'ãĥ¼ãĥī'] +['Ġcabe', 'ça'] +['ج', 'Ùħا'] +['جÙħا', 'Ùĩ'] +['جÙħاÙĩ', 'ÙĬر'] +['ä½İ', 'ãģĦ'] +['ĠÑĤоваÑĢ', 'ов'] +['à¸Ĭาว', 'à¸ļà¹īาà¸Ļ'] +['ĠÑģÑĤан', 'ов'] +['ĠÑģÑĤанов', 'иÑĤÑģÑı'] +['ĠавÑĤом', 'обилÑĮ'] +['ĠÑģлÑĥÑĩ', 'ай'] +['à¸Ńั', 'à¸ŀ'] +['ĠG', 'iriÅŁ'] +['ĠìĿ¼', 'ëĭ¨'] +['ĠпÑĢ', 'оÑģ'] +['ĠпÑĢоÑģ', 'моÑĤÑĢ'] +['ãģªãģıãģª', 'ãģ£ãģŁ'] +['มี', 'à¸Ľà¸±à¸įหา'] +['ïº', 'İ'] +['éc', 'oute'] +['ĠÙħ', 'ÙĪØ¬ÙĪØ¯'] +['Ġس', 'رÙĬع'] +['ĠÙĪÙĩ', 'ÙĨا'] +['ĠÙĪÙĩÙĨا', 'Ùĥ'] +['à¸Ħุà¸ĵ', 'สม'] +['à¸Ħุà¸ĵสม', 'à¸ļัà¸ķิ'] +['Ġìļ°', 'ìĦł'] +['à¸ŀระ', 'à¸ŀุà¸Ĺà¸ĺ'] +['好', 'ãģ¿'] +['ظ', 'ÙĦÙħ'] +['Ġм', 'акÑģ'] +['ĠмакÑģ', 'ималÑĮ'] +['ĠмакÑģималÑĮ', 'но'] +['ãĥª', 'ãĤ¢ãĥ«'] +['à¹ģมà¹ī', 'วà¹Īา'] +['ĠاÙĦØŃ', 'ÙĪØ§Ø±'] +['ãĥĹãĥ©', 'ãĤ¹'] +['Ġع', 'ÙĦاÙĤØ©'] +['Ġíĸī', 'ëıĻ'] +['Ġgönder', 'il'] +['Ġl', 'ãi'] +['ĠsaÄŁ', 'lıkl'] +['ĠsaÄŁlıkl', 'ı'] +['ĠÑĪ', 'аг'] +['Ġ×ij×IJר', '×Ķ'] +['prowadzi', 'Äĩ'] +['ãģĦãģı', 'ãģ¤ãģĭ'] +['Ġبت', 'ارÙĬØ®'] +['Ġ×ij×IJ×ķת', '×Ķ'] +['Ġmó', 'c'] +['ĠÐľ', 'не'] +['ãĥĹãĥ¬', 'ãĥ¼'] +['×IJ', '×ĸר×Ĺ'] +['åł´åIJĪ', 'ãģ«ãģ¯'] +['使', 'ãģĪ'] +['à¹Ģร', 'ืà¸Ńà¸Ļ'] +['ĠÐŁ', 'еÑĤ'] +['ĠÐŁÐµÑĤ', 'ÑĢ'] +['ãģ«åħ¥', 'ãĤĭ'] +['Ùħ', 'ادة'] +['à¹Ģà¸ĩ', 'ืà¹Īà¸Ńà¸Ļ'] +['à¹Ģà¸ĩืà¹Īà¸Ńà¸Ļ', 'à¹Ħà¸Ĥ'] +['ĠÑģоÑģÑĤоÑı', 'ние'] +['ôn', 'ica'] +['ĠÑĦ', 'ев'] +['ĠÑĦев', 'ÑĢа'] +['ĠÑĦевÑĢа', 'лÑı'] +['Ġ×ķ', '×ĸ'] +['Ġ×ķ×ĸ', '×IJת'] +['à¸Ħร', 'ิ'] +['à¸Ħริ', 'ส'] +['ĠÐķ', 'Ñīе'] +['ãģ£ãģ¦ãģĹãģ¾', 'ãģĦãģ¾ãģĹãģŁ'] +['ĠпÑĢав', 'иÑĤелÑĮ'] +['ĠпÑĢавиÑĤелÑĮ', 'ÑģÑĤв'] +['Ġtä', 'glich'] +['Ġëĭ¹', 'ìĭľ'] +['×ŀ×ķ×¢', '×ŀ×ĵ'] +['Ġдв', 'оÑĢ'] +['æī', 'ķ'] +['æīķ', 'ãģĦ'] +['ĠÑģÑĤан', 'еÑĤ'] +['Ġвозд', 'ейÑģÑĤв'] +['ĠвоздейÑģÑĤв', 'и'] +['Ġf', 'ête'] +['à¹Ģส', 'า'] +['תק', '×ķ×ķ×Ķ'] +['Ġu', 'yar'] +['Ġuyar', 'ı'] +['à¸ģลัà¸ļ', 'à¹Ħà¸Ľ'] +['Ġgi', 'ưá»Ŀng'] +['Ġв', 'а'] +['Ġва', 'ÑĪи'] +['ĠÄij', 'áºŃu'] +['ĠSpa', 'ÃŁ'] +['ĠìķĦ', 'ë§Ī'] +['à¹Ħà¸Ķà¹ī', 'à¸ĩà¹Īาย'] +['Ġ×Ķ×ŀ', '×ijקש'] +['æĸ°', 'ãģŁ'] +['æĸ°ãģŁ', 'ãģª'] +['ılı', 'yor'] +['пл', 'ан'] +['Ġ×Ķ×ijר', '×Ļ×IJ×ķת'] +['ĠaÄŁ', 'rı'] +['Ġsay', 'gı'] +['建', 'ãģ¦'] +['Ġnaj', 'wyż'] +['Ġnajwyż', 'sz'] +['سÙĬاس', 'ات'] +['ãģĬ', 'å¾Ĺ'] +['ĠاÙĦع', 'ÙĦÙĬ'] +['ĠاÙĦعÙĦÙĬ', 'ا'] +['Ġcoraz', 'ón'] +['ì¹ĺ', 'ë£Į'] +['หัว', 'à¸Ĥà¹īà¸Ń'] +['Ġب', 'ØŃÙĬ'] +['ĠبØŃÙĬ', 'Ø«'] +['зв', 'езд'] +['بÙĪ', 'ابة'] +['ÐĽ', 'Ðĺ'] +['ÙĦا', 'زÙħ'] +['Ġroz', 'p'] +['Ġrozp', 'oc'] +['Ġrozpoc', 'zÄĻ'] +['触', 'ãĤĮ'] +['ĠاÙĦج', 'ÙħÙĩ'] +['ĠاÙĦجÙħÙĩ', 'ÙĪØ±'] +['Ġsp', 'ÄĻd'] +['ĠspÄĻd', 'z'] +['วิà¸Ĺยา', 'ศาสà¸ķรà¹Į'] +['ив', 'аеÑĤÑģÑı'] +['Ġдан', 'ной'] +['Ġreprés', 'ente'] +['ĠÄij', 'á»ĭch'] +['Ġ×¢×ŀ', '×ķ×§'] +['à¸Ńัà¸Ļ', 'à¸ķร'] +['à¸Ńัà¸Ļà¸ķร', 'าย'] +['Ġestr', 'atég'] +['Ġestratég', 'ia'] +['pad', 'ÅĤ'] +['Ġв', 'полн'] +['Ġвполн', 'е'] +['ĠпÑĢедоÑģÑĤав', 'лен'] +['×Ĺ׾', '×ķ×§'] +['×Ĺ׾×ķ×§', 'ת'] +['ãĤ¢', 'ãĥĬ'] +['ĠاÙĦغ', 'ذ'] +['ĠاÙĦغذ', 'ائÙĬ'] +['ĠÑĥ', 'зн'] +['ĠÑĥзн', 'аÑĤÑĮ'] +['à¸ĭ', 'à¹īาย'] +['å½ĵ', 'ãģ¦'] +['ØŃÙĬ', 'اء'] +['Ġbás', 'ico'] +['×§×ķ×ij', '×¢'] +['ĠاÙĦÙħ', 'باراة'] +['ĠاÙĦÙĩ', 'اتÙģ'] +['Ġ׼', '׳×Ĵ×ĵ'] +['à¸Ľà¸£à¸°', 'หย'] +['à¸Ľà¸£à¸°à¸«à¸¢', 'ัà¸Ķ'] +['Ðļ', 'ак'] +['à¸Ĺีà¹Ī', 'à¸Ļà¹Īา'] +['à¸Ĺีà¹Īà¸Ļà¹Īา', 'สà¸Ļà¹ĥà¸Ī'] +['ãģ¾', 'ãģģ'] +['ï½', '¢'] +['Ñģк', 'оп'] +['Ġson', 'rasında'] +['Ġur', 'zÄħd'] +['ĠurzÄħd', 'zenia'] +['׼×ķ', '×ķ׳'] +['׼×ķ×ķ׳', 'ת'] +['Ġ׾×Ķת', '×ŀ×ķ×ĵ'] +['Ġ׾×Ķת×ŀ×ķ×ĵ', '×ĵ'] +['ĠÑģ', 'ли'] +['ĠÑģли', 'ÑĪ'] +['ĠÑģлиÑĪ', 'ком'] +['ĠÑģÑĤ', 'Ñĥд'] +['ĠÑģÑĤÑĥд', 'енÑĤ'] +['Ġ×Ķ', '×ķ×ĵ'] +['Ġ×Ķ×ķ×ĵ', '×¢×Ķ'] +['ë¹Ħ', 'ìļ©'] +['à¸Ńยาà¸ģ', 'à¹ĥหà¹ī'] +['Ġb', 'á»ģ'] +['ยุ', 'à¸Ĺà¸ĺ'] +['Ðĺ', 'ÐĿ'] +['س', 'ائر'] +['Ø£', 'صÙĪÙĦ'] +['ĠاÙĦغ', 'رÙģ'] +['ãģĵãģ¨ãĤĤ', 'ãģĤãĤĬãģ¾ãģĻ'] +['è¾¼', 'ãģ¾ãĤĮ'] +['ĠاÙĦساب', 'ع'] +['Ġc', 'á»§'] +['ãģĦãģŁãģł', 'ãģĦãģŁ'] +['ì§', 'ĵ'] +['ìĤ¬', '무'] +['powied', 'ź'] +['تÙģ', 'Ùĥ'] +['تÙģÙĥ', 'ÙĬر'] +['иÑĢов', 'ки'] +['ĠíĨµ', 'íķ´ìĦľ'] +['ãĤ¨', 'ãĤ¹ãĥĨ'] +['ĠдеÑıÑĤелÑĮ', 'ноÑģÑĤÑĮ'] +['ĠданнÑĭ', 'м'] +['Ġ×¢', '×ķר'] +['Ġ×¢×ķר', '׼×Ļ'] +['×ķ×ĵ', 'עת'] +['Ġhayat', 'ını'] +['Ġb', 'Äħd'] +['ĠbÄħd', 'ź'] +['obs', 'ÅĤug'] +['à¹Ģà¸ŀียà¸ĩ', 'à¹ģà¸Ħà¹Ī'] +['à¸ĭ', 'à¹Īา'] +['è²ł', 'ãģij'] +['ĠÑģÑĤÑĢ', 'ем'] +['ĠÄij', 'á»īnh'] +['ĠÐł', 'ÑĥÑģ'] +['ĠN', 'ữ'] +['Ġ׾×Ķש', '×Ļ×Ĵ'] +['Ġjed', 'noc'] +['Ġjednoc', 'ze'] +['Ġjednocze', 'ÅĽnie'] +['Ġ×Ķ×Ĵ', '×ij×ķ×Ķ'] +['أخ', 'ÙĦاÙĤ'] +['ĠнаÑģ', 'ел'] +['ĠнаÑģел', 'ениÑı'] +['ĠÙĬ', 'ÙĨب'] +['ĠÙĬÙĨب', 'غÙĬ'] +['ãģĮ', 'ãģĭ'] +['ãģĮãģĭ', 'ãģĭ'] +['×Ĵ', 'עת'] +['Ðŀ', 'Ðł'] +['ĠналиÑĩ', 'ии'] +['Ġë§Ī', 'ì§Ģ'] +['Ġë§Īì§Ģ', 'ë§ī'] +['Ġíĸī', 'ìĤ¬'] +['Ġtre', 'ÅĽci'] +['Ġê°Ģ', 'ì¹ĺ'] +['ì¦', 'ĺ'] +['Ġана', 'лог'] +['×Ķצע', 'ת'] +['в', 'лад'] +['влад', 'е'] +['ĠÑģдел', 'ал'] +['Ġ׳', '×Ĵ×Ļש'] +['Ġ׳×Ĵ×Ļש', '×ķת'] +['полн', 'ение'] +['à¸Ĩ', 'à¹Īา'] +['ĠD', 'ön'] +['׼׾׼', '׾×Ķ'] +['×ŀ×ĸ', '×Ĵ'] +['Ùħ', 'Ùģ'] +['ÙħÙģ', 'Ùĩ'] +['ÙħÙģÙĩ', 'ÙĪÙħ'] +['×Ķ', '×ĵ'] +['×Ķ×ĵ', 'פס'] +['×Ķ×ĵפס', '×Ķ'] +['ãģĻãģİ', 'ãģ¦'] +['Ġг', 'ÑĢ'] +['ĠгÑĢ', 'н'] +['×ŀ×ĺ', '×ķס'] +['Ġ기', 'ìĸµ'] +['ï¾', 'Ł'] +['ĠpÅĤ', 'yn'] +['ĠGr', 'ünde'] +['ĠBü', 'cher'] +['Ġwed', 'ÅĤug'] +['ãģ¾ãģł', 'ãģ¾ãģł'] +['Ġ׳×Ķ', '×ĵר'] +['ĠÙĬست', 'Ø·ÙĬع'] +['ĠHi', 'á»ĩp'] +['ãĤŃãĥ£ãĥ³', 'ãĥļ'] +['ãĤŃãĥ£ãĥ³ãĥļ', 'ãĥ¼ãĥ³'] +['Ġth', 'á»ķ'] +['Ġeuropé', 'enne'] +['à¸ļ', 'ัà¸ĩ'] +['à¸ļัà¸ĩ', 'à¸Ħัà¸ļ'] +['ĠszczegóÅĤ', 'owo'] +['׳', 'שק'] +['ãĥķ', 'ãĥ©ãĥ³ãĤ¹'] +['×ŀ×ķ×ŀ', '×Ĺ×Ļ'] +['Ġcom', 'ún'] +['Ġç', 'arp'] +['ØŃت', 'ÙĬا'] +['ØŃتÙĬا', 'ج'] +['ØŃتÙĬاج', 'ات'] +['ëĭ´', 'ëĭ¹'] +['ä½ķ', '度'] +['ä½ķ度', 'ãĤĤ'] +['×ĵ', '×ij×§'] +['ãģį', 'ãĤĮ'] +['ãģįãĤĮ', 'ãģĦ'] +['Ġк', 'ам'] +['Ġкам', 'еÑĢ'] +['ĠespecÃŃf', 'ico'] +['Ġtel', 'éfono'] +['à¸ķัà¹īà¸ĩ', 'à¸Ńยูà¹Ī'] +['I', 'Åŀ'] +['ãģ©', 'ãĤĵãģ©'] +['ãģ©ãĤĵãģ©', 'ãĤĵ'] +['עצ', '×ŀ×IJ×Ļ'] +['à¸Ķัà¸ĩ', 'à¸Ļีà¹ī'] +['ĠÑĦоÑĢм', 'иÑĢов'] +['ĠÑĦоÑĢмиÑĢов', 'а'] +['×ķ×ŀ', '×ij'] +['Ġkullan', 'ımı'] +['Ðľ', 'Ðŀ'] +['×¢', 'ש×Ļ'] +['עש×Ļ', '×Ļ×Ķ'] +['Ġön', 'lem'] +['à¹Ģà¸Ń', 'à¹ĩ'] +['à¹Ģà¸Ńà¹ĩ', 'ม'] +['×ŀשק', '×Ļ×¢'] +['ר', '×Ļ×Ĺ'] +['à¸Ĥ', 'ัà¸Ķ'] +['ĠíĻ', 'ľ'] +['ĠíĻľ', 'ìļ©'] +['à¸ĭ', 'ะ'] +['ãĤĪãģĨ', 'ãģ«ãģªãĤĬãģ¾ãģĹãģŁ'] +['ĠÑĢаÑģ', 'пÑĢ'] +['ĠÑĢаÑģпÑĢ', 'оÑģÑĤ'] +['ĠÑĢаÑģпÑĢоÑģÑĤ', 'ÑĢан'] +['ĠÑĢаÑģпÑĢоÑģÑĤÑĢан', 'ен'] +['׼×Ļ', '×ķף'] +['ÙĤب', 'ض'] +['تص', 'رÙĬØŃ'] +['تصرÙĬØŃ', 'ات'] +['Ġо', 'ÑĢи'] +['ĠоÑĢи', 'г'] +['ĠоÑĢиг', 'ина'] +['ĠоÑĢигина', 'л'] +['ĠاÙĦع', 'اÙĦÙĬ'] +['à¹ģหà¹Īà¸ĩ', 'à¸Ļีà¹ī'] +['ãĥķãĤ¡', 'ãĥ¼'] +['ãģ¦ãģĦ', 'ãģį'] +['ãģ¦ãģĦãģį', 'ãģŁãģĦ'] +['פ', 'תר'] +['פתר', '×ķ׳×ķת'] +['Ġ×ij', '×Ļ×Ĺ'] +['Ġ×ij×Ļ×Ĺ', '×ĵ'] +['Ġod', 'by'] +['Ġodby', 'ÅĤ'] +['ĠоÑĩеÑĢ', 'ед'] +['Ġtr', 'ương'] +['ãĤŃ', 'ãĥ³'] +['×ŀ', '×ķפ'] +['×ŀ×ķפ', '×¢'] +['ëĵľ', '립'] +['ëĵľë¦½', 'ëĭĪëĭ¤'] +['à¸ŀืà¹īà¸Ļ', 'à¸IJาà¸Ļ'] +['ìŀIJ', '격'] +['ĠVi', 'á»ĩn'] +['ĠDes', 'pués'] +['Ġ×IJ׾', '×Ļ׳×ķ'] +['Ġdur', 'ée'] +['íĩ', '´'] +['Ġmü', 'zik'] +['i', 'ếu'] +['ĠÑĢаз', 'меÑīен'] +['Ġк', 'Ñĥд'] +['ĠкÑĥд', 'а'] +['غ', 'ض'] +['غض', 'ب'] +['ĠTamb', 'ém'] +['à¸Īัà¸Ķ', 'สà¹Īà¸ĩ'] +['à¸ģาร', 'à¹ģสà¸Ķà¸ĩ'] +['onom', 'ÃŃa'] +['Ġан', 'г'] +['Ġанг', 'ли'] +['Ġангли', 'й'] +['Ġанглий', 'Ñģк'] +['Ġzn', 'al'] +['Ġznal', 'az'] +['Ġznalaz', 'ÅĤ'] +['תר', '×Ĵ'] +['תר×Ĵ', '×ķ×Ŀ'] +['ĠÑģ', 'нов'] +['ĠÑģнов', 'а'] +['ĠÑĩаÑģ', 'а'] +['Ġcommun', 'auté'] +['ĠespecÃŃf', 'ica'] +['ĠL', 'á»ĭch'] +['Ġli', 'é'] +['Ùģ', 'جر'] +['à¹Ģà¸ģ', 'à¹Īà¸ĩ'] +['ع', 'اÙĦ'] +['عاÙĦ', 'ج'] +['Ø£ÙĨ', 'ظ'] +['Ø£ÙĨظ', 'ÙħØ©'] +['ES', 'İ'] +['ĠاÙĦØŃ', 'دÙĬد'] +['à¸ŀระ', 'à¸Ńà¸ĩà¸Ħà¹Į'] +['Ġפר', 'שת'] +['Ġдв', 'иж'] +['Ġдвиж', 'ениÑı'] +['ĠاÙĦج', 'ارÙĬ'] +['à¸ĺาà¸Ļ', 'ี'] +['неÑģ', 'ен'] +['ĠاÙĦÙĨ', 'ÙĩائÙĬ'] +['Ġб', 'еÑĢ'] +['ĠбеÑĢ', 'ем'] +['ĠбеÑĢем', 'енн'] +['Ġdépart', 'ement'] +['à¹Ģà¸Ĺ', 'ีย'] +['à¹Ģà¸Ĺีย', 'à¸ļ'] +['ĠÐľ', 'аÑĢи'] +['ĠнекоÑĤоÑĢ', 'ÑĭÑħ'] +['об', 'еÑģп'] +['обеÑģп', 'еÑĩен'] +['×Ĺ', '×ķ×ĸ'] +['×Ĺ×ķ×ĸ', '×Ķ'] +['ÙĨت', 'ج'] +['à¸Īะ', 'à¹Ħà¸Ķà¹īรัà¸ļ'] +['á»', '°'] +['Ġél', 'éments'] +['ع', 'Ø·'] +['عط', 'اء'] +['Ġt', 'ắt'] +['i', 'á»ĩm'] +['ÑİÑīиÑħ', 'ÑģÑı'] +['ãģĹãģ', '°'] +['ãģĹãģ°', 'ãĤīãģı'] +['Ġпом', 'ожеÑĤ'] +['à¸Ĥà¸ĵะ', 'à¸Ļีà¹ī'] +['Ġ×¢', 'שר×ķת'] +['éģķ', 'ãģ£ãģ¦'] +['ĠпÑĢ', 'ог'] +['ĠпÑĢог', 'н'] +['ĠпÑĢогн', 'оз'] +['Ġt', 'ÅĤ'] +['ĠtÅĤ', 'um'] +['ĠtÅĤum', 'acz'] +['T', 'ür'] +['Tür', 'kiye'] +['ãģį', 'ãģ£'] +['ãģįãģ£', 'ãģĭãģij'] +['Ġ×Ķ׳', '×ķ׼'] +['Ġ×Ķ׳×ķ׼', '×Ĺ×Ļ'] +['ĠìĥĿ', 'ìĤ°'] +['ĠÑĦоÑĢм', 'Ñĭ'] +['ç¾İ', 'ãģĹãģĦ'] +['à¸Ľà¸£', 'ึà¸ģ'] +['à¸Ľà¸£à¸¶à¸ģ', 'ษา'] +['Ġlum', 'ière'] +['ãĤª', 'ãĥ¼ãĥĹ'] +['ãĤªãĥ¼ãĥĹ', 'ãĥ³'] +['à¸Ľ', 'ืà¸Ļ'] +['วั', 'สà¸Ķ'] +['วัสà¸Ķ', 'ุ'] +['еÑĢÑĤ', 'в'] +['ÙĥÙĦ', 'Ùģ'] +['ï½', '£'] +['à¸ĺรรม', 'à¸Ķา'] +['׳', '×ĺר'] +['ĠпÑĢедÑģÑĤав', 'лÑıеÑĤ'] +['Ġanál', 'isis'] +['Ġb', 'ãi'] +['با', 'ÙĤÙĬ'] +['à¸Ľà¸£à¸°', 'à¹Ģà¸Ķ'] +['à¸Ľà¸£à¸°à¹Ģà¸Ķ', 'à¹ĩà¸Ļ'] +['ĠÑģлÑĥÑĩ', 'аÑı'] +['ĠÑģлÑĥÑĩаÑı', 'Ñħ'] +['ÐĽ', 'ÐIJ'] +['สัà¸ĩ', 'à¹Ģà¸ģ'] +['สัà¸ĩà¹Ģà¸ģ', 'à¸ķ'] +['Ġprz', 'ec'] +['Ġprzec', 'ież'] +['Ùħ', 'صÙĦ'] +['ÙħصÙĦ', 'ØŃØ©'] +['ש×ķ×§', '×ķ׾×ĵ'] +['ĠобоÑĢÑĥд', 'ованиÑı'] +['Ġtr', 'waÅĤ'] +['رÙĪ', 'Ùħ'] +['ìķĪ', 'ëĤ´'] +['ĠNgh', 'á»ĭ'] +['Ø®', 'Ø´'] +['à¸ļา', 'à¸Ħาร'] +['à¸ļาà¸Ħาร', 'à¹Īา'] +['Ġоп', 'ÑĨион'] +['ĠÑģозд', 'аниÑı'] +['ãĤ³', 'ãĤ¹ãĥĪ'] +['Ġ×Ķ×¢', '׾×Ļ'] +['Ġ×Ķ×¢×ľ×Ļ', '×ķף'] +['lä', 'uft'] +['ãĥĻ', 'ãĤ¹ãĥĪ'] +['Ġr', 'ê'] +['Ġrê', 've'] +['×IJ', '×ij×Ļ×ij'] +['×Ļ', '×Ļ×ļ'] +['ë¶', 'Ļ'] +['ãĤ¤ãĥ³', 'ãĥī'] +['ÅĤo', 'ży'] +['ÅĤoży', 'Äĩ'] +['ع', 'ائÙĦ'] +['عائÙĦ', 'Ø©'] +['Ø£', 'ÙĪØ±'] +['Ø£ÙĪØ±', 'اÙĤ'] +['à¸Ĺà¹īà¸Ńà¸ĩ', 'à¸ĸ'] +['à¸Ĺà¹īà¸Ńà¸ĩà¸ĸ', 'ิà¹Īà¸Ļ'] +['Ġä', 'hn'] +['Ġähn', 'lich'] +['ãĥŁ', 'ãĥĭ'] +['à¸ľ', 'ู'] +['à¸ľà¸¹', 'à¹īà¸Ļ'] +['à¸ľà¸¹à¹īà¸Ļ', 'ำ'] +['ĠмаÑĤеÑĢиал', 'Ñĭ'] +['Ġкап', 'иÑĤ'] +['ĠкапиÑĤ', 'ал'] +['ï¼', '¦'] +['Ġseç', 'il'] +['Ġh', 'ứng'] +['Ġintéress', 'ant'] +['ãģ£ãģ¦', 'ãģĦãģı'] +['Ġe', 'ÄŁer'] +['ëIJĺ', 'ìĹĪìĬµëĭĪëĭ¤'] +['Ġan', 'laÅŁma'] +['ãģĶ', 'åĪ©ç͍'] +['Ġ×ij', '×ĸ׼'] +['Ġ×ij×ĸ׼', '×ķת'] +['ëĿ¼', 'ë©´'] +['ĠÙĬ', 'ÙĪØ³'] +['ĠÙĬÙĪØ³', 'Ùģ'] +['أسÙĦ', 'ØŃØ©'] +['ĠGef', 'ühl'] +['ĠноÑĢм', 'алÑĮн'] +['ãĥĻ', 'ãĥ³'] +['ãģķãĤĮ', 'ãĤĭãģĵãģ¨'] +['ĠÐij', 'еÑģ'] +['ãģ¨ãģĦ', 'ãģĪãģ°'] +['ĠÙħ', 'ÙĩÙħ'] +['ĠÙħÙĩÙħ', 'Ø©'] +['ãģ§ãģĹãĤĩãģĨ', 'ãģŃ'] +['ĠêµŃ', 'ëĤ´'] +['à¹Ģม', 'à¹ĩà¸Ķ'] +['×ŀ×ij', 'קר'] +['ĠاÙĦد', 'ÙĨÙĬ'] +['ĠاÙĦدÙĨÙĬ', 'ا'] +['à¸Ĭ', 'ู'] +['к', 'ÑĢÑĥÑĤ'] +['Ġtho', 'áng'] +['Ġ׳', '×ĵר'] +['Ġ׳×ĵר', 'ש'] +['ĠÑĢаÑģÑģ', 'казал'] +['ĠAu', 'ÃŁerdem'] +['פ', '×IJר'] +['פ×IJר', '×§'] +['Ġ×ŀש×Ĺ×§', '×Ļ×Ŀ'] +['צ', 'ר׼×Ļ×Ŀ'] +['×ŀ×ĵ', '×ķ'] +['×ŀ×ĵ×ķ', '×Ļ×§'] +['èĭ¦', 'ãģĹ'] +['ĠÑģ', 'иг'] +['ĠÑģиг', 'нал'] +['ĠM', 'á»įi'] +['Ġtr', 'ữ'] +['Ġnast', 'ÄĻp'] +['ĠnastÄĻp', 'nie'] +['Ġì¶Ķ', 'ì§Ħ'] +['ĠاÙĦÙģ', 'ÙĨد'] +['ĠاÙĦÙģÙĨد', 'ÙĤ'] +['koÅĦ', 'czyÅĤ'] +['ส', 'ีà¹Ī'] +['×§', '×Ļ×ij'] +['×§×Ļ×ij', '×ķ×¥'] +['ĠнÑĥж', 'нÑĭ'] +['大', 'åĪĩ'] +['大åĪĩ', 'ãģª'] +['æıĽ', 'ãģĪ'] +['ת', '×ķס'] +['ת×ķס', 'פת'] +['ãģ£ãģ¦', 'ãģĦãģªãģĦ'] +['Ġм', 'Ñı'] +['ĠмÑı', 'г'] +['ĠмÑıг', 'к'] +['Ġjak', 'ie'] +['Ġjakie', 'ÅĽ'] +['à¸ķำ', 'à¸ļ'] +['à¸ķำà¸ļ', 'ล'] +['ĠìŀĪ', 'ì§Ģ'] +['×ij×ĺ', '×IJ'] +['ĠоÑĤлиÑĩ', 'но'] +['ÙĤ', 'ÙIJ'] +['ĠавÑĤом', 'об'] +['ĠавÑĤомоб', 'и'] +['ĠавÑĤомоби', 'лÑı'] +['دÙĬÙħÙĤرا', 'Ø·ÙĬ'] +['ĠاÙĦ', 'ÙĪØ§'] +['ĠاÙĦÙĪØ§', 'ØŃد'] +['Ġس', 'ÙĪØ±ÙĬØ©'] +['Ø£', 'غÙĦ'] +['أغÙĦ', 'ب'] +['ĠÑįк', 'ÑĢан'] +['ãĥĹ', 'ãĥ©ãĤ¤'] +['Ġjeste', 'ÅĽ'] +['ãĥIJ', 'ãĥª'] +['Ġ×Ķ×IJ', '×ķ×ķ×Ļר'] +['ائ', 'Ùĥ'] +['à¸Ńยà¹Īาà¸ĩ', 'ยิà¹Īà¸ĩ'] +['ÑĢ', 'екÑĤ'] +['Ġum', 'o'] +['Ġumo', 'ż'] +['Ġumoż', 'li'] +['Ġumożli', 'w'] +['Ġumożliw', 'ia'] +['Ġnäch', 'ste'] +['ĠìŀĪ', 'ì§Ģë§Į'] +['ĠпÑĢед', 'н'] +['ĠпÑĢедн', 'аз'] +['ĠпÑĢедназ', 'наÑĩен'] +['Ġma', 'çı'] +['Ġp', 'omi'] +['Ġpomi', 'ÄĻd'] +['ĠpomiÄĻd', 'zy'] +['ĠاÙĦÙĦ', 'ÙĤاء'] +['à¹Ģà¸Ķ', 'à¸Ńะ'] +['Ġнов', 'оÑģÑĤи'] +['×ŀ×Ĺ', '׾×Ķ'] +['رÙĬاض', 'ÙĬ'] +['à¸Ķ', 'à¸Ļ'] +['à¸Ķà¸Ļ', 'à¸ķรี'] +['ب', 'صر'] +['ìĬ¤', 'íĥĢ'] +['scri', 'pción'] +['Ġnap', 'isa'] +['Ġnapisa', 'ÅĤ'] +['Ġ׳ש', '×ŀ×¢'] +['ĠاÙĦÙħØŃ', 'ÙĦÙĬ'] +['Ġhi', 'á»ĥn'] +['×IJ', '×Ĺ'] +['×IJ×Ĺ', 'ר×IJ×Ļ'] +['Ġг', 'ÑĢаниÑĨ'] +['æīĭ', 'ç¶ļãģį'] +['Ùĥ', 'سب'] +['Ġà¹ģà¸ķà¹Ī', 'à¸ĸà¹īา'] +['à¸Ķาว', 'à¸Ļà¹Į'] +['à¸Ķาวà¸Ļà¹Į', 'à¹Ĥหลà¸Ķ'] +['ãĤĭãģĵãģ¨ãģĮãģ§ãģį', 'ãģ¾ãģĻ'] +['åŁºæľ¬', 'çļĦãģ«'] +['ÙĪÙĦ', 'اد'] +['rä', 'ume'] +['د', 'ÙģØ§Ø¹'] +['×Ļצ', '×¢'] +['ĠO', 'czy'] +['ĠOczy', 'wiÅĽcie'] +['ĠÅ', 'ģ'] +['ĠÅģ', 'a'] +['اÙĦÙĬ', 'اب'] +['اÙĦÙĬاب', 'اÙĨ'] +['áºł', 'I'] +['ĠBir', 'liÄŁi'] +['×Ķ', '×ķצ'] +['×Ķ×ķצ', '×IJת'] +['ĠÄij', 'ua'] +['Ġê·¸ëŁ¬', 'ëĭĪê¹Į'] +['Ġréal', 'ité'] +['ع', 'ÙĦاÙĤات'] +['J', 'este'] +['Jeste', 'ÅĽ'] +['Ġмн', 'ож'] +['Ġмнож', 'еÑģÑĤво'] +['ï¼', '«'] +['ãĥĹãĥŃ', 'ãĤ¸ãĤ§'] +['ãĥĹãĥŃãĤ¸ãĤ§', 'ãĤ¯ãĥĪ'] +['ĠÑĦ', 'л'] +['ظ', 'ÙĨ'] +['×Ĵ׾', '×Ĵ׾'] +['ĠmÅĤod', 'zie'] +['ĠmÅĤodzie', 'ż'] +['à¸Ļà¹īำ', 'à¸ķา'] +['à¸Ļà¹īำà¸ķา', 'ล'] +['ÐĽ', 'Ðķ'] +['×ij', '×ķ×ĺ'] +['Ġ׾×Ķ', '×Ĵ×Ļ×ĵ'] +['ãģĵãģ¨ãĤĤ', 'ãģĤãĤĭ'] +['ز', 'اد'] +['×ŀ×Ļ×ĵ', '×¢'] +['ĠgÅĤówn', 'ie'] +['ãĥı', 'ãĤ¦'] +['ãĥıãĤ¦', 'ãĤ¹'] +['б', 'ел'] +['Ġét', 'ape'] +['ðŁĺ', 'Ģ'] +['Ġмод', 'елÑĮ'] +['a', 'ģını'] +['ש', '×Ĺ×§'] +['ש×Ĺ×§', 'ף'] +['Ġni', 'ño'] +['à¸Ĭ', 'à¹īาà¸ĩ'] +['à¹Ģล', 'ีย'] +['ĠÑĦоÑĢм', 'е'] +['ĠاÙĦØ´', 'رÙĬÙģ'] +['ĠÑĥд', 'аÑĢ'] +['arr', 'iv'] +['arriv', 'ée'] +['Ġmies', 'iÄĻ'] +['ĠmiesiÄĻ', 'cy'] +['ØŃ', 'رÙĥ'] +['ØŃرÙĥ', 'ات'] +['ĠDi', 'á»ħn'] +['ÐĿ', 'Ы'] +['ãģ¾ãģ£ãģŁ', 'ãģı'] +['Ġ×Ļ', 'ר×ķ×§'] +['еÑģÑĤ', 'еÑģÑĤв'] +['еÑģÑĤеÑģÑĤв', 'енн'] +['Ġê·¸', 'ëŁ¼'] +['ĠاÙĦÙħ', 'تÙĪ'] +['ĠاÙĦÙħتÙĪ', 'سط'] +['Ġbéné', 'fic'] +['Ġbénéfic', 'ie'] +['Ġwy', 'bra'] +['Ġwybra', 'Äĩ'] +['ĠاÙĦز', 'ÙħÙĨ'] +['ĠпÑĢин', 'Ñı'] +['ĠпÑĢинÑı', 'л'] +['Ù쨱', 'ØŃ'] +['Ġk', 'sz'] +['Ġksz', 'taÅĤ'] +['ĠksztaÅĤ', 't'] +['ק׾', '×ĺ'] +['×ij×ĵ×Ļ×§', 'ת'] +['Ġgi', 'ấ'] +['Ġgiấ', 'c'] +['Ġpropriet', 'Ãł'] +['деÑĢж', 'ан'] +['ĠKö', 'ln'] +['ĠGü', 'zel'] +['×Ļפ', '×ķ×Ļ'] +['ĠCu', 'á»Ļc'] +['ÑįÑĤ', 'аж'] +['تر', 'ÙĥÙĬ'] +['ترÙĥÙĬ', 'ز'] +['лож', 'ений'] +['Ġп', 'Ñĥ'] +['ĠпÑĥ', 'ÑĤи'] +['اخت', 'ÙĦاÙģ'] +['åĩºãģ¦', 'ãģıãĤĭ'] +['à¸ļุ', 'à¸ģ'] +['âĿ', '¤'] +['ÑĦ', 'ан'] +['פש', '×ĺ'] +['à¸ļัà¸Ļ', 'à¹Ģà¸Ĺ'] +['à¸ļัà¸Ļà¹Ģà¸Ĺ', 'ิà¸ĩ'] +['ĠاÙĦس', 'اد'] +['ĠاÙĦساد', 'س'] +['ĠاÙĦÙĤ', 'ÙĪÙħ'] +['ĠاÙĦÙĤÙĪÙħ', 'ÙĬ'] +['Ġyönet', 'ici'] +['Ùĩ', 'ÙĪØ§Øª'] +['ÙĩÙĪØ§Øª', 'Ùģ'] +['Ġrespons', 'ável'] +['Ġпод', 'деÑĢжива'] +['ĠاÙĦسÙĦ', 'Ø·'] +['ĠاÙĦسÙĦØ·', 'ات'] +['ãģĹãģ¦', 'ãģĬãģı'] +['ãĥļ', 'ãĥĥãĥĪ'] +['à¸Ľ', 'ุà¹Īม'] +['Ġogl', 'Äħda'] +['ÙĨا', 'ÙĤ'] +['ÙĨاÙĤ', 'Ø´'] +['à¸Ħà¸Ńà¸Ļ', 'à¹Ĥà¸Ķ'] +['ĠMü', 'sl'] +['ĠMüsl', 'ü'] +['ĠMüslü', 'man'] +['ĠMo', 'ż'] +['ĠMoż', 'na'] +['Ġnum', 'érique'] +['Ġv', 'á»ı'] +['ĠسÙĬ', 'تÙħ'] +['Ġyer', 'leÅŁ'] +['монÑĤ', 'аж'] +['Ġgo', 'ût'] +['ãģ¦', 'ãģĬãĤĬãģ¾ãģĻ'] +['ĠKh', 'ánh'] +['Ġе', 'дин'] +['Ġедин', 'ÑģÑĤв'] +['اÙĨ', 'Ø®Ùģ'] +['اÙĨØ®Ùģ', 'اض'] +['ìĭľ', 'íĹĺ'] +['Ġl', 'ặng'] +['ĠÑĢ', 'олÑĮ'] +['à¸ķัว', 'à¹ģà¸Ĺà¸Ļ'] +['à¸Ħà¹Īา', 'à¹ĥà¸Ĭà¹ī'] +['à¸Ħà¹Īาà¹ĥà¸Ĭà¹ī', 'à¸Īà¹Īาย'] +['Ġver', 'füg'] +['Ġverfüg', 'bar'] +['ìĻĶ', 'ëĭ¤'] +['ãģĦ', 'ãģļ'] +['ãģĦãģļ', 'ãĤĮ'] +['ĠиÑģÑģлед', 'ованиÑı'] +['меÑī', 'а'] +['×Ķ', '×Ĺ'] +['×Ķ×Ĺ', '×ĸר'] +['à¹ģà¸Ł', 'à¸Ĭัà¹Īà¸Ļ'] +['ت', 'صرÙģ'] +['Ø¥', 'رÙĩاب'] +['Ġexerc', 'ÃŃcio'] +['Ġé', 'lev'] +['Ġélev', 'é'] +['สัà¸įà¸įา', 'à¸ĵ'] +['Ãĸ', 'Z'] +['ãĥĹ', 'ãĥŃãĤ°'] +['ãĥĹãĥŃãĤ°', 'ãĥ©'] +['ãĥĹãĥŃãĤ°ãĥ©', 'ãĥł'] +['Ġw', 'ewnÄĻtrzn'] +['Ġhen', 'üz'] +['é£Ľ', 'ãģ³'] +['à¹Ģà¸Ķ', 'à¸Ńรà¹Į'] +['Ñģ', 'Ñĥж'] +['ÑģÑĥж', 'ден'] +['شع', 'ÙĪØ¨'] +['ãģ²ãģ¨', 'ãĤĬ'] +['Ġwy', 'ÅĤÄħ'] +['ĠwyÅĤÄħ', 'cznie'] +['Ġпло', 'Ñħо'] +['ÐĶ', 'Ðķ'] +['áº', '¦'] +['Ù쨹', 'اÙĦÙĬ'] +['ÙģØ¹Ø§ÙĦÙĬ', 'ات'] +['ĠاÙĦع', 'شر'] +['ÑģÑĤÑĥп', 'ил'] +['Ġy', 'arg'] +['Ġyarg', 'ı'] +['нÑİ', 'Ñİ'] +['×ķ×IJ', '×ij'] +['Ġu', 'ç'] +['Ġuç', 'ak'] +['ë²', '½'] +['تÙĪ', 'ÙĤÙĬ'] +['تÙĪÙĤÙĬ', 'ع'] +['Ġì¤ij', 'ìĭ¬'] +['׳×Ļ×ķ', '×ķ×ĺ'] +['Ø£', 'ÙĥÙĦ'] +['ç½®', 'ãģĦãģ¦'] +['éłĤ', 'ãģį'] +['Ġ×Ķת', '×ij'] +['Ġ×Ķת×ij', '×Ļ×¢×Ķ'] +['Ġdür', 'fen'] +['Ùħ', 'ÙĤاÙĦ'] +['ÙħÙĤاÙĦ', 'ات'] +['Ġز', 'ÙħÙĨ'] +['à¸ŀฤ', 'ศ'] +['à¸ŀฤศ', 'à¸Ī'] +['à¸ŀฤศà¸Ī', 'ิà¸ģ'] +['à¸ŀฤศà¸Īิà¸ģ', 'ายà¸Ļ'] +['ĠнеÑģк', 'олÑĮ'] +['ĠнеÑģколÑĮ', 'ки'] +['ĠнеÑģколÑĮки', 'Ñħ'] +['Ġcrian', 'ça'] +['มิ', 'à¸ķร'] +['×ŀ׼', '×Ļר×ķת'] +['à¸ģาร', 'à¸ļริหาร'] +['Ġtélé', 'charg'] +['Ġ×IJ×ķ×Ķ', '×ijת'] +['ĠBü', 'ro'] +['ä½ľ', 'ãģ£ãģŁ'] +['ĠKi', 'ÅŁi'] +['ç¾İåij³', 'ãģĹ'] +['à¹Ģลย', 'à¸Ħà¹Īะ'] +['à¸ŀà¸ļ', 'à¸ģัà¸ļ'] +['à¸Ī', 'à¹īา'] +['Ġç', 'er'] +['Ġçer', 'ç'] +['Ġçerç', 'eve'] +['ãĤĴä½ľ', 'ãģ£ãģ¦'] +['ĠпеÑĢв', 'ÑĥÑİ'] +['×ŀצ', 'ר×Ļ×Ŀ'] +['×IJ׾', '×ķ×Ķ'] +['×IJ׾×ķ×Ķ', '×Ļ×Ŀ'] +['Ġagr', 'é'] +['Ġagré', 'able'] +['Ġay', 'ır'] +['İL', 'İ'] +['ãĤ', '¥'] +['Ġíĺ', 'Ħ'] +['ĠíĺĦ', 'ìĭ¤'] +['ثاÙĦ', 'Ø«'] +['ת', '×ĸ'] +['ת×ĸ', '×ķ׳×Ķ'] +['ãģ¨ãģĦ', 'ãģ£ãģ¦'] +['ãģ¨ãģĦãģ£ãģ¦', 'ãĤĤ'] +['Ġا', 'بÙĪ'] +['ĠÑģоб', 'ак'] +['é£Łãģ¹', 'ãģŁ'] +['Ġдан', 'ном'] +['à¹Ģล', 'ิ'] +['à¹Ģลิ', 'ศ'] +['Ġí', 'ļ'] +['Ġíļ', '¨'] +['Ġíļ¨', 'ê³¼'] +['ãĤĤãĤī', 'ãģĪãĤĭ'] +['׳', 'צ׾'] +['ÑĦ', 'ик'] +['ÑĦик', 'Ñģ'] +['Ġjeste', 'ÅĽmy'] +['ת×Ĺ×ķש', '×Ķ'] +['à¹Ħมà¹Ī', 'à¸Ħวร'] +['ĠØŃ', 'سÙĬÙĨ'] +['à¸ģาร', 'ลà¸ĩà¸Ĺุà¸Ļ'] +['ë´', '¤'] +['ĠÐĺ', 'менно'] +['à¸ļ', 'à¸Ńรà¹Į'] +['à¸ļà¸Ńรà¹Į', 'à¸Ķ'] +['ĠC', 'ảnh'] +['ìĦľ', 'ë¹ĦìĬ¤'] +['Ġпол', 'ов'] +['Ġполов', 'ин'] +['Ġзам', 'еÑĩа'] +['ãģĦãĤį', 'ãĤĵãģª'] +['Ġ×ij', '×Ļ×§'] +['Ġ×ij×Ļ×§', 'ש'] +['л', 'ÑĥÑĪ'] +['ãĤĴ', 'è¿İ'] +['ãĤĴè¿İ', 'ãģĪ'] +['جرÙĬ', 'ÙħØ©'] +['Ġt', 'ây'] +['ĠاÙĦÙĨ', 'ÙĪ'] +['ĠاÙĦÙĨÙĪ', 'ÙĪÙĬ'] +['ÃĤ', 'N'] +['ì¿', 'ł'] +['หà¸Ļ', 'าว'] +['Ġ×ij×Ĺ', 'ש×ij×ķף'] +['ز', 'ار'] +['à¸Ķ', 'าร'] +['à¸Ķาร', 'า'] +['ĠÅĽ', 'l'] +['ĠÅĽl', 'ub'] +['มีà¸Ħวาม', 'สุà¸Ĥ'] +['Ġn', 'hu'] +['Ġnhu', 'áºŃn'] +['ÙħØŃ', 'طة'] +['à¹Ģสืà¹īà¸Ń', 'à¸ľà¹īา'] +['ĠТ', 'олÑĮко'] +['ĠÙĥ', 'س'] +['ĠÙĥس', 'ارة'] +['ÙħØ´', 'رÙĪØ¹'] +['niÄĻ', 'cia'] +['×¢', '׼ש×Ļ×ķ'] +['ت', 'ÙĦÙģ'] +['تÙĦÙģ', 'زÙĬ'] +['تÙĦÙ쨲ÙĬ', 'ÙĪÙĨ'] +['Ġl', 'Æ°á»Ľi'] +['ĠÐľÐ¾Ñģк', 'вÑĭ'] +['Ġré', 'serve'] +['Ġan', 'laÅŁ'] +['ĠanlaÅŁ', 'ıl'] +['Ġed', 'eceÄŁi'] +['รà¸Ńà¸ĩ', 'à¹Ģà¸Ĺà¹īา'] +['Ġب', 'Ø·'] +['Ġبط', 'رÙĬ'] +['ĠبطرÙĬ', 'ÙĤØ©'] +['ãģ¦ãģĹãģ¾', 'ãģ£ãģ¦'] +['ãĤĤãĤī', 'ãģ£ãģ¦'] +['بر', 'ج'] +['æ±', 'ļ'] +['æ±ļ', 'ãĤĮ'] +['Ġch', 'oc'] +['Ġchoc', 'ia'] +['Ġchocia', 'ż'] +['Ġzob', 'ac'] +['Ġzobac', 'zyÄĩ'] +['пÑĢ', 'Ñı'] +['пÑĢÑı', 'жен'] +['ĠÑĨ', 'иÑĦ'] +['ĠÑĨиÑĦ', 'ÑĢ'] +['Ġм', 'ам'] +['Ġвз', 'ÑıÑĤÑĮ'] +['Ġch', 'ạm'] +['ج', 'سÙħ'] +['ØŃÙħ', 'اس'] +['à¹Ģล', 'à¹Īม'] +['à¸ŀิ', 'ษ'] +['×Ķפ', '׼×ķ'] +['à¸Ĭà¹Īà¸Ńà¸ĩ', 'à¸Ĺาà¸ĩ'] +['Ġв', 'ек'] +['Ġвек', 'а'] +['Æ¡', 'Ìģ'] +['Æ¡Ìģ', 'i'] +['ĠTi', 'á»ģn'] +['Ġtr', 'ầm'] +['мÑĭ', 'ÑĪ'] +['мÑĭÑĪ', 'л'] +['ĠÑĤ', 'Ñĥ'] +['ĠÑĤÑĥ', 'ÑĢиÑģÑĤ'] +['Ġch', 'c'] +['Ġchc', 'Äħ'] +['Ġав', 'г'] +['Ġавг', 'ÑĥÑģÑĤ'] +['ĠавгÑĥÑģÑĤ', 'а'] +['ס', '×IJ×ķת'] +['Ġר', '×Ĵ׾'] +['à¸ľà¸¥', 'à¸ģระà¸Ĺ'] +['à¸ľà¸¥à¸ģระà¸Ĺ', 'à¸ļ'] +['å¤īãĤı', 'ãĤĭ'] +['Ġ×Ķ×IJ×Ĺר', '×ķ׳×Ļ×Ŀ'] +['سÙģ', 'ÙĬر'] +['ĠÑĩа', 'Ñīе'] +['ãģĦ', 'ãĤī'] +['ãģĦãĤī', 'ãģ£'] +['ãģĦãĤīãģ£', 'ãģĹãĤĥ'] +['×ķ×ŀ', '׳×Ļ×Ŀ'] +['Ġart', 'tır'] +['ĠCh', 'á»ĭ'] +['Ġì¡°', 'ì§ģ'] +['ĠÑĥÑģп', 'еÑħ'] +['Ġ×¢', '×ķס'] +['Ġ×¢×ķס', '×§'] +['ĠìĥĿ', 'ëªħ'] +['ÑĨ', 'иÑĤ'] +['Ġreg', 'ión'] +['Ðŀ', 'ÐĿ'] +['ĠdoÄŁ', 'um'] +['ĠyaÅŁ', 'ad'] +['ĠyaÅŁad', 'ıģı'] +['à¸Ĺà¸Ķ', 'ลà¸Ńà¸ĩ'] +['Ġgöz', 'ü'] +['ש', '×Ļר×Ķ'] +['дÑĥм', 'ал'] +['Ġda', 'ģı'] +['Ġdaģı', 't'] +['à¸Ĺีม', 'à¸ĩาà¸Ļ'] +['Ġti', 'á»ģm'] +['ĠاÙĦÙĥ', 'بر'] +['ĠاÙĦÙĥبر', 'Ùī'] +['ì¹', 'Ń'] +['ĠGü', 'nc'] +['ĠGünc', 'elle'] +['ĠGüncelle', 'me'] +['ê¹', 'Ĭ'] +['ĠобоÑĢÑĥд', 'ование'] +['ĠÑĢеÑĪ', 'а'] +['á»', '¤'] +['Ġп', 'иÑĤ'] +['ĠпиÑĤ', 'аниÑı'] +['à¹Ģรีย', 'à¸ļ'] +['×Ľ×ª', '×Ļ×ij×Ķ'] +['Ġп', 'он'] +['Ġпон', 'ÑĢав'] +['ĠпонÑĢав', 'и'] +['Ġ×Ķ', '×ķ׾×ĵ'] +['Ġ×Ķ×ķ׾×ĵ', 'ת'] +['Ġê²', 'ģ'] +['Ġê²ģ', 'ëĭĪëĭ¤'] +['ĠпеÑĢв', 'ой'] +['ãĥ©ãĤ¤', 'ãĥķ'] +['ĠÅŁi', 'ir'] +['kr', 'ÄĻ'] +['krÄĻ', 'c'] +['Ġthi', 'á»ĥu'] +['à¹Ģลย', 'à¸Ĺี'] +['à¹Ģลยà¸Ĺี', 'à¹Ģà¸Ķียว'] +['×ĺ×¢', '׳×ķת'] +['ائ', 'ÙĩÙħ'] +['Ġ×IJ', 'ס×ķר'] +['ĠплаÑĤ', 'еж'] +['تر', 'دد'] +['Ġmożli', 'we'] +['Ġkh', 'Ỽ'] +['ĠkhỼ', 'p'] +['تÙģØ§Ø¹', 'ÙĦ'] +['ĠÑĪ', 'колÑĮ'] +['ĠÑĪколÑĮ', 'н'] +['ĠÙĤ', 'صة'] +['Ġmét', 'ier'] +['nÄĻ', 'ÅĤa'] +['หล', 'à¹Īà¸Ń'] +['Ġ', 'á»§ng'] +['Ġprz', 'egl'] +['Ġprzegl', 'Äħd'] +['ĠاÙĦÙħ', 'تعÙĦ'] +['ĠاÙĦÙħتعÙĦ', 'ÙĤØ©'] +['ĠÑģÑĭ', 'н'] +['Ġв', 'олн'] +['ãĥĩ', 'ãĥ¼ãĥĪ'] +['ĠÐŃ', 'ÑĤи'] +['Ġк', 'ÑĢоме'] +['à¸Ħ', 'ารà¹Į'] +['׳ק', '×ķ×ĵ×Ķ'] +['Ġ׾ש×ŀ', '×ķ×¢'] +['Ġ×ĸ', '×ķ׼ר'] +['ï¼', '§'] +['ÙĬ', 'ÙİØ§'] +['Ġgi', 'á»ıi'] +['åĥį', 'ãģı'] +['ĠÑģ', 'ни'] +['ĠÑģни', 'жен'] +['à¹ģà¸Ķ', 'à¸Ķ'] +['รุ', 'à¸Ļ'] +['รุà¸Ļ', 'à¹ģรà¸ĩ'] +['Ġhi', 'á»ĩp'] +['ograf', 'ÃŃa'] +['à¹Ģà¸Ī', 'à¸Ńรà¹Į'] +['Ġдв', 'иг'] +['Ġдвиг', 'аÑĤ'] +['ĠдвигаÑĤ', 'ел'] +['Ġü', 'y'] +['Ġüy', 'eler'] +['Ġüyeler', 'i'] +['Ġб', 'Ñĥк'] +['ĠбÑĥк', 'в'] +['ãĤĤ', 'å¤ļãģı'] +['Ġthi', 'á»ĩt'] +['ĠPa', 'ÃŃs'] +['ĠØ·', 'بÙĬعÙĬ'] +['à¹ģà¸Ī', 'à¸ģ'] +['ĠاÙĦص', 'ØŃÙĬØŃ'] +['Ġapp', 'ré'] +['Ġappré', 'ci'] +['Ġdecis', 'ión'] +['Ġë°ĺ', 'ëĵľ'] +['Ġë°ĺëĵľ', 'ìĭľ'] +['ĠÑĤеб', 'е'] +['ãĤ·', 'ãĥ¼ãĤº'] +['ãĤ·ãĥ¼ãĤº', 'ãĥ³'] +['Ġд', 'алÑĮн'] +['ĠìĬ', '¤'] +['ĠìĬ¤', 'ìĬ¤'] +['ĠìĬ¤ìĬ¤', 'ë¡ľ'] +['ĠTh', 'á»ĥ'] +['Ġkar', 'ÅŁ'] +['ĠkarÅŁ', 'ıs'] +['ĠkarÅŁÄ±s', 'ında'] +['ĠK', 'ön'] +['ĠKön', 'ig'] +['ив', 'ание'] +['×ij', '×ķצע'] +['г', 'лаÑģ'] +['Ġtw', 'ó'] +['Ġtwó', 'rc'] +['à¸Ľà¸ģ', 'à¸Ħร'] +['à¸Ľà¸ģà¸Ħร', 'à¸Ńà¸ĩ'] +['ĠG', 'ÅĤ'] +['ĠGÅĤ', 'ówn'] +['ĠUnter', 'stüt'] +['ĠUnterstüt', 'zung'] +['Ġд', 'ÑĥÑħ'] +['ĠдÑĥÑħ', 'ов'] +['Ø£', 'ÙħاÙĨ'] +['×Ĺש', 'ש'] +['ت', 'ظ'] +['تظ', 'اÙĩر'] +['ĠлÑİб', 'ом'] +['à¸ķ', 'าร'] +['à¸ķาร', 'าà¸ĩ'] +['Ġkr', 'ól'] +['Ø£', 'ØŃدث'] +['ì¡Į', 'ëĭ¤'] +['Ðļ', 'ÑĥÑĢÑģ'] +['ãĥĥ', 'ãĥĦ'] +['×ŀ×§', '×ķ×ij׾'] +['ĠÑģимв', 'ол'] +['Ġdés', 'orm'] +['Ġdésorm', 'ais'] +['w', 'üns'] +['wüns', 'che'] +['Ñĥ', 'ни'] +['Ñĥни', 'ÑĨип'] +['ÑĥниÑĨип', 'алÑĮн'] +['หลัà¸ģ', 'สูà¸ķร'] +['ÙĨت', 'شر'] +['Ġа', 'л'] +['Ġал', 'к'] +['Ġалк', 'ог'] +['Ġалког', 'ол'] +['ĠÑĥ', 'ÑĩиÑĤÑĭва'] +['à¸ģำ', 'à¸ģัà¸ļ'] +['Ġ׾', 'פע×ķ׾'] +['ĠìŰ', 'ê²°'] +['s', 'Äħd'] +['ĠاÙĦØ£', 'ÙĬ'] +['ĠاÙĦØ£ÙĬ', 'اÙħ'] +['غÙĬ', 'اب'] +['Ġна', 'ÑĢ'] +['ĠнаÑĢ', 'ко'] +['×ŀ×ķ×ĵ', '×¢'] +['ĠÑģеÑĢ', 'ии'] +['пиÑģ', 'Ñĭва'] +['สิ', 'ว'] +['ç¶ļ', 'ãģĦãģ¦'] +['çͳãģĹ', 'è¾¼ãģ¿'] +['Ġ׾', '×Ĵר'] +['Ġ׾×Ĵר', '×ķ×Ŀ'] +['Ġд', 'ем'] +['Ġдем', 'о'] +['Ġë³´', 'ëĤ´'] +['تÙĩ', 'دÙĬد'] +['ĠÙħØ´', 'ÙĬرا'] +['Ġdu', 'y'] +['Ġduy', 'á»ĩt'] +['ĠwiÄĻks', 'ze'] +['Ùħع', 'اÙĬ'] +['ÙħعاÙĬ', 'ÙĬر'] +['ĠG', 'da'] +['ĠGda', 'ÅĦsk'] +['Ġr', 'ah'] +['Ġrah', 'ats'] +['Ġrahats', 'ız'] +['ר', '×ķצ×Ķ'] +['l', 'ös'] +['lös', 'ung'] +['ĠТак', 'им'] +['ÑĪ', 'ед'] +['ÑĪед', 'ÑĪ'] +['ع', 'زÙĦ'] +['Ġרש', '×Ļ×ŀת'] +['Ġ׾×Ķ', '×Ļ׼'] +['Ġ׾×Ķ×Ļ׼', '×ł×¡'] +['Ġп', 'ÑĥÑĤ'] +['ĠпÑĥÑĤ', 'еÑĪ'] +['ĠпÑĥÑĤеÑĪ', 'еÑģÑĤв'] +['Ġnot', 'ÃŃcia'] +['Ġal', 'Ä±ÅŁ'] +['ĠalÄ±ÅŁ', 'ver'] +['ĠalÄ±ÅŁver', 'iÅŁ'] +['ĠwÅĤ', 'os'] +['ĠwÅĤos', 'ów'] +['Ġب', 'غ'] +['Ġبغ', 'داد'] +['Ġver', 'öffent'] +['Ġveröffent', 'licht'] +['ĠKh', 'á'] +['Ġt', 'án'] +['ëIJĺ', '기'] +['Ġë°©', '문'] +['Ùģ', 'ÙĬÙĦ'] +['à¹Ģà¸ģิà¸Ķ', 'à¸Īาà¸ģ'] +['åı¯', 'æĦĽ'] +['åı¯æĦĽ', 'ãģĦ'] +['à¸ĸ', 'ุà¸ĩ'] +['Ġz', 'ewnÄĻtrzn'] +['à¸łà¸²à¸©à¸²', 'à¸Ńัà¸ĩà¸ģฤษ'] +['Ġmá', 'xima'] +['Ġul', 'us'] +['Ġulus', 'lararası'] +['Ġ׳×Ķ', '׳'] +['à¸Ĥà¹Īาว', 'สาร'] +['ĠìĿĺ', 'ìĤ¬'] +['à¹Ģหล', 'ืà¸Ńà¸ĩ'] +['Ġد', 'ÙĤ'] +['ĠدÙĤ', 'ائÙĤ'] +['สืà¹Īà¸Ń', 'สาร'] +['ë¨', '¼'] +['ĠÑģоÑģÑĤоÑı', 'нии'] +['สมา', 'à¸Ħม'] +['á»', 'Ĥ'] +['ĠÐľÐ¾Ñģ', 'ков'] +['ĠÐľÐ¾Ñģков', 'Ñģк'] +['×ŀס', '×ķ×Ĵ׾'] +['ãģĭ', 'ãģĭãĤĬ'] +['ĠTr', 'uyá»ģn'] +['à¹ģà¸Ĥà¹ĩà¸ĩ', 'à¹ģรà¸ĩ'] +['×ŀ×Ĺ', '×ĸ×Ļ×§'] +['à¹Ĥà¸ģ', 'à¹ī'] +['ÙĬس', 'ر'] +['ìĶ', '©'] +['×IJ', '×ķ×§'] +['×IJ×ķ×§', '×ĺ'] +['×IJ×ķ×§×ĺ', '×ķ×ijר'] +['Ġprox', 'imité'] +['ÙħÙĨ', 'Ùĩج'] +['ĠاÙĦج', 'ز'] +['ĠاÙĦجز', 'ائ'] +['ĠاÙĦجزائ', 'رÙĬ'] +['ĠÄIJi', 'á»ĥm'] +['Ġден', 'еж'] +['Ġденеж', 'н'] +['ÙģØŃ', 'ص'] +['Ùģ', 'ئ'] +['ĠÐij', 'Ñĥд'] +['×Ĵ×Ļ×ĵ', '×ķ׾'] +['ĠÐĴ', 'едÑĮ'] +['عÙĦ', 'اÙħØ©'] +['Ġ×IJ×Ĺר', '×ķ׳×ķת'] +['ãģĦãģŁãģł', 'ãģĦãģ¦'] +['سÙĦ', 'ØŃ'] +['ØŃ', 'ÙĦÙħ'] +['ز', 'ÙĪØ§Ø±'] +['Ùĥ', 'سر'] +['×ĺ', 'קס'] +['Ġб', 'ан'] +['Ġбан', 'ков'] +['ĠпÑĢ', 'ож'] +['ĠпÑĢож', 'ива'] +['li', 'wo'] +['liwo', 'ÅĽci'] +['ĠTi', 'ếp'] +['ĠاÙĦÙħÙĨ', 'اسب'] +['ĠاÙĦØ®', 'ÙĬار'] +['ãģĬ', 'ãģĭ'] +['ãģĬãģĭ', 'ãģĴ'] +['à¸Ķà¸Ńà¸ģ', 'à¹Ħมà¹ī'] +['ä', 'mp'] +['ämp', 'fe'] +['à¸ķัà¹īà¸ĩ', 'à¹ĥà¸Ī'] +['Ġза', 'ÑīиÑĤ'] +['ĠзаÑīиÑĤ', 'Ñĭ'] +['ĠTh', 'ưá»Ŀng'] +['Ġص', 'Ùģ'] +['ĠصÙģ', 'ØŃØ©'] +['×Ĺ×ķר', '×£'] +['ãĥIJ', 'ãĥĥãĤ°'] +['Ġ×ĵ', '×Ļ×Ĵ'] +['Ġ×ĵ×Ļ×Ĵ', '×Ļ×ĺ'] +['Ġ×ĵ×Ļ×Ĵ×Ļ×ĺ', '׾×Ļ'] +['Ġ×Ķ×Ĺ', '×ķ׾×Ļ×Ŀ'] +['в', 'еÑī'] +['веÑī', 'а'] +['Ġк', 'ÑĥлÑĮÑĤ'] +['ĠкÑĥлÑĮÑĤ', 'Ñĥ'] +['ĠкÑĥлÑĮÑĤÑĥ', 'ÑĢÑĭ'] +['ĠاÙĦاÙĨ', 'ترÙĨت'] +['Ġhö', 'ch'] +['Ġhöch', 'st'] +['Ġíĺ', 'ķ'] +['Ġíĺķ', 'íĥľ'] +['Ġв', 'ой'] +['Ġвой', 'нÑĭ'] +['ÐĽ', 'Ðŀ'] +['ìĭł', 'ìļ©'] +['Ġ×ŀ×ij', '×ķס'] +['Ġ×ŀ×ij×ķס', 'ס'] +['×ŀ׳', '×Ļ×¢'] +['Ġfiyat', 'ı'] +['ĠÑģл', 'Ñĥж'] +['ĠÑģлÑĥж', 'бÑĭ'] +['à¸Ĺั', 'ศ'] +['à¸Ĺัศ', 'à¸Ļ'] +['ãģĵãģ¨ãģĮ', 'å¤ļãģĦ'] +['Ġ×Ķ×ŀש', 'ת'] +['Ġ×Ķ×ŀשת', '×ŀש'] +['å¯Ħ', 'ãģĽ'] +['×ŀש׾', '×ķ×Ĺ'] +['æĻĤ', 'çĤ¹'] +['æĻĤçĤ¹', 'ãģ§'] +['à¸ŀร', 'ี'] +['à¸ŀรี', 'à¹Ģมีย'] +['à¸ŀรีà¹Ģมีย', 'รà¹Į'] +['à¸ŀรีà¹Ģมียรà¹Į', 'ลีà¸ģ'] +['Ġdiffic', 'olt'] +['Ġdifficolt', 'Ãł'] +['ãĥ¬', 'ãĤ¹ãĥĪ'] +['ãĥ¬ãĤ¹ãĥĪ', 'ãĥ©ãĥ³'] +['สม', 'à¹Ģà¸Ķà¹ĩ'] +['สมà¹Ģà¸Ķà¹ĩ', 'à¸Ī'] +['Ġж', 'ид'] +['Ġжид', 'к'] +['Ġzu', 'peÅĤ'] +['ĠzupeÅĤ', 'nie'] +['ĠÙħ', 'جر'] +['ĠÙħجر', 'د'] +['ãģĮ', 'å§ĭ'] +['ãģĮå§ĭ', 'ãģ¾'] +['ãĤŃãĥ£', 'ãĥ©'] +['Ġ×IJ', '×ķ×ķ×Ļר'] +['ãģĬ', 'äºĴ'] +['ãģĬäºĴ', 'ãģĦ'] +['Ġpot', 'rÃł'] +['ĠPa', 'ÅĦst'] +['ĠPaÅĦst', 'wo'] +['Ġب', 'ÙĬاÙĨ'] +['ĠبÙĬاÙĨ', 'ات'] +['Ġин', 'огда'] +['ĠÑĢ', 'а'] +['ĠÑĢа', 'ÑģÑĤв'] +['ĠÑĢаÑģÑĤв', 'оÑĢ'] +['Ġ×ĸ', '×ŀ׳'] +['ยิ', 'à¹īม'] +['Ä', 'Ĩ'] +['ãģ¾', 'ãģķ'] +['ãģ¾ãģķ', 'ãģ«'] +['ãĥķãĤ¡', 'ãĤ¤ãĥ«'] +['Ġgörd', 'Ã¼ÄŁÃ¼'] +['สà¸ĩ', 'à¸Ħร'] +['สà¸ĩà¸Ħร', 'าม'] +['ĠArk', 'adaÅŁ'] +['ĠrozwiÄħz', 'ania'] +['×ŀ', '×ķ×ĺ'] +['pi', 'ÄĻ'] +['piÄĻ', 't'] +['ص', 'غر'] +['ส', 'ย'] +['สย', 'าม'] +['ãĤĨ', 'ãģ£ãģıãĤĬ'] +['Ġtr', 'ần'] +['Ġeconom', 'ÃŃa'] +['Ġgeh', 'ören'] +['ãĤ·ãĥ§', 'ãĥ¼'] +['ĠsÅĤ', 'ucha'] +['à¸ŀà¸Ń', 'à¹ĥà¸Ī'] +['ĠоÑĤмеÑĤ', 'ил'] +['ÙĨت', 'ÙĤÙĦ'] +['Ġprop', 'ósito'] +['ĠваÑĪ', 'его'] +['Ġnh', 'ắn'] +['à¹ģà¸ĸ', 'ว'] +['Ġком', 'иÑģ'] +['ĠкомиÑģ', 'Ñģи'] +['waż', 'nie'] +['Ġy', 'avaÅŁ'] +['×ŀ', '×Ļ×§'] +['×ŀ×Ļ×§', '×ķ×Ŀ'] +['ש×IJ׾', 'ת'] +['Ġyıll', 'arda'] +['ĠÐ', '®'] +['ĠЮ', 'ÑĢ'] +['×ł×¡', '×Ļ×ij×ķת'] +['ת', 'צ'] +['תצ', '×ķ×Ĵ'] +['Ġод', 'нÑĥ'] +['Ġ', 'à¸Ńยà¹Īาà¸ĩà¹Ħร'] +['Ġà¸Ńยà¹Īาà¸ĩà¹Ħร', 'à¸ģà¹ĩà¸ķาม'] +['ëģ', '¼'] +['à¹Ħล', 'à¹Ī'] +['تس', 'ÙĦÙĬÙħ'] +['بÙĦ', 'اغ'] +['Ġì', 'ī'] +['Ġìī', '½'] +['Ġìī½', 'ê²Į'] +['ãĥļ', 'ãĥ³'] +['зв', 'ÑĥÑĩ'] +['ĠW', 'äh'] +['ĠWäh', 'rend'] +['Ġ×Ļ', '×Ļת'] +['Ġ×Ļ×Ļת', '׼ף'] +['Ġkh', 'uyên'] +['Ġv', 'ẽ'] +['Ġа', 'меÑĢ'] +['ĠамеÑĢ', 'ик'] +['ĠамеÑĢик', 'ан'] +['ĠамеÑĢикан', 'Ñģк'] +['ع', 'جب'] +['ãĥĽãĥ¼ãĥł', 'ãĥļãĥ¼ãĤ¸'] +['Ġник', 'ÑĤо'] +['ĠÙĤ', 'Ùİ'] +['ĠÙĤÙİ', 'اÙĦ'] +['ĠÙĤÙİØ§ÙĦ', 'Ùİ'] +['ÐIJ', 'ÐĹ'] +['Ùħ', 'جÙħÙĪØ¹'] +['ÙħجÙħÙĪØ¹', 'ات'] +['Ġnecess', 'itÃł'] +['Ġpob', 'li'] +['Ġpobli', 'żu'] +['Ġph', 'ấn'] +['ĠСо', 'обÑī'] +['ÙħÙĤ', 'اط'] +['ÙħÙĤاط', 'ع'] +['Ġ×Ķצ', '×ķר×ļ'] +['la', 'ÅŁtırma'] +['ว', 'ิà¸Ķ'] +['วิà¸Ķ', 'ี'] +['วิà¸Ķี', 'à¹Ĥà¸Ń'] +['Ġ그리', 'ìĬ¤'] +['Ġ그리ìĬ¤', 'ëıĦ'] +['ãĤ¿ãĤ¤', 'ãĥŁ'] +['ãĤ¿ãĤ¤ãĥŁ', 'ãĥ³ãĤ°'] +['×§×ĺ', '×Ĵ×ķר'] +['×§×ĺ×Ĵ×ķר', '×Ļ×Ķ'] +['Ġ×Ĺ', '×ķפ'] +['Ġ×Ĺ×ķפ', 'ש×Ļ'] +['Ø£', 'جر'] +['Ġим', 'ени'] +['ĠÑĢан', 'ее'] +['à¹Ģà¸ŀืà¹Īà¸Ńà¸Ļ', 'à¹Ĩ'] +['ĠJes', 'ús'] +['Ñģо', 'един'] +['Ñģоедин', 'ен'] +['Ġר', '×Ĺ×ķ×§'] +['à¹Ĥà¸ļ', 'รา'] +['à¹Ĥà¸ļรา', 'à¸ĵ'] +['ĠH', 'Æ¡n'] +['Ġth', 'áºŃp'] +['تع', 'ÙĬÙĬÙĨ'] +['Ġtart', 'Ä±ÅŁ'] +['ĠtartÄ±ÅŁ', 'ma'] +['ĠGes', 'pr'] +['ĠGespr', 'äch'] +['תר', '×ķפ'] +['תר×ķפ', '×ķת'] +['Ġcat', 'égorie'] +['Ġоказ', 'Ñĭва'] +['ĠналиÑĩ', 'ие'] +['Ġprésent', 'é'] +['Ġk', 'ull'] +['Ġkull', 'and'] +['Ġkulland', 'ı'] +['Ġü', 'nl'] +['Ġünl', 'ü'] +['ĠÙģ', 'Ùĥرة'] +['из', 'аÑĤоÑĢ'] +['×IJ', '×ķ׳'] +['×IJ×ķ׳', '×Ļ×ij'] +['×IJ×ķ׳×Ļ×ij', 'רס'] +['×IJ×ķ׳×Ļ×ijרס', '×Ļ×ĺת'] +['ĠÑĢаÑģÑģ', 'маÑĤ'] +['ĠÑĢаÑģÑģмаÑĤ', 'ÑĢ'] +['ĠÑĢаÑģÑģмаÑĤÑĢ', 'ива'] +['تÙĥÙĦ', 'Ùħ'] +['Ùĥت', 'رÙĪ'] +['ÙĥترÙĪ', 'ÙĨÙĬ'] +['ĠÑģо', 'ÑĩеÑĤ'] +['ĠÑģоÑĩеÑĤ', 'а'] +['ãĤĴè¦ĭ', 'ãģĽ'] +['Ġng', 'ừa'] +['ĠÐł', 'еÑģп'] +['ĠÐłÐµÑģп', 'Ñĥб'] +['ĠÐłÐµÑģпÑĥб', 'лик'] +['ãĤ¦', 'ãĤ©'] +['ãĤ¦ãĤ©', 'ãĥ¼'] +['ĠÐľ', 'еждÑĥ'] +['ĠìŀĪ', 'ê²Į'] +['Ġm', 'â'] +['ĠìļĶ', 'ì²Ń'] +['ض', 'ار'] +['ลุ', 'à¹īà¸Ļ'] +['ëĮĢ', 'íķĻêµIJ'] +['×ĸ', '×Ļ׼'] +['×ĸ×Ļ׼', 'ר×ķף'] +['ãĤ¹', 'ãĥļ'] +['ãĤ¹ãĥļ', 'ãĥ¼ãĤ¹'] +['ĠкÑĢаÑģ', 'оÑĤ'] +['ï¼', '¨'] +['ê¼', 'Ń'] +['ãĤĴ', 'éĽĨ'] +['ãĤĴéĽĨ', 'ãĤģ'] +['ë°', 'Ŀ'] +['Ġ×Ķ׳', '×IJ'] +['Ġ×Ķ׳×IJ', 'ש×Ŀ'] +['Ġê°Ģ', 'ìļ´'] +['Ġê°Ģìļ´', 'ëį°'] +['تÙĥÙĦ', 'Ù쨩'] +['ĠØŃ', 'ÙĤÙĬÙĤÙĬ'] +['Ġh', 'alk'] +['Ġhalk', 'ın'] +['ÑİÑī', 'ÑĥÑİ'] +['ĠÑģп', 'ин'] +['סר×ĺ', 'ף'] +['ĠпеÑĢв', 'ого'] +['Ġпол', 'ож'] +['Ġполож', 'иÑĤелÑĮн'] +['Ġд', 'л'] +['Ġдл', 'иÑĤелÑĮн'] +['ĠV', 'Ä©nh'] +['ê´', '´'] +['ĠÑģÑĭ', 'ÑĢ'] +['ĠíĨµ', 'íķĺìŬ'] +['ë³ij', 'ìĽIJ'] +['à¹Ĥรà¸ĩ', 'à¸ĩาà¸Ļ'] +['รัà¸ļ', 'à¸ľà¸´à¸Ķ'] +['รัà¸ļà¸ľà¸´à¸Ķ', 'à¸Ĭà¸Ńà¸ļ'] +['تج', 'ÙĨب'] +['s', 'ÅĤ'] +['sÅĤ', 'uch'] +['ãĤ¢ãĥ«', 'ãĥIJ'] +['ãĤ¢ãĥ«ãĥIJ', 'ãĥł'] +['ëī´', 'ìĬ¤'] +['Ġpat', 'ië'] +['Ġpatië', 'nt'] +['Ġìĺ', '¤í'] +['Ġìĺ¤í', 'ŀ'] +['Ġìĺ¤íŀ', 'Ī'] +['Ġìĺ¤íŀĪ', '볤'] +['ĠDer', 'ne'] +['ĠDerne', 'ÄŁi'] +['wró', 'ci'] +['wróci', 'Äĩ'] +['Ġоб', 'Ñī'] +['ĠобÑī', 'еÑģÑĤв'] +['ĠобÑīеÑģÑĤв', 'енно'] +['ĠêµIJ', 'ìĪĺ'] +['tıģ', 'ımız'] +['Ġ×Ķ×ŀש', '×Ļ×ij'] +['k', 'örper'] +['Ġпозв', 'ол'] +['Ġпозвол', 'иÑĤ'] +['ĠChi', 'ến'] +['أخ', 'ÙĪ'] +['ĠAy', 'dın'] +['à¸Ķà¹īาà¸Ļ', 'ล'] +['à¸Ķà¹īาà¸Ļล', 'à¹Īาà¸ĩ'] +['Ġdr', 'u'] +['Ġdru', 'ż'] +['Ġdruż', 'yn'] +['Ġë°ľ', 'íijľ'] +['ĠTh', 'ảo'] +['جÙĩ', 'اد'] +['à¸ģระà¸Ĺ', 'ูà¹ī'] +['Ġк', 'ÑĢов'] +['ĠкÑĢов', 'и'] +['Ġiçer', 'ik'] +['Ġnad', 'zie'] +['Ġnadzie', 'jÄĻ'] +['ĠС', 'моÑĤÑĢ'] +['Ġph', 'ức'] +['ج', 'تÙħاع'] +['جتÙħاع', 'ÙĬØ©'] +['ком', 'пон'] +['компон', 'енÑĤ'] +['Ġб', 'ил'] +['Ġбил', 'еÑĤ'] +['ãĥIJ', 'ãĥ³ãĥī'] +['ĠPol', 'ÃŃcia'] +['اÙĦ', 'تÙĩ'] +['اÙĦتÙĩ', 'اب'] +['ØŃر', 'Ùģ'] +['ت', 'خط'] +['تخط', 'ÙĬØ·'] +['ãĤ³', 'ãĥ¼ãĥ'] +['ãĤ³ãĥ¼ãĥ', 'Ĵ'] +['ãĤ³ãĥ¼ãĥĴ', 'ãĥ¼'] +['・・', 'ï½¥'] +['à¸ĭ', 'à¸Ńย'] +['Ġcréd', 'it'] +['è²·', 'ãģ£ãģŁ'] +['ĠпоÑĢ', 'Ñıд'] +['ĠпоÑĢÑıд', 'ке'] +['Ġph', 'ó'] +['Ġw', 'ida'] +['Ġwida', 'Äĩ'] +['جر', 'ائÙħ'] +['à¸ľ', 'ี'] +['ĠbÄĻd', 'ÄĻ'] +['Ġ×ŀ', 'פת×Ĺ'] +['ãĥij', 'ãĥ¼ãĥ'] +['ãĥijãĥ¼ãĥ', 'Ĩ'] +['ãĥijãĥ¼ãĥĨ', 'ãĤ£'] +['ãĥijãĥ¼ãĥĨãĤ£', 'ãĥ¼'] +['ĠKa', 'ż'] +['ĠKaż', 'dy'] +['ĠнеобÑħодим', 'оÑģÑĤи'] +['à¸Ł', 'à¸Ńรà¹Į'] +['à¸Łà¸Ńรà¹Į', 'ม'] +['Ġмал', 'ÑĭÑĪ'] +['Ġпл', 'оÑĤ'] +['ĠÑĥ', 'ÑģÑĤÑĢой'] +['ĠÑĥÑģÑĤÑĢой', 'ÑģÑĤва'] +['à¸ĸ', 'à¸Ńà¸Ļ'] +['ĠoluÅŁtur', 'ul'] +['ĠÅĽwi', 'ad'] +['ĠÅĽwiad', 'om'] +['Ùħع', 'Ùĩد'] +['ĠпÑĢоиз', 'веден'] +['Æ', 'ł'] +['ר', '×Ļש'] +['Ùħست', 'Ø«'] +['Ùħستث', 'Ùħر'] +['׳×Ļ', '×Ļר'] +['pa', 'ñ'] +['Ġ;', '-)'] +['Ġë°ľ', '견'] +['Ġgör', 'üyor'] +['Ùħؤ', 'ÙĦÙģ'] +['ĠÄIJ', 'á»ģ'] +['ĠاÙĦÙĨ', 'ÙĪØ§Ø¨'] +['×Ĺ×§', '×Ļר×Ķ'] +['Ġm', 'á»ıi'] +['è¿°', 'ãģ¹'] +['ÐĿ', 'ик'] +['ìŀĸ', 'ìķĦ'] +['ìŀĸìķĦ', 'ìļĶ'] +['prowadzi', 'ÅĤ'] +['l', 'óg'] +['lóg', 'ica'] +['פס', '×ĺ'] +['פס×ĺ', '×Ļ×ij׾'] +['Ġ×ŀ', '×ĵ×Ķ'] +['Ġ×ŀ×ĵ×Ķ', '×Ļ×Ŀ'] +['ãģĵãģĵ', 'ãģ¾ãģ§'] +['×Ķ', 'ת×Ĺ'] +['×Ķת×Ĺ', '׾×Ķ'] +['Ġפ', '×ķס'] +['Ġפ×ķס', '×ĺ×Ļ×Ŀ'] +['Ġн', 'ев'] +['Ġнев', 'оз'] +['Ġневоз', 'можно'] +['ĠdostÄĻp', 'ny'] +['Ġغ', 'اÙĦ'] +['ĠغاÙĦ', 'ب'] +['Ġbez', 'pieczeÅĦst'] +['ĠbezpieczeÅĦst', 'wa'] +['åĪĨ', 'ãģĭãĤĭ'] +['ĠF', 'ührung'] +['à¸ģ', 'ีà¹ī'] +['gem', 'Ã¤ÃŁ'] +['à¸Ĭà¹Īวà¸ĩ', 'à¹Ģวลา'] +['Ġìļ°ë¦¬', 'ëĤĺ'] +['Ġìļ°ë¦¬ëĤĺ', 'ëĿ¼'] +['ãģ¥', 'ãģıãĤĬ'] +['ĠاÙĦÙħ', 'سÙĦ'] +['ĠاÙĦÙħسÙĦ', 'ØŃØ©'] +['Ġlibert', 'é'] +['клÑİÑĩ', 'ение'] +['Ġzam', 'ów'] +['Ġzamów', 'ienia'] +['รà¸ĸ', 'à¹Ħà¸Ł'] +['Ø£', 'ÙģÙĦ'] +['Ø£ÙģÙĦ', 'اÙħ'] +['Ùħ', 'راج'] +['Ùħراج', 'عة'] +['Ġë¹Ħ', 'êµIJ'] +['ĠاÙĦت', 'اب'] +['ĠاÙĦتاب', 'عة'] +['Ġë§Į', 'ëĤĺ'] +['Ġб', 'Ñĥм'] +['ĠбÑĥм', 'аг'] +['Ġgé', 'nero'] +['Ġìŀĺ', '못'] +['×ŀ', 'פ×ķר×ĺ'] +['è²·ãģĦ', 'çī©'] +['ĠÙĦدÙĬ', 'Ùĥ'] +['Ġ×ľ×¢', '×Ļת'] +['Ġ×ľ×¢×Ļת', '×Ļ×Ŀ'] +['ĠsÅĤ', 'ab'] +['ĠпÑĢедÑģÑĤав', 'лÑı'] +['ãĤ¿', 'ãĤ¤ãĥĪ'] +['ãĤ¿ãĤ¤ãĥĪ', 'ãĥ«'] +['Ùħ', 'ص'] +['Ùħص', 'Ø·Ùģ'] +['ÙħصطÙģ', 'Ùī'] +['Ġdifficult', 'é'] +['ãĥĨãĤ£', 'ãĥĸ'] +['Ġpew', 'noÅĽci'] +['ĠpewnoÅĽci', 'Äħ'] +['Ġ무', 'ìĬ¨'] +['Ø¥', 'رس'] +['إرس', 'اÙĦ'] +['Ġд', 'алÑĮ'] +['ĠдалÑĮ', 'ÑĪе'] +['Ġ׾', '×ł×¡'] +['Ġ×ľ×ł×¡', '×ķת'] +['หมูà¹Ī', 'à¸ļà¹īาà¸Ļ'] +['×ŀס×ŀ', '׼×Ļ'] +['أسÙĦ', 'ÙĪØ¨'] +['Ġzw', 'ÅĤ'] +['ĠzwÅĤ', 'as'] +['ĠzwÅĤas', 'zc'] +['ĠzwÅĤaszc', 'za'] +['ĠпÑĢ', 'еж'] +['ĠпÑĢеж', 'де'] +['ĠоÑĢганиз', 'аÑĨиÑı'] +['Ġdön', 'emin'] +['Ġdönemin', 'de'] +['Ġ', 'Ủ'] +['ĠỦ', 'y'] +['ä¸ĭ', 'ãģĴ'] +['ĠпоÑģлед', 'ние'] +['Ġgü', 'ne'] +['Ġgüne', 'ÅŁ'] +['Ġ×IJ', '×ĸר'] +['Ġ×IJ×ĸר', '×Ĺ×Ļ'] +['ãģ§ãģĤ', 'ãĤįãģĨ'] +['ĠÙĨ', 'ÙĤ'] +['ĠÙĨÙĤ', 'اط'] +['æŃ£', 'ãģĹãģĦ'] +['ĠÑĢ', 'ег'] +['ĠÑĢег', 'иона'] +['ĠFör', 'der'] +['ê²½', 'ìĺģ'] +['dıkl', 'ar'] +['dıklar', 'ını'] +['trzym', 'aÄĩ'] +['أش', 'Ùĥ'] +['أشÙĥ', 'اÙĦ'] +['×Ķת', '×IJ'] +['×Ķת×IJ', '×ŀ×Ķ'] +['à¸Ĺำà¹ĥหà¹ī', 'à¹Ģà¸ģิà¸Ķ'] +['ĠGeb', 'ä'] +['ĠGebä', 'ude'] +['ĠСеÑĢ', 'г'] +['ĠСеÑĢг', 'ей'] +['Ġз', 'доÑĢов'] +['ĠздоÑĢов', 'ÑĮÑı'] +['Ġr', 'ãi'] +['ĠпÑĢед', 'ÑĥÑģ'] +['ĠпÑĢедÑĥÑģ', 'моÑĤÑĢ'] +['ĠпÑĢедÑĥÑģмоÑĤÑĢ', 'ен'] +['Ġ×Ķצ', '×Ļ×ij'] +['Ġ×Ķצ×Ļ×ij', '×ķר×Ļ'] +['Ġdés', 'ir'] +['Ġн', 'оÑĩ'] +['ĠноÑĩ', 'ÑĮ'] +['möglich', 'keiten'] +['Ġ×IJ×Ĺר', '×ķ׳×Ļ×Ŀ'] +['Ġsoir', 'ée'] +['ĠNh', 'áºŃn'] +['Ù', 'ª'] +['à¸Ľà¸£à¸°à¸§à¸±à¸ķิ', 'ศาสà¸ķรà¹Į'] +['êµIJ', 'íĨµ'] +['ĠØ£', 'Ø®ÙĬ'] +['Ġdé', 'cid'] +['Ġdécid', 'é'] +['Ġwy', 'ja'] +['Ġwyja', 'ÅĽni'] +['Ġ', 'สิ'] +['Ġสิ', 'à¸ĩ'] +['Ġสิà¸ĩ', 'หา'] +['Ġสิà¸ĩหา', 'à¸Ħม'] +['à¹ģ', 'à¸Ńรà¹Į'] +['หà¸Ļà¹īา', 'à¸Īà¸Ń'] +['ס', 'תר'] +['Ġê', '¶'] +['Ġê¶', 'Į'] +['Ġê¶Į', '리'] +['pl', 'ätze'] +['ب', 'Ø·ÙĦ'] +['ê±´', 'ìĦ¤'] +['Ġ×IJ', '×Ļ×ŀ×Ļ'] +['Ġ×IJ×Ļ×ŀ×Ļ', '×Ļ׾'] +['ãģ', '½'] +['تر', 'اث'] +['×IJ׾', '×Ļ×ŀ×ķת'] +['Ġdispon', 'ÃŃveis'] +['Ġz', 'ale'] +['Ġzale', 'ży'] +['à¸Ľà¸£à¸°à¸Ĭา', 'สัมà¸ŀัà¸Ļà¸ĺà¹Į'] +['ĠÅļw', 'iat'] +['Ġpor', 'ówn'] +['Ġporówn', 'a'] +['Ġ׾×ĺ', '×ķ×ijת'] +['×Ķ×ĸ', '×ŀ׳×Ķ'] +['Ġ×Ľ×ª', '×ķצ×IJ×Ķ'] +['Ġ×ij', 'ק׾'] +['Ġ×ijק׾', '×ķת'] +['ĠоÑĤ', 'кÑĢ'] +['ĠоÑĤкÑĢ', 'Ñĭва'] +['ãĥij', 'ãĥ¯ãĥ¼'] +['ë¿IJ', 'ë§Į'] +['Ġв', 'ÑģÑı'] +['ĠвÑģÑı', 'к'] +['ãģ¨ãģª', 'ãģ£ãģ¦ãģĦãĤĭ'] +['Ġgi', 'áºŃn'] +['Ġок', 'ÑĢÑĥ'] +['ĠокÑĢÑĥ', 'жа'] +['ĠокÑĢÑĥжа', 'ÑİÑī'] +['ĠUnivers', 'ität'] +['ĠÑĢ', 'ож'] +['ĠÑĢож', 'д'] +['ĠÑĢожд', 'ениÑı'] +['Ø®', 'ÙĬÙĦ'] +['Ġкомпани', 'й'] +['ĠÑĢазлиÑĩ', 'нÑĭе'] +['ĠЦ', 'ена'] +['׳×Ļ', '×ķ×ĸ'] +['׳×Ļ×ķ×ĸ', '׾'] +['׳×Ļ×ķ×ĸ׾', '×ĺר'] +['Ġê³µ', 'ê°Ħ'] +['Ġê°ľ', 'ëħIJ'] +['landır', 'ma'] +['ĠÑĥдал', 'ен'] +['à¸ŀัà¸ģ', 'à¸ľ'] +['à¸ŀัà¸ģà¸ľ', 'à¹Īà¸Ńà¸Ļ'] +['Ġprote', 'cción'] +['Ġb', 'ÅĤ'] +['ĠbÅĤ', 'ÄĻd'] +['Ã', 'Ī'] +['Ġíĸī', 'ë³µ'] +['ĠÅŁ', 'ü'] +['ĠÅŁÃ¼', 'phe'] +['Ġí', 'Ķ'] +['ĠíĶ', '¼'] +['Ġíͼ', 'íķ´'] +['Ġëĭ¤', '르'] +['à¹Ħมà¹Ī', 'à¹Ģà¸ģิà¸Ļ'] +['ãģ¿', 'ãģª'] +['ãģ¿ãģª', 'ãģķãĤĵ'] +['ĠпоÑĤ', 'ÑĢеб'] +['ĠпоÑĤÑĢеб', 'иÑĤел'] +['ĠاÙĦÙĥÙĦ', 'اÙħ'] +['ìķĦ', 'ë²Ħ'] +['ìķĦë²Ħ', 'ì§Ģ'] +['ãĤĴ使', 'ãģ£ãģŁ'] +['Ġbụ', 'i'] +['ĠпоÑĤ', 'еÑĢ'] +['ĠпоÑĤеÑĢ', 'Ñı'] +['ĠØ¢', 'ÙĦاÙģ'] +['ĠнаÑģÑĤоÑıÑī', 'ее'] +['ãģıãģªãĤĬ', 'ãģ¾ãģĹãģŁ'] +['clus', 'ão'] +['ãĤ³', 'ãĥĶãĥ¼'] +['צ', 'פ×Ļ'] +['צפ×Ļ', '×Ļ×Ķ'] +['Ø®', 'ÙĦا'] +['Ø®ÙĦا', 'ص'] +['ล', 'à¹īำ'] +['ãĥ¯', 'ãĤ¤ãĥ³'] +['Ġมี', 'à¸Ļา'] +['Ġมีà¸Ļา', 'à¸Ħม'] +['Ø´', 'خص'] +['شخص', 'ÙĬات'] +['Ġ×ĸ', '×§'] +['Ġ×ĸ×§', '×ķ×§'] +['×Ļ', '×Ļצ'] +['×Ļ×Ļצ', '×Ĵ'] +['èĢĥãģĪ', 'æĸ¹'] +['Ġürün', 'ü'] +['ĠиÑģп', 'ол'] +['ĠиÑģпол', 'ни'] +['Ġcompañ', 'ero'] +['×§', 'צ×Ķ'] +['×ŀ×¢', '׳×Ļ×§'] +['Ùħ', 'ØŃÙħد'] +['Ġc', 'ámara'] +['Ġп', 'ед'] +['Ġпед', 'аг'] +['Ġпедаг', 'ог'] +['м', 'аÑĢ'] +['маÑĢ', 'к'] +['×Ķת', '׳×Ĵ×ĵ'] +['ĠìĨĮ', 'ê°ľ'] +['Ġcom', 'unitÃł'] +['ê³', '¤'] +['ĠNg', 'Ãłi'] +['สà¸ĩ', 'à¸ļ'] +['ĠmieszkaÅĦ', 'ców'] +['ĠÙĨ', 'ÙĩائÙĬ'] +['iv', 'ité'] +['Ġи', 'де'] +['Ġиде', 'алÑĮн'] +['ĠØ£', 'سبÙĪØ¹'] +['Ġ×Ļ', '×¢×ľ'] +['Ġ׾', 'ר×IJש'] +['Ġ׾ר×IJש', '×ķ׳×Ķ'] +['ĠзапиÑģ', 'и'] +['ĠкоÑĢ', 'пÑĥÑģ'] +['วà¸ĩ', 'ศ'] +['วà¸ĩศ', 'à¹Į'] +['ĠÐĶ', 'м'] +['ĠÐĶм', 'иÑĤ'] +['ĠÐĶмиÑĤ', 'ÑĢ'] +['Ġkön', 'nt'] +['Ġböl', 'ges'] +['Ġbölges', 'inde'] +['׼', '×Ļ׼'] +['׼×Ļ׼', 'ר'] +['ĠاÙĦØ¥', 'Ø«ÙĨ'] +['ĠاÙĦإثÙĨ', 'ÙĬÙĨ'] +['Ġng', 'á»Ļ'] +['ì¹', 'ł'] +['د', 'راج'] +['Ġu', 'da'] +['Ġuda', 'ÅĤo'] +['ìº', 'IJ'] +['بر', 'ÙĨاÙħج'] +['ĠÑģÑĥд', 'еб'] +['ĠÑģÑĥдеб', 'н'] +['Ġzun', 'ächst'] +['ĠEduc', 'ación'] +['ãģ¨ãģª', 'ãģ£ãģ¦ãģĦãģ¾ãģĻ'] +['Ġ×Ķ×IJ', '×ŀ×Ļת×Ļ'] +['Ġİ', 'nt'] +['Ġİnt', 'ernet'] +['ĠcaÅĤ', 'ego'] +['ãĥĹãĥª', 'ãĥ³'] +['Ø¥', 'بد'] +['إبد', 'اع'] +['ĠпоÑĢ', 'ÑĤал'] +['à¹Ĥà¸ķ', 'à¹ī'] +['Ġ×Ķ×§', 'ש×ķר'] +['пл', 'од'] +['ĠÙħ', 'د'] +['ĠÙħد', 'رÙĬد'] +['×ŀסע', '×ĵ×Ķ'] +['ĠØ´ÙĬ', 'ئ'] +['ĠØ´ÙĬئ', 'ا'] +['à¸ģà¹Īà¸Ń', 'สรà¹īาà¸ĩ'] +['Ġì°¸', 'ê³ł'] +['à¹Ģà¸Ĺ', 'ร'] +['à¹Ģà¸Ĺร', 'à¸Ķ'] +['Ġ×ij×ŀ', 'קר×Ļ×Ŀ'] +['Ġb', 'ât'] +['Ġbât', 'iment'] +['åij¼', 'ãģ³'] +['ç´ł', 'æķµ'] +['ç´łæķµ', 'ãģª'] +['przedsiÄĻbior', 'st'] +['przedsiÄĻbiorst', 'w'] +['Ġ×ł×ª', '×ķ׳×Ļ×Ŀ'] +['×Ĺ׾', '×ķ×Ŀ'] +['ร', 'วย'] +['Ùħ', 'ÙĪØ¶ÙĪØ¹'] +['ĠÑģоб', 'ÑĢан'] +['вед', 'ÑĥÑī'] +['ĠÑĤе', 'аÑĤ'] +['ĠÑĤеаÑĤ', 'ÑĢ'] +['m', 'eye'] +['meye', 'ceÄŁi'] +['Ġpien', 'iÄħ'] +['ĠpieniÄħ', 'd'] +['ĠpieniÄħd', 'ze'] +['ÑĢез', 'иденÑĤ'] +['ØŃ', 'صر'] +['ìĺ', '¥'] +['à¹Ģย', 'ืà¸Ńà¸Ļ'] +['ĠÑĥ', 'ни'] +['ĠÑĥни', 'веÑĢ'] +['ĠÑĥнивеÑĢ', 'Ñģ'] +['ĠÑĥнивеÑĢÑģ', 'иÑĤеÑĤ'] +['ĠاÙĦر', 'ØŃ'] +['ĠاÙĦرØŃ', 'ÙħÙĨ'] +['ĠÑĤеÑħ', 'нолог'] +['ĠÑĤеÑħнолог', 'ии'] +['ìĹIJ', 'ëĦĪ'] +['ìĹIJëĦĪ', 'ì§Ģ'] +['Ġíķ', 'Ń'] +['ĠíķŃ', 'ìĥģ'] +['à¸ĺ', 'า'] +['à¸ĺา', 'à¸ķุ'] +['ĠEspañ', 'ol'] +['×ĵ×Ĵ', 'ש'] +['Ġêµ', 'ī'] +['Ġêµī', 'ìŀ¥'] +['Ġêµīìŀ¥', 'íŀĪ'] +['ĠÅĤ', 'at'] +['ĠÅĤat', 'wo'] +['Ġk', 'á»ĭch'] +['Ø¥', 'ز'] +['إز', 'اÙĦØ©'] +['ĠдейÑģÑĤв', 'ие'] +['ĠsaÄŁ', 'layan'] +['สุà¸Ķ', 'ยà¸Ńà¸Ķ'] +['Ġzosta', 'Äĩ'] +['Ġdispon', 'ÃŃvel'] +['ïº', 'į'] +['ver', 'ständ'] +['verständ', 'lich'] +['tw', 'or'] +['twor', 'zyÄĩ'] +['ع', 'جز'] +['à¹Ģà¸Ĥ', 'à¹īม'] +['ยà¹Ī', 'à¸Ńม'] +['Ġstrat', 'ég'] +['Ġstratég', 'ie'] +['à¸ľà¸¥', 'à¹Ħมà¹ī'] +['Ġê°ģ', 'ì¢ħ'] +['ĠÙħ', 'ÙĪØ§'] +['ĠÙħÙĪØ§', 'ض'] +['ĠÙħÙĪØ§Ø¶', 'ÙĬع'] +['اØŃ', 'تج'] +['اØŃتج', 'اج'] +['Ġ', 'Ấ'] +['ĠẤ', 'n'] +['×ŀ', '×ŀש׾×Ķ'] +['ĠÅŁek', 'il'] +['×ŀ', '×Ĺ׾'] +['×ŀ×Ĺ׾', '×ķת'] +['Ġ', 'à¸ĺ'] +['Ġà¸ĺ', 'ัà¸Ļ'] +['Ġà¸ĺัà¸Ļ', 'วา'] +['Ġà¸ĺัà¸Ļวา', 'à¸Ħม'] +['Ġìĭ¤', 'ìłľ'] +['Ġìĭ¤ìłľ', 'ë¡ľ'] +['ì¤ij', 'ìķĻ'] +['ëįĶ', 'ëĿ¼'] +['ĠÑĪ', 'иÑĢ'] +['ĠÑĪиÑĢ', 'око'] +['Ġsol', 'ución'] +['วาà¸ĩ', 'à¹ģà¸ľà¸Ļ'] +['×IJ×ķ×ĺ', '×ķ×ŀ'] +['×IJ×ķ×ĺ×ķ×ŀ', '×ĺ×Ļ'] +['ĠÑĢ', 'еÑģÑĤ'] +['ĠÑĢеÑģÑĤ', 'оÑĢ'] +['ĠÑĢеÑģÑĤоÑĢ', 'ан'] +['ëį', '¸'] +['ÑĤ', 'ÑĢад'] +['ÑĤÑĢад', 'и'] +['ÑĤÑĢади', 'ÑĨион'] +['ÑĤÑĢадиÑĨион', 'н'] +['มะ', 'à¹Ģรà¹ĩ'] +['มะà¹Ģรà¹ĩ', 'à¸ĩ'] +['à¹Ĥ', 'ส'] +['Ġol', 'masını'] +['×ŀ×ķס', 'ר'] +['ĠоÑĤноÑĪ', 'ении'] +['Ġê°ĢëĬ¥', 'ìĦ±'] +['Ġy', 'uk'] +['Ġyuk', 'arı'] +['ìĨ', 'Ķ'] +['ĠÑģ', 'ÑĦ'] +['ĠÑģÑĦ', 'еÑĢе'] +['Ġ×§', '×ķפ'] +['ãĤ±', 'ãĥ¼ãĤ'] +['ãĤ±ãĥ¼ãĤ', 'Ń'] +['âĢķ', 'âĢķ'] +['ĠاÙĦØ£', 'ÙĦÙħ'] +['ĠاÙĦØ£ÙĦÙħ', 'اÙĨÙĬ'] +['Ả', 'N'] +['ת×ķ׼', '׳×Ļ×ķת'] +['ĠÑģÑĥÑīеÑģÑĤв', 'ÑĥеÑĤ'] +['æĪij', 'ãĢħ'] +['ĠاÙĦص', 'ادر'] +['ĠTr', 'á»įng'] +['Ġа', 'д'] +['Ġад', 'миниÑģÑĤ'] +['ĠадминиÑģÑĤ', 'ÑĢа'] +['ĠадминиÑģÑĤÑĢа', 'ÑĨи'] +['ĠдÑĢÑĥг', 'ими'] +['Ñģп', 'еÑĪ'] +['عÙĦاÙħ', 'ات'] +['Ġа', 'б'] +['Ġаб', 'Ñģол'] +['ĠабÑģол', 'ÑİÑĤ'] +['ĠабÑģолÑİÑĤ', 'но'] +['ฤ', 'à¸Ķู'] +['é', 'tr'] +['étr', 'anger'] +['нÑı', 'ÑĤи'] +['нÑıÑĤи', 'е'] +['×¢', '×ķ׳'] +['×¢×ķ׳', 'ש'] +['ĠÙĤ', 'ائ'] +['ĠÙĤائ', 'ÙĦا'] +['Ġм', 'аÑģ'] +['ĠмаÑģ', 'ло'] +['ãĥī', 'ãĤ¤'] +['ãĥīãĤ¤', 'ãĥĦ'] +['å¿ħè¦ģ', 'ãģĮãģĤãĤĬãģ¾ãģĻ'] +['×ŀ×ķ×ĸ', '×Ļ×IJ'] +['×ŀ×ķ×ĸ×Ļ×IJ', '×ķף'] +['ĠNgo', 'ại'] +['Ġkê', 'nh'] +['à¸ģาร', 'à¸Ńà¸Ńà¸ģà¹ģà¸ļà¸ļ'] +['×ŀ', 'פק'] +['×ŀפק', '×ĵ'] +['ÙħÙĨ', 'از'] +['ÙħÙĨاز', 'ÙĦ'] +['ë·', '°'] +['íĹ', '¤'] +['ÙħÙĩ', 'ارات'] +['Ġpropri', 'été'] +['פ×Ĵ', '×Ļש×Ķ'] +['Ñĩ', 'ÑĢ'] +['ÑĩÑĢ', 'еж'] +['ÑĩÑĢеж', 'ден'] +['×Ķ', '×ķצ×IJ×Ķ'] +['ØŃÙĥ', 'ÙĬÙħ'] +['ĠíĻ', 'Ī'] +['ĠíĻĪ', 'íİĺìĿ´ì§Ģ'] +['åİ', '³'] +['åݳ', 'ãģĹãģĦ'] +['×¢', '×ŀ×ĵ×Ķ'] +['ĠAu', 'ÃŁen'] +['سÙĪ', 'Ø¡'] +['ë¹', 'Ī'] +['ĠÙĪ', 'Ø®'] +['ĠÙĪØ®', 'اصة'] +['ин', 'ÑĤеÑĢ'] +['инÑĤеÑĢ', 'еÑģ'] +['èĩ´', 'ãģĹãģ¾ãģĻ'] +['Ġhük', 'üm'] +['à¹Ħà¸Ĥ', 'มัà¸Ļ'] +['Ġdav', 'ran'] +['Ġdavran', 'Ä±ÅŁ'] +['à¹Ģà¸ķ', 'ียà¸ĩ'] +['в', 'ÑĢем'] +['вÑĢем', 'енно'] +['à¹Ģà¸Ĺศ', 'à¸ģา'] +['à¹Ģà¸Ĺศà¸ģา', 'ล'] +['å¼ķ', 'ãģ£'] +['å¼ķãģ£', 'è¶ĬãģĹ'] +['×IJר', '×ķ×Ĺ'] +['×IJר×ķ×Ĺ', 'ת'] +['à¹Ģ', 'วิ'] +['à¹Ģวิ', 'รà¹Į'] +['à¸Ńยà¹Īาà¸ĩ', 'รวà¸Ķà¹Ģรà¹ĩว'] +['ĠìŬ', 'íĸī'] +['ĠÑĢан', 'ÑĮ'] +['ĠÑĢанÑĮ', 'ÑĪе'] +['Ġzob', 'ow'] +['Ġzobow', 'iÄħ'] +['ĠzobowiÄħ', 'z'] +['Ġ×ķ׼', '×ŀ×ķ×ijף'] +['ĠاÙĦÙħ', 'Ùĩ'] +['ĠاÙĦÙħÙĩ', 'ÙĨÙĬ'] +['ãĤ¢', 'ãĤ¸'] +['ãĤ¢ãĤ¸', 'ãĤ¢'] +['ë°©', 'ìĨ¡'] +['à¸Ńà¸Ńà¸ģ', 'à¸ģำลัà¸ĩ'] +['à¸Ńà¸Ńà¸ģà¸ģำลัà¸ĩ', 'à¸ģาย'] +['am', 'éli'] +['améli', 'orer'] +['å½ĵãģŁãĤĬ', 'åīį'] +['Ġreg', 'elm'] +['Ġregelm', 'Ã¤ÃŁig'] +['ãģĬ', 'åĭ'] +['ãģĬåĭ', '§'] +['ãģĬåĭ§', 'ãĤģ'] +['Ġm', 'ưá»Ŀi'] +['بر', 'Ùħج'] +['ĠNat', 'ürlich'] +['ĠD', 'Å©ng'] +['ĠاÙĦر', 'جاÙĦ'] +['Ġthé', 'p'] +['Ġol', 'muÅŁtur'] +['×ŀ×ķס', '×Ļ×§×Ķ'] +['f', 'älle'] +['주', 'íĥĿ'] +['ĠاÙĦÙģ', 'رص'] +['Ġnaj', 'wiÄĻks'] +['ĠnajwiÄĻks', 'zy'] +['Ġça', 'ÄŁ'] +['ĠçaÄŁ', 'rı'] +['ì¸', 'ł'] +['ĠvÃŃ', 'ct'] +['ĠvÃŃct', 'ima'] +['ĠÑģовеÑĢ', 'ÑĪен'] +['×Ķ×Ļ', '×Ļת×Ļ'] +['à¹Ģà¸Ķ', 'ี'] +['à¹Ģà¸Ķี', 'à¹ĭ'] +['à¹Ģà¸Ķีà¹ĭ', 'ยว'] +['ü', 'yü'] +['Ġд', 'оп'] +['Ġдоп', 'олн'] +['Ġдополн', 'иÑĤелÑĮно'] +['à¹ģà¸ķà¸ģà¸ķà¹Īาà¸ĩ', 'à¸ģัà¸Ļ'] +['Ġá', 'l'] +['Ġál', 'bum'] +['à¸Ľà¸£à¸°à¸Īำ', 'à¸Ľà¸µ'] +['ĠÑĦ', 'едеÑĢ'] +['ĠÑĦедеÑĢ', 'алÑĮн'] +['Ġobs', 'ÅĤ'] +['ĠobsÅĤ', 'ugi'] +['à¹Ģร', 'ืà¹Ī'] +['à¹Ģรืà¹Ī', 'à¸Ńย'] +['à¹Ģรืà¹Īà¸Ńย', 'à¹Ĩ'] +['ëģ', 'Į'] +['Ġngh', 'ìn'] +['ĠBaÅŁkan', 'lıģı'] +['تأ', 'سÙĬ'] +['تأسÙĬ', 'س'] +['Ġ×ij×ij', '×ķקר'] +['Ġ×¢×ij×ķ×ĵ', '×ķת'] +['Ġبص', 'ÙĪØ±Ø©'] +['ãĤıãģij', 'ãģ§ãģ¯ãģªãģĦ'] +['führ', 'er'] +['ãĤ¹', 'ãĤŃ'] +['ãĤ¹ãĤŃ', 'ãĥ«'] +['ĠاÙĦÙĤ', 'ض'] +['ĠاÙĦÙĤض', 'ÙĬØ©'] +['Ġдолж', 'ноÑģÑĤ'] +['ÙģØ§Ø±', 'ÙĤ'] +['Ġcomeç', 'ou'] +['Ġorganis', 'é'] +['Ġxu', 'ân'] +['ĠÑģообÑī', 'аеÑĤ'] +['ĠпÑĢи', 'д'] +['ĠпÑĢид', 'еÑĤÑģÑı'] +['TÃľ', 'RK'] +['ãĥ¬', 'ãĥ¼ãĤ·ãĥ§ãĥ³'] +['Kh', 'ông'] +['است', 'Ùģ'] +['استÙģ', 'ادة'] +['ä¸ĬãģĮ', 'ãģ£ãģ¦'] +['Ġum', 'ie'] +['Ġumie', 'jÄĻ'] +['ĠumiejÄĻ', 'tn'] +['ĠumiejÄĻtn', 'oÅĽci'] +['ëĤ', '¸'] +['à¹Ģà¸Ļ', 'à¸Ńรà¹Į'] +['×ĵ×ķ', '×ķ×Ĺ'] +['ÃŃs', 'imo'] +['I', 'ÃĬ'] +['IÃĬ', 'N'] +['Ġalcan', 'ç'] +['Ġ', 'à¸ķุ'] +['Ġà¸ķุ', 'ลา'] +['Ġà¸ķุลา', 'à¸Ħม'] +['ש׾', '×ĺ×ķף'] +['Ġél', 'è'] +['Ġélè', 'ves'] +['ĠÄij', 'u'] +['ĠÄiju', 'á»ķi'] +['ĠØ£', 'Ùģ'] +['ĠØ£Ùģ', 'رÙĬ'] +['ĠØ£Ù쨱ÙĬ', 'ÙĤÙĬ'] +['ĠØ£Ù쨱ÙĬÙĤÙĬ', 'ا'] +['ãĤĴæİ¢', 'ãģĻ'] +['ĠпÑĢед', 'ложениÑı'] +['ج', 'اد'] +['ĠÑħоÑĤ', 'ÑĮ'] +['Ñģ', 'ал'] +['Ñģал', 'он'] +['à¸Ľà¸£à¸°', 'à¹Ģม'] +['à¸Ľà¸£à¸°à¹Ģม', 'ิà¸Ļ'] +['ãĤŃ', 'ãĥĥãĥģ'] +['ãĤŃãĥĥãĥģ', 'ãĥ³'] +['×ij×ĵ×Ļ×§', '×ķת'] +['Ġch', 'ù'] +['Ġchù', 'a'] +['ÐĴ', 'иде'] +['ÐĴиде', 'о'] +['иÑĢов', 'ка'] +['ĠÑħоÑĤ', 'иÑĤе'] +['Ġspéc', 'ifique'] +['รส', 'à¸Ĭาà¸ķิ'] +['è¾¼', 'ãĤĵãģł'] +['伸', 'ãģ³'] +['×Ķצ׾', '×Ĺת'] +['ãģ©ãģ®', 'ãĤĪãģĨãģ«'] +['سع', 'ادة'] +['Ġл', 'ид'] +['Ġлид', 'еÑĢ'] +['ม', 'à¸ĩ'] +['มà¸ĩ', 'à¸Ħล'] +['ØŃ', 'اÙħÙĦ'] +['หล', 'ุà¸Ķ'] +['à¸Ńยà¹Īาà¸ĩ', 'à¸ķà¹Īà¸Ń'] +['à¸Ńยà¹Īาà¸ĩà¸ķà¹Īà¸Ń', 'à¹Ģà¸Ļืà¹Īà¸Ńà¸ĩ'] +['ãģķãģĽãģ¦', 'éłĤ'] +['تس', 'ÙĪÙĬ'] +['تسÙĪÙĬ', 'ÙĤ'] +['ĠaÅŁaģı', 'd'] +['ĠaÅŁaģıd', 'aki'] +['ĠÑĨ', 'елÑĮ'] +['ĠÑĨелÑĮ', 'Ñİ'] +['ĠAra', 'ÅŁtırma'] +['à¸Ĥัà¸ļ', 'รà¸ĸ'] +['Ùĩ', 'ذÙĩ'] +['ลà¸ĩ', 'à¸Ĺะ'] +['ลà¸ĩà¸Ĺะ', 'à¹Ģà¸ļ'] +['ลà¸ĩà¸Ĺะà¹Ģà¸ļ', 'ียà¸Ļ'] +['تÙĥ', 'اÙħÙĦ'] +['Ġc', 'io'] +['Ġcio', 'è'] +['ãģ¦', 'ãģĬãģı'] +['ĠاÙĦصØŃ', 'ÙģÙĬ'] +['ĠíĬ¹', 'ìłķ'] +['полн', 'иÑĤÑĮ'] +['ãĤĵ', 'ãģĺãĤĥãģªãģĦ'] +['ãĤĵãģĺãĤĥãģªãģĦ', 'ãģĭ'] +['ĠاÙĦج', 'Ùĩ'] +['ĠاÙĦجÙĩ', 'ات'] +['ĠÑĥÑģпеÑĪ', 'но'] +['Ġв', 'ок'] +['Ġвок', 'ÑĢÑĥг'] +['ĠÑģиÑĤÑĥ', 'аÑĨиÑı'] +['Ġ×Ķ×IJ', '×ŀר'] +['Ġ×Ķ×IJ×ŀר', '×Ļ×§'] +['Ġ×Ķ×IJ×ŀר×Ļ×§', '×IJ×Ļ'] +['×ŀ', '×Ĵ×ĸ'] +['×ŀ×Ĵ×ĸ', '×Ļף'] +['Ġак', 'ÑĤÑĥ'] +['ĠакÑĤÑĥ', 'алÑĮн'] +['é', 'ta'] +['éta', 'is'] +['Ġmog', 'ÅĤa'] +['ĠÑĤоÑĩ', 'ки'] +['Ġ×ŀ×Ķ', '×ŀ×¢'] +['Ġ×ŀ×Ķ×ŀ×¢', '×¨×Ľ×ª'] +['มี', 'à¸Ľà¸£à¸°à¸ªà¸´à¸Ĺà¸ĺà¸´à¸łà¸²à¸ŀ'] +['×Ļר', '×Ļ×ĵ×Ķ'] +['×Ĵר', '×ŀ׳'] +['×Ĵר×ŀ׳', '×Ļ×Ķ'] +['Ġг', 'лав'] +['Ġглав', 'ное'] +['Ġ미', 'ëŀĺ'] +['Ġ׳׼', '×ķ׳×Ķ'] +['ĠÙĪ', 'Ø·ÙĨÙĬ'] +['op', 'port'] +['opport', 'unitÃł'] +['Ġh', 'á»§y'] +['ĠÙĦ', 'تØŃ'] +['ĠÙĦتØŃ', 'ÙĤÙĬÙĤ'] +['Ġó', 'rg'] +['Ġórg', 'ão'] +['ãĤ¹', 'ãĥĶ'] +['ãĤ¹ãĥĶ', 'ãĥ¼ãĥī'] +['Ġön', 'ü'] +['Ġönü', 'ne'] +['Ùħع', 'اÙħÙĦ'] +['ש×ŀ', '×Ļר×Ķ'] +['ĠвеÑģÑĮ', 'ма'] +['ĠwiÄĻks', 'zo'] +['ĠwiÄĻkszo', 'ÅĽÄĩ'] +['Ġاست', 'راتÙĬج'] +['ĠاستراتÙĬج', 'ÙĬØ©'] +['ĠÙģ', 'Ø¥'] +['ĠÙ쨥', 'ذا'] +['à¹Ģà¸Ĭืà¹Īà¸Ń', 'ม'] +['à¹Ģà¸Ĭืà¹Īà¸Ńม', 'à¸ķà¹Īà¸Ń'] +['Ġ׾', 'פר'] +['Ġ׾פר', '×ĺ×Ļ×Ŀ'] +['Ùħض', 'ÙĬ'] +['ĠGer', 'çek'] +['Ġçocuk', 'ların'] +['ÙĪØ«', 'ائÙĤ'] +['ĠÙħساء', 'Ùĭ'] +['Ġunterstüt', 'zt'] +['Ġpré', 'st'] +['Ġprést', 'amo'] +['ĠÐłÐ°Ð·', 'меÑĢ'] +['ĠÅŁ', 'eker'] +['Ġsé', 'culo'] +['×ij×Ķ', '×Ļר'] +['Ø´Ùĩ', 'ÙĪØ±'] +['Ġ', 'à¸Ńีà¸ģ'] +['Ġà¸Ńีà¸ģ', 'à¸Ĺัà¹īà¸ĩ'] +['Ġlleg', 'ó'] +['à¸¨à¸´à¸¥à¸Ľ', 'ะ'] +['æĪij', 'ãģĮ'] +['æĪijãģĮ', 'å®¶'] +['ع', 'ÙĤÙĪ'] +['عÙĤÙĪ', 'بات'] +['ĠF', 'älle'] +['Ġs', 'ÅĤuż'] +['ĠsÅĤuż', 'b'] +['ĠاÙĦØŃÙĤ', 'ÙĪÙĤ'] +['Ġпл', 'иÑĤ'] +['Ġи', 'ноÑģÑĤ'] +['ĠиноÑģÑĤ', 'ÑĢан'] +['ĠиноÑģÑĤÑĢан', 'н'] +['à¹ĥà¸Ļ', 'à¸Ĥà¸ĵะà¸Ĺีà¹Ī'] +['ãĤ«', 'ãĥĨ'] +['ãĤ«ãĥĨ', 'ãĤ´'] +['ãĤ«ãĥĨãĤ´', 'ãĥª'] +['à¸Ńิ', 'ส'] +['à¸Ńิส', 'ระ'] +['à¹Ģà¸ľà¸¢', 'à¹ģ'] +['à¹Ģà¸ľà¸¢à¹ģ', 'à¸ŀร'] +['à¹Ģà¸ľà¸¢à¹ģà¸ŀร', 'à¹Ī'] +['ãģĬ', 'ãģĦ'] +['ãģĬãģĦ', 'ãģĹãģĦ'] +['است', 'ÙĤÙĦ'] +['استÙĤÙĦ', 'اÙĦ'] +['تØŃ', 'ض'] +['تØŃض', 'ÙĬر'] +['åĬ©', 'ãģij'] +['Ùħر', 'اÙģÙĤ'] +['Ġ×ĵ', '×ķר'] +['Ġ×ĵ×ķר', 'ש'] +['×ŀת×Ļ', '×Ļ×Ĺס'] +['ס', '×Ļ׼'] +['ס×Ļ׼', '×ķ×Ŀ'] +['íĮĮ', 'íĬ¸'] +['Ġwy', 'ÅĽ'] +['ĠwyÅĽ', 'w'] +['ĠwyÅĽw', 'iet'] +['ĠwyÅĽwiet', 'l'] +['ĠاÙĦاÙĨ', 'ساÙĨ'] +['ĠStra', 'ÃŁen'] +['ï¼', '¬'] +['ãģ«', 'åŁº'] +['ãģ«åŁº', 'ãģ¥'] +['Ġcap', 'ÃŃtulo'] +['ลุ', 'ย'] +['Ġ×Ķ×ŀ×§', 'צ×ķ×¢×Ļ'] +['ãģĤãĤĭ', 'ç¨ĭ度'] +['á»', '¢'] +['ĠاÙĦ', 'ÙĦا'] +['ĠاÙĦÙĦا', 'زÙħØ©'] +['æķĻ', 'ãģĪ'] +['Ġרש', '×IJ×Ļ'] +['з', 'ав'] +['зав', 'иÑģ'] +['завиÑģ', 'им'] +['à¸Ľà¸±à¸Ī', 'à¸Īัย'] +['à¹Ģà¸ĭ', 'ล'] +['à¹Ģà¸ĭล', 'ลà¹Į'] +['Ġdiffé', 'rence'] +['ĠAlt', 'ın'] +['Ġк', 'ÑĢай'] +['ĠкÑĢай', 'не'] +['Ġз', 'ло'] +['Ġgün', 'ümüz'] +['Ġн', 'аÑĤÑĥÑĢ'] +['ĠнаÑĤÑĥÑĢ', 'алÑĮн'] +['×Ĵ×ķ׾', 'ש×Ļ×Ŀ'] +['Ġк', 'аÑĤегоÑĢ'] +['ĠкаÑĤегоÑĢ', 'ии'] +['Ġз', 'нак'] +['à¸ģà¹Īà¸Ńà¸Ļ', 'หà¸Ļà¹īา'] +['à¸ģà¹Īà¸Ńà¸Ļหà¸Ļà¹īา', 'à¸Ļีà¹ī'] +['ĠÙħÙĨ', 'ت'] +['ĠÙħÙĨت', 'خب'] +['ãĥĽ', 'ãĥ¼ãĥ«'] +['Ġе', 'вÑĢо'] +['ส', 'ว'] +['สว', 'ม'] +['ĠìľĦ', 'ìĽIJ'] +['ĠìľĦìĽIJ', 'ëĭĺ'] +['ĠاÙĦØŃ', 'ÙĪØ«'] +['ĠاÙĦØŃÙĪØ«', 'ÙĬ'] +['ĠÑģодеÑĢж', 'иÑĤ'] +['ãĥķãĤ¡', 'ãĥĥãĤ·ãĥ§ãĥ³'] +['Ġ', 'à¸ģัà¸Ļ'] +['Ġà¸ģัà¸Ļ', 'ย'] +['Ġà¸ģัà¸Ļย', 'ายà¸Ļ'] +['ãĤª', 'ãĥª'] +['ãĤªãĥª', 'ãĤ¸'] +['ãĤªãĥªãĤ¸', 'ãĥĬãĥ«'] +['Ġб', 'ÑĢенд'] +['ãĤĴæĮģ', 'ãģ£ãģ¦ãģĦãĤĭ'] +['Ġinvers', 'ión'] +['Ġê°', 'ĸ'] +['Ġê°ĸ', 'ê³ł'] +['Ġnov', 'itÃł'] +['ê´Ģ', 'ê´ij'] +['Ġà¸ŀ', 'ฤษ'] +['Ġà¸ŀฤษ', 'à¸łà¸²'] +['Ġà¸ŀà¸¤à¸©à¸łà¸²', 'à¸Ħม'] +['×ķר', '×Ĺ×Ļ×Ŀ'] +['׼׾', '×ķ׾'] +['Ġng', 'ạc'] +['×Ļ', '×Ļש'] +['×Ļ×Ļש', '×ķ×ij'] +['f', 'äll'] +['fäll', 'ig'] +['ĠÑĤÑĢеб', 'ÑĥеÑĤÑģÑı'] +['Ġcar', 'á'] +['Ġcará', 'cter'] +['Ġprinc', 'ÃŃpio'] +['ĠÅĤ', 'az'] +['ĠÅĤaz', 'ien'] +['ĠÅĤazien', 'k'] +['Ġgi', 'ãn'] +['ÑģÑĤÑĢа', 'ива'] +['Ùħس', 'اب'] +['Ùħساب', 'ÙĤØ©'] +['à¹Ģà¸Ħรืà¹Īà¸Ńà¸ĩ', 'à¸Ķืà¹Īม'] +['ترÙĥ', 'ÙĬب'] +['vol', 'ução'] +['ĠÐŁ', 'оÑĩ'] +['ĠÐŁÐ¾Ñĩ', 'ем'] +['ĠÐŁÐ¾Ñĩем', 'Ñĥ'] +['казал', 'оÑģÑĮ'] +['ĠпÑĢимен', 'ениÑı'] +['à¹Ģà¸Ĺ', 'ียม'] +['íĮ', 'Ķ'] +['à¸Ĥà¹īà¸Ń', 'à¹Ģสà¸Ļà¸Ń'] +['à¸Ľà¸±à¸į', 'à¸įา'] +['Ġоб', 'ÑĥÑĩ'] +['ĠобÑĥÑĩ', 'ениÑı'] +['ĠÑģеÑĢ', 'и'] +['ĠÑģеÑĢи', 'ал'] +['Ġingl', 'és'] +['ĠÙĦ', 'Ùĥرة'] +['Ġ×ĺ', '׾'] +['Ġ×ĺ׾', 'פ×ķף'] +['Ġìł', 'ij'] +['Ġìłij', 'ê·¼'] +['×IJ', '×ķ×Ĵ'] +['×IJ×ķ×Ĵ', '×ķס'] +['×IJ×ķ×Ĵ×ķס', '×ĺ'] +['ĠболÑĮÑĪ', 'ое'] +['ĠÐļон', 'еÑĩно'] +['×¢×Ļת', '×ķ׳'] +['×¢×Ļת×ķ׳', '×IJ×Ļ'] +['Ġкноп', 'к'] +['Ġз', 'н'] +['Ġзн', 'аÑĤÑĮ'] +['ĠÄij', 'á»±'] +['ĠÄijá»±', 'ng'] +['вл', 'аж'] +['влаж', 'н'] +['×ŀ', '×Ļ×ĺ×ij'] +['ãĤ¬', 'ãĤ¤'] +['ãĤ¬ãĤ¤', 'ãĥī'] +['........', '..'] +['Ġà¸ģ', 'ุม'] +['Ġà¸ģุม', 'à¸łà¸²à¸ŀ'] +['Ġà¸ģà¸¸à¸¡à¸łà¸²à¸ŀ', 'ัà¸Ļ'] +['Ġà¸ģà¸¸à¸¡à¸łà¸²à¸ŀัà¸Ļ', 'à¸ĺ'] +['Ġà¸ģà¸¸à¸¡à¸łà¸²à¸ŀัà¸Ļà¸ĺ', 'à¹Į'] +['be', 'z'] +['bez', 'pieczeÅĦst'] +['bezpieczeÅĦst', 'w'] +['ãĥijãĥij', 'æ´»'] +['ع', 'اط'] +['عاط', 'Ùģ'] +['ĠÄij', 'áºŃm'] +['Ġз', 'ÑĢ'] +['ĠзÑĢ', 'ениÑı'] +['Ġbor', 'ç'] +['Ġнед', 'ел'] +['Ġнедел', 'Ñİ'] +['Ġh', 'á»ı'] +['Ġhá»ı', 'ng'] +['ìŀ¥', 'ìķł'] +['ìŀ¥ìķł', 'ìĿ¸'] +['ĠاÙĦع', 'ÙĦاÙĤØ©'] +['Ġíģ', '¬'] +['Ġíģ¬', 'ê²Į'] +['à¹Ħร', 'à¹Ī'] +['à¸ļา', 'à¸Ķ'] +['à¸ļาà¸Ķ', 'à¹Ģà¸Īà¹ĩà¸ļ'] +['à¸Ŀ', 'รั'] +['à¸Ŀรั', 'à¹Īà¸ĩ'] +['à¸Ŀรัà¹Īà¸ĩ', 'à¹Ģศ'] +['à¸Ŀรัà¹Īà¸ĩà¹Ģศ', 'ส'] +['ר', '×¢×Ļ'] +['רע×Ļ', '×ķ׳×ķת'] +['Ġë', 'Į'] +['ĠëĮ', 'ĵ'] +['ĠëĮĵ', 'ê¸Ģ'] +['Ġnaj', 'b'] +['Ġnajb', 'li'] +['Ġnajbli', 'ż'] +['Ġnajbliż', 'sz'] +['ĠиÑģполÑĮз', 'ÑĥеÑĤÑģÑı'] +['Ġcient', 'ÃŃf'] +['ĠcientÃŃf', 'ico'] +['×¢', '×ŀ×§'] +['Ġg', 'ợi'] +['Ø´', 'ØŃÙĨ'] +['ĠÅĽ', 'm'] +['ĠÅĽm', 'ier'] +['ĠÅĽmier', 'ci'] +['à¸Ħาสิà¹Ĥà¸Ļ', 'à¸Ńà¸Ńà¸Ļà¹Ħลà¸Ļà¹Į'] +['×Ĺש×ij', 'ת×Ļ'] +['Ġn', 'ingu'] +['Ġningu', 'ém'] +['è¾¼', 'ãĤģ'] +['ãģ', '·'] +['ĠÑĥ', 'г'] +['ĠÑĥг', 'ол'] +['ï½', '°'] +['פת', '×Ļ×Ĺ'] +['פת×Ļ×Ĺ', 'ת'] +['Ġ×Ķר×IJש', '×ķ׳×Ļ×Ŀ'] +['p', 'ósito'] +['ãĤŃ', 'ãĥ¬ãĤ¤'] +['ãģ©', 'ãģĵãĤį'] +['à¹Ģà¸Ĺà¹Īา', 'à¹Ħ'] +['à¹Ģà¸Ĺà¹Īาà¹Ħ', 'หร'] +['à¹Ģà¸Ĺà¹Īาà¹Ħหร', 'à¹Ī'] +['ĠинÑĤеÑĢ', 'ÑĮеÑĢ'] +['ĠØŃ', 'اج'] +['ĠØŃاج', 'Ø©'] +['สี', 'à¸Ĥาว'] +['ìĸ', '¼'] +['Ġn', 'á»Ļ'] +['Ġná»Ļ', 'p'] +['ĠÃŃ', 'nd'] +['ĠÃŃnd', 'ice'] +['สำ', 'รวà¸Ī'] +['Ġкажд', 'ой'] +['Ġhot', 'éis'] +['Ġnast', 'ÄĻ'] +['ĠnastÄĻ', 'pn'] +['Ġ×Ķ×§', '×ķ×ĵ'] +['Ġ×Ķ×§×ķ×ĵ', '×Ŀ'] +['פ', '×ķפ'] +['פ×ķפ', '×ķ׾'] +['פ×ķפ×ķ׾', 'ר×Ļ'] +['вÑĪ', 'ей'] +['ãĤ·ãĥ³', 'ãĥĹ'] +['ãĤ·ãĥ³ãĥĹ', 'ãĥ«'] +['ĠzdjÄĻ', 'Äĩ'] +['ĠгÑĢÑĥпп', 'а'] +['Ġпом', 'еÑī'] +['ĠпомеÑī', 'ениÑı'] +['ãģ©ãģĨ', 'ãģĦãģĨ'] +['ĠиÑģп', 'ÑĭÑĤа'] +['Ġog', 'ÅĤ'] +['ĠogÅĤ', 'os'] +['ĠogÅĤos', 'zen'] +['ĠogÅĤoszen', 'i'] +['สรà¹īาà¸ĩ', 'สรร'] +['สรà¹īาà¸ĩสรร', 'à¸Ħà¹Į'] +['à¸ŀร', 'รà¸ĵ'] +['Ġçık', 'Ä±ÅŁ'] +['ĠÑĩаÑģÑĤ', 'ноÑģÑĤи'] +['Ġ×ķ', '×Ļ×ķתר'] +['ç¶ļãģį', 'ãĤĴ'] +['ç¶ļãģįãĤĴ', 'èªŃ'] +['ç¶ļãģįãĤĴèªŃ', 'ãĤĢ'] +['à¸ģร', 'ั'] +['à¸ģรั', 'ม'] +['г', 'ÑĢаÑĦ'] +['Ġв', 'лад'] +['Ġвлад', 'елÑĮ'] +['ĠвладелÑĮ', 'ÑĨ'] +['Ġistedi', 'ÄŁ'] +['ĠistediÄŁ', 'iniz'] +['×ij׾', '×¢'] +['×ij×ľ×¢', '×ĵ×Ļ'] +['ÙħÙĪ', 'اÙģ'] +['ÙħÙĪØ§Ùģ', 'ÙĤØ©'] +['Ġ×Ļ', '×ķר'] +['Ġ×Ļ×ķר', '×§'] +['ãĤ«ãĥ¼ãĥī', 'ãĥŃãĥ¼ãĥ³'] +['ĠاÙĦÙħØ´', 'ÙĥÙĦ'] +['ĠاÙĦÙħØ´ÙĥÙĦ', 'Ø©'] +['ĠêµŃ', 'íļĮ'] +['ס', 'פ×ĺ'] +['ספ×ĺ', '×ŀ'] +['ספ×ĺ×ŀ', '×ijר'] +['Ġìĸ´', 'ëłµ'] +['Ùĥ', 'اÙħ'] +['ÙĥاÙħ', 'ÙĬرا'] +['sch', 'lü'] +['schlü', 'sse'] +['ĠØ«', 'ÙĨ'] +['ĠØ«ÙĨ', 'ائÙĬ'] +['ìī', '½'] +['ĠÐŀ', 'Ñģоб'] +['ĠÐŀÑģоб', 'енно'] +['Ġин', 'веÑģÑĤи'] +['ĠинвеÑģÑĤи', 'ÑĨи'] +['اØŃ', 'تÙħ'] +['اØŃتÙħ', 'اÙĦ'] +['E', 'Äŀ'] +['EÄŀ', 'İ'] +['íķĺ', 'ê²łëĭ¤'] +['Ġ×IJ', '×ijר×Ķ'] +['Ġ×IJ×ijר×Ķ', '×Ŀ'] +['Ġ×ij×Ĺ', '×Ļ׳×Ŀ'] +['Ø£', 'ÙĪØ¶'] +['Ø£ÙĪØ¶', 'اع'] +['Ġdé', 'l'] +['Ġdél', 'ai'] +['Ġ×IJ×ķ×Ķ', '×ij×Ļ×Ŀ'] +['ĠÑģо', 'Ñħ'] +['ĠÑģоÑħ', 'ÑĢ'] +['ĠÑģоÑħÑĢ', 'ани'] +['ĠдоÑģÑĤ', 'иж'] +['ĠдоÑģÑĤиж', 'ени'] +['สิà¹Īà¸ĩ', 'à¹ģ'] +['สิà¹Īà¸ĩà¹ģ', 'วà¸Ķ'] +['สิà¹Īà¸ĩà¹ģวà¸Ķ', 'ล'] +['สิà¹Īà¸ĩà¹ģวà¸Ķล', 'à¹īà¸Ńม'] +['ĠاÙĦÙħ', 'باشر'] +['ĠÑĦ', 'иг'] +['ĠÑĦиг', 'ÑĥÑĢ'] +['мож', 'ем'] +['׾×ŀ×Ļ×ĵ', '×Ķ'] +['Ġcin', 'é'] +['Ġciné', 'ma'] +['Ġb', 'ada'] +['Ġbada', 'ÅĦ'] +['جب', 'ÙĩØ©'] +['Ġд', 'еп'] +['Ġдеп', 'ÑĥÑĤ'] +['ĠдепÑĥÑĤ', 'аÑĤ'] +['Ġdist', 'ância'] +['ĠاÙĦÙħ', 'عار'] +['ĠاÙĦÙħعار', 'ضة'] +['thè', 'se'] +['ü', 'nc'] +['ünc', 'ü'] +['Ġдан', 'ного'] +['ĠBel', 'gi'] +['ĠBelgi', 'ë'] +['Ġ×ij', '×ij×§'] +['Ġ×ij×ij×§', 'ש×Ķ'] +['ย', 'à¹Īาà¸Ļ'] +['Ġsol', 'ução'] +['Ġ×Ķצ', '×ĺר'] +['Ġ×Ķצ×ĺר', 'פ×ķ'] +['ĠØ£ÙĨ', 'ØŃ'] +['ĠØ£ÙĨØŃ', 'اء'] +['Ġد', 'ÙħØ´'] +['ĠدÙħØ´', 'ÙĤ'] +['มั', 'à¹ī'] +['มัà¹ī', 'ย'] +['Ùħ', 'غرب'] +['است', 'عÙħاÙĦ'] +['ĠS', 'ÅĤow'] +['ĠëıĻ', 'ìĭľ'] +['ĠëıĻìĭľ', 'ìĹIJ'] +['ĠÑģ', 'оÑģ'] +['ĠÑģоÑģ', 'ед'] +['ì²Ń', 'ìĨĮ'] +['ì²ŃìĨĮ', 'ëħĦ'] +['Ġг', 'ÑĢаÑĦ'] +['ĠгÑĢаÑĦ', 'ик'] +['Ġìŀij', 'ìĿĢ'] +['Ġyet', 'i'] +['Ġyeti', 'ÅŁtir'] +['ĠìĿ´ê²ĥ', 'ìĿ´'] +['ห', 'à¹Īาà¸ĩ'] +['Ø¥', 'ÙħÙĥاÙĨ'] +['Ø¥ÙħÙĥاÙĨ', 'ÙĬØ©'] +['است', 'عراض'] +['ÙħØ®', 'در'] +['ĠÑĩ', 'ÑĥÑĤÑĮ'] +['Ùħ', 'دÙĬر'] +['ÙħدÙĬر', 'ÙĬØ©'] +['Ġà¹Ģม', 'ษ'] +['Ġà¹Ģมษ', 'ายà¸Ļ'] +['Ġм', 'еÑħ'] +['ĠмеÑħ', 'аниз'] +['ĠмеÑħаниз', 'м'] +['ĠÑģ', 'Ñĥм'] +['ĠÑģÑĥм', 'мÑĥ'] +['Ġv', 'ö'] +['Ġvö', 'll'] +['Ġvöll', 'ig'] +['Ġд', 'ÑĢÑĥз'] +['ĠдÑĢÑĥз', 'ÑĮÑı'] +['ãĤĴåĪ©ç͍', 'ãģĹãģ¦'] +['à¸ļรร', 'à¸Īุ'] +['po', 'życz'] +['×ŀש', '׼'] +['×ŀש׼', '×ł×ª'] +['×ŀ×©×Ľ×ł×ª', '×IJ'] +['Ġeuropé', 'en'] +['Ġpropri', 'é'] +['Ġproprié', 'taire'] +['Ġkh', 'ấu'] +['ãģĦãģŁãģł', 'ãģijãĤĭ'] +['Ġtec', 'rü'] +['Ġtecrü', 'be'] +['×Ķ', '×ij'] +['×Ķ×ij', '׳×Ķ'] +['Ġcu', 'Ì'] +['ĠcuÌ', 'ī'] +['ĠcuÌī', 'a'] +['×IJ', '×ķ×ķ'] +['×IJ×ķ×ķ', '×Ļר×Ķ'] +['Ġ׼×ķ׾', '×ķ'] +['U', 'lus'] +['Ulus', 'lararası'] +['Ġ׳', '×ķת'] +['Ġ׳×ķת', 'ף'] +['ãģ«', 'åIJij'] +['ãģ«åIJij', 'ãģijãģ¦'] +['ë¹', 'Ľ'] +['à¸Ĺ', 'ัà¸ģษ'] +['à¸Ĺัà¸ģษ', 'ะ'] +['س', 'ÙĤÙĪ'] +['سÙĤÙĪ', 'Ø·'] +['Ġв', 'н'] +['Ġвн', 'еÑĪ'] +['ĠвнеÑĪ', 'не'] +['Ġur', 'z'] +['Ġurz', 'ÄĻd'] +['Ġá', 'mb'] +['Ġámb', 'ito'] +['à¸Ń', 'à¸ĺิ'] +['à¸Ńà¸ĺิ', 'à¸ļาย'] +['Ġ', 'ÅĤad'] +['ĠÅĤad', 'n'] +['ê±´', 'ì¶ķ'] +['wód', 'zt'] +['wództ', 'w'] +['Ġquest', 'ões'] +['Ġש', '×§'] +['Ġשק', '×Ļ×ij׾'] +['Ġmiejsc', 'owoÅĽci'] +['Ġв', 'ал'] +['Ġвал', 'ÑİÑĤ'] +['hä', 'user'] +['หà¸Ļ', 'à¸Ńà¸ĩ'] +['ãģ¨', 'åħ±'] +['ãģ¨åħ±', 'ãģ«'] +['ãĥı', 'ãĥ¼ãĥī'] +['Ġê°ľ', 'ìµľ'] +['ĠоÑģнов', 'ном'] +['Ġм', 'ÑıÑģ'] +['اع', 'ت'] +['اعت', 'ÙĤاÙĦ'] +['สà¸ĸ', 'ิ'] +['สà¸ĸิ', 'à¸ķิ'] +['N', 'gu'] +['Ngu', 'á»ĵn'] +['ĠÙħ', 'جÙĦ'] +['ĠÙħجÙĦ', 'Ø©'] +['à¹ģà¸Ĥ', 'à¸Ļ'] +['ĠاÙĦÙĦÙĬ', 'بÙĬ'] +['פע×Ļ׾', '×ķ×Ļ×ķת'] +['Ġ×Ķר', 'פ×ķ×IJ×Ļ'] +['פר', '×ķפ'] +['פר×ķפ', '×Ļ׾'] +['×§', '׾×IJ'] +['ק׾×IJ', 'ס×Ļ'] +['Ùĥت', 'Ø´Ùģ'] +['ãģ«ãģª', 'ãģ£ãģ¦ãģĹãģ¾ãģĨ'] +['à¹Ģà¸Ħล', 'à¹ĩà¸Ķ'] +['à¹Ģà¸Ħลà¹ĩà¸Ķ', 'ลัà¸ļ'] +['Ġì»', '´'] +['Ġì»´', 'íĵ¨'] +['Ġì»´íĵ¨', 'íĦ°'] +['Ġ×Ĺ×Ļ', '×ķ×ij×Ļ'] +['Ġnä', 'm'] +['Ġnäm', 'lich'] +['åij¼', 'ãģ°'] +['åij¼ãģ°', 'ãĤĮ'] +['ĠÑĢ', 'ол'] +['ĠÑĢол', 'и'] +['Ġspécial', 'isé'] +['à¸Ļ', 'วัà¸ķ'] +['à¸Ļวัà¸ķ', 'à¸ģรรม'] +['ÙĨص', 'ÙĪØµ'] +['пеÑĢ', 'ед'] +['пеÑĢед', 'аÑĩ'] +['thè', 'que'] +['Ġר×IJ', '×Ļת×Ļ'] +['ãĥĢ', 'ãĤ¦ãĥ³'] +['ãĤı', 'ãģĭ'] +['ãĤıãģĭ', 'ãģ£ãģ¦'] +['беÑĢ', 'еж'] +['ĠÑģ', 'ек'] +['ĠÑģек', 'ÑĢ'] +['ĠÑģекÑĢ', 'еÑĤ'] +['ĠпоÑģÑĤоÑıн', 'н'] +['à¸Ĥà¸Ļ', 'สà¹Īà¸ĩ'] +['Ġm', 'ük'] +['Ġmük', 'em'] +['Ġmükem', 'mel'] +['еÑĤ', 'еÑģÑĮ'] +['ĠاÙĦسÙĨ', 'ÙĪØ§Øª'] +['ĠìłĦ', 'íĺĢ'] +['Ġ×Ķ×ŀ×§', '×ķר×Ļ'] +['Ġmü', 'd'] +['Ġmüd', 'ah'] +['Ġmüdah', 'ale'] +['Ġwy', 'b'] +['Ġwyb', 'ór'] +['Ġtend', 'ência'] +['Ø¥', 'دار'] +['إدار', 'ÙĬØ©'] +['Ġunterstüt', 'zen'] +['ת', '×ijר'] +['ת×ijר', 'ר'] +['Ġdi', 'á'] +['Ġdiá', 'logo'] +['ĠÃĸ', 'nce'] +['ĠÃĸnce', 'ki'] +['ãĤ¹ãĥĿ', 'ãĥĥãĥĪ'] +['ëĦ', '£'] +['ĠG', 'eli'] +['ĠGeli', 'ÅŁ'] +['ãĤĴ', 'éĢļ'] +['ãĤĴéĢļ', 'ãģĹãģ¦'] +['ĠFuÃŁ', 'ball'] +['Ġsal', 'ari'] +['Ġsalari', 'é'] +['ĠпÑĢодÑĥк', 'ÑĤов'] +['صÙģ', 'ÙĤØ©'] +['รว', 'à¸ļ'] +['รวà¸ļ', 'รวม'] +['à¹ĥà¸Ļ', 'à¸IJาà¸Ļ'] +['à¹ĥà¸Ļà¸IJาà¸Ļ', 'ะ'] +['Ġkay', 'na'] +['Ġkayna', 'ģı'] +['Ġìŀij', 'íĴĪ'] +['ĠвÑĭ', 'ÑĢаж'] +['ĠвÑĭÑĢаж', 'ен'] +['ĠÑģÑĤ', 'еп'] +['ĠÑģÑĤеп', 'ени'] +['ĠاÙĦÙħ', 'ÙĪØ¬ÙĪØ¯'] +['ĠاÙĦÙħÙĪØ¬ÙĪØ¯', 'Ø©'] +['ล', 'à¹īม'] +['Ġnaj', 'czÄĻ'] +['ĠnajczÄĻ', 'ÅĽcie'] +['ĠnajczÄĻÅĽcie', 'j'] +['Ġz', 'wy'] +['Ġzwy', 'k'] +['Ġzwyk', 'ÅĤ'] +['Ġê·¸ëłĩ', 'ì§Ģ'] +['à¸ģระ', 'à¸Ī'] +['à¸ģระà¸Ī', 'าย'] +['Ġëĭ', 'µ'] +['Ġëĭµ', 'ë³Ģ'] +['ĠÑĢе', 'ак'] +['ĠÑĢеак', 'ÑĨи'] +['ĠÅĽwie', 'ż'] +['ĠÑģÑĤоим', 'оÑģÑĤи'] +['ÙħÙĨ', 'اÙĤ'] +['ÙħÙĨاÙĤ', 'Ø´'] +['ÙħÙĨاÙĤØ´', 'Ø©'] +['ĠÑħоÑĩ', 'Ñĥ'] +['ãĥľ', 'ãĥ¼ãĥī'] +['Ġróż', 'nic'] +['Ġк', 'ÑĢÑĭ'] +['ĠкÑĢÑĭ', 'ÑĪ'] +['âľ', 'ĵ'] +['ãĤ³ãĥ³', 'ãĥĨãĥ³'] +['ãĤ³ãĥ³ãĥĨãĥ³', 'ãĥĦ'] +['ĠпÑĢед', 'поÑĩ'] +['×ŀר', '×ij×Ļת'] +['ĠØ´', 'Ùĥ'] +['ĠØ´Ùĥ', 'را'] +['Ġд', 'ал'] +['Ġдал', 'ек'] +['Ġдалек', 'о'] +['بر', 'ÙĬØ·'] +['برÙĬØ·', 'اÙĨÙĬا'] +['ع', 'ÙĨا'] +['عÙĨا', 'ÙĬØ©'] +['ĠÑĢаÑģÑģ', 'каз'] +['ĠÑĢаÑģÑģказ', 'Ñĭва'] +['Ø£', 'ÙĦÙĪ'] +['Ø£ÙĦÙĪ', 'اÙĨ'] +['æĮģ', 'ãģ£ãģ¦'] +['æĮģãģ£ãģ¦', 'ãģĦ'] +['Ùħباد', 'ئ'] +['×Ķ', '×¢×ijר'] +['×Ķ×¢×ijר', 'ת'] +['Ġyay', 'ı'] +['Ġyayı', 'ml'] +['Ġyayıml', 'a'] +['m', 'át'] +['mát', 'icos'] +['à¸ģ', 'ัà¸ĩ'] +['à¸ģัà¸ĩ', 'วล'] +['Ġ׾', 'פת'] +['Ġ×ľ×¤×ª', '×ķ×Ĺ'] +['à¸ŀฤ', 'à¸ķิ'] +['à¸ŀฤà¸ķิ', 'à¸ģรรม'] +['í', 'Ĥ¬'] +['Ġок', 'ÑĢÑĥг'] +['Ġ×ŀצ', '×ķ×ķ×Ķ'] +['ÐĽ', 'ени'] +['ÐĽÐµÐ½Ð¸', 'н'] +['ĠTri', 'á»ģu'] +['ãĤ³ãĥŁ', 'ãĥ¥'] +['ãĤ³ãĥŁãĥ¥', 'ãĥĭ'] +['ãĤ³ãĥŁãĥ¥ãĥĭ', 'ãĤ±'] +['ãĤ³ãĥŁãĥ¥ãĥĭãĤ±', 'ãĥ¼ãĤ·ãĥ§ãĥ³'] +['Ùĥ', 'ÙĨÙĬ'] +['ÙĥÙĨÙĬ', 'سة'] +['ãĤĴ', 'ä¸Ńå¿ĥ'] +['ãĤĴä¸Ńå¿ĥ', 'ãģ«'] +['ĠmiÄĻd', 'z'] +['ĠmiÄĻdz', 'yn'] +['ĠmiÄĻdzyn', 'ar'] +['ĠmiÄĻdzynar', 'od'] +['ĠmiÄĻdzynarod', 'ow'] +['ÙĦ', 'ÙĨ'] +['ÙĦÙĨ', 'دا'] +['بر', 'Ø´'] +['برش', 'ÙĦÙĪÙĨ'] +['برشÙĦÙĪÙĨ', 'Ø©'] +['à¸ģระ', 'à¸ķุ'] +['à¸ģระà¸ķุ', 'à¹īà¸Ļ'] +['Ġg', 'ı'] +['Ġgı', 'da'] +['à¸Ľà¸£à¸°', 'à¸Ĺัà¸ļ'] +['à¸Ľà¸£à¸°à¸Ĺัà¸ļ', 'à¹ĥà¸Ī'] +['Ġë¶Ī', '구'] +['Ġë¶Ī구', 'íķĺê³ł'] +['ĠÙĨ', 'Ø·'] +['ĠÙĨØ·', 'اÙĤ'] +['ĠÐľ', 'ожеÑĤ'] +['Pr', 'äs'] +['Präs', 'ident'] +['ĠÑģк', 'оÑĢ'] +['ĠÑģкоÑĢ', 'оÑģÑĤÑĮ'] +['Ġ×Ķ×ij', '×ķקר'] +['еÑħ', 'аÑĤÑĮ'] +['Ġg', 'ạo'] +['Ġש×IJ', '×Ļ׳×Ŀ'] +['Ġ×ij׳', '×ķ×Ĵ'] +['Ġ×ij׳×ķ×Ĵ', '×¢'] +['Ġо', 'пиÑģание'] +['Ġucz', 'ni'] +['Ġuczni', 'ów'] +['à¹Ģà¸Ń', 'à¹ĩà¸Ļ'] +['Ġت', 'Ø´'] +['Ġتش', 'رÙĬÙĨ'] +['Ġnh', 'ãn'] +['ë¹', '¨'] +['Ġcaract', 'ère'] +['×¢', '׾×Ļ'] +['×¢×ľ×Ļ', '×Ļ×Ķ'] +['楽ãģĹ', 'ãĤģãĤĭ'] +['ĠÑģ', 'аÑħ'] +['ĠÑģаÑħ', 'аÑĢ'] +['дÑĥм', 'аÑĤÑĮ'] +['ĠÐĴоз', 'можно'] +['ص', 'ÙĬاÙĨ'] +['صÙĬاÙĨ', 'Ø©'] +['öm', 'ür'] +['ส', 'ล'] +['สล', 'à¹ĩ'] +['สลà¹ĩ', 'à¸Ń'] +['สลà¹ĩà¸Ń', 'à¸ķ'] +['ë¡', '¯'] +['Ġth', 'ói'] +['gr', 'Ã¶ÃŁe'] +['Ġksi', 'ÄĻ'] +['ĠksiÄĻ', 'g'] +['ĠÑĢ', 'ом'] +['ĠÑĢом', 'ан'] +['ÙĤ', 'اسÙħ'] +['×ŀ×ij', '×ķ×Ĵ'] +['×ŀ×ij×ķ×Ĵ', 'ר×Ļ×Ŀ'] +['bes', 'ch'] +['besch', 'äft'] +['beschäft', 'ig'] +['×Ķצע', '×Ķ'] +['ĠÃģ', 'rea'] +['ĠзаÑıв', 'к'] +['Ä', '¹'] +['ĠлÑİб', 'ого'] +['Ġ', 'ม'] +['Ġม', 'à¸ģร'] +['Ġมà¸ģร', 'าà¸Ħม'] +['ÑĦ', 'из'] +['ÑĦиз', 'иÑĩеÑģк'] +['ин', 'ÑĦ'] +['инÑĦ', 'ек'] +['инÑĦек', 'ÑĨи'] +['اÙĦ', 'Ø·'] +['اÙĦØ·', 'ائÙģ'] +['Ġкол', 'л'] +['Ġколл', 'екÑĤив'] +['ез', 'жа'] +['Ġس', 'بØŃ'] +['ĠسبØŃ', 'اÙĨ'] +['ĠسبØŃاÙĨ', 'Ùĩ'] +['sch', 'lä'] +['schlä', 'ge'] +['Ġд', 'и'] +['Ġди', 'аг'] +['Ġдиаг', 'ноÑģÑĤ'] +['ĠоÑĤмеÑĤ', 'иÑĤÑĮ'] +['Т', 'Ь'] +['ĠاÙĦ', 'در'] +['ĠاÙĦدر', 'اسÙĬ'] +['עצ', '×ŀ'] +['עצ×ŀ', '×IJ×ķת'] +['Ġdém', 'arch'] +['Ġdémarch', 'e'] +['Ġ×ĺ', '×ķ×¢'] +['Ġ×ĺ×ķ×¢', 'ף'] +['Ġfuncion', 'ários'] +['á»', 'µ'] +['׾', '׼×IJ'] +['׾׼×IJ', '×ķר×Ķ'] +['à¸ĭ', 'à¹Ī'] +['à¸ĭà¹Ī', 'à¸Ńม'] +['ĠÑĩ', 'Ñĥв'] +['ĠÑĩÑĥв', 'ÑģÑĤво'] +['âĸ', '¼'] +['п', 'ÑĥÑī'] +['пÑĥÑī', 'ен'] +['Ġм', 'еÑĢ'] +['ĠмеÑĢ', 'оп'] +['ĠмеÑĢоп', 'ÑĢи'] +['ĠмеÑĢопÑĢи', 'ÑıÑĤиÑı'] +['Ġu', 'çu'] +['Ġuçu', 'ÅŁ'] +['ãĤĴåĪ©ç͍', 'ãģĻãĤĭ'] +['a', 'ÄŁ'] +['aÄŁ', 'lı'] +['ìĺĪ', 'ìĪł'] +['à¹ģ', 'ยà¹Ī'] +['ĠاÙĦÙĥ', 'Ùħ'] +['ĠاÙĦÙĥÙħ', 'بÙĬ'] +['ĠاÙĦÙĥÙħبÙĬ', 'ÙĪØªØ±'] +['ت', 'ÙĪÙĬ'] +['تÙĪÙĬ', 'تر'] +['à¹Ģà¸Ĭ', 'ีà¹Īยว'] +['à¹Ģà¸Ĭีà¹Īยว', 'à¸Ĭา'] +['à¹Ģà¸Ĭีà¹Īยวà¸Ĭา', 'à¸į'] +['á»', 'Ķ'] +['Ġhi', 'ếm'] +['ذا', 'Ùĥرة'] +['Ġ×Ķ×ŀ×Ļ', '×ķ×Ĺ×ĵ'] +['ĠìĪ', 'ľ'] +['ĠìĪľ', 'ê°Ħ'] +['ĠK', 'ı'] +['ĠKı', 'sa'] +['Ġgele', 'ceÄŁi'] +['пÑĢо', 'ÑĦеÑģÑģиона'] +['пÑĢоÑĦеÑģÑģиона', 'л'] +['Ġog', 'ó'] +['Ġogó', 'le'] +['ĠgÅĤ', 'ów'] +['ĠgÅĤów', 'ne'] +['ĠÑģÑĤ', 'илÑĮ'] +['×IJ', 'פ׾'] +['×IJפ׾', '×Ļ×§'] +['×IJפ׾×Ļ×§', 'צ×Ļ×Ķ'] +['สม', 'ารà¹Į'] +['สมารà¹Į', 'à¸Ĺ'] +['สมารà¹Įà¸Ĺ', 'à¹Ĥà¸Ł'] +['สมารà¹Įà¸Ĺà¹Ĥà¸Ł', 'à¸Ļ'] +['Ġth', 'ánh'] +['ÐŁ', 'од'] +['ÐŁÐ¾Ð´', 'ÑĢоб'] +['ÐŁÐ¾Ð´ÑĢоб', 'нее'] +['ĠاÙĦت', 'ÙĪÙĨ'] +['ĠاÙĦتÙĪÙĨ', 'سÙĬ'] +['Ġbah', 'çe'] +['à¹ģà¸ģà¹ī', 'à¸Ľà¸±à¸įหา'] +['é', 'ducation'] +['eu', 'rop'] +['europ', 'ä'] +['europä', 'ische'] +['ĠK', 'si'] +['ĠKsi', 'ÄĻ'] +['ĠëĦ', 'ĺ'] +['ĠëĦĺ', 'ìĸ´'] +['Ġv', 'üc'] +['Ġvüc', 'ud'] +['Ġyay', 'g'] +['Ġyayg', 'ın'] +['Ġnie', 'kt'] +['Ġniekt', 'óry'] +['Ġniektóry', 'ch'] +['ãģŃ', 'ãģĩ'] +['Ġк', 'аж'] +['Ġкаж', 'еÑĤÑģÑı'] +['к', 'аж'] +['каж', 'еÑĤ'] +['ĠاÙĦ', 'دÙĬÙħÙĤرا'] +['ĠاÙĦدÙĬÙħÙĤرا', 'Ø·'] +['ĠاÙĦدÙĬÙħÙĤراط', 'ÙĬØ©'] +['æŃ', '©'] +['æŃ©', 'ãģĦãģ¦'] +['Ġv', 'az'] +['Ġvaz', 'ge'] +['Ġvazge', 'ç'] +['Ġмин', 'ималÑĮ'] +['ĠминималÑĮ', 'н'] +['ãĥij', 'ãĤ¿'] +['ãĥijãĤ¿', 'ãĥ¼ãĥ³'] +['Ġë', 'Ĭ'] +['ĠëĬ', 'IJ'] +['ĠëĬIJ', 'ëĤĮ'] +['ãģ¡', 'ãĤĩãģĨ'] +['ãģ¡ãĤĩãģĨ', 'ãģ©'] +['Ġ', 'à¸ģร'] +['Ġà¸ģร', 'à¸ģà¸İ'] +['Ġà¸ģรà¸ģà¸İ', 'าà¸Ħม'] +['تج', 'دÙĬد'] +['ĠØ´', 'اÙħÙĦ'] +['หลัà¸ģ', 'à¸IJาà¸Ļ'] +['ĠмаÑĢ', 'ÑĪ'] +['ĠмаÑĢÑĪ', 'ÑĢÑĥÑĤ'] +['Ġv', 'ÃŃt'] +['ĠvÃŃt', 'ima'] +['Ġquiz', 'á'] +['ay', 'gı'] +['×ĵ×ijר', '×Ļ×ķ'] +['Ġиз', 'д'] +['Ġизд', 'ели'] +['Ġиздели', 'Ñı'] +['п', 'ла'] +['пла', 'Ñĩ'] +['плаÑĩ', 'ива'] +['ä»»', 'ãģĽ'] +['Ġéquip', 'é'] +['ä¹ħ', 'ãģĹãģ'] +['ä¹ħãģĹãģ', '¶'] +['ä¹ħãģĹãģ¶', 'ãĤĬ'] +['Ġк', 'аÑĤ'] +['ĠкаÑĤ', 'ал'] +['ĠкаÑĤал', 'ог'] +['ส', 'à¹īม'] +['ĠÑĢ', 'ей'] +['ĠÑĢей', 'ÑĤ'] +['ĠÑĢейÑĤ', 'инг'] +['Ġth', 'uyá»ģn'] +['ĠاÙĦÙħ', 'ÙĤدس'] +['esp', 'ère'] +['ãģ«åħ¥', 'ãģ£ãģŁ'] +['หมาย', 'à¹Ģลà¸Ĥ'] +['ת×Ĺ×ķש', 'ת'] +['à¸Ļ', 'à¹Īะ'] +['Ġpe', 'ÅĤ'] +['ĠpeÅĤ', 'ne'] +['Ġpé', 'rd'] +['Ġpérd', 'ida'] +['หม', 'วà¸Ķ'] +['หมวà¸Ķ', 'หมูà¹Ī'] +['иÑĩеÑģк', 'ÑĥÑİ'] +['çµĤ', 'ãĤı'] +['çµĤãĤı', 'ãģ£ãģŁ'] +['Ġ×Ĵ', '×ķ×Ĵ׾'] +['à¸Ĺำ', 'à¸Ħวาม'] +['à¸Ĺำà¸Ħวาม', 'สะà¸Ńาà¸Ķ'] +['Hot', 'éis'] +['Ġз', 'аÑĢ'] +['ĠзаÑĢ', 'егиÑģÑĤ'] +['ĠзаÑĢегиÑģÑĤ', 'ÑĢи'] +['ĠзаÑĢегиÑģÑĤÑĢи', 'ÑĢова'] +['ĠÑģ', 'обÑĭÑĤи'] +['ĠÑģобÑĭÑĤи', 'Ñı'] +['Ġ×ĸ', '׼×IJ'] +['ÙħÙĨظ', 'ÙĪÙħØ©'] +['Ġ×Ķ×ŀ', 'צ'] +['Ġ×Ķ×ŀצ', '×Ļ×IJ×ķת'] +['Ùħ', 'ÙĥÙĪÙĨ'] +['ÙħÙĥÙĪÙĨ', 'ات'] +['ä¸ĬãģĮ', 'ãĤĭ'] +['Ġm', 'ÄĻ'] +['ĠmÄĻ', 'sk'] +['หรืà¸Ń', 'à¹Ģà¸Ľà¸¥à¹Īา'] +['ëĤ', '®'] +['Ġnok', 'tas'] +['Ġnoktas', 'ı'] +['ĠболÑĮÑĪ', 'им'] +['ĠлÑĥÑĩ', 'ÑĪиÑħ'] +['Ø´Ùĩ', 'ÙĬد'] +['à¸Ńำ', 'à¸Ļ'] +['à¸Ńำà¸Ļ', 'วย'] +['à¸Ńำà¸Ļวย', 'à¸Ħวาม'] +['à¸Ńำà¸Ļวยà¸Ħวาม', 'สะà¸Ķวà¸ģ'] +['Ġе', 'в'] +['Ġев', 'ÑĢ'] +['ĠевÑĢ', 'оп'] +['ĠевÑĢоп', 'ей'] +['à¸ī', 'าย'] +['ìĦ', 'Ń'] +['Ùħ', 'Ù쨧'] +['ÙħÙ쨧', 'ÙĪØ¶'] +['ÙħÙ쨧ÙĪØ¶', 'ات'] +['ë¹', 'Į'] +['赤', 'ãģ¡ãĤĥãĤĵ'] +['ĠÑĥдал', 'оÑģÑĮ'] +['ĠÐ¥', 'оÑĤ'] +['ĠХоÑĤ', 'Ñı'] +['przedsiÄĻbior', 'c'] +['ĠH', 'ôm'] +['íķĺìĺĢ', 'ìĬµëĭĪëĭ¤'] +['Ġн', 'аг'] +['Ġнаг', 'ÑĢÑĥз'] +['ĠнагÑĢÑĥз', 'к'] +['Ġ×ij×Ļ׳', '׾×IJ×ķ×ŀ×Ļ'] +['Ġê°ĢëĬ¥', 'íķľ'] +['ĠH', 'ữu'] +['à¸Ń', 'ุà¸Ķ'] +['à¸Ńุà¸Ķ', 'ม'] +['ת', '×ķפ'] +['ת×ķפ', '×¢×Ķ'] +['Ġmi', 'ÅĤo'] +['ĠmiÅĤo', 'ÅĽci'] +['ksi', 'Äħż'] +['ksiÄħż', 'ka'] +['ĠاÙĦÙĦ', 'عبة'] +['à¸ī', 'าà¸ģ'] +['สะ', 'สม'] +['×ŀ', 'תר'] +['×ŀתר', '×Ĺש'] +['Ġlég', 'ère'] +['Ġ׾צ', 'פ'] +['Ġ׾צפ', '×Ļ×Ķ'] +['ĠиÑģÑĤоÑĢ', 'иÑı'] +['Ġ', 'ãĥĪãĥ©'] +['ĠãĥĪãĥ©', 'ãĥĥãĤ¯'] +['ĠãĥĪãĥ©ãĥĥãĤ¯', 'ãĥIJãĥĥãĤ¯'] +['Ġк', 'а'] +['Ġка', 'ÑĦе'] +['×ŀס×ŀ', '×ļ'] +['Ġc', 'üm'] +['Ġcüm', 'le'] +['à¹Ģà¸Ħลืà¹Īà¸Ńà¸Ļ', 'à¹Ħหว'] +['ãģĬ', 'ãģĿ'] +['ãģĬãģĿ', 'ãĤīãģı'] +['ìŀIJ', 'ëıĻ'] +['ìŀIJëıĻ', 'ì°¨'] +['à¸Ńั', 'à¸ķ'] +['à¸Ńัà¸ķ', 'à¹Ĥà¸Ļ'] +['à¸Ńัà¸ķà¹Ĥà¸Ļ', 'มั'] +['à¸Ńัà¸ķà¹Ĥà¸Ļมั', 'à¸ķิ'] +['ĠÅŁ', 'ik'] +['ĠÅŁik', 'ay'] +['ĠÅŁikay', 'et'] +['extr', 'ême'] +['kr', 'ä'] +['krä', 'fte'] +['ëĤ', 'Ļ'] +['íķ', 'ij'] +['ì²', 'Ļ'] +['íĺ', 'Ī'] +['ì°', 'į'] +['âĻ', '¡'] +['ìŀ', 'Ķ'] +['ë¢', '°'] +['íĿ', 'Ķ'] +['íĿ', 'IJ'] +['âĩ', 'Ĵ'] +['ë§', 'Ľ'] +['ìĬ', 'Ī'] +['á»', 'Ĵ'] +['ìĺ', 'µ'] +['âĹ', 'İ'] +['í', 'Ĥ¨'] +['ê¿', 'Ī'] +['ìĪ', '¨'] +['ìĽ', '¨'] +['ë§', '¥'] +['ï½', 'Ģ'] +['ï¼', 'ª'] +['áº', '¨'] +['ãħ', 'İ'] +['Ñ', 'Ĺ'] +['ìĦ', '¬'] +['ì¹', '¼'] +['ï¼', '¶'] +['ìĽ', 'ł'] +['ëŁ', '´'] +['Å', 'ĥ'] +['ëĤ', '¼'] +['ëĭ', 'IJ'] +['âĢ', '¹'] +['ë¦', 'Ń'] +['ì§', 'IJ'] +['âĢ', '¤'] +['Ã', 'ħ'] +['ëľ', '¨'] +['íĦ', '¸'] +['íľ', 'ĺ'] +['ê²', 'ģ'] +['ë´', 'ħ'] +['Ã', 'ĺ'] +['ëŃ', 'Ķ'] +['ëĺ', 'ij'] +['âĹ', 'ĩ'] +['ìĹ', 'ĺ'] +['ï»', '´'] +['ë§', '¹'] +['ï¾', 'Ŀ'] +['ìĬ', '·'] +['íĥ', 'ķ'] +['ï¼', 'ł'] +['ì»', '´'] +['ëł', 'Į'] +['ì½', 'ľ'] +['ï»', '¹'] +['ãħ', 'ł'] +['ì¡', '¸'] +['ëħ', '¹'] +['âĤ', 'º'] +['âĸ', '¶'] +['íĥ', 'IJ'] +['êµ', '´'] +['íij', '¸'] +['Ñ', 'Ķ'] +['íĶ', '½'] +['Ð', 'ħ'] +['ë°', '¤'] +['Ô', 'ģ'] +['ì²', '¨'] +['ì¶', 'ĺ'] +['ë²', 'Ĺ'] +['ë©', '¸'] +['ï¼', '»'] +['ï¼', '½'] +['ï¼', '·'] +['ì°', 'Į'] +['Ã', 'Ĵ'] +['íı', '´'] +['ìĵ', '¸'] +['ì´', 'Į'] +['ëģ', 'Ķ'] +['ëĶ', '©'] +['ëĩ', 'Į'] +['ë©', 'Ģ'] +['ë²', '¨'] +['ï¼', 'µ'] +['ë§', '¡'] +['ëĭ', '«'] +['à¸', '¿'] +['ãģ', '±'] +['ìĩ', '¼'] +['ìº', 'ł'] +['ë®', '¤'] +['ê±', '±'] +['ì»', '¬'] +['âĦ', 'ĥ'] +['ëĶ', '±'] +['ëĥ', 'Ī'] +['ìĭ', '±'] +['íĻ', 'Ī'] +['ëŀ', 'IJ'] +['ìħ', 'Ģ'] +['ìł', 'ł'] +['Ð', 'Ĩ'] +['ëł', 'ī'] +['ï½', 'ħ'] +['ï½', 'ı'] +['íĻ', 'Ģ'] +['ëĽ', '°'] +['á»', '®'] +['í', 'Ĥ¹'] +['ê½', 'ĥ'] +['ï»', '¤'] +['ïº', 'Ķ'] +['êº', '¼'] +['ìķ', 'ī'] +['âĻ', '¦'] +['ï½', 'ģ'] +['ìĵ', '´'] +['ãĢ', 'ī'] +['ì°', '®'] +['ì¤', 'ĺ'] +['á»', 'ª'] +['ëģ', 'Ħ'] +['ëIJ', '¨'] +['ìķ', 'Į'] +['íĿ', 'ĺ'] +['íħ', 'IJ'] +['ãĢ', 'Ī'] +['ê²', 'ª'] +['ëĭ', '¥'] +['ê²', '¼'] +['á»', 'Į'] +['ë§', '¨'] +['ëģ', 'Ĭ'] +['ë²', '¤'] +['ëij', 'Ķ'] +['íĿ', '¡'] +['á»', '¬'] +['ë¬', 'ĺ'] +['ãģ', 'ī'] +['ëŀ', '«'] +['íĶ', 'Ī'] +['í', 'ħį'] +['ìŀ', 'ĥ'] +['ï½', 'ī'] +['ìģ', 'ľ'] +['âĸ', '½'] +['ë¬', '»'] +['âĸ', '³'] +['ï¼', '¸'] +['ìģ', 'ĺ'] +['ì¶', '°'] +['ìĬ', '´'] +['ìķ', '±'] +['ìĩ', 'Ħ'] +['áº', '®'] +['ï´', '¿'] +['ï´', '¾'] +['âĤ', '½'] +['ëĦ', 'ĵ'] +['ë£', '©'] +['ì³', '¤'] +['ê´', 'ľ'] +['Ã', 'Ļ'] +['á»', 'ľ'] +['ï¿', '£'] +['ëĵ', 'Ń'] +['ë©', 'ĺ'] +['ê»', '´'] +['ëł', '´'] +['Ð', 'ĥ'] +['ë¬', 'µ'] +['ì§', 'Ŀ'] +['ãģ', 'º'] +['ðŁĺ', 'Ĥ'] +['ëŀ', '¬'] +['ìł', 'Ĭ'] +['ê´', 'Ħ'] +['ìŀ', 'Ĭ'] +['íŀ', 'Į'] +['ìĦ', '¯'] +['âĪ', 'Ģ'] +['âĸ', '¡'] +['ëĢ', 'Į'] +['ëŀ', 'Ļ'] +['ï½', 'ĥ'] +['áº', '¶'] +['ï¾', 'Ħ'] +['ïº', 'ĺ'] +['ë¹', '¼'] +['Ã', 'Į'] +['âĸ', '·'] +['ê¸', 'į'] +['ë©', 'ĭ'] +['ãģ', 'ĥ'] +['ìĺ', 'Ĩ'] +['ìĺ', '®'] +['ëª', '¬'] +['ë¡', '¤'] +['ëł', '¬'] +['ëĬ', '¦'] +['âĸ', 'ª'] +['ì¼', 'ĵ'] +['ìľ', 'Ī'] +['ì§', '§'] +['ï½', '½'] +['ëĥ', 'ī'] +['ï¾', 'Į'] +['ëĺ', 'IJ'] +['ï¼', 'ĥ'] +['á»', 'Ħ'] +['ì´', '¬'] +['ì¶', '¤'] +['ï¼', '¹'] +['ï»', 'Ń'] +['âĤ', '«'] +['ï½', 'ĩ'] +['ìĺ', '·'] +['ëĸ', '¨'] +['âī', '«'] +['ë¦', '¿'] +['âľ', '¨'] +['Ù', '±'] +['ì¯', '¤'] +['ê¹', 'Ķ'] +['ðŁĺ', 'Ĭ'] +['ìĪ', '«'] +['ê³', '±'] +['êµ', '³'] +['ï½', 'ĭ'] +['à¸', 'Į'] +['Ä', 'ł'] +['ëĶ', '¸'] +['ë°', 'ij'] +['ìħ', 'ĭ'] +['íİ', '´'] +['âľ', 'ħ'] +['íĥ', 'ij'] +['ëĪ', 'ĩ'] +['íı', '¼'] +['ðŁĺ', 'į'] +['ìĺ', 'Ľ'] +['ï»', '£'] +['Ñ', 'ĺ'] +['ì©', 'Į'] +['ë¦', 'ħ'] +['ìĿ', 'į'] +['ï½', '¸'] +['ëį', 'ľ'] +['ãģ', 'ħ'] +['íİ', '¼'] +['ëĭ', 'Ŀ'] +['ë¿', 'Į'] +['ì¼', '°'] +['ìĭ', '«'] +['ë°', '¥'] +['íĽ', 'Į'] +['ì¨', 'Į'] +['ë¹', 'Ļ'] +['ï½', 'İ'] +['ë´', 'Ħ'] +['ìĦ', '¹'] +['ï½', '²'] +['ìĮ', 'ĵ'] +['Ò', 'ij'] +['ë°', 'į'] +['ëł', 'Ģ'] +['íĨ', '¤'] +['ï½', '¯'] +['ë¤', 'Ħ'] +['ê½', '¤'] +['ï½', 'Ĵ'] +['ìķ', '¨'] +['ï½', '¼'] +['ê¹', 'IJ'] +['íģ', 'IJ'] +['âĦ', 'ĸ'] +['ë§', 'º'] +['ïº', '®'] +['ëħ', 'ģ'] +['ê²', '¸'] +['ï»', 'ł'] +['íĬ', 'ľ'] +['Å', '¹'] +['ë¥', 'Ń'] +['ëĪ', 'ī'] +['ï½', 'Ķ'] +['íĮ', '¬'] +['ìŀ', 'ĩ'] +['ï', '¬ģ'] +['ï»', '¨'] +['ëij', '¥'] +['ëŀ', 'Ħ'] +['Ù', '¬'] +['íĭ', '´'] +['ìŀ', 'ī'] +['Ú', '¾'] +['ìĽ', 'ħ'] +['ï»', '®'] +['ëĭ', 'ī'] +['âī', 'ª'] +['âĹ', 'Ħ'] +['ëĪ', 'Į'] +['íĽ', '¼'] +['ì¤', 'į'] +['Å', '¸'] +['ì¤', '¬'] +['ì¾', 'Į'] +['ï½', 'ĵ'] +['ï¾', 'Ĭ'] +['ðŁı', '»'] +['ï¾', 'ī'] +['Ð', 'ģ'] +['íĺ', 'IJ'] +['ï¾', 'Ļ'] +['ê¼', '¬'] +['íŀ', 'IJ'] +['âĢ', '¥'] +['ëŁ', 'Ń'] +['ë§', 'ŀ'] +['ìĥ', '¤'] +['ïº', 'Ĵ'] +['íĭ', '±'] +['ë½', 'ij'] +['Ã', 'ķ'] +['âĪ', 'ļ'] +['ëĤ', 'Ħ'] +['ê¹', 'Ŀ'] +['ëĨ', 'Ī'] +['áº', 'º'] +['ìħ', 'Ī'] +['ìĮ', 'į'] +['âĢ', '¡'] +['ï¼', '±'] +['ìģ', '¨'] +['âĺ', 'º'] +['ëĴ', '·'] +['ìĺ', '³'] +['ðŁij', 'į'] +['ëª', '½'] +['ëĤ', 'Ń'] +['ïº', 'Ń'] +['ë©', 'Ī'] +['á»', 'Ī'] +['íķ', 'Ģ'] +['ëĭ', 'Ļ'] +['ë¦', 'ĩ'] +['ìķ', '¤'] +['ìį', '¼'] +['ãĥ', 'µ'] +['Ñ', '£'] +['ìľ', 'Ĺ'] +['â', 'ŃIJ'] +['ï¾', 'ĺ'] +['íĹ', '¬'] +['ê¾', '¼'] +['ìķ', 'Ĺ'] +['ï»', 'Į'] +['ê±', '·'] +['ëħ', 'ķ'] +['ë¡', '±'] +['ìķ', 'Ĭ'] +['ï¾', 'Ģ'] +['ìĩ', 'ł'] +['íĮ', '©'] +['ïº', 'ª'] +['ë§', 'Ļ'] +['ï¼', '¿'] +['ê¿', 'Ķ'] +['íİ', 'ľ'] +['ë£', '¸'] +['íĶ', 'Ķ'] +['ï»', '³'] +['ëı', 'ķ'] +['ìĭ', '¼'] +['á»', 'İ'] +['ë§', 'ĺ'] +['ì¢', 'ĭ'] +['íĨ', '¡'] +['ï½', '±'] +['íĿ', 'ij'] +['á»', '¸'] +['ì¦', 'Į'] +['ì¹', '¸'] +['ëŃ', 'ĺ'] +['ï¾', 'Ĺ'] +['ï»', 'ĭ'] +['íĬ', 'Ģ'] +['ë¥', 'Ļ'] +['ì½', '©'] +['ëģ', 'Ĺ'] +['ëį', '´'] +['ìħ', 'ľ'] +['Â', '¸'] +['ë»', 'IJ'] +['ìĥ', 'µ'] +['ê²', 'IJ'] +['ëĵ', '¬'] +['ë£', '°'] +['ãħ', 'ĭ'] +['ìĹ', 'ī'] +['á»', 'ĸ'] +['ëĦ', 'Į'] +['ï½', '¶'] +['ë´', 'ĩ'] +['ëĤ', '³'] +['ãĤ', 'ľ'] +['ëĸ', '»'] +['íİ', 'Ģ'] +['ëį', '©'] +['íķ', '¸'] +['Ã', '·'] +['ê¼', '¼'] +['ëĶ', 'ľ'] +['ë°', '´'] +['ë©', 'į'] +['âĹ', '¯'] +['ìĹ', 'ij'] +['ìĻ', '¼'] +['ïº', 'ij'] +['ë¶', 'ķ'] +['ë¡', '¬'] +['ï½', 'Į'] +['íĨ', '¨'] +['ïº', '´'] +['ëł', 'ĺ'] +['ê°', '¤'] +['ìĪ', '²'] +['Ñ', 'ĵ'] +['ìħ', 'ī'] +['ï»', 'ĵ'] +['ëĪ', 'Ķ'] +['ëį', '§'] +['âĢ', '¼'] +['ï»', '²'] +['ê°', '±'] +['ê¿', 'Ģ'] +['ëĭ', '·'] +['áº', '¸'] +['áº', 'ª'] +['Æ', 'Ĵ'] +['ëį', '¤'] +['ìĪ', 'Ń'] +['ï½', 'Ĥ'] +['ï½', 'Ī'] +['Å', 'ł'] +['ë£', '¬'] +['Ñ', 'µ'] +['ëĸ', '¡'] +['ëĥ', 'Ħ'] +['ìĦ', '°'] +['ëĵ', 'Ī'] +['ï¾', 'ĥ'] +['ëĩ', '¨'] +['ï½', 'IJ'] +['êµ', '½'] +['ìĹ', '½'] +['ëĤ', 'Ģ'] +['ë¬', '¶'] +['ï½', '·'] +['ìı', 'Ł'] +['íĺ', 'Ķ'] +['ê¼', 'Ī'] +['ëģ', 'Ī'] +['ì¥', 'IJ'] +['ïº', 'Ĺ'] +['Ä', 'Į'] +['ëĪ', 'ł'] +['ëĸ', '¼'] +['íĢ', '´'] +['âī', '¥'] +['ëĭ', 'Ń'] +['ì±', 'Ļ'] +['ê»', 'ı'] +['ë©', '¤'] +['ìĥ', 'ĺ'] +['ëį', '®'] +['ë£', '¡'] +['ìĤ', '½'] +['ãĪ', 'ľ'] +['Ä', '¨'] +['âĢ', '§'] +['ï½', 'º'] +['Ä', '£'] +['ì¦', 'ī'] +['ï¼', '¼'] +['Û', '©'] +['âĪ', 'Ļ'] +['ë°', 'ı'] +['ë¹', 'ħ'] +['ðŁĺ', 'Ľ'] +['íĪ', '´'] +['ðŁĴ', 'ķ'] +['ãĢ', 'Ĵ'] +['ìŀ', 'ĺ'] +['ïº', '¤'] +['ï½', 'ĸ'] +['ë©', 'ľ'] +['ë²', '¼'] +['ëĿ', 'Ħ'] +['ëļ', 'ľ'] +['ï»', 'ĺ'] +['ìĥ', 'Į'] +['ï½', 'Ħ'] +['ì©', 'Ķ'] +['ï½', 'Ļ'] +['ïº', '©'] +['Û', 'ŀ'] +['âĺ', 'İ'] +['ìł', '¤'] +['ëIJ', '©'] +['Å', 'Ŀ'] +['âŀ', '¡'] +['ï»', '§'] +['Ð', 'ı'] +['ì«', 'ĵ'] +['ê³', '½'] +['É', 'ij'] +['ãĥ', '²'] +['ëĤ', '«'] +['ë¦', 'ī'] +['ì¢', 'ģ'] +['ë°', 'Ń'] +['ðŁĺ', 'ģ'] +['ë¹', 'µ'] +['ì²', '©'] +['ì»', 'µ'] +['ðŁĺ', 'ĺ'] +['ë±', 'ħ'] +['âī', 'Ī'] +['ë¹', 'ļ'] +['ï»', 'ľ'] +['ðŁĻ', 'ı'] +['íģ', '°'] +['ìĦ', 'ŀ'] +['ï¾', 'ļ'] +['ìĺ', '¹'] +['ë¼', 'Ī'] +['ëĤ', '¯'] +['ëŀ', '©'] +['íļ', '¡'] +['ï½', 'ķ'] +['íĥ', 'ĵ'] +['ëĿ', 'ł'] +['ê³', 'ģ'] +['ëĵ', 'Ģ'] +['ìĹ', 'ł'] +['ï¼', 'º'] +['ë§', 'ij'] +['ëĭ', '¿'] +['ì¿', '¨'] +['ãİ', '¡'] +['Ð', 'Ĭ'] +['íĦ', '±'] +['Å', '¨'] +['ïº', '³'] +['ï¾', 'ı'] +['âĭ', 'ħ'] +['ê¼', '´'] +['âī', '¤'] +['íĮ', 'ģ'] +['Î', '©'] +['ê¶', '¤'] +['ìĪ', 'į'] +['âľ', '¿'] +['ì½', '¤'] +['ëĪ', 'ħ'] +['íĨ', '±'] +['ãħ', 'ľ'] +['áIJ', 'ħ'] +['Å', 'Ĵ'] +['ðŁij', 'ī'] +['ï»', '¦'] +['Ð', 'ª'] +['ë¥', 'ľ'] +['íķ', '«'] +['ï¾', 'ĭ'] +['âĻ', '«'] +['ê¹', 'ľ'] +['ë°', '¸'] +['ëĶ', 'ĺ'] +['íĿ', 'ī'] +['ï¾', 'ģ'] +['ï¾', 'Ľ'] +['ëł', 'Ľ'] +['ê²', '¹'] +['ì¿', '¼'] +['ï»', '¬'] +['âŀ', '¤'] +['ðŁĻ', 'ģ'] +['ïº', 'ł'] +['ëĨ', '¨'] +['ë¯', '¹'] +['ê¸', 'ĭ'] +['ë»', 'Ķ'] +['ê¹', 'ĥ'] +['ëij', 'ij'] +['íĭ', '¸'] +['íİ', 'Ļ'] +['âŀ', 'ĸ'] +['ãĥ', '½'] +['ì§', 'ļ'] +['ï½', '¬'] +['ï»', '¥'] +['íĮ', '½'] +['âĢ', 'Ĵ'] +['ì', 'ĮĢ'] +['ìŃ', 'ī'] +['ëļ', '±'] +['ãĤ', 'ŀ'] +['íĭ', 'Ī'] +['ãĤ', 'IJ'] +['ëī', 'ĺ'] +['Î', '£'] +['ê³', '°'] +['ë¹', 'Ĺ'] +['ï¾', 'İ'] +['ðŁĺ', 'Ń'] +['íĿ', 'ł'] +['ìĹ', '¿'] +['ê°', 'ļ'] +['ì¤', 'Į'] +['ë§', 'µ'] +['ï½', '³'] +['ãģ', '¢'] +['ï»', 'Ĺ'] +['âī', '¦'] +['Ú', '¤'] +['ë', 'łģ'] +['ê¼', '½'] +['ï»', '«'] +['âī', '§'] +['ì´', 'Ľ'] +['ìł', 'Ŀ'] +['áº', '°'] +['âĻ', '£'] +['ìº', 'ĺ'] +['âĪ', 'ĩ'] +['ê²', 'ī'] +['ë°', 'Ł'] +['ï»', 'Ķ'] +['íĸ', 'ĩ'] +['âĸ', 'Ĵ'] +['ðŁij', 'ı'] +['Ã', 'ŀ'] +['ðŁĺ', 'Ĩ'] +['ïº', '¼'] +['âĿ', 'Ĺ'] +['ìº', 'Ķ'] +['ì¹', '©'] +['ëĸ', '¤'] +['ëĥ', 'ħ'] +['âĶ', 'ľ'] +['ï½', '»'] +['Î', 'Ķ'] +['áĥ', '¦'] +['ìŀ', 'İ'] +['âĺ', 'Ģ'] +['âĪ', '¼'] +['ðŁĶ', '¥'] +['ë°', 'Į'] +['ìł', 'ĸ'] +['íĹ', 'Ľ'] +['Î', 'ķ'] +['ïº', 'ĥ'] +['ë¶', 'ī'] +['âĪ', 'ŀ'] +['íĥ', 'Ń'] +['Ã', 'ĭ'] +['âģ', 'Ħ'] +['ãħ', 'ĩ'] +['ëĦ', '¥'] +['ëĭ', '®'] +['ëł', '·'] +['íĮ', 'Ŀ'] +['ìº', '¡'] +['ë·', 'Ķ'] +['ì©', 'į'] +['íĤ', '´'] +['ëļ', '«'] +['âĵ', 'Ĵ'] +['íķ', 'į'] +['âĻ', 'Ĥ'] +['ï¾', 'Ĩ'] +['âĨ', '©'] +['ìį', '©'] +['ïº', 'ķ'] +['íĿ', 'Ļ'] +['Ñ', 'ľ'] +['íĤ', '·'] +['íĿ', '°'] +['íĥ', '±'] +['ëķ', 'IJ'] +['ï¾', 'Ĵ'] +['×', 'ĥ'] +['ëĮ', 'Ħ'] +['ìĺ', '´'] +['ìķ', 'µ'] +['ê¹', '¥'] +['ëŀ', 'Ń'] +['ìª', '¼'] +['ãİ', 'Ŀ'] +['ðŁĺ', 'ħ'] +['ëı', 'ĭ'] +['ëª', '«'] +['ïº', '¸'] +['ë®', '¬'] +['ë²', 'ħ'] +['ëij', 'ł'] +['ìħ', '°'] +['ì»', '·'] +['ëĶ', 'ª'] +['ëħ', 'Ķ'] +['ãħ', '¡'] +['ìĶ', '»'] +['íķ', 'ı'] +['ëį', '±'] +['ïº', '¨'] +['ï¾', 'į'] +['ï½', 'µ'] +['ì¢', 'Ģ'] +['íİ', 'Į'] +['ï»', '°'] +['ïº', '£'] +['Æ', '£'] +['ð٤', '£'] +['ï·', 'º'] +['ëĤ', 'ļ'] +['âĭ', 'Ĩ'] +['ë³', 'į'] +['ðŁĺ', 'Ħ'] +['ìĸ', 'Ģ'] +['ìĻ', 'ł'] +['ëĨ', 'Ķ'] +['íĹ', '¨'] +['ï»', 'Ľ'] +['ï»', 'Ŀ'] +['á»', '¶'] +['ìĸ', 'ĺ'] +['ìİ', 'Ħ'] +['Ú', 'Ĩ'] +['ï»', 'ŀ'] +['ëĢ', 'IJ'] +['ê²', 'Ķ'] +['ï»', 'µ'] +['âĹ', '¦'] +['íļ', 'Ł'] +['ê¹', 'ģ'] +['ê°', 'ĵ'] +['ëĶ', '´'] +['ìı', 'ĺ'] +['ëļ', 'Ŀ'] +['á»', 'ł'] +['ëŀ', '´'] +['ëĦ', 'ī'] +['âĺ', 'ŀ'] +['ï½', 'ĺ'] +['Å', '½'] +['ë¦', 'İ'] +['âĸ', '¬'] +['ëŃ', 'ī'] +['âĩ', 'Ľ'] +['ìį', '¬'] +['ïº', 'Ł'] +['Ë', 'ľ'] +['ë¶', 'ĵ'] +['ìĽ', '°'] +['Å', 'ľ'] +['ëŃ', 'ĩ'] +['á»', '²'] +['Ë', 'ļ'] +['ëķ', 'Ģ'] +['âĺ', 'ij'] +['ðŁı', '¼'] +['ìĸ', '½'] +['âĮ', 'Ĵ'] +['Ð', 'İ'] +['É', '¾'] +['íĮ', '¡'] +['ï¾', 'ħ'] +['ìŀ', 'Ń'] +['ï½', '¨'] +['ì¹', '«'] +['ìľ', 'Į'] +['Ò', 'Ľ'] +['êµ', '¿'] +['ëĭ', '¦'] +['âĶ', 'Ķ'] +['ï¾', 'ij'] +['ì§', 'ĸ'] +['ìº', 'Ħ'] +['ãĢ', 'ĥ'] +['Ê', '¼'] +['ê²', 'Ł'] +['ï½', '§'] +['Ä', '¢'] +['íİ', 'ł'] +['ë§', '·'] +['ê°', 'ĩ'] +['ìĭ', '¹'] +['ðŁĴ', '¦'] +['ï¾', 'ľ'] +['ëĬ', 'Ļ'] +['ë²', '¡'] +['Å', '¿'] +['ðŁĺ', 'ĭ'] +['ðŁĴ', 'ª'] +['ì¿', 'Ħ'] +['ë©', 'ķ'] +['ìŃ', '¤'] +['ëĬ', 'Ħ'] +['ðŁĮ', '¸'] +['ãĤ', 'Ŀ'] +['Ç', 'İ'] +['ï½', 'ļ'] +['Ä', 'Ĺ'] +['ëģ', 'ĵ'] +['ê¶', 'IJ'] +['áµ', 'ī'] +['ãĥ', 'Ĥ'] +['ê»', 'į'] +['ðŁĺ', '¦'] +['ãĢ', 'Ŀ'] +['ð٤', 'Ĺ'] +['Ñ', 'Ł'] +['ìĹ', 'İ'] +['âľ', 'Į'] +['ìī', 'IJ'] +['Ã', 'Ĩ'] +['íĹ', 'IJ'] +['ðŁİ', 'ī'] +['Î', 'ij'] +['ï½', 'Ń'] +['ðŁĴ', 'Ļ'] +['ìĽ', '¬'] +['íĢ', 'ĺ'] +['ï»', '¢'] +['ðŁĺ', 'İ'] +['íij', '¼'] +['íĿ', '©'] +['ï»', 'Ħ'] +['íħ', 'Ģ'] +['ëł', 'IJ'] +['ì¥', '¬'] +['Ð', 'ĭ'] +['ìĥ', '·'] +['ëľ', '¬'] +['ðŁĺ', 'ĥ'] +['ëĦ', '¬'] +['ë¥', '¨'] +['ìĽ', 'į'] +['ï½', 'Ĩ'] +['ï½', '´'] +['ãĥ', 'ħ'] +['Ã', 'ı'] +['ï»', 'ª'] +['âĻ', 'ł'] +['ëĬ', '¬'] +['ë±', 'Ģ'] +['ë°', 'ĭ'] +['ìĥ', 'Ģ'] +['ï½', '¾'] +['ëĤ', '±'] +['ì»', '¸'] +['ðŁĴ', 'ĸ'] +['ðŁij', 'Į'] +['Ñ', 'ŀ'] +['ì§', '±'] +['Ë', 'Ĩ'] +['ðŁĵ', 'ļ'] +['âŃ', 'ķ'] +['ï¬', 'Ĥ'] +['ï»', '¡'] +['ëij', '¬'] +['íĪ', '¼'] +['âĸ', '¸'] +['ê°', '¯'] +['ê¹', 'ħ'] +['ï½', '®'] +['ëĺ', '¥'] +['Ä', '¡'] +['íĮ', 'Ł'] +['Ð', 'Į'] +['ìĨ', 'Ł'] +['ïº', 'ĵ'] +['ï»', '¼'] +['Ã', 'Ľ'] +['ãĥ', '¾'] +['ëĮ', 'ĵ'] +['íĴ', 'ĭ'] +['ìķ', 'ĵ'] +['ï½', '¹'] +['ëĤ', '¡'] +['ðŁij', 'ĩ'] +['áº', '¼'] +['ãĢ', 'Ł'] +['ðŁĮ', 'Ł'] +['íĥ', 'ł'] +['ãĢ', 'Ĩ'] +['âĢ', 'Ł'] +['ë¸', 'IJ'] +['ðŁĮ', '¹'] +['ìł', '¼'] +['ðŁĵ', 'Į'] +['ìĶ', '¬'] +['âĹ', 'Ģ'] +['ðŁĴ', 'ĵ'] +['ê¹', 'İ'] +['ìĤ', 'IJ'] +['ìĶ', 'Į'] +['Ñ', 'Ľ'] +['âĶ', 'Ī'] +['ë²', '³'] +['ãİ', 'ŀ'] +['Õ', '¡'] +['íĤ', 'µ'] +['ð٤', 'Ķ'] +['ëĢ', 'Ķ'] +['ìĬ', 'IJ'] +['íĻ', 'ī'] +['âľ', '¦'] +['ëľ', '¯'] +['ìł', '¯'] +['ëĶ', '§'] +['Î', '¦'] +['Ë', 'Ī'] +['ìī', '¼'] +['âĹ', 'Ĭ'] +['ëľ', '©'] +['ëľ', '°'] +['ï¾', 'IJ'] +['ë¿', 'Ķ'] +['ìĹ', '®'] +['ì·', 'Į'] +['ïº', '§'] +['Î', 'Ĵ'] +['ëµ', 'Ļ'] +['ï»', 'Ĭ'] +['ì°', 'Ķ'] +['íİ', 'Ħ'] +['ðŁĴ', 'Ĺ'] +['áº', '´'] +['ì°', '¢'] +['íľ', '¼'] +['ê½', 'Ĥ'] +['ì±', 'Ķ'] +['ìī', '´'] +['âĸ', '¾'] +['íĪ', '°'] +['ëĭ', 'Ľ'] +['âĿ', '£'] +['ï½', 'ª'] +['ðŁĴ', 'ľ'] +['Ë', 'ĺ'] +['ãħ', '¤'] +['âĨ', 'Ĺ'] +['íĸ', 'Ħ'] +['âĻ', '¬'] +['ìķ', '°'] +['ïº', 'ľ'] +['âī', '¡'] +['ãĢ', 'ĵ'] +['ìij', '¥'] +['íĮ', 'į'] +['íī', 'ģ'] +['ë»', 'Ĺ'] +['íľ', 'ł'] +['íľ', '©'] +['âľ', 'Ī'] +['íĢ', 'Ħ'] +['ìĸ', 'ĩ'] +['ì¢', 'ĩ'] +['íŀ', 'Ļ'] +['ëª', '¹'] +['ãĤ', 'Ľ'] +['ðŁĺ', '±'] +['ëį', 'Ł'] +['à¹', 'ħ'] +['êµ', '¶'] +['Ù', '«'] +['ìĶ', 'ģ'] +['âľ', 'ª'] +['ï¾', 'Ī'] +['ðŁĻ', 'Į'] +['âļ', '¡'] +['Î', 'ļ'] +['ì¼', 'Ī'] +['ï¾', 'Ķ'] +['ï¾', 'Ĥ'] +['êµ', 'ī'] +['ïº', '»'] +['ðŁĴ', 'ĭ'] +['á¹', '£'] +['Ó', 'Ļ'] +['ìĨ', 'ľ'] +['ìĹ', '£'] +['âľ', '©'] +['ìľ', 'Ļ'] +['ïº', '°'] +['áº', '²'] +['ìŀ', '£'] +['âĿ', 'Į'] +['âĺ', 'ģ'] +['ìķ', 'İ'] +['Ä', '½'] +['Û', 'ģ'] +['ãĦ', '±'] +['ëŁ', '¿'] +['íĮ', '¸'] +['ê½', 'ī'] +['ìı', 'ł'] +['ðŁį', 'Ģ'] +['âĨ', 'Ķ'] +['ëŃ', '¡'] +['ï»', 'ģ'] +['ï¼', 'Ħ'] +['ðŁĴ', '¥'] +['âĺ', 'Ľ'] +['íĹ', '·'] +['ëij', '¡'] +['Î', 'ł'] +['Î', '¤'] +['âĦ', 'ĵ'] +['ïº', '·'] +['Î', 'Ļ'] +['ëı', 'Ķ'] +['ì§', '¤'] +['âĶ', 'ĥ'] +['ãĦ', '·'] +['Ç', 'Ĵ'] +['ðŁ¥', '°'] +['ëĶ', 'ķ'] +['ìļ', '¥'] +['ì¸', 'Ħ'] +['íĽ', 'Ķ'] +['ïº', 'ĩ'] +['ïº', '¬'] +['ðŁĺ', '¢'] +['ë¹', '¡'] +['ìĶ', '¹'] +['Å', '³'] +['Ë', 'Ŀ'] +['íİ', 'ij'] +['ï¾', 'ĵ'] +['ðŁĴ', 'ļ'] +['ëĬ', 'ij'] +['êº', '¾'] +['íĨ', '°'] +['Ã', '¿'] +['Ð', 'Ħ'] +['ëĮ', 'IJ'] +['ë½', 'Ģ'] +['ì·', 'Ħ'] +['ðŁ', 'ĵį'] +['ðŁĻ', 'Ī'] +['âĹ', 'Ī'] +['ê¿', 'ĩ'] +['ì¼', 'Ħ'] +['íİ', '«'] +['ðŁĩ', '·'] +['âĶ', 'ĭ'] +['âļ', 'ł'] +['ë±', 'ī'] +['ì', 'į°'] +['ìĻ', 'Ī'] +['É', 'ª'] +['ïº', 'ĭ'] +['ðŁĺ', 'ľ'] +['Î', 'Ł'] +['ðŁ', 'ĻĤ'] +['âļ', '½'] +['Å', 'Ī'] +['ë¹', 'Ķ'] +['íĮ', 'ľ'] +['à¹', 'ı'] +['ìĸ', '¹'] +['íĪ', 'Ń'] +['ðŁ¥', 'ĩ'] +['ãĦ', '´'] +['ëĶ', '¥'] +['ìŃ', 'Ī'] +['âĪ', 'Ĩ'] +['ëĸ', '³'] +['ë±', 'ĥ'] +['ìŀ', '¦'] +['ï»', 'IJ'] +['Î', 'ľ'] +['âľ', '§'] +['Ï', 'į'] +['ìł', 'ĵ'] +['âĹ', 'ķ'] +['ëĴ', 'Ģ'] +['ï»', 'Ģ'] +['ðŁĶ', '´'] +['ê½', 'ģ'] +['ëĮ', 'Ī'] +['ëİ', 'Į'] +['ãĤ', 'İ'] +['â¦', 'ģ'] +['ì½', '§'] +['ï¯', '¾'] +['âĿ', '¯'] +['à¸', 'ħ'] +['ðŁĻ', 'Ħ'] +['âĿ', 'Ģ'] +['ðŁĶ', '¹'] +['âĩ', 'IJ'] +['êµ', 'µ'] +['âĩ', 'Ķ'] +['ë¶', 'IJ'] +['ðŁĴ', 'Ľ'] +['Î', '¾'] +['íĥ', '¬'] +['âĿ', 'Ħ'] +['Ò', '£'] +['ãĢ', '°'] +['âĪ', 'ij'] +['âĺ', '¼'] +['âī', 'ł'] +['Ò', '¯'] +['ïº', '¯'] +['ê¿', '¨'] +['âľ', 'ĸ'] +['Ê', 'ĸ'] +['íĢ', 'Ģ'] +['ê¾', 'Ģ'] +['íĹ', 'Ŀ'] +['âĶ', '£'] +['ãİ', 'ľ'] +['ëĶ', 'Ľ'] +['ëľ', '¸'] +['ï', 'º«'] +['ê¿', '°'] +['ðŁĩ', '¹'] +['Ç', 'IJ'] +['Û', 'Ĵ'] +['ë£', '»'] +['ïº', 'ĸ'] +['Ñ', 'ļ'] +['ëĬ', 'ł'] +['Û', 'ķ'] +['ê¹', '¡'] +['ë¿', 'ľ'] +['ì²', '¼'] +['ï¨', 'ij'] +['ë¥', 'µ'] +['ìį', '¸'] +['íħ', 'ħ'] +['íij', '¹'] +['Ö', 'Ģ'] +['ï³', 'Į'] +['ãħ', '£'] +['ìij', '¤'] +['ì½', 'ķ'] +['ëķ', 'ł'] +['ðŁĮ', '¿'] +['íĥ', 'Ķ'] +['ìĽ', 'ģ'] +['Î', '¶'] +['âŀ', 'ľ'] +['ìĬ', 'ĺ'] +['íĽ', 'Ĺ'] +['ë©', '§'] +['ìī', 'ĺ'] +['Õ', '¶'] +['á¹', 'ĩ'] +['ðŁİ', 'ģ'] +['ï½', '¿'] +['ï¼', 'Ĥ'] +['á¼', 'IJ'] +['âľ', 'ķ'] +['âŀ', '¢'] +['ëĦ', '¨'] +['ì»', '«'] +['ì¯', 'Ķ'] +['ì°', 'ľ'] +['ðŁĴ', '°'] +['íħ', 'Ŀ'] +['ãİ', 'ı'] +['ë³', '¶'] +['Ò', 'ĵ'] +['âĨ', '³'] +['ìĥ', '´'] +['íģ', 'ĺ'] +['âĸ', 'Ģ'] +['ë²', 'Ļ'] +['à¸', 'ĥ'] +['á½', '¶'] +['Ä', 'ķ'] +['â¬', 'ĩ'] +['ë¤', 'ĺ'] +['ðŁİ', 'µ'] +['âľ', 'ļ'] +['ïº', 'ı'] +['Î', '¡'] +['âĹ', 'ī'] +['ðŁĴ', '«'] +['Ð', 'Ī'] +['ìĸ', 'Ħ'] +['ì§', 'Ļ'] +['ï»', 'ĥ'] +['ðĿij', 'Ĵ'] +['ëŃ', 'Ħ'] +['âĿ', '¥'] +['âĿ', 'ĸ'] +['âĺ', 'Ŀ'] +['Ê', '¹'] +['á¸', '¥'] +['âĢ', '¿'] +['ãħ', 'ħ'] +['ê¸', 'ģ'] +['ëķ', '¡'] +['ëį', '¥'] +['âĪ', '©'] +['ê»', 'Ħ'] +['ë®', 'Į'] +['Ò', '±'] +['âĪ', 'Ĺ'] +['ëł', 'Ļ'] +['ïº', 'Į'] +['Ë', 'IJ'] +['ðŁĺ', '³'] +['ðŁij', '©'] +['ðŁİ', '¶'] +['ì¿', 'µ'] +['ð٤', '©'] +['ê·', '¤'] +['ëĮ', 'Ķ'] +['ïº', 'IJ'] +['Ï', 'İ'] +['ì¶', '¥'] +['ï½', 'Ĭ'] +['á¹', 'Ń'] +['ë¤', '¼'] +['âĸ', '«'] +['ì§', 'ł'] +['á¼', 'Ģ'] +['ê»', 'ij'] +['ëĮ', 'ģ'] +['íĢ', '¸'] +['âĻ', 'Ľ'] +['ðŁĴ', 'ŀ'] +['âĸ', '°'] +['ðĿij', 'ĸ'] +['ëĿ', '¤'] +['à¤', '¦'] +['ì´', 'ĺ'] +['ðŁĺ', 'ĩ'] +['ëĶ', '¤'] +['Î', 'Ĺ'] +['ðŁĻ', 'ĩ'] +['Ë', 'Ľ'] +['ì©', '¡'] +['âĪ', '§'] +['Õ', '¥'] +['Ñ', 'Ļ'] +['ëIJ', '¬'] +['ëĸ', 'Ħ'] +['ðŁĮ', '·'] +['ìĹ', 'Į'] +['ðŁĺ', '¥'] +['ëĪ', '´'] +['ï»', 'ļ'] +['É', 'Ľ'] +['ïº', 'Ħ'] +['ï»', 'ı'] +['Å', 'Į'] +['ë²', 'ļ'] +['ìĭ', '£'] +['ïº', 'Ģ'] +['Î', 'ĵ'] +['ðŁĺ', 'Į'] +['Ë', 'Ļ'] +['ëŀ', 'ı'] +['ðŁĶ', '¸'] +['ðŁĵ', '·'] +['ëģ', '½'] +['íģ', '½'] +['ðŁĴ', '¡'] +['ðŁĮ', '±'] +['ëº', 'ı'] +['ìģ', 'ł'] +['ìĥ', 'IJ'] +['ëı', 'Ĺ'] +['ì¸', '°'] +['ëĪ', 'ķ'] +['Î', 'Ŀ'] +['âģ', 'ī'] +['ðŁĮ', '¼'] +['íĮ', 'ł'] +['âĭ', '¯'] +['áĥ', 'ĺ'] +['âľ', '¤'] +['ê±', 'Ķ'] +['íĮ', 'İ'] +['ðŁĴ', '¯'] +['ìı', 'Ļ'] +['íĹ', 'ī'] +['Ù', 'Ń'] +['ì½', '°'] +['ïº', '¿'] +['ï»', '±'] +['ì±', 'Į'] +['âĺ', 'ķ'] +['ðŁİ', 'Ģ'] +['Ä', 'Ŀ'] +['ë°', '§'] +['ìĤ', '¿'] +['áij', 'ķ'] +['ðŁį', 'ĥ'] +['âĩ', '¨'] +['Î', 'Ľ'] +['ë§', '´'] +['ë³', 'ķ'] +['á', 'ijIJ'] +['âĸ', 'ĵ'] +['ðĿ', 'ijľ'] +['âĻ', '»'] +['íĤ', '¥'] +['Õ', '¸'] +['ãĪ', '±'] +['ëº', 'Ģ'] +['ì²', '¸'] +['ïº', 'Ľ'] +['ðŁı', 'Ĩ'] +['ðŁĩ', 'ª'] +['âĿ', 'ĵ'] +['Ä', 'Ģ'] +['ì½', '¥'] +['ðŁĩ', '§'] +['á½', '·'] +['âľ', 'Ĥ'] +['ìŀ', '¼'] +['ï§', '¡'] +['ðŁĵ', '¸'] +['âĻ', '¯'] +['É', 'Ķ'] +['á½', '¸'] +['âĮ', 'ª'] +['ï»', 'ĸ'] +['ï¥', '§'] +['âļ', '«'] +['âĶ', 'Ĺ'] +['ðŁĮ', 'Ī'] +['ï»', '©'] +['ðŁĵ', '²'] +['Ï', 'Ī'] +['ðŁĺ', '¡'] +['ðĿij', 'İ'] +['ìľ', '½'] +['ì§', '¬'] +['ì§', 'Ĭ'] +['á½', '³'] +['ìĮ', '¤'] +['ëĤ', 'į'] +['âī', 'Ĵ'] +['ðŁij', '¨'] +['âĺ', 'ĺ'] +['Ó', '©'] +['âĤ', 'ĵ'] +['âĪ', 'Ĥ'] +['ï¹', 'ģ'] +['ðŁĴ', 'IJ'] +['íħ', 'ĥ'] +['ðŁı', '½'] +['ê·', 'Ħ'] +['ðŁĺ', 'ı'] +['ðŁĮ', 'º'] +['ðŁĺ', 'Ķ'] +['ï½', '«'] +['âľ', 'İ'] +['ëµ', 'Ī'] +['ðŁĩ', '¸'] +['âĢ', '£'] +['âŀ', 'Ķ'] +['ëĺ', 'ĺ'] +['ìĥ', '¬'] +['Ê', 'ĥ'] +['â¬', 'ħ'] +['ì©', 'IJ'] +['ðŁĻ', 'Ĩ'] +['ðŁİ', 'Ħ'] +['Ä', '¾'] +['âŁ', '¶'] +['áĥ', 'IJ'] +['âĺ', '»'] +['ì±', 'ķ'] +['ìģ', '©'] +['ë½', 'ķ'] +['ìº', '£'] +['ðŁij', 'Ī'] +['ðŁĻ', 'ĭ'] +['ï¾', 'ĸ'] +['Ò', 'ļ'] +['Õ', '«'] +['ìĮ', 'Ī'] +['ë²', '§'] +['ðŁĩ', '®'] +['ï½', 'Ŀ'] +['ðŁį', 'ģ'] +['ìĹ', '¥'] +['Ä', '³'] +['ë½', 'IJ'] +['íį', '½'] +['íĽ', 'ij'] +['âĤ', '¹'] +['ãħ', 'ģ'] +['ìĶ', '½'] +['ðŁĶ', 'ģ'] +['à¤', '¯'] +['ê¾', '¹'] +['ëī', 'ľ'] +['âĹ', '¡'] +['íķ', 'Į'] +['Î', 'ĺ'] +['ë£', '¹'] +['ìĻ', 'ĵ'] +['ðŁĩ', '¦'] +['ðŁij', 'Ģ'] +['âĶ', 'Į'] +['á¿', '¦'] +['ëĦ', 'Ľ'] +['ìĦ', '£'] +['ìŃ', 'Ļ'] +['ï±', 'ł'] +['Î', 'ŀ'] +['Ê', '»'] +['á¿', '¶'] +['âĿ', 'Ŀ'] +['ê±', 'Ģ'] +['ëĸ', '´'] +['ãĦ', '¹'] +['ðŁĴ', 'İ'] +['Ï', '¹'] +['âĽ', 'ħ'] +['ï»', 'ķ'] +['ãĥ', '±'] +['ï½', 'Ľ'] +['ëĮ', 'ķ'] +['ë¹', '½'] +['ì¥', 'Ķ'] +['ì¿', '¤'] +['ðŁĸ', '¤'] +['Ñ', 'Ĵ'] +['ê¹', 'į'] +['ëİ', 'Ģ'] +['ìĭ', '¯'] +['ë»', '¤'] +['ðŁĵ', 'ŀ'] +['ðŁĵ', '£'] +['ðŁĺ', 'Ŀ'] +['ìį', '¹'] +['ìĹ', '¡'] +['ì°', 'IJ'] +['á½', 'IJ'] +['ï»', 'Ī'] +['âľ', 'į'] +['Ä', 'ı'] +['ðŁĮ', 'ŀ'] +['âĦ', '¦'] +['ê½', 'Ŀ'] +['ë»', 'ĺ'] +['ìĪ', '±'] +['âĶ', 'ĺ'] +['ðŁĮ', '»'] +['âĤ', '´'] +['âŀ', '¨'] +['íIJ', 'ģ'] +['ê', '¶Ī'] +['âĺ', '¢'] +['ðŁĺ', 'Ī'] +['ï½', '©'] +['âĦ', 'Ĺ'] +['ê°', 'Ń'] +['ê°', '¸'] +['ë»', 'ij'] +['ì¥', '´'] +['ì»', '¥'] +['ï¤', 'Ĭ'] +['ï»', 'Ĵ'] +['ðŁĺ', 'ķ'] +['âĺ', 'Ķ'] +['ìĺ', 'IJ'] +['ðŁļ', 'Ĺ'] +['ëĹ', 'Ħ'] +['ë§', 'ı'] +['Õ', '½'] +['âĸ', '»'] +['âŁ', 'µ'] +['ìī', '°'] +['ï»', 'ij'] +['âĻ', '©'] +['Î', '¥'] +['ðŁĺ', '£'] +['âĬ', 'Ĥ'] +['ãħ', 'Ĥ'] +['ìħ', '¸'] +['íı', 'Ħ'] +['âľ', '½'] +['ì¦', 'Ļ'] +['âĸ', '£'] +['ê±', 'į'] +['ê¿', 'ĭ'] +['ì«', 'Ħ'] +['ìº', 'ĩ'] +['ðŁĩ', 'µ'] +['ðŁij', 'ij'] +['âľ', 'ĺ'] +['ðĿij', 'Ľ'] +['ìį', '½'] +['ìº', 'ī'] +['ï¬', 'µ'] +['ðŁĶ', 'º'] +['âĦ', '®'] +['íĥ', '¤'] +['ðŁĩ', 'º'] +['ðŁĴ', 'µ'] +['íħ', '¨'] +['ï½', 'ij'] +['Î', '¨'] +['ìĥ', '¹'] +['ìĸ', 'ķ'] +['ì¹', 'µ'] +['ðŁĵ', '±'] +['à¤', 'µ'] +['ðŁij', 'Ĭ'] +['ðŁĴ', 'Ħ'] +['ðŁĴ', 'Ŀ'] +['ãĮ', 'Ķ'] +['ìĻ', 'ģ'] +['Ð', 'ĩ'] +['à®', 'IJ'] +['âĸ', '¹'] +['á´', 'Ľ'] +['âĹ', 'ĺ'] +['ëº', '¨'] +['íĥ', 'ī'] +['ìĸ', 'Į'] +['ðŁIJ', '¶'] +['ãĤ', 'ij'] +['Ë', 'ĩ'] +['Å', 'ı'] +['á½', '¹'] +['ìħ', '§'] +['ï¹', '°'] +['ðĿij', '¡'] +['ðŁĶ', 'Ŀ'] +['ðŁĺ', '»'] +['ðŁĴ', 'ĥ'] +['ð٤', '¦'] +['ðŁį', 'Ĵ'] +['íĢ', 'µ'] +['âľ', 'Ĩ'] +['ë¹', '´'] +['ï§', '¤'] +['ï»', 'Ļ'] +['á´', 'Ĺ'] +['ðŁĮ', '´'] +['Í', '¾'] +['ëĮ', 'ij'] +['ì¨', 'ĭ'] +['ìµ', '¸'] +['ðŁİ', 'Ī'] +['ðŁı', 'ł'] +['á½', '±'] +['Û', 'Ĩ'] +['á¿', 'ĸ'] +['âĢ', 'Ľ'] +['ì°', '¼'] +['íķ', '¥'] +['íĹ', '´'] +['ðŁĩ', '¬'] +['ì°', 'Ŀ'] +['âĪ', 'ł'] +['ï¼', 'ĩ'] +['âĬ', 'Ļ'] +['âĿ', 'ij'] +['ëĦ', 'ĭ'] +['ëŀ', 'Ĺ'] +['ë°', 'ī'] +['ìĹ', 'Ĭ'] +['ì¢', 'Ĩ'] +['íĮ', '¥'] +['ï°', '²'] +['ðŁĵ', 'ĸ'] +['ðŁĺ', '®'] +['âļ', 'ª'] +['ðŁĺ', 'ļ'] +['âĿ', 'ŀ'] +['ðĿij', 'Ł'] +['ðŁİ', 'Ĥ'] +['Å', 'ķ'] +['áIJ', 'Ī'] +['êº', '½'] +['ì±', 'ł'] +['ïº', 'Ŀ'] +['ê¿', 'ī'] +['áĥ', 'ł'] +['ðŁı', 'ĥ'] +['ðŁĴ', '¸'] +['âĿ', 'ģ'] +['âĹ', '¾'] +['Ú', 'ª'] +['á¹', 'ĥ'] +['íĬ', '¬'] +['ðŁĩ', '±'] +['íİ', 'Ń'] +['ðŁĺ', 'ŀ'] +['ë¾', '°'] +['á¹', 'Ľ'] +['ëĽ', '¸'] +['âĿ', 'Ĥ'] +['êĴ', '³'] +['âĶ', 'IJ'] +['íĵ', '°'] +['âŀ', 'ł'] +['ê´', 'ĺ'] +['ëħ', 'ĺ'] +['ë»', '¥'] +['ì¾', 'ħ'] +['ðŁĺ', 'IJ'] +['âĪ', 'ª'] +['ðŁij', 'ģ'] +['âĪ', '´'] +['âĹ', 'ģ'] +['ëº', 'IJ'] +['ìŀ', '¤'] +['ì±', 'Ĺ'] +['ðŁı', '¾'] +['Î', '§'] +['á½', '»'] +['âŀ', '¥'] +['ìŁ', 'Ī'] +['ï»', 'ī'] +['âĸ', 'Į'] +['ãĥ', '®'] +['ð٤', '¤'] +['âĩ', 'ĵ'] +['ì¼', 'ł'] +['á´', 'ı'] +['ë§', '¬'] +['ë»', '£'] +['ðŁĴ', '¬'] +['ðŁį', 'ĵ'] +['Ä', '¸'] +['Ù', '¹'] +['Ê', '¿'] +['á½', '°'] +['ëķ', 'ľ'] +['ì°', '¡'] +['ì°', '»'] +['íİ', 'į'] +['ðŁİ', '¯'] +['ðŁį', 'Ĥ'] +['ðŁij', '§'] +['âĻ', '¢'] +['áĨ', 'ŀ'] +['âĻ', '§'] +['âļ', 'ľ'] +['âľ', 'ī'] +['ëĵ', '¦'] +['ëŃ', '£'] +['ìĪ', 'ı'] +['ìĵ', '±'] +['Å', 'Ń'] +['Ê', 'Ĭ'] +['âĴ', '¸'] +['âĩ', '©'] +['ðŁĴ', 'Ķ'] +['Õ', 'µ'] +['Ð', 'ī'] +['Ò', '»'] +['ë§', '£'] +['ìĽ', 'ľ'] +['ì¿', '¡'] +['íĽ', 'ħ'] +['íĽ', '¤'] +['ïº', '¢'] +['âľ', 'ĭ'] +['âĪ', 'Ī'] +['ðŁĮ', 'į'] +['Ê', 'ľ'] +['ëĬ', 'ª'] +['ëĴ', '¹'] +['ïº', '²'] +['âĸ', 'Ħ'] +['ãħ', 'Ī'] +['ëļ', '¤'] +['íİ', '©'] +['âĪ', '¨'] +['ð٤', 'ª'] +['áĥ', 'ļ'] +['ê³', '¶'] +['íĬ', 'ķ'] +['ðŁĺ', '¬'] +['âĪ', '«'] +['ðŁij', 'ĭ'] +['Ò', 'IJ'] +['íĬ', '¿'] +['ðŁĶ', 'µ'] +['ðŁĴ', '¨'] +['ðŁĮ', 'Ļ'] +['ëĩ', '©'] +['âľ', '³'] +['ë¨', 'ģ'] +['ëº', 'Ħ'] +['ìĻ', 'ij'] +['ìº', 'ħ'] +['íı', 'Ī'] +['ðĿij', 'Ļ'] +['ðŁĴ', 'ĺ'] +['ãİ', '¥'] +['âĿ', 'ı'] +['âľ', '°'] +['ï¯', '¿'] +['ëµ', 'IJ'] +['ì¼', 'IJ'] +['ïº', '±'] +['Õ', '´'] +['ï¬', 'Ģ'] +['âľ', '´'] +['ð٤', 'Ń'] +['ðŁij', 'Ĩ'] +['âĽ', 'Ķ'] +['ê·', 'ĵ'] +['ìĮ', 'Į'] +['ð٤', '·'] +['Û', 'Ķ'] +['ð٧', '¡'] +['ðŁĺ', 'ĵ'] +['Î', 'ĸ'] +['âı', '°'] +['ê²', 'ľ'] +['ëĭ', '³'] +['ëİ', 'ħ'] +['ë°', 'Ī'] +['ï®', 'IJ'] +['ðŁı', '¡'] +['âĨ', 'ª'] +['âĵ', 'Ķ'] +['âľ', 'Ĭ'] +['Ï', '²'] +['Ü', 'IJ'] +['ðŁĩ', '³'] +['Ö', 'Ĥ'] +['âľ', 'ı'] +['ìĸ', 'Ĺ'] +['ì«', 'Ļ'] +['ðŁĺ', '²'] +['Ä', 'Ń'] +['âĻ', 'Ń'] +['âĶ', 'ı'] +['âĹ', 'Į'] +['ðŁĺ', '¯'] +['áµ', 'Ĵ'] +['íĬ', 'ł'] +['Ä', '·'] +['Ê', 'ģ'] +['à¤', 'Ł'] +['á¹', 'ģ'] +['á¼', '°'] +['á¿', 'Ĩ'] +['â', '«'] +['â«', '¸'] +['ëį', '«'] +['ì³', 'ĩ'] +['ì¼', '¤'] +['íĽ', '¨'] +['ðŁĴ', 'Ł'] +['Ê', 'Ģ'] +['Ê', '³'] +['ëĵ', 'IJ'] +['âķ', '°'] +['âĿ', 'ĩ'] +['Ç', 'Ģ'] +['Ç', 'Ķ'] +['É', '´'] +['âĺ', 'ļ'] +['âĺ', 'ľ'] +['ê¶', 'Ĥ'] +['ì«', 'Ĵ'] +['ì±', 'Ī'] +['ðŁĩ', '¨'] +['ðŁİ', '¥'] +['ðŁĵ', 'Ŀ'] +['Ä', '§'] +['ðĿ', 'ijIJ'] +['Û', 'Ī'] +['à¤', '¬'] +['ì¬', 'IJ'] +['íĹ', '¥'] +['âĻ', '¨'] +['ðŁį', '´'] +['ï¹', 'ı'] +['Ë', 'ĭ'] +['ðŁ¥', 'º'] +['âĸ', '¨'] +['íĻ', 'ĭ'] +['âĪ', 'ħ'] +['ëģ', 'Ļ'] +['ëŀ', 'ł'] +['ìĨ', '¥'] +['âĢ', 'ĸ'] +['ð٤', 'ĺ'] +['ðŁIJ', '»'] +['áµ', 'ķ'] +['Ç', 'Ŀ'] +['âĺ', 'ı'] +['ïº', 'ļ'] +['ï»', 'Ĥ'] +['ðŁļ', '©'] +['ìĪ', 'Ł'] +['Ë', 'Ĭ'] +['â¤', 'µ'] +['ðŁĴ', '§'] +['ã', 'ħį'] +['ë©', '©'] +['Æ', '¬'] +['Î', 'ĩ'] +['âĩ', '§'] +['âĵ', 'ļ'] +['ìĤ', '¯'] +['ìĪ', '¯'] +['ëĨ', 'ĭ'] +['âľ', '¯'] +['ðŁļ', 'Ģ'] +['Ú', 'ĺ'] +['Ú', '¨'] +['âľ', 'Ń'] +['ê²', 'ħ'] +['íĮ', '°'] +['íľ', 'Ļ'] +['ðŁĮ', 'Ĭ'] +['ðŁİ', 'ĵ'] +['ðŁĺ', 'Ļ'] +['Ë', 'ĥ'] +['ðŁĴ', 'ģ'] +['ðŁij', 'İ'] +['âĺ', '¹'] +['ðŁĺ', '«'] +['ðŁĴ', '»'] +['ëĤ', 'µ'] +['ìĿ', 'Ĭ'] +['íĮ', '»'] +['Ò', '³'] +['á½', '²'] +['âŀ', 'ŀ'] +['ëĤ', 'ij'] +['ëĿ', 'Ī'] +['ì£', '¤'] +['ï»', '¯'] +['ðŁĩ', '©'] +['ðŁ¥', '³'] +['âĴ', '¼'] +['ð٦', 'ĭ'] +['âĺ', 'Ĥ'] +['ðŁĺ', '°'] +['ðŁĻ', 'ĥ'] +['ðŁĺ', 'Ĵ'] +['Û', 'İ'] +['Ï', 'ķ'] +['á¸', '¤'] +['ë£', '½'] +['ìĬ', '¥'] +['ðĿij', 'ī'] +['É', 'IJ'] +['ðŁį', 'İ'] +['âķ', '¯'] +['âķ', '¹'] +['àº', '²'] +['ï¾', 'ł'] +['ë¹', 'ķ'] +['ïº', 'Ĩ'] +['Ê', 'º'] +['Ó', '§'] +['âĨ', 'ł'] +['ëĥ', 'ĩ'] +['ìİ', 'Ī'] +['ìŁ', '¤'] +['ï±', '¢'] +['âķ', '¬'] +['âĺ', 'ł'] +['ðŁİ', 'Ĭ'] +['ãį', 'į'] +['ãİ', 'İ'] +['âĺ', '°'] +['âľ', 'ĥ'] +['ãħ', 'ī'] +['ë¯', 'Ī'] +['ë¹', '¤'] +['ìı', 'Ń'] +['ðĿij', '¢'] +['ðŁIJ', '¾'] +['Å', 'ĭ'] +['ðŁij', '¶'] +['âĶ', 'Ľ'] +['ï¿', '¢'] +['áĥ', '¡'] +['Ä', '¼'] +['Å', 'Ĩ'] +['Ñ', 'IJ'] +['ìĥ', 'Ľ'] +['ìĺ', 'Į'] +['ì±', '¤'] +['íħ', 'ģ'] +['íļ', 'ĥ'] +['ï³', 'Ĭ'] +['ðĿij', 'Ķ'] +['ðŁĩ', '«'] +['âĭ', '°'] +['ðŁĺ', '¨'] +['âĤ', '©'] +['Õ', '¬'] +['á¸', 'į'] +['á»', '´'] +['âĨ', 'ĺ'] +['âĺ', '¯'] +['ãħ', 'ı'] +['ìł', '¬'] +['âĻ', 'Ķ'] +['ðŁĶ', 'Ķ'] +['ðŁĺ', 'ł'] +['ðŁĻ', 'Ĭ'] +['à®', 'ľ'] +['á¹', 'ħ'] +['âĹ', 'IJ'] +['âĿ', 'Ī'] +['âŀ', '½'] +['ìĥ', 'ħ'] +['ðĿij', 'ł'] +['Æ', '¢'] +['âĭ', 'Ļ'] +['ê°', 'Ľ'] +['ëĿ', 'µ'] +['ë£', 'Ł'] +['ìı', 'ľ'] +['ïº', 'ģ'] +['ðŁĴ', 'Ń'] +['âĬ', 'ĥ'] +['ðŁIJ', '°'] +['ãħ', 'Į'] +['Ü', 'ĵ'] +['âŀ', 'ķ'] +['á½', 'ģ'] +['ìķ', '³'] +['ðĿij', 'Ŀ'] +['ðŁİ', '¬'] +['É', '¡'] +['à¤', 'Ĺ'] +['áIJ', 'ī'] +['ì©', 'ľ'] +['ì¶', '§'] +['ï³', 'ī'] +['ï»', 'ħ'] +['ðĿIJ', 'ŀ'] +['à¤', '¶'] +['ðŁĵ', '¢'] +['ðŁį', 'ĭ'] +['ðŁĴ', 'ħ'] +['ï¾', 'ķ'] +['â¬', 'Ĩ'] +['âĪ', 'µ'] +['ð٤', 'ij'] +['áĥ', '£'] +['Æ', 'Ħ'] +['Ñ', '¹'] +['á¼', 'Ķ'] +['ê°', 'ł'] +['ê´', 'Į'] +['ê·', 'IJ'] +['ëĽ', '´'] +['ì±', 'ĺ'] +['ï®', 'Ń'] +['ïº', '¹'] +['ïº', '¾'] +['âľ', 'Ĺ'] +['âĿ', '¦'] +['ðŁij', '¦'] +['áĥ', 'Ĺ'] +['Ù', '²'] +['á½', '´'] +['âĪ', 'ı'] +['âľ', '®'] +['ê¹', '°'] +['ë²', 'µ'] +['ìĦ', 'Ģ'] +['ì©', 'Ŀ'] +['ïº', 'ŀ'] +['ïº', '½'] +['ðŁĩ', 'Ń'] +['Ë', 'Ĥ'] +['ðŁį', 'ij'] +['ðŁį', 'Į'] +['ðŁĶ', '»'] +['ê¹', '¬'] +['ìĬ', 'Ń'] +['ìľ', '·'] +['ðŁĽ', 'ij'] +['Ç', '§'] +['ë¼', 'Ľ'] +['ïº', '¡'] +['ïº', 'º'] +['ðĿij', 'ļ'] +['ðŁĵ', '¦'] +['ðŁĶ', 'İ'] +['ðŁĹ', 'ĵ'] +['áĥ', 'Ķ'] +['âľ', 'Ĵ'] +['âľ', '¡'] +['ðŁĮ', 'µ'] +['âĶ', 'ķ'] +['ëĢ', 'Ŀ'] +['ðŁį', 'Ĭ'] +['âĺ', 'ĥ'] +['ìĺ', 'ħ'] +['à¦', '¬'] +['ð٦', 'ģ'] +['âİ', '¯'] +['ðŁIJ', 'ķ'] +['Ñ', '¿'] +['à¥', '¤'] +['à¼', 'ĭ'] +['ê·', 'Ī'] +['ì«', 'Į'] +['ðŁĩ', '°'] +['âĿ', 'ī'] +['ì«', 'Ģ'] +['íĿ', 'Ħ'] +['ðĿIJ', '¢'] +['ðŁļ', '¨'] +['âĻ', '¤'] +['ðŁĺ', '©'] +['ðŁį', 'į'] +['ðŁĺ', 'ij'] +['ðŁļ', 'ļ'] +['Ö', 'Ħ'] +['ë', '«'] +['ë«', '¼'] +['à¤', 'ı'] +['á¿', '·'] +['âĮ', '©'] +['âĺ', 'IJ'] +['âŀ', '£'] +['ê¸', '±'] +['ê¼', '¿'] +['ëĦ', 'Ŀ'] +['ìı', '´'] +['ìļ', '¤'] +['ì¿', '±'] +['íİ', 'IJ'] +['ðŁĴ', '¢'] +['ì´', 'IJ'] +['âĩ', 'ij'] +['âĶ', 'ĵ'] +['âģ', '¾'] +['Ü', 'Ŀ'] +['ðŁ', 'į°'] +['â´', '°'] +['Æ', 'ı'] +['Ï', 'Ł'] +['Ú', 'º'] +['Û', 'ĥ'] +['áĦ', 'Ĵ'] +['âĪ', 'Ł'] +['âĿ', 'į'] +['ãĦ', '²'] +['ìľ', 'ħ'] +['ì¤', 'ı'] +['ðŁĩ', '²'] +['êº', 'Ħ'] +['ðŁİ', '¤'] +['âľ', '£'] +['â¸', 'Ŀ'] +['ï¸', 'µ'] +['àº', '§'] +['áĢ', 'Ļ'] +['âķ', 'ł'] +['Õ', '¯'] +['âı', '©'] +['ðĿij', '£'] +['ðŁĴ', '£'] +['Å', 'ĺ'] +['à¥', 'IJ'] +['âģ', 'ĥ'] +['âĮ', 'ĺ'] +['ê»', 'Į'] +['ìĮ', 'Ķ'] +['ðĿij', 'ĺ'] +['ð٤', 'ĵ'] +['Õ', '¿'] +['à¤', 'Ń'] +['âĮ', 'ļ'] +['âľ', 'Ŀ'] +['ðŁIJ', '¼'] +['Ë', 'Į'] +['âķ', 'ļ'] +['ï¦', 'Ĺ'] +['âĿ', 'ķ'] +['âķ', '£'] +['ðŁIJ', '±'] +['à®', '¤'] +['Ñ', '¾'] +['à¤', 'ļ'] +['à¤', 'ľ'] +['ìĪ', 'Ħ'] +['ìļ', 'ľ'] +['ðŁİ', '®'] +['É', 'Ĵ'] +['Ú', '·'] +['àº', 'į'] +['âĨ', 'µ'] +['â', 'Īĺ'] +['âĿ', 'Ĭ'] +['ë¿', 'į'] +['ìIJ', 'Ī'] +['ìļ', 'ĺ'] +['ì¯', '§'] +['íĥ', '¯'] +['ìĸ', 'ı'] +['ï¸', '°'] +['ðŁĩ', '¯'] +['ð٧', 'ļ'] +['ðŁĺ', 'µ'] +['ðŁĺ', '·'] +['ðŁĮ', '³'] +['àº', '¥'] +['Ä', 'ī'] +['Ä', '¥'] +['âľ', '¶'] +['á¿', '¾'] +['âĬ', '±'] +['âĺ', '¾'] +['ê°', 'ī'] +['ê¼', '°'] +['ëº', 'ij'] +['ðŁĶ', 'Ĭ'] +['ðŁĸ', 'IJ'] +['Å', '¤'] +['Ò', '«'] +['à®', '®'] +['âĮ', 'Ī'] +['âĹ', 'Ĺ'] +['ëĦ', 'µ'] +['ëħ', 'ľ'] +['ëľ', '¹'] +['ðĿij', '¥'] +['ðŁĴ', '¿'] +['ðŁĽ', 'Ĵ'] +['Ê', 'Ĵ'] +['áŀ', 'ĵ'] +['ðŁIJ', 'Ŀ'] +['ð٦', 'Ħ'] +['ðŁį', '·'] +['âĺ', 'Ł'] +['ï¸', '¶'] +['ð٤', 'Ł'] +['Ô', '±'] +['âĨ', '²'] +['âĪ', 'İ'] +['âľ', '«'] +['ëĩ', '½'] +['ëı', 'IJ'] +['ëķ', 'Ħ'] +['ï¦', '³'] +['ï§', 'Ŀ'] +['ïº', 'Ļ'] +['ðŁij', '»'] +['ðŁĵ', 'º'] +['êµ', '¼'] +['ìĮ', '©'] +['ðŁĮ', '²'] +['È', '±'] +['íĶ', 'ķ'] +['ðŁĺ', '¤'] +['ãĮ', '¢'] +['Ê', 'Ķ'] +['à¤', '¡'] +['á¼', 'Ī'] +['ëİ', 'ĥ'] +['ë©', '±'] +['ë®', 'Ī'] +['ðĿIJ', '«'] +['âĬ', 'ķ'] +['ëĥ', 'ł'] +['ë»', '¬'] +['íĭ', 'Ķ'] +['Õ', '¤'] +['á¼', '±'] +['âľ', '¥'] +['âĺ', 'Ħ'] +['âĪ', '¥'] +['âļ', 'ķ'] +['ðŁij', 'Ħ'] +['ðŁİ', 'ħ'] +['àº', 'Ļ'] +['âĶ', '¬'] +['á½', 'µ'] +['Õ', '¾'] +['Ö', 'ģ'] +['âĹ', 'Ķ'] +['ê¿', 'į'] +['ëĸ', 'µ'] +['ë©', 'İ'] +['ë®', '´'] +['ìķ', '´'] +['áĥ', 'ľ'] +['á¼', '¡'] +['âĶ', 'Ĭ'] +['âķ', '®'] +['âĹ', '¼'] +['ðŁį', '¾'] +['ðŁĽ', 'į'] +['ðŁij', 'Ĺ'] +['ð٤', 'ŀ'] +['âľ', 'Ħ'] +['Õ', 'Ģ'] +['à¦', '²'] +['Ë', 'ī'] +['âŁ', '¨'] +['Ä', '¯'] +['Ï', 'Ĭ'] +['á´', 'ľ'] +['ë¹', '³'] +['ï³', 'ĭ'] +['ï¿', 'ł'] +['Ä', 'ª'] +['âĤ', '¸'] +['âľ', '±'] +['ê»', 'IJ'] +['ëĭ', '»'] +['ë§', '¸'] +['ìŀ', '¿'] +['ì©', '¨'] +['ì', 'ŃIJ'] +['ì°', '¿'] +['íħ', 'Ł'] +['ðĿIJ', '§'] +['ðĿij', 'ij'] +['ðŁĮ', 'İ'] +['ðŁĵ', '®'] +['ðŁķ', 'Ķ'] +['âĹ', 'Ļ'] +['âĹ', '»'] +['âŀ', '§'] +['ìŁ', 'Ŀ'] +['âľ', '¬'] +['ãĥ', '°'] +['âģ', 'Ī'] +['â', 'ĵĺ'] +['ðŁ', 'ĴĮ'] +['ï¬', 'ĥ'] +['àº', 'Ķ'] +['ìĶ', '°'] +['ðŁĺ', 'ª'] +['×', 'Ģ'] +['ìĥ', '¨'] +['ïŃ', 'ĭ'] +['ðŁį', 'ķ'] +['ðŁĺ', '´'] +['Ï', '³'] +['á¼', 'Ħ'] +['á½', 'ħ'] +['âĩ', '¢'] +['âķ', 'Ń'] +['ìĺ', '»'] +['íĬ', '¤'] +['Ü', 'ĺ'] +['â¤', '´'] +['âĹ', 'į'] +['áŀ', 'Ł'] +['ðŁį', 'º'] +['áŀ', 'ļ'] +['ðŁı', 'Ĭ'] +['ðŁIJ', '·'] +['Ê', 'Į'] +['á½', 'º'] +['âģ', '»'] +['ê½', 'Į'] +['ëĪ', 'Ĺ'] +['ë', 'Ĺı'] +['ì¿', '°'] +['íĢ', '¼'] +['íį', 'ħ'] +['ï·', '²'] +['ðŁĮ', 'ı'] +['ðŁį', '«'] +['ðŁį', '³'] +['ðŁİ', '°'] +['ðŁij', '°'] +['ðŁĴ', '²'] +['á¥', 'Ļ'] +['ðŁIJ', 'Ł'] +['ï¿', '¡'] +['ðŁĹ', '£'] +['ðŁį', 'ľ'] +['âľ', '²'] +['ãİ', '¢'] +['ðŁĶ', '°'] +['á¼', '¸'] +['á½', 'ij'] +['Ä', 'İ'] +['áĦ', 'Ģ'] +['âĻ', 'ķ'] +['ëł', 'Ŀ'] +['ìĪ', '´'] +['ïŃ', 'Ń'] +['Ó', 'ľ'] +['Ô', 'Ģ'] +['ëĢ', 'ľ'] +['ëĥ', 'Ķ'] +['ìĬ', 'Ľ'] +['ì«', 'ij'] +['ìº', '¥'] +['ìº', '¬'] +['ðĿij', '¦'] +['ðŁĶ', '¶'] +['ì¾', '¨'] +['ðĿIJ', 'ļ'] +['ðŁį', '»'] +['ðŁĴ', 'į'] +['ð٤', '¡'] +['ðŁķ', 'Ĭ'] +['â½', 'ĩ'] +['âĵ', 'IJ'] +['ðŁį', 'Ń'] +['ðŁį', 'ª'] +['ðŁĶ', 'Ĩ'] +['Ò', '¡'] +['á´', 'ĩ'] +['É', 'Ĺ'] +['Ü', 'Ķ'] +['âĦ', 'İ'] +['âĿ', 'ĥ'] +['ëĹ', 'Ģ'] +['ï²', 'Ķ'] +['ïº', 'Ī'] +['ðĿIJ', '»'] +['ðŁĴ', 'Ĭ'] +['ðŁļ', '«'] +['Ñ', '°'] +['Ñ', '³'] +['à¤', '·'] +['âĹ', 'ł'] +['ðŁij', '¤'] +['ï¾', 'ĩ'] +['âĺ', 'ĵ'] +['ðŁį', 'µ'] +['ð٤', '¨'] +['âĸ', 'Ń'] +['à®', '´'] +['Ü', '¢'] +['Ü', '¬'] +['à´', '®'] +['ðŁķ', 'º'] +['Ô', '¹'] +['Õ', '£'] +['à´', '¯'] +['á', '´Ģ'] +['âĮ', 'ī'] +['âľ', 'IJ'] +['âŀ', '¦'] +['ê¹', '½'] +['ëĮ', 'ľ'] +['ðŁı', '¥'] +['ðŁĵ', '©'] +['Ò', '¹'] +['Ó', 'ĺ'] +['à¤', 'ħ'] +['âĿ', '§'] +['Æ', 'Ĺ'] +['âĹ', '½'] +['ðŁij', '«'] +['ðŁİ', '§'] +['ðŁij', '£'] +['âľ', '»'] +['ðŁĻ', 'ħ'] +['ðŁĺ', 'ĸ'] +['ðŁĴ', '®'] +['àº', '°'] +['ðŁĶ', 'ľ'] +['ðŁį', 'Ħ'] +['ð٤', 'Ŀ'] +['á', 'ĥĿ'] +['áŀ', 'Ģ'] +['âĩ', '¦'] +['Ê', '¾'] +['Ò', '®'] +['Õ', '¼'] +['à¤', 'Ĩ'] +['âĹ', 'ħ'] +['âļ', 'ĵ'] +['âļ', 'ĸ'] +['ê¿', '©'] +['ë¯', 'Ħ'] +['ìIJ', 'IJ'] +['ìŀ', '°'] +['ì§', 'Ń'] +['íĭ', 'ĭ'] +['íİ', '¨'] +['íĻ', '§'] +['ï²', 'ij'] +['ðŁİ', 'Ĺ'] +['Ù', '³'] +['ðŁij', '¸'] +['à¦', '®'] +['ðŁij', 'ķ'] +['Ú', 'µ'] +['âĢ', '¾'] +['âŀ', '°'] +['ðŁij', '¯'] +['ðŁİ', '¼'] +['ðŁı', 'ģ'] +['Ä', 'º'] +['Ê', 'ı'] +['Ú', '³'] +['âı', '±'] +['ê½', 'Ī'] +['ëĿ', 'Į'] +['ìĮ', 'ī'] +['ìĹ', '·'] +['ìŀ', '´'] +['íĹ', '¹'] +['íľ', '¨'] +['ðĿĹ', '²'] +['ðŁĮ', 'IJ'] +['ðŁİ', 'Ļ'] +['ðŁı', 'µ'] +['íĽ', 'Ļ'] +['ðĿij', 'ħ'] +['ðŁĺ', '¶'] +['âĵ', 'ħ'] +['âķ', '¥'] +['ðŁį', 'ı'] +['ï¦', 'İ'] +['Õ', '©'] +['ðĿIJ', 'Ħ'] +['Ó', '£'] +['Ú', '¿'] +['âĻ', 'ļ'] +['ðŁĶ', 'Ĺ'] +['á¸', '«'] +['âĭ', '®'] +['âĸ', '¦'] +['âĽ', '½'] +['âľ', 'µ'] +['ãħ', 'Ĩ'] +['ãħ', 'Ĭ'] +['ëĦ', 'Ļ'] +['ëĿ', '¨'] +['ë¥', 'Ħ'] +['ìĦ', '¦'] +['ì§', '°'] +['ì§', '¹'] +['íī', 'Ī'] +['ï§', 'ij'] +['ï»', 'ĩ'] +['ðŁĮ', '¾'] +['ðŁı', 'ĸ'] +['ðŁIJ', 'ij'] +['ðŁĴ', '³'] +['ðŁĵ', 'Ĩ'] +['Û', 'ĩ'] +['Ü', 'ķ'] +['á½', '½'] +['ëĦ', 'ľ'] +['à´', '²'] +['à´', '³'] +['àº', 'Ń'] +['áĥ', 'Ľ'] +['âĿ', 'Ķ'] +['âij', 'ħ'] +['áĥ', '¥'] +['ðŁĵ', 'ħ'] +['âŀ', '³'] +['á´', 'µ'] +['ï¹', '¡'] +['ï¹', '¶'] +['Î', 'Ĩ'] +['à¤', '¥'] +['áī', 'µ'] +['âĿ', 'Ļ'] +['âĿ', '±'] +['ëī', 'ł'] +['ëİ', 'ł'] +['ëı', 'Ľ'] +['ë¿', 'ħ'] +['ìĶ', '¸'] +['íij', '¯'] +['íŀ', 'ī'] +['íŀ', 'Ľ'] +['ï§', 'Ħ'] +['ïŃ', 'ĺ'] +['ïº', '¦'] +['ï»', '¸'] +['ðĿij', 'Ĥ'] +['ðĿij', 'ı'] +['Ï', 'ij'] +['Ú', 'ł'] +['áĢ', 'Ķ'] +['áŀ', 'Ķ'] +['á¹', '¢'] +['ëĦ', '¸'] +['ðĿIJ', '¨'] +['ðŁĩ', '´'] +['Õ', '°'] +['ðŁij', 'ł'] +['ðŁį', 'Ĩ'] +['ðŁı', 'Ģ'] +['ðŁ', 'ijIJ'] +['ðŁį', 'ĩ'] +['ðŁIJ', '£'] +['áĪ', 'Ń'] +['Ü', 'ª'] +['ðŁ', 'ĮĢ'] +['áŀ', 'ĺ'] +['âĩ', 'Ħ'] +['ðĿIJ', 'Ģ'] +['Ê', 'Ļ'] +['âĶ', '¼'] +['ðŁı', '¿'] +['Æ', '·'] +['È', 'ł'] +['Ñ', '½'] +['âĤ', '¨'] +['ê´', 'Ń'] +['ê¹', '»'] +['ëĶ', '¨'] +['ìĪ', 'Ģ'] +['ì¾', '°'] +['íĨ', 'Ī'] +['ï®', '§'] +['ï¯', '½'] +['ðŁĶ', 'ħ'] +['ðŁĶ', '®'] +['Å', '¢'] +['Ê', '°'] +['Ñ', '¸'] +['à¤', '£'] +['âĬ', 'Ĺ'] +['ëª', 'Ħ'] +['ï¹', '·'] +['ïº', 'ħ'] +['ðĿIJ', 'µ'] +['ðŁĮ', '¶'] +['ðŁĵ', '°'] +['ðŁĶ', '·'] +['ðŁĸ', 'Ĵ'] +['ð٤', '²'] +['ëī', '©'] +['ðŁİ', 'Ĩ'] +['ð٧', 'IJ'] +['ðŁį', '®'] +['âĨ', 'º'] +['âĿ', '¢'] +['ðŁij', 'ª'] +['ðŁij', '±'] +['âĨ', '¡'] +['áŀ', 'ı'] +['Ú', 'ķ'] +['ðŁį', '¹'] +['ðŁĴ', 'Ģ'] +['Ë', '®'] +['Ó', '¨'] +['Ö', 'ħ'] +['à¤', 'ĩ'] +['âĤ', '¡'] +['âĪ', 'ķ'] +['âĺ', 'ī'] +['ê¹', '¼'] +['ê¼', 'IJ'] +['ì½', '¸'] +['ðĿIJ', '¬'] +['ðŁı', 'ħ'] +['ðŁij', 'Ļ'] +['ðŁĴ', 'ī'] +['ð٤', 'Ļ'] +['È', 'ĺ'] +['É', '³'] +['É', '¹'] +['Ù', 'º'] +['áĢ', 'Ħ'] +['á¿', '³'] +['âļ', 'ĺ'] +['âĿ', 'Ĩ'] +['ëĨ', 'ī'] +['ìĸ', 'į'] +['ìĺ', 'ĩ'] +['ì¥', 'ĺ'] +['íĸ', 'ħ'] +['íĻ', 'ij'] +['ï®', 'Ĭ'] +['ï¿', 'Ń'] +['ðĿĴ', 'IJ'] +['ðĿĹ', '¢'] +['ðŁĶ', 'ĸ'] +['ðŁĶ', '¨'] +['ðŁļ', 'ij'] +['ðŁļ', '²'] +['Æ', '¸'] +['âĹ', '¥'] +['ðĿIJ', 'Ń'] +['ðŁį', '½'] +['âĹ', 'ij'] +['âĵ', 'ĩ'] +['ðŁĶ', '±'] +['âľ', '¼'] +['ï¹', 'ĥ'] +['âķ', '±'] +['ãĢ', 'Ĺ'] +['ðŁı', 'ĭ'] +['ðŁļ', '´'] +['ðĿIJ', '®'] +['Ä', 'ļ'] +['Õ', 'ı'] +['Ä', '¶'] +['áĥ', 'ij'] +['á¹', '¬'] +['Ä', 'Ī'] +['Ä', 'Ĵ'] +['Ò', '°'] +['Ó', 'ķ'] +['â', 'IJ'] +['âIJ', '£'] +['âĹ', '¢'] +['âļ', 'Ļ'] +['ãħ', 'Ĺ'] +['ê°', '¬'] +['ê³', 'ª'] +['ê»', 'Ģ'] +['ëĦ', '´'] +['ëİ', 'ģ'] +['ëĿ', 'Ķ'] +['ë¬', '½'] +['ëŃ', 'į'] +['ìĩ', '³'] +['ì°', '¹'] +['íĮ', '¹'] +['íŀ', 'Ŀ'] +['ï®', 'ĭ'] +['ï', '¶Ī'] +['ðĿĴ', 'Ĥ'] +['ðŁ¥', 'Ģ'] +['ð٦', 'ħ'] +['Ê', 'ĺ'] +['á¼', 'ij'] +['âģ', 'İ'] +['ðŁį', 'ŀ'] +['âĨ', 'ĸ'] +['âĨ', 'Ļ'] +['ðŁİ', 'ĥ'] +['âĦ', '¡'] +['âĭ', '±'] +['ðŁĶ', 'į'] +['à²', '¨'] +['áµ', 'ĥ'] +['âĶ', '«'] +['â¦', '¿'] +['ðŁĩ', '»'] +['Æ', '¤'] +['Ò', 'ı'] +['Ò', '·'] +['Û', 'ī'] +['à®', 'ķ'] +['á¸', '³'] +['ï¬', '±'] +['ðŁĨ', 'Ķ'] +['Ú', 'Ń'] +['Û', '¦'] +['áħ', '¡'] +['âĦ', '¹'] +['ê¿', 'İ'] +['ëķ', 'Ķ'] +['ë¼', 'ī'] +['ìļ', '§'] +['ì²', 'µ'] +['ì´', '¨'] +['íĬ', 'Ī'] +['íĸ', 'IJ'] +['ðĿĹ', 'ĺ'] +['ðŁĩ', '¿'] +['ðŁİ', 'ĸ'] +['ðŁij', 'ħ'] +['ðŁ', 'ĵĺ'] +['ðŁļ', 'Ļ'] +['ðŁĽ', 'µ'] +['à¶', '½'] +['âĽ', 'µ'] +['ðĿIJ', '³'] +['ðĿIJ', '¸'] +['âļ', 'Ķ'] +['ðŁij', 'Ń'] +['Ó', 'ij'] +['âĶ', '¯'] +['ðŁħ', '¿'] +['ðŁĺ', '¹'] +['ï¿', '«'] +['â¼', '¤'] +['ðŁĴ', 'ĩ'] +['ðŁĵ', 'İ'] +['ðŁĸ', 'ĭ'] +['à¦', '¸'] +['ðĿIJ', 'į'] +['Ä', '²'] +['Ï', 'ĭ'] +['Ñ', '¬'] +['Ú', '¬'] +['Ü', 'Ĵ'] +['á´', '¬'] +['ï¨', 'Ħ'] +['É', '£'] +['Ë', 'ij'] +['Ï', 'µ'] +['Ò', 'Ŀ'] +['Û', '¥'] +['Ü', 'ł'] +['à¹', 'Ľ'] +['áĥ', 'ķ'] +['áĬ', 'ķ'] +['á¾', '¶'] +['âĤ', '·'] +['âĩ', '¾'] +['âķ', '©'] +['âĸ', 'IJ'] +['âĺ', 'ª'] +['âĺ', '®'] +['âĿ', 'ļ'] +['âĿ', 'Ń'] +['âŀ', '±'] +['âµ', 'İ'] +['ãı', 'Ĭ'] +['ë©', 'ĵ'] +['ìĹ', '¾'] +['ìª', 'Ħ'] +['íĵ', 'Į'] +['íķ', '¼'] +['ïŃ', '¬'] +['ðĿij', 'Ĩ'] +['ðĿij', 'ŀ'] +['ðĿĸ', 'Ĭ'] +['ðŁİ', '¸'] +['ðŁı', 'Ħ'] +['ðŁij', 'µ'] +['ðŁĴ', 'ł'] +['ðŁĶ', 'ĺ'] +['ðŁ¥', 'Ĥ'] +['Å', 'ª'] +['à·', 'ĥ'] +['á´', '¼'] +['âĬ', '°'] +['ë³', 'ı'] +['ë´', '£'] +['ï¥', 'ľ'] +['ðŁĵ', 'Ī'] +['ðŁķ', '¯'] +['ð٧', 'Ģ'] +['âĻ', 'IJ'] +['ðŁĨ', 'Ĺ'] +['ðŁĵ', 'ķ'] +['ð٧', 'ģ'] +['Ü', '«'] +['âĿ', 'IJ'] +['Õ', 'ķ'] +['à½', 'ķ'] +['âŀ', 'Ŀ'] +['à¦', 'ķ'] +['ðĿIJ', '¶'] +['É', '¢'] +['Î', 'Ħ'] +['áĨ', '¢'] +['âĤ', '±'] +['Õ', 'į'] +['à¡', 'ķ'] +['á´', '°'] +['á¸', '©'] +['âĽ', '·'] +['âĿ', '®'] +['ê¡', 'ĵ'] +['ëı', '¤'] +['ëĹ', 'IJ'] +['ëµ', 'Į'] +['ìij', 'Ī'] +['íı', '¿'] +['íĹ', 'µ'] +['ðĿIJ', 'İ'] +['ðŁĨ', 'ĺ'] +['ðŁı', 'Ł'] +['É', '¥'] +['Õ', '»'] +['à¡', 'Ķ'] +['à¤', 'ĸ'] +['á´', '¸'] +['âİ', 'Ļ'] +['âİ', '¥'] +['âı', '³'] +['ëģ', 'ķ'] +['ëĬ', 'ī'] +['ì¡', 'į'] +['ì¹', '¡'] +['ï¦', '¶'] +['ï¬', 'Ł'] +['ï®', '«'] +['ï®', '¯'] +['ï±', 'ĥ'] +['ï', '·»'] +['ïº', 'µ'] +['ðĿĹ', 'Ķ'] +['ðĿĹ', '¡'] +['ðŁİ', '¨'] +['ðŁĶ', 'Ĵ'] +['Ú', 'Ľ'] +['à¤', '§'] +['âŀ', '¹'] +['áĢ', 'Ģ'] +['ðŁį', 'ħ'] +['âĹ', '¤'] +['à¤', 'ł'] +['ðŁIJ', '¥'] +['áĥ', 'Ĵ'] +['ðŁı', 'Ŀ'] +['ðŁį', '¼'] +['ãĮ', '§'] +['âĿ', 'Ľ'] +['ðŁIJ', 'Ī'] +['à¦', '¯'] +['áĢ', 'ŀ'] +['ãĢ', 'ĸ'] +['áŀ', 'Ļ'] +['à¦', 'ª'] +['Õ', 'Ĩ'] +['âĬ', 'Ĩ'] +['âľ', '¾'] +['ðŁIJ', 'Ĺ'] +['ï¹', '¿'] +['Ä', '¦'] +['Ü', 'Ł'] +['à²', 'ł'] +['à²', '¥'] +['áŀ', 'ī'] +['á´', '¥'] +['á´', '©'] +['á½', 'Ģ'] +['á½', '¡'] +['âĨ', 'ķ'] +['âŀ', '¯'] +['ê¡', 'ij'] +['ëij', '£'] +['ë±', 'Į'] +['ìĪ', 'ij'] +['ìľ', 'Ķ'] +['ìŀ', '½'] +['ì¨', 'į'] +['ðĿij', 'Ģ'] +['ðŁĮ', 'Į'] +['ðŁį', '¦'] +['ðŁį', '©'] +['ðŁIJ', 'ļ'] +['ðŁĵ', 'Ĵ'] +['ðŁĵ', '¹'] +['ðŁ¥', 'ij'] +['Ä', 'ĭ'] +['Ë', 'Ĺ'] +['Ñ', '«'] +['Õ', '¢'] +['Ú', '°'] +['â', 'ĮĢ'] +['âĹ', 'Ĥ'] +['âĹ', '£'] +['âľ', 'Ľ'] +['âĿ', 'Ĵ'] +['âĿ', 'ĺ'] +['âŀ', 'Ļ'] +['âŀ', '²'] +['ãİ', 'į'] +['ê¡', 'IJ'] +['ëŀ', 'ĸ'] +['ìĬ', 'Ŀ'] +['ìĽ', '¤'] +['ì¡', 'ĭ'] +['ì¨', '°'] +['íĹ', 'Ļ'] +['ï¥', '¸'] +['ï³', 'į'] +['ï»', 'İ'] +['ðĿij', 'ĵ'] +['ðŁĵ', 'Ĭ'] +['ðŁļ', '¼'] +['ï¦', 'ģ'] +['ðĿķ', 'Ĵ'] +['ðŁ', 'ijľ'] +['ðŁij', '¿'] +['ðŁĩ', '½'] +['à·', 'Ħ'] +['âĸ', '´'] +['ãį', 'ī'] +['âĬ', 'ĩ'] +['ð٧', '¸'] +['Ú', '¡'] +['â¾', 'ĥ'] +['ðŁĹ', '»'] +['âĵ', 'ij'] +['ð٤', '¸'] +['ð٤', '¯'] +['êĴ', '°'] +['ðĿIJ', 'ĵ'] +['âĶ', '´'] +['êĴ', '±'] +['áĢ', 'ĺ'] +['â', 'ĽĦ'] +['ï¹', '¹'] +['Ó', 'Ķ'] +['áĥ', '±'] +['Ü', '¡'] +['ß', 'ŀ'] +['âĻ', 'ı'] +['âľ', '¸'] +['ìij', '¨'] +['ðĿIJ', 'Ŀ'] +['ðĿIJ', '¥'] +['ðŁį', 'ī'] +['ðŁij', '¼'] +['ðŁ¥', 'Ŀ'] +['Æ', 'Ķ'] +['Ý', '¬'] +['à¤', '«'] +['àº', 'ļ'] +['á´', '´'] +['á½', 'ĸ'] +['âĤ', '¶'] +['âİ', '¢'] +['âĿ', 'ħ'] +['âŁ', '«'] +['ãİ', 'Ľ'] +['ë®', '¨'] +['ëº', 'Į'] +['ë¼', 'ĺ'] +['ìĨ', 'Ŀ'] +['ìľ', '³'] +['ìŀ', 'Į'] +['ì£', 'Ĺ'] +['ìª', 'ĺ'] +['ì»', '¹'] +['ï·', '¼'] +['ïº', 'Ĥ'] +['ðĿIJ', '´'] +['ðĿIJ', '¼'] +['ðŁĮ', 'ļ'] +['ðŁı', '«'] +['ðŁĴ', '¤'] +['ðŁĴ', '¶'] +['ðŁĴ', '¼'] +['Ê', 'ķ'] +['Ê', '½'] +['â²', 'Ł'] +['ãī', 'ł'] +['ê¡', 'Ĵ'] +['ëľ', 'Ģ'] +['ìĥ', '¾'] +['ì¸', '¤'] +['ï¥', 'ģ'] +['ðĿļ', 'Ĭ'] +['ðŁļ', 'ĥ'] +['âŀ', 'Ľ'] +['ìħ', '´'] +['áĦ', 'ĭ'] +['âĩ', 'Ĺ'] +['ï§', '·'] +['âĺ', 'ĸ'] +['ðŁIJ', '¦'] +['â¸', 'ľ'] +['ðŁĴ', '´'] +['ð٤', 'ļ'] +['ãĬ', 'Ĺ'] +['âĮ', 'Ľ'] +['áĪ', 'Ľ'] +['à¼', 'º'] +['â½', 'ī'] +['ðŁı', '¢'] +['âĵ', 'ŀ'] +['âĺ', '½'] +['ãĢ', 'Ļ'] +['ð٤', '®'] +['Å', 'IJ'] +['áĥ', '¬'] +['ðĿĹ', '»'] +['ðŁį', 'ĸ'] +['Æ', 'Ĭ'] +['Ê', 'Ł'] +['ß', 'ĭ'] +['à¤', 'ĭ'] +['áµ', 'Ķ'] +['á¿', 'ĥ'] +['âĦ', 'ī'] +['âĮ', 'ĭ'] +['âı', '²'] +['âĵ', 'Ī'] +['âĵ', '¢'] +['âķ', 'Ķ'] +['âļ', 'ij'] +['âĿ', 'ĭ'] +['âĿ', 'İ'] +['â', 'µľ'] +['âµ', '£'] +['ëĴ', 'Ī'] +['ëľ', 'ģ'] +['ë¶', 'ĩ'] +['ìį', '»'] +['ìĺ', 'Ń'] +['ì§', '¢'] +['íĹ', 'Ģ'] +['ï§', 'Ĭ'] +['ï', '¬¸'] +['ï±', '¡'] +['ðĿIJ', 'º'] +['ðĿij', '§'] +['ðĿĺ', '¦'] +['ðŁĵ', '¥'] +['ðŁĺ', 'Ł'] +['ðŁ¥', 'IJ'] +['Ä', 'ĸ'] +['É', '¨'] +['áĢ', 'IJ'] +['áĥ', 'ĵ'] +['áº', 'ĵ'] +['á¼', '¶'] +['á½', 'Ħ'] +['âĤ', '¤'] +['âĮ', 'ľ'] +['âĮ', 'Ł'] +['âİ', 'ł'] +['âĽ', '¸'] +['âµ', 'į'] +['âµ', 'ı'] +['âµ', 'ĵ'] +['ãĢ', 'ĺ'] +['ë', '·¸'] +['íħ', '¼'] +['ï¦', 'Į'] +['ïŃ', 'Ħ'] +['ïŃ', 'İ'] +['ðĿĻ', 'ļ'] +['ðĿļ', 'ĺ'] +['à¼', 'ĵ'] +['ëŃ', 'ħ'] +['áIJ', 'Ľ'] +['ãİ', '¾'] +['ï¨', 'Ģ'] +['ðŁĹ', '½'] +['âĻ', 'ŀ'] +['Ë', 'ĸ'] +['âĹ', 'ŀ'] +['ð٤', '«'] +['ðŁĺ', 'Ĺ'] +['ï½', '¦'] +['ð٤', '¢'] +['âģ', 'ĩ'] +['ãĢ', 'µ'] +['ðŁį', 'Ķ'] +['áĬ', 'ł'] +['ðŁĺ', '¼'] +['ðĿĹ', '®'] +['ðŁIJ', '³'] +['ðĿIJ', 'ĭ'] +['ðŁĨ', 'ļ'] +['ðŁĶ', 'Ľ'] +['Ñ', '»'] +['Ü', '¨'] +['à®', '²'] +['âľ', 'ŀ'] +['âµ', 'Ļ'] +['êµ', '£'] +['ì¸', '¨'] +['ðĿ', 'IJľ'] +['ðĿĺ', '°'] +['ðŁĶ', '½'] +['Ç', '»'] +['Ç', '¿'] +['Ê', 'ĩ'] +['Î', 'IJ'] +['Ð', 'Ģ'] +['Ñ', '¡'] +['Ñ', '²'] +['Ò', 'Ĵ'] +['Ù', '¶'] +['ß', 'ķ'] +['à¶', '±'] +['áIJ', 'ģ'] +['âģ', 'ŀ'] +['âĸ', '§'] +['âĽ', 'Ī'] +['âľ', 'ľ'] +['âľ', '¹'] +['âŁ', '¹'] +['â¤', 'ĩ'] +['ê²', 'Ĭ'] +['ê¾', 'ľ'] +['ë¯', 'IJ'] +['ë³', 'IJ'] +['ìħ', '©'] +['ìIJ', '¬'] +['ìij', '¹'] +['ï¤', 'Ķ'] +['ï¦', 'ļ'] +['ï¬', 'ł'] +['ïŃ', 'Ķ'] +['ïº', '¶'] +['ðĿĴ', 'ı'] +['ðĿĸ', 'Ĩ'] +['ðĿĹ', '¶'] +['ðŁı', 'Ĥ'] +['ðŁIJ', '½'] +['ðŁĴ', '©'] +['ðŁĵ', '½'] +['ðŁĹ', '¨'] +['ðŁĹ', 'º'] +['ðŁĺ', '¸'] +['ðŁ¥', '§'] +['Å', 'Ĺ'] +['Ê', 'İ'] +['Ò', 'Ļ'] +['×', '²'] +['à¤', 'Ī'] +['á¼', '´'] +['á¿', 'ij'] +['âµ', 'ī'] +['ãħ', 'ĵ'] +['ì½', '´'] +['ðĿĸ', 'ĵ'] +['ðŁĵ', 'Ĺ'] +['ðŁĶ', 'ª'] +['ðŁĸ', 'į'] +['Ï', 'Ĵ'] +['ðŁij', '¬'] +['áĥ', 'Ļ'] +['âĨ', '¬'] +['âĶ', '¤'] +['âĽ', '¹'] +['âĻ', 'Ł'] +['ðŁļ', '¶'] +['ðŁij', '¾'] +['âĪ', 'ĭ'] +['ðŁIJ', '¯'] +['à¼', 'İ'] +['âľ', '·'] +['ï¨', 'Ļ'] +['âĶ', '»'] +['ðŁij', '¹'] +['áĦ', 'ī'] +['àº', 'ª'] +['â¾', 'ı'] +['â½', 'ħ'] +['ãİ', 'ĸ'] +['Ñ', '´'] +['Õ', '®'] +['Ú', '¼'] +['áĢ', 'ķ'] +['áĨ', '¼'] +['ëŃ', 'ı'] +['ðŁIJ', '¸'] +['ðŁļ', '£'] +['Æ', 'Ŀ'] +['Ô', '»'] +['áĥ', '¢'] +['ðŁį', '¯'] +['É', '¦'] +['Õ', '¦'] +['âĻ', 'ĭ'] +['ï¬', '«'] +['ðĿĹ', '¦'] +['Ç', 'ļ'] +['É', '±'] +['à¤', 'ī'] +['á´', 'Ħ'] +['âĻ', 'ĵ'] +['âĽ', '°'] +['âŁ', 'ª'] +['ëĥ', 'ĺ'] +['ë¢', '¸'] +['ìĤ', 'ij'] +['ï®', 'Ķ'] +['ðĿķ', 'ĸ'] +['ðĿĹ', '§'] +['ðŁĩ', '¼'] +['ðŁĵ', 'ĭ'] +['ðŁļ', 'ľ'] +['ðŁ¥', '¤'] +['Ä', '®'] +['Å', '·'] +['ß', 'Ĭ'] +['à¥', '¥'] +['à®', 'ª'] +['áŀ', 'Ħ'] +['áµ', 'Ģ'] +['á¸', 'ħ'] +['á¼', '¢'] +['âĪ', 'Ŀ'] +['âĬ', '¹'] +['âĴ', '¶'] +['âķ', '´'] +['âĽ', '±'] +['âĽ', '³'] +['âĽ', 'º'] +['âŀ', 'Ł'] +['ãı', 'Ħ'] +['ê¸', 'Ķ'] +['ê¹', 'Ł'] +['ëĩ', '°'] +['ë¹', '»'] +['ìĤ', '¥'] +['ìĽ', '»'] +['ì°', 'Ł'] +['íĥ', '°'] +['íĨ', 'º'] +['íļ', '½'] +['ï¤', '´'] +['ï¥', '¾'] +['ï³', 'Ŀ'] +['ðĿIJ', '¦'] +['ðĿĴ', 'ľ'] +['ðĿĴ', 'Ł'] +['ðĿļ', 'Ĺ'] +['ðŁİ', 'Ń'] +['ðŁı', 'ĵ'] +['ðŁı', '³'] +['ðŁı', 'º'] +['ðŁIJ', 'į'] +['ðŁij', 'ĥ'] +['ðŁĴ', 'ı'] +['ð٤', 'ĸ'] +['ð٤', 'µ'] +['Õ', '²'] +['âµ', 'Ķ'] +['ëĺ', '¬'] +['ï¦', '£'] +['Ê', 'Ĥ'] +['áĨ', '«'] +['áŀ', 'ij'] +['ðĿĸ', 'İ'] +['ðĿĹ', 'ĸ'] +['áĦ', 'ĥ'] +['âĩ', 'ł'] +['áĢ', '¡'] +['à½', 'Ħ'] +['âŀ', '¸'] +['ï¦', 'Ļ'] +['âĩ', 'ļ'] +['ðŁIJ', '¬'] +['ðŁIJ', '¢'] +['â¾', 'Ĵ'] +['ðŁIJ', '¤'] +['ðŁĶ', '«'] +['ãĢ', 'ŀ'] +['ï¸', 'º'] +['ðŁĺ', 'º'] +['â½', '´'] +['ðŁĨ', 'ķ'] +['âģ', '¿'] +['ðŁį', '¨'] +['à²', 'ķ'] +['ðŁļ', 'ĺ'] +['áŀ', 'ħ'] +['à¦', 'ħ'] +['áŀ', '¢'] +['à¨', 'ľ'] +['â', 'ļĮ'] +['ãĢ', '½'] +['à·', '´'] +['âĵ', 'Ľ'] +['áĢ', 'ľ'] +['ìĨ', '¨'] +['Ë', '©'] +['Ü', 'Ĺ'] +['âĭ', '¼'] +['ðŁĻ', 'ī'] +['Å', 'Ĭ'] +['É', 'ĵ'] +['Ê', '²'] +['Î', '°'] +['Ñ', '¼'] +['Ô', '¿'] +['à¡', 'IJ'] +['à¼', 'ľ'] +['à½', '¦'] +['á¶', 'ľ'] +['âĤ', '²'] +['âĨ', '¨'] +['âĬ', '¥'] +['âķ', '§'] +['âĻ', 'ľ'] +['ãĭ', '¡'] +['ë´', '¬'] +['ë¶', 'ij'] +['ìī', '¿'] +['ìİ', 'ħ'] +['ìł', '±'] +['ì°', '§'] +['ï²', '¡'] +['ðĿĴ', 'Ľ'] +['ðĿķ', '£'] +['ðĿĹ', 'ľ'] +['ðŁį', '²'] +['ðŁİ', '©'] +['ðŁIJ', 'IJ'] +['ðŁIJ', 'ł'] +['ðŁij', '½'] +['ðŁĴ', 'ij'] +['ðŁĵ', 'ľ'] +['ðŁķ', 'µ'] +['ðŁ', 'ļĮ'] +['ðŁĽ', '£'] +['Ê', 'ĭ'] +['Ó', '¯'] +['Ù', '¸'] +['ß', 'Ķ'] +['ß', 'Ļ'] +['à¡', 'ĵ'] +['á´', 'į'] +['á¸', '¿'] +['âı', 'º'] +['âĸ', '¥'] +['ë¤', '½'] +['íľ', 'ij'] +['ðĿIJ', '¹'] +['ðĿĸ', 'Ķ'] +['ðĿļ', 'İ'] +['ðŁĵ', 'Ħ'] +['ð٦', '·'] +['Æ', 'ĥ'] +['à¦', 'Ł'] +['âĮ', 'Ĥ'] +['âĺ', 'Ń'] +['â²', 'ļ'] +['ëĿ', 'ķ'] +['ðŁİ', '£'] +['à®', 'ĩ'] +['à½', 'Ĩ'] +['áħ', 'µ'] +['áĹ', 'ľ'] +['âĢ', '½'] +['âĮ', '£'] +['âģ', '½'] +['ðŁĵ', '¬'] +['ð٤', '§'] +['âĩ', 'ª'] +['â½', '£'] +['âĹ', 'Ł'] +['ï¨', 'Ĺ'] +['êĴ', 'ª'] +['ðŁĽ', 'Ģ'] +['Ç', 'Ĥ'] +['ðŁ¥', '¶'] +['ðŁİ', 'į'] +['ï¿', '©'] +['ðŁij', 'Ĵ'] +['áµ', 'Ī'] +['ï¸', '¿'] +['áħ', '©'] +['â¾', '¦'] +['à°', '¤'] +['á´', 'ĸ'] +['à¨', '¬'] +['àº', 'Ĺ'] +['à¼', '»'] +['Ñ', 'º'] +['à¨', 'ª'] +['á´', '³'] +['ðĿIJ', 'Ī'] +['à»', 'Ģ'] +['á´', '¿'] +['âĤ', 'į'] +['âĩ', '¡'] +['âĽ', 'ª'] +['ðĿIJ', 'Ĥ'] +['ðĿĴ', 'ķ'] +['ðŁ', 'IJľ'] +['Ê', 'į'] +['Ñ', '±'] +['à½', 'ĥ'] +['ë®', 'IJ'] +['ìĽ', '¡'] +['ìľ', 'ģ'] +['ðĿIJ', '¿'] +['ðĿķ', 'ł'] +['ðŁij', 'Ľ'] +['Æ', 'ª'] +['Ï', 'º'] +['Ó', '¬'] +['Ù', '¿'] +['Ý', '£'] +['àª', 'ī'] +['à®', '¹'] +['à½', 'ij'] +['áĨ', '¯'] +['áµ', 'ĩ'] +['âĩ', '¥'] +['âı', 'ª'] +['âĻ', '°'] +['âļ', 'Ń'] +['âļ', '¾'] +['ãħ', 'Ħ'] +['êĢ', '°'] +['ê°', 'Ĺ'] +['ê²', 'ĭ'] +['ê²', '»'] +['ê¶', 'ľ'] +['ê¼', 'ĩ'] +['ê½', '¹'] +['ëĤ', 'Ł'] +['ëħ', 'Ī'] +['ëĭ', '¢'] +['ë§', 'Ł'] +['ëª', 'Ĩ'] +['ëµ', 'Ģ'] +['ì½', '±'] +['íĩ', 'ĺ'] +['íľ', 'ľ'] +['ï§', '¾'] +['ï±', 'µ'] +['ï²', '¢'] +['ï²', '¤'] +['ðĿĴ', 'Ĭ'] +['ðĿĺ', '¯'] +['ðŁį', 'Ĺ'] +['ðŁı', 'į'] +['ðŁIJ', 'ĺ'] +['ðŁĵ', '¡'] +['ðŁĶ', 'ŀ'] +['ð٤', '³'] +['ðŁ¥', 'ģ'] +['ðŁ¥', 'Ĺ'] +['ð٦', 'Ĭ'] +['Ä', 'µ'] +['Æ', '¦'] +['Ç', 'µ'] +['É', '¯'] +['Î', 'ı'] +['Õ', 'Ħ'] +['Ü', '¥'] +['à½', 'ģ'] +['á¨', 'ł'] +['âķ', '«'] +['ãİ', 'ī'] +['ë·', '´'] +['ìĨ', 'İ'] +['ìİ', 'Į'] +['ì£', 'µ'] +['íĽ', 'ł'] +['ï§', 'ª'] +['ï³', 'ı'] +['ï»', 'º'] +['ðĿij', 'ģ'] +['ðĿij', 'ĩ'] +['ðĿĴ', 'Ĩ'] +['ðŁİ', 'ł'] +['ðŁIJ', 'Ķ'] +['ðŁij', 'Ł'] +['Å', 'ĸ'] +['à¤', 'Į'] +['á¾', '½'] +['ê¦', 'Ĵ'] +['à®', 'Ł'] +['á´', '±'] +['ðŁı', '°'] +['ðŁIJ', 'ŀ'] +['à½', 'Ģ'] +['áĢ', 'ħ'] +['âĬ', '¿'] +['ðŁIJ', '§'] +['áĽ', 'ģ'] +['â¼', 'Ī'] +['âĶ', '¿'] +['ðŁ¥', '´'] +['â¼', '¿'] +['ð٧', 'ľ'] +['ãħ', '¿'] +['âĦ', '«'] +['ãĢ', '³'] +['ãĬ', 'Ļ'] +['â¼', 'Ģ'] +['ï', '¦¬'] +['ðŁı', '¬'] +['ðŁĵ', '»'] +['áĬ', 'Ľ'] +['áĦ', 'ħ'] +['àº', 'Ĭ'] +['àº', 'Ľ'] +['áħ', '³'] +['ðŁij', '®'] +['à®', '±'] +['âĺ', 'ĩ'] +['ðĿIJ', 'ı'] +['à´', 'µ'] +['à»', 'ģ'] +['à½', 'ı'] +['à½', '¢'] +['á¥', '±'] +['âĤ', '£'] +['ï¥', '¦'] +['ïŃ', 'Ļ'] +['ï´', '©'] +['ï¹', 'Ĥ'] +['ðŁį', '£'] +['ðŁķ', '¹'] +['Ï', 'ĸ'] +['à¶', '¸'] +['àº', '¢'] +['áĭ', 'Ń'] +['âİ', 'Ŀ'] +['âĹ', 'Ŀ'] +['âĻ', 'Ī'] +['âĻ', 'İ'] +['ê½', '¥'] +['ì³', 'Ķ'] +['ì¼', 'ij'] +['ï±', '°'] +['ðĿij', 'ĥ'] +['ðŁĮ', 'ª'] +['ðŁį', '¡'] +['Å', 'İ'] +['Ê', '¦'] +['Ñ', '§'] +['Ó', 'İ'] +['Ô', '´'] +['Ú', 'Ī'] +['ß', 'ĵ'] +['ß', '§'] +['à¤', 'Ķ'] +['áĪ', '«'] +['áĪ', 'µ'] +['áĹ', '©'] +['á´', 'ł'] +['á¼', 'ł'] +['âĢ', 'Ĺ'] +['âģ', 'ij'] +['âĦ', 'ı'] +['âĸ', 'ĩ'] +['â²', '£'] +['ãĦ', '³'] +['ãī', '®'] +['ê³', 'Ĺ'] +['ëĦ', 'Ĵ'] +['ëĸ', '«'] +['ë¡', 'Ħ'] +['ë¹', '°'] +['ë½', 'ģ'] +['ìĦ', 'ģ'] +['ìĮ', 'ĺ'] +['ìŁ', 'Į'] +['ì³', 'ī'] +['ì¼', 'ķ'] +['ï¬', '»'] +['ï³', 'İ'] +['ï¹', '¸'] +['ï¹', '¾'] +['ðĿIJ', 'Ĩ'] +['ðĿij', '·'] +['ðĿĽ', '¼'] +['ðŁİ', 'ı'] +['ðŁİ', 'ŀ'] +['ðŁIJ', 'Ļ'] +['ðŁij', 'Ĥ'] +['ðŁĵ', 'ģ'] +['ðŁĸ', '±'] +['ðŁļ', 'į'] +['ðŁļ', '§'] +['ðŁĽ', '¡'] +['ð٤', 'Ĵ'] +['ðŁ¥', 'ŀ'] +['ðŁ¥', '©'] +['ð٦', 'Ģ'] +['ð٦', 'ĸ'] +['Ë', '¢'] +['Ü', 'ļ'] +['à®', 'µ'] +['áĢ', 'ģ'] +['áī', '°'] +['âı', 'Ń'] +['âĻ', '¿'] +['ê³', 'ĺ'] +['ëı', 'Ŀ'] +['ëķ', 'ĥ'] +['ìħ', 'Į'] +['ìĴ', '¸'] +['ìĽ', 'Ł'] +['íħ', 'Ħ'] +['íľ', '«'] +['ï§', 'ĺ'] +['ï¿', '¬'] +['ðŁı', '·'] +['ðŁĶ', '§'] +['ðŁ¥', 'Ī'] +['Æ', 'ĸ'] +['áŀ', 'ĩ'] +['áŀ', 'ĸ'] +['âģ', 'º'] +['âĹ', 'ľ'] +['âŀ', '©'] +['ê¦', 'Ń'] +['ëĻ', '¤'] +['ïŃ', '¼'] +['ðĿĻ', 'ĸ'] +['ðĿĻ', '£'] +['ðĿĻ', '¤'] +['ðŁĮ', 'Ŀ'] +['ðŁĶ', 'ij'] +['ðŁĽ', 'ł'] +['àº', 'ĩ'] +['âĺ', '£'] +['ãĦ', '¨'] +['ðĿĸ', 'Ĺ'] +['Ó', 'ĵ'] +['âĨ', '£'] +['ðŁ¥', 'ī'] +['ðŁĮ', 'ł'] +['ðŁĺ', '½'] +['ãİ', 'ł'] +['Å', '§'] +['ðŁIJ', 'Ĵ'] +['ï§', 'IJ'] +['ðŁĺ', '¿'] +['âĪ', '¬'] +['ðŁIJ', '®'] +['âŁ', '±'] +['à²', '¡'] +['â¾', '¼'] +['à°', '²'] +['Ë', '¶'] +['âĸ', '¿'] +['Õ', 'Ī'] +['áŀ', 'İ'] +['áħ', '¥'] +['áŀ', 'Ĺ'] +['Õ', '§'] +['ð٤', 'IJ'] +['ðŁį', 'ł'] +['à¦', '¤'] +['à¶', 'º'] +['âĻ', 'į'] +['ìĺ', 'Ļ'] +['íĺ', 'ĵ'] +['ï¹', 'º'] +['ðŁĽ', '³'] +['Å', 'ī'] +['á´', 'İ'] +['âı', 'ľ'] +['âĶ', '³'] +['ê¸', '·'] +['ì¡', 'Ķ'] +['ðĿĴ', 'Ī'] +['ðĿĴ', 'į'] +['ðĿĴ', '¹'] +['ðĿĵ', 'ĩ'] +['ðĿķ', 'Ł'] +['ðĿĹ', '¹'] +['ðŁĮ', 'ħ'] +['ðŁı', '´'] +['Ä', 'Ķ'] +['Ä', '¤'] +['Å', 'µ'] +['Ç', '¾'] +['Ï', 'ŀ'] +['Ï', '¶'] +['Ô', '³'] +['Ü', 'Ĩ'] +['ß', '©'] +['à¡', 'Ĵ'] +['à¤', 'ĺ'] +['à¶', 'ļ'] +['à½', 'ĸ'] +['áģ', 'Ĭ'] +['áĥ', 'ŀ'] +['áĦ', 'Ĥ'] +['áĭ', '«'] +['á´', 'º'] +['á¸', '£'] +['á¸', 'ª'] +['á¹', 'Ĥ'] +['á¼', '·'] +['á¿', 'ĩ'] +['âĩ', 'Į'] +['âı', '¬'] +['âĻ', 'Į'] +['â®', 'Ł'] +['â´', '»'] +['âµ', 'Ł'] +['ê¦', 'ķ'] +['ê¦', 'ª'] +['ê¦', '®'] +['ê²', 'Ħ'] +['ê¾', 'IJ'] +['ëĥ', 'ij'] +['ëķ', 'ĭ'] +['ë¡', '¸'] +['ë¬', 'Ģ'] +['ìĩ', '¤'] +['ìĪ', '©'] +['ìľ', 'ķ'] +['ìŃ', 'ĺ'] +['ì·', '°'] +['ì', '·¸'] +['íľ', 'Ģ'] +['ï¤', '£'] +['ï§', 'į'] +['ï±', 'Ħ'] +['ï³', 'ij'] +['ðĿIJ', '¤'] +['ðĿĴ', 'ĵ'] +['ðĿĴ', '¶'] +['ðĿĹ', '¼'] +['ðĿĻ', 'Ĭ'] +['ðŁĩ', '¾'] +['ðŁĮ', 'Ľ'] +['ðŁĮ', '®'] +['ðŁİ', 'ĩ'] +['ðŁİ', '²'] +['ðŁı', 'Ľ'] +['ðŁij', '¥'] +['ðŁij', '´'] +['ðŁĴ', 'Ĩ'] +['ðŁĵ', 'Ĥ'] +['ðŁĵ', '§'] +['ðŁķ', 'IJ'] +['ðŁĸ', 'ķ'] +['ðŁĺ', '§'] +['ðŁĻ', 'Ģ'] +['ðŁļ', 'Ĵ'] +['ðŁĽ', '«'] +['ð٤', 'ł'] +['ðŁ¥', 'ļ'] +['ðŁ¥', 'Ľ'] +['ðŁ¥', '£'] +['Ç', '¯'] +['È', '§'] +['Î', 'Ĭ'] +['Ò', '²'] +['×', '°'] +['Û', 'ij'] +['áĥ', '©'] +['áĦ', 'Į'] +['áĪ', 'į'] +['áī', '¥'] +['áı', 'Ĥ'] +['âģ', '±'] +['âĬ', '¢'] +['âĹ', 'ĵ'] +['âĿ', '°'] +['ë¿', '¡'] +['ìĽ', '©'] +['íģ', 'Ń'] +['íĨ', '³'] +['íĬ', 'Ħ'] +['íĵ', '¸'] +['ï¥', '£'] +['ï¥', '´'] +['ï±', 'IJ'] +['ï±', '¯'] +['ï³', 'ļ'] +['ðĿĸ', 'ĺ'] +['ðĿĺ', 'Ģ'] +['ðŁIJ', 'Ĭ'] +['ðŁIJ', 'Į'] +['ðŁij', 'ļ'] +['ðŁĵ', 'ĥ'] +['ðŁļ', 'Ľ'] +['ðŁļ', 'ª'] +['ð٤', '°'] +['Ä', '´'] +['áĥ', '®'] +['áĹ', '¨'] +['âĻ', '®'] +['â²', 'ŀ'] +['ãĪ', 'Ķ'] +['ì', 'ħį'] +['ãħ', 'ĥ'] +['ï¥', '¡'] +['àº', '¡'] +['Õ', 'İ'] +['Õ', 'º'] +['â¬', 'Ľ'] +['â½', '¤'] +['ðĿIJ', '²'] +['âŀ', 'µ'] +['áĢ', 'Ľ'] +['âĶ', 'ħ'] +['âĨ', 'Ł'] +['â¼', 'Ĭ'] +['ðŁĮ', '½'] +['ðŁļ', '¿'] +['ï¦', 'Ĭ'] +['ãĦ', '£'] +['âĽ', '©'] +['ï©', 'Ľ'] +['ðŁį', '±'] +['â¾', '¨'] +['à´', '¤'] +['áŀ', 'ģ'] +['àº', 'ŀ'] +['Ê', 'ļ'] +['ðĿIJ', 'Ĵ'] +['à´', '±'] +['áŀ', 'ľ'] +['à®', '©'] +['à°', 'Ĺ'] +['à´', 'ļ'] +['âĩ', '£'] +['ï¦', 'ķ'] +['Õ', 'ħ'] +['Æ', 'ĺ'] +['âĤ', '¦'] +['âĶ', 'Ħ'] +['ï¦', 'Ł'] +['ï¦', '«'] +['ðĿIJ', 'ģ'] +['ðĿIJ', 'ĥ'] +['ðŁį', '¸'] +['ðŁIJ', '²'] +['Å', '¶'] +['É', 'ĸ'] +['ß', 'ĺ'] +['à¸', '¦'] +['à½', 'Ķ'] +['áĨ', '·'] +['âģ', 'ķ'] +['âĵ', 'Ĥ'] +['âĿ', 'ľ'] +['ï¥', '¥'] +['ï¬', '®'] +['ðĿĹ', 'Ŀ'] +['ðĿĹ', '¿'] +['ðŁİ', '¾'] +['ðŁĹ', 'Ŀ'] +['ð٦', 'Į'] +['Æ', 'ħ'] +['Ç', 'ª'] +['Ò', 'Ĺ'] +['Ü', 'Ľ'] +['ß', 'ł'] +['à¡', 'ij'] +['áī', '£'] +['áĬ', 'Ń'] +['á¹', '¡'] +['âŀ', '¼'] +['âŀ', '¾'] +['â´', '±'] +['ãī', '¡'] +['ê³', '¯'] +['ë½', 'Ī'] +['ìĤ', 'ĺ'] +['ìī', 'ij'] +['ì', '«ĺ'] +['íĮ', 'ĥ'] +['íĻ', '°'] +['ï¤', 'Ĺ'] +['ðŁĮ', '¬'] +['ðŁĮ', '°'] +['ðŁį', '¤'] +['Ä', '»'] +['Å', 'ĩ'] +['Æ', '¨'] +['É', 'ķ'] +['Ò', '¢'] +['Ò', 'º'] +['Ö', 'į'] +['×', '±'] +['Ú', '±'] +['Ú', '½'] +['Û', 'IJ'] +['à¤', 'Ľ'] +['à·', 'Ģ'] +['à¹', 'ļ'] +['àº', '«'] +['á´', '¹'] +['á', '½Ķ'] +['á¾', '³'] +['âĤ', 'Ĵ'] +['âĨ', '´'] +['âĩ', 'Ŀ'] +['âī', 'ħ'] +['â', 'Į¨'] +['âĵ', 'ĵ'] +['âĸ', '¢'] +['âļ', '¬'] +['âŀ', 'Ń'] +['â²', 'Ĵ'] +['ãİ', '¿'] +['ê¿', '´'] +['ëĪ', '±'] +['ëį', '¬'] +['ëİ', 'IJ'] +['ëIJ', '«'] +['ëĶ', '«'] +['ë±', 'ģ'] +['ìĥ', '¥'] +['íĮ', '¼'] +['ïŃ', 'ĵ'] +['ï®', '¥'] +['ï²', '°'] +['ðĿIJ', 'ĩ'] +['ðĿIJ', 'ij'] +['ðĿij', 'Į'] +['ðĿĵ', 'ª'] +['ðĿķ', 'ļ'] +['ðĿĺ', 'ª'] +['ðĿĺ', '¼'] +['ðĿļ', 'Ľ'] +['ðŁĩ', '¶'] +['ðŁĮ', 'Ħ'] +['ðŁĮ', 'ķ'] +['ðŁĮ', '¤'] +['ðŁĮ', '§'] +['ðŁį', '¬'] +['ðŁİ', 'ĭ'] +['ðŁİ', '»'] +['ðŁı', '¨'] +['ðŁIJ', 'ĩ'] +['ðŁij', 'ĵ'] +['ðŁĵ', 'IJ'] +['ðŁĵ', 'Ļ'] +['ðŁĶ', '¼'] +['ðŁķ', 'Ĵ'] +['ðŁĸ', 'ı'] +['ðŁĸ', '¥'] +['ð٤', '¬'] +['ðŁ¥', 'Ĭ'] +['ðŁ¥', 'Ĵ'] +['ß', 'Į'] +['àº', 'Ħ'] +['á¼', 'µ'] +['âķ', '¡'] +['â²', '¤'] +['â´', '¼'] +['âµ', '¢'] +['ãĪ', '¯'] +['ëĵ', '¸'] +['ëŁ', 'ĩ'] +['ëº', 'į'] +['ðĿĻ', '§'] +['ðŁį', 'Ī'] +['ðŁĶ', '¬'] +['ðŁĸ', 'Ĭ'] +['ð٤', '¾'] +['Ë', '¡'] +['Ü', '©'] +['âĮ', '¡'] +['âŃ', 'ij'] +['â²', '¦'] +['ë©', 'ī'] +['ì¼', 'Ń'] +['ï¿', '¤'] +['ðĿĴ', 'İ'] +['ðĿĹ', '¥'] +['ðŁIJ', 'µ'] +['ðŁķ', '¶'] +['ðŁķ', '¸'] +['ð٤', 'ľ'] +['Õ', 'ª'] +['áĪ', 'ĭ'] +['ðŁ¥', 'µ'] +['ï°', 'ģ'] +['áµ', 'IJ'] +['âķ', 'ĵ'] +['áĢ', 'ĸ'] +['âĭ', 'Ī'] +['É', 'ŀ'] +['âŀ', '®'] +['à¥', '°'] +['ãĨ', 'ģ'] +['ðŁĴ', '±'] +['ðŁı', 'Ń'] +['áĨ', '¨'] +['ðŁį', 'ļ'] +['ð٦', 'IJ'] +['á´', '»'] +['âĺ', 'Į'] +['à´', 'ķ'] +['Õ', '±'] +['áħ', '®'] +['ðĿIJ', 'Į'] +['Å', '¦'] +['àº', 'ķ'] +['âľ', 'Ļ'] +['Ë', '³'] +['Ô', 'µ'] +['âķ', 'Ĵ'] +['ðĿĹ', 'Ĺ'] +['ðĿĹ', 'ł'] +['Ú', 'ļ'] +['à¦', '§'] +['âĨ', 'Ŀ'] +['âĻ', 'ī'] +['ãĮ', '»'] +['ì¹', 'Ĭ'] +['ðĿĹ', 'º'] +['ð٧', 'ĺ'] +['ì³', '£'] +['ï¬', 'Ŀ'] +['ðŁij', 'º'] +['Ç', 'Ł'] +['Î', 'Ī'] +['Î', '«'] +['Ñ', '¥'] +['Ô', '²'] +['Õ', '¨'] +['Ü', '¦'] +['à¦', 'Ĩ'] +['à¦', '¥'] +['áIJ', '¢'] +['á¼', 'ģ'] +['á¼', 'ĺ'] +['á¼', '¦'] +['âĵ', 'Ŀ'] +['ãĪ', '°'] +['ãİ', 'Ĺ'] +['ê²', '¡'] +['ë¨', 'Ģ'] +['ì£', 'Ķ'] +['ì´', '¤'] +['ìµ', 'Ŀ'] +['ï§', '´'] +['ïŃ', 'Ĭ'] +['ï²', 'Ł'] +['ðĿIJ', '·'] +['ðĿij', 'ĭ'] +['ðĿĵ', 'ī'] +['ðĿĺ', 'µ'] +['ðŁĴ', '·'] +['ðŁĽ', '©'] +['ð٧', '¹'] +['Å', 'Ķ'] +['Ê', 'ŀ'] +['Ë', '¥'] +['Î', 'Į'] +['Ñ', '©'] +['Ó', 'IJ'] +['Ó', 'ł'] +['Ú', 'ij'] +['Ú', 'Ĵ'] +['ß', '¨'] +['àª', 'Ī'] +['áIJ', 'ĥ'] +['á¹', '¯'] +['âĤ', 'ĭ'] +['âĤ', 'µ'] +['âĦ', 'ħ'] +['âĦ', 'ł'] +['âĪ', '£'] +['âī', 'º'] +['âī', '»'] +['âĬ', 'Ľ'] +['âĮ', 'IJ'] +['âİ', 'ĵ'] +['âĺ', '¸'] +['âĻ', 'Ĵ'] +['âļ', 'Ĵ'] +['âľ', 'ĩ'] +['âľ', 'ł'] +['â´', '·'] +['âµ', 'ĸ'] +['ãĦ', '¸'] +['ãī', '¢'] +['ãī', '°'] +['êĩ', '´'] +['ê´', '¸'] +['êº', 'ł'] +['ëĤ', 'ı'] +['ëĤ', '¢'] +['ëIJ', 'Ģ'] +['ëº', '´'] +['ìĥ', 'ľ'] +['ìį', 'ħ'] +['ì¤', '«'] +['ì±', '¦'] +['ìº', 'ij'] +['ì¼', 'ģ'] +['ì¿', '³'] +['íĤ', 'ģ'] +['íħ', '¡'] +['íĴ', 'Ĥ'] +['íĴ', 'ī'] +['íľ', 'Ħ'] +['ïŃ', 'ª'] +['ï®', '¬'] +['ï¯', '¦'] +['ï±', 'ª'] +['ï²', 'ı'] +['ï', '´Ģ'] +['ï»', 'Ĩ'] +['ï¿', '¦'] +['ðĿij', 'Ĺ'] +['ðĿĸ', 'Ļ'] +['ðŁĮ', '¡'] +['ðŁį', 'Ŀ'] +['ðŁį', '§'] +['ðŁİ', '«'] +['ðŁı', 'ĺ'] +['ðŁı', 'ª'] +['ðŁIJ', 'ĭ'] +['ðŁIJ', 'Ľ'] +['ðŁIJ', 'º'] +['ðŁij', 'ĸ'] +['ðŁij', 'ŀ'] +['ðŁij', '·'] +['ðŁĵ', 'Ģ'] +['ðŁ', 'ĶĦ'] +['ðŁĶ', 'Į'] +['ðŁķ', 'Ļ'] +['ðŁĻ', 'į'] +['ðŁĻ', 'İ'] +['ð٦', 'į'] +['Ç', '°'] +['É', 'Ł'] +['Ê', 'Ĩ'] +['Ô', '¼'] +['Ú', 'ľ'] +['à¦', '¡'] +['à¦', '¶'] +['áĴ', 'ĥ'] +['á¼', '©'] +['âĵ', 'ķ'] +['â²', 'Ī'] +['ê°', '°'] +['ê¹', 'ł'] +['êº', 'ħ'] +['ëĦ', '¹'] +['ë¯', 'ĵ'] +['íIJ', 'Ī'] +['ï§', '¶'] +['ï®', 'ij'] +['ï²', '¨'] +['ðĿĴ', 'ī'] +['ðĿĴ', 'Ķ'] +['ðĿĹ', '¨'] +['ðĿĻ', 'ŀ'] +['ðĿļ', 'Ĵ'] +['ðĿļ', 'ķ'] +['ðŁIJ', 'İ'] +['ð٤', 'ķ'] +['ð٧', 'Ķ'] +['Ï', '°'] +['Ô', 'Ŀ'] +['âĮ', 'Ĭ'] +['âĴ', '¾'] +['ãī', '£'] +['ïŃ', '©'] +['ðĿļ', 'ŀ'] +['Ê', 'ij'] +['à¦', '¦'] +['áĦ', 'ĩ'] +['âī', 'ĥ'] +['â²', 'Ģ'] +['ìŁ', 'İ'] +['ðĿij', '¶'] +['ðĿĵ', '²'] +['ðŁ', 'İ·'] +['ðŁļ', '¹'] +['àº', 'ģ'] +['áł', 'ł'] +['ãĦ', 'ļ'] +['ðŁIJ', '¿'] +['áĽ', 'ļ'] +['âķ', '³'] +['ðŁIJ', 'Ń'] +['âĴ', '¹'] +['ðĿĸ', 'ļ'] +['âĻ', 'ĸ'] +['ãĪ', '²'] +['âĨ', '¾'] +['áĦ', 'Ĩ'] +['âķ', 'Ľ'] +['ð٤', 'į'] +['â½', '¥'] +['ðŁ', 'Į¨'] +['âĪ', '®'] +['ãĮ', 'ĺ'] +['ãį', 'ij'] +['ï¹', 'Ģ'] +['âĵ', 'Ĺ'] +['âĬ', 'Ħ'] +['ðŁı', '¹'] +['Ë', 'Ĵ'] +['ð٤', '±'] +['ãı', 'ľ'] +['ðŁİ', 'Į'] +['ï¥', 'Ń'] +['à¦', '£'] +['ðŁİ', '¹'] +['ãĬ', 'Ł'] +['à´', '°'] +['ðĿIJ', 'Ķ'] +['à´', '¨'] +['à½', 'ļ'] +['âľ', 'º'] +['Õ', '·'] +['ðŁij', '³'] +['à¦', 'ľ'] +['âĺ', 'ĭ'] +['âĻ', 'Ĭ'] +['ãĢ', 'Ľ'] +['È', 'ĭ'] +['à®', '°'] +['áĥ', '¨'] +['âĦ', 'ķ'] +['íij', 'Ģ'] +['ðĿĵ', 'ĥ'] +['ð٦', 'Ķ'] +['Ä', '¿'] +['Å', 'Ģ'] +['Æ', '³'] +['É', 'ļ'] +['Ö', 'ĥ'] +['Ü', '£'] +['ß', 'Ł'] +['à¦', 'Ń'] +['à§', '¡'] +['à¶', '»'] +['àº', '£'] +['à½', 'ĩ'] +['á¸', '¨'] +['á½', 'Ī'] +['â½', '¬'] +['ê¡', 'Ķ'] +['ì³', 'Ħ'] +['ï¨', 'ī'] +['ðĿIJ', '¡'] +['ðĿĺ', '¢'] +['ðŁį', '¿'] +['ðŁİ', 'Ł'] +['ðŁı', 'ī'] +['ðŁĶ', 'IJ'] +['ðŁļ', 'ħ'] +['ð٤', '½'] +['Æ', 'į'] +['Ç', '«'] +['Ç', '½'] +['È', 'ļ'] +['Î', 'ī'] +['Ó', '¤'] +['Ó', 'ª'] +['Õ', 'Ĭ'] +['Ù', '¼'] +['Ú', '´'] +['ß', 'Ŀ'] +['à¶', 'ľ'] +['á¼', 'ķ'] +['á¿', '¥'] +['âİ', 'ŀ'] +['ãĢ', 'ļ'] +['ãī', '¤'] +['ê³', '¸'] +['ê·', 'ģ'] +['ëĵ', 'Ħ'] +['ëĵ', 'ķ'] +['ì¨', 'Ķ'] +['ì±', '¨'] +['ðĿIJ', '¾'] +['ðĿij', '»'] +['ðĿĶ', '¼'] +['ðĿķ', 'Ŀ'] +['ðĿĺ', 'Ń'] +['ðŁĨ', 'Ļ'] +['ðŁĵ', '¤'] +['ðŁĶ', 'Ł'] +['ðŁĹ', '¼'] +['Ä', 'ľ'] +['Æ', 'ģ'] +['Æ', '¿'] +['Ç', '³'] +['Ç', '·'] +['É', 'ĥ'] +['É', 'ł'] +['Ê', 'ī'] +['Ê', '§'] +['Ë', '²'] +['Ï', '´'] +['Õ', 'ģ'] +['Õ', 'ŀ'] +['Ö', 'ĩ'] +['Û', 'Ĥ'] +['Û', 'ĵ'] +['ß', 'Ĺ'] +['ß', '¦'] +['à¦', '¹'] +['à®', '³'] +['à´', '¸'] +['à»', 'Ĥ'] +['áĪ', 'Ŀ'] +['áĪ', 'ª'] +['áĭ', 'µ'] +['áIJ', 'Ĭ'] +['áĴ', 'ª'] +['áļ', 'ĸ'] +['áŀ', 'Ľ'] +['á´', '¢'] +['áµ', 'ı'] +['áµ', 'Ń'] +['á¶', '«'] +['á¸', 'ı'] +['áº', 'Ĵ'] +['á¼', '¥'] +['á½', 'ķ'] +['á½', '¼'] +['âĤ', 'Ĭ'] +['âĦ', 'Ĥ'] +['âĦ', '©'] +['âĩ', 'ī'] +['âī', '£'] +['âĮ', 'ł'] +['âİ', 'Ł'] +['âı', '®'] +['âķ', 'ĺ'] +['âĹ', 'ĸ'] +['âĺ', '©'] +['âĻ', 'ij'] +['âĻ', '²'] +['âļ', 'Ľ'] +['ãĦ', 'Ł'] +['ãī', '±'] +['ãİ', 'ļ'] +['ê¡', 'ķ'] +['êª', 'ĸ'] +['ê°', '¹'] +['ê²', 'Ĩ'] +['êµ', 'Ħ'] +['ëĩ', '¬'] +['ëĭ', '¯'] +['ëı', 'ł'] +['ëĴ', '¬'] +['ëĸ', 'Ī'] +['ëĸ', '½'] +['ëĺ', 'Ķ'] +['ëŀ', '¸'] +['ë¸', 'ħ'] +['ë»', 'ł'] +['ë¿', 'Ł'] +['ìĤ', 'µ'] +['ìĬ', 'ī'] +['ìľ', '°'] +['ìł', 'ĭ'] +['ìł', 'Ķ'] +['ì¥', '¡'] +['ìŃ', 'Ŀ'] +['ì¼', '¬'] +['íĪ', 'ĩ'] +['íī', 'ľ'] +['íį', 'Ħ'] +['íĽ', '¾'] +['íĿ', '£'] +['ï¤', '©'] +['ï¤', '¯'] +['ï¦', 'ľ'] +['ï¦', '§'] +['ï§', 'ľ'] +['ï¨', 'Ī'] +['ï¬', 'ª'] +['ï', '¬´'] +['ïŃ', '½'] +['ï®', 'ī'] +['ï¯', 'ŀ'] +['ï°', 'Ĵ'] +['ï±', 'ĩ'] +['ï¿', 'Ħ'] +['ðĿIJ', 'ħ'] +['ðĿij', 'Ħ'] +['ðĿij', 'º'] +['ðĿĴ', 'Ĺ'] +['ðĿĵ', '®'] +['ðĿķ', 'Ľ'] +['ðĿķ', 'ŀ'] +['ðĿĸ', 'ij'] +['ðĿĺ', 'ģ'] +['ðĿĺ', 'Ĩ'] +['ðĿĺ', '¶'] +['ðĿĻ', '¢'] +['ðĿļ', 'ľ'] +['ðŁĮ', 'ĥ'] +['ðŁĮ', '¦'] +['ðŁį', 'Ł'] +['ðŁİ', 'İ'] +['ðŁı', 'Ļ'] +['ðŁIJ', '©'] +['ðŁIJ', '«'] +['ðŁIJ', '´'] +['ðŁij', 'Ķ'] +['ðŁĵ', 'ī'] +['ðŁĵ', 'Ľ'] +['ðŁĶ', 'ī'] +['ðŁĸ', '¼'] +['ðŁĹ', 'ĥ'] +['ðŁĹ', '¯'] +['ðŁļ', 'ĩ'] +['ðŁļ', 'IJ'] +['ðŁļ', 'µ'] +['ð٤', '¶'] +['ðŁ¥', 'ĭ'] +['ðŁ¥', 'ĵ'] +['ðŁ¥', '®'] +['ð٦', 'İ'] +['ð٦', 'ł'] +['ð٧', 'Ĵ'] +['ð٧', '¨'] +['Æ', 'IJ'] +['Ç', 'į'] +['Ó', 'Ģ'] +['Ô', 'Ľ'] +['à²', '°'] +['à´', 'Ļ'] +['áĢ', 'Ĵ'] +['ê²', 'Ŀ'] +['ê¹', '¹'] +['ë©', '¥'] +['ìĸ', 'Ķ'] +['ï¤', 'ģ'] +['ï¤', 'ı'] +['ï¦', 'ī'] +['ï¦', 'ĵ'] +['ï§', 'ī'] +['ï²', 'Ŀ'] +['ðĿĹ', 'ŀ'] +['ðĿĹ', '±'] +['ðŁĮ', 'ĭ'] +['ðŁį', '¶'] +['à¦', 'ļ'] +['ìķ', 'ľ'] +['ðĿIJ', '¯'] +['ðĿļ', 'Ŀ'] +['à°', '¨'] +['à½', 'ĺ'] +['à½', 'ł'] +['á¡', '¥'] +['á¾', '°'] +['âģ', 'į'] +['âĶ', '°'] +['â¬', 'ľ'] +['ðĿIJ', 'ł'] +['ðĿij', '¯'] +['ðĿĹ', 'Ľ'] +['ðĿĵ', '»'] +['ðĿĸ', 'Ī'] +['âŀ', '»'] +['áŀ', 'ł'] +['â¡', '±'] +['â»', 'ij'] +['ð٧', 'µ'] +['ï¦', '¢'] +['ðŁij', 'ĺ'] +['ãĤ', 'Ķ'] +['â¼', 'Ł'] +['ãĬ', '¤'] +['ï¦', 'Ŀ'] +['ãĮ', '¦'] +['âĢ', '¸'] +['ðŁĶ', 'Ļ'] +['ã', '¹'] +['ã¹', '¦'] +['ï¹', 'ħ'] +['ï©', 'Į'] +['ãī', '¨'] +['ï¸', '½'] +['âį', '¥'] +['ðŁļ', 'ī'] +['ðŁ¥', 'ľ'] +['âĵ', 'ľ'] +['â»', 'Ŀ'] +['ï¨', 'ľ'] +['ðŁĴ', 'Ĵ'] +['áĦ', 'ij'] +['â¾', 'ŀ'] +['ï¨', 'ģ'] +['à´', 'ª'] +['áĦ', 'İ'] +['âŀ', '´'] +['à¦', '·'] +['áħ', '¬'] +['áŀ', '§'] +['âĨ', '¢'] +['âķ', '¦'] +['âľ', 'ij'] +['Ë', '¬'] +['Õ', 'IJ'] +['à¼', 'Ķ'] +['Ê', '¤'] +['Ë', '¨'] +['à¤', 'ŀ'] +['à»', 'ĥ'] +['à¼', 'ļ'] +['âĵ', '¥'] +['âķ', 'ľ'] +['ðŁIJ', 'ĸ'] +['á¼', 'Ļ'] +['á¼', '¤'] +['ìĨ', '°'] +['È', 'Ĥ'] +['Ê', '±'] +['à®', 'ļ'] +['áĥ', '§'] +['á´', 'ĭ'] +['á´', '®'] +['âĿ', '¡'] +['âŀ', '·'] +['ëĿ', '¡'] +['ï§', '¢'] +['ï¯', '¡'] +['ðĿķ', 'ķ'] +['ðŁħ', '°'] +['ð٦', '¸'] +['Ç', '¸'] +['Ó', 'ŀ'] +['Ô', '¶'] +['Ö', 'Ĩ'] +['Ú', 'ģ'] +['Û', 'ĭ'] +['áİ', '¥'] +['á¾', '¿'] +['âĶ', 'Ń'] +['âĶ', '®'] +['êĢ', 'Ģ'] +['ê±', 'ĺ'] +['ëIJ', 'Ń'] +['ë½', 'Ħ'] +['ìĶ', 'IJ'] +['ì¸', 'Į'] +['íģ', 'ł'] +['íĻ', '±'] +['ï¥', 'ī'] +['ï¨', 'ĸ'] +['ðĿij', '´'] +['ðĿĸ', 'Ĵ'] +['ðĿĺ', '¨'] +['ðĿ', 'ļĮ'] +['ðŁIJ', '¡'] +['ðŁij', '¢'] +['ðŁĵ', 'Ķ'] +['Å', 'ħ'] +['Æ', 'İ'] +['È', '©'] +['Ò', 'ª'] +['Ô', 'ĥ'] +['áĥ', '«'] +['á¸', 'ĩ'] +['âĽ', 'Ł'] +['ê»', 'Ń'] +['ë¨', 'Ħ'] +['ìŁ', 'Ģ'] +['ì¤', '´'] +['íļ', 'IJ'] +['ï¤', '³'] +['ðŁŁ', '¢'] +['Æ', '§'] +['È', '¼'] +['Ê', 'Ŀ'] +['Ë', 'Ħ'] +['Ë', 'ħ'] +['Ë', 'į'] +['Ë', '§'] +['Ò', '¥'] +['Õ', 'Ķ'] +['Ø', 'ı'] +['Ø', '¼'] +['ß', 'IJ'] +['ß', 'ľ'] +['à¤', 'ĵ'] +['à¦', 'Ļ'] +['à®', 'ĵ'] +['à¶', '´'] +['à¼', 'į'] +['à¼', 'Ĵ'] +['à½', '£'] +['áĢ', 'Ĥ'] +['áĢ', 'Ĭ'] +['áĦ', 'Ħ'] +['á', 'Īĺ'] +['áĭ', 'Ĭ'] +['áĮ', 'į'] +['áij', 'ĭ'] +['áŀ', 'Ĥ'] +['áł', '¢'] +['á¡', 'Ŀ'] +['á´', '¦'] +['áµ', 'į'] +['áµ', '¨'] +['á¸', '¡'] +['á¸', '¯'] +['á¼', '£'] +['âģ', 'Ĥ'] +['âĦ', 'ĺ'] +['âĦ', 'ľ'] +['âĦ', '³'] +['âĦ', 'µ'] +['âĨ', '¦'] +['âĩ', 'Ĩ'] +['âĪ', '·'] +['âĬ', 'ļ'] +['âĮ', '«'] +['âĮ', '¯'] +['âİ', 'Ľ'] +['âİ', 'ľ'] +['âİ', '¤'] +['âİ', '¦'] +['âİ', '®'] +['âij', 'ī'] +['âĶ', 'ī'] +['âķ', 'Ļ'] +['âĸ', 'Ĥ'] +['âĹ', 'Ń'] +['âĺ', 'Ĭ'] +['âĺ', 'į'] +['âĺ', 'Ĵ'] +['âļ', 'Ĩ'] +['âĽ', '§'] +['âĽ', '²'] +['âŀ', 'ĺ'] +['â¥', 'Ħ'] +['â´', '³'] +['â´', '½'] +['âµ', 'Ī'] +['ãī', '¯'] +['ãİ', 'ij'] +['ã§', '¬'] +['êĻ', '¬'] +['ê§', 'ģ'] +['ê³', '¬'] +['ê´', 'ŀ'] +['ê»', 'ľ'] +['ëħ', 'ĵ'] +['ëĭ', '¼'] +['ëį', 'ĸ'] +['ëĸ', '±'] +['ëĿ', '°'] +['ë¡', '¹'] +['ë¢', '´'] +['ë£', 'Ģ'] +['ë¤', 'ł'] +['ë¨', 'ķ'] +['ëŃ', '¥'] +['ìĦ', '¶'] +['ìħ', '¤'] +['ìĮ', 'ķ'] +['ìį', 'ª'] +['ìı', '©'] +['ìĴ', 'Ģ'] +['ìĶ', '¯'] +['ìĿ', 'Ķ'] +['ìĿ', 'ľ'] +['ìł', 'Ń'] +['ì§', '¦'] +['ì¨', '©'] +['ì²', '¬'] +['ì³', '¥'] +['ì¼', '¯'] +['íĢ', '«'] +['íĢ', 'Ń'] +['íĥ', '¸'] +['íĵ', 'ģ'] +['íķ', '¬'] +['íĹ', '¸'] +['íĽ', 'ķ'] +['íľ', 'Ń'] +['íĿ', 'Ĺ'] +['ï¤', 'Į'] +['ï¤', 'ª'] +['ï§', '¿'] +['ï¬', 'Ħ'] +['ï¬', 'ħ'] +['ïŃ', 'ij'] +['ïŃ', '«'] +['ïŃ', 'º'] +['ï®', 'Ĥ'] +['ï®', '¢'] +['ï®', '¨'] +['ï°', 'İ'] +['ï°', 'ł'] +['ï²', '£'] +['ï³', 'IJ'] +['ï³', 'Ĵ'] +['ï³', 'ĺ'] +['ï³', 'ľ'] +['ï¹', '¼'] +['ï¿', '¨'] +['ðĿIJ', '©'] +['ðĿĴ', 'ļ'] +['ðĿķ', 'Ķ'] +['ðĿķ', '¤'] +['ðĿĸ', 'Į'] +['ðĿĹ', '£'] +['ðĿĹ', '°'] +['ðĿĹ', '´'] +['ðĿĺ', 'Ĥ'] +['ðĿĺ', '¥'] +['ðĿĺ', '®'] +['ðĿĺ', '¸'] +['ðĿĻ', 'Ģ'] +['ðĿĽ', '¾'] +['ðĿľ', 'ı'] +['ðŁĮ', 'ģ'] +['ðŁĮ', 'ľ'] +['ðŁĮ', '¥'] +['ðŁĮ', '¯'] +['ðŁį', 'IJ'] +['ðŁİ', 'Ĵ'] +['ðŁı', 'Ķ'] +['ðŁı', 'ķ'] +['ðŁı', '®'] +['ðŁIJ', 'Ĥ'] +['ðŁIJ', 'ī'] +['ðŁIJ', '¹'] +['ðŁĶ', 'ķ'] +['ðŁĶ', 'ļ'] +['ðŁķ', 'ij'] +['ðŁķ', '£'] +['ðŁĹ', 'ŀ'] +['ðŁĹ', '¡'] +['ðŁĹ', '¿'] +['ðŁļ', 'Ĩ'] +['ðŁļ', 'Ĭ'] +['ðŁļ', 'ĵ'] +['ðŁļ', 'ķ'] +['ðŁļ', '¾'] +['ðŁĽ', 'ģ'] +['ðŁĽ', 'İ'] +['ðŁĽ', 'ı'] +['ð٤', '´'] +['ðŁ¥', 'ķ'] +['ðŁ¥', 'ĸ'] +['ðŁ¥', 'ł'] +['ðŁ¥', '¥'] +['ð٦', 'Ĩ'] +['ð٦', 'ī'] +['ð٦', 'ļ'] +['ð٧', 'ij'] +['ð٧', '¥'] +['ð٧', '¿'] +['Å', '°'] +['Æ', 'º'] +['É', '§'] +['àª', 'ĩ'] +['à®', '£'] +['áĪ', 'Ī'] +['áĬ', '¤'] +['áĭ', '®'] +['áĮ', 'Ī'] +['áĮ', 'µ'] +['á¥', '²'] +['âĵ', 'Ł'] +['êĻ', '³'] +['ê°', 'Ĭ'] +['ëķ', 'ģ'] +['ëķ', '¨'] +['ìĬ', 'ģ'] +['ï¦', 'µ'] +['ï¬', '²'] +['ðĿĸ', 'į'] +['ðĿĺ', 'Į'] +['ðĿĺ', '³'] +['ðĿĻ', '©'] +['ðŁį', 'Ļ'] +['ðŁĸ', 'ĸ'] +['áī', '³'] +['áĭ', '¨'] +['áĸ', 'ĩ'] +['áŀ', 'Į'] +['á¹', '§'] +['âķ', 'ª'] +['âŀ', 'ļ'] +['â²', 'ĺ'] +['ê', 'ķ'] +['êķ', '¥'] +['ï¤', '·'] +['ï®', '£'] +['ï¯', 'ł'] +['ðĿĴ', 'ĸ'] +['ðĿķ', 'ĺ'] +['ðĿĸ', 'ĩ'] +['ðĿĹ', 'Ł'] +['ðĿĹ', 'ª'] +['ðĿĹ', '¯'] +['ðĿĻ', 'ł'] +['ðŁĵ', 'ı'] +['à¦', 'Ĺ'] +['âĴ', '»'] +['â²', 'ł'] +['ðĿĵ', 'µ'] +['Ê', '£'] +['à°', 'ľ'] +['áĬ', '¢'] +['áŀ', 'IJ'] +['á¸', '·'] +['âĦ', 'Ľ'] +['âĩ', 'Ģ'] +['âĩ', 'Ĭ'] +['êĴ', '¦'] +['ê¦', 'ł'] +['ï®', '¤'] +['ðŁį', 'Ľ'] +['ð٤', 'Ľ'] +['á¨', '¾'] +['âŀ', 'º'] +['áķ', '¯'] +['áĽ', 'ı'] +['âĩ', 'Ĥ'] +['âĶ', '¹'] +['âĻ', 'Ĺ'] +['ðŁĸ', '¨'] +['ê¦', 'ı'] +['àª', '°'] +['áļ', '¨'] +['ð٤', '¥'] +['ð٧', '¢'] +['ãIJ', 'Ĥ'] +['ãĦ', '¥'] +['ðŁĸ', 'Į'] +['â¼', 'Ĵ'] +['ãĬ', '§'] +['âį', '©'] +['ð٦', 'ij'] +['âĶ', '·'] +['ï©', 'IJ'] +['ï©', '¡'] +['ðĵ', 'Ī'] +['ðĵĪ', 'Ĵ'] +['â»', 'Ħ'] +['ï¨', 'Ĵ'] +['âĦ', 'ª'] +['Ò', '§'] +['Ú', 'Į'] +['âĢ', '¶'] +['âº', 'ł'] +['â»', 'ģ'] +['âĨ', '¸'] +['áĦ', 'IJ'] +['ãħ', 'IJ'] +['à»', 'Ħ'] +['áĹ', 'ª'] +['âĨ', '¼'] +['âĩ', 'ĭ'] +['âĩ', 'ĺ'] +['âĮ', 'ij'] +['âĸ', '©'] +['ðĿIJ', 'Ĺ'] +['Ä', 'Ĭ'] +['à¦', 'ī'] +['ìī', 'ł'] +['É', '¤'] +['ß', 'į'] +['ß', 'ı'] +['áµ', 'Ĺ'] +['âĤ', '¥'] +['âĵ', 'ī'] +['âĶ', 'ł'] +['âĶ', '¨'] +['âķ', 'Ħ'] +['ä', '¤'] +['ä¤', 'Ģ'] +['ê»', '¸'] +['ï®', 'ģ'] +['ðĵ', 'Ĥ'] +['ðĵĤ', 'ĥ'] +['ð٦', 'ķ'] +['Æ', 'Ľ'] +['à¦', 'ĩ'] +['ãı', 'ĺ'] +['ï®', '¼'] +['Ú', 'ĵ'] +['Ú', 'Ŀ'] +['à¦', 'ĵ'] +['à¶', '¯'] +['á´', 'ħ'] +['á½', 'Ļ'] +['âģ', '¼'] +['âĸ', 'İ'] +['â¼', '©'] +['ä', 'Ķ'] +['äĶ', 'Ģ'] +['ë»', '¡'] +['ìĽ', '½'] +['íģ', 'Ħ'] +['ï¥', '¼'] +['ï±', 'ī'] +['ï¹', '»'] +['ðĿĸ', 'ĭ'] +['ðĿĻ', 'Ī'] +['ðĿĻ', 'ª'] +['ðĿ', '϶'] +['ðŁIJ', 'Ħ'] +['ðŁIJ', 'Ĩ'] +['áİ', '¢'] +['á¸', 'Į'] +['âĿ', '´'] +['ðŁı', '¸'] +['È', 'Ŀ'] +['É', '¸'] +['Î', 'ħ'] +['Ï', 'ľ'] +['Ó', '¢'] +['Õ', '¹'] +['à´', 'ħ'] +['àº', 'Ī'] +['áĭ', '°'] +['áij', 'İ'] +['áł', 'µ'] +['á¡', 'ł'] +['á´', 'ī'] +['á¸', 'µ'] +['á¿', '´'] +['âĵ', '£'] +['âĶ', '¶'] +['â½', '¯'] +['ê²', '¥'] +['ê¿', 'ĺ'] +['ëģ', 'İ'] +['ëİ', 'Ī'] +['ëĶ', '¯'] +['ë²', '°'] +['ìĺ', '¯'] +['ìĽ', '¸'] +['ìŀ', 'Ĺ'] +['ì§', 'ĺ'] +['ì¬', '¬'] +['ì·', '¬'] +['íģ', 'ħ'] +['íĵ', 'Ķ'] +['íĽ', 'Ŀ'] +['ï¤', '®'] +['ï¤', '¹'] +['ï¥', '²'] +['ï¯', 'ĸ'] +['ðĿĵ', 'ħ'] +['ðĿĻ', 'Ħ'] +['ðŁĵ', '¶'] +['ðŁĹ', 'Ĵ'] +['ðŁ¥', 'Ķ'] +['ðŁ¥', 'Ń'] +['Å', '®'] +['Å', '´'] +['Æ', 'ī'] +['Æ', '«'] +['Ç', 'ģ'] +['Ç', '£'] +['Ç', 'º'] +['Ç', '¼'] +['È', 'į'] +['È', '¯'] +['É', 'ľ'] +['Ê', '¬'] +['Ë', 'ģ'] +['Ë', '¤'] +['Ë', 'µ'] +['Ï', 'Ľ'] +['Ò', '¤'] +['Ò', '¬'] +['Ó', 'ı'] +['Ó', 'Ľ'] +['Ó', '¡'] +['Ó', '³'] +['Ô', 'Į'] +['Ô', '¬'] +['Õ', '³'] +['Ù', '»'] +['Ú', 'ī'] +['Ú', '§'] +['Ü', 'ľ'] +['ß', 'ª'] +['à¤', 'Ŀ'] +['à¦', 'Ľ'] +['à¨', 'Ĩ'] +['àª', 'ķ'] +['àª', '¡'] +['à®', 'İ'] +['à°', '¬'] +['àµ', '»'] +['àµ', '¼'] +['à¶', 'ł'] +['à¶', 'Ń'] +['à¶', '¶'] +['à·', 'Ĩ'] +['à¼', '½'] +['áĢ', 'ļ'] +['áħ', '¢'] +['áĨ', '¸'] +['áĪ', 'Ģ'] +['áĪ', 'ķ'] +['áĪ', '°'] +['áī', '¡'] +['áī', '¤'] +['áĬ', '¦'] +['áĬ', '«'] +['áĭ', 'ĭ'] +['áĭ', 'į'] +['áİ', '¯'] +['áij', 'Ń'] +['áķ', 'Ĺ'] +['áŁ', 'Ľ'] +['á¥', 'Ĵ'] +['á©', 'ī'] +['áŃ', 'º'] +['á´', '¡'] +['áµ', 'ĺ'] +['áµ', 'Ľ'] +['á¶', 'ł'] +['á¸', 'ģ'] +['á¸', 'ĭ'] +['á¹', 'Ļ'] +['á¹', 'Ŀ'] +['á¹', '¦'] +['áº', 'ħ'] +['á¼', 'Ĥ'] +['á½', 'ĥ'] +['á½', 'į'] +['á½', '§'] +['á¾', '·'] +['âĢ', 'µ'] +['âĤ', 'İ'] +['âĦ', 'Ŀ'] +['âħ', 'Ģ'] +['âĨ', 'ŀ'] +['âĨ', '§'] +['âĩ', 'ħ'] +['âĪ', 'ĥ'] +['âī', 'ı'] +['âī', '½'] +['âĬ', 'ŀ'] +['âĬ', '¡'] +['âĬ', '§'] +['â', 'Ĭ¶'] +['âĭ', 'Ħ'] +['âİ', 'Ĵ'] +['âİ', '¡'] +['âİ', '£'] +['âİ', 'ª'] +['âı', 'İ'] +['âĵ', 'ĥ'] +['âĵ', 'ĸ'] +['âĵ', '¨'] +['âķ', 'ĭ'] +['âķ', 'ĸ'] +['âķ', '¢'] +['âķ', '²'] +['âĸ', 'Ĩ'] +['âĸ', 'Ĭ'] +['âĸ', 'į'] +['âĸ', '®'] +['âĺ', '¡'] +['âĺ', '¦'] +['âĺ', '±'] +['âĺ', '¿'] +['âĻ', 'ĺ'] +['âĻ', 'Ŀ'] +['âļ', '°'] +['âĽ', 'ij'] +['âŀ', 'ª'] +['â¤', 'Ŀ'] +['â¤', '¢'] +['â¤', '·'] +['â§', '«'] +['â¨', 'Ń'] +['â¨', '¯'] +['â±', '£'] +['â²', 'İ'] +['âµ', 'Ľ'] +['ãħ', 'Ķ'] +['ãĪ', 'ı'] +['ãī', '²'] +['ãī', '³'] +['ãĬ', 'ij'] +['ãĭ', 'Ľ'] +['ãİ', 'IJ'] +['ê²', '¤'] +['ê·', '¿'] +['ê¹', 'ŀ'] +['ê»', '¨'] +['ê¼', 'į'] +['ê¿', '¸'] +['ëĥ', '¬'] +['ëĩ', 'IJ'] +['ëĭ', 'ł'] +['ëį', '¯'] +['ëĹ', 'Į'] +['ëĹ', 'ij'] +['ë¥', 'Ģ'] +['ëª', 'ĥ'] +['ëª', '¯'] +['ë±', '¡'] +['ë³', 'ĵ'] +['ë³', '½'] +['ë', 'µľ'] +['ìĤ', '³'] +['ìħ', '¥'] +['ìĩ', '½'] +['ìı', '¨'] +['ìı', '¸'] +['ìķ', 'į'] +['ìĸ', 'ĸ'] +['ìŁ', '¨'] +['ì¢', 'ĥ'] +['ì¢', 'į'] +['ì¥', 'ij'] +['ì§', '¼'] +['ì©', 'ĥ'] +['ì®', 'ľ'] +['ì®', '¸'] +['ì³', 'ij'] +['ì´', '¥'] +['ì¾', 'ĥ'] +['íħ', '¦'] +['íĪ', '¿'] +['íĵ', '½'] +['íķ', '³'] +['íĸ', 'ı'] +['íĹ', 'ł'] +['íĿ', '«'] +['ï¤', 'ĵ'] +['ï¤', 'ĺ'] +['ï¥', 'İ'] +['ï¥', '¶'] +['ï¦', 'ħ'] +['ï¦', '½'] +['ï§', 'ĩ'] +['ï¬', 'Ĩ'] +['ï¬', '³'] +['ï®', 'ĩ'] +['ï®', 'Ī'] +['ï®', 'Ŀ'] +['ï®', '©'] +['ï®', '±'] +['ï¯', 'ĺ'] +['ï¯', 'Ļ'] +['ï¯', '¢'] +['ï¯', '£'] +['ï¯', '¤'] +['ï¯', '¥'] +['ï±', 'Ĥ'] +['ï²', 'Ĩ'] +['ï²', 'ª'] +['ï´', '¼'] +['ïº', 'ī'] +['ïº', 'Ĭ'] +['ïº', '¥'] +['ðĿij', '¨'] +['ðĿij', '©'] +['ðĿij', '²'] +['ðĿ', 'ĴĮ'] +['ðĿĴ', 'ª'] +['ðĿĴ', '®'] +['ðĿĵ', 'Ĥ'] +['ðĿĵ', 'Ī'] +['ðĿĵ', '¯'] +['ðĿĶ', '¨'] +['ðĿķ', 'Ģ'] +['ðĿķ', 'Ĩ'] +['ðĿķ', '¦'] +['ðĿķ', '§'] +['ðĿķ', '«'] +['ðĿķ', '·'] +['ðĿĹ', 'µ'] +['ðĿĹ', '¸'] +['ðĿĺ', 'Ħ'] +['ðĿĺ', 'Ļ'] +['ðĿĺ', 'ł'] +['ðĿĺ', '¬'] +['ðĿĻ', 'į'] +['ðĿĻ', 'ij'] +['ðĿĻ', '¡'] +['ðĿ', 'ύ'] +['ðĿĻ', '·'] +['ðĿļ', 'į'] +['ðĿĽ', '¿'] +['ðŁ', 'ĥ'] +['ðŁĥ', 'ı'] +['ðŁħ', 'ĺ'] +['ðŁ', 'ī'] +['ðŁī', 'ij'] +['ðŁİ', '¡'] +['ðŁİ', 'ª'] +['ðŁİ', '±'] +['ðŁİ', '³'] +['ðŁİ', 'º'] +['ðŁı', 'İ'] +['ðŁı', 'Ĺ'] +['ðŁı', 'ļ'] +['ðŁı', 'ŀ'] +['ðŁı', '¦'] +['ðŁı', '§'] +['ðŁIJ', 'ģ'] +['ðŁIJ', 'ħ'] +['ðŁIJ', 'ĵ'] +['ðŁĴ', 'Ĥ'] +['ðŁĵ', 'ij'] +['ðŁĵ', 'ĵ'] +['ðŁĵ', '¨'] +['ðŁĵ', '«'] +['ðŁĶ', 'ĭ'] +['ðŁĶ', 'Ń'] +['ðŁĶ', '¯'] +['ðŁķ', 'Ĺ'] +['ðŁļ', 'Ĥ'] +['ðŁļ', '¢'] +['ðŁļ', '¦'] +['ðŁļ', '¬'] +['ðŁĽ', 'ĭ'] +['ðŁĽ', 'Į'] +['ðŁĽ', '¬'] +['ðŁĽ', '¶'] +['ðŁŁ', '¡'] +['ðŁ¥', 'ĺ'] +['ðŁ¥', 'Ł'] +['ðŁ¥', '¦'] +['ð٦', 'ĩ'] +['ð٦', 'Ī'] +['ð٧', 'Ĭ'] +['ð٧', 'Ĺ'] +['ð٧', '¤'] +['Ê', '·'] +['Ë', '¹'] +['á¹', 'ļ'] +['á½', '¥'] +['âĦ', 'Ł'] +['ê²', '¯'] +['ê»', '«'] +['ë°', '·'] +['ìĥ', 'Ĩ'] +['ìĽ', 'Ŀ'] +['ì¨', 'ī'] +['ì«', 'ı'] +['ï¯', 'ķ'] +['ðĿľ', 'ĭ'] +['É', '²'] +['Ò', 'Ń'] +['Ó', 'Ī'] +['à½', 'Ľ'] +['áĭ', 'ĵ'] +['áĻ', 'Ń'] +['áł', '©'] +['á¹', '®'] +['âĦ', 'Ĵ'] +['âĨ', '»'] +['âµ', 'ĥ'] +['ëĢ', '¨'] +['ëł', '§'] +['ìī', '¥'] +['ìĮ', 'ľ'] +['ìĹ', '¶'] +['ì¨', 'Ī'] +['ìª', '¾'] +['íı', '½'] +['íļ', 'Ķ'] +['íĽ', 'µ'] +['ï¤', '¸'] +['ï¦', 'IJ'] +['ï§', 'Ĺ'] +['ï§', 'ļ'] +['ï¬', '¯'] +['ðĿIJ', 'Ĭ'] +['ðĿķ', 'Ĺ'] +['ðĿĹ', 'ļ'] +['ðĿļ', 'ĸ'] +['ðŁħ', '´'] +['È', 'ĥ'] +['É', 'Ŀ'] +['Ï', '±'] +['Ó', 'Ĺ'] +['à¤', '¢'] +['áħ', 'ł'] +['áī', '¦'] +['áij', 'Į'] +['áĴ', '¼'] +['áŀ', '¡'] +['áł', '¨'] +['áł', 'Ń'] +['á¨', 'ħ'] +['á¨', 'Ķ'] +['á´', 'ĺ'] +['á¶', '¦'] +['á¸', 'İ'] +['á¼', 'ħ'] +['á¼', '¹'] +['âĨ', '¯'] +['âĵ', 'İ'] +['ãı', 'Į'] +['ê', 'ī'] +['êī', 'Ĥ'] +['ëĨ', '§'] +['ëĿ', '±'] +['ì¢', '¡'] +['íĪ', '½'] +['ï¤', 'ĩ'] +['ï¤', 'Ľ'] +['ðĿIJ', 'ķ'] +['ðĿĵ', '¸'] +['ðĿĵ', '¼'] +['ðĿĹ', 'ķ'] +['ðĿĺ', 'Ī'] +['ðŁı', '£'] +['ðŁı', '¤'] +['ðŁĹ', 'Ħ'] +['Ñ', '·'] +['Ò', 'ł'] +['áµ', 'ĸ'] +['á¼', '¨'] +['ë¬', 'Ħ'] +['ï°', '´'] +['âĪ', '½'] +['Õ', 'Ń'] +['Ú', '¹'] +['à¥', 'Ł'] +['áĢ', 'Ĩ'] +['áŀ', 'Ĵ'] +['ãĢ', '¶'] +['ê¦', '«'] +['ï¸', 'ĵ'] +['ðĿIJ', 'Ľ'] +['ðĿĺ', 'Ĺ'] +['ðŁı', 'ľ'] +['ì«', 'Ń'] +['ð٧', 'ŀ'] +['à½', 'Ĥ'] +['âĨ', '¿'] +['âĩ', 'ı'] +['âĵ', 'ģ'] +['âĶ', '§'] +['âķ', 'ģ'] +['âķ', '¤'] +['ê¦', 'Ĺ'] +['ê¦', '¤'] +['ðŁı', 'Ī'] +['áŀ', 'ķ'] +['Ô', '½'] +['àª', 'Ĺ'] +['à¬', 'Ĩ'] +['âķ', 'ķ'] +['ï½', 'ł'] +['â¼', '¦'] +['â¼', '¯'] +['â¾', '·'] +['âĶ', 'ĸ'] +['à¬', 'ĵ'] +['âĺ', 'Ĺ'] +['âį', 'ĭ'] +['ï¨', 'Ŀ'] +['â¼', '¥'] +['ï¦', 'ª'] +['âĦ', 'Ĭ'] +['ãĢ', '´'] +['âį', '¢'] +['ð¡', 'Ī'] +['ð¡Ī', '½'] +['ï©', '¨'] +['ãĢ', '»'] +['ãı', 'ĥ'] +['ï¦', '¡'] +['ï¨', 'ĺ'] +['ðŁIJ', 'ĥ'] +['ðŁĨ', 'ĸ'] +['ðŁĹ', '¾'] +['ãĦ', 'ĩ'] +['Þ', 'ĭ'] +['â¼', '¼'] +['ï¨', 'Ń'] +['Þ', 'Ģ'] +['Þ', 'Ħ'] +['Þ', 'Ī'] +['Þ', 'IJ'] +['âĮ', 'Ħ'] +['â»', 'ĺ'] +['ãŁ', '¢'] +['á', 'ħ§'] +['ðIJĮ', '¿'] +['Ë', '»'] +['à²', 'Ĺ'] +['áĢ', 'ĩ'] +['áŀ', 'Ĭ'] +['âķ', 'ĩ'] +['ãĩ', '¼'] +['ãİ', '°'] +['Õ', 'Ĵ'] +['Ü', 'Ī'] +['ß', '¥'] +['à¿', 'IJ'] +['áĢ', 'Ł'] +['âĨ', '¥'] +['âķ', 'Į'] +['â½', 'Ģ'] +['â½', '°'] +['â¾', 'Ĭ'] +['ä', 'Ħ'] +['äĦ', 'Ģ'] +['ðĵ', 'IJ'] +['ðĵIJ', 'į'] +['ðŁİ', '¦'] +['âĤ', '¯'] +['âĬ', 'ĺ'] +['âĦ', 'į'] +['Ê', 'µ'] +['Ñ', '¶'] +['Ú', 'ĥ'] +['à¦', 'Ķ'] +['à´', '¦'] +['áİ', '¶'] +['áĵ', 'ķ'] +['á¹', '¨'] +['âĤ', 'ł'] +['âĩ', '°'] +['âĹ', 'Ĵ'] +['â¿', 'Ĭ'] +['ê·', '±'] +['ì¹', 'ķ'] +['íĪ', '©'] +['ïŃ', 'Ģ'] +['ðĿĴ', '¸'] +['ðĿĵ', 'Ĭ'] +['ðĿĺ', '©'] +['Ç', '¦'] +['É', '«'] +['áĬ', '¨'] +['È', '¹'] +['Ê', '¯'] +['Î', 'ª'] +['Ú', 'Ģ'] +['áĮ', '¸'] +['áİ', '»'] +['áı', 'ķ'] +['áı', '´'] +['á²', 'Ĥ'] +['á½', '¨'] +['âı', 'Ŀ'] +['âĺ', 'Ļ'] +['ëĥ', '¨'] +['ëĦ', '¼'] +['ëĪ', 'Ļ'] +['ë£', 'ħ'] +['ìĶ', '¼'] +['ìķ', 'Ŀ'] +['ìļ', '¬'] +['ìľ', '±'] +['ï¥', 'Ĥ'] +['ï¦', '¹'] +['ï¬', '¹'] +['ïŃ', 'ģ'] +['ï³', 'Ī'] +['ðĿĶ', 'ħ'] +['ðĿĺ', '¤'] +['ðĿĻ', 'ı'] +['ðĿĻ', 'Ļ'] +['ðŁķ', 'ī'] +['ð٧', 'Ļ'] +['á¸', 'ij'] +['ê´', '¼'] +['ëģ', 'į'] +['ëĹ', '´'] +['ëĿ', '³'] +['ë°', 'ŀ'] +['ë°', '¢'] +['ëµ', 'ĺ'] +['ìĤ', 'Ķ'] +['ìĦ', 'Ħ'] +['ì¼', 'ļ'] +['íĢ', 'ł'] +['íĬ', '±'] +['íĮ', 'ĸ'] +['ï¤', 'ij'] +['ï¦', '´'] +['ï¦', '¸'] +['ï´', 'į'] +['ðĿĺ', '·'] +['Ä', '¬'] +['Å', '¬'] +['Æ', 'Ģ'] +['Æ', 'ĭ'] +['Æ', 'ľ'] +['Ç', 'ij'] +['Ç', 'ĺ'] +['Ç', 'ŀ'] +['Ç', '¥'] +['Ç', '®'] +['É', '°'] +['É', '¶'] +['É', '·'] +['É', '½'] +['Ê', 'Ī'] +['Ê', 'IJ'] +['Ë', 'İ'] +['Ë', 'Ł'] +['Ë', '¦'] +['Ë', '¯'] +['Ï', 'IJ'] +['Ï', 'ĵ'] +['Ï', '¢'] +['Ï', '¤'] +['Ï', 'ª'] +['Ï', 'Ń'] +['Ï', '®'] +['Ï', '»'] +['Ñ', 'ł'] +['Ñ', 'Ń'] +['Ò', '¨'] +['Ó', 'Ŀ'] +['Ô', '¡'] +['Ô', '·'] +['Õ', 'ī'] +['Õ', 'ĵ'] +['Õ', 'ĸ'] +['Õ', 'ļ'] +['Õ', 'Ŀ'] +['Ö', 'İ'] +['Ø', '¿'] +['Ú', 'ħ'] +['Ú', 'į'] +['Ú', 'Ķ'] +['Û', 'Ĭ'] +['Û', '¾'] +['Ü', 'Ļ'] +['Ý', 'Ĵ'] +['Ý', 'ĺ'] +['ß', 'Ĵ'] +['ß', 'ĸ'] +['à¤', 'Ĭ'] +['à¤', 'IJ'] +['à¦', 'ı'] +['à¦', 'ĸ'] +['à§', 'Ł'] +['àª', '®'] +['àª', '¹'] +['à®', 'ħ'] +['à®', 'Ĩ'] +['à°', '¡'] +['à°', '°'] +['à²', 'ļ'] +['à²', '®'] +['à²', '¯'] +['à´', 'Ł'] +['à´', '·'] +['àµ', '¾'] +['à¶', 'ij'] +['à¶', 'ŀ'] +['à¼', '¼'] +['à½', 'ĵ'] +['áĢ', 'ĵ'] +['áĤ', '¦'] +['áĥ', 'ĸ'] +['áĥ', 'Ń'] +['áĥ', '¯'] +['áħ', '¨'] +['áħ', 'ª'] +['áĨ', '°'] +['áĪ', 'ģ'] +['áĪ', 'İ'] +['áĪ', 'ĵ'] +['áĪ', '¥'] +['áĪ', '²'] +['áĪ', '´'] +['áĪ', '»'] +['áī', 'ł'] +['áī', '²'] +['áī', '¶'] +['áĬ', '£'] +['áĬ', '¥'] +['áĬ', 'ª'] +['áĭ', 'ĺ'] +['áĭ', '²'] +['áĭ', '¶'] +['áĮ', '£'] +['áį', '¡'] +['áį', '£'] +['áİ', '¬'] +['áİ', '¾'] +['áIJ', '¡'] +['áķ', 'ķ'] +['áĸ', '±'] +['áĹ', 'IJ'] +['áĹ', 'Ń'] +['áĺ', 'ī'] +['áļ', '±'] +['áĽ', 'Ł'] +['áŀ', '¥'] +['áŁ', 'Ķ'] +['áł', '£'] +['áł', 'ª'] +['áł', '°'] +['áł', '´'] +['á¤', 'ĸ'] +['á¥', '£'] +['á', '®'] +['á®', 'ł'] +['á', '¯'] +['á¯', 'Ļ'] +['á', '°'] +['á°', 'į'] +['á´', 'Ĭ'] +['á´', '¾'] +['áµ', 'ģ'] +['áµ', 'İ'] +['áµ', 'ŀ'] +['áµ', '¤'] +['á¶', 'ħ'] +['á¶', 'ĺ'] +['á¶', 'Ł'] +['á¶', '¢'] +['á¶', '¤'] +['á¶', '±'] +['á¶', '»'] +['á¸', 'ī'] +['á¸', 'ŀ'] +['á¸', 'º'] +['á¹', 'ĵ'] +['á¹', 'Ĺ'] +['á¹', 'ª'] +['áº', 'Ĭ'] +['áº', 'ı'] +['áº', 'Ľ'] +['á¼', 'ĥ'] +['á¼', 'Į'] +['á¼', '¿'] +['á½', 'Ĥ'] +['á½', 'ĵ'] +['á½', 'Ĺ'] +['á½', '¦'] +['á¾', '±'] +['á¾', '´'] +['á¿', 'ĺ'] +['á¿', 'Ł'] +['á¿', '¸'] +['âģ', 'ĺ'] +['âĤ', 'ij'] +['âĤ', 'Ľ'] +['âĤ', '¿'] +['âĦ', 'ĩ'] +['âĦ', 'ŀ'] +['âĦ', '±'] +['âĩ', 'Ł'] +['âĩ', '²'] +['âĪ', '¤'] +['âĪ', '¶'] +['âī', 'Ĥ'] +['âī', '¾'] +['âĬ', '¨'] +['âĬ', '³'] +['âĬ', '·'] +['âĭ', 'Į'] +['âĭ', 'ĺ'] +['âĮ', 'ķ'] +['âĮ', '¥'] +['âĮ', 'µ'] +['âĮ', 'º'] +['âį', '£'] +['âį', '²'] +['âį', 'µ'] +['âİ', 'ĩ'] +['âı', 'ĥ'] +['âı', 'IJ'] +['âı', 'ł'] +['âı', '¤'] +['âı', '¶'] +['âı', '¸'] +['âı', '¹'] +['âij', 'Ĥ'] +['âĴ', '·'] +['âĴ', 'º'] +['âĵ', '¡'] +['âĵ', '¤'] +['âĶ', '¾'] +['âĸ', 'ĺ'] +['âĸ', 'µ'] +['âĹ', 'ª'] +['âĹ', '·'] +['âĺ', '¨'] +['âĺ', '«'] +['âĺ', '²'] +['âĺ', '³'] +['âĻ', 'Ĩ'] +['âļ', '¤'] +['âļ', '¥'] +['âĽ', 'ĵ'] +['âĽ', '´'] +['âĽ', '¾'] +['âŀ', '«'] +['âŀ', '¿'] +['âŁ', '·'] +['â¤', 'ij'] +['â¤', '«'] +['â¤', '¶'] +['â¤', '½'] +['â§', 'ª'] +['â¨', 'Ģ'] +['â', '©½'] +['â¬', '¡'] +['â¬', '¢'] +['â¬', '¤'] +['â²', 'ĸ'] +['â²', 'ª'] +['âµ', 'Ģ'] +['â¸', '®'] +['â¸', '½'] +['ãĢ', 'ł'] +['ãĢ', '·'] +['ãĦ', 'Į'] +['ãĦ', 'ĺ'] +['ãħ', 'ij'] +['ãĪ', 'İ'] +['ãĪ', 'IJ'] +['ãĬ', 'ľ'] +['ãĮ', 'ĵ'] +['ãĮ', 'ł'] +['ãİ', 'Ł'] +['ãİ', '¤'] +['ãİ', '§'] +['ã¬', '®'] +['ä', 'Ī'] +['äĪ', 'Ģ'] +['ä', '°'] +['ä°', 'Ģ'] +['ê', 'ħ'] +['êħ', 'ī'] +['êĩ', 'Ĺ'] +['ê', 'Ī'] +['êĪ', 'į'] +['ê§', 'Ĥ'] +['ê§', 'Ĭ'] +['êª', 'Ģ'] +['ê²', 'Ī'] +['ê²', 'į'] +['ê³', 'Ģ'] +['êµ', 'ł'] +['ê½', 'IJ'] +['ê¾', 'Ī'] +['ê¿', '±'] +['ëĥ', 'ı'] +['ëĦ', 'ij'] +['ëħ', '¤'] +['ëĩ', '¸'] +['ëĪ', '¼'] +['ëī', 'ħ'] +['ëĬ', '£'] +['ëĭ', 'º'] +['ëį', 'ŀ'] +['ëIJ', 'Į'] +['ëķ', '¸'] +['ëĺ', 'ł'] +['ëĻ', 'ĩ'] +['ëĻ', 'Ī'] +['ëľ', '½'] +['ëŀ', 'Ķ'] +['ëł', 'ľ'] +['ë£', 'IJ'] +['ë§', 'Ģ'] +['ë§', 'Ĭ'] +['ëª', 'Ģ'] +['ë¬', 'Ń'] +['ë¯', '¾'] +['ë³', 'ľ'] +['ë´', 'Ĭ'] +['ëµ', 'ī'] +['ë·', 'ľ'] +['ë¸', 'Ģ'] +['ë¹', 'ĭ'] +['ìģ', 'Ħ'] +['ìĤ', '£'] +['ìĤ', '»'] +['ìĦ', 'µ'] +['ìħ', 'Ĵ'] +['ìī', 'Ī'] +['ìī', 'Ķ'] +['ìĬ', 'Į'] +['ìĬ', 'Ļ'] +['ìIJ', '´'] +['ìĵ', 'º'] +['ìķ', 'ļ'] +['ìķ', 'º'] +['ìĸ', 'ľ'] +['ìĹ', 'ª'] +['ìĺ', 'ľ'] +['ìĻ', '¤'] +['ìļ', 'Ľ'] +['ìļ', 'º'] +['ìĿ', 'ħ'] +['ìĿ', 'ı'] +['ìĿ', 'Ń'] +['ìĿ', '¶'] +['ìł', 'Ľ'] +['ì¡', 'Ī'] +['ì¢', 'ī'] +['ì¢', 'Ķ'] +['ì©', 'ł'] +['ìŃ', 'Į'] +['ì¯', '©'] +['ì´', '£'] +['ì¸', 'ķ'] +['ì¹', 'Ł'] +['ì¾', '¡'] +['ì¿', 'Ļ'] +['íģ', 'ĩ'] +['íģ', 'ī'] +['íĩ', 'Ģ'] +['íĪ', '¶'] +['íĸ', 'ij'] +['íĸ', '¤'] +['íĹ', 'ħ'] +['íľ', 'ı'] +['íĿ', 'Ŀ'] +['ï¤', 'Ĵ'] +['ï¤', 'ķ'] +['ï¤', '¬'] +['ï¥', 'ħ'] +['ï¥', 'ĩ'] +['ï¥', 'ı'] +['ï¥', 'ļ'] +['ï¥', 'Ł'] +['ï¦', 'Ħ'] +['ï¦', 'Ī'] +['ï¦', '¨'] +['ï¦', '©'] +['ï¦', '²'] +['ï§', 'ģ'] +['ï§', 'ĥ'] +['ï§', 'Ķ'] +['ï§', 'ł'] +['ï§', '£'] +['ï§', '®'] +['ï', 'ŃIJ'] +['ïŃ', 'ĸ'] +['ïŃ', '¦'] +['ïŃ', '´'] +['ïŃ', 'µ'] +['ïŃ', '¶'] +['ïŃ', '¸'] +['ï®', 'Į'] +['ï®', 'İ'] +['ï®', 'ŀ'] +['ï®', 'Ł'] +['ï®', '¡'] +['ï®', 'ª'] +['ï¯', 'Ķ'] +['ï¯', 'Ĺ'] +['ï¯', 'ļ'] +['ï¯', 'Ľ'] +['ï¯', 'Ŀ'] +['ï¯', 'Ł'] +['ï¯', '§'] +['ï¯', '¨'] +['ï¯', '«'] +['ï¯', '¯'] +['ï¯', '°'] +['ï¯', '±'] +['ï¯', '²'] +['ï¯', '³'] +['ï¯', '´'] +['ï¯', 'µ'] +['ï¯', '¶'] +['ï°', 'Ģ'] +['ï±', 'ħ'] +['ï±', 'Ķ'] +['ï±', '´'] +['ï²', 'ģ'] +['ï³', 'ķ'] +['ï·', '½'] +['ï¸', 'ķ'] +['ï¸', '±'] +['ï¹', '£'] +['ï¹', '½'] +['ï»', 'į'] +['ï¾', '±'] +['ðĿIJ', 'Ļ'] +['ðĿIJ', '½'] +['ðĿij', '¤'] +['ðĿij', '®'] +['ðĿij', 'µ'] +['ðĿĴ', 'ĥ'] +['ðĿĴ', 'Ħ'] +['ðĿĵ', 'Ń'] +['ðĿĵ', '·'] +['ðĿĶ', 'ĸ'] +['ðĿĶ', 'ŀ'] +['ðĿĶ', '¢'] +['ðĿĶ', '¦'] +['ðĿĶ', '¬'] +['ðĿķ', 'Ħ'] +['ðĿķ', 'Ĭ'] +['ðĿķ', 'İ'] +['ðĿķ', 'Ļ'] +['ðĿķ', 'ľ'] +['ðĿķ', 'Ń'] +['ðĿķ', '³'] +['ðĿķ', '¸'] +['ðĿķ', '¾'] +['ðĿ', 'ĸī'] +['ðĿĸ', 'ı'] +['ðĿĺ', 'ĩ'] +['ðĿĺ', 'ī'] +['ðĿĺ', 'ĸ'] +['ðĿĺ', 'Ľ'] +['ðĿĺ', 'ŀ'] +['ðĿĺ', '«'] +['ðĿĺ', '¾'] +['ðĿĻ', 'ĩ'] +['ðĿĻ', 'ī'] +['ðĿĻ', 'ĭ'] +['ðĿĻ', 'İ'] +['ðĿĻ', 'ĺ'] +['ðĿĻ', '¥'] +['ðĿļ', 'ĥ'] +['ðĿļ', 'IJ'] +['ðĿļ', 'Ķ'] +['ðĿľ', 'ĥ'] +['ðŁĦ', '·'] +['ðŁħ', 'Ŀ'] +['ðŁħ', '¾'] +['ðŁĨ', 'Ĥ'] +['ðŁĨ', 'ĵ'] +['ðŁĮ', 'Ĥ'] +['ðŁĮ', 'Ĩ'] +['ðŁĮ', 'ī'] +['ðŁĮ', 'ij'] +['ðŁĮ', 'ĺ'] +['ðŁĮ', '©'] +['ðŁĮ', '«'] +['ðŁį', '¢'] +['ðŁį', '¥'] +['ðŁİ', 'Ľ'] +['ðŁİ', '¢'] +['ðŁİ', '´'] +['ðŁij', '¡'] +['ðŁĴ', '¾'] +['ðŁĵ', 'Ń'] +['ðŁĶ', 'Ī'] +['ðŁĶ', '¦'] +['ðŁĶ', '²'] +['ðŁĶ', '³'] +['ðŁķ', 'ĵ'] +['ðŁķ', 'ķ'] +['ðŁķ', 'ĺ'] +['ðŁķ', 'Ł'] +['ðŁķ', '·'] +['ðŁĹ', '³'] +['ðŁļ', 'Ħ'] +['ðŁļ', 'Ķ'] +['ðŁļ', 'ĸ'] +['ðŁĽ', 'IJ'] +['ðŁĽ', '¤'] +['ðŁĽ', '¸'] +['ðŁ', 'ł'] +['ðŁł', '³'] +['ð٤', '¹'] +['ðŁ¥', 'ĥ'] +['ðŁ¥', '¨'] +['ðŁ¥', 'ª'] +['ðŁ¥', '¾'] +['ð٦', 'ĥ'] +['ð٦', 'Ĵ'] +['ð٦', 'Ļ'] +['ð٦', '¶'] +['ð٧', 'ł'] +['ð٧', 'ª'] +['ð٧', 'Ń'] +['ð٧', '²'] +['ð£', '·'] +['ð£·', 'Ń'] +['ð¦', 'ĺ'] +['ð¦ĺ', 'Ĵ'] +['Æ', 'ij'] +['Ç', 'Ļ'] +['È', '®'] +['Ø', 'ł'] +['Ú', 'Ħ'] +['Ü', 'Ģ'] +['ß', '¢'] +['áī', 'Ģ'] +['áĬ', 'IJ'] +['áİ', 'ł'] +['áº', 'ŀ'] +['ëĪ', 'ŀ'] +['ëķ', 'Ł'] +['ë£', 'ģ'] +['ë¤', 'Ĺ'] +['ìĦ', '¥'] +['ìħ', 'ij'] +['ìĸ', 'IJ'] +['ìĽ', 'Ľ'] +['ì£', 'ķ'] +['íİ', 'ı'] +['íĽ', 'ĵ'] +['ï¥', 'º'] +['ï³', 'Ľ'] +['ï´', '«'] +['ðĸ', '§'] +['ðĸ§', '·'] +['ðĿķ', 'ģ'] +['ðŁIJ', 'ª'] +['ðŁĴ', 'Ī'] +['ðŁĵ', 'ł'] +['ðŁķ', 'Ľ'] +['ðŁķ', '´'] +['Ñ', 'Ŀ'] +['Ó', 'Ĭ'] +['à¥', '²'] +['àª', 'ª'] +['áĥ', '¤'] +['áį', 'IJ'] +['á¶', '°'] +['á¼', 'Ŀ'] +['á½', '©'] +['âĭ', 'ĭ'] +['âĴ', '½'] +['âĻ', '¾'] +['â', '½Ķ'] +['â¾', '¯'] +['ãĦ', 'Ĵ'] +['ãħ', 'ļ'] +['ëIJ', 'į'] +['ë·', 'ģ'] +['ìĭ', 'Ģ'] +['ìļ', 'Ŀ'] +['ì¥', '°'] +['ìº', '´'] +['íĭ', 'ī'] +['íĿ', '½'] +['ï¦', 'Ģ'] +['ï¦', '¿'] +['ï§', 'ħ'] +['ï§', 'ĵ'] +['ïŃ', '¯'] +['ï®', 'Ĩ'] +['ðIJ¤', 'ķ'] +['ðĿIJ', 'Ł'] +['ðĿĴ', 'ħ'] +['ðĿĵ', 'ľ'] +['ðĿĶ', '°'] +['ðĿĶ', '»'] +['ðĿĺ', 'į'] +['ðĿĻ', '¯'] +['ðŁĦ', '½'] +['ðŁħ', 'Ĥ'] +['ðŁħ', 'Ķ'] +['ðŁħ', '½'] +['ðŁĵ', '´'] +['ð٧', 'ĸ'] +['Ó', 'Ĵ'] +['á¸', '²'] +['ëī', '¼'] +['Ç', 'ı'] +['È', 'ĵ'] +['Ê', '¸'] +['Õ', 'Ĥ'] +['Û', 'ħ'] +['ß', '¡'] +['ß', '£'] +['à®', '¯'] +['à°', 'Ī'] +['à²', '¸'] +['àº', '®'] +['à¼', 'ķ'] +['áĢ', 'İ'] +['áĨ', '¡'] +['áIJ', 'ĭ'] +['áIJ', 'ķ'] +['áij', '¯'] +['áŀ', 'Ĩ'] +['á¨', 'ķ'] +['á©', 'Ī'] +['âģ', 'ħ'] +['âĨ', 'ļ'] +['âĶ', 'İ'] +['âł', '©'] +['â²', 'Ĥ'] +['â²', 'Ķ'] +['â²', '¨'] +['ãĬ', 'ļ'] +['íĵ', '²'] +['ðĿij', 'Ī'] +['ðĿij', '¬'] +['ðĿij', '¹'] +['ðĿĴ', '¾'] +['ðĿĵ', '±'] +['ðĿĵ', '½'] +['ðĿķ', '¯'] +['ðĿķ', '»'] +['ðĿĺ', '½'] +['ðĿļ', 'Ĩ'] +['ðŁĦ', '°'] +['ðŁIJ', '¨'] +['Ò', 'ķ'] +['à²', 'ħ'] +['ï¨', 'Ĩ'] +['ðĿij', '°'] +['ðŁĦ', '¸'] +['Ô', 'İ'] +['Ø', 'į'] +['Ù', 'µ'] +['à²', '¶'] +['áĢ', 'Ī'] +['áĺ', 'Ĺ'] +['áł', '¸'] +['á¡', '¡'] +['á¨', '²'] +['á©', 'ģ'] +['á´', '·'] +['áµ', '§'] +['âķ', '¨'] +['âļ', 'ģ'] +['â¾', 'Ŀ'] +['ãĢ', '¼'] +['ãĦ', 'ı'] +['êĴ', '«'] +['ê¦', '¥'] +['ê¦', '©'] +['ê¦', '²'] +['ìĺ', '¼'] +['íĵ', 'IJ'] +['ðĵ', 'ĩ'] +['ðĵĩ', '¼'] +['ðĿķ', '¿'] +['ðŁĽ', '´'] +['ë¨', 'ľ'] +['à²', 'µ'] +['à´', 'İ'] +['à¼', 'Ģ'] +['âĩ', 'ĸ'] +['ãĪ', '«'] +['âĵ', 'Ģ'] +['áħ', '´'] +['áļ', '¾'] +['áĽ', 'ŀ'] +['áĽ', '«'] +['á¥', '´'] +['âĨ', 'Ľ'] +['âĨ', '¶'] +['âĩ', '¤'] +['âķ', 'Ł'] +['âĺ', '·'] +['âļ', 'IJ'] +['ð٧', '´'] +['á¹', '³'] +['âĶ', 'į'] +['âĶ', 'Ĵ'] +['âĶ', '©'] +['âĶ', '¦'] +['â¾', 'µ'] +['àª', 'ľ'] +['àª', '¤'] +['âĩ', 'Ļ'] +['âĶ', '±'] +['âķ', 'Ģ'] +['â½', 'Ĭ'] +['ï½', 'Ł'] +['à¬', '¡'] +['ðł', '®'] +['ðł®', '·'] +['âķ', 'ĥ'] +['â°', 'Ķ'] +['ãĬ', '¦'] +['ðŁİ', 'IJ'] +['ãĩ', '°'] +['â¼', 'Ŀ'] +['â¾', 'Ķ'] +['â½', 'Ĵ'] +['âł', 'Ĵ'] +['ï¨', '¦'] +['ï©', 'Ĵ'] +['ï¨', '²'] +['ï©', 'ĸ'] +['ðĵı', '¸'] +['ãĮ', 'ĥ'] +['ðĸ', '¤'] +['ðĸ¤', 'IJ'] +['ï¦', 'Ń'] +['âĬ', 'ħ'] +['â¾', '³'] +['ä´', '¥'] +['ï©', 'ķ'] +['ðŁĮ', 'Ķ'] +['áŀ', 'ĭ'] +['âļ', 'į'] +['â¼', 'ĭ'] +['ãİ', 'ĺ'] +['ðIJĮ', '²'] +['É', '©'] +['áİ', 'ij'] +['âĨ', '®'] +['âĩ', 'ĥ'] +['âļ', 'İ'] +['ãĩ', '±'] +['ãĭ', '©'] +['ãĮ', '¶'] +['êĻ', 'ª'] +['ëİ', '¬'] +['ï¨', 'IJ'] +['ï¨', 'Ľ'] +['ï©', 'Ĭ'] +['ï©', 'į'] +['ðĵ', 'ħ'] +['ðĵħ', 'º'] +['Ï', '¡'] +['È', 'ij'] +['É', 'Ĥ'] +['Ô', 'ĵ'] +['ß', 'İ'] +['à´', '§'] +['áĢ', 'ī'] +['áĢ', 'ĭ'] +['áĢ', 'ij'] +['áĢ', 'ł'] +['áļ', 'Ļ'] +['á¨', 'Ħ'] +['á¨', '©'] +['á¨', '¹'] +['á©', 'ĵ'] +['á¬', 'ľ'] +['á´', 'Ļ'] +['áµ', 'ij'] +['âĤ', 'Ń'] +['âĨ', '°'] +['âľ', 'ģ'] +['â½', 'IJ'] +['ãĭ', '¯'] +['ãĮ', '½'] +['íĨ', '¢'] +['ï¤', '¿'] +['ðŁ', 'Ĥ'] +['ðŁĤ', '»'] +['È', 'Ĵ'] +['Í', 'º'] +['Ô', '¥'] +['Õ', 'ij'] +['Ú', '¶'] +['à§', 'İ'] +['à¶', '®'] +['àº', 'ĸ'] +['àº', 'ľ'] +['àº', '½'] +['áĥ', '»'] +['áħ', '¯'] +['áĭ', 'ŀ'] +['áĸ', 'ķ'] +['á', '´Ī'] +['á¶', 'Ĩ'] +['á¸', 'ľ'] +['á¹', '¼'] +['á¿', '¨'] +['âĦ', 'ĭ'] +['âĦ', 'Ń'] +['âĪ', '±'] +['âĮ', 'ĵ'] +['âĶ', 'ĩ'] +['âĶ', '¢'] +['â±', '®'] +['â²', 'Ħ'] +['ãĩ', '¾'] +['ãĪ', '¬'] +['ë¸', '¡'] +['ìIJ', 'ī'] +['íĻ', 'Ľ'] +['ðĿķ', 'ª'] +['Æ', '¹'] +['Í', '²'] +['Ó', 'ģ'] +['Û', '¼'] +['à¦', '«'] +['áħ', 'Ł'] +['áī', 'Ĩ'] +['áį', 'Ī'] +['áº', 'ĸ'] +['á½', 'ī'] +['âĶ', '¸'] +['â½', '©'] +['ê', 'ľ'] +['êľ', '¥'] +['êµ', 'ħ'] +['ëĤ', 'Ķ'] +['ëĦ', 'ł'] +['ëĩ', 'Ĺ'] +['ëĻ', 'Ŀ'] +['ìļ', '¯'] +['ìļ', '·'] +['ìŁ', 'Ľ'] +['ì·', 'IJ'] +['íŁ', '¬'] +['íŁ', '®'] +['íŁ', '°'] +['ï¦', 'Ĩ'] +['ï¦', '±'] +['ï²', 'ŀ'] +['ï³', '¤'] +['ï³', '¥'] +['ðIJĮ', '¸'] +['ðĿĶ', 'ı'] +['ðĿķ', '®'] +['ðĿĺ', '£'] +['à¦', 'Ī'] +['âı', 'ı'] +['ãĦ', 'ĸ'] +['ê²', 'ĩ'] +['ëĸ', 'ĺ'] +['ëľ', '·'] +['ëŀ', 'Ĵ'] +['ë¡', 'ĵ'] +['ë¢', 'ī'] +['ë£', 'ĥ'] +['ë§', 'ĭ'] +['ë²', 'ĭ'] +['ìĤ', '·'] +['ìĪ', 'ķ'] +['ì', 'Į¨'] +['ìĵ', '»'] +['ìĸ', 'Ĭ'] +['ìĻ', '¬'] +['ìĿ', '»'] +['ì¦', 'ģ'] +['ìµ', '¤'] +['ì·', 'ĥ'] +['íĢ', 'ľ'] +['íħ', 'ī'] +['íį', 'ł'] +['íı', 'ħ'] +['íij', '±'] +['íķ', 'ķ'] +['íĸ', 'ł'] +['íĿ', 'ķ'] +['Æ', 'Ļ'] +['Æ', 'ļ'] +['Æ', 'ŀ'] +['Ç', 'ĥ'] +['Ç', 'Ĭ'] +['Ç', 'ľ'] +['Ç', '¤'] +['Ç', 'Ń'] +['Ç', '¹'] +['È', 'Ģ'] +['È', 'ģ'] +['È', 'ħ'] +['È', 'ī'] +['È', 'Ĺ'] +['È', 'Ł'] +['È', '¤'] +['È', '¥'] +['È', '¨'] +['È', 'µ'] +['È', 'º'] +['È', '»'] +['É', 'Į'] +['É', '®'] +['Ê', 'ħ'] +['Ê', '¥'] +['Ê', '¨'] +['Ë', 'ĵ'] +['Ë', 'Ķ'] +['Ë', 'ł'] +['Ë', '£'] +['Ë', '¸'] +['Í', '´'] +['Ï', 'Ĺ'] +['Ï', 'ĺ'] +['Ï', 'Ļ'] +['Ï', 'ļ'] +['Ï', 'Ŀ'] +['Ï', '¨'] +['Ï', '¬'] +['Ï', '¾'] +['Ï', '¿'] +['Ñ', 'ª'] +['Ò', 'Ģ'] +['Ò', 'ľ'] +['Ò', '¼'] +['Ò', '½'] +['Ó', 'Ĥ'] +['Ó', 'ħ'] +['Ó', 'ĩ'] +['Ó', 'į'] +['Ó', 'ĸ'] +['Ó', 'Ł'] +['Ó', '«'] +['Ó', '±'] +['Ô', 'Ĩ'] +['Ô', 'ĩ'] +['Ô', 'º'] +['Õ', 'ĭ'] +['Ö', 'ī'] +['Ø', 'Ī'] +['Ø', 'Ĭ'] +['Ø', '½'] +['Ø', '¾'] +['Ù', '·'] +['Ú', 'Ĥ'] +['Ú', 'Ĭ'] +['Ú', 'ĸ'] +['Ú', 'Ĺ'] +['Ú', '£'] +['Ú', '«'] +['Ú', '¸'] +['Û', 'Ģ'] +['Û', 'į'] +['Û', '½'] +['Ü', 'ī'] +['Ü', '¤'] +['Ý', '§'] +['Ý', '´'] +['Þ', 'ĥ'] +['Þ', '¤'] +['Þ', '¥'] +['ß', 'ļ'] +['ß', 'Ľ'] +['ß', '¤'] +['àł', 'į'] +['àł', 'ĵ'] +['àł', '³'] +['à¡', '¢'] +['à¥', 'ł'] +['à§', 'ł'] +['à§', 'º'] +['à¨', 'Ĭ'] +['à¨', 'IJ'] +['à¨', '®'] +['à¨', '¯'] +['à¨', '°'] +['à¨', '¸'] +['àª', 'Ĩ'] +['àª', '³'] +['àª', 'µ'] +['àª', '½'] +['à¬', 'Į'] +['à¬', 'ĺ'] +['à¬', '½'] +['à®', 'ĥ'] +['à®', '¸'] +['à°', 'Ĩ'] +['à°', 'ķ'] +['à°', '¦'] +['à²', 'Ĩ'] +['à²', 'Ĭ'] +['à²', 'Į'] +['à²', 'IJ'] +['à²', 'Ľ'] +['à²', '¤'] +['à²', '¦'] +['à²', 'ª'] +['à²', '²'] +['à²', '¹'] +['à´', 'Ĩ'] +['à´', 'ı'] +['à´', 'Ĺ'] +['à´', '«'] +['à´', '¹'] +['àµ', 'º'] +['àµ', '½'] +['à¶', 'ħ'] +['à¶', 'Ĭ'] +['à¶', 'Ķ'] +['à¶', '§'] +['à¶', '«'] +['à¶', '°'] +['à¼', 'Ħ'] +['à¼', 'ħ'] +['à¼', 'Ĭ'] +['à½', 'Ļ'] +['à½', '¡'] +['à½', '§'] +['à¿', 'Ģ'] +['à¿', 'Ļ'] +['áĢ', 'Ŀ'] +['áĢ', '§'] +['áĢ', '©'] +['áĢ', '¿'] +['áģ', 'µ'] +['áĤ', 'ģ'] +['áĤ', '½'] +['áĥ', 'Ĥ'] +['áĥ', 'ª'] +['áĦ', 'Ĭ'] +['áĦ', '¢'] +['áħ', '¦'] +['áħ', 'Ń'] +['áĨ', '®'] +['áĨ', '±'] +['áĨ', '»'] +['á', 'ĩ'] +['áĩ', 'Ĥ'] +['áĪ', 'ħ'] +['áĪ', 'ī'] +['áĪ', 'Į'] +['áĪ', 'IJ'] +['áĪ', 'Ĵ'] +['áĪ', 'Ļ'] +['áĪ', 'ļ'] +['áĪ', 'ľ'] +['áĪ', 'ŀ'] +['áĪ', '©'] +['áĪ', '³'] +['áĪ', 'º'] +['áĪ', '½'] +['áī', 'ħ'] +['áī', '¢'] +['áī', '±'] +['áī', '´'] +['áĬ', 'ĥ'] +['áĬ', 'į'] +['áĬ', 'ĸ'] +['áĬ', '®'] +['áĬ', '¸'] +['áĭ', 'Ľ'] +['áĭ', 'Ŀ'] +['áĭ', '³'] +['áĮ', 'ģ'] +['áĮ', 'ħ'] +['áĮ', '¥'] +['áĮ', '¦'] +['á', 'Į¨'] +['áį', 'Ĭ'] +['áį', 'į'] +['áį', 'ķ'] +['áį', 'ĸ'] +['áį', '¢'] +['áį', '¤'] +['áİ', 'Ĵ'] +['áİ', 'ª'] +['áı', 'ģ'] +['áı', 'IJ'] +['áı', 'Ł'] +['áIJ', 'Ĥ'] +['áIJ', 'ĸ'] +['áIJ', 'Ŀ'] +['áIJ', 'ŀ'] +['áIJ', 'Ł'] +['áIJ', 'ł'] +['áij', 'ĸ'] +['áĴ', 'ĭ'] +['áĴ', 'į'] +['áĴ', '¡'] +['áĵ', '«'] +['áĶ', 'ķ'] +['áķ', 'ĭ'] +['áķ', 'ij'] +['áķ', 'Ļ'] +['áķ', 'ļ'] +['áķ', 'Ľ'] +['áķ', '¤'] +['áķ', '¦'] +['áķ', '®'] +['áķ', '¼'] +['áĸ', 'ĵ'] +['áĹ', 'Ĺ'] +['áĹ', '¢'] +['áĹ', '¯'] +['áĹ', '·'] +['áĺ', 'Ħ'] +['áĺ', 'ij'] +['áĽ', 'Ĥ'] +['áĽ', 'Ļ'] +['áŀ', 'į'] +['áł', 'Ĩ'] +['áł', '¡'] +['áł', '¦'] +['áł', '®'] +['áł', '¯'] +['áł', '²'] +['áł', '·'] +['á¡', 'į'] +['á¡', 'ŀ'] +['á¡', '¤'] +['á', '¡´'] +['á¡', 'µ'] +['á¤', 'ĵ'] +['á¥', 'ĸ'] +['á¥', '°'] +['á¨', '¦'] +['á¨', '§'] +['á¨', '¨'] +['á¨', 'ª'] +['á¨', '¬'] +['á¨', '¯'] +['á¨', '³'] +['á¨', 'µ'] +['á©', 'ĥ'] +['á¬', 'ķ'] +['áŃ', '£'] +['á', '±'] +['á±', 'ļ'] +['á²', 'ł'] +['á´', 'ĵ'] +['á´', '¶'] +['áµ', 'Ĥ'] +['áµ', 'Į'] +['áµ', '¥'] +['áµ', '´'] +['á¶', 'ĩ'] +['á¸', 'Ī'] +['á¸', 'ł'] +['á¸', '§'] +['á¸', '´'] +['á¸', '¾'] +['á¹', 'Ģ'] +['á¹', 'ĸ'] +['á¹', 'Ł'] +['á¹', 'ł'] +['á¹', '«'] +['á¹', '±'] +['á¹', '·'] +['á¹', '¿'] +['áº', 'Ħ'] +['áº', 'į'] +['áº', 'ij'] +['áº', 'Ĺ'] +['á¼', 'ī'] +['á¼', 'ĵ'] +['á¼', 'Ń'] +['á½', 'ĭ'] +['á½', 'Ĵ'] +['á½', 'ł'] +['á½', '£'] +['á¾', 'Ħ'] +['á¾', 'ı'] +['á¾', 'ij'] +['á¾', 'Ĺ'] +['á¾', '¦'] +['á¾', '§'] +['á¾', '¾'] +['á¿', 'Ħ'] +['á¿', 'ĵ'] +['á¿', '¡'] +['á¿', '¬'] +['âģ', 'ļ'] +['âĤ', 'Į'] +['âĦ', 'ģ'] +['âĦ', 'Ķ'] +['âĦ', '£'] +['âĦ', '§'] +['âĦ', '¯'] +['âĦ', '°'] +['âĦ', '´'] +['âħ', 'ħ'] +['âĨ', 'ľ'] +['âĨ', '«'] +['âĨ', 'Ń'] +['âĨ', '±'] +['âĨ', '¹'] +['âĨ', '½'] +['âĩ', 'ĩ'] +['âĩ', 'ľ'] +['âĩ', 'µ'] +['âĪ', 'ī'] +['âĪ', 'Ĭ'] +['âĪ', 'ĸ'] +['âĪ', 'ľ'] +['âĪ', '¾'] +['âī', 'Ģ'] +['âī', 'ĭ'] +['âī', 'Į'] +['âī', 'ĵ'] +['âī', 'ľ'] +['âī', '´'] +['âī', '¿'] +['âĬ', 'Ĭ'] +['âĬ', 'ĭ'] +['âĬ', 'Ķ'] +['âĬ', 'ĸ'] +['âĬ', '£'] +['âĬ', '¦'] +['âĭ', 'İ'] +['âĭ', 'ª'] +['âĭ', '²'] +['âĮ', '¦'] +['âĮ', '§'] +['âį', 'º'] +['âİ', 'Ī'] +['âİ', '¨'] +['âİ', '¬'] +['âİ', '³'] +['âİ', '¼'] +['âİ', '¾'] +['âı', 'Į'] +['âı', 'ļ'] +['âı', '«'] +['âı', '¯'] +['âı', 'µ'] +['âĴ', 'ľ'] +['âĴ', 'Ŀ'] +['âĴ', '«'] +['âĵ', 'Ħ'] +['âĵ', 'Ĭ'] +['âĵ', 'Ļ'] +['âĵ', '©'] +['âĶ', 'ij'] +['âĶ', 'Ļ'] +['âĶ', 'ļ'] +['âĶ', '¥'] +['âķ', 'ħ'] +['âķ', 'ī'] +['âķ', 'į'] +['âķ', 'ı'] +['âķ', 'ŀ'] +['âĸ', 'ļ'] +['âĸ', '¯'] +['âĹ', 'ĥ'] +['âĹ', 'ļ'] +['âĹ', '¬'] +['âĹ', '´'] +['âĺ', 'Ī'] +['âĺ', '¤'] +['âĺ', '¥'] +['âĺ', '§'] +['âĺ', '¬'] +['âĻ', 'ģ'] +['âĻ', '±'] +['âļ', 'ĥ'] +['âļ', 'Ħ'] +['âļ', 'ħ'] +['âļ', 'ı'] +['âļ', 'ļ'] +['âļ', 'ŀ'] +['âļ', 'Ł'] +['âļ', '±'] +['âļ', '²'] +['âľ', 'Ģ'] +['âľ', 'Ł'] +['âľ', '¢'] +['âĿ', 'µ'] +['âŁ', '¡'] +['âŁ', '¦'] +['âŁ', '§'] +['âŁ', '³'] +['âŁ', '¾'] +['âŁ', '¿'] +['âł', 'ĩ'] +['â¤', 'Ħ'] +['â¤', 'º'] +['â¥', 'Ĥ'] +['â¥', '¹'] +['â§', 'ī'] +['â§', '¼'] +['â§', '½'] +['â¨', 'į'] +['â¬', 'Ĭ'] +['â¬', 'Ł'] +['âŃ', 'ŀ'] +['â®', 'ŀ'] +['â®', '³'] +['â¯', 'Ī'] +['â¯', 'ij'] +['â±', 'ł'] +['â±', '±'] +['â²', 'Ń'] +['â´', '¹'] +['âµ', 'ķ'] +['â¸', '¾'] +['â', 'º«'] +['â¼', 'Ĩ'] +['â¼', 'ł'] +['â½', 'Ł'] +['â½', '¼'] +['â¾', 'Ľ'] +['â¾', '§'] +['â¿', 'ĥ'] +['â¿', '»'] +['ãĤ', 'ķ'] +['ãĤ', 'Ł'] +['ãĦ', 'Ľ'] +['ãĦ', '¡'] +['ãĦ', '¶'] +['ãĦ', 'º'] +['ãħ', 'Ĵ'] +['ãħ', 'Ł'] +['ãĨ', 'Ģ'] +['ãĩ', '»'] +['ãĪ', 'ij'] +['ãĪ', 'Ń'] +['ãĪ', '®'] +['ãĪ', '³'] +['ãĪ', '¹'] +['ãī', '¥'] +['ãī', '¦'] +['ãī', '¹'] +['ãī', '¿'] +['ãĬ', 'ŀ'] +['ãĬ', '¨'] +['ãĭ', 'ij'] +['ãĭ', '¥'] +['ãĭ', '´'] +['ãĭ', 'º'] +['ãİ', 'Ħ'] +['ãİ', 'ķ'] +['ãİ', '¯'] +['ãı', 'Ĥ'] +['ãı', 'Ī'] +['ãı', 'ĵ'] +['ãı', 'ĸ'] +['ãı', '±'] +['ãIJ', '±'] +['ãŁ', 'ģ'] +['ã', '¢'] +['ã¢', '¨'] +['ã', '¨'] +['ã¨', '³'] +['ã«', 'ª'] +['ã«', '´'] +['ã¶', '³'] +['ãº', '¾'] +['ä', 'Ģ'] +['äĢ', 'Ģ'] +['ä', 'ĭ'] +['äĭ', 'Į'] +['ä', 'ĮĢ'] +['äIJ', 'Ģ'] +['ä', 'łĢ'] +['ä', 'ł'] +['äł', '¼'] +['ä', '§'] +['ä§', 'ŀ'] +['ä¨', '°'] +['ä¨', 'º'] +['ä', '´Ģ'] +['ä', '·'] +['ä·', 'ħ'] +['ä', '·¸'] +['ê', 'Ĥ'] +['êĤ', '«'] +['ê', 'Į'] +['êĮ', '¼'] +['ê', 'į'] +['êį', '²'] +['êĴ', 'µ'] +['ê', 'ĵ'] +['êĵ', '½'] +['êĻ', 'Ń'] +['êĿ', 'Ľ'] +['êĿ', '¥'] +['ê', 'ŀ'] +['êŀ', 'Ĭ'] +['ê¦', 'Ĩ'] +['ê¦', 'ĩ'] +['ê¦', 'Ł'] +['ê¦', '¨'] +['ê§', 'Ī'] +['ê', '©'] +['ê©', 'Ł'] +['êª', 'ĭ'] +['êª', 'ij'] +['êª', 'ķ'] +['êª', 'Ĺ'] +['êª', 'ľ'] +['êª', '®'] +['êª', '±'] +['êª', '»'] +['êª', '¼'] +['ê«', 'Ģ'] +['ê«', 'Ŀ'] +['ê°', 'ĥ'] +['ê°', 'ĺ'] +['ê±', 'ľ'] +['ê²', 'ĵ'] +['ê²', 'ļ'] +['ê³', 'Ļ'] +['ê³', '¾'] +['ê´', 'Ĺ'] +['ê´', 'Ļ'] +['êµ', 'Ľ'] +['ê¶', 'ĥ'] +['ê¶', 'ķ'] +['ê¶', '¨'] +['ê¸', '©'] +['ê¸', '¿'] +['ê', '¹Ħ'] +['ê¹', 'Ĩ'] +['ê¹', 'ī'] +['ê¹', 'ĵ'] +['ê¹', '¢'] +['ê¹', '£'] +['ê¹', '¸'] +['êº', '³'] +['ê¿', 'ı'] +['ê¿', 'ķ'] +['ê¿', '§'] +['ëĢ', '©'] +['ëģ', 'ħ'] +['ëĥ', 'µ'] +['ëĦ', 'ĸ'] +['ëĦ', 'Ĺ'] +['ëĦ', '¢'] +['ëħ', 'Ĥ'] +['ëĨ', 'IJ'] +['ëĩ', 'ľ'] +['ëĪ', 'ĭ'] +['ëĪ', 'ļ'] +['ëī', 'į'] +['ëī', '¨'] +['ëĬ', 'ļ'] +['ëĬ', '¡'] +['ëĭ', 'ľ'] +['ëĭ', 'ª'] +['ëĮ', 'ĺ'] +['ëĮ', '¤'] +['ëĮ', '¸'] +['ëİ', 'Ł'] +['ëı', '¨'] +['ëIJ', 'Ħ'] +['ëIJ', 'ı'] +['ëIJ', '´'] +['ëIJ', '¸'] +['ëij', 'ģ'] +['ëij', '¿'] +['ëĴ', '¨'] +['ëĵ', '·'] +['ëĶ', '®'] +['ëĶ', '²'] +['ëķ', '§'] +['ëĸ', 'Ķ'] +['ëĸ', 'ª'] +['ëĺ', 'Ń'] +['ëļ', 'Ģ'] +['ëļ', 'ł'] +['ëĽ', 'Ķ'] +['ëĽ', '©'] +['ëľ', 'ħ'] +['ëŀ', 'ķ'] +['ëŀ', '°'] +['ëŁ', 'IJ'] +['ëł', '¡'] +['ë¡', 'ŀ'] +['ë¡', '£'] +['ë¡', 'µ'] +['ë£', 'Ħ'] +['ë£', 'į'] +['ë¤', '³'] +['ë¦', 'į'] +['ë¦', 'ı'] +['ë¦', '³'] +['ë§', 'Ħ'] +['ë§', 'Ĩ'] +['ë§', 'į'] +['ë§', 'ľ'] +['ë§', '«'] +['ë§', '»'] +['ë¨', '®'] +['ë©', 'Ĥ'] +['ë©', 'Ń'] +['ëª', '´'] +['ë¬', 'ľ'] +['ë¬', 'ł'] +['ë¬', '«'] +['ë¬', '¾'] +['ëŃ', '¬'] +['ë®', 'ĺ'] +['ë®', '¹'] +['ë¯', 'ķ'] +['ë¯', 'ľ'] +['ë°', '¨'] +['ë°', 'ª'] +['ë±', 'Ķ'] +['ë²', 'ĺ'] +['ë²', 'Ľ'] +['ë²', '±'] +['ë²', '´'] +['ë´', '½'] +['ëµ', '¤'] +['ëµ', '¨'] +['ë·', 'Ĺ'] +['ë·', 'ĺ'] +['ë¸', 'ĵ'] +['ë¸', 'ľ'] +['ë¹', 'ª'] +['ëº', 'ĥ'] +['ëº', 'ĺ'] +['ëº', 'µ'] +['ë»', '´'] +['ë¼', 'IJ'] +['ë¾', 'Ķ'] +['ìģ', 'Ń'] +['ìĤ', 'ł'] +['ìĤ', '®'] +['ìĥ', 'ı'] +['ìĥ', 'Ļ'] +['ìĦ', 'º'] +['ìħ', '¢'] +['ìĨ', 'Ģ'] +['ìĨ', 'ħ'] +['ìĨ', '¤'] +['ìĨ', '¦'] +['ìĨ', '¬'] +['ìĩ', '±'] +['ìĪ', 'µ'] +['ìĭ', '¨'] +['ìĭ', '´'] +['ìĮ', '°'] +['ìį', 'ľ'] +['ìİ', 'Ĺ'] +['ìİ', 'ĺ'] +['ìİ', '¼'] +['ìij', 'ī'] +['ìij', 'Ŀ'] +['ìij', '»'] +['ìĴ', 'Ķ'] +['ìĴ', '¯'] +['ìĵ', '©'] +['ìķ', 'IJ'] +['ìķ', 'ĸ'] +['ìĸ', 'ł'] +['ìĸ', '¾'] +['ìĹ', 'ĥ'] +['ìĹ', 'Ĺ'] +['ìĹ', 'ľ'] +['ìĹ', '¨'] +['ìĺ', 'Ĥ'] +['ìĺ', 'Ħ'] +['ìĺ', 'ı'] +['ìĺ', '¾'] +['ìĺ', '¿'] +['ìľ', '§'] +['ìĿ', 'IJ'] +['ìĿ', 'ĸ'] +['ìĿ', '·'] +['ìŀ', 'į'] +['ìŀ', 'ı'] +['ìŀ', '¨'] +['ìŀ', 'ª'] +['ìŀ', '³'] +['ìł', '¡'] +['ìł', '´'] +['ìł', '¹'] +['ì¡', 'Ģ'] +['ì¡', 'ª'] +['ì¡', 'µ'] +['ì¢', 'IJ'] +['ì¢', '¨'] +['ì£', 'Į'] +['ì£', 'Ļ'] +['ì£', '³'] +['ì¦', 'ij'] +['ì§', '¥'] +['ì§', '´'] +['ì§', '¾'] +['ì¨', 'ĵ'] +['ì¨', 'ķ'] +['ì©', '°'] +['ì©', '»'] +['ì©', '¼'] +['ìª', 'Ĺ'] +['ì¬', 'Ķ'] +['ì¬', 'ĺ'] +['ì®', '®'] +['ì¯', 'ķ'] +['ì¯', 'ĺ'] +['ì°', 'İ'] +['ì°', '¯'] +['ì±', 'ĥ'] +['ì±', 'µ'] +['ì²', '§'] +['ì²', '®'] +['ì²', '¯'] +['ì³', '¬'] +['ì´', 'ĭ'] +['ì´', '¢'] +['ìµ', '¥'] +['ì¶', '£'] +['ì¸', 'Ī'] +['ì¸', 'Ļ'] +['ìº', '¤'] +['ìº', 'Ń'] +['ì»', '½'] +['ì¼', 'Ļ'] +['ì½', '¬'] +['ì¾', 'Ģ'] +['ì¿', 'ħ'] +['ì¿', '½'] +['íĢ', 'ħ'] +['íģ', '¦'] +['íĤ', 'ħ'] +['íĥ', '¶'] +['íĥ', '¹'] +['íĦ', 'Ķ'] +['íħ', '£'] +['íĨ', 'Ħ'] +['íĨ', '§'] +['íĨ', '¹'] +['íĩ', '¼'] +['íī', '¤'] +['íĬ', '½'] +['íĭ', 'Ĥ'] +['íĭ', 'ij'] +['íį', 'Ī'] +['íį', 'Ļ'] +['íį', '¿'] +['íİ', '¶'] +['íIJ', 'Ŀ'] +['íĴ', 'ľ'] +['íĵ', 'Ŀ'] +['íĵ', 'ª'] +['íĵ', '±'] +['íĵ', '·'] +['íĵ', '¼'] +['íĶ', 'Ļ'] +['íĶ', 'ł'] +['íķ', 'ļ'] +['íķ', 'Ľ'] +['íķ', 'ŀ'] +['íķ', 'Ł'] +['íķ', '§'] +['íķ', '¶'] +['íĸ', 'Ĭ'] +['íĸ', 'ĭ'] +['íĸ', 'į'] +['íĸ', 'Ķ'] +['íĸ', 'ĺ'] +['íĸ', '¡'] +['íĸ', '¬'] +['íĹ', '£'] +['íĹ', '¿'] +['íĺ', 'ĸ'] +['íĺ', 'Ń'] +['íļ', '°'] +['íĽ', 'į'] +['íĽ', '½'] +['íĿ', 'Ł'] +['íĿ', 'Ń'] +['íĿ', '´'] +['íŀ', 'ľ'] +['ï¤', 'ī'] +['ï¤', 'Ń'] +['ï¤', '²'] +['ï¤', 'µ'] +['ï¤', '¼'] +['ï¥', 'Ģ'] +['ï¥', 'ij'] +['ï¥', 'Ĵ'] +['ï¥', 'ķ'] +['ï¥', 'ĺ'] +['ï¥', 'Ļ'] +['ï¥', '«'] +['ï¥', '¬'] +['ï¥', '°'] +['ï', '¥¿'] +['ï¦', 'ĭ'] +['ï¦', 'ı'] +['ï¦', 'Ķ'] +['ï¦', 'ĸ'] +['ï¦', 'ĺ'] +['ï¦', 'Ľ'] +['ï¦', 'ł'] +['ï¦', '®'] +['ï¦', '¯'] +['ï¦', 'º'] +['ï¦', '»'] +['ï¦', '¾'] +['ï§', 'Ĩ'] +['ï§', 'ĸ'] +['ï§', 'Ľ'] +['ï§', 'ŀ'] +['ï§', 'Ł'] +['ï§', '§'] +['ï§', '³'] +['ï§', 'º'] +['ï§', '½'] +['ï¨', 'ĥ'] +['ï¨', 'ļ'] +['ï¨', '¢'] +['ï©', 'Ł'] +['ï¬', '¤'] +['ï¬', '¬'] +['ï¬', '¼'] +['ïŃ', 'Ĵ'] +['ïŃ', 'ķ'] +['ïŃ', 'Ľ'] +['ïŃ', 'Ŀ'] +['ïŃ', 'ŀ'] +['ïŃ', 'Ł'] +['ïŃ', '¤'] +['ïŃ', '§'] +['ïŃ', '¨'] +['ïŃ', '®'] +['ïŃ', '°'] +['ïŃ', '±'] +['ïŃ', '·'] +['ïŃ', '¹'] +['ïŃ', '»'] +['ï®', 'Ģ'] +['ï®', 'ĥ'] +['ï®', 'Ħ'] +['ï®', 'ħ'] +['ï®', 'į'] +['ï®', 'Ĵ'] +['ï®', 'ĵ'] +['ï®', 'ķ'] +['ï®', '¦'] +['ï®', '®'] +['ï®', '°'] +['ï¯', 'ĵ'] +['ï¯', 'ľ'] +['ï¯', '©'] +['ï¯', 'ª'] +['ï¯', '¬'] +['ï¯', 'Ń'] +['ï¯', '®'] +['ï¯', '·'] +['ï¯', '¹'] +['ï¯', '»'] +['ï¯', '¼'] +['ï°', 'ĥ'] +['ï°', 'Į'] +['ï°', 'IJ'] +['ï°', 'ĺ'] +['ï°', 'Ļ'] +['ï°', 'ľ'] +['ï°', 'ŀ'] +['ï°', '¢'] +['ï°', '®'] +['ï°', '°'] +['ï°', '¼'] +['ï°', '¿'] +['ï±', 'Ģ'] +['ï±', 'ģ'] +['ï±', 'Ī'] +['ï±', 'ĭ'] +['ï±', 'ı'] +['ï±', 'Ń'] +['ï²', 'Ģ'] +['ï²', 'ĩ'] +['ï²', 'Ī'] +['ï²', 'ĭ'] +['ï²', 'İ'] +['ï²', 'Ĵ'] +['ï²', 'ľ'] +['ï²', 'ł'] +['ï²', '¬'] +['ï²', '»'] +['ï³', 'ĩ'] +['ï³', 'Ķ'] +['ï³', '£'] +['ï³', '«'] +['ï´', 'ĺ'] +['ï´', '°'] +['ï´', '½'] +['ï', '¶'] +['ï¶', '°'] +['ï¸', 'ĸ'] +['ï¸', '´'] +['ï¸', '¹'] +['ï¹', 'į'] +['ï¹', 'Ĺ'] +['ï¹', '¢'] +['ï¹', '¤'] +['ï¹', '©'] +['ï¹', '±'] +['ï¾', '°'] +['ï¿', 'Ĥ'] +['ï¿', '®'] +['ðIJĮ', '°'] +['ðIJĮ', '¹'] +['ðIJĮ', 'º'] +['ðIJĮ', '½'] +['ðIJį', 'Ĥ'] +['ðIJį', 'ĥ'] +['ðIJį', 'Ħ'] +['ðIJ', 'İ'] +['ðIJİ', '¹'] +['ðIJ¤', 'Ĥ'] +['ðIJ¤', 'į'] +['ðIJ¤', 'ı'] +['ðIJ¤', 'ĵ'] +['ðIJŃ', 'ī'] +['ðIJŃ', 'į'] +['ðIJ°', 'ĩ'] +['ðIJ°', '°'] +['ðij', 'Ĥ'] +['ðijĤ', 'Ħ'] +['ðij', 'ĺ'] +['ðijĺ', 'ģ'] +['ðĴ', 'Ģ'] +['ðĴĢ', '¸'] +['ðĴ', 'ģ'] +['ðĴģ', 'º'] +['ðĴ', 'Ħ'] +['ðĴĦ', '·'] +['ðĴ', 'Ĭ'] +['ðĴĬ', 'ij'] +['ðĴ', 'ĭ'] +['ðĴĭ', 'Ĺ'] +['ð', 'ĴĮ'] +['ðĴĮ', '¨'] +['ðĵĥ', '¢'] +['ðĵĥ', '°'] +['ðĸ', 'ł'] +['ðĸł', 'ļ'] +['ðĿĦ', 'ĥ'] +['ðĿĦ', 'ħ'] +['ðĿĦ', 'ķ'] +['ðĿĦ', 'Ļ'] +['ðĿĦ', '±'] +['ðĿĦ', '´'] +['ðĿĦ', '¹'] +['ðĿħ', 'İ'] +['ðĿħ', 'ª'] +['ðĿĨ', '£'] +['ðĿĨ', '³'] +['ðĿĨ', '¹'] +['ðĿĩ', 'Ĭ'] +['ðĿĩ', 'Ĺ'] +['ðĿĩ', 'ļ'] +['ðĿĩ', 'ľ'] +['ðĿĩ', 'ł'] +['ðĿIJ', 'ī'] +['ðĿIJ', 'ĸ'] +['ðĿIJ', 'ĺ'] +['ðĿIJ', '£'] +['ðĿIJ', '±'] +['ðĿij', 'Ĭ'] +['ðĿij', 'Ń'] +['ðĿij', '¼'] +['ðĿij', '½'] +['ðĿĴ', '°'] +['ðĿĴ', '·'] +['ðĿĴ', '¿'] +['ðĿĵ', 'ģ'] +['ðĿĵ', 'ĭ'] +['ðĿĵ', 'İ'] +['ðĿĵ', 'Ĵ'] +['ðĿ', 'ĵĺ'] +['ðĿĵ', '¢'] +['ðĿĵ', '¦'] +['ðĿĵ', '«'] +['ðĿĵ', '¿'] +['ðĿĶ', 'İ'] +['ðĿĶ', '±'] +['ðĿĶ', '´'] +['ðĿĶ', '·'] +['ðĿĶ', '¸'] +['ðĿĶ', '½'] +['ðĿķ', 'Ĥ'] +['ðĿķ', 'ĥ'] +['ðĿķ', 'ĭ'] +['ðĿķ', 'ı'] +['ðĿķ', 'IJ'] +['ðĿķ', '¥'] +['ðĿķ', '´'] +['ðĿķ', 'º'] +['ðĿĸ', 'IJ'] +['ðĿĸ', 'Ľ'] +['ðĿĸ', 'Ŀ'] +['ðĿĸ', 'ŀ'] +['ðĿĹ', '©'] +['ðĿĹ', '³'] +['ðĿĹ', '½'] +['ðĿĺ', 'Ĭ'] +['ðĿĺ', 'ĭ'] +['ðĿĺ', 'Ķ'] +['ðĿĺ', '±'] +['ðĿĺ', '´'] +['ðĿĺ', '¿'] +['ðĿĻ', 'Ĵ'] +['ðĿĻ', 'Ŀ'] +['ðĿĻ', 'Ł'] +['ðĿĻ', '¬'] +['ðĿĻ', 'Ń'] +['ðĿĻ', '»'] +['ðĿĻ', '¾'] +['ðĿļ', 'Ī'] +['ðĿļ', 'ĭ'] +['ðĿļ', 'ij'] +['ðĿļ', 'Ł'] +['ðĿļ', 'ł'] +['ðĿļ', '£'] +['ðĿĽ', '½'] +['ðĿľ', 'Ĥ'] +['ðĿľ', 'Ķ'] +['ðĿľ', 'Ļ'] +['ðŁ', 'Ģ'] +['ðŁĢ', 'Ħ'] +['ðŁĦ', '²'] +['ðŁĦ', '¶'] +['ðŁħ', 'IJ'] +['ðŁħ', 'ĸ'] +['ðŁħ', 'ļ'] +['ðŁħ', 'Ľ'] +['ðŁħ', '¦'] +['ðŁħ', '¶'] +['ðŁħ', '»'] +['ðŁħ', '¼'] +['ðŁĨ', 'ĥ'] +['ðŁĨ', 'Ĩ'] +['ðŁĨ', 'İ'] +['ðŁĪ', '¯'] +['ðŁĪ', '²'] +['ðŁĪ', '¹'] +['ðŁĮ', 'ĩ'] +['ðŁĮ', 'ĵ'] +['ðŁį', 'ĺ'] +['ðŁİ', 'ij'] +['ðŁİ', '¿'] +['ðŁı', 'ı'] +['ðŁı', 'Ĵ'] +['ðŁı', '©'] +['ðŁı', '¯'] +['ðŁIJ', 'Ģ'] +['ðŁij', 'Ŀ'] +['ðŁĴ', '¹'] +['ðŁĴ', 'º'] +['ðŁĵ', 'Ł'] +['ðŁĵ', 'ª'] +['ðŁĵ', '¼'] +['ðŁĶ', 'Ģ'] +['ðŁĶ', 'Ĥ'] +['ðŁĶ', 'ĥ'] +['ðŁĶ', 'ĩ'] +['ðŁĶ', 'ĵ'] +['ðŁĶ', '¢'] +['ðŁĶ', '¤'] +['ðŁĶ', '©'] +['ðŁķ', 'ĸ'] +['ðŁķ', 'ļ'] +['ðŁķ', 'ľ'] +['ðŁķ', 'Ŀ'] +['ðŁķ', 'ŀ'] +['ðŁķ', 'ł'] +['ðŁķ', '¢'] +['ðŁķ', '³'] +['ðŁĸ', 'ĩ'] +['ðŁĸ', 'ij'] +['ðŁĸ', '¶'] +['ðŁĹ', 'ģ'] +['Ñ', '¨'] +['Ú', 'İ'] +['á¡', 'Į'] +['á¸', '°'] +['áº', 'Ģ'] +['á¼', '®'] +['á½', 'Ŀ'] +['âĦ', '¬'] +['âļ', '§'] +['âĽ', '¤'] +['ã³', '¬'] +['êĻ', 'ĭ'] +['ê¸', 'ij'] +['ëĶ', 'ī'] +['ëĹ', 'į'] +['ë¡', 'ij'] +['ë¯', 'ij'] +['ë»', 'ħ'] +['ë¼', 'Ŀ'] +['ìĦ', 'IJ'] +['ìī', '¡'] +['ìĭ', '²'] +['ìı', '±'] +['ìĹ', '¤'] +['ìĿ', '©'] +['ìĿ', '¿'] +['ìŁ', 'Ļ'] +['ìł', '°'] +['ì¥', 'ī'] +['íĬ', 'Ń'] +['íķ', '®'] +['ï®', 'ı'] +['ðŁħ', '±'] +['ðŁĨ', 'Ĵ'] +['ðŁķ', 'ĭ'] +['É', 'ĺ'] +['Ê', 'ĵ'] +['Õ', 'ĥ'] +['à´', '´'] +['à½', 'ħ'] +['áĨ', 'º'] +['áĪ', 'Ĭ'] +['áĪ', '¨'] +['áĪ', '¾'] +['áī', 'IJ'] +['áĮ', 'ĥ'] +['áĮ', '½'] +['áĶ', 'Ń'] +['áł', 'Ĥ'] +['áł', '¬'] +['á¨', '¸'] +['á©', 'ĭ'] +['á¶', 'ı'] +['á¾', 'Ķ'] +['á¿', 'IJ'] +['á¿', 'ļ'] +['âĻ', 'Ļ'] +['âļ', 'Ĥ'] +['âļ', 'Ĺ'] +['â¡', '¢'] +['â¤', '¦'] +['ëĸ', '°'] +['ë¤', 'Ĥ'] +['ë§', 'ł'] +['ë±', 'ĭ'] +['ë±', 'IJ'] +['ìĽ', '¢'] +['ìľ', '¾'] +['ì³', 'ħ'] +['ì»', 'ģ'] +['íģ', '»'] +['íĥ', 'Ļ'] +['íĵ', 'ĸ'] +['íĵ', 'Ń'] +['íķ', '±'] +['íĽ', 'ľ'] +['ï¤', 'ħ'] +['ï¤', 'Ĩ'] +['ï¦', 'ĥ'] +['ï§', '©'] +['ï¨', 'Ĥ'] +['ðIJ¤', 'Ķ'] +['ðIJŃ', 'ĵ'] +['ðIJ°', '¼'] +['ðĿĵ', 'ŀ'] +['ðĿĵ', '°'] +['ðĿĻ', 'ľ'] +['ðĿļ', 'ģ'] +['ðŁħ', '¢'] +['ðŁı', 'ĩ'] +['È', '²'] +['Ê', '¶'] +['Ô', 'Ī'] +['Ô', 'ij'] +['Ý', 'ĵ'] +['Ý', '¥'] +['à¤', 'ij'] +['à¥', '±'] +['à¬', 'ī'] +['à°', '³'] +['à°', 'µ'] +['à²', 'Ł'] +['áĢ', 'ı'] +['áģ', '¼'] +['áī', '¨'] +['áĬ', 'Ĵ'] +['áĭ', '©'] +['áĮ', 'Ħ'] +['áĮ', 'Ķ'] +['áIJ', '§'] +['á', 'ĴĮ'] +['áĶ', 'ħ'] +['áĶ', 'Ĭ'] +['áł', 'Ħ'] +['á¨', 'ģ'] +['á¸', 'ĥ'] +['á¸', '»'] +['âĶ', 'ŀ'] +['âĺ', 'µ'] +['âļ', '£'] +['â²', '¢'] +['ãĪ', 'ª'] +['ä¶', 'µ'] +['ê²', 'Ļ'] +['ê²', '´'] +['ê³', 'Ĥ'] +['ë¡', '¼'] +['ìĨ', 'Ĭ'] +['ì¼', 'ĩ'] +['íĭ', 'į'] +['íĵ', '¬'] +['íĵ', '®'] +['íĵ', '¶'] +['íĵ', '»'] +['ï¤', '¦'] +['ï¥', 'ł'] +['ï¥', '±'] +['ïŃ', '²'] +['ðIJŃ', 'Ĭ'] +['ðIJ', '±ħ'] +['ðĸ', '¥'] +['ðĸ¥', '¨'] +['ðĿij', '³'] +['ðĿĵ', 'ķ'] +['ðĿĵ', '¬'] +['ðĿĵ', '¹'] +['ðĿĵ', '¾'] +['ðĿĶ', 'ĵ'] +['ðĿķ', 'į'] +['ðĿķ', '¡'] +['ðĿķ', '±'] +['ðĿĸ', 'ĸ'] +['ðĿĺ', 'ı'] +['ðĿĺ', 'IJ'] +['ðĿĺ', 'ļ'] +['ðĿĻ', '®'] +['ðĿĻ', '°'] +['ðĿĻ', '¸'] +['ðĿĻ', 'º'] +['ðĿĻ', '¼'] +['ðĿĻ', '½'] +['ðĿĻ', '¿'] +['ðĿļ', 'Ħ'] +['ðĿļ', 'ı'] +['ðŁħ', 'ħ'] +['ðŁħ', 'ĵ'] +['Æ', 'Ī'] +['àł', 'Į'] +['áĻ', '³'] +['á', 'ļĮ'] +['áĽ', 'ħ'] +['áĽ', 'IJ'] +['á¤', 'Ĭ'] +['á¸', 'Ĭ'] +['âĶ', '½'] +['âķ', 'Ĭ'] +['âĽ', 'ĩ'] +['âĽ', 'ı'] +['âĿ', 'ª'] +['âĿ', '«'] +['âŁ', '°'] +['ãĦ', 'į'] +['ãĦ', 'ĵ'] +['ãĦ', '§'] +['ãħ', 'ĸ'] +['ãī', '«'] +['ê¦', 'Ķ'] +['ï±', 'Ĭ'] +['àº', 'Ĥ'] +['áħ', '£'] +['á¥', 'Ķ'] +['á¥', '¤'] +['âĨ', '¤'] +['âĨ', '·'] +['âĩ', 'ŀ'] +['âĸ', '¤'] +['âŀ', '¶'] +['ãĪ', '¼'] +['ï¨', '·'] +['ðĵı', '§'] +['âĶ', '²'] +['âĢ', '´'] +['âĴ', 'Ł'] +['âĴ', '¡'] +['â°', 'Ĥ'] +['â°', 'į'] +['â°', 'İ'] +['â°', 'IJ'] +['â°', 'ij'] +['â°', 'Ł'] +['â°', 'ł'] +['â°', '¡'] +['â¼', 'Ń'] +['ãĬ', '¥'] +['âĴ', 'ł'] +['â½', 'º'] +['ãĩ', 'º'] +['ãĩ', '½'] +['ï¨', 'Ĭ'] +['áķ', '·'] +['âį', '¨'] +['âº', 'Ł'] +['â½', 'Ĺ'] diff --git a/vocab/smallthinker_vocab.mllm b/vocab/smallthinker_vocab.mllm new file mode 100644 index 0000000000000000000000000000000000000000..adfa9853c0650566f8bfdd4e4317616504e4a4ad GIT binary patch literal 3189859 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ⅅ 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 z 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 y>3=fGeQB#L8DM>Zgx=* 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�O#7~)EoVlc3Z>(WBgfhdxrR~}oa>79_$ZlD? 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

  • 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∈;Xe-G(Sr>iUK%OJ*xwqBn7yXi&U2;jSM z`m9SQa1~M1S3)k-rlxX>6?GGc)e=X>Q7k5RYEfSWvz9hDxzmcexmHX)2OCt2MSTs( zW|}>yXb5o)&nW5^V5<{8Uou#jpIOw`1H#Q)eA@>z2}>gE&`hm0!C6dQ7L zi%JBbr+;ju*PUHd62Q6v?;%UvyrNQ}0Bl=aV^Qglo&yREQc)QIKg_1jvNJ3VUszPO zR?2X%JEy1|v{kj$%cT||0Bg$#z{nAySc^qIQCL z_HI4P^%nI_XzTmNKDV~0T~L0MMbD1=i~1IbpP}8GBIj0aps3w|R>xSQ_2N)b-wwbu zv#D^yMePZIokBX@Xi?t*F!r{gZMOw#Ls5HytSSqsvD;MCccJ~KmJb9~Vo`Sh`lk8t zk~ViQDe8M6Z<}qYTZ_6A+A1EK7L9<*iu(RR#7FkNyr_Mls91DxK@0+yt|)3hur-D| zGl%pmi<$uNY-0f#Wx8Kg)DOUnO|z%EtBblTq?l$>Ascbm6!k+e8;86#^v+PQ)+*|5 zP-`PyUUJtJ^&@ECyRC@wt}p5y0Gl5x<~O<S~S2>si+4I zmKV7?&J^`?0ITBQhC!Dr>Osh`i=dGmSj5vWY_*E|1-PF;gskLLTPo@yAU~X%ZH=lF z^-B=r2X1*Wh%f44Xy4~NU5LE@Y%l6pfSyS$3+vsEq8_Q0vtZe>Mz^!5UxV1kP=heJ z2qjq5qal~Yt(@g{7xfze&j-v$BjX*8MnydaY|Yt-J(x(^lgOs$OCV~1tUE$-o> z{=zSwi)QMD)g#;RBSk$Mir#Ob?b7biqW%hEd?gx!d#tGEAgvR}hHVNxUew>h?;XfC zo+#>hNMli~$vY-=PZsreFq>s(VIyDE3!wz>(BME({|H$ypuwXGi^kJMy$I$Tgjml! zmD+34XNvkKxN*A?LkRb5Q7=JTCpCuK@pDD}3&^;wr?%# z>~x2f^g2ktiZLk78`0q<9SY`KvZQa+9Z}NjLm6%LOB>yhB^?HBENNwH3(*B8m-L2^ zZ4CQ2PEI8q4sdY9TR$9K(i=lgd+FBh-=7{+(h;?UP0<15*pl7^6wNm@$##?~=|~V? z)6PLwAs!%>^ky&{2`G9`C~0!77#}|1#FE|uYvvfv~O&Xkgl0<~Umv!L@+OL{A` z@ucls;trN{bRcmT@9Ii=8>DXrdpQ#C=_MT#3P4*j=w_7k_K>6Q0MyH zzp+k;URKU7=>$OQytc?Y#GI1e4dAOE`5JU{OF9wA>Q`^d=@xf(N$&wMj`03*%*`ul zN=Sh#ID*=`#**F}QnYmrjX9MxwU#3CX|k}S_kq}#Su$9G&ME060Ap+2^yzMKNz)*G z6EL>x#;xtrlIm)u^kd%Qno2r3AZ>GV(#nvp@*Tha$Z3hw>p-g#|F zXMp(bLPYQSOZpIiAF*b*5=AB&DCx{lP+JE=&Y_Y%9O%aR4U64yNwcB-TH|jAX3#ZS z(no-;2bM2tbsI{W6G$E@xJ@OU1!><#I)k~!mXhX%-`8;{zoev(LfXi|RTqM!9=Elm zvqP3P#w?PjlIlYmTn$9Q>Mk#79*}hb+gy*kqNE0Bo2304+?6FELJXW6;T59oH&>N3 zAJA&T+i=dGSC=FJ zU(z`MHt6h55*g^=8zKMH#)gYNi6_= zek>Y@UR>l#Y6UyE5%)y<7W-D*923cRqNfoC9MJSOvOBI$lX^`Z!OVAHZUR$medy#O*#4Gizlvj50tbvBx>V1oEiH( zSkgKmV`lVl<)M=Lp^e+^ykABkSkn3c%tl%x)-LLm%7xo1n-1nrNJkr4%gtjLn!xso>5@*=`Swp7v< z5Z^PbAl%4aDCy!*Tzk*DcK2dQmq1&iTG2MYRMMr8Hl$X~KNz^<<&w4r5VNFkEPJJ- zPXb!gFz?+lQE;!8bQy>>ZOxE#Wqk_Df15p{f4!Sj*5yFf6ccc}L(2LzwCC9TE;E~S zhn95(n78Jq!!h=Z+>_X0_OP-(!*6~vdK*vPhi!I;mvtq0RF&Ms9s4Toh_XHl5*m)x zEnctb)0DhmV zAH(Bgq!&58tgnT1Z9ELZF=<)1gmUmx?#?Xh>yUn>Lce0K7ToNzZUv0Ge;e*A>_|1I ztavDB4yq@-yqA>#@KszqU#;%!vXcKRtDW5#!NR<f*17_J{W;w30tTeEnEZA-G zY#1*erhryi8GbRQNADEq%!OrTfoynk>}+@El$C?_3^&tr4)mC{mz570IjLbqH|Um@ zRRFR&c9=g8OtH!;f>_h+@t(O#cgMpZw0Mol|y!Oiol#-QC0=SDi>SR zKZwrAtt_hw6vjT+U9%Zyh@M~8IJkWYMS8cH|GQOXeIsD@f`PS{BUM@3!K{whKz8_ME2RbLMpzp}m?%Bs8g(iv_`S$EXR z!m}VdnTb>`DeHS7*-)=ZtIE0)+FCi%Jw`;a%gXvbfOW$D@kvLOEUqf+2LYMbW>1FP)n(lU63vSQmUd?1 zb4^)41T${5*@K*G%eoudH`}K4kh`v|AJrgK!nlsQzN~u!gh6npN#JfM>&KxWJgJSj z8_T*E+B(jRg%-CX^cZzFmGzU53iSq7S!LZ93PNB^K^xsIW&N}UwXn6I;VbKYAm54j ziEMI-vVI2QO-rNB2mn!Q4ezI0ZcUT6r%arx=Q09Dse%n0FmGvNyHN4Ia8-=od z0d0MPpAOE2rLrChc_tDwBN<<%tY6k36NGfS@v zeu+Xu$2cExJInetpl^}5YPwxzJqi+a#G>YpyWM5|2HNQl>oHJ2KQ?g2 z+FRCd0j$5~5E0niAly;b;{n1D8+R5Qy2|<;P#EJTA&Im+`^tJEq>P!8ol!GU*6#yE zK#j<{{jRc}1d4WYbf0&Z^@otcPSpsT+&yJI1!Q$c8r|EBrLJA`B-R_<*>*Y`c zvOPpzFO>Cf0MBJa3}dEweX*=pYUOl{b*^(SmGz%c&Mbsz?&Y#x4duj!2N_bYl=a_` zpv^)Ey;_!A;j6;Q0M{|jRrDGVKML!)GEJ&zQUEMK1H!3_UJDQ{TtV7_9acq$gjA!0 z=2H2vie480!m%+X4zK7?0OP_$Vp^R$qN3MB`~HmfrpV;{$chdF_WflZC^jMlM!dVm zO|Iw-p#UBYjJl&LIvm>9w1?IH=!)JL612@s-UqNAW~)U_^g zQ!9FFpk}wZlPWqoq~#FFL&A#Q7Ji+zBA06}=t6A7|GhCt*8k@J>Tq ztfFK2&Ce`5#N*a(vpcn-cYs@O} zrcn&bw6iOE52R-v_gHh!=jK&31<80jcx3Qx40$5eru}^iXXlf{A8k&-Y6}>N{ zx1DmcJEx+P0Q|{@<;^@6@EFuBu4o##eQh~sX*N|>>7^Cb0U9e}b|B-ZRnf^HQ5`!` z{Z%v_GU`h#saL?L;j}u3*7k?#UMSe7Z8iet*U5N zNKk)Xi@T_zQz3nU=dx<9uIT+ChwU{?kB*8?tCg|;GrWB4s^|kCzN`J&k43bnqSHbB z$~dy#-ih>9^g$r2{zT&9*=}t`XM~~_<6Doy`z!iTNHO;U*ga6unSsXb6X&LiJ`C;G zy2u#^Zw4!x4d&~-noOe=eFVU_awBHSZbL=b{YOb`h3|5kDmtrHPT%_VW2{nJDw-P- z)kQj|ODg&(fFBV}h_B7+W@|-fhgA5d=@@aBRa6gPjpD^3z8ET+S4&_zmn$l2r~&nj z4erW{8UcJGF1>V$#Z$PdqWNG}=ea(B_|+8&#OCQ)9qyWn7KGm?66cyI@7jtM2Bg0o z-Fv&cuA)UCVajoKw^8h_ujm|5V~<&B4!9dC`WS#;xa@RjQHG*J-HjD3<`=8j%!AVG zn<`oY=DU$6I82J0D`L@#N@R6sR^L+5G64H9H&3L%-5eF%trazadiFKgz{f&3QPIZ% zZ9uPMnNL;J3>hs(=ebNpE#b!t2_T%Ss1-7r4lSdbku~!j>Hx5o;^T7AO;pqw62w?(FkP>x3&5HlDTAZK z;@uT>1NyHuqL+gm_f*sa=D%iMCkdTX(HbDX#i5R~M_kO3`zq=M_7jQc`#5Q+s1GFS z0DCdz9;j$7fS=NYp?a{QbfvpN`_hWYEdZeNO zAiq#HccX?y#=x=Z(TWDatp)fIPQm@{?y-u7!0e-K7Oe5{iartOAAAaLOixra4DDOk z9mUspvZ9et%tWHSW7u^6PgOJu=9@>s-*g8m8mncj@4}$cJzdcTAZt)ZKd%QX+6ZY} z{@>B=*@`v+`c`r^Auf%b1D>mBGqC4P-xl|LMO&alHzUyKaxYYLae&&wJI)s?x&+8r zjF6w%^-@Kb0vHEk1X^Jg!sUBKTSKCm(bLjbD*7aV|JL%w?$wGe3kllrk%PbYsy+qa z>$u3w)FUy)q^d3l4*Qci4zl6L*{P~ehw{eED(ujzuBfG3-)(O*xa{=1!>alW_*<-U zk#(%UV>LzgtcO>1B|rMvXcu$i$`Mt47SLCu9r5I5G#p5+*M#&qWwD3U$5!=u5MwUyF_^Z; zRdsCuCKA(6KFJ+l)fWQLhGZD8qg7o8V7(TJmN?{|Sk)JS{J`OCPoSNuuCF0WY}`z( z>PsOT&!aej?{X(qbpw!R2L_;#NU*M|F9TYQE{wcgPOs`l0M8!^M}^TzkI$&;D*Uhae5%S=a-#jaw zT~!jq+BmWikGXDMRjH6%i^l?Aig0M+cl^@msVA%;Y`s{Q_;hRrmBkI#s_RBU2|0>NZ&ehq{h&1 zt*Q)WE4%mcXQn1@MOBr6^2){pV^-YCs;Zz-OR=8jVPRF{05&ff13TQRs=fj3KS2B$ zJGNg`)pjtyE|}(Fqg!3oZ6Vtr7jM^5)edMs;^x)2%y(T?-40?Ek8x1!scI)=#J|P! z>l+s>UEq4F`X-o_8$Fbrhs>&~U7?&dyqU2s^jGyQ5WjFVjk$rUb_Y7v#hGoWs&7O4 z3OAstVGkRwYELMoiDj%4K~+`X0r5?kH{YT@Zm4Q6kg8ap&c#m- zR&7^QwIA3j#T%h$S-Y~T2_UP~#5OY;zpAPq09f-|%`Mi|RoxZx#5y9bxofKWA&?Cz zZk|YGkg-}UplhqT8$7H6=HKPIs(utQn>DvF=K8Ac0g67D=o}t%H&pdw0N+F$>o5-8 zjaA(XW}G471Gif&+TBf6{UjvhVG`eEGrYN~`@pQWed}1xZmH_0(8j$BmbzQ3x*y7h zMBT?nU81U=LE5M5=J6!lrK)-WAX+hqM6vH1E>qRdL9DzEd)l0<>OpAVjYNv#0#m5! z7eH1hPS{+js)s@uZM>S`22rW%mmt1Dgkv>1+;~+FgW0EB@yW~+!K!`*U>|BQVdRdg z9;sz&ViKTo+F8}F!Tk7GG{Q4c9xCjr>QO+?2o zun=OzO^my{s(KQ{SFwQz8q1nm-Q89F0nk3ZYRW2iPgPHaGM2A!_g3{sC~G)RqV~A^ zsyYx7W1!;huj)^M!~u|dpsJ@s-m_M_2dnxsl>b^Icllw=+#jmynUDk(;=@(_1Ocfio!9CR7@PgV5-nDtVdkPOUs2der9NVGAxvW>QIsvKH^JSbW` zpRVdfe)U!0;O?HO>YoAd%hIz|y#!! z@9dgW$Mx14(t`JSchb0y2AM}8oYVe){^RP#^)^cLBi;+0xf`=bO&`}WwGX3BBS`eP z-VS1HXj{&{8ynZL(0;^mJY$#da;J{#9e~EqlTXI_+MPD8;{g1)u%5(=!?@lV3PQC; zc%E?`AMzlo!3gxsalNaS2Wcw$?AhZw0mz?bFhTi0yuAx_omCa@yF^4pL_|bHL?{J9 zX;VZ*tfe+>@^4epHYVwVQkv$~CT*I8Jo@4x7DQSR5fKp)BNjx&{eJIF#S#z^5fKp) z5fKp)5fKp)@%-kuRyOC{bH})MjC;n7gAV6^ueH9l=6cUHAG`-fDrU1|`XIO;Pl&%q z-JFW31uKajWoEMV>%JYPxy75URz?C z1`sAL{*LYR)E3i8)r^?qaCBTA({!NFjNvHA+{&0{fLWcV%sOw1TNP6+v@g74BSNj1 zIEO}sH%6Yt%oJu#OeX_cJ&9Usm#DQdeF(&lXq4D_USzB4jOmn+ISe!Uvpc2_2axGD z;&qY^M1d#q`l?GHgW#Vmdw0l-}uv zV)_`gZ!{Y77R72frdeQC{n`db9qLyxeHNGnvQvF?|B?3cmFJhhg&n`){}lW136NjJ>8f;4X>@tIvohsKA?e zc1KL}0%DIW2wE?RY5pX#6FJEycWF%Z0YQh#42Lg^i6@3=0P%Fhoo`o63IG z!TiJ;VV@k2>5~A~x^{cb<)JgC77%M4%m0Ym9aAf`Eisd!ZEudL4al>p#iTvx>BqDT z%u2R6orJ!QX?Zn~ZD&LQxGkm?RSemxz1_xQT3N-m3=&dqz$IcjtBPSYWgBxUrd43} z0Uq4D@U9xu*#W3sgnt&7i)nQLCdQj_3sQ*b8~|$^=P1k-T`8tDA;~7Hz13A>Y6q}= zBN_rW45Fd1C#JRhFv(J!chbl^V(JJ5nlT(bx;Lgy5aZT~EI4i=rY>k(N_%kga(7JK zA%od2kl~(~dO++z+JN8snAU~t%?)hH_rxLKpW2p zMHZW=xW{4|1o3r3i-T)Ag+CtC5U34{>5PSsCq7@Eg^vg5awL>d`w$G{9tVD zGFwykLQLDhe3e_fSTjv`_QjaCgZjb0f&0lzF`X9*LxhMp+r1pq`5?wJduwv9#B@QR zBW0dfW4f@K1L+tMuVeZYi2qcNnG)G;_Vt)90yXZ?&{1=m=HmKv$QtDM`^2>aB;rQH zO1E!Z7eiV@aJn)$Y(nGx;<{uq$qL-m$MqRVE7qK$VM*W)i0e`yFZ;&@U8KwrshJ%Z z*Jt^~H+Kn3!9j6d7IL>QYp$hFkjG)(G-Frw}yZFKCHrmT+GOo`- zMs+joRg*Iu7T4t=N&8rzJ3Ow>LmKNE>l>E3BjUOO+MjeVH@4Hg#TGp>t}le5Oa_E= zf-UZ-xUK}Vs!kt`oI%9(MF7v$uZxKclHgKxAW8Dx*o`;f6e*s^tiqb z<;%9mlv#1z0AMXNc?0_Gv*Y^4WRjgkt#EVV8V9hRIq9V7Zf;!P48L&5^e zsbkpJ$Mr1$E7PKb@UE`7c7s?~wU2VLTo~6)(0=u(8$jEmZ_q7@>*kPXV!URyYl`dJ zp_s@G0bv{Cx&_3~Jp6IkaBPn2J0TS^Obqc|OI){xa%wU9b!~BdH>6;}F&)a~aoq-D zEt<(dS{c{(AdN+}$GKH;#lnyDhg%(29MXR?gw9(NR|3qczr3S=tfv`W7`HaAB%ra@ zE_SGi#gzi^Y-ls#PIp}CDzceZ3%4$=Ocjy2JnxMw3*uQLE>@<*wjr)uH5u<dI77CjczoqGPIxE1TSEn z-yByZB;o9_#chr2c4*%QrUg%&aqS725ci;0fG3E!zF$q$WIDMQ#&t(XG#OvwqPTtl zw%D@p`~S+8;|Q}(AMg9{2p-h;7krnt}AyOVrMREN)&@D$O=rv7=AMr0C2;#}Uk8z^(>p$MqVtRe;aES?o_ykEM6-UMiDvzO7O#Jw`Ln|%`62iU&c zvk6ZSZr_C795P!t6T2g9bNeNXn3+AJs?ha1qZP3;wwe|DdAqgD->3hyAt4Av4hbHuP zaH}tVI+&=3C3GNwU%yZvA9jZ)^bQc?o$V5~b-5!FIta|ZrY2mg9huNOCyUv+sbi}< zDxrg`#dMkl+|dcW3&c8l3$}_09RlSW(ZI2v#k0#zP3YaAe$a6mHYt}oKA}SaeLt;> z^aX1YdJm8_ZYJiJ(-Jxi(rVK}2uC+Pq4z@jHgt}m8&jLm;UPoq$R>AkLhpmLCYcLK z^H$?dN$7}BNEGSj)P&w&Eu_^{;Z95FND!+?-Kbrax4P34`am^Ny?vk+}@ z^$8st@=qtcbwX32?1Mh4=E8)I16T}Trr`g_{@kL3jt^hj$^i|f{e(^c@ZE(CeGlq9 zZb?ElA=Uh*y2iz>IiV8)jM*mp8?->wEeTBn^WD#rZwIl$5W^*O5~wj|eurD0&~zy4 z)egMGxs?gc_@DBi_-%PsB~%M)ozg(~G*fX~ozP4mzoISYC^R_6{_fT!baE)K*TM>| zP3S|=VM^c)0h?JXu`{7lLOSl}jjlVP4?`P+Yw=Er>(qo!1+dXq!;?>MLLZs@J#s~| zA)(Vk0kbTEMSnsc4GEZIH~=3===6{Pk6fI%68cz30AD#g4<|GWzz=y$mAiV~XhI(c zvX9Q=RS1aVN@S7>9@*3C#nuueY`~xl0n7AF|lZ!d;qBJ+vPPyvuC1MgOvd zxGqNJPTaKjcDE}bLHnwzw-3Y7D=d(J`;{ zS0%Iv#OjL^P#kR~bSAX_xT$*~F>%)<)C6c19>g;F+JqKEdWP1aWq_Nlgq8qVw=yi@ z@bw8T4QWmYo{Mits2RwrJb;vGy_aZ?C-g~Bt6-DdjS01ca%P%!lG~k7YXBHOXi(jp zP#b{n9E1=#cS}OcK&%PopUT~u(DFbZd+fw6cUwX$psn_ejg2mr&`L zki>Kf!3AF=R#oPOa&vkneS{vxddi0KjIzllPwSCm=_xC2$2^P&C zLXqMhBB3sTsHVe%-64F}-3fJrS|e+1GvqFGPeMIFzGqi(aj@&qy$P)Y^lNwLSagHE zFQN5d#;;mVxc4X28%P|Wxd#&JgY>*=w&T=;32gxJ1#iLSp4s<2l+Z>%KR(T0keOe& zhZE|rCgld+-N*cVB%w`!#s)jexJMHjfVL)1jN_cuJ(kd5NPxhm!#$qRP)J~o0EXQY z37rezKV~Lb(E|8nLc^fGUQ2pL*Y)>pbx$QU67rrufMCr%ozN(NajG3zh&fJvCZRDP zYhvwI^OfbEO=xpSWT$e3VeYwvwuD4xUews?o=<3NKqBuN=-DT<4a8bjgZ#(6n9z1; zYgrF2f>9hx=sW;l@uj$2!(a%3R6^%hQPdi@*(17pC7}yIt*h!M-|b#a=t8h)1R>RM zuO;*;XzMz&A$mQbiy-|(Z7`qR&L#C}AZuHD>%vBC)%Hnh2Z$d6b*9aP-dIu>Pp0CK z*m9QJFR4pF{5HT!VJh-$J^Ls1nUI;GV1_d|pHJ%2YJohR4s#ScFsaW@7U-Sa9F){$ zAikFuHZFGuC$$s6cNeO$=9I%7lGLt{56=|lYx&TmJ{R(}ca36yaadB919%?JM+(+y z0-(c_`aGyDE7P~TBa*rzWJ3PXyv!Y$)E6d!ofaqRsHCn0@LzB49pqtpt2;WWFHWW! zpSP^lO-br10MD!8u}%vkI5nv+g+%Rj%i0#Yu2||$N$NT%>+A)bdhCpK zYEoYdP_%$>SUxSO>w)}1h=%jrgbtg@Do;=9>-=JEgNeKxux89k>IN|1Nt^IwHan?r z0QlKI-@KR2Nou@`^ljv9Iyb3rhD@bO-0Gy_AbunaW6RJNowC*>l?Vy%#1uQg?$`>kx-tp41ORLG#QBl3BT3k<>ktd3b>0+40JxeiTwM zXvc;}xZ+)v)V*N7bLN@)eo{XU*>IB4gXHa+r0xqz@Wq6`j%$_nAAg|DC{QOElK@ilI+>;ZcXapY94k;WYEdN3-ILT4p#EzOk%IOeN&PNlp4ZbG>AbqV zNj(W>-ByEhmQgp6)b9f@6T_7ecXv`x0ZdNu$*|M+B=v_-7zYNHGPrqfQcs7x(aV#& zFR4EQSS1?FP@`?o-JjGm)ihHG`}jaoe**CATHiO^@BIR}2a|dh+}O-|mUIs#^=D{f z2HI1`=!cVfE+F2T$32qNUqC#2hRmL@=pIe#c`#o-V`|c@>anE$3T~rh1-iaoQ1N(D zF9fj0)Qh7F+!IOt4bW;bYNClJlX?-_cs7rN3m)f_`a6LCtW7p5_jFP(fmv6cK!BcS zlKKavae}ZL2+g*+XOnt4fiigTpRQ8TwYGh@DqQI^F9@xwCxhCU!PBm(rUctwQZlWWRk<+6TaMq@PnT^Jd?a z-W)LQ3wt6#@_s4p3ue_r(01a)F1LS5ZvnCDeVjjcKuY@snwTGW;Y#VPA;-jc6p`hi zl=crPEH;=sIHk8iTV=*JZbUkKNJ<9)SXcCP@#>e-+XLC&y22fn(t#oS#Q54=mL0`(h4C!KDa_mL^Rvzl}XcJIhp2i;LA9Sk}-VNe_3&VoQIrFVrA z+BsI3G!u8GDIEf6t;J9XiB?MQhPJwsZ|gR9d`gD`_|c1JV|?yJx3Zd)-V-ujFmvj8 zZdyu*LHnhGjvsN;Q+h9mbwMqniY2CORh!b`Ay;%tIXR{GLHk9*>@|DbDJdNRWHqpe zVFT{el->_uCG*&CAy-dJ=|~XcCyyBJ^prjT>7|q2g9H!!9Gz#SbQC{W<9Mvv=4Pk# zL1_QA4P*AuGbg2^fo%6_+v4V?bPSYdeKW^uWCO(YNofkG=VxTz9WlQ?rDLm!ZCXTp zQA$%m?HgQk;qjnbn9^|}e{D05uACb!gwdjujt92d@k%h@no>Fe+V}7vs{Na|s4PjT zCKPAqOY}Kib4n)y`5t*g80%V6npVxDNP6UEuu@g z%(bC$xH6>~z{c0wx*@kJrCLZohqwvbh+Cb~%#dVB#}ceD95n;Q+)dpk9X*IIVU7ONksCPrvEF2vj zYUK{WQKrRAk9pj_E~O>>?3WIzIOMKRX=%ug?#vA-HADG^@k-Hy9bvZ{PwA7OlZ+(j zpBXB3yBkyDG93*foQSdx?M|sR6xO!V-JDVzl<{L5+qfCW+>+9=kb@gA!{OGHmIH)F zGKamQ%WWyG0JcU>j4#4nd`c^!jgO6LoFDn{bBUDB0<^|(7(+_oQYozhu`dn=UoV-I z&JKx8ArgavTuQ4!d>d^cA2#*6LQ3aU)AifqaVe!WAifS~62m&Bc4*(1n;A=HMzklT zwSYE{+j#}NBc%>V-?fx&M~J;Cb%I$nO-RhiZX%^F5I<1*1~5f&cc;`1u?XJ)E~$bF1WxwlF}wf|Dm9E^Jq!~V7^4|mF}^W1_Myj zJG!agJ)Y7KfFEkD>=N#Yl+FzZFL+k3CsP^*@r>X(lRMB;DUDR2ks)&^_jF35)shx6 z58N{;je+=kKdbB;9;=>BX*0iAy-ba=*FBfg767aKOs)da!ti`bTdM^wW@Ne-QrZUM z$3)~?#kP$XQ`!#dd)&eb!ejSRO6P?FImct!!*S>3l+Fi>)(_kLUPI5!rY#;0`&m~UD0Fp;Ef9`2vkXR4*z(_v4yStz;#(z+Dfck4XV z{|`*-vjJ#Xy39PGrga&Bjht>oS_h}K6Vh59MV37ztzCg8CJ$~U()t{<9|eod?)|W| zE)N9|644!=*5^Y8drxpjq;*BefHzOOr5u^o7eIWS7I!UhN2PTofHkR&MQyP+eL6a= zFNTb!pB3dNIO2v@o?f!P3vpbeEl7fSFO|1x*p89e9}o1yWHt%eI44kI>Q7po87Fm zZUFI2TF~6&W~cQH0N?MJ5%!o%K{qF@@sM$Z;~UrTxoLe9#QM`jp!3qY5z+=FgT*}G zP^J2`z7^8+4Q+EuYd54{7^lr~3)8wOY%Z%E=7!TMf%w{Vp<0Zi`LxO*Q-c}(Z%(Tck|49; zEXkoOt=mJA8CYhy?P=`^NeHHhco@~Jw7w5yj6qork5?C_bq9c7#RdmZE<%iSQCdF$ z^eyk~VZFi!MOu5o`~>UZTE%lO~rI3{S3s9we@HS-k8>d0DkJ)voY%vXREY+4r;^s6Pw-5 zX+2cU)QSA+mb88WU_D-Ihd##Nt!X_RAQV>ETyZm>)-MCZ1Ei_ZxL8_`R3SS}kGMoy zzXI|+;Tb8qgQe1X6wqoFxz6zo%%t_}YHsrvig{#Oj{#Xl&mDG!w0;9+BfJ)WfUcC* z|QeL45n?aqZue))N6}kHUlAk=E}3Jaf^;L94|$vNx?Kf&JEK&KWoZ z*>IUi>-XTkckn}jTq~`oK&(nLXS;jS`a_`3CInAfPeWN_YwYPcdPBW0tv>>W`Gb)Y zD(q=JQ-yfPLYw!2wEhHSA6n;MARkQY*?{n#kFl0}D6Kz(*r%uUxrftwuKGJ0(x7`J zt-pX+>)Wxu+~OWh>-hkf4b~R-SXzGt@WY{z2_9`PkEitlsPCg{_?@)=2528^u6IwS z^&*sw^m$8Hx~J0mdo@REa|6*Po7~fBy#(kRis3Js($A#z4pCQ$qyZ4s&-sGN7>lF~|>8UmN=6oToe?j|tn{9QpD8881t05oyHGQ0hUrOuW zAifIhIcPM#oYrdrih7&n4kA4qkkNjCUOLhh#WwM?io>kiN89YFTAnkbIZ5g8o> zU{zmomOC<|cZM7j<69y-z@sucxC(I_;)&_#jNS$0+hY1wHoI(NpOVob{NQID^I#*_ za+Bvz&FJ0W#*y~sy4KbeOIzyQ@fjT&3ML*{Q^Wi=SCi3ufc#*p8^(OF!%fTRFfi*A z{D?CI-1Lmz3*tGpd2pMn&FF9dKblMjf&cRE+)8A06o~(18)jKiJ7;I~!D>2lLGR{d zbaW`qDly!}8EI}t$ArAzDk)O0oR`s*YKcfg?7oYm`HYSQwYE-=Uh$RDQ~*Cj7a{L< z3o|;dn$c|2qet{b8696mxdIa{odMsJ(Fvir$h(bOl2HwSpI~)J@B3YIMkfN<7nr@@ zCtg}hM$`h?=uk!<1G8F9?e28L8O?%>hAeSG5DJZE^zmvbTuj{N zjAmC$35M=lGdd$=;{mH@V4K^X(VS|wd9C&C{ER*U5G@1a8;9M68O;rJFCtNQQATyp zzNgIa1MSEi8O;OpR~`HYu>G4;R4Q>vM)Uc_*n;0x3oPv}&8R*=)PXA@VSF-bsFsN$ zp52IcWu%Y{cRgbWF5TrBEdcWU+O%L^o4X>Tg&>}FW{!4cMvWoYr25WP87%@b&Nb9G zx~nrfvzn!i@qbN5O#s&5_GK-N?%IqNL;GQ2x`W;m*mW5#3Hgu#AfmiJqon}WwAxn2 z6JzCujG9AHXbAVX@r*tRZ519tor>GqjTyCoSY_Hf*Sp;rwT3cS4AH+CaW`kw2IQCa zAU|`rWV8&>n7*trytmw%(Q+_fPqgz`p=~+fBBQfH z3ND$5tuk5#Z4Qe}@@%%*tPFJQW~!6P=xlzp3Qsxb442DjHKgzTNED9jDx-6%*urR` zcBPEgR55~%+kC5J)DC8y)!uIB*gYAo1uzc6t}#>r-5nWq0NGwKHt6}wol8bi7kb5Yjjn&*|pA(rtKAcg1 zHFwp8kb5MfO~Ag2oQo+JU#J-kRP&EgBwM^oqsq>5N803iIDYFF%vf7)V&t%$t%OFrUq6 zb4XXyxy{l&m(dmwjLrx5P2IHFy^_%dRhm#guV!>%C}smg|Fw)h1!*G?cOD%U z?CJH4E&}q+G53_VbW*a*>eC_VNYDDnLSUb)b^sac?M~9=_RZ>I0IOsz;dA%P>XK?v zxXi_>Ey}llR-Xa)BhBJCaQZqRt4l*!b51b3?E|y=EPx++_*my)Xw^65qD@-p98WQ*HPom?y#&b2eA3JaG^Uq ztIvmG@E1#rS_{N>L{?XXB<&w}M`rbfki;I|c}-?o9+lOVfL5$mWH~ykF9P`4h29D0 zwydrKG1k;IFLYD0`VyqKyBHeTM#KxunIn7D$lhK%N)ehVWcu zyqK2NHNc*atvG9^N2h1?6)^v0UdMY}ZC2M-Gk2`Vjt0qek2^W5uL65U+O^(hmpdh^ z>p-m~L@Hu>oto9x0Q_*^eo0)lXcnH9)%D>1JKd%leR@`32l0I{DgT_6)eV5w7_9Fx z;o0bBXZ4McvmN72j63FJH4fsd!bxwyj7Z(wtiBo2VdrVK(etvpv6>E7X1xp?%oDTv z7N~J{1r=6SyCJOwSXXk`TA0;M0G>-t9UQKRyO`C@)slE1_DY^jS$!MS+SG?{I9_{} zWOWOOZ~Ys_v939*?|}Pet&7&-maJ|C@_mFm2p*P9g{Up7?*iKZYoFzoXLVaOQ8#w5 z2u|q8m05ic*s8c-(vV|SRC@@nVrx94s2XZH>zt+?uQs0kF&bHn%pbWB^Rb z3Bg!aDF9zB+adil>dq=%h1(Deb9BY{Yh6|uVBd#}gQjwCR#`yL1hdHq`i2{_%7KSv zm2+HHd1yZ*>Tq}I2C^!I6n9>`x9EnlDnk3NSk5-YiDfveQpi>7Bkzo6RR*zEE*)Oa z>*waIDgZ|SL=h4f4EJ?g>rguz<)MK2HAXb9ty$epDqo$JR<}K?JEAUHj-3T-|4NFLbydS^!LQwv7n+>a2du4}Sd5M>cj%R`&t;QBB_s zyKA%hNi|8`idJ`BR`*XP8CXvQba#DLKLs)7g_F9wA*%;MB0LURaPsl2eg+a|{4i=x zoaS%L>Onx?4O{x$?yPDj@c-Zl}Af9tE)pfVl;uV1UCN=en$Z z9TIYlx^<%Da#=kFVqMl^7BidavO-qB2^i`)+c>51FqzfkV8&pczWHV)tKR}d^CNOl z7rCh$cYCsW0^F)RqmDHO-s4~_tKR_{d(Jj%?7dk%32ls?IfU^Gt(wT{_dtFgEvsv3 zb9ZO;R7k|86FF?SC#ydIdA2U%VFfFDJl<#ZbQRsiO>bb7Z`_yFA47qW1E!?AKdWaz zqE4~^xesLZr;x(LLX7VRvw9Z9TFExRFnTDfKLhwxptG;KT|J!DbJeVi%?#v`to{Px zN5FB%xks~lJ`{!aY)^-KEUUi)_;ItiXKTcm$Fq6?(AZzg7QklDlVw(a1M{4)3%h$V zs~16hvr#0o*Pb5tR91hlqNZa3h%?u$UIMjx)bb|kp2_MT(0)#`@tDx(*{og$vsrt_ zO!r(?{|qU*21m>!aFcsJt5?AMe8Q~Ry^z(v0IbKld%7asl^3&mHRP*Zj{d#{$$TlR ze}j20v=MkHtJk29B%60*_<#SednK#?kk0eD8xefu1eVv!tX>DVar{38({!(8^@^9jy}SF*gaw2oZehb)WONh?U&QO zAl3?07!bVW^p-%QLD1$7$Z5Yo&t%Vc2j=uv=x8|OXw6P`2j#RsP_#ee1oGgV-UewE zx$~xpZ%^Fh4$0|&P{ssdxt%N9Od-kP1-~-YwiwIUNjQO|poh?&zG}1?@X{Gi{iX(;=aliSfv1BM}>O zdUwcFbHWMJ-SIgc3LP}D2=u}UC|Xx)a(Yj-w8gCp+_any3ps6%b<=ZtFSLzd(=kL& zV4~F8oDL7!%-(Xuot)GA0DQmlG;dler{r`*NYsiwQ@=Ykr}tMA@utIbjXN!;BSWGN zF5P|Z^qf8b;AflHYeTq}(@}udDQ9m$6+fpBR?`sWjGdWKL^&M|XpF+`*N~f=(=pJ# zO5R}B&C6*Dm}lNb9vw3EvK=$hY&)3lJKy%R;B0oRt(Ng!6+ z8Ay1e%fs@VriWDXZPV^?D|4Cw;@6X^@19jT)q+~_Xhstic6ClOL&nHKRJU7`)5#%; zS%I{=wK;tVz&G>G&+M%rI?L%4AZw-=c-=XDIHbUFTeN|#%jwim3MvS>0oR+;M*xg{ zGg(^j;Ibj7(?TKW8@v9TJ_>2Ps^Qe`268$*WH5zMlro2M`dCQOGl1Fqa89$JZHb$? z(2eHwaVTHSh3q9*Eao&jWWY7csN0&;86m^KR<}K;IZ&QM3v2_&I?|MglhG z)C%S2$uU#i%{jG&f=moU&;ncOZ^>yHsPAEWDZ@o;PRoJ(3i?S?MdS2@dVNkSLV3+~ z^BY_&rC0)+`nNnFXPogb{`ER~U{U{6kKLxFbZ#S4B;9o5Vh zdX1D(WA^6M$q#m;ek0OHVZ?a$b8_woYsdF?R72g{+xOteY0>m%iY~QkW(L+FO&u7!JIZg8#mjVTN>GE9?EHB zNI_7h1@7UT`a_DyVRWZ^B&SUvo;4ysHS=f_x~%TeoCf&8#>^Y1Soc^?gVh4K2KBhd za~cA%mNems@rj(yg|tD{I=`i{ISLl}WKP3?zLWYHdQasv0${B{YD;)!M$ywbjRvgU zoa`=L*5;ncX{?$NPP%7v+6>^w6{}N_d_9-b7GOW+qBFM{Z#YiduJz`;aL7eX5c?!5S}i*dr0)29H8PqlWdj0}Wc&*>sS<7IQboXhLeA=AY8 zMtiu-YX^Xp+TLDsg4;K*i>nEy%$nl%%j*&VD-|csXx5s1d;h#X6F^g*K~;d&^MJfA z1+*T(yvoil+uVV9eHP4$pJSCiD6h+)tn4#{g*C}d)M9*Y`l z@S%BqE@Z+}%<9?hu)Hn@FdmyhnsxQzd3_$p_u@KSUSO(Ee;tw66~Oj=JmCzxBlG$~ zpwGF0`W%(lm4TiZpE|`Io!1uwZEknnl)SEjw)$F-IQ-w|^(6q~XAS4*1y)&GPHGdtyevpme(~Q121)MdR||d%rLISt~Rf01HFC>Ww?{``YN=4g&81N5AJ9D zLU&4D*YS%L-Lc-3(A=qceGSB~w!9y+*mS$o^141G8{?gh;dgpoUk9-&*L9=jmDdfB z)=jL?yk~F;o}Je>z`|JiG}5fR#sh%uRqK2=H?MDoT-M_zR&?|7x)IE3WO3?Im#fd~ zTOfym{I6pg%ABGouic?o{2#F-EX?bsQ0xr)hu1qIVCQu+m~R%TBK@7FyuJ-+9f?Ft zZb@FZ1e)cu+coF)9cbHR=G3{Cyl#c^OWUF*bByZR^7<~ApH&32;J(g2wmh%fK>fJk zB8(nCp&Q)FyuJr)Ji|GgTa{M~(%)wmR3nVL)p^CiqdvjBikYz{uLMXmT_VL`>!`JP zB>{bPBAu$uXgU3ykSKpP$$F zLrSh`_Rx4?UUz`lFkC%l*6JzlqP%_(0OD+*BDW*2y#T)2W;AT7n3v>rC!l8>_JwGm z*wgK$c})OY-RjYbVZdIN*Igjd-W)70cI9<9knb9FHu2)*F3;#=UIiyt_8<#jKh6+eShj5&(9IF%OVbM91jkxRbx<8~cji&4K`e`69m~)=HA+HA@eFaRyZfB42ynYtaU`6C^ z%542KZo`kGaZ45nioeV&&_!~#1A%krnk6T^7;jo^+L^wwn*NZ*TVro zQ<25?w!D4`;HMJt#8_r{7LDcgNEL16^lX~aE|J%-Ks|$5@ok)?@_H1^PbaJ@xDQ7G z5;J-I8r&FD!!0|P*JF@Y|7|8xEadf@YEkne-56KO>v6DX2C`D1yHLsNw;-M~i}B*e zU~_x&dIB(7$9Yf~b$8_Ty8uj#FPS&r?ak{+0AJ58qEo=niM)PaO~m7dyF0I^0PJhL zvaav!aQEc(hiZ~}98>Sj>*-LAz2Ptndfa_^{SnOC)l9$KpVu>x;oXGV;N`$fbK&d* zdHpHmj-;V>!hJBWXTj{FHS@M1FLDp%^=A-c3^%UZ+{1Z22W_px2lvty?vcFy0uUWS zxEWxcB_=s&pnzC;`me*fHX{dz_xX1H)A<(!XTkW36>u=EBj>f_Va|@aj zpFf$`i~MGFGxN#s47jKA`a6i{BaSA`_rTM6y#!|MpE<48J(JfzAgy*2<2@WG5Mkx@ zay8d{vqA?JzHYuw9uy#{Fv#2q7=VR`*0{M^^s<6h0{^=cvFvBmGeujTdMDop%` zA$(}@GW&X7ZuMk~F~T$JFjvrspj=2L0+Ak#FeaD)2U_oyU3DD?r2NkqGq@Mz8kEVz2 z4ld|zfYveXTez&5O<0y*Qs-SlO z`47}_owl3h5d|FtXdl2-p}(7f=Z-AsonSUH+dHOTnN`qHAqnRK z?=fk1K_3M3ts;0U)tFPz(E)02ZNrh#VmG&-V}SgepLSx6n^zEFI{XP}s;e*P*zogG z0_QAoDrhQz@ptK&jSX&LLB~PcR~qLvHZ``LJf*tkf=&$in1$M^f3VI5!RAkH(b!HKu?UH zeViLD=;P47>YeyjVfbt=Xf~LAm4VzdY$rsN?h87jnzGA#nA~2_958D^EoLFS8y55l z0BdzSaQ%Q z5zv}2DyRv>cT03_x4ZMT1uX`(8koV2iB_*G zXbF(9qi-XABMMpy=~qJJ2bld@r`=FcGq8QYl$%&v#|!%8WKn$s=32nrSWpX4G+1_S zWRmPIs1?A;394!?;a?q55(%c#GJc5SkQ)$2{o(rrvCR( zK^sFR)17BXJzP+K$iyXrr@?|YL0dy>%~JcwnUd}4p;@92jbhp(IV1iPbu>RuEoY6Jn z_9N6pQxd6mFjXR*IOM$Eg zy!LQWat9XmSrB6yYQVR+gNnKg+SiD3mozlFgNxb;=2>8|R7S9wi`LLXirN)&+dGRp zw5ZQPM{5r@qK6fAdH5L4{7&>PsO0D%Oc)Be+~UzNo9g{c<#7 zC)21iYl`|ZaI{eD#GuR0c+-ly1}sc`B;4G}-Sncq0vIuD$KLO{+M=$7_Fu+?dBB}q z)K@`_33UjVPATd-NNcn?kR5WT7WK7I0zQhG-DyQ#4;}SnXAk3x!&FgU4|%9Li@>a+ zZUC^=Wm%t_UDP+A>Wm>oyWj@A@igH$Pd`YKOL=B8WHnqHY4R=8RbgN4Kb`n*r?W7WHm) z3>&njqP`7gABj}8ux2dk77(j)2Tz*KMSTa-v(|Pqi*nUc)UAMioOw?+Q8hSY74=K=thewL;JRNjd9!CTvP?b22J0&ZfjAuL-~P^c3TuIal~yeY7emQeT3`79sI!D zL&kl6QQv=~MDxIRVNrL0_y+Po;4Uia2LM(njuyjiM^SsB!|dX^Ys&MkJ9oW23hfGm)^in<%n8r2MdjN$U4ehA|4Sp=13cjM02 zyUkru)II#*KaKCUO+C!Ujqb{#egqsuG6Y?+slc(~s-o@%_ZAa4Z?=O zPI^sI_l0z|%~+DN8(mw}PpU;CsGD^0cU@8UgWIUA3A(xN`l5bXO>2q>X2;7iazjxM zfEy<_NAq&LsGk8?eP#@OH67xi;~wXX&5CKY#c zQ4fJdvmS-WH~cx>Qq(U(=@a99n3IgSTZ?)a$nP^Fy>X)F=OtT0Hv7#P< z_Pr9-faNJs)UQG!^hP<074;~zHRcR^&3Boiehpyrr=M4$Tv3lfM$^@V+L*GqLQ%g7 zWtbB*S1RgpXx|^L{id~EDeAW&8@me{uw1kE6!iqyq=e18edaWOM^V26_an2OO>1va zPXbs&x;oaaa}!1V9@<6{s&LpQxx0&c3dFw1TU2Cpb5Bu!2$}A>XySYB-lCp{_Fs!E zIH^AEyRWD}R`C#Bd4x;){Y5|`5^&F(<#yUhdgz_osFF@8Hw7@pHM~iwM+V>1Whb<1Yd#tFx0@{~m zL=w%%i+Ujx#NH4&V0xmczlDqznarEQJXzF>AsyFF9w)lpQ$_t9$PW-!(~c2ahMq3! zB~bftxAl8tLQ|K3pu%i$(nx&~H1@&B~Mz>v^+!y(o8%{}x7j4J{Z*mh>hN z&l5x#xMf5bzE4T}gmg2aW!3Fl(wjki|KS{?A7!nQ_N_vUX12-wOL_}XG{Ld*;Ia|9 zv004v5JUZdlJ*Ow;=sj_150`)cZ-=th<=sHKtNy9%`9b|?(mY{0TdOCTbMEP9&eQT z8L(P3qoXVFQ6(J=X2SzxSWZJnm-H?GtI;`UOmS06It0>pAMs)EH&N2NLk@(3*jpW6 z(xCxBpOPK2rlj{&flh1(rj>LUfK7#!{JH5Ry%*Z|N+n7^c2&LXJ5l9nCMko{aBChl@>_(B zWl5)k+2`h)d2eq?9|<&;eRXa_NvATGAOH zeh}FyfcG_ee0xcALTR{*z%Oe_pMbV`F~69iEc81(t4{2l0chDrpg<@wIlu!oTroS<;z6e*WR_ z3TZ8pn`=sH0*!cyu)wG6OVH@m(&(Y zi`3$7DQQ`?v=!#Zm@K!Jv>eb^;?7$cP`8z|0>qD=v4KGsD`{ml$$96^nBfv7odq(v z!n0?MxKv52!2CEIGdo0=Dd}t=<8HJ~yyjCdb93aoy`kqaLU7Xik zsiZZazABtiT&1M;0L+Y@4fd3@7QmQ4qhqMg-BD6Upb0Cq&Fw9z6WZ5wop-G^QBqeG zBTx-?%I@xxx~usX^tyXW>VY=4u&Z*Parc(A4#eux6>VSlm9#!2;VNi@@&1x}K|BkN zImVudA1J90$a-X9qkFKV4IxY9!yTzwNgF}@#Op$F)MmrOCG}T9mInf_6Z*TPO`)XK z1Y#^{0Lp)Aeg7cWwZ}>t1hOi(cMe+Uw8u*t0`ZOSM1hOT{u3pg3+C@X(G=!o-?q&s zOB&_}-vd1Z7#!Fp_*6+Fpw?`e+WMrFO;+m#6H`;q7hf=FP5}D02AX& zkp;a}(s>~dcL?*Q{BlX>PnOczVP-t9lym`zZxWAj!BbdC7lIngYmmrzFYvFG^r--{ zX<t%NmVRb-Vq_ zx+LW5LsWg&4!3_CGN_{vN>j`F5~$}gt8pEbJie@}!NRn#m6o>Dl=WpmUvoSh1>w%LvaSI(KJ=M{ zX?j^-f%g5;#>+%)S=WXHxL)AxvaGK{`yt%fVXpzFlyx1D|K28ZyuktB)Uv(?=y}&- z=a$pTx*o)e?%?Sd#};LMJrspKoegX^tE?M0c^G8K-KN$lr>&W z##s)_r4eM4bIbZBu&;=T9T^&KURgH+dcL7IKG0(tTJ>dp3)J(CcLkfBDr+~GogIFNhY{9^{-?fx=Yc&Z^ldi3-?*^dOL|krpS+`a5)Z4&ZS=RSJtP|Q%KW#<>byZoh zkf^=wtY%!etu8AL;<+)z!eSS*HDx6LJ%dLEarVy!*yYxil?=H}L6Uy&EGq?KYwtA9 zTxF%9tR47JnSZ8RS5^kVp92UH#UdE>RBu^Xa6dfeo&Mp!M~Wo6w3V&7>udRJL@Lwhdr2C)P` zH1?8rd09UUISIelNxxlD);%D$!qluAa95V~Bgnw!;SOG4t}5$ZAV1W2ymMEV^*v6}1!vNo__rwQ zAt29Z4qY8Q+uc&uFTm_8#4embZLF+^0X*YPY0}+R)-OYn6Q>aM#Kp>b1i%_@kzQP) ztX~D1V<2{qWjzY*?}$utFB!CF=}cL_4n>V^;?>6G%6bgI2EvvuS19W@;b*qZd9AKg z*5d$H8CqatvQpM>12V%@!nV0RWjz664Xx=Owt3?2DC>7XR>8$}EoZvDWjzV)8_rT@ z6Lq4j--B7hdn{UvySuEX048Ug9oKn1+2-yk>kr_bk+_RyaNb+i(;+YW{gMWEUs->w z=EZ&Dqyv=u%X$XfM%6iIPjwHJ^(RPMDv2mDrY*-%=0(^4WdK2+A91HfXz z683Oe&jDC_diuFkKT_6TpshW3?YQ$h6Xm_T-J@ka59VjEdHprL&&SI8YZWvfFvh~i z%X$IODz$a%R`*0%e}lBb=hyMj_GDQvLi_fP_7bzfJyq73})a@~2$-kaS)7408r)|XB0;ELV`ZOxd$sJ7=-cSuDCgf!?5 z;u^oAw?i9W7^=*|(QWfNP_JiF99GeR{A9HxaPl$j?(mA<0bmWO;h594(H&9IL7_C9 zjdZvpD|%;0!D2SZLU~k02ZutKX=n@`UD3M$JZ~3wFiCMrQPCk_c5qzGg=%=)ics6B z6}_7u{BgqkKwy4|lh%q31@%h`=N4Gc_efflSFg*jWFs->t3aaDKO@)6h-Z+{qQaF97Bzcf_4i(GdW?8DqnUF+1I<6}=xU zdXs34tah=5F*WJaDms!M{48qdGws6DEBXMCUtost)ilx@85+&1=qPY&@vLQpis7k= zIX}Ci4}#kG=tLjW&8g_gHB-474BJ7fjj@MoKC3Dw@JiesYdto5QH=>T&fI z9SiKgA8EPU>+*i5nY(;qwt>{D$TX5PJwz-yyra}51=HkND4dF>!MJIt;>74ly zsZ}%`+H;$Gn<-4LtY}6xr&mK{(5|YeHsr)lZ_cf*Xl9`CO1sXjspw>A>seL?X4Tq? zJ`@0}H(LD_odV#;kQX+OxbBKR98&RM#$9J!MW+Hp4TEMK?ycw}0pT>dkomcxqSFF` z$fS=&q`#t%f>`5iuNMpEkE{N4( zF}@tS+(i}D0a%^;)^BnkH{w=b=z9wZDoY^S*dFgY))sG*vW z=v?>~t4JVLmtNe8RkQ%gxH0RTiCylBiWWlq)^XsEOvA6Ns4*l$OCsj3s%R0k)vlIE zA6Hj&X80L1N8U6mYJ&Cy2Xi8G=X7mFi@|)GyHK-o*HyHnnhGQ5ZtjrRSF{w&#(Ztx zfZ2q)8!BoBGS<{EV>yIX^hp5UP<*_Q$PP9)R@4G)4XItvTiNc4T0^oLcCUeu?BRJ07hK4}_a=*+rXD_S11atQJdC#F(X(F$N|^$@Qzv5HngT8r9wI3;9s zqN1}vtO`75t#hf0RzdqEGrDnm=P5X#sOW5du|{D9&UToqXmuzIr+~Ll#9g7Hb3m+{ z&YtN?6|D&wSV{}c^Zg+bsS_^HJ+k`{rJ1Xi3WEUpPdn@XM^lRbz9#g2D zsHh9bs$gymc(1Ie8^GGLtTD2IyQiX_YA(!lIL_Q#(K;X-9$vZ0f-&A#(Rx7pc4O;O zcYj5_kiLUDh6$!MY!5LHRMZFT7o8CtO`;z%>>jLWL&#gpssEvhHbVMgvKSXk?%|61 zLHvM3vKEc%M=II`XzgK4*W1hTqZJJR`QlMn^>Wq6DjEc}R#qG2QJ-6TOx+J7R&VM6*S2Aw@+x3}{svWP)Kj?N{7V?{r7495-yLN&YcP4f=VVZl$?b-!kJdUjY4!vEU`yaf$dzjW$`Tx5@ zFf%hVGcz+Kf`Q<{%*+VMftfc42N-7tL`BCr!r(ANb3njDW@bWWW@cn&6Dg6A5vdXS zoX^i=W@ct)W@ct)W@ct)wqN&Wt$F1*7SxV{v!;5&qi@zl7k2k>Wv@RCDp8CMtA zmqWtb*jb#HXT)^_fK|YriA@>9&5Y|SV7^-;hafH%*LEPQc^!U`7_BG7_0>?48Nd=_ zJFXi;60SqHaFsbJuCI-kgM~;pMV}nkO+aBDV##Pq1E<9G^-$F8j&&WI+?=>>2C$*n zh$_?ExV|x74!W>*)|nUA7?3fbZzHFS)8hJOC?ax#=H|z>BNQ=X`c&5t*S8?8{tUJa zY$b~8mXM=m@WOg@#^Smaz*^mhrI=l`m&CO*EQzn>c-s#C11-)ok_a3RD~8 zx(C!c4^N`eJKCnW;BKo?hrq-s$LUU3Dl~J#`+X@ZCqt&&-dB0quauDaaF*qvh@Rzb2E2+ zTvZ_J3U-uTTzzkd>)wzkhS}r@a;NQa{UnstZYr~8IDTVX_XUhWZXUIV-A!@*6fD{> z`Yja2&2ily64|@qP}h1~P{j2!FdKVkEpt2KdLU%!K#bAtZi(yX09Hq|CPvMd&d#_V z1hSPXdTstJF;BY;t#G34)v>(`LuJ?ov+p`0Jrqczx6X?Q1N z#_x;kH^9*bF=kGV_s8`ZfNz?q3t|fy*KdLRWIf%SYbD}(9K`qA(vHY2e=4ruf%(2w ztINdoL@ieo?>raR??IxXBmIXSSBUG$P*8j8ist6!Ep4t8*B`))_tR#%N?cDtS#xY; zAufpyxcA2OM_|uZ&MA=$?Y_942DHYYT)`#v{)!MOfh zOBkMC-9vFb3m6T%TO$>#qP_XM+GIh@CqI z%)XVA^J8&6&u{+w^%k<6gI8RC1G7)fnLOQunoq>_LM@d!qvwwOWL$p-vz}&AaZknd zVn|{h?d^Wzo{sAuU=a(th<)asiR&c*;aI_?es8QUX23^)i5cxQ<(`*+a(l zuYjN@%#qH$5Z5ap_SyCYE$+p*{tao}7()_(pvJuv*Q)`lTjvesUykcPp%^T_s&RWCMVL}riEq`pGNjWDb zbO3Z1c6Pg&3V2?|T^Mewa6q4BP4$}@!=s*xZa7-R#N<4=o^u`(}d~=#} zmO~Rd2+$AcGkG#h=uObp?q#h}NECN?LI(pyoEh5Wj!5XuAw@fJ2Fw-8kqI3F(oGi0yB_0CZV?i`msh&AfS#${;>%i25#RRUEk-9 zOXzKoQ3oPv=dL$7p~FFy)odK6B=q)>D!ViDL*8VjCUgXduY|cUtV`$}0hrIS zIP7L5bmVxRTXTCdNjEd0cY;KpCLU)jp`&U=2vh455_%Vaag49*b|)ruG_=3+q2`G0 zad?J2DWP|Vl2)|VyOR?-268PK@$vBg%YW{agx1@RJ2f9uxC!J0m(WyD<1Axy$TcN24caQ-VJ;)0tI@KA>Hw{3 z*<16U#*t%lLeoKfCr^t_b1ezYr~w<+Zg6c0eIVq)1gvHG0=F`unIQg9(=)Da&#in_ zLbLe6dcTe%@YxB)YDFzEm9Ka9JzpO?@Hpb?vq6E2R<4Cg2G!2n_&g@V0Z zIyw_NF%&q;a>wBk>LS0PQOmH=gPG z6Z%L1E}3lZlm`+z1;E!6xw@ZL8xs0xNOn%-NMk6WIkjZw02b@eJ~xuk$3Xp5MGo6F z*pFA%gyx34CLzLoMM9?rpgA%_*^i4 z=`-E7gfw1+J*T^?6Iuvh%${RcPZ)JgLW_X>3dAco2d&5<(zOXK2KUpt^^B(1Z8EM) zXbHb~?nJ^U_O|O2Ivp??gl3-ZZb+yJz%Q&@E_B-yS~{L!tber6-I&la0Dpvu{H#Uc zL~crGc}O?Kd}z3v6KbwyJhT2RHU#c6BA-I35a0MRPjKkDvEXf>qOvdx}zye^R2 zm(aQ6+3Z=u?N8{u0K_)iHQ}Cw+5xOb@!Dp=o?RlL^MQQ-;E@2q9IulJb%b;=FJf?+ zggOIsX5;)w0U(!97mziTXC~TSNT@rcX|G?fz+4ZO66yi+GYd}_xFkiyT1lukBxGrf zE@1a2v<4_z6c(Fr1(O@ym(W^3&rICwx%(691MuU|jFy-VHgz6IXdSpQ==kGf?!kmE zfb^Zdkj=XbYs-ZC17@M|qVRYRC$t{S7(Z?L^pCkm5*mQElM&W*k0vw-<+;VO$06>q zgf@giVyHbf+Y8v^34H?0Drvg(-R_Bmh5$TE@nRi$DStAdVLw)oX+Ywh2jHUMt0%No;Tv zllpXkVj&3Nfk|BfWPO6w#X(7Z2Fg#Krcpwe9-P#bAf8DJM>#aw3+^FFeHPSDWZvP1 zHY1Wo=PRkJYKb|~+0r=T4ohllC^TkI&^_+(q_%~zW}6-MrzUkhpjDhPwcgbw_2rN?H)bnj zq%l7usT)8&7l*N1cQcdv3WzOpKF(~|loh_#%nPq&+&)DGw{d;5p6dTB`NTeV__E&i>N zx&_34y=!x1TD~Z$TWhIMxBjtPlGIKR>!IA%#jYu-Z$ld6aW=*?_y+Fp%aYm!=N^0&riLDLVf_4cElJ%5>{-uyB*v9VeK!(T}L_(I-?Ep46Mn>K0q`nX3i(Y^?9d}+*dqDg!#$D<8N&O%cP#3)}bSAYIz%vPz zT03GT^+TY*5}JorRc}&vgk-F_9FT_G+NAERC5sFnhTOWO?y6y}ix(~R~sW`NCQX@ezwd~44%Pi^kfq*9@j=mqt%q|)QGsi9q- zR0i4~eeI0ElPNFdxMoc%%MX6`G5w=wmn)OX0s4c*|Kg1Gs-*J#;y>LSDUxnWssQ9` zcme7ZF#qbLiXjRvF<`z{_v-S(t@0^%EjcdckOzcH!%0E2;vm4;!l&2#pjo09q|zxnx( z4OTdP+?>??z+nP#EgDPeX8`u8Q}Nh}sq&7b9tcTLUE;QLOHw}v@Y{Lx7UR$TJCk}4 z+}EiaF}OKl*_G5U0F8x>7Q@62TS+|>3N)43A-6lJUxqZfu`?{PfV(}ZhXd3%WNtNh zhfL~MKsIewobL7}^++v`-EQz@k<_n&Z1B~YYVKW0JqqpHR^PDF?Mv!605;fW&Y9`< zC-oSlX9;J35f(+3pnH<~Z72rWbG=I>^*FR21g0yAAB&`Z2jn>rOp;iAT_&j~LW$9V$AbGQcnW=`n55vOG*6!z<-J8Fvz$nNj(MR*8+}G_a^m6 z=)hx44$aZSeMvoC1Dnl*777UT-t~x=)+0<1=I#bA1fjmA4%#t5bKPY1e8qbuOU~YuIjHYk0tdysIU8S z!Wt#@H)uc4+K3D}5P96Ev?r2!fnThAG)=$DJMoiA{T;+lvjsGXW8F$W2bg_hnca?_N$MqN>*D#a_}QfX3F$ey!n~Eb=aPCE$aAn6qgs3RdOoRt)zYCH zjdbsYq+S8CI`I&0f|VDO`ZtKL6K~_TpuCjSt6=^d!-_USkR8;(lKKy*u@zAR!}*n@ zUK`K4mHpBTqF+twzX3Cqfar?&T2k)(@gdPYIO<$VZve1wwvUHgosiOmfSG60r~wmG zIsnZ0&`!)-cVJ2rp?zHy`QLH}r8FsEF>_mJ+CB%TbRd{9s69BhKP06$0$Jr3G_7c8 zbcd#NP)LJl0WCVz!BTn?kg>UwHS6${4u&js@ILk4x!o z0qEPr=H@1+bU1)baJKwfoQx?cy&c%v%%%{jf=o^62q0hf;1*Yx(mSB7eeDfBZbnK+ zLPlJoSIjDLW=ih_vX-HuGdSpCDIEo1BO&&>9qtJ!y$jR|jzScjn9|YEmd)I^qi&zl zy8&#NMGsFLw^BL=#CM%3D6yTKlG1xZD%;ypAeocWu^?7(JL{vHo6>ust%|&4Txj8| z=cRO9fUp{32JtMJ((yok$-@c)&*yfFn4i*QU~6vAFupBPdLN`8)W$fwIXk5^1=OZ| z&!AhB()*$O_gZ-_!dxd8faBI-~GA&D~4)8cfZ6g`Q|NdXs zoYHjC8b4Y`Y;og|+LF=?urP_E`NWYdr4IlaOBnDyZe>a{p`*cPZVKJ1lx6`~GnXT! zK0Botq;Eo7G{#n^G#kiz17Y_dV)ye>IswEl^?V<5`sh*T{FFWzGB=ywH{ADirgS2Z z@3;-4TeeV#?vy?hk`WXpdUEbf=_DYlmg#6Wy0s~N7{E8iq$IS*txM@-Kx<5HE808# zDSZUm*Npvp$PJ`)3W)EeVU%51&~bQ?(nmu&4i6WwpADrn2gIsn4_Wr857yV@QZ!7t=^)JT$xe> zfPJ@>z>V&zlp3M^VuPC9z~F`bJ!a0bEhX`TAKbkEp*w6wc2}pg5ZH6B%@(0+Qd$J! zo7O;lfooG*4B%^xGADMsV(HiV^DNf+?CP_AR86<qs%X!g6kDV+`EIljRj zukJ|c91!0oF1;3jlWBZcN~?kW5HgiX1NWtLZYXekd)}YYc|bN?XS1%~lTtfmG@`G~ z+{uXkp-ZH6KA4RX;sP&lsgybbJ&Q}L%cRr^ZJmOZ$9S}*TuNP_zFu8}YuHWgdApEO zH?VI20n|6RQc67_R{UDz$F7o6FSO@O6P9!R?%tHv)H3yK;O25)N^3#vn^D-tR&%i9 z?oX*NWR00e&)&`Mft1z(MT~DU_iYcRbOC^UZh6b%v)w}}^+Q`pOZ&P}T}B7H$32|V zdQf9uq(l-OAs$I-0MN2Vw!)95Gze{NX%}`q4eqg&Hh}m>H<@9>1`|j6te1Q30HD`Nb9^Q81rN*4oK#m`(Dc}8?Er*uhxT3FYu=vPv@6v&1VzK>9cVQ9UY z(kH=;TP>)Mvp2q$(q#c5!U0a_oJ;FdAXcT#uw+77mqYqVhfsPbGTiHS6Vv)MxaZ8u z9>N&29~_w06@XSV-fbhR&x6wXOf4P0B+!hw%^jT9l_4FX;>gk5A!&UU$iB0zwSj}H zUF_h%p=n(OZq48l6ZuVWho!X@%$hMe!0_*Oho`j-#CM#yY#fo+=Ry)*^Xy1-WLj5) zSi5=|T}P$$c}U+M4U1cmgD+m{j!x?u(9i(W&Tz-1^#z~_@SVkRMG>>pCFMdQ|Is5Hn3l>q}rZXc*p`-PE+Muccwfv50haX?+>Y3P;(_ z=KYMcZUC`%wWENs(alWjD*!gSkB?kgChctDVrgv$ww#!n*cs%6w7v=w>VPZ&7Mz&Y zjWvvsY4^^P()t>hv1QsNGu_E)-4w_+#3HAp^>s+A^5tdG2E#Qd~&fcq}%W`$`;>stU;6AWdY(z*rG z&tt52O?LtwElTUwkZP!Ji(8V`PDtNOT=rPgo6`C=m{pnxJELw{TDzeAP{nsiZE8+|KWa^~CrU&3(8jvuO$~HQZ(4VR1o*^W&WK*o>tT7cI(o*3)~NS z+o+-^qyDsh1Ztd)nKKKvRVJSsNNXRkeTCZ;FYO!B`f*4X?X&%n^u-OOwIA5piGIYu zM&5x((z+YSf1kz3{5u&xH>Pz@NQ#m+#_I%uOe+p#)2n{1+mcoS%6bL&>82ulaau_b zKTMV_U+gYTD;1J3Nj{Az^s=s}CJ8piO;8t`MjJ*}Svhy@!F#-O_~t^0uN!*mRj z>87-P3Sb|KwM05CH>Y(!h-dW>k@WBw)WwQ8me$X}{h)6#N58C9JJNap(8}Yb&78NU z^>Y9#&xf0FJJWg)#3q#aaW<1Yw=1n*fLUdc#YN9*x25$EkY@?|joY2pF9ED1(?`wS z>26Q!VGuuo!^Ecvd(!$Pnv9!L;-Idm(09N+#ej@El z>o);GKHb5?&Hl6=1Mz%dYwO$SNAW#r{TAGMJ2$qf*(K6?yq0eM>-IOPw0>8^&%hB9 zmq(ignY5k&w+SC3P$9B90+aF)_i$Q&sijyj$kO{rTF-&_uCn8b#ho2; zkEZq4kg>gG;e7X4TF*oKPH)E!;Jb9+V07;{?5<7 zNm{YY+Z8{R){CIN+GNs*D?q%ZMoaJuX}tnu1tIP^-MyIBzXM%o&PHBJ>(!7Yw-xK?fnN7=TK@sE z+E^%O*3nnedMzL^XcDBgnd>{x+ZVWlGdl2fsNWoj9g@)- z0~EtF%5M3GW^@pc@%NJRO&92}jNTLgTsB~Qcz8w!14LZeiq6y#8NC@g8p>ll+nBl6 zkr^EV=7%!zCs9@B{{eSYMsEQ(_S7@!c%V2sqeDS_FVhmXZccK?Wb{^0`vy-;J?_|y z4h#8mTV>`g$7S?35dYO^d&J@~qr*e4x~Am|-IR>p4(-Q^#TuTP(Gj5--ek-ZQ(Z>y z05Lw*F(^&3Y(_>$2FN5IcJP^*(K~^R`@_TDx(=8P0V6HwPo}H=<$Qp0Ff`z zJEdc=Va#YIKUuxn@Fv*mR%J8`!1HRMUDVFbCRu4V2D|P6V@0&9)fp{jNKs4}pXgd|djAZ?B9_ z0=FIhywz@PMjwXqbF;~I54SF(lYxBku+pOD^k?)DFl*W@<_>PXGCCyyvGsVZavL)G zD1hGnJfrymLDXpH zohve00Akr~%Y>)AIh!>urO&Dx=04I5K3a@)$T~BtXwU+d4bk)fp`W zvRV+l*j0jz4oy1EC0tlb%%3F4Wzh*w**@-tcm6dhZT#Vx;ZpmuE8lhIlH6lVEm^Vfr? zuZ+$HG|t89n-{w~GCBv^kELH#yB#Zb;M9q39%y+Ah6{}*k+dox-C zZmh9Ts_wpw@MaZigrsWN-JcQGoq_*ofN_O*Aft6aaWM8! z2CsMHwL`}g3p4j{MhvOw6MeSr@FJNJQzCrA9$<#uqZthX`3AFC4-PF2_r=FD+Q2VX z<90JFeLSO2jA!0@p~XOVPh_y>86Q;(2s`p*M%e!ZCe;rNjB+e|DkD~;=%aPsA%J^2 zqfsE=9UHkSx@R)l2x1?@;(pjYo6&{Pet0b+T%xJWKbO%az^Dthnj->k70+jcTZNF2 z2NeR64Z9aI+5+gO0UrCKAk8KRdNHGm_`#2HY(C-KOBr1ZWM5w1($wHy&gha_l7=2^ z8Qd!wT^f=s#UZ|XHKR{L+hoECCS|;q(Pbfz>CKF;A7EDLQ$U`t-F_P}#bq4sXLUKh zSmjvX)(&F!6Gek|6SMksD0Y|&9)hr}t_T39%!cLepsYRv;KxI7@W;?RIIAmxjh#F_ zo0#g5tUe3k+lfm`M)sjuT@?~V6F%+^%W5l#wVdUn!yTU0HfTR}ko9@vrX#ZY9H=$6 zJ-T!rnbp++K$)){KNVSh9>BWA8$VH{qqDjO%$D7{4T!(8`a($3z{MxJlOLPawP04q zKAvXGE!%NfeG$m7Qp+0K+~lmT3uy?+N(>{k`?LB|CF){@MgZFM*? zs~ds*_*$@bh@&aqrr4@Z%Ia(U;8{p?juDi*H@lOwx(W0hQHhI2MmBJ;+t}YT!iCy& zD0#Zf>gy!%Ys=cr7Kp^n$?9e>YDb_Kw=G!Y8nXHpbl{A6Ur|=KfcTHEK<^(>#GN^0w(#>AU(zRrD8=%#I!;1NYXv^xm zAzypsR%vBcyFiYn;S=A4%8IClC z%qu!8;dxo@3FXBaxLia=$>(SF13=$b2=vUE;~LkQ)n3qO;7*_6y0iKrWW=1i(7TA| zFLS+F-2vvC*|xmdt*B1E<0R|SrCFsQty$=YA#A=Zt2BTgDufR}7eA{^4dIOp z$6#4yLHx9eJQ_xG`^v0xz`jAt?cD%3{8{C}{9r|#4YVz*LM^v>d2X}~$X%UPv6gbU zZxfBbCaY2nLMBWrug$6q?VhZD1!5m!1&z7ASv>-6ERgWX=I+Sq z*8si;n@tfAO$HRhvU(KQIK$a`KNEG(?aS&nU{*SE0|ftWe^!ryM18Q8t4U;;e@|Aw z9S6tIPqtSvm&oezP~I%l`7$>7>Li}SgS z`9fAt0$D}u-pm7bDXTw#STlP~Z>*BlQy~-D!C0;gxO=nuBak029Rs+&-~@ADR!`T` znJ0QgV_E$P$oP(v1NT5y&p`Sif@stpN*~PX&tUd_#FRVm=l@Vv&xTCBBe-PE>MxMS zRP+!cQJB^Hk*uBzFbdKLV@*QX?H@!)tG@f89 zio4Hd^-pNeDtmA?6T#=QdKu9A!7PMqL3uu_e*yWi)8BDnWJS;ME2~$4jb)6&NVCel znAN{)MOtRd|58@30$M#0Psi#N4^gL0Y#XuO-v%Ipr#>A+f|W;_(zv^ylHH-&H$?2`ozP%gF6VI_Z9R?C+fO+U;@Ew=a+W`IeCTv1w$8M(VBE}{-U$@0 zra@uKhIuTfqxiwl`(uz>{)%H;`4vhX2Vq9Rq2V zZDC6qcBka@9ssKjiqIw%pOe$EAim+|E!0%M=H~QXK;Q8B)Us=>o0rpZA?qvzH}uA7 zIUNsTr6W#YM9$A?a!7)uk=-B~a(Z7#GP{?h%_*lT0KVjfLmjxxaEo$!e=QqtuKV4R zoTh^KS;?bdQ%=*MeI>b9;p_*O`8m}AdI6XDS9{$ZesfOKYw5cq{{#rga+(2X?BXUu z7>PBmEvFCE(nZI5M%2ojW&#?IP;IgKvMQ%p0kP}eNS`}9r&!2{4Sk@+}hUaI&(TPlvOt!gQQ4`-ksBj0Id=&EWM0{ z-keUVA(8de+MGTNV*EFCAVMAGbaDWAKOEld`g8gSfPK21>zNzK=@e*RLoZgfR6 z;ChPy5=W2&+zr?UX8GjQOQ%-o*c znY%0VW4AY_v%zgZkPPOyJ90V)#5dMVCD3%bE2q^p42M~Ee&3hVxnRC|oxuWQe@^EC zdS2T*9$NT0wF6nx&@v;0QBLPWPk^4*;ZiwuK>0yJ+ybuiBWn@sXL9NU_kA(c6P@_b zUPT2zr!Ic53ft2cGW0@D-5|ycb}{ypQcgVpp~D$X-L8^TFOXHX&fIiF_5t_iv?hQ& zZP-1S73RL2)&d%*+ZtE7`*Z56l|@Jw-s2v~X&sOao>(gn6--O!(Stc%5KxAq>DJrw z{ZLN*p|sHpI^4rK;gu(hJG=Xti%|DSP6MEx;~i^IAs~2nPJ>|9%msZzrf~FFP8$M} z9n0*)jPUWCJ^^CwZ0|H3QS|R~8Upg2g6UB70Q+Q4ymN)YHTh!qR8Aw~CE;E+cdL6k zr_q2A3fiPt&*Zcb#MlsH_CK4`g^*V6>v6N6%V|@{6`2pBeV@~25bNvgE?$*h$Y~3- zZ`txqoH4uIi#c6X!!E?$h0XA#oGuO}#paLpVXysiPM3sK?OjY-d&GGqr%S=CPHQ{* z+^ac#64DP5FJ1PstJiY6ETqGj2@kmX6r^8j346gjv>kmyUY7&g$XmSZf0#&2%v7Y&jVP4V&U=<>1Q0B*EO}QXAbuFx?}SC0*GJ!@D#;M3x~*K^SU;q%YHL+H{Ew! zUS9->)?f1^=_coO9e}Ysh5=jsNZ69xl)S#g4^h{!i%iYydPv`Z$d=yK<@IGCYe3Ab zoN*AA*9{=X8{Qo@xS4r<1=%EMVCyAxfAoc5yW?x z-8bwV_@unP255!bGV4yx>n3PF2%?vzn-Kn=ox!;iEfD*H zJ*lFQpVut_o?XQLV?|t)*R3JVY?kFUZb@D{LovghqeDdIY0B%{Aoj7wO&pI*hO{iN zU0~Mi=&imvukS$nW+QnqT`!KBEqUD*3NxDn7LK;Oz8jEOQxsx$WnQ~M#&<*Zyx_id zRbJoY2dh4(H=g0o&g*snfBrD%4eQ4vrL4~D`}|@JvxnH|43^iPkQ-xrPSWS+^@EUx z3(bI;g?8q(7bwhFeC^ty4u7k8{SeqXx_$9d^Gt-4syDAYLU|ZQa?)O#*PQ^K-))PK zs;X=&%)o~q+~s*?YI*A!P40@kvLK$p!yIAp zOvpIAGOt`MAyywKjOCRFF$Szfbq8TsUIl;&086{v)p-@e&uHBtRJ*0{h-mh%V?8)m_K)$kY!>_vJ-<#JX{9x=} zjtJ$BynYR76>T*$5_eZ#j{-~pSh?8k%j-8#z5;8xEe*N-c|8VX1(^EOJ$d~W((|!# zQxrCe6I))7gGPg3)U0+>dHoI`YF<#>ByEm^thCKMg;?3c{yq+E}WUDRE_viH|0RN$R z(WUKyyq>8Q)H{Ux1570I`g1MWMl`~Q+(UUi3uIGov5)!wa9)1_v7R(rLH9^r&p~_E zFQ^H$d6LZQuc0)~C-?-yJ4Ig4htgQdHgKPQJg>ijOrSK*K~LoMLipYMLNSn@%Rqq7Rig;^LhO%AZt;7qeoxJ>y?1u#tt(*_hMfE2C+KW!;yO_uUDaM5Y$CM zPG8RJKOu`rpwDh}ujKU_h_9yE;F{08SM&NWpzl%y;2g5uYk9e@ag0+vGDhbLdIOl1 zkJ1XWZbCs50IYB7q8Btbv7iG&5_?-fX{?}$0mzMsfLjL@G%4gU;TXjpT+o59BldWH zNI`D|3C!dOjwIO~TF^m&e&9z|ayIV{E9gz26R5(eQ{CYO9Smi|%xutYxjmwwHv{=) zicx@dek2|~vYtLSu{;9=x~1V?dpo|45;E4^!D)*y!UxGwV)$_ ze4WjQ5TT+?*|M&nchvHC!xWRd%_!(dK;L`A_IilHWI^u?Wuh0}-?tvWV+9=*lC^v3 z_pm#mpm%{85AZy|k>8hpK(x~Q_!)sf^cdz?B*8q-cV2sakvQ<=M{8ZC}=kBmfdLu9S*^)Aj6`9-VfkUf3JtHi`?HAG?kw`XV;sre|A+y zNmD`7!2PEYZ?J3Gr4`e<1w1&Vo)1xoC#j!gUw)ArN1=Es?TeZ$T%8g4#{{ZEZmx4m4p2&=o7_ zWN6PNuQG?0EBayueFWUMoEOSoH&DJ5)l!es^3hdgyi3N9~bek}nnN2BhFf)<1X_460FD+_9Xw4RA|+6CyUf*Jw* z*tTfDNME)Uq*^I0jje6&>Vg)AY$jG4cGncN2;cz9So=a$`ZuYMGj%8^TQmEf0x!YrBOn z-&|00KoBVpA+;GR=!}3MT{JDg9R;<3`27<*nLh3o(Gqz}L9P5?)h4J+liOKP8?^Nt z=0Ii&csE9_x4T^htpN8-TFH!JlH69%N-%3ud+YKQEx0D$UC^08);&Bgvm?9P3t9zo z0LbEo2Dhi6vmkAS$NoOp4!FGqoegTWScnydyQ83UpyxpUKX!V!&D~YdYD%#>bExYv z!#uaIpmW2QFza6D_7`*>bW|U2U~NK)dkSg?wNZJ=xh_%A`Jo(i$B#htf;wx+0=6KRE2s;^S~ZI>B(6|UH?)mBB0mvTp;S;0fM1c8^dJFIJr? z!lGy6kbv9Wy#=iaY3)Kgeu}@ZptT`wZVVUlQOw!<3u2FoKGYW3(L7Mlx&WYLu(aMi zSkMKvY{c+IgulT(R8T*l)fcapKXMNjw7!;$M-TT%LA*Ug6>IOts3{WQJX#Qf=O`C% z19)*QXals33NHAF^N1E%&?kV5Sr%${?rir&K{)Ln-{@hM>E5{~3*sFim+JD9*m0cr9;9o81lc0V{XyPo&k*uK0fPB>(?R`C(z|Ix* zsgRVYoEYk?cN2=b9OwWlQhz!=UyJ&5AkALjz@n~zw6TW7hPCvdqCNv)ADiDZ!V*TL z$fB+UvZl1#u6syPpAAVGa0h6*VTTrV6_95yP7iFuJglg#A(^RC60FG`UevZwQfuQG zE8G!9eGb~sj;ZbFeH~fU)gZn;y)5KM74`XAlGdi>ZSLrzt_evRqfl?h6!nDwAoYSf z#};)hfaeYhQ6n7;Lay$|74=1MKabFRj5@N*O)ly>V5`OPUI;X$s4oSCd0>jiQ;WJD z#5WMFqdp=|))n<-uxN+i;=jtxDC&k3J zi5^lr`lH*WJHMzO)Uxw3n{b^)?FD%oDY;S%<8-T|zikk!4Vx<6Mg6dre9X}{d>Y|F^)@+=1 zV$x$CvaTtr1Zcf(b}}H>7F7-izP$&zPhD431;n$4s|qc=zNjitbPT9-HxzX*)B#pV z;{vz6sGmSujq!bt2p{?>9o@w8{qJ9H#0KkR|F_bLovG6<3$~Ygtr>NhC-B7bH&xW{_|1C7#Biprl_}~8ApiNsPM0g{_t1WzM<#bHiiM({42h6B4Z2cM ze}MiUvO5#Ypb=0h>M4Hk!;uyuX=KdaTht#xeGm2Gh05Jm)YBlwFq^d|$8`4>^(Qc^ z+-%dgH!b|4o&oY5X+on1i~4iOXM@5{67Hd*o(&j-oqIBefrpFw3z)TP)OLVJih3^4 zgJ`|GM~nJvppokhxyOon9y(ejJIuy2I*dJD)ZaioFYM%EN0ujwdLd+Ov``gK7WH>% zU&j_4OFmW9ivZ)y!Q#qROZN4ri~2{%SvUOylif2#y#(#qvdH{RK3mj30}`}5o-69* z@jOIlaL*U@uRzlg9IlFbrB=oQlt|QSFKhVCG z;}1TzcDz#5Yat;P%iZqPqW%jVRz7qOO*iMYqFi?kv?mx&ims$L07fG>ioHIeqzM4l zqr{SnJh)9P>41<10UM6A4=iaSfS>5mh#7DPl{5)#BKexl8T!E`9T+lUG|9emNJ(!D zfXNQ~-JvBN1mF(?yr`kaJGeQzk{wpkoA||69W8Z-mvk`HL?}*L$ht~;GqhE?KYK;y z2kyv{4hhMZ4!WaCdQ14Z(Skp?qf0sz-~iGuZfJGKl=Rj>;yMJrj+z{P|pfBO0xr+TGA0AGcWKx2$Wo1N$&vi z9c+=O{gq}$Nk;-()!Gq4&n)Skkk)N|!`+i~ zOF`UAZZmFPNymZtwuDzU_;XrG#{+vtwl=n`T#VyqH@~FGpw?OKk!4^*N$&%&U5k_D z>kqdoX-Y_lqFC4IZc$0^AJ2)VM6X*?(o_IrR*XYZQ%Tbxt@4w{*SuvV)qz>zbP=;3 zg8{Zc*Id$c@QL8IDZ7@EWesggbbV)bN!;>NbJq?rI#Jet7XP;pgBv%n^T zooxRIP@n=TDq~iKYp;^#)DZRu4ooF|48(sI?GA2-8%vrCWFsJE zjxr-R`NVcC=~Q6f+-3`dj?1epCCvl$Yu2*JbB<~E47-a<`ZzyKq>$E*Ud~P>od#`n z@kW>KvXbgS{Fm$dJ1On*lIDj@=2_fbQPKiv>$X!PbJ{CQY6y9VqB~+1RaceN2xKfc zcb?l;lA!D}?M?Ob8=KtKB`pjHkwG{(yK72X1TxXmAW?AFmb4f;RHVc1d)Jk;1jq_K zv)Nr=(&>Tv*c5j|Nlj1_`K_Z5Vbu1LmO}dp6Gb_Q_RbqiS_bUdh4MN2CwT8FX*r+` z^2U~WcXLV2kTwe2ahMZ%FB>cAj9PK5?UCaYTz8e!5_006%H2{@E2KXihG4U{q3tZG z4SXUcTAX^ftE3gsehAvzW5DnJDQ@fKU`S@*oJfy`)tkYYfwW)_^@F zodx0u=xoKP$R$cTKNN(W0CoVWl6V#k&0EAV)n!WR z4B5E6d*3O!lDfbq+UNLlg_62!xo~WIp(~Zdp(v_h7f)ljQ7x$#z?vHA&mp|Ix1=>d z6M?ed%k6gem9!Sxv$m~|=Yji6>I1PVNA9)kviCqq>%fe=vB>pp(As~nqzk~K4+Is- zhe|>;7-dIagYy?Gf4HReV1DtSpS^wUBPAijjXs^-l}X?k$8&v2n*gl4J8;SMd`X*Y=|{WV3nguV zwh!YB#7rq)Ea{?Jih=d+rIIcVbgT=0yj;>H(0(8;-Q4<#e)mdAmjc-sI|pw&sK%G{ zNq}hln7x2$UcOe+Wg!ur(bMBxS)T&1-mysKEa1&%Y3(MIbvd|IsU4kZ_LzxfeHz3* zIeGfIkr3>_vaSH~>|yNNo&BJ)J_Ba`Rfie?5*(8c9$eOypvHhXBs!$5&qDh7U|PC| zmUR`tM1KFktPjj`hn2Mz+Lt`vi^C2tYa5tV$uw#y^@y@Q7Z46^m{hwX%eorGzJ3~t zRD|5LhuNdb`aI}F(BTVt4L-W8YoM)ko6pA^k|6k7e5h{hM(t zQP!71Cz7bCk8NT`SvLf_ePw-%n_1RZ0=)&1vWu0q9oo3S^frP131xj1#F*K>pq__} z6U(|0z<-GQfVYx4sjRPo`c;~}1nHD5$S0R|6YxZGuQcy)r5(?%|H+G=jNBSBhYq_cMWBI3p()Hj-SHL z5KZ~AZUOhb-a;r{=KrFyZVh=`+ps-YQr1prYpsvc*i_cHL#A^OPe&edmX);&%$U?= z;>$tTT-J9&Doz)XjizfU>$Z>zyPa?0L$0l?@77W^;5q??-j!wT4p{ce%pTL&bF0ew z9#}u+|37}c82dlZ>CP_ecE0Q9%`o~etIPU6fHl-y1EaWeURirUY|x#7I^+3e{Qxp- z!ltOoRPHQmZz!h2Oio>QSw95ujOW5*dY8Rr-2vuDQDlx{(_w8{cZRHW+=si}y0Y#9 zu)bvNih>r--^^*EzpNkCimdkvSOaD41M_3I^#WGT4Q2hfmI`$|JDCoZwI9q{Fk^b1 z8!78U8LnIr!dWo1Jq6Q%XLE6d6OOr&IP zcnGq}$_Kj60w--Ns}M5S*z0pwmsJGtQxOMHwp`FH*OXPN!Dt`hOu`&cTw7MTmL2($ zyRNJXK(wx`SnC?>94P`8)$laOvYGHBDSzpm4iWXZ&E?8^$mRkycp`1b|~tV}rY; zte*o|)l3dxYTrA{dJt&5?WS2_<7!t~zW}ygZfCo(GZ?BHx0Ur!D6k6!$YHm;tX~3H z(`V!P_V%(KhO~Ctoz-iv>?!M4fYt&+vzo&0-m)G6v93pJp`*V8uH8}AufeSH$e{Vw zU1dEA;K$iUTh;C2xv#9>gsi!-OQuKL-u|*41M`{*qh`>@-4c#4pzbN_xBO%cCSG8p z`6^D7^*GQ(pry7!rpo$VNWuahd5FxE^#qU~bxX~pBUje%L9E8@!=r?4;`mi4>q)SQ zVDoK2m&*DBw6&madMvliRmyrQBxvXuy1?CA)*l1i-h?x_`^tJ6+RyT(-U#^qvi=0- z2M-=S7!(hb^-Rdt2NT?bW&JrMSrD1w5o4&VXMy~XVA+ZMADW=%;j;e14|Z*s*XkZA z>p3Xj*PVl#do7A3g08au3hbM^sDrETV`V)L;^(2=dmbnlwzIK5 zS=Qe}@>wWz^th+WdJ(`r+qKC(UDiLKqV8T2yevOc)=MD^Im??1Qs#o@`;1UoGpuKsE+rulqoGtt{6QGMf*$4(?p8 zqBnrqC%p=in^4gNkcn2Dsk}|B=m6+R(DG+n7N7F29B%fZQxN4Y_-J|Te!&;9S&x#iXsrA##PbV zLuqF9=B8G31hlmP1p}&!L)D7j0W>N4fa#6QsOU%lzu2xJ&b`?f&aCL2HPAk1-WOsO z9R+B0$ID5-JE5X?LHlvjiO9p9SkciSzRhUNZH(SmPO9kLpk93bx+)aS;`~<8G5i*d zNxoy@n1&Jaxl<~74|o&bvKRUPZ~j>heAF1eL0LGYBnvUZW#?Z!! z<^tLR{{BsFQ$?pjS)0%c`Hb6A(L89+3KIw+X1utfkB4G%W6Ouk&;_H)icSNZWEr>G zJ^8YV>H+)^;8wR5$GT?Nd3iQ1gs8zN7CXeD{26X3?~)P7?{%Ru~+ zOUQKAu$wAcUW10wbi`#vMa?y64NoeY-B?9u)S&e}>o^hZsHg=fY~S|!6~)cIrJ~ka zN*)B*w{}+479fP)=2OM(s%Qn!c%RYFgfXgUC75rv=_Ik{x!o0=Sp!k#j+~s`UePK* z+y56gx4JzQomDHWm*85=g}oJ>4Q4GxRNA(9Wuv>JqH|s^YAx@K9DDDoXmv<8+g=Xn z{e2ak3p9zWxiK!tZhuAR1pu!CJYnBcQ9FRIJvxzHh(r<(fkp~G_f@nul+sQ$-Tf8(D})ik`m)hIP|>=O$(-6^M84iVSkVPw zzLsG=54(pdf)ml#Mlq;+xFX~!(ab?ba9@anai@Evq5<%T?Y)DMa{r?h4FXMq3$t;r zHS8X%h@lt_OO{M?{{MJIp8zp_E?ct{55Roti3;JS{qTyJ)CNk6%=FRMEu%zC+EcoINPN zT+tHja5JF~BRj4Adt3$1!rM>QhiQ zx3P~g$E*{ox*Wt0kw~uLCRX+7S|Y(KcVJalfcO;;<#M~BBcX(CXz&t~IG-r-_ zRecW7H=x->(??cybq(QIJmik5>hmDcJlAq}bXC_tPU7<&8*SViQ`Hv$e0@+mJGQE8 zp{+hMhZ!w{z3#ZGz6j(ShPsOxuuiV(Ixyqp`i*W%RbL8)@IKw|rdD-*pf{s_>FTQb za;=1Q1RJM>8CBf?Hi;5qY|3`s;`Bja$}nZ*Px7F)lDFNM&jI#H%~79r&RUz8fteeWRk?`uIgq` zV~Od;xw%z+1KL=)p>x>Ht7;4~s%QUj578h`tLmE}K|R~S{Hk_@1Vm>r)0>8>z7-Of zt-q?e1#%JvE?!!XLzP8U-3nm6+m1q2b7M=}S#C*HI|1!GkpsECuBobT2gJl2RBc&R zyFmOb#8kT*X$hC)=BmB}><1M~GJ~q6s@s49>*y5L#$Ry=wy=wqIaZvwA%fwv#Pxz!I>PIx~uvjq}AH|-QaY^^;UHUkgs(x`B_`lonZc~9))8?tYT70 zWOM7Px{KeuMnHF8Z*Mf~tb+Yj{U{WUlfh_%7^rGrfX?KMVz#y$s`_z&+7ZOqU3#dh z{XoW$cFv7%q^i3^lF4|dHutj|tGWls^T;IF!={?Lsj7HLh~o@G501DkRV8YWdB5Wk zv#KPJF{vH$(yCIBzQHSa-KFa;t12CmoHJ*ZyS%Clq)ok*$jYk9LPgcXRNGxyRjyXR zI$olg4p&u`2lFeI_rw(4Y_?TZ0QdDqGZnX{SVmu6RT0!`^l{XTuc@j8X`ef1wY#>e zaxIHJ$8)a5gKJe4(5Mo&{a;^I71|HW`Rrl#va`Y6P}RL58K=o^x4o*LKu0r)7i!ka z8>_l6q{v>LiMyMs`e{hP`vY5*ySb|SYsh@_Dl}Hr&p?K#;QzV6_y27Ux1*{D_`2^f zj4Vf4<8P_z=U~Q;Hk+k8t9mfh8R7PRoT2Qh>K7oBNU?mG>5bi1)k7f(e&jg_y4_X% z62uC&H}B|e_x7qD4%yC)oHOpJ>Q?}s(HG#wtY@Gf{h+;7JrdI4I%M{2cSlvf2Jk&i zEs>(qO?OrGD5%wQ-bEKpar>(J4Yc26Ov}nlqW4$z7@&2Mxh$r)@2TpyAil{92I)E6 zz*hA*m<^g(E03mC{SI;xBSGS7c+$VOsy~AGYS(f6H=WY^s(KpGKFAGWjk~|9 zKS585=q_yZAE@e?0L(VohkLN9KLc0|+C%iVhpKuO$XeRY5hv1me7LH=fQ89~-L5%G zXJ9^3)pOu}d23yP>&Hi{`YVXdocYb}v8tYj@?Fr{#fzIAgCDQzZ{wwHwZ(+EthS^) zQPm6JlgPWqB2l|1tNJ^DXF95}7&W-3s(KO3+PHXNm{VI-{|K4v<*L~|Q`JiW=s?!7 z**#m;KWiyk8ynqoRlOX51?G3dJzv$o0IW>Y@^mj$^$N6cWp(6Q8}S&x;wHp22Ef;jOBfvUPB$^8vDJJy>f7Xwj%gf-uY>8Jkm{J2#)qtR zb_I?sDvph50-%j`%R1vgG}$fSxR{Otwa?aadgEp+rir6~oj~q{nBEBB7eQ+z3_mfZ zqk(KZE;1JMNin?%+Sh^SqJ^|LIi_R4eD%$!#Do!(VtRAP$O7QT7SplNe*PId!d?XK z)R^8$HfYGQgT*chuj=Bcn9rp9zUNOW+qb5D!uZIHg|MD2tV zSsT*{Ax{*vv(C+o>Fpp^QM7w3EEJ5YGh;e2fOb{yhYc6gNg%e> z)$(fb4y3rk#q`dQ5X0GCZY;B6IvK>*#82wkF}*854}RijpWr6$=EO7!$okcW&CQMJ z-O#pJmn?JhW13to11o%rt&8atARE25hWbWsaWS1*O~d7JU5{HF(|f8=ePa_^!%JeC z0_4XATe-*zz9FX50BsPlYcpegJdedx12zWC1VBu!rkG9#iRO!`l)2`ZrUrnvqH5O~ z(-{G1G^UnY5!18)^qVfBTNTrEfT-8d6kvD>Qqbcrh^e+((!!>BZgosE0#J)m8B)%e zW&(`zbts)D9(&H(nBEI+!*0IeI$}B#(q`3y$PsfC>Af?i_ksFjiK8n-b?J`jtdO@G zTZW#P-VZs3yc?p3>2708XM_08;$VsR(Y-N!0MN$M)Ip4+(HGM>K)!rbg0UvEx^0Q+ zgTPj|(=V!Z12N5lwEi0z-i)vCp_o1d;EUfdh%jqIr`s0O?2u{R;3l^trgHPkY! zuOTeJkaNaF0ILXM-9{3OdtzE$O@;m+8jpu!x+p;A%F4tq_r|ma$mRytKjuJ%yH!kW zV9|VQsGsldk7;d4<9(7cTo1&Ao7S+CH?{;l;=?g@R8!*Sz&wDA#I&xOl4puYFWt1HE{8O#q> zEB+eLs&bW>c?y;D*K#z&qiOtG3_jpVfgZ!`30UP`$ zVjAEFe>lQ#X^o=1JsHy=sI7~}CihfKLr^vo+BffXPsfBtTl6&xT<@NVX@;fm>_KsG5* zlwIduis=&Q(Y-ke_hlTYmt(pV+;^-^Ddagm_Q)$SUB)lbo7paz|KqQFHKvd8n{T`6 zO7ND3RTk6bpkw%^IfkWsU0fdz2pb1sE!`1uT>)YvYw=qL-H~y90>FxDHZ?*naNO9( z#C0X8uWrP9u}uXvtzkBRFVaGSnS1V&15$HuiAEZUM#PdF~FPeYC&2~UQ5NA7UP z$8~MUWOl$PX~I5>>oZ{1^|-m+>`sj9x-oW| zTU!?*BDhI$eGbs?F|3U+aVN)h1F+Q=-3i)ds%>$79?bgoQli}Kc2nZIF#xrZj#o`w zUkCtOC(Mhfaoq&q`t}pF%DP&wX@^8707Dp{g|E;*H-|>MBl?oguvi&-4>E? z#bZX#j_a!cetU`JDuhUiYZ%PN2i-k4H?FTij)7!8;?>H{kL&h;j0~T`A6FOG*FkJ_ z7PR6GKymGX_GvWz892{%nIuHs+t7y;RJKWm1z8kV2 zTR7x8;yM_zL=I?bKZo z*G~cjZz6i}To%^@KsJC{)=coidK}$c9@kF+eUmLHGR0jH*I}?RBs88L&#WusdJx2F zW`+${#We!yr@|H%Gx8O8bzDCSX*dhq?zkR;w6Q}bvx{ipas52}UV}c~b#XlmS>2Gm z9?|u2{Q}hY7p4(h8*PKSA+AS4Vas_VAkd8KmjP&No!4@nyD6?%D9&PGcnu?Wb6j!I zF;t=jM=ERzx5SkI@$K!#g9luhTjNTCMJHghyDhF1lvUguM-I8+xY8lZf>9Ri?QvxS zhGRt^AYo5j*^m)Q3tIMj@Fs5OM2%_dr~~ z4fLX>`ep8LTu+Ste*MUOZX~YXLHpeb6>}V!KNQ!KKw~J@ItoeO!*TsSWI~;1o_i#& zr>dFYm>B;nu0MoK=OLitA&`jcX%IgPy z>rYjzb1QcU%q`=3wwjskIno?1#r0=E>*|r=^H>a(xSj*BensDk8(Ca`f%Yxj+&{3T z$2}I;^FV%b+a_**+~aZm71URF!J;NELPPF}xLye0?5$>(U|g9e zMwZp{as4wCVO|wcIx=R@3vs;yYHQGzQqbpjFUIvRVBbvQ6!Ni`;(8UxpT)=)kV>xa z;aUB1T>l0iLkS2hY+rmOuGc{PF5JVdDGG4L$6k%=Km6cJZO1ki?pR!I{pcQG{y`&- ztaAyy4%m-F1E$bNBySJIS5ZRePr(6ON$BHZ*CcPyc| zgnY~aHk>I59S2}@XyrUtlh9kC{NmxRYLBF;2^}A@Oplz)O-tx)0RB^GHAMCjwF#X7 z=m!WH!3H-op|^*!W{if6KQo~d17@;4yNA285_$)iHO0p{Jv*V3szu=_j_}_Jy%WSb zbvyg|tb|SuIYzEQDDP$`^sbO&KKE5-`<#R(f%u_~)Q`=gac)BI4(T>@V^c(g%7i9| zqSm1z(&_3FIt9Q_UW{&z^$h#q0=F)!@U9(L)o0r)PUifjaa=sL;z3d46w1J!+tjM z!n`7(X+TysafZ$AVO2uYL86{S6&hpAglYl&ypOERi8zS`KteM@I=oZB240iU%mCDy z!n#|V(0c)FR&4Ke9SNN|`g3h9612{Q-Unc_v8`_53fG;`S%K!Xnc;d8dVk1(W19X= zZev1c16ZrgBYJN_AAqzOv|$KMTH`#szJ$&RnfeKhhyRL%J_ulagRsrt{09=66>=J9 z9@#zT;ZQ;!0vt<1bUQfayWF;fW{12;Z;d;HEoMUJ2F!%bc=W)VYeI9t{9N{N3_9H< z34IvQPadQUOckngSweF`txry$?JiGfUNz%Te}_Fz-4zMV9|f-&j4Y12-IWO~02~|D z4$Ef-;Hre`fc!EeI4)a*yE>tTV1BHYcJ+3^HHO!-J0VqJm^iSBZQfp+&>~dt*Z9f%w^P z0Zh2gMd1@~N~nP!tnuf~b2lfn6v}!n(glok&2LGl5zrcC3&fax?$(5s1&kN=)((p_ ze_KLLU{=xPwzUl>^bu%lO0D_HB|LaS%^=~`-^(r6uJNXXwkM&MkTx=y$2K6LRuKCt z4@AFI?@VYp*jO;rKr@BYeF?1qvX7zy{A0I2p_L&?Tccf&8{Az9tpc(EKnv280wT`u zfrQQvDRIldQ+TI4n9v2Gu=*BE7Vb{yLTH=aOPAHTdlFg=X}yCPWP9f_<31ls=%SDZ z-y0q7-h|dv=>>RqO{gu~pvUrMZh5>vHo1oq>a6COOfb5K6T*dk)ZNpkM=F?)B-9OJ4d341&%=dPwGQ86 z39SeACmh#v%wNm}hf5^X6AIv&VsR5v385JsrmksmdYMrsp^d=S=R8a5TrQza&|z7z zPurE-6%s<28Fe1Ikgk-_W=P*|d1bLmLcCN$K?H7lG@*WIzi3y^Yi_joSC1vMC6qHA ze+-W&bTQ;u`}j59nB|FtP?rux^A<2u(I*oc49SQI8(Et?mCz87FI{NWw4*`ubV6GJ zN4M6U?wN$PRa0%|^|+7SUzNa~6Jpb!e<<;bKy5dbDq>q0jssVf1jAse_qF&yKP z`Xop+%gw5*!8p?slDZ1;e;H!rj!AtA)LOWb33PN)S3{14Y4y?t7O3s zx?_{t4P;HjR0U^Y$0haYkY;4Ke*mRicYIRU0$FPZdrZBCdYzEeXTbcl_0}Wyn>#V7 z>#Es(wDFUY`Ye#uYdT6LCnt4%Ah}_>NlASU(kifW@xtbXZgNsL1OT@C;1+jkQlAHi zIvZvENVRuLQa6HGN5KKK7@RdpeF0=F2&XMGzbKKeF?y!_kUoTP@K{Ro>s zgXqmZH>t0Md@O!bwVj{T?I2^L@6C(+s?;U*bs(z~Va+knQ&M{Z&^BcEyv0dJ6jVG^HDox&tI=OCgH(OhG%^Tw_vq@|)GxG&@{VQs1l=*uB9byEZ4a z56Jh-;;kL7HK}ifH0w+b%+|6Zsr^8{k@Y6iwQX)yQr`ykC$#x^K&1;F^#w`YRfQYd zw{2J-*`cjY>N~(Tx!UG8yERE2fV9s}j}*?kA>qB!o zh#px|KLxNpT>W3$rz?^=4C-676gC$}=aor42$|~x+$p`ke{CLvE0o`#R04}^DvIsNvKqJOHv6iKR(^4y>bjw{H;kP zfyYM0tz$~{yW5gV0ofOkpAER-q|(s7ZxlVu-R((bz^pWsChgpc&aOR4WkXW4*p755 z_a>DCvu-53gat^rGpRg?pL1KbyM0L&Laup(X!Y2X+n-bs%ujVxFuh9WT}hQdZFXYL zFgWCITS=8ecH3jQ(ha$TNman?6I`Cxxx1746|`^tN_-old`nordy;yznw7`DaqIpDE@KLO6Tk|{JNK(H8_br{jyrsTzVM~j9D5)m{Dmbil@Fv-09!~1_q1;y7 zDm0pE+9OFl1!lFu%xIm9CG`hrzk-*x@7S;z?pPwJr>mfU`oRlJ>W?8OAsoN&GD$rH zJ(iNpn;3TimrLqTK+!m}ywIG8RCEeSJqzsXjJ`}Ko!;e2N&Okrx~UdNNtL9YgS2je zM{x&Csz;Oh3y7bnb9fX!melhh2Qhfv<4OHBkTo?^-4jW@0BJ4zFn`>WN&O9aEVL=1 zVjAh5O6tXsWK$QX`_oDN9ommGHlO(BG6$v4B=r)o?Fp^*?%AaN5i(gYXZKuEF9*5} zZ7KJBQvZauYMwjUR03Z}>JDt~<}YmXz!9HQ3B$ zs@LvdUCyQSx`5)FHF~$ObdE^r2vD1RBg2H2F^1uhDZM_VtV6+dU?`GCj7jN8(6Ld< zmdMm(TuN^M@)buLjdP4ET1sO8$3^LyySU5^xrr%_1+&3HMP$7@I;C;YzHumXa4JS7 zXUC*89^4w&*4|4rJ$GzM6F{tS)9jJyj!Wq%0ACGQmGzzO_>?9B`5v#j$vYvXH-cK_ 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

    ;q8t*kG#G`H8aK7owGb8146O(W_o(~mN;N4 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

    TeR!uoOq(cUW6Uq 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�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

    -m_&dwPod!f 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�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®-AjsL8<8le!R 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%0AjdUpTB5SDGuPQC`R_$^m@JTw|x! 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

    oaoadO}dz$w!vPg&5&WSDS@jdYTyqq15{sP&{ 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

    S<<^(!2V3vU!{rLC+^XSm0C4l|3%6 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

    4mOePqHNCVg3fB&Mf$2n;C~E?7m3F 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

    SRG-y<$bUlo+US&7@}DfM z{zLwgWmM+Kf0A&`Bj;ve^&j$|EF*@TmxSDSf&3@SxFP3<`179?StS1n@$91C5KBT? zcLVuP2yLx3Lx!wuiSM8-KO+ChGH=L*Sr%js`A?QbLoP}}pXkTrKUr27a&Z#c8%yLr zSt^EHl7;y{H49L&Of3l1ia&=2ca>nEq@}Cf9 z{8A<$*M!h3SbKr|oct$*`M&hOkZVKOuagFq3)6kn2Kd5pm7`g8V0>!uWE( zA=hW=mfOgGvh*3!7UI3^3Hc@YPY6j4{S>4l33b!$`A-P>59Kp57UJmvtN)Pyw1n2hh#?b2yuSDy`A>)^ITMCV zg|I6+*YiE(KSkK3%aEBYbMkxgpDc@p%oUlTe7=|bCri5_3t1}i2lAf~o@$|ujoc98 z_g6*kBmZd$HPM(MYeIZJ(v{3pw_Axj~?N=~=jPyQ3aym#&|Erxo%S@}D9z zoD1Z(B=o5tBL6AE?(>G+USyUs^RMJTMOZ`4kUO%>OO^a5q_U=+wmNcW2y23pkJZS3 zvP>FsR}r84T_^uZLivN-UBp)fZIJ&InWbDs?#a?AP4b^4v^S7@i}+sZ%j7>r*b&T- z`?8G7!{k3jX82yn{Y7SJ*ZqzBrzP}i`wV%Y2xY%KLjDutrNodS4;JaA{`x!lPY83C zD94b8l910oO8yhV@60(xs#z-X5AvTZ3x?FQ49R2UKOwZnD0`7+2x$*x=0C}Qvh*7A zaEK=`3-UPmPmw;pJMu`8Uh2Vrk^dB-mNDefEEDns`A-p_3yM4z;+f2>{G0qI%Yq?~ zXPK8L$$vt;g+F1)6Cs}VEXse#e?oX?&MER_k~OR3De|8zZH7FRrCt6@{u9DG^FD~& z{Y?Jj2~4L*L!TAGu5V-o$T~%sjUdlz=(CFq^7|m`hEQU2t*+D1=Y(`ITCr%zdLcaL zPaELb4SjA)m@85-Wc?756Z&!MHuQNRtoXasZpa29JVj6T^_+%2zsM+U5@f?7W7IqA zHS`4`@mVM{^8ALrILn+NTegI~;ksqRhHljoUbSe*)*-BY zO&j0^4Sh+7|Mw|Fwn;+SyHP`5nuL4<**3&`N&T{MLthqB;mM9EL$)h2L7BNpLtkFR z#~qOELwpVGRkCSAUlHPM0QUcC=nf&|KlG_LYv_(4{;SR#vQrZ3xED6`m04K*r=dG1 z;ac6ip|2{!?_tO;McC z)gj*38Zcy_NC&OD_cwGf31v7klx19wY3Oj4c|%6B^veetI$C6iSs=(*mLWN|q2pOb z44DXF#Tj~@A8hDkh+hfwhD?Rf1EEYfuA$ROxSo-jBx}0lLk*ox!u5>IWtoxV8#*82 z^ZQ2(SqSN-HgA&;H*_(?KhJ_8Hx!}&EGIPdMsmO^9 zT^r(cWt$;4hWI=8$wwRdlMwIwbs2I~mTozzp+61r-r#~EH)k1=k2UmXS=tS`C4?2E z*IpneH}vNrJ^b>6hTNKk-Mm7;;C5_ZVm8)Q0{#3B4WU&JgeEwaF(N`kN4*C1AE6a#u?zZARp@hW<9BhqF9t z$lW2{N1BySHS~8Oe$1F5_k{Q{y>fa(f1iXI49LA%I^@$0{X-JUOys^K^cc@*=pRG4 z>NxMn{UQFpI^{DB{ZkTVEFllHgx1%BoY~MnhfuE4i$fkPQlYH-Y(xK2q?>brJXEAY zTlB1k{x!>tA=M(3^zyle)!1y?3P9650tp^7)1?w}ht@SpBD= z4~MW4ByG`i8v3^^vxYnp;yt2X`9eeg9^#42j3JMPc#o)0&TZ&Fvh*ABScoSeqw>Xu z{xif&fB{1u&$3$1Yv{kSj2iMpi1(5%kS{g#-$iCg;*ckk@I==64gF7uk1??OS3{o) zp_jzy#g`lU-;hq$tzh;~L*;jo{ye<{v622{VfQc6pClv&D@cEma6KdICLt+UN&1sz zz>xK_49W$hKUroBSw9JVvBGR8M1BPtW63z~* z|B(K)gc0#^LpDi5opLehPnJ1DHVg6IR=<3W^e4p6#hf9Vhxji)D3_4_WSKQ&i!1~3 zb<&?K6NYRV;_o~!mo{{(5PDmb3CPw-sF%M%`cq_rYXjLP%c5LH`V->y#f%}_wuEw{ zU%pBDlcmp)?XnEW<)lAZh7H+1%b0wN^e4->Av$w6J1666GGk1?~Lpg;_coU z`7Y^C2z>|AaAfx+oQtbTf3mb0vPYJ7`5x&{mQF+V%+f8_kp5)pF=Ve0?_W&I_ep<} z@OhBEL%hc^DA$tygm`aa+>m{;Ovn#Ne~Qd7n*`Z6q>~x{^Ku>ePl)#~<_*~|35nhh z$$zr68M1#8+CSHm|AerID(4hAFvLf;hGZ4_PskASK4%R%2zh2_W&cFe(nbOlM=_2? z>5CkkWl-8lfUQ)E^328=_CQlGGNGIMVN^pT_iwRx(qoy z%ZPN70EKwVrPq)nLg<%J`c_DQl5nRYM}~O&eL#9hfI_^DKWfNPA>Mu;m0l8{BFyqK z)uRao>Bx_jzhXkm|5Iu~35}*)zSF~J^V?(?p-X*I^fLg*DwnK&-7vkCSfDDiT zg;Xf%ng2rq6yhz`ei7u$&fQcy4SGdxlEG)74bDy zkh4Old8nCZNPt3US8^93XNUMPD`b`gD5OI2-(ko(St>F|0u<8q^cW&?ZV0d9GtZL% zC876;oR@_Abb$mYOSd8ChjjTYI9VhCDni0yh-G2-FA|_4^f3%sS%lRxX_h&;kpw7&wlJ-JghBtRiPUeIgE4Y@LexkmKlZYBW=>1GGy6^2}uWu^R#1SkpR26A;s=hJiWZXp56QZeM3 zBD2g5`#A|vh_{6o47oO>LSMX1ZY2RKGR1jEuFEnnzaRlBGEL%wT%V;~ZX*F|3HNfv zkhUcBFn&n_l%?B{jwH1DZzloDveJ;QEGy(!BtRjwD;ZlyDp~sE4ica&vxf9$nUi0W z0EKw2KW#{Vh_4Q}Aa{}gAE38L;NB)zgV#rho^MC21-9!FUWRS5WWF`sO z;P1(QvUC|Tm!((kCI3l68yi_@3G*X6j`W3vy?Ozp7ViPKFmWRoITH-sU z7;=A+9%`?@k^dy2Uw}N2gq-9N@}DG({UHyAbn%?hsQjJ$Crh6p4;7i`K7Ew@rwH@X z45?;e?=SM7ES-kbvrNciYJeFld{!RXqWz>+zTS8XZBTth5 zWa%~Ji4bPjlGFZ&{3nDK8?7kh$&gNRtx0)`{3pbFcB6(o72@NkUGiV@pAdhaHbdl| z$bV>`O^Y=3Ss`SVj4vbWWa*b@HTBsc-m054WZfduJi)t8Q=gNi-H`P{Xy@^Hp54^v zCZQFMtltv$mRK$8HuZTSv~~E*$Oa)^W{%2pn)>`A9o!elhDF-Bch+m_3qokG@xPFb zim>*FJh!PEXJPf9rfw4Ab0|k;{ibdj;=eq5e>HWp5T1UgrT)C8zA(hwD8q(qo~2th zXzGhXy#2xIKTX{t%a}aBsV~mbZ^)J{;dzWs*|4cw6){@s$ktiLP zO^9D(qq0#`Us_}Zp9k4C#J|P3Y~0kBg?KAr-jMCGEXXEJeR)VHBS({lY#-vQ11!j< zO?^d{MMHKd!Y-7uSyOk+(q_m`Eup`$N?zF1S7vE5WaljHvUyWqm8Hv&U9xn`i<Q5?G-RKa zFnfNbytJur4(aAv?J;EE5T6G>BilChEg@bnv-(d{_Y3i3Cgf#JeQQg&y9W%}zet69 zXS=2zP=q_)kOQ-H%FCPjwh(W(%o%b}mU-E}sc$bbN>3O$I7_FzqN$pt+mJ)D^vDiP zeMgplLk4Fu#B1sWLk=&(dZY5nroOu+o)Q~! zM2NQ&R?E&!eNPCh7jT~ie>+H00ia{y zjOsDum?HhOTXt>g2SWV3cN%hRNQLJT+vPP){a}cf{L_XU*AjAy8QHC=9}4j&u4fE6 zKE&(gQF(1sKOEvMBIf@z^@NZLdnfeE?oItji2w5ahMd?E+L^ubx~6`#$S`vTkdsa-zehV;;m8jv?N z^|K-VO&1M0D}ZQKB5E__?2yXSZQ3_C_47rTiDAe&E#Z94%f3zhLJ|@O zm#I=F6h4^ncB=2czdzJ}9Iff*#7Cf}44DgQXWYCZ z$2WC8q?-{1R{v@0LK4cl4>xr&gqo2|2Dzcg5aakKH1$VC*st1W@Rb z@5$;vOkl&jr>VaP@oTKdklV6!$|+6# zWtLt;Zf^slUoHX2=~a;hnqX)TaJAq?=FJVaS~=p>IATpKR)HLcDxt^`EBR z6~df*>gCg#`r8n{4i^l$JIkVcs;R$ALK%+S6XMy|f}Gye--pot;l4ob4e|5dEuU`c zA41pzhI5MC7vjI_tenx*KemK3IAh5DA+!NFr=Mx+pF+IuX7!(@J`h6v&b4u7Q~w;o z_u_s>9xO7$Xu)Tj`j-&qrY^DiPg5TXVSO@=IjgCEEz(Y1fK*#TT{$YBYicco5f92A zq#ojT+?<@<)J8~U?MnJPNV6r}al`WYrY?tgt6`A?QxE?qB3T zA?yT8nTf0);@^EhE+qd6>7?a3VaNs{K4W20zC!*J!dNnWMr6Yfu0!gJi^zXMyq010 zAM&3No(<;O_$v8N2v76yy^u|c%yX??O#agn?%aMuHVg4FGgkj0|3UtLHiECeyk^3% z&C5}PO9OHV2~ddloMsH!BE-K3>;I4dg)j=kCqlLi@hf^#E+qj9>7Wc)ZOGO|X1NQ$ zK>`%g>1`rIwh7^V7!$vY1gOX`J$Pi>BCM_~-y{JFVFh-6MP$1o14~_UISCN*%v=o4 zD*X^_`#6gK&b|6AGN2GveW9L1b_ntB$_hYaKw0_>*(s#r>l4Vg$$+wS8nSap7wVoJ*v*&~EK#;H}mM+y|e?gW%($eu;!n2mM~DNqv58M0T1-{Xt& zeNvzzzFz{ecL?8$UdFYgKp~{!%mqRA3GpjtSbjhX6ym?eDns@~;!IN?PRe!UKyeh$ zTyQla`ytOfDYhU#Bn65iIygV=hU_2WSI4YePYQ&@JM(n58FpYC^#9Qi5wB)ubYtyX;28OTT)XY zM~3(+UL(>&8Wh4kLrsMom8D&JNrQ^4CJ{l7&eA7+q(MdcDX)-YlF+i~Ck;wMFB~~G zWQe-7M^=*tA@Qp%kvbZ7TpZ<}u|o#PgF?Fa_LGJjpJi4C$%C?V8FE4r>ct`Qpe#Lx zoEYMze6I|X2W6=ka#9F$IXGs7JP2uh>X9YZ10oTMqx=kw$ta0Xh?h^jhMW?@^D_KK zV@liL|cKDN5{{$%f)6zmob5xhjMw%E(@SMm7}EK?``skgG%dm^rzHY$$}@ zHfI;PCdtx_{G4nk#9IP$hFpt0^NA2@wOdJt;wZ0G1`N3_q=)wZi2Q*FYY9lL{(50#@RMY)==wqpLuMfoKeQGVr|AssDYt?&-Hos1|6btKZ2gj)MoWJF2m zdm@z(KbP}z2N_Y8MMHW+DA~vyeoaP{Wyp~JEd6pP8BvybLk3zx+q5FTAtMU$nU~{+ z42AfaoRhoAh(dG3y|}B))bkcHU3AkqAX*EEM@7H`^kzzI%#|M z8FFKm9{CelQIJiok1LkH zZ;c~Zr-yRnFC;}F^a`ohklT>f@7PZ{@(@{39OZ555kqdzG9iB@E6Oru$Q>cRZ)2xa z$%;a_UuYd8cZQJBF_I@bfIO9@BL5{Z3Zbn+{{oSFTc3ev&FNvvvOWu2 zPegv~M-3UWPCjaIsZE}>tj~_4I{EDE8MdtJhIEkEP02dT`kWAIY_23^y&}Hn!Lyh3 zxgp+$7&2siBz_lC5mpUa*5}1h6`v(!$Oa*u!#&>SpA504YpYv#m;IZKF?d$ z7iJkTWb>BrDpn3!))$3PhmwgQTZFJS9wp@Sm-WRVtYt_7g=|@5m{#3}%eqyTZbP<4 zq7>yRqIr42vc4oAwc3zviVRV*ZM3W}Ei$|`V92&bJYU*)Szi|7Yspp&*)GIO(K*>< zSzn%ngc8|433u+M%le8Wv_+8}imagRzuB_xSj6ZZAv=ZmZ`LC(T-H~H^pIr@8nSbU zf1V-Pd|6+WgpwcGB?&$L7cJ|nvzQ^fhIG*~8J8`V^)(^9GuIiiTM|C=i|5T+^T$=P?Xtclj`H^0 zydnD)8Kh_QvSod1h_}op4cR}Wi>qo)VU0pdX4H9OAX(oV;RLHH0;$X*(i^gfP~^x!++~-x1;^(TpL7hIEohP05bS`pytm z10}&m4$CqsJ1y(GvUC}8c!*!q!}7{yeRl}Y-E%gOBar_usp#?UysYnuBRYI#2Sbhw z@vLK9UbU?6&BE?s%X(CnY1w62-=HK>mbJ<&s;$WIoGbs z`hhsgUpH^au_4{wx|7!|>jy(ZB4K2 zv#g)X(r?JwNx1XhysV!O@!nOpA?LJ&8PEN)@3MX&q=P%H&yaINXyGok%UhQ9iy<6C zA00U_%dG6TtY6A9Xvp~?UNcO}TbK3AAr;oy9WumPLO$Fs`!DN?5Z~pg$B>mFwA@Jp z4_MXGxdcoOSjdzP~@_Gmrf|>+JVA`?B`hud~nD3c11wPfPG2 zA6pFHabil^kV39>!uy?!4f`#I?>e!#d|Dw_Ik7#wTO}-p?>S-BG4Um2c_g-X*Zzy) z>Vz=YgIoj2=YHJP#}~u*-J%75HKdShowU!7&^8WO3_nN+y$Et$O4vzkFfA$Yw{EruT_ zgxZ4Kk`mSuErzCqFmgbeQ_?A)UJNafuy2M!TAkQ^P01mPq0I>;Mic{SPf3e>W-)Y> zWPvYbD5TQ~-{qoz9l990obZ0dLbF1;o$y40In!qsLyr?y>obx;dYzcQI4FlLhLtH9 zQb=D)#^rO1q2Gx`>oW=&aKbDDe|Gp{7)%IrLCBDkHd<=4e10(uN78`}WF#SIWJfH9 z(Ui0*WGp4DC0Y#QDdAf}i($eEnh*-$k&9u{iAD2#OK34nIbjV49{-DrVH#5OT=YM@ zFl;7a%tL17sKqdwFzmV%HWwM+ET;^p}h1?T!;^`iDcgkY;wOh4u-IEHrHxiwnlT#PNZ&JdSg%-nokz9-l z`sKy&+emDME#&@4E=I*TZ87{VC0z=6z)2@_x&b+TG5kJ~KFSgDAf&wiIo5G6Sqy)0 zE53wBzlA*H#Bv&wGZw=i6GBdqhn=u;m?-tk#qcL5oW-*X$RkeJX$*b)D~sXJC7Ewx ztb#o1WPsJ6t#a04_zR@GM%zab_Ly7oHUneKR~N%yBVi|Sg*;voer-g~UJQRL3EJ_9 zLY^oIk@Se1vl#yFgm1DkQbV3h$)KFO82$k%uE^%*oeF!(t%%8qi@&xQ78Al1K`IGh zt{>YdQX*l7XCj7(&i{YP6m}?MWLY{VFPb!Aw>x%`s{ zZ&t|jPKan3*S@(J{^x|aWT8VL^2fqM8R->8FLJ^y`k|9}!TI7UpKj4ob>pQWhJMD4_T2V?m6|#X7dulx_m!cIxyoK;( z>L!J4=vHmSZi8|eT2Uk;sKAhoA{j;p`4(DH%!##0%=BR!M=SeU_2sBVkxZbLKsJeF zgqr;}T9Fg0k4}Yb3h|yrTs|RJpcc6mG5-9xLN;65YFfU7UbHrwRM_TgvsH2>no+`- zgSRMb3s^P=br3_&$am3*|rK(2Sh4@r+|yAzP(nM81b+g!OAoY?xfeueB5$pj<7 z^{7TpC?UKXWM?N9(T~asR3j(MABdqLyF@aL%?+qVPHex|S%vKC1brTFdn2lm6K10G zg9_QriP=oc4^fRGu@!5O-63AmJg4fAn^2A13auOM4YG$5c2A`T{0P-367E$Ydqy&e zm%JIxs3i2$DTVA6$sD8BkI{@$GOCcho!D5@E4QE-l>{%*qmX@^u)1N*QfWdnN(kNt zvTs5dMVrx#QZlWO{UF{WZB2-@pc=VVJ39#WD`fvjMw#=qq8cTHHUv2!A;jZts78^D zEwn4-z=YtB+fj`Y!u$YoP$Z+Yp$=4|gfI((9GnnT;7)X-gv`$<OU8A%`V|Ywkfef|O-udl0}5cPpEXbVx6{krSJZbSUJAl=R9rWwjS|A>2st_-^ymR}BPX^SX@^3Nbz;x*reqM^ z$O&zVo(MVKiM^ZKFGJ`?P8jEz^+8UA6y;&7d#7a><;bmUHZ-D;lbz6FSwk>_a#Rw2 ztxqARIAO!3)!0As0EJuDPC7 zXhta+Qiw*vngO{L&BzJ);LjmToiOKMUFMXud@uE1cMGb;_NnMow56$Jhb6(TUBRX5|;CMo!p6 z7VinUDJ8RV7phStP51`L&5<-SxBMllQ6x=71dv-I;k_fd8`UTwv<^sfBu&iZe}!sP z62`kRg|s^1nFRUVgKFfYgHdu!A?;4=iP?bs8r8^&*-R^>GbJ-}FRD>WdKJ>0l79IO zs*w|`(=mngIC4lSrcR+5_X4^`%#UYn1Ab5 z$PlE^9DC$ct&qmtOOTZK$TV(T6MfNBKsyy=&-3Y$r-rsN?sBPX`M`-np3oV4Oi_y!SrkrQ_L zW|V^5nh<>X!{|jRQH9JWgc$cv=tU{%Q^-O>h+!T zPYI?Ja=#PKLIr;ky(l6056A-vL3#KGdJ&{(>8q6VgKp8nYMQ0;6k3rJ(~3G2@{kjL ziMhfeT2V>piL(lM*on=GMx=sPR1%(s@EszwqLi?<2(8G8-PMdj9(B@Ayx1uV zJ#7kk%n9=(YNC!(1Sw*JRZ9ACw`gTu_Ovw6iJaIxa!eslB!t=4KhcR&aAz8lAbDRg zf{%eU+{&J^49c_UL@Ak3$kQnqmj9p=IkCCbs6w7`V%~L3ocu$W}{&_T_l#DCn`I1nBtSUkyiiG=6h&)^>2&|b9sf3p}VXq~8 z2V@tjy5qp`sEh$><8$Sn6E*{~Ac;Aiq=8vhE}q9pjv5qVW5 zywQoRJ!3zzO4u?bW3o{tya`g?4QtF5wv}5kqoPf|x)R>(q-~xr2`FUiNYKS(<4Sl- zB)ki$kZmIAW~6>iCA>8f-gs5Wwh1B1-J}xUmXbb&Y?lzCi`Q1d+f&l2knIz~^SDhb z;T;KCvs58FK>S{r@$|~;D&d`LF=`mLW5VdUt+H7qyel#^kok6n?F7peIc8at^7=}6 zcVfk}iw=eD9GT6t`epM=Lak{|qLUv0@lf1DK-k%WqFJ$+G;F-3pgbyTyQh@B?#AeZR@}^4oU`l2bvZs^wY_;E3 zmGB`aHfxzu$X-q?pALC*C49If%*HzvvUf?a>6EQ2;Ugtstm{z7J|$VRlu`68mGDs~ zlnIYtlNG^pvTY@N+=+Ra z0fijkgc%Tu`r9hu6Oph6Rv`yEvHb>nWxGoFq!V(+4?+%#WCV}$_Dc9vO1c$tuoD}j zXJq?I__UMGY(+WbkVrgIe9npe z)__6|k7StMy<;VOJ`(hGg&Yyd5Iy8wmGA{8?bHUllvTo!DPfngO88<*dK7Y0B+T~Y z-IegAlng86Xeai(rA>COgkvCOf9GqU3Om-V7~2+_foRfC^ZKpzxkHliJT`J*( zgv|FU&}PPj%|EaX&(Un67ixV*0tzU)?fO&U)F zIn9afc-StxRl?~`EVk)W$Py>4N@Hg5{z^E*3Ev^Z%RtU72|HG?Q&}Z^#YsC?#FvUH z;VdVe`1*_G1C{VqNO6rl%=Cv8c6PLyBbL~s63%f#&0+&N*NM#~Tjhh5@HHoP|C0(i z4^rO$B;(|sm2kdW*%vA%6>@p`w^V)OQC36=0Yi2oYb-KVhSZe`ys?vwp1;p&tO zDdZX__S|e(K3)mmPsxZvu61Hs$DkZg2|p+a^NvY{TnF(M!n3em`9vjLpIXf-WJR>% zO=^7Kft7GWWVXs~Okp?1Gsnp5la=tpl*JR6bP+ zKX$_V-P8)?7AJf`f|ch7S3;8$cHE%fLYhlL&du`aN@z*RltNllGAD;rLR&)S+Z58C zkcAHUOeJ(UX=9$(rjX8*^vI!=(B;JHdsZRcPVB4^`D`Whq-0zny-ry1M{7H*5>`5~ z_TQ_JK1kAT`sH(#(C=0@LtLehfk^oNuN+z6N9!Zf6qqf9C38MkQRSwg!URSC0B?28&b3Yl}###^eR@}){x<;2F_Nrl|%#Crd@ z99;=Nfq1#jk28wE=G}^Qg0!<^Dq(d>Iu)|u#PaTwV=G~e6Wa@r-ODQBHYZ)E5S?;d zCH&Nh?L;`FklP_;$=Y`&j<1BDxmCwPJM#m`9f?);w)qK_@N>7av1VE!cRE20ou7~s zE8!RMJP2wq>@K%r$9TN|NtN)+l(Z=1?nox_wkKD@uOhK0n~-}VvG3=eQVG9?6t%_| zj4I(?x8QrW3uAI>CH%%oJG(YqtdRR6nOd_{zFY~vjl>id$o-Mnm#0swgx^In$z4Gn zNC^J%^h)@BBzyx#ArF>>IvbKDmGFm@v?=7FNXA)zdPXJu(TT+m{R(;5iA7zVa%Ls` zsU(c3y$X56iR~cYB44S5KRdD6>5M`ib;3LlRp_ir_)8@ART#))2|@GuY9;*D3D3ju z>5#{ru3!Le+`Q(%8kU5^7HP4g?sI_4^Ki)X2_aVdW+nX33Evndet^iIe7?&y4vV56IWd1RrI2+>g1>5(i&2l9 z*e)j5r;rVt zFmJ(EU5a{?624=EdK3u?x?F~O6v-H|JY=ItYz@}8P>&L_(5jG)BN?H0T#kAa$tb-Z zvWXLB8_bBljdm1?twDoq8j0=sa0SXyN;(v>StPtKA>TncN(eJO$mWso9b35))hLoy z6d}kKk)VOecTtT>LOjx;kS(29)ZQ&up&CKTUe?X8!M1X%4q}})`5vlKN(L3Ob#fl_ z$T3-tZj@SeD`XodL@h)zSECy_;RzUV17uq#jAnS@YtW6H*qXc%g=_~Yuaec2@_m$} z$ZRe%s<7?-Oq-{4%C%@mPHc8Hr;r^Wc~pXL`~kX=Td>BSmJiv{3A1zNao3?4IkCAW zD~nK!oY-jIBiExCL5gdH5H-Sfb}M!TB1T<-UgX5`?oh}sPT04Nc6|eCQAvo&hZM4F zN(SUc)FLNs^s^y_?B>LxboMhtEpmd_<7o z5WEaz&y;k?&FDob=~l>I5U({_AbXmj7^PM{3fVg)tS&+^TKl|Nh3(^37Htnp6Pi&< z*wqZp2vWqG9ny?qLA}2)T^HT~r$ceQqRu`ccIkCONyA*P;6Wgo1LpsrmQqrT4 zLrTK?fiu#DUKEKv(}x^d610a|=|(R~NvA>%OG&@rb;vN9 zkrRu_rxbE>NvK)AWQ1l^5^Uxaa%xG4hnr;-#i%6At6CItS|oh`M8;5zAjN(35EqUq zY>8WSFq3MLaWtcpv?=7wgz#Kp0?jBP)ClCPgsiz(Cee%%f|rGy?WBF4Z%4}%icutd z8&DzVCWO&(8pSA*Y1$*?yp;6F40=%{rp!YwNXe+oq8CLn!<-3nVI=mZ%N%-9LZ}VM zMJef*Rp><}Vcc1!5RHU5S#Cu!N(k2sS?a`Mph5WwdJ&|ojXq)w*d=ad5%`SEqZm0s z^`oRAm!)J(R-+iDWJ)2Ir({GHP>h_|zJxsrxx$HgkTF?DxeJDmwc+UVI3h7HpxBM2pC=yoD zDr6v%F+9Zm=tT)(CI=aE!d}6Y_3u!OoU~`}#zRIDLS*m&icuu!df;z!{{T{st zQj{8m9toRpE8Z1bn3D%lj3S}eC}hfstv_Y05qeR~i8l!FHn17DGL@gTMrcMUnN!GI zN`~Z*Xhta+QOK=Mh{REhAFhO-II)O&Kq2#x;!b+0+e!Honvq-Cd7TPbaKaw2c!@{Q zjN*B=`fEsGx4D&_Hz|KcHA+dFLT-0ryRx;)qi9AkCp3NLys$gm%I3wB@)tBCCw%>w z*(2mmCmpn;et8Vd$cg!~35DF{#3JYc`74T%6N{H;6>@h;_(JBKJdR@Igk7G=2Xap& ztRa`bp%|5fD0^BV_d<%2H060vo$h1?%=LS^Qyx+l?% zQmZ+IJdl!A@(*;QNZ5N`ArGdcU7kWWN(n2D(2YvM*s@9%(TyUpoh={_JLzCOc&Aj* zjS@l`K^}2pHQO##bfZYvLqs8urlehJ=tc=)Eh6Nxlnh86-N=dctTu%_?u4hyJO^u_ z8#%GKZ$u$aq-0$FiEacbYRFpJxWb-HttRAYl%tePD&(n@Ov%4cjZ!kLkP5{65%KAe zJcDkuHXBq}&CeV_Ih&P#qZ~ym2|j^0X6+StsQ`Xh$(8 z^CdG1d&aFyTb`2VP>)JNJUXn9XHzmQ|3y7=ViD@3LY_+q(arN{M+u=UAzZ^2?Wus^JxG!A`2oA0Qhz;rbT3y?*R!>bcQ3<=p7Qd~`+tX~bUaf=rE-JC);ft2lx6?gKA zYIv<%u{R$z0ol}v#f!7DK{dQCB{K@y%!$1((Iu~}hSxi>m~LDlni-jEPx zA&@N+LbUd(YIq~WuaVUstqR)`R@~XNY*Y5s!7(HHH4R3bB?#|RY zWNRnZR@!CbYIutidvm=@A={LMQK&^;Qw?uTNxMR}O-Yk%QVnk_3Epc+A=^2zeUV$_ zwbk(UNXCgmAlpYWhSs%dHN3-#?GeB?jH+P=CwMR7;@4HfJDu1#wMrp7I$^h9Mvl#@ z;aw?V2efL~$%%dWyhUDL4eu@q3dJ&o?Ciw$5AKl7tKmIPP>kkB6|zf8hU5*^@ZOY+ zDP&hCojiMKmo2K{eJN>C$Zk%E_2{Khn(2%cw-9L%ZcrUHzaSah7TuXVN@Y|J85B+WtVJS4IgpB zStqOk#Ilu|49J%VZRl_Ho5TP=QfgG3+di-|P@JS~YLrp2 zRF-A(&T9Ca6Z`$83OPI>^G&j2HGJNQ?e5m4kRwvkE$^y^FGR8mEdX+)6LLnm->DkD zn35KS9OZ<)Rw%`HSHqW_v}a#@fE=9=Ry^)p4aYzV-!`hGk9CU{wA3MaPcWxMn3JtZomJSGZpAplb?;sc zUva|oA=)(Ltau*Zz+dQ<4^+cf-3otC`+%ICk|Ein8qP@w{uOer6V^NPxzGs;Fq*?&)$k37mt?lH zI_x61>cn46%7?4rn~~Vpc_13eI9IfHHC*h3-a(&+EKSJ5uzaK%mL-H%4Y|Y#dkA5( zPc>ZXgg%9C54p^V?M2@tAFYOOIkEZNxI!+66!&58voy=T)$nb%vQcSHAy+uD9a{V3 zW7Y7TcwWz%i@7G)m67$LOm@qD)$rZO?3)jB3cJd4vmQAop&GvD#J=m*s*vSQZ2Vd! z`&Yx&k<6kOK(0wiw|u-BzVF25eKQKV)`{)b*C7W~!w({vU<83&=fp;|S@}dYTKdSm|D`MkeeVyc|(ZI52}VAxs{Dz z?FzX$TG>pnS3Xq@KaR}inZpXZB{H+?mxHUJ$#X-SraeKLo!EZt?eghrXo;ksa)Pub zgnSOEhPFrsQ1Bt`PHeB6S@}#gbU5LS6udU1(}{gmu3ZkThAtDVbEr0Hi4Io@{S`!>eJ?t$3O;KcSEz zC#)wzQU8233`a7>6+uQ~PRz2nw~hIN%)pgHQbYu2|1-2e(l8eWF1z>y^-|rtohVx z_)R3;^jFAzPHcZTzGPGlzjb1J1Gg*W{zw>E<+N(}T}q}E@<2)Gc|CG^HT*s$qY8P@ ziTOuX7*)d`O2Qiqg9>>FlE*ptt23(Mk8Z(}Z`4G{!;qpj%nuFAnbq(ow<3DRr$ZiD z+iFa{QVoBOjHgm49I!{zGuz~>YWPb^SY=cVkHz!s7boPa)$rHI%tNwQS~WZ#nc2C?YbJW+WVKF6b z3aO-IP|mA{suSC1x?LePC+yv_uu{&ihPo4;DKKt98cr;(pOFiy;hzw%2YeJ?G^&QD zODmrJtdg%+!@r!^Q`V&lc_uxN`H);#4gYp4d@>pYDup~3$uJ}3 zMb+@%l(Z`3`IL0aH>=@)Dd|y&{Ml>7-l!5qF>=B<&Ama^abnM5r{rQ3BPX^m^0-3Q zP05TbMKOYur8I`p4O_3YqOT0fGBhJ6tfFIlhpg|!c1G@%OHhqc(x#9NobVN1BA`oA zjUdIZ*|RRbX@qVRnSHZiLM}r&@-uDULDn3h969M?s*O;avFe0eg?0ofuG&`6cPeZvx3Ya- zo8^0`M+qU`glt_B`gV^jM?G?4Eonp{+c@Ey!}O)AQIDM1{)BA`*|sEjv_828^(ZBS z3fV3azLYQDM?ESDbEgi4Z12Q&EnX_uq8=p#WeBoELhwgFKs|C|(N~W`c1%f^T!(t( z1bu)SgY4wQ_R<`d>rs!K(EFK_Kz4RwyK4^13e=;Nj3{K6NG9nYH=rJ+q+cPsI&a$>zP+zG4A>50AQM@}rR8db;t zR<_S>m-M3`Ik7Jyb|~cNlHgGWWB>)piR}p3sgPqKvHbBegQ!SuWmm9FA;(862yyff zI+9zlZXOQ`InjxY4P!EljuZ*Ixhmx3luXJ9I#Nnz6mn`xMr9No$%*Yd+M|%uoV3}h zQ5i!;a$@TU+ZD0|;`c@`S}Eh`NN#0oHwF}PrW0Gi+#?gHNbx)fb5Yn?Ze^q8giN9$ zIk7e|rI53o*mpttWeOE3=41-RsKU;5D->n?(KI@e6Z5o#3OO&5VLbK>I#NOy(;ye5 zq(x@Yk(^NeM2C#6fjCZ70#PpQhiE0${u-{>g5xP;dStY+fHCoGt7zTDzw3(2* z(2PiD^Oakex3wzdX18G97x^W6ky{MVj`)fZYEeptW>uh5Fp zvxXJYS`wc349PucMJ3_41{Kntk}>%;T2V^+6w;ZJ0l62gC?%r`>4xO>i0}OkN>ORS zZx1V^7ZPiZl}z`c75Q2HcplPy#aRotP;cY%Ta==;&l*|_=L5AYlR&L$$I~1eTYFr^BkWGsG7A7sf`BDB(GB0=l?a1?3G2gLz1=k51 zEAt>yZI$1n9=TQ4F7YC;31=(j2Up)fH1Z${lC$d?7VI#hq~}Wu zN_1NOgqj42waAzXTkx}*P;MSUO)AdHYH?N}x0U(O?q=lAs7Zc~tzaX4yQll{1COF4 zkuH8`IBW5+J0hd(@b7;?OY-xYm>-b7leFDa_S=*47&=n4m{HPq6&6`5nUuexA|>bG zOCfhdVt->yejFVMmeo?r0`Fa|<}bAjzbD}fqsGyK{)VOm&uXa&?UMApo+mAV*3clk#`8C0OA}Y)%Ea-_Oq4s$Yp=r!d&tl0r`0T?Gm*~Q5v^oYArBWMtA%N) zpfdS6*Hho5A0b_~`N87atLRK_XWyJ9{ivty>*X~RCej<_^=oBw!$LcKvPC)aSej$j zTTnIXs7;YiF7#x-G_CN*Q{J5Qt`=#aI>BQLXY_zQ0W0cqQvQkNM7petF@-!C&oWQb zAy1<^C05J_AWuR3uDNpaG%fNkw5QaP{nyZ*5=*>?)oqJBg97E2Hd>4;qz1{Z_lAY; ztX=&Z4JtW1_mH$}cmtl@N46ImI#ih(H8-NqqC!DlRKBcULXArDoX^X5TH(*YV_(7h zKZhpe%<6~suCQmFWv!AH_+L~hSm}9Z^YY044k$;T<7iP@d;=mYgIReVoeJ)K91jF} zKIUzsb(8!LrK+&9^RR-*qh(21%jp!Ug_k(Xj^TYRCreJ;(5| zs?d$0WecO%$@;bMn&MpR;Y4AOP27t31n)5z4 zpY)cVwr@6VR10q+otGTFVn!ibxy1nY_3B!9GikrCq91oCeCvegb%7V%xE9`0+_sHh8@E*78VHQJr7f<)k_sSb;;k}-=cMeJK zO1foh4I?Mfahr;%R6~9-M7$fUeweTT$Q3Df7dM`gW_o2=5 z=34l$+t?oKr1$ppN@DD-YvCiL%hKpj$UbhtvtW5kEqs*p<{tmHXZ6^T{mo;}CdFo7 zY`jE@{y8Aq)WXN$`5msYm|;v|`@!rNv)0}rZ>@z;5X+UQ39^68&qw7h*|ruw9{EJ! z&6*T`0KDigHp+F#+iKwx&WNKeUQyVA&MeAWL43SjEqpTOS=2SQ@Ppj;dZK=-owwJ* zr%E>8WlUiQr|0M6(4=f%3!g4+*H}!|sjx#}S&j9ecD$n&KI1kkXh)2O3Om#p{+08Z zWrte$te@A6I#2qr(k8pNF?nY#d=6HYYpX&Ihj^_N{IUvtNZB;Vf%A zjB4+yg)ca}VWAbfUWFYAE85(E>{JV1bek1Ks4HmKu%n#i?XXGST?=1Yi{Y7JN5{No zW#?Kr#?$?1NTiSTbTc!D_te61o^GPQkv=}Adu5keIH62a+N4h;owbS^7P>Oe_}*GL z30C$|YZqe*J=raD-#8?@*1{>yXis*w!cK*iejyu8i*oIf_tnCe{S2GY;kgxd8tjF= zf4*0CtA*3uI;&^mS=bV1_M5Z^d4DaO;Vdg*d^zk)*xDX}S;+3S@D;Zu#?0Cr>?~MO zV;%B=TKKA`d(l`(pY7>xRG2+#;T%t!l12JlPxFS6e6SY2M!NJEeEq2w&T|VCLfNwx z&i8Z^aV_Z!$}{kz9l)+|W#~uNq8*oRSv9$8%mbV zV}}%WBkV;zw@p4-3qRyY=~tI#r81=On-X3qH6wCRE&RxH&ugJeVK+O&XJ$3?sap6k zEGwDr`DrD6i>LV>vK(9sO@0nBHCH~Vu;yqpC7-T^7Ekk~Dka_OY1=94kXmRf)2s#{ z-R|jTW*48Sg^rk>Q_`KJi&C(Nq?lF9p|#M(k-QwUv3*=&-G25B3#24F9!FPp_3UJHX9 zDSbZk7S`}VhoD7&ZI{p2!Z7L5f7qP5j69U1Bk9q+C*3;b_EsQ(2U&!JG=27qo&x3wK?as-OwJ;gkROZiNQ}KLuQp#Jme6bd$ z6P}Ms#0u~kcy^z?#1co75>5{`kJBPws)bdNyRYt5_^oBW`1GS|;U{iq zbv0@COACX~yIl_&#WA(8I;O{!^aAO!zfa4twXnu5nwe>kzRlB3^J8*cE&P;pIWo9c zg5M4=y|T@Oj<1EE!Af6Hj3Rm6Do5`~bILsh`{~uf&*52_T|eKVr0)cuv_8x`?*)s zVwdwo=d@b*o!eSV$!7#33V*Ut-P%fJHsD#Tk}&ZxTiB~;ZHE{*G0duHe<7Ajy~dN*i~4> z^_5!qv$H%t?oimHu%e_{k(Kq15jm?C{^GWItlO@z$6$G>F07KT*1}&sy^>ld{kW%l z8L!T+g}-^aX`xd|KS8=^$6Z`ghn!Oje~0;9Fh*IK7txAx^hu7E<a$(pPx&w8ci1amtA#~p`Fv?eVHIciSjv-CZnaQ_W&PFq`HVtpZk3M^y>fmn)L}1Z zvn%HNlp_tdUcnt$o)^@@KVeykt>n2A>8DATy*5{^eE$9QTKE@7%et7bvLGsgKjS&) zk=2x3SPTD-%$^i9E9_ZV@oSy(jav9mk{|OzE88K3KbP=gJa3YVYT>_So;C}_d&8bD zSvG5Hl5f_+|6tkgbo2CqwEU$=^Uj1Q>Y}H6Xcwf{@iglr2>w4ODRalCq z=xO_20_pWgm!7m!mZ2rOMH8)^^!hP9E|;JslFnM%iunQRqC;UDz`S(nTUHwE>W7k; zavL8k7KU#Ke?d(%0?K75ik>_Digw(lu#J*j3hks@zJ<1!@FL!xQ253%4|^`sA(x{r zx-Cz6%xm&*mBKfHdmouEuF$TZr_|p@ZHzft95bn~O<_e_wr{{+fzs$!=0R*EhiwKc z8hp+z})9Nnbw&0`Mv6<>+w2+Mw_iM4Y*3fTgZU90t?;<=FZ&xJnuE*fOa z!+c)9!nSmlx9%~y3N5l^))Hw&u&tcsv))1Z9*QJv?Q3O@1>YL(eVO&g%h4hsMc-Jd zq_^=j-+Gj*Q6Xb`R!MK`Y4&}UYfv6N&EA+wdOJ_ABqIDiile7{I8J)|GR^buYf&0K z-GbggdI!?wm1pBOqvQ`z8{u~43n&qnml)$D0YUxDxLwpkzI znaE8jm8tDq)*5FOzK7f9V`QiN2%XXyJ~fLbV0*$|R0gcqL#d3`rknAFFw{y|-qKK; zevDG-HhJ7ItgyYE*;rwt^DQWruC+t+Q) zyXB*KlQg4Ox-Cx)`Mpks?dL3;brH+8pjej7;u%H&*#6G)IZ3CqqE|-N$Mtk8>;PEl zbK0a0r4o{rMDKi)l0Gn|TcjO@l5}>*%jYMEzJ~ZWpzwp7$GaGm4phpNn^JBq9)57l zcS1T*C_T+P3`+VC(i@x7OaA{M!_uEe7iA)ogDLI zkH0L=>yr^QO!$j>hScKw3QU#4XY4fFrX ze^5EHgd;v?T113)IF6PH^%5@n-LS&XjNHdk)(oO&!VBMN^ZY@Do#nRX(Q>V9P$tne z;V-D~yw(Slqi1_g`PGlg6iTP(RL;bSXyE5YTWcFLGL7mPnW<~j3OmnPu5L`q4BDqN zR0iyZ6?TEMd(8dcaOu&my$URa4o$UKnDqh&g` z9NV)V(4_Fo5?;&=2W2&SX2MZ9tjDw|{Bn5i0qF}1Xqle2T?P~aoOXGarp&;B<$sO8sX)_s#6qn6R7MBdClZArBS&HMUtb%?=+vUfSUp31?AJr zA^9beB)s@FYxbiGyCpKj4IIJUNR!F=#e+FMbcQ_XwoJxpzU}fWB+6*(oxMZht3QUVL6^eXVJ~oO1Sj%q1Wb;&w{$tyc-GYw+NV}O}6;2 zO<@DD^2(`OI`;jDmu{K;5|5{0Lolzc!i~1b?~pJ{+iYlLpA9J2f?DDQGzele0Jej^*$ti5Y+4c52W6b`M-t#r{qzD&NQ!F z8tPN{9SP6nV#?+(NSyIEtlTFRb|)+=;~w1PW5}B^y-G>n71Mq4S0qhO_cPTYeYdB3 zag&cDWyW-mlD@~&J@cdTH{?rCH{shz-|OjSg32e5EImDd=OKNcr+LXh{*GKpx^!}_ zR=T;sN9}R+ez(4XhXzj~Sfykj##y&u zV!o9=_b+%ZQsT^(iS>|#q2Bb9PSyWH|g*?jcP}tKjZ!G9; z|3U3^t8DmTeGKdw&(VfT)9G88MLmbwnex054=DWEG7p9eTYvgrR8LqD156#Kfal!E zn#T$jyFHK8=@~N47hZi#;m;Q*FWj=^q?6@;Xq|xUx~&#YR){LqvJW3o;?ybPALjl6{ORi*ItA~zi^ z8(`$6_3-kThpoHmP}urzoAsf*)yul|@QP?_#nP*=4H8>glC_2wd09QY(s?#mXM^CF z!Z-9hnt0cyWywjhUOl|ZnGLM;JcVrp%Sy+tp+{a`53hz4u7X_$k5kabpzLPzDMlW5 ztX~hWffpm>n3CRvbTNw9gmPG3Q4gdwuEKQ6We@BT})}S$B;}ZHmZj=mFKZ&gf5`4t(@ht&8WP(9^MSI zDmd+!)tA!QAX`HUS!C4YkmBE*Y+Mg-i8;`~@b0i}V17q=gC<6PO+CD|$T@2+EZwY! zZQU|=rS@p7OE#&8w|TA>@!I$g+s*1tUtU`eZ+C8uu#hDczP;y>$Bi?xX+6Bd zZCe)F=nVFESm8T3w`P|=`kj#1)x$gCRu&7ltnOxl0@)E#w2M6Uu&LmjY*r8N;z(XE zS?oEiu$^FD5_#PsG`_wb-ktDb8rY)nojng?Qrgy}Y+euVafS<~e7Y63i=Ur&_k5|; z8|vY`rLDR5HA@w?D=h0$9emhxMz*Mj_c^f=YgNc@kfP`G%Ny(A{hnr{86~}YnP#cY zmi6!fPxmtYB)x~HZEN*6)x!rp-NGUa(tDCFdsFU+Y^dF;9zMj8G7@MxM?rg~#@Vfz zcaS&N!-qNI-K?mlY?Prfb98Tx7JhMnGx$DUJ$wY_6)>MGfn5sUC+6hZls)$%=8(74 z!$&sjz*MoP30nZR+7;F{g4hmNjsq3y$u`(X8-kYIMW5)3fn); zJAdNTEZf$@$Khq+OrN5l13W`>q=WLddiX>%!nK~EpaWxmlc-^KHDj_}J$w>gxDL7+ zPfK72!Mse1(I*eko8;~F@F_nd9}-#bSq}%t+$W0XV-vD{J$yRNDSH-Qtj_3CjvnGU zF)5poX>)}hFqD`Cr*QKzd{dB9> zytVKhzj`<(@?x@vJBA^~gas)}+dA^>DhM!61!4Xjj-0XL&`9$@}Z!444)BIp-5W zcP~-UnV_tAR`Qv&9@)Jfz7kI~@pnvNXTjXLWH)Bb>;v`iRk&YP_Bb7$-FAm^^lXln zV|Bh%p*Ndt`@Qr_^;*TT&Kd$b(Sq{WqH&G>)~rKcP~h?knzMX<6B zx1A#&u7_{BnaM%cCSVFHx&Y1J1}j2@z3buP(w5lKo*4$G%n@JB zaACSi@$gGIcCDXNRFmC{98eEG@ci>O+NZGVVA=hd6B(9I)Wh{|l}9wA3R~ehngg3E z+S7scaD$)CEAu==gWL$oT5~VI`N?|tq34#nGCoCE4>v_-OME-!pnCWb%v*TTGy4>N zGrVZeu4NQzlzgflew?0_t7roXza`;Ce;JU2>!AsrU0o0J2-3}-w#`I8T@NjuX3I+@ z-Rfz!Rh2{Pq0Q6X^HWN?-P65Hsy|Z?9iHx4Xjamlp6(_8L+hc-)An&U(%og6IPbId z(Bo-78K$Ir%QPbYVfC=m(@jKir29P0CkEwn_0aF>ZtjotfTwREiaop@24lKcNe_|E zYMhY=dlcQ44T!G_2*9Wj`^&H<*Z+*hjETt z_h;^X@+k_K02JNLCWBcFAxGB3B-}I4hTk!TPC<(ZqEL+HO|kI?(IH=~hiPnH$xp1l zj3>c1)XyHL;F)-8`3hFnemk{Gv&B?_-V`(J<5uKs)pb0oXT5saTZ3k$no{? zGtZV)EA~?gyTfhGq2&@|i=0poKZh3=man@URp_12vi^!SpGo}<$%*yw3;z{XFyRyi z6?Rw5EuTs?$w~F_%V=quV6VdNhPkx4c1)aAbM7))qyOU7cxXxIa=LLcisM^3MY z-}`Ci-6s|Dpr3|lX@w_C>fsO0vhiZRU11Nw{4R?Sa7fOmhd(;E9=fz!S(?}?g+B@}OM#+4s~-LWDvK>yW66qV zjy{&2&~&zZwI2QoDtd$kCtV7AJZ9ogNZPX+Xpyt);ctFM{`9X)VNW>AqyK3+ryl+e zE3dBqYy~|TGtQqZdzT%ObL-(Bo(XN6_T8nhr(i{)v73N=tsWL3S+VC`*xGle!Yh6@ zo^8GhHSWB6s1^*VgKrL_G{S0rzBQ>_-0zd~>!A)WO0EoT?WPGqIoe3hqFLCv!*W4A z{ImE4uD6GOtaGi0r=8_u3VX=b!@ppqSdh>EiQttZ&v2x4R3?VB%Z2suZ>ZfjS8jHY zXJ4Gd4TR?3sE7X)w#YfQ{u%NdB&*as%IlSj>fyhzEF3BnQ}Q+Cv|Bm$JjY5WntPv> z^38hqUzraB7WN90zZQ8fM=CU7QPF>4-WB|Tox<0Fm#s0ApmKLW|GXF#*mFV@%B}>q zuIH5dxLgEUiWVGgO(^S7*m|%mR9P|KB+Jl$Nqb3J^v(4`*N0};Mu%`W7r}XBNJ~HgY>_1+2M}Z=w4- z%kOSnVH?BB7CtMNBl$wIE9Sdf3{&Ptx)r{Oa~s$5r$W>6ZRB6)w1=`*;hVw>U)Ow& zT!H>u7-pB*$}@A@ZVkSfXJE~`cp4_(sfX9Yt@^S?=#AEVVux~cbB>l%T^epy!z*TY+2g-Se^%^%Q3`F~hB zwvF4{EPy=ZYSduQ+Z;z8+w>`XTXA|4&UBwsf}y_>a{4ru)=99r}0B}aI0)l5l#9B=)az$)pj<#GmOJ`bZ!l9WmX@( zavd5l+`853OXdfc*q;j&x|3U5W6Xsy7TTf$J1=KrloovF$XNtjoBQE^xe-0sZ8K41%~FN!2Fq$;*?h+dUzQ)D z2}AO^7>U2c;pIS;mweu5+mxewr)TA5*Cn?g8ppFH zxHrqQh^LgJ`}ooF8nW<~&*w`M(y`}hx?!&F^eB8^=W(LJf?MQccou3}Zfh-rx4X-p zQM4@dE0+8D@7nbgAt=|zFeWX?$}#^57Rg$9b}4*+cvfpGsi9URWl#6AsGjrzp6=lT zd~K-7o?gk)f6@nf+CKEzj)d%K`vfrQgFM|t$kBmd9MdC8`e4#oJF<_C%}FORacMyd zCVfb0!6$p#r3+cOBnw0HtqM65;=@%ok(-llq~L^RZE#GXhe69a&wX6}Kz=}akbskO z^4AO%dN?$@N{eh~r56<#lJzy4{7o~*f*s+^UKX)vcO}}dGgC}ZP84<|EGzTtc|hNX z-b*^`6;`9!f=%umeiXd8t9&?Wk$xm!sQc@DgvlN^l;NLZb99N*4Ilx-J%}iL zYUZ_=|8w-%BdzIs1T`^;eXJA*AB;Xx`8Ak{?oz zp2*SYw`c{!h{fse*z}P8tniaxoKs$V%`$>y%+aiDtR%CKjPa~3JD0z_8mrixicJ|y zuR2pk(T-!Ld~-az<=mOGt``-VqgmzimJ%`A7|L-Z!(0|*38WbC?A_FH8AmsUZJW>i z+^y#~T};%i6BaRCmtucrnFrn4T<-+3a{Q%HDhYB{v@$2(B$Eir&hp{2S7B%SnG7Cu zn<+$Nh<6fuRLIIq=(&Eb#h|R8muX~USRUsQbmU6-oWjp@+dK@IlNki$m}~w{K(9hC zfR-_O_T`SOL(C!~b0lkmRxLI(#;?I~^uqENvTi&rbI8cfmNS4|z0jtxi=1Uw!jrRA z=*W>Foe*Kd6qesfHXXJl8r^a$Ix^hq^z>7*huDy%<=I)cUnM_5M~0OpmJKory(Fc! z#B^BZk&=rX7j9X-95EGg8Kj6AJ5G?*Xvl#4Vk|1kFG%5+!;2y*KW>l}Oph!eDVJyE zGkqKD6n+IfYnE2Q{jvsC8Im=^d^*>wuq&PAA8F~9+t8Gq<+F0OH%3v0mA7hBrw;ik zdh!b>eI2?yq2^cTo8)%%WN7JE6RCqqA4jj@Xm;z7@Ixns->M2k!Px^kvV%8fCG* zR^c}~&)1XW^5HK~o69`1>Cl+MZgSf)mcs+yh2reCM7OJX)}pYRVMQm&rqru@_;h-& z{1T;^Bc+eGvYhlMMCLRoQEYC(#(jA%tQAp6m)wo^?7x?<=Vh%i`ZKI7&1{jr{0bEs zn$=7m!{<|Pc&l@MvB;lImQkfWXUd&B=~q~L%sC&aI_1~s)1HG(k9k1CzYc|WI=A~O zW*KrXdNn-jFqh3YouYv5m~B>d$j-k(wuTlCe0skB7zOo$%C?tJx^rcW<)I}|pRW?rl!&hJV7fF#b*wMyCB ztgGAD%wXdsROo#1BFp-ahfvA=_jB2$Rbg}S_sa*^#qa+Sm7JqlndV|lzQhfFtLK!x zBE;I>htbDVTWgsnk-_KVFXXc&zlSFI6Z$wu3y<5%6BWpU=bf)P>XAp##bMsd^5IjV zw?VV3D+fGgEPqBGkGw4tDB2j7;kP@_pPuC}>phA*4lja{LBtWr9gxD4**t4V{(>-G zG8<`lc?))@Gkf{b)($;}4DPwvRShZRF31ZSP(GJvmcJr~dmj0`Yn8(8c9sVpE%G?B zH>_;mnOL>ZqVRj%*5YUuqsrgv;n!|!5!%S=PPR~3sqlN9$38MBPoQ$ct$h8_3v1Az z_qlcPKxWOwghP2mqa z&#pOZS1fNv_jYbI*px-NZ3=$`p8aC(NhYO=_6;kq%{*DVLLY?|VM@~}QbYIlEX{T0 z-ycba{^ZI!~GbY6}c36PW!C>j?&etGc`Vd5;jmxf4d#BR6cEe3wCSz*sa+hRmmXp!d-y5Z$0m@j?G zS|;%kN1yex@}bnk+bQ`kk~h5YD7H-!;E6G zVo%HekiOT>FAt>Q@_1QuwzP-svK!$gu)uKXp9@KRXOa;MH# zz`BLe!Y#+MRA+37tkVcD^ApYG^fOV1tq03)+4gGel9x8Z%Tp`5xWd+lxf7%EtSPj} zx{dG(x6QxL(XX%#BD0r(#^q&=@XF+T3e2i>P~jUowlx6ut@E zE3*ho^1(ZE;Vj*JMI*e{&&?aU<=Lw6O`Ti!%-0l7%La|`I(T;F*3I+DxPSYIqnr6z z`JkPxVUt%j!t0%LZIqn}pe+jD+_}|8e^#bLvSA~1X6mlUV)OgN~cVcED5-U2IYwh&{ow#IJXjj#~tN(x%Lmuf4 zDtudbR)M*;p1p?34cLn8iOgGV(g<(ECij zoYPJ)?Bq&){(r5BXl-2=8{b94};53ELS~cHlzLkpU+(8zI^hzH7|G{C$gT(FpH@6>|ui@Pn9Lrn|o3Xc%!V!h-?ks=y%ja<$;RDX{5*|_59x%T%q73VDee$M8_@Hy^oEACS-NE;C9>>mB z*{Tsf1kc)wb zrM|Thf~T8!&5QK@o^Iy&wvF&{Pj}-YNgv?pW;B4eHNq!6J;1n6`asgz6`DTXCEGQ^ zCn04NWp5;OEA*g9%?0sK-rfkGiZmC;SRma92S=L6IAgMXBYYZ~m66p&{%Ns(g&&ey zn}F3N?`VY2K=ZMf*vS+S*rBlOT9>U^w&Y~lp%FgodFHc-{2?{`uryD`V?HqQ&PMng zv~>Tuf|BaL(~8aE*p&U)Y$ZM9Kp@1V&^L!M^JAaeBs}a7y(ejq_ zx3T&aek9y(6!E+z7{Tw5(5yO}Z6&EY!=Qc#fM#`PogZStjpkgyZ6w<~J#0g&q$rZz_*#dt{eJ zI00Td`h0-QUO3?WYmT1C(d>4(y6C z%?oNk-ropkaI`2!*TAz#st}Zh6q_@#vD#+1SixAkdn0@WQr2zH5(S+FGPUD$YZBSu z^MOYADli|)GR<~OVQ0s4rx%8o$R3Sw4yg2U9n|~_*X?6-E;d=;u~4H~KG+CfgJkt+ zMV^0(VN~Jg!Sf%r_oR^N_iTjo-PZE9r*y46lY?IXPm7ngV?NXfUw3PA&gYIiHHKdZ z&#s}HU+k8>8sQrdZ-sbWv$x`NRf5m@Ho`@I7N002MEh_fd=pYO4GVc;3M*PApD?j9 zz~AlN2p7YPzOlCU%x8QXVJSz8ir__;Q{*F!unbfb6jNk{T;f^SvjWP8$u@;u>1VS#h4#K*BYd|YS-b2}$W@-76<_AB7W4+>nmLGu&_Yj>)=twWpMP`3RmI#=kt2fSR1^6{nr}!hHZeAA#lo`pcoGf zr-#kw(OOz@(+k~#bS(07_vNPaf%!ZRvr<&&2+n$);s|^rT+7?)w>up^pC=%tuH2CC z5$GiJUT>}=&BIAR241Pw{^bJN5=pi4t+`SSN6hD~k*%pv#tPUrm^XYrZoMjfWIk_?t7E>0?@Qp9 zN6KM7wX-1|IiJ59DSe5xJ(9p@;YDq5@F=-1n$K4RbE|epU~~2L>bKPEhtg5=c}MWN z@lFZ+%HV4KYuDFV!O`>idy)4yY$V+*u&ZFvsZ?n*79TU8zaKehtW($f_u>wKUk$IS zqt6;kQCsQQ`TT?WD#l|Q_Xh-iO>pf9e$|?E+WV$;8j(PE>6eK=O2R> zxC7l=z?sGK`6nIO*m$VBD^HluKZVD`I*(;Kg7n(B%Eu%NNuxr{$mi$c}yU8*4LV=ST$lgbw2+IUbVZ9 zupJ?Gq<6(t#V+9;N7HHZ`Oom83_LsryBk)XVhv7=)93SFB5!@;avrvJPo_dh@2T_9 z@qRFUY(D=LW>xL&T&r+e;D3v>dZwbf;m?@Qe~+}TWb`z@NrBHtS`Wx?PiM~OMle6y zvsYkESTs*ttvs1NKA&5W(yb6yj?d?INvX37n_`@qJ~5yF0WGc%4F>CRLVCLQq#*kz zGCOX_+kn|bJfClm`Q&{57jk<~Mif(el&ir14X+tT` zQE$wsaMf*e@3ZH| zPfDwB#Dl6EY7}1mP2GZI=g7p36z$A|>1^EbaBGx(e584+Kz6B9s`=~ZnSBoj$@T$GIug0HdP>}9b z=d@Apn!bu}9cJBE)nTVU)dC;1WzBm=NV#|1(>%QzPMGaVU&HGjxn6*sqh>Sg*^$;& zke+C^Jza?JJ-AQjwBxc;9sfH#l)#P>OGF72qZ*IJ*YU?k8aIa*oR&uZtYXJ2Pnt3W zXi#f?x(I)KeNWx>r(M5a;QPY0tf(70w>ETFhV;>I;GK`Fv=RG2JRtBF1|OXDcF@DR zgp2Xe2iNvw)&ivle{t|y8Es47#7htNmT{B@{+0^trIFUBK^|eh1TTGXw;fD72>j*n z%FtTBEPV?XeaTi|o>oxX!_J}&lIgGF%#zF(bo zlC+~~HU4>6sXf=O+VB0th)DOZbDE-7eG1csufF0MhjH~L@HfM&lI&WRx^dfs%He#f z?W&WL`TsUS{#NAW1+)uuhBU7H$i7ziBLaV0r1c=lmeh+|AExd>^BAi>6W{@nfv@GV zvx(9geEg9CE3A0Wet{hrX?>ofy01U=;q8YPB|bE}i71-RqDBPCK}gIvaK)_Sk^Y%Z z{rLTBnKGaCsJ20NaNMa<-Ygd$!2b^~b>I;eH8u2^Hww~2kj7wQ!AGryt~5v_Ao6p2 zSa%-w3H(raF-g`c!dDp2P_YuHgPB$E=|J(2jVt9Ay6Md zzrYWJhaFPFaU%o*>b&X(<=@gndU)jJ_vq#E)}^(?1A==|>Xj@P=^8zL(UZoB2Egr!)v8jxQy)-;^n{YNZz@U~i3LPHuKskt-lV`!gqNPCs(3t2 z5Cw>|)G5q7Vgg?ZFXbE7sM(Zd0ymW=i3-HEs;YfuLchS5!=r@DAmk<7lQt0-2&rm3 z9~@(jg!E*jl@S=8oxwCkWT5kI>T}X5I($WNA9(P_;gXmpLIAe{CS1Mp)D;3+StaGM zT$^>J%|r>{X25Axt`W#-k@9?cu#Pw=t~5hr0A6~&9gbHO8M2SXHAPR_gKQx}5ZCy) zuE*4Cep?0EnaHB3Xhd3&W^GXMTZtARwdc}-WmF)ah;il&sw}=skN{@g z!Znzk2q*BfgKHUEh0m@_vjho(SCc6kEBqX|m9%p5 zrJ0ZMw1a7m06}5cD7?=}M+@v+Sn0sM4D#BohSCl~1i>%B#wl+h@Gk||Nv^IFU;$0K zl3+pbTHCJ|_<3-BO77Xwp{-MYkHA4(75gU{O9Xy?xysstIT*_%aZ9?2umMtS)JGqy zdStPHz8V>+cF>LTI`jHIk%Qpcc*+4i0>7}_fXAx!v+CQ?bT#pVxXL#v=up!w@QdKu z6xHt7vON8O=s~2^*Y;*NDe#L+{`LZ8qo2P_x`wzxhqUMtwT84WBfTW@)WS9Y38woG zi68`bjiv_8gupKi?xTqgn^WmW#0%ioarn+PyFnnAK|1O{Mx@cMcKZRw?5EHq|F*B#fg5R756C;gOQ0qpVK4t&BlR&r1+utiAG zONtn%R5Q)?rE3WtK&^dxJJkF33%oD57rNTvJ?Uoz5a301l9Ie_>=z^hNXi>+(5gz; z5kiPuw5Wa6%UXdCMOwGzd(+PeA4J;PZkZPNNGCU=mY~)31P|bqcIjxtG$o|#inOBv z`rxxM{es{D(kdwAhO#>_?El0sy|IvT11XD@qh^7xbYcxqx`BWKGJ9it3qpdhv0xWd zhic>fk}v|y%2+k84`EXR-w4+RwA9Dz8wn%SDU0VA_Z)l@Ufy-81T$luz^@1H`lyu-o*6#H8F(X>K4}}J8Lja;alKE>G-Rw zS4x*y4y2n2Cm=1umwj`EVo+R48%SY~-Mpqc>NU(-T?1~7 zPk5oeLM#|Jr`N=>Fe5M!vXuv#>w z&@V`Sf+U)o+r7n^KAr9$&VV#J&qAqc;5blANO|poJKMBkd-@|Whu~4?+B)FZ!NcC> zX|%f(tJ!l-cM^VxYh6og%bOJV^}+S3F26SYiI4+4-o;{qQ`WtwSR{`0hPcY7aOMn5 zcM*69u4QZoKrwK_Z-mDa78jqZj}7*O)9KHIB1ofce9_V7^n%<3DP{&^oh^9Qe>bMP z2|*yU7OlQMl(4{Vh83e>4J%o+-)%{MAp}u!Hqs}MTOy?^H~W}Cx`*fkTt}k0)qaXD z=vGkaI_gaBPk$x&5SM%4-9KszzYQLRR)R>bE@sl-2ty#X@zW_tHe zf&uZni^j+ACcn!QYqa!V1OXsc+8UDAH8QYvq~aqa?DF_G0RTvh$>!A>66imnMJ1>@ zE1e|$2d95Wdh4!30{u5MYO9P6Zr=~4|KjpTT1JPlV#p;)d9xGQXQvoSf~3n@&k}p zZ_8AfvV-mfEzdW;INiUI9|*A5srsIcJ&a+3^g&3is8`KyrVt;{$PX@r+p?)eAUi{< z8{sUZ(spX(ht$+#I0FLR1!^x->!QB&z(#&3ycFs*Ba>=2Up>+-NFRo@SbA)YJ2^e5 zksl7y_pl*C0FS71s5Fx0Gm{?N$d5!?YJr1vX&|sib>=$0GVR>Rj|P>B(TS>CbMRf^ zl_FZJ*)H5zo*vT3kLgTfuTWyKu2i=OX&&2|Mh*Dl#r0l~FL#$lejI7;)gFm@2$IJm z(RW^|277vFBR>IPZ>1v~%k*0MCG zZh<^4@~#cPiS(#OetP7i@6s8STq{WTL>jYz9jnerk8b2=fJ%e(g6S9NUQoLs+eDa7 z?b^uCgjn&FoxlRy8&>*9*U9NIjr^=Ck=ZVr1omuLlrbuU=kh*789%m>pA%Q$KBQJA z1-1{&#w6dL5RGd(J+6_Ti_GezZ?4Y|7h!$_e_nl!`i<1Drc1S1NZ-iMN2X6eeYr!} z&MDB*PLS>!IcnM3@<96J6B_viaC>22;5{X<7sBr46>?9E8TmBH-5U8tksliXuuXJL zU9Z4j46h2>*BL#rkzWEW^&VfzD(15weJN6V26wcsNxL`l%OZarS9OYp&sg9uhpXSM zifN@MHS#MW1E0=L2<(+GuiM%6bd5b4`Bjmn_A&2`{Q`eAJRYu?Q@TKn)1A_j8~HUz z%OMX_3#FFEjgRQhq<<~xJF3;r1VL|XOiyX#*CEqqawAqCuZJusu95WAMt%dd%q8pb z$30OfNg>64q_753FFG1ZPiy2iF66#K8oqyURipmyrQWu5(oAzwvw;-sBved9%jG2P;tw>8fYfxr=dPXB>m{rr- z9fIuzd0P-&@i&t8YUH;={ADc+q27uifgb>`?&hnsJls2zp4rInKx%jMPX$d0?7(1H z^4bs6-i`cD*uvIcoMf?lg)|3s+{ucM0oAI1EIq4{--XoPVT9g#mOu`M*b}?5(R&T1 zXE*Y@;r2|vKWMYS4ymu+MxT66BflrER&C+!zfa(Y2KQA6R=H`PMt*P2)o0?B4u2oK zl+QFh$eOg(#`^T!Mt(oi>b)08NyGaIX$~VzjIy)Ci_-HN`2!tjZvA2b9S*YhS8Y6* zp5MqH465^uHg~_U8jsKrkB&1pz`315Pv_ZO_ znNF{2#e-dfwED<&D68NX;tHK!eWkX%*4UPQixJnhS z@9xk`O2!7(L{FD803jzZ|K&XHN<2 zJXjRMY|rA98~H1sXu)OvH74-$;Z@;i=TnFK`t-I&zM#IM%*$qb1pd|FrqZ!5^l{(b z$X~0t4teIdnGyJf!Rxlymkwy;uLpNmn=K(1_(j20fpoLRvY$ZgI~w^L!QEZw!Cv^q za4R}rJu{vTY~*jkI#fZ=asgff3@vD1fIcg|vys0Q*_t=f9($9(FO6*NLz7sL2Q~7y zVWpm34OH4!yBErZG?$U46zKWnrW#(OrSEFw?;z0@Kojnes8o=yMryj($9enS7*#Qt z4sPTwWLoPhb;`6tAl)S|+9q4Z%yusa@uhb+au3o{Bva%uDzM&Q8aQOOo(^f`HLyxi zxI%C@wp$ARx9`lF6w>#RK1#5x`F~F%_d~5|4a^PF9M;SYp_t$U!F6qg1{ky)4sGPY zIv3^vNX7&@1TCdgC=v~0jHdTC@-WiyAMS83pZ2p-{%+{8DW8-hB_FMk!aednl-}3K zYmruOTw+g}viK^!?-sYdkbWKM%NrA(Gn?`Kjl3Rey^!ylG0TB$fZWUcbv5nYwZj^D zloX{-be6kOU}G>VxiWQQuozDtXyoz8U-i#Mfoz2MbDXj0WPOaK>F`FLfL5J1M$ip{ zWD-ee8-fa2QeK-~>4S~DsY7bcpQ;@T(kY}x`Svlz{7@rLS7derD-I!>A@<}x2h+Ok zP9JXM8F;CuGSHOTQp>b@1|j7ZQZ78LesMaYk+*`am^{WcF0gH|=ys(_ZTuud!QIWImuGsm&2nw+F^3)4cVBEY~=686}}qNl|OtI9!2MYz%q}RNsAi!iq8CW z0I)-n1<4$e(zL?)WU zxI({i1-YuEaxyoTj%noY!;13XjL%R&SA)X5V3@tH&N#M_e^9cb4eA;9+XZ$FEc&~y zQ=xSp*T_GNlpda3FR&lMtoVKQV1=2EZ{#1ttu1LwUMG;BL`pw&O{-%jozTcXg;y1& zD}7WlE=aD8EBt=CaA{3i+{izJmm<<0H7u~}V7}m9!|B>lmZTFK`R9?;$BsdPT@PE> zRLi*7v8)--@RCOU1t~*mlrVv%v1!#5w^0S+N~23ie*@{G*l7Ohv|rlDzpS4@gE>6{ zyAf8sv<8Va0K?vdM*dYt9@ua?eT3cwb%kNZxqr!dc_aTCZi7cXp|G%oAiEh^)gJoK zNGCP&Z$QzZii4n|e=_qW%`K!U`btfLp>%R1{}!ghstrT>mjG{#gxI4b97!K-2#S{6~PcL0>~JkUL9ubQ|WsMCMOzwWEf;XJWNdn5 z5{vuejogC8BNnaewKpS3+eoV>)M+%hX6{d)Xykv8#%kDIq4wotf&a6?S_BS6B*n?pAGB0$>qRN)JPg+Glqs~u1kg=H&qL(oO$&NK3PG1Bk=& z32SuZRf4?}>2m}$f@@y>&7AcDe-zvu5k8NgZ@VMn^F%k0>9cEFCv@j8 z5XXS2)?=lZjsgODEXZC+&-x$ouPLN+301($Bm0;%Bhbf}Oer#5R@RrkNTdQ*xuA9w5i?q<7r#H@Pw4Rld@FHCLF+DCVBz!SJMx@Z8=k5 zd%*m8kFmv8$F4}{5xaoe+wplUtl2eu&S*&BPl-Hra^ID{Ld+sk`Ycv$w_bri4IUl7 zI62&M9!cjDzlf`Rgtz6x0^c*Z&r*Hi-vxv(f=6f2{a5h4I{CUQdeur#UnPtY+#M$j zZ7j-x?;Tt<=qej(r_$GmXu#uXeHB@et`VfqMjG>l;sSBy<>xc`kTjMqB+fxf>zux` zn#~HtIbb$~;3r;`zD{tX<7VYH#m_8ApNBMb;XsBBXgWY3!~2$uw}ZEq$BV z2i%^;pL#-IuZ5MVb+{I_a}K7k;mOFiiNC(oQxz*yq zk|VEiL9!nbdnPq@yXn?zh{voZ!Vz3QN;y;lPw@SNS0zl%brInR9<73LM&NG_?p_)- zvIkN(Aq=?HsNQ!{AaAWx>I78nGPW-ex(H4!@#JRA2>fmE(h1Zy9Z0=|Fd}U^QjR=E z1%3d$vM0AMOKXT*fT{|+&-n%vDrpX^Zb28(Tl5jffOXm^9B%|Y2R zr3?|bh_o6L@YQWY0)Jm{H$T{_PV*WjVi8=mpz3}-njU@_+&h>W^3{6|rV+vw9oMk$ zRIlk3_~CG?W{q5KOlyf*K&pmX_UKspX+ioSq*g1M!vZO3^xO06h-Gx#s|@DD0zU%o z-N-ub=CqzTMqzWSkFrpvz>bXTz3g;7Usu{dB%|h9o>qqfKPtEy72c^Q(kPJ&xR-|= z?Q5=j?b3qmn7BrlxE9ZA8Y6xIS1o<~6`!Sm0LKBU*;FK*NaF-AB76U4xNe+MP0%mM zPKfNQ5EXr8BY_OK7Wdq0TrMjGa$=;^$}C^_OA`b#;8pY2!%4N5>kImvuv_baKP`Be z$U1<{5X1elJGp<5Z6a+Yh!J`E zeN^S!*1&S#X(7!gNMmKB_cE)1YEX-gQ~n8RAT0x1FK^s0uus9f7qY@+Ds3l-0ojR$ zLR49V-@W(PaYqJgBT28C#U*h*|(j z`IJdODW6F}dTz;;L0)yzblO4GqVtMQ4|1;{{SwkLY^#N*8#1?~D~V#1oOm{U_5p#N z7io2kt`AlN>3f7Sf~zH}8_Z~n0zW_U(CsYhB)Ezo2CVGyi;dgWrZYkQRpeG?zMVqj zEcQKz^nC&v$l~46(AuHv66JuG zeqpngQVWxUtS_#yG1&U+mh>}X8o{;ixmTrI-~++yeH|0&I$|1ddtx0LOb3-UPDL4`g1Z4?CyokyOK@M* zpkw;BbTcswcx4ZG;pybFbR)VpX|`3@(pi}mp$rGpZ-`^St0;mueUFPTD1NO3%xcnK zUgZ;>5=!G1q8q{0ec^-cfWT*i>swFp?i^yAeoI^fUX`tP9-lA|3eq{G3mcrNm?=B_ zk@rfs63-yby`KEOA;sby6w+TwdLKyHy}Tv;j`#+|8dTK~P#*BBg4gx6Dcwe-18z^% z!R?Lu?eB3R&DEqSi%dLJrH)-ajWl$!16H4B;9Yqv{eb`pDa*jD`?5v^_LE?mP6MEK5FUv; z)qc!wfnN*Pb#1Yv%{JSnKN1~@3w%YEYL;PvUl*DCShOMCNq7X-(PPcnq|rW{;NFTEG&r>Kt{l6>E zvGf-LB$0#mv$7Ri;I{EDD?I`8XEHtvh`pY>I1Xwa_M|3e@pxCR$} zXq*!Gzv1P5OJh#|C5#fOwc&eEW?bO^g;(9w)q2N}hDP`wAr;bCS^2J{eu1UCs_7~x z6r7n-Gv5!S$!NVJv)vqW2D?AZib7BLDXl%-ubCfEbL|zXWO@a@6FjPbwyC|>Mk^de z_iyG0)>rAbEcD7zfjrh&9mGe4xH zI`i12OBXK@$S#obS4|N#JB_9n*|Mg8)Hg<;SiR=u;xKYktcmJ+hgf8eB`NY$Or*)8J*I8b`XR2TR{|COxW| zpN`yHBl=Y*ys$lCp`o=LXZzBloB0`?ckr&dQQ&*Qt>&@#SpK+cGd~kjwG^{5$y=YR zN09Cv`B*tvWArkS4=`K+Crp*A7UhQzQw%L;?XHuG~z)-)>ZfbMSAIr69=-3Mts zEL!!e7h@C60^S!~`RKJznnNT# zp_yNR#QLk-VA{531pdPM3SakY22I+nnO}sYv@+X?&&$~KRgk?HnU$%Y{k1tgv6){I z`Mb3_rIRj!zcjd(Z=dy$4Qcmgep$)kj1?B9guEPLwW8|Zw~>}pyV8@I`4x3O;V2sx z_$%Wo&A;Qo8D;}}H1n(CDxH3ZMufi_zTn-wvij4LoB1`!ti|abzD;a4gS|GG8-wf+ zY3A2O-qzAh4-E!PP$Tel#fX{epYH;~aBlCQobTH^Q|%XiBwC z(7v%%knSH>scz9V)10cBp5DxF3hsB;F<@NaZ-!TIT!I70*b36jZ$TD=9F3NeEXxAD z7j+A1-b$Jn-v6&OcGXyVMl76K zvVQ)8`o>9lOyuC@rGxgm^x|edHn=vuG0F?YCh+5e56_L#d534am{z}}nU4>yDea@D ztQ~}(0JpbR3ljyKUfRryVODWUi=jft?1k*6+SMb&6>>zeuF!K>3VmMs$aCxW|CrJuUkoL=9|pM={RXv?SE1@@^( z8){Jd(i@uj)9})-RmZ5V(Pv`YNi$1aqkW#XtFp9TGk*qNy+OngdIZT?NMdlRPvYRZ z&FPKJyejgm_1dVw&kpXUmF{4gN&7eRXW`bCwLGkD?eA(EkdWq_xK{gy8wR84P0jo{ zxRrtXTxJCJc~}e}XdKl_z9e~FdUG>>A#!5)qtvvHdjx)N&28AE-r0}R%wL3;QtT52W18Ux{nHKj>YC1%7_# zU98UZ{^@Pad;ya3o-rEu$5GY@(yvB-{?ulYrMEZp*Mhrd_fZ0VVa+wIEz3;@H1pTt zrR8WJRo9$e(=Es@3Yqs4EjL|A(U;!Q%-=v(J)OIB-O<%8NH31NQ9G{x*=uxQGk+6a z#)UBSeDE)eB!x7WkfyYIU8B~Y-r3CGiu|+<=~{2Tiz)C+;cBGY2G}J_(?QMrZIBHs zxJ*u2B9P01FfgJV-_^|DiR`?hbe+wlz*pB?gZ}Eg7*7W`a~HfrafIJ$P>^*at9-G3 zc=h=-ih5=@mfqdWJqvQS{b!p6-U~0ykJ)0G@ph*}nt4s!(|x0{p_GqWG;?3%Ru2yw z(tDb@KRAt^%F+tsqZZ9P5Zsr+>o7f$4sGT^c$wpD-mz+#fQCT6N^EZCsPx`u9tM=^ z&~r+s1vV1-X+`*HRwL*E>Y+ovPx1I;|%c~@T>KPK>v!7X~B zOFUTTet0uaz>C4=9eAriCnGgc2UlvS;}16Trr`avlXxri3DygID!9Il&yxq!hnjgB zZfzD$m>9AdQc8WDsPkm6^VV7#>**{WLRll- zhIC=K^c-Bh5*YhPGjAu2J);iM8wGMXq#8g}src9Gj%?=dBC+~b53aXEKjRkJEHZry zWro;fT=a-x9cGVd=I@iTJRQDc+fp(i@T=kG zJJR{bf{kld_rA`q-`hbtwwZrG`l<|6<*GW?o-ry&uR&UBBfR*oB;9j7n2u}aACksP z81?EiKJD!zg6u~ncYAJE&E9|3q~n|U$4GagBzc+v;rCDYZS_ice&vdELNosqqHT{= z#%JPtK3-tg!m0_2epz`iEpFzYLBr^F?=}+|_;v8AW$2)06OD9YGyfb(H7~0qq);Qy z7cuDIL(1z(X+1yH1jWD_Uz~Lru@Ev-&K$B_@2*jyVKHU{w30Qy0R>5O5isJ zr@XD~H5#?7nSTY3axZgC_r_~4n?|dU=BCa&TCMn$h$+0mm!nSTqn7w_J&O89+i{9ZdZmOk3d zzl-0hX!w0w{O;nxRy6bP<99c64u0QW|6Y?$Y34t~?-Atuz9W9G<^c4S&HTss-HpSM z-*?9EF5(QQHuImV-?P2K@4Mo6H^J%Cn)%Q1do5NqzwhR^HM$L~=w6>rZ|1*r5bRdS zJvG^mqxxgb{MU-?_zcwn`5UBamb$)fTRNke|6WrDEY#U&}* z1=_5sr|nN4Z{`+Mhs(Lu%dS|p<17KSK|24RTYZdeG+&cG(airS>6FY39xb4Mf=X*v zGpj#+vYGz{)7tm7{D6N0toD62#c4m3-lv-RKk#@<87wI{v?DgYU)<|Hi6zBY8^obF0*etw(sl596v)4qvJ}HCWe$icY>CV zUxIg9`spmf7f4D0=xlR?z#dem_V%tm)q%8%z(p;=G}GMqGbu=RMq({zc&;By^lZWx zk+ZA&O#<5`m|N~s>9YhcU`6Tr%r{)p6N2<%NVPKTT=R4e5ez_8=vZGw3ZakaplToP zkn}ks7bWXj+oQ{DED)rRLTc5j#i`yr{p!KziCVy|NQ(X!*sj6K>gn_aVis||JCM|I zGbQlHM%pr^Naqrj2@u&2R_t*(~V|8-i}`9vk|dq4H)((nc8o{_JY z`nGfd(Fs_wAc}QGmrxsT!TJ^<VD>Z*x!5pfEb75(ts1m>)*0~7eZB`uY#2OW&1ZxEt@`QtCO$KNWz7Xr1@VZt$v zTufLZa_snyi@;x8UF~XiG<}n(1h8r=x>XkTQkb{qm0nD1(D$C6B5j$y3GB6Ka#3X`l@kVjID8s zF5(n*-Z9&7En)6sOc>I9%E7KqDnM2+;cw898~#>!^%(jH`q`7A)I&G| zi9LoEr5nj^0Cow|w?%&SQnu}>m!L#&t$g=dbP42uQ%RiTV+yfCJ-V z*V;Po+?e`^M8I{;(%kALi&m&#(?VYe4vJiT!mugz6Lg47v;q0KdA$NZ7;cr)!A)U% z!|F=|gd9ktPef1~8w79&pv-%8n53RGc8+^%kU#@6eI>f$$lL%fVA!FBkw!xglWBAs!UKVSs2-#V1$xqBSaY@v;Mg) zJ{Zz*;fKSuCV5a-{i><#sG_u%SOe0c4hOJsAs>QNou8Cx9TA0+hjs8iy(cfIot@nu zL>G`+G3hJ1KT&<9(`h|X24wmwyvfKi0UTMf;&Do==U?>+4WtbO8<18rM$;i>S479_ z&h`i?k0NDhy80m2+p!r&2|$!P*kgLr^@T4R1nDuIQtvx9*T`q~W=Z~hK4%_G z69gYR(wI+&*^|AezhS?SW+`bFj+tcuDmp^b6WW<1C_zfA{Gr(mb3FoC4$R&8?(*UaT{G9W}X@RswX_klr$Zd(0MmGuY9AK%eva)Bk4{z@k1QC$@f3~#pN)!tz zKTk@ljEjjA`;=rf%@I_97xgp6RyWAGHJRSAD(xVU0I?z^e4{!;U|)ji%PcXc)s;jJ z0OcWlW@`4BAUW^e5_O!dPv0YQfTXGgH(A}RG-bnsljeNVl-4^mJIYZ9R}nubj9M{w zm%zRX(+9EzQR(}H3jk#R4eeC)nIOFosg;MSQtiR&2fLb}K?nDqjSU6A2<~M-U)CY| z2LuXWUd_iZrnWdaS)dn34rW)|m@<&AAwU2R&1#m~6q-lxzCgzaDKCi}Jk+Hgrs?!U zLIv1w2<>yIo?KOuww@HTr2gUpr{#|p5!q?%j((NoVzKP61inQ6x=OqQr2?L}(U zu?7vL%iP(0o~|WS058R^Zl`I1^;Jw)B2g7TBRl}J!et1LJ(!-0RX}_+kCX$|)#}J% zxWA5I0jxt)>6(H`fe*pU$Za!l+v~{Gn4$9Lgb$EvVJ>!VXcIA-g&V57g3dviq<+m~JFUfKqLgmK=^s~@K!(7s4rV4a z%h7(1Qyyef6iY0yP(w}hB!?gx@8a+9yq6pw7K)EOD+>c$7?#3BkGxMYh?B>GgM|vLEc=`)Y zcvw70xrw(YpGj^M(%eFtYFP3IS&+sCk4@Pk+T{ z53!cY6Ps>?-3F^_O)Y?p>2G-Np{3SX?WFw%NxvYu9f>`=_7rte#i|PHHJo|=cYOP# z(ZaHG76otzpsFDKzW6*2ewa7jLv46kBEUOKLNu?g66;M3JpC|xKeIG#bm$WJUGNxN z+znS;owaj-R+5^;0!Ue!`6Oinxf@dHTpy0@Zyv2hWT3vIj&8m(2YyeKt-8DQ6&PUQ|BSS* z1%}dph#f>)t#U15JsA-GZ+JBb#&VLL^k0GqaYa2iP6_0q#^M z_b{OP=KItATls+{`P^#v=gkQ4LBLXXwhu5ppp_pCv(j@lrE}J;0^d2f)qt56Lusd0 zen`m!HD$Feuw7s=RFcx_-@5ipdSEL*6lo}dg;LT?7r)sWA?3qJxsSeMm4m0ZczTu6 zbGB>Or3bb0!^;!ttMl~R1onuU=`4LLJ-C%03A1 z{AkjYHwmlX{nce4^^`)&T}f%B8qryOhKIEBW8kF*%rFqxV_{WG(xA;m+NG5r*Gbif zxK*H!k9@V|ngeXEFFmxCpAg*rSh@xGGXmcYuJ@z1hFMcFlpfZ~PlQEn`TU@iGM~+8 z<=rDE-9u4&VS0EgKM7u*(q|4+0^I{zso1Kgrbo2$laW+I*Y=|Y^prXa4{dBsk8I_q z)>#beN3(g*5$3~4o`z(v(j3eqHH9aFrs2ygJaA5kTpQ6)dQ>Yvo%FRLFsJK;!1siE zq4T1=QhIbNKO>kgXc!RKUNF~p`mLH7%=cYe`I&X5x@}CogaZQK8(zx8%p)}3V_NxH zRccl7x=(_6FZ|iTBfO^u;bU9*Il)Vr(pIMgz7PC9nou>Kny7v0ajpDZQbaA5KI8*$ zk05p7w$C_*Q;C(yA`Itj|FAg__agI@dRGY9Rdyt^5LHR~b1<8veH$M$ZTlYkIVk^G{UY@I{Gl9M|QtM!CN0*@Y zcW>pF!7C$6)4OMRgCKi(T;mg`f=9C%5uzK;>06@Wkq6JylMSycS6rwKvg3p3=&%tJBhycy$)rFylb- zdL$h|zCLT~<=EKt)K-22@=`pphz7b}XMXBFpz~ufJgt@Ah{Os=D@SKMtexcF2|>1h zotHK$)^Mk%xAL2y`f7`g@vnY?-VCyu*Oufb{0*i(Tlp=)tMjVx-N4@(yhLZY;imMA zR?cvJ7>)QdkvC7j?k*E#Z$s8O>S>YS?cJ-D-(GS{fm^JStH~cg}K!9s&)6v;;P6v!^fW#UOo7E5C;{ zYLKe6utfle#x2yZ;q$%mv`;I)7jF8_T=3ig_CA=kLp?BmC_T58-yc_-M?zgTtS*2b z7F>@<^1171dR{Ak0KN~mw^q5plV-&CDfqzY?&==ls>8Xe8X$CkfSYa4Z{-gn@q#$I zgd7F>A*emOx5~k^Z!3QoW=&8vy*spq1b#$t9oo8C9@K{i?**;=k>KU<%h^FXF8oM% z>9~AS?bP(bR$c@uLrhGKOT1oR%Hq&>u%!^`MXh`^yix%AL7|bkEp%!m z$J7#!4A^?L^x{@N7Ky&<>2}1+l2ZhB9Be`B=uR(b<>R4N0IubHp)vdfxDQy%k3Rv! za4@~Jl@~{1A7fRyZWj27aDDrgC2;t%R$fwFe@yvOFK{Wav>sgsIG$eK%FAHYV_{(L z5P>d-7S&MBKSRU4qLojAYg^MLhM3oolOfe$<-P~oPfVcVm96~I$R`fuVn7x63V6qp zY)`LhStRgNY9L`JRWb0+0yG;`QyRe>d=LI z69WGP+3H{z0{c{4T@9P)`8Txkr>m=H$C(*IBvR_hpMGlG=Cofc zeH4lOy}6aY5Zs%v+Qgd#es1vEt=XI2(#l_iNAoHk zZ;#1O3eqptSLvKgXLsZ2t*!iJxEK0t*N(FUa$cnL*U`||`jlJwE5ThU+5TdIpARq1 zsjLAa@9pVrt$YEJYIVDY5p)3VJR_K|XSDKH>wMi!s59EPxAND5tFhbX>Q&$u!fime zgqZtO%t-?8Zsndjt-44i1lAjA-NIG7cqkpx%4^`Iq=)A?L!051W1a*_ zACjs>yrd!m{GL|s4=FtY>p=U3uN>$Xqyup`R{;8C1L@FK9<1+HpXV_nNQRJ9c28`F zi&F*0(tBHZm=s!<)O^RarN#PsZ#)A+%8|IcI(qG+vU5G@eXYC}zHkhkb2Fe!&8#)} zdYyhD{kq6UTelx8u`#{BmDj^#kTD~+Tc8^vwYB*j=FU%twel#u^xh2&aFDS`=_*|7 zVl;iAmB)jdM@4-^m_+c66=yY(!_n3QHdm_FRfGqrTu z3)`-x>j}~=NQ3_ zsp`Y~Mu+aiEIO{0e@L22Q~0@GrGy0OkM1iCSIF_L{Nv92-7nxv8+BI(Cv^#FeiAuU zz9d`crmJjEXyu<*JOEo2W*u;R!gs zmHz^m|I0^jo4m~#zo2|DNCbMJ6_$F?8#{57Q8ZD zb^E0ns9OX{8;P}!k=aoi{U=)aACZSPdf%osF7ST_uU1bncll&1{|jEdeW!Zv7Nq}1 zs^cPES>1(k+>W{L(x+PaKgf&mr*hqUt^4~Y1=)Y=JKC&-H)8ijEB`O9@raww?AG$9 zSCFN@RLW_DZ?tYsLg)o%r7}3n$CJvS1iwGLluA86+?+l`_@(4R7t|=?gur%+T-^EMhNk9XPJwqci46?h@#OB6UUi`uHjWFu}FCdEe_7_|EV$&|tDKM23lSHbI!U zM!T4viJ*&<;k&@SXX6X$O`j$B0x5%-x;HU@1^O`P19-xvOO8$F5J8FT)>N8wy}%z4 z+zt@XV#2Eb9FY`w(f7JgeS^RrRWbWG#gg=S;w7*$3-ZeLBL~!r;WM}~A=R#=vKQ4! zu}`ACF?@k|2{L`5ll3UKUV%IoaxZJMZ11+Fzrf~9=MqOD{XSY5I-=OVBE1N)Q$W&9Re%h)P^*GYT}J9vN{S@f3LJRPi3}gc}s3PlsVD*X{4_bM}ddZb1iHtu{iXwFi5jEX{sksWx6eWjhG75-bBxj(e3}RXV)p!U#s)x z3yG#cwTu`Ie5TGEz)EnvAl;|Frl_9ub>b*c)#^(Z*%l@NJr88P2p`kZW70(gOdzEY zY|>>@2>8D6&~z4wDjO3B*?xndNp%%3?8~5s1pY#JrF-?1X&t;brHcuf#1%RSdT4P} z;4kjDPjG9j8`C!ln;?zRV4>6-wEm5^hm(o|*O6F)bi#sujrBj=bo={~qi39ba!Zt2^ZdIbJzxVtnD^);&L z+k{tuS|J3p7cE&Lkk>*=>sDK!CtXHhrKBp~goV5wV$~MfM&EUd#MWHp|8; zF&(!-NV8wu!IzE!1jk(W6>AniyZ_}Aoqz6sLx2}19otVkm}8( zDviKHKr|6_LN}3>au=@9IqYVEy%iQc!vmYChnNb~-cJkBik@eJzYSjcTE%Gu#WTa~ zqL;`DY3#YzayZO7fgAuS1G5ge+pS@`$9Y{^Lu>_k(WKEhJHh~N;1o;0XjS2=1G%bn z9a~UIN0>={#9M;vbCuwMzz>4kbLldzm8qY23#62ku4LbaZ+$yaQX~gQ9valxM4gPY zvSNT3OYnN6nGyIQa4$uRp`3Q?@-#?X1?qMkF7ypc1#~D#n->*ri|5l2QI+aqDn)Go zzV$&|1?ruJLFcB7H_ihNNBV8b^4MDx!q&kdLRzSMZz^i;HjSz2vR|?-N zSO2CG1?l0nG$su`rRqs*iLD^D?h!s|*oR=DfXfir*;}`ybwpY^bM<{~p6i4lJ)%e{ z6?da*_`~*ur1eByka{QOEhYtWWM^*0DQLQAG;JXCf;6;NG0Xjqu08rJC7VGAx2B5MSg%Z+33bv(H3a>RJc04g|>xBvoTm^5-Nk83A3gbOLO&KT`{qh zP)|v3Wv#&^*e776yz~4tapazZ~yt1)4L)H+(1kmfAXl;?9#gN|B5>AQr4%02o1jV?g5bAtqaHeBm) z$w}DfeQB1E5X8DQrOTUW8Ea^|7agzv_hpT1g_P%%JdNAukhs?s1d8BQ{S>ZgSkZ*^ z^Kq4a*rUuC(i|}(co`vmlpPc3xslq&*wRaO5HSi~jfy)~3H(cN>+Cie+p#KLNt_5~ z?R02%Bdd8J=RvIAz58m6!q0H|919*t`^1Rinn6lcJyH1W1b$&~D>37v>1yIb@KU$_v^vIb6eJfR zv2ovHSd{`rK9znz)Tq8v1M2!wnk_gfkX&5fD^4-)PuCDRf?Hej@mFVc)e&m^f18lz z64ET3$MKHZ`rW3m;ex?Zwb)GhA(14~+xkcB0vx-{cY&7zO#x^%-ltJ7FiDD1OFtsK z#8qD0=IBT`bL2d6~1hd9lYVoVSY{k30@jj zcxwnG36c>c@w^t6Ee0rFlIsZ@A+`6@r4myDSqCXkqu!m(=@$frV5LsZ$5X?&EYJ;c z?ONj4z3B$RK@fXtx2&v21U?oiS(mlrtn^F5K@feaxz*H~u13*dpneRsUyyFB^HIm2 z2a#?hDAakCFJ%sY3ew3UwFc~#PC5K0{fa0NQhQT6Jna@T6?dsZQgdVJCSpRtwIg_Y z?h*KAcqs*)&|)d3UlRq2)b2U*L;vAh;MV6avLejv|!<9DCykkH-v_eM=jGsc=FP1w+Pb9krvga9xUDBH&Y zWZR#9PZ$Vh?O=FroD~(2Yamst_14yvZYT6puI3$d!njFbKY~^5Hd>(XIQatspCYCF z%ajjmRsTOMNPiOdsTS)o)ZRgmC%E6o!r}tIHuxHJi5pfu>5l|@f_tygUN$K3>)`&j zOv3u%}{U4Iuo$b zU?Ba45DnZ~m$qQv{;K~D2(nuucOTZr(>;V}DrPRVDS_QuF}0k=m&H+yV^OMfRo6I_Q?>#MYH_#JR-nQP}p z=mPVEW+0&-7EbE5hnKMZgpl&i&Xn$obse(7QkK|7Y7nd;rRgP~ZF%o4Gc8_aLP&EL zY3vnEQ<>K4O-+J0aI0N4%XRUA9~aJfw}SNUxXQkCtWu69YZ1zct2(&pz^#Jx9;6*w zLG_c4b~C9>WCxjQ1>1Vtb%ucc2D0G^kE}Mj^bbNgEwjd_jaD0B`Zoa_ zWX0Bsqo{3?Z8MExI2ENmD5U=<>FsGoSXj9!{fCea#EL_We?Air`ZuUFM%`jzld|+* z;y1xHDxr&4)}Vvn{|&C~$6Lij`X8|yc+qQSFsmLlAIgj%P4`rH(V4j&cb8H--w$5u zPU}n;E2!?>F39eWtkMLX8=$wO`?d1}kXDB9dK*1-rjKN&xR<-_StP(z?*8rkz~IBP zYSE3*M|uVRAoxDoMyfH-^v-m7yJB&g7VgtD#0($M&JT{<{E6+!1->)9Jast5HFidB zX{UC6NRciWFV&CKCrEdRYqhlP401b(oZ~gq1KatbNK3=DZ_x_uVKA#bH_@jkhwk*C zc7Awp?L$5}9u)W^g5#+s?ON($b9!()KN7A@<@7VmCWkxV1y4{7JeAhoCDtA5ttxmw_lg_n-tA8+x--j{Z1=f}l0K50_V z`;5RJ5BD+3?AImfq3!$x*u5sjrWO6Df3`S~X1B;sb&h_>SuM_oweu5$`^G7?L;3~2 zdvM=Lr>$~ZdU!iO>Av?W^{Z`zXC%!YajnNiUBN%1ou3RZc8~hFjF*2m3G$~P-$Pqs z$8{m+Utb*X$aa2eo8haeZeT zgc-%7+xZ!BS8bjCnYm$s?*%Wd!W}58u=>)j?fgt6-n&szK5}~RMz%Myj`lU09@Eax ziaXRJ3m+qC=V!w`nt%<);Q=etW83*Tk+{C;fWY^GR~^uXFrPqTygja+pNq5%h%wdl zH90vmM62l$lkPdol(-YeH1#o*wk9qY7 z?1eCG1gLdVyBe1Bp)zXYl4dNyeFAwk#JrviJ7=UPxASY_(mFaiD)86B7uHU3DZ43R zYgA~APig1Zk+PU}K5T3h=$ko_U9c9fuypWe=If|cg2Ca|dp{@o8Nb z)}?3ydMl{XsyY_v+2@d-tGKOWF5*&Z5}ni_0Kjzeo%ES z>b05>Q~u9t=XW8q{$Zxs4t2^*3jAQW^;I3Fd>^E5fay!mZs&I+E&Z&A2{+`B$R}14 zbN}?5c79Lr0oF)|7Y%+W+@9GRx>{7Wc!GK!O#8I+dy#tq>pCMndP1P@gH~NZ-(R&pkO{W*N^U)8S!Z0iZ==Ks(~fQ&*&yw)5h`RfT)ErE$YgjLhBG*9!5`_+{<91X)#)=Itp)c#j}m zTIblynCf=N%iDPw+#2`rTptP>vOH4imR$|)Xf?i~oljcGHM%$`@RQ-CnVwIvx;?Qe zy|SG@io}WsHAgPv0$UNe)XT%Sq*t}`Dey|is1>_epev!pqM9lySf?6Tu~u1w>DBFg zYNXLd9jl&V`lfHSK&l(o)4{D`I=81Ad(#`xvr#E}KVeO|Na| zGoYnO`}7C}FYq&itM>GPb1=QGoj+c4ZKfLU9ToT|;Hri>u22IZ>GkdW$w*omRdb^P z{}jAbZ!xx5zd{;fT5o9QPa}Kzd_4uL`bJ;0M%f68PEhs_7MO)ij*;Z|Bd(RW>$hA!6pi&k644wiXzl8)@gy z!7IJTZXMIpd~~FpKaZs7e$_kreFxozpvH1fdUHE}A#$u7Q#3mGxp1pskEr>=IMo(! zY3DB@D;4aMiC%$zDRR;h(8|=g?_1mX%Qe@Jc4}o#2>iU@YIBWTF*rAf(>%BHSK#Gc zd=UGQ>`ef1b$KQI`TD^-qFtADEZE$rmf+e8wOh>ke$^ zZ$ed<`MO}hB>c<<3gd9mT68lclV+xc6h)Ahs12ZZ03^1B+8sGxLEJAWHy53QZR zjjkzyUk0xlnj6)2awrY?UG4lGq|ph=79#hXdysiZNVA$W;k@|2(pZ=B-Gn{q;CAjJ zeHps7vKh9~s$TKy1$j4ed-@A7QPc>2cRTmM?CE{Ko(^pN0`Cp3jl>U69!rO`^BQ<* zo~m)x)K;z1E6DngMQ4DPK_$JXo%@kgvrX@GJ_EG3C1ygJ0n$`qvHv5Dy{&r|X40YU zJV^S|SXcvUqr`TB55e^<`51vsebRf|c{tLBt!Ep1+Ia--4Ve9dTX2f8-fqaZnHP&VGG@1?K~P>M?Nik zT}%!igO~EvwK?6kVXZrTpqyHS+(dukZwe3?cxHKKDyV#*L)CjONY1f1oASb zOclARtQkQzi7Z+->QI&VX!>9~Z-QIN>06EqWGYhDb6q}F($3S7yB!K)s@#lZLADv0 zwMd^QZBHL==NVXs;`ILLewPVBzNN}fO)w7`tC~(nwDVSE`c!oP5!xhVTe*W12B43$ z^LAKOS__tF2-3@udXKO%RC`2MI6mu@K3rAdsT!IQz|{b&e4mY#wJa3pvF-c=WL0O-E?G4zYuqzJnrljiIwcxT z$F=hh0i|E!g|j>N3;ajHwZ&Mk*|91e-_Ab{ZW9gDSnCD;6L|e#wxibCO*)~Se~K(L zjZU{L0<}$$TpPK$32y6~(&Bdh8N6t2jd%_U?7Et5fQ_aT+xh3PGQ|4o`;7v<9$IGO z8xBlM+W8lN@^IQfbWY%I8e}&h^9F>=$1DPti!N>FUk29#Fc;KZkHBvXuD*>Kmfh(D zby++AD!3bqs%HBIep7I*k3Or3$+Wzke+^$yTT@sYnx+`oLYkXNQ>iXfvJ2B_ZsEpC zC$;l$NWYH`fXe@W()*JLSKY!@<}dDUuc z*$kuWN89;#!K}CU_jt^)Lh3_uwj z8WxTwxQtb37d#dIo+Y!1&|wDraq#p+x@}|?rgYi1OJw0w;U6%j^?qNQZs{{bxF=dm z(^X}d9a;2L_-Dp_Vr7|`2>v8^Za_=3r3ShL!hVe0t`_p{aCACS*H6&m14jV-o``nuz& zQ3d#BzRpdxPk1kSD*PLKM}3n^$A==npU!exPhMNA<+D$P|A3qM?-^T8s0&2?o;t<= zYmaQNA7(a^1_DpdUd0YJM3^1&6>9W*ttD2=#iW10TMTMC8V^$lwe0FOUd;BSo7u_fo4y9`qND%FOSIVgiINSee&lM z!F6&Od7peMUm2uUqdS5>58VAbb?@fRlh2Xo$+9g$xCp*8xHVS`?tUrCc{w>Bcr{cr zC;7TQpk08hmOO0XpSdJlE1xIj1D9S(4NBqEi1BzUBQm=pV}`8KwQl(WiJ*L~YIjTe zBkOxaX18=LJzI}xnlfWX`*ist$sq8Smdg>S{s^}_oChUm+G#42W%fc4<5=kK>eB`p|7NZx_9`HR2ZrY$rJ_hAV5<%ehTpD`uML}wBh9cZv za790LskGMECiybyAehqg)e)Fry2scHL^=qW?Nr03R(*06NukyfTyYX>wqr0Nvo|v7 zU5GThM$1=71htlI+b_~i@J$hRA6V;uOnbIPxtbIZNU;$)hp;8W>44wSMwd z5y~Rt{eYLo*HPC$WR@ae5s3ryl^)c$xQ~3D^iOrAtF(@N zwl;@<`y&zuAz@FXb43p&yP@ip>qz}nSKN#GVTC2!{kGN0_G~XZz1gGZ2 zHq=FcLvkVR1|WzAUQgzy;MrNnYJwk{akt<4G9&U$az5Z$_k71O9+%oOH#}VtnZuBA z7o5>=P;MXr1d?8`o2%4jTdJA#KJ4N7UhXn@5b|3jfimt(>$TF?MDQaro)+I}g~*L0 zf%09nG5t$|o?%-aVUNsLeZw>g%Sj_)!^8x{rLH+(Z@#ywreC zUi~h~C6CA)jf^*qokpQkdG&7B%6G^MMXrZM;?OSfG- zHYAJ562X|u<)MS22zD%(^_85VP?cRmt|;TwcUt(eK7t>YarY>6Y+fy$x(eQ!=x6yglT>kX`)<4$-1C7;3s5U@2T6qx~a8pl11R28MOT~HhBU*5!h!7ev%hX zLJxVOT!<$M)LgHM;3pMaqa$XLR!c8wqKs?fnMuOY13wu&85ngoG<;~OBk3bOl&|r< z8P-G*{FDmMgZEbHCoz<9Uz28A$0GQt;2zaI$v%xSKxQb5rW}X%wFrJ1xYeSb5V>9k z$pwKVQ~_R?QHmEbb=_h3ZwjC3!?Mo+ft`4c+z z>z5(2Mb*7h-?1K@MixACWIl#Wa`#uE87pNOIU}%C#XcgsyRs$1oe5{}yA023g)ApK z1Y(+sUeHk51C~Vav%s@`$hhhbSFIpF1Z(xsa+S08_u7ce*|}slv8uU)GE9C5+@8L@;PW!BCd*@tt7Rh@rwZ3V z`v9l7bw=>>GoDhlR{Nvmm%vM#wI18m9bqqkP5b&<7yV(dOD%396NuHZc0KY|^y69>W)%=-XHX6v^cg$%v#qcNK-u>C;BJnUqwzhqmvw zi(6YT!d?Pv+M+G%ftX9=yQHUD?>(&gr%%Pd9+^!urHJHZxdi{(sJcFVGDfNj+%5O4 z8I$Kvk3g4aQMVQrF_K%zQh}!i$v0un7-7Buqn%`-C2QIy$vBxQFl&fQ8Pl(fAXk8x z{Xn^xuc-f{%Nx6~AKS=E!6y5b8^v=(Y1?!}=E__`sRp{VR#=o<$yC9XQNZW(iB%cz zG}t60uR=0e;4YS<)99SI^gVJ{8UKbklX`sPXav6++@4&^ac{>L=dP36$X~&x`)FgAwkga*ck0 z&z4Q}%a6%^6+Fw6LjYe~%BpbY1Q*MlWVbS>;m|5)y*k2m!kJz7`Gwl-F5XN#K)3va zELXXoK8J;Cw?y#njJu83`N?Xzi!2wo_pRC3p4Abk7bvx#`v~eUjL1((Zo#;5FfX~< z4GPx}H&L^F){!P|Hg_cqemChXB)xix@_5u`a|9m*w_(gvBqQ=O(pg!SXq7$%f7V9u zA#l|?{a91~T=_ZaERbXXy*fzP(Svo+fL)%;(dd_(zE1fC39F2&_WIDYB7zTtXHCtx z>AatWG$8koyh0|KN;Q#Xhi-&hRb8J`B0m35!=L<;R91DpIxhSX5sbL z%$qVp?j?5xWYy*~SsSq;_&V^kE>x{+9?7(-@?Pmq`4xGre7$RqPTqPW_y~9!>8kLW zMzA#8r(wcwxsTiyQe{@{tF*l;mm{@4BC!#PqBeTqxaNmC<=5o7@}2Dk?L|i;_$F`- z=x8IZ)}_UAKZz~CG&n9}GYQC+e7V|TwS+y)RewWr3q0BCy#LfUKlMl0n=@P4E03Hk zkq1a|!McGk9jP|!!;R(pl}QSg_qU|Ez_U)I7_GHtvf7;ynQ>&iJH4NmS|YzA&jpk` zMjeuHT_fnNt%dcPYWd@tv18o(JsB@#ti`omJV&!Kg5Q>I;`#lHp3lqg$P=ek8DEZuQj=X3UH9q;K(C}8i+C97V03Vf;j zm7G|{?W1+9D`g#U1iug5`iFl$_))T9ASv{#u?vl2>x@zVe`|!lA71S$_qXL_@;9VU13COIg$^n`xGqYhUaBTOA84MFKmxkhtW zb}j!7$-l`+A?2FCEfTE9-MMq2>6Pd-xj%PN51tD9@>d7lNxxug?3t2(T+a z889_#Gb}sR!izwQ+ioa!M2}r@Eka^9B+{yA&-Q2^D-!&_Pj=NQd2TJd7-`p$$u?pF z?GBWxEuD4GjNy5;@DlLcaF);-!7ozduq49nQL!lqN1ed3`tA9(@X}mn<@;=j;Cp6V z4Wo}(qq1`?{2#d0tQ+w)5o|9o>#q8;`IXc!dqFL{3{KUoqy79TbLK{nmxE|KFvL&M z@tse;xo*s3gW)c<@CtZ+8-|12*;05p!tM=Q1~eZ4Y#N!8%)|1+T6iTgsVTgR>Y__E zB(_!{BC!t=RS;g;#@UH8{d%M6mt9 zlGR#kH?v;PoMN|HcnzHE%tHT~W=90wAG9>6>bv%X7uUjT!E=MAQO;+;gAw+Ce4i@x zr(@|_*}WECm+nKoZtAdTO$0p<)GDo7?x9*)&cl$G)WYkLv1d`$urqtuxdVPs3!d`K zBeF*=ya8Ohg`Pv&9RUso@IGhX?C6r0*1{XX%*gcc<=_nw=Euzxa~B;jcLF9UoE^jv8L0WMofNNggp#a)BWu;C%4O9weXhoo7Z0&`F%LQ zC&mg>?=anBfYyHGvBEBSSuMP^^=@8Gez%?odjzca4)hJbQ(j&RZv)ec9rusUESl0W zV@d=+5m+KeIwF$D> z3W%d2vd?L`3T^Q9^2%CxCye^tYR@_*PnzBy0gnN+*4K{Wqr`yhQw#3`w+6&^PnjM; zjsn>9i`Mk06h*=C*1Vo%2CSmHjS;>L|68$h4&ztT?4H*waI*H z4CZ(kt0V2lo_*EF8Gr7)xvvonQpCo{gb+U za3{i9HKfs&YX{{uweUW08#{c>lFmG}K2=k@Bm7DEIzRSZcet*V{cGX<;M-}gniifY z!k!G9287De8O!zRp6I$>UrzMeTKGV958diz3*RI7Dd6^Od_O7U{HqSf5;>q2J_w)8 zQfnP9k8r2LnPKqz=cNOAk$S(pt`fems{EqoL-+yB-{ZtArI5t)x6 zqffO+4{Y5mZ>WWjS9eiu;rnjmYq44|XTl`K&u_Lt4z7hyWW0N9V>*3eO$0v+yx0rx z|2_)&_P*8$cbB}e7Cwo*)xJ%9%;_~_9pTP~Yk7B{L9dfTYGG2od+v_tVFW)1yy#PL zyJ_hjc~dR4<*TaHJe!efVRFW=$CCMoI3S1C!W8gyf4Z^`ZF8n{v_+V6VXR$sNLnXv zu7#-}En1}7rBTa)2sbTr%(7|Q6et?&mBVVGy>R;OOny?^N4WFgCe%I8CU2>Q>EP)t z-Sf~z9opa4N7xyORjWvOI)eD;DF)>5T9^r|`lsKV#K0|zU>#t^zUZV(x5N#~TWet! zj6H!mqPnk|y99|554mC zT37&{`pae1mM$s=y#Q3}(#A1gi09)~ryNxa3t@}Xs@c7=F~%$#5{r8MD{{tt>$zgYPTF+3!ec=wl=>ZB*mv02|#Yqh+)7Cv8y5b0>qxw=jxsyqtfL)weY3Pxx$TTWATUmNwsig zzJnzW%m{bO@wM>ff}4TT2+f8FeieA?h7P&wUj_t))O@{zmPdZ0FR11BexoUh`MIcfudU=HH&v$k& zMaKypsW-`KwJ-qZvFgcoBJ{EdIG8VRM=hthdga5luoTW-*#i@}JA`?_hrmmp(Sed% zY`a8GuZ3kW$!g@yyOy=(I@sl~DT!h+Oj=tH?bcSe>=$jeQa(}(EAoBKalk3UVT<6y z74B{WxhFZJ7FL39SEXK!z7oxJk1Pk0t8xiC;QBVSb@I_#SPia*bcTJSd`<*f1C;9- zRVp(m{Lzoq!rFAf_+tO6IncUvf%UQp2_pG;Ev$!4y-6n$*{PoPR^=@&AFr@ z4piumAX`AnTYDvXuB1~wSqocRSsk}F_}r4pg}oWJ3@>^=9emcv*|qRpnBqqyQ*OL2 za)uv+x93k|E!ER4lWO6X>V6v-0JII;r^7mGnZqp8YT+kHtI?ZbLCl$x zBG_Fm5#uVbm8brJl&bO%1(HG&HC5v}N`goDUZ5&U=HsY_&BgG{OW zvODHeweb6VJGaPrF`M5G{=rN&m9+?)9!9rL!|Wo*&tO5e?sO(l!ldMa^U+cEG8czAAx+y{~{;N zm^4S`*TSC>C?-l9+Fg5?zrduv#?C17bZt#GCTu=*thcR_74Z|WO@W(Um9oj-$ zvalBZ0d6BhHx0QVf;<6Y73h%{mDDImo{{y*qFVSTGTssG)JPpG_(PN(?nyY)xH9*4 zP8&%+T?_w$_ia5Buk}W>j>!h8T6hXMtxOvVRT=WEu}dzjg&J(K_UZ=cENf!~uV-BQ znYox4uFup$1H8p_SVEFJu8VL@xb231pC6_*j;1)Ba#1b(8_8txvs3y%Bu#!vME>dg zG(J61hq6mPTMPfG@I1NN9Kq!usWnu~J0z0H0?8_c!NpAbGJh5T!R`Q?jF+VV^^N6X zQd;>cR6Z-dJr!R{BE6Nb>f>XW7BOH_atVp8j912bWdwgVxM_s$|J9X~+a+z~Qj%Ng zjpTOU?)udeVLiN9;+e}yHs~-U5J(>O#SqkK2M4a zNo$bmREVt+d{=N+KU;LBiI_!hlkr zsH#o%d@#c94x3y7?GGiX!T)cOE69$)7sHjEh3*KmM=IAU$UK=exOd5y$c({S`>Vt2 zt2wH5uDZPfnLUvyO_tAwoY-Vnk~2f9G}-@@;#oIGB=n9sHd z@Nxiit88_WTt(sxBpC-?SgYZj&IrCYc^`ui z^0d=hAWN<$SC+5S@ukJx9bXY)_k~TyWjod?dxdq&Rq|CbX-Jll%V)XjHfxtty&a9n z?ALOyR{w|z#Wm#CU{zy$M4KLg_6I7Dt(`Z(?+Gj&vJ$Q+tW)Iim++1jP@P4a5s_T2hujFAX(SeEqq)LhPHxq+No z#&hpfg9d&$czVyY21^Zqe2Xj^OiSovT?9J_BKFUW6He!)tgR>U(-G2IZT@n0P@MK%E7l4*< zM<4mI53+>ZTQ1pKRW-@8QgFw?r6<-_uly;xv2>DmgD;)bjui0OdRlO1YY6CoNFI-* z=gSvPn(i|f=^_OOY>%#$q;WnXoe}(mjQe^gTjM0%q~0>#JGK&~*T8mH1V1t3?!IUh zbx99tH*i%!hF1=Sjvyz2sNy)nilAPSY+$L`(g(uQnv|gkdot{STw&Iv*X&N8{q13J zvp8;3{J>Q@bRWq!u4);%%*~@wH%7Qq(lg*5YAm!{`bn~ZrJ7*n9dD)s1o){LSBvJW z`G#bGq#C$;#mA}<^3N4Uh|?g71@P9ac0_c_AQ`q?WR=X{9KlZqw?}qu(bl#+r7R`O z2KPUvsM=@L>+zjvYPD8Gq|ZRwE1A7?x=M72yc?KRvKnRofUjr8+0aGC4K~?|9^C$A zWZXckLiEM0+KH=xp9!wUnk{aZ&TgM2%Sp8XC1bFRN9c=SXMySMXlGYk9ntiN=k>CJ zq*`@_PA!Kb*x6vo*l;v5Gb8&#hzyfVgE2MN>7jpJtxsDB=U)HzHMzYJ$#amj4&xIN zt&n``*MO`f!3LjNImh&uM)1ktuES_C^6OowwFg4W4u z@@oKUzYUl=qrGif1f2$IH>}!vtE?fbmT~QJ9xhoC!OsJ?TlvPkQCUki4a{a9RT(;c zo8Tu!L9uj8|kO|qV>8WL$V^vsTCa`4e3+-$f! zCa5#0%kv0LkC0n~v3K=AyR8n0;B#_mEjZ7=MmCUTgDYL%yIo$620IVdbd3W+CNFB2 zjU?6bO;nA2vB=5@em;2iLNbn(NL#?jD~yt0L&hrCJyy11kzPv}mBuuIN!KQlYG6g* z(#{*R2)=AM#i1gSi;#4)I@u0Hn}UC^nYw=G4$hg5J#nPcuhevi?k#Ec8_+Z^5@QeViLA+V$@j>jBg>Z#@pUfPH)wZ{{W+F`GBHXpP6g5q%@jc^P<#w`i;Hl&1vo3I9 zBFuFaU-roC(*4J=^SzO9ruxRQGxswDMNLH7HZHppMXA-h6L2i|wkUIk@DiW=k z{ZOc^M#yyMtClg$ZIZjlprxYelp2eRK)pad^*KjVTdXAcDVZ`rQw8^&Eq)up`@tu? zhF0Syxtk1GE0Z%Nt0K%`F3Y-Rk7o@|$O?8*48b**|5FKadq%TNKo+S5>2CJ^ua(l;z z$2ueUD)7{>9#~JwGi%(H@=MZRNTj#Ou7ZaBH$=EKaK$d?td1JVHF7U`uzXJ|+00g7 z1YehNS4hT3R+RjTG#Gg4z-0zUX*LsyNQ|WWnKo2Y=@Fdi`^bjDYD06HI=!1vTLj#g zZ-%YpvCZR=Uy~LCZ)qG2w&<%5Mz~GYZ8nU%b@qt(fZR`F3^pm|cC0=YeG!>0`L3GJ z^A{M9-;g9rC8M6cTtg?=p0j|x8P@I4*oyH^d4S|tE@vrUV`VQW-^uQc;A5#AyQ7}) zlk6G3{clN)wXhz!u;`ekfnmoptCmZ{K2@~jcO=MQ)09dl(^=8=%%ScGe=B@xBwzI7 z%ewSEx61EHhar(hFAFk9u-m}w%~%|R`}`pJFpxYxq@~Rk$!9tSd;5R0-t9-_59G#j zY2@4HEQ}y`fT*{58i!tOk%vft0a*XW0k-s5H)}S*e+1qV&zd-s@EFP;Nrxeo%)fbQ zyqeEB;qHX9*Yp0eTplLn1vc?z(xA2^!rqljvr{Q`m}Qx<+K4}q`hwfeu(rTP zHI{l7_RL9>xr^nvsJ(tf>K>#_ z2Rv}&>0z%bJ`P1v3_cl8U(|&Wi{STWJozB1GxApwV&K;LEA%vv2y!3Dj=a>^%JDvV zlq49x58=0Ia!ahu*JE#U^Pe=pbY3TDs?S_|Ki8JZ*R<@099fgUktl<;XRS_7Tpht5 z0M}|=U?*A4lgCJq0cp$9IfurEal62N2j)?yMJCy|Nd8Vb3^W-JUB#+%0JHEB?m@Vu zdAVZ^%j2ZN!1H+KM=~+V1EJA ze#XJv)8@;QB)essa&SeUxgvvqW_Szbi)2_*M-9Z=Kl zO8;MyT%~@&Dyfq*;|gnURXlS?8F;{-1W)nof%Bz7f(#(_%*uyiAvG>E>{GBwr3|C7 zbgbgbQY6LTwyPZNBOG0!sxZDOB2&-Tdr-vZ0eGA8Z<1u`&ZamX8}h!iKEgI((+iAX zM^w2+&!&8Q*B+s;BdFsM4v2n*NplkRHo-vIeAq z8Tcc(JdsSQZxR?3sfTBP6+4!_dH2C#cYrOU&;*ty8=gb($GiygY!L1KHVrbrLY`R<&jC$J@A)2G=d?D$>;z+KxNLkF zM^L|^z9t==ykk8)7q*xNJJy#i8sN`MS7CU3P*J0zt-nN`RS(b4R~7eCw}92d&KcJo zoyp?Lv+Lmn;Pw{mHO1P3>{3bUCJYU_4a;-t;f3H6>e%NWD1C(8HL<2+z6{3KObyCT z_3$FtV$LS8ra?<0GP@z;*5c%;)8x7J@L~X~0FTM(`s)4&zB{-zmU_tEIW%skRWK;e ztB055o4Mj>icJ>>qz(VrPGt5#CN+vzJE7U}9(jH}ytHCGYNU$_`XkJqFjiH1)W%xb zxgP!xBw66RCaBk5$mbrZ0u)Jhdo*&@UR;%Y0-Z?=$P4P>Wng*w>H`v~CGE6s-PF40 z4$N1n>fzuTsy5fcpV@ z&FQLb*{vR417fPL@8xyo>#_PG?Eaap0+MOhkG!}ZUJF~gv(6vPx>}dj5DF3pAW>SE zPbkr~2H6O^dp*1kCe^*>%7-J^ff>{JUSG#lc}YFI9xN*??`>vI|Mpw}fp26E%GaeS ztn5(_Zvayzp24EKjtFotfW5lT|Ch*1>*0+c77x?nbiR-q*4L(_IDAC%5F|YwHrF=B z&X_b)_N<3D0cR7O*KJ1dL&4Kq>ll?XAo73p@Mf6Qbz2x(xhKLNR0FWa<++)x~>ekJfEHAHzw*gL2 zVLlKU!H-OrGk@t}`u&P}csodL3{#fmvw5dtYKqKJxisG#qaA*u>|GDlx2+%*yQR9GGO8Irx%4a@85;X|Owsj%=CZ&HQq;7@}$ov8dqm0KeR*29P4REcJq z2Ju0o2zWYRnU7_6Qy+efc4hwED6g-Fk052$?Ph6B1Um!Fs#~*0UZEp$P(6GUJUv3e z;a5hukHJl>%Cz4#SLGY(;p52ID_)P!l!jn41)7C|KNH?7X41?_ZR!`v!S(P7PqF(a?YbWO&Gj%9DD^sTD%JIs5oTIdR0~4`uad*+p*^uxzbDd16YIUh&vKh^NMc0(0_3#{IgMOL1{>9_R~%Ij3*oFU zxz?vxpE+Hl5q=T8x)$^1ELu2I-cb*q2GGvMyLXd6zPNpA1icVc>v7fsw(6-1C`Z@B zX8`TJbatkTNtpUa@QV^YzIe{860&$_J$x42^YK%4B+?OSK}Up$5T*leoz?hQuuqPu zhl}$~d?hp87rg<$1UxmOH=a!?^h$YGJzSbgoaoIDM7Yb~Y^0hqYXQNmW9#8_AgWcf z4O!G4!7c|YD?`-pDRcDn|9lXu9zLJ%9B zJ+{A+zvVsk@Fno#i@KF>S&z& zDMYLy(2coBAA5BCv8j%nTo2!_IGevGt}nvf1ebOrc~Hv-bgepV3SV~efqM83a-|pg zKERa`d@;Co*(nP;n2n9jn3sd zhk+vP0n_PoBj_M#8g+6i#Dn-Y_V7^J@;+?)TABg*a6K&LDs3my%ltPt0u2Fa)g;Ia z=;`&a4A{n?WqdZbGlDG7$kOqp_*EaNhZP{!1m46N6W9{Lhrvrf&LN_*I#$l8hm}Ya zAK6!-W5FWKs$8bensgCVuY9x~R)d=srkNP3ps~TS(j+3Y2AS-#q&TmS#D0oPnt;g1 z>R~OCsrDv%pc5q3VpvU%jID`WwT`QNTqapPA|J1Z^&rVB)%VkWS|zOEN8q)kXSYvb zGJ^H*l{4#M1E|(ph0dK9!8hjemyQkMlYgQfMl+%-#QP)2rgW{22Phtq*lkhHs)x;4 zQs>>h5oAl2RA0T{tRLUSs)w!M*(zq-*q#V`Gi>sB%2m!*2e|cyH&8HZ6!i zWBD>>fN2G=A5Yxpb3&O^54RwrMsfr}md+h&@YxOSVqqJ?Te=@pL+8ycP4cBND zeOS(|haZ9`k8nNnPLLmglveboHT}kYo>~t-hRyn&ywSv3nHC2#JcUbetGVjVTxJis zZwotf(y_WXLo%%%egdm?tsc@0j+p_v3&_;pha^kXF{G$Zxl-Ee;ivH0UR=`E5drQ7 zu=iNH?GmDX=hef{5;9M{&i)AUa}awoz4ICtLJSgE(0vvCGQA#tkxO951l9)Ro{TKx z+>L&jQ4hb&C20S3w=s?T5%%5|*6TjS0+z_kdiYf?O`W@e2y$OW^cceB(oqk;21#}% zd-hevs94>IIb{u7}@NzXu|}f0uuE67Kp` zJ^Y^ER)53WE+*Fj@?e(e8eb)I>fsOhcPG1d`2A4+y@Wvf+rr8>q6&+I}_|xSU z^b9SiM?PB*|0yVAt$E!MRQ{PCQm0ZdTP2dl0W}}id4r_KcS^xx0jf4OsGCC&oF4BJ8taivyL;ghoFvC4mFuwjB$+nm5}x zwzVTd>;&O8jbo|j84Sv0o}u28c#qPLifvt@TPT0^0>F-CUoF8Jc{aBn@b8n|5o2uK5vs*CIX7?zN;{zCcS0`FDe*{XUQ$GY0( z%VbpwJk2X(pd$jmyufyR!B`Kqd=gXzPfybpf%gSYHH&`r%#^Q^MJbpKGD8t;zf!38t`%)^ z4T+S3s{T<;gAsIpP&F=kq`-iDjhsm(=DOb>K@R}+TdUxjcDa@e30Ua|^jBShg58BV zuqwkt6r=KWG9@jj`gg2r2R#VXH4DRnx-69INRE`EJBqQ{+!kRDE(`@|=hNU48+^!? zv=r}Wnnch;K>fj|QPPqQxt_F0RYq1C{*5q)R%K`%Ffo+$v%pLTIBC6}!hdQRojpRX! zC|`!wby33+^vHsmF~#J_x5?I5F-(@eO zy^aHS(7~%sgHi#gng5(x-RT?1U z09ZBk>h=hBS`pOh*np`UB)tHb43zh`brJOR3eD#lEhV1-+G-FOY;@8Lb4HQJ7&FLH z_7FJ*P=AGU^o`Nnc@g+yML5kk*UB;y2nDshH5;j6&@(~(<#fcIM7hh!8UPmc(0-~0 zxF^D#1>>)++vx{8WCi(xQt))`m8d}kJ-bMDs8yOJ!{h?M{AM;@vA_oKoC2oHWhGgF zay8%C7$#H?HW|#7UhlnGR*?uuV!3T2*tuX{Ddt09CKk$SQUJiE9msVsr2?H+&^D{U zz7APK*uS7QSYtgR=y{<2^o)GG=R8?Ud>_!XOY`TtIzYp{;4{FrqG$nIXe#T7+?N70 z_{2~c0Xqulqw=V%CwgB%b8N1iePiVyb^ry#w^MP zLiWJ!gtqiG#s#Q(P`Q50O-QRWz6#;lYU@_;*O+AvAC!+-F%ROe~?#%pd zYJ|F=+{0_TXSQr28ei_A4wHH@fQtaVvCpTjhh#HB_yWz-f+Ns{K>nKc?KSmLWD7BP z;L?xqmeODeb5SWnbH78fl>j_Yd2uWr4i{(y^%r+9ZmZl(*d5Sn+T(lcBiJQi?rwEV z&92XE`7Y7+Qm#%8Hjb^I7eOxrO^@dOie_y1mJjjvit#mgmhp)&mzR=s_~B2V+(MKc z)ZaY~TRjUS@E3r+hw8w$WTA``W3LL(RaHzbBIp%Gax#((rrQXzgO!@oaZO{GYa`5+ zMOq!0&Y5y6f%U3fTSCi;%BMh z=!k&VR7JX5(I?+0eqPY&+4_NA3z}l%8b9%joX=$}2FgtLb|UCVB^`EWPNUXp=K3P+ zb+D-#u!=sK;4c1v*m=1pFQ$uo*GJInTTwOI>*WsO=AdchQJ38uhzNc|k#_fTv|WBk zlpNICQw_mJ2A`=B_{Lm_hdeF0AU`5X4qjSHi?=TuM3|dO@u2GAZIvGr5iiAGFyG3@ zK>%J{3G0GDqWE$r5%Gfhvvkdhpq&M^jyk@2p8SMxIB4!EHatea?jlN+s@pOocM$^z zoiH^SrE()gFNB-6dDe$?B$J;K3kUZ)$z5xH1nw{Jyfp63mb;0C1A9+SGp|_@bP%+q z)2@@B5$P_HW;a-i6hVhT^-V0BhmB?92chnCIfsU;AG$GuEl+|On=QW}-VK=MCX7xI zWEjMs=TlzgU2+f6ZBT!w8MCY*_;3jDD&XwWF+q@D64h=kaZLnS1LB>VM_I#QeJ{~! zux!7qxz|U~b)YHAo@}!=0)Nyg?~`8O;hgK`oN6 zeoM>NWF8HKxivCBLMA=-)x>%|)ixr3B!Ud%m79V9eH{__&gueJG+Q((4-+1S@rRh< zjnNT7?G-CNz!t*Gui=#{?`F@{MN z%zOL#wg`M*b%8I{(yd!di(mx1Ams_dH*f_SdBZ59$ zP<>KVvQM5MEDh>ffD)|h;M>`Nj}%cWVB4h&<)6f-LA@?m@1-iYx+4Prr3l;2x`-D% zNw6BUgz_yAO83yTfx8pF^sg%-`DiKjgQ?gy`4`b_V1KaWp+vyP0DVBRfDc!|Vw0B!t&Q z8UtzK2GMU|HzBsrct!+!s+4^i&#`IF^!9~Qq)Gf6Tw`C__XZ+B9Uy6f_XF#F@^8Z5 zFn+gmj%nMp2;3~Ne!$WXn|qqLcY*!c##eMi;HQC8Ex9+;C;uVr4Vn|XEej_{NVb+V zHys>FdD6STnK;crlCp6{6lsKKzFqZ5`izVgFC~Vuwa}7BZ=NJh-CX@u~>(Y?x$Jd_VCs8{s)%$yiwsP&-@- z5yI}&QkKOD7*kl3zhfgj7sf~C6V!o@K+glp6}L^dsSnDt8sYg>5o(0IN|#2MohznV zLAzF--3Tuzg)^<^cp9KxO5xZF1|6)+a~k1=pr!A4O0in1Kf>*-A4Md0Mbi6&4QA_P zr$%@Yn70L+J8Y^9xLXn&Uu@x~c6n|iycjHbj&qWq-Vwof2QQVULv9M+;h8_L5nht6 zx@BnFC3I%pmoO5+_W<|XzMD5u2kZHb@KV4s>}reUsHr>jNbFhN%>5=!_3QeSVcEG6 z{twpP&n?z)1ltR&3{ko`PXlo4j~=gja#u&HDKKb+0M)Uf8!&HHupl>UiA`<%{p-O>~awf0;u$4`ia~*`%%5IJD8YFX9vACU2 zZ(#O^$t`XcoSc}vxDj3pt}U+Jn$;irw;g`YunBuWW^;@CCtR1XD|Poqcpa?QiOn3g zT{=609tfJB!D6A>_@nZYMtD7p)ypzYgWSm8_*HmJ;0J-b@nn*`?UHucqY>T!mgWUl zbIJ|K!61G&_j=a0%S#*Kjp|uC1Um%GpMb8V4z5Pvr^=p<@TS5fh19v|x(IV< z#UyW^()eCYBfJ?V8_JaVPL73k#=PV>B6%2+X>9P}Y_v`GYJ|4{`&gnUYUZ0v=gJ z-CM+_zM>J{4w@TDxA<%E?8AaN3dZ~!Uwx`y*YmXpdpE*6;F1!#gN;uV!H+KYpcH1+ zq;y`{2=4?<*2wzN{0MjqV74$8U`keIe68%$2=9XR$o2T<$nRtMtwZH>%vqnjsuA7| zke*vdspMTmnB!o)O5F45>5zRJ;XRdnHFm6zFvr787~vU`=F6)aAwZ--Mc4lgMz9mA zVr(ClZ-tZn8sWW3+L!pQo)p1O1WWCgXOS&4J9$kbyss*+Wqui9PJ%I=$UU7CdS(Ac zct5!7mIbXx#|P#`;FGg>wQzNdytWZOP~D)#@!gkbQ+MoiJn&F=5?hU*a#m6PrcpdsuApTu+*&8oN0@^ zz7akGQ)xP3&bA182B^IRJtw&hW@nSNO&d7nphoy;xf`7i+Y-S(R^82`QM?AW_zjKl z@mA@vC9@*fnPB!FI`sOnHluQIBYdJNW$F0x@lF=nuP5yQa~6z0a}Kn~8yn%1sT?vk zDf~j`0Y4ku>qE^0$$>)}VG>xf%KpVbce%Q8T4B$D)yifi7S2S6yr~h|N+B9&9GV%y zCMS%Sv+X=`Xd_Gk(+;Ik&VdMUEH8oK<_@&Qut_I1fC77)#1AXk7$HX zl>$?k5^N5bKVFK7Y?Ze)!rUY|zF3{}arw$mv`Hp2W|wr3oMBiQ++ z6nnvbd3z%)NTpCk*?c5-A;Mk&n~aMuZ7y4OXu9QcR3j`z!k^cJHH0id7ZudTfsHJN zd`BaE8q}J|t$k+%yAUjOMqf3e)A9j1x)DB8%HYZLLtT9l^rA}MkA%=9`#O1NBYZZM zuKVk$q}35Df_Y1L#+87r9McFFSB3cas{!|+2y+R{1PxV-_^w8{6x`dHCbf_^;AMc? zpxO&o%dw5{xvE@?_;~au!dzZ4Lweeboz>GN?{0+8!=y^l)%wE`>ru3j!fo6+opPDtVQ9>hpC6}S!9HTBH*wtX^8Ffv(dyKlNev6#Y2wyFC z&^o7S2P5b;pjwrd(v|l%!q)(7QpbjiNi!qJwIJysywNPxE+;m^*J12MJSnq2f?by} zPwtJ#`x@aJ8S@m)UzY)F#Y$~J4 zBAuXNfFk&f;9ixUTv{xx&=)L6Ed}_OXbu?=t-sX0{W$_l@YABU^=TK&Gey0=qq>B zE?!cEF#Q$dJwR8I^DUM}7=ZCg=Nfe*)<@7m&|IxPt;J8*=kcfQk`Fh+Qe^a<#}}V( z)7c0%1ZIt;q3O~{aE2@%we@QjQ!VbfFqs=w* zK2^?Wgq479h zA8UlQpvA&l8k`PWPPK_htV1I8yA<0n2j=6AupTCL^cIGOx;Vm)RM+_?AX{B5XEwry zim|APMNHO5n2j)|c@{rY!0Gd##++2%D>N-9q@92$(G}=}B7{ z?KkqtM%Y^J&@t7ldwT@E8FV|Jec2>AyAi$%p&rp3J1t;x1R4X<=jI?u+vY8k8sU~w zD)-R|_{s=64yv&O6jt3I-E&vXdd_KtZSc8HEoopUeW1vEUZoLkh0SeYyFoRpxJB9; z;d?My#myT?r&A_%UlNhI4Vi2P{+En(U0-h9Ba<89`_ZM_#wD!yJsJkwM~n_KLRdBUkkA>cFNR7_%Tch z!VHeBr!tq0^)dzxj;$u127f2Kt4$7%%d|%LNkRSe%=Q@(^e#|SJ5>(iY|`EcKLyKG zT_OvcBFx<|MVWXes@NNNg`C$2KPz|Wun~0Y{0RDU(Cw6IeY;F=gkKbKOS_FNofJXu zDX6bnUePWy8sV3q>5+WUHzzv6+zaEzOV{0OY?GOd@GG$Lm^wJ?vSmBSAi~}U>p@dK zc{wN@jqvMAzRX@z&xE}nHd_yju@2_58sRsft(9c*qY>r-7;AqW4m_&3MrJp{Z^3QG z?+%h~|F;xbg!^5&hp&|-+Wo0U_&umS=^!rr@(A)^kyE>C%Yx@L!XH4>Tr(SXJ?3sh za^&^@NBE2wk`E!7bW@LO&}eSI%x#1}f~U8sHm7fjFb~7HcD7BMZ-M>}nb!z^0xmjs z>9$MJS2|I^`eoRaa(*NH6~^?@LzG)0*rQ+* zG{{!cENFzkLHI*hAfCK@1bqy&*aJW1u4PLZDtq2I6IO8?eX0(nIO0H(dkD zyg(K}5p)O8Z2QgRXcSu&Xq8+{QUg{M$YvW0BFK&)=~e9%bxdFn=TBWi z7NaW3XI0vgdWIt(FCmkWSPK?UNG!{xMz>){*m@k)+%*Yqu zCE1~f_(~D{c@^$wt98*1pChLMo~$kE!wN&Nox!|)bwNFgf#q@%8Gx=itlKgdYajye z0&J?SURldmH#}p>KAq2#+Q|2C_h2}J?FyzZHoo{%^kJRdu!7|aBr>wBHihn)1=|fQ zPwke-7fE6O_ycl`iRK+5;O>Ci^~v>Zas|l?h-59@&hd0SFMzdS z)%WX~6+!k)2>$UX4SFRB3J|L^?|LgD*j`|ztJ<`g2JVwDlc0dfilm-%j_HnXjj%6= zO%1Hd$2pGSqS`9v}1$HQyYoX6emyk&RCYc9dug~|} zsJbBn9tNn2WR2!0CHQG}gK`782H5nX-aS`F(8F7<@kx_qaGCbVw@5dX+h`<9m+b-` z0ce%WdhXeBBgq8-Q&C!Mn+N<>MerjNjtSQcx`x80$+yWcfT#YJ{QC%cR4&Dr;GpOP zUT-3^0AA`#+gxWAn*O6BsCFJSxjC5+$v3- z506tOM~9bT-`vzIufws z!6w+oZmyum72DWF&H))$0NZ(EOVWW)0N%$G)V!wFVCzKBp_@bmverIJ$5)Zju}`f< z@DnqxvBY%Tfb@`p05316i4OHe`yldgi3Y%= zR%yL&1U(J3sE@`NJUTZ>wxP(U^(^xu=;@%_z0i_bvXpcKgg>J1ywc^Qz-LtDSC)2@ z43S@eNp{^A3ER3TwfYhEV-=exUGAW5kY!{WVBOZto2H}B#%-6*i{NL1TYO)$_@lFB zImreff3BQ7m=}T10=7Qj=Y9{#3i1qKsV@8&Mf=cZggG0gm<}CB=pA0&GEB}Pm8IJ< z38&7FVCR6PN#(@YrjIf!NjxCo&8#cV*F>PnK=}cfh@}dXRb(Gv(p#u?viAi(7r4bb zkFA&_tI0qV;k-?wBLYtYcC9c|&dS?0WEucV`)j^g-K4D%<~$fvE;lKd70mEjat`20 zkJ1+eBj}6@y&5B@6XA7a847Ca_BeArf_CJR2eB#3)3KQANi`H{oW{5! znnnpukC1HuEN01bnY}hA>WZ*)VBMH#w2A!~8^}6B zNX`M&USFf2s(RYT!OyRxEt@{pC8J~>s?zPz(_%H43t;^5efj2U*+inD6vDJHrhMdJ;Q@Ey6zDv#l znG`D0yJ;jnpR}<)!e5qn2E&#-aT*`S$VR|hb1Y?FeYa+j$2%kVA15nhn1K-7aE{DEurJrWaHWDuWkX#}|%Bt4ra z$n{X?6>=LX378fo(ouhH1iuE{pLwbp5MB82eKHeOIjxR0%(XE7HmW!SayzMsRJ64n z*-q7%2!36{^ISxisL2mVQM4AWu8H>PRT1X;T#_%=*WtBK?jTc<@e+b%jS2V-1-CNX z`S~H~3h*?BnA2+ux^!l{F2ddj>s=4iZwcZbk+UeEe?_k&0^U?WUoF@tKPEQ;Xe!rD zb@>PAmPhc#8Bd!Esg5qWlf*=Y>p?KK_9KFKg1dTIx7Li6{Dd3?a57;dDUabP&%OxT z4Qra?p;hfG+HdT@A^zPgcaeKYCD3PV%aQg~H9R;0u)VN0!r4}DZ1+#eLV)?BOwXD0 z2;2{>Do8RcGXhQVBs&7g8Pn%qNzp`g6K?jv0v zL09E+OB0SQmtT@u$T%GuS#_DWM({P@CG2KSqvd)=_~4H^@4kp|RPH6!fTRyGzKbw| ztph6tLuaC@@9X4OBp1s4JdeXO4o2`1@T|WUnNi(U?e3TRNG(*XuLD@aAY}CxVK-K+ z_aZ-Y4+;4-iH3Yfbt00jjo_QW(=+;7GXJvh{UjVxc|MG`yziz6y9HLw!K?+I6Zj38 z1|ZcDjd2V_fSUnayC(b6NNmglq!@rpwde%i;`|Y2491%h1E8MtYWXd>2GH&1Eo|CFUa3&-a{n+Vzn%eJ3JRs>t@MN3Jjp;cS;J1R8M^THU35h}ZJt>EZ@ff%c`n?h6 zwp13HZFyh*T_q2aPyqM-rGaAl9N6t(>4mHvw_PHCAbkMpcE}ReOl|=00QAaI+tkd~6ky=X8 zz(3E0^suuwe~$RiWDCIE>YO}v{=x`y4~VzCBI@mpqe6cnSpbpRt!1tdVeW-VHSTGh zVficR0?=env~Tl={sw*@c=CLFIA?i}TMN^JM@bx1<@q+w%@Oo|P=By$)8$P08##lj zK+i*J7DJ7ox%m-^2dV=7kg&D#7?}f5dqAIa4vp)fUf{ng(iSYy!!G_#)&R7qtr`^{ zNMRl<^4_m7^N*7~0CnR;BjZCvu!q3xj_N4&B}eHWD~F{EK`6Y`V7}_P%u6#W>S2kHJ_NMi1kZr$`V0Xa%U|m%$JG zad2;2J%lbh)HQMh5ansrFzeI$i43q$z?Ow{Eo=MpH!*#ZD0OlM>Bc;JWx&Co1W)O0 zTZ4eQ>&9hikT-xThEZR7FoHe>>MohCD_AW}vIan{vx}7xunySL5A{oo@^4ZGz}1k2 zR)96Z%2c2_ci6p`Zh4y20TSit$N!R0ZI4JjjZ~_uD&XUrG5$j`0oI?=_B66O5Kx}V z@2D#d2;9sUX@+Njrk+c6CnW>l0o>*fmf28?YooT$N}tgT&xB82^e}7dL3Yd~>FDU; zn=aX*8J-314|A+pn9&IMY(TFYTkO~&&uoV0fO$1`s5MdtG6L@e>}{iy%T0@>%#a;w#NSij(Z~D7^PO(oB5h8M&5E8t|(``RPm?trNVx;b6!dCl+=5bt;M<|Jd^)e#}~ zs7m&ky6-`LelxrjCL4QfpiY}X_XI7|Pg`c1oC8}H#9Qp#4F88rb{%{v>O>i9wv`dd zy^t*H3jRlFE~$TyZ;%%>!^@D*RzhuAQO&Ip_T?4ptg?|k4Ws3N}8@JDZ4hqs{p(abW`Ifb{%kEK(9ZI z3yzL&XqOi?!>iM^3%IsB0_+E1o{g#mp%2-u8D0bCPnLE@_soyL`vY6EY9Mz=Ufc|? z1u1%=-k!~zBg_G*SeEf}Czk8(-VCoR#oB~~#n~MZ_&{Lm9Ryu?0{wtYue_ugUJveX zWnK!qtN;&6<#I0qn7DI$G{YOfvelxNbWC=e<{wXBQWcRpIA5u*9Zr_Kv>DzAwq4Kg z8MbDL^0h{a~O>23XL>h_G*T=q$2bj8+W${=11_u3vSa*9aZ||WzFzb@YH!2 zaH*`-5%h>8&Eu=btIH7kL+^i+e2+gDMRNq?EA7PJ%Ek3ZX<{!~&kXJUtJK_8- zQkJGYf*w;)6hKYkdfBHL-UXT}IiD}w6~T|qxM~-lRn?}GS2e@CGp;U@rjqq+74YN0 zC#bZgl4aj!cn^#Z8$_fw6WahgK4HA8)u_C>83I_Udq;;O=m`bYk%-;19kO3Dycaah zs&xsQ&N+rr&h7|zB3ynF9XD)z9FW&E!~0^8TWd|MmDe`I2S9R*rH_vLw`qDK>?x@Xtx5i@kpr6HgJAYVu5CIW z-Vni01yAqbok?q{PhQsyA4>ONP_mD-nU<>mzA3_$FU`HU^9F;U19oZi(=9o zeIUY~4qMD-a^P&F)s2l8%j=urBS^SaOIyE5;Q^lkoF37(CZsUrLCx^dim_g84KNsC zJ_b`pn3fP@I@Hq--tU(;G{eVRBvVMzPL{_K(Aiv`v=5SJBKcn(LH8gZ+zg+np5$uI z@=JCk!kh(@l+8!~L3v{{d=k`*x~EfyBG}nrrBPeH>_sH;kY<>at{7j;ep}rD0(K6V z8({B#YvoPN(3XqoA0NPqa7HTq%KA`*ot)WfjjBb5$4BMRW|#tNT2jSzdn5R{;I5UY zW5&o^zPTBuf~96jv1--j2s16+1I=k+`2V$XSTnTed-&>Y-*gUs9(d|$xtHmjd%3)& z8K&oJ+@!0H_DAp;;8u-3G7ZY%%`g*8O>-N=+Uf|<0bm{pmEcPST4n`oLzlNU!z^TS z-J1#Yq%j%bEY!Fl`I(9W3^5p+(zLKlg6z{kcsd0R8gZMhc> zq)nq=$HB-&*mMey^%tvcN7ER(l4!ve7M zp%)JlYtYi>gxVlHn+BvjI*RlKNc-FP0t1$j9Mud9)BXG@^>4N`fG+~i1~AXZn47+% z89oh@mQXHbJJE914-H}3`Bph*8U8}}{FbSw`AR1Ow!)HO#Q~0Om?eOmi6Je5i=r)XQIi?vd2FopNOMETNMcKMiajXrZidf;T5r?l z^^aQgM({7RNUKR>8gX1Rd=a!%Hm+QXEyG+zK#%{r7R?9vE+9r$*WFkOJ?_M~6l*9_mtSE`TWBlFe>em%H#emoG{Sr8B0X7+)?O3kY&tSd38NOBBHD?n>BlwNrsVi&nYOS2y4BrOx@zFPM zkzkI%HvxO)y-z2px^Mjh&G4O608Q6PuUi(u7K4>h(Z@IMbuAW#q5PC)Sb}7#dY^Wv zYc?EVI$?6pwc$NkrZlpS$_JaF3z_8a`$*Wj`d=GzWkjkQsnoCh%nDu4B&Rk*4}`xE z^DY)6u{!~@7c`j^HH7}iX=jOis2Td;t>yKB(`xPr-Vff|Z*1xNsGQae0~O;D2_IKr z24Sqt-6yi|Eubs?^5JG!3TG|zRlWzPQx~wIEbo&NkNxY1B2RCIWvzGVPN&_Q<*a7d43wtb9=?fyTL6n5ZD3udK3iHvC7*1Dt?;Q;&?8h_Cz#+jgKG`z z0nW?~&TfY9f|!<6VFvY&w??=zxYjnr&6v~-x1=)EGh%lr$T)~u5Y=hRYk57fQSqE+ z*an-dfI5}SBG|2^WL?U>ag5`M+nV8fSu%xVBiLVHBO*G-PLklGyDv^7z;}n(x9Ue=I1c3-uN=BSvott8GeyV>8A1gJ2Pt{ z_&wnMO5VxXZ7`!5ewj+3A^T9;;RtqbRVs&05wn@u48H;^D&YpslWC(7_C8p9a`h_H z1X4Ph;nxY*FJ5IgC4%3d<^3%^3OuVBegj_Kbi^mG?5=`&AYW0XX;;YXX83K!J#^q} zaKL{Do(!TcBBJ3lu z#lBQqj(q#nAd+ikelz?TsWh5*VK3Agy4&vgy#9#HUyyMn(b-4md^x`v{#r2Gfj2LL zJql*ldKurY*dz;@;cp;5w&#U$9TE63U~6sN+QB!A`FoRG&N@Gs!h0xgP2`*cOvrz+Oh9N10%Kf>NTFt4Ke|34z)hCA*XZitAA zh`4J+bRr@mBJN9Q3zW8@mKG_Z4h0br5nK=vkv4l;+9Yk$q)FQtQba^VR7BkOeczGi zd48|6%)L(vzt8uNr0M&8?%aE4&YU@O&dgkHHZEu1nf?nKFKeke0ss@lMq%!#nQEO9 z@$3)Ynf?dk9o#JVW~(0XJHhL&X&YTWbZ2USR+Z)>LhRJfu+37IT2TK$^t62V&eW>P z!kTLoXC#Ble@g|Nwse`Nuq2a80oDg1Kxm63adsAD@V&sT_e307&LMpQ7V0s`-Wia+ zLHw~*iN;qiT_kHro`4pWw6D#v4FbiCj3RamnSGFniua&mwO32dy))e#)~dk1UZ@^MM#6V7^zK*THr2a3sGd%<> zp56nQ8p>OjVIB%o6oAQux&%HG?U#>{LxI)%*;kq}zI&Q0HGs%d3A$b%SAB(zH z+m7=L_y|CEO)Q@!AHOp_63A|-&80zrUQDF^-Jf9}RhO^ddm2RJxAF=X-I*Q@6P~F~ zP~9`--wgMdwlX8o;j6&=NHcA#hQXM;yqcGIj;R7+yW=SY>5l3Xh$GuR=4F$}9p56k7G zLcl@~&SNe_EHQ%~3TiD{)*)Rp+bf?Z1p@B+Y|bX9OamTPggu|6mAX}~APEBQ4zUIc ztg^%N)l6lu7lQfikHGHPhaAX;07g62R=+=A zNj?N7-pxNYJ1Acy7XoVU)=QSnmkw^u;4dwBq{VpD0lA8NNL{|0Oxx?1VO|asW@3`q zz16Ap{bBhM*$`OOhSU99?;suJ4w^OdS=)eIO)jM1W!|Yh82kwEcr#yFqgQQ{wPZtJ z{LNws)v647Bxq$=?O0SQ)Ali;)4j5eoJe(@ddyREo7l@iR-{7po%tD*9`YifWoqx? zMmx*EXGglh6`4+Ctcks5^!fCwkOR_7t^_WgUR^|;3+sEq991(uplB*`m-LY-feD@V zVL@{x_9hwjXjp4GpJ%Ev4N5;*67b^jqrh~3z+(W_O515nGC-CDAchWguKP0Bv8BX1 z!o6Jv$&Y}C=J=ebFM}Qj8iQI1VW`vHD?{W*sw-G?s1vcC40=51y!TP{R=0RmhRKk? zx*b#-g1ZfN0$5dRT9-N*8I|?qLty+ZZ5n|%;9H{zOsu+?t7QXu5HMA|xvNjYAI>0e z2XQYWz}qsLQTb z-A-qig)sI;9(mCP5!+>qOh$dhFbmzLVvRb?Nu~5_IPGdoHj~K!vFG!d=3oXp1isoHEJebez(=kL z87GfX-^*jYCHA^K!*-W@*+^jS65oy>kpUj9V3B4UtHv|T^0)_M!TPyTGWZiDFTko0 z+?Z)G>mealK*WpAcgT0iBpHmFEukn6l#FKBm9Wv3{B?H9c5)VRjT+4`E*ip{U~xF? z8L;jlX?SI;Op&+%@@I?l6m<1UhBy;KE6ZNw8VtfT849p!bn!DrbQCEkR3UK|67yn` zw#J}H&{SJx2YHLSoGP%a0ec_FGZJUV-F3{v9QDXfG8JH9rc{<;8N~&RBb z9olhY2Quu%Q4;n*mxv6=SIAe?rR)2SWw1+XIrXJ`BD5d<@X}PX@UfB<|>XwoPs(QBlhDNWDJEH5q(e!F6WlThhkmo1`Yd^$Bgp zHLtxgY%gqCZnpbe(~C|nu0B*P01}}Dv+*h|s;5Cwg27#<{E+@&PR#lyVZ-ND{tm|>| z8GNLa?+Q37w~>YwmamEetKuRwvAEc zQX9=ZVCG;-V2O%QJ7+7xEK<>fFZ(lc6Ucbg#zBld8T7igGHqsovSQwTPKE+TZQ(Lo zhPra`iVS!?pc{PqT+}N01?h%>hlwFUeBC`m@*$h*_qo zpf`d>O_i@b49Ks@P*gXdn#Wl(oB?kt!u?dVo!X97{59zb@T&T30zxHCXPBE|Lf^Ev zvY~?n1(-gFuUuERJA>W=8hzLj)zOE?ywFu-fJOw0|Hs0a^?n&8CBF zBLf_mE#%qC$Qen&31A=G^+R)G8qN; z6*0a93H)c^wHi&$j&{jk$z_1>$&s8oUseMaQp~34yO@2aQvO5wWB#2PVKeC8Kz&?@ z<;#4u>%ZhYfZYt3^;VZ|FoXXCyn01H$4YfRPPaoV?;yv4Otgl@v#JA|wr1FW!P+Ah zk4h)8ngRPC2@g1PB9-&dM%j%tmf`;s*Xn}dl3Cq-4r@2=B;f()dTV2Y&L`Go@H@cE z_^|ujmC_*30puR0@5i6afOi7gxTHp9NSY)#K+IN!#%Hi*Na6f%WlLy_ga$~}L;duo z2q0%zxg(y+C$Boy9ujG!dla1X2r)lG!ZZi?Uf_05JQ)V6^>U9!x+hpDoI7mloDXK0 zymNt3qvc9dU^ax({ePXZw+tx|Z*rjdX9=Y7CyhBC73j2X1|azYn~R zIm)mgVedw|FPQd_IACj;TJEzl#Qh-rvB)zj+Aa5Lr2B)$Ys3kGd@*QyhS?V;Zr;XV ztovETwNE2GpuTeb+;+^kA8-QmKp1UwOqnl-A)+MrZlni+m(I)7(jraEGQ@)+D%~VY zr}0*`bJ)21G}1$0{lVivs#O{Ep`fN2EUZCK@7qWZ15uq?V93cCXg{E~Sql@o`!&+T z0n6RY11&orrZVg!V7=>=b1J*!{*ClV;7~gqBG@3(NRO&S?L9SoC;K+iqk;7~eB|uP zK#u{c)X~1_;JF5d+6Oe!V_~a-StH@<*Gy%Y$HBx@-{a&OBR4+;39YD|^1w!VJW|nl z)sHA!5;kVIC%}2-m6cZVphkKks2OXYJ%a2HVjZ=fR_%}nH`0?z**<%;87PWAn&F;Y zIG^T~bu44@kVbk+DbFW(9$5l^D!4z7hZ}uEt6p6v@ZX`|K@o{-nBR!X^e7wNv z^_ke(41OrMHv%f8e#Q=YbR#_vRNtIqV|JgL0S+sd`$P?WqeDKXk)98}#~DLv?=#fl zP~PFR{`3P~k8PwE0Q&7-MR;hpexeWbg`j#n?Y;}-agFpMfW!SA%W@l^w6%ZS!<`fJ z3t~#=?>n6-;lQQ?fUeP5_Y@}C!TJQ6iYZ=`KGh7E;=�H`epw{dL>xt?Y8oD9SyK6!yEyly;5Un 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 eLAc@=^3mx*H}X4 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 dtu_6!a~3Q*Z Date: Mon, 25 Aug 2025 14:32:29 +0800 Subject: [PATCH 17/22] feat: add qwen2.5vl --- examples/CMakeLists.txt | 1 + examples/demo_qwen2.5_vl.cpp | 71 ++ src/Tensor.hpp | 10 +- src/backends/cpu/op/CPUBinaryFunc.hpp | 10 +- src/models/qwen/configuration_qwen.hpp | 15 - .../qwen2_5_vl/configuration_qwen2_5_vl.hpp | 68 ++ src/models/qwen2_5_vl/modeling_qwen2_5_vl.hpp | 770 ++++++++++++++++++ tools/quantizer/QuantWriter.cpp | 9 + 8 files changed, 933 insertions(+), 21 deletions(-) create mode 100644 examples/demo_qwen2.5_vl.cpp create mode 100644 src/models/qwen2_5_vl/configuration_qwen2_5_vl.hpp create mode 100644 src/models/qwen2_5_vl/modeling_qwen2_5_vl.hpp diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6a65b0d15..7ff3fd5df 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -122,6 +122,7 @@ func_vlm_add_executable(demo_imagebind) func_vlm_add_executable(demo_imagebind_1mod) func_vlm_add_executable(demo_phi3v) func_vlm_add_executable(demo_qwen2_vl) +func_vlm_add_executable(demo_qwen2.5_vl) func_vlm_add_executable(demo_showui) func_vlm_add_executable(demo_qwen2_vl_vtp) func_vlm_add_executable(demo_showui_vtp) diff --git a/examples/demo_qwen2.5_vl.cpp b/examples/demo_qwen2.5_vl.cpp new file mode 100644 index 000000000..c0fabb89e --- /dev/null +++ b/examples/demo_qwen2.5_vl.cpp @@ -0,0 +1,71 @@ +#include +#include "cmdline.h" +#include "models/qwen2_5_vl/configuration_qwen2_5_vl.hpp" +#include "models/qwen2_5_vl/modeling_qwen2_5_vl.hpp" +// #include "models/qwen2_vl/vtp/modeling_qwen2_vl.hpp" +#include "models/qwen2_vl/processing_qwen2_vl.hpp" +#include "processor/PostProcess.hpp" + +using namespace mllm; +int main(int argc, char **argv) { + cmdline::parser cmdParser; + cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2vl_vocab.mllm"); + cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2vl_merges.txt"); +#ifdef ARM + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2.5-vl-3b-instruct-kai_q4_0_f.mllm"); +#else + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); +#endif + cmdParser.add("billion", 'b', "[3B | 7B |]", false, "3B"); + cmdParser.add("limits", 'l', "max KV cache size", false, 800); + cmdParser.add("thread", 't', "num of threads", false, 4); + cmdParser.parse_check(argc, argv); + + string vocab_path = cmdParser.get("vocab"); + string merge_path = cmdParser.get("merge"); + string model_path = cmdParser.get("model"); + string model_billion = cmdParser.get("billion") == "3B" ? "3b" : cmdParser.get("billion"); + int tokens_limit = cmdParser.get("limits"); + int thread_num = cmdParser.get("thread"); + CPUBackend::cpu_threads = cmdParser.get("thread"); + + ParamLoader param_loader(model_path); + auto processor = Qwen2VLProcessor(vocab_path, merge_path); + Qwen2VLConfig config(tokens_limit, model_billion); + auto model = Qwen2VLModel(config); + model.load(model_path); + + vector in_imgs = { + // "../assets/bus.png", + "../assets/two_cats.jpg", + // "../assets/bird_image.jpg", + }; + vector in_strs = { + "<|vision_start|><|image_pad|><|vision_end|>Describe this image.", + }; + + for (int i = 0; i < in_strs.size(); ++i) { + auto in_str = in_strs[i]; + in_str = processor.tokenizer->apply_chat_template(in_str); + auto input_tensor = processor.process(in_str, in_imgs[i]); + std::cout << "[Q] " << in_strs[i] << std::endl; + std::cout << "[A] " << std::flush; + + for (int step = 0; step < 100; step++) { + model.get_position_ids(input_tensor); + auto result = model(input_tensor); + auto outputs = processor.detokenize(result[0]); + auto out_string = outputs.first; + auto out_token = outputs.second; + auto [not_end, output_string] = processor.tokenizer->postprocess(out_string); + if (!not_end) { break; } + std::cout << output_string << std::flush; + chatPostProcessing(out_token, input_tensor[0], {&input_tensor[1], &input_tensor[2]}); + } + printf("\n"); + model.clear_kvcache(); + model.profiling(); + } + + return 0; +} \ No newline at end of file diff --git a/src/Tensor.hpp b/src/Tensor.hpp index 3b08bcd41..bbee7bcc3 100644 --- a/src/Tensor.hpp +++ b/src/Tensor.hpp @@ -818,13 +818,19 @@ class Tensor : public std::enable_shared_from_this { static Tensor zeros(int batch, int head, int sequence, int dimension, BackendType bn_type = MLLM_CPU) { Tensor tensor1(batch, head, sequence, dimension, bn_type, true); - memset(tensor1.hostPtr(), 0, tensor1.count() * sizeof(float)); + std::fill(tensor1.hostPtr(), tensor1.hostPtr() + tensor1.count(), 0); tensor1.shouldInGraphs() = false; return tensor1; } static Tensor ones(int batch, int head, int sequence, int dimension, BackendType bn_type = MLLM_CPU) { Tensor tensor1(batch, head, sequence, dimension, bn_type, true); - memset(tensor1.hostPtr(), 1, tensor1.count() * sizeof(float)); + std::fill(tensor1.hostPtr(), tensor1.hostPtr() + tensor1.count(), 1); + tensor1.shouldInGraphs() = false; + return tensor1; + } + static Tensor full(int batch, int head, int sequence, int dimension, float data, BackendType bn_type = MLLM_CPU) { + Tensor tensor1(batch, head, sequence, dimension, bn_type, true); + std::fill(tensor1.hostPtr(), tensor1.hostPtr() + tensor1.count(), data); tensor1.shouldInGraphs() = false; return tensor1; } diff --git a/src/backends/cpu/op/CPUBinaryFunc.hpp b/src/backends/cpu/op/CPUBinaryFunc.hpp index 484a32e72..270cfc2a5 100644 --- a/src/backends/cpu/op/CPUBinaryFunc.hpp +++ b/src/backends/cpu/op/CPUBinaryFunc.hpp @@ -227,15 +227,17 @@ class CPUaddTwoFunction : public Op { auto input0 = inputs[0]; auto input1 = inputs[1]; int batch_ = std::max(input0->batch(), input1->batch()); + int head_ = std::max(input0->head(), input1->head()); for (int n = 0; n < batch_; ++n) { auto n_0 = std::min(n, input0->batch() - 1); auto n_1 = std::min(n, input1->batch() - 1); #pragma omp parallel for collapse(2) num_threads(CPUBackend::cpu_threads) - for (int c = 0; c < input0->head(); ++c) { + for (int c = 0; c < head_; ++c) { + auto c_0 = std::min(c, input0->head() - 1); + auto c_1 = std::min(c, input1->head() - 1); for (int h = 0; h < input0->sequence(); ++h) { - auto s_1 = std::min(h, input1->sequence() - 1); - mllm_add_fp32(input0->ptrAt(n_0, c, h, 0), - input1->ptrAt(n_1, c, s_1, 0), + mllm_add_fp32(input0->ptrAt(n_0, c_0, h, 0), + input1->ptrAt(n_1, c_1, h, 0), outputs[0]->ptrAt(n, c, h, 0), input0->dimension()); } } diff --git a/src/models/qwen/configuration_qwen.hpp b/src/models/qwen/configuration_qwen.hpp index 8f3789106..32f708bcb 100644 --- a/src/models/qwen/configuration_qwen.hpp +++ b/src/models/qwen/configuration_qwen.hpp @@ -180,21 +180,6 @@ struct QWenConfig : public TransformerConfig { sliding_window = 32768; vocab_size = 151936; tie_embedding_words = true; - } else if (billionsType == "3b") { - attention_dropout = 0.0; - std::string hidden_act = "silu"; - hidden_size = 2048; - intermediate_size = 11008; - max_position_embeddings = 32768; - max_window_layers = 70; - num_attention_heads = 16; - num_hidden_layers = 36; - num_key_value_heads = 2; - rms_norm_eps = 1e-6; - rope_theta = 1000000.0; - sliding_window = 32768; - vocab_size = 151936; - tie_embedding_words = true; } else if (billionsType == "ds-1.5b") { attention_dropout = 0.0; std::string hidden_act = "silu"; diff --git a/src/models/qwen2_5_vl/configuration_qwen2_5_vl.hpp b/src/models/qwen2_5_vl/configuration_qwen2_5_vl.hpp new file mode 100644 index 000000000..cc6700700 --- /dev/null +++ b/src/models/qwen2_5_vl/configuration_qwen2_5_vl.hpp @@ -0,0 +1,68 @@ +// +// Created by Rongjie Yi on 25-2-9. +// +#ifndef CONFIG_PHI3V_HPP +#define CONFIG_PHI3V_HPP +#include "models/qwen/configuration_qwen.hpp" +#include "models/vit/configuration_vit.hpp" +#include +// #include + +using namespace mllm; + +class Qwen2VLNameConfig : public ViTNameConfig { +public: + // string token_embd_name = "model.embed_tokens"; + string patch_embed_name = ".patch_embed"; // + string _merger_name = ".merger"; // + string _ln_q_name = ".ln_q"; // + string _m_mlp_0_name = ".mlp.0"; // + string _m_mlp_2_name = ".mlp.2"; // + string _gate_proj_name = "gate_proj"; + void init_qwen2vl() { + vison_model_name = "visual"; // + _patch_embedding_name = ".proj"; // + _layer_name = ".blocks."; // + _attn_base_name = "attn."; // + _ffn_base_name = "mlp."; // + _qkv_proj_name = "qkv"; // + _o_proj_name = "proj"; // + _up_proj_name = "up_proj"; // + _gate_proj_name = "gate_proj"; // + _down_proj_name = "down_proj"; // + _attn_norm_name = "norm1"; // + _ffn_norm_name = "norm2"; // + } +}; + +class Qwen2VLConfig : public QWenConfig { +public: + int vision_embed_dim; + int visiion_intermediate_size; + int spatial_merge_size = 2; + int spatial_patch_size = 14; + int window_size = 112; + string projection_cls; + + int bos_token_id = 151643; + int eos_token_id = 151645; + int vision_start_token_id = 151652; + int vision_end_token_id = 151653; + int vision_token_id = 151654; + int image_token_id = 151655; + int video_token_id = 151656; + vector mrope_section = {16, 24, 24}; + vector fullatt_block_indexes = {7, 15, 23, 31}; + + Qwen2VLNameConfig vision_names_config; + Qwen2VLConfig(int token_limit, string billions = "3b", RoPEType type = HFHUBROPE, int vocab = 32064, string project_cls = "MLP") : + QWenConfig(token_limit, billions, type) { + // names_config.init(type); + projection_cls = project_cls; + vision_embed_dim = 1280; + visiion_intermediate_size = 3420; + vision_names_config.init_qwen2vl(); + } +}; + +#endif // CONFIG_PHI3V_HPP diff --git a/src/models/qwen2_5_vl/modeling_qwen2_5_vl.hpp b/src/models/qwen2_5_vl/modeling_qwen2_5_vl.hpp new file mode 100644 index 000000000..b29eb745b --- /dev/null +++ b/src/models/qwen2_5_vl/modeling_qwen2_5_vl.hpp @@ -0,0 +1,770 @@ +// +// Created by Rongjie Yi on 25-2-9. +// +#ifndef MODELING_QWEN2VL_HPP +#define MODELING_QWEN2VL_HPP + +#include "Layer.hpp" +#include "Module.hpp" +#include "Tensor.hpp" +#include "Types.hpp" +#include "configuration_qwen2_5_vl.hpp" +// #include "models/qwen/modeling_qwen.hpp" +#include +#include +#include +#include + +using namespace mllm; + +class Qwen2PatchEmbed final : public Module { + Layer proj; + int embed_dim{}; + +public: + Qwen2PatchEmbed() = default; + Qwen2PatchEmbed(int vision_embed_dim, int patch, int img_hw, const Qwen2VLNameConfig &names, const string &base_name) { + proj = Convolution3D(3, vision_embed_dim, {2, patch, patch}, {2, patch, patch}, VALID, false, base_name + names._patch_embedding_name); + embed_dim = vision_embed_dim; + } + vector Forward(vector inputs, vector args) override { + auto embd = proj(inputs[0]); + embd = embd.view(1, 1, -1, embed_dim); + return {embd}; + } +}; + +class VisionAttention final : public Module { + Layer qkv_proj; + Softmax softmax; + Layer o_proj; + int head_size_{}; + int kv_head_size_{}; + int head_dim_{}; + string attn_impl; + +public: + VisionAttention() = default; + VisionAttention(int hidden_dim, int head_size, int kv_head_size, int head_dim, bool bias, string attn_implementation, + const TransformerNameConfig &names, const string &base_name) { + head_dim_ = head_dim; + head_size_ = head_size; + kv_head_size_ = kv_head_size; + attn_impl = attn_implementation; + + qkv_proj = Linear(hidden_dim, head_size * head_dim * 3, bias, base_name + names._qkv_proj_name); + softmax = Softmax(DIMENSION, false, base_name + "softmax"); + o_proj = Linear(head_size * head_dim, hidden_dim, bias, base_name + names._o_proj_name); + } + vector Forward(vector inputs, vector args) override { + auto cu_seqlens = inputs[1]; + auto rotary_pos_emb = inputs[2]; + auto seq_length = inputs[0].sequence(); + Tensor q, k, v; + auto qkv = qkv_proj(inputs[0]); + auto qkv_sp = qkv.split({head_dim_ * head_size_, head_dim_ * head_size_, head_dim_ * head_size_}, DIMENSION); + q = qkv_sp[0]; + k = qkv_sp[1]; + v = qkv_sp[2]; + q = q.view(-1, head_size_, -1, head_dim_); + k = k.view(-1, head_size_, -1, head_dim_); + v = v.view(-1, head_size_, -1, head_dim_); + k.saveData(); + q = Tensor::apply_rotary_pos_emb_vision(q, rotary_pos_emb); + k = Tensor::apply_rotary_pos_emb_vision(k, rotary_pos_emb); + Tensor o; + // if (attn_impl == "flash_attention_2") { + // o = Tensor::flash_attention2_forward(q, k, v, false); + // } else + { // eager implementation + k = k.transpose(SEQUENCE, DIMENSION); + auto qk = Tensor::mm(q, k); + qk = qk / std::sqrt(head_dim_); + auto attn_mask = Tensor::full(1, 1, seq_length, seq_length, + -INFINITY, qk.backend()->type()); + for (int sid = 1; sid < cu_seqlens.dimension(); ++sid) { + auto cu_end = cu_seqlens.dataAt(0, 0, 0, sid); + auto cu_start = cu_seqlens.dataAt(0, 0, 0, sid - 1); + for (int sx = cu_start; sx < cu_end; ++sx) { + for (int sy = cu_start; sy < cu_end; ++sy) { + attn_mask.setDataAt(0, 0, sx, sy, 0.0f); + } + } + } + // + // static int Layer_idx = 0; + // attn_mask.saveData("mask" + std::to_string(Layer_idx)); + // if (seq_length > 0) { + // Layer_idx++; + // } + // + qk = qk + attn_mask; + qk = softmax(qk); + o = Tensor::mm(qk, v); + } + o = o.view(-1, 1, -1, head_dim_ * head_size_); + o = o_proj(o); + return {o}; + } +}; + +class VisionMLP final : public Module { + Layer up_proj; + Layer gate_proj; + Layer act; + Layer down_proj; + +public: + VisionMLP() = default; + VisionMLP(int hidden_dim, int ffn_hidden, const string &act_fn_type, const Qwen2VLNameConfig &names, const string &base_name) { + up_proj = Linear(hidden_dim, ffn_hidden, true, base_name + names._up_proj_name); + gate_proj = Linear(hidden_dim, ffn_hidden, true, base_name + names._gate_proj_name); + act = ACT_FN[act_fn_type](base_name + names._ffn_base_name + "act"); + down_proj = Linear(ffn_hidden, hidden_dim, true, base_name + names._down_proj_name); + } + vector Forward(vector inputs, vector args) override { + auto x = gate_proj(inputs[0]); + x = act(x); + auto y = up_proj(inputs[0]); + x = x * y; + x = down_proj(x); + return {x}; + } +}; + +class VisionBlock final : public Module { + VisionAttention attention; + VisionMLP mlp; + Layer norm1; + Layer norm2; + +public: + VisionBlock() = default; + VisionBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, string attn_implementation, const Qwen2VLNameConfig &names, const string &base_name) { + attention = VisionAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, true, attn_implementation, names, base_name + names._attn_base_name); + mlp = VisionMLP(hidden_dim, ffn_hidden, act_fn_type, names, base_name + names._ffn_base_name); + norm1 = RMSNorm(hidden_dim, 1e-6, base_name + names._attn_norm_name); + norm2 = RMSNorm(hidden_dim, 1e-6, base_name + names._ffn_norm_name); + } + vector Forward(vector inputs, vector args) override { + auto cu_seqlens = inputs[1]; + auto rotary_pos_emb = inputs[2]; + auto hidden_states = norm1(inputs[0]); + hidden_states = attention({hidden_states, cu_seqlens, rotary_pos_emb})[0]; + auto residual = hidden_states + inputs[0]; + hidden_states = norm2(residual); + hidden_states = mlp({hidden_states})[0]; + hidden_states = hidden_states + residual; + return {hidden_states}; + } +}; + +class PatchMerger final : public Module { + int hidden_size; + Layer ln_q; + Layer mlp0; + Layer gelu; + Layer mlp2; + +public: + PatchMerger() = default; + PatchMerger(int dim, int context_dim, int spatial_merge_size, const Qwen2VLNameConfig &names, const string &base_name) { + hidden_size = context_dim * (spatial_merge_size * spatial_merge_size); + ln_q = RMSNorm(context_dim, 1e-6, base_name + names._ln_q_name); + mlp0 = Linear(hidden_size, hidden_size, true, base_name + names._m_mlp_0_name); + gelu = GELU(base_name + ".gelu"); + mlp2 = Linear(hidden_size, dim, true, base_name + names._m_mlp_2_name); + } + vector Forward(vector inputs, vector args) override { + auto x = inputs[0]; + x = mlp2(gelu(mlp0(ln_q(x).view(1, 1, -1, hidden_size)))); + return {x}; + } +}; + +class Qwen2VisionModel final : public Module { + Qwen2PatchEmbed patch_embed; + Layer rot_pos_emb; + Layer pre_layrnorm; + vector blocks; + PatchMerger patch_merger; + vector fullatt_block_indexes; + int spatial_merge_size; + int spatial_merge_unit; + int spatial_patch_size; + int window_size; + +public: + Qwen2VisionModel() = default; + Qwen2VisionModel(int hidden_dim, int vision_embed_dim, int head_size, int mlp_hidden_dim, const string &act_fn_type, int patch, int img_hw, int block_num, string attn_implementation, const Qwen2VLConfig &config, const Qwen2VLNameConfig &names, const string &base_name) { + fullatt_block_indexes = config.fullatt_block_indexes; + spatial_merge_size = config.spatial_merge_size; + spatial_merge_unit = spatial_merge_size * spatial_merge_size; + spatial_patch_size = config.spatial_patch_size; + window_size = config.window_size; + patch_embed = Qwen2PatchEmbed(vision_embed_dim, patch, img_hw, names, base_name + names.patch_embed_name); + rot_pos_emb = VisionRoPE((vision_embed_dim / head_size) / 2, spatial_merge_size, base_name + ".rot_pos_emb"); + blocks = List(block_num, vision_embed_dim, head_size, mlp_hidden_dim, act_fn_type, attn_implementation, names, base_name + names._layer_name); + patch_merger = PatchMerger(hidden_dim, vision_embed_dim, spatial_merge_size, names, base_name + names._merger_name); + } + vector Forward(vector inputs, vector args) override { + auto hidden_states = patch_embed({inputs[0]})[0]; + auto rotary_pos_emb = rot_pos_emb(inputs[1]); + auto grid_twh = inputs[1]; + auto grid_t = grid_twh.dataAt(0, 0, 0, 0); + auto grid_h = grid_twh.dataAt(0, 0, 0, 1); + auto grid_w = grid_twh.dataAt(0, 0, 0, 2); + vector cu_seqlens_v = {0.0F, grid_t * grid_h * grid_w}; + Tensor cu_seqlens = Tensor(cu_seqlens_v); + auto window_lens = get_window_index(grid_twh, + window_size, spatial_merge_size, + spatial_patch_size, spatial_merge_unit); + auto window_index = window_lens[0]; + auto cu_window_seqlens = window_lens[1]; + Tensor cu_seqlens_new; + auto seq_len = hidden_states.sequence(); + hidden_states = hidden_states.view(-1, spatial_merge_unit, seq_len / spatial_merge_unit, -1); + hidden_states = hidden_states.clip(window_index, SEQUENCE); + hidden_states = hidden_states.view(-1, 1, seq_len, -1); + rotary_pos_emb = rotary_pos_emb.view(-1, spatial_merge_unit, seq_len / spatial_merge_unit, -1); + rotary_pos_emb = rotary_pos_emb.clip(window_index, SEQUENCE); + rotary_pos_emb = rotary_pos_emb.view(-1, 1, seq_len, -1); + for (int layer_num = 0; layer_num < blocks.size(); ++layer_num) { + if (std::find(fullatt_block_indexes.begin(), fullatt_block_indexes.end(), layer_num) != fullatt_block_indexes.end()) { + cu_seqlens_new = cu_seqlens; + } else { + cu_seqlens_new = cu_window_seqlens; + } + hidden_states = blocks[layer_num]({hidden_states, cu_seqlens_new, rotary_pos_emb})[0]; + } + hidden_states = patch_merger({hidden_states})[0]; + auto reverse_indices = window_index.argsort(); + hidden_states = hidden_states.clip(reverse_indices, SEQUENCE); + return {hidden_states}; + } + vector get_window_index( + Tensor grid_twh, + int window_size, + int spatial_merge_size, + int spatial_patch_size, + int spatial_merge_unit) { + std::vector> window_index_parts; + std::vector cu_window_seqlens = {0.0f}; + long long window_index_id = 0; + int vit_merger_window_size = window_size / spatial_merge_size / spatial_patch_size; + for (int id = 0; id < grid_twh.batch(); id++) { + int grid_t = grid_twh.dataAt(id, 0, 0, 0); + int grid_h = grid_twh.dataAt(id, 0, 0, 1); + int grid_w = grid_twh.dataAt(id, 0, 0, 2); + int llm_grid_h = grid_h / spatial_merge_size; + int llm_grid_w = grid_w / spatial_merge_size; + long long total_elements = static_cast(grid_t) * llm_grid_h * llm_grid_w; + std::vector index_flat(total_elements); + std::iota(index_flat.begin(), index_flat.end(), 0.0f); + std::vector>> index( + grid_t, std::vector>( + llm_grid_h, std::vector(llm_grid_w))); + for (int t = 0; t < grid_t; ++t) { + for (int h = 0; h < llm_grid_h; ++h) { + for (int w = 0; w < llm_grid_w; ++w) { + index[t][h][w] = index_flat[t * llm_grid_h * llm_grid_w + h * llm_grid_w + w]; + } + } + } + int pad_h = (vit_merger_window_size - (llm_grid_h % vit_merger_window_size)) % vit_merger_window_size; + int pad_w = (vit_merger_window_size - (llm_grid_w % vit_merger_window_size)) % vit_merger_window_size; + int padded_h = llm_grid_h + pad_h; + int padded_w = llm_grid_w + pad_w; + std::vector>> index_padded( + grid_t, std::vector>( + padded_h, std::vector(padded_w, -100.0f))); + for (int t = 0; t < grid_t; ++t) { + for (int h = 0; h < llm_grid_h; ++h) { + for (int w = 0; w < llm_grid_w; ++w) { + index_padded[t][h][w] = index[t][h][w]; + } + } + } + int num_windows_h = padded_h / vit_merger_window_size; + int num_windows_w = padded_w / vit_merger_window_size; + std::vector>>> permuted_windows( + grid_t, std::vector>>( + num_windows_h * num_windows_w, std::vector>( + vit_merger_window_size, std::vector(vit_merger_window_size)))); + for (int t = 0; t < grid_t; ++t) { + for (int wh = 0; wh < num_windows_h; ++wh) { + for (int ww = 0; ww < num_windows_w; ++ww) { + for (int h_in_win = 0; h_in_win < vit_merger_window_size; ++h_in_win) { + for (int w_in_win = 0; w_in_win < vit_merger_window_size; ++w_in_win) { + int original_h = wh * vit_merger_window_size + h_in_win; + int original_w = ww * vit_merger_window_size + w_in_win; + permuted_windows[t][wh * num_windows_w + ww][h_in_win][w_in_win] = index_padded[t][original_h][original_w]; + } + } + } + } + } + std::vector seqlens; + for (int t = 0; t < grid_t; ++t) { + for (int win_idx = 0; win_idx < num_windows_h * num_windows_w; ++win_idx) { + int count = 0; + for (int h = 0; h < vit_merger_window_size; ++h) { + for (int w = 0; w < vit_merger_window_size; ++w) { + if (permuted_windows[t][win_idx][h][w] != -100.0f) { + count++; + } + } + } + seqlens.push_back(static_cast(count)); + } + } + std::vector index_new; + for (int t = 0; t < grid_t; ++t) { + for (int win_idx = 0; win_idx < num_windows_h * num_windows_w; ++win_idx) { + for (int h = 0; h < vit_merger_window_size; ++h) { + for (int w = 0; w < vit_merger_window_size; ++w) { + float val = permuted_windows[t][win_idx][h][w]; + if (val != -100.0f) { + index_new.push_back(val); + } + } + } + } + } + for (float &val : index_new) { + val += window_index_id; + } + window_index_parts.push_back(index_new); + std::vector cu_seqlens_tmp(seqlens.size()); + if (!seqlens.empty()) { + cu_seqlens_tmp[0] = seqlens[0]; + for (size_t i = 1; i < seqlens.size(); ++i) { + cu_seqlens_tmp[i] = cu_seqlens_tmp[i - 1] + seqlens[i]; + } + } + for (float &val : cu_seqlens_tmp) { + val = val * spatial_merge_unit + cu_window_seqlens.back(); + } + cu_window_seqlens.insert(cu_window_seqlens.end(), cu_seqlens_tmp.begin(), cu_seqlens_tmp.end()); + window_index_id += total_elements; + } + std::vector final_window_index; + for (const auto &part : window_index_parts) { + final_window_index.insert(final_window_index.end(), part.begin(), part.end()); + } + // cu_window_seqlens去除重复元素 + cu_window_seqlens.erase(std::unique(cu_window_seqlens.begin(), cu_window_seqlens.end()), cu_window_seqlens.end()); + // 转为Tensor类型输出 + Tensor window_index_tensor(final_window_index, MLLM_CPU); + Tensor cu_window_seqlens_tensor(cu_window_seqlens, MLLM_CPU); + // window_index_tensor.setName("window_index"); + // cu_window_seqlens_tensor.setName("cu_window_seqlens"); + return {window_index_tensor, cu_window_seqlens_tensor}; + } +}; + +class QWen2MLP final : public Module { +public: + QWen2MLP() = default; + QWen2MLP(int hidden_size, int intermediate_size, const QWenNameConfig &names, + const std::string &base_name) { + gate_proj = Linear(hidden_size, intermediate_size, false, base_name + names._gate_proj_name); + silu = SiLU(base_name + "act"); + up_proj = Linear(hidden_size, intermediate_size, false, base_name + names._up_proj_name); + down_proj = + Linear(intermediate_size, hidden_size, false, base_name + names._down_proj_name); + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto x = gate_proj(inputs[0]); + x = silu(x); + auto y = up_proj(inputs[0]); + x = x * y; + x = down_proj(x); + return {x}; + } + +private: + Layer gate_proj; + Layer up_proj; + Layer down_proj; + Layer silu; +}; + +// Copied from GemmaAttention with Gemma->Qwen and using SWA +class QWen2Attention final : public Module { +public: + QWen2Attention() = default; + QWen2Attention(const Qwen2VLConfig &config, const QWenNameConfig &names, const string &base_name) { + hidden_size = config.hidden_size; + num_heads = config.num_attention_heads; + head_dim = config.hidden_size / num_heads; + num_key_value_heads = config.num_key_value_heads; + num_key_value_groups = num_heads / num_key_value_heads; + name = base_name; + attn_impl = config.attn_implementation; + + // init layers + q_proj = Linear(hidden_size, num_heads * head_dim, true, base_name + names._q_proj_name); + k_proj = Linear(hidden_size, num_key_value_heads * head_dim, true, + base_name + names._k_proj_name); + v_proj = Linear(hidden_size, num_key_value_heads * head_dim, true, + base_name + names._v_proj_name); + o_proj = Linear(num_heads * head_dim, hidden_size, false, base_name + names._o_proj_name); + q_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "q_rope"); + k_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "k_rope"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, config.attn_implementation, base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, config.attn_implementation, base_name + "v_cache"); + softmax = Softmax(DIMENSION, true, base_name + "softmax"); + } + + std::vector Forward(std::vector inputs, std::vector args) override { + auto position_ids = inputs[1]; + auto query_states = q_proj(inputs[0]); + auto key_states = k_proj(inputs[0]); + auto value_states = v_proj(inputs[0]); + query_states = query_states.view(-1, num_heads, -1, head_dim); + key_states = key_states.view(-1, num_key_value_heads, -1, head_dim); + value_states = value_states.view(-1, num_key_value_heads, -1, head_dim); + query_states = q_rope(query_states, position_ids); + key_states = k_rope(key_states, position_ids); + key_states = k_cache(key_states); + value_states = v_cache(value_states); + + Tensor atten_output; + if (attn_impl == "flash_attention_2") { + atten_output = Tensor::flash_attention2_forward(query_states, key_states, value_states, true); + } else if (attn_impl == "sage_attention") { + atten_output = Tensor::sage_attention_forward(query_states, key_states, value_states, true); + } else { // eager implementation + auto atten_weight = + Tensor::mm(query_states, key_states.transpose(Chl::SEQUENCE, Chl::DIMENSION)) + / std::sqrt(head_dim); + atten_weight = softmax(atten_weight, k_cache.getCacheSeqLen()); + atten_output = Tensor::mm(atten_weight, value_states); + } + atten_output = atten_output.view(-1, 1, -1, head_dim * num_heads); + atten_output = o_proj(atten_output); + return {atten_output}; + } + + vector get_cache() { + return {&k_cache, &v_cache}; + } + vector get_rope() { + return {&q_rope, &k_rope}; + } + +private: + int hidden_size; + int num_heads; + int head_dim; + int num_key_value_heads; + int num_key_value_groups; + Layer q_proj; + Layer k_proj; + Layer v_proj; + Layer o_proj; + MultimodalRoPE q_rope; + MultimodalRoPE k_rope; + KVCache k_cache; + KVCache v_cache; + Softmax softmax; + string name; + string attn_impl; +}; + +// Copied from GemmaDecoder with Gemma->Qwen and set RmsNorm(without add_unit_offset) +class QWen2Decoder final : public Module { +public: + QWen2Decoder() = default; + QWen2Decoder(const Qwen2VLConfig &config, const QWenNameConfig &names, const string &base_name) { + self_atten = QWen2Attention(config, names, base_name + names._attn_base_name); + mlp = QWen2MLP(config.hidden_size, config.intermediate_size, names, + base_name + names._ffn_base_name); + input_layernorm = + RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._attn_norm_name); + post_attention_layernorm = + RMSNorm(config.hidden_size, config.rms_norm_eps, base_name + names._ffn_norm_name); + } + std::vector Forward(std::vector inputs, std::vector args) override { + auto position_ids = inputs[1]; + auto x = input_layernorm(inputs[0]); + x = self_atten({x, position_ids})[0]; + auto tmp = x + inputs[0]; + x = post_attention_layernorm(tmp); + x = mlp({x})[0]; + x = x + tmp; + return {x}; + } + QWen2Attention &get_attention() { + return self_atten; + } + +private: + QWen2Attention self_atten; + QWen2MLP mlp; + Layer input_layernorm; + Layer post_attention_layernorm; +}; + +class Qwen2VLModel final : public Module { + Qwen2VisionModel visual; + Layer embed_tokens; + + vector blocks; + Layer norm; + Parameter lm_head; + Layer lm_head_layer; + + bool tie_embedding_words; + + int64_t spatial_merge_size; + int64_t image_token_id; + int64_t video_token_id; + int64_t vision_start_token_id; + +public: + explicit Qwen2VLModel(const Qwen2VLConfig &config) { + auto vocab_size = config.vocab_size; + auto hidden_dim = config.hidden_size; + auto head_size = config.num_attention_heads; + auto ffn_hidden = config.intermediate_size; + auto projection_cls = config.projection_cls; + auto vision_embed_dim = config.vision_embed_dim; + auto visiion_intermediate_size = config.visiion_intermediate_size; + image_token_id = config.image_token_id; + auto vision_names = config.vision_names_config; + auto qwen_names = config.names_config; + tie_embedding_words = config.tie_embedding_words; + image_token_id = config.image_token_id; + video_token_id = config.video_token_id; + vision_start_token_id = config.vision_start_token_id; + + embed_tokens = Embedding(vocab_size, hidden_dim, qwen_names.token_embd_name); + visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, visiion_intermediate_size, "SiLU", 14, 336, 32, config.attn_implementation, config, vision_names, vision_names.vison_model_name); + + blocks = List(config.num_hidden_layers, config, qwen_names, qwen_names.blk_name); + norm = RMSNorm(hidden_dim, 1e-6, qwen_names.post_norm_name); + if (tie_embedding_words) { + lm_head = Parameter(1, config.vocab_size, 1, config.hidden_size, qwen_names.token_embd_name + ".weight"); + } else { + lm_head_layer = Linear(config.hidden_size, config.vocab_size, false, qwen_names.lm_head_name); + } + } + vector Forward(vector inputs, vector args) override { + auto position_ids = inputs[3]; + bool have_img = inputs[1].batch() > 0; + auto hidden_states = embed_tokens({inputs[0]}); + if (have_img) { + auto image_embeds = visual({inputs[1], inputs[2]})[0]; + auto n_image_features = image_embeds.sequence(); + auto where_idx = inputs[0].where(image_token_id, SEQUENCE); + hidden_states = hidden_states.index_put(image_embeds, where_idx, false); + } + for (auto &block : blocks) { + hidden_states = block({hidden_states, position_ids})[0]; + } + hidden_states = norm(hidden_states); + if (hidden_states.sequence() > 1) { + hidden_states = hidden_states.clip({}, {}, {-1}, {}); + } + if (tie_embedding_words) { + hidden_states = Tensor::mm(hidden_states, lm_head().transpose(Chl::SEQUENCE, Chl::DIMENSION)); + } else { + hidden_states = lm_head_layer(hidden_states); + } + return {hidden_states}; + } + void clear_kvcache() override { + for (auto &block : blocks) { + auto kvcahce = block.get_attention().get_cache(); + for (auto &cache : kvcahce) { + cache->clearCache(); + } + } + } + void get_position_ids(vector &inputs) { + if (inputs[0].sequence() > 1) { + Tensor video_grid_thw(0, 0, 0, 0, MLLM_CPU, true); + auto rope_indices = get_rope_index(inputs[0], inputs[2], video_grid_thw); + auto position = rope_indices[0]; + if (inputs.size() == 4) { + inputs[3] = position; + } else { + inputs.push_back(position); + } + } else { + auto &position_ids = inputs[3]; + auto last_pos = position_ids.dataAt(0, 0, 0, position_ids.dimension() - 1); + position_ids.reshape(position_ids.batch(), 1, position_ids.sequence(), 1); + for (int b = 0; b < position_ids.batch(); b++) { + for (int s = 0; s < position_ids.sequence(); s++) { + position_ids.setDataAt(b, 0, s, 0, last_pos + 1); + } + } + } + } + +private: + vector get_rope_index( + Tensor input_ids, + Tensor image_grid_thw, + Tensor video_grid_thw) { + vector> attention_mask; + auto attention_mask_shape = input_ids.sequence(); + for (int b = 0; b < input_ids.batch(); b++) { + attention_mask.emplace_back(attention_mask_shape, 1); + } + const size_t batch_size = input_ids.batch(); // input_ids.size(); + const size_t seq_len = batch_size > 0 ? input_ids.sequence() : 0; // batch_size > 0 ? input_ids[0].size() : 0; + Tensor position_ids(3, 1, batch_size, seq_len, Backend::global_backends[MLLM_CPU].get(), true); + Tensor mrope_position_deltas(1, 1, 1, batch_size, Backend::global_backends[MLLM_CPU].get(), true); + bool has_vision = (image_grid_thw.sequence() > 0) || (video_grid_thw.sequence() > 0); // image_grid_thw || video_grid_thw; + if (!has_vision) { + // Pure text case + for (size_t i = 0; i < batch_size; ++i) { + const auto &mask = !attention_mask.empty() ? attention_mask[i] : vector(seq_len, 1); + vector positions; + int64_t pos = 0; + for (size_t j = 0; j < seq_len; ++j) { + if (mask[j] == 1) { + positions.push_back(pos++); + } else { + positions.push_back(1); // Will be overwritten by mask + } + } + for (int dim = 0; dim < 3; ++dim) { + for (size_t j = 0; j < seq_len; ++j) { + position_ids.setDataAt(dim, 0, i, j, (float)(mask[j] == 1 ? positions[j] : 1)); + } + } + int64_t max_pos = pos - 1; + mrope_position_deltas.setDataAt(0, 0, 0, i, (float)((max_pos + 1) - static_cast(input_ids.sequence()))); + } + position_ids.setName("position_ids"); + mrope_position_deltas.setName("mrope_position_deltas"); + return {position_ids, mrope_position_deltas}; + } + // Process vision cases + size_t image_idx = 0, video_idx = 0; + for (size_t i = 0; i < batch_size; ++i) { + const auto &mask = !attention_mask.empty() ? attention_mask[i] : vector(seq_len, 1); + // Extract valid tokens + vector valid_tokens; + for (size_t j = 0; j < input_ids.sequence(); ++j) { + if (mask[j] == 1) valid_tokens.push_back((int)input_ids.dataAt(i, 0, j, 0)); + } + // Find vision start positions + vector vision_starts; + vector vision_types; + for (size_t j = 0; j < valid_tokens.size(); ++j) { + if (valid_tokens[j] == vision_start_token_id && j + 1 < valid_tokens.size()) { + vision_starts.push_back(j); + vision_types.push_back(valid_tokens[j + 1]); + } + } + int64_t image_count = count(vision_types.begin(), vision_types.end(), image_token_id); + int64_t video_count = vision_types.size() - image_count; + vector> llm_positions(3); + size_t st = 0; + int64_t current_max = 0; + int64_t remain_images = image_count; + int64_t remain_videos = video_count; + // Process each vision segment + for (size_t vs = 0; vs < vision_starts.size(); ++vs) { + // Find next vision token + size_t ed_image = valid_tokens.size(); + size_t ed_video = valid_tokens.size(); + if (remain_images > 0) { + auto it = find(valid_tokens.begin() + st, valid_tokens.end(), image_token_id); + if (it != valid_tokens.end()) ed_image = it - valid_tokens.begin(); + } + if (remain_videos > 0) { + auto it = find(valid_tokens.begin() + st, valid_tokens.end(), video_token_id); + if (it != valid_tokens.end()) ed_video = it - valid_tokens.begin(); + } + size_t ed = min(ed_image, ed_video); + if (ed == valid_tokens.size()) break; + // Get grid parameters + int64_t t, h, w; + bool is_image = (ed == ed_image); + if (is_image) { + t = (int64_t)image_grid_thw.dataAt(0, 0, image_idx, 0); + h = (int64_t)image_grid_thw.dataAt(0, 0, image_idx, 1); + w = (int64_t)image_grid_thw.dataAt(0, 0, image_idx, 2); + image_idx++; + remain_images--; + } else { + t = (int64_t)video_grid_thw.dataAt(0, 0, video_idx, 0); + h = (int64_t)video_grid_thw.dataAt(0, 0, video_idx, 1); + w = (int64_t)video_grid_thw.dataAt(0, 0, video_idx, 2); + video_idx++; + remain_videos--; + } + // Calculate grid dimensions + int64_t llm_grid_t = t; + int64_t llm_grid_h = h / spatial_merge_size; + int64_t llm_grid_w = w / spatial_merge_size; + // Process text segment + size_t text_len = ed - st; + if (text_len > 0) { + int64_t start_idx = current_max; + for (int64_t k = 0; k < text_len; ++k) { + for (int dim = 0; dim < 3; ++dim) { + llm_positions[dim].push_back(start_idx + k); + } + } + current_max += text_len; + } + for (int64_t ti = 0; ti < llm_grid_t; ++ti) { + for (int64_t hi = 0; hi < llm_grid_h; ++hi) { + for (int64_t wi = 0; wi < llm_grid_w; ++wi) { + llm_positions[0].push_back(current_max + ti); + llm_positions[1].push_back(current_max + hi); + llm_positions[2].push_back(current_max + wi); + } + } + } + current_max = std::max({llm_positions[0][llm_positions[0].size() - 1], + llm_positions[1][llm_positions[1].size() - 1], + llm_positions[2][llm_positions[2].size() - 1]}); + st = ed + llm_grid_t * llm_grid_h * llm_grid_w; + } + // Process remaining text + if (st < valid_tokens.size()) { + size_t text_len = valid_tokens.size() - st; + int64_t st_idx = current_max + 1; + for (int64_t k = 0; k < text_len; ++k) { + for (int dim = 0; dim < 3; ++dim) { + llm_positions[dim].push_back(st_idx + k); + } + } + current_max += text_len; + } + // Fill position_ids with valid positions + size_t valid_idx = 0; + for (size_t j = 0; j < seq_len; ++j) { + if (mask[j] == 1) { + if (valid_idx < llm_positions[0].size()) { + position_ids.setDataAt(0, 0, i, j, (float)llm_positions[0][valid_idx]); + position_ids.setDataAt(1, 0, i, j, (float)llm_positions[1][valid_idx]); + position_ids.setDataAt(2, 0, i, j, (float)llm_positions[2][valid_idx]); + valid_idx++; + } + } + } + // Calculate delta + int64_t max_pos = 0; + for (const auto &dim : llm_positions) { + for (auto val : dim) { + max_pos = max(max_pos, val); + } + } + mrope_position_deltas.setDataAt(0, 0, 0, i, (float)((max_pos + 1) - static_cast(input_ids.sequence()))); + } + position_ids.setName("position_ids"); + mrope_position_deltas.setName("mrope_position_deltas"); + return {position_ids, mrope_position_deltas}; + } +}; +#endif // MODELING_QWEN2VL_HPP \ No newline at end of file diff --git a/tools/quantizer/QuantWriter.cpp b/tools/quantizer/QuantWriter.cpp index ffea80a3d..de7e53a45 100644 --- a/tools/quantizer/QuantWriter.cpp +++ b/tools/quantizer/QuantWriter.cpp @@ -121,6 +121,15 @@ std::vector QuantWriter::load_full_fp32_param(const std::string &name) { } DataType QuantWriter::getQuantizationTypeFor(const std::string &name, DataType target_type, const std::string &other_flag) { + /* + if (name.find("down_proj") != std::string::npos && name.find("visual.blocks") != std::string::npos + && name.find("bias") == std::string::npos) { + return MLLM_TYPE_F32; + } + if (name.find("qkv") != std::string::npos && name.find("bias") == std::string::npos) { + return MLLM_TYPE_Q4_K; + } + */ if (find_in_layers(name, q40_layers)) { return MLLM_TYPE_Q4_0; } From b30be26f5d3f067178bc128c8a91519f0f2000af Mon Sep 17 00:00:00 2001 From: yirongjie Date: Sun, 14 Sep 2025 15:28:37 +0800 Subject: [PATCH 18/22] fix: vison token purning && qwen2-vl's config --- .gitignore | 2 + examples/demo_qwen2_vl_vtp.cpp | 9 ++- src/backends/cpu/compute/GemmKleidiai.cpp | 70 +++++++++++++++++-- src/backends/cpu/compute/GemmKleidiai.hpp | 8 +++ src/backends/cpu/op/CPULinear.cpp | 61 ++++++++++++---- src/models/qwen/configuration_qwen.hpp | 2 +- src/models/qwen2_5_vl/modeling_qwen2_5_vl.hpp | 1 - src/models/qwen2_vl/modeling_qwen2_vl.hpp | 6 +- src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp | 31 ++++---- src/models/qwen2_vl/vtp/ndc_tools.hpp | 5 +- tools/convertor/converter.py | 54 ++++++++++---- 11 files changed, 195 insertions(+), 54 deletions(-) diff --git a/.gitignore b/.gitignore index a915cc77c..33fdaad42 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,5 @@ examples/test.cpp examples/demo_bailing_moe2* src/models/ling2 scripts/tmp.sh +tools/convertor/gptq_converter.py +*.patch diff --git a/examples/demo_qwen2_vl_vtp.cpp b/examples/demo_qwen2_vl_vtp.cpp index 10875f6ce..40bd82ade 100644 --- a/examples/demo_qwen2_vl_vtp.cpp +++ b/examples/demo_qwen2_vl_vtp.cpp @@ -10,11 +10,12 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen2vl_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen2vl_merges.txt"); - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-q4_k.mllm"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-2-vl-2b-instruct-kai_q4_0.mllm"); cmdParser.add("billion", 'b', "[2B | 7B |]", false, "2B"); cmdParser.add("limits", 'l', "max KV cache size", false, 800); cmdParser.add("thread", 't', "num of threads", false, 4); - cmdParser.add("premerge", 'p', "enable pre-ViT image token merging"); + cmdParser.add("premerge", 'g', "enable pre-ViT image token merging", false, false); + cmdParser.add("pruning", 'p', "enable pruning", false, false); cmdParser.parse_check(argc, argv); string vocab_path = cmdParser.get("vocab"); @@ -25,6 +26,10 @@ int main(int argc, char **argv) { int thread_num = cmdParser.get("thread"); CPUBackend::cpu_threads = cmdParser.get("thread"); use_pre_vit_merge = cmdParser.exist("premerge"); + bool use_pruning = cmdParser.exist("pruning"); + if (!use_pruning) { + WHERE_TOKEN_PRUNING.pruning_place_cfg = {}; + } ParamLoader param_loader(model_path); auto processor = Qwen2VLProcessor(vocab_path, merge_path); diff --git a/src/backends/cpu/compute/GemmKleidiai.cpp b/src/backends/cpu/compute/GemmKleidiai.cpp index 9b0d2ec8a..d83ac8c5c 100644 --- a/src/backends/cpu/compute/GemmKleidiai.cpp +++ b/src/backends/cpu/compute/GemmKleidiai.cpp @@ -3,6 +3,7 @@ #include "GemmKleidiai.hpp" #include "FeatureCheck.hpp" +#include #include #include #include @@ -235,20 +236,16 @@ void mllm_kleidai_pack_b_and_bias_qsi4( for (int n = 0; n < N; ++n) { for (size_t kb = 0; kb < num_blocks_k; ++kb) { float amax = 0.0f; - float max_with_sign = 0.0f; int start_k = kb * block_len; int end_k = std::min(start_k + block_len, K); for (int k = start_k; k < end_k; ++k) { const float val = b_ptr[k * N + n]; const float abs_val = std::abs(val); - if (abs_val > amax) { - amax = abs_val; - max_with_sign = val; - } + amax = std::max(abs_val, amax); } - const float scale = max_with_sign / -8.0f; + const float scale = amax / 7.0f; const float inv_scale = scale != 0.0f ? 1.0f / scale : 0.0f; - temp_scales[n * num_blocks_k + kb] = kai_cast_bf16_f32(scale); + temp_scales[(n * num_blocks_k) + kb] = kai_cast_bf16_f32(scale); for (int k = start_k; k < end_k; ++k) { const float val = b_ptr[k * N + n]; int32_t q_val = static_cast(round(val * inv_scale)); @@ -272,6 +269,65 @@ void mllm_kleidai_pack_b_and_bias_qsi4( temp_quantized_b.data(), N / 2, bias_to_use, (const uint8_t *)temp_scales.data(), num_blocks_k * sizeof(uint16_t), packed_b_ptr, 0, ¶ms); } +/** + * @brief Packs pre-quantized 4-bit weights, scales, and bias into the format required by the QSI4 GEMM kernel. + * + * This function takes weights that are already quantized to 4-bit values (represented as uint8_t in the range [0, 15]), + * their corresponding floating-point scales, and an optional bias vector. It then transforms and packs this data + * into a single buffer (`packed_b_ptr`) for efficient use in `mllm_kleidai_gemm_qsi4`. + * + * @param packed_b_ptr [out] Pointer to the destination buffer for the packed data. + * @param b_qweight_ptr [in] Pointer to the pre-quantized 4-bit weights. Assumed layout is KxN row-major, with each uint8_t holding one 4-bit value. + * @param b_scale_ptr [in] Pointer to the quantization scales. Assumed layout is Nx(K/32) row-major. +// * @param b_zero_ptr [in] Pointer to the quantization zero points. This parameter is currently IGNORED because the underlying kernel supports only a single, symmetric zero point, which is hardcoded to 8. + * @param bias_ptr [in] Pointer to the bias vector of size N. Can be nullptr if no bias is to be added. + * @param N The N dimension of the weight matrix (number of columns/output channels). + * @param K The K dimension of the weight matrix (number of rows/input channels). + */ +void mllm_kleidai_pack_b_and_bias_qsi4_quant( + uint8_t *packed_b_ptr, + const uint8_t *b_qweight_ptr, + const float *b_scale_ptr, + // const uint8_t *b_zero_ptr, + const float *bias_ptr, + int N, + int K) { + const auto tile_cfg = kleidiai_get_best_qsi4_tile_config(); + const auto &ukernel = qsi4_ukernels.at(tile_cfg); + const float *bias_to_use = bias_ptr; + std::vector fake_bias; + if (bias_to_use == nullptr) { + fake_bias.assign(N, 0.0f); + bias_to_use = fake_bias.data(); + } + const int block_len = 32; // Corresponds to the 'c32p' part of the qsi4c32p scheme. + const size_t num_blocks_k = (K + block_len - 1) / block_len; + std::vector temp_quantized_b(K * N / 2); + std::vector temp_scales(N * num_blocks_k); +#pragma omp parallel for + for (size_t i = 0; i < N * num_blocks_k; ++i) { + temp_scales[i] = kai_cast_bf16_f32(b_scale_ptr[i]); + } +#pragma omp parallel for + for (int k = 0; k < K; ++k) { + for (int n = 0; n < N; n += 2) { + size_t byte_idx = (size_t)k * (N / 2) + (n / 2); + uint8_t val1 = b_qweight_ptr[(size_t)k * N + n]; + uint8_t val2 = b_qweight_ptr[(size_t)k * N + n + 1]; + temp_quantized_b[byte_idx] = val1 | (val2 << 4); + } + } + kai_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0_params params = {}; + params.lhs_zero_point = 1; + params.rhs_zero_point = 8; + params.scale_dt = kai_dt_bf16; + kai_run_rhs_pack_kxn_qsi4c32p_qsu4c32s1s0( + 1, N, K, ukernel.get_nr(), ukernel.get_kr(), ukernel.get_sr(), block_len, + temp_quantized_b.data(), N / 2, + bias_to_use, + (const uint8_t *)temp_scales.data(), num_blocks_k * sizeof(uint16_t), + packed_b_ptr, 0, ¶ms); +} #ifndef KAI_FP16_CAL void mllm_kleidai_gemm_qsi4( diff --git a/src/backends/cpu/compute/GemmKleidiai.hpp b/src/backends/cpu/compute/GemmKleidiai.hpp index dbdf18962..f844629eb 100644 --- a/src/backends/cpu/compute/GemmKleidiai.hpp +++ b/src/backends/cpu/compute/GemmKleidiai.hpp @@ -12,6 +12,14 @@ static int kai_thread_count = 4; // --- 实现 1: float * qsi4c32 -> float--- size_t mllm_kleidai_get_packed_b_qsi4_size(int N, int K); void mllm_kleidai_pack_b_and_bias_qsi4(uint8_t *packed_b_ptr, const float *b_ptr, const float *bias_ptr, int N, int K); +void mllm_kleidai_pack_b_and_bias_qsi4_quant( + uint8_t *packed_b_ptr, + const uint8_t *b_qweight_ptr, + const float *b_scale_ptr, + // const uint8_t *b_zero_ptr, + const float *bias_ptr, + int N, + int K); void mllm_kleidai_gemm_qsi4(float *c_ptr, const float *a_ptr, const uint8_t *packed_b_ptr, int M, int N, int K); // --- 实现 1.5: float * qsi4c32 -> fp16--- diff --git a/src/backends/cpu/op/CPULinear.cpp b/src/backends/cpu/op/CPULinear.cpp index 356fd2356..bfa573f42 100644 --- a/src/backends/cpu/op/CPULinear.cpp +++ b/src/backends/cpu/op/CPULinear.cpp @@ -3,6 +3,7 @@ #include "Types.hpp" #include #include +#include #include "../compute/GemmKleidiai.hpp" #include "backends/cpu/third_party/ggml/QuantizeQ8.hpp" @@ -171,18 +172,53 @@ ErrorCode CPULinear::execute(vector> inputs, vectorbatch(); b++) { - auto M = inputs[0]->sequence(); - auto N = outputs[0]->dimension(); // out_features_ - auto K = inputs[0]->dimension(); // in_features_ - if (outputs[0]->dtype() == MLLM_TYPE_F16) { - mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(b, 0, 0, 0), - inputs[0]->ptrAt(b, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); - } else { - mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(b, 0, 0, 0), - inputs[0]->ptrAt(b, 0, 0, 0), - (const uint8_t *)weight_.rawHostPtr(), M, N, K); + if (outputs[0]->ctype() == BHDS) { //&& outputs[0]->masterTensor() != nullptr && outputs[0]->masterTensor()->ctype() == BHDS) { + for (int b = 0; b < inputs[0]->batch(); b++) { + auto M = inputs[0]->sequence(); + auto N = outputs[0]->dimension(); // out_features_ + auto K = inputs[0]->dimension(); // in_features_ + if (outputs[0]->dtype() == MLLM_TYPE_F16) { + // auto out_ptr = outputs[0]->ptrAt(b, 0, 0, 0); + vector out_vec(M * N); + auto out_ptr = out_vec.data(); + mllm_kleidai_gemm_qsi4_to_fp16(out_ptr, + inputs[0]->ptrAt(b, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); +#pragma omp parallel for num_threads(thread_count) + for (int s = 0; s < M; s++) { + for (int d = 0; d < N; d++) { + outputs[0]->setDataAt(b, 0, s, d, out_ptr[s * N + d]); + } + } + } else { + // auto out_ptr = outputs[0]->ptrAt(b, 0, 0, 0); + vector out_vec(M * N); + auto out_ptr = out_vec.data(); + mllm_kleidai_gemm_qsi4(out_ptr, + inputs[0]->ptrAt(b, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); +#pragma omp parallel for num_threads(thread_count) + for (int s = 0; s < M; s++) { + for (int d = 0; d < N; d++) { + outputs[0]->setDataAt(b, 0, s, d, out_ptr[s * N + d]); + } + } + } + } + } else { + for (int b = 0; b < inputs[0]->batch(); b++) { + auto M = inputs[0]->sequence(); + auto N = outputs[0]->dimension(); // out_features_ + auto K = inputs[0]->dimension(); // in_features_ + if (outputs[0]->dtype() == MLLM_TYPE_F16) { + mllm_kleidai_gemm_qsi4_to_fp16(outputs[0]->ptrAt(b, 0, 0, 0), + inputs[0]->ptrAt(b, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } else { + mllm_kleidai_gemm_qsi4(outputs[0]->ptrAt(b, 0, 0, 0), + inputs[0]->ptrAt(b, 0, 0, 0), + (const uint8_t *)weight_.rawHostPtr(), M, N, K); + } } } return MLLM_NO_ERROR; @@ -192,7 +228,6 @@ ErrorCode CPULinear::execute(vector> inputs, vector(); q = Tensor::apply_rotary_pos_emb_vision(q, rotary_pos_emb); k = Tensor::apply_rotary_pos_emb_vision(k, rotary_pos_emb); Tensor o; diff --git a/src/models/qwen2_vl/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/modeling_qwen2_vl.hpp index 9d5b382df..0676dea6b 100644 --- a/src/models/qwen2_vl/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/modeling_qwen2_vl.hpp @@ -4,6 +4,7 @@ #ifndef MODELING_QWEN2VL_HPP #define MODELING_QWEN2VL_HPP +#include "DataType.hpp" #include "Layer.hpp" #include "Module.hpp" #include "Tensor.hpp" @@ -11,6 +12,7 @@ #include "configuration_qwen2_vl.hpp" // #include "models/qwen/modeling_qwen.hpp" #include +#include #include #include @@ -237,8 +239,8 @@ class QWen2Attention final : public Module { o_proj = Linear(num_heads * head_dim, hidden_size, false, base_name + names._o_proj_name); q_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "q_rope"); k_rope = MultimodalRoPE(config.rope_theta, config.max_position_embeddings, config.mrope_section, base_name + "k_rope"); - k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, config.attn_implementation, base_name + "k_cache"); - v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, config.attn_implementation, base_name + "v_cache"); + k_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, attn_impl, base_name + "k_cache"); + v_cache = KVCache(num_key_value_heads, head_dim, num_key_value_groups, config.cache_limit, attn_impl, base_name + "v_cache"); softmax = Softmax(DIMENSION, true, base_name + "softmax"); } diff --git a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp index e65c5601d..b6444a22e 100644 --- a/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp +++ b/src/models/qwen2_vl/vtp/modeling_qwen2_vl.hpp @@ -48,14 +48,16 @@ class VisionAttention final : public Module { int head_size_{}; int kv_head_size_{}; int head_dim_{}; + string attn_impl; public: VisionAttention() = default; - VisionAttention(int hidden_dim, int head_size, int kv_head_size, int head_dim, bool bias, + VisionAttention(int hidden_dim, int head_size, int kv_head_size, int head_dim, bool bias, string attn_implementation, const TransformerNameConfig &names, const string &base_name) { head_dim_ = head_dim; head_size_ = head_size; kv_head_size_ = kv_head_size; + attn_impl = attn_implementation; qkv_proj = Linear(hidden_dim, head_size * head_dim * 3, bias, base_name + names._qkv_proj_name); softmax = Softmax(DIMENSION, false, base_name + "softmax"); @@ -76,12 +78,17 @@ class VisionAttention final : public Module { v = v.view(-1, head_size_, -1, head_dim_); q = Tensor::apply_rotary_pos_emb_vision(q, rotary_pos_emb); k = Tensor::apply_rotary_pos_emb_vision(k, rotary_pos_emb); - k = k.transpose(SEQUENCE, DIMENSION); - auto qk = Tensor::mm(q, k); - qk = qk / std::sqrt(head_dim_); - // mask - qk = softmax(qk); - auto o = Tensor::mm(qk, v); + Tensor o; + if (attn_impl == "flash_attention_2") { + o = Tensor::flash_attention2_forward(q, k, v, false); + } else { // eager implementation + k = k.transpose(SEQUENCE, DIMENSION); + auto qk = Tensor::mm(q, k); + qk = qk / std::sqrt(head_dim_); + // mask + qk = softmax(qk); + o = Tensor::mm(qk, v); + } o = o.view(-1, 1, -1, head_dim_ * head_size_); o = o_proj(o); return {o}; @@ -116,8 +123,8 @@ class VisionBlock final : public Module { public: VisionBlock() = default; - VisionBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, const ViTNameConfig &names, const string &base_name) { - attention = VisionAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, true, names, base_name + names._attn_base_name); + VisionBlock(int hidden_dim, int head_size, int ffn_hidden, const string &act_fn_type, string attn_implementation, const ViTNameConfig &names, const string &base_name) { + attention = VisionAttention(hidden_dim, head_size, head_size, hidden_dim / head_size, true, attn_implementation, names, base_name + names._attn_base_name); mlp = VisionMLP(hidden_dim, ffn_hidden, act_fn_type, names, base_name + names._ffn_base_name); norm1 = LayerNorm(hidden_dim, true, 1e-6, base_name + names._attn_norm_name); norm2 = LayerNorm(hidden_dim, true, 1e-6, base_name + names._ffn_norm_name); @@ -167,10 +174,10 @@ class Qwen2VisionModel final : public Module { public: Qwen2VisionModel() = default; - Qwen2VisionModel(int hidden_dim, int vision_embed_dim, int head_size, int mlp_hidden_dim, const string &act_fn_type, int patch, int img_hw, int block_num, int spatial_merge_size, const Qwen2VLNameConfig &names, const string &base_name) { + Qwen2VisionModel(int hidden_dim, int vision_embed_dim, int head_size, int mlp_hidden_dim, const string &act_fn_type, int patch, int img_hw, int block_num, int spatial_merge_size, string attn_implementation, const Qwen2VLNameConfig &names, const string &base_name) { patch_embed = Qwen2PatchEmbed(vision_embed_dim, patch, img_hw, names, base_name + names.patch_embed_name); rot_pos_emb = VisionRoPE((vision_embed_dim / head_size) / 2, spatial_merge_size, base_name + ".rot_pos_emb"); - blocks = List(block_num, vision_embed_dim, head_size, mlp_hidden_dim, act_fn_type, names, base_name + names._layer_name); + blocks = List(block_num, vision_embed_dim, head_size, mlp_hidden_dim, act_fn_type, attn_implementation, names, base_name + names._layer_name); patch_merger = PatchMerger(hidden_dim, vision_embed_dim, spatial_merge_size, names, base_name + names._merger_name); } vector Forward(vector inputs, vector args) override { @@ -419,7 +426,7 @@ class Qwen2VLModel final : public Module { vision_start_token_id = config.vision_start_token_id; embed_tokens = Embedding(vocab_size, hidden_dim, qwen_names.token_embd_name); - visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, vision_embed_dim * 4, "QuickGELU", 14, 336, 32, spatial_merge_size, vision_names, vision_names.vison_model_name); + visual = Qwen2VisionModel(hidden_dim, vision_embed_dim, 16, vision_embed_dim * 4, "QuickGELU", 14, 336, 32, spatial_merge_size, config.attn_implementation, vision_names, vision_names.vison_model_name); blocks = List(config.num_hidden_layers, config, qwen_names, qwen_names.blk_name); norm = RMSNorm(hidden_dim, 1e-6, qwen_names.post_norm_name); diff --git a/src/models/qwen2_vl/vtp/ndc_tools.hpp b/src/models/qwen2_vl/vtp/ndc_tools.hpp index 0463c63ae..aa8d8bc1c 100644 --- a/src/models/qwen2_vl/vtp/ndc_tools.hpp +++ b/src/models/qwen2_vl/vtp/ndc_tools.hpp @@ -191,9 +191,12 @@ class NdcContext { int num_head = 0; int original_kv_length = 0; int chunk_size = 4; + +public: // map pruning_place_cfg = {{3, 0.2}, {9, 0.2}, {12, 0.6}, {15, 0.6}, {18, 0.8}, {26, 0.8}}; // map pruning_place_cfg = {{3, 0.2}, {6, 0.8}, {12, 0.8}, {15, 0.8}, {18, 0.8}, {26, 0.8}}; - map pruning_place_cfg = {{3, 0.2}, {6, 0.2}, {12, 0.8}, {15, 0.8}, {18, 0.8}, {26, 0.8}}; + // map pruning_place_cfg = {{3, 0.8}, {6, 0.8}, {12, 0.8}, {15, 0.8}, {18, 0.8}, {26, 0.8}}; + map pruning_place_cfg = {{6, 0.8}, {12, 0.8}, {18, 0.8}}; // map pruning_place_cfg = {{3, 0.2}, {9, 0.2}}; public: diff --git a/tools/convertor/converter.py b/tools/convertor/converter.py index 7cc2e3b10..5e8427b77 100644 --- a/tools/convertor/converter.py +++ b/tools/convertor/converter.py @@ -45,6 +45,8 @@ def __torch_dtype_to_int(self, dtype: torch.dtype) -> int: return 1 elif dtype == torch.int8 or dtype == torch.bool: return 16 + elif dtype == torch.uint8: + return 31 elif dtype == torch.int32: return 18 else: @@ -69,8 +71,10 @@ def write_tensor(self, tensor: torch.Tensor, name: str) -> [int, int]: offset = self.writer.tell() if tensor.dtype == torch.bfloat16: # to float 16 tensor_numpy = tensor.detach().to(torch.float32).numpy() - elif tensor.dtype == torch.bool or tensor.dtype == torch.int8: # exported model for QNN int8 + elif tensor.dtype == torch.bool or tensor.dtype == torch.int8: tensor_numpy = tensor.detach().to(torch.int8).numpy() + elif tensor.dtype == torch.uint8: + tensor_numpy = tensor.detach().to(torch.uint8).numpy() else: # print(f"Write tensor {name} with dtype {tensor.dtype}") tensor_numpy = tensor.detach().to(torch.float32).numpy() @@ -81,7 +85,7 @@ def write_tensor(self, tensor: torch.Tensor, name: str) -> [int, int]: return offset, size def write_tensor_index( - self, + self, ): self.writer.seek(4 + 8) for tensor_name in self.tensors_name: @@ -95,7 +99,9 @@ def write_tensor_index( self.write_u64(tensor.size) self.write_u64(tensor.offset) self.write_int(tensor.dtype) - print(f"Write tensor {tensor.name} to {tensor.offset} with size {tensor.size}") + print( + f"Write tensor {tensor.name} to {tensor.offset} with size {tensor.size}" + ) def write_tensor_index_padding(self, tensors_name: [str]): if len(tensors_name) > 0: @@ -117,7 +123,11 @@ def close(self): def get_tensor(model: dict, key: str, index_: dict): - if index_ is not None and isinstance(index_, dict) and "weight_map" in index_.keys(): + if ( + index_ is not None + and isinstance(index_, dict) + and "weight_map" in index_.keys() + ): if key in index_["weight_map"].keys(): model_ = file_map[index_["weight_map"][key]] if args.type == "torch": @@ -138,9 +148,13 @@ def get_tensor(model: dict, key: str, index_: dict): def all_keys(model: dict, index_: dict): global file_map all_keys_name = [] - if index_ is not None and isinstance(index_, dict) and "weight_map" in index_.keys(): + if ( + index_ is not None + and isinstance(index_, dict) + and "weight_map" in index_.keys() + ): json_pwd = os.path.dirname(args.input_model.name) - for (key, val) in index_["weight_map"].items(): + for key, val in index_["weight_map"].items(): all_keys_name.append(key) if val is not None and val not in file_map.keys(): # JOIN PATH @@ -166,16 +180,17 @@ def all_keys(model: dict, index_: dict): return all_keys_name -def process_str(name: str, type: str='dense'): - if type == 'dense' or ('down_proj.weight' not in name): +def process_str(name: str, type: str = "dense"): + if type == "dense" or ("down_proj.weight" not in name): return name - return name.replace('weight', 'weight_T') + return name.replace("weight", "weight_T") -def process(name: str, ten: torch.Tensor, type: str='dense'): - if type == 'dense' or ('down_proj.weight' not in name): + +def process(name: str, ten: torch.Tensor, type: str = "dense"): + if type == "dense" or ("down_proj.weight" not in name): return name, ten - new_name = name.replace('weight', 'weight_T') + new_name = name.replace("weight", "weight_T") transposed_tensor = ten.transpose(-2, -1).contiguous() return new_name, transposed_tensor @@ -202,7 +217,10 @@ def process(name: str, ten: torch.Tensor, type: str='dense'): args = parser.parse_args() if args.type == "torch": if args.input_model.name.endswith(".json"): - if os.path.basename(args.input_model.name) != "pytorch_model.bin.index.json": + if ( + os.path.basename(args.input_model.name) + != "pytorch_model.bin.index.json" + ): raise Exception("Only support pytorch_model.bin.index.json") index_ = json.load(args.input_model) else: @@ -224,12 +242,18 @@ def process(name: str, ten: torch.Tensor, type: str='dense'): raise Exception("Unknown type") writer = Writer(args.output_model) model_keys = all_keys(model, index_) - writer.write_tensor_index_padding([process_str(name, args.model_type) for name in model_keys]) + writer.write_tensor_index_padding( + [process_str(name, args.model_type) for name in model_keys] + ) for key in model_keys: tensor = get_tensor(model, key, index_) key, tensor = process(key, tensor, args.model_type) - if tensor.dtype != torch.bool or tensor.dtype != torch.int8: + if ( + tensor.dtype != torch.bool + or tensor.dtype != torch.int8 + or tensor.dtype != torch.uint8 + ): tensor = tensor.float() offset, size = writer.write_tensor(tensor, key) print(f"Get tensor {key} to {offset} with size {size}") From 2c46281f16ce3228c799043cb2a9f9ce871dd0dd Mon Sep 17 00:00:00 2001 From: yirongjie Date: Sat, 11 Oct 2025 11:10:55 +0800 Subject: [PATCH 19/22] fix: qwen3 kai_quant --- examples/demo_qwen3.cpp | 6 ++++-- tools/quantizer/QuantWriter.cpp | 9 +++++++-- tools/quantizer/main_quantize.cpp | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/examples/demo_qwen3.cpp b/examples/demo_qwen3.cpp index 6a93e6d36..009dceb00 100644 --- a/examples/demo_qwen3.cpp +++ b/examples/demo_qwen3.cpp @@ -20,8 +20,8 @@ int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/qwen_vocab.mllm"); cmdParser.add("merge", 'e', "specify mllm merge file path", false, "../vocab/qwen_merges.txt"); - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-3-0.6b-q4_k.mllm"); - cmdParser.add("billion", 'b', "[0.6B | 4B |]", false, "0.6B"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/qwen-3-0.6b-kai_q4_0.mllm"); + cmdParser.add("billion", 'b', "[0.6B | 4B |]", false, "0.6b-lm"); cmdParser.add("limits", 'l', "max KV cache size", false, 800); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); @@ -67,5 +67,7 @@ int main(int argc, char **argv) { return true; }); std::cout << "\n"; + model.clear_kvcache(); + model.profiling(); } } diff --git a/tools/quantizer/QuantWriter.cpp b/tools/quantizer/QuantWriter.cpp index de7e53a45..30ed8d019 100644 --- a/tools/quantizer/QuantWriter.cpp +++ b/tools/quantizer/QuantWriter.cpp @@ -168,6 +168,7 @@ void QuantWriter::quantize(DataType target_quant_type, const std::string &other_ int tmp_hidden_dim = -1; int vit_tmp_hidden_dim = -1; + int qw3_hidden_dim = 2048; // 预扫描以找到隐藏维度 std::cout << "Pre-scanning to find hidden dimensions..." << std::endl; @@ -226,6 +227,10 @@ void QuantWriter::quantize(DataType target_quant_type, const std::string &other_ if (final_quant_type == MLLM_TYPE_KLEIDIAI_Q4_0) { #if defined(__aarch64__) || defined(__arm__) || defined(__arm64__) int H = find_in_layers(name, {"visual"}) ? vit_tmp_hidden_dim : tmp_hidden_dim; + if (find_in_layers(name, {"self_attn.o_proj.weight"}) && other_flag == "qw3") { + H = qw3_hidden_dim; + std::cout << "(QWen3 self_attn.o_proj.weight detected, using hidden dim: " << H << ") "; + } if (H <= 0) { std::cout << "FAIL! Hidden dimension not found for " << name << std::endl; __exit(-1); @@ -237,14 +242,14 @@ void QuantWriter::quantize(DataType target_quant_type, const std::string &other_ if (find_in_layers(name, {"w2", "down_proj", "down", "fc2"})) { N = H; if (num_floats % N != 0) { - std::cerr << "FAIL! num_floats not divisible by N for " << name << std::endl; + std::cerr << "FAIL! num_floats " << num_floats << " not divisible by N for " << name << std::endl; __exit(-1); } K = num_floats / N; } else { K = H; if (num_floats % K != 0) { - std::cerr << "FAIL! num_floats not divisible by K for " << name << std::endl; + std::cerr << "FAIL! num_floats " << num_floats << " not divisible by K for " << name << std::endl; __exit(-1); } N = num_floats / K; diff --git a/tools/quantizer/main_quantize.cpp b/tools/quantizer/main_quantize.cpp index 3911233c8..0f5134fca 100644 --- a/tools/quantizer/main_quantize.cpp +++ b/tools/quantizer/main_quantize.cpp @@ -23,8 +23,8 @@ int main(int argc, char **argv) { std::string other_flag = ""; if (argc == 5) { other_flag = std::string(argv[4]); - if (other_flag != "vl" && other_flag != "eager") { - std::cout << "Invalid other_flag. Use 'vl' or 'eager'.\n"; + if (other_flag != "vl" && other_flag != "eager" && other_flag != "qw3") { + std::cout << "Invalid other_flag. Use 'vl' or 'eager' or 'qw3'.\n"; return -1; } } From bb1f5c20f6e3bd78a2639ac4960b753ca387037f Mon Sep 17 00:00:00 2001 From: yirongjie Date: Sat, 11 Oct 2025 12:21:50 +0800 Subject: [PATCH 20/22] fix: llama3.2-kai --- examples/demo_llama3.cpp | 4 ++-- src/models/llama3/configuration_llama3.hpp | 17 ++++++++++++++ src/models/llama3/modeling_llama3.hpp | 26 +++++++++++++++++----- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/examples/demo_llama3.cpp b/examples/demo_llama3.cpp index 005f6c777..c7957e43e 100644 --- a/examples/demo_llama3.cpp +++ b/examples/demo_llama3.cpp @@ -13,8 +13,8 @@ using namespace mllm; int main(int argc, char **argv) { cmdline::parser cmdParser; cmdParser.add("vocab", 'v', "specify mllm tokenizer model path", false, "../vocab/llama3_tokenizer.model"); - cmdParser.add("model", 'm', "specify mllm model path", false, "../models/llama-3.2-1b-instruct_q4_k.mllm"); - cmdParser.add("billion", 'b', "[1B | 3B |]", false, "1B"); + cmdParser.add("model", 'm', "specify mllm model path", false, "../models/llama-3.2-1b-instruct-kai_q4_0.mllm"); + cmdParser.add("billion", 'b', "[1B | 3B |]", false, "1B-lm"); cmdParser.add("limits", 'l', "max KV cache size", false, 400); cmdParser.add("thread", 't', "num of threads", false, 4); cmdParser.parse_check(argc, argv); diff --git a/src/models/llama3/configuration_llama3.hpp b/src/models/llama3/configuration_llama3.hpp index acf0166d9..35e2a4dc2 100644 --- a/src/models/llama3/configuration_llama3.hpp +++ b/src/models/llama3/configuration_llama3.hpp @@ -95,6 +95,23 @@ class Llama3Config : public TransformerConfig { rope_theta = 500000.0; tie_word_embeddings = true; + rope_scaling = { + {"factor", 32.0f}, + {"high_freq_factor", 4.0f}, + {"low_freq_factor", 1.0f}, + {"original_max_position_embeddings", 8192}, + {"rope_type", std::string("llama3")}}; + } else if (billions == "1B-lm" || billions == "1b-lm") { + vocab_size = 128256; + hidden_dim = 2048; + head_size = 32; + num_key_value_heads = 8; + ffn_hidden = 8192; + block_num = 16; + max_position_embeddings = 131072; + rope_theta = 500000.0; + tie_word_embeddings = false; + rope_scaling = { {"factor", 32.0f}, {"high_freq_factor", 4.0f}, diff --git a/src/models/llama3/modeling_llama3.hpp b/src/models/llama3/modeling_llama3.hpp index 59e364fdf..8c0404d87 100644 --- a/src/models/llama3/modeling_llama3.hpp +++ b/src/models/llama3/modeling_llama3.hpp @@ -186,14 +186,17 @@ class Llama3Model final : public Module { vector blocks; Layer norm; Parameter lm_head; + Layer lm_head_layer; + bool tie_embedding_words_; public: explicit Llama3Model(const Llama3Config &config) : Llama3Model(config.vocab_size, config.hidden_dim, config.head_size, config.num_key_value_heads, config.ffn_hidden, config.block_num, - config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, + config.RoPE_type, config.rope_theta, config.max_position_embeddings, config.cache_limit, config.tie_word_embeddings, config.names_config, config, config.names_config.blk_name) { } Llama3Model(int vocab_size, int hidden_dim, int head_size, int kv_head_size, int ffn_hidden, int block_num, RoPEType RoPE_type, float rope_theta, int max_position_embeddings, int cache_limit, + bool tie_embedding_words, const Llama3NameConfig &names, const Llama3Config &config, const string &base_name) { @@ -201,13 +204,21 @@ class Llama3Model final : public Module { blocks = List(block_num, hidden_dim, head_size, kv_head_size, ffn_hidden, RoPE_type, rope_theta, max_position_embeddings, cache_limit, names, config, base_name); norm = RMSNorm(hidden_dim, 1e-6, names.post_norm_name); // TODO: tie_word_embeddings + tie_embedding_words_ = tie_embedding_words; // this is a workaround // we just simply use the token embedding as the lm_head // but now we are not really tying the word embeddings auto lm_head_name = names.lm_head_name; - assert(config.tie_word_embeddings); - lm_head_name = names.token_embd_name; - lm_head = Parameter(1, vocab_size, 1, hidden_dim, lm_head_name + ".weight"); + // assert(config.tie_word_embeddings); + if (tie_embedding_words) { + lm_head = Parameter(1, vocab_size, 1, hidden_dim, + names.token_embd_name + ".weight"); + } else { + lm_head_layer = + Linear(hidden_dim, vocab_size, false, names.lm_head_name); + } + // lm_head_name = names.token_embd_name; + // lm_head = Parameter(1, vocab_size, 1, hidden_dim, lm_head_name + ".weight"); } vector Forward(vector inputs, vector args) override { auto x = embedding(inputs[0]); @@ -215,7 +226,12 @@ class Llama3Model final : public Module { x = block({x})[0]; } x = norm(x); - x = Tensor::mm(x, lm_head().transpose(Chl::SEQUENCE, Chl::DIMENSION)); + if (tie_embedding_words_) { + x = Tensor::mm(x, lm_head().transpose(Chl::SEQUENCE, Chl::DIMENSION)); + } else { + x = lm_head_layer(x); + } + // x = Tensor::mm(x, lm_head().transpose(Chl::SEQUENCE, Chl::DIMENSION)); return {x}; } From 2a11989289e19706a3a6eedc5c290eff5c46af93 Mon Sep 17 00:00:00 2001 From: yirongjie Date: Mon, 27 Oct 2025 09:05:42 +0000 Subject: [PATCH 21/22] feat: add Qwen2-VL QNN Co-authored-by: liang1232018 <40791416+liang1232018@users.noreply.github.com> Co-authored-by: oreomaker <70836772+oreomaker@users.noreply.github.com> Co-authored-by: oreomaker Co-authored-by: xudaliang Co-authored-by: xwk <1263212259@qq.com> Co-authored-by: yuerqiqi <2500526025@qq.com> --- .gitignore | 3 +- CMakeLists.txt | 9 +- README.md | 30 +- assets/rotation.png | Bin 0 -> 440996 bytes examples/CMakeLists.txt | 6 +- examples/demo_phonelm_npu.cpp | 181 +- examples/demo_qwen2.5_npu.cpp | 108 - examples/demo_qwen2_vl_npu.cpp | 181 + examples/demo_qwen_npu.cpp | 138 +- ...ipeline.cpp => demo_qwen_npu_pipeline.cpp} | 53 +- examples/demo_qwen_pipeline.cpp | 124 - examples/main_alpaca.cpp | 163 - examples/main_clip.cpp | 201 - examples/main_fuyu.cpp | 235 - examples/main_imagebind.cpp | 322 -- examples/main_llama.cpp | 156 - examples/main_llava.cpp | 267 -- examples/main_phonelm_npu.cpp | 233 - examples/main_phonelm_npu.hpp | 231 - examples/main_qwen_npu.cpp | 235 - examples/main_qwen_npu.hpp | 227 - examples/main_tinyllama.cpp | 168 - examples/main_vit.cpp | 1183 ----- examples/mllm_benchmark.cpp | 1 + include/OpDefined.hpp | 223 +- include/Types.hpp | 1 - scripts/push_qnn_lib.sh | 17 + scripts/run_qwen_qnn.sh | 2 + src/Backend.hpp | 16 +- src/Context.cpp | 42 + src/Context.hpp | 47 + src/Executor.cpp | 151 - src/Executor.hpp | 101 - src/Graph.cpp | 236 - src/Graph.hpp | 109 - src/Layer.hpp | 103 + src/Module.cpp | 5 - src/Module.hpp | 2 - src/Net.cpp | 54 - src/Net.hpp | 50 - src/Parallel.hpp | 10 +- src/StateManager.hpp | 139 + src/Tensor.cpp | 35 +- src/Tensor.hpp | 35 +- src/backends/cpu/CPUBackend.cpp | 4 + src/backends/cpu/op/CPUBinaryFunc.hpp | 2 +- src/backends/cpu/op/CPUHeadLinear.cpp | 5 +- src/backends/cpu/op/CPUIRoPE.cpp | 10 +- src/backends/cpu/op/CPUKVCache.cpp | 11 +- src/backends/cpu/op/CPUKVCacheNPU.cpp | 16 +- .../cpu/op/CPUMultimodalRoPEPipeline.cpp | 10 +- src/backends/cpu/op/CPUQuantize.cpp | 13 + src/backends/cpu/op/CPURoPE.cpp | 6 +- src/backends/cpu/op/CPURoPETree.cpp | 11 +- src/backends/cpu/op/CPUTransposeFunc.hpp | 4 + src/backends/cpu/op/CPUViewFunc.hpp | 1 - src/backends/cpu/op/CPUVisionRoPECos.cpp | 213 + src/backends/cpu/op/CPUVisionRoPECos.hpp | 114 + src/backends/cpu/op/CPUVisionRoPESin.cpp | 213 + src/backends/cpu/op/CPUVisionRoPESin.hpp | 114 + src/backends/qnn/CMakeLists.txt | 20 +- .../LLaMAPackage/config/LLaMAOpPackageHtp.xml | 70 +- .../src/LLaMAPackageInterface.cpp | 279 +- .../LLaMAPackage/src/ops/IRoPE.cpp | 11 +- .../LLaMAPackage/src/ops/LLaMAQuantize.cpp | 56 + .../LLaMAPackage/src/ops/RMSNorm.cpp | 2 +- .../LLaMAPackage/src/ops/RoPE.cpp | 3 +- .../LLaMAPackage/src/ops/RoPESimple.cpp | 210 + src/backends/qnn/Log/LogUtils.cpp | 45 - src/backends/qnn/Log/LogUtils.hpp | 27 - src/backends/qnn/Log/Logger.cpp | 105 - src/backends/qnn/Log/Logger.hpp | 107 - src/backends/qnn/Model/QnnModel.cpp | 658 --- src/backends/qnn/Model/QnnModel.hpp | 271 -- src/backends/qnn/Model/QnnModelPal.cpp | 27 - src/backends/qnn/Model/QnnModelPal.hpp | 54 - src/backends/qnn/PAL/include/PAL/Debug.hpp | 21 - .../qnn/PAL/include/PAL/Directory.hpp | 80 - .../qnn/PAL/include/PAL/DynamicLoading.hpp | 99 - src/backends/qnn/PAL/include/PAL/FileOp.hpp | 238 - src/backends/qnn/PAL/include/PAL/GetOpt.hpp | 93 - src/backends/qnn/PAL/include/PAL/Path.hpp | 50 - src/backends/qnn/PAL/include/PAL/StringOp.hpp | 60 - src/backends/qnn/PAL/src/common/GetOpt.cpp | 154 - src/backends/qnn/PAL/src/common/StringOp.cpp | 45 - src/backends/qnn/PAL/src/linux/Directory.cpp | 153 - .../qnn/PAL/src/linux/DynamicLoading.cpp | 88 - src/backends/qnn/PAL/src/linux/FileOp.cpp | 356 -- src/backends/qnn/PAL/src/linux/Path.cpp | 48 - src/backends/qnn/QNN.hpp | 46 - src/backends/qnn/QNNBackend.cpp | 1654 ++++--- src/backends/qnn/QNNBackend.hpp | 204 +- src/backends/qnn/QNNExecutor.cpp | 341 -- src/backends/qnn/QNNExecutor.hpp | 85 - src/backends/qnn/QNNGraph.cpp | 175 - src/backends/qnn/QNNGraph.hpp | 50 - src/backends/qnn/QNNMemoryManager.cpp | 62 +- src/backends/qnn/QNNMemoryManager.hpp | 13 +- src/backends/qnn/QNNModel.cpp | 381 ++ src/backends/qnn/QNNModel.hpp | 99 + src/backends/qnn/QNNNet.cpp | 66 - src/backends/qnn/QNNNet.hpp | 23 - src/backends/qnn/QNNUtils.cpp | 328 ++ src/backends/qnn/QNNUtils.hpp | 74 + src/backends/qnn/README.md | 181 +- src/backends/qnn/Utils/DataUtil.cpp | 403 -- src/backends/qnn/Utils/DataUtil.hpp | 121 - src/backends/qnn/Utils/DynamicLoadUtil.cpp | 175 - src/backends/qnn/Utils/DynamicLoadUtil.hpp | 36 - src/backends/qnn/Utils/IOTensor.cpp | 934 ---- src/backends/qnn/Utils/IOTensor.hpp | 115 - src/backends/qnn/Utils/QnnSampleAppUtils.cpp | 441 -- src/backends/qnn/Utils/QnnSampleAppUtils.hpp | 87 - .../qnn/WrapperUtils/QnnWrapperUtils.cpp | 55 - .../qnn/WrapperUtils/QnnWrapperUtils.hpp | 166 - src/backends/qnn/op/QNNCommonOp.cpp | 41 +- src/backends/qnn/op/QNNCommonOp.hpp | 2 +- src/backends/qnn/op/QNNDequantize.cpp | 301 +- src/backends/qnn/op/QNNDequantizeAdd.cpp | 202 + src/backends/qnn/op/QNNDequantizeAdd.hpp | 32 + src/backends/qnn/op/QNNGELU.cpp | 27 +- src/backends/qnn/op/QNNGELU.hpp | 1 - src/backends/qnn/op/QNNIRoPE.cpp | 76 +- src/backends/qnn/op/QNNIRoPE.hpp | 2 - src/backends/qnn/op/QNNLayerNorm.cpp | 3 +- src/backends/qnn/op/QNNLinearINT8.cpp | 47 +- src/backends/qnn/op/QNNMatmul.cpp | 85 +- src/backends/qnn/op/QNNMergeOutput.cpp | 6 +- src/backends/qnn/op/QNNMul.cpp | 21 +- src/backends/qnn/op/QNNMul.hpp | 3 - src/backends/qnn/op/QNNQuantize.cpp | 13 +- src/backends/qnn/op/QNNQuickGELU.cpp | 156 + src/backends/qnn/op/QNNQuickGELU.hpp | 24 + src/backends/qnn/op/QNNRMSNorm.cpp | 25 +- src/backends/qnn/op/QNNRMSNorm.hpp | 2 - src/backends/qnn/op/QNNReLU.cpp | 26 +- src/backends/qnn/op/QNNReLU.hpp | 3 - src/backends/qnn/op/QNNRoPE.cpp | 26 +- src/backends/qnn/op/QNNRoPE.hpp | 2 - src/backends/qnn/op/QNNRoPESimple.cpp | 67 + src/backends/qnn/op/QNNRoPESimple.hpp | 32 + src/backends/qnn/op/QNNScale.cpp | 85 +- src/backends/qnn/op/QNNSiLUHigh.cpp | 72 + src/backends/qnn/op/QNNSiLUHigh.hpp | 25 + src/backends/qnn/op/QNNSoftMax.cpp | 1 + src/backends/qnn/op/QNNSplit.cpp | 219 + src/backends/qnn/op/QNNSplit.hpp | 50 + src/backends/qnn/op/QNNSplitInput.cpp | 4 +- src/backends/qnn/op/QNNSubGraphStart.cpp | 15 +- src/backends/qnn/op/QNNSuperSiLU.cpp | 67 +- src/backends/qnn/op/QNNView.cpp | 118 +- src/backends/qnn/op/QNNView.hpp | 2 - src/express/Express.cpp | 1182 ----- src/express/Express.hpp | 63 - src/express/ExpressBase.cpp | 423 -- src/express/ExpressBase.hpp | 113 - src/models/llama3/tokenization_llama3.hpp | 2 +- src/models/qwen/configuration_qwen.hpp | 58 +- ..._qwen_npu.hpp => modeling_qwen_npu_v2.hpp} | 109 +- .../qwen2_vl/configuration_qwen2_vl.hpp | 43 +- src/models/qwen2_vl/modeling_qwen2_vl_npu.hpp | 114 +- .../qwen2_vl/modeling_qwen2_vl_npuvit.hpp | 492 ++ .../transformer/modeling_transformer.hpp | 10 + src/tokenizers/Tokenizer.cpp | 6 +- test/CMakeLists.txt | 2 +- test/xnnpack/XpCausalMaskTest.cpp | 4 +- test/xnnpack/XpDynamicShapeTest.cpp | 9 +- test/xnnpack/XpEmbeddingTest.cpp | 4 +- test/xnnpack/XpExternalTensorTest.cpp | 6 +- test/xnnpack/XpKVCacheTest.cpp | 5 +- test/xnnpack/XpLinearTest.cpp | 4 +- test/xnnpack/XpLlamaMHATest.cpp | 4 +- test/xnnpack/XpReLUTest.cpp | 4 +- test/xnnpack/XpRoPETest.cpp | 4 +- test/xnnpack/XpSDPATest.cpp | 8 +- test/xnnpack/XpSliceTest.cpp | 7 +- test/xnnpack/XpSoftmaxTest.cpp | 4 +- test/xnnpack/XpTensorFunctionTest.cpp | 4 +- test/xnnpack/XpTransposeTest.cpp | 15 +- tools/convertor/converter.py | 4 +- .../convertor/profiling_activation/README.md | 58 - .../eval_quantize_threshold.py | 131 - .../profiling_activation/export_int8_model.py | 143 - .../get_act_distribution.py | 99 - .../simulate_inference.py | 84 - .../utils/quantization_simulation.py | 650 --- tools/jni/LibHelper.cpp | 68 +- tools/jni/helper.hpp | 89 - tools/qnn_convertor/README.md | 161 + tools/qnn_convertor/config/qwen1.5-1.8b.json | 34 + tools/qnn_convertor/config/show-ui-2b.json | 39 + tools/qnn_convertor/export_qnn_model.py | 249 + tools/qnn_convertor/export_rotate_model.py | 87 + tools/qnn_convertor/get_distribution.py | 221 + tools/qnn_convertor/model_interface.py | 374 ++ tools/qnn_convertor/utils/__init__.py | 1 + tools/qnn_convertor/utils/config.py | 220 + .../utils/get_input_output_scales.py | 10 +- tools/qnn_convertor/utils/model.py | 251 + .../utils/quantization_simulation.py | 1252 +++++ tools/qnn_convertor/utils/wrapper.py | 91 + tools/rotate/README.md | 106 + tools/rotate/__init__.py | 7 + tools/rotate/common.py | 373 ++ tools/rotate/hadamard_utils.py | 4196 +++++++++++++++++ tools/rotate/model/__init__.py | 0 tools/rotate/model/qwen.py | 378 ++ tools/rotate/rotation_utils.py | 129 + 208 files changed, 14335 insertions(+), 16077 deletions(-) create mode 100644 assets/rotation.png delete mode 100644 examples/demo_qwen2.5_npu.cpp create mode 100644 examples/demo_qwen2_vl_npu.cpp rename examples/{demo_qwen2.5_pipeline.cpp => demo_qwen_npu_pipeline.cpp} (56%) delete mode 100644 examples/demo_qwen_pipeline.cpp delete mode 100644 examples/main_alpaca.cpp delete mode 100644 examples/main_clip.cpp delete mode 100644 examples/main_fuyu.cpp delete mode 100644 examples/main_imagebind.cpp delete mode 100644 examples/main_llama.cpp delete mode 100644 examples/main_llava.cpp delete mode 100644 examples/main_phonelm_npu.cpp delete mode 100644 examples/main_phonelm_npu.hpp delete mode 100644 examples/main_qwen_npu.cpp delete mode 100644 examples/main_qwen_npu.hpp delete mode 100644 examples/main_tinyllama.cpp delete mode 100644 examples/main_vit.cpp create mode 100644 scripts/push_qnn_lib.sh create mode 100644 src/Context.cpp create mode 100644 src/Context.hpp delete mode 100644 src/Executor.cpp delete mode 100644 src/Executor.hpp delete mode 100644 src/Graph.cpp delete mode 100644 src/Graph.hpp delete mode 100644 src/Net.cpp delete mode 100644 src/Net.hpp create mode 100644 src/StateManager.hpp create mode 100644 src/backends/cpu/op/CPUVisionRoPECos.cpp create mode 100644 src/backends/cpu/op/CPUVisionRoPECos.hpp create mode 100644 src/backends/cpu/op/CPUVisionRoPESin.cpp create mode 100644 src/backends/cpu/op/CPUVisionRoPESin.hpp create mode 100644 src/backends/qnn/LLaMAOpPackageHtp/LLaMAPackage/src/ops/RoPESimple.cpp delete mode 100644 src/backends/qnn/Log/LogUtils.cpp delete mode 100644 src/backends/qnn/Log/LogUtils.hpp delete mode 100644 src/backends/qnn/Log/Logger.cpp delete mode 100644 src/backends/qnn/Log/Logger.hpp delete mode 100644 src/backends/qnn/Model/QnnModel.cpp delete mode 100644 src/backends/qnn/Model/QnnModel.hpp delete mode 100644 src/backends/qnn/Model/QnnModelPal.cpp delete mode 100644 src/backends/qnn/Model/QnnModelPal.hpp delete mode 100644 src/backends/qnn/PAL/include/PAL/Debug.hpp delete mode 100644 src/backends/qnn/PAL/include/PAL/Directory.hpp delete mode 100644 src/backends/qnn/PAL/include/PAL/DynamicLoading.hpp delete mode 100644 src/backends/qnn/PAL/include/PAL/FileOp.hpp delete mode 100644 src/backends/qnn/PAL/include/PAL/GetOpt.hpp delete mode 100644 src/backends/qnn/PAL/include/PAL/Path.hpp delete mode 100644 src/backends/qnn/PAL/include/PAL/StringOp.hpp delete mode 100644 src/backends/qnn/PAL/src/common/GetOpt.cpp delete mode 100644 src/backends/qnn/PAL/src/common/StringOp.cpp delete mode 100644 src/backends/qnn/PAL/src/linux/Directory.cpp delete mode 100644 src/backends/qnn/PAL/src/linux/DynamicLoading.cpp delete mode 100644 src/backends/qnn/PAL/src/linux/FileOp.cpp delete mode 100644 src/backends/qnn/PAL/src/linux/Path.cpp delete mode 100644 src/backends/qnn/QNN.hpp delete mode 100644 src/backends/qnn/QNNExecutor.cpp delete mode 100644 src/backends/qnn/QNNExecutor.hpp delete mode 100644 src/backends/qnn/QNNGraph.cpp delete mode 100644 src/backends/qnn/QNNGraph.hpp create mode 100644 src/backends/qnn/QNNModel.cpp create mode 100644 src/backends/qnn/QNNModel.hpp delete mode 100644 src/backends/qnn/QNNNet.cpp delete mode 100644 src/backends/qnn/QNNNet.hpp create mode 100644 src/backends/qnn/QNNUtils.cpp create mode 100644 src/backends/qnn/QNNUtils.hpp delete mode 100644 src/backends/qnn/Utils/DataUtil.cpp delete mode 100644 src/backends/qnn/Utils/DataUtil.hpp delete mode 100644 src/backends/qnn/Utils/DynamicLoadUtil.cpp delete mode 100644 src/backends/qnn/Utils/DynamicLoadUtil.hpp delete mode 100644 src/backends/qnn/Utils/IOTensor.cpp delete mode 100644 src/backends/qnn/Utils/IOTensor.hpp delete mode 100644 src/backends/qnn/Utils/QnnSampleAppUtils.cpp delete mode 100644 src/backends/qnn/Utils/QnnSampleAppUtils.hpp delete mode 100644 src/backends/qnn/WrapperUtils/QnnWrapperUtils.cpp delete mode 100644 src/backends/qnn/WrapperUtils/QnnWrapperUtils.hpp create mode 100644 src/backends/qnn/op/QNNDequantizeAdd.cpp create mode 100644 src/backends/qnn/op/QNNDequantizeAdd.hpp create mode 100644 src/backends/qnn/op/QNNQuickGELU.cpp create mode 100644 src/backends/qnn/op/QNNQuickGELU.hpp create mode 100644 src/backends/qnn/op/QNNRoPESimple.cpp create mode 100644 src/backends/qnn/op/QNNRoPESimple.hpp create mode 100644 src/backends/qnn/op/QNNSiLUHigh.cpp create mode 100644 src/backends/qnn/op/QNNSiLUHigh.hpp create mode 100644 src/backends/qnn/op/QNNSplit.cpp create mode 100644 src/backends/qnn/op/QNNSplit.hpp delete mode 100644 src/express/Express.cpp delete mode 100644 src/express/Express.hpp delete mode 100644 src/express/ExpressBase.cpp delete mode 100644 src/express/ExpressBase.hpp rename src/models/qwen/{modeling_qwen_npu.hpp => modeling_qwen_npu_v2.hpp} (84%) create mode 100644 src/models/qwen2_vl/modeling_qwen2_vl_npuvit.hpp delete mode 100644 tools/convertor/profiling_activation/README.md delete mode 100644 tools/convertor/profiling_activation/eval_quantize_threshold.py delete mode 100644 tools/convertor/profiling_activation/export_int8_model.py delete mode 100644 tools/convertor/profiling_activation/get_act_distribution.py delete mode 100644 tools/convertor/profiling_activation/simulate_inference.py delete mode 100644 tools/convertor/profiling_activation/utils/quantization_simulation.py delete mode 100644 tools/jni/helper.hpp create mode 100644 tools/qnn_convertor/README.md create mode 100644 tools/qnn_convertor/config/qwen1.5-1.8b.json create mode 100644 tools/qnn_convertor/config/show-ui-2b.json create mode 100644 tools/qnn_convertor/export_qnn_model.py create mode 100644 tools/qnn_convertor/export_rotate_model.py create mode 100644 tools/qnn_convertor/get_distribution.py create mode 100644 tools/qnn_convertor/model_interface.py create mode 100644 tools/qnn_convertor/utils/__init__.py create mode 100644 tools/qnn_convertor/utils/config.py rename tools/{convertor/profiling_activation => qnn_convertor}/utils/get_input_output_scales.py (87%) create mode 100644 tools/qnn_convertor/utils/model.py create mode 100644 tools/qnn_convertor/utils/quantization_simulation.py create mode 100644 tools/qnn_convertor/utils/wrapper.py create mode 100644 tools/rotate/README.md create mode 100644 tools/rotate/__init__.py create mode 100644 tools/rotate/common.py create mode 100644 tools/rotate/hadamard_utils.py create mode 100644 tools/rotate/model/__init__.py create mode 100644 tools/rotate/model/qwen.py create mode 100644 tools/rotate/rotation_utils.py diff --git a/.gitignore b/.gitignore index 33fdaad42..4e1f07e9a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .vscode/ .idea/ .cache/ +.DS_Store build*/ build/ bin/ @@ -32,7 +33,7 @@ tmp/ py-build-out/ mllm.egg-info/ -src/backends/qnn/sdk/* +src/backends/qnn/sdk* diff --git a/CMakeLists.txt b/CMakeLists.txt index e449c9fd3..43f9eef34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -186,6 +186,8 @@ endif() aux_source_directory(${PROJECT_SOURCE_DIR}/src DIR_SRC) aux_source_directory(${PROJECT_SOURCE_DIR}/src/express DIR_SRC_EXP) +# directory for legacy code, which is not used in the current version(Graph,Net,Executor) +aux_source_directory(${PROJECT_SOURCE_DIR}/src/legacy DIR_SRC_LEGACY) aux_source_directory(${PROJECT_SOURCE_DIR}/src/processor DIR_SRC_PROCESSOE) aux_source_directory(${PROJECT_SOURCE_DIR}/src/memory DIR_SRC_MEM_MANAGER) @@ -215,11 +217,6 @@ if(QNN) # QNN lib # $ENV{QNN_SDK_ROOT}/include/QNN # QNN SDK include ${PROJECT_SOURCE_DIR}/src/backends/qnn/sdk/include/QNN # QNN SDK include ${CMAKE_CURRENT_LIST_DIR}/src/backends/qnn - ${CMAKE_CURRENT_LIST_DIR}/src/backends/qnn/Log - ${CMAKE_CURRENT_LIST_DIR}/src/backends/qnn/PAL/include - ${CMAKE_CURRENT_LIST_DIR}/src/backends/qnn/Model - ${CMAKE_CURRENT_LIST_DIR}/src/backends/qnn/Utils - ${CMAKE_CURRENT_LIST_DIR}/src/backends/qnn/WrapperUtils ) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/src/backends/qnn) endif() @@ -341,7 +338,7 @@ endif() add_subdirectory(examples) if(APK) - add_library(mllm_lib STATIC ${DIR_SRC_CPU} ${DIR_SRC_EXP} ${DIR_SRC} ${DIR_SRC_MEM_MANAGER} ${DIR_SRC_PROCESSOE} + add_library(mllm_lib STATIC ${DIR_SRC_EXP} ${DIR_SRC} ${DIR_SRC_MEM_MANAGER} ${DIR_SRC_PROCESSOE} ${DIR_SRC_LEGACY} ${DIR_THIRDPARTY_AUDIO} src/tokenizers/Tokenizer.cpp tools/jni/LibHelper.cpp diff --git a/README.md b/README.md index 588ffb6ce..7fd25f208 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ fast and lightweight multimodal LLM inference engine for mobile and e mllm is a lightweight, fast, and easy-to-use (multimodal) on-device LLM inference engine for mobile devices (mainly supporting CPU/NPU), initiated by the research groups led by [Mengwei Xu](https://xumengwei.github.io/) (BUPT) and [Xuanzhe Liu](http://www.liuxuanzhe.com/) (PKU). ## Recent update +- [2025 July 30] Add Rotation Quantization method for QNN backend models and support Qwen-2-VL 2B - [2024 November 21] Support new model: Phi 3 Vision https://github.com/UbiquitousLearning/mllm/pull/186 - [2024 August 30] Support new model: MiniCPM 2B https://github.com/UbiquitousLearning/mllm/pull/132 - [2024 August 15] Support new model: Phi 3 mini https://github.com/UbiquitousLearning/mllm/pull/119 @@ -91,9 +92,9 @@ mllm is a lightweight, fast, and easy-to-use (multimodal) on-device LLM inferenc | [LLaVA 7B](https://github.com/haotian-liu/LLaVA) | [✔️](https://huggingface.co/mllmTeam/llava-1.5-7b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/llava-1.5-7b-mllm/tree/main) | | | [Gemma 2B](https://github.com/google/gemma_pytorch) | [✔️](https://huggingface.co/mllmTeam/gemma-2b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/gemma-2b-mllm/tree/main) | | | [Gemma 2 2B](https://github.com/google/gemma_pytorch) | [✔️](https://huggingface.co/mllmTeam/gemma-2-2b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/gemma-2-2b-mllm/tree/main) | | -| [Qwen 1.5 0.5B](https://github.com/QwenLM/Qwen) | [✔️](https://huggingface.co/mllmTeam/qwen-1.5-0.5b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/qwen-1.5-0.5b-mllm/tree/main) | | +| [Qwen 1.5 0.5B](https://github.com/QwenLM/Qwen) | [✔️](https://huggingface.co/mllmTeam/qwen-1.5-0.5b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/qwen-1.5-0.5b-mllm/tree/main) | ✔️ | | [Qwen 1.5 1.8B](https://github.com/QwenLM/Qwen) | [✔️](https://huggingface.co/mllmTeam/qwen-1.5-1.8b-chat-mllm) | [✔️](https://huggingface.co/mllmTeam/qwen-1.5-1.8b-chat-mllm) | [✔️](https://huggingface.co/mllmTeam/qwen-1.5-1.8b-chat-mllm) | -| [Qwen 2.5 1.5B](https://github.com/QwenLM/Qwen2.5) | [✔️](https://huggingface.co/mllmTeam/qwen-2.5-1.5b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/qwen-2.5-1.5b-mllm/tree/main) | | +| [Qwen 2.5 1.5B](https://github.com/QwenLM/Qwen2.5) | [✔️](https://huggingface.co/mllmTeam/qwen-2.5-1.5b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/qwen-2.5-1.5b-mllm/tree/main) | ✔️ | | [Qwen 3 0.6B](https://github.com/QwenLM/Qwen3) | [✔️](https://huggingface.co/mllmTeam/qwen-3-0.6b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/qwen-3-0.6b-mllm/tree/main) | | | [Mistral 7B](https://github.com/mistralai/mistral-src) | [✔️](https://huggingface.co/mllmTeam/mistral-7b-instruct-v0.2-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/mistral-7b-instruct-v0.2-mllm/tree/main) | | | [Yi 6B](https://huggingface.co/01-ai/Yi-1.5-6B) | [✔️](https://huggingface.co/mllmTeam/yi-1.5-6b-chat-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/yi-1.5-6b-chat-mllm/tree/main) | | @@ -110,15 +111,15 @@ mllm is a lightweight, fast, and easy-to-use (multimodal) on-device LLM inferenc ### Multimodal models -| Model | CPU
    FP32 | CPU
    INT4 | -|-----------------------------------------------------------------------------|------|-----| +| Model | CPU
    FP32 | CPU
    INT4 | Hexagon NPU
    INT8 | +|-----------------------------------------------------------------------------|------|-----|----------------------------| | [Fuyu 8B](https://www.adept.ai/blog/fuyu-8b) | [✔️](https://huggingface.co/mllmTeam/fuyu-8b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/fuyu-8b-mllm/tree/main) | | [Vision Transformer](https://github.com/google-research/vision_transformer) | [✔️](https://huggingface.co/mllmTeam/vit-base-patch16-224-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/vit-base-patch16-224-mllm/tree/main) | | [CLIP](https://github.com/openai/CLIP) | [✔️](https://huggingface.co/mllmTeam/clip-vit-base-patch32-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/clip-vit-base-patch32-mllm/tree/main) | | [ImageBind](https://github.com/facebookresearch/ImageBind) (3 modalities) | [✔️](https://huggingface.co/mllmTeam/imagebind_huge-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/imagebind_huge-mllm/tree/main) | | [LLaVA 7B](https://github.com/haotian-liu/LLaVA) | [✔️](https://huggingface.co/mllmTeam/llava-1.5-7b-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/llava-1.5-7b-mllm/tree/main) | | [Phi-3-Vision](https://huggingface.co/microsoft/Phi-3-vision-128k-instruct) | [✔️](https://huggingface.co/mllmTeam/phi-3-vision-instruct-mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/phi-3-vision-instruct-mllm/tree/main) | -| [Qwen2-VL 2B](https://github.com/QwenLM/Qwen2-VL) | [✔️](https://huggingface.co/mllmTeam/qwen-2-vl-2b-instruct--mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/qwen-2-vl-2b-instruct--mllm/tree/main) | +| [Qwen2-VL 2B](https://github.com/QwenLM/Qwen2-VL) | [✔️](https://huggingface.co/mllmTeam/qwen-2-vl-2b-instruct--mllm/tree/main) | [✔️](https://huggingface.co/mllmTeam/qwen-2-vl-2b-instruct--mllm/tree/main) | ✔️ | ## Quick Start @@ -148,7 +149,12 @@ Building mllm requires following tools: *`NOTE:` The QNN backend is preliminary version which can do end-to-end inference. It is still under active development for better performance and more supported models.* -We support running Qwen-1.5-1.8B-Chat using [Qualcomm QNN](https://www.qualcomm.com/developer/software/qualcomm-ai-engine-direct-sdk) to get Hexagon NPU acceleration on devices with Snapdragon 8 Gen3. The details of QNN environment set up and design is [here](./src/backends/qnn/README.md). The prefilling stage is performered by QNN & CPU, and the inference stage is performed by CPU. +We support running several Qwen family models including Qwen-2-vl using [Qualcomm QNN](https://www.qualcomm.com/developer/software/qualcomm-ai-engine-direct-sdk) to get Hexagon NPU acceleration on devices with Snapdragon 8 Gen3. The details of QNN environment set up and design is [here](./src/backends/qnn/README.md). The prefilling stage is performered by QNN & CPU, and the inference stage is performed by CPU. + +Specifically, we support the following models (similar architecture models are also supported): +- Qwen 1.5 1.8B (demo_qwen_npu, demo_qwen_pipeline) +- Qwen 2.5 1.5B (demo_qwen_npu, demo_qwen_pipeline) +- Qwen 2 VL (demo_qwen2_vl_npu and demo_qwen2_vl_npuvit) Build the target with QNN backend. @@ -157,7 +163,7 @@ cd ../script ./build_qnn_android.sh ``` -Download the model from [here](https://huggingface.co/mllmTeam/qwen-1.5-1.8b-chat-mllm/blob/main/), or using the following instructions +Download the model from [here](https://huggingface.co/mllmTeam/qwen-1.5-1.8b-chat-mllm/blob/main/), or using the following instructions to download the model. You can also export Pytorch models for QNN backend with int8 weight quantization and apply rotation quantization. Details can be found in backend specific [README](./src/backends/qnn/README.md). ```bash mkdir ../models && cd ../models @@ -166,19 +172,19 @@ wget https://huggingface.co/mllmTeam/qwen-1.5-1.8b-chat-mllm/resolve/main/qwen-1 wget https://huggingface.co/mllmTeam/qwen-1.5-1.8b-chat-mllm/resolve/main/qwen-1.5-1.8b-chat-q4k.mllm?download=true -O qwen-1.5-1.8b-chat-q4k.mllm ``` -Run on an android phone with at least 16GB of memory. +Currently, QNN backend uses models with W8A8 or W8A16 quantization. (It is determined by Quantize & Dequantize ops in modeling class, you can refer to `src/models/qwen/modeling_qwen_npu_v2.hpp` for more details.) + +Run on an android phone with at least 16GB of memory as building the QNN graphs on device will consume a lot of memory. After building and saving QNN graphs to qnn_context.bin, the runtime memory usage will meet the expectation. The `demo_qwen_pipeline.cpp` will show the pipeline parallel execution for QNN models, which will nearly has 1.5x speedup compared with the original execution. ```bash cd ../script -./run_qwen_npu.sh +./run_qwen_qnn.sh ``` -There are two arguments in the executable. `-s` is for the sequence length of prefilling, the default value is 64 in the demo we provided. `-c` for type of QNN prefilling options, when it is set to 1, the input will be splited into many chunks of sequence 32 and be executed in a pipeline. When it is set to 0, the input will be executed in one chunk. - Result are as followed: ``` -> ./main_qwen_npu -s 64 -c 1 +> ./demo_qwen_npu [Q] <|im_start|>system You are a helpful assistant.<|im_end|> <|im_start|>user diff --git a/assets/rotation.png b/assets/rotation.png new file mode 100644 index 0000000000000000000000000000000000000000..43f9f2960eeb344811ef753e82701e39aaf69144 GIT binary patch literal 440996 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 z

  • =ZPRVJrCI^y-leAat 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 Mb8Yt=Qe*Tfx=q*gzaJuH?Qn>~9CL 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