racket/collects/math/private/array/array-parallel.rkt
Neil Toronto b8efd58aca Array changes in response to user feedback (and my personal neuroses)
* `list->array' now accepts an optional shape argument, and always returns
  an immutable array

* `vector->array' now accepts an optional shape argument, and always
  returns a mutable array

* Removed `make-mutable-array' because `vector->array' does its job now (I
  never liked the name anyway)

* Renamed `unsafe-mutable-array' to `unsafe-vector->array'

* Added optional type annotation to `array' macro to match `mutable-array'

* Reworded error messages in array broadcasting functions

* Made minor array doc fixes
2012-12-17 15:54:29 -07:00

70 lines
2.8 KiB
Racket

#lang typed/racket/base
(require racket/future
racket/list
"../unsafe.rkt"
"../parameters.rkt"
"array-struct.rkt"
"mutable-array.rkt"
"utils.rkt")
(provide parallel-array->mutable-array
parallel-array-strict)
(: eval-array-proc! (All (A) (Indexes (Indexes -> A) Indexes (Vectorof A) Index Index -> Void)))
(define (eval-array-proc! ds proc js vs start end)
(define dims (vector-length ds))
(unsafe-value-index->array-index! ds start js)
(let: k-loop : Nonnegative-Fixnum ([k : Nonnegative-Fixnum 0]
[j : Nonnegative-Fixnum start])
(cond [(k . < . dims)
(define: dk : Index (unsafe-vector-ref ds k))
(let: jk-loop : Nonnegative-Fixnum ([jk : Nonnegative-Fixnum (unsafe-vector-ref js k)]
[j : Nonnegative-Fixnum j])
(cond [(jk . < . dk)
(unsafe-vector-set! js k jk)
(jk-loop (+ jk 1) (k-loop (+ k 1) j))]
[else
(unsafe-vector-set! js k 0)
j]))]
[(j . >= . end) j]
[else (define v (proc js))
(unsafe-vector-set! vs j v)
(unsafe-fx+ j 1)]))
(void))
(: parallel-array->mutable-array (All (A) ((Array A) -> (Mutable-Array A))))
(define (parallel-array->mutable-array arr)
(define size (array-size arr))
(cond
[(zero? size) (unsafe-vector->array (array-shape arr) (vector))]
[else
(define ds (array-shape arr))
(define dims (vector-length ds))
(define proc (unsafe-array-proc arr))
;; Use all the available processors
(define num-futures (max-math-threads))
(parameterize ([max-math-threads 1])
(define jss
(for/list: : (Listof Indexes) ([i (in-range num-futures)])
(ann (make-vector dims 0) Indexes)))
(define: vs : (Vectorof A) (make-vector size (proc (first jss))))
(define stops
(for/list: : (Listof Index) ([i (in-range num-futures)])
(assert (quotient (* (+ i 1) size) num-futures) index?)))
(define futures
(for/list: : (Listof (Futureof Void)) ([start (in-list stops)]
[end (in-list (rest stops))]
[js (in-list (rest jss))])
(future (λ () (eval-array-proc! ds proc js vs start end)))))
(eval-array-proc! ds proc (first jss) vs 1 (first stops))
(for: ([f (in-list futures)])
(touch f))
(unsafe-vector->array ds vs))]))
(: parallel-array-strict (All (A) ((Array A) -> (Array A))))
(define (parallel-array-strict arr)
(cond [(array-strict? arr) arr]
[else (parallel-array->mutable-array arr)]))