11.3 HPF捆绑 BACKWARD FORWARD


HPF是缺省的语言假设。它在接口定义中不要求map-to属性。可通过标准Fortran显式接口完成所有所需的子程序捆绑信息。Fortran标准14.7节中所指定的规则适用于基于Fortran的SERIAL和LOCAL作用于单元中所定义的变量。特别是,如果一个变量的定义状态,关联状态或分配空间状态是基于Fortran子程序中RETURN语句或END语句的执行定义的,则在SERIAL或LOCAL子程序中将基于RETURN语句或END语句的执行定义这种变量。

不同模型的外部子程序中所执行的任意I/O,文件名的对应性以及用于全局HPF和本地或串行子程序代码的单元号都将在实现时定义。

11.3.1 为HPF_LOCAL附加的特殊考虑

关于在书写一个本地,每个处理器过程时可以使用什么HPF特征有一些考虑。

本地程序单元可使用除REDISTRIBUTE和REALIGN之外的所有HPF结构。而且,DISTRIBUTE,ALIGN,以及INHERIT指令仅适用于哑参;也就是说,每个对准子和分配子都必须是哑参,且每个对准目标必须是模板或哑参。本地HPF程序单元中的映射指令被理解为具有全局意义,就好象它们已经出现在全局HPF代码中,适用于全局数组,该数组各部分在每个处理器上传递。这种映射指令的主要用途是在全局HPF模块所使用的HPF_LOCAL模块中。)

分配查询库子程序,HPF_ALIGNMENT,HPF_TEMPLATE和HPF_DISTRIBUTION,可适用于非顺序本地数组。它们的输出等同于将它们用于全局数组,该数组碰巧在一个单节点上具有所有的元素。

正如5.3.1节所介绍的,一个本地HPF程序单元不能通过实参直接或间接地访问除了可访问数据之外的全局HPF数据。特别是,本地HPF程序单元不能访问全局HPF COMMON块;出现在本地HPF程序单元中的COMMON块不能用全局HPF COMMON块标志。在一个本地HPF程序单元中和同一执行程序的HPF程序单元中都不能使用同样的名字来标志一个COMMON块。

本地HPF COMMON块定义了包含在每个处理器上的存储;每个处理器都具有其自身的全体COMMON块的私有拷贝且仅能访问其自己的私有拷贝。

与LOCAL子程序的本地变量一样,本地子程序中的COMMON包含了本地数据,保存在每个处理器的本地存储器中。这种存储所包含的数据一般来说在每个处理器上都是不同的。实际上,本地COMMON块的大小在每个处理器上是不同的。

根据Fortran说明,不保留作用于范围之外的COMMON块,除非它具有SAVE属性。对于本地COMMON块也是这样的,如果它们试图在子程序的调用之间传递信息,就应给这些COMMON块以SAVE属性。

一个显式映射派生类型的标量不能传给HPF_LOCAL子程序。

哑参的属性(类型,类,维数,选项,意图)必须与显式接口中相应哑参的属性匹配。EXTRINSIC(HPF_LOCAL)例程的哑参不能是一个过程名。

EXTRINSIC(HPF_LOCAL)例程的哑参不能具有POINTER属性。

即使在接口中具有显式形状,EXTRINSIC(HPF_LOCAL)例程的一个非顺序数组哑参也必须具有假定的形状。注意,一般来说,哑数组参数的形状不同于相应实参的形状,除非有一个单执行处理器。

哑参的显式映射指令可出现在本地过程中。这些指令被认为适用于全局数组,该数组的本地区域在每个处理器上作为实参或结果传递。如果出现这种指令,相应的映射指令必须对于每个全局HPF调用者都是可见的。可通过在调用者中提供一个接口块做到这一点,或者通过将本地过程放在外部类HPF_LOCAL的模块中做到这一点,该模块紧接着被调用本地过程的全局HPF程序单元所使用。

