当前位置:   article > 正文

基于oneMKL和开源FFTW3对于二维实数到复数的FFT进行加速与优化

onemkl和开源fftw3对于

1、题目描述
 

本次比赛为命题形式,题目要求如下:

(1)、使用oneMKl工具生成2048*2048随机单精度实数;

(2)、根据产生的随机数据作为输入,实现两维 Real to complex FFT 参考代码;

(3)、根据产生的随机数据作为输入, 调用 oneMKL API 计算两维 Real to complex FFT;

(4)、 结果正确性验证;

(5)、平均性能数据比对;

oneMKL介绍

oneMKL是英特尔(Intel)为加速数学库开发的一个跨平台的程序库。它是英特尔数学核心函数库(Intel Math Kernel Library,简称MKL)的一部分。oneMKL旨在提供高效的数学函数和算法,以帮助开发者在各种硬件架构上实现更高的性能。

oneMKL涵盖了多个数学领域,包括线性代数、傅里叶变换、随机数生成等。它提供了丰富的函数接口,方便开发者在应用程序中使用这些数学函数,从而加速计算过程。oneMKL支持多种编程语言,如C/C++、Fortran和Python,可以在各种操作系统和硬件平台上使用。

通过使用oneMKL,开发者可以充分利用英特尔处理器的优势,如向量化指令集和多核并行处理能力,从而提高应用程序的性能和效率。它可以在科学计算、机器学习、深度学习等领域中发挥重要作用,帮助开发者快速实现高性能的数值计算任务。

总之,oneMKL是一个用于加速数学库的跨平台程序库,它为开发者提供了高效的数学函数和算法,以帮助他们在各种硬件平台上实现更高的性能和效率。


产生随机数和FFTW方案

  1. //Random
  2. VSLStreamStatePtr stream;
  3. vslNewStream(&stream,VSL_BRNG_MT19937,1);
  4. vsRngUniform(VSL_RNG_METHOD_UNIFORM_STD,stream,N*N,array_in,0.0f,1.0f);
  5. //FFTW
  6. fftwf_complex *fftw_out=(fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex)*N*(N/2+1));
  7. fftwf_plan status_fftwf=fftwf_plan_dft_r2c_2d(N,N,array_in,fftw_out,FFTW_MEASURE);
  8. clock_t t0=clock();
  9. fftwf_execute(status_fftwf);
  10. clock_t t1=clock();
  11. double time_taken=((double)(t1-t0)/CLOCKS_PER_SEC);
  12. fprintf(stderr,"1 times FFT (FFTW3) time taken is %f s\n",time_taken);

oneMKL

  1. MKL_LONG rs[3]={0,N,1};
  2. MKL_LONG cs[3]={0,N/2+1,1};
  3. MKL_Complex8 *mkl_out=(MKL_Complex8 *)malloc(sizeof(MKL_Complex8)*N*(N/2+1));
  4. DFTI_DESCRIPTOR_HANDLE descriptor;
  5. MKL_LONG sizeN[2]={N,N};
  6. DftiCreateDescriptor(&descriptor,DFTI_SINGLE,DFTI_REAL,2,sizeN);
  7. DftiSetValue(descriptor,DFTI_PLACEMENT,DFTI_NOT_INPLACE);
  8. DftiSetValue(descriptor,DFTI_CONJUGATE_EVEN_STORAGE,DFTI_COMPLEX_COMPLEX);
  9. DftiSetValue(descriptor,DFTI_INPUT_STRIDES,rs);
  10. DftiSetValue(descriptor,DFTI_OUTPUT_STRIDES,cs);
  11. DftiCommitDescriptor(descriptor);
  12. clock_t t2=clock();
  13. DftiComputeForward(descriptor,array_in,mkl_out);
  14. clock_t t3=clock();
  15. double time_taken1=((double)(t3-t2)/CLOCKS_PER_SEC);
  16. fprintf(stderr,"1 times FFT (MKL ) time taken is %f s\n",time_taken1);

oneMKL和FFTW3做比较

  1. //Compare
  2. float EPS=0.00001;//1e-5
  3. float residual_r=0;
  4. float residual_i=0;
  5. int result=0;
  6. for(int i=0;i<(N/2+1)*N;i++)
  7. {
  8. residual_r=(float)fabs(mkl_out[i].real-fftw_out[i][0]);
  9. residual_i=(float)fabs(mkl_out[i].imag-fftw_out[i][1]);
  10. if(residual_r>EPS || residual_i>EPS) result=1;
  11. }
  12. if(result==0) fprintf(stderr,"The result was correct(^ ^)\n");
  13. else fprintf(stderr,"The result was wrong(* *)\n");

结果

  1. 1 times FFT (FFTW3) time taken is 0.015783 s
  2. 1 times FFT (MKL ) time taken is 0.017072 s
  3. 1000 times Avarage FFT (FFTW3) time taken is 0.012243 s
  4. 1000 times Avarage FFT (MKL ) time taken is 0.013808 s
  5. The result was correct(^ ^)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/105035?site
推荐阅读
相关标签
  

闽ICP备14008679号