並列領域のデバッグ

コンパイラは、領域のコードを有効にして、コンパイラが生成した、別のエントリポイントにコードを置くことによって、並列領域をサポートします。これは、アウトライン化 (他のコンパイラに使用される手法、つまりサブルーチンの作成) とは異なりますが、同じデバッグ手法を適用できます。

エントリポイント名の構成

コンパイラが生成する並列領域のエントリポイント名は、次の連続した文字列で構成されます。

ルーチン名 (例: padd) やエントリ名 (例 : _PADD, ___PADD_6__par_loop0) が使用されると、Fortran コンパイラは次のように動作します:
デフォルトでは、コンパイラは最初に小文字および大文字/小文字の混在したルーチン名を大文字に変換します。例えば、pAdD()PADD() に変換され、これに "_" を付けることによりエントリ名になります。その後に、第 2 のエントリ名の変換が行われます。そのため、エントリ名の "__par_loop" 部分は小文字のままになります。これは、デバッガがブレークポイントを設定する際、大文字のルーチン名 "PADD" を認識せず、 代わりに、小文字の "padd" を認識していたためです。

例 1 では、並列領域によるコードのデバッグを示します。例 1 は次のコマンドで生成されます。

ifort -openmp -g -O0 -S file.f90

例 1 のサブルーチン parallel のコードを検証します。

サブルーチン PARALLEL() のソースリスト

1    subroutine parallel
2    integer id,OMP_GET_THREAD_NUM
3 !$OMP PARALLEL PRIVATE(id)
4    id = OMP_GET_THREAD_NUM()
5 !$OMP END PARALLEL
6    end

3 行目が並列領域です。コンパイラは 2 つのエントリポイント、parallel____parallel_3__par_region0 を作成しました。最初のエントリポイントはサブルーチン parallel() に対応し、2 番目のエントリポイントは、3 行目の OpenMP 並列領域に対応しています。

例 1: 並列領域によるコードのデバッグ

サブルーチン parallel() のマシン・コード・リスト

        .globl parallel_
parallel_:
..B1.1:                    # Preds ..B1.0
..LN1:
pushl     %ebp                                    #1.0
movl      %esp, %ebp                              #1.0
subl      $44, %esp                               #1.0
pushl     %edi                                    #1.0
... ... ... ... ... ... ... ... ... ... ... ... ...
..B1.13:                    # Preds ..B1.9
addl      $-12, %esp                             #6.0
movl      $.2.1_2_kmpc_loc_struct_pack.2, (%esp) #6.0
movl      $0, 4(%esp)                            #6.0
movl      $_parallel__6__par_region1, 8(%esp)    #6.0
call      __kmpc_fork_call                       #6.0

       # LOE
..B1.31:                    # Preds ..B1.13
addl      $12, %esp                              #6.0

       # LOE
..B1.14:                    # Preds ..B1.31 ..B1.30
..LN4:
leave                                            #9.0
ret                                              #9.0

       # LOE

.type parallel_,@function
.size parallel_,.-parallel_
.globl _parallel__3__par_region0
_parallel__3__par_region0:
# parameter 1: 8 + %ebp
# parameter 2: 12 + %ebp
..B1.15:                    # Preds ..B1.0
pushl     %ebp                                   #9.0
movl      %esp, %ebp                             #9.0
subl      $44, %esp                              #9.0
..LN5:
call      omp_get_thread_num_                    #4.0

       # LOE eax
..B1.32:                    # Preds ..B1.15
movl      %eax, -32(%ebp)                        #4.0

       # LOE
..B1.16:                    # Preds ..B1.32
movl      -32(%ebp), %eax                        #4.0
movl      %eax, -20(%ebp)                        #4.0
..LN6:
leave                                            #9.0
ret                                              #9.0

       # LOE
.type _parallel__3__par_region0,@function
.size _parallel__3__par_region0,._parallel__3__par_region0
.globl _parallel__6__par_region1
_parallel__6__par_region1:
# parameter 1: 8 + %ebp
# parameter 2: 12 + %ebp
..B1.17:                     # Preds ..B1.0

pushl     %ebp                                   #9.0
movl      %esp, %ebp                             #9.0
subl      $44, %esp                              #9.0
..LN7:
call      omp_get_thread_num_                    #7.0

       # LOE eax
..B1.33:                    # Preds ..B1.17
movl      %eax, -28(%ebp)                        #7.0

       # LOE
..B1.18:                    # Preds ..B1.33
movl      -28(%ebp), %eax                        #7.0
movl      %eax, -16(%ebp)                        #7.0
..LN8:
leave                                            #9.0
ret                                              #9.0
.align    4,0x90
# mark_end;

このレベルでプログラムをデバッグすることは、POSIX スレッド を直接使用するプログラムをデバッグするようなものです。他のルーチンと同じように、スレッドコード内で、ブレークポイントを設定できます。GNU デバッガの場合、ソースレベル・ルーチン名 (parallel など) にブレークポイントを設定できます。また、エントリポイント名 (parallel_、 _parallel__3__par_region0 など) にも設定できます。Linux* 版インテル® Fortran コンパイラが、大文字の Fortran サブルーチン名を小文字に変換したことに注意してください。