38
38
this non-determinism is inherent in all lock-free and wait-free data structures.
39
39
*/
40
40
41
+
42
+
41
43
/*
44
+
45
+ Summary
46
+ ________
47
+
48
+
42
49
A parallel-safe scalable distributed deque. A deque is a double-ended queue that supports
43
50
insertion and removal from both ends of the queue, effectively supporting both
44
51
FIFO, LIFO, and a Total ordering, where the order in which you add them will be
45
52
the exact order you remove them in; for emphasis, a Deque can be used as a Queue,
46
53
a Stack, and a List respectively.
47
54
55
+ .. note::
56
+
57
+ The documentation for the Collection modules are being incrementally revised and improved.
58
+
59
+ Usage
60
+ _____
61
+
48
62
First, the :record:`DistDeque` must be initialized before use by calling its constructor.
49
63
50
64
.. code-block:: chapel
81
95
}
82
96
83
97
The deque supports both serial and parallel iteration, and a means to iterate in a particular order
84
- (currently only FIFO and LIFO) using the `Ordering` enumerator.
98
+ (currently only FIFO and LIFO) using the `` Ordering` ` enumerator.
85
99
86
100
.. code-block:: chapel
87
101
101
115
102
116
deque.addBulk(1..100);
103
117
var result = + reduce deque;
104
-
118
+
119
+ Bugs and Known Issues
120
+ _____________________
121
+
122
+ 1. It is not safe to call other methods while iterating, as it will lead to deadlock. It is an open question
123
+ whether using a snapshot approach is better to allow concurrent operations at the expense of elevated memory
124
+ consumption, and iterating directly over elements while holding locks, which strangles potential concurrency.
125
+
126
+ 2. Reduction cannot be performed in any ordered way. This may be fixed in the near future, either by adding
127
+ pseudo-parallel iterators that merely yield sequentially in order, or by creating a method to perform reduction
128
+ for the user in a specified ordering.
129
+
130
+ 3. This data structure **requires** network atomic support for scalability, and without it will result in degrading
131
+ performance. It is another open question whether a specific implementation that is more friendly for remote-execution
132
+ atomic operations should be provided.
133
+
134
+ 4. The ordered serial iterators currently do not work when the ``globalHead`` or ``globalTail`` are negative, which is a
135
+ result of iteration being an after-thought. This will be improved upon soon, but for now if you use :proc:`pushBack`
136
+ or :proc:`pushFront` methods, I would advise against using them for now.
137
+
138
+ Planned Improvements
139
+ ____________________
140
+
141
+ 1. Double the size of each successor up to some maximmum, similar to :mod:`DistributedBag` for unroll blocks.
142
+ Currently they are fixed-sized, but it can benefit from improved locality if a lot of elements are added at
143
+ once.
144
+
145
+ Methods
146
+ _______
105
147
*/
106
148
module DistributedDeque {
107
149
@@ -114,7 +156,7 @@ module DistributedDeque {
114
156
config param distributedDequeBlockSize = 8 ;
115
157
116
158
/*
117
- The ordering used for serial iteration. NONE, the default, is the most performant
159
+ The ordering used for serial iteration. `` NONE`` , the default, is the most performant
118
160
and is algorithmically similar to parallel iteration.
119
161
*/
120
162
enum Ordering {
@@ -144,6 +186,11 @@ module DistributedDeque {
144
186
*/
145
187
record DistDeque {
146
188
type eltType;
189
+ /*
190
+ The implementation of the Deque, is forwarded. See :class:`DistributedDequeImpl` for
191
+ documentation.
192
+ */
193
+ var _impl : DistributedDequeImpl(eltType);
147
194
148
195
// Privatization id
149
196
pragma " no doc"
@@ -157,6 +204,7 @@ module DistributedDeque {
157
204
_rc = new Shared(new DistributedDequeRC(eltType, _pid = _pid));
158
205
}
159
206
207
+ pragma " no doc"
160
208
inline proc _value {
161
209
if _pid == - 1 {
162
210
halt(" DistDeque is uninitialized..." );
@@ -175,6 +223,9 @@ module DistributedDeque {
175
223
__primitive(" method call resolves" , _value, " these" , tag= tag)
176
224
return _value.these(order, tag= tag);
177
225
226
+ /*
227
+ See :class:`DistributedDequeImpl`.
228
+ */
178
229
forwarding _value;
179
230
}
180
231
@@ -190,12 +241,6 @@ module DistributedDeque {
190
241
forwarding _value;
191
242
}
192
243
193
- /*
194
- A parallel-safe scalable distributed double-ended queue that supports both
195
- insertion and removal from either end of the queue. Can be used as a Queue,
196
- Stack, or even a List.
197
- */
198
- pragma " no doc"
199
244
class DistributedDequeImpl : CollectionImpl {
200
245
/*
201
246
Capacity, the maximum number of elements a Deque can hold. A `cap` of -1 is
@@ -523,9 +568,8 @@ module DistributedDeque {
523
568
524
569
/*
525
570
Iterate over all elements in the deque in the order specified.
526
-
527
- **Warning:** Calling other methods while inside of an iterator is not safe as
528
- it will likely lead to deadlock.
571
+
572
+
529
573
530
574
**FIXME:** Likely can be worked around by either using snapshot iteration approach
531
575
or by making the lock reentrant and forcing all iterators to acquire all locks in
@@ -718,6 +762,7 @@ module DistributedDeque {
718
762
followThis.lock$;
719
763
}
720
764
765
+ pragma " no doc"
721
766
proc Destroy () {
722
767
for slot in slots do delete slot;
723
768
delete globalHead;
0 commit comments