RokkoFortranBindingArray - t-sakashita/rokko GitHub Wiki
Fortran配列をC言語に渡す方法
Fortranの配列をC言語のポインタとして渡すには、配列のサイズに(:,:)
を使うと、コンパイルは通るが、正しいポインタが渡されない。
配列のサイズを指定すれば、正しく渡せる。
配列サイズを引数とするラッパー関数rokko_distributed_matrix_construct_array_sizes
をC言語側で用意した。
これはFortranバンディングの作成のためにのみ用いる。(Cバインディングからも、この関数を使用することはない。)
この関数のinterfaceは以下の通りである。配列のサイズをarray(dim1, dim2)
と指定している。
dim1
とdim2
は、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の場合の列のパディングは、ユーザから見えないので無視)
- ユーザから見えるサイズを指定