一个本地过程可以具有几个入口点。一个全局HPF调用者必须为每个可从HPF程序中引用的入口点包含一个分离的外部接口。

11.3.2 参数相联

EXTRINSIC(HPF_LOCAL)例程的哑参是一个标量,则本地过程的相应哑参必须是同种类型和类参数的标量。只有那些没有显式映射的内部类型或派生类型的标量可以从全局例程中传给HPF_LOCAL例程。当引用外部过程时,传送给本地过程一个包含重复标量本地拷贝的参数。这个拷贝将是一个有效的HPF标量。

如果EXTRINSIC(HPF_LOCAL)例程的哑参是一个数组,则本地过程说明中相应的哑参必须是一个具有相同维数,类型和类参数的数组。如果数组在外部接口中是顺序的,则相应的实参就象传递标量参数一样,将通过在所有处理器上重复传递。每个本地哑参将与实数组参数的一个完整拷贝相关联。外部接口中的哑参和本地过程说明中相应哑参可用相同的显式形状定义。通过复制传送给EXTRINSIC(HPF_LOCAL)过程的所有顺序哑参必须或者式INTENT(IN)参数或者应跨越处理器被一致性更新。

如果哑参是一个非顺序数组,则当引用一个外部过程时,本地哑参与某本地数组相关联,该数组包含了存储在本地的全局数组的子网格。这个本地数组将是一个有效的HPF数组。

如果EXTRINSIC(HPF_LOCAL)例程是一个函数,则本地过程作为HPF外部函数返回一个相同类型和类型参数的标量。每个本地引用所返回的值必须是相同的。

每个物理处理器具有每个HPF变量的至多一个拷贝。

考虑下列外部接口:

   INTERFACE
    EXTRINSIC(HPF_LOCAL) FUNCTION MATZOH(X, Y) RESULT(Z)
     REAL, DIMENSION(:,:) :: X
     REAL, DIMENSION(SIZE(X,1)) :: Y
     REAL Z  
!HPF$   ALIGN WITH X(:,*) :: Y(:)
!HPF$   DISTRIBUTE X(BLOCK, CYCLIC)
    END FUNCTION
   END INTERFACE

相应的本地HPF过程被指定为如下:

  EXTRINSIC(HPF_LOCAL) FUNCTION MATZOH(XX, YY) RESULT(ZZ)
  REAL, DIMENSION(:,:) :: XX
  REAL, DIMENSION(5 : SIZE(XX,1)+4) :: YY
  REAL ZZ
  NX1 = SIZE(XX, 1)
  LX1 = LBOUND(XX, 1)
  UX1 = UBOUND(XX, 1)
  NX2 = SIZE(XX, 2)
  LX2 = LBOUND(XX, 2)
  UX2 = UBOUND(XX, 2)
  NY = SIZE(YY, 1)
  LY = LBOUND(YY, 1)
  UY = UBOUND(YY, 1)
  ...
  END FUNCTION

假定在一个4处理器机器上用形状为3*3的实(全局)数组X和一个长为3的实向量Y引用此函数,所使用的处理器排列是2*2(假定每个物理处理器一个抽象处理器)。

则函数MATZOH的每个本地引用收到下列实参数:

   Processor(1,1)        Processor(1,2)

   X(1,1) X(1,3)        X(1,2)
   X(2,1) X(2,3)        X(2,2)

   Y(1)             Y(1)
   Y(2)             Y(2)

   Processor(2,1)        Processor(2,2)

   X(3,1) X(3,3)        X(3,2)

   Y(3)             Y(3)

