7.10 新的分配格式 BACKWARD FORWARD


本节描述两个新的分配格式。我们可以将句法扩展成下列形式化形式:

H701 extended-dist-format   is BLOCK[(int-expr)]
                   or CYCLIC[(int-expr)]
                    or GEN_BLOCK(int-array)
                   or INDIRECT(int-array)
                    or *

约束:出现在DISTRIBUTE或REDISTRIBUTE指令extended-dist-format中的整数数组(int-array)必须是一个一维整数数组。

约束:出现在DISTRIBUTE指令extended-dist-format中的整数数组(int-array)必须是一个受限表达式。

约束:以GEN_BLOCK分配方式出现的任意整数数组(int-array)的大小必须等于目标处理器排列相应维的范围。

约束:以INDIRECT分配方式出现的任意整数数组(int-array)的大小必须等于此分配所应用的分配子相应维的范围。

一般化的分配方式,“GEN_BLOCK”,允许将一个数组的相邻段(这些段可能大小不等)映射到处理器上。这些段的大小由一个用户定义整数映射数组的值所指定,每个映射目标处理器一个值。即,映射数组的第i个元素指定了存储到目标处理器排列第i个处理器上的块的大小。这样,映射数组的值被限制为非负的且它们的和必须大于或等于被分配数组相应维的范围。

当映射数组用于DISTRIBUTE指令时,它必须是一个受限表达式,但在REDISTRIBUTE指令中它可以是一个数组变量。在后面的情形中,当指令执行完后,改变映射数组的值不会改变被分配数组的映射。

令l和u是分配子维的上下界,MAP是映射数组且令BS(i):BE(i)是映射到目标处理器排列相应维第i个处理器上的结果元素。则

  BS(1)=l,
  BE(i)=max(BS(i)+MAP(i)-1,u),
  BS(i)=BE(i-1)+1

例子:

     PARAMETER (S = /2,25,20,0,8,65/)
 !HPF$ PROCESSORS P(6)
     REAL A(100), B(200), new(6)
 !HPF$ DISTRIBUTE A( GEN_BLOCK( S) ) ONTO P
 !HPF$ DYNAMIC B
    ...
    new = ...
 !HPF$ REDISTRIBUTE ( B( GEN_BLOCK(new) )

根据上面的说明,数组元素A(1:2)被映射到P(1)上,A(3:27)被映射到P(2)上,A(28:37)被映射到P(3)上,没有元素被映射到P(4)上,数组元素A(38:45)被映射到P(5)上,A(46:200)被映射到P(6)上。数组B基于数组new进行分配,new的值在运行时计算。

对实现者的建议:访问使用一般化块分配方式进行分配的数组元素可能需要在运行时访问映射数组的值。可是,因为这种数组的大小等于处理器排列的大小,所以在大多数情况下,可将它复制到所有的处理器上。

对于动态数组,映射数组的一个独立拷贝必须被内部维护以便改变映射数组的值不影响分配数组的访问。(对实现者的建议结束)

在许多科学应用中,它们的基本域结构不能直接映射到Fortran数据结构上。例如,在许多CFD应用中,使用一个非结构化的网眼(mesh)(包括二维中的三角形或三维中的四面体)来描述基本域。这样一个mesh的节点一般来说用一个一维数组来描述而用另一个一维数组来描述它们的互联关系。使用结构化的分配机制(BLOCK和CYCLIC)来映射这种数组会导致许多无关元素被映射到同一处理器上。这样的结果是导致大量的不必要的通信。我们所需要的机制是能够将任意相关的数组元素的集合映射到同一处理器上。INDIRECT分配就提供了这样一种机制。

INDIRECT分配允许一个多对一的映射,即将数据数组某一维的元素映射到目标处理器排列的某一维上。使用一个整数数组来指定被分配的数组维上的每个个体元素的目标处理器。即,映射数组的第i个元素提供了第i个数组元素将要映射到的处理器号。由于映射数组将数组元素映射到处理器元素上,因此映射数组的范围必须同它所分配的数组维的范围相匹配。另一方面,映射数组的值必须介于处理器排列目标维的上下界之间。

当映射数组用于DISTRIBUTE指令中时,它必须是一个受限表达式,但当用于REDISTRIBUTE指令中时,它可以是一个数组变量。在后面的情形中,当指令执行完后,改变映射数组的值不会改变被分配数组的映射。

例子:

 !HPF$ PROCESSORS P(4)
     REAL A(100), B(50)
     INTEGER map1(100), map2(50)
     PARAMETER (map1 = /1,3,4,3,3,2,1,4, ..../)
 !HPF$ DYNAMIC B
 !HPF$ DISTRIBUTE A( INDIRECT(map1) ) ONTO P
 !HPF$ DISTRIBUTE map2(BLOCK) ONTO P

     map2 = ...
 !HPF$ DISTRIBUTE B( INDIRECT(map2) ) ONTO P
     ....

在这里,使用常数数组map1对数组A进行了静态分配。这样:

 A(1)被映射到P(1)上,
 A(2)被映射到P(3)上,
 A(3)被映射到P(4)上,
 A(4)被映射到P(3)上,
 A(5)被映射到P(3)上,
 A(6)被映射到P(2)上,
 A(7)被映射到P(1)上,
 A(8)被映射到P(4)上,等等。

数组B被定义成动态的,并通过映射数组map2对其重分配。

对实现者的建议:一般来说,INDIRECT分配将被用于REDISTRIBUTE指令中,并以一个数组变量作为映射数组。另一方面,由于映射数组的大小必须等于被分配数组的大小,因此最有可能使用BLOCK分配方式对其自身进行分配。这样就引起一些问题。为正确实现这一分配方式,运行时系统应该维护映射数组的一个(被分配)的拷贝,以便当程序修改映射数组时,分配方式不会改变。用一个数组变量作为映射数组意味着每个数组元素的位置只有到运行时才能知道。这样,可能需要一次通信来计算指定数组元素的位置。(对实现这的建议结束)


Copyright: NPACT BACKWARD FORWARD