Skip to content

Commit 7a497ba

Browse files
Adding changes to Collections
1 parent 7a6581d commit 7a497ba

File tree

3 files changed

+74
-16
lines changed

3 files changed

+74
-16
lines changed

collections/Collection.chpl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
1. Is safe parallel-safe, hence is safe to use across multiple tasks across multiple locales.
66
2. Supports the basic operations that any data structure needs to be truly useful, that is:
7-
7+
88
a. Insertion of an arbitrary element. From this, we can insert bulk arbitrary elements.
99
b. Removal of an arbitrary element. From this, we can remove bulk arbitrary elements.
1010
c. Iteration over all elements. From this, we can perform lookups over all elements.
@@ -72,11 +72,19 @@ module Collection {
7272
Otherwise, just make sure you always capture the return value inside of a loop
7373
in a variable not declared outside of loop...
7474
75-
::
75+
.. code-block:: chapel
7676
7777
for i in 1 .. N {
7878
var retval = c.remove();
7979
}
80+
81+
**BUG:** Sometimes the compiler will produce an internal error related to 'visibility blocks',
82+
this can be resolved by declaring the return type rather than letting the compiler infer it.
83+
The exact cause has yet to be found.
84+
85+
.. code-block:: chapel
86+
87+
var retval : (bool, eltType) = c.remove();
8088
8189
*/
8290
proc remove() : (bool, eltType) {

collections/DistributedBag.chpl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444
*/
4545

4646
/*
47+
48+
Summary
49+
_______
50+
4751
A parallel-safe distributed multiset implementation that scales in terms of
4852
nodes, processors per node (PPN), and workload; The more PPN, the more segments
4953
we allocate to increase raw parallelism, and the larger the workload the better
@@ -57,7 +61,7 @@
5761
.. code-block:: chapel
5862
5963
var bag = new DistBag(int, targetLocales=Locales[0..1]);
60-
64+
6165
While usage of the `bag` can be used safely across locales, each locale has its own
6266
instance allocated in it's address space, a `privatized` copy. While this instance
6367
is managed transparently from the user, its impact on performance is significant.
@@ -74,8 +78,9 @@
7478
}
7579
// Elements redistributed across all nodes...
7680
bag.balance();
77-
81+
7882
*/
83+
7984
module DistributedBag {
8085
use Collection;
8186
use BlockDist;

collections/DistributedDeque.chpl

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,27 @@
3838
this non-determinism is inherent in all lock-free and wait-free data structures.
3939
*/
4040

41+
42+
4143
/*
44+
45+
Summary
46+
________
47+
48+
4249
A parallel-safe scalable distributed deque. A deque is a double-ended queue that supports
4350
insertion and removal from both ends of the queue, effectively supporting both
4451
FIFO, LIFO, and a Total ordering, where the order in which you add them will be
4552
the exact order you remove them in; for emphasis, a Deque can be used as a Queue,
4653
a Stack, and a List respectively.
4754
55+
.. note::
56+
57+
The documentation for the Collection modules are being incrementally revised and improved.
58+
59+
Usage
60+
_____
61+
4862
First, the :record:`DistDeque` must be initialized before use by calling its constructor.
4963
5064
.. code-block:: chapel
@@ -81,7 +95,7 @@
8195
}
8296
8397
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.
8599
86100
.. code-block:: chapel
87101
@@ -101,7 +115,35 @@
101115
102116
deque.addBulk(1..100);
103117
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+
_______
105147
*/
106148
module DistributedDeque {
107149

@@ -114,7 +156,7 @@ module DistributedDeque {
114156
config param distributedDequeBlockSize = 8;
115157

116158
/*
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
118160
and is algorithmically similar to parallel iteration.
119161
*/
120162
enum Ordering {
@@ -144,6 +186,11 @@ module DistributedDeque {
144186
*/
145187
record DistDeque {
146188
type eltType;
189+
/*
190+
The implementation of the Deque, is forwarded. See :class:`DistributedDequeImpl` for
191+
documentation.
192+
*/
193+
var _impl : DistributedDequeImpl(eltType);
147194

148195
// Privatization id
149196
pragma "no doc"
@@ -157,6 +204,7 @@ module DistributedDeque {
157204
_rc = new Shared(new DistributedDequeRC(eltType, _pid = _pid));
158205
}
159206

207+
pragma "no doc"
160208
inline proc _value {
161209
if _pid == -1 {
162210
halt("DistDeque is uninitialized...");
@@ -175,6 +223,9 @@ module DistributedDeque {
175223
__primitive("method call resolves", _value, "these", tag=tag)
176224
return _value.these(order, tag=tag);
177225

226+
/*
227+
See :class:`DistributedDequeImpl`.
228+
*/
178229
forwarding _value;
179230
}
180231

@@ -190,12 +241,6 @@ module DistributedDeque {
190241
forwarding _value;
191242
}
192243

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"
199244
class DistributedDequeImpl : CollectionImpl {
200245
/*
201246
Capacity, the maximum number of elements a Deque can hold. A `cap` of -1 is
@@ -523,9 +568,8 @@ module DistributedDeque {
523568

524569
/*
525570
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+
529573
530574
**FIXME:** Likely can be worked around by either using snapshot iteration approach
531575
or by making the lock reentrant and forcing all iterators to acquire all locks in
@@ -718,6 +762,7 @@ module DistributedDeque {
718762
followThis.lock$;
719763
}
720764

765+
pragma "no doc"
721766
proc Destroy() {
722767
for slot in slots do delete slot;
723768
delete globalHead;

0 commit comments

Comments
 (0)