我将一些由C函数读入的数据传递给Fortran程序,该程序将执行所有数字运算。该数组自然被视为在Fortran中具有形状(2, nn)
。由于C没有多维数组,因此数组在C中分配并使用,长度为2 * nn
。
我想在Fortran中重塑数组,以便我可以在数字代码中使用方便的索引。 Fortran例程看起来像这样:
subroutine fortran_glue_code(n, array) bind(c)
use iso_c_binding, only: c_int
integer(c_int), intent(in) :: n, array(2 * n)
real(double_precision) :: result
call do_the_number_crunching(result, reshape(array, [2, n]))
{ do stuff with the result... }
end subroutine
subroutine do_the_number_crunching(result, array) ! not C-interoperable
real(double_precision), intent(out) :: result
integer, intent(in) :: array(:,:)
if (size(array, 1) /= 2) then
print *, "Wrong size!"
call exit(1)
end if
{ crunch crunch crunch... }
end subroutine
我感到不满意的是reshape
不必要地创建了一个临时数组,并且使用了我将要使用的数据,这是一个非常大的数据。
有问题的程序将array
视为只读,所以我认为,编译器可以简单地创建一个新的Fortran数组头,引用内存中的相同位置,而不是进行数组复制。数组内容,只是具有不同的维度。有没有办法避免使用重塑的数组副本?
答案 0 :(得分:4)
我没有得到你的问题,你为什么不这样做
subroutine fortran_glue_code(n, array) bind(c)
use iso_c_binding, only: c_int
integer(c_int), intent(in) :: n, array(2, n)
real(double_precision) :: result
call do_the_number_crunching(result, array)
{ do stuff with the result... }
end subroutine
或者,您也可以使用序列关联
subroutine fortran_glue_code(n, array) bind(c)
use iso_c_binding, only: c_int
integer(c_int), intent(in) :: n, array(2 * n)
real(double_precision) :: result
call do_the_number_crunching(result, array, n)
{ do stuff with the result... }
end subroutine
subroutine do_the_number_crunching(result, array, n) ! not C-interoperable
real(double_precision), intent(out) :: result
integer, intent(in) :: array(2,n)
integer, intent(in) :: n
if (size(array, 1) /= 2) then
print *, "Wrong size!"
call exit(1)
end if
{ crunch crunch crunch... }
end subroutine
但这是一种不必要的并发症。
答案 1 :(得分:0)
如果在C代码中使用int **
,然后在Fortran中使用type (c_ptr)
,则可以使用内部子例程c_f_pointer
将C指针与具有指针属性的Fortran数组相关联,使用c_f_pointer
的第三个参数指定Fortran数组的维度。猜测,在我看来,编译器不需要执行复制,而是创建Fortran指针/结构,使用C指针地址来定位数据。