5 Replies Latest reply on Dec 2, 2013 1:30 PM by kknox

    2DFFTs

    jimmyajones

      Basic Question: Does anyone have an example of the setup and call of any of the 2DFFT (or 3D for that matter) function calls from C?

       

      I'm in the middle of transforming a FORTRAN coded program using the ACML library to C++ and I'm stuck on the 2D application within the C++ environment.  Any quick examples of a call would be much appreciated.

        • Re: 2DFFTs
          kknox

          Are you familiar with the FFTW interfaces?  You can find plenty of examples of using that interface online and it's a native C API.

           

          ACML 5.3.1 ships with wrapper headers that provide the API of FFTW, but call into ACML underneath to do all the work. You can find these header files in ...\gfortran64_mp\examples\FFTW_wrappers\FFTW3 or the equivalent path for your distribution.

           

          Kent

            • Re: 2DFFTs
              jimmyajones

              The lack of C examples for the 2D or 3D FFT implementation are why I'm asking.  There are plenty of 1D examples for the C header files but nothing for the 2D or 3D cases.  ACML uses complex (a typedef with a little c) for it's implementation of complex numbers while the standard library uses Complex (a class with a capitol C).  I think all of the FFT C wrappers use a pointer to a complex array.  Some of the other ACML C examples use a macro and state "This macro allows access to a 1-d array as though it is a 2-d array stored in column-major order, as required by ACML C routines."


              I'm far from being a C++ guru and just looking for a quick example of the proper use of C on a complex 2D array so I can convert my Complex arrays to complex arrays the wrappers can use.  I haven't come across any of the 2D examples on-line yet.


              The actual program is a C++ version of a FORTRAN program that I use for an E-M model.  I'm modifying this C++ version that previously used IMSL.  IMSL is only good if you spend the money for the license (as I'm sure you're more than aware of).  If I get this ACML code to work properly I can maintain an open program in addition to eventually taking advantage of my AMD processors (CPU and GPUs) to gain significant speed.

                • Re: Re: 2DFFTs
                  kknox

                  You are right, i can't find many c examples of the 2d FFT interfaces.  However, i did find helpful snippets of code inside of the ACML FFT documentation (.pdf inside of /Doc directory), specifically section 5.2.3.  The documentation for each routine has a small example of using that call, for instance:


                  C Forward 2D FFT is performed unscaled, without final transpose

                  C and out-of-place on data stored in array X and output to Y.

                  C Manipulations are stored in vector Y which is then transformed

                  C back, with scaling, into the first M rows of X.

                  C

                   

                  COMPLEX X(M,N), Y(N,M)

                  SCALE = 1.0

                  INPL = .FALSE.

                  LTRANS = .FALSE.

                  CALL CFFT2DX(0,SCALE,LTRANS,INPL,M,N,X,1,M,Y,1,N,COMM,INFO)

                  CALL CFFT2DX(-1,SCALE,LTRANS,INPL,M,N,X,1,M,Y,1,N,COMM,INFO)

                  DO 20 I = M

                    DO 10 J = 1, N

                      Y(J,I) = 0.5*Y(J,I)*EXP(-0.001*REAL(I+J-2))

                      IY = IY + 1

                    10 CONTINUE

                  20 CONTINUE

                  SCALE = 1.0/REAL(M*N)

                  CALL CFFT2DX(1,SCALE,LTRANS,INPL,N,M,Y,1,N,X,1,M,COMM,INFO)

                    • Re: Re: Re: 2DFFTs
                      jimmyajones

                      Let me update my question.  The below ACML CFFT2D code works in C++.  I defined the the complex array, A, as a 1D 65,536 element array and used a macro to treat it like a 2D array.  However the structure for 'complex' which is 'float real, imag;' will not let me resize the array dynamically using malloc that I commented out below.  Is there a way to dynamically resize ACML's complex array?

                       

                      #define a(i,j) A[jj*nx+ii]

                        int ii=0, jj=0;

                        double h, k;

                        complex A[256 * 256];

                       

                        //complex *A;

                        //A = (complex *) malloc((nx*ny)*sizeof(complex));

                       

                        /*I deleted the loop that filled in matrix A here.  It's not important for the question*/

                       

                        comm = (complex *)malloc((nx*ny+5*(nx*ny))*sizeof(complex));

                        cfft2d(-1,nx,ny,A,comm,&info);

                        • Re: Re: Re: Re: 2DFFTs
                          kknox

                          Hi jimmyajones~

                           

                          You can not write code that redefines a symbol within the same scope; this is an error (in this case, you are implying that A is both an array of complex structs and a complex pointer).

                           

                          1>redefinition.cpp(18): error C2372: 'A' : redefinition; different types of indirection

                          1>          redefinition.cpp(13) : see declaration of 'A'

                          1>redefinition.cpp(19): error C2440: '=' : cannot convert from 'complex *' to 'complex [65536]'

                          1>          There are no conversions to array types, although there are conversions to references or pointers to arrays


                          In your example code, delete the

                          complex A[256 * 256];

                          line to remove the previous definition.  Then the complex* A is the sole declaration and memory allocation with the malloc() call succeeds.  Resizing the array involves first free()'ing the previous memory instantiation and then calling malloc() again with the new size.


                          If you are able to use C++ types, you might want to play with std::vector<complex>, as vectors natively supports resizing operations.


                          Kent