4

最近,我遇到了教堂。我喜欢教程中给出的示例,但其中许多在我眼中是令人尴尬的平行。我正在研究多体量子物理学中的散射问题,一个常见问题可以简化为以下问题。

  1. A一个形状的张量用不同参数M x N x N的矩阵方程的解来填充M1..M
  2. 需要张量的一个子集A来计算每个参数的校正项1..M

问题的第一部分令人尴尬地平行。

因此,我的问题是,是否以及如何仅将所需的张量子集传输A到集群的每个区域并最小化必要的通信?

4

1 回答 1

3

当 Chapel 工作正常时,应该以有效的方式在分布式和本地数组(比如说)之间传输数组切片。这意味着您应该能够使用 Chapel 的数组切片表示法编写此类张量子集传输。

例如,这是编写这种模式的一种方法:

// define a domain describing a 5 x 7 x 3 index set anchored at index (x,y,z)
const Slice = {x..#5, y..#7, z..#3};

// create a new array variable that stores the elements from distributed array 
// `myDistArray` locally
var myLocalArray = myDistArray[Slice];

新变量myLocalArray将是一个数组,其元素是 in 中的元素的副本,myDistArray如 中的索引所述Slice。的域myLocalArray将是切片域Slice,因此由于Slice是非分布式域,myLocalArray因此也将是本地/非分布式数组,因此在操作时不会产生使用 Chapel 的分布式数组表示法的任何开销当前语言环境。

迄今为止,我们主要专注于优化块分布式阵列的此类传输。例如,对于上述示例的情况,当 myDistArray 是块分布的时,我看到区域设置之间的通信数量是固定的,因为我改变了切片的大小(尽管这些通信的大小显然会根据需要传输的元素数量)。已知其他案例和模式需要更多优化工作,因此如果您发现一个案例没有按预期执行/扩展,请针对它提交Chapel GitHub 问题,以帮助提醒我们您的需求和/或帮助你找到一个解决方法。

所以,勾勒出你描述的模式,我可能会想象做这样的事情:

// create a local and distributed version of the complete tensor space
const LocTensorSpace = {1..M, 1..N, 1..N},
      TensorSpace = LocTensorSpace dmapped Block(LocTensorSpace);

// declare array A to store the result of step 1
var A: [TensorSpace] real;

// ...compute A here...

// declare a 1D distributed form of the parameter space to drive step 2    
const ParameterSpace = {1..M} dmapped Block({1..M});

// loop over the distributed parameter space; each locale will use all its cores
// to compute on its subset of {1..M} in parallel
forall m in ParameterSpace {
  // create a local domain to describe the indices you want from A
  const TensorSlice = { /* ...whatever indices you need here... */ };

  // copy those elements into a local array
  var locTensor = A[TensorSlice];

  // ...compute on locTensor here...
}

其他一些似乎与我有关,但我不想让这个问题陷入困境的事情是:

  • 如果需要,可以声明 TensorSpace / A 使得只有 1..M 维度分布在区域设置中,并且 {1..N, 1..N} 平面是局部的
  • 还有一些方法可以查询语言环境拥有的分布式数组的索引;结合上一点,假设步骤 2 的迭代与 A 的平面之间存在对应关系,这可能是一种减少所需通信量的方法
  • 还有一些方法可以就地引用分布式数组切片和/或给它一个符号名称,而不是像上面建议的那样创建它的本地副本
  • 如果需要/首选 A 可以声明为 2D 数组的 1D 分布式数组,但如果您想访问空间的 3D 切片,这可能不太好

(因此,如果您对这些感兴趣,请随时提出后续问题)

最后,为了子孙后代,这是我在将这个响应放在一起时编写的程序,以确保我在通信数量和获得本地数组方面得到我期望的行为(chpl version 1.23.0 pre-release (ad097333b1)虽然我'd 期望最近版本的 Chapel 有相同的行为:

use BlockDist, CommDiagnostics;

config const M = 10, N=20;

const LocTensorSpace = {1..M, 1..N, 1..N},
      TensorSpace = LocTensorSpace dmapped Block(LocTensorSpace);

var A: [TensorSpace] real;

forall (i,j,k) in TensorSpace do
  A[i,j,k] = i + j / 100.0 + k / 100000.0;


config const xs = 5, ys = 7, zs = 3,            // size of slice                
             x = M/2-xs/2, y = N/2-ys/2, z = N/2-zs/2;  // origin of slice      


const Slice = {x..#xs, y..#ys, z..#zs};

writeln("Copying a ", (xs,ys,zs), " slice of A from ", (x,y,z));

resetCommDiagnostics();
startCommDiagnostics();

var myLocArr = A[Slice];

stopCommDiagnostics();
writeln(getCommDiagnostics());

writeln(myLocArr);
writeln(myLocArr.isDefaultRectangular());
于 2020-06-08T19:55:10.447 回答