gpt4 book ai didi

chapel - 嵌套归约——在 Chapel 中编写这些最惯用的方式是什么?

转载 作者:行者123 更新时间:2023-12-04 09:33:25 25 4
gpt4 key购买 nike

教堂缩减目前忽略变量的初始值。这意味着这段代码

var x: int;
for i in 1..3 {
forall j in 1..10 with (+ reduce x) {
x += 1;
}
}

writeln(x);

返回 10 而不是 30,正如该用户天真地认为的那样。虽然这种行为很好(并且记录在关于减少条款的注释中 - 我只是没有认真考虑过),但事实证明,如果我想获得 30(通过在两个循环中累积),我需要实际上是手工计算的。我认为 for 会非常优雅和对称循环也有 reduce意图......即我想写
var x: int;
for i in 1..3 with (+ reduce x) {
forall j in 1..10 with (+ reduce x) {
x += 1;
}
}

writeln(x);

请注意,即使在对数字求和的情况下,我也需要引入一个临时变量。对于类似 max/min 的操作,需要更加小心。

有什么理由不支持 reduce for 循环中的意图?或者,是否有更惯用的(Chapel-rrific)方式来做到这一点?

更新:我想得越多,我提议的代码在外部 for 的情况下是否有效并不明显。被 forall 取代.我认为问题在于变量是任务本地的而不是迭代本地的,因此减少只会发生在任务上。所以仍然需要一个单独的内部还原步骤。这将消除对临时变量的需要。

我认为更重要的问题是进行这些嵌套减少的正确方法是什么......

最佳答案

在我看来,这是 Chapel 的 reduce 意图设计中的一个疏忽。具体来说,虽然我认为每个任务在将其还原变量的个人副本初始化为身份时忽略原始变量的值是合适的(正如您所注意到的,目前已完成),但我相信任务的贡献应该合并回原始变量在并行循环结束时更改变量的值,而不是在它们相互组合时简单地覆盖原始值。这将使您的原始尝试按您的预期工作,并且还将遵循 OpenMP 的做法,如以下 C 示例所建议的,其结果为 35:

#include <stdio.h>
#include <omp.h>

int main(int argc, char* argv[]) {
int tot = 5;
for (int i=0; i<3; i++) {
#pragma omp parallel for reduction(+:tot)
for (int j=0; j<10; j++) {
tot += 1;
}
}
printf("tot is: %d\n", tot);
}

我建议在 Chapel GitHub issues page 上提交一个错误/功能请求来提倡这种行为。 .

从 Chapel 1.15.0 开始,解决此问题的一种方法是在串行循环中手动进行缩减,如下所示:
config var tot: int = 5;

for i in 1..3 {
var subtot: int;
forall j in 1..10 with (+ reduce subtot) do
subtot += 1;
tot += subtot;
}

writeln("tot is: ", tot);

关于chapel - 嵌套归约——在 Chapel 中编写这些最惯用的方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45111312/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com