与等级无关的代码:大小列表中的数组和域
Rank-independent code: array and domain from list of sizes
当然可以很容易地创建一个具有固定已知等级和数组大小的域(以及由此而来的数组),
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
似乎它在两个方向上扩展了域。
您可以从范围元组分配域:
var tup = (1..10,2..20);
var D : domain(2) = tup;
param
修饰符将起作用。这是一个例子,我输入一个域,创建一个大一维的域,并在其上 return 一个数组。
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} ) );
当然可以很容易地创建一个具有固定已知等级和数组大小的域(以及由此而来的数组),
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
似乎它在两个方向上扩展了域。
您可以从范围元组分配域:
var tup = (1..10,2..20);
var D : domain(2) = tup;
param
修饰符将起作用。这是一个例子,我输入一个域,创建一个大一维的域,并在其上 return 一个数组。
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} ) );