From 43204f038e8d11acb97e8938022251a46ce9eaf5 Mon Sep 17 00:00:00 2001
From: zhifu gao <zhifu.gzf@alibaba-inc.com>
Date: 星期五, 03 三月 2023 21:52:28 +0800
Subject: [PATCH] Merge pull request #185 from RapidAI/main
---
funasr/runtime/cpp/onnxruntime/src/tmp.h | 112
funasr/runtime/cpp/onnxruntime/src/Model.cpp | 11
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/get_scaling_square.c | 46
funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3l-3.dll | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_core.h | 114
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/spl_inl.h | 153
funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.exp | 0
funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3f-3.dll | 0
funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.exp | 0
funasr/runtime/cpp/onnxruntime/win/bin/x86/onnxruntime.dll | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_core.c | 685 +
funasr/runtime/cpp/onnxruntime/readme.md | 107
funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_run_options_config_keys.h | 32
funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.def | 634 +
funasr/runtime/cpp/onnxruntime/src/FeatureExtract.h | 36
funasr/runtime/cpp/onnxruntime/include/Audio.h | 53
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_sp.c | 176
funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.def | 1017 +
funasr/runtime/cpp/onnxruntime/win/include/fftw3.h | 415
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.cc | 34
funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3-3.dll | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/numerics/safe_compare.h | 176
funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3f-3.dll | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/typedefs.h | 149
funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.exp | 0
funasr/runtime/cpp/onnxruntime/win/include/cpu_provider_factory.h | 19
funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/system/inline.h | 31
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h | 29
funasr/runtime/cpp/onnxruntime/win/images/sample.png | 0
funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.exp | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_sp.h | 54
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c | 77
funasr/runtime/cpp/onnxruntime/models/readme.md | 1
funasr/runtime/cpp/onnxruntime/src/Audio.cpp | 298
funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_cxx_inline.h | 1874 +++
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c | 165
funasr/runtime/cpp/onnxruntime/src/alignedmem.h | 10
funasr/runtime/cpp/onnxruntime/src/CommonStruct.h | 6
funasr/runtime/cpp/onnxruntime/win/include/tensorrt_provider_factory.h | 14
funasr/runtime/cpp/onnxruntime/models/vocab.txt | 8404 +++++++++++++++
funasr/runtime/cpp/onnxruntime/wave/short.wav | 0
funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.def | 1017 +
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/signal_processing_library.h | 1612 ++
funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.def | 634 +
funasr/runtime/cpp/onnxruntime/include/webrtc_vad.h | 87
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.c | 689 +
funasr/runtime/cpp/onnxruntime/src/SpeechWrap.h | 26
funasr/runtime/cpp/onnxruntime/win/bin/x64/onnxruntime.dll | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/downsample_fast.c | 65
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.h | 60
funasr/runtime/cpp/onnxruntime/include/ComDefine.h | 11
funasr/runtime/cpp/onnxruntime/images/demo.png | 0
funasr/runtime/cpp/onnxruntime/win/readme.md | 1
funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/checks.cc | 167
funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3l-3.dll | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/min_max_operations.c | 224
funasr/runtime/cpp/onnxruntime/wave/long.wav | 0
funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.lib | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/system/arch.h | 58
funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.def | 1017 +
funasr/runtime/cpp/onnxruntime/src/FeatureQueue.cpp | 59
funasr/runtime/cpp/onnxruntime/win/lib/x64/onnxruntime.lib | 0
funasr/runtime/cpp/onnxruntime/src/util.cpp | 180
funasr/runtime/cpp/onnxruntime/src/paraformer_onnx.h | 52
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/division_operations.c | 141
funasr/runtime/cpp/onnxruntime/src/Vocab.h | 24
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_fft_tables.h | 132
funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/compile_assert_c.h | 25
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/webrtc_vad.c | 115
funasr/runtime/cpp/onnxruntime/src/Tensor.h | 155
funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.lib | 0
funasr/runtime/cpp/onnxruntime/src/util.h | 30
funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.lib | 0
funasr/runtime/cpp/onnxruntime/tester/tester.cpp | 72
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/energy.c | 39
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/include/webrtc_vad.h | 87
funasr/runtime/cpp/onnxruntime/images/threadnum.png | 0
funasr/runtime/cpp/onnxruntime/src/alignedmem.cpp | 18
funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_c_api.h | 3987 +++++++
funasr/runtime/cpp/onnxruntime/tester/CMakeLists.txt | 20
funasr/runtime/cpp/onnxruntime/src/precomp.h | 49
funasr/runtime/cpp/onnxruntime/CMakeLists.txt | 30
funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/checks.h | 400
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_sqrt.c | 194
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_inl.c | 24
funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_cxx_api.h | 1876 +++
funasr/runtime/cpp/onnxruntime/include/win_func.h | 28
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/cross_correlation.c | 30
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/real_fft.h | 96
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_48khz.c | 186
funasr/runtime/cpp/onnxruntime/third_party/webrtc/system_wrappers/include/cpu_features_wrapper.h | 48
funasr/runtime/cpp/onnxruntime/win/include/provider_options.h | 18
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_fractional.c | 239
funasr/runtime/cpp/onnxruntime/win/lib/x86/onnxruntime.lib | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_bit_reverse.c | 108
funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.exp | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/type_traits.h | 140
funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.lib | 0
funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.lib | 0
funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_session_options_config_keys.h | 186
funasr/runtime/cpp/onnxruntime/src/predefine_coe.h | 592 +
funasr/runtime/cpp/onnxruntime/CMakeSettings.json | 26
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_filterbank.h | 45
funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/sanitizer.h | 144
funasr/runtime/cpp/onnxruntime/src/FeatureQueue.h | 28
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_fft.c | 299
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_filterbank.c | 329
funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.exp | 0
funasr/runtime/cpp/onnxruntime/src/Vocab.cpp | 170
funasr/runtime/cpp/onnxruntime/src/SpeechWrap.cpp | 39
funasr/runtime/cpp/onnxruntime/src/CMakeLists.txt | 43
funasr/runtime/cpp/onnxruntime/include/Model.h | 17
funasr/runtime/cpp/onnxruntime/src/paraformer_onnx.cpp | 179
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_init.c | 133
funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.def | 1017 +
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_gmm.h | 39
funasr/runtime/cpp/onnxruntime/wave/asr_example.wav | 0
funasr/runtime/cpp/onnxruntime/src/FeatureExtract.cpp | 408
funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.lib | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.h | 40
funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_gmm.c | 82
funasr/runtime/cpp/onnxruntime/src/commonfunc.h | 45
funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3-3.dll | 0
funasr/runtime/cpp/onnxruntime/third_party/webrtc/CMakeLists.txt | 16
124 files changed, 33,079 insertions(+), 0 deletions(-)
diff --git a/funasr/runtime/cpp/onnxruntime/CMakeLists.txt b/funasr/runtime/cpp/onnxruntime/CMakeLists.txt
new file mode 100644
index 0000000..8d502c4
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.10)
+
+#-DONNXRUNTIME_DIR=D:\thirdpart\onnxruntime
+project(FastASR)
+
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+# for onnxruntime
+
+IF(WIN32)
+
+
+ if(CMAKE_CL_64)
+ link_directories(${ONNXRUNTIME_DIR}\\lib)
+ else()
+ add_definitions(-D_WIN_X86)
+ endif()
+ELSE()
+
+
+link_directories(${ONNXRUNTIME_DIR}/lib)
+
+endif()
+
+#option(FASTASR_BUILD_PYTHON_MODULE "build python module, using FastASR in Python" OFF)
+
+add_subdirectory("./third_party/webrtc")
+add_subdirectory(src)
+add_subdirectory(tester)
diff --git a/funasr/runtime/cpp/onnxruntime/CMakeSettings.json b/funasr/runtime/cpp/onnxruntime/CMakeSettings.json
new file mode 100644
index 0000000..f515d1f
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/CMakeSettings.json
@@ -0,0 +1,26 @@
+锘縶
+ "configurations": [
+ {
+ "name": "x64-Debug",
+ "generator": "Ninja",
+ "configurationType": "Debug",
+ "inheritEnvironments": [ "msvc_x64_x64" ],
+ "buildRoot": "${projectDir}\\out\\build\\${name}",
+ "installRoot": "${projectDir}\\out\\install\\${name}",
+ "buildCommandArgs": "",
+ "ctestCommandArgs": ""
+ },
+ {
+ "name": "x64-Release",
+ "generator": "Ninja",
+ "configurationType": "RelWithDebInfo",
+ "buildRoot": "${projectDir}\\out\\build\\${name}",
+ "installRoot": "${projectDir}\\out\\install\\${name}",
+ "cmakeCommandArgs": "",
+ "buildCommandArgs": "",
+ "ctestCommandArgs": "",
+ "inheritEnvironments": [ "msvc_x64_x64" ],
+ "variables": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/funasr/runtime/cpp/onnxruntime/images/demo.png b/funasr/runtime/cpp/onnxruntime/images/demo.png
new file mode 100644
index 0000000..03171b2
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/images/demo.png
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/images/threadnum.png b/funasr/runtime/cpp/onnxruntime/images/threadnum.png
new file mode 100644
index 0000000..dd70cc8
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/images/threadnum.png
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/include/Audio.h b/funasr/runtime/cpp/onnxruntime/include/Audio.h
new file mode 100644
index 0000000..af8d2a9
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/include/Audio.h
@@ -0,0 +1,53 @@
+
+#ifndef AUDIO_H
+#define AUDIO_H
+
+#include <ComDefine.h>
+#include <queue>
+#include <stdint.h>
+
+using namespace std;
+
+class AudioFrame {
+ private:
+ int start;
+ int end;
+ int len;
+
+ public:
+ AudioFrame();
+ AudioFrame(int len);
+
+ ~AudioFrame();
+ int set_start(int val);
+ int set_end(int val, int max_len);
+ int get_start();
+ int get_len();
+ int disp();
+};
+
+class Audio {
+ private:
+ float *speech_data;
+ int16_t *speech_buff;
+ int speech_len;
+ int speech_align_len;
+ int16_t sample_rate;
+ int offset;
+ float align_size;
+ int data_type;
+ queue<AudioFrame *> frame_queue;
+
+ public:
+ Audio(int data_type);
+ Audio(int data_type, int size);
+ ~Audio();
+ void disp();
+ bool loadwav(const char *filename);
+ int fetch_chunck(float *&dout, int len);
+ int fetch(float *&dout, int &len, int &flag);
+ void padding();
+ void split();
+};
+
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/include/ComDefine.h b/funasr/runtime/cpp/onnxruntime/include/ComDefine.h
new file mode 100644
index 0000000..f131e5e
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/include/ComDefine.h
@@ -0,0 +1,11 @@
+
+#ifndef COMDEFINE_H
+#define COMDEFINE_H
+
+#define S_BEGIN 0
+#define S_MIDDLE 1
+#define S_END 2
+#define S_ALL 3
+#define S_ERR 4
+
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/include/Model.h b/funasr/runtime/cpp/onnxruntime/include/Model.h
new file mode 100644
index 0000000..06267cb
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/include/Model.h
@@ -0,0 +1,17 @@
+
+#ifndef MODEL_H
+#define MODEL_H
+
+#include <string>
+
+class Model {
+ public:
+ virtual ~Model(){};
+ virtual void reset() = 0;
+ virtual std::string forward_chunk(float *din, int len, int flag) = 0;
+ virtual std::string forward(float *din, int len, int flag) = 0;
+ virtual std::string rescoring() = 0;
+};
+
+Model *create_model(const char *path,int nThread=0);
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/include/webrtc_vad.h b/funasr/runtime/cpp/onnxruntime/include/webrtc_vad.h
new file mode 100644
index 0000000..f5bbadf
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/include/webrtc_vad.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * This header file includes the VAD API calls. Specific function calls are
+ * given below.
+ */
+
+#ifndef COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ // NOLINT
+#define COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef struct WebRtcVadInst VadInst;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Creates an instance to the VAD structure.
+VadInst* WebRtcVad_Create(void);
+
+// Frees the dynamic memory of a specified VAD instance.
+//
+// - handle [i] : Pointer to VAD instance that should be freed.
+void WebRtcVad_Free(VadInst* handle);
+
+// Initializes a VAD instance.
+//
+// - handle [i/o] : Instance that should be initialized.
+//
+// returns : 0 - (OK),
+// -1 - (null pointer or Default mode could not be set).
+int WebRtcVad_Init(VadInst* handle);
+
+// Sets the VAD operating mode. A more aggressive (higher mode) VAD is more
+// restrictive in reporting speech. Put in other words the probability of being
+// speech when the VAD returns 1 is increased with increasing mode. As a
+// consequence also the missed detection rate goes up.
+//
+// - handle [i/o] : VAD instance.
+// - mode [i] : Aggressiveness mode (0, 1, 2, or 3).
+//
+// returns : 0 - (OK),
+// -1 - (null pointer, mode could not be set or the VAD instance
+// has not been initialized).
+int WebRtcVad_set_mode(VadInst* handle, int mode);
+
+// Calculates a VAD decision for the |audio_frame|. For valid sampling rates
+// frame lengths, see the description of WebRtcVad_ValidRatesAndFrameLengths().
+//
+// - handle [i/o] : VAD Instance. Needs to be initialized by
+// WebRtcVad_Init() before call.
+// - fs [i] : Sampling frequency (Hz): 8000, 16000, or 32000
+// - audio_frame [i] : Audio frame buffer.
+// - frame_length [i] : Length of audio frame buffer in number of samples.
+//
+// returns : 1 - (Active Voice),
+// 0 - (Non-active Voice),
+// -1 - (Error)
+int WebRtcVad_Process(VadInst* handle,
+ int fs,
+ const int16_t* audio_frame,
+ size_t frame_length);
+
+// Checks for valid combinations of |rate| and |frame_length|. We support 10,
+// 20 and 30 ms frames and the rates 8000, 16000 and 32000 Hz.
+//
+// - rate [i] : Sampling frequency (Hz).
+// - frame_length [i] : Speech frame buffer length in number of samples.
+//
+// returns : 0 - (valid combination), -1 - (invalid combination)
+int WebRtcVad_ValidRateAndFrameLength(int rate, size_t frame_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ // NOLINT
diff --git a/funasr/runtime/cpp/onnxruntime/include/win_func.h b/funasr/runtime/cpp/onnxruntime/include/win_func.h
new file mode 100644
index 0000000..1baaae5
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/include/win_func.h
@@ -0,0 +1,28 @@
+#include <time.h>
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+#ifdef WIN32
+int gettimeofday(struct timeval* tp, void* tzp)
+{
+ time_t clock;
+ struct tm tm;
+ SYSTEMTIME wtm;
+
+ GetLocalTime(&wtm);
+ tm.tm_year = wtm.wYear - 1900;
+ tm.tm_mon = wtm.wMonth - 1;
+ tm.tm_mday = wtm.wDay;
+ tm.tm_hour = wtm.wHour;
+ tm.tm_min = wtm.wMinute;
+ tm.tm_sec = wtm.wSecond;
+ tm.tm_isdst = -1;
+
+ clock = mktime(&tm);
+ tp->tv_sec = clock;
+ tp->tv_usec = wtm.wMilliseconds * 1000;
+ return (0);
+}
+#endif
\ No newline at end of file
diff --git a/funasr/runtime/cpp/onnxruntime/models/readme.md b/funasr/runtime/cpp/onnxruntime/models/readme.md
new file mode 100644
index 0000000..732ef01
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/models/readme.md
@@ -0,0 +1 @@
+Place model.onnx here!
diff --git a/funasr/runtime/cpp/onnxruntime/models/vocab.txt b/funasr/runtime/cpp/onnxruntime/models/vocab.txt
new file mode 100644
index 0000000..61cb04e
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/models/vocab.txt
@@ -0,0 +1,8404 @@
+<blank>
+<s>
+</s>
+and@@
+绛�
+闄�
+鐪�
+濉�
+妾�
+琛�
+姘�
+瀛�
+闃�
+閭�
+鍧�
+鍠�
+鏇�
+榧�
+闅�
+鑵�
+鏃�
+鐭�
+鏁�
+淇�
+浼�
+鎬�
+濉�
+price
+鏄�
+缃�
+濞�
+妫�
+寮�
+鑼�
+搴�
+姹�
+鎿�
+璐�
+楣�
+these
+杩�
+璇�
+do@@
+鐩�
+绉�
+鍟�
+棰�
+杈�
+褰�
+ps
+鏂�
+鐬�
+閾�
+婕�
+韫�
+鏃�
+绐�
+鑷�
+瑙�
+鍢�
+娣�
+灏�
+琚�
+鏂�
+绛�
+濯�
+鎸�
+鑷�
+榻�
+鐠�
+绗�
+婊�
+鍗�
+鎰�
+鎬�
+gr@@
+骞�
+绁�
+绠�
+绀�
+鑼�
+鍖�
+婢�
+淇�
+铇�
+ing
+鑲�
+鑲�
+宸�
+涔�
+锠�
+璺�
+钘�
+娌�
+ness
+鐠�
+绉�
+瀵�
+鏍�
+鑸�
+鍖�
+鐪�
+宀�
+鍕�
+鐠�
+榛�
+鐘�
+鍝�
+缃�
+k
+涓�
+de
+璺�
+姊�
+闇�
+姣�
+宄�
+绔�
+鐮�
+鐮�
+鐪�
+婊�
+楣�
+鑲�
+闃�
+per
+蹇�
+涔�
+搴�
+閭�
+杓�
+椹�
+澶�
+瀵�
+蹇�
+宕�
+鐫�
+閫�
+宄�
+瓒�
+鐙�
+锜�
+绗�
+閫�
+娲�
+缂�
+ore
+杈�
+绮�
+韫�
+榛�
+娴�
+comp@@
+鐘�
+钘�
+鏈�
+鍡�
+榛�
+閫�
+缁�
+閴�
+楹�
+鍠�
+琚�
+鍒�
+渚�
+ic@@
+楠�
+鐡�
+鏌�
+妗�
+椴�
+瑜�
+闊�
+濡�
+鐢�
+to@@
+杞�
+濉�
+鍧�
+璨�
+n@@
+钑�
+鐤�
+浼�
+閰�
+鏆�
+闇�
+浜�
+钀�
+鍢�
+nu@@
+鎸�
+by
+鑱�
+琚�
+宥�
+妗�
+鎶�
+鏀�
+闉�
+姣�
+鏃�
+搴�
+鍛�
+璇�
+tting
+鐙�
+榄�
+浼�
+鍠�
+妯�
+缈�
+鎬�
+鍦�
+鐫�
+鐩�
+times
+椴�
+鐖�
+缁�
+鐨�
+灏�
+鍢�
+娓�
+杩�
+鍢�
+琚�
+濮�
+濂�
+鍙�
+绂�
+鎸�
+搴�
+缁�
+婕�
+榫�
+tu@@
+姒�
+璇�
+minu@@
+钀�
+瑁�
+鐜�
+璋�
+浜�
+鍓�
+any@@
+璇�
+鍞�
+闋�
+鏂�
+璧�
+楠�
+璁�
+姣�
+搴�
+寰�
+妞�
+杩�
+鍩�
+杈�
+姹�
+鍙�
+杈�
+闅�
+閬�
+pp@@
+缈�
+浣�
+鏍�
+韪�
+鐨�
+鑻�
+鐥�
+濂�
+闃�
+鎮�
+鐐�
+纰�
+鑼�
+鐫�
+闂�
+few
+绫�
+瀛�
+鎷�
+for
+鏇�
+鐤�
+杈�
+璧�
+濮�
+涓�
+璇�
+鎬�
+娌�
+with@@
+鐫�
+璋�
+鏅�
+鍡�
+id
+aga@@
+瀹�
+榄�
+椴�
+瀵�
+婊�
+鐝�
+鑵�
+鍐�
+澶�
+濞�
+瀹�
+渚�
+绛�
+an
+纾�
+閭�
+鐫�
+韪�
+ite
+鐙�
+ele@@
+钃�
+鐚�
+璞�
+钄�
+娌�
+鍘�
+閾�
+鐧�
+绔�
+鐢�
+鐠�
+鑼�
+鍝�
+鑿�
+榫�
+宀�
+瀚�
+鎷�
+鏈�
+鎴�
+鐞�
+缁�
+婢�
+妤�
+鑾�
+cer@@
+here
+鍒�
+甯�
+鍡�
+鍋�
+鎷�
+楂�
+绌�
+鍕�
+鏍�
+濉�
+ou@@
+姗�
+鍒�
+渚�
+閹�
+bre@@
+瓒�
+绋�
+宀�
+鎷�
+钀�
+宀�
+姘�
+妗�
+楝�
+clu@@
+铓�
+鑲�
+璁�
+楠�
+蹇�
+闆�
+0@@
+绠�
+鑵�
+鐠�
+閰�
+閿�
+锜�
+閫�
+妞�
+棰�
+ts
+鐭�
+鎷�
+鐝�
+渚�
+铓�
+鐨�
+缈�
+鍎�
+鎭�
+鐎�
+鏁�
+鐮�
+濂�
+鑰�
+鐑�
+缁�
+缂�
+杈�
+time
+钄�
+too
+鍦�
+楠�
+鎱�
+鍟�
+甯�
+妤�
+bi@@
+铓�
+娴�
+ine
+缍�
+old
+鑲�
+鎿�
+ling
+鐦�
+濞�
+prob@@
+鏆�
+椴�
+鐒�
+鍓�
+鐜�
+涔�
+绾�
+bo@@
+鐔�
+姣�
+槌�
+闉�
+绲�
+绯�
+鑿�
+寤�
+璋�
+鍐�
+閬�
+琛�
+ich
+鏌�
+宄�
+娓�
+浜�
+鑽�
+铦�
+鎵�
+閯�
+璇�
+灏�
+鎽�
+鐗�
+钖�
+da@@
+w
+鍛�
+闄�
+纾�
+鍖�
+while
+杩�
+鑹�
+閮�
+ct@@
+铓�
+娴�
+椴�
+鑵�
+pres@@
+姘�
+棰�
+澶�
+ter@@
+宸�
+渚�
+濡�
+鍤�
+娈�
+绉�
+bas@@
+閿�
+绡�
+鍚�
+閯�
+槌�
+鐤�
+cor@@
+姣�
+姝�
+閭�
+鍦�
+inn
+鑸�
+鍩�
+璨�
+甯�
+濡�
+ged
+绐�
+put
+璇�
+鍫�
+姘�
+鍦�
+鎽�
+娌�
+璋�
+杞�
+璇�
+鐞�
+缇�
+妾�
+鎱�
+韪�
+鍟�
+鐬�
+灞�
+鎾�
+绛�
+璐�
+椋�
+鑻�
+鎵�
+mis@@
+妗�
+渚�
+jo@@
+ke@@
+鍐�
+婊�
+锠�
+鍛�
+鎹�
+璇�
+宕�
+闃�
+鎺�
+鍔�
+鐨�
+宸�
+鑲�
+鑲�
+钁�
+妾�
+鐢�
+鐙�
+璋�
+鍌�
+璇�
+绾�
+鑽�
+鍘�
+bri@@
+缁�
+鐫�
+甯�
+姹�
+鍣�
+鐏�
+閯�
+鐓�
+钂�
+鍘�
+棣�
+鐙�
+纰�
+绌�
+lar@@
+椋�
+杩�
+meeting
+tter
+瓒�
+杈�
+妞�
+姹�
+鐕�
+ate
+绀�
+楠�
+will
+not
+鐓�
+鍡�
+绉�
+鍕�
+闄�
+閿�
+澧�
+瀹�
+铇�
+閰�
+鍞�
+棰�
+浠�
+iting
+鐢�
+妤�
+鐟�
+閯�
+our
+璇�
+venue
+闇�
+闀�
+鐥�
+濞�
+濠�
+鍩�
+姹�
+閾�
+寰�
+闅�
+鐚�
+鍗�
+鎱�
+said
+瑁�
+bus@@
+鍙�
+绮�
+杩�
+缂�
+绾�
+纾�
+鐐�
+鍑�
+鏇�
+鍏�
+娲�
+鏉�
+姒�
+hotels
+鐫�
+绯�
+绐�
+钁�
+甯�
+鑽�
+濉�
+鐭�
+鍦�
+er@@
+铓�
+绡�
+鍜�
+鍚�
+鍠�
+宀�
+鍤�
+璋�
+宕�
+锜�
+wal@@
+濮�
+璋�
+涓�
+鑿�
+ction
+鑲�
+绁�
+杩�
+鐠�
+浠�
+鍞�
+纭�
+鍢�
+閱�
+鍏�
+鎭�
+閾�
+鍙�
+cre@@
+寮�
+鏇�
+铻�
+鑻�
+鐤�
+楦�
+鏉�
+鎼�
+閫�
+鑼�
+鐨�
+琛�
+鑲�
+ns
+market
+璁�
+闃�
+鏈�
+鑻�
+楂�
+is@@
+骞�
+閮�
+钀�
+甯�
+鐑�
+瑗�
+宕�
+婧�
+铻�
+閾�
+浠�
+鑸�
+鏁�
+鍊�
+閿�
+楦�
+澶�
+鍩�
+鑵�
+闆�
+ol@@
+娑�
+缈�
+澶�
+鐤�
+el
+椹�
+楣�
+鐟�
+钖�
+濂�
+濞�
+闈�
+闀�
+浼�
+鏆�
+what
+钀�
+鐨�
+鐑�
+鏁�
+鏍�
+ri@@
+鐫�
+浼�
+寰�
+绁�
+璐�
+姹�
+绠�
+鎺�
+姊�
+ob@@
+璧�
+榛�
+娼�
+椴�
+鐗�
+缃�
+inter@@
+鍐�
+鎴�
+钖�
+if
+鍫�
+鎼�
+婕�
+璧�
+鐥�
+鍙�
+椴�
+鍏�
+娴�
+钖�
+姊�
+璋�
+鍔�
+鑼�
+椋�
+r
+her
+椴�
+濡�
+鎯�
+姒�
+璋�
+姊�
+twenty
+ni@@
+鐚�
+鍏�
+姘�
+鑲�
+楗�
+闄�
+within
+杞�
+cted
+鍗�
+鍤�
+鍞�
+inte@@
+閽�
+鎶�
+閮�
+鐗�
+钄�
+閭�
+鎳�
+閭�
+鑼�
+杈�
+绉�
+榛�
+hard
+鎮�
+缁�
+ved
+oo@@
+used
+婧�
+钘�
+澹�
+鐚�
+鑺�
+char@@
+we
+鍛�
+ss@@
+宀�
+妗�
+杩�
+鑽�
+鍝�
+浠�
+鎶�
+娣�
+il
+鐢�
+瑜�
+鏋�
+bir@@
+ges
+鏆�
+妞�
+鍚�
+sal@@
+鐛�
+鐓�
+绠�
+鐖�
+鍛�
+閭�
+灏�
+姘�
+sh@@
+fore
+mat@@
+娴�
+鏋�
+绋�
+鑹�
+鍞�
+can@@
+eng
+know
+妗�
+浜�
+tou@@
+浼�
+铏�
+缍�
+sha@@
+鑵�
+钄�
+鑾�
+鎴�
+閶�
+閰�
+鐠�
+闃�
+璐�
+杩�
+楠�
+dre@@
+璧�
+鎯�
+瑁�
+鏅�
+閾�
+鎰�
+闅�
+绁�
+璨�
+鐗�
+al
+鎶�
+鏌�
+鎺�
+鍠�
+锜�
+娼�
+鎵�
+鑳�
+閮�
+钃�
+绋�
+鍌�
+鍨�
+鐢�
+闈�
+chic@@
+鏁�
+鏍�
+榻�
+浠�
+鎷�
+har@@
+浠�
+鐮�
+i
+鑸�
+鍚�
+鎱�
+鑺�
+why
+tic
+鍝�
+浣�
+閾�
+濡�
+x
+鍒�
+娈�
+韬�
+鑾�
+瀹�
+鎷�
+钁�
+鍝�
+濠�
+ance
+妫�
+娌�
+宕�
+鏇�
+瀹�
+鏂�
+鎺�
+閱�
+搴�
+榛�
+涔�
+鏃�
+閾�
+瀵�
+閽�
+娌�
+gh@@
+鍚�
+瀣�
+鍘�
+绠�
+ah
+璀�
+椴�
+钂�
+閵�
+瑙�
+鑴�
+澶�
+who
+姣�
+璧�
+鍢�
+韫�
+椐�
+avenue
+鍛�
+that's
+瑷�
+钂�
+灏�
+鎶�
+闇�
+que@@
+鐗�
+鍙�
+缁�
+鎹�
+鍩�
+铔�
+杩�
+ir
+鏈�
+涓�
+楣�
+閽�
+鏅�
+閽�
+宀�
+鐑�
+鎺�
+绗�
+棣�
+鐢�
+鍟�
+璧�
+锠�
+鑽�
+婵�
+鎽�
+鍓�
+娴�
+鐡�
+娑�
+闃�
+eng@@
+澧�
+椴�
+鑰�
+鎷�
+杞�
+寮�
+绉�
+ken
+鐪�
+绌�
+璺�
+鑺�
+鍓�
+婀�
+鍚�
+鍠�
+鍊�
+浼�
+鍜�
+鍣�
+鍓�
+鐣�
+鍥�
+姣�
+鐖�
+绠�
+ans@@
+no
+缂�
+fic@@
+蹇�
+绀�
+瑙�
+渚�
+涔�
+缂�
+姣�
+娈�
+绂�
+韫�
+鑼�
+娌�
+鑵�
+鏇�
+鍊�
+楠�
+淇�
+涓�
+宸�
+绯�
+there
+绗�
+娉�
+铏�
+闅�
+瀹�
+璋�
+娣�
+even
+鍢�
+鎺�
+杩�
+鏍�
+闅�
+閽�
+楗�
+瑁�
+鎼�
+鏈�
+鍤�
+鍨�
+鍊�
+sy@@
+钂�
+瑷�
+鐏�
+钁�
+韪�
+only
+den@@
+鑳�
+鏇�
+姹�
+濂�
+闄�
+鏅�
+鑷�
+璧�
+铓�
+渚�
+钘�
+閸�
+绌�
+灏�
+find
+鍋�
+椤�
+瀣�
+娴�
+area
+鐨�
+韫�
+af@@
+鏇�
+ger
+琚�
+娓�
+鍖�
+鎯�
+鏋�
+妲�
+璺�
+姹�
+瀚�
+宕�
+棰�
+涓�
+涓�
+鍝�
+椴�
+浣�
+鐤�
+渚�
+褰�
+浠�
+楦�
+寮�
+缂�
+妾�
+娓�
+灏�
+comm@@
+鐦�
+鍥�
+閿�
+鎯�
+琛�
+钄�
+榫�
+閰�
+ina
+灏�
+瀛�
+钄�
+甯�
+寮�
+杩�
+瑷�
+鎭�
+绱�
+鍚�
+瑙�
+鍗�
+need
+鍙�
+鑼�
+姹�
+閭�
+纾�
+鐒�
+铚�
+绫�
+淇�
+ath
+铔�
+缁�
+澹�
+璇�
+ing@@
+甯�
+鑼�
+鐮�
+has
+铦�
+鐭�
+鎷�
+涔�
+娴�
+another
+杈�
+鏈�
+娈�
+澹�
+鐏�
+绀�
+閽�
+鐡�
+搴�
+璇�
+姣�
+闈�
+楦�
+澧�
+鐠�
+鍜�
+鎯�
+鍖�
+鑵�
+鑻�
+鑻�
+涓�
+鑺�
+鍥�
+娣�
+棣�
+姒�
+鑽�
+鎽�
+閱�
+缂�
+甯�
+铔�
+鏇�
+钀�
+鑾�
+鐘�
+鎷�
+鐗�
+钑�
+骞�
+鍐�
+鍩�
+鑼�
+浣�
+鍣�
+ked
+port
+鏌�
+鍚�
+绔�
+闉�
+绯�
+鏍�
+瑜�
+鏉�
+闄�
+shi@@
+鏈�
+鍗�
+閽�
+鎷�
+walk
+閽�
+宀�
+琛�
+鑻�
+鐕�
+澧�
+鎴�
+ations
+璇�
+鍐�
+寮�
+鎺�
+鑵�
+娣�
+榧�
+濡�
+浜�
+淇�
+楣�
+鍗�
+浣�
+妫�
+does
+tes
+鎷�
+鍔�
+缁�
+ren@@
+璐�
+g@@
+娣�
+閽�
+妫�
+澧�
+鐤�
+楠�
+鎽�
+绁�
+鍏�
+鍧�
+int
+use
+娉�
+璧�
+鐢�
+钁�
+杈�
+鐐�
+鏃�
+楦�
+鑼�
+铻�
+鑹�
+鏅�
+閽�
+鍕�
+鍢�
+榫�
+钑�
+娓�
+閽�
+鍐�
+寮�
+棰�
+鐏�
+鍩�
+椴�
+浜�
+鐭�
+杞�
+a
+鍗�
+瑙�
+鍛�
+绁�
+rec@@
+閫�
+鎲�
+钂�
+鍏�
+涔�
+楦�
+鍗�
+搴�
+浠�
+how
+閾�
+韪�
+闅�
+閬�
+璞�
+low@@
+ak
+鍔�
+鍝�
+澶�
+proble@@
+es
+璇�
+鍝�
+鎶�
+绁�
+鍋�
+鎻�
+鐨�
+鐩�
+鍒�
+楠�
+鑽�
+楗�
+鑰�
+鑾�
+just
+绨�
+鐜�
+pl@@
+绫�
+鐝�
+钑�
+鑷�
+闂�
+宕�
+gra@@
+鐞�
+鍦�
+鐡�
+璧�
+闀�
+琚�
+鍏�
+鑺�
+铓�
+stu@@
+mee@@
+娌�
+浼�
+瑙�
+绛�
+搴�
+still
+棰�
+wat@@
+4
+缁�
+鍏�
+浜�
+sho@@
+鐝�
+楗�
+榛�
+than
+good
+l@@
+姊�
+蹇�
+鑽�
+韬�
+韫�
+鍛�
+鍦�
+鍞�
+闄�
+ue
+椴�
+纰�
+鎬�
+椋�
+country
+绮�
+鎬�
+椋�
+鐑�
+鍚�
+宓�
+椹�
+绾�
+in@@
+闂�
+棣�
+姒�
+绐�
+娉�
+纭�
+韬�
+th
+鑰�
+璐�
+wom@@
+鎺�
+绠�
+缁�
+鑸�
+鐒�
+鎸�
+闀�
+thirty
+闂�
+鎽�
+鍫�
+鐗�
+鏍�
+鍫�
+棣�
+鐩�
+t
+鏃�
+鍑�
+娲�
+閷�
+闊�
+por@@
+瀛�
+鑼�
+闂�
+娣�
+鍧�
+鐑�
+娲�
+gre@@
+鏁�
+鍝�
+鍒�
+ding
+閬�
+閽�
+澹�
+lo
+绾�
+鐮�
+鐏�
+lee
+鐜�
+up
+姊�
+鏃�
+浣�
+绔�
+缁�
+鐮�
+閰�
+鑻�
+鐒�
+绁�
+鑻�
+鍡�
+ail@@
+娈�
+om@@
+妫�
+缈�
+澧�
+钀�
+鍨�
+纰�
+cts
+娓�
+鐭�
+鎺�
+best
+閿�
+璋�
+鍠�
+闆�
+杈�
+鍟�
+鍡�
+璋�
+鐤�
+鐜�
+鍞�
+鍏�
+褰�
+婧�
+涓�
+妫�
+妗�
+妯�
+璺�
+铦�
+鍝�
+鍟�
+鏇�
+涔�
+绠�
+鍩�
+鏈�
+ear@@
+椴�
+ship
+鍚�
+绮�
+鑸�
+浼�
+瑙�
+鐕�
+閾�
+纭�
+鎾�
+鐦�
+thanks
+閿�
+鍦�
+contin@@
+渚�
+娴�
+妫�
+姝�
+ici@@
+鐝�
+瑜�
+鍒�
+婕�
+绠�
+缂�
+绡�
+椴�
+鐮�
+鍚�
+閮�
+蹇�
+鏍�
+鐦�
+楗�
+tw@@
+鎷�
+鐩�
+澹�
+妗�
+鍡�
+闉�
+鐢�
+閿�
+娑�
+鍐�
+閯�
+娣�
+杈�
+鍞�
+鏆�
+铓�
+璺�
+閮�
+闀�
+ku@@
+璧�
+濮�
+璇�
+纭�
+鑰�
+娑�
+day
+绗�
+away
+绋�
+楣�
+鐝�
+姣�
+閰�
+姹�
+姊�
+瀚�
+鍑�
+ces
+宸�
+鏅�
+鑲�
+鑾�
+鐥�
+缂�
+鎬�
+閯�
+鎼�
+fri@@
+浠�
+璇�
+瀹�
+鐝�
+鍦�
+寮�
+鎮�
+buil@@
+缁�
+澶�
+澶�
+绁�
+钃�
+鍦�
+渚�
+璺�
+璋�
+鑾�
+楂�
+杩�
+楣�
+鍗�
+鍡�
+浣�
+鎰�
+濯�
+娈�
+榻�
+濡�
+娈�
+鍡�
+閽�
+court
+韪�
+鑴�
+鑿�
+鐞�
+鍌�
+涓�
+铏�
+鍞�
+閫�
+椴�
+闀�
+鑲�
+寮�
+鏉�
+灞�
+鎭�
+钂�
+澶�
+鐜�
+鍧�
+gar@@
+ans
+鍢�
+宓�
+鍛�
+閰�
+灞�
+閳�
+楹�
+鏃�
+鏃�
+鐤�
+with
+瑙�
+灞�
+瓒�
+锠�
+瀵�
+鐬�
+灞�
+鏄�
+榄�
+琛�
+閽�
+閰�
+槌�
+鎴�
+鑺�
+鍗�
+gu@@
+闄�
+榛�
+缂�
+ch@@
+鎽�
+姊�
+鑳�
+鎾�
+鐤�
+鐮�
+el@@
+鍞�
+鑺�
+閫�
+ol
+缁�
+棣�
+鐘�
+bal@@
+椴�
+闊�
+鐒�
+鑳�
+绮�
+鏋�
+宓�
+鍙�
+she
+through
+绛�
+缈�
+鍗�
+se
+榄�
+鏍�
+mes
+鏅�
+璺�
+鎺�
+闃�
+鏅�
+鏉�
+st@@
+闈�
+鏂�
+绮�
+鑸�
+鐎�
+妫�
+鑼�
+闊�
+閻�
+鐏�
+榫�
+鍗�
+lion
+鏇�
+鍝�
+鐨�
+鍝�
+pe@@
+鎮�
+閫�
+娑�
+铔�
+浣�
+鐚�
+鐙�
+nine
+鍥�
+椋�
+鎬�
+鎱�
+鎱�
+淇�
+姹�
+鑲�
+闅�
+鍧�
+璧�
+娴�
+鐧�
+my
+濮�
+ill
+鑳�
+瑕�
+鑷�
+鐭�
+鐐�
+琛�
+鍓�
+棣�
+浼�
+鑹�
+濡�
+鑲�
+妾�
+soon
+姘�
+鐞�
+璋�
+light
+澶�
+seven@@
+鏃�
+鑺�
+en@@
+鐑�
+璇�
+鏀�
+闄�
+瑙�
+閾�
+姘�
+浣�
+night
+hou@@
+楣�
+鑶�
+鐐�
+鎶�
+鐝�
+ses
+婕�
+both
+妗�
+绗�
+閹�
+led
+鎶�
+鑶�
+铚�
+鑿�
+濞�
+鍥�
+鎻�
+娴�
+f@@
+鑺�
+鍚�
+sion
+閬�
+鐡�
+鎱�
+浠�
+閯�
+鐭�
+thou@@
+娌�
+鍞�
+鍖�
+璁�
+宓�
+楂�
+ine@@
+鎭�
+绐�
+-@@
+琛�
+鑶�
+纰�
+national
+it@@
+鐦�
+ci@@
+渚�
+l
+闄�
+鐓�
+鍘�
+鍘�
+鎮�
+绛�
+鐘�
+缃�
+缁�
+鏁�
+ys
+鎹�
+娈�
+濉�
+鎸�
+tal@@
+钀�
+鍗�
+鐢�
+鍚�
+铚�
+甯�
+绗�
+new
+鏄�
+璇�
+瑗�
+鐭�
+钘�
+鑻�
+th@@
+鍝�
+its
+铓�
+ran@@
+婢�
+eight
+璐�
+鍌�
+浜�
+缁�
+妲�
+绛�
+杩�
+閱�
+閷�
+韫�
+鐜�
+look
+鍦�
+棰�
+鏃�
+鍦�
+缁�
+op@@
+鍜�
+妲�
+鍐�
+涔�
+楦�
+鏌�
+铓�
+鎿�
+閿�
+濮�
+鎯�
+绠�
+濂�
+ra@@
+鐬�
+渚�
+鎭�
+宀�
+鍠�
+鎽�
+鍗�
+wee@@
+缇�
+cep@@
+fron@@
+濡�
+寰�
+绂�
+宸�
+澶�
+閯�
+re@@
+鍔�
+杩�
+鐙�
+鐟�
+妫�
+灞�
+鐨�
+闄�
+娈�
+浠�
+铦�
+缂�
+闀�
+鍝�
+ase
+row
+缂�
+stance
+浜�
+custom@@
+鎶�
+闉�
+铔�
+鍩�
+婕�
+鍑�
+铏�
+濮�
+鐥�
+閭�
+ss
+鎴�
+鎮�
+spe@@
+缇�
+鍚�
+閿�
+婀�
+绔�
+娣�
+瀛�
+3
+閮�
+鍗�
+fif@@
+婵�
+灏�
+绨�
+閿�
+鍟�
+鎳�
+闇�
+妫�
+绨�
+鎬�
+g
+姣�
+鐘�
+ffe@@
+闀�
+闁�
+鍚�
+椹�
+are@@
+鍩�
+蹇�
+婕�
+濞�
+渚�
+钄�
+鍊�
+椴�
+fr@@
+ful
+鍢�
+婊�
+楱�
+ility
+鍠�
+鎮�
+鍡�
+浜�
+纭�
+mer@@
+纾�
+闇�
+楹�
+鏇�
+铚�
+police
+闀�
+绗�
+鑻�
+闈�
+鍑�
+澶�
+璐�
+缂�
+鍡�
+娌�
+ened
+鑺�
+璇�
+灏�
+鐝�
+宕�
+ld
+x@@
+鎻�
+绾�
+缂�
+杞�
+搴�
+娓�
+楦�
+涔�
+鎯�
+peop@@
+姝�
+鍞�
+妯�
+鑶�
+fro@@
+鍝�
+鑵�
+闇�
+鍧�
+闇�
+鎺�
+濞�
+闀�
+宸�
+纰�
+钘�
+娲�
+鑽�
+鍥�
+缂�
+閽�
+椋�
+鍎�
+鑻�
+璨�
+鏌�
+钃�
+闃�
+璐�
+纰�
+鐙�
+鑹�
+鍠�
+绋�
+鏄�
+i'm
+璋�
+铚�
+杞�
+涔�
+瀵�
+鍟�
+铏�
+ster@@
+鍨�
+鍡�
+璁�
+ves
+again
+闅�
+甯�
+鍡�
+缁�
+鍏�
+鍗�
+鎶�
+浠�
+浠�
+鏍�
+鎷�
+钀�
+him
+鑽�
+娣�
+7
+閶�
+鏁�
+棰�
+ment
+瀚�
+妫�
+show
+璺�
+out@@
+姹�
+杩�
+姒�
+鏆�
+绯�
+鏅�
+9
+绋�
+鏇�
+钂�
+ture
+楝�
+閫�
+宀�
+鑺�
+鏄�
+鍩�
+骞�
+鐚�
+浼�
+pub@@
+鍗�
+鑽�
+瓒�
+娣�
+鍢�
+鎮�
+钘�
+浜�
+娓�
+pool
+绨�
+璋�
+鍣�
+绐�
+绁�
+闃�
+娑�
+鎺�
+鐧�
+鐤�
+鎼�
+婕�
+閿�
+閽�
+鑰�
+韪�
+楠�
+绋�
+閿�
+绻�
+缂�
+鍔�
+鍟�
+钑�
+浠�
+鏄�
+涓�
+婊�
+鏌�
+闀�
+鍝�
+鍑�
+鍣�
+鐟�
+鍡�
+绠�
+铚�
+鏈�
+璞�
+ap@@
+鍟�
+缈�
+鎰�
+peri@@
+铓�
+寮�
+绂�
+铓�
+鍧�
+鎹�
+绾�
+韫�
+for@@
+鑽�
+鑽�
+鎳�
+濂�
+槌�
+鐤�
+鎼�
+涓�
+骞�
+宀�
+鐗�
+铦�
+绲�
+绉�
+缂�
+at
+缃�
+鍡�
+宀�
+缁�
+鍦�
+鎭�
+鍙�
+鏂�
+鐧�
+鐓�
+闆�
+灏�
+閻�
+楹�
+榛�
+娈�
+閮�
+鍒�
+鍓�
+鎻�
+姣�
+鍣�
+fi
+姘�
+娉�
+妯�
+杩�
+瀚�
+榻�
+娈�
+澧�
+褰�
+鏅�
+鍜�
+鑺�
+鐫�
+鏌�
+鎴�
+灞�
+铏�
+闊�
+娑�
+濮�
+閶�
+sure
+鏃�
+娑�
+鐢�
+鍢�
+纭�
+som@@
+鎯�
+鐙�
+鍫�
+灞�
+鎰�
+li@@
+琛�
+璋�
+宥�
+宄�
+纰�
+鏆�
+h@@
+閺�
+鐦�
+铚�
+娴�
+钀�
+鑱�
+铓�
+姹�
+people
+濡�
+楦�
+鏄�
+鑺�
+鎸�
+褰�
+绔�
+娲�
+鐑�
+楣�
+鑳�
+鍏�
+鍜�
+妤�
+甯�
+濡�
+ant
+鑷�
+妗�
+鍒�
+鍥�
+na@@
+闉�
+妤�
+閫�
+鎯�
+鍗�
+闂�
+鑰�
+閭�
+绔�
+閽�
+鐜�
+閮�
+鏄�
+涔�
+閽�
+鏅�
+绗�
+鏍�
+鑺�
+灏�
+蹇�
+鍖�
+as@@
+棰�
+our@@
+that
+绋�
+閿�
+闊�
+鍒�
+寤�
+k@@
+teen
+骞�
+pic@@
+鍙�
+楠�
+妫�
+缇�
+鍨�
+鐘�
+濯�
+鍏�
+灏�
+涔�
+椴�
+鍒�
+澹�
+鑺�
+hotel
+浣�
+姘�
+鎮�
+棰�
+姹�
+缂�
+骞�
+绔�
+鍠�
+鐤�
+long
+骞�
+闀�
+閰�
+ings
+ood
+鏌�
+鍞�
+杈�
+绋�
+瑗�
+璁�
+绡�
+鍧�
+琚�
+鍗�
+鑷�
+姝�
+鏄�
+鎽�
+gh
+鑱�
+鐘�
+鏁�
+鐗�
+鏃�
+閿�
+鐜�
+浣�
+閯�
+婕�
+鍙�
+宸�
+鍛�
+where
+鎴�
+鍡�
+鐞�
+鍘�
+绐�
+cas@@
+鑸�
+鐢�
+鍑�
+璋�
+鏃�
+娌�
+鐙�
+婧�
+缁�
+鍔�
+婊�
+in
+瑜�
+fam@@
+妤�
+閲�
+纾�
+see
+鏂�
+浣�
+澹�
+澧�
+璇�
+around
+缇�
+娴�
+鐭�
+閾�
+provi@@
+钘�
+浼�
+闃�
+鍝�
+娼�
+绮�
+鍍�
+鍑�
+鐞�
+绉�
+娑�
+璞�
+闀�
+钂�
+鍙�
+棰�
+鑾�
+闃�
+鐥�
+鐖�
+瀣�
+婊�
+鐗�
+娌�
+鐠�
+绐�
+婀�
+鍠�
+寰�
+鑰�
+浠�
+铔�
+鍚�
+鏍�
+閮�
+璋�
+鑶�
+鍨�
+鎭�
+绛�
+娣�
+鍓�
+vie@@
+浼�
+first
+娓�
+槎�
+缂�
+韪�
+鍛�
+瀹�
+棰�
+钄�
+鎸�
+浜�
+澧�
+鍊�
+姊�
+鐚�
+椤�
+娉�
+楦�
+璧�
+鑱�
+楝�
+闅�
+鑳�
+椹�
+涓�
+閭�
+椴�
+闊�
+濠�
+sed
+it
+瀹�
+灞�
+浼�
+缈�
+閾�
+纾�
+閱�
+鐦�
+浣�
+闇�
+鑷�
+鍧�
+淇�
+鑸�
+杈�
+璋�
+鐢�
+绁�
+tell
+鍟�
+ace
+瀹�
+楠�
+娴�
+鍐�
+鑲�
+im@@
+win@@
+鐢�
+韫�
+绮�
+鑴�
+閬�
+next
+expe@@
+姒�
+韫�
+閭�
+stru@@
+娌�
+瀹�
+鏃�
+閿�
+渚�
+鎷�
+杈�
+浠�
+be
+娲�
+鎽�
+寰�
+棰�
+寰�
+楝�
+鎸�
+鎴�
+鍢�
+鏉�
+楠�
+鍔�
+鍝�
+闆�
+鎿�
+榇�
+琛�
+鑺�
+鎹�
+闇�
+com@@
+淇�
+浼�
+ory
+杞�
+鍗�
+璋�
+瀛�
+te@@
+閿�
+鐬�
+瀵�
+绯�
+鍫�
+涔�
+鎼�
+閺�
+浣�
+con@@
+鐞�
+art
+寰�
+濉�
+璁�
+鐬�
+rence
+婧�
+鍗�
+閫�
+闃�
+闃�
+濠�
+mil@@
+涓�
+濮�
+娴�
+搴�
+sing@@
+鍡�
+鍝�
+鐮�
+鍚�
+闂�
+璐�
+灞�
+濞�
+ce
+鍥�
+妤�
+鍏�
+椴�
+鍡�
+tely
+甯�
+閭�
+鎳�
+娆�
+ong
+閮�
+涓�
+breakfast
+宕�
+姗�
+鍋�
+娌�
+under@@
+tion@@
+闈�
+鍫�
+浠�
+閾�
+闅�
+铔�
+鐙�
+鎵�
+鐔�
+over@@
+妾�
+楦�
+妾�
+褰�
+锜�
+鑵�
+妲�
+娉�
+鑸�
+鐥�
+绉�
+姘�
+缃�
+鍟�
+鍟�
+鍐�
+鐤�
+宓�
+鍚�
+鑸�
+閲�
+mb@@
+瑁�
+妾�
+杈�
+鐪�
+婧�
+can
+鍞�
+濯�
+浣�
+鐙�
+浠�
+rent
+娌�
+璇�
+闇�
+濠�
+闆�
+eigh@@
+鐧�
+鐬�
+婢�
+娲�
+闃�
+ta@@
+渚�
+韬�
+鑾�
+楠�
+瀹�
+绺�
+birth
+钀�
+men@@
+绉�
+杞�
+鍒�
+fl@@
+楦�
+蹇�
+鑳�
+鏀�
+纾�
+椋�
+椴�
+閭�
+闃�
+鐨�
+鍗�
+鎼�
+闈�
+鍞�
+鎾�
+鏌�
+鍨�
+鑶�
+杈�
+姒�
+閭�
+閿�
+鎴�
+钄�
+绮�
+缈�
+鏀�
+鎮�
+娑�
+濯�
+淇�
+闀�
+姊�
+钃�
+鑹�
+guest
+椤�
+璀�
+鍏�
+鍥�
+鍊�
+閬�
+鏈�
+such
+绡�
+鍥�
+瀹�
+鎴�
+宓�
+濞�
+绠�
+妾�
+鐜�
+please
+褰�
+铚�
+鎬�
+鐧�
+鎬�
+闀�
+杩�
+璇�
+搴�
+寮�
+鑺�
+鍗�
+閫�
+棰�
+鏉�
+铇�
+妤�
+棰�
+鍚�
+鍫�
+婢�
+寮�
+娴�
+鍫�
+涓�
+鐒�
+on
+绾�
+宸�
+纭�
+瀛�
+绱�
+娌�
+鎴�
+灞�
+鑳�
+鍔�
+鐝�
+淇�
+妯�
+璁�
+璞�
+鍙�
+閽�
+闇�
+鐎�
+绯�
+鍣�
+璞�
+婀�
+娲�
+鑿�
+鎮�
+ree
+鍑�
+寰�
+閮�
+today
+鍕�
+瀣�
+铻�
+鎴�
+鐠�
+蹇�
+淇�
+瑷�
+搴�
+璐�
+璐�
+kind
+鎵�
+楠�
+鍜�
+鍑�
+璁�
+鎺�
+ated
+鑻�
+槌�
+鍣�
+鑼�
+govern@@
+绛�
+棰�
+鎰�
+娓�
+韪�
+缃�
+姹�
+韪�
+闄�
+鐤�
+闂�
+鎴�
+钂�
+缂�
+鏇�
+濠�
+鍐�
+闇�
+鏌�
+sent
+姘�
+et
+鍜�
+鍦�
+鍜�
+site
+sti@@
+姊�
+water
+鑸�
+鍤�
+铚�
+閫�
+婀�
+鏍�
+鍒�
+钖�
+ally
+璇�
+钘�
+閽�
+浼�
+鑾�
+纭�
+绐�
+sa@@
+鎰�
+锜�
+绉�
+闆�
+瑜�
+楣�
+娉�
+ner
+ast
+鑿�
+鏅�
+鏋�
+鍋�
+鍤�
+閬�
+su@@
+鎺�
+鍗�
+棣�
+鍔�
+鑳�
+rep@@
+娑�
+ther
+瀛�
+娑�
+鐙�
+涓�
+宸�
+鑴�
+鐢�
+鐝�
+閮�
+钄�
+鐤�
+搴�
+纭�
+瑁�
+楠�
+sequ@@
+杩�
+鐩�
+鍣�
+灏�
+鍜�
+铚�
+搴�
+闀�
+铦�
+瀹�
+鍗�
+寮�
+瀛�
+鐚�
+鐘�
+濡�
+钁�
+every@@
+铻�
+棣�
+ating
+澹�
+鐔�
+rela@@
+鍡�
+绾�
+閿�
+鍛�
+鎶�
+纾�
+鐤�
+缇�
+缁�
+閾�
+鎺�
+瀹�
+鑽�
+鐜�
+ser@@
+鍟�
+姘�
+鐩�
+鐤�
+楝�
+缁�
+閿�
+楝�
+鐡�
+楹�
+鏃�
+濞�
+鏁�
+璺�
+鐑�
+锠�
+te
+璇�
+閲�
+缈�
+鐝�
+鎱�
+椴�
+鍕�
+琚�
+鐟�
+tly
+搴�
+government
+鑽�
+闃�
+鐑�
+鍊�
+淇�
+楦�
+鍊�
+ound
+co@@
+绔�
+鑵�
+鏄�
+婵�
+鍟�
+鎻�
+娉�
+閮�
+鍨�
+杞�
+鏌�
+閰�
+鏉�
+鏅�
+寤�
+濂�
+閱�
+闀�
+璁�
+缂�
+榫�
+鐣�
+鑴�
+ma@@
+閱�
+鍡�
+涓�
+娈�
+榄�
+鐔�
+wr@@
+鍤�
+褰�
+鏍�
+americ@@
+璋�
+娉�
+鏌�
+楂�
+鐩�
+璇�
+鐦�
+钀�
+鍠�
+濯�
+蹇�
+闃�
+鏇�
+瑁�
+閿�
+something
+鐘�
+鐖�
+鐓�
+鎻�
+鑻�
+鍢�
+鑳�
+閾�
+灞�
+棰�
+閿�
+楠�
+娓�
+閭�
+鑴�
+婊�
+缃�
+鏁�
+榧�
+鐖�
+鎽�
+杈�
+鐢�
+鑻�
+鏁�
+鍐�
+钑�
+閮�
+鑰�
+闂�
+閫�
+鎷�
+灏�
+fe
+椴�
+棰�
+0
+room
+鑳�
+婢�
+濯�
+寤�
+閲�
+璐�
+闀�
+nine@@
+鎭�
+楣�
+鏃�
+閾�
+鍫�
+鍓�
+ket
+鏀�
+澧�
+娲�
+淇�
+ors
+璇�
+榛�
+鐝�
+璺�
+娴�
+瀛�
+mp@@
+鐙�
+韪�
+娓�
+閫�
+棰�
+鍔�
+缇�
+缇�
+闃�
+璺�
+瑜�
+涔�
+鎷�
+鐩�
+楦�
+鎶�
+閫�
+瑜�
+鎬�
+cou@@
+锜�
+cen@@
+鍌�
+鐮�
+椴�
+韫�
+restaurant
+鏉�
+鑼�
+灏�
+鑰�
+娣�
+韬�
+铚�
+鍢�
+璋�
+铦�
+鍫�
+濮�
+happ@@
+閾�
+妤�
+park
+鍔�
+娈�
+鐣�
+say
+缁�
+绾�
+婧�
+铏�
+绡�
+铚�
+鎯�
+璺�
+鍟�
+婧�
+楗�
+瑁�
+鍕�
+鏌�
+鎯�
+闄�
+娈�
+瀹�
+寰�
+绾�
+鐥�
+璋�
+鍙�
+鐘�
+閯�
+绮�
+鐪�
+鍧�
+濡�
+鍓�
+闆�
+鍌�
+瀚�
+鍢�
+鍜�
+鎰�
+绨�
+璧�
+绠�
+榫�
+鏀�
+鑿�
+鍧�
+濂�
+榛�
+鐞�
+娼�
+鏈�
+tually
+閾�
+涔�
+閱�
+娼�
+妲�
+绾�
+鐎�
+璇�
+鎱�
+濂�
+鍢�
+鎻�
+鏄�
+闈�
+鍙�
+ce@@
+瓒�
+閱�
+纰�
+鍣�
+婢�
+鐭�
+&
+鍘�
+鍟�
+鏅�
+鐐�
+ook
+鏂�
+鐩�
+濡�
+濞�
+鐕�
+绐�
+娉�
+also
+鑿�
+鐐�
+閫�
+鍩�
+鍑�
+婊�
+閾�
+瑙�
+鑾�
+le@@
+鍖�
+韪�
+閰�
+楣�
+enjoy
+闂�
+姣�
+绁�
+韬�
+閮�
+绗�
+涔�
+鐢�
+like
+鍚�
+鍘�
+鐖�
+鐗�
+璧�
+鍍�
+閽�
+娴�
+蹇�
+get
+鍐�
+妯�
+璇�
+韫�
+閼�
+鐣�
+婊�
+鎺�
+灏�
+war@@
+妗�
+鐡�
+姣�
+鑶�
+楂�
+閽�
+妗�
+纰�
+杈�
+鍞�
+绔�
+鐥�
+鑶�
+閿�
+鍢�
+闆�
+鐗�
+鏄�
+鏁�
+钑�
+浼�
+寰�
+瑗�
+鐩�
+鎲�
+娑�
+different
+after
+铏�
+浣�
+鐓�
+瀹�
+ori@@
+鏀�
+鍐�
+闆�
+妯�
+鍝�
+鐡�
+棣�
+鍞�
+鐐�
+鏃�
+鍘�
+钁�
+鐥�
+宸�
+闈�
+鍑�
+鏈�
+鐑�
+浠�
+鎭�
+鍠�
+璐�
+閮�
+楗�
+閾�
+婊�
+锠�
+钖�
+榻�
+瑜�
+榛�
+娑�
+n't
+纾�
+鍖�
+娌�
+闀�
+nice
+娴�
+鎮�
+娣�
+鎹�
+绠�
+鐬�
+鍕�
+灞�
+韫�
+韫�
+妲�
+绫�
+鏍�
+鑴�
+椤�
+妗�
+鑴�
+娆�
+铦�
+鍕�
+鍧�
+閰�
+鍞�
+绺�
+娆�
+鑶�
+璇�
+鍏�
+妤�
+濞�
+濞�
+闄�
+ple
+灏�
+骞�
+璞�
+妗�
+婊�
+楹�
+缃�
+鏈�
+鑰�
+姹�
+鐧�
+杈�
+閫�
+钄�
+璧�
+绉�
+鍜�
+鏂�
+璺�
+鑸�
+鑾�
+闂�
+姘�
+楠�
+妲�
+鐡�
+椁�
+鐬�
+娌�
+鏈�
+had
+椴�
+宓�
+nothing
+瀚�
+鎭�
+琛�
+杞�
+鏉�
+璧�
+娲�
+red
+鎷�
+鐙�
+鍗�
+铓�
+鐤�
+鎹�
+濠�
+鍥�
+姊�
+鍨�
+閫�
+楂�
+鏅�
+楠�
+瀛�
+鐐�
+鍠�
+鍨�
+铚�
+sts
+闃�
+鏈�
+鐔�
+缁�
+鍧�
+鑻�
+are
+瀵�
+鍚�
+鐨�
+鎹�
+鐐�
+b
+the
+鍝�
+闉�
+ir@@
+鎺�
+tation
+鍣�
+閰�
+蹇�
+纭�
+鑰�
+鍋�
+闆�
+纾�
+閿�
+over
+渚�
+濠�
+鍚�
+绔�
+man
+涔�
+鑻�
+缁�
+鍐�
+鍛�
+瀛�
+缂�
+鍩�
+鐘�
+楹�
+钃�
+鎶�
+澶�
+tri@@
+鏉�
+浣�
+鑾�
+di@@
+姣�
+璐�
+鐚�
+妗�
+so
+姘�
+鍙�
+鍝�
+婵�
+婀�
+鍏�
+璇�
+鐩�
+閽�
+楝�
+涓�
+椴�
+璨�
+閶�
+鍫�
+鑼�
+鎷�
+鐗�
+铦�
+闀�
+鍤�
+鏉�
+鍠�
+褰�
+col@@
+浠�
+娑�
+铓�
+濡�
+绠�
+闅�
+浜�
+鐤�
+瀣�
+鍠�
+鏀�
+am
+鍚�
+fe@@
+zero
+鐥�
+璇�
+骞�
+鐤�
+瀣�
+闄�
+绛�
+涓�
+sm@@
+楂�
+鍔�
+钀�
+璇�
+闀�
+鍧�
+鍜�
+姹�
+姒�
+宀�
+宕�
+ined
+chu@@
+绯�
+绁�
+鐚�
+濠�
+鎼�
+鍜�
+绠�
+杈�
+鎮�
+鑽�
+鎸�
+鎵�
+drive
+鎾�
+鑾�
+閯�
+鍐�
+绋�
+鎴�
+ould
+閾�
+缈�
+try
+鍦�
+鑹�
+妗�
+鍏�
+鎻�
+鍫�
+妗�
+ink
+email
+鐘�
+閾�
+鎷�
+槌�
+鏁�
+闆�
+濂�
+瑁�
+鎴�
+鍝�
+鏍�
+鍝�
+ds
+娴�
+宀�
+鎸�
+鑾�
+鑵�
+鏉�
+淇�
+鏂�
+铔�
+璇�
+鐐�
+鐠�
+鎬�
+绀�
+鍜�
+鐝�
+闊�
+閭�
+绁�
+鐨�
+娓�
+鍥�
+娼�
+娣�
+ter
+che@@
+濡�
+钀�
+鐔�
+鎵�
+浜�
+浜�
+鐦�
+鑸�
+鐨�
+璇�
+铏�
+娆�
+鎺�
+妫�
+宀�
+姣�
+鍗�
+缃�
+鐤�
+ali@@
+鏁�
+i@@
+绱�
+mu@@
+娑�
+鎼�
+濂�
+cri@@
+棣�
+缈�
+鎶�
+绛�
+鐜�
+闇�
+閾�
+婢�
+瀚�
+澶�
+鍜�
+鍥�
+寰�
+鐚�
+pre@@
+閫�
+绯�
+婕�
+鑱�
+鍙�
+鐦�
+缁�
+妫�
+绗�
+閾�
+閲�
+鎭�
+鐧�
+鑻�
+鏂�
+閱�
+妞�
+楸�
+娑�
+z
+鐩�
+par@@
+鎾�
+鎴�
+鍋�
+宸�
+鎵�
+busine@@
+妗�
+搴�
+鍧�
+problem
+鑸�
+centr@@
+fifty
+姊�
+皤柉
+restaurants
+beau@@
+fac@@
+璋�
+鑵�
+闃�
+瀛�
+绉�
+搴�
+鐣�
+渚�
+ang
+骞�
+涓�
+婧�
+褰�
+榄�
+璇�
+楦�
+閭�
+鐦�
+ay
+鑳�
+鍕�
+妲�
+姗�
+鐢�
+ide@@
+娌�
+閿�
+绁�
+鎱�
+浣�
+鑻�
+鏆�
+鏃�
+鎾�
+淇�
+灞�
+鎶�
+瀚�
+娴�
+椴�
+鏆�
+绐�
+鐐�
+婧�
+楂�
+绨�
+宥�
+宄�
+si@@
+瑙�
+鍗�
+鑱�
+ty
+鐚�
+鑵�
+鏅�
+琚�
+鎴�
+娉�
+鍟�
+鎴�
+钂�
+楹�
+姹�
+鑼�
+鍩�
+铔�
+寰�
+楦�
+鑹�
+椤�
+楂�
+寰�
+璞�
+纰�
+娆�
+钖�
+hi
+鍛�
+鑸�
+鍔�
+褰�
+'
+娓�
+缇�
+鏋�
+妯�
+寮�
+鍧�
+寰�
+棣�
+鍒�
+鐠�
+閿�
+閽�
+鍥�
+鎷�
+鍓�
+鎻�
+婊�
+缂�
+ach@@
+鏂�
+璇�
+瀵�
+瑁�
+鍚�
+should
+钂�
+绐�
+绀�
+鎴�
+褰�
+鎭�
+鍩�
+杩�
+閭�
+鐔�
+娉�
+涔�
+绡�
+center
+鐧�
+鏄�
+鐗�
+婵�
+鍣�
+鑻�
+ang@@
+give
+濮�
+绁�
+鎼�
+鎮�
+鐡�
+瀚�
+wit@@
+鐣�
+绁�
+婀�
+鎵�
+妗�
+閱�
+璋�
+铏�
+鐜�
+鏂�
+瀵�
+鏀�
+蹇�
+man@@
+鍍�
+money
+椋�
+鍥�
+鍚�
+鎵�
+j@@
+骞�
+娉�
+鎽�
+鍖�
+寤�
+閫�
+琚�
+妤�
+鎼�
+缂�
+ft
+宀�
+scho@@
+涓�
+铚�
+钃�
+鍗�
+鍊�
+鍠�
+铔�
+娈�
+缁�
+chan@@
+闇�
+妫�
+娼�
+钁�
+鍤�
+ed
+婕�
+闃�
+淇�
+寰�
+妲�
+閰�
+鍊�
+姗�
+send
+璋�
+鍡�
+缃�
+璐�
+鎼�
+鍧�
+韫�
+绶�
+闃�
+姝�
+闁�
+宀�
+鍊�
+璇�
+鍋�
+閱�
+鐥�
+绀�
+鍑�
+鐣�
+鎽�
+杩�
+鎺�
+鎸�
+濯�
+same
+铓�
+鎿�
+婢�
+鐪�
+鍓�
+瀚�
+楣�
+濞�
+鍑�
+鍘�
+鑷�
+鏋�
+鐐�
+鐑�
+鎺�
+娲�
+鍍�
+velo@@
+瑙�
+閫�
+have
+鐨�
+閰�
+鎬�
+鍙�
+缁�
+thir@@
+浠�
+绾�
+les
+鏈�
+寰�
+寰�
+come
+韬�
+姝�
+鐢�
+璺�
+br@@
+閹�
+璁�
+鐜�
+琛�
+楹�
+鏋�
+鎷�
+鑵�
+reas@@
+鑺�
+楣�
+more
+鍎�
+鎰�
+娣�
+韬�
+鐜�
+灞�
+姘�
+鍝�
+铏�
+sit@@
+瀹�
+澶�
+姊�
+绱�
+鐦�
+recei@@
+鍖�
+鍙�
+from
+鍐�
+鐣�
+璋�
+鑾�
+閿�
+pas@@
+椹�
+鏄�
+鍠�
+v@@
+鍛�
+'re
+闃�
+韪�
+璁�
+璁�
+榛�
+绛�
+seven
+浠�
+鑸�
+鎻�
+濡�
+绀�
+楂�
+浼�
+棣�
+璋�
+绡�
+閫�
+鐜�
+鐪�
+椹�
+all@@
+鍡�
+浜�
+娣�
+瑁�
+鍜�
+鐒�
+姘�
+ari@@
+宕�
+鎺�
+娌�
+瀵�
+杞�
+鏃�
+缁�
+test
+楹�
+鏋�
+鎸�
+鍙�
+椹�
+绛�
+鍧�
+椤�
+榧�
+鐐�
+鎺�
+濮�
+婧�
+搴�
+绠�
+鐕�
+鎷�
+鍛�
+鎰�
+琚�
+鐫�
+鐪�
+鍐�
+钁�
+but
+鐫�
+鎺�
+鍞�
+闄�
+鍠�
+鏅�
+婧�
+鑹�
+鑻�
+鑵�
+锜�
+鐕�
+鍊�
+浼�
+钀�
+姹�
+6@@
+鍍�
+铇�
+鐦�
+涔�
+鎺�
+涔�
+婧�
+鐥�
+lo@@
+铦�
+鍟�
+缂�
+part@@
+鍙�
+鏂�
+楦�
+閹�
+鎮�
+璇�
+瀛�
+鐛�
+鐜�
+姹�
+ary
+鍚�
+鎷�
+璇�
+鎵�
+榧�
+鐝�
+姗�
+闅�
+close
+濮�
+ty@@
+杩�
+楠�
+宕�
+go@@
+鍕�
+鍊�
+ble
+鐩�
+鍓�
+qu@@
+鍦�
+鑽�
+鑽�
+鐤�
+閰�
+绋�
+骞�
+浜�
+铔�
+娉�
+瀹�
+q
+妤�
+鍒�
+浣�
+娼�
+铻�
+閾�
+宸�
+鍛�
+鍨�
+鍟�
+鎴�
+浣�
+瀵�
+缈�
+鍟�
+fa@@
+w@@
+缁�
+鎶�
+璎�
+蹇�
+瓒�
+浣�
+铻�
+last
+杩�
+鐖�
+纰�
+寤�
+鍟�
+鏌�
+閰�
+鐑�
+鐓�
+绮�
+姹�
+妤�
+鑰�
+鎸�
+瑙�
+鑽�
+鑽�
+鐤�
+閬�
+浠�
+鐟�
+鎵�
+鎭�
+钘�
+缇�
+鍛�
+缂�
+浜�
+鏋�
+瀹�
+娴�
+back
+鎵�
+绡�
+sou@@
+娑�
+son
+缈�
+璁�
+鐞�
+鐜�
+鏍�
+闂�
+榫�
+浜�
+妗�
+sil
+骞�
+濠�
+鑴�
+鐤�
+姝�
+鍏�
+鏌�
+闀�
+娑�
+闇�
+寰�
+蹇�
+璀�
+绉�
+鑴�
+鐞�
+鐪�
+own
+閱�
+缁�
+ices
+宥�
+鑳�
+u@@
+宄�
+绠�
+涓�
+鐥�
+琛�
+閿�
+瀹�
+鐨�
+鎰�
+鐭�
+鐖�
+浜�
+瑁�
+楣�
+鎴�
+鎹�
+涔�
+鑳�
+褰�
+kil@@
+钁�
+姘�
+鎹�
+鎴�
+鐗�
+5
+dis@@
+鍥�
+瀛�
+鏌�
+姒�
+鍠�
+鎮�
+淇�
+c
+缂�
+瀵�
+je@@
+绔�
+way
+鎷�
+鐗�
+闃�
+绌�
+閽�
+婵�
+鐨�
+闂�
+鍛�
+闉�
+鐕�
+鑲�
+铻�
+绡�
+褰�
+娲�
+娓�
+鐮�
+杈�
+鎱�
+宕�
+璇�
+鎰�
+濮�
+椋�
+鍣�
+閾�
+瀵�
+鍜�
+浼�
+娈�
+瀹�
+铓�
+鏌�
+鏋�
+鐟�
+鎸�
+缁�
+鏈�
+缁�
+闅�
+鍍�
+绾�
+鎻�
+鑰�
+鑸�
+tom@@
+鏃�
+缈�
+products
+缂�
+鑲�
+闂�
+纭�
+鐮�
+铚�
+bu@@
+閸�
+鏅�
+闃�
+琛�
+铦�
+涓�
+楂�
+鐓�
+涔�
+绐�
+鑺�
+娅�
+ru@@
+deta@@
+璋�
+淇�
+妗�
+鑺�
+娉�
+浼�
+绮�
+鎻�
+棰�
+qui@@
+閯�
+鑲�
+灏�
+婊�
+妞�
+鐧�
+鐢�
+local
+fol@@
+鍋�
+涓�
+娑�
+閾�
+du@@
+鍣�
+鍊�
+鐝�
+鍦�
+澧�
+car@@
+鎾�
+鏍�
+璇�
+铻�
+铇�
+鎵�
+鎸�
+杞�
+娈�
+閰�
+high
+ach
+椴�
+鍟�
+think
+don't
+琛�
+cho@@
+鐩�
+鍟�
+鎬�
+婊�
+鑹�
+寰�
+鎾�
+娣�
+鑼�
+纭�
+妗�
+榄�
+娼�
+at@@
+浠�
+楣�
+娌�
+鎿�
+鐐�
+鐮�
+涔�
+璁�
+鍚�
+鐤�
+钁�
+澶�
+璺�
+铇�
+椴�
+婊�
+鑿�
+婊�
+鍔�
+鍊�
+浣�
+鑼�
+楂�
+闆�
+ile
+娆�
+宕�
+鍥�
+鍍�
+瀹�
+杈�
+妫�
+se@@
+鎹�
+鎵�
+閾�
+閾�
+浜�
+鐔�
+娲�
+濞�
+the@@
+鐥�
+绠�
+椹�
+绀�
+閮�
+璋�
+ack@@
+鏅�
+res
+lot
+绾�
+璇�
+ways
+璋�
+鐓�
+缁�
+鐐�
+鍗�
+灞�
+鐣�
+鎷�
+ar
+閬�
+鍛�
+椹�
+鑲�
+璺�
+鑾�
+绾�
+鍜�
+hu@@
+鍟�
+姝�
+蹇�
+涓�
+many
+鍕�
+ned
+their
+鐫�
+鍐�
+涔�
+宸�
+鍫�
+娲�
+閮�
+钁�
+this
+姣�
+閱�
+ton
+璇�
+鏃�
+铔�
+瑙�
+鐞�
+楱�
+鎹�
+imp@@
+灏�
+鎷�
+e@@
+姝�
+鍒�
+璺�
+three
+閿�
+渚�
+鎷�
+鎵�
+楗�
+鍓�
+娼�
+淇�
+鍡�
+绌�
+鍦�
+鎯�
+鎲�
+鎯�
+濂�
+inclu@@
+mo@@
+閾�
+鑷�
+娴�
+绁�
+really
+甯�
+dri@@
+妤�
+閭�
+寮�
+绡�
+鍏�
+up@@
+鎱�
+鑵�
+纰�
+鎸�
+璁�
+璞�
+婊�
+indi@@
+into
+瑜�
+閰�
+t@@
+绗�
+褰�
+娑�
+body
+ins
+婕�
+宄�
+down
+缂�
+鍓�
+绂�
+鍙�
+wa@@
+澶�
+闅�
+鎬�
+鎵�
+great
+娉�
+濞�
+瀛�
+褰�
+姣�
+铔�
+钀�
+娉�
+鑸�
+dge
+鐬�
+vo@@
+鍜�
+绁�
+鏋�
+鎲�
+鏂�
+gro@@
+鍊�
+楣�
+all
+妲�
+蹇�
+绲�
+瑁�
+two
+鍏�
+鏄�
+閬�
+绐�
+鍚�
+it's
+鍚�
+濡�
+閮�
+ies
+centre
+鍚�
+浜�
+闆�
+ask
+鍙�
+濯�
+铓�
+濂�
+鍨�
+妞�
+绡�
+鑱�
+绐�
+鍨�
+diffe@@
+璐�
+瑜�
+璞�
+鑵�
+鍜�
+鐪�
+鏁�
+榧�
+鏄�
+椤�
+鐞�
+鐮�
+鍍�
+涔�
+鐬�
+鎾�
+缇�
+绾�
+璧�
+鐒�
+姗�
+宓�
+闄�
+妤�
+鐗�
+楣�
+甯�
+may
+鍋�
+涓�
+鍏�
+鐮�
+婵�
+鐛�
+濂�
+鑵�
+闈�
+鏈�
+鍞�
+绾�
+瑁�
+cl@@
+hund@@
+浼�
+鐚�
+鐒�
+宀�
+杈�
+涓�
+鏌�
+绉�
+鑳�
+槌�
+宀�
+鍠�
+榛�
+瑙�
+forty
+绾�
+娉�
+椹�
+閾�
+钀�
+绛�
+铔�
+鐞�
+楦�
+杩�
+閾�
+read@@
+鍨�
+韪�
+濂�
+鍒�
+杞�
+鐩�
+榛�
+绾�
+chil@@
+鎵�
+鐙�
+璐�
+璐�
+槌�
+绡�
+der@@
+婊�
+宓�
+濡�
+鑷�
+璋�
+澶�
+闊�
+鎯�
+妫�
+宄�
+ms
+鑳�
+鎭�
+鏋�
+楣�
+鍒�
+璁�
+鍞�
+姊�
+鎹�
+鐢�
+蹇�
+杈�
+姊�
+姝�
+al@@
+娣�
+鑸�
+鎭�
+鐛�
+澶�
+鍠�
+锜�
+浼�
+sh
+'s
+濮�
+鐥�
+ck
+淇�
+楂�
+铚�
+鎰�
+鍛�
+mer
+妗�
+楝�
+鍨�
+鍥�
+鍝�
+榫�
+槌�
+楠�
+鐮�
+娉�
+鐚�
+鑼�
+鑼�
+cha@@
+small
+鍊�
+涔�
+濂�
+楣�
+鐥�
+濂�
+杈�
+sting
+鍐�
+璧�
+娉�
+缇�
+鎮�
+鐒�
+鐬�
+绱�
+鍗�
+take
+槌�
+鑿�
+濮�
+杈�
+鍢�
+fast
+鍥�
+鍑�
+绾�
+鍜�
+绠�
+well
+閽�
+he@@
+杈�
+楣�
+unk@@
+璇�
+娉�
+涓�
+闀�
+楠�
+ve
+瀵�
+pay
+榇�
+鐫�
+姘�
+鐗�
+娲�
+灏�
+quo@@
+妞�
+鑺�
+闄�
+鑰�
+鏌�
+鐗�
+铓�
+much
+most
+now
+singapore
+涓�
+娲�
+鐕�
+鍟�
+鑳�
+濯�
+纰�
+婵�
+闄�
+鎵�
+鍔�
+鎱�
+绗�
+娉�
+閯�
+hote@@
+缃�
+娌�
+钁�
+锠�
+浜�
+椴�
+鍑�
+钀�
+绫�
+鑳�
+鍝�
+渚�
+鏅�
+鍜�
+鏉�
+閭�
+鐢�
+鑳�
+鍘�
+鍢�
+鍠�
+is
+闇�
+浠�
+槌�
+閴�
+鐚�
+绾�
+鍐�
+闃�
+楗�
+瀹�
+璞�
+鍎�
+鐚�
+鐎�
+鑽�
+婊�
+鑼�
+閰�
+榧�
+鏃�
+灞�
+姒�
+s@@
+鍛�
+椹�
+钖�
+楣�
+棣�
+楣�
+绾�
+thank
+杞�
+娓�
+闀�
+cost
+姹�
+璋�
+鐢�
+publi@@
+鍌�
+鎶�
+鏉�
+瑁�
+姝�
+閺�
+鐘�
+韫�
+鎰�
+鏂�
+able
+ind
+鐙�
+闆�
+濡�
+宸�
+鍢�
+绛�
+鍠�
+鑸�
+鍒�
+fi@@
+company
+閮�
+鐬�
+瑜�
+娓�
+宸�
+鑻�
+鍐�
+鏆�
+鍨�
+鎴�
+婧�
+鍓�
+钁�
+鐚�
+钄�
+宀�
+閭�
+any
+pri@@
+鍗�
+鍩�
+棣�
+鍑�
+鏌�
+婧�
+鍚�
+铚�
+鐐�
+寰�
+inve@@
+妗�
+frien@@
+閾�
+搴�
+寤�
+瑾�
+鍡�
+蹇�
+i'@@
+铻�
+鑳�
+un@@
+閾�
+閰�
+榉�
+wi
+鐪�
+璺�
+姹�
+閽�
+閽�
+闆�
+闄�
+闈�
+铔�
+榛�
+鑴�
+鍙�
+鏋�
+鏁�
+sk@@
+缂�
+鑿�
+鍕�
+姹�
+鑳�
+娲�
+娲�
+ers
+楂�
+瀹�
+鑱�
+宓�
+鍥�
+娣�
+鍨�
+娆�
+oms
+鎻�
+before
+鐣�
+楗�
+绉�
+鑾�
+鍔�
+鐐�
+鍖�
+闄�
+钑�
+铦�
+po@@
+鍖�
+year
+姗�
+pping
+娉�
+鎵�
+鐞�
+鍙�
+鐜�
+褰�
+缂�
+鎬�
+閬�
+鍧�
+sta@@
+鐥�
+鍩�
+鍙�
+姘�
+鑴�
+鏄�
+ments
+瀹�
+鐩�
+鎯�
+棣�
+缁�
+閬�
+鎵�
+钄�
+宕�
+闃�
+钁�
+娈�
+娼�
+姣�
+ro@@
+闈�
+涓�
+tional
+闂�
+娑�
+绗�
+n
+闀�
+铚�
+鑳�
+琛�
+鐚�
+楣�
+淇�
+璞�
+浜�
+鐥�
+钃�
+楠�
+鎵�
+缁�
+绮�
+鏈�
+鍑�
+榄�
+閲�
+ars
+閫�
+clo@@
+甯�
+閬�
+璁�
+瑾�
+鐗�
+鍒�
+鎵�
+宄�
+9@@
+鏄�
+杞�
+瀣�
+them
+绐�
+韫�
+楠�
+婀�
+鍫�
+宸�
+濠�
+楠�
+铻�
+閰�
+ag@@
+闂�
+婊�
+閮�
+鏈�
+supp@@
+鍊�
+鑵�
+瑜�
+鏋�
+婕�
+浣�
+鐓�
+娌�
+鑲�
+experi@@
+浜�
+鍫�
+瀵�
+绉�
+every
+閾�
+铔�
+鎿�
+a@@
+槌�
+淇�
+ze
+寮�
+瓒�
+缈�
+娑�
+鐩�
+閬�
+閬�
+灞�
+缁�
+cont@@
+閮�
+den
+浠�
+璇�
+绮�
+闀�
+婧�
+鍟�
+璐�
+杞�
+鐚�
+钖�
+鑳�
+鎶�
+than@@
+king
+鐕�
+绗�
+楦�
+钃�
+宄�
+ent
+鎼�
+纾�
+鏄�
+濡�
+鐜�
+鍙�
+娓�
+褰�
+lim
+瀛�
+鍥�
+we@@
+缁�
+椹�
+鏋�
+鏂�
+璧�
+纰�
+婵�
+鍐�
+鍚�
+浣�
+because
+鏅�
+椁�
+鐬�
+鏍�
+韫�
+鑽�
+灏�
+渚�
+姘�
+鐐�
+鎶�
+涓�
+娼�
+娼�
+mon@@
+鍩�
+鏉�
+鍏�
+鎹�
+鎬�
+姝�
+f
+near
+鍒�
+鎼�
+楦�
+淇�
+鑰�
+鐗�
+鐬�
+楝�
+鎯�
+bro@@
+娌�
+娴�
+pe
+閲�
+vi@@
+jal@@
+鎷�
+鍐�
+鏆�
+榄�
+鐥�
+鐩�
+鏋�
+绉�
+鏉�
+閮�
+鍍�
+鏄�
+瓒�
+sen@@
+family
+宀�
+姒�
+铔�
+缁�
+鏉�
+楣�
+閽�
+鎷�
+dly
+鑻�
+閿�
+璺�
+纰�
+閽�
+娣�
+槌�
+娴�
+鏌�
+妗�
+鎰�
+瑁�
+閭�
+鎭�
+妤�
+娌�
+ban@@
+ssi@@
+槌�
+瑜�
+閽�
+y
+鎼�
+楠�
+鍧�
+濞�
+閯�
+琚�
+鍖�
+鍘�
+鑹�
+闅�
+鑸�
+韫�
+鏉�
+鑳�
+鐥�
+鍑�
+鎲�
+ll
+鐫�
+绐�
+鐮�
+闆�
+鍊�
+绫�
+楗�
+浠�
+绗�
+闉�
+绛�
+鏍�
+鎻�
+娲�
+鍨�
+妾�
+鐪�
+鍋�
+闂�
+濮�
+灏�
+鐮�
+鎬�
+鎵�
+鎭�
+宀�
+浜�
+鍨�
+韪�
+娉�
+鎴�
+杞�
+鐑�
+澶�
+姝�
+宸�
+澹�
+鍙�
+缁�
+宸�
+閭�
+妞�
+纭�
+鐣�
+甯�
+娌�
+姒�
+蹇�
+濡�
+鐨�
+璁�
+閾�
+杞�
+琛�
+钂�
+钑�
+things
+鑵�
+鍧�
+闉�
+姒�
+闇�
+鍨�
+ous
+绮�
+鏋�
+钖�
+鑳�
+榫�
+缁�
+ning
+med
+鎸�
+璇�
+璇�
+浣�
+鍗�
+杈�
+鑺�
+鍙�
+缈�
+灏�
+闈�
+閰�
+鍜�
+鏆�
+濮�
+璨�
+澧�
+鍖�
+been
+澧�
+鑺�
+sc@@
+濡�
+鐙�
+宀�
+ants
+璋�
+闉�
+濠�
+one
+韪�
+璁�
+land
+骞�
+杌�
+鏅�
+wi@@
+鐟�
+渚�
+鍟�
+鏈�
+鏋�
+濂�
+鍜�
+瑷�
+鑷�
+纭�
+甯�
+dent
+鎴�
+鐦�
+娈�
+鍌�
+oun@@
+鏋�
+灞�
+閲�
+鑺�
+璇�
+閽�
+鍫�
+uring
+璇�
+琛�
+棣�
+榫�
+璁�
+stre@@
+濡�
+椹�
+钁�
+妲�
+娲�
+side
+姘�
+瀛�
+鐙�
+姝�
+鍥�
+鎰�
+杩�
+pu@@
+right
+璧�
+闃�
+mber
+璋�
+town
+鐩�
+鏁�
+楗�
+loc@@
+spa
+姗�
+鍓�
+钂�
+濮�
+鍘�
+閾�
+濂�
+寮�
+鏍�
+楣�
+绯�
+楱�
+闆�
+瑁�
+鎷�
+榧�
+some
+鎼�
+鍧�
+钃�
+ice
+鍗�
+ad@@
+鐦�
+婀�
+姘�
+璋�
+缂�
+ard
+鏍�
+杩�
+娴�
+绉�
+钀�
+always
+姹�
+韪�
+鏉�
+ded
+楂�
+绉�
+婀�
+绮�
+灞�
+妲�
+鍨�
+璧�
+鎯�
+lar
+钖�
+杩�
+p
+濉�
+ga@@
+ey
+ho@@
+鎭�
+鏅�
+娉�
+鑼�
+鍡�
+缁�
+lit@@
+娓�
+閬�
+娲�
+鏅�
+婧�
+ying
+鏋�
+鏃�
+閫�
+鐝�
+绾�
+缃�
+ons
+宥�
+鐟�
+瑁�
+鎼�
+6
+鍜�
+鍞�
+鐟�
+鐫�
+鏂�
+din@@
+浼�
+楠�
+鍑�
+鐦�
+鍍�
+闉�
+鍏�
+浼�
+鏌�
+甯�
+宄�
+閯�
+鎶�
+an@@
+鐗�
+loca@@
+绌�
+鎳�
+2
+amer@@
+绋�
+鍙�
+bra@@
+鎷�
+str@@
+res@@
+娌�
+楗�
+pen@@
+鍘�
+鍌�
+ality
+寤�
+寮�
+澶�
+鐫�
+闆�
+鏅�
+鍓�
+璧�
+鐤�
+鐮�
+褰�
+min@@
+寰�
+闃�
+tions
+濂�
+钀�
+閭�
+鍋�
+浼�
+er
+绛�
+铔�
+business
+椤�
+鐦�
+娲�
+閽�
+瑙�
+鏀�
+鍔�
+鎾�
+break@@
+姘�
+婕�
+sor@@
+鍧�
+甯�
+澧�
+ation
+鐬�
+绋�
+鎱�
+鑲�
+韬�
+绯�
+缇�
+璞�
+us
+鐐�
+楗�
+鎸�
+鎸�
+鏋�
+dr@@
+閾�
+濂�
+妲�
+缁�
+鎿�
+铏�
+閽�
+鑳�
+鍑�
+杈�
+铏�
+閾�
+鏉�
+鐮�
+璧�
+娼�
+鍚�
+榘�
+鍚�
+杩�
+婊�
+寮�
+ff
+鐥�
+铔�
+瑙�
+鏉�
+鍢�
+鍋�
+璧�
+鐑�
+瀛�
+閽�
+榫�
+閽�
+鐫�
+鎾�
+big
+绗�
+淇�
+閿�
+鍛�
+娆�
+cle@@
+鐝�
+娴�
+澧�
+hel@@
+褰�
+濮�
+鎷�
+闆�
+hi@@
+閽�
+澹�
+骞�
+鍗�
+鐥�
+婢�
+闀�
+鑸�
+鍏�
+缁�
+妫�
+灏�
+绐�
+鐕�
+鑶�
+闀�
+瑁�
+鍔�
+resta@@
+寤�
+瀹�
+钃�
+濞�
+鐚�
+闃�
+锜�
+鎭�
+璁�
+铚�
+of@@
+鎬�
+绗�
+鐬�
+璧�
+宀�
+绂�
+鏄�
+濂�
+閽�
+鎱�
+婊�
+ack
+璺�
+璐�
+宸�
+瀵�
+閾�
+pro@@
+鏈�
+mor@@
+绠�
+涓�
+ready
+姝�
+璺�
+缂�
+妗�
+璁�
+鎽�
+鐘�
+椹�
+鍜�
+閾�
+缁�
+鍙�
+閬�
+閿�
+閲�
+绗�
+缂�
+宓�
+鑶�
+甯�
+娉�
+槌�
+瀚�
+浠�
+鎹�
+寰�
+each
+vil@@
+濯�
+琚�
+瑁�
+浣�
+璧�
+鏈�
+绗�
+鍟�
+杞�
+鎺�
+褰�
+姘�
+got
+缂�
+锠�
+鏀�
+瀵�
+楠�
+鍣�
+ar@@
+妫�
+鐤�
+璞�
+绁�
+琛�
+鍖�
+鐜�
+瑙�
+搴�
+浜�
+绡�
+閾�
+鍜�
+绂�
+鑹�
+鍝�
+hope
+绯�
+濞�
+绐�
+楂�
+闃�
+鎳�
+鍙�
+绂�
+绌�
+娓�
+閭�
+鑲�
+鏉�
+鑲�
+鍨�
+骞�
+ct
+鑻�
+闅�
+wh@@
+瀹�
+鐓�
+鏌�
+闀�
+鑰�
+kes
+婵�
+鐥�
+work
+鍚�
+褰�
+鏍�
+绛�
+璐�
+灏�
+ere
+娼�
+鐭�
+绺�
+鐟�
+娌�
+婧�
+婕�
+rooms
+闇�
+鍜�
+e
+鐝�
+浠�
+鐪�
+閱�
+绁�
+榧�
+绐�
+ia
+hundred
+鐡�
+灏�
+no@@
+瑗�
+娼�
+妤�
+鍌�
+铚�
+yes
+铔�
+sig@@
+gs
+绛�
+鍥�
+璋�
+bur@@
+璺�
+椴�
+鎯�
+鑲�
+dy
+铻�
+闇�
+鐪�
+閮�
+瀹�
+鐣�
+鍒�
+缈�
+璇�
+璺�
+or
+棰�
+璺�
+娣�
+鑷�
+妤�
+灞�
+璧�
+缇�
+you
+鍜�
+als
+鏂�
+鐣�
+鏅�
+蹇�
+鑲�
+瀹�
+鍑�
+瑜�
+ba@@
+鎽�
+鐔�
+绡�
+涔�
+缁�
+娌�
+鐬�
+鍝�
+鑸�
+鐢�
+浜�
+鐟�
+韪�
+榛�
+椴�
+cal@@
+鐠�
+enty
+鍓�
+娲�
+瀛�
+绁�
+澶�
+宀�
+鎷�
+nineteen
+cause
+鎰�
+缈�
+鐬�
+鏄�
+寮�
+鎽�
+涔�
+鍜�
+鍕�
+浼�
+鐟�
+姗�
+涓�
+閾�
+鎬�
+缁�
+鑶�
+5@@
+鎵�
+to
+鐚�
+鐞�
+缇�
+鍙�
+鐙�
+鐪�
+鐑�
+铓�
+鍎�
+鎻�
+ber@@
+1
+鎺�
+瑁�
+钘�
+r@@
+squ@@
+椴�
+娼�
+鏅�
+娑�
+楦�
+瑙�
+璇�
+鍗�
+as
+寮�
+鑴�
+閾�
+鍐�
+鎳�
+鍟�
+娑�
+鎵�
+鍨�
+妫�
+璧�
+鍨�
+闀�
+鎬�
+宄�
+鎯�
+缂�
+ass
+璇�
+tive
+never
+鏄�
+ence
+鑰�
+寮�
+鏈�
+鏋�
+瑗�
+濂�
+绁�
+楠�
+缇�
+璞�
+鐦�
+璐�
+绂�
+鍝�
+绁�
+铻�
+閿�
+瀛�
+st
+蹇�
+鎺�
+鏄�
+鍝�
+楣�
+鐤�
+閬�
+锠�
+鎭�
+鐙�
+鎲�
+鎮�
+寮�
+鑴�
+soci@@
+鐖�
+home
+濂�
+鎳�
+鐖�
+甯�
+瑗�
+闄�
+ters
+ted
+鏅�
+鏄�
+eas@@
+ven@@
+韫�
+ac@@
+姝�
+fas@@
+鎶�
+鐗�
+娴�
+姒�
+lan@@
+宸�
+鍒�
+secon@@
+椤�
+涓�
+椴�
+鍡�
+out
+鍑�
+瑜�
+鐟�
+鐝�
+鎯�
+鏂�
+鐩�
+鍦�
+did
+date
+闄�
+鐪�
+婀�
+璋�
+鎾�
+绀�
+鎶�
+鏃�
+鍊�
+锜�
+produ@@
+蹇�
+free
+鐡�
+搴�
+鏅�
+鍋�
+楹�
+缂�
+鍞�
+鏉�
+鎴�
+鍧�
+鐨�
+鎷�
+绨�
+鎬�
+璐�
+闄�
+鍩�
+鐨�
+绱�
+閿�
+鑻�
+鑿�
+鍤�
+鍏�
+瀚�
+闈�
+d
+灏�
+棰�
+鑻�
+de@@
+inc@@
+绛�
+娴�
+绐�
+涔�
+澹�
+pi@@
+鑽�
+鎰�
+鐮�
+宸�
+ke
+鏃�
+鍜�
+鐭�
+濠�
+缁�
+绾�
+濂�
+琚�
+鍠�
+璐�
+閸�
+閫�
+days
+鐤�
+绛�
+楂�
+閿�
+淇�
+缂�
+閿�
+楠�
+belie@@
+璺�
+宀�
+鐫�
+铚�
+閾�
+闂�
+楹�
+瓒�
+閿�
+褰�
+缂�
+鐢�
+鑻�
+閽�
+ph@@
+ef@@
+鐏�
+閵�
+濉�
+娣�
+楦�
+鎾�
+娴�
+though
+鎴�
+av@@
+鑽�
+瑕�
+road
+wn
+绾�
+甯�
+瑁�
+棰�
+end
+姹�
+椹�
+8
+妞�
+鐗�
+ties
+渚�
+妯�
+鎵�
+鍚�
+钑�
+鍨�
+鑼�
+娉�
+wor@@
+鑹�
+娆�
+鐝�
+寤�
+鍒�
+鐩�
+绨�
+bus
+ten@@
+check
+纭�
+姒�
+琚�
+鍘�
+棣�
+姗�
+娑�
+鎶�
+鍏�
+棰�
+鎵�
+娓�
+搴�
+鐛�
+鐦�
+鍠�
+鏈�
+韪�
+闀�
+绯�
+缈�
+鍏�
+鑻�
+gi@@
+椤�
+铓�
+鐞�
+鍘�
+妲�
+婊�
+閽�
+ple@@
+鍙�
+鍥�
+鐓�
+鏉�
+閾�
+涓�
+浠�
+鍜�
+鑾�
+璇�
+鍠�
+鏃�
+鏋�
+棰�
+鍦�
+闇�
+鑰�
+闃�
+宓�
+楸�
+鍊�
+me
+鍜�
+sing
+鐪�
+缇�
+浜�
+姗�
+鑿�
+宸�
+鏌�
+璧�
+鏆�
+d@@
+鎹�
+world
+闅�
+閼�
+鎹�
+杞�
+鎸�
+鍟�
+鑱�
+鐐�
+婀�
+瑭�
+楗�
+鏌�
+鎭�
+鎺�
+鐖�
+鏂�
+绐�
+姝�
+鍒�
+瀹�
+椁�
+榈�
+鏄�
+姒�
+閫�
+绮�
+淇�
+闊�
+浠�
+缃�
+鐮�
+钃�
+铇�
+缂�
+going
+閬�
+your
+ever@@
+鍒�
+娣�
+鍐�
+濡�
+閽�
+鎬�
+vern@@
+z@@
+寮�
+鐮�
+铚�
+楗�
+鍐�
+琛�
+闊�
+瀵�
+铏�
+鐜�
+3@@
+tho@@
+闂�
+鏃�
+鐓�
+宥�
+娑�
+榫�
+ko@@
+ge@@
+閬�
+閮�
+瑜�
+钖�
+閭�
+瀚�
+鍙�
+瀚�
+婕�
+gue@@
+钘�
+鑷�
+灞�
+ily
+鏃�
+鐥�
+鍩�
+鍥�
+淇�
+ours
+钃�
+娓�
+閿�
+鏈�
+闄�
+璧�
+make
+鐏�
+姹�
+鍩�
+鍚�
+鏍�
+缈�
+纾�
+姹�
+妞�
+閿�
+鎼�
+钂�
+闊�
+鎾�
+绾�
+绗�
+order
+鍧�
+浼�
+val@@
+鐑�
+姊�
+鐟�
+闄�
+go
+缁�
+鐞�
+婀�
+纭�
+鐔�
+瑙�
+渚�
+寰�
+鐗�
+绉�
+鐭�
+绁�
+璺�
+age
+鍒�
+缂�
+澶�
+闃�
+鍒�
+am@@
+鑻�
+姝�
+cess
+钃�
+he
+鍠�
+鐣�
+閯�
+璁�
+闆�
+鍣�
+sel@@
+閽�
+鑳�
+韫�
+help
+鎹�
+鑺�
+鑲�
+鎺�
+鏃�
+璎�
+鐢�
+ort
+鎼�
+鍝�
+楠�
+鍚�
+鍙�
+鍊�
+鑲�
+鎲�
+绔�
+product
+妫�
+榛�
+鐮�
+鎰�
+鏄�
+闃�
+榄�
+鎸�
+鐚�
+pa@@
+鍑�
+鍘�
+浣�
+椴�
+绮�
+楣�
+濮�
+鎶�
+绫�
+part
+found
+鍡�
+鎻�
+铔�
+绫�
+鐩�
+瑁�
+鏆�
+濡�
+鍠�
+鎯�
+wha@@
+绐�
+ks
+姗�
+缁�
+鑿�
+楗�
+ste@@
+鐚�
+鑺�
+鎼�
+tain
+street
+鍛�
+鎳�
+琚�
+鑲�
+on@@
+浜�
+璋�
+妞�
+鑾�
+鏍�
+韬�
+棰�
+鍦�
+鍖�
+mail
+绋�
+骞�
+鑴�
+閮�
+鎷�
+fo@@
+閼�
+鏀�
+la
+杞�
+鎺�
+鑺�
+can't
+褰�
+瑙�
+閭�
+鍩�
+鑾�
+浼�
+鑵�
+闃�
+tre@@
+鐪�
+璐�
+闈�
+閽�
+point
+鍍�
+搴�
+鍏�
+杩�
+绌�
+閫�
+婧�
+鍜�
+浠�
+缁�
+鍙�
+鍡�
+閫�
+渚�
+鎶�
+缇�
+娆�
+鑰�
+閿�
+缃�
+璺�
+姹�
+璧�
+绱�
+鎺�
+鍟�
+鑶�
+鎹�
+绂�
+宕�
+鏍�
+鎺�
+璁�
+y@@
+鐟�
+璐�
+鎸�
+楣�
+鍎�
+槌�
+楠�
+閲�
+鐭�
+娼�
+ort@@
+鐥�
+鏃�
+o
+鎲�
+闀�
+铚�
+澹�
+钁�
+鑱�
+鐏�
+绔�
+鎬�
+m@@
+璇�
+韬�
+娉�
+would
+缂�
+妯�
+杩�
+铔�
+ls
+楣�
+椴�
+鑼�
+缃�
+ques@@
+鐣�
+鍘�
+缂�
+鍔�
+鎷�
+钀�
+鍊�
+鍋�
+闀�
+韪�
+瓒�
+鎵�
+妞�
+鐥�
+鍙�
+绉�
+thing
+q@@
+fre@@
+鍓�
+beach
+鑸�
+榛�
+鎵�
+楗�
+娆�
+楠�
+钃�
+閭�
+鐤�
+'@@
+鍚�
+鎾�
+鑻�
+铚�
+mar@@
+妗�
+made
+鐓�
+瑗�
+鍨�
+濮�
+閫�
+鏌�
+鍩�
+鎬�
+铓�
+little
+娈�
+鐐�
+铔�
+浼�
+绂�
+鐫�
+鎹�
+棰�
+鐚�
+锜�
+宀�
+o@@
+绾�
+濡�
+闃�
+鐜�
+钂�
+瀵�
+瀛�
+鎯�
+娲�
+娌�
+閾�
+闀�
+娼�
+鏉�
+tal
+闀�
+铏�
+槎�
+妞�
+绨�
+閿�
+椤�
+浠�
+棰�
+鎺�
+鑰�
+鑽�
+鎾�
+璋�
+娌�
+鎯�
+纰�
+鐨�
+宄�
+鐐�
+鍘�
+鎷�
+寰�
+甯�
+铚�
+鑾�
+杩�
+璇�
+鍠�
+sequence
+鎰�
+ure
+鏋�
+thous@@
+妲�
+绉�
+鑿�
+鑿�
+ten
+鐧�
+鐝�
+婀�
+鐡�
+鍚�
+濡�
+鍐�
+鍌�
+铓�
+鑽�
+瀛�
+鍖�
+鍫�
+鑽�
+缁�
+鍒�
+des
+1@@
+鐣�
+瑁�
+璧�
+ving
+鍏�
+ly
+鐫�
+閬�
+鐞�
+淇�
+宀�
+铔�
+钂�
+nor@@
+閽�
+楹�
+绾�
+coun@@
+鏉�
+瀹�
+鍚�
+铦�
+婀�
+鎯�
+enjo@@
+鍗�
+鐗�
+璇�
+璋�
+鎽�
+铻�
+鐒�
+鐩�
+mple
+钀�
+鐏�
+鐣�
+when
+鐑�
+淇�
+琛�
+榫�
+璋�
+鍞�
+妤�
+鐥�
+鏇�
+缇�
+缃�
+鑴�
+寤�
+sur@@
+鎷�
+娲�
+婀�
+楦�
+鍐�
+璺�
+school
+灏�
+鎸�
+鐤�
+璁�
+self
+鎷�
+婧�
+鍨�
+鐬�
+绗�
+thousand
+涔�
+鍣�
+lie@@
+娌�
+淇�
+鐏�
+璧�
+鐮�
+閫�
+鏍�
+loo@@
+缃�
+槌�
+缈�
+閾�
+璇�
+閰�
+浣�
+姝�
+鐟�
+鐪�
+鐠�
+鎷�
+u
+棰�
+绗�
+ur@@
+铦�
+铔�
+number
+棣�
+place
+浼�
+鐑�
+ver@@
+娣�
+鍤�
+榧�
+璎�
+瓒�
+鎭�
+鎼�
+浼�
+鏉�
+鐞�
+宕�
+鑻�
+鍏�
+鐔�
+鍦�
+娉�
+姣�
+very
+鐞�
+瀛�
+鎵�
+鎭�
+t's
+鍩�
+do
+鏀�
+鏄�
+闈�
+feel
+閰�
+钑�
+der
+鐒�
+gen@@
+杈�
+瑙�
+骞�
+妞�
+鑰�
+榛�
+瀵�
+閱�
+鑰�
+鎾�
+钄�
+鏇�
+璋�
+鐑�
+鏃�
+kno@@
+鐖�
+绲�
+娆�
+鍦�
+鑷�
+ch
+璋�
+鑽�
+宸�
+鎿�
+宓�
+闇�
+ames
+wel@@
+鍙�
+鍌�
+tra@@
+闅�
+鍞�
+婢�
+鐒�
+绐�
+鍓�
+鑿�
+閿�
+閿�
+鏋�
+濞�
+渚�
+姗�
+鎰�
+娉�
+鑼�
+鑽�
+閬�
+锜�
+鎹�
+鎸�
+韫�
+鏆�
+ity
+鐝�
+椹�
+鍡�
+璐�
+鎵�
+纭�
+娌�
+楦�
+钑�
+浠�
+looking
+鍐�
+閭�
+璧�
+宓�
+chi@@
+鍏�
+妗�
+about
+鑼�
+es@@
+缂�
+钑�
+闂�
+鐙�
+楠�
+灏�
+椴�
+und@@
+璇�
+濮�
+鑴�
+鑵�
+鎷�
+濠�
+鏉�
+淇�
+缁�
+they
+璺�
+鍍�
+杈�
+楠�
+鐫�
+澶�
+door
+鎹�
+闈�
+搴�
+鍔�
+鑸�
+楗�
+骞�
+ry
+鎮�
+鐣�
+鍏�
+鐣�
+ye@@
+those
+鑿�
+姒�
+閭�
+city
+娉�
+澶�
+better
+鍚�
+閰�
+钑�
+鐘�
+纾�
+閿�
+楣�
+楣�
+you@@
+鑰�
+姊�
+楦�
+姒�
+绗�
+鐫�
+姝�
+閬�
+椋�
+绗�
+钃�
+浜�
+娆�
+涓�
+鐞�
+瀹�
+ki@@
+tle
+鐩�
+婕�
+years
+鐑�
+鎹�
+棣�
+re
+璇�
+tur@@
+deci@@
+鍔�
+浣�
+bl@@
+of
+鍣�
+闃�
+姊�
+瀛�
+鏉�
+瑕�
+鐬�
+鐟�
+瑙�
+寰�
+娉�
+six@@
+闆�
+cust@@
+鐦�
+灏�
+楸�
+铏�
+鏉�
+other
+琛�
+鑺�
+鍗�
+鎿�
+閿�
+鐜�
+lu@@
+缂�
+鐎�
+缂�
+瀚�
+鍋�
+杩�
+鍘�
+椤�
+鐠�
+閿�
+鎮�
+off
+鑻�
+鎭�
+鍥�
+閿�
+鑸�
+绮�
+涓�
+瀛�
+閰�
+椴�
+璞�
+鍘�
+鐞�
+璋�
+绨�
+鐧�
+铓�
+閫�
+鎴�
+浜�
+棰�
+cur@@
+鑵�
+鍛�
+娌�
+楠�
+宕�
+鎵�
+鎬�
+app@@
+瀛�
+瀹�
+鑹�
+韪�
+娣�
+鍡�
+鐛�
+鎬�
+鐮�
+闀�
+姣�
+table
+@
+椴�
+瀵�
+妗�
+鍢�
+楂�
+鍝�
+缁�
+鍡�
+楹�
+let
+鍋�
+鑻�
+鐕�
+rou@@
+鍝�
+閯�
+缈�
+閰�
+鍜�
+鍡�
+钂�
+铏�
+鍥�
+鏉�
+楣�
+鎸�
+per@@
+鐭�
+鐝�
+鍥�
+鍐�
+浣�
+娲�
+婕�
+鑿�
+闀�
+灏�
+low
+鑻�
+鍓�
+could
+鍩�
+閾�
+缁�
+渚�
+鏄�
+then
+鍩�
+宄�
+鏅�
+鐫�
+鎼�
+鏅�
+閾�
+鍋�
+might
+姘�
+鍛�
+娣�
+ge
+缂�
+鑴�
+鑶�
+鑻�
+pla@@
+妗�
+鐢�
+椤�
+璁�
+鑹�
+tic@@
+鐮�
+鑽�
+瀹�
+娑�
+闉�
+娼�
+閮�
+瀹�
+鐮�
+锜�
+宀�
+璧�
+铔�
+绮�
+椹�
+鑶�
+鍨�
+nee@@
+閫�
+鑺�
+铻�
+瓒�
+change
+j
+閿�
+绠�
+绗�
+寮�
+鐣�
+鍒�
+鏀�
+铔�
+鐑�
+鑴�
+鏄�
+鍜�
+缇�
+鑺�
+鍗�
+鍣�
+椋�
+铚�
+some@@
+宕�
+瀣�
+浠�
+鏌�
+楣�
+澧�
+涔�
+瀚�
+楠�
+宸�
+鎲�
+鍒�
+椤�
+纾�
+浼�
+瀛�
+纰�
+鍫�
+绁�
+槌�
+姹�
+ab@@
+琚�
+璇�
+鍓�
+閿�
+閿�
+鐩�
+绠�
+鐦�
+restaur@@
+楣�
+鐦�
+鐭�
+his
+鐏�
+鍕�
+鎷�
+鍛�
+婕�
+缃�
+鍤�
+鐒�
+tru@@
+璧�
+浼�
+鍨�
+鎿�
+闀�
+鎯�
+璐�
+鎯�
+鎹�
+sto@@
+鐘�
+were
+鑹�
+浣�
+閰�
+鑰�
+鐚�
+閬�
+璞�
+鎬�
+钃�
+娉�
+灞�
+鐒�
+绛�
+缂�
+鏌�
+铚�
+鐝�
+鎬�
+娣�
+.
+闈�
+杞�
+鍫�
+娼�
+鎳�
+閭�
+鎯�
+绮�
+鏂�
+婕�
+re's
+绨�
+淇�
+姊�
+tr@@
+鑲�
+钁�
+椴�
+鍛�
+娓�
+寤�
+鏀�
+槌�
+瑕�
+鐞�
+鐔�
+缈�
+姘�
+椋�
+铻�
+濯�
+杈�
+鏃�
+姒�
+鐟�
+鍡�
+娓�
+ic
+鐔�
+鏆�
+鏌�
+楝�
+鏂�
+澶�
+鏅�
+姘�
+鐐�
+dn't
+鎶�
+鎾�
+鐑�
+鍋�
+璨�
+鍐�
+鑳�
+绯�
+娑�
+鍜�
+鍚�
+鎽�
+閷�
+鍨�
+鎻�
+鑸�
+宥�
+绛�
+浣�
+閰�
+闀�
+宸�
+鍡�
+閾�
+鏆�
+off@@
+鑼�
+楂�
+鎸�
+鐬�
+浼�
+蹇�
+鍍�
+钀�
+鏅�
+that@@
+鐖�
+绋�
+鐡�
+宕�
+um
+纾�
+鎶�
+鐣�
+缂�
+妤�
+鎮�
+鍒�
+绛�
+棣�
+鑺�
+閬�
+榛�
+杩�
+铦�
+鑵�
+鎵�
+宄�
+鎮�
+绂�
+鎯�
+five
+灞�
+鐮�
+ver
+鎭�
+鏂�
+韫�
+鐘�
+缁�
+ep
+鍠�
+浜�
+宓�
+姹�
+鐙�
+杩�
+鐩�
+line
+濡�
+韬�
+鐞�
+璧�
+le
+鐤�
+绌�
+鐒�
+璺�
+鍖�
+feat@@
+楣�
+鐠�
+钄�
+鐧�
+鎰�
+鑺�
+鍚�
+璋�
+鐔�
+鍝�
+ad
+杞�
+绁�
+娉�
+鐦�
+鍒�
+绨�
+璋�
+lea@@
+鍨�
+鍟�
+婊�
+楗�
+鐬�
+鐛�
+鍊�
+鑲�
+瀹�
+娑�
+绀�
+鏁�
+灞�
+婵�
+锜�
+涓�
+瑭�
+瑜�
+鐪�
+鑿�
+鐦�
+铦�
+鐪�
+缇�
+纭�
+鑳�
+鑺�
+姝�
+绾�
+琛�
+娣�
+姗�
+妯�
+绾�
+鍦�
+stay
+鍐�
+绔�
+鐜�
+瀹�
+鎬�
+钖�
+娈�
+鐪�
+鍓�
+妫�
+鐦�
+be@@
+瑁�
+绡�
+甯�
+鍔�
+楠�
+閿�
+寤�
+搴�
+缁�
+鍔�
+铦�
+閿�
+婵�
+绛�
+榄�
+閰�
+闃�
+寮�
+鎮�
+濮�
+鍌�
+which
+鑲�
+婀�
+璐�
+鐩�
+鑼�
+鑽�
+閽�
+鑷�
+娌�
+鍙�
+妗�
+浣�
+鐝�
+鏄�
+鍩�
+鍓�
+绠�
+宀�
+娑�
+鏌�
+涓�
+鍕�
+姘�
+绋�
+鍖�
+ting
+鐦�
+缂�
+楣�
+闆�
+铔�
+闀�
+榄�
+璎�
+me@@
+set
+璞�
+h
+绉�
+鑽�
+璧�
+娌�
+鍚�
+鐭�
+韪�
+杩�
+鍙�
+鎶�
+闀�
+鍤�
+鍙�
+閿�
+ex@@
+杈�
+璋�
+缍�
+ws
+鍚�
+婀�
+ll@@
+甯�
+濞�
+鍫�
+璺�
+澶�
+鍘�
+鏈�
+绗�
+鎮�
+瀛�
+鍢�
+鎭�
+鐨�
+濉�
+who@@
+濡�
+鏍�
+鐡�
+绋�
+纰�
+鍝�
+pol@@
+寰�
+s
+閭�
+鎭�
+妯�
+榧�
+鎷�
+璋�
+澧�
+鍖�
+speci@@
+ha@@
+搴�
+楣�
+ak@@
+闀�
+m
+鍞�
+宸�
+绛�
+鎬�
+楂�
+鍝�
+闀�
+璐�
+and
+鑿�
+濮�
+鑱�
+tion
+鍌�
+閱�
+鍞�
+闆�
+鍫�
+鑺�
+鎿�
+鍖�
+鎮�
+閽�
+gy
+寰�
+娓�
+瑾�
+ti@@
+鍐�
+閾�
+鍜�
+娌�
+鍏�
+鐭�
+鑲�
+闊�
+閭�
+璋�
+鑰�
+娴�
+public
+鑳�
+鐚�
+six
+榛�
+being
+寮�
+鎹�
+ical
+鐧�
+鍫�
+浼�
+鍓�
+寮�
+la@@
+榧�
+閫�
+鍫�
+cap@@
+棣�
+璋�
+鐦�
+纭�
+閮�
+鍑�
+fu@@
+b@@
+鐫�
+楠�
+浣�
+绡�
+璐�
+閾�
+act
+鍛�
+绔�
+鑾�
+闄�
+椋�
+榛�
+闀�
+灞�
+浠�
+鏁�
+椹�
+鍩�
+鍨�
+闃�
+鑰�
+绗�
+钃�
+濡�
+璁�
+see@@
+鍚�
+韪�
+寮�
+姊�
+鍧�
+娓�
+au@@
+璧�
+鍧�
+鑻�
+don@@
+瀵�
+淇�
+fir@@
+婵�
+鍧�
+娴�
+鍞�
+濠�
+鎭�
+闅�
+楹�
+ca@@
+鑾�
+寰�
+闉�
+绂�
+琛�
+娼�
+鑼�
+ven
+鐬�
+楦�
+鍑�
+鍜�
+楗�
+鑰�
+uni@@
+鐟�
+鐓�
+鑸�
+灏�
+甯�
+榧�
+瀚�
+濠�
+璧�
+妫�
+娌�
+绉�
+绮�
+roo@@
+铓�
+浜�
+澶�
+鍘�
+鎮�
+鍤�
+fin@@
+浜�
+鐧�
+璺�
+鑾�
+闂�
+缃�
+鐐�
+閽�
+楣�
+鍙�
+鍌�
+绯�
+service
+閭�
+绐�
+鎵�
+椴�
+鐩�
+鐜�
+鍗�
+ne@@
+鐪�
+楦�
+鍏�
+鏉�
+纰�
+绡�
+瑁�
+閽�
+澶�
+浠�
+鎻�
+鐮�
+鍗�
+寮�
+棰�
+瀚�
+浠�
+浼�
+鎮�
+鑰�
+绠�
+鐣�
+鐤�
+sp@@
+鑱�
+鐎�
+鎸�
+鎷�
+姘�
+鐠�
+鑲�
+tan
+ul@@
+锠�
+榫�
+瀹�
+鎸�
+must
+韫�
+妯�
+浠�
+楗�
+buy
+蹇�
+濞�
+鎵�
+house
+璐�
+鍢�
+鑾�
+鑼�
+瀹�
+鍒�
+鍌�
+rest
+鍘�
+娲�
+鐗�
+鏋�
+閾�
+瑙�
+瀣�
+鑺�
+鍏�
+绲�
+闄�
+zer@@
+钘�
+air@@
+璐�
+瓒�
+瀛�
+琚�
+姘�
+绔�
+鏌�
+鎭�
+楹�
+鑳�
+came
+浼�
+鑸�
+绫�
+鎯�
+娉�
+棣�
+鐢�
+wer
+楣�
+鍜�
+宕�
+宓�
+铦�
+ils
+婀�
+鎶�
+铚�
+鍓�
+鏍�
+鎭�
+鍛�
+閮�
+鎶�
+绐�
+鐧�
+xt
+姒�
+鍌�
+鐢�
+鎾�
+铓�
+鑿�
+宕�
+閰�
+瑗�
+cu@@
+鍛�
+甯�
+鐐�
+鎻�
+鍟�
+椴�
+ve@@
+鑹�
+鍡�
+ili@@
+鍑�
+鐞�
+楝�
+鑽�
+缁�
+浜�
+閱�
+鐕�
+槌�
+渚�
+绨�
+娲�
+鍢�
+绋�
+'t
+姘�
+鏆�
+鎸�
+娉�
+鎬�
+offer
+绯�
+鑶�
+姣�
+韫�
+鐓�
+妗�
+浠�
+娴�
+鍏�
+娑�
+璺�
+绁�
+婀�
+鑴�
+鎻�
+pr@@
+鐙�
+璧�
+鐮�
+琚�
+棣�
+鏋�
+纰�
+濞�
+杈�
+棰�
+鎹�
+宄�
+鑱�
+鍠�
+璇�
+鐤�
+鍧�
+纰�
+缂�
+榧�
+閽�
+鑵�
+婧�
+鑴�
+娈�
+鑲�
+娉�
+鎹�
+妲�
+鍚�
+娌�
+婧�
+搴�
+娈�
+楠�
+楗�
+cour@@
+鑷�
+绌�
+2@@
+鍏�
+鏋�
+钂�
+or@@
+瓒�
+鑿�
+鏍�
+view
+possi@@
+浠�
+槌�
+鎽�
+瀵�
+韬�
+婀�
+鍚�
+鍒�
+鎻�
+寰�
+瀵�
+鍧�
+鎸�
+涓�
+姘�
+鑷�
+楗�
+涓�
+褰�
+娉�
+鏇�
+琛�
+ei@@
+鍛�
+鐙�
+鐢�
+绂�
+钖�
+shipping
+ght
+鎱�
+骞�
+鍖�
+鐐�
+璁�
+four
+绉�
+妯�
+闄�
+鑴�
+鏋�
+纾�
+鍝�
+鍚�
+鑴�
+鐏�
+鍥�
+绱�
+鐠�
+閭�
+鎰�
+钖�
+杈�
+鐝�
+闆�
+楝�
+璧�
+鏋�
+閭�
+浣�
+棰�
+瀵�
+鎶�
+椴�
+鍒�
+绲�
+鎴�
+婧�
+琚�
+less
+閫�
+灏�
+food
+鍖�
+鍏�
+灏�
+鐨�
+槌�
+鎼�
+骞�
+杩�
+鏉�
+韫�
+褰�
+铏�
+鎬�
+闆�
+閽�
+婢�
+鎵�
+閿�
+妯�
+榛�
+鑳�
+钖�
+闃�
+澧�
+瑙�
+鍒�
+姹�
+缇�
+鏉�
+娣�
+钃�
+鑵�
+鍝�
+was
+閽�
+鑳�
+鑹�
+鎾�
+铏�
+鐓�
+椋�
+throu@@
+闂�
+鐜�
+鐞�
+鐓�
+閰�
+濠�
+serv@@
+纭�
+鍑�
+澶�
+鎾�
+闋�
+want
+鐘�
+鍘�
+p@@
+en
+鏂�
+灞�
+鐜�
+life
+娼�
+楠�
+鑷�
+璋�
+娈�
+鍘�
+鎽�
+纾�
+v
+dress
+缁�
+鍥�
+鐪�
+蹇�
+澹�
+鍜�
+鎼�
+鑲�
+榄�
+鑺�
+绐�
+鎷�
+绾�
+妤�
+钄�
+瀵�
+濡�
+鏁�
+淇�
+棰�
+纰�
+浜�
+濂�
+鎲�
+鐐�
+韫�
+鑱�
+鍛�
+鍛�
+鐬�
+il@@
+鎭�
+闃�
+鍗�
+mi@@
+绂�
+妞�
+yo@@
+甯�
+閱�
+甯�
+闅�
+蹇�
+鍝�
+鍔�
+妤�
+榧�
+濉�
+鑻�
+铚�
+鍋�
+閱�
+ju@@
+鏂�
+绋�
+鑼�
+鐞�
+鍑�
+鎻�
+鍖�
+鐮�
+绂�
+缃�
+鍕�
+鎿�
+鐣�
+妗�
+娉�
+鏋�
+娌�
+鍋�
+绻�
+鍡�
+鍛�
+蹇�
+so@@
+婧�
+鏇�
+spon@@
+鐙�
+鍊�
+濞�
+娼�
+韪�
+鏅�
+鍚�
+琚�
+鍠�
+娲�
+鐐�
+绾�
+鎶�
+绨�
+c@@
+涔�
+鍚�
+淇�
+姊�
+鍙�
+绁�
+鐑�
+鑽�
+鐪�
+<unk>
diff --git a/funasr/runtime/cpp/onnxruntime/readme.md b/funasr/runtime/cpp/onnxruntime/readme.md
new file mode 100644
index 0000000..56e9787
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/readme.md
@@ -0,0 +1,107 @@
+
+## 鐗瑰埆楦h阿
+
+鏈▼搴忎腑鐨勯澶勭悊鍙婂悗澶勭悊浠g爜锛屾潵鑷簬锛歨ttps://github.com/chenkui164/FastASR
+
+
+## 绾跨▼鏁颁笌鎬ц兘鍏崇郴
+
+娴嬭瘯鐜Rocky Linux 8锛屼粎娴嬭瘯cpp鐗堟湰缁撴灉锛堟湭娴媝ython鐗堟湰锛夛紝@acely
+
+绠�杩帮細
+鍦�3鍙伴厤缃笉鍚岀殑鏈哄櫒涓婂垎鍒紪璇戝苟娴嬭瘯锛屽湪fftw鍜宱nnxruntime鐗堟湰閮界浉鍚岀殑鍓嶆彁涓嬶紝璇嗗埆鍚屼竴涓�30鍒嗛挓鐨勯煶棰戞枃浠讹紝鍒嗗埆娴嬭瘯涓嶅悓onnx绾跨▼鏁伴噺鐨勮〃鐜般��
+
+
+
+## 娉ㄦ剰
+鏈▼搴忓彧鏀寔 閲囨牱鐜�16000hz, 浣嶆繁16bit鐨� **鍗曞0閬�** 闊抽銆�
+
+## 蹇�熶娇鐢�
+
+### Windows
+
+ 瀹夎Vs2022 鎵撳紑cpp_onnx鐩綍涓嬬殑cmake宸ョ▼锛岀洿鎺� build鍗冲彲銆� 鏈粨搴撳凡缁忓噯澶囧ソ鎵�鏈夌浉鍏充緷璧栧簱銆�
+
+ Windows涓嬪凡缁忛缃甪ftw3銆乷nnxruntime鍙妎penblas搴�
+
+
+### Linux
+See the bottom of this page: Building Guidance
+
+
+### 杩愯绋嬪簭
+
+tester /path/to/models/dir /path/to/wave/file
+
+ 渚嬪锛� tester /data/models /data/test.wav
+
+/data/models 闇�瑕佸寘鎷涓嬩袱涓枃浠讹細 model.onnx 鍜寁ocab.txt
+
+
+## 鏀寔骞冲彴
+- Windows
+- Linux/Unix
+
+## 渚濊禆
+- fftw3
+- onnxruntime
+
+## 瀵煎嚭onnx鏍煎紡妯″瀷鏂囦欢
+瀹夎 modelscope涓嶧unASR锛屼緷璧栵細torch锛宼orchaudio锛屽畨瑁呰繃绋媅璇︾粏鍙傝�冩枃妗(https://github.com/alibaba-damo-academy/FunASR/wiki)
+```shell
+pip install "modelscope[audio_asr]" -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html
+git clone https://github.com/alibaba/FunASR.git && cd FunASR
+pip install --editable ./
+```
+瀵煎嚭onnx妯″瀷锛孾璇﹁](https://github.com/alibaba-damo-academy/FunASR/tree/main/funasr/export)锛屽弬鑰冪ず渚嬶紝浠巑odelscope涓ā鍨嬪鍑猴細
+
+```
+python -m funasr.export.export_model 'damo/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-pytorch' "./export" true
+```
+
+## Building Guidance for Linux/Unix
+
+```
+git clone https://github.com/RapidAI/RapidASR.git
+cd RapidASR/cpp_onnx/
+mkdir build
+cd build
+# download an appropriate onnxruntime from https://github.com/microsoft/onnxruntime/releases/tag/v1.14.0
+# here we get a copy of onnxruntime for linux 64
+wget https://github.com/microsoft/onnxruntime/releases/download/v1.14.0/onnxruntime-linux-x64-1.14.0.tgz
+# ls
+# onnxruntime-linux-x64-1.14.0 onnxruntime-linux-x64-1.14.0.tgz
+
+#install fftw3-dev
+apt install libfftw3-dev
+
+# build
+ cmake -DCMAKE_BUILD_TYPE=release .. -DONNXRUNTIME_DIR=/mnt/c/Users/ma139/RapidASR/cpp_onnx/build/onnxruntime-linux-x64-1.14.0
+ make
+
+ # then in the subfolder tester of current direcotry, you will see a program, tester
+
+````
+
+### The structure of a qualified onnxruntime package.
+```
+onnxruntime_xxx
+鈹溾攢鈹�鈹�include
+鈹斺攢鈹�鈹�lib
+```
diff --git a/funasr/runtime/cpp/onnxruntime/src/Audio.cpp b/funasr/runtime/cpp/onnxruntime/src/Audio.cpp
new file mode 100644
index 0000000..f515a6d
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/Audio.cpp
@@ -0,0 +1,298 @@
+#include <math.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <webrtc_vad.h>
+
+#include "Audio.h"
+
+using namespace std;
+
+class AudioWindow {
+ private:
+ int *window;
+ int in_idx;
+ int out_idx;
+ int sum;
+ int window_size = 0;
+
+ public:
+ AudioWindow(int window_size) : window_size(window_size)
+ {
+ window = (int *)calloc(sizeof(int), window_size + 1);
+ in_idx = 0;
+ out_idx = 1;
+ sum = 0;
+ };
+ ~AudioWindow()
+ {
+ free(window);
+ };
+ int put(int val)
+ {
+ sum = sum + val - window[out_idx];
+ window[in_idx] = val;
+ in_idx = in_idx == window_size ? 0 : in_idx + 1;
+ out_idx = out_idx == window_size ? 0 : out_idx + 1;
+ return sum;
+ };
+};
+
+AudioFrame::AudioFrame(){};
+AudioFrame::AudioFrame(int len) : len(len)
+{
+ start = 0;
+};
+AudioFrame::~AudioFrame(){};
+int AudioFrame::set_start(int val)
+{
+ start = val < 0 ? 0 : val;
+ return start;
+};
+
+int AudioFrame::set_end(int val, int max_len)
+{
+
+ float num_samples = val - start;
+ float frame_length = 400;
+ float frame_shift = 160;
+ float num_new_samples =
+ ceil((num_samples - 400) / frame_shift) * frame_shift + frame_length;
+
+ end = start + num_new_samples;
+ len = (int)num_new_samples;
+ if (end > max_len)
+ printf("frame end > max_len!!!!!!!\n");
+ return end;
+};
+
+int AudioFrame::get_start()
+{
+ return start;
+};
+
+int AudioFrame::get_len()
+{
+ return len;
+};
+
+int AudioFrame::disp()
+{
+ printf("not imp!!!!\n");
+
+ return 0;
+};
+
+Audio::Audio(int data_type) : data_type(data_type)
+{
+ speech_buff = NULL;
+ speech_data = NULL;
+ align_size = 1360;
+}
+
+Audio::Audio(int data_type, int size) : data_type(data_type)
+{
+ speech_buff = NULL;
+ speech_data = NULL;
+ align_size = (float)size;
+}
+
+Audio::~Audio()
+{
+ if (speech_buff != NULL) {
+ free(speech_buff);
+ free(speech_data);
+ }
+}
+
+void Audio::disp()
+{
+ printf("Audio time is %f s. len is %d\n", (float)speech_len / 16000,
+ speech_len);
+}
+
+bool Audio::loadwav(const char *filename)
+{
+
+ if (speech_buff != NULL) {
+ free(speech_buff);
+ free(speech_data);
+ }
+
+ offset = 0;
+
+ FILE *fp;
+ fp = fopen(filename, "rb");
+ if (fp == nullptr)
+ return false;
+ fseek(fp, 0, SEEK_END);
+ uint32_t nFileLen = ftell(fp);
+ fseek(fp, 44, SEEK_SET);
+
+ speech_len = (nFileLen - 44) / 2;
+ speech_align_len = (int)(ceil((float)speech_len / align_size) * align_size);
+ speech_buff = (int16_t *)malloc(sizeof(int16_t) * speech_align_len);
+ memset(speech_buff, 0, sizeof(int16_t) * speech_align_len);
+ int ret = fread(speech_buff, sizeof(int16_t), speech_len, fp);
+ fclose(fp);
+
+ speech_data = (float *)malloc(sizeof(float) * speech_align_len);
+ memset(speech_data, 0, sizeof(float) * speech_align_len);
+ int i;
+ float scale = 1;
+
+ if (data_type == 1) {
+ scale = 32768;
+ }
+
+ for (i = 0; i < speech_len; i++) {
+ speech_data[i] = (float)speech_buff[i] / scale;
+ }
+
+ AudioFrame *frame = new AudioFrame(speech_len);
+ frame_queue.push(frame);
+ return true;
+}
+
+int Audio::fetch_chunck(float *&dout, int len)
+{
+ if (offset >= speech_align_len) {
+ dout = NULL;
+ return S_ERR;
+ } else if (offset == speech_align_len - len) {
+ dout = speech_data + offset;
+ offset = speech_align_len;
+ // 涓存椂瑙e喅
+ AudioFrame *frame = frame_queue.front();
+ frame_queue.pop();
+ delete frame;
+
+ return S_END;
+ } else {
+ dout = speech_data + offset;
+ offset += len;
+ return S_MIDDLE;
+ }
+}
+
+int Audio::fetch(float *&dout, int &len, int &flag)
+{
+ if (frame_queue.size() > 0) {
+ AudioFrame *frame = frame_queue.front();
+ frame_queue.pop();
+
+ dout = speech_data + frame->get_start();
+ len = frame->get_len();
+ delete frame;
+ flag = S_END;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void Audio::padding()
+{
+
+ float num_samples = speech_len;
+ float frame_length = 400;
+ float frame_shift = 160;
+ float num_frames = floor((num_samples + (frame_shift / 2)) / frame_shift);
+ float num_new_samples = (num_frames - 1) * frame_shift + frame_length;
+ float num_padding = num_new_samples - num_samples;
+ float num_left_padding = (frame_length - frame_shift) / 2;
+ float num_right_padding = num_padding - num_left_padding;
+
+ float *new_data = (float *)malloc(num_new_samples * sizeof(float));
+ int i;
+ int tmp_off = 0;
+ for (i = 0; i < num_left_padding; i++) {
+ int ii = num_left_padding - i - 1;
+ new_data[i] = speech_data[ii];
+ }
+ tmp_off = num_left_padding;
+ memcpy(new_data + tmp_off, speech_data, speech_len * sizeof(float));
+ tmp_off += speech_len;
+
+ for (i = 0; i < num_right_padding; i++) {
+ int ii = speech_len - i - 1;
+ new_data[tmp_off + i] = speech_data[ii];
+ }
+ free(speech_data);
+ speech_data = new_data;
+ speech_len = num_new_samples;
+
+ AudioFrame *frame = new AudioFrame(num_new_samples);
+ frame_queue.push(frame);
+ frame = frame_queue.front();
+ frame_queue.pop();
+ delete frame;
+}
+
+#define UNTRIGGERED 0
+#define TRIGGERED 1
+
+#define SPEECH_LEN_5S (16000 * 5)
+#define SPEECH_LEN_10S (16000 * 10)
+#define SPEECH_LEN_20S (16000 * 20)
+#define SPEECH_LEN_30S (16000 * 30)
+
+void Audio::split()
+{
+ VadInst *handle = WebRtcVad_Create();
+ WebRtcVad_Init(handle);
+ WebRtcVad_set_mode(handle, 2);
+ int window_size = 10;
+ AudioWindow audiowindow(window_size);
+ int status = UNTRIGGERED;
+ int offset = 0;
+ int fs = 16000;
+ int step = 480;
+
+ AudioFrame *frame;
+
+ frame = frame_queue.front();
+ frame_queue.pop();
+ delete frame;
+ frame = NULL;
+
+ while (offset < speech_len - step) {
+ int n = WebRtcVad_Process(handle, fs, speech_buff + offset, step);
+ if (status == UNTRIGGERED && audiowindow.put(n) >= window_size - 1) {
+ frame = new AudioFrame();
+ int start = offset - step * (window_size - 1);
+ frame->set_start(start);
+ status = TRIGGERED;
+ } else if (status == TRIGGERED) {
+ int win_weight = audiowindow.put(n);
+ int voice_len = (offset - frame->get_start());
+ int gap = 0;
+ if (voice_len < SPEECH_LEN_5S) {
+ offset += step;
+ continue;
+ } else if (voice_len < SPEECH_LEN_10S) {
+ gap = 1;
+ } else if (voice_len < SPEECH_LEN_20S) {
+ gap = window_size / 5;
+ } else {
+ gap = window_size / 2;
+ }
+
+ if (win_weight < gap) {
+ status = UNTRIGGERED;
+ offset = frame->set_end(offset, speech_align_len);
+ frame_queue.push(frame);
+ frame = NULL;
+ }
+ }
+ offset += step;
+ }
+
+ if (frame != NULL) {
+ frame->set_end(speech_len, speech_align_len);
+ frame_queue.push(frame);
+ frame = NULL;
+ }
+ WebRtcVad_Free(handle);
+}
diff --git a/funasr/runtime/cpp/onnxruntime/src/CMakeLists.txt b/funasr/runtime/cpp/onnxruntime/src/CMakeLists.txt
new file mode 100644
index 0000000..4842072
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/CMakeLists.txt
@@ -0,0 +1,43 @@
+
+file(GLOB files1 "*.cpp")
+file(GLOB files4 "paraformer/*.cpp")
+
+set(files ${files1} ${files2} ${files3} ${files4})
+
+# message("${files}")
+
+add_library(rapidasr ${files})
+
+if(WIN32)
+
+ set(EXTRA_LIBS libfftw3f-3 webrtcvad)
+ if(CMAKE_CL_64)
+ target_link_directories(rapidasr PUBLIC ${CMAKE_SOURCE_DIR}/win/lib/x64)
+ else()
+ target_link_directories(rapidasr PUBLIC ${CMAKE_SOURCE_DIR}/win/lib/x86)
+ endif()
+ target_include_directories(rapidasr PUBLIC ${CMAKE_SOURCE_DIR}/win/include )
+
+
+else()
+
+ set(EXTRA_LIBS fftw3f webrtcvad pthread)
+ target_include_directories(rapidasr PUBLIC "/usr/local/opt/fftw/include")
+ target_link_directories(rapidasr PUBLIC "/usr/local/opt/fftw/lib")
+
+ target_include_directories(rapidasr PUBLIC "/usr/local/opt/openblas/include")
+ target_link_directories(rapidasr PUBLIC "/usr/local/opt/openblas/lib")
+
+ target_include_directories(rapidasr PUBLIC "/usr/include")
+ target_link_directories(rapidasr PUBLIC "/usr/lib64")
+
+ target_include_directories(rapidasr PUBLIC ${FFTW3F_INCLUDE_DIR})
+ target_link_directories(rapidasr PUBLIC ${FFTW3F_LIBRARY_DIR})
+ include_directories(${ONNXRUNTIME_DIR}/include)
+endif()
+
+include_directories(${CMAKE_SOURCE_DIR}/include)
+target_link_libraries(rapidasr PUBLIC onnxruntime ${EXTRA_LIBS})
+
+
+
diff --git a/funasr/runtime/cpp/onnxruntime/src/CommonStruct.h b/funasr/runtime/cpp/onnxruntime/src/CommonStruct.h
new file mode 100644
index 0000000..538d38b
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/CommonStruct.h
@@ -0,0 +1,6 @@
+
+#ifndef COMMONSTRUCT_H
+#define COMMONSTRUCT_H
+
+
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/FeatureExtract.cpp b/funasr/runtime/cpp/onnxruntime/src/FeatureExtract.cpp
new file mode 100644
index 0000000..1b0c3c4
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/FeatureExtract.cpp
@@ -0,0 +1,408 @@
+
+#include "precomp.h"
+
+using namespace std;
+
+FeatureExtract::FeatureExtract(int mode) : mode(mode)
+{
+ fftw_init();
+}
+
+FeatureExtract::~FeatureExtract()
+{
+ fftwf_free(fft_input);
+ fftwf_free(fft_out);
+ fftwf_destroy_plan(p);
+}
+
+void FeatureExtract::reset()
+{
+ speech.reset();
+ fqueue.reset();
+}
+
+int FeatureExtract::size()
+{
+ return fqueue.size();
+}
+
+void FeatureExtract::fftw_init()
+{
+ int fft_size = 512;
+ fft_input = (float *)fftwf_malloc(sizeof(float) * fft_size);
+ fft_out = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex) * fft_size);
+ memset(fft_input, 0, sizeof(float) * fft_size);
+ p = fftwf_plan_dft_r2c_1d(fft_size, fft_input, fft_out, FFTW_ESTIMATE);
+}
+
+void FeatureExtract::insert(float *din, int len, int flag)
+{
+ const float *window = (const float *)&window_hex;
+ if (mode == 3)
+ window = (const float *)&window_hamm_hex;
+
+ int window_size = 400;
+ int fft_size = 512;
+ int window_shift = 160;
+
+ speech.load(din, len);
+ int i, j;
+ float tmp_feature[80];
+ if (mode == 0 || mode == 2 || mode == 3) {
+ int ll = (speech.size() - 400) / 160 + 1;
+ fqueue.reinit(ll);
+ }
+
+ for (i = 0; i <= speech.size() - 400; i = i + window_shift) {
+ float tmp_mean = 0;
+ for (j = 0; j < window_size; j++) {
+ tmp_mean += speech[i + j];
+ }
+
+ tmp_mean = tmp_mean / window_size;
+
+ float pre_val = (float)speech[i] - tmp_mean;
+
+ for (j = 0; j < window_size; j++) {
+ float win = window[j];
+ float cur_val = (float)speech[i + j] - tmp_mean;
+ fft_input[j] = win * (cur_val - 0.97 * pre_val);
+ pre_val = cur_val;
+ }
+
+ fftwf_execute(p);
+
+ melspect((float *)fft_out, tmp_feature);
+ int tmp_flag = S_MIDDLE;
+ if (flag == S_END && i > speech.size() - 560)
+ tmp_flag = S_END;
+
+ fqueue.push(tmp_feature, tmp_flag);
+ }
+ speech.update(i);
+}
+
+bool FeatureExtract::fetch(Tensor<float> *&dout)
+{
+ if (fqueue.size() < 1) {
+ return false;
+ } else {
+ dout = fqueue.pop();
+ return true;
+ }
+}
+
+void FeatureExtract::global_cmvn(float *din)
+{
+ const float *std;
+ const float *mean;
+
+ if (mode < 2) {
+ if (mode == 0) {
+ std = (const float *)global_cmvn_std_hex;
+ mean = (const float *)global_cmvn_mean_hex;
+ } else {
+ std = (const float *)global_cmvn_std_online_hex;
+ mean = (const float *)global_cmvn_mean_online_hex;
+ }
+
+ int i;
+ for (i = 0; i < 80; i++) {
+ float tmp = din[i] < 1e-7 ? 1e-7 : din[i];
+ tmp = log(tmp);
+ din[i] = (tmp - mean[i]) / std[i];
+ }
+ } else {
+ int i;
+
+ int val = 0x34000000;
+ float min_resol = *((float *)&val);
+
+ for (i = 0; i < 80; i++) {
+ float tmp = din[i] < min_resol ? min_resol : din[i];
+ din[i] = log(tmp);
+ }
+ }
+}
+
+void FeatureExtract::melspect(float *din, float *dout)
+{
+ float fftmag[256];
+// float tmp;
+ const float *melcoe = (const float *)melcoe_hex;
+ int i;
+ for (i = 0; i < 256; i++) {
+ float real = din[2 * i];
+ float imag = din[2 * i + 1];
+ fftmag[i] = real * real + imag * imag;
+ }
+ dout[0] = melcoe[0] * fftmag[1] + melcoe[1] * fftmag[2];
+ dout[1] = melcoe[2] * fftmag[2];
+ dout[2] = melcoe[3] * fftmag[3];
+ dout[3] = melcoe[4] * fftmag[3] + melcoe[5] * fftmag[4];
+ dout[4] = melcoe[6] * fftmag[4] + melcoe[7] * fftmag[5];
+ dout[5] = melcoe[8] * fftmag[5] + melcoe[9] * fftmag[6];
+ dout[6] = melcoe[10] * fftmag[6] + melcoe[11] * fftmag[7];
+ dout[7] = melcoe[12] * fftmag[7];
+ dout[8] = melcoe[13] * fftmag[8];
+ dout[9] = melcoe[14] * fftmag[8] + melcoe[15] * fftmag[9];
+ dout[10] = melcoe[16] * fftmag[9] + melcoe[17] * fftmag[10];
+ dout[11] = melcoe[18] * fftmag[10] + melcoe[19] * fftmag[11];
+ dout[12] = melcoe[20] * fftmag[11] + melcoe[21] * fftmag[12] +
+ melcoe[22] * fftmag[13];
+ dout[13] = melcoe[23] * fftmag[12] + melcoe[24] * fftmag[13] +
+ melcoe[25] * fftmag[14];
+ dout[14] = melcoe[26] * fftmag[14] + melcoe[27] * fftmag[15];
+ dout[15] = melcoe[28] * fftmag[15] + melcoe[29] * fftmag[16];
+ dout[16] = melcoe[30] * fftmag[16] + melcoe[31] * fftmag[17];
+ dout[17] = melcoe[32] * fftmag[17] + melcoe[33] * fftmag[18];
+ dout[18] = melcoe[34] * fftmag[18] + melcoe[35] * fftmag[19] +
+ melcoe[36] * fftmag[20];
+ dout[19] = melcoe[37] * fftmag[19] + melcoe[38] * fftmag[20] +
+ melcoe[39] * fftmag[21];
+ dout[20] = melcoe[40] * fftmag[21] + melcoe[41] * fftmag[22];
+ dout[21] = melcoe[42] * fftmag[22] + melcoe[43] * fftmag[23] +
+ melcoe[44] * fftmag[24];
+ dout[22] = melcoe[45] * fftmag[23] + melcoe[46] * fftmag[24] +
+ melcoe[47] * fftmag[25];
+ dout[23] = melcoe[48] * fftmag[25] + melcoe[49] * fftmag[26] +
+ melcoe[50] * fftmag[27];
+ dout[24] = melcoe[51] * fftmag[26] + melcoe[52] * fftmag[27] +
+ melcoe[53] * fftmag[28];
+ dout[25] = melcoe[54] * fftmag[28] + melcoe[55] * fftmag[29] +
+ melcoe[56] * fftmag[30];
+ dout[26] = melcoe[57] * fftmag[29] + melcoe[58] * fftmag[30] +
+ melcoe[59] * fftmag[31] + melcoe[60] * fftmag[32];
+ dout[27] = melcoe[61] * fftmag[31] + melcoe[62] * fftmag[32] +
+ melcoe[63] * fftmag[33];
+ dout[28] = melcoe[64] * fftmag[33] + melcoe[65] * fftmag[34] +
+ melcoe[66] * fftmag[35];
+ dout[29] = melcoe[67] * fftmag[34] + melcoe[68] * fftmag[35] +
+ melcoe[69] * fftmag[36] + melcoe[70] * fftmag[37];
+ dout[30] = melcoe[71] * fftmag[36] + melcoe[72] * fftmag[37] +
+ melcoe[73] * fftmag[38] + melcoe[74] * fftmag[39];
+ dout[31] = melcoe[75] * fftmag[38] + melcoe[76] * fftmag[39] +
+ melcoe[77] * fftmag[40] + melcoe[78] * fftmag[41];
+ dout[32] = melcoe[79] * fftmag[40] + melcoe[80] * fftmag[41] +
+ melcoe[81] * fftmag[42] + melcoe[82] * fftmag[43];
+ dout[33] = melcoe[83] * fftmag[42] + melcoe[84] * fftmag[43] +
+ melcoe[85] * fftmag[44] + melcoe[86] * fftmag[45];
+ dout[34] = melcoe[87] * fftmag[44] + melcoe[88] * fftmag[45] +
+ melcoe[89] * fftmag[46] + melcoe[90] * fftmag[47];
+ dout[35] = melcoe[91] * fftmag[46] + melcoe[92] * fftmag[47] +
+ melcoe[93] * fftmag[48] + melcoe[94] * fftmag[49];
+ dout[36] = melcoe[95] * fftmag[48] + melcoe[96] * fftmag[49] +
+ melcoe[97] * fftmag[50] + melcoe[98] * fftmag[51];
+ dout[37] = melcoe[99] * fftmag[50] + melcoe[100] * fftmag[51] +
+ melcoe[101] * fftmag[52] + melcoe[102] * fftmag[53] +
+ melcoe[103] * fftmag[54];
+ dout[38] = melcoe[104] * fftmag[52] + melcoe[105] * fftmag[53] +
+ melcoe[106] * fftmag[54] + melcoe[107] * fftmag[55] +
+ melcoe[108] * fftmag[56];
+ dout[39] = melcoe[109] * fftmag[55] + melcoe[110] * fftmag[56] +
+ melcoe[111] * fftmag[57] + melcoe[112] * fftmag[58];
+ dout[40] = melcoe[113] * fftmag[57] + melcoe[114] * fftmag[58] +
+ melcoe[115] * fftmag[59] + melcoe[116] * fftmag[60] +
+ melcoe[117] * fftmag[61];
+ dout[41] = melcoe[118] * fftmag[59] + melcoe[119] * fftmag[60] +
+ melcoe[120] * fftmag[61] + melcoe[121] * fftmag[62] +
+ melcoe[122] * fftmag[63] + melcoe[123] * fftmag[64];
+ dout[42] = melcoe[124] * fftmag[62] + melcoe[125] * fftmag[63] +
+ melcoe[126] * fftmag[64] + melcoe[127] * fftmag[65] +
+ melcoe[128] * fftmag[66];
+ dout[43] = melcoe[129] * fftmag[65] + melcoe[130] * fftmag[66] +
+ melcoe[131] * fftmag[67] + melcoe[132] * fftmag[68] +
+ melcoe[133] * fftmag[69];
+ dout[44] = melcoe[134] * fftmag[67] + melcoe[135] * fftmag[68] +
+ melcoe[136] * fftmag[69] + melcoe[137] * fftmag[70] +
+ melcoe[138] * fftmag[71] + melcoe[139] * fftmag[72];
+ dout[45] = melcoe[140] * fftmag[70] + melcoe[141] * fftmag[71] +
+ melcoe[142] * fftmag[72] + melcoe[143] * fftmag[73] +
+ melcoe[144] * fftmag[74] + melcoe[145] * fftmag[75];
+ dout[46] = melcoe[146] * fftmag[73] + melcoe[147] * fftmag[74] +
+ melcoe[148] * fftmag[75] + melcoe[149] * fftmag[76] +
+ melcoe[150] * fftmag[77] + melcoe[151] * fftmag[78];
+ dout[47] = melcoe[152] * fftmag[76] + melcoe[153] * fftmag[77] +
+ melcoe[154] * fftmag[78] + melcoe[155] * fftmag[79] +
+ melcoe[156] * fftmag[80] + melcoe[157] * fftmag[81];
+ dout[48] = melcoe[158] * fftmag[79] + melcoe[159] * fftmag[80] +
+ melcoe[160] * fftmag[81] + melcoe[161] * fftmag[82] +
+ melcoe[162] * fftmag[83] + melcoe[163] * fftmag[84];
+ dout[49] = melcoe[164] * fftmag[82] + melcoe[165] * fftmag[83] +
+ melcoe[166] * fftmag[84] + melcoe[167] * fftmag[85] +
+ melcoe[168] * fftmag[86] + melcoe[169] * fftmag[87] +
+ melcoe[170] * fftmag[88];
+ dout[50] = melcoe[171] * fftmag[85] + melcoe[172] * fftmag[86] +
+ melcoe[173] * fftmag[87] + melcoe[174] * fftmag[88] +
+ melcoe[175] * fftmag[89] + melcoe[176] * fftmag[90] +
+ melcoe[177] * fftmag[91];
+ dout[51] = melcoe[178] * fftmag[89] + melcoe[179] * fftmag[90] +
+ melcoe[180] * fftmag[91] + melcoe[181] * fftmag[92] +
+ melcoe[182] * fftmag[93] + melcoe[183] * fftmag[94] +
+ melcoe[184] * fftmag[95];
+ dout[52] = melcoe[185] * fftmag[92] + melcoe[186] * fftmag[93] +
+ melcoe[187] * fftmag[94] + melcoe[188] * fftmag[95] +
+ melcoe[189] * fftmag[96] + melcoe[190] * fftmag[97] +
+ melcoe[191] * fftmag[98];
+ dout[53] = melcoe[192] * fftmag[96] + melcoe[193] * fftmag[97] +
+ melcoe[194] * fftmag[98] + melcoe[195] * fftmag[99] +
+ melcoe[196] * fftmag[100] + melcoe[197] * fftmag[101] +
+ melcoe[198] * fftmag[102];
+ dout[54] = melcoe[199] * fftmag[99] + melcoe[200] * fftmag[100] +
+ melcoe[201] * fftmag[101] + melcoe[202] * fftmag[102] +
+ melcoe[203] * fftmag[103] + melcoe[204] * fftmag[104] +
+ melcoe[205] * fftmag[105] + melcoe[206] * fftmag[106];
+ dout[55] = melcoe[207] * fftmag[103] + melcoe[208] * fftmag[104] +
+ melcoe[209] * fftmag[105] + melcoe[210] * fftmag[106] +
+ melcoe[211] * fftmag[107] + melcoe[212] * fftmag[108] +
+ melcoe[213] * fftmag[109] + melcoe[214] * fftmag[110];
+ dout[56] = melcoe[215] * fftmag[107] + melcoe[216] * fftmag[108] +
+ melcoe[217] * fftmag[109] + melcoe[218] * fftmag[110] +
+ melcoe[219] * fftmag[111] + melcoe[220] * fftmag[112] +
+ melcoe[221] * fftmag[113] + melcoe[222] * fftmag[114];
+ dout[57] = melcoe[223] * fftmag[111] + melcoe[224] * fftmag[112] +
+ melcoe[225] * fftmag[113] + melcoe[226] * fftmag[114] +
+ melcoe[227] * fftmag[115] + melcoe[228] * fftmag[116] +
+ melcoe[229] * fftmag[117] + melcoe[230] * fftmag[118] +
+ melcoe[231] * fftmag[119];
+ dout[58] = melcoe[232] * fftmag[115] + melcoe[233] * fftmag[116] +
+ melcoe[234] * fftmag[117] + melcoe[235] * fftmag[118] +
+ melcoe[236] * fftmag[119] + melcoe[237] * fftmag[120] +
+ melcoe[238] * fftmag[121] + melcoe[239] * fftmag[122] +
+ melcoe[240] * fftmag[123];
+ dout[59] = melcoe[241] * fftmag[120] + melcoe[242] * fftmag[121] +
+ melcoe[243] * fftmag[122] + melcoe[244] * fftmag[123] +
+ melcoe[245] * fftmag[124] + melcoe[246] * fftmag[125] +
+ melcoe[247] * fftmag[126] + melcoe[248] * fftmag[127] +
+ melcoe[249] * fftmag[128];
+ dout[60] = melcoe[250] * fftmag[124] + melcoe[251] * fftmag[125] +
+ melcoe[252] * fftmag[126] + melcoe[253] * fftmag[127] +
+ melcoe[254] * fftmag[128] + melcoe[255] * fftmag[129] +
+ melcoe[256] * fftmag[130] + melcoe[257] * fftmag[131] +
+ melcoe[258] * fftmag[132];
+ dout[61] = melcoe[259] * fftmag[129] + melcoe[260] * fftmag[130] +
+ melcoe[261] * fftmag[131] + melcoe[262] * fftmag[132] +
+ melcoe[263] * fftmag[133] + melcoe[264] * fftmag[134] +
+ melcoe[265] * fftmag[135] + melcoe[266] * fftmag[136] +
+ melcoe[267] * fftmag[137];
+ dout[62] = melcoe[268] * fftmag[133] + melcoe[269] * fftmag[134] +
+ melcoe[270] * fftmag[135] + melcoe[271] * fftmag[136] +
+ melcoe[272] * fftmag[137] + melcoe[273] * fftmag[138] +
+ melcoe[274] * fftmag[139] + melcoe[275] * fftmag[140] +
+ melcoe[276] * fftmag[141] + melcoe[277] * fftmag[142];
+ dout[63] = melcoe[278] * fftmag[138] + melcoe[279] * fftmag[139] +
+ melcoe[280] * fftmag[140] + melcoe[281] * fftmag[141] +
+ melcoe[282] * fftmag[142] + melcoe[283] * fftmag[143] +
+ melcoe[284] * fftmag[144] + melcoe[285] * fftmag[145] +
+ melcoe[286] * fftmag[146] + melcoe[287] * fftmag[147];
+ dout[64] = melcoe[288] * fftmag[143] + melcoe[289] * fftmag[144] +
+ melcoe[290] * fftmag[145] + melcoe[291] * fftmag[146] +
+ melcoe[292] * fftmag[147] + melcoe[293] * fftmag[148] +
+ melcoe[294] * fftmag[149] + melcoe[295] * fftmag[150] +
+ melcoe[296] * fftmag[151] + melcoe[297] * fftmag[152] +
+ melcoe[298] * fftmag[153];
+ dout[65] = melcoe[299] * fftmag[148] + melcoe[300] * fftmag[149] +
+ melcoe[301] * fftmag[150] + melcoe[302] * fftmag[151] +
+ melcoe[303] * fftmag[152] + melcoe[304] * fftmag[153] +
+ melcoe[305] * fftmag[154] + melcoe[306] * fftmag[155] +
+ melcoe[307] * fftmag[156] + melcoe[308] * fftmag[157] +
+ melcoe[309] * fftmag[158];
+ dout[66] = melcoe[310] * fftmag[154] + melcoe[311] * fftmag[155] +
+ melcoe[312] * fftmag[156] + melcoe[313] * fftmag[157] +
+ melcoe[314] * fftmag[158] + melcoe[315] * fftmag[159] +
+ melcoe[316] * fftmag[160] + melcoe[317] * fftmag[161] +
+ melcoe[318] * fftmag[162] + melcoe[319] * fftmag[163] +
+ melcoe[320] * fftmag[164];
+ dout[67] = melcoe[321] * fftmag[159] + melcoe[322] * fftmag[160] +
+ melcoe[323] * fftmag[161] + melcoe[324] * fftmag[162] +
+ melcoe[325] * fftmag[163] + melcoe[326] * fftmag[164] +
+ melcoe[327] * fftmag[165] + melcoe[328] * fftmag[166] +
+ melcoe[329] * fftmag[167] + melcoe[330] * fftmag[168] +
+ melcoe[331] * fftmag[169] + melcoe[332] * fftmag[170];
+ dout[68] = melcoe[333] * fftmag[165] + melcoe[334] * fftmag[166] +
+ melcoe[335] * fftmag[167] + melcoe[336] * fftmag[168] +
+ melcoe[337] * fftmag[169] + melcoe[338] * fftmag[170] +
+ melcoe[339] * fftmag[171] + melcoe[340] * fftmag[172] +
+ melcoe[341] * fftmag[173] + melcoe[342] * fftmag[174] +
+ melcoe[343] * fftmag[175] + melcoe[344] * fftmag[176];
+ dout[69] = melcoe[345] * fftmag[171] + melcoe[346] * fftmag[172] +
+ melcoe[347] * fftmag[173] + melcoe[348] * fftmag[174] +
+ melcoe[349] * fftmag[175] + melcoe[350] * fftmag[176] +
+ melcoe[351] * fftmag[177] + melcoe[352] * fftmag[178] +
+ melcoe[353] * fftmag[179] + melcoe[354] * fftmag[180] +
+ melcoe[355] * fftmag[181] + melcoe[356] * fftmag[182];
+ dout[70] = melcoe[357] * fftmag[177] + melcoe[358] * fftmag[178] +
+ melcoe[359] * fftmag[179] + melcoe[360] * fftmag[180] +
+ melcoe[361] * fftmag[181] + melcoe[362] * fftmag[182] +
+ melcoe[363] * fftmag[183] + melcoe[364] * fftmag[184] +
+ melcoe[365] * fftmag[185] + melcoe[366] * fftmag[186] +
+ melcoe[367] * fftmag[187] + melcoe[368] * fftmag[188];
+ dout[71] = melcoe[369] * fftmag[183] + melcoe[370] * fftmag[184] +
+ melcoe[371] * fftmag[185] + melcoe[372] * fftmag[186] +
+ melcoe[373] * fftmag[187] + melcoe[374] * fftmag[188] +
+ melcoe[375] * fftmag[189] + melcoe[376] * fftmag[190] +
+ melcoe[377] * fftmag[191] + melcoe[378] * fftmag[192] +
+ melcoe[379] * fftmag[193] + melcoe[380] * fftmag[194] +
+ melcoe[381] * fftmag[195];
+ dout[72] = melcoe[382] * fftmag[189] + melcoe[383] * fftmag[190] +
+ melcoe[384] * fftmag[191] + melcoe[385] * fftmag[192] +
+ melcoe[386] * fftmag[193] + melcoe[387] * fftmag[194] +
+ melcoe[388] * fftmag[195] + melcoe[389] * fftmag[196] +
+ melcoe[390] * fftmag[197] + melcoe[391] * fftmag[198] +
+ melcoe[392] * fftmag[199] + melcoe[393] * fftmag[200] +
+ melcoe[394] * fftmag[201] + melcoe[395] * fftmag[202];
+ dout[73] = melcoe[396] * fftmag[196] + melcoe[397] * fftmag[197] +
+ melcoe[398] * fftmag[198] + melcoe[399] * fftmag[199] +
+ melcoe[400] * fftmag[200] + melcoe[401] * fftmag[201] +
+ melcoe[402] * fftmag[202] + melcoe[403] * fftmag[203] +
+ melcoe[404] * fftmag[204] + melcoe[405] * fftmag[205] +
+ melcoe[406] * fftmag[206] + melcoe[407] * fftmag[207] +
+ melcoe[408] * fftmag[208] + melcoe[409] * fftmag[209];
+ dout[74] = melcoe[410] * fftmag[203] + melcoe[411] * fftmag[204] +
+ melcoe[412] * fftmag[205] + melcoe[413] * fftmag[206] +
+ melcoe[414] * fftmag[207] + melcoe[415] * fftmag[208] +
+ melcoe[416] * fftmag[209] + melcoe[417] * fftmag[210] +
+ melcoe[418] * fftmag[211] + melcoe[419] * fftmag[212] +
+ melcoe[420] * fftmag[213] + melcoe[421] * fftmag[214] +
+ melcoe[422] * fftmag[215] + melcoe[423] * fftmag[216];
+ dout[75] = melcoe[424] * fftmag[210] + melcoe[425] * fftmag[211] +
+ melcoe[426] * fftmag[212] + melcoe[427] * fftmag[213] +
+ melcoe[428] * fftmag[214] + melcoe[429] * fftmag[215] +
+ melcoe[430] * fftmag[216] + melcoe[431] * fftmag[217] +
+ melcoe[432] * fftmag[218] + melcoe[433] * fftmag[219] +
+ melcoe[434] * fftmag[220] + melcoe[435] * fftmag[221] +
+ melcoe[436] * fftmag[222] + melcoe[437] * fftmag[223];
+ dout[76] = melcoe[438] * fftmag[217] + melcoe[439] * fftmag[218] +
+ melcoe[440] * fftmag[219] + melcoe[441] * fftmag[220] +
+ melcoe[442] * fftmag[221] + melcoe[443] * fftmag[222] +
+ melcoe[444] * fftmag[223] + melcoe[445] * fftmag[224] +
+ melcoe[446] * fftmag[225] + melcoe[447] * fftmag[226] +
+ melcoe[448] * fftmag[227] + melcoe[449] * fftmag[228] +
+ melcoe[450] * fftmag[229] + melcoe[451] * fftmag[230] +
+ melcoe[452] * fftmag[231];
+ dout[77] = melcoe[453] * fftmag[224] + melcoe[454] * fftmag[225] +
+ melcoe[455] * fftmag[226] + melcoe[456] * fftmag[227] +
+ melcoe[457] * fftmag[228] + melcoe[458] * fftmag[229] +
+ melcoe[459] * fftmag[230] + melcoe[460] * fftmag[231] +
+ melcoe[461] * fftmag[232] + melcoe[462] * fftmag[233] +
+ melcoe[463] * fftmag[234] + melcoe[464] * fftmag[235] +
+ melcoe[465] * fftmag[236] + melcoe[466] * fftmag[237] +
+ melcoe[467] * fftmag[238] + melcoe[468] * fftmag[239];
+ dout[78] = melcoe[469] * fftmag[232] + melcoe[470] * fftmag[233] +
+ melcoe[471] * fftmag[234] + melcoe[472] * fftmag[235] +
+ melcoe[473] * fftmag[236] + melcoe[474] * fftmag[237] +
+ melcoe[475] * fftmag[238] + melcoe[476] * fftmag[239] +
+ melcoe[477] * fftmag[240] + melcoe[478] * fftmag[241] +
+ melcoe[479] * fftmag[242] + melcoe[480] * fftmag[243] +
+ melcoe[481] * fftmag[244] + melcoe[482] * fftmag[245] +
+ melcoe[483] * fftmag[246] + melcoe[484] * fftmag[247];
+ dout[79] = melcoe[485] * fftmag[240] + melcoe[486] * fftmag[241] +
+ melcoe[487] * fftmag[242] + melcoe[488] * fftmag[243] +
+ melcoe[489] * fftmag[244] + melcoe[490] * fftmag[245] +
+ melcoe[491] * fftmag[246] + melcoe[492] * fftmag[247] +
+ melcoe[493] * fftmag[248] + melcoe[494] * fftmag[249] +
+ melcoe[495] * fftmag[250] + melcoe[496] * fftmag[251] +
+ melcoe[497] * fftmag[252] + melcoe[498] * fftmag[253] +
+ melcoe[499] * fftmag[254] + melcoe[500] * fftmag[255];
+ global_cmvn(dout);
+}
diff --git a/funasr/runtime/cpp/onnxruntime/src/FeatureExtract.h b/funasr/runtime/cpp/onnxruntime/src/FeatureExtract.h
new file mode 100644
index 0000000..f16ea3a
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/FeatureExtract.h
@@ -0,0 +1,36 @@
+
+#ifndef FEATUREEXTRACT_H
+#define FEATUREEXTRACT_H
+
+#include <fftw3.h>
+#include <stdint.h>
+
+#include "FeatureQueue.h"
+#include "SpeechWrap.h"
+#include "Tensor.h"
+
+class FeatureExtract {
+ private:
+ SpeechWrap speech;
+ FeatureQueue fqueue;
+ int mode;
+
+ float *fft_input;
+ fftwf_complex *fft_out;
+ fftwf_plan p;
+
+ void fftw_init();
+ void melspect(float *din, float *dout);
+ void global_cmvn(float *din);
+
+ public:
+ FeatureExtract(int mode);
+ ~FeatureExtract();
+ int size();
+ int status();
+ void reset();
+ void insert(float *din, int len, int flag);
+ bool fetch(Tensor<float> *&dout);
+};
+
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/FeatureQueue.cpp b/funasr/runtime/cpp/onnxruntime/src/FeatureQueue.cpp
new file mode 100644
index 0000000..f07633b
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/FeatureQueue.cpp
@@ -0,0 +1,59 @@
+#include "precomp.h"
+FeatureQueue::FeatureQueue()
+{
+ buff = new Tensor<float>(67, 80);
+ window_size = 67;
+ buff_idx = 0;
+}
+
+FeatureQueue::~FeatureQueue()
+{
+ delete buff;
+}
+
+void FeatureQueue::reinit(int size)
+{
+ delete buff;
+ buff = new Tensor<float>(size, 80);
+ buff_idx = 0;
+ window_size = size;
+}
+
+void FeatureQueue::reset()
+{
+ buff_idx = 0;
+}
+
+void FeatureQueue::push(float *din, int flag)
+{
+ int offset = buff_idx * 80;
+ memcpy(buff->buff + offset, din, 80 * sizeof(float));
+ buff_idx++;
+
+ if (flag == S_END) {
+ Tensor<float> *tmp = new Tensor<float>(buff_idx, 80);
+ memcpy(tmp->buff, buff->buff, buff_idx * 80 * sizeof(float));
+ feature_queue.push(tmp);
+ buff_idx = 0;
+ } else if (buff_idx == window_size) {
+ feature_queue.push(buff);
+ Tensor<float> *tmp = new Tensor<float>(window_size, 80);
+ memcpy(tmp->buff, buff->buff + (window_size - 3) * 80,
+ 3 * 80 * sizeof(float));
+ buff_idx = 3;
+ buff = tmp;
+ }
+}
+
+Tensor<float> *FeatureQueue::pop()
+{
+
+ Tensor<float> *tmp = feature_queue.front();
+ feature_queue.pop();
+ return tmp;
+}
+
+int FeatureQueue::size()
+{
+ return feature_queue.size();
+}
diff --git a/funasr/runtime/cpp/onnxruntime/src/FeatureQueue.h b/funasr/runtime/cpp/onnxruntime/src/FeatureQueue.h
new file mode 100644
index 0000000..be3360b
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/FeatureQueue.h
@@ -0,0 +1,28 @@
+
+#ifndef FEATUREQUEUE_H
+#define FEATUREQUEUE_H
+
+#include "Tensor.h"
+#include <queue>
+#include <stdint.h>
+using namespace std;
+
+
+class FeatureQueue {
+ private:
+ queue<Tensor<float> *> feature_queue;
+ Tensor<float> *buff;
+ int buff_idx;
+ int window_size;
+
+ public:
+ FeatureQueue();
+ ~FeatureQueue();
+ void reinit(int size);
+ void reset();
+ void push(float *din, int flag);
+ Tensor<float> *pop();
+ int size();
+};
+
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/Model.cpp b/funasr/runtime/cpp/onnxruntime/src/Model.cpp
new file mode 100644
index 0000000..ddd4fd0
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/Model.cpp
@@ -0,0 +1,11 @@
+#include "precomp.h"
+
+Model *create_model(const char *path,int nThread)
+{
+ Model *mm;
+
+
+ mm = new paraformer::ModelImp(path, nThread);
+
+ return mm;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/src/SpeechWrap.cpp b/funasr/runtime/cpp/onnxruntime/src/SpeechWrap.cpp
new file mode 100644
index 0000000..60d0a2b
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/SpeechWrap.cpp
@@ -0,0 +1,39 @@
+#include "precomp.h"
+
+SpeechWrap::SpeechWrap()
+{
+ cache_size = 0;
+}
+
+SpeechWrap::~SpeechWrap()
+{
+}
+
+void SpeechWrap::reset()
+{
+ cache_size = 0;
+}
+
+void SpeechWrap::load(float *din, int len)
+{
+ in = din;
+ in_size = len;
+ total_size = cache_size + in_size;
+}
+
+int SpeechWrap::size()
+{
+ return total_size;
+}
+
+void SpeechWrap::update(int offset)
+{
+ int in_offset = offset - cache_size;
+ cache_size = (total_size - offset);
+ memcpy(cache, in + in_offset, cache_size * sizeof(float));
+}
+
+float &SpeechWrap::operator[](int i)
+{
+ return i < cache_size ? cache[i] : in[i - cache_size];
+}
diff --git a/funasr/runtime/cpp/onnxruntime/src/SpeechWrap.h b/funasr/runtime/cpp/onnxruntime/src/SpeechWrap.h
new file mode 100644
index 0000000..5d3ee40
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/SpeechWrap.h
@@ -0,0 +1,26 @@
+
+#ifndef SPEECHWRAP_H
+#define SPEECHWRAP_H
+
+#include <stdint.h>
+
+class SpeechWrap {
+ private:
+ float cache[400];
+ int cache_size;
+ float *in;
+ int in_size;
+ int total_size;
+ int next_cache_size;
+
+ public:
+ SpeechWrap();
+ ~SpeechWrap();
+ void load(float *din, int len);
+ void update(int offset);
+ void reset();
+ int size();
+ float &operator[](int i);
+};
+
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/Tensor.h b/funasr/runtime/cpp/onnxruntime/src/Tensor.h
new file mode 100644
index 0000000..68ac9aa
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/Tensor.h
@@ -0,0 +1,155 @@
+#ifndef TENSOR_H
+#define TENSOR_H
+
+#include "alignedmem.h"
+
+using namespace std;
+
+template <typename T> class Tensor {
+ private:
+ void alloc_buff();
+ void free_buff();
+ int mem_size;
+
+ public:
+ T *buff;
+ int size[4];
+ int buff_size;
+ Tensor(Tensor<T> *in);
+ Tensor(int a);
+ Tensor(int a, int b);
+ Tensor(int a, int b, int c);
+ Tensor(int a, int b, int c, int d);
+ ~Tensor();
+ void zeros();
+ void shape();
+ void disp();
+ void dump(const char *mode);
+ void concat(Tensor<T> *din, int dim);
+ void resize(int a, int b, int c, int d);
+ void add(float coe, Tensor<T> *in);
+ void add(Tensor<T> *in);
+ void add(Tensor<T> *in1, Tensor<T> *in2);
+ void reload(Tensor<T> *in);
+};
+
+template <typename T> Tensor<T>::Tensor(int a) : size{1, 1, 1, a}
+{
+ alloc_buff();
+}
+
+template <typename T> Tensor<T>::Tensor(int a, int b) : size{1, 1, a, b}
+{
+ alloc_buff();
+}
+
+template <typename T> Tensor<T>::Tensor(int a, int b, int c) : size{1, a, b, c}
+{
+
+ alloc_buff();
+}
+
+template <typename T>
+Tensor<T>::Tensor(int a, int b, int c, int d) : size{a, b, c, d}
+{
+ alloc_buff();
+}
+
+template <typename T> Tensor<T>::Tensor(Tensor<T> *in)
+{
+ memcpy(size, in->size, 4 * sizeof(int));
+ alloc_buff();
+ memcpy(buff, in->buff, in->buff_size * sizeof(T));
+}
+
+template <typename T> Tensor<T>::~Tensor()
+{
+ free_buff();
+}
+
+template <typename T> void Tensor<T>::alloc_buff()
+{
+ buff_size = size[0] * size[1] * size[2] * size[3];
+ mem_size = buff_size;
+ buff = (T *)aligned_malloc(32, buff_size * sizeof(T));
+}
+
+template <typename T> void Tensor<T>::free_buff()
+{
+ aligned_free(buff);
+}
+
+template <typename T> void Tensor<T>::zeros()
+{
+ memset(buff, 0, buff_size * sizeof(T));
+}
+
+template <typename T> void Tensor<T>::shape()
+{
+ printf("(%d,%d,%d,%d)\n", size[0], size[1], size[2], size[3]);
+}
+
+// TODO:: fix it!!!!
+template <typename T> void Tensor<T>::concat(Tensor<T> *din, int dim)
+{
+ memcpy(buff + buff_size, din->buff, din->buff_size * sizeof(T));
+ buff_size += din->buff_size;
+ size[dim] += din->size[dim];
+}
+
+// TODO:: fix it!!!!
+template <typename T> void Tensor<T>::resize(int a, int b, int c, int d)
+{
+ size[0] = a;
+ size[1] = b;
+ size[2] = c;
+ size[3] = d;
+ buff_size = size[0] * size[1] * size[2] * size[3];
+}
+
+template <typename T> void Tensor<T>::add(float coe, Tensor<T> *in)
+{
+ int i;
+ for (i = 0; i < buff_size; i++) {
+ buff[i] = buff[i] + coe * in->buff[i];
+ }
+}
+
+template <typename T> void Tensor<T>::add(Tensor<T> *in)
+{
+ int i;
+ for (i = 0; i < buff_size; i++) {
+ buff[i] = buff[i] + in->buff[i];
+ }
+}
+
+template <typename T> void Tensor<T>::add(Tensor<T> *in1, Tensor<T> *in2)
+{
+ int i;
+ for (i = 0; i < buff_size; i++) {
+ buff[i] = buff[i] + in1->buff[i] + in2->buff[i];
+ }
+}
+
+template <typename T> void Tensor<T>::reload(Tensor<T> *in)
+{
+ memcpy(buff, in->buff, in->buff_size * sizeof(T));
+}
+
+template <typename T> void Tensor<T>::disp()
+{
+ int i;
+ for (i = 0; i < buff_size; i++) {
+ cout << buff[i] << " ";
+ }
+ cout << endl;
+}
+
+template <typename T> void Tensor<T>::dump(const char *mode)
+{
+ FILE *fp;
+ fp = fopen("tmp.bin", mode);
+ fwrite(buff, 1, buff_size * sizeof(T), fp);
+ fclose(fp);
+}
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/Vocab.cpp b/funasr/runtime/cpp/onnxruntime/src/Vocab.cpp
new file mode 100644
index 0000000..d2d0341
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/Vocab.cpp
@@ -0,0 +1,170 @@
+#include "Vocab.h"
+
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <sstream>
+#include <string>
+
+using namespace std;
+
+Vocab::Vocab(const char *filename)
+{
+ ifstream in(filename);
+ string line;
+
+ if (in) // 鏈夎鏂囦欢
+ {
+ while (getline(in, line)) // line涓笉鍖呮嫭姣忚鐨勬崲琛岀
+ {
+ vocab.push_back(line);
+ }
+ // cout << vocab[1719] << endl;
+ }
+ // else // 娌℃湁璇ユ枃浠�
+ //{
+ // cout << "no such file" << endl;
+ // }
+}
+Vocab::~Vocab()
+{
+}
+
+string Vocab::vector2string(vector<int> in)
+{
+ int i;
+ stringstream ss;
+ for (auto it = in.begin(); it != in.end(); it++) {
+ ss << vocab[*it];
+ }
+
+ return ss.str();
+}
+
+int str2int(string str)
+{
+ const char *ch_array = str.c_str();
+ if (((ch_array[0] & 0xf0) != 0xe0) || ((ch_array[1] & 0xc0) != 0x80) ||
+ ((ch_array[2] & 0xc0) != 0x80))
+ return 0;
+
+ int val = ((ch_array[0] & 0x0f) << 12) | ((ch_array[1] & 0x3f) << 6) |
+ (ch_array[2] & 0x3f);
+ return val;
+}
+
+bool Vocab::isChinese(string ch)
+{
+ if (ch.size() != 3) {
+ return false;
+ }
+
+ int unicode = str2int(ch);
+ if (unicode >= 19968 && unicode <= 40959) {
+ return true;
+ }
+
+ return false;
+}
+
+
+string Vocab::vector2stringV2(vector<int> in)
+{
+ int i;
+ list<string> words;
+
+ int is_pre_english = false;
+ int pre_english_len = 0;
+
+ int is_combining = false;
+ string combine = "";
+
+ for (auto it = in.begin(); it != in.end(); it++) {
+ string word = vocab[*it];
+
+ // step1 space character skips
+ if (word == "<s>" || word == "</s>" || word == "<unk>")
+ continue;
+
+ // step2 combie phoneme to full word
+ {
+ int sub_word = !(word.find("@@") == string::npos);
+
+ // process word start and middle part
+ if (sub_word) {
+ combine += word.erase(word.length() - 2);
+ is_combining = true;
+ continue;
+ }
+ // process word end part
+ else if (is_combining) {
+ combine += word;
+ is_combining = false;
+ word = combine;
+ combine = "";
+ }
+ }
+
+ // step3 process english word deal with space , turn abbreviation to upper case
+ {
+
+ // input word is chinese, not need process
+ if (isChinese(word)) {
+ words.push_back(word);
+ is_pre_english = false;
+ }
+ // input word is english word
+ else {
+
+ // pre word is chinese
+ if (!is_pre_english) {
+ word[0] = word[0] - 32;
+ words.push_back(word);
+ pre_english_len = word.size();
+
+ }
+
+ // pre word is english word
+ else {
+
+ // single letter turn to upper case
+ if (word.size() == 1) {
+ word[0] = word[0] - 32;
+ }
+
+ if (pre_english_len > 1) {
+ words.push_back(" ");
+ words.push_back(word);
+ pre_english_len = word.size();
+ }
+ else {
+ if (word.size() > 1) {
+ words.push_back(" ");
+ }
+ words.push_back(word);
+ pre_english_len = word.size();
+ }
+ }
+
+ is_pre_english = true;
+
+ }
+ }
+ }
+
+ // for (auto it = words.begin(); it != words.end(); it++) {
+ // cout << *it << endl;
+ // }
+
+ stringstream ss;
+ for (auto it = words.begin(); it != words.end(); it++) {
+ ss << *it;
+ }
+
+ return ss.str();
+}
+
+int Vocab::size()
+{
+ return vocab.size();
+}
diff --git a/funasr/runtime/cpp/onnxruntime/src/Vocab.h b/funasr/runtime/cpp/onnxruntime/src/Vocab.h
new file mode 100644
index 0000000..328a2a1
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/Vocab.h
@@ -0,0 +1,24 @@
+
+#ifndef VOCAB_H
+#define VOCAB_H
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+using namespace std;
+
+class Vocab {
+ private:
+ vector<string> vocab;
+ bool isChinese(string ch);
+ bool isEnglish(string ch);
+
+ public:
+ Vocab(const char *filename);
+ ~Vocab();
+ int size();
+ string vector2string(vector<int> in);
+ string vector2stringV2(vector<int> in);
+};
+
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/alignedmem.cpp b/funasr/runtime/cpp/onnxruntime/src/alignedmem.cpp
new file mode 100644
index 0000000..e174afe
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/alignedmem.cpp
@@ -0,0 +1,18 @@
+#include "precomp.h"
+void *aligned_malloc(size_t alignment, size_t required_bytes)
+{
+ void *p1; // original block
+ void **p2; // aligned block
+ int offset = alignment - 1 + sizeof(void *);
+ if ((p1 = (void *)malloc(required_bytes + offset)) == NULL) {
+ return NULL;
+ }
+ p2 = (void **)(((size_t)(p1) + offset) & ~(alignment - 1));
+ p2[-1] = p1;
+ return p2;
+}
+
+void aligned_free(void *p)
+{
+ free(((void **)p)[-1]);
+}
diff --git a/funasr/runtime/cpp/onnxruntime/src/alignedmem.h b/funasr/runtime/cpp/onnxruntime/src/alignedmem.h
new file mode 100644
index 0000000..dca68f4
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/alignedmem.h
@@ -0,0 +1,10 @@
+
+#ifndef ALIGNEDMEM_H
+#define ALIGNEDMEM_H
+
+
+
+extern void *aligned_malloc(size_t alignment, size_t required_bytes);
+extern void aligned_free(void *p);
+
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/commonfunc.h b/funasr/runtime/cpp/onnxruntime/src/commonfunc.h
new file mode 100644
index 0000000..3f3c53a
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/commonfunc.h
@@ -0,0 +1,45 @@
+#pragma once
+#ifdef _WIN32
+#include <codecvt>
+
+inline std::wstring string2wstring(const std::string& str, const std::string& locale)
+{
+ typedef std::codecvt_byname<wchar_t, char, std::mbstate_t> F;
+ std::wstring_convert<F> strCnv(new F(locale));
+ return strCnv.from_bytes(str);
+}
+
+inline std::wstring strToWstr(std::string str) {
+ if (str.length() == 0)
+ return L"";
+ return string2wstring(str, "zh-CN");
+
+}
+
+#endif
+
+
+
+inline void getInputName(Ort::Session* session, string& inputName,int nIndex=0) {
+ size_t numInputNodes = session->GetInputCount();
+ if (numInputNodes > 0) {
+ Ort::AllocatorWithDefaultOptions allocator;
+ {
+ auto t = session->GetInputNameAllocated(nIndex, allocator);
+ inputName = t.get();
+
+ }
+ }
+}
+
+inline void getOutputName(Ort::Session* session, string& outputName, int nIndex = 0) {
+ size_t numOutputNodes = session->GetOutputCount();
+ if (numOutputNodes > 0) {
+ Ort::AllocatorWithDefaultOptions allocator;
+ {
+ auto t = session->GetOutputNameAllocated(nIndex, allocator);
+ outputName = t.get();
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/funasr/runtime/cpp/onnxruntime/src/paraformer_onnx.cpp b/funasr/runtime/cpp/onnxruntime/src/paraformer_onnx.cpp
new file mode 100644
index 0000000..46b5211
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/paraformer_onnx.cpp
@@ -0,0 +1,179 @@
+#include "precomp.h"
+
+using namespace std;
+using namespace paraformer;
+
+ModelImp::ModelImp(const char* path,int nNumThread)
+{
+ string model_path = pathAppend(path, "model.onnx");
+ string vocab_path = pathAppend(path, "vocab.txt");
+
+ fe = new FeatureExtract(3);
+
+ sessionOptions.SetInterOpNumThreads(nNumThread);
+ sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);
+
+#ifdef _WIN32
+ wstring wstrPath = strToWstr(model_path);
+ m_session = new Ort::Session(env, wstrPath.c_str(), sessionOptions);
+#else
+ m_session = new Ort::Session(env, model_path.c_str(), sessionOptions);
+#endif
+
+ string strName;
+ getInputName(m_session, strName);
+ m_strInputNames.push_back(strName.c_str());
+ getInputName(m_session, strName,1);
+ m_strInputNames.push_back(strName);
+
+ getOutputName(m_session, strName);
+ m_strOutputNames.push_back(strName);
+ getOutputName(m_session, strName,1);
+ m_strOutputNames.push_back(strName);
+
+ for (auto& item : m_strInputNames)
+ m_szInputNames.push_back(item.c_str());
+ for (auto& item : m_strOutputNames)
+ m_szOutputNames.push_back(item.c_str());
+ vocab = new Vocab(vocab_path.c_str());
+}
+
+ModelImp::~ModelImp()
+{
+ if(fe)
+ delete fe;
+ if (m_session)
+ {
+ delete m_session;
+ m_session = nullptr;
+ }
+ if(vocab)
+ delete vocab;
+}
+
+void ModelImp::reset()
+{
+ fe->reset();
+}
+
+void ModelImp::apply_lfr(Tensor<float>*& din)
+{
+ int mm = din->size[2];
+ int ll = ceil(mm / 6.0);
+ Tensor<float>* tmp = new Tensor<float>(ll, 560);
+ int out_offset = 0;
+ for (int i = 0; i < ll; i++) {
+ for (int j = 0; j < 7; j++) {
+ int idx = i * 6 + j - 3;
+ if (idx < 0) {
+ idx = 0;
+ }
+ if (idx >= mm) {
+ idx = mm - 1;
+ }
+ memcpy(tmp->buff + out_offset, din->buff + idx * 80,
+ sizeof(float) * 80);
+ out_offset += 80;
+ }
+ }
+ delete din;
+ din = tmp;
+}
+
+void ModelImp::apply_cmvn(Tensor<float>* din)
+{
+ const float* var;
+ const float* mean;
+ float scale = 22.6274169979695;
+ int m = din->size[2];
+ int n = din->size[3];
+
+ var = (const float*)paraformer_cmvn_var_hex;
+ mean = (const float*)paraformer_cmvn_mean_hex;
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ int idx = i * n + j;
+ din->buff[idx] = (din->buff[idx] + mean[j]) * var[j];
+ }
+ }
+}
+
+string ModelImp::greedy_search(float * in, int nLen )
+{
+ vector<int> hyps;
+ int Tmax = nLen;
+ for (int i = 0; i < Tmax; i++) {
+ int max_idx;
+ float max_val;
+ findmax(in + i * 8404, 8404, max_val, max_idx);
+ hyps.push_back(max_idx);
+ }
+
+ return vocab->vector2stringV2(hyps);
+}
+
+string ModelImp::forward(float* din, int len, int flag)
+{
+
+ Tensor<float>* in;
+ fe->insert(din, len, flag);
+ fe->fetch(in);
+ apply_lfr(in);
+ apply_cmvn(in);
+ Ort::RunOptions run_option;
+
+ std::array<int64_t, 3> input_shape_{ in->size[0],in->size[2],in->size[3] };
+ Ort::Value onnx_feats = Ort::Value::CreateTensor<float>(m_memoryInfo,
+ in->buff,
+ in->buff_size,
+ input_shape_.data(),
+ input_shape_.size());
+
+ std::vector<int32_t> feats_len{ in->size[2] };
+ std::vector<int64_t> feats_len_dim{ 1 };
+ Ort::Value onnx_feats_len = Ort::Value::CreateTensor(
+ m_memoryInfo,
+ feats_len.data(),
+ feats_len.size() * sizeof(int32_t),
+ feats_len_dim.data(),
+ feats_len_dim.size(), ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32);
+ std::vector<Ort::Value> input_onnx;
+ input_onnx.emplace_back(std::move(onnx_feats));
+ input_onnx.emplace_back(std::move(onnx_feats_len));
+
+ string result;
+ try {
+
+ auto outputTensor = m_session->Run(run_option, m_szInputNames.data(), input_onnx.data(), m_szInputNames.size(), m_szOutputNames.data(), m_szOutputNames.size());
+ std::vector<int64_t> outputShape = outputTensor[0].GetTensorTypeAndShapeInfo().GetShape();
+
+
+ int64_t outputCount = std::accumulate(outputShape.begin(), outputShape.end(), 1, std::multiplies<int64_t>());
+ float* floatData = outputTensor[0].GetTensorMutableData<float>();
+ auto encoder_out_lens = outputTensor[1].GetTensorMutableData<int64_t>();
+ result = greedy_search(floatData, *encoder_out_lens);
+ }
+ catch (...)
+ {
+ result = "";
+ }
+
+
+ if(in)
+ delete in;
+
+ return result;
+}
+
+string ModelImp::forward_chunk(float* din, int len, int flag)
+{
+
+ printf("Not Imp!!!!!!\n");
+ return "Hello";
+}
+
+string ModelImp::rescoring()
+{
+ printf("Not Imp!!!!!!\n");
+ return "Hello";
+}
diff --git a/funasr/runtime/cpp/onnxruntime/src/paraformer_onnx.h b/funasr/runtime/cpp/onnxruntime/src/paraformer_onnx.h
new file mode 100644
index 0000000..ebbbb51
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/paraformer_onnx.h
@@ -0,0 +1,52 @@
+#pragma once
+
+
+#ifndef PARAFORMER_MODELIMP_H
+#define PARAFORMER_MODELIMP_H
+
+
+
+
+
+namespace paraformer {
+
+ class ModelImp : public Model {
+ private:
+ FeatureExtract* fe;
+
+ Vocab* vocab;
+
+ void apply_lfr(Tensor<float>*& din);
+ void apply_cmvn(Tensor<float>* din);
+
+
+ string greedy_search( float* in, int nLen);
+
+#ifdef _WIN_X86
+ Ort::MemoryInfo m_memoryInfo = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);
+#else
+ Ort::MemoryInfo m_memoryInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
+#endif
+
+ Ort::Session* m_session = nullptr;
+ Ort::Env env = Ort::Env(ORT_LOGGING_LEVEL_ERROR, "paraformer");
+ Ort::SessionOptions sessionOptions = Ort::SessionOptions();
+
+ vector<string> m_strInputNames, m_strOutputNames;
+ vector<const char*> m_szInputNames;
+ vector<const char*> m_szOutputNames;
+ //string m_strInputName, m_strInputNameLen;
+ //string m_strOutputName, m_strOutputNameLen;
+
+ public:
+ ModelImp(const char* path, int nNumThread=0);
+ ~ModelImp();
+ void reset();
+ string forward_chunk(float* din, int len, int flag);
+ string forward(float* din, int len, int flag);
+ string rescoring();
+
+ };
+
+} // namespace paraformer
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/precomp.h b/funasr/runtime/cpp/onnxruntime/src/precomp.h
new file mode 100644
index 0000000..ec0766d
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/precomp.h
@@ -0,0 +1,49 @@
+#pragma once
+// system
+
+#include <iostream>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <deque>
+#include <iostream>
+#include <list>
+#include <locale.h>
+#include <vector>
+#include <string>
+#include <math.h>
+#include <numeric>
+
+
+#include <cstring>
+
+using namespace std;
+// third part
+
+#include <fftw3.h>
+#include "onnxruntime_run_options_config_keys.h"
+#include "onnxruntime_cxx_api.h"
+
+
+// mine
+
+#include "commonfunc.h"
+#include <ComDefine.h>
+#include "predefine_coe.h"
+
+#include <ComDefine.h>
+//#include "alignedmem.h"
+#include "Vocab.h"
+#include "Tensor.h"
+#include "util.h"
+#include "CommonStruct.h"
+#include "FeatureExtract.h"
+#include "FeatureQueue.h"
+#include "SpeechWrap.h"
+#include "Model.h"
+#include "paraformer_onnx.h"
+
+
+
+using namespace paraformer;
diff --git a/funasr/runtime/cpp/onnxruntime/src/predefine_coe.h b/funasr/runtime/cpp/onnxruntime/src/predefine_coe.h
new file mode 100644
index 0000000..93012d8
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/predefine_coe.h
@@ -0,0 +1,592 @@
+#ifndef PREDEFINE_COE_H
+#define PREDEFINE_COE_H
+
+#include <stdint.h>
+
+const int32_t melcoe_hex[] = {
+
+ 0x3f01050c, 0x3e0afb11, 0x3f5d413c, 0x3f547fd0, 0x3e2e00c1, 0x3f132970,
+ 0x3ed9ad21, 0x3ebb8bb9, 0x3f223a24, 0x3e4de6f8, 0x3f4c8642, 0x3d9c0424,
+ 0x3f6c7f7c, 0x3f7d295a, 0x3c35a961, 0x3f6fd497, 0x3d815b45, 0x3f6af197,
+ 0x3da87344, 0x3f6dfce9, 0x3d9018b9, 0x3f787ebc, 0x3d2098fe, 0x3cf02873,
+ 0x3f75f670, 0x3e08e423, 0x3f5dc6f7, 0x3e8161eb, 0x3f3f4f0b, 0x3eca38e2,
+ 0x3f1ae38f, 0x3f0f2d23, 0x3ee1a5ba, 0x3f3e9a98, 0x3e82cad1, 0x3f7321ac,
+ 0x3e321028, 0x3d4de548, 0x3f537bf6, 0x3ed50f76, 0x3f157845, 0x3f2cf6bc,
+ 0x3ea61288, 0x3f739ea7, 0x3e794186, 0x3d461590, 0x3f41af9f, 0x3f0cdfd4,
+ 0x3ee64058, 0x3f5f23aa, 0x3e53d467, 0x3e037156, 0x3f4b0ae6, 0x3f0e2fac,
+ 0x3ee3a0a8, 0x3f6ab111, 0x3e94b1ed, 0x3daa7774, 0x3f35a70a, 0x3f2d08dc,
+ 0x3d951fb4, 0x3ea5ee48, 0x3f6d5c09, 0x3ef61e1a, 0x3f04f0f3, 0x3f66305c,
+ 0x3ea7def9, 0x3dce7d20, 0x3f2c1083, 0x3f44354b, 0x3e5baf49, 0x3e6f2ad2,
+ 0x3f49142e, 0x3f2bfe35, 0x3e0d627b, 0x3ea80396, 0x3f5ca761, 0x3f1ce830,
+ 0x3dc4d786, 0x3ec62fa0, 0x3f67650f, 0x3f165fc0, 0x3db1323f, 0x3ed34080,
+ 0x3f69d9b8, 0x3f17def1, 0x3ddbd6b6, 0x3ed0421e, 0x3f648529, 0x3f20ebbd,
+ 0x3e20901a, 0x3ebe2886, 0x3f57dbf9, 0x3f3116ac, 0x3e6edcc6, 0x3e9dd2a9,
+ 0x3f4448ce, 0x3f47f9a3, 0x3eaba511, 0x3e601974, 0x3f2a2d77, 0x3f6536e2,
+ 0x3eec3842, 0x3d0781f6, 0x3dd648ed, 0x3f09e3df, 0x3f7787e1, 0x3f1c411f,
+ 0x3e45b702, 0x3ec77dc2, 0x3f4e9240, 0x3f47f500, 0x3ebf9c61, 0x3e602c00,
+ 0x3f2031d0, 0x3f78f0f7, 0x3f135547, 0x3e3bcd78, 0x3ce1e12a, 0x3ed95573,
+ 0x3f510ca2, 0x3f4bc3c2, 0x3ed37e77, 0x3d0ded37, 0x3e50f0f8, 0x3f1640c5,
+ 0x3f77212d, 0x3f291bd1, 0x3e94df6c, 0x3eadc85e, 0x3f35904a, 0x3f6cd43b,
+ 0x3f104351, 0x3e52dc63, 0x3d995e26, 0x3edf795f, 0x3f4b48e7, 0x3f5a29e7,
+ 0x3f00963d, 0x3e1fdb2f, 0x3e175865, 0x3efed385, 0x3f580934, 0x3f50466d,
+ 0x3ef30046, 0x3e0e7c6b, 0x3e3ee64e, 0x3f067fdd, 0x3f5c60e5, 0x3f4e9ea4,
+ 0x3ef4f46a, 0x3e1cb596, 0x3e45856f, 0x3f0585cb, 0x3f58d29b, 0x3f54b3ef,
+ 0x3f0309ad, 0x3e48aa5b, 0x3e2d3042, 0x3ef9eca6, 0x3f4dd569, 0x3f6212c4,
+ 0x3f12be68, 0x3e8853a3, 0x3def69e0, 0x3eda8330, 0x3f3bd62e, 0x3f76516a,
+ 0x3f2931b5, 0x3eb98e9b, 0x3d88773c, 0x3d1ae95c, 0x3ead9c96, 0x3f2338b2,
+ 0x3f6ef119, 0x3f46054d, 0x3ef74eba, 0x3e47c83a, 0x3e67eace, 0x3f0458a3,
+ 0x3f4e0df1, 0x3f68e26b, 0x3f207590, 0x3eb1515d, 0x3d8bc852, 0x3db8eca9,
+ 0x3ebf14e0, 0x3f275751, 0x3f6e86f6, 0x3f4ae3f8, 0x3f04e6de, 0x3e7dfcce,
+ 0x3e547020, 0x3ef63244, 0x3f4080cd, 0x3f7aaa80, 0x3f366659, 0x3ee560cb,
+ 0x3e3e1967, 0x3caab00e, 0x3e93334e, 0x3f0d4f9a, 0x3f5079a6, 0x3f6ce5f8,
+ 0x3f2acd10, 0x3ed272ff, 0x3e20a4c5, 0x3d98d042, 0x3eaa65e0, 0x3f16c680,
+ 0x3f57d6cf, 0x3f679a1b, 0x3f278a40, 0x3ecfef5c, 0x3e2381fd, 0x3dc32f28,
+ 0x3eb0eb80, 0x3f180852, 0x3f571f81, 0x3f6a42d8, 0x3f2c1ce8, 0x3edcd9d1,
+ 0x3e44c475, 0x3dade93f, 0x3ea7c630, 0x3f119318, 0x3f4ecee3, 0x3f7467d4,
+ 0x3f380f62, 0x3ef84c54, 0x3e815525, 0x3cb361d7, 0x3d3982c8, 0x3e8fe13b,
+ 0x3f03d9d6, 0x3f3f556d, 0x3f7a64f1, 0x3f4af618, 0x3f10ba30, 0x3eadcbc5,
+ 0x3debbe02, 0x3e5427a0, 0x3ede8b9f, 0x3f291a1d, 0x3f628840, 0x3f646e63,
+ 0x3f2bc86b, 0x3ee70902, 0x3e6e854e, 0x3c83b300, 0x3ddc8cea, 0x3ea86f2a,
+ 0x3f0c7b7f, 0x3f445eac, 0x3f7be268, 0x3f4cf80b, 0x3f162f6e, 0x3ebf8516,
+ 0x3e26c0c2, 0x3e4c1fd5, 0x3ed3a124, 0x3f203d75, 0x3f564fd0, 0x3f73f733,
+ 0x3f3e966d, 0x3f098cbf, 0x3ea9b21c, 0x3e01e917, 0x3d408cd1, 0x3e82d326,
+ 0x3eece682, 0x3f2b26f2, 0x3f5f85ba, 0x3f6c6f56, 0x3f38b733, 0x3f0550d9,
+ 0x3ea47689, 0x3dfbabd7, 0x3d9c8552, 0x3e8e919a, 0x3ef55e4f, 0x3f2dc4bb,
+ 0x3f608a85, 0x3f6cfe84, 0x3f3ad56c, 0x3f08f945, 0x3eaed247, 0x3e189086,
+ 0x3d980be2, 0x3e8a5528, 0x3eee0d76, 0x3f2896dc, 0x3f59dbde, 0x3f75295d,
+ 0x3f4477f6, 0x3f140f14, 0x3ec7dbbd, 0x3e504e0f, 0x3c8fe67e, 0x3d2d6a38,
+ 0x3e6e2028, 0x3ed7e1d9, 0x3f1c1221, 0x3f4bec7c, 0x3f7b80cc, 0x3f553023,
+ 0x3f262589, 0x3eeebd40, 0x3e91b54d, 0x3dd4c6f8, 0x3e2b3f74, 0x3eb3b4ef,
+ 0x3f08a160, 0x3f372559, 0x3f656721, 0x3f6c988d, 0x3f3ed8f9, 0x3f11596d,
+ 0x3ec83270, 0x3e5c5ea4, 0x3d254149, 0x3d9b3b97, 0x3e824e0e, 0x3edd4d25,
+ 0x3f1be6c8, 0x3f48e857, 0x3f75abeb, 0x3f5dcdd1, 0x3f318436, 0x3f0576a0,
+ 0x3eb348db, 0x3e3833fb, 0x3c2bedc9, 0x3e08c8be, 0x3e9cf794, 0x3ef512c0,
+ 0x3f265b92, 0x3f51f301, 0x3f7d5049, 0x3f578bfc, 0x3f2ca136, 0x3f01eecf,
+ 0x3eaee867, 0x3e34c34c, 0x3c490794, 0x3e21d00f, 0x3ea6bd94, 0x3efc2262,
+ 0x3f288bcc, 0x3f52cf2d, 0x3f7cdbe2, 0x3f594d89, 0x3f2fac87, 0x3f064092,
+ 0x3eba1245, 0x3e5016cd, 0x3d335c27, 0x3e1ac9dd, 0x3ea0a6f1, 0x3ef37edc,
+ 0x3f22f6de, 0x3f4bfa4d, 0x3f74ca3e, 0x3f6298cf, 0x3f3a2e5b, 0x3f11f5e8,
+ 0x3ed3ddf9, 0x3e84323c, 0x3dd39eaa, 0x3deb3986, 0x3e8ba34a, 0x3edc142f,
+ 0x3f161103, 0x3f3de6e2, 0x3f658c2b, 0x3f72feac, 0x3f4bb92e, 0x3f24a2e9,
+ 0x3efb76d9, 0x3eae048f, 0x3e41dc34, 0x3d219509, 0x3d50153e, 0x3e511b46,
+ 0x3eb6ba2d, 0x3f024494, 0x3f28fdb9, 0x3f4f88f3, 0x3f75e6af, 0x3f63e8a7,
+ 0x3f3de4a8, 0x3f180cea, 0x3ee4c20e, 0x3e99c134, 0x3e1e2cfc, 0x3c1824f4,
+ 0x3de0bac6, 0x3e8436b1, 0x3ecfe62d, 0x3f0d9ef9, 0x3f331f66, 0x3f5874c1,
+ 0x3f7d9f6c, 0x3f5d6037, 0x3f3889c9, 0x3f13dcea, 0x3edeb27d, 0x3e95fcd3,
+ 0x3e1b303e, 0x3c3075cb, 0x3e0a7f24, 0x3e8eec6e, 0x3ed8462b, 0x3f10a6c1,
+ 0x3f350197, 0x3f5933f1, 0x3f7d3e29, 0x3f5edf68, 0x3f3b246a, 0x3f179088,
+ 0x3ee846d8, 0x3ea1b983, 0x3e36f0d8, 0x3d2c1773, 0x3e048260, 0x3e89b72b,
+ 0x3ed0def0, 0x3f0bdc94, 0x3f2f233e, 0x3f5243ca, 0x3f753e89, 0x3f67ec34,
+ 0x3f453c1d, 0x3f22b0e2, 0x3f004a36, 0x3ebc0f98, 0x3e6fa55d, 0x3dcf7467,
+ 0x3dc09e5f, 0x3e6b0f8d, 0x3eba9e3c, 0x3eff6b94, 0x3f21f834, 0x3f4416a9,
+ 0x3f661173, 0x3f781723, 0x3f5662cf, 0x3f34d14a, 0x3f13624c, 0x3ee42b1a,
+ 0x3ea1d591, 0x3e3f86e3, 0x3d6fa1a1, 0x3cfd1ba9, 0x3e2674c3, 0x3e965d6c,
+ 0x3ed93b69, 0x3f0dea73, 0x3f2f1538, 0x3f501e47, 0x3f7105e6, 0x3f6e33a9,
+ 0x3f4d8e22, 0x3f2d0944, 0x3f0ca4cd, 0x3ed8c0fd, 0x3e98782f, 0x3e30dd66,
+ 0x3d452061, 0x3d8e62bc, 0x3e49c779, 0x3ea5ed78, 0x3ee6b665, 0x3f139f81,
+ 0x3f33c3e8, 0x3f53c8a7, 0x3f73adfa, 0x3f6c8be0, 0x3f4ce4ab, 0x3f2d5c2a,
+ 0x3f0df223, 0x3edd4cb5, 0x3e9ef12d, 0x3e41a276, 0x3d8bb1ba, 0x3d9ba0ff,
+ 0x3e4c6d54, 0x3ea547ab, 0x3ee41bba, 0x3f1159a6, 0x3f30876a, 0x3f4f9762,
+ 0x3f6e89c9, 0x3f72a12b, 0x3f53e942, 0x3f354e46, 0x3f16cffe, 0x3ef0dc6f,
+ 0x3eb45177, 0x3e6ffd59, 0x3def8e9c
+
+};
+
+const int32_t window_hex[] = {
+ 0x00000000, 0x398b03f6, 0x3a61d1c5, 0x3ae0ee32, 0x3b37623a, 0x3b85f871,
+ 0x3bb69d19, 0x3bed453b, 0x3c14d40b, 0x3c35c45b, 0x3c59595d, 0x3c7f7c1d,
+ 0x3c940c13, 0x3ca98d81, 0x3cc039eb, 0x3cd8098d, 0x3cf0f52e, 0x3d057b06,
+ 0x3d1302e6, 0x3d210f33, 0x3d2f9d0e, 0x3d3ea9ba, 0x3d4e3293, 0x3d5e3510,
+ 0x3d6eaebd, 0x3d7f9d38, 0x3d887f19, 0x3d9167b5, 0x3d9a8756, 0x3da3dce9,
+ 0x3dad675d, 0x3db725ab, 0x3dc116cc, 0x3dcb39bf, 0x3dd58d86, 0x3de01126,
+ 0x3deac3a7, 0x3df5a413, 0x3e0058bb, 0x3e05f571, 0x3e0ba7b2, 0x3e116f08,
+ 0x3e174afe, 0x3e1d3b1c, 0x3e233ef0, 0x3e295605, 0x3e2f7fe7, 0x3e35bc23,
+ 0x3e3c0a46, 0x3e4269de, 0x3e48da79, 0x3e4f5ba5, 0x3e55ecf2, 0x3e5c8ded,
+ 0x3e633e26, 0x3e69fd2c, 0x3e70ca8f, 0x3e77a5de, 0x3e7e8eaa, 0x3e82c241,
+ 0x3e86437c, 0x3e89cacd, 0x3e8d57fc, 0x3e90ead3, 0x3e948319, 0x3e982097,
+ 0x3e9bc316, 0x3e9f6a5d, 0x3ea31636, 0x3ea6c66a, 0x3eaa7ac0, 0x3eae3303,
+ 0x3eb1eefa, 0x3eb5ae6f, 0x3eb9712a, 0x3ebd36f6, 0x3ec0ff9b, 0x3ec4cae2,
+ 0x3ec89895, 0x3ecc687d, 0x3ed03a64, 0x3ed40e13, 0x3ed7e354, 0x3edbb9f2,
+ 0x3edf91b5, 0x3ee36a69, 0x3ee743d7, 0x3eeb1dca, 0x3eeef80c, 0x3ef2d267,
+ 0x3ef6aca8, 0x3efa8698, 0x3efe6002, 0x3f011c59, 0x3f03083a, 0x3f04f389,
+ 0x3f06de2d, 0x3f08c80b, 0x3f0ab10a, 0x3f0c990f, 0x3f0e8001, 0x3f1065c6,
+ 0x3f124a45, 0x3f142d65, 0x3f160f0c, 0x3f17ef21, 0x3f19cd8b, 0x3f1baa32,
+ 0x3f1d84fb, 0x3f1f5dd0, 0x3f213498, 0x3f230939, 0x3f24db9d, 0x3f26abaa,
+ 0x3f28794a, 0x3f2a4464, 0x3f2c0ce1, 0x3f2dd2a9, 0x3f2f95a6, 0x3f3155bf,
+ 0x3f3312e0, 0x3f34ccef, 0x3f3683d8, 0x3f383784, 0x3f39e7dd, 0x3f3b94cc,
+ 0x3f3d3e3c, 0x3f3ee418, 0x3f40864a, 0x3f4224bd, 0x3f43bf5c, 0x3f455613,
+ 0x3f46e8cc, 0x3f487774, 0x3f4a01f6, 0x3f4b883f, 0x3f4d0a3b, 0x3f4e87d6,
+ 0x3f5000fe, 0x3f5175a0, 0x3f52e5a9, 0x3f545106, 0x3f55b7a5, 0x3f571975,
+ 0x3f587664, 0x3f59ce60, 0x3f5b2158, 0x3f5c6f3b, 0x3f5db7f9, 0x3f5efb80,
+ 0x3f6039c2, 0x3f6172af, 0x3f62a636, 0x3f63d448, 0x3f64fcd6, 0x3f661fd3,
+ 0x3f673d2e, 0x3f6854db, 0x3f6966ca, 0x3f6a72ef, 0x3f6b793d, 0x3f6c79a5,
+ 0x3f6d741d, 0x3f6e6896, 0x3f6f5706, 0x3f703f5f, 0x3f712198, 0x3f71fda4,
+ 0x3f72d379, 0x3f73a30c, 0x3f746c52, 0x3f752f43, 0x3f75ebd4, 0x3f76a1fc,
+ 0x3f7751b2, 0x3f77faee, 0x3f789da6, 0x3f7939d4, 0x3f79cf6e, 0x3f7a5e6f,
+ 0x3f7ae6cf, 0x3f7b6886, 0x3f7be38f, 0x3f7c57e4, 0x3f7cc57f, 0x3f7d2c5b,
+ 0x3f7d8c72, 0x3f7de5bf, 0x3f7e3840, 0x3f7e83ee, 0x3f7ec8c7, 0x3f7f06c7,
+ 0x3f7f3deb, 0x3f7f6e31, 0x3f7f9795, 0x3f7fba17, 0x3f7fd5b4, 0x3f7fea6b,
+ 0x3f7ff83b, 0x3f7fff23, 0x3f7fff23, 0x3f7ff83b, 0x3f7fea6b, 0x3f7fd5b4,
+ 0x3f7fba17, 0x3f7f9795, 0x3f7f6e31, 0x3f7f3deb, 0x3f7f06c7, 0x3f7ec8c7,
+ 0x3f7e83ee, 0x3f7e3840, 0x3f7de5bf, 0x3f7d8c72, 0x3f7d2c5b, 0x3f7cc57f,
+ 0x3f7c57e4, 0x3f7be38f, 0x3f7b6886, 0x3f7ae6cf, 0x3f7a5e6f, 0x3f79cf6e,
+ 0x3f7939d4, 0x3f789da6, 0x3f77faee, 0x3f7751b2, 0x3f76a1fc, 0x3f75ebd4,
+ 0x3f752f43, 0x3f746c52, 0x3f73a30c, 0x3f72d379, 0x3f71fda4, 0x3f712198,
+ 0x3f703f5f, 0x3f6f5706, 0x3f6e6896, 0x3f6d741d, 0x3f6c79a5, 0x3f6b793d,
+ 0x3f6a72ef, 0x3f6966ca, 0x3f6854db, 0x3f673d2e, 0x3f661fd3, 0x3f64fcd6,
+ 0x3f63d448, 0x3f62a636, 0x3f6172af, 0x3f6039c2, 0x3f5efb80, 0x3f5db7f9,
+ 0x3f5c6f3b, 0x3f5b2158, 0x3f59ce60, 0x3f587664, 0x3f571975, 0x3f55b7a5,
+ 0x3f545106, 0x3f52e5a9, 0x3f5175a0, 0x3f5000fe, 0x3f4e87d6, 0x3f4d0a3b,
+ 0x3f4b883f, 0x3f4a01f6, 0x3f487774, 0x3f46e8cc, 0x3f455613, 0x3f43bf5c,
+ 0x3f4224bd, 0x3f40864a, 0x3f3ee418, 0x3f3d3e3c, 0x3f3b94cc, 0x3f39e7dd,
+ 0x3f383784, 0x3f3683d8, 0x3f34ccef, 0x3f3312e0, 0x3f3155bf, 0x3f2f95a6,
+ 0x3f2dd2a9, 0x3f2c0ce1, 0x3f2a4464, 0x3f28794a, 0x3f26abaa, 0x3f24db9d,
+ 0x3f230939, 0x3f213498, 0x3f1f5dd0, 0x3f1d84fb, 0x3f1baa32, 0x3f19cd8b,
+ 0x3f17ef21, 0x3f160f0c, 0x3f142d65, 0x3f124a45, 0x3f1065c6, 0x3f0e8001,
+ 0x3f0c990f, 0x3f0ab10a, 0x3f08c80b, 0x3f06de2d, 0x3f04f389, 0x3f03083a,
+ 0x3f011c59, 0x3efe6002, 0x3efa8698, 0x3ef6aca8, 0x3ef2d267, 0x3eeef80c,
+ 0x3eeb1dca, 0x3ee743d7, 0x3ee36a69, 0x3edf91b5, 0x3edbb9f2, 0x3ed7e354,
+ 0x3ed40e13, 0x3ed03a64, 0x3ecc687d, 0x3ec89895, 0x3ec4cae2, 0x3ec0ff9b,
+ 0x3ebd36f6, 0x3eb9712a, 0x3eb5ae6f, 0x3eb1eefa, 0x3eae3303, 0x3eaa7ac0,
+ 0x3ea6c66a, 0x3ea31636, 0x3e9f6a5d, 0x3e9bc316, 0x3e982097, 0x3e948319,
+ 0x3e90ead3, 0x3e8d57fc, 0x3e89cacd, 0x3e86437c, 0x3e82c241, 0x3e7e8eaa,
+ 0x3e77a5de, 0x3e70ca8f, 0x3e69fd2c, 0x3e633e26, 0x3e5c8ded, 0x3e55ecf2,
+ 0x3e4f5ba5, 0x3e48da79, 0x3e4269de, 0x3e3c0a46, 0x3e35bc23, 0x3e2f7fe7,
+ 0x3e295605, 0x3e233ef0, 0x3e1d3b1c, 0x3e174afe, 0x3e116f08, 0x3e0ba7b2,
+ 0x3e05f571, 0x3e0058bb, 0x3df5a413, 0x3deac3a7, 0x3de01126, 0x3dd58d86,
+ 0x3dcb39bf, 0x3dc116cc, 0x3db725ab, 0x3dad675d, 0x3da3dce9, 0x3d9a8756,
+ 0x3d9167b5, 0x3d887f19, 0x3d7f9d38, 0x3d6eaebd, 0x3d5e3510, 0x3d4e3293,
+ 0x3d3ea9ba, 0x3d2f9d0e, 0x3d210f33, 0x3d1302e6, 0x3d057b06, 0x3cf0f52e,
+ 0x3cd8098d, 0x3cc039eb, 0x3ca98d81, 0x3c940c13, 0x3c7f7c1d, 0x3c59595d,
+ 0x3c35c45b, 0x3c14d40b, 0x3bed453b, 0x3bb69d19, 0x3b85f871, 0x3b37623a,
+ 0x3ae0ee32, 0x3a61d1c5, 0x398b03f6, 0x00000000
+
+};
+
+const int32_t window_hamm_hex[] = {
+ 0x3da3d70a, 0x3da3f4f1, 0x3da44ea4, 0x3da4e41d, 0x3da5b554, 0x3da6c239,
+ 0x3da80abd, 0x3da98ecb, 0x3dab4e4a, 0x3dad491d, 0x3daf7f25, 0x3db1f03d,
+ 0x3db49c3e, 0x3db782fd, 0x3dbaa449, 0x3dbdfff1, 0x3dc195be, 0x3dc56575,
+ 0x3dc96ed9, 0x3dcdb1a8, 0x3dd22d9d, 0x3dd6e26e, 0x3ddbcfd0, 0x3de0f572,
+ 0x3de65301, 0x3debe825, 0x3df1b484, 0x3df7b7c0, 0x3dfdf176, 0x3e0230a1,
+ 0x3e05835d, 0x3e08f0ba, 0x3e0c7880, 0x3e101a75, 0x3e13d65f, 0x3e17ac00,
+ 0x3e1b9b1b, 0x3e1fa36f, 0x3e23c4bc, 0x3e27febd, 0x3e2c512e, 0x3e30bbc9,
+ 0x3e353e46, 0x3e39d85c, 0x3e3e89c0, 0x3e435226, 0x3e483140, 0x3e4d26be,
+ 0x3e523251, 0x3e5753a7, 0x3e5c8a6b, 0x3e61d64a, 0x3e6736ec, 0x3e6cabfc,
+ 0x3e72351f, 0x3e77d1fd, 0x3e7d8239, 0x3e81a2bc, 0x3e848dae, 0x3e8781c3,
+ 0x3e8a7eca, 0x3e8d8495, 0x3e9092f0, 0x3e93a9ab, 0x3e96c894, 0x3e99ef77,
+ 0x3e9d1e22, 0x3ea05460, 0x3ea391ff, 0x3ea6d6c8, 0x3eaa2286, 0x3ead7505,
+ 0x3eb0ce0f, 0x3eb42d6c, 0x3eb792e6, 0x3ebafe46, 0x3ebe6f54, 0x3ec1e5d9,
+ 0x3ec5619c, 0x3ec8e264, 0x3ecc67f8, 0x3ecff220, 0x3ed380a2, 0x3ed71344,
+ 0x3edaa9cb, 0x3ede43fe, 0x3ee1e1a3, 0x3ee5827d, 0x3ee92653, 0x3eeccce9,
+ 0x3ef07604, 0x3ef42168, 0x3ef7ceda, 0x3efb7e1d, 0x3eff2ef7, 0x3f017096,
+ 0x3f034a3f, 0x3f052459, 0x3f06fec5, 0x3f08d967, 0x3f0ab41f, 0x3f0c8ed0,
+ 0x3f0e695b, 0x3f1043a2, 0x3f121d87, 0x3f13f6ec, 0x3f15cfb4, 0x3f17a7bf,
+ 0x3f197ef0, 0x3f1b5529, 0x3f1d2a4d, 0x3f1efe3d, 0x3f20d0db, 0x3f22a20b,
+ 0x3f2471ae, 0x3f263fa8, 0x3f280bda, 0x3f29d628, 0x3f2b9e74, 0x3f2d64a2,
+ 0x3f2f2895, 0x3f30ea30, 0x3f32a956, 0x3f3465ec, 0x3f361fd4, 0x3f37d6f3,
+ 0x3f398b2d, 0x3f3b3c66, 0x3f3cea83, 0x3f3e9569, 0x3f403cfb, 0x3f41e121,
+ 0x3f4381be, 0x3f451eb8, 0x3f46b7f6, 0x3f484d5d, 0x3f49ded3, 0x3f4b6c3f,
+ 0x3f4cf588, 0x3f4e7a94, 0x3f4ffb4c, 0x3f517796, 0x3f52ef5a, 0x3f546282,
+ 0x3f55d0f4, 0x3f573a9a, 0x3f589f5d, 0x3f59ff26, 0x3f5b59df, 0x3f5caf72,
+ 0x3f5dffc9, 0x3f5f4acf, 0x3f60906f, 0x3f61d093, 0x3f630b29, 0x3f64401b,
+ 0x3f656f57, 0x3f6698c9, 0x3f67bc5d, 0x3f68da03, 0x3f69f1a6, 0x3f6b0337,
+ 0x3f6c0ea3, 0x3f6d13d9, 0x3f6e12c9, 0x3f6f0b62, 0x3f6ffd95, 0x3f70e953,
+ 0x3f71ce8c, 0x3f72ad32, 0x3f738537, 0x3f74568d, 0x3f752127, 0x3f75e4f8,
+ 0x3f76a1f3, 0x3f77580d, 0x3f780739, 0x3f78af6e, 0x3f79509f, 0x3f79eac3,
+ 0x3f7a7dd1, 0x3f7b09be, 0x3f7b8e83, 0x3f7c0c15, 0x3f7c826e, 0x3f7cf187,
+ 0x3f7d5957, 0x3f7db9d8, 0x3f7e1305, 0x3f7e64d7, 0x3f7eaf4a, 0x3f7ef258,
+ 0x3f7f2dfe, 0x3f7f6237, 0x3f7f8f00, 0x3f7fb457, 0x3f7fd239, 0x3f7fe8a4,
+ 0x3f7ff797, 0x3f7fff11, 0x3f7fff11, 0x3f7ff797, 0x3f7fe8a4, 0x3f7fd239,
+ 0x3f7fb457, 0x3f7f8f00, 0x3f7f6237, 0x3f7f2dfe, 0x3f7ef258, 0x3f7eaf4a,
+ 0x3f7e64d7, 0x3f7e1305, 0x3f7db9d8, 0x3f7d5957, 0x3f7cf187, 0x3f7c826e,
+ 0x3f7c0c15, 0x3f7b8e83, 0x3f7b09be, 0x3f7a7dd1, 0x3f79eac3, 0x3f79509f,
+ 0x3f78af6e, 0x3f780739, 0x3f77580d, 0x3f76a1f3, 0x3f75e4f8, 0x3f752127,
+ 0x3f74568d, 0x3f738537, 0x3f72ad32, 0x3f71ce8c, 0x3f70e953, 0x3f6ffd95,
+ 0x3f6f0b62, 0x3f6e12c9, 0x3f6d13d9, 0x3f6c0ea3, 0x3f6b0337, 0x3f69f1a6,
+ 0x3f68da03, 0x3f67bc5d, 0x3f6698c9, 0x3f656f57, 0x3f64401b, 0x3f630b29,
+ 0x3f61d093, 0x3f60906f, 0x3f5f4acf, 0x3f5dffc9, 0x3f5caf72, 0x3f5b59df,
+ 0x3f59ff26, 0x3f589f5d, 0x3f573a9a, 0x3f55d0f4, 0x3f546282, 0x3f52ef5a,
+ 0x3f517796, 0x3f4ffb4c, 0x3f4e7a94, 0x3f4cf588, 0x3f4b6c3f, 0x3f49ded3,
+ 0x3f484d5d, 0x3f46b7f6, 0x3f451eb8, 0x3f4381be, 0x3f41e121, 0x3f403cfb,
+ 0x3f3e9569, 0x3f3cea83, 0x3f3b3c66, 0x3f398b2d, 0x3f37d6f3, 0x3f361fd4,
+ 0x3f3465ec, 0x3f32a956, 0x3f30ea30, 0x3f2f2895, 0x3f2d64a2, 0x3f2b9e74,
+ 0x3f29d628, 0x3f280bda, 0x3f263fa8, 0x3f2471ae, 0x3f22a20b, 0x3f20d0db,
+ 0x3f1efe3d, 0x3f1d2a4d, 0x3f1b5529, 0x3f197ef0, 0x3f17a7bf, 0x3f15cfb4,
+ 0x3f13f6ec, 0x3f121d87, 0x3f1043a2, 0x3f0e695b, 0x3f0c8ed0, 0x3f0ab41f,
+ 0x3f08d967, 0x3f06fec5, 0x3f052459, 0x3f034a3f, 0x3f017096, 0x3eff2ef7,
+ 0x3efb7e1d, 0x3ef7ceda, 0x3ef42168, 0x3ef07604, 0x3eeccce9, 0x3ee92653,
+ 0x3ee5827d, 0x3ee1e1a3, 0x3ede43fe, 0x3edaa9cb, 0x3ed71344, 0x3ed380a2,
+ 0x3ecff220, 0x3ecc67f8, 0x3ec8e264, 0x3ec5619c, 0x3ec1e5d9, 0x3ebe6f54,
+ 0x3ebafe46, 0x3eb792e6, 0x3eb42d6c, 0x3eb0ce0f, 0x3ead7505, 0x3eaa2286,
+ 0x3ea6d6c8, 0x3ea391ff, 0x3ea05460, 0x3e9d1e22, 0x3e99ef77, 0x3e96c894,
+ 0x3e93a9ab, 0x3e9092f0, 0x3e8d8495, 0x3e8a7eca, 0x3e8781c3, 0x3e848dae,
+ 0x3e81a2bc, 0x3e7d8239, 0x3e77d1fd, 0x3e72351f, 0x3e6cabfc, 0x3e6736ec,
+ 0x3e61d64a, 0x3e5c8a6b, 0x3e5753a7, 0x3e523251, 0x3e4d26be, 0x3e483140,
+ 0x3e435226, 0x3e3e89c0, 0x3e39d85c, 0x3e353e46, 0x3e30bbc9, 0x3e2c512e,
+ 0x3e27febd, 0x3e23c4bc, 0x3e1fa36f, 0x3e1b9b1b, 0x3e17ac00, 0x3e13d65f,
+ 0x3e101a75, 0x3e0c7880, 0x3e08f0ba, 0x3e05835d, 0x3e0230a1, 0x3dfdf176,
+ 0x3df7b7c0, 0x3df1b484, 0x3debe825, 0x3de65301, 0x3de0f572, 0x3ddbcfd0,
+ 0x3dd6e26e, 0x3dd22d9d, 0x3dcdb1a8, 0x3dc96ed9, 0x3dc56575, 0x3dc195be,
+ 0x3dbdfff1, 0x3dbaa449, 0x3db782fd, 0x3db49c3e, 0x3db1f03d, 0x3daf7f25,
+ 0x3dad491d, 0x3dab4e4a, 0x3da98ecb, 0x3da80abd, 0x3da6c239, 0x3da5b554,
+ 0x3da4e41d, 0x3da44ea4, 0x3da3f4f1, 0x3da3d70a
+
+};
+
+const int global_cmvn_mean_hex[] = {
+ 0x413d6566, 0x4147923f, 0x4156ab15, 0x41613d12, 0x416b155b, 0x41722783,
+ 0x4176cd05, 0x4178532a, 0x417aa3c3, 0x417aed19, 0x417d4d2c, 0x417e6abb,
+ 0x41805848, 0x418122ab, 0x41812b23, 0x418161a8, 0x41810ef9, 0x4180863a,
+ 0x41815d8f, 0x417ff8b2, 0x417de2aa, 0x4180a5f2, 0x417e8bd1, 0x418041ac,
+ 0x417f2d60, 0x4180487f, 0x417eb835, 0x418018d8, 0x417ef8c1, 0x417ea302,
+ 0x417f30cf, 0x417ea0bb, 0x417ebac2, 0x417faab6, 0x417fca4d, 0x41805e45,
+ 0x4180e308, 0x4180ef3e, 0x418109fc, 0x4180afa3, 0x418113e2, 0x4180c915,
+ 0x41819f86, 0x418190bf, 0x418220bd, 0x4182f2e5, 0x4183e1c7, 0x41843eec,
+ 0x4184b066, 0x418574db, 0x41852611, 0x4184fc81, 0x41851b2a, 0x4185a1c7,
+ 0x41861152, 0x41868c28, 0x41871930, 0x41871f83, 0x41868893, 0x4185d919,
+ 0x4185664b, 0x418480a6, 0x41840e3a, 0x41836ace, 0x4182b217, 0x4181cb79,
+ 0x4180fb13, 0x418098b9, 0x41805ded, 0x417ff69a, 0x417f49bd, 0x417ecef8,
+ 0x417e286c, 0x417d9135, 0x417cfff4, 0x417ca8f7, 0x417b2e8f, 0x41773788,
+ 0x4170b095, 0x4167417f};
+
+const int global_cmvn_std_hex[] = {
+ 0x4040335e, 0x405235d3, 0x40589be4, 0x4054261f, 0x40544ba2, 0x40575418,
+ 0x405b6528, 0x40617999, 0x40605fcf, 0x405c9c6d, 0x40590796, 0x405899fc,
+ 0x405810b8, 0x40587c40, 0x40592b5e, 0x4057fb12, 0x4057028b, 0x405515d7,
+ 0x4053d714, 0x405418c7, 0x405536bc, 0x4052f54e, 0x4052d382, 0x4051201d,
+ 0x4050a8d2, 0x4050857f, 0x404ffe85, 0x4050a0da, 0x40517a8a, 0x40508862,
+ 0x40504f68, 0x404f3159, 0x404f0930, 0x404e8a2e, 0x404e7383, 0x404eb185,
+ 0x404edaa9, 0x404efed2, 0x404ea8f4, 0x404f6d0d, 0x404ee9d9, 0x404f4cca,
+ 0x404fb13f, 0x405051c5, 0x40503f5e, 0x4050df6e, 0x4052974e, 0x4053d421,
+ 0x40544d48, 0x40544ec8, 0x40550e57, 0x40558287, 0x4055d122, 0x4056b22a,
+ 0x4058ea5c, 0x405acbc3, 0x405a89e7, 0x405a88ed, 0x405afadb, 0x405a1c60,
+ 0x405a6f46, 0x405b0a24, 0x405b5f44, 0x405cc0a9, 0x405d984b, 0x405ef9b8,
+ 0x4061178a, 0x406262bf, 0x40644904, 0x40660b20, 0x4067f7f1, 0x406a35e5,
+ 0x406c1e97, 0x406e16a9, 0x406eadb1, 0x406d0cba, 0x406d9ca0, 0x406f5a14,
+ 0x406e84a7, 0x406cd985};
+
+const int global_cmvn_mean_online_hex[] = {
+
+ 0x413d5d27, 0x414785ae, 0x4156986a, 0x41612a4e, 0x416b063e, 0x41721c9b,
+ 0x4176c505, 0x41784b5b, 0x417a9575, 0x417adfb2, 0x417d4153, 0x417e611e,
+ 0x41805288, 0x41811c27, 0x4181250c, 0x41815cd4, 0x41810b77, 0x4180817c,
+ 0x41815881, 0x417feaf2, 0x417dd2bf, 0x41809f37, 0x417e7b47, 0x41803a6a,
+ 0x417f1ff4, 0x41804382, 0x417ead10, 0x41801220, 0x417eeb28, 0x417e9801,
+ 0x417f26b9, 0x417e95f9, 0x417eac06, 0x417f9aa5, 0x417fbb16, 0x41805651,
+ 0x4180daaa, 0x4180e84c, 0x41810566, 0x4180ab2c, 0x418111b0, 0x4180c6cc,
+ 0x41819e27, 0x418190cc, 0x4182205c, 0x4182f265, 0x4183e1a2, 0x41844012,
+ 0x4184b0cd, 0x41857447, 0x418527f7, 0x4184fdc6, 0x41851ad2, 0x4185a148,
+ 0x41860f8b, 0x41868888, 0x418712e4, 0x41871702, 0x41867ec3, 0x4185cc48,
+ 0x418559b4, 0x41847855, 0x418408f4, 0x418368f4, 0x4182b718, 0x4181d76d,
+ 0x41810e52, 0x4180b204, 0x418078a4, 0x41801179, 0x417f5579, 0x417e93b7,
+ 0x417d6f2c, 0x417c1a0b, 0x417a6c7a, 0x41787d18, 0x4174eceb, 0x416e3ed3,
+ 0x41644af8, 0x41566dd4
+
+};
+
+const int global_cmvn_std_online_hex[] = {
+
+ 0x40408fdd, 0x405293b6, 0x4058f2d2, 0x40546ddb, 0x4054984c, 0x4057971b,
+ 0x405ba086, 0x4061afa7, 0x4060a24c, 0x405cbb7e, 0x405923f7, 0x4058c91f,
+ 0x40585cf3, 0x4058c22a, 0x40594960, 0x405824a6, 0x405703f3, 0x40556377,
+ 0x4053e02d, 0x40540a7e, 0x405553c7, 0x4052ead5, 0x4052d23d, 0x40510308,
+ 0x4050a2f3, 0x40505b81, 0x404fed20, 0x4050a372, 0x40515196, 0x40504810,
+ 0x40501fdd, 0x404f2225, 0x404f0931, 0x404e8a2b, 0x404e773b, 0x404ea782,
+ 0x404ee17d, 0x404ef49c, 0x404e884d, 0x404f696b, 0x404edd0e, 0x404f23cc,
+ 0x404f74d4, 0x40501e89, 0x405009f3, 0x4050c422, 0x4052902b, 0x4053987c,
+ 0x40542997, 0x40543695, 0x4054cbef, 0x40553947, 0x4055ab7c, 0x4056887c,
+ 0x4058b710, 0x405a8d28, 0x405a6a27, 0x405a6b3b, 0x405ac8d3, 0x405a031d,
+ 0x405a2158, 0x405abb1b, 0x405b1350, 0x405c98c0, 0x405d5cf9, 0x405ead5b,
+ 0x40609748, 0x4061dfb9, 0x4063aa9f, 0x40655831, 0x40671a35, 0x40694bf5,
+ 0x406b1f59, 0x406cb49b, 0x406cf19e, 0x406b592b, 0x406b757c, 0x406c866d,
+ 0x406ac24f, 0x406678d9
+
+};
+
+const unsigned int paraformer_cmvn_mean_hex[] = {
+
+ 0xc104fd75, 0xc1099d56, 0xc119dad7, 0xc126f9a7, 0xc133681f, 0xc13e221f,
+ 0xc145cc83, 0xc14a3166, 0xc14e1bda, 0xc14d4a62, 0xc14e41a9, 0xc14f4e7b,
+ 0xc153297e, 0xc1567ee5, 0xc157dbab, 0xc158dfa4, 0xc158e6f9, 0xc1584e70,
+ 0xc15aecea, 0xc15886b8, 0xc156bcb4, 0xc15a7ba9, 0xc1581d34, 0xc15c0a48,
+ 0xc15c463f, 0xc15dfc3b, 0xc15bb28b, 0xc15b4413, 0xc158f8c0, 0xc1588ede,
+ 0xc158c880, 0xc158ff19, 0xc159815a, 0xc159ed72, 0xc15a458d, 0xc15a93d3,
+ 0xc15a06ec, 0xc15953d8, 0xc1592e92, 0xc1579518, 0xc1587d76, 0xc157bc56,
+ 0xc159c47c, 0xc15a5ac4, 0xc15b7286, 0xc15cab60, 0xc15e7f8d, 0xc1607ee5,
+ 0xc162e9ad, 0xc165bdb0, 0xc167bf3e, 0xc169a0a5, 0xc16b4b68, 0xc16d5682,
+ 0xc16ebd51, 0xc170197a, 0xc170d1cc, 0xc1707fc1, 0xc16fd830, 0xc16ec4b1,
+ 0xc16de888, 0xc16d3b06, 0xc16cc155, 0xc16c4e31, 0xc16b6abe, 0xc169cde8,
+ 0xc1684578, 0xc166c2a4, 0xc165d326, 0xc164df46, 0xc163b4ad, 0xc1632d19,
+ 0xc162a94a, 0xc16280fc, 0xc161ae3e, 0xc15fec42, 0xc15cbadc, 0xc15664c3,
+ 0xc14c6d5d, 0xc13b64ae, 0xc104fd75, 0xc1099d56, 0xc119dad7, 0xc126f9a7,
+ 0xc133681f, 0xc13e221f, 0xc145cc83, 0xc14a3166, 0xc14e1bda, 0xc14d4a62,
+ 0xc14e41a9, 0xc14f4e7b, 0xc153297e, 0xc1567ee5, 0xc157dbab, 0xc158dfa4,
+ 0xc158e6f9, 0xc1584e70, 0xc15aecea, 0xc15886b8, 0xc156bcb4, 0xc15a7ba9,
+ 0xc1581d34, 0xc15c0a48, 0xc15c463f, 0xc15dfc3b, 0xc15bb28b, 0xc15b4413,
+ 0xc158f8c0, 0xc1588ede, 0xc158c880, 0xc158ff19, 0xc159815a, 0xc159ed72,
+ 0xc15a458d, 0xc15a93d3, 0xc15a06ec, 0xc15953d8, 0xc1592e92, 0xc1579518,
+ 0xc1587d76, 0xc157bc56, 0xc159c47c, 0xc15a5ac4, 0xc15b7286, 0xc15cab60,
+ 0xc15e7f8d, 0xc1607ee5, 0xc162e9ad, 0xc165bdb0, 0xc167bf3e, 0xc169a0a5,
+ 0xc16b4b68, 0xc16d5682, 0xc16ebd51, 0xc170197a, 0xc170d1cc, 0xc1707fc1,
+ 0xc16fd830, 0xc16ec4b1, 0xc16de888, 0xc16d3b06, 0xc16cc155, 0xc16c4e31,
+ 0xc16b6abe, 0xc169cde8, 0xc1684578, 0xc166c2a4, 0xc165d326, 0xc164df46,
+ 0xc163b4ad, 0xc1632d19, 0xc162a94a, 0xc16280fc, 0xc161ae3e, 0xc15fec42,
+ 0xc15cbadc, 0xc15664c3, 0xc14c6d5d, 0xc13b64ae, 0xc104fd75, 0xc1099d56,
+ 0xc119dad7, 0xc126f9a7, 0xc133681f, 0xc13e221f, 0xc145cc83, 0xc14a3166,
+ 0xc14e1bda, 0xc14d4a62, 0xc14e41a9, 0xc14f4e7b, 0xc153297e, 0xc1567ee5,
+ 0xc157dbab, 0xc158dfa4, 0xc158e6f9, 0xc1584e70, 0xc15aecea, 0xc15886b8,
+ 0xc156bcb4, 0xc15a7ba9, 0xc1581d34, 0xc15c0a48, 0xc15c463f, 0xc15dfc3b,
+ 0xc15bb28b, 0xc15b4413, 0xc158f8c0, 0xc1588ede, 0xc158c880, 0xc158ff19,
+ 0xc159815a, 0xc159ed72, 0xc15a458d, 0xc15a93d3, 0xc15a06ec, 0xc15953d8,
+ 0xc1592e92, 0xc1579518, 0xc1587d76, 0xc157bc56, 0xc159c47c, 0xc15a5ac4,
+ 0xc15b7286, 0xc15cab60, 0xc15e7f8d, 0xc1607ee5, 0xc162e9ad, 0xc165bdb0,
+ 0xc167bf3e, 0xc169a0a5, 0xc16b4b68, 0xc16d5682, 0xc16ebd51, 0xc170197a,
+ 0xc170d1cc, 0xc1707fc1, 0xc16fd830, 0xc16ec4b1, 0xc16de888, 0xc16d3b06,
+ 0xc16cc155, 0xc16c4e31, 0xc16b6abe, 0xc169cde8, 0xc1684578, 0xc166c2a4,
+ 0xc165d326, 0xc164df46, 0xc163b4ad, 0xc1632d19, 0xc162a94a, 0xc16280fc,
+ 0xc161ae3e, 0xc15fec42, 0xc15cbadc, 0xc15664c3, 0xc14c6d5d, 0xc13b64ae,
+ 0xc104fd75, 0xc1099d56, 0xc119dad7, 0xc126f9a7, 0xc133681f, 0xc13e221f,
+ 0xc145cc83, 0xc14a3166, 0xc14e1bda, 0xc14d4a62, 0xc14e41a9, 0xc14f4e7b,
+ 0xc153297e, 0xc1567ee5, 0xc157dbab, 0xc158dfa4, 0xc158e6f9, 0xc1584e70,
+ 0xc15aecea, 0xc15886b8, 0xc156bcb4, 0xc15a7ba9, 0xc1581d34, 0xc15c0a48,
+ 0xc15c463f, 0xc15dfc3b, 0xc15bb28b, 0xc15b4413, 0xc158f8c0, 0xc1588ede,
+ 0xc158c880, 0xc158ff19, 0xc159815a, 0xc159ed72, 0xc15a458d, 0xc15a93d3,
+ 0xc15a06ec, 0xc15953d8, 0xc1592e92, 0xc1579518, 0xc1587d76, 0xc157bc56,
+ 0xc159c47c, 0xc15a5ac4, 0xc15b7286, 0xc15cab60, 0xc15e7f8d, 0xc1607ee5,
+ 0xc162e9ad, 0xc165bdb0, 0xc167bf3e, 0xc169a0a5, 0xc16b4b68, 0xc16d5682,
+ 0xc16ebd51, 0xc170197a, 0xc170d1cc, 0xc1707fc1, 0xc16fd830, 0xc16ec4b1,
+ 0xc16de888, 0xc16d3b06, 0xc16cc155, 0xc16c4e31, 0xc16b6abe, 0xc169cde8,
+ 0xc1684578, 0xc166c2a4, 0xc165d326, 0xc164df46, 0xc163b4ad, 0xc1632d19,
+ 0xc162a94a, 0xc16280fc, 0xc161ae3e, 0xc15fec42, 0xc15cbadc, 0xc15664c3,
+ 0xc14c6d5d, 0xc13b64ae, 0xc104fd75, 0xc1099d56, 0xc119dad7, 0xc126f9a7,
+ 0xc133681f, 0xc13e221f, 0xc145cc83, 0xc14a3166, 0xc14e1bda, 0xc14d4a62,
+ 0xc14e41a9, 0xc14f4e7b, 0xc153297e, 0xc1567ee5, 0xc157dbab, 0xc158dfa4,
+ 0xc158e6f9, 0xc1584e70, 0xc15aecea, 0xc15886b8, 0xc156bcb4, 0xc15a7ba9,
+ 0xc1581d34, 0xc15c0a48, 0xc15c463f, 0xc15dfc3b, 0xc15bb28b, 0xc15b4413,
+ 0xc158f8c0, 0xc1588ede, 0xc158c880, 0xc158ff19, 0xc159815a, 0xc159ed72,
+ 0xc15a458d, 0xc15a93d3, 0xc15a06ec, 0xc15953d8, 0xc1592e92, 0xc1579518,
+ 0xc1587d76, 0xc157bc56, 0xc159c47c, 0xc15a5ac4, 0xc15b7286, 0xc15cab60,
+ 0xc15e7f8d, 0xc1607ee5, 0xc162e9ad, 0xc165bdb0, 0xc167bf3e, 0xc169a0a5,
+ 0xc16b4b68, 0xc16d5682, 0xc16ebd51, 0xc170197a, 0xc170d1cc, 0xc1707fc1,
+ 0xc16fd830, 0xc16ec4b1, 0xc16de888, 0xc16d3b06, 0xc16cc155, 0xc16c4e31,
+ 0xc16b6abe, 0xc169cde8, 0xc1684578, 0xc166c2a4, 0xc165d326, 0xc164df46,
+ 0xc163b4ad, 0xc1632d19, 0xc162a94a, 0xc16280fc, 0xc161ae3e, 0xc15fec42,
+ 0xc15cbadc, 0xc15664c3, 0xc14c6d5d, 0xc13b64ae, 0xc104fd75, 0xc1099d56,
+ 0xc119dad7, 0xc126f9a7, 0xc133681f, 0xc13e221f, 0xc145cc83, 0xc14a3166,
+ 0xc14e1bda, 0xc14d4a62, 0xc14e41a9, 0xc14f4e7b, 0xc153297e, 0xc1567ee5,
+ 0xc157dbab, 0xc158dfa4, 0xc158e6f9, 0xc1584e70, 0xc15aecea, 0xc15886b8,
+ 0xc156bcb4, 0xc15a7ba9, 0xc1581d34, 0xc15c0a48, 0xc15c463f, 0xc15dfc3b,
+ 0xc15bb28b, 0xc15b4413, 0xc158f8c0, 0xc1588ede, 0xc158c880, 0xc158ff19,
+ 0xc159815a, 0xc159ed72, 0xc15a458d, 0xc15a93d3, 0xc15a06ec, 0xc15953d8,
+ 0xc1592e92, 0xc1579518, 0xc1587d76, 0xc157bc56, 0xc159c47c, 0xc15a5ac4,
+ 0xc15b7286, 0xc15cab60, 0xc15e7f8d, 0xc1607ee5, 0xc162e9ad, 0xc165bdb0,
+ 0xc167bf3e, 0xc169a0a5, 0xc16b4b68, 0xc16d5682, 0xc16ebd51, 0xc170197a,
+ 0xc170d1cc, 0xc1707fc1, 0xc16fd830, 0xc16ec4b1, 0xc16de888, 0xc16d3b06,
+ 0xc16cc155, 0xc16c4e31, 0xc16b6abe, 0xc169cde8, 0xc1684578, 0xc166c2a4,
+ 0xc165d326, 0xc164df46, 0xc163b4ad, 0xc1632d19, 0xc162a94a, 0xc16280fc,
+ 0xc161ae3e, 0xc15fec42, 0xc15cbadc, 0xc15664c3, 0xc14c6d5d, 0xc13b64ae,
+ 0xc104fd75, 0xc1099d56, 0xc119dad7, 0xc126f9a7, 0xc133681f, 0xc13e221f,
+ 0xc145cc83, 0xc14a3166, 0xc14e1bda, 0xc14d4a62, 0xc14e41a9, 0xc14f4e7b,
+ 0xc153297e, 0xc1567ee5, 0xc157dbab, 0xc158dfa4, 0xc158e6f9, 0xc1584e70,
+ 0xc15aecea, 0xc15886b8, 0xc156bcb4, 0xc15a7ba9, 0xc1581d34, 0xc15c0a48,
+ 0xc15c463f, 0xc15dfc3b, 0xc15bb28b, 0xc15b4413, 0xc158f8c0, 0xc1588ede,
+ 0xc158c880, 0xc158ff19, 0xc159815a, 0xc159ed72, 0xc15a458d, 0xc15a93d3,
+ 0xc15a06ec, 0xc15953d8, 0xc1592e92, 0xc1579518, 0xc1587d76, 0xc157bc56,
+ 0xc159c47c, 0xc15a5ac4, 0xc15b7286, 0xc15cab60, 0xc15e7f8d, 0xc1607ee5,
+ 0xc162e9ad, 0xc165bdb0, 0xc167bf3e, 0xc169a0a5, 0xc16b4b68, 0xc16d5682,
+ 0xc16ebd51, 0xc170197a, 0xc170d1cc, 0xc1707fc1, 0xc16fd830, 0xc16ec4b1,
+ 0xc16de888, 0xc16d3b06, 0xc16cc155, 0xc16c4e31, 0xc16b6abe, 0xc169cde8,
+ 0xc1684578, 0xc166c2a4, 0xc165d326, 0xc164df46, 0xc163b4ad, 0xc1632d19,
+ 0xc162a94a, 0xc16280fc, 0xc161ae3e, 0xc15fec42, 0xc15cbadc, 0xc15664c3,
+ 0xc14c6d5d, 0xc13b64ae};
+
+const unsigned int paraformer_cmvn_var_hex[] = {
+
+ 0x40619618, 0x405fb77c, 0x405d3028, 0x405bef11, 0x405a189d, 0x4057aad5,
+ 0x4054f9cc, 0x40518e8c, 0x404fffdd, 0x40510d0d, 0x4052400d, 0x4052bab0,
+ 0x40526416, 0x40515cb8, 0x40506aee, 0x404fef8d, 0x404ff527, 0x40505b95,
+ 0x4050d61c, 0x4051d0a5, 0x4052abd2, 0x4052f14b, 0x4053d196, 0x4054800d,
+ 0x405545f2, 0x4055d71f, 0x40567588, 0x4056de4d, 0x40579b72, 0x40584d35,
+ 0x4058cd2f, 0x40594731, 0x4059a53f, 0x405a00ed, 0x405a34c1, 0x405a406e,
+ 0x405a1748, 0x405a0300, 0x405a1547, 0x405a66a7, 0x405a9be4, 0x405b04b2,
+ 0x405b5754, 0x405b9189, 0x405b9016, 0x405b7a07, 0x405b63f9, 0x405b3f45,
+ 0x405b0cb4, 0x405ac80b, 0x405ac1f7, 0x405abbd9, 0x405ac86a, 0x405ad72b,
+ 0x405af2f0, 0x405ab465, 0x405a6364, 0x405a1350, 0x4059baa3, 0x4059911d,
+ 0x40597921, 0x40595564, 0x40593b8d, 0x4059310f, 0x40594e46, 0x40599bae,
+ 0x4059e703, 0x4059feec, 0x405a053a, 0x4059feaa, 0x4059d7a0, 0x40599386,
+ 0x40592d0e, 0x4058ce4c, 0x40587335, 0x4058396a, 0x40584ee1, 0x4058925a,
+ 0x40592f6d, 0x405a9f0a, 0x40619618, 0x405fb77c, 0x405d3028, 0x405bef11,
+ 0x405a189d, 0x4057aad5, 0x4054f9cc, 0x40518e8c, 0x404fffdd, 0x40510d0d,
+ 0x4052400d, 0x4052bab0, 0x40526416, 0x40515cb8, 0x40506aee, 0x404fef8d,
+ 0x404ff527, 0x40505b95, 0x4050d61c, 0x4051d0a5, 0x4052abd2, 0x4052f14b,
+ 0x4053d196, 0x4054800d, 0x405545f2, 0x4055d71f, 0x40567588, 0x4056de4d,
+ 0x40579b72, 0x40584d35, 0x4058cd2f, 0x40594731, 0x4059a53f, 0x405a00ed,
+ 0x405a34c1, 0x405a406e, 0x405a1748, 0x405a0300, 0x405a1547, 0x405a66a7,
+ 0x405a9be4, 0x405b04b2, 0x405b5754, 0x405b9189, 0x405b9016, 0x405b7a07,
+ 0x405b63f9, 0x405b3f45, 0x405b0cb4, 0x405ac80b, 0x405ac1f7, 0x405abbd9,
+ 0x405ac86a, 0x405ad72b, 0x405af2f0, 0x405ab465, 0x405a6364, 0x405a1350,
+ 0x4059baa3, 0x4059911d, 0x40597921, 0x40595564, 0x40593b8d, 0x4059310f,
+ 0x40594e46, 0x40599bae, 0x4059e703, 0x4059feec, 0x405a053a, 0x4059feaa,
+ 0x4059d7a0, 0x40599386, 0x40592d0e, 0x4058ce4c, 0x40587335, 0x4058396a,
+ 0x40584ee1, 0x4058925a, 0x40592f6d, 0x405a9f0a, 0x40619618, 0x405fb77c,
+ 0x405d3028, 0x405bef11, 0x405a189d, 0x4057aad5, 0x4054f9cc, 0x40518e8c,
+ 0x404fffdd, 0x40510d0d, 0x4052400d, 0x4052bab0, 0x40526416, 0x40515cb8,
+ 0x40506aee, 0x404fef8d, 0x404ff527, 0x40505b95, 0x4050d61c, 0x4051d0a5,
+ 0x4052abd2, 0x4052f14b, 0x4053d196, 0x4054800d, 0x405545f2, 0x4055d71f,
+ 0x40567588, 0x4056de4d, 0x40579b72, 0x40584d35, 0x4058cd2f, 0x40594731,
+ 0x4059a53f, 0x405a00ed, 0x405a34c1, 0x405a406e, 0x405a1748, 0x405a0300,
+ 0x405a1547, 0x405a66a7, 0x405a9be4, 0x405b04b2, 0x405b5754, 0x405b9189,
+ 0x405b9016, 0x405b7a07, 0x405b63f9, 0x405b3f45, 0x405b0cb4, 0x405ac80b,
+ 0x405ac1f7, 0x405abbd9, 0x405ac86a, 0x405ad72b, 0x405af2f0, 0x405ab465,
+ 0x405a6364, 0x405a1350, 0x4059baa3, 0x4059911d, 0x40597921, 0x40595564,
+ 0x40593b8d, 0x4059310f, 0x40594e46, 0x40599bae, 0x4059e703, 0x4059feec,
+ 0x405a053a, 0x4059feaa, 0x4059d7a0, 0x40599386, 0x40592d0e, 0x4058ce4c,
+ 0x40587335, 0x4058396a, 0x40584ee1, 0x4058925a, 0x40592f6d, 0x405a9f0a,
+ 0x40619618, 0x405fb77c, 0x405d3028, 0x405bef11, 0x405a189d, 0x4057aad5,
+ 0x4054f9cc, 0x40518e8c, 0x404fffdd, 0x40510d0d, 0x4052400d, 0x4052bab0,
+ 0x40526416, 0x40515cb8, 0x40506aee, 0x404fef8d, 0x404ff527, 0x40505b95,
+ 0x4050d61c, 0x4051d0a5, 0x4052abd2, 0x4052f14b, 0x4053d196, 0x4054800d,
+ 0x405545f2, 0x4055d71f, 0x40567588, 0x4056de4d, 0x40579b72, 0x40584d35,
+ 0x4058cd2f, 0x40594731, 0x4059a53f, 0x405a00ed, 0x405a34c1, 0x405a406e,
+ 0x405a1748, 0x405a0300, 0x405a1547, 0x405a66a7, 0x405a9be4, 0x405b04b2,
+ 0x405b5754, 0x405b9189, 0x405b9016, 0x405b7a07, 0x405b63f9, 0x405b3f45,
+ 0x405b0cb4, 0x405ac80b, 0x405ac1f7, 0x405abbd9, 0x405ac86a, 0x405ad72b,
+ 0x405af2f0, 0x405ab465, 0x405a6364, 0x405a1350, 0x4059baa3, 0x4059911d,
+ 0x40597921, 0x40595564, 0x40593b8d, 0x4059310f, 0x40594e46, 0x40599bae,
+ 0x4059e703, 0x4059feec, 0x405a053a, 0x4059feaa, 0x4059d7a0, 0x40599386,
+ 0x40592d0e, 0x4058ce4c, 0x40587335, 0x4058396a, 0x40584ee1, 0x4058925a,
+ 0x40592f6d, 0x405a9f0a, 0x40619618, 0x405fb77c, 0x405d3028, 0x405bef11,
+ 0x405a189d, 0x4057aad5, 0x4054f9cc, 0x40518e8c, 0x404fffdd, 0x40510d0d,
+ 0x4052400d, 0x4052bab0, 0x40526416, 0x40515cb8, 0x40506aee, 0x404fef8d,
+ 0x404ff527, 0x40505b95, 0x4050d61c, 0x4051d0a5, 0x4052abd2, 0x4052f14b,
+ 0x4053d196, 0x4054800d, 0x405545f2, 0x4055d71f, 0x40567588, 0x4056de4d,
+ 0x40579b72, 0x40584d35, 0x4058cd2f, 0x40594731, 0x4059a53f, 0x405a00ed,
+ 0x405a34c1, 0x405a406e, 0x405a1748, 0x405a0300, 0x405a1547, 0x405a66a7,
+ 0x405a9be4, 0x405b04b2, 0x405b5754, 0x405b9189, 0x405b9016, 0x405b7a07,
+ 0x405b63f9, 0x405b3f45, 0x405b0cb4, 0x405ac80b, 0x405ac1f7, 0x405abbd9,
+ 0x405ac86a, 0x405ad72b, 0x405af2f0, 0x405ab465, 0x405a6364, 0x405a1350,
+ 0x4059baa3, 0x4059911d, 0x40597921, 0x40595564, 0x40593b8d, 0x4059310f,
+ 0x40594e46, 0x40599bae, 0x4059e703, 0x4059feec, 0x405a053a, 0x4059feaa,
+ 0x4059d7a0, 0x40599386, 0x40592d0e, 0x4058ce4c, 0x40587335, 0x4058396a,
+ 0x40584ee1, 0x4058925a, 0x40592f6d, 0x405a9f0a, 0x40619618, 0x405fb77c,
+ 0x405d3028, 0x405bef11, 0x405a189d, 0x4057aad5, 0x4054f9cc, 0x40518e8c,
+ 0x404fffdd, 0x40510d0d, 0x4052400d, 0x4052bab0, 0x40526416, 0x40515cb8,
+ 0x40506aee, 0x404fef8d, 0x404ff527, 0x40505b95, 0x4050d61c, 0x4051d0a5,
+ 0x4052abd2, 0x4052f14b, 0x4053d196, 0x4054800d, 0x405545f2, 0x4055d71f,
+ 0x40567588, 0x4056de4d, 0x40579b72, 0x40584d35, 0x4058cd2f, 0x40594731,
+ 0x4059a53f, 0x405a00ed, 0x405a34c1, 0x405a406e, 0x405a1748, 0x405a0300,
+ 0x405a1547, 0x405a66a7, 0x405a9be4, 0x405b04b2, 0x405b5754, 0x405b9189,
+ 0x405b9016, 0x405b7a07, 0x405b63f9, 0x405b3f45, 0x405b0cb4, 0x405ac80b,
+ 0x405ac1f7, 0x405abbd9, 0x405ac86a, 0x405ad72b, 0x405af2f0, 0x405ab465,
+ 0x405a6364, 0x405a1350, 0x4059baa3, 0x4059911d, 0x40597921, 0x40595564,
+ 0x40593b8d, 0x4059310f, 0x40594e46, 0x40599bae, 0x4059e703, 0x4059feec,
+ 0x405a053a, 0x4059feaa, 0x4059d7a0, 0x40599386, 0x40592d0e, 0x4058ce4c,
+ 0x40587335, 0x4058396a, 0x40584ee1, 0x4058925a, 0x40592f6d, 0x405a9f0a,
+ 0x40619618, 0x405fb77c, 0x405d3028, 0x405bef11, 0x405a189d, 0x4057aad5,
+ 0x4054f9cc, 0x40518e8c, 0x404fffdd, 0x40510d0d, 0x4052400d, 0x4052bab0,
+ 0x40526416, 0x40515cb8, 0x40506aee, 0x404fef8d, 0x404ff527, 0x40505b95,
+ 0x4050d61c, 0x4051d0a5, 0x4052abd2, 0x4052f14b, 0x4053d196, 0x4054800d,
+ 0x405545f2, 0x4055d71f, 0x40567588, 0x4056de4d, 0x40579b72, 0x40584d35,
+ 0x4058cd2f, 0x40594731, 0x4059a53f, 0x405a00ed, 0x405a34c1, 0x405a406e,
+ 0x405a1748, 0x405a0300, 0x405a1547, 0x405a66a7, 0x405a9be4, 0x405b04b2,
+ 0x405b5754, 0x405b9189, 0x405b9016, 0x405b7a07, 0x405b63f9, 0x405b3f45,
+ 0x405b0cb4, 0x405ac80b, 0x405ac1f7, 0x405abbd9, 0x405ac86a, 0x405ad72b,
+ 0x405af2f0, 0x405ab465, 0x405a6364, 0x405a1350, 0x4059baa3, 0x4059911d,
+ 0x40597921, 0x40595564, 0x40593b8d, 0x4059310f, 0x40594e46, 0x40599bae,
+ 0x4059e703, 0x4059feec, 0x405a053a, 0x4059feaa, 0x4059d7a0, 0x40599386,
+ 0x40592d0e, 0x4058ce4c, 0x40587335, 0x4058396a, 0x40584ee1, 0x4058925a,
+ 0x40592f6d, 0x405a9f0a
+
+};
+
+const int pos_enc_coe_hex[] = {
+ 0x3f800000, 0x3f84b063, 0x3f898cc0, 0x3f8e96b2, 0x3f93cfe5, 0x3f993a15,
+ 0x3f9ed70c, 0x3fa4a8a8, 0x3faab0d5, 0x3fb0f193, 0x3fb76cf5, 0x3fbe2520,
+ 0x3fc51c50, 0x3fcc54d2, 0x3fd3d10c, 0x3fdb9378, 0x3fe39ea9, 0x3febf549,
+ 0x3ff49a1b, 0x3ffd8ffe, 0x40036cf4, 0x40083d78, 0x400d3b22, 0x40126799,
+ 0x4017c496, 0x401d53df, 0x4023174b, 0x402910c4, 0x402f4244, 0x4035adda,
+ 0x403c55a4, 0x40433bd9, 0x404a62c2, 0x4051ccbd, 0x40597c3f, 0x406173d4,
+ 0x4069b621, 0x407245e2, 0x407b25ed, 0x40822c9a, 0x4086f161, 0x408be2e0,
+ 0x409102bc, 0x409652a6, 0x409bd461, 0x40a189c1, 0x40a774aa, 0x40ad9711,
+ 0x40b3f300, 0x40ba8a92, 0x40c15ff6, 0x40c8756f, 0x40cfcd58, 0x40d76a1e,
+ 0x40df4e48, 0x40e77c73, 0x40eff755, 0x40f8c1be, 0x4100ef4c, 0x4105a873,
+ 0x410a8de6, 0x410fa144, 0x4114e43b, 0x411a588a, 0x41200000, 0x4125dc7c,
+ 0x412beff0, 0x41323c5f, 0x4138c3df, 0x413f889a, 0x41468cd0, 0x414dd2d2,
+ 0x41555d0a, 0x415d2df7, 0x41654832, 0x416dae69, 0x41766364, 0x417f6a07,
+ 0x418462a7, 0x41893c2b, 0x418e432a, 0x4193794e, 0x4198e051, 0x419e79ff,
+ 0x41a44831, 0x41aa4cd6, 0x41b089ea, 0x41b70180, 0x41bdb5bc, 0x41c4a8d7,
+ 0x41cbdd1e, 0x41d354f5, 0x41db12d6, 0x41e31950, 0x41eb6b0d, 0x41f40ad0,
+ 0x41fcfb72, 0x42031ff6, 0x4207eda7, 0x420ce865, 0x421211d5, 0x42176bad,
+ 0x421cf7b4, 0x4222b7c0, 0x4228adb9, 0x422edb98, 0x4235436b, 0x423be74f,
+ 0x4242c979, 0x4249ec31, 0x425151d4, 0x4258fcd6, 0x4260efc0, 0x42692d37,
+ 0x4271b7f3, 0x427a92cb, 0x4281e057, 0x4286a253, 0x428b90ed, 0x4290adc8,
+ 0x4295fa95, 0x429b7917, 0x42a12b1f, 0x42a71290, 0x42ad3160, 0x42b38995,
+ 0x42ba1d4a, 0x42c0eead, 0x42c80000, 0x42cf539b, 0x42d6ebec, 0x42decb76,
+ 0x42e6f4d6, 0x42ef6ac1, 0x42f83003, 0x4300a3c3, 0x43055a26, 0x430a3cbb,
+ 0x430f4d1f, 0x43148d01, 0x4319fe1e, 0x431fa244, 0x43257b51, 0x432b8b36,
+ 0x4331d3f4, 0x433857a1, 0x433f1865, 0x4346187e, 0x434d5a3e, 0x4354e00b,
+ 0x435cac64, 0x4364c1e0, 0x436d232b, 0x4375d30c, 0x437ed466, 0x43841519,
+ 0x4388ebc5, 0x438defd2, 0x439322e8, 0x439886c2, 0x439e1d27, 0x43a3e7f3,
+ 0x43a9e911, 0x43b0227e, 0x43b6964a, 0x43bd4698, 0x43c435a1, 0x43cb65b0,
+ 0x43d2d927, 0x43da927e, 0x43e29445, 0x43eae123, 0x43f37bd8, 0x43fc673e,
+ 0x4402d325, 0x44079e06, 0x440c95d8, 0x4411bc42, 0x441712f8, 0x441c9bbf,
+ 0x4422586d, 0x44284ae8, 0x442e7528, 0x4434d93a, 0x443b793b, 0x4442575d,
+ 0x444975e6, 0x4450d734, 0x44587db7, 0x44606bfa, 0x4468a49c, 0x44712a58,
+ 0x447a0000, 0x44819441, 0x44865373, 0x448b3f2a, 0x44905906, 0x4495a2b9,
+ 0x449b1e02, 0x44a0ccb4, 0x44a6b0b0, 0x44accbe9, 0x44b32067, 0x44b9b042,
+ 0x44c07da6, 0x44c78ad5, 0x44ceda26, 0x44d66e03, 0x44de48f1, 0x44e66d89,
+ 0x44eede7f, 0x44f79e9e, 0x45005867, 0x45050c07, 0x4509ebbf, 0x450ef92c,
+ 0x451435fb, 0x4519a3e8, 0x451f44bf, 0x45251a60, 0x452b26b7, 0x45316bc7,
+ 0x4537eba3, 0x453ea872, 0x4545a471, 0x454ce1f0, 0x45546355, 0x455c2b1d,
+ 0x45643bdc, 0x456c983e, 0x45754309, 0x457e3f1c, 0x4583c7b8, 0x45889b8f,
+ 0x458d9cab, 0x4592ccb6, 0x45982d67, 0x459dc087, 0x45a387ee, 0x45a98587,
+ 0x45afbb4e, 0x45b62b53, 0x45bcd7b6, 0x45c3c2af, 0x45caee88, 0x45d25da1,
+ 0x45da1272, 0x45e20f88, 0x45ea5789, 0x45f2ed34, 0x45fbd360, 0x46028680,
+ 0x46074e93, 0x460c437c, 0x461166e2, 0x4616ba77};
+
+const int pos_enc_div_term_hex[] = {
+ 0x3f800000, 0x3f76f410, 0x3f6e39f8, 0x3f65ced3, 0x3f5dafd7, 0x3f55da52,
+ 0x3f4e4bac, 0x3f470165, 0x3f3ff911, 0x3f39305c, 0x3f32a506, 0x3f2c54e5,
+ 0x3f263de0, 0x3f205df3, 0x3f1ab32b, 0x3f153ba8, 0x3f0ff59a, 0x3f0adf41,
+ 0x3f05f6ee, 0x3f013b01, 0x3ef953cf, 0x3ef0843c, 0x3ee80460, 0x3edfd167,
+ 0x3ed7e89b, 0x3ed0475c, 0x3ec8eb24, 0x3ec1d181, 0x3ebaf81a, 0x3eb45caa,
+ 0x3eadfcff, 0x3ea7d6fd, 0x3ea1e89b, 0x3e9c2fe1, 0x3e96aaea, 0x3e9157e1,
+ 0x3e8c3504, 0x3e87409d, 0x3e827909, 0x3e7bb965, 0x3e72d424, 0x3e6a3f5c,
+ 0x3e61f836, 0x3e59fbf3, 0x3e5247ed, 0x3e4ad998, 0x3e43ae7c, 0x3e3cc43a,
+ 0x3e361887, 0x3e2fa92d, 0x3e29740a, 0x3e23770f, 0x3e1db040, 0x3e181db4,
+ 0x3e12bd91, 0x3e0d8e0f, 0x3e088d77, 0x3e03ba20, 0x3dfe24e1, 0x3df529bb,
+ 0x3dec7fd5, 0x3de42450, 0x3ddc1466, 0x3dd44d6c, 0x3dcccccd, 0x3dc5900d,
+ 0x3dbe94c7, 0x3db7d8a9, 0x3db15978, 0x3dab150e, 0x3da50957, 0x3d9f3451,
+ 0x3d99940e, 0x3d9426b0, 0x3d8eea6c, 0x3d89dd84, 0x3d84fe4d, 0x3d804b29,
+ 0x3d778512, 0x3d6ec5da, 0x3d6655c3, 0x3d5e3202, 0x3d5657e4, 0x3d4ec4ce,
+ 0x3d47763f, 0x3d4069ca, 0x3d399d19, 0x3d330dec, 0x3d2cba15, 0x3d269f7d,
+ 0x3d20bc1d, 0x3d1b0e01, 0x3d159348, 0x3d104a21, 0x3d0b30cc, 0x3d064597,
+ 0x3d0186e2, 0x3cf9e635, 0x3cf11176, 0x3ce88c9c, 0x3ce054d2, 0x3cd86761,
+ 0x3cd0c1a8, 0x3cc9611d, 0x3cc24350, 0x3cbb65e3, 0x3cb4c691, 0x3cae6328,
+ 0x3ca8398b, 0x3ca247ad, 0x3c9c8b97, 0x3c970362, 0x3c91ad39, 0x3c8c8757,
+ 0x3c879008, 0x3c82c5a5, 0x3c7c4d33, 0x3c7362b9, 0x3c6ac8e7, 0x3c627ce5,
+ 0x3c5a7bf1, 0x3c52c366, 0x3c4b50b4, 0x3c442163, 0x3c3d3311, 0x3c368373,
+ 0x3c301052, 0x3c29d789, 0x3c23d70a, 0x3c1e0cd7, 0x3c187705, 0x3c1313ba,
+ 0x3c0de12d, 0x3c08dda5, 0x3c040779, 0x3bfeba1b, 0x3bf5b9b0, 0x3bed0ab3,
+ 0x3be4aa46, 0x3bdc95a0, 0x3bd4ca14, 0x3bcd450e, 0x3bc6040e, 0x3bbf04ae,
+ 0x3bb8449c, 0x3bb1c19b, 0x3bab7983, 0x3ba56a3f, 0x3b9f91cc, 0x3b99ee3b,
+ 0x3b947dae, 0x3b8f3e56, 0x3b8a2e77, 0x3b854c64, 0x3b80967d, 0x3b781668,
+ 0x3b6f520d, 0x3b66dd02, 0x3b5eb47a, 0x3b56d5bf, 0x3b4f3e37, 0x3b47eb5e,
+ 0x3b40dac5, 0x3b3a0a16, 0x3b33770f, 0x3b2d1f81, 0x3b270153, 0x3b211a7e,
+ 0x3b1b690d, 0x3b15eb1c, 0x3b109edb, 0x3b0b8287, 0x3b06946f, 0x3b01d2f1,
+ 0x3afa78f1, 0x3af19f03, 0x3ae91528, 0x3ae0d88b, 0x3ad8e673, 0x3ad13c3c,
+ 0x3ac9d75c, 0x3ac2b561, 0x3abbd3ec, 0x3ab530b7, 0x3aaec98e, 0x3aa89c52,
+ 0x3aa2a6f6, 0x3a9ce782, 0x3a975c0e, 0x3a9202c3, 0x3a8cd9db, 0x3a87dfa1,
+ 0x3a83126f, 0x3a7ce158, 0x3a73f1a2, 0x3a6b52c4, 0x3a6301e2, 0x3a5afc3b,
+ 0x3a533f27, 0x3a4bc816, 0x3a44948c, 0x3a3da229, 0x3a36ee9e, 0x3a3077b3,
+ 0x3a2a3b43, 0x3a24373e, 0x3a1e69a5, 0x3a18d08b, 0x3a136a16, 0x3a0e347c,
+ 0x3a092e02, 0x3a0454ff, 0x39ff4fad, 0x39f649f8, 0x39ed95e3, 0x39e5308a,
+ 0x39dd1726, 0x39d54706, 0x39cdbd95, 0x39c67853, 0x39bf74d7, 0x39b8b0cf,
+ 0x39b229fb, 0x39abde33, 0x39a5cb5f, 0x399fef7e, 0x399a489e, 0x3994d4df,
+ 0x398f9272, 0x398a7f9b, 0x39859aa9, 0x3980e1fe, 0x3978a814, 0x396fde93,
+ 0x39676491, 0x395f373e, 0x395753e5, 0x394fb7e7, 0x394860c1, 0x39414c02,
+ 0x393a7753, 0x3933e06f, 0x392d8529, 0x39276363, 0x39217917, 0x391bc44d,
+ 0x39164323, 0x3910f3c6, 0x390bd472, 0x3906e374, 0x39021f2b, 0x38fb0c03,
+ 0x38f22ce3, 0x38e99e04, 0x38e15c92, 0x38d965ce};
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/tmp.h b/funasr/runtime/cpp/onnxruntime/src/tmp.h
new file mode 100644
index 0000000..b57303f
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/tmp.h
@@ -0,0 +1,112 @@
+
+#ifndef WENETPARAMS_H
+#define WENETPARAMS_H
+// #pragma pack(1)
+
+#define vocab_size 5538
+
+typedef struct {
+ float conv0_weight[512 * 9];
+ float conv0_bias[512];
+
+ float conv1_weight[512 * 512 * 9];
+ float conv1_bias[512];
+
+ float out0_weight[9728 * 512];
+ float out0_bias[512];
+
+} EncEmbedParams;
+
+typedef struct {
+ float linear_q_weight[512 * 512];
+ float linear_q_bias[512];
+ float linear_k_weight[512 * 512];
+ float linear_k_bias[512];
+ float linear_v_weight[512 * 512];
+ float linear_v_bias[512];
+ float linear_out_weight[512 * 512];
+ float linear_out_bias[512];
+} SelfAttnParams;
+
+typedef struct {
+ SelfAttnParams linear0;
+ float linear_pos_weight[512 * 512];
+ float pos_bias_u[512];
+ float pos_bias_v[512];
+
+} EncSelfAttnParams;
+
+typedef struct {
+ float w1_weight[512 * 2048];
+ float w1_bias[2048];
+ float w2_weight[2048 * 512];
+ float w2_bias[512];
+} FeedForwardParams;
+
+typedef struct {
+ float weight[512];
+ float bias[512];
+} NormParams;
+
+typedef struct {
+ float pointwise_conv1_weight[1024 * 512];
+ float pointwise_conv1_bias[1024];
+
+ float depthwise_conv_weight[512 * 15];
+ float depthwise_conv_bias[512];
+
+ float pointwise_conv2_weight[512 * 512];
+ float pointwise_conv2_bias[512];
+ NormParams norm;
+} EncConvParams;
+
+typedef struct {
+ EncSelfAttnParams self_attn;
+ FeedForwardParams feedforward;
+ FeedForwardParams feedforward_macaron;
+ EncConvParams conv_module;
+ NormParams norm_ff;
+ NormParams norm_mha;
+ NormParams norm_macaron;
+ NormParams norm_conv;
+ NormParams norm_final;
+ // float concat_weight[1024 * 512];
+ // float concat_bias[512];
+} SubEncoderParams;
+
+typedef struct {
+ EncEmbedParams embed;
+ SubEncoderParams sub_encoder[12];
+ NormParams after_norm;
+} EncoderParams;
+
+typedef struct {
+ SelfAttnParams self_attn;
+ SelfAttnParams src_attn;
+ FeedForwardParams feedward;
+ NormParams norm1;
+ NormParams norm2;
+ NormParams norm3;
+ // float concat_weight1[1024 * 512];
+ // float concat_bias1[512];
+ // float concat_weight2[1024 * 512];
+ // float concat_bias2[512];
+} SubDecoderParams;
+
+typedef struct {
+ float embed_weight[vocab_size * 512];
+ SubDecoderParams sub_decoder[6];
+ NormParams after_norm;
+ float output_weight[vocab_size * 512];
+ float output_bias[vocab_size];
+} DecoderParams;
+
+typedef struct {
+ EncoderParams encoder;
+ float ctc_weight[512 * vocab_size];
+ float ctc_bias[vocab_size];
+ DecoderParams decoder;
+} WenetParams;
+
+// #pragma pack()
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/src/util.cpp b/funasr/runtime/cpp/onnxruntime/src/util.cpp
new file mode 100644
index 0000000..5a72c72
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/util.cpp
@@ -0,0 +1,180 @@
+
+#include "precomp.h"
+
+float *loadparams(const char *filename)
+{
+
+ FILE *fp;
+ fp = fopen(filename, "rb");
+ fseek(fp, 0, SEEK_END);
+ uint32_t nFileLen = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ float *params_addr = (float *)aligned_malloc(32, nFileLen);
+ int n = fread(params_addr, 1, nFileLen, fp);
+ fclose(fp);
+
+ return params_addr;
+}
+
+int val_align(int val, int align)
+{
+ float tmp = ceil((float)val / (float)align) * (float)align;
+ return (int)tmp;
+}
+
+void disp_params(float *din, int size)
+{
+ int i;
+ for (i = 0; i < size; i++) {
+ printf("%f ", din[i]);
+ }
+ printf("\n");
+}
+void SaveDataFile(const char *filename, void *data, uint32_t len)
+{
+ FILE *fp;
+ fp = fopen(filename, "wb+");
+ fwrite(data, 1, len, fp);
+ fclose(fp);
+}
+
+void basic_norm(Tensor<float> *&din, float norm)
+{
+
+ int Tmax = din->size[2];
+
+ int i, j;
+ for (i = 0; i < Tmax; i++) {
+ float sum = 0;
+ for (j = 0; j < 512; j++) {
+ int ii = i * 512 + j;
+ sum += din->buff[ii] * din->buff[ii];
+ }
+ float mean = sqrt(sum / 512 + norm);
+ for (j = 0; j < 512; j++) {
+ int ii = i * 512 + j;
+ din->buff[ii] = din->buff[ii] / mean;
+ }
+ }
+}
+
+void findmax(float *din, int len, float &max_val, int &max_idx)
+{
+ int i;
+ max_val = -INFINITY;
+ max_idx = -1;
+ for (i = 0; i < len; i++) {
+ if (din[i] > max_val) {
+ max_val = din[i];
+ max_idx = i;
+ }
+ }
+}
+
+string pathAppend(const string &p1, const string &p2)
+{
+
+ char sep = '/';
+ string tmp = p1;
+
+#ifdef _WIN32
+ sep = '\\';
+#endif
+
+ if (p1[p1.length()-1] != sep) { // Need to add a
+ tmp += sep; // path separator
+ return (tmp + p2);
+ } else
+ return (p1 + p2);
+}
+
+void relu(Tensor<float> *din)
+{
+ int i;
+ for (i = 0; i < din->buff_size; i++) {
+ float val = din->buff[i];
+ din->buff[i] = val < 0 ? 0 : val;
+ }
+}
+
+void swish(Tensor<float> *din)
+{
+ int i;
+ for (i = 0; i < din->buff_size; i++) {
+ float val = din->buff[i];
+ din->buff[i] = val / (1 + exp(-val));
+ }
+}
+
+void sigmoid(Tensor<float> *din)
+{
+ int i;
+ for (i = 0; i < din->buff_size; i++) {
+ float val = din->buff[i];
+ din->buff[i] = 1 / (1 + exp(-val));
+ }
+}
+
+void doubleswish(Tensor<float> *din)
+{
+ int i;
+ for (i = 0; i < din->buff_size; i++) {
+ float val = din->buff[i];
+ din->buff[i] = val / (1 + exp(-val + 1));
+ }
+}
+
+void softmax(float *din, int mask, int len)
+{
+ float *tmp = (float *)malloc(mask * sizeof(float));
+ int i;
+ float sum = 0;
+ float max = -INFINITY;
+
+ for (i = 0; i < mask; i++) {
+ max = max < din[i] ? din[i] : max;
+ }
+
+ for (i = 0; i < mask; i++) {
+ tmp[i] = exp(din[i] - max);
+ sum += tmp[i];
+ }
+ for (i = 0; i < mask; i++) {
+ din[i] = tmp[i] / sum;
+ }
+ free(tmp);
+ for (i = mask; i < len; i++) {
+ din[i] = 0;
+ }
+}
+
+void log_softmax(float *din, int len)
+{
+ float *tmp = (float *)malloc(len * sizeof(float));
+ int i;
+ float sum = 0;
+ for (i = 0; i < len; i++) {
+ tmp[i] = exp(din[i]);
+ sum += tmp[i];
+ }
+ for (i = 0; i < len; i++) {
+ din[i] = log(tmp[i] / sum);
+ }
+ free(tmp);
+}
+
+void glu(Tensor<float> *din, Tensor<float> *dout)
+{
+ int mm = din->buff_size / 1024;
+ int i, j;
+ for (i = 0; i < mm; i++) {
+ for (j = 0; j < 512; j++) {
+ int in_off = i * 1024 + j;
+ int out_off = i * 512 + j;
+ float a = din->buff[in_off];
+ float b = din->buff[in_off + 512];
+ dout->buff[out_off] = a / (1 + exp(-b));
+ }
+ }
+}
diff --git a/funasr/runtime/cpp/onnxruntime/src/util.h b/funasr/runtime/cpp/onnxruntime/src/util.h
new file mode 100644
index 0000000..48a27db
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/src/util.h
@@ -0,0 +1,30 @@
+
+
+#ifndef UTIL_H
+#define UTIL_H
+
+using namespace std;
+
+extern float *loadparams(const char *filename);
+
+extern void SaveDataFile(const char *filename, void *data, uint32_t len);
+extern void relu(Tensor<float> *din);
+extern void swish(Tensor<float> *din);
+extern void sigmoid(Tensor<float> *din);
+extern void doubleswish(Tensor<float> *din);
+
+extern void softmax(float *din, int mask, int len);
+
+extern void log_softmax(float *din, int len);
+extern int val_align(int val, int align);
+extern void disp_params(float *din, int size);
+
+extern void basic_norm(Tensor<float> *&din, float norm);
+
+extern void findmax(float *din, int len, float &max_val, int &max_idx);
+
+extern void glu(Tensor<float> *din, Tensor<float> *dout);
+
+string pathAppend(const string &p1, const string &p2);
+
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/tester/CMakeLists.txt b/funasr/runtime/cpp/onnxruntime/tester/CMakeLists.txt
new file mode 100644
index 0000000..651b87f
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/tester/CMakeLists.txt
@@ -0,0 +1,20 @@
+
+
+if(WIN32)
+ if(CMAKE_CL_64)
+ link_directories( ${CMAKE_SOURCE_DIR}/win/lib/x64 )
+ else()
+ link_directories( ${CMAKE_SOURCE_DIR}/win/lib/x86 )
+ endif()
+endif()
+
+set(EXTRA_LIBS rapidasr)
+
+
+include_directories(${CMAKE_SOURCE_DIR}/include)
+set(EXECNAME "tester")
+
+add_executable(${EXECNAME} "tester.cpp")
+target_link_libraries(${EXECNAME} PUBLIC onnxruntime ${EXTRA_LIBS})
+
+
diff --git a/funasr/runtime/cpp/onnxruntime/tester/tester.cpp b/funasr/runtime/cpp/onnxruntime/tester/tester.cpp
new file mode 100644
index 0000000..7bfb4c0
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/tester/tester.cpp
@@ -0,0 +1,72 @@
+#include <iostream>
+#ifndef _WIN32
+#include <sys/time.h>
+#else
+#include <win_func.h>
+#endif
+
+#include <Audio.h>
+#include <Model.h>
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+
+ if (argc < 2)
+ {
+ printf("Usage: %s /path/to/model_dir /path/to/wav/file", argv[0]);
+ exit(-1);
+ }
+ struct timeval start, end;
+ gettimeofday(&start, NULL);
+ int nThreadNum = 4;
+ Model* mm = create_model(argv[1], nThreadNum);
+ if (!mm)
+ {
+ printf("Cannot load ASR Model from: %s, there must be files model.onnx and vocab.txt", argv[1]);
+ exit(-1);
+ }
+
+
+ Audio audio(0);
+ if (!audio.loadwav(argv[2]))
+ {
+ printf("cannot load %s\n", argv[2]);
+ return -1;
+ }
+ audio.disp();
+
+
+ gettimeofday(&end, NULL);
+ long seconds = (end.tv_sec - start.tv_sec);
+ long micros = ((seconds * 1000000) + end.tv_usec) - (start.tv_usec);
+ printf("Model initialization takes %lfs.\n", (double)micros / 1000000);
+ audio.split();
+
+ setbuf(stdout, NULL);
+ cout << "Result: \"";
+ gettimeofday(&start, NULL);
+ float *buff;
+ int len;
+ int flag;
+ while (audio.fetch(buff, len, flag) > 0) {
+ mm->reset();
+ string msg = mm->forward(buff, len, flag);
+ cout << msg;
+ }
+
+ gettimeofday(&end, NULL);
+
+ cout << "\"." << endl;
+
+ seconds = (end.tv_sec - start.tv_sec);
+ long taking_micros = ((seconds * 1000000) + end.tv_usec) - (start.tv_usec);
+ printf("Model inference takes %lfs.\n", (double)micros / 1000000);
+
+ printf("Model inference RTF: %04lf.\n", (double)taking_micros/micros );
+
+ delete mm;
+
+ return 0;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/CMakeLists.txt b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/CMakeLists.txt
new file mode 100644
index 0000000..51812eb
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/CMakeLists.txt
@@ -0,0 +1,16 @@
+
+
+if(WIN32)
+ add_definitions(-DWEBRTC_WIN)
+else()
+ add_definitions(-DWEBRTC_POSIX)
+endif()
+
+
+include_directories("..")
+
+file(GLOB_RECURSE files "*.c" "rtc_base/checks.cc")
+
+message("${files}")
+
+add_library(webrtcvad ${files})
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_bit_reverse.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_bit_reverse.c
new file mode 100644
index 0000000..c8bd2dc
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_bit_reverse.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+/* Tables for data buffer indexes that are bit reversed and thus need to be
+ * swapped. Note that, index_7[{0, 2, 4, ...}] are for the left side of the swap
+ * operations, while index_7[{1, 3, 5, ...}] are for the right side of the
+ * operation. Same for index_8.
+ */
+
+/* Indexes for the case of stages == 7. */
+static const int16_t index_7[112] = {
+ 1, 64, 2, 32, 3, 96, 4, 16, 5, 80, 6, 48, 7, 112, 9, 72, 10, 40, 11, 104,
+ 12, 24, 13, 88, 14, 56, 15, 120, 17, 68, 18, 36, 19, 100, 21, 84, 22, 52,
+ 23, 116, 25, 76, 26, 44, 27, 108, 29, 92, 30, 60, 31, 124, 33, 66, 35, 98,
+ 37, 82, 38, 50, 39, 114, 41, 74, 43, 106, 45, 90, 46, 58, 47, 122, 49, 70,
+ 51, 102, 53, 86, 55, 118, 57, 78, 59, 110, 61, 94, 63, 126, 67, 97, 69,
+ 81, 71, 113, 75, 105, 77, 89, 79, 121, 83, 101, 87, 117, 91, 109, 95, 125,
+ 103, 115, 111, 123
+};
+
+/* Indexes for the case of stages == 8. */
+static const int16_t index_8[240] = {
+ 1, 128, 2, 64, 3, 192, 4, 32, 5, 160, 6, 96, 7, 224, 8, 16, 9, 144, 10, 80,
+ 11, 208, 12, 48, 13, 176, 14, 112, 15, 240, 17, 136, 18, 72, 19, 200, 20,
+ 40, 21, 168, 22, 104, 23, 232, 25, 152, 26, 88, 27, 216, 28, 56, 29, 184,
+ 30, 120, 31, 248, 33, 132, 34, 68, 35, 196, 37, 164, 38, 100, 39, 228, 41,
+ 148, 42, 84, 43, 212, 44, 52, 45, 180, 46, 116, 47, 244, 49, 140, 50, 76,
+ 51, 204, 53, 172, 54, 108, 55, 236, 57, 156, 58, 92, 59, 220, 61, 188, 62,
+ 124, 63, 252, 65, 130, 67, 194, 69, 162, 70, 98, 71, 226, 73, 146, 74, 82,
+ 75, 210, 77, 178, 78, 114, 79, 242, 81, 138, 83, 202, 85, 170, 86, 106, 87,
+ 234, 89, 154, 91, 218, 93, 186, 94, 122, 95, 250, 97, 134, 99, 198, 101,
+ 166, 103, 230, 105, 150, 107, 214, 109, 182, 110, 118, 111, 246, 113, 142,
+ 115, 206, 117, 174, 119, 238, 121, 158, 123, 222, 125, 190, 127, 254, 131,
+ 193, 133, 161, 135, 225, 137, 145, 139, 209, 141, 177, 143, 241, 147, 201,
+ 149, 169, 151, 233, 155, 217, 157, 185, 159, 249, 163, 197, 167, 229, 171,
+ 213, 173, 181, 175, 245, 179, 205, 183, 237, 187, 221, 191, 253, 199, 227,
+ 203, 211, 207, 243, 215, 235, 223, 251, 239, 247
+};
+
+void WebRtcSpl_ComplexBitReverse(int16_t* __restrict complex_data, int stages) {
+ /* For any specific value of stages, we know exactly the indexes that are
+ * bit reversed. Currently (Feb. 2012) in WebRTC the only possible values of
+ * stages are 7 and 8, so we use tables to save unnecessary iterations and
+ * calculations for these two cases.
+ */
+ if (stages == 7 || stages == 8) {
+ int m = 0;
+ int length = 112;
+ const int16_t* index = index_7;
+
+ if (stages == 8) {
+ length = 240;
+ index = index_8;
+ }
+
+ /* Decimation in time. Swap the elements with bit-reversed indexes. */
+ for (m = 0; m < length; m += 2) {
+ /* We declare a int32_t* type pointer, to load both the 16-bit real
+ * and imaginary elements from complex_data in one instruction, reducing
+ * complexity.
+ */
+ int32_t* complex_data_ptr = (int32_t*)complex_data;
+ int32_t temp = 0;
+
+ temp = complex_data_ptr[index[m]]; /* Real and imaginary */
+ complex_data_ptr[index[m]] = complex_data_ptr[index[m + 1]];
+ complex_data_ptr[index[m + 1]] = temp;
+ }
+ }
+ else {
+ int m = 0, mr = 0, l = 0;
+ int n = 1 << stages;
+ int nn = n - 1;
+
+ /* Decimation in time - re-order data */
+ for (m = 1; m <= nn; ++m) {
+ int32_t* complex_data_ptr = (int32_t*)complex_data;
+ int32_t temp = 0;
+
+ /* Find out indexes that are bit-reversed. */
+ l = n;
+ do {
+ l >>= 1;
+ } while (l > nn - mr);
+ mr = (mr & (l - 1)) + l;
+
+ if (mr <= m) {
+ continue;
+ }
+
+ /* Swap the elements with bit-reversed indexes.
+ * This is similar to the loop in the stages == 7 or 8 cases.
+ */
+ temp = complex_data_ptr[m]; /* Real and imaginary */
+ complex_data_ptr[m] = complex_data_ptr[mr];
+ complex_data_ptr[mr] = temp;
+ }
+ }
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_fft.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_fft.c
new file mode 100644
index 0000000..3280872
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_fft.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This file contains the function WebRtcSpl_ComplexFFT().
+ * The description header can be found in signal_processing_library.h
+ *
+ */
+
+#include "webrtc/common_audio/signal_processing/complex_fft_tables.h"
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+#include "webrtc/rtc_base/system/arch.h"
+
+#define CFFTSFT 14
+#define CFFTRND 1
+#define CFFTRND2 16384
+
+#define CIFFTSFT 14
+#define CIFFTRND 1
+
+
+int WebRtcSpl_ComplexFFT(int16_t frfi[], int stages, int mode)
+{
+ int i, j, l, k, istep, n, m;
+ int16_t wr, wi;
+ int32_t tr32, ti32, qr32, qi32;
+
+ /* The 1024-value is a constant given from the size of kSinTable1024[],
+ * and should not be changed depending on the input parameter 'stages'
+ */
+ n = 1 << stages;
+ if (n > 1024)
+ return -1;
+
+ l = 1;
+ k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
+ depending on the input parameter 'stages' */
+
+ if (mode == 0)
+ {
+ // mode==0: Low-complexity and Low-accuracy mode
+ while (l < n)
+ {
+ istep = l << 1;
+
+ for (m = 0; m < l; ++m)
+ {
+ j = m << k;
+
+ /* The 256-value is a constant given as 1/4 of the size of
+ * kSinTable1024[], and should not be changed depending on the input
+ * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
+ */
+ wr = kSinTable1024[j + 256];
+ wi = -kSinTable1024[j];
+
+ for (i = m; i < n; i += istep)
+ {
+ j = i + l;
+
+ tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15;
+
+ ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15;
+
+ qr32 = (int32_t)frfi[2 * i];
+ qi32 = (int32_t)frfi[2 * i + 1];
+ frfi[2 * j] = (int16_t)((qr32 - tr32) >> 1);
+ frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> 1);
+ frfi[2 * i] = (int16_t)((qr32 + tr32) >> 1);
+ frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> 1);
+ }
+ }
+
+ --k;
+ l = istep;
+
+ }
+
+ } else
+ {
+ // mode==1: High-complexity and High-accuracy mode
+ while (l < n)
+ {
+ istep = l << 1;
+
+ for (m = 0; m < l; ++m)
+ {
+ j = m << k;
+
+ /* The 256-value is a constant given as 1/4 of the size of
+ * kSinTable1024[], and should not be changed depending on the input
+ * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
+ */
+ wr = kSinTable1024[j + 256];
+ wi = -kSinTable1024[j];
+
+#ifdef WEBRTC_ARCH_ARM_V7
+ int32_t wri = 0;
+ __asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
+ "r"((int32_t)wr), "r"((int32_t)wi));
+#endif
+
+ for (i = m; i < n; i += istep)
+ {
+ j = i + l;
+
+#ifdef WEBRTC_ARCH_ARM_V7
+ register int32_t frfi_r;
+ __asm __volatile(
+ "pkhbt %[frfi_r], %[frfi_even], %[frfi_odd],"
+ " lsl #16\n\t"
+ "smlsd %[tr32], %[wri], %[frfi_r], %[cfftrnd]\n\t"
+ "smladx %[ti32], %[wri], %[frfi_r], %[cfftrnd]\n\t"
+ :[frfi_r]"=&r"(frfi_r),
+ [tr32]"=&r"(tr32),
+ [ti32]"=r"(ti32)
+ :[frfi_even]"r"((int32_t)frfi[2*j]),
+ [frfi_odd]"r"((int32_t)frfi[2*j +1]),
+ [wri]"r"(wri),
+ [cfftrnd]"r"(CFFTRND));
+#else
+ tr32 = wr * frfi[2 * j] - wi * frfi[2 * j + 1] + CFFTRND;
+
+ ti32 = wr * frfi[2 * j + 1] + wi * frfi[2 * j] + CFFTRND;
+#endif
+
+ tr32 >>= 15 - CFFTSFT;
+ ti32 >>= 15 - CFFTSFT;
+
+ qr32 = ((int32_t)frfi[2 * i]) * (1 << CFFTSFT);
+ qi32 = ((int32_t)frfi[2 * i + 1]) * (1 << CFFTSFT);
+
+ frfi[2 * j] = (int16_t)(
+ (qr32 - tr32 + CFFTRND2) >> (1 + CFFTSFT));
+ frfi[2 * j + 1] = (int16_t)(
+ (qi32 - ti32 + CFFTRND2) >> (1 + CFFTSFT));
+ frfi[2 * i] = (int16_t)(
+ (qr32 + tr32 + CFFTRND2) >> (1 + CFFTSFT));
+ frfi[2 * i + 1] = (int16_t)(
+ (qi32 + ti32 + CFFTRND2) >> (1 + CFFTSFT));
+ }
+ }
+
+ --k;
+ l = istep;
+ }
+ }
+ return 0;
+}
+
+int WebRtcSpl_ComplexIFFT(int16_t frfi[], int stages, int mode)
+{
+ size_t i, j, l, istep, n, m;
+ int k, scale, shift;
+ int16_t wr, wi;
+ int32_t tr32, ti32, qr32, qi32;
+ int32_t tmp32, round2;
+
+ /* The 1024-value is a constant given from the size of kSinTable1024[],
+ * and should not be changed depending on the input parameter 'stages'
+ */
+ n = ((size_t)1) << stages;
+ if (n > 1024)
+ return -1;
+
+ scale = 0;
+
+ l = 1;
+ k = 10 - 1; /* Constant for given kSinTable1024[]. Do not change
+ depending on the input parameter 'stages' */
+
+ while (l < n)
+ {
+ // variable scaling, depending upon data
+ shift = 0;
+ round2 = 8192;
+
+ tmp32 = WebRtcSpl_MaxAbsValueW16(frfi, 2 * n);
+ if (tmp32 > 13573)
+ {
+ shift++;
+ scale++;
+ round2 <<= 1;
+ }
+ if (tmp32 > 27146)
+ {
+ shift++;
+ scale++;
+ round2 <<= 1;
+ }
+
+ istep = l << 1;
+
+ if (mode == 0)
+ {
+ // mode==0: Low-complexity and Low-accuracy mode
+ for (m = 0; m < l; ++m)
+ {
+ j = m << k;
+
+ /* The 256-value is a constant given as 1/4 of the size of
+ * kSinTable1024[], and should not be changed depending on the input
+ * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
+ */
+ wr = kSinTable1024[j + 256];
+ wi = kSinTable1024[j];
+
+ for (i = m; i < n; i += istep)
+ {
+ j = i + l;
+
+ tr32 = (wr * frfi[2 * j] - wi * frfi[2 * j + 1]) >> 15;
+
+ ti32 = (wr * frfi[2 * j + 1] + wi * frfi[2 * j]) >> 15;
+
+ qr32 = (int32_t)frfi[2 * i];
+ qi32 = (int32_t)frfi[2 * i + 1];
+ frfi[2 * j] = (int16_t)((qr32 - tr32) >> shift);
+ frfi[2 * j + 1] = (int16_t)((qi32 - ti32) >> shift);
+ frfi[2 * i] = (int16_t)((qr32 + tr32) >> shift);
+ frfi[2 * i + 1] = (int16_t)((qi32 + ti32) >> shift);
+ }
+ }
+ } else
+ {
+ // mode==1: High-complexity and High-accuracy mode
+
+ for (m = 0; m < l; ++m)
+ {
+ j = m << k;
+
+ /* The 256-value is a constant given as 1/4 of the size of
+ * kSinTable1024[], and should not be changed depending on the input
+ * parameter 'stages'. It will result in 0 <= j < N_SINE_WAVE/2
+ */
+ wr = kSinTable1024[j + 256];
+ wi = kSinTable1024[j];
+
+#ifdef WEBRTC_ARCH_ARM_V7
+ int32_t wri = 0;
+ __asm __volatile("pkhbt %0, %1, %2, lsl #16" : "=r"(wri) :
+ "r"((int32_t)wr), "r"((int32_t)wi));
+#endif
+
+ for (i = m; i < n; i += istep)
+ {
+ j = i + l;
+
+#ifdef WEBRTC_ARCH_ARM_V7
+ register int32_t frfi_r;
+ __asm __volatile(
+ "pkhbt %[frfi_r], %[frfi_even], %[frfi_odd], lsl #16\n\t"
+ "smlsd %[tr32], %[wri], %[frfi_r], %[cifftrnd]\n\t"
+ "smladx %[ti32], %[wri], %[frfi_r], %[cifftrnd]\n\t"
+ :[frfi_r]"=&r"(frfi_r),
+ [tr32]"=&r"(tr32),
+ [ti32]"=r"(ti32)
+ :[frfi_even]"r"((int32_t)frfi[2*j]),
+ [frfi_odd]"r"((int32_t)frfi[2*j +1]),
+ [wri]"r"(wri),
+ [cifftrnd]"r"(CIFFTRND)
+ );
+#else
+
+ tr32 = wr * frfi[2 * j] - wi * frfi[2 * j + 1] + CIFFTRND;
+
+ ti32 = wr * frfi[2 * j + 1] + wi * frfi[2 * j] + CIFFTRND;
+#endif
+ tr32 >>= 15 - CIFFTSFT;
+ ti32 >>= 15 - CIFFTSFT;
+
+ qr32 = ((int32_t)frfi[2 * i]) * (1 << CIFFTSFT);
+ qi32 = ((int32_t)frfi[2 * i + 1]) * (1 << CIFFTSFT);
+
+ frfi[2 * j] = (int16_t)(
+ (qr32 - tr32 + round2) >> (shift + CIFFTSFT));
+ frfi[2 * j + 1] = (int16_t)(
+ (qi32 - ti32 + round2) >> (shift + CIFFTSFT));
+ frfi[2 * i] = (int16_t)(
+ (qr32 + tr32 + round2) >> (shift + CIFFTSFT));
+ frfi[2 * i + 1] = (int16_t)(
+ (qi32 + ti32 + round2) >> (shift + CIFFTSFT));
+ }
+ }
+
+ }
+ --k;
+ l = istep;
+ }
+ return scale;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_fft_tables.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_fft_tables.h
new file mode 100644
index 0000000..90fac07
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/complex_fft_tables.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
+#define COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
+
+#include <stdint.h>
+
+static const int16_t kSinTable1024[] = {
+ 0, 201, 402, 603, 804, 1005, 1206, 1406, 1607,
+ 1808, 2009, 2209, 2410, 2610, 2811, 3011, 3211, 3411,
+ 3611, 3811, 4011, 4210, 4409, 4608, 4807, 5006, 5205,
+ 5403, 5601, 5799, 5997, 6195, 6392, 6589, 6786, 6982,
+ 7179, 7375, 7571, 7766, 7961, 8156, 8351, 8545, 8739,
+ 8932, 9126, 9319, 9511, 9703, 9895, 10087, 10278, 10469,
+ 10659, 10849, 11038, 11227, 11416, 11604, 11792, 11980, 12166,
+ 12353, 12539, 12724, 12909, 13094, 13278, 13462, 13645, 13827,
+ 14009, 14191, 14372, 14552, 14732, 14911, 15090, 15268, 15446,
+ 15623, 15799, 15975, 16150, 16325, 16499, 16672, 16845, 17017,
+ 17189, 17360, 17530, 17699, 17868, 18036, 18204, 18371, 18537,
+ 18702, 18867, 19031, 19194, 19357, 19519, 19680, 19840, 20000,
+ 20159, 20317, 20474, 20631, 20787, 20942, 21096, 21249, 21402,
+ 21554, 21705, 21855, 22004, 22153, 22301, 22448, 22594, 22739,
+ 22883, 23027, 23169, 23311, 23452, 23592, 23731, 23869, 24006,
+ 24143, 24278, 24413, 24546, 24679, 24811, 24942, 25072, 25201,
+ 25329, 25456, 25582, 25707, 25831, 25954, 26077, 26198, 26318,
+ 26437, 26556, 26673, 26789, 26905, 27019, 27132, 27244, 27355,
+ 27466, 27575, 27683, 27790, 27896, 28001, 28105, 28208, 28309,
+ 28410, 28510, 28608, 28706, 28802, 28897, 28992, 29085, 29177,
+ 29268, 29358, 29446, 29534, 29621, 29706, 29790, 29873, 29955,
+ 30036, 30116, 30195, 30272, 30349, 30424, 30498, 30571, 30643,
+ 30713, 30783, 30851, 30918, 30984, 31049, 31113, 31175, 31236,
+ 31297, 31356, 31413, 31470, 31525, 31580, 31633, 31684, 31735,
+ 31785, 31833, 31880, 31926, 31970, 32014, 32056, 32097, 32137,
+ 32176, 32213, 32249, 32284, 32318, 32350, 32382, 32412, 32441,
+ 32468, 32495, 32520, 32544, 32567, 32588, 32609, 32628, 32646,
+ 32662, 32678, 32692, 32705, 32717, 32727, 32736, 32744, 32751,
+ 32757, 32761, 32764, 32766, 32767, 32766, 32764, 32761, 32757,
+ 32751, 32744, 32736, 32727, 32717, 32705, 32692, 32678, 32662,
+ 32646, 32628, 32609, 32588, 32567, 32544, 32520, 32495, 32468,
+ 32441, 32412, 32382, 32350, 32318, 32284, 32249, 32213, 32176,
+ 32137, 32097, 32056, 32014, 31970, 31926, 31880, 31833, 31785,
+ 31735, 31684, 31633, 31580, 31525, 31470, 31413, 31356, 31297,
+ 31236, 31175, 31113, 31049, 30984, 30918, 30851, 30783, 30713,
+ 30643, 30571, 30498, 30424, 30349, 30272, 30195, 30116, 30036,
+ 29955, 29873, 29790, 29706, 29621, 29534, 29446, 29358, 29268,
+ 29177, 29085, 28992, 28897, 28802, 28706, 28608, 28510, 28410,
+ 28309, 28208, 28105, 28001, 27896, 27790, 27683, 27575, 27466,
+ 27355, 27244, 27132, 27019, 26905, 26789, 26673, 26556, 26437,
+ 26318, 26198, 26077, 25954, 25831, 25707, 25582, 25456, 25329,
+ 25201, 25072, 24942, 24811, 24679, 24546, 24413, 24278, 24143,
+ 24006, 23869, 23731, 23592, 23452, 23311, 23169, 23027, 22883,
+ 22739, 22594, 22448, 22301, 22153, 22004, 21855, 21705, 21554,
+ 21402, 21249, 21096, 20942, 20787, 20631, 20474, 20317, 20159,
+ 20000, 19840, 19680, 19519, 19357, 19194, 19031, 18867, 18702,
+ 18537, 18371, 18204, 18036, 17868, 17699, 17530, 17360, 17189,
+ 17017, 16845, 16672, 16499, 16325, 16150, 15975, 15799, 15623,
+ 15446, 15268, 15090, 14911, 14732, 14552, 14372, 14191, 14009,
+ 13827, 13645, 13462, 13278, 13094, 12909, 12724, 12539, 12353,
+ 12166, 11980, 11792, 11604, 11416, 11227, 11038, 10849, 10659,
+ 10469, 10278, 10087, 9895, 9703, 9511, 9319, 9126, 8932,
+ 8739, 8545, 8351, 8156, 7961, 7766, 7571, 7375, 7179,
+ 6982, 6786, 6589, 6392, 6195, 5997, 5799, 5601, 5403,
+ 5205, 5006, 4807, 4608, 4409, 4210, 4011, 3811, 3611,
+ 3411, 3211, 3011, 2811, 2610, 2410, 2209, 2009, 1808,
+ 1607, 1406, 1206, 1005, 804, 603, 402, 201, 0,
+ -201, -402, -603, -804, -1005, -1206, -1406, -1607, -1808,
+ -2009, -2209, -2410, -2610, -2811, -3011, -3211, -3411, -3611,
+ -3811, -4011, -4210, -4409, -4608, -4807, -5006, -5205, -5403,
+ -5601, -5799, -5997, -6195, -6392, -6589, -6786, -6982, -7179,
+ -7375, -7571, -7766, -7961, -8156, -8351, -8545, -8739, -8932,
+ -9126, -9319, -9511, -9703, -9895, -10087, -10278, -10469, -10659,
+ -10849, -11038, -11227, -11416, -11604, -11792, -11980, -12166, -12353,
+ -12539, -12724, -12909, -13094, -13278, -13462, -13645, -13827, -14009,
+ -14191, -14372, -14552, -14732, -14911, -15090, -15268, -15446, -15623,
+ -15799, -15975, -16150, -16325, -16499, -16672, -16845, -17017, -17189,
+ -17360, -17530, -17699, -17868, -18036, -18204, -18371, -18537, -18702,
+ -18867, -19031, -19194, -19357, -19519, -19680, -19840, -20000, -20159,
+ -20317, -20474, -20631, -20787, -20942, -21096, -21249, -21402, -21554,
+ -21705, -21855, -22004, -22153, -22301, -22448, -22594, -22739, -22883,
+ -23027, -23169, -23311, -23452, -23592, -23731, -23869, -24006, -24143,
+ -24278, -24413, -24546, -24679, -24811, -24942, -25072, -25201, -25329,
+ -25456, -25582, -25707, -25831, -25954, -26077, -26198, -26318, -26437,
+ -26556, -26673, -26789, -26905, -27019, -27132, -27244, -27355, -27466,
+ -27575, -27683, -27790, -27896, -28001, -28105, -28208, -28309, -28410,
+ -28510, -28608, -28706, -28802, -28897, -28992, -29085, -29177, -29268,
+ -29358, -29446, -29534, -29621, -29706, -29790, -29873, -29955, -30036,
+ -30116, -30195, -30272, -30349, -30424, -30498, -30571, -30643, -30713,
+ -30783, -30851, -30918, -30984, -31049, -31113, -31175, -31236, -31297,
+ -31356, -31413, -31470, -31525, -31580, -31633, -31684, -31735, -31785,
+ -31833, -31880, -31926, -31970, -32014, -32056, -32097, -32137, -32176,
+ -32213, -32249, -32284, -32318, -32350, -32382, -32412, -32441, -32468,
+ -32495, -32520, -32544, -32567, -32588, -32609, -32628, -32646, -32662,
+ -32678, -32692, -32705, -32717, -32727, -32736, -32744, -32751, -32757,
+ -32761, -32764, -32766, -32767, -32766, -32764, -32761, -32757, -32751,
+ -32744, -32736, -32727, -32717, -32705, -32692, -32678, -32662, -32646,
+ -32628, -32609, -32588, -32567, -32544, -32520, -32495, -32468, -32441,
+ -32412, -32382, -32350, -32318, -32284, -32249, -32213, -32176, -32137,
+ -32097, -32056, -32014, -31970, -31926, -31880, -31833, -31785, -31735,
+ -31684, -31633, -31580, -31525, -31470, -31413, -31356, -31297, -31236,
+ -31175, -31113, -31049, -30984, -30918, -30851, -30783, -30713, -30643,
+ -30571, -30498, -30424, -30349, -30272, -30195, -30116, -30036, -29955,
+ -29873, -29790, -29706, -29621, -29534, -29446, -29358, -29268, -29177,
+ -29085, -28992, -28897, -28802, -28706, -28608, -28510, -28410, -28309,
+ -28208, -28105, -28001, -27896, -27790, -27683, -27575, -27466, -27355,
+ -27244, -27132, -27019, -26905, -26789, -26673, -26556, -26437, -26318,
+ -26198, -26077, -25954, -25831, -25707, -25582, -25456, -25329, -25201,
+ -25072, -24942, -24811, -24679, -24546, -24413, -24278, -24143, -24006,
+ -23869, -23731, -23592, -23452, -23311, -23169, -23027, -22883, -22739,
+ -22594, -22448, -22301, -22153, -22004, -21855, -21705, -21554, -21402,
+ -21249, -21096, -20942, -20787, -20631, -20474, -20317, -20159, -20000,
+ -19840, -19680, -19519, -19357, -19194, -19031, -18867, -18702, -18537,
+ -18371, -18204, -18036, -17868, -17699, -17530, -17360, -17189, -17017,
+ -16845, -16672, -16499, -16325, -16150, -15975, -15799, -15623, -15446,
+ -15268, -15090, -14911, -14732, -14552, -14372, -14191, -14009, -13827,
+ -13645, -13462, -13278, -13094, -12909, -12724, -12539, -12353, -12166,
+ -11980, -11792, -11604, -11416, -11227, -11038, -10849, -10659, -10469,
+ -10278, -10087, -9895, -9703, -9511, -9319, -9126, -8932, -8739,
+ -8545, -8351, -8156, -7961, -7766, -7571, -7375, -7179, -6982,
+ -6786, -6589, -6392, -6195, -5997, -5799, -5601, -5403, -5205,
+ -5006, -4807, -4608, -4409, -4210, -4011, -3811, -3611, -3411,
+ -3211, -3011, -2811, -2610, -2410, -2209, -2009, -1808, -1607,
+ -1406, -1206, -1005, -804, -603, -402, -201};
+
+#endif // COMMON_AUDIO_SIGNAL_PROCESSING_COMPLEX_FFT_TABLES_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/cross_correlation.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/cross_correlation.c
new file mode 100644
index 0000000..d7c9f2b
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/cross_correlation.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+/* C version of WebRtcSpl_CrossCorrelation() for generic platforms. */
+void WebRtcSpl_CrossCorrelationC(int32_t* cross_correlation,
+ const int16_t* seq1,
+ const int16_t* seq2,
+ size_t dim_seq,
+ size_t dim_cross_correlation,
+ int right_shifts,
+ int step_seq2) {
+ size_t i = 0, j = 0;
+
+ for (i = 0; i < dim_cross_correlation; i++) {
+ int32_t corr = 0;
+ for (j = 0; j < dim_seq; j++)
+ corr += (seq1[j] * seq2[j]) >> right_shifts;
+ seq2 += step_seq2;
+ *cross_correlation++ = corr;
+ }
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/division_operations.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/division_operations.c
new file mode 100644
index 0000000..2d42052
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/division_operations.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This file contains implementations of the divisions
+ * WebRtcSpl_DivU32U16()
+ * WebRtcSpl_DivW32W16()
+ * WebRtcSpl_DivW32W16ResW16()
+ * WebRtcSpl_DivResultInQ31()
+ * WebRtcSpl_DivW32HiLow()
+ *
+ * The description header can be found in signal_processing_library.h
+ *
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+#include "webrtc/rtc_base/sanitizer.h"
+
+uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den)
+{
+ // Guard against division with 0
+ if (den != 0)
+ {
+ return (uint32_t)(num / den);
+ } else
+ {
+ return (uint32_t)0xFFFFFFFF;
+ }
+}
+
+int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den)
+{
+ // Guard against division with 0
+ if (den != 0)
+ {
+ return (int32_t)(num / den);
+ } else
+ {
+ return (int32_t)0x7FFFFFFF;
+ }
+}
+
+int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den)
+{
+ // Guard against division with 0
+ if (den != 0)
+ {
+ return (int16_t)(num / den);
+ } else
+ {
+ return (int16_t)0x7FFF;
+ }
+}
+
+int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den)
+{
+ int32_t L_num = num;
+ int32_t L_den = den;
+ int32_t div = 0;
+ int k = 31;
+ int change_sign = 0;
+
+ if (num == 0)
+ return 0;
+
+ if (num < 0)
+ {
+ change_sign++;
+ L_num = -num;
+ }
+ if (den < 0)
+ {
+ change_sign++;
+ L_den = -den;
+ }
+ while (k--)
+ {
+ div <<= 1;
+ L_num <<= 1;
+ if (L_num >= L_den)
+ {
+ L_num -= L_den;
+ div++;
+ }
+ }
+ if (change_sign == 1)
+ {
+ div = -div;
+ }
+ return div;
+}
+
+int32_t RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486
+WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low)
+{
+ int16_t approx, tmp_hi, tmp_low, num_hi, num_low;
+ int32_t tmpW32;
+
+ approx = (int16_t)WebRtcSpl_DivW32W16((int32_t)0x1FFFFFFF, den_hi);
+ // result in Q14 (Note: 3FFFFFFF = 0.5 in Q30)
+
+ // tmpW32 = 1/den = approx * (2.0 - den * approx) (in Q30)
+ tmpW32 = (den_hi * approx << 1) + ((den_low * approx >> 15) << 1);
+ // tmpW32 = den * approx
+
+ tmpW32 = (int32_t)0x7fffffffL - tmpW32; // result in Q30 (tmpW32 = 2.0-(den*approx))
+ // UBSan: 2147483647 - -2 cannot be represented in type 'int'
+
+ // Store tmpW32 in hi and low format
+ tmp_hi = (int16_t)(tmpW32 >> 16);
+ tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
+
+ // tmpW32 = 1/den in Q29
+ tmpW32 = (tmp_hi * approx + (tmp_low * approx >> 15)) << 1;
+
+ // 1/den in hi and low format
+ tmp_hi = (int16_t)(tmpW32 >> 16);
+ tmp_low = (int16_t)((tmpW32 - ((int32_t)tmp_hi << 16)) >> 1);
+
+ // Store num in hi and low format
+ num_hi = (int16_t)(num >> 16);
+ num_low = (int16_t)((num - ((int32_t)num_hi << 16)) >> 1);
+
+ // num * (1/den) by 32 bit multiplication (result in Q28)
+
+ tmpW32 = num_hi * tmp_hi + (num_hi * tmp_low >> 15) +
+ (num_low * tmp_hi >> 15);
+
+ // Put result in Q31 (convert from Q28)
+ tmpW32 = WEBRTC_SPL_LSHIFT_W32(tmpW32, 3);
+
+ return tmpW32;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.cc b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.cc
new file mode 100644
index 0000000..d9661af
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/common_audio/signal_processing/dot_product_with_scale.h"
+
+#include "webrtc/rtc_base/numerics/safe_conversions.h"
+
+int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1,
+ const int16_t* vector2,
+ size_t length,
+ int scaling) {
+ int64_t sum = 0;
+ size_t i = 0;
+
+ /* Unroll the loop to improve performance. */
+ for (i = 0; i + 3 < length; i += 4) {
+ sum += (vector1[i + 0] * vector2[i + 0]) >> scaling;
+ sum += (vector1[i + 1] * vector2[i + 1]) >> scaling;
+ sum += (vector1[i + 2] * vector2[i + 2]) >> scaling;
+ sum += (vector1[i + 3] * vector2[i + 3]) >> scaling;
+ }
+ for (; i < length; i++) {
+ sum += (vector1[i] * vector2[i]) >> scaling;
+ }
+
+ return rtc::saturated_cast<int32_t>(sum);
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.h
new file mode 100644
index 0000000..bb892d4
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/dot_product_with_scale.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_
+#define COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_
+
+#include <stdint.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Calculates the dot product between two (int16_t) vectors.
+//
+// Input:
+// - vector1 : Vector 1
+// - vector2 : Vector 2
+// - vector_length : Number of samples used in the dot product
+// - scaling : The number of right bit shifts to apply on each term
+// during calculation to avoid overflow, i.e., the
+// output will be in Q(-|scaling|)
+//
+// Return value : The dot product in Q(-scaling)
+int32_t WebRtcSpl_DotProductWithScale(const int16_t* vector1,
+ const int16_t* vector2,
+ size_t length,
+ int scaling);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif // COMMON_AUDIO_SIGNAL_PROCESSING_DOT_PRODUCT_WITH_SCALE_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/downsample_fast.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/downsample_fast.c
new file mode 100644
index 0000000..e575861
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/downsample_fast.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+#include "webrtc/rtc_base/checks.h"
+#include "webrtc/rtc_base/sanitizer.h"
+
+// TODO(Bjornv): Change the function parameter order to WebRTC code style.
+// C version of WebRtcSpl_DownsampleFast() for generic platforms.
+int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
+ size_t data_in_length,
+ int16_t* data_out,
+ size_t data_out_length,
+ const int16_t* __restrict coefficients,
+ size_t coefficients_length,
+ int factor,
+ size_t delay) {
+ int16_t* const original_data_out = data_out;
+ size_t i = 0;
+ size_t j = 0;
+ int32_t out_s32 = 0;
+ size_t endpos = delay + factor * (data_out_length - 1) + 1;
+
+ // Return error if any of the running conditions doesn't meet.
+ if (data_out_length == 0 || coefficients_length == 0
+ || data_in_length < endpos) {
+ return -1;
+ }
+
+ rtc_MsanCheckInitialized(coefficients, sizeof(coefficients[0]),
+ coefficients_length);
+
+ for (i = delay; i < endpos; i += factor) {
+ out_s32 = 2048; // Round value, 0.5 in Q12.
+
+ for (j = 0; j < coefficients_length; j++) {
+ // Negative overflow is permitted here, because this is
+ // auto-regressive filters, and the state for each batch run is
+ // stored in the "negative" positions of the output vector.
+ rtc_MsanCheckInitialized(&data_in[(ptrdiff_t) i - (ptrdiff_t) j],
+ sizeof(data_in[0]), 1);
+ // out_s32 is in Q12 domain.
+ out_s32 += coefficients[j] * data_in[(ptrdiff_t) i - (ptrdiff_t) j];
+ }
+
+ out_s32 >>= 12; // Q0.
+
+ // Saturate and store the output.
+ *data_out++ = WebRtcSpl_SatW32ToW16(out_s32);
+ }
+
+ RTC_DCHECK_EQ(original_data_out + data_out_length, data_out);
+ rtc_MsanCheckInitialized(original_data_out, sizeof(original_data_out[0]),
+ data_out_length);
+
+ return 0;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/energy.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/energy.c
new file mode 100644
index 0000000..e83f1a6
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/energy.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This file contains the function WebRtcSpl_Energy().
+ * The description header can be found in signal_processing_library.h
+ *
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+int32_t WebRtcSpl_Energy(int16_t* vector,
+ size_t vector_length,
+ int* scale_factor)
+{
+ int32_t en = 0;
+ size_t i;
+ int scaling =
+ WebRtcSpl_GetScalingSquare(vector, vector_length, vector_length);
+ size_t looptimes = vector_length;
+ int16_t *vectorptr = vector;
+
+ for (i = 0; i < looptimes; i++)
+ {
+ en += (*vectorptr * *vectorptr) >> scaling;
+ vectorptr++;
+ }
+ *scale_factor = scaling;
+
+ return en;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/get_scaling_square.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/get_scaling_square.c
new file mode 100644
index 0000000..82e3c8b
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/get_scaling_square.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This file contains the function WebRtcSpl_GetScalingSquare().
+ * The description header can be found in signal_processing_library.h
+ *
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+int16_t WebRtcSpl_GetScalingSquare(int16_t* in_vector,
+ size_t in_vector_length,
+ size_t times)
+{
+ int16_t nbits = WebRtcSpl_GetSizeInBits((uint32_t)times);
+ size_t i;
+ int16_t smax = -1;
+ int16_t sabs;
+ int16_t *sptr = in_vector;
+ int16_t t;
+ size_t looptimes = in_vector_length;
+
+ for (i = looptimes; i > 0; i--)
+ {
+ sabs = (*sptr > 0 ? *sptr++ : -*sptr++);
+ smax = (sabs > smax ? sabs : smax);
+ }
+ t = WebRtcSpl_NormW32(WEBRTC_SPL_MUL(smax, smax));
+
+ if (smax == 0)
+ {
+ return 0; // Since norm(0) returns 0
+ } else
+ {
+ return (t > nbits) ? 0 : nbits - t;
+ }
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/real_fft.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/real_fft.h
new file mode 100644
index 0000000..8445066
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/real_fft.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
+#define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
+
+#include <stdint.h>
+
+// For ComplexFFT(), the maximum fft order is 10;
+// WebRTC APM uses orders of only 7 and 8.
+enum { kMaxFFTOrder = 10 };
+
+struct RealFFT;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct RealFFT* WebRtcSpl_CreateRealFFT(int order);
+void WebRtcSpl_FreeRealFFT(struct RealFFT* self);
+
+// Compute an FFT for a real-valued signal of length of 2^order,
+// where 1 < order <= MAX_FFT_ORDER. Transform length is determined by the
+// specification structure, which must be initialized prior to calling the FFT
+// function with WebRtcSpl_CreateRealFFT().
+// The relationship between the input and output sequences can
+// be expressed in terms of the DFT, i.e.:
+// x[n] = (2^(-scalefactor)/N) . SUM[k=0,...,N-1] X[k].e^(jnk.2.pi/N)
+// n=0,1,2,...N-1
+// N=2^order.
+// The conjugate-symmetric output sequence is represented using a CCS vector,
+// which is of length N+2, and is organized as follows:
+// Index: 0 1 2 3 4 5 . . . N-2 N-1 N N+1
+// Component: R0 0 R1 I1 R2 I2 . . . R[N/2-1] I[N/2-1] R[N/2] 0
+// where R[n] and I[n], respectively, denote the real and imaginary components
+// for FFT bin 'n'. Bins are numbered from 0 to N/2, where N is the FFT length.
+// Bin index 0 corresponds to the DC component, and bin index N/2 corresponds to
+// the foldover frequency.
+//
+// Input Arguments:
+// self - pointer to preallocated and initialized FFT specification structure.
+// real_data_in - the input signal. For an ARM Neon platform, it must be
+// aligned on a 32-byte boundary.
+//
+// Output Arguments:
+// complex_data_out - the output complex signal with (2^order + 2) 16-bit
+// elements. For an ARM Neon platform, it must be different
+// from real_data_in, and aligned on a 32-byte boundary.
+//
+// Return Value:
+// 0 - FFT calculation is successful.
+// -1 - Error with bad arguments (null pointers).
+int WebRtcSpl_RealForwardFFT(struct RealFFT* self,
+ const int16_t* real_data_in,
+ int16_t* complex_data_out);
+
+// Compute the inverse FFT for a conjugate-symmetric input sequence of length of
+// 2^order, where 1 < order <= MAX_FFT_ORDER. Transform length is determined by
+// the specification structure, which must be initialized prior to calling the
+// FFT function with WebRtcSpl_CreateRealFFT().
+// For a transform of length M, the input sequence is represented using a packed
+// CCS vector of length M+2, which is explained in the comments for
+// WebRtcSpl_RealForwardFFTC above.
+//
+// Input Arguments:
+// self - pointer to preallocated and initialized FFT specification structure.
+// complex_data_in - the input complex signal with (2^order + 2) 16-bit
+// elements. For an ARM Neon platform, it must be aligned on
+// a 32-byte boundary.
+//
+// Output Arguments:
+// real_data_out - the output real signal. For an ARM Neon platform, it must
+// be different to complex_data_in, and aligned on a 32-byte
+// boundary.
+//
+// Return Value:
+// 0 or a positive number - a value that the elements in the |real_data_out|
+// should be shifted left with in order to get
+// correct physical values.
+// -1 - Error with bad arguments (null pointers).
+int WebRtcSpl_RealInverseFFT(struct RealFFT* self,
+ const int16_t* complex_data_in,
+ int16_t* real_data_out);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_REAL_FFT_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/signal_processing_library.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/signal_processing_library.h
new file mode 100644
index 0000000..ccbb306
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/signal_processing_library.h
@@ -0,0 +1,1612 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * This header file includes all of the fix point signal processing library
+ * (SPL) function descriptions and declarations. For specific function calls,
+ * see bottom of file.
+ */
+
+#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SIGNAL_PROCESSING_LIBRARY_H_
+#define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SIGNAL_PROCESSING_LIBRARY_H_
+
+#include <string.h>
+#include "webrtc/common_audio/signal_processing/dot_product_with_scale.h"
+
+// Macros specific for the fixed point implementation
+#define WEBRTC_SPL_WORD16_MAX 32767
+#define WEBRTC_SPL_WORD16_MIN -32768
+#define WEBRTC_SPL_WORD32_MAX (int32_t)0x7fffffff
+#define WEBRTC_SPL_WORD32_MIN (int32_t)0x80000000
+#define WEBRTC_SPL_MAX_LPC_ORDER 14
+#define WEBRTC_SPL_MIN(A, B) (A < B ? A : B) // Get min value
+#define WEBRTC_SPL_MAX(A, B) (A > B ? A : B) // Get max value
+// TODO(kma/bjorn): For the next two macros, investigate how to correct the code
+// for inputs of a = WEBRTC_SPL_WORD16_MIN or WEBRTC_SPL_WORD32_MIN.
+#define WEBRTC_SPL_ABS_W16(a) (((int16_t)a >= 0) ? ((int16_t)a) : -((int16_t)a))
+#define WEBRTC_SPL_ABS_W32(a) (((int32_t)a >= 0) ? ((int32_t)a) : -((int32_t)a))
+
+#define WEBRTC_SPL_MUL(a, b) ((int32_t)((int32_t)(a) * (int32_t)(b)))
+#define WEBRTC_SPL_UMUL(a, b) ((uint32_t)((uint32_t)(a) * (uint32_t)(b)))
+#define WEBRTC_SPL_UMUL_32_16(a, b) ((uint32_t)((uint32_t)(a) * (uint16_t)(b)))
+#define WEBRTC_SPL_MUL_16_U16(a, b) ((int32_t)(int16_t)(a) * (uint16_t)(b))
+
+// clang-format off
+// clang-format would choose some identation
+// leading to presubmit error (cpplint.py)
+#ifndef WEBRTC_ARCH_ARM_V7
+// For ARMv7 platforms, these are inline functions in spl_inl_armv7.h
+#ifndef MIPS32_LE
+// For MIPS platforms, these are inline functions in spl_inl_mips.h
+#define WEBRTC_SPL_MUL_16_16(a, b) ((int32_t)(((int16_t)(a)) * ((int16_t)(b))))
+#define WEBRTC_SPL_MUL_16_32_RSFT16(a, b) \
+ (WEBRTC_SPL_MUL_16_16(a, b >> 16) + \
+ ((WEBRTC_SPL_MUL_16_16(a, (b & 0xffff) >> 1) + 0x4000) >> 15))
+#endif
+#endif
+
+#define WEBRTC_SPL_MUL_16_32_RSFT11(a, b) \
+ (WEBRTC_SPL_MUL_16_16(a, (b) >> 16) * (1 << 5) + \
+ (((WEBRTC_SPL_MUL_16_U16(a, (uint16_t)(b)) >> 1) + 0x0200) >> 10))
+#define WEBRTC_SPL_MUL_16_32_RSFT14(a, b) \
+ (WEBRTC_SPL_MUL_16_16(a, (b) >> 16) * (1 << 2) + \
+ (((WEBRTC_SPL_MUL_16_U16(a, (uint16_t)(b)) >> 1) + 0x1000) >> 13))
+#define WEBRTC_SPL_MUL_16_32_RSFT15(a, b) \
+ ((WEBRTC_SPL_MUL_16_16(a, (b) >> 16) * (1 << 1)) + \
+ (((WEBRTC_SPL_MUL_16_U16(a, (uint16_t)(b)) >> 1) + 0x2000) >> 14))
+// clang-format on
+
+#define WEBRTC_SPL_MUL_16_16_RSFT(a, b, c) (WEBRTC_SPL_MUL_16_16(a, b) >> (c))
+
+#define WEBRTC_SPL_MUL_16_16_RSFT_WITH_ROUND(a, b, c) \
+ ((WEBRTC_SPL_MUL_16_16(a, b) + ((int32_t)(((int32_t)1) << ((c)-1)))) >> (c))
+
+// C + the 32 most significant bits of A * B
+#define WEBRTC_SPL_SCALEDIFF32(A, B, C) \
+ (C + (B >> 16) * A + (((uint32_t)(B & 0x0000FFFF) * A) >> 16))
+
+#define WEBRTC_SPL_SAT(a, b, c) (b > a ? a : b < c ? c : b)
+
+// Shifting with negative numbers allowed
+// Positive means left shift
+#define WEBRTC_SPL_SHIFT_W32(x, c) ((c) >= 0 ? (x) * (1 << (c)) : (x) >> -(c))
+
+// Shifting with negative numbers not allowed
+// We cannot do casting here due to signed/unsigned problem
+#define WEBRTC_SPL_LSHIFT_W32(x, c) ((x) << (c))
+
+#define WEBRTC_SPL_RSHIFT_U32(x, c) ((uint32_t)(x) >> (c))
+
+#define WEBRTC_SPL_RAND(a) ((int16_t)((((int16_t)a * 18816) >> 7) & 0x00007fff))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WEBRTC_SPL_MEMCPY_W16(v1, v2, length) \
+ memcpy(v1, v2, (length) * sizeof(int16_t))
+
+// inline functions:
+#include "webrtc/common_audio/signal_processing/include/spl_inl.h"
+
+// third party math functions
+#include "webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h"
+
+// Initialize SPL. Currently it contains only function pointer initialization.
+// If the underlying platform is known to be ARM-Neon (WEBRTC_HAS_NEON defined),
+// the pointers will be assigned to code optimized for Neon; otherwise, generic
+// C code will be assigned.
+// Note that this function MUST be called in any application that uses SPL
+// functions.
+void WebRtcSpl_Init(void);
+
+int16_t WebRtcSpl_GetScalingSquare(int16_t* in_vector,
+ size_t in_vector_length,
+ size_t times);
+
+// Copy and set operations. Implementation in copy_set_operations.c.
+// Descriptions at bottom of file.
+void WebRtcSpl_MemSetW16(int16_t* vector,
+ int16_t set_value,
+ size_t vector_length);
+void WebRtcSpl_MemSetW32(int32_t* vector,
+ int32_t set_value,
+ size_t vector_length);
+void WebRtcSpl_MemCpyReversedOrder(int16_t* out_vector,
+ int16_t* in_vector,
+ size_t vector_length);
+void WebRtcSpl_CopyFromEndW16(const int16_t* in_vector,
+ size_t in_vector_length,
+ size_t samples,
+ int16_t* out_vector);
+void WebRtcSpl_ZerosArrayW16(int16_t* vector, size_t vector_length);
+void WebRtcSpl_ZerosArrayW32(int32_t* vector, size_t vector_length);
+// End: Copy and set operations.
+
+// Minimum and maximum operation functions and their pointers.
+// Implementation in min_max_operations.c.
+
+// Returns the largest absolute value in a signed 16-bit vector.
+//
+// Input:
+// - vector : 16-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Maximum absolute value in vector.
+typedef int16_t (*MaxAbsValueW16)(const int16_t* vector, size_t length);
+extern MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16;
+int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, size_t length);
+#if defined(WEBRTC_HAS_NEON)
+int16_t WebRtcSpl_MaxAbsValueW16Neon(const int16_t* vector, size_t length);
+#endif
+#if defined(MIPS32_LE)
+int16_t WebRtcSpl_MaxAbsValueW16_mips(const int16_t* vector, size_t length);
+#endif
+
+// Returns the largest absolute value in a signed 32-bit vector.
+//
+// Input:
+// - vector : 32-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Maximum absolute value in vector.
+typedef int32_t (*MaxAbsValueW32)(const int32_t* vector, size_t length);
+extern MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32;
+int32_t WebRtcSpl_MaxAbsValueW32C(const int32_t* vector, size_t length);
+#if defined(WEBRTC_HAS_NEON)
+int32_t WebRtcSpl_MaxAbsValueW32Neon(const int32_t* vector, size_t length);
+#endif
+#if defined(MIPS_DSP_R1_LE)
+int32_t WebRtcSpl_MaxAbsValueW32_mips(const int32_t* vector, size_t length);
+#endif
+
+// Returns the maximum value of a 16-bit vector.
+//
+// Input:
+// - vector : 16-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Maximum sample value in |vector|.
+typedef int16_t (*MaxValueW16)(const int16_t* vector, size_t length);
+extern MaxValueW16 WebRtcSpl_MaxValueW16;
+int16_t WebRtcSpl_MaxValueW16C(const int16_t* vector, size_t length);
+#if defined(WEBRTC_HAS_NEON)
+int16_t WebRtcSpl_MaxValueW16Neon(const int16_t* vector, size_t length);
+#endif
+#if defined(MIPS32_LE)
+int16_t WebRtcSpl_MaxValueW16_mips(const int16_t* vector, size_t length);
+#endif
+
+// Returns the maximum value of a 32-bit vector.
+//
+// Input:
+// - vector : 32-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Maximum sample value in |vector|.
+typedef int32_t (*MaxValueW32)(const int32_t* vector, size_t length);
+extern MaxValueW32 WebRtcSpl_MaxValueW32;
+int32_t WebRtcSpl_MaxValueW32C(const int32_t* vector, size_t length);
+#if defined(WEBRTC_HAS_NEON)
+int32_t WebRtcSpl_MaxValueW32Neon(const int32_t* vector, size_t length);
+#endif
+#if defined(MIPS32_LE)
+int32_t WebRtcSpl_MaxValueW32_mips(const int32_t* vector, size_t length);
+#endif
+
+// Returns the minimum value of a 16-bit vector.
+//
+// Input:
+// - vector : 16-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Minimum sample value in |vector|.
+typedef int16_t (*MinValueW16)(const int16_t* vector, size_t length);
+extern MinValueW16 WebRtcSpl_MinValueW16;
+int16_t WebRtcSpl_MinValueW16C(const int16_t* vector, size_t length);
+#if defined(WEBRTC_HAS_NEON)
+int16_t WebRtcSpl_MinValueW16Neon(const int16_t* vector, size_t length);
+#endif
+#if defined(MIPS32_LE)
+int16_t WebRtcSpl_MinValueW16_mips(const int16_t* vector, size_t length);
+#endif
+
+// Returns the minimum value of a 32-bit vector.
+//
+// Input:
+// - vector : 32-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Minimum sample value in |vector|.
+typedef int32_t (*MinValueW32)(const int32_t* vector, size_t length);
+extern MinValueW32 WebRtcSpl_MinValueW32;
+int32_t WebRtcSpl_MinValueW32C(const int32_t* vector, size_t length);
+#if defined(WEBRTC_HAS_NEON)
+int32_t WebRtcSpl_MinValueW32Neon(const int32_t* vector, size_t length);
+#endif
+#if defined(MIPS32_LE)
+int32_t WebRtcSpl_MinValueW32_mips(const int32_t* vector, size_t length);
+#endif
+
+// Returns the vector index to the largest absolute value of a 16-bit vector.
+//
+// Input:
+// - vector : 16-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Index to the maximum absolute value in vector.
+// If there are multiple equal maxima, return the index of the
+// first. -32768 will always have precedence over 32767 (despite
+// -32768 presenting an int16 absolute value of 32767).
+size_t WebRtcSpl_MaxAbsIndexW16(const int16_t* vector, size_t length);
+
+// Returns the vector index to the maximum sample value of a 16-bit vector.
+//
+// Input:
+// - vector : 16-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Index to the maximum value in vector (if multiple
+// indexes have the maximum, return the first).
+size_t WebRtcSpl_MaxIndexW16(const int16_t* vector, size_t length);
+
+// Returns the vector index to the maximum sample value of a 32-bit vector.
+//
+// Input:
+// - vector : 32-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Index to the maximum value in vector (if multiple
+// indexes have the maximum, return the first).
+size_t WebRtcSpl_MaxIndexW32(const int32_t* vector, size_t length);
+
+// Returns the vector index to the minimum sample value of a 16-bit vector.
+//
+// Input:
+// - vector : 16-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Index to the mimimum value in vector (if multiple
+// indexes have the minimum, return the first).
+size_t WebRtcSpl_MinIndexW16(const int16_t* vector, size_t length);
+
+// Returns the vector index to the minimum sample value of a 32-bit vector.
+//
+// Input:
+// - vector : 32-bit input vector.
+// - length : Number of samples in vector.
+//
+// Return value : Index to the mimimum value in vector (if multiple
+// indexes have the minimum, return the first).
+size_t WebRtcSpl_MinIndexW32(const int32_t* vector, size_t length);
+
+// End: Minimum and maximum operations.
+
+// Vector scaling operations. Implementation in vector_scaling_operations.c.
+// Description at bottom of file.
+void WebRtcSpl_VectorBitShiftW16(int16_t* out_vector,
+ size_t vector_length,
+ const int16_t* in_vector,
+ int16_t right_shifts);
+void WebRtcSpl_VectorBitShiftW32(int32_t* out_vector,
+ size_t vector_length,
+ const int32_t* in_vector,
+ int16_t right_shifts);
+void WebRtcSpl_VectorBitShiftW32ToW16(int16_t* out_vector,
+ size_t vector_length,
+ const int32_t* in_vector,
+ int right_shifts);
+void WebRtcSpl_ScaleVector(const int16_t* in_vector,
+ int16_t* out_vector,
+ int16_t gain,
+ size_t vector_length,
+ int16_t right_shifts);
+void WebRtcSpl_ScaleVectorWithSat(const int16_t* in_vector,
+ int16_t* out_vector,
+ int16_t gain,
+ size_t vector_length,
+ int16_t right_shifts);
+void WebRtcSpl_ScaleAndAddVectors(const int16_t* in_vector1,
+ int16_t gain1,
+ int right_shifts1,
+ const int16_t* in_vector2,
+ int16_t gain2,
+ int right_shifts2,
+ int16_t* out_vector,
+ size_t vector_length);
+
+// The functions (with related pointer) perform the vector operation:
+// out_vector[k] = ((scale1 * in_vector1[k]) + (scale2 * in_vector2[k])
+// + round_value) >> right_shifts,
+// where round_value = (1 << right_shifts) >> 1.
+//
+// Input:
+// - in_vector1 : Input vector 1
+// - in_vector1_scale : Gain to be used for vector 1
+// - in_vector2 : Input vector 2
+// - in_vector2_scale : Gain to be used for vector 2
+// - right_shifts : Number of right bit shifts to be applied
+// - length : Number of elements in the input vectors
+//
+// Output:
+// - out_vector : Output vector
+// Return value : 0 if OK, -1 if (in_vector1 == null
+// || in_vector2 == null || out_vector == null
+// || length <= 0 || right_shift < 0).
+typedef int (*ScaleAndAddVectorsWithRound)(const int16_t* in_vector1,
+ int16_t in_vector1_scale,
+ const int16_t* in_vector2,
+ int16_t in_vector2_scale,
+ int right_shifts,
+ int16_t* out_vector,
+ size_t length);
+extern ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound;
+int WebRtcSpl_ScaleAndAddVectorsWithRoundC(const int16_t* in_vector1,
+ int16_t in_vector1_scale,
+ const int16_t* in_vector2,
+ int16_t in_vector2_scale,
+ int right_shifts,
+ int16_t* out_vector,
+ size_t length);
+#if defined(MIPS_DSP_R1_LE)
+int WebRtcSpl_ScaleAndAddVectorsWithRound_mips(const int16_t* in_vector1,
+ int16_t in_vector1_scale,
+ const int16_t* in_vector2,
+ int16_t in_vector2_scale,
+ int right_shifts,
+ int16_t* out_vector,
+ size_t length);
+#endif
+// End: Vector scaling operations.
+
+// iLBC specific functions. Implementations in ilbc_specific_functions.c.
+// Description at bottom of file.
+void WebRtcSpl_ReverseOrderMultArrayElements(int16_t* out_vector,
+ const int16_t* in_vector,
+ const int16_t* window,
+ size_t vector_length,
+ int16_t right_shifts);
+void WebRtcSpl_ElementwiseVectorMult(int16_t* out_vector,
+ const int16_t* in_vector,
+ const int16_t* window,
+ size_t vector_length,
+ int16_t right_shifts);
+void WebRtcSpl_AddVectorsAndShift(int16_t* out_vector,
+ const int16_t* in_vector1,
+ const int16_t* in_vector2,
+ size_t vector_length,
+ int16_t right_shifts);
+void WebRtcSpl_AddAffineVectorToVector(int16_t* out_vector,
+ int16_t* in_vector,
+ int16_t gain,
+ int32_t add_constant,
+ int16_t right_shifts,
+ size_t vector_length);
+void WebRtcSpl_AffineTransformVector(int16_t* out_vector,
+ int16_t* in_vector,
+ int16_t gain,
+ int32_t add_constant,
+ int16_t right_shifts,
+ size_t vector_length);
+// End: iLBC specific functions.
+
+// Signal processing operations.
+
+// A 32-bit fix-point implementation of auto-correlation computation
+//
+// Input:
+// - in_vector : Vector to calculate autocorrelation upon
+// - in_vector_length : Length (in samples) of |vector|
+// - order : The order up to which the autocorrelation should be
+// calculated
+//
+// Output:
+// - result : auto-correlation values (values should be seen
+// relative to each other since the absolute values
+// might have been down shifted to avoid overflow)
+//
+// - scale : The number of left shifts required to obtain the
+// auto-correlation in Q0
+//
+// Return value : Number of samples in |result|, i.e. (order+1)
+size_t WebRtcSpl_AutoCorrelation(const int16_t* in_vector,
+ size_t in_vector_length,
+ size_t order,
+ int32_t* result,
+ int* scale);
+
+// A 32-bit fix-point implementation of the Levinson-Durbin algorithm that
+// does NOT use the 64 bit class
+//
+// Input:
+// - auto_corr : Vector with autocorrelation values of length >= |order|+1
+// - order : The LPC filter order (support up to order 20)
+//
+// Output:
+// - lpc_coef : lpc_coef[0..order] LPC coefficients in Q12
+// - refl_coef : refl_coef[0...order-1]| Reflection coefficients in Q15
+//
+// Return value : 1 for stable 0 for unstable
+int16_t WebRtcSpl_LevinsonDurbin(const int32_t* auto_corr,
+ int16_t* lpc_coef,
+ int16_t* refl_coef,
+ size_t order);
+
+// Converts reflection coefficients |refl_coef| to LPC coefficients |lpc_coef|.
+// This version is a 16 bit operation.
+//
+// NOTE: The 16 bit refl_coef -> lpc_coef conversion might result in a
+// "slightly unstable" filter (i.e., a pole just outside the unit circle) in
+// "rare" cases even if the reflection coefficients are stable.
+//
+// Input:
+// - refl_coef : Reflection coefficients in Q15 that should be converted
+// to LPC coefficients
+// - use_order : Number of coefficients in |refl_coef|
+//
+// Output:
+// - lpc_coef : LPC coefficients in Q12
+void WebRtcSpl_ReflCoefToLpc(const int16_t* refl_coef,
+ int use_order,
+ int16_t* lpc_coef);
+
+// Converts LPC coefficients |lpc_coef| to reflection coefficients |refl_coef|.
+// This version is a 16 bit operation.
+// The conversion is implemented by the step-down algorithm.
+//
+// Input:
+// - lpc_coef : LPC coefficients in Q12, that should be converted to
+// reflection coefficients
+// - use_order : Number of coefficients in |lpc_coef|
+//
+// Output:
+// - refl_coef : Reflection coefficients in Q15.
+void WebRtcSpl_LpcToReflCoef(int16_t* lpc_coef,
+ int use_order,
+ int16_t* refl_coef);
+
+// Calculates reflection coefficients (16 bit) from auto-correlation values
+//
+// Input:
+// - auto_corr : Auto-correlation values
+// - use_order : Number of coefficients wanted be calculated
+//
+// Output:
+// - refl_coef : Reflection coefficients in Q15.
+void WebRtcSpl_AutoCorrToReflCoef(const int32_t* auto_corr,
+ int use_order,
+ int16_t* refl_coef);
+
+// The functions (with related pointer) calculate the cross-correlation between
+// two sequences |seq1| and |seq2|.
+// |seq1| is fixed and |seq2| slides as the pointer is increased with the
+// amount |step_seq2|. Note the arguments should obey the relationship:
+// |dim_seq| - 1 + |step_seq2| * (|dim_cross_correlation| - 1) <
+// buffer size of |seq2|
+//
+// Input:
+// - seq1 : First sequence (fixed throughout the correlation)
+// - seq2 : Second sequence (slides |step_vector2| for each
+// new correlation)
+// - dim_seq : Number of samples to use in the cross-correlation
+// - dim_cross_correlation : Number of cross-correlations to calculate (the
+// start position for |vector2| is updated for each
+// new one)
+// - right_shifts : Number of right bit shifts to use. This will
+// become the output Q-domain.
+// - step_seq2 : How many (positive or negative) steps the
+// |vector2| pointer should be updated for each new
+// cross-correlation value.
+//
+// Output:
+// - cross_correlation : The cross-correlation in Q(-right_shifts)
+typedef void (*CrossCorrelation)(int32_t* cross_correlation,
+ const int16_t* seq1,
+ const int16_t* seq2,
+ size_t dim_seq,
+ size_t dim_cross_correlation,
+ int right_shifts,
+ int step_seq2);
+extern CrossCorrelation WebRtcSpl_CrossCorrelation;
+void WebRtcSpl_CrossCorrelationC(int32_t* cross_correlation,
+ const int16_t* seq1,
+ const int16_t* seq2,
+ size_t dim_seq,
+ size_t dim_cross_correlation,
+ int right_shifts,
+ int step_seq2);
+#if defined(WEBRTC_HAS_NEON)
+void WebRtcSpl_CrossCorrelationNeon(int32_t* cross_correlation,
+ const int16_t* seq1,
+ const int16_t* seq2,
+ size_t dim_seq,
+ size_t dim_cross_correlation,
+ int right_shifts,
+ int step_seq2);
+#endif
+#if defined(MIPS32_LE)
+void WebRtcSpl_CrossCorrelation_mips(int32_t* cross_correlation,
+ const int16_t* seq1,
+ const int16_t* seq2,
+ size_t dim_seq,
+ size_t dim_cross_correlation,
+ int right_shifts,
+ int step_seq2);
+#endif
+
+// Creates (the first half of) a Hanning window. Size must be at least 1 and
+// at most 512.
+//
+// Input:
+// - size : Length of the requested Hanning window (1 to 512)
+//
+// Output:
+// - window : Hanning vector in Q14.
+void WebRtcSpl_GetHanningWindow(int16_t* window, size_t size);
+
+// Calculates y[k] = sqrt(1 - x[k]^2) for each element of the input vector
+// |in_vector|. Input and output values are in Q15.
+//
+// Inputs:
+// - in_vector : Values to calculate sqrt(1 - x^2) of
+// - vector_length : Length of vector |in_vector|
+//
+// Output:
+// - out_vector : Output values in Q15
+void WebRtcSpl_SqrtOfOneMinusXSquared(int16_t* in_vector,
+ size_t vector_length,
+ int16_t* out_vector);
+// End: Signal processing operations.
+
+// Randomization functions. Implementations collected in
+// randomization_functions.c and descriptions at bottom of this file.
+int16_t WebRtcSpl_RandU(uint32_t* seed);
+int16_t WebRtcSpl_RandN(uint32_t* seed);
+int16_t WebRtcSpl_RandUArray(int16_t* vector,
+ int16_t vector_length,
+ uint32_t* seed);
+// End: Randomization functions.
+
+// Math functions
+int32_t WebRtcSpl_Sqrt(int32_t value);
+
+// Divisions. Implementations collected in division_operations.c and
+// descriptions at bottom of this file.
+uint32_t WebRtcSpl_DivU32U16(uint32_t num, uint16_t den);
+int32_t WebRtcSpl_DivW32W16(int32_t num, int16_t den);
+int16_t WebRtcSpl_DivW32W16ResW16(int32_t num, int16_t den);
+int32_t WebRtcSpl_DivResultInQ31(int32_t num, int32_t den);
+int32_t WebRtcSpl_DivW32HiLow(int32_t num, int16_t den_hi, int16_t den_low);
+// End: Divisions.
+
+int32_t WebRtcSpl_Energy(int16_t* vector,
+ size_t vector_length,
+ int* scale_factor);
+
+// Filter operations.
+size_t WebRtcSpl_FilterAR(const int16_t* ar_coef,
+ size_t ar_coef_length,
+ const int16_t* in_vector,
+ size_t in_vector_length,
+ int16_t* filter_state,
+ size_t filter_state_length,
+ int16_t* filter_state_low,
+ size_t filter_state_low_length,
+ int16_t* out_vector,
+ int16_t* out_vector_low,
+ size_t out_vector_low_length);
+
+// WebRtcSpl_FilterMAFastQ12(...)
+//
+// Performs a MA filtering on a vector in Q12
+//
+// Input:
+// - in_vector : Input samples (state in positions
+// in_vector[-order] .. in_vector[-1])
+// - ma_coef : Filter coefficients (in Q12)
+// - ma_coef_length : Number of B coefficients (order+1)
+// - vector_length : Number of samples to be filtered
+//
+// Output:
+// - out_vector : Filtered samples
+//
+void WebRtcSpl_FilterMAFastQ12(const int16_t* in_vector,
+ int16_t* out_vector,
+ const int16_t* ma_coef,
+ size_t ma_coef_length,
+ size_t vector_length);
+
+// Performs a AR filtering on a vector in Q12
+// Input:
+// - data_in : Input samples
+// - data_out : State information in positions
+// data_out[-order] .. data_out[-1]
+// - coefficients : Filter coefficients (in Q12)
+// - coefficients_length: Number of coefficients (order+1)
+// - data_length : Number of samples to be filtered
+// Output:
+// - data_out : Filtered samples
+void WebRtcSpl_FilterARFastQ12(const int16_t* data_in,
+ int16_t* data_out,
+ const int16_t* __restrict coefficients,
+ size_t coefficients_length,
+ size_t data_length);
+
+// The functions (with related pointer) perform a MA down sampling filter
+// on a vector.
+// Input:
+// - data_in : Input samples (state in positions
+// data_in[-order] .. data_in[-1])
+// - data_in_length : Number of samples in |data_in| to be filtered.
+// This must be at least
+// |delay| + |factor|*(|out_vector_length|-1) + 1)
+// - data_out_length : Number of down sampled samples desired
+// - coefficients : Filter coefficients (in Q12)
+// - coefficients_length: Number of coefficients (order+1)
+// - factor : Decimation factor
+// - delay : Delay of filter (compensated for in out_vector)
+// Output:
+// - data_out : Filtered samples
+// Return value : 0 if OK, -1 if |in_vector| is too short
+typedef int (*DownsampleFast)(const int16_t* data_in,
+ size_t data_in_length,
+ int16_t* data_out,
+ size_t data_out_length,
+ const int16_t* __restrict coefficients,
+ size_t coefficients_length,
+ int factor,
+ size_t delay);
+extern DownsampleFast WebRtcSpl_DownsampleFast;
+int WebRtcSpl_DownsampleFastC(const int16_t* data_in,
+ size_t data_in_length,
+ int16_t* data_out,
+ size_t data_out_length,
+ const int16_t* __restrict coefficients,
+ size_t coefficients_length,
+ int factor,
+ size_t delay);
+#if defined(WEBRTC_HAS_NEON)
+int WebRtcSpl_DownsampleFastNeon(const int16_t* data_in,
+ size_t data_in_length,
+ int16_t* data_out,
+ size_t data_out_length,
+ const int16_t* __restrict coefficients,
+ size_t coefficients_length,
+ int factor,
+ size_t delay);
+#endif
+#if defined(MIPS32_LE)
+int WebRtcSpl_DownsampleFast_mips(const int16_t* data_in,
+ size_t data_in_length,
+ int16_t* data_out,
+ size_t data_out_length,
+ const int16_t* __restrict coefficients,
+ size_t coefficients_length,
+ int factor,
+ size_t delay);
+#endif
+
+// End: Filter operations.
+
+// FFT operations
+
+int WebRtcSpl_ComplexFFT(int16_t vector[], int stages, int mode);
+int WebRtcSpl_ComplexIFFT(int16_t vector[], int stages, int mode);
+
+// Treat a 16-bit complex data buffer |complex_data| as an array of 32-bit
+// values, and swap elements whose indexes are bit-reverses of each other.
+//
+// Input:
+// - complex_data : Complex data buffer containing 2^|stages| real
+// elements interleaved with 2^|stages| imaginary
+// elements: [Re Im Re Im Re Im....]
+// - stages : Number of FFT stages. Must be at least 3 and at most
+// 10, since the table WebRtcSpl_kSinTable1024[] is 1024
+// elements long.
+//
+// Output:
+// - complex_data : The complex data buffer.
+
+void WebRtcSpl_ComplexBitReverse(int16_t* __restrict complex_data, int stages);
+
+// End: FFT operations
+
+/************************************************************
+ *
+ * RESAMPLING FUNCTIONS AND THEIR STRUCTS ARE DEFINED BELOW
+ *
+ ************************************************************/
+
+/*******************************************************************
+ * resample.c
+ *
+ * Includes the following resampling combinations
+ * 22 kHz -> 16 kHz
+ * 16 kHz -> 22 kHz
+ * 22 kHz -> 8 kHz
+ * 8 kHz -> 22 kHz
+ *
+ ******************************************************************/
+
+// state structure for 22 -> 16 resampler
+typedef struct {
+ int32_t S_22_44[8];
+ int32_t S_44_32[8];
+ int32_t S_32_16[8];
+} WebRtcSpl_State22khzTo16khz;
+
+void WebRtcSpl_Resample22khzTo16khz(const int16_t* in,
+ int16_t* out,
+ WebRtcSpl_State22khzTo16khz* state,
+ int32_t* tmpmem);
+
+void WebRtcSpl_ResetResample22khzTo16khz(WebRtcSpl_State22khzTo16khz* state);
+
+// state structure for 16 -> 22 resampler
+typedef struct {
+ int32_t S_16_32[8];
+ int32_t S_32_22[8];
+} WebRtcSpl_State16khzTo22khz;
+
+void WebRtcSpl_Resample16khzTo22khz(const int16_t* in,
+ int16_t* out,
+ WebRtcSpl_State16khzTo22khz* state,
+ int32_t* tmpmem);
+
+void WebRtcSpl_ResetResample16khzTo22khz(WebRtcSpl_State16khzTo22khz* state);
+
+// state structure for 22 -> 8 resampler
+typedef struct {
+ int32_t S_22_22[16];
+ int32_t S_22_16[8];
+ int32_t S_16_8[8];
+} WebRtcSpl_State22khzTo8khz;
+
+void WebRtcSpl_Resample22khzTo8khz(const int16_t* in,
+ int16_t* out,
+ WebRtcSpl_State22khzTo8khz* state,
+ int32_t* tmpmem);
+
+void WebRtcSpl_ResetResample22khzTo8khz(WebRtcSpl_State22khzTo8khz* state);
+
+// state structure for 8 -> 22 resampler
+typedef struct {
+ int32_t S_8_16[8];
+ int32_t S_16_11[8];
+ int32_t S_11_22[8];
+} WebRtcSpl_State8khzTo22khz;
+
+void WebRtcSpl_Resample8khzTo22khz(const int16_t* in,
+ int16_t* out,
+ WebRtcSpl_State8khzTo22khz* state,
+ int32_t* tmpmem);
+
+void WebRtcSpl_ResetResample8khzTo22khz(WebRtcSpl_State8khzTo22khz* state);
+
+/*******************************************************************
+ * resample_fractional.c
+ * Functions for internal use in the other resample functions
+ *
+ * Includes the following resampling combinations
+ * 48 kHz -> 32 kHz
+ * 32 kHz -> 24 kHz
+ * 44 kHz -> 32 kHz
+ *
+ ******************************************************************/
+
+void WebRtcSpl_Resample48khzTo32khz(const int32_t* In, int32_t* Out, size_t K);
+
+void WebRtcSpl_Resample32khzTo24khz(const int32_t* In, int32_t* Out, size_t K);
+
+void WebRtcSpl_Resample44khzTo32khz(const int32_t* In, int32_t* Out, size_t K);
+
+/*******************************************************************
+ * resample_48khz.c
+ *
+ * Includes the following resampling combinations
+ * 48 kHz -> 16 kHz
+ * 16 kHz -> 48 kHz
+ * 48 kHz -> 8 kHz
+ * 8 kHz -> 48 kHz
+ *
+ ******************************************************************/
+
+typedef struct {
+ int32_t S_48_48[16];
+ int32_t S_48_32[8];
+ int32_t S_32_16[8];
+} WebRtcSpl_State48khzTo16khz;
+
+void WebRtcSpl_Resample48khzTo16khz(const int16_t* in,
+ int16_t* out,
+ WebRtcSpl_State48khzTo16khz* state,
+ int32_t* tmpmem);
+
+void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state);
+
+typedef struct {
+ int32_t S_16_32[8];
+ int32_t S_32_24[8];
+ int32_t S_24_48[8];
+} WebRtcSpl_State16khzTo48khz;
+
+void WebRtcSpl_Resample16khzTo48khz(const int16_t* in,
+ int16_t* out,
+ WebRtcSpl_State16khzTo48khz* state,
+ int32_t* tmpmem);
+
+void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state);
+
+typedef struct {
+ int32_t S_48_24[8];
+ int32_t S_24_24[16];
+ int32_t S_24_16[8];
+ int32_t S_16_8[8];
+} WebRtcSpl_State48khzTo8khz;
+
+void WebRtcSpl_Resample48khzTo8khz(const int16_t* in,
+ int16_t* out,
+ WebRtcSpl_State48khzTo8khz* state,
+ int32_t* tmpmem);
+
+void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state);
+
+typedef struct {
+ int32_t S_8_16[8];
+ int32_t S_16_12[8];
+ int32_t S_12_24[8];
+ int32_t S_24_48[8];
+} WebRtcSpl_State8khzTo48khz;
+
+void WebRtcSpl_Resample8khzTo48khz(const int16_t* in,
+ int16_t* out,
+ WebRtcSpl_State8khzTo48khz* state,
+ int32_t* tmpmem);
+
+void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state);
+
+/*******************************************************************
+ * resample_by_2.c
+ *
+ * Includes down and up sampling by a factor of two.
+ *
+ ******************************************************************/
+
+void WebRtcSpl_DownsampleBy2(const int16_t* in,
+ size_t len,
+ int16_t* out,
+ int32_t* filtState);
+
+void WebRtcSpl_UpsampleBy2(const int16_t* in,
+ size_t len,
+ int16_t* out,
+ int32_t* filtState);
+
+/************************************************************
+ * END OF RESAMPLING FUNCTIONS
+ ************************************************************/
+void WebRtcSpl_AnalysisQMF(const int16_t* in_data,
+ size_t in_data_length,
+ int16_t* low_band,
+ int16_t* high_band,
+ int32_t* filter_state1,
+ int32_t* filter_state2);
+void WebRtcSpl_SynthesisQMF(const int16_t* low_band,
+ const int16_t* high_band,
+ size_t band_length,
+ int16_t* out_data,
+ int32_t* filter_state1,
+ int32_t* filter_state2);
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SIGNAL_PROCESSING_LIBRARY_H_
+
+//
+// WebRtcSpl_AddSatW16(...)
+// WebRtcSpl_AddSatW32(...)
+//
+// Returns the result of a saturated 16-bit, respectively 32-bit, addition of
+// the numbers specified by the |var1| and |var2| parameters.
+//
+// Input:
+// - var1 : Input variable 1
+// - var2 : Input variable 2
+//
+// Return value : Added and saturated value
+//
+
+//
+// WebRtcSpl_SubSatW16(...)
+// WebRtcSpl_SubSatW32(...)
+//
+// Returns the result of a saturated 16-bit, respectively 32-bit, subtraction
+// of the numbers specified by the |var1| and |var2| parameters.
+//
+// Input:
+// - var1 : Input variable 1
+// - var2 : Input variable 2
+//
+// Returned value : Subtracted and saturated value
+//
+
+//
+// WebRtcSpl_GetSizeInBits(...)
+//
+// Returns the # of bits that are needed at the most to represent the number
+// specified by the |value| parameter.
+//
+// Input:
+// - value : Input value
+//
+// Return value : Number of bits needed to represent |value|
+//
+
+//
+// WebRtcSpl_NormW32(...)
+//
+// Norm returns the # of left shifts required to 32-bit normalize the 32-bit
+// signed number specified by the |value| parameter.
+//
+// Input:
+// - value : Input value
+//
+// Return value : Number of bit shifts needed to 32-bit normalize |value|
+//
+
+//
+// WebRtcSpl_NormW16(...)
+//
+// Norm returns the # of left shifts required to 16-bit normalize the 16-bit
+// signed number specified by the |value| parameter.
+//
+// Input:
+// - value : Input value
+//
+// Return value : Number of bit shifts needed to 32-bit normalize |value|
+//
+
+//
+// WebRtcSpl_NormU32(...)
+//
+// Norm returns the # of left shifts required to 32-bit normalize the unsigned
+// 32-bit number specified by the |value| parameter.
+//
+// Input:
+// - value : Input value
+//
+// Return value : Number of bit shifts needed to 32-bit normalize |value|
+//
+
+//
+// WebRtcSpl_GetScalingSquare(...)
+//
+// Returns the # of bits required to scale the samples specified in the
+// |in_vector| parameter so that, if the squares of the samples are added the
+// # of times specified by the |times| parameter, the 32-bit addition will not
+// overflow (result in int32_t).
+//
+// Input:
+// - in_vector : Input vector to check scaling on
+// - in_vector_length : Samples in |in_vector|
+// - times : Number of additions to be performed
+//
+// Return value : Number of right bit shifts needed to avoid
+// overflow in the addition calculation
+//
+
+//
+// WebRtcSpl_MemSetW16(...)
+//
+// Sets all the values in the int16_t vector |vector| of length
+// |vector_length| to the specified value |set_value|
+//
+// Input:
+// - vector : Pointer to the int16_t vector
+// - set_value : Value specified
+// - vector_length : Length of vector
+//
+
+//
+// WebRtcSpl_MemSetW32(...)
+//
+// Sets all the values in the int32_t vector |vector| of length
+// |vector_length| to the specified value |set_value|
+//
+// Input:
+// - vector : Pointer to the int16_t vector
+// - set_value : Value specified
+// - vector_length : Length of vector
+//
+
+//
+// WebRtcSpl_MemCpyReversedOrder(...)
+//
+// Copies all the values from the source int16_t vector |in_vector| to a
+// destination int16_t vector |out_vector|. It is done in reversed order,
+// meaning that the first sample of |in_vector| is copied to the last sample of
+// the |out_vector|. The procedure continues until the last sample of
+// |in_vector| has been copied to the first sample of |out_vector|. This
+// creates a reversed vector. Used in e.g. prediction in iLBC.
+//
+// Input:
+// - in_vector : Pointer to the first sample in a int16_t vector
+// of length |length|
+// - vector_length : Number of elements to copy
+//
+// Output:
+// - out_vector : Pointer to the last sample in a int16_t vector
+// of length |length|
+//
+
+//
+// WebRtcSpl_CopyFromEndW16(...)
+//
+// Copies the rightmost |samples| of |in_vector| (of length |in_vector_length|)
+// to the vector |out_vector|.
+//
+// Input:
+// - in_vector : Input vector
+// - in_vector_length : Number of samples in |in_vector|
+// - samples : Number of samples to extract (from right side)
+// from |in_vector|
+//
+// Output:
+// - out_vector : Vector with the requested samples
+//
+
+//
+// WebRtcSpl_ZerosArrayW16(...)
+// WebRtcSpl_ZerosArrayW32(...)
+//
+// Inserts the value "zero" in all positions of a w16 and a w32 vector
+// respectively.
+//
+// Input:
+// - vector_length : Number of samples in vector
+//
+// Output:
+// - vector : Vector containing all zeros
+//
+
+//
+// WebRtcSpl_VectorBitShiftW16(...)
+// WebRtcSpl_VectorBitShiftW32(...)
+//
+// Bit shifts all the values in a vector up or downwards. Different calls for
+// int16_t and int32_t vectors respectively.
+//
+// Input:
+// - vector_length : Length of vector
+// - in_vector : Pointer to the vector that should be bit shifted
+// - right_shifts : Number of right bit shifts (negative value gives left
+// shifts)
+//
+// Output:
+// - out_vector : Pointer to the result vector (can be the same as
+// |in_vector|)
+//
+
+//
+// WebRtcSpl_VectorBitShiftW32ToW16(...)
+//
+// Bit shifts all the values in a int32_t vector up or downwards and
+// stores the result as an int16_t vector. The function will saturate the
+// signal if needed, before storing in the output vector.
+//
+// Input:
+// - vector_length : Length of vector
+// - in_vector : Pointer to the vector that should be bit shifted
+// - right_shifts : Number of right bit shifts (negative value gives left
+// shifts)
+//
+// Output:
+// - out_vector : Pointer to the result vector (can be the same as
+// |in_vector|)
+//
+
+//
+// WebRtcSpl_ScaleVector(...)
+//
+// Performs the vector operation:
+// out_vector[k] = (gain*in_vector[k])>>right_shifts
+//
+// Input:
+// - in_vector : Input vector
+// - gain : Scaling gain
+// - vector_length : Elements in the |in_vector|
+// - right_shifts : Number of right bit shifts applied
+//
+// Output:
+// - out_vector : Output vector (can be the same as |in_vector|)
+//
+
+//
+// WebRtcSpl_ScaleVectorWithSat(...)
+//
+// Performs the vector operation:
+// out_vector[k] = SATURATE( (gain*in_vector[k])>>right_shifts )
+//
+// Input:
+// - in_vector : Input vector
+// - gain : Scaling gain
+// - vector_length : Elements in the |in_vector|
+// - right_shifts : Number of right bit shifts applied
+//
+// Output:
+// - out_vector : Output vector (can be the same as |in_vector|)
+//
+
+//
+// WebRtcSpl_ScaleAndAddVectors(...)
+//
+// Performs the vector operation:
+// out_vector[k] = (gain1*in_vector1[k])>>right_shifts1
+// + (gain2*in_vector2[k])>>right_shifts2
+//
+// Input:
+// - in_vector1 : Input vector 1
+// - gain1 : Gain to be used for vector 1
+// - right_shifts1 : Right bit shift to be used for vector 1
+// - in_vector2 : Input vector 2
+// - gain2 : Gain to be used for vector 2
+// - right_shifts2 : Right bit shift to be used for vector 2
+// - vector_length : Elements in the input vectors
+//
+// Output:
+// - out_vector : Output vector
+//
+
+//
+// WebRtcSpl_ReverseOrderMultArrayElements(...)
+//
+// Performs the vector operation:
+// out_vector[n] = (in_vector[n]*window[-n])>>right_shifts
+//
+// Input:
+// - in_vector : Input vector
+// - window : Window vector (should be reversed). The pointer
+// should be set to the last value in the vector
+// - right_shifts : Number of right bit shift to be applied after the
+// multiplication
+// - vector_length : Number of elements in |in_vector|
+//
+// Output:
+// - out_vector : Output vector (can be same as |in_vector|)
+//
+
+//
+// WebRtcSpl_ElementwiseVectorMult(...)
+//
+// Performs the vector operation:
+// out_vector[n] = (in_vector[n]*window[n])>>right_shifts
+//
+// Input:
+// - in_vector : Input vector
+// - window : Window vector.
+// - right_shifts : Number of right bit shift to be applied after the
+// multiplication
+// - vector_length : Number of elements in |in_vector|
+//
+// Output:
+// - out_vector : Output vector (can be same as |in_vector|)
+//
+
+//
+// WebRtcSpl_AddVectorsAndShift(...)
+//
+// Performs the vector operation:
+// out_vector[k] = (in_vector1[k] + in_vector2[k])>>right_shifts
+//
+// Input:
+// - in_vector1 : Input vector 1
+// - in_vector2 : Input vector 2
+// - right_shifts : Number of right bit shift to be applied after the
+// multiplication
+// - vector_length : Number of elements in |in_vector1| and |in_vector2|
+//
+// Output:
+// - out_vector : Output vector (can be same as |in_vector1|)
+//
+
+//
+// WebRtcSpl_AddAffineVectorToVector(...)
+//
+// Adds an affine transformed vector to another vector |out_vector|, i.e,
+// performs
+// out_vector[k] += (in_vector[k]*gain+add_constant)>>right_shifts
+//
+// Input:
+// - in_vector : Input vector
+// - gain : Gain value, used to multiply the in vector with
+// - add_constant : Constant value to add (usually 1<<(right_shifts-1),
+// but others can be used as well
+// - right_shifts : Number of right bit shifts (0-16)
+// - vector_length : Number of samples in |in_vector| and |out_vector|
+//
+// Output:
+// - out_vector : Vector with the output
+//
+
+//
+// WebRtcSpl_AffineTransformVector(...)
+//
+// Affine transforms a vector, i.e, performs
+// out_vector[k] = (in_vector[k]*gain+add_constant)>>right_shifts
+//
+// Input:
+// - in_vector : Input vector
+// - gain : Gain value, used to multiply the in vector with
+// - add_constant : Constant value to add (usually 1<<(right_shifts-1),
+// but others can be used as well
+// - right_shifts : Number of right bit shifts (0-16)
+// - vector_length : Number of samples in |in_vector| and |out_vector|
+//
+// Output:
+// - out_vector : Vector with the output
+//
+
+//
+// WebRtcSpl_IncreaseSeed(...)
+//
+// Increases the seed (and returns the new value)
+//
+// Input:
+// - seed : Seed for random calculation
+//
+// Output:
+// - seed : Updated seed value
+//
+// Return value : The new seed value
+//
+
+//
+// WebRtcSpl_RandU(...)
+//
+// Produces a uniformly distributed value in the int16_t range
+//
+// Input:
+// - seed : Seed for random calculation
+//
+// Output:
+// - seed : Updated seed value
+//
+// Return value : Uniformly distributed value in the range
+// [Word16_MIN...Word16_MAX]
+//
+
+//
+// WebRtcSpl_RandN(...)
+//
+// Produces a normal distributed value in the int16_t range
+//
+// Input:
+// - seed : Seed for random calculation
+//
+// Output:
+// - seed : Updated seed value
+//
+// Return value : N(0,1) value in the Q13 domain
+//
+
+//
+// WebRtcSpl_RandUArray(...)
+//
+// Produces a uniformly distributed vector with elements in the int16_t
+// range
+//
+// Input:
+// - vector_length : Samples wanted in the vector
+// - seed : Seed for random calculation
+//
+// Output:
+// - vector : Vector with the uniform values
+// - seed : Updated seed value
+//
+// Return value : Number of samples in vector, i.e., |vector_length|
+//
+
+//
+// WebRtcSpl_Sqrt(...)
+//
+// Returns the square root of the input value |value|. The precision of this
+// function is integer precision, i.e., sqrt(8) gives 2 as answer.
+// If |value| is a negative number then 0 is returned.
+//
+// Algorithm:
+//
+// A sixth order Taylor Series expansion is used here to compute the square
+// root of a number y^0.5 = (1+x)^0.5
+// where
+// x = y-1
+// = 1+(x/2)-0.5*((x/2)^2+0.5*((x/2)^3-0.625*((x/2)^4+0.875*((x/2)^5)
+// 0.5 <= x < 1
+//
+// Input:
+// - value : Value to calculate sqrt of
+//
+// Return value : Result of the sqrt calculation
+//
+
+//
+// WebRtcSpl_DivU32U16(...)
+//
+// Divides a uint32_t |num| by a uint16_t |den|.
+//
+// If |den|==0, (uint32_t)0xFFFFFFFF is returned.
+//
+// Input:
+// - num : Numerator
+// - den : Denominator
+//
+// Return value : Result of the division (as a uint32_t), i.e., the
+// integer part of num/den.
+//
+
+//
+// WebRtcSpl_DivW32W16(...)
+//
+// Divides a int32_t |num| by a int16_t |den|.
+//
+// If |den|==0, (int32_t)0x7FFFFFFF is returned.
+//
+// Input:
+// - num : Numerator
+// - den : Denominator
+//
+// Return value : Result of the division (as a int32_t), i.e., the
+// integer part of num/den.
+//
+
+//
+// WebRtcSpl_DivW32W16ResW16(...)
+//
+// Divides a int32_t |num| by a int16_t |den|, assuming that the
+// result is less than 32768, otherwise an unpredictable result will occur.
+//
+// If |den|==0, (int16_t)0x7FFF is returned.
+//
+// Input:
+// - num : Numerator
+// - den : Denominator
+//
+// Return value : Result of the division (as a int16_t), i.e., the
+// integer part of num/den.
+//
+
+//
+// WebRtcSpl_DivResultInQ31(...)
+//
+// Divides a int32_t |num| by a int16_t |den|, assuming that the
+// absolute value of the denominator is larger than the numerator, otherwise
+// an unpredictable result will occur.
+//
+// Input:
+// - num : Numerator
+// - den : Denominator
+//
+// Return value : Result of the division in Q31.
+//
+
+//
+// WebRtcSpl_DivW32HiLow(...)
+//
+// Divides a int32_t |num| by a denominator in hi, low format. The
+// absolute value of the denominator has to be larger (or equal to) the
+// numerator.
+//
+// Input:
+// - num : Numerator
+// - den_hi : High part of denominator
+// - den_low : Low part of denominator
+//
+// Return value : Divided value in Q31
+//
+
+//
+// WebRtcSpl_Energy(...)
+//
+// Calculates the energy of a vector
+//
+// Input:
+// - vector : Vector which the energy should be calculated on
+// - vector_length : Number of samples in vector
+//
+// Output:
+// - scale_factor : Number of left bit shifts needed to get the physical
+// energy value, i.e, to get the Q0 value
+//
+// Return value : Energy value in Q(-|scale_factor|)
+//
+
+//
+// WebRtcSpl_FilterAR(...)
+//
+// Performs a 32-bit AR filtering on a vector in Q12
+//
+// Input:
+// - ar_coef : AR-coefficient vector (values in Q12),
+// ar_coef[0] must be 4096.
+// - ar_coef_length : Number of coefficients in |ar_coef|.
+// - in_vector : Vector to be filtered.
+// - in_vector_length : Number of samples in |in_vector|.
+// - filter_state : Current state (higher part) of the filter.
+// - filter_state_length : Length (in samples) of |filter_state|.
+// - filter_state_low : Current state (lower part) of the filter.
+// - filter_state_low_length : Length (in samples) of |filter_state_low|.
+// - out_vector_low_length : Maximum length (in samples) of
+// |out_vector_low|.
+//
+// Output:
+// - filter_state : Updated state (upper part) vector.
+// - filter_state_low : Updated state (lower part) vector.
+// - out_vector : Vector containing the upper part of the
+// filtered values.
+// - out_vector_low : Vector containing the lower part of the
+// filtered values.
+//
+// Return value : Number of samples in the |out_vector|.
+//
+
+//
+// WebRtcSpl_ComplexIFFT(...)
+//
+// Complex Inverse FFT
+//
+// Computes an inverse complex 2^|stages|-point FFT on the input vector, which
+// is in bit-reversed order. The original content of the vector is destroyed in
+// the process, since the input is overwritten by the output, normal-ordered,
+// FFT vector. With X as the input complex vector, y as the output complex
+// vector and with M = 2^|stages|, the following is computed:
+//
+// M-1
+// y(k) = sum[X(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]]
+// i=0
+//
+// The implementations are optimized for speed, not for code size. It uses the
+// decimation-in-time algorithm with radix-2 butterfly technique.
+//
+// Input:
+// - vector : In pointer to complex vector containing 2^|stages|
+// real elements interleaved with 2^|stages| imaginary
+// elements.
+// [ReImReImReIm....]
+// The elements are in Q(-scale) domain, see more on Return
+// Value below.
+//
+// - stages : Number of FFT stages. Must be at least 3 and at most 10,
+// since the table WebRtcSpl_kSinTable1024[] is 1024
+// elements long.
+//
+// - mode : This parameter gives the user to choose how the FFT
+// should work.
+// mode==0: Low-complexity and Low-accuracy mode
+// mode==1: High-complexity and High-accuracy mode
+//
+// Output:
+// - vector : Out pointer to the FFT vector (the same as input).
+//
+// Return Value : The scale value that tells the number of left bit shifts
+// that the elements in the |vector| should be shifted with
+// in order to get Q0 values, i.e. the physically correct
+// values. The scale parameter is always 0 or positive,
+// except if N>1024 (|stages|>10), which returns a scale
+// value of -1, indicating error.
+//
+
+//
+// WebRtcSpl_ComplexFFT(...)
+//
+// Complex FFT
+//
+// Computes a complex 2^|stages|-point FFT on the input vector, which is in
+// bit-reversed order. The original content of the vector is destroyed in
+// the process, since the input is overwritten by the output, normal-ordered,
+// FFT vector. With x as the input complex vector, Y as the output complex
+// vector and with M = 2^|stages|, the following is computed:
+//
+// M-1
+// Y(k) = 1/M * sum[x(i)*[cos(2*pi*i*k/M) + j*sin(2*pi*i*k/M)]]
+// i=0
+//
+// The implementations are optimized for speed, not for code size. It uses the
+// decimation-in-time algorithm with radix-2 butterfly technique.
+//
+// This routine prevents overflow by scaling by 2 before each FFT stage. This is
+// a fixed scaling, for proper normalization - there will be log2(n) passes, so
+// this results in an overall factor of 1/n, distributed to maximize arithmetic
+// accuracy.
+//
+// Input:
+// - vector : In pointer to complex vector containing 2^|stages| real
+// elements interleaved with 2^|stages| imaginary elements.
+// [ReImReImReIm....]
+// The output is in the Q0 domain.
+//
+// - stages : Number of FFT stages. Must be at least 3 and at most 10,
+// since the table WebRtcSpl_kSinTable1024[] is 1024
+// elements long.
+//
+// - mode : This parameter gives the user to choose how the FFT
+// should work.
+// mode==0: Low-complexity and Low-accuracy mode
+// mode==1: High-complexity and High-accuracy mode
+//
+// Output:
+// - vector : The output FFT vector is in the Q0 domain.
+//
+// Return value : The scale parameter is always 0, except if N>1024,
+// which returns a scale value of -1, indicating error.
+//
+
+//
+// WebRtcSpl_AnalysisQMF(...)
+//
+// Splits a 0-2*F Hz signal into two sub bands: 0-F Hz and F-2*F Hz. The
+// current version has F = 8000, therefore, a super-wideband audio signal is
+// split to lower-band 0-8 kHz and upper-band 8-16 kHz.
+//
+// Input:
+// - in_data : Wide band speech signal, 320 samples (10 ms)
+//
+// Input & Output:
+// - filter_state1 : Filter state for first All-pass filter
+// - filter_state2 : Filter state for second All-pass filter
+//
+// Output:
+// - low_band : Lower-band signal 0-8 kHz band, 160 samples (10 ms)
+// - high_band : Upper-band signal 8-16 kHz band (flipped in frequency
+// domain), 160 samples (10 ms)
+//
+
+//
+// WebRtcSpl_SynthesisQMF(...)
+//
+// Combines the two sub bands (0-F and F-2*F Hz) into a signal of 0-2*F
+// Hz, (current version has F = 8000 Hz). So the filter combines lower-band
+// (0-8 kHz) and upper-band (8-16 kHz) channels to obtain super-wideband 0-16
+// kHz audio.
+//
+// Input:
+// - low_band : The signal with the 0-8 kHz band, 160 samples (10 ms)
+// - high_band : The signal with the 8-16 kHz band, 160 samples (10 ms)
+//
+// Input & Output:
+// - filter_state1 : Filter state for first All-pass filter
+// - filter_state2 : Filter state for second All-pass filter
+//
+// Output:
+// - out_data : Super-wideband speech signal, 0-16 kHz
+//
+
+// int16_t WebRtcSpl_SatW32ToW16(...)
+//
+// This function saturates a 32-bit word into a 16-bit word.
+//
+// Input:
+// - value32 : The value of a 32-bit word.
+//
+// Output:
+// - out16 : the saturated 16-bit word.
+//
+
+// int32_t WebRtc_MulAccumW16(...)
+//
+// This function multiply a 16-bit word by a 16-bit word, and accumulate this
+// value to a 32-bit integer.
+//
+// Input:
+// - a : The value of the first 16-bit word.
+// - b : The value of the second 16-bit word.
+// - c : The value of an 32-bit integer.
+//
+// Return Value: The value of a * b + c.
+//
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/spl_inl.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/spl_inl.h
new file mode 100644
index 0000000..d24b3a5
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/include/spl_inl.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This header file includes the inline functions in
+// the fix point signal processing library.
+
+#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_
+#define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_
+
+#include "webrtc/rtc_base/compile_assert_c.h"
+
+extern const int8_t kWebRtcSpl_CountLeadingZeros32_Table[64];
+
+// Don't call this directly except in tests!
+static __inline int WebRtcSpl_CountLeadingZeros32_NotBuiltin(uint32_t n) {
+ // Normalize n by rounding up to the nearest number that is a sequence of 0
+ // bits followed by a sequence of 1 bits. This number has the same number of
+ // leading zeros as the original n. There are exactly 33 such values.
+ n |= n >> 1;
+ n |= n >> 2;
+ n |= n >> 4;
+ n |= n >> 8;
+ n |= n >> 16;
+
+ // Multiply the modified n with a constant selected (by exhaustive search)
+ // such that each of the 33 possible values of n give a product whose 6 most
+ // significant bits are unique. Then look up the answer in the table.
+ return kWebRtcSpl_CountLeadingZeros32_Table[(n * 0x8c0b2891) >> 26];
+}
+
+// Don't call this directly except in tests!
+static __inline int WebRtcSpl_CountLeadingZeros64_NotBuiltin(uint64_t n) {
+ const int leading_zeros = n >> 32 == 0 ? 32 : 0;
+ return leading_zeros + WebRtcSpl_CountLeadingZeros32_NotBuiltin(
+ (uint32_t)(n >> (32 - leading_zeros)));
+}
+
+// Returns the number of leading zero bits in the argument.
+static __inline int WebRtcSpl_CountLeadingZeros32(uint32_t n) {
+#ifdef __GNUC__
+ RTC_COMPILE_ASSERT(sizeof(unsigned int) == sizeof(uint32_t));
+ return n == 0 ? 32 : __builtin_clz(n);
+#else
+ return WebRtcSpl_CountLeadingZeros32_NotBuiltin(n);
+#endif
+}
+
+// Returns the number of leading zero bits in the argument.
+static __inline int WebRtcSpl_CountLeadingZeros64(uint64_t n) {
+#ifdef __GNUC__
+ RTC_COMPILE_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t)); // NOLINT
+ return n == 0 ? 64 : __builtin_clzll(n);
+#else
+ return WebRtcSpl_CountLeadingZeros64_NotBuiltin(n);
+#endif
+}
+
+#ifdef WEBRTC_ARCH_ARM_V7
+#include "webrtc/common_audio/signal_processing/include/spl_inl_armv7.h"
+#else
+
+#if defined(MIPS32_LE)
+#include "webrtc/common_audio/signal_processing/include/spl_inl_mips.h"
+#endif
+
+#if !defined(MIPS_DSP_R1_LE)
+static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
+ int16_t out16 = (int16_t)value32;
+
+ if (value32 > 32767)
+ out16 = 32767;
+ else if (value32 < -32768)
+ out16 = -32768;
+
+ return out16;
+}
+
+static __inline int32_t WebRtcSpl_AddSatW32(int32_t a, int32_t b) {
+ // Do the addition in unsigned numbers, since signed overflow is undefined
+ // behavior.
+ const int32_t sum = (int32_t)((uint32_t)a + (uint32_t)b);
+
+ // a + b can't overflow if a and b have different signs. If they have the
+ // same sign, a + b also has the same sign iff it didn't overflow.
+ if ((a < 0) == (b < 0) && (a < 0) != (sum < 0)) {
+ // The direction of the overflow is obvious from the sign of a + b.
+ return sum < 0 ? INT32_MAX : INT32_MIN;
+ }
+ return sum;
+}
+
+static __inline int32_t WebRtcSpl_SubSatW32(int32_t a, int32_t b) {
+ // Do the subtraction in unsigned numbers, since signed overflow is undefined
+ // behavior.
+ const int32_t diff = (int32_t)((uint32_t)a - (uint32_t)b);
+
+ // a - b can't overflow if a and b have the same sign. If they have different
+ // signs, a - b has the same sign as a iff it didn't overflow.
+ if ((a < 0) != (b < 0) && (a < 0) != (diff < 0)) {
+ // The direction of the overflow is obvious from the sign of a - b.
+ return diff < 0 ? INT32_MAX : INT32_MIN;
+ }
+ return diff;
+}
+
+static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
+ return WebRtcSpl_SatW32ToW16((int32_t)a + (int32_t)b);
+}
+
+static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
+ return WebRtcSpl_SatW32ToW16((int32_t)var1 - (int32_t)var2);
+}
+#endif // #if !defined(MIPS_DSP_R1_LE)
+
+#if !defined(MIPS32_LE)
+static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
+ return 32 - WebRtcSpl_CountLeadingZeros32(n);
+}
+
+// Return the number of steps a can be left-shifted without overflow,
+// or 0 if a == 0.
+static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
+ return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a : a) - 1;
+}
+
+// Return the number of steps a can be left-shifted without overflow,
+// or 0 if a == 0.
+static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
+ return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a);
+}
+
+// Return the number of steps a can be left-shifted without overflow,
+// or 0 if a == 0.
+static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
+ const int32_t a32 = a;
+ return a == 0 ? 0 : WebRtcSpl_CountLeadingZeros32(a < 0 ? ~a32 : a32) - 17;
+}
+
+static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
+ return (a * b + c);
+}
+#endif // #if !defined(MIPS32_LE)
+
+#endif // WEBRTC_ARCH_ARM_V7
+
+#endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/min_max_operations.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/min_max_operations.c
new file mode 100644
index 0000000..75975bb
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/min_max_operations.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * This file contains the implementation of functions
+ * WebRtcSpl_MaxAbsValueW16C()
+ * WebRtcSpl_MaxAbsValueW32C()
+ * WebRtcSpl_MaxValueW16C()
+ * WebRtcSpl_MaxValueW32C()
+ * WebRtcSpl_MinValueW16C()
+ * WebRtcSpl_MinValueW32C()
+ * WebRtcSpl_MaxAbsIndexW16()
+ * WebRtcSpl_MaxIndexW16()
+ * WebRtcSpl_MaxIndexW32()
+ * WebRtcSpl_MinIndexW16()
+ * WebRtcSpl_MinIndexW32()
+ *
+ */
+
+#include <stdlib.h>
+
+#include "webrtc/rtc_base/checks.h"
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+// TODO(bjorn/kma): Consolidate function pairs (e.g. combine
+// WebRtcSpl_MaxAbsValueW16C and WebRtcSpl_MaxAbsIndexW16 into a single one.)
+// TODO(kma): Move the next six functions into min_max_operations_c.c.
+
+// Maximum absolute value of word16 vector. C version for generic platforms.
+int16_t WebRtcSpl_MaxAbsValueW16C(const int16_t* vector, size_t length) {
+ size_t i = 0;
+ int absolute = 0, maximum = 0;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ absolute = abs((int)vector[i]);
+
+ if (absolute > maximum) {
+ maximum = absolute;
+ }
+ }
+
+ // Guard the case for abs(-32768).
+ if (maximum > WEBRTC_SPL_WORD16_MAX) {
+ maximum = WEBRTC_SPL_WORD16_MAX;
+ }
+
+ return (int16_t)maximum;
+}
+
+// Maximum absolute value of word32 vector. C version for generic platforms.
+int32_t WebRtcSpl_MaxAbsValueW32C(const int32_t* vector, size_t length) {
+ // Use uint32_t for the local variables, to accommodate the return value
+ // of abs(0x80000000), which is 0x80000000.
+
+ uint32_t absolute = 0, maximum = 0;
+ size_t i = 0;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ absolute = abs((int)vector[i]);
+ if (absolute > maximum) {
+ maximum = absolute;
+ }
+ }
+
+ maximum = WEBRTC_SPL_MIN(maximum, WEBRTC_SPL_WORD32_MAX);
+
+ return (int32_t)maximum;
+}
+
+// Maximum value of word16 vector. C version for generic platforms.
+int16_t WebRtcSpl_MaxValueW16C(const int16_t* vector, size_t length) {
+ int16_t maximum = WEBRTC_SPL_WORD16_MIN;
+ size_t i = 0;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ if (vector[i] > maximum)
+ maximum = vector[i];
+ }
+ return maximum;
+}
+
+// Maximum value of word32 vector. C version for generic platforms.
+int32_t WebRtcSpl_MaxValueW32C(const int32_t* vector, size_t length) {
+ int32_t maximum = WEBRTC_SPL_WORD32_MIN;
+ size_t i = 0;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ if (vector[i] > maximum)
+ maximum = vector[i];
+ }
+ return maximum;
+}
+
+// Minimum value of word16 vector. C version for generic platforms.
+int16_t WebRtcSpl_MinValueW16C(const int16_t* vector, size_t length) {
+ int16_t minimum = WEBRTC_SPL_WORD16_MAX;
+ size_t i = 0;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ if (vector[i] < minimum)
+ minimum = vector[i];
+ }
+ return minimum;
+}
+
+// Minimum value of word32 vector. C version for generic platforms.
+int32_t WebRtcSpl_MinValueW32C(const int32_t* vector, size_t length) {
+ int32_t minimum = WEBRTC_SPL_WORD32_MAX;
+ size_t i = 0;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ if (vector[i] < minimum)
+ minimum = vector[i];
+ }
+ return minimum;
+}
+
+// Index of maximum absolute value in a word16 vector.
+size_t WebRtcSpl_MaxAbsIndexW16(const int16_t* vector, size_t length) {
+ // Use type int for local variables, to accomodate the value of abs(-32768).
+
+ size_t i = 0, index = 0;
+ int absolute = 0, maximum = 0;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ absolute = abs((int)vector[i]);
+
+ if (absolute > maximum) {
+ maximum = absolute;
+ index = i;
+ }
+ }
+
+ return index;
+}
+
+// Index of maximum value in a word16 vector.
+size_t WebRtcSpl_MaxIndexW16(const int16_t* vector, size_t length) {
+ size_t i = 0, index = 0;
+ int16_t maximum = WEBRTC_SPL_WORD16_MIN;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ if (vector[i] > maximum) {
+ maximum = vector[i];
+ index = i;
+ }
+ }
+
+ return index;
+}
+
+// Index of maximum value in a word32 vector.
+size_t WebRtcSpl_MaxIndexW32(const int32_t* vector, size_t length) {
+ size_t i = 0, index = 0;
+ int32_t maximum = WEBRTC_SPL_WORD32_MIN;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ if (vector[i] > maximum) {
+ maximum = vector[i];
+ index = i;
+ }
+ }
+
+ return index;
+}
+
+// Index of minimum value in a word16 vector.
+size_t WebRtcSpl_MinIndexW16(const int16_t* vector, size_t length) {
+ size_t i = 0, index = 0;
+ int16_t minimum = WEBRTC_SPL_WORD16_MAX;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ if (vector[i] < minimum) {
+ minimum = vector[i];
+ index = i;
+ }
+ }
+
+ return index;
+}
+
+// Index of minimum value in a word32 vector.
+size_t WebRtcSpl_MinIndexW32(const int32_t* vector, size_t length) {
+ size_t i = 0, index = 0;
+ int32_t minimum = WEBRTC_SPL_WORD32_MAX;
+
+ RTC_DCHECK_GT(length, 0);
+
+ for (i = 0; i < length; i++) {
+ if (vector[i] < minimum) {
+ minimum = vector[i];
+ index = i;
+ }
+ }
+
+ return index;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_48khz.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_48khz.c
new file mode 100644
index 0000000..2220cc3
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_48khz.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This file contains resampling functions between 48 kHz and nb/wb.
+ * The description header can be found in signal_processing_library.h
+ *
+ */
+
+#include <string.h>
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+#include "webrtc/common_audio/signal_processing/resample_by_2_internal.h"
+
+////////////////////////////
+///// 48 kHz -> 16 kHz /////
+////////////////////////////
+
+// 48 -> 16 resampler
+void WebRtcSpl_Resample48khzTo16khz(const int16_t* in, int16_t* out,
+ WebRtcSpl_State48khzTo16khz* state, int32_t* tmpmem)
+{
+ ///// 48 --> 48(LP) /////
+ // int16_t in[480]
+ // int32_t out[480]
+ /////
+ WebRtcSpl_LPBy2ShortToInt(in, 480, tmpmem + 16, state->S_48_48);
+
+ ///// 48 --> 32 /////
+ // int32_t in[480]
+ // int32_t out[320]
+ /////
+ // copy state to and from input array
+ memcpy(tmpmem + 8, state->S_48_32, 8 * sizeof(int32_t));
+ memcpy(state->S_48_32, tmpmem + 488, 8 * sizeof(int32_t));
+ WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 160);
+
+ ///// 32 --> 16 /////
+ // int32_t in[320]
+ // int16_t out[160]
+ /////
+ WebRtcSpl_DownBy2IntToShort(tmpmem, 320, out, state->S_32_16);
+}
+
+// initialize state of 48 -> 16 resampler
+void WebRtcSpl_ResetResample48khzTo16khz(WebRtcSpl_State48khzTo16khz* state)
+{
+ memset(state->S_48_48, 0, 16 * sizeof(int32_t));
+ memset(state->S_48_32, 0, 8 * sizeof(int32_t));
+ memset(state->S_32_16, 0, 8 * sizeof(int32_t));
+}
+
+////////////////////////////
+///// 16 kHz -> 48 kHz /////
+////////////////////////////
+
+// 16 -> 48 resampler
+void WebRtcSpl_Resample16khzTo48khz(const int16_t* in, int16_t* out,
+ WebRtcSpl_State16khzTo48khz* state, int32_t* tmpmem)
+{
+ ///// 16 --> 32 /////
+ // int16_t in[160]
+ // int32_t out[320]
+ /////
+ WebRtcSpl_UpBy2ShortToInt(in, 160, tmpmem + 16, state->S_16_32);
+
+ ///// 32 --> 24 /////
+ // int32_t in[320]
+ // int32_t out[240]
+ // copy state to and from input array
+ /////
+ memcpy(tmpmem + 8, state->S_32_24, 8 * sizeof(int32_t));
+ memcpy(state->S_32_24, tmpmem + 328, 8 * sizeof(int32_t));
+ WebRtcSpl_Resample32khzTo24khz(tmpmem + 8, tmpmem, 80);
+
+ ///// 24 --> 48 /////
+ // int32_t in[240]
+ // int16_t out[480]
+ /////
+ WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48);
+}
+
+// initialize state of 16 -> 48 resampler
+void WebRtcSpl_ResetResample16khzTo48khz(WebRtcSpl_State16khzTo48khz* state)
+{
+ memset(state->S_16_32, 0, 8 * sizeof(int32_t));
+ memset(state->S_32_24, 0, 8 * sizeof(int32_t));
+ memset(state->S_24_48, 0, 8 * sizeof(int32_t));
+}
+
+////////////////////////////
+///// 48 kHz -> 8 kHz /////
+////////////////////////////
+
+// 48 -> 8 resampler
+void WebRtcSpl_Resample48khzTo8khz(const int16_t* in, int16_t* out,
+ WebRtcSpl_State48khzTo8khz* state, int32_t* tmpmem)
+{
+ ///// 48 --> 24 /////
+ // int16_t in[480]
+ // int32_t out[240]
+ /////
+ WebRtcSpl_DownBy2ShortToInt(in, 480, tmpmem + 256, state->S_48_24);
+
+ ///// 24 --> 24(LP) /////
+ // int32_t in[240]
+ // int32_t out[240]
+ /////
+ WebRtcSpl_LPBy2IntToInt(tmpmem + 256, 240, tmpmem + 16, state->S_24_24);
+
+ ///// 24 --> 16 /////
+ // int32_t in[240]
+ // int32_t out[160]
+ /////
+ // copy state to and from input array
+ memcpy(tmpmem + 8, state->S_24_16, 8 * sizeof(int32_t));
+ memcpy(state->S_24_16, tmpmem + 248, 8 * sizeof(int32_t));
+ WebRtcSpl_Resample48khzTo32khz(tmpmem + 8, tmpmem, 80);
+
+ ///// 16 --> 8 /////
+ // int32_t in[160]
+ // int16_t out[80]
+ /////
+ WebRtcSpl_DownBy2IntToShort(tmpmem, 160, out, state->S_16_8);
+}
+
+// initialize state of 48 -> 8 resampler
+void WebRtcSpl_ResetResample48khzTo8khz(WebRtcSpl_State48khzTo8khz* state)
+{
+ memset(state->S_48_24, 0, 8 * sizeof(int32_t));
+ memset(state->S_24_24, 0, 16 * sizeof(int32_t));
+ memset(state->S_24_16, 0, 8 * sizeof(int32_t));
+ memset(state->S_16_8, 0, 8 * sizeof(int32_t));
+}
+
+////////////////////////////
+///// 8 kHz -> 48 kHz /////
+////////////////////////////
+
+// 8 -> 48 resampler
+void WebRtcSpl_Resample8khzTo48khz(const int16_t* in, int16_t* out,
+ WebRtcSpl_State8khzTo48khz* state, int32_t* tmpmem)
+{
+ ///// 8 --> 16 /////
+ // int16_t in[80]
+ // int32_t out[160]
+ /////
+ WebRtcSpl_UpBy2ShortToInt(in, 80, tmpmem + 264, state->S_8_16);
+
+ ///// 16 --> 12 /////
+ // int32_t in[160]
+ // int32_t out[120]
+ /////
+ // copy state to and from input array
+ memcpy(tmpmem + 256, state->S_16_12, 8 * sizeof(int32_t));
+ memcpy(state->S_16_12, tmpmem + 416, 8 * sizeof(int32_t));
+ WebRtcSpl_Resample32khzTo24khz(tmpmem + 256, tmpmem + 240, 40);
+
+ ///// 12 --> 24 /////
+ // int32_t in[120]
+ // int16_t out[240]
+ /////
+ WebRtcSpl_UpBy2IntToInt(tmpmem + 240, 120, tmpmem, state->S_12_24);
+
+ ///// 24 --> 48 /////
+ // int32_t in[240]
+ // int16_t out[480]
+ /////
+ WebRtcSpl_UpBy2IntToShort(tmpmem, 240, out, state->S_24_48);
+}
+
+// initialize state of 8 -> 48 resampler
+void WebRtcSpl_ResetResample8khzTo48khz(WebRtcSpl_State8khzTo48khz* state)
+{
+ memset(state->S_8_16, 0, 8 * sizeof(int32_t));
+ memset(state->S_16_12, 0, 8 * sizeof(int32_t));
+ memset(state->S_12_24, 0, 8 * sizeof(int32_t));
+ memset(state->S_24_48, 0, 8 * sizeof(int32_t));
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.c
new file mode 100644
index 0000000..72bc0f9
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.c
@@ -0,0 +1,689 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This header file contains some internal resampling functions.
+ *
+ */
+
+#include "webrtc/common_audio/signal_processing/resample_by_2_internal.h"
+#include "webrtc/rtc_base/sanitizer.h"
+
+// allpass filter coefficients.
+static const int16_t kResampleAllpass[2][3] = {
+ {821, 6110, 12382},
+ {3050, 9368, 15063}
+};
+
+//
+// decimator
+// input: int32_t (shifted 15 positions to the left, + offset 16384) OVERWRITTEN!
+// output: int16_t (saturated) (of length len/2)
+// state: filter state array; length = 8
+
+void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486
+WebRtcSpl_DownBy2IntToShort(int32_t *in, int32_t len, int16_t *out,
+ int32_t *state)
+{
+ int32_t tmp0, tmp1, diff;
+ int32_t i;
+
+ len >>= 1;
+
+ // lower allpass filter (operates on even input samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = in[i << 1];
+ diff = tmp0 - state[1];
+ // UBSan: -1771017321 - 999586185 cannot be represented in type 'int'
+
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
+ state[0] = tmp0;
+ diff = tmp1 - state[2];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
+ state[1] = tmp1;
+ diff = tmp0 - state[3];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
+ state[2] = tmp0;
+
+ // divide by two and store temporarily
+ in[i << 1] = (state[3] >> 1);
+ }
+
+ in++;
+
+ // upper allpass filter (operates on odd input samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = in[i << 1];
+ diff = tmp0 - state[5];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
+ state[4] = tmp0;
+ diff = tmp1 - state[6];
+ // scale down and round
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
+ state[5] = tmp1;
+ diff = tmp0 - state[7];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
+ state[6] = tmp0;
+
+ // divide by two and store temporarily
+ in[i << 1] = (state[7] >> 1);
+ }
+
+ in--;
+
+ // combine allpass outputs
+ for (i = 0; i < len; i += 2)
+ {
+ // divide by two, add both allpass outputs and round
+ tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15;
+ tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15;
+ if (tmp0 > (int32_t)0x00007FFF)
+ tmp0 = 0x00007FFF;
+ if (tmp0 < (int32_t)0xFFFF8000)
+ tmp0 = 0xFFFF8000;
+ out[i] = (int16_t)tmp0;
+ if (tmp1 > (int32_t)0x00007FFF)
+ tmp1 = 0x00007FFF;
+ if (tmp1 < (int32_t)0xFFFF8000)
+ tmp1 = 0xFFFF8000;
+ out[i + 1] = (int16_t)tmp1;
+ }
+}
+
+//
+// decimator
+// input: int16_t
+// output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len/2)
+// state: filter state array; length = 8
+
+void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486
+WebRtcSpl_DownBy2ShortToInt(const int16_t *in,
+ int32_t len,
+ int32_t *out,
+ int32_t *state)
+{
+ int32_t tmp0, tmp1, diff;
+ int32_t i;
+
+ len >>= 1;
+
+ // lower allpass filter (operates on even input samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
+ diff = tmp0 - state[1];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
+ state[0] = tmp0;
+ diff = tmp1 - state[2];
+ // UBSan: -1379909682 - 834099714 cannot be represented in type 'int'
+
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
+ state[1] = tmp1;
+ diff = tmp0 - state[3];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
+ state[2] = tmp0;
+
+ // divide by two and store temporarily
+ out[i] = (state[3] >> 1);
+ }
+
+ in++;
+
+ // upper allpass filter (operates on odd input samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
+ diff = tmp0 - state[5];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
+ state[4] = tmp0;
+ diff = tmp1 - state[6];
+ // scale down and round
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
+ state[5] = tmp1;
+ diff = tmp0 - state[7];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
+ state[6] = tmp0;
+
+ // divide by two and store temporarily
+ out[i] += (state[7] >> 1);
+ }
+
+ in--;
+}
+
+//
+// interpolator
+// input: int16_t
+// output: int32_t (normalized, not saturated) (of length len*2)
+// state: filter state array; length = 8
+void WebRtcSpl_UpBy2ShortToInt(const int16_t *in, int32_t len, int32_t *out,
+ int32_t *state)
+{
+ int32_t tmp0, tmp1, diff;
+ int32_t i;
+
+ // upper allpass filter (generates odd output samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = ((int32_t)in[i] << 15) + (1 << 14);
+ diff = tmp0 - state[5];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
+ state[4] = tmp0;
+ diff = tmp1 - state[6];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
+ state[5] = tmp1;
+ diff = tmp0 - state[7];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
+ state[6] = tmp0;
+
+ // scale down, round and store
+ out[i << 1] = state[7] >> 15;
+ }
+
+ out++;
+
+ // lower allpass filter (generates even output samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = ((int32_t)in[i] << 15) + (1 << 14);
+ diff = tmp0 - state[1];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
+ state[0] = tmp0;
+ diff = tmp1 - state[2];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
+ state[1] = tmp1;
+ diff = tmp0 - state[3];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
+ state[2] = tmp0;
+
+ // scale down, round and store
+ out[i << 1] = state[3] >> 15;
+ }
+}
+
+//
+// interpolator
+// input: int32_t (shifted 15 positions to the left, + offset 16384)
+// output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len*2)
+// state: filter state array; length = 8
+void WebRtcSpl_UpBy2IntToInt(const int32_t *in, int32_t len, int32_t *out,
+ int32_t *state)
+{
+ int32_t tmp0, tmp1, diff;
+ int32_t i;
+
+ // upper allpass filter (generates odd output samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = in[i];
+ diff = tmp0 - state[5];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
+ state[4] = tmp0;
+ diff = tmp1 - state[6];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
+ state[5] = tmp1;
+ diff = tmp0 - state[7];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
+ state[6] = tmp0;
+
+ // scale down, round and store
+ out[i << 1] = state[7];
+ }
+
+ out++;
+
+ // lower allpass filter (generates even output samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = in[i];
+ diff = tmp0 - state[1];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
+ state[0] = tmp0;
+ diff = tmp1 - state[2];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
+ state[1] = tmp1;
+ diff = tmp0 - state[3];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
+ state[2] = tmp0;
+
+ // scale down, round and store
+ out[i << 1] = state[3];
+ }
+}
+
+//
+// interpolator
+// input: int32_t (shifted 15 positions to the left, + offset 16384)
+// output: int16_t (saturated) (of length len*2)
+// state: filter state array; length = 8
+void WebRtcSpl_UpBy2IntToShort(const int32_t *in, int32_t len, int16_t *out,
+ int32_t *state)
+{
+ int32_t tmp0, tmp1, diff;
+ int32_t i;
+
+ // upper allpass filter (generates odd output samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = in[i];
+ diff = tmp0 - state[5];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
+ state[4] = tmp0;
+ diff = tmp1 - state[6];
+ // scale down and round
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
+ state[5] = tmp1;
+ diff = tmp0 - state[7];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
+ state[6] = tmp0;
+
+ // scale down, saturate and store
+ tmp1 = state[7] >> 15;
+ if (tmp1 > (int32_t)0x00007FFF)
+ tmp1 = 0x00007FFF;
+ if (tmp1 < (int32_t)0xFFFF8000)
+ tmp1 = 0xFFFF8000;
+ out[i << 1] = (int16_t)tmp1;
+ }
+
+ out++;
+
+ // lower allpass filter (generates even output samples)
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = in[i];
+ diff = tmp0 - state[1];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
+ state[0] = tmp0;
+ diff = tmp1 - state[2];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
+ state[1] = tmp1;
+ diff = tmp0 - state[3];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
+ state[2] = tmp0;
+
+ // scale down, saturate and store
+ tmp1 = state[3] >> 15;
+ if (tmp1 > (int32_t)0x00007FFF)
+ tmp1 = 0x00007FFF;
+ if (tmp1 < (int32_t)0xFFFF8000)
+ tmp1 = 0xFFFF8000;
+ out[i << 1] = (int16_t)tmp1;
+ }
+}
+
+// lowpass filter
+// input: int16_t
+// output: int32_t (normalized, not saturated)
+// state: filter state array; length = 8
+void WebRtcSpl_LPBy2ShortToInt(const int16_t* in, int32_t len, int32_t* out,
+ int32_t* state)
+{
+ int32_t tmp0, tmp1, diff;
+ int32_t i;
+
+ len >>= 1;
+
+ // lower allpass filter: odd input -> even output samples
+ in++;
+ // initial state of polyphase delay element
+ tmp0 = state[12];
+ for (i = 0; i < len; i++)
+ {
+ diff = tmp0 - state[1];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
+ state[0] = tmp0;
+ diff = tmp1 - state[2];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
+ state[1] = tmp1;
+ diff = tmp0 - state[3];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
+ state[2] = tmp0;
+
+ // scale down, round and store
+ out[i << 1] = state[3] >> 1;
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
+ }
+ in--;
+
+ // upper allpass filter: even input -> even output samples
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
+ diff = tmp0 - state[5];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
+ state[4] = tmp0;
+ diff = tmp1 - state[6];
+ // scale down and round
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
+ state[5] = tmp1;
+ diff = tmp0 - state[7];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
+ state[6] = tmp0;
+
+ // average the two allpass outputs, scale down and store
+ out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
+ }
+
+ // switch to odd output samples
+ out++;
+
+ // lower allpass filter: even input -> odd output samples
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
+ diff = tmp0 - state[9];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[8] + diff * kResampleAllpass[1][0];
+ state[8] = tmp0;
+ diff = tmp1 - state[10];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[9] + diff * kResampleAllpass[1][1];
+ state[9] = tmp1;
+ diff = tmp0 - state[11];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[11] = state[10] + diff * kResampleAllpass[1][2];
+ state[10] = tmp0;
+
+ // scale down, round and store
+ out[i << 1] = state[11] >> 1;
+ }
+
+ // upper allpass filter: odd input -> odd output samples
+ in++;
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
+ diff = tmp0 - state[13];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[12] + diff * kResampleAllpass[0][0];
+ state[12] = tmp0;
+ diff = tmp1 - state[14];
+ // scale down and round
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[13] + diff * kResampleAllpass[0][1];
+ state[13] = tmp1;
+ diff = tmp0 - state[15];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[15] = state[14] + diff * kResampleAllpass[0][2];
+ state[14] = tmp0;
+
+ // average the two allpass outputs, scale down and store
+ out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
+ }
+}
+
+// lowpass filter
+// input: int32_t (shifted 15 positions to the left, + offset 16384)
+// output: int32_t (normalized, not saturated)
+// state: filter state array; length = 8
+void RTC_NO_SANITIZE("signed-integer-overflow") // bugs.webrtc.org/5486
+WebRtcSpl_LPBy2IntToInt(const int32_t* in, int32_t len, int32_t* out,
+ int32_t* state)
+{
+ int32_t tmp0, tmp1, diff;
+ int32_t i;
+
+ len >>= 1;
+
+ // lower allpass filter: odd input -> even output samples
+ in++;
+ // initial state of polyphase delay element
+ tmp0 = state[12];
+ for (i = 0; i < len; i++)
+ {
+ diff = tmp0 - state[1];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[0] + diff * kResampleAllpass[1][0];
+ state[0] = tmp0;
+ diff = tmp1 - state[2];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[1] + diff * kResampleAllpass[1][1];
+ state[1] = tmp1;
+ diff = tmp0 - state[3];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[3] = state[2] + diff * kResampleAllpass[1][2];
+ state[2] = tmp0;
+
+ // scale down, round and store
+ out[i << 1] = state[3] >> 1;
+ tmp0 = in[i << 1];
+ }
+ in--;
+
+ // upper allpass filter: even input -> even output samples
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = in[i << 1];
+ diff = tmp0 - state[5];
+ // UBSan: -794814117 - 1566149201 cannot be represented in type 'int'
+
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[4] + diff * kResampleAllpass[0][0];
+ state[4] = tmp0;
+ diff = tmp1 - state[6];
+ // scale down and round
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[5] + diff * kResampleAllpass[0][1];
+ state[5] = tmp1;
+ diff = tmp0 - state[7];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[7] = state[6] + diff * kResampleAllpass[0][2];
+ state[6] = tmp0;
+
+ // average the two allpass outputs, scale down and store
+ out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
+ }
+
+ // switch to odd output samples
+ out++;
+
+ // lower allpass filter: even input -> odd output samples
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = in[i << 1];
+ diff = tmp0 - state[9];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[8] + diff * kResampleAllpass[1][0];
+ state[8] = tmp0;
+ diff = tmp1 - state[10];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[9] + diff * kResampleAllpass[1][1];
+ state[9] = tmp1;
+ diff = tmp0 - state[11];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[11] = state[10] + diff * kResampleAllpass[1][2];
+ state[10] = tmp0;
+
+ // scale down, round and store
+ out[i << 1] = state[11] >> 1;
+ }
+
+ // upper allpass filter: odd input -> odd output samples
+ in++;
+ for (i = 0; i < len; i++)
+ {
+ tmp0 = in[i << 1];
+ diff = tmp0 - state[13];
+ // scale down and round
+ diff = (diff + (1 << 13)) >> 14;
+ tmp1 = state[12] + diff * kResampleAllpass[0][0];
+ state[12] = tmp0;
+ diff = tmp1 - state[14];
+ // scale down and round
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ tmp0 = state[13] + diff * kResampleAllpass[0][1];
+ state[13] = tmp1;
+ diff = tmp0 - state[15];
+ // scale down and truncate
+ diff = diff >> 14;
+ if (diff < 0)
+ diff += 1;
+ state[15] = state[14] + diff * kResampleAllpass[0][2];
+ state[14] = tmp0;
+
+ // average the two allpass outputs, scale down and store
+ out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
+ }
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.h
new file mode 100644
index 0000000..145395a
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_by_2_internal.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * This header file contains some internal resampling functions.
+ *
+ */
+
+#ifndef COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_
+#define COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_
+
+#include <stdint.h>
+
+/*******************************************************************
+ * resample_by_2_fast.c
+ * Functions for internal use in the other resample functions
+ ******************************************************************/
+void WebRtcSpl_DownBy2IntToShort(int32_t* in,
+ int32_t len,
+ int16_t* out,
+ int32_t* state);
+
+void WebRtcSpl_DownBy2ShortToInt(const int16_t* in,
+ int32_t len,
+ int32_t* out,
+ int32_t* state);
+
+void WebRtcSpl_UpBy2ShortToInt(const int16_t* in,
+ int32_t len,
+ int32_t* out,
+ int32_t* state);
+
+void WebRtcSpl_UpBy2IntToInt(const int32_t* in,
+ int32_t len,
+ int32_t* out,
+ int32_t* state);
+
+void WebRtcSpl_UpBy2IntToShort(const int32_t* in,
+ int32_t len,
+ int16_t* out,
+ int32_t* state);
+
+void WebRtcSpl_LPBy2ShortToInt(const int16_t* in,
+ int32_t len,
+ int32_t* out,
+ int32_t* state);
+
+void WebRtcSpl_LPBy2IntToInt(const int32_t* in,
+ int32_t len,
+ int32_t* out,
+ int32_t* state);
+
+#endif // COMMON_AUDIO_SIGNAL_PROCESSING_RESAMPLE_BY_2_INTERNAL_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_fractional.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_fractional.c
new file mode 100644
index 0000000..6409fba
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/resample_fractional.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This file contains the resampling functions between 48, 44, 32 and 24 kHz.
+ * The description headers can be found in signal_processing_library.h
+ *
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+// interpolation coefficients
+static const int16_t kCoefficients48To32[2][8] = {
+ {778, -2050, 1087, 23285, 12903, -3783, 441, 222},
+ {222, 441, -3783, 12903, 23285, 1087, -2050, 778}
+};
+
+static const int16_t kCoefficients32To24[3][8] = {
+ {767, -2362, 2434, 24406, 10620, -3838, 721, 90},
+ {386, -381, -2646, 19062, 19062, -2646, -381, 386},
+ {90, 721, -3838, 10620, 24406, 2434, -2362, 767}
+};
+
+static const int16_t kCoefficients44To32[4][9] = {
+ {117, -669, 2245, -6183, 26267, 13529, -3245, 845, -138},
+ {-101, 612, -2283, 8532, 29790, -5138, 1789, -524, 91},
+ {50, -292, 1016, -3064, 32010, 3933, -1147, 315, -53},
+ {-156, 974, -3863, 18603, 21691, -6246, 2353, -712, 126}
+};
+
+// Resampling ratio: 2/3
+// input: int32_t (normalized, not saturated) :: size 3 * K
+// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 2 * K
+// K: number of blocks
+
+void WebRtcSpl_Resample48khzTo32khz(const int32_t *In, int32_t *Out, size_t K)
+{
+ /////////////////////////////////////////////////////////////
+ // Filter operation:
+ //
+ // Perform resampling (3 input samples -> 2 output samples);
+ // process in sub blocks of size 3 samples.
+ int32_t tmp;
+ size_t m;
+
+ for (m = 0; m < K; m++)
+ {
+ tmp = 1 << 14;
+ tmp += kCoefficients48To32[0][0] * In[0];
+ tmp += kCoefficients48To32[0][1] * In[1];
+ tmp += kCoefficients48To32[0][2] * In[2];
+ tmp += kCoefficients48To32[0][3] * In[3];
+ tmp += kCoefficients48To32[0][4] * In[4];
+ tmp += kCoefficients48To32[0][5] * In[5];
+ tmp += kCoefficients48To32[0][6] * In[6];
+ tmp += kCoefficients48To32[0][7] * In[7];
+ Out[0] = tmp;
+
+ tmp = 1 << 14;
+ tmp += kCoefficients48To32[1][0] * In[1];
+ tmp += kCoefficients48To32[1][1] * In[2];
+ tmp += kCoefficients48To32[1][2] * In[3];
+ tmp += kCoefficients48To32[1][3] * In[4];
+ tmp += kCoefficients48To32[1][4] * In[5];
+ tmp += kCoefficients48To32[1][5] * In[6];
+ tmp += kCoefficients48To32[1][6] * In[7];
+ tmp += kCoefficients48To32[1][7] * In[8];
+ Out[1] = tmp;
+
+ // update pointers
+ In += 3;
+ Out += 2;
+ }
+}
+
+// Resampling ratio: 3/4
+// input: int32_t (normalized, not saturated) :: size 4 * K
+// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 3 * K
+// K: number of blocks
+
+void WebRtcSpl_Resample32khzTo24khz(const int32_t *In, int32_t *Out, size_t K)
+{
+ /////////////////////////////////////////////////////////////
+ // Filter operation:
+ //
+ // Perform resampling (4 input samples -> 3 output samples);
+ // process in sub blocks of size 4 samples.
+ size_t m;
+ int32_t tmp;
+
+ for (m = 0; m < K; m++)
+ {
+ tmp = 1 << 14;
+ tmp += kCoefficients32To24[0][0] * In[0];
+ tmp += kCoefficients32To24[0][1] * In[1];
+ tmp += kCoefficients32To24[0][2] * In[2];
+ tmp += kCoefficients32To24[0][3] * In[3];
+ tmp += kCoefficients32To24[0][4] * In[4];
+ tmp += kCoefficients32To24[0][5] * In[5];
+ tmp += kCoefficients32To24[0][6] * In[6];
+ tmp += kCoefficients32To24[0][7] * In[7];
+ Out[0] = tmp;
+
+ tmp = 1 << 14;
+ tmp += kCoefficients32To24[1][0] * In[1];
+ tmp += kCoefficients32To24[1][1] * In[2];
+ tmp += kCoefficients32To24[1][2] * In[3];
+ tmp += kCoefficients32To24[1][3] * In[4];
+ tmp += kCoefficients32To24[1][4] * In[5];
+ tmp += kCoefficients32To24[1][5] * In[6];
+ tmp += kCoefficients32To24[1][6] * In[7];
+ tmp += kCoefficients32To24[1][7] * In[8];
+ Out[1] = tmp;
+
+ tmp = 1 << 14;
+ tmp += kCoefficients32To24[2][0] * In[2];
+ tmp += kCoefficients32To24[2][1] * In[3];
+ tmp += kCoefficients32To24[2][2] * In[4];
+ tmp += kCoefficients32To24[2][3] * In[5];
+ tmp += kCoefficients32To24[2][4] * In[6];
+ tmp += kCoefficients32To24[2][5] * In[7];
+ tmp += kCoefficients32To24[2][6] * In[8];
+ tmp += kCoefficients32To24[2][7] * In[9];
+ Out[2] = tmp;
+
+ // update pointers
+ In += 4;
+ Out += 3;
+ }
+}
+
+//
+// fractional resampling filters
+// Fout = 11/16 * Fin
+// Fout = 8/11 * Fin
+//
+
+// compute two inner-products and store them to output array
+static void WebRtcSpl_ResampDotProduct(const int32_t *in1, const int32_t *in2,
+ const int16_t *coef_ptr, int32_t *out1,
+ int32_t *out2)
+{
+ int32_t tmp1 = 16384;
+ int32_t tmp2 = 16384;
+ int16_t coef;
+
+ coef = coef_ptr[0];
+ tmp1 += coef * in1[0];
+ tmp2 += coef * in2[-0];
+
+ coef = coef_ptr[1];
+ tmp1 += coef * in1[1];
+ tmp2 += coef * in2[-1];
+
+ coef = coef_ptr[2];
+ tmp1 += coef * in1[2];
+ tmp2 += coef * in2[-2];
+
+ coef = coef_ptr[3];
+ tmp1 += coef * in1[3];
+ tmp2 += coef * in2[-3];
+
+ coef = coef_ptr[4];
+ tmp1 += coef * in1[4];
+ tmp2 += coef * in2[-4];
+
+ coef = coef_ptr[5];
+ tmp1 += coef * in1[5];
+ tmp2 += coef * in2[-5];
+
+ coef = coef_ptr[6];
+ tmp1 += coef * in1[6];
+ tmp2 += coef * in2[-6];
+
+ coef = coef_ptr[7];
+ tmp1 += coef * in1[7];
+ tmp2 += coef * in2[-7];
+
+ coef = coef_ptr[8];
+ *out1 = tmp1 + coef * in1[8];
+ *out2 = tmp2 + coef * in2[-8];
+}
+
+// Resampling ratio: 8/11
+// input: int32_t (normalized, not saturated) :: size 11 * K
+// output: int32_t (shifted 15 positions to the left, + offset 16384) :: size 8 * K
+// K: number of blocks
+
+void WebRtcSpl_Resample44khzTo32khz(const int32_t *In, int32_t *Out, size_t K)
+{
+ /////////////////////////////////////////////////////////////
+ // Filter operation:
+ //
+ // Perform resampling (11 input samples -> 8 output samples);
+ // process in sub blocks of size 11 samples.
+ int32_t tmp;
+ size_t m;
+
+ for (m = 0; m < K; m++)
+ {
+ tmp = 1 << 14;
+
+ // first output sample
+ Out[0] = ((int32_t)In[3] << 15) + tmp;
+
+ // sum and accumulate filter coefficients and input samples
+ tmp += kCoefficients44To32[3][0] * In[5];
+ tmp += kCoefficients44To32[3][1] * In[6];
+ tmp += kCoefficients44To32[3][2] * In[7];
+ tmp += kCoefficients44To32[3][3] * In[8];
+ tmp += kCoefficients44To32[3][4] * In[9];
+ tmp += kCoefficients44To32[3][5] * In[10];
+ tmp += kCoefficients44To32[3][6] * In[11];
+ tmp += kCoefficients44To32[3][7] * In[12];
+ tmp += kCoefficients44To32[3][8] * In[13];
+ Out[4] = tmp;
+
+ // sum and accumulate filter coefficients and input samples
+ WebRtcSpl_ResampDotProduct(&In[0], &In[17], kCoefficients44To32[0], &Out[1], &Out[7]);
+
+ // sum and accumulate filter coefficients and input samples
+ WebRtcSpl_ResampDotProduct(&In[2], &In[15], kCoefficients44To32[1], &Out[2], &Out[6]);
+
+ // sum and accumulate filter coefficients and input samples
+ WebRtcSpl_ResampDotProduct(&In[3], &In[14], kCoefficients44To32[2], &Out[3], &Out[5]);
+
+ // update pointers
+ In += 11;
+ Out += 8;
+ }
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_init.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_init.c
new file mode 100644
index 0000000..82fba1d
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_init.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+/* The global function contained in this file initializes SPL function
+ * pointers, currently only for ARM platforms.
+ *
+ * Some code came from common/rtcd.c in the WebM project.
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+#include "webrtc/system_wrappers/include/cpu_features_wrapper.h"
+
+/* Declare function pointers. */
+MaxAbsValueW16 WebRtcSpl_MaxAbsValueW16;
+MaxAbsValueW32 WebRtcSpl_MaxAbsValueW32;
+MaxValueW16 WebRtcSpl_MaxValueW16;
+MaxValueW32 WebRtcSpl_MaxValueW32;
+MinValueW16 WebRtcSpl_MinValueW16;
+MinValueW32 WebRtcSpl_MinValueW32;
+CrossCorrelation WebRtcSpl_CrossCorrelation;
+DownsampleFast WebRtcSpl_DownsampleFast;
+ScaleAndAddVectorsWithRound WebRtcSpl_ScaleAndAddVectorsWithRound;
+
+#if (!defined(WEBRTC_HAS_NEON)) && !defined(MIPS32_LE)
+/* Initialize function pointers to the generic C version. */
+static void InitPointersToC(void) {
+ WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16C;
+ WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C;
+ WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16C;
+ WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32C;
+ WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16C;
+ WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32C;
+ WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationC;
+ WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastC;
+ WebRtcSpl_ScaleAndAddVectorsWithRound =
+ WebRtcSpl_ScaleAndAddVectorsWithRoundC;
+}
+#endif
+
+#if defined(WEBRTC_HAS_NEON)
+/* Initialize function pointers to the Neon version. */
+static void InitPointersToNeon(void) {
+ WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16Neon;
+ WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32Neon;
+ WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16Neon;
+ WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32Neon;
+ WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16Neon;
+ WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32Neon;
+ WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelationNeon;
+ WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFastNeon;
+ WebRtcSpl_ScaleAndAddVectorsWithRound =
+ WebRtcSpl_ScaleAndAddVectorsWithRoundC;
+}
+#endif
+
+#if defined(MIPS32_LE)
+/* Initialize function pointers to the MIPS version. */
+static void InitPointersToMIPS(void) {
+ WebRtcSpl_MaxAbsValueW16 = WebRtcSpl_MaxAbsValueW16_mips;
+ WebRtcSpl_MaxValueW16 = WebRtcSpl_MaxValueW16_mips;
+ WebRtcSpl_MaxValueW32 = WebRtcSpl_MaxValueW32_mips;
+ WebRtcSpl_MinValueW16 = WebRtcSpl_MinValueW16_mips;
+ WebRtcSpl_MinValueW32 = WebRtcSpl_MinValueW32_mips;
+ WebRtcSpl_CrossCorrelation = WebRtcSpl_CrossCorrelation_mips;
+ WebRtcSpl_DownsampleFast = WebRtcSpl_DownsampleFast_mips;
+#if defined(MIPS_DSP_R1_LE)
+ WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32_mips;
+ WebRtcSpl_ScaleAndAddVectorsWithRound =
+ WebRtcSpl_ScaleAndAddVectorsWithRound_mips;
+#else
+ WebRtcSpl_MaxAbsValueW32 = WebRtcSpl_MaxAbsValueW32C;
+ WebRtcSpl_ScaleAndAddVectorsWithRound =
+ WebRtcSpl_ScaleAndAddVectorsWithRoundC;
+#endif
+}
+#endif
+
+static void InitFunctionPointers(void) {
+#if defined(WEBRTC_HAS_NEON)
+ InitPointersToNeon();
+#elif defined(MIPS32_LE)
+ InitPointersToMIPS();
+#else
+ InitPointersToC();
+#endif /* WEBRTC_HAS_NEON */
+}
+
+#if defined(WEBRTC_POSIX)
+#include <pthread.h>
+
+static void once(void (*func)(void)) {
+ static pthread_once_t lock = PTHREAD_ONCE_INIT;
+ pthread_once(&lock, func);
+}
+
+#elif defined(_WIN32)
+#include <windows.h>
+
+static void once(void (*func)(void)) {
+ /* Didn't use InitializeCriticalSection() since there's no race-free context
+ * in which to execute it.
+ *
+ * TODO(kma): Change to different implementation (e.g.
+ * InterlockedCompareExchangePointer) to avoid issues similar to
+ * http://code.google.com/p/webm/issues/detail?id=467.
+ */
+ static CRITICAL_SECTION lock = {(void *)((size_t)-1), -1, 0, 0, 0, 0};
+ static int done = 0;
+
+ EnterCriticalSection(&lock);
+ if (!done) {
+ func();
+ done = 1;
+ }
+ LeaveCriticalSection(&lock);
+}
+
+/* There's no fallback version as an #else block here to ensure thread safety.
+ * In case of neither pthread for WEBRTC_POSIX nor _WIN32 is present, build
+ * system should pick it up.
+ */
+#endif /* WEBRTC_POSIX */
+
+void WebRtcSpl_Init(void) {
+ once(InitFunctionPointers);
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_inl.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_inl.c
new file mode 100644
index 0000000..efa6a65
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_inl.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <stdint.h>
+
+#include "webrtc/common_audio/signal_processing/include/spl_inl.h"
+
+// Table used by WebRtcSpl_CountLeadingZeros32_NotBuiltin. For each uint32_t n
+// that's a sequence of 0 bits followed by a sequence of 1 bits, the entry at
+// index (n * 0x8c0b2891) >> 26 in this table gives the number of zero bits in
+// n.
+const int8_t kWebRtcSpl_CountLeadingZeros32_Table[64] = {
+ 32, 8, 17, -1, -1, 14, -1, -1, -1, 20, -1, -1, -1, 28, -1, 18,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 26, 25, 24,
+ 4, 11, 23, 31, 3, 7, 10, 16, 22, 30, -1, -1, 2, 6, 13, 9,
+ -1, 15, -1, 21, -1, 29, 19, -1, -1, -1, -1, -1, 1, 27, 5, 12,
+};
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_sqrt.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_sqrt.c
new file mode 100644
index 0000000..f79ac9f
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/spl_sqrt.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This file contains the function WebRtcSpl_Sqrt().
+ * The description header can be found in signal_processing_library.h
+ *
+ */
+
+#include "webrtc/rtc_base/checks.h"
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+int32_t WebRtcSpl_SqrtLocal(int32_t in);
+
+int32_t WebRtcSpl_SqrtLocal(int32_t in)
+{
+
+ int16_t x_half, t16;
+ int32_t A, B, x2;
+
+ /* The following block performs:
+ y=in/2
+ x=y-2^30
+ x_half=x/2^31
+ t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4)
+ + 0.875*((x_half)^5)
+ */
+
+ B = in / 2;
+
+ B = B - ((int32_t)0x40000000); // B = in/2 - 1/2
+ x_half = (int16_t)(B >> 16); // x_half = x/2 = (in-1)/2
+ B = B + ((int32_t)0x40000000); // B = 1 + x/2
+ B = B + ((int32_t)0x40000000); // Add 0.5 twice (since 1.0 does not exist in Q31)
+
+ x2 = ((int32_t)x_half) * ((int32_t)x_half) * 2; // A = (x/2)^2
+ A = -x2; // A = -(x/2)^2
+ B = B + (A >> 1); // B = 1 + x/2 - 0.5*(x/2)^2
+
+ A >>= 16;
+ A = A * A * 2; // A = (x/2)^4
+ t16 = (int16_t)(A >> 16);
+ B += -20480 * t16 * 2; // B = B - 0.625*A
+ // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4
+
+ A = x_half * t16 * 2; // A = (x/2)^5
+ t16 = (int16_t)(A >> 16);
+ B += 28672 * t16 * 2; // B = B + 0.875*A
+ // After this, B = 1 + x/2 - 0.5*(x/2)^2 - 0.625*(x/2)^4 + 0.875*(x/2)^5
+
+ t16 = (int16_t)(x2 >> 16);
+ A = x_half * t16 * 2; // A = x/2^3
+
+ B = B + (A >> 1); // B = B + 0.5*A
+ // After this, B = 1 + x/2 - 0.5*(x/2)^2 + 0.5*(x/2)^3 - 0.625*(x/2)^4 + 0.875*(x/2)^5
+
+ B = B + ((int32_t)32768); // Round off bit
+
+ return B;
+}
+
+int32_t WebRtcSpl_Sqrt(int32_t value)
+{
+ /*
+ Algorithm:
+
+ Six term Taylor Series is used here to compute the square root of a number
+ y^0.5 = (1+x)^0.5 where x = y-1
+ = 1+(x/2)-0.5*((x/2)^2+0.5*((x/2)^3-0.625*((x/2)^4+0.875*((x/2)^5)
+ 0.5 <= x < 1
+
+ Example of how the algorithm works, with ut=sqrt(in), and
+ with in=73632 and ut=271 (even shift value case):
+
+ in=73632
+ y= in/131072
+ x=y-1
+ t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5)
+ ut=t*(1/sqrt(2))*512
+
+ or:
+
+ in=73632
+ in2=73632*2^14
+ y= in2/2^31
+ x=y-1
+ t = 1 + (x/2) - 0.5*((x/2)^2) + 0.5*((x/2)^3) - 0.625*((x/2)^4) + 0.875*((x/2)^5)
+ ut=t*(1/sqrt(2))
+ ut2=ut*2^9
+
+ which gives:
+
+ in = 73632
+ in2 = 1206386688
+ y = 0.56176757812500
+ x = -0.43823242187500
+ t = 0.74973506527313
+ ut = 0.53014274874797
+ ut2 = 2.714330873589594e+002
+
+ or:
+
+ in=73632
+ in2=73632*2^14
+ y=in2/2
+ x=y-2^30
+ x_half=x/2^31
+ t = 1 + (x_half) - 0.5*((x_half)^2) + 0.5*((x_half)^3) - 0.625*((x_half)^4)
+ + 0.875*((x_half)^5)
+ ut=t*(1/sqrt(2))
+ ut2=ut*2^9
+
+ which gives:
+
+ in = 73632
+ in2 = 1206386688
+ y = 603193344
+ x = -470548480
+ x_half = -0.21911621093750
+ t = 0.74973506527313
+ ut = 0.53014274874797
+ ut2 = 2.714330873589594e+002
+
+ */
+
+ int16_t x_norm, nshift, t16, sh;
+ int32_t A;
+
+ int16_t k_sqrt_2 = 23170; // 1/sqrt2 (==5a82)
+
+ A = value;
+
+ // The convention in this function is to calculate sqrt(abs(A)). Negate the
+ // input if it is negative.
+ if (A < 0) {
+ if (A == WEBRTC_SPL_WORD32_MIN) {
+ // This number cannot be held in an int32_t after negating.
+ // Map it to the maximum positive value.
+ A = WEBRTC_SPL_WORD32_MAX;
+ } else {
+ A = -A;
+ }
+ } else if (A == 0) {
+ return 0; // sqrt(0) = 0
+ }
+
+ sh = WebRtcSpl_NormW32(A); // # shifts to normalize A
+ A = WEBRTC_SPL_LSHIFT_W32(A, sh); // Normalize A
+ if (A < (WEBRTC_SPL_WORD32_MAX - 32767))
+ {
+ A = A + ((int32_t)32768); // Round off bit
+ } else
+ {
+ A = WEBRTC_SPL_WORD32_MAX;
+ }
+
+ x_norm = (int16_t)(A >> 16); // x_norm = AH
+
+ nshift = (sh / 2);
+ RTC_DCHECK_GE(nshift, 0);
+
+ A = (int32_t)WEBRTC_SPL_LSHIFT_W32((int32_t)x_norm, 16);
+ A = WEBRTC_SPL_ABS_W32(A); // A = abs(x_norm<<16)
+ A = WebRtcSpl_SqrtLocal(A); // A = sqrt(A)
+
+ if (2 * nshift == sh) {
+ // Even shift value case
+
+ t16 = (int16_t)(A >> 16); // t16 = AH
+
+ A = k_sqrt_2 * t16 * 2; // A = 1/sqrt(2)*t16
+ A = A + ((int32_t)32768); // Round off
+ A = A & ((int32_t)0x7fff0000); // Round off
+
+ A >>= 15; // A = A>>16
+
+ } else
+ {
+ A >>= 16; // A = A>>16
+ }
+
+ A = A & ((int32_t)0x0000ffff);
+ A >>= nshift; // De-normalize the result.
+
+ return A;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c
new file mode 100644
index 0000000..e1f391d
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/signal_processing/vector_scaling_operations.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This file contains implementations of the functions
+ * WebRtcSpl_VectorBitShiftW16()
+ * WebRtcSpl_VectorBitShiftW32()
+ * WebRtcSpl_VectorBitShiftW32ToW16()
+ * WebRtcSpl_ScaleVector()
+ * WebRtcSpl_ScaleVectorWithSat()
+ * WebRtcSpl_ScaleAndAddVectors()
+ * WebRtcSpl_ScaleAndAddVectorsWithRoundC()
+ */
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+void WebRtcSpl_VectorBitShiftW16(int16_t *res, size_t length,
+ const int16_t *in, int16_t right_shifts)
+{
+ size_t i;
+
+ if (right_shifts > 0)
+ {
+ for (i = length; i > 0; i--)
+ {
+ (*res++) = ((*in++) >> right_shifts);
+ }
+ } else
+ {
+ for (i = length; i > 0; i--)
+ {
+ (*res++) = ((*in++) * (1 << (-right_shifts)));
+ }
+ }
+}
+
+void WebRtcSpl_VectorBitShiftW32(int32_t *out_vector,
+ size_t vector_length,
+ const int32_t *in_vector,
+ int16_t right_shifts)
+{
+ size_t i;
+
+ if (right_shifts > 0)
+ {
+ for (i = vector_length; i > 0; i--)
+ {
+ (*out_vector++) = ((*in_vector++) >> right_shifts);
+ }
+ } else
+ {
+ for (i = vector_length; i > 0; i--)
+ {
+ (*out_vector++) = ((*in_vector++) << (-right_shifts));
+ }
+ }
+}
+
+void WebRtcSpl_VectorBitShiftW32ToW16(int16_t* out, size_t length,
+ const int32_t* in, int right_shifts) {
+ size_t i;
+ int32_t tmp_w32;
+
+ if (right_shifts >= 0) {
+ for (i = length; i > 0; i--) {
+ tmp_w32 = (*in++) >> right_shifts;
+ (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32);
+ }
+ } else {
+ int left_shifts = -right_shifts;
+ for (i = length; i > 0; i--) {
+ tmp_w32 = (*in++) << left_shifts;
+ (*out++) = WebRtcSpl_SatW32ToW16(tmp_w32);
+ }
+ }
+}
+
+void WebRtcSpl_ScaleVector(const int16_t *in_vector, int16_t *out_vector,
+ int16_t gain, size_t in_vector_length,
+ int16_t right_shifts)
+{
+ // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
+ size_t i;
+ const int16_t *inptr;
+ int16_t *outptr;
+
+ inptr = in_vector;
+ outptr = out_vector;
+
+ for (i = 0; i < in_vector_length; i++)
+ {
+ *outptr++ = (int16_t)((*inptr++ * gain) >> right_shifts);
+ }
+}
+
+void WebRtcSpl_ScaleVectorWithSat(const int16_t *in_vector, int16_t *out_vector,
+ int16_t gain, size_t in_vector_length,
+ int16_t right_shifts)
+{
+ // Performs vector operation: out_vector = (gain*in_vector)>>right_shifts
+ size_t i;
+ const int16_t *inptr;
+ int16_t *outptr;
+
+ inptr = in_vector;
+ outptr = out_vector;
+
+ for (i = 0; i < in_vector_length; i++) {
+ *outptr++ = WebRtcSpl_SatW32ToW16((*inptr++ * gain) >> right_shifts);
+ }
+}
+
+void WebRtcSpl_ScaleAndAddVectors(const int16_t *in1, int16_t gain1, int shift1,
+ const int16_t *in2, int16_t gain2, int shift2,
+ int16_t *out, size_t vector_length)
+{
+ // Performs vector operation: out = (gain1*in1)>>shift1 + (gain2*in2)>>shift2
+ size_t i;
+ const int16_t *in1ptr;
+ const int16_t *in2ptr;
+ int16_t *outptr;
+
+ in1ptr = in1;
+ in2ptr = in2;
+ outptr = out;
+
+ for (i = 0; i < vector_length; i++)
+ {
+ *outptr++ = (int16_t)((gain1 * *in1ptr++) >> shift1) +
+ (int16_t)((gain2 * *in2ptr++) >> shift2);
+ }
+}
+
+// C version of WebRtcSpl_ScaleAndAddVectorsWithRound() for generic platforms.
+int WebRtcSpl_ScaleAndAddVectorsWithRoundC(const int16_t* in_vector1,
+ int16_t in_vector1_scale,
+ const int16_t* in_vector2,
+ int16_t in_vector2_scale,
+ int right_shifts,
+ int16_t* out_vector,
+ size_t length) {
+ size_t i = 0;
+ int round_value = (1 << right_shifts) >> 1;
+
+ if (in_vector1 == NULL || in_vector2 == NULL || out_vector == NULL ||
+ length == 0 || right_shifts < 0) {
+ return -1;
+ }
+
+ for (i = 0; i < length; i++) {
+ out_vector[i] = (int16_t)((
+ in_vector1[i] * in_vector1_scale + in_vector2[i] * in_vector2_scale +
+ round_value) >> right_shifts);
+ }
+
+ return 0;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c
new file mode 100644
index 0000000..25bb0a1
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.c
@@ -0,0 +1,77 @@
+/*
+ * Written by Wilco Dijkstra, 1996. The following email exchange establishes the
+ * license.
+ *
+ * From: Wilco Dijkstra <Wilco.Dijkstra@ntlworld.com>
+ * Date: Fri, Jun 24, 2011 at 3:20 AM
+ * Subject: Re: sqrt routine
+ * To: Kevin Ma <kma@google.com>
+ * Hi Kevin,
+ * Thanks for asking. Those routines are public domain (originally posted to
+ * comp.sys.arm a long time ago), so you can use them freely for any purpose.
+ * Cheers,
+ * Wilco
+ *
+ * ----- Original Message -----
+ * From: "Kevin Ma" <kma@google.com>
+ * To: <Wilco.Dijkstra@ntlworld.com>
+ * Sent: Thursday, June 23, 2011 11:44 PM
+ * Subject: Fwd: sqrt routine
+ * Hi Wilco,
+ * I saw your sqrt routine from several web sites, including
+ * http://www.finesse.demon.co.uk/steven/sqrt.html.
+ * Just wonder if there's any copyright information with your Successive
+ * approximation routines, or if I can freely use it for any purpose.
+ * Thanks.
+ * Kevin
+ */
+
+// Minor modifications in code style for WebRTC, 2012.
+
+#include "webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h"
+
+/*
+ * Algorithm:
+ * Successive approximation of the equation (root + delta) ^ 2 = N
+ * until delta < 1. If delta < 1 we have the integer part of SQRT (N).
+ * Use delta = 2^i for i = 15 .. 0.
+ *
+ * Output precision is 16 bits. Note for large input values (close to
+ * 0x7FFFFFFF), bit 15 (the highest bit of the low 16-bit half word)
+ * contains the MSB information (a non-sign value). Do with caution
+ * if you need to cast the output to int16_t type.
+ *
+ * If the input value is negative, it returns 0.
+ */
+
+#define WEBRTC_SPL_SQRT_ITER(N) \
+ try1 = root + (1 << (N)); \
+ if (value >= try1 << (N)) \
+ { \
+ value -= try1 << (N); \
+ root |= 2 << (N); \
+ }
+
+int32_t WebRtcSpl_SqrtFloor(int32_t value)
+{
+ int32_t root = 0, try1;
+
+ WEBRTC_SPL_SQRT_ITER (15);
+ WEBRTC_SPL_SQRT_ITER (14);
+ WEBRTC_SPL_SQRT_ITER (13);
+ WEBRTC_SPL_SQRT_ITER (12);
+ WEBRTC_SPL_SQRT_ITER (11);
+ WEBRTC_SPL_SQRT_ITER (10);
+ WEBRTC_SPL_SQRT_ITER ( 9);
+ WEBRTC_SPL_SQRT_ITER ( 8);
+ WEBRTC_SPL_SQRT_ITER ( 7);
+ WEBRTC_SPL_SQRT_ITER ( 6);
+ WEBRTC_SPL_SQRT_ITER ( 5);
+ WEBRTC_SPL_SQRT_ITER ( 4);
+ WEBRTC_SPL_SQRT_ITER ( 3);
+ WEBRTC_SPL_SQRT_ITER ( 2);
+ WEBRTC_SPL_SQRT_ITER ( 1);
+ WEBRTC_SPL_SQRT_ITER ( 0);
+
+ return root >> 1;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h
new file mode 100644
index 0000000..eaa58e3
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/third_party/spl_sqrt_floor/spl_sqrt_floor.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <stdint.h>
+
+//
+// WebRtcSpl_SqrtFloor(...)
+//
+// Returns the square root of the input value |value|. The precision of this
+// function is rounding down integer precision, i.e., sqrt(8) gives 2 as answer.
+// If |value| is a negative number then 0 is returned.
+//
+// Algorithm:
+//
+// An iterative 4 cylce/bit routine
+//
+// Input:
+// - value : Value to calculate sqrt of
+//
+// Return value : Result of the sqrt calculation
+//
+int32_t WebRtcSpl_SqrtFloor(int32_t value);
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/include/webrtc_vad.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/include/webrtc_vad.h
new file mode 100644
index 0000000..f5bbadf
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/include/webrtc_vad.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * This header file includes the VAD API calls. Specific function calls are
+ * given below.
+ */
+
+#ifndef COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ // NOLINT
+#define COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+typedef struct WebRtcVadInst VadInst;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Creates an instance to the VAD structure.
+VadInst* WebRtcVad_Create(void);
+
+// Frees the dynamic memory of a specified VAD instance.
+//
+// - handle [i] : Pointer to VAD instance that should be freed.
+void WebRtcVad_Free(VadInst* handle);
+
+// Initializes a VAD instance.
+//
+// - handle [i/o] : Instance that should be initialized.
+//
+// returns : 0 - (OK),
+// -1 - (null pointer or Default mode could not be set).
+int WebRtcVad_Init(VadInst* handle);
+
+// Sets the VAD operating mode. A more aggressive (higher mode) VAD is more
+// restrictive in reporting speech. Put in other words the probability of being
+// speech when the VAD returns 1 is increased with increasing mode. As a
+// consequence also the missed detection rate goes up.
+//
+// - handle [i/o] : VAD instance.
+// - mode [i] : Aggressiveness mode (0, 1, 2, or 3).
+//
+// returns : 0 - (OK),
+// -1 - (null pointer, mode could not be set or the VAD instance
+// has not been initialized).
+int WebRtcVad_set_mode(VadInst* handle, int mode);
+
+// Calculates a VAD decision for the |audio_frame|. For valid sampling rates
+// frame lengths, see the description of WebRtcVad_ValidRatesAndFrameLengths().
+//
+// - handle [i/o] : VAD Instance. Needs to be initialized by
+// WebRtcVad_Init() before call.
+// - fs [i] : Sampling frequency (Hz): 8000, 16000, or 32000
+// - audio_frame [i] : Audio frame buffer.
+// - frame_length [i] : Length of audio frame buffer in number of samples.
+//
+// returns : 1 - (Active Voice),
+// 0 - (Non-active Voice),
+// -1 - (Error)
+int WebRtcVad_Process(VadInst* handle,
+ int fs,
+ const int16_t* audio_frame,
+ size_t frame_length);
+
+// Checks for valid combinations of |rate| and |frame_length|. We support 10,
+// 20 and 30 ms frames and the rates 8000, 16000 and 32000 Hz.
+//
+// - rate [i] : Sampling frequency (Hz).
+// - frame_length [i] : Speech frame buffer length in number of samples.
+//
+// returns : 0 - (valid combination), -1 - (invalid combination)
+int WebRtcVad_ValidRateAndFrameLength(int rate, size_t frame_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COMMON_AUDIO_VAD_INCLUDE_WEBRTC_VAD_H_ // NOLINT
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_core.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_core.c
new file mode 100644
index 0000000..eb336f9
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_core.c
@@ -0,0 +1,685 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/common_audio/vad/vad_core.h"
+
+#include "webrtc/rtc_base/sanitizer.h"
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+#include "webrtc/common_audio/vad/vad_filterbank.h"
+#include "webrtc/common_audio/vad/vad_gmm.h"
+#include "webrtc/common_audio/vad/vad_sp.h"
+
+// Spectrum Weighting
+static const int16_t kSpectrumWeight[kNumChannels] = { 6, 8, 10, 12, 14, 16 };
+static const int16_t kNoiseUpdateConst = 655; // Q15
+static const int16_t kSpeechUpdateConst = 6554; // Q15
+static const int16_t kBackEta = 154; // Q8
+// Minimum difference between the two models, Q5
+static const int16_t kMinimumDifference[kNumChannels] = {
+ 544, 544, 576, 576, 576, 576 };
+// Upper limit of mean value for speech model, Q7
+static const int16_t kMaximumSpeech[kNumChannels] = {
+ 11392, 11392, 11520, 11520, 11520, 11520 };
+// Minimum value for mean value
+static const int16_t kMinimumMean[kNumGaussians] = { 640, 768 };
+// Upper limit of mean value for noise model, Q7
+static const int16_t kMaximumNoise[kNumChannels] = {
+ 9216, 9088, 8960, 8832, 8704, 8576 };
+// Start values for the Gaussian models, Q7
+// Weights for the two Gaussians for the six channels (noise)
+static const int16_t kNoiseDataWeights[kTableSize] = {
+ 34, 62, 72, 66, 53, 25, 94, 66, 56, 62, 75, 103 };
+// Weights for the two Gaussians for the six channels (speech)
+static const int16_t kSpeechDataWeights[kTableSize] = {
+ 48, 82, 45, 87, 50, 47, 80, 46, 83, 41, 78, 81 };
+// Means for the two Gaussians for the six channels (noise)
+static const int16_t kNoiseDataMeans[kTableSize] = {
+ 6738, 4892, 7065, 6715, 6771, 3369, 7646, 3863, 7820, 7266, 5020, 4362 };
+// Means for the two Gaussians for the six channels (speech)
+static const int16_t kSpeechDataMeans[kTableSize] = {
+ 8306, 10085, 10078, 11823, 11843, 6309, 9473, 9571, 10879, 7581, 8180, 7483
+};
+// Stds for the two Gaussians for the six channels (noise)
+static const int16_t kNoiseDataStds[kTableSize] = {
+ 378, 1064, 493, 582, 688, 593, 474, 697, 475, 688, 421, 455 };
+// Stds for the two Gaussians for the six channels (speech)
+static const int16_t kSpeechDataStds[kTableSize] = {
+ 555, 505, 567, 524, 585, 1231, 509, 828, 492, 1540, 1079, 850 };
+
+// Constants used in GmmProbability().
+//
+// Maximum number of counted speech (VAD = 1) frames in a row.
+static const int16_t kMaxSpeechFrames = 6;
+// Minimum standard deviation for both speech and noise.
+static const int16_t kMinStd = 384;
+
+// Constants in WebRtcVad_InitCore().
+// Default aggressiveness mode.
+static const short kDefaultMode = 0;
+static const int kInitCheck = 42;
+
+// Constants used in WebRtcVad_set_mode_core().
+//
+// Thresholds for different frame lengths (10 ms, 20 ms and 30 ms).
+//
+// Mode 0, Quality.
+static const int16_t kOverHangMax1Q[3] = { 8, 4, 3 };
+static const int16_t kOverHangMax2Q[3] = { 14, 7, 5 };
+static const int16_t kLocalThresholdQ[3] = { 24, 21, 24 };
+static const int16_t kGlobalThresholdQ[3] = { 57, 48, 57 };
+// Mode 1, Low bitrate.
+static const int16_t kOverHangMax1LBR[3] = { 8, 4, 3 };
+static const int16_t kOverHangMax2LBR[3] = { 14, 7, 5 };
+static const int16_t kLocalThresholdLBR[3] = { 37, 32, 37 };
+static const int16_t kGlobalThresholdLBR[3] = { 100, 80, 100 };
+// Mode 2, Aggressive.
+static const int16_t kOverHangMax1AGG[3] = { 6, 3, 2 };
+static const int16_t kOverHangMax2AGG[3] = { 9, 5, 3 };
+static const int16_t kLocalThresholdAGG[3] = { 82, 78, 82 };
+static const int16_t kGlobalThresholdAGG[3] = { 285, 260, 285 };
+// Mode 3, Very aggressive.
+static const int16_t kOverHangMax1VAG[3] = { 6, 3, 2 };
+static const int16_t kOverHangMax2VAG[3] = { 9, 5, 3 };
+static const int16_t kLocalThresholdVAG[3] = { 94, 94, 94 };
+static const int16_t kGlobalThresholdVAG[3] = { 1100, 1050, 1100 };
+
+// Calculates the weighted average w.r.t. number of Gaussians. The |data| are
+// updated with an |offset| before averaging.
+//
+// - data [i/o] : Data to average.
+// - offset [i] : An offset added to |data|.
+// - weights [i] : Weights used for averaging.
+//
+// returns : The weighted average.
+static int32_t WeightedAverage(int16_t* data, int16_t offset,
+ const int16_t* weights) {
+ int k;
+ int32_t weighted_average = 0;
+
+ for (k = 0; k < kNumGaussians; k++) {
+ data[k * kNumChannels] += offset;
+ weighted_average += data[k * kNumChannels] * weights[k * kNumChannels];
+ }
+ return weighted_average;
+}
+
+// An s16 x s32 -> s32 multiplication that's allowed to overflow. (It's still
+// undefined behavior, so not a good idea; this just makes UBSan ignore the
+// violation, so that our old code can continue to do what it's always been
+// doing.)
+static inline int32_t RTC_NO_SANITIZE("signed-integer-overflow")
+ OverflowingMulS16ByS32ToS32(int16_t a, int32_t b) {
+ return a * b;
+}
+
+// Calculates the probabilities for both speech and background noise using
+// Gaussian Mixture Models (GMM). A hypothesis-test is performed to decide which
+// type of signal is most probable.
+//
+// - self [i/o] : Pointer to VAD instance
+// - features [i] : Feature vector of length |kNumChannels|
+// = log10(energy in frequency band)
+// - total_power [i] : Total power in audio frame.
+// - frame_length [i] : Number of input samples
+//
+// - returns : the VAD decision (0 - noise, 1 - speech).
+static int16_t GmmProbability(VadInstT* self, int16_t* features,
+ int16_t total_power, size_t frame_length) {
+ int channel, k;
+ int16_t feature_minimum;
+ int16_t h0, h1;
+ int16_t log_likelihood_ratio;
+ int16_t vadflag = 0;
+ int16_t shifts_h0, shifts_h1;
+ int16_t tmp_s16, tmp1_s16, tmp2_s16;
+ int16_t diff;
+ int gaussian;
+ int16_t nmk, nmk2, nmk3, smk, smk2, nsk, ssk;
+ int16_t delt, ndelt;
+ int16_t maxspe, maxmu;
+ int16_t deltaN[kTableSize], deltaS[kTableSize];
+ int16_t ngprvec[kTableSize] = { 0 }; // Conditional probability = 0.
+ int16_t sgprvec[kTableSize] = { 0 }; // Conditional probability = 0.
+ int32_t h0_test, h1_test;
+ int32_t tmp1_s32, tmp2_s32;
+ int32_t sum_log_likelihood_ratios = 0;
+ int32_t noise_global_mean, speech_global_mean;
+ int32_t noise_probability[kNumGaussians], speech_probability[kNumGaussians];
+ int16_t overhead1, overhead2, individualTest, totalTest;
+
+ // Set various thresholds based on frame lengths (80, 160 or 240 samples).
+ if (frame_length == 80) {
+ overhead1 = self->over_hang_max_1[0];
+ overhead2 = self->over_hang_max_2[0];
+ individualTest = self->individual[0];
+ totalTest = self->total[0];
+ } else if (frame_length == 160) {
+ overhead1 = self->over_hang_max_1[1];
+ overhead2 = self->over_hang_max_2[1];
+ individualTest = self->individual[1];
+ totalTest = self->total[1];
+ } else {
+ overhead1 = self->over_hang_max_1[2];
+ overhead2 = self->over_hang_max_2[2];
+ individualTest = self->individual[2];
+ totalTest = self->total[2];
+ }
+
+ if (total_power > kMinEnergy) {
+ // The signal power of current frame is large enough for processing. The
+ // processing consists of two parts:
+ // 1) Calculating the likelihood of speech and thereby a VAD decision.
+ // 2) Updating the underlying model, w.r.t., the decision made.
+
+ // The detection scheme is an LRT with hypothesis
+ // H0: Noise
+ // H1: Speech
+ //
+ // We combine a global LRT with local tests, for each frequency sub-band,
+ // here defined as |channel|.
+ for (channel = 0; channel < kNumChannels; channel++) {
+ // For each channel we model the probability with a GMM consisting of
+ // |kNumGaussians|, with different means and standard deviations depending
+ // on H0 or H1.
+ h0_test = 0;
+ h1_test = 0;
+ for (k = 0; k < kNumGaussians; k++) {
+ gaussian = channel + k * kNumChannels;
+ // Probability under H0, that is, probability of frame being noise.
+ // Value given in Q27 = Q7 * Q20.
+ tmp1_s32 = WebRtcVad_GaussianProbability(features[channel],
+ self->noise_means[gaussian],
+ self->noise_stds[gaussian],
+ &deltaN[gaussian]);
+ noise_probability[k] = kNoiseDataWeights[gaussian] * tmp1_s32;
+ h0_test += noise_probability[k]; // Q27
+
+ // Probability under H1, that is, probability of frame being speech.
+ // Value given in Q27 = Q7 * Q20.
+ tmp1_s32 = WebRtcVad_GaussianProbability(features[channel],
+ self->speech_means[gaussian],
+ self->speech_stds[gaussian],
+ &deltaS[gaussian]);
+ speech_probability[k] = kSpeechDataWeights[gaussian] * tmp1_s32;
+ h1_test += speech_probability[k]; // Q27
+ }
+
+ // Calculate the log likelihood ratio: log2(Pr{X|H1} / Pr{X|H1}).
+ // Approximation:
+ // log2(Pr{X|H1} / Pr{X|H1}) = log2(Pr{X|H1}*2^Q) - log2(Pr{X|H1}*2^Q)
+ // = log2(h1_test) - log2(h0_test)
+ // = log2(2^(31-shifts_h1)*(1+b1))
+ // - log2(2^(31-shifts_h0)*(1+b0))
+ // = shifts_h0 - shifts_h1
+ // + log2(1+b1) - log2(1+b0)
+ // ~= shifts_h0 - shifts_h1
+ //
+ // Note that b0 and b1 are values less than 1, hence, 0 <= log2(1+b0) < 1.
+ // Further, b0 and b1 are independent and on the average the two terms
+ // cancel.
+ shifts_h0 = WebRtcSpl_NormW32(h0_test);
+ shifts_h1 = WebRtcSpl_NormW32(h1_test);
+ if (h0_test == 0) {
+ shifts_h0 = 31;
+ }
+ if (h1_test == 0) {
+ shifts_h1 = 31;
+ }
+ log_likelihood_ratio = shifts_h0 - shifts_h1;
+
+ // Update |sum_log_likelihood_ratios| with spectrum weighting. This is
+ // used for the global VAD decision.
+ sum_log_likelihood_ratios +=
+ (int32_t) (log_likelihood_ratio * kSpectrumWeight[channel]);
+
+ // Local VAD decision.
+ if ((log_likelihood_ratio * 4) > individualTest) {
+ vadflag = 1;
+ }
+
+ // TODO(bjornv): The conditional probabilities below are applied on the
+ // hard coded number of Gaussians set to two. Find a way to generalize.
+ // Calculate local noise probabilities used later when updating the GMM.
+ h0 = (int16_t) (h0_test >> 12); // Q15
+ if (h0 > 0) {
+ // High probability of noise. Assign conditional probabilities for each
+ // Gaussian in the GMM.
+ tmp1_s32 = (noise_probability[0] & 0xFFFFF000) << 2; // Q29
+ ngprvec[channel] = (int16_t) WebRtcSpl_DivW32W16(tmp1_s32, h0); // Q14
+ ngprvec[channel + kNumChannels] = 16384 - ngprvec[channel];
+ } else {
+ // Low noise probability. Assign conditional probability 1 to the first
+ // Gaussian and 0 to the rest (which is already set at initialization).
+ ngprvec[channel] = 16384;
+ }
+
+ // Calculate local speech probabilities used later when updating the GMM.
+ h1 = (int16_t) (h1_test >> 12); // Q15
+ if (h1 > 0) {
+ // High probability of speech. Assign conditional probabilities for each
+ // Gaussian in the GMM. Otherwise use the initialized values, i.e., 0.
+ tmp1_s32 = (speech_probability[0] & 0xFFFFF000) << 2; // Q29
+ sgprvec[channel] = (int16_t) WebRtcSpl_DivW32W16(tmp1_s32, h1); // Q14
+ sgprvec[channel + kNumChannels] = 16384 - sgprvec[channel];
+ }
+ }
+
+ // Make a global VAD decision.
+ vadflag |= (sum_log_likelihood_ratios >= totalTest);
+
+ // Update the model parameters.
+ maxspe = 12800;
+ for (channel = 0; channel < kNumChannels; channel++) {
+
+ // Get minimum value in past which is used for long term correction in Q4.
+ feature_minimum = WebRtcVad_FindMinimum(self, features[channel], channel);
+
+ // Compute the "global" mean, that is the sum of the two means weighted.
+ noise_global_mean = WeightedAverage(&self->noise_means[channel], 0,
+ &kNoiseDataWeights[channel]);
+ tmp1_s16 = (int16_t) (noise_global_mean >> 6); // Q8
+
+ for (k = 0; k < kNumGaussians; k++) {
+ gaussian = channel + k * kNumChannels;
+
+ nmk = self->noise_means[gaussian];
+ smk = self->speech_means[gaussian];
+ nsk = self->noise_stds[gaussian];
+ ssk = self->speech_stds[gaussian];
+
+ // Update noise mean vector if the frame consists of noise only.
+ nmk2 = nmk;
+ if (!vadflag) {
+ // deltaN = (x-mu)/sigma^2
+ // ngprvec[k] = |noise_probability[k]| /
+ // (|noise_probability[0]| + |noise_probability[1]|)
+
+ // (Q14 * Q11 >> 11) = Q14.
+ delt = (int16_t)((ngprvec[gaussian] * deltaN[gaussian]) >> 11);
+ // Q7 + (Q14 * Q15 >> 22) = Q7.
+ nmk2 = nmk + (int16_t)((delt * kNoiseUpdateConst) >> 22);
+ }
+
+ // Long term correction of the noise mean.
+ // Q8 - Q8 = Q8.
+ ndelt = (feature_minimum << 4) - tmp1_s16;
+ // Q7 + (Q8 * Q8) >> 9 = Q7.
+ nmk3 = nmk2 + (int16_t)((ndelt * kBackEta) >> 9);
+
+ // Control that the noise mean does not drift to much.
+ tmp_s16 = (int16_t) ((k + 5) << 7);
+ if (nmk3 < tmp_s16) {
+ nmk3 = tmp_s16;
+ }
+ tmp_s16 = (int16_t) ((72 + k - channel) << 7);
+ if (nmk3 > tmp_s16) {
+ nmk3 = tmp_s16;
+ }
+ self->noise_means[gaussian] = nmk3;
+
+ if (vadflag) {
+ // Update speech mean vector:
+ // |deltaS| = (x-mu)/sigma^2
+ // sgprvec[k] = |speech_probability[k]| /
+ // (|speech_probability[0]| + |speech_probability[1]|)
+
+ // (Q14 * Q11) >> 11 = Q14.
+ delt = (int16_t)((sgprvec[gaussian] * deltaS[gaussian]) >> 11);
+ // Q14 * Q15 >> 21 = Q8.
+ tmp_s16 = (int16_t)((delt * kSpeechUpdateConst) >> 21);
+ // Q7 + (Q8 >> 1) = Q7. With rounding.
+ smk2 = smk + ((tmp_s16 + 1) >> 1);
+
+ // Control that the speech mean does not drift to much.
+ maxmu = maxspe + 640;
+ if (smk2 < kMinimumMean[k]) {
+ smk2 = kMinimumMean[k];
+ }
+ if (smk2 > maxmu) {
+ smk2 = maxmu;
+ }
+ self->speech_means[gaussian] = smk2; // Q7.
+
+ // (Q7 >> 3) = Q4. With rounding.
+ tmp_s16 = ((smk + 4) >> 3);
+
+ tmp_s16 = features[channel] - tmp_s16; // Q4
+ // (Q11 * Q4 >> 3) = Q12.
+ tmp1_s32 = (deltaS[gaussian] * tmp_s16) >> 3;
+ tmp2_s32 = tmp1_s32 - 4096;
+ tmp_s16 = sgprvec[gaussian] >> 2;
+ // (Q14 >> 2) * Q12 = Q24.
+ tmp1_s32 = tmp_s16 * tmp2_s32;
+
+ tmp2_s32 = tmp1_s32 >> 4; // Q20
+
+ // 0.1 * Q20 / Q7 = Q13.
+ if (tmp2_s32 > 0) {
+ tmp_s16 = (int16_t) WebRtcSpl_DivW32W16(tmp2_s32, ssk * 10);
+ } else {
+ tmp_s16 = (int16_t) WebRtcSpl_DivW32W16(-tmp2_s32, ssk * 10);
+ tmp_s16 = -tmp_s16;
+ }
+ // Divide by 4 giving an update factor of 0.025 (= 0.1 / 4).
+ // Note that division by 4 equals shift by 2, hence,
+ // (Q13 >> 8) = (Q13 >> 6) / 4 = Q7.
+ tmp_s16 += 128; // Rounding.
+ ssk += (tmp_s16 >> 8);
+ if (ssk < kMinStd) {
+ ssk = kMinStd;
+ }
+ self->speech_stds[gaussian] = ssk;
+ } else {
+ // Update GMM variance vectors.
+ // deltaN * (features[channel] - nmk) - 1
+ // Q4 - (Q7 >> 3) = Q4.
+ tmp_s16 = features[channel] - (nmk >> 3);
+ // (Q11 * Q4 >> 3) = Q12.
+ tmp1_s32 = (deltaN[gaussian] * tmp_s16) >> 3;
+ tmp1_s32 -= 4096;
+
+ // (Q14 >> 2) * Q12 = Q24.
+ tmp_s16 = (ngprvec[gaussian] + 2) >> 2;
+ tmp2_s32 = OverflowingMulS16ByS32ToS32(tmp_s16, tmp1_s32);
+ // Q20 * approx 0.001 (2^-10=0.0009766), hence,
+ // (Q24 >> 14) = (Q24 >> 4) / 2^10 = Q20.
+ tmp1_s32 = tmp2_s32 >> 14;
+
+ // Q20 / Q7 = Q13.
+ if (tmp1_s32 > 0) {
+ tmp_s16 = (int16_t) WebRtcSpl_DivW32W16(tmp1_s32, nsk);
+ } else {
+ tmp_s16 = (int16_t) WebRtcSpl_DivW32W16(-tmp1_s32, nsk);
+ tmp_s16 = -tmp_s16;
+ }
+ tmp_s16 += 32; // Rounding
+ nsk += tmp_s16 >> 6; // Q13 >> 6 = Q7.
+ if (nsk < kMinStd) {
+ nsk = kMinStd;
+ }
+ self->noise_stds[gaussian] = nsk;
+ }
+ }
+
+ // Separate models if they are too close.
+ // |noise_global_mean| in Q14 (= Q7 * Q7).
+ noise_global_mean = WeightedAverage(&self->noise_means[channel], 0,
+ &kNoiseDataWeights[channel]);
+
+ // |speech_global_mean| in Q14 (= Q7 * Q7).
+ speech_global_mean = WeightedAverage(&self->speech_means[channel], 0,
+ &kSpeechDataWeights[channel]);
+
+ // |diff| = "global" speech mean - "global" noise mean.
+ // (Q14 >> 9) - (Q14 >> 9) = Q5.
+ diff = (int16_t) (speech_global_mean >> 9) -
+ (int16_t) (noise_global_mean >> 9);
+ if (diff < kMinimumDifference[channel]) {
+ tmp_s16 = kMinimumDifference[channel] - diff;
+
+ // |tmp1_s16| = ~0.8 * (kMinimumDifference - diff) in Q7.
+ // |tmp2_s16| = ~0.2 * (kMinimumDifference - diff) in Q7.
+ tmp1_s16 = (int16_t)((13 * tmp_s16) >> 2);
+ tmp2_s16 = (int16_t)((3 * tmp_s16) >> 2);
+
+ // Move Gaussian means for speech model by |tmp1_s16| and update
+ // |speech_global_mean|. Note that |self->speech_means[channel]| is
+ // changed after the call.
+ speech_global_mean = WeightedAverage(&self->speech_means[channel],
+ tmp1_s16,
+ &kSpeechDataWeights[channel]);
+
+ // Move Gaussian means for noise model by -|tmp2_s16| and update
+ // |noise_global_mean|. Note that |self->noise_means[channel]| is
+ // changed after the call.
+ noise_global_mean = WeightedAverage(&self->noise_means[channel],
+ -tmp2_s16,
+ &kNoiseDataWeights[channel]);
+ }
+
+ // Control that the speech & noise means do not drift to much.
+ maxspe = kMaximumSpeech[channel];
+ tmp2_s16 = (int16_t) (speech_global_mean >> 7);
+ if (tmp2_s16 > maxspe) {
+ // Upper limit of speech model.
+ tmp2_s16 -= maxspe;
+
+ for (k = 0; k < kNumGaussians; k++) {
+ self->speech_means[channel + k * kNumChannels] -= tmp2_s16;
+ }
+ }
+
+ tmp2_s16 = (int16_t) (noise_global_mean >> 7);
+ if (tmp2_s16 > kMaximumNoise[channel]) {
+ tmp2_s16 -= kMaximumNoise[channel];
+
+ for (k = 0; k < kNumGaussians; k++) {
+ self->noise_means[channel + k * kNumChannels] -= tmp2_s16;
+ }
+ }
+ }
+ self->frame_counter++;
+ }
+
+ // Smooth with respect to transition hysteresis.
+ if (!vadflag) {
+ if (self->over_hang > 0) {
+ vadflag = 2 + self->over_hang;
+ self->over_hang--;
+ }
+ self->num_of_speech = 0;
+ } else {
+ self->num_of_speech++;
+ if (self->num_of_speech > kMaxSpeechFrames) {
+ self->num_of_speech = kMaxSpeechFrames;
+ self->over_hang = overhead2;
+ } else {
+ self->over_hang = overhead1;
+ }
+ }
+ return vadflag;
+}
+
+// Initialize the VAD. Set aggressiveness mode to default value.
+int WebRtcVad_InitCore(VadInstT* self) {
+ int i;
+
+ if (self == NULL) {
+ return -1;
+ }
+
+ // Initialization of general struct variables.
+ self->vad = 1; // Speech active (=1).
+ self->frame_counter = 0;
+ self->over_hang = 0;
+ self->num_of_speech = 0;
+
+ // Initialization of downsampling filter state.
+ memset(self->downsampling_filter_states, 0,
+ sizeof(self->downsampling_filter_states));
+
+ // Initialization of 48 to 8 kHz downsampling.
+ WebRtcSpl_ResetResample48khzTo8khz(&self->state_48_to_8);
+
+ // Read initial PDF parameters.
+ for (i = 0; i < kTableSize; i++) {
+ self->noise_means[i] = kNoiseDataMeans[i];
+ self->speech_means[i] = kSpeechDataMeans[i];
+ self->noise_stds[i] = kNoiseDataStds[i];
+ self->speech_stds[i] = kSpeechDataStds[i];
+ }
+
+ // Initialize Index and Minimum value vectors.
+ for (i = 0; i < 16 * kNumChannels; i++) {
+ self->low_value_vector[i] = 10000;
+ self->index_vector[i] = 0;
+ }
+
+ // Initialize splitting filter states.
+ memset(self->upper_state, 0, sizeof(self->upper_state));
+ memset(self->lower_state, 0, sizeof(self->lower_state));
+
+ // Initialize high pass filter states.
+ memset(self->hp_filter_state, 0, sizeof(self->hp_filter_state));
+
+ // Initialize mean value memory, for WebRtcVad_FindMinimum().
+ for (i = 0; i < kNumChannels; i++) {
+ self->mean_value[i] = 1600;
+ }
+
+ // Set aggressiveness mode to default (=|kDefaultMode|).
+ if (WebRtcVad_set_mode_core(self, kDefaultMode) != 0) {
+ return -1;
+ }
+
+ self->init_flag = kInitCheck;
+
+ return 0;
+}
+
+// Set aggressiveness mode
+int WebRtcVad_set_mode_core(VadInstT* self, int mode) {
+ int return_value = 0;
+
+ switch (mode) {
+ case 0:
+ // Quality mode.
+ memcpy(self->over_hang_max_1, kOverHangMax1Q,
+ sizeof(self->over_hang_max_1));
+ memcpy(self->over_hang_max_2, kOverHangMax2Q,
+ sizeof(self->over_hang_max_2));
+ memcpy(self->individual, kLocalThresholdQ,
+ sizeof(self->individual));
+ memcpy(self->total, kGlobalThresholdQ,
+ sizeof(self->total));
+ break;
+ case 1:
+ // Low bitrate mode.
+ memcpy(self->over_hang_max_1, kOverHangMax1LBR,
+ sizeof(self->over_hang_max_1));
+ memcpy(self->over_hang_max_2, kOverHangMax2LBR,
+ sizeof(self->over_hang_max_2));
+ memcpy(self->individual, kLocalThresholdLBR,
+ sizeof(self->individual));
+ memcpy(self->total, kGlobalThresholdLBR,
+ sizeof(self->total));
+ break;
+ case 2:
+ // Aggressive mode.
+ memcpy(self->over_hang_max_1, kOverHangMax1AGG,
+ sizeof(self->over_hang_max_1));
+ memcpy(self->over_hang_max_2, kOverHangMax2AGG,
+ sizeof(self->over_hang_max_2));
+ memcpy(self->individual, kLocalThresholdAGG,
+ sizeof(self->individual));
+ memcpy(self->total, kGlobalThresholdAGG,
+ sizeof(self->total));
+ break;
+ case 3:
+ // Very aggressive mode.
+ memcpy(self->over_hang_max_1, kOverHangMax1VAG,
+ sizeof(self->over_hang_max_1));
+ memcpy(self->over_hang_max_2, kOverHangMax2VAG,
+ sizeof(self->over_hang_max_2));
+ memcpy(self->individual, kLocalThresholdVAG,
+ sizeof(self->individual));
+ memcpy(self->total, kGlobalThresholdVAG,
+ sizeof(self->total));
+ break;
+ default:
+ return_value = -1;
+ break;
+ }
+
+ return return_value;
+}
+
+// Calculate VAD decision by first extracting feature values and then calculate
+// probability for both speech and background noise.
+
+int WebRtcVad_CalcVad48khz(VadInstT* inst, const int16_t* speech_frame,
+ size_t frame_length) {
+ int vad;
+ size_t i;
+ int16_t speech_nb[240]; // 30 ms in 8 kHz.
+ // |tmp_mem| is a temporary memory used by resample function, length is
+ // frame length in 10 ms (480 samples) + 256 extra.
+ int32_t tmp_mem[480 + 256] = { 0 };
+ const size_t kFrameLen10ms48khz = 480;
+ const size_t kFrameLen10ms8khz = 80;
+ size_t num_10ms_frames = frame_length / kFrameLen10ms48khz;
+
+ for (i = 0; i < num_10ms_frames; i++) {
+ WebRtcSpl_Resample48khzTo8khz(speech_frame,
+ &speech_nb[i * kFrameLen10ms8khz],
+ &inst->state_48_to_8,
+ tmp_mem);
+ }
+
+ // Do VAD on an 8 kHz signal
+ vad = WebRtcVad_CalcVad8khz(inst, speech_nb, frame_length / 6);
+
+ return vad;
+}
+
+int WebRtcVad_CalcVad32khz(VadInstT* inst, const int16_t* speech_frame,
+ size_t frame_length)
+{
+ size_t len;
+ int vad;
+ int16_t speechWB[480]; // Downsampled speech frame: 960 samples (30ms in SWB)
+ int16_t speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB)
+
+
+ // Downsample signal 32->16->8 before doing VAD
+ WebRtcVad_Downsampling(speech_frame, speechWB, &(inst->downsampling_filter_states[2]),
+ frame_length);
+ len = frame_length / 2;
+
+ WebRtcVad_Downsampling(speechWB, speechNB, inst->downsampling_filter_states, len);
+ len /= 2;
+
+ // Do VAD on an 8 kHz signal
+ vad = WebRtcVad_CalcVad8khz(inst, speechNB, len);
+
+ return vad;
+}
+
+int WebRtcVad_CalcVad16khz(VadInstT* inst, const int16_t* speech_frame,
+ size_t frame_length)
+{
+ size_t len;
+ int vad;
+ int16_t speechNB[240]; // Downsampled speech frame: 480 samples (30ms in WB)
+
+ // Wideband: Downsample signal before doing VAD
+ WebRtcVad_Downsampling(speech_frame, speechNB, inst->downsampling_filter_states,
+ frame_length);
+
+ len = frame_length / 2;
+ vad = WebRtcVad_CalcVad8khz(inst, speechNB, len);
+
+ return vad;
+}
+
+int WebRtcVad_CalcVad8khz(VadInstT* inst, const int16_t* speech_frame,
+ size_t frame_length)
+{
+ int16_t feature_vector[kNumChannels], total_power;
+
+ // Get power in the bands
+ total_power = WebRtcVad_CalculateFeatures(inst, speech_frame, frame_length,
+ feature_vector);
+
+ // Make a VAD
+ inst->vad = GmmProbability(inst, feature_vector, total_power, frame_length);
+
+ return inst->vad;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_core.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_core.h
new file mode 100644
index 0000000..8f0cfc0
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_core.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * This header file includes the descriptions of the core VAD calls.
+ */
+
+#ifndef COMMON_AUDIO_VAD_VAD_CORE_H_
+#define COMMON_AUDIO_VAD_VAD_CORE_H_
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+enum { kNumChannels = 6 }; // Number of frequency bands (named channels).
+enum { kNumGaussians = 2 }; // Number of Gaussians per channel in the GMM.
+enum { kTableSize = kNumChannels * kNumGaussians };
+enum { kMinEnergy = 10 }; // Minimum energy required to trigger audio signal.
+
+typedef struct VadInstT_ {
+ int vad;
+ int32_t downsampling_filter_states[4];
+ WebRtcSpl_State48khzTo8khz state_48_to_8;
+ int16_t noise_means[kTableSize];
+ int16_t speech_means[kTableSize];
+ int16_t noise_stds[kTableSize];
+ int16_t speech_stds[kTableSize];
+ // TODO(bjornv): Change to |frame_count|.
+ int32_t frame_counter;
+ int16_t over_hang; // Over Hang
+ int16_t num_of_speech;
+ // TODO(bjornv): Change to |age_vector|.
+ int16_t index_vector[16 * kNumChannels];
+ int16_t low_value_vector[16 * kNumChannels];
+ // TODO(bjornv): Change to |median|.
+ int16_t mean_value[kNumChannels];
+ int16_t upper_state[5];
+ int16_t lower_state[5];
+ int16_t hp_filter_state[4];
+ int16_t over_hang_max_1[3];
+ int16_t over_hang_max_2[3];
+ int16_t individual[3];
+ int16_t total[3];
+
+ int init_flag;
+} VadInstT;
+
+// Initializes the core VAD component. The default aggressiveness mode is
+// controlled by |kDefaultMode| in vad_core.c.
+//
+// - self [i/o] : Instance that should be initialized
+//
+// returns : 0 (OK), -1 (null pointer in or if the default mode can't be
+// set)
+int WebRtcVad_InitCore(VadInstT* self);
+
+/****************************************************************************
+ * WebRtcVad_set_mode_core(...)
+ *
+ * This function changes the VAD settings
+ *
+ * Input:
+ * - inst : VAD instance
+ * - mode : Aggressiveness degree
+ * 0 (High quality) - 3 (Highly aggressive)
+ *
+ * Output:
+ * - inst : Changed instance
+ *
+ * Return value : 0 - Ok
+ * -1 - Error
+ */
+
+int WebRtcVad_set_mode_core(VadInstT* self, int mode);
+
+/****************************************************************************
+ * WebRtcVad_CalcVad48khz(...)
+ * WebRtcVad_CalcVad32khz(...)
+ * WebRtcVad_CalcVad16khz(...)
+ * WebRtcVad_CalcVad8khz(...)
+ *
+ * Calculate probability for active speech and make VAD decision.
+ *
+ * Input:
+ * - inst : Instance that should be initialized
+ * - speech_frame : Input speech frame
+ * - frame_length : Number of input samples
+ *
+ * Output:
+ * - inst : Updated filter states etc.
+ *
+ * Return value : VAD decision
+ * 0 - No active speech
+ * 1-6 - Active speech
+ */
+int WebRtcVad_CalcVad48khz(VadInstT* inst,
+ const int16_t* speech_frame,
+ size_t frame_length);
+int WebRtcVad_CalcVad32khz(VadInstT* inst,
+ const int16_t* speech_frame,
+ size_t frame_length);
+int WebRtcVad_CalcVad16khz(VadInstT* inst,
+ const int16_t* speech_frame,
+ size_t frame_length);
+int WebRtcVad_CalcVad8khz(VadInstT* inst,
+ const int16_t* speech_frame,
+ size_t frame_length);
+
+#endif // COMMON_AUDIO_VAD_VAD_CORE_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_filterbank.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_filterbank.c
new file mode 100644
index 0000000..7d25e2a
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_filterbank.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/common_audio/vad/vad_filterbank.h"
+
+#include "webrtc/rtc_base/checks.h"
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+// Constants used in LogOfEnergy().
+static const int16_t kLogConst = 24660; // 160*log10(2) in Q9.
+static const int16_t kLogEnergyIntPart = 14336; // 14 in Q10
+
+// Coefficients used by HighPassFilter, Q14.
+static const int16_t kHpZeroCoefs[3] = { 6631, -13262, 6631 };
+static const int16_t kHpPoleCoefs[3] = { 16384, -7756, 5620 };
+
+// Allpass filter coefficients, upper and lower, in Q15.
+// Upper: 0.64, Lower: 0.17
+static const int16_t kAllPassCoefsQ15[2] = { 20972, 5571 };
+
+// Adjustment for division with two in SplitFilter.
+static const int16_t kOffsetVector[6] = { 368, 368, 272, 176, 176, 176 };
+
+// High pass filtering, with a cut-off frequency at 80 Hz, if the |data_in| is
+// sampled at 500 Hz.
+//
+// - data_in [i] : Input audio data sampled at 500 Hz.
+// - data_length [i] : Length of input and output data.
+// - filter_state [i/o] : State of the filter.
+// - data_out [o] : Output audio data in the frequency interval
+// 80 - 250 Hz.
+static void HighPassFilter(const int16_t* data_in, size_t data_length,
+ int16_t* filter_state, int16_t* data_out) {
+ size_t i;
+ const int16_t* in_ptr = data_in;
+ int16_t* out_ptr = data_out;
+ int32_t tmp32 = 0;
+
+
+ // The sum of the absolute values of the impulse response:
+ // The zero/pole-filter has a max amplification of a single sample of: 1.4546
+ // Impulse response: 0.4047 -0.6179 -0.0266 0.1993 0.1035 -0.0194
+ // The all-zero section has a max amplification of a single sample of: 1.6189
+ // Impulse response: 0.4047 -0.8094 0.4047 0 0 0
+ // The all-pole section has a max amplification of a single sample of: 1.9931
+ // Impulse response: 1.0000 0.4734 -0.1189 -0.2187 -0.0627 0.04532
+
+ for (i = 0; i < data_length; i++) {
+ // All-zero section (filter coefficients in Q14).
+ tmp32 = kHpZeroCoefs[0] * *in_ptr;
+ tmp32 += kHpZeroCoefs[1] * filter_state[0];
+ tmp32 += kHpZeroCoefs[2] * filter_state[1];
+ filter_state[1] = filter_state[0];
+ filter_state[0] = *in_ptr++;
+
+ // All-pole section (filter coefficients in Q14).
+ tmp32 -= kHpPoleCoefs[1] * filter_state[2];
+ tmp32 -= kHpPoleCoefs[2] * filter_state[3];
+ filter_state[3] = filter_state[2];
+ filter_state[2] = (int16_t) (tmp32 >> 14);
+ *out_ptr++ = filter_state[2];
+ }
+}
+
+// All pass filtering of |data_in|, used before splitting the signal into two
+// frequency bands (low pass vs high pass).
+// Note that |data_in| and |data_out| can NOT correspond to the same address.
+//
+// - data_in [i] : Input audio signal given in Q0.
+// - data_length [i] : Length of input and output data.
+// - filter_coefficient [i] : Given in Q15.
+// - filter_state [i/o] : State of the filter given in Q(-1).
+// - data_out [o] : Output audio signal given in Q(-1).
+static void AllPassFilter(const int16_t* data_in, size_t data_length,
+ int16_t filter_coefficient, int16_t* filter_state,
+ int16_t* data_out) {
+ // The filter can only cause overflow (in the w16 output variable)
+ // if more than 4 consecutive input numbers are of maximum value and
+ // has the the same sign as the impulse responses first taps.
+ // First 6 taps of the impulse response:
+ // 0.6399 0.5905 -0.3779 0.2418 -0.1547 0.0990
+
+ size_t i;
+ int16_t tmp16 = 0;
+ int32_t tmp32 = 0;
+ int32_t state32 = ((int32_t) (*filter_state) * (1 << 16)); // Q15
+
+ for (i = 0; i < data_length; i++) {
+ tmp32 = state32 + filter_coefficient * *data_in;
+ tmp16 = (int16_t) (tmp32 >> 16); // Q(-1)
+ *data_out++ = tmp16;
+ state32 = (*data_in * (1 << 14)) - filter_coefficient * tmp16; // Q14
+ state32 *= 2; // Q15.
+ data_in += 2;
+ }
+
+ *filter_state = (int16_t) (state32 >> 16); // Q(-1)
+}
+
+// Splits |data_in| into |hp_data_out| and |lp_data_out| corresponding to
+// an upper (high pass) part and a lower (low pass) part respectively.
+//
+// - data_in [i] : Input audio data to be split into two frequency bands.
+// - data_length [i] : Length of |data_in|.
+// - upper_state [i/o] : State of the upper filter, given in Q(-1).
+// - lower_state [i/o] : State of the lower filter, given in Q(-1).
+// - hp_data_out [o] : Output audio data of the upper half of the spectrum.
+// The length is |data_length| / 2.
+// - lp_data_out [o] : Output audio data of the lower half of the spectrum.
+// The length is |data_length| / 2.
+static void SplitFilter(const int16_t* data_in, size_t data_length,
+ int16_t* upper_state, int16_t* lower_state,
+ int16_t* hp_data_out, int16_t* lp_data_out) {
+ size_t i;
+ size_t half_length = data_length >> 1; // Downsampling by 2.
+ int16_t tmp_out;
+
+ // All-pass filtering upper branch.
+ AllPassFilter(&data_in[0], half_length, kAllPassCoefsQ15[0], upper_state,
+ hp_data_out);
+
+ // All-pass filtering lower branch.
+ AllPassFilter(&data_in[1], half_length, kAllPassCoefsQ15[1], lower_state,
+ lp_data_out);
+
+ // Make LP and HP signals.
+ for (i = 0; i < half_length; i++) {
+ tmp_out = *hp_data_out;
+ *hp_data_out++ -= *lp_data_out;
+ *lp_data_out++ += tmp_out;
+ }
+}
+
+// Calculates the energy of |data_in| in dB, and also updates an overall
+// |total_energy| if necessary.
+//
+// - data_in [i] : Input audio data for energy calculation.
+// - data_length [i] : Length of input data.
+// - offset [i] : Offset value added to |log_energy|.
+// - total_energy [i/o] : An external energy updated with the energy of
+// |data_in|.
+// NOTE: |total_energy| is only updated if
+// |total_energy| <= |kMinEnergy|.
+// - log_energy [o] : 10 * log10("energy of |data_in|") given in Q4.
+static void LogOfEnergy(const int16_t* data_in, size_t data_length,
+ int16_t offset, int16_t* total_energy,
+ int16_t* log_energy) {
+ // |tot_rshifts| accumulates the number of right shifts performed on |energy|.
+ int tot_rshifts = 0;
+ // The |energy| will be normalized to 15 bits. We use unsigned integer because
+ // we eventually will mask out the fractional part.
+ uint32_t energy = 0;
+
+ RTC_DCHECK(data_in);
+ RTC_DCHECK_GT(data_length, 0);
+
+ energy = (uint32_t) WebRtcSpl_Energy((int16_t*) data_in, data_length,
+ &tot_rshifts);
+
+ if (energy != 0) {
+ // By construction, normalizing to 15 bits is equivalent with 17 leading
+ // zeros of an unsigned 32 bit value.
+ int normalizing_rshifts = 17 - WebRtcSpl_NormU32(energy);
+ // In a 15 bit representation the leading bit is 2^14. log2(2^14) in Q10 is
+ // (14 << 10), which is what we initialize |log2_energy| with. For a more
+ // detailed derivations, see below.
+ int16_t log2_energy = kLogEnergyIntPart;
+
+ tot_rshifts += normalizing_rshifts;
+ // Normalize |energy| to 15 bits.
+ // |tot_rshifts| is now the total number of right shifts performed on
+ // |energy| after normalization. This means that |energy| is in
+ // Q(-tot_rshifts).
+ if (normalizing_rshifts < 0) {
+ energy <<= -normalizing_rshifts;
+ } else {
+ energy >>= normalizing_rshifts;
+ }
+
+ // Calculate the energy of |data_in| in dB, in Q4.
+ //
+ // 10 * log10("true energy") in Q4 = 2^4 * 10 * log10("true energy") =
+ // 160 * log10(|energy| * 2^|tot_rshifts|) =
+ // 160 * log10(2) * log2(|energy| * 2^|tot_rshifts|) =
+ // 160 * log10(2) * (log2(|energy|) + log2(2^|tot_rshifts|)) =
+ // (160 * log10(2)) * (log2(|energy|) + |tot_rshifts|) =
+ // |kLogConst| * (|log2_energy| + |tot_rshifts|)
+ //
+ // We know by construction that |energy| is normalized to 15 bits. Hence,
+ // |energy| = 2^14 + frac_Q15, where frac_Q15 is a fractional part in Q15.
+ // Further, we'd like |log2_energy| in Q10
+ // log2(|energy|) in Q10 = 2^10 * log2(2^14 + frac_Q15) =
+ // 2^10 * log2(2^14 * (1 + frac_Q15 * 2^-14)) =
+ // 2^10 * (14 + log2(1 + frac_Q15 * 2^-14)) ~=
+ // (14 << 10) + 2^10 * (frac_Q15 * 2^-14) =
+ // (14 << 10) + (frac_Q15 * 2^-4) = (14 << 10) + (frac_Q15 >> 4)
+ //
+ // Note that frac_Q15 = (|energy| & 0x00003FFF)
+
+ // Calculate and add the fractional part to |log2_energy|.
+ log2_energy += (int16_t) ((energy & 0x00003FFF) >> 4);
+
+ // |kLogConst| is in Q9, |log2_energy| in Q10 and |tot_rshifts| in Q0.
+ // Note that we in our derivation above have accounted for an output in Q4.
+ *log_energy = (int16_t)(((kLogConst * log2_energy) >> 19) +
+ ((tot_rshifts * kLogConst) >> 9));
+
+ if (*log_energy < 0) {
+ *log_energy = 0;
+ }
+ } else {
+ *log_energy = offset;
+ return;
+ }
+
+ *log_energy += offset;
+
+ // Update the approximate |total_energy| with the energy of |data_in|, if
+ // |total_energy| has not exceeded |kMinEnergy|. |total_energy| is used as an
+ // energy indicator in WebRtcVad_GmmProbability() in vad_core.c.
+ if (*total_energy <= kMinEnergy) {
+ if (tot_rshifts >= 0) {
+ // We know by construction that the |energy| > |kMinEnergy| in Q0, so add
+ // an arbitrary value such that |total_energy| exceeds |kMinEnergy|.
+ *total_energy += kMinEnergy + 1;
+ } else {
+ // By construction |energy| is represented by 15 bits, hence any number of
+ // right shifted |energy| will fit in an int16_t. In addition, adding the
+ // value to |total_energy| is wrap around safe as long as
+ // |kMinEnergy| < 8192.
+ *total_energy += (int16_t) (energy >> -tot_rshifts); // Q0.
+ }
+ }
+}
+
+int16_t WebRtcVad_CalculateFeatures(VadInstT* self, const int16_t* data_in,
+ size_t data_length, int16_t* features) {
+ int16_t total_energy = 0;
+ // We expect |data_length| to be 80, 160 or 240 samples, which corresponds to
+ // 10, 20 or 30 ms in 8 kHz. Therefore, the intermediate downsampled data will
+ // have at most 120 samples after the first split and at most 60 samples after
+ // the second split.
+ int16_t hp_120[120], lp_120[120];
+ int16_t hp_60[60], lp_60[60];
+ const size_t half_data_length = data_length >> 1;
+ size_t length = half_data_length; // |data_length| / 2, corresponds to
+ // bandwidth = 2000 Hz after downsampling.
+
+ // Initialize variables for the first SplitFilter().
+ int frequency_band = 0;
+ const int16_t* in_ptr = data_in; // [0 - 4000] Hz.
+ int16_t* hp_out_ptr = hp_120; // [2000 - 4000] Hz.
+ int16_t* lp_out_ptr = lp_120; // [0 - 2000] Hz.
+
+ RTC_DCHECK_LE(data_length, 240);
+ RTC_DCHECK_LT(4, kNumChannels - 1); // Checking maximum |frequency_band|.
+
+ // Split at 2000 Hz and downsample.
+ SplitFilter(in_ptr, data_length, &self->upper_state[frequency_band],
+ &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr);
+
+ // For the upper band (2000 Hz - 4000 Hz) split at 3000 Hz and downsample.
+ frequency_band = 1;
+ in_ptr = hp_120; // [2000 - 4000] Hz.
+ hp_out_ptr = hp_60; // [3000 - 4000] Hz.
+ lp_out_ptr = lp_60; // [2000 - 3000] Hz.
+ SplitFilter(in_ptr, length, &self->upper_state[frequency_band],
+ &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr);
+
+ // Energy in 3000 Hz - 4000 Hz.
+ length >>= 1; // |data_length| / 4 <=> bandwidth = 1000 Hz.
+
+ LogOfEnergy(hp_60, length, kOffsetVector[5], &total_energy, &features[5]);
+
+ // Energy in 2000 Hz - 3000 Hz.
+ LogOfEnergy(lp_60, length, kOffsetVector[4], &total_energy, &features[4]);
+
+ // For the lower band (0 Hz - 2000 Hz) split at 1000 Hz and downsample.
+ frequency_band = 2;
+ in_ptr = lp_120; // [0 - 2000] Hz.
+ hp_out_ptr = hp_60; // [1000 - 2000] Hz.
+ lp_out_ptr = lp_60; // [0 - 1000] Hz.
+ length = half_data_length; // |data_length| / 2 <=> bandwidth = 2000 Hz.
+ SplitFilter(in_ptr, length, &self->upper_state[frequency_band],
+ &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr);
+
+ // Energy in 1000 Hz - 2000 Hz.
+ length >>= 1; // |data_length| / 4 <=> bandwidth = 1000 Hz.
+ LogOfEnergy(hp_60, length, kOffsetVector[3], &total_energy, &features[3]);
+
+ // For the lower band (0 Hz - 1000 Hz) split at 500 Hz and downsample.
+ frequency_band = 3;
+ in_ptr = lp_60; // [0 - 1000] Hz.
+ hp_out_ptr = hp_120; // [500 - 1000] Hz.
+ lp_out_ptr = lp_120; // [0 - 500] Hz.
+ SplitFilter(in_ptr, length, &self->upper_state[frequency_band],
+ &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr);
+
+ // Energy in 500 Hz - 1000 Hz.
+ length >>= 1; // |data_length| / 8 <=> bandwidth = 500 Hz.
+ LogOfEnergy(hp_120, length, kOffsetVector[2], &total_energy, &features[2]);
+
+ // For the lower band (0 Hz - 500 Hz) split at 250 Hz and downsample.
+ frequency_band = 4;
+ in_ptr = lp_120; // [0 - 500] Hz.
+ hp_out_ptr = hp_60; // [250 - 500] Hz.
+ lp_out_ptr = lp_60; // [0 - 250] Hz.
+ SplitFilter(in_ptr, length, &self->upper_state[frequency_band],
+ &self->lower_state[frequency_band], hp_out_ptr, lp_out_ptr);
+
+ // Energy in 250 Hz - 500 Hz.
+ length >>= 1; // |data_length| / 16 <=> bandwidth = 250 Hz.
+ LogOfEnergy(hp_60, length, kOffsetVector[1], &total_energy, &features[1]);
+
+ // Remove 0 Hz - 80 Hz, by high pass filtering the lower band.
+ HighPassFilter(lp_60, length, self->hp_filter_state, hp_120);
+
+ // Energy in 80 Hz - 250 Hz.
+ LogOfEnergy(hp_120, length, kOffsetVector[0], &total_energy, &features[0]);
+
+ return total_energy;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_filterbank.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_filterbank.h
new file mode 100644
index 0000000..b400505
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_filterbank.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+/*
+ * This file includes feature calculating functionality used in vad_core.c.
+ */
+
+#ifndef COMMON_AUDIO_VAD_VAD_FILTERBANK_H_
+#define COMMON_AUDIO_VAD_VAD_FILTERBANK_H_
+
+#include "webrtc/common_audio/vad/vad_core.h"
+
+// Takes |data_length| samples of |data_in| and calculates the logarithm of the
+// energy of each of the |kNumChannels| = 6 frequency bands used by the VAD:
+// 80 Hz - 250 Hz
+// 250 Hz - 500 Hz
+// 500 Hz - 1000 Hz
+// 1000 Hz - 2000 Hz
+// 2000 Hz - 3000 Hz
+// 3000 Hz - 4000 Hz
+//
+// The values are given in Q4 and written to |features|. Further, an approximate
+// overall energy is returned. The return value is used in
+// WebRtcVad_GmmProbability() as a signal indicator, hence it is arbitrary above
+// the threshold |kMinEnergy|.
+//
+// - self [i/o] : State information of the VAD.
+// - data_in [i] : Input audio data, for feature extraction.
+// - data_length [i] : Audio data size, in number of samples.
+// - features [o] : 10 * log10(energy in each frequency band), Q4.
+// - returns : Total energy of the signal (NOTE! This value is not
+// exact. It is only used in a comparison.)
+int16_t WebRtcVad_CalculateFeatures(VadInstT* self,
+ const int16_t* data_in,
+ size_t data_length,
+ int16_t* features);
+
+#endif // COMMON_AUDIO_VAD_VAD_FILTERBANK_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_gmm.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_gmm.c
new file mode 100644
index 0000000..176270c
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_gmm.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/common_audio/vad/vad_gmm.h"
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+
+static const int32_t kCompVar = 22005;
+static const int16_t kLog2Exp = 5909; // log2(exp(1)) in Q12.
+
+// For a normal distribution, the probability of |input| is calculated and
+// returned (in Q20). The formula for normal distributed probability is
+//
+// 1 / s * exp(-(x - m)^2 / (2 * s^2))
+//
+// where the parameters are given in the following Q domains:
+// m = |mean| (Q7)
+// s = |std| (Q7)
+// x = |input| (Q4)
+// in addition to the probability we output |delta| (in Q11) used when updating
+// the noise/speech model.
+int32_t WebRtcVad_GaussianProbability(int16_t input,
+ int16_t mean,
+ int16_t std,
+ int16_t* delta) {
+ int16_t tmp16, inv_std, inv_std2, exp_value = 0;
+ int32_t tmp32;
+
+ // Calculate |inv_std| = 1 / s, in Q10.
+ // 131072 = 1 in Q17, and (|std| >> 1) is for rounding instead of truncation.
+ // Q-domain: Q17 / Q7 = Q10.
+ tmp32 = (int32_t) 131072 + (int32_t) (std >> 1);
+ inv_std = (int16_t) WebRtcSpl_DivW32W16(tmp32, std);
+
+ // Calculate |inv_std2| = 1 / s^2, in Q14.
+ tmp16 = (inv_std >> 2); // Q10 -> Q8.
+ // Q-domain: (Q8 * Q8) >> 2 = Q14.
+ inv_std2 = (int16_t)((tmp16 * tmp16) >> 2);
+ // TODO(bjornv): Investigate if changing to
+ // inv_std2 = (int16_t)((inv_std * inv_std) >> 6);
+ // gives better accuracy.
+
+ tmp16 = (input << 3); // Q4 -> Q7
+ tmp16 = tmp16 - mean; // Q7 - Q7 = Q7
+
+ // To be used later, when updating noise/speech model.
+ // |delta| = (x - m) / s^2, in Q11.
+ // Q-domain: (Q14 * Q7) >> 10 = Q11.
+ *delta = (int16_t)((inv_std2 * tmp16) >> 10);
+
+ // Calculate the exponent |tmp32| = (x - m)^2 / (2 * s^2), in Q10. Replacing
+ // division by two with one shift.
+ // Q-domain: (Q11 * Q7) >> 8 = Q10.
+ tmp32 = (*delta * tmp16) >> 9;
+
+ // If the exponent is small enough to give a non-zero probability we calculate
+ // |exp_value| ~= exp(-(x - m)^2 / (2 * s^2))
+ // ~= exp2(-log2(exp(1)) * |tmp32|).
+ if (tmp32 < kCompVar) {
+ // Calculate |tmp16| = log2(exp(1)) * |tmp32|, in Q10.
+ // Q-domain: (Q12 * Q10) >> 12 = Q10.
+ tmp16 = (int16_t)((kLog2Exp * tmp32) >> 12);
+ tmp16 = -tmp16;
+ exp_value = (0x0400 | (tmp16 & 0x03FF));
+ tmp16 ^= 0xFFFF;
+ tmp16 >>= 10;
+ tmp16 += 1;
+ // Get |exp_value| = exp(-|tmp32|) in Q10.
+ exp_value >>= tmp16;
+ }
+
+ // Calculate and return (1 / s) * exp(-(x - m)^2 / (2 * s^2)), in Q20.
+ // Q-domain: Q10 * Q10 = Q20.
+ return inv_std * exp_value;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_gmm.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_gmm.h
new file mode 100644
index 0000000..6b2d11b
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_gmm.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// Gaussian probability calculations internally used in vad_core.c.
+
+#ifndef COMMON_AUDIO_VAD_VAD_GMM_H_
+#define COMMON_AUDIO_VAD_VAD_GMM_H_
+
+#include <stdint.h>
+
+// Calculates the probability for |input|, given that |input| comes from a
+// normal distribution with mean and standard deviation (|mean|, |std|).
+//
+// Inputs:
+// - input : input sample in Q4.
+// - mean : mean input in the statistical model, Q7.
+// - std : standard deviation, Q7.
+//
+// Output:
+//
+// - delta : input used when updating the model, Q11.
+// |delta| = (|input| - |mean|) / |std|^2.
+//
+// Return:
+// (probability for |input|) =
+// 1 / |std| * exp(-(|input| - |mean|)^2 / (2 * |std|^2));
+int32_t WebRtcVad_GaussianProbability(int16_t input,
+ int16_t mean,
+ int16_t std,
+ int16_t* delta);
+
+#endif // COMMON_AUDIO_VAD_VAD_GMM_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_sp.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_sp.c
new file mode 100644
index 0000000..97d5d6c
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_sp.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/common_audio/vad/vad_sp.h"
+
+#include "webrtc/rtc_base/checks.h"
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+#include "webrtc/common_audio/vad/vad_core.h"
+
+// Allpass filter coefficients, upper and lower, in Q13.
+// Upper: 0.64, Lower: 0.17.
+static const int16_t kAllPassCoefsQ13[2] = { 5243, 1392 }; // Q13.
+static const int16_t kSmoothingDown = 6553; // 0.2 in Q15.
+static const int16_t kSmoothingUp = 32439; // 0.99 in Q15.
+
+// TODO(bjornv): Move this function to vad_filterbank.c.
+// Downsampling filter based on splitting filter and allpass functions.
+void WebRtcVad_Downsampling(const int16_t* signal_in,
+ int16_t* signal_out,
+ int32_t* filter_state,
+ size_t in_length) {
+ int16_t tmp16_1 = 0, tmp16_2 = 0;
+ int32_t tmp32_1 = filter_state[0];
+ int32_t tmp32_2 = filter_state[1];
+ size_t n = 0;
+ // Downsampling by 2 gives half length.
+ size_t half_length = (in_length >> 1);
+
+ // Filter coefficients in Q13, filter state in Q0.
+ for (n = 0; n < half_length; n++) {
+ // All-pass filtering upper branch.
+ tmp16_1 = (int16_t) ((tmp32_1 >> 1) +
+ ((kAllPassCoefsQ13[0] * *signal_in) >> 14));
+ *signal_out = tmp16_1;
+ tmp32_1 = (int32_t)(*signal_in++) - ((kAllPassCoefsQ13[0] * tmp16_1) >> 12);
+
+ // All-pass filtering lower branch.
+ tmp16_2 = (int16_t) ((tmp32_2 >> 1) +
+ ((kAllPassCoefsQ13[1] * *signal_in) >> 14));
+ *signal_out++ += tmp16_2;
+ tmp32_2 = (int32_t)(*signal_in++) - ((kAllPassCoefsQ13[1] * tmp16_2) >> 12);
+ }
+ // Store the filter states.
+ filter_state[0] = tmp32_1;
+ filter_state[1] = tmp32_2;
+}
+
+// Inserts |feature_value| into |low_value_vector|, if it is one of the 16
+// smallest values the last 100 frames. Then calculates and returns the median
+// of the five smallest values.
+int16_t WebRtcVad_FindMinimum(VadInstT* self,
+ int16_t feature_value,
+ int channel) {
+ int i = 0, j = 0;
+ int position = -1;
+ // Offset to beginning of the 16 minimum values in memory.
+ const int offset = (channel << 4);
+ int16_t current_median = 1600;
+ int16_t alpha = 0;
+ int32_t tmp32 = 0;
+ // Pointer to memory for the 16 minimum values and the age of each value of
+ // the |channel|.
+ int16_t* age = &self->index_vector[offset];
+ int16_t* smallest_values = &self->low_value_vector[offset];
+
+ RTC_DCHECK_LT(channel, kNumChannels);
+
+ // Each value in |smallest_values| is getting 1 loop older. Update |age|, and
+ // remove old values.
+ for (i = 0; i < 16; i++) {
+ if (age[i] != 100) {
+ age[i]++;
+ } else {
+ // Too old value. Remove from memory and shift larger values downwards.
+ for (j = i; j < 15; j++) {
+ smallest_values[j] = smallest_values[j + 1];
+ age[j] = age[j + 1];
+ }
+ age[15] = 101;
+ smallest_values[15] = 10000;
+ }
+ }
+
+ // Check if |feature_value| is smaller than any of the values in
+ // |smallest_values|. If so, find the |position| where to insert the new value
+ // (|feature_value|).
+ if (feature_value < smallest_values[7]) {
+ if (feature_value < smallest_values[3]) {
+ if (feature_value < smallest_values[1]) {
+ if (feature_value < smallest_values[0]) {
+ position = 0;
+ } else {
+ position = 1;
+ }
+ } else if (feature_value < smallest_values[2]) {
+ position = 2;
+ } else {
+ position = 3;
+ }
+ } else if (feature_value < smallest_values[5]) {
+ if (feature_value < smallest_values[4]) {
+ position = 4;
+ } else {
+ position = 5;
+ }
+ } else if (feature_value < smallest_values[6]) {
+ position = 6;
+ } else {
+ position = 7;
+ }
+ } else if (feature_value < smallest_values[15]) {
+ if (feature_value < smallest_values[11]) {
+ if (feature_value < smallest_values[9]) {
+ if (feature_value < smallest_values[8]) {
+ position = 8;
+ } else {
+ position = 9;
+ }
+ } else if (feature_value < smallest_values[10]) {
+ position = 10;
+ } else {
+ position = 11;
+ }
+ } else if (feature_value < smallest_values[13]) {
+ if (feature_value < smallest_values[12]) {
+ position = 12;
+ } else {
+ position = 13;
+ }
+ } else if (feature_value < smallest_values[14]) {
+ position = 14;
+ } else {
+ position = 15;
+ }
+ }
+
+ // If we have detected a new small value, insert it at the correct position
+ // and shift larger values up.
+ if (position > -1) {
+ for (i = 15; i > position; i--) {
+ smallest_values[i] = smallest_values[i - 1];
+ age[i] = age[i - 1];
+ }
+ smallest_values[position] = feature_value;
+ age[position] = 1;
+ }
+
+ // Get |current_median|.
+ if (self->frame_counter > 2) {
+ current_median = smallest_values[2];
+ } else if (self->frame_counter > 0) {
+ current_median = smallest_values[0];
+ }
+
+ // Smooth the median value.
+ if (self->frame_counter > 0) {
+ if (current_median < self->mean_value[channel]) {
+ alpha = kSmoothingDown; // 0.2 in Q15.
+ } else {
+ alpha = kSmoothingUp; // 0.99 in Q15.
+ }
+ }
+ tmp32 = (alpha + 1) * self->mean_value[channel];
+ tmp32 += (WEBRTC_SPL_WORD16_MAX - alpha) * current_median;
+ tmp32 += 16384;
+ self->mean_value[channel] = (int16_t) (tmp32 >> 15);
+
+ return self->mean_value[channel];
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_sp.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_sp.h
new file mode 100644
index 0000000..002fcd8
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/vad_sp.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file includes specific signal processing tools used in vad_core.c.
+
+#ifndef COMMON_AUDIO_VAD_VAD_SP_H_
+#define COMMON_AUDIO_VAD_VAD_SP_H_
+
+#include "webrtc/common_audio/vad/vad_core.h"
+
+// Downsamples the signal by a factor 2, eg. 32->16 or 16->8.
+//
+// Inputs:
+// - signal_in : Input signal.
+// - in_length : Length of input signal in samples.
+//
+// Input & Output:
+// - filter_state : Current filter states of the two all-pass filters. The
+// |filter_state| is updated after all samples have been
+// processed.
+//
+// Output:
+// - signal_out : Downsampled signal (of length |in_length| / 2).
+void WebRtcVad_Downsampling(const int16_t* signal_in,
+ int16_t* signal_out,
+ int32_t* filter_state,
+ size_t in_length);
+
+// Updates and returns the smoothed feature minimum. As minimum we use the
+// median of the five smallest feature values in a 100 frames long window.
+// As long as |handle->frame_counter| is zero, that is, we haven't received any
+// "valid" data, FindMinimum() outputs the default value of 1600.
+//
+// Inputs:
+// - feature_value : New feature value to update with.
+// - channel : Channel number.
+//
+// Input & Output:
+// - handle : State information of the VAD.
+//
+// Returns:
+// : Smoothed minimum value for a moving window.
+int16_t WebRtcVad_FindMinimum(VadInstT* handle,
+ int16_t feature_value,
+ int channel);
+
+#endif // COMMON_AUDIO_VAD_VAD_SP_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/webrtc_vad.c b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/webrtc_vad.c
new file mode 100644
index 0000000..4315b09
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/common_audio/vad/webrtc_vad.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/common_audio/vad/include/webrtc_vad.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
+#include "webrtc/common_audio/vad/vad_core.h"
+
+static const int kInitCheck = 42;
+static const int kValidRates[] = { 8000, 16000, 32000, 48000 };
+static const size_t kRatesSize = sizeof(kValidRates) / sizeof(*kValidRates);
+static const int kMaxFrameLengthMs = 30;
+
+VadInst* WebRtcVad_Create() {
+ VadInstT* self = (VadInstT*)malloc(sizeof(VadInstT));
+
+ WebRtcSpl_Init();
+ self->init_flag = 0;
+
+ return (VadInst*)self;
+}
+
+void WebRtcVad_Free(VadInst* handle) {
+ free(handle);
+}
+
+// TODO(bjornv): Move WebRtcVad_InitCore() code here.
+int WebRtcVad_Init(VadInst* handle) {
+ // Initialize the core VAD component.
+ return WebRtcVad_InitCore((VadInstT*) handle);
+}
+
+// TODO(bjornv): Move WebRtcVad_set_mode_core() code here.
+int WebRtcVad_set_mode(VadInst* handle, int mode) {
+ VadInstT* self = (VadInstT*) handle;
+
+ if (handle == NULL) {
+ return -1;
+ }
+ if (self->init_flag != kInitCheck) {
+ return -1;
+ }
+
+ return WebRtcVad_set_mode_core(self, mode);
+}
+
+int WebRtcVad_Process(VadInst* handle, int fs, const int16_t* audio_frame,
+ size_t frame_length) {
+ int vad = -1;
+ VadInstT* self = (VadInstT*) handle;
+
+ if (handle == NULL) {
+ return -1;
+ }
+
+ if (self->init_flag != kInitCheck) {
+ return -1;
+ }
+ if (audio_frame == NULL) {
+ return -1;
+ }
+ if (WebRtcVad_ValidRateAndFrameLength(fs, frame_length) != 0) {
+ return -1;
+ }
+
+ if (fs == 48000) {
+ vad = WebRtcVad_CalcVad48khz(self, audio_frame, frame_length);
+ } else if (fs == 32000) {
+ vad = WebRtcVad_CalcVad32khz(self, audio_frame, frame_length);
+ } else if (fs == 16000) {
+ vad = WebRtcVad_CalcVad16khz(self, audio_frame, frame_length);
+ } else if (fs == 8000) {
+ vad = WebRtcVad_CalcVad8khz(self, audio_frame, frame_length);
+ }
+
+ if (vad > 0) {
+ vad = 1;
+ }
+ return vad;
+}
+
+int WebRtcVad_ValidRateAndFrameLength(int rate, size_t frame_length) {
+ int return_value = -1;
+ size_t i;
+ int valid_length_ms;
+ size_t valid_length;
+
+ // We only allow 10, 20 or 30 ms frames. Loop through valid frame rates and
+ // see if we have a matching pair.
+ for (i = 0; i < kRatesSize; i++) {
+ if (kValidRates[i] == rate) {
+ for (valid_length_ms = 10; valid_length_ms <= kMaxFrameLengthMs;
+ valid_length_ms += 10) {
+ valid_length = (size_t)(kValidRates[i] / 1000 * valid_length_ms);
+ if (frame_length == valid_length) {
+ return_value = 0;
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return return_value;
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/checks.cc b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/checks.cc
new file mode 100644
index 0000000..03baf31
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/checks.cc
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2006 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// Most of this was borrowed (with minor modifications) from V8's and Chromium's
+// src/base/logging.cc.
+
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+
+#if defined(WEBRTC_ANDROID)
+#define RTC_LOG_TAG_ANDROID "rtc"
+#include <android/log.h> // NOLINT
+#endif
+
+#if defined(WEBRTC_WIN)
+#include <windows.h>
+#endif
+
+#if defined(WEBRTC_WIN)
+#define LAST_SYSTEM_ERROR (::GetLastError())
+#elif defined(__native_client__) && __native_client__
+#define LAST_SYSTEM_ERROR (0)
+#elif defined(WEBRTC_POSIX)
+#include <errno.h>
+#define LAST_SYSTEM_ERROR (errno)
+#endif // WEBRTC_WIN
+
+#include "webrtc/rtc_base/checks.h"
+
+namespace {
+#if defined(__GNUC__)
+__attribute__((__format__(__printf__, 2, 3)))
+#endif
+ void AppendFormat(std::string* s, const char* fmt, ...) {
+ va_list args, copy;
+ va_start(args, fmt);
+ va_copy(copy, args);
+ const int predicted_length = std::vsnprintf(nullptr, 0, fmt, copy);
+ va_end(copy);
+
+ if (predicted_length > 0) {
+ const size_t size = s->size();
+ s->resize(size + predicted_length);
+ // Pass "+ 1" to vsnprintf to include space for the '\0'.
+ std::vsnprintf(&((*s)[size]), predicted_length + 1, fmt, args);
+ }
+ va_end(args);
+}
+}
+
+namespace rtc {
+namespace webrtc_checks_impl {
+
+// Reads one argument from args, appends it to s and advances fmt.
+// Returns true iff an argument was sucessfully parsed.
+bool ParseArg(va_list* args, const CheckArgType** fmt, std::string* s) {
+ if (**fmt == CheckArgType::kEnd)
+ return false;
+
+ switch (**fmt) {
+ case CheckArgType::kInt:
+ AppendFormat(s, "%d", va_arg(*args, int));
+ break;
+ case CheckArgType::kLong:
+ AppendFormat(s, "%ld", va_arg(*args, long));
+ break;
+ case CheckArgType::kLongLong:
+ AppendFormat(s, "%lld", va_arg(*args, long long));
+ break;
+ case CheckArgType::kUInt:
+ AppendFormat(s, "%u", va_arg(*args, unsigned));
+ break;
+ case CheckArgType::kULong:
+ AppendFormat(s, "%lu", va_arg(*args, unsigned long));
+ break;
+ case CheckArgType::kULongLong:
+ AppendFormat(s, "%llu", va_arg(*args, unsigned long long));
+ break;
+ case CheckArgType::kDouble:
+ AppendFormat(s, "%g", va_arg(*args, double));
+ break;
+ case CheckArgType::kLongDouble:
+ AppendFormat(s, "%Lg", va_arg(*args, long double));
+ break;
+ case CheckArgType::kCharP:
+ s->append(va_arg(*args, const char*));
+ break;
+ case CheckArgType::kStdString:
+ s->append(*va_arg(*args, const std::string*));
+ break;
+ case CheckArgType::kVoidP:
+ AppendFormat(s, "%p", va_arg(*args, const void*));
+ break;
+ default:
+ s->append("[Invalid CheckArgType]");
+ return false;
+ }
+ (*fmt)++;
+ return true;
+}
+
+RTC_NORETURN void FatalLog(const char* file,
+ int line,
+ const char* message,
+ const CheckArgType* fmt,
+ ...) {
+ va_list args;
+ va_start(args, fmt);
+
+ std::string s;
+ AppendFormat(&s,
+ "\n\n"
+ "#\n"
+ "# Fatal error in: %s, line %d\n"
+ "# last system error: %u\n"
+ "# Check failed: %s",
+ file, line, LAST_SYSTEM_ERROR, message);
+
+ if (*fmt == CheckArgType::kCheckOp) {
+ // This log message was generated by RTC_CHECK_OP, so we have to complete
+ // the error message using the operands that have been passed as the first
+ // two arguments.
+ fmt++;
+
+ std::string s1, s2;
+ if (ParseArg(&args, &fmt, &s1) && ParseArg(&args, &fmt, &s2))
+ AppendFormat(&s, " (%s vs. %s)\n# ", s1.c_str(), s2.c_str());
+ } else {
+ s.append("\n# ");
+ }
+
+ // Append all the user-supplied arguments to the message.
+ while (ParseArg(&args, &fmt, &s))
+ ;
+
+ va_end(args);
+
+ const char* output = s.c_str();
+
+#if defined(WEBRTC_ANDROID)
+ __android_log_print(ANDROID_LOG_ERROR, RTC_LOG_TAG_ANDROID, "%s\n", output);
+#endif
+
+ fflush(stdout);
+ fprintf(stderr, "%s", output);
+ fflush(stderr);
+ abort();
+}
+
+} // namespace webrtc_checks_impl
+} // namespace rtc
+
+// Function to call from the C version of the RTC_CHECK and RTC_DCHECK macros.
+RTC_NORETURN void rtc_FatalMessage(const char* file, int line,
+ const char* msg) {
+ static constexpr rtc::webrtc_checks_impl::CheckArgType t[] = {
+ rtc::webrtc_checks_impl::CheckArgType::kEnd};
+ FatalLog(file, line, msg, t);
+}
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/checks.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/checks.h
new file mode 100644
index 0000000..3dbef18
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/checks.h
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2006 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef RTC_BASE_CHECKS_H_
+#define RTC_BASE_CHECKS_H_
+
+// If you for some reson need to know if DCHECKs are on, test the value of
+// RTC_DCHECK_IS_ON. (Test its value, not if it's defined; it'll always be
+// defined, to either a true or a false value.)
+#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
+#define RTC_DCHECK_IS_ON 1
+#else
+#define RTC_DCHECK_IS_ON 0
+#endif
+
+// Annotate a function that will not return control flow to the caller.
+#if defined(_MSC_VER)
+#define RTC_NORETURN __declspec(noreturn)
+#elif defined(__GNUC__)
+#define RTC_NORETURN __attribute__ ((__noreturn__))
+#else
+#define RTC_NORETURN
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+RTC_NORETURN void rtc_FatalMessage(const char* file, int line, const char* msg);
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#ifdef __cplusplus
+// C++ version.
+
+#include <string>
+
+#include "webrtc/rtc_base/numerics/safe_compare.h"
+#include "webrtc/rtc_base/system/inline.h"
+
+// The macros here print a message to stderr and abort under various
+// conditions. All will accept additional stream messages. For example:
+// RTC_DCHECK_EQ(foo, bar) << "I'm printed when foo != bar.";
+//
+// - RTC_CHECK(x) is an assertion that x is always true, and that if it isn't,
+// it's better to terminate the process than to continue. During development,
+// the reason that it's better to terminate might simply be that the error
+// handling code isn't in place yet; in production, the reason might be that
+// the author of the code truly believes that x will always be true, but that
+// she recognizes that if she is wrong, abrupt and unpleasant process
+// termination is still better than carrying on with the assumption violated.
+//
+// RTC_CHECK always evaluates its argument, so it's OK for x to have side
+// effects.
+//
+// - RTC_DCHECK(x) is the same as RTC_CHECK(x)---an assertion that x is always
+// true---except that x will only be evaluated in debug builds; in production
+// builds, x is simply assumed to be true. This is useful if evaluating x is
+// expensive and the expected cost of failing to detect the violated
+// assumption is acceptable. You should not handle cases where a production
+// build fails to spot a violated condition, even those that would result in
+// crashes. If the code needs to cope with the error, make it cope, but don't
+// call RTC_DCHECK; if the condition really can't occur, but you'd sleep
+// better at night knowing that the process will suicide instead of carrying
+// on in case you were wrong, use RTC_CHECK instead of RTC_DCHECK.
+//
+// RTC_DCHECK only evaluates its argument in debug builds, so if x has visible
+// side effects, you need to write e.g.
+// bool w = x; RTC_DCHECK(w);
+//
+// - RTC_CHECK_EQ, _NE, _GT, ..., and RTC_DCHECK_EQ, _NE, _GT, ... are
+// specialized variants of RTC_CHECK and RTC_DCHECK that print prettier
+// messages if the condition doesn't hold. Prefer them to raw RTC_CHECK and
+// RTC_DCHECK.
+//
+// - FATAL() aborts unconditionally.
+//
+// TODO(ajm): Ideally, checks.h would be combined with logging.h, but
+// consolidation with system_wrappers/logging.h should happen first.
+
+namespace rtc {
+namespace webrtc_checks_impl {
+enum class CheckArgType : int8_t {
+ kEnd = 0,
+ kInt,
+ kLong,
+ kLongLong,
+ kUInt,
+ kULong,
+ kULongLong,
+ kDouble,
+ kLongDouble,
+ kCharP,
+ kStdString,
+ kVoidP,
+
+ // kCheckOp doesn't represent an argument type. Instead, it is sent as the
+ // first argument from RTC_CHECK_OP to make FatalLog use the next two
+ // arguments to build the special CHECK_OP error message
+ // (the "a == b (1 vs. 2)" bit).
+ kCheckOp,
+};
+
+RTC_NORETURN void FatalLog(const char* file,
+ int line,
+ const char* message,
+ const CheckArgType* fmt,
+ ...);
+
+// Wrapper for log arguments. Only ever make values of this type with the
+// MakeVal() functions.
+template <CheckArgType N, typename T>
+struct Val {
+ static constexpr CheckArgType Type() { return N; }
+ T GetVal() const { return val; }
+ T val;
+};
+
+inline Val<CheckArgType::kInt, int> MakeVal(int x) {
+ return {x};
+}
+inline Val<CheckArgType::kLong, long> MakeVal(long x) {
+ return {x};
+}
+inline Val<CheckArgType::kLongLong, long long> MakeVal(long long x) {
+ return {x};
+}
+inline Val<CheckArgType::kUInt, unsigned int> MakeVal(unsigned int x) {
+ return {x};
+}
+inline Val<CheckArgType::kULong, unsigned long> MakeVal(unsigned long x) {
+ return {x};
+}
+inline Val<CheckArgType::kULongLong, unsigned long long> MakeVal(
+ unsigned long long x) {
+ return {x};
+}
+
+inline Val<CheckArgType::kDouble, double> MakeVal(double x) {
+ return {x};
+}
+inline Val<CheckArgType::kLongDouble, long double> MakeVal(long double x) {
+ return {x};
+}
+
+inline Val<CheckArgType::kCharP, const char*> MakeVal(const char* x) {
+ return {x};
+}
+inline Val<CheckArgType::kStdString, const std::string*> MakeVal(
+ const std::string& x) {
+ return {&x};
+}
+
+inline Val<CheckArgType::kVoidP, const void*> MakeVal(const void* x) {
+ return {x};
+}
+
+// Ephemeral type that represents the result of the logging << operator.
+template <typename... Ts>
+class LogStreamer;
+
+// Base case: Before the first << argument.
+template <>
+class LogStreamer<> final {
+ public:
+ template <
+ typename U,
+ typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
+ RTC_FORCE_INLINE LogStreamer<decltype(MakeVal(std::declval<U>()))> operator<<(
+ U arg) const {
+ return LogStreamer<decltype(MakeVal(std::declval<U>()))>(MakeVal(arg),
+ this);
+ }
+
+ template <
+ typename U,
+ typename std::enable_if<!std::is_arithmetic<U>::value>::type* = nullptr>
+ RTC_FORCE_INLINE LogStreamer<decltype(MakeVal(std::declval<U>()))> operator<<(
+ const U& arg) const {
+ return LogStreamer<decltype(MakeVal(std::declval<U>()))>(MakeVal(arg),
+ this);
+ }
+
+ template <typename... Us>
+ RTC_NORETURN RTC_FORCE_INLINE static void Call(const char* file,
+ const int line,
+ const char* message,
+ const Us&... args) {
+ static constexpr CheckArgType t[] = {Us::Type()..., CheckArgType::kEnd};
+ FatalLog(file, line, message, t, args.GetVal()...);
+ }
+
+ template <typename... Us>
+ RTC_NORETURN RTC_FORCE_INLINE static void CallCheckOp(const char* file,
+ const int line,
+ const char* message,
+ const Us&... args) {
+ static constexpr CheckArgType t[] = {CheckArgType::kCheckOp, Us::Type()...,
+ CheckArgType::kEnd};
+ FatalLog(file, line, message, t, args.GetVal()...);
+ }
+};
+
+// Inductive case: We've already seen at least one << argument. The most recent
+// one had type `T`, and the earlier ones had types `Ts`.
+template <typename T, typename... Ts>
+class LogStreamer<T, Ts...> final {
+ public:
+ RTC_FORCE_INLINE LogStreamer(T arg, const LogStreamer<Ts...>* prior)
+ : arg_(arg), prior_(prior) {}
+
+ template <
+ typename U,
+ typename std::enable_if<std::is_arithmetic<U>::value>::type* = nullptr>
+ RTC_FORCE_INLINE LogStreamer<decltype(MakeVal(std::declval<U>())), T, Ts...>
+ operator<<(U arg) const {
+ return LogStreamer<decltype(MakeVal(std::declval<U>())), T, Ts...>(
+ MakeVal(arg), this);
+ }
+
+ template <
+ typename U,
+ typename std::enable_if<!std::is_arithmetic<U>::value>::type* = nullptr>
+ RTC_FORCE_INLINE LogStreamer<decltype(MakeVal(std::declval<U>())), T, Ts...>
+ operator<<(const U& arg) const {
+ return LogStreamer<decltype(MakeVal(std::declval<U>())), T, Ts...>(
+ MakeVal(arg), this);
+ }
+
+ template <typename... Us>
+ RTC_NORETURN RTC_FORCE_INLINE void Call(const char* file,
+ const int line,
+ const char* message,
+ const Us&... args) const {
+ prior_->Call(file, line, message, arg_, args...);
+ }
+
+ template <typename... Us>
+ RTC_NORETURN RTC_FORCE_INLINE void CallCheckOp(const char* file,
+ const int line,
+ const char* message,
+ const Us&... args) const {
+ prior_->CallCheckOp(file, line, message, arg_, args...);
+ }
+
+ private:
+ // The most recent argument.
+ T arg_;
+
+ // Earlier arguments.
+ const LogStreamer<Ts...>* prior_;
+};
+
+template <bool isCheckOp>
+class FatalLogCall final {
+ public:
+ FatalLogCall(const char* file, int line, const char* message)
+ : file_(file), line_(line), message_(message) {}
+
+ // This can be any binary operator with precedence lower than <<.
+ template <typename... Ts>
+ RTC_NORETURN RTC_FORCE_INLINE void operator&(
+ const LogStreamer<Ts...>& streamer) {
+ isCheckOp ? streamer.CallCheckOp(file_, line_, message_)
+ : streamer.Call(file_, line_, message_);
+ }
+
+ private:
+ const char* file_;
+ int line_;
+ const char* message_;
+};
+} // namespace webrtc_checks_impl
+
+// The actual stream used isn't important. We reference |ignored| in the code
+// but don't evaluate it; this is to avoid "unused variable" warnings (we do so
+// in a particularly convoluted way with an extra ?: because that appears to be
+// the simplest construct that keeps Visual Studio from complaining about
+// condition being unused).
+#define RTC_EAT_STREAM_PARAMETERS(ignored) \
+ (true ? true : ((void)(ignored), true)) \
+ ? static_cast<void>(0) \
+ : rtc::webrtc_checks_impl::FatalLogCall<false>("", 0, "") & \
+ rtc::webrtc_checks_impl::LogStreamer<>()
+
+// Call RTC_EAT_STREAM_PARAMETERS with an argument that fails to compile if
+// values of the same types as |a| and |b| can't be compared with the given
+// operation, and that would evaluate |a| and |b| if evaluated.
+#define RTC_EAT_STREAM_PARAMETERS_OP(op, a, b) \
+ RTC_EAT_STREAM_PARAMETERS(((void)rtc::Safe##op(a, b)))
+
+// RTC_CHECK dies with a fatal error if condition is not true. It is *not*
+// controlled by NDEBUG or anything else, so the check will be executed
+// regardless of compilation mode.
+//
+// We make sure RTC_CHECK et al. always evaluates |condition|, as
+// doing RTC_CHECK(FunctionWithSideEffect()) is a common idiom.
+#define RTC_CHECK(condition) \
+ while (!(condition)) \
+ rtc::webrtc_checks_impl::FatalLogCall<false>(__FILE__, __LINE__, \
+ #condition) & \
+ rtc::webrtc_checks_impl::LogStreamer<>()
+
+// Helper macro for binary operators.
+// Don't use this macro directly in your code, use RTC_CHECK_EQ et al below.
+#define RTC_CHECK_OP(name, op, val1, val2) \
+ while (!rtc::Safe##name((val1), (val2))) \
+ rtc::webrtc_checks_impl::FatalLogCall<true>(__FILE__, __LINE__, \
+ #val1 " " #op " " #val2) & \
+ rtc::webrtc_checks_impl::LogStreamer<>() << (val1) << (val2)
+
+#define RTC_CHECK_EQ(val1, val2) RTC_CHECK_OP(Eq, ==, val1, val2)
+#define RTC_CHECK_NE(val1, val2) RTC_CHECK_OP(Ne, !=, val1, val2)
+#define RTC_CHECK_LE(val1, val2) RTC_CHECK_OP(Le, <=, val1, val2)
+#define RTC_CHECK_LT(val1, val2) RTC_CHECK_OP(Lt, <, val1, val2)
+#define RTC_CHECK_GE(val1, val2) RTC_CHECK_OP(Ge, >=, val1, val2)
+#define RTC_CHECK_GT(val1, val2) RTC_CHECK_OP(Gt, >, val1, val2)
+
+// The RTC_DCHECK macro is equivalent to RTC_CHECK except that it only generates
+// code in debug builds. It does reference the condition parameter in all cases,
+// though, so callers won't risk getting warnings about unused variables.
+#if RTC_DCHECK_IS_ON
+#define RTC_DCHECK(condition) RTC_CHECK(condition)
+#define RTC_DCHECK_EQ(v1, v2) RTC_CHECK_EQ(v1, v2)
+#define RTC_DCHECK_NE(v1, v2) RTC_CHECK_NE(v1, v2)
+#define RTC_DCHECK_LE(v1, v2) RTC_CHECK_LE(v1, v2)
+#define RTC_DCHECK_LT(v1, v2) RTC_CHECK_LT(v1, v2)
+#define RTC_DCHECK_GE(v1, v2) RTC_CHECK_GE(v1, v2)
+#define RTC_DCHECK_GT(v1, v2) RTC_CHECK_GT(v1, v2)
+#else
+#define RTC_DCHECK(condition) RTC_EAT_STREAM_PARAMETERS(condition)
+#define RTC_DCHECK_EQ(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Eq, v1, v2)
+#define RTC_DCHECK_NE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ne, v1, v2)
+#define RTC_DCHECK_LE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Le, v1, v2)
+#define RTC_DCHECK_LT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Lt, v1, v2)
+#define RTC_DCHECK_GE(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Ge, v1, v2)
+#define RTC_DCHECK_GT(v1, v2) RTC_EAT_STREAM_PARAMETERS_OP(Gt, v1, v2)
+#endif
+
+#define RTC_UNREACHABLE_CODE_HIT false
+#define RTC_NOTREACHED() RTC_DCHECK(RTC_UNREACHABLE_CODE_HIT)
+
+// TODO(bugs.webrtc.org/8454): Add an RTC_ prefix or rename differently.
+#define FATAL() \
+ rtc::webrtc_checks_impl::FatalLogCall<false>(__FILE__, __LINE__, \
+ "FATAL()") & \
+ rtc::webrtc_checks_impl::LogStreamer<>()
+
+// Performs the integer division a/b and returns the result. CHECKs that the
+// remainder is zero.
+template <typename T>
+inline T CheckedDivExact(T a, T b) {
+ RTC_CHECK_EQ(a % b, 0) << a << " is not evenly divisible by " << b;
+ return a / b;
+}
+
+} // namespace rtc
+
+#else // __cplusplus not defined
+// C version. Lacks many features compared to the C++ version, but usage
+// guidelines are the same.
+
+#define RTC_CHECK(condition) \
+ do { \
+ if (!(condition)) { \
+ rtc_FatalMessage(__FILE__, __LINE__, "CHECK failed: " #condition); \
+ } \
+ } while (0)
+
+#define RTC_CHECK_EQ(a, b) RTC_CHECK((a) == (b))
+#define RTC_CHECK_NE(a, b) RTC_CHECK((a) != (b))
+#define RTC_CHECK_LE(a, b) RTC_CHECK((a) <= (b))
+#define RTC_CHECK_LT(a, b) RTC_CHECK((a) < (b))
+#define RTC_CHECK_GE(a, b) RTC_CHECK((a) >= (b))
+#define RTC_CHECK_GT(a, b) RTC_CHECK((a) > (b))
+
+#define RTC_DCHECK(condition) \
+ do { \
+ if (RTC_DCHECK_IS_ON && !(condition)) { \
+ rtc_FatalMessage(__FILE__, __LINE__, "DCHECK failed: " #condition); \
+ } \
+ } while (0)
+
+#define RTC_DCHECK_EQ(a, b) RTC_DCHECK((a) == (b))
+#define RTC_DCHECK_NE(a, b) RTC_DCHECK((a) != (b))
+#define RTC_DCHECK_LE(a, b) RTC_DCHECK((a) <= (b))
+#define RTC_DCHECK_LT(a, b) RTC_DCHECK((a) < (b))
+#define RTC_DCHECK_GE(a, b) RTC_DCHECK((a) >= (b))
+#define RTC_DCHECK_GT(a, b) RTC_DCHECK((a) > (b))
+
+#endif // __cplusplus
+
+#endif // RTC_BASE_CHECKS_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/compile_assert_c.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/compile_assert_c.h
new file mode 100644
index 0000000..db2e4a8
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/compile_assert_c.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef RTC_BASE_COMPILE_ASSERT_C_H_
+#define RTC_BASE_COMPILE_ASSERT_C_H_
+
+// Use this macro to verify at compile time that certain restrictions are met.
+// The argument is the boolean expression to evaluate.
+// Example:
+// RTC_COMPILE_ASSERT(sizeof(foo) < 128);
+// Note: In C++, use static_assert instead!
+#define RTC_COMPILE_ASSERT(expression) \
+ switch (0) { \
+ case 0: \
+ case expression:; \
+ }
+
+#endif // RTC_BASE_COMPILE_ASSERT_C_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/numerics/safe_compare.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/numerics/safe_compare.h
new file mode 100644
index 0000000..d62eee1
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/numerics/safe_compare.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file defines six constexpr functions:
+//
+// rtc::SafeEq // ==
+// rtc::SafeNe // !=
+// rtc::SafeLt // <
+// rtc::SafeLe // <=
+// rtc::SafeGt // >
+// rtc::SafeGe // >=
+//
+// They each accept two arguments of arbitrary types, and in almost all cases,
+// they simply call the appropriate comparison operator. However, if both
+// arguments are integers, they don't compare them using C++'s quirky rules,
+// but instead adhere to the true mathematical definitions. It is as if the
+// arguments were first converted to infinite-range signed integers, and then
+// compared, although of course nothing expensive like that actually takes
+// place. In practice, for signed/signed and unsigned/unsigned comparisons and
+// some mixed-signed comparisons with a compile-time constant, the overhead is
+// zero; in the remaining cases, it is just a few machine instructions (no
+// branches).
+
+#ifndef RTC_BASE_NUMERICS_SAFE_COMPARE_H_
+#define RTC_BASE_NUMERICS_SAFE_COMPARE_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <type_traits>
+#include <utility>
+
+#include "webrtc/rtc_base/type_traits.h"
+
+namespace rtc {
+
+namespace safe_cmp_impl {
+
+template <size_t N>
+struct LargerIntImpl : std::false_type {};
+template <>
+struct LargerIntImpl<sizeof(int8_t)> : std::true_type {
+ using type = int16_t;
+};
+template <>
+struct LargerIntImpl<sizeof(int16_t)> : std::true_type {
+ using type = int32_t;
+};
+template <>
+struct LargerIntImpl<sizeof(int32_t)> : std::true_type {
+ using type = int64_t;
+};
+
+// LargerInt<T1, T2>::value is true iff there's a signed type that's larger
+// than T1 (and no larger than the larger of T2 and int*, for performance
+// reasons); and if there is such a type, LargerInt<T1, T2>::type is an alias
+// for it.
+template <typename T1, typename T2>
+struct LargerInt
+ : LargerIntImpl<sizeof(T1) < sizeof(T2) || sizeof(T1) < sizeof(int*)
+ ? sizeof(T1)
+ : 0> {};
+
+template <typename T>
+constexpr typename std::make_unsigned<T>::type MakeUnsigned(T a) {
+ return static_cast<typename std::make_unsigned<T>::type>(a);
+}
+
+// Overload for when both T1 and T2 have the same signedness.
+template <typename Op,
+ typename T1,
+ typename T2,
+ typename std::enable_if<std::is_signed<T1>::value ==
+ std::is_signed<T2>::value>::type* = nullptr>
+constexpr bool Cmp(T1 a, T2 b) {
+ return Op::Op(a, b);
+}
+
+// Overload for signed - unsigned comparison that can be promoted to a bigger
+// signed type.
+template <typename Op,
+ typename T1,
+ typename T2,
+ typename std::enable_if<std::is_signed<T1>::value &&
+ std::is_unsigned<T2>::value &&
+ LargerInt<T2, T1>::value>::type* = nullptr>
+constexpr bool Cmp(T1 a, T2 b) {
+ return Op::Op(a, static_cast<typename LargerInt<T2, T1>::type>(b));
+}
+
+// Overload for unsigned - signed comparison that can be promoted to a bigger
+// signed type.
+template <typename Op,
+ typename T1,
+ typename T2,
+ typename std::enable_if<std::is_unsigned<T1>::value &&
+ std::is_signed<T2>::value &&
+ LargerInt<T1, T2>::value>::type* = nullptr>
+constexpr bool Cmp(T1 a, T2 b) {
+ return Op::Op(static_cast<typename LargerInt<T1, T2>::type>(a), b);
+}
+
+// Overload for signed - unsigned comparison that can't be promoted to a bigger
+// signed type.
+template <typename Op,
+ typename T1,
+ typename T2,
+ typename std::enable_if<std::is_signed<T1>::value &&
+ std::is_unsigned<T2>::value &&
+ !LargerInt<T2, T1>::value>::type* = nullptr>
+constexpr bool Cmp(T1 a, T2 b) {
+ return a < 0 ? Op::Op(-1, 0) : Op::Op(safe_cmp_impl::MakeUnsigned(a), b);
+}
+
+// Overload for unsigned - signed comparison that can't be promoted to a bigger
+// signed type.
+template <typename Op,
+ typename T1,
+ typename T2,
+ typename std::enable_if<std::is_unsigned<T1>::value &&
+ std::is_signed<T2>::value &&
+ !LargerInt<T1, T2>::value>::type* = nullptr>
+constexpr bool Cmp(T1 a, T2 b) {
+ return b < 0 ? Op::Op(0, -1) : Op::Op(a, safe_cmp_impl::MakeUnsigned(b));
+}
+
+#define RTC_SAFECMP_MAKE_OP(name, op) \
+ struct name { \
+ template <typename T1, typename T2> \
+ static constexpr bool Op(T1 a, T2 b) { \
+ return a op b; \
+ } \
+ };
+RTC_SAFECMP_MAKE_OP(EqOp, ==)
+RTC_SAFECMP_MAKE_OP(NeOp, !=)
+RTC_SAFECMP_MAKE_OP(LtOp, <)
+RTC_SAFECMP_MAKE_OP(LeOp, <=)
+RTC_SAFECMP_MAKE_OP(GtOp, >)
+RTC_SAFECMP_MAKE_OP(GeOp, >=)
+#undef RTC_SAFECMP_MAKE_OP
+
+} // namespace safe_cmp_impl
+
+#define RTC_SAFECMP_MAKE_FUN(name) \
+ template <typename T1, typename T2> \
+ constexpr \
+ typename std::enable_if<IsIntlike<T1>::value && IsIntlike<T2>::value, \
+ bool>::type Safe##name(T1 a, T2 b) { \
+ /* Unary plus here turns enums into real integral types. */ \
+ return safe_cmp_impl::Cmp<safe_cmp_impl::name##Op>(+a, +b); \
+ } \
+ template <typename T1, typename T2> \
+ constexpr \
+ typename std::enable_if<!IsIntlike<T1>::value || !IsIntlike<T2>::value, \
+ bool>::type Safe##name(const T1& a, \
+ const T2& b) { \
+ return safe_cmp_impl::name##Op::Op(a, b); \
+ }
+RTC_SAFECMP_MAKE_FUN(Eq)
+RTC_SAFECMP_MAKE_FUN(Ne)
+RTC_SAFECMP_MAKE_FUN(Lt)
+RTC_SAFECMP_MAKE_FUN(Le)
+RTC_SAFECMP_MAKE_FUN(Gt)
+RTC_SAFECMP_MAKE_FUN(Ge)
+#undef RTC_SAFECMP_MAKE_FUN
+
+} // namespace rtc
+
+#endif // RTC_BASE_NUMERICS_SAFE_COMPARE_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/sanitizer.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/sanitizer.h
new file mode 100644
index 0000000..a9eccfc
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/sanitizer.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef RTC_BASE_SANITIZER_H_
+#define RTC_BASE_SANITIZER_H_
+
+#include <stddef.h> // For size_t.
+
+#ifdef __cplusplus
+#include <type_traits>
+#endif
+
+#if defined(__has_feature)
+#if __has_feature(address_sanitizer)
+#define RTC_HAS_ASAN 1
+#endif
+#if __has_feature(memory_sanitizer)
+#define RTC_HAS_MSAN 1
+#endif
+#endif
+#ifndef RTC_HAS_ASAN
+#define RTC_HAS_ASAN 0
+#endif
+#ifndef RTC_HAS_MSAN
+#define RTC_HAS_MSAN 0
+#endif
+
+#if RTC_HAS_ASAN
+#include <sanitizer/asan_interface.h>
+#endif
+#if RTC_HAS_MSAN
+#include <sanitizer/msan_interface.h>
+#endif
+
+#ifdef __has_attribute
+#if __has_attribute(no_sanitize)
+#define RTC_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
+#endif
+#endif
+#ifndef RTC_NO_SANITIZE
+#define RTC_NO_SANITIZE(what)
+#endif
+
+// Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements)
+// as being unaddressable, so that reads and writes are not allowed. ASan may
+// narrow the range to the nearest alignment boundaries.
+static inline void rtc_AsanPoison(const volatile void* ptr,
+ size_t element_size,
+ size_t num_elements) {
+#if RTC_HAS_ASAN
+ ASAN_POISON_MEMORY_REGION(ptr, element_size * num_elements);
+#endif
+}
+
+// Ask ASan to mark the memory range [ptr, ptr + element_size * num_elements)
+// as being addressable, so that reads and writes are allowed. ASan may widen
+// the range to the nearest alignment boundaries.
+static inline void rtc_AsanUnpoison(const volatile void* ptr,
+ size_t element_size,
+ size_t num_elements) {
+#if RTC_HAS_ASAN
+ ASAN_UNPOISON_MEMORY_REGION(ptr, element_size * num_elements);
+#endif
+}
+
+// Ask MSan to mark the memory range [ptr, ptr + element_size * num_elements)
+// as being uninitialized.
+static inline void rtc_MsanMarkUninitialized(const volatile void* ptr,
+ size_t element_size,
+ size_t num_elements) {
+#if RTC_HAS_MSAN
+ __msan_poison(ptr, element_size * num_elements);
+#endif
+}
+
+// Force an MSan check (if any bits in the memory range [ptr, ptr +
+// element_size * num_elements) are uninitialized the call will crash with an
+// MSan report).
+static inline void rtc_MsanCheckInitialized(const volatile void* ptr,
+ size_t element_size,
+ size_t num_elements) {
+#if RTC_HAS_MSAN
+ __msan_check_mem_is_initialized(ptr, element_size * num_elements);
+#endif
+}
+
+#ifdef __cplusplus
+
+namespace rtc {
+namespace sanitizer_impl {
+
+template <typename T>
+constexpr bool IsTriviallyCopyable() {
+ return static_cast<bool>(std::is_trivially_copy_constructible<T>::value &&
+ (std::is_trivially_copy_assignable<T>::value ||
+ !std::is_copy_assignable<T>::value) &&
+ std::is_trivially_destructible<T>::value);
+}
+
+} // namespace sanitizer_impl
+
+template <typename T>
+inline void AsanPoison(const T& mem) {
+ rtc_AsanPoison(mem.data(), sizeof(mem.data()[0]), mem.size());
+}
+
+template <typename T>
+inline void AsanUnpoison(const T& mem) {
+ rtc_AsanUnpoison(mem.data(), sizeof(mem.data()[0]), mem.size());
+}
+
+template <typename T>
+inline void MsanMarkUninitialized(const T& mem) {
+ rtc_MsanMarkUninitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
+}
+
+template <typename T>
+inline T MsanUninitialized(T t) {
+#if RTC_HAS_MSAN
+ // TODO(bugs.webrtc.org/8762): Switch to std::is_trivially_copyable when it
+ // becomes available in downstream projects.
+ static_assert(sanitizer_impl::IsTriviallyCopyable<T>(), "");
+#endif
+ rtc_MsanMarkUninitialized(&t, sizeof(T), 1);
+ return t;
+}
+
+template <typename T>
+inline void MsanCheckInitialized(const T& mem) {
+ rtc_MsanCheckInitialized(mem.data(), sizeof(mem.data()[0]), mem.size());
+}
+
+} // namespace rtc
+
+#endif // __cplusplus
+
+#endif // RTC_BASE_SANITIZER_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/system/arch.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/system/arch.h
new file mode 100644
index 0000000..a2a1180
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/system/arch.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains platform-specific typedefs and defines.
+// Much of it is derived from Chromium's build/build_config.h.
+
+#ifndef RTC_BASE_SYSTEM_ARCH_H_
+#define RTC_BASE_SYSTEM_ARCH_H_
+
+// Processor architecture detection. For more info on what's defined, see:
+// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+// http://www.agner.org/optimize/calling_conventions.pdf
+// or with gcc, run: "echo | gcc -E -dM -"
+#if defined(_M_X64) || defined(__x86_64__)
+#define WEBRTC_ARCH_X86_FAMILY
+#define WEBRTC_ARCH_X86_64
+#define WEBRTC_ARCH_64_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(__aarch64__)
+#define WEBRTC_ARCH_ARM_FAMILY
+#define WEBRTC_ARCH_64_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(_M_IX86) || defined(__i386__)
+#define WEBRTC_ARCH_X86_FAMILY
+#define WEBRTC_ARCH_X86
+#define WEBRTC_ARCH_32_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(__ARMEL__)
+#define WEBRTC_ARCH_ARM_FAMILY
+#define WEBRTC_ARCH_32_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(__MIPSEL__)
+#define WEBRTC_ARCH_MIPS_FAMILY
+#if defined(__LP64__)
+#define WEBRTC_ARCH_64_BITS
+#else
+#define WEBRTC_ARCH_32_BITS
+#endif
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(__pnacl__)
+#define WEBRTC_ARCH_32_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#else
+#error Please add support for your architecture in typedefs.h
+#endif
+
+#if !(defined(WEBRTC_ARCH_LITTLE_ENDIAN) ^ defined(WEBRTC_ARCH_BIG_ENDIAN))
+#error Define either WEBRTC_ARCH_LITTLE_ENDIAN or WEBRTC_ARCH_BIG_ENDIAN
+#endif
+
+#endif // RTC_BASE_SYSTEM_ARCH_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/system/inline.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/system/inline.h
new file mode 100644
index 0000000..f585d34
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/system/inline.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef RTC_BASE_SYSTEM_INLINE_H_
+#define RTC_BASE_SYSTEM_INLINE_H_
+
+#if defined(_MSC_VER)
+
+#define RTC_FORCE_INLINE __forceinline
+#define RTC_NO_INLINE __declspec(noinline)
+
+#elif defined(__GNUC__)
+
+#define RTC_FORCE_INLINE __attribute__((__always_inline__))
+#define RTC_NO_INLINE __attribute__((__noinline__))
+
+#else
+
+#define RTC_FORCE_INLINE
+#define RTC_NO_INLINE
+
+#endif
+
+#endif // RTC_BASE_SYSTEM_INLINE_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/type_traits.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/type_traits.h
new file mode 100644
index 0000000..0cb899c
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/rtc_base/type_traits.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2016 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef RTC_BASE_TYPE_TRAITS_H_
+#define RTC_BASE_TYPE_TRAITS_H_
+
+#include <cstddef>
+#include <type_traits>
+
+namespace rtc {
+
+// Determines if the given class has zero-argument .data() and .size() methods
+// whose return values are convertible to T* and size_t, respectively.
+template <typename DS, typename T>
+class HasDataAndSize {
+ private:
+ template <
+ typename C,
+ typename std::enable_if<
+ std::is_convertible<decltype(std::declval<C>().data()), T*>::value &&
+ std::is_convertible<decltype(std::declval<C>().size()),
+ std::size_t>::value>::type* = nullptr>
+ static int Test(int);
+
+ template <typename>
+ static char Test(...);
+
+ public:
+ static constexpr bool value = std::is_same<decltype(Test<DS>(0)), int>::value;
+};
+
+namespace test_has_data_and_size {
+
+template <typename DR, typename SR>
+struct Test1 {
+ DR data();
+ SR size();
+};
+static_assert(HasDataAndSize<Test1<int*, int>, int>::value, "");
+static_assert(HasDataAndSize<Test1<int*, int>, const int>::value, "");
+static_assert(HasDataAndSize<Test1<const int*, int>, const int>::value, "");
+static_assert(!HasDataAndSize<Test1<const int*, int>, int>::value,
+ "implicit cast of const int* to int*");
+static_assert(!HasDataAndSize<Test1<char*, size_t>, int>::value,
+ "implicit cast of char* to int*");
+
+struct Test2 {
+ int* data;
+ size_t size;
+};
+static_assert(!HasDataAndSize<Test2, int>::value,
+ ".data and .size aren't functions");
+
+struct Test3 {
+ int* data();
+};
+static_assert(!HasDataAndSize<Test3, int>::value, ".size() is missing");
+
+class Test4 {
+ int* data();
+ size_t size();
+};
+static_assert(!HasDataAndSize<Test4, int>::value,
+ ".data() and .size() are private");
+
+} // namespace test_has_data_and_size
+
+namespace type_traits_impl {
+
+// Determines if the given type is an enum that converts implicitly to
+// an integral type.
+template <typename T>
+struct IsIntEnum {
+ private:
+ // This overload is used if the type is an enum, and unary plus
+ // compiles and turns it into an integral type.
+ template <typename X,
+ typename std::enable_if<
+ std::is_enum<X>::value &&
+ std::is_integral<decltype(+std::declval<X>())>::value>::type* =
+ nullptr>
+ static int Test(int);
+
+ // Otherwise, this overload is used.
+ template <typename>
+ static char Test(...);
+
+ public:
+ static constexpr bool value =
+ std::is_same<decltype(Test<typename std::remove_reference<T>::type>(0)),
+ int>::value;
+};
+
+} // namespace type_traits_impl
+
+// Determines if the given type is integral, or an enum that
+// converts implicitly to an integral type.
+template <typename T>
+struct IsIntlike {
+ private:
+ using X = typename std::remove_reference<T>::type;
+
+ public:
+ static constexpr bool value =
+ std::is_integral<X>::value || type_traits_impl::IsIntEnum<X>::value;
+};
+
+namespace test_enum_intlike {
+
+enum E1 { e1 };
+enum { e2 };
+enum class E3 { e3 };
+struct S {};
+
+static_assert(type_traits_impl::IsIntEnum<E1>::value, "");
+static_assert(type_traits_impl::IsIntEnum<decltype(e2)>::value, "");
+static_assert(!type_traits_impl::IsIntEnum<E3>::value, "");
+static_assert(!type_traits_impl::IsIntEnum<int>::value, "");
+static_assert(!type_traits_impl::IsIntEnum<float>::value, "");
+static_assert(!type_traits_impl::IsIntEnum<S>::value, "");
+
+static_assert(IsIntlike<E1>::value, "");
+static_assert(IsIntlike<decltype(e2)>::value, "");
+static_assert(!IsIntlike<E3>::value, "");
+static_assert(IsIntlike<int>::value, "");
+static_assert(!IsIntlike<float>::value, "");
+static_assert(!IsIntlike<S>::value, "");
+
+} // namespace test_enum_intlike
+
+} // namespace rtc
+
+#endif // RTC_BASE_TYPE_TRAITS_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/system_wrappers/include/cpu_features_wrapper.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/system_wrappers/include/cpu_features_wrapper.h
new file mode 100644
index 0000000..739161a
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/system_wrappers/include/cpu_features_wrapper.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_
+#define SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_
+
+#include <stdint.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+// List of features in x86.
+typedef enum { kSSE2, kSSE3 } CPUFeature;
+
+// List of features in ARM.
+enum {
+ kCPUFeatureARMv7 = (1 << 0),
+ kCPUFeatureVFPv3 = (1 << 1),
+ kCPUFeatureNEON = (1 << 2),
+ kCPUFeatureLDREXSTREX = (1 << 3)
+};
+
+typedef int (*WebRtc_CPUInfo)(CPUFeature feature);
+
+// Returns true if the CPU supports the feature.
+extern WebRtc_CPUInfo WebRtc_GetCPUInfo;
+
+// No CPU feature is available => straight C path.
+extern WebRtc_CPUInfo WebRtc_GetCPUInfoNoASM;
+
+// Return the features in an ARM device.
+// It detects the features in the hardware platform, and returns supported
+// values in the above enum definition as a bitmask.
+extern uint64_t WebRtc_GetCPUFeaturesARM(void);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+} // extern "C"
+#endif
+
+#endif // SYSTEM_WRAPPERS_INCLUDE_CPU_FEATURES_WRAPPER_H_
diff --git a/funasr/runtime/cpp/onnxruntime/third_party/webrtc/typedefs.h b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/typedefs.h
new file mode 100644
index 0000000..8286eca
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/third_party/webrtc/typedefs.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+// This file contains platform-specific typedefs and defines.
+// Much of it is derived from Chromium's build/build_config.h.
+
+#ifndef WEBRTC_TYPEDEFS_H_
+#define WEBRTC_TYPEDEFS_H_
+
+// Processor architecture detection. For more info on what's defined, see:
+// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+// http://www.agner.org/optimize/calling_conventions.pdf
+// or with gcc, run: "echo | gcc -E -dM -"
+#if defined(_M_X64) || defined(__x86_64__)
+#define WEBRTC_ARCH_X86_FAMILY
+#define WEBRTC_ARCH_X86_64
+#define WEBRTC_ARCH_64_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(__aarch64__)
+#define WEBRTC_ARCH_64_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(_M_IX86) || defined(__i386__)
+#define WEBRTC_ARCH_X86_FAMILY
+#define WEBRTC_ARCH_X86
+#define WEBRTC_ARCH_32_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(__ARMEL__)
+// TODO(ajm): We'd prefer to control platform defines here, but this is
+// currently provided by the Android makefiles. Commented to avoid duplicate
+// definition warnings.
+//#define WEBRTC_ARCH_ARM
+// TODO(ajm): Chromium uses the following two defines. Should we switch?
+//#define WEBRTC_ARCH_ARM_FAMILY
+//#define WEBRTC_ARCH_ARMEL
+#define WEBRTC_ARCH_32_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(__MIPSEL__)
+#define WEBRTC_ARCH_32_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(__pnacl__)
+#define WEBRTC_ARCH_32_BITS
+#define WEBRTC_ARCH_LITTLE_ENDIAN
+#elif defined(__PPC__)
+#if defined(__PPC64__)
+#define WEBRTC_ARCH_64_BITS
+#else
+#define WEBRTC_ARCH_32_BITS
+#endif
+#define WEBRTC_ARCH_BIG_ENDIAN
+#else
+#error Please add support for your architecture in typedefs.h
+#endif
+
+#if !(defined(WEBRTC_ARCH_LITTLE_ENDIAN) ^ defined(WEBRTC_ARCH_BIG_ENDIAN))
+#error Define either WEBRTC_ARCH_LITTLE_ENDIAN or WEBRTC_ARCH_BIG_ENDIAN
+#endif
+
+#if (defined(WEBRTC_ARCH_X86_FAMILY) && !defined(__SSE2__)) || \
+ (defined(WEBRTC_ARCH_ARM_V7) && !defined(WEBRTC_ARCH_ARM_NEON))
+#define WEBRTC_CPU_DETECTION
+#endif
+
+#if !defined(_MSC_VER)
+#include <stdint.h>
+#else
+// Define C99 equivalent types, since pre-2010 MSVC doesn't provide stdint.h.
+typedef signed char int8_t;
+typedef signed short int16_t;
+typedef signed int int32_t;
+typedef __int64 int64_t;
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned __int64 uint64_t;
+#endif
+
+// Borrowed from Chromium's base/compiler_specific.h.
+// Annotate a virtual method indicating it must be overriding a virtual
+// method in the parent class.
+// Use like:
+// virtual void foo() OVERRIDE;
+#if defined(_MSC_VER)
+#define OVERRIDE override
+#elif defined(__clang__)
+// Clang defaults to C++03 and warns about using override. Squelch that.
+// Intentionally no push/pop here so all users of OVERRIDE ignore the warning
+// too. This is like passing -Wno-c++11-extensions, except that GCC won't die
+// (because it won't see this pragma).
+#pragma clang diagnostic ignored "-Wc++11-extensions"
+#define OVERRIDE override
+#elif defined(__GNUC__) && __cplusplus >= 201103 && \
+ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100) >= 40700
+// GCC 4.7 supports explicit virtual overrides when C++11 support is enabled.
+#define OVERRIDE override
+#else
+#define OVERRIDE
+#endif
+
+// Annotate a function indicating the caller must examine the return value.
+// Use like:
+// int foo() WARN_UNUSED_RESULT;
+// TODO(ajm): Hack to avoid multiple definitions until the base/ of webrtc and
+// libjingle are merged.
+#if !defined(WARN_UNUSED_RESULT)
+#if defined(__GNUC__)
+#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+#define WARN_UNUSED_RESULT
+#endif
+#endif // WARN_UNUSED_RESULT
+
+// Put after a variable that might not be used, to prevent compiler warnings:
+// int result ATTRIBUTE_UNUSED = DoSomething();
+// assert(result == 17);
+#ifndef ATTRIBUTE_UNUSED
+#if defined(__GNUC__) || defined(__clang__)
+#define ATTRIBUTE_UNUSED __attribute__((unused))
+#else
+#define ATTRIBUTE_UNUSED
+#endif
+#endif
+
+// Macro to be used for switch-case fallthrough (required for enabling
+// -Wimplicit-fallthrough warning on Clang).
+#ifndef FALLTHROUGH
+#if defined(__clang__)
+#define FALLTHROUGH() [[clang::fallthrough]]
+#else
+#define FALLTHROUGH() do { } while (0)
+#endif
+#endif
+
+// Annotate a function that will not return control flow to the caller.
+#if defined(_MSC_VER)
+#define NO_RETURN __declspec(noreturn)
+#elif defined(__GNUC__)
+#define NO_RETURN __attribute__((noreturn))
+#else
+#define NO_RETURN
+#endif
+
+#endif // WEBRTC_TYPEDEFS_H_
diff --git a/funasr/runtime/cpp/onnxruntime/wave/asr_example.wav b/funasr/runtime/cpp/onnxruntime/wave/asr_example.wav
new file mode 100644
index 0000000..be33a3c
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/wave/asr_example.wav
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/wave/long.wav b/funasr/runtime/cpp/onnxruntime/wave/long.wav
new file mode 100644
index 0000000..22b383a
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/wave/long.wav
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/wave/short.wav b/funasr/runtime/cpp/onnxruntime/wave/short.wav
new file mode 100644
index 0000000..bf13bb1
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/wave/short.wav
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3-3.dll b/funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3-3.dll
new file mode 100644
index 0000000..75080e4
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3-3.dll
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3f-3.dll b/funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3f-3.dll
new file mode 100644
index 0000000..32a3fcf
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3f-3.dll
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3l-3.dll b/funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3l-3.dll
new file mode 100644
index 0000000..3e46d34
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/bin/x64/libfftw3l-3.dll
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/bin/x64/onnxruntime.dll b/funasr/runtime/cpp/onnxruntime/win/bin/x64/onnxruntime.dll
new file mode 100644
index 0000000..087a1b4
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/bin/x64/onnxruntime.dll
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3-3.dll b/funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3-3.dll
new file mode 100644
index 0000000..f5a97b4
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3-3.dll
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3f-3.dll b/funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3f-3.dll
new file mode 100644
index 0000000..b0a053a
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3f-3.dll
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3l-3.dll b/funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3l-3.dll
new file mode 100644
index 0000000..abc81ea
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/bin/x86/libfftw3l-3.dll
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/bin/x86/onnxruntime.dll b/funasr/runtime/cpp/onnxruntime/win/bin/x86/onnxruntime.dll
new file mode 100644
index 0000000..e284b45
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/bin/x86/onnxruntime.dll
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/images/sample.png b/funasr/runtime/cpp/onnxruntime/win/images/sample.png
new file mode 100644
index 0000000..cbd7cd3
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/images/sample.png
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/include/cpu_provider_factory.h b/funasr/runtime/cpp/onnxruntime/win/include/cpu_provider_factory.h
new file mode 100644
index 0000000..2926786
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/include/cpu_provider_factory.h
@@ -0,0 +1,19 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#include "onnxruntime_c_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \param use_arena zero: false. non-zero: true.
+ */
+ORT_EXPORT
+ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_CPU, _In_ OrtSessionOptions* options, int use_arena)
+ORT_ALL_ARGS_NONNULL;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/win/include/fftw3.h b/funasr/runtime/cpp/onnxruntime/win/include/fftw3.h
new file mode 100644
index 0000000..39661d2
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/include/fftw3.h
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2003, 2007-14 Matteo Frigo
+ * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
+ *
+ * The following statement of license applies *only* to this header file,
+ * and *not* to the other files distributed with FFTW or derived therefrom:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/***************************** NOTE TO USERS *********************************
+ *
+ * THIS IS A HEADER FILE, NOT A MANUAL
+ *
+ * If you want to know how to use FFTW, please read the manual,
+ * online at http://www.fftw.org/doc/ and also included with FFTW.
+ * For a quick start, see the manual's tutorial section.
+ *
+ * (Reading header files to learn how to use a library is a habit
+ * stemming from code lacking a proper manual. Arguably, it's a
+ * *bad* habit in most cases, because header files can contain
+ * interfaces that are not part of the public, stable API.)
+ *
+ ****************************************************************************/
+
+#ifndef FFTW3_H
+#define FFTW3_H
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* If <complex.h> is included, use the C99 complex type. Otherwise
+ define a type bit-compatible with C99 complex */
+#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
+# define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
+#else
+# define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
+#endif
+
+#define FFTW_CONCAT(prefix, name) prefix ## name
+#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
+#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
+#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
+#define FFTW_MANGLE_QUAD(name) FFTW_CONCAT(fftwq_, name)
+
+/* IMPORTANT: for Windows compilers, you should add a line
+*/
+#define FFTW_DLL
+/*
+ here and in kernel/ifftw.h if you are compiling/using FFTW as a
+ DLL, in order to do the proper importing/exporting, or
+ alternatively compile with -DFFTW_DLL or the equivalent
+ command-line flag. This is not necessary under MinGW/Cygwin, where
+ libtool does the imports/exports automatically. */
+#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
+ /* annoying Windows syntax for shared-library declarations */
+# if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
+# define FFTW_EXTERN extern __declspec(dllexport)
+# else /* user is calling FFTW; import symbol */
+# define FFTW_EXTERN extern __declspec(dllimport)
+# endif
+#else
+# define FFTW_EXTERN extern
+#endif
+
+enum fftw_r2r_kind_do_not_use_me {
+ FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
+ FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
+ FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
+};
+
+struct fftw_iodim_do_not_use_me {
+ int n; /* dimension size */
+ int is; /* input stride */
+ int os; /* output stride */
+};
+
+#include <stddef.h> /* for ptrdiff_t */
+struct fftw_iodim64_do_not_use_me {
+ ptrdiff_t n; /* dimension size */
+ ptrdiff_t is; /* input stride */
+ ptrdiff_t os; /* output stride */
+};
+
+typedef void (*fftw_write_char_func_do_not_use_me)(char c, void *);
+typedef int (*fftw_read_char_func_do_not_use_me)(void *);
+
+/*
+ huge second-order macro that defines prototypes for all API
+ functions. We expand this macro for each supported precision
+
+ X: name-mangling macro
+ R: real data type
+ C: complex data type
+*/
+
+#define FFTW_DEFINE_API(X, R, C) \
+ \
+FFTW_DEFINE_COMPLEX(R, C); \
+ \
+typedef struct X(plan_s) *X(plan); \
+ \
+typedef struct fftw_iodim_do_not_use_me X(iodim); \
+typedef struct fftw_iodim64_do_not_use_me X(iodim64); \
+ \
+typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind); \
+ \
+typedef fftw_write_char_func_do_not_use_me X(write_char_func); \
+typedef fftw_read_char_func_do_not_use_me X(read_char_func); \
+ \
+FFTW_EXTERN void X(execute)(const X(plan) p); \
+ \
+FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n, \
+ C *in, C *out, int sign, unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign, \
+ unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1, \
+ C *in, C *out, int sign, unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2, \
+ C *in, C *out, int sign, unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n, \
+ int howmany, \
+ C *in, const int *inembed, \
+ int istride, int idist, \
+ C *out, const int *onembed, \
+ int ostride, int odist, \
+ int sign, unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims, \
+ int howmany_rank, \
+ const X(iodim) *howmany_dims, \
+ C *in, C *out, \
+ int sign, unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
+ int howmany_rank, \
+ const X(iodim) *howmany_dims, \
+ R *ri, R *ii, R *ro, R *io, \
+ unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank, \
+ const X(iodim64) *dims, \
+ int howmany_rank, \
+ const X(iodim64) *howmany_dims, \
+ C *in, C *out, \
+ int sign, unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank, \
+ const X(iodim64) *dims, \
+ int howmany_rank, \
+ const X(iodim64) *howmany_dims, \
+ R *ri, R *ii, R *ro, R *io, \
+ unsigned flags); \
+ \
+FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out); \
+FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii, \
+ R *ro, R *io); \
+ \
+FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n, \
+ int howmany, \
+ R *in, const int *inembed, \
+ int istride, int idist, \
+ C *out, const int *onembed, \
+ int ostride, int odist, \
+ unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n, \
+ R *in, C *out, unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1, \
+ R *in, C *out, unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1, \
+ int n2, \
+ R *in, C *out, unsigned flags); \
+ \
+ \
+FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n, \
+ int howmany, \
+ C *in, const int *inembed, \
+ int istride, int idist, \
+ R *out, const int *onembed, \
+ int ostride, int odist, \
+ unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n, \
+ C *in, R *out, unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1, \
+ C *in, R *out, unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1, \
+ int n2, \
+ C *in, R *out, unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims, \
+ int howmany_rank, \
+ const X(iodim) *howmany_dims, \
+ R *in, C *out, \
+ unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims, \
+ int howmany_rank, \
+ const X(iodim) *howmany_dims, \
+ C *in, R *out, \
+ unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)( \
+ int rank, const X(iodim) *dims, \
+ int howmany_rank, \
+ const X(iodim) *howmany_dims, \
+ R *in, R *ro, R *io, \
+ unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)( \
+ int rank, const X(iodim) *dims, \
+ int howmany_rank, \
+ const X(iodim) *howmany_dims, \
+ R *ri, R *ii, R *out, \
+ unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank, \
+ const X(iodim64) *dims, \
+ int howmany_rank, \
+ const X(iodim64) *howmany_dims, \
+ R *in, C *out, \
+ unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank, \
+ const X(iodim64) *dims, \
+ int howmany_rank, \
+ const X(iodim64) *howmany_dims, \
+ C *in, R *out, \
+ unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)( \
+ int rank, const X(iodim64) *dims, \
+ int howmany_rank, \
+ const X(iodim64) *howmany_dims, \
+ R *in, R *ro, R *io, \
+ unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)( \
+ int rank, const X(iodim64) *dims, \
+ int howmany_rank, \
+ const X(iodim64) *howmany_dims, \
+ R *ri, R *ii, R *out, \
+ unsigned flags); \
+ \
+FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out); \
+FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out); \
+ \
+FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p, \
+ R *in, R *ro, R *io); \
+FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p, \
+ R *ri, R *ii, R *out); \
+ \
+FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n, \
+ int howmany, \
+ R *in, const int *inembed, \
+ int istride, int idist, \
+ R *out, const int *onembed, \
+ int ostride, int odist, \
+ const X(r2r_kind) *kind, unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out, \
+ const X(r2r_kind) *kind, unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out, \
+ X(r2r_kind) kind, unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out, \
+ X(r2r_kind) kind0, X(r2r_kind) kind1, \
+ unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2, \
+ R *in, R *out, X(r2r_kind) kind0, \
+ X(r2r_kind) kind1, X(r2r_kind) kind2, \
+ unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims, \
+ int howmany_rank, \
+ const X(iodim) *howmany_dims, \
+ R *in, R *out, \
+ const X(r2r_kind) *kind, unsigned flags); \
+ \
+FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims, \
+ int howmany_rank, \
+ const X(iodim64) *howmany_dims, \
+ R *in, R *out, \
+ const X(r2r_kind) *kind, unsigned flags); \
+ \
+FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out); \
+ \
+FFTW_EXTERN void X(destroy_plan)(X(plan) p); \
+FFTW_EXTERN void X(forget_wisdom)(void); \
+FFTW_EXTERN void X(cleanup)(void); \
+ \
+FFTW_EXTERN void X(set_timelimit)(double t); \
+ \
+FFTW_EXTERN void X(plan_with_nthreads)(int nthreads); \
+FFTW_EXTERN int X(init_threads)(void); \
+FFTW_EXTERN void X(cleanup_threads)(void); \
+FFTW_EXTERN void X(make_planner_thread_safe)(void); \
+ \
+FFTW_EXTERN int X(export_wisdom_to_filename)(const char *filename); \
+FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file); \
+FFTW_EXTERN char *X(export_wisdom_to_string)(void); \
+FFTW_EXTERN void X(export_wisdom)(X(write_char_func) write_char, \
+ void *data); \
+FFTW_EXTERN int X(import_system_wisdom)(void); \
+FFTW_EXTERN int X(import_wisdom_from_filename)(const char *filename); \
+FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file); \
+FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string); \
+FFTW_EXTERN int X(import_wisdom)(X(read_char_func) read_char, void *data); \
+ \
+FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file); \
+FFTW_EXTERN void X(print_plan)(const X(plan) p); \
+FFTW_EXTERN char *X(sprint_plan)(const X(plan) p); \
+ \
+FFTW_EXTERN void *X(malloc)(size_t n); \
+FFTW_EXTERN R *X(alloc_real)(size_t n); \
+FFTW_EXTERN C *X(alloc_complex)(size_t n); \
+FFTW_EXTERN void X(free)(void *p); \
+ \
+FFTW_EXTERN void X(flops)(const X(plan) p, \
+ double *add, double *mul, double *fmas); \
+FFTW_EXTERN double X(estimate_cost)(const X(plan) p); \
+FFTW_EXTERN double X(cost)(const X(plan) p); \
+ \
+FFTW_EXTERN int X(alignment_of)(R *p); \
+FFTW_EXTERN const char X(version)[]; \
+FFTW_EXTERN const char X(cc)[]; \
+FFTW_EXTERN const char X(codelet_optim)[];
+
+
+/* end of FFTW_DEFINE_API macro */
+
+FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
+FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
+FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
+
+/* __float128 (quad precision) is a gcc extension on i386, x86_64, and ia64
+ for gcc >= 4.6 (compiled in FFTW with --enable-quad-precision) */
+#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) \
+ && !(defined(__ICC) || defined(__INTEL_COMPILER) || defined(__CUDACC__) || defined(__PGI)) \
+ && (defined(__i386__) || defined(__x86_64__) || defined(__ia64__))
+# if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
+/* note: __float128 is a typedef, which is not supported with the _Complex
+ keyword in gcc, so instead we use this ugly __attribute__ version.
+ However, we can't simply pass the __attribute__ version to
+ FFTW_DEFINE_API because the __attribute__ confuses gcc in pointer
+ types. Hence redefining FFTW_DEFINE_COMPLEX. Ugh. */
+# undef FFTW_DEFINE_COMPLEX
+# define FFTW_DEFINE_COMPLEX(R, C) typedef _Complex float __attribute__((mode(TC))) C
+# endif
+FFTW_DEFINE_API(FFTW_MANGLE_QUAD, __float128, fftwq_complex)
+#endif
+
+#define FFTW_FORWARD (-1)
+#define FFTW_BACKWARD (+1)
+
+#define FFTW_NO_TIMELIMIT (-1.0)
+
+/* documented flags */
+#define FFTW_MEASURE (0U)
+#define FFTW_DESTROY_INPUT (1U << 0)
+#define FFTW_UNALIGNED (1U << 1)
+#define FFTW_CONSERVE_MEMORY (1U << 2)
+#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
+#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
+#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
+#define FFTW_ESTIMATE (1U << 6)
+#define FFTW_WISDOM_ONLY (1U << 21)
+
+/* undocumented beyond-guru flags */
+#define FFTW_ESTIMATE_PATIENT (1U << 7)
+#define FFTW_BELIEVE_PCOST (1U << 8)
+#define FFTW_NO_DFT_R2HC (1U << 9)
+#define FFTW_NO_NONTHREADED (1U << 10)
+#define FFTW_NO_BUFFERING (1U << 11)
+#define FFTW_NO_INDIRECT_OP (1U << 12)
+#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
+#define FFTW_NO_RANK_SPLITS (1U << 14)
+#define FFTW_NO_VRANK_SPLITS (1U << 15)
+#define FFTW_NO_VRECURSE (1U << 16)
+#define FFTW_NO_SIMD (1U << 17)
+#define FFTW_NO_SLOW (1U << 18)
+#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
+#define FFTW_ALLOW_PRUNING (1U << 20)
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* FFTW3_H */
diff --git a/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_c_api.h b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_c_api.h
new file mode 100644
index 0000000..44875b0
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_c_api.h
@@ -0,0 +1,3987 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+// See docs\c_cxx\README.md on generating the Doxygen documentation from this file
+
+/** \mainpage C & C++ APIs
+ *
+ * <h1>C</h1>
+ *
+ * ::OrtApi - Click here to go to the structure with all C API functions.
+ *
+ * <h1>C++</h1>
+ *
+ * ::Ort - Click here to go to the namespace holding all of the C++ wrapper classes
+ *
+ * It is a set of header only wrapper classes around the C API. The goal is to turn the C style return value error codes into C++ exceptions, and to
+ * automate memory management through standard C++ RAII principles.
+ *
+ * \addtogroup Global
+ * ONNX Runtime C API
+ * @{
+ */
+
+#pragma once
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+/** \brief The API version defined in this header
+ *
+ * This value is used by some API functions to behave as this version of the header expects.
+ */
+#define ORT_API_VERSION 14
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//! @}
+// SAL2 Definitions
+#ifndef _WIN32
+#define _In_
+#define _In_z_
+#define _In_opt_
+#define _In_opt_z_
+#define _Out_
+#define _Outptr_
+#define _Out_opt_
+#define _Inout_
+#define _Inout_opt_
+#define _Frees_ptr_opt_
+#define _Ret_maybenull_
+#define _Ret_notnull_
+#define _Check_return_
+#define _Outptr_result_maybenull_
+#define _In_reads_(X)
+#define _Inout_updates_all_(X)
+#define _Out_writes_bytes_all_(X)
+#define _Out_writes_all_(X)
+#define _Success_(X)
+#define _Outptr_result_buffer_maybenull_(X)
+#define ORT_ALL_ARGS_NONNULL __attribute__((nonnull))
+#else
+#include <specstrings.h>
+#define ORT_ALL_ARGS_NONNULL
+#endif
+
+#ifdef _WIN32
+// Define ORT_DLL_IMPORT if your program is dynamically linked to Ort.
+// dllexport is not used, we use a .def file.
+#ifdef ORT_DLL_IMPORT
+#define ORT_EXPORT __declspec(dllimport)
+#else
+#define ORT_EXPORT
+#endif
+#define ORT_API_CALL _stdcall
+#define ORT_MUST_USE_RESULT
+#define ORTCHAR_T wchar_t
+#else
+// To make symbols visible on macOS/iOS
+#ifdef __APPLE__
+#define ORT_EXPORT __attribute__((visibility("default")))
+#else
+#define ORT_EXPORT
+#endif
+#define ORT_API_CALL
+#define ORT_MUST_USE_RESULT __attribute__((warn_unused_result))
+#define ORTCHAR_T char
+#endif
+
+#ifndef ORT_TSTR
+#ifdef _WIN32
+#define ORT_TSTR(X) L##X
+#else
+#define ORT_TSTR(X) X
+#endif
+#endif
+
+// Any pointer marked with _In_ or _Out_, cannot be NULL.
+
+// Windows users should use unicode paths when possible to bypass the MAX_PATH limitation
+// Every pointer marked with _In_ or _Out_, cannot be NULL. Caller should ensure that.
+// for ReleaseXXX(...) functions, they can accept NULL pointer.
+
+#ifdef __cplusplus
+// For any compiler with C++11 support, MSVC 2015 and greater, or Clang version supporting noexcept.
+// Such complex condition is needed because compilers set __cplusplus value differently.
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+#if ((__cplusplus >= 201103L) || (_MSC_VER >= 1900) || (defined(__has_feature) && __has_feature(cxx_noexcept)))
+#define NO_EXCEPTION noexcept
+#else
+#define NO_EXCEPTION throw()
+#endif
+#else
+#define NO_EXCEPTION
+#endif
+
+// __VA_ARGS__ on Windows and Linux are different
+#define ORT_API(RETURN_TYPE, NAME, ...) RETURN_TYPE ORT_API_CALL NAME(__VA_ARGS__) NO_EXCEPTION
+
+#define ORT_API_STATUS(NAME, ...) \
+ _Success_(return == 0) _Check_return_ _Ret_maybenull_ OrtStatusPtr ORT_API_CALL NAME(__VA_ARGS__) \
+ NO_EXCEPTION ORT_MUST_USE_RESULT
+
+// XXX: Unfortunately, SAL annotations are known to not work with function pointers
+#define ORT_API2_STATUS(NAME, ...) \
+ _Check_return_ _Ret_maybenull_ OrtStatusPtr(ORT_API_CALL* NAME)(__VA_ARGS__) NO_EXCEPTION ORT_MUST_USE_RESULT
+
+// Used in *.cc files. Almost as same as ORT_API_STATUS, except without ORT_MUST_USE_RESULT and ORT_EXPORT
+#define ORT_API_STATUS_IMPL(NAME, ...) \
+ _Success_(return == 0) _Check_return_ _Ret_maybenull_ OrtStatusPtr ORT_API_CALL NAME(__VA_ARGS__) NO_EXCEPTION
+
+#define ORT_CLASS_RELEASE(X) void(ORT_API_CALL * Release##X)(_Frees_ptr_opt_ Ort##X * input)
+
+#ifdef __DOXYGEN__
+#undef ORT_API_STATUS
+#define ORT_API_STATUS(NAME, ...) OrtStatus* NAME(__VA_ARGS__)
+#undef ORT_API2_STATUS
+#define ORT_API2_STATUS(NAME, ...) OrtStatus* NAME(__VA_ARGS__)
+#undef ORT_CLASS_RELEASE
+#define ORT_CLASS_RELEASE(X) void Release##X(Ort##X* input)
+#undef NO_EXCEPTION
+#define NO_EXCEPTION
+#endif
+/** \addtogroup Global
+ * ONNX Runtime C API
+ * @{
+ */
+
+/** Copied from TensorProto::DataType
+ * Currently, Ort doesn't support complex64, complex128
+ */
+typedef enum ONNXTensorElementDataType {
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED,
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT, // maps to c type float
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8, // maps to c type uint8_t
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8, // maps to c type int8_t
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16, // maps to c type uint16_t
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16, // maps to c type int16_t
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32, // maps to c type int32_t
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64, // maps to c type int64_t
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_STRING, // maps to c++ type std::string
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_BOOL,
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16,
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_DOUBLE, // maps to c type double
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32, // maps to c type uint32_t
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT64, // maps to c type uint64_t
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX64, // complex with float32 real and imaginary components
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX128, // complex with float64 real and imaginary components
+ ONNX_TENSOR_ELEMENT_DATA_TYPE_BFLOAT16 // Non-IEEE floating-point format based on IEEE754 single-precision
+} ONNXTensorElementDataType;
+
+// Synced with onnx TypeProto oneof
+typedef enum ONNXType {
+ ONNX_TYPE_UNKNOWN,
+ ONNX_TYPE_TENSOR,
+ ONNX_TYPE_SEQUENCE,
+ ONNX_TYPE_MAP,
+ ONNX_TYPE_OPAQUE,
+ ONNX_TYPE_SPARSETENSOR,
+ ONNX_TYPE_OPTIONAL
+} ONNXType;
+
+// These types are synced with internal
+// SparseFormatFlags
+typedef enum OrtSparseFormat {
+ ORT_SPARSE_UNDEFINED = 0,
+ ORT_SPARSE_COO = 0x1,
+ ORT_SPARSE_CSRC = 0x2,
+ ORT_SPARSE_BLOCK_SPARSE = 0x4
+} OrtSparseFormat;
+
+// Enum allows to query sparse tensor indices
+enum OrtSparseIndicesFormat {
+ ORT_SPARSE_COO_INDICES,
+ ORT_SPARSE_CSR_INNER_INDICES,
+ ORT_SPARSE_CSR_OUTER_INDICES,
+ ORT_SPARSE_BLOCK_SPARSE_INDICES
+};
+
+/** \brief Logging severity levels
+ *
+ * In typical API usage, specifying a logging severity level specifies the minimum severity of log messages to show.
+ */
+typedef enum OrtLoggingLevel {
+ ORT_LOGGING_LEVEL_VERBOSE, ///< Verbose informational messages (least severe).
+ ORT_LOGGING_LEVEL_INFO, ///< Informational messages.
+ ORT_LOGGING_LEVEL_WARNING, ///< Warning messages.
+ ORT_LOGGING_LEVEL_ERROR, ///< Error messages.
+ ORT_LOGGING_LEVEL_FATAL, ///< Fatal error messages (most severe).
+} OrtLoggingLevel;
+
+typedef enum OrtErrorCode {
+ ORT_OK,
+ ORT_FAIL,
+ ORT_INVALID_ARGUMENT,
+ ORT_NO_SUCHFILE,
+ ORT_NO_MODEL,
+ ORT_ENGINE_ERROR,
+ ORT_RUNTIME_EXCEPTION,
+ ORT_INVALID_PROTOBUF,
+ ORT_MODEL_LOADED,
+ ORT_NOT_IMPLEMENTED,
+ ORT_INVALID_GRAPH,
+ ORT_EP_FAIL,
+} OrtErrorCode;
+
+typedef enum OrtOpAttrType {
+ ORT_OP_ATTR_UNDEFINED = 0,
+ ORT_OP_ATTR_INT,
+ ORT_OP_ATTR_INTS,
+ ORT_OP_ATTR_FLOAT,
+ ORT_OP_ATTR_FLOATS,
+ ORT_OP_ATTR_STRING,
+ ORT_OP_ATTR_STRINGS,
+} OrtOpAttrType;
+
+//! @}
+#define ORT_RUNTIME_CLASS(X) \
+ struct Ort##X; \
+ typedef struct Ort##X Ort##X;
+
+/** \addtogroup Global
+ * ONNX Runtime C API
+ * @{
+ */
+// The actual types defined have an Ort prefix
+ORT_RUNTIME_CLASS(Env);
+ORT_RUNTIME_CLASS(Status); // nullptr for Status* indicates success
+ORT_RUNTIME_CLASS(MemoryInfo);
+ORT_RUNTIME_CLASS(IoBinding);
+ORT_RUNTIME_CLASS(Session); // Don't call ReleaseSession from Dllmain (because session owns a thread pool)
+ORT_RUNTIME_CLASS(Value);
+ORT_RUNTIME_CLASS(RunOptions);
+ORT_RUNTIME_CLASS(TypeInfo);
+ORT_RUNTIME_CLASS(TensorTypeAndShapeInfo);
+ORT_RUNTIME_CLASS(SessionOptions);
+ORT_RUNTIME_CLASS(CustomOpDomain);
+ORT_RUNTIME_CLASS(MapTypeInfo);
+ORT_RUNTIME_CLASS(SequenceTypeInfo);
+ORT_RUNTIME_CLASS(ModelMetadata);
+ORT_RUNTIME_CLASS(ThreadPoolParams);
+ORT_RUNTIME_CLASS(ThreadingOptions);
+ORT_RUNTIME_CLASS(ArenaCfg);
+ORT_RUNTIME_CLASS(PrepackedWeightsContainer);
+ORT_RUNTIME_CLASS(TensorRTProviderOptionsV2);
+ORT_RUNTIME_CLASS(CUDAProviderOptionsV2);
+ORT_RUNTIME_CLASS(CANNProviderOptions);
+ORT_RUNTIME_CLASS(Op);
+ORT_RUNTIME_CLASS(OpAttr);
+
+#ifdef _WIN32
+typedef _Return_type_success_(return == 0) OrtStatus* OrtStatusPtr;
+#else
+typedef OrtStatus* OrtStatusPtr;
+#endif
+
+/** \brief Memory allocation interface
+ *
+ * Structure of function pointers that defines a memory allocator. This can be created and filled in by the user for custom allocators.
+ *
+ * When an allocator is passed to any function, be sure that the allocator object is not destroyed until the last allocated object using it is freed.
+ */
+typedef struct OrtAllocator {
+ uint32_t version; ///< Must be initialized to ORT_API_VERSION
+ void*(ORT_API_CALL* Alloc)(struct OrtAllocator* this_, size_t size); ///< Returns a pointer to an allocated block of `size` bytes
+ void(ORT_API_CALL* Free)(struct OrtAllocator* this_, void* p); ///< Free a block of memory previously allocated with OrtAllocator::Alloc
+ const struct OrtMemoryInfo*(ORT_API_CALL* Info)(const struct OrtAllocator* this_); ///< Return a pointer to an ::OrtMemoryInfo that describes this allocator
+} OrtAllocator;
+
+typedef void(ORT_API_CALL* OrtLoggingFunction)(
+ void* param, OrtLoggingLevel severity, const char* category, const char* logid, const char* code_location,
+ const char* message);
+
+/** \brief Graph optimization level
+ *
+ * Refer to https://www.onnxruntime.ai/docs/resources/graph-optimizations.html
+ * for an in-depth understanding of Graph Optimizations
+ */
+typedef enum GraphOptimizationLevel {
+ ORT_DISABLE_ALL = 0,
+ ORT_ENABLE_BASIC = 1,
+ ORT_ENABLE_EXTENDED = 2,
+ ORT_ENABLE_ALL = 99
+} GraphOptimizationLevel;
+
+typedef enum ExecutionMode {
+ ORT_SEQUENTIAL = 0,
+ ORT_PARALLEL = 1,
+} ExecutionMode;
+
+/** \brief Language projection identifiers
+ * /see OrtApi::SetLanguageProjection
+ */
+typedef enum OrtLanguageProjection {
+ ORT_PROJECTION_C = 0,
+ ORT_PROJECTION_CPLUSPLUS = 1,
+ ORT_PROJECTION_CSHARP = 2,
+ ORT_PROJECTION_PYTHON = 3,
+ ORT_PROJECTION_JAVA = 4,
+ ORT_PROJECTION_WINML = 5,
+ ORT_PROJECTION_NODEJS = 6,
+} OrtLanguageProjection;
+
+struct OrtKernelInfo;
+typedef struct OrtKernelInfo OrtKernelInfo;
+struct OrtKernelContext;
+typedef struct OrtKernelContext OrtKernelContext;
+struct OrtCustomOp;
+typedef struct OrtCustomOp OrtCustomOp;
+
+typedef enum OrtAllocatorType {
+ OrtInvalidAllocator = -1,
+ OrtDeviceAllocator = 0,
+ OrtArenaAllocator = 1
+} OrtAllocatorType;
+
+/** \brief Memory types for allocated memory, execution provider specific types should be extended in each provider.
+ */
+// Whenever this struct is updated, please also update the MakeKey function in onnxruntime / core / framework / execution_provider.cc
+typedef enum OrtMemType {
+ OrtMemTypeCPUInput = -2, ///< Any CPU memory used by non-CPU execution provider
+ OrtMemTypeCPUOutput = -1, ///< CPU accessible memory outputted by non-CPU execution provider, i.e. CUDA_PINNED
+ OrtMemTypeCPU = OrtMemTypeCPUOutput, ///< Temporary CPU accessible memory allocated by non-CPU execution provider, i.e. CUDA_PINNED
+ OrtMemTypeDefault = 0, ///< The default allocator for execution provider
+} OrtMemType;
+
+/** \brief This mimics OrtDevice type constants so they can be returned in the API
+ */
+typedef enum OrtMemoryInfoDeviceType {
+ OrtMemoryInfoDeviceType_CPU = 0,
+ OrtMemoryInfoDeviceType_GPU = 1,
+ OrtMemoryInfoDeviceType_FPGA = 2
+} OrtMemoryInfoDeviceType;
+
+/** \brief Algorithm to use for cuDNN Convolution Op
+ */
+typedef enum OrtCudnnConvAlgoSearch {
+ OrtCudnnConvAlgoSearchExhaustive, // expensive exhaustive benchmarking using cudnnFindConvolutionForwardAlgorithmEx
+ OrtCudnnConvAlgoSearchHeuristic, // lightweight heuristic based search using cudnnGetConvolutionForwardAlgorithm_v7
+ OrtCudnnConvAlgoSearchDefault, // default algorithm using CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMM
+} OrtCudnnConvAlgoSearch;
+
+/** \brief CUDA Provider Options
+ *
+ * \see OrtApi::SessionOptionsAppendExecutionProvider_CUDA
+ */
+typedef struct OrtCUDAProviderOptions {
+#ifdef __cplusplus
+ OrtCUDAProviderOptions()
+ : device_id{},
+ cudnn_conv_algo_search{OrtCudnnConvAlgoSearchExhaustive},
+ gpu_mem_limit{SIZE_MAX},
+ arena_extend_strategy{},
+ do_copy_in_default_stream{1},
+ has_user_compute_stream{},
+ user_compute_stream{},
+ default_memory_arena_cfg{},
+ tunable_op_enabled{false} {}
+#endif
+
+ /** \brief CUDA device Id
+ * Defaults to 0.
+ */
+ int device_id;
+
+ /** \brief CUDA Convolution algorithm search configuration.
+ * See enum OrtCudnnConvAlgoSearch for more details.
+ * Defaults to OrtCudnnConvAlgoSearchExhaustive.
+ */
+ OrtCudnnConvAlgoSearch cudnn_conv_algo_search;
+
+ /** \brief CUDA memory limit (To use all possible memory pass in maximum size_t)
+ * Defaults to SIZE_MAX.
+ * \note If a ::OrtArenaCfg has been applied, it will override this field
+ */
+ size_t gpu_mem_limit;
+
+ /** \brief Strategy used to grow the memory arena
+ * 0 = kNextPowerOfTwo<br>
+ * 1 = kSameAsRequested<br>
+ * Defaults to 0.
+ * \note If a ::OrtArenaCfg has been applied, it will override this field
+ */
+ int arena_extend_strategy;
+
+ /** \brief Flag indicating if copying needs to take place on the same stream as the compute stream in the CUDA EP
+ * 0 = Use separate streams for copying and compute.
+ * 1 = Use the same stream for copying and compute.
+ * Defaults to 1.
+ * WARNING: Setting this to 0 may result in data races for some models.
+ * Please see issue #4829 for more details.
+ */
+ int do_copy_in_default_stream;
+
+ /** \brief Flag indicating if there is a user provided compute stream
+ * Defaults to 0.
+ */
+ int has_user_compute_stream;
+
+ /** \brief User provided compute stream.
+ * If provided, please set `has_user_compute_stream` to 1.
+ */
+ void* user_compute_stream;
+
+ /** \brief CUDA memory arena configuration parameters
+ */
+ OrtArenaCfg* default_memory_arena_cfg;
+
+ /** \brief Enable TunableOp.
+ * Set it to 1 to enable TunableOp. Otherwise, it is disabled by default.
+ * This option can be superseded by environment variable ORT_CUDA_TUNABLE_OP_ENABLED.
+ */
+ int tunable_op_enabled;
+
+} OrtCUDAProviderOptions;
+
+/** \brief ROCM Provider Options
+ *
+ * \see OrtApi::SessionOptionsAppendExecutionProvider_ROCM
+ */
+typedef struct OrtROCMProviderOptions {
+#ifdef __cplusplus
+ OrtROCMProviderOptions()
+ : device_id{},
+ miopen_conv_exhaustive_search{0},
+ gpu_mem_limit{SIZE_MAX},
+ arena_extend_strategy{},
+ do_copy_in_default_stream{1},
+ has_user_compute_stream{},
+ user_compute_stream{},
+ default_memory_arena_cfg{},
+ tunable_op_enabled{false} {}
+#endif
+
+ /** \brief ROCM device Id
+ * Defaults to 0.
+ */
+ int device_id;
+
+ /** \brief ROCM MIOpen Convolution algorithm exaustive search option.
+ * Defaults to 0 (false).
+ */
+ int miopen_conv_exhaustive_search;
+
+ /** \brief ROCM memory limit (To use all possible memory pass in maximum size_t)
+ * Defaults to SIZE_MAX.
+ * \note If a ::OrtArenaCfg has been applied, it will override this field
+ */
+ size_t gpu_mem_limit;
+
+ /** \brief Strategy used to grow the memory arena
+ * 0 = kNextPowerOfTwo<br>
+ * 1 = kSameAsRequested<br>
+ * Defaults to 0.
+ * \note If a ::OrtArenaCfg has been applied, it will override this field
+ */
+ int arena_extend_strategy;
+
+ /** \brief Flag indicating if copying needs to take place on the same stream as the compute stream in the ROCM EP
+ * 0 = Use separate streams for copying and compute.
+ * 1 = Use the same stream for copying and compute.
+ * Defaults to 1.
+ * WARNING: Setting this to 0 may result in data races for some models.
+ * Please see issue #4829 for more details.
+ */
+ int do_copy_in_default_stream;
+
+ /** \brief Flag indicating if there is a user provided compute stream
+ * Defaults to 0.
+ */
+ int has_user_compute_stream;
+
+ /** \brief User provided compute stream.
+ * If provided, please set `has_user_compute_stream` to 1.
+ */
+ void* user_compute_stream;
+
+ /** \brief ROCM memory arena configuration parameters
+ */
+ OrtArenaCfg* default_memory_arena_cfg;
+
+ /** \brief Enable TunableOp.
+ * Set it to 1 to enable TunableOp. Otherwise, it is disabled by default.
+ * This option can be superseded by environment variable ORT_ROCM_TUNABLE_OP_ENABLED.
+ */
+ int tunable_op_enabled;
+
+} OrtROCMProviderOptions;
+
+/** \brief TensorRT Provider Options
+ *
+ * \see OrtApi::SessionOptionsAppendExecutionProvider_TensorRT
+ */
+typedef struct OrtTensorRTProviderOptions {
+ int device_id; ///< CUDA device id (0 = default device)
+ int has_user_compute_stream; // indicator of user specified CUDA compute stream.
+ void* user_compute_stream; // user specified CUDA compute stream.
+ int trt_max_partition_iterations; // maximum iterations for TensorRT parser to get capability
+ int trt_min_subgraph_size; // minimum size of TensorRT subgraphs
+ size_t trt_max_workspace_size; // maximum workspace size for TensorRT.
+ int trt_fp16_enable; // enable TensorRT FP16 precision. Default 0 = false, nonzero = true
+ int trt_int8_enable; // enable TensorRT INT8 precision. Default 0 = false, nonzero = true
+ const char* trt_int8_calibration_table_name; // TensorRT INT8 calibration table name.
+ int trt_int8_use_native_calibration_table; // use native TensorRT generated calibration table. Default 0 = false, nonzero = true
+ int trt_dla_enable; // enable DLA. Default 0 = false, nonzero = true
+ int trt_dla_core; // DLA core number. Default 0
+ int trt_dump_subgraphs; // dump TRT subgraph. Default 0 = false, nonzero = true
+ int trt_engine_cache_enable; // enable engine caching. Default 0 = false, nonzero = true
+ const char* trt_engine_cache_path; // specify engine cache path
+ int trt_engine_decryption_enable; // enable engine decryption. Default 0 = false, nonzero = true
+ const char* trt_engine_decryption_lib_path; // specify engine decryption library path
+ int trt_force_sequential_engine_build; // force building TensorRT engine sequentially. Default 0 = false, nonzero = true
+ // This is the legacy struct and don't add new fields here.
+ // For new field that can be represented by string, please add it in include/onnxruntime/core/providers/tensorrt/tensorrt_provider_options.h
+ // For non-string field, need to create a new separate api to handle it.
+} OrtTensorRTProviderOptions;
+
+/** \brief MIGraphX Provider Options
+ *
+ * \see OrtApi::SessionOptionsAppendExecutionProvider_MIGraphX
+ */
+typedef struct OrtMIGraphXProviderOptions {
+ int device_id; // hip device id.
+ int migraphx_fp16_enable; // enable MIGraphX FP16 precision. Default 0 = false, nonzero = true
+ int migraphx_int8_enable; // enable MIGraphX INT8 precision. Default 0 = false, nonzero = true
+} OrtMIGraphXProviderOptions;
+
+/** \brief OpenVINO Provider Options
+ *
+ * \see OrtApi::SessionOptionsAppendExecutionProvider_OpenVINO
+ */
+typedef struct OrtOpenVINOProviderOptions {
+#ifdef __cplusplus
+ OrtOpenVINOProviderOptions() : device_type{}, enable_vpu_fast_compile{}, device_id{},
+ num_of_threads{}, cache_dir{},
+ context{}, enable_opencl_throttling{}, enable_dynamic_shapes{} {}
+#endif
+ /** \brief Device type string
+ *
+ * Valid settings are one of: "CPU_FP32", "CPU_FP16", "GPU_FP32", "GPU_FP16", "MYRIAD_FP16", "VAD-M_FP16" or "VAD-F_FP32"
+ */
+ const char* device_type;
+ unsigned char enable_vpu_fast_compile; ///< 0 = disabled, nonzero = enabled
+ const char* device_id;
+ size_t num_of_threads; ///< 0 = Use default number of threads
+ const char* cache_dir; // path is set to empty by default
+ void* context;
+ unsigned char enable_opencl_throttling; ///< 0 = disabled, nonzero = enabled
+ unsigned char enable_dynamic_shapes; ///< 0 = disabled, nonzero = enabled
+} OrtOpenVINOProviderOptions;
+
+struct OrtApi;
+typedef struct OrtApi OrtApi;
+
+struct OrtTrainingApi;
+typedef struct OrtTrainingApi OrtTrainingApi;
+
+/** \brief The helper interface to get the right version of OrtApi
+ *
+ * Get a pointer to this structure through ::OrtGetApiBase
+ */
+struct OrtApiBase {
+ /** \brief Get a pointer to the requested version of the ::OrtApi
+ *
+ * \param[in] version Must be ::ORT_API_VERSION
+ * \return The ::OrtApi for the version requested, nullptr will be returned if this version is unsupported, for example when using a runtime
+ * older than the version created with this header file.
+ */
+ const OrtApi*(ORT_API_CALL* GetApi)(uint32_t version)NO_EXCEPTION;
+ const char*(ORT_API_CALL* GetVersionString)(void)NO_EXCEPTION; ///< Returns a null terminated string of the version of the Onnxruntime library (eg: "1.8.1")
+};
+typedef struct OrtApiBase OrtApiBase;
+
+/** \brief The Onnxruntime library's entry point to access the C API
+ *
+ * Call this to get the a pointer to an ::OrtApiBase
+ */
+ORT_EXPORT const OrtApiBase* ORT_API_CALL OrtGetApiBase(void) NO_EXCEPTION;
+
+/** \brief Thread work loop function
+ *
+ * Onnxruntime will provide the working loop on custom thread creation
+ * Argument is an onnxruntime built-in type which will be provided when thread pool calls OrtCustomCreateThreadFn
+ */
+typedef void (*OrtThreadWorkerFn)(void* ort_worker_fn_param);
+
+typedef const struct OrtCustomHandleType {
+ char __place_holder;
+}* OrtCustomThreadHandle;
+
+/** \brief Ort custom thread creation function
+ *
+ * The function should return a thread handle to be used in onnxruntime thread pools
+ * Onnxruntime will throw exception on return value of nullptr or 0, indicating that the function failed to create a thread
+ */
+typedef OrtCustomThreadHandle (*OrtCustomCreateThreadFn)(void* ort_custom_thread_creation_options, OrtThreadWorkerFn ort_thread_worker_fn, void* ort_worker_fn_param);
+
+/** \brief Custom thread join function
+ *
+ * Onnxruntime thread pool destructor will call the function to join a custom thread.
+ * Argument ort_custom_thread_handle is the value returned by OrtCustomCreateThreadFn
+ */
+typedef void (*OrtCustomJoinThreadFn)(OrtCustomThreadHandle ort_custom_thread_handle);
+
+typedef OrtStatus*(ORT_API_CALL* RegisterCustomOpsFn)(OrtSessionOptions* options, const OrtApiBase* api);
+
+/** \brief The C API
+ *
+ * All C API functions are defined inside this structure as pointers to functions.
+ * Call OrtApiBase::GetApi to get a pointer to it
+ *
+ * \nosubgrouping
+ */
+struct OrtApi {
+ /// \name OrtStatus
+ /// @{
+
+ /**
+ * \brief Create an OrtStatus from a null terminated string
+ *
+ * \param[in] code
+ * \param[in] msg A null-terminated string. Its contents will be copied.
+ * \return A new OrtStatus object, must be destroyed with OrtApi::ReleaseStatus
+ */
+ OrtStatus*(ORT_API_CALL* CreateStatus)(OrtErrorCode code, _In_ const char* msg)NO_EXCEPTION ORT_ALL_ARGS_NONNULL;
+
+ /** \brief Get OrtErrorCode from OrtStatus
+ *
+ * \param[in] status
+ * \return OrtErrorCode that \p status was created with
+ */
+ OrtErrorCode(ORT_API_CALL* GetErrorCode)(_In_ const OrtStatus* status) NO_EXCEPTION ORT_ALL_ARGS_NONNULL;
+
+ /** \brief Get error string from OrtStatus
+ *
+ * \param[in] status
+ * \return The error message inside the `status`. Do not free the returned value.
+ */
+ const char*(ORT_API_CALL* GetErrorMessage)(_In_ const OrtStatus* status)NO_EXCEPTION ORT_ALL_ARGS_NONNULL;
+
+ /// @}
+ /// \name OrtEnv
+ /// @{
+
+ /** \brief Create an OrtEnv
+ *
+ * \param[in] log_severity_level The log severity level.
+ * \param[in] logid The log identifier.
+ * \param[out] out Returned newly created OrtEnv. Must be freed with OrtApi::ReleaseEnv
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateEnv, OrtLoggingLevel log_severity_level, _In_ const char* logid, _Outptr_ OrtEnv** out);
+
+ /** \brief Create an OrtEnv
+ *
+ * \param[in] logging_function A pointer to a logging function.
+ * \param[in] logger_param A pointer to arbitrary data passed as the ::OrtLoggingFunction `param` parameter to
+ * `logging_function`.
+ * \param[in] log_severity_level The log severity level.
+ * \param[in] logid The log identifier.
+ * \param[out] out Returned newly created OrtEnv. Must be freed with OrtApi::ReleaseEnv
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateEnvWithCustomLogger, OrtLoggingFunction logging_function, _In_opt_ void* logger_param,
+ OrtLoggingLevel log_severity_level, _In_ const char* logid, _Outptr_ OrtEnv** out);
+
+ /** \brief Enable Telemetry
+ *
+ * \note Telemetry events are on by default since they are lightweight
+ * \param[in] env
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(EnableTelemetryEvents, _In_ const OrtEnv* env);
+ /** \brief Disable Telemetry
+ *
+ * \see OrtApi::EnableTelemetryEvents
+ * \param[in] env
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(DisableTelemetryEvents, _In_ const OrtEnv* env);
+
+ /// @}
+ /// \name OrtSession
+ /// @{
+
+ /** \brief Create an OrtSession from a model file
+ *
+ * \param[in] env
+ * \param[in] model_path
+ * \param[in] options
+ * \param[out] out Returned newly created OrtSession. Must be freed with OrtApi::ReleaseSession
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ // TODO: document the path separator convention? '/' vs '\'
+ // TODO: should specify the access characteristics of model_path. Is this read only during the
+ // execution of CreateSession, or does the OrtSession retain a handle to the file/directory
+ // and continue to access throughout the OrtSession lifetime?
+ // What sort of access is needed to model_path : read or read/write?
+ ORT_API2_STATUS(CreateSession, _In_ const OrtEnv* env, _In_ const ORTCHAR_T* model_path,
+ _In_ const OrtSessionOptions* options, _Outptr_ OrtSession** out);
+
+ /** \brief Create an OrtSession from memory
+ *
+ * \param[in] env
+ * \param[in] model_data
+ * \param[in] model_data_length
+ * \param[in] options
+ * \param[out] out Returned newly created OrtSession. Must be freed with OrtApi::ReleaseSession
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateSessionFromArray, _In_ const OrtEnv* env, _In_ const void* model_data, size_t model_data_length,
+ _In_ const OrtSessionOptions* options, _Outptr_ OrtSession** out);
+
+ /** \brief Run the model in an ::OrtSession
+ *
+ * Will not return until the model run has completed. Multiple threads might be used to run the model based on
+ * the options in the ::OrtSession and settings used when creating the ::OrtEnv
+ *
+ * \param[in] session
+ * \param[in] run_options If nullptr, will use a default ::OrtRunOptions
+ * \param[in] input_names Array of null terminated UTF8 encoded strings of the input names
+ * \param[in] inputs Array of ::OrtValue%s of the input values
+ * \param[in] input_len Number of elements in the input_names and inputs arrays
+ * \param[in] output_names Array of null terminated UTF8 encoded strings of the output names
+ * \param[in] output_names_len Number of elements in the output_names and outputs array
+ * \param[out] outputs Array of ::OrtValue%s that the outputs are stored in. This can also be
+ * an array of nullptr values, in this case ::OrtValue objects will be allocated and pointers
+ * to them will be set into the `outputs` array.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(Run, _Inout_ OrtSession* session, _In_opt_ const OrtRunOptions* run_options,
+ _In_reads_(input_len) const char* const* input_names,
+ _In_reads_(input_len) const OrtValue* const* inputs, size_t input_len,
+ _In_reads_(output_names_len) const char* const* output_names, size_t output_names_len,
+ _Inout_updates_all_(output_names_len) OrtValue** outputs);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Create an ::OrtSessionOptions object
+ *
+ * To use additional providers, you must build ORT with the extra providers enabled. Then call one of these
+ * functions to enable them in the session:<br>
+ * OrtSessionOptionsAppendExecutionProvider_CPU<br>
+ * OrtSessionOptionsAppendExecutionProvider_CUDA<br>
+ * OrtSessionOptionsAppendExecutionProvider_(remaining providers...)<br>
+ * The order they are called indicates the preference order as well. In other words call this method
+ * on your most preferred execution provider first followed by the less preferred ones.
+ * If none are called Ort will use its internal CPU execution provider.
+ *
+ * \param[out] options The newly created OrtSessionOptions. Must be freed with OrtApi::ReleaseSessionOptions
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateSessionOptions, _Outptr_ OrtSessionOptions** options);
+
+ /** \brief Set filepath to save optimized model after graph level transformations
+ *
+ * \param[in] options
+ * \param[in] optimized_model_filepath
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetOptimizedModelFilePath, _Inout_ OrtSessionOptions* options,
+ _In_ const ORTCHAR_T* optimized_model_filepath);
+
+ /** \brief Create a copy of an existing ::OrtSessionOptions
+ *
+ * \param[in] in_options OrtSessionOptions to copy
+ * \param[out] out_options Returned newly created ::OrtSessionOptions. Must be freed with OrtApi::ReleaseSessionOptions
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CloneSessionOptions, _In_ const OrtSessionOptions* in_options,
+ _Outptr_ OrtSessionOptions** out_options);
+
+ /** \brief Set execution mode
+ *
+ * Controls whether you want to execute operators in your graph sequentially or in parallel. Usually when the model
+ * has many branches, setting this option to ExecutionMode.ORT_PARALLEL will give you better performance.
+ * See [docs/ONNX_Runtime_Perf_Tuning.md] for more details.
+ *
+ * \param[in] options
+ * \param[in] execution_mode
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetSessionExecutionMode, _Inout_ OrtSessionOptions* options, ExecutionMode execution_mode);
+
+ /** \brief Enable profiling for a session
+ *
+ * \param[in] options
+ * \param[in] profile_file_prefix
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(EnableProfiling, _Inout_ OrtSessionOptions* options, _In_ const ORTCHAR_T* profile_file_prefix);
+
+ /** \brief Disable profiling for a session
+ *
+ * \param[in] options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(DisableProfiling, _Inout_ OrtSessionOptions* options);
+
+ /** \brief Enable the memory pattern optimization
+ *
+ * The idea is if the input shapes are the same, we could trace the internal memory allocation
+ * and generate a memory pattern for future request. So next time we could just do one allocation
+ * with a big chunk for all the internal memory allocation.
+ * \note Memory pattern optimization is only available when Sequential Execution mode is enabled (see OrtApi::SetSessionExecutionMode)
+ *
+ * \see OrtApi::DisableMemPattern
+ *
+ * \param[in] options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(EnableMemPattern, _Inout_ OrtSessionOptions* options);
+
+ /** \brief Disable the memory pattern optimization
+ *
+ * \see OrtApi::EnableMemPattern
+ *
+ * \param[in] options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(DisableMemPattern, _Inout_ OrtSessionOptions* options);
+
+ /** \brief Enable the memory arena on CPU
+ *
+ * Arena may pre-allocate memory for future usage.
+ *
+ * \param[in] options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(EnableCpuMemArena, _Inout_ OrtSessionOptions* options);
+
+ /** \brief Disable the memory arena on CPU
+ *
+ * \param[in] options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(DisableCpuMemArena, _Inout_ OrtSessionOptions* options);
+
+ /** \brief Set session log id
+ *
+ * \param[in] options
+ * \param[in] logid The log identifier.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetSessionLogId, _Inout_ OrtSessionOptions* options, const char* logid);
+
+ /** \brief Set session log verbosity level
+ *
+ * Applies to session load, initialization, etc
+ *
+ * \param[in] options
+ * \param[in] session_log_verbosity_level \snippet{doc} snippets.dox Log Verbosity Level
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetSessionLogVerbosityLevel, _Inout_ OrtSessionOptions* options, int session_log_verbosity_level);
+
+ /** \brief Set session log severity level
+ *
+ * \param[in] options
+ * \param[in] session_log_severity_level The log severity level (refer to ::OrtLoggingLevel for possible values).
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetSessionLogSeverityLevel, _Inout_ OrtSessionOptions* options, int session_log_severity_level);
+
+ /** \brief Set the optimization level to apply when loading a graph
+ *
+ * Please see https://www.onnxruntime.ai/docs/resources/graph-optimizations.html for an in-depth explanation
+ * \param[in,out] options The session options object
+ * \param[in] graph_optimization_level The optimization level
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetSessionGraphOptimizationLevel, _Inout_ OrtSessionOptions* options,
+ GraphOptimizationLevel graph_optimization_level);
+
+ /** \brief Sets the number of threads used to parallelize the execution within nodes
+ *
+ * When running a single node operation, ex. add, this sets the maximum number of threads to use.
+ *
+ * \note If built with OpenMP, this has no effect on the number of threads used. In this case
+ * use the OpenMP env variables to configure the number of intra op num threads.
+ *
+ * \param[in] options
+ * \param[in] intra_op_num_threads Number of threads to use<br>
+ * A value of 0 will use the default number of threads<br>
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetIntraOpNumThreads, _Inout_ OrtSessionOptions* options, int intra_op_num_threads);
+
+ /** \brief Sets the number of threads used to parallelize the execution of the graph
+ *
+ * If nodes can be run in parallel, this sets the maximum number of threads to use to run them in parallel.
+ *
+ * \note If sequential execution is enabled this value is ignored, it acts as if it was set to 1.
+ *
+ * \param[in] options
+ * \param[in] inter_op_num_threads Number of threads to use<br>
+ * A value of 0 will use the default number of threads<br>
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetInterOpNumThreads, _Inout_ OrtSessionOptions* options, int inter_op_num_threads);
+
+ /// @}
+ /// \name OrtCustomOpDomain
+ /// @{
+
+ /** \brief Create a custom op domain
+ *
+ * \param[in] domain
+ * \param[out] out Newly created domain. Must be freed with OrtApi::ReleaseCustomOpDomain
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateCustomOpDomain, _In_ const char* domain, _Outptr_ OrtCustomOpDomain** out);
+
+ /** \brief Add a custom op to a custom op domain
+ *
+ * \note The OrtCustomOp* pointer must remain valid until the ::OrtCustomOpDomain using it is released
+ *
+ * \param[in] custom_op_domain
+ * \param[in] op
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CustomOpDomain_Add, _Inout_ OrtCustomOpDomain* custom_op_domain, _In_ const OrtCustomOp* op);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Add custom op domain to a session options
+ *
+ * \note The OrtCustomOpDomain* must not be deleted until all sessions using it are released
+ *
+ * \param[in] options
+ * \param[in] custom_op_domain
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(AddCustomOpDomain, _Inout_ OrtSessionOptions* options, _In_ OrtCustomOpDomain* custom_op_domain);
+
+ /** \deprecated Use OrtApi::RegisterCustomOpsLibrary_V2.
+ *
+ * Registers custom ops from a shared library.
+ *
+ * Loads a shared library (dll on windows, so on linux, etc) named 'library_path' and looks for this entry point:
+ * OrtStatus* RegisterCustomOps(OrtSessionOptions * options, const OrtApiBase* api);
+ * It then passes in the provided session options to this function along with the api base.
+ * The handle to the loaded library is returned in library_handle. It can be freed by the caller after all sessions using the passed in
+ * session options are destroyed, or if an error occurs and it is non null.
+ *
+ * \param[in] options
+ * \param[in] library_path
+ * \param[out] library_handle OS specific handle to the loaded library (Use FreeLibrary on Windows, dlclose on Linux, etc.. to unload)
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(RegisterCustomOpsLibrary, _Inout_ OrtSessionOptions* options, _In_ const char* library_path, _Outptr_ void** library_handle);
+
+ /// @}
+ /// \name OrtSession
+ /// @{
+
+ /** \brief Get input count for a session
+ *
+ * This number must also match the number of inputs passed to OrtApi::Run
+ *
+ * \see OrtApi::SessionGetInputTypeInfo, OrtApi::SessionGetInputName, OrtApi::Session
+ *
+ * \param[in] session
+ * \param[out] out Number of inputs
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetInputCount, _In_ const OrtSession* session, _Out_ size_t* out);
+
+ /** \brief Get output count for a session
+ *
+ * This number must also match the number of outputs returned by OrtApi::Run
+ *
+ * \see OrtApi::SessionGetOutputTypeInfo, OrtApi::SessionGetOutputName, OrtApi::Session
+ *
+ * \param[in] session
+ * \param[out] out Number of outputs
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetOutputCount, _In_ const OrtSession* session, _Out_ size_t* out);
+
+ /** \brief Get overridable initializer count
+ *
+ * \see OrtApi::SessionGetOverridableInitializerTypeInfo, OrtApi::SessionGetOverridableInitializerName
+ *
+ * \param[in] session
+ * \param[in] out
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetOverridableInitializerCount, _In_ const OrtSession* session, _Out_ size_t* out);
+
+ /** \brief Get input type information
+ *
+ * \param[in] session
+ * \param[in] index Must be between 0 (inclusive) and what OrtApi::SessionGetInputCount returns (exclusive)
+ * \param[out] type_info Must be freed with OrtApi::ReleaseTypeInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetInputTypeInfo, _In_ const OrtSession* session, size_t index, _Outptr_ OrtTypeInfo** type_info);
+
+ /** \brief Get output type information
+ *
+ * \param[in] session
+ * \param[in] index Must be between 0 (inclusive) and what OrtApi::SessionGetOutputCount returns (exclusive)
+ * \param[out] type_info Must be freed with OrtApi::ReleaseTypeInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetOutputTypeInfo, _In_ const OrtSession* session, size_t index, _Outptr_ OrtTypeInfo** type_info);
+
+ /** \brief Get overridable initializer type information
+ *
+ * \param[in] session
+ * \param[in] index Must be between 0 (inclusive) and what OrtApi::SessionGetOverridableInitializerCount returns (exclusive)
+ * \param[out] type_info Must be freed with OrtApi::ReleaseTypeInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetOverridableInitializerTypeInfo, _In_ const OrtSession* session, size_t index, _Outptr_ OrtTypeInfo** type_info);
+
+ /** \brief Get input name
+ *
+ * \param[in] session
+ * \param[in] index Must be between 0 (inclusive) and what OrtApi::SessionGetInputCount returns (exclusive)
+ * \param[in] allocator
+ * \param[out] value Set to a null terminated UTF-8 encoded string allocated using `allocator`. Must be freed using `allocator`.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetInputName, _In_ const OrtSession* session, size_t index, _Inout_ OrtAllocator* allocator, _Outptr_ char** value);
+
+ /** \brief Get output name
+ *
+ * \param[in] session
+ * \param[in] index Must be between 0 (inclusive) and what OrtApi::SessionGetOutputCount returns (exclusive)
+ * \param[in] allocator
+ * \param[out] value Set to a null terminated UTF-8 encoded string allocated using `allocator`. Must be freed using `allocator`.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetOutputName, _In_ const OrtSession* session, size_t index, _Inout_ OrtAllocator* allocator, _Outptr_ char** value);
+
+ /** \brief Get overridable initializer name
+ *
+ * \param[in] session
+ * \param[in] index Must be between 0 (inclusive) and what OrtApi::SessionGetOverridableInitializerCount returns (exclusive)
+ * \param[in] allocator
+ * \param[out] value Set to a null terminated UTF-8 encoded string allocated using `allocator`. Must be freed using `allocator`.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetOverridableInitializerName, _In_ const OrtSession* session, size_t index,
+ _Inout_ OrtAllocator* allocator, _Outptr_ char** value);
+
+ /// @}
+ /// \name OrtRunOptions
+ /// @{
+
+ /** \brief Create an OrtRunOptions
+ *
+ * \param[out] out Returned newly created ::OrtRunOptions. Must be freed with OrtApi::ReleaseRunOptions
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateRunOptions, _Outptr_ OrtRunOptions** out);
+
+ /** \brief Set per-run log verbosity level
+ *
+ * \see OrtApi::RunOptionsGetRunLogVerbosityLevel
+ *
+ * \param[in] options
+ * \param[in] log_verbosity_level \snippet{doc} snippets.dox Log Verbosity Level
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(RunOptionsSetRunLogVerbosityLevel, _Inout_ OrtRunOptions* options, int log_verbosity_level);
+
+ /** \brief Set per-run log severity level
+ *
+ * \see OrtApi::RunOptionsGetRunLogSeverityLevel
+ *
+ * \param[in] options
+ * \param[in] log_severity_level The log severity level (refer to ::OrtLoggingLevel for possible values).
+ */
+ ORT_API2_STATUS(RunOptionsSetRunLogSeverityLevel, _Inout_ OrtRunOptions* options, int log_severity_level);
+
+ /** \brief Set per-run tag
+ *
+ * This is used in a per-run log identifier.
+ *
+ * \see OrtApi::RunOptionsGetRunTag
+ *
+ * \param[in] options
+ * \param[in] run_tag The run tag.
+ */
+ ORT_API2_STATUS(RunOptionsSetRunTag, _Inout_ OrtRunOptions* options, _In_ const char* run_tag);
+
+ /** \brief Get per-run log verbosity level
+ *
+ * \see OrtApi::RunOptionsSetRunLogVerbosityLevel
+ *
+ * \param[in] options
+ * \param[out] log_verbosity_level \snippet{doc} snippets.dox Log Verbosity Level
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(RunOptionsGetRunLogVerbosityLevel, _In_ const OrtRunOptions* options,
+ _Out_ int* log_verbosity_level);
+
+ /** \brief Get per-run log severity level
+ *
+ * \see OrtApi::RunOptionsSetRunLogSeverityLevel
+ *
+ * \param[in] options
+ * \param[out] log_severity_level The log severity level (refer to ::OrtLoggingLevel for possible values).
+ */
+ ORT_API2_STATUS(RunOptionsGetRunLogSeverityLevel, _In_ const OrtRunOptions* options, _Out_ int* log_severity_level);
+
+ /** \brief Get per-run tag
+ *
+ * This is used in a per-run log identifier.
+ *
+ * \see OrtApi::RunOptionsSetRunTag
+ *
+ * \param[in] options
+ * \param[out] run_tag The run tag.
+ * Do not free this value, it is owned by `options`. It will be invalidated if the run tag
+ * changes (i.e., with OrtApi::RunOptionsSetRunTag) or `options` is freed.
+ */
+ ORT_API2_STATUS(RunOptionsGetRunTag, _In_ const OrtRunOptions* options, _Out_ const char** run_tag);
+
+ /** \brief Set terminate flag
+ *
+ * If a currently executing session needs to be force terminated, this can be called from another thread to force it to fail with an error.
+ *
+ * \param[in] options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(RunOptionsSetTerminate, _Inout_ OrtRunOptions* options);
+
+ /** \brief Clears the terminate flag
+ *
+ * Used so the OrtRunOptions instance can be used in a new OrtApi::Run call without it instantly terminating
+ *
+ * \param[in] options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(RunOptionsUnsetTerminate, _Inout_ OrtRunOptions* options);
+
+ /// @}
+ /// \name OrtValue
+ /// @{
+
+ /** \brief Create a tensor
+ *
+ * Create a tensor using a supplied ::OrtAllocator
+ *
+ * \param[in] allocator
+ * \param[in] shape Pointer to the tensor shape dimensions.
+ * \param[in] shape_len The number of tensor shape dimensions.
+ * \param[in] type
+ * \param[out] out Returns newly created ::OrtValue. Must be freed with OrtApi::ReleaseValue
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateTensorAsOrtValue, _Inout_ OrtAllocator* allocator, _In_ const int64_t* shape, size_t shape_len,
+ ONNXTensorElementDataType type, _Outptr_ OrtValue** out);
+
+ /** \brief Create a tensor backed by a user supplied buffer
+ *
+ * Create a tensor with user's buffer. You can fill the buffer either before calling this function or after.
+ * p_data is owned by caller. ReleaseValue won't release p_data.
+ *
+ * \param[in] info Memory description of where the p_data buffer resides (CPU vs GPU etc).
+ * \param[in] p_data Pointer to the data buffer.
+ * \param[in] p_data_len The number of bytes in the data buffer.
+ * \param[in] shape Pointer to the tensor shape dimensions.
+ * \param[in] shape_len The number of tensor shape dimensions.
+ * \param[in] type The data type.
+ * \param[out] out Returns newly created ::OrtValue. Must be freed with OrtApi::ReleaseValue
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateTensorWithDataAsOrtValue, _In_ const OrtMemoryInfo* info, _Inout_ void* p_data,
+ size_t p_data_len, _In_ const int64_t* shape, size_t shape_len, ONNXTensorElementDataType type,
+ _Outptr_ OrtValue** out);
+
+ /** \brief Return if an ::OrtValue is a tensor type
+ *
+ * \param[in] value A tensor type (string tensors are not supported)
+ * \param[out] out Set to 1 iff ::OrtValue is a tensor, 0 otherwise
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(IsTensor, _In_ const OrtValue* value, _Out_ int* out);
+
+ /** \brief Get a pointer to the raw data inside a tensor
+ *
+ * Used to read/write/modify the internal tensor data directly.
+ * \note The returned pointer is valid until the \p value is destroyed.
+ *
+ * \param[in] value A tensor type (string tensors are not supported)
+ * \param[out] out Filled in with a pointer to the internal storage
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetTensorMutableData, _In_ OrtValue* value, _Outptr_ void** out);
+
+ /** \brief Set all strings at once in a string tensor
+ *
+ * \param[in,out] value A tensor of type ONNX_TENSOR_ELEMENT_DATA_TYPE_STRING
+ * \param[in] s An array of strings. Each string in this array must be null terminated.
+ * \param[in] s_len Count of strings in s (Must match the size of \p value's tensor shape)
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(FillStringTensor, _Inout_ OrtValue* value, _In_ const char* const* s, size_t s_len);
+
+ /** \brief Get total byte length for all strings in a string tensor
+ *
+ * Typically used with OrtApi::GetStringTensorContent
+ *
+ * \param[in] value A tensor of type ONNX_TENSOR_ELEMENT_DATA_TYPE_STRING
+ * \param[out] len Total byte length of all strings (does not include trailing nulls)
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetStringTensorDataLength, _In_ const OrtValue* value, _Out_ size_t* len);
+
+ /** \brief Get all strings from a string tensor
+ *
+ * An example of the results:<br>
+ * Given \p value is a string tensor with the strings { "This" "is" "a" "test" }<br>
+ * \p s must have a size of 11 bytes<br>
+ * \p offsets must have 4 elements<br>
+ * After the call, these values will be filled in:<br>
+ * \p s will contain "Thisisatest"<br>
+ * \p offsets will contain { 0, 4, 6, 7 }<br>
+ * The length of the last string is just s_len - offsets[last]
+ *
+ * \param[in] value A tensor of type ONNX_TENSOR_ELEMENT_DATA_TYPE_STRING
+ * \param[in] s Buffer to sequentially write all tensor strings to. Each string is NOT null-terminated.
+ * \param[in] s_len Number of bytes of buffer pointed to by \p s (Get it from OrtApi::GetStringTensorDataLength)
+ * \param[out] offsets Array of start offsets into the strings written to \p s
+ * \param[in] offsets_len Number of elements in offsets
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetStringTensorContent, _In_ const OrtValue* value, _Out_writes_bytes_all_(s_len) void* s,
+ size_t s_len, _Out_writes_all_(offsets_len) size_t* offsets, size_t offsets_len);
+
+ /// @}
+ /// \name OrtTypeInfo
+ /// @{
+
+ /** \brief Get ::OrtTensorTypeAndShapeInfo from an ::OrtTypeInfo
+ *
+ * \param[in] type_info
+ * \param[out] out Do not free this value, it will be valid until type_info is freed.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CastTypeInfoToTensorInfo, _In_ const OrtTypeInfo* type_info,
+ _Outptr_result_maybenull_ const OrtTensorTypeAndShapeInfo** out);
+
+ /** \brief Get ::ONNXType from ::OrtTypeInfo
+ *
+ * \param[in] type_info
+ * \param[out] out
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetOnnxTypeFromTypeInfo, _In_ const OrtTypeInfo* type_info, _Out_ enum ONNXType* out);
+
+ /// @}
+ /// \name OrtTensorTypeAndShapeInfo
+ /// @{
+
+ /** \brief Create an ::OrtTensorTypeAndShapeInfo object
+ *
+ * \param[out] out Returns newly created ::OrtTensorTypeAndShapeInfo. Must be freed with OrtApi::ReleaseTensorTypeAndShapeInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateTensorTypeAndShapeInfo, _Outptr_ OrtTensorTypeAndShapeInfo** out);
+
+ /** \brief Set element type in ::OrtTensorTypeAndShapeInfo
+ *
+ * \param[in] info
+ * \param[in] type
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetTensorElementType, _Inout_ OrtTensorTypeAndShapeInfo* info, enum ONNXTensorElementDataType type);
+
+ /** \brief Set shape information in ::OrtTensorTypeAndShapeInfo
+ *
+ * \param[in] info
+ * \param[in] dim_values Array with `dim_count` elements. Can contain negative values.
+ * \param[in] dim_count Number of elements in `dim_values`
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetDimensions, OrtTensorTypeAndShapeInfo* info, _In_ const int64_t* dim_values, size_t dim_count);
+
+ /** \brief Get element type in ::OrtTensorTypeAndShapeInfo
+ *
+ * \see OrtApi::SetTensorElementType
+ *
+ * \param[in] info
+ * \param[out] out
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetTensorElementType, _In_ const OrtTensorTypeAndShapeInfo* info,
+ _Out_ enum ONNXTensorElementDataType* out);
+
+ /** \brief Get dimension count in ::OrtTensorTypeAndShapeInfo
+ *
+ * \see OrtApi::GetDimensions
+ *
+ * \param[in] info
+ * \param[out] out
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetDimensionsCount, _In_ const OrtTensorTypeAndShapeInfo* info, _Out_ size_t* out);
+
+ /** \brief Get dimensions in ::OrtTensorTypeAndShapeInfo
+ *
+ * \param[in] info
+ * \param[out] dim_values Array with `dim_values_length` elements. On return, filled with the dimensions stored in the ::OrtTensorTypeAndShapeInfo
+ * \param[in] dim_values_length Number of elements in `dim_values`. Use OrtApi::GetDimensionsCount to get this value
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetDimensions, _In_ const OrtTensorTypeAndShapeInfo* info, _Out_ int64_t* dim_values,
+ size_t dim_values_length);
+
+ /** \brief Get symbolic dimension names in ::OrtTensorTypeAndShapeInfo
+ *
+ * \param[in] info
+ * \param[in] dim_params Array with `dim_params_length` elements. On return filled with pointers to null terminated strings of the dimension names
+ * \param[in] dim_params_length Number of elements in `dim_params`. Use OrtApi::GetDimensionsCount to get this value
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetSymbolicDimensions, _In_ const OrtTensorTypeAndShapeInfo* info,
+ _Out_writes_all_(dim_params_length) const char* dim_params[], size_t dim_params_length);
+
+ /** \brief Get total number of elements in a tensor shape from an ::OrtTensorTypeAndShapeInfo
+ *
+ * Return the number of elements specified by the tensor shape (all dimensions multiplied by each other).
+ * For 0 dimensions, 1 is returned. If any dimension is less than 0, the result is always -1.
+ *
+ * Examples:<br>
+ * [] = 1<br>
+ * [1,3,4] = 12<br>
+ * [2,0,4] = 0<br>
+ * [-1,3,4] = -1<br>
+ *
+ * \param[in] info
+ * \param[out] out Number of elements
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetTensorShapeElementCount, _In_ const OrtTensorTypeAndShapeInfo* info, _Out_ size_t* out);
+
+ /// @}
+ /// \name OrtValue
+ /// @{
+
+ /** \brief Get type and shape information from a tensor ::OrtValue
+ *
+ * \param[in] value Must be a tensor (not a map/sequence/etc) or will return failure
+ * \param[out] out Newly created ::OrtTensorTypeAndShapeInfo. Must be freed with OrtApi::ReleaseTensorTypeAndShapeInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetTensorTypeAndShape, _In_ const OrtValue* value, _Outptr_ OrtTensorTypeAndShapeInfo** out);
+
+ /** \brief Get type information of an OrtValue
+ *
+ * \param[in] value
+ * \param[out] out Newly created ::OrtTypeInfo. Must be freed with OrtApi::ReleaseTypeInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetTypeInfo, _In_ const OrtValue* value, _Outptr_result_maybenull_ OrtTypeInfo** out);
+
+ /** \brief Get ONNXType of an ::OrtValue
+ *
+ * \param[in] value
+ * \param[out] out
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetValueType, _In_ const OrtValue* value, _Out_ enum ONNXType* out);
+
+ /// @}
+ /// \name OrtMemoryInfo
+ /// @{
+
+ /** \brief Create an ::OrtMemoryInfo
+ *
+ * \param[in] name
+ * \param[in] type
+ * \param[in] id
+ * \param[in] mem_type
+ * \param[out] out Newly created ::OrtMemoryInfo. Must be freed with OrtAPi::ReleaseMemoryInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateMemoryInfo, _In_ const char* name, enum OrtAllocatorType type, int id,
+ enum OrtMemType mem_type, _Outptr_ OrtMemoryInfo** out);
+
+ /** \brief Create an ::OrtMemoryInfo for CPU memory
+ *
+ * Special case version of OrtApi::CreateMemoryInfo for CPU based memory. Same as using OrtApi::CreateMemoryInfo with name = "Cpu" and id = 0.
+ *
+ * \param[in] type
+ * \param[in] mem_type
+ * \param[out] out
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateCpuMemoryInfo, enum OrtAllocatorType type, enum OrtMemType mem_type,
+ _Outptr_ OrtMemoryInfo** out);
+
+ /** \brief Compare ::OrtMemoryInfo objects for equality
+ *
+ * Compares all settings of each ::OrtMemoryInfo for equality
+ *
+ * \param[in] info1
+ * \param[in] info2
+ * \param[out] out Set to 0 if equal, -1 if not equal
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CompareMemoryInfo, _In_ const OrtMemoryInfo* info1, _In_ const OrtMemoryInfo* info2, _Out_ int* out);
+
+ /** \brief Get name from ::OrtMemoryInfo
+ *
+ * \param[in] ptr
+ * \param[out] out Writes null terminated string to this pointer. Do NOT free the returned pointer. It is valid for the lifetime of the ::OrtMemoryInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(MemoryInfoGetName, _In_ const OrtMemoryInfo* ptr, _Out_ const char** out);
+
+ /** \brief Get the id from ::OrtMemoryInfo
+ */
+ ORT_API2_STATUS(MemoryInfoGetId, _In_ const OrtMemoryInfo* ptr, _Out_ int* out);
+
+ /** \brief Get the ::OrtMemType from ::OrtMemoryInfo
+ */
+ ORT_API2_STATUS(MemoryInfoGetMemType, _In_ const OrtMemoryInfo* ptr, _Out_ OrtMemType* out);
+
+ /** \brief Get the ::OrtAllocatorType from ::OrtMemoryInfo
+ */
+ ORT_API2_STATUS(MemoryInfoGetType, _In_ const OrtMemoryInfo* ptr, _Out_ OrtAllocatorType* out);
+
+ /// @}
+ /// \name OrtAllocator
+ /// @{
+
+ /// \brief Calls OrtAllocator::Alloc function
+ ORT_API2_STATUS(AllocatorAlloc, _Inout_ OrtAllocator* ort_allocator, size_t size, _Outptr_ void** out);
+ /// \brief Calls OrtAllocator::Free function
+ ORT_API2_STATUS(AllocatorFree, _Inout_ OrtAllocator* ort_allocator, void* p);
+ /// \brief Calls OrtAllocator::Info function
+ ORT_API2_STATUS(AllocatorGetInfo, _In_ const OrtAllocator* ort_allocator, _Outptr_ const struct OrtMemoryInfo** out);
+
+ /** \brief Get the default allocator
+ *
+ * The default allocator is a CPU based, non-arena. Always returns the same pointer to the same default allocator.
+ *
+ * \param[out] out Returned value should NOT be freed
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetAllocatorWithDefaultOptions, _Outptr_ OrtAllocator** out);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Override session symbolic dimensions
+ *
+ * Override symbolic dimensions (by specific denotation strings) with actual values if known at session initialization time to enable
+ * optimizations that can take advantage of fixed values (such as memory planning, etc)
+ *
+ * \param[in] options
+ * \param[in] dim_denotation
+ * \param[in] dim_value
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(AddFreeDimensionOverride, _Inout_ OrtSessionOptions* options, _In_ const char* dim_denotation,
+ _In_ int64_t dim_value);
+
+ /// @}
+ /// \name OrtValue
+ /// @{
+
+ /* Internal information (not seen in Doxygen)
+ *
+ * APIs to support non-tensor types - map and sequence.
+ * Currently only the following types are supported
+ * Note: the following types should be kept in sync with data_types.h
+ * Map types
+ * =========
+ * std::map<std::string, std::string>
+ * std::map<std::string, int64_t>
+ * std::map<std::string, float>
+ * std::map<std::string, double>
+ * std::map<int64_t, std::string>
+ * std::map<int64_t, int64_t>
+ * std::map<int64_t, float>
+ * std::map<int64_t, double>
+ *
+ * Sequence types
+ * ==============
+ * std::vector<std::string>
+ * std::vector<int64_t>
+ * std::vector<float>
+ * std::vector<double>
+ * std::vector<std::map<std::string, float>>
+ * std::vector<std::map<int64_t, float>
+ */
+
+ /** \brief Get non tensor data from an ::OrtValue
+ *
+ * If `value` is of type ONNX_TYPE_MAP, you need to retrieve the keys and values
+ * separately. Use index=0 to retrieve keys and index=1 to retrieve values.
+ * If `value` is of type ONNX_TYPE_SEQUENCE, use index to retrieve the index'th element
+ * of the sequence.
+ *
+ * \param[in] value
+ * \param[in] index See above for usage based on `value` type
+ * \param[in] allocator Allocator used to allocate ::OrtValue
+ * \param[out] out Created ::OrtValue that holds the element requested. Must be freed with OrtApi::ReleaseValue
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetValue, _In_ const OrtValue* value, int index, _Inout_ OrtAllocator* allocator,
+ _Outptr_ OrtValue** out);
+
+ /** \brief Get non tensor value count from an ::OrtValue
+ *
+ * If `value` is of type ONNX_TYPE_MAP 2 will always be returned. For ONNX_TYPE_SEQUENCE
+ * the number of elements in the sequence will be returned
+ *
+ * \param[in] value
+ * \param[out] out
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetValueCount, _In_ const OrtValue* value, _Out_ size_t* out);
+
+ /** \brief Create a map or sequence ::OrtValue
+ *
+ * To construct a map (ONNX_TYPE_MAP), use num_values = 2 and `in` should be an array of 2 ::OrtValue%s
+ * representing keys and values.<br>
+ *
+ * To construct a sequence (ONNX_TYPE_SEQUENCE), use num_values = N where N is the number of the elements in the
+ * sequence. 'in' should be an array of N ::OrtValue%s.
+ *
+ * \param[in] in See above for details
+ * \param[in] num_values
+ * \param[in] value_type Must be either ONNX_TYPE_MAP or ONNX_TYPE_SEQUENCE
+ * \param[out] out Newly created ::OrtValue. Must be freed with OrtApi::ReleaseValue
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateValue, _In_reads_(num_values) const OrtValue* const* in, size_t num_values,
+ enum ONNXType value_type, _Outptr_ OrtValue** out);
+
+ /** \brief Create an opaque (custom user defined type) ::OrtValue
+ *
+ * Constructs an ::OrtValue that contains a value of non-standard type created for
+ * experiments or while awaiting standardization. ::OrtValue in this case would contain
+ * an internal representation of the Opaque type. Opaque types are distinguished from
+ * each other by two strings 1) domain and 2) type name. The combination of the two
+ * must be unique, so the type representation is properly identified internally. The combination
+ * must be properly registered from within ORT at both compile/run time or by another API.
+ *
+ * To construct the ::OrtValue pass domain and type names, also a pointer to a data container
+ * the type of which must be known to both ORT and the client program. That data container may or may
+ * not match the internal representation of the Opaque type. The sizeof(data_container) is passed for
+ * verification purposes.
+ *
+ * \param[in] domain_name Null terminated string of the domain name
+ * \param[in] type_name Null terminated string of the type name
+ * \param[in] data_container User pointer Data to populate ::OrtValue
+ * \param[in] data_container_size Size in bytes of what `data_container` points to
+ * \param[out] out Newly created ::OrtValue. Must be freed with OrtApi::ReleaseValue
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateOpaqueValue, _In_z_ const char* domain_name, _In_z_ const char* type_name,
+ _In_ const void* data_container, size_t data_container_size, _Outptr_ OrtValue** out);
+
+ /** \brief Get internal data from an opaque (custom user defined type) ::OrtValue
+ *
+ * Copies internal data from an opaque value into a user provided buffer
+ *
+ * \see OrtApi::CreateOpaqueValue
+ *
+ * \param[in] domain_name Null terminated string of the domain name
+ * \param[in] type_name Null terminated string of the type name
+ * \param[in] in The opaque ::OrtValue
+ * \param[out] data_container Buffer to copy data into
+ * \param[out] data_container_size Size in bytes of the buffer pointed to by data_container. Must match the size of the internal buffer.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetOpaqueValue, _In_ const char* domain_name, _In_ const char* type_name, _In_ const OrtValue* in,
+ _Out_ void* data_container, size_t data_container_size);
+
+ /// @}
+ /// \name OrtKernelInfo
+ /// Custom operator APIs.
+ /// @{
+
+ /** \brief Get a float stored as an attribute in the graph node
+ *
+ * \param[in] info ::OrtKernelInfo instance
+ * \param[in] name Null terminated string of the name of the attribute
+ * \param[out] out Pointer to memory where the attribute will be stored
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(KernelInfoGetAttribute_float, _In_ const OrtKernelInfo* info, _In_ const char* name,
+ _Out_ float* out);
+
+ /** \brief Fetch a 64-bit int stored as an attribute in the graph node
+ *
+ * \param[in] info ::OrtKernelInfo instance
+ * \param[in] name Null terminated string of the name of the attribute
+ * \param[out] out Pointer to memory where the attribute will be stored
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(KernelInfoGetAttribute_int64, _In_ const OrtKernelInfo* info, _In_ const char* name,
+ _Out_ int64_t* out);
+
+ /** \brief Fetch a string stored as an attribute in the graph node
+ *
+ * If `out` is nullptr, the value of `size` is set to the true size of the string
+ * attribute, and a success status is returned.
+ *
+ * If the `size` parameter is greater than or equal to the actual string attribute's size,
+ * the value of `size` is set to the true size of the string attribute, the provided memory
+ * is filled with the attribute's contents, and a success status is returned.
+ *
+ * If the `size` parameter is less than the actual string attribute's size and `out`
+ * is not nullptr, the value of `size` is set to the true size of the string attribute
+ * and a failure status is returned.)
+ *
+ * \param[in] info ::OrtKernelInfo instance
+ * \param[in] name Null terminated string of the name of the attribute
+ * \param[out] out Pointer to memory where the attribute will be stored
+ * \param[in,out] size See above comments for details
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(KernelInfoGetAttribute_string, _In_ const OrtKernelInfo* info, _In_ const char* name, _Out_ char* out,
+ _Inout_ size_t* size);
+
+ /// @}
+ /// \name OrtKernelContext
+ /// Custom operator APIs.
+ /// @{
+
+ /** \brief Used for custom operators, get the input count of a kernel
+ *
+ * \see ::OrtCustomOp
+ */
+ ORT_API2_STATUS(KernelContext_GetInputCount, _In_ const OrtKernelContext* context, _Out_ size_t* out);
+
+ /** \brief Used for custom operators, get the output count of a kernel
+ *
+ * \see ::OrtCustomOp
+ */
+ ORT_API2_STATUS(KernelContext_GetOutputCount, _In_ const OrtKernelContext* context, _Out_ size_t* out);
+
+ /** \brief Used for custom operators, get an input of a kernel
+ *
+ * \see ::OrtCustomOp
+ */
+ ORT_API2_STATUS(KernelContext_GetInput, _In_ const OrtKernelContext* context, _In_ size_t index,
+ _Out_ const OrtValue** out);
+
+ /** \brief Used for custom operators, get an output of a kernel
+ *
+ * \see ::OrtCustomOp
+ */
+ ORT_API2_STATUS(KernelContext_GetOutput, _Inout_ OrtKernelContext* context, _In_ size_t index,
+ _In_ const int64_t* dim_values, size_t dim_count, _Outptr_ OrtValue** out);
+
+ /// @}
+ /// \name OrtEnv
+ /// @{
+ ORT_CLASS_RELEASE(Env);
+ /// @}
+ /// \name OrtStatus
+ /// @{
+ ORT_CLASS_RELEASE(Status);
+ /// @}
+ /// \name OrtMemoryInfo
+ /// @{
+ ORT_CLASS_RELEASE(MemoryInfo);
+ /// @}
+ /// \name OrtSession
+ /// @{
+ ORT_CLASS_RELEASE(Session); // Don't call ReleaseSession from Dllmain (because session owns a thread pool)
+ /// @}
+ /// \name OrtValue
+ /// @{
+ ORT_CLASS_RELEASE(Value);
+ /// @}
+ /// \name OrtRunOptions
+ /// @{
+ ORT_CLASS_RELEASE(RunOptions);
+ /// @}
+ /// \name OrtTypeInfo
+ /// @{
+ ORT_CLASS_RELEASE(TypeInfo);
+ /// @}
+ /// \name OrtTensorTypeAndShapeInfo
+ /// @{
+ ORT_CLASS_RELEASE(TensorTypeAndShapeInfo);
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+ ORT_CLASS_RELEASE(SessionOptions);
+ /// @}
+ /// \name OrtCustomOpDomain
+ /// @{
+ ORT_CLASS_RELEASE(CustomOpDomain);
+
+ /// @}
+ /// \name OrtTypeInfo
+ /// @{
+
+ /** \brief Get denotation from type information
+ *
+ * Augments ::OrtTypeInfo to return denotations on the type.
+ *
+ * This is used by WinML to determine if an input/output is intended to be an Image or a Tensor.
+ *
+ * \param[in] type_info
+ * \param[out] denotation Pointer to the null terminated denotation string is written to this pointer. This pointer is valid until the object is destroyed or the name is changed, do not free.
+ * \param[out] len Length in bytes of the string returned in `denotation`
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetDenotationFromTypeInfo, _In_ const OrtTypeInfo* type_info, _Out_ const char** const denotation,
+ _Out_ size_t* len);
+
+ /** \brief Get detailed map information from an ::OrtTypeInfo
+ *
+ * This augments ::OrtTypeInfo to return an ::OrtMapTypeInfo when the type is a map.
+ * The OrtMapTypeInfo has additional information about the map's key type and value type.
+ *
+ * This is used by WinML to support model reflection APIs.
+ *
+ * \param[out] type_info
+ * \param[out] out A pointer to the ::OrtMapTypeInfo. Do not free this value
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CastTypeInfoToMapTypeInfo, _In_ const OrtTypeInfo* type_info,
+ _Outptr_result_maybenull_ const OrtMapTypeInfo** out);
+
+ /** \brief Cast ::OrtTypeInfo to an ::OrtSequenceTypeInfo
+ *
+ * This api augments ::OrtTypeInfo to return an ::OrtSequenceTypeInfo when the type is a sequence.
+ * The ::OrtSequenceTypeInfo has additional information about the sequence's element type.
+ *
+ * This is used by WinML to support model reflection APIs.
+ *
+ * \param[in] type_info
+ * \param[out] out A pointer to the OrtSequenceTypeInfo. Do not free this value
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CastTypeInfoToSequenceTypeInfo, _In_ const OrtTypeInfo* type_info,
+ _Outptr_result_maybenull_ const OrtSequenceTypeInfo** out);
+
+ /// @}
+ /// \name OrtMapTypeInfo
+ /// @{
+
+ /** \brief Get key type from an ::OrtMapTypeInfo
+ *
+ * Key types are restricted to being scalar types.
+ *
+ * This is used by WinML to support model reflection APIs.
+ *
+ * \param[in] map_type_info
+ * \param[out] out
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetMapKeyType, _In_ const OrtMapTypeInfo* map_type_info, _Out_ enum ONNXTensorElementDataType* out);
+
+ /** \brief Get the value type from an ::OrtMapTypeInfo
+ *
+ * \param[in] map_type_info
+ * \param[out] type_info
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetMapValueType, _In_ const OrtMapTypeInfo* map_type_info, _Outptr_ OrtTypeInfo** type_info);
+
+ /// @}
+ /// \name OrtSequenceTypeInfo
+ /// @{
+
+ /** \brief Get element type from an ::OrtSequenceTypeInfo
+ *
+ * This is used by WinML to support model reflection APIs.
+ *
+ * \param[in] sequence_type_info
+ * \param[out] type_info
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetSequenceElementType, _In_ const OrtSequenceTypeInfo* sequence_type_info,
+ _Outptr_ OrtTypeInfo** type_info);
+
+ /// @}
+ /// \name OrtMapTypeInfo
+ /// @{
+ ORT_CLASS_RELEASE(MapTypeInfo);
+ /// @}
+ /// \name OrtSequenceTypeInfo
+ /// @{
+ ORT_CLASS_RELEASE(SequenceTypeInfo);
+
+ /// @}
+ /// \name OrtSession
+ /// @{
+
+ /** \brief End profiling and return filename of the profile data
+ *
+ * Profiling is turned on through OrtApi::EnableProfiling
+ *
+ * \param[in] session
+ * \param[in] allocator
+ * \param[out] out Null terminated string of the filename, allocated using `allocator`. Must be freed using `allocator`
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionEndProfiling, _In_ OrtSession* session, _Inout_ OrtAllocator* allocator, _Outptr_ char** out);
+
+ /** \brief Get ::OrtModelMetadata from an ::OrtSession
+ *
+ * \param[in] session
+ * \param[out] out Newly created ::OrtModelMetadata. Must be freed using OrtApi::ReleaseModelMetadata
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetModelMetadata, _In_ const OrtSession* session, _Outptr_ OrtModelMetadata** out);
+
+ /// @}
+ /// \name OrtModelMetadata
+ /// @{
+
+ /** \brief Get `producer name` from an ::OrtModelMetadata
+ *
+ * \param[in] model_metadata
+ * \param[in] allocator
+ * \param[out] value Set to a null terminated string allocated using `allocator`. Must be freed using `allocator`
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(ModelMetadataGetProducerName, _In_ const OrtModelMetadata* model_metadata,
+ _Inout_ OrtAllocator* allocator, _Outptr_ char** value);
+
+ /** \brief Get `graph name` from an ::OrtModelMetadata
+ *
+ * \param[in] model_metadata
+ * \param[in] allocator
+ * \param[out] value Set to a null terminated string allocated using `allocator`. Must be freed using `allocator`
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(ModelMetadataGetGraphName, _In_ const OrtModelMetadata* model_metadata,
+ _Inout_ OrtAllocator* allocator, _Outptr_ char** value);
+
+ /** \brief Get `domain` from an ::OrtModelMetadata
+ *
+ * \param[in] model_metadata
+ * \param[in] allocator
+ * \param[out] value Set to a null terminated string allocated using `allocator`. Must be freed using `allocator`
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(ModelMetadataGetDomain, _In_ const OrtModelMetadata* model_metadata, _Inout_ OrtAllocator* allocator,
+ _Outptr_ char** value);
+
+ /** \brief Get `description` from an ::OrtModelMetadata
+ *
+ * \param[in] model_metadata
+ * \param[in] allocator
+ * \param[out] value Set to a null terminated string allocated using `allocator`. Must be freed using `allocator`
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(ModelMetadataGetDescription, _In_ const OrtModelMetadata* model_metadata,
+ _Inout_ OrtAllocator* allocator, _Outptr_ char** value);
+
+ /** \brief Return data for a key in the custom metadata map in an ::OrtModelMetadata
+ *
+ * \param[in] model_metadata
+ * \param[in] allocator
+ * \param[in] key Null terminated string
+ * \param[out] value Set to a null terminated string allocated using `allocator`. Must be freed using `allocator`
+ * `value` will be set to nullptr if the given key is not found in the custom metadata map.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(ModelMetadataLookupCustomMetadataMap, _In_ const OrtModelMetadata* model_metadata,
+ _Inout_ OrtAllocator* allocator, _In_ const char* key, _Outptr_result_maybenull_ char** value);
+
+ /** \brief Get version number from an ::OrtModelMetadata
+ *
+ * \param[in] model_metadata
+ * \param[out] value Set to the version number
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(ModelMetadataGetVersion, _In_ const OrtModelMetadata* model_metadata, _Out_ int64_t* value);
+
+ ORT_CLASS_RELEASE(ModelMetadata);
+
+ /// @}
+ /// \name OrtEnv
+ /// @{
+
+ /** \brief Create an OrtEnv
+ *
+ * Create an environment with global threadpools that will be shared across sessions.
+ * Use this in conjunction with OrtApi::DisablePerSessionThreads or else the session will use
+ * its own thread pools.
+ *
+ * \param[in] log_severity_level The log severity level.
+ * \param[in] logid The log identifier.
+ * \param[in] tp_options
+ * \param[out] out Returned newly created OrtEnv. Must be freed with OrtApi::ReleaseEnv
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateEnvWithGlobalThreadPools, OrtLoggingLevel log_severity_level, _In_ const char* logid,
+ _In_ const OrtThreadingOptions* tp_options, _Outptr_ OrtEnv** out);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Use global thread pool on a session
+ *
+ * Disable using per session thread pool and use the shared global threadpool.
+ * This should be used in conjunction with OrtApi::CreateEnvWithGlobalThreadPools.
+ *
+ * \param[in] options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(DisablePerSessionThreads, _Inout_ OrtSessionOptions* options);
+
+ /// @}
+ /// \name OrtThreadingOptions
+ /// @{
+
+ /** \brief Create an ::OrtThreadingOptions
+ *
+ * \param[out] out Newly created ::OrtThreadingOptions. Must be freed with OrtApi::ReleaseThreadingOptions
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateThreadingOptions, _Outptr_ OrtThreadingOptions** out);
+
+ ORT_CLASS_RELEASE(ThreadingOptions);
+
+ /// @}
+ /// \name OrtModelMetadata
+ /// @{
+
+ /**
+ *
+ * \param[in] model_metadata
+ * \param[in] allocator
+ * \param[out] keys Array of null terminated strings (array count = num_keys) allocated using `allocator`.
+ * The strings and the pointer array must be freed using `allocator`
+ * `keys` will be set to nullptr if the custom metadata map is empty.
+ * \param[out] num_keys Set to the number of elements in the `keys` array
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(ModelMetadataGetCustomMetadataMapKeys, _In_ const OrtModelMetadata* model_metadata,
+ _Inout_ OrtAllocator* allocator, _Outptr_result_buffer_maybenull_(*num_keys) char*** keys, _Out_ int64_t* num_keys);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /**
+ *
+ * Override symbolic dimensions (by specific name strings) with actual values
+ * if known at session initialization time to enable optimizations that can
+ * take advantage of fixed values (such as memory planning, etc)
+ *
+ */
+ ORT_API2_STATUS(AddFreeDimensionOverrideByName,
+ _Inout_ OrtSessionOptions* options, _In_ const char* dim_name,
+ _In_ int64_t dim_value);
+
+ /// @}
+ /// \name Misc
+ /// @{
+
+ /** \brief Get the names of all available providers
+ *
+ * \note The providers in the list are not guaranteed to be usable. They may fail to load due to missing system dependencies.
+ * For example, if the CUDA/cuDNN libraries are not installed, the CUDA provider will report an error when it is added to the session options.
+ *
+ * \param[out] out_ptr Set to a pointer to an array of null terminated strings of the available providers. The entries and the
+ * array itself must be freed using OrtApi::ReleaseAvailableProviders
+ * \param[out] provider_length Set to the number of entries in the `out_ptr` array
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetAvailableProviders, _Outptr_ char*** out_ptr, _Out_ int* provider_length);
+
+ /** \brief Release data from OrtApi::GetAvailableProviders
+ *
+ * \param[in] ptr The `out_ptr` result from OrtApi::GetAvailableProviders.
+ * \param[in] providers_length The `provider_length` result from OrtApi::GetAvailableProviders
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(ReleaseAvailableProviders, _In_ char** ptr,
+ _In_ int providers_length);
+
+ /// @}
+ /// \name OrtValue
+ /// @{
+
+ /** \brief Get the length of a single string in a string tensor
+ *
+ * \param[in] value A string tensor
+ * \param[in] index Index of the string in the tensor
+ * \param[out] out Set to number of bytes of the string element
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetStringTensorElementLength, _In_ const OrtValue* value, size_t index, _Out_ size_t* out);
+
+ /** \brief Get a single string from a string tensor
+ *
+ * \param[in] value A string tensor
+ * \param[in] s_len Number of bytes in the `s` buffer. Must match the value returned by OrtApi::GetStringTensorElementLength.
+ * \param[in] index Index of the string in the tensor
+ * \param[out] s The string element contents in UTF-8 encoding. The string is NOT null-terminated.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetStringTensorElement, _In_ const OrtValue* value, size_t s_len, size_t index, _Out_writes_bytes_all_(s_len) void* s);
+
+ /** \brief Set a single string in a string tensor
+ *
+ * \param[in] value A string tensor
+ * \param[in] s A null terminated UTF-8 encoded string
+ * \param[in] index Index of the string in the tensor to set
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(FillStringTensorElement, _Inout_ OrtValue* value, _In_ const char* s, size_t index);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Set a session configuration entry as a pair of strings
+ *
+ * If a configuration with same key exists, this will overwrite the configuration with the given config_value.
+ *
+ * The config_key and the format of config_value are defined in onnxruntime_session_options_config_keys.h
+ *
+ * \param[in] options
+ * \param[in] config_key A null terminated string representation of the config key
+ * \param[in] config_value A null terminated string representation of the config value
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(AddSessionConfigEntry, _Inout_ OrtSessionOptions* options,
+ _In_z_ const char* config_key, _In_z_ const char* config_value);
+
+ /// @}
+ /// \name OrtAllocator
+ /// @{
+
+ /** \brief Create an allocator for an ::OrtSession following an ::OrtMemoryInfo
+ *
+ * \param[in] session
+ * \param[in] mem_info valid ::OrtMemoryInfo instance
+ * \param[out] out Newly created ::OrtAllocator. Must be freed with OrtApi::ReleaseAllocator
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateAllocator, _In_ const OrtSession* session, _In_ const OrtMemoryInfo* mem_info,
+ _Outptr_ OrtAllocator** out);
+
+ /** \brief Release an ::OrtAllocator obtained from OrtApi::CreateAllocator
+ */
+ ORT_CLASS_RELEASE(Allocator);
+
+ /// @}
+ /// \name OrtSession
+ /// @{
+
+ /** \brief Run a model using Io Bindings for the inputs & outputs
+ *
+ * \see OrtApi::Run
+ *
+ * \param[in] session
+ * \param[in] run_options
+ * \param[in] binding_ptr
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(RunWithBinding, _Inout_ OrtSession* session, _In_ const OrtRunOptions* run_options, _In_ const OrtIoBinding* binding_ptr);
+
+ /** \brief Create an ::OrtIoBinding instance
+ *
+ * An IoBinding object allows one to bind pre-allocated ::OrtValue%s to input names.
+ * Thus if you want to use a raw on device buffer as input or output you can avoid
+ * extra copy during runtime.
+ *
+ * \param[in] session
+ * \param[out] out Newly created ::OrtIoBinding. Must be freed with OrtApi::ReleaseIoBinding
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateIoBinding, _Inout_ OrtSession* session, _Outptr_ OrtIoBinding** out);
+
+ /// @}
+ /// \name OrtIoBinding
+ /// @{
+
+ /** \brief Release an ::OrtIoBinding obtained from OrtApi::CreateIoBinding
+ */
+ ORT_CLASS_RELEASE(IoBinding);
+
+ /** \brief Bind an ::OrtValue to an ::OrtIoBinding input
+ *
+ * When using OrtApi::RunWithBinding this value is used for the named input
+ *
+ * \param[in] binding_ptr
+ * \param[in] name Name for the model input
+ * \param[in] val_ptr ::OrtValue of Tensor type.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(BindInput, _Inout_ OrtIoBinding* binding_ptr, _In_ const char* name, _In_ const OrtValue* val_ptr);
+
+ /** \brief Bind an ::OrtValue to an ::OrtIoBinding output
+ *
+ * When using OrtApi::RunWithBinding this value is used for the named output
+ *
+ * \param[in] binding_ptr
+ * \param[in] name Null terminated string of the model output name
+ * \param[in] val_ptr ::OrtValue of Tensor type.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(BindOutput, _Inout_ OrtIoBinding* binding_ptr, _In_ const char* name, _In_ const OrtValue* val_ptr);
+
+ /** \brief Bind an ::OrtIoBinding output to a device
+ *
+ * Binds the ::OrtValue to a device which is specified by ::OrtMemoryInfo.
+ * You can either create an instance of ::OrtMemoryInfo with a device id or obtain one from the allocator that you have created/are using
+ * This is useful when one or more outputs have dynamic shapes and, it is hard to pre-allocate and bind a chunk of
+ * memory within ::OrtValue ahead of time.
+ *
+ * \see OrtApi::RunWithBinding
+ *
+ * \param[in] binding_ptr
+ * \param[in] name Null terminated string of the device name
+ * \param[in] mem_info_ptr
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(BindOutputToDevice, _Inout_ OrtIoBinding* binding_ptr, _In_ const char* name, _In_ const OrtMemoryInfo* mem_info_ptr);
+
+ /** \brief Get the names of an ::OrtIoBinding's outputs
+ *
+ * Returns the names of the outputs in the order they were bound. This is useful after running the model
+ * with bound outputs because the returned names are in order in which output ::OrtValue are returned. This is useful if
+ * the order of outputs and their names is not known.
+ *
+ * \param[in] binding_ptr
+ * \param[in] allocator Allocator used to allocate continuous buffers for output strings and lengths.
+ * \param[out] buffer Returns an array of non-null terminated UTF-8 strings. The number of strings stored is returned in the count parameter.
+ * This buffer is allocated using `allocator` and must be freed using it.
+ * \param[out] lengths Returns an array of `count` lengths of the strings returned in `buffer`
+ * This buffer is allocated using `allocator` and must be freed using it.
+ * \param[out] count Number of strings returned. If `binding_ptr` has no bound outputs, zero is returned,
+ * no memory allocation is performed and buffer and lengths are set to nullptr.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetBoundOutputNames, _In_ const OrtIoBinding* binding_ptr, _In_ OrtAllocator* allocator,
+ _Out_ char** buffer, _Out_writes_all_(count) size_t** lengths, _Out_ size_t* count);
+
+ /** \brief Get the output ::OrtValue objects from an ::OrtIoBinding
+ *
+ * Returns an array of pointers to individually allocated ::OrtValue%s that contain results of a model execution with OrtApi::RunWithBinding
+ * The array contains the same number of ::OrtValue%s and they are in the same order as they were bound with OrtApi::BindOutput
+ * or OrtApi::BindOutputToDevice.
+ *
+ * The returned ::OrtValue%s must be released using OrtApi::ReleaseValue after they are no longer needed.
+ * The array is allocated using the specified instance of the allocator and must be freed using the same allocator after
+ * all the ::OrtValue%s contained therein are individually released.
+ *
+ * \param[in] binding_ptr
+ * \param[in] allocator Allocator used to allocate output array
+ * \param[out] output Set to the allocated array of allocated ::OrtValue outputs. Set to nullptr if there are 0 outputs.
+ * \param[out] output_count Set to number of ::OrtValue%s returned
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetBoundOutputValues, _In_ const OrtIoBinding* binding_ptr, _In_ OrtAllocator* allocator,
+ _Out_writes_all_(output_count) OrtValue*** output, _Out_ size_t* output_count);
+
+ /** \brief Clears any previously set Inputs for an ::OrtIoBinding
+ */
+ void(ORT_API_CALL* ClearBoundInputs)(_Inout_ OrtIoBinding* binding_ptr) NO_EXCEPTION ORT_ALL_ARGS_NONNULL;
+
+ /** \brief Clears any previously set Outputs for an ::OrtIoBinding
+ */
+ void(ORT_API_CALL* ClearBoundOutputs)(_Inout_ OrtIoBinding* binding_ptr) NO_EXCEPTION ORT_ALL_ARGS_NONNULL;
+
+ /// @}
+ /// \name OrtValue
+ /// @{
+
+ /** \brief Direct memory access to a specified tensor element
+ *
+ * For example, given a tensor with shape of [3,224,224], a pointer to the element at location [2,150,128] can be retrieved
+ *
+ * This function only works for numeric type tensors (No strings, etc).
+ * This is a no-copy method whose returned pointer is valid until the passed in ::OrtValue is free'd.
+ *
+ * \param[in] value
+ * \param[in] location_values Pointer to an array of index values that specify an element's location relative to its shape
+ * \param[in] location_values_count Number of elements in location_values. Must match the number of elements in the tensor's shape.
+ * \param[out] out Set to a pointer to the element specified
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(TensorAt, _Inout_ OrtValue* value, const int64_t* location_values, size_t location_values_count, _Outptr_ void** out);
+
+ /// @}
+ /// \name OrtEnv
+ /// @{
+
+ /** \brief Create an allocator and register it with the ::OrtEnv
+ *
+ * Enables sharing the allocator between multiple sessions that use the same env instance.
+ * Lifetime of the created allocator will be valid for the duration of the environment.
+ * Returns an error if an allocator with the same ::OrtMemoryInfo is already registered.
+ *
+ * See https://onnxruntime.ai/docs/reference/api/c-api.html for details.
+ *
+ * \param[in] env ::OrtEnv instance
+ * \param[in] mem_info
+ * \param[in] arena_cfg Pass nullptr for defaults
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateAndRegisterAllocator, _Inout_ OrtEnv* env, _In_ const OrtMemoryInfo* mem_info,
+ _In_ const OrtArenaCfg* arena_cfg);
+
+ /** \brief Set language projection
+ *
+ * Set the language projection for collecting telemetry data when Env is created.
+ *
+ * The default is ORT_PROJECTION_C, which means it will classify the language not in the list to C also.
+ *
+ * \param[in] ort_env
+ * \param[in] projection
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetLanguageProjection, _In_ const OrtEnv* ort_env, _In_ OrtLanguageProjection projection);
+
+ /// @}
+ /// \name OrtSession
+ /// @{
+
+ /** \brief Return the time that profiling was started
+ *
+ * \note The timer precision varies per platform. On Windows and MacOS, the precision will be ~100ns
+ *
+ * \param[in] session
+ * \param[out] out nanoseconds of profiling's start time
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionGetProfilingStartTimeNs, _In_ const OrtSession* session, _Outptr_ uint64_t* out);
+
+ /// @}
+ /// \name OrtThreadingOptions
+ /// @{
+
+ /** \brief Set global intra-op thread count
+ *
+ * This configures the global thread pool options to be used in the call to OrtApi::CreateEnvWithGlobalThreadPools
+ *
+ * \param[in] tp_options
+ * \param[in] intra_op_num_threads Number of threads, special values:<br>
+ * 0 = Use default thread count<br>
+ * 1 = The invoking thread will be used; no threads will be created in the thread pool.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetGlobalIntraOpNumThreads, _Inout_ OrtThreadingOptions* tp_options, int intra_op_num_threads);
+
+ /** \brief Set global inter-op thread count
+ *
+ * This configures the global thread pool options to be used in the call to OrtApi::CreateEnvWithGlobalThreadPools
+ *
+ * \param[in] tp_options
+ * \param[in] inter_op_num_threads Number of threads, special values:<br>
+ * 0 = Use default thread count<br>
+ * 1 = The invoking thread will be used; no threads will be created in the thread pool.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetGlobalInterOpNumThreads, _Inout_ OrtThreadingOptions* tp_options, int inter_op_num_threads);
+
+ /** \brief Set global spin control options
+ *
+ * This will configure the global thread pool options to be used in the call to OrtApi::CreateEnvWithGlobalThreadPools.
+ * Allow spinning of thread pools when their queues are empty. This will set the value for both
+ * inter_op and intra_op threadpools.
+ *
+ * \param[in] tp_options
+ * \param[in] allow_spinning Valid values are 0 or 1.<br>
+ * 0 = It won't spin (recommended if CPU usage is high)<br>
+ * 1 = Threadpool will spin to wait for queue to become non-empty
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetGlobalSpinControl, _Inout_ OrtThreadingOptions* tp_options, int allow_spinning);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Add a pre-allocated initializer to a session
+ *
+ * If a model contains an initializer with a name that is same as the name passed to this call,
+ * ORT will use this initializer instance instead of deserializing one from the model file. This
+ * is useful when you want to share the same initializer across sessions.
+ *
+ * \param[in] options
+ * \param[in] name Null terminated string of the initializer name
+ * \param[in] val ::OrtValue containing the initializer. Its lifetime and the underlying initializer buffer must be
+ * managed by the user (created using the OrtApi::CreateTensorWithDataAsOrtValue) and it must outlive the session object
+ * to which it is added.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(AddInitializer, _Inout_ OrtSessionOptions* options, _In_z_ const char* name,
+ _In_ const OrtValue* val);
+
+ /// @}
+ /// \name OrtEnv
+ /// @{
+
+ /**
+ * Create a custom environment with global threadpools and logger that will be shared across sessions.
+ * Use this in conjunction with OrtApi::DisablePerSessionThreads or else the session will use
+ * its own thread pools.
+ *
+ * \param[in] logging_function A pointer to a logging function.
+ * \param[in] logger_param A pointer to arbitrary data passed as the ::OrtLoggingFunction `param` parameter to
+ * `logging_function`.
+ * \param[in] log_severity_level The log severity level.
+ * \param[in] logid The log identifier.
+ * \param[in] tp_options
+ * \param[out] out Newly created OrtEnv. Must be freed with OrtApi::ReleaseEnv
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateEnvWithCustomLoggerAndGlobalThreadPools, OrtLoggingFunction logging_function, _In_opt_ void* logger_param, OrtLoggingLevel log_severity_level,
+ _In_ const char* logid, _In_ const struct OrtThreadingOptions* tp_options, _Outptr_ OrtEnv** out);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Append CUDA provider to session options
+ *
+ * If CUDA is not available (due to a non CUDA enabled build, or if CUDA is not installed on the system), this function will return failure.
+ *
+ * \param[in] options
+ * \param[in] cuda_options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_CUDA,
+ _In_ OrtSessionOptions* options, _In_ const OrtCUDAProviderOptions* cuda_options);
+
+ /** \brief Append ROCM execution provider to the session options
+ *
+ * If ROCM is not available (due to a non ROCM enabled build, or if ROCM is not installed on the system), this function will return failure.
+ *
+ * \param[in] options
+ * \param[in] rocm_options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_ROCM,
+ _In_ OrtSessionOptions* options, _In_ const OrtROCMProviderOptions* rocm_options);
+
+ /** \brief Append OpenVINO execution provider to the session options
+ *
+ * If OpenVINO is not available (due to a non OpenVINO enabled build, or if OpenVINO is not installed on the system), this function will fail.
+ *
+ * \param[in] options
+ * \param[in] provider_options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_OpenVINO,
+ _In_ OrtSessionOptions* options, _In_ const OrtOpenVINOProviderOptions* provider_options);
+
+ /// @}
+ /// \name OrtThreadingOptions
+ /// @{
+
+ /** \brief Set threading flush-to-zero and denormal-as-zero
+ *
+ * Sets global thread pool options to be used in the call to OrtApi::CreateEnvWithGlobalThreadPools.
+ * Flush-to-zero and denormal-as-zero are applied to threads in both intra and inter global thread pool.
+ * \note This option is not needed if the models used have no denormals. Having no denormals is recommended as this option may hurt model accuracy.
+ *
+ * \param[in] tp_options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetGlobalDenormalAsZero, _Inout_ OrtThreadingOptions* tp_options);
+
+ /// @}
+ /// \name OrtArenaCfg
+ /// @{
+
+ /** \deprecated Use OrtApi::CreateArenaCfgV2
+ *
+ * This will create the configuration of an arena that can eventually be used to define an arena based allocator's behavior
+ *
+ * \param[in] max_mem Use 0 to allow ORT to choose the default
+ * \param[in] arena_extend_strategy Use -1 to allow ORT to choose the default, 0 = kNextPowerOfTwo, 1 = kSameAsRequested
+ * \param[in] initial_chunk_size_bytes Use -1 to allow ORT to choose the default
+ * \param[in] max_dead_bytes_per_chunk Use -1 to allow ORT to choose the default
+ * \param[in] out A pointer to an OrtArenaCfg instance
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateArenaCfg, _In_ size_t max_mem, int arena_extend_strategy, int initial_chunk_size_bytes,
+ int max_dead_bytes_per_chunk, _Outptr_ OrtArenaCfg** out);
+
+ ORT_CLASS_RELEASE(ArenaCfg);
+
+ /// @}
+ /// \name OrtModelMetadata
+ /// @{
+
+ /**
+ * Use this to obtain the description of the graph present in the model
+ * (doc_string field of the GraphProto message within the ModelProto message).
+ * If it doesn't exist, an empty string will be returned.
+ *
+ * \param[in] model_metadata An instance of ::OrtModelMetadata
+ * \param[in] allocator Allocator used to allocate the string that will be returned back
+ * \param[out] value Set to a null terminated string allocated using `allocator`. The caller is responsible for freeing it using `allocator`
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(ModelMetadataGetGraphDescription, _In_ const OrtModelMetadata* model_metadata,
+ _Inout_ OrtAllocator* allocator, _Outptr_ char** value);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Append TensorRT provider to session options
+ *
+ * If TensorRT is not available (due to a non TensorRT enabled build, or if TensorRT is not installed on the system), this function will return failure.
+ *
+ * \param[in] options
+ * \param[in] tensorrt_options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_TensorRT,
+ _In_ OrtSessionOptions* options, _In_ const OrtTensorRTProviderOptions* tensorrt_options);
+
+ /// @}
+ /// \name Misc
+ /// @{
+
+ /** \brief Set current GPU device ID
+ *
+ * Set the current device id of the GPU execution provider (CUDA/tensorrt/rocm). The device id should be less
+ * than the total number of devices available. This is only useful when multiple-GPUs are installed and it is
+ * required to restrict execution to a single GPU.
+ *
+ * \param[in] device_id
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetCurrentGpuDeviceId, _In_ int device_id);
+
+ /** \brief Get current GPU device ID
+ *
+ * Get the current device id of the GPU execution provider (CUDA/tensorrt/rocm).
+ *
+ * \see OrtApi::SetCurrentGpuDeviceId
+ *
+ * \param[out] device_id
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetCurrentGpuDeviceId, _In_ int* device_id);
+
+ /// @}
+ /// \name OrtKernelInfo
+ /// Custom operator APIs.
+ /// @{
+
+ /** \brief Fetch an array of int64_t values stored as an attribute in the graph node
+ *
+ *
+ * If `out` is nullptr, the value of `size` is set to the true size of the attribute
+ * array's size, and a success status is returned.
+ *
+ * If the `size` parameter is greater than or equal to the actual attribute array's size,
+ * the value of `size` is set to the true size of the attribute array's size,
+ * the provided memory is filled with the attribute's contents,
+ * and a success status is returned.
+ *
+ * If the `size` parameter is less than the actual attribute array's size and `out`
+ * is not nullptr, the value of `size` is set to the true size of the attribute array's size
+ * and a failure status is returned.)
+ *
+ * \param[in] info instance
+ * \param[in] name name of the attribute to be parsed
+ * \param[out] out pointer to memory where the attribute's contents are to be stored
+ * \param[in, out] size actual size of attribute array
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(KernelInfoGetAttributeArray_float, _In_ const OrtKernelInfo* info, _In_ const char* name,
+ _Out_ float* out, _Inout_ size_t* size);
+
+ /** \brief Fetch an array of int64_t values stored as an attribute in the graph node
+ *
+ * If `out` is nullptr, the value of `size` is set to the true size of the attribute
+ * array's size, and a success status is returned.
+ *
+ * If the `size` parameter is greater than or equal to the actual attribute array's size,
+ * the value of `size` is set to the true size of the attribute array's size,
+ * the provided memory is filled with the attribute's contents,
+ * and a success status is returned.
+ *
+ * If the `size` parameter is less than the actual attribute array's size and `out`
+ * is not nullptr, the value of `size` is set to the true size of the attribute array's size
+ * and a failure status is returned.)
+ *
+ * \param[in] info instance
+ * \param[in] name name of the attribute to be parsed
+ * \param[out] out pointer to memory where the attribute's contents are to be stored
+ * \param[in, out] size actual size of attribute array
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(KernelInfoGetAttributeArray_int64, _In_ const OrtKernelInfo* info, _In_ const char* name,
+ _Out_ int64_t* out, _Inout_ size_t* size);
+
+ /// @}
+ /// \name OrtArenaCfg
+ /// @{
+
+ /** \brief Create an ::OrtArenaCfg
+ *
+ * Create the configuration of an arena that can eventually be used to define an arena based allocator's behavior.
+ *
+ * Supported keys are (See https://onnxruntime.ai/docs/reference/api/c-api.html for details on what the
+ * following parameters mean and how to choose these values.):
+ * "max_mem": Maximum memory that can be allocated by the arena based allocator.
+ * Use 0 for ORT to pick the best value. Default is 0.
+ * "arena_extend_strategy": 0 = kNextPowerOfTwo, 1 = kSameAsRequested.
+ * Use -1 to allow ORT to choose the default.
+ * "initial_chunk_size_bytes": (Possible) Size of the first allocation in the arena.
+ * Only relevant if arena strategy is `kNextPowerOfTwo`. Use -1 to allow ORT to choose the default.
+ * Ultimately, the first allocation size is determined by the allocation memory request.
+ * "max_dead_bytes_per_chunk": Threshold of unused memory in an allocated chunk of arena memory after
+ * crossing which the current chunk is chunked into 2.
+ * "initial_growth_chunk_size_bytes": (Possible) Size of the second allocation in the arena.
+ * Only relevant if arena strategy is `kNextPowerOfTwo`. Use -1 to allow ORT to choose the default.
+ * Ultimately, the allocation size is determined by the allocation memory request.
+ * Further allocation sizes are governed by the arena extend strategy.
+ *
+ * \param[in] arena_config_keys Keys to configure the arena
+ * \param[in] arena_config_values Values to configure the arena
+ * \param[in] num_keys Number of keys in `arena_config_keys` and `arena_config_values`
+ * \param[out] out Newly created ::OrtArenaCfg. Must be freed with OrtApi::ReleaseArenaCfg
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateArenaCfgV2, _In_reads_(num_keys) const char* const* arena_config_keys,
+ _In_reads_(num_keys) const size_t* arena_config_values, _In_ size_t num_keys,
+ _Outptr_ OrtArenaCfg** out);
+
+ /// @}
+ /// \name OrtRunOptions
+ /// @{
+
+ /** \brief Set a single run configuration entry as a pair of strings
+ *
+ * If a configuration with same key exists, this will overwrite the configuration with the given config_value
+ *
+ * The config_key and the format of config_value are defined in onnxruntime_run_options_config_keys.h
+ *
+ * \param[in] options
+ * \param[in] config_key A null terminated string representation of the config key
+ * \param[in] config_value A null terminated string representation of the config value
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(AddRunConfigEntry, _Inout_ OrtRunOptions* options,
+ _In_z_ const char* config_key, _In_z_ const char* config_value);
+
+ /// @}
+ /// \name OrtPrepackedWeightsContainer
+ /// @{
+
+ /** \brief Create an ::OrtPrepackedWeightsContainer
+ *
+ * This container will hold pre-packed buffers of shared initializers for sharing between sessions
+ * (i.e.) if there are shared initializers that can be shared between sessions, the pre-packed buffers
+ * of these (if any) may possibly be shared to provide memory footprint savings. Pass this container
+ * to sessions that you would like to share pre-packed buffers of shared initializers at session
+ * creation time.
+ *
+ * \param[out] out Newly created ::OrtPrepackedWeightsContainer. Must be freed with OrtApi::ReleasePrepackedWeightsContainer
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreatePrepackedWeightsContainer, _Outptr_ OrtPrepackedWeightsContainer** out);
+
+ /** \brief Release OrtPrepackedWeightsContainer instance
+ *
+ * \note instance must not be released until the sessions using it are released
+ */
+ ORT_CLASS_RELEASE(PrepackedWeightsContainer);
+
+ /// @}
+ /// \name OrtSession
+ /// @{
+
+ /** \brief Create session with prepacked weights container
+ *
+ * Same functionality offered by OrtApi::CreateSession except that a container that contains
+ * pre-packed weights' buffers is written into/read from by the created session.
+ * This is useful when used in conjunction with OrtApi::AddInitializer which injects
+ * shared initializer info into sessions. Wherever possible, the pre-packed versions of these
+ * shared initializers are cached in this container so that multiple sessions can just re-use
+ * these instead of duplicating these in memory.
+ *
+ * \param[in] env OrtEnv instance instance
+ * \param[in] model_path Null terminated string of the path (wchar on Windows, char otherwise)
+ * \param[in] options
+ * \param[in] prepacked_weights_container
+ * \param[out] out Newly created ::OrtSession. Must be freed with OrtApi::ReleaseSession
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateSessionWithPrepackedWeightsContainer, _In_ const OrtEnv* env, _In_ const ORTCHAR_T* model_path,
+ _In_ const OrtSessionOptions* options, _Inout_ OrtPrepackedWeightsContainer* prepacked_weights_container,
+ _Outptr_ OrtSession** out);
+
+ /** \brief Create session from memory with prepacked weights container
+ *
+ * Same functionality offered by OrtApi::CreateSessionFromArray except that a container that contains
+ * pre-packed weights' buffers is written into/read from by the created session.
+ * This is useful when used in conjunction with OrtApi::AddInitializer which injects
+ * shared initializer info into sessions. Wherever possible, the pre-packed versions of these
+ * shared initializers are cached in this container so that multiple sessions can just re-use
+ * these instead of duplicating these in memory.
+ *
+ * \param[in] env
+ * \param[in] model_data Array of bytes holding the model
+ * \param[in] model_data_length Number of bytes in `model_data_model`
+ * \param[in] options
+ * \param[in] prepacked_weights_container
+ * \param[out] out Newly created ::OrtSession. Must be freed with OrtApi::ReleaseSession
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateSessionFromArrayWithPrepackedWeightsContainer, _In_ const OrtEnv* env,
+ _In_ const void* model_data, size_t model_data_length,
+ _In_ const OrtSessionOptions* options, _Inout_ OrtPrepackedWeightsContainer* prepacked_weights_container,
+ _Outptr_ OrtSession** out);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Append TensorRT execution provider to the session options
+ *
+ * If TensorRT is not available (due to a non TensorRT enabled build), this function will return failure.
+ *
+ * This is slightly different from OrtApi::SessionOptionsAppendExecutionProvider_TensorRT, it takes an
+ * ::OrtTensorRTProviderOptions which is publicly defined. This takes an opaque ::OrtTensorRTProviderOptionsV2
+ * which must be created with OrtApi::CreateTensorRTProviderOptions.
+ *
+ * For OrtApi::SessionOptionsAppendExecutionProvider_TensorRT, the user needs to instantiate ::OrtTensorRTProviderOptions
+ * as well as allocate/release buffers for some members of ::OrtTensorRTProviderOptions.
+ * Here, OrtApi::CreateTensorRTProviderOptions and Ortapi::ReleaseTensorRTProviderOptions will do the memory management for you.
+ *
+ * \param[in] options
+ * \param[in] tensorrt_options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_TensorRT_V2,
+ _In_ OrtSessionOptions* options, _In_ const OrtTensorRTProviderOptionsV2* tensorrt_options);
+
+ /// @}
+ /// \name OrtTensorRTProviderOptionsV2
+ /// @{
+
+ /** \brief Create an OrtTensorRTProviderOptionsV2
+ *
+ * \param[out] out Newly created ::OrtTensorRTProviderOptionsV2. Must be released with OrtApi::ReleaseTensorRTProviderOptions
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateTensorRTProviderOptions, _Outptr_ OrtTensorRTProviderOptionsV2** out);
+
+ /** \brief Set options in a TensorRT Execution Provider.
+ *
+ * Please refer to https://www.onnxruntime.ai/docs/reference/execution-providers/TensorRT-ExecutionProvider.html#c-api-example
+ * to know the available keys and values. Key should be in null terminated string format of the member of ::OrtTensorRTProviderOptionsV2
+ * and value should be its related range.
+ *
+ * For example, key="trt_max_workspace_size" and value="2147483648"
+ *
+ * \param[in] tensorrt_options
+ * \param[in] provider_options_keys Array of UTF-8 null-terminated string for provider options keys
+ * \param[in] provider_options_values Array of UTF-8 null-terminated string for provider options values
+ * \param[in] num_keys Number of elements in the `provider_option_keys` and `provider_options_values` arrays
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(UpdateTensorRTProviderOptions, _Inout_ OrtTensorRTProviderOptionsV2* tensorrt_options,
+ _In_reads_(num_keys) const char* const* provider_options_keys,
+ _In_reads_(num_keys) const char* const* provider_options_values,
+ _In_ size_t num_keys);
+
+ /** \brief Get serialized TensorRT provider options string.
+ *
+ * For example, "trt_max_workspace_size=2147483648;trt_max_partition_iterations=10;trt_int8_enable=1;......"
+ *
+ * \param tensorrt_options - OrTensorRTProviderOptionsV2 instance
+ * \param allocator - a ptr to an instance of OrtAllocator obtained with OrtApi::CreateAllocator or OrtApi::GetAllocatorWithDefaultOptions
+ * the specified allocator will be used to allocate continuous buffers for output strings and lengths.
+ * \param ptr - is a UTF-8 null terminated string allocated using 'allocator'. The caller is responsible for using the same allocator to free it.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetTensorRTProviderOptionsAsString, _In_ const OrtTensorRTProviderOptionsV2* tensorrt_options, _Inout_ OrtAllocator* allocator, _Outptr_ char** ptr);
+
+ /** \brief Release an ::OrtTensorRTProviderOptionsV2
+ *
+ * \note This is an exception in the naming convention of other Release* functions, as the name of the method does not have the V2 suffix, but the type does
+ */
+ void(ORT_API_CALL* ReleaseTensorRTProviderOptions)(_Frees_ptr_opt_ OrtTensorRTProviderOptionsV2* input);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Enable custom operators
+ *
+ * See onnxruntime-extensions: https://github.com/microsoft/onnxruntime-extensions.git
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(EnableOrtCustomOps, _Inout_ OrtSessionOptions* options);
+
+ /// @}
+ /// \name OrtAllocator
+ /// @{
+
+ /** \brief Register a custom allocator
+ *
+ * Enables sharing between multiple sessions that use the same env instance.
+ * Returns an error if an allocator with the same ::OrtMemoryInfo is already registered.
+ *
+ * The behavior of this is exactly the same as OrtApi::CreateAndRegisterAllocator except
+ * instead of ORT creating an allocator based on provided info, in this case
+ * ORT uses the user-provided custom allocator.
+ * See https://onnxruntime.ai/docs/reference/api/c-api.html for details.
+ *
+ * \param[in] env
+ * \param[in] allocator User provided allocator
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(RegisterAllocator, _Inout_ OrtEnv* env, _In_ OrtAllocator* allocator);
+
+ /** \brief Unregister a custom allocator
+ *
+ * It is an error if you provide an ::OrtMemoryInfo not corresponding to any
+ * registered allocators for sharing.
+ *
+ * \param[in] env
+ * \param[in] mem_info
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(UnregisterAllocator, _Inout_ OrtEnv* env,
+ _In_ const OrtMemoryInfo* mem_info);
+
+ /// @}
+ /// \name OrtValue
+ /// @{
+
+ /** \brief Sets *out to 1 iff an ::OrtValue is a SparseTensor, and 0 otherwise
+ *
+ * \param[in] value existing ::OrtValue
+ * \param[out] out unless an error occurs, contains 1 iff the value contains an instance
+ * of sparse tensor or 0 otherwise.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(IsSparseTensor, _In_ const OrtValue* value, _Out_ int* out);
+
+ /** \brief Create an ::OrtValue with a sparse tensor that is empty.
+ *
+ * Use FillSparseTensor<Format>() functions to populate sparse tensor with non-zero values and
+ * format specific indices data.
+ * Use ReleaseValue to destroy the sparse tensor, this will also release the buffer inside the output value
+ * if any was allocated.
+ * \param[in,out] allocator allocator to use when performing an allocation. Allocation will be performed
+ * by FillSparseTensor<Format>() APIs. The lifespan of the allocator instance must eclipse the lifespan
+ * this sparse tensor instance as the same allocator will be used to free memory.
+ * \param[in] dense_shape shape of the original dense tensor
+ * \param[in] dense_shape_len number of shape dimensions being passed
+ * \param[in] type must be one of TENSOR_ELEMENT_DATA_TYPE_xxxx
+ * \param[out] out Should be freed by calling ReleaseValue
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateSparseTensorAsOrtValue, _Inout_ OrtAllocator* allocator, _In_ const int64_t* dense_shape,
+ size_t dense_shape_len, ONNXTensorElementDataType type, _Outptr_ OrtValue** out);
+
+ /**
+ * This fills populates an empty tensor that was created using OrtApi::CreateSparseTensorAsOrtValue.
+ * This will allocate required memory and copy the supplied NNZ values and COO indices into that memory allocation.
+ * Memory allocation is performed using the allocator that was specified with OrtApi::CreateSparseTensorAsOrtValue.
+ *
+ * \param[in,out] ort_value ::OrtValue to populate with data
+ * \param[in] data_mem_info serves to identify the location of the data to be copied. If the allocator specified
+ * at the creation time has memory info that is not the same as mem_info argument to this function a X-device copy will be performed.
+ * String data is assumed to be on CPU and will only be copied into a CPU allocated buffer.
+ * \param[in] values_shape pointer to values shape array
+ * \param[in] values_shape_len length of the values_shape
+ * \param[in] values pointer to an array of values. For strings, pass const char**.
+ * \param[in] indices_data pointer to a location of COO indices
+ * \param[in] indices_num number of COO indices
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(FillSparseTensorCoo, _Inout_ OrtValue* ort_value, _In_ const OrtMemoryInfo* data_mem_info,
+ _In_ const int64_t* values_shape, size_t values_shape_len, _In_ const void* values,
+ _In_ const int64_t* indices_data, size_t indices_num);
+
+ /**
+ * This fills populates an empty tensor that was created using OrtApi::CreateSparseTensorAsOrtValue.
+ * This will allocate required memory and copy the supplied NNZ values and CSR indices into that memory allocation.
+ * Memory allocation is performed using the allocator that was specified with OrtApi::CreateSparseTensorAsOrtValue.
+ *
+ * \param[in,out] ort_value ::OrtValue to populate with data
+ * \param[in] data_mem_info serves to identify the location of the data to be copied. If the allocator specified
+ * at the creation time has memory info that is not the same as mem_info argument to this function a X-device copy will be performed.
+ * String data is assumed to be on CPU and will only be copied into a CPU allocated buffer.
+ * \param[in] values_shape pointer to values shape array
+ * \param[in] values_shape_len length of the values_shape
+ * \param[in] values - pointer to an array of values. For strings, pass const char**.
+ * \param[in] inner_indices_data pointer to a location of CSR inner indices
+ * \param[in] inner_indices_num number of CSR inner indices
+ * \param[in] outer_indices_data pointer to a location of CSR outer indices
+ * \param[in] outer_indices_num number of CSR outer indices
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(FillSparseTensorCsr, _Inout_ OrtValue* ort_value, _In_ const OrtMemoryInfo* data_mem_info,
+ _In_ const int64_t* values_shape, size_t values_shape_len, _In_ const void* values,
+ _In_ const int64_t* inner_indices_data, size_t inner_indices_num,
+ _In_ const int64_t* outer_indices_data, size_t outer_indices_num);
+
+ /**
+ * This fills populates an empty tensor that was created using OrtApi::CreateSparseTensorAsOrtValue.
+ * This will allocate required memory and copy the supplied NNZ values and BlockSparse indices into that memory allocation.
+ * Memory allocation is performed using the allocator that was specified with OrtApi::CreateSparseTensorAsOrtValue.
+ *
+ * \param[in,out] ort_value ::OrtValue to populate with data
+ * \param[in] data_mem_info serves to identify the location of the data to be copied. If the allocator specified
+ * at the creation time has memory info that is not the same as mem_info argument to this function a X-device copy will be performed.
+ * String data is assumed to be on CPU and will only be copied into a CPU allocated buffer.
+ * \param[in] values_shape
+ * \param[in] values_shape_len
+ * \param[in] values structure with values information
+ * \param[in] indices_shape_data pointer to a location of indices shape
+ * \param[in] indices_shape_len length of the block sparse indices shape
+ * \param[in] indices_data pointer to a location of indices data. Shape will determine the length of the indices data.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(FillSparseTensorBlockSparse, _Inout_ OrtValue* ort_value, _In_ const OrtMemoryInfo* data_mem_info,
+ _In_ const int64_t* values_shape, size_t values_shape_len, _In_ const void* values,
+ _In_ const int64_t* indices_shape_data, size_t indices_shape_len,
+ _In_ const int32_t* indices_data);
+
+ /**
+ * Create an ::OrtValue with a sparse tensor. This is the first step.
+ * Next, use Use<Format>Indices() functions to supply sparse tensor with
+ * format specific indices data and set its sparse format to a specific enum value.
+ * This will not perform memory allocations. It will
+ * use supplied user buffer which should outlive the created sparse tensor.
+ * Use OrtApi::ReleaseValue to destroy the sparse tensor. It would not release the supplied values buffer.
+ * This function can not be used to map strings from the user allocated memory. Strings must always be copied
+ * and have UTF-8 encoding. Therefore, use OrtApi::CreateSparseTensorAsOrtValue above and then fill it with data
+ * using appropriate Make*() function.
+ *
+ * \param[in] info memory info where sparse values reside.
+ * \param[in,out] p_data pointer to a user allocated buffer with values. To create a full sparse tensor with no non-zero
+ * values, pass nullptr
+ * \param[in] dense_shape shape of the original dense tensor
+ * \param[in] dense_shape_len number of shape dimensions being passed
+ * \param[in] values_shape shape of the values data. To create a fully sparse tensor with no non-zero values,
+ * pass {0} shape.
+ * \param[in] values_shape_len number of values shape dimensions
+ * \param[in] type must be one of TENSOR_ELEMENT_DATA_TYPE_xxxx
+ * \param[out] out Should be freed by calling ReleaseValue
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(CreateSparseTensorWithValuesAsOrtValue, _In_ const OrtMemoryInfo* info, _Inout_ void* p_data,
+ _In_ const int64_t* dense_shape, size_t dense_shape_len,
+ _In_ const int64_t* values_shape, size_t values_shape_len,
+ ONNXTensorElementDataType type, _Outptr_ OrtValue** out);
+
+ /**
+ * This assigns Coo format indices to the SparseTensor that was created by
+ * OrtApi::CreateSparseTensorWithValuesAsOrtValue above. It also sets OrtSparseFormat to
+ * ORT_SPARSE_COO. This will not allocate any additional memory for data. The life span of
+ * indices_data buffer should eclipse the life span of this ::OrtValue.
+ *
+ * \param[in,out] ort_value ::OrtValue instance constructed with OrtApi::CreateSparseTensorWithValuesAsOrtValue
+ * \param[in,out] indices_data pointer to a user pre-allocated buffer or nullptr for fully sparse tensors.
+ * \param[in] indices_num number of COO indices. Should either be 0 for fully sparse tensors, be equal
+ * to the number of nnz values specified to OrtApi::CreateSparseTensorWithValuesAsOrtValue for 1-D {nnz} indices or
+ * be twice as number of nnz values for a 2-D indices {nnz, 2}
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(UseCooIndices, _Inout_ OrtValue* ort_value, _Inout_ int64_t* indices_data, size_t indices_num);
+
+ /**
+ * The assigns CSR format indices to the SparseTensor that was created by
+ * OrtApi::CreateSparseTensorWithValuesAsOrtValue above. It also sets OrtSparseFormat to
+ * ORT_SPARSE_CSRC. This will not allocate any additional memory for data. The life spans of
+ * inner_data and outer_data buffers should eclipse the life span of this ::OrtValue.
+ *
+ * \param[in,out] ort_value ::OrtValue instance constructed with OrtApi::CreateSparseTensorWithValuesAsOrtValue
+ * \param[in,out] inner_data pointer to a user pre-allocated buffer or nullptr for fully sparse tensors.
+ * \param[in] inner_num number of inner CSR indices. Should either be 0 for fully sparse tensors or be equal
+ * to the number of nnz values specified to OrtApi::CreateSparseTensorWithValuesAsOrtValue.
+ * \param[in,out] outer_data pointer to user pre-allocated buffer or nullptr for fully sparse tensors.
+ * \param[in] outer_num number of CSR outer indices. Should either be 0 for fully sparse tensors or
+ * equal to rows + 1 of the dense shape.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(UseCsrIndices, _Inout_ OrtValue* ort_value, _Inout_ int64_t* inner_data, size_t inner_num,
+ _Inout_ int64_t* outer_data, size_t outer_num);
+
+ /**
+ * The assigns BlockSparse format indices to the SparseTensor that was created by
+ * OrtApi::CreateSparseTensorWithValuesAsOrtValue above. It also sets OrtSparseFormat to
+ * ORT_SPARSE_BLOCK_SPARSE. This will not allocate any additional memory for data. The life span of
+ * indices_data buffer must eclipse the lifespan of this ::OrtValue.
+ *
+ * \param[in,out] ort_value OrtValue instance constructed with OrtApi::CreateSparseTensorWithValuesAsOrtValue
+ * \param[in] indices_shape pointer to indices shape. Use {0} for fully sparse tensors
+ * \param[in] indices_shape_len length of the indices shape
+ * \param[in,out] indices_data pointer to user pre-allocated buffer or nullptr for fully sparse tensors.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(UseBlockSparseIndices, _Inout_ OrtValue* ort_value, const int64_t* indices_shape, size_t indices_shape_len, _Inout_ int32_t* indices_data);
+
+ /** \brief Returns sparse tensor format enum iff a given ort value contains an instance of sparse tensor.
+ *
+ * \param[in] ort_value ::OrtValue that contains an instance of sparse tensor
+ * \param[out] out pointer to out parameter
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetSparseTensorFormat, _In_ const OrtValue* ort_value, _Out_ enum OrtSparseFormat* out);
+
+ /** \brief Returns data type and shape of sparse tensor values (nnz) iff ::OrtValue contains a SparseTensor.
+ *
+ * \param[in] ort_value An ::OrtValue that contains a fully constructed sparse tensor
+ * \param[out] out Must be freed by OrtApi::ReleaseTensorTypeAndShapeInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetSparseTensorValuesTypeAndShape, _In_ const OrtValue* ort_value, _Outptr_ OrtTensorTypeAndShapeInfo** out);
+
+ /** \brief Returns numeric data for sparse tensor values (nnz). For string values use GetStringTensor*().
+ *
+ * \param[in] ort_value an instance of ::OrtValue containing sparse tensor
+ * \param[out] out returns a pointer to values data. Do not attempt to free this ptr.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetSparseTensorValues, _In_ const OrtValue* ort_value, _Outptr_ const void** out);
+
+ /** \brief Returns data type, shape for the type of indices specified by indices_format.
+ *
+ * \param[in] ort_value ::OrtValue containing sparse tensor.
+ * \param[in] indices_format One of the indices formats. It is an error to request a format that the sparse
+ * tensor does not contain.
+ * \param[out] out an instance of ::OrtTensorTypeAndShapeInfo. Must be freed by OrtApi::ReleaseTensorTypeAndShapeInfo
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetSparseTensorIndicesTypeShape, _In_ const OrtValue* ort_value, enum OrtSparseIndicesFormat indices_format, _Outptr_ OrtTensorTypeAndShapeInfo** out);
+
+ /** \brief Returns indices data for the type of the indices specified by indices_format
+ *
+ * \param[in] ort_value ::OrtValue containing sparse tensor.
+ * \param[in] indices_format One of the indices formats. It is an error to request a format that the sparse tensor does not contain.
+ * \param[out] num_indices Pointer to where the number of indices entries is returned
+ * \param[out] indices Returned pointer to the indices data. Do not free the returned pointer as it refers to internal data owned by the ::OrtValue
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetSparseTensorIndices, _In_ const OrtValue* ort_value, enum OrtSparseIndicesFormat indices_format, _Out_ size_t* num_indices, _Outptr_ const void** indices);
+ /// @}
+ /// \name OrtSessionOptions
+ /// @{
+
+ /**
+ * \brief Sets out to 1 iff an optional type OrtValue has an element, 0 otherwise (OrtValue is None)
+ * Use this API to find if the optional type OrtValue is None or not.
+ * If the optional type OrtValue is not None, use the OrtValue just like any other OrtValue.
+ * For example, if you get an OrtValue that corresponds to Optional(tensor) and
+ * if HasValue() returns true, use it as tensor and so on.
+
+ * \param[in] value Input OrtValue.
+ * \param[out] out indicating if the input OrtValue contains data (1) or if it is a None (0)
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(HasValue, _In_ const OrtValue* value, _Out_ int* out);
+
+ /// @}
+ /// \name OrtKernelContext
+ /// Custom operator APIs.
+ /// @{
+
+ /** \brief Used for custom operators, gets the GPU compute stream to use to launch the custom a GPU kernel
+ * \see ::OrtCustomOp
+ * \param[in] context OrtKernelContext instance
+ * \param[out] out Returns pointer to a GPU compute stream that can be used to launch the custom GPU kernel.
+ * If retrieving the GPU compute stream is not relevant (GPU not enabled in the build, kernel partitioned to
+ * some other EP), then a nullptr is returned as the output param.
+ * Do not free or mutate the returned pointer as it refers to internal data owned by the underlying session.
+ * Only use it for custom kernel launching.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(KernelContext_GetGPUComputeStream, _In_ const OrtKernelContext* context, _Outptr_ void** out);
+
+ /// @}
+ /// \name GetTensorMemoryInfo
+ /// @{
+ /** \brief Returns a pointer to the ::OrtMemoryInfo of a Tensor
+ * \param[in] value ::OrtValue containing tensor.
+ * \param[out] mem_info ::OrtMemoryInfo of the tensor. Do NOT free the returned pointer. It is valid for the lifetime of the ::OrtValue
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetTensorMemoryInfo, _In_ const OrtValue* value, _Out_ const OrtMemoryInfo** mem_info);
+
+ /// @}
+ /// \name GetExecutionProviderApi
+ /// @{
+ /** \brief Get a pointer to the requested version of the Execution Provider specific
+ * API extensions to the OrtApi
+ * \param[in] provider_name The name of the execution provider name. Currently only the following
+ * values are supported: "DML".
+ * \param[in] version Must be ::ORT_API_VERSION.
+ * \param[out] provider_api A void pointer containing a reference to the execution provider versioned api structure.
+ * For example, the provider_api pointer can be cast to the OrtDmlApi* when the provider_name is "DML".
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(GetExecutionProviderApi, _In_ const char* provider_name, _In_ uint32_t version, _Outptr_ const void** provider_api);
+
+ /// @}
+
+ /// \name SessionOptions
+ /// @{
+ /** \brief Set custom thread creation function
+ *
+ * \param[in] options Session options
+ * \param[in] ort_custom_create_thread_fn Custom thread creation function
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionOptionsSetCustomCreateThreadFn, _Inout_ OrtSessionOptions* options, _In_ OrtCustomCreateThreadFn ort_custom_create_thread_fn);
+
+ /** \brief Set creation options for custom thread
+ *
+ * \param[in] options Session options
+ * \param[in] ort_custom_thread_creation_options Custom thread creation options (can be nullptr)
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionOptionsSetCustomThreadCreationOptions, _Inout_ OrtSessionOptions* options, _In_ void* ort_custom_thread_creation_options);
+
+ /** \brief Set custom thread join function
+ *
+ * \param[in] options Session options
+ * \param[in] ort_custom_join_thread_fn Custom join thread function, must not be nullptr when ort_custom_create_thread_fn is set
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SessionOptionsSetCustomJoinThreadFn, _Inout_ OrtSessionOptions* options, _In_ OrtCustomJoinThreadFn ort_custom_join_thread_fn);
+ /// @}
+
+ /// \name OrtThreadingOptions
+ /// @{
+ /** \brief Set custom thread creation function for global thread pools
+ *
+ * \param[inout] tp_options
+ * \param[in] ort_custom_create_thread_fn Custom thread creation function
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetGlobalCustomCreateThreadFn, _Inout_ OrtThreadingOptions* tp_options, _In_ OrtCustomCreateThreadFn ort_custom_create_thread_fn);
+
+ /** \brief Set custom thread creation options for global thread pools
+ *
+ * \param[inout] tp_options
+ * \param[in] ort_custom_thread_creation_options Custom thread creation options (can be nullptr)
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetGlobalCustomThreadCreationOptions, _Inout_ OrtThreadingOptions* tp_options, _In_ void* ort_custom_thread_creation_options);
+
+ /** \brief Set custom thread join function for global thread pools
+ *
+ * \param[inout] tp_options
+ * \param[in] ort_custom_join_thread_fn Custom thread join function, must not be nullptr when global ort_custom_create_thread_fn is set
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SetGlobalCustomJoinThreadFn, _Inout_ OrtThreadingOptions* tp_options, _In_ OrtCustomJoinThreadFn ort_custom_join_thread_fn);
+ /// @}
+
+ /** \brief Synchronize bound inputs. The call may be necessary for some providers, such as cuda,
+ * in case the system that allocated bound memory operated on a different stream. However, the
+ * operation is provider specific and could be a no-op.
+ *
+ * \param[inout] binding_ptr
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SynchronizeBoundInputs, _Inout_ OrtIoBinding* binding_ptr);
+
+ /** \brief Synchronize bound outputs. The call may be necessary for some providers, such as cuda,
+ * in case the system that allocated bound memory operated on a different stream. However, the
+ * operation is provider specific and could be a no-op.
+ *
+ * \param[inout] binding_ptr
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(SynchronizeBoundOutputs, _Inout_ OrtIoBinding* binding_ptr);
+
+ /// \name OrtSessionOptions
+ /// @{
+
+ /** \brief Append CUDA execution provider to the session options
+ *
+ * If CUDA is not available (due to a non CUDA enabled build), this function will return failure.
+ *
+ * This is slightly different from OrtApi::SessionOptionsAppendExecutionProvider_CUDA, it takes an
+ * ::OrtCUDAProviderOptions which is publicly defined. This takes an opaque ::OrtCUDAProviderOptionsV2
+ * which must be created with OrtApi::CreateCUDAProviderOptions.
+ *
+ * For OrtApi::SessionOptionsAppendExecutionProvider_CUDA, the user needs to instantiate ::OrtCUDAProviderOptions
+ * as well as allocate/release buffers for some members of ::OrtCUDAProviderOptions.
+ * Here, OrtApi::CreateCUDAProviderOptions and Ortapi::ReleaseCUDAProviderOptions will do the memory management for you.
+ *
+ * \param[in] options
+ * \param[in] cuda_options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.11.
+ */
+ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_CUDA_V2,
+ _In_ OrtSessionOptions* options, _In_ const OrtCUDAProviderOptionsV2* cuda_options);
+
+ /// @}
+ /// \name OrtCUDAProviderOptionsV2
+ /// @{
+
+ /** \brief Create an OrtCUDAProviderOptionsV2
+ *
+ * \param[out] out Newly created ::OrtCUDAProviderOptionsV2. Must be released with OrtApi::ReleaseCudaProviderOptions
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.11.
+ */
+ ORT_API2_STATUS(CreateCUDAProviderOptions, _Outptr_ OrtCUDAProviderOptionsV2** out);
+
+ /** \brief Set options in a CUDA Execution Provider.
+ *
+ * Please refer to https://onnxruntime.ai/docs/execution-providers/CUDA-ExecutionProvider.html#configuration-options
+ * to know the available keys and values. Key should be in null terminated string format of the member of ::OrtCUDAProviderOptionsV2
+ * and value should be its related range.
+ *
+ * For example, key="device_id" and value="0"
+ *
+ * \param[in] cuda_options
+ * \param[in] provider_options_keys Array of UTF-8 null-terminated string for provider options keys
+ * \param[in] provider_options_values Array of UTF-8 null-terminated string for provider options values
+ * \param[in] num_keys Number of elements in the `provider_option_keys` and `provider_options_values` arrays
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.11.
+ */
+ ORT_API2_STATUS(UpdateCUDAProviderOptions, _Inout_ OrtCUDAProviderOptionsV2* cuda_options,
+ _In_reads_(num_keys) const char* const* provider_options_keys,
+ _In_reads_(num_keys) const char* const* provider_options_values,
+ _In_ size_t num_keys);
+
+ /**
+ * Get serialized CUDA provider options string.
+ *
+ * For example, "device_id=0;arena_extend_strategy=0;......"
+ *
+ * \param cuda_options - OrtCUDAProviderOptionsV2 instance
+ * \param allocator - a ptr to an instance of OrtAllocator obtained with CreateAllocator() or GetAllocatorWithDefaultOptions()
+ * the specified allocator will be used to allocate continuous buffers for output strings and lengths.
+ * \param ptr - is a UTF-8 null terminated string allocated using 'allocator'. The caller is responsible for using the same allocator to free it.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.11.
+ */
+ ORT_API2_STATUS(GetCUDAProviderOptionsAsString, _In_ const OrtCUDAProviderOptionsV2* cuda_options, _Inout_ OrtAllocator* allocator, _Outptr_ char** ptr);
+
+ /** \brief Release an ::OrtCUDAProviderOptionsV2
+ *
+ * \note This is an exception in the naming convention of other Release* functions, as the name of the method does not have the V2 suffix, but the type does
+ *
+ * \since Version 1.11.
+ */
+ void(ORT_API_CALL* ReleaseCUDAProviderOptions)(_Frees_ptr_opt_ OrtCUDAProviderOptionsV2* input);
+
+ /// @}
+
+ /** \brief Append MIGraphX provider to session options
+ *
+ * If MIGraphX is not available (due to a non MIGraphX enabled build, or if MIGraphX is not installed on the system), this function will return failure.
+ *
+ * \param[in] options
+ * \param[in] migraphx_options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.11.
+ */
+ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_MIGraphX,
+ _In_ OrtSessionOptions* options, _In_ const OrtMIGraphXProviderOptions* migraphx_options);
+
+ /** \brief Replace initialized Tensors with external data with the data provided in initializers.
+ *
+ * The function will find the initialized TensorProtos with external data in the graph with the provided names and
+ * replace them with the provided tensors. The API verifies that the TensorProto being replaced
+ * has an external data reference and has the same name, dimensions and data type as its replacement. The replacement
+ * will occur before any of the optimizations take place. The data will be copied into the graph
+ * since TensorProto can't refer to the user provided buffers.
+ *
+ * Once the model has been loaded, the OrtValue(s) added to SessionOptions instance will be removed
+ * from the internal SessionOptions copy to save memory, the user provided buffers can then be deallocated
+ * and the SessionOptions instance that refers to them can be destroyed.
+ *
+ * \param[in] options
+ * \param[in] initializer_names Array of null terminated UTF-8 encoded strings of the initializers names.
+ * \param[in] initializers Array of ::OrtValue type
+ * \param[in] initializers_num Number of elements in the initializer_names and initializers
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.12.
+ */
+ ORT_API2_STATUS(AddExternalInitializers, _In_ OrtSessionOptions* options,
+ _In_reads_(input_len) const char* const* initializer_names,
+ _In_reads_(input_len) const OrtValue* const* initializers, size_t initializers_num);
+
+ /** \brief: Create attribute of onnxruntime operator
+ *
+ * \param[in] name Name of the attribute
+ * \param[in] data Data content of the attribute
+ * \param[in] len Number of bytes stored in data
+ * \param[in] type Data type
+ * \param[out] op_attr Attribute that has been created, which must be released by OrtApi::ReleaseOpAttr
+ *
+ * \since Version 1.12.
+ */
+ ORT_API2_STATUS(CreateOpAttr,
+ _In_ const char* name,
+ _In_ const void* data,
+ _In_ int len,
+ _In_ OrtOpAttrType type,
+ _Outptr_ OrtOpAttr** op_attr);
+
+ /* \brief: Release op attribute
+ *
+ * \param[in] opAttr Attribute created by OrtApi::CreateOpAttr
+ *
+ * \since Version 1.12.
+ */
+ ORT_CLASS_RELEASE(OpAttr);
+
+ /** \brief: Create onnxruntime native operator
+ *
+ * \param[in] info Kernel info
+ * \param[in] op_name Operator name
+ * \param[in] domain Operator domain
+ * \param[in] version Operator opset version
+ * \param[in] type_constraint_names Name of the type contraints, such as "T" or "T1"
+ * \param[in] type_constraint_values Type of each contraints
+ * \param[in] type_constraint_count Number of contraints
+ * \param[in] attr_values Attributes used to initialize the operator
+ * \param[in] attr_count Number of the attributes
+ * \param[in] input_count Number of inputs
+ * \param[in] output_count Number of outputs
+ * \param[out] ort_op Operator that has been created
+ *
+ * \since Version 1.12.
+ */
+ ORT_API2_STATUS(CreateOp,
+ _In_ const OrtKernelInfo* info,
+ _In_ const char* op_name,
+ _In_ const char* domain,
+ _In_ int version,
+ _In_opt_ const char** type_constraint_names,
+ _In_opt_ const ONNXTensorElementDataType* type_constraint_values,
+ _In_opt_ int type_constraint_count,
+ _In_opt_ const OrtOpAttr* const* attr_values,
+ _In_opt_ int attr_count,
+ _In_ int input_count,
+ _In_ int output_count,
+ _Outptr_ OrtOp** ort_op);
+
+ /** \brief: Invoke the operator created by OrtApi::CreateOp
+ * The inputs must follow the order as specified in onnx specification
+ *
+ * \param[in] context Kernel context
+ * \param[in] ort_op Operator that has been created
+ * \param[in] input_values Array of inputs
+ * \param[in] input_count Number of inputs
+ * \param[in] output_values Array of outputs
+ * \param[in] output_count Number of outputs
+ *
+ * \since Version 1.12.
+ */
+ ORT_API2_STATUS(InvokeOp,
+ _In_ const OrtKernelContext* context,
+ _In_ const OrtOp* ort_op,
+ _In_ const OrtValue* const* input_values,
+ _In_ int input_count,
+ _Inout_ OrtValue* const* output_values,
+ _In_ int output_count);
+
+ /* \brief: Release an onnxruntime operator
+ *
+ * \param[in] Op Operator created by OrtApi::CreateOp
+ *
+ * \since Version 1.12.
+ */
+ ORT_CLASS_RELEASE(Op);
+
+ /** \brief: Append execution provider to the session options.
+ * \param[in] options
+ * \param[in] provider_name - provider to add.
+ * \param[in] provider_options_keys - keys to configure the provider options
+ * \param[in] provider_options_values - values to configure the provider options
+ * \param[in] num_keys - number of keys passed in
+ *
+ * Currently supported providers:
+ * SNPE
+ * XNNPACK
+ *
+ * Note: If an execution provider has a dedicated SessionOptionsAppendExecutionProvider_<provider name> function
+ * that should be used to add it.
+ *
+ * SNPE supported keys:
+ * "runtime": SNPE runtime engine, options: "CPU", "CPU_FLOAT32", "GPU", "GPU_FLOAT32_16_HYBRID", "GPU_FLOAT16",
+ * "DSP", "DSP_FIXED8_TF", "AIP_FIXED_TF", "AIP_FIXED8_TF".
+ * Mapping to SNPE Runtime_t definition: CPU, CPU_FLOAT32 => zdl::DlSystem::Runtime_t::CPU;
+ * GPU, GPU_FLOAT32_16_HYBRID => zdl::DlSystem::Runtime_t::GPU;
+ * GPU_FLOAT16 => zdl::DlSystem::Runtime_t::GPU_FLOAT16;
+ * DSP, DSP_FIXED8_TF => zdl::DlSystem::Runtime_t::DSP.
+ * AIP_FIXED_TF, AIP_FIXED8_TF => zdl::DlSystem::Runtime_t::AIP_FIXED_TF.
+ * "priority": execution priority, options: "low", "normal".
+ * "buffer_type": ITensor or user buffers, options: "ITENSOR", user buffer with different types - "TF8", "TF16", "UINT8", "FLOAT".
+ * "ITENSOR" -- default, ITensor which is float only.
+ * "TF8" -- quantized model required, "FLOAT" -- for both quantized or non-quantized model
+ * If SNPE is not available (due to a non Snpe enabled build or its dependencies not being installed), this function will fail.
+ *
+ * XNNPACK supported keys:
+ * "intra_op_num_threads": number of thread-pool size to use for XNNPACK execution provider.
+ * default value is 0, which means to use the session thread-pool size.
+ *
+ * \since Version 1.12.
+ */
+ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider, _In_ OrtSessionOptions* options,
+ _In_ const char* provider_name,
+ _In_reads_(num_keys) const char* const* provider_options_keys,
+ _In_reads_(num_keys) const char* const* provider_options_values,
+ _In_ size_t num_keys);
+
+ /* \brief: Get a copy of kernel info
+ *
+ * \param[in] info Kernel info
+ * \param[out] info_copy Copy of kernel info
+ *
+ * \since Version 1.12.
+ */
+ ORT_API2_STATUS(CopyKernelInfo,
+ _In_ const OrtKernelInfo* info,
+ _Outptr_ OrtKernelInfo** info_copy);
+
+ /* \brief: Release kernel info
+ *
+ * \param[in] KernelInfo A copy of kernel info returned by CopyKernelInfo
+ *
+ * \since Version 1.12.
+ */
+ ORT_CLASS_RELEASE(KernelInfo);
+
+ /* \brief: Get the training C Api
+ *
+ * \since Version 1.13
+ */
+ const OrtTrainingApi*(ORT_API_CALL* GetTrainingApi)(uint32_t version)NO_EXCEPTION;
+
+ /** \brief Append CANN provider to session options
+ *
+ * If CANN is not available (due to a non CANN enabled build, or if CANN is not installed on the system), this function will return failure.
+ *
+ * \param[in] options
+ * \param[in] cann_options
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.13.
+ */
+ ORT_API2_STATUS(SessionOptionsAppendExecutionProvider_CANN,
+ _In_ OrtSessionOptions* options, _In_ const OrtCANNProviderOptions* cann_options);
+
+ /** \brief Create an OrtCANNProviderOptions
+ *
+ * \param[out] out created ::OrtCANNProviderOptions. Must be released with OrtApi::ReleaseCANNProviderOptions
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.13.
+ */
+ ORT_API2_STATUS(CreateCANNProviderOptions, _Outptr_ OrtCANNProviderOptions** out);
+
+ /** \brief Set options in a CANN Execution Provider.
+ *
+ * \param[in] cann_options
+ * \param[in] provider_options_keys Array of UTF-8 null-terminated string for provider options keys
+ * \param[in] provider_options_values Array of UTF-8 null-terminated string for provider options values
+ * \param[in] num_keys Number of elements in the `provider_option_keys` and `provider_options_values` arrays
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.13.
+ */
+ ORT_API2_STATUS(UpdateCANNProviderOptions, _Inout_ OrtCANNProviderOptions* cann_options,
+ _In_reads_(num_keys) const char* const* provider_options_keys,
+ _In_reads_(num_keys) const char* const* provider_options_values,
+ _In_ size_t num_keys);
+
+ /** \brief Get serialized CANN provider options string.
+ *
+ * \param[in] cann_options OrtCANNProviderOptions instance
+ * \param[in] allocator a ptr to an instance of OrtAllocator obtained with CreateAllocator()
+ * or GetAllocatorWithDefaultOptions(), the specified allocator will be used to allocate
+ * continuous buffers for output strings and lengths.
+ * \param[out] ptr is a UTF-8 null terminated string allocated using 'allocator'.
+ * The caller is responsible for using the same allocator to free it.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ *
+ * \since Version 1.13.
+ */
+ ORT_API2_STATUS(GetCANNProviderOptionsAsString, _In_ const OrtCANNProviderOptions* cann_options,
+ _Inout_ OrtAllocator* allocator, _Outptr_ char** ptr);
+
+ /** \brief Release an OrtCANNProviderOptions
+ *
+ * \param[in] the pointer of OrtCANNProviderOptions which will been deleted
+ *
+ * \since Version 1.13.
+ */
+ void(ORT_API_CALL* ReleaseCANNProviderOptions)(_Frees_ptr_opt_ OrtCANNProviderOptions* input);
+
+ /* \brief Get OrtDevice type from MemoryInfo
+ *
+ * \since Version 1.14
+ */
+ void(ORT_API_CALL* MemoryInfoGetDeviceType)(_In_ const OrtMemoryInfo* ptr, _Out_ OrtMemoryInfoDeviceType* out);
+
+ /* \brief Update the OrtEnv instance with custom log severity level
+ *
+ * \param[in] ort_env The OrtEnv instance being used
+ * \param[in] log_severity_level The log severity level.
+ *
+ * \since Version 1.14.
+ */
+ ORT_API2_STATUS(UpdateEnvWithCustomLogLevel, _In_ OrtEnv* ort_env, OrtLoggingLevel log_severity_level);
+
+ /* \brief Set affinities for intra op threads
+ *
+ * Affinity string follows format:
+ * logical_processor_id,logical_processor_id;logical_processor_id,logical_processor_id
+ * Semicolon isolates configurations among threads, while comma split processors where ith thread expected to attach to.
+ * e.g. 1,2,3;4,5
+ * specifies affinities for two threads, with the 1st thread attach to the 1st, 2nd, and 3rd processor, and 2nd thread to the 4th and 5th.
+ * To ease the configuration, an "interval" is also allowed:
+ * e.g. 1-8;8-16;17-24
+ * orders that the 1st thread runs on first eight processors, 2nd thread runs on next eight processors, and so forth.
+ * Note:
+ * 1. Once set, the number of thread affinities must equal to intra_op_num_threads - 1,
+ * ort does not set affinity on the main thread which is started and managed by the calling app;
+ * 2. For windows, ort will infer the group id from a logical processor id, for example, assuming there are two groups with each has 64 logical processors,
+ * an id of 64 will be inferred as the last processor of the 1st group, while 65 will be interpreted as the 1st processor of the second group.
+ * Hence 64-65 is an invalid configuration, because a windows thread cannot be attached to processors across group boundary.
+ *
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(SetGlobalIntraOpThreadAffinity, _Inout_ OrtThreadingOptions* tp_options, const char* affinity_string);
+
+ /** \brief Register custom ops from a shared library.
+ *
+ * Loads a shared library (.dll on windows, .so on linux, etc) named 'library_name' and looks for this entry point:
+ * OrtStatus* RegisterCustomOps(OrtSessionOptions * options, const OrtApiBase* api);
+ * It then passes in the provided session options to this function along with the api base.
+ *
+ * The handle to the loaded library is automatically released by ORT when the last OrtSession that references the
+ * library handle is released. If no OrtSession is created, then the library handle is released when the provided
+ * OrtSessionOptions is released.
+ *
+ * \param[in] options The session options.
+ * \param[in] library_name The name of the shared library to load and register. Refer to OS-specific dynamic library
+ * loading utilities (e.g., LoadLibraryEx on Windows or dlopen on Linux/MacOS) for information
+ * on the format of library names and search paths.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(RegisterCustomOpsLibrary_V2, _Inout_ OrtSessionOptions* options, _In_ const ORTCHAR_T* library_name);
+
+ /** \brief Register custom ops by calling a RegisterCustomOpsFn function.
+ *
+ * Searches for registration_func_name and if found calls it.
+ *
+ * The library containing the function must either be linked against or previously loaded by the executable.
+ *
+ * If you want ONNX Runtime to load the library and manage its lifetime, use RegisterCustomOpsLibrary_V2.
+ *
+ * RegisterCustomOpsUsingFunction can be used in scenarios where it may not be possible for ONNX Runtime to load
+ * the library from a path. e.g. mobile platforms where the library must be linked into the app.
+ *
+ * The registration function must have the signature of RegisterCustomOpsFn:
+ * OrtStatus* (*fn)(OrtSessionOptions* options, const OrtApiBase* api);
+ *
+ * See https://onnxruntime.ai/docs/reference/operators/add-custom-op.html for details on how the registration
+ * function should be implemented.
+ *
+ * \param[in] options OrtSessionOptions that is passed through as the first argument in the call to the
+ * registration function.
+ * \param[in] registration_func_name Name of registration function to use.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(RegisterCustomOpsUsingFunction, _Inout_ OrtSessionOptions* options,
+ _In_ const char* registration_func_name);
+
+ /// @}
+ /// \name OrtKernelInfo
+ /// Custom operator APIs.
+ /// @{
+
+ /** \brief Get the number of inputs from ::OrtKernelInfo.
+ *
+ * Used in the CreateKernel callback of an OrtCustomOp to query the number of inputs
+ * during kernel/session creation.
+ *
+ * \param[in] info Instance of ::OrtKernelInfo.
+ * \param[out] out Pointer to variable assigned with the result on success.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(KernelInfo_GetInputCount, _In_ const OrtKernelInfo* info, _Out_ size_t* out);
+
+ /** \brief Get the number of outputs from ::OrtKernelInfo.
+ *
+ * Used in the CreateKernel callback of an OrtCustomOp to query the number of outputs
+ * during kernel/session creation.
+ *
+ * \param[in] info Instance of ::OrtKernelInfo.
+ * \param[out] out Pointer to variable assigned with the result on success.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(KernelInfo_GetOutputCount, _In_ const OrtKernelInfo* info, _Out_ size_t* out);
+
+ /** \brief Get the name of a ::OrtKernelInfo's input.
+ *
+ * Used in the CreateKernel callback of an OrtCustomOp to query an input's name
+ * during kernel/session creation.
+ *
+ * If `out` is nullptr, the value of `size` is set to the size of the name
+ * string (including null-terminator), and a success status is returned.
+ *
+ * If the `size` parameter is greater than or equal to the name string's size,
+ * the value of `size` is set to the true size of the string (including null-terminator),
+ * the provided memory is filled with the string's contents, and a success status is returned.
+ *
+ * If the `size` parameter is less than the actual string's size and `out`
+ * is not nullptr, the value of `size` is set to the true size of the string
+ * and a failure status is returned.
+ *
+ * \param[in] info An instance of ::OrtKernelInfo.
+ * \param[in] index The index of the input name to get. Returns a failure status if out-of-bounds.
+ * \param[out] out Memory location into which to write the UTF-8 null-terminated string representing the input's name.
+ * \param[in,out] size Pointer to the size of the `out` buffer. See above comments for details.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(KernelInfo_GetInputName, _In_ const OrtKernelInfo* info, size_t index, _Out_ char* out,
+ _Inout_ size_t* size);
+
+ /** \brief Get the name of a ::OrtKernelInfo's output.
+ *
+ * Used in the CreateKernel callback of an OrtCustomOp to query an output's name
+ * during kernel/session creation.
+ *
+ * If `out` is nullptr, the value of `size` is set to the size of the name
+ * string (including null-terminator), and a success status is returned.
+ *
+ * If the `size` parameter is greater than or equal to the name string's size,
+ * the value of `size` is set to the true size of the string (including null-terminator),
+ * the provided memory is filled with the string's contents, and a success status is returned.
+ *
+ * If the `size` parameter is less than the actual string's size and `out`
+ * is not nullptr, the value of `size` is set to the true size of the string
+ * and a failure status is returned.
+ *
+ * \param[in] info An instance of ::OrtKernelInfo.
+ * \param[in] index The index of the output name to get. Returns a failure status if out-of-bounds.
+ * \param[out] out Memory location into which to write the UTF-8 null-terminated string representing the output's
+ * name.
+ * \param[in,out] size Pointer to the size of the `out` buffer. See above comments for details.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(KernelInfo_GetOutputName, _In_ const OrtKernelInfo* info, size_t index, _Out_ char* out,
+ _Inout_ size_t* size);
+
+ /** \brief Get the type information for a ::OrtKernelInfo's input.
+ *
+ * Used in the CreateKernel callback of an OrtCustomOp to query the shape and type information
+ * of an input during kernel/session creation.
+ *
+ * \param[in] info An instance of ::OrtKernelInfo.
+ * \param[out] type_info Pointer set to the resulting ::OrtTypeInfo. Must be freed with OrtApi::ReleaseTypeInfo.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(KernelInfo_GetInputTypeInfo, _In_ const OrtKernelInfo* info, size_t index,
+ _Outptr_ OrtTypeInfo** type_info);
+
+ /** \brief Get the type information for a ::OrtKernelInfo's output.
+ *
+ * Used in the CreateKernel callback of an OrtCustomOp to query the shape and type information
+ * of an output during kernel/session creation.
+ *
+ * \param[in] info An instance of ::OrtKernelInfo.
+ * \param[out] type_info Pointer set to the resulting ::OrtTypeInfo. Must be freed with OrtApi::ReleaseTypeInfo.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(KernelInfo_GetOutputTypeInfo, _In_ const OrtKernelInfo* info, size_t index,
+ _Outptr_ OrtTypeInfo** type_info);
+
+ /** \brief Get a ::OrtValue tensor stored as an attribute in the graph node.
+ *
+ * Used in the CreateKernel callback of an OrtCustomOp to get a tensor attribute.
+ *
+ * \param[in] info ::OrtKernelInfo instance.
+ * \param[in] name UTF-8 null-terminated string representing the attribute's name.
+ * \param[in] allocator Allocator used to allocate the internal tensor state.
+ * \param[out] out Returns newly created ::OrtValue. Must be freed with OrtApi::ReleaseValue,
+ * which will also free internal tensor state allocated with the provided allocator.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ */
+ ORT_API2_STATUS(KernelInfoGetAttribute_tensor, _In_ const OrtKernelInfo* info, _In_z_ const char* name,
+ _Inout_ OrtAllocator* allocator, _Outptr_ OrtValue** out);
+
+ /// @}
+ /// \name OrtSessionOptions
+ /// Custom operator APIs
+ /// @{
+
+ /** \brief Checks if the given session configuration entry exists.
+ *
+ * The config_key formats are defined in onnxruntime_session_options_config_keys.h
+ *
+ * Can be used in a custom operator library to check for session configuration entries
+ * that target one or more custom operators in the library. Example: The config entry
+ * custom_op.myop.some_key targets a custom op named "myop".
+ *
+ * \param[in] options The ::OrtSessionOptions instance.
+ * \param[in] config_key A null-terminated UTF-8 string representation of the configuration key.
+ * \param[out] out Pointer set to 1 if the entry exists and 0 otherwise.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(HasSessionConfigEntry, _In_ const OrtSessionOptions* options,
+ _In_z_ const char* config_key, _Out_ int* out);
+
+ /** \brief Get a session configuration value.
+ *
+ * Returns a failure status if the configuration key does not exist.
+ * The config_key and the format of config_value are defined in onnxruntime_session_options_config_keys.h
+ *
+ * If `config_value` is nullptr, the value of `size` is set to the true size of the string
+ * value (including null-terminator), and a success status is returned.
+ *
+ * If the `size` parameter is greater than or equal to the actual string value's size,
+ * the value of `size` is set to the true size of the string value, the provided memory
+ * is filled with the value's contents, and a success status is returned.
+ *
+ * If the `size` parameter is less than the actual string value's size and `config_value`
+ * is not nullptr, the value of `size` is set to the true size of the string value
+ * and a failure status is returned.
+ *
+ * Can be used in a custom operator library to get session configuration entries
+ * that target one or more custom operators in the library. Example: The config entry
+ * custom_op.myop.some_key targets a custom op named "myop".
+ *
+ * \param[in] options The session options.
+ * \param[in] config_key A null-terminated UTF-8 string representation of the config key.
+ * \param[in] config_value Pointer to memory where the null-terminated UTF-8 string value will be stored.
+ * \param[in,out] size Pointer to the size of the `config_value` buffer. See above comments for details.
+ *
+ * \snippet{doc} snippets.dox OrtStatus Return Value
+ * \since Version 1.14
+ */
+ ORT_API2_STATUS(GetSessionConfigEntry, _In_ const OrtSessionOptions* options,
+ _In_z_ const char* config_key, _Out_ char* config_value, _Inout_ size_t* size);
+
+ /// @}
+
+#ifdef __cplusplus
+ OrtApi(const OrtApi&) = delete; // Prevent users from accidentally copying the API structure, it should always be passed as a pointer
+#endif
+};
+
+/*
+ * Steps to use a custom op:
+ * 1 Create an OrtCustomOpDomain with the domain name used by the custom ops
+ * 2 Create an OrtCustomOp structure for each op and add them to the domain
+ * 3 Call OrtAddCustomOpDomain to add the custom domain of ops to the session options
+ */
+
+// Specifies some characteristics of inputs/outputs of custom ops:
+// Specify if the inputs/outputs are one of:
+// 1) Non-optional (input/output must be present in the node)
+// 2) Optional (input/output may be absent in the node)
+// 3) Variadic: A variadic input or output specifies N (i.e., the minimum arity) or more operands.
+// Only the last input or output of a custom op may be marked as variadic.
+// The homogeneity of the variadic input or output determines whether all operands must be of the same
+// tensor element type.
+typedef enum OrtCustomOpInputOutputCharacteristic {
+ INPUT_OUTPUT_REQUIRED = 0,
+ INPUT_OUTPUT_OPTIONAL,
+ INPUT_OUTPUT_VARIADIC,
+} OrtCustomOpInputOutputCharacteristic;
+
+/*
+ * The OrtCustomOp structure defines a custom op's schema and its kernel callbacks. The callbacks are filled in by
+ * the implementor of the custom op.
+ */
+struct OrtCustomOp {
+ uint32_t version; // Must be initialized to ORT_API_VERSION
+
+ // This callback creates the kernel, which is a user defined parameter that is passed to the Kernel* callbacks below.
+ void*(ORT_API_CALL* CreateKernel)(_In_ const struct OrtCustomOp* op, _In_ const OrtApi* api,
+ _In_ const OrtKernelInfo* info);
+
+ // Returns the name of the op
+ const char*(ORT_API_CALL* GetName)(_In_ const struct OrtCustomOp* op);
+
+ // Returns the type of the execution provider, return nullptr to use CPU execution provider
+ const char*(ORT_API_CALL* GetExecutionProviderType)(_In_ const struct OrtCustomOp* op);
+
+ // Returns the count and types of the input & output tensors
+ ONNXTensorElementDataType(ORT_API_CALL* GetInputType)(_In_ const struct OrtCustomOp* op, _In_ size_t index);
+ size_t(ORT_API_CALL* GetInputTypeCount)(_In_ const struct OrtCustomOp* op);
+ ONNXTensorElementDataType(ORT_API_CALL* GetOutputType)(_In_ const struct OrtCustomOp* op, _In_ size_t index);
+ size_t(ORT_API_CALL* GetOutputTypeCount)(_In_ const struct OrtCustomOp* op);
+
+ // Op kernel callbacks
+ void(ORT_API_CALL* KernelCompute)(_In_ void* op_kernel, _In_ OrtKernelContext* context);
+ void(ORT_API_CALL* KernelDestroy)(_In_ void* op_kernel);
+
+ // Returns the characteristics of the input & output tensors
+ OrtCustomOpInputOutputCharacteristic(ORT_API_CALL* GetInputCharacteristic)(_In_ const struct OrtCustomOp* op, _In_ size_t index);
+ OrtCustomOpInputOutputCharacteristic(ORT_API_CALL* GetOutputCharacteristic)(_In_ const struct OrtCustomOp* op, _In_ size_t index);
+
+ // Returns the memory type of the input tensors. This API allows the custom op
+ // to place the inputs on specific devices. By default, it returns
+ // OrtMemTypeDefault, which means the input is placed on the default device for
+ // the execution provider. If the inputs need to be with different memory tyeps,
+ // this function can be overridden to return the specific memory types.
+ OrtMemType(ORT_API_CALL* GetInputMemoryType)(_In_ const struct OrtCustomOp* op, _In_ size_t index);
+
+ // Returns the minimum number of input arguments expected for the variadic input.
+ // Applicable only for custom ops that have a variadic input.
+ int(ORT_API_CALL* GetVariadicInputMinArity)(_In_ const struct OrtCustomOp* op);
+
+ // Returns true (non-zero) if all arguments of a variadic input have to be of the same type (homogeneous),
+ // and false (zero) otherwise.
+ // Applicable only for custom ops that have a variadic input.
+ int(ORT_API_CALL* GetVariadicInputHomogeneity)(_In_ const struct OrtCustomOp* op);
+
+ // Returns the minimum number of output values expected for the variadic output.
+ // Applicable only for custom ops that have a variadic output.
+ int(ORT_API_CALL* GetVariadicOutputMinArity)(_In_ const struct OrtCustomOp* op);
+
+ // Returns true (non-zero) if all outputs values of a variadic output have to be of the same type (homogeneous),
+ // and false (zero) otherwise.
+ // Applicable only for custom ops that have a variadic output.
+ int(ORT_API_CALL* GetVariadicOutputHomogeneity)(_In_ const struct OrtCustomOp* op);
+};
+
+/*
+ * This is the old way to add the CUDA provider to the session, please use SessionOptionsAppendExecutionProvider_CUDA above to access the latest functionality
+ * This function always exists, but will only succeed if Onnxruntime was built with CUDA support and the CUDA provider shared library exists
+ *
+ * \param device_id CUDA device id, starts from zero.
+ */
+ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_CUDA, _In_ OrtSessionOptions* options, int device_id);
+
+/*
+ * This is the old way to add the MIGraphX provider to the session, please use
+ * SessionOptionsAppendExecutionProvider_MIGraphX above to access the latest functionality
+ * This function always exists, but will only succeed if Onnxruntime was built with
+ * HIP support and the MIGraphX provider shared library exists
+ *
+ * \param device_id HIP device id, starts from zero.
+ */
+ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_MIGraphX, _In_ OrtSessionOptions* options, int device_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+//! @}
diff --git a/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_cxx_api.h b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_cxx_api.h
new file mode 100644
index 0000000..97b2aa4
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_cxx_api.h
@@ -0,0 +1,1876 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+// Summary: The Ort C++ API is a header only wrapper around the Ort C API.
+//
+// The C++ API simplifies usage by returning values directly instead of error codes, throwing exceptions on errors
+// and automatically releasing resources in the destructors. The primary purpose of C++ API is exception safety so
+// all the resources follow RAII and do not leak memory.
+//
+// Each of the C++ wrapper classes holds only a pointer to the C internal object. Treat them like smart pointers.
+// To create an empty object, pass 'nullptr' to the constructor (for example, Env e{nullptr};). However, you can't use them
+// until you assign an instance that actually holds an underlying object.
+//
+// For Ort objects only move assignment between objects is allowed, there are no copy constructors.
+// Some objects have explicit 'Clone' methods for this purpose.
+//
+// ConstXXXX types are copyable since they do not own the underlying C object, so you can pass them to functions as arguments
+// by value or by reference. ConstXXXX types are restricted to const only interfaces.
+//
+// UnownedXXXX are similar to ConstXXXX but also allow non-const interfaces.
+//
+// The lifetime of the corresponding owning object must eclipse the lifetimes of the ConstXXXX/UnownedXXXX types. They exists so you do not
+// have to fallback to C types and the API with the usual pitfalls. In general, do not use C API from your C++ code.
+
+#pragma once
+#include "onnxruntime_c_api.h"
+#include <cstddef>
+#include <array>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <vector>
+#include <unordered_map>
+#include <utility>
+#include <type_traits>
+
+#ifdef ORT_NO_EXCEPTIONS
+#include <iostream>
+#endif
+
+/** \brief All C++ Onnxruntime APIs are defined inside this namespace
+ *
+ */
+namespace Ort {
+
+/** \brief All C++ methods that can fail will throw an exception of this type
+ *
+ * If <tt>ORT_NO_EXCEPTIONS</tt> is defined, then any error will result in a call to abort()
+ */
+struct Exception : std::exception {
+ Exception(std::string&& string, OrtErrorCode code) : message_{std::move(string)}, code_{code} {}
+
+ OrtErrorCode GetOrtErrorCode() const { return code_; }
+ const char* what() const noexcept override { return message_.c_str(); }
+
+ private:
+ std::string message_;
+ OrtErrorCode code_;
+};
+
+#ifdef ORT_NO_EXCEPTIONS
+// The #ifndef is for the very special case where the user of this library wants to define their own way of handling errors.
+// NOTE: This header expects control flow to not continue after calling ORT_CXX_API_THROW
+#ifndef ORT_CXX_API_THROW
+#define ORT_CXX_API_THROW(string, code) \
+ do { \
+ std::cerr << Ort::Exception(string, code) \
+ .what() \
+ << std::endl; \
+ abort(); \
+ } while (false)
+#endif
+#else
+#define ORT_CXX_API_THROW(string, code) \
+ throw Ort::Exception(string, code)
+#endif
+
+// This is used internally by the C++ API. This class holds the global variable that points to the OrtApi,
+// it's in a template so that we can define a global variable in a header and make
+// it transparent to the users of the API.
+template <typename T>
+struct Global {
+ static const OrtApi* api_;
+};
+
+// If macro ORT_API_MANUAL_INIT is defined, no static initialization will be performed. Instead, user must call InitApi() before using it.
+template <typename T>
+#ifdef ORT_API_MANUAL_INIT
+const OrtApi* Global<T>::api_{};
+inline void InitApi() { Global<void>::api_ = OrtGetApiBase()->GetApi(ORT_API_VERSION); }
+
+// Used by custom operator libraries that are not linked to onnxruntime. Sets the global API object, which is
+// required by C++ APIs.
+//
+// Example mycustomop.cc:
+//
+// #define ORT_API_MANUAL_INIT
+// #include <onnxruntime_cxx_api.h>
+// #undef ORT_API_MANUAL_INIT
+//
+// OrtStatus* ORT_API_CALL RegisterCustomOps(OrtSessionOptions* options, const OrtApiBase* api_base) {
+// Ort::InitApi(api_base->GetApi(ORT_API_VERSION));
+// // ...
+// }
+//
+inline void InitApi(const OrtApi* api) { Global<void>::api_ = api; }
+#else
+#if defined(_MSC_VER) && !defined(__clang__)
+#pragma warning(push)
+// "Global initializer calls a non-constexpr function." Therefore you can't use ORT APIs in the other global initializers.
+// Please define ORT_API_MANUAL_INIT if it conerns you.
+#pragma warning(disable : 26426)
+#endif
+const OrtApi* Global<T>::api_ = OrtGetApiBase()->GetApi(ORT_API_VERSION);
+#if defined(_MSC_VER) && !defined(__clang__)
+#pragma warning(pop)
+#endif
+#endif
+
+/// This returns a reference to the OrtApi interface in use
+inline const OrtApi& GetApi() { return *Global<void>::api_; }
+
+/// <summary>
+/// This is a C++ wrapper for OrtApi::GetAvailableProviders() and
+/// returns a vector of strings representing the available execution providers.
+/// </summary>
+/// <returns>vector of strings</returns>
+std::vector<std::string> GetAvailableProviders();
+
+/** \brief IEEE 754 half-precision floating point data type
+ * \details It is necessary for type dispatching to make use of C++ API
+ * The type is implicitly convertible to/from uint16_t.
+ * The size of the structure should align with uint16_t and one can freely cast
+ * uint16_t buffers to/from Ort::Float16_t to feed and retrieve data.
+ *
+ * Generally, you can feed any of your types as float16/blfoat16 data to create a tensor
+ * on top of it, providing it can form a continuous buffer with 16-bit elements with no padding.
+ * And you can also feed a array of uint16_t elements directly. For example,
+ *
+ * \code{.unparsed}
+ * uint16_t values[] = { 15360, 16384, 16896, 17408, 17664};
+ * constexpr size_t values_length = sizeof(values) / sizeof(values[0]);
+ * std::vector<int64_t> dims = {values_length}; // one dimensional example
+ * Ort::MemoryInfo info("Cpu", OrtDeviceAllocator, 0, OrtMemTypeDefault);
+ * // Note we are passing bytes count in this api, not number of elements -> sizeof(values)
+ * auto float16_tensor = Ort::Value::CreateTensor(info, values, sizeof(values),
+ * dims.data(), dims.size(), ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16);
+ * \endcode
+ *
+ * Here is another example, a little bit more elaborate. Let's assume that you use your own float16 type and you want to use
+ * a templated version of the API above so the type is automatically set based on your type. You will need to supply an extra
+ * template specialization.
+ *
+ * \code{.unparsed}
+ * namespace yours { struct half {}; } // assume this is your type, define this:
+ * namespace Ort {
+ * template<>
+ * struct TypeToTensorType<yours::half> { static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16; };
+ * } //namespace Ort
+ *
+ * std::vector<yours::half> values;
+ * std::vector<int64_t> dims = {values.size()}; // one dimensional example
+ * Ort::MemoryInfo info("Cpu", OrtDeviceAllocator, 0, OrtMemTypeDefault);
+ * // Here we are passing element count -> values.size()
+ * auto float16_tensor = Ort::Value::CreateTensor<yours::half>(info, values.data(), values.size(), dims.data(), dims.size());
+ *
+ * \endcode
+ */
+struct Float16_t {
+ uint16_t value;
+ constexpr Float16_t() noexcept : value(0) {}
+ constexpr Float16_t(uint16_t v) noexcept : value(v) {}
+ constexpr operator uint16_t() const noexcept { return value; }
+ constexpr bool operator==(const Float16_t& rhs) const noexcept { return value == rhs.value; };
+ constexpr bool operator!=(const Float16_t& rhs) const noexcept { return value != rhs.value; };
+};
+
+static_assert(sizeof(Float16_t) == sizeof(uint16_t), "Sizes must match");
+
+/** \brief bfloat16 (Brain Floating Point) data type
+ * \details It is necessary for type dispatching to make use of C++ API
+ * The type is implicitly convertible to/from uint16_t.
+ * The size of the structure should align with uint16_t and one can freely cast
+ * uint16_t buffers to/from Ort::BFloat16_t to feed and retrieve data.
+ *
+ * See also code examples for Float16_t above.
+ */
+struct BFloat16_t {
+ uint16_t value;
+ constexpr BFloat16_t() noexcept : value(0) {}
+ constexpr BFloat16_t(uint16_t v) noexcept : value(v) {}
+ constexpr operator uint16_t() const noexcept { return value; }
+ constexpr bool operator==(const BFloat16_t& rhs) const noexcept { return value == rhs.value; };
+ constexpr bool operator!=(const BFloat16_t& rhs) const noexcept { return value != rhs.value; };
+};
+
+static_assert(sizeof(BFloat16_t) == sizeof(uint16_t), "Sizes must match");
+
+namespace detail {
+// This is used internally by the C++ API. This macro is to make it easy to generate overloaded methods for all of the various OrtRelease* functions for every Ort* type
+// This can't be done in the C API since C doesn't have function overloading.
+#define ORT_DEFINE_RELEASE(NAME) \
+ inline void OrtRelease(Ort##NAME* ptr) { GetApi().Release##NAME(ptr); }
+
+ORT_DEFINE_RELEASE(Allocator);
+ORT_DEFINE_RELEASE(MemoryInfo);
+ORT_DEFINE_RELEASE(CustomOpDomain);
+ORT_DEFINE_RELEASE(ThreadingOptions);
+ORT_DEFINE_RELEASE(Env);
+ORT_DEFINE_RELEASE(RunOptions);
+ORT_DEFINE_RELEASE(Session);
+ORT_DEFINE_RELEASE(SessionOptions);
+ORT_DEFINE_RELEASE(TensorTypeAndShapeInfo);
+ORT_DEFINE_RELEASE(SequenceTypeInfo);
+ORT_DEFINE_RELEASE(MapTypeInfo);
+ORT_DEFINE_RELEASE(TypeInfo);
+ORT_DEFINE_RELEASE(Value);
+ORT_DEFINE_RELEASE(ModelMetadata);
+ORT_DEFINE_RELEASE(IoBinding);
+ORT_DEFINE_RELEASE(ArenaCfg);
+ORT_DEFINE_RELEASE(Status);
+ORT_DEFINE_RELEASE(OpAttr);
+ORT_DEFINE_RELEASE(Op);
+ORT_DEFINE_RELEASE(KernelInfo);
+
+#undef ORT_DEFINE_RELEASE
+
+/** \brief This is a tagging template type. Use it with Base<T> to indicate that the C++ interface object
+ * has no ownership of the underlying C object.
+ */
+template <typename T>
+struct Unowned {
+ using Type = T;
+};
+
+/** \brief Used internally by the C++ API. C++ wrapper types inherit from this.
+ * This is a zero cost abstraction to wrap the C API objects and delete them on destruction.
+ *
+ * All of the C++ classes
+ * a) serve as containers for pointers to objects that are created by the underlying C API.
+ * Their size is just a pointer size, no need to dynamically allocate them. Use them by value.
+ * b) Each of struct XXXX, XXX instances function as smart pointers to the underlying C API objects.
+ * they would release objects owned automatically when going out of scope, they are move-only.
+ * c) ConstXXXX and UnownedXXX structs function as non-owning, copyable containers for the above pointers.
+ * ConstXXXX allow calling const interfaces only. They give access to objects that are owned by somebody else
+ * such as Onnxruntime or instances of XXXX classes.
+ * d) serve convenient interfaces that return C++ objects and further enhance exception and type safety so they can be used
+ * in C++ code.
+ *
+ */
+
+/// <summary>
+/// This is a non-const pointer holder that is move-only. Disposes of the pointer on destruction.
+/// </summary>
+template <typename T>
+struct Base {
+ using contained_type = T;
+
+ constexpr Base() = default;
+ constexpr explicit Base(contained_type* p) noexcept : p_{p} {}
+ ~Base() { OrtRelease(p_); }
+
+ Base(const Base&) = delete;
+ Base& operator=(const Base&) = delete;
+
+ Base(Base&& v) noexcept : p_{v.p_} { v.p_ = nullptr; }
+ Base& operator=(Base&& v) noexcept {
+ OrtRelease(p_);
+ p_ = v.release();
+ return *this;
+ }
+
+ constexpr operator contained_type*() const noexcept { return p_; }
+
+ /// \brief Relinquishes ownership of the contained C object pointer
+ /// The underlying object is not destroyed
+ contained_type* release() {
+ T* p = p_;
+ p_ = nullptr;
+ return p;
+ }
+
+ protected:
+ contained_type* p_{};
+};
+
+// Undefined. For const types use Base<Unowned<const T>>
+template <typename T>
+struct Base<const T>;
+
+/// <summary>
+/// Covers unowned pointers owned by either the ORT
+/// or some other instance of CPP wrappers.
+/// Used for ConstXXX and UnownedXXXX types that are copyable.
+/// Also convenient to wrap raw OrtXX pointers .
+/// </summary>
+/// <typeparam name="T"></typeparam>
+template <typename T>
+struct Base<Unowned<T>> {
+ using contained_type = typename Unowned<T>::Type;
+
+ constexpr Base() = default;
+ constexpr explicit Base(contained_type* p) noexcept : p_{p} {}
+
+ ~Base() = default;
+
+ Base(const Base&) = default;
+ Base& operator=(const Base&) = default;
+
+ Base(Base&& v) noexcept : p_{v.p_} { v.p_ = nullptr; }
+ Base& operator=(Base&& v) noexcept {
+ p_ = nullptr;
+ std::swap(p_, v.p_);
+ return *this;
+ }
+
+ constexpr operator contained_type*() const noexcept { return p_; }
+
+ protected:
+ contained_type* p_{};
+};
+
+// Light functor to release memory with OrtAllocator
+struct AllocatedFree {
+ OrtAllocator* allocator_;
+ explicit AllocatedFree(OrtAllocator* allocator)
+ : allocator_(allocator) {}
+ void operator()(void* ptr) const {
+ if (ptr) allocator_->Free(allocator_, ptr);
+ }
+};
+
+} // namespace detail
+
+struct AllocatorWithDefaultOptions;
+struct Env;
+struct TypeInfo;
+struct Value;
+struct ModelMetadata;
+
+/** \brief unique_ptr typedef used to own strings allocated by OrtAllocators
+ * and release them at the end of the scope. The lifespan of the given allocator
+ * must eclipse the lifespan of AllocatedStringPtr instance
+ */
+using AllocatedStringPtr = std::unique_ptr<char, detail::AllocatedFree>;
+
+/** \brief The Status that holds ownership of OrtStatus received from C API
+ * Use it to safely destroy OrtStatus* returned from the C API. Use appropriate
+ * constructors to construct an instance of a Status object from exceptions.
+ */
+struct Status : detail::Base<OrtStatus> {
+ explicit Status(std::nullptr_t) {} ///< Create an empty object, must be assigned a valid one to be used
+ explicit Status(OrtStatus* status); ///< Takes ownership of OrtStatus instance returned from the C API. Must be non-null
+ explicit Status(const Exception&); ///< Creates status instance out of exception
+ explicit Status(const std::exception&); ///< Creates status instance out of exception
+ std::string GetErrorMessage() const;
+ OrtErrorCode GetErrorCode() const;
+};
+
+/** \brief The ThreadingOptions
+ *
+ * The ThreadingOptions used for set global threadpools' options of The Env.
+ */
+struct ThreadingOptions : detail::Base<OrtThreadingOptions> {
+ /// \brief Wraps OrtApi::CreateThreadingOptions
+ ThreadingOptions();
+
+ /// \brief Wraps OrtApi::SetGlobalIntraOpNumThreads
+ ThreadingOptions& SetGlobalIntraOpNumThreads(int intra_op_num_threads);
+
+ /// \brief Wraps OrtApi::SetGlobalInterOpNumThreads
+ ThreadingOptions& SetGlobalInterOpNumThreads(int inter_op_num_threads);
+
+ /// \brief Wraps OrtApi::SetGlobalSpinControl
+ ThreadingOptions& SetGlobalSpinControl(int allow_spinning);
+
+ /// \brief Wraps OrtApi::SetGlobalDenormalAsZero
+ ThreadingOptions& SetGlobalDenormalAsZero();
+
+ /// \brief Wraps OrtApi::SetGlobalCustomCreateThreadFn
+ ThreadingOptions& SetGlobalCustomCreateThreadFn(OrtCustomCreateThreadFn ort_custom_create_thread_fn);
+
+ /// \brief Wraps OrtApi::SetGlobalCustomThreadCreationOptions
+ ThreadingOptions& SetGlobalCustomThreadCreationOptions(void* ort_custom_thread_creation_options);
+
+ /// \brief Wraps OrtApi::SetGlobalCustomJoinThreadFn
+ ThreadingOptions& SetGlobalCustomJoinThreadFn(OrtCustomJoinThreadFn ort_custom_join_thread_fn);
+};
+
+/** \brief The Env (Environment)
+ *
+ * The Env holds the logging state used by all other objects.
+ * <b>Note:</b> One Env must be created before using any other Onnxruntime functionality
+ */
+struct Env : detail::Base<OrtEnv> {
+ explicit Env(std::nullptr_t) {} ///< Create an empty Env object, must be assigned a valid one to be used
+
+ /// \brief Wraps OrtApi::CreateEnv
+ Env(OrtLoggingLevel logging_level = ORT_LOGGING_LEVEL_WARNING, _In_ const char* logid = "");
+
+ /// \brief Wraps OrtApi::CreateEnvWithCustomLogger
+ Env(OrtLoggingLevel logging_level, const char* logid, OrtLoggingFunction logging_function, void* logger_param);
+
+ /// \brief Wraps OrtApi::CreateEnvWithGlobalThreadPools
+ Env(const OrtThreadingOptions* tp_options, OrtLoggingLevel logging_level = ORT_LOGGING_LEVEL_WARNING, _In_ const char* logid = "");
+
+ /// \brief Wraps OrtApi::CreateEnvWithCustomLoggerAndGlobalThreadPools
+ Env(const OrtThreadingOptions* tp_options, OrtLoggingFunction logging_function, void* logger_param,
+ OrtLoggingLevel logging_level = ORT_LOGGING_LEVEL_WARNING, _In_ const char* logid = "");
+
+ /// \brief C Interop Helper
+ explicit Env(OrtEnv* p) : Base<OrtEnv>{p} {}
+
+ Env& EnableTelemetryEvents(); ///< Wraps OrtApi::EnableTelemetryEvents
+ Env& DisableTelemetryEvents(); ///< Wraps OrtApi::DisableTelemetryEvents
+
+ Env& UpdateEnvWithCustomLogLevel(OrtLoggingLevel log_severity_level); ///< Wraps OrtApi::UpdateEnvWithCustomLogLevel
+
+ Env& CreateAndRegisterAllocator(const OrtMemoryInfo* mem_info, const OrtArenaCfg* arena_cfg); ///< Wraps OrtApi::CreateAndRegisterAllocator
+};
+
+/** \brief Custom Op Domain
+ *
+ */
+struct CustomOpDomain : detail::Base<OrtCustomOpDomain> {
+ explicit CustomOpDomain(std::nullptr_t) {} ///< Create an empty CustomOpDomain object, must be assigned a valid one to be used
+
+ /// \brief Wraps OrtApi::CreateCustomOpDomain
+ explicit CustomOpDomain(const char* domain);
+
+ // This does not take ownership of the op, simply registers it.
+ void Add(const OrtCustomOp* op); ///< Wraps CustomOpDomain_Add
+};
+
+/** \brief RunOptions
+ *
+ */
+struct RunOptions : detail::Base<OrtRunOptions> {
+ explicit RunOptions(std::nullptr_t) {} ///< Create an empty RunOptions object, must be assigned a valid one to be used
+ RunOptions(); ///< Wraps OrtApi::CreateRunOptions
+
+ RunOptions& SetRunLogVerbosityLevel(int); ///< Wraps OrtApi::RunOptionsSetRunLogVerbosityLevel
+ int GetRunLogVerbosityLevel() const; ///< Wraps OrtApi::RunOptionsGetRunLogVerbosityLevel
+
+ RunOptions& SetRunLogSeverityLevel(int); ///< Wraps OrtApi::RunOptionsSetRunLogSeverityLevel
+ int GetRunLogSeverityLevel() const; ///< Wraps OrtApi::RunOptionsGetRunLogSeverityLevel
+
+ RunOptions& SetRunTag(const char* run_tag); ///< wraps OrtApi::RunOptionsSetRunTag
+ const char* GetRunTag() const; ///< Wraps OrtApi::RunOptionsGetRunTag
+
+ RunOptions& AddConfigEntry(const char* config_key, const char* config_value); ///< Wraps OrtApi::AddRunConfigEntry
+
+ /** \brief Terminates all currently executing Session::Run calls that were made using this RunOptions instance
+ *
+ * If a currently executing session needs to be force terminated, this can be called from another thread to force it to fail with an error
+ * Wraps OrtApi::RunOptionsSetTerminate
+ */
+ RunOptions& SetTerminate();
+
+ /** \brief Clears the terminate flag so this RunOptions instance can be used in a new Session::Run call without it instantly terminating
+ *
+ * Wraps OrtApi::RunOptionsUnsetTerminate
+ */
+ RunOptions& UnsetTerminate();
+};
+
+
+namespace detail {
+// Utility function that returns a SessionOption config entry key for a specific custom operator.
+// Ex: custom_op.[custom_op_name].[config]
+std::string MakeCustomOpConfigEntryKey(const char* custom_op_name, const char* config);
+} // namespace detail
+
+/// <summary>
+/// Class that represents session configuration entries for one or more custom operators.
+///
+/// Example:
+/// Ort::CustomOpConfigs op_configs;
+/// op_configs.AddConfig("my_custom_op", "device_type", "CPU");
+///
+/// Passed to Ort::SessionOptions::RegisterCustomOpsLibrary.
+/// </summary>
+struct CustomOpConfigs {
+ CustomOpConfigs() = default;
+ ~CustomOpConfigs() = default;
+ CustomOpConfigs(const CustomOpConfigs&) = default;
+ CustomOpConfigs& operator=(const CustomOpConfigs&) = default;
+ CustomOpConfigs(CustomOpConfigs&& o) = default;
+ CustomOpConfigs& operator=(CustomOpConfigs&& o) = default;
+
+ /** \brief Adds a session configuration entry/value for a specific custom operator.
+ *
+ * \param custom_op_name The name of the custom operator for which to add a configuration entry.
+ * Must match the name returned by the CustomOp's GetName() method.
+ * \param config_key The name of the configuration entry.
+ * \param config_value The value of the configuration entry.
+ * \return A reference to this object to enable call chaining.
+ */
+ CustomOpConfigs& AddConfig(const char* custom_op_name, const char* config_key, const char* config_value);
+
+ /** \brief Returns a flattened map of custom operator configuration entries and their values.
+ *
+ * The keys has been flattened to include both the custom operator name and the configuration entry key name.
+ * For example, a prior call to AddConfig("my_op", "key", "value") corresponds to the flattened key/value pair
+ * {"my_op.key", "value"}.
+ *
+ * \return An unordered map of flattened configurations.
+ */
+ const std::unordered_map<std::string, std::string>& GetFlattenedConfigs() const;
+
+ private:
+ std::unordered_map<std::string, std::string> flat_configs_;
+};
+
+/** \brief Options object used when creating a new Session object
+ *
+ * Wraps ::OrtSessionOptions object and methods
+ */
+
+struct SessionOptions;
+
+namespace detail {
+// we separate const-only methods because passing const ptr to non-const methods
+// is only discovered when inline methods are compiled which is counter-intuitive
+template <typename T>
+struct ConstSessionOptionsImpl : Base<T> {
+ using B = Base<T>;
+ using B::B;
+
+ SessionOptions Clone() const; ///< Creates and returns a copy of this SessionOptions object. Wraps OrtApi::CloneSessionOptions
+
+ std::string GetConfigEntry(const char* config_key) const; ///< Wraps OrtApi::GetSessionConfigEntry
+ bool HasConfigEntry(const char* config_key) const; ///< Wraps OrtApi::HasSessionConfigEntry
+ std::string GetConfigEntryOrDefault(const char* config_key, const std::string& def);
+};
+
+template <typename T>
+struct SessionOptionsImpl : ConstSessionOptionsImpl<T> {
+ using B = ConstSessionOptionsImpl<T>;
+ using B::B;
+
+ SessionOptionsImpl& SetIntraOpNumThreads(int intra_op_num_threads); ///< Wraps OrtApi::SetIntraOpNumThreads
+ SessionOptionsImpl& SetInterOpNumThreads(int inter_op_num_threads); ///< Wraps OrtApi::SetInterOpNumThreads
+ SessionOptionsImpl& SetGraphOptimizationLevel(GraphOptimizationLevel graph_optimization_level); ///< Wraps OrtApi::SetSessionGraphOptimizationLevel
+
+ SessionOptionsImpl& EnableCpuMemArena(); ///< Wraps OrtApi::EnableCpuMemArena
+ SessionOptionsImpl& DisableCpuMemArena(); ///< Wraps OrtApi::DisableCpuMemArena
+
+ SessionOptionsImpl& SetOptimizedModelFilePath(const ORTCHAR_T* optimized_model_file); ///< Wraps OrtApi::SetOptimizedModelFilePath
+
+ SessionOptionsImpl& EnableProfiling(const ORTCHAR_T* profile_file_prefix); ///< Wraps OrtApi::EnableProfiling
+ SessionOptionsImpl& DisableProfiling(); ///< Wraps OrtApi::DisableProfiling
+
+ SessionOptionsImpl& EnableOrtCustomOps(); ///< Wraps OrtApi::EnableOrtCustomOps
+
+ SessionOptionsImpl& EnableMemPattern(); ///< Wraps OrtApi::EnableMemPattern
+ SessionOptionsImpl& DisableMemPattern(); ///< Wraps OrtApi::DisableMemPattern
+
+ SessionOptionsImpl& SetExecutionMode(ExecutionMode execution_mode); ///< Wraps OrtApi::SetSessionExecutionMode
+
+ SessionOptionsImpl& SetLogId(const char* logid); ///< Wraps OrtApi::SetSessionLogId
+ SessionOptionsImpl& SetLogSeverityLevel(int level); ///< Wraps OrtApi::SetSessionLogSeverityLevel
+
+ SessionOptionsImpl& Add(OrtCustomOpDomain* custom_op_domain); ///< Wraps OrtApi::AddCustomOpDomain
+
+ SessionOptionsImpl& DisablePerSessionThreads(); ///< Wraps OrtApi::DisablePerSessionThreads
+
+ SessionOptionsImpl& AddConfigEntry(const char* config_key, const char* config_value); ///< Wraps OrtApi::AddSessionConfigEntry
+
+ SessionOptionsImpl& AddInitializer(const char* name, const OrtValue* ort_val); ///< Wraps OrtApi::AddInitializer
+ SessionOptionsImpl& AddExternalInitializers(const std::vector<std::string>& names, const std::vector<Value>& ort_values); ///< Wraps OrtApi::AddExternalInitializers
+
+ SessionOptionsImpl& AppendExecutionProvider_CUDA(const OrtCUDAProviderOptions& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_CUDA
+ SessionOptionsImpl& AppendExecutionProvider_CUDA_V2(const OrtCUDAProviderOptionsV2& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_CUDA_V2
+ SessionOptionsImpl& AppendExecutionProvider_ROCM(const OrtROCMProviderOptions& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_ROCM
+ SessionOptionsImpl& AppendExecutionProvider_OpenVINO(const OrtOpenVINOProviderOptions& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_OpenVINO
+ SessionOptionsImpl& AppendExecutionProvider_TensorRT(const OrtTensorRTProviderOptions& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_TensorRT
+ SessionOptionsImpl& AppendExecutionProvider_TensorRT_V2(const OrtTensorRTProviderOptionsV2& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_TensorRT
+ SessionOptionsImpl& AppendExecutionProvider_MIGraphX(const OrtMIGraphXProviderOptions& provider_options); ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_MIGraphX
+ ///< Wraps OrtApi::SessionOptionsAppendExecutionProvider_CANN
+ SessionOptionsImpl& AppendExecutionProvider_CANN(const OrtCANNProviderOptions& provider_options);
+ /// Wraps OrtApi::SessionOptionsAppendExecutionProvider. Currently supports SNPE and XNNPACK.
+ SessionOptionsImpl& AppendExecutionProvider(const std::string& provider_name,
+ const std::unordered_map<std::string, std::string>& provider_options = {});
+
+ SessionOptionsImpl& SetCustomCreateThreadFn(OrtCustomCreateThreadFn ort_custom_create_thread_fn); ///< Wraps OrtApi::SessionOptionsSetCustomCreateThreadFn
+ SessionOptionsImpl& SetCustomThreadCreationOptions(void* ort_custom_thread_creation_options); ///< Wraps OrtApi::SessionOptionsSetCustomThreadCreationOptions
+ SessionOptionsImpl& SetCustomJoinThreadFn(OrtCustomJoinThreadFn ort_custom_join_thread_fn); ///< Wraps OrtApi::SessionOptionsSetCustomJoinThreadFn
+
+ ///< Registers the custom operator from the specified shared library via OrtApi::RegisterCustomOpsLibrary_V2.
+ ///< The custom operator configurations are optional. If provided, custom operator configs are set via
+ ///< OrtApi::AddSessionConfigEntry.
+ SessionOptionsImpl& RegisterCustomOpsLibrary(const ORTCHAR_T* library_name, const CustomOpConfigs& custom_op_configs = {});
+
+ SessionOptionsImpl& RegisterCustomOpsUsingFunction(const char* function_name); ///< Wraps OrtApi::RegisterCustomOpsUsingFunction
+};
+} // namespace detail
+
+using UnownedSessionOptions = detail::SessionOptionsImpl<detail::Unowned<OrtSessionOptions>>;
+using ConstSessionOptions = detail::ConstSessionOptionsImpl<detail::Unowned<const OrtSessionOptions>>;
+
+/** \brief Wrapper around ::OrtSessionOptions
+ *
+ */
+struct SessionOptions : detail::SessionOptionsImpl<OrtSessionOptions> {
+ explicit SessionOptions(std::nullptr_t) {} ///< Create an empty SessionOptions object, must be assigned a valid one to be used
+ SessionOptions(); ///< Wraps OrtApi::CreateSessionOptions
+ explicit SessionOptions(OrtSessionOptions* p) : SessionOptionsImpl<OrtSessionOptions>{p} {} ///< Used for interop with the C API
+ UnownedSessionOptions GetUnowned() const { return UnownedSessionOptions{this->p_}; }
+ ConstSessionOptions GetConst() const { return ConstSessionOptions{this->p_}; }
+};
+
+/** \brief Wrapper around ::OrtModelMetadata
+ *
+ */
+struct ModelMetadata : detail::Base<OrtModelMetadata> {
+ explicit ModelMetadata(std::nullptr_t) {} ///< Create an empty ModelMetadata object, must be assigned a valid one to be used
+ explicit ModelMetadata(OrtModelMetadata* p) : Base<OrtModelMetadata>{p} {} ///< Used for interop with the C API
+
+ /** \brief Returns a copy of the producer name.
+ *
+ * \param allocator to allocate memory for the copy of the name returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr GetProducerNameAllocated(OrtAllocator* allocator) const; ///< Wraps OrtApi::ModelMetadataGetProducerName
+
+ /** \brief Returns a copy of the graph name.
+ *
+ * \param allocator to allocate memory for the copy of the name returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr GetGraphNameAllocated(OrtAllocator* allocator) const; ///< Wraps OrtApi::ModelMetadataGetGraphName
+
+ /** \brief Returns a copy of the domain name.
+ *
+ * \param allocator to allocate memory for the copy of the name returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr GetDomainAllocated(OrtAllocator* allocator) const; ///< Wraps OrtApi::ModelMetadataGetDomain
+
+ /** \brief Returns a copy of the description.
+ *
+ * \param allocator to allocate memory for the copy of the string returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr GetDescriptionAllocated(OrtAllocator* allocator) const; ///< Wraps OrtApi::ModelMetadataGetDescription
+
+ /** \brief Returns a copy of the graph description.
+ *
+ * \param allocator to allocate memory for the copy of the string returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr GetGraphDescriptionAllocated(OrtAllocator* allocator) const; ///< Wraps OrtApi::ModelMetadataGetGraphDescription
+
+ /** \brief Returns a vector of copies of the custom metadata keys.
+ *
+ * \param allocator to allocate memory for the copy of the string returned
+ * \return a instance std::vector of smart pointers that would deallocate the buffers when out of scope.
+ * The OrtAllocator instance must be valid at the point of memory release.
+ */
+ std::vector<AllocatedStringPtr> GetCustomMetadataMapKeysAllocated(OrtAllocator* allocator) const; ///< Wraps OrtApi::ModelMetadataGetCustomMetadataMapKeys
+
+ /** \brief Looks up a value by a key in the Custom Metadata map
+ *
+ * \param key zero terminated string key to lookup
+ * \param allocator to allocate memory for the copy of the string returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * maybe nullptr if key is not found.
+ *
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr LookupCustomMetadataMapAllocated(const char* key, OrtAllocator* allocator) const; ///< Wraps OrtApi::ModelMetadataLookupCustomMetadataMap
+
+ int64_t GetVersion() const; ///< Wraps OrtApi::ModelMetadataGetVersion
+};
+
+struct IoBinding;
+
+namespace detail {
+
+// we separate const-only methods because passing const ptr to non-const methods
+// is only discovered when inline methods are compiled which is counter-intuitive
+template <typename T>
+struct ConstSessionImpl : Base<T> {
+ using B = Base<T>;
+ using B::B;
+
+ size_t GetInputCount() const; ///< Returns the number of model inputs
+ size_t GetOutputCount() const; ///< Returns the number of model outputs
+ size_t GetOverridableInitializerCount() const; ///< Returns the number of inputs that have defaults that can be overridden
+
+ /** \brief Returns a copy of input name at the specified index.
+ *
+ * \param index must less than the value returned by GetInputCount()
+ * \param allocator to allocate memory for the copy of the name returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr GetInputNameAllocated(size_t index, OrtAllocator* allocator) const;
+
+ /** \brief Returns a copy of output name at then specified index.
+ *
+ * \param index must less than the value returned by GetOutputCount()
+ * \param allocator to allocate memory for the copy of the name returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr GetOutputNameAllocated(size_t index, OrtAllocator* allocator) const;
+
+ /** \brief Returns a copy of the overridable initializer name at then specified index.
+ *
+ * \param index must less than the value returned by GetOverridableInitializerCount()
+ * \param allocator to allocate memory for the copy of the name returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr GetOverridableInitializerNameAllocated(size_t index, OrtAllocator* allocator) const; ///< Wraps OrtApi::SessionGetOverridableInitializerName
+
+ uint64_t GetProfilingStartTimeNs() const; ///< Wraps OrtApi::SessionGetProfilingStartTimeNs
+ ModelMetadata GetModelMetadata() const; ///< Wraps OrtApi::SessionGetModelMetadata
+
+ TypeInfo GetInputTypeInfo(size_t index) const; ///< Wraps OrtApi::SessionGetInputTypeInfo
+ TypeInfo GetOutputTypeInfo(size_t index) const; ///< Wraps OrtApi::SessionGetOutputTypeInfo
+ TypeInfo GetOverridableInitializerTypeInfo(size_t index) const; ///< Wraps OrtApi::SessionGetOverridableInitializerTypeInfo
+};
+
+template <typename T>
+struct SessionImpl : ConstSessionImpl<T> {
+ using B = ConstSessionImpl<T>;
+ using B::B;
+
+ /** \brief Run the model returning results in an Ort allocated vector.
+ *
+ * Wraps OrtApi::Run
+ *
+ * The caller provides a list of inputs and a list of the desired outputs to return.
+ *
+ * See the output logs for more information on warnings/errors that occur while processing the model.
+ * Common errors are.. (TODO)
+ *
+ * \param[in] run_options
+ * \param[in] input_names Array of null terminated strings of length input_count that is the list of input names
+ * \param[in] input_values Array of Value objects of length input_count that is the list of input values
+ * \param[in] input_count Number of inputs (the size of the input_names & input_values arrays)
+ * \param[in] output_names Array of C style strings of length output_count that is the list of output names
+ * \param[in] output_count Number of outputs (the size of the output_names array)
+ * \return A std::vector of Value objects that directly maps to the output_names array (eg. output_name[0] is the first entry of the returned vector)
+ */
+ std::vector<Value> Run(const RunOptions& run_options, const char* const* input_names, const Value* input_values, size_t input_count,
+ const char* const* output_names, size_t output_count);
+
+ /** \brief Run the model returning results in user provided outputs
+ * Same as Run(const RunOptions&, const char* const*, const Value*, size_t,const char* const*, size_t)
+ */
+ void Run(const RunOptions& run_options, const char* const* input_names, const Value* input_values, size_t input_count,
+ const char* const* output_names, Value* output_values, size_t output_count);
+
+ void Run(const RunOptions& run_options, const IoBinding&); ///< Wraps OrtApi::RunWithBinding
+
+ /** \brief End profiling and return a copy of the profiling file name.
+ *
+ * \param allocator to allocate memory for the copy of the string returned
+ * \return a instance of smart pointer that would deallocate the buffer when out of scope.
+ * The OrtAllocator instances must be valid at the point of memory release.
+ */
+ AllocatedStringPtr EndProfilingAllocated(OrtAllocator* allocator); ///< Wraps OrtApi::SessionEndProfiling
+};
+
+} // namespace detail
+
+using ConstSession = detail::ConstSessionImpl<detail::Unowned<const OrtSession>>;
+using UnownedSession = detail::SessionImpl<detail::Unowned<OrtSession>>;
+
+/** \brief Wrapper around ::OrtSession
+ *
+ */
+struct Session : detail::SessionImpl<OrtSession> {
+ explicit Session(std::nullptr_t) {} ///< Create an empty Session object, must be assigned a valid one to be used
+ Session(const Env& env, const ORTCHAR_T* model_path, const SessionOptions& options); ///< Wraps OrtApi::CreateSession
+ Session(const Env& env, const ORTCHAR_T* model_path, const SessionOptions& options,
+ OrtPrepackedWeightsContainer* prepacked_weights_container); ///< Wraps OrtApi::CreateSessionWithPrepackedWeightsContainer
+ Session(const Env& env, const void* model_data, size_t model_data_length, const SessionOptions& options); ///< Wraps OrtApi::CreateSessionFromArray
+ Session(const Env& env, const void* model_data, size_t model_data_length, const SessionOptions& options,
+ OrtPrepackedWeightsContainer* prepacked_weights_container); ///< Wraps OrtApi::CreateSessionFromArrayWithPrepackedWeightsContainer
+
+ ConstSession GetConst() const { return ConstSession{this->p_}; }
+ UnownedSession GetUnowned() const { return UnownedSession{this->p_}; }
+};
+
+namespace detail {
+template <typename T>
+struct MemoryInfoImpl : Base<T> {
+ using B = Base<T>;
+ using B::B;
+
+ std::string GetAllocatorName() const;
+ OrtAllocatorType GetAllocatorType() const;
+ int GetDeviceId() const;
+ OrtMemoryInfoDeviceType GetDeviceType() const;
+ OrtMemType GetMemoryType() const;
+
+ template <typename U>
+ bool operator==(const MemoryInfoImpl<U>& o) const;
+};
+} // namespace detail
+
+// Const object holder that does not own the underlying object
+using ConstMemoryInfo = detail::MemoryInfoImpl<detail::Unowned<const OrtMemoryInfo>>;
+
+/** \brief Wrapper around ::OrtMemoryInfo
+ *
+ */
+struct MemoryInfo : detail::MemoryInfoImpl<OrtMemoryInfo> {
+ static MemoryInfo CreateCpu(OrtAllocatorType type, OrtMemType mem_type1);
+ explicit MemoryInfo(std::nullptr_t) {} ///< No instance is created
+ explicit MemoryInfo(OrtMemoryInfo* p) : MemoryInfoImpl<OrtMemoryInfo>{p} {} ///< Take ownership of a pointer created by C Api
+ MemoryInfo(const char* name, OrtAllocatorType type, int id, OrtMemType mem_type);
+ ConstMemoryInfo GetConst() const { return ConstMemoryInfo{this->p_}; }
+};
+
+namespace detail {
+template <typename T>
+struct TensorTypeAndShapeInfoImpl : Base<T> {
+ using B = Base<T>;
+ using B::B;
+
+ ONNXTensorElementDataType GetElementType() const; ///< Wraps OrtApi::GetTensorElementType
+ size_t GetElementCount() const; ///< Wraps OrtApi::GetTensorShapeElementCount
+
+ size_t GetDimensionsCount() const; ///< Wraps OrtApi::GetDimensionsCount
+
+ /** \deprecated use GetShape() returning std::vector
+ * [[deprecated]]
+ * This interface is unsafe to use
+ */
+ [[deprecated("use GetShape()")]] void GetDimensions(int64_t* values, size_t values_count) const; ///< Wraps OrtApi::GetDimensions
+
+ void GetSymbolicDimensions(const char** values, size_t values_count) const; ///< Wraps OrtApi::GetSymbolicDimensions
+
+ std::vector<int64_t> GetShape() const; ///< Uses GetDimensionsCount & GetDimensions to return a std::vector of the shape
+};
+
+} // namespace detail
+
+using ConstTensorTypeAndShapeInfo = detail::TensorTypeAndShapeInfoImpl<detail::Unowned<const OrtTensorTypeAndShapeInfo>>;
+
+/** \brief Wrapper around ::OrtTensorTypeAndShapeInfo
+ *
+ */
+struct TensorTypeAndShapeInfo : detail::TensorTypeAndShapeInfoImpl<OrtTensorTypeAndShapeInfo> {
+ explicit TensorTypeAndShapeInfo(std::nullptr_t) {} ///< Create an empty TensorTypeAndShapeInfo object, must be assigned a valid one to be used
+ explicit TensorTypeAndShapeInfo(OrtTensorTypeAndShapeInfo* p) : TensorTypeAndShapeInfoImpl{p} {} ///< Used for interop with the C API
+ ConstTensorTypeAndShapeInfo GetConst() const { return ConstTensorTypeAndShapeInfo{this->p_}; }
+};
+
+namespace detail {
+template <typename T>
+struct SequenceTypeInfoImpl : Base<T> {
+ using B = Base<T>;
+ using B::B;
+ TypeInfo GetSequenceElementType() const; ///< Wraps OrtApi::GetSequenceElementType
+};
+
+} // namespace detail
+
+using ConstSequenceTypeInfo = detail::SequenceTypeInfoImpl<detail::Unowned<const OrtSequenceTypeInfo>>;
+
+/** \brief Wrapper around ::OrtSequenceTypeInfo
+ *
+ */
+struct SequenceTypeInfo : detail::SequenceTypeInfoImpl<OrtSequenceTypeInfo> {
+ explicit SequenceTypeInfo(std::nullptr_t) {} ///< Create an empty SequenceTypeInfo object, must be assigned a valid one to be used
+ explicit SequenceTypeInfo(OrtSequenceTypeInfo* p) : SequenceTypeInfoImpl<OrtSequenceTypeInfo>{p} {} ///< Used for interop with the C API
+ ConstSequenceTypeInfo GetConst() const { return ConstSequenceTypeInfo{this->p_}; }
+};
+
+namespace detail {
+template <typename T>
+struct MapTypeInfoImpl : detail::Base<T> {
+ using B = Base<T>;
+ using B::B;
+ ONNXTensorElementDataType GetMapKeyType() const; ///< Wraps OrtApi::GetMapKeyType
+ TypeInfo GetMapValueType() const; ///< Wraps OrtApi::GetMapValueType
+};
+
+} // namespace detail
+
+using ConstMapTypeInfo = detail::MapTypeInfoImpl<detail::Unowned<const OrtMapTypeInfo>>;
+
+/** \brief Wrapper around ::OrtMapTypeInfo
+ *
+ */
+struct MapTypeInfo : detail::MapTypeInfoImpl<OrtMapTypeInfo> {
+ explicit MapTypeInfo(std::nullptr_t) {} ///< Create an empty MapTypeInfo object, must be assigned a valid one to be used
+ explicit MapTypeInfo(OrtMapTypeInfo* p) : MapTypeInfoImpl<OrtMapTypeInfo>{p} {} ///< Used for interop with the C API
+ ConstMapTypeInfo GetConst() const { return ConstMapTypeInfo{this->p_}; }
+};
+
+namespace detail {
+template <typename T>
+struct TypeInfoImpl : detail::Base<T> {
+ using B = Base<T>;
+ using B::B;
+
+ ConstTensorTypeAndShapeInfo GetTensorTypeAndShapeInfo() const; ///< Wraps OrtApi::CastTypeInfoToTensorInfo
+ ConstSequenceTypeInfo GetSequenceTypeInfo() const; ///< Wraps OrtApi::CastTypeInfoToSequenceTypeInfo
+ ConstMapTypeInfo GetMapTypeInfo() const; ///< Wraps OrtApi::CastTypeInfoToMapTypeInfo
+
+ ONNXType GetONNXType() const;
+};
+} // namespace detail
+
+/// <summary>
+/// Contains a constant, unowned OrtTypeInfo that can be copied and passed around by value.
+/// Provides access to const OrtTypeInfo APIs.
+/// </summary>
+using ConstTypeInfo = detail::TypeInfoImpl<detail::Unowned<const OrtTypeInfo>>;
+
+/// <summary>
+/// Type information that may contain either TensorTypeAndShapeInfo or
+/// the information about contained sequence or map depending on the ONNXType.
+/// </summary>
+struct TypeInfo : detail::TypeInfoImpl<OrtTypeInfo> {
+ explicit TypeInfo(std::nullptr_t) {} ///< Create an empty TypeInfo object, must be assigned a valid one to be used
+ explicit TypeInfo(OrtTypeInfo* p) : TypeInfoImpl<OrtTypeInfo>{p} {} ///< C API Interop
+
+ ConstTypeInfo GetConst() const { return ConstTypeInfo{this->p_}; }
+};
+
+namespace detail {
+// This structure is used to feed sparse tensor values
+// information for use with FillSparseTensor<Format>() API
+// if the data type for the sparse tensor values is numeric
+// use data.p_data, otherwise, use data.str pointer to feed
+// values. data.str is an array of const char* that are zero terminated.
+// number of strings in the array must match shape size.
+// For fully sparse tensors use shape {0} and set p_data/str
+// to nullptr.
+struct OrtSparseValuesParam {
+ const int64_t* values_shape;
+ size_t values_shape_len;
+ union {
+ const void* p_data;
+ const char** str;
+ } data;
+};
+
+// Provides a way to pass shape in a single
+// argument
+struct Shape {
+ const int64_t* shape;
+ size_t shape_len;
+};
+
+template <typename T>
+struct ConstValueImpl : Base<T> {
+ using B = Base<T>;
+ using B::B;
+
+ /// <summary>
+ /// Obtains a pointer to a user defined data for experimental purposes
+ /// </summary>
+ template <typename R>
+ void GetOpaqueData(const char* domain, const char* type_name, R&) const; ///< Wraps OrtApi::GetOpaqueValue
+
+ bool IsTensor() const; ///< Returns true if Value is a tensor, false for other types like map/sequence/etc
+ bool HasValue() const; /// < Return true if OrtValue contains data and returns false if the OrtValue is a None
+
+ size_t GetCount() const; // If a non tensor, returns 2 for map and N for sequence, where N is the number of elements
+ Value GetValue(int index, OrtAllocator* allocator) const;
+
+ /// <summary>
+ /// This API returns a full length of string data contained within either a tensor or a sparse Tensor.
+ /// For sparse tensor it returns a full length of stored non-empty strings (values). The API is useful
+ /// for allocating necessary memory and calling GetStringTensorContent().
+ /// </summary>
+ /// <returns>total length of UTF-8 encoded bytes contained. No zero terminators counted.</returns>
+ size_t GetStringTensorDataLength() const;
+
+ /// <summary>
+ /// The API copies all of the UTF-8 encoded string data contained within a tensor or a sparse tensor
+ /// into a supplied buffer. Use GetStringTensorDataLength() to find out the length of the buffer to allocate.
+ /// The user must also allocate offsets buffer with the number of entries equal to that of the contained
+ /// strings.
+ ///
+ /// Strings are always assumed to be on CPU, no X-device copy.
+ /// </summary>
+ /// <param name="buffer">user allocated buffer</param>
+ /// <param name="buffer_length">length in bytes of the allocated buffer</param>
+ /// <param name="offsets">a pointer to the offsets user allocated buffer</param>
+ /// <param name="offsets_count">count of offsets, must be equal to the number of strings contained.
+ /// that can be obtained from the shape of the tensor or from GetSparseTensorValuesTypeAndShapeInfo()
+ /// for sparse tensors</param>
+ void GetStringTensorContent(void* buffer, size_t buffer_length, size_t* offsets, size_t offsets_count) const;
+
+ /// <summary>
+ /// Returns a const typed pointer to the tensor contained data.
+ /// No type checking is performed, the caller must ensure the type matches the tensor type.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <returns>const pointer to data, no copies made</returns>
+ template <typename R>
+ const R* GetTensorData() const; ///< Wraps OrtApi::GetTensorMutableData /// <summary>
+
+ /// <summary>
+ /// Returns a non-typed pointer to a tensor contained data.
+ /// </summary>
+ /// <returns>const pointer to data, no copies made</returns>
+ const void* GetTensorRawData() const;
+
+ /// <summary>
+ /// The API returns type information for data contained in a tensor. For sparse
+ /// tensors it returns type information for contained non-zero values.
+ /// It returns dense shape for sparse tensors.
+ /// </summary>
+ /// <returns>TypeInfo</returns>
+ TypeInfo GetTypeInfo() const;
+
+ /// <summary>
+ /// The API returns type information for data contained in a tensor. For sparse
+ /// tensors it returns type information for contained non-zero values.
+ /// It returns dense shape for sparse tensors.
+ /// </summary>
+ /// <returns>TensorTypeAndShapeInfo</returns>
+ TensorTypeAndShapeInfo GetTensorTypeAndShapeInfo() const;
+
+ /// <summary>
+ /// This API returns information about the memory allocation used to hold data.
+ /// </summary>
+ /// <returns>Non owning instance of MemoryInfo</returns>
+ ConstMemoryInfo GetTensorMemoryInfo() const;
+
+ /// <summary>
+ /// The API copies UTF-8 encoded bytes for the requested string element
+ /// contained within a tensor or a sparse tensor into a provided buffer.
+ /// Use GetStringTensorElementLength() to obtain the length of the buffer to allocate.
+ /// </summary>
+ /// <param name="buffer_length"></param>
+ /// <param name="element_index"></param>
+ /// <param name="buffer"></param>
+ void GetStringTensorElement(size_t buffer_length, size_t element_index, void* buffer) const;
+
+ /// <summary>
+ /// The API returns a byte length of UTF-8 encoded string element
+ /// contained in either a tensor or a spare tensor values.
+ /// </summary>
+ /// <param name="element_index"></param>
+ /// <returns>byte length for the specified string element</returns>
+ size_t GetStringTensorElementLength(size_t element_index) const;
+
+#if !defined(DISABLE_SPARSE_TENSORS)
+ /// <summary>
+ /// The API returns the sparse data format this OrtValue holds in a sparse tensor.
+ /// If the sparse tensor was not fully constructed, i.e. Use*() or Fill*() API were not used
+ /// the value returned is ORT_SPARSE_UNDEFINED.
+ /// </summary>
+ /// <returns>Format enum</returns>
+ OrtSparseFormat GetSparseFormat() const;
+
+ /// <summary>
+ /// The API returns type and shape information for stored non-zero values of the
+ /// sparse tensor. Use GetSparseTensorValues() to obtain values buffer pointer.
+ /// </summary>
+ /// <returns>TensorTypeAndShapeInfo values information</returns>
+ TensorTypeAndShapeInfo GetSparseTensorValuesTypeAndShapeInfo() const;
+
+ /// <summary>
+ /// The API returns type and shape information for the specified indices. Each supported
+ /// indices have their own enum values even if a give format has more than one kind of indices.
+ /// Use GetSparseTensorIndicesData() to obtain pointer to indices buffer.
+ /// </summary>
+ /// <param name="format">enum requested</param>
+ /// <returns>type and shape information</returns>
+ TensorTypeAndShapeInfo GetSparseTensorIndicesTypeShapeInfo(OrtSparseIndicesFormat format) const;
+
+ /// <summary>
+ /// The API retrieves a pointer to the internal indices buffer. The API merely performs
+ /// a convenience data type casting on the return type pointer. Make sure you are requesting
+ /// the right type, use GetSparseTensorIndicesTypeShapeInfo();
+ /// </summary>
+ /// <typeparam name="T">type to cast to</typeparam>
+ /// <param name="indices_format">requested indices kind</param>
+ /// <param name="num_indices">number of indices entries</param>
+ /// <returns>Pinter to the internal sparse tensor buffer containing indices. Do not free this pointer.</returns>
+ template <typename R>
+ const R* GetSparseTensorIndicesData(OrtSparseIndicesFormat indices_format, size_t& num_indices) const;
+
+ /// <summary>
+ /// Returns true if the OrtValue contains a sparse tensor
+ /// </summary>
+ /// <returns></returns>
+ bool IsSparseTensor() const;
+
+ /// <summary>
+ /// The API returns a pointer to an internal buffer of the sparse tensor
+ /// containing non-zero values. The API merely does casting. Make sure you
+ /// are requesting the right data type by calling GetSparseTensorValuesTypeAndShapeInfo()
+ /// first.
+ /// </summary>
+ /// <typeparam name="T">numeric data types only. Use GetStringTensor*() to retrieve strings.</typeparam>
+ /// <returns>a pointer to the internal values buffer. Do not free this pointer.</returns>
+ template <typename R>
+ const R* GetSparseTensorValues() const;
+
+#endif
+};
+
+template <typename T>
+struct ValueImpl : ConstValueImpl<T> {
+ using B = ConstValueImpl<T>;
+ using B::B;
+
+ /// <summary>
+ /// Returns a non-const typed pointer to an OrtValue/Tensor contained buffer
+ /// No type checking is performed, the caller must ensure the type matches the tensor type.
+ /// </summary>
+ /// <returns>non-const pointer to data, no copies made</returns>
+ template <typename R>
+ R* GetTensorMutableData();
+
+ /// <summary>
+ /// Returns a non-typed non-const pointer to a tensor contained data.
+ /// </summary>
+ /// <returns>pointer to data, no copies made</returns>
+ void* GetTensorMutableRawData();
+
+ /// <summary>
+ // Obtain a reference to an element of data at the location specified
+ /// by the vector of dims.
+ /// </summary>
+ /// <typeparam name="R"></typeparam>
+ /// <param name="location">[in] expressed by a vecotr of dimensions offsets</param>
+ /// <returns></returns>
+ template <typename R>
+ R& At(const std::vector<int64_t>& location);
+
+ /// <summary>
+ /// Set all strings at once in a string tensor
+ /// </summary>
+ /// <param name="s">[in] An array of strings. Each string in this array must be null terminated.</param>
+ /// <param name="s_len">[in] Count of strings in s (Must match the size of \p value's tensor shape)</param>
+ void FillStringTensor(const char* const* s, size_t s_len);
+
+ /// <summary>
+ /// Set a single string in a string tensor
+ /// </summary>
+ /// <param name="s">[in] A null terminated UTF-8 encoded string</param>
+ /// <param name="index">[in] Index of the string in the tensor to set</param>
+ void FillStringTensorElement(const char* s, size_t index);
+
+#if !defined(DISABLE_SPARSE_TENSORS)
+ /// <summary>
+ /// Supplies COO format specific indices and marks the contained sparse tensor as being a COO format tensor.
+ /// Values are supplied with a CreateSparseTensor() API. The supplied indices are not copied and the user
+ /// allocated buffers lifespan must eclipse that of the OrtValue.
+ /// The location of the indices is assumed to be the same as specified by OrtMemoryInfo argument at the creation time.
+ /// </summary>
+ /// <param name="indices_data">pointer to the user allocated buffer with indices. Use nullptr for fully sparse tensors.</param>
+ /// <param name="indices_num">number of indices entries. Use 0 for fully sparse tensors</param>
+ void UseCooIndices(int64_t* indices_data, size_t indices_num);
+
+ /// <summary>
+ /// Supplies CSR format specific indices and marks the contained sparse tensor as being a CSR format tensor.
+ /// Values are supplied with a CreateSparseTensor() API. The supplied indices are not copied and the user
+ /// allocated buffers lifespan must eclipse that of the OrtValue.
+ /// The location of the indices is assumed to be the same as specified by OrtMemoryInfo argument at the creation time.
+ /// </summary>
+ /// <param name="inner_data">pointer to the user allocated buffer with inner indices or nullptr for fully sparse tensors</param>
+ /// <param name="inner_num">number of csr inner indices or 0 for fully sparse tensors</param>
+ /// <param name="outer_data">pointer to the user allocated buffer with outer indices or nullptr for fully sparse tensors</param>
+ /// <param name="outer_num">number of csr outer indices or 0 for fully sparse tensors</param>
+ void UseCsrIndices(int64_t* inner_data, size_t inner_num, int64_t* outer_data, size_t outer_num);
+
+ /// <summary>
+ /// Supplies BlockSparse format specific indices and marks the contained sparse tensor as being a BlockSparse format tensor.
+ /// Values are supplied with a CreateSparseTensor() API. The supplied indices are not copied and the user
+ /// allocated buffers lifespan must eclipse that of the OrtValue.
+ /// The location of the indices is assumed to be the same as specified by OrtMemoryInfo argument at the creation time.
+ /// </summary>
+ /// <param name="indices_shape">indices shape or a {0} for fully sparse</param>
+ /// <param name="indices_data">user allocated buffer with indices or nullptr for fully spare tensors</param>
+ void UseBlockSparseIndices(const Shape& indices_shape, int32_t* indices_data);
+
+ /// <summary>
+ /// The API will allocate memory using the allocator instance supplied to the CreateSparseTensor() API
+ /// and copy the values and COO indices into it. If data_mem_info specifies that the data is located
+ /// at difference device than the allocator, a X-device copy will be performed if possible.
+ /// </summary>
+ /// <param name="data_mem_info">specified buffer memory description</param>
+ /// <param name="values_param">values buffer information.</param>
+ /// <param name="indices_data">coo indices buffer or nullptr for fully sparse data</param>
+ /// <param name="indices_num">number of COO indices or 0 for fully sparse data</param>
+ void FillSparseTensorCoo(const OrtMemoryInfo* data_mem_info, const OrtSparseValuesParam& values_param,
+ const int64_t* indices_data, size_t indices_num);
+
+ /// <summary>
+ /// The API will allocate memory using the allocator instance supplied to the CreateSparseTensor() API
+ /// and copy the values and CSR indices into it. If data_mem_info specifies that the data is located
+ /// at difference device than the allocator, a X-device copy will be performed if possible.
+ /// </summary>
+ /// <param name="data_mem_info">specified buffer memory description</param>
+ /// <param name="values">values buffer information</param>
+ /// <param name="inner_indices_data">csr inner indices pointer or nullptr for fully sparse tensors</param>
+ /// <param name="inner_indices_num">number of csr inner indices or 0 for fully sparse tensors</param>
+ /// <param name="outer_indices_data">pointer to csr indices data or nullptr for fully sparse tensors</param>
+ /// <param name="outer_indices_num">number of csr outer indices or 0</param>
+ void FillSparseTensorCsr(const OrtMemoryInfo* data_mem_info,
+ const OrtSparseValuesParam& values,
+ const int64_t* inner_indices_data, size_t inner_indices_num,
+ const int64_t* outer_indices_data, size_t outer_indices_num);
+
+ /// <summary>
+ /// The API will allocate memory using the allocator instance supplied to the CreateSparseTensor() API
+ /// and copy the values and BlockSparse indices into it. If data_mem_info specifies that the data is located
+ /// at difference device than the allocator, a X-device copy will be performed if possible.
+ /// </summary>
+ /// <param name="data_mem_info">specified buffer memory description</param>
+ /// <param name="values">values buffer information</param>
+ /// <param name="indices_shape">indices shape. use {0} for fully sparse tensors</param>
+ /// <param name="indices_data">pointer to indices data or nullptr for fully sparse tensors</param>
+ void FillSparseTensorBlockSparse(const OrtMemoryInfo* data_mem_info,
+ const OrtSparseValuesParam& values,
+ const Shape& indices_shape,
+ const int32_t* indices_data);
+
+#endif
+};
+
+} // namespace detail
+
+using ConstValue = detail::ConstValueImpl<detail::Unowned<const OrtValue>>;
+using UnownedValue = detail::ValueImpl<detail::Unowned<OrtValue>>;
+
+/** \brief Wrapper around ::OrtValue
+ *
+ */
+struct Value : detail::ValueImpl<OrtValue> {
+ using Base = detail::ValueImpl<OrtValue>;
+ using OrtSparseValuesParam = detail::OrtSparseValuesParam;
+ using Shape = detail::Shape;
+
+ explicit Value(std::nullptr_t) {} ///< Create an empty Value object, must be assigned a valid one to be used
+ explicit Value(OrtValue* p) : Base{p} {} ///< Used for interop with the C API
+ Value(Value&&) = default;
+ Value& operator=(Value&&) = default;
+
+ ConstValue GetConst() const { return ConstValue{this->p_}; }
+ UnownedValue GetUnowned() const { return UnownedValue{this->p_}; }
+
+ /** \brief Creates a tensor with a user supplied buffer. Wraps OrtApi::CreateTensorWithDataAsOrtValue.
+ * \tparam T The numeric datatype. This API is not suitable for strings.
+ * \param info Memory description of where the p_data buffer resides (CPU vs GPU etc).
+ * \param p_data Pointer to the data buffer.
+ * \param p_data_element_count The number of elements in the data buffer.
+ * \param shape Pointer to the tensor shape dimensions.
+ * \param shape_len The number of tensor shape dimensions.
+ */
+ template <typename T>
+ static Value CreateTensor(const OrtMemoryInfo* info, T* p_data, size_t p_data_element_count, const int64_t* shape, size_t shape_len);
+
+ /** \brief Creates a tensor with a user supplied buffer. Wraps OrtApi::CreateTensorWithDataAsOrtValue.
+ * \param info Memory description of where the p_data buffer resides (CPU vs GPU etc).
+ * \param p_data Pointer to the data buffer.
+ * \param p_data_byte_count The number of bytes in the data buffer.
+ * \param shape Pointer to the tensor shape dimensions.
+ * \param shape_len The number of tensor shape dimensions.
+ * \param type The data type.
+ */
+ static Value CreateTensor(const OrtMemoryInfo* info, void* p_data, size_t p_data_byte_count, const int64_t* shape, size_t shape_len,
+ ONNXTensorElementDataType type);
+
+ /** \brief Creates a tensor using a supplied OrtAllocator. Wraps OrtApi::CreateTensorAsOrtValue.
+ * \tparam T The numeric datatype. This API is not suitable for strings.
+ * \param allocator The allocator to use.
+ * \param shape Pointer to the tensor shape dimensions.
+ * \param shape_len The number of tensor shape dimensions.
+ */
+ template <typename T>
+ static Value CreateTensor(OrtAllocator* allocator, const int64_t* shape, size_t shape_len);
+
+ /** \brief Creates a tensor using a supplied OrtAllocator. Wraps OrtApi::CreateTensorAsOrtValue.
+ * \param allocator The allocator to use.
+ * \param shape Pointer to the tensor shape dimensions.
+ * \param shape_len The number of tensor shape dimensions.
+ * \param type The data type.
+ */
+ static Value CreateTensor(OrtAllocator* allocator, const int64_t* shape, size_t shape_len, ONNXTensorElementDataType type);
+
+ static Value CreateMap(Value& keys, Value& values); ///< Wraps OrtApi::CreateValue
+ static Value CreateSequence(std::vector<Value>& values); ///< Wraps OrtApi::CreateValue
+
+ template <typename T>
+ static Value CreateOpaque(const char* domain, const char* type_name, const T&); ///< Wraps OrtApi::CreateOpaqueValue
+
+#if !defined(DISABLE_SPARSE_TENSORS)
+ /// <summary>
+ /// This is a simple forwarding method to the other overload that helps deducing
+ /// data type enum value from the type of the buffer.
+ /// </summary>
+ /// <typeparam name="T">numeric datatype. This API is not suitable for strings.</typeparam>
+ /// <param name="info">Memory description where the user buffers reside (CPU vs GPU etc)</param>
+ /// <param name="p_data">pointer to the user supplied buffer, use nullptr for fully sparse tensors</param>
+ /// <param name="dense_shape">a would be dense shape of the tensor</param>
+ /// <param name="values_shape">non zero values shape. Use a single 0 shape for fully sparse tensors.</param>
+ /// <returns></returns>
+ template <typename T>
+ static Value CreateSparseTensor(const OrtMemoryInfo* info, T* p_data, const Shape& dense_shape,
+ const Shape& values_shape);
+
+ /// <summary>
+ /// Creates an OrtValue instance containing SparseTensor. This constructs
+ /// a sparse tensor that makes use of user allocated buffers. It does not make copies
+ /// of the user provided data and does not modify it. The lifespan of user provided buffers should
+ /// eclipse the life span of the resulting OrtValue. This call constructs an instance that only contain
+ /// a pointer to non-zero values. To fully populate the sparse tensor call Use<Format>Indices() API below
+ /// to supply a sparse format specific indices.
+ /// This API is not suitable for string data. Use CreateSparseTensor() with allocator specified so strings
+ /// can be properly copied into the allocated buffer.
+ /// </summary>
+ /// <param name="info">Memory description where the user buffers reside (CPU vs GPU etc)</param>
+ /// <param name="p_data">pointer to the user supplied buffer, use nullptr for fully sparse tensors</param>
+ /// <param name="dense_shape">a would be dense shape of the tensor</param>
+ /// <param name="values_shape">non zero values shape. Use a single 0 shape for fully sparse tensors.</param>
+ /// <param name="type">data type</param>
+ /// <returns>Ort::Value instance containing SparseTensor</returns>
+ static Value CreateSparseTensor(const OrtMemoryInfo* info, void* p_data, const Shape& dense_shape,
+ const Shape& values_shape, ONNXTensorElementDataType type);
+
+ /// <summary>
+ /// This is a simple forwarding method to the below CreateSparseTensor.
+ /// This helps to specify data type enum in terms of C++ data type.
+ /// Use CreateSparseTensor<T>
+ /// </summary>
+ /// <typeparam name="T">numeric data type only. String data enum must be specified explicitly.</typeparam>
+ /// <param name="allocator">allocator to use</param>
+ /// <param name="dense_shape">a would be dense shape of the tensor</param>
+ /// <returns>Ort::Value</returns>
+ template <typename T>
+ static Value CreateSparseTensor(OrtAllocator* allocator, const Shape& dense_shape);
+
+ /// <summary>
+ /// Creates an instance of OrtValue containing sparse tensor. The created instance has no data.
+ /// The data must be supplied by on of the FillSparseTensor<Format>() methods that take both non-zero values
+ /// and indices. The data will be copied into a buffer that would be allocated using the supplied allocator.
+ /// Use this API to create OrtValues that contain sparse tensors with all supported data types including
+ /// strings.
+ /// </summary>
+ /// <param name="allocator">allocator to use. The allocator lifespan must eclipse that of the resulting OrtValue</param>
+ /// <param name="dense_shape">a would be dense shape of the tensor</param>
+ /// <param name="type">data type</param>
+ /// <returns>an instance of Ort::Value</returns>
+ static Value CreateSparseTensor(OrtAllocator* allocator, const Shape& dense_shape, ONNXTensorElementDataType type);
+
+#endif // !defined(DISABLE_SPARSE_TENSORS)
+};
+
+/// <summary>
+/// Represents native memory allocation coming from one of the
+/// OrtAllocators registered with OnnxRuntime.
+/// Use it to wrap an allocation made by an allocator
+/// so it can be automatically released when no longer needed.
+/// </summary>
+struct MemoryAllocation {
+ MemoryAllocation(OrtAllocator* allocator, void* p, size_t size);
+ ~MemoryAllocation();
+ MemoryAllocation(const MemoryAllocation&) = delete;
+ MemoryAllocation& operator=(const MemoryAllocation&) = delete;
+ MemoryAllocation(MemoryAllocation&&) noexcept;
+ MemoryAllocation& operator=(MemoryAllocation&&) noexcept;
+
+ void* get() { return p_; }
+ size_t size() const { return size_; }
+
+ private:
+ OrtAllocator* allocator_;
+ void* p_;
+ size_t size_;
+};
+
+namespace detail {
+template <typename T>
+struct AllocatorImpl : Base<T> {
+ using B = Base<T>;
+ using B::B;
+
+ void* Alloc(size_t size);
+ MemoryAllocation GetAllocation(size_t size);
+ void Free(void* p);
+ ConstMemoryInfo GetInfo() const;
+};
+
+} // namespace detail
+
+/** \brief Wrapper around ::OrtAllocator default instance that is owned by Onnxruntime
+ *
+ */
+struct AllocatorWithDefaultOptions : detail::AllocatorImpl<detail::Unowned<OrtAllocator>> {
+ explicit AllocatorWithDefaultOptions(std::nullptr_t) {} ///< Convenience to create a class member and then replace with an instance
+ AllocatorWithDefaultOptions();
+};
+
+/** \brief Wrapper around ::OrtAllocator
+ *
+ */
+struct Allocator : detail::AllocatorImpl<OrtAllocator> {
+ explicit Allocator(std::nullptr_t) {} ///< Convenience to create a class member and then replace with an instance
+ Allocator(const Session& session, const OrtMemoryInfo*);
+};
+
+using UnownedAllocator = detail::AllocatorImpl<detail::Unowned<OrtAllocator>>;
+
+namespace detail {
+namespace binding_utils {
+// Bring these out of template
+std::vector<std::string> GetOutputNamesHelper(const OrtIoBinding* binding, OrtAllocator*);
+std::vector<Value> GetOutputValuesHelper(const OrtIoBinding* binding, OrtAllocator*);
+} // namespace binding_utils
+
+template <typename T>
+struct ConstIoBindingImpl : Base<T> {
+ using B = Base<T>;
+ using B::B;
+
+ std::vector<std::string> GetOutputNames() const;
+ std::vector<std::string> GetOutputNames(OrtAllocator*) const;
+ std::vector<Value> GetOutputValues() const;
+ std::vector<Value> GetOutputValues(OrtAllocator*) const;
+};
+
+template <typename T>
+struct IoBindingImpl : ConstIoBindingImpl<T> {
+ using B = ConstIoBindingImpl<T>;
+ using B::B;
+
+ void BindInput(const char* name, const Value&);
+ void BindOutput(const char* name, const Value&);
+ void BindOutput(const char* name, const OrtMemoryInfo*);
+ void ClearBoundInputs();
+ void ClearBoundOutputs();
+ void SynchronizeInputs();
+ void SynchronizeOutputs();
+};
+
+} // namespace detail
+
+using ConstIoBinding = detail::ConstIoBindingImpl<detail::Unowned<const OrtIoBinding>>;
+using UnownedIoBinding = detail::IoBindingImpl<detail::Unowned<OrtIoBinding>>;
+
+/** \brief Wrapper around ::OrtIoBinding
+ *
+ */
+struct IoBinding : detail::IoBindingImpl<OrtIoBinding> {
+ explicit IoBinding(std::nullptr_t) {} ///< Create an empty object for convenience. Sometimes, we want to initialize members later.
+ explicit IoBinding(Session& session);
+ ConstIoBinding GetConst() const { return ConstIoBinding{this->p_}; }
+ UnownedIoBinding GetUnowned() const { return UnownedIoBinding{this->p_}; }
+};
+
+/*! \struct Ort::ArenaCfg
+ * \brief it is a structure that represents the configuration of an arena based allocator
+ * \details Please see docs/C_API.md for details
+ */
+struct ArenaCfg : detail::Base<OrtArenaCfg> {
+ explicit ArenaCfg(std::nullptr_t) {} ///< Create an empty ArenaCfg object, must be assigned a valid one to be used
+ /**
+ * Wraps OrtApi::CreateArenaCfg
+ * \param max_mem - use 0 to allow ORT to choose the default
+ * \param arena_extend_strategy - use -1 to allow ORT to choose the default, 0 = kNextPowerOfTwo, 1 = kSameAsRequested
+ * \param initial_chunk_size_bytes - use -1 to allow ORT to choose the default
+ * \param max_dead_bytes_per_chunk - use -1 to allow ORT to choose the default
+ * See docs/C_API.md for details on what the following parameters mean and how to choose these values
+ */
+ ArenaCfg(size_t max_mem, int arena_extend_strategy, int initial_chunk_size_bytes, int max_dead_bytes_per_chunk);
+};
+
+//
+// Custom OPs (only needed to implement custom OPs)
+//
+
+/// <summary>
+/// This struct provides life time management for custom op attribute
+/// </summary>
+struct OpAttr : detail::Base<OrtOpAttr> {
+ OpAttr(const char* name, const void* data, int len, OrtOpAttrType type);
+};
+
+/// <summary>
+/// This class wraps a raw pointer OrtKernelContext* that is being passed
+/// to the custom kernel Compute() method. Use it to safely access context
+/// attributes, input and output parameters with exception safety guarantees.
+/// See usage example in onnxruntime/test/testdata/custom_op_library/custom_op_library.cc
+/// </summary>
+struct KernelContext {
+ explicit KernelContext(OrtKernelContext* context);
+ size_t GetInputCount() const;
+ size_t GetOutputCount() const;
+ ConstValue GetInput(size_t index) const;
+ UnownedValue GetOutput(size_t index, const int64_t* dim_values, size_t dim_count) const;
+ UnownedValue GetOutput(size_t index, const std::vector<int64_t>& dims) const;
+ void* GetGPUComputeStream() const;
+
+ private:
+ OrtKernelContext* ctx_;
+};
+
+struct KernelInfo;
+
+namespace detail {
+namespace attr_utils {
+void GetAttr(const OrtKernelInfo* p, const char* name, float&);
+void GetAttr(const OrtKernelInfo* p, const char* name, int64_t&);
+void GetAttr(const OrtKernelInfo* p, const char* name, std::string&);
+void GetAttrs(const OrtKernelInfo* p, const char* name, std::vector<float>&);
+void GetAttrs(const OrtKernelInfo* p, const char* name, std::vector<int64_t>&);
+} // namespace attr_utils
+
+template <typename T>
+struct KernelInfoImpl : Base<T> {
+ using B = Base<T>;
+ using B::B;
+
+ KernelInfo Copy() const;
+
+ template <typename R> // R is only implemented for float, int64_t, and string
+ R GetAttribute(const char* name) const {
+ R val;
+ attr_utils::GetAttr(this->p_, name, val);
+ return val;
+ }
+
+ template <typename R> // R is only implemented for std::vector<float>, std::vector<int64_t>
+ std::vector<R> GetAttributes(const char* name) const {
+ std::vector<R> result;
+ attr_utils::GetAttrs(this->p_, name, result);
+ return result;
+ }
+
+ Value GetTensorAttribute(const char* name, OrtAllocator* allocator) const;
+
+ size_t GetInputCount() const;
+ size_t GetOutputCount() const;
+
+ std::string GetInputName(size_t index) const;
+ std::string GetOutputName(size_t index) const;
+
+ TypeInfo GetInputTypeInfo(size_t index) const;
+ TypeInfo GetOutputTypeInfo(size_t index) const;
+};
+
+} // namespace detail
+
+using ConstKernelInfo = detail::KernelInfoImpl<detail::Unowned<const OrtKernelInfo>>;
+
+/// <summary>
+/// This struct owns the OrtKernInfo* pointer when a copy is made.
+/// For convenient wrapping of OrtKernelInfo* passed to kernel constructor
+/// and query attributes, warp the pointer with Ort::Unowned<KernelInfo> instance
+/// so it does not destroy the pointer the kernel does not own.
+/// </summary>
+struct KernelInfo : detail::KernelInfoImpl<OrtKernelInfo> {
+ explicit KernelInfo(std::nullptr_t) {} ///< Create an empty instance to initialize later
+ explicit KernelInfo(OrtKernelInfo* info); ///< Take ownership of the instance
+ ConstKernelInfo GetConst() const { return ConstKernelInfo{this->p_}; }
+};
+
+/// <summary>
+/// Create and own custom defined operation.
+/// </summary>
+struct Op : detail::Base<OrtOp> {
+ explicit Op(std::nullptr_t) {} ///< Create an empty Operator object, must be assigned a valid one to be used
+
+ explicit Op(OrtOp*); ///< Take ownership of the OrtOp
+
+ static Op Create(const OrtKernelInfo* info, const char* op_name, const char* domain,
+ int version, const char** type_constraint_names,
+ const ONNXTensorElementDataType* type_constraint_values,
+ size_t type_constraint_count,
+ const OpAttr* attr_values,
+ size_t attr_count,
+ size_t input_count, size_t output_count);
+
+ void Invoke(const OrtKernelContext* context,
+ const Value* input_values,
+ size_t input_count,
+ Value* output_values,
+ size_t output_count);
+
+ // For easier refactoring
+ void Invoke(const OrtKernelContext* context,
+ const OrtValue* const* input_values,
+ size_t input_count,
+ OrtValue* const* output_values,
+ size_t output_count);
+};
+
+/// <summary>
+/// This entire structure is deprecated, but we not marking
+/// it as a whole yet since we want to preserve for the next release.
+/// </summary>
+struct CustomOpApi {
+ CustomOpApi(const OrtApi& api) : api_(api) {}
+
+ /** \deprecated use Ort::Value::GetTensorTypeAndShape()
+ * [[deprecated]]
+ * This interface produces a pointer that must be released. Not exception safe.
+ */
+ [[deprecated("use Ort::Value::GetTensorTypeAndShape()")]] OrtTensorTypeAndShapeInfo* GetTensorTypeAndShape(_In_ const OrtValue* value);
+
+ /** \deprecated use Ort::TensorTypeAndShapeInfo::GetElementCount()
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::TensorTypeAndShapeInfo::GetElementCount()")]] size_t GetTensorShapeElementCount(_In_ const OrtTensorTypeAndShapeInfo* info);
+
+ /** \deprecated use Ort::TensorTypeAndShapeInfo::GetElementType()
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::TensorTypeAndShapeInfo::GetElementType()")]] ONNXTensorElementDataType GetTensorElementType(const OrtTensorTypeAndShapeInfo* info);
+
+ /** \deprecated use Ort::TensorTypeAndShapeInfo::GetDimensionsCount()
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::TensorTypeAndShapeInfo::GetDimensionsCount()")]] size_t GetDimensionsCount(_In_ const OrtTensorTypeAndShapeInfo* info);
+
+ /** \deprecated use Ort::TensorTypeAndShapeInfo::GetShape()
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::TensorTypeAndShapeInfo::GetShape()")]] void GetDimensions(_In_ const OrtTensorTypeAndShapeInfo* info, _Out_ int64_t* dim_values, size_t dim_values_length);
+
+ /** \deprecated
+ * [[deprecated]]
+ * This interface sets dimensions to TensorTypeAndShapeInfo, but has no effect on the OrtValue.
+ */
+ [[deprecated("Do not use")]] void SetDimensions(OrtTensorTypeAndShapeInfo* info, _In_ const int64_t* dim_values, size_t dim_count);
+
+ /** \deprecated use Ort::Value::GetTensorMutableData()
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ template <typename T>
+ [[deprecated("use Ort::Value::GetTensorMutableData()")]] T* GetTensorMutableData(_Inout_ OrtValue* value);
+
+ /** \deprecated use Ort::Value::GetTensorData()
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ template <typename T>
+ [[deprecated("use Ort::Value::GetTensorData()")]] const T* GetTensorData(_Inout_ const OrtValue* value);
+
+ /** \deprecated use Ort::Value::GetTensorMemoryInfo()
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::Value::GetTensorMemoryInfo()")]] const OrtMemoryInfo* GetTensorMemoryInfo(_In_ const OrtValue* value);
+
+ /** \deprecated use Ort::TensorTypeAndShapeInfo::GetShape()
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::TensorTypeAndShapeInfo::GetShape()")]] std::vector<int64_t> GetTensorShape(const OrtTensorTypeAndShapeInfo* info);
+
+ /** \deprecated use TensorTypeAndShapeInfo instances for automatic ownership.
+ * [[deprecated]]
+ * This interface is not exception safe.
+ */
+ [[deprecated("use TensorTypeAndShapeInfo")]] void ReleaseTensorTypeAndShapeInfo(OrtTensorTypeAndShapeInfo* input);
+
+ /** \deprecated use Ort::KernelContext::GetInputCount
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::KernelContext::GetInputCount")]] size_t KernelContext_GetInputCount(const OrtKernelContext* context);
+
+ /** \deprecated use Ort::KernelContext::GetInput
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::KernelContext::GetInput")]] const OrtValue* KernelContext_GetInput(const OrtKernelContext* context, _In_ size_t index);
+
+ /** \deprecated use Ort::KernelContext::GetOutputCount
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::KernelContext::GetOutputCount")]] size_t KernelContext_GetOutputCount(const OrtKernelContext* context);
+
+ /** \deprecated use Ort::KernelContext::GetOutput
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::KernelContext::GetOutput")]] OrtValue* KernelContext_GetOutput(OrtKernelContext* context, _In_ size_t index, _In_ const int64_t* dim_values, size_t dim_count);
+
+ /** \deprecated use Ort::KernelContext::GetGPUComputeStream
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::KernelContext::GetGPUComputeStream")]] void* KernelContext_GetGPUComputeStream(const OrtKernelContext* context);
+
+ /** \deprecated use Ort::ThrowOnError()
+ * [[deprecated]]
+ * This interface is redundant.
+ */
+ [[deprecated("use Ort::ThrowOnError()")]] void ThrowOnError(OrtStatus* result);
+
+ /** \deprecated use Ort::OpAttr
+ * [[deprecated]]
+ * This interface is not exception safe.
+ */
+ [[deprecated("use Ort::OpAttr")]] OrtOpAttr* CreateOpAttr(_In_ const char* name,
+ _In_ const void* data,
+ _In_ int len,
+ _In_ OrtOpAttrType type);
+
+ /** \deprecated use Ort::OpAttr
+ * [[deprecated]]
+ * This interface is not exception safe.
+ */
+ [[deprecated("use Ort::OpAttr")]] void ReleaseOpAttr(_Frees_ptr_opt_ OrtOpAttr* op_attr);
+
+ /** \deprecated use Ort::Op
+ * [[deprecated]]
+ * This interface is not exception safe.
+ */
+ [[deprecated("use Ort::Op")]] OrtOp* CreateOp(_In_ const OrtKernelInfo* info,
+ _In_ const char* op_name,
+ _In_ const char* domain,
+ _In_ int version,
+ _In_opt_ const char** type_constraint_names,
+ _In_opt_ const ONNXTensorElementDataType* type_constraint_values,
+ _In_opt_ int type_constraint_count,
+ _In_opt_ const OrtOpAttr* const* attr_values,
+ _In_opt_ int attr_count,
+ _In_ int input_count,
+ _In_ int output_count);
+
+ /** \deprecated use Ort::Op::Invoke
+ * [[deprecated]]
+ * This interface is redundant
+ */
+ [[deprecated("use Ort::Op::Invoke")]] void InvokeOp(_In_ const OrtKernelContext* context,
+ _In_ const OrtOp* ort_op,
+ _In_ const OrtValue* const* input_values,
+ _In_ int input_count,
+ _Inout_ OrtValue* const* output_values,
+ _In_ int output_count);
+
+ /** \deprecated use Ort::Op for automatic lifespan management.
+ * [[deprecated]]
+ * This interface is not exception safe.
+ */
+ [[deprecated("use Ort::Op")]] void ReleaseOp(_Frees_ptr_opt_ OrtOp* ort_op);
+
+ /** \deprecated use Ort::KernelInfo for automatic lifespan management or for
+ * querying attributes
+ * [[deprecated]]
+ * This interface is redundant
+ */
+ template <typename T> // T is only implemented for std::vector<float>, std::vector<int64_t>, float, int64_t, and string
+ [[deprecated("use Ort::KernelInfo::GetAttribute")]] T KernelInfoGetAttribute(_In_ const OrtKernelInfo* info, _In_ const char* name);
+
+ /** \deprecated use Ort::KernelInfo::Copy
+ * querying attributes
+ * [[deprecated]]
+ * This interface is not exception safe
+ */
+ [[deprecated("use Ort::KernelInfo::Copy")]] OrtKernelInfo* CopyKernelInfo(_In_ const OrtKernelInfo* info);
+
+ /** \deprecated use Ort::KernelInfo for lifespan management
+ * querying attributes
+ * [[deprecated]]
+ * This interface is not exception safe
+ */
+ [[deprecated("use Ort::KernelInfo")]] void ReleaseKernelInfo(_Frees_ptr_opt_ OrtKernelInfo* info_copy);
+
+ private:
+ const OrtApi& api_;
+};
+
+template <typename TOp, typename TKernel>
+struct CustomOpBase : OrtCustomOp {
+ CustomOpBase() {
+ OrtCustomOp::version = ORT_API_VERSION;
+ OrtCustomOp::CreateKernel = [](const OrtCustomOp* this_, const OrtApi* api, const OrtKernelInfo* info) { return static_cast<const TOp*>(this_)->CreateKernel(*api, info); };
+ OrtCustomOp::GetName = [](const OrtCustomOp* this_) { return static_cast<const TOp*>(this_)->GetName(); };
+
+ OrtCustomOp::GetExecutionProviderType = [](const OrtCustomOp* this_) { return static_cast<const TOp*>(this_)->GetExecutionProviderType(); };
+
+ OrtCustomOp::GetInputTypeCount = [](const OrtCustomOp* this_) { return static_cast<const TOp*>(this_)->GetInputTypeCount(); };
+ OrtCustomOp::GetInputType = [](const OrtCustomOp* this_, size_t index) { return static_cast<const TOp*>(this_)->GetInputType(index); };
+ OrtCustomOp::GetInputMemoryType = [](const OrtCustomOp* this_, size_t index) { return static_cast<const TOp*>(this_)->GetInputMemoryType(index); };
+
+ OrtCustomOp::GetOutputTypeCount = [](const OrtCustomOp* this_) { return static_cast<const TOp*>(this_)->GetOutputTypeCount(); };
+ OrtCustomOp::GetOutputType = [](const OrtCustomOp* this_, size_t index) { return static_cast<const TOp*>(this_)->GetOutputType(index); };
+
+ OrtCustomOp::KernelCompute = [](void* op_kernel, OrtKernelContext* context) { static_cast<TKernel*>(op_kernel)->Compute(context); };
+#if defined(_MSC_VER) && !defined(__clang__)
+#pragma warning(push)
+#pragma warning(disable : 26409)
+#endif
+ OrtCustomOp::KernelDestroy = [](void* op_kernel) { delete static_cast<TKernel*>(op_kernel); };
+#if defined(_MSC_VER) && !defined(__clang__)
+#pragma warning(pop)
+#endif
+ OrtCustomOp::GetInputCharacteristic = [](const OrtCustomOp* this_, size_t index) { return static_cast<const TOp*>(this_)->GetInputCharacteristic(index); };
+ OrtCustomOp::GetOutputCharacteristic = [](const OrtCustomOp* this_, size_t index) { return static_cast<const TOp*>(this_)->GetOutputCharacteristic(index); };
+
+ OrtCustomOp::GetVariadicInputMinArity = [](const OrtCustomOp* this_) { return static_cast<const TOp*>(this_)->GetVariadicInputMinArity(); };
+ OrtCustomOp::GetVariadicInputHomogeneity = [](const OrtCustomOp* this_) { return static_cast<int>(static_cast<const TOp*>(this_)->GetVariadicInputHomogeneity()); };
+ OrtCustomOp::GetVariadicOutputMinArity = [](const OrtCustomOp* this_) { return static_cast<const TOp*>(this_)->GetVariadicOutputMinArity(); };
+ OrtCustomOp::GetVariadicOutputHomogeneity = [](const OrtCustomOp* this_) { return static_cast<int>(static_cast<const TOp*>(this_)->GetVariadicOutputHomogeneity()); };
+ }
+
+ // Default implementation of GetExecutionProviderType that returns nullptr to default to the CPU provider
+ const char* GetExecutionProviderType() const { return nullptr; }
+
+ // Default implementations of GetInputCharacteristic() and GetOutputCharacteristic() below
+ // (inputs and outputs are required by default)
+ OrtCustomOpInputOutputCharacteristic GetInputCharacteristic(size_t /*index*/) const {
+ return OrtCustomOpInputOutputCharacteristic::INPUT_OUTPUT_REQUIRED;
+ }
+
+ OrtCustomOpInputOutputCharacteristic GetOutputCharacteristic(size_t /*index*/) const {
+ return OrtCustomOpInputOutputCharacteristic::INPUT_OUTPUT_REQUIRED;
+ }
+
+ // Default implemention of GetInputMemoryType() that returns OrtMemTypeDefault
+ OrtMemType GetInputMemoryType(size_t /*index*/) const {
+ return OrtMemTypeDefault;
+ }
+
+ // Default implementation of GetVariadicInputMinArity() returns 1 to specify that a variadic input
+ // should expect at least 1 argument.
+ int GetVariadicInputMinArity() const {
+ return 1;
+ }
+
+ // Default implementation of GetVariadicInputHomegeneity() returns true to specify that all arguments
+ // to a variadic input should be of the same type.
+ bool GetVariadicInputHomogeneity() const {
+ return true;
+ }
+
+ // Default implementation of GetVariadicOutputMinArity() returns 1 to specify that a variadic output
+ // should produce at least 1 output value.
+ int GetVariadicOutputMinArity() const {
+ return 1;
+ }
+
+ // Default implementation of GetVariadicOutputHomegeneity() returns true to specify that all output values
+ // produced by a variadic output should be of the same type.
+ bool GetVariadicOutputHomogeneity() const {
+ return true;
+ }
+
+ // Declare list of session config entries used by this Custom Op.
+ // Implement this function in order to get configs from CustomOpBase::GetSessionConfigs().
+ // This default implementation returns an empty vector of config entries.
+ std::vector<std::string> GetSessionConfigKeys() const {
+ return std::vector<std::string>{};
+ }
+
+ protected:
+ // Helper function that returns a map of session config entries specified by CustomOpBase::GetSessionConfigKeys.
+ void GetSessionConfigs(std::unordered_map<std::string, std::string>& out, ConstSessionOptions options) const;
+};
+
+} // namespace Ort
+
+#include "onnxruntime_cxx_inline.h"
diff --git a/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_cxx_inline.h b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_cxx_inline.h
new file mode 100644
index 0000000..6d391ad
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_cxx_inline.h
@@ -0,0 +1,1874 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+// Do not include this file directly. Please include "onnxruntime_cxx_api.h" instead.
+// If interested in trying out features of the new experimental C++ API, include "experimental_onnxruntime_cxx_api.h" instead.
+//
+// These are the inline implementations of the C++ header APIs. They're in this separate file as to not clutter
+// the main C++ file with implementation details.
+
+namespace Ort {
+
+namespace detail {
+inline void ThrowStatus(const Status& st) {
+ std::string error_message = st.GetErrorMessage();
+ OrtErrorCode error_code = st.GetErrorCode();
+ ORT_CXX_API_THROW(std::move(error_message), error_code);
+}
+} // namespace detail
+
+inline void ThrowOnError(OrtStatus* ort_status) {
+ if (ort_status) {
+ Ort::Status st(ort_status);
+ detail::ThrowStatus(st);
+ }
+}
+
+inline void ThrowOnError(const Status& st) {
+ if (st) {
+ detail::ThrowStatus(st);
+ }
+}
+
+inline Status::Status(OrtStatus* status) : Base<OrtStatus>{status} {
+}
+
+inline Status::Status(const std::exception& e) {
+ p_ = GetApi().CreateStatus(ORT_FAIL, e.what());
+}
+
+inline Status::Status(const Exception& e) {
+ p_ = GetApi().CreateStatus(e.GetOrtErrorCode(), e.what());
+}
+
+inline std::string Status::GetErrorMessage() const {
+ std::string message(GetApi().GetErrorMessage(p_));
+ return message;
+}
+
+inline OrtErrorCode Status::GetErrorCode() const {
+ return GetApi().GetErrorCode(p_);
+}
+
+// This template converts a C++ type into it's ONNXTensorElementDataType
+template <typename T>
+struct TypeToTensorType;
+template <>
+struct TypeToTensorType<float> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT;
+};
+template <>
+struct TypeToTensorType<Float16_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16;
+};
+template <>
+struct TypeToTensorType<BFloat16_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_BFLOAT16;
+};
+template <>
+struct TypeToTensorType<double> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_DOUBLE;
+};
+template <>
+struct TypeToTensorType<int8_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8;
+};
+template <>
+struct TypeToTensorType<int16_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16;
+};
+template <>
+struct TypeToTensorType<int32_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32;
+};
+template <>
+struct TypeToTensorType<int64_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64;
+};
+template <>
+struct TypeToTensorType<uint8_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8;
+};
+template <>
+struct TypeToTensorType<uint16_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16;
+};
+template <>
+struct TypeToTensorType<uint32_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32;
+};
+template <>
+struct TypeToTensorType<uint64_t> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT64;
+};
+template <>
+struct TypeToTensorType<bool> {
+ static constexpr ONNXTensorElementDataType type = ONNX_TENSOR_ELEMENT_DATA_TYPE_BOOL;
+};
+
+inline MemoryAllocation::MemoryAllocation(OrtAllocator* allocator, void* p, size_t size)
+ : allocator_(allocator), p_(p), size_(size) {
+}
+
+inline MemoryAllocation::~MemoryAllocation() {
+ if (p_ != nullptr) {
+ // We do not throw out of destructor
+ auto ret = GetApi().AllocatorFree(allocator_, p_);
+ static_cast<void>(ret);
+ }
+}
+
+inline MemoryAllocation::MemoryAllocation(MemoryAllocation&& o) noexcept : allocator_(nullptr), p_(nullptr), size_(0) {
+ *this = std::move(o);
+}
+
+inline MemoryAllocation& MemoryAllocation::operator=(MemoryAllocation&& o) noexcept {
+ OrtAllocator* alloc = nullptr;
+ void* p = nullptr;
+ size_t sz = 0;
+
+ // Swap out this
+ std::swap(alloc, allocator_);
+ std::swap(p, p_);
+ std::swap(sz, size_);
+
+ // Swap with incoming
+ std::swap(allocator_, o.allocator_);
+ std::swap(p_, o.p_);
+ std::swap(size_, o.size_);
+
+ // Destroy this instance if needed
+ MemoryAllocation this_alloc(alloc, p, sz);
+ return *this;
+}
+
+namespace detail {
+
+template <typename T>
+inline void* AllocatorImpl<T>::Alloc(size_t size) {
+ void* out;
+ ThrowOnError(GetApi().AllocatorAlloc(this->p_, size, &out));
+ return out;
+}
+
+template <typename T>
+inline MemoryAllocation AllocatorImpl<T>::GetAllocation(size_t size) {
+ void* out;
+ ThrowOnError(GetApi().AllocatorAlloc(this->p_, size, &out));
+ MemoryAllocation result(this->p_, out, size);
+ return result;
+}
+
+template <typename T>
+inline void AllocatorImpl<T>::Free(void* p) {
+ ThrowOnError(GetApi().AllocatorFree(this->p_, p));
+}
+
+template <typename T>
+inline ConstMemoryInfo AllocatorImpl<T>::GetInfo() const {
+ const OrtMemoryInfo* out;
+ ThrowOnError(GetApi().AllocatorGetInfo(this->p_, &out));
+ return ConstMemoryInfo{out};
+}
+
+} // namespace detail
+
+inline AllocatorWithDefaultOptions::AllocatorWithDefaultOptions() {
+ ThrowOnError(GetApi().GetAllocatorWithDefaultOptions(&this->p_));
+}
+
+inline Allocator::Allocator(const Session& sess, const OrtMemoryInfo* mem_info) {
+ ThrowOnError(GetApi().CreateAllocator(sess, mem_info, &this->p_));
+}
+
+namespace detail {
+
+template <typename T>
+inline std::string MemoryInfoImpl<T>::GetAllocatorName() const {
+ const char* name = nullptr;
+ ThrowOnError(GetApi().MemoryInfoGetName(this->p_, &name));
+ return std::string(name);
+}
+
+template <typename T>
+inline OrtAllocatorType MemoryInfoImpl<T>::GetAllocatorType() const {
+ OrtAllocatorType type;
+ ThrowOnError(GetApi().MemoryInfoGetType(this->p_, &type));
+ return type;
+}
+
+template <typename T>
+inline int MemoryInfoImpl<T>::GetDeviceId() const {
+ int id = 0;
+ ThrowOnError(GetApi().MemoryInfoGetId(this->p_, &id));
+ return id;
+}
+
+template <typename T>
+inline OrtMemoryInfoDeviceType MemoryInfoImpl<T>::GetDeviceType() const {
+ OrtMemoryInfoDeviceType type;
+ GetApi().MemoryInfoGetDeviceType(this->p_, &type);
+ return type;
+}
+
+template <typename T>
+inline OrtMemType MemoryInfoImpl<T>::GetMemoryType() const {
+ OrtMemType type;
+ ThrowOnError(GetApi().MemoryInfoGetMemType(this->p_, &type));
+ return type;
+}
+
+template <typename T>
+template <typename U>
+inline bool MemoryInfoImpl<T>::operator==(const MemoryInfoImpl<U>& o) const {
+ int comp_result = 0;
+ ThrowOnError(Ort::GetApi().CompareMemoryInfo(this->p_, o, &comp_result));
+ return comp_result == 0;
+}
+
+} // namespace detail
+
+inline MemoryInfo MemoryInfo::CreateCpu(OrtAllocatorType type, OrtMemType mem_type) {
+ OrtMemoryInfo* p;
+ ThrowOnError(GetApi().CreateCpuMemoryInfo(type, mem_type, &p));
+ return MemoryInfo(p);
+}
+
+inline MemoryInfo::MemoryInfo(const char* name, OrtAllocatorType type, int id, OrtMemType mem_type) {
+ ThrowOnError(GetApi().CreateMemoryInfo(name, type, id, mem_type, &this->p_));
+}
+
+namespace detail {
+template <typename T>
+inline std::vector<std::string> ConstIoBindingImpl<T>::GetOutputNames() const {
+ AllocatorWithDefaultOptions allocator;
+ return binding_utils::GetOutputNamesHelper(this->p_, allocator);
+}
+
+template <typename T>
+inline std::vector<std::string> ConstIoBindingImpl<T>::GetOutputNames(OrtAllocator* allocator) const {
+ return binding_utils::GetOutputNamesHelper(this->p_, allocator);
+}
+
+template <typename T>
+inline std::vector<Value> ConstIoBindingImpl<T>::GetOutputValues() const {
+ AllocatorWithDefaultOptions allocator;
+ return binding_utils::GetOutputValuesHelper(this->p_, allocator);
+}
+
+template <typename T>
+inline std::vector<Value> ConstIoBindingImpl<T>::GetOutputValues(OrtAllocator* allocator) const {
+ return binding_utils::GetOutputValuesHelper(this->p_, allocator);
+}
+
+template <typename T>
+inline void IoBindingImpl<T>::BindInput(const char* name, const Value& value) {
+ ThrowOnError(GetApi().BindInput(this->p_, name, value));
+}
+
+template <typename T>
+inline void IoBindingImpl<T>::BindOutput(const char* name, const Value& value) {
+ ThrowOnError(GetApi().BindOutput(this->p_, name, value));
+}
+
+template <typename T>
+inline void IoBindingImpl<T>::BindOutput(const char* name, const OrtMemoryInfo* mem_info) {
+ ThrowOnError(GetApi().BindOutputToDevice(this->p_, name, mem_info));
+}
+
+template <typename T>
+inline void IoBindingImpl<T>::ClearBoundInputs() {
+ GetApi().ClearBoundInputs(this->p_);
+}
+
+template <typename T>
+inline void IoBindingImpl<T>::ClearBoundOutputs() {
+ GetApi().ClearBoundOutputs(this->p_);
+}
+
+template <typename T>
+inline void IoBindingImpl<T>::SynchronizeInputs() {
+ ThrowOnError(GetApi().SynchronizeBoundInputs(this->p_));
+}
+
+template <typename T>
+inline void IoBindingImpl<T>::SynchronizeOutputs() {
+ ThrowOnError(GetApi().SynchronizeBoundOutputs(this->p_));
+}
+
+namespace binding_utils {
+inline std::vector<std::string> GetOutputNamesHelper(const OrtIoBinding* binding, OrtAllocator* allocator) {
+ std::vector<std::string> result;
+ auto free_fn = detail::AllocatedFree(allocator);
+ using Ptr = std::unique_ptr<void, decltype(free_fn)>;
+
+ char* buffer = nullptr;
+ size_t* lengths = nullptr;
+ size_t count = 0;
+ ThrowOnError(GetApi().GetBoundOutputNames(binding, allocator, &buffer, &lengths, &count));
+
+ if (count == 0) {
+ return result;
+ }
+
+ Ptr buffer_g(buffer, free_fn);
+ Ptr lengths_g(lengths, free_fn);
+
+ result.reserve(count);
+ for (size_t i = 0; i < count; ++i) {
+ auto sz = *lengths;
+ result.emplace_back(buffer, sz);
+ buffer += sz;
+ ++lengths;
+ }
+ return result;
+}
+
+inline std::vector<Value> GetOutputValuesHelper(const OrtIoBinding* binding, OrtAllocator* allocator) {
+ std::vector<Value> result;
+ size_t owned = 0;
+ size_t output_count = 0;
+ // Lambda to release the buffer when no longer needed and
+ // make sure that we destroy all instances on exception
+ auto free_fn = [&owned, &output_count, allocator](OrtValue** buffer) {
+ if (buffer) {
+ while (owned < output_count) {
+ auto* p = buffer + owned++;
+ GetApi().ReleaseValue(*p);
+ }
+ allocator->Free(allocator, buffer);
+ }
+ };
+ using Ptr = std::unique_ptr<OrtValue*, decltype(free_fn)>;
+
+ OrtValue** output_buffer = nullptr;
+ ThrowOnError(GetApi().GetBoundOutputValues(binding, allocator, &output_buffer, &output_count));
+ if (output_count == 0) {
+ return result;
+ }
+
+ Ptr buffer_g(output_buffer, free_fn);
+
+ result.reserve(output_count);
+ for (size_t i = 0; i < output_count; ++i) {
+ result.emplace_back(output_buffer[i]);
+ ++owned;
+ }
+ return result;
+}
+
+} // namespace binding_utils
+} // namespace detail
+
+inline IoBinding::IoBinding(Session& session) {
+ ThrowOnError(GetApi().CreateIoBinding(session, &this->p_));
+}
+
+inline ArenaCfg::ArenaCfg(size_t max_mem, int arena_extend_strategy, int initial_chunk_size_bytes, int max_dead_bytes_per_chunk) {
+ ThrowOnError(GetApi().CreateArenaCfg(max_mem, arena_extend_strategy, initial_chunk_size_bytes, max_dead_bytes_per_chunk, &p_));
+}
+
+inline ThreadingOptions::ThreadingOptions() {
+ ThrowOnError(GetApi().CreateThreadingOptions(&p_));
+}
+
+inline ThreadingOptions& ThreadingOptions::SetGlobalIntraOpNumThreads(int intra_op_num_threads) {
+ ThrowOnError(GetApi().SetGlobalIntraOpNumThreads(p_, intra_op_num_threads));
+ return *this;
+}
+
+inline ThreadingOptions& ThreadingOptions::SetGlobalInterOpNumThreads(int inter_op_num_threads) {
+ ThrowOnError(GetApi().SetGlobalInterOpNumThreads(p_, inter_op_num_threads));
+ return *this;
+}
+
+inline ThreadingOptions& ThreadingOptions::SetGlobalSpinControl(int allow_spinning) {
+ ThrowOnError(GetApi().SetGlobalSpinControl(p_, allow_spinning));
+ return *this;
+}
+
+inline ThreadingOptions& ThreadingOptions::SetGlobalDenormalAsZero() {
+ ThrowOnError(GetApi().SetGlobalDenormalAsZero(p_));
+ return *this;
+}
+
+inline ThreadingOptions& ThreadingOptions::SetGlobalCustomCreateThreadFn(OrtCustomCreateThreadFn ort_custom_create_thread_fn) {
+ ThrowOnError(GetApi().SetGlobalCustomCreateThreadFn(p_, ort_custom_create_thread_fn));
+ return *this;
+}
+
+inline ThreadingOptions& ThreadingOptions::SetGlobalCustomThreadCreationOptions(void* ort_custom_thread_creation_options) {
+ ThrowOnError(GetApi().SetGlobalCustomThreadCreationOptions(p_, ort_custom_thread_creation_options));
+ return *this;
+}
+
+inline ThreadingOptions& ThreadingOptions::SetGlobalCustomJoinThreadFn(OrtCustomJoinThreadFn ort_custom_join_thread_fn) {
+ ThrowOnError(GetApi().SetGlobalCustomJoinThreadFn(p_, ort_custom_join_thread_fn));
+ return *this;
+}
+
+inline Env::Env(OrtLoggingLevel logging_level, _In_ const char* logid) {
+ ThrowOnError(GetApi().CreateEnv(logging_level, logid, &p_));
+ if (strcmp(logid, "onnxruntime-node") == 0) {
+ ThrowOnError(GetApi().SetLanguageProjection(p_, OrtLanguageProjection::ORT_PROJECTION_NODEJS));
+ } else {
+ ThrowOnError(GetApi().SetLanguageProjection(p_, OrtLanguageProjection::ORT_PROJECTION_CPLUSPLUS));
+ }
+}
+
+inline Env::Env(OrtLoggingLevel logging_level, const char* logid, OrtLoggingFunction logging_function, void* logger_param) {
+ ThrowOnError(GetApi().CreateEnvWithCustomLogger(logging_function, logger_param, logging_level, logid, &p_));
+ if (strcmp(logid, "onnxruntime-node") == 0) {
+ ThrowOnError(GetApi().SetLanguageProjection(p_, OrtLanguageProjection::ORT_PROJECTION_NODEJS));
+ } else {
+ ThrowOnError(GetApi().SetLanguageProjection(p_, OrtLanguageProjection::ORT_PROJECTION_CPLUSPLUS));
+ }
+}
+
+inline Env::Env(const OrtThreadingOptions* tp_options, OrtLoggingLevel logging_level, _In_ const char* logid) {
+ ThrowOnError(GetApi().CreateEnvWithGlobalThreadPools(logging_level, logid, tp_options, &p_));
+ if (strcmp(logid, "onnxruntime-node") == 0) {
+ ThrowOnError(GetApi().SetLanguageProjection(p_, OrtLanguageProjection::ORT_PROJECTION_NODEJS));
+ } else {
+ ThrowOnError(GetApi().SetLanguageProjection(p_, OrtLanguageProjection::ORT_PROJECTION_CPLUSPLUS));
+ }
+}
+
+inline Env::Env(const OrtThreadingOptions* tp_options, OrtLoggingFunction logging_function, void* logger_param,
+ OrtLoggingLevel logging_level, _In_ const char* logid) {
+ ThrowOnError(GetApi().CreateEnvWithCustomLoggerAndGlobalThreadPools(logging_function, logger_param, logging_level, logid, tp_options, &p_));
+ if (strcmp(logid, "onnxruntime-node") == 0) {
+ ThrowOnError(GetApi().SetLanguageProjection(p_, OrtLanguageProjection::ORT_PROJECTION_NODEJS));
+ } else {
+ ThrowOnError(GetApi().SetLanguageProjection(p_, OrtLanguageProjection::ORT_PROJECTION_CPLUSPLUS));
+ }
+}
+
+inline Env& Env::EnableTelemetryEvents() {
+ ThrowOnError(GetApi().EnableTelemetryEvents(p_));
+ return *this;
+}
+
+inline Env& Env::DisableTelemetryEvents() {
+ ThrowOnError(GetApi().DisableTelemetryEvents(p_));
+ return *this;
+}
+
+inline Env& Env::UpdateEnvWithCustomLogLevel(OrtLoggingLevel log_severity_level) {
+ ThrowOnError(GetApi().UpdateEnvWithCustomLogLevel(p_, log_severity_level));
+ return *this;
+}
+
+inline Env& Env::CreateAndRegisterAllocator(const OrtMemoryInfo* mem_info, const OrtArenaCfg* arena_cfg) {
+ ThrowOnError(GetApi().CreateAndRegisterAllocator(p_, mem_info, arena_cfg));
+ return *this;
+}
+
+inline CustomOpDomain::CustomOpDomain(const char* domain) {
+ ThrowOnError(GetApi().CreateCustomOpDomain(domain, &p_));
+}
+
+inline void CustomOpDomain::Add(const OrtCustomOp* op) {
+ ThrowOnError(GetApi().CustomOpDomain_Add(p_, op));
+}
+
+inline RunOptions::RunOptions() {
+ ThrowOnError(GetApi().CreateRunOptions(&p_));
+}
+
+inline RunOptions& RunOptions::SetRunLogVerbosityLevel(int level) {
+ ThrowOnError(GetApi().RunOptionsSetRunLogVerbosityLevel(p_, level));
+ return *this;
+}
+
+inline RunOptions& RunOptions::SetRunLogSeverityLevel(int level) {
+ ThrowOnError(GetApi().RunOptionsSetRunLogSeverityLevel(p_, level));
+ return *this;
+}
+
+inline int RunOptions::GetRunLogVerbosityLevel() const {
+ int out;
+ ThrowOnError(GetApi().RunOptionsGetRunLogVerbosityLevel(p_, &out));
+ return out;
+}
+
+inline int RunOptions::GetRunLogSeverityLevel() const {
+ int out;
+ ThrowOnError(GetApi().RunOptionsGetRunLogSeverityLevel(p_, &out));
+ return out;
+}
+
+inline RunOptions& RunOptions::SetRunTag(const char* run_tag) {
+ ThrowOnError(GetApi().RunOptionsSetRunTag(p_, run_tag));
+ return *this;
+}
+
+inline const char* RunOptions::GetRunTag() const {
+ const char* out;
+ ThrowOnError(GetApi().RunOptionsGetRunTag(p_, &out));
+ return out;
+}
+
+inline RunOptions& RunOptions::AddConfigEntry(const char* config_key, const char* config_value) {
+ ThrowOnError(GetApi().AddRunConfigEntry(p_, config_key, config_value));
+ return *this;
+}
+
+inline RunOptions& RunOptions::SetTerminate() {
+ ThrowOnError(GetApi().RunOptionsSetTerminate(p_));
+ return *this;
+}
+
+inline RunOptions& RunOptions::UnsetTerminate() {
+ ThrowOnError(GetApi().RunOptionsUnsetTerminate(p_));
+ return *this;
+}
+
+namespace detail {
+
+template <typename T>
+inline Ort::SessionOptions ConstSessionOptionsImpl<T>::Clone() const {
+ OrtSessionOptions* out;
+ ThrowOnError(GetApi().CloneSessionOptions(this->p_, &out));
+ return SessionOptions{out};
+}
+
+template <typename T>
+inline std::string ConstSessionOptionsImpl<T>::GetConfigEntry(const char* config_key) const {
+ size_t size = 0;
+ // Feed nullptr for the data buffer to query the true size of the string value
+ Ort::ThrowOnError(GetApi().GetSessionConfigEntry(this->p_, config_key, nullptr, &size));
+
+ std::string out;
+ out.resize(size);
+ Ort::ThrowOnError(GetApi().GetSessionConfigEntry(this->p_, config_key, &out[0], &size));
+ out.resize(size - 1); // remove the terminating character '\0'
+
+ return out;
+}
+
+template <typename T>
+inline bool ConstSessionOptionsImpl<T>::HasConfigEntry(const char* config_key) const {
+ int out = 0;
+ Ort::ThrowOnError(GetApi().HasSessionConfigEntry(this->p_, config_key, &out));
+ return static_cast<bool>(out);
+}
+
+template <typename T>
+inline std::string ConstSessionOptionsImpl<T>::GetConfigEntryOrDefault(const char* config_key, const std::string& def) {
+ if (!this->HasConfigEntry(config_key)) {
+ return def;
+ }
+
+ return this->GetConfigEntry(config_key);
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetIntraOpNumThreads(int intra_op_num_threads) {
+ ThrowOnError(GetApi().SetIntraOpNumThreads(this->p_, intra_op_num_threads));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetInterOpNumThreads(int inter_op_num_threads) {
+ ThrowOnError(GetApi().SetInterOpNumThreads(this->p_, inter_op_num_threads));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetGraphOptimizationLevel(GraphOptimizationLevel graph_optimization_level) {
+ ThrowOnError(GetApi().SetSessionGraphOptimizationLevel(this->p_, graph_optimization_level));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetOptimizedModelFilePath(const ORTCHAR_T* optimized_model_filepath) {
+ ThrowOnError(GetApi().SetOptimizedModelFilePath(this->p_, optimized_model_filepath));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::EnableProfiling(const ORTCHAR_T* profile_file_prefix) {
+ ThrowOnError(GetApi().EnableProfiling(this->p_, profile_file_prefix));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::DisableProfiling() {
+ ThrowOnError(GetApi().DisableProfiling(this->p_));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::EnableOrtCustomOps() {
+ ThrowOnError(GetApi().EnableOrtCustomOps(this->p_));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::EnableMemPattern() {
+ ThrowOnError(GetApi().EnableMemPattern(this->p_));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::DisableMemPattern() {
+ ThrowOnError(GetApi().DisableMemPattern(this->p_));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::EnableCpuMemArena() {
+ ThrowOnError(GetApi().EnableCpuMemArena(this->p_));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::DisableCpuMemArena() {
+ ThrowOnError(GetApi().DisableCpuMemArena(this->p_));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetExecutionMode(ExecutionMode execution_mode) {
+ ThrowOnError(GetApi().SetSessionExecutionMode(this->p_, execution_mode));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetLogId(const char* logid) {
+ ThrowOnError(GetApi().SetSessionLogId(this->p_, logid));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetLogSeverityLevel(int level) {
+ ThrowOnError(GetApi().SetSessionLogSeverityLevel(this->p_, level));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::Add(OrtCustomOpDomain* custom_op_domain) {
+ ThrowOnError(GetApi().AddCustomOpDomain(this->p_, custom_op_domain));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AddConfigEntry(const char* config_key, const char* config_value) {
+ ThrowOnError(GetApi().AddSessionConfigEntry(this->p_, config_key, config_value));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AddInitializer(const char* name, const OrtValue* ort_val) {
+ ThrowOnError(GetApi().AddInitializer(this->p_, name, ort_val));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::DisablePerSessionThreads() {
+ ThrowOnError(GetApi().DisablePerSessionThreads(this->p_));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AddExternalInitializers(const std::vector<std::string>& names,
+ const std::vector<Value>& ort_values) {
+ const size_t inputs_num = names.size();
+ if (inputs_num != ort_values.size()) {
+ ORT_CXX_API_THROW("Expecting names and ort_values to have the same length", ORT_INVALID_ARGUMENT);
+ }
+ std::vector<const char*> names_ptr;
+ std::vector<const OrtValue*> ort_values_ptrs;
+ names_ptr.reserve(inputs_num);
+ ort_values_ptrs.reserve(inputs_num);
+ for (size_t i = 0; i < inputs_num; ++i) {
+ names_ptr.push_back(names[i].c_str());
+ ort_values_ptrs.push_back(ort_values[i]);
+ }
+ ThrowOnError(GetApi().AddExternalInitializers(this->p_, names_ptr.data(), ort_values_ptrs.data(), inputs_num));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AppendExecutionProvider_CUDA(const OrtCUDAProviderOptions& provider_options) {
+ ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider_CUDA(this->p_, &provider_options));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AppendExecutionProvider_CUDA_V2(const OrtCUDAProviderOptionsV2& provider_options) {
+ ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider_CUDA_V2(this->p_, &provider_options));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AppendExecutionProvider_ROCM(const OrtROCMProviderOptions& provider_options) {
+ ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider_ROCM(this->p_, &provider_options));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AppendExecutionProvider_TensorRT(const OrtTensorRTProviderOptions& provider_options) {
+ ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider_TensorRT(this->p_, &provider_options));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AppendExecutionProvider_TensorRT_V2(const OrtTensorRTProviderOptionsV2& provider_options) {
+ ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider_TensorRT_V2(this->p_, &provider_options));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AppendExecutionProvider_MIGraphX(const OrtMIGraphXProviderOptions& provider_options) {
+ ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider_MIGraphX(this->p_, &provider_options));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AppendExecutionProvider_CANN(const OrtCANNProviderOptions& provider_options) {
+ ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider_CANN(this->p_, &provider_options));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AppendExecutionProvider(
+ const std::string& provider_name,
+ const std::unordered_map<std::string, std::string>& provider_options) {
+ auto num_entries = provider_options.size();
+ std::vector<const char*> keys, values;
+ if (num_entries > 0) {
+ keys.reserve(num_entries);
+ values.reserve(num_entries);
+
+ for (const auto& entry : provider_options) {
+ keys.push_back(entry.first.c_str());
+ values.push_back(entry.second.c_str());
+ }
+ }
+
+ ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider(this->p_, provider_name.c_str(),
+ keys.data(), values.data(), num_entries));
+
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetCustomCreateThreadFn(OrtCustomCreateThreadFn ort_custom_create_thread_fn) {
+ ThrowOnError(GetApi().SessionOptionsSetCustomCreateThreadFn(this->p_, ort_custom_create_thread_fn));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetCustomThreadCreationOptions(void* ort_custom_thread_creation_options) {
+ ThrowOnError(GetApi().SessionOptionsSetCustomThreadCreationOptions(this->p_, ort_custom_thread_creation_options));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::SetCustomJoinThreadFn(OrtCustomJoinThreadFn ort_custom_join_thread_fn) {
+ ThrowOnError(GetApi().SessionOptionsSetCustomJoinThreadFn(this->p_, ort_custom_join_thread_fn));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::AppendExecutionProvider_OpenVINO(const OrtOpenVINOProviderOptions& provider_options) {
+ ThrowOnError(GetApi().SessionOptionsAppendExecutionProvider_OpenVINO(this->p_, &provider_options));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::RegisterCustomOpsLibrary(const ORTCHAR_T* library_name,
+ const CustomOpConfigs& custom_op_configs) {
+ // Add custom op config entries before registering the custom op library. Otherwise, the config entries _may_ be ignored by
+ // the custom op library.
+ for (const auto& config_iter : custom_op_configs.GetFlattenedConfigs()) {
+ AddConfigEntry(config_iter.first.c_str(), config_iter.second.c_str());
+ }
+
+ ThrowOnError(GetApi().RegisterCustomOpsLibrary_V2(this->p_, library_name));
+ return *this;
+}
+
+template <typename T>
+inline SessionOptionsImpl<T>& SessionOptionsImpl<T>::RegisterCustomOpsUsingFunction(const char* registration_function_name) {
+ ThrowOnError(GetApi().RegisterCustomOpsUsingFunction(this->p_, registration_function_name));
+ return *this;
+}
+
+/// Session
+template <typename T>
+inline size_t ConstSessionImpl<T>::GetInputCount() const {
+ size_t out;
+ ThrowOnError(GetApi().SessionGetInputCount(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline size_t ConstSessionImpl<T>::GetOutputCount() const {
+ size_t out;
+ ThrowOnError(GetApi().SessionGetOutputCount(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline size_t ConstSessionImpl<T>::GetOverridableInitializerCount() const {
+ size_t out;
+ ThrowOnError(GetApi().SessionGetOverridableInitializerCount(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline AllocatedStringPtr ConstSessionImpl<T>::GetInputNameAllocated(size_t index, OrtAllocator* allocator) const {
+ char* out;
+ ThrowOnError(GetApi().SessionGetInputName(this->p_, index, allocator, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+template <typename T>
+inline AllocatedStringPtr ConstSessionImpl<T>::GetOutputNameAllocated(size_t index, OrtAllocator* allocator) const {
+ char* out;
+ ThrowOnError(GetApi().SessionGetOutputName(this->p_, index, allocator, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+template <typename T>
+inline AllocatedStringPtr ConstSessionImpl<T>::GetOverridableInitializerNameAllocated(size_t index, OrtAllocator* allocator) const {
+ char* out;
+ ThrowOnError(GetApi().SessionGetOverridableInitializerName(this->p_, index, allocator, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+template <typename T>
+inline uint64_t ConstSessionImpl<T>::GetProfilingStartTimeNs() const {
+ uint64_t out;
+ ThrowOnError(GetApi().SessionGetProfilingStartTimeNs(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline ModelMetadata ConstSessionImpl<T>::GetModelMetadata() const {
+ OrtModelMetadata* out;
+ ThrowOnError(GetApi().SessionGetModelMetadata(this->p_, &out));
+ return ModelMetadata{out};
+}
+
+template <typename T>
+inline TypeInfo ConstSessionImpl<T>::GetInputTypeInfo(size_t index) const {
+ OrtTypeInfo* out;
+ ThrowOnError(GetApi().SessionGetInputTypeInfo(this->p_, index, &out));
+ return TypeInfo{out};
+}
+
+template <typename T>
+inline TypeInfo ConstSessionImpl<T>::GetOutputTypeInfo(size_t index) const {
+ OrtTypeInfo* out;
+ ThrowOnError(GetApi().SessionGetOutputTypeInfo(this->p_, index, &out));
+ return TypeInfo{out};
+}
+
+template <typename T>
+inline TypeInfo ConstSessionImpl<T>::GetOverridableInitializerTypeInfo(size_t index) const {
+ OrtTypeInfo* out;
+ ThrowOnError(GetApi().SessionGetOverridableInitializerTypeInfo(this->p_, index, &out));
+ return TypeInfo{out};
+}
+
+template <typename T>
+inline std::vector<Value> SessionImpl<T>::Run(const RunOptions& run_options, const char* const* input_names, const Value* input_values, size_t input_count,
+ const char* const* output_names, size_t output_count) {
+ std::vector<Value> output_values;
+ output_values.reserve(output_count);
+ for (size_t i = 0; i < output_count; i++)
+ output_values.emplace_back(nullptr);
+ Run(run_options, input_names, input_values, input_count, output_names, output_values.data(), output_count);
+ return output_values;
+}
+
+template <typename T>
+inline void SessionImpl<T>::Run(const RunOptions& run_options, const char* const* input_names, const Value* input_values, size_t input_count,
+ const char* const* output_names, Value* output_values, size_t output_count) {
+ static_assert(sizeof(Value) == sizeof(OrtValue*), "Value is really just an array of OrtValue* in memory, so we can reinterpret_cast safely");
+ auto ort_input_values = reinterpret_cast<const OrtValue* const*>(input_values);
+ auto ort_output_values = reinterpret_cast<OrtValue**>(output_values);
+ ThrowOnError(GetApi().Run(this->p_, run_options, input_names, ort_input_values, input_count, output_names, output_count, ort_output_values));
+}
+
+template <typename T>
+inline void SessionImpl<T>::Run(const RunOptions& run_options, const IoBinding& io_binding) {
+ ThrowOnError(GetApi().RunWithBinding(this->p_, run_options, io_binding));
+}
+
+template <typename T>
+inline AllocatedStringPtr SessionImpl<T>::EndProfilingAllocated(OrtAllocator* allocator) {
+ char* out = nullptr;
+ ThrowOnError(GetApi().SessionEndProfiling(this->p_, allocator, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+} // namespace detail
+
+inline SessionOptions::SessionOptions() {
+ ThrowOnError(GetApi().CreateSessionOptions(&this->p_));
+}
+
+/// CustomOpConfigs
+inline std::string detail::MakeCustomOpConfigEntryKey(const char* custom_op_name, const char* config) {
+ std::string config_key = "custom_op.";
+
+ config_key += custom_op_name;
+ config_key += ".";
+ config_key += config;
+
+ return config_key;
+}
+
+inline CustomOpConfigs& CustomOpConfigs::AddConfig(const char* custom_op_name, const char* config_key, const char* config_value) {
+ const std::string full_flat_key = detail::MakeCustomOpConfigEntryKey(custom_op_name, config_key);
+ flat_configs_[full_flat_key] = config_value;
+ return *this;
+}
+
+inline const std::unordered_map<std::string, std::string>& CustomOpConfigs::GetFlattenedConfigs() const {
+ return flat_configs_;
+}
+
+inline Session::Session(const Env& env, const ORTCHAR_T* model_path, const SessionOptions& options) {
+ ThrowOnError(GetApi().CreateSession(env, model_path, options, &this->p_));
+}
+
+inline Session::Session(const Env& env, const ORTCHAR_T* model_path, const SessionOptions& options,
+ OrtPrepackedWeightsContainer* prepacked_weights_container) {
+ ThrowOnError(GetApi().CreateSessionWithPrepackedWeightsContainer(env, model_path, options, prepacked_weights_container, &this->p_));
+}
+
+inline Session::Session(const Env& env, const void* model_data, size_t model_data_length, const SessionOptions& options) {
+ ThrowOnError(GetApi().CreateSessionFromArray(env, model_data, model_data_length, options, &this->p_));
+}
+
+inline Session::Session(const Env& env, const void* model_data, size_t model_data_length,
+ const SessionOptions& options, OrtPrepackedWeightsContainer* prepacked_weights_container) {
+ ThrowOnError(GetApi().CreateSessionFromArrayWithPrepackedWeightsContainer(env, model_data, model_data_length, options,
+ prepacked_weights_container, &this->p_));
+}
+
+inline AllocatedStringPtr ModelMetadata::GetProducerNameAllocated(OrtAllocator* allocator) const {
+ char* out;
+ ThrowOnError(GetApi().ModelMetadataGetProducerName(p_, allocator, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+inline AllocatedStringPtr ModelMetadata::GetGraphNameAllocated(OrtAllocator* allocator) const {
+ char* out;
+ ThrowOnError(GetApi().ModelMetadataGetGraphName(p_, allocator, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+inline AllocatedStringPtr ModelMetadata::GetDomainAllocated(OrtAllocator* allocator) const {
+ char* out;
+ ThrowOnError(GetApi().ModelMetadataGetDomain(p_, allocator, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+inline AllocatedStringPtr Ort::ModelMetadata::GetDescriptionAllocated(OrtAllocator* allocator) const {
+ char* out;
+ ThrowOnError(GetApi().ModelMetadataGetDescription(p_, allocator, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+inline AllocatedStringPtr ModelMetadata::GetGraphDescriptionAllocated(OrtAllocator* allocator) const {
+ char* out;
+ ThrowOnError(GetApi().ModelMetadataGetGraphDescription(p_, allocator, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+inline AllocatedStringPtr ModelMetadata::LookupCustomMetadataMapAllocated(const char* key, OrtAllocator* allocator) const {
+ char* out;
+ ThrowOnError(GetApi().ModelMetadataLookupCustomMetadataMap(p_, allocator, key, &out));
+ return AllocatedStringPtr(out, detail::AllocatedFree(allocator));
+}
+
+inline std::vector<AllocatedStringPtr> ModelMetadata::GetCustomMetadataMapKeysAllocated(OrtAllocator* allocator) const {
+ auto deletor = detail::AllocatedFree(allocator);
+ std::vector<AllocatedStringPtr> result;
+
+ char** out = nullptr;
+ int64_t num_keys = 0;
+ ThrowOnError(GetApi().ModelMetadataGetCustomMetadataMapKeys(p_, allocator, &out, &num_keys));
+ if (num_keys <= 0) {
+ return result;
+ }
+
+ // array of pointers will be freed
+ std::unique_ptr<void, decltype(deletor)> array_guard(out, deletor);
+ // reserve may throw
+ auto strings_deletor = [&deletor, num_keys](char** out) { for(int64_t i = 0; i < num_keys; ++i) deletor(out[i]); };
+ std::unique_ptr<char*, decltype(strings_deletor)> strings_guard(out, strings_deletor);
+ result.reserve(static_cast<size_t>(num_keys));
+ strings_guard.release();
+ for (int64_t i = 0; i < num_keys; ++i) {
+ result.push_back(AllocatedStringPtr(out[i], deletor));
+ }
+
+ return result;
+}
+
+inline int64_t ModelMetadata::GetVersion() const {
+ int64_t out;
+ ThrowOnError(GetApi().ModelMetadataGetVersion(p_, &out));
+ return out;
+}
+
+namespace detail {
+
+template <typename T>
+inline ONNXTensorElementDataType TensorTypeAndShapeInfoImpl<T>::GetElementType() const {
+ ONNXTensorElementDataType out;
+ ThrowOnError(GetApi().GetTensorElementType(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline size_t TensorTypeAndShapeInfoImpl<T>::GetElementCount() const {
+ size_t out;
+ ThrowOnError(GetApi().GetTensorShapeElementCount(this->p_, &out));
+ return static_cast<size_t>(out);
+}
+
+template <typename T>
+inline size_t TensorTypeAndShapeInfoImpl<T>::GetDimensionsCount() const {
+ size_t out;
+ ThrowOnError(GetApi().GetDimensionsCount(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline void TensorTypeAndShapeInfoImpl<T>::GetDimensions(int64_t* values, size_t values_count) const {
+ ThrowOnError(GetApi().GetDimensions(this->p_, values, values_count));
+}
+
+template <typename T>
+inline void TensorTypeAndShapeInfoImpl<T>::GetSymbolicDimensions(const char** values, size_t values_count) const {
+ ThrowOnError(GetApi().GetSymbolicDimensions(this->p_, values, values_count));
+}
+
+template <typename T>
+inline std::vector<int64_t> TensorTypeAndShapeInfoImpl<T>::GetShape() const {
+ std::vector<int64_t> out(GetDimensionsCount(), 0);
+ ThrowOnError(GetApi().GetDimensions(this->p_, out.data(), out.size()));
+ return out;
+}
+
+} // namespace detail
+
+namespace detail {
+template <typename T>
+inline ConstTensorTypeAndShapeInfo TypeInfoImpl<T>::GetTensorTypeAndShapeInfo() const {
+ const OrtTensorTypeAndShapeInfo* out;
+ ThrowOnError(GetApi().CastTypeInfoToTensorInfo(this->p_, &out));
+ return ConstTensorTypeAndShapeInfo{out};
+}
+
+template <typename T>
+inline ConstSequenceTypeInfo TypeInfoImpl<T>::GetSequenceTypeInfo() const {
+ const OrtSequenceTypeInfo* out;
+ ThrowOnError(GetApi().CastTypeInfoToSequenceTypeInfo(this->p_, &out));
+ return ConstSequenceTypeInfo{out};
+}
+
+template <typename T>
+inline ConstMapTypeInfo TypeInfoImpl<T>::GetMapTypeInfo() const {
+ const OrtMapTypeInfo* out;
+ ThrowOnError(GetApi().CastTypeInfoToMapTypeInfo(this->p_, &out));
+ return ConstMapTypeInfo{out};
+}
+
+template <typename T>
+inline ONNXType TypeInfoImpl<T>::GetONNXType() const {
+ ONNXType out;
+ ThrowOnError(GetApi().GetOnnxTypeFromTypeInfo(this->p_, &out));
+ return out;
+}
+
+} // namespace detail
+
+namespace detail {
+template <typename T>
+inline TypeInfo SequenceTypeInfoImpl<T>::GetSequenceElementType() const {
+ OrtTypeInfo* output;
+ ThrowOnError(GetApi().GetSequenceElementType(this->p_, &output));
+ return TypeInfo{output};
+}
+
+} // namespace detail
+
+namespace detail {
+template <typename T>
+inline ONNXTensorElementDataType MapTypeInfoImpl<T>::GetMapKeyType() const {
+ ONNXTensorElementDataType out;
+ ThrowOnError(GetApi().GetMapKeyType(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline TypeInfo MapTypeInfoImpl<T>::GetMapValueType() const {
+ OrtTypeInfo* output;
+ ThrowOnError(GetApi().GetMapValueType(this->p_, &output));
+ return TypeInfo{output};
+}
+} // namespace detail
+
+namespace detail {
+
+template <typename T>
+template <typename R>
+inline void ConstValueImpl<T>::GetOpaqueData(const char* domain, const char* type_name, R& out) const {
+ ThrowOnError(GetApi().GetOpaqueValue(domain, type_name, this->p_, &out, sizeof(R)));
+}
+
+template <typename T>
+inline bool ConstValueImpl<T>::IsTensor() const {
+ int out;
+ ThrowOnError(GetApi().IsTensor(this->p_, &out));
+ return out != 0;
+}
+
+template <typename T>
+inline bool ConstValueImpl<T>::HasValue() const {
+ int out;
+ ThrowOnError(GetApi().HasValue(this->p_, &out));
+ return out != 0;
+}
+
+template <typename T>
+inline size_t ConstValueImpl<T>::GetCount() const {
+ size_t out;
+ ThrowOnError(GetApi().GetValueCount(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline Value ConstValueImpl<T>::GetValue(int index, OrtAllocator* allocator) const {
+ OrtValue* out;
+ ThrowOnError(GetApi().GetValue(this->p_, index, allocator, &out));
+ return Value{out};
+}
+
+template <typename T>
+inline size_t ConstValueImpl<T>::GetStringTensorDataLength() const {
+ size_t out;
+ ThrowOnError(GetApi().GetStringTensorDataLength(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline size_t ConstValueImpl<T>::GetStringTensorElementLength(size_t element_index) const {
+ size_t out;
+ ThrowOnError(GetApi().GetStringTensorElementLength(this->p_, element_index, &out));
+ return out;
+}
+
+template <typename T>
+template <typename R>
+inline const R* ConstValueImpl<T>::GetTensorData() const {
+ R* out;
+ ThrowOnError(GetApi().GetTensorMutableData(const_cast<OrtValue*>(this->p_), (void**)&out));
+ return out;
+}
+
+template <typename T>
+inline const void* ConstValueImpl<T>::GetTensorRawData() const {
+ void* out;
+ ThrowOnError(GetApi().GetTensorMutableData(const_cast<OrtValue*>(this->p_), &out));
+ return out;
+}
+
+template <typename T>
+inline TypeInfo ConstValueImpl<T>::GetTypeInfo() const {
+ OrtTypeInfo* output;
+ ThrowOnError(GetApi().GetTypeInfo(this->p_, &output));
+ return TypeInfo{output};
+}
+
+template <typename T>
+inline TensorTypeAndShapeInfo ConstValueImpl<T>::GetTensorTypeAndShapeInfo() const {
+ OrtTensorTypeAndShapeInfo* output;
+ ThrowOnError(GetApi().GetTensorTypeAndShape(this->p_, &output));
+ return TensorTypeAndShapeInfo{output};
+}
+
+template <typename T>
+inline ConstMemoryInfo ConstValueImpl<T>::GetTensorMemoryInfo() const {
+ const OrtMemoryInfo* mem_info;
+ ThrowOnError(GetApi().GetTensorMemoryInfo(this->p_, &mem_info));
+ return ConstMemoryInfo(mem_info);
+}
+
+template <typename T>
+inline void ConstValueImpl<T>::GetStringTensorElement(size_t buffer_length, size_t element_index, void* buffer) const {
+ ThrowOnError(GetApi().GetStringTensorElement(this->p_, buffer_length, element_index, buffer));
+}
+
+template <typename T>
+inline void ConstValueImpl<T>::GetStringTensorContent(void* buffer, size_t buffer_length, size_t* offsets, size_t offsets_count) const {
+ ThrowOnError(GetApi().GetStringTensorContent(this->p_, buffer, buffer_length, offsets, offsets_count));
+}
+
+#if !defined(DISABLE_SPARSE_TENSORS)
+template <typename T>
+inline OrtSparseFormat ConstValueImpl<T>::GetSparseFormat() const {
+ OrtSparseFormat format;
+ ThrowOnError(GetApi().GetSparseTensorFormat(this->p_, &format));
+ return format;
+}
+
+template <typename T>
+inline TensorTypeAndShapeInfo ConstValueImpl<T>::GetSparseTensorValuesTypeAndShapeInfo() const {
+ OrtTensorTypeAndShapeInfo* output;
+ ThrowOnError(GetApi().GetSparseTensorValuesTypeAndShape(this->p_, &output));
+ return TensorTypeAndShapeInfo{output};
+}
+
+template <typename T>
+inline TensorTypeAndShapeInfo ConstValueImpl<T>::GetSparseTensorIndicesTypeShapeInfo(OrtSparseIndicesFormat indices_format) const {
+ OrtTensorTypeAndShapeInfo* output;
+ ThrowOnError(GetApi().GetSparseTensorIndicesTypeShape(this->p_, indices_format, &output));
+ return TensorTypeAndShapeInfo{output};
+}
+
+template <typename T>
+template <typename R>
+inline const R* ConstValueImpl<T>::GetSparseTensorIndicesData(OrtSparseIndicesFormat indices_format, size_t& num_indices) const {
+ const void* out;
+ ThrowOnError(GetApi().GetSparseTensorIndices(this->p_, indices_format, &num_indices, &out));
+ return reinterpret_cast<const R*>(out);
+}
+
+template <typename T>
+inline bool ConstValueImpl<T>::IsSparseTensor() const {
+ int out;
+ ThrowOnError(GetApi().IsSparseTensor(this->p_, &out));
+ return out != 0;
+}
+
+template <typename T>
+template <typename R>
+inline const R* ConstValueImpl<T>::GetSparseTensorValues() const {
+ const void* out;
+ ThrowOnError(GetApi().GetSparseTensorValues(this->p_, &out));
+ return reinterpret_cast<const R*>(out);
+}
+
+#endif
+
+template <typename T>
+void ValueImpl<T>::FillStringTensor(const char* const* s, size_t s_len) {
+ ThrowOnError(GetApi().FillStringTensor(this->p_, s, s_len));
+}
+
+template <typename T>
+void ValueImpl<T>::FillStringTensorElement(const char* s, size_t index) {
+ ThrowOnError(GetApi().FillStringTensorElement(this->p_, s, index));
+}
+
+template <typename T>
+void* ValueImpl<T>::GetTensorMutableRawData() {
+ void* out;
+ ThrowOnError(GetApi().GetTensorMutableData(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+template <typename R>
+R* ValueImpl<T>::GetTensorMutableData() {
+ R* out;
+ ThrowOnError(GetApi().GetTensorMutableData(this->p_, (void**)&out));
+ return out;
+}
+
+template <typename T>
+template <typename R>
+R& ValueImpl<T>::At(const std::vector<int64_t>& location) {
+ static_assert(!std::is_same<T, std::string>::value, "this api does not support std::string");
+ R* out;
+ ThrowOnError(GetApi().TensorAt(this->p_, location.data(), location.size(), (void**)&out));
+ return *out;
+}
+
+#if !defined(DISABLE_SPARSE_TENSORS)
+template <typename T>
+void ValueImpl<T>::UseCooIndices(int64_t* indices_data, size_t indices_num) {
+ ThrowOnError(GetApi().UseCooIndices(this->p_, indices_data, indices_num));
+}
+
+template <typename T>
+void ValueImpl<T>::UseCsrIndices(int64_t* inner_data, size_t inner_num, int64_t* outer_data, size_t outer_num) {
+ ThrowOnError(GetApi().UseCsrIndices(this->p_, inner_data, inner_num, outer_data, outer_num));
+}
+
+template <typename T>
+void ValueImpl<T>::UseBlockSparseIndices(const Shape& indices_shape, int32_t* indices_data) {
+ ThrowOnError(GetApi().UseBlockSparseIndices(this->p_, indices_shape.shape, indices_shape.shape_len, indices_data));
+}
+
+template <typename T>
+void ValueImpl<T>::FillSparseTensorCoo(const OrtMemoryInfo* mem_info, const OrtSparseValuesParam& values_param,
+ const int64_t* indices_data, size_t indices_num) {
+ ThrowOnError(GetApi().FillSparseTensorCoo(this->p_, mem_info, values_param.values_shape,
+ values_param.values_shape_len, values_param.data.p_data,
+ indices_data, indices_num));
+}
+
+template <typename T>
+void ValueImpl<T>::FillSparseTensorCsr(const OrtMemoryInfo* data_mem_info,
+ const OrtSparseValuesParam& values,
+ const int64_t* inner_indices_data, size_t inner_indices_num,
+ const int64_t* outer_indices_data, size_t outer_indices_num) {
+ ThrowOnError(GetApi().FillSparseTensorCsr(this->p_, data_mem_info, values.values_shape, values.values_shape_len, values.data.p_data,
+ inner_indices_data, inner_indices_num,
+ outer_indices_data, outer_indices_num));
+}
+
+template <typename T>
+void ValueImpl<T>::FillSparseTensorBlockSparse(const OrtMemoryInfo* data_mem_info,
+ const OrtSparseValuesParam& values,
+ const Shape& indices_shape,
+ const int32_t* indices_data) {
+ ThrowOnError(GetApi().FillSparseTensorBlockSparse(this->p_, data_mem_info, values.values_shape, values.values_shape_len, values.data.p_data,
+ indices_shape.shape, indices_shape.shape_len,
+ indices_data));
+}
+
+#endif // !defined(DISABLE_SPARSE_TENSORS)
+
+} // namespace detail
+
+template <typename T>
+inline Value Value::CreateTensor(const OrtMemoryInfo* info, T* p_data, size_t p_data_element_count, const int64_t* shape, size_t shape_len) {
+ return CreateTensor(info, p_data, p_data_element_count * sizeof(T), shape, shape_len, TypeToTensorType<T>::type);
+}
+
+inline Value Value::CreateTensor(const OrtMemoryInfo* info, void* p_data, size_t p_data_byte_count, const int64_t* shape, size_t shape_len,
+ ONNXTensorElementDataType type) {
+ OrtValue* out;
+ ThrowOnError(GetApi().CreateTensorWithDataAsOrtValue(info, p_data, p_data_byte_count, shape, shape_len, type, &out));
+ return Value{out};
+}
+
+template <typename T>
+inline Value Value::CreateTensor(OrtAllocator* allocator, const int64_t* shape, size_t shape_len) {
+ return CreateTensor(allocator, shape, shape_len, TypeToTensorType<T>::type);
+}
+
+inline Value Value::CreateTensor(OrtAllocator* allocator, const int64_t* shape, size_t shape_len, ONNXTensorElementDataType type) {
+ OrtValue* out;
+ ThrowOnError(GetApi().CreateTensorAsOrtValue(allocator, shape, shape_len, type, &out));
+ return Value{out};
+}
+
+#if !defined(DISABLE_SPARSE_TENSORS)
+
+template <typename T>
+inline Value Value::CreateSparseTensor(const OrtMemoryInfo* info, T* p_data, const Shape& dense_shape,
+ const Shape& values_shape) {
+ return CreateSparseTensor(info, p_data, dense_shape, values_shape, TypeToTensorType<T>::type);
+}
+
+inline Value Value::CreateSparseTensor(const OrtMemoryInfo* info, void* p_data, const Shape& dense_shape,
+ const Shape& values_shape, ONNXTensorElementDataType type) {
+ OrtValue* out;
+ ThrowOnError(GetApi().CreateSparseTensorWithValuesAsOrtValue(info, p_data, dense_shape.shape, dense_shape.shape_len,
+ values_shape.shape, values_shape.shape_len, type, &out));
+ return Value{out};
+}
+
+template <typename T>
+inline Value Value::CreateSparseTensor(OrtAllocator* allocator, const Shape& dense_shape) {
+ return CreateSparseTensor(allocator, dense_shape, TypeToTensorType<T>::type);
+}
+
+inline Value Value::CreateSparseTensor(OrtAllocator* allocator, const Shape& dense_shape,
+ ONNXTensorElementDataType type) {
+ OrtValue* out;
+ ThrowOnError(GetApi().CreateSparseTensorAsOrtValue(allocator, dense_shape.shape, dense_shape.shape_len, type, &out));
+ return Value{out};
+}
+#endif // !defined(DISABLE_SPARSE_TENSORS)
+
+inline Value Value::CreateMap(Value& keys, Value& values) {
+ OrtValue* out;
+ OrtValue* inputs[2] = {keys, values};
+ ThrowOnError(GetApi().CreateValue(inputs, 2, ONNX_TYPE_MAP, &out));
+ return Value{out};
+}
+
+inline Value Value::CreateSequence(std::vector<Value>& values) {
+ OrtValue* out;
+ std::vector<OrtValue*> values_ort{values.data(), values.data() + values.size()};
+ ThrowOnError(GetApi().CreateValue(values_ort.data(), values_ort.size(), ONNX_TYPE_SEQUENCE, &out));
+ return Value{out};
+}
+
+template <typename T>
+inline Value Value::CreateOpaque(const char* domain, const char* type_name, const T& data_container) {
+ OrtValue* out;
+ ThrowOnError(GetApi().CreateOpaqueValue(domain, type_name, &data_container, sizeof(T), &out));
+ return Value{out};
+}
+
+//
+// Custom OP Inlines
+//
+inline KernelContext::KernelContext(OrtKernelContext* context) : ctx_(context) {
+}
+
+inline size_t KernelContext::GetInputCount() const {
+ size_t out = 0;
+ Ort::ThrowOnError(GetApi().KernelContext_GetInputCount(ctx_, &out));
+ return out;
+}
+
+inline size_t KernelContext::GetOutputCount() const {
+ size_t out = 0;
+ Ort::ThrowOnError(GetApi().KernelContext_GetOutputCount(ctx_, &out));
+ return out;
+}
+
+inline ConstValue KernelContext::GetInput(size_t index) const {
+ const OrtValue* out = nullptr;
+ Ort::ThrowOnError(GetApi().KernelContext_GetInput(ctx_, index, &out));
+ return ConstValue{out};
+}
+
+inline UnownedValue KernelContext::GetOutput(size_t index, const int64_t* dim_values, size_t dim_count) const {
+ OrtValue* out = nullptr;
+ Ort::ThrowOnError(GetApi().KernelContext_GetOutput(ctx_, index, dim_values, dim_count, &out));
+ return UnownedValue(out);
+}
+
+inline UnownedValue KernelContext::GetOutput(size_t index, const std::vector<int64_t>& dims) const {
+ OrtValue* out = nullptr;
+ Ort::ThrowOnError(GetApi().KernelContext_GetOutput(ctx_, index, dims.data(), dims.size(), &out));
+ return UnownedValue(out);
+}
+
+inline void* KernelContext::GetGPUComputeStream() const {
+ void* out = nullptr;
+ Ort::ThrowOnError(GetApi().KernelContext_GetGPUComputeStream(ctx_, &out));
+ return out;
+}
+
+inline OpAttr::OpAttr(const char* name, const void* data, int len, OrtOpAttrType type) {
+ Ort::ThrowOnError(GetApi().CreateOpAttr(name, data, len, type, &p_));
+}
+
+namespace detail {
+template <typename T>
+inline KernelInfo KernelInfoImpl<T>::Copy() const {
+ OrtKernelInfo* info_copy = nullptr;
+ Ort::ThrowOnError(GetApi().CopyKernelInfo(this->p_, &info_copy));
+ return KernelInfo{info_copy};
+}
+
+template <typename T>
+inline size_t KernelInfoImpl<T>::GetInputCount() const {
+ size_t out = 0;
+ ThrowOnError(GetApi().KernelInfo_GetInputCount(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline size_t KernelInfoImpl<T>::GetOutputCount() const {
+ size_t out = 0;
+ ThrowOnError(GetApi().KernelInfo_GetOutputCount(this->p_, &out));
+ return out;
+}
+
+template <typename T>
+inline std::string KernelInfoImpl<T>::GetInputName(size_t index) const {
+ size_t size = 0;
+
+ // Feed nullptr for the data buffer to query the true size of the string value
+ Ort::ThrowOnError(GetApi().KernelInfo_GetInputName(this->p_, index, nullptr, &size));
+
+ std::string out;
+ out.resize(size);
+ Ort::ThrowOnError(GetApi().KernelInfo_GetInputName(this->p_, index, &out[0], &size));
+ out.resize(size - 1); // remove the terminating character '\0'
+
+ return out;
+}
+
+template <typename T>
+inline std::string KernelInfoImpl<T>::GetOutputName(size_t index) const {
+ size_t size = 0;
+
+ // Feed nullptr for the data buffer to query the true size of the string value
+ Ort::ThrowOnError(GetApi().KernelInfo_GetOutputName(this->p_, index, nullptr, &size));
+
+ std::string out;
+ out.resize(size);
+ Ort::ThrowOnError(GetApi().KernelInfo_GetOutputName(this->p_, index, &out[0], &size));
+ out.resize(size - 1); // remove the terminating character '\0'
+
+ return out;
+}
+
+template <typename T>
+inline TypeInfo KernelInfoImpl<T>::GetInputTypeInfo(size_t index) const {
+ OrtTypeInfo* out = nullptr;
+ ThrowOnError(GetApi().KernelInfo_GetInputTypeInfo(this->p_, index, &out));
+ return TypeInfo{out};
+}
+
+template <typename T>
+inline TypeInfo KernelInfoImpl<T>::GetOutputTypeInfo(size_t index) const {
+ OrtTypeInfo* out = nullptr;
+ ThrowOnError(GetApi().KernelInfo_GetOutputTypeInfo(this->p_, index, &out));
+ return TypeInfo{out};
+}
+
+template <typename T>
+inline Value KernelInfoImpl<T>::GetTensorAttribute(const char* name, OrtAllocator* allocator) const {
+ OrtValue* out = nullptr;
+ ThrowOnError(GetApi().KernelInfoGetAttribute_tensor(this->p_, name, allocator, &out));
+ return Value{out};
+}
+
+inline void attr_utils::GetAttr(const OrtKernelInfo* p, const char* name, float& out) {
+ Ort::ThrowOnError(GetApi().KernelInfoGetAttribute_float(p, name, &out));
+}
+
+inline void attr_utils::GetAttr(const OrtKernelInfo* p, const char* name, int64_t& out) {
+ Ort::ThrowOnError(GetApi().KernelInfoGetAttribute_int64(p, name, &out));
+}
+
+inline void attr_utils::GetAttr(const OrtKernelInfo* p, const char* name, std::string& result) {
+ size_t size = 0;
+ // Feed nullptr for the data buffer to query the true size of the string attribute
+ Ort::ThrowOnError(GetApi().KernelInfoGetAttribute_string(p, name, nullptr, &size));
+
+ std::string out;
+ out.resize(size);
+ Ort::ThrowOnError(GetApi().KernelInfoGetAttribute_string(p, name, &out[0], &size));
+ out.resize(size - 1); // remove the terminating character '\0'
+ out.swap(result);
+}
+
+inline void attr_utils::GetAttrs(const OrtKernelInfo* p, const char* name, std::vector<float>& result) {
+ size_t size = 0;
+ // Feed nullptr for the data buffer to query the true size of the attribute
+ Ort::ThrowOnError(GetApi().KernelInfoGetAttributeArray_float(p, name, nullptr, &size));
+
+ std::vector<float> out;
+ out.resize(size);
+ Ort::ThrowOnError(GetApi().KernelInfoGetAttributeArray_float(p, name, out.data(), &size));
+ out.swap(result);
+}
+
+inline void attr_utils::GetAttrs(const OrtKernelInfo* p, const char* name, std::vector<int64_t>& result) {
+ size_t size = 0;
+
+ // Feed nullptr for the data buffer to query the true size of the attribute
+ Ort::ThrowOnError(GetApi().KernelInfoGetAttributeArray_int64(p, name, nullptr, &size));
+
+ std::vector<int64_t> out;
+ out.resize(size);
+ Ort::ThrowOnError(GetApi().KernelInfoGetAttributeArray_int64(p, name, out.data(), &size));
+ out.swap(result);
+}
+} // namespace detail
+
+inline KernelInfo::KernelInfo(OrtKernelInfo* info) : detail::KernelInfoImpl<OrtKernelInfo>{info} {}
+
+inline Op::Op(OrtOp* p) : Base<OrtOp>(p) {}
+
+inline Op Op::Create(const OrtKernelInfo* info, const char* op_name, const char* domain, int version,
+ const char** type_constraint_names,
+ const ONNXTensorElementDataType* type_constraint_values,
+ size_t type_constraint_count,
+ const OpAttr* attr_values, size_t attr_count,
+ size_t input_count, size_t output_count) {
+ static_assert(sizeof(OpAttr) == sizeof(OrtOpAttr*),
+ "OpAttr's is expected to be just an array of OrtOpAttr in memory so we can reinterpret safely");
+ auto attr_input_values = reinterpret_cast<const OrtOpAttr* const*>(attr_values);
+ OrtOp* op;
+ Ort::ThrowOnError(GetApi().CreateOp(info, op_name, domain, version, type_constraint_names, type_constraint_values,
+ static_cast<int>(type_constraint_count),
+ attr_input_values,
+ static_cast<int>(attr_count),
+ static_cast<int>(input_count),
+ static_cast<int>(output_count), &op));
+ return Op{op};
+}
+
+inline void Op::Invoke(const OrtKernelContext* context,
+ const Value* input_values,
+ size_t input_count,
+ Value* output_values,
+ size_t output_count) {
+ static_assert(sizeof(Value) == sizeof(OrtValue*),
+ "Value is really just an array of OrtValue* in memory, so we can reinterpret_cast safely");
+ auto ort_input_values = reinterpret_cast<const OrtValue* const*>(input_values);
+ auto ort_output_values = reinterpret_cast<OrtValue**>(output_values);
+ Ort::ThrowOnError(GetApi().InvokeOp(context, p_, ort_input_values, static_cast<int>(input_count),
+ ort_output_values, static_cast<int>(output_count)));
+}
+
+inline void Op::Invoke(const OrtKernelContext* context,
+ const OrtValue* const* input_values,
+ size_t input_count,
+ OrtValue* const* output_values,
+ size_t output_count) {
+ Ort::ThrowOnError(GetApi().InvokeOp(context, p_, input_values, static_cast<int>(input_count),
+ output_values, static_cast<int>(output_count)));
+}
+
+inline void CustomOpApi::ThrowOnError(OrtStatus* status) {
+ Ort::ThrowOnError(status);
+}
+
+template <>
+inline float CustomOpApi::KernelInfoGetAttribute<float>(_In_ const OrtKernelInfo* info, _In_ const char* name) {
+ float out;
+ Ort::ThrowOnError(api_.KernelInfoGetAttribute_float(info, name, &out));
+ return out;
+}
+
+template <>
+inline int64_t CustomOpApi::KernelInfoGetAttribute<int64_t>(_In_ const OrtKernelInfo* info, _In_ const char* name) {
+ int64_t out;
+ Ort::ThrowOnError(api_.KernelInfoGetAttribute_int64(info, name, &out));
+ return out;
+}
+
+template <>
+inline std::string CustomOpApi::KernelInfoGetAttribute<std::string>(_In_ const OrtKernelInfo* info, _In_ const char* name) {
+ size_t size = 0;
+ std::string out;
+
+ // Feed nullptr for the data buffer to query the true size of the string attribute
+ OrtStatus* status = api_.KernelInfoGetAttribute_string(info, name, nullptr, &size);
+
+ if (status == nullptr) {
+ out.resize(size);
+ Ort::ThrowOnError(api_.KernelInfoGetAttribute_string(info, name, &out[0], &size));
+ out.resize(size - 1); // remove the terminating character '\0'
+ } else {
+ Ort::ThrowOnError(status);
+ }
+ return out;
+}
+
+template <>
+inline std::vector<float> CustomOpApi::KernelInfoGetAttribute(_In_ const OrtKernelInfo* info, _In_ const char* name) {
+ size_t size = 0;
+ std::vector<float> out;
+
+ // Feed nullptr for the data buffer to query the true size of the attribute
+ OrtStatus* status = api_.KernelInfoGetAttributeArray_float(info, name, nullptr, &size);
+
+ if (status == nullptr) {
+ out.resize(size);
+ Ort::ThrowOnError(api_.KernelInfoGetAttributeArray_float(info, name, out.data(), &size));
+ } else {
+ Ort::ThrowOnError(status);
+ }
+ return out;
+}
+
+template <>
+inline std::vector<int64_t> CustomOpApi::KernelInfoGetAttribute(_In_ const OrtKernelInfo* info, _In_ const char* name) {
+ size_t size = 0;
+ std::vector<int64_t> out;
+
+ // Feed nullptr for the data buffer to query the true size of the attribute
+ OrtStatus* status = api_.KernelInfoGetAttributeArray_int64(info, name, nullptr, &size);
+
+ if (status == nullptr) {
+ out.resize(size);
+ Ort::ThrowOnError(api_.KernelInfoGetAttributeArray_int64(info, name, out.data(), &size));
+ } else {
+ Ort::ThrowOnError(status);
+ }
+ return out;
+}
+inline OrtTensorTypeAndShapeInfo* CustomOpApi::GetTensorTypeAndShape(_In_ const OrtValue* value) {
+ OrtTensorTypeAndShapeInfo* out;
+ Ort::ThrowOnError(api_.GetTensorTypeAndShape(value, &out));
+ return out;
+}
+
+inline size_t CustomOpApi::GetTensorShapeElementCount(_In_ const OrtTensorTypeAndShapeInfo* info) {
+ size_t out;
+ Ort::ThrowOnError(api_.GetTensorShapeElementCount(info, &out));
+ return out;
+}
+
+inline ONNXTensorElementDataType CustomOpApi::GetTensorElementType(const OrtTensorTypeAndShapeInfo* info) {
+ ONNXTensorElementDataType out;
+ Ort::ThrowOnError(api_.GetTensorElementType(info, &out));
+ return out;
+}
+
+inline size_t CustomOpApi::GetDimensionsCount(_In_ const OrtTensorTypeAndShapeInfo* info) {
+ size_t out;
+ Ort::ThrowOnError(api_.GetDimensionsCount(info, &out));
+ return out;
+}
+
+inline void CustomOpApi::GetDimensions(_In_ const OrtTensorTypeAndShapeInfo* info, _Out_ int64_t* dim_values, size_t dim_values_length) {
+ Ort::ThrowOnError(api_.GetDimensions(info, dim_values, dim_values_length));
+}
+
+inline void CustomOpApi::SetDimensions(OrtTensorTypeAndShapeInfo* info, _In_ const int64_t* dim_values, size_t dim_count) {
+ Ort::ThrowOnError(api_.SetDimensions(info, dim_values, dim_count));
+}
+
+template <typename T>
+inline T* CustomOpApi::GetTensorMutableData(_Inout_ OrtValue* value) {
+ T* data;
+ Ort::ThrowOnError(api_.GetTensorMutableData(value, reinterpret_cast<void**>(&data)));
+ return data;
+}
+
+inline const OrtMemoryInfo* CustomOpApi::GetTensorMemoryInfo(_In_ const OrtValue* value) {
+ const OrtMemoryInfo* mem_info;
+ Ort::ThrowOnError(api_.GetTensorMemoryInfo(value, &mem_info));
+ return mem_info;
+}
+
+template <typename T>
+inline const T* CustomOpApi::GetTensorData(_Inout_ const OrtValue* value) {
+ T* data = nullptr;
+ Ort::ThrowOnError(api_.GetTensorMutableData(const_cast<OrtValue*>(value), reinterpret_cast<void**>(&data)));
+ return data;
+}
+
+inline std::vector<int64_t> CustomOpApi::GetTensorShape(const OrtTensorTypeAndShapeInfo* info) {
+ size_t out;
+ Ort::ThrowOnError(api_.GetDimensionsCount(info, &out));
+ std::vector<int64_t> output(out);
+ Ort::ThrowOnError(api_.GetDimensions(info, output.data(), out));
+ return output;
+}
+
+inline void CustomOpApi::ReleaseTensorTypeAndShapeInfo(OrtTensorTypeAndShapeInfo* input) {
+ api_.ReleaseTensorTypeAndShapeInfo(input);
+}
+
+inline size_t CustomOpApi::KernelContext_GetInputCount(const OrtKernelContext* context) {
+ size_t out;
+ Ort::ThrowOnError(api_.KernelContext_GetInputCount(context, &out));
+ return out;
+}
+
+inline const OrtValue* CustomOpApi::KernelContext_GetInput(const OrtKernelContext* context, _In_ size_t index) {
+ const OrtValue* out;
+ Ort::ThrowOnError(api_.KernelContext_GetInput(context, index, &out));
+ return out;
+}
+
+inline size_t CustomOpApi::KernelContext_GetOutputCount(const OrtKernelContext* context) {
+ size_t out;
+ Ort::ThrowOnError(api_.KernelContext_GetOutputCount(context, &out));
+ return out;
+}
+
+inline OrtValue* CustomOpApi::KernelContext_GetOutput(OrtKernelContext* context, _In_ size_t index,
+ _In_ const int64_t* dim_values, size_t dim_count) {
+ OrtValue* out;
+ Ort::ThrowOnError(api_.KernelContext_GetOutput(context, index, dim_values, dim_count, &out));
+ return out;
+}
+
+inline void* CustomOpApi::KernelContext_GetGPUComputeStream(const OrtKernelContext* context) {
+ void* out;
+ Ort::ThrowOnError(api_.KernelContext_GetGPUComputeStream(context, &out));
+ return out;
+}
+
+inline OrtOpAttr* CustomOpApi::CreateOpAttr(_In_ const char* name,
+ _In_ const void* data,
+ _In_ int len,
+ _In_ OrtOpAttrType type) {
+ OrtOpAttr* op_attr{};
+ Ort::ThrowOnError(api_.CreateOpAttr(name, data, len, type, &op_attr));
+ return op_attr;
+}
+
+inline void CustomOpApi::ReleaseOpAttr(_Frees_ptr_opt_ OrtOpAttr* op_attr) {
+ api_.ReleaseOpAttr(op_attr);
+}
+
+inline OrtOp* CustomOpApi::CreateOp(_In_ const OrtKernelInfo* info,
+ _In_ const char* op_name,
+ _In_ const char* domain,
+ _In_ int version,
+ _In_opt_ const char** type_constraint_names,
+ _In_opt_ const ONNXTensorElementDataType* type_constraint_values,
+ _In_opt_ int type_constraint_count,
+ _In_opt_ const OrtOpAttr* const* attr_values,
+ _In_opt_ int attr_count,
+ _In_ int input_count,
+ _In_ int output_count) {
+ OrtOp* ort_op{};
+ Ort::ThrowOnError(api_.CreateOp(info, op_name, domain, version, type_constraint_names, type_constraint_values,
+ type_constraint_count, attr_values, attr_count, input_count, output_count, &ort_op));
+ return ort_op;
+}
+
+inline void CustomOpApi::InvokeOp(_In_ const OrtKernelContext* context,
+ _In_ const OrtOp* ort_op,
+ _In_ const OrtValue* const* input_values,
+ _In_ int input_count,
+ _Inout_ OrtValue* const* output_values,
+ _In_ int output_count) {
+ Ort::ThrowOnError(api_.InvokeOp(context, ort_op, input_values, input_count, output_values, output_count));
+}
+
+inline void CustomOpApi::ReleaseOp(_Frees_ptr_opt_ OrtOp* ort_op) {
+ api_.ReleaseOp(ort_op);
+}
+
+inline OrtKernelInfo* CustomOpApi::CopyKernelInfo(_In_ const OrtKernelInfo* info) {
+ OrtKernelInfo* info_copy{};
+ Ort::ThrowOnError(api_.CopyKernelInfo(info, &info_copy));
+ return info_copy;
+}
+
+inline void CustomOpApi::ReleaseKernelInfo(_Frees_ptr_opt_ OrtKernelInfo* info_copy) {
+ api_.ReleaseKernelInfo(info_copy);
+}
+
+inline std::vector<std::string> GetAvailableProviders() {
+ int len;
+ char** providers;
+ ThrowOnError(GetApi().GetAvailableProviders(&providers, &len));
+ std::vector<std::string> available_providers(providers, providers + len);
+ ThrowOnError(GetApi().ReleaseAvailableProviders(providers, len));
+ return available_providers;
+}
+
+SessionOptions& AddInitializer(const char* name, const OrtValue* ort_val);
+
+template <typename TOp, typename TKernel>
+void CustomOpBase<TOp, TKernel>::GetSessionConfigs(std::unordered_map<std::string, std::string>& out,
+ ConstSessionOptions options) const {
+ const TOp* derived = static_cast<const TOp*>(this);
+ std::vector<std::string> keys = derived->GetSessionConfigKeys();
+
+ out.reserve(keys.size());
+
+ std::string config_entry_key = detail::MakeCustomOpConfigEntryKey(derived->GetName(), "");
+ const size_t prefix_size = config_entry_key.length();
+
+ for (const auto& key : keys) {
+ config_entry_key.resize(prefix_size);
+ config_entry_key.append(key);
+ out[key] = options.GetConfigEntryOrDefault(config_entry_key.c_str(), "");
+ }
+}
+
+} // namespace Ort
diff --git a/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_run_options_config_keys.h b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_run_options_config_keys.h
new file mode 100644
index 0000000..1f5fcd5
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_run_options_config_keys.h
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#pragma once
+
+/*
+ * This file defines RunOptions Config Keys and format of the Config Values.
+ *
+ * The Naming Convention for a RunOptions Config Key,
+ * "[Area][.[SubArea1].[SubArea2]...].[Keyname]"
+ * Such as "ep.cuda.use_arena"
+ * The Config Key cannot be empty
+ * The maximum length of the Config Key is 128
+ *
+ * The string format of a RunOptions Config Value is defined individually for each Config.
+ * The maximum length of the Config Value is 1024
+ */
+
+// Key for enabling shrinkages of user listed device memory arenas.
+// Expects a list of semi-colon separated key value pairs separated by colon in the following format:
+// "device_0:device_id_0;device_1:device_id_1"
+// No white-spaces allowed in the provided list string.
+// Currently, the only supported devices are : "cpu", "gpu" (case sensitive).
+// If "cpu" is included in the list, DisableCpuMemArena() API must not be called (i.e.) arena for cpu should be enabled.
+// Example usage: "cpu:0;gpu:0" (or) "gpu:0"
+// By default, the value for this key is empty (i.e.) no memory arenas are shrunk
+static const char* const kOrtRunOptionsConfigEnableMemoryArenaShrinkage = "memory.enable_memory_arena_shrinkage";
+
+// Set to '1' to not synchronize execution providers with CPU at the end of session run.
+// Per default it will be set to '0'
+// Taking CUDA EP as an example, it omit triggering cudaStreamSynchronize on the compute stream.
+static const char* const kOrtRunOptionsConfigDisableSynchronizeExecutionProviders = "disable_synchronize_execution_providers";
diff --git a/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_session_options_config_keys.h b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_session_options_config_keys.h
new file mode 100644
index 0000000..92482d7
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/include/onnxruntime_session_options_config_keys.h
@@ -0,0 +1,186 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#pragma once
+
+/*
+ * This file defines SessionOptions Config Keys and format of the Config Values.
+ *
+ * The Naming Convention for a SessionOptions Config Key,
+ * "[Area][.[SubArea1].[SubArea2]...].[Keyname]"
+ * Such as "ep.cuda.use_arena"
+ * The Config Key cannot be empty
+ * The maximum length of the Config Key is 128
+ *
+ * The string format of a SessionOptions Config Value is defined individually for each Config.
+ * The maximum length of the Config Value is 1024
+ */
+
+// Key for disable PrePacking,
+// If the config value is set to "1" then the prepacking is disabled, otherwise prepacking is enabled (default value)
+static const char* const kOrtSessionOptionsConfigDisablePrepacking = "session.disable_prepacking";
+
+// A value of "1" means allocators registered in the env will be used. "0" means the allocators created in the session
+// will be used. Use this to override the usage of env allocators on a per session level.
+static const char* const kOrtSessionOptionsConfigUseEnvAllocators = "session.use_env_allocators";
+
+// Set to 'ORT' (case sensitive) to load an ORT format model.
+// If unset, model type will default to ONNX unless inferred from filename ('.ort' == ORT format) or bytes to be ORT
+static const char* const kOrtSessionOptionsConfigLoadModelFormat = "session.load_model_format";
+
+// Set to 'ORT' (case sensitive) to save optimized model in ORT format when SessionOptions.optimized_model_path is set.
+// If unset, format will default to ONNX unless optimized_model_filepath ends in '.ort'.
+static const char* const kOrtSessionOptionsConfigSaveModelFormat = "session.save_model_format";
+
+// If a value is "1", flush-to-zero and denormal-as-zero are applied. The default is "0".
+// When multiple sessions are created, a main thread doesn't override changes from succeeding session options,
+// but threads in session thread pools follow option changes.
+// When ORT runs with OpenMP, the same rule is applied, i.e. the first session option to flush-to-zero and
+// denormal-as-zero is only applied to global OpenMP thread pool, which doesn't support per-session thread pool.
+// Note that an alternative way not using this option at runtime is to train and export a model without denormals
+// and that's recommended because turning this option on may hurt model accuracy.
+static const char* const kOrtSessionOptionsConfigSetDenormalAsZero = "session.set_denormal_as_zero";
+
+// It controls to run quantization model in QDQ (QuantizelinearDeQuantizelinear) format or not.
+// "0": enable. ORT does fusion logic for QDQ format.
+// "1": disable. ORT doesn't do fusion logic for QDQ format.
+// Its default value is "0"
+static const char* const kOrtSessionOptionsDisableQuantQDQ = "session.disable_quant_qdq";
+
+// It controls whether to enable Double QDQ remover and Identical Children Consolidation
+// "0": not to disable. ORT does remove the middle 2 Nodes from a Q->(QD->Q)->QD pairs
+// "1": disable. ORT doesn't remove the middle 2 Nodes from a Q->(QD->Q)->QD pairs
+// Its default value is "0"
+static const char* const kOrtSessionOptionsDisableDoubleQDQRemover = "session.disable_double_qdq_remover";
+
+// If set to "1", enables the removal of QuantizeLinear/DequantizeLinear node pairs once all QDQ handling has been
+// completed. e.g. If after all QDQ handling has completed and we have -> FloatOp -> Q -> DQ -> FloatOp -> the
+// Q -> DQ could potentially be removed. This will provide a performance benefit by avoiding going from float to
+// 8-bit and back to float, but could impact accuracy. The impact on accuracy will be model specific and depend on
+// other factors like whether the model was created using Quantization Aware Training or Post Training Quantization.
+// As such, it's best to test to determine if enabling this works well for your scenario.
+// The default value is "0"
+// Available since version 1.11.
+static const char* const kOrtSessionOptionsEnableQuantQDQCleanup = "session.enable_quant_qdq_cleanup";
+
+// Enable or disable gelu approximation in graph optimization. "0": disable; "1": enable. The default is "0".
+// GeluApproximation has side effects which may change the inference results. It is disabled by default due to this.
+static const char* const kOrtSessionOptionsEnableGeluApproximation = "optimization.enable_gelu_approximation";
+
+#ifdef ENABLE_TRAINING
+// Specifies a list of op types for memory footprint reduction.
+// The value should be a ","-delimited list of pair of
+// <subgraph string : optimization strategy : number of subgraph to apply>.
+// For example, "Gelu+Cast+:1:0,Dropout+:1:1".
+// A valid "subgraph string" should be one subgraph representation output by ORT graph transformations.
+// "optimization strategy" currently has valid values: 0 - disabled, 1 - recompute.
+// "number of subgraph to apply" is used to control how many subgraphs to apply optimization, to avoid "oversaving"
+// the memory.
+static const char* const kOrtSessionOptionsMemoryOptimizerEnabler = "optimization.enable_memory_optimizer";
+
+// Specifies the level for detecting subgraphs for memory footprint reduction.
+// The value should be an integer. The default value is 0.
+static const char* const kOrtSessionOptionsMemoryOptimizerProbeLevel = "optimization.enable_memory_probe_recompute_level";
+#endif
+
+// Enable or disable using device allocator for allocating initialized tensor memory. "1": enable; "0": disable. The default is "0".
+// Using device allocators means the memory allocation is made using malloc/new.
+static const char* const kOrtSessionOptionsUseDeviceAllocatorForInitializers = "session.use_device_allocator_for_initializers";
+
+// Configure whether to allow the inter_op/intra_op threads spinning a number of times before blocking
+// "0": thread will block if found no job to run
+// "1": default, thread will spin a number of times before blocking
+static const char* const kOrtSessionOptionsConfigAllowInterOpSpinning = "session.inter_op.allow_spinning";
+static const char* const kOrtSessionOptionsConfigAllowIntraOpSpinning = "session.intra_op.allow_spinning";
+
+// Key for using model bytes directly for ORT format
+// If a session is created using an input byte array contains the ORT format model data,
+// By default we will copy the model bytes at the time of session creation to ensure the model bytes
+// buffer is valid.
+// Setting this option to "1" will disable copy the model bytes, and use the model bytes directly. The caller
+// has to guarantee that the model bytes are valid until the ORT session using the model bytes is destroyed.
+static const char* const kOrtSessionOptionsConfigUseORTModelBytesDirectly = "session.use_ort_model_bytes_directly";
+
+/// <summary>
+/// Key for using the ORT format model flatbuffer bytes directly for initializers.
+/// This avoids copying the bytes and reduces peak memory usage during model loading and initialization.
+/// Requires `session.use_ort_model_bytes_directly` to be true.
+/// If set, the flatbuffer bytes provided when creating the InferenceSession MUST remain valid for the entire
+/// duration of the InferenceSession.
+/// </summary>
+static const char* const kOrtSessionOptionsConfigUseORTModelBytesForInitializers =
+ "session.use_ort_model_bytes_for_initializers";
+
+// This should only be specified when exporting an ORT format model for use on a different platform.
+// If the ORT format model will be used on ARM platforms set to "1". For other platforms set to "0"
+// Available since version 1.11.
+static const char* const kOrtSessionOptionsQDQIsInt8Allowed = "session.qdqisint8allowed";
+
+// x64 SSE4.1/AVX2/AVX512(with no VNNI) has overflow problem with quantizied matrix multiplication with U8S8.
+// To avoid this we need to use slower U8U8 matrix multiplication instead. This option, if
+// turned on, use slower U8U8 matrix multiplications. Only effective with AVX2 or AVX512
+// platforms.
+static const char* const kOrtSessionOptionsAvx2PrecisionMode = "session.x64quantprecision";
+
+// Specifies how minimal build graph optimizations are handled in a full build.
+// These optimizations are at the extended level or higher.
+// Possible values and their effects are:
+// "save": Save runtime optimizations when saving an ORT format model.
+// "apply": Only apply optimizations available in a minimal build.
+// ""/<unspecified>: Apply optimizations available in a full build.
+// Available since version 1.11.
+static const char* const kOrtSessionOptionsConfigMinimalBuildOptimizations =
+ "optimization.minimal_build_optimizations";
+
+// Note: The options specific to an EP should be specified prior to appending that EP to the session options object in
+// order for them to take effect.
+
+// Specifies a list of stop op types. Nodes of a type in the stop op types and nodes downstream from them will not be
+// run by the NNAPI EP.
+// The value should be a ","-delimited list of op types. For example, "Add,Sub".
+// If not specified, the default set of stop ops is used. To specify an empty stop ops types list and disable stop op
+// exclusion, set the value to "".
+static const char* const kOrtSessionOptionsConfigNnapiEpPartitioningStopOps = "ep.nnapi.partitioning_stop_ops";
+
+// Enabling dynamic block-sizing for multithreading.
+// With a positive value, thread pool will split a task of N iterations to blocks of size starting from:
+// N / (num_of_threads * dynamic_block_base)
+// As execution progresses, the size will decrease according to the diminishing residual of N,
+// meaning the task will be distributed in smaller granularity for better parallelism.
+// For some models, it helps to reduce the variance of E2E inference latency and boost performance.
+// The feature will not function by default, specify any positive integer, e.g. "4", to enable it.
+// Available since version 1.11.
+static const char* const kOrtSessionOptionsConfigDynamicBlockBase = "session.dynamic_block_base";
+
+// This option allows to decrease CPU usage between infrequent
+// requests and forces any TP threads spinning stop immediately when the last of
+// concurrent Run() call returns.
+// Spinning is restarted on the next Run() call.
+// Applies only to internal thread-pools
+static const char* const kOrtSessionOptionsConfigForceSpinningStop = "session.force_spinning_stop";
+
+// "1": all inconsistencies encountered during shape and type inference
+// will result in failures.
+// "0": in some cases warnings will be logged but processing will continue. The default.
+// May be useful to expose bugs in models.
+static const char* const kOrtSessionOptionsConfigStrictShapeTypeInference = "session.strict_shape_type_inference";
+
+// The file saves configuration for partitioning node among logic streams
+static const char* const kNodePartitionConfigFile = "session.node_partition_config_file";
+
+// This Option allows setting affinities for intra op threads.
+// Affinity string follows format:
+// logical_processor_id,logical_processor_id;logical_processor_id,logical_processor_id
+// Semicolon isolates configurations among threads, while comma split processors where ith thread expected to attach to.
+// e.g.1,2,3;4,5
+// specifies affinities for two threads, with the 1st thread attach to the 1st, 2nd, and 3rd processor, and 2nd thread to the 4th and 5th.
+// To ease the configuration, an "interval" is also allowed:
+// e.g. 1-8;8-16;17-24
+// orders that the 1st thread runs on first eight processors, 2nd thread runs on next eight processors, and so forth.
+// Note:
+// 1. Once set, the number of thread affinities must equal to intra_op_num_threads - 1, since ort does not set affinity on the main thread which
+// is started and managed by the calling app;
+// 2. For windows, ort will infer the group id from a logical processor id, for example, assuming there are two groups with each has 64 logical processors,
+// an id of 64 will be inferred as the last processor of the 1st group, while 65 will be interpreted as the 1st processor of the second group.
+// Hence 64-65 is an invalid configuration, because a windows thread cannot be attached to processors across group boundary.
+static const char* const kOrtSessionOptionsConfigIntraOpThreadAffinities = "session.intra_op_thread_affinities";
diff --git a/funasr/runtime/cpp/onnxruntime/win/include/provider_options.h b/funasr/runtime/cpp/onnxruntime/win/include/provider_options.h
new file mode 100644
index 0000000..aab13e8
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/include/provider_options.h
@@ -0,0 +1,18 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#pragma once
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace onnxruntime {
+
+// data types for execution provider options
+
+using ProviderOptions = std::unordered_map<std::string, std::string>;
+using ProviderOptionsVector = std::vector<ProviderOptions>;
+using ProviderOptionsMap = std::unordered_map<std::string, ProviderOptions>;
+
+} // namespace onnxruntime
diff --git a/funasr/runtime/cpp/onnxruntime/win/include/tensorrt_provider_factory.h b/funasr/runtime/cpp/onnxruntime/win/include/tensorrt_provider_factory.h
new file mode 100644
index 0000000..44debc9
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/include/tensorrt_provider_factory.h
@@ -0,0 +1,14 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+#include "onnxruntime_c_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ORT_API_STATUS(OrtSessionOptionsAppendExecutionProvider_Tensorrt, _In_ OrtSessionOptions* options, int device_id);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.def b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.def
new file mode 100644
index 0000000..4b50ecd
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.def
@@ -0,0 +1,1017 @@
+LIBRARY libfftw3-3.dll
+EXPORTS
+dfftw_cleanup_
+dfftw_cleanup__
+dfftw_cleanup_threads_
+dfftw_cleanup_threads__
+dfftw_cost_
+dfftw_cost__
+dfftw_destroy_plan_
+dfftw_destroy_plan__
+dfftw_estimate_cost_
+dfftw_estimate_cost__
+dfftw_execute_
+dfftw_execute__
+dfftw_execute_dft_
+dfftw_execute_dft__
+dfftw_execute_dft_c2r_
+dfftw_execute_dft_c2r__
+dfftw_execute_dft_r2c_
+dfftw_execute_dft_r2c__
+dfftw_execute_r2r_
+dfftw_execute_r2r__
+dfftw_execute_split_dft_
+dfftw_execute_split_dft__
+dfftw_execute_split_dft_c2r_
+dfftw_execute_split_dft_c2r__
+dfftw_execute_split_dft_r2c_
+dfftw_execute_split_dft_r2c__
+dfftw_export_wisdom_
+dfftw_export_wisdom__
+dfftw_flops_
+dfftw_flops__
+dfftw_forget_wisdom_
+dfftw_forget_wisdom__
+dfftw_import_system_wisdom_
+dfftw_import_system_wisdom__
+dfftw_import_wisdom_
+dfftw_import_wisdom__
+dfftw_init_threads_
+dfftw_init_threads__
+dfftw_plan_dft_
+dfftw_plan_dft__
+dfftw_plan_dft_1d_
+dfftw_plan_dft_1d__
+dfftw_plan_dft_2d_
+dfftw_plan_dft_2d__
+dfftw_plan_dft_3d_
+dfftw_plan_dft_3d__
+dfftw_plan_dft_c2r_
+dfftw_plan_dft_c2r__
+dfftw_plan_dft_c2r_1d_
+dfftw_plan_dft_c2r_1d__
+dfftw_plan_dft_c2r_2d_
+dfftw_plan_dft_c2r_2d__
+dfftw_plan_dft_c2r_3d_
+dfftw_plan_dft_c2r_3d__
+dfftw_plan_dft_r2c_
+dfftw_plan_dft_r2c__
+dfftw_plan_dft_r2c_1d_
+dfftw_plan_dft_r2c_1d__
+dfftw_plan_dft_r2c_2d_
+dfftw_plan_dft_r2c_2d__
+dfftw_plan_dft_r2c_3d_
+dfftw_plan_dft_r2c_3d__
+dfftw_plan_guru_dft_
+dfftw_plan_guru_dft__
+dfftw_plan_guru_dft_c2r_
+dfftw_plan_guru_dft_c2r__
+dfftw_plan_guru_dft_r2c_
+dfftw_plan_guru_dft_r2c__
+dfftw_plan_guru_r2r_
+dfftw_plan_guru_r2r__
+dfftw_plan_guru_split_dft_
+dfftw_plan_guru_split_dft__
+dfftw_plan_guru_split_dft_c2r_
+dfftw_plan_guru_split_dft_c2r__
+dfftw_plan_guru_split_dft_r2c_
+dfftw_plan_guru_split_dft_r2c__
+dfftw_plan_many_dft_
+dfftw_plan_many_dft__
+dfftw_plan_many_dft_c2r_
+dfftw_plan_many_dft_c2r__
+dfftw_plan_many_dft_r2c_
+dfftw_plan_many_dft_r2c__
+dfftw_plan_many_r2r_
+dfftw_plan_many_r2r__
+dfftw_plan_r2r_
+dfftw_plan_r2r__
+dfftw_plan_r2r_1d_
+dfftw_plan_r2r_1d__
+dfftw_plan_r2r_2d_
+dfftw_plan_r2r_2d__
+dfftw_plan_r2r_3d_
+dfftw_plan_r2r_3d__
+dfftw_plan_with_nthreads_
+dfftw_plan_with_nthreads__
+dfftw_print_plan_
+dfftw_print_plan__
+dfftw_set_timelimit_
+dfftw_set_timelimit__
+fftw_alignment_of
+fftw_alloc_complex
+fftw_alloc_real
+fftw_assertion_failed
+fftw_bufdist
+fftw_check_alignment_of_sse2_pm
+fftw_choose_radix
+fftw_cleanup
+fftw_cleanup_threads
+fftw_codelet_e01_8
+fftw_codelet_e10_8
+fftw_codelet_hb_10
+fftw_codelet_hb_12
+fftw_codelet_hb_15
+fftw_codelet_hb_16
+fftw_codelet_hb_2
+fftw_codelet_hb_20
+fftw_codelet_hb2_16
+fftw_codelet_hb2_20
+fftw_codelet_hb2_25
+fftw_codelet_hb2_32
+fftw_codelet_hb2_4
+fftw_codelet_hb_25
+fftw_codelet_hb2_5
+fftw_codelet_hb2_8
+fftw_codelet_hb_3
+fftw_codelet_hb_32
+fftw_codelet_hb_4
+fftw_codelet_hb_5
+fftw_codelet_hb_6
+fftw_codelet_hb_64
+fftw_codelet_hb_7
+fftw_codelet_hb_8
+fftw_codelet_hb_9
+fftw_codelet_hc2cb_10
+fftw_codelet_hc2cb_12
+fftw_codelet_hc2cb_16
+fftw_codelet_hc2cb_2
+fftw_codelet_hc2cb_20
+fftw_codelet_hc2cb2_16
+fftw_codelet_hc2cb2_20
+fftw_codelet_hc2cb2_32
+fftw_codelet_hc2cb2_4
+fftw_codelet_hc2cb2_8
+fftw_codelet_hc2cb_32
+fftw_codelet_hc2cb_4
+fftw_codelet_hc2cb_6
+fftw_codelet_hc2cb_8
+fftw_codelet_hc2cbdft_10
+fftw_codelet_hc2cbdft_12
+fftw_codelet_hc2cbdft_16
+fftw_codelet_hc2cbdft_2
+fftw_codelet_hc2cbdft_20
+fftw_codelet_hc2cbdft2_16
+fftw_codelet_hc2cbdft2_20
+fftw_codelet_hc2cbdft2_32
+fftw_codelet_hc2cbdft2_4
+fftw_codelet_hc2cbdft2_8
+fftw_codelet_hc2cbdft_32
+fftw_codelet_hc2cbdft_4
+fftw_codelet_hc2cbdft_6
+fftw_codelet_hc2cbdft_8
+fftw_codelet_hc2cbdftv_10_avx
+fftw_codelet_hc2cbdftv_10_sse2
+fftw_codelet_hc2cbdftv_12_avx
+fftw_codelet_hc2cbdftv_12_sse2
+fftw_codelet_hc2cbdftv_16_avx
+fftw_codelet_hc2cbdftv_16_sse2
+fftw_codelet_hc2cbdftv_20_avx
+fftw_codelet_hc2cbdftv_20_sse2
+fftw_codelet_hc2cbdftv_2_avx
+fftw_codelet_hc2cbdftv_2_sse2
+fftw_codelet_hc2cbdftv_32_avx
+fftw_codelet_hc2cbdftv_32_sse2
+fftw_codelet_hc2cbdftv_4_avx
+fftw_codelet_hc2cbdftv_4_sse2
+fftw_codelet_hc2cbdftv_6_avx
+fftw_codelet_hc2cbdftv_6_sse2
+fftw_codelet_hc2cbdftv_8_avx
+fftw_codelet_hc2cbdftv_8_sse2
+fftw_codelet_hc2cf_10
+fftw_codelet_hc2cf_12
+fftw_codelet_hc2cf_16
+fftw_codelet_hc2cf_2
+fftw_codelet_hc2cf_20
+fftw_codelet_hc2cf2_16
+fftw_codelet_hc2cf2_20
+fftw_codelet_hc2cf2_32
+fftw_codelet_hc2cf2_4
+fftw_codelet_hc2cf2_8
+fftw_codelet_hc2cf_32
+fftw_codelet_hc2cf_4
+fftw_codelet_hc2cf_6
+fftw_codelet_hc2cf_8
+fftw_codelet_hc2cfdft_10
+fftw_codelet_hc2cfdft_12
+fftw_codelet_hc2cfdft_16
+fftw_codelet_hc2cfdft_2
+fftw_codelet_hc2cfdft_20
+fftw_codelet_hc2cfdft2_16
+fftw_codelet_hc2cfdft2_20
+fftw_codelet_hc2cfdft2_32
+fftw_codelet_hc2cfdft2_4
+fftw_codelet_hc2cfdft2_8
+fftw_codelet_hc2cfdft_32
+fftw_codelet_hc2cfdft_4
+fftw_codelet_hc2cfdft_6
+fftw_codelet_hc2cfdft_8
+fftw_codelet_hc2cfdftv_10_avx
+fftw_codelet_hc2cfdftv_10_sse2
+fftw_codelet_hc2cfdftv_12_avx
+fftw_codelet_hc2cfdftv_12_sse2
+fftw_codelet_hc2cfdftv_16_avx
+fftw_codelet_hc2cfdftv_16_sse2
+fftw_codelet_hc2cfdftv_20_avx
+fftw_codelet_hc2cfdftv_20_sse2
+fftw_codelet_hc2cfdftv_2_avx
+fftw_codelet_hc2cfdftv_2_sse2
+fftw_codelet_hc2cfdftv_32_avx
+fftw_codelet_hc2cfdftv_32_sse2
+fftw_codelet_hc2cfdftv_4_avx
+fftw_codelet_hc2cfdftv_4_sse2
+fftw_codelet_hc2cfdftv_6_avx
+fftw_codelet_hc2cfdftv_6_sse2
+fftw_codelet_hc2cfdftv_8_avx
+fftw_codelet_hc2cfdftv_8_sse2
+fftw_codelet_hf_10
+fftw_codelet_hf_12
+fftw_codelet_hf_15
+fftw_codelet_hf_16
+fftw_codelet_hf_2
+fftw_codelet_hf_20
+fftw_codelet_hf2_16
+fftw_codelet_hf2_20
+fftw_codelet_hf2_25
+fftw_codelet_hf2_32
+fftw_codelet_hf2_4
+fftw_codelet_hf_25
+fftw_codelet_hf2_5
+fftw_codelet_hf2_8
+fftw_codelet_hf_3
+fftw_codelet_hf_32
+fftw_codelet_hf_4
+fftw_codelet_hf_5
+fftw_codelet_hf_6
+fftw_codelet_hf_64
+fftw_codelet_hf_7
+fftw_codelet_hf_8
+fftw_codelet_hf_9
+fftw_codelet_n1_10
+fftw_codelet_n1_11
+fftw_codelet_n1_12
+fftw_codelet_n1_13
+fftw_codelet_n1_14
+fftw_codelet_n1_15
+fftw_codelet_n1_16
+fftw_codelet_n1_2
+fftw_codelet_n1_20
+fftw_codelet_n1_25
+fftw_codelet_n1_3
+fftw_codelet_n1_32
+fftw_codelet_n1_4
+fftw_codelet_n1_5
+fftw_codelet_n1_6
+fftw_codelet_n1_64
+fftw_codelet_n1_7
+fftw_codelet_n1_8
+fftw_codelet_n1_9
+fftw_codelet_n1bv_10_avx
+fftw_codelet_n1bv_10_sse2
+fftw_codelet_n1bv_11_avx
+fftw_codelet_n1bv_11_sse2
+fftw_codelet_n1bv_128_avx
+fftw_codelet_n1bv_128_sse2
+fftw_codelet_n1bv_12_avx
+fftw_codelet_n1bv_12_sse2
+fftw_codelet_n1bv_13_avx
+fftw_codelet_n1bv_13_sse2
+fftw_codelet_n1bv_14_avx
+fftw_codelet_n1bv_14_sse2
+fftw_codelet_n1bv_15_avx
+fftw_codelet_n1bv_15_sse2
+fftw_codelet_n1bv_16_avx
+fftw_codelet_n1bv_16_sse2
+fftw_codelet_n1bv_20_avx
+fftw_codelet_n1bv_20_sse2
+fftw_codelet_n1bv_25_avx
+fftw_codelet_n1bv_25_sse2
+fftw_codelet_n1bv_2_avx
+fftw_codelet_n1bv_2_sse2
+fftw_codelet_n1bv_32_avx
+fftw_codelet_n1bv_32_sse2
+fftw_codelet_n1bv_3_avx
+fftw_codelet_n1bv_3_sse2
+fftw_codelet_n1bv_4_avx
+fftw_codelet_n1bv_4_sse2
+fftw_codelet_n1bv_5_avx
+fftw_codelet_n1bv_5_sse2
+fftw_codelet_n1bv_64_avx
+fftw_codelet_n1bv_64_sse2
+fftw_codelet_n1bv_6_avx
+fftw_codelet_n1bv_6_sse2
+fftw_codelet_n1bv_7_avx
+fftw_codelet_n1bv_7_sse2
+fftw_codelet_n1bv_8_avx
+fftw_codelet_n1bv_8_sse2
+fftw_codelet_n1bv_9_avx
+fftw_codelet_n1bv_9_sse2
+fftw_codelet_n1fv_10_avx
+fftw_codelet_n1fv_10_sse2
+fftw_codelet_n1fv_11_avx
+fftw_codelet_n1fv_11_sse2
+fftw_codelet_n1fv_128_avx
+fftw_codelet_n1fv_128_sse2
+fftw_codelet_n1fv_12_avx
+fftw_codelet_n1fv_12_sse2
+fftw_codelet_n1fv_13_avx
+fftw_codelet_n1fv_13_sse2
+fftw_codelet_n1fv_14_avx
+fftw_codelet_n1fv_14_sse2
+fftw_codelet_n1fv_15_avx
+fftw_codelet_n1fv_15_sse2
+fftw_codelet_n1fv_16_avx
+fftw_codelet_n1fv_16_sse2
+fftw_codelet_n1fv_20_avx
+fftw_codelet_n1fv_20_sse2
+fftw_codelet_n1fv_25_avx
+fftw_codelet_n1fv_25_sse2
+fftw_codelet_n1fv_2_avx
+fftw_codelet_n1fv_2_sse2
+fftw_codelet_n1fv_32_avx
+fftw_codelet_n1fv_32_sse2
+fftw_codelet_n1fv_3_avx
+fftw_codelet_n1fv_3_sse2
+fftw_codelet_n1fv_4_avx
+fftw_codelet_n1fv_4_sse2
+fftw_codelet_n1fv_5_avx
+fftw_codelet_n1fv_5_sse2
+fftw_codelet_n1fv_64_avx
+fftw_codelet_n1fv_64_sse2
+fftw_codelet_n1fv_6_avx
+fftw_codelet_n1fv_6_sse2
+fftw_codelet_n1fv_7_avx
+fftw_codelet_n1fv_7_sse2
+fftw_codelet_n1fv_8_avx
+fftw_codelet_n1fv_8_sse2
+fftw_codelet_n1fv_9_avx
+fftw_codelet_n1fv_9_sse2
+fftw_codelet_n2bv_10_avx
+fftw_codelet_n2bv_10_sse2
+fftw_codelet_n2bv_12_avx
+fftw_codelet_n2bv_12_sse2
+fftw_codelet_n2bv_14_avx
+fftw_codelet_n2bv_14_sse2
+fftw_codelet_n2bv_16_avx
+fftw_codelet_n2bv_16_sse2
+fftw_codelet_n2bv_20_avx
+fftw_codelet_n2bv_20_sse2
+fftw_codelet_n2bv_2_avx
+fftw_codelet_n2bv_2_sse2
+fftw_codelet_n2bv_32_avx
+fftw_codelet_n2bv_32_sse2
+fftw_codelet_n2bv_4_avx
+fftw_codelet_n2bv_4_sse2
+fftw_codelet_n2bv_64_avx
+fftw_codelet_n2bv_64_sse2
+fftw_codelet_n2bv_6_avx
+fftw_codelet_n2bv_6_sse2
+fftw_codelet_n2bv_8_avx
+fftw_codelet_n2bv_8_sse2
+fftw_codelet_n2fv_10_avx
+fftw_codelet_n2fv_10_sse2
+fftw_codelet_n2fv_12_avx
+fftw_codelet_n2fv_12_sse2
+fftw_codelet_n2fv_14_avx
+fftw_codelet_n2fv_14_sse2
+fftw_codelet_n2fv_16_avx
+fftw_codelet_n2fv_16_sse2
+fftw_codelet_n2fv_20_avx
+fftw_codelet_n2fv_20_sse2
+fftw_codelet_n2fv_2_avx
+fftw_codelet_n2fv_2_sse2
+fftw_codelet_n2fv_32_avx
+fftw_codelet_n2fv_32_sse2
+fftw_codelet_n2fv_4_avx
+fftw_codelet_n2fv_4_sse2
+fftw_codelet_n2fv_64_avx
+fftw_codelet_n2fv_64_sse2
+fftw_codelet_n2fv_6_avx
+fftw_codelet_n2fv_6_sse2
+fftw_codelet_n2fv_8_avx
+fftw_codelet_n2fv_8_sse2
+fftw_codelet_n2sv_16_avx
+fftw_codelet_n2sv_16_sse2
+fftw_codelet_n2sv_32_avx
+fftw_codelet_n2sv_32_sse2
+fftw_codelet_n2sv_4_avx
+fftw_codelet_n2sv_4_sse2
+fftw_codelet_n2sv_64_avx
+fftw_codelet_n2sv_64_sse2
+fftw_codelet_n2sv_8_avx
+fftw_codelet_n2sv_8_sse2
+fftw_codelet_q1_2
+fftw_codelet_q1_3
+fftw_codelet_q1_4
+fftw_codelet_q1_5
+fftw_codelet_q1_6
+fftw_codelet_q1_8
+fftw_codelet_q1bv_2_avx
+fftw_codelet_q1bv_2_sse2
+fftw_codelet_q1bv_4_avx
+fftw_codelet_q1bv_4_sse2
+fftw_codelet_q1bv_5_avx
+fftw_codelet_q1bv_5_sse2
+fftw_codelet_q1bv_8_avx
+fftw_codelet_q1bv_8_sse2
+fftw_codelet_q1fv_2_avx
+fftw_codelet_q1fv_2_sse2
+fftw_codelet_q1fv_4_avx
+fftw_codelet_q1fv_4_sse2
+fftw_codelet_q1fv_5_avx
+fftw_codelet_q1fv_5_sse2
+fftw_codelet_q1fv_8_avx
+fftw_codelet_q1fv_8_sse2
+fftw_codelet_r2cb_10
+fftw_codelet_r2cb_11
+fftw_codelet_r2cb_12
+fftw_codelet_r2cb_128
+fftw_codelet_r2cb_13
+fftw_codelet_r2cb_14
+fftw_codelet_r2cb_15
+fftw_codelet_r2cb_16
+fftw_codelet_r2cb_2
+fftw_codelet_r2cb_20
+fftw_codelet_r2cb_25
+fftw_codelet_r2cb_3
+fftw_codelet_r2cb_32
+fftw_codelet_r2cb_4
+fftw_codelet_r2cb_5
+fftw_codelet_r2cb_6
+fftw_codelet_r2cb_64
+fftw_codelet_r2cb_7
+fftw_codelet_r2cb_8
+fftw_codelet_r2cb_9
+fftw_codelet_r2cbIII_10
+fftw_codelet_r2cbIII_12
+fftw_codelet_r2cbIII_15
+fftw_codelet_r2cbIII_16
+fftw_codelet_r2cbIII_2
+fftw_codelet_r2cbIII_20
+fftw_codelet_r2cbIII_25
+fftw_codelet_r2cbIII_3
+fftw_codelet_r2cbIII_32
+fftw_codelet_r2cbIII_4
+fftw_codelet_r2cbIII_5
+fftw_codelet_r2cbIII_6
+fftw_codelet_r2cbIII_64
+fftw_codelet_r2cbIII_7
+fftw_codelet_r2cbIII_8
+fftw_codelet_r2cbIII_9
+fftw_codelet_r2cf_10
+fftw_codelet_r2cf_11
+fftw_codelet_r2cf_12
+fftw_codelet_r2cf_128
+fftw_codelet_r2cf_13
+fftw_codelet_r2cf_14
+fftw_codelet_r2cf_15
+fftw_codelet_r2cf_16
+fftw_codelet_r2cf_2
+fftw_codelet_r2cf_20
+fftw_codelet_r2cf_25
+fftw_codelet_r2cf_3
+fftw_codelet_r2cf_32
+fftw_codelet_r2cf_4
+fftw_codelet_r2cf_5
+fftw_codelet_r2cf_6
+fftw_codelet_r2cf_64
+fftw_codelet_r2cf_7
+fftw_codelet_r2cf_8
+fftw_codelet_r2cf_9
+fftw_codelet_r2cfII_10
+fftw_codelet_r2cfII_12
+fftw_codelet_r2cfII_15
+fftw_codelet_r2cfII_16
+fftw_codelet_r2cfII_2
+fftw_codelet_r2cfII_20
+fftw_codelet_r2cfII_25
+fftw_codelet_r2cfII_3
+fftw_codelet_r2cfII_32
+fftw_codelet_r2cfII_4
+fftw_codelet_r2cfII_5
+fftw_codelet_r2cfII_6
+fftw_codelet_r2cfII_64
+fftw_codelet_r2cfII_7
+fftw_codelet_r2cfII_8
+fftw_codelet_r2cfII_9
+fftw_codelet_t1_10
+fftw_codelet_t1_12
+fftw_codelet_t1_15
+fftw_codelet_t1_16
+fftw_codelet_t1_2
+fftw_codelet_t1_20
+fftw_codelet_t1_25
+fftw_codelet_t1_3
+fftw_codelet_t1_32
+fftw_codelet_t1_4
+fftw_codelet_t1_5
+fftw_codelet_t1_6
+fftw_codelet_t1_64
+fftw_codelet_t1_7
+fftw_codelet_t1_8
+fftw_codelet_t1_9
+fftw_codelet_t1buv_10_avx
+fftw_codelet_t1buv_10_sse2
+fftw_codelet_t1buv_2_avx
+fftw_codelet_t1buv_2_sse2
+fftw_codelet_t1buv_3_avx
+fftw_codelet_t1buv_3_sse2
+fftw_codelet_t1buv_4_avx
+fftw_codelet_t1buv_4_sse2
+fftw_codelet_t1buv_5_avx
+fftw_codelet_t1buv_5_sse2
+fftw_codelet_t1buv_6_avx
+fftw_codelet_t1buv_6_sse2
+fftw_codelet_t1buv_7_avx
+fftw_codelet_t1buv_7_sse2
+fftw_codelet_t1buv_8_avx
+fftw_codelet_t1buv_8_sse2
+fftw_codelet_t1buv_9_avx
+fftw_codelet_t1buv_9_sse2
+fftw_codelet_t1bv_10_avx
+fftw_codelet_t1bv_10_sse2
+fftw_codelet_t1bv_12_avx
+fftw_codelet_t1bv_12_sse2
+fftw_codelet_t1bv_15_avx
+fftw_codelet_t1bv_15_sse2
+fftw_codelet_t1bv_16_avx
+fftw_codelet_t1bv_16_sse2
+fftw_codelet_t1bv_20_avx
+fftw_codelet_t1bv_20_sse2
+fftw_codelet_t1bv_25_avx
+fftw_codelet_t1bv_25_sse2
+fftw_codelet_t1bv_2_avx
+fftw_codelet_t1bv_2_sse2
+fftw_codelet_t1bv_32_avx
+fftw_codelet_t1bv_32_sse2
+fftw_codelet_t1bv_3_avx
+fftw_codelet_t1bv_3_sse2
+fftw_codelet_t1bv_4_avx
+fftw_codelet_t1bv_4_sse2
+fftw_codelet_t1bv_5_avx
+fftw_codelet_t1bv_5_sse2
+fftw_codelet_t1bv_64_avx
+fftw_codelet_t1bv_64_sse2
+fftw_codelet_t1bv_6_avx
+fftw_codelet_t1bv_6_sse2
+fftw_codelet_t1bv_7_avx
+fftw_codelet_t1bv_7_sse2
+fftw_codelet_t1bv_8_avx
+fftw_codelet_t1bv_8_sse2
+fftw_codelet_t1bv_9_avx
+fftw_codelet_t1bv_9_sse2
+fftw_codelet_t1fuv_10_avx
+fftw_codelet_t1fuv_10_sse2
+fftw_codelet_t1fuv_2_avx
+fftw_codelet_t1fuv_2_sse2
+fftw_codelet_t1fuv_3_avx
+fftw_codelet_t1fuv_3_sse2
+fftw_codelet_t1fuv_4_avx
+fftw_codelet_t1fuv_4_sse2
+fftw_codelet_t1fuv_5_avx
+fftw_codelet_t1fuv_5_sse2
+fftw_codelet_t1fuv_6_avx
+fftw_codelet_t1fuv_6_sse2
+fftw_codelet_t1fuv_7_avx
+fftw_codelet_t1fuv_7_sse2
+fftw_codelet_t1fuv_8_avx
+fftw_codelet_t1fuv_8_sse2
+fftw_codelet_t1fuv_9_avx
+fftw_codelet_t1fuv_9_sse2
+fftw_codelet_t1fv_10_avx
+fftw_codelet_t1fv_10_sse2
+fftw_codelet_t1fv_12_avx
+fftw_codelet_t1fv_12_sse2
+fftw_codelet_t1fv_15_avx
+fftw_codelet_t1fv_15_sse2
+fftw_codelet_t1fv_16_avx
+fftw_codelet_t1fv_16_sse2
+fftw_codelet_t1fv_20_avx
+fftw_codelet_t1fv_20_sse2
+fftw_codelet_t1fv_25_avx
+fftw_codelet_t1fv_25_sse2
+fftw_codelet_t1fv_2_avx
+fftw_codelet_t1fv_2_sse2
+fftw_codelet_t1fv_32_avx
+fftw_codelet_t1fv_32_sse2
+fftw_codelet_t1fv_3_avx
+fftw_codelet_t1fv_3_sse2
+fftw_codelet_t1fv_4_avx
+fftw_codelet_t1fv_4_sse2
+fftw_codelet_t1fv_5_avx
+fftw_codelet_t1fv_5_sse2
+fftw_codelet_t1fv_64_avx
+fftw_codelet_t1fv_64_sse2
+fftw_codelet_t1fv_6_avx
+fftw_codelet_t1fv_6_sse2
+fftw_codelet_t1fv_7_avx
+fftw_codelet_t1fv_7_sse2
+fftw_codelet_t1fv_8_avx
+fftw_codelet_t1fv_8_sse2
+fftw_codelet_t1fv_9_avx
+fftw_codelet_t1fv_9_sse2
+fftw_codelet_t1sv_16_avx
+fftw_codelet_t1sv_16_sse2
+fftw_codelet_t1sv_2_avx
+fftw_codelet_t1sv_2_sse2
+fftw_codelet_t1sv_32_avx
+fftw_codelet_t1sv_32_sse2
+fftw_codelet_t1sv_4_avx
+fftw_codelet_t1sv_4_sse2
+fftw_codelet_t1sv_8_avx
+fftw_codelet_t1sv_8_sse2
+fftw_codelet_t2_10
+fftw_codelet_t2_16
+fftw_codelet_t2_20
+fftw_codelet_t2_25
+fftw_codelet_t2_32
+fftw_codelet_t2_4
+fftw_codelet_t2_5
+fftw_codelet_t2_64
+fftw_codelet_t2_8
+fftw_codelet_t2bv_10_avx
+fftw_codelet_t2bv_10_sse2
+fftw_codelet_t2bv_16_avx
+fftw_codelet_t2bv_16_sse2
+fftw_codelet_t2bv_20_avx
+fftw_codelet_t2bv_20_sse2
+fftw_codelet_t2bv_25_avx
+fftw_codelet_t2bv_25_sse2
+fftw_codelet_t2bv_2_avx
+fftw_codelet_t2bv_2_sse2
+fftw_codelet_t2bv_32_avx
+fftw_codelet_t2bv_32_sse2
+fftw_codelet_t2bv_4_avx
+fftw_codelet_t2bv_4_sse2
+fftw_codelet_t2bv_5_avx
+fftw_codelet_t2bv_5_sse2
+fftw_codelet_t2bv_64_avx
+fftw_codelet_t2bv_64_sse2
+fftw_codelet_t2bv_8_avx
+fftw_codelet_t2bv_8_sse2
+fftw_codelet_t2fv_10_avx
+fftw_codelet_t2fv_10_sse2
+fftw_codelet_t2fv_16_avx
+fftw_codelet_t2fv_16_sse2
+fftw_codelet_t2fv_20_avx
+fftw_codelet_t2fv_20_sse2
+fftw_codelet_t2fv_25_avx
+fftw_codelet_t2fv_25_sse2
+fftw_codelet_t2fv_2_avx
+fftw_codelet_t2fv_2_sse2
+fftw_codelet_t2fv_32_avx
+fftw_codelet_t2fv_32_sse2
+fftw_codelet_t2fv_4_avx
+fftw_codelet_t2fv_4_sse2
+fftw_codelet_t2fv_5_avx
+fftw_codelet_t2fv_5_sse2
+fftw_codelet_t2fv_64_avx
+fftw_codelet_t2fv_64_sse2
+fftw_codelet_t2fv_8_avx
+fftw_codelet_t2fv_8_sse2
+fftw_codelet_t2sv_16_avx
+fftw_codelet_t2sv_16_sse2
+fftw_codelet_t2sv_32_avx
+fftw_codelet_t2sv_32_sse2
+fftw_codelet_t2sv_4_avx
+fftw_codelet_t2sv_4_sse2
+fftw_codelet_t2sv_8_avx
+fftw_codelet_t2sv_8_sse2
+fftw_codelet_t3bv_10_avx
+fftw_codelet_t3bv_10_sse2
+fftw_codelet_t3bv_16_avx
+fftw_codelet_t3bv_16_sse2
+fftw_codelet_t3bv_20_avx
+fftw_codelet_t3bv_20_sse2
+fftw_codelet_t3bv_25_avx
+fftw_codelet_t3bv_25_sse2
+fftw_codelet_t3bv_32_avx
+fftw_codelet_t3bv_32_sse2
+fftw_codelet_t3bv_4_avx
+fftw_codelet_t3bv_4_sse2
+fftw_codelet_t3bv_5_avx
+fftw_codelet_t3bv_5_sse2
+fftw_codelet_t3bv_8_avx
+fftw_codelet_t3bv_8_sse2
+fftw_codelet_t3fv_10_avx
+fftw_codelet_t3fv_10_sse2
+fftw_codelet_t3fv_16_avx
+fftw_codelet_t3fv_16_sse2
+fftw_codelet_t3fv_20_avx
+fftw_codelet_t3fv_20_sse2
+fftw_codelet_t3fv_25_avx
+fftw_codelet_t3fv_25_sse2
+fftw_codelet_t3fv_32_avx
+fftw_codelet_t3fv_32_sse2
+fftw_codelet_t3fv_4_avx
+fftw_codelet_t3fv_4_sse2
+fftw_codelet_t3fv_5_avx
+fftw_codelet_t3fv_5_sse2
+fftw_codelet_t3fv_8_avx
+fftw_codelet_t3fv_8_sse2
+fftw_compute_tilesz
+fftw_configure_planner
+fftw_cost
+fftw_cpy1d
+fftw_cpy2d
+fftw_cpy2d_ci
+fftw_cpy2d_co
+fftw_cpy2d_pair
+fftw_cpy2d_pair_ci
+fftw_cpy2d_pair_co
+fftw_cpy2d_tiled
+fftw_cpy2d_tiledbuf
+fftw_ct_applicable
+fftw_ct_genericbuf_register
+fftw_ct_generic_register
+fftw_ct_uglyp
+fftw_destroy_plan
+fftw_dft_bluestein_register
+fftw_dft_buffered_register
+fftw_dft_conf_standard
+fftw_dft_generic_register
+fftw_dft_indirect_register
+fftw_dft_indirect_transpose_register
+fftw_dft_nop_register
+fftw_dft_r2hc_register
+fftw_dft_rader_register
+fftw_dft_rank_geq2_register
+fftw_dft_solve
+fftw_dft_thr_vrank_geq1_register
+fftw_dft_vrank_geq1_register
+fftw_dft_zerotens
+fftw_dht_r2hc_register
+fftw_dht_rader_register
+fftw_dimcmp
+fftw_elapsed_since
+fftw_estimate_cost
+fftw_execute
+fftw_execute_dft
+fftw_execute_dft_c2r
+fftw_execute_dft_r2c
+fftw_execute_r2r
+fftw_execute_split_dft
+fftw_execute_split_dft_c2r
+fftw_execute_split_dft_r2c
+fftw_export_wisdom
+fftw_export_wisdom_to_file
+fftw_export_wisdom_to_filename
+fftw_export_wisdom_to_string
+fftw_extract_reim
+fftw_factors_into
+fftw_factors_into_small_primes
+fftw_find_generator
+fftw_first_divisor
+fftw_flops
+fftw_forget_wisdom
+fftw_fprint_plan
+fftw_free
+fftw_get_crude_time
+fftw_guru64_kosherp
+fftw_guru_kosherp
+fftw_hash
+fftw_have_simd_avx
+fftw_have_simd_sse2
+fftw_hc2hc_applicable
+fftw_hc2hc_generic_register
+fftw_iabs
+fftw_ialignment_of
+fftw_iestimate_cost
+fftw_ifree
+fftw_ifree0
+fftw_imax
+fftw_imin
+fftw_import_system_wisdom
+fftw_import_wisdom
+fftw_import_wisdom_from_file
+fftw_import_wisdom_from_filename
+fftw_import_wisdom_from_string
+fftw_init_threads
+fftw_is_prime
+fftw_isqrt
+fftw_ithreads_init
+fftw_join_taint
+fftw_kdft_dif_register
+fftw_kdft_difsq_register
+fftw_kdft_dit_register
+fftw_kdft_register
+fftw_kernel_free
+fftw_kernel_malloc
+fftw_khc2c_register
+fftw_khc2hc_register
+fftw_kr2c_register
+fftw_kr2r_register
+fftw_make_planner_thread_safe
+fftw_malloc
+fftw_malloc_plain
+fftw_many_kosherp
+fftw_mapflags
+fftw_map_r2r_kind
+fftw_md5begin
+fftw_md5end
+fftw_md5int
+fftw_md5INT
+fftw_md5putb
+fftw_md5putc
+fftw_md5puts
+fftw_md5unsigned
+fftw_measure_execution_time
+fftw_mkapiplan
+fftw_mkplan
+fftw_mkplan_d
+fftw_mkplan_dft
+fftw_mkplan_dftw
+fftw_mkplan_f_d
+fftw_mkplan_hc2c
+fftw_mkplan_hc2hc
+fftw_mkplanner
+fftw_mkplan_rdft
+fftw_mkplan_rdft2
+fftw_mkprinter
+fftw_mkprinter_cnt
+fftw_mkprinter_file
+fftw_mkprinter_str
+fftw_mkproblem
+fftw_mkproblem_dft
+fftw_mkproblem_dft_d
+fftw_mkproblem_rdft
+fftw_mkproblem_rdft_0_d
+fftw_mkproblem_rdft_1
+fftw_mkproblem_rdft_1_d
+fftw_mkproblem_rdft2
+fftw_mkproblem_rdft2_d
+fftw_mkproblem_rdft2_d_3pointers
+fftw_mkproblem_rdft_d
+fftw_mkproblem_unsolvable
+fftw_mkscanner
+fftw_mksolver
+fftw_mksolver_ct
+fftw_mksolver_ct_threads
+fftw_mksolver_dft_direct
+fftw_mksolver_dft_directbuf
+fftw_mksolver_hc2c
+fftw_mksolver_hc2hc
+fftw_mksolver_hc2hc_threads
+fftw_mksolver_rdft2_direct
+fftw_mksolver_rdft_r2c_direct
+fftw_mksolver_rdft_r2c_directbuf
+fftw_mksolver_rdft_r2r_direct
+fftw_mkstride
+fftw_mktensor
+fftw_mktensor_0d
+fftw_mktensor_1d
+fftw_mktensor_2d
+fftw_mktensor_3d
+fftw_mktensor_4d
+fftw_mktensor_5d
+fftw_mktensor_iodims
+fftw_mktensor_iodims64
+fftw_mktensor_rowmajor
+fftw_mktriggen
+fftw_modulo
+fftw_nbuf
+fftw_nbuf_redundant
+fftw_next_prime
+fftw_null_awake
+fftw_ops_add
+fftw_ops_add2
+fftw_ops_cpy
+fftw_ops_madd
+fftw_ops_madd2
+fftw_ops_other
+fftw_ops_zero
+fftw_pickdim
+fftw_plan_awake
+fftw_plan_destroy_internal
+fftw_plan_dft
+fftw_plan_dft_1d
+fftw_plan_dft_2d
+fftw_plan_dft_3d
+fftw_plan_dft_c2r
+fftw_plan_dft_c2r_1d
+fftw_plan_dft_c2r_2d
+fftw_plan_dft_c2r_3d
+fftw_plan_dft_r2c
+fftw_plan_dft_r2c_1d
+fftw_plan_dft_r2c_2d
+fftw_plan_dft_r2c_3d
+fftw_plan_guru64_dft
+fftw_plan_guru64_dft_c2r
+fftw_plan_guru64_dft_r2c
+fftw_plan_guru64_r2r
+fftw_plan_guru64_split_dft
+fftw_plan_guru64_split_dft_c2r
+fftw_plan_guru64_split_dft_r2c
+fftw_plan_guru_dft
+fftw_plan_guru_dft_c2r
+fftw_plan_guru_dft_r2c
+fftw_plan_guru_r2r
+fftw_plan_guru_split_dft
+fftw_plan_guru_split_dft_c2r
+fftw_plan_guru_split_dft_r2c
+fftw_plan_many_dft
+fftw_plan_many_dft_c2r
+fftw_plan_many_dft_r2c
+fftw_plan_many_r2r
+fftw_planner_destroy
+fftw_plan_null_destroy
+fftw_plan_r2r
+fftw_plan_r2r_1d
+fftw_plan_r2r_2d
+fftw_plan_r2r_3d
+fftw_plan_with_nthreads
+fftw_power_mod
+fftw_printer_destroy
+fftw_print_plan
+fftw_problem_destroy
+fftw_rader_tl_delete
+fftw_rader_tl_find
+fftw_rader_tl_insert
+fftw_rdft2_buffered_register
+fftw_rdft2_complex_n
+fftw_rdft2_inplace_strides
+fftw_rdft2_nop_register
+fftw_rdft2_pad
+fftw_rdft2_rank0_register
+fftw_rdft2_rank_geq2_register
+fftw_rdft2_rdft_register
+fftw_rdft2_solve
+fftw_rdft2_strides
+fftw_rdft2_tensor_max_index
+fftw_rdft2_thr_vrank_geq1_register
+fftw_rdft2_vrank_geq1_register
+fftw_rdft_buffered_register
+fftw_rdft_conf_standard
+fftw_rdft_dht_register
+fftw_rdft_generic_register
+fftw_rdft_indirect_register
+fftw_rdft_kind_str
+fftw_rdft_nop_register
+fftw_rdft_rank0_register
+fftw_rdft_rank_geq2_register
+fftw_rdft_solve
+fftw_rdft_thr_vrank_geq1_register
+fftw_rdft_vrank3_transpose_register
+fftw_rdft_vrank_geq1_register
+fftw_rdft_zerotens
+fftw_redft00e_r2hc_pad_register
+fftw_regsolver_ct_directw
+fftw_regsolver_ct_directwsq
+fftw_regsolver_hc2c_direct
+fftw_regsolver_hc2hc_direct
+fftw_reodft00e_splitradix_register
+fftw_reodft010e_r2hc_register
+fftw_reodft11e_r2hc_odd_register
+fftw_reodft11e_radix2_r2hc_register
+fftw_reodft_conf_standard
+fftw_rodft00e_r2hc_pad_register
+fftw_safe_mulmod
+fftw_scanner_destroy
+fftw_set_planner_hooks
+fftw_set_timelimit
+fftw_solver_destroy
+fftw_solver_register
+fftw_solver_use
+fftw_solvtab_exec
+fftw_spawn_loop
+fftw_sprint_plan
+fftw_stride_destroy
+fftw_taint
+fftw_tensor_append
+fftw_tensor_compress
+fftw_tensor_compress_contiguous
+fftw_tensor_copy
+fftw_tensor_copy_except
+fftw_tensor_copy_inplace
+fftw_tensor_copy_sub
+fftw_tensor_destroy
+fftw_tensor_destroy2
+fftw_tensor_destroy4
+fftw_tensor_equal
+fftw_tensor_inplace_locations
+fftw_tensor_inplace_strides
+fftw_tensor_inplace_strides2
+fftw_tensor_kosherp
+fftw_tensor_max_index
+fftw_tensor_md5
+fftw_tensor_min_istride
+fftw_tensor_min_ostride
+fftw_tensor_min_stride
+fftw_tensor_print
+fftw_tensor_split
+fftw_tensor_strides_decrease
+fftw_tensor_sz
+fftw_tensor_tornk1
+fftw_the_planner
+fftw_threads_cleanup
+fftw_threads_conf_standard
+fftw_threads_register_planner_hooks
+fftw_tile2d
+fftw_toobig
+fftw_transpose
+fftw_transpose_tiled
+fftw_transpose_tiledbuf
+fftw_triggen_destroy
+fftw_twiddle_awake
+fftw_twiddle_length
+fftw_zero1d_pair
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.exp b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.exp
new file mode 100644
index 0000000..9ab00ba
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.exp
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.lib b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.lib
new file mode 100644
index 0000000..48c4af9
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3-3.lib
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.def b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.def
new file mode 100644
index 0000000..d61a2c3
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.def
@@ -0,0 +1,1017 @@
+LIBRARY libfftw3f-3.dll
+EXPORTS
+fftwf_alignment_of
+fftwf_alloc_complex
+fftwf_alloc_real
+fftwf_assertion_failed
+fftwf_bufdist
+fftwf_check_alignment_of_sse2_pm
+fftwf_choose_radix
+fftwf_cleanup
+fftwf_cleanup_threads
+fftwf_codelet_e01_8
+fftwf_codelet_e10_8
+fftwf_codelet_hb_10
+fftwf_codelet_hb_12
+fftwf_codelet_hb_15
+fftwf_codelet_hb_16
+fftwf_codelet_hb_2
+fftwf_codelet_hb_20
+fftwf_codelet_hb2_16
+fftwf_codelet_hb2_20
+fftwf_codelet_hb2_25
+fftwf_codelet_hb2_32
+fftwf_codelet_hb2_4
+fftwf_codelet_hb_25
+fftwf_codelet_hb2_5
+fftwf_codelet_hb2_8
+fftwf_codelet_hb_3
+fftwf_codelet_hb_32
+fftwf_codelet_hb_4
+fftwf_codelet_hb_5
+fftwf_codelet_hb_6
+fftwf_codelet_hb_64
+fftwf_codelet_hb_7
+fftwf_codelet_hb_8
+fftwf_codelet_hb_9
+fftwf_codelet_hc2cb_10
+fftwf_codelet_hc2cb_12
+fftwf_codelet_hc2cb_16
+fftwf_codelet_hc2cb_2
+fftwf_codelet_hc2cb_20
+fftwf_codelet_hc2cb2_16
+fftwf_codelet_hc2cb2_20
+fftwf_codelet_hc2cb2_32
+fftwf_codelet_hc2cb2_4
+fftwf_codelet_hc2cb2_8
+fftwf_codelet_hc2cb_32
+fftwf_codelet_hc2cb_4
+fftwf_codelet_hc2cb_6
+fftwf_codelet_hc2cb_8
+fftwf_codelet_hc2cbdft_10
+fftwf_codelet_hc2cbdft_12
+fftwf_codelet_hc2cbdft_16
+fftwf_codelet_hc2cbdft_2
+fftwf_codelet_hc2cbdft_20
+fftwf_codelet_hc2cbdft2_16
+fftwf_codelet_hc2cbdft2_20
+fftwf_codelet_hc2cbdft2_32
+fftwf_codelet_hc2cbdft2_4
+fftwf_codelet_hc2cbdft2_8
+fftwf_codelet_hc2cbdft_32
+fftwf_codelet_hc2cbdft_4
+fftwf_codelet_hc2cbdft_6
+fftwf_codelet_hc2cbdft_8
+fftwf_codelet_hc2cbdftv_10_avx
+fftwf_codelet_hc2cbdftv_10_sse2
+fftwf_codelet_hc2cbdftv_12_avx
+fftwf_codelet_hc2cbdftv_12_sse2
+fftwf_codelet_hc2cbdftv_16_avx
+fftwf_codelet_hc2cbdftv_16_sse2
+fftwf_codelet_hc2cbdftv_20_avx
+fftwf_codelet_hc2cbdftv_20_sse2
+fftwf_codelet_hc2cbdftv_2_avx
+fftwf_codelet_hc2cbdftv_2_sse2
+fftwf_codelet_hc2cbdftv_32_avx
+fftwf_codelet_hc2cbdftv_32_sse2
+fftwf_codelet_hc2cbdftv_4_avx
+fftwf_codelet_hc2cbdftv_4_sse2
+fftwf_codelet_hc2cbdftv_6_avx
+fftwf_codelet_hc2cbdftv_6_sse2
+fftwf_codelet_hc2cbdftv_8_avx
+fftwf_codelet_hc2cbdftv_8_sse2
+fftwf_codelet_hc2cf_10
+fftwf_codelet_hc2cf_12
+fftwf_codelet_hc2cf_16
+fftwf_codelet_hc2cf_2
+fftwf_codelet_hc2cf_20
+fftwf_codelet_hc2cf2_16
+fftwf_codelet_hc2cf2_20
+fftwf_codelet_hc2cf2_32
+fftwf_codelet_hc2cf2_4
+fftwf_codelet_hc2cf2_8
+fftwf_codelet_hc2cf_32
+fftwf_codelet_hc2cf_4
+fftwf_codelet_hc2cf_6
+fftwf_codelet_hc2cf_8
+fftwf_codelet_hc2cfdft_10
+fftwf_codelet_hc2cfdft_12
+fftwf_codelet_hc2cfdft_16
+fftwf_codelet_hc2cfdft_2
+fftwf_codelet_hc2cfdft_20
+fftwf_codelet_hc2cfdft2_16
+fftwf_codelet_hc2cfdft2_20
+fftwf_codelet_hc2cfdft2_32
+fftwf_codelet_hc2cfdft2_4
+fftwf_codelet_hc2cfdft2_8
+fftwf_codelet_hc2cfdft_32
+fftwf_codelet_hc2cfdft_4
+fftwf_codelet_hc2cfdft_6
+fftwf_codelet_hc2cfdft_8
+fftwf_codelet_hc2cfdftv_10_avx
+fftwf_codelet_hc2cfdftv_10_sse2
+fftwf_codelet_hc2cfdftv_12_avx
+fftwf_codelet_hc2cfdftv_12_sse2
+fftwf_codelet_hc2cfdftv_16_avx
+fftwf_codelet_hc2cfdftv_16_sse2
+fftwf_codelet_hc2cfdftv_20_avx
+fftwf_codelet_hc2cfdftv_20_sse2
+fftwf_codelet_hc2cfdftv_2_avx
+fftwf_codelet_hc2cfdftv_2_sse2
+fftwf_codelet_hc2cfdftv_32_avx
+fftwf_codelet_hc2cfdftv_32_sse2
+fftwf_codelet_hc2cfdftv_4_avx
+fftwf_codelet_hc2cfdftv_4_sse2
+fftwf_codelet_hc2cfdftv_6_avx
+fftwf_codelet_hc2cfdftv_6_sse2
+fftwf_codelet_hc2cfdftv_8_avx
+fftwf_codelet_hc2cfdftv_8_sse2
+fftwf_codelet_hf_10
+fftwf_codelet_hf_12
+fftwf_codelet_hf_15
+fftwf_codelet_hf_16
+fftwf_codelet_hf_2
+fftwf_codelet_hf_20
+fftwf_codelet_hf2_16
+fftwf_codelet_hf2_20
+fftwf_codelet_hf2_25
+fftwf_codelet_hf2_32
+fftwf_codelet_hf2_4
+fftwf_codelet_hf_25
+fftwf_codelet_hf2_5
+fftwf_codelet_hf2_8
+fftwf_codelet_hf_3
+fftwf_codelet_hf_32
+fftwf_codelet_hf_4
+fftwf_codelet_hf_5
+fftwf_codelet_hf_6
+fftwf_codelet_hf_64
+fftwf_codelet_hf_7
+fftwf_codelet_hf_8
+fftwf_codelet_hf_9
+fftwf_codelet_n1_10
+fftwf_codelet_n1_11
+fftwf_codelet_n1_12
+fftwf_codelet_n1_13
+fftwf_codelet_n1_14
+fftwf_codelet_n1_15
+fftwf_codelet_n1_16
+fftwf_codelet_n1_2
+fftwf_codelet_n1_20
+fftwf_codelet_n1_25
+fftwf_codelet_n1_3
+fftwf_codelet_n1_32
+fftwf_codelet_n1_4
+fftwf_codelet_n1_5
+fftwf_codelet_n1_6
+fftwf_codelet_n1_64
+fftwf_codelet_n1_7
+fftwf_codelet_n1_8
+fftwf_codelet_n1_9
+fftwf_codelet_n1bv_10_avx
+fftwf_codelet_n1bv_10_sse2
+fftwf_codelet_n1bv_11_avx
+fftwf_codelet_n1bv_11_sse2
+fftwf_codelet_n1bv_128_avx
+fftwf_codelet_n1bv_128_sse2
+fftwf_codelet_n1bv_12_avx
+fftwf_codelet_n1bv_12_sse2
+fftwf_codelet_n1bv_13_avx
+fftwf_codelet_n1bv_13_sse2
+fftwf_codelet_n1bv_14_avx
+fftwf_codelet_n1bv_14_sse2
+fftwf_codelet_n1bv_15_avx
+fftwf_codelet_n1bv_15_sse2
+fftwf_codelet_n1bv_16_avx
+fftwf_codelet_n1bv_16_sse2
+fftwf_codelet_n1bv_20_avx
+fftwf_codelet_n1bv_20_sse2
+fftwf_codelet_n1bv_25_avx
+fftwf_codelet_n1bv_25_sse2
+fftwf_codelet_n1bv_2_avx
+fftwf_codelet_n1bv_2_sse2
+fftwf_codelet_n1bv_32_avx
+fftwf_codelet_n1bv_32_sse2
+fftwf_codelet_n1bv_3_avx
+fftwf_codelet_n1bv_3_sse2
+fftwf_codelet_n1bv_4_avx
+fftwf_codelet_n1bv_4_sse2
+fftwf_codelet_n1bv_5_avx
+fftwf_codelet_n1bv_5_sse2
+fftwf_codelet_n1bv_64_avx
+fftwf_codelet_n1bv_64_sse2
+fftwf_codelet_n1bv_6_avx
+fftwf_codelet_n1bv_6_sse2
+fftwf_codelet_n1bv_7_avx
+fftwf_codelet_n1bv_7_sse2
+fftwf_codelet_n1bv_8_avx
+fftwf_codelet_n1bv_8_sse2
+fftwf_codelet_n1bv_9_avx
+fftwf_codelet_n1bv_9_sse2
+fftwf_codelet_n1fv_10_avx
+fftwf_codelet_n1fv_10_sse2
+fftwf_codelet_n1fv_11_avx
+fftwf_codelet_n1fv_11_sse2
+fftwf_codelet_n1fv_128_avx
+fftwf_codelet_n1fv_128_sse2
+fftwf_codelet_n1fv_12_avx
+fftwf_codelet_n1fv_12_sse2
+fftwf_codelet_n1fv_13_avx
+fftwf_codelet_n1fv_13_sse2
+fftwf_codelet_n1fv_14_avx
+fftwf_codelet_n1fv_14_sse2
+fftwf_codelet_n1fv_15_avx
+fftwf_codelet_n1fv_15_sse2
+fftwf_codelet_n1fv_16_avx
+fftwf_codelet_n1fv_16_sse2
+fftwf_codelet_n1fv_20_avx
+fftwf_codelet_n1fv_20_sse2
+fftwf_codelet_n1fv_25_avx
+fftwf_codelet_n1fv_25_sse2
+fftwf_codelet_n1fv_2_avx
+fftwf_codelet_n1fv_2_sse2
+fftwf_codelet_n1fv_32_avx
+fftwf_codelet_n1fv_32_sse2
+fftwf_codelet_n1fv_3_avx
+fftwf_codelet_n1fv_3_sse2
+fftwf_codelet_n1fv_4_avx
+fftwf_codelet_n1fv_4_sse2
+fftwf_codelet_n1fv_5_avx
+fftwf_codelet_n1fv_5_sse2
+fftwf_codelet_n1fv_64_avx
+fftwf_codelet_n1fv_64_sse2
+fftwf_codelet_n1fv_6_avx
+fftwf_codelet_n1fv_6_sse2
+fftwf_codelet_n1fv_7_avx
+fftwf_codelet_n1fv_7_sse2
+fftwf_codelet_n1fv_8_avx
+fftwf_codelet_n1fv_8_sse2
+fftwf_codelet_n1fv_9_avx
+fftwf_codelet_n1fv_9_sse2
+fftwf_codelet_n2bv_10_avx
+fftwf_codelet_n2bv_10_sse2
+fftwf_codelet_n2bv_12_avx
+fftwf_codelet_n2bv_12_sse2
+fftwf_codelet_n2bv_14_avx
+fftwf_codelet_n2bv_14_sse2
+fftwf_codelet_n2bv_16_avx
+fftwf_codelet_n2bv_16_sse2
+fftwf_codelet_n2bv_20_avx
+fftwf_codelet_n2bv_20_sse2
+fftwf_codelet_n2bv_2_avx
+fftwf_codelet_n2bv_2_sse2
+fftwf_codelet_n2bv_32_avx
+fftwf_codelet_n2bv_32_sse2
+fftwf_codelet_n2bv_4_avx
+fftwf_codelet_n2bv_4_sse2
+fftwf_codelet_n2bv_64_avx
+fftwf_codelet_n2bv_64_sse2
+fftwf_codelet_n2bv_6_avx
+fftwf_codelet_n2bv_6_sse2
+fftwf_codelet_n2bv_8_avx
+fftwf_codelet_n2bv_8_sse2
+fftwf_codelet_n2fv_10_avx
+fftwf_codelet_n2fv_10_sse2
+fftwf_codelet_n2fv_12_avx
+fftwf_codelet_n2fv_12_sse2
+fftwf_codelet_n2fv_14_avx
+fftwf_codelet_n2fv_14_sse2
+fftwf_codelet_n2fv_16_avx
+fftwf_codelet_n2fv_16_sse2
+fftwf_codelet_n2fv_20_avx
+fftwf_codelet_n2fv_20_sse2
+fftwf_codelet_n2fv_2_avx
+fftwf_codelet_n2fv_2_sse2
+fftwf_codelet_n2fv_32_avx
+fftwf_codelet_n2fv_32_sse2
+fftwf_codelet_n2fv_4_avx
+fftwf_codelet_n2fv_4_sse2
+fftwf_codelet_n2fv_64_avx
+fftwf_codelet_n2fv_64_sse2
+fftwf_codelet_n2fv_6_avx
+fftwf_codelet_n2fv_6_sse2
+fftwf_codelet_n2fv_8_avx
+fftwf_codelet_n2fv_8_sse2
+fftwf_codelet_n2sv_16_avx
+fftwf_codelet_n2sv_16_sse2
+fftwf_codelet_n2sv_32_avx
+fftwf_codelet_n2sv_32_sse2
+fftwf_codelet_n2sv_4_avx
+fftwf_codelet_n2sv_4_sse2
+fftwf_codelet_n2sv_64_avx
+fftwf_codelet_n2sv_64_sse2
+fftwf_codelet_n2sv_8_avx
+fftwf_codelet_n2sv_8_sse2
+fftwf_codelet_q1_2
+fftwf_codelet_q1_3
+fftwf_codelet_q1_4
+fftwf_codelet_q1_5
+fftwf_codelet_q1_6
+fftwf_codelet_q1_8
+fftwf_codelet_q1bv_2_avx
+fftwf_codelet_q1bv_2_sse2
+fftwf_codelet_q1bv_4_avx
+fftwf_codelet_q1bv_4_sse2
+fftwf_codelet_q1bv_5_avx
+fftwf_codelet_q1bv_5_sse2
+fftwf_codelet_q1bv_8_avx
+fftwf_codelet_q1bv_8_sse2
+fftwf_codelet_q1fv_2_avx
+fftwf_codelet_q1fv_2_sse2
+fftwf_codelet_q1fv_4_avx
+fftwf_codelet_q1fv_4_sse2
+fftwf_codelet_q1fv_5_avx
+fftwf_codelet_q1fv_5_sse2
+fftwf_codelet_q1fv_8_avx
+fftwf_codelet_q1fv_8_sse2
+fftwf_codelet_r2cb_10
+fftwf_codelet_r2cb_11
+fftwf_codelet_r2cb_12
+fftwf_codelet_r2cb_128
+fftwf_codelet_r2cb_13
+fftwf_codelet_r2cb_14
+fftwf_codelet_r2cb_15
+fftwf_codelet_r2cb_16
+fftwf_codelet_r2cb_2
+fftwf_codelet_r2cb_20
+fftwf_codelet_r2cb_25
+fftwf_codelet_r2cb_3
+fftwf_codelet_r2cb_32
+fftwf_codelet_r2cb_4
+fftwf_codelet_r2cb_5
+fftwf_codelet_r2cb_6
+fftwf_codelet_r2cb_64
+fftwf_codelet_r2cb_7
+fftwf_codelet_r2cb_8
+fftwf_codelet_r2cb_9
+fftwf_codelet_r2cbIII_10
+fftwf_codelet_r2cbIII_12
+fftwf_codelet_r2cbIII_15
+fftwf_codelet_r2cbIII_16
+fftwf_codelet_r2cbIII_2
+fftwf_codelet_r2cbIII_20
+fftwf_codelet_r2cbIII_25
+fftwf_codelet_r2cbIII_3
+fftwf_codelet_r2cbIII_32
+fftwf_codelet_r2cbIII_4
+fftwf_codelet_r2cbIII_5
+fftwf_codelet_r2cbIII_6
+fftwf_codelet_r2cbIII_64
+fftwf_codelet_r2cbIII_7
+fftwf_codelet_r2cbIII_8
+fftwf_codelet_r2cbIII_9
+fftwf_codelet_r2cf_10
+fftwf_codelet_r2cf_11
+fftwf_codelet_r2cf_12
+fftwf_codelet_r2cf_128
+fftwf_codelet_r2cf_13
+fftwf_codelet_r2cf_14
+fftwf_codelet_r2cf_15
+fftwf_codelet_r2cf_16
+fftwf_codelet_r2cf_2
+fftwf_codelet_r2cf_20
+fftwf_codelet_r2cf_25
+fftwf_codelet_r2cf_3
+fftwf_codelet_r2cf_32
+fftwf_codelet_r2cf_4
+fftwf_codelet_r2cf_5
+fftwf_codelet_r2cf_6
+fftwf_codelet_r2cf_64
+fftwf_codelet_r2cf_7
+fftwf_codelet_r2cf_8
+fftwf_codelet_r2cf_9
+fftwf_codelet_r2cfII_10
+fftwf_codelet_r2cfII_12
+fftwf_codelet_r2cfII_15
+fftwf_codelet_r2cfII_16
+fftwf_codelet_r2cfII_2
+fftwf_codelet_r2cfII_20
+fftwf_codelet_r2cfII_25
+fftwf_codelet_r2cfII_3
+fftwf_codelet_r2cfII_32
+fftwf_codelet_r2cfII_4
+fftwf_codelet_r2cfII_5
+fftwf_codelet_r2cfII_6
+fftwf_codelet_r2cfII_64
+fftwf_codelet_r2cfII_7
+fftwf_codelet_r2cfII_8
+fftwf_codelet_r2cfII_9
+fftwf_codelet_t1_10
+fftwf_codelet_t1_12
+fftwf_codelet_t1_15
+fftwf_codelet_t1_16
+fftwf_codelet_t1_2
+fftwf_codelet_t1_20
+fftwf_codelet_t1_25
+fftwf_codelet_t1_3
+fftwf_codelet_t1_32
+fftwf_codelet_t1_4
+fftwf_codelet_t1_5
+fftwf_codelet_t1_6
+fftwf_codelet_t1_64
+fftwf_codelet_t1_7
+fftwf_codelet_t1_8
+fftwf_codelet_t1_9
+fftwf_codelet_t1buv_10_avx
+fftwf_codelet_t1buv_10_sse2
+fftwf_codelet_t1buv_2_avx
+fftwf_codelet_t1buv_2_sse2
+fftwf_codelet_t1buv_3_avx
+fftwf_codelet_t1buv_3_sse2
+fftwf_codelet_t1buv_4_avx
+fftwf_codelet_t1buv_4_sse2
+fftwf_codelet_t1buv_5_avx
+fftwf_codelet_t1buv_5_sse2
+fftwf_codelet_t1buv_6_avx
+fftwf_codelet_t1buv_6_sse2
+fftwf_codelet_t1buv_7_avx
+fftwf_codelet_t1buv_7_sse2
+fftwf_codelet_t1buv_8_avx
+fftwf_codelet_t1buv_8_sse2
+fftwf_codelet_t1buv_9_avx
+fftwf_codelet_t1buv_9_sse2
+fftwf_codelet_t1bv_10_avx
+fftwf_codelet_t1bv_10_sse2
+fftwf_codelet_t1bv_12_avx
+fftwf_codelet_t1bv_12_sse2
+fftwf_codelet_t1bv_15_avx
+fftwf_codelet_t1bv_15_sse2
+fftwf_codelet_t1bv_16_avx
+fftwf_codelet_t1bv_16_sse2
+fftwf_codelet_t1bv_20_avx
+fftwf_codelet_t1bv_20_sse2
+fftwf_codelet_t1bv_25_avx
+fftwf_codelet_t1bv_25_sse2
+fftwf_codelet_t1bv_2_avx
+fftwf_codelet_t1bv_2_sse2
+fftwf_codelet_t1bv_32_avx
+fftwf_codelet_t1bv_32_sse2
+fftwf_codelet_t1bv_3_avx
+fftwf_codelet_t1bv_3_sse2
+fftwf_codelet_t1bv_4_avx
+fftwf_codelet_t1bv_4_sse2
+fftwf_codelet_t1bv_5_avx
+fftwf_codelet_t1bv_5_sse2
+fftwf_codelet_t1bv_64_avx
+fftwf_codelet_t1bv_64_sse2
+fftwf_codelet_t1bv_6_avx
+fftwf_codelet_t1bv_6_sse2
+fftwf_codelet_t1bv_7_avx
+fftwf_codelet_t1bv_7_sse2
+fftwf_codelet_t1bv_8_avx
+fftwf_codelet_t1bv_8_sse2
+fftwf_codelet_t1bv_9_avx
+fftwf_codelet_t1bv_9_sse2
+fftwf_codelet_t1fuv_10_avx
+fftwf_codelet_t1fuv_10_sse2
+fftwf_codelet_t1fuv_2_avx
+fftwf_codelet_t1fuv_2_sse2
+fftwf_codelet_t1fuv_3_avx
+fftwf_codelet_t1fuv_3_sse2
+fftwf_codelet_t1fuv_4_avx
+fftwf_codelet_t1fuv_4_sse2
+fftwf_codelet_t1fuv_5_avx
+fftwf_codelet_t1fuv_5_sse2
+fftwf_codelet_t1fuv_6_avx
+fftwf_codelet_t1fuv_6_sse2
+fftwf_codelet_t1fuv_7_avx
+fftwf_codelet_t1fuv_7_sse2
+fftwf_codelet_t1fuv_8_avx
+fftwf_codelet_t1fuv_8_sse2
+fftwf_codelet_t1fuv_9_avx
+fftwf_codelet_t1fuv_9_sse2
+fftwf_codelet_t1fv_10_avx
+fftwf_codelet_t1fv_10_sse2
+fftwf_codelet_t1fv_12_avx
+fftwf_codelet_t1fv_12_sse2
+fftwf_codelet_t1fv_15_avx
+fftwf_codelet_t1fv_15_sse2
+fftwf_codelet_t1fv_16_avx
+fftwf_codelet_t1fv_16_sse2
+fftwf_codelet_t1fv_20_avx
+fftwf_codelet_t1fv_20_sse2
+fftwf_codelet_t1fv_25_avx
+fftwf_codelet_t1fv_25_sse2
+fftwf_codelet_t1fv_2_avx
+fftwf_codelet_t1fv_2_sse2
+fftwf_codelet_t1fv_32_avx
+fftwf_codelet_t1fv_32_sse2
+fftwf_codelet_t1fv_3_avx
+fftwf_codelet_t1fv_3_sse2
+fftwf_codelet_t1fv_4_avx
+fftwf_codelet_t1fv_4_sse2
+fftwf_codelet_t1fv_5_avx
+fftwf_codelet_t1fv_5_sse2
+fftwf_codelet_t1fv_64_avx
+fftwf_codelet_t1fv_64_sse2
+fftwf_codelet_t1fv_6_avx
+fftwf_codelet_t1fv_6_sse2
+fftwf_codelet_t1fv_7_avx
+fftwf_codelet_t1fv_7_sse2
+fftwf_codelet_t1fv_8_avx
+fftwf_codelet_t1fv_8_sse2
+fftwf_codelet_t1fv_9_avx
+fftwf_codelet_t1fv_9_sse2
+fftwf_codelet_t1sv_16_avx
+fftwf_codelet_t1sv_16_sse2
+fftwf_codelet_t1sv_2_avx
+fftwf_codelet_t1sv_2_sse2
+fftwf_codelet_t1sv_32_avx
+fftwf_codelet_t1sv_32_sse2
+fftwf_codelet_t1sv_4_avx
+fftwf_codelet_t1sv_4_sse2
+fftwf_codelet_t1sv_8_avx
+fftwf_codelet_t1sv_8_sse2
+fftwf_codelet_t2_10
+fftwf_codelet_t2_16
+fftwf_codelet_t2_20
+fftwf_codelet_t2_25
+fftwf_codelet_t2_32
+fftwf_codelet_t2_4
+fftwf_codelet_t2_5
+fftwf_codelet_t2_64
+fftwf_codelet_t2_8
+fftwf_codelet_t2bv_10_avx
+fftwf_codelet_t2bv_10_sse2
+fftwf_codelet_t2bv_16_avx
+fftwf_codelet_t2bv_16_sse2
+fftwf_codelet_t2bv_20_avx
+fftwf_codelet_t2bv_20_sse2
+fftwf_codelet_t2bv_25_avx
+fftwf_codelet_t2bv_25_sse2
+fftwf_codelet_t2bv_2_avx
+fftwf_codelet_t2bv_2_sse2
+fftwf_codelet_t2bv_32_avx
+fftwf_codelet_t2bv_32_sse2
+fftwf_codelet_t2bv_4_avx
+fftwf_codelet_t2bv_4_sse2
+fftwf_codelet_t2bv_5_avx
+fftwf_codelet_t2bv_5_sse2
+fftwf_codelet_t2bv_64_avx
+fftwf_codelet_t2bv_64_sse2
+fftwf_codelet_t2bv_8_avx
+fftwf_codelet_t2bv_8_sse2
+fftwf_codelet_t2fv_10_avx
+fftwf_codelet_t2fv_10_sse2
+fftwf_codelet_t2fv_16_avx
+fftwf_codelet_t2fv_16_sse2
+fftwf_codelet_t2fv_20_avx
+fftwf_codelet_t2fv_20_sse2
+fftwf_codelet_t2fv_25_avx
+fftwf_codelet_t2fv_25_sse2
+fftwf_codelet_t2fv_2_avx
+fftwf_codelet_t2fv_2_sse2
+fftwf_codelet_t2fv_32_avx
+fftwf_codelet_t2fv_32_sse2
+fftwf_codelet_t2fv_4_avx
+fftwf_codelet_t2fv_4_sse2
+fftwf_codelet_t2fv_5_avx
+fftwf_codelet_t2fv_5_sse2
+fftwf_codelet_t2fv_64_avx
+fftwf_codelet_t2fv_64_sse2
+fftwf_codelet_t2fv_8_avx
+fftwf_codelet_t2fv_8_sse2
+fftwf_codelet_t2sv_16_avx
+fftwf_codelet_t2sv_16_sse2
+fftwf_codelet_t2sv_32_avx
+fftwf_codelet_t2sv_32_sse2
+fftwf_codelet_t2sv_4_avx
+fftwf_codelet_t2sv_4_sse2
+fftwf_codelet_t2sv_8_avx
+fftwf_codelet_t2sv_8_sse2
+fftwf_codelet_t3bv_10_avx
+fftwf_codelet_t3bv_10_sse2
+fftwf_codelet_t3bv_16_avx
+fftwf_codelet_t3bv_16_sse2
+fftwf_codelet_t3bv_20_avx
+fftwf_codelet_t3bv_20_sse2
+fftwf_codelet_t3bv_25_avx
+fftwf_codelet_t3bv_25_sse2
+fftwf_codelet_t3bv_32_avx
+fftwf_codelet_t3bv_32_sse2
+fftwf_codelet_t3bv_4_avx
+fftwf_codelet_t3bv_4_sse2
+fftwf_codelet_t3bv_5_avx
+fftwf_codelet_t3bv_5_sse2
+fftwf_codelet_t3bv_8_avx
+fftwf_codelet_t3bv_8_sse2
+fftwf_codelet_t3fv_10_avx
+fftwf_codelet_t3fv_10_sse2
+fftwf_codelet_t3fv_16_avx
+fftwf_codelet_t3fv_16_sse2
+fftwf_codelet_t3fv_20_avx
+fftwf_codelet_t3fv_20_sse2
+fftwf_codelet_t3fv_25_avx
+fftwf_codelet_t3fv_25_sse2
+fftwf_codelet_t3fv_32_avx
+fftwf_codelet_t3fv_32_sse2
+fftwf_codelet_t3fv_4_avx
+fftwf_codelet_t3fv_4_sse2
+fftwf_codelet_t3fv_5_avx
+fftwf_codelet_t3fv_5_sse2
+fftwf_codelet_t3fv_8_avx
+fftwf_codelet_t3fv_8_sse2
+fftwf_compute_tilesz
+fftwf_configure_planner
+fftwf_cost
+fftwf_cpy1d
+fftwf_cpy2d
+fftwf_cpy2d_ci
+fftwf_cpy2d_co
+fftwf_cpy2d_pair
+fftwf_cpy2d_pair_ci
+fftwf_cpy2d_pair_co
+fftwf_cpy2d_tiled
+fftwf_cpy2d_tiledbuf
+fftwf_ct_applicable
+fftwf_ct_genericbuf_register
+fftwf_ct_generic_register
+fftwf_ct_uglyp
+fftwf_destroy_plan
+fftwf_dft_bluestein_register
+fftwf_dft_buffered_register
+fftwf_dft_conf_standard
+fftwf_dft_generic_register
+fftwf_dft_indirect_register
+fftwf_dft_indirect_transpose_register
+fftwf_dft_nop_register
+fftwf_dft_r2hc_register
+fftwf_dft_rader_register
+fftwf_dft_rank_geq2_register
+fftwf_dft_solve
+fftwf_dft_thr_vrank_geq1_register
+fftwf_dft_vrank_geq1_register
+fftwf_dft_zerotens
+fftwf_dht_r2hc_register
+fftwf_dht_rader_register
+fftwf_dimcmp
+fftwf_elapsed_since
+fftwf_estimate_cost
+fftwf_execute
+fftwf_execute_dft
+fftwf_execute_dft_c2r
+fftwf_execute_dft_r2c
+fftwf_execute_r2r
+fftwf_execute_split_dft
+fftwf_execute_split_dft_c2r
+fftwf_execute_split_dft_r2c
+fftwf_export_wisdom
+fftwf_export_wisdom_to_file
+fftwf_export_wisdom_to_filename
+fftwf_export_wisdom_to_string
+fftwf_extract_reim
+fftwf_factors_into
+fftwf_factors_into_small_primes
+fftwf_find_generator
+fftwf_first_divisor
+fftwf_flops
+fftwf_forget_wisdom
+fftwf_fprint_plan
+fftwf_free
+fftwf_get_crude_time
+fftwf_guru64_kosherp
+fftwf_guru_kosherp
+fftwf_hash
+fftwf_have_simd_avx
+fftwf_have_simd_sse2
+fftwf_hc2hc_applicable
+fftwf_hc2hc_generic_register
+fftwf_iabs
+fftwf_ialignment_of
+fftwf_iestimate_cost
+fftwf_ifree
+fftwf_ifree0
+fftwf_imax
+fftwf_imin
+fftwf_import_system_wisdom
+fftwf_import_wisdom
+fftwf_import_wisdom_from_file
+fftwf_import_wisdom_from_filename
+fftwf_import_wisdom_from_string
+fftwf_init_threads
+fftwf_is_prime
+fftwf_isqrt
+fftwf_ithreads_init
+fftwf_join_taint
+fftwf_kdft_dif_register
+fftwf_kdft_difsq_register
+fftwf_kdft_dit_register
+fftwf_kdft_register
+fftwf_kernel_free
+fftwf_kernel_malloc
+fftwf_khc2c_register
+fftwf_khc2hc_register
+fftwf_kr2c_register
+fftwf_kr2r_register
+fftwf_make_planner_thread_safe
+fftwf_malloc
+fftwf_malloc_plain
+fftwf_many_kosherp
+fftwf_mapflags
+fftwf_map_r2r_kind
+fftwf_md5begin
+fftwf_md5end
+fftwf_md5int
+fftwf_md5INT
+fftwf_md5putb
+fftwf_md5putc
+fftwf_md5puts
+fftwf_md5unsigned
+fftwf_measure_execution_time
+fftwf_mkapiplan
+fftwf_mkplan
+fftwf_mkplan_d
+fftwf_mkplan_dft
+fftwf_mkplan_dftw
+fftwf_mkplan_f_d
+fftwf_mkplan_hc2c
+fftwf_mkplan_hc2hc
+fftwf_mkplanner
+fftwf_mkplan_rdft
+fftwf_mkplan_rdft2
+fftwf_mkprinter
+fftwf_mkprinter_cnt
+fftwf_mkprinter_file
+fftwf_mkprinter_str
+fftwf_mkproblem
+fftwf_mkproblem_dft
+fftwf_mkproblem_dft_d
+fftwf_mkproblem_rdft
+fftwf_mkproblem_rdft_0_d
+fftwf_mkproblem_rdft_1
+fftwf_mkproblem_rdft_1_d
+fftwf_mkproblem_rdft2
+fftwf_mkproblem_rdft2_d
+fftwf_mkproblem_rdft2_d_3pointers
+fftwf_mkproblem_rdft_d
+fftwf_mkproblem_unsolvable
+fftwf_mkscanner
+fftwf_mksolver
+fftwf_mksolver_ct
+fftwf_mksolver_ct_threads
+fftwf_mksolver_dft_direct
+fftwf_mksolver_dft_directbuf
+fftwf_mksolver_hc2c
+fftwf_mksolver_hc2hc
+fftwf_mksolver_hc2hc_threads
+fftwf_mksolver_rdft2_direct
+fftwf_mksolver_rdft_r2c_direct
+fftwf_mksolver_rdft_r2c_directbuf
+fftwf_mksolver_rdft_r2r_direct
+fftwf_mkstride
+fftwf_mktensor
+fftwf_mktensor_0d
+fftwf_mktensor_1d
+fftwf_mktensor_2d
+fftwf_mktensor_3d
+fftwf_mktensor_4d
+fftwf_mktensor_5d
+fftwf_mktensor_iodims
+fftwf_mktensor_iodims64
+fftwf_mktensor_rowmajor
+fftwf_mktriggen
+fftwf_modulo
+fftwf_nbuf
+fftwf_nbuf_redundant
+fftwf_next_prime
+fftwf_null_awake
+fftwf_ops_add
+fftwf_ops_add2
+fftwf_ops_cpy
+fftwf_ops_madd
+fftwf_ops_madd2
+fftwf_ops_other
+fftwf_ops_zero
+fftwf_pickdim
+fftwf_plan_awake
+fftwf_plan_destroy_internal
+fftwf_plan_dft
+fftwf_plan_dft_1d
+fftwf_plan_dft_2d
+fftwf_plan_dft_3d
+fftwf_plan_dft_c2r
+fftwf_plan_dft_c2r_1d
+fftwf_plan_dft_c2r_2d
+fftwf_plan_dft_c2r_3d
+fftwf_plan_dft_r2c
+fftwf_plan_dft_r2c_1d
+fftwf_plan_dft_r2c_2d
+fftwf_plan_dft_r2c_3d
+fftwf_plan_guru64_dft
+fftwf_plan_guru64_dft_c2r
+fftwf_plan_guru64_dft_r2c
+fftwf_plan_guru64_r2r
+fftwf_plan_guru64_split_dft
+fftwf_plan_guru64_split_dft_c2r
+fftwf_plan_guru64_split_dft_r2c
+fftwf_plan_guru_dft
+fftwf_plan_guru_dft_c2r
+fftwf_plan_guru_dft_r2c
+fftwf_plan_guru_r2r
+fftwf_plan_guru_split_dft
+fftwf_plan_guru_split_dft_c2r
+fftwf_plan_guru_split_dft_r2c
+fftwf_plan_many_dft
+fftwf_plan_many_dft_c2r
+fftwf_plan_many_dft_r2c
+fftwf_plan_many_r2r
+fftwf_planner_destroy
+fftwf_plan_null_destroy
+fftwf_plan_r2r
+fftwf_plan_r2r_1d
+fftwf_plan_r2r_2d
+fftwf_plan_r2r_3d
+fftwf_plan_with_nthreads
+fftwf_power_mod
+fftwf_printer_destroy
+fftwf_print_plan
+fftwf_problem_destroy
+fftwf_rader_tl_delete
+fftwf_rader_tl_find
+fftwf_rader_tl_insert
+fftwf_rdft2_buffered_register
+fftwf_rdft2_complex_n
+fftwf_rdft2_inplace_strides
+fftwf_rdft2_nop_register
+fftwf_rdft2_pad
+fftwf_rdft2_rank0_register
+fftwf_rdft2_rank_geq2_register
+fftwf_rdft2_rdft_register
+fftwf_rdft2_solve
+fftwf_rdft2_strides
+fftwf_rdft2_tensor_max_index
+fftwf_rdft2_thr_vrank_geq1_register
+fftwf_rdft2_vrank_geq1_register
+fftwf_rdft_buffered_register
+fftwf_rdft_conf_standard
+fftwf_rdft_dht_register
+fftwf_rdft_generic_register
+fftwf_rdft_indirect_register
+fftwf_rdft_kind_str
+fftwf_rdft_nop_register
+fftwf_rdft_rank0_register
+fftwf_rdft_rank_geq2_register
+fftwf_rdft_solve
+fftwf_rdft_thr_vrank_geq1_register
+fftwf_rdft_vrank3_transpose_register
+fftwf_rdft_vrank_geq1_register
+fftwf_rdft_zerotens
+fftwf_redft00e_r2hc_pad_register
+fftwf_regsolver_ct_directw
+fftwf_regsolver_ct_directwsq
+fftwf_regsolver_hc2c_direct
+fftwf_regsolver_hc2hc_direct
+fftwf_reodft00e_splitradix_register
+fftwf_reodft010e_r2hc_register
+fftwf_reodft11e_r2hc_odd_register
+fftwf_reodft11e_radix2_r2hc_register
+fftwf_reodft_conf_standard
+fftwf_rodft00e_r2hc_pad_register
+fftwf_safe_mulmod
+fftwf_scanner_destroy
+fftwf_set_planner_hooks
+fftwf_set_timelimit
+fftwf_solver_destroy
+fftwf_solver_register
+fftwf_solver_use
+fftwf_solvtab_exec
+fftwf_spawn_loop
+fftwf_sprint_plan
+fftwf_stride_destroy
+fftwf_taint
+fftwf_tensor_append
+fftwf_tensor_compress
+fftwf_tensor_compress_contiguous
+fftwf_tensor_copy
+fftwf_tensor_copy_except
+fftwf_tensor_copy_inplace
+fftwf_tensor_copy_sub
+fftwf_tensor_destroy
+fftwf_tensor_destroy2
+fftwf_tensor_destroy4
+fftwf_tensor_equal
+fftwf_tensor_inplace_locations
+fftwf_tensor_inplace_strides
+fftwf_tensor_inplace_strides2
+fftwf_tensor_kosherp
+fftwf_tensor_max_index
+fftwf_tensor_md5
+fftwf_tensor_min_istride
+fftwf_tensor_min_ostride
+fftwf_tensor_min_stride
+fftwf_tensor_print
+fftwf_tensor_split
+fftwf_tensor_strides_decrease
+fftwf_tensor_sz
+fftwf_tensor_tornk1
+fftwf_the_planner
+fftwf_threads_cleanup
+fftwf_threads_conf_standard
+fftwf_threads_register_planner_hooks
+fftwf_tile2d
+fftwf_toobig
+fftwf_transpose
+fftwf_transpose_tiled
+fftwf_transpose_tiledbuf
+fftwf_triggen_destroy
+fftwf_twiddle_awake
+fftwf_twiddle_length
+fftwf_zero1d_pair
+sfftw_cleanup_
+sfftw_cleanup__
+sfftw_cleanup_threads_
+sfftw_cleanup_threads__
+sfftw_cost_
+sfftw_cost__
+sfftw_destroy_plan_
+sfftw_destroy_plan__
+sfftw_estimate_cost_
+sfftw_estimate_cost__
+sfftw_execute_
+sfftw_execute__
+sfftw_execute_dft_
+sfftw_execute_dft__
+sfftw_execute_dft_c2r_
+sfftw_execute_dft_c2r__
+sfftw_execute_dft_r2c_
+sfftw_execute_dft_r2c__
+sfftw_execute_r2r_
+sfftw_execute_r2r__
+sfftw_execute_split_dft_
+sfftw_execute_split_dft__
+sfftw_execute_split_dft_c2r_
+sfftw_execute_split_dft_c2r__
+sfftw_execute_split_dft_r2c_
+sfftw_execute_split_dft_r2c__
+sfftw_export_wisdom_
+sfftw_export_wisdom__
+sfftw_flops_
+sfftw_flops__
+sfftw_forget_wisdom_
+sfftw_forget_wisdom__
+sfftw_import_system_wisdom_
+sfftw_import_system_wisdom__
+sfftw_import_wisdom_
+sfftw_import_wisdom__
+sfftw_init_threads_
+sfftw_init_threads__
+sfftw_plan_dft_
+sfftw_plan_dft__
+sfftw_plan_dft_1d_
+sfftw_plan_dft_1d__
+sfftw_plan_dft_2d_
+sfftw_plan_dft_2d__
+sfftw_plan_dft_3d_
+sfftw_plan_dft_3d__
+sfftw_plan_dft_c2r_
+sfftw_plan_dft_c2r__
+sfftw_plan_dft_c2r_1d_
+sfftw_plan_dft_c2r_1d__
+sfftw_plan_dft_c2r_2d_
+sfftw_plan_dft_c2r_2d__
+sfftw_plan_dft_c2r_3d_
+sfftw_plan_dft_c2r_3d__
+sfftw_plan_dft_r2c_
+sfftw_plan_dft_r2c__
+sfftw_plan_dft_r2c_1d_
+sfftw_plan_dft_r2c_1d__
+sfftw_plan_dft_r2c_2d_
+sfftw_plan_dft_r2c_2d__
+sfftw_plan_dft_r2c_3d_
+sfftw_plan_dft_r2c_3d__
+sfftw_plan_guru_dft_
+sfftw_plan_guru_dft__
+sfftw_plan_guru_dft_c2r_
+sfftw_plan_guru_dft_c2r__
+sfftw_plan_guru_dft_r2c_
+sfftw_plan_guru_dft_r2c__
+sfftw_plan_guru_r2r_
+sfftw_plan_guru_r2r__
+sfftw_plan_guru_split_dft_
+sfftw_plan_guru_split_dft__
+sfftw_plan_guru_split_dft_c2r_
+sfftw_plan_guru_split_dft_c2r__
+sfftw_plan_guru_split_dft_r2c_
+sfftw_plan_guru_split_dft_r2c__
+sfftw_plan_many_dft_
+sfftw_plan_many_dft__
+sfftw_plan_many_dft_c2r_
+sfftw_plan_many_dft_c2r__
+sfftw_plan_many_dft_r2c_
+sfftw_plan_many_dft_r2c__
+sfftw_plan_many_r2r_
+sfftw_plan_many_r2r__
+sfftw_plan_r2r_
+sfftw_plan_r2r__
+sfftw_plan_r2r_1d_
+sfftw_plan_r2r_1d__
+sfftw_plan_r2r_2d_
+sfftw_plan_r2r_2d__
+sfftw_plan_r2r_3d_
+sfftw_plan_r2r_3d__
+sfftw_plan_with_nthreads_
+sfftw_plan_with_nthreads__
+sfftw_print_plan_
+sfftw_print_plan__
+sfftw_set_timelimit_
+sfftw_set_timelimit__
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.exp b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.exp
new file mode 100644
index 0000000..65b8806
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.exp
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.lib b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.lib
new file mode 100644
index 0000000..e8f03dd
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3f-3.lib
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.def b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.def
new file mode 100644
index 0000000..62a5e42
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.def
@@ -0,0 +1,634 @@
+LIBRARY libfftw3l-3.dll
+EXPORTS
+fftwl_alignment_of
+fftwl_alloc_complex
+fftwl_alloc_real
+fftwl_assertion_failed
+fftwl_bufdist
+fftwl_choose_radix
+fftwl_cleanup
+fftwl_cleanup_threads
+fftwl_codelet_e01_8
+fftwl_codelet_e10_8
+fftwl_codelet_hb_10
+fftwl_codelet_hb_12
+fftwl_codelet_hb_15
+fftwl_codelet_hb_16
+fftwl_codelet_hb_2
+fftwl_codelet_hb_20
+fftwl_codelet_hb2_16
+fftwl_codelet_hb2_20
+fftwl_codelet_hb2_25
+fftwl_codelet_hb2_32
+fftwl_codelet_hb2_4
+fftwl_codelet_hb_25
+fftwl_codelet_hb2_5
+fftwl_codelet_hb2_8
+fftwl_codelet_hb_3
+fftwl_codelet_hb_32
+fftwl_codelet_hb_4
+fftwl_codelet_hb_5
+fftwl_codelet_hb_6
+fftwl_codelet_hb_64
+fftwl_codelet_hb_7
+fftwl_codelet_hb_8
+fftwl_codelet_hb_9
+fftwl_codelet_hc2cb_10
+fftwl_codelet_hc2cb_12
+fftwl_codelet_hc2cb_16
+fftwl_codelet_hc2cb_2
+fftwl_codelet_hc2cb_20
+fftwl_codelet_hc2cb2_16
+fftwl_codelet_hc2cb2_20
+fftwl_codelet_hc2cb2_32
+fftwl_codelet_hc2cb2_4
+fftwl_codelet_hc2cb2_8
+fftwl_codelet_hc2cb_32
+fftwl_codelet_hc2cb_4
+fftwl_codelet_hc2cb_6
+fftwl_codelet_hc2cb_8
+fftwl_codelet_hc2cbdft_10
+fftwl_codelet_hc2cbdft_12
+fftwl_codelet_hc2cbdft_16
+fftwl_codelet_hc2cbdft_2
+fftwl_codelet_hc2cbdft_20
+fftwl_codelet_hc2cbdft2_16
+fftwl_codelet_hc2cbdft2_20
+fftwl_codelet_hc2cbdft2_32
+fftwl_codelet_hc2cbdft2_4
+fftwl_codelet_hc2cbdft2_8
+fftwl_codelet_hc2cbdft_32
+fftwl_codelet_hc2cbdft_4
+fftwl_codelet_hc2cbdft_6
+fftwl_codelet_hc2cbdft_8
+fftwl_codelet_hc2cf_10
+fftwl_codelet_hc2cf_12
+fftwl_codelet_hc2cf_16
+fftwl_codelet_hc2cf_2
+fftwl_codelet_hc2cf_20
+fftwl_codelet_hc2cf2_16
+fftwl_codelet_hc2cf2_20
+fftwl_codelet_hc2cf2_32
+fftwl_codelet_hc2cf2_4
+fftwl_codelet_hc2cf2_8
+fftwl_codelet_hc2cf_32
+fftwl_codelet_hc2cf_4
+fftwl_codelet_hc2cf_6
+fftwl_codelet_hc2cf_8
+fftwl_codelet_hc2cfdft_10
+fftwl_codelet_hc2cfdft_12
+fftwl_codelet_hc2cfdft_16
+fftwl_codelet_hc2cfdft_2
+fftwl_codelet_hc2cfdft_20
+fftwl_codelet_hc2cfdft2_16
+fftwl_codelet_hc2cfdft2_20
+fftwl_codelet_hc2cfdft2_32
+fftwl_codelet_hc2cfdft2_4
+fftwl_codelet_hc2cfdft2_8
+fftwl_codelet_hc2cfdft_32
+fftwl_codelet_hc2cfdft_4
+fftwl_codelet_hc2cfdft_6
+fftwl_codelet_hc2cfdft_8
+fftwl_codelet_hf_10
+fftwl_codelet_hf_12
+fftwl_codelet_hf_15
+fftwl_codelet_hf_16
+fftwl_codelet_hf_2
+fftwl_codelet_hf_20
+fftwl_codelet_hf2_16
+fftwl_codelet_hf2_20
+fftwl_codelet_hf2_25
+fftwl_codelet_hf2_32
+fftwl_codelet_hf2_4
+fftwl_codelet_hf_25
+fftwl_codelet_hf2_5
+fftwl_codelet_hf2_8
+fftwl_codelet_hf_3
+fftwl_codelet_hf_32
+fftwl_codelet_hf_4
+fftwl_codelet_hf_5
+fftwl_codelet_hf_6
+fftwl_codelet_hf_64
+fftwl_codelet_hf_7
+fftwl_codelet_hf_8
+fftwl_codelet_hf_9
+fftwl_codelet_n1_10
+fftwl_codelet_n1_11
+fftwl_codelet_n1_12
+fftwl_codelet_n1_13
+fftwl_codelet_n1_14
+fftwl_codelet_n1_15
+fftwl_codelet_n1_16
+fftwl_codelet_n1_2
+fftwl_codelet_n1_20
+fftwl_codelet_n1_25
+fftwl_codelet_n1_3
+fftwl_codelet_n1_32
+fftwl_codelet_n1_4
+fftwl_codelet_n1_5
+fftwl_codelet_n1_6
+fftwl_codelet_n1_64
+fftwl_codelet_n1_7
+fftwl_codelet_n1_8
+fftwl_codelet_n1_9
+fftwl_codelet_q1_2
+fftwl_codelet_q1_3
+fftwl_codelet_q1_4
+fftwl_codelet_q1_5
+fftwl_codelet_q1_6
+fftwl_codelet_q1_8
+fftwl_codelet_r2cb_10
+fftwl_codelet_r2cb_11
+fftwl_codelet_r2cb_12
+fftwl_codelet_r2cb_128
+fftwl_codelet_r2cb_13
+fftwl_codelet_r2cb_14
+fftwl_codelet_r2cb_15
+fftwl_codelet_r2cb_16
+fftwl_codelet_r2cb_2
+fftwl_codelet_r2cb_20
+fftwl_codelet_r2cb_25
+fftwl_codelet_r2cb_3
+fftwl_codelet_r2cb_32
+fftwl_codelet_r2cb_4
+fftwl_codelet_r2cb_5
+fftwl_codelet_r2cb_6
+fftwl_codelet_r2cb_64
+fftwl_codelet_r2cb_7
+fftwl_codelet_r2cb_8
+fftwl_codelet_r2cb_9
+fftwl_codelet_r2cbIII_10
+fftwl_codelet_r2cbIII_12
+fftwl_codelet_r2cbIII_15
+fftwl_codelet_r2cbIII_16
+fftwl_codelet_r2cbIII_2
+fftwl_codelet_r2cbIII_20
+fftwl_codelet_r2cbIII_25
+fftwl_codelet_r2cbIII_3
+fftwl_codelet_r2cbIII_32
+fftwl_codelet_r2cbIII_4
+fftwl_codelet_r2cbIII_5
+fftwl_codelet_r2cbIII_6
+fftwl_codelet_r2cbIII_64
+fftwl_codelet_r2cbIII_7
+fftwl_codelet_r2cbIII_8
+fftwl_codelet_r2cbIII_9
+fftwl_codelet_r2cf_10
+fftwl_codelet_r2cf_11
+fftwl_codelet_r2cf_12
+fftwl_codelet_r2cf_128
+fftwl_codelet_r2cf_13
+fftwl_codelet_r2cf_14
+fftwl_codelet_r2cf_15
+fftwl_codelet_r2cf_16
+fftwl_codelet_r2cf_2
+fftwl_codelet_r2cf_20
+fftwl_codelet_r2cf_25
+fftwl_codelet_r2cf_3
+fftwl_codelet_r2cf_32
+fftwl_codelet_r2cf_4
+fftwl_codelet_r2cf_5
+fftwl_codelet_r2cf_6
+fftwl_codelet_r2cf_64
+fftwl_codelet_r2cf_7
+fftwl_codelet_r2cf_8
+fftwl_codelet_r2cf_9
+fftwl_codelet_r2cfII_10
+fftwl_codelet_r2cfII_12
+fftwl_codelet_r2cfII_15
+fftwl_codelet_r2cfII_16
+fftwl_codelet_r2cfII_2
+fftwl_codelet_r2cfII_20
+fftwl_codelet_r2cfII_25
+fftwl_codelet_r2cfII_3
+fftwl_codelet_r2cfII_32
+fftwl_codelet_r2cfII_4
+fftwl_codelet_r2cfII_5
+fftwl_codelet_r2cfII_6
+fftwl_codelet_r2cfII_64
+fftwl_codelet_r2cfII_7
+fftwl_codelet_r2cfII_8
+fftwl_codelet_r2cfII_9
+fftwl_codelet_t1_10
+fftwl_codelet_t1_12
+fftwl_codelet_t1_15
+fftwl_codelet_t1_16
+fftwl_codelet_t1_2
+fftwl_codelet_t1_20
+fftwl_codelet_t1_25
+fftwl_codelet_t1_3
+fftwl_codelet_t1_32
+fftwl_codelet_t1_4
+fftwl_codelet_t1_5
+fftwl_codelet_t1_6
+fftwl_codelet_t1_64
+fftwl_codelet_t1_7
+fftwl_codelet_t1_8
+fftwl_codelet_t1_9
+fftwl_codelet_t2_10
+fftwl_codelet_t2_16
+fftwl_codelet_t2_20
+fftwl_codelet_t2_25
+fftwl_codelet_t2_32
+fftwl_codelet_t2_4
+fftwl_codelet_t2_5
+fftwl_codelet_t2_64
+fftwl_codelet_t2_8
+fftwl_compute_tilesz
+fftwl_configure_planner
+fftwl_cost
+fftwl_cpy1d
+fftwl_cpy2d
+fftwl_cpy2d_ci
+fftwl_cpy2d_co
+fftwl_cpy2d_pair
+fftwl_cpy2d_pair_ci
+fftwl_cpy2d_pair_co
+fftwl_cpy2d_tiled
+fftwl_cpy2d_tiledbuf
+fftwl_ct_applicable
+fftwl_ct_genericbuf_register
+fftwl_ct_generic_register
+fftwl_ct_uglyp
+fftwl_destroy_plan
+fftwl_dft_bluestein_register
+fftwl_dft_buffered_register
+fftwl_dft_conf_standard
+fftwl_dft_generic_register
+fftwl_dft_indirect_register
+fftwl_dft_indirect_transpose_register
+fftwl_dft_nop_register
+fftwl_dft_r2hc_register
+fftwl_dft_rader_register
+fftwl_dft_rank_geq2_register
+fftwl_dft_solve
+fftwl_dft_thr_vrank_geq1_register
+fftwl_dft_vrank_geq1_register
+fftwl_dft_zerotens
+fftwl_dht_r2hc_register
+fftwl_dht_rader_register
+fftwl_dimcmp
+fftwl_elapsed_since
+fftwl_estimate_cost
+fftwl_execute
+fftwl_execute_dft
+fftwl_execute_dft_c2r
+fftwl_execute_dft_r2c
+fftwl_execute_r2r
+fftwl_execute_split_dft
+fftwl_execute_split_dft_c2r
+fftwl_execute_split_dft_r2c
+fftwl_export_wisdom
+fftwl_export_wisdom_to_file
+fftwl_export_wisdom_to_filename
+fftwl_export_wisdom_to_string
+fftwl_extract_reim
+fftwl_factors_into
+fftwl_factors_into_small_primes
+fftwl_find_generator
+fftwl_first_divisor
+fftwl_flops
+fftwl_forget_wisdom
+fftwl_fprint_plan
+fftwl_free
+fftwl_get_crude_time
+fftwl_guru64_kosherp
+fftwl_guru_kosherp
+fftwl_hash
+fftwl_hc2hc_applicable
+fftwl_hc2hc_generic_register
+fftwl_iabs
+fftwl_ialignment_of
+fftwl_iestimate_cost
+fftwl_ifree
+fftwl_ifree0
+fftwl_imax
+fftwl_imin
+fftwl_import_system_wisdom
+fftwl_import_wisdom
+fftwl_import_wisdom_from_file
+fftwl_import_wisdom_from_filename
+fftwl_import_wisdom_from_string
+fftwl_init_threads
+fftwl_is_prime
+fftwl_isqrt
+fftwl_ithreads_init
+fftwl_kdft_dif_register
+fftwl_kdft_difsq_register
+fftwl_kdft_dit_register
+fftwl_kdft_register
+fftwl_kernel_free
+fftwl_kernel_malloc
+fftwl_khc2c_register
+fftwl_khc2hc_register
+fftwl_kr2c_register
+fftwl_kr2r_register
+fftwl_make_planner_thread_safe
+fftwl_malloc
+fftwl_malloc_plain
+fftwl_many_kosherp
+fftwl_mapflags
+fftwl_map_r2r_kind
+fftwl_md5begin
+fftwl_md5end
+fftwl_md5int
+fftwl_md5INT
+fftwl_md5putb
+fftwl_md5putc
+fftwl_md5puts
+fftwl_md5unsigned
+fftwl_measure_execution_time
+fftwl_mkapiplan
+fftwl_mkplan
+fftwl_mkplan_d
+fftwl_mkplan_dft
+fftwl_mkplan_dftw
+fftwl_mkplan_f_d
+fftwl_mkplan_hc2c
+fftwl_mkplan_hc2hc
+fftwl_mkplanner
+fftwl_mkplan_rdft
+fftwl_mkplan_rdft2
+fftwl_mkprinter
+fftwl_mkprinter_cnt
+fftwl_mkprinter_file
+fftwl_mkprinter_str
+fftwl_mkproblem
+fftwl_mkproblem_dft
+fftwl_mkproblem_dft_d
+fftwl_mkproblem_rdft
+fftwl_mkproblem_rdft_0_d
+fftwl_mkproblem_rdft_1
+fftwl_mkproblem_rdft_1_d
+fftwl_mkproblem_rdft2
+fftwl_mkproblem_rdft2_d
+fftwl_mkproblem_rdft2_d_3pointers
+fftwl_mkproblem_rdft_d
+fftwl_mkproblem_unsolvable
+fftwl_mkscanner
+fftwl_mksolver
+fftwl_mksolver_ct
+fftwl_mksolver_ct_threads
+fftwl_mksolver_dft_direct
+fftwl_mksolver_dft_directbuf
+fftwl_mksolver_hc2c
+fftwl_mksolver_hc2hc
+fftwl_mksolver_hc2hc_threads
+fftwl_mksolver_rdft2_direct
+fftwl_mksolver_rdft_r2c_direct
+fftwl_mksolver_rdft_r2c_directbuf
+fftwl_mksolver_rdft_r2r_direct
+fftwl_mktensor
+fftwl_mktensor_0d
+fftwl_mktensor_1d
+fftwl_mktensor_2d
+fftwl_mktensor_3d
+fftwl_mktensor_4d
+fftwl_mktensor_5d
+fftwl_mktensor_iodims
+fftwl_mktensor_iodims64
+fftwl_mktensor_rowmajor
+fftwl_mktriggen
+fftwl_modulo
+fftwl_nbuf
+fftwl_nbuf_redundant
+fftwl_next_prime
+fftwl_null_awake
+fftwl_ops_add
+fftwl_ops_add2
+fftwl_ops_cpy
+fftwl_ops_madd
+fftwl_ops_madd2
+fftwl_ops_other
+fftwl_ops_zero
+fftwl_pickdim
+fftwl_plan_awake
+fftwl_plan_destroy_internal
+fftwl_plan_dft
+fftwl_plan_dft_1d
+fftwl_plan_dft_2d
+fftwl_plan_dft_3d
+fftwl_plan_dft_c2r
+fftwl_plan_dft_c2r_1d
+fftwl_plan_dft_c2r_2d
+fftwl_plan_dft_c2r_3d
+fftwl_plan_dft_r2c
+fftwl_plan_dft_r2c_1d
+fftwl_plan_dft_r2c_2d
+fftwl_plan_dft_r2c_3d
+fftwl_plan_guru64_dft
+fftwl_plan_guru64_dft_c2r
+fftwl_plan_guru64_dft_r2c
+fftwl_plan_guru64_r2r
+fftwl_plan_guru64_split_dft
+fftwl_plan_guru64_split_dft_c2r
+fftwl_plan_guru64_split_dft_r2c
+fftwl_plan_guru_dft
+fftwl_plan_guru_dft_c2r
+fftwl_plan_guru_dft_r2c
+fftwl_plan_guru_r2r
+fftwl_plan_guru_split_dft
+fftwl_plan_guru_split_dft_c2r
+fftwl_plan_guru_split_dft_r2c
+fftwl_plan_many_dft
+fftwl_plan_many_dft_c2r
+fftwl_plan_many_dft_r2c
+fftwl_plan_many_r2r
+fftwl_planner_destroy
+fftwl_plan_null_destroy
+fftwl_plan_r2r
+fftwl_plan_r2r_1d
+fftwl_plan_r2r_2d
+fftwl_plan_r2r_3d
+fftwl_plan_with_nthreads
+fftwl_power_mod
+fftwl_printer_destroy
+fftwl_print_plan
+fftwl_problem_destroy
+fftwl_rader_tl_delete
+fftwl_rader_tl_find
+fftwl_rader_tl_insert
+fftwl_rdft2_buffered_register
+fftwl_rdft2_complex_n
+fftwl_rdft2_inplace_strides
+fftwl_rdft2_nop_register
+fftwl_rdft2_pad
+fftwl_rdft2_rank0_register
+fftwl_rdft2_rank_geq2_register
+fftwl_rdft2_rdft_register
+fftwl_rdft2_solve
+fftwl_rdft2_strides
+fftwl_rdft2_tensor_max_index
+fftwl_rdft2_thr_vrank_geq1_register
+fftwl_rdft2_vrank_geq1_register
+fftwl_rdft_buffered_register
+fftwl_rdft_conf_standard
+fftwl_rdft_dht_register
+fftwl_rdft_generic_register
+fftwl_rdft_indirect_register
+fftwl_rdft_kind_str
+fftwl_rdft_nop_register
+fftwl_rdft_rank0_register
+fftwl_rdft_rank_geq2_register
+fftwl_rdft_solve
+fftwl_rdft_thr_vrank_geq1_register
+fftwl_rdft_vrank3_transpose_register
+fftwl_rdft_vrank_geq1_register
+fftwl_rdft_zerotens
+fftwl_redft00e_r2hc_pad_register
+fftwl_regsolver_ct_directw
+fftwl_regsolver_ct_directwsq
+fftwl_regsolver_hc2c_direct
+fftwl_regsolver_hc2hc_direct
+fftwl_reodft00e_splitradix_register
+fftwl_reodft010e_r2hc_register
+fftwl_reodft11e_r2hc_odd_register
+fftwl_reodft11e_radix2_r2hc_register
+fftwl_reodft_conf_standard
+fftwl_rodft00e_r2hc_pad_register
+fftwl_safe_mulmod
+fftwl_scanner_destroy
+fftwl_set_planner_hooks
+fftwl_set_timelimit
+fftwl_solver_destroy
+fftwl_solver_register
+fftwl_solver_use
+fftwl_solvtab_exec
+fftwl_spawn_loop
+fftwl_sprint_plan
+fftwl_tensor_append
+fftwl_tensor_compress
+fftwl_tensor_compress_contiguous
+fftwl_tensor_copy
+fftwl_tensor_copy_except
+fftwl_tensor_copy_inplace
+fftwl_tensor_copy_sub
+fftwl_tensor_destroy
+fftwl_tensor_destroy2
+fftwl_tensor_destroy4
+fftwl_tensor_equal
+fftwl_tensor_inplace_locations
+fftwl_tensor_inplace_strides
+fftwl_tensor_inplace_strides2
+fftwl_tensor_kosherp
+fftwl_tensor_max_index
+fftwl_tensor_md5
+fftwl_tensor_min_istride
+fftwl_tensor_min_ostride
+fftwl_tensor_min_stride
+fftwl_tensor_print
+fftwl_tensor_split
+fftwl_tensor_strides_decrease
+fftwl_tensor_sz
+fftwl_tensor_tornk1
+fftwl_the_planner
+fftwl_threads_cleanup
+fftwl_threads_conf_standard
+fftwl_threads_register_planner_hooks
+fftwl_tile2d
+fftwl_toobig
+fftwl_transpose
+fftwl_transpose_tiled
+fftwl_transpose_tiledbuf
+fftwl_triggen_destroy
+fftwl_twiddle_awake
+fftwl_twiddle_length
+fftwl_zero1d_pair
+lfftw_cleanup_
+lfftw_cleanup__
+lfftw_cleanup_threads_
+lfftw_cleanup_threads__
+lfftw_cost_
+lfftw_cost__
+lfftw_destroy_plan_
+lfftw_destroy_plan__
+lfftw_estimate_cost_
+lfftw_estimate_cost__
+lfftw_execute_
+lfftw_execute__
+lfftw_execute_dft_
+lfftw_execute_dft__
+lfftw_execute_dft_c2r_
+lfftw_execute_dft_c2r__
+lfftw_execute_dft_r2c_
+lfftw_execute_dft_r2c__
+lfftw_execute_r2r_
+lfftw_execute_r2r__
+lfftw_execute_split_dft_
+lfftw_execute_split_dft__
+lfftw_execute_split_dft_c2r_
+lfftw_execute_split_dft_c2r__
+lfftw_execute_split_dft_r2c_
+lfftw_execute_split_dft_r2c__
+lfftw_export_wisdom_
+lfftw_export_wisdom__
+lfftw_flops_
+lfftw_flops__
+lfftw_forget_wisdom_
+lfftw_forget_wisdom__
+lfftw_import_system_wisdom_
+lfftw_import_system_wisdom__
+lfftw_import_wisdom_
+lfftw_import_wisdom__
+lfftw_init_threads_
+lfftw_init_threads__
+lfftw_plan_dft_
+lfftw_plan_dft__
+lfftw_plan_dft_1d_
+lfftw_plan_dft_1d__
+lfftw_plan_dft_2d_
+lfftw_plan_dft_2d__
+lfftw_plan_dft_3d_
+lfftw_plan_dft_3d__
+lfftw_plan_dft_c2r_
+lfftw_plan_dft_c2r__
+lfftw_plan_dft_c2r_1d_
+lfftw_plan_dft_c2r_1d__
+lfftw_plan_dft_c2r_2d_
+lfftw_plan_dft_c2r_2d__
+lfftw_plan_dft_c2r_3d_
+lfftw_plan_dft_c2r_3d__
+lfftw_plan_dft_r2c_
+lfftw_plan_dft_r2c__
+lfftw_plan_dft_r2c_1d_
+lfftw_plan_dft_r2c_1d__
+lfftw_plan_dft_r2c_2d_
+lfftw_plan_dft_r2c_2d__
+lfftw_plan_dft_r2c_3d_
+lfftw_plan_dft_r2c_3d__
+lfftw_plan_guru_dft_
+lfftw_plan_guru_dft__
+lfftw_plan_guru_dft_c2r_
+lfftw_plan_guru_dft_c2r__
+lfftw_plan_guru_dft_r2c_
+lfftw_plan_guru_dft_r2c__
+lfftw_plan_guru_r2r_
+lfftw_plan_guru_r2r__
+lfftw_plan_guru_split_dft_
+lfftw_plan_guru_split_dft__
+lfftw_plan_guru_split_dft_c2r_
+lfftw_plan_guru_split_dft_c2r__
+lfftw_plan_guru_split_dft_r2c_
+lfftw_plan_guru_split_dft_r2c__
+lfftw_plan_many_dft_
+lfftw_plan_many_dft__
+lfftw_plan_many_dft_c2r_
+lfftw_plan_many_dft_c2r__
+lfftw_plan_many_dft_r2c_
+lfftw_plan_many_dft_r2c__
+lfftw_plan_many_r2r_
+lfftw_plan_many_r2r__
+lfftw_plan_r2r_
+lfftw_plan_r2r__
+lfftw_plan_r2r_1d_
+lfftw_plan_r2r_1d__
+lfftw_plan_r2r_2d_
+lfftw_plan_r2r_2d__
+lfftw_plan_r2r_3d_
+lfftw_plan_r2r_3d__
+lfftw_plan_with_nthreads_
+lfftw_plan_with_nthreads__
+lfftw_print_plan_
+lfftw_print_plan__
+lfftw_set_timelimit_
+lfftw_set_timelimit__
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.exp b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.exp
new file mode 100644
index 0000000..1c98b3a
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.exp
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.lib b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.lib
new file mode 100644
index 0000000..3661f5a
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/libfftw3l-3.lib
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x64/onnxruntime.lib b/funasr/runtime/cpp/onnxruntime/win/lib/x64/onnxruntime.lib
new file mode 100644
index 0000000..b1a314c
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x64/onnxruntime.lib
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.def b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.def
new file mode 100644
index 0000000..4b50ecd
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.def
@@ -0,0 +1,1017 @@
+LIBRARY libfftw3-3.dll
+EXPORTS
+dfftw_cleanup_
+dfftw_cleanup__
+dfftw_cleanup_threads_
+dfftw_cleanup_threads__
+dfftw_cost_
+dfftw_cost__
+dfftw_destroy_plan_
+dfftw_destroy_plan__
+dfftw_estimate_cost_
+dfftw_estimate_cost__
+dfftw_execute_
+dfftw_execute__
+dfftw_execute_dft_
+dfftw_execute_dft__
+dfftw_execute_dft_c2r_
+dfftw_execute_dft_c2r__
+dfftw_execute_dft_r2c_
+dfftw_execute_dft_r2c__
+dfftw_execute_r2r_
+dfftw_execute_r2r__
+dfftw_execute_split_dft_
+dfftw_execute_split_dft__
+dfftw_execute_split_dft_c2r_
+dfftw_execute_split_dft_c2r__
+dfftw_execute_split_dft_r2c_
+dfftw_execute_split_dft_r2c__
+dfftw_export_wisdom_
+dfftw_export_wisdom__
+dfftw_flops_
+dfftw_flops__
+dfftw_forget_wisdom_
+dfftw_forget_wisdom__
+dfftw_import_system_wisdom_
+dfftw_import_system_wisdom__
+dfftw_import_wisdom_
+dfftw_import_wisdom__
+dfftw_init_threads_
+dfftw_init_threads__
+dfftw_plan_dft_
+dfftw_plan_dft__
+dfftw_plan_dft_1d_
+dfftw_plan_dft_1d__
+dfftw_plan_dft_2d_
+dfftw_plan_dft_2d__
+dfftw_plan_dft_3d_
+dfftw_plan_dft_3d__
+dfftw_plan_dft_c2r_
+dfftw_plan_dft_c2r__
+dfftw_plan_dft_c2r_1d_
+dfftw_plan_dft_c2r_1d__
+dfftw_plan_dft_c2r_2d_
+dfftw_plan_dft_c2r_2d__
+dfftw_plan_dft_c2r_3d_
+dfftw_plan_dft_c2r_3d__
+dfftw_plan_dft_r2c_
+dfftw_plan_dft_r2c__
+dfftw_plan_dft_r2c_1d_
+dfftw_plan_dft_r2c_1d__
+dfftw_plan_dft_r2c_2d_
+dfftw_plan_dft_r2c_2d__
+dfftw_plan_dft_r2c_3d_
+dfftw_plan_dft_r2c_3d__
+dfftw_plan_guru_dft_
+dfftw_plan_guru_dft__
+dfftw_plan_guru_dft_c2r_
+dfftw_plan_guru_dft_c2r__
+dfftw_plan_guru_dft_r2c_
+dfftw_plan_guru_dft_r2c__
+dfftw_plan_guru_r2r_
+dfftw_plan_guru_r2r__
+dfftw_plan_guru_split_dft_
+dfftw_plan_guru_split_dft__
+dfftw_plan_guru_split_dft_c2r_
+dfftw_plan_guru_split_dft_c2r__
+dfftw_plan_guru_split_dft_r2c_
+dfftw_plan_guru_split_dft_r2c__
+dfftw_plan_many_dft_
+dfftw_plan_many_dft__
+dfftw_plan_many_dft_c2r_
+dfftw_plan_many_dft_c2r__
+dfftw_plan_many_dft_r2c_
+dfftw_plan_many_dft_r2c__
+dfftw_plan_many_r2r_
+dfftw_plan_many_r2r__
+dfftw_plan_r2r_
+dfftw_plan_r2r__
+dfftw_plan_r2r_1d_
+dfftw_plan_r2r_1d__
+dfftw_plan_r2r_2d_
+dfftw_plan_r2r_2d__
+dfftw_plan_r2r_3d_
+dfftw_plan_r2r_3d__
+dfftw_plan_with_nthreads_
+dfftw_plan_with_nthreads__
+dfftw_print_plan_
+dfftw_print_plan__
+dfftw_set_timelimit_
+dfftw_set_timelimit__
+fftw_alignment_of
+fftw_alloc_complex
+fftw_alloc_real
+fftw_assertion_failed
+fftw_bufdist
+fftw_check_alignment_of_sse2_pm
+fftw_choose_radix
+fftw_cleanup
+fftw_cleanup_threads
+fftw_codelet_e01_8
+fftw_codelet_e10_8
+fftw_codelet_hb_10
+fftw_codelet_hb_12
+fftw_codelet_hb_15
+fftw_codelet_hb_16
+fftw_codelet_hb_2
+fftw_codelet_hb_20
+fftw_codelet_hb2_16
+fftw_codelet_hb2_20
+fftw_codelet_hb2_25
+fftw_codelet_hb2_32
+fftw_codelet_hb2_4
+fftw_codelet_hb_25
+fftw_codelet_hb2_5
+fftw_codelet_hb2_8
+fftw_codelet_hb_3
+fftw_codelet_hb_32
+fftw_codelet_hb_4
+fftw_codelet_hb_5
+fftw_codelet_hb_6
+fftw_codelet_hb_64
+fftw_codelet_hb_7
+fftw_codelet_hb_8
+fftw_codelet_hb_9
+fftw_codelet_hc2cb_10
+fftw_codelet_hc2cb_12
+fftw_codelet_hc2cb_16
+fftw_codelet_hc2cb_2
+fftw_codelet_hc2cb_20
+fftw_codelet_hc2cb2_16
+fftw_codelet_hc2cb2_20
+fftw_codelet_hc2cb2_32
+fftw_codelet_hc2cb2_4
+fftw_codelet_hc2cb2_8
+fftw_codelet_hc2cb_32
+fftw_codelet_hc2cb_4
+fftw_codelet_hc2cb_6
+fftw_codelet_hc2cb_8
+fftw_codelet_hc2cbdft_10
+fftw_codelet_hc2cbdft_12
+fftw_codelet_hc2cbdft_16
+fftw_codelet_hc2cbdft_2
+fftw_codelet_hc2cbdft_20
+fftw_codelet_hc2cbdft2_16
+fftw_codelet_hc2cbdft2_20
+fftw_codelet_hc2cbdft2_32
+fftw_codelet_hc2cbdft2_4
+fftw_codelet_hc2cbdft2_8
+fftw_codelet_hc2cbdft_32
+fftw_codelet_hc2cbdft_4
+fftw_codelet_hc2cbdft_6
+fftw_codelet_hc2cbdft_8
+fftw_codelet_hc2cbdftv_10_avx
+fftw_codelet_hc2cbdftv_10_sse2
+fftw_codelet_hc2cbdftv_12_avx
+fftw_codelet_hc2cbdftv_12_sse2
+fftw_codelet_hc2cbdftv_16_avx
+fftw_codelet_hc2cbdftv_16_sse2
+fftw_codelet_hc2cbdftv_20_avx
+fftw_codelet_hc2cbdftv_20_sse2
+fftw_codelet_hc2cbdftv_2_avx
+fftw_codelet_hc2cbdftv_2_sse2
+fftw_codelet_hc2cbdftv_32_avx
+fftw_codelet_hc2cbdftv_32_sse2
+fftw_codelet_hc2cbdftv_4_avx
+fftw_codelet_hc2cbdftv_4_sse2
+fftw_codelet_hc2cbdftv_6_avx
+fftw_codelet_hc2cbdftv_6_sse2
+fftw_codelet_hc2cbdftv_8_avx
+fftw_codelet_hc2cbdftv_8_sse2
+fftw_codelet_hc2cf_10
+fftw_codelet_hc2cf_12
+fftw_codelet_hc2cf_16
+fftw_codelet_hc2cf_2
+fftw_codelet_hc2cf_20
+fftw_codelet_hc2cf2_16
+fftw_codelet_hc2cf2_20
+fftw_codelet_hc2cf2_32
+fftw_codelet_hc2cf2_4
+fftw_codelet_hc2cf2_8
+fftw_codelet_hc2cf_32
+fftw_codelet_hc2cf_4
+fftw_codelet_hc2cf_6
+fftw_codelet_hc2cf_8
+fftw_codelet_hc2cfdft_10
+fftw_codelet_hc2cfdft_12
+fftw_codelet_hc2cfdft_16
+fftw_codelet_hc2cfdft_2
+fftw_codelet_hc2cfdft_20
+fftw_codelet_hc2cfdft2_16
+fftw_codelet_hc2cfdft2_20
+fftw_codelet_hc2cfdft2_32
+fftw_codelet_hc2cfdft2_4
+fftw_codelet_hc2cfdft2_8
+fftw_codelet_hc2cfdft_32
+fftw_codelet_hc2cfdft_4
+fftw_codelet_hc2cfdft_6
+fftw_codelet_hc2cfdft_8
+fftw_codelet_hc2cfdftv_10_avx
+fftw_codelet_hc2cfdftv_10_sse2
+fftw_codelet_hc2cfdftv_12_avx
+fftw_codelet_hc2cfdftv_12_sse2
+fftw_codelet_hc2cfdftv_16_avx
+fftw_codelet_hc2cfdftv_16_sse2
+fftw_codelet_hc2cfdftv_20_avx
+fftw_codelet_hc2cfdftv_20_sse2
+fftw_codelet_hc2cfdftv_2_avx
+fftw_codelet_hc2cfdftv_2_sse2
+fftw_codelet_hc2cfdftv_32_avx
+fftw_codelet_hc2cfdftv_32_sse2
+fftw_codelet_hc2cfdftv_4_avx
+fftw_codelet_hc2cfdftv_4_sse2
+fftw_codelet_hc2cfdftv_6_avx
+fftw_codelet_hc2cfdftv_6_sse2
+fftw_codelet_hc2cfdftv_8_avx
+fftw_codelet_hc2cfdftv_8_sse2
+fftw_codelet_hf_10
+fftw_codelet_hf_12
+fftw_codelet_hf_15
+fftw_codelet_hf_16
+fftw_codelet_hf_2
+fftw_codelet_hf_20
+fftw_codelet_hf2_16
+fftw_codelet_hf2_20
+fftw_codelet_hf2_25
+fftw_codelet_hf2_32
+fftw_codelet_hf2_4
+fftw_codelet_hf_25
+fftw_codelet_hf2_5
+fftw_codelet_hf2_8
+fftw_codelet_hf_3
+fftw_codelet_hf_32
+fftw_codelet_hf_4
+fftw_codelet_hf_5
+fftw_codelet_hf_6
+fftw_codelet_hf_64
+fftw_codelet_hf_7
+fftw_codelet_hf_8
+fftw_codelet_hf_9
+fftw_codelet_n1_10
+fftw_codelet_n1_11
+fftw_codelet_n1_12
+fftw_codelet_n1_13
+fftw_codelet_n1_14
+fftw_codelet_n1_15
+fftw_codelet_n1_16
+fftw_codelet_n1_2
+fftw_codelet_n1_20
+fftw_codelet_n1_25
+fftw_codelet_n1_3
+fftw_codelet_n1_32
+fftw_codelet_n1_4
+fftw_codelet_n1_5
+fftw_codelet_n1_6
+fftw_codelet_n1_64
+fftw_codelet_n1_7
+fftw_codelet_n1_8
+fftw_codelet_n1_9
+fftw_codelet_n1bv_10_avx
+fftw_codelet_n1bv_10_sse2
+fftw_codelet_n1bv_11_avx
+fftw_codelet_n1bv_11_sse2
+fftw_codelet_n1bv_128_avx
+fftw_codelet_n1bv_128_sse2
+fftw_codelet_n1bv_12_avx
+fftw_codelet_n1bv_12_sse2
+fftw_codelet_n1bv_13_avx
+fftw_codelet_n1bv_13_sse2
+fftw_codelet_n1bv_14_avx
+fftw_codelet_n1bv_14_sse2
+fftw_codelet_n1bv_15_avx
+fftw_codelet_n1bv_15_sse2
+fftw_codelet_n1bv_16_avx
+fftw_codelet_n1bv_16_sse2
+fftw_codelet_n1bv_20_avx
+fftw_codelet_n1bv_20_sse2
+fftw_codelet_n1bv_25_avx
+fftw_codelet_n1bv_25_sse2
+fftw_codelet_n1bv_2_avx
+fftw_codelet_n1bv_2_sse2
+fftw_codelet_n1bv_32_avx
+fftw_codelet_n1bv_32_sse2
+fftw_codelet_n1bv_3_avx
+fftw_codelet_n1bv_3_sse2
+fftw_codelet_n1bv_4_avx
+fftw_codelet_n1bv_4_sse2
+fftw_codelet_n1bv_5_avx
+fftw_codelet_n1bv_5_sse2
+fftw_codelet_n1bv_64_avx
+fftw_codelet_n1bv_64_sse2
+fftw_codelet_n1bv_6_avx
+fftw_codelet_n1bv_6_sse2
+fftw_codelet_n1bv_7_avx
+fftw_codelet_n1bv_7_sse2
+fftw_codelet_n1bv_8_avx
+fftw_codelet_n1bv_8_sse2
+fftw_codelet_n1bv_9_avx
+fftw_codelet_n1bv_9_sse2
+fftw_codelet_n1fv_10_avx
+fftw_codelet_n1fv_10_sse2
+fftw_codelet_n1fv_11_avx
+fftw_codelet_n1fv_11_sse2
+fftw_codelet_n1fv_128_avx
+fftw_codelet_n1fv_128_sse2
+fftw_codelet_n1fv_12_avx
+fftw_codelet_n1fv_12_sse2
+fftw_codelet_n1fv_13_avx
+fftw_codelet_n1fv_13_sse2
+fftw_codelet_n1fv_14_avx
+fftw_codelet_n1fv_14_sse2
+fftw_codelet_n1fv_15_avx
+fftw_codelet_n1fv_15_sse2
+fftw_codelet_n1fv_16_avx
+fftw_codelet_n1fv_16_sse2
+fftw_codelet_n1fv_20_avx
+fftw_codelet_n1fv_20_sse2
+fftw_codelet_n1fv_25_avx
+fftw_codelet_n1fv_25_sse2
+fftw_codelet_n1fv_2_avx
+fftw_codelet_n1fv_2_sse2
+fftw_codelet_n1fv_32_avx
+fftw_codelet_n1fv_32_sse2
+fftw_codelet_n1fv_3_avx
+fftw_codelet_n1fv_3_sse2
+fftw_codelet_n1fv_4_avx
+fftw_codelet_n1fv_4_sse2
+fftw_codelet_n1fv_5_avx
+fftw_codelet_n1fv_5_sse2
+fftw_codelet_n1fv_64_avx
+fftw_codelet_n1fv_64_sse2
+fftw_codelet_n1fv_6_avx
+fftw_codelet_n1fv_6_sse2
+fftw_codelet_n1fv_7_avx
+fftw_codelet_n1fv_7_sse2
+fftw_codelet_n1fv_8_avx
+fftw_codelet_n1fv_8_sse2
+fftw_codelet_n1fv_9_avx
+fftw_codelet_n1fv_9_sse2
+fftw_codelet_n2bv_10_avx
+fftw_codelet_n2bv_10_sse2
+fftw_codelet_n2bv_12_avx
+fftw_codelet_n2bv_12_sse2
+fftw_codelet_n2bv_14_avx
+fftw_codelet_n2bv_14_sse2
+fftw_codelet_n2bv_16_avx
+fftw_codelet_n2bv_16_sse2
+fftw_codelet_n2bv_20_avx
+fftw_codelet_n2bv_20_sse2
+fftw_codelet_n2bv_2_avx
+fftw_codelet_n2bv_2_sse2
+fftw_codelet_n2bv_32_avx
+fftw_codelet_n2bv_32_sse2
+fftw_codelet_n2bv_4_avx
+fftw_codelet_n2bv_4_sse2
+fftw_codelet_n2bv_64_avx
+fftw_codelet_n2bv_64_sse2
+fftw_codelet_n2bv_6_avx
+fftw_codelet_n2bv_6_sse2
+fftw_codelet_n2bv_8_avx
+fftw_codelet_n2bv_8_sse2
+fftw_codelet_n2fv_10_avx
+fftw_codelet_n2fv_10_sse2
+fftw_codelet_n2fv_12_avx
+fftw_codelet_n2fv_12_sse2
+fftw_codelet_n2fv_14_avx
+fftw_codelet_n2fv_14_sse2
+fftw_codelet_n2fv_16_avx
+fftw_codelet_n2fv_16_sse2
+fftw_codelet_n2fv_20_avx
+fftw_codelet_n2fv_20_sse2
+fftw_codelet_n2fv_2_avx
+fftw_codelet_n2fv_2_sse2
+fftw_codelet_n2fv_32_avx
+fftw_codelet_n2fv_32_sse2
+fftw_codelet_n2fv_4_avx
+fftw_codelet_n2fv_4_sse2
+fftw_codelet_n2fv_64_avx
+fftw_codelet_n2fv_64_sse2
+fftw_codelet_n2fv_6_avx
+fftw_codelet_n2fv_6_sse2
+fftw_codelet_n2fv_8_avx
+fftw_codelet_n2fv_8_sse2
+fftw_codelet_n2sv_16_avx
+fftw_codelet_n2sv_16_sse2
+fftw_codelet_n2sv_32_avx
+fftw_codelet_n2sv_32_sse2
+fftw_codelet_n2sv_4_avx
+fftw_codelet_n2sv_4_sse2
+fftw_codelet_n2sv_64_avx
+fftw_codelet_n2sv_64_sse2
+fftw_codelet_n2sv_8_avx
+fftw_codelet_n2sv_8_sse2
+fftw_codelet_q1_2
+fftw_codelet_q1_3
+fftw_codelet_q1_4
+fftw_codelet_q1_5
+fftw_codelet_q1_6
+fftw_codelet_q1_8
+fftw_codelet_q1bv_2_avx
+fftw_codelet_q1bv_2_sse2
+fftw_codelet_q1bv_4_avx
+fftw_codelet_q1bv_4_sse2
+fftw_codelet_q1bv_5_avx
+fftw_codelet_q1bv_5_sse2
+fftw_codelet_q1bv_8_avx
+fftw_codelet_q1bv_8_sse2
+fftw_codelet_q1fv_2_avx
+fftw_codelet_q1fv_2_sse2
+fftw_codelet_q1fv_4_avx
+fftw_codelet_q1fv_4_sse2
+fftw_codelet_q1fv_5_avx
+fftw_codelet_q1fv_5_sse2
+fftw_codelet_q1fv_8_avx
+fftw_codelet_q1fv_8_sse2
+fftw_codelet_r2cb_10
+fftw_codelet_r2cb_11
+fftw_codelet_r2cb_12
+fftw_codelet_r2cb_128
+fftw_codelet_r2cb_13
+fftw_codelet_r2cb_14
+fftw_codelet_r2cb_15
+fftw_codelet_r2cb_16
+fftw_codelet_r2cb_2
+fftw_codelet_r2cb_20
+fftw_codelet_r2cb_25
+fftw_codelet_r2cb_3
+fftw_codelet_r2cb_32
+fftw_codelet_r2cb_4
+fftw_codelet_r2cb_5
+fftw_codelet_r2cb_6
+fftw_codelet_r2cb_64
+fftw_codelet_r2cb_7
+fftw_codelet_r2cb_8
+fftw_codelet_r2cb_9
+fftw_codelet_r2cbIII_10
+fftw_codelet_r2cbIII_12
+fftw_codelet_r2cbIII_15
+fftw_codelet_r2cbIII_16
+fftw_codelet_r2cbIII_2
+fftw_codelet_r2cbIII_20
+fftw_codelet_r2cbIII_25
+fftw_codelet_r2cbIII_3
+fftw_codelet_r2cbIII_32
+fftw_codelet_r2cbIII_4
+fftw_codelet_r2cbIII_5
+fftw_codelet_r2cbIII_6
+fftw_codelet_r2cbIII_64
+fftw_codelet_r2cbIII_7
+fftw_codelet_r2cbIII_8
+fftw_codelet_r2cbIII_9
+fftw_codelet_r2cf_10
+fftw_codelet_r2cf_11
+fftw_codelet_r2cf_12
+fftw_codelet_r2cf_128
+fftw_codelet_r2cf_13
+fftw_codelet_r2cf_14
+fftw_codelet_r2cf_15
+fftw_codelet_r2cf_16
+fftw_codelet_r2cf_2
+fftw_codelet_r2cf_20
+fftw_codelet_r2cf_25
+fftw_codelet_r2cf_3
+fftw_codelet_r2cf_32
+fftw_codelet_r2cf_4
+fftw_codelet_r2cf_5
+fftw_codelet_r2cf_6
+fftw_codelet_r2cf_64
+fftw_codelet_r2cf_7
+fftw_codelet_r2cf_8
+fftw_codelet_r2cf_9
+fftw_codelet_r2cfII_10
+fftw_codelet_r2cfII_12
+fftw_codelet_r2cfII_15
+fftw_codelet_r2cfII_16
+fftw_codelet_r2cfII_2
+fftw_codelet_r2cfII_20
+fftw_codelet_r2cfII_25
+fftw_codelet_r2cfII_3
+fftw_codelet_r2cfII_32
+fftw_codelet_r2cfII_4
+fftw_codelet_r2cfII_5
+fftw_codelet_r2cfII_6
+fftw_codelet_r2cfII_64
+fftw_codelet_r2cfII_7
+fftw_codelet_r2cfII_8
+fftw_codelet_r2cfII_9
+fftw_codelet_t1_10
+fftw_codelet_t1_12
+fftw_codelet_t1_15
+fftw_codelet_t1_16
+fftw_codelet_t1_2
+fftw_codelet_t1_20
+fftw_codelet_t1_25
+fftw_codelet_t1_3
+fftw_codelet_t1_32
+fftw_codelet_t1_4
+fftw_codelet_t1_5
+fftw_codelet_t1_6
+fftw_codelet_t1_64
+fftw_codelet_t1_7
+fftw_codelet_t1_8
+fftw_codelet_t1_9
+fftw_codelet_t1buv_10_avx
+fftw_codelet_t1buv_10_sse2
+fftw_codelet_t1buv_2_avx
+fftw_codelet_t1buv_2_sse2
+fftw_codelet_t1buv_3_avx
+fftw_codelet_t1buv_3_sse2
+fftw_codelet_t1buv_4_avx
+fftw_codelet_t1buv_4_sse2
+fftw_codelet_t1buv_5_avx
+fftw_codelet_t1buv_5_sse2
+fftw_codelet_t1buv_6_avx
+fftw_codelet_t1buv_6_sse2
+fftw_codelet_t1buv_7_avx
+fftw_codelet_t1buv_7_sse2
+fftw_codelet_t1buv_8_avx
+fftw_codelet_t1buv_8_sse2
+fftw_codelet_t1buv_9_avx
+fftw_codelet_t1buv_9_sse2
+fftw_codelet_t1bv_10_avx
+fftw_codelet_t1bv_10_sse2
+fftw_codelet_t1bv_12_avx
+fftw_codelet_t1bv_12_sse2
+fftw_codelet_t1bv_15_avx
+fftw_codelet_t1bv_15_sse2
+fftw_codelet_t1bv_16_avx
+fftw_codelet_t1bv_16_sse2
+fftw_codelet_t1bv_20_avx
+fftw_codelet_t1bv_20_sse2
+fftw_codelet_t1bv_25_avx
+fftw_codelet_t1bv_25_sse2
+fftw_codelet_t1bv_2_avx
+fftw_codelet_t1bv_2_sse2
+fftw_codelet_t1bv_32_avx
+fftw_codelet_t1bv_32_sse2
+fftw_codelet_t1bv_3_avx
+fftw_codelet_t1bv_3_sse2
+fftw_codelet_t1bv_4_avx
+fftw_codelet_t1bv_4_sse2
+fftw_codelet_t1bv_5_avx
+fftw_codelet_t1bv_5_sse2
+fftw_codelet_t1bv_64_avx
+fftw_codelet_t1bv_64_sse2
+fftw_codelet_t1bv_6_avx
+fftw_codelet_t1bv_6_sse2
+fftw_codelet_t1bv_7_avx
+fftw_codelet_t1bv_7_sse2
+fftw_codelet_t1bv_8_avx
+fftw_codelet_t1bv_8_sse2
+fftw_codelet_t1bv_9_avx
+fftw_codelet_t1bv_9_sse2
+fftw_codelet_t1fuv_10_avx
+fftw_codelet_t1fuv_10_sse2
+fftw_codelet_t1fuv_2_avx
+fftw_codelet_t1fuv_2_sse2
+fftw_codelet_t1fuv_3_avx
+fftw_codelet_t1fuv_3_sse2
+fftw_codelet_t1fuv_4_avx
+fftw_codelet_t1fuv_4_sse2
+fftw_codelet_t1fuv_5_avx
+fftw_codelet_t1fuv_5_sse2
+fftw_codelet_t1fuv_6_avx
+fftw_codelet_t1fuv_6_sse2
+fftw_codelet_t1fuv_7_avx
+fftw_codelet_t1fuv_7_sse2
+fftw_codelet_t1fuv_8_avx
+fftw_codelet_t1fuv_8_sse2
+fftw_codelet_t1fuv_9_avx
+fftw_codelet_t1fuv_9_sse2
+fftw_codelet_t1fv_10_avx
+fftw_codelet_t1fv_10_sse2
+fftw_codelet_t1fv_12_avx
+fftw_codelet_t1fv_12_sse2
+fftw_codelet_t1fv_15_avx
+fftw_codelet_t1fv_15_sse2
+fftw_codelet_t1fv_16_avx
+fftw_codelet_t1fv_16_sse2
+fftw_codelet_t1fv_20_avx
+fftw_codelet_t1fv_20_sse2
+fftw_codelet_t1fv_25_avx
+fftw_codelet_t1fv_25_sse2
+fftw_codelet_t1fv_2_avx
+fftw_codelet_t1fv_2_sse2
+fftw_codelet_t1fv_32_avx
+fftw_codelet_t1fv_32_sse2
+fftw_codelet_t1fv_3_avx
+fftw_codelet_t1fv_3_sse2
+fftw_codelet_t1fv_4_avx
+fftw_codelet_t1fv_4_sse2
+fftw_codelet_t1fv_5_avx
+fftw_codelet_t1fv_5_sse2
+fftw_codelet_t1fv_64_avx
+fftw_codelet_t1fv_64_sse2
+fftw_codelet_t1fv_6_avx
+fftw_codelet_t1fv_6_sse2
+fftw_codelet_t1fv_7_avx
+fftw_codelet_t1fv_7_sse2
+fftw_codelet_t1fv_8_avx
+fftw_codelet_t1fv_8_sse2
+fftw_codelet_t1fv_9_avx
+fftw_codelet_t1fv_9_sse2
+fftw_codelet_t1sv_16_avx
+fftw_codelet_t1sv_16_sse2
+fftw_codelet_t1sv_2_avx
+fftw_codelet_t1sv_2_sse2
+fftw_codelet_t1sv_32_avx
+fftw_codelet_t1sv_32_sse2
+fftw_codelet_t1sv_4_avx
+fftw_codelet_t1sv_4_sse2
+fftw_codelet_t1sv_8_avx
+fftw_codelet_t1sv_8_sse2
+fftw_codelet_t2_10
+fftw_codelet_t2_16
+fftw_codelet_t2_20
+fftw_codelet_t2_25
+fftw_codelet_t2_32
+fftw_codelet_t2_4
+fftw_codelet_t2_5
+fftw_codelet_t2_64
+fftw_codelet_t2_8
+fftw_codelet_t2bv_10_avx
+fftw_codelet_t2bv_10_sse2
+fftw_codelet_t2bv_16_avx
+fftw_codelet_t2bv_16_sse2
+fftw_codelet_t2bv_20_avx
+fftw_codelet_t2bv_20_sse2
+fftw_codelet_t2bv_25_avx
+fftw_codelet_t2bv_25_sse2
+fftw_codelet_t2bv_2_avx
+fftw_codelet_t2bv_2_sse2
+fftw_codelet_t2bv_32_avx
+fftw_codelet_t2bv_32_sse2
+fftw_codelet_t2bv_4_avx
+fftw_codelet_t2bv_4_sse2
+fftw_codelet_t2bv_5_avx
+fftw_codelet_t2bv_5_sse2
+fftw_codelet_t2bv_64_avx
+fftw_codelet_t2bv_64_sse2
+fftw_codelet_t2bv_8_avx
+fftw_codelet_t2bv_8_sse2
+fftw_codelet_t2fv_10_avx
+fftw_codelet_t2fv_10_sse2
+fftw_codelet_t2fv_16_avx
+fftw_codelet_t2fv_16_sse2
+fftw_codelet_t2fv_20_avx
+fftw_codelet_t2fv_20_sse2
+fftw_codelet_t2fv_25_avx
+fftw_codelet_t2fv_25_sse2
+fftw_codelet_t2fv_2_avx
+fftw_codelet_t2fv_2_sse2
+fftw_codelet_t2fv_32_avx
+fftw_codelet_t2fv_32_sse2
+fftw_codelet_t2fv_4_avx
+fftw_codelet_t2fv_4_sse2
+fftw_codelet_t2fv_5_avx
+fftw_codelet_t2fv_5_sse2
+fftw_codelet_t2fv_64_avx
+fftw_codelet_t2fv_64_sse2
+fftw_codelet_t2fv_8_avx
+fftw_codelet_t2fv_8_sse2
+fftw_codelet_t2sv_16_avx
+fftw_codelet_t2sv_16_sse2
+fftw_codelet_t2sv_32_avx
+fftw_codelet_t2sv_32_sse2
+fftw_codelet_t2sv_4_avx
+fftw_codelet_t2sv_4_sse2
+fftw_codelet_t2sv_8_avx
+fftw_codelet_t2sv_8_sse2
+fftw_codelet_t3bv_10_avx
+fftw_codelet_t3bv_10_sse2
+fftw_codelet_t3bv_16_avx
+fftw_codelet_t3bv_16_sse2
+fftw_codelet_t3bv_20_avx
+fftw_codelet_t3bv_20_sse2
+fftw_codelet_t3bv_25_avx
+fftw_codelet_t3bv_25_sse2
+fftw_codelet_t3bv_32_avx
+fftw_codelet_t3bv_32_sse2
+fftw_codelet_t3bv_4_avx
+fftw_codelet_t3bv_4_sse2
+fftw_codelet_t3bv_5_avx
+fftw_codelet_t3bv_5_sse2
+fftw_codelet_t3bv_8_avx
+fftw_codelet_t3bv_8_sse2
+fftw_codelet_t3fv_10_avx
+fftw_codelet_t3fv_10_sse2
+fftw_codelet_t3fv_16_avx
+fftw_codelet_t3fv_16_sse2
+fftw_codelet_t3fv_20_avx
+fftw_codelet_t3fv_20_sse2
+fftw_codelet_t3fv_25_avx
+fftw_codelet_t3fv_25_sse2
+fftw_codelet_t3fv_32_avx
+fftw_codelet_t3fv_32_sse2
+fftw_codelet_t3fv_4_avx
+fftw_codelet_t3fv_4_sse2
+fftw_codelet_t3fv_5_avx
+fftw_codelet_t3fv_5_sse2
+fftw_codelet_t3fv_8_avx
+fftw_codelet_t3fv_8_sse2
+fftw_compute_tilesz
+fftw_configure_planner
+fftw_cost
+fftw_cpy1d
+fftw_cpy2d
+fftw_cpy2d_ci
+fftw_cpy2d_co
+fftw_cpy2d_pair
+fftw_cpy2d_pair_ci
+fftw_cpy2d_pair_co
+fftw_cpy2d_tiled
+fftw_cpy2d_tiledbuf
+fftw_ct_applicable
+fftw_ct_genericbuf_register
+fftw_ct_generic_register
+fftw_ct_uglyp
+fftw_destroy_plan
+fftw_dft_bluestein_register
+fftw_dft_buffered_register
+fftw_dft_conf_standard
+fftw_dft_generic_register
+fftw_dft_indirect_register
+fftw_dft_indirect_transpose_register
+fftw_dft_nop_register
+fftw_dft_r2hc_register
+fftw_dft_rader_register
+fftw_dft_rank_geq2_register
+fftw_dft_solve
+fftw_dft_thr_vrank_geq1_register
+fftw_dft_vrank_geq1_register
+fftw_dft_zerotens
+fftw_dht_r2hc_register
+fftw_dht_rader_register
+fftw_dimcmp
+fftw_elapsed_since
+fftw_estimate_cost
+fftw_execute
+fftw_execute_dft
+fftw_execute_dft_c2r
+fftw_execute_dft_r2c
+fftw_execute_r2r
+fftw_execute_split_dft
+fftw_execute_split_dft_c2r
+fftw_execute_split_dft_r2c
+fftw_export_wisdom
+fftw_export_wisdom_to_file
+fftw_export_wisdom_to_filename
+fftw_export_wisdom_to_string
+fftw_extract_reim
+fftw_factors_into
+fftw_factors_into_small_primes
+fftw_find_generator
+fftw_first_divisor
+fftw_flops
+fftw_forget_wisdom
+fftw_fprint_plan
+fftw_free
+fftw_get_crude_time
+fftw_guru64_kosherp
+fftw_guru_kosherp
+fftw_hash
+fftw_have_simd_avx
+fftw_have_simd_sse2
+fftw_hc2hc_applicable
+fftw_hc2hc_generic_register
+fftw_iabs
+fftw_ialignment_of
+fftw_iestimate_cost
+fftw_ifree
+fftw_ifree0
+fftw_imax
+fftw_imin
+fftw_import_system_wisdom
+fftw_import_wisdom
+fftw_import_wisdom_from_file
+fftw_import_wisdom_from_filename
+fftw_import_wisdom_from_string
+fftw_init_threads
+fftw_is_prime
+fftw_isqrt
+fftw_ithreads_init
+fftw_join_taint
+fftw_kdft_dif_register
+fftw_kdft_difsq_register
+fftw_kdft_dit_register
+fftw_kdft_register
+fftw_kernel_free
+fftw_kernel_malloc
+fftw_khc2c_register
+fftw_khc2hc_register
+fftw_kr2c_register
+fftw_kr2r_register
+fftw_make_planner_thread_safe
+fftw_malloc
+fftw_malloc_plain
+fftw_many_kosherp
+fftw_mapflags
+fftw_map_r2r_kind
+fftw_md5begin
+fftw_md5end
+fftw_md5int
+fftw_md5INT
+fftw_md5putb
+fftw_md5putc
+fftw_md5puts
+fftw_md5unsigned
+fftw_measure_execution_time
+fftw_mkapiplan
+fftw_mkplan
+fftw_mkplan_d
+fftw_mkplan_dft
+fftw_mkplan_dftw
+fftw_mkplan_f_d
+fftw_mkplan_hc2c
+fftw_mkplan_hc2hc
+fftw_mkplanner
+fftw_mkplan_rdft
+fftw_mkplan_rdft2
+fftw_mkprinter
+fftw_mkprinter_cnt
+fftw_mkprinter_file
+fftw_mkprinter_str
+fftw_mkproblem
+fftw_mkproblem_dft
+fftw_mkproblem_dft_d
+fftw_mkproblem_rdft
+fftw_mkproblem_rdft_0_d
+fftw_mkproblem_rdft_1
+fftw_mkproblem_rdft_1_d
+fftw_mkproblem_rdft2
+fftw_mkproblem_rdft2_d
+fftw_mkproblem_rdft2_d_3pointers
+fftw_mkproblem_rdft_d
+fftw_mkproblem_unsolvable
+fftw_mkscanner
+fftw_mksolver
+fftw_mksolver_ct
+fftw_mksolver_ct_threads
+fftw_mksolver_dft_direct
+fftw_mksolver_dft_directbuf
+fftw_mksolver_hc2c
+fftw_mksolver_hc2hc
+fftw_mksolver_hc2hc_threads
+fftw_mksolver_rdft2_direct
+fftw_mksolver_rdft_r2c_direct
+fftw_mksolver_rdft_r2c_directbuf
+fftw_mksolver_rdft_r2r_direct
+fftw_mkstride
+fftw_mktensor
+fftw_mktensor_0d
+fftw_mktensor_1d
+fftw_mktensor_2d
+fftw_mktensor_3d
+fftw_mktensor_4d
+fftw_mktensor_5d
+fftw_mktensor_iodims
+fftw_mktensor_iodims64
+fftw_mktensor_rowmajor
+fftw_mktriggen
+fftw_modulo
+fftw_nbuf
+fftw_nbuf_redundant
+fftw_next_prime
+fftw_null_awake
+fftw_ops_add
+fftw_ops_add2
+fftw_ops_cpy
+fftw_ops_madd
+fftw_ops_madd2
+fftw_ops_other
+fftw_ops_zero
+fftw_pickdim
+fftw_plan_awake
+fftw_plan_destroy_internal
+fftw_plan_dft
+fftw_plan_dft_1d
+fftw_plan_dft_2d
+fftw_plan_dft_3d
+fftw_plan_dft_c2r
+fftw_plan_dft_c2r_1d
+fftw_plan_dft_c2r_2d
+fftw_plan_dft_c2r_3d
+fftw_plan_dft_r2c
+fftw_plan_dft_r2c_1d
+fftw_plan_dft_r2c_2d
+fftw_plan_dft_r2c_3d
+fftw_plan_guru64_dft
+fftw_plan_guru64_dft_c2r
+fftw_plan_guru64_dft_r2c
+fftw_plan_guru64_r2r
+fftw_plan_guru64_split_dft
+fftw_plan_guru64_split_dft_c2r
+fftw_plan_guru64_split_dft_r2c
+fftw_plan_guru_dft
+fftw_plan_guru_dft_c2r
+fftw_plan_guru_dft_r2c
+fftw_plan_guru_r2r
+fftw_plan_guru_split_dft
+fftw_plan_guru_split_dft_c2r
+fftw_plan_guru_split_dft_r2c
+fftw_plan_many_dft
+fftw_plan_many_dft_c2r
+fftw_plan_many_dft_r2c
+fftw_plan_many_r2r
+fftw_planner_destroy
+fftw_plan_null_destroy
+fftw_plan_r2r
+fftw_plan_r2r_1d
+fftw_plan_r2r_2d
+fftw_plan_r2r_3d
+fftw_plan_with_nthreads
+fftw_power_mod
+fftw_printer_destroy
+fftw_print_plan
+fftw_problem_destroy
+fftw_rader_tl_delete
+fftw_rader_tl_find
+fftw_rader_tl_insert
+fftw_rdft2_buffered_register
+fftw_rdft2_complex_n
+fftw_rdft2_inplace_strides
+fftw_rdft2_nop_register
+fftw_rdft2_pad
+fftw_rdft2_rank0_register
+fftw_rdft2_rank_geq2_register
+fftw_rdft2_rdft_register
+fftw_rdft2_solve
+fftw_rdft2_strides
+fftw_rdft2_tensor_max_index
+fftw_rdft2_thr_vrank_geq1_register
+fftw_rdft2_vrank_geq1_register
+fftw_rdft_buffered_register
+fftw_rdft_conf_standard
+fftw_rdft_dht_register
+fftw_rdft_generic_register
+fftw_rdft_indirect_register
+fftw_rdft_kind_str
+fftw_rdft_nop_register
+fftw_rdft_rank0_register
+fftw_rdft_rank_geq2_register
+fftw_rdft_solve
+fftw_rdft_thr_vrank_geq1_register
+fftw_rdft_vrank3_transpose_register
+fftw_rdft_vrank_geq1_register
+fftw_rdft_zerotens
+fftw_redft00e_r2hc_pad_register
+fftw_regsolver_ct_directw
+fftw_regsolver_ct_directwsq
+fftw_regsolver_hc2c_direct
+fftw_regsolver_hc2hc_direct
+fftw_reodft00e_splitradix_register
+fftw_reodft010e_r2hc_register
+fftw_reodft11e_r2hc_odd_register
+fftw_reodft11e_radix2_r2hc_register
+fftw_reodft_conf_standard
+fftw_rodft00e_r2hc_pad_register
+fftw_safe_mulmod
+fftw_scanner_destroy
+fftw_set_planner_hooks
+fftw_set_timelimit
+fftw_solver_destroy
+fftw_solver_register
+fftw_solver_use
+fftw_solvtab_exec
+fftw_spawn_loop
+fftw_sprint_plan
+fftw_stride_destroy
+fftw_taint
+fftw_tensor_append
+fftw_tensor_compress
+fftw_tensor_compress_contiguous
+fftw_tensor_copy
+fftw_tensor_copy_except
+fftw_tensor_copy_inplace
+fftw_tensor_copy_sub
+fftw_tensor_destroy
+fftw_tensor_destroy2
+fftw_tensor_destroy4
+fftw_tensor_equal
+fftw_tensor_inplace_locations
+fftw_tensor_inplace_strides
+fftw_tensor_inplace_strides2
+fftw_tensor_kosherp
+fftw_tensor_max_index
+fftw_tensor_md5
+fftw_tensor_min_istride
+fftw_tensor_min_ostride
+fftw_tensor_min_stride
+fftw_tensor_print
+fftw_tensor_split
+fftw_tensor_strides_decrease
+fftw_tensor_sz
+fftw_tensor_tornk1
+fftw_the_planner
+fftw_threads_cleanup
+fftw_threads_conf_standard
+fftw_threads_register_planner_hooks
+fftw_tile2d
+fftw_toobig
+fftw_transpose
+fftw_transpose_tiled
+fftw_transpose_tiledbuf
+fftw_triggen_destroy
+fftw_twiddle_awake
+fftw_twiddle_length
+fftw_zero1d_pair
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.exp b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.exp
new file mode 100644
index 0000000..5048009
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.exp
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.lib b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.lib
new file mode 100644
index 0000000..7103673
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3-3.lib
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.def b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.def
new file mode 100644
index 0000000..d61a2c3
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.def
@@ -0,0 +1,1017 @@
+LIBRARY libfftw3f-3.dll
+EXPORTS
+fftwf_alignment_of
+fftwf_alloc_complex
+fftwf_alloc_real
+fftwf_assertion_failed
+fftwf_bufdist
+fftwf_check_alignment_of_sse2_pm
+fftwf_choose_radix
+fftwf_cleanup
+fftwf_cleanup_threads
+fftwf_codelet_e01_8
+fftwf_codelet_e10_8
+fftwf_codelet_hb_10
+fftwf_codelet_hb_12
+fftwf_codelet_hb_15
+fftwf_codelet_hb_16
+fftwf_codelet_hb_2
+fftwf_codelet_hb_20
+fftwf_codelet_hb2_16
+fftwf_codelet_hb2_20
+fftwf_codelet_hb2_25
+fftwf_codelet_hb2_32
+fftwf_codelet_hb2_4
+fftwf_codelet_hb_25
+fftwf_codelet_hb2_5
+fftwf_codelet_hb2_8
+fftwf_codelet_hb_3
+fftwf_codelet_hb_32
+fftwf_codelet_hb_4
+fftwf_codelet_hb_5
+fftwf_codelet_hb_6
+fftwf_codelet_hb_64
+fftwf_codelet_hb_7
+fftwf_codelet_hb_8
+fftwf_codelet_hb_9
+fftwf_codelet_hc2cb_10
+fftwf_codelet_hc2cb_12
+fftwf_codelet_hc2cb_16
+fftwf_codelet_hc2cb_2
+fftwf_codelet_hc2cb_20
+fftwf_codelet_hc2cb2_16
+fftwf_codelet_hc2cb2_20
+fftwf_codelet_hc2cb2_32
+fftwf_codelet_hc2cb2_4
+fftwf_codelet_hc2cb2_8
+fftwf_codelet_hc2cb_32
+fftwf_codelet_hc2cb_4
+fftwf_codelet_hc2cb_6
+fftwf_codelet_hc2cb_8
+fftwf_codelet_hc2cbdft_10
+fftwf_codelet_hc2cbdft_12
+fftwf_codelet_hc2cbdft_16
+fftwf_codelet_hc2cbdft_2
+fftwf_codelet_hc2cbdft_20
+fftwf_codelet_hc2cbdft2_16
+fftwf_codelet_hc2cbdft2_20
+fftwf_codelet_hc2cbdft2_32
+fftwf_codelet_hc2cbdft2_4
+fftwf_codelet_hc2cbdft2_8
+fftwf_codelet_hc2cbdft_32
+fftwf_codelet_hc2cbdft_4
+fftwf_codelet_hc2cbdft_6
+fftwf_codelet_hc2cbdft_8
+fftwf_codelet_hc2cbdftv_10_avx
+fftwf_codelet_hc2cbdftv_10_sse2
+fftwf_codelet_hc2cbdftv_12_avx
+fftwf_codelet_hc2cbdftv_12_sse2
+fftwf_codelet_hc2cbdftv_16_avx
+fftwf_codelet_hc2cbdftv_16_sse2
+fftwf_codelet_hc2cbdftv_20_avx
+fftwf_codelet_hc2cbdftv_20_sse2
+fftwf_codelet_hc2cbdftv_2_avx
+fftwf_codelet_hc2cbdftv_2_sse2
+fftwf_codelet_hc2cbdftv_32_avx
+fftwf_codelet_hc2cbdftv_32_sse2
+fftwf_codelet_hc2cbdftv_4_avx
+fftwf_codelet_hc2cbdftv_4_sse2
+fftwf_codelet_hc2cbdftv_6_avx
+fftwf_codelet_hc2cbdftv_6_sse2
+fftwf_codelet_hc2cbdftv_8_avx
+fftwf_codelet_hc2cbdftv_8_sse2
+fftwf_codelet_hc2cf_10
+fftwf_codelet_hc2cf_12
+fftwf_codelet_hc2cf_16
+fftwf_codelet_hc2cf_2
+fftwf_codelet_hc2cf_20
+fftwf_codelet_hc2cf2_16
+fftwf_codelet_hc2cf2_20
+fftwf_codelet_hc2cf2_32
+fftwf_codelet_hc2cf2_4
+fftwf_codelet_hc2cf2_8
+fftwf_codelet_hc2cf_32
+fftwf_codelet_hc2cf_4
+fftwf_codelet_hc2cf_6
+fftwf_codelet_hc2cf_8
+fftwf_codelet_hc2cfdft_10
+fftwf_codelet_hc2cfdft_12
+fftwf_codelet_hc2cfdft_16
+fftwf_codelet_hc2cfdft_2
+fftwf_codelet_hc2cfdft_20
+fftwf_codelet_hc2cfdft2_16
+fftwf_codelet_hc2cfdft2_20
+fftwf_codelet_hc2cfdft2_32
+fftwf_codelet_hc2cfdft2_4
+fftwf_codelet_hc2cfdft2_8
+fftwf_codelet_hc2cfdft_32
+fftwf_codelet_hc2cfdft_4
+fftwf_codelet_hc2cfdft_6
+fftwf_codelet_hc2cfdft_8
+fftwf_codelet_hc2cfdftv_10_avx
+fftwf_codelet_hc2cfdftv_10_sse2
+fftwf_codelet_hc2cfdftv_12_avx
+fftwf_codelet_hc2cfdftv_12_sse2
+fftwf_codelet_hc2cfdftv_16_avx
+fftwf_codelet_hc2cfdftv_16_sse2
+fftwf_codelet_hc2cfdftv_20_avx
+fftwf_codelet_hc2cfdftv_20_sse2
+fftwf_codelet_hc2cfdftv_2_avx
+fftwf_codelet_hc2cfdftv_2_sse2
+fftwf_codelet_hc2cfdftv_32_avx
+fftwf_codelet_hc2cfdftv_32_sse2
+fftwf_codelet_hc2cfdftv_4_avx
+fftwf_codelet_hc2cfdftv_4_sse2
+fftwf_codelet_hc2cfdftv_6_avx
+fftwf_codelet_hc2cfdftv_6_sse2
+fftwf_codelet_hc2cfdftv_8_avx
+fftwf_codelet_hc2cfdftv_8_sse2
+fftwf_codelet_hf_10
+fftwf_codelet_hf_12
+fftwf_codelet_hf_15
+fftwf_codelet_hf_16
+fftwf_codelet_hf_2
+fftwf_codelet_hf_20
+fftwf_codelet_hf2_16
+fftwf_codelet_hf2_20
+fftwf_codelet_hf2_25
+fftwf_codelet_hf2_32
+fftwf_codelet_hf2_4
+fftwf_codelet_hf_25
+fftwf_codelet_hf2_5
+fftwf_codelet_hf2_8
+fftwf_codelet_hf_3
+fftwf_codelet_hf_32
+fftwf_codelet_hf_4
+fftwf_codelet_hf_5
+fftwf_codelet_hf_6
+fftwf_codelet_hf_64
+fftwf_codelet_hf_7
+fftwf_codelet_hf_8
+fftwf_codelet_hf_9
+fftwf_codelet_n1_10
+fftwf_codelet_n1_11
+fftwf_codelet_n1_12
+fftwf_codelet_n1_13
+fftwf_codelet_n1_14
+fftwf_codelet_n1_15
+fftwf_codelet_n1_16
+fftwf_codelet_n1_2
+fftwf_codelet_n1_20
+fftwf_codelet_n1_25
+fftwf_codelet_n1_3
+fftwf_codelet_n1_32
+fftwf_codelet_n1_4
+fftwf_codelet_n1_5
+fftwf_codelet_n1_6
+fftwf_codelet_n1_64
+fftwf_codelet_n1_7
+fftwf_codelet_n1_8
+fftwf_codelet_n1_9
+fftwf_codelet_n1bv_10_avx
+fftwf_codelet_n1bv_10_sse2
+fftwf_codelet_n1bv_11_avx
+fftwf_codelet_n1bv_11_sse2
+fftwf_codelet_n1bv_128_avx
+fftwf_codelet_n1bv_128_sse2
+fftwf_codelet_n1bv_12_avx
+fftwf_codelet_n1bv_12_sse2
+fftwf_codelet_n1bv_13_avx
+fftwf_codelet_n1bv_13_sse2
+fftwf_codelet_n1bv_14_avx
+fftwf_codelet_n1bv_14_sse2
+fftwf_codelet_n1bv_15_avx
+fftwf_codelet_n1bv_15_sse2
+fftwf_codelet_n1bv_16_avx
+fftwf_codelet_n1bv_16_sse2
+fftwf_codelet_n1bv_20_avx
+fftwf_codelet_n1bv_20_sse2
+fftwf_codelet_n1bv_25_avx
+fftwf_codelet_n1bv_25_sse2
+fftwf_codelet_n1bv_2_avx
+fftwf_codelet_n1bv_2_sse2
+fftwf_codelet_n1bv_32_avx
+fftwf_codelet_n1bv_32_sse2
+fftwf_codelet_n1bv_3_avx
+fftwf_codelet_n1bv_3_sse2
+fftwf_codelet_n1bv_4_avx
+fftwf_codelet_n1bv_4_sse2
+fftwf_codelet_n1bv_5_avx
+fftwf_codelet_n1bv_5_sse2
+fftwf_codelet_n1bv_64_avx
+fftwf_codelet_n1bv_64_sse2
+fftwf_codelet_n1bv_6_avx
+fftwf_codelet_n1bv_6_sse2
+fftwf_codelet_n1bv_7_avx
+fftwf_codelet_n1bv_7_sse2
+fftwf_codelet_n1bv_8_avx
+fftwf_codelet_n1bv_8_sse2
+fftwf_codelet_n1bv_9_avx
+fftwf_codelet_n1bv_9_sse2
+fftwf_codelet_n1fv_10_avx
+fftwf_codelet_n1fv_10_sse2
+fftwf_codelet_n1fv_11_avx
+fftwf_codelet_n1fv_11_sse2
+fftwf_codelet_n1fv_128_avx
+fftwf_codelet_n1fv_128_sse2
+fftwf_codelet_n1fv_12_avx
+fftwf_codelet_n1fv_12_sse2
+fftwf_codelet_n1fv_13_avx
+fftwf_codelet_n1fv_13_sse2
+fftwf_codelet_n1fv_14_avx
+fftwf_codelet_n1fv_14_sse2
+fftwf_codelet_n1fv_15_avx
+fftwf_codelet_n1fv_15_sse2
+fftwf_codelet_n1fv_16_avx
+fftwf_codelet_n1fv_16_sse2
+fftwf_codelet_n1fv_20_avx
+fftwf_codelet_n1fv_20_sse2
+fftwf_codelet_n1fv_25_avx
+fftwf_codelet_n1fv_25_sse2
+fftwf_codelet_n1fv_2_avx
+fftwf_codelet_n1fv_2_sse2
+fftwf_codelet_n1fv_32_avx
+fftwf_codelet_n1fv_32_sse2
+fftwf_codelet_n1fv_3_avx
+fftwf_codelet_n1fv_3_sse2
+fftwf_codelet_n1fv_4_avx
+fftwf_codelet_n1fv_4_sse2
+fftwf_codelet_n1fv_5_avx
+fftwf_codelet_n1fv_5_sse2
+fftwf_codelet_n1fv_64_avx
+fftwf_codelet_n1fv_64_sse2
+fftwf_codelet_n1fv_6_avx
+fftwf_codelet_n1fv_6_sse2
+fftwf_codelet_n1fv_7_avx
+fftwf_codelet_n1fv_7_sse2
+fftwf_codelet_n1fv_8_avx
+fftwf_codelet_n1fv_8_sse2
+fftwf_codelet_n1fv_9_avx
+fftwf_codelet_n1fv_9_sse2
+fftwf_codelet_n2bv_10_avx
+fftwf_codelet_n2bv_10_sse2
+fftwf_codelet_n2bv_12_avx
+fftwf_codelet_n2bv_12_sse2
+fftwf_codelet_n2bv_14_avx
+fftwf_codelet_n2bv_14_sse2
+fftwf_codelet_n2bv_16_avx
+fftwf_codelet_n2bv_16_sse2
+fftwf_codelet_n2bv_20_avx
+fftwf_codelet_n2bv_20_sse2
+fftwf_codelet_n2bv_2_avx
+fftwf_codelet_n2bv_2_sse2
+fftwf_codelet_n2bv_32_avx
+fftwf_codelet_n2bv_32_sse2
+fftwf_codelet_n2bv_4_avx
+fftwf_codelet_n2bv_4_sse2
+fftwf_codelet_n2bv_64_avx
+fftwf_codelet_n2bv_64_sse2
+fftwf_codelet_n2bv_6_avx
+fftwf_codelet_n2bv_6_sse2
+fftwf_codelet_n2bv_8_avx
+fftwf_codelet_n2bv_8_sse2
+fftwf_codelet_n2fv_10_avx
+fftwf_codelet_n2fv_10_sse2
+fftwf_codelet_n2fv_12_avx
+fftwf_codelet_n2fv_12_sse2
+fftwf_codelet_n2fv_14_avx
+fftwf_codelet_n2fv_14_sse2
+fftwf_codelet_n2fv_16_avx
+fftwf_codelet_n2fv_16_sse2
+fftwf_codelet_n2fv_20_avx
+fftwf_codelet_n2fv_20_sse2
+fftwf_codelet_n2fv_2_avx
+fftwf_codelet_n2fv_2_sse2
+fftwf_codelet_n2fv_32_avx
+fftwf_codelet_n2fv_32_sse2
+fftwf_codelet_n2fv_4_avx
+fftwf_codelet_n2fv_4_sse2
+fftwf_codelet_n2fv_64_avx
+fftwf_codelet_n2fv_64_sse2
+fftwf_codelet_n2fv_6_avx
+fftwf_codelet_n2fv_6_sse2
+fftwf_codelet_n2fv_8_avx
+fftwf_codelet_n2fv_8_sse2
+fftwf_codelet_n2sv_16_avx
+fftwf_codelet_n2sv_16_sse2
+fftwf_codelet_n2sv_32_avx
+fftwf_codelet_n2sv_32_sse2
+fftwf_codelet_n2sv_4_avx
+fftwf_codelet_n2sv_4_sse2
+fftwf_codelet_n2sv_64_avx
+fftwf_codelet_n2sv_64_sse2
+fftwf_codelet_n2sv_8_avx
+fftwf_codelet_n2sv_8_sse2
+fftwf_codelet_q1_2
+fftwf_codelet_q1_3
+fftwf_codelet_q1_4
+fftwf_codelet_q1_5
+fftwf_codelet_q1_6
+fftwf_codelet_q1_8
+fftwf_codelet_q1bv_2_avx
+fftwf_codelet_q1bv_2_sse2
+fftwf_codelet_q1bv_4_avx
+fftwf_codelet_q1bv_4_sse2
+fftwf_codelet_q1bv_5_avx
+fftwf_codelet_q1bv_5_sse2
+fftwf_codelet_q1bv_8_avx
+fftwf_codelet_q1bv_8_sse2
+fftwf_codelet_q1fv_2_avx
+fftwf_codelet_q1fv_2_sse2
+fftwf_codelet_q1fv_4_avx
+fftwf_codelet_q1fv_4_sse2
+fftwf_codelet_q1fv_5_avx
+fftwf_codelet_q1fv_5_sse2
+fftwf_codelet_q1fv_8_avx
+fftwf_codelet_q1fv_8_sse2
+fftwf_codelet_r2cb_10
+fftwf_codelet_r2cb_11
+fftwf_codelet_r2cb_12
+fftwf_codelet_r2cb_128
+fftwf_codelet_r2cb_13
+fftwf_codelet_r2cb_14
+fftwf_codelet_r2cb_15
+fftwf_codelet_r2cb_16
+fftwf_codelet_r2cb_2
+fftwf_codelet_r2cb_20
+fftwf_codelet_r2cb_25
+fftwf_codelet_r2cb_3
+fftwf_codelet_r2cb_32
+fftwf_codelet_r2cb_4
+fftwf_codelet_r2cb_5
+fftwf_codelet_r2cb_6
+fftwf_codelet_r2cb_64
+fftwf_codelet_r2cb_7
+fftwf_codelet_r2cb_8
+fftwf_codelet_r2cb_9
+fftwf_codelet_r2cbIII_10
+fftwf_codelet_r2cbIII_12
+fftwf_codelet_r2cbIII_15
+fftwf_codelet_r2cbIII_16
+fftwf_codelet_r2cbIII_2
+fftwf_codelet_r2cbIII_20
+fftwf_codelet_r2cbIII_25
+fftwf_codelet_r2cbIII_3
+fftwf_codelet_r2cbIII_32
+fftwf_codelet_r2cbIII_4
+fftwf_codelet_r2cbIII_5
+fftwf_codelet_r2cbIII_6
+fftwf_codelet_r2cbIII_64
+fftwf_codelet_r2cbIII_7
+fftwf_codelet_r2cbIII_8
+fftwf_codelet_r2cbIII_9
+fftwf_codelet_r2cf_10
+fftwf_codelet_r2cf_11
+fftwf_codelet_r2cf_12
+fftwf_codelet_r2cf_128
+fftwf_codelet_r2cf_13
+fftwf_codelet_r2cf_14
+fftwf_codelet_r2cf_15
+fftwf_codelet_r2cf_16
+fftwf_codelet_r2cf_2
+fftwf_codelet_r2cf_20
+fftwf_codelet_r2cf_25
+fftwf_codelet_r2cf_3
+fftwf_codelet_r2cf_32
+fftwf_codelet_r2cf_4
+fftwf_codelet_r2cf_5
+fftwf_codelet_r2cf_6
+fftwf_codelet_r2cf_64
+fftwf_codelet_r2cf_7
+fftwf_codelet_r2cf_8
+fftwf_codelet_r2cf_9
+fftwf_codelet_r2cfII_10
+fftwf_codelet_r2cfII_12
+fftwf_codelet_r2cfII_15
+fftwf_codelet_r2cfII_16
+fftwf_codelet_r2cfII_2
+fftwf_codelet_r2cfII_20
+fftwf_codelet_r2cfII_25
+fftwf_codelet_r2cfII_3
+fftwf_codelet_r2cfII_32
+fftwf_codelet_r2cfII_4
+fftwf_codelet_r2cfII_5
+fftwf_codelet_r2cfII_6
+fftwf_codelet_r2cfII_64
+fftwf_codelet_r2cfII_7
+fftwf_codelet_r2cfII_8
+fftwf_codelet_r2cfII_9
+fftwf_codelet_t1_10
+fftwf_codelet_t1_12
+fftwf_codelet_t1_15
+fftwf_codelet_t1_16
+fftwf_codelet_t1_2
+fftwf_codelet_t1_20
+fftwf_codelet_t1_25
+fftwf_codelet_t1_3
+fftwf_codelet_t1_32
+fftwf_codelet_t1_4
+fftwf_codelet_t1_5
+fftwf_codelet_t1_6
+fftwf_codelet_t1_64
+fftwf_codelet_t1_7
+fftwf_codelet_t1_8
+fftwf_codelet_t1_9
+fftwf_codelet_t1buv_10_avx
+fftwf_codelet_t1buv_10_sse2
+fftwf_codelet_t1buv_2_avx
+fftwf_codelet_t1buv_2_sse2
+fftwf_codelet_t1buv_3_avx
+fftwf_codelet_t1buv_3_sse2
+fftwf_codelet_t1buv_4_avx
+fftwf_codelet_t1buv_4_sse2
+fftwf_codelet_t1buv_5_avx
+fftwf_codelet_t1buv_5_sse2
+fftwf_codelet_t1buv_6_avx
+fftwf_codelet_t1buv_6_sse2
+fftwf_codelet_t1buv_7_avx
+fftwf_codelet_t1buv_7_sse2
+fftwf_codelet_t1buv_8_avx
+fftwf_codelet_t1buv_8_sse2
+fftwf_codelet_t1buv_9_avx
+fftwf_codelet_t1buv_9_sse2
+fftwf_codelet_t1bv_10_avx
+fftwf_codelet_t1bv_10_sse2
+fftwf_codelet_t1bv_12_avx
+fftwf_codelet_t1bv_12_sse2
+fftwf_codelet_t1bv_15_avx
+fftwf_codelet_t1bv_15_sse2
+fftwf_codelet_t1bv_16_avx
+fftwf_codelet_t1bv_16_sse2
+fftwf_codelet_t1bv_20_avx
+fftwf_codelet_t1bv_20_sse2
+fftwf_codelet_t1bv_25_avx
+fftwf_codelet_t1bv_25_sse2
+fftwf_codelet_t1bv_2_avx
+fftwf_codelet_t1bv_2_sse2
+fftwf_codelet_t1bv_32_avx
+fftwf_codelet_t1bv_32_sse2
+fftwf_codelet_t1bv_3_avx
+fftwf_codelet_t1bv_3_sse2
+fftwf_codelet_t1bv_4_avx
+fftwf_codelet_t1bv_4_sse2
+fftwf_codelet_t1bv_5_avx
+fftwf_codelet_t1bv_5_sse2
+fftwf_codelet_t1bv_64_avx
+fftwf_codelet_t1bv_64_sse2
+fftwf_codelet_t1bv_6_avx
+fftwf_codelet_t1bv_6_sse2
+fftwf_codelet_t1bv_7_avx
+fftwf_codelet_t1bv_7_sse2
+fftwf_codelet_t1bv_8_avx
+fftwf_codelet_t1bv_8_sse2
+fftwf_codelet_t1bv_9_avx
+fftwf_codelet_t1bv_9_sse2
+fftwf_codelet_t1fuv_10_avx
+fftwf_codelet_t1fuv_10_sse2
+fftwf_codelet_t1fuv_2_avx
+fftwf_codelet_t1fuv_2_sse2
+fftwf_codelet_t1fuv_3_avx
+fftwf_codelet_t1fuv_3_sse2
+fftwf_codelet_t1fuv_4_avx
+fftwf_codelet_t1fuv_4_sse2
+fftwf_codelet_t1fuv_5_avx
+fftwf_codelet_t1fuv_5_sse2
+fftwf_codelet_t1fuv_6_avx
+fftwf_codelet_t1fuv_6_sse2
+fftwf_codelet_t1fuv_7_avx
+fftwf_codelet_t1fuv_7_sse2
+fftwf_codelet_t1fuv_8_avx
+fftwf_codelet_t1fuv_8_sse2
+fftwf_codelet_t1fuv_9_avx
+fftwf_codelet_t1fuv_9_sse2
+fftwf_codelet_t1fv_10_avx
+fftwf_codelet_t1fv_10_sse2
+fftwf_codelet_t1fv_12_avx
+fftwf_codelet_t1fv_12_sse2
+fftwf_codelet_t1fv_15_avx
+fftwf_codelet_t1fv_15_sse2
+fftwf_codelet_t1fv_16_avx
+fftwf_codelet_t1fv_16_sse2
+fftwf_codelet_t1fv_20_avx
+fftwf_codelet_t1fv_20_sse2
+fftwf_codelet_t1fv_25_avx
+fftwf_codelet_t1fv_25_sse2
+fftwf_codelet_t1fv_2_avx
+fftwf_codelet_t1fv_2_sse2
+fftwf_codelet_t1fv_32_avx
+fftwf_codelet_t1fv_32_sse2
+fftwf_codelet_t1fv_3_avx
+fftwf_codelet_t1fv_3_sse2
+fftwf_codelet_t1fv_4_avx
+fftwf_codelet_t1fv_4_sse2
+fftwf_codelet_t1fv_5_avx
+fftwf_codelet_t1fv_5_sse2
+fftwf_codelet_t1fv_64_avx
+fftwf_codelet_t1fv_64_sse2
+fftwf_codelet_t1fv_6_avx
+fftwf_codelet_t1fv_6_sse2
+fftwf_codelet_t1fv_7_avx
+fftwf_codelet_t1fv_7_sse2
+fftwf_codelet_t1fv_8_avx
+fftwf_codelet_t1fv_8_sse2
+fftwf_codelet_t1fv_9_avx
+fftwf_codelet_t1fv_9_sse2
+fftwf_codelet_t1sv_16_avx
+fftwf_codelet_t1sv_16_sse2
+fftwf_codelet_t1sv_2_avx
+fftwf_codelet_t1sv_2_sse2
+fftwf_codelet_t1sv_32_avx
+fftwf_codelet_t1sv_32_sse2
+fftwf_codelet_t1sv_4_avx
+fftwf_codelet_t1sv_4_sse2
+fftwf_codelet_t1sv_8_avx
+fftwf_codelet_t1sv_8_sse2
+fftwf_codelet_t2_10
+fftwf_codelet_t2_16
+fftwf_codelet_t2_20
+fftwf_codelet_t2_25
+fftwf_codelet_t2_32
+fftwf_codelet_t2_4
+fftwf_codelet_t2_5
+fftwf_codelet_t2_64
+fftwf_codelet_t2_8
+fftwf_codelet_t2bv_10_avx
+fftwf_codelet_t2bv_10_sse2
+fftwf_codelet_t2bv_16_avx
+fftwf_codelet_t2bv_16_sse2
+fftwf_codelet_t2bv_20_avx
+fftwf_codelet_t2bv_20_sse2
+fftwf_codelet_t2bv_25_avx
+fftwf_codelet_t2bv_25_sse2
+fftwf_codelet_t2bv_2_avx
+fftwf_codelet_t2bv_2_sse2
+fftwf_codelet_t2bv_32_avx
+fftwf_codelet_t2bv_32_sse2
+fftwf_codelet_t2bv_4_avx
+fftwf_codelet_t2bv_4_sse2
+fftwf_codelet_t2bv_5_avx
+fftwf_codelet_t2bv_5_sse2
+fftwf_codelet_t2bv_64_avx
+fftwf_codelet_t2bv_64_sse2
+fftwf_codelet_t2bv_8_avx
+fftwf_codelet_t2bv_8_sse2
+fftwf_codelet_t2fv_10_avx
+fftwf_codelet_t2fv_10_sse2
+fftwf_codelet_t2fv_16_avx
+fftwf_codelet_t2fv_16_sse2
+fftwf_codelet_t2fv_20_avx
+fftwf_codelet_t2fv_20_sse2
+fftwf_codelet_t2fv_25_avx
+fftwf_codelet_t2fv_25_sse2
+fftwf_codelet_t2fv_2_avx
+fftwf_codelet_t2fv_2_sse2
+fftwf_codelet_t2fv_32_avx
+fftwf_codelet_t2fv_32_sse2
+fftwf_codelet_t2fv_4_avx
+fftwf_codelet_t2fv_4_sse2
+fftwf_codelet_t2fv_5_avx
+fftwf_codelet_t2fv_5_sse2
+fftwf_codelet_t2fv_64_avx
+fftwf_codelet_t2fv_64_sse2
+fftwf_codelet_t2fv_8_avx
+fftwf_codelet_t2fv_8_sse2
+fftwf_codelet_t2sv_16_avx
+fftwf_codelet_t2sv_16_sse2
+fftwf_codelet_t2sv_32_avx
+fftwf_codelet_t2sv_32_sse2
+fftwf_codelet_t2sv_4_avx
+fftwf_codelet_t2sv_4_sse2
+fftwf_codelet_t2sv_8_avx
+fftwf_codelet_t2sv_8_sse2
+fftwf_codelet_t3bv_10_avx
+fftwf_codelet_t3bv_10_sse2
+fftwf_codelet_t3bv_16_avx
+fftwf_codelet_t3bv_16_sse2
+fftwf_codelet_t3bv_20_avx
+fftwf_codelet_t3bv_20_sse2
+fftwf_codelet_t3bv_25_avx
+fftwf_codelet_t3bv_25_sse2
+fftwf_codelet_t3bv_32_avx
+fftwf_codelet_t3bv_32_sse2
+fftwf_codelet_t3bv_4_avx
+fftwf_codelet_t3bv_4_sse2
+fftwf_codelet_t3bv_5_avx
+fftwf_codelet_t3bv_5_sse2
+fftwf_codelet_t3bv_8_avx
+fftwf_codelet_t3bv_8_sse2
+fftwf_codelet_t3fv_10_avx
+fftwf_codelet_t3fv_10_sse2
+fftwf_codelet_t3fv_16_avx
+fftwf_codelet_t3fv_16_sse2
+fftwf_codelet_t3fv_20_avx
+fftwf_codelet_t3fv_20_sse2
+fftwf_codelet_t3fv_25_avx
+fftwf_codelet_t3fv_25_sse2
+fftwf_codelet_t3fv_32_avx
+fftwf_codelet_t3fv_32_sse2
+fftwf_codelet_t3fv_4_avx
+fftwf_codelet_t3fv_4_sse2
+fftwf_codelet_t3fv_5_avx
+fftwf_codelet_t3fv_5_sse2
+fftwf_codelet_t3fv_8_avx
+fftwf_codelet_t3fv_8_sse2
+fftwf_compute_tilesz
+fftwf_configure_planner
+fftwf_cost
+fftwf_cpy1d
+fftwf_cpy2d
+fftwf_cpy2d_ci
+fftwf_cpy2d_co
+fftwf_cpy2d_pair
+fftwf_cpy2d_pair_ci
+fftwf_cpy2d_pair_co
+fftwf_cpy2d_tiled
+fftwf_cpy2d_tiledbuf
+fftwf_ct_applicable
+fftwf_ct_genericbuf_register
+fftwf_ct_generic_register
+fftwf_ct_uglyp
+fftwf_destroy_plan
+fftwf_dft_bluestein_register
+fftwf_dft_buffered_register
+fftwf_dft_conf_standard
+fftwf_dft_generic_register
+fftwf_dft_indirect_register
+fftwf_dft_indirect_transpose_register
+fftwf_dft_nop_register
+fftwf_dft_r2hc_register
+fftwf_dft_rader_register
+fftwf_dft_rank_geq2_register
+fftwf_dft_solve
+fftwf_dft_thr_vrank_geq1_register
+fftwf_dft_vrank_geq1_register
+fftwf_dft_zerotens
+fftwf_dht_r2hc_register
+fftwf_dht_rader_register
+fftwf_dimcmp
+fftwf_elapsed_since
+fftwf_estimate_cost
+fftwf_execute
+fftwf_execute_dft
+fftwf_execute_dft_c2r
+fftwf_execute_dft_r2c
+fftwf_execute_r2r
+fftwf_execute_split_dft
+fftwf_execute_split_dft_c2r
+fftwf_execute_split_dft_r2c
+fftwf_export_wisdom
+fftwf_export_wisdom_to_file
+fftwf_export_wisdom_to_filename
+fftwf_export_wisdom_to_string
+fftwf_extract_reim
+fftwf_factors_into
+fftwf_factors_into_small_primes
+fftwf_find_generator
+fftwf_first_divisor
+fftwf_flops
+fftwf_forget_wisdom
+fftwf_fprint_plan
+fftwf_free
+fftwf_get_crude_time
+fftwf_guru64_kosherp
+fftwf_guru_kosherp
+fftwf_hash
+fftwf_have_simd_avx
+fftwf_have_simd_sse2
+fftwf_hc2hc_applicable
+fftwf_hc2hc_generic_register
+fftwf_iabs
+fftwf_ialignment_of
+fftwf_iestimate_cost
+fftwf_ifree
+fftwf_ifree0
+fftwf_imax
+fftwf_imin
+fftwf_import_system_wisdom
+fftwf_import_wisdom
+fftwf_import_wisdom_from_file
+fftwf_import_wisdom_from_filename
+fftwf_import_wisdom_from_string
+fftwf_init_threads
+fftwf_is_prime
+fftwf_isqrt
+fftwf_ithreads_init
+fftwf_join_taint
+fftwf_kdft_dif_register
+fftwf_kdft_difsq_register
+fftwf_kdft_dit_register
+fftwf_kdft_register
+fftwf_kernel_free
+fftwf_kernel_malloc
+fftwf_khc2c_register
+fftwf_khc2hc_register
+fftwf_kr2c_register
+fftwf_kr2r_register
+fftwf_make_planner_thread_safe
+fftwf_malloc
+fftwf_malloc_plain
+fftwf_many_kosherp
+fftwf_mapflags
+fftwf_map_r2r_kind
+fftwf_md5begin
+fftwf_md5end
+fftwf_md5int
+fftwf_md5INT
+fftwf_md5putb
+fftwf_md5putc
+fftwf_md5puts
+fftwf_md5unsigned
+fftwf_measure_execution_time
+fftwf_mkapiplan
+fftwf_mkplan
+fftwf_mkplan_d
+fftwf_mkplan_dft
+fftwf_mkplan_dftw
+fftwf_mkplan_f_d
+fftwf_mkplan_hc2c
+fftwf_mkplan_hc2hc
+fftwf_mkplanner
+fftwf_mkplan_rdft
+fftwf_mkplan_rdft2
+fftwf_mkprinter
+fftwf_mkprinter_cnt
+fftwf_mkprinter_file
+fftwf_mkprinter_str
+fftwf_mkproblem
+fftwf_mkproblem_dft
+fftwf_mkproblem_dft_d
+fftwf_mkproblem_rdft
+fftwf_mkproblem_rdft_0_d
+fftwf_mkproblem_rdft_1
+fftwf_mkproblem_rdft_1_d
+fftwf_mkproblem_rdft2
+fftwf_mkproblem_rdft2_d
+fftwf_mkproblem_rdft2_d_3pointers
+fftwf_mkproblem_rdft_d
+fftwf_mkproblem_unsolvable
+fftwf_mkscanner
+fftwf_mksolver
+fftwf_mksolver_ct
+fftwf_mksolver_ct_threads
+fftwf_mksolver_dft_direct
+fftwf_mksolver_dft_directbuf
+fftwf_mksolver_hc2c
+fftwf_mksolver_hc2hc
+fftwf_mksolver_hc2hc_threads
+fftwf_mksolver_rdft2_direct
+fftwf_mksolver_rdft_r2c_direct
+fftwf_mksolver_rdft_r2c_directbuf
+fftwf_mksolver_rdft_r2r_direct
+fftwf_mkstride
+fftwf_mktensor
+fftwf_mktensor_0d
+fftwf_mktensor_1d
+fftwf_mktensor_2d
+fftwf_mktensor_3d
+fftwf_mktensor_4d
+fftwf_mktensor_5d
+fftwf_mktensor_iodims
+fftwf_mktensor_iodims64
+fftwf_mktensor_rowmajor
+fftwf_mktriggen
+fftwf_modulo
+fftwf_nbuf
+fftwf_nbuf_redundant
+fftwf_next_prime
+fftwf_null_awake
+fftwf_ops_add
+fftwf_ops_add2
+fftwf_ops_cpy
+fftwf_ops_madd
+fftwf_ops_madd2
+fftwf_ops_other
+fftwf_ops_zero
+fftwf_pickdim
+fftwf_plan_awake
+fftwf_plan_destroy_internal
+fftwf_plan_dft
+fftwf_plan_dft_1d
+fftwf_plan_dft_2d
+fftwf_plan_dft_3d
+fftwf_plan_dft_c2r
+fftwf_plan_dft_c2r_1d
+fftwf_plan_dft_c2r_2d
+fftwf_plan_dft_c2r_3d
+fftwf_plan_dft_r2c
+fftwf_plan_dft_r2c_1d
+fftwf_plan_dft_r2c_2d
+fftwf_plan_dft_r2c_3d
+fftwf_plan_guru64_dft
+fftwf_plan_guru64_dft_c2r
+fftwf_plan_guru64_dft_r2c
+fftwf_plan_guru64_r2r
+fftwf_plan_guru64_split_dft
+fftwf_plan_guru64_split_dft_c2r
+fftwf_plan_guru64_split_dft_r2c
+fftwf_plan_guru_dft
+fftwf_plan_guru_dft_c2r
+fftwf_plan_guru_dft_r2c
+fftwf_plan_guru_r2r
+fftwf_plan_guru_split_dft
+fftwf_plan_guru_split_dft_c2r
+fftwf_plan_guru_split_dft_r2c
+fftwf_plan_many_dft
+fftwf_plan_many_dft_c2r
+fftwf_plan_many_dft_r2c
+fftwf_plan_many_r2r
+fftwf_planner_destroy
+fftwf_plan_null_destroy
+fftwf_plan_r2r
+fftwf_plan_r2r_1d
+fftwf_plan_r2r_2d
+fftwf_plan_r2r_3d
+fftwf_plan_with_nthreads
+fftwf_power_mod
+fftwf_printer_destroy
+fftwf_print_plan
+fftwf_problem_destroy
+fftwf_rader_tl_delete
+fftwf_rader_tl_find
+fftwf_rader_tl_insert
+fftwf_rdft2_buffered_register
+fftwf_rdft2_complex_n
+fftwf_rdft2_inplace_strides
+fftwf_rdft2_nop_register
+fftwf_rdft2_pad
+fftwf_rdft2_rank0_register
+fftwf_rdft2_rank_geq2_register
+fftwf_rdft2_rdft_register
+fftwf_rdft2_solve
+fftwf_rdft2_strides
+fftwf_rdft2_tensor_max_index
+fftwf_rdft2_thr_vrank_geq1_register
+fftwf_rdft2_vrank_geq1_register
+fftwf_rdft_buffered_register
+fftwf_rdft_conf_standard
+fftwf_rdft_dht_register
+fftwf_rdft_generic_register
+fftwf_rdft_indirect_register
+fftwf_rdft_kind_str
+fftwf_rdft_nop_register
+fftwf_rdft_rank0_register
+fftwf_rdft_rank_geq2_register
+fftwf_rdft_solve
+fftwf_rdft_thr_vrank_geq1_register
+fftwf_rdft_vrank3_transpose_register
+fftwf_rdft_vrank_geq1_register
+fftwf_rdft_zerotens
+fftwf_redft00e_r2hc_pad_register
+fftwf_regsolver_ct_directw
+fftwf_regsolver_ct_directwsq
+fftwf_regsolver_hc2c_direct
+fftwf_regsolver_hc2hc_direct
+fftwf_reodft00e_splitradix_register
+fftwf_reodft010e_r2hc_register
+fftwf_reodft11e_r2hc_odd_register
+fftwf_reodft11e_radix2_r2hc_register
+fftwf_reodft_conf_standard
+fftwf_rodft00e_r2hc_pad_register
+fftwf_safe_mulmod
+fftwf_scanner_destroy
+fftwf_set_planner_hooks
+fftwf_set_timelimit
+fftwf_solver_destroy
+fftwf_solver_register
+fftwf_solver_use
+fftwf_solvtab_exec
+fftwf_spawn_loop
+fftwf_sprint_plan
+fftwf_stride_destroy
+fftwf_taint
+fftwf_tensor_append
+fftwf_tensor_compress
+fftwf_tensor_compress_contiguous
+fftwf_tensor_copy
+fftwf_tensor_copy_except
+fftwf_tensor_copy_inplace
+fftwf_tensor_copy_sub
+fftwf_tensor_destroy
+fftwf_tensor_destroy2
+fftwf_tensor_destroy4
+fftwf_tensor_equal
+fftwf_tensor_inplace_locations
+fftwf_tensor_inplace_strides
+fftwf_tensor_inplace_strides2
+fftwf_tensor_kosherp
+fftwf_tensor_max_index
+fftwf_tensor_md5
+fftwf_tensor_min_istride
+fftwf_tensor_min_ostride
+fftwf_tensor_min_stride
+fftwf_tensor_print
+fftwf_tensor_split
+fftwf_tensor_strides_decrease
+fftwf_tensor_sz
+fftwf_tensor_tornk1
+fftwf_the_planner
+fftwf_threads_cleanup
+fftwf_threads_conf_standard
+fftwf_threads_register_planner_hooks
+fftwf_tile2d
+fftwf_toobig
+fftwf_transpose
+fftwf_transpose_tiled
+fftwf_transpose_tiledbuf
+fftwf_triggen_destroy
+fftwf_twiddle_awake
+fftwf_twiddle_length
+fftwf_zero1d_pair
+sfftw_cleanup_
+sfftw_cleanup__
+sfftw_cleanup_threads_
+sfftw_cleanup_threads__
+sfftw_cost_
+sfftw_cost__
+sfftw_destroy_plan_
+sfftw_destroy_plan__
+sfftw_estimate_cost_
+sfftw_estimate_cost__
+sfftw_execute_
+sfftw_execute__
+sfftw_execute_dft_
+sfftw_execute_dft__
+sfftw_execute_dft_c2r_
+sfftw_execute_dft_c2r__
+sfftw_execute_dft_r2c_
+sfftw_execute_dft_r2c__
+sfftw_execute_r2r_
+sfftw_execute_r2r__
+sfftw_execute_split_dft_
+sfftw_execute_split_dft__
+sfftw_execute_split_dft_c2r_
+sfftw_execute_split_dft_c2r__
+sfftw_execute_split_dft_r2c_
+sfftw_execute_split_dft_r2c__
+sfftw_export_wisdom_
+sfftw_export_wisdom__
+sfftw_flops_
+sfftw_flops__
+sfftw_forget_wisdom_
+sfftw_forget_wisdom__
+sfftw_import_system_wisdom_
+sfftw_import_system_wisdom__
+sfftw_import_wisdom_
+sfftw_import_wisdom__
+sfftw_init_threads_
+sfftw_init_threads__
+sfftw_plan_dft_
+sfftw_plan_dft__
+sfftw_plan_dft_1d_
+sfftw_plan_dft_1d__
+sfftw_plan_dft_2d_
+sfftw_plan_dft_2d__
+sfftw_plan_dft_3d_
+sfftw_plan_dft_3d__
+sfftw_plan_dft_c2r_
+sfftw_plan_dft_c2r__
+sfftw_plan_dft_c2r_1d_
+sfftw_plan_dft_c2r_1d__
+sfftw_plan_dft_c2r_2d_
+sfftw_plan_dft_c2r_2d__
+sfftw_plan_dft_c2r_3d_
+sfftw_plan_dft_c2r_3d__
+sfftw_plan_dft_r2c_
+sfftw_plan_dft_r2c__
+sfftw_plan_dft_r2c_1d_
+sfftw_plan_dft_r2c_1d__
+sfftw_plan_dft_r2c_2d_
+sfftw_plan_dft_r2c_2d__
+sfftw_plan_dft_r2c_3d_
+sfftw_plan_dft_r2c_3d__
+sfftw_plan_guru_dft_
+sfftw_plan_guru_dft__
+sfftw_plan_guru_dft_c2r_
+sfftw_plan_guru_dft_c2r__
+sfftw_plan_guru_dft_r2c_
+sfftw_plan_guru_dft_r2c__
+sfftw_plan_guru_r2r_
+sfftw_plan_guru_r2r__
+sfftw_plan_guru_split_dft_
+sfftw_plan_guru_split_dft__
+sfftw_plan_guru_split_dft_c2r_
+sfftw_plan_guru_split_dft_c2r__
+sfftw_plan_guru_split_dft_r2c_
+sfftw_plan_guru_split_dft_r2c__
+sfftw_plan_many_dft_
+sfftw_plan_many_dft__
+sfftw_plan_many_dft_c2r_
+sfftw_plan_many_dft_c2r__
+sfftw_plan_many_dft_r2c_
+sfftw_plan_many_dft_r2c__
+sfftw_plan_many_r2r_
+sfftw_plan_many_r2r__
+sfftw_plan_r2r_
+sfftw_plan_r2r__
+sfftw_plan_r2r_1d_
+sfftw_plan_r2r_1d__
+sfftw_plan_r2r_2d_
+sfftw_plan_r2r_2d__
+sfftw_plan_r2r_3d_
+sfftw_plan_r2r_3d__
+sfftw_plan_with_nthreads_
+sfftw_plan_with_nthreads__
+sfftw_print_plan_
+sfftw_print_plan__
+sfftw_set_timelimit_
+sfftw_set_timelimit__
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.exp b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.exp
new file mode 100644
index 0000000..c238065
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.exp
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.lib b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.lib
new file mode 100644
index 0000000..55fd550
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3f-3.lib
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.def b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.def
new file mode 100644
index 0000000..62a5e42
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.def
@@ -0,0 +1,634 @@
+LIBRARY libfftw3l-3.dll
+EXPORTS
+fftwl_alignment_of
+fftwl_alloc_complex
+fftwl_alloc_real
+fftwl_assertion_failed
+fftwl_bufdist
+fftwl_choose_radix
+fftwl_cleanup
+fftwl_cleanup_threads
+fftwl_codelet_e01_8
+fftwl_codelet_e10_8
+fftwl_codelet_hb_10
+fftwl_codelet_hb_12
+fftwl_codelet_hb_15
+fftwl_codelet_hb_16
+fftwl_codelet_hb_2
+fftwl_codelet_hb_20
+fftwl_codelet_hb2_16
+fftwl_codelet_hb2_20
+fftwl_codelet_hb2_25
+fftwl_codelet_hb2_32
+fftwl_codelet_hb2_4
+fftwl_codelet_hb_25
+fftwl_codelet_hb2_5
+fftwl_codelet_hb2_8
+fftwl_codelet_hb_3
+fftwl_codelet_hb_32
+fftwl_codelet_hb_4
+fftwl_codelet_hb_5
+fftwl_codelet_hb_6
+fftwl_codelet_hb_64
+fftwl_codelet_hb_7
+fftwl_codelet_hb_8
+fftwl_codelet_hb_9
+fftwl_codelet_hc2cb_10
+fftwl_codelet_hc2cb_12
+fftwl_codelet_hc2cb_16
+fftwl_codelet_hc2cb_2
+fftwl_codelet_hc2cb_20
+fftwl_codelet_hc2cb2_16
+fftwl_codelet_hc2cb2_20
+fftwl_codelet_hc2cb2_32
+fftwl_codelet_hc2cb2_4
+fftwl_codelet_hc2cb2_8
+fftwl_codelet_hc2cb_32
+fftwl_codelet_hc2cb_4
+fftwl_codelet_hc2cb_6
+fftwl_codelet_hc2cb_8
+fftwl_codelet_hc2cbdft_10
+fftwl_codelet_hc2cbdft_12
+fftwl_codelet_hc2cbdft_16
+fftwl_codelet_hc2cbdft_2
+fftwl_codelet_hc2cbdft_20
+fftwl_codelet_hc2cbdft2_16
+fftwl_codelet_hc2cbdft2_20
+fftwl_codelet_hc2cbdft2_32
+fftwl_codelet_hc2cbdft2_4
+fftwl_codelet_hc2cbdft2_8
+fftwl_codelet_hc2cbdft_32
+fftwl_codelet_hc2cbdft_4
+fftwl_codelet_hc2cbdft_6
+fftwl_codelet_hc2cbdft_8
+fftwl_codelet_hc2cf_10
+fftwl_codelet_hc2cf_12
+fftwl_codelet_hc2cf_16
+fftwl_codelet_hc2cf_2
+fftwl_codelet_hc2cf_20
+fftwl_codelet_hc2cf2_16
+fftwl_codelet_hc2cf2_20
+fftwl_codelet_hc2cf2_32
+fftwl_codelet_hc2cf2_4
+fftwl_codelet_hc2cf2_8
+fftwl_codelet_hc2cf_32
+fftwl_codelet_hc2cf_4
+fftwl_codelet_hc2cf_6
+fftwl_codelet_hc2cf_8
+fftwl_codelet_hc2cfdft_10
+fftwl_codelet_hc2cfdft_12
+fftwl_codelet_hc2cfdft_16
+fftwl_codelet_hc2cfdft_2
+fftwl_codelet_hc2cfdft_20
+fftwl_codelet_hc2cfdft2_16
+fftwl_codelet_hc2cfdft2_20
+fftwl_codelet_hc2cfdft2_32
+fftwl_codelet_hc2cfdft2_4
+fftwl_codelet_hc2cfdft2_8
+fftwl_codelet_hc2cfdft_32
+fftwl_codelet_hc2cfdft_4
+fftwl_codelet_hc2cfdft_6
+fftwl_codelet_hc2cfdft_8
+fftwl_codelet_hf_10
+fftwl_codelet_hf_12
+fftwl_codelet_hf_15
+fftwl_codelet_hf_16
+fftwl_codelet_hf_2
+fftwl_codelet_hf_20
+fftwl_codelet_hf2_16
+fftwl_codelet_hf2_20
+fftwl_codelet_hf2_25
+fftwl_codelet_hf2_32
+fftwl_codelet_hf2_4
+fftwl_codelet_hf_25
+fftwl_codelet_hf2_5
+fftwl_codelet_hf2_8
+fftwl_codelet_hf_3
+fftwl_codelet_hf_32
+fftwl_codelet_hf_4
+fftwl_codelet_hf_5
+fftwl_codelet_hf_6
+fftwl_codelet_hf_64
+fftwl_codelet_hf_7
+fftwl_codelet_hf_8
+fftwl_codelet_hf_9
+fftwl_codelet_n1_10
+fftwl_codelet_n1_11
+fftwl_codelet_n1_12
+fftwl_codelet_n1_13
+fftwl_codelet_n1_14
+fftwl_codelet_n1_15
+fftwl_codelet_n1_16
+fftwl_codelet_n1_2
+fftwl_codelet_n1_20
+fftwl_codelet_n1_25
+fftwl_codelet_n1_3
+fftwl_codelet_n1_32
+fftwl_codelet_n1_4
+fftwl_codelet_n1_5
+fftwl_codelet_n1_6
+fftwl_codelet_n1_64
+fftwl_codelet_n1_7
+fftwl_codelet_n1_8
+fftwl_codelet_n1_9
+fftwl_codelet_q1_2
+fftwl_codelet_q1_3
+fftwl_codelet_q1_4
+fftwl_codelet_q1_5
+fftwl_codelet_q1_6
+fftwl_codelet_q1_8
+fftwl_codelet_r2cb_10
+fftwl_codelet_r2cb_11
+fftwl_codelet_r2cb_12
+fftwl_codelet_r2cb_128
+fftwl_codelet_r2cb_13
+fftwl_codelet_r2cb_14
+fftwl_codelet_r2cb_15
+fftwl_codelet_r2cb_16
+fftwl_codelet_r2cb_2
+fftwl_codelet_r2cb_20
+fftwl_codelet_r2cb_25
+fftwl_codelet_r2cb_3
+fftwl_codelet_r2cb_32
+fftwl_codelet_r2cb_4
+fftwl_codelet_r2cb_5
+fftwl_codelet_r2cb_6
+fftwl_codelet_r2cb_64
+fftwl_codelet_r2cb_7
+fftwl_codelet_r2cb_8
+fftwl_codelet_r2cb_9
+fftwl_codelet_r2cbIII_10
+fftwl_codelet_r2cbIII_12
+fftwl_codelet_r2cbIII_15
+fftwl_codelet_r2cbIII_16
+fftwl_codelet_r2cbIII_2
+fftwl_codelet_r2cbIII_20
+fftwl_codelet_r2cbIII_25
+fftwl_codelet_r2cbIII_3
+fftwl_codelet_r2cbIII_32
+fftwl_codelet_r2cbIII_4
+fftwl_codelet_r2cbIII_5
+fftwl_codelet_r2cbIII_6
+fftwl_codelet_r2cbIII_64
+fftwl_codelet_r2cbIII_7
+fftwl_codelet_r2cbIII_8
+fftwl_codelet_r2cbIII_9
+fftwl_codelet_r2cf_10
+fftwl_codelet_r2cf_11
+fftwl_codelet_r2cf_12
+fftwl_codelet_r2cf_128
+fftwl_codelet_r2cf_13
+fftwl_codelet_r2cf_14
+fftwl_codelet_r2cf_15
+fftwl_codelet_r2cf_16
+fftwl_codelet_r2cf_2
+fftwl_codelet_r2cf_20
+fftwl_codelet_r2cf_25
+fftwl_codelet_r2cf_3
+fftwl_codelet_r2cf_32
+fftwl_codelet_r2cf_4
+fftwl_codelet_r2cf_5
+fftwl_codelet_r2cf_6
+fftwl_codelet_r2cf_64
+fftwl_codelet_r2cf_7
+fftwl_codelet_r2cf_8
+fftwl_codelet_r2cf_9
+fftwl_codelet_r2cfII_10
+fftwl_codelet_r2cfII_12
+fftwl_codelet_r2cfII_15
+fftwl_codelet_r2cfII_16
+fftwl_codelet_r2cfII_2
+fftwl_codelet_r2cfII_20
+fftwl_codelet_r2cfII_25
+fftwl_codelet_r2cfII_3
+fftwl_codelet_r2cfII_32
+fftwl_codelet_r2cfII_4
+fftwl_codelet_r2cfII_5
+fftwl_codelet_r2cfII_6
+fftwl_codelet_r2cfII_64
+fftwl_codelet_r2cfII_7
+fftwl_codelet_r2cfII_8
+fftwl_codelet_r2cfII_9
+fftwl_codelet_t1_10
+fftwl_codelet_t1_12
+fftwl_codelet_t1_15
+fftwl_codelet_t1_16
+fftwl_codelet_t1_2
+fftwl_codelet_t1_20
+fftwl_codelet_t1_25
+fftwl_codelet_t1_3
+fftwl_codelet_t1_32
+fftwl_codelet_t1_4
+fftwl_codelet_t1_5
+fftwl_codelet_t1_6
+fftwl_codelet_t1_64
+fftwl_codelet_t1_7
+fftwl_codelet_t1_8
+fftwl_codelet_t1_9
+fftwl_codelet_t2_10
+fftwl_codelet_t2_16
+fftwl_codelet_t2_20
+fftwl_codelet_t2_25
+fftwl_codelet_t2_32
+fftwl_codelet_t2_4
+fftwl_codelet_t2_5
+fftwl_codelet_t2_64
+fftwl_codelet_t2_8
+fftwl_compute_tilesz
+fftwl_configure_planner
+fftwl_cost
+fftwl_cpy1d
+fftwl_cpy2d
+fftwl_cpy2d_ci
+fftwl_cpy2d_co
+fftwl_cpy2d_pair
+fftwl_cpy2d_pair_ci
+fftwl_cpy2d_pair_co
+fftwl_cpy2d_tiled
+fftwl_cpy2d_tiledbuf
+fftwl_ct_applicable
+fftwl_ct_genericbuf_register
+fftwl_ct_generic_register
+fftwl_ct_uglyp
+fftwl_destroy_plan
+fftwl_dft_bluestein_register
+fftwl_dft_buffered_register
+fftwl_dft_conf_standard
+fftwl_dft_generic_register
+fftwl_dft_indirect_register
+fftwl_dft_indirect_transpose_register
+fftwl_dft_nop_register
+fftwl_dft_r2hc_register
+fftwl_dft_rader_register
+fftwl_dft_rank_geq2_register
+fftwl_dft_solve
+fftwl_dft_thr_vrank_geq1_register
+fftwl_dft_vrank_geq1_register
+fftwl_dft_zerotens
+fftwl_dht_r2hc_register
+fftwl_dht_rader_register
+fftwl_dimcmp
+fftwl_elapsed_since
+fftwl_estimate_cost
+fftwl_execute
+fftwl_execute_dft
+fftwl_execute_dft_c2r
+fftwl_execute_dft_r2c
+fftwl_execute_r2r
+fftwl_execute_split_dft
+fftwl_execute_split_dft_c2r
+fftwl_execute_split_dft_r2c
+fftwl_export_wisdom
+fftwl_export_wisdom_to_file
+fftwl_export_wisdom_to_filename
+fftwl_export_wisdom_to_string
+fftwl_extract_reim
+fftwl_factors_into
+fftwl_factors_into_small_primes
+fftwl_find_generator
+fftwl_first_divisor
+fftwl_flops
+fftwl_forget_wisdom
+fftwl_fprint_plan
+fftwl_free
+fftwl_get_crude_time
+fftwl_guru64_kosherp
+fftwl_guru_kosherp
+fftwl_hash
+fftwl_hc2hc_applicable
+fftwl_hc2hc_generic_register
+fftwl_iabs
+fftwl_ialignment_of
+fftwl_iestimate_cost
+fftwl_ifree
+fftwl_ifree0
+fftwl_imax
+fftwl_imin
+fftwl_import_system_wisdom
+fftwl_import_wisdom
+fftwl_import_wisdom_from_file
+fftwl_import_wisdom_from_filename
+fftwl_import_wisdom_from_string
+fftwl_init_threads
+fftwl_is_prime
+fftwl_isqrt
+fftwl_ithreads_init
+fftwl_kdft_dif_register
+fftwl_kdft_difsq_register
+fftwl_kdft_dit_register
+fftwl_kdft_register
+fftwl_kernel_free
+fftwl_kernel_malloc
+fftwl_khc2c_register
+fftwl_khc2hc_register
+fftwl_kr2c_register
+fftwl_kr2r_register
+fftwl_make_planner_thread_safe
+fftwl_malloc
+fftwl_malloc_plain
+fftwl_many_kosherp
+fftwl_mapflags
+fftwl_map_r2r_kind
+fftwl_md5begin
+fftwl_md5end
+fftwl_md5int
+fftwl_md5INT
+fftwl_md5putb
+fftwl_md5putc
+fftwl_md5puts
+fftwl_md5unsigned
+fftwl_measure_execution_time
+fftwl_mkapiplan
+fftwl_mkplan
+fftwl_mkplan_d
+fftwl_mkplan_dft
+fftwl_mkplan_dftw
+fftwl_mkplan_f_d
+fftwl_mkplan_hc2c
+fftwl_mkplan_hc2hc
+fftwl_mkplanner
+fftwl_mkplan_rdft
+fftwl_mkplan_rdft2
+fftwl_mkprinter
+fftwl_mkprinter_cnt
+fftwl_mkprinter_file
+fftwl_mkprinter_str
+fftwl_mkproblem
+fftwl_mkproblem_dft
+fftwl_mkproblem_dft_d
+fftwl_mkproblem_rdft
+fftwl_mkproblem_rdft_0_d
+fftwl_mkproblem_rdft_1
+fftwl_mkproblem_rdft_1_d
+fftwl_mkproblem_rdft2
+fftwl_mkproblem_rdft2_d
+fftwl_mkproblem_rdft2_d_3pointers
+fftwl_mkproblem_rdft_d
+fftwl_mkproblem_unsolvable
+fftwl_mkscanner
+fftwl_mksolver
+fftwl_mksolver_ct
+fftwl_mksolver_ct_threads
+fftwl_mksolver_dft_direct
+fftwl_mksolver_dft_directbuf
+fftwl_mksolver_hc2c
+fftwl_mksolver_hc2hc
+fftwl_mksolver_hc2hc_threads
+fftwl_mksolver_rdft2_direct
+fftwl_mksolver_rdft_r2c_direct
+fftwl_mksolver_rdft_r2c_directbuf
+fftwl_mksolver_rdft_r2r_direct
+fftwl_mktensor
+fftwl_mktensor_0d
+fftwl_mktensor_1d
+fftwl_mktensor_2d
+fftwl_mktensor_3d
+fftwl_mktensor_4d
+fftwl_mktensor_5d
+fftwl_mktensor_iodims
+fftwl_mktensor_iodims64
+fftwl_mktensor_rowmajor
+fftwl_mktriggen
+fftwl_modulo
+fftwl_nbuf
+fftwl_nbuf_redundant
+fftwl_next_prime
+fftwl_null_awake
+fftwl_ops_add
+fftwl_ops_add2
+fftwl_ops_cpy
+fftwl_ops_madd
+fftwl_ops_madd2
+fftwl_ops_other
+fftwl_ops_zero
+fftwl_pickdim
+fftwl_plan_awake
+fftwl_plan_destroy_internal
+fftwl_plan_dft
+fftwl_plan_dft_1d
+fftwl_plan_dft_2d
+fftwl_plan_dft_3d
+fftwl_plan_dft_c2r
+fftwl_plan_dft_c2r_1d
+fftwl_plan_dft_c2r_2d
+fftwl_plan_dft_c2r_3d
+fftwl_plan_dft_r2c
+fftwl_plan_dft_r2c_1d
+fftwl_plan_dft_r2c_2d
+fftwl_plan_dft_r2c_3d
+fftwl_plan_guru64_dft
+fftwl_plan_guru64_dft_c2r
+fftwl_plan_guru64_dft_r2c
+fftwl_plan_guru64_r2r
+fftwl_plan_guru64_split_dft
+fftwl_plan_guru64_split_dft_c2r
+fftwl_plan_guru64_split_dft_r2c
+fftwl_plan_guru_dft
+fftwl_plan_guru_dft_c2r
+fftwl_plan_guru_dft_r2c
+fftwl_plan_guru_r2r
+fftwl_plan_guru_split_dft
+fftwl_plan_guru_split_dft_c2r
+fftwl_plan_guru_split_dft_r2c
+fftwl_plan_many_dft
+fftwl_plan_many_dft_c2r
+fftwl_plan_many_dft_r2c
+fftwl_plan_many_r2r
+fftwl_planner_destroy
+fftwl_plan_null_destroy
+fftwl_plan_r2r
+fftwl_plan_r2r_1d
+fftwl_plan_r2r_2d
+fftwl_plan_r2r_3d
+fftwl_plan_with_nthreads
+fftwl_power_mod
+fftwl_printer_destroy
+fftwl_print_plan
+fftwl_problem_destroy
+fftwl_rader_tl_delete
+fftwl_rader_tl_find
+fftwl_rader_tl_insert
+fftwl_rdft2_buffered_register
+fftwl_rdft2_complex_n
+fftwl_rdft2_inplace_strides
+fftwl_rdft2_nop_register
+fftwl_rdft2_pad
+fftwl_rdft2_rank0_register
+fftwl_rdft2_rank_geq2_register
+fftwl_rdft2_rdft_register
+fftwl_rdft2_solve
+fftwl_rdft2_strides
+fftwl_rdft2_tensor_max_index
+fftwl_rdft2_thr_vrank_geq1_register
+fftwl_rdft2_vrank_geq1_register
+fftwl_rdft_buffered_register
+fftwl_rdft_conf_standard
+fftwl_rdft_dht_register
+fftwl_rdft_generic_register
+fftwl_rdft_indirect_register
+fftwl_rdft_kind_str
+fftwl_rdft_nop_register
+fftwl_rdft_rank0_register
+fftwl_rdft_rank_geq2_register
+fftwl_rdft_solve
+fftwl_rdft_thr_vrank_geq1_register
+fftwl_rdft_vrank3_transpose_register
+fftwl_rdft_vrank_geq1_register
+fftwl_rdft_zerotens
+fftwl_redft00e_r2hc_pad_register
+fftwl_regsolver_ct_directw
+fftwl_regsolver_ct_directwsq
+fftwl_regsolver_hc2c_direct
+fftwl_regsolver_hc2hc_direct
+fftwl_reodft00e_splitradix_register
+fftwl_reodft010e_r2hc_register
+fftwl_reodft11e_r2hc_odd_register
+fftwl_reodft11e_radix2_r2hc_register
+fftwl_reodft_conf_standard
+fftwl_rodft00e_r2hc_pad_register
+fftwl_safe_mulmod
+fftwl_scanner_destroy
+fftwl_set_planner_hooks
+fftwl_set_timelimit
+fftwl_solver_destroy
+fftwl_solver_register
+fftwl_solver_use
+fftwl_solvtab_exec
+fftwl_spawn_loop
+fftwl_sprint_plan
+fftwl_tensor_append
+fftwl_tensor_compress
+fftwl_tensor_compress_contiguous
+fftwl_tensor_copy
+fftwl_tensor_copy_except
+fftwl_tensor_copy_inplace
+fftwl_tensor_copy_sub
+fftwl_tensor_destroy
+fftwl_tensor_destroy2
+fftwl_tensor_destroy4
+fftwl_tensor_equal
+fftwl_tensor_inplace_locations
+fftwl_tensor_inplace_strides
+fftwl_tensor_inplace_strides2
+fftwl_tensor_kosherp
+fftwl_tensor_max_index
+fftwl_tensor_md5
+fftwl_tensor_min_istride
+fftwl_tensor_min_ostride
+fftwl_tensor_min_stride
+fftwl_tensor_print
+fftwl_tensor_split
+fftwl_tensor_strides_decrease
+fftwl_tensor_sz
+fftwl_tensor_tornk1
+fftwl_the_planner
+fftwl_threads_cleanup
+fftwl_threads_conf_standard
+fftwl_threads_register_planner_hooks
+fftwl_tile2d
+fftwl_toobig
+fftwl_transpose
+fftwl_transpose_tiled
+fftwl_transpose_tiledbuf
+fftwl_triggen_destroy
+fftwl_twiddle_awake
+fftwl_twiddle_length
+fftwl_zero1d_pair
+lfftw_cleanup_
+lfftw_cleanup__
+lfftw_cleanup_threads_
+lfftw_cleanup_threads__
+lfftw_cost_
+lfftw_cost__
+lfftw_destroy_plan_
+lfftw_destroy_plan__
+lfftw_estimate_cost_
+lfftw_estimate_cost__
+lfftw_execute_
+lfftw_execute__
+lfftw_execute_dft_
+lfftw_execute_dft__
+lfftw_execute_dft_c2r_
+lfftw_execute_dft_c2r__
+lfftw_execute_dft_r2c_
+lfftw_execute_dft_r2c__
+lfftw_execute_r2r_
+lfftw_execute_r2r__
+lfftw_execute_split_dft_
+lfftw_execute_split_dft__
+lfftw_execute_split_dft_c2r_
+lfftw_execute_split_dft_c2r__
+lfftw_execute_split_dft_r2c_
+lfftw_execute_split_dft_r2c__
+lfftw_export_wisdom_
+lfftw_export_wisdom__
+lfftw_flops_
+lfftw_flops__
+lfftw_forget_wisdom_
+lfftw_forget_wisdom__
+lfftw_import_system_wisdom_
+lfftw_import_system_wisdom__
+lfftw_import_wisdom_
+lfftw_import_wisdom__
+lfftw_init_threads_
+lfftw_init_threads__
+lfftw_plan_dft_
+lfftw_plan_dft__
+lfftw_plan_dft_1d_
+lfftw_plan_dft_1d__
+lfftw_plan_dft_2d_
+lfftw_plan_dft_2d__
+lfftw_plan_dft_3d_
+lfftw_plan_dft_3d__
+lfftw_plan_dft_c2r_
+lfftw_plan_dft_c2r__
+lfftw_plan_dft_c2r_1d_
+lfftw_plan_dft_c2r_1d__
+lfftw_plan_dft_c2r_2d_
+lfftw_plan_dft_c2r_2d__
+lfftw_plan_dft_c2r_3d_
+lfftw_plan_dft_c2r_3d__
+lfftw_plan_dft_r2c_
+lfftw_plan_dft_r2c__
+lfftw_plan_dft_r2c_1d_
+lfftw_plan_dft_r2c_1d__
+lfftw_plan_dft_r2c_2d_
+lfftw_plan_dft_r2c_2d__
+lfftw_plan_dft_r2c_3d_
+lfftw_plan_dft_r2c_3d__
+lfftw_plan_guru_dft_
+lfftw_plan_guru_dft__
+lfftw_plan_guru_dft_c2r_
+lfftw_plan_guru_dft_c2r__
+lfftw_plan_guru_dft_r2c_
+lfftw_plan_guru_dft_r2c__
+lfftw_plan_guru_r2r_
+lfftw_plan_guru_r2r__
+lfftw_plan_guru_split_dft_
+lfftw_plan_guru_split_dft__
+lfftw_plan_guru_split_dft_c2r_
+lfftw_plan_guru_split_dft_c2r__
+lfftw_plan_guru_split_dft_r2c_
+lfftw_plan_guru_split_dft_r2c__
+lfftw_plan_many_dft_
+lfftw_plan_many_dft__
+lfftw_plan_many_dft_c2r_
+lfftw_plan_many_dft_c2r__
+lfftw_plan_many_dft_r2c_
+lfftw_plan_many_dft_r2c__
+lfftw_plan_many_r2r_
+lfftw_plan_many_r2r__
+lfftw_plan_r2r_
+lfftw_plan_r2r__
+lfftw_plan_r2r_1d_
+lfftw_plan_r2r_1d__
+lfftw_plan_r2r_2d_
+lfftw_plan_r2r_2d__
+lfftw_plan_r2r_3d_
+lfftw_plan_r2r_3d__
+lfftw_plan_with_nthreads_
+lfftw_plan_with_nthreads__
+lfftw_print_plan_
+lfftw_print_plan__
+lfftw_set_timelimit_
+lfftw_set_timelimit__
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.exp b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.exp
new file mode 100644
index 0000000..cc66aff
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.exp
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.lib b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.lib
new file mode 100644
index 0000000..bdceb32
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/libfftw3l-3.lib
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/lib/x86/onnxruntime.lib b/funasr/runtime/cpp/onnxruntime/win/lib/x86/onnxruntime.lib
new file mode 100644
index 0000000..b00709f
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/lib/x86/onnxruntime.lib
Binary files differ
diff --git a/funasr/runtime/cpp/onnxruntime/win/readme.md b/funasr/runtime/cpp/onnxruntime/win/readme.md
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/funasr/runtime/cpp/onnxruntime/win/readme.md
@@ -0,0 +1 @@
+
--
Gitblit v1.9.1