代码之家  ›  专栏  ›  技术社区  ›  Jonathan Dursi

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

  •  5
  • Jonathan Dursi  · 技术社区  · 8 年前

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

    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 回复  |  直到 8 年前
        1
  •  4
  •   memorableusername    8 年前

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

    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