Fortran Coder

查看: 589|回复: 7

[子程序] fortran 数组作为参数传递

[复制链接]

7

帖子

2

主题

0

精华

入门

F 币
53 元
贡献
28 点
发表于 2017-12-18 00:54:35 | 显示全部楼层 |阅读模式
我正在读一段代码,其中有段数组作为子程序参数传递没有看懂,特来求助:

在主程序里面代码如下:

[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 的元素对应呢?

谢谢!



回复

使用道具 举报

1237

帖子

12

主题

5

精华

论坛跑堂

Fcode跑堂伙计

F 币
790 元
贡献
357 点

新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2017-12-18 08:33:21 | 显示全部楼层
按顺序对应,如果 Ct 的第一维和第二维大小都是 m 的话。相当于把 Ct(:,:,icx) 传递进去了,也就是 Ct 第三维度为 icx 时的所有第一维度和第二维度。

这种方式非常不建议使用。可以用 Ct(:,:,icx) 代替

7

帖子

2

主题

0

精华

入门

F 币
53 元
贡献
28 点
 楼主| 发表于 2017-12-18 08:52:37 | 显示全部楼层
谢谢回复!我也是第一次见这种写法,觉得挺不符合我的习惯。我得再理解理解。

82

帖子

3

主题

0

精华

版主

F 币
419 元
贡献
257 点

贡献勋章管理勋章帅哥勋章元老勋章星光勋章规矩勋章

发表于 2018-5-2 14:50:22 | 显示全部楼层
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

1237

帖子

12

主题

5

精华

论坛跑堂

Fcode跑堂伙计

F 币
790 元
贡献
357 点

新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2018-5-2 15:22:24 | 显示全部楼层
chiangtp,
是的,需要虚参是 assumed-shape array

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

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

82

帖子

3

主题

0

精华

版主

F 币
419 元
贡献
257 点

贡献勋章管理勋章帅哥勋章元老勋章星光勋章规矩勋章

发表于 2018-5-2 19:02:45 | 显示全部楼层
能 进行 "沒有實參虛參間誤會" 越界检查, 的確是要 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, 請問大家 你會怎做?

1

帖子

0

主题

0

精华

新人

F 币
17 元
贡献
4 点
发表于 2018-5-22 16:40:02 | 显示全部楼层
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 )矩阵怎么对应??

82

帖子

3

主题

0

精华

版主

F 币
419 元
贡献
257 点

贡献勋章管理勋章帅哥勋章元老勋章星光勋章规矩勋章

发表于 2018-5-22 18:01:29 | 显示全部楼层
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) 对应
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

QQ|捐赠本站|Archiver|关于我们 About Us|群聊|Fcode

GMT+8, 2018-7-23 06:10

Powered by Discuz! X3.2

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表