目次

5. プログラムの実行法

5.1 プログラムのインストール

ファイル(dlgpr.zip) をダウンロードして、 適当なフォルダに展開してください。ファイル構成は以下の通りです。

  1. dl/ : 深層学習プログラム(Python)
  2. fdtd2d/ : 2次元FDTDプログラム(C)
  3. fdtd3d/ : 3次元FDTDプログラム(C)

図5-1にシステム構成図を示します。

図5-1 システム構成図

5.2 FDTDプログラムのデータ入力

ファイルMain.cを編集して計算条件を設定してください。

5.2.1 2次元版

誘電率/導電率については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.2 3次元版

リスト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;            // タイムステップ数(初期分除く)

5.3 FDTDプログラムのビルド法

FDTDプログラムをビルドするには、 2次元モデルはfdtd2dで3次元モデルはfdtd3dで以下のコマンドを実行してください。
いくつかのファイルはfdtd2dとfdtd3dで共通なので両者は同じ方法でビルドしてください。

表5-1 FDTDプログラムのビルド法(2次元モデル, 3次元モデル)
ビルドコマンドOSコンパイラー実行プログラム
$ nmake.exe -f Makefile_cl Windows cl.exefdtd2d.exe または fdtd3d.exe
$ nmake.exe -f Makefile_cl_mpiWindows cl.exefdtd2d_mpi.exe または fdtd3d_mpi.exe (MPI対応)
$ make -f Makefile_gcc LinuxまたはWSL2gcc fdtd2d または fdtd3d
$ make -f Makefile_gcc_mpi LinuxまたはWSL2mpicc fdtd2d_mpi または fdtd3d_mpi (MPI対応)

5.4 FDTDプログラムの実行法

FDTDプログラムはデータに関して独立した計算なので、 OpenMP(共有メモリー環境、スレッド並列)またはMPI(分散メモリー環境、プロセス並列) で並列計算することができます。計算時間はスレッド数分の1、かつプロセス数分の1になります。
それぞれの環境で以下のコマンドを実行してください。

5.4.1 2次元版, Windows

$ 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版)

5.4.2 3次元版, Windows

$ 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版)

5.4.3 2次元版, LinuxまたはWSL2

$ ./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版)

5.4.4 3次元版, LinuxまたはWSL2

$ ./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を使用してください。

5.5 深層学習プログラムのデータ入力

ファイル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)

5.6 深層学習プログラムの実行法

深層学習プログラムはPythonで記述されているのでビルド作業は不要です。
実行する前に、numpy, matplotlib, torch, torchvision をインストールしてください。

深層学習を行うには下記のコマンドを実行してください。

$ python dlgpr.py

計算結果を図形出力するには下記のコマンドを実行してください。

$ python plot.py

5.7 計算時間

5.7.1 2次元FDTDの計算時間

2次元FDTDの計算時間は以下のように評価されます。

2次元FDTDの計算時間 ∝ Nx * Ny * タイムステップ数 * Tx * データ数 / スレッド数 / プロセス数

計算時間の1例として以下のようになります。
・計算条件:Nx=80, Ny=55, Tx=56, タイムステップ数=309, データ数=100,000
・ハードウェア: AMD Ryzen 7 7840HS, 8コア16スレッド
・計算時間: 3442秒

5.7.2 3次元FDTDの計算時間

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秒

5.7.3 2次元モデル深層学習の計算時間

深層学習の計算時間は以下のように評価されます。

深層学習の計算時間 ∝ エポック数 * データ数 * パラメータ数

計算時間の1例として以下のようになります。
・計算条件:エポック数=100, データ数=100,000, ResNet34, 112x112px, パラメーター数=22,920,000
・ハードウェア: NVIDIA GeForce RTX 4060 Laptop, 3072コア
・計算時間: 6504秒

5.7.4 3次元モデル深層学習の計算時間

深層学習の計算時間は以下のように評価されます。

深層学習の計算時間 ∝ エポック数 * データ数 * パラメータ数

計算時間の1例として以下のようになります。
・計算条件:エポック数=200, データ数=10,000, ResNet34, 112x112px, パラメーター数=70,532,672
・ハードウェア: NVIDIA GeForce RTX 4060 Laptop, 3072コア
・計算時間: 2510秒