Fortran Coder

标题: fortran 数组作为参数传递 [打印本页]

作者: dypang    时间: 2017-12-18 00:54
标题: fortran 数组作为参数传递
我正在读一段代码,其中有段数组作为子程序参数传递没有看懂,特来求助:

在主程序里面代码如下:

[Fortran] 纯文本查看 复制代码
  do icx=1,ncx
   call var_pack(nx,idimx(icx),wmh,xpac,Vt(1,1,icx),nx*2,&
     &            St(1,icx),Ct(1,1,icx),iprint)
...


这里数组 Ct 是三维数组,在调用语句里面用的是它的某一个元素 Ct(1,1,icx)。

而在子程序 var_pack 里面,对应的 C1 这个数组是两维的:

subroutine var_pack(n,nc,wmh,xpac,V,m,S,C1,iprint)

REAL*8 V(m,m),xpac(0:m),S(m),C1(m,m)

那么,在子程序里面计算得到的 C1(m,m) 这个矩阵的 m*m 个元素如何和主程序里面的三维矩阵 Ct 的元素对应呢?

谢谢!




作者: fcode    时间: 2017-12-18 08:33
按顺序对应,如果 Ct 的第一维和第二维大小都是 m 的话。相当于把 Ct(:,:,icx) 传递进去了,也就是 Ct 第三维度为 icx 时的所有第一维度和第二维度。

这种方式非常不建议使用。可以用 Ct(:,:,icx) 代替
作者: dypang    时间: 2017-12-18 08:52
谢谢回复!我也是第一次见这种写法,觉得挺不符合我的习惯。我得再理解理解。
作者: chiangtp    时间: 2018-5-2 14:50
0. 抱歉, 翻個舊案

1. to [dypang]
   這是 Fortran 77 的語法:
       實參(actual argument): not pass an array, but the address of one array element, ct(1,1,icx)
       虛參(dummy argument): 由該adress起, 做 c1(m,m) array 使用 (explicit-shape adjustable-size dummy array)
   如 [fcode] 所說: 如果 Ct 的第一维和第二维大小都是 m 的话。"相当于" 把 Ct(:,:,icx) 传递进去了

2, to [fcode] "...不建议使用。可以用 Ct(:,:,icx) 代替"
    這話可能有點 "語病"
    實參若寫 Ct(:,:,icx), 是 array (section) 沒錯, 但是 依然只 pass the address of the first array element "ct(1,1,icx)",  除非 虛參是 assumed-shape array
    (這也是為何要 explicit interface for assumed-shape dummy array)
    另外, runtime 可能會 (compiler, compile-time-option dependent) create an array temporary (多餘的負擔) for 實參 Ct(:,:,icx) array section
作者: fcode    时间: 2018-5-2 15:22
chiangtp,
是的,需要虚参是 assumed-shape array

因为我的习惯是所有参数数组,均为 assumed-shape array 或 pointer。所以我总是假设是这样。
构建一个 array descriptor 对于CPU来说,是很迅速的,我认为对于程序的可理解性、可阅读性来说,是值得的。

并且 assumed-shape 相比 pass address 来说,更可以让编译器进行越界检查。

作者: chiangtp    时间: 2018-5-2 19:02
能 进行 "沒有實參虛參間誤會" 越界检查, 的確是要 assumed-shape

我一直在想: "assumed-shape" 既出, "exsplicit-shape adjustable-size" 該引退了嗎?

先有 data (actual array, shape已定), 而後 work 某一功能, dummy array 就是用 "assumed-shape" 別無懸念
先想定 work (dummy array適合的shape已定), 要能 for any shape (actual) array, ...

假如 Fortran intrinsic library 沒有 SUM, 要自己coding, 請問大家 你會怎做?

作者: czqczqczq    时间: 2018-5-22 16:40
fcode 发表于 2018-5-2 15:22
chiangtp,
是的,需要虚参是 assumed-shape array

类似的问题:
call Update ( nblock,  stateOld(1,12), stateNew(1,12 )
stateOld是(nblock,17), stateNew(nblock,17 ) 矩阵
而在
subroutine strainUpdate ( nblock, strainOld, strainNew )

dimension   strainOld(nblock,6),    strainNew(nblock,6)

那么 子程序中strainOld(nblock,6),    strainNew(nblock,6)矩阵与原来的stateOld是(nblock,17), stateNew(nblock,17 )矩阵怎么对应??

作者: chiangtp    时间: 2018-5-22 18:01
0. Fortran 是 column-major
    REAL :: A(N,M)
    linear addressing 是 (A(i,j),i=1,N),j=1,M),  i.e.,  A(1,1), A(2,1), ..., A(N,1),    A(1,2), A(2,2), ..., A(N,2),    ...,    A(1,M), A(2,M), ..., A(N,M)

1.  For Fortran 77 Standard, array argument
     實參(actual argument): not pass an array, but pass the address of one array element
     虛參(dummy argument): 由該adress起, 做 任意的(exsplicit-shape adjustable-size) array 使用

2.  你的問題
    子程序中矩阵 strainOld(nblock,6), strainNew(nblock,6)  与 主程序中矩阵 stateOld(1:nblock,12:17), stateNew(1:nblock,12:17) 对应




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2