Skip to content

Commit ba83ff5

Browse files
Moved tests to modules/packages/collections
1 parent e5e240a commit ba83ff5

16 files changed

+398
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use DistributedBag;
2+
use DistributedDeque;
3+
use Barrier;
4+
5+
// For this test, we implement a simple counter; we add a predetermined number
6+
// of elements, then concurrently remove all elements from it until it is empty,
7+
// testing that all elements added were removed.
8+
config param isBoundedDeque = false;
9+
config param isDeque = false;
10+
config param isBag = false;
11+
12+
config param nElems = 1000;
13+
const expected = (nElems * (nElems + 1)) / 2;
14+
15+
var c = (
16+
if isBoundedDeque then new DistributedDeque(int, cap=nElems)
17+
else if isDeque then new DistributedDeque(int)
18+
else if isBag then new DistributedBag(int)
19+
else compilerError("Require 'isBoundedDeque', 'isDeque', or 'isBag' to be set...")
20+
);
21+
22+
23+
// Fill...
24+
for i in 1 .. nElems {
25+
c.add(i);
26+
}
27+
28+
assert(c.size == nElems);
29+
assert(c.contains((nElems / 2) : int));
30+
31+
// Iterate over the collection.
32+
var actual = 0;
33+
for elem in c {
34+
actual = actual + elem;
35+
}
36+
assert(actual == expected);
37+
assert(c.size == nElems);
38+
39+
// Iterate concurrently over the collection.
40+
var concurrentActual : atomic int;
41+
forall elem in c {
42+
concurrentActual.add(elem);
43+
}
44+
assert(concurrentActual.read() == expected);
45+
assert(c.size == nElems);
46+
47+
// Empty collection. Make sure all tasks start around same time...
48+
if isBag then c.balance();
49+
concurrentActual.write(0);
50+
var barrier = new Barrier(here.maxTaskPar * numLocales);
51+
coforall loc in Locales do on loc {
52+
var perLocaleActual : atomic int;
53+
const _c = c;
54+
coforall tid in 0..#here.maxTaskPar {
55+
barrier.barrier();
56+
var (hasElem, elt) : (bool, int) = (true, 0);
57+
var perTaskActual : int;
58+
while hasElem {
59+
perTaskActual = perTaskActual + elt;
60+
(hasElem, elt) = _c.remove();
61+
}
62+
perLocaleActual.add(perTaskActual);
63+
}
64+
concurrentActual.add(perLocaleActual.read());
65+
}
66+
67+
assert(concurrentActual.read() == expected);
68+
assert(c.size == 0 && c.isEmpty());
69+
writeln("SUCCESS");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--no-loop-invariant-code-motion -sisDeque --main-module=CollectionCounter
2+
--no-loop-invariant-code-motion -sisBag --main-module=CollectionCounter
3+
--no-loop-invariant-code-motion -sisBoundedDeque --main-module=CollectionCounter
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SUCCESS
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
use Barrier;
2+
use DistributedBag;
3+
use DistributedDeque;
4+
5+
/*
6+
Precomputed number of solutions...
7+
8+
N x N | Total | Unique
9+
1 x 1 1 1
10+
2 x 2 0 0
11+
3 x 3 0 0
12+
4 x 4 2 1
13+
5 x 5 10 2
14+
6 x 6 4 1
15+
7 x 7 40 6
16+
8 x 8 92 12
17+
9 x 9 352 46
18+
10 x 10 724 92
19+
11 x 11 2,680 341
20+
12 x 12 14,200 1,787
21+
13 x 13 73,712 9,233
22+
14 x 14 365,596 45,752
23+
15 x 15 2,279,184 285,053
24+
16 x 16 14,772,512 1,846,955
25+
17 x 17 95,815,104 11,977,939
26+
18 x 18 666,090,624 83,263,591
27+
19 x 19 4,968,057,848 621,012,754
28+
20 x 20 39,029,188,884 4,878,666,808
29+
21 x 21 314,666,222,712 39,333,324,973
30+
22 x 22 2,691,008,701,644 336,376,244,042
31+
23 x 23 24,233,937,684,440 3,029,242,658,210
32+
24 x 24 227,514,171,973,736 28,439,272,956,934
33+
25 x 25 2,207,893,435,808,350 275,986,683,743,434
34+
26 x 26 22,317,699,616,364,000 2,789,712,466,510,280 */
35+
36+
37+
config param nQueens = 8;
38+
config param isDeque = false;
39+
config param isBag = false;
40+
41+
inline proc getTotalSolutions() {
42+
var retval = 0;
43+
select nQueens {
44+
when 1 do retval = 1;
45+
when 2 do retval = 0;
46+
when 3 do retval = 0;
47+
when 4 do retval = 2;
48+
when 5 do retval = 10;
49+
when 6 do retval = 4;
50+
when 7 do retval = 40;
51+
when 8 do retval = 92;
52+
when 9 do retval = 352;
53+
when 10 do retval = 724;
54+
when 11 do retval = 2680;
55+
when 12 do retval = 14200;
56+
when 13 do retval = 73712;
57+
when 14 do retval = 365596;
58+
when 15 do retval = 2279184;
59+
when 16 do retval = 14722512;
60+
when 17 do retval = 95815104;
61+
when 18 do retval = 666090624;
62+
otherwise do halt("Bad parameter for nQueens: ", nQueens, "; Must be in 1 .. 18");
63+
}
64+
65+
return retval;
66+
}
67+
68+
proc findFirstEmptyRow(board) {
69+
var idx = 1;
70+
for row in board {
71+
if idx > nQueens {
72+
return nQueens + 1;
73+
}
74+
if row == 0 {
75+
return idx;
76+
}
77+
idx = idx + 1;
78+
}
79+
80+
return nQueens + 1;
81+
}
82+
83+
proc canPlaceQueen(board, row, col) {
84+
// If at any row, the column is taken, we can't occupy the slot...
85+
for occupiedCol in board {
86+
if occupiedCol == col then return false;
87+
}
88+
89+
// Horizontal - Left/Right
90+
var x = 1;
91+
while x <= nQueens {
92+
if board[x] == col then return false;
93+
x = x + 1;
94+
}
95+
96+
// Note: We do not need to check vertical, as it is ensured already to be vacant
97+
98+
// Diagonal - Up Right
99+
x = row + 1;
100+
var y = col + 1;
101+
while x <= nQueens && y <= nQueens {
102+
if board[x] == y then return false;
103+
104+
x = x + 1;
105+
y = y + 1;
106+
}
107+
108+
// Diagonal - Down Left
109+
x = row - 1;
110+
y = col - 1;
111+
while x > 0 && y > 0 {
112+
if board[x] == y then return false;
113+
x = x - 1;
114+
y = y - 1;
115+
}
116+
117+
// Diagonal - Up Left
118+
x = row - 1;
119+
y = col + 1;
120+
while x > 0 && y <= nQueens {
121+
if board[x] == y then return false;
122+
x = x - 1;
123+
y = y + 1;
124+
}
125+
126+
// Diagonal - Down Right
127+
x = row + 1;
128+
y = col - 1;
129+
while x <= nQueens && y > 0 {
130+
if board[x] == y then return false;
131+
x = x + 1;
132+
y = y - 1;
133+
}
134+
135+
return true;
136+
}
137+
138+
139+
140+
141+
type boardType = nQueens * int;
142+
const totalSolutions = getTotalSolutions();
143+
var found : atomic int;
144+
var c : Collection(boardType);
145+
if isDeque {
146+
c = new DistributedDeque(boardType);
147+
} else if isBag {
148+
c = new DistributedBag(boardType);
149+
} else {
150+
halt("Require 'isDeque' or 'isBag' to be set...");
151+
}
152+
153+
// Fill with initial board...
154+
c.add(_defaultOf(boardType));
155+
156+
// Begin concurrent NQueens...
157+
var barrier = new Barrier(here.maxTaskPar * numLocales);
158+
coforall loc in Locales do on loc {
159+
coforall tid in 0 .. #here.maxTaskPar {
160+
barrier.barrier();
161+
var nSpins : int;
162+
while found.read() < totalSolutions {
163+
var (exists, myBoard) = c.remove();
164+
// Spin: We haven't found solution yet...
165+
if !exists {
166+
nSpins = nSpins + 1;
167+
if nSpins == 1000000 {
168+
halt("Spun: ", nSpins);
169+
}
170+
chpl_task_yield();
171+
continue;
172+
}
173+
174+
nSpins = 0;
175+
176+
const firstEmptyRow = findFirstEmptyRow(myBoard);
177+
if firstEmptyRow == nQueens+1 { //no empty row
178+
// We are done: Alert everyone that it is done (including ourselves...)
179+
found.add(1);
180+
continue;
181+
}
182+
for j in 1..nQueens {
183+
if canPlaceQueen(myBoard, firstEmptyRow, j) {
184+
var newBoard = myBoard;
185+
newBoard[firstEmptyRow] = j;
186+
c.add(newBoard);
187+
}
188+
}
189+
}
190+
}
191+
}
192+
193+
writeln("SUCCESS");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-sisDeque --main-module=CollectionNQueens
2+
-sisBag --main-module=CollectionNQueens
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SUCCESS
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use DistributedDeque;
2+
3+
// We test both FIFO and LIFO capabilities of the Deque, as well as total ordering.
4+
// This test differs from DequeAccumulator in that it is entirely sequential and
5+
// that the outcome should be deterministic.
6+
7+
config param isBounded = false;
8+
9+
const nElems = 1000;
10+
var deque = (if isBounded then new DistributedDeque(int, cap = nElems) else new DistributedDeque(int));
11+
12+
// FIFO
13+
for i in 1 .. nElems {
14+
deque.enqueue(i);
15+
}
16+
17+
assert(deque.size == nElems);
18+
assert(deque.contains(nElems / 2));
19+
20+
var expect = 1;
21+
for elem in deque.these(Ordering.FIFO) {
22+
assert(elem == expect);
23+
expect += 1;
24+
}
25+
26+
for i in 1 .. nElems {
27+
var (hasElem, elem) = deque.dequeue();
28+
assert(hasElem && elem == i);
29+
}
30+
var hasElem = deque.dequeue()[1];
31+
assert(deque.size == 0 && deque.isEmpty() && !hasElem);
32+
33+
// LIFO
34+
for i in 1 .. nElems {
35+
deque.push(i);
36+
}
37+
assert(deque.size == nElems);
38+
assert(deque.contains(nElems / 2));
39+
40+
expect = nElems;
41+
for elem in deque.these(Ordering.LIFO) {
42+
assert(elem == expect);
43+
expect -= 1;
44+
}
45+
46+
for i in 0 .. #nElems {
47+
var (hasElem, elem) = deque.pop();
48+
assert(hasElem && elem == nElems - i);
49+
}
50+
hasElem = deque.dequeue()[1];
51+
assert(deque.size == 0 && deque.isEmpty() && !hasElem);
52+
53+
// Total Ordering
54+
// In this case, we add the middle element, then all elements preceeding it to the
55+
// beginning, and all elements succeeding it to the end.
56+
var middle = nElems / 2;
57+
deque.add(middle);
58+
for i in 1 .. middle - 1 {
59+
deque.pushFront(middle - i);
60+
}
61+
for i in middle + 1 .. nElems {
62+
deque.pushBack(i);
63+
}
64+
assert(deque.size == nElems);
65+
for i in 1 .. nElems {
66+
var (hasElem, elem) = deque.dequeue();
67+
assert(hasElem && elem == i);
68+
}
69+
70+
writeln("SUCCESS");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
--main-module=DequeOrdering
2+
--main-module=DequeOrdering -sisBounded=true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SUCCESS

0 commit comments

Comments
 (0)