Intel® Windows、シェル操作、ACMLライブラリ
PGIコンパイラ製品の中で Windows® 版のコンパイラ製品は、二種類あります。Fortran/C/C++ 言語を完備するPGI Workstation/Server 製品シリーズの中の「Windows版」とFortran のみの製品となりますが、Microsoft® Visual Studio にプラグインすることができる PGI Visual Fortran の二つです。前者のPGI Workstation/Serverシリーズの製品は、他のプラットフォーム版のLinux版やOS X 版と同じコマンド・インタフェースで使用できます。いわゆる、Linux の bash シェル環境で使用できる Windows用のコンパイラ製品です。Linux や OS X 上でコマンドベースでコンパイラを使用しているユーザが、Windows® においても同じコマンド・インタフェースで使用できるものと考えればよいでしょう。このコラムでは、Makefile 等を利用して、Linux ベースと同じように使用できる例をお見せします。また、Windows上で ACML ライブラリをリンクして使用する方法も説明します。
2010年2月24日 Copyright © 株式会社ソフテック 加藤
Windows版の概要とその利用における留意点は、以下のリンク先のページにて、説明しております。なお、PGI Visual Fortran for Windows は別シリーズの製品となりますので、これに関してはこちらのページをご参照下さい。
Windows上で PGI コンパイラを使用するための「コマンドプロンプト」は、デスクトップ上にそのアイコンがあります。これをクリックすると、PGIのbash専用のコマンド用画面が現れます。64bit Windows の場合は、デフォルトが 64ビット環境のコマンドプロンプトとなります。コマンドプロンプトを起動する方法は、以下の画面のようにWindows の「スタート」メニューから行う方法もあります。この画面は、64bit Vista 上の例ですが、ここでは、32bit 用 PGI コマンドプロンプトや 64bit 用の PGI コマンドプロンプトを選択できます。また、Windows で一般的な DOS コマンドプロンプトも選択できるようになっています。 DOS プロンプトにおいても、PGIのコマンドパスが設定されていますので、PGIコンパイラ・コマンドが使用できます。


