与等级无关的代码:大小列表中的数组和域

时间:2018-07-20 14:35:59

标签: arrays chapel

因此,当然很容易创建一个具有固定已知等级和大小数组的域(并由此创建一个数组),

proc do_something(sizes: [1..2] int) {
  const D: domain(2) = {1..sizes[1], 1..sizes[2]};
  var arr: [D] int;
    // ...
}

但是,如何处理运行时确定的(或至少不是硬编码的)长度的各种大小的数组呢?

proc do_something_2(sizes: [?sd] int) {
  const rank = sd.rank;
  var D: domain(rank); 
  var arr: [D] int; 

  writeln(arr);
}

var D: domain(rank);行失败了,因为它似乎需要一个param等级-但是,即使这样行​​之有效,现在还不清楚如何设置域; expand似乎在两个方向上都扩展了域。

1 个答案:

答案 0 :(得分:4)

您可以从范围的元组中分配域:

var tup = (1..10,2..20);
var D : domain(2) = tup;

param修饰符将起作用。这是一个示例,其中我采用一个域,创建一个大一维的域,并在其上返回一个数组。

proc dimensionalExpansion( dom : domain ) {
  // Get and expand rank
  param oldRank = dom.rank;
  param newRank = oldRank+1;

  // create tuple of size newRank to store each dimensions ranges
  var ranges : newRank*range(dom.idxType, BoundedRangeType.bounded, dom.stridable);
  // copy range from domain
  for i in 1..#oldRank do ranges[i] = dom.dim(i);
  // use last range from domain as our last range
  ranges[newRank] = ranges[oldRank];

  // Create new domain from ranges tuple
  var D: domain(newRank) = ranges;
  // Create array
  var arr: [D] int;

  // Putting some arbitrary values into the array;
  for idx in D {
    arr[idx] = if newRank > 1 then idx[newRank] - idx[1] else idx; 
  }

  return arr;
}

writeln( "==================" );
writeln( dimensionalExpansion( {1..3} ) );
writeln( "==================" );
writeln( dimensionalExpansion( {1..3,1..3} ) );
writeln( "==================" );
writeln( dimensionalExpansion( {1..3,1..3,1..3} ) );

Running TIO Instance