远程变量声明
Remote variable declarations
远程变量声明是如何工作的?我已经尝试按照 Chapel language specification 的第 26.2.1 节中的描述使用 on 子句来扩充普通变量声明,但它似乎不起作用。比如这行代码:
on Locales[1] var x: [0..10] real;
编译失败,错误syntax error: near 'var'
。
简而言之,语法已指定,但目前尚未实现。不幸的是,语言规范目前没有指出这是未来的功能。
感谢您指出问题。这个可以说是针对 Chapel 项目的 GitHub 问题,所以我创建了 an issue to track the problem.
典型的解决方法是选择以下之一:
- 使用嵌套的
on
语句达到预期效果
- 在
on
语句中分配一个 class 实例
- 使用分布式数组
下面我一一介绍。
首先,我们需要一个稍微长一点的例子。假设您尝试写:
on Locales[1] var A: [0..10] real; // declare array stored on Locales[1]
A = 1; // on Locale 0, set every element of A to 1
writeln(A); // on Locale 0, print out the array
// print out the locale storing each element
for x in A {
write(x.locale.id, " ");
}
writeln();
使用嵌套 on
语句编写的等效方法是:
on Locales[1] {
var A: [0..10] real;
on Locales[0] {
A = 1;
writeln(A);
for x in A {
write(x.locale.id, " ");
}
writeln();
}
}
// result, when run on 2 locales:
// from printing array elements:
// 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
// from printing element locales:
// 1 1 1 1 1 1 1 1 1 1 1
请注意,在示例中,我们知道分配将发生在区域设置 0 上。如果我们不知道我们 运行 所在的区域设置,我们可以将其保存到变量中第一个 on
(例如 var fromLocale = here;
)并在第二个 on
.
中使用该变量
在某些情况下,使用 on
语句指定变量的初始化位置而不更改其声明位置可能更方便。现在,这可以用 class 个实例来完成。请注意,这些不是垃圾收集 - 您需要使用 Owned/Shared 或确保调用 delete
。
本着更简单地回答问题的精神,我将展示一个调用 delete
.
的版本
class MyArrayWrapper {
var A: [0..10] real;
}
var myObject: MyArrayWrapper; // starts out as nil
on Locales[1] {
// set myObject to a new instance
// since we do that on Locales[1], it is allocated there
// and the contained array is stored there too.
myObject = new MyArrayWrapper();
}
myObject.A = 1;
writeln(myObject.A);
for x in myObject.A {
write(x.locale.id, " ");
}
writeln();
delete myObject;
// result, when run on 2 locales:
// from printing array elements:
// 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
// from printing element locales:
// 1 1 1 1 1 1 1 1 1 1 1
现在,我们如何使用分布式数组实现相同的目的?
首先,考虑这个例子,它将 11 个元素分布在 Chapel 程序 运行 所使用的任何语言环境中。
use BlockDist;
const MyDom = {0..10}; // this domain represents the index set 0..10
// declare a Block-distributed index set 0..10
// by default, this is distributed over all available Locales
const MyBlockDistributedDomain = MyDom dmapped Block(boundingBox=MyDom);
// declare an Block-distributed array
var BlockDistributedA: [MyBlockDistributedDomain] real;
BlockDistributedA = 1;
writeln(BlockDistributedA);
for x in BlockDistributedA {
write(x.locale.id, " ");
}
writeln();
// result, when run on 2 locales:
// from printing array elements:
// 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
// from printing element locales:
// 0 0 0 0 0 0 1 1 1 1 1
这将数组分布在可用的语言环境中,但该行为只是 Block 分布的默认行为。我们可以使用 Block 构造函数的参数指定语言环境,如下例所示:
use BlockDist;
const MyDom = {0..10};
// This time, specify the target locales for the Block distribution to use.
// Here we pass in an anonymous array storing just Locales[1], so that
// the resulting array only stores elements on Locales[1].
const MyDistributedDomain = MyDom dmapped Block(boundingBox=MyDom,
targetLocales=[Locales[1]]);
var DistributedA: [MyDistributedDomain] real;
DistributedA = 1;
writeln(DistributedA);
for x in DistributedA {
write(x.locale.id, " ");
}
writeln();
// result, when run on 2 locales:
// from printing array elements:
// 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
// from printing element locales:
// 1 1 1 1 1 1 1 1 1 1 1
远程变量声明是如何工作的?我已经尝试按照 Chapel language specification 的第 26.2.1 节中的描述使用 on 子句来扩充普通变量声明,但它似乎不起作用。比如这行代码:
on Locales[1] var x: [0..10] real;
编译失败,错误syntax error: near 'var'
。
简而言之,语法已指定,但目前尚未实现。不幸的是,语言规范目前没有指出这是未来的功能。
感谢您指出问题。这个可以说是针对 Chapel 项目的 GitHub 问题,所以我创建了 an issue to track the problem.
典型的解决方法是选择以下之一:
- 使用嵌套的
on
语句达到预期效果 - 在
on
语句中分配一个 class 实例 - 使用分布式数组
下面我一一介绍。
首先,我们需要一个稍微长一点的例子。假设您尝试写:
on Locales[1] var A: [0..10] real; // declare array stored on Locales[1]
A = 1; // on Locale 0, set every element of A to 1
writeln(A); // on Locale 0, print out the array
// print out the locale storing each element
for x in A {
write(x.locale.id, " ");
}
writeln();
使用嵌套 on
语句编写的等效方法是:
on Locales[1] {
var A: [0..10] real;
on Locales[0] {
A = 1;
writeln(A);
for x in A {
write(x.locale.id, " ");
}
writeln();
}
}
// result, when run on 2 locales:
// from printing array elements:
// 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
// from printing element locales:
// 1 1 1 1 1 1 1 1 1 1 1
请注意,在示例中,我们知道分配将发生在区域设置 0 上。如果我们不知道我们 运行 所在的区域设置,我们可以将其保存到变量中第一个 on
(例如 var fromLocale = here;
)并在第二个 on
.
在某些情况下,使用 on
语句指定变量的初始化位置而不更改其声明位置可能更方便。现在,这可以用 class 个实例来完成。请注意,这些不是垃圾收集 - 您需要使用 Owned/Shared 或确保调用 delete
。
本着更简单地回答问题的精神,我将展示一个调用 delete
.
class MyArrayWrapper {
var A: [0..10] real;
}
var myObject: MyArrayWrapper; // starts out as nil
on Locales[1] {
// set myObject to a new instance
// since we do that on Locales[1], it is allocated there
// and the contained array is stored there too.
myObject = new MyArrayWrapper();
}
myObject.A = 1;
writeln(myObject.A);
for x in myObject.A {
write(x.locale.id, " ");
}
writeln();
delete myObject;
// result, when run on 2 locales:
// from printing array elements:
// 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
// from printing element locales:
// 1 1 1 1 1 1 1 1 1 1 1
现在,我们如何使用分布式数组实现相同的目的? 首先,考虑这个例子,它将 11 个元素分布在 Chapel 程序 运行 所使用的任何语言环境中。
use BlockDist;
const MyDom = {0..10}; // this domain represents the index set 0..10
// declare a Block-distributed index set 0..10
// by default, this is distributed over all available Locales
const MyBlockDistributedDomain = MyDom dmapped Block(boundingBox=MyDom);
// declare an Block-distributed array
var BlockDistributedA: [MyBlockDistributedDomain] real;
BlockDistributedA = 1;
writeln(BlockDistributedA);
for x in BlockDistributedA {
write(x.locale.id, " ");
}
writeln();
// result, when run on 2 locales:
// from printing array elements:
// 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
// from printing element locales:
// 0 0 0 0 0 0 1 1 1 1 1
这将数组分布在可用的语言环境中,但该行为只是 Block 分布的默认行为。我们可以使用 Block 构造函数的参数指定语言环境,如下例所示:
use BlockDist;
const MyDom = {0..10};
// This time, specify the target locales for the Block distribution to use.
// Here we pass in an anonymous array storing just Locales[1], so that
// the resulting array only stores elements on Locales[1].
const MyDistributedDomain = MyDom dmapped Block(boundingBox=MyDom,
targetLocales=[Locales[1]]);
var DistributedA: [MyDistributedDomain] real;
DistributedA = 1;
writeln(DistributedA);
for x in DistributedA {
write(x.locale.id, " ");
}
writeln();
// result, when run on 2 locales:
// from printing array elements:
// 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
// from printing element locales:
// 1 1 1 1 1 1 1 1 1 1 1