ファイル(dlgpr.zip) をダウンロードして、
適当なフォルダに展開してください。ファイル構成は以下の通りです。
図5-1にシステム構成図を示します。
ファイルMain.cを編集して計算条件を設定してください。
誘電率/導電率についてはcase-1~3のいずれかを有効にしてください。
リスト5-1 2次元版のデータ入力(Main.cの一部)
const int Ndata = 1000; // データ数 const int Nrect = 3; // 長方形数 const int Lrect[] = {5, 15, 10}; // 長方形パラメーター(最小,最大,余白)(セル数) const int Nsmot = 1; // 平滑化回数(0以上) const int Nx = 80; // X方向セル数 const int Ny = 55; // Y方向セル数 const int iTx0 = 10; // 送信アンテナ位置の開始点(セル数) const int NTx = 56; // 送信アンテナ数 const int DTx = 1; // 送信アンテナ移動間隔(セル数) const int LTxRx = 5; // 送受信アンテナ間距離(セル数) const int Lyant = 5; // 送信アンテナの地面からの高さ(セル数) const int Ly0 = 15; // 地上のセル数 const float Eps0 = 1.0f; // 地上の比誘電率 const float Sig0 = 0.0f; // 地上の導電率[S/m] const float Dx = 0.025f; // X方向セルサイズ const float Dy = 0.025f; // Y方向セルサイズ const float Freq = 600e6f; // 周波数 const int WF = 0; // 0:ガウス, 1:微分ガウス const int Nant = 1; // 送信アンテナ数(通常1) const int Labc = 6; // PML層数(0のときはMur) const int Ntime = 224; // タイムステップ数(初期分除く) // case-1 const float Eps[] = {1.0f, 1.0f}; // 長方形比誘電率(最小,最大) const float Sig[] = {0.0f, 0.0f}; // 長方形導電率[S/m](最小,最大) const float pLy1 = 0.0f; // 地下境界面の存在する確率 const int iLy1[] = {10, 30}; // 地下境界面深さの下限と上限(セル数) const float Eps1[] = {4.0f, 4.0f}; // 地下の比誘電率(最小,最大) const float Sig1[] = {0.0f, 0.0f}; // 地下の導電率[S/m](最小,最大) /* // case-2 const float Eps[] = {1.0f, 6.0f}; // 長方形比誘電率(最小,最大) const float Sig[] = {0.0f, 0.03f}; // 長方形導電率[S/m](最小,最大) const float pLy1 = 0.0f; // 地下境界面の存在する確率 const int iLy1[] = {10, 30}; // 地下境界面深さの下限と上限(セル数) const float Eps1[] = {4.0f, 4.0f}; // 地下の比誘電率(最小,最大) const float Sig1[] = {0.0f, 0.0f}; // 地下の導電率[S/m](最小,最大) */ /* // case-3 const float Eps[] = {1.0f, 3.0f}; // 長方形比誘電率(最小,最大) const float Sig[] = {0.0f, 0.01f}; // 長方形導電率[S/m](最小,最大) const float pLy1 = 0.3f; // 地下境界面の存在する確率 const int iLy1[] = {10, 30}; // 地下境界面深さの下限と上限(セル数) const float Eps1[] = {3.0f, 4.0f}; // 地下の比誘電率(最小,最大) const float Sig1[] = {0.0f, 0.01f}; // 地下の導電率[S/m](最小,最大) */
リスト5-2 3次元版のデータ入力(Main.cの一部)
const int Ndata = 100; // データ数 const int Nrect = 2; // 直方体数 const int Lrect[] = {8, 16, 5}; // 直方体パラメーター(最小,最大,余白)(セル数) const int Nsmot = 1; // 平滑化回数(0以上) const int Nx = 80; // X方向セル数 const int Ny = 30; // Y方向セル数 const int Nz = 50; // Z方向セル数 const int iTx0 = 10; // 送信アンテナ位置の開始点(セル数) const int NTx = 56; // 送信アンテナ数 const int DTx = 1; // 送信アンテナ移動間隔(セル数) const int LTxRx = 5; // 送受信アンテナ間距離(セル数) const int Lzant = 5; // 送信アンテナの地面からの高さ(セル数) const int Lz0 = 10; // 地上のセル数 const int NRx = 11; // 受信アンテナ数, 1/3/5,... const int DyRx = 2; // 受信アンテナY方向間隔(セル数) const float Dx = 0.025f; // X方向セルサイズ const float Dy = 0.025f; // Y方向セルサイズ const float Dz = 0.025f; // Z方向セルサイズ const float Freq = 600e6f; // 周波数 const int WF = 0; // 0:ガウス, 1:微分ガウス const float Eps0 = 1.0f; // 地上の比誘電率 const float Sig0 = 0.0f; // 地上の導電率[S/m] const float Eps1 = 4.0f; // 地下の比誘電率 const float Sig1 = 0.0f; // 地下の導電率[S/m] const float Eps[] = {1.0f, 1.0f}; // 直方体の誘電率(最小,最大) const float Sig[] = {0.0f, 0.0f}; // 直方体の導電率[S/m](最小,最大) const int Labc = 6; // PML層数(0のときはMur) const int Ntime = 224; // タイムステップ数(初期分除く)
FDTDプログラムをビルドするには、
2次元モデルはfdtd2dで3次元モデルはfdtd3dで以下のコマンドを実行してください。
いくつかのファイルはfdtd2dとfdtd3dで共通なので両者は同じ方法でビルドしてください。
ビルドコマンド | OS | コンパイラー | 実行プログラム |
---|---|---|---|
$ nmake.exe -f Makefile_cl | Windows | cl.exe | fdtd2d.exe または fdtd3d.exe |
$ nmake.exe -f Makefile_cl_mpi | Windows | cl.exe | fdtd2d_mpi.exe または fdtd3d_mpi.exe (MPI対応) |
$ make -f Makefile_gcc | LinuxまたはWSL2 | gcc | fdtd2d または fdtd3d |
$ make -f Makefile_gcc_mpi | LinuxまたはWSL2 | mpicc | fdtd2d_mpi または fdtd3d_mpi (MPI対応) |
FDTDプログラムはデータに関して独立した計算なので、
OpenMP(共有メモリー環境、スレッド並列)またはMPI(分散メモリー環境、プロセス並列)
で並列計算することができます。計算時間はスレッド数分の1、かつプロセス数分の1になります。
それぞれの環境で以下のコマンドを実行してください。
$ fdtd2d.exe 1スレッド, fdtd.bin出力 $ fdtd2d.exe 8 8スレッド, fdtd.bin出力 $ fdtd2d.exe 8 foo.bin 8スレッド, foo.bin出力 $ mpiexec.exe -n 2 fdtd2d_mpi.exe 4 foo.bin 2プロセス, 4スレッド, foo.bin出力(MPI版)
$ fdtd3d.exe 1スレッド, fdtd.bin出力 $ fdtd3d.exe 8 8スレッド, fdtd.bin出力 $ fdtd3d.exe 8 foo.bin 8スレッド, foo.bin出力 $ mpiexec.exe -n 2 fdtd3d_mpi.exe 4 foo.bin 2プロセス, 4スレッド, foo.bin出力(MPI版)
$ ./fdtd2d 1スレッド, fdtd.bin出力 $ ./fdtd2d 8 8スレッド, fdtd.bin出力 $ ./fdtd2d 8 foo.bin 8スレッド, foo.bin出力 $ mpiexec -n 2 fdtd2d_mpi 4 foo.bin 2プロセス, 4スレッド, foo.bin出力(MPI版)
$ ./fdtd3d 1スレッド, fdtd.bin出力 $ ./fdtd3d 8 8スレッド, fdtd.bin出力 $ ./fdtd3d 8 foo.bin 8スレッド, foo.bin出力 $ mpiexec -n 2 fdtd3d_mpi 4 foo.bin 2プロセス, 4スレッド, foo.bin出力(MPI版)
(注1)
MPI版は複数ノードで実行するときに使用し、その他の設定が必要ですが、ここでは説明は省略します。
通常は1ノードで非MPI版を使用してください。
(注2)
デバッグを行って図形出力するときは、
OpenFDTD等に付属している2次元図形表示プログラムev2d.exeを使用してください。
ファイルdlgpr.pyを編集して計算条件を設定してください。
リスト5-3 深層学習プログラムのデータ入力(dlgpr.pyの一部)
# FDTD計算結果ファイル名(誘電率と地中レーダー画像からなる) fdtd_bin = '../fdtd2d/fdtd.bin' #fdtd_bin = '../fdtd3d/fdtd.bin' # モデルファイル modelfile = 'dlgpr.pth' load_model = 0 # 通常0, 前回保存したmodelfileからrestartするときと推論時は1 save_model = 1 # 通常1, 計算終了時にmodelfileを保存しないときと推論時は0 # 計算パラメーター ndata = 1000 # データ数, -1のときはすべてのデータ batch_size = 50 # バッチサイズ, 通常50-100程度 num_epochs = 100 # エポック数(推論時は0) train_ratio = 0.8 # 訓練データの割合(通常0.8程度, 推論時は0)
深層学習プログラムはPythonで記述されているのでビルド作業は不要です。
実行する前に、numpy, matplotlib, torch, torchvision をインストールしてください。
深層学習を行うには下記のコマンドを実行してください。
$ python dlgpr.py
計算結果を図形出力するには下記のコマンドを実行してください。
$ python plot.py
2次元FDTDの計算時間は以下のように評価されます。
2次元FDTDの計算時間 ∝ Nx * Ny * タイムステップ数 * Tx * データ数 / スレッド数 / プロセス数
計算時間の1例として以下のようになります。
・計算条件:Nx=80, Ny=55, Tx=56, タイムステップ数=309, データ数=100,000
・ハードウェア: AMD Ryzen 7 7840HS, 8コア16スレッド
・計算時間: 3442秒
3次元FDTDの計算時間は以下のように評価されます。
3次元FDTDの計算時間 ∝ Nx * Ny * Nz * タイムステップ数 * Tx * データ数 / スレッド数 / プロセス数
計算時間の1例として以下のようになります。
・計算条件:Nx=80, Ny=30, Nz=50, Tx=56, タイムステップ数=309, データ数=10,000
・ハードウェア: FOCUSスパコン[9], Sシステム, AMD EPYC 9654, 96コア×2CPU×5ノード=960コア
・計算時間: 3664秒
深層学習の計算時間は以下のように評価されます。
深層学習の計算時間 ∝ エポック数 * データ数 * パラメータ数
計算時間の1例として以下のようになります。
・計算条件:エポック数=100, データ数=100,000, ResNet34, 112x112px, パラメーター数=22,920,000
・ハードウェア: NVIDIA GeForce RTX 4060 Laptop, 3072コア
・計算時間: 6504秒
深層学習の計算時間は以下のように評価されます。
深層学習の計算時間 ∝ エポック数 * データ数 * パラメータ数
計算時間の1例として以下のようになります。
・計算条件:エポック数=200, データ数=10,000, ResNet34, 112x112px, パラメーター数=70,532,672
・ハードウェア: NVIDIA GeForce RTX 4060 Laptop, 3072コア
・計算時間: 2510秒