fortran66のブログ

fortran について書きます。

Compaq Visual Fortran Ver.6.6 (CVF6)

DEC 社の Visual Fortran (DVF) Ver.5 にひきつづき DVF Ver.6 が Win95/98 および WindowsNT 上の Fortran95 規格対応コンパイラとして出荷されました。MS Visual C++ Ver.6 と統合できるのが売りのひとつでしたが、DLL のバージョンがらみの微妙な問題が生じることもあるようです。

当時 DEC の経営が思わしくなくなり DEC は Compaq 社に買収されることになりました。DEC の Fortran 開発チームの存続が危ぶまれましたが、CompaqFortran 事業を継続し、名前を Comaq Visual Fortran (CVF) と変えて、CVF Ver.6.1 の update がリリースされました。

その後、CVF Ver.6.5 が CD による有料 update として出ました。しかし、今度は Compaq が Hewlett Packard 社と合併することになり、またもや Fortran 開発チームの存続が危ぶまれることになりました。結局 Fortran 開発チームは、Intel 社に譲渡されることとなって CVF は Intel Visual Fortran (IVF) と三たび名前を変えて開発が継続されることになりました。

CVF Ver.6.5 には、Ver.6.6C までの update patch が存在しますが、以上の事情から、現在 patch は Hewlett Packard のサイト上に存在しています。無料の登録を済ませた後ダウンロードできます。なお、この update patch は、最新版がすべての版を update した DVF 時代とは異なって、古いものから順々に当ててゆく必要があります。

Intel は、それまで MS Visual C++ へのプラグインの形で、バックエンド部分を Intel の最新チップに対応させた Fortran コンパイラを開発していましたが、Visual Fortan 開発チームが加わってからは、フロントエンド部分を DEC Fortran の流れを汲むものに置き換えた新しい製品としました。

正規のサポートではありませんが、IVF のサポート掲示板で CVF がらみの事を聞くと、それなりに答えてもらえるようです。

なお、HP 名義の HP Visual Fortran(HVF) なるものは存在しません。

今では CVF6.5 が出荷停止になっているので DVF6.0 ないし CVF6.1 から CVF6.6 への正規 upgrade パスは存在しないようです。 BOX パッケージとして出荷されたのは DVF6.0 が最後ではないかと思います。(ただググると怪しげな OEM 版販売業者なるものが、CVF6.5 CD をダウンロード販売しているものが引っかかります。はなはだ怪しいです。)

正式に Fortran95 規格完全対応になったは Ver.6 からです。

■実行例

Fortran95 でのQuick Sort のプログラム。ソート条件を関数引数として与えられるようにします。ソート条件は、ふたつのスカラー引数間で演算を行い論理型のスカラー値を返す要素型関数として与えます。

Fortran95 で導入された修飾子 ELEMENTAL(要素型)を用いています。


VMware Windows2000 上にて

■出力

20個の要素を、比較の関数を引数として与えることで、それぞれ昇順と降順でソートした結果。

PRINT *, qsort2(x, lt)

PRINT *, qsort2(x, gt)


■Fortan95 source

CVF6.6Cでは何も言われませんが、厳格に言うと自作の要素型副プログラムを実引数にしてはいけないようです。Intel Fortran Ver.11 で非標準について警告させると、しかられます。

MODULE m_sort
IMPLICIT NONE
CONTAINS
!-----------------------------------------------------
RECURSIVE FUNCTION qsort2(x, f) RESULT(res)
REAL, INTENT(IN) :: x(:)
REAL :: res(SIZE(x))
LOGICAL :: mask(SIZE(x) - 1)
INTERFACE 
 ELEMENTAL LOGICAL FUNCTION f(x1, x2) 
 REAL, INTENT(IN) :: x1, x2
 END FUNCTION f
END INTERFACE
IF (SIZE(x) > 1) THEN
 mask = f(x(2:), x(1))
 res = (/  qsort2( PACK(x(2:), mask), f ), x(1), qsort2( PACK(x(2:), .NOT. mask), f )  /)  
ELSE
 res = x
END IF
RETURN
END FUNCTION qsort2
!-----------------------------------------------------
END MODULE m_sort
!========================================================
MODULE m_func
IMPLICIT NONE
CONTAINS
!-----------------------------------------------------
ELEMENTAL LOGICAL FUNCTION lt(a, b) 
REAL, INTENT(IN) :: a, b
IF (a < b) THEN
 lt = .TRUE.
ELSE
 lt = .FALSE.
ENDIF
RETURN
END FUNCTION lt
!-----------------------------------------------------
ELEMENTAL LOGICAL FUNCTION gt(a, b)
REAL, INTENT(IN) :: a, b
IF (a > b) THEN 
 gt = .TRUE.
ELSE
 gt = .FALSE.
ENDIF
RETURN
END FUNCTION gt
!-----------------------------------------------------
END MODULE m_func
!========================================================
PROGRAM sort
USE m_sort
USE m_func
IMPLICIT NONE
REAL :: x(20)
CALL RANDOM_SEED()
CALL RANDOM_NUMBER(x)
PRINT *, qsort2(x, lt)
PRINT *
PRINT *, qsort2(x, gt)
STOP
END PROGRAM sort