The following test program shows the sample usage and calling sequence of AOCL-FFTZ APIs for single-threaded N-dimensional FFT computation for real input to complex output (Forward FFT) using double-precision on ILP64 architecture systems:
1
2 aoclfftz_dim_t_64_ vecs[] = {{.n = 3, .in_stride = 0, .out_stride = 0},
3 {.n = 6, .in_stride = 0, .out_stride = 0}};
4 aoclfftz_prob_desc_d_64_ problem = {
5 .dim_rank = 3, // the number of signal/frequency dimensions, must be >= 1.
6 .vec_rank = 2, // the number of batch/vector dimensions, must be >= 1.
7 .dims = dims,
8 .vecs = vecs,
9 .flags = {
10 1, // fft_type : complex(0), real(1)
11 0, // fft_direction : forward(0), backward(1)
12 0, // storage_order : inorder(0), out-of-order(1)
13 0, // fft_placement : inplace(0), out-of-place(1)
14 0 // transpose_mode : FFT(0), standalone transpose(1)
15 },
16 .pthr_fft = {
17 /*
18 * num_threads = 1 for Single Threaded Execution
19 * num_threads > 1 for Multithreaded Execution (Make sure that Library
20 * is built with ENABLE_MULTI_THREADING=ON for multithreading execution)
21 */
22 .num_threads = 1,
23 .dynamic_load_model = 0},
24 .cntrl_params =
25 {
26 .opt_level = 0,
27 .opt_off = 1,
28 .logger_mode = 0,
29 .measure_stats = 0,
30 },
31 };
32
33 /* STEP 1.1: Set default vecs and dims strides values. */
34 set_default_dims_vecs(problem.dims, problem.dim_rank,
35 problem.vecs, problem.vec_rank, problem.flags);
36 UINT8 is_out_of_place = problem.flags.fft_placement;
37
38 /* STEP 1.2: Calculate input/output buffer sizes. */
39 UINTP in_buffer_size = 0;
40 UINTP out_buffer_size = 0;
41 calculate_buffer_sizes(problem.dims, problem.dim_rank, problem.vecs,
42 problem.vec_rank, &in_buffer_size, &out_buffer_size);
43
44
45 /* Real forward: input is real, output is half-complex.
46 Complex values need 2 doubles (real + imag), real values need 1 double. */
47 UINTP in_data_stride = 1;
48 UINTP out_data_stride = 2;
49
50 /* STEP 1.3: Allocate memory input/output buffers and
51 create new output buffer in case of out-of-place problem.
52 For in-place real FFT, output is half-complex (out_data_stride doubles
53 per element), so allocate max(in_size, out_size*out_data_stride). */
54 DOUBLE *in = NULL;
55 DOUBLE *out = NULL;
56 UINTP alloc_size = in_buffer_size * in_data_stride;
57 if (!is_out_of_place && problem.flags.fft_type == 1)
58 {
59 UINTP out_doubles = out_buffer_size * out_data_stride;
60 if (out_doubles > alloc_size)
61 {
62 alloc_size = out_doubles;
63 }
64 }
65 ALLOC(in, DOUBLE, alloc_size);
66 if (is_out_of_place)
67 {
68 ALLOC(out, DOUBLE, (out_buffer_size * out_data_stride));
69 }
70
71 /* STEP 1.4: Prepare input for FFT calculation and
72 Use input buffer as output for in-place buffer. */
73 PREPARE_RANDOM_INPUT(in, in_buffer_size, problem.flags.fft_type, DOUBLE);
74 problem.in = in;
75 problem.out = !is_out_of_place ? in : out;
76
77 /* STEP 2: Invoke appropriate setup API to generate solution. */
78 VOID *aoclfftz_handle = aoclfftz_setup_d_64_(&problem);
79
80 /* STEP 3: Invoke execute API. */
81 if (aoclfftz_handle)
82 {
83 printf("\nSetup Successful\n");
84 INT32 res = AOCLFFTZ_SUCCESS;
85 res = aoclfftz_execute(aoclfftz_handle);
86
87 if (res == AOCLFFTZ_EXECUTION_FAILURE)
88 {
89 printf("\nExecution Failure\n");
90 }
91 else
92 {
93 printf("\nExecution successful\n");
94 }
95 }
96 else
97 {
98 printf("\nSetup Failure\n");
99 }
100
101 /* STEP 4: Invoke destroy API to free `aoclfftz_handle`
102 and free the allocated memory. */
103 aoclfftz_destroy(aoclfftz_handle);
104 free(problem.in);
105 if (is_out_of_place)
106 {
107 free(problem.out);
108 }
109}
To build this example test program on a Linux system using GCC or AOCC, you must specify path to aoclfftz.h header file and link with libaocl_fftz.so file as follows:
GCC : gcc -I<aoclfftz.h file directory> -L<libaocl_fftz.so file directory> example_n_dim_real_forward.c -laocl_fftz -lm
Clang : clang -I<aoclfftz.h file directory> -L<libaocl_fftz.so file directory> example_n_dim_real_forward.c -laocl_fftz -lm
Before running the example program, ensure it points to the right library dependencies for OpenMP for Multithreading.