RokkoFortranBindingArray - t-sakashita/rokko GitHub Wiki

Fortran配列をC言語に渡す方法

Fortranの配列をC言語のポインタとして渡すには、配列のサイズに(:,:)を使うと、コンパイルは通るが、正しいポインタが渡されない。 配列のサイズを指定すれば、正しく渡せる。

配列サイズを引数とするラッパー関数rokko_distributed_matrix_construct_array_sizesをC言語側で用意した。 これはFortranバンディングの作成のためにのみ用いる。(Cバインディングからも、この関数を使用することはない。)

この関数のinterfaceは以下の通りである。配列のサイズをarray(dim1, dim2)と指定している。 dim1dim2は、C言語側にも渡されるが、C言語ラッパー側では不要である。

     subroutine rokko_distributed_matrix_construct_array_sizes(matrix, map, dim1, dim2, array) &
          bind(c)
       use iso_c_binding
       import rokko_mapping_bc, rokko_distributed_matrix
       implicit none
       type(rokko_distributed_matrix), intent(out) :: matrix
       type(rokko_mapping_bc), value, intent(in) :: map
       integer(c_int), value, intent(in) :: dim1, dim2
       double precision, intent(in) :: array(dim1, dim2)
     end subroutine rokko_distributed_matrix_construct_array_sizes

これを呼ぶ以下のラッパーsubroutineが必要である。

  subroutine rokko_distributed_matrix_construct_array_f(matrix, map, array) bind(c)
    use iso_c_binding
    implicit none
    type(rokko_distributed_matrix), intent(out) :: matrix
    type(rokko_mapping_bc), value, intent(in) :: map
    double precision, intent(in) :: array(:,:)
    integer :: sizes(2)

    sizes = shape(array)
    call rokko_distributed_matrix_construct_array_sizes(matrix, map, sizes(1), sizes(2), array)
  end subroutine rokko_distributed_matrix_construct_array_f

C++側でのメモリの解放

deallocateとdestructの順番は、どちらであっても、seg faultにはならない。 C++側でdestructされた場合に代入されたnullptrは、deallocateでも判定され、解放済みとみなされるから問題ないということか?

  deallocate(array)
  call rokko_destruct(mat)

上記のコードの場合、Fortranでallocateした配列をC++で解放することになる。

C++側のdeleteで呼び出されるデストラクタ:

  ~distributed_matrix() {
    if (!array) {
      delete[] array;
      array = nullptr;
    }
  }

上記のように、判定には、!arrayを用いる。 Fortranで配列がdeallocateされた場合、array != nullptrでは判定できなかった。(この場合、array != NULLだと判定できるのか?)

パディングの考慮

distributed_matrixのFortranバインディングの以下のsubroutineにおいて、渡される配列のサイズは異なる。

  • rokko_distributed_matrix_construct_array
    • ユーザから見えない所も含めてサイズを指定
    • Fortranから渡された配列のサイズを使用
    • length_arrayと比べてサイズが足りるかのチェックを行うべきか?
  • rokko_distributed_matrix_get_array_pointer
    • ユーザから見えるサイズを指定
      • m_size(行のパディング(lld)の時もある。)
      • n_size(EigenExaで使われているcol-majorの場合の列のパディングは、ユーザから見えないので無視)