fortran数组重塑没有临时数组

时间:2014-11-21 23:20:33

标签: c fortran fortran-iso-c-binding

我将一些由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数组头,引用内存中的相同位置,而不是进行数组复制。数组内容,只是具有不同的维度。有没有办法避免使用重塑的数组副本?

2 个答案:

答案 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指针地址来定位数据。