Chapel中的用户定义函数具有奇怪的行为.type vs .eltType

时间:2018-05-16 22:31:52

标签: chapel

我想写一个连接函数,所以我想出了

proc concat(x:[], y:[]) {
  const d:int = x.size + y.size;
  var v:[1..d] x.type;

  writeln("\n d: ", d);
  writeln("\n x.domain: ", x.domain);
  writeln("\n y.domain: ", y.domain);
  var k = 1;
  for i in x.domain {
    v[k] = x[i];
    writeln("i: ", i, " k: ", k,  " x[i]: ", x[i], " v[k]: ", v[k]);
    k += 1;
  }
  for i in y.domain {
    v[k] = y[i];
    writeln("i: ", i, " k: ", k, " y[i]: ", y[i], " v[k]: ", v[k]);
    k += 1;
  }
  writeln("\n v: ", v);

  return v;
}

但它有一个非常奇怪的输出

var x: [1..3] real = [1.1, 2.2, 3.3],
    y: [9..11] real = [9.9, 10.10, 11.11];

var z = concat(x,y);
writeln(z);

可生产

 d: 6

 x.domain: {1..3}

 y.domain: {9..11}
i: 1 k: 1 x[i]: 1.1 v[k]: 1.1 1.1 1.1
i: 2 k: 2 x[i]: 2.2 v[k]: 2.2 2.2 2.2
i: 3 k: 3 x[i]: 3.3 v[k]: 3.3 3.3 3.3
i: 9 k: 4 y[i]: 9.9 v[k]: 9.9 9.9 9.9
i: 10 k: 5 y[i]: 10.1 v[k]: 10.1 10.1 10.1
i: 11 k: 6 y[i]: 11.11 v[k]: 11.11 11.11 11.11

 v: 1.1 1.1 1.1 2.2 2.2 2.2 3.3 3.3 3.3 9.9 9.9 9.9 10.1 10.1 10.1 11.11 11.11 11.11
1.1 1.1 1.1 2.2 2.2 2.2 3.3 3.3 3.3 9.9 9.9 9.9 10.1 10.1 10.1 11.11 11.11 11.11

这有点神秘。

1 个答案:

答案 0 :(得分:2)

看起来您的代码混淆了.type.eltType。给定像var A: [1..3] real;这样的数组变量,A.type实际上是[1..3] real,而A.eltType只是real。所以当你宣布:

var v:[1..d] x.type;

而不是获取您想要的real值数组,而不是实际声明一个数组,其元素本身就是real值的数组。

然后,由于Chapel支持从标量到数组的提升赋值(例如,A = 0.0将一个简单的方法将上面的A数组清零),当你复制元素时原始数组到vv的每个数组元素都将值存储在每个位置,导致值的三次重复。

v的声明更改为:

var v:[1..d] x.eltType;

应该给你你想要的东西。 Here's the corrected version online

var x: [1.. 3] real = [1.1, 2.2, 3.3],
    y: [9..11] real = [9.9, 10.10, 11.11];

var z = concat( x, y );
writeln( z );

proc concat( x:[], y:[] ) {
     const d:int = x.size + y.size;
  // var   v:[1..d] x.type;    // ------------------------------------ FAIL
                               /*     d: 6
                               x.domain: {1..3}
                               y.domain: {9..11}

                               i:   1, k:   1, x[i]:    1.10, v[k]: 1.1 1.1 1.1
                               i:   2, k:   2, x[i]:    2.20, v[k]: 2.2 2.2 2.2
                               i:   3, k:   3, x[i]:    3.30, v[k]: 3.3 3.3 3.3
                               i:   9, k:   4, y[i]:    9.90, v[k]: 9.9 9.9 9.9
                               i:  10, k:   5, y[i]:   10.10, v[k]: 10.1 10.1 10.1
                               i:  11, k:   6, y[i]:   11.11, v[k]: 11.11 11.11 11.11

                               v:
                               1.1 1.1 1.1 2.2 2.2 2.2 3.3 3.3 3.3 9.9 9.9 9.9 10.1 10.1 10.1 11.11 11.11 11.11
                               1.1 1.1 1.1 2.2 2.2 2.2 3.3 3.3 3.3 9.9 9.9 9.9 10.1 10.1 10.1 11.11 11.11 11.11
                               */
     var   v:[1..d] x.eltType; // ------------------------------------ PASS
                               /*     d: 6
                               x.domain: {1..3}
                               y.domain: {9..11}

                               i:   1, k:   1, x[i]:    1.10, v[k]: 1.1
                               i:   2, k:   2, x[i]:    2.20, v[k]: 2.2
                               i:   3, k:   3, x[i]:    3.30, v[k]: 3.3
                               i:   9, k:   4, y[i]:    9.90, v[k]: 9.9
                               i:  10, k:   5, y[i]:   10.10, v[k]: 10.1
                               i:  11, k:   6, y[i]:   11.11, v[k]: 11.11

                               v:
                               1.1 2.2 3.3 9.9 10.1 11.11
                               1.1 2.2 3.3 9.9 10.1 11.11
                               */
     writeln( "\n       d: ", d );
     writeln(   "x.domain: ", x.domain );
     writeln(   "y.domain: ", y.domain );
     var k = 1;
     for i in x.domain {
         v[k] = x[i];
      // writeln("i: ", i, " k: ", k,  " x[i]: ", x[i], " v[k]: ", v[k]);
         writef( "i: %{###},", i ); writef( " k: %{###},", k ); writef( " x[i]: %{####.##},", x[i] ); writeln( " v[k]: ", v[k] );
         k += 1;
     }
     for i in y.domain {
         v[k] = y[i];
      // writeln("i: ", i, " k: ", k, " y[i]: ", y[i], " v[k]: ", v[k]);
         writef( "i: %{###},", i ); writef( " k: %{###},", k ); writef( " y[i]: %{####.##},", y[i] ); writeln( " v[k]: ", v[k] );
         k += 1;
     }
     writeln( "\nv:\n", v );

     return v;
}

and both alternatives, side by side, left for any further experimentations