Skip to content

Commit dcf1e17

Browse files
committed
Base ra-index-map! on ra-slice-for-each-2
This is a bit faster even without special casing the 1-cell. * mod/newra/lib.scm (ra-index-map!): As stated.
1 parent 3969bf7 commit dcf1e17

File tree

5 files changed

+63
-74
lines changed

5 files changed

+63
-74
lines changed

mod/newra/from.scm

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,15 @@
178178
; FIXME going over the args twice, here and in fromb
179179

180180
(define (parse-args A . i)
181-
(let ((rank (ra-rank A)))
181+
(let ((r (ra-rank A)))
182182
(let loop ((j 0) (m 0) (ii i)
183183
(ib '()) (ibi '()) (tb '())
184184
(iu '()) (iui '()) (tu '()))
185185
(match ii
186186
((i0 . irest)
187187
(match i0
188188
(($ <dots> n)
189-
(let* ((k (or n (- rank j (count-axes-left irest))))
189+
(let* ((k (or n (- r j (count-axes-left irest))))
190190
(idest (iota k m)))
191191
(loop (+ j k) (+ m k) irest
192192
(cons (dots k) ib) (fold cons ibi (iota k j)) (fold cons tb idest)
@@ -202,8 +202,8 @@
202202
ib ibi tb
203203
(cons i0 iu) (cons j iui) (fold cons tu idest)))))))
204204
(()
205-
(when (> j rank)
206-
(throw 'too-many-indices-for-rank-of-A j rank))
205+
(when (> j r)
206+
(throw 'too-many-indices-for-rank-of-A j r))
207207
(let ((ib (reverse! ib))
208208
(ibi (reverse! ibi))
209209
(iu (reverse! iu))

mod/newra/lib.scm

Lines changed: 42 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,6 @@ See also: @code{make-ra}
149149
(loop (+ k 1)))))))))
150150
(make-ra-root (%%ra-root oldra) dims (- ref (ra-offset 0 dims))))))))
151151
152-
; FIXME Depends on traversal order of ra-for-each.
153-
154152
(define (ra->list ra)
155153
"
156154
Return a nested list of the elements of array @var{ra}. For example, if @var{ra} is a
@@ -160,32 +158,28 @@ list contains a list for each of the rows of @var{ra}; and so on.
160158
See also: @code{as-ra}
161159
"
162160
(let* ((ra (ra-check ra))
163-
(rank (%%ra-rank ra)))
164-
(cond
165-
((zero? rank) (ra-ref ra))
166-
(else
167-
(let ((ra (apply ra-reverse ra (iota rank))))
168-
(match (vector-ref (%%ra-dims ra) (- rank 1))
169-
(($ <dim> klen klo kstep)
170-
(let loop-rank ((ra ra))
171-
(cond
172-
((= 1 (%%ra-rank ra))
173-
(if (> klen 20)
174-
(ra-fold xcons '() ra)
175-
(let loop-dim ((l '()) (i klo))
176-
(if (> i (dim-hi klen klo))
177-
l
178-
(loop-dim (cons (ra-ref ra i) l) (+ i 1))))))
179-
(else
180-
(let ((l '()))
181-
(ra-slice-for-each 1 (lambda (x) (set! l (cons (loop-rank x) l))) ra)
182-
l)))))))))))
183-
184-
; Similar to (@ (newra) ra-for-each-slice-1) - since we cannot unroll. It
185-
; might be cheaper to go Fortran order (building the index lists back to front);
186-
; should try that. C order and set-cdr! is how oldra does it.
187-
; This function is provided for compatibility with oldra; generally we shouldn't
188-
; be building index lists.
161+
(rank (%%ra-rank ra))
162+
(ra (apply ra-reverse ra (iota rank))))
163+
(if (zero? rank)
164+
(ra-ref ra)
165+
(match (vector-ref (%%ra-dims ra) (- rank 1))
166+
(($ <dim> klen klo _)
167+
(let loop-rank ((ra ra))
168+
(if (= 1 (%%ra-rank ra))
169+
(if (> klen 20)
170+
(ra-fold xcons '() ra)
171+
(let loop-dim ((l '()) (i klo))
172+
(if (> i (dim-hi klen klo))
173+
l
174+
(loop-dim (cons (ra-ref ra i) l) (+ i 1)))))
175+
(let ((l '()))
176+
(ra-slice-for-each-in-order 1 (lambda (x) (set! l (cons (loop-rank x) l))) ra)
177+
l))))))))
178+
179+
; Based on (@ (newra) ra-for-each-slice-2) - we cannot unroll. It might be cheaper to
180+
; go Fortran order (building the index lists back to front); should try that. C order
181+
; and set-cdr! is how oldra does it. This function is provided for compatibility with
182+
; oldra; generally we shouldn't be building index lists.
189183
190184
(define (ra-index-map! ra op)
191185
"
@@ -204,30 +198,26 @@ x @result{} #%2:2:3(((0 0) (0 1) (0 2)) ((1 0) (1 1) (1 2)))
204198

205199
See also: @code{ra-iota} @code{ra-i}
206200
"
207-
(let* ((kk (ra-rank ra))
208-
(ii (make-list kk))
209-
(los lens ((@ (newra map) ra-slice-for-each-check) kk ra)))
210-
(if (= kk 0)
211-
(ra-set! ra (apply op ii))
212-
(let loop-rank ((k 0) (ra ra) (endi ii))
213-
(let* ((lo (vector-ref los k))
214-
(end (+ lo (vector-ref lens k))))
215-
(if (= (+ 1 k) kk)
216-
(let loop-dim ((i lo))
217-
(if (= i end)
218-
(set-car! endi lo)
219-
(begin
220-
(set-car! endi i)
221-
(ra-set! ra (apply op ii) i)
222-
(loop-dim (+ i 1)))))
223-
(let loop-dim ((i lo))
224-
(if (= i end)
225-
(set-car! endi lo)
226-
(begin
227-
(set-car! endi i)
228-
(loop-rank (+ k 1) (ra-slice ra i) (cdr endi))
229-
(loop-dim (+ i 1)))))))))
230-
ra))
201+
(let* ((frame (ra-check ra))
202+
(ii (make-list (%%ra-rank frame)))
203+
(dims (%%ra-dims frame))
204+
(ra (make-ra-root (%%ra-root frame) #() (ra-offset frame))))
205+
(let loop-rank ((k 0) (endi ii))
206+
(if (null? endi)
207+
((%%ra-vset! ra) (%%ra-root ra) (%%ra-zero ra) (apply op ii))
208+
(match (vector-ref dims k)
209+
(($ <dim> len lo step)
210+
(let loop-dim ((i 0))
211+
(if (= i len)
212+
(begin
213+
(set-car! endi lo)
214+
(%%ra-zero-set! ra (- (%%ra-zero ra) (* step len))))
215+
(begin
216+
(set-car! endi (+ i lo))
217+
(loop-rank (+ k 1) (cdr endi))
218+
(%%ra-zero-set! ra (+ (%%ra-zero ra) step))
219+
(loop-dim (+ i 1)))))))))
220+
frame))
231221
232222
233223
; ----------------

mod/newra/map.scm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
(%let ((ra (frame) (make-ra-root-prefix frame k los)) ...)
150150
; since we'll unroll, special case for rank 0
151151
(if (zero? k)
152-
; no fresh slice descriptor like in array-slice-for-each. Should be all right b/c the descriptors can be copied.
152+
; no fresh slice descriptor like in array-slice-for-each. Should be all right bc descriptors can be copied.
153153
(%op ra ...)
154154
; check early so we can save a step in the loop later.
155155
(when (vector-every positive? lens)

mod/test/map-ladder.scm

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,22 @@
4343
(ra (map (cut make-ra-root-prefix <> kk los) frame)))
4444
(let loop-rank ((k 0))
4545
(if (= k kk)
46-
; no fresh slice descriptor like in array-slice-for-each. Should be all right b/c the descriptors can be copied.
46+
; no fresh slice descriptor like in array-slice-for-each. Should be all right bc descriptors can be copied.
4747
(apply op ra)
48-
(let ((lenk (vector-ref lens k)))
48+
(let ((len (vector-ref lens k)))
4949
(let loop-dim ((i 0))
50-
(cond
51-
((= i lenk)
52-
(for-each
53-
(lambda (ra frame)
54-
(let ((step (dim-step (vector-ref (%%ra-dims frame) k))))
55-
(%%ra-zero-set! ra (- (%%ra-zero ra) (* step lenk)))))
56-
ra frame))
57-
(else
58-
(loop-rank (+ k 1))
59-
(for-each
60-
(lambda (ra frame)
61-
(let ((step (dim-step (vector-ref (%%ra-dims frame) k))))
62-
(%%ra-zero-set! ra (+ (%%ra-zero ra) step))))
50+
(if (= i len)
51+
(for-each (lambda (ra frame)
52+
(let ((step (dim-step (vector-ref (%%ra-dims frame) k))))
53+
(%%ra-zero-set! ra (- (%%ra-zero ra) (* step len)))))
6354
ra frame)
64-
(loop-dim (+ i 1))))))))))
55+
(begin
56+
(loop-rank (+ k 1))
57+
(for-each (lambda (ra frame)
58+
(let ((step (dim-step (vector-ref (%%ra-dims frame) k))))
59+
(%%ra-zero-set! ra (+ (%%ra-zero ra) step))))
60+
ra frame)
61+
(loop-dim (+ i 1))))))))))
6562

6663
; moving slice with row-major unrolling.
6764
(define (ra-slice-for-each-3 u op . frame)
@@ -91,7 +88,7 @@
9188
(if (= k u)
9289
; unrolled dimensions.
9390
(let loop ((i lenm))
94-
; no fresh slice descriptor like in array-slice-for-each. Should be all right b/c the descriptors can be copied.
91+
; no fresh slice descriptor like in array-slice-for-each. Should be all right bc descriptors can be copied.
9592
(apply op ra)
9693
(cond
9794
((zero? i)

test/everything.scm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,8 @@
639639

640640
(test-equal "#%2:2:3(((0 0) (0 1) (0 2)) ((1 0) (1 1) (1 2)))"
641641
(ra->string (let ((x (make-ra 0 2 3))) (ra-index-map! x (lambda x x)))))
642+
(test-equal "#%2@2:2@3:3(((2 3) (2 4) (2 5)) ((3 3) (3 4) (3 5)))"
643+
(ra->string (let ((x (make-ra 0 '(2 3) '(3 5)))) (ra-index-map! x (lambda x x)))))
642644
(test-equal "#%0(99)"
643645
(ra->string (let ((x (make-ra 0))) (ra-index-map! x (lambda x 99)))))
644646

0 commit comments

Comments
 (0)