我要评分
获取效率
正确性
完整性
易理解

Migration Procedure

Migrating the Library That Uses the C Language

  • Example: C2C transform
    Before the migration:
    #include "mkl_cdft.h"
    #include "mkl_cdft_types.h"
    
        DFTI_DESCRIPTOR_HANDLE desc_handle = NULL;
        MKL_LONG rank = 2;
        MKL_LONG length[2] = {2, 3};
        MKL_LONG istrides[3] = {0, 3, 1};
        MKL_LONG ostrides[3] = {0, 3, 1};
        MKL_LONG nthreads = 1;
        MKL_LONG howmany = 2;
        MKL_LONG idistance = 2 * 3;
        MKL_LONG odistance = 2 * 3;
        double init[12][2] = {{120, 0}, {8, 8}, {0, 0}, {0, 16}, {0, 16}, {-8, 8}, {-8, 0}, {-8, 8}, {-16, 0}, {0, -16}, {-40, 8}, {-8, -8}};
        double *ri;
        ri = (double*)malloc(sizeof(double) * 12);
        double *ii;
        ii = (double*)malloc(sizeof(double) * 12);
        for (int i = 0; i < 12; i++) {
            ri[i] = init[i][0];
            ii[i] = init[i][1];
        }
    
        MKL_LONG s = DftiCreateDescriptor(&desc_handle, DFTI_DOUBLE, DFTI_COMPLEX, rank, length);
        s = DftiSetValue(desc_handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
        s = DftiSetValue(desc_handle, DFTI_INPUT_STRIDES, istrides);
        s = DftiSetValue(desc_handle, DFTI_OUTPUT_STRIDES, ostrides);
        s = DftiSetValue(desc_handle, DFTI_THREAD_LIMIT, nthreads);
        s = DftiSetValue(desc_handle, DFTI_COMPLEX_STORAGE, DFTI_REAL_REAL);
        s = DftiSetValue(desc_handle, DFTI_NUMBER_OF_TRANSFORMS, howmany);
        s = DftiSetValue(desc_handle, DFTI_INPUT_DISTANCE, idistance);
        s = DftiSetValue(desc_handle, DFTI_OUTPUT_DISTANCE, odistance);
        s = DftiCommitDescriptor(desc_handle);
        double *ro;
        ro = (double*)malloc(sizeof(double) * 12);
        double *io;
        io = (double*)malloc(sizeof(double) * 12);
        DftiComputeForward(desc_handle, ri, ii, ro, io);
        DftiFreeDescriptor(&desc_handle);
        free(ri);
        free(ii);
        free(ro);
        free(io);
    After the migration:
    #include "kfft.h"
    
        int rank = 2; 
        kml_fft_iodim64 *dims; 
        dims = (kml_fft_iodim64*)kml_fft_malloc(sizeof(kml_fft_iodim64) * rank); 
        dims[0].n = 2; 
        dims[0].is = 3; 
        dims[0].os = 3; 
        dims[1].n = 3; 
        dims[1].is = 1; 
        dims[1].os = 1; 
        int howmany_rank = 1; 
        kml_fft_iodim64 *howmany_dims; 
        howmany_dims = (kml_fft_iodim64*)kml_fft_malloc(sizeof(kml_fft_iodim64) * howmany_rank); 
        howmany_dims[0].n = 2; 
        howmany_dims[0].is = 2 * 3; 
        howmany_dims[0].os = 2 * 3; 
        double init[12][2] = {{120, 0}, {8, 8}, {0, 0}, {0, 16}, {0, 16}, {-8, 8}, {-8, 0}, {-8, 8}, {-16, 0}, {0, -16}, {-40, 8}, {-8, -8}}; 
        double *ri; 
        ri = (double*)kml_fft_malloc(sizeof(double) * 12); 
        double *ii; 
        ii = (double*)kml_fft_malloc(sizeof(double) * 12); 
        for (int i = 0; i < 12; i++) { 
            ri[i] = init[i][0]; 
            ii[i] = init[i][1]; 
        } 
        double *ro; 
        ro = (double*)kml_fft_malloc(sizeof(double) * 12); 
        double *io; 
        io = (double*)kml_fft_malloc(sizeof(double) * 12); 
        kml_fft_plan plan; 
        plan = kml_fft_plan_guru64_split_dft(rank, dims, howmany_rank, howmany_dims, ri, ii, ro, io, KML_FFT_ESTIMATE); 
        kml_fft_execute_split_dft(plan, ri, ii, ro, io); 
     
        kml_fft_destroy_plan(plan); 
        kml_fft_free(howmany_dims); 
        kml_fft_free(dims); 
        kml_fft_free(ri); 
        kml_fft_free(ii); 
        kml_fft_free(ro); 
        kml_fft_free(io); 
     
        /* 
         * ro = {1.200000e+02, 1.338564e+02, 1.061436e+02, 1.360000e+02, 
         *       1.120000e+02, 1.120000e+02, -8.000000e+01, 4.878461e+01, 
         *       7.215390e+00, 1.600000e+01, -2.692820e+01, -1.307180e+01} 
         */ 
     
        /* 
         * io = {4.800000e+01, -1.385641e+01, 1.385641e+01, -3.200000e+01, 
         *       -8.000000e+00, -8.000000e+00, -8.000000e+00, 7.846097e-01, 
         *       -4.078461e+01, 2.400000e+01, -2.264102e+01, 4.664102e+01} 
         */
  • Example: R2C transform
    Before the migration:
    #include "mkl_cdft.h"
    #include "mkl_cdft_types.h"
    
        DFTI_DESCRIPTOR_HANDLE desc_handle = NULL;
        MKL_LONG rank = 2;
        MKL_LONG length[2] = {2, 3};
        MKL_LONG istrides[3] = {0, 3, 1};
        MKL_LONG ostrides[3] = {0, 2, 1};
        MKL_LONG nthreads = 1;
        MKL_LONG howmany = 2;
        MKL_LONG idistance = 2 * 3;
        MKL_LONG odistance = 2 * 2;
        double init[12] = {120, 8, 0, 0, 0, -8, -8, -8, -16, 0, -40, -8};
        double *in;
        in = (double*)malloc(sizeof(double) * 12);
        for (int i = 0; i < 12; i++) {
            in[i] = init[i];
        }
    
        MKL_LONG s = DftiCreateDescriptor(&desc_handle, DFTI_DOUBLE, DFTI_REAL, rank, length);
        s = DftiSetValue(desc_handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
        s = DftiSetValue(desc_handle, DFTI_INPUT_STRIDES, istrides);
        s = DftiSetValue(desc_handle, DFTI_OUTPUT_STRIDES, ostrides);
        s = DftiSetValue(desc_handle, DFTI_THREAD_LIMIT, nthreads);
        s = DftiSetValue(desc_handle, DFTI_COMPLEX_STORAGE, DFTI_COMPLEX_COMPLEX);
        s = DftiSetValue(desc_handle, DFTI_NUMBER_OF_TRANSFORMS, howmany);
        s = DftiSetValue(desc_handle, DFTI_INPUT_DISTANCE, idistance);
        s = DftiSetValue(desc_handle, DFTI_OUTPUT_DISTANCE, odistance);
        s = DftiSetValue(desc_handle, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
        s = DftiCommitDescriptor(desc_handle);
    
        MKL_Complex16 *out;
        out = (MKL_Complex16*)malloc(sizeof(MKL_Complex16) * 2 * 2 * howmany);
        DftiComputeForward(desc_handle, in, out);
        DftiFreeDescriptor(&desc_handle);
        free(in);
        free(out);
    After the migration:
    #include "kfft.h"
    
        int rank = 2; 
        kml_fft_iodim64 *dims; 
        dims = (kml_fft_iodim64*)kml_fft_malloc(sizeof(kml_fft_iodim64) * rank); 
        dims[0].n = 2; 
        dims[0].is = 3; 
        dims[0].os = 2; 
        dims[1].n = 3; 
        dims[1].is = 1; 
        dims[1].os = 1; 
        int howmany_rank = 1; 
        kml_fft_iodim64 *howmany_dims; 
        howmany_dims = (kml_fft_iodim64*)kml_fft_malloc(sizeof(kml_fft_iodim64) * howmany_rank); 
        howmany_dims[0].n = 2; 
        howmany_dims[0].is = 2 * 3; 
        howmany_dims[0].os = 2 * 2; 
        double init[12] = {120, 8, 0, 0, 0, -8, -8, -8, -16, 0, -40, -8}; 
        double *in; 
        in = (double*)kml_fft_malloc(sizeof(double) * 12); 
        for (int i = 0; i < 12; i++) { 
            in[i] = init[i]; 
        } 
        kml_fft_complex *out; 
        out = (kml_fft_complex*)kml_fft_malloc(sizeof(kml_fft_complex) * 8); 
        kml_fft_plan plan; 
        plan = kml_fft_plan_guru64_dft_r2c(rank, dims, howmany_rank, howmany_dims, in, out, KML_FFT_ESTIMATE); 
        kml_fft_execute_dft_r2c(plan, in, out); 
     
        kml_fft_destroy_plan(plan); 
        kml_fft_free(howmany_dims); 
        kml_fft_free(dims); 
        kml_fft_free(in); 
        kml_fft_free(out); 
     
        /* 
         * out = {{1.200000e+02, 0.000000e+00}, {1.200000e+02, -1.385641e+01}, 
         *        {1.360000e+02, 0.000000e+00}, {1.120000e+02, 0.000000e+00}, 
         *        {-8.000000e+01, 0.000000e+00}, {2.800000e+01, 2.078461e+01}, 
         *        {1.600000e+01, 0.000000e+00}, {-2.000000e+01, -3.464102e+01}} 
         */
  • Example: C2R transform
    Before the migration:
    #include "mkl_cdft.h"
    #include "mkl_cdft_types.h"
    
        DFTI_DESCRIPTOR_HANDLE desc_handle = NULL;
        MKL_LONG rank = 2;
        MKL_LONG length[2] = {2, 3};
        MKL_LONG istrides[3] = {0, 2, 1};
        MKL_LONG ostrides[3] = {0, 3, 1};
        MKL_LONG nthreads = 1;
        MKL_LONG howmany = 2;
        MKL_LONG idistance = 2 * 2;
        MKL_LONG odistance = 2 * 3;
        double init[8][2] = {{120, 0}, {8, 8}, {0, 0}, {0, 16}, {0, 16}, {-8, 8}, {-8, 0}, {-8, 8}}; 
        MKL_Complex16 *in; 
        in = (MKL_Complex16*)malloc(sizeof(MKL_Complex16) * 8); 
        for (int i = 0; i < 8; i++) { 
            in[i].real = init[i][0]; 
            in[i].imag = init[i][1];
        } 
    
        MKL_LONG s = DftiCreateDescriptor(&desc_handle, DFTI_DOUBLE, DFTI_REAL, rank, length);
        s = DftiSetValue(desc_handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE);
        s = DftiSetValue(desc_handle, DFTI_INPUT_STRIDES, istrides);
        s = DftiSetValue(desc_handle, DFTI_OUTPUT_STRIDES, ostrides);
        s = DftiSetValue(desc_handle, DFTI_THREAD_LIMIT, nthreads);
        s = DftiSetValue(desc_handle, DFTI_COMPLEX_STORAGE, DFTI_COMPLEX_COMPLEX);
        s = DftiSetValue(desc_handle, DFTI_NUMBER_OF_TRANSFORMS, howmany);
        s = DftiSetValue(desc_handle, DFTI_INPUT_DISTANCE, idistance);
        s = DftiSetValue(desc_handle, DFTI_OUTPUT_DISTANCE, odistance);
        s = DftiSetValue(desc_handle, DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
        s = DftiCommitDescriptor(desc_handle);
    
        double *out; 
        out = (double*)malloc(sizeof(double) * 12);
        DftiComputeBackward(desc_handle, in, out);
        DftiFreeDescriptor(&desc_handle);
        free(in);
        free(out);
    After the migration:
    #include "kfft.h"
    
        int rank = 2; 
        kml_fft_iodim64 *dims; 
        dims = (kml_fft_iodim64*)kml_fft_malloc(sizeof(kml_fft_iodim64) * rank); 
        dims[0].n = 2; 
        dims[0].is = 2; 
        dims[0].os = 3; 
        dims[1].n = 3; 
        dims[1].is = 1; 
        dims[1].os = 1; 
        int howmany_rank = 1; 
        kml_fft_iodim64 *howmany_dims; 
        howmany_dims = (kml_fft_iodim64*)kml_fft_malloc(sizeof(kml_fft_iodim64) * howmany_rank); 
        howmany_dims[0].n = 2; 
        howmany_dims[0].is = 2 * 2; 
        howmany_dims[0].os = 2 * 3; 
        double init[8][2] = {{120, 0}, {8, 8}, {0, 0}, {0, 16}, {0, 16}, {-8, 8}, {-8, 0}, {-8, 8}}; 
        kml_fft_complex *in; 
        in = (kml_fft_complex*)kml_fft_malloc(sizeof(kml_fft_complex) * 8); 
        for (int i = 0; i < 8; i++) { 
            in[i].r = init[i][0]; 
            in[i].i = init[i][1]; 
        }
        double *out; 
        out = (double*)kml_fft_malloc(sizeof(double) * 12); 
        kml_fft_plan plan; 
        plan = kml_fft_plan_guru64_dft_c2r(rank, dims, howmany_rank, howmany_dims, in, out, KML_FFT_ESTIMATE); 
        kml_fft_execute_dft_c2r(plan, in, out); 
     
        kml_fft_destroy_plan(plan); 
        kml_fft_free(howmany_dims); 
        kml_fft_free(dims); 
        kml_fft_free(in); 
        kml_fft_free(out); 
     
        /* 
         * out = {1.360000e+02, 7.043078e+01, 1.535692e+02, 1.360000e+02, 
         *        1.258564e+02, 9.814359e+01, -4.000000e+01, -1.971281e+01, 
         *        3.571281e+01, 8.000000e+00, 8.000000e+00, 8.000000e+00} 
         */

    Due to the software architecture, different plans are required for calculating different types of Fourier transforms for multiple times in the service code. Similar to MKL, a plan constructed based on the same type of transform can be used for multiple times.

Migrating the Library That Uses the Fortran Interface

The procedure of migrating the library that uses the Fortran interface is the same as that in Migrating the Library That Uses the C Language.