mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-27 20:02:15 +00:00
fix complex multi-dim dft (#10896)
Co-authored-by: Sheil Kumar <sheilk@microsoft.com>
This commit is contained in:
parent
07a71d5bf2
commit
810c18e809
2 changed files with 60 additions and 15 deletions
|
|
@ -278,17 +278,22 @@ static Status discrete_fourier_transform(OpKernelContext* ctx, const Tensor* X,
|
|||
|
||||
auto batch_and_signal_rank = X->Shape().NumDimensions();
|
||||
auto total_dfts = static_cast<size_t>(X->Shape().Size() / X->Shape()[axis]);
|
||||
|
||||
auto is_input_real = X->Shape().NumDimensions() == 2 || X->Shape()[X->Shape().NumDimensions() - 1] == 1;
|
||||
auto compex_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);
|
||||
size_t X_stride = X_shape.SizeFromDimension(axis+1) / compex_input_factor;
|
||||
size_t cumulative_packed_stride = total_dfts;
|
||||
size_t temp = i;
|
||||
for (size_t r = 0; r < batch_and_signal_rank; r++) {
|
||||
|
|
@ -299,7 +304,7 @@ static Status discrete_fourier_transform(OpKernelContext* ctx, const Tensor* X,
|
|||
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);
|
||||
X_offset += index * X_shape.SizeFromDimension(r + 1) / compex_input_factor;
|
||||
}
|
||||
|
||||
size_t Y_offset = 0;
|
||||
|
|
|
|||
|
|
@ -944,40 +944,80 @@ static void ModelBuilding_DiscreteFourierTransform() {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void ModelBuilding_DiscreteFourierTransformInverseIdentity() {
|
||||
#if !defined(BUILD_INBOX) && defined(BUILD_MS_EXPERIMENTAL_OPS)
|
||||
std::vector<int64_t> shape = {1, 5};
|
||||
std::vector<int64_t> output_shape = {1, shape[1], 2};
|
||||
static void DiscreteFourierTransformInverse(size_t axis) {
|
||||
std::vector<int64_t> shape = {2, 5, 8, 1};
|
||||
std::vector<int64_t> output_shape = {2, 5, 8, 2};
|
||||
|
||||
auto model =
|
||||
LearningModelBuilder::Create(13)
|
||||
.Inputs().Add(LearningModelBuilder::CreateTensorFeatureDescriptor(L"Input.TimeSignal", TensorKind::Float, shape))
|
||||
.Outputs().Add(LearningModelBuilder::CreateTensorFeatureDescriptor(L"Output.Spectra", TensorKind::Float, output_shape))
|
||||
.Outputs().Add(LearningModelBuilder::CreateTensorFeatureDescriptor(L"Output.Inverse", TensorKind::Float, output_shape))
|
||||
.Operators().Add(Operator(L"DFT", MS_EXPERIMENTAL_DOMAIN)
|
||||
.SetInput(L"input", L"Input.TimeSignal")
|
||||
.SetOutput(L"output", L"DFTOutput"))
|
||||
.Operators().Add(Operator(L"IDFT", MS_EXPERIMENTAL_DOMAIN)
|
||||
.SetInput(L"input", L"DFTOutput")
|
||||
.SetAttribute(L"axis", TensorInt64Bit::CreateFromArray({}, {INT64(axis)}))
|
||||
.SetOutput(L"output", L"Output.Spectra"))
|
||||
.Operators().Add(Operator(L"IDFT", MS_EXPERIMENTAL_DOMAIN)
|
||||
.SetInput(L"input", L"Output.Spectra")
|
||||
.SetAttribute(L"axis", TensorInt64Bit::CreateFromArray({}, {INT64(axis)}))
|
||||
.SetOutput(L"output", L"Output.Inverse"))
|
||||
.CreateModel();
|
||||
|
||||
LearningModelSession session(model);
|
||||
LearningModelBinding binding(session);
|
||||
|
||||
auto input_vector =
|
||||
std::vector<float>{
|
||||
1, 2, 3, 4, 5, 6, 7, 8,
|
||||
1, 2, 3, 4, 5, 6, 7, 8,
|
||||
1, 2, 3, 4, 5, 6, 7, 8,
|
||||
1, 2, 3, 4, 5, 6, 7, 8,
|
||||
1, 2, 3, 4, 5, 6, 7, 8,
|
||||
|
||||
2, 4, 6, 8, 10, 12, 14, 16,
|
||||
2, 4, 6, 8, 10, 12, 14, 16,
|
||||
2, 4, 6, 8, 10, 12, 14, 16,
|
||||
2, 4, 6, 8, 10, 12, 14, 16,
|
||||
2, 4, 6, 8, 10, 12, 14, 16,
|
||||
};
|
||||
// Populate binding
|
||||
binding.Bind(L"Input.TimeSignal", TensorFloat::CreateFromArray(shape, {1, 2, 3, 4, 5}));
|
||||
binding.Bind(
|
||||
L"Input.TimeSignal",
|
||||
TensorFloat::CreateFromArray(
|
||||
shape,
|
||||
input_vector));
|
||||
|
||||
// Evaluate
|
||||
auto result = session.Evaluate(binding, L"");
|
||||
|
||||
|
||||
// Check results
|
||||
printf("Output.Spectra\n");
|
||||
auto y_tensor = result.Outputs().Lookup(L"Output.Spectra").as<TensorFloat>();
|
||||
auto y_tensor = result.Outputs().Lookup(L"Output.Inverse").as<TensorFloat>();
|
||||
auto y_ivv = y_tensor.GetAsVectorView();
|
||||
for (int i = 0; i < output_shape[0] * output_shape[1] * 2; i += 2) {
|
||||
printf("(%f + %fi), ", y_ivv.GetAt(i), y_ivv.GetAt(i + 1));
|
||||
for (uint32_t i = 0; i < y_ivv.Size(); i += 2) {
|
||||
WINML_EXPECT_TRUE(abs(y_ivv.GetAt(i) - input_vector[i / 2]) < .001);
|
||||
WINML_EXPECT_TRUE(abs(y_ivv.GetAt(i + 1) - 0) < .001);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
//printf("Output.Spectra\n");
|
||||
//auto y_tensor = result.Outputs().Lookup(L"Output.Spectra").as<TensorFloat>();
|
||||
//auto y_ivv = y_tensor.GetAsVectorView();
|
||||
//for (uint32_t i = 0; i < y_ivv.Size(); i+=2) {
|
||||
// auto format_size = 16;
|
||||
// if (i % format_size == 0 && i != 0) {
|
||||
// printf("\n");
|
||||
// }
|
||||
// printf("(%.2f + %.2fi), ", y_ivv.GetAt(i), y_ivv.GetAt(i + 1));
|
||||
//}
|
||||
//printf("\n");
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ModelBuilding_DiscreteFourierTransformInverseIdentity() {
|
||||
#if !defined(BUILD_INBOX) && defined(BUILD_MS_EXPERIMENTAL_OPS)
|
||||
DiscreteFourierTransformInverse(0);
|
||||
DiscreteFourierTransformInverse(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue