在 Chapel 中将数组类型限制为具有连续数据的本地数组的最佳方法是什么?

What is the best way to constrain the type of an array to be a local array with contiguous data in Chapel?

考虑以下 Chapel 功能:

proc myfunc(arr : []?T) {}

我想保证数组(在编译时)是

  1. 本地
  2. 底层数据存储在一个连续的内存块中。

最好的方法是什么?

一个可能的应用是在 myfunc 中调用 C 函数的情况。如果满足 1 和 2,则在编译时执行此操作作为约束可能允许重载 myfunc 以采用快速路径。

不幸的是,从 Chapel 1.22 开始,没有正式的面向用户的方式来进行此类查询,尽管在 Chapel's GitHub issues page 上提交功能请求以请求此类功能是合理的。这样做时,请注意,了解数组是否存储在单个连续块中与存储在单个区域设置与本地存储之间存在细微差别(例如,数组可以存储在单个连续块中但在distinct/remote 来自进行查询的语言环境)。 Chapel 编译器通常可以静态地回答前两个查询,但第三个查询只能动态回答,因为通常不可能在编译时推断出存储变量的语言环境。

同时可能用作权宜之计的内部/面向开发人员的查询是 .isDefaultRectangular() 查询,它是为域和数组实现的,并依赖于在实现中进行此类查询。它指示是否使用矩形域和数组的默认域映射来实现域或数组。这个域映射本质上是非分布式的,并且是连续存储的。以下示例显示其行为 (TIO):

use CyclicDist;

// declare a local / non-distributed domain and array
var Dloc = {1..3, 1..3};
var Aloc: [Dloc] real;

// declare a cyclically-distributed domain and array
var Ddist = {1..3, 1..3} dmapped Cyclic((1,1));
var Adist: [Ddist] real;

// generic function that queries whether or not its argument uses the
// default rectangular domain map
proc testit(name, X) {
  writeln(name, ".isDefaultRectangular() = ", X.isDefaultRectangular());
}

// various calls to the generic function
testit("Dloc", Dloc);
testit("Aloc", Aloc);
testit("Ddist", Ddist);
testit("Adist", Adist);
testit("slice", Aloc[2..3, 2..3]);

其中输出为:

Dloc.isDefaultRectangular() = true
Aloc.isDefaultRectangular() = true
Ddist.isDefaultRectangular() = false
Adist.isDefaultRectangular() = false
slice.isDefaultRectangular() = false

这个查询returns一个param结果,表明它的结果在编译时是已知的。因此,当它 returns true 时,它表示数组存储在单个区域设置的单个块中,但并没有说明它是否是查询所在的区域设置 运行。为此,需要使用执行时间 X.locale == here 检查。

另外,请注意,对于局部数组的切片,它 returns 为 false。这可能是也可能不是您想要的,因为尽管底层数组仍然是连续的和局部的,但切片描述的元素不一定是。