| # Licensed to the Apache Software Foundation (ASF) under one | 
 | # or more contributor license agreements.  See the NOTICE file | 
 | # distributed with this work for additional information | 
 | # regarding copyright ownership.  The ASF licenses this file | 
 | # to you under the Apache License, Version 2.0 (the | 
 | # "License"); you may not use this file except in compliance | 
 | # with the License.  You may obtain a copy of the License at | 
 | # | 
 | #   http://www.apache.org/licenses/LICENSE-2.0 | 
 | # | 
 | # Unless required by applicable law or agreed to in writing, | 
 | # software distributed under the License is distributed on an | 
 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
 | # KIND, either express or implied.  See the License for the | 
 | # specific language governing permissions and limitations | 
 | # under the License. | 
 | """Test code for discrete Fourier transform.""" | 
 | import numpy as np | 
 | import tvm | 
 | import tvm.testing | 
 | from tvm import topi | 
 | import tvm.topi.testing | 
 |  | 
 |  | 
 | inverse = tvm.testing.parameter(False, True) | 
 | shape = tvm.testing.parameter((7,), (3, 7), (3, 4, 5)) | 
 | dtype = tvm.testing.parameter("float16", "float32", "float64") | 
 |  | 
 |  | 
 | # pylint: disable=redefined-outer-name, invalid-name | 
 | def numpy_reference(inverse, re: np.ndarray, im: np.ndarray): | 
 |     if inverse: | 
 |         reference = np.fft.ifft(re + 1j * im) | 
 |     else: | 
 |         reference = np.fft.fft(re + 1j * im) | 
 |     return np.real(reference), np.imag(reference) | 
 |  | 
 |  | 
 | def test_dft(target, dev, inverse, shape, dtype): | 
 |     """Test for discrete Fourier transform.""" | 
 |     implementations = { | 
 |         "generic": ( | 
 |             topi.dft, | 
 |             topi.generic.schedule_extern, | 
 |         ), | 
 |         "gpu": ( | 
 |             topi.cuda.dft, | 
 |             topi.cuda.schedule_extern, | 
 |         ), | 
 |         "nvptx": ( | 
 |             topi.cuda.dft, | 
 |             topi.cuda.schedule_extern, | 
 |         ), | 
 |     } | 
 |  | 
 |     Re = tvm.te.placeholder(shape, dtype=dtype, name="Re") | 
 |     Im = tvm.te.placeholder(shape, dtype=dtype, name="Im") | 
 |  | 
 |     with tvm.target.Target(target): | 
 |         fcompute, fschedule = tvm.topi.testing.dispatch(target, implementations) | 
 |  | 
 |         outs = fcompute(Re, Im, inverse) | 
 |         s = fschedule(outs) | 
 |  | 
 |         f = tvm.build(s, [Re, Im, *outs], target) | 
 |  | 
 |     re_np = np.random.normal(size=shape).astype(dtype) | 
 |     im_np = np.random.normal(size=shape).astype(dtype) | 
 |  | 
 |     re = tvm.nd.array(re_np, device=dev) | 
 |     im = tvm.nd.array(im_np, device=dev) | 
 |     re_out = tvm.nd.array(np.zeros(shape).astype(dtype), device=dev) | 
 |     im_out = tvm.nd.array(np.zeros(shape).astype(dtype), device=dev) | 
 |  | 
 |     f(re, im, re_out, im_out) | 
 |  | 
 |     re_reference, im_reference = numpy_reference(inverse, re_np, im_np) | 
 |  | 
 |     atol = rtol = 1e-3 | 
 |     if dtype == "float16": | 
 |         atol = rtol = 1e-1 | 
 |  | 
 |     tvm.testing.assert_allclose(re_out.numpy(), re_reference, rtol=rtol, atol=atol) | 
 |     tvm.testing.assert_allclose(im_out.numpy(), im_reference, rtol=rtol, atol=atol) | 
 |  | 
 |  | 
 | if __name__ == "__main__": | 
 |     tvm.testing.main() |