Fortran:哪种方法可以更快地更改数组的等级?(重塑与指针)

Vah*_*hid 6 arrays fortran pointers reshape

当我们处理大型数组时,考虑数组的秩和形状变化的成本可能很重要,特别是当它在多个子例程/函数中发生几次时。

我问题的主要目的是将数组的排名从第二更改为第一,反之亦然......

为此,可以使用:

  1. 重塑声明
  2. 指针变量。下面的代码展示了如何使用指针变量:

    program test
        real, pointer :: a(:)
        real, pointer :: b(:,:)
    
        allocate(a(6))
        a = (/1,2,3,4,5,6/)
        b (1:2, 1:3) => a
    
        WRITE(*,*) 'b=',b(3,1)
    end program test
    
    Run Code Online (Sandbox Code Playgroud)

问题: 1. 哪种方法更快?2.还有其他更快的方法吗?3. 对于这项工作还有其他建议吗?

谢谢...

Vah*_*hid 4

嗯,Fortran 被设计为数学语言。我进行了一些挖掘,发现了 Fortran 中的以下几点。

在解释要点之前先做一些解释:

我的子例程必须使用第一级数组。我在子例程开始时调用第二级数组作为输入。然后,我需要将排名从第二更改为第一。稍后在子例程中,我需要将等级更改回 2。这种等级更改在代码中发生了 3-4 次。

  1. 使用等效语句:

这是最快的方法。记忆中没有任何改变,我认为这是最好的。但是,它以我的问题的属性冲突错误结束,因为我正在子例程内工作。

  1. 使用指针属性:

我当时就尝试过指针。但是,似乎不可能将第二级数组重新映射到第一级数组。将第一级数组重新映射到第二级数组效果很好。

我编写的简单代码是将第一级数组重新映射到第二级数组:

program ptrtest
real, pointer :: a(:)
real, pointer :: b(:,:)

allocate(b(1:2,1:3))
b = transpose(reshape((/ 1, 2, 3, 4, 5, 6 /), shape(b)))
a(1:6) => b(:,:) 

WRITE(*,*) a(4), b(2,2) ! to see if the remapped elements are same?
end program ptrtest
Run Code Online (Sandbox Code Playgroud)

我收到的错误:

gfortran -Wall -o "POINTER" "POINTER.f90" (in directory: /home/vahid/Desktop)
POINTER.f90:12.14:
a(1:6) => b(:,:)
          1
Error: Rank remapping target must be rank 1 or simply contiguous at (1)
Compilation failed.
Run Code Online (Sandbox Code Playgroud)
  1. 重塑声明:

能够进行任何类型转换的最慢方法。基本上,它为转换的元素分配另一个内存位置,考虑到内存效率和处理成本,这是昂贵的。

因此,Fortran 2003 手册指出:(第 2.2.4 和 5.2 节)

数据对象的大小、形状、类型或长度类型参数可以是动态的,但等级或种类类型参数不是动态的。

我不知道后果,但我认为数组的等级也应该是动态的。如有部分错误请指正。

  • 关于第 (2) 点,如果您按照错误建议进行操作并为“b”赋予属性“连续”,那么它就可以工作。 (2认同)