2015-11-18 237 views
1

我在Fortran中使用了一個API,它提供了寫入數據的例程。假設它的名字是api_write_data。這個例程需要數組作爲參數,該參數可以是尺寸1,2或3。將1D陣列傳遞到3D陣列

我想要寫其工作方式包裝該API子程序的子程序。但是因此我需要編寫一個可以處理1D,2D或3D數組的程序,並且可以將它們正確地傳遞給API例程。我怎樣才能做到這一點?我可以這樣做嗎?

我的做法是這樣的事情,但它不工作:

subroutine write_data(array) 
implicit none 
integer, dimension(:,:,:), intent(in):: array 

call api_write_data(array) 

end subroutine write_data 

然而,當我把這個程序與例如一個一維數組,我得到已知的錯誤:

Error: Rank mismatch in argument 'array' at (1) (rank-3 and rank-1) 

在Fortran中有沒有辦法做這種事情?對我而言,有必要將陣列作爲1D,2D或3D陣列傳遞給write_data例程。但是,我可以將數組作爲1D數組傳遞給api_write_data

你知道我該怎麼做嗎?

回答

1

reshape功能的替代方法可能是有朝向多維陣列的1D指針:

p(1:size(c)) => c(:,:,:) 

可以傳遞指針作爲一維陣列不進行復制。事實上,它應該像傳遞數組本身一樣快。 當然,你需要告訴子程序的一些方式,也塑造陣列有:

module test_mod 
contains 
    subroutine print_arr(arr, dimX, dimY, dimZ) 
    integer,intent(in) :: arr(:) 
    integer,intent(in) :: dimX, dimY, dimZ 

    if (dimZ == 0) then 
     if (dimY == 0) then 
     ! 1D 
     print *, "1D array provided" 
     print *, "a(4) =", arr(4) 
     else 
     ! 2D 
     print *, "2D array provided" 
     print *, "a(1,2) =", arr((2-1)*dimX+1) 
     endif 
    else 
     ! 3D 
     print *, "3D array provided" 
     print *, "a(1,2,1) =", arr(((1-1)*dimY + (2-1))*dimX+1) 
    endif 
    end subroutine 
end module 

program test 
use test_mod 
    integer :: i 
    integer, target :: a(8) 
    integer, target :: b(4,2) 
    integer, target :: c(2,2,2) 
    integer, pointer :: p(:) 

    a = [ (i,i=1,8) ] 
    b = reshape(a, [4,2]) 
    c = reshape(a, [2,2,2]) 

    p(1:size(a)) => a(:) 
    call print_arr(p, 8, 0, 0) 

    p(1:size(b)) => b(:,:) 
    call print_arr(p, 4, 2, 0) 

    p(1:size(c)) => c(:,:,:) 
    call print_arr(p, 2, 2, 2) 
end program 

這也適用反過來想...你可以一維數組映射到3D指針:

integer, pointer :: p2(:,:,:) 
!... 
p2(1:4,1:2,1:1) => a 
+0

對fortran90沒有限制,會不會有另一種可能性?也許有新的語言功能,也可以通過ifort和gfort編譯.f90文件 – Skyy2010

1

您可以使用的Fortran接口來定義例程的幾個版本:

interface write_data 
    module procedure write_data_1d 
    module procedure write_data_2d 
    module procedure write_data_3d 
end interface write_data 

然後這些程序可以處理不同類型的輸入。然後在這些過程中,您可以使用RESHAPE函數將輸入轉換爲方便的形狀,以便三者都可以調用一個公共的子程序來實現您所做的任何邏輯。

+0

雖然'reshape'確實給出了複製的可能性。 – francescalus

+0

這將是一種選擇,但這會導致很多代碼。因爲我有6個不同版本的這個例程,總共給我18個例程。 – Skyy2010

+0

@francescalus你是什麼意思? – Skyy2010