Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a future to lock in the behavior when an iterator is unstable #26591

Merged
merged 3 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions test/unstable-keyword/iterator/COMPOPTS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--warn-unstable
35 changes: 35 additions & 0 deletions test/unstable-keyword/iterator/onlySerial.bad
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
onlySerial.chpl:7: In function 'main':
onlySerial.chpl:9: warning: The serial version of foo is unstable
onlySerial.chpl:15: warning: The serial version of foo is unstable
onlySerial.chpl:22: warning: The serial version of foo is unstable
onlySerial.chpl:68: In iterator 'foo':
onlySerial.chpl:73: warning: range.translate() is unstable and its behavior may change in the future
onlySerial.chpl:22: called as foo(param tag = iterKind.leader)
onlySerial.chpl:80: In iterator 'foo':
onlySerial.chpl:85: warning: range.translate() is unstable and its behavior may change in the future
$CHPL_HOME/modules/internal/ChapelIteratorSupport.chpl:641: called as foo(param tag = iterKind.follower, followThis: 1*range(int(64),both,one))
within internal functions (use --print-callstack-on-error to see)
onlySerial.chpl:7: In function 'main':
onlySerial.chpl:31: warning: The serial version of foo is unstable
testing call of serial
in the serial iterator
0
1
2
3
4
5
6
7
8
9
testing call of standalone
in the standalone iterator
0 1 2 3 4 5 6 7 8 9
testing call of leader (and follower)
in the leader iterator
in the follower iterator at least once
0 2 4 6 8 10 12 14 16 18
testing call of just follower
in the follower iterator at least once
0 3 6 9 12 15 18 21 24 27
89 changes: 89 additions & 0 deletions test/unstable-keyword/iterator/onlySerial.chpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Tests behavior when a serial iterator is declared unstable (but none of the
// others are)
var rangeToUse = 0..9;

var triggeredFollower: atomic bool = false;

proc main() {
writeln("testing call of serial");
for i in foo() {
writeln(i);
}

writeln("testing call of standalone");
var arr1: [rangeToUse] int;
forall i in foo() {
arr1[i] = i;
}
writeln(arr1);

writeln("testing call of leader (and follower)");
var arr2: [rangeToUse] int;
forall (val, loc) in zip(foo(), arr2) {
loc = val*2;
}
writeln(arr2);

triggeredFollower.clear();

writeln("testing call of just follower");
var arr3: [rangeToUse] int;
forall (loc, val) in zip(arr3, foo()) {
loc = val*3;
}
writeln(arr3);
}

@unstable("The serial version of foo is unstable")
iter foo() {
writeln("in the serial iterator");
for i in rangeToUse {
yield i;
}
}

iter foo(param tag) where tag == iterKind.standalone {
writeln("in the standalone iterator");
for i in rangeToUse {
yield i;
}
}

// Stolen from the parallel iterators primer
proc computeChunk(r: range, myChunk, numChunks) {
const numElems = r.size;
const elemsperChunk = numElems/numChunks;
const rem = numElems%numChunks;
var mylow = r.low;
if myChunk < rem {
mylow += (elemsperChunk+1)*myChunk;
return mylow..#(elemsperChunk + 1);
} else {
mylow += ((elemsperChunk+1)*rem + (elemsperChunk)*(myChunk-rem));
return mylow..#elemsperChunk;
}
}

// Partially stolen from the parallel iterators primer
iter foo(param tag) where tag == iterKind.leader {
writeln("in the leader iterator");

coforall tid in 0..#here.maxTaskPar {
const myIters = computeChunk(rangeToUse, tid, here.maxTaskPar);
const zeroBasedIters = myIters.translate(-rangeToUse.low);

yield (zeroBasedIters,);
}
}

// Also stolen from the parallel iterators primer
iter foo(param tag, followThis) where tag == iterKind.follower {
if (triggeredFollower.testAndSet() == false) {
writeln("in the follower iterator at least once");
}
const (followInds,) = followThis;
const lowBasedIters = followInds.translate(rangeToUse.low);

for i in lowBasedIters do
yield i;
}
2 changes: 2 additions & 0 deletions test/unstable-keyword/iterator/onlySerial.future
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bug: unstable warnings on iterator overloads trigger too often
#26590
31 changes: 31 additions & 0 deletions test/unstable-keyword/iterator/onlySerial.good
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
onlySerial.chpl:7: In function 'main':
onlySerial.chpl:9: warning: The serial version of foo is unstable
onlySerial.chpl:68: In iterator 'foo':
onlySerial.chpl:73: warning: range.translate() is unstable and its behavior may change in the future
onlySerial.chpl:22: called as foo(param tag = iterKind.leader)
onlySerial.chpl:80: In iterator 'foo':
onlySerial.chpl:85: warning: range.translate() is unstable and its behavior may change in the future
$CHPL_HOME/modules/internal/ChapelIteratorSupport.chpl:641: called as foo(param tag = iterKind.follower, followThis: 1*range(int(64),both,one))
within internal functions (use --print-callstack-on-error to see)
testing call of serial
in the serial iterator
0
1
2
3
4
5
6
7
8
9
testing call of standalone
in the standalone iterator
0 1 2 3 4 5 6 7 8 9
testing call of leader (and follower)
in the leader iterator
in the follower iterator at least once
0 2 4 6 8 10 12 14 16 18
testing call of just follower
in the follower iterator at least once
0 3 6 9 12 15 18 21 24 27
Loading