ここでの説明に用いるプログラムは、行列積の計算を LAPACK ルーチンの中の dgemm を使用して処理するものです。この LAPACK ルーチンは、ACML ライブラリを使用することにします。以下にソースプログラムとWindows 64bit 用の Makefile と 32bit 用の Makefile (Makefile32bitと言うファイル)を示しました。
このプログラムは、単純に、LAPACK dgemm ルーチンを使用して行列積の計算を行うものである。
do i = 1, niter
call dgemm('n','n',m,n,k,alpha,a,ii,b,ii,beta,c,ii)
enddo
PGI Workstation/Server シリーズの Windows版コンパイラには、Linux bashシェル環境をエミュレートする「PGIコマンドプロンプト」が使用できます。このコマンドプロンプト上は、bashシェル環境ですので、Linux の主要コマンドや Make 等の GNU の一部のユーティリティを利用できます。これによって、ユーザは、今まで UNIX/Linux 上で開発してきたプログラム資産と開発環境を、多くの労なくして Windows 環境へ移行することができます。すなわち、今まで使用してきたMakefile 等のシステム開発用 Wrapper interface が多少の変更で使用できると言うことになります。但し、システムのライブラリや C の include ファイル、そしてリンカー、アセンブラ等の機能は、Microsoft が提供する SDK を使用するため、Linux上の GNU 環境の SDK と全く一致するものではありません。Windows 上では、ソースプログラムをコンパイルした後、Microsoft が提供するプログラミング環境を使用して必要とされるシステム・ライブラリ等がリンクされ実行モジュールが生成されます。PGIコンパイラの Linux/OS X 環境(SDK 環境がGNU系)と Windows 環境の大きな違いは、ベースとなるプログラミング開発環境 SDK の違いと言うことになります。Windows 版では、Micorosoft の SDK を使用するため、Visual C/C++ 等の言語環境に互換性があると考えて下さい。大きな違いは、C言語系のヘッダーファイル(GNU と Microsoft の違い)等に出てくるものと思います。Fortran レベルでは、こうした互換性に関しては意識する必要がありません。
このコラムでは、Windows上で Make ファイルを使用する上での留意点、ACML ライブラリのリンク方法を説明することにします。
Windows上での Makefile の一例
例題のプログラムをコンパイル、リンクするための Makefile の例を以下に示します。Linux上の Makefile と Windows 上の Makefile の書き方の大きな違いは、ファイル名のコンベンション(慣習的な名付け方)が異なることです。下の例を見て下さい。OBJS = pgi_mm.obj と言う定義を行っていますが、一般に Windows の世界では、オブジェクト名は ***.obj と言う suffix を慣習的に使用します。一方、Linux/UNIX 等では、***.o と言う suffix を使います。 あともう一つ、実行モジュール名のデフォルトは {ソースファイル名}.exe とするのが Windows であり、Linux/OS X では、デフォルトの名前が a.out となります。主な違いの大きなものは、これくらいでしょう。
64ビットWindows環境での Makefile
#for 64-bit Windows SRC = pgi_mm.f OBJS = pgi_mm.obj FC = pgf95 RM = /bin/rm PROG =mm64.exe #ACMLLIB = -Bdynamic libacml_mp.lib #If OpenMP parallel, -mp option is required.(ACMLの並列版を使用する) #ACML ライブラリの並列版のリンク FFLAGS = -fastsse -mp -Minfo ACMLLIB = -Bdynamic -lacml_mp #If seriall , -mp option is not required.(ACMLのシリアル版を使用する) #FFLAGS = -fastsse -Minfo #ACML ライブラリのシリアル版のリンク #ACMLLIB = -Bdynamic -lacml LDFLAGS = ${FFLAGS} all : ${PROG} ${PROG}: ${OBJS} ${FC} -o $@ ${OBJS} ${LDFLAGS} ${ACMLLIB} ${OBJS}: ${SRC} ${FC} -c ${FFLAGS} $< clean: ${RM} -f ${PROG} ${OBJS} core *.mod *.obj *.exe *.pdb *.dwf
環境変数 PGI_OBJSUFFIX で、オブジェクトの suffix を変更
Windows 環境のオブジェクトファイル名は、デフォルトで ***.obj となりますが、これを任意に変更することができます。例えば、Linuxで使用してきた ***.o と同じにしたい場合は、予め、環境変数 PGI_OBJSUFFIX に "o" を指定しておけば、例えば、Linux で使用してきた Makefile の変更を少なくすることができます。但し、この PGI_OBJSUFFIX 環境変数は、PGIコマンド・プロンプト画面を開いたときに、必ず設定する必要があります。あるいは、自分のホームの .bashrc ファイルに定義しておく必要があります。この設定を忘れると、***.obj ファイルがデフォルトのため、make 実行がエラーとなります。
PGI$ export PGI_OBJSUFFIX=o (***.o のsuffixにする) 【上記 Makefile の内容の変更】 OBJS = pgi_mm.o に変更 PGI$ make pgf95 -c -fastsse -mp -Minfo pgi_mm.f matmul: 39, Generated vector sse code for the loop 62, Loop not vectorized/parallelized: contains call 91, Loop not vectorized/parallelized: contains call 114, Loop not vectorized/parallelized: contains call pgf95 -o mm64.exe pgi_mm.o -fastsse -mp -Minfo -Bdynamic -lacml_mp PGI$ ls Makefile mm64.exe pgi_mm.f mm64.dwf mm64.pdb pgi_mm.o 【再度、***.obj に戻すには】 $ export PGI_OBJSUFFIX=obj (***.obj のsuffixにする)
ACMLライブラリのリンク方法
ACMLライブラリを Windows 上でリンクするためには、他の Linux や OS X 版とは異なり、特別に -Bdynamic と言うオプションを指定する必要があります。このオプションは、ACMLライブラリが Dynamic リンク形式のライブラリ形態となっているため、明示的にリンカーに指示するためのものです(PGIのデフォルトのリンク形式は静的リンク形式です)。
次に、ACMLライブラリをリンク指定するオプションは、-lacml あるいは、-lacml_mp があります。たまに、この他に -lacml_mv も指定が必要な場合もあります。-lacml は、シリアル計算バージョンのライブラリであり、-lacml_mp は、マルチスレッド版の並列バージョンのライブラリとなります。
ACMLライブラリの使用法については、こちらをご覧下さい。
ACMLライブラリのリンク用オプション
【ACMLのシリアル(1CPU)バージョンのリンクのためのオプション】 -lacml -Bdynamic 【ACMLの並列バージョンのリンクのためのオプション】 -lacml_mp -Bdynamic
32bit Windows環境 ACMLライブラリのリンク方法
Windows 版では 32bit コンパイラ環境と 64bit環境では、コンパイルオプションが多少異なります。32ビット環境では、外部ライブラリ等のサブプログラムや関数との引数の引き渡し方法(呼び出し規約)を指定する必要があります。Windows 32ビット環境では、 Fortran のための呼び出しルール(コンベンション)を指定しなければいけません(64ビット環境では必要ありません)。プログラムの中で、従来の UNIX calling conventions のルール、すなわち、Fortran側で call する外部ルーチン名の語末のアンダースコアがないタイプでプログラム構成されている場合(Fortran ではこれが一般的)は、-Munix オプションあるいは、-Miface=unix を付けなければいけません。一般的な Fortran レベルの慣習に沿ったプログラムは、このオプションで良いです。ACMLライブラリのルーチン名も、このルールで作られていますので、-Munix を付けてコンパイル、リンクを行います。(64bit環境では、このオプションは必要ありません)
(ご参考)PGI Visual Fortran 製品を使う
64bit Windows 環境には、32bit用のPGIコンパイラ環境と 64bit 用の PGIコンパイラ環境が実装されています。32bit 環境を使用したい場合は、必ず、Windows アプリケーションの「スタート」メニューから 32bit用の PGI Bash プロンプトを選択して実行して下さい。
32bit PGI 環境での FORTRAN コンパイルとリンクオプション
【ACMLのシリアル(1CPU)バージョンのリンク】 pgf95 -fastsse -Minfo -Munix pgi_mm.f -lacml -Bdynamic 【ACMLの並列バージョンのリンク】 -mp を入れて、-lacml_mp を指定 pgf95 -fastsse -Minfo -Munix -mp pgi_mm.f -lacml_mp -Bdynamic
64bit Windows環境 ACMLライブラリのリンク方法
64bit 環境の場合は、-lacml あるいは -lacml_mp と -Bdynamic をリンクオプションに付加することでACMLライブラリをリンクできます。
64bit PGI 環境での FORTRAN コンパイルとリンクオプション
【ACMLのシリアル(1CPU)バージョンのリンク】 pgf95 -fastsse -Minfo pgi_mm.f -lacml -Bdynamic 【ACMLの並列バージョンのリンク】 -mp を入れて、-lacml_mp を指定 pgf95 -fastsse -Minfo -mp pgi_mm.f -lacml_mp -Bdynamic
以下の例は、Makefile を使用してコンパイル・リンクし、Core2 Duo (2.4GHz) の 2コアのシステムで実行したものです。
PGI$ make
pgf95 -c -fastsse -mp -Minfo pgi_mm.f
matmul:
39, Generated vector sse code for the loop
62, Loop not vectorized/parallelized: contains call
91, Loop not vectorized/parallelized: contains call
114, Loop not vectorized/parallelized: contains call
pgf95 -o mm64.exe pgi_mm.obj -fastsse -mp -Minfo -Bdynamic -lacml_mp
PGI$ export OMP_NUM_THREADS=1 (1スレッド実行)
PGI$ mm64.exe
Time measurement accuracy : .10000E-05
10 116.9590643274854
20 851.0638297872340
30 1651.376146788991
40 2723.404255319149
50 3205.128205128205
60 3483.870967741936
70 3988.372093023256
80 4697.247706422018
90 4673.076923076923
100 5128.205128205129
100 6250.000000000000
200 6425.702811244980
300 7366.984993178718
400 7441.860465116280
500 7621.951219512196
600 7700.534759358289
700 7995.337995337995
800 7907.335907335908
900 8055.253069200591
1000 8116.879822694877
1000 8000.000000000000
1100 8115.853658536586
1200 8209.026128266034
1300 8290.566037735849
1400 8378.625954198475
1500 8323.057953144267
1600 8471.561530506722
1700 8398.290598290600
1800 8397.408207343413
1900 8457.459926017264
2000 8474.576271186441
PGI$ export OMP_NUM_THREADS=2 (2スレッド並列実行)
PGI$ mm64.exe
Time measurement accuracy : .10000E-05
10 116.2790697674419
20 788.1773399014779
30 1651.376146788991
40 2723.404255319149
50 3205.128205128205
60 3483.870967741936
70 3988.372093023256
80 4376.068376068376
90 4925.675675675676
100 5347.593582887701
100 4255.319148936170
200 9302.325581395349
300 11538.46153846154
400 10240.00000000000
500 10683.76068376068
600 13846.15384615385
700 14658.11965811966
800 14927.11370262391
900 14832.14649033571
1000 13642.56480218281
1000 14184.39716312057
1100 15567.25146198831
1200 14769.23076923077
1300 14794.61279461279
1400 16782.92594166955
1500 15446.18891032286
1600 15456.60377358490
1700 15746.79487179487
1800 15912.68758526603
1900 16272.83511269277
2000 16032.06412825651