diff --git a/docs/OperatorKernels.md b/docs/OperatorKernels.md
index 36436ec368ffa..102dce0737296 100644
--- a/docs/OperatorKernels.md
+++ b/docs/OperatorKernels.md
@@ -43,6 +43,7 @@ Do not modify directly.*
|||[9, 13]|**T** = tensor(double), tensor(float)|
|||[7, 8]|**T** = tensor(double), tensor(float)|
|BitShift|*in* X:**T**
*in* Y:**T**
*out* Z:**T**|11+|**T** = tensor(uint32), tensor(uint64), tensor(uint8)|
+|BlackmanWindow|*in* size:**T1**
*out* output:**T2**|17+|**T1** = tensor(int32), tensor(int64)
**T2** = tensor(double), tensor(float), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)|
|Cast|*in* input:**T1**
*out* output:**T2**|13+|**T1** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)
**T2** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)|
|||[6, 12]|**T1** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)
**T2** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)|
|Ceil|*in* X:**T**
*out* Y:**T**|13+|**T** = tensor(float)|
@@ -69,6 +70,7 @@ Do not modify directly.*
|Crop|*in* input:**T**
*out* output:**T**|1+|**T** = tensor(float)|
|CumSum|*in* x:**T**
*in* axis:**T2**
*out* y:**T**|14+|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)
**T2** = tensor(int32), tensor(int64)|
|||[11, 13]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)
**T2** = tensor(int32), tensor(int64)|
+|DFT|*in* input:**T1**
*in* dft_length:**T2**
*out* output:**T1**|17+|**T1** = tensor(double), tensor(float)
**T2** = tensor(int32), tensor(int64)|
|DepthToSpace|*in* input:**T**
*out* output:**T**|13+|**T** = tensor(double), tensor(float)|
|||[11, 12]|**T** = tensor(double), tensor(float)|
|||[1, 10]|**T** = tensor(double), tensor(float)|
@@ -125,6 +127,8 @@ Do not modify directly.*
|GreaterOrEqual|*in* A:**T**
*in* B:**T**
*out* C:**T1**|16+|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)
**T1** = tensor(bool)|
|||[12, 15]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)
**T1** = tensor(bool)|
|GridSample|*in* X:**T1**
*in* grid:**T1**
*out* Y:**T2**|16+|**T1** = tensor(float)
**T2** = tensor(float)|
+|HammingWindow|*in* size:**T1**
*out* output:**T2**|17+|**T1** = tensor(int32), tensor(int64)
**T2** = tensor(double), tensor(float), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)|
+|HannWindow|*in* size:**T1**
*out* output:**T2**|17+|**T1** = tensor(int32), tensor(int64)
**T2** = tensor(double), tensor(float), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)|
|HardSigmoid|*in* X:**T**
*out* Y:**T**|6+|**T** = tensor(float)|
|Hardmax|*in* input:**T**
*out* output:**T**|13+|**T** = tensor(float)|
|||[11, 12]|**T** = tensor(float)|
@@ -186,6 +190,7 @@ Do not modify directly.*
|MeanVarianceNormalization|*in* X:**T**
*out* Y:**T**
or
*in* input:**T**
*out* output:**T**|13+|**T** = tensor(float)|
|||[9, 12]|**T** = tensor(float)|
|||[1, 8]|**T** = tensor(float)|
+|MelWeightMatrix|*in* num_mel_bins:**T1**
*in* dft_length:**T1**
*in* sample_rate:**T1**
*in* lower_edge_hertz:**T2**
*in* upper_edge_hertz:**T2**
*out* output:**T3**|17+|**T1** = tensor(int32), tensor(int64)
**T2** = tensor(float)
**T3** = tensor(double), tensor(float), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)|
|Min|*in* data_0:**T**
*out* min:**T**|13+|**T** = tensor(double), tensor(float), tensor(float16), tensor(int32), tensor(int64), tensor(uint32), tensor(uint64)|
|||12|**T** = tensor(double), tensor(float), tensor(float16), tensor(int32), tensor(int64), tensor(uint32), tensor(uint64)|
|||[8, 11]|**T** = tensor(double), tensor(float)|
@@ -277,6 +282,7 @@ Do not modify directly.*
|RoiAlign|*in* X:**T1**
*in* rois:**T1**
*in* batch_indices:**T2**
*out* Y:**T1**|16+|**T1** = tensor(double), tensor(float)
**T2** = tensor(int64)|
|||[10, 15]|**T1** = tensor(double), tensor(float)
**T2** = tensor(int64)|
|Round|*in* X:**T**
*out* Y:**T**|11+|**T** = tensor(double), tensor(float), tensor(float16)|
+|STFT|*in* signal:**T1**
*in* frame_step:**T2**
*in* window:**T1**
*in* frame_length:**T2**
*out* output:**T1**|17+|**T1** = tensor(double), tensor(float)
**T2** = tensor(int32), tensor(int64)|
|Scale|*in* input:**T**
*out* output:**T**|1+|**T** = tensor(float)|
|ScaledTanh|*in* input:**T**
*out* output:**T**|1+|**T** = tensor(float)|
|Scan|*in* initial_state_and_scan_inputs:**V**
*out* final_state_and_scan_outputs:**V**
or
*in* sequence_lens:**I**
*in* initial_state_and_scan_inputs:**V**
*out* final_state_and_scan_outputs:**V**|16+|**V** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)|
diff --git a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc
index 2068b3c3e3f1f..d89d30b62c737 100644
--- a/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc
+++ b/onnxruntime/contrib_ops/cpu/cpu_contrib_kernels.cc
@@ -41,16 +41,6 @@ class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, FastG
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, NGramRepeatBlock);
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, BifurcationDetector);
-#ifdef BUILD_MS_EXPERIMENTAL_OPS
-class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSExperimentalDomain, 1, DFT);
-class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSExperimentalDomain, 1, IDFT);
-class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSExperimentalDomain, 1, HannWindow);
-class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSExperimentalDomain, 1, HammingWindow);
-class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSExperimentalDomain, 1, BlackmanWindow);
-class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSExperimentalDomain, 1, MelWeightMatrix);
-class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSExperimentalDomain, 1, STFT);
-#endif
-
// ******** Start: Quantization ******************* //
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, MatMulInteger16);
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kMSDomain, 1, QLinearGlobalAveragePool);
@@ -224,16 +214,6 @@ Status RegisterCpuContribKernels(KernelRegistry& kernel_registry) {
BuildKernelCreateInfo,
BuildKernelCreateInfo,
BuildKernelCreateInfo,
-
-#ifdef BUILD_MS_EXPERIMENTAL_OPS
- BuildKernelCreateInfo,
- BuildKernelCreateInfo,
- BuildKernelCreateInfo,
- BuildKernelCreateInfo,
- BuildKernelCreateInfo,
- BuildKernelCreateInfo,
- BuildKernelCreateInfo,
-#endif
// These ops were experimental ops in onnx domain which have been removed now. We add them here as
// contrib ops to main backward compatibility
BuildKernelCreateInfo,
diff --git a/onnxruntime/contrib_ops/cpu/signal/dft.cc b/onnxruntime/contrib_ops/cpu/signal/dft.cc
deleted file mode 100644
index 87aac44976540..0000000000000
--- a/onnxruntime/contrib_ops/cpu/signal/dft.cc
+++ /dev/null
@@ -1,606 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-#ifdef BUILD_MS_EXPERIMENTAL_OPS
-
-#include "core/providers/common.h"
-#include "core/framework/op_kernel.h"
-#include "core/util/math_cpuonly.h"
-#include "Eigen/src/Core/Map.h"
-#include "dft.h"
-#include
-
-#include "core/platform/threadpool.h"
-
-#include
-#include
-
-namespace onnxruntime {
-namespace contrib {
-
-ONNX_OPERATOR_KERNEL_EX(
- DFT,
- kMSExperimentalDomain,
- 1,
- kCpuExecutionProvider,
- KernelDefBuilder().TypeConstraint("T1", BuildKernelDefConstraints())
- .TypeConstraint("T2", BuildKernelDefConstraints()),
- DFT);
-
-ONNX_OPERATOR_KERNEL_EX(
- IDFT,
- kMSExperimentalDomain,
- 1,
- kCpuExecutionProvider,
- KernelDefBuilder().TypeConstraint("T1", BuildKernelDefConstraints())
- .TypeConstraint("T2", BuildKernelDefConstraints()),
- IDFT);
-
-ONNX_OPERATOR_KERNEL_EX(
- STFT,
- kMSExperimentalDomain,
- 1,
- kCpuExecutionProvider,
- KernelDefBuilder().MayInplace(0, 0).TypeConstraint("T1", BuildKernelDefConstraints())
- .TypeConstraint("T2", BuildKernelDefConstraints()),
- STFT);
-
-// dedupe with the other one in window_functions.cc
-template
-static T get_scalar_value_from_tensor(const Tensor* tensor) {
- ORT_ENFORCE(tensor->Shape().Size() == 1, "ratio input should have a single value.");
-
- auto data_type = tensor->DataType()->AsPrimitiveDataType()->GetDataType();
- switch (data_type) {
- case ONNX_NAMESPACE::TensorProto_DataType_FLOAT:
- return static_cast(*reinterpret_cast(tensor->DataRaw()));
- case ONNX_NAMESPACE::TensorProto_DataType_DOUBLE:
- return static_cast(*reinterpret_cast(tensor->DataRaw()));
- case ONNX_NAMESPACE::TensorProto_DataType_INT32:
- return static_cast(*reinterpret_cast(tensor->DataRaw()));
- case ONNX_NAMESPACE::TensorProto_DataType_INT64:
- return static_cast(*reinterpret_cast(tensor->DataRaw()));
- default:
- ORT_THROW("Unsupported input data type of ", data_type);
- }
-}
-
-static bool is_real_valued_signal(const onnxruntime::TensorShape & shape) {
- return shape.NumDimensions() == 2 || shape[shape.NumDimensions() - 1] == 1;
-}
-
-static bool is_complex_valued_signal(const onnxruntime::TensorShape& shape) {
- return shape.NumDimensions() > 2 && shape[shape.NumDimensions() - 1] == 2;
-}
-
-static bool is_power_of_2(size_t size) {
- unsigned n_bits = 0;
- while (size != 0) {
- n_bits += size & 1;
- size = size >> 1;
- }
- return n_bits == 1;
-}
-
-static const unsigned char BitReverseTable256[] =
-{
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF};
-
-template
-uint32_t bit_reverse(uint32_t num) {
- uint32_t rev = (BitReverseTable256[num & 0xff] << 24) |
- (BitReverseTable256[(num >> 8) & 0xff] << 16) |
- (BitReverseTable256[(num >> 16) & 0xff] << 8) |
- (BitReverseTable256[(num >> 24) & 0xff]);
- return static_cast(((uint64_t)rev) >> (32 - TSignificantBits));
-}
-
-template
-static inline T bit_reverse(T num, unsigned significant_bits) {
- switch (significant_bits) {
- case 0: return static_cast(bit_reverse<0>(static_cast(num)));
- case 1: return static_cast(bit_reverse<1>(static_cast(num)));
- case 2: return static_cast(bit_reverse<2>(static_cast(num)));
- case 3: return static_cast(bit_reverse<3>(static_cast(num)));
- case 4: return static_cast(bit_reverse<4>(static_cast(num)));
- case 5: return static_cast(bit_reverse<5>(static_cast(num)));
- case 6: return static_cast(bit_reverse<6>(static_cast(num)));
- case 7: return static_cast(bit_reverse<7>(static_cast(num)));
- case 8: return static_cast(bit_reverse<8>(static_cast(num)));
- case 9: return static_cast(bit_reverse<9>(static_cast(num)));
- case 10: return static_cast(bit_reverse<10>(static_cast(num)));
- case 11: return static_cast(bit_reverse<11>(static_cast(num)));
- case 12: return static_cast(bit_reverse<12>(static_cast(num)));
- case 13: return static_cast(bit_reverse<13>(static_cast(num)));
- case 14: return static_cast(bit_reverse<14>(static_cast(num)));
- case 15: return static_cast(bit_reverse<15>(static_cast(num)));
- case 16: return static_cast(bit_reverse<16>(static_cast(num)));
- case 17: return static_cast(bit_reverse<17>(static_cast(num)));
- case 18: return static_cast(bit_reverse<18>(static_cast(num)));
- case 19: return static_cast(bit_reverse<19>(static_cast(num)));
- case 20: return static_cast(bit_reverse<20>(static_cast(num)));
- case 21: return static_cast(bit_reverse<21>(static_cast(num)));
- case 22: return static_cast(bit_reverse<22>(static_cast(num)));
- case 23: return static_cast(bit_reverse<23>(static_cast(num)));
- case 24: return static_cast(bit_reverse<24>(static_cast(num)));
- case 25: return static_cast(bit_reverse<25>(static_cast(num)));
- case 26: return static_cast(bit_reverse<26>(static_cast(num)));
- case 27: return static_cast(bit_reverse<27>(static_cast(num)));
- case 28: return static_cast(bit_reverse<28>(static_cast(num)));
- case 29: return static_cast(bit_reverse<29>(static_cast(num)));
- case 30: return static_cast(bit_reverse<30>(static_cast(num)));
- case 31: return static_cast(bit_reverse<31>(static_cast(num)));
- case 32: return static_cast(bit_reverse<32>(static_cast(num)));
- default: ORT_THROW("Unsupported bit size.");
- }
-}
-
-template
-static T compute_angular_velocity(size_t number_of_samples, bool inverse) {
- // Calculate fundamental angular velocity
- static const T pi = static_cast(3.14159265);
- static const T tau = 2 * pi;
- T inverse_switch = inverse ? 1.f : -1.f;
- T angular_velocity = inverse_switch * tau / number_of_samples;
- return angular_velocity;
-}
-
-template
-static Status fft_radix2(OpKernelContext* /*ctx*/,
- const Tensor* X, Tensor* Y,
- size_t X_offset, size_t X_stride, size_t Y_offset, size_t Y_stride, int64_t axis, size_t dft_length,
- const Tensor* window, bool is_onesided, bool inverse,
- std::vector>& V,
- std::vector>& temp_output) {
-
- // Get shape and significant bits
- const auto& X_shape = X->Shape();
- size_t number_of_samples = static_cast(X_shape[axis]);
- unsigned significant_bits = static_cast(log2(dft_length));
-
- // Get data
- auto* X_data = const_cast(reinterpret_cast(X->DataRaw())) + X_offset;
- // Get window
- U* window_data = nullptr;
- if (window) {
- window_data = const_cast(reinterpret_cast(window->DataRaw()));
- }
-
- size_t Y_data_stride = 1;
- std::complex* Y_data;
- if (is_onesided) {
- if (temp_output.size() != dft_length) {
- temp_output = std::vector>(dft_length);
- }
- Y_data = temp_output.data();
- } else {
- Y_data = reinterpret_cast*>(Y->MutableDataRaw()) + Y_offset;
- Y_data_stride = Y_stride;
- }
-
- auto angular_velocity = compute_angular_velocity(dft_length, inverse);
-
- // Create vandermonde matrix V ordered with the bit-reversed permutation
- if (V.size() != dft_length) {
- V = std::vector>(dft_length); // e^(i *2*pi / N * k)
- for (size_t i = 0; i < dft_length; i++) {
- size_t bit_reversed_index = bit_reverse(i, significant_bits);
- V[bit_reversed_index] = std::complex(cos(i * angular_velocity), sin(i * angular_velocity));
- }
- }
-
- for (size_t i = 0; i < dft_length; i++) {
- size_t bit_reversed_index = bit_reverse(i, significant_bits);
- auto x = (bit_reversed_index < number_of_samples) ? * (X_data + bit_reversed_index * X_stride) : 0;
- auto window_element = window_data ? *(window_data + bit_reversed_index) : 1;
- *(Y_data + i*Y_data_stride) = std::complex(1, 0) * x * window_element;
- }
-
- // Run fft_radix2
- unsigned current_significant_bits = 0;
- for (size_t i = 2; i <= dft_length; i <<= 1) {
- size_t midpoint = i >> 1;
- current_significant_bits++;
-
- for (size_t k = 0; k < midpoint; k++) {
- auto first_idx = bit_reverse(k, current_significant_bits);
- auto second_idx = bit_reverse(midpoint + k, current_significant_bits);
- for (size_t j = 0; j < dft_length; j += i) {
- auto even_index = k + j;
- auto odd_index = k + j + midpoint;
- std::complex* even = (Y_data + even_index * Y_data_stride);
- std::complex* odd = (Y_data + odd_index * Y_data_stride);
- std::complex first = *even + (V[first_idx] * *odd);
- std::complex second = *even + (V[second_idx] * *odd);
- *even = first;
- *odd = second;
- }
- }
- }
-
- // Scale the output if inverse
- if (inverse) {
- for (size_t i = 0; i < dft_length; i++) {
- std::complex& val = *(Y_data + i * Y_data_stride);
- val /= static_cast(dft_length);
- }
- }
-
- if (is_onesided) {
- auto destination = reinterpret_cast*>(Y->MutableDataRaw()) + Y_offset;
- for (size_t i = 0; i < dft_length; i++) {
- *(destination + Y_stride * i) = *(Y_data + i * Y_data_stride);
- }
- }
-
- return Status::OK();
-}
-
-template
-static Status dft_naive(const Tensor* X, Tensor* Y,
- size_t X_offset, size_t X_stride, size_t Y_offset, size_t Y_stride, int64_t axis,
- size_t dft_length, const Tensor* window, bool inverse) {
- // Get shape and significant bits
- const auto& X_shape = X->Shape();
- size_t number_of_samples = static_cast(X_shape[axis]);
- const auto& Y_shape = Y->Shape();
- size_t dft_output_size = static_cast(Y_shape[axis]);
-
- // Get data
- auto* X_data = const_cast(reinterpret_cast(X->DataRaw())) + X_offset;
- auto* Y_data = reinterpret_cast*>(Y->MutableDataRaw()) + Y_offset;
-
- U* window_data = nullptr;
- if (window) {
- window_data = const_cast(reinterpret_cast(window->DataRaw()));
- }
-
- auto angular_velocity = compute_angular_velocity(dft_length, inverse);
-
- for (size_t i = 0; i < dft_output_size; i++) {
- std::complex& out = *(Y_data + i*Y_stride);
- out.real(0);
- out.imag(0);
-
- for (size_t j = 0; j < dft_length; j++) { // vectorize over this loop
- auto exponential = std::complex(cos(i * j * angular_velocity), sin(i * j * angular_velocity));
- auto window_element = window_data ? * (window_data + j) : 1;
- auto x = (j < number_of_samples) ? *(X_data + j * X_stride) : 0;
- auto element = x * window_element;
- out += exponential * element;
- }
-
- if (inverse) {
- out /= static_cast(dft_length);
- }
- }
-
- return Status::OK();
-}
-
-template
-static Status discrete_fourier_transform(OpKernelContext* ctx, const Tensor* X, Tensor* Y, int64_t axis, int64_t dft_length, const Tensor* window, bool is_onesided, bool inverse,
- std::vector>& V, std::vector>& temp_output) {
- // Get shape
- const auto& X_shape = X->Shape();
- const auto& Y_shape = Y->Shape();
-
- auto batch_and_signal_rank = X->Shape().NumDimensions();
- auto total_dfts = static_cast(X->Shape().Size() / X->Shape()[axis]);
-
- auto is_input_real = X->Shape().NumDimensions() == 2 || X->Shape()[X->Shape().NumDimensions() - 1] == 1;
- auto complex_input_factor = is_input_real ? 1 : 2;
- if (X->Shape().NumDimensions() > 2)
- {
- total_dfts /= X->Shape()[X->Shape().NumDimensions() - 1];
- batch_and_signal_rank -= 1;
- }
-
- // Calculate x/y offsets/strides
- for (size_t i = 0; i < total_dfts; i++)
- {
- size_t X_offset = 0;
- size_t X_stride = X_shape.SizeFromDimension(axis+1) / complex_input_factor;
- size_t cumulative_packed_stride = total_dfts;
- size_t temp = i;
- for (size_t r = 0; r < batch_and_signal_rank; r++) {
- if (r == static_cast(axis))
- {
- continue;
- }
- cumulative_packed_stride /= X_shape[r];
- auto index = temp / cumulative_packed_stride;
- temp -= (index * cumulative_packed_stride);
- X_offset += index * X_shape.SizeFromDimension(r + 1) / complex_input_factor;
- }
-
- size_t Y_offset = 0;
- size_t Y_stride = Y_shape.SizeFromDimension(axis + 1) / 2;
- cumulative_packed_stride = total_dfts;
- temp = i;
- for (size_t r = 0; r < batch_and_signal_rank; r++) {
- if (r == static_cast(axis))
- {
- continue;
- }
- cumulative_packed_stride /= X_shape[r];
- auto index = temp / cumulative_packed_stride;
- temp -= (index * cumulative_packed_stride);
- Y_offset += index * Y_shape.SizeFromDimension(r + 1) / 2;
- }
-
- if (is_power_of_2(dft_length)) {
- ORT_RETURN_IF_ERROR((fft_radix2(ctx, X, Y, X_offset, X_stride, Y_offset, Y_stride, axis, dft_length, window, is_onesided, inverse, V, temp_output)));
- } else {
- ORT_RETURN_IF_ERROR((dft_naive(X, Y, X_offset, X_stride, Y_offset, Y_stride, axis, dft_length, window, inverse)));
- }
- }
-
- return Status::OK();
-}
-
-static Status discrete_fourier_transform(OpKernelContext* ctx, int64_t axis, bool is_onesided, bool inverse) {
- // Get input shape
- const auto* X = ctx->Input(0);
- const auto* dft_length = ctx->Input(1);
- const auto& X_shape = X->Shape();
- const auto is_real_valued = is_real_valued_signal(X_shape);
- const auto is_complex_valued = is_complex_valued_signal(X_shape);
-
- // Get the rank of the input tensor
- // Ensure that the axis is in the valid range of [-rank, rank)
- auto rank = static_cast(X_shape.GetDims().size());
- if (!(-rank <= axis && axis < rank)) {
- ORT_RETURN_IF(!(-rank <= axis && axis < rank),
- "axis attribute value ",
- axis,
- " is invalid for a tensor of rank ",
- rank);
- }
- axis = (axis >= 0 ? axis : axis + rank);
-
- int64_t number_of_samples = static_cast(X_shape[axis]);
- if (dft_length) {
- const auto& dft_length_shape = dft_length->Shape();
- ORT_RETURN_IF(!dft_length_shape.IsScalar(), "dft_length must be a scalar value.");
- number_of_samples = static_cast(get_scalar_value_from_tensor(dft_length));
- ORT_RETURN_IF(number_of_samples <= 0, "dft_length must be greater than zero.");
- }
-
- // Get the DFT output size. Onesided will return only the unique values!
- // note: x >> 1 === std::floor(x / 2.f)
- auto dft_output_size = is_onesided ?
- ((number_of_samples >> 1) + 1) :
- number_of_samples;
-
- // Get output shape
- auto Y_shape = onnxruntime::TensorShape(X_shape);
- if (X_shape.NumDimensions() == 2)
- {
- Y_shape = onnxruntime::TensorShape({X_shape[0], dft_output_size, 2});
- } else
- {
- Y_shape[Y_shape.NumDimensions() - 1] = 2;
- }
- Y_shape[axis] = dft_output_size;
- auto Y = ctx->Output(0, Y_shape);
-
- // Get data type
- auto data_type = X->DataType();
-
- auto element_size = data_type->Size();
- if (element_size == sizeof(float)) {
- std::vector> V;
- std::vector> temp_output;
- if (is_real_valued) {
- ORT_RETURN_IF_ERROR((discrete_fourier_transform(ctx, X, Y, axis, number_of_samples, nullptr, is_onesided, inverse, V, temp_output)));
- } else if (is_complex_valued) {
- ORT_RETURN_IF_ERROR((discrete_fourier_transform>(ctx, X, Y, axis, number_of_samples, nullptr, is_onesided, inverse, V, temp_output)));
- } else {
- ORT_THROW("Unsupported input signal shape. The signal's first dimenstion must be the batch dimension and its second dimension must be the signal length dimension. It may optionally include a 3rd dimension of size 2 for complex inputs.", data_type);
- }
- } else if (element_size == sizeof(double)) {
- std::vector> V;
- std::vector> temp_output;
- if (is_real_valued) {
- ORT_RETURN_IF_ERROR((discrete_fourier_transform(ctx, X, Y, axis, number_of_samples, nullptr, is_onesided, inverse, V, temp_output)));
- } else if (is_complex_valued) {
- ORT_RETURN_IF_ERROR((discrete_fourier_transform>(ctx, X, Y, axis, number_of_samples, nullptr, is_onesided, inverse, V, temp_output)));
- } else {
- ORT_THROW("Unsupported input signal shape. The signal's first dimenstion must be the batch dimension and its second dimension must be the signal length dimension. It may optionally include a 3rd dimension of size 2 for complex inputs.", data_type);
- }
- } else {
- ORT_THROW("Unsupported input data type of ", data_type);
- }
-
- return Status::OK();
-}
-
-Status DFT::Compute(OpKernelContext* ctx) const {
- ORT_RETURN_IF_ERROR(
- discrete_fourier_transform(ctx,
- axis_,
- is_onesided_,
- is_inverse_));
- return Status::OK();
-}
-
-Status IDFT::Compute(OpKernelContext* ctx) const {
- ORT_RETURN_IF_ERROR(
- discrete_fourier_transform(ctx,
- axis_,
- false /*is_onesided_*/,
- true /*is_inverse_*/));
- return Status::OK();
-}
-
-template
-static Status short_time_fourier_transform(OpKernelContext* ctx, bool is_onesided, bool /*inverse*/) {
- // Attr("onesided"): default = 1
- // Input(0, "signal") type = T1
- // Input(1, "frame_length") type = T2
- // Input(2, "window") type = T1, optional
- // Input(3, "frame_step") type = T2
- // Output(0, "output") type = T1
-
- // Get signal
- const auto* signal = ctx->Input(0);
- const auto frame_step = get_scalar_value_from_tensor(ctx->Input(1));
- const auto* window = ctx->Input(2);
- const auto* frame_length_tensor = ctx->Input(3);
-
- // Get input signal shape
- const auto& signal_shape = signal->Shape();
- const auto batch_size = signal_shape[0];
- const auto signal_size = signal_shape[1];
- const auto signal_components =
- signal_shape.NumDimensions() == 2 ? 1 : signal_shape.NumDimensions() == 3 ? signal_shape[2] : 0; // error
- ORT_ENFORCE(signal_components == 1 || signal_components == 2, "Ensure that the signal has either 1 or 2 components.");
-
- // Get the frame length
- int64_t frame_length = std::numeric_limits::min();
- if (frame_length_tensor)
- {
- frame_length = get_scalar_value_from_tensor(frame_length_tensor);
- }
-
- // Get window length
- int64_t window_length = std::numeric_limits::min();
- if (window) {
- window_length = window->Shape()[0];
- }
-
- // The frame_length and window inputs are generally used interchangably, and should match!
- if (frame_length != std::numeric_limits::min() &&
- window_length != std::numeric_limits::min()) {
- ORT_ENFORCE(frame_length == window_length, "If both frame_length and window are set, then the size of the window must be equal to the frame_length.");
- }
-
- // Calculate the window size with preference to the window input.
- const auto window_size = window ? window->Shape()[0] : frame_length;
- ORT_ENFORCE(window_size < signal_size, "Ensure that the dft size is smaller than the signal.");
-
- // Calculate the number of dfts to run
- const auto n_dfts = static_cast(std::floor((signal_size - window_size) / static_cast(frame_step)) + 1);
-
- // Calculate the output spectra length (onesided will return only the unique values)
- // note: x >> 1 === std::floor(x / 2.f)
- const auto dft_output_size =
- is_onesided ?
- (window_size >> 1) + 1 :
- window_size;
-
- // Get/create the output mutable data
- auto output_spectra_shape = onnxruntime::TensorShape({batch_size, n_dfts, dft_output_size, 2});
- auto Y = ctx->Output(0, output_spectra_shape);
- auto Y_data = reinterpret_cast(Y->MutableDataRaw());
-
- // Get/create the signal mutable data
- auto* signal_data = const_cast(reinterpret_cast(signal->DataRaw()));
-
- // Define tensor shapes for each dft run
- const int64_t output_components = 2;
- auto dft_input_shape = onnxruntime::TensorShape({1, window_size, signal_components});
- auto dft_output_shape = onnxruntime::TensorShape({1, dft_output_size, output_components});
-
- std::vector> V;
- std::vector> temp_output;
-
- // Run each dft of each batch as if it was a real-valued batch size 1 dft operation
- for (int64_t batch_idx = 0; batch_idx < batch_size; batch_idx++) {
- for (int64_t i = 0; i < n_dfts; i++) {
- auto input_frame_begin =
- signal_data +
- (batch_idx * signal_size * signal_components) +
- (i * frame_step * signal_components);
-
- auto output_frame_begin =
- Y_data +
- (batch_idx * n_dfts * dft_output_size * output_components) +
- (i * dft_output_size * output_components);
-
- // Tensors do not own the backing memory, so no worries on destruction
- auto input =
- onnxruntime::Tensor(
- signal->DataType(),
- dft_input_shape,
- input_frame_begin,
- signal->Location(),
- 0);
-
- auto output =
- onnxruntime::Tensor(
- Y->DataType(),
- dft_output_shape,
- output_frame_begin,
- Y->Location(),
- 0);
-
- // Run individual dft
- ORT_RETURN_IF_ERROR((discrete_fourier_transform(ctx, &input, &output, 1, window_size, window, is_onesided, false, V, temp_output)));
- }
- }
-
- return Status::OK();
-}
-
-Status STFT::Compute(OpKernelContext* ctx) const {
- // Attr("onesided"): default = 1
- // Input(0, "signal") type = T1
- // Input(1, "frame_length") type = T2
- // Input(2, "window") type = T1, optional
- // Input(3, "frame_step") type = T2
- // Output(0, "output") type = T1
-
- // Get signal shape
- const auto* signal = ctx->Input(0);
- const auto& signal_shape = signal->Shape();
- const auto is_real_valued = is_real_valued_signal(signal_shape);
- const auto is_complex_valued = is_complex_valued_signal(signal_shape);
-
- // Get data type
- auto data_type = signal->DataType();
-
- const auto element_size = data_type->Size();
- if (element_size == sizeof(float)) {
- if (is_real_valued) {
- ORT_RETURN_IF_ERROR((short_time_fourier_transform(ctx, is_onesided_, false)));
- } else if (is_complex_valued) {
- ORT_RETURN_IF_ERROR((short_time_fourier_transform>(ctx, is_onesided_, false)));
- } else {
- ORT_THROW("Unsupported input signal shape. The signal's first dimenstion must be the batch dimension and its second dimension must be the signal length dimension. It may optionally include a 3rd dimension of size 2 for complex inputs.", data_type);
- }
- } else if (element_size == sizeof(double)) {
- if (is_real_valued) {
- ORT_RETURN_IF_ERROR((short_time_fourier_transform(ctx, is_onesided_, false)));
- } else if (is_complex_valued) {
- ORT_RETURN_IF_ERROR((short_time_fourier_transform>(ctx, is_onesided_, false)));
- } else {
- ORT_THROW("Unsupported input signal shape. The signal's first dimenstion must be the batch dimension and its second dimension must be the signal length dimension. It may optionally include a 3rd dimension of size 2 for complex inputs.", data_type);
- }
- } else {
- ORT_THROW("Unsupported input data type of ", data_type);
- }
-
- return Status::OK();
-}
-
-} // namespace contrib
-} // namespace onnxruntime
-
-#endif
diff --git a/onnxruntime/contrib_ops/cpu/signal/window_functions.cc b/onnxruntime/contrib_ops/cpu/signal/window_functions.cc
deleted file mode 100644
index 29256adb264d0..0000000000000
--- a/onnxruntime/contrib_ops/cpu/signal/window_functions.cc
+++ /dev/null
@@ -1,334 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-#ifdef BUILD_MS_EXPERIMENTAL_OPS
-
-#include "core/providers/common.h"
-#include "core/framework/op_kernel.h"
-#include "core/util/math_cpuonly.h"
-#include "Eigen/src/Core/Map.h"
-#include "window_functions.h"
-#include
-
-#include "core/platform/threadpool.h"
-
-#include
-#include
-
-namespace onnxruntime {
-namespace contrib {
-
-ONNX_OPERATOR_KERNEL_EX(
- HannWindow,
- kMSExperimentalDomain,
- 1,
- kCpuExecutionProvider,
- KernelDefBuilder().MayInplace(0, 0)
- .TypeConstraint("T1", BuildKernelDefConstraints())
- .TypeConstraint("T2", BuildKernelDefConstraints()),
- HannWindow);
-
-ONNX_OPERATOR_KERNEL_EX(
- HammingWindow,
- kMSExperimentalDomain,
- 1,
- kCpuExecutionProvider,
- KernelDefBuilder().MayInplace(0, 0)
- .TypeConstraint("T1", BuildKernelDefConstraints())
- .TypeConstraint("T2", BuildKernelDefConstraints()),
- HammingWindow);
-
-ONNX_OPERATOR_KERNEL_EX(
- BlackmanWindow,
- kMSExperimentalDomain,
- 1,
- kCpuExecutionProvider,
- KernelDefBuilder().MayInplace(0, 0)
- .TypeConstraint("T1", BuildKernelDefConstraints())
- .TypeConstraint("T2", BuildKernelDefConstraints()),
- BlackmanWindow);
-
-
-ONNX_OPERATOR_KERNEL_EX(
- MelWeightMatrix,
- kMSExperimentalDomain,
- 1,
- kCpuExecutionProvider,
- KernelDefBuilder().MayInplace(0, 0)
- .TypeConstraint("T1", BuildKernelDefConstraints())
- .TypeConstraint("T2", BuildKernelDefConstraints())
- .TypeConstraint("T3", BuildKernelDefConstraints()),
- MelWeightMatrix);
-
-
-template
-static Status cosine_sum_window(Tensor* Y, size_t size, float a0, float a1, float a2) {
- auto* Y_data = reinterpret_cast(Y->MutableDataRaw());
-
- // Calculate the radians to increment per sample
- constexpr double pi = 3.14159265;
- constexpr double tau = 2 * pi;
- const double angular_increment = tau / size;
-
- for (size_t i = 0; i < size; i++) {
- auto a2_component = a2 == 0 ? 0 : (a2 * cos(2 * angular_increment * i));
-
- T& value = *(Y_data + i);
- value = static_cast(a0 - (a1 * cos(angular_increment * i)) + a2_component);
- }
-
- return Status::OK();
-}
-
-template
-static T get_scalar_value_from_tensor(const Tensor* tensor) {
- ORT_ENFORCE(tensor->Shape().Size() == 1, "Tensor input should have a single value.");
- auto data_type = tensor->DataType()->AsPrimitiveDataType()->GetDataType();
- switch (data_type) {
- case ONNX_NAMESPACE::TensorProto_DataType_FLOAT:
- return static_cast(*reinterpret_cast(tensor->DataRaw()));
- case ONNX_NAMESPACE::TensorProto_DataType_DOUBLE:
- return static_cast(*reinterpret_cast(tensor->DataRaw()));
- case ONNX_NAMESPACE::TensorProto_DataType_INT32:
- return static_cast(*reinterpret_cast(tensor->DataRaw()));
- case ONNX_NAMESPACE::TensorProto_DataType_INT64:
- return static_cast(*reinterpret_cast(tensor->DataRaw()));
- default:
- ORT_THROW("Unsupported input data type of ", data_type);
- }
-}
-
-static Status create_cosine_sum_window(
- OpKernelContext* ctx,
- onnx::TensorProto_DataType output_datatype,
- float a0, float a1, float a2) {
-
- // Get the size of the window
- auto size = get_scalar_value_from_tensor(ctx->Input(0));
-
- // Get the output tensor
- auto Y_shape = onnxruntime::TensorShape({size});
- auto Y = ctx->Output(0, Y_shape);
-
- switch (output_datatype) {
- case ONNX_NAMESPACE::TensorProto_DataType_FLOAT: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_DOUBLE: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_INT8: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_INT16: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_INT32: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_INT64: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_UINT8: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_UINT16: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_UINT32: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_UINT64: {
- ORT_RETURN_IF_ERROR((cosine_sum_window(Y, size, a0, a1, a2)));
- break;
- }
- default:
- ORT_THROW("Unsupported input data type of ", output_datatype);
- }
-
- return Status::OK();
-}
-
-Status HannWindow::Compute(OpKernelContext* ctx) const {
- // HannWindows are a special case of Cosine-Sum Windows which take the following form:
- // w[n] = SUM_k=0_K( (-1)^k * a_k * cos(2*pi*k*n/N) ) with values the following values for a_k:
- float a0 = .5f;
- float a1 = a0;
- float a2 = 0;
- return create_cosine_sum_window(ctx, data_type_, a0, a1, a2);
-}
-
-Status HammingWindow::Compute(OpKernelContext* ctx) const {
- // HammingWindows are a special case of Cosine-Sum Windows which take the following form:
- // w[n] = SUM_k=0_K( (-1)^k * a_k * cos(2*pi*k*n/N) ) with values the following values for a_k:
- float a0 = 25.f / 46.f;
- float a1 = 1 - a0;
- float a2 = 0;
- return create_cosine_sum_window(ctx, data_type_, a0, a1, a2);
-}
-
-Status BlackmanWindow::Compute(OpKernelContext* ctx) const {
- // BlackmanWindows are a special case of Cosine-Sum Windows which take the following form:
- // w[n] = SUM_k=0_K( (-1)^k * a_k * cos(2*pi*k*n/N) ) with values the following values for a_k:
- float alpha = .16f;
- float a2 = alpha / 2.f;
- float a0 = .5f - a2;
- float a1 = .5f;
- return create_cosine_sum_window(ctx, data_type_, a0, a1, a2);
-}
-
-static inline double hz_to_mel_scale(double hz) {
- return 2595 * std::log10(1 + hz / 700);
-}
-
-static inline double mel_scale_to_hz(double mels) {
- return 700 * (pow(10, (mels / 2595)) - 1);
-}
-
-template
-Status create_mel_weight_matrix(OpKernelContext* ctx, int64_t num_mel_bins, int64_t dft_length, int64_t sample_rate, float lower_edge_hertz, float upper_edge_hertz) {
- // Determine the width of the spectrogram.
- // This is determined as half the size of the fft size. The first element of the spectrum is always retained,
- // and the remaining are halved. The second half can be discarded due to the conjugate symmetry of the output with real valued ffts.
- // Taken together the formula for the size of the output will be std::floor(dft_length / 2) + 1.
- int64_t num_spectrogram_bins = static_cast(std::floor(dft_length / 2 + 1));
-
- // Checks
- auto lowest_index = std::floor(((dft_length + 1) * lower_edge_hertz) / sample_rate);
- auto highest_index = std::floor(((dft_length + 1) * upper_edge_hertz) / sample_rate);
- ORT_ENFORCE(lowest_index >= 0 && lowest_index < num_spectrogram_bins, "lower_edge_hertz produces a mel triangle filter bank that is out of range given the dft_length and the sample_rate.");
- ORT_ENFORCE(highest_index >= 0 && highest_index < num_spectrogram_bins, "upper_edge_hertz produces a mel triangle filter bank that is out of range given the dft_length and the sample_rate.");
-
- // Create the output shape
- onnxruntime::TensorShape output_shape(
- {
- static_cast(num_spectrogram_bins),
- num_mel_bins
- });
- auto* Y = ctx->Output(0, output_shape);
-
- // Get the raw output data
- auto* Y_data = reinterpret_cast(Y->MutableDataRaw());
-
- // Set the weight matrix to 0
- memset(Y_data, 0, num_spectrogram_bins * num_mel_bins * sizeof(T));
-
- // The mel filterbank is a triangular shaped peak with a height of 1 and a base equal to the size of the MEL range divided by
- // the number of bins needed times 2. This triagle is then slid across the mel domain linearly, with a constant step size that
- // is equal to half of the base of the triange. To accomodate N bins, N+2 data points will be needed to determine the
- // start, center and end points of each mel triange filter.
- //
- // low_frequency where the mel triangle filter banks begin, and they end on the high_frequency_mel
- // The range is divided evenly to create the needed points corresponding to the begin, center, end points of each triangle filterbank
- std::vector frequency_bins(num_mel_bins + 2);
- auto low_frequency_mel = hz_to_mel_scale(lower_edge_hertz);
- auto high_frequency_mel = hz_to_mel_scale(upper_edge_hertz);
- auto mel_step = (high_frequency_mel - low_frequency_mel) / static_cast(frequency_bins.size());
-
- // Convert each point from mel scale back to hertz, and then compute the corresponding index in the fft
- for (size_t i = 0; i < frequency_bins.size(); i++) {
- auto hz = mel_scale_to_hz(low_frequency_mel + mel_step * i);
- frequency_bins[i] = static_cast(std::floor(((dft_length + 1) * hz) / sample_rate));
- }
-
- for (size_t i = 0; i < static_cast(num_mel_bins); i++) {
- auto lower_frequency_value = frequency_bins[i]; //left
- auto center_frequency_point = frequency_bins[i+1]; //center
- auto higher_frequency_point = frequency_bins[i+2]; //right
-
- auto low_to_center = center_frequency_point - lower_frequency_value;
- if (low_to_center == 0) {
- auto& current_element = *(Y_data + (center_frequency_point * num_mel_bins) + i);
- current_element = static_cast(1);
- } else {
- for (size_t j = lower_frequency_value; j <= center_frequency_point; j++) {
- auto& current_element = *(Y_data + (j * num_mel_bins) + i);
- current_element = static_cast((j - lower_frequency_value) / static_cast(low_to_center));
- }
- }
-
- auto center_to_high = higher_frequency_point - center_frequency_point;
- if (center_to_high > 0) {
- for (size_t j = center_frequency_point; j < higher_frequency_point; j++) {
- auto& current_element = *(Y_data + (j * num_mel_bins) + i);
- current_element = static_cast((higher_frequency_point - j) / static_cast(center_to_high));
- }
- }
- }
-
- return Status::OK();
-}
-
-static Status create_mel_weight_matrix(OpKernelContext* ctx, onnx::TensorProto_DataType output_datatype,
- int64_t num_mel_bins, int64_t dft_length, int64_t sample_rate, float lower_edge_hertz, float upper_edge_hertz) {
- switch (output_datatype) {
- case ONNX_NAMESPACE::TensorProto_DataType_FLOAT: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_DOUBLE: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_INT8: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_INT16: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_INT32: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_INT64: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_UINT8: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_UINT16: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_UINT32: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- case ONNX_NAMESPACE::TensorProto_DataType_UINT64: {
- ORT_RETURN_IF_ERROR((create_mel_weight_matrix(ctx, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz)));
- break;
- }
- default:
- ORT_THROW("Unsupported input data type of ", output_datatype);
- }
- return Status::OK();
-}
-
-Status MelWeightMatrix::Compute(OpKernelContext* ctx) const {
- const auto num_mel_bins = get_scalar_value_from_tensor(ctx->Input(0));
- const auto dft_length = get_scalar_value_from_tensor(ctx->Input(1));
- const auto sample_rate = get_scalar_value_from_tensor(ctx->Input(2));
- const auto lower_edge_hertz = get_scalar_value_from_tensor(ctx->Input(3));
- const auto upper_edge_hertz = get_scalar_value_from_tensor(ctx->Input(4));
-
- ORT_RETURN_IF_ERROR(create_mel_weight_matrix(ctx, data_type_, num_mel_bins, dft_length, sample_rate, lower_edge_hertz, upper_edge_hertz));
- return Status::OK();
-}
-
-} // namespace contrib
-} // namespace onnxruntime
-
-#endif
diff --git a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc
index 8cf2d278e0ead..fb7bc16cc190a 100644
--- a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc
+++ b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc
@@ -16,7 +16,6 @@
#include "core/graph/contrib_ops/range_schema_defs.h"
#include "core/graph/op.h"
#include "core/mlas/inc/mlas.h"
-#include "core/graph/signal_ops/signal_defs.h"
#include "core/graph/contrib_ops/onnx_function_util.h"
#include "onnx/defs/function.h"
@@ -370,7 +369,6 @@ void sparseCompatibleMatmulShapeInference(
updateOutputShape(ctx, 0, resultShape, default_tensor_type);
}
-
bool ParseScalar(const TensorProto* initializer, int& value) {
std::vector parsed_data;
if (initializer->data_type() == TensorProto::INT32) {
@@ -2417,7 +2415,6 @@ void RegisterContribSchemas() {
// }
// updateOutputShape(ctx, 0, disentangled_attention_shape);
propagateShapeFromInputToOutput(ctx, 0, 0);
-
});
ONNX_CONTRIB_OPERATOR_SCHEMA(Snpe)
@@ -2535,10 +2532,6 @@ This op functions in much the same was as Dropout-11 and Dropout-13 do, execpt t
RegisterNchwcSchemas();
}
#endif
-
-#ifdef BUILD_MS_EXPERIMENTAL_OPS
- onnxruntime::signal::RegisterSignalSchemas();
-#endif
}
} // namespace contrib
diff --git a/onnxruntime/core/graph/signal_ops/signal_defs.cc b/onnxruntime/core/graph/signal_ops/signal_defs.cc
deleted file mode 100644
index 27e077c9fefe4..0000000000000
--- a/onnxruntime/core/graph/signal_ops/signal_defs.cc
+++ /dev/null
@@ -1,738 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT License.
-
-#ifdef BUILD_MS_EXPERIMENTAL_OPS
-
-#include "core/framework/tensorprotoutils.h"
-#include "core/providers/common.h"
-#include "core/graph/constants.h"
-#include "core/graph/signal_ops/signal_defs.h"
-#include "core/graph/op.h"
-#include "onnx/defs/schema.h"
-#include "onnx/defs/shape_inference.h"
-#include "onnx/defs/tensor_proto_util.h"
-
-#include
-
-namespace onnxruntime {
-namespace signal {
-
-using ONNX_NAMESPACE::AttributeProto;
-using ONNX_NAMESPACE::OpSchema;
-using ONNX_NAMESPACE::OPTIONAL_VALUE;
-
-template
-static T get_scalar_value_from_tensor(const ONNX_NAMESPACE::TensorProto* t) {
- if (t == nullptr) {
- return T{};
- }
-
- auto data_type = t->data_type();
- switch (data_type) {
- case ONNX_NAMESPACE::TensorProto::FLOAT:
- return static_cast(ONNX_NAMESPACE::ParseData