这里的值是每个处理器为NX1,LX1,UX1,NX2,LX2,UX2,NY,LY,和UY所置的值:

   Processor(1,1)        Processor(1,2)

   NX1=2 LX1=1 UX1=2       NX1=2 LX1=1 UX1=2
   NX2=2 LX2=1 UX2=2       NX2=1 LX2=1 UX2=1
    NY=2 LY=5 UY=6        NY=2 LY=5 UY=6

   Processor(2,1)        Processor(2,2)

   NX1=1 LX1=1 UX1=1       NX1=1 LX1=1 UX1=1
   NX2=2 LX2=1 UX2=2       NX2=1 LX2=1 UX2=1
    NY=1 LY=5 UY=5       NY=1 LY=5 UY=5

外部过程的实参可以是一个指针。由于相应的哑参不能具有POINTER属性,哑参变得与HPF全局指针的目标向关联。任何方式下一个本地指针都不能成为与一个全局HPF目标相关联的指针。因此,实参不能是包含指针部件的派生类型。

基本原理:希望全局指针变量与本地指针变量具有不同的描述,至少在分布存储的机器上是这样的,这是因为对于全局编址需要执行额外的信息。将来这一约束可能会去掉。(基本原理结束)

其他的查询内部函数,诸如ALLOCATED或者PRESENT,也应该象期望的那样执行。注意,一个全局数组传递给一个本地例程时,一些处理器可能会收到一个空元素集合。

11.3.3 HPF_SERIAL的特殊考虑

有一些约束适用于HPF_SERIAL子程序。

不允许说明指令,重对准指令或重分配指令出现在一个HPF_SERIAL子程序中或接口体中。

基本原理:一个HPF映射指令在HPF_SERIAL子程序中可能是没有意义的。但是注意,INDEPENDENT指令可以出现在HPF_SERIAL子程序中,这是因为它可向编译器提供关于DO循环或者FORALL语句或结构的有用信息。(基本原理结束)

HPF_SERIAL过程的任何哑数据对象以及任何函数结果变量都被认为是顺序的。

HPF_SERIAL子程序不能包含同HPF或者HPF_LOCAL程序单元所定义的公共块具有相同名字的公共块的定义。另外,如果HPF或者HPF_LOCAL程序单元具有空白公共块的定义,则HPF_SERIAL子程序不能包含空白公共块的定义。

全局HPF中所引用的HPF_SERIAL过程的哑参或者函数结果变量不能具有POINTER属性。全局HPF中所引用的HPF_SERIAL过程的哑参的子对象或者函数结果不能具有POINTER属性。

全局HPF中所引用的HPF_SERIAL过程的哑参以及这种哑参的任意子对象不能具有TARGET属性。

HPF_SERIAL过程的哑过程参数必须是HPF_SERIAL过程。

   PROGRAM MY_TEST
    INTERFACE
     EXTRINSIC(HPF_SERIAL) SUBROUTINE GRAPH_DISPLAY(DATA)
      INTEGER, INTENT(IN) :: DATA(:, :)
     END SUBROUTINE GRAPH_DISPLAY
    END INTERFACE

    INTEGER, PARAMETER :: X_SIZE = 1024, Y_SIZE = 1024

    INTEGER DATA_ARRAY(X_SIZE, Y_SIZE)
 !HPF$ DISTRIBUTE DATA_ARRAY(BLOCK, BLOCK)

 ! 计算DATA_ARRAY
     ...
     CALL DISPLAY_DATA(DATA_ARRAY)
   END PROGRAM MY_TEST

 ! 图形显示子程序的定义.
 ! 在一些依赖于实现的方式中,
 ! 将在DATA中画出一个数据图。

   EXTRINSIC(HPF_SERIAL) SUBROUTINE GRAPH_DISPLAY(DATA)
    INTEGER, INTENT(IN) :: DATA(:, :)
    INTEGER :: X_IDX, Y_IDX

    DO Y_IDX = LBOUND(DATA, 2), UBOUND(DATA, 2)
     DO X_IDX = LBOUND(DATA, 1), UBOUND(DATA, 1)
      ...
     END DO
    END DO
   END SUBROUTINE GRAPH_DISPLAY


Copyright: NPACT BACKWARD FORWARD