0

I have a function that uses a for loop to modify the elements of a matrix. The element-wise function is not huge, so I am unsure about the best way to deal with this. I want to have one thread for each core of the machine (automatically detected) to just execute all these. Ideally, it could also balance execution based on core workload. I have looked into creating custom thread pools for receiving workers, but not sure about if that will work. pmap seems like it might be useful, but I saw in another thread that the coordination overhead would be signficant if every single operation was a future. What are your thoughts about how to approach this? Code below, with some links afterwards.

(defn alter-matrix! [matrix]


(let [row-count (nrow matrix)
    col-count (ncol matrix)]

; Iterate through each element by coordinates.
(for [x (range row-count)
      y (range col-count)]

  ; Calculate whether the element will be altered.
  (let [event (rand)]

    ; 50% chance of alteration.
    (if (< event 0.50)

      ; Unsafely set the new element to a altered version.
      (.setQuick matrix x y 

                 ; Return an altered form of the element.
                 (alter-element (.getQuick matrix x y))))))))

(defn alter-element [element] (let [selector (rand-int 1 4)]
  (cond (= 1 selector) 1.0 (= 2 selector) (* 2.0 element) (= 3 selector) (* 0.5 element))))

Parallel doseq for Clojure http://clojure.com/blog/2012/05/15/anatomy-of-reducer.html Better alternative to pmap in Clojure for parallelizing moderately inexpensive functions over big data?

user1559027
  • 343
  • 2
  • 13
  • 1
    I think you can use core.matrix operations on Incanter matrices. Not sure if this is always correct. However, if so, you might be able to use handy core.matrix functions such as `emap`. (I'm not posting this as part of an answer because I have nothing to say about the parallellization, threading, etc. dimensions of the question. Well, then again: My intuition is that there's not enough work happening here to make it worth sending it off to separate cores, especially since all of the threads will be modifying a common object, i.e. the matrix. My gut feeling based on little experience.) – Mars Apr 22 '14 at 06:01
  • Thank you for your thoughts. The size of the matrix justifies parallel execution. It's large enough to even run through CUDA. I would like to look into `emap`. Where did you find it? – user1559027 Apr 22 '14 at 06:40
  • `emap` is part of [core.matrix](https://github.com/mikera/core.matrix), a matrix library for Clojure that supports several different underlying matrix implementations using the same interface. You can use a unified Clojure-ey interface, and switch implementations depending on your performance needs. core.matrix is partly integrated with Incanter; I'm not sure what the status of the integration project is. The Numerical Clojure Google group would be a good place to ask questions like this one, too; people there might have useful insights. – Mars Apr 22 '14 at 07:29
  • There's also been some discussion of problems and pitfalls of many-threaded multicore execution in the main Clojure Google group in the last six months or a year. – Mars Apr 22 '14 at 07:34
  • 1
    Also: It's common for Clojure programmers on SE to warn about the dangers of depending on side effects within a lazy seq, such as that produced by `for`, and I have sometimes found that very slightly annoying. (Of *course* I'm going to call `doall`.) After seeing A. Webb's answer to my question [here](http://stackoverflow.com/questions/23136930/differences-in-whether-realization-of-a-lazy-sequence-inside-of-a-lazy-sequence/23138464#23138464), I am doing the warning too. You probably know the dangers. (I haven't given up on causing side effects in lazy sequences, but now I am more careful.) – Mars Apr 22 '14 at 14:15
  • 1
    @Mars You may have intended to link [here](http://stackoverflow.com/a/23066351/1756702) instead for that warning? – A. Webb Apr 22 '14 at 15:55
  • @A.Webb, yes, you're absolutely right. [That's what I meant](http://stackoverflow.com/questions/23065811/need-to-force-realization-of-lazy-seqs-before-after-element-wise-imperative-oper/23066351#23066351). Thanks for catching that. – Mars Apr 22 '14 at 21:08
  • Possible duplicate of [Need to force realization of lazy seqs before/after element-wise imperative operations?](https://stackoverflow.com/questions/23065811/need-to-force-realization-of-lazy-seqs-before-after-element-wise-imperative-oper) – bfontaine Jan 09 '19 at 15:48

0 Answers0