| 91 | } |
| 92 | |
| 93 | TfLiteStatus ResizeOutputandTemporaryTensors(TfLiteContext* context, |
| 94 | TfLiteNode* node) { |
| 95 | const TfLiteTensor* input = GetInput(context, node, kInputTensor); |
| 96 | const int num_dims = NumDimensions(input); |
| 97 | TF_LITE_ENSURE(context, num_dims >= 2); |
| 98 | const TfLiteTensor* fft_length = GetInput(context, node, kFftLengthTensor); |
| 99 | const int32_t* fft_length_data = GetTensorData<int32_t>(fft_length); |
| 100 | // The lib, fft2d, can only handle fft_lengths of power of 2. |
| 101 | TF_LITE_ENSURE(context, IsPowerOfTwo(fft_length_data[0])); |
| 102 | TF_LITE_ENSURE(context, IsPowerOfTwo(fft_length_data[1])); |
| 103 | |
| 104 | int fft_height, fft_width; |
| 105 | fft_height = fft_length_data[0]; |
| 106 | fft_width = fft_length_data[1]; |
| 107 | int fft_working_length = std::max(fft_height, fft_width / 2); |
| 108 | int half_fft_working_length = fft_working_length / 2; |
| 109 | |
| 110 | // Resize output tensor. |
| 111 | TfLiteTensor* output = GetOutput(context, node, kOutputTensor); |
| 112 | TfLiteIntArray* output_shape = TfLiteIntArrayCopy(input->dims); |
| 113 | output_shape->data[num_dims - 2] = fft_length_data[0]; |
| 114 | output_shape->data[num_dims - 1] = fft_length_data[1] / 2 + 1; |
| 115 | TF_LITE_ENSURE_STATUS(context->ResizeTensor(context, output, output_shape)); |
| 116 | |
| 117 | // Resize temporary tensors, fft_integer_working_area. |
| 118 | TfLiteTensor* fft_integer_working_area = |
| 119 | GetTemporary(context, node, kFftIntegerWorkingAreaTensor); |
| 120 | TfLiteIntArray* fft_integer_working_area_shape = TfLiteIntArrayCreate(1); |
| 121 | fft_integer_working_area_shape->data[0] = |
| 122 | 2 + static_cast<int>(sqrt(fft_working_length)); |
| 123 | TF_LITE_ENSURE_STATUS(context->ResizeTensor(context, fft_integer_working_area, |
| 124 | fft_integer_working_area_shape)); |
| 125 | |
| 126 | // Resize temporary tensors, fft_double_working_area. |
| 127 | TfLiteTensor* fft_double_working_area = |
| 128 | GetTemporary(context, node, kFftDoubleWorkingAreaTensor); |
| 129 | TfLiteIntArray* fft_double_working_area_shape = TfLiteIntArrayCreate(1); |
| 130 | fft_double_working_area_shape->data[0] = |
| 131 | half_fft_working_length + fft_width / 4; |
| 132 | TF_LITE_ENSURE_STATUS(context->ResizeTensor(context, fft_double_working_area, |
| 133 | fft_double_working_area_shape)); |
| 134 | |
| 135 | return kTfLiteOk; |
| 136 | } |
| 137 | |
| 138 | void* Init(TfLiteContext* context, const char* buffer, size_t length) { |
| 139 | auto* data = new OpData; |
no test coverage detected