【问题标题】:In Fortran, what is the difference between passing myArray or myArray(:) to a function?在 Fortran 中,将 myArray 或 myArray(:) 传递给函数有什么区别?
【发布时间】:2014-05-16 23:29:11
【问题描述】:

正如标题所说,我对数组本身和数组子集之间的类型差异很感兴趣。作为背景,我将数组传递给 MPI 函数,当使用零长度数组调用时,该函数会触发“数组索引越界”错误,但仅使用子集表示法。以下是手头问题的简化示例:

real(4), allocatable :: myData(:)

allocate(myData(numElements), STAT=iStat)

! The following calls only differ in the second argument
! Passing array itself always works (e.g. myData)
call MPI_FILE_WRITE_ALL(file, myData, MPI_REAL4, numElements, &
                        MPI_STATUS_IGNORE, mpiErr)

! Passing converted subset always works (e.g. real(myData(:), 4)
call MPI_FILE_WRITE_ALL(file, real(myData(:), 4), MPI_REAL4, numElements, &
                        MPI_STATUS_IGNORE, mpiErr)

! Passing subset works unless numElements is zero
call MPI_FILE_WRITE_ALL(file, myData(:), MPI_REAL4, numElements, &
                        MPI_STATUS_IGNORE, mpiErr)

这是documentation for MPI_FILE_WRITE_ALL 的链接,但它似乎只需要BUFFER(*)。关于为什么这些不同的调用表现如此不同的任何想法?

【问题讨论】:

标签: arrays fortran mpi subset


【解决方案1】:

回答关于你标题的问题:

当传递一个数组切片时,必须创建一个临时数组并将数据复制到其中,当传递整个数组时,这不是必需的,而是使用对原始数组的引用而不是复制。

正如 M. S. B. 提供的链接和 cmets 中提到的,传递切片也会导致数组边界信息的丢失。

【讨论】:

  • 这并没有解决问题主体中的要点,只是非常不具体的标题。然而,在后者中,它过于简单化了。复制不是数组切片的“必须”,也不是整个数组的“不得”:即使对于整个数组,如果虚拟参数具有 value 属性,则必须进行复制.关于“边界损失”,这仅适用于延迟形状数组,在这个问题中不太可能出现这种情况。对于假定形状的数组,无论实际参数的形式如何,都不会传递边界信息。
  • @francescalus 很公平,出于兴趣,您在传递切片时如何避免复制?
  • 人们通常希望编译器尽可能避免复制,但这些事情会因编译器/编译选项而异。请注意,许多编译器提供了复制发生时的诊断。
  • 这个答案不正确。标准中没有说明制作临时副本,因此取决于编译器。我已经在 ifort 编译器中测试了发送相对较大数组的切片,我相信编译器不会制作临时副本,因为时间正好等于传递引用。但是,当我故意复制发送时,时间会明显变慢。发送切片时,编译器基本上会发送 Dope Vector en.wikipedia.org/wiki/Dope_vector 不一定要复制切片。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-08
相关资源
最近更新 更多