Fortran Coder

查看: 2283|回复: 4
打印 上一主题 下一主题

[数学库] MKL_DFTI, MODULE, INCLUDE

[复制链接]

4

帖子

2

主题

0

精华

入门

F 币
42 元
贡献
19 点
跳转到指定楼层
楼主
发表于 2023-6-5 15:59:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 Novice 于 2023-6-5 16:13 编辑

mkl_dft在fortran中的模块调用
使用原帖中的代码:
[Fortran] 纯文本查看 复制代码
Module MKL_FFT !// 以下代码复制粘贴,直接使用
  Use MKL_DFTI
  private
  Type , public :: CLS_FFT
    type(DFTI_DESCRIPTOR), Pointer :: h => NULL()
    Integer :: Err
  contains
    Procedure :: Create
    Procedure :: Forward
    Procedure :: Backward
    Procedure :: Destory
  End Type CLS_FFT

contains

  Subroutine Create( this , N )
    class( CLS_FFT ) :: this
    Integer , Intent( IN ) :: N
    this%Err = DftiCreateDescriptor( this%h , DFTI_SINGLE , DFTI_REAL , 1 , N )
    this%Err = DftiSetValue( this%h , DFTI_PLACEMENT , DFTI_NOT_INPLACE )
    this%Err = DftiCommitDescriptor( this%h )
  End Subroutine Create

  Function Forward( this , X ) result( F )
    class( CLS_FFT ) :: this
    Real :: X(:)
    Complex :: F( size(X)/2+1 )
    this%Err = DftiComputeForward( this%h , X , F )
  End Function Forward

  Function Backward( this , X ) result( T )
    class( CLS_FFT ) :: this
    Complex :: X(:)
    Real    :: T( size(X)*2-1 )
    this%Err = DftiComputeBackward( this%h , X , T )
  End Function Backward

  Subroutine Destory( this )
    class( CLS_FFT ) :: this
    this%Err = DftiFreeDescriptor( this%h )
  End Subroutine Destory

End Module MKL_FFT
!// 以上代码复制粘贴,直接使用

Program Test_FFT
  use MKL_FFT   !// 这句代码必须 *************
  Type( CLS_FFT ) :: FFT !// 这句定义一个 FFT 的过程 ************
  Integer , parameter :: N = 30 !//不需要2^k 次方整幂
  Real     :: r(N) = & !// 时间域
    [3,2,4,6,2,5,7,8,5,3,7,8,4,2,4,7,8,9,3,2,5,7,8,4,2,5,8,9,4,6]
  Complex  :: f(N/2+1) !// 频率域,为复数,大小为 n/2 + 1

  call FFT%Create( N ) !// 创建FFT过程。N 是 FFT 的点数 ************
  f  = FFT%Forward( r )  !// 正向 FFT 变换  *************
  Do i = 1 , size(f)
    Write( * , * ) i , f( i ) !// 输出频率域
  End Do
  r = FFT%Backward( f ) / n !// 这一句可以做反傅氏变换 *************
  call FFT%Destory() !// 销毁 FFT 过程*************
  Do i = 1 , size(r)
    Write( * , * ) i , r(i) !// 输出反变换
  End Do
  Read(*,*)
End Program Test_FFT

编译环境:Ubuntu22.04 + ifort (OneAPI)
编译命令:
ifort -o MKL_FFT MKL_FFT.f90 -L${MKLROOT}/lib/intel64 -I${MKLROOT}/include -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm

无法编译,报错为
MKL_FFT.f90(3): error #7002: Error in opening the compiled module file.  Check INCLUDE paths.   [MKL_DFTI]

  Use MKL_DFTI

- 第一个问题:这个错误为编译命令中未先生成mkl相关的Mod吗?
- 第二个问题:在声明使用MKL_DFTI mod之前,参考troubleshot_mkl_fortran加入include如下:
[Fortran] 纯文本查看 复制代码
Module MKL_FFT !// 以下代码复制粘贴,直接使用
  INCLUDE 'mkl_dfti.f90'
  Use MKL_DFTI

编译报错为:
/opt/intel/oneapi/mkl/2023.1.0/include/mkl_dfti.f90(20): error #6218: This statement is positioned incorrectly and/or has syntax errors.
MODULE MKL_DFT_TYPE

但将include置于MOD声明之前,如下:
[Fortran] 纯文本查看 复制代码
INCLUDE 'mkl_dfti.f90'
Module MKL_FFT !// 以下代码复制粘贴,直接使用
  Use MKL_DFTI

则编译正常,这个问题是因为include为预处理命令,得在编译前先加入才能在编译mod时使用吗?还是有其他的原因导致此处include的位置对编译成败有影响?先向前辈们致谢!

分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

2015

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1572 元
贡献
676 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

沙发
发表于 2023-6-5 19:09:35 | 只看该作者
我一般是单独编译 mkl_dfti.f90 文件。

它是一些独立的module,你可以打开这个文件自行查看:
通常内含两个module,即:
MODULE MKL_DFT_TYPE
MODULE MKL_DFTI


Fortran 不允许在一个module中直接包含另一个module,所以你不能把include语句放在
Module MKL_FFT 里面,因为这样的话 Module MKL_FFT 就包含了 MODULE MKL_DFT_TYPE 和 MODULE MKL_DFTI
放在mod语句前面可以避免这个问题。但是 include 的写法,只适合于“你的整个工程,只有 MKL_FFT 这个模块需要 MKL_DFTI

更好的方法,是单独编译 mkl_dfti.f90,得到 MKL_DFT_TYPE.mod 和 MODULE MKL_DFTI.mod
然后再编译 Module MKL_FFT
这样无需写 include,并且可以解决多个源代码文件中都需要使用 MKL_DFT_TYPE 和 MKL_DFTI 的问题。
如果你在多个源代码文件中,例如在 MKL_FFT MKL_FFT_ABC 中,都写了 INCLUDE 'mkl_dfti.f90',就会产生冲突。

4

帖子

2

主题

0

精华

入门

F 币
42 元
贡献
19 点
板凳
 楼主| 发表于 2023-6-6 10:04:49 | 只看该作者
fcode 发表于 2023-6-5 19:09
我一般是单独编译 mkl_dfti.f90 文件。

它是一些独立的module,你可以打开这个文件自行查看:

多谢前辈回复,所以应该避免将多次使用的外部module直接放在代码中,而应该先编译这些mod再编译主要的源代码,所以这个命令一般只适合单一模块需要外部module :
ifort -o MKL_FFT MKL_FFT.f90 -L${MKLROOT}/lib/intel64 -I${MKLROOT}/include -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -liomp5 -lpthread -lm
,一般还是得把外部文件例如mkl_dfti.f90和源代码放在一起编译

2015

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1572 元
贡献
676 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

地板
发表于 2023-6-7 08:19:41 | 只看该作者
通常来说,1个module,1个源代码文件。

少数情况下,2-3个强烈相关联的module可以放同一个源代码文件。
比如 mkl_dfti.f90 中有2个module,MODULE MKL_DFT_TYPE 和 MODULE MKL_DFTI。但它们几乎不分开使用,所以放一起没什么问题。

2

帖子

0

主题

0

精华

新人

F 币
11 元
贡献
3 点
5#
发表于 2023-6-8 00:18:12 | 只看该作者
我想实现二维快速傅里叶变换,不知道怎么编写程序,希望有大佬能指导指导
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-11-5 05:12

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表