我在尝试使用 Block 分发版进行编译时遇到了错误。这是错误:
error: unresolved access of '[BlockDom(3,int(64),false,unmanaged DefaultDist)] real(64)' by '[int(64), int(64)]'
Run Code Online (Sandbox Code Playgroud)
use Random, BlockDist;
config const size = 10;
const Space = {1..size, 1..size};
const gridSpace: domain(2) dmapped Block(boundingBox=Space);
var grid: [gridSpace] real;
var grid2: [gridSpace] real;
var grid3: [gridSpace] real;
fillRandom(grid);
fillRandom(grid2);
forall i in gridSpace do {
forall j in gridSpace do {
forall k in gridSpace do {
grid3[i,j] += grid[i,k] * grid2[k,j]; //error here
}
}
}
Run Code Online (Sandbox Code Playgroud)
当使用单个索引迭代 Chapel 中的多维域时,索引将具有域的索引类型。在上面的示例中,分布式域gridSpace
是一个二维域,因此使用单个索引对其进行迭代将产生 2 个整数的元组。
例如,
var dom = {1..2, 1..2};
for idx in dom {
writeln(idx); // index type is (int, int)
}
Run Code Online (Sandbox Code Playgroud)
将打印:
(1, 1)
(1, 2)
(2, 1)
(2, 2)
Run Code Online (Sandbox Code Playgroud)
使用 Chapel 1.19.0 编译您的示例时遇到的错误是:
error: unresolved access of '[BlockDom(2,int(64),false,unmanaged DefaultDist)] real(64)' by '[2*int(64), 2*int(64)]'
Run Code Online (Sandbox Code Playgroud)
这告诉我们,我们正试图用 2 个整数 ( ) 的2 个元组索引[BlockDom(2,int(64),false,unmanaged DefaultDist)]
实数 ( real(64)
)的块分布二维数组( [2*int(64), 2*int(64)]
)。
您可以更正上述示例的一种方法是显式迭代每个维度:
forall i in gridSpace.dim(1) {
forall j in gridSpace.dim(2) {
forall k in gridSpace.dim(1) {
grid3[i,j] += grid[i,k] * grid2[k,j];
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,请注意,最内层循环将进行多次迭代,尝试grid3
并行添加到相同的索引,从而造成数据竞争。
您可以通过使内循环串行来消除此数据竞争:
forall (i,j) in gridSpace {
for k in gridSpace.dim(2) {
grid3[i,j] += grid[i,k] * grid2[k,j];
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用+ 归约来处理内循环求和:
forall (i,j) in gridSpace {
grid3[i,j] = + reduce (grid[i,..]*grid2[..,j]);
}
Run Code Online (Sandbox Code Playgroud)
我注意到上面的代码还有另外两个问题:
gridSpace
只与一个类型和没有价值定义的,所以它实际上是一个空的分布域。您可以通过使用以下值对其进行初始化来解决此问题Space
:const gridSpace: domain(2) dmapped Block(boundingBox=Space) = Space;
Run Code Online (Sandbox Code Playgroud)
有关更多示例,请参阅发行版入门。
do
不需要在forall
上述循环。do
仅在为循环体的单表达式省略花括号时才需要,例如for i in dom do writeln(i);
Run Code Online (Sandbox Code Playgroud)
有关更多信息,请参阅for 循环指南。
归档时间: |
|
查看次数: |
57 次 |
最近记录: |