proffreda

CS6068: Experiments with Clojure Parallel Code on oakley.o

Aug 28th, 2016
471
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.41 KB | None | 0 0
  1. Experiments with Clojure Parallel Code Running on oakley.osc.edu
  2.  
  3. #Connect to OSC
  4. $ ssh oakley.osc.edu -l ucn1386
  5.  
  6. #Download and install lein
  7. -bash-4.1$ wget https://raw.github.com/technomancy/leiningen/stable/bin/lein
  8. -bash-4.1$ mkdir ~/bin
  9. -bash-4.1$ cp ./lein ~/bin
  10. -bash-4.1$ chmod +x ~/bin/lein
  11.  
  12.  
  13. #Request multi-core node
  14. -bash-4.1$ qsub -I -l nodes=1:ppn=12 -l walltime=00:20:00
  15. qsub: waiting for job 4496542.oak-batch.osc.edu to startqsub: job 4496542.oak-batch.osc.edu ready
  16.  
  17. #Create a Clojure Project called wonderland using lein
  18.  
  19. -bash-4.1$ ~/bin/lein new wonderland
  20. -bash-4.1$ cd wonderland/
  21. -bash-4.1$ ~/bin/lein repl
  22.  
  23.  
  24. nREPL server started on port 58060 on host 127.0.0.1 - nrepl://127.0.0.1:58060
  25. user=> (defn long-running-job2 [n]
  26. (dorun (for [x (range 1000) y (range 1000)] (* x y))))
  27.  
  28. #'user/long-running-job2
  29. user=> (time (doall (map long-running-job2 (range 20))))
  30.  
  31. "Elapsed time: 2939.689332 msecs"
  32. user=> (time (doall (pmap long-running-job2 (range 20))))
  33.  
  34. "Elapsed time: 769.314443 msecs"
  35.  
  36. .............................4x speedup with pmap .......................
  37.  
  38. user=> (def orc-names (random-string-list 40 700000))
  39.  
  40. #'user/orc-names
  41.  
  42. user=> (time (dorun (map clojure.string/lower-case orc-names)))
  43.  
  44. "Elapsed time: 501.401414 msecs"
  45.  
  46. nil
  47.  
  48. user=> (time (dorun (pmap clojure.string/lower-case orc-names)))
  49.  
  50. "Elapsed time: 80.57307 msecs"
  51.  
  52. nil
  53.  
  54. user=> (def orc-name-abbrevs (random-string-list 1200000 300))
  55. #'user/orc-name-abbrevs
  56.  
  57. user=> (time (dorun (map clojure.string/lower-case orc-name-abbrevs)))
  58. "Elapsed time: 5349.481361 msecs"
  59. nil
  60. user=> (time (dorun (pmap clojure.string/lower-case orc-name-abbrevs)))
  61. "Elapsed time: 2831.096441 msecs"
  62. nil
  63. user=> (time (dorun (apply concat
  64. (pmap (fn [name] (doall (map clojure.string/lower-case name)))
  65. (partition-all 100000 orc-name-abbrevs)))))
  66. "Elapsed time: 1064.08318 msecs"
  67. nil
  68.  
  69. # Another Experiment
  70.  
  71. user=> (def orc-names (random-string-list 100000 2))
  72. #'user/orc-names
  73. user=> (time (reduce #(assoc %1 %2 (inc (get %1 %2 0))) {} orc-names))
  74. "Elapsed time: 181.191269 msecs"
  75. user=> (defn mysort [x] (into (sorted-map-by (fn [key1 key2](compare [(get x key2) key2] [(get x key1) key1]))) x))
  76. #'user/mysort
  77. user=> (mysort (r/reduce #(assoc %1 %2 (inc (get %1 %2 0))) {} orc-names))
  78. {"IX" 192, "BA" 192, "XH" 183, "PH" 180, "NB" 180, "SE" 179, "KN" 178, "BL" 178, "ZJ" 177, "WJ" 175, "CP" 174, "PG" 173, "LD" 173, "EI" 173, "BD" 173, "AR" 173, "SW" 172, "JF" 172, "JE" 172, "GX" 172,
  79. ...}
  80.  
  81.  
  82.  
  83.  
  84.  
  85. -bash-4.1$ cat > mypmap.clj
  86. ;; MY-PMAP
  87. (defn long-running-job [n]
  88. (Thread/sleep 3000) ; wait for 3 seconds
  89. (+ n 10))
  90.  
  91. (time (doall (map long-running-job (range 20))))
  92. ;; Elapsed time: 60053.862705 msecs
  93. (10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29)
  94.  
  95. (time (doall (pmap long-running-job (range 20))))
  96. ;;Elapsed time: 3009.768988 msecs
  97. (10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29)
  98.  
  99. ;; This is a false test for speedup, since sleep function apparently allows
  100. ;; and arbitrary number of threads to rest simultaneously.
  101. ;; So let us define a collection active jobs using dorun.
  102.  
  103. ;; dorun, doall, and doseq are all used for forcing lazy sequences, presumably to get side effects.
  104.  
  105. ;; dorun - don't hold whole seq in memory while forcing, return nil
  106. ;; doall - hold whole seq in memory while forcing (i.e., all of it) and return the seq
  107. ;; doseq - same as dorun, but gives you chance to do something with each element as it's forced; returns nil
  108.  
  109.  
  110. (defn long-running-job2 [n]
  111. (dorun (for [x (range 1000) y (range 1000)] (* x y))))
  112.  
  113. (time (doall (map long-running-job2 (range 20))))
  114. ;; Elapsed time: 6489.148202 msecs
  115. ;;(nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)
  116.  
  117. (time (doall (pmap long-running-job2 (range 20))))
  118. ;;Elapsed time: 3378.788034 msecs
  119. ;;(nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)
  120.  
  121. ;; The experiment above shows pmap gives approximate 2x speedup.
  122.  
  123. ;;String processing
  124. (def alphabet-length 26)
  125.  
  126. ;; vector of chars, A-Z
  127. (def letters (mapv (comp str char (partial + 65)) (range alphabet-length)))
  128.  
  129. (defn random-string
  130. ;; returns a random string of specified length
  131. [length]
  132. (apply str (take length (repeatedly #(rand-nth letters)))))
  133.  
  134. (defn random-string-list
  135. [list-length string-length]
  136. (doall (take list-length (repeatedly (partial random-string string-length)))))
  137.  
  138. (def orc-names (random-string-list 40 70000))
  139.  
  140.  
  141. ;; Use `dorun` to realize the lazy seq returned by map without
  142. ;; printing the results in the REPL
  143. (time (dorun (map clojure.string/lower-case orc-names)))
  144.  
  145. (time (dorun (pmap clojure.string/lower-case orc-names)))
  146.  
  147.  
  148. ;;Partitioning for grain size
  149. (def numbers [1 2 3 4 5 6 7 8 9 10])
  150. (partition-all 3 numbers)
  151.  
  152. (pmap inc numbers) ; grain size 1
  153.  
  154. (pmap (fn [number-group] (doall (map inc number-group)))
  155. (partition-all 3 numbers))
  156.  
  157.  
  158. (apply concat
  159. (pmap (fn [number-group] (doall (map inc number-group)))
  160. (partition-all 3 numbers)))
  161.  
  162. (def orc-name-abbrevs (random-string-list 200000 300))
  163.  
  164. (time (dorun (map clojure.string/lower-case orc-name-abbrevs)))
  165.  
  166. (time
  167. (dorun
  168. (apply concat
  169. (pmap (fn [name] (doall (map clojure.string/lower-case name)))
  170. (partition-all 100000 orc-name-abbrevs)))))
Add Comment
Please, Sign In to add comment