fortran66のブログ

fortran について書きます。

Intel Fortran Compiler 16.0 での新機能

Intel Fortran Compiler 16.0 の New Language Features を見てみると、幾つか興味深い機能が新たに実装されています。

Fortran2008 の機能からは submodule が利用可能になっています。

Fortran2015 (Draft) の機能からは、assumed-rank 型の引数が利用可能になっています。

submodule

submodule は module 機能の拡張で、インターフェース部と実装部を別モジュールに完全に分離することが可能になります。これによりカスケード的なリコンパイルを回避できるようになります。実装部の隠ぺいも容易になります。

利用例 (参照: Modern Fortran Explained 18.2.1)

ソースプログラム

実装部ではインターフェースに当たるものを完全に省略できます。(明示的に書いてもいいです。)

    module m_points
      implicit none
      type :: t_point
        real :: x, y  
      end type t_point    
      interface
        real module function point_dist(a, b)
          type(t_point), intent(in) :: a, b
        end function point_dist  
      end interface
    end module m_points
    
    submodule (m_points) points_a
      implicit none
    contains
      module procedure point_dist
        point_dist = sqrt((a%x - b%x)**2 + (a%y - b%y)**2)
      end procedure point_dist
    end submodule points_a



    program SubModuleTest
      use m_points
      implicit none
      type(t_point) :: a, b
      a = t_point(0.0, 0.0)
      b = t_point(1.0, 1.0)
      print *, point_dist(a, b)
    end program SubModuleTest
実行例

1.414214
続行するには何かキーを押してください . . .

assumed-rank 引数

Fortran ではユーザー定義副プログラムでは配列のランク(次元)が可変な引数を取ることができませんでした。

これに類する機能として Fortran90 の 総称名を用いて各次元ごとに副プログラムを書いてそれを束ねるものと、Fortran95 の ELEMENTAL 型の副プログラムでスカラーに対して定義した内容を MAP 的に作用させるものしうかありませんでした。

Fortran2015 (これはまだドラフトの段階で、正式の規格としては通っていませんが)では、C言語との相互運用の関係で、配列のランクも可変とした引数を副プログラムでとれるようになる予定です。

ソースプログラム

assumed-rank 引数は a(..) の形であらわします。これは assumed-size の a(:) の類比による記法だと思います。

    module m_test
      implicit none
    contains  
      subroutine sub(a)
        real, intent(in) :: a(..) ! assumed rank argument
        print *, shape(a)
      end subroutine sub
    end module m_test

    program AssumedRankTest
      use m_test
      implicit none
      real :: a(10), b(5, 5), c(1, 2, 3)
      a = 1; b = 2; c = 3
      call sub(a)
      call sub(b)
      call sub(c)
    end program AssumedRankTest
実行例

ここでは、渡された配列のランク毎のサイズを表示させています。

10
5 5
1 2 3
続行するには何かキーを押してください . . .