远程变量声明

时间:2017-11-01 02:44:10

标签: chapel

远程变量声明如何工作?我已尝试使用Chapel language specification的第26.2.1节中所述的on子句扩充普通变量声明,但它似乎不起作用。例如,这行代码:

on Locales[1] var x: [0..10] real;

无法编译,错误为syntax error: near 'var'

1 个答案:

答案 0 :(得分:5)

简而言之,语法已指定,但目前尚未实现。不幸的是,语言规范目前没有指出它是未来的功能。

感谢你指出这个问题。作为针对Chapel项目的GitHub问题,这个可以说是更好的,所以我创建了an issue to track the problem

典型的解决方法是选择以下之一:

  1. 使用嵌套的on语句来达到预期的效果
  2. on语句
  3. 中分配类实例
  4. 使用分布式阵列
  5. 我将在此描述每一个。

    首先,我们需要一个稍长的例子。假设您正在尝试写:

    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
    

    请注意,在示例中,我们知道分配将在Locale 0上进行。如果我们不知道我们运行的Locale,我们可以在第一个on之前将其保存到变量中(例如var fromLocale = here;)并在第二个on中使用该变量。

    在某些情况下,使用on语句指定变量的初始化位置而不更改声明的位置可能更方便。现在,这可以通过类实例来完成。请注意,这些不是垃圾回收 - 您需要使用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
    

    现在,我们如何使用分布式阵列实现相同的目标? 首先,考虑这个例子,它在运行Chapel程序的Locales之间分配11个元素。

    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