sandbox.scm 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. ; -*- mode: scheme; coding: utf-8 -*-
  2. ; (c) Daniel Llorens - 2016-2023
  3. ; This library is free software; you can redistribute it and/or modify it under
  4. ; the terms of the GNU General Public License as published by the Free
  5. ; Software Foundation; either version 3 of the License, or (at your option) any
  6. ; later version.
  7. ; Trying things.
  8. (import (newra) (newra tools) (newra base) (ice-9 match) (ice-9 format)
  9. (srfi srfi-8) (srfi srfi-26) (srfi srfi-1)
  10. (only (srfi srfi-43) vector-copy! vector-fill!)
  11. (rnrs io ports) (only (rnrs base) vector-map)
  12. (only (rnrs bytevectors) bytevector-copy! bytevector-fill!))
  13. (define ⍉ ra-transpose)
  14. ; -----------------------
  15. ; goops (?)
  16. ; -----------------------
  17. (import (oop) (goops))
  18. (define <ra> (class-of (make-ra 0 0)))
  19. (define-method (+ (x <ra>) (y <ra>)) (ra-map #f + x y))
  20. (define-method (+ (x <number>) (y <ra>)) (ra-map #f + (make-ra x) y))
  21. (define-method (+ (x <ra>) (y <number>)) (ra-map #f + x (make-ra y)))
  22. ; -----------------------
  23. ; lazy ops
  24. ; -----------------------
  25. #|
  26. Normal arrays have bounds (lo hi) and an affine map N to 1: [inc ... zero] (a row)
  27. A 'general' array (expr) would have bounds (lo hi) and an affine map M×N to N: [inc₀ ... zero₀; ... incₘ₋₁ ... zeroₘ₋₁] (m rows).
  28. Although if eventually all leaves are 1D, do we need to make that explicit?
  29. So idea 1) for exprs is (op args) where each arg may be an array or an expr.
  30. Then any shape op on arrays needs to be beatable on the args to avoid having to store a full affine map for the expr.
  31. |#
  32. ; -----------------------
  33. ; ra-rotate!
  34. ; -----------------------
  35. (time (ra-rotate! 11 (ra-copy #t (ra-i 4000 3500)))) ; 2.73 - 0.73 with ra-swap!
  36. ; -----------------------
  37. ; ra-amend!
  38. ; -----------------------
  39. (ra-from (ra-copy #t (ra-i 6 4))
  40. (array->ra #2((0 1) (2 3) (4 5))) (array->ra #1(3 2 1)))
  41. (ra-amend! (ra-copy #t (ra-i 6 4)) (array->ra #(A B C))
  42. (array->ra #2((0 1) (2 3) (4 5))) (array->ra #1(3 2 1)))
  43. (ra-amend! (ra-copy #t (ra-i 6 4)) (array->ra #2((A a) (B b) (C c)))
  44. (array->ra #2((0 1) (2 3) (4 5))) (array->ra #1(3 2 1)))
  45. (ra-amend! (ra-copy #t (ra-i 6 4)) (array->ra #3(((A B C) (a b c)) ((P Q R) (p q r)) ((X Y Z) (x y z))))
  46. (array->ra #2((0 1) (2 3) (4 5))) (array->ra #1(3 2 1)))
  47. ; -----------------------
  48. ; can't remember
  49. ; -----------------------
  50. (define ra0 (array->ra #(1 2 3)))
  51. (define ra1 (array->ra #@1(1 2 3)))
  52. (define ra2 (array->ra #2((1 2) (3 4))))
  53. (define ra3 (array->ra #2@1@1((1 2) (3 4))))
  54. (define ra4 (array->ra #3@1@1@-1(((1 2 3) (3 4 5)) ((4 5 6) (6 7 8)))))
  55. (define ra5 (array->ra #0(99)))
  56. (define v #(1 2 3 4))
  57. (define (vector->list-forward v)
  58. (case (vector-length v)
  59. ((0) '())
  60. ((1) (list (vector-ref v 0)))
  61. (else
  62. (let ((first (list (vector-ref v 0))))
  63. (let loop ((last first) (i 1))
  64. (if (= i (vector-length v))
  65. first
  66. (let ((next (list (vector-ref v i))))
  67. (set-cdr! last next)
  68. (loop next (+ i 1)))))))))
  69. ,m (newra)
  70. ; call macro with PARAM according to values OPT of TAG
  71. (define-syntax %tag-dispatch
  72. (syntax-rules ()
  73. ((_ tag macro (opt ...) (param ...) args ...)
  74. (case tag ((opt) (macro param args ...)) ... (else (throw 'bad-tag tag))))))
  75. (%tag-dispatch 'TWO display (ONE TWO) ('one 'two))
  76. (import (srfi 1))
  77. (define-inlinable-case demo1
  78. (case-lambda
  79. "DOC"
  80. (() 0)
  81. ((a) a)
  82. ((a b) (+ a b))
  83. (x (fold + 0 x))))
  84. (define-inlinable-case demo2
  85. (case-lambda
  86. (() 0)
  87. ((a) a)
  88. ((a b) (+ a b))
  89. (x (fold + 0 x))))
  90. ; -----------------------------
  91. ; some examples, benchmarks
  92. ; -----------------------------
  93. ; GEMM
  94. ; guile-newra - pure scheme, Guile 2.9
  95. (define n 100)
  96. (define B (ra-copy #t (ra-i n n)))
  97. (define C (ra-copy #t (ra-i n n)))
  98. (define ⍉ ra-transpose)
  99. ; Guile newra doesn't define gemm so we make it up on the spot. A few versions...
  100. ,time (define A0 (let* ((A (make-typed-ra #t 0 n n))
  101. (X (⍉ A 0 2)))
  102. (ra-map! X (lambda (a b c) (+ a (* b c))) X B (⍉ C 1))
  103. A))
  104. ,time (define A1 (let* ((A (make-typed-ra #t 0 n n))
  105. (X (⍉ A 0 2)))
  106. (ra-slice-for-each 3 (lambda (a b c) (set! (a) (+ (a) (* (b) (c))))) X B (⍉ C 1))
  107. A))
  108. ,time (define A2 (let* ((A (make-typed-ra #t 0 n n)))
  109. (ra-slice-for-each 2
  110. (lambda (A B C) (set! (A) (ra-fold (lambda (a b c) (+ (* b c) a)) 0 B C)))
  111. A (⍉ B 0 2) (⍉ C 2 1))
  112. A))
  113. ; check result
  114. (ra-equal? A0 A1 A2)
  115. (ra-fold + 0 A0)
  116. 250032502500000 ; n 100
  117. 3205173202000000 ; n 200
  118. (define B (i/t. 'f64 100 100))
  119. (define C (i/t. 'f64 100 100))
  120. ,time (define A (blas-dgemm B C 1 'no 'no))
  121. ;; 0.015948s real time, 0.029959s run time. 0.020600s spent in GC.
  122. ; check result
  123. (over + (ravel A))
  124. 2.500325025e14
  125. (define x (ra-copy 'f64 (ra-iota #e1e6)))
  126. ,time (ra-fold + 0 x)
  127. ,time (let ((a 0.)) (ra-for-each (lambda (x) (set! a (+ a x))) x) a)
  128. ,time (let ((a 0.)) (ra-slice-for-each 1 (lambda (x) (set! a (+ a (x)))) x) a)
  129. (define N #e1e7)
  130. (define y (ra-copy 'f64 (ra-iota N)))
  131. ,time (ra-fold + 0 y) ; ~ 4.7s for #e1e8, 1.7s for #e1e7
  132. (define y (let ((y (make-typed-array 'f64 0 N)))
  133. (array-index-map! y (lambda (i) i))
  134. y))
  135. ; if you look at the disassembly of these, it looks a lot better than (ra-fold + 0 x). Why is that?
  136. ,time (let loop ((a 0) (i 0)) (if (= i N) a (loop (+ a (f64vector-ref y i)) (+ 1 i))))
  137. ,time ((lambda (op) (let loop ((a 0) (i 0)) (if (= i N) a (loop (op a (f64vector-ref y i)) (+ 1 i))))) +)
  138. ,time (let ((a 0)) (let loop ((i 0)) (if (= i N) a (begin (set! a (+ a (f64vector-ref y i))) (loop (+ 1 i))))))
  139. (let-syntax ((%macro (syntax-rules () ((_ a) a)))) (define (fun a) (%macro a)))