MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / DoFFT

Method DoFFT

tensorflow/core/kernels/fft_ops.cc:126–251  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

124 bool IsReal() const override { return _Real; }
125
126 void DoFFT(OpKernelContext* ctx, const Tensor& in, uint64* fft_shape,
127 Tensor* out) override {
128 // Create the axes (which are always trailing).
129 const auto axes = Eigen::ArrayXi::LinSpaced(FFTRank, 1, FFTRank);
130 auto device = ctx->eigen_device<CPUDevice>();
131
132 if (!IsReal()) {
133 // Compute the FFT using Eigen.
134 constexpr auto direction =
135 Forward ? Eigen::FFT_FORWARD : Eigen::FFT_REVERSE;
136 if (in.dtype() == DT_COMPLEX64) {
137 DCHECK_EQ(out->dtype(), DT_COMPLEX64);
138 auto input = Tensor(in).flat_inner_dims<complex64, FFTRank + 1>();
139 auto output = out->flat_inner_dims<complex64, FFTRank + 1>();
140 output.device(device) =
141 input.template fft<Eigen::BothParts, direction>(axes);
142 } else {
143 DCHECK_EQ(DT_COMPLEX128, in.dtype());
144 DCHECK_EQ(DT_COMPLEX128, out->dtype());
145 auto input = Tensor(in).flat_inner_dims<complex128, FFTRank + 1>();
146 auto output = out->flat_inner_dims<complex128, FFTRank + 1>();
147 output.device(device) =
148 input.template fft<Eigen::BothParts, direction>(axes);
149 }
150 } else {
151 if (IsForward()) {
152 auto input = Tensor(in).flat_inner_dims<float, FFTRank + 1>();
153 const auto input_dims = input.dimensions();
154
155 // Slice input to fft_shape on its inner-most dimensions.
156 Eigen::DSizes<Eigen::DenseIndex, FFTRank + 1> input_slice_sizes;
157 input_slice_sizes[0] = input_dims[0];
158 TensorShape temp_shape{input_dims[0]};
159 for (int i = 1; i <= FFTRank; ++i) {
160 input_slice_sizes[i] = fft_shape[i - 1];
161 temp_shape.AddDim(fft_shape[i - 1]);
162 }
163
164 auto output = out->flat_inner_dims<complex64, FFTRank + 1>();
165 const Eigen::DSizes<Eigen::DenseIndex, FFTRank + 1> zero_start_indices;
166
167 // Compute the full FFT using a temporary tensor.
168 Tensor temp;
169 OP_REQUIRES_OK(ctx, ctx->allocate_temp(DataTypeToEnum<complex64>::v(),
170 temp_shape, &temp));
171 auto full_fft = temp.flat_inner_dims<complex64, FFTRank + 1>();
172 full_fft.device(device) =
173 input.slice(zero_start_indices, input_slice_sizes)
174 .template fft<Eigen::BothParts, Eigen::FFT_FORWARD>(axes);
175
176 // Slice away the negative frequency components.
177 output.device(device) =
178 full_fft.slice(zero_start_indices, output.dimensions());
179 } else {
180 // Reconstruct the full FFT and take the inverse.
181 auto input = Tensor(in).flat_inner_dims<complex64, FFTRank + 1>();
182 auto output = out->flat_inner_dims<float, FFTRank + 1>();
183 const auto input_dims = input.dimensions();

Callers

nothing calls this directly

Calls 10

IsRealFunction · 0.85
sliceMethod · 0.80
conjugateMethod · 0.80
TensorClass · 0.70
dtypeMethod · 0.45
deviceMethod · 0.45
dimensionsMethod · 0.45
AddDimMethod · 0.45
allocate_tempMethod · 0.45
reverseMethod · 0.45

Tested by

no test coverage detected