Skip to content

Commit 5260a41

Browse files
Merge pull request #5934 from awallace-cray/chapdev-204
Fix rank changes with mixed stride (cherry-pick #5929) [approved for release/1.15]
2 parents 27ebd8c + 63319b2 commit 5260a41

File tree

3 files changed

+92
-35
lines changed

3 files changed

+92
-35
lines changed

Diff for: modules/internal/ChapelArray.chpl

+29-35
Original file line numberDiff line numberDiff line change
@@ -1112,14 +1112,22 @@ module ChapelArray {
11121112
// Compute which dimensions are collapsed and what the index
11131113
// (idx) is in the event that it is. These will be stored in
11141114
// the array view to convert from lower-D indices to higher-D.
1115+
// Also compute the upward-facing rank and tuple of ranges.
11151116
//
11161117
var collapsedDim: rank*bool;
11171118
var idx: rank*idxType;
1119+
param uprank = chpl__countRanges((...args));
1120+
param upstridable = this.stridable || chpl__anyRankChangeStridable(args);
1121+
var upranges: uprank*range(idxType=_value.idxType,
1122+
stridable=upstridable);
1123+
var updim = 1;
11181124

11191125
for param i in 1..rank {
11201126
if (isRange(args(i))) {
11211127
collapsedDim(i) = false;
11221128
idx(i) = dim(i).alignedLow;
1129+
upranges(updim) = this._value.dsiDim(i)[args(i)]; // intersect ranges
1130+
updim += 1;
11231131
} else {
11241132
collapsedDim(i) = true;
11251133
idx(i) = args(i);
@@ -1128,9 +1136,7 @@ module ChapelArray {
11281136

11291137
// Create distribution, domain, and array objects representing
11301138
// the array view
1131-
var upranges = _getRankChangeRanges(args, this._value);
11321139
const emptyrange: upranges(1).type;
1133-
param uprank = upranges.size;
11341140
//
11351141
// If idx isn't in the original domain, we need to generate an
11361142
// empty upward facing domain (intersection is empty)
@@ -3100,13 +3106,33 @@ module ChapelArray {
31003106

31013107

31023108
// computes || reduction over stridable of ranges
3103-
proc chpl__anyStridable(ranges, param d: int = 1) param {
3109+
proc chpl__anyStridable(ranges) param {
31043110
for param i in 1..ranges.size do
31053111
if ranges(i).stridable then
31063112
return true;
31073113
return false;
31083114
}
31093115

3116+
// computes || reduction over stridable of ranges, but permits some
3117+
// elements not to be ranges (as in a rank-change slice)
3118+
proc chpl__anyRankChangeStridable(args) param {
3119+
for param i in 1..args.size do
3120+
if isRangeValue(args(i)) then
3121+
if args(i).stridable then
3122+
return true;
3123+
return false;
3124+
}
3125+
3126+
// the following pair of routines counts the number of ranges in its
3127+
// argument list and is used for rank-change slices
3128+
proc chpl__countRanges(arg) param {
3129+
return isRangeValue(arg):int;
3130+
}
3131+
3132+
proc chpl__countRanges(arg, args...) param {
3133+
return chpl__countRanges(arg) + chpl__countRanges((...args));
3134+
}
3135+
31103136
// given a tuple args, returns true if the tuple contains only
31113137
// integers and ranges; that is, it is a valid argument list for rank
31123138
// change
@@ -3147,38 +3173,6 @@ module ChapelArray {
31473173
//return help(1);
31483174
}
31493175

3150-
proc _getRankChangeRanges(args, downdom) {
3151-
return collectRanges(1);
3152-
3153-
proc collectRanges(param dim: int) {
3154-
if isRange(args(dim)) {
3155-
const newRange = downdom.dsiDim(dim)[args(dim)]; // intersect ranges
3156-
return collectRanges(dim+1, (newRange,));
3157-
} else
3158-
return collectRanges(dim+1);
3159-
}
3160-
3161-
proc collectRanges(param dim: int, x: _tuple) {
3162-
if dim > args.size {
3163-
return x;
3164-
} else if dim < args.size {
3165-
if isRange(args(dim)) {
3166-
const newRange = downdom.dsiDim(dim)[args(dim)]; // intersect ranges
3167-
return collectRanges(dim+1, ((...x), newRange));
3168-
} else {
3169-
return collectRanges(dim+1, x);
3170-
}
3171-
} else {
3172-
if isRange(args(dim)) {
3173-
const newRange = downdom.dsiDim(dim)[args(dim)]; // intersect ranges
3174-
return ((...x), newRange);
3175-
} else {
3176-
return x;
3177-
}
3178-
}
3179-
}
3180-
}
3181-
31823176
//
31833177
// Assignment of domains and arrays
31843178
//

Diff for: test/arrays/rankChange/rankChangeMixStridables.chpl

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
config const n = 5;
2+
config const it = 3;
3+
4+
var b: [0..n+1, 0..n+1, 0..1] bool;
5+
6+
b[2..n-1 by 2, 2..n-1, 0] = true;
7+
8+
writeln(b);

Diff for: test/arrays/rankChange/rankChangeMixStridables.good

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
false false
2+
false false
3+
false false
4+
false false
5+
false false
6+
false false
7+
false false
8+
9+
false false
10+
false false
11+
false false
12+
false false
13+
false false
14+
false false
15+
false false
16+
17+
false false
18+
false false
19+
true false
20+
true false
21+
true false
22+
false false
23+
false false
24+
25+
false false
26+
false false
27+
false false
28+
false false
29+
false false
30+
false false
31+
false false
32+
33+
false false
34+
false false
35+
true false
36+
true false
37+
true false
38+
false false
39+
false false
40+
41+
false false
42+
false false
43+
false false
44+
false false
45+
false false
46+
false false
47+
false false
48+
49+
false false
50+
false false
51+
false false
52+
false false
53+
false false
54+
false false
55+
false false

0 commit comments

Comments
 (0)