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