はじめに
色々試行錯誤して一応どうにか動いたので備忘録としてメモします。
ざっくり結論
結論としてはiRIC.exeの入っているフォルダ(iRIC_v4\guis\prepost)にIntel® Fortran Compiler Runtimeでインストールしたランタイムdllを入れたらiRIC上でも動くようになった。
ただしこの方法が正しいかはよくわからないので自己責任で。
背景等は読む必要がないので解決法だけ知りたい人は 一応解決した方法 へ。
背景
普段、fortranで書かれたiRICのソルバーのコンパイルには以下の記事を参考に導入したIntel® Fortran Compiler Classicを使用していて、導入した当時は特に何も考えずに使用できていた。
当時Visual Studio2022でうまくコンパイルできなかったのでVisual Studio2019を使用していたのだが、アップデートで直ったようなので、先日Visual Studio2022と合わせてIntel oneAPI Base ToolkitとIntel oneAPI HPC Toolkitをアップデートしたことがこの話の始まり。
Intel® Fortran Compiler Classic (ifort)が廃止になる
アップデートして試しにifortでコンパイルしてみたところ以下のようなメッセージが表示された。
読むにIntel® Fortran Compiler Classic (ifort)が2024年末に廃止になるからIntel® Fortran Compiler (ifx) 使ってねってことらしい。知らなかった。
ifort: remark #10448: Intel(R) Fortran Compiler Classic (ifort) is now deprecated and will be discontinued late 2024. Intel recommends that customers transition now to using the LLVM-based Intel(R) Fortran Compiler (ifx) for continued Windows* and Linux* support, new language support, new language features, and optimizations. Use '/Qdiag-disable:10448' to disable this message.
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.12.0 Build 20240222_000000
Copyright (C) 1985-2024 Intel Corporation. All rights reserved.
参考:
なのでifxでコンパイルしてみたらexeがiRIC上で動かなくなって困ったという話です。ちなみにifortでビルドしたexeはiRIC上でも普通に動いた。
状況
使用環境
ソフト | Version |
---|---|
Microsoft Visual Studio Community 2022 | 17.9.5 |
Intel oneAPI Base Toolkit | 2024.1 |
Intel HPC Toolkit | 2024.1 |
Intel® Fortran Compiler | 2024.1.0 |
Intel® Fortran Compiler Classic | 2021.12.0 |
- Visual Studio2022上で動かす場合、普通に動いた
- Visual Studio2022で「 構成のプロパティ > Fortran > Libraries > Runtime Library」で
Multithreaded
かDebug Multithreaded (/libs:static /threads /dbglibs)
にしてビルドしたexeはiRIC上でも動く(こちらを参考にした)
- コマンドラインでifortを使用してビルドしたexeもiRIC上で普通に動く
batファイルからifxでビルドしたexeがiRIC上で動かない
普段batファイルを使ってコマンドラインでビルドしているので、今回も同様にコマンドラインでifxを使ってビルドを行ったところiRIC上でexeが動かなかった。
実際のbatは以下。
@echo off
call "C:\Program Files (x86)\Intel\oneAPI\setvars.bat" intel64 vs2022
rem ----------------------------------------------------------------------
rem ifort compile
rem ----------------------------------------------------------------------
ifx .\src\iric.f90 /Qopenmp /nostandard-realloc-lhs /MD /c
ifx .\src\Grid_tester.f90 /Qopenmp /nostandard-realloc-lhs /MD /c
ifx *.obj ^
.\lib\iriclib.lib ^
-o ".\install\Grid_tester.exe"
del *.obj
del *.mod
for_alloc_allocatable_handl ダイナミックリンクライブラリが見つからない
上記の内容でビルドしたexeをiRIC上で実行すると「プロシージャエントリポイント for_alloc_allocatable_handl がダイナミックリンクライブラリ ~ から見つかりませんでした。」と言われソルバーが異常終了してしまう。
Intel® Fortran Compiler (ifx) のランタイムdllがある場所にはPATHを通してあったがどうも認識されていないよう。どのdllが必要なのかもよくわからない。
__kmpc_aligned_alloc ダイナミックリンクライブラリが見つからない
それならば静的リンクにしてしまえということで、ビルド時のオプションを/MD
から/MT
に変更した。
for_alloc_allocatable_handlは無事に見つかったようだが、今度は__kmpc_aligned_allocが見つからないと言われた。PATHは通してあるはずなのに見つからないものだらけである。
ちなみにこれはlibiomp5md.dll
が原因っぽい
これが入っているifxのランタイムDLLのあるC:\Program Files (x86)\Intel\oneAPI\compiler\latest\bin
にPATHは通っているのに。。。。
類似の事例
そう言えば同様の問題を見たことがあると思ったら以下の記事だった。
最終的にバッチファイルからソルバーを実行しているが、iRIC上から実行するのは無理なのだろうか。
一応解決した方法
どうにもならないので某iRIC開発者に助言を求めたところ以下の回答を頂いた。
- iRICにはIntel® Fortran Compiler Classic (ifort)のランタイムDLLは同梱している
- だがはIntel® Fortran Compiler (ifx)のランタイムDLLは同梱していない
- iRIC.exeと同じフォルダにifxのランタイムDLLを置けば動くはず
ということでifxのランタイムDLLをiRIC_v4\guis\prepost
に入れてみる。
Intel® Fortran Compiler (ifx)のランタイムDLLを探す
ifxのランタイムDLLはIntel oneAPI Base ToolkitとIntel HPC ToolkitをインストールしていればC:\Program Files (x86)\Intel\oneAPI\compiler\latest\bin
に入っている。
またはIntel® Fortran Compiler Runtime for Windowsでランタイムパッケージだけをインストールしている場合はC:\Program Files (x86)\Common Files\intel\Shared Libraries\bin
に入っている。自分でコンパイルしない人はこっちで十分。
iRIC_v4\guis\prepostにランタイムDLLをコピーする
先ほど探したランタイムDLLをiRIC.exeが入っているiRIC_v4\guis\prepost
にコピーする。
何かあってもiRICを再インストールすれば問題ないが、めんどくさいのでprepostを丸ごとバックアップとっておきましょう。
私の環境では以下のファイルが既にあると言われましたが上書きでいいです。
tbbmalloc_proxy.dll
tbbmalloc.dll
tbbbind_2_5.dll
tbbbind_2_0.dll
tbbbind.dll
tbb12.dll
svml_dispmd.dll
onnxruntime.1.12.22.721.dll
libmmdd.dll
libmmd.dll
libiomp5md.dll
libifportmd.dll
libifcorertd.dll
libifcorert.dll
libifcoremdd.dll
libifcoremd.dll
コピー後にiRICを起動して実行してみたらうまく動きました。
まとめ
- iRIC.exeのあるフォルダに必要なDLLを置けば動く
- 自己責任でお願いします
参考リンク集
インテル® Fortran コンパイラー クラシックおよびインテル® Fortran コンパイラー開発者ガイドおよびリファレンス
インテル® Fortran コンパイラー移植ガイド
インテル® Fortran コンパイラー クラシックおよびインテル® Fortran コンパイラー開発者ガイドおよびリファレンス
アルファベット順オプションリスト
独り言
あってるのかどうかもわからないけど自分なりの今回の解釈
ifxのランタイムDLLがあるフォルダにPATH通していたのに動かなかったのは、iRICに同梱されているifortの古いランタイムDLLが先に読み込まれていたから?
DLLの読み込み優先度について、下記リンクの記事を読むに、明らかにiRIC.exeのあるフォルダのほうが優先度が高いので十分ありえる。
DLLのバージョンについて、ifortとifxは一応互換性あるらしいですが、iRICに同梱されたDLLが古かったり足りなかったのでしょうか。
そう言えば__kmpc_aligned_allocで問題になっていたlibiomp5md.dll
は元々iRICに同梱されていたが、同梱されていたものはバージョンが5.0.2020.1007
で、今回コピーしたものは5.0.2023.1212
なので確かに古かった。
今回ビルドに使ったifxのバージョンは最新の2024.1.0
、それに対してifortは最新版でも2021.12.0
、iRICに同梱されているランタイムがどのバージョンのifortのものかはわからないが、ifortのランタイムという時点でifxで使用しているランタイムより古いというのは納得できる。
なるほど、どうりでPATHを頑張って通したりしてもうまくいかなかったわけですね。