7.8 指针 BACKWARD FORWARD


作为HPF所认可的扩展,可对指针进行显式映射。形式上这意味着2.3节2.4节所声明的关于对准子和分配子不能具有POINTER属性的约束被去掉了。

同可分配对象一样,指针的映射说明不会立即起作用,但是当指针通过分配空间或通过指针赋值与一个目标建立起关联时,它就会起作用。

当一个具有显式映射的指针被用于ALLOCATE语句时,数据就会以指定的映射被分配空间。

例如:

     REAL, POINTER, DIMENSION(:) :: A, B
 !HPF$ ALIGN B(I) WITH A(I)
 !HPF$ DISTRIBUTE A(BLOCK)
     ...
     ALLOCATE(A(100))
     ALLOCATE(B(50))
     ...
     ALLOCATE(B(200))    不符合HPF标准

指针A被定义成具有BLOCK分配方式而指针B被定义成与A同等对准。 当为A分配空间时,它以BLOCK分配方式被创建。当为B分配空间时,它与A的头50个元素对准。注意,ALLOCATE语句不能以相反的次序出现,这是因为一个对象能够与另一个对象对准仅当它已被创建或已被分配空间。另一方面,对于B的第二次分配空间是不符合HPF标准的,这是因为在这种情况下一个较大的对象B不能与一个较小的对象A相对准。

一个具有显式映射的指针P可以在下列条件下通过指针赋值语句与目标T建立关联:

1.T的映射是P的映射的一个特殊化;且

2.如果P被显式对准,则它的根本对准目标具有一个完全指定,非抄写性的分配方式;且

3.P和T或者都具有DYNAMIC属性或者都没有。

这里是一些例子:

    REAL, POINTER, DIMENSION(:,:) :: P
 !HPF$ DISTRIBUTE P(BLOCK,BLOCK)
    REAL, TARGET, DIMENSION(100,100) :: B,C,D
 !HPF$ DISTRIBUTE B(BLOCK,BLOCK)
 !HPF$ DISTRIBUTE C(BLOCK,CYCLIC)
     ...
    P=>B          !符合HPF标准
    P=>B(1:50,1:50)    !不符合HPF标准:目标必须是整个数组
    P=>C          !不符合HPF标准:第二维的分配方式不匹配
    P=>D          !不符合HPF标准:D不是显式映射的。
    ...

即使没有为指针指定处理器排列下列指针赋值也是有效的;在这种情况下,B的映射是P的映射的一个特殊化:

    REAL, POINTER, DIMENSION(:) :: P
    REAL, TARGET, DIMENSION(100) :: B
 !HPF$ DISTRIBUTE P(BLOCK)
 !HPF$ DISTRIBUTE (BLOCK) ONTO P :: B
    ...
    A => B ! 符合HPF标准
    ...

    REAL, POINTER, DIMENSION(:) :: P
 !HPF$ DISTRIBUTE * :: P
    REAL, TARGET, DIMENSION(100) :: B, C
    !HPF$ DISTRIBUTE B(BLOCK), C(CYCLIC)
    ...
    P => B ! 符合HPF标准
    P => C ! 符合HPF标准
    P => C(1:50) ! 不符合HPF标准:目标必须是整个数组
    ...

在这里,使用*来指示指针A的抄写性分配,这样它就可以是一个同时与目标B和C相关联的指针,这两个目标分别以BLOCK和CYCLIC方式分配。但是仍然不能使用它来指向一个诸如C(1:50)的数组区域。为做到那一点,指针必须具有INHERIT属性:

    REAL, POINTER, DIMENSION(:) :: P
 !HPF$ INHERIT :: P
    REAL, TARGET, DIMENSION(100) :: B, C
 !HPF$ DISTRIBUTE B(BLOCK), C(CYCLIC)
    ...
    P => B ! 符合HPF标准
    P => C ! 符合HPF标准
    P => C(1:50) ! 符合HPF标准
    ...

为允许指针具有抄写性分配,我们必须改变2.3节所指定的关于dist-format-clause的约束,如下所示:

约束:如果DISTRIBUTE指令中的dist-format-clause或dist-target以“*”开始,则每个分配子必须是一个哑参,除非分配子具有POINTER属性。

2.4节所指定的关于align-spec的约束应被修改为下面的形式:

约束:如果ALIGN指令中的align-spec以“*”开始,则每个对准子必须是一个哑参,除非对准子具有POINTER属性。

4.4.2节所指定的关于inheritee的约束应被修改为下面的形式:

约束:继承子必须是一个哑参,除非对准子具有POINTER属性。

当具有这种抄写性映射的指针被用于ALLOCATE语句时,编译器可为分配空间的数据选择任意映射。可使用范围说明来限制分配格式的集合。(见7.11节)如果指针具有DYNAMIC属性,则在下列约束下,可使用REDISTRIBUTE或REALIGN语句对任意与指针相关联的目标(该目标因此也具有DYNAMIC属性)进行重映射:

当且仅当指针是与整个数组而不是数组区域相关联时,可将指针在REALIGN和REDISTRIBUTE中用作对准子,对准目标和分配子。

注意:当一个对象被重映射时,新的映射对于任何同该对象相关联的指针来说都是可见的。

7.8.1 指针和子程序

如果一个指针哑参不是显式映射,则指针实参也不能显式映射。

如果一个指针哑参具有显式映射,则实参必须遵循上面所声明的关于指针赋值的规则,只有一个例外:如果实参具有DYNAMIC属性,则相应的哑参不必要具有DYNAMIC属性。即,154页第3条被弱化成:

3.如果指针哑参具有DYNAMIC属性,则相应实参也必须具有DYNAMIC属性。

另外,可使用范围说明(见7.11节)来限制实参的分配格式的集合。

指针哑参可具有DYNAMIC属性。在这种情况下,实参也必须具有DYNAMIC属性。在遵循最后一个分节中所声明的约束的前提下,可对与哑参相关联的目标进行重分配。依据Fortran规则,如果实参也是可见的(通过宿主或使用关联),则仅需通过哑参就可对目标进行重分配。如果对哑参进行了重分配,则当从过程返回时实参具有新的映射。在这种情况下,新映射必须匹配实参的范围约束(如果有的话)。


Copyright: NPACT BACKWARD FORWARD