diff options
author | Rich Hickey <richhickey@gmail.com> | 2008-05-14 23:41:48 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2008-05-14 23:41:48 +0000 |
commit | 9c2df55473a3311af5f6475d1543de3812cd033c (patch) | |
tree | ab81f9055c7ef7998e6103de5f3020cd3b253902 | |
parent | 91fa51c1107526ad4c7ed141c8a6a3b275bbb0e2 (diff) |
added docs to parallel.clj
-rw-r--r-- | src/parallel.clj | 130 |
1 files changed, 105 insertions, 25 deletions
diff --git a/src/parallel.clj b/src/parallel.clj index 8f99d0e6..63368b3f 100644 --- a/src/parallel.clj +++ b/src/parallel.clj @@ -9,31 +9,65 @@ (in-ns 'parallel) (clojure/refer 'clojure) +(comment " +The parallel library wraps the ForkJoin library scheduled for inclusion in JDK 7: + +http://gee.cs.oswego.edu/dl/concurrency-interest/index.html + +You'll need jsr166y.jar in your classpath in order to use this +library. The basic idea is that Clojure collections, and most +efficiently vectors, can be turned into parallel arrays for use by +this library with the function par, although most of the functions +take collections and will call par if needed. Parallel arrays support +the attachment of bounds, filters and mapping functions prior to +realization, which happens as the result of any of several operations +on the array (pall/psort/pfilter-nils/pfilter-dupes/pvec). Rather than +perform composite operations in steps, as would normally be done with +sequences, maps and filters are instead attached and thus composed +with the with-* functions. Note that there is an order sensitivity to +the attachments - bounds precede filters precede mappings. All +operations then happen in parallel, using multiple threads and a +sophisticated work-stealing system supported by fork-join, either when +the array is realized, or to perform aggregate operations like +preduce/pmin/pmax etc. A parallel array can be realized into a Clojure +vector using pvec. +") + (import '(jsr166y.forkjoin ParallelArray ParallelArrayWithBounds ParallelArrayWithFilter ParallelArrayWithMapping - Ops$Op Ops$BinaryOp Ops$Reducer Ops$Predicate Ops$BinaryPredicate Ops$IntAndObjectPredicate - Ops$IntAndObjectToObject)) + Ops$Op Ops$BinaryOp Ops$Reducer Ops$Predicate Ops$BinaryPredicate + Ops$IntAndObjectPredicate Ops$IntAndObjectToObject)) -(defn par [coll] +(defn par + "Creates a parallel array from coll if it is not already one" + [coll] (if (instance? ParallelArrayWithMapping coll) coll (ParallelArray.createUsingHandoff (to-array coll) (ParallelArray.defaultExecutor)))) -(defn pall [coll] +(defn pall + "Realizes a copy of the coll as a parallel array, with any bounds/filters/maps applied" + [coll] (if (instance? ParallelArrayWithMapping coll) (. coll all) (par coll))) -(defn pany [coll] +(defn pany + "Returns some (random) element of the coll if it satisfies the bound/filter/map" + [coll] (. (par coll) any)) -(defn pmax +(defn pmax + "Returns the maximum element, presuming Comparable elements, unless + a Comparator comp is supplied" ([coll] (. (par coll) max)) ([coll comp] (. (par coll) max comp))) (defn pmin + "Returns the maximum element, presuming Comparable elements, unless + a Comparator comp is supplied" ([coll] (. (par coll) min)) ([coll comp] (. (par coll) min comp))) @@ -41,10 +75,14 @@ {:min (s.min) :max (s.max) :size (s.size) :min-index (s.indexOfMin) :max-index (s.indexOfMax)}) (defn psummary + "Returns a map of summary statistics (min. max, size, min-index, max-index, + presuming Comparable elements, unless a Comparator comp is supplied" ([coll] (summary-map (. (par coll) summary))) ([coll comp] (summary-map (. (par coll) summary comp)))) -(defn punique [coll] +(defn pdistinct + "Returns a parallel array of the distinct elements of coll" + [coll] (. (par coll) allUniqueElements)) (defn- op [f] @@ -76,52 +114,94 @@ (op [i x] (boolean (f i x))))) ;this doesn't work, passes null to reducer? -(defn pcumulate [coll f init] +(defn- pcumulate [coll f init] (.. (pall coll) (precumulate (reducer f) init))) -(defn preduce [f base coll] +(defn preduce + "Returns a parallel array of the reduction of the realized elements of coll + using function f. Note f will not necessarily be called + consecutively, and so must be commutative. Also note that + (f base an-element) might be performed many times, i.e. base is not + an initial value as with sequential reduce. Returns a new parallel + array." + [f base coll] (. (par coll) (reduce (reducer f) base))) (defn psort + "Returns a new parallel array consisting of the realized items in coll, sorted, + presuming Comparable elements, unless a Comparator comp is supplied" ([coll] (. (pall coll) sort)) ([coll comp] (. (pall coll) sort comp))) -(defn pfilter-nils [coll] +(defn pfilter-nils + "Returns a parallel array containing the non-nil (realized) elements of coll" + [coll] (. (pall coll) removeNulls)) -(defn pfilter-dupes [coll] +(defn pfilter-dupes + "Returns a parallel array containing the (realized) elements of coll, + without any consecutive duplicates" + [coll] (. (pall coll) removeConsecutiveDuplicates)) -(defn with-bounds [coll start end] +(defn with-bounds + "Returns a parallel array with the bounds attached. Note bounds must + be attached before filters or mappings. Only elements from + start (inclusive) to end (exclusive) will be processed when the + array is realized." + [coll start end] (. (par coll) withBounds start end)) (defn with-filter - ([coll f] - (. (par coll) withFilter (predicate f))) - ([coll f2 coll2] - (. (par coll) withFilter (binary-predicate f2) (par coll2)))) + "Returns a parallel array with the filter attached. Note filters + must be attached before mappings. pred must be a function of one + argument whose return will be processed via boolean. pred2 must be a + function of two arguments, which will be corresponding elements of + the 2 collections. The predicate will be used to remove elements + from processing when the array is realized." + ([coll pred] + (. (par coll) withFilter (predicate pred))) + ([coll pred2 coll2] + (. (par coll) withFilter (binary-predicate pred2) (par coll2)))) (defn with-indexed-filter - ([coll f] - (. (par coll) withIndexedFilter (int-and-object-predicate f)))) + "Returns a parallel array with the filter attached. Note filters + must be attached before mappings. pred2 must be a function of two + arguments, which will be an index and the corresponding element of + the collection, whose return will be processed via boolean. The + predicate will be used to remove elements from processing when + the array is realized." + ([coll pred2] + (. (par coll) withIndexedFilter (int-and-object-predicate pred2)))) (defn with-mapping + "Returns a parallel array with the mapping function attached. f + must be a function of one argument. f2 must be a function of two + arguments, which will be corresponding elements of the 2 + collections. The mapping fn will be used to transform elements when + the array is realized." ([coll f] (. (par coll) withMapping (op f))) ([coll f2 coll2] (. (par coll) withMapping (binary-op f2) (par coll2)))) (defn with-indexed-mapping - ([coll f] - (. (par coll) withIndexedMapping (int-and-object-to-object f)))) + "Returns a parallel array with the mapping function attached. f2 + must be a function of two arguments, which will be an index and the + corresponding element of the collection. The mapping fn will be used + to transform elements when the array is realized." + ([coll f2] + (. (par coll) withIndexedMapping (int-and-object-to-object f2)))) -(defn pvec [pa] - (vec (. (pall pa) getArray))) +(defn pvec + "Returns the realized contents of the parallel array pa as a Clojure vector" + [pa] (vec (. (pall pa) getArray))) -(comment -(punique [1 2 3 2 1]) -(pcumulate [1 2 3 2 1] + 0) ;broken +(comment +(refer 'parallel) +(pdistinct [1 2 3 2 1]) +;(pcumulate [1 2 3 2 1] + 0) ;broken, not exposed (def a (make-array Object 1000000)) (dotimes i (count a) (aset a i i)) |