check/ensure 两个数组具有相同域和分布的最佳方法是什么?

What is the best way to check/ensure that two arrays have the same domain and distribution?

Chapel 的一个很好的特性是它区分数组的域和它的分布。检查两个数组是否具有相同的域和分布(通常需要哪个)的最佳方法是什么?

我能看到的最好的办法是检查 D1==D2D1.dist==D2.dist,如果 D1D2 都是域。

特别是考虑以下代码:

const Dom = {1..5, 1..5};
const BDom = newBlockDom(Dom);
var x : [Dom] int;
var y : [BDom] int;

test(x,y);

proc test(a : [?Dom1] int, b : [Dom1] int) {
}

这编译并运行得很好,如果函数声明中的查询语法只测试域相等性而不是分布相等性(即使 Dom1 也知道如何 a 分发)。在这种情况下检查分布是否相等的唯一方法是 a.domain.dist==b.domain.dist?

要检查两个域是否描述了 Chapel 中的相同分布式索引集,您使用 D1 == D2D1.dist == D2.dist 是正确的。 Chapel 中的域相等性检查两个域是否描述相同的索引集,因此独立于域映射/分布。类似地,两个域映射/分布之间的相等性检查检查它们是否相同地分布索引。

请注意,在 Chapel 中,域和分布都有身份的概念,因此如果您创建了两个分布式域,如下所示:

var BDom1 = newBlockDom(Dom),
    BDom2 = newBlockDom(Dom);

它们将通过上述相等性检查,但仍是不同的域值。在某些情况下,怀疑两个域表达式是否引用相同的域实例可能是合理的,但我相信今天在 Chapel 中没有官方的面向用户的方式来执行此操作。如果对此感兴趣,值得在我们的 GitHub issues 页面上提交功能请求。

关于您的代码示例:

const Dom = {1..5, 1..5};
const BDom = newBlockDom(Dom);
var x : [Dom] int;
var y : [BDom] int;

test(x,y);

proc test(a : [?Dom1] int, b : [Dom1] int) {
}

这里有一个需要解释的微妙之处。首先,请注意,如果您反转 test() 例程的参数,它将不会编译,其行为可能更类似于您所期望的 (TIO):

test(y,x);

原因是没有显式域映射的域在形式数组参数中被特殊对待。具体来说,在定义 Chapel 时,我们不想在此处声明像 X 这样的正式参数:

proc foo(X: [1..n] real) { ... }

要求实际数组参数是非分布式的/具有默认域映射。换句话说,我们希望用户能够传入从 1..n 索引的块或循环分布式数组,以便形式约束数组的索引集而不是其分布。相反,如果形式参数的域是根据显式域映射定义的,例如:

proc bar(X: [BDom] int) { ... }

(使用上面 BDom 的块分布式定义),它需要实际的数组参数来匹配该域。

这样做的一个效果是,在您的示例中,由于 Dom1 与具有默认域映射的域匹配,因此 b 同样被松散地限制为具有相同的索引集分配。而当第一个实际参数是块分布时(如在我的调用中),Dom1 对该分布进行编码并将约束应用于 b.

如果您对此的反应是感到困惑/不对称,我倾向于同意。我相信我们已经讨论过在这方面将 declared/named 域与匿名域区别对待(因为在采用此规则时我们关注的是 X: [1..n] 域的匿名性,以及它在查询域中的应用像 Dom1 这样的情况是当前实现的副作用)。同样,GitHub issue 将是质疑/挑战此行为的完全公平游戏。