Helpers - 5.2 English - 68552

AOCL API Guide (68552)

Document ID
68552
Release Date
2025-12-29
Version
5.2 English

The following file contains helper routines for AOCL-FFTZ examples, including macros/functions for preparing input data, setting default strides for dimensions and vectors, calculating buffer sizes and handling memory allocation.

  1#ifndef HELPERS_H
  2#define HELPERS_H
  3
  4#include <stdio.h>
  5#include <stdlib.h>
  6#include <string.h>
  7#include "aoclfftz.h"
  8
  9// 1 - for real problems, 2 - for complex problems
 10#define DATA_STRIDE(fft_type) (((fft_type) == 1) ? 1 : 2)
 11#define MAX(a, b) ((a) > (b) ? (a) : (b))
 12
 13#define ALLOC(ptr, type, n_ele)                                                \
 14{                                                                              \
 15    ptr = (type *)malloc(sizeof(type) * n_ele);                                \
 16    if(ptr == NULL)                                                            \
 17    {                                                                          \
 18        printf("\nMemory allocation failed\n");                                \
 19        exit(EXIT_FAILURE);                                                    \
 20    }                                                                          \
 21    else                                                                       \
 22    {                                                                          \
 23        memset(ptr, 0, sizeof(type) * n_ele);                                  \
 24    }                                                                          \
 25}
 26
 27#define PREPARE_RANDOM_INPUT(in, input_size, fft_type, data_type)              \
 28{                                                                              \
 29    UINTP data_stride = DATA_STRIDE(fft_type);                                 \
 30    INTP idx = 0;                                                              \
 31    for (idx = 0; idx < input_size * data_stride; ++idx)                       \
 32    {                                                                          \
 33        in[idx] = (data_type)(20.0 / RAND_MAX) * rand() - 10.0;                \
 34    }                                                                          \
 35}
 36
 37/**
 38 * @brief Set default stride values for dims and vecs.
 39 *
 40 * This function calculates appropriate default stride values for dims and vecs
 41 * The stride calculations vary based on the FFT type and whether the operation
 42 * is in-place or out-of-place.
 43 *
 44 * Stride Calculation Rules:
 45 *
 46 * For dims:
 47 * - dims[0]: Unit stride (1) for both input and output
 48 * - dims[1]: Stride calculations based on FFT type:
 49 *   * consider, n = n, is = in_stride, os = out_stride of dims[0]
 50 *   ------------------|--------------------|--------------------
 51 *    Type             | in_stride          | out_stride
 52 *   ------------------|--------------------|--------------------
 53 *    C2C              | n * is             | n * os
 54 *    R2C out-of-place | n * is             | (n/2 + 1) * os
 55 *    R2C in-place     | (n/2 + 1) * is * 2 | (n/2 + 1) * os     (where is = os)
 56 *    C2R out-of-place | (n/2 + 1) * is     | n * os
 57 *    C2R in-place     | (n/2 + 1) * is     | (n/2 + 1) * os * 2 (where is = os)
 58 *   ------------------|--------------------|--------------------
 59 * - dims[2] or above: dims[i-1].n * dims[i-1].stride
 60 *                     (where stride = in_stride or out_stride)
 61 *
 62 * For vecs:
 63 *
 64 * - vecs[0]: This is same as dims[1] configuration
 65 *            where, n = n, is = in_stride, os = out_stride of dims[dim_rank-1]
 66 * - vecs[1] or above: vecs[i-1].n * vecs[i-1].stride
 67 *                     (where stride = in_stride or out_stride)
 68 *
 69 * @param dim_rank rank of the dimensions
 70 * @param vec_rank rank of the vectors
 71 * @param dims dims structure to set default strides
 72 * @param vecs vecs structure to set default strides
 73 * @param flags fft configuration flags
 74 * @return VOID
 75 */
 76VOID set_default_dims_vecs(aoclfftz_dim_t_64_ *dims, INT32 dim_rank,
 77                           aoclfftz_dim_t_64_ *vecs, INT32 vec_rank,
 78                           aoclfftz_flags_t flags)
 79{
 80    // Set default strides for dims if not explicitly provided
 81    UINT8 is_in_place = !flags.fft_placement;
 82    UINT8 is_backward = flags.fft_direction;
 83    for (INT32 i = 0; i < dim_rank; i++)
 84    {
 85        INTP def_in_stride = 0;
 86        INTP def_out_stride = 0;
 87        if (i == 0)
 88        {
 89            def_in_stride = 1;
 90            def_out_stride = 1;
 91        }
 92        else if (i == 1)
 93        {
 94            if (flags.fft_type == 1 /* Real */)
 95            {
 96                if (!is_backward && is_in_place)
 97                {
 98                    def_in_stride = (dims[0].n / 2 + 1) * dims[0].in_stride * 2;
 99                    def_out_stride = (dims[0].n / 2 + 1) * dims[0].out_stride;
100                }
101                else if (!is_backward && !is_in_place)
102                {
103                    def_in_stride = dims[0].n * dims[0].in_stride;
104                    def_out_stride = (dims[0].n / 2 + 1) * dims[0].out_stride;
105                }
106                else if (is_backward && is_in_place)
107                {
108                    def_in_stride = (dims[0].n / 2 + 1) * dims[0].in_stride;
109                    def_out_stride = (dims[0].n / 2 + 1) * dims[0].out_stride * 2;
110                }
111                else if (is_backward && !is_in_place)
112                {
113                    def_in_stride = (dims[0].n / 2 + 1) * dims[0].in_stride;
114                    def_out_stride = dims[0].n * dims[0].out_stride;
115                }
116            }
117            else /* Complex */
118            {
119                def_in_stride = dims[0].n * dims[0].in_stride;
120                def_out_stride = dims[0].n * dims[0].out_stride;
121            }
122        }
123        else /* i > 1 */
124        {
125            def_in_stride = dims[i - 1].n * dims[i - 1].in_stride;
126            def_out_stride = dims[i - 1].n * dims[i - 1].out_stride;
127        }
128        if (dims[i].in_stride == 0)
129        {
130            /* in stride for dims[i] is set to default value */
131            dims[i].in_stride = def_in_stride;
132        }
133        if (dims[i].out_stride == 0)
134        {
135            /* out stride for dim[i] is set to default value */
136            dims[i].out_stride = def_out_stride;
137        }
138    }
139
140    // set strides for vecs if not provided
141    for (INT32 i = 0; i < vec_rank; i++)
142    {
143        INTP def_in_stride = 0;
144        INTP def_out_stride = 0;
145        if (i == 0)
146        {
147            aoclfftz_dim_t_64_ last_dim = dims[dim_rank - 1];
148            if (flags.fft_type == 1 /* Real */)
149            {
150                if (!is_backward && is_in_place)
151                {
152                    def_in_stride = (last_dim.n / 2 + 1) * last_dim.in_stride * 2;
153                    def_out_stride = (last_dim.n / 2 + 1) * last_dim.out_stride;
154                }
155                else if (!is_backward && !is_in_place)
156                {
157                    def_in_stride = last_dim.n * last_dim.in_stride;
158                    def_out_stride = (last_dim.n / 2 + 1) * last_dim.out_stride;
159                }
160                else if (is_backward && is_in_place)
161                {
162                    def_in_stride = (last_dim.n / 2 + 1) * last_dim.in_stride;
163                    def_out_stride = (last_dim.n / 2 + 1) * last_dim.out_stride * 2;
164                }
165                else if (is_backward && !is_in_place)
166                {
167                    def_in_stride = (last_dim.n / 2 + 1) * last_dim.in_stride;
168                    def_out_stride = last_dim.n * last_dim.out_stride;
169                }
170            }
171            else /* Complex */
172            {
173                def_in_stride = last_dim.n * last_dim.in_stride;
174                def_out_stride = last_dim.n * last_dim.out_stride;
175            }
176        }
177        else /* i > 0 */
178        {
179            def_in_stride = vecs[i - 1].n * vecs[i - 1].in_stride;
180            def_out_stride = vecs[i - 1].n * vecs[i - 1].out_stride;
181        }
182        if (vecs[i].in_stride == 0)
183        {
184            /* in stride for vec[i] is set to default value */
185            vecs[i].in_stride = def_in_stride;
186        }
187        if (vecs[i].out_stride == 0)
188        {
189            /* out stride for vec[i] is set to default value */
190            vecs[i].out_stride = def_out_stride;
191        }
192    }
193}
194
195/**
196 * @brief calculate the buffer sizes for input and output
197 *
198 * @param dims dims structure to set default strides
199 * @param dim_rank rank of the dimensions
200 * @param vecs vecs structure to set default strides
201 * @param vec_rank rank of the vectors
202 * @param in_buffer_size calculated size of input
203 * @param out_buffer_size calculated size of output
204 * @return VOID
205 */
206VOID calculate_buffer_sizes(aoclfftz_dim_t_64_ *dims, INT32 dim_rank,
207                            aoclfftz_dim_t_64_ *vecs, INT32 vec_rank,
208                            UINTP *in_buffer_size, UINTP *out_buffer_size)
209{
210    // Example: for an 1D problem with 1D batch
211    // Problem size : 3:6:6v4:1:1
212    // Data arrangement considered :
213    // [1, 2, 3, 4]<0, 0>[5, 6, 7, 8]<0, 0>[9, 10, 11, 12]
214    // <---vec stride--->
215    // <-------------(Batches -1)---------><--- Problem size * dim_stride --->
216    // ((Batches -1) * (vec_stride)) + (Problem size * dim stride)
217    UINTP in_size = 1;
218    UINTP out_size = 1;
219    for (INT32 i = 0; i < dim_rank; i++)
220    {
221        in_size += ((dims[i].n - 1) * (dims[i].in_stride));
222        out_size += ((dims[i].n - 1) * (dims[i].out_stride));
223    }
224    for (INT32 i = 0; i < vec_rank; i++)
225    {
226        in_size += ((vecs[i].n - 1) * (vecs[i].in_stride));
227        out_size += ((vecs[i].n - 1) * (vecs[i].out_stride));
228    }
229    *in_buffer_size = in_size;
230    *out_buffer_size = out_size;
231}
232
233#endif // HELPERS_H